From fcb617a2ef533460b92bcd030aef81e3ed7106b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 19 Jul 2021 11:07:54 +0200 Subject: [PATCH 0001/1333] host/l2cap: send command reject in L2CAP disc req for invalid CID If ble_hs_conn_chan_find_by_scid fails to find channel, it means that destination CID in L2CAP Disconnection Request is invalid. Send L2CAP_COMMAND_REJECT_RSP with BLE_L2CAP_SIG_ERR_INVALID_CID reason. This is affecting L2CAP/LE/CFC/BV-23-C --- nimble/host/src/ble_l2cap_sig.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index fab16ea441..2a36161998 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -1552,7 +1552,13 @@ ble_l2cap_sig_disc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, * is from peer perspective. It is source CID from nimble perspective */ chan = ble_hs_conn_chan_find_by_scid(conn, le16toh(req->dcid)); - if (!chan || (le16toh(req->scid) != chan->dcid)) { + if (!chan) { + os_mbuf_free_chain(txom); + ble_hs_unlock(); + ble_l2cap_sig_reject_invalid_cid_tx(conn_handle, hdr->identifier, req->dcid, req->scid); + return 0; + } + if (le16toh(req->scid) != chan->dcid) { os_mbuf_free_chain(txom); ble_hs_unlock(); return 0; From e0b15dadd1d3007879b912ad48a481ed1a4bffec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 2 Aug 2021 10:28:09 +0200 Subject: [PATCH 0002/1333] host/tests: add test for invalid CID in disconnection request --- nimble/host/test/src/ble_hs_test_util.h | 2 + nimble/host/test/src/ble_l2cap_test.c | 64 +++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/nimble/host/test/src/ble_hs_test_util.h b/nimble/host/test/src/ble_hs_test_util.h index 411443cfdd..7a0aa3eb19 100644 --- a/nimble/host/test/src/ble_hs_test_util.h +++ b/nimble/host/test/src/ble_hs_test_util.h @@ -162,6 +162,8 @@ int ble_hs_test_util_l2cap_rx_payload_flat(uint16_t conn_handle, uint16_t cid, const void *data, int len); uint8_t ble_hs_test_util_verify_tx_l2cap_sig(uint16_t opcode, void *cmd, uint16_t cmd_size); +uint8_t ble_hs_test_util_verify_tx_l2cap_discon_rej(uint16_t opcode, void *cmd, + uint16_t cmd_size); int ble_hs_test_util_inject_rx_l2cap_sig(uint16_t conn_handle, uint8_t opcode, uint8_t id, void *cmd, uint16_t cmd_size); void ble_hs_test_util_verify_tx_l2cap(struct os_mbuf *txom); diff --git a/nimble/host/test/src/ble_l2cap_test.c b/nimble/host/test/src/ble_l2cap_test.c index 2b17da06a7..0f55bc006b 100644 --- a/nimble/host/test/src/ble_l2cap_test.c +++ b/nimble/host/test/src/ble_l2cap_test.c @@ -999,6 +999,46 @@ ble_l2cap_test_coc_disc_by_peer(struct test_data *t) &req, sizeof(req)) == id); } +static void +ble_l2cap_test_coc_disc_by_peer_invalid_dcid(struct test_data *t) +{ + struct ble_l2cap_sig_disc_req req; + struct event *ev = &t->event[t->event_iter++]; + uint8_t id = 10; + int rc; + struct os_mbuf *cmd; + uint16_t rej_err = htole16(BLE_L2CAP_SIG_ERR_INVALID_CID); + req.dcid = htole16(t->chan[0]->dcid + 1); + req.scid = htole16(t->chan[0]->dcid); + + rc = ble_hs_test_util_inject_rx_l2cap_sig(2, BLE_L2CAP_SIG_OP_DISCONN_REQ, + id, &req, sizeof(req)); + TEST_ASSERT(rc == 0); + + /* Ensure callback got NOT called. */ + TEST_ASSERT(!ev->handled); + + struct { + uint16_t local_cid; + uint16_t remote_cid; + } data = { + .local_cid = req.scid, + .remote_cid = req.dcid, + }; + + /* Ensure an we sent back Command Reject response + * Recect command should contain reason and CIDs pair + */ + cmd = os_mbuf_get(&sdu_os_mbuf_pool, 0); + os_mbuf_append(cmd, &rej_err, sizeof(uint16_t)); + os_mbuf_append(cmd, &data, sizeof(data)); + + ble_hs_test_util_verify_tx_l2cap_sig( + BLE_L2CAP_SIG_OP_REJECT, + cmd->om_data, cmd->om_len); + os_mbuf_free_chain(cmd); +} + static void ble_l2cap_test_coc_invalid_disc_by_peer(struct test_data *t) { @@ -1361,6 +1401,29 @@ TEST_CASE_SELF(ble_l2cap_test_case_sig_coc_incoming_disconnect_failed) ble_hs_test_util_assert_mbufs_freed(NULL); } +TEST_CASE_SELF(ble_l2cap_test_case_invalid_cid_in_disconnect_req) +{ + struct test_data t; + + ble_l2cap_test_util_init(); + + ble_l2cap_test_set_chan_test_conf(BLE_L2CAP_TEST_PSM, + BLE_L2CAP_TEST_COC_MTU, &t); + t.expected_num_of_ev = 1; + + t.event[0].type = BLE_L2CAP_EVENT_COC_CONNECTED; + t.event[0].app_status = 0; + t.event[0].l2cap_status = BLE_L2CAP_COC_ERR_CONNECTION_SUCCESS; + t.event[1].type = BLE_L2CAP_EVENT_COC_DISCONNECTED; + + ble_l2cap_test_coc_connect(&t); + ble_l2cap_test_coc_disc_by_peer_invalid_dcid(&t); + + TEST_ASSERT(t.expected_num_of_ev == t.event_cnt); + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + TEST_CASE_SELF(ble_l2cap_test_case_coc_send_data_succeed) { struct test_data t; @@ -1493,6 +1556,7 @@ TEST_SUITE(ble_l2cap_test_suite) ble_l2cap_test_case_sig_coc_disconnect_succeed(); ble_l2cap_test_case_sig_coc_incoming_disconnect_succeed(); ble_l2cap_test_case_sig_coc_incoming_disconnect_failed(); + ble_l2cap_test_case_invalid_cid_in_disconnect_req(); ble_l2cap_test_case_coc_send_data_succeed(); ble_l2cap_test_case_coc_send_data_failed_too_big_sdu(); ble_l2cap_test_case_coc_recv_data_succeed(); From 5b93f6945a7761c39a1cab3bc0fad727a9635332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 20 Jul 2021 10:45:11 +0200 Subject: [PATCH 0003/1333] host/l2cap: disconnect channel if received more than expected If receive data lenght exceeds what was defined in first packet disconnect with peer. This is affecting L2CAP/LE/CFC/BV-28-C --- nimble/host/src/ble_l2cap_coc.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c index aa953d79c5..f74cea2800 100644 --- a/nimble/host/src/ble_l2cap_coc.c +++ b/nimble/host/src/ble_l2cap_coc.c @@ -198,6 +198,17 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) } sdu_len = get_le16((*om)->om_data); + + /* We should receive payload of size sdu_len + 2 bytes of sdu_len field */ + if (om_total > sdu_len + 2) { + BLE_HS_LOG(ERROR, "Payload larger than expected (%d>%d)\n", + om_total, sdu_len + 2); + /* Disconnect peer with invalid behaviour */ + rx->sdu = NULL; + rx->data_offset = 0; + ble_l2cap_disconnect(chan); + return BLE_HS_EBADDATA; + } if (sdu_len > rx->mtu) { BLE_HS_LOG(INFO, "error: sdu_len > rx->mtu (%d>%d)\n", sdu_len, rx->mtu); @@ -227,6 +238,15 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) } else { BLE_HS_LOG(DEBUG, "Continuation...received %d\n", (*om)->om_len); + if (OS_MBUF_PKTLEN(rx->sdu) + (*om)->om_len > rx->data_offset) { + /* Disconnect peer with invalid behaviour */ + BLE_HS_LOG(ERROR, "Payload larger than expected (%d>%d)\n", + OS_MBUF_PKTLEN(rx->sdu) + (*om)->om_len, rx->data_offset); + rx->sdu = NULL; + rx->data_offset = 0; + ble_l2cap_disconnect(chan); + return BLE_HS_EBADDATA; + } rc = os_mbuf_appendfrom(rx->sdu, *om, 0, om_total); if (rc != 0) { /* FIXME: need to handle it better */ From ba36c802f33b2f9e2b79d8a09a78c2f88dfb211f Mon Sep 17 00:00:00 2001 From: Daniel Jackson Date: Sun, 26 Sep 2021 00:37:43 +0100 Subject: [PATCH 0004/1333] Return the current tick as when the RF will be fully enabled (when MYNEWT_VAL_BLE_LL_RFMGMT_ENABLE_TIME is not defined). When `MYNEWT_VAL_BLE_LL_RFMGMT_ENABLE_TIME` is not defined, the existing code always returns 0 as the "tick at which RF will be fully enabled". However, this causes problems. For example, in `ble_ll_adv_sm_start()` (ble_ll_adv.c:2743) the calculation of `delta` overflows when the system timer is between 0x80000000 and 0xFFFFFFFF -- causing an incorrect, huge adjustment to be made to the scheduled time, ultimately stopping the advertisements from being sent. --- nimble/controller/include/controller/ble_ll_rfmgmt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/include/controller/ble_ll_rfmgmt.h b/nimble/controller/include/controller/ble_ll_rfmgmt.h index 37b81a88be..5e2d636ff8 100644 --- a/nimble/controller/include/controller/ble_ll_rfmgmt.h +++ b/nimble/controller/include/controller/ble_ll_rfmgmt.h @@ -51,7 +51,7 @@ static inline void ble_ll_rfmgmt_reset(void) { } static inline void ble_ll_rfmgmt_scan_changed(bool e, uint32_t n) { } static inline void ble_ll_rfmgmt_sched_changed(struct ble_ll_sched_item *f) { } static inline void ble_ll_rfmgmt_release(void) { } -static inline uint32_t ble_ll_rfmgmt_enable_now(void) { return 0; } +static inline uint32_t ble_ll_rfmgmt_enable_now(void) { return os_cputime_get32(); } static inline bool ble_ll_rfmgmt_is_enabled(void) { return true; } #endif From e4f5b4498af0b5e549acb336a0f1bab200aa9739 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 28 Sep 2021 19:28:00 +0200 Subject: [PATCH 0005/1333] apps/ext_advertiser: Fix instance and sid values Let's use instance number as sid also, this makes it easier to find those instances in the air. Also fix instance numbers in comments. --- apps/ext_advertiser/src/main.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/ext_advertiser/src/main.c b/apps/ext_advertiser/src/main.c index 86b728436e..9cb6c6fe57 100644 --- a/apps/ext_advertiser/src/main.c +++ b/apps/ext_advertiser/src/main.c @@ -86,7 +86,7 @@ start_ext_max_events(uint8_t pattern, bool configure) params.primary_phy = BLE_HCI_LE_PHY_1M; params.secondary_phy = BLE_HCI_LE_PHY_1M; params.tx_power = 127; - params.sid = pattern % 16; + params.sid = 4; /* allow larger interval, 400 * 0.625ms with 100 events will give up to * ~2.5 seconds for instance @@ -94,7 +94,7 @@ start_ext_max_events(uint8_t pattern, bool configure) params.itvl_min = BLE_GAP_ADV_FAST_INTERVAL1_MIN; params.itvl_max = 400; - /* configure instance 0 */ + /* configure instance 4 */ rc = ble_gap_ext_adv_configure(instance, ¶ms, NULL, start_ext_max_events_gap_event, NULL); assert (rc == 0); @@ -184,9 +184,9 @@ start_legacy_duration(uint8_t pattern, bool configure) params.primary_phy = BLE_HCI_LE_PHY_1M; params.secondary_phy = BLE_HCI_LE_PHY_1M; params.tx_power = 127; - params.sid = pattern % 16; + params.sid = 3; - /* configure instance 0 */ + /* configure instance 3 */ rc = ble_gap_ext_adv_configure(instance, ¶ms, NULL, start_legacy_duration_gap_event, NULL); assert (rc == 0); @@ -251,7 +251,7 @@ start_scannable_legacy_ext(void) params.tx_power = 127; params.sid = 2; - /* configure instance 0 */ + /* configure instance 2 */ rc = ble_gap_ext_adv_configure(instance, ¶ms, NULL, NULL, NULL); assert (rc == 0); @@ -335,7 +335,7 @@ start_scannable_ext(void) params.tx_power = 127; params.sid = 1; - /* configure instance 0 */ + /* configure instance 1 */ rc = ble_gap_ext_adv_configure(instance, ¶ms, NULL, scannable_ext_gap_event, NULL); assert (rc == 0); @@ -387,7 +387,7 @@ start_non_connectable_ext(void) params.tx_power = 127; params.sid = 0; - /* configure instance */ + /* configure instance 0 */ rc = ble_gap_ext_adv_configure(instance, ¶ms, NULL, NULL, NULL); assert (rc == 0); @@ -430,9 +430,9 @@ static void start_periodic(void) params.primary_phy = BLE_HCI_LE_PHY_1M; params.secondary_phy = BLE_HCI_LE_PHY_1M; params.tx_power = 127; - params.sid = 2; + params.sid = 5; - /* configure instance 0 */ + /* configure instance 5 */ rc = ble_gap_ext_adv_configure(instance, ¶ms, NULL, NULL, NULL); assert (rc == 0); From 2bc5aede344b093577fe0070e4c1b514e769e8fe Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 10 Mar 2021 00:11:05 +0100 Subject: [PATCH 0006/1333] nimble/ll: Rename ble_ll_scan_params to ble_ll_scan_phy --- .../include/controller/ble_ll_scan.h | 8 +- nimble/controller/src/ble_ll_scan.c | 76 +++++++++---------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index 9bbd4d6900..4ee1aa4b43 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -80,7 +80,7 @@ struct ble_ll_scan_timing { uint32_t start_time; }; -struct ble_ll_scan_params +struct ble_ll_scan_phy { uint8_t phy; uint8_t own_addr_type; @@ -185,9 +185,9 @@ struct ble_ll_scan_sm uint8_t restart_timer_needed; struct ble_ll_aux_data *cur_aux_data; - struct ble_ll_scan_params *scanp; - struct ble_ll_scan_params *scanp_next; - struct ble_ll_scan_params scanp_phys[BLE_LL_SCAN_PHY_NUMBER]; + struct ble_ll_scan_phy *scanp; + struct ble_ll_scan_phy *scanp_next; + struct ble_ll_scan_phy scan_phys[BLE_LL_SCAN_PHY_NUMBER]; }; /* Scan types */ diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 7eac16b5ae..aef0c12b5d 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -65,7 +65,7 @@ #endif /* The scanning parameters set by host */ -static struct ble_ll_scan_params g_ble_ll_scan_params[BLE_LL_SCAN_PHY_NUMBER]; +static struct ble_ll_scan_phy g_ble_ll_scan_phys[BLE_LL_SCAN_PHY_NUMBER]; /* The scanning state machine global object */ static struct ble_ll_scan_sm g_ble_ll_scan_sm; @@ -884,7 +884,7 @@ static void ble_ll_get_chan_to_scan(struct ble_ll_scan_sm *scansm, uint8_t *chan, int *phy) { - struct ble_ll_scan_params *scanp = scansm->scanp; + struct ble_ll_scan_phy *scanp = scansm->scanp; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) struct ble_ll_aux_data *aux_data = scansm->cur_aux_data; @@ -914,7 +914,7 @@ static int ble_ll_scan_start(struct ble_ll_scan_sm *scansm, struct ble_ll_sched_item *sch) { int rc; - struct ble_ll_scan_params *scanp = scansm->scanp; + struct ble_ll_scan_phy *scanp = scansm->scanp; uint8_t scan_chan; #if (BLE_LL_BT5_PHY_SUPPORTED == 1) uint8_t phy_mode; @@ -1005,7 +1005,7 @@ ble_ll_scan_get_next_adv_prim_chan(uint8_t chan) } static uint32_t -ble_ll_scan_move_window_to(struct ble_ll_scan_params *scanp, uint32_t time) +ble_ll_scan_move_window_to(struct ble_ll_scan_phy *scanp, uint32_t time) { uint32_t end_time; @@ -1025,7 +1025,7 @@ ble_ll_scan_move_window_to(struct ble_ll_scan_params *scanp, uint32_t time) } static bool -ble_ll_scan_is_inside_window(struct ble_ll_scan_params *scanp, uint32_t time) +ble_ll_scan_is_inside_window(struct ble_ll_scan_phy *scanp, uint32_t time) { uint32_t start_time; @@ -1175,8 +1175,8 @@ ble_ll_scan_sm_stop(int chk_disable) static int ble_ll_scan_sm_start(struct ble_ll_scan_sm *scansm) { - struct ble_ll_scan_params *scanp; - struct ble_ll_scan_params *scanp_next; + struct ble_ll_scan_phy *scanp; + struct ble_ll_scan_phy *scanp_next; if (!ble_ll_is_valid_own_addr_type(scansm->own_addr_type, g_random_addr)) { return BLE_ERR_INV_HCI_CMD_PARMS; @@ -1295,10 +1295,10 @@ ble_ll_scan_event_proc(struct ble_npl_event *ev) os_sr_t sr; bool start_scan; bool inside_window; - struct ble_ll_scan_params *scanp; + struct ble_ll_scan_phy *scanp; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) bool inside_window_next; - struct ble_ll_scan_params *scanp_next; + struct ble_ll_scan_phy *scanp_next; #endif uint32_t next_proc_time; uint32_t now; @@ -1438,7 +1438,7 @@ ble_ll_scan_rx_isr_start(uint8_t pdu_type, uint16_t *rxflags) { int rc; struct ble_ll_scan_sm *scansm; - struct ble_ll_scan_params *scanp; + struct ble_ll_scan_phy *scanp; rc = 0; scansm = &g_ble_ll_scan_sm; @@ -1990,7 +1990,7 @@ static int ble_ll_scan_rx_filter(struct ble_mbuf_hdr *hdr, struct ble_ll_scan_addr_data *addrd) { struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; - struct ble_ll_scan_params *scanp = scansm->scanp; + struct ble_ll_scan_phy *scanp = scansm->scanp; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) struct ble_ll_aux_data *aux_data = hdr->rxinfo.user_data; @@ -2130,7 +2130,7 @@ ble_ll_scan_rx_isr_on_legacy(uint8_t pdu_type, uint8_t *rxbuf, struct ble_ll_scan_addr_data *addrd) { struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; - struct ble_ll_scan_params *scanp = scansm->scanp; + struct ble_ll_scan_phy *scanp = scansm->scanp; struct ble_mbuf_hdr_rxinfo *rxinfo = &hdr->rxinfo; uint8_t sreq_adva_type; uint8_t *sreq_adva; @@ -2201,7 +2201,7 @@ ble_ll_scan_rx_isr_on_aux(uint8_t pdu_type, uint8_t *rxbuf, struct ble_ll_scan_addr_data *addrd) { struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; - struct ble_ll_scan_params *scanp = scansm->scanp; + struct ble_ll_scan_phy *scanp = scansm->scanp; struct ble_mbuf_hdr_rxinfo *rxinfo = &hdr->rxinfo; struct ble_ll_aux_data *aux_data; int rc; @@ -3234,7 +3234,7 @@ ble_ll_scan_set_scan_params(const uint8_t *cmdbuf, uint8_t len) uint16_t scan_itvl; uint16_t scan_window; struct ble_ll_scan_sm *scansm; - struct ble_ll_scan_params *scanp; + struct ble_ll_scan_phy *scanp; if (len != sizeof(*cmd)) { return BLE_ERR_INV_HCI_CMD_PARMS; @@ -3276,7 +3276,7 @@ ble_ll_scan_set_scan_params(const uint8_t *cmdbuf, uint8_t len) } /* Store scan parameters */ - scanp = &g_ble_ll_scan_params[PHY_UNCODED]; + scanp = &g_ble_ll_scan_phys[PHY_UNCODED]; scanp->configured = 1; scanp->scan_type = cmd->scan_type; scanp->timing.interval = ble_ll_scan_time_hci_to_ticks(scan_itvl); @@ -3285,7 +3285,7 @@ ble_ll_scan_set_scan_params(const uint8_t *cmdbuf, uint8_t len) scanp->own_addr_type = cmd->own_addr_type; #if (BLE_LL_SCAN_PHY_NUMBER == 2) - g_ble_ll_scan_params[PHY_CODED].configured = 0; + g_ble_ll_scan_phys[PHY_CODED].configured = 0; #endif return 0; @@ -3319,9 +3319,9 @@ ble_ll_set_ext_scan_params(const uint8_t *cmdbuf, uint8_t len) const struct ble_hci_le_set_ext_scan_params_cp *cmd = (const void *) cmdbuf; const struct scan_params *params = cmd->scans; - struct ble_ll_scan_params new_params[BLE_LL_SCAN_PHY_NUMBER] = { }; - struct ble_ll_scan_params *uncoded = &new_params[PHY_UNCODED]; - struct ble_ll_scan_params *coded = &new_params[PHY_CODED]; + struct ble_ll_scan_phy new_params[BLE_LL_SCAN_PHY_NUMBER] = { }; + struct ble_ll_scan_phy *uncoded = &new_params[PHY_UNCODED]; + struct ble_ll_scan_phy *coded = &new_params[PHY_CODED]; uint16_t interval; uint16_t window; int rc; @@ -3420,7 +3420,7 @@ ble_ll_set_ext_scan_params(const uint8_t *cmdbuf, uint8_t len) } } - memcpy(g_ble_ll_scan_params, new_params, sizeof(new_params)); + memcpy(g_ble_ll_scan_phys, new_params, sizeof(new_params)); return 0; } @@ -3487,8 +3487,8 @@ ble_ll_scan_set_enable(uint8_t enable, uint8_t filter_dups, uint16_t period, { int rc; struct ble_ll_scan_sm *scansm; - struct ble_ll_scan_params *scanp; - struct ble_ll_scan_params *scanp_phy; + struct ble_ll_scan_phy *scanp; + struct ble_ll_scan_phy *scanp_phy; int i; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) ble_npl_time_t period_ticks = 0; @@ -3543,7 +3543,7 @@ ble_ll_scan_set_enable(uint8_t enable, uint8_t filter_dups, uint16_t period, if (scansm->scan_enabled) { /* Controller does not allow initiating and scanning.*/ for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) { - scanp_phy = &scansm->scanp_phys[i]; + scanp_phy = &scansm->scan_phys[i]; if (scanp_phy->configured && scanp_phy->scan_type == BLE_SCAN_TYPE_INITIATE) { return BLE_ERR_CMD_DISALLOWED; @@ -3576,8 +3576,8 @@ ble_ll_scan_set_enable(uint8_t enable, uint8_t filter_dups, uint16_t period, scansm->scanp_next = NULL; for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) { - scanp_phy = &scansm->scanp_phys[i]; - scanp = &g_ble_ll_scan_params[i]; + scanp_phy = &scansm->scan_phys[i]; + scanp = &g_ble_ll_scan_phys[i]; if (!scanp->configured) { continue; @@ -3606,7 +3606,7 @@ ble_ll_scan_set_enable(uint8_t enable, uint8_t filter_dups, uint16_t period, * Parameters defaults. */ if (!scansm->scanp) { - scansm->scanp = &scansm->scanp_phys[PHY_UNCODED]; + scansm->scanp = &scansm->scan_phys[PHY_UNCODED]; scansm->own_addr_type = BLE_ADDR_PUBLIC; scanp_phy = scansm->scanp; @@ -3671,7 +3671,7 @@ ble_ll_scan_can_chg_whitelist(void) { int rc; struct ble_ll_scan_sm *scansm; - struct ble_ll_scan_params *scanp; + struct ble_ll_scan_phy *scanp; scansm = &g_ble_ll_scan_sm; scanp = scansm->scanp; @@ -3689,7 +3689,7 @@ ble_ll_scan_initiator_start(struct hci_create_conn *hcc, struct ble_ll_scan_sm **sm) { struct ble_ll_scan_sm *scansm; - struct ble_ll_scan_params *scanp; + struct ble_ll_scan_phy *scanp; int rc; scansm = &g_ble_ll_scan_sm; @@ -3697,7 +3697,7 @@ ble_ll_scan_initiator_start(struct hci_create_conn *hcc, #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) scansm->ext_scanning = 0; #endif - scansm->scanp = &scansm->scanp_phys[PHY_UNCODED]; + scansm->scanp = &scansm->scan_phys[PHY_UNCODED]; scansm->scanp_next = NULL; scanp = scansm->scanp; @@ -3726,8 +3726,8 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, struct ble_ll_scan_sm **sm) { struct ble_ll_scan_sm *scansm; - struct ble_ll_scan_params *scanp_uncoded; - struct ble_ll_scan_params *scanp_coded; + struct ble_ll_scan_phy *scanp_uncoded; + struct ble_ll_scan_phy *scanp_coded; struct hci_ext_conn_params *params; int rc; @@ -3739,7 +3739,7 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, if (hcc->init_phy_mask & BLE_PHY_MASK_1M) { params = &hcc->params[0]; - scanp_uncoded = &scansm->scanp_phys[PHY_UNCODED]; + scanp_uncoded = &scansm->scan_phys[PHY_UNCODED]; scanp_uncoded->timing.interval = ble_ll_scan_time_hci_to_ticks(params->scan_itvl); scanp_uncoded->timing.window = ble_ll_scan_time_hci_to_ticks(params->scan_window); @@ -3750,7 +3750,7 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, if (hcc->init_phy_mask & BLE_PHY_MASK_CODED) { params = &hcc->params[2]; - scanp_coded = &scansm->scanp_phys[PHY_CODED]; + scanp_coded = &scansm->scan_phys[PHY_CODED]; scanp_coded->timing.interval = ble_ll_scan_time_hci_to_ticks(params->scan_itvl); scanp_coded->timing.window = ble_ll_scan_time_hci_to_ticks(params->scan_window); @@ -3864,7 +3864,7 @@ static void ble_ll_scan_common_init(void) { struct ble_ll_scan_sm *scansm; - struct ble_ll_scan_params *scanp; + struct ble_ll_scan_phy *scanp; int i; /* Clear state machine in case re-initialized */ @@ -3872,23 +3872,23 @@ ble_ll_scan_common_init(void) memset(scansm, 0, sizeof(struct ble_ll_scan_sm)); /* Clear scan parameters in case re-initialized */ - memset(g_ble_ll_scan_params, 0, sizeof(g_ble_ll_scan_params)); + memset(g_ble_ll_scan_phys, 0, sizeof(g_ble_ll_scan_phys)); /* Initialize scanning window end event */ ble_npl_event_init(&scansm->scan_sched_ev, ble_ll_scan_event_proc, scansm); for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) { /* Set all non-zero default parameters */ - scanp = &g_ble_ll_scan_params[i]; + scanp = &g_ble_ll_scan_phys[i]; scanp->timing.interval = ble_ll_scan_time_hci_to_ticks(BLE_HCI_SCAN_ITVL_DEF); scanp->timing.window = ble_ll_scan_time_hci_to_ticks(BLE_HCI_SCAN_WINDOW_DEF); } - scansm->scanp_phys[PHY_UNCODED].phy = BLE_PHY_1M; + scansm->scan_phys[PHY_UNCODED].phy = BLE_PHY_1M; #if (BLE_LL_SCAN_PHY_NUMBER == 2) - scansm->scanp_phys[PHY_CODED].phy = BLE_PHY_CODED; + scansm->scan_phys[PHY_CODED].phy = BLE_PHY_CODED; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) From e084ef70efdb62ddff25a5f97b024561bf4d8de6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 9 Mar 2021 16:02:50 +0100 Subject: [PATCH 0007/1333] nimble/ll: Simplify scansm parameters 'own_addr_type' and 'scan_filt_policy' are the same for both PHYs so no need to keep them separately for each scanp. Also we already had own_addr_type so usage of this parameter was somewhat inconsistent. --- .../include/controller/ble_ll_scan.h | 4 +- nimble/controller/src/ble_ll_scan.c | 68 +++++++++---------- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index 4ee1aa4b43..8827af4d61 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -83,8 +83,6 @@ struct ble_ll_scan_timing { struct ble_ll_scan_phy { uint8_t phy; - uint8_t own_addr_type; - uint8_t scan_filt_policy; uint8_t configured; uint8_t scan_type; uint8_t scan_chan; @@ -154,7 +152,9 @@ struct ble_ll_scan_pdu_data { struct ble_ll_scan_sm { uint8_t scan_enabled; + uint8_t own_addr_type; + uint8_t scan_filt_policy; uint8_t scan_filt_dups; uint8_t scan_rsp_pending; uint8_t scan_rsp_cons_fails; diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index aef0c12b5d..c7cdcbfa00 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -64,8 +64,13 @@ #define SCAN_VALID_PHY_MASK (BLE_HCI_LE_PHY_1M_PREF_MASK) #endif -/* The scanning parameters set by host */ -static struct ble_ll_scan_phy g_ble_ll_scan_phys[BLE_LL_SCAN_PHY_NUMBER]; +struct ble_ll_scan_params { + uint8_t own_addr_type; + uint8_t scan_filt_policy; + struct ble_ll_scan_phy scan_phys[BLE_LL_SCAN_PHY_NUMBER]; +}; + +static struct ble_ll_scan_params g_ble_ll_scan_params; /* The scanning state machine global object */ static struct ble_ll_scan_sm g_ble_ll_scan_sm; @@ -976,7 +981,7 @@ ble_ll_scan_start(struct ble_ll_scan_sm *scansm, struct ble_ll_sched_item *sch) rc = 0; /* Enable/disable whitelisting */ - if (scanp->scan_filt_policy & 1) { + if (scansm->scan_filt_policy & 1) { ble_ll_whitelist_enable(); } else { ble_ll_whitelist_disable(); @@ -1990,7 +1995,6 @@ static int ble_ll_scan_rx_filter(struct ble_mbuf_hdr *hdr, struct ble_ll_scan_addr_data *addrd) { struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; - struct ble_ll_scan_phy *scanp = scansm->scanp; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) struct ble_ll_aux_data *aux_data = hdr->rxinfo.user_data; @@ -2080,7 +2084,7 @@ ble_ll_scan_rx_filter(struct ble_mbuf_hdr *hdr, struct ble_ll_scan_addr_data *ad } /* Check if scan filter policy allows unresolved RPAs to be processed */ - if (!(scanp->scan_filt_policy & 0x02)) { + if (!(scansm->scan_filt_policy & 0x02)) { return 0; } @@ -2093,7 +2097,7 @@ ble_ll_scan_rx_filter(struct ble_mbuf_hdr *hdr, struct ble_ll_scan_addr_data *ad break; case BLE_LL_ADDR_SUBTYPE_IDENTITY: /* We shall ignore identity in TargetA if we are using RPA */ - if ((scanp->own_addr_type & 0x02) && rl && rl->rl_has_local) { + if ((scansm->own_addr_type & 0x02) && rl && rl->rl_has_local) { return 0; } /* Ignore if not directed to us */ @@ -2115,7 +2119,7 @@ ble_ll_scan_rx_filter(struct ble_mbuf_hdr *hdr, struct ble_ll_scan_addr_data *ad #endif /* Check on WL if required by scan filter policy */ - if (scanp->scan_filt_policy & 0x01) { + if (scansm->scan_filt_policy & 0x01) { if (!ble_ll_whitelist_match(addrd->adv_addr, addrd->adv_addr_type, resolved)) { return 0; } @@ -3276,16 +3280,18 @@ ble_ll_scan_set_scan_params(const uint8_t *cmdbuf, uint8_t len) } /* Store scan parameters */ - scanp = &g_ble_ll_scan_phys[PHY_UNCODED]; + g_ble_ll_scan_params.own_addr_type = cmd->own_addr_type; + g_ble_ll_scan_params.scan_filt_policy = cmd->filter_policy; + + scanp = &g_ble_ll_scan_params.scan_phys[PHY_UNCODED]; scanp->configured = 1; scanp->scan_type = cmd->scan_type; scanp->timing.interval = ble_ll_scan_time_hci_to_ticks(scan_itvl); scanp->timing.window = ble_ll_scan_time_hci_to_ticks(scan_window); - scanp->scan_filt_policy = cmd->filter_policy; - scanp->own_addr_type = cmd->own_addr_type; #if (BLE_LL_SCAN_PHY_NUMBER == 2) - g_ble_ll_scan_phys[PHY_CODED].configured = 0; + scanp = &g_ble_ll_scan_params.scan_phys[PHY_CODED]; + scanp->configured = 0; #endif return 0; @@ -3342,17 +3348,11 @@ ble_ll_set_ext_scan_params(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } - coded->own_addr_type = cmd->own_addr_type; - uncoded->own_addr_type = cmd->own_addr_type; - /* Check scanner filter policy */ if (cmd->filter_policy > BLE_HCI_SCAN_FILT_MAX) { return BLE_ERR_INV_HCI_CMD_PARMS; } - coded->scan_filt_policy = cmd->filter_policy; - uncoded->scan_filt_policy = cmd->filter_policy; - /* Check if no reserved bits in PHYS are set and that at least one valid PHY * is set. */ @@ -3420,7 +3420,10 @@ ble_ll_set_ext_scan_params(const uint8_t *cmdbuf, uint8_t len) } } - memcpy(g_ble_ll_scan_phys, new_params, sizeof(new_params)); + g_ble_ll_scan_params.own_addr_type = cmd->own_addr_type; + g_ble_ll_scan_params.scan_filt_policy = cmd->filter_policy; + + memcpy(g_ble_ll_scan_params.scan_phys, new_params, sizeof(new_params)); return 0; } @@ -3575,9 +3578,12 @@ ble_ll_scan_set_enable(uint8_t enable, uint8_t filter_dups, uint16_t period, scansm->scanp = NULL; scansm->scanp_next = NULL; + scansm->own_addr_type = g_ble_ll_scan_params.own_addr_type; + scansm->scan_filt_policy = g_ble_ll_scan_params.scan_filt_policy; + for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) { scanp_phy = &scansm->scan_phys[i]; - scanp = &g_ble_ll_scan_phys[i]; + scanp = &g_ble_ll_scan_params.scan_phys[i]; if (!scanp->configured) { continue; @@ -3586,15 +3592,9 @@ ble_ll_scan_set_enable(uint8_t enable, uint8_t filter_dups, uint16_t period, scanp_phy->configured = scanp->configured; scanp_phy->scan_type = scanp->scan_type; scanp_phy->timing = scanp->timing; - scanp_phy->scan_filt_policy = scanp->scan_filt_policy; - scanp_phy->own_addr_type = scanp->own_addr_type; if (!scansm->scanp) { scansm->scanp = scanp_phy; - /* Take own_addr_type from the first configured PHY. - * Note: All configured PHYs shall have the same own_addr_type - */ - scansm->own_addr_type = scanp_phy->own_addr_type; } else { scansm->scanp_next = scanp_phy; } @@ -3608,6 +3608,7 @@ ble_ll_scan_set_enable(uint8_t enable, uint8_t filter_dups, uint16_t period, if (!scansm->scanp) { scansm->scanp = &scansm->scan_phys[PHY_UNCODED]; scansm->own_addr_type = BLE_ADDR_PUBLIC; + scansm->scan_filt_policy = BLE_HCI_SCAN_FILT_NO_WL; scanp_phy = scansm->scanp; scanp_phy->configured = 1; @@ -3616,8 +3617,6 @@ ble_ll_scan_set_enable(uint8_t enable, uint8_t filter_dups, uint16_t period, ble_ll_scan_time_hci_to_ticks(BLE_HCI_SCAN_ITVL_DEF); scanp_phy->timing.window = ble_ll_scan_time_hci_to_ticks(BLE_HCI_SCAN_WINDOW_DEF); - scanp_phy->scan_filt_policy = BLE_HCI_SCAN_FILT_NO_WL; - scanp_phy->own_addr_type = BLE_ADDR_PUBLIC; } rc = ble_ll_scan_sm_start(scansm); @@ -3671,11 +3670,9 @@ ble_ll_scan_can_chg_whitelist(void) { int rc; struct ble_ll_scan_sm *scansm; - struct ble_ll_scan_phy *scanp; scansm = &g_ble_ll_scan_sm; - scanp = scansm->scanp; - if (scansm->scan_enabled && (scanp->scan_filt_policy & 1)) { + if (scansm->scan_enabled && (scansm->scan_filt_policy & 1)) { rc = 0; } else { rc = 1; @@ -3694,6 +3691,7 @@ ble_ll_scan_initiator_start(struct hci_create_conn *hcc, scansm = &g_ble_ll_scan_sm; scansm->own_addr_type = hcc->own_addr_type; + scansm->scan_filt_policy = hcc->filter_policy; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) scansm->ext_scanning = 0; #endif @@ -3701,7 +3699,6 @@ ble_ll_scan_initiator_start(struct hci_create_conn *hcc, scansm->scanp_next = NULL; scanp = scansm->scanp; - scanp->scan_filt_policy = hcc->filter_policy; scanp->timing.interval = ble_ll_scan_time_hci_to_ticks(hcc->scan_itvl); scanp->timing.window = ble_ll_scan_time_hci_to_ticks(hcc->scan_window); scanp->scan_type = BLE_SCAN_TYPE_INITIATE; @@ -3733,6 +3730,7 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, scansm = &g_ble_ll_scan_sm; scansm->own_addr_type = hcc->own_addr_type; + scansm->scan_filt_policy = hcc->filter_policy; scansm->scanp = NULL; scansm->scanp_next = NULL; scansm->ext_scanning = 1; @@ -3744,7 +3742,6 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, scanp_uncoded->timing.interval = ble_ll_scan_time_hci_to_ticks(params->scan_itvl); scanp_uncoded->timing.window = ble_ll_scan_time_hci_to_ticks(params->scan_window); scanp_uncoded->scan_type = BLE_SCAN_TYPE_INITIATE; - scanp_uncoded->scan_filt_policy = hcc->filter_policy; scansm->scanp = scanp_uncoded; } @@ -3755,7 +3752,6 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, scanp_coded->timing.interval = ble_ll_scan_time_hci_to_ticks(params->scan_itvl); scanp_coded->timing.window = ble_ll_scan_time_hci_to_ticks(params->scan_window); scanp_coded->scan_type = BLE_SCAN_TYPE_INITIATE; - scanp_coded->scan_filt_policy = hcc->filter_policy; if (scansm->scanp) { scansm->scanp_next = scanp_coded; } else { @@ -3857,7 +3853,7 @@ ble_ll_scan_get_pdu_data(void) int ble_ll_scan_whitelist_enabled(void) { - return g_ble_ll_scan_sm.scanp->scan_filt_policy & 1; + return g_ble_ll_scan_sm.scan_filt_policy & 1; } static void @@ -3872,14 +3868,14 @@ ble_ll_scan_common_init(void) memset(scansm, 0, sizeof(struct ble_ll_scan_sm)); /* Clear scan parameters in case re-initialized */ - memset(g_ble_ll_scan_phys, 0, sizeof(g_ble_ll_scan_phys)); + memset(&g_ble_ll_scan_params, 0, sizeof(g_ble_ll_scan_params)); /* Initialize scanning window end event */ ble_npl_event_init(&scansm->scan_sched_ev, ble_ll_scan_event_proc, scansm); for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) { /* Set all non-zero default parameters */ - scanp = &g_ble_ll_scan_phys[i]; + scanp = &g_ble_ll_scan_params.scan_phys[i]; scanp->timing.interval = ble_ll_scan_time_hci_to_ticks(BLE_HCI_SCAN_ITVL_DEF); scanp->timing.window = From eed4389851fcf96922a2e429376808f2dfddc912 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 20 Mar 2021 17:46:28 +0100 Subject: [PATCH 0008/1333] nimble/ll: Decouple aux scanner from main scansm This change moves handling of scanning aux PDUs to separate unit and thus simplifies code in ble_ll_scan. Basically, once ADV_EXT_IND is scanned by main scansm, scanning aux PDUs is running as a separate LL state and is handled by separate code. Handling on aux PDUs was also refactored a bit, more importantly we no longer need ref/unref for aux_data which caused lots of issues in the past - aux_data is always only allocated in ISR context when ADV_EXT_IND with AuxPtr is received and then can be freed only in LL context if no subsequent scan is scheduled. In addition, some changes were done to filtering routines so that now filtering and address resolution is done only once for each scanned ext advertising event, i.e. either on ADV_EXT_IND or AUX_ADV_IND. There is still some legacy code for aux scanner left since it's used by initiator role. This will be eventually removed once initiator is refactored to use the same code as generic scanner. --- nimble/controller/include/controller/ble_ll.h | 2 + .../include/controller/ble_ll_resolv.h | 6 + .../include/controller/ble_ll_scan.h | 33 + .../include/controller/ble_ll_scan_aux.h | 54 + .../include/controller/ble_ll_sched.h | 4 + .../include/controller/ble_ll_sync.h | 4 +- nimble/controller/src/ble_ll.c | 27 + nimble/controller/src/ble_ll_scan.c | 1094 ++---------- nimble/controller/src/ble_ll_scan_aux.c | 1555 +++++++++++++++++ nimble/controller/src/ble_ll_sched.c | 68 + nimble/controller/src/ble_ll_sync.c | 32 +- nimble/controller/syscfg.yml | 6 + 12 files changed, 1958 insertions(+), 927 deletions(-) create mode 100644 nimble/controller/include/controller/ble_ll_scan_aux.h create mode 100644 nimble/controller/src/ble_ll_scan_aux.c diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 24d7db3003..4a832c6558 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -220,6 +220,7 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats; #define BLE_LL_STATE_CONNECTION (4) #define BLE_LL_STATE_DTM (5) #define BLE_LL_STATE_SYNC (6) +#define BLE_LL_STATE_SCAN_AUX (7) /* LL Features */ #define BLE_LL_FEAT_LE_ENCRYPTION (0x0000000001) @@ -354,6 +355,7 @@ struct ble_dev_addr #define BLE_LL_EXT_ADV_FLAGS_SIZE (1) #define BLE_LL_EXT_ADV_ADVA_SIZE (6) #define BLE_LL_EXT_ADV_TARGETA_SIZE (6) +#define BLE_LL_EXT_ADV_CTE_INFO_SIZE (1) #define BLE_LL_EXT_ADV_DATA_INFO_SIZE (2) #define BLE_LL_EXT_ADV_AUX_PTR_SIZE (3) #define BLE_LL_EXT_ADV_SYNC_INFO_SIZE (18) diff --git a/nimble/controller/include/controller/ble_ll_resolv.h b/nimble/controller/include/controller/ble_ll_resolv.h index 228e0a3703..b9ca7fd387 100644 --- a/nimble/controller/include/controller/ble_ll_resolv.h +++ b/nimble/controller/include/controller/ble_ll_resolv.h @@ -72,6 +72,12 @@ int ble_ll_resolv_local_addr_rd(const uint8_t *cmdbuf, uint8_t len, struct ble_ll_resolv_entry * ble_ll_resolv_list_find(const uint8_t *addr, uint8_t addr_type); +static inline int8_t +ble_ll_resolv_get_idx(struct ble_ll_resolv_entry *rl) +{ + return rl - g_ble_ll_resolv_list; +} + /* Returns true if address resolution is enabled */ uint8_t ble_ll_resolv_enabled(void); diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index 8827af4d61..d3097f2b11 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -149,6 +149,20 @@ struct ble_ll_scan_pdu_data { uint8_t adva[BLE_DEV_ADDR_LEN]; }; +struct ble_ll_scan_addr_data { + uint8_t *adva; + uint8_t *targeta; + uint8_t *adv_addr; + uint8_t adva_type : 1; + uint8_t targeta_type : 1; + uint8_t adv_addr_type : 1; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + uint8_t adva_resolved : 1; + uint8_t targeta_resolved : 1; + int8_t rpa_index; +#endif +}; + struct ble_ll_scan_sm { uint8_t scan_enabled; @@ -286,6 +300,25 @@ void ble_ll_scan_end_adv_evt(struct ble_ll_aux_data *aux_data); /* Called to halt currently running scan */ void ble_ll_scan_halt(void); +uint8_t *ble_ll_get_scan_nrpa(void); +uint8_t ble_ll_scan_get_own_addr_type(void); +uint8_t ble_ll_scan_get_filt_policy(void); +uint8_t ble_ll_scan_get_filt_dups(void); +uint8_t ble_ll_scan_backoff_kick(void); +void ble_ll_scan_backoff_update(int success); + +int ble_ll_scan_dup_check_ext(uint8_t addr_type, uint8_t *addr, bool has_aux, + uint16_t adi); +int ble_ll_scan_dup_update_ext(uint8_t addr_type, uint8_t *addr, bool has_aux, + uint16_t adi); +int ble_ll_scan_have_rxd_scan_rsp(uint8_t *addr, uint8_t txadd, uint8_t ext_adv, + uint16_t adi); +void ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t txadd, uint8_t ext_adv, + uint16_t adi); + +int ble_ll_scan_rx_filter(uint8_t own_addr_type, uint8_t scan_filt_policy, + struct ble_ll_scan_addr_data *addrd, uint8_t *scan_ok); + #ifdef __cplusplus } #endif diff --git a/nimble/controller/include/controller/ble_ll_scan_aux.h b/nimble/controller/include/controller/ble_ll_scan_aux.h new file mode 100644 index 0000000000..c7d63b8449 --- /dev/null +++ b/nimble/controller/include/controller/ble_ll_scan_aux.h @@ -0,0 +1,54 @@ +/* + * 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_BLE_LL_SCAN_AUX_ +#define H_BLE_LL_SCAN_AUX_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + +struct ble_ll_scan_aux_data; + +void ble_ll_scan_aux_init(void); +int ble_ll_scan_aux_sched(struct ble_ll_scan_aux_data *aux, uint32_t pdu_time, + uint8_t pdu_time_rem, uint32_t aux_ptr); +int ble_ll_scan_aux_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *rxhdr); +int ble_ll_scan_aux_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok); +void ble_ll_scan_aux_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr); + +void ble_ll_scan_aux_break(struct ble_ll_scan_aux_data *aux); +void ble_ll_scan_aux_wfr_timer_exp(void); +void ble_ll_scan_aux_halt(void); +void ble_ll_scan_aux_sched_remove(struct ble_ll_sched_item *sch); + +int ble_ll_scan_aux_rx_isr_end_on_ext(struct ble_ll_scan_sm *scansm, + struct os_mbuf *rxpdu); +void ble_ll_scan_aux_pkt_in_on_ext(struct os_mbuf *rxpdu, + struct ble_mbuf_hdr *rxhdr); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* H_BLE_LL_SCAN_AUX_ */ diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index a614cf0905..96834bb075 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -71,6 +71,7 @@ extern uint8_t g_ble_ll_sched_offset_ticks; #define BLE_LL_SCHED_TYPE_DTM (5) #define BLE_LL_SCHED_TYPE_PERIODIC (6) #define BLE_LL_SCHED_TYPE_SYNC (7) +#define BLE_LL_SCHED_TYPE_SCAN_AUX (8) /* Return values for schedule callback. */ #define BLE_LL_SCHED_STATE_RUNNING (0) @@ -200,6 +201,9 @@ int ble_ll_sched_aux_scan(struct ble_mbuf_hdr *ble_hdr, struct ble_ll_aux_data *aux_scan); int ble_ll_sched_scan_req_over_aux_ptr(uint32_t chan, uint8_t phy_mode); + +int ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time, + uint8_t pdu_time_rem, uint32_t offset_us); #endif /* Stop the scheduler */ diff --git a/nimble/controller/include/controller/ble_ll_sync.h b/nimble/controller/include/controller/ble_ll_sync.h index 712af6dffc..8002d2a317 100644 --- a/nimble/controller/include/controller/ble_ll_sync.h +++ b/nimble/controller/include/controller/ble_ll_sync.h @@ -30,6 +30,7 @@ extern "C" { #endif +struct ble_ll_scan_addr_data; struct ble_ll_sync_sm; int ble_ll_sync_create(const uint8_t *cmdbuf, uint8_t len); @@ -48,8 +49,7 @@ void ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, uint16_t max_skip, uint32_t sync_timeout); void ble_ll_sync_transfer_disconnected(struct ble_ll_conn_sm *connsm); -void ble_ll_sync_info_event(const uint8_t *addr, uint8_t addr_type, - int rpa_index, uint8_t sid, +void ble_ll_sync_info_event(struct ble_ll_scan_addr_data *addrd, uint8_t sid, struct ble_mbuf_hdr *rxhdr, const uint8_t *syncinfo); diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index cf83b79c38..8c7095a7e1 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -37,6 +37,7 @@ #include "controller/ble_ll_adv.h" #include "controller/ble_ll_sched.h" #include "controller/ble_ll_scan.h" +#include "controller/ble_ll_scan_aux.h" #include "controller/ble_ll_hci.h" #include "controller/ble_ll_whitelist.h" #include "controller/ble_ll_resolv.h" @@ -688,6 +689,11 @@ ble_ll_wfr_timer_exp(void *arg) case BLE_LL_STATE_SYNC: ble_ll_sync_wfr_timer_exp(); break; +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + case BLE_LL_STATE_SCAN_AUX: + ble_ll_scan_aux_wfr_timer_exp(); + break; #endif default: break; @@ -848,6 +854,11 @@ ble_ll_rx_pkt_in(void) case BLE_LL_STATE_SYNC: ble_ll_sync_rx_pkt_in(m, ble_hdr); break; +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + case BLE_LL_STATE_SCAN_AUX: + ble_ll_scan_aux_rx_pkt_in(m, ble_hdr); + break; #endif default: /* Any other state should never occur */ @@ -984,6 +995,11 @@ ble_ll_rx_start(uint8_t *rxbuf, uint8_t chan, struct ble_mbuf_hdr *rxhdr) case BLE_LL_STATE_SYNC: rc = ble_ll_sync_rx_isr_start(pdu_type, rxhdr); break; +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + case BLE_LL_STATE_SCAN_AUX: + rc = ble_ll_scan_aux_rx_isr_start(pdu_type, rxhdr); + break; #endif default: /* Should not be in this state! */ @@ -1109,6 +1125,17 @@ ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) case BLE_LL_STATE_INITIATING: rc = ble_ll_init_rx_isr_end(rxbuf, crcok, rxhdr); break; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + case BLE_LL_STATE_SCAN_AUX: + if (!badpkt) { + rxpdu = ble_ll_rxpdu_alloc(len + BLE_LL_PDU_HDR_LEN); + if (rxpdu) { + ble_phy_rxpdu_copy(rxbuf, rxpdu); + } + } + rc = ble_ll_scan_aux_rx_isr_end(rxpdu, crcok); + break; +#endif default: rc = -1; STATS_INC(ble_ll_stats, bad_ll_state); diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index c7cdcbfa00..cf264b0ab0 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -32,8 +32,10 @@ #include "controller/ble_hw.h" #include "controller/ble_ll.h" #include "controller/ble_ll_sched.h" -#include "controller/ble_ll_adv.h" #include "controller/ble_ll_scan.h" +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +#include "controller/ble_ll_scan_aux.h" +#endif #include "controller/ble_ll_hci.h" #include "controller/ble_ll_whitelist.h" #include "controller/ble_ll_resolv.h" @@ -75,24 +77,6 @@ static struct ble_ll_scan_params g_ble_ll_scan_params; /* The scanning state machine global object */ static struct ble_ll_scan_sm g_ble_ll_scan_sm; -struct ble_ll_ext_adv_hdr -{ - uint8_t mode; - uint8_t hdr_len; - uint8_t hdr[0]; -}; - -struct ble_ll_scan_addr_data { - bool adva_present; - uint8_t adva_type; - uint8_t *adva; - uint8_t targeta_type; - uint8_t *targeta; - uint8_t adv_addr_type; - uint8_t *adv_addr; - struct ble_ll_resolv_entry *rl; -}; - /* * Structure used to store advertisers. This is used to limit sending scan * requests to the same advertiser and also to filter duplicate events sent @@ -319,17 +303,66 @@ ble_ll_scan_refresh_nrpa(struct ble_ll_scan_sm *scansm) scansm->scan_nrpa_timer = now + ble_ll_resolv_get_rpa_tmo(); } } + +uint8_t * +ble_ll_get_scan_nrpa(void) +{ + struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; + + ble_ll_scan_refresh_nrpa(scansm); + + return scansm->scan_nrpa; +} #endif +uint8_t +ble_ll_scan_get_own_addr_type(void) +{ + return g_ble_ll_scan_sm.own_addr_type; +} + +uint8_t +ble_ll_scan_get_filt_policy(void) +{ + return g_ble_ll_scan_sm.scan_filt_policy; +} + +uint8_t +ble_ll_scan_get_filt_dups(void) +{ + return g_ble_ll_scan_sm.scan_filt_dups; +} + +uint8_t +ble_ll_scan_backoff_kick(void) +{ + struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; + + if (scansm->backoff_count > 0) { + scansm->backoff_count--; + } + + return scansm->backoff_count; +} + +void +ble_ll_scan_backoff_update(int success) +{ + struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; + + ble_ll_scan_req_backoff(scansm, success); +} + static void ble_ll_scan_req_pdu_prepare(struct ble_ll_scan_sm *scansm, const uint8_t *adv_addr, uint8_t adv_addr_type, - struct ble_ll_resolv_entry *rl) + int8_t rpa_index) { uint8_t hdr_byte; struct ble_ll_scan_pdu_data *pdu_data; uint8_t *scana; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + struct ble_ll_resolv_entry *rl; uint8_t rpa[BLE_DEV_ADDR_LEN]; #endif @@ -351,6 +384,12 @@ ble_ll_scan_req_pdu_prepare(struct ble_ll_scan_sm *scansm, #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) if (scansm->own_addr_type & 0x02) { + if (rpa_index >= 0) { + rl = &g_ble_ll_resolv_list[rpa_index]; + } else { + rl = NULL; + } + /* * If device is on RL and we have local IRK, we use RPA generated using * that IRK as ScanA. Otherwise we use NRPA as ScanA to prevent our @@ -436,74 +475,9 @@ ble_ll_scan_get_ext_adv_report(struct ext_adv_report *copy_from) return hci_ev; } -static void -ble_ll_scan_send_truncated(struct ble_ll_aux_data *aux_data) -{ - struct ble_hci_ev_le_subev_ext_adv_rpt *ev; - struct ext_adv_report *report; - struct ble_hci_ev *hci_ev; - - if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) { - return; - } - - BLE_LL_ASSERT(aux_data); - - /* No need to send if we did not send any report or sent truncated already */ - if (!(aux_data->flags_ll & BLE_LL_AUX_FLAG_HCI_SENT_ANY) || - (aux_data->flags_ll & BLE_LL_AUX_FLAG_HCI_SENT_TRUNCATED)) { - return; - } - - BLE_LL_ASSERT(aux_data->evt); - hci_ev = aux_data->evt; - aux_data->evt = NULL; - - hci_ev->length = sizeof(*ev) + sizeof(*report); - - ev = (void *) hci_ev->data; - report = ev->reports; - - report->data_len = 0; - - report->evt_type = aux_data->evt_type; - report->evt_type |= BLE_HCI_ADV_DATA_STATUS_TRUNCATED; - - if (aux_data->flags & BLE_LL_AUX_HAS_ADVA) { - memcpy(report->addr, aux_data->adva, 6); - report->addr_type = aux_data->adva_type; - } - - if (aux_data->flags & BLE_LL_AUX_HAS_TARGETA) { - memcpy(report->dir_addr, aux_data->targeta, 6); - report->dir_addr_type = aux_data->targeta_type; - } - - report->sid = aux_data->adi >> 12; - ble_ll_hci_event_send(hci_ev); - - aux_data->flags_ll |= BLE_LL_AUX_FLAG_SCAN_ERROR; - aux_data->flags_ll |= BLE_LL_AUX_FLAG_HCI_SENT_ANY; - aux_data->flags_ll |= BLE_LL_AUX_FLAG_HCI_SENT_TRUNCATED; -} - -static int -ble_ll_scan_get_adi(struct ble_ll_aux_data *aux_data, uint16_t *adi) -{ - if (!aux_data || !(aux_data->flags & BLE_LL_AUX_HAS_ADI)) { - return -1; - } - - *adi = aux_data->adi; - - return 0; -} - void ble_ll_scan_end_adv_evt(struct ble_ll_aux_data *aux_data) { - /* Make sure we send report with 'truncated' data state if needed */ - ble_ll_scan_send_truncated(aux_data); } #endif @@ -544,7 +518,7 @@ ble_ll_scan_halt(void) * * @return int 0: have not received a scan response; 1 otherwise. */ -static int +int ble_ll_scan_have_rxd_scan_rsp(uint8_t *addr, uint8_t txadd, uint8_t ext_adv, uint16_t adi) { @@ -588,7 +562,7 @@ ble_ll_scan_have_rxd_scan_rsp(uint8_t *addr, uint8_t txadd, } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -static void +void ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t txadd, uint8_t ext_adv, uint16_t adi) { @@ -867,8 +841,8 @@ ble_ll_scan_send_adv_report(uint8_t pdu_type, hdr->rxinfo.rssi, adv_data_len, om, inita, inita_type); - goto done; - } +goto done; +} #endif if (subev == BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT) { @@ -1154,6 +1128,7 @@ ble_ll_scan_sm_stop(int chk_disable) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (scansm->ext_scanning) { + ble_ll_sched_rmv_elem_type(BLE_LL_SCHED_TYPE_SCAN_AUX, ble_ll_scan_aux_sched_remove); ble_ll_scan_clean_cur_aux_data(); ble_ll_sched_rmv_elem_type(BLE_LL_SCHED_TYPE_AUX_SCAN, ble_ll_scan_sched_remove); scansm->ext_scanning = 0; @@ -1388,6 +1363,7 @@ ble_ll_scan_event_proc(struct ble_npl_event *ev) case BLE_LL_STATE_ADV: case BLE_LL_STATE_CONNECTION: case BLE_LL_STATE_SYNC: + case BLE_LL_STATE_SCAN_AUX: start_scan = false; break; case BLE_LL_STATE_INITIATING: @@ -1556,16 +1532,6 @@ ble_ll_ext_scan_parse_aux_ptr(struct ble_ll_aux_data *aux_data, uint8_t *buf) return 0; } -static void -ble_ll_ext_scan_parse_adv_info(struct ext_adv_report *report, const uint8_t *buf) -{ - uint16_t adv_info = get_le16(buf); - - /* TODO Use DID */ - - report->sid = (adv_info >> 12); -} - /** * ble_ll_scan_update_aux_data * @@ -1699,139 +1665,6 @@ ble_ll_scan_update_aux_data(struct ble_mbuf_hdr *ble_hdr, uint8_t *rxbuf, (aux_data->flags_isr & BLE_LL_AUX_FLAG_SCAN_ERROR); } -/** - * Called when a receive ADV_EXT PDU has ended. - * - * Context: Interrupt - * - * @return int - * < 0 Error - * >= 0: Success (number of bytes left in PDU) - * - */ -static int -ble_ll_scan_parse_ext_hdr(struct os_mbuf *om, - const uint8_t *adva, uint8_t adva_type, - const uint8_t *inita, uint8_t inita_type, - struct ble_mbuf_hdr *ble_hdr, - struct ext_adv_report *report) -{ - uint8_t pdu_len; - uint8_t ext_hdr_len; - uint8_t ext_hdr_flags; - uint8_t *ext_hdr; - uint8_t *rxbuf = om->om_data; - int i = 1; - struct ble_ll_scan_sm *scansm; - struct ble_ll_aux_data *aux_data = ble_hdr->rxinfo.user_data; - - BLE_LL_ASSERT(report); - - scansm = &g_ble_ll_scan_sm; - - if (!scansm->ext_scanning) { - /* Ignore ext adv if host does not want it*/ - return -1; - } - - pdu_len = rxbuf[1]; - if (pdu_len == 0) { - return -1; - } - - report->evt_type = rxbuf[2] >> 6; - if ( report->evt_type > BLE_LL_EXT_ADV_MODE_SCAN) { - return -1; - } - - if (BLE_MBUF_HDR_SCAN_RSP_RXD(ble_hdr)) { - report->evt_type |= BLE_HCI_ADV_SCAN_RSP_MASK; - } - - ext_hdr_len = rxbuf[2] & 0x3F; - os_mbuf_adj(om, 3); - - ext_hdr_flags = rxbuf[3]; - ext_hdr = &rxbuf[4]; - - if (ext_hdr_len) { - i = 0; - if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_ADVA_BIT)) { - i += BLE_LL_EXT_ADV_ADVA_SIZE; - } - - if (adva) { - memcpy(report->addr, adva, 6); - report->addr_type = adva_type; - } - - if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_TARGETA_BIT)) { - i += BLE_LL_EXT_ADV_TARGETA_SIZE; - } - - if (inita) { - memcpy(report->dir_addr, inita, 6); - report->dir_addr_type = inita_type; - report->evt_type |= BLE_HCI_ADV_DIRECT_MASK; - } - - if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_CTE_INFO_BIT)) { - /* Just skip it for now*/ - i += 1; - } - - if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) { - ble_ll_ext_scan_parse_adv_info(report, (ext_hdr + i)); - i += BLE_LL_EXT_ADV_DATA_INFO_SIZE; - } else if (report->evt_type & BLE_HCI_ADV_SCAN_RSP_MASK) { - report->sid = (aux_data->adi >> 12); - } - - /* In this point of time we don't want to care about aux ptr */ - if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { - i += BLE_LL_EXT_ADV_AUX_PTR_SIZE; - } - - if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_SYNC_INFO_BIT)) { - report->periodic_itvl = get_le16(ext_hdr + i + 2); - i += BLE_LL_EXT_ADV_SYNC_INFO_SIZE; - } - - if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_TX_POWER_BIT)) { - report->tx_power = *(ext_hdr + i); - i += BLE_LL_EXT_ADV_TX_POWER_SIZE; - } - - /* TODO Handle ACAD if needed */ - } - - /* In the event we need information on primary and secondary PHY used during - * advertising. - */ - if (!aux_data) { - report->pri_phy = ble_hdr->rxinfo.phy; - goto done; - } - - report->sec_phy = aux_data->aux_phy; - report->pri_phy = aux_data->aux_primary_phy; - - if (ext_hdr_len) { - /* Adjust mbuf to contain advertising data only */ - os_mbuf_adj(om, ext_hdr_len); - } - - /* Let us first keep update event type in aux data. - * Note that in aux chain and aux scan response packets - * we do miss original event type, which we need for advertising report. - */ - aux_data->evt_type |= report->evt_type; - report->evt_type = aux_data->evt_type; - -done: - return pdu_len - ext_hdr_len - 1; -} - static int ble_ll_scan_get_addr_from_ext_adv(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr, uint8_t **addr, uint8_t *addr_type, @@ -1968,8 +1801,6 @@ ble_ll_scan_get_addr_data_from_legacy(uint8_t pdu_type, uint8_t *rxbuf, { BLE_LL_ASSERT(pdu_type < BLE_ADV_PDU_TYPE_ADV_EXT_IND); - addrd->adva_present = true; - addrd->adva = rxbuf + BLE_LL_PDU_HDR_LEN; addrd->adva_type = ble_ll_get_addr_type(rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK); @@ -1982,79 +1813,45 @@ ble_ll_scan_get_addr_data_from_legacy(uint8_t pdu_type, uint8_t *rxbuf, } } -/* - * Matches incoming PDU using scan filter policy and whitelist, if applicable. - * This will also resolve addresses and update flags/fields in header and - * addr_data as needed. - * - * @return 0 = no match - * 1 = match - * 2 = match, but do not scan - */ -static int -ble_ll_scan_rx_filter(struct ble_mbuf_hdr *hdr, struct ble_ll_scan_addr_data *addrd) +int +ble_ll_scan_rx_filter(uint8_t own_addr_type, uint8_t scan_filt_policy, + struct ble_ll_scan_addr_data *addrd, uint8_t *scan_ok) { - struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - struct ble_ll_aux_data *aux_data = hdr->rxinfo.user_data; -#endif - struct ble_mbuf_hdr_rxinfo *rxinfo = &hdr->rxinfo; struct ble_ll_resolv_entry *rl = NULL; #endif bool scan_req_allowed = true; - int resolved = 0; + bool resolved; - /* Use AdvA as initial advertiser address, we may try to resolve it later */ + /* Note: caller is expected to fill adva, targeta and rpa_index in addrd */ + + /* Use AdvA as initial advertiser address, we may change it if resolved */ addrd->adv_addr = addrd->adva; addrd->adv_addr_type = addrd->adva_type; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - /* By default, assume AdvA is not resolved */ - rxinfo->rpa_index = -1; + addrd->adva_resolved = 0; + addrd->targeta_resolved = 0; + + BLE_LL_ASSERT((addrd->rpa_index < 0) || + (ble_ll_addr_subtype(addrd->adva, addrd->adva_type) == + BLE_LL_ADDR_SUBTYPE_RPA)); switch (ble_ll_addr_subtype(addrd->adva, addrd->adva_type)) { case BLE_LL_ADDR_SUBTYPE_RPA: - /* - * Only resolve if packet actually contained AdvA. - * In extended advertising PDUs we may use RL index from a PDU that - * already had AdvA (e.g. ADV_EXT_IND in case of AUX_ADV_IND without - * AdvA). In legacy advertising PDUs we always need to resolve AdvA. - */ - if (addrd->adva_present) { - rxinfo->rpa_index = ble_hw_resolv_list_match(); - } else { -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - BLE_LL_ASSERT(aux_data); - rxinfo->rpa_index = aux_data->rpa_index; -#else - BLE_LL_ASSERT(false); - rxinfo->rpa_index = -1; -#endif - } - - if (rxinfo->rpa_index < 0) { + if (addrd->rpa_index < 0) { break; } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - if (aux_data) { - aux_data->rpa_index = rxinfo->rpa_index; - } -#endif + addrd->adva_resolved = 1; /* Use resolved identity address as advertiser address */ - rl = &g_ble_ll_resolv_list[rxinfo->rpa_index]; + rl = &g_ble_ll_resolv_list[addrd->rpa_index]; addrd->adv_addr = rl->rl_identity_addr; addrd->adv_addr_type = rl->rl_addr_type; - addrd->rl = rl; - - rxinfo->flags |= BLE_MBUF_HDR_F_RESOLVED; - resolved = 1; break; case BLE_LL_ADDR_SUBTYPE_IDENTITY: - /* - * If AdvA is an identity address, we need to check if that device was + /* If AdvA is an identity address, we need to check if that device was * added to RL in order to use proper privacy mode. */ rl = ble_ll_resolv_list_find(addrd->adva, addrd->adva_type); @@ -2062,12 +1859,12 @@ ble_ll_scan_rx_filter(struct ble_mbuf_hdr *hdr, struct ble_ll_scan_addr_data *ad break; } - addrd->rl = rl; - /* Ignore device if using network privacy mode and it has IRK */ if ((rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) && rl->rl_has_peer) { - return 0; + return -1; } + + addrd->rpa_index = ble_ll_resolv_get_idx(rl); break; default: /* NRPA goes through filtering policy directly */ @@ -2079,30 +1876,29 @@ ble_ll_scan_rx_filter(struct ble_mbuf_hdr *hdr, struct ble_ll_scan_addr_data *ad case BLE_LL_ADDR_SUBTYPE_RPA: /* Check if TargetA can be resolved using the same RL entry as AdvA */ if (rl && ble_ll_resolv_rpa(addrd->targeta, rl->rl_local_irk)) { - rxinfo->flags |= BLE_MBUF_HDR_F_TARGETA_RESOLVED; + addrd->targeta_resolved = 1; break; } /* Check if scan filter policy allows unresolved RPAs to be processed */ - if (!(scansm->scan_filt_policy & 0x02)) { - return 0; + if (!(scan_filt_policy & 0x02)) { + return -2; } - /* - * We will notify host as requited by scan policy, but make sure we - * do not send scan request since we do not know if this is directed - * to us. + /* Do not send scan request even if scan policy allows unresolved + * RPAs - we do not know if this one if directed to us. */ scan_req_allowed = false; break; case BLE_LL_ADDR_SUBTYPE_IDENTITY: /* We shall ignore identity in TargetA if we are using RPA */ - if ((scansm->own_addr_type & 0x02) && rl && rl->rl_has_local) { - return 0; + if ((own_addr_type & 0x02) && rl && rl->rl_has_local) { + return -1; } + /* Ignore if not directed to us */ if (!ble_ll_is_our_devaddr(addrd->targeta, addrd->targeta_type)) { - return 0; + return -1; } break; default: @@ -2110,85 +1906,69 @@ ble_ll_scan_rx_filter(struct ble_mbuf_hdr *hdr, struct ble_ll_scan_addr_data *ad break; } } + + resolved = addrd->adva_resolved; #else /* Ignore if not directed to us */ if (addrd->targeta && !ble_ll_is_our_devaddr(addrd->targeta, addrd->targeta_type)) { - return 0; + return -1; } + + resolved = false; #endif /* Check on WL if required by scan filter policy */ - if (scansm->scan_filt_policy & 0x01) { - if (!ble_ll_whitelist_match(addrd->adv_addr, addrd->adv_addr_type, resolved)) { - return 0; - } + if ((scan_filt_policy & 0x01) && + !ble_ll_whitelist_match(addrd->adv_addr, addrd->adv_addr_type, + resolved)) { + return -2; + } + + if (scan_ok) { + *scan_ok = scan_req_allowed; } - return scan_req_allowed ? 1 : 2; + return 0; } static int -ble_ll_scan_rx_isr_on_legacy(uint8_t pdu_type, uint8_t *rxbuf, - struct ble_mbuf_hdr *hdr, - struct ble_ll_scan_addr_data *addrd) +ble_ll_scan_rx_isr_on_adv(uint8_t pdu_type, uint8_t *rxbuf, + struct ble_mbuf_hdr *hdr, + struct ble_ll_scan_addr_data *addrd) { struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; struct ble_ll_scan_phy *scanp = scansm->scanp; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) struct ble_mbuf_hdr_rxinfo *rxinfo = &hdr->rxinfo; - uint8_t sreq_adva_type; - uint8_t *sreq_adva; +#endif + uint8_t scan_ok; int rc; ble_ll_scan_get_addr_data_from_legacy(pdu_type, rxbuf, addrd); - if (pdu_type == BLE_ADV_PDU_TYPE_SCAN_RSP) { - if (!BLE_MBUF_HDR_SCAN_RSP_RXD(hdr)) { - /* - * We were not expecting scan response so just ignore and do not - * update backoff. - */ - return -1; - } - - sreq_adva_type = !!(scansm->pdu_data.hdr_byte & BLE_ADV_PDU_HDR_RXADD_MASK); - sreq_adva = scansm->pdu_data.adva; - - /* - * Ignore scan response if AdvA does not match AdvA in request and also - * update backoff as if there was no scan response. - */ - if ((addrd->adva_type != sreq_adva_type) || - memcmp(addrd->adva, sreq_adva, BLE_DEV_ADDR_LEN)) { - ble_ll_scan_req_backoff(scansm, 0); - return -1; - } - #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - /* - * We are not pushing this one through filters so need to update - * rpa_index here as otherwise pkt_in won't be able to determine - * advertiser address properly. - */ - rxinfo->rpa_index = ble_hw_resolv_list_match(); - if (rxinfo->rpa_index >= 0) { - rxinfo->flags |= BLE_MBUF_HDR_F_RESOLVED; - } + addrd->rpa_index = ble_hw_resolv_list_match(); #endif - rxinfo->flags |= BLE_MBUF_HDR_F_DEVMATCH; - - return 0; - } - - rc = ble_ll_scan_rx_filter(hdr, addrd); - if (!rc) { + rc = ble_ll_scan_rx_filter(scansm->own_addr_type, scansm->scan_filt_policy, + addrd, &scan_ok); + if (rc < 0) { return 0; } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) rxinfo->flags |= BLE_MBUF_HDR_F_DEVMATCH; + rxinfo->rpa_index = addrd->rpa_index; + if (addrd->adva_resolved) { + rxinfo->flags |= BLE_MBUF_HDR_F_RESOLVED; + } + if (addrd->targeta_resolved) { + rxinfo->flags |= BLE_MBUF_HDR_F_TARGETA_RESOLVED; + } +#endif - if (rc == 2) { + if (!scan_ok) { /* Scan request forbidden by filter policy */ return 0; } @@ -2198,94 +1978,55 @@ ble_ll_scan_rx_isr_on_legacy(uint8_t pdu_type, uint8_t *rxbuf, (pdu_type == BLE_ADV_PDU_TYPE_ADV_SCAN_IND)); } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) static int -ble_ll_scan_rx_isr_on_aux(uint8_t pdu_type, uint8_t *rxbuf, - struct ble_mbuf_hdr *hdr, - struct ble_ll_scan_addr_data *addrd) +ble_ll_scan_rx_isr_on_scan_rsp(uint8_t pdu_type, uint8_t *rxbuf, + struct ble_mbuf_hdr *hdr, + struct ble_ll_scan_addr_data *addrd) { struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; - struct ble_ll_scan_phy *scanp = scansm->scanp; struct ble_mbuf_hdr_rxinfo *rxinfo = &hdr->rxinfo; - struct ble_ll_aux_data *aux_data; - int rc; + uint8_t sreq_adva_type; + uint8_t *sreq_adva; - if (!scansm->ext_scanning) { - return -1; - } + ble_ll_scan_get_addr_data_from_legacy(pdu_type, rxbuf, addrd); - rc = ble_ll_scan_update_aux_data(hdr, rxbuf, &addrd->adva_present); - if (rc < 0) { - rxinfo->flags |= BLE_MBUF_HDR_F_AUX_INVALID; + if (!BLE_MBUF_HDR_SCAN_RSP_RXD(hdr)) { + /* + * We were not expecting scan response so just ignore and do not + * update backoff. + */ return -1; - } else if (rc == 0) { - rxinfo->flags |= BLE_MBUF_HDR_F_AUX_PTR_WAIT; } - /* Now we can update aux_data from header since it may have just been created */ - aux_data = rxinfo->user_data; + sreq_adva_type = !!(scansm->pdu_data.hdr_byte & BLE_ADV_PDU_HDR_RXADD_MASK); + sreq_adva = scansm->pdu_data.adva; /* - * Restore proper header flags if filtering was already done successfully on - * some previous PDU in an event. + * Ignore scan response if AdvA does not match AdvA in request and also + * update backoff as if there was no scan response. */ - if (aux_data->flags & BLE_LL_AUX_IS_MATCHED) { - rxinfo->flags |= BLE_MBUF_HDR_F_DEVMATCH; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - rxinfo->rpa_index = aux_data->rpa_index; - if (rxinfo->rpa_index >= 0) { - rxinfo->flags |= BLE_MBUF_HDR_F_RESOLVED; - } - if (aux_data->flags & BLE_LL_AUX_IS_TARGETA_RESOLVED) { - rxinfo->flags |= BLE_MBUF_HDR_F_TARGETA_RESOLVED; - } -#endif - goto done; + if ((addrd->adva_type != sreq_adva_type) || + memcmp(addrd->adva, sreq_adva, BLE_DEV_ADDR_LEN)) { + ble_ll_scan_req_backoff(scansm, 0); + return -1; } - if (aux_data->flags & BLE_LL_AUX_HAS_ADVA) { - addrd->adva = aux_data->adva; - addrd->adva_type = aux_data->adva_type; - } else { - /* Accept this PDU and wait for AdvA in aux */ - rxinfo->flags |= BLE_MBUF_HDR_F_DEVMATCH; - return 0; - } - if (aux_data->flags & BLE_LL_AUX_HAS_TARGETA) { - addrd->targeta = aux_data->targeta; - addrd->targeta_type = aux_data->targeta_type; - } else { - addrd->targeta = NULL; - } - - rc = ble_ll_scan_rx_filter(hdr, addrd); - if (!rc) { - return 0; - } - - rxinfo->flags |= BLE_MBUF_HDR_F_DEVMATCH; - +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) /* - * Once we matched device, there's no need to go through filtering on every - * other PDU in an event so just store info required to restore state for - * subsequent PDUs in aux_data. + * We are not pushing this one through filters so need to update + * rpa_index here as otherwise pkt_in won't be able to determine + * advertiser address properly. */ - aux_data->flags |= BLE_LL_AUX_IS_MATCHED; - if (rxinfo->flags & BLE_MBUF_HDR_F_TARGETA_RESOLVED) { - aux_data->flags |= BLE_LL_AUX_IS_TARGETA_RESOLVED; - /* AdvA state is already stored in rpa_index */ + rxinfo->rpa_index = ble_hw_resolv_list_match(); + if (rxinfo->rpa_index >= 0) { + rxinfo->flags |= BLE_MBUF_HDR_F_RESOLVED; } +#endif - if (rc == 2) { - /* Scan request forbidden by filter policy */ - return 0; - } + rxinfo->flags |= BLE_MBUF_HDR_F_DEVMATCH; -done: - return (scanp->scan_type == BLE_SCAN_TYPE_ACTIVE) && - ((rxbuf[2] >> 6) == BLE_LL_EXT_ADV_MODE_SCAN); + return 0; } -#endif static bool ble_ll_scan_send_scan_req(uint8_t pdu_type, uint8_t *rxbuf, @@ -2294,23 +2035,11 @@ ble_ll_scan_send_scan_req(uint8_t pdu_type, uint8_t *rxbuf, { struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; struct ble_mbuf_hdr_rxinfo *rxinfo = &hdr->rxinfo; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - struct ble_ll_aux_data *aux_data = rxinfo->user_data; - uint8_t phy_mode; -#endif bool is_ext_adv = false; + int8_t rpa_index; uint16_t adi = 0; int rc; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - if (pdu_type == BLE_ADV_PDU_TYPE_ADV_EXT_IND) { - if (ble_ll_scan_get_adi(aux_data, &adi) < 0) { - return false; - } - is_ext_adv = true; - } -#endif - /* Check if we already scanned this device successfully */ if (ble_ll_scan_have_rxd_scan_rsp(addrd->adv_addr, addrd->adv_addr_type, is_ext_adv, adi)) { @@ -2327,15 +2056,15 @@ ble_ll_scan_send_scan_req(uint8_t pdu_type, uint8_t *rxbuf, } } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - phy_mode = ble_ll_phy_to_phy_mode(rxinfo->phy, BLE_HCI_LE_PHY_CODED_ANY); - if (ble_ll_sched_scan_req_over_aux_ptr(rxinfo->channel, phy_mode)) { - return false; - } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + rpa_index = addrd->rpa_index; +#else + rpa_index = -1; #endif /* Use original AdvA in scan request (Core 5.1, Vol 6, Part B, section 6.3) */ - ble_ll_scan_req_pdu_prepare(scansm, addrd->adva, addrd->adva_type, addrd->rl); + ble_ll_scan_req_pdu_prepare(scansm, addrd->adva, addrd->adva_type, + rpa_index); rc = ble_phy_tx(ble_ll_scan_req_tx_pdu_cb, scansm, BLE_PHY_TRANSITION_TX_RX); if (rc) { @@ -2345,14 +2074,6 @@ ble_ll_scan_send_scan_req(uint8_t pdu_type, uint8_t *rxbuf, scansm->scan_rsp_pending = 1; rxinfo->flags |= BLE_MBUF_HDR_F_SCAN_REQ_TXD; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - if (rxinfo->channel < BLE_PHY_NUM_DATA_CHANS) { - /* Keep aux_data for expected scan response */ - scansm->cur_aux_data = ble_ll_scan_aux_data_ref(aux_data); - STATS_INC(ble_ll_stats, aux_scan_req_tx); - } -#endif - return true; } @@ -2388,48 +2109,31 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) return 0; } - rxbuf = rxpdu->om_data; - pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - /* - * In case aux was expected, copy aux_data for LL to use. Make sure this was - * indeed an aux as otherwise there's no need to process it and just pass to - * LL immediately. - */ - if (scansm->cur_aux_data) { - rxinfo->user_data = scansm->cur_aux_data; - scansm->cur_aux_data = NULL; - if (pdu_type != BLE_ADV_PDU_TYPE_ADV_EXT_IND) { - ble_ll_state_set(BLE_LL_STATE_STANDBY); - return -1; - } - } -#endif - if (!crcok) { goto scan_rx_isr_ignore; } - /* - * Addresses will be always set in handlers, no need to initialize them. We - * only need to initialize rl which may not be always set, depending on how - * filtering goes. - */ - addrd.rl = NULL; + rxbuf = rxpdu->om_data; + pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK; switch (pdu_type) { case BLE_ADV_PDU_TYPE_ADV_IND: case BLE_ADV_PDU_TYPE_ADV_DIRECT_IND: case BLE_ADV_PDU_TYPE_ADV_NONCONN_IND: - case BLE_ADV_PDU_TYPE_SCAN_RSP: case BLE_ADV_PDU_TYPE_ADV_SCAN_IND: - rc = ble_ll_scan_rx_isr_on_legacy(pdu_type, rxbuf, hdr, &addrd); + rc = ble_ll_scan_rx_isr_on_adv(pdu_type, rxbuf, hdr, &addrd); + break; + case BLE_ADV_PDU_TYPE_SCAN_RSP: + rc = ble_ll_scan_rx_isr_on_scan_rsp(pdu_type, rxbuf, hdr, &addrd); break; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) case BLE_ADV_PDU_TYPE_ADV_EXT_IND: - rc = ble_ll_scan_rx_isr_on_aux(pdu_type, rxbuf, hdr, &addrd); - break; + rc = ble_ll_scan_aux_rx_isr_end_on_ext(&g_ble_ll_scan_sm, rxpdu); + if (rc < 0) { + rxinfo->flags |= BLE_MBUF_HDR_F_IGNORED; + } + ble_ll_state_set(BLE_LL_STATE_STANDBY); + return -1; #endif default: /* This is not something we would like to process here */ @@ -2579,281 +2283,6 @@ ble_ll_scan_wfr_timer_exp(void) ble_phy_restart_rx(); } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -/* - * Send extended advertising report - * - * @return -1 on error (data truncated or other error) - * 0 on success (data status is "completed") - * 1 on success (data status is not "completed") - */ -static int -ble_ll_hci_send_ext_adv_report(uint8_t ptype, uint8_t *adva, uint8_t adva_type, - uint8_t *inita, uint8_t inita_type, - struct os_mbuf *om, - struct ble_mbuf_hdr *hdr) -{ - struct ble_ll_aux_data *aux_data = hdr->rxinfo.user_data; - struct ble_hci_ev_le_subev_ext_adv_rpt *ev; - struct ext_adv_report *report; - struct ble_hci_ev *hci_ev; - struct ble_hci_ev *hci_ev_next; - int offset; - int datalen; - int rc; - bool need_event; - bool is_scannable_aux; - uint8_t max_data_len; - - if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) { - rc = -1; - goto done; - } - - /* Just ignore PDU if truncated was already sent. - * This can happen if next PDU in chain was already received before we - * manage to cancel scan on error (which resulted in sending truncated HCI - * event) - */ - if (aux_data && (aux_data->flags_ll & BLE_LL_AUX_FLAG_HCI_SENT_TRUNCATED)) { - rc = -1; - goto done; - } - - /* - * We keep one allocated event in aux_data to be able to truncate chain - * properly in case of error. If there is no event in aux_data it means this - * is the first event for this chain. - */ - if (aux_data && aux_data->evt) { - hci_ev = aux_data->evt; - aux_data->evt = NULL; - - hci_ev->length = sizeof(*ev) + sizeof(*report); - } else { - hci_ev = ble_ll_scan_get_ext_adv_report(NULL); - if (!hci_ev) { - rc = -1; - goto done; - } - } - - ev = (void *) hci_ev->data; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - /* If RPA has been used, make sure we use correct address types - * in the advertising report. - */ - if (BLE_MBUF_HDR_RESOLVED(hdr)) { - adva_type += 2; - } - if (BLE_MBUF_HDR_TARGETA_RESOLVED(hdr)) { - inita_type += 2; - } -#endif - - datalen = ble_ll_scan_parse_ext_hdr(om, adva, adva_type, inita, inita_type, - hdr, ev->reports); - if (datalen < 0) { - rc = -1; - - /* Need to send truncated event if we already sent some reports */ - if (aux_data && (aux_data->flags_ll & BLE_LL_AUX_FLAG_HCI_SENT_ANY)) { - BLE_LL_ASSERT(!(aux_data->flags_ll & BLE_LL_AUX_FLAG_HCI_SENT_COMPLETED)); - - aux_data->flags_ll |= BLE_LL_AUX_FLAG_SCAN_ERROR; - aux_data->flags_ll |= BLE_LL_AUX_FLAG_HCI_SENT_TRUNCATED; - - report = ev->reports; - report->data_len = 0; - report->evt_type |= BLE_HCI_ADV_DATA_STATUS_TRUNCATED; - - ble_ll_hci_event_send(hci_ev); - goto done; - } - - ble_hci_trans_buf_free((uint8_t *)hci_ev); - goto done; - } - - is_scannable_aux = aux_data && - (aux_data->evt_type & BLE_HCI_ADV_SCAN_MASK) && - !(aux_data->evt_type & BLE_HCI_ADV_SCAN_RSP_MASK); - - max_data_len = BLE_LL_MAX_EVT_LEN - sizeof(*hci_ev) - sizeof(*ev) - sizeof(*report); - offset = 0; - - do { - hci_ev_next = NULL; - - ev = (void *) hci_ev->data; - report = ev->reports; - - report->data_len = min(max_data_len, datalen - offset); - - /* adjust event length */ - hci_ev->length += report->data_len; - report->rssi = hdr->rxinfo.rssi; - - os_mbuf_copydata(om, offset, report->data_len, report->data); - offset += report->data_len; - - /* - * We need another event if either there are still some data left to - * send in current PDU or scan is not completed. There are two exceptions - * though: - * - we sent all data from this PDU and there is scan error set already; - * it may be set before entering current function due to failed aux - * scan scheduling - * - this is a scannable event which is not a scan response - */ - need_event = ((offset < datalen) || (aux_data && !(aux_data->flags_ll & BLE_LL_AUX_FLAG_SCAN_COMPLETE))) && - !((offset == datalen) && (aux_data->flags_ll & BLE_LL_AUX_FLAG_SCAN_ERROR)) && - !is_scannable_aux; - - if (need_event) { - /* - * We will need another event so let's try to allocate one now. If - * we cannot do this, need to mark event as truncated. - */ - hci_ev_next = ble_ll_scan_get_ext_adv_report(report); - - if (hci_ev_next) { - report->evt_type |= BLE_HCI_ADV_DATA_STATUS_INCOMPLETE; - rc = 1; - } else { - report->evt_type |= BLE_HCI_ADV_DATA_STATUS_TRUNCATED; - rc = -1; - } - } else if (aux_data && (aux_data->flags_ll & BLE_LL_AUX_FLAG_SCAN_ERROR)) { - report->evt_type |= BLE_HCI_ADV_DATA_STATUS_TRUNCATED; - rc = -1; - } else { - rc = 0; - } - - if ((rc == -1) && aux_data) { - aux_data->flags_ll |= BLE_LL_AUX_FLAG_SCAN_ERROR; - - if (!(aux_data->flags_ll & BLE_LL_AUX_FLAG_HCI_SENT_ANY)) { - ble_hci_trans_buf_free((uint8_t *)hci_ev); - goto done; - } - - aux_data->flags_ll |= BLE_LL_AUX_FLAG_HCI_SENT_TRUNCATED; - } else if (!is_scannable_aux) { - /* - * We do not set 'sent' flags for scannable AUX since we only care - * about scan response that will come next. - */ - aux_data->flags_ll |= BLE_LL_AUX_FLAG_HCI_SENT_ANY; - if (rc == 0) { - aux_data->flags_ll |= BLE_LL_AUX_FLAG_HCI_SENT_COMPLETED; - } - } - - ble_ll_hci_event_send(hci_ev); - - hci_ev = hci_ev_next; - } while ((offset < datalen) && hci_ev); - - BLE_LL_ASSERT(offset <= datalen); - - if (aux_data) { - /* Store any event left for later use */ - aux_data->evt = hci_ev; - } else { - /* If it is empty beacon, evt shall be NULL */ - BLE_LL_ASSERT(!hci_ev); - } - -done: - if (!aux_data) { - return rc; - } - - if (rc == 0) { - if (aux_data->evt_type & BLE_HCI_ADV_SCAN_RSP_MASK) { - /* Complete scan response can be added to duplicates list */ - ble_ll_scan_add_scan_rsp_adv(aux_data->adva, aux_data->adva_type, - 1, aux_data->adi); - } else if (is_scannable_aux) { - /* - * Scannable AUX is marked as incomplete because we do not want to - * add this to duplicates list now, this should happen only after - * we receive complete scan response. The drawback here is that we - * will keep receiving reports for scannable PDUs until complete - * scan response is received. - * - * XXX ^^ extend duplicates list to fix - */ - rc = 1; - } - } else if (rc < 0) { - aux_data->flags_ll |= BLE_LL_AUX_FLAG_SCAN_ERROR; - } - - return rc; -} -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) -static void -ble_ll_scan_check_periodic_sync(const struct os_mbuf *om, struct ble_mbuf_hdr *rxhdr, - uint8_t *adva, uint8_t adva_type, int rpa_index) -{ - uint8_t pdu_len; - uint8_t ext_hdr_len; - uint8_t ext_hdr_flags; - uint8_t *ext_hdr; - uint8_t *rxbuf = om->om_data; - uint8_t sid; - int i; - - pdu_len = rxbuf[1]; - if (pdu_len == 0) { - return; - } - - ext_hdr_len = rxbuf[2] & 0x3F; - - if (ext_hdr_len) { - ext_hdr_flags = rxbuf[3]; - ext_hdr = &rxbuf[4]; - i = 0; - - if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_ADVA_BIT)) { - i += BLE_LL_EXT_ADV_ADVA_SIZE; - } - - if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_TARGETA_BIT)) { - i += BLE_LL_EXT_ADV_TARGETA_SIZE; - } - - if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_CTE_INFO_BIT)) { - i += 1; - } - - if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) { - sid = (get_le16(ext_hdr + i) >> 12); - i += BLE_LL_EXT_ADV_DATA_INFO_SIZE; - } else { - /* ADI is mandatory */ - return; - } - - if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { - i += BLE_LL_EXT_ADV_AUX_PTR_SIZE; - } - - if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_SYNC_INFO_BIT)) { - ble_ll_sync_info_event(adva, adva_type, rpa_index, sid, rxhdr, - ext_hdr + i); - } - } -} -#endif - static inline void ble_ll_scan_dup_move_to_head(struct ble_ll_scan_dup_entry *e) { @@ -2919,20 +2348,17 @@ ble_ll_scan_dup_check_legacy(uint8_t addr_type, uint8_t *addr, uint8_t pdu_type) } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -static int -ble_ll_scan_dup_check_ext(uint8_t addr_type, uint8_t *addr, - struct ble_ll_aux_data *aux_data) +int +ble_ll_scan_dup_check_ext(uint8_t addr_type, uint8_t *addr, bool has_aux, + uint16_t adi) { struct ble_ll_scan_dup_entry *e; - bool has_aux; bool is_anon; - uint16_t adi; uint8_t type; int rc; - has_aux = aux_data != NULL; is_anon = addr == NULL; - adi = has_aux ? aux_data->adi : 0; + adi = has_aux ? adi : 0; type = BLE_LL_SCAN_ENTRY_TYPE_EXT(addr_type, has_aux, is_anon, adi); @@ -2971,19 +2397,16 @@ ble_ll_scan_dup_check_ext(uint8_t addr_type, uint8_t *addr, return rc; } -static int -ble_ll_scan_dup_update_ext(uint8_t addr_type, uint8_t *addr, - struct ble_ll_aux_data *aux_data) +int +ble_ll_scan_dup_update_ext(uint8_t addr_type, uint8_t *addr, bool has_aux, + uint16_t adi) { struct ble_ll_scan_dup_entry *e; - bool has_aux; bool is_anon; - uint16_t adi; uint8_t type; - has_aux = aux_data != NULL; is_anon = addr == NULL; - adi = has_aux ? aux_data->adi : 0; + adi = has_aux ? adi : 0; type = BLE_LL_SCAN_ENTRY_TYPE_EXT(addr_type, has_aux, is_anon, adi); @@ -3019,7 +2442,6 @@ ble_ll_scan_rx_pkt_in_restore_addr_data(struct ble_mbuf_hdr *hdr, rl = &g_ble_ll_resolv_list[rxinfo->rpa_index]; addrd->adv_addr = rl->rl_identity_addr; addrd->adv_addr_type = rl->rl_addr_type; - addrd->rl = rl; } if (hdr->rxinfo.flags & BLE_MBUF_HDR_F_TARGETA_RESOLVED) { addrd->targeta = ble_ll_get_our_devaddr(scansm->own_addr_type & 1); @@ -3065,143 +2487,6 @@ ble_ll_scan_rx_pkt_in_on_legacy(uint8_t pdu_type, struct os_mbuf *om, } } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -static void -ble_ll_scan_rx_pkt_in_on_aux(uint8_t pdu_type, struct os_mbuf *om, - struct ble_mbuf_hdr *hdr, - struct ble_ll_scan_addr_data *addrd) -{ - struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) - uint8_t *rxbuf = om->om_data; -#endif - struct ble_mbuf_hdr_rxinfo *rxinfo = &hdr->rxinfo; - struct ble_ll_aux_data *aux_data = rxinfo->user_data; - bool send_hci_report; - int rc; - - if (aux_data) { - aux_data->flags_ll |= aux_data->flags_isr; - } - - /* - * For every new extended advertising event scanned, rx_isr_end will either - * allocate new aux_data or set 'invalid' flag. This means if no 'invalid' - * flag is set, aux_data is always valid. - */ - - /* Drop on scan error or if we received not what we expected to receive */ - if (!BLE_MBUF_HDR_CRC_OK(hdr) || - BLE_MBUF_HDR_IGNORED(hdr) || - BLE_MBUF_HDR_AUX_INVALID(hdr) || - (aux_data->flags_ll & BLE_LL_AUX_FLAG_SCAN_ERROR) || - (pdu_type != BLE_ADV_PDU_TYPE_ADV_EXT_IND) || - !scansm->scan_enabled) { - if (aux_data) { - ble_ll_scan_end_adv_evt(aux_data); - ble_ll_scan_aux_data_unref(aux_data); - rxinfo->user_data = NULL; - } - return; - } - - BLE_LL_ASSERT(aux_data); - - if (aux_data->flags & BLE_LL_AUX_HAS_ADVA) { - addrd->adva = aux_data->adva; - addrd->adva_type = aux_data->adva_type; - } else { - addrd->adva = NULL; - addrd->adva_type = 0; - } - if (aux_data->flags & BLE_LL_AUX_HAS_TARGETA) { - addrd->targeta = aux_data->targeta; - addrd->targeta_type = aux_data->targeta_type; - } else { - addrd->targeta = NULL; - addrd->targeta_type = 0; - } - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) - /* - * Periodic scan uses own filter list so we need to let it do own filtering - * regardless of scanner filtering. Just make sure we already have AdvA. - */ - if (ble_ll_sync_enabled() && - ((rxbuf[2] >> 6) == BLE_LL_EXT_ADV_MODE_NON_CONN) && addrd->adva && - !(aux_data->flags_ll & BLE_LL_AUX_FLAG_AUX_CHAIN_RECEIVED)) { - ble_ll_scan_check_periodic_sync(om, hdr, addrd->adva, addrd->adva_type, - rxinfo->rpa_index); - } -#endif - - /* Ignore if device was not matched by either whitelist or scan policy */ - if (!BLE_MBUF_HDR_DEVMATCH(hdr)) { - goto scan_continue; - } - - ble_ll_scan_rx_pkt_in_restore_addr_data(hdr, addrd); - - /* - * If there is AuxPtr in this PDU, we should first try to schedule scan for - * subsequent aux. - */ - if (BLE_MBUF_HDR_WAIT_AUX(hdr)) { - if (ble_ll_sched_aux_scan(hdr, scansm, aux_data)) { - rxinfo->flags &= ~BLE_MBUF_HDR_F_AUX_PTR_WAIT; - aux_data->flags_ll |= BLE_LL_AUX_FLAG_SCAN_ERROR; - - /* Silently ignore if no HCI event was sent to host */ - if (!(aux_data->flags_ll & BLE_LL_AUX_FLAG_HCI_SENT_ANY)) { - goto scan_continue; - } - } - - /* Ignore if this was just ADV_EXT_IND with AuxPtr, will process aux */ - if (!(aux_data->flags_ll & BLE_LL_AUX_FLAG_AUX_ADV_RECEIVED)) { - goto scan_continue; - } - - STATS_INC(ble_ll_stats, aux_chain_cnt); - } - - send_hci_report = !scansm->scan_filt_dups || - !ble_ll_scan_dup_check_ext(addrd->adv_addr_type, - addrd->adv_addr, aux_data); - if (send_hci_report) { - rc = ble_ll_hci_send_ext_adv_report(pdu_type, - addrd->adv_addr, addrd->adv_addr_type, - addrd->targeta, addrd->targeta_type, - om, hdr); - if ((rc < 0) && BLE_MBUF_HDR_WAIT_AUX(hdr)) { - /* Data were truncated so stop scanning for subsequent auxes */ - aux_data->flags_ll |= BLE_LL_AUX_FLAG_SCAN_ERROR; - - if (ble_ll_sched_rmv_elem(&aux_data->sch) == 0) { - ble_ll_scan_aux_data_unref(aux_data->sch.cb_arg); - aux_data->sch.cb_arg = NULL; - } - } else if ((rc == 0) && scansm->scan_filt_dups) { - /* Complete data were send so we can update scan_dup list */ - ble_ll_scan_dup_update_ext(addrd->adv_addr_type, addrd->adv_addr, - aux_data); - } - } - - if (BLE_MBUF_HDR_SCAN_RSP_RXD(hdr)) { - /* - * For now assume success if we just received direct scan response, - * don't care about complete aux chain. - */ - ble_ll_scan_req_backoff(scansm, 1); - } - -scan_continue: - ble_ll_scan_aux_data_unref(rxinfo->user_data); - rxinfo->user_data = NULL; -} -#endif - /** * Process a received PDU while in the scanning state. * @@ -3213,15 +2498,11 @@ ble_ll_scan_rx_pkt_in_on_aux(uint8_t pdu_type, struct os_mbuf *om, void ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hdr) { -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - struct ble_mbuf_hdr_rxinfo *rxinfo = &hdr->rxinfo; - struct ble_ll_aux_data *aux_data = rxinfo->user_data; -#endif struct ble_ll_scan_addr_data addrd; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - if (aux_data || (ptype == BLE_ADV_PDU_TYPE_ADV_EXT_IND)) { - ble_ll_scan_rx_pkt_in_on_aux(ptype, om, hdr, &addrd); + if (ptype == BLE_ADV_PDU_TYPE_ADV_EXT_IND) { + ble_ll_scan_aux_pkt_in_on_ext(om, hdr); ble_ll_scan_chk_resume(); return; } @@ -3976,4 +3257,7 @@ ble_ll_scan_init(void) TAILQ_INIT(&g_scan_dup_list); ble_ll_scan_common_init(); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + ble_ll_scan_aux_init(); +#endif } diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c new file mode 100644 index 0000000000..128b45a7cc --- /dev/null +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -0,0 +1,1555 @@ +/* + * 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. + */ + +#include + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + +#include +#include +#include +#include +#include "os/os.h" +#include "nimble/ble.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" +#include "controller/ble_ll_sched.h" +#include "controller/ble_ll_scan.h" +#include "controller/ble_ll_scan_aux.h" +#include "controller/ble_ll_hci.h" +#include "controller/ble_ll_whitelist.h" +#include "controller/ble_ll_resolv.h" +#include "controller/ble_ll_sync.h" + +#define BLE_LL_SCAN_AUX_F_AUX_ADV 0x0001 +#define BLE_LL_SCAN_AUX_F_AUX_CHAIN 0x0002 +#define BLE_LL_SCAN_AUX_F_MATCHED 0x0004 +#define BLE_LL_SCAN_AUX_F_W4_SCAN_RSP 0x0008 +#define BLE_LL_SCAN_AUX_F_SCANNED 0x0010 +#define BLE_LL_SCAN_AUX_F_HAS_ADVA 0x0020 +#define BLE_LL_SCAN_AUX_F_HAS_TARGETA 0x0040 +#define BLE_LL_SCAN_AUX_F_HAS_ADI 0x0080 +#define BLE_LL_SCAN_AUX_F_RESOLVED_ADVA 0x0100 +#define BLE_LL_SCAN_AUX_F_RESOLVED_TARGETA 0x0200 + +#define BLE_LL_SCAN_AUX_H_SENT_ANY 0x01 +#define BLE_LL_SCAN_AUX_H_DONE 0x02 +#define BLE_LL_SCAN_AUX_H_TRUNCATED 0x04 + +struct ble_ll_scan_aux_data { + uint16_t flags; + uint8_t hci_state; + + uint8_t scan_type; + + uint8_t pri_phy; + uint8_t sec_phy; + uint8_t chan; + uint8_t offset_unit : 1; + uint32_t aux_ptr; + struct ble_ll_sched_item sch; + struct ble_npl_event break_ev; + struct ble_hci_ev *hci_ev; + + uint16_t adi; + + uint8_t adva[6]; + uint8_t targeta[6]; + uint8_t adva_type : 1; + uint8_t targeta_type : 1; + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + int8_t rpa_index; +#endif +}; + +#define AUX_MEMPOOL_SIZE (OS_MEMPOOL_SIZE( \ + MYNEWT_VAL(BLE_LL_SCAN_AUX_SEGMENT_CNT), \ + sizeof(struct ble_ll_scan_aux_data))) + +static os_membuf_t aux_data_mem[AUX_MEMPOOL_SIZE]; +static struct os_mempool aux_data_pool; + +static struct ble_ll_scan_aux_data *aux_data_current; + +static void ble_ll_hci_ev_send_ext_adv_truncated_report(struct ble_ll_scan_aux_data *aux); + +static inline uint8_t * +ble_ll_scan_aux_get_own_addr(void) +{ + uint8_t own_addr_type; + + own_addr_type = ble_ll_scan_get_own_addr_type() & 1; + + return ble_ll_get_our_devaddr(own_addr_type); +} + +static int +ble_ll_scan_aux_sched_cb(struct ble_ll_sched_item *sch) +{ + struct ble_ll_scan_aux_data *aux = sch->cb_arg; + uint32_t wfr_us; +#if BLE_LL_BT5_PHY_SUPPORTED + uint8_t phy_mode; +#endif + uint8_t lls; + int rc; + + BLE_LL_ASSERT(aux); + + lls = ble_ll_state_get(); + BLE_LL_ASSERT(lls == BLE_LL_STATE_STANDBY); + + rc = ble_phy_setchan(aux->chan, BLE_ACCESS_ADDR_ADV, BLE_LL_CRCINIT_ADV); + BLE_LL_ASSERT(rc == 0); + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) + ble_phy_encrypt_disable(); +#endif + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + if (ble_ll_resolv_enabled()) { + ble_phy_resolv_list_enable(); + } else { + ble_phy_resolv_list_disable(); + } +#endif + +#if BLE_LL_BT5_PHY_SUPPORTED + phy_mode = ble_ll_phy_to_phy_mode(aux->sec_phy, BLE_HCI_LE_PHY_CODED_ANY); + ble_phy_mode_set(phy_mode, phy_mode); +#endif + + rc = ble_phy_rx_set_start_time(sch->start_time + g_ble_ll_sched_offset_ticks, + sch->remainder); + if (rc != 0 && rc != BLE_PHY_ERR_RX_LATE) { + ble_ll_scan_aux_break(aux); + return BLE_LL_SCHED_STATE_DONE; + } + + /* Keep listening even if we are late, we may still receive something */ + + if (ble_ll_scan_get_filt_policy() & 1) { + ble_ll_whitelist_enable(); + } else { + ble_ll_whitelist_disable(); + } + + wfr_us = aux->offset_unit ? 300 : 30; + ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_RX, 0, wfr_us); + + aux_data_current = aux; + + ble_ll_state_set(BLE_LL_STATE_SCAN_AUX); + + return BLE_LL_SCHED_STATE_DONE; +} + +static struct ble_ll_scan_aux_data * +ble_ll_scan_aux_alloc(void) +{ + struct ble_ll_scan_aux_data *aux; + + aux = os_memblock_get(&aux_data_pool); + if (!aux) { + return NULL; + } + + memset(aux, 0, sizeof(*aux)); + + aux->sch.sched_cb = ble_ll_scan_aux_sched_cb; + aux->sch.sched_type = BLE_LL_SCHED_TYPE_SCAN_AUX; + aux->sch.cb_arg = aux; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + aux->rpa_index = -1; +#endif + + return aux; +} + +static void +ble_ll_scan_aux_free(struct ble_ll_scan_aux_data *aux) +{ + BLE_LL_ASSERT(!aux->sch.enqueued); + BLE_LL_ASSERT(aux->hci_ev == NULL); + BLE_LL_ASSERT((aux->hci_state & BLE_LL_SCAN_AUX_H_DONE) || + !(aux->hci_state & BLE_LL_SCAN_AUX_H_SENT_ANY)); + + os_memblock_put(&aux_data_pool, aux); +} + +static void +ble_ll_scan_aux_update_scan_backoff(struct ble_ll_scan_aux_data *aux) +{ + if (!(aux->flags & BLE_LL_SCAN_AUX_F_W4_SCAN_RSP) && + !(aux->flags & BLE_LL_SCAN_AUX_F_SCANNED)) { + return; + } + + if ((aux->hci_state & BLE_LL_SCAN_AUX_H_DONE) && + !(aux->hci_state & BLE_LL_SCAN_AUX_H_TRUNCATED)) { + ble_ll_scan_backoff_update(1); + } else { + ble_ll_scan_backoff_update(0); + } +} + +static inline bool +ble_ll_scan_aux_need_truncation(struct ble_ll_scan_aux_data *aux) +{ + return (aux->hci_state & BLE_LL_SCAN_AUX_H_SENT_ANY) && + !(aux->hci_state & BLE_LL_SCAN_AUX_H_DONE); +} + +static struct ble_hci_ev * +ble_ll_hci_ev_alloc_ext_adv_report_for_aux(struct ble_ll_scan_addr_data *addrd, + struct ble_ll_scan_aux_data *aux) +{ + struct ble_hci_ev_le_subev_ext_adv_rpt *hci_subev; + struct ext_adv_report *report; + struct ble_hci_ev *hci_ev; + + hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + if (!hci_ev) { + return NULL; + } + + hci_ev->opcode = BLE_HCI_EVCODE_LE_META; + hci_ev->length = sizeof(*hci_subev) + sizeof(*report); + + hci_subev = (void *)hci_ev->data; + hci_subev->subev_code = BLE_HCI_LE_SUBEV_EXT_ADV_RPT; + hci_subev->num_reports = 1; + + report = hci_subev->reports; + + memset(report, 0, sizeof(*report)); + + report->evt_type = 0; + if (addrd->adva) { + report->addr_type = addrd->adv_addr_type; + memcpy(report->addr, addrd->adv_addr, 6); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + if (addrd->adva_resolved) { + report->addr_type += 2; + } +#endif + } else { + report->addr_type = 0xff; + } + report->pri_phy = aux->pri_phy; + report->sec_phy = aux->sec_phy; + report->sid = aux->adi >> 12; + report->tx_power = 0x7f; + report->rssi = 0x7f; + report->periodic_itvl = 0; + if (addrd->targeta) { + report->evt_type |= BLE_HCI_ADV_DIRECT_MASK; + report->dir_addr_type = addrd->targeta_type; + memcpy(report->dir_addr, addrd->targeta, 6); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + if (addrd->targeta_resolved) { + report->dir_addr_type += 2; + } +#endif + } + report->data_len = 0; + + return hci_ev; +} + +static struct ble_hci_ev * +ble_ll_hci_ev_dup_ext_adv_report(struct ble_hci_ev *hci_ev_src) +{ + struct ble_hci_ev_le_subev_ext_adv_rpt *hci_subev; + struct ext_adv_report *report; + struct ble_hci_ev *hci_ev; + + hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + if (!hci_ev) { + return NULL; + } + + memcpy(hci_ev, hci_ev_src, sizeof(*hci_ev) + sizeof(*hci_subev) + + sizeof(*report)); + hci_ev->length = sizeof(*hci_subev) + sizeof(*report); + + hci_subev = (void *)hci_ev->data; + + report = hci_subev->reports; + report->data_len = 0; + + return hci_ev; +} + +static void +ble_ll_hci_ev_update_ext_adv_report_from_aux(struct ble_hci_ev *hci_ev, + struct os_mbuf *rxpdu, + struct ble_mbuf_hdr *rxhdr) +{ + struct ble_hci_ev_le_subev_ext_adv_rpt *hci_subev; + struct ext_adv_report *report; + uint8_t adv_mode; + uint8_t eh_len; + uint8_t eh_flags; + uint8_t *eh_data; + uint8_t *rxbuf; + + hci_subev = (void *)hci_ev->data; + report = hci_subev->reports; + rxbuf = rxpdu->om_data; + + adv_mode = rxbuf[2] >> 6; + eh_len = rxbuf[2] & 0x3f; + eh_flags = rxbuf[3]; + eh_data = &rxbuf[4]; + + report->evt_type |= adv_mode; + if (rxhdr->rxinfo.flags & BLE_MBUF_HDR_F_SCAN_RSP_RXD) { + report->evt_type |= BLE_HCI_ADV_SCAN_MASK | BLE_HCI_ADV_SCAN_RSP_MASK; + } + report->sec_phy = rxhdr->rxinfo.phy; + + /* Strip PDU header and ext header, leave only AD */ + os_mbuf_adj(rxpdu, 3 + eh_len); + + /* + * We only care about SyncInfo and TxPower so don't bother parsing if they + * are not present, just set to 'unknown' values. + */ + if ((eh_len == 0) || !(eh_flags & ((1 << BLE_LL_EXT_ADV_SYNC_INFO_BIT) | + (1 << BLE_LL_EXT_ADV_TX_POWER_BIT)))) { + report->periodic_itvl = 0; + report->tx_power = 0x7f; + return; + } + /* Now parse extended header... */ + + if (eh_flags & (1 << BLE_LL_EXT_ADV_ADVA_BIT)) { + eh_data += BLE_LL_EXT_ADV_ADVA_SIZE; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_TARGETA_BIT)) { + eh_data += BLE_LL_EXT_ADV_TARGETA_SIZE; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_CTE_INFO_BIT)) { + eh_data += BLE_LL_EXT_ADV_CTE_INFO_SIZE; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) { + eh_data += BLE_LL_EXT_ADV_DATA_INFO_SIZE; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { + eh_data += BLE_LL_EXT_ADV_AUX_PTR_SIZE; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_SYNC_INFO_BIT)) { + report->periodic_itvl = get_le16(eh_data + 2); + eh_data += BLE_LL_EXT_ADV_SYNC_INFO_SIZE; + } else { + report->periodic_itvl = 0; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_TX_POWER_BIT)) { + report->tx_power = *eh_data; + } else { + report->tx_power = 0x7f; + } +} + +static void +ble_ll_hci_ev_update_ext_adv_report_from_ext(struct ble_hci_ev *hci_ev, + struct os_mbuf *rxpdu, + struct ble_mbuf_hdr *rxhdr) +{ + struct ble_mbuf_hdr_rxinfo *rxinfo = &rxhdr->rxinfo; + struct ble_hci_ev_le_subev_ext_adv_rpt *hci_subev; + struct ext_adv_report *report; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + struct ble_ll_resolv_entry *rl; +#endif + uint8_t pdu_hdr; + uint8_t adv_mode; + uint8_t eh_len; + uint8_t eh_flags; + uint8_t *eh_data; + uint8_t *rxbuf; + + rxbuf = rxpdu->om_data; + + pdu_hdr = rxbuf[0]; + adv_mode = rxbuf[2] >> 6; + eh_len = rxbuf[2] & 0x3f; + eh_flags = rxbuf[3]; + eh_data = &rxbuf[4]; + + hci_ev->opcode = BLE_HCI_EVCODE_LE_META; + hci_ev->length = sizeof(*hci_subev) + sizeof(*report); + + hci_subev = (void *)hci_ev->data; + hci_subev->subev_code = BLE_HCI_LE_SUBEV_EXT_ADV_RPT; + hci_subev->num_reports = 1; + + report = hci_subev->reports; + + memset(report, 0, sizeof(*report)); + + report->evt_type = adv_mode; + + report->pri_phy = rxinfo->phy; + report->sec_phy = 0; + report->sid = 0xff; + report->rssi = rxhdr->rxinfo.rssi; + report->periodic_itvl = 0; + report->data_len = 0; + + /* Now parse extended header... */ + + if (eh_flags & (1 << BLE_LL_EXT_ADV_ADVA_BIT)) { +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + if (rxinfo->rpa_index >= 0) { + rl = &g_ble_ll_resolv_list[rxinfo->rpa_index]; + report->addr_type = rl->rl_addr_type + 2; + memcpy(report->addr, rl->rl_identity_addr, 6); + } else { + report->addr_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_TXADD_MASK); + memcpy(report->addr, eh_data, 6); + } +#else + report->addr_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_TXADD_MASK); + memcpy(report->addr, eh_data, 6); +#endif + eh_data += BLE_LL_EXT_ADV_ADVA_SIZE; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_TARGETA_BIT)) { + report->evt_type |= BLE_HCI_ADV_DIRECT_MASK; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + if (rxinfo->flags & BLE_MBUF_HDR_F_TARGETA_RESOLVED) { + report->dir_addr_type = (ble_ll_scan_get_own_addr_type() & 1) + 2; + memcpy(report->dir_addr, ble_ll_scan_aux_get_own_addr(), 6); + } else { + report->dir_addr_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_RXADD_MASK); + memcpy(report->dir_addr, eh_data, 6); + } +#else + report->dir_addr_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_RXADD_MASK); + memcpy(report->dir_addr, eh_data, 6); +#endif + eh_data += BLE_LL_EXT_ADV_TARGETA_SIZE; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_CTE_INFO_BIT)) { + eh_data += BLE_LL_EXT_ADV_CTE_INFO_SIZE; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) { + eh_data += BLE_LL_EXT_ADV_DATA_INFO_SIZE; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { + eh_data += BLE_LL_EXT_ADV_AUX_PTR_SIZE; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_SYNC_INFO_BIT)) { + eh_data += BLE_LL_EXT_ADV_SYNC_INFO_SIZE; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_TX_POWER_BIT)) { + report->tx_power = *eh_data; + } else { + report->tx_power = 0x7f; + } + + /* Strip PDU header and ext header, leave only AD */ + os_mbuf_adj(rxpdu, 3 + eh_len); + +} + +static void +ble_ll_hci_ev_send_ext_adv_truncated_report(struct ble_ll_scan_aux_data *aux) +{ + struct ble_hci_ev_le_subev_ext_adv_rpt *hci_subev; + struct ext_adv_report *report; + struct ble_hci_ev *hci_ev; + + if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) { + return; + } + + hci_ev = aux->hci_ev; + aux->hci_ev = NULL; + + BLE_LL_ASSERT(hci_ev); + + hci_subev = (void *)hci_ev->data; + report = hci_subev->reports; + report->evt_type |= BLE_HCI_ADV_DATA_STATUS_TRUNCATED; + + ble_ll_hci_event_send(hci_ev); + + aux->hci_state |= BLE_LL_SCAN_AUX_H_DONE | BLE_LL_SCAN_AUX_H_TRUNCATED; +} + +static int +ble_ll_hci_ev_send_ext_adv_report(struct os_mbuf *rxpdu, + struct ble_mbuf_hdr *rxhdr, + struct ble_hci_ev **hci_ev) +{ + struct ble_mbuf_hdr_rxinfo *rxinfo = &rxhdr->rxinfo; + struct ble_hci_ev_le_subev_ext_adv_rpt *hci_subev; + struct ble_hci_ev *hci_ev_next; + struct ext_adv_report *report; + bool truncated = false; + int max_data_len; + int data_len; + int offset; + + data_len = OS_MBUF_PKTLEN(rxpdu); + max_data_len = BLE_LL_MAX_EVT_LEN - + sizeof(**hci_ev) - sizeof(*hci_subev) - sizeof(*report); + offset = 0; + hci_ev_next = NULL; + + do { + hci_subev = (void *)(*hci_ev)->data; + report = hci_subev->reports; + + report->rssi = rxinfo->rssi; + + report->data_len = min(max_data_len, data_len - offset); + os_mbuf_copydata(rxpdu, offset, report->data_len, report->data); + (*hci_ev)->length += report->data_len; + + offset += report->data_len; + + /* + * We need another event if either there are still some data left in + * this PDU or scan for next aux is scheduled. + */ + if ((offset < data_len) || + (rxinfo->flags & BLE_MBUF_HDR_F_AUX_PTR_WAIT)) { + hci_ev_next = ble_ll_hci_ev_dup_ext_adv_report(*hci_ev); + if (hci_ev_next) { + report->evt_type |= BLE_HCI_ADV_DATA_STATUS_INCOMPLETE; + } else { + report->evt_type |= BLE_HCI_ADV_DATA_STATUS_TRUNCATED; + } + } + + switch (report->evt_type & BLE_HCI_ADV_DATA_STATUS_MASK) { + case BLE_HCI_ADV_DATA_STATUS_TRUNCATED: + truncated = true; + /* no break */ + case BLE_HCI_ADV_DATA_STATUS_COMPLETE: + BLE_LL_ASSERT(!hci_ev_next); + break; + case BLE_HCI_ADV_DATA_STATUS_INCOMPLETE: + BLE_LL_ASSERT(hci_ev_next); + break; + default: + BLE_LL_ASSERT(0); + } + + ble_ll_hci_event_send(*hci_ev); + + *hci_ev = hci_ev_next; + } while ((offset < data_len) && *hci_ev); + + return truncated ? -1 : 0; +} + + +static int +ble_ll_hci_ev_send_ext_adv_report_for_aux(struct os_mbuf *rxpdu, + struct ble_mbuf_hdr *rxhdr, + struct ble_ll_scan_aux_data *aux, + struct ble_ll_scan_addr_data *addrd) +{ + struct ble_hci_ev *hci_ev; + int rc; + + if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) { + return -1; + } + + /* + * We need to always keep one event allocated in aux to be able to truncate + * data properly in case of an error. If there is no event in aux it means + * this is first event and we can silently ignore in case of an error. + */ + if (aux->hci_ev) { + hci_ev = aux->hci_ev; + aux->hci_ev = NULL; + } else { + hci_ev = ble_ll_hci_ev_alloc_ext_adv_report_for_aux(addrd, aux); + if (!hci_ev) { + return -1; + } + } + + ble_ll_hci_ev_update_ext_adv_report_from_aux(hci_ev, rxpdu, rxhdr); + + rc = ble_ll_hci_ev_send_ext_adv_report(rxpdu, rxhdr, &hci_ev); + if (rc < 0) { + BLE_LL_ASSERT(!hci_ev); + aux->hci_state = BLE_LL_SCAN_AUX_H_DONE | BLE_LL_SCAN_AUX_H_TRUNCATED; + } else if (hci_ev) { + aux->hci_state = BLE_LL_SCAN_AUX_H_SENT_ANY; + } else { + aux->hci_state = BLE_LL_SCAN_AUX_H_DONE; + } + + aux->hci_ev = hci_ev; + + return rc; +} + +static void +ble_ll_hci_ev_send_ext_adv_report_for_ext(struct os_mbuf *rxpdu, + struct ble_mbuf_hdr *rxhdr) +{ + struct ble_hci_ev *hci_ev; + + if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) { + return; + } + + hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + if (!hci_ev) { + return; + } + + ble_ll_hci_ev_update_ext_adv_report_from_ext(hci_ev, rxpdu, rxhdr); + + ble_ll_hci_ev_send_ext_adv_report(rxpdu, rxhdr, &hci_ev); + + BLE_LL_ASSERT(!hci_ev); +} + +static void +ble_ll_scan_aux_break_ev(struct ble_npl_event *ev) +{ + struct ble_ll_scan_aux_data *aux = ble_npl_event_get_arg(ev); + + BLE_LL_ASSERT(aux); + + if (ble_ll_scan_aux_need_truncation(aux)) { + ble_ll_hci_ev_send_ext_adv_truncated_report(aux); + } + + ble_ll_scan_aux_update_scan_backoff(aux); + + ble_ll_scan_aux_free(aux); + ble_ll_scan_chk_resume(); +} + +void +ble_ll_scan_aux_break(struct ble_ll_scan_aux_data *aux) +{ + ble_npl_event_init(&aux->break_ev, ble_ll_scan_aux_break_ev, aux); + ble_ll_event_send(&aux->break_ev); +} + +static int +ble_ll_scan_aux_parse_aux_ptr(struct ble_ll_scan_aux_data *aux, + uint32_t aux_ptr, uint32_t *offset_us) +{ + uint8_t offset_unit; + uint32_t offset; + uint8_t chan; + uint8_t phy; + + phy = (aux_ptr >> 21) & 0x07; + switch (phy) { + case 0: + phy = BLE_PHY_1M; + break; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) + case 1: + phy = BLE_PHY_2M; + break; +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) + case 2: + phy = BLE_PHY_CODED; + break; +#endif + default: + return -1; + } + + chan = aux_ptr & 0x3f; + if (chan >= BLE_PHY_NUM_DATA_CHANS) { + return -1; + } + + offset = 30 * ((aux_ptr >> 8) & 0x1fff); + if ((aux_ptr >> 7) & 0x01) { + offset *= 10; + offset_unit = 1; + } else { + offset_unit = 0; + } + + if (offset < BLE_LL_MAFS) { + return -1; + } + + aux->sec_phy = phy; + aux->chan = chan; + aux->offset_unit = offset_unit; + + *offset_us = offset; + + return 0; +} + +int +ble_ll_scan_aux_sched(struct ble_ll_scan_aux_data *aux, uint32_t pdu_time, + uint8_t pdu_time_rem, uint32_t aux_ptr) +{ + uint32_t offset_us; + int rc; + + rc = ble_ll_scan_aux_parse_aux_ptr(aux, aux_ptr, &offset_us); + if (rc < 0) { + return -1; + } + + rc = ble_ll_sched_scan_aux(&aux->sch, pdu_time, pdu_time_rem, offset_us); + if (rc < 0) { + return -1; + } + + return 0; +} + +int +ble_ll_scan_aux_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *rxhdr) +{ + struct ble_ll_scan_aux_data *aux; + + if (pdu_type != BLE_ADV_PDU_TYPE_ADV_EXT_IND) { + return -1; + } + + BLE_LL_ASSERT(aux_data_current); + aux = aux_data_current; + + /* + * Prepare TX transition when doing active scanning and receiving 1st PDU + * since we may want to send AUX_SCAN_REQ. + */ + if ((aux->scan_type == BLE_SCAN_TYPE_ACTIVE) && + !(aux->flags & BLE_LL_SCAN_AUX_F_AUX_ADV)) { + return 1; + } + + return 0; +} + +static int +ble_ll_scan_aux_parse_to_aux_data(struct ble_ll_scan_aux_data *aux, + uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) +{ + uint8_t pdu_hdr; + uint8_t pdu_len; + uint8_t adv_mode; + uint8_t eh_len; + uint8_t eh_flags; + uint8_t *eh_data; + + pdu_hdr = rxbuf[0]; + pdu_len = rxbuf[1]; + + /* PDU without at least Extended Header Length is invalid */ + if (pdu_len == 0) { + return -1; + } + + /* Mark as AUX received on 1st PDU, then as CHAIN received on subsequent */ + if (aux->flags & BLE_LL_SCAN_AUX_F_AUX_ADV) { + aux->flags |= BLE_LL_SCAN_AUX_F_AUX_CHAIN; + } else { + aux->flags |= BLE_LL_SCAN_AUX_F_AUX_ADV; + } + + adv_mode = rxbuf[2] >> 6; + eh_len = rxbuf[2] & 0x3f; + + /* Only AUX_CHAIN_IND is valid without Extended Header */ + if (eh_len == 0) { + if (!(aux->flags & BLE_LL_SCAN_AUX_F_AUX_CHAIN) || adv_mode) { + return -1; + } + return 0; + } + + eh_flags = rxbuf[3]; + eh_data = &rxbuf[4]; + + /* Now parse extended header... */ + + /* AdvA is only valid in 1st PDU, ignore in AUX_CHAIN_IND */ + if (eh_flags & (1 << BLE_LL_EXT_ADV_ADVA_BIT)) { + if (!(aux->flags & BLE_LL_SCAN_AUX_F_AUX_CHAIN)) { + memcpy(aux->adva, eh_data, 6); + aux->adva_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_TXADD_MASK); + aux->flags |= BLE_LL_SCAN_AUX_F_HAS_ADVA; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + aux->rpa_index = ble_hw_resolv_list_match(); +#endif + } + eh_data += BLE_LL_EXT_ADV_ADVA_SIZE; + } + + /* TargetA is only valid in 1st PDU, ignore in AUX_CHAIN_IND */ + if (eh_flags & (1 << BLE_LL_EXT_ADV_TARGETA_BIT)) { + if (!(aux->flags & BLE_LL_SCAN_AUX_F_AUX_CHAIN)) { + memcpy(aux->targeta, eh_data, 6); + aux->targeta_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_RXADD_MASK); + aux->flags |= BLE_LL_SCAN_AUX_F_HAS_TARGETA; + } + eh_data += BLE_LL_EXT_ADV_TARGETA_SIZE; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_CTE_INFO_BIT)) { + eh_data += BLE_LL_EXT_ADV_CTE_INFO_SIZE; + } + + /* + * ADI handling is a bit convoluted.... + * ADI is mandatory in ADV_EXT_IND with AuxPtr and is also mandatory in PDU + * if included in superior PDU. This implies that each AUX_CHAIN shall have + * ADI. However... AUX_SCAN_RSP does not need to have ADI, so if there's no + * ADI in AUX_SCAN_RSP we allow it and clear corresponding flag to skip ADI + * checks on subsequent PDUs. + */ + if (eh_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) { + if (aux->flags & BLE_LL_SCAN_AUX_F_HAS_ADI) { + if (get_le16(eh_data) != aux->adi) { + return -1; + } + } + eh_data += BLE_LL_EXT_ADV_DATA_INFO_SIZE; + } else if (aux->flags & BLE_LL_SCAN_AUX_F_HAS_ADI) { + if (rxhdr->rxinfo.flags & BLE_MBUF_HDR_F_SCAN_RSP_RXD) { + aux->flags &= ~BLE_LL_SCAN_AUX_F_HAS_ADI; + } else { + return -1; + } + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { + aux->aux_ptr = get_le24(eh_data); + rxhdr->rxinfo.flags |= BLE_MBUF_HDR_F_AUX_PTR_WAIT; + } + + return 0; +} + +static int +ble_ll_scan_aux_ext_parse(uint8_t *rxbuf, struct ble_ll_scan_addr_data *addrd, + uint16_t *adi, uint32_t *aux_ptr) +{ + uint8_t pdu_hdr; + uint8_t pdu_len; + uint8_t adv_mode; + uint8_t eh_len; + uint8_t eh_flags; + uint8_t *eh_data; + + pdu_hdr = rxbuf[0]; + pdu_len = rxbuf[1]; + + if (pdu_len == 0) { + return -1; + } + + adv_mode = rxbuf[2] >> 6; + eh_len = rxbuf[2] & 0x3f; + + if ((adv_mode == 3) || (eh_len == 0)) { + return -1; + } + + eh_flags = rxbuf[3]; + eh_data = &rxbuf[4]; + + /* ADV_EXT_IND with AuxPtr but without ADI is invalid */ + if ((eh_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) && + !(eh_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT))) { + return -1; + } + + /* ADV_EXT_IND without either AdvA or AuxPtr is not valid */ + if (!(eh_flags & ((1 << BLE_LL_EXT_ADV_ADVA_BIT) | + (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)))) { + return -1; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_ADVA_BIT)) { + addrd->adva = eh_data; + addrd->adva_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_TXADD_RAND); + eh_data += BLE_LL_EXT_ADV_ADVA_SIZE; + } else { + addrd->adva = NULL; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_TARGETA_BIT)) { + addrd->targeta = eh_data; + addrd->targeta_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_RXADD_RAND); + eh_data += BLE_LL_EXT_ADV_TARGETA_SIZE; + } else { + addrd->targeta = NULL; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_CTE_INFO_BIT)) { + eh_data += BLE_LL_EXT_ADV_CTE_INFO_SIZE; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) { + *adi = get_le16(eh_data); + eh_data += BLE_LL_EXT_ADV_DATA_INFO_SIZE; + } else { + *adi = 0; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { + *aux_ptr = get_le24(eh_data); + } else { + *aux_ptr = 0; + } + + return 0; +} + +static void +ble_ll_scan_aux_update_rxinfo_from_addrd(struct ble_ll_scan_addr_data *addrd, + struct ble_mbuf_hdr_rxinfo *rxinfo) +{ +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + rxinfo->rpa_index = addrd->rpa_index; + if (addrd->adva_resolved) { + rxinfo->flags |= BLE_MBUF_HDR_F_RESOLVED; + } + if (addrd->targeta_resolved) { + rxinfo->flags |= BLE_MBUF_HDR_F_TARGETA_RESOLVED; + } +#endif +} + +static void +ble_ll_scan_aux_update_aux_data_from_addrd(struct ble_ll_scan_addr_data *addrd, + struct ble_ll_scan_aux_data *aux) +{ +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + aux->rpa_index = addrd->rpa_index; + if (addrd->adva_resolved) { + aux->flags |= BLE_LL_SCAN_AUX_F_RESOLVED_ADVA; + } + if (addrd->targeta_resolved) { + aux->flags |= BLE_LL_SCAN_AUX_F_RESOLVED_TARGETA; + } +#endif +} + +int +ble_ll_scan_aux_rx_isr_end_on_ext(struct ble_ll_scan_sm *scansm, + struct os_mbuf *rxpdu) +{ + struct ble_mbuf_hdr *rxhdr = BLE_MBUF_HDR_PTR(rxpdu); + struct ble_mbuf_hdr_rxinfo *rxinfo = &rxhdr->rxinfo; + struct ble_ll_scan_addr_data addrd; + struct ble_ll_scan_aux_data *aux; + uint8_t *rxbuf; + uint32_t aux_ptr; + uint16_t adi; + bool do_match; + int rc; + + rxbuf = rxpdu->om_data; + + rc = ble_ll_scan_aux_ext_parse(rxbuf, &addrd, &adi, &aux_ptr); + if (rc < 0) { + return -1; + } + + /* We can filter based on ext PDU alone if both AdvA and TargetA are present + * or there's no AuxPtr. Otherwise, we need to wait for aux PDU to filter. + */ + do_match = !aux_ptr || (addrd.adva && addrd.targeta); + if (do_match) { +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + addrd.rpa_index = ble_hw_resolv_list_match(); +#endif + rc = ble_ll_scan_rx_filter(ble_ll_scan_get_own_addr_type(), + ble_ll_scan_get_filt_policy(), + &addrd, NULL); + if (rc < 0) { + return -1; + } + + if (!aux_ptr) { + /* We do not allocate aux_data for ADV_EXT_IND without AuxPtr so + * need to pass match data in rxinfo. + */ + ble_ll_scan_aux_update_rxinfo_from_addrd(&addrd, rxinfo); + } + } + + if (aux_ptr) { + aux = ble_ll_scan_aux_alloc(); + if (!aux) { + return -1; + } + + aux->scan_type = scansm->scanp->scan_type; + + aux->pri_phy = rxinfo->phy; + aux->aux_ptr = aux_ptr; + + if (addrd.adva) { + memcpy(aux->adva, addrd.adva, 6); + aux->adva_type = addrd.adva_type; + aux->flags |= BLE_LL_SCAN_AUX_F_HAS_ADVA; + } + + if (addrd.targeta) { + memcpy(aux->targeta, addrd.targeta, 6); + aux->targeta_type = addrd.targeta_type; + aux->flags |= BLE_LL_SCAN_AUX_F_HAS_TARGETA; + } + + aux->adi = adi; + aux->flags |= BLE_LL_SCAN_AUX_F_HAS_ADI; + + if (do_match) { + aux->flags |= BLE_LL_SCAN_AUX_F_MATCHED; + ble_ll_scan_aux_update_aux_data_from_addrd(&addrd, aux); + } else if (addrd.adva) { +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + /* If ext PDU has AdvA, we need to store rpa_index to be able to + * reuse it for filtering when done on aux PDU. + */ + aux->rpa_index = ble_hw_resolv_list_match(); +#endif + } + + rxinfo->user_data = aux; + } + + return 0; +} + +void +ble_ll_scan_aux_pkt_in_on_ext(struct os_mbuf *rxpdu, + struct ble_mbuf_hdr *rxhdr) +{ + struct ble_mbuf_hdr_rxinfo *rxinfo = &rxhdr->rxinfo; + struct ble_ll_scan_aux_data *aux = rxinfo->user_data; + int rc; + + if (rxinfo->flags & BLE_MBUF_HDR_F_IGNORED) { + BLE_LL_ASSERT(!aux); + return; + } + + if (!aux) { + ble_ll_hci_ev_send_ext_adv_report_for_ext(rxpdu, rxhdr); + return; + } + + BLE_LL_ASSERT(aux->aux_ptr); + + rc = ble_ll_scan_aux_sched(aux, rxhdr->beg_cputime, rxhdr->rem_usecs, + aux->aux_ptr); + if (rc < 0) { + ble_ll_scan_aux_free(aux); + } +} + +static uint8_t +ble_ll_scan_aux_scan_req_tx_pdu_cb(uint8_t *dptr, void *arg, uint8_t *hdr_byte) +{ + struct ble_ll_scan_aux_data *aux = arg; + uint8_t *scana; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + struct ble_ll_resolv_entry *rl; + uint8_t rpa[BLE_DEV_ADDR_LEN]; +#endif + uint8_t hb; + + hb = BLE_ADV_PDU_TYPE_SCAN_REQ; + + /* ScanA */ + if (ble_ll_scan_get_own_addr_type() & 0x01) { + hb |= BLE_ADV_PDU_HDR_TXADD_RAND; + scana = g_random_addr; + } else { + scana = g_dev_addr; + } + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + if (ble_ll_scan_get_own_addr_type() & 0x02) { + if (aux->rpa_index >=0) { + rl = &g_ble_ll_resolv_list[aux->rpa_index]; + } else { + rl = NULL; + } + + /* + * If device is on RL and we have local IRK, we use RPA generated using + * that IRK as ScanA. Otherwise we use NRPA as ScanA to prevent our + * device from being tracked when doing an active scan + * ref: Core 5.2, Vol 6, Part B, section 6.3) + */ + if (rl && rl->rl_has_local) { + ble_ll_resolv_get_priv_addr(rl, 1, rpa); + scana = rpa; + } else { + scana = ble_ll_get_scan_nrpa(); + } + + hb |= BLE_ADV_PDU_HDR_TXADD_RAND; + } +#endif + memcpy(dptr, scana, BLE_DEV_ADDR_LEN); + + /* AdvA */ + if (aux->adva_type) { + hb |= BLE_ADV_PDU_HDR_RXADD_RAND; + } + memcpy(dptr + BLE_DEV_ADDR_LEN, aux->adva, BLE_DEV_ADDR_LEN); + + *hdr_byte = hb; + + return BLE_DEV_ADDR_LEN * 2; +} + +static bool +ble_ll_scan_aux_send_scan_req(struct ble_ll_scan_aux_data *aux, + struct ble_ll_scan_addr_data *addrd) +{ + int rc; + + /* Check if we already scanned this device successfully */ + if (ble_ll_scan_have_rxd_scan_rsp(addrd->adv_addr, addrd->adv_addr_type, + true, aux->adi)) { + return false; + } + + /* We want to send a request, see if backoff allows us */ + if (ble_ll_scan_backoff_kick() != 0) { + return false; + } + + /* TODO perhaps we should check if scan req+rsp won't overlap with scheduler + * item (old code did it), but for now let's just scan and we will be + * interrupted if scheduler kicks in. + */ + + rc = ble_phy_tx(ble_ll_scan_aux_scan_req_tx_pdu_cb, aux, + BLE_PHY_TRANSITION_TX_RX); + if (rc) { + return false; + } + + return true; +} + +int +ble_ll_scan_aux_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) +{ + struct ble_ll_scan_addr_data addrd; + struct ble_mbuf_hdr_rxinfo *rxinfo; + struct ble_ll_scan_aux_data *aux; + struct ble_mbuf_hdr *rxhdr; + uint8_t scan_ok; + uint8_t adv_mode; + uint8_t *rxbuf; + int rc; + + BLE_LL_ASSERT(aux_data_current); + aux = aux_data_current; + aux_data_current = NULL; + + if (rxpdu == NULL) { + ble_ll_scan_aux_break(aux); + goto done; + } + + rxhdr = BLE_MBUF_HDR_PTR(rxpdu); + rxinfo = &rxhdr->rxinfo; + rxinfo->user_data = aux; + + if (!crcok) { + rxinfo->flags |= BLE_MBUF_HDR_F_IGNORED; + goto done; + } + + rxbuf = rxpdu->om_data; + + if (aux->flags & BLE_LL_SCAN_AUX_F_W4_SCAN_RSP) { + aux->flags &= ~BLE_LL_SCAN_AUX_F_W4_SCAN_RSP; + aux->flags |= BLE_LL_SCAN_AUX_F_SCANNED; + rxinfo->flags |= BLE_MBUF_HDR_F_SCAN_RSP_RXD; + } + + rc = ble_ll_scan_aux_parse_to_aux_data(aux, rxbuf, rxhdr); + if (rc < 0) { + rxinfo->flags |= BLE_MBUF_HDR_F_IGNORED; + goto done; + } + + if (aux->flags & BLE_LL_SCAN_AUX_F_MATCHED) { + goto done; + } + + /* We do filtering on either ADV_EXT_IND or AUX_ADV_IND so we should not be + * here when processing AUX_CHAIN_IND. + */ + BLE_LL_ASSERT(!(aux->flags & BLE_LL_SCAN_AUX_F_AUX_CHAIN)); + + if (aux->flags & BLE_LL_SCAN_AUX_F_HAS_ADVA) { + addrd.adva = aux->adva; + addrd.adva_type = aux->adva_type; + } else { + addrd.adva = NULL; + } + + if (aux->flags & BLE_LL_SCAN_AUX_F_HAS_TARGETA) { + addrd.targeta = aux->targeta; + addrd.targeta_type = aux->targeta_type; + } else { + addrd.targeta = NULL; + } + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + addrd.rpa_index = aux->rpa_index; +#endif + + rc = ble_ll_scan_rx_filter(ble_ll_scan_get_own_addr_type(), + ble_ll_scan_get_filt_policy(), + &addrd, &scan_ok); + if (rc < 0) { + rxinfo->flags |= BLE_MBUF_HDR_F_IGNORED; + /* + * XXX hack warning + * Even if PDU was not allowed by current scan filter policy, we should + * still allow it to sync if SyncInfo is present. Since we do not use + * F_DEVMATCH in aux code for its intended purpose, let's use it here to + * indicate no match due to scan filter policy. + */ + if (rc == -2) { + rxinfo->flags |= BLE_MBUF_HDR_F_DEVMATCH; + } + goto done; + } + + aux->flags |= BLE_LL_SCAN_AUX_F_MATCHED; + + ble_ll_scan_aux_update_aux_data_from_addrd(&addrd, aux); + + adv_mode = rxbuf[2] >> 6; + + if ((aux->scan_type == BLE_SCAN_TYPE_ACTIVE) && + (adv_mode == BLE_LL_EXT_ADV_MODE_SCAN) && scan_ok) { + if (ble_ll_scan_aux_send_scan_req(aux, &addrd)) { + /* AUX_SCAN_REQ sent, keep PHY enabled to continue */ + aux->flags |= BLE_LL_SCAN_AUX_F_W4_SCAN_RSP; + rxinfo->flags |= BLE_MBUF_HDR_F_SCAN_REQ_TXD; + aux_data_current = aux; + return 0; + } + } + +done: + /* We are done with this PDU so go to standby and let LL resume if needed */ + ble_ll_state_set(BLE_LL_STATE_STANDBY); + return -1; +} + +static void +ble_ll_scan_aux_init_addrd_from_aux_data(struct ble_ll_scan_aux_data *aux, + struct ble_ll_scan_addr_data *addrd) +{ +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + struct ble_ll_resolv_entry *rl; +#endif + + if (aux->flags & BLE_LL_SCAN_AUX_F_HAS_ADVA) { + addrd->adva = aux->adva; + addrd->adva_type = aux->adva_type; + } else { + addrd->adva = NULL; + addrd->adva_type = 0; + } + + if (aux->flags & BLE_LL_SCAN_AUX_F_HAS_TARGETA) { + addrd->targeta = aux->targeta; + addrd->targeta_type = aux->targeta_type; + } else { + addrd->targeta = NULL; + addrd->targeta_type = 0; + } + + addrd->adv_addr = addrd->adva; + addrd->adv_addr_type = addrd->adva_type; + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + addrd->rpa_index = aux->rpa_index; + + if (aux->flags & BLE_LL_SCAN_AUX_F_RESOLVED_ADVA) { + BLE_LL_ASSERT(aux->rpa_index >= 0); + rl = &g_ble_ll_resolv_list[aux->rpa_index]; + addrd->adv_addr = rl->rl_identity_addr; + addrd->adv_addr_type = rl->rl_addr_type; + addrd->adva_resolved = 1; + } else { + addrd->adva_resolved = 0; + } + + if (aux->flags & BLE_LL_SCAN_AUX_F_RESOLVED_TARGETA) { + addrd->targeta = ble_ll_scan_aux_get_own_addr(); + addrd->targeta_type = ble_ll_scan_get_own_addr_type() & 1; + addrd->targeta_resolved = 1; + } else { + addrd->targeta_resolved = 0; + } +#endif +} + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) +static void +ble_ll_scan_aux_sync_check(struct os_mbuf *rxpdu, + struct ble_ll_scan_addr_data *addrd) +{ + struct ble_mbuf_hdr *rxhdr = BLE_MBUF_HDR_PTR(rxpdu); + uint8_t *rxbuf = rxpdu->om_data; + uint8_t adv_mode; + uint8_t eh_len; + uint8_t eh_flags; + uint8_t *eh_data; + uint8_t sid; + + adv_mode = rxbuf[2] >> 6; + + if (adv_mode != BLE_LL_EXT_ADV_MODE_NON_CONN) { + return; + } + + eh_len = rxbuf[2] & 0x3f; + + if (eh_len == 0) { + return; + } + + eh_flags = rxbuf[3]; + eh_data = &rxbuf[4]; + + /* Need ADI and SyncInfo */ + if (!(eh_flags & ((1 << BLE_LL_EXT_ADV_SYNC_INFO_BIT) | + (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)))) { + return; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_ADVA_BIT)) { + eh_data += BLE_LL_EXT_ADV_ADVA_SIZE; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_TARGETA_BIT)) { + eh_data += BLE_LL_EXT_ADV_TARGETA_SIZE; + } + + if (eh_flags & (1 << BLE_LL_EXT_ADV_CTE_INFO_BIT)) { + eh_data += 1; + } + + sid = get_le16(eh_data) >> 12; + eh_data += BLE_LL_EXT_ADV_DATA_INFO_SIZE; + + if (eh_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { + eh_data += BLE_LL_EXT_ADV_AUX_PTR_SIZE; + } + + ble_ll_sync_info_event(addrd, sid, rxhdr, eh_data); +} +#endif + +void +ble_ll_scan_aux_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr) +{ + struct ble_ll_scan_addr_data addrd; + struct ble_mbuf_hdr_rxinfo *rxinfo; + struct ble_ll_scan_aux_data *aux; + bool scan_duplicate = false; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) + bool sync_check = false; +#endif + int rc; + + rxinfo = &rxhdr->rxinfo; + aux = rxinfo->user_data; + + BLE_LL_ASSERT(aux); + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) + sync_check = ble_ll_sync_enabled() && + !(aux->flags & BLE_LL_SCAN_AUX_F_AUX_CHAIN); + + /* PDU was not allowed due to scan filter policy, but we can still try to + * sync since separate filter policy is used for this purpose. + */ + if ((rxinfo->flags & BLE_MBUF_HDR_F_DEVMATCH) && sync_check) { + ble_ll_scan_aux_init_addrd_from_aux_data(aux, &addrd); + ble_ll_scan_aux_sync_check(rxpdu, &addrd); + } +#endif + + if (rxinfo->flags & BLE_MBUF_HDR_F_IGNORED) { + if (ble_ll_scan_aux_need_truncation(aux)) { + ble_ll_hci_ev_send_ext_adv_truncated_report(aux); + } else { + aux->hci_state |= BLE_LL_SCAN_AUX_H_DONE; + } + + ble_ll_scan_aux_update_scan_backoff(aux); + } + + if (aux->hci_state & BLE_LL_SCAN_AUX_H_DONE) { + ble_ll_scan_aux_free(aux); + ble_ll_scan_chk_resume(); + return; + } + + /* Try to schedule scan for subsequent aux asap, if needed */ + if (rxinfo->flags & BLE_MBUF_HDR_F_AUX_PTR_WAIT) { + rc = ble_ll_scan_aux_sched(aux, rxhdr->beg_cputime, rxhdr->rem_usecs, + aux->aux_ptr); + if (rc < 0) { + rxinfo->flags &= ~BLE_MBUF_HDR_F_AUX_PTR_WAIT; + } + } + + ble_ll_scan_aux_init_addrd_from_aux_data(aux, &addrd); + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) + if (sync_check) { + ble_ll_scan_aux_sync_check(rxpdu, &addrd); + } +#endif + + scan_duplicate = ble_ll_scan_get_filt_dups() && + ble_ll_scan_dup_check_ext(addrd.adv_addr_type, + addrd.adv_addr, true, aux->adi); + if (!scan_duplicate) { + rc = ble_ll_hci_ev_send_ext_adv_report_for_aux(rxpdu, rxhdr, aux, + &addrd); + + /* + * Update duplicates list if report was sent successfully and we are + * done with this chain. On error, status is already set to 'done' so + * we will cancel aux scan (if any) and stop further processing. + * However, if we send AUX_SCAN_REQ for this PDU then need to remove + * 'done' as we should continue with scanning after AUX_SCAN_RSP. + */ + + if (rc == 0) { + if (rxinfo->flags & BLE_MBUF_HDR_F_SCAN_REQ_TXD) { + aux->hci_state &= ~BLE_LL_SCAN_AUX_H_DONE; + } else if (aux->hci_state & BLE_LL_SCAN_AUX_H_DONE) { + BLE_LL_ASSERT(!(rxinfo->flags & BLE_MBUF_HDR_F_AUX_PTR_WAIT)); + if (ble_ll_scan_get_filt_dups()) { + ble_ll_scan_dup_update_ext(addrd.adv_addr_type, + addrd.adv_addr, true, aux->adi); + } + if (aux->flags & BLE_LL_SCAN_AUX_F_SCANNED) { + ble_ll_scan_add_scan_rsp_adv(addrd.adv_addr, + addrd.adv_addr_type, + 1, aux->adi); + } + } + } + } else { + /* This is a duplicate, we don't want to scan it anymore */ + aux->hci_state |= BLE_LL_SCAN_AUX_H_DONE; + } + + /* + * If we are done processing this chain and aux scan was not scheduled or + * we removed it from scheduler, we can remove aux_data now. Otherwise we + * will remove on next pkt_in. + */ + if ((aux->hci_state & BLE_LL_SCAN_AUX_H_DONE) && + (!(rxinfo->flags & BLE_MBUF_HDR_F_AUX_PTR_WAIT) || + (ble_ll_sched_rmv_elem(&aux->sch) == 0))) { + ble_ll_scan_aux_update_scan_backoff(aux); + ble_ll_scan_aux_free(aux); + } + + ble_ll_scan_chk_resume(); +} + +void +ble_ll_scan_aux_wfr_timer_exp(void) +{ + ble_phy_disable(); + ble_ll_scan_aux_halt(); +} + +void +ble_ll_scan_aux_halt(void) +{ + struct ble_ll_scan_aux_data *aux = aux_data_current; + + BLE_LL_ASSERT(aux); + + aux_data_current = NULL; + + ble_ll_state_set(BLE_LL_STATE_STANDBY); + + ble_ll_scan_aux_break(aux); +} + +void +ble_ll_scan_aux_sched_remove(struct ble_ll_sched_item *sch) +{ + ble_ll_scan_aux_break(sch->cb_arg); +} + +void +ble_ll_scan_aux_init(void) +{ + os_error_t err; + + err = os_mempool_init(&aux_data_pool, + MYNEWT_VAL(BLE_LL_SCAN_AUX_SEGMENT_CNT), + sizeof(struct ble_ll_scan_aux_data), + aux_data_mem, "ble_ll_scan_aux_data_pool"); + BLE_LL_ASSERT(err == 0); +} + +#endif /* BLE_LL_CFG_FEAT_LL_EXT_ADV */ \ No newline at end of file diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index d01f10edab..c41ad3fef6 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -28,6 +28,7 @@ #include "controller/ble_ll_sched.h" #include "controller/ble_ll_adv.h" #include "controller/ble_ll_scan.h" +#include "controller/ble_ll_scan_aux.h" #include "controller/ble_ll_rfmgmt.h" #include "controller/ble_ll_trace.h" #include "controller/ble_ll_sync.h" @@ -244,6 +245,9 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) ble_ll_adv_event_rmvd_from_sched((struct ble_ll_adv_sm *)entry->cb_arg); break; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + case BLE_LL_SCHED_TYPE_SCAN_AUX: + ble_ll_scan_aux_break(entry->cb_arg); + break; case BLE_LL_SCHED_TYPE_AUX_SCAN: ble_ll_scan_end_adv_evt((struct ble_ll_aux_data *)entry->cb_arg); break; @@ -1463,6 +1467,11 @@ ble_ll_sched_execute_item(struct ble_ll_sched_item *sch) } else if (lls == BLE_LL_STATE_SYNC) { STATS_INC(ble_ll_stats, sched_state_sync_errs); ble_ll_sync_halt(); +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + } else if (lls == BLE_LL_STATE_SCAN_AUX) { + ble_ll_state_set(BLE_LL_STATE_STANDBY); + ble_ll_scan_aux_halt(); #endif } else { STATS_INC(ble_ll_stats, sched_state_conn_errs); @@ -1714,6 +1723,65 @@ ble_ll_sched_aux_scan(struct ble_mbuf_hdr *ble_hdr, return rc; } + +int +ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time, + uint8_t pdu_time_rem, uint32_t offset_us) +{ + struct ble_ll_sched_item *entry; + uint32_t offset_ticks; + os_sr_t sr; + int rc; + + offset_us += pdu_time_rem; + offset_ticks = os_cputime_usecs_to_ticks(offset_us); + + sch->start_time = pdu_time + offset_ticks - g_ble_ll_sched_offset_ticks; + sch->remainder = offset_us - os_cputime_ticks_to_usecs(offset_ticks); + /* TODO: make some sane slot reservation */ + sch->end_time = sch->start_time + os_cputime_usecs_to_ticks(5000); + + OS_ENTER_CRITICAL(sr); + + if (!ble_ll_sched_insert_if_empty(sch)) { + /* Scheduler was empty, inserted as 1st element */ + rc = 0; + goto done; + } + + os_cputime_timer_stop(&g_ble_ll_sched_timer); + TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { + if (CPUTIME_LEQ(sch->end_time, entry->start_time)) { + TAILQ_INSERT_BEFORE(entry, sch, link); + sch->enqueued = 1; + rc = 0; + break; + } + + if (ble_ll_sched_is_overlap(sch, entry)) { + rc = -1; + break; + } + } + + if (!entry) { + TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); + sch->enqueued = 1; + rc = 0; + } + +done: + entry = TAILQ_FIRST(&g_ble_ll_sched_q); + + OS_EXIT_CRITICAL(sr); + + if (entry == sch) { + ble_ll_rfmgmt_sched_changed(sch); + } + os_cputime_timer_start(&g_ble_ll_sched_timer, entry->start_time); + + return rc; +} #endif #if MYNEWT_VAL(BLE_LL_DTM) diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 7c46d10a29..cdffc4bf18 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -1333,14 +1333,11 @@ ble_ll_sync_event_end(struct ble_npl_event *ev) } void -ble_ll_sync_info_event(const uint8_t *addr, uint8_t addr_type, int rpa_index, +ble_ll_sync_info_event(struct ble_ll_scan_addr_data *addrd, uint8_t sid, struct ble_mbuf_hdr *rxhdr, const uint8_t *syncinfo) { struct ble_ll_sync_sm *sm = NULL; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) - const uint8_t *rpa = NULL; -#endif uint16_t max_skip; uint32_t offset; uint32_t usecs; @@ -1365,28 +1362,21 @@ ble_ll_sync_info_event(const uint8_t *addr, uint8_t addr_type, int rpa_index, return; } - /* check if resolved */ - if (rpa_index >= 0) { -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) - rpa = addr; -#endif - addr = g_ble_ll_resolv_list[rpa_index].rl_identity_addr; - addr_type = g_ble_ll_resolv_list[rpa_index].rl_addr_type; - } - /* check peer */ if (g_ble_ll_sync_create_params.options & BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_FILTER) { - if (ble_ll_sync_on_list(addr, addr_type, sid) < 0) { + if (ble_ll_sync_on_list(addrd->adv_addr, + addrd->adv_addr_type, sid) < 0) { return; } /* set addr and sid in sm */ sm->adv_sid = sid; - sm->adv_addr_type = addr_type; - memcpy(sm->adv_addr, addr, BLE_DEV_ADDR_LEN); + sm->adv_addr_type = addrd->adv_addr_type; + memcpy(sm->adv_addr, addrd->adv_addr, BLE_DEV_ADDR_LEN); } else { - if ((sm->adv_sid != sid) || (sm->adv_addr_type != addr_type) || - memcmp(sm->adv_addr, addr, BLE_DEV_ADDR_LEN)) { + if ((sm->adv_sid != sid) || + (sm->adv_addr_type != addrd->adv_addr_type) || + memcmp(sm->adv_addr, addrd->adv_addr, BLE_DEV_ADDR_LEN)) { return; } } @@ -1406,12 +1396,14 @@ ble_ll_sync_info_event(const uint8_t *addr, uint8_t addr_type, int rpa_index, return; } - if (rpa_index >= 0) { +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + if (addrd->adva_resolved) { sm->flags |= BLE_LL_SYNC_SM_FLAG_ADDR_RESOLVED; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) - memcpy(sm->adv_addr_rpa, rpa, BLE_DEV_ADDR_LEN); + memcpy(sm->adv_addr_rpa, addrd->adva, BLE_DEV_ADDR_LEN); #endif } +#endif /* set params from HCI LE Create Periodic Sync */ sm->timeout = g_ble_ll_sync_create_params.timeout; diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index b900ba9106..ea5590f8e4 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -291,6 +291,12 @@ syscfg.defs: restrictions: - 'BLE_LL_CFG_FEAT_LL_ISO if 1' + BLE_LL_SCAN_AUX_SEGMENT_CNT: + description: > + Number of auxiliary advertising segments that can be scanned + concurrently (Core 5.2, Vol 6, Part B, 4.4.2.2.2). + value: 8 + BLE_LL_EXT_ADV_AUX_PTR_CNT: description: > This option configure a max number of scheduled outstanding auxiliary From 08e69722d9b427c05400f4cb0483a02a0e63ce20 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 29 Sep 2021 23:44:37 +0200 Subject: [PATCH 0009/1333] nimble/ll: Fix TX time restrictions during phy transition We do not need to restrict TX time after sending LL_PHY_REQ as a master, this only applies to slave. This makes LL/CON/CEN/BV-53-C pass instead of being inconclusive due to data fragmentation done by IUT between LL_PHY_REQ and LL_PHU_UPDATE_IND. Ref: Core 5.x, Vol. 6, Part B, section 5.1.10.1 --- nimble/controller/src/ble_ll_ctrl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index c4ac6504c9..384a48756e 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -2858,8 +2858,11 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) #endif #if (BLE_LL_BT5_PHY_SUPPORTED == 1) case BLE_LL_CTRL_PHY_REQ: - connsm->phy_tx_transition = - ble_ll_ctrl_phy_tx_transition_get(connsm->phy_data.req_pref_tx_phys_mask); + if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + connsm->phy_tx_transition = + ble_ll_ctrl_phy_tx_transition_get( + connsm->phy_data.req_pref_tx_phys_mask); + } break; case BLE_LL_CTRL_PHY_UPDATE_IND: connsm->phy_tx_transition = From 17f985ff00900fed845f9f6aaa9b2dfb93a704af Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 30 Sep 2021 14:22:19 +0200 Subject: [PATCH 0010/1333] porting: Fix typo in linux blemesh sample --- porting/examples/linux_blemesh/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porting/examples/linux_blemesh/Makefile b/porting/examples/linux_blemesh/Makefile index 556fc8ca6c..c1518e0e4d 100644 --- a/porting/examples/linux_blemesh/Makefile +++ b/porting/examples/linux_blemesh/Makefile @@ -17,7 +17,7 @@ # Toolchain commands CROSS_COMPILE ?= -CC := ccache $(CROSS_COMPILIE)gcc +CC := ccache $(CROSS_COMPILE)gcc CXX := ccache $(CROSS_COMPILE)g++ LD := $(CROSS_COMPILE)gcc AR := $(CROSS_COMPILE)ar From 93368f517fa12cede5eaaaab99e53210377bfa5f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sun, 3 Oct 2021 01:20:44 +0200 Subject: [PATCH 0011/1333] travis.yml: Bump Go to 1.16 This is required for updated install script to work properly. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 285b81e5d0..0b59e7a862 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,7 @@ _addons: &addon_conf - gcc-7-multilib go: - - "1.12" + - "1.16" git: depth: false From aa14cf801ae36d22ca5889541bc2149a347700b6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 29 Sep 2021 21:24:21 +0200 Subject: [PATCH 0012/1333] nimble/ll: Fix handling of removing adv item from scheduler If adv item is removed from scheduler we should drop event instead of just sending done event. Sending done event instead can cause issues on extended advertising instances if we remove aux items since it does not clear aux_active flag. As a result, when done even is handled and we reached max_events, HCI event will not be sent since it waits for done event for secondary channel but that one won't cone since aux items are already removed. --- nimble/controller/src/ble_ll_adv.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 6ab6b24331..7efe914240 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -206,6 +206,8 @@ struct ble_ll_adv_sm struct ble_ll_adv_sm g_ble_ll_adv_sm[BLE_ADV_INSTANCES]; struct ble_ll_adv_sm *g_ble_ll_cur_adv_sm; +static void ble_ll_adv_drop_event(struct ble_ll_adv_sm *advsm); + static struct ble_ll_adv_sm * ble_ll_adv_sm_find_configured(uint8_t instance) { @@ -1049,12 +1051,7 @@ ble_ll_adv_tx_done(void *arg) void ble_ll_adv_event_rmvd_from_sched(struct ble_ll_adv_sm *advsm) { - /* - * Need to set advertising channel to final chan so new event gets - * scheduled. - */ - advsm->adv_chan = ble_ll_adv_final_chan(advsm); - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev); + ble_ll_adv_drop_event(advsm); } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) From 74e121759876df954ea1dce73d27e0eb65ff822e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 30 Sep 2021 23:24:24 +0200 Subject: [PATCH 0013/1333] nimble/ll: Fix build with past and without privacy --- nimble/controller/src/ble_ll_sync.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index cdffc4bf18..78d9456f64 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -1922,6 +1922,7 @@ ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, rpa_index = -1; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) /* check if need to resolve */ if (ble_ll_is_rpa(addr, addr_type)) { rpa_index = ble_ll_resolv_peer_rpa_any(addr); @@ -1931,6 +1932,7 @@ ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, addr_type = g_ble_ll_resolv_list[rpa_index].rl_addr_type; } } +#endif OS_ENTER_CRITICAL(sr); /* check if already synchronized with this peer */ From 94039bc18e4173f5e058483d763c23aaea147853 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 27 Sep 2021 23:20:25 +0200 Subject: [PATCH 0014/1333] nimble/ll: Remove unused code Not used anymore. --- .../include/controller/ble_ll_sched.h | 2 - nimble/controller/src/ble_ll_sched.c | 47 ------------------- 2 files changed, 49 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index 96834bb075..bed864029f 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -200,8 +200,6 @@ int ble_ll_sched_aux_scan(struct ble_mbuf_hdr *ble_hdr, struct ble_ll_scan_sm *scansm, struct ble_ll_aux_data *aux_scan); -int ble_ll_sched_scan_req_over_aux_ptr(uint32_t chan, uint8_t phy_mode); - int ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time, uint8_t pdu_time_rem, uint32_t offset_us); #endif diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index c41ad3fef6..b0fc4f5c42 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -1562,53 +1562,6 @@ ble_ll_sched_next_time(uint32_t *next_event_time) } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -/** - * Called to check if there is place for a planned scan req. - * - * @param chan - * @param phy_mode - * - * @return int 0: Clear for scan req 1: there is an upcoming event - */ -int -ble_ll_sched_scan_req_over_aux_ptr(uint32_t chan, uint8_t phy_mode) -{ - struct ble_ll_sched_item *sch; - uint32_t usec_dur; - uint32_t now = os_cputime_get32(); - - /* Lets calculate roughly how much time we need for scan req and scan rsp */ - usec_dur = ble_ll_pdu_tx_time_get(BLE_SCAN_REQ_LEN, phy_mode); - if (chan >= BLE_PHY_NUM_DATA_CHANS) { - usec_dur += ble_ll_pdu_tx_time_get(BLE_SCAN_RSP_MAX_LEN, phy_mode); - } else { - usec_dur += ble_ll_pdu_tx_time_get(BLE_SCAN_RSP_MAX_EXT_LEN, phy_mode); - } - - sch = TAILQ_FIRST(&g_ble_ll_sched_q); - while (sch) { - /* Let's check if there is no scheduled item which want to start within - * given usecs.*/ - if (CPUTIME_GT(sch->start_time, now + os_cputime_usecs_to_ticks(usec_dur))) { - /* We are fine. Have time for scan req */ - return 0; - } - - /* There is something in the scheduler. If it is not aux ptr we assume - * it is more important that scan req - */ - if (sch->sched_type != BLE_LL_SCHED_TYPE_AUX_SCAN) { - return 1; - } - - ble_ll_scan_end_adv_evt((struct ble_ll_aux_data *)sch->cb_arg); - TAILQ_REMOVE(&g_ble_ll_sched_q, sch, link); - sch->enqueued = 0; - sch = TAILQ_FIRST(&g_ble_ll_sched_q); - } - return 0; -} - /** * Called to schedule a aux scan. * From c0ef83b072542da7a47f53dc6af20bd108843281 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 30 Sep 2021 23:14:14 +0200 Subject: [PATCH 0015/1333] nimble/ll: Add clarification comment Just clarify why we should return here instead of 'break'. --- nimble/controller/src/ble_ll_scan.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index cf264b0ab0..399ce22580 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -2133,6 +2133,9 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) rxinfo->flags |= BLE_MBUF_HDR_F_IGNORED; } ble_ll_state_set(BLE_LL_STATE_STANDBY); + /* Return here, we do not want any further processing since it's all + * handled in scan_aux. + */ return -1; #endif default: From cddb7c4ccee72e718c8b1a57166e702917e02c13 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 30 Sep 2021 20:39:09 +0200 Subject: [PATCH 0016/1333] nimble/ll: Fix phy configuration for initiator Not sure how this even works, but configuration flags for phys were never set... --- nimble/controller/src/ble_ll_scan.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 399ce22580..660abf9023 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -2986,6 +2986,12 @@ ble_ll_scan_initiator_start(struct hci_create_conn *hcc, scanp->timing.interval = ble_ll_scan_time_hci_to_ticks(hcc->scan_itvl); scanp->timing.window = ble_ll_scan_time_hci_to_ticks(hcc->scan_window); scanp->scan_type = BLE_SCAN_TYPE_INITIATE; + scanp->configured = 1; + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) + scanp = &scansm->scan_phys[PHY_CODED]; + scanp->configured = 0; +#endif rc = ble_ll_scan_sm_start(scansm); if (sm == NULL) { @@ -3019,20 +3025,23 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, scansm->scanp_next = NULL; scansm->ext_scanning = 1; + params = &hcc->params[0]; + scanp_uncoded = &scansm->scan_phys[PHY_UNCODED]; if (hcc->init_phy_mask & BLE_PHY_MASK_1M) { - params = &hcc->params[0]; - scanp_uncoded = &scansm->scan_phys[PHY_UNCODED]; - + scanp_uncoded->configured = 1; scanp_uncoded->timing.interval = ble_ll_scan_time_hci_to_ticks(params->scan_itvl); scanp_uncoded->timing.window = ble_ll_scan_time_hci_to_ticks(params->scan_window); scanp_uncoded->scan_type = BLE_SCAN_TYPE_INITIATE; scansm->scanp = scanp_uncoded; + } else { + scanp_uncoded->configured = 0; } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) + params = &hcc->params[2]; + scanp_coded = &scansm->scan_phys[PHY_CODED]; if (hcc->init_phy_mask & BLE_PHY_MASK_CODED) { - params = &hcc->params[2]; - scanp_coded = &scansm->scan_phys[PHY_CODED]; - + scanp_coded->configured = 1; scanp_coded->timing.interval = ble_ll_scan_time_hci_to_ticks(params->scan_itvl); scanp_coded->timing.window = ble_ll_scan_time_hci_to_ticks(params->scan_window); scanp_coded->scan_type = BLE_SCAN_TYPE_INITIATE; @@ -3041,7 +3050,12 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, } else { scansm->scanp = scanp_coded; } + } else { + scanp_coded->configured = 0; } +#else + scanp_coded = NULL; +#endif /* if any of PHYs is configured for continuous scan we alter interval to * fit other PHY From 6c9f70972e8c68efe1fd38d413778c9487c5d997 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 6 Oct 2021 17:33:02 +0200 Subject: [PATCH 0017/1333] nimble/ll: Fix scanning with LL Privacy disabled This is regression after eed4389851fcf96922a2e429376808f2dfddc912. Without this fix only SCAN_RSP are reported back to host... --- nimble/controller/src/ble_ll_scan.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 660abf9023..9b123622cb 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1939,9 +1939,7 @@ ble_ll_scan_rx_isr_on_adv(uint8_t pdu_type, uint8_t *rxbuf, { struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; struct ble_ll_scan_phy *scanp = scansm->scanp; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) struct ble_mbuf_hdr_rxinfo *rxinfo = &hdr->rxinfo; -#endif uint8_t scan_ok; int rc; @@ -1957,8 +1955,8 @@ ble_ll_scan_rx_isr_on_adv(uint8_t pdu_type, uint8_t *rxbuf, return 0; } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) rxinfo->flags |= BLE_MBUF_HDR_F_DEVMATCH; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) rxinfo->rpa_index = addrd->rpa_index; if (addrd->adva_resolved) { rxinfo->flags |= BLE_MBUF_HDR_F_RESOLVED; From 6c9f95ad23c5ed8703ee7e35107a246b3e287dcd Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 5 Oct 2021 17:17:39 +0200 Subject: [PATCH 0018/1333] nimble/ll: Optimize AUX_CONNECT_REQ tx Currently we initialize a lot of connsm settings prior to scheduling 1st connection event and this takes some time. However, we only need connection interval, latency and supervision timeout to be initialized in order to schedule event properly and send AUX_CONNECT_REQ, other stuff can be done after tx has already started. This is especially important on slower MCU like CMAC as with old code it was barely possible to make tx within Tifs even on speed build. New code saves ~15us on CMAC prior to tx so we have quite a good margin to complete on time. --- .../include/controller/ble_ll_conn.h | 5 +- nimble/controller/src/ble_ll_conn.c | 38 +++++++------ nimble/controller/src/ble_ll_conn_hci.c | 54 ++++++++++++++----- 3 files changed, 66 insertions(+), 31 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index d7db6878a1..daf7db5848 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -192,8 +192,9 @@ struct hci_ext_conn_params { uint16_t scan_itvl; uint16_t scan_window; - uint16_t conn_itvl_min; - uint16_t conn_itvl_max; + uint32_t conn_itvl; + uint16_t conn_itvl_ticks; + uint8_t conn_itvl_usecs; uint16_t conn_latency; uint16_t supervision_timeout; uint16_t min_ce_len; diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index af610b50ba..53303789b9 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1755,14 +1755,6 @@ void ble_ll_conn_ext_set_params(struct ble_ll_conn_sm *connsm, struct hci_ext_conn_params *hcc_params, int phy) { - /* Set slave latency and supervision timeout */ - connsm->slave_latency = hcc_params->conn_latency; - connsm->supervision_tmo = hcc_params->supervision_timeout; - - /* XXX: for now, just make connection interval equal to max */ - connsm->conn_itvl = hcc_params->conn_itvl_max; - - /* Check the min/max CE lengths are less than connection interval */ if (hcc_params->min_ce_len > (connsm->conn_itvl * 2)) { connsm->min_ce_len = connsm->conn_itvl * 2; @@ -1776,8 +1768,6 @@ ble_ll_conn_ext_set_params(struct ble_ll_conn_sm *connsm, connsm->max_ce_len = hcc_params->max_ce_len; } - ble_ll_conn_calc_itvl_ticks(connsm); - #if (BLE_LL_BT5_PHY_SUPPORTED == 1) ble_ll_conn_init_phy(connsm, phy); #endif @@ -3176,6 +3166,7 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok, struct ble_ll_resolv_entry *rl; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + struct hci_ext_conn_params *hcp; struct ble_ll_scan_sm *scansm; uint8_t phy; #endif @@ -3425,15 +3416,16 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok, } if (connsm->scansm->ext_scanning) { - phy = ble_hdr->rxinfo.phy; + phy = ble_hdr->rxinfo.phy; - /* Update connection state machine with appropriate parameters for - * certain PHY - */ - ble_ll_conn_ext_set_params(connsm, - &connsm->initial_params.params[phy - 1], - phy); + hcp = &connsm->initial_params.params[phy - 1]; + connsm->slave_latency = hcp->conn_latency; + connsm->supervision_tmo = hcp->supervision_timeout; + + connsm->conn_itvl = hcp->conn_itvl; + connsm->conn_itvl_ticks = hcp->conn_itvl_ticks; + connsm->conn_itvl_usecs = hcp->conn_itvl_usecs; } #endif @@ -3472,6 +3464,18 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok, ble_hdr->rxinfo.user_data = NULL; STATS_INC(ble_ll_stats, aux_conn_req_tx); } + + if (connsm->scansm->ext_scanning) { + phy = ble_hdr->rxinfo.phy; + + /* Update connection state machine with appropriate parameters for + * certain PHY + */ + ble_ll_conn_ext_set_params(connsm, + &connsm->initial_params.params[phy - 1], + phy); + + } #endif STATS_INC(ble_ll_conn_stats, conn_req_txd); diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 9936b9d34e..aa6de540ba 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -556,6 +556,25 @@ ble_ll_conn_hcc_params_set_fallback(struct hci_ext_create_conn *hcc, #endif } +static void +ble_ll_conn_itvl_to_ticks(uint32_t itvl, uint16_t *itvl_ticks, + uint8_t *itvl_usecs) +{ + uint32_t ticks; + uint32_t usecs; + + usecs = itvl * BLE_LL_CONN_ITVL_USECS; + ticks = os_cputime_usecs_to_ticks(usecs); + usecs = usecs - os_cputime_ticks_to_usecs(ticks); + if (usecs == 31) { + usecs = 0; + ++ticks; + } + + *itvl_ticks = ticks; + *itvl_usecs = usecs; +} + int ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len) { @@ -564,6 +583,8 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len) const struct hci_ext_conn_params *fallback_params = NULL; struct hci_ext_create_conn hcc = { 0 }; struct ble_ll_conn_sm *connsm; + uint16_t conn_itvl_min; + uint16_t conn_itvl_max; int rc; /* validate length */ @@ -629,13 +650,12 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len) return rc; } - hcc.params[0].conn_itvl_min = le16toh(params->conn_min_itvl); - hcc.params[0].conn_itvl_max = le16toh(params->conn_min_itvl); + conn_itvl_min = le16toh(params->conn_min_itvl); + conn_itvl_max = le16toh(params->conn_max_itvl); hcc.params[0].conn_latency = le16toh(params->conn_latency); hcc.params[0].supervision_timeout = le16toh(params->supervision_timeout); - rc = ble_ll_conn_hci_chk_conn_params(hcc.params[0].conn_itvl_min, - hcc.params[0].conn_itvl_max, + rc = ble_ll_conn_hci_chk_conn_params(conn_itvl_min, conn_itvl_max, hcc.params[0].conn_latency, hcc.params[0].supervision_timeout); if (rc) { @@ -649,6 +669,10 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } + hcc.params[0].conn_itvl = conn_itvl_max; + ble_ll_conn_itvl_to_ticks(conn_itvl_max, &hcc.params[0].conn_itvl_ticks, + &hcc.params[0].conn_itvl_usecs); + fallback_params = &hcc.params[0]; params++; } @@ -660,13 +684,12 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len) } len -= sizeof(*params); - hcc.params[1].conn_itvl_min = le16toh(params->conn_min_itvl); - hcc.params[1].conn_itvl_max = le16toh(params->conn_min_itvl); + conn_itvl_min = le16toh(params->conn_min_itvl); + conn_itvl_max = le16toh(params->conn_max_itvl); hcc.params[1].conn_latency = le16toh(params->conn_latency); hcc.params[1].supervision_timeout = le16toh(params->supervision_timeout); - rc = ble_ll_conn_hci_chk_conn_params(hcc.params[1].conn_itvl_min, - hcc.params[1].conn_itvl_max, + rc = ble_ll_conn_hci_chk_conn_params(conn_itvl_min, conn_itvl_max, hcc.params[1].conn_latency, hcc.params[1].supervision_timeout); if (rc) { @@ -680,6 +703,10 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } + hcc.params[1].conn_itvl = conn_itvl_max; + ble_ll_conn_itvl_to_ticks(conn_itvl_max, &hcc.params[1].conn_itvl_ticks, + &hcc.params[1].conn_itvl_usecs); + params++; } #endif @@ -700,13 +727,12 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len) return rc; } - hcc.params[2].conn_itvl_min = le16toh(params->conn_min_itvl); - hcc.params[2].conn_itvl_max = le16toh(params->conn_min_itvl); + conn_itvl_min = le16toh(params->conn_min_itvl); + conn_itvl_max = le16toh(params->conn_max_itvl); hcc.params[2].conn_latency = le16toh(params->conn_latency); hcc.params[2].supervision_timeout = le16toh(params->supervision_timeout); - rc = ble_ll_conn_hci_chk_conn_params(hcc.params[2].conn_itvl_min, - hcc.params[2].conn_itvl_max, + rc = ble_ll_conn_hci_chk_conn_params(conn_itvl_min, conn_itvl_max, hcc.params[2].conn_latency, hcc.params[2].supervision_timeout); if (rc) { @@ -720,6 +746,10 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } + hcc.params[2].conn_itvl = conn_itvl_max; + ble_ll_conn_itvl_to_ticks(conn_itvl_max, &hcc.params[2].conn_itvl_ticks, + &hcc.params[2].conn_itvl_usecs); + if (!fallback_params) { fallback_params = &hcc.params[2]; } From a892c8f78952907c88b9ff714a446a73348cef5c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 5 Oct 2021 17:21:39 +0200 Subject: [PATCH 0019/1333] nimble/ll: Allow 2M params as fallback for ext conn create We ignore 2M values only for scanning since we do not scan on 2M when ext conn create is pending, but there's nothing wrong in using those parameters as fallback in case we established connection on phy that was not in phy mask. --- nimble/controller/src/ble_ll_conn_hci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index aa6de540ba..fe384c4147 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -707,6 +707,9 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len) ble_ll_conn_itvl_to_ticks(conn_itvl_max, &hcc.params[1].conn_itvl_ticks, &hcc.params[1].conn_itvl_usecs); + if (!fallback_params) { + fallback_params = &hcc.params[1]; + } params++; } #endif From 4ed4f9e3814b617f800094f74f8c01306f95f6a5 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 4 Oct 2021 10:09:14 +0200 Subject: [PATCH 0020/1333] mesh: Fix linux port It looks like create_free_list() in glue.c requires word aligned blocks which on 64-bit is 8 bytes. --- nimble/host/mesh/include/mesh/glue.h | 2 +- nimble/host/mesh/src/glue.c | 1 + nimble/host/mesh/src/transport.c | 7 ++++--- porting/npl/linux/include/nimble/nimble_npl_os.h | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index 8c9166c259..9a4bd9a524 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -411,7 +411,7 @@ static inline unsigned int find_msb_set(uint32_t op) #define CONFIG_BT_MESH_LPN_GROUPS MYNEWT_VAL(BLE_MESH_LPN_GROUPS) #define CONFIG_BT_MESH_ADV_BUF_COUNT MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT) -#define CONFIG_BT_MESH_SEG_BUFS MYNEWT_VAL(BLE_MESH_SEG_BUFS ) +#define CONFIG_BT_MESH_SEG_BUFS MYNEWT_VAL(BLE_MESH_SEG_BUFS) #define CONFIG_BT_MESH_FRIEND_QUEUE_SIZE MYNEWT_VAL(BLE_MESH_FRIEND_QUEUE_SIZE) #define CONFIG_BT_MESH_FRIEND_RECV_WIN MYNEWT_VAL(BLE_MESH_FRIEND_RECV_WIN) #define CONFIG_BT_MESH_LPN_POLL_TIMEOUT MYNEWT_VAL(BLE_MESH_LPN_POLL_TIMEOUT) diff --git a/nimble/host/mesh/src/glue.c b/nimble/host/mesh/src/glue.c index aab7f37414..8862344dca 100644 --- a/nimble/host/mesh/src/glue.c +++ b/nimble/host/mesh/src/glue.c @@ -906,6 +906,7 @@ int create_free_list(struct k_mem_slab *slab) uint32_t j; char *p; + /* blocks must be word aligned */ if(((slab->block_size | (uintptr_t)slab->buffer) & (sizeof(void *) - 1)) != 0) { return -EINVAL; diff --git a/nimble/host/mesh/src/transport.c b/nimble/host/mesh/src/transport.c index 6391272d02..3582c998bf 100644 --- a/nimble/host/mesh/src/transport.c +++ b/nimble/host/mesh/src/transport.c @@ -113,11 +113,12 @@ static struct seg_rx { struct k_delayed_work ack; } seg_rx[CONFIG_BT_MESH_RX_SEG_MSG_COUNT]; -char _k_mem_slab_buffer_[(BT_MESH_APP_SEG_SDU_MAX*CONFIG_BT_MESH_SEG_BUFS)]; + +char _k_mem_slab_buffer_[OS_ALIGN((BT_MESH_APP_SEG_SDU_MAX)*(CONFIG_BT_MESH_SEG_BUFS), OS_ALIGNMENT)]; struct k_mem_slab segs = { .num_blocks = CONFIG_BT_MESH_SEG_BUFS, - .block_size = BT_MESH_APP_SEG_SDU_MAX, + .block_size = OS_ALIGN(BT_MESH_APP_SEG_SDU_MAX, OS_ALIGNMENT), .buffer = _k_mem_slab_buffer_, .free_list = NULL, .num_used = 0 @@ -1616,7 +1617,7 @@ void bt_mesh_trans_init(void) /* We need to initialize memslab free list here */ rc = create_free_list(&segs); if (rc) { - BT_ERR("Failed to create free memslab list") + BT_ERR("Failed to create free memslab list (error: %d)", rc); } for (i = 0; i < ARRAY_SIZE(seg_tx); i++) { diff --git a/porting/npl/linux/include/nimble/nimble_npl_os.h b/porting/npl/linux/include/nimble/nimble_npl_os.h index bdd3988699..585d378525 100644 --- a/porting/npl/linux/include/nimble/nimble_npl_os.h +++ b/porting/npl/linux/include/nimble/nimble_npl_os.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "os_types.h" @@ -30,7 +31,7 @@ extern "C" { #endif -#define BLE_NPL_OS_ALIGNMENT 4 +#define BLE_NPL_OS_ALIGNMENT (__WORDSIZE / 8) #define BLE_NPL_TIME_FOREVER INT32_MAX From c185dd6719b1cc9e08abada79e16e866118d3501 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 1 Oct 2021 22:08:10 +0200 Subject: [PATCH 0021/1333] nimble/ll: Fix encrypted data PDU payload length calculation Encrypted data PDU payload includes MIC, so we need to take this into account when calculating actual payload size available for data. --- nimble/controller/src/ble_ll_conn.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 53303789b9..a2a577e769 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -918,6 +918,7 @@ static uint16_t ble_ll_conn_adjust_pyld_len(struct ble_ll_conn_sm *connsm, uint16_t pyld_len) { uint16_t phy_max_tx_octets; + uint16_t mic_len; uint16_t ret; #if (BLE_LL_BT5_PHY_SUPPORTED == 1) @@ -940,11 +941,19 @@ ble_ll_conn_adjust_pyld_len(struct ble_ll_conn_sm *connsm, uint16_t pyld_len) ret = pyld_len; - if (ret > connsm->eff_max_tx_octets) { + mic_len = 0; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) + if (CONN_F_ENCRYPTED(connsm)) { + mic_len = BLE_LL_DATA_MIC_LEN; + } +#endif + + + if (ret > connsm->eff_max_tx_octets - mic_len) { ret = connsm->eff_max_tx_octets; } - if (ret > phy_max_tx_octets) { + if (ret > phy_max_tx_octets - mic_len) { ret = phy_max_tx_octets; } From fbd0a8c24d369a17dc04281f58a17ed7392e7f22 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 28 Sep 2021 01:38:26 +0200 Subject: [PATCH 0022/1333] nimble/ll: Refactor item scheduling This refactors all scheduling APIs (i.e. insertions to scheduler) to use common code instead of reimplementing the same or similar flow over and over again. The single 'ble_ll_sched_insert' call covers all currently possible scenarios with minimal overhead so all existing insertion APIs use it and add some more extra processing if needed. Also it adds some flexibility via preemption callback so it's possible to better define priorities for each item. --- .../include/controller/ble_ll_sched.h | 9 +- nimble/controller/src/ble_ll_adv.c | 22 +- nimble/controller/src/ble_ll_conn.c | 4 +- nimble/controller/src/ble_ll_sched.c | 1083 +++++------------ 4 files changed, 352 insertions(+), 766 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index bed864029f..15f331998c 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -25,8 +25,8 @@ extern "C" { #endif /* Time per BLE scheduler slot */ -#define BLE_LL_SCHED_USECS_PER_SLOT (1250) -#define BLE_LL_SCHED_32KHZ_TICKS_PER_SLOT (41) /* 1 tick = 30.517 usecs */ +#define BLE_LL_SCHED_USECS_PER_SLOT (1250) +#define BLE_LL_SCHED_TICKS_PER_SLOT (41) /* 1 tick = 30.517 usecs */ /* * Worst case time needed for scheduled advertising item. This is the longest @@ -160,8 +160,7 @@ int ble_ll_sched_adv_new(struct ble_ll_sched_item *sch, ble_ll_sched_adv_new_cb cb, void *arg); /* Schedule periodic advertising event */ -int ble_ll_sched_periodic_adv(struct ble_ll_sched_item *sch, uint32_t *start, - bool after_overlap); +int ble_ll_sched_periodic_adv(struct ble_ll_sched_item *sch, bool first_event); int ble_ll_sched_sync_reschedule(struct ble_ll_sched_item *sch, uint32_t anchor_point, @@ -172,7 +171,7 @@ int ble_ll_sched_sync(struct ble_ll_sched_item *sch, int8_t phy_mode); /* Reschedule an advertising event */ -int ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch, uint32_t *start, +int ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch, uint32_t max_delay_ticks); /* Reschedule and advertising pdu */ diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 7efe914240..19270accde 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -2280,7 +2280,6 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm, { struct ble_ll_adv_sync *sync; struct ble_ll_sched_item *sch; - uint32_t sch_start; uint32_t max_usecs; uint8_t chan; int rc; @@ -2323,7 +2322,7 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm, sch->end_time = sch->start_time + ble_ll_usecs_to_ticks_round_up(max_usecs); sch->start_time -= g_ble_ll_sched_offset_ticks; - rc = ble_ll_sched_periodic_adv(sch, &sch_start, first_pdu); + rc = ble_ll_sched_periodic_adv(sch, first_pdu); if (rc) { STATS_INC(ble_ll_stats, periodic_adv_drop_event); ble_npl_eventq_put(&g_ble_ll_data.ll_evq, @@ -2331,7 +2330,7 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm, return; } - sync->start_time = sch_start + g_ble_ll_sched_offset_ticks; + sync->start_time = sch->start_time + g_ble_ll_sched_offset_ticks; assert(first_pdu || (sync->start_time == advsm->periodic_adv_event_start_time)); @@ -4585,13 +4584,15 @@ ble_ll_adv_drop_event(struct ble_ll_adv_sm *advsm) static void ble_ll_adv_reschedule_event(struct ble_ll_adv_sm *advsm) { - int rc; - uint32_t start_time; + struct ble_ll_sched_item *sch; uint32_t max_delay_ticks; + int rc; assert(advsm->adv_enabled); - if (!advsm->adv_sch.enqueued) { + sch = &advsm->adv_sch; + + if (!sch->enqueued) { if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) { max_delay_ticks = 0; } else { @@ -4599,16 +4600,15 @@ ble_ll_adv_reschedule_event(struct ble_ll_adv_sm *advsm) os_cputime_usecs_to_ticks(BLE_LL_ADV_DELAY_MS_MAX * 1000); } - rc = ble_ll_sched_adv_reschedule(&advsm->adv_sch, &start_time, - max_delay_ticks); + rc = ble_ll_sched_adv_reschedule(sch, max_delay_ticks); if (rc) { ble_ll_adv_drop_event(advsm); return; } - start_time += g_ble_ll_sched_offset_ticks; - advsm->adv_event_start_time = start_time; - advsm->adv_pdu_start_time = start_time; + advsm->adv_event_start_time = sch->start_time + + g_ble_ll_sched_offset_ticks; + advsm->adv_pdu_start_time = advsm->adv_event_start_time; } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index a2a577e769..0f930d94e3 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2337,7 +2337,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) #if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) itvl = g_ble_ll_sched_data.sch_ticks_per_period; #else - itvl = MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * BLE_LL_SCHED_32KHZ_TICKS_PER_SLOT; + itvl = MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * BLE_LL_SCHED_TICKS_PER_SLOT; #endif if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { @@ -2451,7 +2451,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) #else connsm->ce_end_time = connsm->anchor_point + - (MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * BLE_LL_SCHED_32KHZ_TICKS_PER_SLOT) + (MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * BLE_LL_SCHED_TICKS_PER_SLOT) + os_cputime_usecs_to_ticks(connsm->slave_cur_tx_win_usecs) + 1; #endif connsm->slave_cur_window_widening = BLE_LL_JITTER_USECS; diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index b0fc4f5c42..1eb7d549ea 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -20,7 +20,6 @@ #include #include #include -#include "os/os.h" #include "os/os_cputime.h" #include "ble/xcvr.h" #include "controller/ble_phy.h" @@ -35,20 +34,21 @@ #include "ble_ll_priv.h" #include "ble_ll_conn_priv.h" -/* XXX: this is temporary. Not sure what I want to do here */ -struct hal_timer g_ble_ll_sched_timer; +#define BLE_LL_SCHED_MAX_DELAY_ANY (0x7fffffff) -uint8_t g_ble_ll_sched_offset_ticks; +static struct hal_timer g_ble_ll_sched_timer; +static uint8_t g_ble_ll_sched_timer_running; -#define BLE_LL_SCHED_ADV_WORST_CASE_USECS \ - (BLE_LL_SCHED_MAX_ADV_PDU_USECS + BLE_LL_IFS + BLE_LL_SCHED_ADV_MAX_USECS \ - + XCVR_TX_SCHED_DELAY_USECS) +uint8_t g_ble_ll_sched_offset_ticks; #if (BLE_LL_SCHED_DEBUG == 1) int32_t g_ble_ll_sched_max_late; int32_t g_ble_ll_sched_max_early; #endif +typedef int (* ble_ll_sched_preempt_cb_t)(struct ble_ll_sched_item *sch, + struct ble_ll_sched_item *item); + /* XXX: TODO: * 1) Add some accounting to the schedule code to see how late we are * (min/max?) @@ -62,12 +62,203 @@ int32_t g_ble_ll_sched_max_early; */ /* Queue for timers */ -TAILQ_HEAD(ll_sched_qhead, ble_ll_sched_item) g_ble_ll_sched_q; +static TAILQ_HEAD(ll_sched_qhead, ble_ll_sched_item) g_ble_ll_sched_q; #if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) struct ble_ll_sched_obj g_ble_ll_sched_data; #endif +static int +preempt_any(struct ble_ll_sched_item *sch, + struct ble_ll_sched_item *item) +{ + return 1; +} + +static int +preempt_none(struct ble_ll_sched_item *sch, + struct ble_ll_sched_item *item) +{ + return 0; +} + +static int +preempt_any_except_conn(struct ble_ll_sched_item *sch, + struct ble_ll_sched_item *item) +{ + BLE_LL_ASSERT(sch->sched_type == BLE_LL_SCHED_TYPE_CONN); + + if (item->sched_type != BLE_LL_SCHED_TYPE_CONN) { + return 1; + } + + return ble_ll_conn_is_lru(sch->cb_arg, item->cb_arg); +} + +static inline int +ble_ll_sched_check_overlap(struct ble_ll_sched_item *sch1, + struct ble_ll_sched_item *sch2) +{ + /* Note: item ranges are defined as [start, end) so items do not overlap + * if one item starts at the same time as another ends. + */ + return CPUTIME_GT(sch1->end_time, sch2->start_time) && + CPUTIME_GT(sch2->end_time, sch1->start_time); +} + +static void +ble_ll_sched_preempt(struct ble_ll_sched_item *sch, + struct ble_ll_sched_item *first) +{ + struct ble_ll_sched_item *entry; + struct ble_ll_sched_item *next; + struct ble_ll_conn_sm *connsm; + + entry = first; + + do { + next = TAILQ_NEXT(entry, link); + + TAILQ_REMOVE(&g_ble_ll_sched_q, entry, link); + entry->enqueued = 0; + + switch (entry->sched_type) { + case BLE_LL_SCHED_TYPE_CONN: + connsm = (struct ble_ll_conn_sm *)entry->cb_arg; + ble_ll_event_send(&connsm->conn_ev_end); + break; + case BLE_LL_SCHED_TYPE_ADV: + ble_ll_adv_event_rmvd_from_sched(entry->cb_arg); + break; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + case BLE_LL_SCHED_TYPE_SCAN_AUX: + ble_ll_scan_aux_break(entry->cb_arg); + break; + case BLE_LL_SCHED_TYPE_AUX_SCAN: + ble_ll_scan_end_adv_evt(entry->cb_arg); + break; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) + case BLE_LL_SCHED_TYPE_PERIODIC: + ble_ll_adv_periodic_rmvd_from_sched(entry->cb_arg); + break; + case BLE_LL_SCHED_TYPE_SYNC: + ble_ll_sync_rmvd_from_sched(entry->cb_arg); + break; +#endif +#endif + default: + BLE_LL_ASSERT(0); + break; + } + + entry = next; + } while (entry != sch); +} + +static inline void +ble_ll_sched_q_head_changed(void) +{ + struct ble_ll_sched_item *first; + + g_ble_ll_sched_timer_running = 0; + os_cputime_timer_stop(&g_ble_ll_sched_timer); + + first = TAILQ_FIRST(&g_ble_ll_sched_q); + ble_ll_rfmgmt_sched_changed(first); +} + +static inline void +ble_ll_sched_restart(void) +{ + struct ble_ll_sched_item *first; + + first = TAILQ_FIRST(&g_ble_ll_sched_q); + + if (!g_ble_ll_sched_timer_running && first) { + g_ble_ll_sched_timer_running = 1; + os_cputime_timer_start(&g_ble_ll_sched_timer, first->start_time); + } +} + +static int +ble_ll_sched_insert(struct ble_ll_sched_item *sch, uint32_t max_delay, + ble_ll_sched_preempt_cb_t preempt_cb) +{ + struct ble_ll_sched_item *preempt_first; + struct ble_ll_sched_item *first; + struct ble_ll_sched_item *entry; + uint32_t max_start_time; + uint32_t duration; + + OS_ASSERT_CRITICAL(); + + preempt_first = NULL; + + max_start_time = sch->start_time + max_delay; + duration = sch->end_time - sch->start_time; + + first = TAILQ_FIRST(&g_ble_ll_sched_q); + if (!first) { + TAILQ_INSERT_HEAD(&g_ble_ll_sched_q, sch, link); + sch->enqueued = 1; + goto done; + } + + TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { + if (CPUTIME_LEQ(sch->end_time, entry->start_time)) { + TAILQ_INSERT_BEFORE(entry, sch, link); + sch->enqueued = 1; + goto done; + } + + /* If current item overlaps our item check if we can preempt. If we + * cannot preempt, move our item past current item and see if it's + * still within allowed range. + */ + + if (ble_ll_sched_check_overlap(sch, entry)) { + if (preempt_cb(sch, entry)) { + if (!preempt_first) { + preempt_first = entry; + } + } else { + sch->start_time = entry->end_time; + + if ((max_delay == 0) || CPUTIME_GEQ(sch->start_time, + max_start_time)) { + sch->enqueued = 0; + goto done; + } + + sch->end_time = sch->start_time + duration; + preempt_first = NULL; + } + } + } + + if (!entry) { + TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); + sch->enqueued = 1; + } + +done: + if (preempt_first) { + BLE_LL_ASSERT(sch->enqueued); + ble_ll_sched_preempt(sch, preempt_first); + } + + /* Pause scheduler if inserted as 1st item, we do not want to miss this + * one. Caller should restart outside critical section. + */ + if (TAILQ_FIRST(&g_ble_ll_sched_q) == sch) { + BLE_LL_ASSERT(sch->enqueued); + ble_ll_sched_q_head_changed(); + } + + return sch->enqueued ? 0 : -1; +} + +#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) /** * Checks if two events in the schedule will overlap in time. NOTE: consecutive * schedule items can end and start at the same time. @@ -98,6 +289,7 @@ ble_ll_sched_is_overlap(struct ble_ll_sched_item *s1, return rc; } +#endif /* * Determines if the schedule item overlaps the currently running schedule @@ -119,26 +311,7 @@ ble_ll_sched_overlaps_current(struct ble_ll_sched_item *sch) return rc; } -static int -ble_ll_sched_conn_overlap(struct ble_ll_sched_item *entry) -{ - int rc; - struct ble_ll_conn_sm *connsm; - - /* Should only be advertising or a connection here */ - if (entry->sched_type == BLE_LL_SCHED_TYPE_CONN) { - connsm = (struct ble_ll_conn_sm *)entry->cb_arg; - entry->enqueued = 0; - TAILQ_REMOVE(&g_ble_ll_sched_q, entry, link); - ble_ll_event_send(&connsm->conn_ev_end); - rc = 0; - } else { - rc = -1; - } - - return rc; -} - +#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) static struct ble_ll_sched_item * ble_ll_sched_insert_if_empty(struct ble_ll_sched_item *sch) { @@ -151,18 +324,15 @@ ble_ll_sched_insert_if_empty(struct ble_ll_sched_item *sch) } return entry; } +#endif int ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) { - int rc; - os_sr_t sr; - uint32_t usecs; struct ble_ll_sched_item *sch; - struct ble_ll_sched_item *start_overlap; - struct ble_ll_sched_item *end_overlap; - struct ble_ll_sched_item *entry; - struct ble_ll_conn_sm *tmp; + uint32_t usecs; + os_sr_t sr; + int rc; /* Get schedule element from connection */ sch = &connsm->conn_sch; @@ -183,7 +353,6 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) return -1; } - /* We have to find a place for this schedule */ OS_ENTER_CRITICAL(sr); if (ble_ll_sched_overlaps_current(sch)) { @@ -191,101 +360,11 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) return -1; } - /* Stop timer since we will add an element */ - os_cputime_timer_stop(&g_ble_ll_sched_timer); - - start_overlap = NULL; - end_overlap = NULL; - rc = 0; - TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { - if (ble_ll_sched_is_overlap(sch, entry)) { - if (entry->sched_type == BLE_LL_SCHED_TYPE_CONN && - !ble_ll_conn_is_lru((struct ble_ll_conn_sm *)sch->cb_arg, - (struct ble_ll_conn_sm *)entry->cb_arg)) { - /* Only insert if this element is older than all that we - * overlap - */ - start_overlap = NULL; - rc = -1; - break; - } - - if (start_overlap == NULL) { - start_overlap = entry; - end_overlap = entry; - } else { - end_overlap = entry; - } - } else { - if (CPUTIME_LEQ(sch->end_time, entry->start_time)) { - rc = 0; - TAILQ_INSERT_BEFORE(entry, sch, link); - break; - } - } - } - - if (!rc) { - if (!entry) { - TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); - } - sch->enqueued = 1; - } - - /* Remove first to last scheduled elements */ - entry = start_overlap; - while (entry) { - start_overlap = TAILQ_NEXT(entry,link); - switch (entry->sched_type) { - case BLE_LL_SCHED_TYPE_CONN: - tmp = (struct ble_ll_conn_sm *)entry->cb_arg; - ble_ll_event_send(&tmp->conn_ev_end); - break; - case BLE_LL_SCHED_TYPE_ADV: - ble_ll_adv_event_rmvd_from_sched((struct ble_ll_adv_sm *)entry->cb_arg); - break; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - case BLE_LL_SCHED_TYPE_SCAN_AUX: - ble_ll_scan_aux_break(entry->cb_arg); - break; - case BLE_LL_SCHED_TYPE_AUX_SCAN: - ble_ll_scan_end_adv_evt((struct ble_ll_aux_data *)entry->cb_arg); - break; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) - case BLE_LL_SCHED_TYPE_PERIODIC: - ble_ll_adv_periodic_rmvd_from_sched((struct ble_ll_adv_sm *)entry->cb_arg); - break; - case BLE_LL_SCHED_TYPE_SYNC: - ble_ll_sync_rmvd_from_sched((struct ble_ll_sync_sm *)entry->cb_arg); - break; -#endif -#endif - default: - BLE_LL_ASSERT(0); - break; - } - - TAILQ_REMOVE(&g_ble_ll_sched_q, entry, link); - entry->enqueued = 0; - - if (entry == end_overlap) { - break; - } - entry = start_overlap; - } - - entry = TAILQ_FIRST(&g_ble_ll_sched_q); - if (entry == sch) { - ble_ll_rfmgmt_sched_changed(sch); - } else { - sch = entry; - } + rc = ble_ll_sched_insert(sch, 0, preempt_any_except_conn); OS_EXIT_CRITICAL(sr); - /* Restart timer */ - BLE_LL_ASSERT(sch != NULL); - os_cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time); + ble_ll_sched_restart(); return rc; } @@ -405,7 +484,7 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, } } earliest_start += MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET) * - BLE_LL_SCHED_32KHZ_TICKS_PER_SLOT; + BLE_LL_SCHED_TICKS_PER_SLOT; itvl_t = connsm->conn_itvl_ticks; /* We have to find a place for this schedule */ @@ -540,27 +619,17 @@ int ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *ble_hdr, uint8_t pyld_len) { - int rc; - os_sr_t sr; - uint8_t req_slots; - uint32_t initial_start; + struct ble_ll_sched_item *sch; + uint32_t orig_start_time; uint32_t earliest_start; - uint32_t earliest_end; - uint32_t dur; - uint32_t itvl_t; + uint32_t min_win_offset; + uint32_t max_delay; uint32_t adv_rxend; - struct ble_ll_sched_item *entry; - struct ble_ll_sched_item *sch; - - /* - * XXX: TODO this code assumes the advertisement and connect request were - * sent at 1Mbps. - */ + os_sr_t sr; + int rc; /* Get schedule element from connection */ - rc = -1; sch = &connsm->conn_sch; - req_slots = MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS); /* XXX: * The calculations for the 32kHz crystal bear alot of explanation. The @@ -603,7 +672,6 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, * wont be listening. We could do better calculation if we wanted to use * a transmit window of 1 as opposed to 2, but for now we dont care. */ - dur = req_slots * BLE_LL_SCHED_32KHZ_TICKS_PER_SLOT; adv_rxend = os_cputime_get32(); if (ble_hdr->rxinfo.channel >= BLE_PHY_NUM_DATA_CHANS) { /* @@ -635,86 +703,38 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, BLE_LL_ASSERT(0); } } - earliest_start += MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET) * - BLE_LL_SCHED_32KHZ_TICKS_PER_SLOT; - earliest_end = earliest_start + dur; - itvl_t = connsm->conn_itvl_ticks; - /* We have to find a place for this schedule */ - OS_ENTER_CRITICAL(sr); + sch->start_time = earliest_start - g_ble_ll_sched_offset_ticks; + sch->end_time = earliest_start + MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * + BLE_LL_SCHED_TICKS_PER_SLOT; - /* The schedule item must occur after current running item (if any) */ - sch->start_time = earliest_start; - initial_start = earliest_start; + orig_start_time = sch->start_time; - if (!ble_ll_sched_insert_if_empty(sch)) { - /* Nothing in schedule. Schedule as soon as possible */ - rc = 0; - connsm->tx_win_off = MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET); - } else { - os_cputime_timer_stop(&g_ble_ll_sched_timer); - TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { - /* Set these because overlap function needs them to be set */ - sch->start_time = earliest_start; - sch->end_time = earliest_end; + min_win_offset = MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET) * + BLE_LL_SCHED_TICKS_PER_SLOT; + sch->start_time += min_win_offset; + sch->end_time += min_win_offset; - /* We can insert if before entry in list */ - if (CPUTIME_LEQ(sch->end_time, entry->start_time)) { - if ((earliest_start - initial_start) <= itvl_t) { - rc = 0; - TAILQ_INSERT_BEFORE(entry, sch, link); - } - break; - } + max_delay = connsm->conn_itvl_ticks - min_win_offset; - /* Check for overlapping events */ - if (ble_ll_sched_is_overlap(sch, entry)) { - /* Earliest start is end of this event since we overlap */ - earliest_start = entry->end_time; - earliest_end = earliest_start + dur; - } - } + OS_ENTER_CRITICAL(sr); - /* Must be able to schedule within one connection interval */ - if (!entry) { - if ((earliest_start - initial_start) <= itvl_t) { - rc = 0; - TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); - } - } + rc = ble_ll_sched_insert(sch, max_delay, preempt_none); + + if (rc == 0) { + connsm->tx_win_off = os_cputime_ticks_to_usecs(sch->start_time - + orig_start_time) / + BLE_LL_CONN_TX_OFF_USECS; + + connsm->anchor_point = sch->start_time + g_ble_ll_sched_offset_ticks; + connsm->anchor_point_usecs = 0; + connsm->ce_end_time = sch->end_time; - if (!rc) { - /* calculate number of window offsets. Each offset is 1.25 ms */ - sch->enqueued = 1; - /* - * NOTE: we dont add sched offset ticks as we want to under-estimate - * the transmit window slightly since the window size is currently - * 2 when using a 32768 crystal. - */ - dur = os_cputime_ticks_to_usecs(earliest_start - initial_start); - connsm->tx_win_off = dur / BLE_LL_CONN_TX_OFF_USECS; - } } - if (!rc) { - sch->start_time = earliest_start; - sch->end_time = earliest_end; - /* - * Since we have the transmit window to transmit in, we dont need - * to set the anchor point usecs; just transmit to the nearest tick. - */ - connsm->anchor_point = earliest_start + g_ble_ll_sched_offset_ticks; - connsm->anchor_point_usecs = 0; - connsm->ce_end_time = earliest_end; - } - - /* Get head of list to restart timer */ - sch = TAILQ_FIRST(&g_ble_ll_sched_q); - ble_ll_rfmgmt_sched_changed(sch); - OS_EXIT_CRITICAL(sr); - os_cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time); + ble_ll_sched_restart(); return rc; } @@ -732,15 +752,11 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, int ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm) { - int rc; - os_sr_t sr; - struct ble_ll_sched_item *entry; - struct ble_ll_sched_item *next_sch; struct ble_ll_sched_item *sch; - int first = 0; + os_sr_t sr; + int rc; /* Get schedule element from connection */ - rc = -1; sch = &connsm->conn_sch; /* Set schedule start and end times */ @@ -755,68 +771,13 @@ ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm) sch->end_time = connsm->ce_end_time; sch->remainder = 0; - /* We have to find a place for this schedule */ OS_ENTER_CRITICAL(sr); - /* The schedule item must occur after current running item (if any) */ - if (ble_ll_sched_overlaps_current(sch)) { - OS_EXIT_CRITICAL(sr); - return rc; - } - - entry = ble_ll_sched_insert_if_empty(sch); - if (!entry) { - /* Nothing in schedule. Schedule as soon as possible */ - rc = 0; - first = 1; - } else { - os_cputime_timer_stop(&g_ble_ll_sched_timer); - while (1) { - next_sch = entry->link.tqe_next; - /* Insert if event ends before next starts */ - if (CPUTIME_LEQ(sch->end_time, entry->start_time)) { - rc = 0; - TAILQ_INSERT_BEFORE(entry, sch, link); - break; - } - - if (ble_ll_sched_is_overlap(sch, entry)) { - /* If we overlap with a connection, we re-schedule */ - if (ble_ll_sched_conn_overlap(entry)) { - break; - } - } - - /* Move to next entry */ - entry = next_sch; - - /* Insert at tail if none left to check */ - if (!entry) { - rc = 0; - TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); - break; - } - } - - if (!rc) { - sch->enqueued = 1; - } - - next_sch = TAILQ_FIRST(&g_ble_ll_sched_q); - if (next_sch == sch) { - first = 1; - } else { - sch = next_sch; - } - } - - if (first) { - ble_ll_rfmgmt_sched_changed(sch); - } + rc = ble_ll_sched_insert(sch, 0, preempt_any); OS_EXIT_CRITICAL(sr); - os_cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time); + ble_ll_sched_restart(); return rc; } @@ -853,7 +814,6 @@ ble_ll_sched_sync_reschedule(struct ble_ll_sched_item *sch, uint32_t window_widening, int8_t phy_mode) { - struct ble_ll_sched_item *entry; uint8_t start_time_rem_usecs; uint8_t window_rem_usecs; uint32_t window_ticks; @@ -893,7 +853,6 @@ ble_ll_sched_sync_reschedule(struct ble_ll_sched_item *sch, return -1; } - /* We have to find a place for this schedule */ OS_ENTER_CRITICAL(sr); if (ble_ll_sched_sync_overlaps_current(sch)) { @@ -901,43 +860,11 @@ ble_ll_sched_sync_reschedule(struct ble_ll_sched_item *sch, return -1; } - /* Try to find slot for sync scan. */ - os_cputime_timer_stop(&g_ble_ll_sched_timer); - - TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { - /* We can insert if before entry in list */ - if (CPUTIME_LEQ(sch->end_time, entry->start_time)) { - TAILQ_INSERT_BEFORE(entry, sch, link); - sch->enqueued = 1; - break; - } - - /* Check for overlapping events. For now drop if it overlaps with - * anything. We can make it smarter later on - */ - if (ble_ll_sched_is_overlap(sch, entry)) { - rc = -1; - break; - } - } - - if (!entry) { - TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); - sch->enqueued = 1; - } - - entry = TAILQ_FIRST(&g_ble_ll_sched_q); - if (entry == sch) { - ble_ll_rfmgmt_sched_changed(sch); - } else { - sch = entry; - } + rc = ble_ll_sched_insert(sch, 0, preempt_none); OS_EXIT_CRITICAL(sr); - /* Restart timer */ - BLE_LL_ASSERT(sch != NULL); - os_cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time); + ble_ll_sched_restart(); return rc; } @@ -947,7 +874,6 @@ ble_ll_sched_sync(struct ble_ll_sched_item *sch, uint32_t beg_cputime, uint32_t rem_usecs, uint32_t offset, int8_t phy_mode) { - struct ble_ll_sched_item *entry; uint32_t start_time_rem_usecs; uint32_t off_rem_usecs; uint32_t start_time; @@ -979,51 +905,14 @@ ble_ll_sched_sync(struct ble_ll_sched_item *sch, OS_ENTER_CRITICAL(sr); - if (!ble_ll_sched_insert_if_empty(sch)) { - /* Nothing in schedule. Schedule as soon as possible - * If we are here it means sch has been added to the scheduler */ - goto done; - } - - /* Try to find slot for scan. */ - os_cputime_timer_stop(&g_ble_ll_sched_timer); - TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { - /* We can insert if before entry in list */ - if (CPUTIME_LEQ(sch->end_time, entry->start_time)) { - TAILQ_INSERT_BEFORE(entry, sch, link); - sch->enqueued = 1; - break; - } - - /* Check for overlapping events. For now drop if it overlaps with - * anything. We can make it smarter later on - */ - if (ble_ll_sched_is_overlap(sch, entry)) { - rc = -1; - break; - } - } - - if (!entry) { - TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); - sch->enqueued = 1; - } - -done: - entry = TAILQ_FIRST(&g_ble_ll_sched_q); - if (entry == sch) { - ble_ll_rfmgmt_sched_changed(sch); - } else { - sch = entry; - } + rc = ble_ll_sched_insert(sch, 0, preempt_none); OS_EXIT_CRITICAL(sr); - /* Restart timer */ - BLE_LL_ASSERT(sch != NULL); - os_cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time); + ble_ll_sched_restart(); STATS_INC(ble_ll_stats, sync_scheduled); + return rc; } #endif @@ -1033,257 +922,87 @@ ble_ll_sched_adv_new(struct ble_ll_sched_item *sch, ble_ll_sched_adv_new_cb cb, void *arg) { os_sr_t sr; - uint32_t adv_start; - uint32_t duration; - struct ble_ll_sched_item *entry; - struct ble_ll_sched_item *orig; - - /* Get length of schedule item */ - duration = sch->end_time - sch->start_time; - orig = sch; + int rc; OS_ENTER_CRITICAL(sr); - entry = ble_ll_sched_insert_if_empty(sch); - if (!entry) { - adv_start = sch->start_time; - } else { - /* XXX: no need to stop timer if not first on list. Modify code? */ - os_cputime_timer_stop(&g_ble_ll_sched_timer); - TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { - /* We can insert if before entry in list */ - if (CPUTIME_LEQ(sch->end_time, entry->start_time)) { - TAILQ_INSERT_BEFORE(entry, sch, link); - break; - } - - /* Check for overlapping events */ - if (ble_ll_sched_is_overlap(sch, entry)) { - /* Earliest start is end of this event since we overlap */ - sch->start_time = entry->end_time; - sch->end_time = sch->start_time + duration; - } - } - if (!entry) { - TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); - } - adv_start = sch->start_time; + rc = ble_ll_sched_insert(sch, BLE_LL_SCHED_MAX_DELAY_ANY, + preempt_none); + BLE_LL_ASSERT(rc == 0); - sch->enqueued = 1; - - /* Restart with head of list */ - sch = TAILQ_FIRST(&g_ble_ll_sched_q); - } - - if (cb) { - cb((struct ble_ll_adv_sm *)orig->cb_arg, adv_start, arg); - } - - if (orig == sch) { - ble_ll_rfmgmt_sched_changed(sch); - } + cb(sch->cb_arg, sch->start_time, arg); OS_EXIT_CRITICAL(sr); - /* Restart timer */ - BLE_LL_ASSERT(sch != NULL); - os_cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time); + ble_ll_sched_restart(); - return 0; + return rc; } int -ble_ll_sched_periodic_adv(struct ble_ll_sched_item *sch, uint32_t *start, - bool after_overlap) +ble_ll_sched_periodic_adv(struct ble_ll_sched_item *sch, bool first_event) { - int rc = 0; os_sr_t sr; - uint32_t adv_start; - uint32_t duration; - struct ble_ll_sched_item *entry; - struct ble_ll_sched_item *orig = sch; - - /* Get length of schedule item */ - duration = sch->end_time - sch->start_time; + int rc; OS_ENTER_CRITICAL(sr); - entry = ble_ll_sched_insert_if_empty(sch); - if (!entry) { - adv_start = sch->start_time; - } else { - /* XXX: no need to stop timer if not first on list. Modify code? */ - os_cputime_timer_stop(&g_ble_ll_sched_timer); - TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { - /* We can insert if before entry in list */ - if (CPUTIME_LEQ(sch->end_time, entry->start_time)) { - TAILQ_INSERT_BEFORE(entry, sch, link); - break; - } - /* Check for overlapping events */ - if (ble_ll_sched_is_overlap(sch, entry)) { - if (after_overlap) { - /* Earliest start is end of this event since we overlap */ - sch->start_time = entry->end_time; - sch->end_time = sch->start_time + duration; - } else { - rc = -1; - break; - } - } - } - - if (!entry) { - TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); - } - adv_start = sch->start_time; - - if (!rc) { - sch->enqueued = 1; - } - - /* Restart with head of list */ - sch = TAILQ_FIRST(&g_ble_ll_sched_q); - } - - if (!rc) { - *start = adv_start; - } - - if (orig == sch) { - ble_ll_rfmgmt_sched_changed(sch); + if (first_event) { + rc = ble_ll_sched_insert(sch, BLE_LL_SCHED_MAX_DELAY_ANY, + preempt_none); + } else { + rc = ble_ll_sched_insert(sch, 0, preempt_any); } OS_EXIT_CRITICAL(sr); - /* Restart timer */ - BLE_LL_ASSERT(sch != NULL); - os_cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time); + ble_ll_sched_restart(); return rc; } int -ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch, uint32_t *start, +ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch, uint32_t max_delay_ticks) { - int rc; - os_sr_t sr; - uint32_t orig_start; - uint32_t duration; + struct ble_ll_sched_item *next; + uint32_t max_end_time; uint32_t rand_ticks; - struct ble_ll_sched_item *entry; - struct ble_ll_sched_item *next_sch; - struct ble_ll_sched_item *before; - struct ble_ll_sched_item *start_overlap; - struct ble_ll_sched_item *end_overlap; - - /* Get length of schedule item */ - duration = sch->end_time - sch->start_time; + os_sr_t sr; + int rc; - /* Add maximum randomization delay to end */ - rand_ticks = max_delay_ticks; - sch->end_time += max_delay_ticks; + max_end_time = sch->end_time + max_delay_ticks; - start_overlap = NULL; - end_overlap = NULL; - before = NULL; - rc = 0; OS_ENTER_CRITICAL(sr); - entry = ble_ll_sched_insert_if_empty(sch); - if (entry) { - os_cputime_timer_stop(&g_ble_ll_sched_timer); - while (1) { - next_sch = entry->link.tqe_next; - if (ble_ll_sched_is_overlap(sch, entry)) { - if (start_overlap == NULL) { - start_overlap = entry; - end_overlap = entry; - } else { - end_overlap = entry; - } - } else { - if (CPUTIME_LEQ(sch->end_time, entry->start_time)) { - before = entry; - break; - } - } - - entry = next_sch; - if (entry == NULL) { - break; - } - } + /* Try to schedule as early as possible but no later than max allowed delay. + * If succeeded, randomize start time to be within max allowed delay from + * the original start time but make sure it ends before next scheduled item. + */ - /* - * If there is no overlap, we either insert before the 'before' entry - * or we insert at the end if there is no before entry. - */ - if (start_overlap == NULL) { - if (before) { - TAILQ_INSERT_BEFORE(before, sch, link); - } else { - TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); + rc = ble_ll_sched_insert(sch, max_delay_ticks, preempt_none); + if (rc == 0) { + next = TAILQ_NEXT(sch, link); + if (next) { + if (CPUTIME_LT(next->start_time, max_end_time)) { + max_end_time = next->start_time; } + rand_ticks = max_end_time - sch->end_time; } else { - /* - * This item will overlap with others. See if we can fit it in - * with original duration. - */ - before = NULL; - orig_start = sch->start_time; - entry = start_overlap; - sch->end_time = sch->start_time + duration; - while (1) { - next_sch = entry->link.tqe_next; - if (CPUTIME_LEQ(sch->end_time, entry->start_time)) { - rand_ticks = entry->start_time - sch->end_time; - before = entry; - TAILQ_INSERT_BEFORE(before, sch, link); - break; - } else { - sch->start_time = entry->end_time; - sch->end_time = sch->start_time + duration; - } - - if (entry == end_overlap) { - rand_ticks = (orig_start + max_delay_ticks) - sch->start_time; - if (rand_ticks > max_delay_ticks) { - /* No place for advertisement. */ - rc = -1; - } else { - if (next_sch == NULL) { - TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); - } else { - TAILQ_INSERT_BEFORE(next_sch, sch, link); - } - } - break; - } - entry = next_sch; - BLE_LL_ASSERT(entry != NULL); - } + rand_ticks = max_delay_ticks; } - } - if (!rc) { - sch->enqueued = 1; if (rand_ticks) { - sch->start_time += ble_ll_rand() % rand_ticks; + rand_ticks = ble_ll_rand() % rand_ticks; } - sch->end_time = sch->start_time + duration; - *start = sch->start_time; - if (sch == TAILQ_FIRST(&g_ble_ll_sched_q)) { - ble_ll_rfmgmt_sched_changed(sch); - } + sch->start_time += rand_ticks; + sch->end_time += rand_ticks; } OS_EXIT_CRITICAL(sr); - sch = TAILQ_FIRST(&g_ble_ll_sched_q); - os_cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time); + ble_ll_sched_restart(); return rc; } @@ -1293,36 +1012,24 @@ ble_ll_sched_adv_resched_pdu(struct ble_ll_sched_item *sch) { uint8_t lls; os_sr_t sr; - struct ble_ll_sched_item *entry; + int rc; OS_ENTER_CRITICAL(sr); lls = ble_ll_state_get(); if ((lls == BLE_LL_STATE_ADV) || (lls == BLE_LL_STATE_CONNECTION) || - (lls == BLE_LL_STATE_SYNC)) { - goto adv_resched_pdu_fail; - } - - entry = ble_ll_sched_insert_if_empty(sch); - if (entry) { - /* If we overlap with the first item, simply re-schedule */ - if (ble_ll_sched_is_overlap(sch, entry)) { - goto adv_resched_pdu_fail; - } - os_cputime_timer_stop(&g_ble_ll_sched_timer); - TAILQ_INSERT_BEFORE(entry, sch, link); - sch->enqueued = 1; + (lls == BLE_LL_STATE_SYNC)) { + OS_EXIT_CRITICAL(sr); + return -1; } - ble_ll_rfmgmt_sched_changed(TAILQ_FIRST(&g_ble_ll_sched_q)); + rc = ble_ll_sched_insert(sch, 0, preempt_none); OS_EXIT_CRITICAL(sr); - os_cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time); - return 0; -adv_resched_pdu_fail: - OS_EXIT_CRITICAL(sr); - return -1; + ble_ll_sched_restart(); + + return rc; } /** @@ -1335,75 +1042,71 @@ ble_ll_sched_adv_resched_pdu(struct ble_ll_sched_item *sch) int ble_ll_sched_rmv_elem(struct ble_ll_sched_item *sch) { + uint8_t first_removed; os_sr_t sr; - struct ble_ll_sched_item *first; - int rc = 1; + int rc; - if (!sch) { - return rc; - } + BLE_LL_ASSERT(sch); OS_ENTER_CRITICAL(sr); + + first_removed = 0; + if (sch->enqueued) { - first = TAILQ_FIRST(&g_ble_ll_sched_q); - if (first == sch) { - os_cputime_timer_stop(&g_ble_ll_sched_timer); + if (sch == TAILQ_FIRST(&g_ble_ll_sched_q)) { + first_removed = 1; } TAILQ_REMOVE(&g_ble_ll_sched_q, sch, link); sch->enqueued = 0; + rc = 0; + } else { + rc = 1; + } - if (first == sch) { - first = TAILQ_FIRST(&g_ble_ll_sched_q); - if (first) { - os_cputime_timer_start(&g_ble_ll_sched_timer, first->start_time); - } - ble_ll_rfmgmt_sched_changed(first); - } + if (first_removed) { + ble_ll_sched_q_head_changed(); } + OS_EXIT_CRITICAL(sr); + ble_ll_sched_restart(); + return rc; } void ble_ll_sched_rmv_elem_type(uint8_t type, sched_remove_cb_func remove_cb) { - os_sr_t sr; - struct ble_ll_sched_item *entry; struct ble_ll_sched_item *first; + struct ble_ll_sched_item *entry; + uint8_t first_removed; + os_sr_t sr; OS_ENTER_CRITICAL(sr); - first = TAILQ_FIRST(&g_ble_ll_sched_q); - if (!first) { - OS_EXIT_CRITICAL(sr); - return; + first = TAILQ_FIRST(&g_ble_ll_sched_q); + if (first->sched_type == type) { + first_removed = 1; } TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { - if (entry->sched_type == type) { - if (first == entry) { - os_cputime_timer_stop(&g_ble_ll_sched_timer); - first = NULL; - } - - TAILQ_REMOVE(&g_ble_ll_sched_q, entry, link); - remove_cb(entry); - entry->enqueued = 0; + if (entry->sched_type != type) { + continue; } + TAILQ_REMOVE(&g_ble_ll_sched_q, entry, link); + remove_cb(entry); + entry->enqueued = 0; } - if (!first) { - first = TAILQ_FIRST(&g_ble_ll_sched_q); - if (first) { - os_cputime_timer_start(&g_ble_ll_sched_timer, first->start_time); - } - ble_ll_rfmgmt_sched_changed(first); + if (first_removed) { + ble_ll_sched_q_head_changed(); } OS_EXIT_CRITICAL(sr); + + ble_ll_sched_restart(); } /** @@ -1481,6 +1184,7 @@ ble_ll_sched_execute_item(struct ble_ll_sched_item *sch) sched: BLE_LL_DEBUG_GPIO(SCHED_ITEM_CB, 1); BLE_LL_ASSERT(sch->sched_cb); + rc = sch->sched_cb(sch); BLE_LL_DEBUG_GPIO(SCHED_ITEM_CB, 0); return rc; @@ -1500,6 +1204,8 @@ ble_ll_sched_run(void *arg) BLE_LL_DEBUG_GPIO(SCHED_RUN, 1); + g_ble_ll_sched_timer_running = 0; + /* Look through schedule queue */ sch = TAILQ_FIRST(&g_ble_ll_sched_q); if (sch) { @@ -1520,13 +1226,7 @@ ble_ll_sched_run(void *arg) TAILQ_REMOVE(&g_ble_ll_sched_q, sch, link); sch->enqueued = 0; ble_ll_sched_execute_item(sch); - - /* Restart if there is an item on the schedule */ - sch = TAILQ_FIRST(&g_ble_ll_sched_q); - if (sch) { - os_cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time); - } - ble_ll_rfmgmt_sched_changed(sch); + ble_ll_sched_restart(); } BLE_LL_DEBUG_GPIO(SCHED_RUN, 0); @@ -1586,7 +1286,6 @@ ble_ll_sched_aux_scan(struct ble_mbuf_hdr *ble_hdr, uint32_t start_time_rem_usecs; uint32_t end_time; uint32_t dur; - struct ble_ll_sched_item *entry; struct ble_ll_sched_item *sch; int phy_mode; @@ -1621,58 +1320,16 @@ ble_ll_sched_aux_scan(struct ble_mbuf_hdr *ble_hdr, OS_ENTER_CRITICAL(sr); - if (!ble_ll_sched_insert_if_empty(sch)) { - /* Nothing in schedule. Schedule as soon as possible - * If we are here it means sch has been added to the scheduler */ - rc = 0; - goto done; - } - - /* Try to find slot for aux scan. */ - os_cputime_timer_stop(&g_ble_ll_sched_timer); - TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { - /* We can insert if before entry in list */ - if (CPUTIME_LEQ(sch->end_time, entry->start_time)) { - rc = 0; - TAILQ_INSERT_BEFORE(entry, sch, link); - sch->enqueued = 1; - break; - } - - /* Check for overlapping events. For now drop if it overlaps with - * anything. We can make it smarter later on - */ - if (ble_ll_sched_is_overlap(sch, entry)) { - break; - } - } - - if (!entry) { - rc = 0; - TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); - sch->enqueued = 1; - } - -done: + rc = ble_ll_sched_insert(sch, 0, preempt_none); if (rc == 0) { sch->cb_arg = ble_ll_scan_aux_data_ref(aux_scan); STATS_INC(ble_ll_stats, aux_scheduled); } - /* Get head of list to restart timer */ - entry = TAILQ_FIRST(&g_ble_ll_sched_q); - if (entry == sch) { - ble_ll_rfmgmt_sched_changed(sch); - } else { - sch = entry; - } - OS_EXIT_CRITICAL(sr); - /* Restart timer */ - BLE_LL_ASSERT(sch != NULL); - os_cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time); + ble_ll_sched_restart(); return rc; } @@ -1681,7 +1338,6 @@ int ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time, uint8_t pdu_time_rem, uint32_t offset_us) { - struct ble_ll_sched_item *entry; uint32_t offset_ticks; os_sr_t sr; int rc; @@ -1696,42 +1352,11 @@ ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time, OS_ENTER_CRITICAL(sr); - if (!ble_ll_sched_insert_if_empty(sch)) { - /* Scheduler was empty, inserted as 1st element */ - rc = 0; - goto done; - } - - os_cputime_timer_stop(&g_ble_ll_sched_timer); - TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { - if (CPUTIME_LEQ(sch->end_time, entry->start_time)) { - TAILQ_INSERT_BEFORE(entry, sch, link); - sch->enqueued = 1; - rc = 0; - break; - } - - if (ble_ll_sched_is_overlap(sch, entry)) { - rc = -1; - break; - } - } - - if (!entry) { - TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); - sch->enqueued = 1; - rc = 0; - } - -done: - entry = TAILQ_FIRST(&g_ble_ll_sched_q); + rc = ble_ll_sched_insert(sch, 0, preempt_none); OS_EXIT_CRITICAL(sr); - if (entry == sch) { - ble_ll_rfmgmt_sched_changed(sch); - } - os_cputime_timer_start(&g_ble_ll_sched_timer, entry->start_time); + ble_ll_sched_restart(); return rc; } @@ -1740,57 +1365,18 @@ ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time, #if MYNEWT_VAL(BLE_LL_DTM) int ble_ll_sched_dtm(struct ble_ll_sched_item *sch) { - int rc; os_sr_t sr; - struct ble_ll_sched_item *entry; + int rc; OS_ENTER_CRITICAL(sr); - if (!ble_ll_sched_insert_if_empty(sch)) { - /* Nothing in schedule. Schedule as soon as possible - * If we are here it means sch has been added to the scheduler */ - rc = 0; - goto done; - } - - /* Try to find slot for test. */ - os_cputime_timer_stop(&g_ble_ll_sched_timer); - TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { - /* We can insert if before entry in list */ - if (sch->end_time <= entry->start_time) { - rc = 0; - TAILQ_INSERT_BEFORE(entry, sch, link); - sch->enqueued = 1; - break; - } - - /* Check for overlapping events. For now drop if it overlaps with - * anything. We can make it smarter later on - */ - if (ble_ll_sched_is_overlap(sch, entry)) { - OS_EXIT_CRITICAL(sr); - return -1; - } - } - - if (!entry) { - rc = 0; - TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); - sch->enqueued = 1; - } - -done: - - /* Get head of list to restart timer */ - sch = TAILQ_FIRST(&g_ble_ll_sched_q); - - ble_ll_rfmgmt_sched_changed(sch); + rc = ble_ll_sched_insert(sch, 0, preempt_any); OS_EXIT_CRITICAL(sr); - /* Restart timer */ - BLE_LL_ASSERT(sch != NULL); - os_cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time); + if (rc == 0) { + ble_ll_sched_restart(); + } return rc; } @@ -1803,6 +1389,7 @@ int ble_ll_sched_dtm(struct ble_ll_sched_item *sch) void ble_ll_sched_stop(void) { + g_ble_ll_sched_timer_running = 0; os_cputime_timer_stop(&g_ble_ll_sched_timer); } From 815d890d537cd60b50b2797ee56dfc5467e4b4c5 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 14 Oct 2021 15:44:30 +0200 Subject: [PATCH 0023/1333] nimble/transport: Use max ACL data size for RAM transport Since in RAM transport ACL data are passed simply as an mbuf pointer between host and controller we can use max ACL data size to avoid data fragmentation over HCI. This actually saves some RAM since we do not need extra buffers for fragmented HCI ACL data. --- nimble/transport/ram/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/transport/ram/syscfg.yml b/nimble/transport/ram/syscfg.yml index 3b822fcc60..cbb57163ad 100644 --- a/nimble/transport/ram/syscfg.yml +++ b/nimble/transport/ram/syscfg.yml @@ -37,7 +37,7 @@ syscfg.defs: description: > This is the maximum size of the data portion of HCI ACL data packets. It does not include the HCI data header (of 4 bytes). - value: 255 + value: 65535 BLE_TRANS_RAM_SYSINIT_STAGE: description: > From eaa1e6771ed8fb8b8ce1c7bca6c46c32bb204978 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 14 Oct 2021 12:47:31 +0200 Subject: [PATCH 0024/1333] nimble/hci: Fix mbuf allocation for HCI ACL fragmentation We need to use proper user pkt header length when allocating new mbuf for HCI ACL data fragment, otherwise leading space won't be set properly and data may be overwritten. See 20c4817625fc4d33b0d9c2f23cb0fe96eba5e988 for reference. Note: technically this does not make much sense since we use max HCI ACL data size for combined build so fragmentation won't happen, but let's fix it anyway just in case someone uses other value for whatever reason. --- nimble/host/src/ble_gatts.c | 2 +- nimble/host/src/ble_hs_hci.c | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_gatts.c b/nimble/host/src/ble_gatts.c index a635f2d7f4..83402e7242 100644 --- a/nimble/host/src/ble_gatts.c +++ b/nimble/host/src/ble_gatts.c @@ -364,7 +364,7 @@ ble_gatts_val_access(uint16_t conn_handle, uint16_t attr_handle, gatt_ctxt->om = *om; } else { new_om = 1; - gatt_ctxt->om = os_msys_get_pkthdr(0, 0); + gatt_ctxt->om = ble_hs_mbuf_att_pkt(); if (gatt_ctxt->om == NULL) { return BLE_ATT_ERR_INSUFFICIENT_RES; } diff --git a/nimble/host/src/ble_hs_hci.c b/nimble/host/src/ble_hs_hci.c index e5c3a741e5..53d36473b6 100644 --- a/nimble/host/src/ble_hs_hci.c +++ b/nimble/host/src/ble_hs_hci.c @@ -41,11 +41,20 @@ static uint32_t ble_hs_hci_sup_feat; static uint8_t ble_hs_hci_version; +#if MYNEWT_VAL(BLE_CONTROLLER) #define BLE_HS_HCI_FRAG_DATABUF_SIZE \ (BLE_ACL_MAX_PKT_SIZE + \ BLE_HCI_DATA_HDR_SZ + \ sizeof (struct os_mbuf_pkthdr) + \ + sizeof (struct ble_mbuf_hdr) + \ sizeof (struct os_mbuf)) +#else +#define BLE_HS_HCI_FRAG_DATABUF_SIZE \ + (BLE_ACL_MAX_PKT_SIZE + \ + BLE_HCI_DATA_HDR_SZ + \ + sizeof (struct os_mbuf_pkthdr) + \ + sizeof (struct os_mbuf)) +#endif #define BLE_HS_HCI_FRAG_MEMBLOCK_SIZE \ (OS_ALIGN(BLE_HS_HCI_FRAG_DATABUF_SIZE, 4)) @@ -421,7 +430,11 @@ ble_hs_hci_frag_alloc(uint16_t frag_size, void *arg) struct os_mbuf *om; /* Prefer the dedicated one-element fragment pool. */ +#if MYNEWT_VAL(BLE_CONTROLLER) + om = os_mbuf_get_pkthdr(&ble_hs_hci_frag_mbuf_pool, sizeof(struct ble_mbuf_hdr)); +#else om = os_mbuf_get_pkthdr(&ble_hs_hci_frag_mbuf_pool, 0); +#endif if (om != NULL) { om->om_data += BLE_HCI_DATA_HDR_SZ; return om; From 43308a629e5b10b0848114e280bc4515d7cee4e2 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 14 Oct 2021 11:26:05 +0200 Subject: [PATCH 0025/1333] nimble/ll: Add gpio debug for rfmgmt --- nimble/controller/src/ble_ll_rfmgmt.c | 5 +++++ nimble/controller/syscfg.yml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/nimble/controller/src/ble_ll_rfmgmt.c b/nimble/controller/src/ble_ll_rfmgmt.c index 3bf5d5fae6..986645f4a1 100644 --- a/nimble/controller/src/ble_ll_rfmgmt.c +++ b/nimble/controller/src/ble_ll_rfmgmt.c @@ -27,6 +27,7 @@ #include "controller/ble_ll.h" #include "controller/ble_ll_sched.h" #include "controller/ble_ll_rfmgmt.h" +#include "ble_ll_priv.h" #if MYNEWT_VAL(BLE_LL_RFMGMT_ENABLE_TIME) > 0 @@ -65,6 +66,7 @@ ble_ll_rfmgmt_enable(void) g_ble_ll_rfmgmt_data.state = RFMGMT_STATE_ENABLING; g_ble_ll_rfmgmt_data.enabled_at = os_cputime_get32(); ble_phy_rfclk_enable(); + BLE_LL_DEBUG_GPIO(RFMGMT, 1); } } @@ -74,6 +76,7 @@ ble_ll_rfmgmt_disable(void) OS_ASSERT_CRITICAL(); if (g_ble_ll_rfmgmt_data.state != RFMGMT_STATE_OFF) { + BLE_LL_DEBUG_GPIO(RFMGMT, 0); ble_phy_rfclk_disable(); g_ble_ll_rfmgmt_data.state = RFMGMT_STATE_OFF; } @@ -212,6 +215,8 @@ ble_ll_rfmgmt_init(void) { struct ble_ll_rfmgmt_data *rfmgmt = &g_ble_ll_rfmgmt_data; + BLE_LL_DEBUG_GPIO_INIT(RFMGMT); + rfmgmt->state = RFMGMT_STATE_OFF; rfmgmt->ticks_to_enabled = diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index ea5590f8e4..1050dbb7cc 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -367,6 +367,11 @@ syscfg.defs: GPIO pin number to debug scheduler item execution times. Pin is set to high state while item is executed. value: -1 + BLE_LL_DEBUG_GPIO_RFMGMT: + description: > + GPIO pin number to debug rfmgmt activity. Pin is set to high state + while rfmgmt is active. + value: -1 # Below settings allow to change scheduler timings. These should be left at # default values unless you know what you are doing! From 0682fa32b95dee9e79cc33580f8c33acd9f4e91f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sun, 17 Oct 2021 12:29:46 +0200 Subject: [PATCH 0026/1333] nimble/phy/nrf: Fix checking for resolved addr We should check if NRF_AAR was enabled prior to checking its result to avoid reading some uninitialied values if resolver was not enabled. --- nimble/drivers/nrf51/src/ble_hw.c | 9 ++------- nimble/drivers/nrf52/src/ble_hw.c | 9 ++------- nimble/drivers/nrf5340/src/ble_hw.c | 10 +++------- 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/nimble/drivers/nrf51/src/ble_hw.c b/nimble/drivers/nrf51/src/ble_hw.c index 3c7296b845..437efd4f7c 100644 --- a/nimble/drivers/nrf51/src/ble_hw.c +++ b/nimble/drivers/nrf51/src/ble_hw.c @@ -474,13 +474,8 @@ ble_hw_resolv_list_size(void) int ble_hw_resolv_list_match(void) { - uint32_t index; - - if (NRF_AAR->EVENTS_END) { - if (NRF_AAR->EVENTS_RESOLVED) { - index = NRF_AAR->STATUS; - return (int)index; - } + if (NRF_AAR->ENABLE && NRF_AAR->EVENTS_END && NRF_AAR->EVENTS_RESOLVED) { + return (int)NRF_AAR->STATUS; } return -1; diff --git a/nimble/drivers/nrf52/src/ble_hw.c b/nimble/drivers/nrf52/src/ble_hw.c index 82e6d17ed7..8ab24eba5a 100644 --- a/nimble/drivers/nrf52/src/ble_hw.c +++ b/nimble/drivers/nrf52/src/ble_hw.c @@ -474,13 +474,8 @@ ble_hw_resolv_list_size(void) int ble_hw_resolv_list_match(void) { - uint32_t index; - - if (NRF_AAR->EVENTS_END) { - if (NRF_AAR->EVENTS_RESOLVED) { - index = NRF_AAR->STATUS; - return (int)index; - } + if (NRF_AAR->ENABLE && NRF_AAR->EVENTS_END && NRF_AAR->EVENTS_RESOLVED) { + return (int)NRF_AAR->STATUS; } return -1; diff --git a/nimble/drivers/nrf5340/src/ble_hw.c b/nimble/drivers/nrf5340/src/ble_hw.c index bbe6169779..92bf024979 100644 --- a/nimble/drivers/nrf5340/src/ble_hw.c +++ b/nimble/drivers/nrf5340/src/ble_hw.c @@ -461,13 +461,9 @@ ble_hw_resolv_list_size(void) int ble_hw_resolv_list_match(void) { - uint32_t index; - - if (NRF_AAR_NS->EVENTS_END) { - if (NRF_AAR_NS->EVENTS_RESOLVED) { - index = NRF_AAR_NS->STATUS; - return (int)index; - } + if (NRF_AAR_NS->ENABLE && NRF_AAR_NS->EVENTS_END && + NRF_AAR_NS->EVENTS_RESOLVED) { + return (int)NRF_AAR_NS->STATUS; } return -1; From aab952c4a3f5a3c3ebd2b30e9b294a0569b664a3 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 15 Nov 2019 10:47:03 +0100 Subject: [PATCH 0027/1333] nimble/ll: Add LLCP tracing via HCI events This adds option to trace LLCP PDUs via HCI events. Each LLCP PDU is sent in a vendor-specific HCI event which can be decoded e.g. by btmon. Identifier and format of HCI event os the same as used by controllers from Intel so it may be necessary to fake NimBLE's manufacturer id by setting 'BLE_LL_MFRG_ID: 2' so btmon can decode events properly. --- .../include/controller/ble_ll_ctrl.h | 2 ++ nimble/controller/src/ble_ll_ctrl.c | 10 +++++++ nimble/controller/src/ble_ll_hci_ev.c | 28 +++++++++++++++++++ nimble/controller/syscfg.yml | 5 ++++ 4 files changed, 45 insertions(+) diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index 15a45b2a08..bd38e583e9 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -316,6 +316,8 @@ void ble_ll_calc_session_key(struct ble_ll_conn_sm *connsm); void ble_ll_ctrl_phy_update_proc_complete(struct ble_ll_conn_sm *connsm); void ble_ll_ctrl_initiate_dle(struct ble_ll_conn_sm *connsm); void ble_ll_hci_ev_send_vendor_err(const char *file, uint32_t line); +void ble_ll_hci_ev_send_llcp_trace(uint8_t type, uint16_t handle, uint16_t count, + void *pdu, size_t length); uint8_t ble_ll_ctrl_phy_tx_transition_get(uint8_t phy_mask); uint8_t ble_ll_ctrl_phy_from_phy_mask(uint8_t phy_mask); diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 384a48756e..7ef63d132d 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -2473,6 +2473,11 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) len = dptr[1]; opcode = dptr[2]; +#if MYNEWT_VAL(BLE_LL_HCI_LLCP_TRACE) + ble_ll_hci_ev_send_llcp_trace(0x03, connsm->conn_handle, connsm->event_cntr, + &dptr[2], len); +#endif + /* * rspbuf points to first byte of response. The response buffer does not * contain the Data Channel PDU. Thus, the first byte of rspbuf is the @@ -2802,6 +2807,11 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) int rc; uint8_t opcode; +#if MYNEWT_VAL(BLE_LL_HCI_LLCP_TRACE) + ble_ll_hci_ev_send_llcp_trace(0x04, connsm->conn_handle, connsm->event_cntr, + txpdu->om_data, txpdu->om_len); +#endif + rc = 0; opcode = txpdu->om_data[0]; switch (opcode) { diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index 0d6da9a01e..ccbb1aa94d 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -551,3 +551,31 @@ ble_ll_hci_ev_send_vendor_err(const char *file, uint32_t line) ble_ll_hci_event_send(hci_ev); } } + +#if MYNEWT_VAL(BLE_LL_HCI_LLCP_TRACE) +void +ble_ll_hci_ev_send_llcp_trace(uint8_t type, uint16_t handle, uint16_t count, + void *pdu, size_t length) +{ + struct ble_hci_ev_vendor_debug *ev; + struct ble_hci_ev *hci_ev; + + hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + if (hci_ev) { + hci_ev->opcode = BLE_HCI_EVCODE_VENDOR_DEBUG; + hci_ev->length = sizeof(*ev) + 8 + length; + ev = (void *) hci_ev->data; + + ev->id = 0x17; + ev->data[0] = type; + put_le16(&ev->data[1], handle); + put_le16(&ev->data[3], count); + ev->data[5] = 0; + ev->data[6] = 0; + ev->data[7] = 0; + memcpy(&ev->data[8], pdu, length); + + ble_ll_hci_event_send(hci_ev); + } +} +#endif diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 1050dbb7cc..b1fb6b1fb9 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -163,6 +163,11 @@ syscfg.defs: PHY enabled all the time. value: MYNEWT_VAL(BLE_XTAL_SETTLE_TIME) + BLE_LL_HCI_LLCP_TRACE: + description: > + Enables LLCP tracing using HCI vendor-specific events. + value: '0' + # Configuration for LL supported features. # # There are a total 8 features that the LL can support. These can be found From 99de1340e7fbdee6a604415972bd24ec5117a78d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 12 Oct 2021 14:13:20 +0200 Subject: [PATCH 0028/1333] nimble/ll: Optimize sync sm scheduler handling Scheduler item in sync sm can be initialize only once, no need to do this on each event. Callbacks for ADV_SYNC_IND and ADV_CHAIN_IND are pretty much the same except for wfr calculations so we'll just have flag to indicate what is being scanned. --- nimble/controller/src/ble_ll_sync.c | 127 ++++++++-------------------- 1 file changed, 36 insertions(+), 91 deletions(-) diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 78d9456f64..f121c286b0 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -61,6 +61,7 @@ #define BLE_LL_SYNC_SM_FLAG_ADDR_RESOLVED 0x0080 #define BLE_LL_SYNC_SM_FLAG_HCI_TRUNCATED 0x0100 #define BLE_LL_SYNC_SM_FLAG_NEW_CHANMAP 0x0200 +#define BLE_LL_SYNC_SM_FLAG_CHAIN 0x0400 #define BLE_LL_SYNC_CHMAP_LEN 5 #define BLE_LL_SYNC_ITVL_USECS 1250 @@ -137,6 +138,8 @@ static uint8_t *g_ble_ll_sync_create_comp_ev; static struct ble_ll_sync_sm *g_ble_ll_sync_sm_current; +static int ble_ll_sync_event_start_cb(struct ble_ll_sched_item *sch); + static int ble_ll_sync_on_list(const uint8_t *addr, uint8_t addr_type, uint8_t sid) { @@ -211,7 +214,12 @@ ble_ll_sync_sm_clear(struct ble_ll_sync_sm *sm) BLE_LL_ASSERT(sm->sync_ev_end.ev.ev_queued == 0); BLE_LL_ASSERT(sm->sch.enqueued == 0); + memset(sm, 0, sizeof(*sm)); + + sm->sch.sched_cb = ble_ll_sync_event_start_cb; + sm->sch.cb_arg = sm; + sm->sch.sched_type = BLE_LL_SCHED_TYPE_SYNC; } static uint8_t @@ -436,6 +444,7 @@ ble_ll_sync_event_start_cb(struct ble_ll_sched_item *sch) struct ble_ll_sync_sm *sm; uint32_t wfr_usecs; uint32_t start; + uint8_t chan; int rc; /* Set current connection state machine */ @@ -451,7 +460,9 @@ ble_ll_sync_event_start_cb(struct ble_ll_sched_item *sch) ble_ll_state_set(BLE_LL_STATE_SYNC); /* Set channel */ - ble_phy_setchan(sm->chan_index, sm->access_addr, sm->crcinit); + chan = sm->flags & BLE_LL_SYNC_SM_FLAG_CHAIN ? sm->chan_chain : + sm->chan_index; + ble_phy_setchan(chan, sm->access_addr, sm->crcinit); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) ble_phy_resolv_list_disable(); @@ -469,31 +480,35 @@ ble_ll_sync_event_start_cb(struct ble_ll_sched_item *sch) rc = ble_phy_rx_set_start_time(start, sch->remainder); if (rc && rc != BLE_PHY_ERR_RX_LATE) { STATS_INC(ble_ll_stats, sync_event_failed); - rc = BLE_LL_SCHED_STATE_DONE; ble_ll_event_send(&sm->sync_ev_end); ble_ll_sync_current_sm_over(); + rc = BLE_LL_SCHED_STATE_DONE; } else { - /* - * Set flag that tells to set last anchor point if a packet - * has been received. - */ - sm->flags |= BLE_LL_SYNC_SM_FLAG_SET_ANCHOR; - - /* Set WFR timer. - * If establishing we always adjust with offset unit. - * If this is first packet of sync (one that was pointed by from - * SyncInfo we don't adjust WFT with window widening. - */ - if (sm->flags & BLE_LL_SYNC_SM_FLAG_ESTABLISHING) { + if (sm->flags & BLE_LL_SYNC_SM_FLAG_CHAIN) { wfr_usecs = (sm->flags & BLE_LL_SYNC_SM_FLAG_OFFSET_300) ? 300 : 30; - if (!(sm->flags & BLE_LL_SYNC_SM_FLAG_SYNC_INFO)) { - wfr_usecs += 2 * sm->window_widening; - } } else { - wfr_usecs = 2 * sm->window_widening; + /* Set flag that tells to set last anchor point if a packet + * has been received. + */ + sm->flags |= BLE_LL_SYNC_SM_FLAG_SET_ANCHOR; + + /* Set WFR timer. + * If establishing we always adjust with offset unit. + * If this is first packet of sync (one that was pointed by from + * SyncInfo we don't adjust WFR with window widening. + */ + if (sm->flags & BLE_LL_SYNC_SM_FLAG_ESTABLISHING) { + wfr_usecs = (sm->flags & BLE_LL_SYNC_SM_FLAG_OFFSET_300) ? 300 + : 30; + if (!(sm->flags & BLE_LL_SYNC_SM_FLAG_SYNC_INFO)) { + wfr_usecs += 2 * sm->window_widening; + } + } else { + wfr_usecs = 2 * sm->window_widening; + } } - ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_RX, 0, wfr_usecs); + ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_RX, 0, wfr_usecs); rc = BLE_LL_SCHED_STATE_RUNNING; } @@ -865,63 +880,6 @@ ble_ll_sync_parse_aux_ptr(const uint8_t *buf, uint8_t *chan, uint32_t *offset, *phy = (aux_ptr_field >> 21) & 0x07; } -static int -ble_ll_sync_chain_start_cb(struct ble_ll_sched_item *sch) -{ - struct ble_ll_sync_sm *sm; - uint32_t wfr_usecs; - uint32_t start; - int rc; - - /* Set current connection state machine */ - sm = sch->cb_arg; - g_ble_ll_sync_sm_current = sm; - BLE_LL_ASSERT(sm); - - /* Disable whitelisting */ - ble_ll_whitelist_disable(); - - /* Set LL state */ - ble_ll_state_set(BLE_LL_STATE_SYNC); - - /* Set channel */ - ble_phy_setchan(sm->chan_chain, sm->access_addr, sm->crcinit); - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - ble_phy_resolv_list_disable(); -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - ble_phy_encrypt_disable(); -#endif - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_set(sm->phy_mode, sm->phy_mode); -#endif - - start = sch->start_time + g_ble_ll_sched_offset_ticks; - rc = ble_phy_rx_set_start_time(start, sch->remainder); - if (rc && rc != BLE_PHY_ERR_RX_LATE) { - STATS_INC(ble_ll_stats, sync_chain_failed); - rc = BLE_LL_SCHED_STATE_DONE; - ble_ll_event_send(&sm->sync_ev_end); - ble_ll_sync_current_sm_over(); - } else { - /* - * Clear flag that tells to set last anchor point if a packet - * has been received, this is chain and we don't need it. - */ - sm->flags &= ~BLE_LL_SYNC_SM_FLAG_SET_ANCHOR; - - wfr_usecs = (sm->flags & BLE_LL_SYNC_SM_FLAG_OFFSET_300) ? 300 : 30; - - ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_RX, 0, wfr_usecs); - rc = BLE_LL_SCHED_STATE_RUNNING; - } - - return rc; -} - static int ble_ll_sync_schedule_chain(struct ble_ll_sync_sm *sm, struct ble_mbuf_hdr *hdr, const uint8_t *aux) @@ -954,9 +912,7 @@ ble_ll_sync_schedule_chain(struct ble_ll_sync_sm *sm, struct ble_mbuf_hdr *hdr, sm->chan_chain = chan; - sm->sch.sched_cb = ble_ll_sync_chain_start_cb; - sm->sch.cb_arg = sm; - sm->sch.sched_type = BLE_LL_SCHED_TYPE_SYNC; + sm->flags |= BLE_LL_SYNC_SM_FLAG_CHAIN; return ble_ll_sched_sync(&sm->sch, hdr->beg_cputime, hdr->rem_usecs, offset, sm->phy_mode); @@ -1308,10 +1264,7 @@ ble_ll_sync_event_end(struct ble_npl_event *ev) /* Event ended so we are no longer chaining */ sm->flags &= ~BLE_LL_SYNC_SM_FLAG_HCI_TRUNCATED; - - sm->sch.sched_cb = ble_ll_sync_event_start_cb; - sm->sch.cb_arg = sm; - sm->sch.sched_type = BLE_LL_SCHED_TYPE_SYNC; + sm->flags &= ~BLE_LL_SYNC_SM_FLAG_CHAIN; do { if (ble_ll_sync_next_event(sm, 0) < 0) { @@ -1473,10 +1426,6 @@ ble_ll_sync_info_event(struct ble_ll_scan_addr_data *addrd, sm->chan_index = ble_ll_utils_calc_dci_csa2(sm->event_cntr, sm->channel_id, sm->num_used_chans, sm->chanmap); - sm->sch.sched_cb = ble_ll_sync_event_start_cb; - sm->sch.cb_arg = sm; - sm->sch.sched_type = BLE_LL_SCHED_TYPE_SYNC; - if (ble_ll_sched_sync(&sm->sch, rxhdr->beg_cputime, rxhdr->rem_usecs, offset, sm->phy_mode)) { return; @@ -2031,10 +1980,6 @@ ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, sm->chan_index = ble_ll_utils_calc_dci_csa2(sm->event_cntr, sm->channel_id, sm->num_used_chans, sm->chanmap); - sm->sch.sched_cb = ble_ll_sync_event_start_cb; - sm->sch.cb_arg = sm; - sm->sch.sched_type = BLE_LL_SCHED_TYPE_SYNC; - /* get anchor for specified conn event */ conn_event_count = get_le16(sync_ind + 20); ble_ll_conn_get_anchor(connsm, conn_event_count, &sm->anchor_point, From 70021b6dd854350b37e782212c318cb25e4caeea Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Thu, 14 Oct 2021 13:36:32 +0200 Subject: [PATCH 0029/1333] npl/riot: update syscfg/syscfg.h --- porting/npl/riot/include/syscfg/syscfg.h | 96 ++++++++++++++++-------- 1 file changed, 63 insertions(+), 33 deletions(-) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index e3d282e1d8..480616b819 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0-dev + * This file was generated by Apache newt version: 1.9.0 */ #ifndef H_MYNEWT_SYSCFG_ @@ -18,16 +18,16 @@ /*** Repository @apache-mynewt-core info */ #ifndef MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_CORE -#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_CORE ("6b205affd69a6f05787264fa2c70c621bbbdd325") +#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_CORE ("58d4be4b8e33dd4738a2a0c1c2016a9195542833") #endif #ifndef MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_CORE -#define MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_CORE ("0.0.0") +#define MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_CORE ("0.0.1") #endif /*** Repository @apache-mynewt-mcumgr info */ #ifndef MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_MCUMGR -#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_MCUMGR ("64f5060bd8bb466367e0da94da8b425d5b9f6388") +#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_MCUMGR ("12b496e37caf20a45ab5aee4209b06c5d79ef9b1") #endif #ifndef MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_MCUMGR @@ -36,7 +36,7 @@ /*** Repository @apache-mynewt-nimble info */ #ifndef MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_NIMBLE -#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_NIMBLE ("3e5d7a994e117b2758906154433a1aac860cc845-dirty") +#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_NIMBLE ("99de1340e7fbdee6a604415972bd24ec5117a78d") #endif #ifndef MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_NIMBLE @@ -45,7 +45,7 @@ /*** Repository @mcuboot info */ #ifndef MYNEWT_VAL_REPO_HASH_MCUBOOT -#define MYNEWT_VAL_REPO_HASH_MCUBOOT ("579b30c29999860f9f7d843a25ff5453b6542cce") +#define MYNEWT_VAL_REPO_HASH_MCUBOOT ("137d79717764ed32d5da4b4b301f32f81b2bf40f") #endif #ifndef MYNEWT_VAL_REPO_VERSION_MCUBOOT @@ -73,6 +73,10 @@ #define MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS (1) #endif +#ifndef MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT +#define MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT (0) +#endif + #ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ #define MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ (16) #endif @@ -85,6 +89,10 @@ #define MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES (0) #endif +#ifndef MYNEWT_VAL_HAL_SBRK +#define MYNEWT_VAL_HAL_SBRK (1) +#endif + #ifndef MYNEWT_VAL_HAL_SYSTEM_RESET_CB #define MYNEWT_VAL_HAL_SYSTEM_RESET_CB (0) #endif @@ -157,10 +165,24 @@ #define MYNEWT_VAL_MCU_GPIO_USE_PORT_EVENT (0) #endif +#ifndef MYNEWT_VAL_MCU_HFCLK_SOURCE__HFINT +#define MYNEWT_VAL_MCU_HFCLK_SOURCE__HFINT (0) +#endif +#ifndef MYNEWT_VAL_MCU_HFCLK_SOURCE__HFXO +#define MYNEWT_VAL_MCU_HFCLK_SOURCE__HFXO (1) +#endif +#ifndef MYNEWT_VAL_MCU_HFCLK_SOURCE +#define MYNEWT_VAL_MCU_HFCLK_SOURCE (1) +#endif + #ifndef MYNEWT_VAL_MCU_I2C_RECOVERY_DELAY_USEC #define MYNEWT_VAL_MCU_I2C_RECOVERY_DELAY_USEC (100) #endif +#ifndef MYNEWT_VAL_MCU_ICACHE_ENABLED +#define MYNEWT_VAL_MCU_ICACHE_ENABLED (0) +#endif + /* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_MCU_LFCLK_SOURCE__LFRC #define MYNEWT_VAL_MCU_LFCLK_SOURCE__LFRC (0) @@ -204,10 +226,6 @@ #define MYNEWT_VAL_NFC_PINS_AS_GPIO (1) #endif -#ifndef MYNEWT_VAL_OS_TICKS_PER_SEC -#define MYNEWT_VAL_OS_TICKS_PER_SEC (128) -#endif - #ifndef MYNEWT_VAL_PWM_0 #define MYNEWT_VAL_PWM_0 (0) #endif @@ -532,6 +550,10 @@ #define MYNEWT_VAL_OS_COREDUMP (0) #endif +#ifndef MYNEWT_VAL_OS_COREDUMP_CB +#define MYNEWT_VAL_OS_COREDUMP_CB (0) +#endif + /* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_CPUTIME_FREQ #define MYNEWT_VAL_OS_CPUTIME_FREQ (32768) @@ -650,6 +672,11 @@ #define MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME (0) #endif +/* Overridden by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx (defined by @apache-mynewt-core/kernel/os) */ +#ifndef MYNEWT_VAL_OS_TICKS_PER_SEC +#define MYNEWT_VAL_OS_TICKS_PER_SEC (128) +#endif + #ifndef MYNEWT_VAL_OS_TIME_DEBUG #define MYNEWT_VAL_OS_TIME_DEBUG (0) #endif @@ -671,6 +698,10 @@ #define MYNEWT_VAL_BASELIBC_ASSERT_FILE_LINE (0) #endif +#ifndef MYNEWT_VAL_BASELIBC_EXECUTE_GLOBAL_CONSTRUCTORS +#define MYNEWT_VAL_BASELIBC_EXECUTE_GLOBAL_CONSTRUCTORS (1) +#endif + #ifndef MYNEWT_VAL_BASELIBC_PRESENT #define MYNEWT_VAL_BASELIBC_PRESENT (1) #endif @@ -693,8 +724,12 @@ #define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10) #endif +#ifndef MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG +#define MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG (0) +#endif + #ifndef MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE -#define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (2) +#define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (9) #endif /*** @apache-mynewt-core/sys/log/common */ @@ -748,23 +783,6 @@ #define MYNEWT_VAL_LOG_LEVEL (255) #endif -/*** @apache-mynewt-core/sys/mfg */ -#ifndef MYNEWT_VAL_MFG_LOG_LVL -#define MYNEWT_VAL_MFG_LOG_LVL (15) -#endif - -#ifndef MYNEWT_VAL_MFG_LOG_MODULE -#define MYNEWT_VAL_MFG_LOG_MODULE (128) -#endif - -#ifndef MYNEWT_VAL_MFG_MAX_MMRS -#define MYNEWT_VAL_MFG_MAX_MMRS (2) -#endif - -#ifndef MYNEWT_VAL_MFG_SYSINIT_STAGE -#define MYNEWT_VAL_MFG_SYSINIT_STAGE (100) -#endif - /*** @apache-mynewt-core/sys/sys */ #ifndef MYNEWT_VAL_DEBUG_PANIC_ENABLED #define MYNEWT_VAL_DEBUG_PANIC_ENABLED (1) @@ -994,6 +1012,10 @@ #define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_HCI_EV (-1) #endif +#ifndef MYNEWT_VAL_BLE_LL_DEBUG_GPIO_RFMGMT +#define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_RFMGMT (-1) +#endif + #ifndef MYNEWT_VAL_BLE_LL_DEBUG_GPIO_SCHED_ITEM_CB #define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_SCHED_ITEM_CB (-1) #endif @@ -1019,6 +1041,10 @@ #define MYNEWT_VAL_BLE_LL_EXT_ADV_AUX_PTR_CNT (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_HCI_LLCP_TRACE +#define MYNEWT_VAL_BLE_LL_HCI_LLCP_TRACE (0) +#endif + #ifndef MYNEWT_VAL_BLE_LL_MASTER_SCA #define MYNEWT_VAL_BLE_LL_MASTER_SCA (4) #endif @@ -1069,6 +1095,10 @@ #define MYNEWT_VAL_BLE_LL_SCA (60) #endif +#ifndef MYNEWT_VAL_BLE_LL_SCAN_AUX_SEGMENT_CNT +#define MYNEWT_VAL_BLE_LL_SCAN_AUX_SEGMENT_CNT (8) +#endif + #ifndef MYNEWT_VAL_BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY #define MYNEWT_VAL_BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY (0) #endif @@ -1487,16 +1517,16 @@ #define MYNEWT_VAL_BLE_SM_SC (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY -#define MYNEWT_VAL_BLE_SM_SC_ONLY (0) +#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS +#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif #ifndef MYNEWT_VAL_BLE_SM_SC_LVL #define MYNEWT_VAL_BLE_SM_SC_LVL (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS -#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) +#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY +#define MYNEWT_VAL_BLE_SM_SC_ONLY (0) #endif #ifndef MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST @@ -1568,7 +1598,7 @@ #endif #ifndef MYNEWT_VAL_BLE_ACL_BUF_SIZE -#define MYNEWT_VAL_BLE_ACL_BUF_SIZE (255) +#define MYNEWT_VAL_BLE_ACL_BUF_SIZE (65535) #endif #ifndef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE From 4fd03df5433617284294078ac4dc39e3b16a569c Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Wed, 20 Oct 2021 17:22:31 +0200 Subject: [PATCH 0030/1333] npl/riot: map nrf52_clock_hfxo_request/release() Compiling the hal_timer abstractions requires nrf52_clock_hfxo_request() and _release() functions to be available. This commit maps the appropriate RIOT functions in the NPL layer. --- .../npl/riot/include/nimble/nimble_npl_os.h | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/porting/npl/riot/include/nimble/nimble_npl_os.h b/porting/npl/riot/include/nimble/nimble_npl_os.h index ee0dfab340..4633cbd1a7 100644 --- a/porting/npl/riot/include/nimble/nimble_npl_os.h +++ b/porting/npl/riot/include/nimble/nimble_npl_os.h @@ -27,6 +27,10 @@ #include "sema.h" #include "ztimer.h" +#if defined(CPU_FAM_NRF51) || defined(CPU_FAM_NRF52) +#include "nrf_clock.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -270,6 +274,22 @@ ble_npl_hw_is_in_critical(void) return (bool)!irq_is_enabled(); } +/* XXX: these functions are required to build hal_timer.c, however with the +* default configuration they are never used... */ +#if defined(CPU_FAM_NRF51) || defined(CPU_FAM_NRF52) +static inline void +nrf52_clock_hfxo_request(void) +{ + clock_hfxo_request(); +} + +static inline void +nrf52_clock_hfxo_release(void) +{ + clock_hfxo_release(); +} +#endif + #ifdef __cplusplus } #endif From 8d66e40cc901ac37eccea54752df0803879c1e57 Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Mon, 25 Oct 2021 12:34:16 +0200 Subject: [PATCH 0031/1333] controller: fix assert bug in ble_ll_sched_insert() When trying to schedule connection events for a connection while there are already advertising events as well as connections events for other connections in the queue, ble_ll_sched_insert() triggers an assertion failure. This happens, because `preemt_first` is not reset for the case that the new event can not be scheduled. This commit fixes this issue. --- nimble/controller/src/ble_ll_sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 1eb7d549ea..1c7db41b9b 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -222,6 +222,7 @@ ble_ll_sched_insert(struct ble_ll_sched_item *sch, uint32_t max_delay, preempt_first = entry; } } else { + preempt_first = NULL; sch->start_time = entry->end_time; if ((max_delay == 0) || CPUTIME_GEQ(sch->start_time, @@ -231,7 +232,6 @@ ble_ll_sched_insert(struct ble_ll_sched_item *sch, uint32_t max_delay, } sch->end_time = sch->start_time + duration; - preempt_first = NULL; } } } From 21fa48c18cc5376f997c87ce27704035e097c42d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 29 Oct 2021 10:05:47 +0200 Subject: [PATCH 0032/1333] host/mesh: fix send_pub_key We should copy from om_data, not om_databuf. --- nimble/host/mesh/src/provisioner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/provisioner.c b/nimble/host/mesh/src/provisioner.c index c51a769674..2e592096e1 100644 --- a/nimble/host/mesh/src/provisioner.c +++ b/nimble/host/mesh/src/provisioner.c @@ -349,7 +349,7 @@ static void send_pub_key(void) sys_memcpy_swap(net_buf_simple_add(buf, 32), &key[32], 32); /* PublicKeyProvisioner */ - memcpy(&bt_mesh_prov_link.conf_inputs[17], &buf->om_databuf[1], 64); + memcpy(&bt_mesh_prov_link.conf_inputs[17], &buf->om_data[1], 64); if (bt_mesh_prov_send(buf, public_key_sent)) { BT_ERR("Failed to send Public Key"); From 5c80f17a36a422837d9d5fa1d93a83831cb4da72 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 28 Oct 2021 10:31:44 +0200 Subject: [PATCH 0033/1333] nimble/phy/cmac: Fix rx-tx-rx transition setup In rare cases, tx-rx transition after rx may not be set properly and this can result in a connection that is not established properly. Transition type is set from ble_phy_tx which is called from sw_mac isr and it should be set before bs_start is fired since it will setup that transition. This is not a problem on 1st tx, but in case this happens after rx, it may happen that bs_start is called before ble_phy_tx sets transition type, so there will be no transition set. However, following events will have proper transition set so they will act accordingly. This probably can be recovered in most cases, but in case of extended connection we will not receive AUX_CONNECT_RSP and will keep "waiting" for it, so the connection will not be set properly before 1st conn event and that results in an assert. The fix is to block bs_ctrl interrupts on tx-rx transition to make sure bs_start will not happen until ble_phy_tx sets transition correctly. Similar flow is already used for 1st tx, i.e. bs_ctrl interrupts are disabled by ble_phy_set_start_time and enabled again in ble_phy_tx. Obviously, we also have to enable interrupts in ble_phy_disable in case flow is interrupted somewhere in the middle. --- nimble/drivers/dialog_cmac/src/ble_phy.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index 74c67b68b5..212d19b671 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -935,6 +935,12 @@ ble_phy_irq_frame_rx_exc_phy_to_idle_4this(void) rf_chan = g_ble_phy_chan_to_rf[g_ble_phy_data.channel]; ble_rf_setup_tx(rf_chan, g_ble_phy_data.phy_mode_tx); g_ble_phy_data.phy_state = BLE_PHY_STATE_TX; + + /* We do not want FIELD/FRAME interrupts until ble_phy_tx() has pushed all + * fields. + */ + NVIC_DisableIRQ(FRAME_IRQn); + NVIC_DisableIRQ(FIELD_IRQn); } static void @@ -1305,6 +1311,9 @@ ble_phy_disable(void) __enable_irq(); + NVIC_EnableIRQ(FRAME_IRQn); + NVIC_EnableIRQ(FIELD_IRQn); + g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE; } @@ -1552,8 +1561,6 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) tx_late: STATS_INC(ble_phy_stats, tx_late); ble_phy_disable(); - NVIC_EnableIRQ(FRAME_IRQn); - NVIC_EnableIRQ(FIELD_IRQn); rc = BLE_PHY_ERR_TX_LATE; done: From f75ccfca9a25793de82a552abb13a0ce65b4d37f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sun, 17 Oct 2021 13:09:40 +0200 Subject: [PATCH 0034/1333] nimble/ll: Fix marking AdvA as resolved when restoring addrd AdvA was resolved only if corresponding flag is set. It's possible to have rpa_index>0 and not resolved AdvA in case AdvA was an identity address but it was added to rl. --- nimble/controller/src/ble_ll_scan.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 9b123622cb..4fdf0f640b 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -2439,14 +2439,19 @@ ble_ll_scan_rx_pkt_in_restore_addr_data(struct ble_mbuf_hdr *hdr, addrd->adv_addr_type = addrd->adva_type; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - if (rxinfo->rpa_index >= 0) { + addrd->rpa_index = rxinfo->rpa_index; + + if (hdr->rxinfo.flags & BLE_MBUF_HDR_F_RESOLVED) { + BLE_LL_ASSERT(rxinfo->rpa_index >= 0); rl = &g_ble_ll_resolv_list[rxinfo->rpa_index]; addrd->adv_addr = rl->rl_identity_addr; addrd->adv_addr_type = rl->rl_addr_type; + addrd->adva_resolved = 1; } if (hdr->rxinfo.flags & BLE_MBUF_HDR_F_TARGETA_RESOLVED) { addrd->targeta = ble_ll_get_our_devaddr(scansm->own_addr_type & 1); addrd->targeta_type = scansm->own_addr_type & 1; + addrd->targeta_resolved = 1; } #endif } From 4d95b1c3ccfdf2d30abc53ac6eeb8b0e7cc6362e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sun, 17 Oct 2021 12:34:38 +0200 Subject: [PATCH 0035/1333] nimble/ll: Fix uninitialized members in addr_data --- nimble/controller/src/ble_ll_scan.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 4fdf0f640b..9ce7877b10 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -2447,11 +2447,16 @@ ble_ll_scan_rx_pkt_in_restore_addr_data(struct ble_mbuf_hdr *hdr, addrd->adv_addr = rl->rl_identity_addr; addrd->adv_addr_type = rl->rl_addr_type; addrd->adva_resolved = 1; + } else { + addrd->adva_resolved = 0; } + if (hdr->rxinfo.flags & BLE_MBUF_HDR_F_TARGETA_RESOLVED) { addrd->targeta = ble_ll_get_our_devaddr(scansm->own_addr_type & 1); addrd->targeta_type = scansm->own_addr_type & 1; addrd->targeta_resolved = 1; + } else { + addrd->targeta_resolved = 0; } #endif } From 2443892ccc707886d04ef2cf802a41a935ec6cfd Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 16 Oct 2021 01:20:00 +0200 Subject: [PATCH 0036/1333] nimble/ll: Use generic scanner for initiator This moves initiator state handling to generic scanner and removes existing spearate ll_initiating state from LL and associated code. By using generic code we no longer need to worry about maintaining two separate instances of similar code since e.g. privacy and filtering is done via the same code path. Also we no longer need old aux scanner code so all remaining parts of that code can be removed. This saves ~3K of flash (optimized build with all features enabled) and also some RAM (mostly depending on pool size used by old aux scanner). --- nimble/controller/include/controller/ble_ll.h | 1 - .../include/controller/ble_ll_conn.h | 35 +- .../include/controller/ble_ll_scan.h | 84 +- .../include/controller/ble_ll_sched.h | 1 - nimble/controller/src/ble_ll.c | 12 - nimble/controller/src/ble_ll_conn.c | 826 ++--------------- nimble/controller/src/ble_ll_conn_hci.c | 19 +- nimble/controller/src/ble_ll_conn_priv.h | 8 - nimble/controller/src/ble_ll_scan.c | 852 +++--------------- nimble/controller/src/ble_ll_scan_aux.c | 208 ++++- nimble/controller/src/ble_ll_sched.c | 94 -- nimble/include/nimble/ble.h | 3 + 12 files changed, 477 insertions(+), 1666 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 4a832c6558..556883422c 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -216,7 +216,6 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats; #define BLE_LL_STATE_STANDBY (0) #define BLE_LL_STATE_ADV (1) #define BLE_LL_STATE_SCANNING (2) -#define BLE_LL_STATE_INITIATING (3) #define BLE_LL_STATE_CONNECTION (4) #define BLE_LL_STATE_DTM (5) #define BLE_LL_STATE_SYNC (6) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index daf7db5848..7be3a43157 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -225,9 +225,6 @@ struct ble_ll_conn_sm /* RSSI */ int8_t conn_rssi; - /* For privacy */ - int8_t rpa_index; - /* Connection data length management */ uint8_t max_tx_octets; uint8_t max_rx_octets; @@ -328,6 +325,9 @@ struct ble_ll_conn_sm uint8_t own_addr_type; uint8_t peer_addr_type; uint8_t peer_addr[BLE_DEV_ADDR_LEN]; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + uint8_t peer_addr_resolved; +#endif /* * XXX: TODO. Could save memory. Have single event at LL and put these @@ -379,7 +379,6 @@ struct ble_ll_conn_sm /* XXX: for now, just store them all */ struct ble_ll_conn_params conn_cp; - struct ble_ll_scan_sm *scansm; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) struct hci_ext_create_conn initial_params; #endif @@ -426,6 +425,34 @@ uint8_t ble_ll_conn_calc_dci(struct ble_ll_conn_sm *conn, uint16_t latency); void ble_ll_conn_get_anchor(struct ble_ll_conn_sm *connsm, uint16_t conn_event, uint32_t *anchor, uint8_t *anchor_usecs); +struct ble_ll_scan_addr_data; +struct ble_ll_scan_pdu_data; + +uint8_t ble_ll_conn_tx_connect_ind_pducb(uint8_t *dptr, void *pducb_arg, + uint8_t *hdr_byte); +void ble_ll_conn_prepare_connect_ind(struct ble_ll_conn_sm *connsm, + struct ble_ll_scan_pdu_data *pdu_data, + uint8_t adva_type, uint8_t *adva, + uint8_t inita_type, uint8_t *inita, + int rpa_index, uint8_t channel); + +/* Send CONNECT_IND/AUX_CONNECT_REQ */ +int ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu, + struct ble_ll_scan_addr_data *addrd, + uint8_t ext); +/* Cancel connection after AUX_CONNECT_REQ was sent */ +void ble_ll_conn_send_connect_req_cancel(void); +/* Signal connection created via CONNECT_IND */ +void ble_ll_conn_created_on_legacy(struct os_mbuf *rxpdu, + struct ble_ll_scan_addr_data *addrd, + uint8_t *targeta); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +/* Signal connection created via AUX_CONNECT_REQ */ +void ble_ll_conn_created_on_aux(struct os_mbuf *rxpdu, + struct ble_ll_scan_addr_data *addrd, + uint8_t *targeta); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index d3097f2b11..eae0c39457 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -89,56 +89,6 @@ struct ble_ll_scan_phy struct ble_ll_scan_timing timing; }; -#define BLE_LL_AUX_HAS_ADVA 0x01 -#define BLE_LL_AUX_HAS_TARGETA 0x02 -#define BLE_LL_AUX_HAS_ADI 0x04 -#define BLE_LL_AUX_IS_MATCHED 0x08 -#define BLE_LL_AUX_IS_TARGETA_RESOLVED 0x10 - -#define BLE_LL_AUX_FLAG_HCI_SENT_ANY 0x02 -#define BLE_LL_AUX_FLAG_HCI_SENT_COMPLETED 0x04 -#define BLE_LL_AUX_FLAG_HCI_SENT_TRUNCATED 0x08 -#define BLE_LL_AUX_FLAG_SCAN_COMPLETE 0x10 -#define BLE_LL_AUX_FLAG_SCAN_ERROR 0x20 -#define BLE_LL_AUX_FLAG_AUX_ADV_RECEIVED 0x40 -#define BLE_LL_AUX_FLAG_AUX_CHAIN_RECEIVED 0x80 - -struct ble_ll_aux_data { - uint8_t flags; - - /* - * Since aux_data can be accessed from ISR and LL, we have separate copies - * of flags to make sure that ISR does not modify flags while LL uses them. - * ISR updates 'flags_isr' and LL adds these to 'flags_ll' which it then - * uses for further processing allowing to update 'flags_isr' if another - * scan for given 'aux_data' is scheduled. Note that flags must not be unset - * while aux_data is valid. - */ - uint8_t flags_isr; - uint8_t flags_ll; - - uint8_t ref_cnt; - uint8_t chan; - uint8_t aux_phy; - uint8_t aux_primary_phy; - uint8_t mode; - uint8_t scanning; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - int8_t rpa_index; -#endif - uint16_t adi; - uint32_t offset; - uint8_t offset_units; - uint8_t adva[6]; - uint8_t adva_type; - uint8_t targeta[6]; - uint8_t targeta_type; - uint16_t evt_type; - struct ble_ll_sched_item sch; - struct ble_hci_ev *evt; - struct ble_npl_event ev; -}; - struct ble_ll_scan_pdu_data { uint8_t hdr_byte; /* ScanA for SCAN_REQ and InitA for CONNECT_IND */ @@ -197,11 +147,13 @@ struct ble_ll_scan_sm #endif uint8_t restart_timer_needed; - struct ble_ll_aux_data *cur_aux_data; struct ble_ll_scan_phy *scanp; struct ble_ll_scan_phy *scanp_next; struct ble_ll_scan_phy scan_phys[BLE_LL_SCAN_PHY_NUMBER]; + + /* Connection sm for initiator scan */ + struct ble_ll_conn_sm *connsm; }; /* Scan types */ @@ -244,13 +196,11 @@ int ble_ll_scan_can_chg_whitelist(void); /* Boolean function returning true if scanning enabled */ int ble_ll_scan_enabled(void); -/* Boolean function returns true if whitelist is enabled for scanning */ -int ble_ll_scan_whitelist_enabled(void); - /* Initialize the scanner when we start initiating */ struct hci_create_conn; -int ble_ll_scan_initiator_start(struct hci_create_conn *hcc, - struct ble_ll_scan_sm **sm); +int +ble_ll_scan_initiator_start(struct hci_create_conn *hcc, + struct ble_ll_conn_sm *connsm); /* Returns storage for PDU data (for SCAN_REQ or CONNECT_IND) */ struct ble_ll_scan_pdu_data *ble_ll_scan_get_pdu_data(void); @@ -276,24 +226,14 @@ void ble_ll_scan_wfr_timer_exp(void); /* Called when scan could be interrupted */ void ble_ll_scan_interrupted(struct ble_ll_scan_sm *scansm); -int ble_ll_scan_adv_decode_addr(uint8_t pdu_type, uint8_t *rxbuf, - struct ble_mbuf_hdr *ble_hdr, - uint8_t **addr, uint8_t *addr_type, - uint8_t **inita, uint8_t *init_addr_type, - int *ext_mode); - #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -int ble_ll_scan_update_aux_data(struct ble_mbuf_hdr *ble_hdr, uint8_t *rxbuf, - bool *adva_present); - /* Initialize the extended scanner when we start initiating */ struct hci_ext_create_conn; -int ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, - struct ble_ll_scan_sm **sm); +int +ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, + struct ble_ll_conn_sm *connsm); /* Called to parse extended advertising*/ -struct ble_ll_aux_data *ble_ll_scan_aux_data_ref(struct ble_ll_aux_data *aux_scan); -void ble_ll_scan_aux_data_unref(struct ble_ll_aux_data *aux_scan); void ble_ll_scan_end_adv_evt(struct ble_ll_aux_data *aux_data); #endif @@ -316,8 +256,10 @@ int ble_ll_scan_have_rxd_scan_rsp(uint8_t *addr, uint8_t txadd, uint8_t ext_adv, void ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t txadd, uint8_t ext_adv, uint16_t adi); -int ble_ll_scan_rx_filter(uint8_t own_addr_type, uint8_t scan_filt_policy, - struct ble_ll_scan_addr_data *addrd, uint8_t *scan_ok); +int +ble_ll_scan_rx_filter(uint8_t own_addr_type, uint8_t scan_filt_policy, + struct ble_ll_scan_addr_data *addrd, uint8_t *scan_ok); +int ble_ll_scan_rx_check_init(struct ble_ll_scan_addr_data *addrd); #ifdef __cplusplus } diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index 15f331998c..45e148cbd6 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -67,7 +67,6 @@ extern uint8_t g_ble_ll_sched_offset_ticks; #define BLE_LL_SCHED_TYPE_ADV (1) #define BLE_LL_SCHED_TYPE_SCAN (2) #define BLE_LL_SCHED_TYPE_CONN (3) -#define BLE_LL_SCHED_TYPE_AUX_SCAN (4) #define BLE_LL_SCHED_TYPE_DTM (5) #define BLE_LL_SCHED_TYPE_PERIODIC (6) #define BLE_LL_SCHED_TYPE_SYNC (7) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 8c7095a7e1..2702b7c53a 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -677,9 +677,6 @@ ble_ll_wfr_timer_exp(void *arg) case BLE_LL_STATE_SCANNING: ble_ll_scan_wfr_timer_exp(); break; - case BLE_LL_STATE_INITIATING: - ble_ll_conn_init_wfr_timer_exp(); - break; #if MYNEWT_VAL(BLE_LL_DTM) case BLE_LL_STATE_DTM: ble_ll_dtm_wfr_timer_exp(); @@ -842,9 +839,6 @@ ble_ll_rx_pkt_in(void) case BLE_LL_STATE_SCANNING: ble_ll_scan_rx_pkt_in(pdu_type, m, ble_hdr); break; - case BLE_LL_STATE_INITIATING: - ble_ll_init_rx_pkt_in(pdu_type, rxbuf, ble_hdr); - break; #if MYNEWT_VAL(BLE_LL_DTM) case BLE_LL_STATE_DTM: ble_ll_dtm_rx_pkt_in(m, ble_hdr); @@ -980,9 +974,6 @@ ble_ll_rx_start(uint8_t *rxbuf, uint8_t chan, struct ble_mbuf_hdr *rxhdr) case BLE_LL_STATE_ADV: rc = ble_ll_adv_rx_isr_start(pdu_type); break; - case BLE_LL_STATE_INITIATING: - rc = ble_ll_init_rx_isr_start(pdu_type, rxhdr); - break; case BLE_LL_STATE_SCANNING: rc = ble_ll_scan_rx_isr_start(pdu_type, &rxhdr->rxinfo.flags); break; @@ -1122,9 +1113,6 @@ ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) } rc = ble_ll_scan_rx_isr_end(rxpdu, crcok); break; - case BLE_LL_STATE_INITIATING: - rc = ble_ll_init_rx_isr_end(rxbuf, crcok, rxhdr); - break; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) case BLE_LL_STATE_SCAN_AUX: if (!badpkt) { diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 0f930d94e3..76dd18e4bc 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -674,64 +674,6 @@ ble_ll_conn_wfr_timer_exp(void) STATS_INC(ble_ll_conn_stats, wfr_expirations); } -void -ble_ll_conn_reset_pending_aux_conn_rsp(void) -{ -#if !MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - return; -#endif - struct ble_ll_conn_sm *connsm; - - connsm = g_ble_ll_conn_create_sm; - if (!connsm) { - return; - } - - if (CONN_F_AUX_CONN_REQ(connsm)) { - STATS_INC(ble_ll_stats, aux_conn_rsp_err); - CONN_F_CONN_REQ_TXD(connsm) = 0; - CONN_F_AUX_CONN_REQ(connsm) = 0; - ble_ll_sched_rmv_elem(&connsm->conn_sch); - return; - } - - return; -} - -bool -ble_ll_conn_init_pending_aux_conn_rsp(void) -{ -#if !MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - return false; -#endif - struct ble_ll_conn_sm *connsm; - - connsm = g_ble_ll_conn_create_sm; - if (!connsm) { - return false; - } - - return CONN_F_AUX_CONN_REQ(connsm); -} - -void -ble_ll_conn_init_wfr_timer_exp(void) -{ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - struct ble_ll_conn_sm *connsm; - - connsm = g_ble_ll_conn_create_sm; - if (!connsm) { - return; - } - - ble_ll_conn_reset_pending_aux_conn_rsp(); - connsm->inita_identity_used = 0; - - ble_ll_scan_interrupted(connsm->scansm); - -#endif -} /** * Callback for slave when it transmits a data pdu and the connection event * ends after the transmission. @@ -1764,6 +1706,13 @@ void ble_ll_conn_ext_set_params(struct ble_ll_conn_sm *connsm, struct hci_ext_conn_params *hcc_params, int phy) { + connsm->slave_latency = hcc_params->conn_latency; + connsm->supervision_tmo = hcc_params->supervision_timeout; + + connsm->conn_itvl = hcc_params->conn_itvl; + connsm->conn_itvl_ticks = hcc_params->conn_itvl_ticks; + connsm->conn_itvl_usecs = hcc_params->conn_itvl_usecs; + /* Check the min/max CE lengths are less than connection interval */ if (hcc_params->min_ce_len > (connsm->conn_itvl * 2)) { connsm->min_ce_len = connsm->conn_itvl * 2; @@ -1833,7 +1782,6 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) connsm->sub_vers_nr = 0; connsm->reject_reason = BLE_ERR_SUCCESS; connsm->conn_rssi = BLE_LL_CONN_UNKNOWN_RSSI; - connsm->rpa_index = -1; connsm->inita_identity_used = 0; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) @@ -2667,8 +2615,8 @@ ble_ll_conn_event_end(struct ble_npl_event *ev) * @param txoffset The tx window offset for this connection */ -static void -ble_ll_conn_connect_ind_prepare(struct ble_ll_conn_sm *connsm, +void +ble_ll_conn_prepare_connect_ind(struct ble_ll_conn_sm *connsm, struct ble_ll_scan_pdu_data *pdu_data, uint8_t adva_type, uint8_t *adva, uint8_t inita_type, uint8_t *inita, @@ -2753,110 +2701,8 @@ ble_ll_conn_connect_ind_prepare(struct ble_ll_conn_sm *connsm, pdu_data->hdr_byte = hdr; } -/* Returns true if the address matches the connection peer address having in - * mind privacy mode - */ -static int -ble_ll_conn_is_peer_adv(uint8_t addr_type, uint8_t *adva, int index) -{ - int rc; - uint8_t *peer_addr = NULL; - struct ble_ll_conn_sm *connsm; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - struct ble_ll_resolv_entry *rl; -#endif - - /* XXX: Deal with different types of random addresses here! */ - connsm = g_ble_ll_conn_create_sm; - if (!connsm) { - return 0; - } - - switch (connsm->peer_addr_type) { - /* Fall-through intentional */ - case BLE_HCI_CONN_PEER_ADDR_PUBLIC: - case BLE_HCI_CONN_PEER_ADDR_RANDOM: -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - if (ble_ll_addr_is_id(adva, addr_type)) { - /* Peer uses its identity address. Let's verify privacy mode. - * - * Note: Core Spec 5.0 Vol 6, Part B - * If the Host has added the peer device to the resolving list - * with an all-zero peer IRK, the Controller shall only accept - * the peer's identity address. - */ - if (ble_ll_resolv_enabled()) { - rl = ble_ll_resolv_list_find(adva, addr_type); - if (rl && (rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) && - rl->rl_has_peer) { - return 0; - } - } - } - - /* Check if peer uses RPA. If so and it match, use it as controller - * supports privacy mode - */ - if ((index >= 0) && - (g_ble_ll_resolv_list[index].rl_addr_type == connsm->peer_addr_type)) { - peer_addr = g_ble_ll_resolv_list[index].rl_identity_addr; - } -#endif - /* - * If we are here it means we don't know the device, lets - * check if type is what we are looking for and later - * if address matches - */ - if ((connsm->peer_addr_type == addr_type) && !peer_addr) { - peer_addr = adva; - } - - break; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - case BLE_HCI_CONN_PEER_ADDR_PUBLIC_IDENT: - if ((index < 0) || - (g_ble_ll_resolv_list[index].rl_addr_type != 0)) { - return 0; - } - peer_addr = g_ble_ll_resolv_list[index].rl_identity_addr; - break; - case BLE_HCI_CONN_PEER_ADDR_RANDOM_IDENT: - if ((index < 0) || - (g_ble_ll_resolv_list[index].rl_addr_type != 1)) { - return 0; - } - peer_addr = g_ble_ll_resolv_list[index].rl_identity_addr; - break; -#endif - default: - peer_addr = NULL; - break; - } - - rc = 0; - if (peer_addr) { - if (!memcmp(peer_addr, connsm->peer_addr, BLE_DEV_ADDR_LEN)) { - rc = 1; - } - } - - return rc; -} - -static void -ble_ll_conn_connect_ind_txend_to_standby(void *arg) -{ - ble_ll_state_set(BLE_LL_STATE_STANDBY); -} - -static void -ble_ll_conn_connect_ind_txend_to_init(void *arg) -{ - ble_ll_state_set(BLE_LL_STATE_INITIATING); -} - -static uint8_t -ble_ll_conn_connect_ind_tx_pducb(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) +uint8_t +ble_ll_conn_tx_connect_ind_pducb(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) { struct ble_ll_conn_sm *connsm; struct ble_ll_scan_pdu_data *pdu_data; @@ -2890,30 +2736,6 @@ ble_ll_conn_connect_ind_tx_pducb(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_by return 34; } -/** - * Send a connection requestion to an advertiser - * - * Context: Interrupt - * - * @param addr_type Address type of advertiser - * @param adva Address of advertiser - */ -int -ble_ll_conn_connect_ind_send(struct ble_ll_conn_sm *connsm, uint8_t end_trans) -{ - int rc; - - if (end_trans == BLE_PHY_TRANSITION_NONE) { - ble_phy_set_txend_cb(ble_ll_conn_connect_ind_txend_to_standby, NULL); - } else { - ble_phy_set_txend_cb(ble_ll_conn_connect_ind_txend_to_init, NULL); - } - - rc = ble_phy_tx(ble_ll_conn_connect_ind_tx_pducb, connsm, end_trans); - - return rc; -} - /** * Called when a schedule item overlaps the currently running connection * event. This generally should not happen, but if it does we stop the @@ -2933,595 +2755,141 @@ ble_ll_conn_event_halt(void) } } -/** - * Process a received PDU while in the initiating state. - * - * Context: Link Layer task. - * - * @param pdu_type - * @param rxbuf - * @param ble_hdr - */ -void -ble_ll_init_rx_pkt_in(uint8_t pdu_type, uint8_t *rxbuf, - struct ble_mbuf_hdr *ble_hdr) +int +ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu, + struct ble_ll_scan_addr_data *addrd, + uint8_t ext) { - uint8_t addr_type; - uint8_t *addr; - uint8_t *adv_addr; - uint8_t *inita; - uint8_t inita_type; struct ble_ll_conn_sm *connsm; - int ext_adv_mode = -1; + struct ble_mbuf_hdr *rxhdr; + int8_t rpa_index; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - struct ble_ll_aux_data *aux_data = NULL; - - if (ble_hdr->rxinfo.user_data) { - /* aux_data just a local helper, no need to ref - * as ble_hdr->rxinfo.user_data is unref in the end of this function - */ - aux_data = ble_hdr->rxinfo.user_data; - } + struct hci_ext_conn_params *ecp; + uint8_t phy; #endif + int rc; - /* Get the connection state machine we are trying to create */ connsm = g_ble_ll_conn_create_sm; - if (!connsm) { -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - if (aux_data) { - ble_ll_scan_aux_data_unref(ble_hdr->rxinfo.user_data); - ble_hdr->rxinfo.user_data = NULL; - } -#endif - return; - } - - if (!BLE_MBUF_HDR_CRC_OK(ble_hdr)) { - goto scan_continue; - } + rxhdr = BLE_MBUF_HDR_PTR(rxpdu); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - if (BLE_MBUF_HDR_AUX_INVALID(ble_hdr)) { - goto scan_continue; - } - - if (pdu_type == BLE_ADV_PDU_TYPE_ADV_EXT_IND) { - if (BLE_MBUF_HDR_WAIT_AUX(ble_hdr)) { - /* Just continue scanning. We are waiting for AUX */ - if (!ble_ll_sched_aux_scan(ble_hdr, connsm->scansm, aux_data)) { - /* ref for aux ptr in the scheduler */ - ble_ll_scan_aux_data_unref(ble_hdr->rxinfo.user_data); - ble_hdr->rxinfo.user_data = NULL; - ble_ll_scan_chk_resume(); - return; - } - goto scan_continue; - } - } - - if (CONN_F_AUX_CONN_REQ(connsm)) { - if (pdu_type != BLE_ADV_PDU_TYPE_AUX_CONNECT_RSP) { - /* Wait for connection response, in this point of time aux is NULL */ - BLE_LL_ASSERT(ble_hdr->rxinfo.user_data == NULL); - return; - } + if (ext) { +#if BLE_LL_BT5_PHY_SUPPORTED + phy = rxhdr->rxinfo.phy; +#else + phy = BLE_PHY_1M; +#endif + ecp = &connsm->initial_params.params[phy - 1]; + ble_ll_conn_ext_set_params(connsm, ecp, phy); } #endif - /* If we have sent a connect request, we need to enter CONNECTION state */ - if (connsm && CONN_F_CONN_REQ_TXD(connsm)) { - /* Set address of advertiser to which we are connecting. */ - - if (ble_ll_scan_adv_decode_addr(pdu_type, rxbuf, ble_hdr, - &adv_addr, &addr_type, - &inita, &inita_type, &ext_adv_mode)) { - /* Something got wrong, keep trying to connect */ - goto scan_continue; - } + if (ble_ll_sched_master_new(connsm, rxhdr, 0)) { + return -1; + } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - /* - * Did we resolve this address? If so, set correct peer address - * and peer address type. - */ - if (connsm->rpa_index >= 0) { - addr_type = g_ble_ll_resolv_list[connsm->rpa_index].rl_addr_type + 2; - addr = g_ble_ll_resolv_list[connsm->rpa_index].rl_identity_addr; - } else { - addr = adv_addr; - } + rpa_index = addrd->rpa_index; #else - addr = adv_addr; + rpa_index = -1; #endif + ble_ll_conn_prepare_connect_ind(connsm, ble_ll_scan_get_pdu_data(), + addrd->adva_type, addrd->adva, + addrd->targeta_type, addrd->targeta, + rpa_index, rxhdr->rxinfo.channel); - if (connsm->rpa_index >= 0) { - connsm->peer_addr_type = addr_type; - memcpy(connsm->peer_addr, addr, BLE_DEV_ADDR_LEN); - - ble_ll_scan_set_peer_rpa(adv_addr); - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - /* Update resolving list with current peer RPA */ - ble_ll_resolv_set_peer_rpa(connsm->rpa_index, rxbuf + BLE_LL_PDU_HDR_LEN); - if (ble_ll_is_rpa(inita, inita_type)) { - ble_ll_resolv_set_local_rpa(connsm->rpa_index, inita); - } - -#endif - } else if (ble_ll_scan_whitelist_enabled()) { - /* if WL is used we need to store peer addr also if it was not - * resolved - */ - connsm->peer_addr_type = addr_type; - memcpy(connsm->peer_addr, addr, BLE_DEV_ADDR_LEN); - } - - /* Connection has been created. Stop scanning */ - g_ble_ll_conn_create_sm = NULL; - ble_ll_scan_sm_stop(0); - - /* For AUX Connect CSA2 is mandatory. Otherwise we need to check bit - * mask - */ - if (ble_hdr->rxinfo.channel < BLE_PHY_NUM_DATA_CHANS) { - ble_ll_conn_set_csa(connsm, 1); - } else { - ble_ll_conn_set_csa(connsm, rxbuf[0] & BLE_ADV_PDU_HDR_CHSEL_MASK); - } - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - /* Lets take last used phy */ - ble_ll_conn_init_phy(connsm, ble_hdr->rxinfo.phy); -#endif - if (aux_data) { - ble_ll_scan_aux_data_unref(ble_hdr->rxinfo.user_data); - ble_hdr->rxinfo.user_data = NULL; - } -#endif - ble_ll_conn_created(connsm, NULL); - return; + ble_phy_set_txend_cb(NULL, NULL); + rc = ble_phy_tx(ble_ll_conn_tx_connect_ind_pducb, connsm, + ext ? BLE_PHY_TRANSITION_TX_RX : BLE_PHY_TRANSITION_NONE); + if (rc) { + ble_ll_conn_send_connect_req_cancel(); + return -1; } -scan_continue: -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - /* Drop last reference and keep continue to connect */ - if (aux_data) { - ble_ll_scan_aux_data_unref(ble_hdr->rxinfo.user_data); - ble_hdr->rxinfo.user_data = NULL; - } -#endif - ble_ll_scan_chk_resume(); + return 0; } -/** - * Called when a receive PDU has started and we are in the initiating state. - * - * Context: Interrupt - * - * @param pdu_type - * @param ble_hdr - * - * @return int - * 0: we will not attempt to reply to this frame - * 1: we may send a response to this frame. - */ -int -ble_ll_init_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *ble_hdr) +void +ble_ll_conn_send_connect_req_cancel(void) { struct ble_ll_conn_sm *connsm; connsm = g_ble_ll_conn_create_sm; - if (!connsm) { - return 0; - } - - if ((pdu_type == BLE_ADV_PDU_TYPE_ADV_IND) || - (pdu_type == BLE_ADV_PDU_TYPE_ADV_DIRECT_IND || - pdu_type == BLE_ADV_PDU_TYPE_AUX_CONNECT_RSP)) { - return 1; - } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - if (pdu_type == BLE_ADV_PDU_TYPE_ADV_EXT_IND && - connsm->scansm->ext_scanning) { - if (connsm->scansm->cur_aux_data) { - STATS_INC(ble_ll_stats, aux_received); - } - - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_EXT_ADV; - return 1; - } -#endif - - return 0; + ble_ll_sched_rmv_elem(&connsm->conn_sch); } -/** - * Called when a receive PDU has ended and we are in the initiating state. - * - * Context: Interrupt - * - * @param rxpdu - * @param crcok - * @param ble_hdr - * - * @return int - * < 0: Disable the phy after reception. - * == 0: Success. Do not disable the PHY. - * > 0: Do not disable PHY as that has already been done. - */ -int -ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok, - struct ble_mbuf_hdr *ble_hdr) +static void +ble_ll_conn_master_start(uint8_t phy, uint8_t csa, + struct ble_ll_scan_addr_data *addrd, uint8_t *targeta) { - int rc; - int resolved; - int chk_wl; - int index; - uint8_t pdu_type; - uint8_t adv_addr_type; - uint8_t peer_addr_type; - uint8_t *adv_addr = NULL; - uint8_t *peer; - uint8_t *init_addr = NULL; - uint8_t init_addr_type; - uint8_t pyld_len; - uint8_t inita_is_rpa; - uint8_t conn_req_end_trans; - struct os_mbuf *rxpdu; struct ble_ll_conn_sm *connsm; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - struct ble_ll_resolv_entry *rl; -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - struct hci_ext_conn_params *hcp; - struct ble_ll_scan_sm *scansm; - uint8_t phy; -#endif - int ext_adv_mode = -1; - /* Get connection state machine to use if connection to be established */ connsm = g_ble_ll_conn_create_sm; - /* This could happen if connection init was cancelled while isr end was - * already pending - */ - if (!connsm) { - ble_ll_state_set(BLE_LL_STATE_STANDBY); - return -1; - } - - rc = -1; - pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK; - pyld_len = rxbuf[1]; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - scansm = connsm->scansm; - if (scansm->cur_aux_data) { - ble_hdr->rxinfo.user_data = scansm->cur_aux_data; - scansm->cur_aux_data = NULL; - } -#endif - - if (!crcok) { -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - /* Invalid packet - make sure we do not wait for AUX_CONNECT_RSP */ - ble_ll_conn_reset_pending_aux_conn_rsp(); -#endif - - /* Ignore this packet */ - goto init_rx_isr_exit; - } - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - /* If we sent AUX_CONNECT_REQ, we only expect AUX_CONNECT_RSP here */ - if (CONN_F_AUX_CONN_REQ(connsm)) { - if (pdu_type != BLE_ADV_PDU_TYPE_AUX_CONNECT_RSP) { - STATS_INC(ble_ll_stats, aux_conn_rsp_err); - CONN_F_CONN_REQ_TXD(connsm) = 0; - CONN_F_AUX_CONN_REQ(connsm) = 0; - ble_ll_sched_rmv_elem(&connsm->conn_sch); - } - goto init_rx_isr_exit; - } -#endif - - inita_is_rpa = 0; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - if (pdu_type == BLE_ADV_PDU_TYPE_ADV_EXT_IND) { - if (!scansm->ext_scanning) { - goto init_rx_isr_exit; - } - - rc = ble_ll_scan_update_aux_data(ble_hdr, rxbuf, NULL); - if (rc < 0) { - /* No memory or broken packet */ - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_AUX_INVALID; - goto init_rx_isr_exit; - } - } -#endif - - /* Lets get addresses from advertising report*/ - if (ble_ll_scan_adv_decode_addr(pdu_type, rxbuf, ble_hdr, - &adv_addr, &adv_addr_type, - &init_addr, &init_addr_type, - &ext_adv_mode)) { -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_AUX_INVALID; -#endif - goto init_rx_isr_exit; - } - - switch (pdu_type) { - case BLE_ADV_PDU_TYPE_ADV_IND: - break; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - case BLE_ADV_PDU_TYPE_ADV_EXT_IND: - rc = -1; - - /* If this is not connectable adv mode, lets skip it */ - if (!(ext_adv_mode & BLE_LL_EXT_ADV_MODE_CONN)) { - goto init_rx_isr_exit; - } - - if (!adv_addr) { - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_AUX_PTR_WAIT; - goto init_rx_isr_exit; - } - - if (!init_addr) { - break; - } - /* if there is direct address lets fall down and check it.*/ - // no break -#endif - case BLE_ADV_PDU_TYPE_ADV_DIRECT_IND: - inita_is_rpa = (uint8_t)ble_ll_is_rpa(init_addr, init_addr_type); - if (!inita_is_rpa) { - - /* Resolving will be done later. Check if identity InitA matches */ - if (!ble_ll_is_our_devaddr(init_addr, init_addr_type)) { - goto init_rx_isr_exit; - } - } -#if !MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - else { - /* If privacy is off - reject RPA InitA*/ - goto init_rx_isr_exit; - } -#endif - - break; - default: - goto init_rx_isr_exit; - } - - /* Should we send a connect request? */ - index = -1; - peer = adv_addr; - peer_addr_type = adv_addr_type; + g_ble_ll_conn_create_sm = NULL; - resolved = 0; - chk_wl = ble_ll_scan_whitelist_enabled(); + connsm->peer_addr_type = addrd->adv_addr_type; + memcpy(connsm->peer_addr, addrd->adv_addr, 6); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - if (ble_ll_is_rpa(adv_addr, adv_addr_type) && ble_ll_resolv_enabled()) { - index = ble_hw_resolv_list_match(); - if (index >= 0) { - rl = &g_ble_ll_resolv_list[index]; - - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_RESOLVED; - connsm->rpa_index = index; - peer = rl->rl_identity_addr; - peer_addr_type = rl->rl_addr_type; - resolved = 1; - - /* Assure privacy */ - if ((rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) && init_addr && - !inita_is_rpa && rl->rl_has_local) { - goto init_rx_isr_exit; - } - - /* - * If the InitA is a RPA, we must see if it resolves based on the - * identity address of the resolved ADVA. - */ - if (init_addr && inita_is_rpa) { - if (!ble_ll_resolv_rpa(init_addr, - g_ble_ll_resolv_list[index].rl_local_irk)) { - goto init_rx_isr_exit; - } - - /* Core Specification Vol 6, Part B, Section 6.4: - * "The Link Layer should not set the InitA field to the same - * value as the TargetA field in the received advertising PDU." - * - * We update the received PDU directly here, so ble_ll_init_rx_pkt_in - * can process it as is. - */ - memcpy(init_addr, rl->rl_local_rpa, BLE_DEV_ADDR_LEN); - } - - } else { - if (chk_wl) { - goto init_rx_isr_exit; - } - - /* Could not resolved InitA */ - if (init_addr && inita_is_rpa) { - goto init_rx_isr_exit; - } - } - } else if (init_addr) { - - /* If resolving is off and InitA is RPA we reject advertising */ - if (inita_is_rpa && !ble_ll_resolv_enabled()) { - goto init_rx_isr_exit; - } - - /* Let's see if we have IRK with that peer.*/ - rl = ble_ll_resolv_list_find(adv_addr, adv_addr_type); - - /* Lets make sure privacy mode is correct together with InitA in case it - * is identity address - */ - if (rl && !inita_is_rpa && - (rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) && - rl->rl_has_local) { - goto init_rx_isr_exit; - } - - /* - * If the InitA is a RPA, we must see if it resolves based on the - * identity address of the resolved ADVA. - */ - if (inita_is_rpa) { - if (!rl || !ble_ll_resolv_rpa(init_addr, rl->rl_local_irk)) { - goto init_rx_isr_exit; - } - - /* Core Specification Vol 6, Part B, Section 6.4: - * "The Link Layer should not set the InitA field to the same - * value as the TargetA field in the received advertising PDU." - * - * We update the received PDU directly here, so ble_ll_init_rx_pkt_in - * can process it as is. - */ - memcpy(init_addr, rl->rl_local_rpa, BLE_DEV_ADDR_LEN); - } - } else if (!ble_ll_is_rpa(adv_addr, adv_addr_type)) { - /* undirected with ID address, assure privacy if on RL */ - rl = ble_ll_resolv_list_find(adv_addr, adv_addr_type); - if (rl && (rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) && - rl->rl_has_peer) { - goto init_rx_isr_exit; - } - } -#endif - - /* Check filter policy */ - if (chk_wl) { - if (!ble_ll_whitelist_match(peer, peer_addr_type, resolved)) { - goto init_rx_isr_exit; - } + if (addrd->adva_resolved) { + BLE_LL_ASSERT(addrd->rpa_index >= 0); + connsm->peer_addr_resolved = 1; + ble_ll_resolv_set_peer_rpa(addrd->rpa_index, addrd->adva); + ble_ll_scan_set_peer_rpa(addrd->adva); } else { - /* Must match the connection address */ - if (!ble_ll_conn_is_peer_adv(adv_addr_type, adv_addr, index)) { - goto init_rx_isr_exit; - } + connsm->peer_addr_resolved = 0; } - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_DEVMATCH; - - /* For CONNECT_IND we don't go into RX state */ - conn_req_end_trans = BLE_PHY_TRANSITION_NONE; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - /* Check if we should send AUX_CONNECT_REQ and wait for AUX_CONNECT_RSP */ - if (ble_hdr->rxinfo.channel < BLE_PHY_NUM_DATA_CHANS) { - conn_req_end_trans = BLE_PHY_TRANSITION_TX_RX; - } - - if (connsm->scansm->ext_scanning) { - phy = ble_hdr->rxinfo.phy; - - hcp = &connsm->initial_params.params[phy - 1]; - connsm->slave_latency = hcp->conn_latency; - connsm->supervision_tmo = hcp->supervision_timeout; - - connsm->conn_itvl = hcp->conn_itvl; - connsm->conn_itvl_ticks = hcp->conn_itvl_ticks; - connsm->conn_itvl_usecs = hcp->conn_itvl_usecs; + if (addrd->targeta_resolved) { + BLE_LL_ASSERT(addrd->rpa_index >= 0); + BLE_LL_ASSERT(targeta); + ble_ll_resolv_set_local_rpa(addrd->rpa_index, targeta); } #endif - /* Schedule new connection */ - if (ble_ll_sched_master_new(connsm, ble_hdr, pyld_len)) { - STATS_INC(ble_ll_conn_stats, cant_set_sched); - goto init_rx_isr_exit; - } - - /* Prepare data for connect request */ - ble_ll_conn_connect_ind_prepare(connsm, - ble_ll_scan_get_pdu_data(), - adv_addr_type, adv_addr, - init_addr_type, init_addr, - index, ble_hdr->rxinfo.channel); + ble_ll_conn_set_csa(connsm, csa); +#if BLE_LL_BT5_PHY_SUPPORTED + ble_ll_conn_init_phy(connsm, phy); +#endif + ble_ll_conn_created(connsm, NULL); +} - /* Setup to transmit the connect request */ - rc = ble_ll_conn_connect_ind_send(connsm, conn_req_end_trans); - if (rc) { - ble_ll_sched_rmv_elem(&connsm->conn_sch); - goto init_rx_isr_exit; - } +void +ble_ll_conn_created_on_legacy(struct os_mbuf *rxpdu, + struct ble_ll_scan_addr_data *addrd, + uint8_t *targeta) +{ + uint8_t *rxbuf; + uint8_t csa; - if (init_addr && !inita_is_rpa) { - connsm->inita_identity_used = 1; - } + rxbuf = rxpdu->om_data; + csa = rxbuf[0] & BLE_ADV_PDU_HDR_CHSEL_MASK; - CONN_F_CONN_REQ_TXD(connsm) = 1; + ble_ll_conn_master_start(BLE_PHY_1M, csa, addrd, targeta); +} #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - if (ble_hdr->rxinfo.channel < BLE_PHY_NUM_DATA_CHANS) { - /* Lets wait for AUX_CONNECT_RSP */ - CONN_F_AUX_CONN_REQ(connsm) = 1; - /* Keep aux data until we get scan response */ - scansm->cur_aux_data = ble_hdr->rxinfo.user_data; - ble_hdr->rxinfo.user_data = NULL; - STATS_INC(ble_ll_stats, aux_conn_req_tx); - } - - if (connsm->scansm->ext_scanning) { - phy = ble_hdr->rxinfo.phy; - - /* Update connection state machine with appropriate parameters for - * certain PHY - */ - ble_ll_conn_ext_set_params(connsm, - &connsm->initial_params.params[phy - 1], - phy); - - } +void +ble_ll_conn_created_on_aux(struct os_mbuf *rxpdu, + struct ble_ll_scan_addr_data *addrd, + uint8_t *targeta) +{ +#if BLE_LL_BT5_PHY_SUPPORTED + struct ble_mbuf_hdr *rxhdr; #endif + uint8_t phy; - STATS_INC(ble_ll_conn_stats, conn_req_txd); - -init_rx_isr_exit: - - /* - * We have to restart receive if we cant hand up pdu. We return 0 so that - * the phy does not get disabled. - */ - rxpdu = ble_ll_rxpdu_alloc(pyld_len + BLE_LL_PDU_HDR_LEN); - if (rxpdu == NULL) { - /* - * XXX: possible allocate the PDU when we start initiating? - * I cannot say I like this solution, but if we cannot allocate a PDU - * to hand up to the LL, we need to remove the connection we just - * scheduled since the connection state machine will not get processed - * by link layer properly. For now, just remove it from the scheduler - */ - if (CONN_F_CONN_REQ_TXD(connsm) == 1) { - CONN_F_CONN_REQ_TXD(connsm) = 0; - CONN_F_AUX_CONN_REQ(connsm) = 0; - ble_ll_sched_rmv_elem(&connsm->conn_sch); - } - ble_phy_restart_rx(); - rc = 0; - } else { - ble_phy_rxpdu_copy(rxbuf, rxpdu); - ble_ll_rx_pdu_in(rxpdu); - } - - if (rc) { - ble_ll_state_set(BLE_LL_STATE_STANDBY); - } +#if BLE_LL_BT5_PHY_SUPPORTED + rxhdr = BLE_MBUF_HDR_PTR(rxpdu); + phy = rxhdr->rxinfo.phy; +#else + phy = BLE_PHY_1M; +#endif - return rc; + ble_ll_conn_master_start(phy, 1, addrd, targeta); } +#endif /* BLE_LL_CFG_FEAT_LL_EXT_ADV */ /** * Function called when a timeout has occurred for a connection. There are diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index fe384c4147..e53918f96c 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -179,13 +179,12 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, memcpy(enh_ev->local_rpa, rpa, BLE_DEV_ADDR_LEN); } - /* We need to adjust peer type if device connected using RPA - * and was resolved since RPA needs to be added to HCI event. - */ - if (connsm->peer_addr_type < BLE_HCI_CONN_PEER_ADDR_PUBLIC_IDENT - && (connsm->rpa_index > -1)) { +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + /* Adjust address type if peer address was resolved */ + if (connsm->peer_addr_resolved) { enh_ev->peer_addr_type += 2; } +#endif if (enh_ev->peer_addr_type > BLE_HCI_CONN_PEER_ADDR_RANDOM) { if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { @@ -220,10 +219,6 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, ev->conn_handle = htole16(connsm->conn_handle); ev->role = connsm->conn_role - 1; ev->peer_addr_type = connsm->peer_addr_type; - - if (ev->peer_addr_type > BLE_HCI_CONN_PEER_ADDR_RANDOM) { - ev->peer_addr_type -= 2; - } memcpy(ev->peer_addr, connsm->peer_addr, BLE_DEV_ADDR_LEN); ev->conn_itvl = htole16(connsm->conn_itvl); ev->conn_latency = htole16(connsm->slave_latency); @@ -520,7 +515,7 @@ ble_ll_conn_create(const uint8_t *cmdbuf, uint8_t len) /* CSA will be selected when advertising is received */ /* Start scanning */ - rc = ble_ll_scan_initiator_start(&hcc, &connsm->scansm); + rc = ble_ll_scan_initiator_start(&hcc, connsm); if (rc) { SLIST_REMOVE(&g_ble_ll_conn_active_list,connsm,ble_ll_conn_sm,act_sle); STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe); @@ -777,10 +772,8 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len) ble_ll_conn_ext_master_init(connsm, &hcc); ble_ll_conn_sm_new(connsm); - /* CSA will be selected when advertising is received */ - /* Start scanning */ - rc = ble_ll_scan_ext_initiator_start(&hcc, &connsm->scansm); + rc = ble_ll_scan_ext_initiator_start(&hcc, connsm); if (rc) { SLIST_REMOVE(&g_ble_ll_conn_active_list,connsm,ble_ll_conn_sm,act_sle); STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe); diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index 915a4d2a62..099ce77f50 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -148,18 +148,10 @@ void ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t len); int ble_ll_conn_rx_isr_start(struct ble_mbuf_hdr *rxhdr, uint32_t aa); int ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr); void ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr); -void ble_ll_init_rx_pkt_in(uint8_t pdu_type, uint8_t *rxbuf, - struct ble_mbuf_hdr *ble_hdr); -int ble_ll_init_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *ble_hdr); -int ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok, - struct ble_mbuf_hdr *ble_hdr); void ble_ll_conn_wfr_timer_exp(void); -void ble_ll_conn_init_wfr_timer_exp(void); int ble_ll_conn_is_lru(struct ble_ll_conn_sm *s1, struct ble_ll_conn_sm *s2); uint32_t ble_ll_conn_get_ce_end_time(void); void ble_ll_conn_event_halt(void); -void ble_ll_conn_reset_pending_aux_conn_rsp(void); -bool ble_ll_conn_init_pending_aux_conn_rsp(void); /* HCI */ void ble_ll_disconn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t reason); diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 9ce7877b10..0d9d36f666 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -25,7 +25,6 @@ #include "os/os.h" #include "os/os_cputime.h" #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" @@ -129,122 +128,9 @@ static struct os_mempool g_scan_dup_pool; static TAILQ_HEAD(ble_ll_scan_dup_list, ble_ll_scan_dup_entry) g_scan_dup_list; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -#if MYNEWT_VAL(BLE_LL_EXT_ADV_AUX_PTR_CNT) != 0 -static os_membuf_t ext_scan_aux_mem[ OS_MEMPOOL_SIZE( - MYNEWT_VAL(BLE_LL_EXT_ADV_AUX_PTR_CNT), - sizeof (struct ble_ll_aux_data)) -]; -#else -#define ext_scan_aux_mem NULL -#endif - -static struct os_mempool ext_scan_aux_pool; - -static int ble_ll_scan_start(struct ble_ll_scan_sm *scansm, - struct ble_ll_sched_item *sch); - -static void -ble_ll_aux_scan_drop_event_cb(struct ble_npl_event *ev) -{ - struct ble_ll_aux_data *aux_data = ble_npl_event_get_arg(ev); - - ble_ll_scan_end_adv_evt(aux_data); - ble_ll_scan_aux_data_unref(aux_data); -} - -static void -ble_ll_aux_scan_drop(struct ble_ll_aux_data *aux_data) -{ - BLE_LL_ASSERT(aux_data); - - STATS_INC(ble_ll_stats, aux_scan_drop); - - ble_npl_event_init(&aux_data->ev, ble_ll_aux_scan_drop_event_cb, aux_data); - ble_ll_event_send(&aux_data->ev); -} - -static int -ble_ll_aux_scan_cb(struct ble_ll_sched_item *sch) -{ - struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; - uint8_t lls = ble_ll_state_get(); - uint32_t wfr_usec; - - STATS_INC(ble_ll_stats, aux_sched_cb); - - /* Drop the scheduled item if scan was disable or there is aux or scan - * response pending - */ - if (!scansm->scan_enabled || scansm->cur_aux_data || - scansm->scan_rsp_pending) { - ble_ll_aux_scan_drop(sch->cb_arg); - sch->cb_arg = NULL; - goto done; - } - - /* Check if there is no aux connect sent. If so drop the sched item */ - if (lls == BLE_LL_STATE_INITIATING && ble_ll_conn_init_pending_aux_conn_rsp()) { - ble_ll_aux_scan_drop(sch->cb_arg); - sch->cb_arg = NULL; - goto done; - } - - /* This function is called only when scanner is running. This can happen - * in 3 states: - * BLE_LL_STATE_SCANNING - * BLE_LL_STATE_INITIATING - * BLE_LL_STATE_STANDBY - */ - if (lls != BLE_LL_STATE_STANDBY) { - ble_phy_disable(); - ble_ll_state_set(BLE_LL_STATE_STANDBY); - } - - /* When doing RX for AUX pkt, cur_aux_data keeps valid aux data */ - scansm->cur_aux_data = sch->cb_arg; - sch->cb_arg = NULL; - BLE_LL_ASSERT(scansm->cur_aux_data != NULL); - scansm->cur_aux_data->scanning = 1; - - if (ble_ll_scan_start(scansm, sch)) { - ble_ll_scan_interrupted(scansm); - goto done; - } - - STATS_INC(ble_ll_stats, aux_fired_for_read); - - wfr_usec = scansm->cur_aux_data->offset_units ? 300 : 30; - ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_RX, 0, wfr_usec); - -done: - - return BLE_LL_SCHED_STATE_DONE; -} - static int -ble_ll_scan_ext_adv_init(struct ble_ll_aux_data **aux_data) -{ - struct ble_ll_aux_data *e; - - e = os_memblock_get(&ext_scan_aux_pool); - if (!e) { - return -1; - } - - memset(e, 0, sizeof(*e)); - e->sch.sched_cb = ble_ll_aux_scan_cb; - e->sch.sched_type = BLE_LL_SCHED_TYPE_AUX_SCAN; - e->ref_cnt = 1; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - e->rpa_index = -1; -#endif - ble_ll_trace_u32x2(BLE_LL_TRACE_ID_AUX_REF, (uint32_t)e, e->ref_cnt); - - *aux_data = e; - STATS_INC(ble_ll_stats, aux_allocated); +ble_ll_scan_start(struct ble_ll_scan_sm *scansm); - return 0; -} #endif static inline uint32_t @@ -481,28 +367,11 @@ ble_ll_scan_end_adv_evt(struct ble_ll_aux_data *aux_data) } #endif -static void -ble_ll_scan_clean_cur_aux_data(void) -{ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; - - /* If scanner was reading aux ptr, we need to clean it up */ - if (scansm->cur_aux_data) { - ble_ll_scan_end_adv_evt(scansm->cur_aux_data); - ble_ll_scan_aux_data_unref(scansm->cur_aux_data); - scansm->cur_aux_data = NULL; - } -#endif -} - void ble_ll_scan_halt(void) { struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; - ble_ll_scan_clean_cur_aux_data(); - /* Update backoff if we failed to receive scan response */ if (scansm->scan_rsp_pending) { scansm->scan_rsp_pending = 0; @@ -859,27 +728,6 @@ goto done; } } -static void -ble_ll_get_chan_to_scan(struct ble_ll_scan_sm *scansm, uint8_t *chan, - int *phy) -{ - struct ble_ll_scan_phy *scanp = scansm->scanp; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - struct ble_ll_aux_data *aux_data = scansm->cur_aux_data; - - if (!scansm->ext_scanning || !aux_data || !aux_data->scanning) { - *chan = scanp->scan_chan; - *phy = scanp->phy; - return; - } - - *chan = aux_data->chan; - *phy = aux_data->aux_phy; -#else - *chan = scanp->scan_chan; - *phy = scanp->phy; -#endif -} /** * Called to enable the receiver for scanning. * @@ -890,29 +738,21 @@ ble_ll_get_chan_to_scan(struct ble_ll_scan_sm *scansm, uint8_t *chan, * @return int */ static int -ble_ll_scan_start(struct ble_ll_scan_sm *scansm, struct ble_ll_sched_item *sch) +ble_ll_scan_start(struct ble_ll_scan_sm *scansm) { int rc; struct ble_ll_scan_phy *scanp = scansm->scanp; - uint8_t scan_chan; + uint8_t chan; #if (BLE_LL_BT5_PHY_SUPPORTED == 1) uint8_t phy_mode; -#endif int phy; +#endif BLE_LL_ASSERT(scansm->scan_rsp_pending == 0); - ble_ll_get_chan_to_scan(scansm, &scan_chan, &phy); - - /* XXX: right now scheduled item is only present if we schedule for aux - * scan just make sanity check that we have proper combination of - * sch and resulting scan_chan - */ - BLE_LL_ASSERT(!sch || scan_chan < BLE_PHY_ADV_CHAN_START); - BLE_LL_ASSERT(sch || scan_chan >= BLE_PHY_ADV_CHAN_START); - /* Set channel */ - rc = ble_phy_setchan(scan_chan, BLE_ACCESS_ADDR_ADV, BLE_LL_CRCINIT_ADV); + chan = scanp->scan_chan; + rc = ble_phy_setchan(chan, BLE_ACCESS_ADDR_ADV, BLE_LL_CRCINIT_ADV); BLE_LL_ASSERT(rc == 0); /* @@ -934,20 +774,13 @@ ble_ll_scan_start(struct ble_ll_scan_sm *scansm, struct ble_ll_sched_item *sch) #endif #if (BLE_LL_BT5_PHY_SUPPORTED == 1) + phy = scanp->phy; phy_mode = ble_ll_phy_to_phy_mode(phy, BLE_HCI_LE_PHY_CODED_ANY); ble_phy_mode_set(phy_mode, phy_mode); #endif - /* XXX: probably need to make sure hfxo is running too */ - /* XXX: can make this better; want to just start asap. */ - if (sch) { - rc = ble_phy_rx_set_start_time(sch->start_time + - g_ble_ll_sched_offset_ticks, - sch->remainder); - } else { - rc = ble_phy_rx_set_start_time(os_cputime_get32() + - g_ble_ll_sched_offset_ticks, 0); - } + rc = ble_phy_rx_set_start_time(os_cputime_get32() + + g_ble_ll_sched_offset_ticks, 0); if (!rc || rc == BLE_PHY_ERR_RX_LATE) { /* If we are late here, it is still OK because we keep scanning. * Clear error @@ -961,12 +794,7 @@ ble_ll_scan_start(struct ble_ll_scan_sm *scansm, struct ble_ll_sched_item *sch) ble_ll_whitelist_disable(); } - /* Set link layer state to scanning */ - if (scanp->scan_type == BLE_SCAN_TYPE_INITIATE) { - ble_ll_state_set(BLE_LL_STATE_INITIATING); - } else { - ble_ll_state_set(BLE_LL_STATE_SCANNING); - } + ble_ll_state_set(BLE_LL_STATE_SCANNING); } return rc; @@ -1020,76 +848,6 @@ ble_ll_scan_is_inside_window(struct ble_ll_scan_phy *scanp, uint32_t time) CPUTIME_LT(time, start_time + scanp->timing.window); } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -static void -ble_ll_scan_aux_data_free(struct ble_ll_aux_data *aux_data) -{ - if (aux_data) { - if (aux_data->evt) { - ble_hci_trans_buf_free((uint8_t *)aux_data->evt); - aux_data->evt = NULL; - } - os_memblock_put(&ext_scan_aux_pool, aux_data); - STATS_INC(ble_ll_stats, aux_freed); - } -} - -struct ble_ll_aux_data * -ble_ll_scan_aux_data_ref(struct ble_ll_aux_data *aux_data) -{ - os_sr_t sr; - - BLE_LL_ASSERT(aux_data); - - OS_ENTER_CRITICAL(sr); - aux_data->ref_cnt++; - ble_ll_trace_u32x2(BLE_LL_TRACE_ID_AUX_REF, (uint32_t) aux_data, aux_data->ref_cnt); - - OS_EXIT_CRITICAL(sr); - - return aux_data; -} - -void -ble_ll_scan_aux_data_unref(struct ble_ll_aux_data *aux_data) -{ - os_sr_t sr; - - BLE_LL_ASSERT(aux_data); - - OS_ENTER_CRITICAL(sr); - aux_data->ref_cnt--; - ble_ll_trace_u32x2(BLE_LL_TRACE_ID_AUX_UNREF, (uint32_t) aux_data, aux_data->ref_cnt); - - if (aux_data->ref_cnt == 0) { - /* - * Some validation to make sure that we completed scan properly: - * - we either did not send any report or sent completed/truncated - * - we only sent one of completed/truncated - * - in case of error, we wither did not send anything or sent truncated - */ - BLE_LL_ASSERT(!(aux_data->flags_ll & BLE_LL_AUX_FLAG_HCI_SENT_ANY) || - ((aux_data->flags_ll & BLE_LL_AUX_FLAG_HCI_SENT_ANY) && - (aux_data->flags_ll & (BLE_LL_AUX_FLAG_HCI_SENT_COMPLETED | BLE_LL_AUX_FLAG_HCI_SENT_TRUNCATED)))); - BLE_LL_ASSERT(!(aux_data->flags_ll & BLE_LL_AUX_FLAG_HCI_SENT_COMPLETED) || !(aux_data->flags_ll & BLE_LL_AUX_FLAG_HCI_SENT_TRUNCATED)); - BLE_LL_ASSERT(!(aux_data->flags_ll & BLE_LL_AUX_FLAG_SCAN_ERROR) || - !(aux_data->flags_ll & BLE_LL_AUX_FLAG_HCI_SENT_ANY) || - (aux_data->flags_ll & BLE_LL_AUX_FLAG_HCI_SENT_TRUNCATED)); - - ble_ll_scan_aux_data_free(aux_data); - } - - OS_EXIT_CRITICAL(sr); -} - -static void -ble_ll_scan_sched_remove(struct ble_ll_sched_item *sch) -{ - ble_ll_scan_end_adv_evt(sch->cb_arg); - ble_ll_scan_aux_data_unref(sch->cb_arg); - sch->cb_arg = NULL; -} -#endif /** * Stop the scanning state machine */ @@ -1109,8 +867,7 @@ ble_ll_scan_sm_stop(int chk_disable) OS_ENTER_CRITICAL(sr); lls = ble_ll_state_get(); - if ((lls == BLE_LL_STATE_SCANNING) || - (lls == BLE_LL_STATE_INITIATING && chk_disable == 1)) { + if (lls == BLE_LL_STATE_SCANNING) { /* Disable phy */ ble_phy_disable(); @@ -1122,6 +879,8 @@ ble_ll_scan_sm_stop(int chk_disable) OS_ENTER_CRITICAL(sr); + scansm->connsm = NULL; + /* Disable scanning state machine */ scansm->scan_enabled = 0; scansm->restart_timer_needed = 0; @@ -1129,8 +888,6 @@ ble_ll_scan_sm_stop(int chk_disable) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (scansm->ext_scanning) { ble_ll_sched_rmv_elem_type(BLE_LL_SCHED_TYPE_SCAN_AUX, ble_ll_scan_aux_sched_remove); - ble_ll_scan_clean_cur_aux_data(); - ble_ll_sched_rmv_elem_type(BLE_LL_SCHED_TYPE_AUX_SCAN, ble_ll_scan_sched_remove); scansm->ext_scanning = 0; } #endif @@ -1209,45 +966,15 @@ ble_ll_scan_sm_start(struct ble_ll_scan_sm *scansm) return BLE_ERR_SUCCESS; } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -static void -ble_ll_aux_scan_rsp_failed(struct ble_ll_scan_sm *scansm) -{ - if (!scansm->cur_aux_data) { - return; - } - - STATS_INC(ble_ll_stats, aux_scan_rsp_err); - ble_ll_scan_interrupted(scansm); -} -#endif - static void ble_ll_scan_interrupted_event_cb(struct ble_npl_event *ev) { struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - struct ble_ll_aux_data *aux_data; -#endif if (!scansm->scan_enabled) { return; } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - aux_data = ble_npl_event_get_arg(ev); - - if (aux_data) { - if (scansm->scan_rsp_pending) { - STATS_INC(ble_ll_stats, aux_scan_rsp_err); - } - ble_ll_scan_end_adv_evt(aux_data); - ble_ll_scan_aux_data_unref(aux_data); - ble_npl_event_set_arg(ev, NULL); - STATS_INC(ble_ll_stats, aux_missed_adv); - } -#endif - /* * If we timed out waiting for a response, the scan response pending * flag should be set. Deal with scan backoff. Put device back into rx. @@ -1301,7 +1028,7 @@ ble_ll_scan_event_proc(struct ble_npl_event *ev) return; } - if (scansm->cur_aux_data || scansm->scan_rsp_pending) { + if (scansm->scan_rsp_pending) { /* Aux scan in progress. Wait */ STATS_INC(ble_ll_stats, scan_timer_stopped); scansm->restart_timer_needed = 1; @@ -1366,15 +1093,6 @@ ble_ll_scan_event_proc(struct ble_npl_event *ev) case BLE_LL_STATE_SCAN_AUX: start_scan = false; break; - case BLE_LL_STATE_INITIATING: - /* Must disable PHY since we will move to a new channel */ - ble_phy_disable(); - if (!inside_window) { - ble_ll_state_set(BLE_LL_STATE_STANDBY); - } - /* PHY is disabled - make sure we do not wait for AUX_CONNECT_RSP */ - ble_ll_conn_reset_pending_aux_conn_rsp(); - break; case BLE_LL_STATE_SCANNING: /* Must disable PHY since we will move to a new channel */ ble_phy_disable(); @@ -1390,7 +1108,7 @@ ble_ll_scan_event_proc(struct ble_npl_event *ev) } if (start_scan) { - ble_ll_scan_start(scansm, NULL); + ble_ll_scan_start(scansm); } else { ble_ll_rfmgmt_release(); } @@ -1440,10 +1158,6 @@ ble_ll_scan_rx_isr_start(uint8_t pdu_type, uint16_t *rxflags) } #endif - if (scansm->cur_aux_data && !scansm->scan_rsp_pending ) { - STATS_INC(ble_ll_stats, aux_received); - } - /* * If this is the first PDU after we sent the scan response (as * denoted by the scan rsp pending flag), we set a bit in the ble @@ -1460,9 +1174,6 @@ ble_ll_scan_rx_isr_start(uint8_t pdu_type, uint16_t *rxflags) *rxflags |= BLE_MBUF_HDR_F_SCAN_RSP_RXD; } else { ble_ll_scan_req_backoff(scansm, 0); -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - ble_ll_aux_scan_rsp_failed(scansm); -#endif } } break; @@ -1473,326 +1184,24 @@ ble_ll_scan_rx_isr_start(uint8_t pdu_type, uint16_t *rxflags) } break; #endif - default: - break; - } - - return rc; -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -static uint8_t -ble_ll_ext_adv_phy_mode_to_local_phy(uint8_t adv_phy_mode) -{ - switch (adv_phy_mode) { - case 0x00: - return BLE_PHY_1M; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) - case 0x01: - return BLE_PHY_2M; -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - case 0x02: - return BLE_PHY_CODED; -#endif - } - - return 0; -} - -static int -ble_ll_ext_scan_parse_aux_ptr(struct ble_ll_aux_data *aux_data, uint8_t *buf) -{ - uint32_t aux_ptr_field = get_le32(buf) & 0x00FFFFFF; - - aux_data->chan = (aux_ptr_field) & 0x3F; - if (aux_data->chan >= BLE_PHY_NUM_DATA_CHANS) { - return -1; - } - - /* TODO use CA aux_ptr_field >> 6 */ - - aux_data->offset = 30 * ((aux_ptr_field >> 8) & 0x1FFF); - - if ((aux_ptr_field >> 7) & 0x01) { - aux_data->offset *= 10; - aux_data->offset_units = 1; - } - - if (aux_data->offset < BLE_LL_MAFS) { - return -1; - } - - aux_data->aux_phy = - ble_ll_ext_adv_phy_mode_to_local_phy((aux_ptr_field >> 21) & 0x07); - if (aux_data->aux_phy == 0) { - return -1; - } - - return 0; -} - -/** - * ble_ll_scan_update_aux_data - * - * Update aux_data stored in ble_hdr.rxinfo.user_data. If no aux_data is present - * (i.e. processing ADV_EXT_IND) this will try to allocate new aux_data. - * - * Context: Interrupt - * - * @param ble_hdr - * @param rxbuf - * - * @return int - * 1: do not scan for next AUX (no AuxPtr or malformed data) - * 0: scan for next AUX (valid AuxPtr found) - * -1: error - */ -int -ble_ll_scan_update_aux_data(struct ble_mbuf_hdr *ble_hdr, uint8_t *rxbuf, - bool *adva_present) -{ - uint8_t pdu_hdr; - uint8_t pdu_len; - uint8_t adv_mode; - uint8_t eh_len; - uint8_t eh_flags; - uint8_t *eh; - struct ble_ll_aux_data *aux_data; - bool is_aux; - - aux_data = ble_hdr->rxinfo.user_data; - /* aux_data is initially not set only for ADV_EXT_IND */ - is_aux = aux_data; - - pdu_hdr = rxbuf[0]; - pdu_len = rxbuf[1]; - - /* PDU without at least Extended Header Length is invalid */ - if (pdu_len == 0) { - return -1; - } - - adv_mode = rxbuf[2] >> 6; - eh_len = rxbuf[2] & 0x3f; - eh_flags = rxbuf[3]; - eh = &rxbuf[4]; - - /* - * PDU without Extended Header is valid in case of last AUX_CHAIN_IND in - * chain so aux_data has to be set and advertising mode has to be 00b, - * otherwise it's an invalid PDU. - */ - if (eh_len == 0) { - if (!aux_data || adv_mode) { - return -1; - } - aux_data->flags_isr |= BLE_LL_AUX_FLAG_SCAN_COMPLETE; - return 1; - } - - /* - * If aux_data is not set, this is ADV_EXT_IND which starts new extended - * advertising event. - */ - if (!aux_data) { - if (ble_ll_scan_ext_adv_init(&aux_data)) { - return -1; - } - - aux_data->aux_primary_phy = ble_hdr->rxinfo.phy; - } else { - if (aux_data->flags_isr & BLE_LL_AUX_FLAG_AUX_ADV_RECEIVED) { - aux_data->flags_isr |= BLE_LL_AUX_FLAG_AUX_CHAIN_RECEIVED; - } else { - aux_data->flags_isr |= BLE_LL_AUX_FLAG_AUX_ADV_RECEIVED; - } - } - - /* Now parse extended header... */ - - if (eh_flags & (1 << BLE_LL_EXT_ADV_ADVA_BIT)) { - aux_data->flags |= BLE_LL_AUX_HAS_ADVA; - memcpy(aux_data->adva, eh, 6); - aux_data->adva_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_TXADD_MASK); - eh += BLE_LL_EXT_ADV_ADVA_SIZE; - - if (adva_present) { - *adva_present = true; - } - } else if (adva_present) { - *adva_present = false; - } - - if (eh_flags & (1 << BLE_LL_EXT_ADV_TARGETA_BIT)) { - aux_data->flags |= BLE_LL_AUX_HAS_TARGETA; - memcpy(aux_data->targeta, eh, 6); - aux_data->targeta_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_RXADD_MASK); - eh += BLE_LL_EXT_ADV_TARGETA_SIZE; - } - - - if (eh_flags & (1 << BLE_LL_EXT_ADV_CTE_INFO_BIT)) { - eh += 1; - } - - if (eh_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) { - aux_data->flags |= BLE_LL_AUX_HAS_ADI; - if (is_aux) { - if (get_le16(eh) != aux_data->adi) { - aux_data->flags_isr |= BLE_LL_AUX_FLAG_SCAN_ERROR; - STATS_INC(ble_ll_stats, aux_chain_err); - } - } else { - aux_data->adi = get_le16(eh); - } - eh += BLE_LL_EXT_ADV_DATA_INFO_SIZE; - } - - if (eh_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { - if (ble_ll_ext_scan_parse_aux_ptr(aux_data, eh)) { - aux_data->flags_isr |= BLE_LL_AUX_FLAG_SCAN_ERROR; - } - } else if (!(adv_mode & BLE_LL_EXT_ADV_MODE_SCAN)) { - /* No AuxPtr for scannable PDU is ignored since we can still scan it */ - aux_data->flags_isr |= BLE_LL_AUX_FLAG_SCAN_COMPLETE; - } - - ble_hdr->rxinfo.user_data = aux_data; - - /* Do not scan for next AUX if either no AuxPtr or malformed data found */ - return !(eh_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) || - (aux_data->flags_isr & BLE_LL_AUX_FLAG_SCAN_ERROR); -} - -static int -ble_ll_scan_get_addr_from_ext_adv(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr, - uint8_t **addr, uint8_t *addr_type, - uint8_t **inita, uint8_t *inita_type, - int *ext_mode) -{ - uint8_t pdu_len; - uint8_t ext_hdr_len; - uint8_t ext_hdr_flags; - uint8_t *ext_hdr; - bool has_adva = false; - bool has_inita = false; - int i; - struct ble_ll_aux_data *aux_data = ble_hdr->rxinfo.user_data; - - *addr = NULL; - *inita = NULL; - - pdu_len = rxbuf[1]; - if (pdu_len == 0) { - return -1; - } - - *ext_mode = rxbuf[2] >> 6; - if (*ext_mode > BLE_LL_EXT_ADV_MODE_SCAN) { - return -1; - } - - ext_hdr_len = rxbuf[2] & 0x3F; - if (ext_hdr_len == 0) { - goto done; - } - - ext_hdr_flags = rxbuf[3]; - ext_hdr = &rxbuf[4]; - - i = 0; - if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_ADVA_BIT)) { - if (ext_hdr_len < BLE_LL_EXT_ADV_ADVA_SIZE) { - return -1; - } - - *addr = ext_hdr + i; - *addr_type = - ble_ll_get_addr_type(rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK); - i += BLE_LL_EXT_ADV_ADVA_SIZE; - - has_adva = true; - } - - if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_TARGETA_BIT)) { - *inita = ext_hdr + i; - *inita_type = - ble_ll_get_addr_type(rxbuf[0] & BLE_ADV_PDU_HDR_RXADD_MASK); - i += BLE_LL_EXT_ADV_TARGETA_SIZE; - - has_inita = true; - } - -done: - /* Check if we had address already. If yes, replace it with new one */ - - if (aux_data) { - /* If address has been provided, we do have it already in aux_data.*/ - if (aux_data->flags & BLE_LL_AUX_HAS_ADVA) { - if (!has_adva) { - *addr = aux_data->adva; - *addr_type = aux_data->adva_type; - } else { - memcpy(aux_data->adva, *addr, 6); - aux_data->adva_type = *addr_type; - } + case BLE_SCAN_TYPE_INITIATE: + if ((pdu_type == BLE_ADV_PDU_TYPE_ADV_IND) || + (pdu_type == BLE_ADV_PDU_TYPE_ADV_DIRECT_IND)) { + rc = 1; } - if (aux_data->flags & BLE_LL_AUX_HAS_TARGETA) { - if (!has_inita) { - *inita = aux_data->targeta; - *inita_type = aux_data->targeta_type; - } else { - memcpy(aux_data->targeta, *inita, 6); - aux_data->targeta_type = *inita_type; - } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + if ((pdu_type == BLE_ADV_PDU_TYPE_ADV_EXT_IND && scansm->ext_scanning)) { + *rxflags |= BLE_MBUF_HDR_F_EXT_ADV; + rc = 1; } - } - - return 0; -} #endif - -int -ble_ll_scan_adv_decode_addr(uint8_t pdu_type, uint8_t *rxbuf, - struct ble_mbuf_hdr *ble_hdr, - uint8_t **addr, uint8_t *addr_type, - uint8_t **inita, uint8_t *inita_type, - int *ext_mode) -{ - /* - * XXX this should be only used for legacy advertising, but need to refactor - * code in ble_ll_init first so it does not call this for ext - */ - - if (pdu_type != BLE_ADV_PDU_TYPE_ADV_EXT_IND && - pdu_type != BLE_ADV_PDU_TYPE_AUX_CONNECT_RSP) { - /* Legacy advertising */ - *addr_type = ble_ll_get_addr_type(rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK); - *addr = rxbuf + BLE_LL_PDU_HDR_LEN; - - if (pdu_type != BLE_ADV_PDU_TYPE_ADV_DIRECT_IND) { - *inita = NULL; - *inita_type = 0; - return 0; - } - - *inita = rxbuf + BLE_LL_PDU_HDR_LEN + BLE_DEV_ADDR_LEN; - *inita_type = ble_ll_get_addr_type(rxbuf[0] & BLE_ADV_PDU_HDR_RXADD_MASK); - - return 0; + break; + default: + break; } - /* Extended advertising */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - return ble_ll_scan_get_addr_from_ext_adv(rxbuf, ble_hdr, addr, addr_type, - inita, inita_type, ext_mode); -#else - return -1; -#endif - - return 0; + return rc; } static void @@ -1918,11 +1327,12 @@ ble_ll_scan_rx_filter(uint8_t own_addr_type, uint8_t scan_filt_policy, resolved = false; #endif - /* Check on WL if required by scan filter policy */ - if ((scan_filt_policy & 0x01) && - !ble_ll_whitelist_match(addrd->adv_addr, addrd->adv_addr_type, - resolved)) { + if (scan_filt_policy & 0x01) { + /* Check on WL if required by scan filter policy */ + if (!ble_ll_whitelist_match(addrd->adv_addr, addrd->adv_addr_type, + resolved)) { return -2; + } } if (scan_ok) { @@ -1932,10 +1342,33 @@ ble_ll_scan_rx_filter(uint8_t own_addr_type, uint8_t scan_filt_policy, return 0; } +int +ble_ll_scan_rx_check_init(struct ble_ll_scan_addr_data *addrd) +{ + struct ble_ll_scan_sm *scansm; + struct ble_ll_conn_sm *connsm; + + scansm = &g_ble_ll_scan_sm; + connsm = scansm->connsm; + BLE_LL_ASSERT(connsm); + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + if ((connsm->peer_addr_type > BLE_ADDR_RANDOM) && !addrd->adva_resolved) { + return -1; + } +#endif + if ((addrd->adv_addr_type != (connsm->peer_addr_type & 0x01)) || + memcmp(addrd->adv_addr, connsm->peer_addr, 6) != 0) { + return -1; + } + + return 0; +} + static int -ble_ll_scan_rx_isr_on_adv(uint8_t pdu_type, uint8_t *rxbuf, - struct ble_mbuf_hdr *hdr, - struct ble_ll_scan_addr_data *addrd) +ble_ll_scan_rx_isr_end_on_adv(uint8_t pdu_type, uint8_t *rxbuf, + struct ble_mbuf_hdr *hdr, + struct ble_ll_scan_addr_data *addrd) { struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; struct ble_ll_scan_phy *scanp = scansm->scanp; @@ -1949,12 +1382,20 @@ ble_ll_scan_rx_isr_on_adv(uint8_t pdu_type, uint8_t *rxbuf, addrd->rpa_index = ble_hw_resolv_list_match(); #endif - rc = ble_ll_scan_rx_filter(scansm->own_addr_type, scansm->scan_filt_policy, - addrd, &scan_ok); + rc = ble_ll_scan_rx_filter(scansm->own_addr_type, + scansm->scan_filt_policy, addrd, &scan_ok); if (rc < 0) { return 0; } + if ((scanp->scan_type == BLE_SCAN_TYPE_INITIATE) && + !(scansm->scan_filt_policy & 0x01)) { + rc = ble_ll_scan_rx_check_init(addrd); + if (rc < 0) { + return 0; + } + } + rxinfo->flags |= BLE_MBUF_HDR_F_DEVMATCH; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) rxinfo->rpa_index = addrd->rpa_index; @@ -1971,15 +1412,19 @@ ble_ll_scan_rx_isr_on_adv(uint8_t pdu_type, uint8_t *rxbuf, return 0; } - return (scanp->scan_type == BLE_SCAN_TYPE_ACTIVE) && + /* Allow responding to all PDUs when initiating since unwanted PDUs were + * already filtered out in isr_start. + */ + return ((scanp->scan_type == BLE_SCAN_TYPE_ACTIVE) && ((pdu_type == BLE_ADV_PDU_TYPE_ADV_IND) || - (pdu_type == BLE_ADV_PDU_TYPE_ADV_SCAN_IND)); + (pdu_type == BLE_ADV_PDU_TYPE_ADV_SCAN_IND))) || + (scanp->scan_type == BLE_SCAN_TYPE_INITIATE); } static int -ble_ll_scan_rx_isr_on_scan_rsp(uint8_t pdu_type, uint8_t *rxbuf, - struct ble_mbuf_hdr *hdr, - struct ble_ll_scan_addr_data *addrd) +ble_ll_scan_rx_isr_end_on_scan_rsp(uint8_t pdu_type, uint8_t *rxbuf, + struct ble_mbuf_hdr *hdr, + struct ble_ll_scan_addr_data *addrd) { struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; struct ble_mbuf_hdr_rxinfo *rxinfo = &hdr->rxinfo; @@ -2119,10 +1564,10 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) case BLE_ADV_PDU_TYPE_ADV_DIRECT_IND: case BLE_ADV_PDU_TYPE_ADV_NONCONN_IND: case BLE_ADV_PDU_TYPE_ADV_SCAN_IND: - rc = ble_ll_scan_rx_isr_on_adv(pdu_type, rxbuf, hdr, &addrd); + rc = ble_ll_scan_rx_isr_end_on_adv(pdu_type, rxbuf, hdr, &addrd); break; case BLE_ADV_PDU_TYPE_SCAN_RSP: - rc = ble_ll_scan_rx_isr_on_scan_rsp(pdu_type, rxbuf, hdr, &addrd); + rc = ble_ll_scan_rx_isr_end_on_scan_rsp(pdu_type, rxbuf, hdr, &addrd); break; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) case BLE_ADV_PDU_TYPE_ADV_EXT_IND: @@ -2144,10 +1589,22 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) if (rc == -1) { goto scan_rx_isr_ignore; - } else if (rc == 1) { - if (ble_ll_scan_send_scan_req(pdu_type, rxbuf, hdr, &addrd)) { - /* Keep PHY active and LL in scanning state */ - return 0; + } + + if (rc == 1) { + switch (scansm->scanp->scan_type) { + case BLE_SCAN_TYPE_ACTIVE: + if (ble_ll_scan_send_scan_req(pdu_type, rxbuf, hdr, &addrd)) { + /* Keep PHY active and LL in scanning state */ + return 0; + } + break; + case BLE_SCAN_TYPE_INITIATE: + if (ble_ll_conn_send_connect_req(rxpdu, &addrd, 0) == 0) { + hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CONNECT_IND_TXD; + return 0; + } + break; } } @@ -2193,7 +1650,7 @@ ble_ll_scan_chk_resume(void) if (ble_ll_state_get() == BLE_LL_STATE_STANDBY && ble_ll_scan_is_inside_window(scansm->scanp, now)) { /* Turn on the receiver and set state */ - ble_ll_scan_start(scansm, NULL); + ble_ll_scan_start(scansm); } OS_EXIT_CRITICAL(sr); } @@ -2219,11 +1676,6 @@ ble_ll_scan_timer_cb(void *arg) void ble_ll_scan_interrupted(struct ble_ll_scan_sm *scansm) { -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - ble_npl_event_set_arg(&scansm->scan_interrupted_ev, scansm->cur_aux_data); - scansm->cur_aux_data = NULL; -#endif - ble_ll_event_send(&scansm->scan_interrupted_ev); } @@ -2236,16 +1688,7 @@ ble_ll_scan_interrupted(struct ble_ll_scan_sm *scansm) void ble_ll_scan_wfr_timer_exp(void) { - struct ble_ll_scan_sm *scansm; - uint8_t chan; - int phy; - int rc; -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - uint8_t phy_mode; -#endif - uint32_t now; - - scansm = &g_ble_ll_scan_sm; + struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; /* Update backoff if we failed to receive scan response */ if (scansm->scan_rsp_pending) { @@ -2253,34 +1696,6 @@ ble_ll_scan_wfr_timer_exp(void) ble_ll_scan_req_backoff(scansm, 0); } - if (scansm->cur_aux_data) { - /* We actually care about interrupted scan only for EXT ADV because only - * then we might consider to send truncated event to the host. - */ - ble_ll_scan_interrupted(scansm); - - /* Need to disable phy since we are going to move to BLE_LL_STATE_STANDBY - * or we will need to change channel to primary one - */ - ble_phy_disable(); - - now = os_cputime_get32(); - if (!ble_ll_scan_is_inside_window(scansm->scanp, now)) { - /* Outside the window scan */ - ble_ll_state_set(BLE_LL_STATE_STANDBY); - return; - } - - ble_ll_get_chan_to_scan(scansm, &chan, &phy); -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - phy_mode = ble_ll_phy_to_phy_mode(phy, BLE_HCI_LE_PHY_CODED_ANY); - ble_phy_mode_set(phy_mode, phy_mode); -#endif - rc = ble_phy_setchan(chan, BLE_ACCESS_ADDR_ADV, BLE_LL_CRCINIT_ADV); - BLE_LL_ASSERT(rc == 0); - } - - ble_phy_restart_rx(); } @@ -2509,7 +1924,10 @@ ble_ll_scan_rx_pkt_in_on_legacy(uint8_t pdu_type, struct os_mbuf *om, void ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hdr) { + struct ble_mbuf_hdr_rxinfo *rxinfo; + struct ble_ll_scan_sm *scansm; struct ble_ll_scan_addr_data addrd; + uint8_t *targeta; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (ptype == BLE_ADV_PDU_TYPE_ADV_EXT_IND) { @@ -2519,7 +1937,26 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd } #endif - ble_ll_scan_rx_pkt_in_on_legacy(ptype, om, hdr, &addrd); + scansm = &g_ble_ll_scan_sm; + rxinfo = &hdr->rxinfo; + + if (scansm->scanp->scan_type == BLE_SCAN_TYPE_INITIATE) { + if (rxinfo->flags & BLE_MBUF_HDR_F_CONNECT_IND_TXD) { + /* We need to keep original TargetA in case it was resolved, so rl + * can be updated properly. + */ + ble_ll_scan_get_addr_data_from_legacy(ptype, om->om_data, &addrd); + targeta = addrd.targeta; + ble_ll_scan_rx_pkt_in_restore_addr_data(hdr, &addrd); + + ble_ll_scan_sm_stop(0); + ble_ll_conn_created_on_legacy(om, &addrd, targeta); + return; + } + } else { + ble_ll_scan_rx_pkt_in_on_legacy(ptype, om, hdr, &addrd); + } + ble_ll_scan_chk_resume(); } @@ -2975,7 +2412,7 @@ ble_ll_scan_can_chg_whitelist(void) int ble_ll_scan_initiator_start(struct hci_create_conn *hcc, - struct ble_ll_scan_sm **sm) + struct ble_ll_conn_sm *connsm) { struct ble_ll_scan_sm *scansm; struct ble_ll_scan_phy *scanp; @@ -2987,6 +2424,8 @@ ble_ll_scan_initiator_start(struct hci_create_conn *hcc, #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) scansm->ext_scanning = 0; #endif + scansm->connsm = connsm; + scansm->scanp = &scansm->scan_phys[PHY_UNCODED]; scansm->scanp_next = NULL; @@ -3002,15 +2441,6 @@ ble_ll_scan_initiator_start(struct hci_create_conn *hcc, #endif rc = ble_ll_scan_sm_start(scansm); - if (sm == NULL) { - return rc; - } - - if (rc == BLE_ERR_SUCCESS) { - *sm = scansm; - } else { - *sm = NULL; - } return rc; } @@ -3018,7 +2448,7 @@ ble_ll_scan_initiator_start(struct hci_create_conn *hcc, #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) int ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, - struct ble_ll_scan_sm **sm) + struct ble_ll_conn_sm *connsm) { struct ble_ll_scan_sm *scansm; struct ble_ll_scan_phy *scanp_uncoded; @@ -3032,6 +2462,7 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, scansm->scanp = NULL; scansm->scanp_next = NULL; scansm->ext_scanning = 1; + scansm->connsm = connsm; params = &hcc->params[0]; scanp_uncoded = &scansm->scan_phys[PHY_UNCODED]; @@ -3080,15 +2511,6 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, } rc = ble_ll_scan_sm_start(scansm); - if (sm == NULL) { - return rc; - } - - if (rc == BLE_ERR_SUCCESS) { - *sm = scansm; - } else { - *sm = NULL; - } return rc; } @@ -3155,13 +2577,6 @@ ble_ll_scan_get_pdu_data(void) return &g_ble_ll_scan_sm.pdu_data; } -/* Returns true if whitelist is enabled for scanning */ -int -ble_ll_scan_whitelist_enabled(void) -{ - return g_ble_ll_scan_sm.scan_filt_policy & 1; -} - static void ble_ll_scan_common_init(void) { @@ -3243,13 +2658,11 @@ ble_ll_scan_reset(void) os_mempool_clear(&g_scan_dup_pool); TAILQ_INIT(&g_scan_dup_list); -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - /* clear memory pool for AUX scan results */ - os_mempool_clear(&ext_scan_aux_pool); -#endif - /* Call the common init function again */ ble_ll_scan_common_init(); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + ble_ll_scan_aux_init(); +#endif } /** @@ -3263,15 +2676,6 @@ ble_ll_scan_init(void) { os_error_t err; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - err = os_mempool_init(&ext_scan_aux_pool, - MYNEWT_VAL(BLE_LL_EXT_ADV_AUX_PTR_CNT), - sizeof (struct ble_ll_aux_data), - ext_scan_aux_mem, - "ble_ll_aux_scan_pool"); - BLE_LL_ASSERT(err == 0); -#endif - err = os_mempool_init(&g_scan_dup_pool, MYNEWT_VAL(BLE_LL_NUM_SCAN_DUP_ADVS), sizeof(struct ble_ll_scan_dup_entry), diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 128b45a7cc..94f776df9b 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -50,6 +50,8 @@ #define BLE_LL_SCAN_AUX_F_HAS_ADI 0x0080 #define BLE_LL_SCAN_AUX_F_RESOLVED_ADVA 0x0100 #define BLE_LL_SCAN_AUX_F_RESOLVED_TARGETA 0x0200 +#define BLE_LL_SCAN_AUX_F_CONNECTABLE 0x0400 +#define BLE_LL_SCAN_AUX_F_W4_CONNECT_RSP 0x0800 #define BLE_LL_SCAN_AUX_H_SENT_ANY 0x01 #define BLE_LL_SCAN_AUX_H_DONE 0x02 @@ -668,6 +670,10 @@ ble_ll_scan_aux_break_ev(struct ble_npl_event *ev) void ble_ll_scan_aux_break(struct ble_ll_scan_aux_data *aux) { + if (aux->flags & BLE_LL_SCAN_AUX_F_W4_CONNECT_RSP) { + ble_ll_conn_send_connect_req_cancel(); + } + ble_npl_event_init(&aux->break_ev, ble_ll_scan_aux_break_ev, aux); ble_ll_event_send(&aux->break_ev); } @@ -751,18 +757,29 @@ ble_ll_scan_aux_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *rxhdr) { struct ble_ll_scan_aux_data *aux; + BLE_LL_ASSERT(aux_data_current); + aux = aux_data_current; + + if (aux->flags & BLE_LL_SCAN_AUX_F_W4_CONNECT_RSP) { + if (pdu_type != BLE_ADV_PDU_TYPE_AUX_CONNECT_RSP) { + aux_data_current = NULL; + ble_ll_scan_aux_break(aux); + return -1; + } + return 0; + } + if (pdu_type != BLE_ADV_PDU_TYPE_ADV_EXT_IND) { + aux_data_current = NULL; + ble_ll_scan_aux_break(aux); return -1; } - BLE_LL_ASSERT(aux_data_current); - aux = aux_data_current; - /* * Prepare TX transition when doing active scanning and receiving 1st PDU * since we may want to send AUX_SCAN_REQ. */ - if ((aux->scan_type == BLE_SCAN_TYPE_ACTIVE) && + if ((aux->scan_type != BLE_SCAN_TYPE_PASSIVE) && !(aux->flags & BLE_LL_SCAN_AUX_F_AUX_ADV)) { return 1; } @@ -1012,6 +1029,10 @@ ble_ll_scan_aux_rx_isr_end_on_ext(struct ble_ll_scan_sm *scansm, return -1; } + /* Don't care about initiator here, there are no AdvA and TargetA + * in connectable ADV_EXT_IND so no filtering to do. + */ + if (!aux_ptr) { /* We do not allocate aux_data for ADV_EXT_IND without AuxPtr so * need to pass match data in rxinfo. @@ -1046,6 +1067,10 @@ ble_ll_scan_aux_rx_isr_end_on_ext(struct ble_ll_scan_sm *scansm, aux->adi = adi; aux->flags |= BLE_LL_SCAN_AUX_F_HAS_ADI; + if (aux->scan_type == BLE_SCAN_TYPE_INITIATE) { + aux->flags |= BLE_LL_SCAN_AUX_F_CONNECTABLE; + } + if (do_match) { aux->flags |= BLE_LL_SCAN_AUX_F_MATCHED; ble_ll_scan_aux_update_aux_data_from_addrd(&addrd, aux); @@ -1187,6 +1212,7 @@ ble_ll_scan_aux_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) struct ble_mbuf_hdr_rxinfo *rxinfo; struct ble_ll_scan_aux_data *aux; struct ble_mbuf_hdr *rxhdr; + uint8_t scan_filt_policy; uint8_t scan_ok; uint8_t adv_mode; uint8_t *rxbuf; @@ -1212,6 +1238,12 @@ ble_ll_scan_aux_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) rxbuf = rxpdu->om_data; + if (aux->flags & BLE_LL_SCAN_AUX_F_W4_CONNECT_RSP) { + aux->flags &= ~BLE_LL_SCAN_AUX_F_W4_CONNECT_RSP; + rxinfo->flags |= BLE_MBUF_HDR_F_CONNECT_RSP_RXD; + goto done; + } + if (aux->flags & BLE_LL_SCAN_AUX_F_W4_SCAN_RSP) { aux->flags &= ~BLE_LL_SCAN_AUX_F_W4_SCAN_RSP; aux->flags |= BLE_LL_SCAN_AUX_F_SCANNED; @@ -1251,9 +1283,10 @@ ble_ll_scan_aux_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) addrd.rpa_index = aux->rpa_index; #endif + scan_filt_policy = ble_ll_scan_get_filt_policy(); + rc = ble_ll_scan_rx_filter(ble_ll_scan_get_own_addr_type(), - ble_ll_scan_get_filt_policy(), - &addrd, &scan_ok); + scan_filt_policy, &addrd, &scan_ok); if (rc < 0) { rxinfo->flags |= BLE_MBUF_HDR_F_IGNORED; /* @@ -1269,21 +1302,42 @@ ble_ll_scan_aux_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) goto done; } + if ((aux->scan_type == BLE_SCAN_TYPE_INITIATE) && + !(scan_filt_policy & 0x01)) { + rc = ble_ll_scan_rx_check_init(&addrd); + if (rc < 0) { + goto done; + } + } + aux->flags |= BLE_LL_SCAN_AUX_F_MATCHED; ble_ll_scan_aux_update_aux_data_from_addrd(&addrd, aux); adv_mode = rxbuf[2] >> 6; - if ((aux->scan_type == BLE_SCAN_TYPE_ACTIVE) && - (adv_mode == BLE_LL_EXT_ADV_MODE_SCAN) && scan_ok) { - if (ble_ll_scan_aux_send_scan_req(aux, &addrd)) { + switch (aux->scan_type) { + case BLE_SCAN_TYPE_ACTIVE: + if ((adv_mode == BLE_LL_EXT_ADV_MODE_SCAN) && scan_ok && + ble_ll_scan_aux_send_scan_req(aux, &addrd)) { /* AUX_SCAN_REQ sent, keep PHY enabled to continue */ aux->flags |= BLE_LL_SCAN_AUX_F_W4_SCAN_RSP; rxinfo->flags |= BLE_MBUF_HDR_F_SCAN_REQ_TXD; aux_data_current = aux; return 0; } + break; + case BLE_SCAN_TYPE_INITIATE: + if (ble_ll_conn_send_connect_req(rxpdu, &addrd, 1) == 0) { + /* AUX_CONNECT_REQ sent, keep PHY enabled to continue */ + aux->flags |= BLE_LL_SCAN_AUX_F_W4_CONNECT_RSP; + rxinfo->flags |= BLE_MBUF_HDR_F_CONNECT_REQ_TXD; + aux_data_current = aux; + return 0; + } else { + rxinfo->flags |= BLE_MBUF_HDR_F_IGNORED; + } + break; } done: @@ -1399,6 +1453,137 @@ ble_ll_scan_aux_sync_check(struct os_mbuf *rxpdu, } #endif + +static int +ble_ll_scan_aux_check_connect_rsp(uint8_t *rxbuf, + struct ble_ll_scan_pdu_data *pdu_data, + struct ble_ll_scan_addr_data *addrd) +{ + uint8_t pdu_hdr; + uint8_t pdu_len; + uint8_t adv_mode; + uint8_t eh_len; + uint8_t eh_flags; + uint8_t *eh_data; + uint8_t adva_type; + uint8_t *adva; + uint8_t targeta_type; + uint8_t *targeta; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + struct ble_ll_resolv_entry *rl = NULL; +#endif + + pdu_hdr = rxbuf[0]; + pdu_len = rxbuf[1]; + + if (pdu_len == 0) { + return -1; + } + + adv_mode = rxbuf[2] >> 6; + eh_len = rxbuf[2] & 0x3f; + + if ((adv_mode != 0) || (eh_len == 0)) { + return -1; + } + + eh_flags = rxbuf[3]; + eh_data = &rxbuf[4]; + + /* AUX_CONNECT_RSP without AdvA or TargetA is not valid */ + if (!(eh_flags & ((1 << BLE_LL_EXT_ADV_ADVA_BIT) | + (1 << BLE_LL_EXT_ADV_TARGETA_BIT)))) { + return -1; + } + + adva = eh_data; + adva_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_TXADD_RAND); + eh_data += BLE_LL_EXT_ADV_ADVA_SIZE; + + targeta = eh_data; + targeta_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_RXADD_RAND); + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + /* If AdvA was initially resolved, we need to check if current AdvA also + * resolved with the same IRK since it may have changes due to RPA timeout. + * Otherwise it shall be the same as in AUX_CONNECT_REQ. + */ + if (addrd->adva_resolved) { + if (!adva_type) { + return -1; + } + + BLE_LL_ASSERT(addrd->rpa_index >= 0); + rl = &g_ble_ll_resolv_list[addrd->rpa_index]; + + if (!ble_ll_resolv_rpa(adva, rl->rl_peer_irk)) { + return -1; + } + + addrd->adva = adva; + } else if ((adva_type != + !!(pdu_data->hdr_byte & BLE_ADV_PDU_HDR_RXADD_MASK)) || + (memcmp(adva, pdu_data->adva, 6) != 0)) { + return -1; + } +#else + if ((adva_type != !!(pdu_data->hdr_byte & BLE_ADV_PDU_HDR_RXADD_MASK)) || + (memcmp(adva, pdu_data->adva, 6) != 0)) { + return -1; + } +#endif /* BLE_LL_CFG_FEAT_LL_PRIVACY */ + + if ((targeta_type != !!(pdu_data->hdr_byte & BLE_ADV_PDU_HDR_RXADD_MASK)) || + (memcmp(targeta, pdu_data->inita, 6) != 0)) { + return -1; + } + + return 0; +} + +static void +ble_ll_scan_aux_rx_pkt_in_for_initiator(struct os_mbuf *rxpdu, + struct ble_mbuf_hdr *rxhdr) +{ + struct ble_ll_scan_addr_data addrd; + struct ble_mbuf_hdr_rxinfo *rxinfo; + struct ble_ll_scan_aux_data *aux; + + rxinfo = &rxhdr->rxinfo; + aux = rxinfo->user_data; + + if (rxinfo->flags & BLE_MBUF_HDR_F_IGNORED) { + ble_ll_scan_chk_resume(); + goto done; + } + + if (!(rxinfo->flags & BLE_MBUF_HDR_F_CONNECT_RSP_RXD)) { + BLE_LL_ASSERT(rxinfo->flags & BLE_MBUF_HDR_F_CONNECT_REQ_TXD); + /* Waiting for AUX_CONNECT_RSP, do nothing */ + return; + } + + ble_ll_scan_aux_init_addrd_from_aux_data(aux, &addrd); + + if (ble_ll_scan_aux_check_connect_rsp(rxpdu->om_data, + ble_ll_scan_get_pdu_data(), + &addrd) < 0) { + ble_ll_scan_chk_resume(); + goto done; + } + + aux->flags &= ~BLE_LL_SCAN_AUX_F_W4_CONNECT_RSP; + + ble_ll_scan_sm_stop(0); + ble_ll_conn_created_on_aux(rxpdu, &addrd, aux->targeta); + +done: + if (aux->flags & BLE_LL_SCAN_AUX_F_W4_CONNECT_RSP) { + ble_ll_conn_send_connect_req_cancel(); + } + ble_ll_scan_aux_free(aux); +} + void ble_ll_scan_aux_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr) { @@ -1416,6 +1601,11 @@ ble_ll_scan_aux_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr) BLE_LL_ASSERT(aux); + if (aux->scan_type == BLE_SCAN_TYPE_INITIATE) { + ble_ll_scan_aux_rx_pkt_in_for_initiator(rxpdu, rxhdr); + return; + } + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) sync_check = ble_ll_sync_enabled() && !(aux->flags & BLE_LL_SCAN_AUX_F_AUX_CHAIN); diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 1c7db41b9b..03dea23a73 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -134,9 +134,6 @@ ble_ll_sched_preempt(struct ble_ll_sched_item *sch, case BLE_LL_SCHED_TYPE_SCAN_AUX: ble_ll_scan_aux_break(entry->cb_arg); break; - case BLE_LL_SCHED_TYPE_AUX_SCAN: - ble_ll_scan_end_adv_evt(entry->cb_arg); - break; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) case BLE_LL_SCHED_TYPE_PERIODIC: ble_ll_adv_periodic_rmvd_from_sched(entry->cb_arg); @@ -1133,20 +1130,6 @@ ble_ll_sched_execute_item(struct ble_ll_sched_item *sch) goto sched; } - /* If aux scan scheduled and LL is in state when scanner is running - * in 3 states: - * BLE_LL_STATE_SCANNING - * BLE_LL_STATE_INITIATING - * BLE_LL_STATE_STANDBY - * - * Let scanner to decide to disable phy or not. - */ - if (sch->sched_type == BLE_LL_SCHED_TYPE_AUX_SCAN) { - if (lls == BLE_LL_STATE_INITIATING || lls == BLE_LL_STATE_SCANNING) { - goto sched; - } - } - /* * This is either an advertising event or connection event start. If * we are scanning or initiating just stop it. @@ -1158,11 +1141,6 @@ ble_ll_sched_execute_item(struct ble_ll_sched_item *sch) if (lls == BLE_LL_STATE_SCANNING) { ble_ll_state_set(BLE_LL_STATE_STANDBY); ble_ll_scan_halt(); - } else if (lls == BLE_LL_STATE_INITIATING) { - ble_ll_state_set(BLE_LL_STATE_STANDBY); - ble_ll_scan_halt(); - /* PHY is disabled - make sure we do not wait for AUX_CONNECT_RSP */ - ble_ll_conn_reset_pending_aux_conn_rsp(); } else if (lls == BLE_LL_STATE_ADV) { STATS_INC(ble_ll_stats, sched_state_adv_errs); ble_ll_adv_halt(); @@ -1262,78 +1240,6 @@ ble_ll_sched_next_time(uint32_t *next_event_time) } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -/** - * Called to schedule a aux scan. - * - * Context: Interrupt - * - * @param ble_hdr - * @param scansm - * @param aux_scan - * - * @return 0 on success, 1 otherwise - */ -int -ble_ll_sched_aux_scan(struct ble_mbuf_hdr *ble_hdr, - struct ble_ll_scan_sm *scansm, - struct ble_ll_aux_data *aux_scan) -{ - int rc = 1; - os_sr_t sr; - uint32_t off_ticks; - uint32_t off_rem_usecs; - uint32_t start_time; - uint32_t start_time_rem_usecs; - uint32_t end_time; - uint32_t dur; - struct ble_ll_sched_item *sch; - int phy_mode; - - sch = &aux_scan->sch; - BLE_LL_ASSERT(sch->cb_arg == NULL); - - off_ticks = os_cputime_usecs_to_ticks(aux_scan->offset); - off_rem_usecs = aux_scan->offset - os_cputime_ticks_to_usecs(off_ticks); - - start_time = ble_hdr->beg_cputime + off_ticks; - start_time_rem_usecs = ble_hdr->rem_usecs + off_rem_usecs; - if (start_time_rem_usecs >= 31) { - start_time++; - start_time_rem_usecs -= 31; - } - start_time -= g_ble_ll_sched_offset_ticks; - - /* Let's calculate time we reserve for aux packet. For now we assume to wait - * for fixed number of bytes and handle possible interrupting it in - * ble_ll_sched_execute_item(). This is because aux packet can be up to - * 256bytes and we don't want to block sched that long - */ - phy_mode = ble_ll_phy_to_phy_mode(aux_scan->aux_phy, - BLE_HCI_LE_PHY_CODED_ANY); - dur = ble_ll_pdu_tx_time_get(MYNEWT_VAL(BLE_LL_SCHED_SCAN_AUX_PDU_LEN), - phy_mode); - end_time = start_time + os_cputime_usecs_to_ticks(dur); - - sch->start_time = start_time; - sch->remainder = start_time_rem_usecs; - sch->end_time = end_time; - - OS_ENTER_CRITICAL(sr); - - rc = ble_ll_sched_insert(sch, 0, preempt_none); - - if (rc == 0) { - sch->cb_arg = ble_ll_scan_aux_data_ref(aux_scan); - STATS_INC(ble_ll_stats, aux_scheduled); - } - - OS_EXIT_CRITICAL(sr); - - ble_ll_sched_restart(); - - return rc; -} - int ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time, uint8_t pdu_time_rem, uint32_t offset_us) diff --git a/nimble/include/nimble/ble.h b/nimble/include/nimble/ble.h index 1ddd5773d0..d349afebb0 100644 --- a/nimble/include/nimble/ble.h +++ b/nimble/include/nimble/ble.h @@ -88,6 +88,9 @@ struct ble_mbuf_hdr_rxinfo * set for the same PDU (e.g. one use by scanner, other one used by * connection) */ +#define BLE_MBUF_HDR_F_CONNECT_IND_TXD (0x4000) +#define BLE_MBUF_HDR_F_CONNECT_REQ_TXD (0x4000) +#define BLE_MBUF_HDR_F_CONNECT_RSP_RXD (0x0008) #define BLE_MBUF_HDR_F_CONN_CREDIT (0x8000) #define BLE_MBUF_HDR_F_IGNORED (0x8000) #define BLE_MBUF_HDR_F_SCAN_REQ_TXD (0x4000) From df6ac21d2f3a5d845dd490dbdd148628d030e2e1 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 19 Oct 2021 17:55:49 +0200 Subject: [PATCH 0037/1333] nimble/ll: Refactor conn init param handling This fixes handling of parameters used for conn init. Firstly, we only need conn init params when intiating new connection so we can have single, global instance of that params - no need to store them in conns. This saves 72 bytes of RAM per connsm. Secondly, we do not need to store all parameters from HCI command since some of them are only used to initialize scanner and those can be used immediately. We only need to store connection parameters for ext conn create. This also allows to share more code between legacy and ext conn create code paths. --- .../include/controller/ble_ll_conn.h | 27 - .../include/controller/ble_ll_scan.h | 13 +- .../controller/include/controller/ble_phy.h | 5 + nimble/controller/src/ble_ll.c | 2 +- nimble/controller/src/ble_ll_conn.c | 147 ++---- nimble/controller/src/ble_ll_conn_hci.c | 464 +++++++++--------- nimble/controller/src/ble_ll_conn_priv.h | 52 +- nimble/controller/src/ble_ll_hci.c | 4 +- nimble/controller/src/ble_ll_resolv.c | 2 +- nimble/controller/src/ble_ll_scan.c | 81 +-- 10 files changed, 353 insertions(+), 444 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 7be3a43157..0de54afb3d 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -188,29 +188,6 @@ struct hci_conn_update uint16_t max_ce_len; }; -struct hci_ext_conn_params -{ - uint16_t scan_itvl; - uint16_t scan_window; - uint32_t conn_itvl; - uint16_t conn_itvl_ticks; - uint8_t conn_itvl_usecs; - uint16_t conn_latency; - uint16_t supervision_timeout; - uint16_t min_ce_len; - uint16_t max_ce_len; -}; - -struct hci_ext_create_conn -{ - uint8_t filter_policy; - uint8_t own_addr_type; - uint8_t peer_addr_type; - uint8_t peer_addr[BLE_DEV_ADDR_LEN]; - uint8_t init_phy_mask; - struct hci_ext_conn_params params[3]; -}; - /* Connection state machine */ struct ble_ll_conn_sm { @@ -379,10 +356,6 @@ struct ble_ll_conn_sm /* XXX: for now, just store them all */ struct ble_ll_conn_params conn_cp; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - struct hci_ext_create_conn initial_params; -#endif - #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) uint8_t sync_transfer_mode; uint16_t sync_transfer_skip; diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index eae0c39457..04ca48177b 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -197,10 +197,11 @@ int ble_ll_scan_can_chg_whitelist(void); int ble_ll_scan_enabled(void); /* Initialize the scanner when we start initiating */ -struct hci_create_conn; +struct ble_ll_conn_create_scan; +struct ble_ll_conn_create_params; int -ble_ll_scan_initiator_start(struct hci_create_conn *hcc, - struct ble_ll_conn_sm *connsm); +ble_ll_scan_initiator_start(struct ble_ll_conn_sm *connsm, uint8_t ext, + struct ble_ll_conn_create_scan *cc_scan); /* Returns storage for PDU data (for SCAN_REQ or CONNECT_IND) */ struct ble_ll_scan_pdu_data *ble_ll_scan_get_pdu_data(void); @@ -227,12 +228,6 @@ void ble_ll_scan_wfr_timer_exp(void); void ble_ll_scan_interrupted(struct ble_ll_scan_sm *scansm); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -/* Initialize the extended scanner when we start initiating */ -struct hci_ext_create_conn; -int -ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, - struct ble_ll_conn_sm *connsm); - /* Called to parse extended advertising*/ void ble_ll_scan_end_adv_evt(struct ble_ll_aux_data *aux_data); #endif diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index cd8350d657..47f3afd4ec 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -202,6 +202,11 @@ void ble_phy_resolv_list_disable(void); #define BLE_PHY_MASK_2M (BLE_HCI_LE_PHY_2M_PREF_MASK) #define BLE_PHY_MASK_CODED (BLE_HCI_LE_PHY_CODED_PREF_MASK) +/* PHY indices (for a zero-based array) */ +#define BLE_PHY_IDX_1M (0) +#define BLE_PHY_IDX_2M (1) +#define BLE_PHY_IDX_CODED (2) + #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) || MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)) uint32_t ble_phy_mode_pdu_start_off(int phy); void ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode); diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 2702b7c53a..014f7e2809 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -577,7 +577,7 @@ ble_ll_set_random_addr(const uint8_t *cmdbuf, uint8_t len, bool hci_adv_ext) * Test specification extends this also to initiating. */ - if (g_ble_ll_conn_create_sm || ble_ll_scan_enabled() || + if (g_ble_ll_conn_create_sm.connsm || ble_ll_scan_enabled() || (!hci_adv_ext && ble_ll_adv_enabled())) { return BLE_ERR_CMD_DISALLOWED; } diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 76dd18e4bc..eb61414f2c 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -143,8 +143,7 @@ struct ble_ll_conn_global_params g_ble_ll_conn_params; struct ble_ll_conn_sync_transfer_params g_ble_ll_conn_sync_transfer_params; #endif -/* Pointer to connection state machine we are trying to create */ -struct ble_ll_conn_sm *g_ble_ll_conn_create_sm; +struct ble_ll_conn_create_sm g_ble_ll_conn_create_sm; /* Pointer to current connection */ struct ble_ll_conn_sm *g_ble_ll_conn_cur_sm; @@ -421,25 +420,23 @@ ble_ll_conn_chk_phy_upd_start(struct ble_ll_conn_sm *csm) } #endif -static void -ble_ll_conn_calc_itvl_ticks(struct ble_ll_conn_sm *connsm) +void +ble_ll_conn_itvl_to_ticks(uint32_t itvl, uint32_t *itvl_ticks, + uint8_t *itvl_usecs) { uint32_t ticks; uint32_t usecs; - /* - * Precalculate the number of ticks and remaining microseconds for - * the connection interval - */ - usecs = connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS; + usecs = itvl * BLE_LL_CONN_ITVL_USECS; ticks = os_cputime_usecs_to_ticks(usecs); - connsm->conn_itvl_usecs = (uint8_t)(usecs - - os_cputime_ticks_to_usecs(ticks)); - if (connsm->conn_itvl_usecs == 31) { - connsm->conn_itvl_usecs = 0; + usecs = usecs - os_cputime_ticks_to_usecs(ticks); + if (usecs == 31) { + usecs = 0; ++ticks; } - connsm->conn_itvl_ticks = ticks; + + *itvl_ticks = ticks; + *itvl_usecs = usecs; } /** @@ -1578,37 +1575,23 @@ ble_ll_conn_master_common_init(struct ble_ll_conn_sm *connsm) */ void ble_ll_conn_master_init(struct ble_ll_conn_sm *connsm, - struct hci_create_conn *hcc) + struct ble_ll_conn_create_scan *cc_scan, + struct ble_ll_conn_create_params *cc_params) { ble_ll_conn_master_common_init(connsm); - /* Set slave latency and supervision timeout */ - connsm->slave_latency = hcc->conn_latency; - connsm->supervision_tmo = hcc->supervision_timeout; - - /* Set own address type and peer address if needed */ - connsm->own_addr_type = hcc->own_addr_type; - if (hcc->filter_policy == 0) { - memcpy(&connsm->peer_addr, &hcc->peer_addr, BLE_DEV_ADDR_LEN); - connsm->peer_addr_type = hcc->peer_addr_type; - } - - /* XXX: for now, just make connection interval equal to max */ - connsm->conn_itvl = hcc->conn_itvl_max; - - /* Check the min/max CE lengths are less than connection interval */ - if (hcc->min_ce_len > (connsm->conn_itvl * 2)) { - connsm->min_ce_len = connsm->conn_itvl * 2; - } else { - connsm->min_ce_len = hcc->min_ce_len; - } + connsm->own_addr_type = cc_scan->own_addr_type; + memcpy(&connsm->peer_addr, &cc_scan->peer_addr, BLE_DEV_ADDR_LEN); + connsm->peer_addr_type = cc_scan->peer_addr_type; - if (hcc->max_ce_len > (connsm->conn_itvl * 2)) { - connsm->max_ce_len = connsm->conn_itvl * 2; - } else { - connsm->max_ce_len = hcc->max_ce_len; - } + connsm->conn_itvl = cc_params->conn_itvl; + connsm->conn_itvl_ticks = cc_params->conn_itvl_ticks; + connsm->conn_itvl_usecs = cc_params->conn_itvl_usecs; + connsm->slave_latency = cc_params->conn_latency; + connsm->supervision_tmo = cc_params->supervision_timeout; + connsm->min_ce_len = cc_params->min_ce_len; + connsm->max_ce_len = cc_params->max_ce_len; } static void @@ -1684,54 +1667,20 @@ ble_ll_conn_init_phy(struct ble_ll_conn_sm *connsm, int phy) #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - -void -ble_ll_conn_ext_master_init(struct ble_ll_conn_sm *connsm, - struct hci_ext_create_conn *hcc) -{ - - ble_ll_conn_master_common_init(connsm); - - /* Set own address type and peer address if needed */ - connsm->own_addr_type = hcc->own_addr_type; - if (hcc->filter_policy == 0) { - memcpy(&connsm->peer_addr, &hcc->peer_addr, BLE_DEV_ADDR_LEN); - connsm->peer_addr_type = hcc->peer_addr_type; - } - - connsm->initial_params = *hcc; -} - -void -ble_ll_conn_ext_set_params(struct ble_ll_conn_sm *connsm, - struct hci_ext_conn_params *hcc_params, int phy) +static void +ble_ll_conn_create_set_params(struct ble_ll_conn_sm *connsm, uint8_t phy) { - connsm->slave_latency = hcc_params->conn_latency; - connsm->supervision_tmo = hcc_params->supervision_timeout; + struct ble_ll_conn_create_params *cc_params; - connsm->conn_itvl = hcc_params->conn_itvl; - connsm->conn_itvl_ticks = hcc_params->conn_itvl_ticks; - connsm->conn_itvl_usecs = hcc_params->conn_itvl_usecs; + cc_params = &g_ble_ll_conn_create_sm.params[phy - 1]; - /* Check the min/max CE lengths are less than connection interval */ - if (hcc_params->min_ce_len > (connsm->conn_itvl * 2)) { - connsm->min_ce_len = connsm->conn_itvl * 2; - } else { - connsm->min_ce_len = hcc_params->min_ce_len; - } + connsm->slave_latency = cc_params->conn_latency; + connsm->supervision_tmo = cc_params->supervision_timeout; - if (hcc_params->max_ce_len > (connsm->conn_itvl * 2)) { - connsm->max_ce_len = connsm->conn_itvl * 2; - } else { - connsm->max_ce_len = hcc_params->max_ce_len; - } - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_ll_conn_init_phy(connsm, phy); -#endif + connsm->conn_itvl = cc_params->conn_itvl; + connsm->conn_itvl_ticks = cc_params->conn_itvl_ticks; + connsm->conn_itvl_usecs = cc_params->conn_itvl_usecs; } - - #endif static void @@ -1862,8 +1811,6 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) connsm); #endif - ble_ll_conn_calc_itvl_ticks(connsm); - /* Add to list of active connections */ SLIST_INSERT_HEAD(&g_ble_ll_conn_active_list, connsm, act_sle); } @@ -2170,7 +2117,10 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) connsm->tx_win_size * BLE_LL_CONN_TX_WIN_USECS; connsm->tx_win_off = upd->winoffset; connsm->conn_itvl = upd->interval; - ble_ll_conn_calc_itvl_ticks(connsm); + + ble_ll_conn_itvl_to_ticks(connsm->conn_itvl, &connsm->conn_itvl_ticks, + &connsm->conn_itvl_usecs); + if (upd->winoffset != 0) { usecs = upd->winoffset * BLE_LL_CONN_ITVL_USECS; ticks = os_cputime_usecs_to_ticks(usecs); @@ -2651,7 +2601,7 @@ ble_ll_conn_prepare_connect_ind(struct ble_ll_conn_sm *connsm, } } else { /* Get pointer to our device address */ - connsm = g_ble_ll_conn_create_sm; + connsm = g_ble_ll_conn_create_sm.connsm; if ((connsm->own_addr_type & 1) == 0) { addr = g_dev_addr; } else { @@ -2764,12 +2714,11 @@ ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr; int8_t rpa_index; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - struct hci_ext_conn_params *ecp; uint8_t phy; #endif int rc; - connsm = g_ble_ll_conn_create_sm; + connsm = g_ble_ll_conn_create_sm.connsm; rxhdr = BLE_MBUF_HDR_PTR(rxpdu); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) @@ -2779,8 +2728,7 @@ ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu, #else phy = BLE_PHY_1M; #endif - ecp = &connsm->initial_params.params[phy - 1]; - ble_ll_conn_ext_set_params(connsm, ecp, phy); + ble_ll_conn_create_set_params(connsm, phy); } #endif @@ -2806,6 +2754,12 @@ ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu, return -1; } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && BLE_LL_BT5_PHY_SUPPORTED + if (ext) { + ble_ll_conn_init_phy(connsm, phy); + } +#endif + return 0; } @@ -2814,7 +2768,7 @@ ble_ll_conn_send_connect_req_cancel(void) { struct ble_ll_conn_sm *connsm; - connsm = g_ble_ll_conn_create_sm; + connsm = g_ble_ll_conn_create_sm.connsm; ble_ll_sched_rmv_elem(&connsm->conn_sch); } @@ -2825,8 +2779,8 @@ ble_ll_conn_master_start(uint8_t phy, uint8_t csa, { struct ble_ll_conn_sm *connsm; - connsm = g_ble_ll_conn_create_sm; - g_ble_ll_conn_create_sm = NULL; + connsm = g_ble_ll_conn_create_sm.connsm; + g_ble_ll_conn_create_sm.connsm = NULL; connsm->peer_addr_type = addrd->adv_addr_type; memcpy(connsm->peer_addr, addrd->adv_addr, 6); @@ -3688,6 +3642,9 @@ ble_ll_conn_slave_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr, goto err_slave_start; } + ble_ll_conn_itvl_to_ticks(connsm->conn_itvl, &connsm->conn_itvl_ticks, + &connsm->conn_itvl_usecs); + /* Start the connection state machine */ connsm->conn_role = BLE_LL_CONN_ROLE_SLAVE; ble_ll_conn_sm_new(connsm); @@ -3751,7 +3708,7 @@ ble_ll_conn_module_reset(void) } /* Reset connection we are attempting to create */ - g_ble_ll_conn_create_sm = NULL; + g_ble_ll_conn_create_sm.connsm = NULL; /* Now go through and end all the connections */ while (1) { diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index e53918f96c..decc4851f0 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -43,19 +43,22 @@ static ble_npl_time_t g_ble_ll_last_num_comp_pkt_evt; extern uint8_t *g_ble_ll_conn_comp_ev; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -static const uint8_t ble_ll_valid_conn_phy_mask = (BLE_HCI_LE_PHY_1M_PREF_MASK +static const uint8_t ble_ll_conn_create_valid_phy_mask = ( + BLE_HCI_LE_PHY_1M_PREF_MASK | #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) - | BLE_HCI_LE_PHY_2M_PREF_MASK + BLE_HCI_LE_PHY_2M_PREF_MASK | #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - | BLE_HCI_LE_PHY_CODED_PREF_MASK + BLE_HCI_LE_PHY_CODED_PREF_MASK | #endif - ); -static const uint8_t ble_ll_conn_required_phy_mask = (BLE_HCI_LE_PHY_1M_PREF_MASK + 0); + +static const uint8_t ble_ll_conn_create_required_phy_mask = ( + BLE_HCI_LE_PHY_1M_PREF_MASK | #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - | BLE_HCI_LE_PHY_CODED_PREF_MASK + BLE_HCI_LE_PHY_CODED_PREF_MASK | #endif - ); + 0); #endif /** @@ -401,18 +404,74 @@ ble_ll_disconn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t reason) } } +int +ble_ll_conn_hci_create_check_scan(struct ble_ll_conn_create_scan *p) +{ + if (p->filter_policy > BLE_HCI_INITIATOR_FILT_POLICY_MAX) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if ((p->filter_policy == 0) && + (p->peer_addr_type > BLE_HCI_CONN_PEER_ADDR_MAX)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (p->own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + if (p->init_phy_mask & ~ble_ll_conn_create_valid_phy_mask) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (!(p->init_phy_mask & ble_ll_conn_create_required_phy_mask)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } +#endif + + return 0; +} + static int -ble_ll_conn_hci_chk_scan_params(uint16_t itvl, uint16_t window) +ble_ll_conn_hci_create_check_params(struct ble_ll_conn_create_params *cc_params) { - /* Check interval and window */ - if ((itvl < BLE_HCI_SCAN_ITVL_MIN) || - (itvl > BLE_HCI_SCAN_ITVL_MAX) || - (window < BLE_HCI_SCAN_WINDOW_MIN) || - (window > BLE_HCI_SCAN_WINDOW_MAX) || - (itvl < window)) { + uint32_t supervision_tmo_us; + uint32_t conn_itvl_us; + + if ((cc_params->conn_itvl < BLE_HCI_CONN_ITVL_MIN) || + (cc_params->conn_itvl > BLE_HCI_CONN_ITVL_MAX) || + (cc_params->conn_latency > BLE_HCI_CONN_LATENCY_MAX) || + (cc_params->supervision_timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN) || + (cc_params->supervision_timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* Supervision timeout must be longer than (1 + latency) * interval * 2 */ + supervision_tmo_us = cc_params->supervision_timeout * + BLE_HCI_CONN_SPVN_TMO_UNITS * 1000; + conn_itvl_us = cc_params->conn_itvl * BLE_LL_CONN_ITVL_USECS; + + if (supervision_tmo_us <= (1 + cc_params->conn_latency) * conn_itvl_us * 2) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (cc_params->min_ce_len > cc_params->max_ce_len) { return BLE_ERR_INV_HCI_CMD_PARMS; } + /* Adjust min/max ce length to be less than interval */ + if (cc_params->min_ce_len > cc_params->conn_itvl) { + cc_params->min_ce_len = cc_params->conn_itvl; + } + if (cc_params->max_ce_len > cc_params->conn_itvl) { + cc_params->max_ce_len = cc_params->conn_itvl; + } + + /* Precalculate conn interval */ + ble_ll_conn_itvl_to_ticks(cc_params->conn_itvl, &cc_params->conn_itvl_ticks, + &cc_params->conn_itvl_usecs); + return 0; } @@ -426,11 +485,14 @@ ble_ll_conn_hci_chk_scan_params(uint16_t itvl, uint16_t window) * @return int */ int -ble_ll_conn_create(const uint8_t *cmdbuf, uint8_t len) +ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len) { const struct ble_hci_le_create_conn_cp *cmd = (const void *) cmdbuf; + struct ble_ll_conn_create_scan cc_scan; + struct ble_ll_conn_create_params cc_params; struct ble_ll_conn_sm *connsm; - struct hci_create_conn hcc = { 0 }; + uint16_t conn_itvl_min; + uint16_t conn_itvl_max; int rc; if (len < sizeof(*cmd)) { @@ -438,7 +500,7 @@ ble_ll_conn_create(const uint8_t *cmdbuf, uint8_t len) } /* If we are already creating a connection we should leave */ - if (g_ble_ll_conn_create_sm) { + if (g_ble_ll_conn_create_sm.connsm) { return BLE_ERR_CMD_DISALLOWED; } @@ -447,57 +509,48 @@ ble_ll_conn_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_CMD_DISALLOWED; } - /* Retrieve command data */ - hcc.scan_itvl = le16toh(cmd->scan_itvl); - hcc.scan_window = le16toh(cmd->scan_window); - - rc = ble_ll_conn_hci_chk_scan_params(hcc.scan_itvl, hcc.scan_window); - if (rc) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Check filter policy */ - hcc.filter_policy = cmd->filter_policy; - if (hcc.filter_policy > BLE_HCI_INITIATOR_FILT_POLICY_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; + cc_scan.own_addr_type = cmd->own_addr_type; + cc_scan.filter_policy = cmd->filter_policy; + if (cc_scan.filter_policy == 0) { + cc_scan.peer_addr_type = cmd->peer_addr_type; + memcpy(&cc_scan.peer_addr, cmd->peer_addr, BLE_DEV_ADDR_LEN); + } else { + cc_scan.peer_addr_type = 0; + memset(&cc_scan.peer_addr, 0, BLE_DEV_ADDR_LEN); } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + cc_scan.init_phy_mask = BLE_HCI_LE_PHY_1M_PREF_MASK; +#endif - /* Get peer address type and address only if no whitelist used */ - if (hcc.filter_policy == 0) { - hcc.peer_addr_type = cmd->peer_addr_type; - if (hcc.peer_addr_type > BLE_HCI_CONN_PEER_ADDR_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } + cc_scan.scan_params[PHY_UNCODED].itvl = le16toh(cmd->scan_itvl); + cc_scan.scan_params[PHY_UNCODED].window = le16toh(cmd->scan_window); - memcpy(&hcc.peer_addr, cmd->peer_addr, BLE_DEV_ADDR_LEN); + rc = ble_ll_conn_hci_create_check_scan(&cc_scan); + if (rc) { + return rc; } - /* Get own address type (used in connection request) */ - hcc.own_addr_type = cmd->own_addr_type; - if (hcc.own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) { + conn_itvl_min = le16toh(cmd->min_conn_itvl); + conn_itvl_max = le16toh(cmd->max_conn_itvl); + + /* Check min/max interval here since generic check does not have min/max + * parameters to check. + */ + if (conn_itvl_min > conn_itvl_max) { return BLE_ERR_INV_HCI_CMD_PARMS; } - /* Check connection interval, latency and supervision timeoout */ - hcc.conn_itvl_min = le16toh(cmd->min_conn_itvl); - hcc.conn_itvl_max = le16toh(cmd->max_conn_itvl); - hcc.conn_latency = le16toh(cmd->conn_latency); - hcc.supervision_timeout = le16toh(cmd->tmo); - rc = ble_ll_conn_hci_chk_conn_params(hcc.conn_itvl_min, - hcc.conn_itvl_max, - hcc.conn_latency, - hcc.supervision_timeout); + cc_params.conn_itvl = conn_itvl_max; + cc_params.conn_latency = le16toh(cmd->conn_latency); + cc_params.supervision_timeout = le16toh(cmd->tmo); + cc_params.min_ce_len = le16toh(cmd->min_ce); + cc_params.max_ce_len = le16toh(cmd->max_ce); + + rc = ble_ll_conn_hci_create_check_params(&cc_params); if (rc) { return rc; } - /* Min/max connection event lengths */ - hcc.min_ce_len = le16toh(cmd->min_ce); - hcc.max_ce_len = le16toh(cmd->max_ce); - if (hcc.min_ce_len > hcc.max_ce_len) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - /* Make sure we can allocate an event to send the connection complete */ if (ble_ll_init_alloc_conn_comp_ev()) { return BLE_ERR_MEM_CAPACITY; @@ -510,18 +563,14 @@ ble_ll_conn_create(const uint8_t *cmdbuf, uint8_t len) } /* Initialize state machine in master role and start state machine */ - ble_ll_conn_master_init(connsm, &hcc); + ble_ll_conn_master_init(connsm, &cc_scan, &cc_params); ble_ll_conn_sm_new(connsm); - /* CSA will be selected when advertising is received */ /* Start scanning */ - rc = ble_ll_scan_initiator_start(&hcc, connsm); + rc = ble_ll_scan_initiator_start(connsm, 0, &cc_scan); if (rc) { SLIST_REMOVE(&g_ble_ll_conn_active_list,connsm,ble_ll_conn_sm,act_sle); STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe); - } else { - /* Set the connection state machine we are trying to create. */ - g_ble_ll_conn_create_sm = connsm; } return rc; @@ -529,68 +578,117 @@ ble_ll_conn_create(const uint8_t *cmdbuf, uint8_t len) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) static void -ble_ll_conn_hcc_params_set_fallback(struct hci_ext_create_conn *hcc, - const struct hci_ext_conn_params *fallback) +ble_ll_conn_hci_ext_create_set_fb_params(uint8_t init_phy_mask, + struct ble_ll_conn_create_params *cc_params_fb) { - BLE_LL_ASSERT(fallback); - - if (!(hcc->init_phy_mask & BLE_PHY_MASK_1M)) { - hcc->params[0] = *fallback; + if ((init_phy_mask & BLE_PHY_MASK_1M) == 0) { + g_ble_ll_conn_create_sm.params[BLE_PHY_IDX_1M] = *cc_params_fb; } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) - if (!(hcc->init_phy_mask & BLE_PHY_MASK_2M)) { - hcc->params[1] = *fallback; + if ((init_phy_mask & BLE_PHY_MASK_2M) == 0) { + g_ble_ll_conn_create_sm.params[BLE_PHY_IDX_2M] = *cc_params_fb; } #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - if (!(hcc->init_phy_mask & BLE_PHY_MASK_CODED)) { - hcc->params[2] = *fallback; + if ((init_phy_mask & BLE_PHY_MASK_CODED) == 0) { + g_ble_ll_conn_create_sm.params[BLE_PHY_IDX_CODED] = *cc_params_fb; } #endif } -static void -ble_ll_conn_itvl_to_ticks(uint32_t itvl, uint16_t *itvl_ticks, - uint8_t *itvl_usecs) +static int +ble_ll_conn_hci_ext_create_parse_params(const struct conn_params *params, + uint8_t phy, + struct ble_ll_conn_create_scan *cc_scan, + struct ble_ll_conn_create_params *cc_params) { - uint32_t ticks; - uint32_t usecs; + uint16_t conn_itvl_min; + uint16_t conn_itvl_max; + uint16_t scan_itvl; + uint16_t scan_window; + int rc; + + conn_itvl_min = le16toh(params->conn_min_itvl); + conn_itvl_max = le16toh(params->conn_max_itvl); + + /* Check min/max interval here since generic check does not have min/max + * parameters to check. + */ + if (conn_itvl_min > conn_itvl_max) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + cc_params->conn_itvl = conn_itvl_max; + cc_params->conn_latency = le16toh(params->conn_latency); + cc_params->supervision_timeout = le16toh(params->supervision_timeout); + cc_params->min_ce_len = le16toh(params->min_ce); + cc_params->max_ce_len = le16toh(params->max_ce); + + rc = ble_ll_conn_hci_create_check_params(cc_params); + if (rc) { + return rc; + } + + if (phy != BLE_PHY_2M) { + scan_itvl = le16toh(params->scan_itvl); + scan_window = le16toh(params->scan_window); - usecs = itvl * BLE_LL_CONN_ITVL_USECS; - ticks = os_cputime_usecs_to_ticks(usecs); - usecs = usecs - os_cputime_ticks_to_usecs(ticks); - if (usecs == 31) { - usecs = 0; - ++ticks; + if ((scan_itvl < BLE_HCI_SCAN_ITVL_MIN) || + (scan_itvl > BLE_HCI_SCAN_ITVL_MAX) || + (scan_window < BLE_HCI_SCAN_WINDOW_MIN) || + (scan_window > BLE_HCI_SCAN_WINDOW_MAX) || + (scan_itvl < scan_window)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (phy == BLE_PHY_1M) { + cc_scan->scan_params[PHY_UNCODED].itvl = scan_itvl; + cc_scan->scan_params[PHY_UNCODED].window = scan_window; + } else { + cc_scan->scan_params[PHY_CODED].itvl = scan_itvl; + cc_scan->scan_params[PHY_CODED].window = scan_window; + } } - *itvl_ticks = ticks; - *itvl_usecs = usecs; + return 0; } int -ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len) +ble_ll_conn_hci_ext_create(const uint8_t *cmdbuf, uint8_t len) { - const struct ble_hci_le_ext_create_conn_cp *cmd = (const void *) cmdbuf; + static const struct init_phy { + uint8_t idx; + uint8_t mask; + uint8_t phy; + } init_phys[] = { + {BLE_PHY_IDX_1M, BLE_PHY_MASK_1M, BLE_PHY_1M}, +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) + {BLE_PHY_IDX_2M, BLE_PHY_MASK_2M, BLE_PHY_2M}, +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) + {BLE_PHY_IDX_CODED, BLE_PHY_MASK_CODED, BLE_PHY_CODED}, +#endif + }; + + const struct ble_hci_le_ext_create_conn_cp *cmd = (const void *)cmdbuf; const struct conn_params *params = cmd->conn_params; - const struct hci_ext_conn_params *fallback_params = NULL; - struct hci_ext_create_conn hcc = { 0 }; + struct ble_ll_conn_create_scan cc_scan; + struct ble_ll_conn_create_params *cc_params; + struct ble_ll_conn_create_params *cc_params_fb; struct ble_ll_conn_sm *connsm; - uint16_t conn_itvl_min; - uint16_t conn_itvl_max; + const struct init_phy *init_phy; int rc; /* validate length */ - if (len < sizeof(*cmd)) { + if (len < sizeof(*cmd) + + __builtin_popcount(cmd->init_phy_mask) * sizeof(*params)) { return BLE_ERR_INV_HCI_CMD_PARMS; } - len -= sizeof(*cmd); - /* If we are already creating a connection we should leave */ - if (g_ble_ll_conn_create_sm) { + if (g_ble_ll_conn_create_sm.connsm) { return BLE_ERR_CMD_DISALLOWED; } @@ -599,161 +697,47 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_CMD_DISALLOWED; } - hcc.filter_policy = cmd->filter_policy; - if (hcc.filter_policy > BLE_HCI_INITIATOR_FILT_POLICY_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - hcc.own_addr_type = cmd->own_addr_type; - if (hcc.own_addr_type > BLE_HCI_ADV_OWN_ADDR_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Validate peer address type only if no whitelist used */ - if (hcc.filter_policy == 0) { - hcc.peer_addr_type = cmd->peer_addr_type; - - if (hcc.peer_addr_type > BLE_HCI_CONN_PEER_ADDR_MAX) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - memcpy(hcc.peer_addr, cmd->peer_addr, BLE_DEV_ADDR_LEN); - } - - hcc.init_phy_mask = cmd->init_phy_mask; - if (hcc.init_phy_mask & ~ble_ll_valid_conn_phy_mask) { - return BLE_ERR_INV_HCI_CMD_PARMS; + cc_scan.own_addr_type = cmd->own_addr_type; + cc_scan.filter_policy = cmd->filter_policy; + if (cc_scan.filter_policy == 0) { + cc_scan.peer_addr_type = cmd->peer_addr_type; + memcpy(cc_scan.peer_addr, cmd->peer_addr, BLE_DEV_ADDR_LEN); + } else { + cc_scan.peer_addr_type = 0; + memset(cc_scan.peer_addr, 0, BLE_DEV_ADDR_LEN); } + cc_scan.init_phy_mask = cmd->init_phy_mask; - if (!(hcc.init_phy_mask & ble_ll_conn_required_phy_mask)) { - /* At least one of those need to be set */ - return BLE_ERR_INV_HCI_CMD_PARMS; + rc = ble_ll_conn_hci_create_check_scan(&cc_scan); + if (rc) { + return rc; } - if (hcc.init_phy_mask & BLE_PHY_MASK_1M) { - if (len < sizeof(*params)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - len -= sizeof(*params); + cc_params_fb = NULL; - hcc.params[0].scan_itvl = le16toh(params->scan_itvl); - hcc.params[0].scan_window = le16toh(params->scan_window); + for (int i = 0; i < ARRAY_SIZE(init_phys); i++) { + init_phy = &init_phys[i]; - rc = ble_ll_conn_hci_chk_scan_params(hcc.params[0].scan_itvl, - hcc.params[0].scan_window); - if (rc) { - return rc; + if ((cc_scan.init_phy_mask & init_phy->mask) == 0) { + continue; } - conn_itvl_min = le16toh(params->conn_min_itvl); - conn_itvl_max = le16toh(params->conn_max_itvl); - hcc.params[0].conn_latency = le16toh(params->conn_latency); - hcc.params[0].supervision_timeout = le16toh(params->supervision_timeout); + cc_params = &g_ble_ll_conn_create_sm.params[init_phy->idx]; - rc = ble_ll_conn_hci_chk_conn_params(conn_itvl_min, conn_itvl_max, - hcc.params[0].conn_latency, - hcc.params[0].supervision_timeout); + rc = ble_ll_conn_hci_ext_create_parse_params(params, init_phy->phy, + &cc_scan, cc_params); if (rc) { return rc; } - /* Min/max connection event lengths */ - hcc.params[0].min_ce_len = le16toh(params->min_ce); - hcc.params[0].max_ce_len = le16toh(params->max_ce); - if (hcc.params[0].min_ce_len > hcc.params[0].max_ce_len) { - return BLE_ERR_INV_HCI_CMD_PARMS; + if (!cc_params_fb) { + cc_params_fb = cc_params; } - - hcc.params[0].conn_itvl = conn_itvl_max; - ble_ll_conn_itvl_to_ticks(conn_itvl_max, &hcc.params[0].conn_itvl_ticks, - &hcc.params[0].conn_itvl_usecs); - - fallback_params = &hcc.params[0]; params++; } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) - if (hcc.init_phy_mask & BLE_PHY_MASK_2M) { - if (len < sizeof(*params)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - len -= sizeof(*params); - - conn_itvl_min = le16toh(params->conn_min_itvl); - conn_itvl_max = le16toh(params->conn_max_itvl); - hcc.params[1].conn_latency = le16toh(params->conn_latency); - hcc.params[1].supervision_timeout = le16toh(params->supervision_timeout); - - rc = ble_ll_conn_hci_chk_conn_params(conn_itvl_min, conn_itvl_max, - hcc.params[1].conn_latency, - hcc.params[1].supervision_timeout); - if (rc) { - return rc; - } - - /* Min/max connection event lengths */ - hcc.params[1].min_ce_len = le16toh(params->min_ce); - hcc.params[1].max_ce_len = le16toh(params->max_ce); - if (hcc.params[1].min_ce_len > hcc.params[1].max_ce_len) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - hcc.params[1].conn_itvl = conn_itvl_max; - ble_ll_conn_itvl_to_ticks(conn_itvl_max, &hcc.params[1].conn_itvl_ticks, - &hcc.params[1].conn_itvl_usecs); - - if (!fallback_params) { - fallback_params = &hcc.params[1]; - } - params++; - } -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - if (hcc.init_phy_mask & BLE_PHY_MASK_CODED) { - if (len < sizeof(*params)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - len -= sizeof(*params); - - hcc.params[2].scan_itvl = le16toh(params->scan_itvl); - hcc.params[2].scan_window = le16toh(params->scan_window); - - rc = ble_ll_conn_hci_chk_scan_params(hcc.params[2].scan_itvl, - hcc.params[2].scan_window); - if (rc) { - return rc; - } - - conn_itvl_min = le16toh(params->conn_min_itvl); - conn_itvl_max = le16toh(params->conn_max_itvl); - hcc.params[2].conn_latency = le16toh(params->conn_latency); - hcc.params[2].supervision_timeout = le16toh(params->supervision_timeout); - - rc = ble_ll_conn_hci_chk_conn_params(conn_itvl_min, conn_itvl_max, - hcc.params[2].conn_latency, - hcc.params[2].supervision_timeout); - if (rc) { - return rc; - } - - /* Min/max connection event lengths */ - hcc.params[2].min_ce_len = le16toh(params->min_ce); - hcc.params[2].max_ce_len = le16toh(params->max_ce); - if (hcc.params[2].min_ce_len > hcc.params[2].max_ce_len) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - hcc.params[2].conn_itvl = conn_itvl_max; - ble_ll_conn_itvl_to_ticks(conn_itvl_max, &hcc.params[2].conn_itvl_ticks, - &hcc.params[2].conn_itvl_usecs); - - if (!fallback_params) { - fallback_params = &hcc.params[2]; - } - params++; - } -#endif + ble_ll_conn_hci_ext_create_set_fb_params(cc_scan.init_phy_mask, + cc_params_fb); /* Make sure we can allocate an event to send the connection complete */ if (ble_ll_init_alloc_conn_comp_ev()) { @@ -766,20 +750,16 @@ ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_CONN_LIMIT; } - ble_ll_conn_hcc_params_set_fallback(&hcc, fallback_params); - /* Initialize state machine in master role and start state machine */ - ble_ll_conn_ext_master_init(connsm, &hcc); + ble_ll_conn_master_init(connsm, &cc_scan, + &g_ble_ll_conn_create_sm.params[0]); ble_ll_conn_sm_new(connsm); /* Start scanning */ - rc = ble_ll_scan_ext_initiator_start(&hcc, connsm); + rc = ble_ll_scan_initiator_start(connsm, 1, &cc_scan); if (rc) { SLIST_REMOVE(&g_ble_ll_conn_active_list,connsm,ble_ll_conn_sm,act_sle); STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe); - } else { - /* Set the connection state machine we are trying to create. */ - g_ble_ll_conn_create_sm = connsm; } return rc; @@ -1125,10 +1105,10 @@ ble_ll_conn_create_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb) * return disallowed as well */ OS_ENTER_CRITICAL(sr); - connsm = g_ble_ll_conn_create_sm; + connsm = g_ble_ll_conn_create_sm.connsm; if (connsm && (connsm->conn_state == BLE_LL_CONN_STATE_IDLE)) { /* stop scanning and end the connection event */ - g_ble_ll_conn_create_sm = NULL; + g_ble_ll_conn_create_sm.connsm = NULL; ble_ll_scan_sm_stop(1); ble_ll_conn_end(connsm, BLE_ERR_UNK_CONN_ID); diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index 099ce77f50..d1a4a3e884 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -93,8 +93,38 @@ STAILQ_HEAD(ble_ll_conn_free_list, ble_ll_conn_sm); extern struct ble_ll_conn_active_list g_ble_ll_conn_active_list; 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; +struct ble_ll_conn_create_scan { + uint8_t filter_policy; + uint8_t own_addr_type; + uint8_t peer_addr_type; + uint8_t peer_addr[BLE_DEV_ADDR_LEN]; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + uint8_t init_phy_mask; +#endif + struct { + uint16_t itvl; + uint16_t window; + } scan_params[2]; +}; + +struct ble_ll_conn_create_params { + uint32_t conn_itvl; + uint32_t conn_itvl_ticks; + uint8_t conn_itvl_usecs; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_ce_len; + uint16_t max_ce_len; +}; + +struct ble_ll_conn_create_sm { + struct ble_ll_conn_sm *connsm; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + struct ble_ll_conn_create_params params[3]; +#endif +}; + +extern struct ble_ll_conn_create_sm g_ble_ll_conn_create_sm; /* Generic interface */ struct ble_ll_len_req; @@ -123,15 +153,8 @@ void ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm *connsm, struct os_mbuf *om, uint8_t hdr_byte, uint16_t length); struct ble_ll_conn_sm *ble_ll_conn_sm_get(void); void ble_ll_conn_master_init(struct ble_ll_conn_sm *connsm, - struct hci_create_conn *hcc); -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -void ble_ll_conn_ext_master_init(struct ble_ll_conn_sm *connsm, - struct hci_ext_create_conn *hcc); - -void ble_ll_conn_ext_set_params(struct ble_ll_conn_sm *connsm, - struct hci_ext_conn_params *hcc_params, - int phy); -#endif + struct ble_ll_conn_create_scan *cc_scan, + struct ble_ll_conn_create_params *cc_params); struct ble_ll_conn_sm *ble_ll_conn_find_active_conn(uint16_t handle); void ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm); @@ -158,7 +181,7 @@ void ble_ll_disconn_comp_event_send(struct ble_ll_conn_sm *connsm, void ble_ll_auth_pyld_tmo_event_send(struct ble_ll_conn_sm *connsm); int ble_ll_conn_hci_disconnect_cmd(const struct ble_hci_lc_disconnect_cp *cmd); int ble_ll_conn_hci_rd_rem_ver_cmd(const uint8_t *cmdbuf, uint8_t len); -int ble_ll_conn_create(const uint8_t *cmdbuf, uint8_t len); +int ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len); int ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len); int ble_ll_conn_hci_set_chan_class(const uint8_t *cmdbuf, uint8_t len); int ble_ll_conn_hci_param_rr(const uint8_t *cmdbuf, uint8_t len, @@ -205,6 +228,9 @@ bool ble_ll_conn_cth_flow_enable(bool enabled); void ble_ll_conn_cth_flow_process_cmd(const uint8_t *cmdbuf); #endif +void ble_ll_conn_itvl_to_ticks(uint32_t itvl, + uint32_t *itvl_ticks, uint8_t *itvl_usecs); + int ble_ll_hci_cmd_rx(uint8_t *cmd, void *arg); int ble_ll_hci_acl_rx(struct os_mbuf *om, void *arg); @@ -213,7 +239,7 @@ int ble_ll_conn_hci_le_rd_phy(const uint8_t *cmdbuf, uint8_t len, int ble_ll_conn_hci_le_set_phy(const uint8_t *cmdbuf, uint8_t len); int ble_ll_conn_chk_phy_upd_start(struct ble_ll_conn_sm *connsm); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -int ble_ll_ext_conn_create(const uint8_t *cmdbuf, uint8_t cmdlen); +int ble_ll_conn_hci_ext_create(const uint8_t *cmdbuf, uint8_t len); #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 7cd3621c6d..547b661594 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -910,7 +910,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, rc = ble_ll_hci_scan_set_enable(cmdbuf, len); break; case BLE_HCI_OCF_LE_CREATE_CONN: - rc = ble_ll_conn_create(cmdbuf, len); + rc = ble_ll_conn_hci_create(cmdbuf, len); break; case BLE_HCI_OCF_LE_CREATE_CONN_CANCEL: if (len == 0) { @@ -1113,7 +1113,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, rc = ble_ll_hci_ext_scan_set_enable(cmdbuf, len); break; case BLE_HCI_OCF_LE_EXT_CREATE_CONN: - rc = ble_ll_ext_conn_create(cmdbuf, len); + rc = ble_ll_conn_hci_ext_create(cmdbuf, len); break; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) diff --git a/nimble/controller/src/ble_ll_resolv.c b/nimble/controller/src/ble_ll_resolv.c index 02af93040a..f85e26a8ad 100644 --- a/nimble/controller/src/ble_ll_resolv.c +++ b/nimble/controller/src/ble_ll_resolv.c @@ -57,7 +57,7 @@ ble_ll_is_controller_busy(void) #endif return ble_ll_adv_enabled() || ble_ll_scan_enabled() || - g_ble_ll_conn_create_sm; + g_ble_ll_conn_create_sm.connsm; } /** * Called to determine if a change is allowed to the resolving list at this diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 0d9d36f666..736383197a 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -2411,65 +2411,37 @@ ble_ll_scan_can_chg_whitelist(void) } int -ble_ll_scan_initiator_start(struct hci_create_conn *hcc, - struct ble_ll_conn_sm *connsm) -{ - struct ble_ll_scan_sm *scansm; - struct ble_ll_scan_phy *scanp; - int rc; - - scansm = &g_ble_ll_scan_sm; - scansm->own_addr_type = hcc->own_addr_type; - scansm->scan_filt_policy = hcc->filter_policy; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - scansm->ext_scanning = 0; -#endif - scansm->connsm = connsm; - - scansm->scanp = &scansm->scan_phys[PHY_UNCODED]; - scansm->scanp_next = NULL; - - scanp = scansm->scanp; - scanp->timing.interval = ble_ll_scan_time_hci_to_ticks(hcc->scan_itvl); - scanp->timing.window = ble_ll_scan_time_hci_to_ticks(hcc->scan_window); - scanp->scan_type = BLE_SCAN_TYPE_INITIATE; - scanp->configured = 1; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - scanp = &scansm->scan_phys[PHY_CODED]; - scanp->configured = 0; -#endif - - rc = ble_ll_scan_sm_start(scansm); - - return rc; -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -int -ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, - struct ble_ll_conn_sm *connsm) +ble_ll_scan_initiator_start(struct ble_ll_conn_sm *connsm, uint8_t ext, + struct ble_ll_conn_create_scan *cc_scan) { struct ble_ll_scan_sm *scansm; struct ble_ll_scan_phy *scanp_uncoded; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) struct ble_ll_scan_phy *scanp_coded; - struct hci_ext_conn_params *params; +#endif + uint8_t init_phy_mask; int rc; scansm = &g_ble_ll_scan_sm; - scansm->own_addr_type = hcc->own_addr_type; - scansm->scan_filt_policy = hcc->filter_policy; + scansm->own_addr_type = cc_scan->own_addr_type; + scansm->scan_filt_policy = cc_scan->filter_policy; scansm->scanp = NULL; scansm->scanp_next = NULL; - scansm->ext_scanning = 1; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + scansm->ext_scanning = ext; + init_phy_mask = cc_scan->init_phy_mask; +#else + init_phy_mask = BLE_PHY_MASK_1M; +#endif scansm->connsm = connsm; - params = &hcc->params[0]; scanp_uncoded = &scansm->scan_phys[PHY_UNCODED]; - if (hcc->init_phy_mask & BLE_PHY_MASK_1M) { + if (init_phy_mask & BLE_PHY_MASK_1M) { scanp_uncoded->configured = 1; - scanp_uncoded->timing.interval = ble_ll_scan_time_hci_to_ticks(params->scan_itvl); - scanp_uncoded->timing.window = ble_ll_scan_time_hci_to_ticks(params->scan_window); + scanp_uncoded->timing.interval = ble_ll_scan_time_hci_to_ticks( + cc_scan->scan_params[PHY_UNCODED].itvl); + scanp_uncoded->timing.window = ble_ll_scan_time_hci_to_ticks( + cc_scan->scan_params[PHY_UNCODED].window); scanp_uncoded->scan_type = BLE_SCAN_TYPE_INITIATE; scansm->scanp = scanp_uncoded; } else { @@ -2477,12 +2449,13 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - params = &hcc->params[2]; scanp_coded = &scansm->scan_phys[PHY_CODED]; - if (hcc->init_phy_mask & BLE_PHY_MASK_CODED) { + if (init_phy_mask & BLE_PHY_MASK_CODED) { scanp_coded->configured = 1; - scanp_coded->timing.interval = ble_ll_scan_time_hci_to_ticks(params->scan_itvl); - scanp_coded->timing.window = ble_ll_scan_time_hci_to_ticks(params->scan_window); + scanp_coded->timing.interval = ble_ll_scan_time_hci_to_ticks( + cc_scan->scan_params[PHY_CODED].itvl); + scanp_coded->timing.window = ble_ll_scan_time_hci_to_ticks( + cc_scan->scan_params[PHY_CODED].window); scanp_coded->scan_type = BLE_SCAN_TYPE_INITIATE; if (scansm->scanp) { scansm->scanp_next = scanp_coded; @@ -2492,9 +2465,6 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, } else { scanp_coded->configured = 0; } -#else - scanp_coded = NULL; -#endif /* if any of PHYs is configured for continuous scan we alter interval to * fit other PHY @@ -2509,12 +2479,15 @@ ble_ll_scan_ext_initiator_start(struct hci_ext_create_conn *hcc, scanp_uncoded->timing.interval += scanp_coded->timing.window; } } +#endif rc = ble_ll_scan_sm_start(scansm); + if (rc == 0) { + g_ble_ll_conn_create_sm.connsm = connsm; + } return rc; } -#endif /** * Checks to see if the scanner is enabled. From 9f8fab797bc491a5cf8e406b4f0a156912cdaa3a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 21 Oct 2021 17:05:49 +0200 Subject: [PATCH 0038/1333] nimble/ll: Remove redundant variable in local scope --- nimble/controller/src/ble_ll_conn.c | 1 - 1 file changed, 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index eb61414f2c..4456eb77b7 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2080,7 +2080,6 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) connsm->anchor_point += connsm->conn_itvl_ticks; connsm->anchor_point_usecs += connsm->conn_itvl_usecs; } else { - uint32_t ticks; ticks = os_cputime_usecs_to_ticks(itvl); connsm->anchor_point += ticks; connsm->anchor_point_usecs += (itvl - os_cputime_ticks_to_usecs(ticks)); From 12cd822cfa11c719efed339db4eea25b52210b3d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 21 Oct 2021 17:06:22 +0200 Subject: [PATCH 0039/1333] nimble/ll: Remove unused #includes --- nimble/controller/src/ble_ll_conn.c | 3 --- nimble/controller/src/ble_ll_conn_hci.c | 1 - 2 files changed, 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 4456eb77b7..53b717c5da 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -25,10 +25,8 @@ #include "os/os.h" #include "os/os_cputime.h" #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" #include "controller/ble_ll_scan.h" @@ -40,7 +38,6 @@ #include "controller/ble_ll_trace.h" #include "controller/ble_ll_rfmgmt.h" #include "controller/ble_phy.h" -#include "controller/ble_hw.h" #include "controller/ble_ll_utils.h" #include "ble_ll_conn_priv.h" diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index decc4851f0..17be064622 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -23,7 +23,6 @@ #include "syscfg/syscfg.h" #include "os/os.h" #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" From dc47bc58577b34cca71140ce21e54a80210459dd Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 21 Oct 2021 17:07:21 +0200 Subject: [PATCH 0040/1333] nimble/ll: Remove unused #defines --- nimble/controller/include/controller/ble_ll_conn.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 0de54afb3d..207d27eded 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -45,16 +45,6 @@ extern "C" { /* Channel map size */ #define BLE_LL_CONN_CHMAP_LEN (5) -/* Definitions for source clock accuracy */ -#define BLE_MASTER_SCA_251_500_PPM (0) -#define BLE_MASTER_SCA_151_250_PPM (1) -#define BLE_MASTER_SCA_101_150_PPM (2) -#define BLE_MASTER_SCA_76_100_PPM (3) -#define BLE_MASTER_SCA_51_75_PPM (4) -#define BLE_MASTER_SCA_31_50_PPM (5) -#define BLE_MASTER_SCA_21_30_PPM (6) -#define BLE_MASTER_SCA_0_20_PPM (7) - /* Definition for RSSI when the RSSI is unknown */ #define BLE_LL_CONN_UNKNOWN_RSSI (127) From 868881bc892bb175c1c41c0b54c0bb86204c39d1 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 21 Oct 2021 17:10:52 +0200 Subject: [PATCH 0041/1333] nimble/ll: Remove max_tx_octets_phy_mode from connsm This is never accessed so looks like we do not need it (anymore)... --- .../include/controller/ble_ll_conn.h | 1 - nimble/controller/src/ble_ll_conn.c | 23 ------------------- 2 files changed, 24 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 207d27eded..7128dcb966 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -205,7 +205,6 @@ struct ble_ll_conn_sm uint16_t rem_max_rx_time; uint16_t eff_max_tx_time; uint16_t eff_max_rx_time; - uint8_t max_tx_octets_phy_mode[BLE_PHY_NUM_MODE]; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) uint16_t host_req_max_tx_time; #endif diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 53b717c5da..08bc1fca27 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1591,23 +1591,6 @@ ble_ll_conn_master_init(struct ble_ll_conn_sm *connsm, connsm->max_ce_len = cc_params->max_ce_len; } -static void -ble_ll_update_max_tx_octets_phy_mode(struct ble_ll_conn_sm *connsm) -{ - uint32_t usecs; - - usecs = connsm->eff_max_tx_time; - - connsm->max_tx_octets_phy_mode[BLE_PHY_MODE_1M] = - ble_ll_pdu_max_tx_octets_get(usecs, BLE_PHY_MODE_1M); - connsm->max_tx_octets_phy_mode[BLE_PHY_MODE_2M] = - ble_ll_pdu_max_tx_octets_get(usecs, BLE_PHY_MODE_2M); - connsm->max_tx_octets_phy_mode[BLE_PHY_MODE_CODED_125KBPS] = - ble_ll_pdu_max_tx_octets_get(usecs, BLE_PHY_MODE_CODED_125KBPS); - connsm->max_tx_octets_phy_mode[BLE_PHY_MODE_CODED_500KBPS] = - ble_ll_pdu_max_tx_octets_get(usecs, BLE_PHY_MODE_CODED_500KBPS); -} - #if (BLE_LL_BT5_PHY_SUPPORTED == 1) static void @@ -1657,8 +1640,6 @@ ble_ll_conn_init_phy(struct ble_ll_conn_sm *connsm, int phy) connsm->rem_max_rx_octets = BLE_LL_CONN_SUPP_BYTES_MIN; connsm->eff_max_tx_octets = BLE_LL_CONN_SUPP_BYTES_MIN; connsm->eff_max_rx_octets = BLE_LL_CONN_SUPP_BYTES_MIN; - - ble_ll_update_max_tx_octets_phy_mode(connsm); } #endif @@ -1791,8 +1772,6 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) connsm->host_req_max_tx_time = 0; #endif - ble_ll_update_max_tx_octets_phy_mode(connsm); - /* Reset encryption data */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) memset(&connsm->enc_data, 0, sizeof(struct ble_ll_conn_enc_data)); @@ -1842,8 +1821,6 @@ ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm) if (eff_time != connsm->eff_max_tx_time) { connsm->eff_max_tx_time = eff_time; send_event = 1; - - ble_ll_update_max_tx_octets_phy_mode(connsm); } eff_bytes = min(connsm->rem_max_tx_octets, connsm->max_rx_octets); if (eff_bytes != connsm->eff_max_rx_octets) { From da46f181fcb568e6156bc1ddc438a67e28a6f5d0 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 21 Oct 2021 19:50:03 +0200 Subject: [PATCH 0042/1333] nimble/ll: Use common helper for conn params check Turns out we already have one, so let's use it in new code. --- nimble/controller/src/ble_ll_conn_hci.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 17be064622..7e47377381 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -435,23 +435,13 @@ ble_ll_conn_hci_create_check_scan(struct ble_ll_conn_create_scan *p) static int ble_ll_conn_hci_create_check_params(struct ble_ll_conn_create_params *cc_params) { - uint32_t supervision_tmo_us; - uint32_t conn_itvl_us; - - if ((cc_params->conn_itvl < BLE_HCI_CONN_ITVL_MIN) || - (cc_params->conn_itvl > BLE_HCI_CONN_ITVL_MAX) || - (cc_params->conn_latency > BLE_HCI_CONN_LATENCY_MAX) || - (cc_params->supervision_timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN) || - (cc_params->supervision_timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Supervision timeout must be longer than (1 + latency) * interval * 2 */ - supervision_tmo_us = cc_params->supervision_timeout * - BLE_HCI_CONN_SPVN_TMO_UNITS * 1000; - conn_itvl_us = cc_params->conn_itvl * BLE_LL_CONN_ITVL_USECS; + int rc; - if (supervision_tmo_us <= (1 + cc_params->conn_latency) * conn_itvl_us * 2) { + rc = ble_ll_conn_hci_chk_conn_params(cc_params->conn_itvl, + cc_params->conn_itvl, + cc_params->conn_latency, + cc_params->supervision_timeout); + if (rc) { return BLE_ERR_INV_HCI_CMD_PARMS; } From 971633179581faff002d906c7a5d0e168b4236cd Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Thu, 28 Oct 2021 15:37:54 +0200 Subject: [PATCH 0043/1333] nimble/host/include/host/ble_gap: add ble_gap_ext_adv_active() --- nimble/host/include/host/ble_gap.h | 12 ++++++++++++ nimble/host/src/ble_gap.c | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index fa7ee562df..af9c978bcc 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -1314,6 +1314,18 @@ int ble_gap_ext_adv_remove(uint8_t instance); * other error code on failure. */ int ble_gap_ext_adv_clear(void); + +/** + * Indicates whether an advertisement procedure is currently in progress on + * the specified Instance + * + * @param instance Instance Id + * + * @return 0 if there is no active advertising procedure for the instance, + * 1 otherwise + * + */ +int ble_gap_ext_adv_active(uint8_t instance); #endif /* Periodic Advertising */ diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 3125870fa6..06829142b3 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -1303,6 +1303,16 @@ ble_gap_adv_active_instance(uint8_t instance) } #endif +#if MYNEWT_VAL(BLE_EXT_ADV) +int ble_gap_ext_adv_active(uint8_t instance) +{ + if (instance >= BLE_ADV_INSTANCES) { + return 0; + } + return ble_gap_adv_active_instance(instance); +} +#endif + /** * Clears advertisement and discovery state. This function is necessary * when the controller loses its active state (e.g. on stack reset). From 7f31820ea13c1632b69166477a33b3acd1ff7e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reynir=20Bj=C3=B6rnsson?= Date: Tue, 2 Nov 2021 20:59:52 +0100 Subject: [PATCH 0044/1333] complaint -> compliant --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index b41b1b283e..b07f1f88d0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -46,7 +46,7 @@ ideal wireless technology for the Internet of Things (IoT). - LE Secure Connections featuring FIPS-compliant algorithms. - LE Data Length Extension for higher throughput - **Coming Soon**: Assigning an Internet Protocol (IP) address - (complaint with the IPv6 or 6LoWPAN standard) to a Bluetooth device + (compliant with the IPv6 or 6LoWPAN standard) to a Bluetooth device through Internet Protocol Support Profile (IPSP) The Bluetooth 5 is backward compatible with previous Bluetooth version From 8135e511854e3c665408cbe331e257fd7aa91226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 29 Sep 2021 08:43:39 +0200 Subject: [PATCH 0045/1333] apps/bttester: implement NRPA rotation As per CORE v5.3, Vol 3, Part C 10.7.1 NRPA should also rotate, same as RPA is doing right now. For time beeing let's implement this in tester application, before it's implemented in host. This affects GAP/BROB/BCST/BV-04-C --- apps/bttester/src/gap.c | 48 +++++++++++++++++++++++++++++++++++++++- apps/bttester/syscfg.yml | 4 ++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/apps/bttester/src/gap.c b/apps/bttester/src/gap.c index acac9989f0..63150e2877 100644 --- a/apps/bttester/src/gap.c +++ b/apps/bttester/src/gap.c @@ -63,6 +63,10 @@ static struct os_callout connected_ev_co; static struct gap_device_connected_ev connected_ev; #define CONNECTED_EV_DELAY_MS(itvl) 8 * BLE_HCI_CONN_ITVL * itvl / 1000 static int connection_attempts; +#if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) +static int64_t advertising_start; +static struct os_callout bttester_nrpa_rotate_timer; +#endif static const struct ble_gap_conn_params dflt_conn_params = { .scan_itvl = 0x0010, @@ -248,6 +252,38 @@ static struct ble_gap_adv_params adv_params = { .disc_mode = BLE_GAP_DISC_MODE_NON, }; +#if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) +static void rotate_nrpa_cb(struct os_event *ev) +{ + int rc; + ble_addr_t addr; + int32_t duration_ms = BLE_HS_FOREVER; + int32_t remaining_time; + os_time_t remaining_ticks; + + if (adv_params.disc_mode == BLE_GAP_DISC_MODE_LTD) { + duration_ms = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); + } + + ble_gap_adv_stop(); + rc = ble_hs_id_gen_rnd(1, &addr); + assert(rc == 0); + rc = ble_hs_id_set_rnd(addr.val); + assert(rc == 0); + + ble_gap_adv_start(own_addr_type, NULL, duration_ms, + &adv_params, gap_event_cb, NULL); + + remaining_time = os_get_uptime_usec() - advertising_start; + if (remaining_time > 0) { + advertising_start = os_get_uptime_usec(); + os_time_ms_to_ticks(remaining_time, &remaining_ticks); + os_callout_reset(&bttester_nrpa_rotate_timer, + remaining_ticks); + } +} +#endif + static void set_connectable(uint8_t *data, uint16_t len) { const struct gap_set_connectable_cmd *cmd = (void *) data; @@ -418,6 +454,13 @@ static void start_advertising(const uint8_t *data, uint16_t len) duration_ms = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); } +#if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) + if (MYNEWT_VAL(BTTESTER_NRPA_TIMEOUT) < duration_ms / 1000) { + advertising_start = os_get_uptime_usec(); + os_callout_reset(&bttester_nrpa_rotate_timer, + OS_TICKS_PER_SEC * MYNEWT_VAL(BTTESTER_NRPA_TIMEOUT)); + } +#endif err = ble_gap_adv_start(own_addr_type, NULL, duration_ms, &adv_params, gap_event_cb, NULL); if (err) { @@ -1675,7 +1718,10 @@ uint8_t tester_init_gap(void) return BTP_STATUS_FAILED; } #endif - +#if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) + os_callout_init(&bttester_nrpa_rotate_timer, os_eventq_dflt_get(), + rotate_nrpa_cb, NULL); +#endif adv_buf = NET_BUF_SIMPLE(ADV_BUF_LEN); tester_init_gap_cb(BTP_STATUS_SUCCESS); diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 7f99ded013..f00afeb10f 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -75,6 +75,10 @@ syscfg.defs: description: Maximum MTU size the application can handle value: 230 + BTTESTER_NRPA_TIMEOUT: + description: NRPA rotation timeout in seconds + value: 5 + syscfg.vals: OS_MAIN_STACK_SIZE: 512 SHELL_TASK: 0 From 4f70d00335d70252cd54b8287883d73f1dbbd0c8 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 30 Sep 2021 19:26:05 +0200 Subject: [PATCH 0046/1333] nimble/ll: Fix scan window/interval limits for ext scan Max scan window and interval is different for ext scan, we should allow proper value to be used. Also change func name to have proper prefix and define values to hex values, as defined Core spec. --- nimble/controller/src/ble_ll_scan.c | 10 +++++----- nimble/include/nimble/hci_common.h | 10 ++++++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 736383197a..901bda7c43 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -2028,7 +2028,7 @@ ble_ll_scan_set_scan_params(const uint8_t *cmdbuf, uint8_t len) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) static int -ble_ll_check_scan_params(uint8_t type, uint16_t itvl, uint16_t window) +ble_ll_scan_check_phy_params(uint8_t type, uint16_t itvl, uint16_t window) { /* Check scan type */ if ((type != BLE_HCI_SCAN_TYPE_PASSIVE) && @@ -2038,9 +2038,9 @@ ble_ll_check_scan_params(uint8_t type, uint16_t itvl, uint16_t window) /* Check interval and window */ if ((itvl < BLE_HCI_SCAN_ITVL_MIN) || - (itvl > BLE_HCI_SCAN_ITVL_MAX) || + (itvl > BLE_HCI_SCAN_ITVL_MAX_EXT) || (window < BLE_HCI_SCAN_WINDOW_MIN) || - (window > BLE_HCI_SCAN_WINDOW_MAX) || + (window > BLE_HCI_SCAN_WINDOW_MAX_EXT) || (itvl < window)) { return BLE_ERR_INV_HCI_CMD_PARMS; } @@ -2098,7 +2098,7 @@ ble_ll_set_ext_scan_params(const uint8_t *cmdbuf, uint8_t len) interval = le16toh(params->itvl); window = le16toh(params->window); - rc = ble_ll_check_scan_params(params->type, interval, window); + rc = ble_ll_scan_check_phy_params(params->type, interval, window); if (rc) { return rc; } @@ -2122,7 +2122,7 @@ ble_ll_set_ext_scan_params(const uint8_t *cmdbuf, uint8_t len) interval = le16toh(params->itvl); window = le16toh(params->window); - rc = ble_ll_check_scan_params(params->type, interval, window); + rc = ble_ll_scan_check_phy_params(params->type, interval, window); if (rc) { return rc; } diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 92031c3c16..9acb76238f 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1152,11 +1152,13 @@ struct ble_hci_vs_rd_static_addr_rp { /* Scan interval and scan window timing */ #define BLE_HCI_SCAN_ITVL (625) /* usecs */ -#define BLE_HCI_SCAN_ITVL_MIN (4) /* units */ -#define BLE_HCI_SCAN_ITVL_MAX (16384) /* units */ +#define BLE_HCI_SCAN_ITVL_MIN (0x0004) /* units */ +#define BLE_HCI_SCAN_ITVL_MAX (0x4000) /* units */ +#define BLE_HCI_SCAN_ITVL_MAX_EXT (0xffff) /* units */ #define BLE_HCI_SCAN_ITVL_DEF (16) /* units */ -#define BLE_HCI_SCAN_WINDOW_MIN (4) /* units */ -#define BLE_HCI_SCAN_WINDOW_MAX (16384) /* units */ +#define BLE_HCI_SCAN_WINDOW_MIN (0x0004) /* units */ +#define BLE_HCI_SCAN_WINDOW_MAX (0x4000) /* units */ +#define BLE_HCI_SCAN_WINDOW_MAX_EXT (0xffff) /* units */ #define BLE_HCI_SCAN_WINDOW_DEF (16) /* units */ /* From 7875bc285575ada3e29f47019ba6a2129f4d417f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 30 Sep 2021 19:33:38 +0200 Subject: [PATCH 0047/1333] nimble/ll: Cleanup function names Use common prefix ble_ll_scan_hci for all HCI commands handlers in ble_ll_scan. --- nimble/controller/include/controller/ble_ll_scan.h | 8 ++++---- nimble/controller/src/ble_ll_hci.c | 8 ++++---- nimble/controller/src/ble_ll_scan.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index 04ca48177b..77f9fa4265 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -163,14 +163,14 @@ struct ble_ll_scan_sm /*---- HCI ----*/ /* Set scanning parameters */ -int ble_ll_scan_set_scan_params(const uint8_t *cmdbuf, uint8_t len); +int ble_ll_scan_hci_set_params(const uint8_t *cmdbuf, uint8_t len); /* Turn scanning on/off */ -int ble_ll_hci_scan_set_enable(const uint8_t *cmdbuf, uint8_t len); -int ble_ll_hci_ext_scan_set_enable(const uint8_t *cmdbuf, uint8_t len); +int ble_ll_scan_hci_set_enable(const uint8_t *cmdbuf, uint8_t len); +int ble_ll_scan_hci_set_ext_enable(const uint8_t *cmdbuf, uint8_t len); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -int ble_ll_set_ext_scan_params(const uint8_t *cmdbuf, uint8_t len); +int ble_ll_scan_hci_set_ext_params(const uint8_t *cmdbuf, uint8_t len); #endif /*--- Controller Internal API ---*/ diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 547b661594..c2603c989d 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -904,10 +904,10 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, rc = ble_ll_hci_adv_set_enable(cmdbuf, len); break; case BLE_HCI_OCF_LE_SET_SCAN_PARAMS: - rc = ble_ll_scan_set_scan_params(cmdbuf, len); + rc = ble_ll_scan_hci_set_params(cmdbuf, len); break; case BLE_HCI_OCF_LE_SET_SCAN_ENABLE: - rc = ble_ll_hci_scan_set_enable(cmdbuf, len); + rc = ble_ll_scan_hci_set_enable(cmdbuf, len); break; case BLE_HCI_OCF_LE_CREATE_CONN: rc = ble_ll_conn_hci_create(cmdbuf, len); @@ -1107,10 +1107,10 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) case BLE_HCI_OCF_LE_SET_EXT_SCAN_PARAM: - rc = ble_ll_set_ext_scan_params(cmdbuf, len); + rc = ble_ll_scan_hci_set_ext_params(cmdbuf, len); break; case BLE_HCI_OCF_LE_SET_EXT_SCAN_ENABLE: - rc = ble_ll_hci_ext_scan_set_enable(cmdbuf, len); + rc = ble_ll_scan_hci_set_ext_enable(cmdbuf, len); break; case BLE_HCI_OCF_LE_EXT_CREATE_CONN: rc = ble_ll_conn_hci_ext_create(cmdbuf, len); diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 901bda7c43..8539257c2a 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1961,7 +1961,7 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd } int -ble_ll_scan_set_scan_params(const uint8_t *cmdbuf, uint8_t len) +ble_ll_scan_hci_set_params(const uint8_t *cmdbuf, uint8_t len) { const struct ble_hci_le_set_scan_params_cp *cmd = (const void *)cmdbuf; uint16_t scan_itvl; @@ -2049,7 +2049,7 @@ ble_ll_scan_check_phy_params(uint8_t type, uint16_t itvl, uint16_t window) } int -ble_ll_set_ext_scan_params(const uint8_t *cmdbuf, uint8_t len) +ble_ll_scan_hci_set_ext_params(const uint8_t *cmdbuf, uint8_t len) { const struct ble_hci_le_set_ext_scan_params_cp *cmd = (const void *) cmdbuf; const struct scan_params *params = cmd->scans; @@ -2361,7 +2361,7 @@ ble_ll_scan_set_enable(uint8_t enable, uint8_t filter_dups, uint16_t period, return rc; } -int ble_ll_hci_scan_set_enable(const uint8_t *cmdbuf, uint8_t len) +int ble_ll_scan_hci_set_enable(const uint8_t *cmdbuf, uint8_t len) { const struct ble_hci_le_set_scan_enable_cp *cmd = (const void *) cmdbuf; @@ -2374,7 +2374,7 @@ int ble_ll_hci_scan_set_enable(const uint8_t *cmdbuf, uint8_t len) } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -int ble_ll_hci_ext_scan_set_enable(const uint8_t *cmdbuf, uint8_t len) +int ble_ll_scan_hci_set_ext_enable(const uint8_t *cmdbuf, uint8_t len) { const struct ble_hci_le_set_ext_scan_enable_cp *cmd = (const void *) cmdbuf; From 9559689bc076bb1a46be78f56a7c302609324b22 Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Thu, 23 Sep 2021 06:29:19 +1000 Subject: [PATCH 0048/1333] nimble: Fix a few types in many places --- apps/blecsc/src/main.c | 2 +- docs/btshell/btshell_GAP.rst | 2 +- nimble/controller/src/ble_ll_adv.c | 2 +- nimble/controller/src/ble_ll_conn.c | 4 ++-- nimble/drivers/nrf51/src/ble_phy.c | 4 ++-- nimble/drivers/nrf52/src/ble_phy.c | 2 +- nimble/host/mesh/src/pb_adv.c | 2 +- nimble/host/mesh/src/subnet.h | 2 +- nimble/host/src/ble_att_svr.c | 2 +- nimble/host/src/ble_gap.c | 2 +- nimble/host/src/ble_sm_lgcy.c | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/apps/blecsc/src/main.c b/apps/blecsc/src/main.c index 60f0b3d8f7..5cca6b77ec 100644 --- a/apps/blecsc/src/main.c +++ b/apps/blecsc/src/main.c @@ -58,7 +58,7 @@ static struct os_callout blecsc_measure_timer; /* Variable holds current CSC measurement state */ static struct ble_csc_measurement_state csc_measurement_state; -/* Variable holds simulted speed (kilometers per hour) */ +/* Variable holds simulated speed (kilometers per hour) */ static uint16_t csc_sim_speed_kph = CSC_SIM_SPEED_KPH_MIN; /* Variable holds simulated cadence (RPM) */ diff --git a/docs/btshell/btshell_GAP.rst b/docs/btshell/btshell_GAP.rst index ce6475554d..738d146c5b 100644 --- a/docs/btshell/btshell_GAP.rst +++ b/docs/btshell/btshell_GAP.rst @@ -411,7 +411,7 @@ Advertising with Extended Advertising enabled +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ | | scan\_req\_notif | [``0``-1] | Enable SCAN\_REQ notifications | +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| **advertise-set-addr** | | | Configure *random* adress for instance | +| **advertise-set-addr** | | | Configure *random* address for instance | +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ | | instance | [``0``-UINT8\_MAX] | Advertising instance | +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 19270accde..88c4ae12b1 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -4479,7 +4479,7 @@ ble_ll_adv_rx_pkt_in(uint8_t ptype, uint8_t *rxbuf, struct ble_mbuf_hdr *hdr) #endif /* - * It is possible that advertising was stopped and a packet plcaed on the + * It is possible that advertising was stopped and a packet placed on the * LL receive packet queue. In this case, just ignore the received packet * as the advertising state machine is no longer "valid" */ diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 08bc1fca27..55ca20e900 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3163,7 +3163,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) /* * Check the packet CRC. A connection event can continue even if the * received PDU does not pass the CRC check. If we receive two consecutive - * CRC errors we end the conection event. + * CRC errors we end the connection event. */ if (!BLE_MBUF_HDR_CRC_OK(rxhdr)) { /* @@ -3753,7 +3753,7 @@ ble_ll_conn_module_init(void) uint16_t i; struct ble_ll_conn_sm *connsm; - /* Initialize list of active conections */ + /* Initialize list of active connections */ SLIST_INIT(&g_ble_ll_conn_active_list); STAILQ_INIT(&g_ble_ll_conn_free_list); diff --git a/nimble/drivers/nrf51/src/ble_phy.c b/nimble/drivers/nrf51/src/ble_phy.c index b7e6329721..d3bc3c2ecc 100644 --- a/nimble/drivers/nrf51/src/ble_phy.c +++ b/nimble/drivers/nrf51/src/ble_phy.c @@ -408,7 +408,7 @@ ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs) /** * Function is used to set PPI so that we can time out waiting for a reception * to occur. This happens for two reasons: we have sent a packet and we are - * waiting for a respons (txrx should be set to ENABLE_TXRX) or we are + * waiting for a response (txrx should be set to ENABLE_TXRX) or we are * starting a connection event and we are a slave and we are waiting for the * master to send us a packet (txrx should be set to ENABLE_RX). * @@ -1357,7 +1357,7 @@ ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit) NRF_RADIO->RXADDRESSES = (1 << 1); NRF_RADIO->CRCINIT = crcinit; } else { - /* Logical adddress 0 preconfigured */ + /* Logical address 0 preconfigured */ NRF_RADIO->TXADDRESS = 0; NRF_RADIO->RXADDRESSES = (1 << 0); NRF_RADIO->CRCINIT = BLE_LL_CRCINIT_ADV; diff --git a/nimble/drivers/nrf52/src/ble_phy.c b/nimble/drivers/nrf52/src/ble_phy.c index 2f6ce08e72..6c520ab8b8 100644 --- a/nimble/drivers/nrf52/src/ble_phy.c +++ b/nimble/drivers/nrf52/src/ble_phy.c @@ -669,7 +669,7 @@ ble_phy_set_start_now(void) /** * Function is used to set PPI so that we can time out waiting for a reception * to occur. This happens for two reasons: we have sent a packet and we are - * waiting for a respons (txrx should be set to ENABLE_TXRX) or we are + * waiting for a response (txrx should be set to ENABLE_TXRX) or we are * starting a connection event and we are a slave and we are waiting for the * master to send us a packet (txrx should be set to ENABLE_RX). * diff --git a/nimble/host/mesh/src/pb_adv.c b/nimble/host/mesh/src/pb_adv.c index 653ec03fa9..50b8419e10 100644 --- a/nimble/host/mesh/src/pb_adv.c +++ b/nimble/host/mesh/src/pb_adv.c @@ -845,7 +845,7 @@ static int prov_link_accept(const struct prov_bearer_cb *cb, void *cb_data) link.cb = cb; link.cb_data = cb_data; - /* Make sure we're scanning for provisioning inviations */ + /* Make sure we're scanning for provisioning invitations */ bt_mesh_scan_enable(); /* Enable unprovisioned beacon sending */ bt_mesh_beacon_enable(); diff --git a/nimble/host/mesh/src/subnet.h b/nimble/host/mesh/src/subnet.h index 154b5d4e31..7a82999789 100644 --- a/nimble/host/mesh/src/subnet.h +++ b/nimble/host/mesh/src/subnet.h @@ -37,7 +37,7 @@ struct bt_mesh_subnet { uint8_t beacons_last; /* Number of beacons during last * observation window */ - uint8_t beacons_cur; /* Number of beaconds observed during + uint8_t beacons_cur; /* Number of beacons observed during * currently ongoing window. */ diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 4fdf27e843..9af0e0d043 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -30,7 +30,7 @@ * ATT server - Attribute Protocol * * Notes on buffer reuse: - * Most request handlers reuse the request buffer for the reponse. This is + * Most request handlers reuse the request buffer for the response. This is * done to prevent out-of-memory conditions. However, there are two handlers * which do not reuse the request buffer: * 1. Write request. diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 06829142b3..8f7e5ca60a 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -5784,7 +5784,7 @@ ble_gap_enc_event(uint16_t conn_handle, int status, return; } - /* If encryption succeded and encryption has been restored for bonded device, + /* If encryption succeeded and encryption has been restored for bonded device, * notify gatt server so it has chance to send notification/indication if needed. */ if (security_restored) { diff --git a/nimble/host/src/ble_sm_lgcy.c b/nimble/host/src/ble_sm_lgcy.c index 0259ff4682..1a500fb746 100644 --- a/nimble/host/src/ble_sm_lgcy.c +++ b/nimble/host/src/ble_sm_lgcy.c @@ -36,7 +36,7 @@ #define IOACT_INPUT BLE_SM_IOACT_INPUT #define IOACT_DISP BLE_SM_IOACT_DISP -/* This is the initiator passkey action action dpeneding on the io +/* This is the initiator passkey action action depending on the io * capabilties of both parties */ static const uint8_t ble_sm_lgcy_init_ioa[5 /*resp*/ ][5 /*init*/ ] = From b67d108e943b6359512338d8f8bd12366dd006b2 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 4 Oct 2021 14:01:44 +0200 Subject: [PATCH 0049/1333] nimble/ll: Fix return values from scheduler callbacks Make sure we use 'running' and 'done' properly. This did not matter so far since return value from sched_cb is not used anywhere, but this is going to change. --- nimble/controller/src/ble_ll_dtm.c | 5 +++-- nimble/controller/src/ble_ll_scan_aux.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index de3b168b22..8c9167799a 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -261,7 +261,7 @@ ble_ll_dtm_tx_sched_cb(struct ble_ll_sched_item *sch) ble_ll_state_set(BLE_LL_STATE_DTM); - return BLE_LL_SCHED_STATE_DONE; + return BLE_LL_SCHED_STATE_RUNNING; resched: /* Reschedule from LL task if late for this PDU */ @@ -427,9 +427,10 @@ ble_ll_dtm_rx_sched_cb(struct ble_ll_sched_item *sch) if (ble_ll_dtm_rx_start() != 0) { ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_dtm_ctx.evt); STATS_INC(ble_ll_dtm_stats, rx_failed); + return BLE_LL_SCHED_STATE_DONE; } - return BLE_LL_SCHED_STATE_DONE; + return BLE_LL_SCHED_STATE_RUNNING; } static int diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 94f776df9b..a521679a20 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -163,7 +163,7 @@ ble_ll_scan_aux_sched_cb(struct ble_ll_sched_item *sch) ble_ll_state_set(BLE_LL_STATE_SCAN_AUX); - return BLE_LL_SCHED_STATE_DONE; + return BLE_LL_SCHED_STATE_RUNNING; } static struct ble_ll_scan_aux_data * From 7f63bd094e0ae5a3596b36fc9a116c1bf52330fb Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 6 Oct 2021 09:58:16 +0200 Subject: [PATCH 0050/1333] nimble/ll: Optimize sched restart When sched_q head changed we only should stop sched timer to make sure it does not fire after we leave critical section and we can restart it then without need for additional locking. We do not need to change rfmgmt because in case new sched_q head is later then previous one, rfmgmt will fire too early and we'll either disable it immediately on restart or keep it enabled for upcoming item, depending on timing. --- nimble/controller/src/ble_ll_sched.c | 31 ++++++++++++++++++---------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 03dea23a73..7a2e6f3a1c 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -37,7 +37,6 @@ #define BLE_LL_SCHED_MAX_DELAY_ANY (0x7fffffff) static struct hal_timer g_ble_ll_sched_timer; -static uint8_t g_ble_ll_sched_timer_running; uint8_t g_ble_ll_sched_offset_ticks; @@ -63,6 +62,7 @@ typedef int (* ble_ll_sched_preempt_cb_t)(struct ble_ll_sched_item *sch, /* Queue for timers */ static TAILQ_HEAD(ll_sched_qhead, ble_ll_sched_item) g_ble_ll_sched_q; +static uint8_t g_ble_ll_sched_q_head_changed; #if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) struct ble_ll_sched_obj g_ble_ll_sched_data; @@ -155,13 +155,13 @@ ble_ll_sched_preempt(struct ble_ll_sched_item *sch, static inline void ble_ll_sched_q_head_changed(void) { - struct ble_ll_sched_item *first; + if (g_ble_ll_sched_q_head_changed) { + return; + } - g_ble_ll_sched_timer_running = 0; - os_cputime_timer_stop(&g_ble_ll_sched_timer); + g_ble_ll_sched_q_head_changed = 1; - first = TAILQ_FIRST(&g_ble_ll_sched_q); - ble_ll_rfmgmt_sched_changed(first); + os_cputime_timer_stop(&g_ble_ll_sched_timer); } static inline void @@ -169,10 +169,17 @@ ble_ll_sched_restart(void) { struct ble_ll_sched_item *first; + if (!g_ble_ll_sched_q_head_changed) { + return; + } + + g_ble_ll_sched_q_head_changed = 0; + first = TAILQ_FIRST(&g_ble_ll_sched_q); - if (!g_ble_ll_sched_timer_running && first) { - g_ble_ll_sched_timer_running = 1; + ble_ll_rfmgmt_sched_changed(first); + + if (first) { os_cputime_timer_start(&g_ble_ll_sched_timer, first->start_time); } } @@ -1182,8 +1189,6 @@ ble_ll_sched_run(void *arg) BLE_LL_DEBUG_GPIO(SCHED_RUN, 1); - g_ble_ll_sched_timer_running = 0; - /* Look through schedule queue */ sch = TAILQ_FIRST(&g_ble_ll_sched_q); if (sch) { @@ -1203,7 +1208,10 @@ ble_ll_sched_run(void *arg) /* Remove schedule item and execute the callback */ TAILQ_REMOVE(&g_ble_ll_sched_q, sch, link); sch->enqueued = 0; + g_ble_ll_sched_q_head_changed = 1; + ble_ll_sched_execute_item(sch); + ble_ll_sched_restart(); } @@ -1295,7 +1303,6 @@ int ble_ll_sched_dtm(struct ble_ll_sched_item *sch) void ble_ll_sched_stop(void) { - g_ble_ll_sched_timer_running = 0; os_cputime_timer_stop(&g_ble_ll_sched_timer); } @@ -1338,5 +1345,7 @@ ble_ll_sched_init(void) g_ble_ll_sched_data.sch_ticks_per_period; #endif + g_ble_ll_sched_q_head_changed = 0; + return 0; } From ed4563741cf75353105fa6ae42a997343b1152ad Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 3 Nov 2021 13:36:34 +0100 Subject: [PATCH 0051/1333] nimble/ll: Add fast path for aux chain scheduling For short aux offsets we can to usecs to ticks conversion using only 32-bit arithmetics without integer division. This is much faster than generic routine, especially on M0 (e.g. CMAC) which does not have hw support for integer division. The faster calculation is even more accurate than generic one since it's never off by 1 tick. This is a temporary solution until we have more generic timer routines that do the same kind of optimizations. --- nimble/controller/src/ble_ll_sched.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 7a2e6f3a1c..5217557851 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -786,6 +786,22 @@ ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm) return rc; } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +static inline uint32_t +usecs_to_ticks_fast(uint32_t usecs) +{ + uint32_t ticks; + + if (usecs <= 31249) { + ticks = (usecs * 137439) / 4194304; + } else { + ticks = os_cputime_usecs_to_ticks(usecs); + } + + return ticks; +} +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) /* * Determines if the schedule item overlaps the currently running schedule @@ -887,7 +903,7 @@ ble_ll_sched_sync(struct ble_ll_sched_item *sch, os_sr_t sr; int rc = 0; - off_ticks = os_cputime_usecs_to_ticks(offset); + off_ticks = usecs_to_ticks_fast(offset); off_rem_usecs = offset - os_cputime_ticks_to_usecs(off_ticks); start_time = beg_cputime + off_ticks; @@ -899,7 +915,7 @@ ble_ll_sched_sync(struct ble_ll_sched_item *sch, dur = ble_ll_pdu_tx_time_get(MYNEWT_VAL(BLE_LL_SCHED_SCAN_SYNC_PDU_LEN), phy_mode); - end_time = start_time + os_cputime_usecs_to_ticks(dur); + end_time = start_time + usecs_to_ticks_fast(dur); start_time -= g_ble_ll_sched_offset_ticks; @@ -1257,12 +1273,12 @@ ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time, int rc; offset_us += pdu_time_rem; - offset_ticks = os_cputime_usecs_to_ticks(offset_us); + offset_ticks = usecs_to_ticks_fast(offset_us); sch->start_time = pdu_time + offset_ticks - g_ble_ll_sched_offset_ticks; sch->remainder = offset_us - os_cputime_ticks_to_usecs(offset_ticks); /* TODO: make some sane slot reservation */ - sch->end_time = sch->start_time + os_cputime_usecs_to_ticks(5000); + sch->end_time = sch->start_time + usecs_to_ticks_fast(5000); OS_ENTER_CRITICAL(sr); From 5271e1f95586f479fd546fe5ed3acdc920951c3c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 2 Nov 2021 17:32:20 +0100 Subject: [PATCH 0052/1333] nimble/ll: Add debugging for sched active item This replaces sched_item_cb debug GPIO with sched_item that is set to high state for the entire duration of sched item active time, i.e. from sched run to LL standby. Note that sched_item_cb debugging is not that useful since it's almost the same as sched_run, so we better replace it instead of keeping both to avoid syscfg clutter. --- nimble/controller/src/ble_ll.c | 5 +++++ nimble/controller/src/ble_ll_sched.c | 9 ++++++--- nimble/controller/syscfg.yml | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 014f7e2809..1a8e4622c3 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -45,6 +45,7 @@ #include "controller/ble_ll_trace.h" #include "controller/ble_ll_sync.h" #include "ble_ll_conn_priv.h" +#include "ble_ll_priv.h" #if MYNEWT_VAL(BLE_LL_DTM) #include "ble_ll_dtm_priv.h" @@ -1241,6 +1242,10 @@ void ble_ll_state_set(uint8_t ll_state) { g_ble_ll_data.ll_state = ll_state; + + if (ll_state == BLE_LL_STATE_STANDBY) { + BLE_LL_DEBUG_GPIO(SCHED_ITEM, 0); + } } /** diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 5217557851..0a9be9c8ae 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -1183,11 +1183,14 @@ ble_ll_sched_execute_item(struct ble_ll_sched_item *sch) } sched: - BLE_LL_DEBUG_GPIO(SCHED_ITEM_CB, 1); BLE_LL_ASSERT(sch->sched_cb); + BLE_LL_DEBUG_GPIO(SCHED_ITEM, 1); rc = sch->sched_cb(sch); - BLE_LL_DEBUG_GPIO(SCHED_ITEM_CB, 0); + if (rc != BLE_LL_SCHED_STATE_RUNNING) { + BLE_LL_DEBUG_GPIO(SCHED_ITEM, 0); + } + return rc; } @@ -1331,7 +1334,7 @@ ble_ll_sched_stop(void) int ble_ll_sched_init(void) { - BLE_LL_DEBUG_GPIO_INIT(SCHED_ITEM_CB); + BLE_LL_DEBUG_GPIO_INIT(SCHED_ITEM); BLE_LL_DEBUG_GPIO_INIT(SCHED_RUN); /* diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index b1fb6b1fb9..13b6780c1b 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -367,10 +367,10 @@ syscfg.defs: GPIO pin number to debug scheduler running (on timer). Pin is set to high state while scheduler is running. value: -1 - BLE_LL_DEBUG_GPIO_SCHED_ITEM_CB: + BLE_LL_DEBUG_GPIO_SCHED_ITEM: description: > GPIO pin number to debug scheduler item execution times. Pin is set - to high state while item is executed. + to high state while item is active. value: -1 BLE_LL_DEBUG_GPIO_RFMGMT: description: > From 5cb95b3951e53c1975c7eb5be52ac9b8ec959754 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 3 Nov 2021 13:38:17 +0100 Subject: [PATCH 0053/1333] nimble/ll: Use get_le24 to read AuxPtr No need to read more bytes and discard bits, we have helper that reads exactly 24 bits :) --- nimble/controller/src/ble_ll_sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index f121c286b0..e4ca5edd80 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -863,7 +863,7 @@ static void ble_ll_sync_parse_aux_ptr(const uint8_t *buf, uint8_t *chan, uint32_t *offset, uint8_t *offset_units, uint8_t *phy) { - uint32_t aux_ptr_field = get_le32(buf) & 0x00FFFFFF; + uint32_t aux_ptr_field = get_le24(buf); *chan = aux_ptr_field & 0x3F; From 47cabcd893bdcb98842190911ff31fad0658a57e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 3 Nov 2021 13:44:45 +0100 Subject: [PATCH 0054/1333] nimble/ll: Remove magic number --- nimble/controller/src/ble_ll_sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index e4ca5edd80..4b2004953d 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -581,7 +581,7 @@ ble_ll_sync_parse_ext_hdr(struct os_mbuf *om, uint8_t **aux, int8_t *tx_power, /* Ignore CTE for now */ if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_CTE_INFO_BIT)) { - i += 1; + i += BLE_LL_EXT_ADV_CTE_INFO_SIZE; } /* there should be no ADI in Sync or chain, skip it */ From 5e6bb6f878ccf7a3bcc7c10cf025de0ca5ff8762 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 8 Nov 2021 15:07:26 +0100 Subject: [PATCH 0055/1333] apps/blestress: Fix tx_stress_13 We should not free mbuf in BLE_GAP_EVENT_NOTIFY_RX since it's freed by host after returning from event callback. --- apps/blestress/src/tx_stress.c | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/blestress/src/tx_stress.c b/apps/blestress/src/tx_stress.c index 4416c568cb..217d5b5d1b 100644 --- a/apps/blestress/src/tx_stress.c +++ b/apps/blestress/src/tx_stress.c @@ -1271,7 +1271,6 @@ tx_stress_13_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_NOTIFY_RX: MODLOG_DFLT(INFO, "Notify RX event\n"); console_printf("\033[0;32m>\033[0m"); - os_mbuf_free_chain(event->notify_rx.om); ++tx_stress_ctx->rcv_num; return 0; From 0b36c1ac0328d01761a64613c15f296c27865b1a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 8 Nov 2021 15:37:19 +0100 Subject: [PATCH 0056/1333] apps/blestress: Fix log in tx_stress_14 --- apps/blestress/src/tx_stress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/blestress/src/tx_stress.c b/apps/blestress/src/tx_stress.c index 217d5b5d1b..1711f9fbf8 100644 --- a/apps/blestress/src/tx_stress.c +++ b/apps/blestress/src/tx_stress.c @@ -1389,7 +1389,7 @@ tx_stress_14_gap_event(struct ble_gap_event *event, void *arg) if (++tx_stress_ctx->rcv_num >= MYNEWT_VAL(BLE_STRESS_REPEAT)) { rc = ble_gap_terminate(event->notify_rx.conn_handle, BLE_ERR_REM_USER_CONN_TERM); - MODLOG_DFLT(INFO, "rc=%d\n"); + MODLOG_DFLT(INFO, "rc=%d\n", rc); assert(rc == 0); return 0; } From 33aa9b4612abaab7e6627c932e73b6f67dfa2294 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 5 Nov 2021 15:10:36 +0100 Subject: [PATCH 0057/1333] nimble/ll: Ignore aux PDUs while not ext scanning We do not really want to process aux PDUs when using legacy scanning. --- nimble/controller/src/ble_ll_scan.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 8539257c2a..e99f431717 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1928,6 +1928,22 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd struct ble_ll_scan_sm *scansm; struct ble_ll_scan_addr_data addrd; uint8_t *targeta; + uint8_t max_pdu_type; + + scansm = &g_ble_ll_scan_sm; + rxinfo = &hdr->rxinfo; + + /* Ignore PDUs we do not expect here */ + max_pdu_type = BLE_ADV_PDU_TYPE_ADV_SCAN_IND; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + if (scansm->ext_scanning) { + /* Note: We do not expect AUX_CONNECT_RSP here */ + max_pdu_type = BLE_ADV_PDU_TYPE_ADV_EXT_IND; + } +#endif + if (ptype > max_pdu_type) { + return; + } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (ptype == BLE_ADV_PDU_TYPE_ADV_EXT_IND) { @@ -1937,9 +1953,6 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd } #endif - scansm = &g_ble_ll_scan_sm; - rxinfo = &hdr->rxinfo; - if (scansm->scanp->scan_type == BLE_SCAN_TYPE_INITIATE) { if (rxinfo->flags & BLE_MBUF_HDR_F_CONNECT_IND_TXD) { /* We need to keep original TargetA in case it was resolved, so rl From e7507652387ebbd9f8c83ec594721d6a1bdce871 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 5 Nov 2021 15:26:54 +0100 Subject: [PATCH 0058/1333] nimble/ll: Fix aux handling in initiator If AUX_ADV_IND is ignored due to address mismatch in initiator it should be marked as ignored, otherwise LL will assert since it assumes that while initiating any valid PDU is either AUX_CONNECT_RSP or it was an AUX_ADV_IND with AUX_CONNECT_REQ sent. In our case it will be an AUX_ADV_IND without AUX_CONNECT_REQ sent... --- nimble/controller/src/ble_ll_scan_aux.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index a521679a20..477fa81241 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -1306,6 +1306,7 @@ ble_ll_scan_aux_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) !(scan_filt_policy & 0x01)) { rc = ble_ll_scan_rx_check_init(&addrd); if (rc < 0) { + rxinfo->flags |= BLE_MBUF_HDR_F_IGNORED; goto done; } } From 3153e2057607a53f022c5a9675618305afe2b43a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 5 Nov 2021 15:39:58 +0100 Subject: [PATCH 0059/1333] nimble/ll: Fix LE Coded scan parameters handling Make sure we only try to setup LE Coded in scanner if both ext adv (i.e. also ext scan) and LE Coded PHY are enabled. --- nimble/controller/src/ble_ll_scan.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index e99f431717..47b7d0bd7f 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -2069,7 +2069,9 @@ ble_ll_scan_hci_set_ext_params(const uint8_t *cmdbuf, uint8_t len) struct ble_ll_scan_phy new_params[BLE_LL_SCAN_PHY_NUMBER] = { }; struct ble_ll_scan_phy *uncoded = &new_params[PHY_UNCODED]; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) struct ble_ll_scan_phy *coded = &new_params[PHY_CODED]; +#endif uint16_t interval; uint16_t window; int rc; @@ -2147,7 +2149,6 @@ ble_ll_scan_hci_set_ext_params(const uint8_t *cmdbuf, uint8_t len) /* That means user wants to use this PHY for scanning */ coded->configured = 1; } -#endif /* if any of PHYs is configured for continuous scan we alter interval to * fit other PHY @@ -2161,6 +2162,7 @@ ble_ll_scan_hci_set_ext_params(const uint8_t *cmdbuf, uint8_t len) uncoded->timing.interval += coded->timing.window; } } +#endif g_ble_ll_scan_params.own_addr_type = cmd->own_addr_type; g_ble_ll_scan_params.scan_filt_policy = cmd->filter_policy; @@ -2429,7 +2431,7 @@ ble_ll_scan_initiator_start(struct ble_ll_conn_sm *connsm, uint8_t ext, { struct ble_ll_scan_sm *scansm; struct ble_ll_scan_phy *scanp_uncoded; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) struct ble_ll_scan_phy *scanp_coded; #endif uint8_t init_phy_mask; @@ -2461,7 +2463,7 @@ ble_ll_scan_initiator_start(struct ble_ll_conn_sm *connsm, uint8_t ext, scanp_uncoded->configured = 0; } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) scanp_coded = &scansm->scan_phys[PHY_CODED]; if (init_phy_mask & BLE_PHY_MASK_CODED) { scanp_coded->configured = 1; From 99942496b6a47efa1f45b5cd4b6726e38b7c4cfc Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 5 Nov 2021 15:51:01 +0100 Subject: [PATCH 0060/1333] nimble/ll: Fix rx abort on aux scan If rx on aux scan is aborted, we need to set LL back to standby. --- nimble/controller/src/ble_ll_scan_aux.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 477fa81241..f1e56bd3eb 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -764,6 +764,7 @@ ble_ll_scan_aux_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *rxhdr) if (pdu_type != BLE_ADV_PDU_TYPE_AUX_CONNECT_RSP) { aux_data_current = NULL; ble_ll_scan_aux_break(aux); + ble_ll_state_set(BLE_LL_STATE_STANDBY); return -1; } return 0; @@ -772,6 +773,7 @@ ble_ll_scan_aux_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *rxhdr) if (pdu_type != BLE_ADV_PDU_TYPE_ADV_EXT_IND) { aux_data_current = NULL; ble_ll_scan_aux_break(aux); + ble_ll_state_set(BLE_LL_STATE_STANDBY); return -1; } From 17a724066414d76675d5d756c994048a43d5fda9 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 8 Nov 2021 13:48:17 +0100 Subject: [PATCH 0061/1333] nimble/ll: Fix starting ctrl proc timer We cannot just initialize callout prior to restarting since this will wipe it out and thus break callouts queue if it was already added there. Instead, initialize once on module init. --- nimble/controller/src/ble_ll_conn.c | 4 +++ nimble/controller/src/ble_ll_ctrl.c | 12 ++++---- nimble/controller/src/ble_ll_ctrl_priv.h | 35 ++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 nimble/controller/src/ble_ll_ctrl_priv.h diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 55ca20e900..ebeddd7498 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -40,6 +40,7 @@ #include "controller/ble_phy.h" #include "controller/ble_ll_utils.h" #include "ble_ll_conn_priv.h" +#include "ble_ll_ctrl_priv.h" #if (BLETEST_THROUGHPUT_TEST == 1) extern void bletest_completed_pkt(uint16_t handle); @@ -3772,6 +3773,9 @@ ble_ll_conn_module_init(void) /* Initialize fixed schedule elements */ connsm->conn_sch.sched_type = BLE_LL_SCHED_TYPE_CONN; connsm->conn_sch.cb_arg = connsm; + + ble_ll_ctrl_init_conn_sm(connsm); + ++connsm; } diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 7ef63d132d..b6c6036ec1 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -559,11 +559,6 @@ ble_ll_ctrl_proc_rsp_timer_cb(struct ble_npl_event *ev) static void ble_ll_ctrl_start_rsp_timer(struct ble_ll_conn_sm *connsm) { - ble_npl_callout_init(&connsm->ctrl_proc_rsp_timer, - &g_ble_ll_data.ll_evq, - ble_ll_ctrl_proc_rsp_timer_cb, - connsm); - /* Re-start timer. Control procedure timeout is 40 seconds */ ble_npl_callout_reset(&connsm->ctrl_proc_rsp_timer, ble_npl_time_ms_to_ticks32(BLE_LL_CTRL_PROC_TIMEOUT_MS)); @@ -2886,3 +2881,10 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) os_mbuf_free_chain(txpdu); return rc; } + +void +ble_ll_ctrl_init_conn_sm(struct ble_ll_conn_sm *connsm) +{ + ble_npl_callout_init(&connsm->ctrl_proc_rsp_timer, &g_ble_ll_data.ll_evq, + ble_ll_ctrl_proc_rsp_timer_cb, connsm); +} diff --git a/nimble/controller/src/ble_ll_ctrl_priv.h b/nimble/controller/src/ble_ll_ctrl_priv.h new file mode 100644 index 0000000000..ca1c83d390 --- /dev/null +++ b/nimble/controller/src/ble_ll_ctrl_priv.h @@ -0,0 +1,35 @@ +/* + * 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_BLE_LL_CTRL_PRIV_ +#define H_BLE_LL_CTRL_PRIV_ + +#include "controller/ble_ll_conn.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void ble_ll_ctrl_init_conn_sm(struct ble_ll_conn_sm *connsm); + +#ifdef __cplusplus +} +#endif + +#endif /* H_BLE_LL_CTRL_PRIV_ */ From 513ea2738655bb10010dcf1d7e646b6e1ed3a355 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 8 Nov 2021 11:23:14 +0100 Subject: [PATCH 0062/1333] Revert "nimble/ll: Fix encrypted data PDU payload length calculation" This reverts commit c185dd6719b1cc9e08abada79e16e866118d3501. --- nimble/controller/src/ble_ll_conn.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index ebeddd7498..20b578aa7b 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -855,7 +855,6 @@ static uint16_t ble_ll_conn_adjust_pyld_len(struct ble_ll_conn_sm *connsm, uint16_t pyld_len) { uint16_t phy_max_tx_octets; - uint16_t mic_len; uint16_t ret; #if (BLE_LL_BT5_PHY_SUPPORTED == 1) @@ -878,19 +877,11 @@ ble_ll_conn_adjust_pyld_len(struct ble_ll_conn_sm *connsm, uint16_t pyld_len) ret = pyld_len; - mic_len = 0; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (CONN_F_ENCRYPTED(connsm)) { - mic_len = BLE_LL_DATA_MIC_LEN; - } -#endif - - - if (ret > connsm->eff_max_tx_octets - mic_len) { + if (ret > connsm->eff_max_tx_octets) { ret = connsm->eff_max_tx_octets; } - if (ret > phy_max_tx_octets - mic_len) { + if (ret > phy_max_tx_octets) { ret = phy_max_tx_octets; } From 4a89a4c5cb1a33e8eae3c01a2108fedfb7eb180e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 8 Nov 2021 11:23:31 +0100 Subject: [PATCH 0063/1333] nimble/ll: Fix encrypted payload length ble_ll_pdu_max_tx_octets_get() returns number of bytes that can be added between LL header and CRC so the complete PDU is no longer than maxTxTime allowed. However, if link is encrypted there will be also MIC added after the payload so effectively we need to stript that extra 4 bytes from allowed payload length. --- nimble/controller/src/ble_ll_conn.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 20b578aa7b..30a381e1ec 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -854,7 +854,7 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm) static uint16_t ble_ll_conn_adjust_pyld_len(struct ble_ll_conn_sm *connsm, uint16_t pyld_len) { - uint16_t phy_max_tx_octets; + uint16_t max_pyld_len; uint16_t ret; #if (BLE_LL_BT5_PHY_SUPPORTED == 1) @@ -867,22 +867,28 @@ ble_ll_conn_adjust_pyld_len(struct ble_ll_conn_sm *connsm, uint16_t pyld_len) phy_mode = connsm->phy_data.tx_phy_mode; } - phy_max_tx_octets = ble_ll_pdu_max_tx_octets_get(connsm->eff_max_tx_time, - phy_mode); + max_pyld_len = ble_ll_pdu_max_tx_octets_get(connsm->eff_max_tx_time, + phy_mode); #else - phy_max_tx_octets = ble_ll_pdu_max_tx_octets_get(connsm->eff_max_tx_time, - BLE_PHY_MODE_1M); + max_pyld_len = ble_ll_pdu_max_tx_octets_get(connsm->eff_max_tx_time, + BLE_PHY_MODE_1M); #endif ret = pyld_len; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) + if (CONN_F_ENCRYPTED(connsm)) { + max_pyld_len -= BLE_LL_DATA_MIC_LEN; + } +#endif + if (ret > connsm->eff_max_tx_octets) { ret = connsm->eff_max_tx_octets; } - if (ret > phy_max_tx_octets) { - ret = phy_max_tx_octets; + if (ret > max_pyld_len) { + ret = max_pyld_len; } return ret; From 91c5d9a39319b31b81d6655f4dec16e06259cd4a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 6 Nov 2021 00:45:44 +0100 Subject: [PATCH 0064/1333] nimble/ll: Add more convenient way to set pub dev addr This adds BLE_LL_PUBLIC_DEV_ADDR which allows to conveniently set public device address as 48-bit number. It has priority over existing BLE_PUBLIC_DEV_ADDR which allows to do the same but in a very nasty way via code injection so is not very intuitive to use. --- nimble/controller/src/ble_ll.c | 19 +++++++++++++++---- nimble/controller/syscfg.yml | 9 +++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 1a8e4622c3..5305e162bc 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1573,6 +1573,10 @@ ble_ll_init(void) { int rc; uint64_t features; +#if MYNEWT_VAL(BLE_LL_PUBLIC_DEV_ADDR) + uint64_t pub_dev_addr; + int i; +#endif ble_addr_t addr; struct ble_ll_obj *lldata; @@ -1584,10 +1588,17 @@ ble_ll_init(void) /* Set public device address if not already set */ if (ble_ll_is_addr_empty(g_dev_addr)) { - /* Use sycfg address if configured, otherwise try to read from HW */ - if (!ble_ll_is_addr_empty(MYNEWT_VAL(BLE_PUBLIC_DEV_ADDR))) { - memcpy(g_dev_addr, MYNEWT_VAL(BLE_PUBLIC_DEV_ADDR), BLE_DEV_ADDR_LEN); - } else { +#if MYNEWT_VAL(BLE_LL_PUBLIC_DEV_ADDR) + pub_dev_addr = MYNEWT_VAL(BLE_LL_PUBLIC_DEV_ADDR); + + for (i = 0; i < BLE_DEV_ADDR_LEN; i++) { + g_dev_addr[i] = pub_dev_addr & 0xff; + pub_dev_addr >>= 8; + } +#else + memcpy(g_dev_addr, MYNEWT_VAL(BLE_PUBLIC_DEV_ADDR), BLE_DEV_ADDR_LEN); +#endif + if (ble_ll_is_addr_empty(g_dev_addr)) { rc = ble_hw_get_public_addr(&addr); if (!rc) { memcpy(g_dev_addr, &addr.val[0], BLE_DEV_ADDR_LEN); diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 13b6780c1b..de6e688c6d 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -308,6 +308,13 @@ syscfg.defs: packets for receive on secondary advertising channel. value: 0 + BLE_LL_PUBLIC_DEV_ADDR: + description: > + Set public device address. Address is specified as 48-bit number. + If non-zero, this setting has priority over BLE_PUBLIC_DEV_ADDR. + Note: this setting should only be used for testing purposes, it is + not intended for production builds. + value: 0x000000000000 BLE_PUBLIC_DEV_ADDR: description: > Allows the target or app to override the public device address @@ -316,6 +323,7 @@ syscfg.defs: chip specific location. If non-zero, this address will be used. value: "(uint8_t[6]){0x00, 0x00, 0x00, 0x00, 0x00, 0x00}" + deprecated: 1 BLE_LL_DTM: description: > @@ -462,3 +470,4 @@ syscfg.vals.!BLE_HOST: syscfg.restrictions: - OS_CPUTIME_FREQ == 32768 + - BLE_LL_PUBLIC_DEV_ADDR <= 0xffffffffffff From 911a257fe3dfd529fa42365fc17d8ec68157b064 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 8 Nov 2021 14:12:47 +0100 Subject: [PATCH 0065/1333] apps/blestress: Fix rx_stress_13 ble_gattc_notify_custom() will trigger a GAP event so we cannot use it inside GAP event handler as this will create infinite loop. --- apps/blestress/src/rx_stress.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/apps/blestress/src/rx_stress.c b/apps/blestress/src/rx_stress.c index 440966adcc..01149c43a8 100644 --- a/apps/blestress/src/rx_stress.c +++ b/apps/blestress/src/rx_stress.c @@ -1010,12 +1010,24 @@ rx_stress_12_gap_event(struct ble_gap_event *event, void *arg) return 0; } -static int -rx_stress_13_gap_event(struct ble_gap_event *event, void *arg) +static struct ble_npl_event rx_stress_13_notify_ev; + +static void +rx_stress_13_notify_ev_func(struct ble_npl_event *ev) { + struct os_mbuf *om; int rc; - struct os_mbuf *om = NULL; + om = ble_hs_mbuf_from_flat(test_6_pattern, 10); + rc = ble_gattc_notify_custom(rx_stress_ctx->conn_handle, + hrs_hrm_handle, om); + assert(rc == 0); + +} + +static int +rx_stress_13_gap_event(struct ble_gap_event *event, void *arg) +{ switch (event->type) { case BLE_GAP_EVENT_CONNECT: /* A new connection was established or a connection attempt failed */ @@ -1026,6 +1038,9 @@ rx_stress_13_gap_event(struct ble_gap_event *event, void *arg) rx_stress_ctx->conn_handle = event->connect.conn_handle; rx_stress_ctx->begin_us = os_get_uptime_usec(); + + ble_npl_eventq_put((struct ble_npl_eventq *)os_eventq_dflt_get(), + &rx_stress_13_notify_ev); break; } else { /* Connection failed; resume advertising */ @@ -1061,6 +1076,9 @@ rx_stress_13_gap_event(struct ble_gap_event *event, void *arg) BLE_ERR_REM_USER_CONN_TERM); return 0; } + + ble_npl_eventq_put((struct ble_npl_eventq *)os_eventq_dflt_get(), + &rx_stress_13_notify_ev); break; default: @@ -1068,10 +1086,6 @@ rx_stress_13_gap_event(struct ble_gap_event *event, void *arg) return 0; } - om = ble_hs_mbuf_from_flat(test_6_pattern, 10); - rc = ble_gattc_notify_custom(rx_stress_ctx->conn_handle, - hrs_hrm_handle, om); - assert(rc == 0); return 0; } @@ -1377,6 +1391,8 @@ rx_stress_start(int test_num) break; case 13: console_printf("Stress GATT notification\033[0m\n"); + ble_npl_event_init(&rx_stress_13_notify_ev, + rx_stress_13_notify_ev_func, NULL); rx_stress_simple_adv(&rx_stress_adv_sets[13]); break; case 14: From b67d3c186689112717a95bbd24b5e7fd6ba7e959 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 8 Nov 2021 14:14:10 +0100 Subject: [PATCH 0066/1333] apps/blestress: Fix printout in rx_stress_13 --- apps/blestress/src/rx_stress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/blestress/src/rx_stress.c b/apps/blestress/src/rx_stress.c index 01149c43a8..50415ea4e6 100644 --- a/apps/blestress/src/rx_stress.c +++ b/apps/blestress/src/rx_stress.c @@ -1060,7 +1060,7 @@ rx_stress_13_gap_event(struct ble_gap_event *event, void *arg) rx_stress_ctx->s13_notif_time = rx_stress_ctx->time_sum / rx_stress_ctx->send_num; - MODLOG_DFLT(INFO, "Average time: %lld us\n", + MODLOG_DFLT(INFO, "Average time: %d us\n", rx_stress_ctx->s13_notif_time); rx_stress_on_test_finish(13); return 0; From ec0819fac61049b0fd0c50219f7ff0f5de46dc24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 1 Oct 2021 08:20:20 +0200 Subject: [PATCH 0067/1333] host/mesh: Fixes Friend Queue store message If the SRC field of the received message is a unicast address of an element of the Low Power node, then the message shall not be stored in the Friend Queue. Otherwise, lpn will discard this message, eventually it breaks friendship. this is port of 5b11c053efcb6eec351bb275020fdac9ed6592d9 --- nimble/host/mesh/src/friend.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimble/host/mesh/src/friend.c b/nimble/host/mesh/src/friend.c index 4742e89d36..ff34eda9c6 100644 --- a/nimble/host/mesh/src/friend.c +++ b/nimble/host/mesh/src/friend.c @@ -1663,6 +1663,11 @@ void bt_mesh_friend_enqueue_rx(struct bt_mesh_net_rx *rx, continue; } + if (friend_lpn_matches(frnd, rx->sub->net_idx, + rx->ctx.addr)) { + continue; + } + if (!friend_queue_prepare_space(frnd, rx->ctx.addr, seq_auth, seg_count)) { continue; From 41ee1e2108e1e0d19ee69cb9eb4df2c94c5eaa20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 6 Oct 2021 07:23:32 +0200 Subject: [PATCH 0068/1333] host/mesh: Break up mesh settings The mesh settings.c module is a giant piece of code responsible for storing the mesh stack configuration. Such approach makes it difficult to control the data to be stored, breaks the stack modules' encapsulation by forcing them to reveal the internal kitchen, which leads to unpleasant issues such as #19799. This commit moves the responsibility of storing the configuration to corresponding modules while keeping control of the moment of storing the configuration and of starting the stack after the settingss loading is completed. This doesn't introduce any abstraction between the mesh settings.c and other modules as it will add more complexity and overhead than necessary for the actual task. This is a port of 561a8e4f0e9ff43d878f382de4d1052e025febec --- apps/bttester/src/mesh.c | 2 +- nimble/host/mesh/include/mesh/glue.h | 1 + nimble/host/mesh/src/access.c | 451 +++++ nimble/host/mesh/src/access.h | 15 +- nimble/host/mesh/src/app_keys.c | 276 ++- nimble/host/mesh/src/app_keys.h | 24 +- nimble/host/mesh/src/cdb.c | 761 +++++++- nimble/host/mesh/src/cdb_priv.h | 12 + nimble/host/mesh/src/cfg.c | 131 +- nimble/host/mesh/src/cfg.h | 1 + nimble/host/mesh/src/cfg_srv.c | 24 +- nimble/host/mesh/src/heartbeat.c | 104 +- nimble/host/mesh/src/heartbeat.h | 2 + nimble/host/mesh/src/mesh.c | 15 +- nimble/host/mesh/src/net.c | 352 +++- nimble/host/mesh/src/net.h | 17 +- nimble/host/mesh/src/provisioner.c | 2 +- nimble/host/mesh/src/rpl.c | 190 +- nimble/host/mesh/src/rpl.h | 7 +- nimble/host/mesh/src/settings.c | 2410 +------------------------- nimble/host/mesh/src/settings.h | 41 +- nimble/host/mesh/src/shell.c | 6 +- nimble/host/mesh/src/subnet.c | 211 ++- nimble/host/mesh/src/subnet.h | 9 + nimble/host/mesh/src/transport.c | 183 +- nimble/host/mesh/src/transport.h | 17 +- nimble/host/mesh/syscfg.yml | 7 + 27 files changed, 2721 insertions(+), 2550 deletions(-) create mode 100644 nimble/host/mesh/src/cdb_priv.h diff --git a/apps/bttester/src/mesh.c b/apps/bttester/src/mesh.c index 87bdbea430..46bf7699c3 100644 --- a/apps/bttester/src/mesh.c +++ b/apps/bttester/src/mesh.c @@ -599,7 +599,7 @@ static void net_send(uint8_t *data, uint16_t len) SYS_LOG_DBG("ttl 0x%02x dst 0x%04x payload_len %d", ctx.send_ttl, ctx.addr, cmd->payload_len); - if (!bt_mesh_app_key_get(vnd_app_key_idx)) { + if (!bt_mesh_app_key_exists(vnd_app_key_idx)) { (void)bt_mesh_app_key_add(vnd_app_key_idx, net.net_idx, vnd_app_key); vnd_models[0].keys[0] = vnd_app_key_idx; diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index 9a4bd9a524..eedaaac92d 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -405,6 +405,7 @@ static inline unsigned int find_msb_set(uint32_t op) #define CONFIG_BT_MESH_PROVISIONER BLE_MESH_PROVISIONER #define CONFIG_BT_MESH_PROV_DEVICE BLE_MESH_PROV_DEVICE #define CONFIG_BT_MESH_CDB BLE_MESH_CDB +#define CONFIG_BT_MESH_DEBUG_CFG BLE_MESH_DEBUG_CFG /* Above flags are used with IS_ENABLED macro */ #define IS_ENABLED(config) MYNEWT_VAL(config) diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index d23a656551..c6436e85e8 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -10,6 +10,7 @@ #define MESH_LOG_MODULE BLE_MESH_ACCESS_LOG #include +#include #include #include "mesh/mesh.h" @@ -21,10 +22,30 @@ #include "transport.h" #include "access.h" #include "foundation.h" +#include "settings.h" #if MYNEWT_VAL(BLE_MESH_SHELL_MODELS) #include "mesh/model_cli.h" #endif +/* bt_mesh_model.flags */ +enum { + BT_MESH_MOD_BIND_PENDING = BIT(0), + BT_MESH_MOD_SUB_PENDING = BIT(1), + BT_MESH_MOD_PUB_PENDING = BIT(2), + BT_MESH_MOD_NEXT_IS_PARENT = BIT(3), +}; + +/* Model publication information for persistent storage. */ +struct mod_pub_val { + uint16_t addr; + uint16_t key; + uint8_t ttl; + uint8_t retransmit; + uint8_t period; + uint8_t period_div:4, + cred:1; +}; + static const struct bt_mesh_comp *dev_comp; static uint16_t dev_primary_addr; @@ -847,3 +868,433 @@ int bt_mesh_model_extend(struct bt_mesh_model *mod, return 0; } #endif + +static int mod_set_bind(struct bt_mesh_model *mod, char *val) +{ + int len, err, i; + + /* Start with empty array regardless of cleared or set value */ + for (i = 0; i < ARRAY_SIZE(mod->keys); i++) { + mod->keys[i] = BT_MESH_KEY_UNUSED; + } + + if (!val) { + BT_DBG("Cleared bindings for model"); + return 0; + } + + len = sizeof(mod->keys); + err = settings_bytes_from_str(val, mod->keys, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return -EINVAL; + } + + BT_DBG("Decoded %u bound keys for model", len / sizeof(mod->keys[0])); + return 0; +} + +static int mod_set_sub(struct bt_mesh_model *mod, char *val) +{ + int len, err; + + /* Start with empty array regardless of cleared or set value */ + memset(mod->groups, 0, sizeof(mod->groups)); + + if (!val) { + BT_DBG("Cleared subscriptions for model"); + return 0; + } + + len = sizeof(mod->groups); + err = settings_bytes_from_str(val, mod->groups, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return -EINVAL; + } + + BT_DBG("Decoded %u subscribed group addresses for model", + len / sizeof(mod->groups[0])); + return 0; +} + +static int mod_set_pub(struct bt_mesh_model *mod, char *val) +{ + struct mod_pub_val pub; + int len, err; + + if (!mod->pub) { + BT_WARN("Model has no publication context!"); + return -EINVAL; + } + + if (!val) { + mod->pub->addr = BT_MESH_ADDR_UNASSIGNED; + mod->pub->key = 0; + mod->pub->cred = 0; + mod->pub->ttl = 0; + mod->pub->period = 0; + mod->pub->retransmit = 0; + mod->pub->period_div = pub.period_div; + mod->pub->count = 0; + + BT_DBG("Cleared publication for model"); + return 0; + } + + len = sizeof(pub); + err = settings_bytes_from_str(val, &pub, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return -EINVAL; + } + + if (len != sizeof(pub)) { + BT_ERR("Invalid length for model publication"); + return -EINVAL; + } + + mod->pub->addr = pub.addr; + mod->pub->key = pub.key; + mod->pub->cred = pub.cred; + mod->pub->ttl = pub.ttl; + mod->pub->period = pub.period; + mod->pub->retransmit = pub.retransmit; + mod->pub->count = 0; + + BT_DBG("Restored model publication, dst 0x%04x app_idx 0x%03x", + pub.addr, pub.key); + + return 0; +} + +static int mod_data_set(struct bt_mesh_model *mod, + char *name, char *len_rd) +{ + char *next; + + settings_name_next(name, &next); + + if (mod->cb && mod->cb->settings_set) { + return mod->cb->settings_set(mod, next, len_rd); + } + + return 0; +} + +static int mod_set(bool vnd, int argc, char **argv, char *val) +{ + struct bt_mesh_model *mod; + uint8_t elem_idx, mod_idx; + uint16_t mod_key; + + if (argc < 2) { + BT_ERR("Too small argc (%d)", argc); + return -ENOENT; + } + + mod_key = strtol(argv[0], NULL, 16); + elem_idx = mod_key >> 8; + mod_idx = mod_key; + + BT_DBG("Decoded mod_key 0x%04x as elem_idx %u mod_idx %u", + mod_key, elem_idx, mod_idx); + + mod = bt_mesh_model_get(vnd, elem_idx, mod_idx); + if (!mod) { + BT_ERR("Failed to get model for elem_idx %u mod_idx %u", + elem_idx, mod_idx); + return -ENOENT; + } + + if (!strcmp(argv[1], "bind")) { + return mod_set_bind(mod, val); + } + + if (!strcmp(argv[1], "sub")) { + return mod_set_sub(mod, val); + } + + if (!strcmp(argv[1], "pub")) { + return mod_set_pub(mod, val); + } + + if (!strcmp(argv[1], "data")) { + return mod_data_set(mod, argv[1], val); + } + + BT_WARN("Unknown module key %s", argv[1]); + return -ENOENT; +} + +static int sig_mod_set(int argc, char **argv, char *val) +{ + return mod_set(false, argc, argv, val); +} + +static int vnd_mod_set(int argc, char **argv, char *val) +{ + return mod_set(true, argc, argv, val); +} + +static void encode_mod_path(struct bt_mesh_model *mod, bool vnd, + const char *key, char *path, size_t path_len) +{ + uint16_t mod_key = (((uint16_t)mod->elem_idx << 8) | mod->mod_idx); + + if (vnd) { + snprintk(path, path_len, "bt_mesh/v/%x/%s", mod_key, key); + } else { + snprintk(path, path_len, "bt_mesh/s/%x/%s", mod_key, key); + } +} + +static void store_pending_mod_bind(struct bt_mesh_model *mod, bool vnd) +{ + uint16_t keys[CONFIG_BT_MESH_MODEL_KEY_COUNT]; + char buf[BT_SETTINGS_SIZE(sizeof(keys))]; + char path[20]; + int i, count, err; + char *val; + + for (i = 0, count = 0; i < ARRAY_SIZE(mod->keys); i++) { + if (mod->keys[i] != BT_MESH_KEY_UNUSED) { + keys[count++] = mod->keys[i]; + BT_DBG("model key 0x%04x", mod->keys[i]); + } + } + + if (count) { + val = settings_str_from_bytes(keys, count * sizeof(keys[0]), + buf, sizeof(buf)); + if (!val) { + BT_ERR("Unable to encode model bindings as value"); + return; + } + } else { + val = NULL; + } + + encode_mod_path(mod, vnd, "bind", path, sizeof(path)); + + BT_DBG("Saving %s as %s", path, val ? val : "(null)"); + err = settings_save_one(path, val); + if (err) { + BT_ERR("Failed to store bind"); + } else { + BT_DBG("Stored bind"); + } +} + +static void store_pending_mod_sub(struct bt_mesh_model *mod, bool vnd) +{ + uint16_t groups[CONFIG_BT_MESH_MODEL_GROUP_COUNT]; + char buf[BT_SETTINGS_SIZE(sizeof(groups))]; + char path[20]; + int i, count, err; + char *val; + + for (i = 0, count = 0; i < CONFIG_BT_MESH_MODEL_GROUP_COUNT; i++) { + if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) { + groups[count++] = mod->groups[i]; + } + } + + if (count) { + val = settings_str_from_bytes(groups, count * sizeof(groups[0]), + buf, sizeof(buf)); + if (!val) { + BT_ERR("Unable to encode model subscription as value"); + return; + } + } else { + val = NULL; + } + + encode_mod_path(mod, vnd, "sub", path, sizeof(path)); + + BT_DBG("Saving %s as %s", path, val ? val : "(null)"); + err = settings_save_one(path, val); + if (err) { + BT_ERR("Failed to store sub"); + } else { + BT_DBG("Stored sub"); + } +} + +static void store_pending_mod_pub(struct bt_mesh_model *mod, bool vnd) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct mod_pub_val))]; + struct mod_pub_val pub; + char path[20]; + char *val; + int err; + + if (!mod->pub || mod->pub->addr == BT_MESH_ADDR_UNASSIGNED) { + val = NULL; + } else { + pub.addr = mod->pub->addr; + pub.key = mod->pub->key; + pub.ttl = mod->pub->ttl; + pub.retransmit = mod->pub->retransmit; + pub.period = mod->pub->period; + pub.period_div = mod->pub->period_div; + pub.cred = mod->pub->cred; + + val = settings_str_from_bytes(&pub, sizeof(pub), buf, sizeof(buf)); + if (!val) { + BT_ERR("Unable to encode model publication as value"); + return; + } + } + + encode_mod_path(mod, vnd, "pub", path, sizeof(path)); + + BT_DBG("Saving %s as %s", path, val ? val : "(null)"); + err = settings_save_one(path, val); + if (err) { + BT_ERR("Failed to store pub"); + } else { + BT_DBG("Stored pub"); + } +} + +static void store_pending_mod(struct bt_mesh_model *mod, + struct bt_mesh_elem *elem, bool vnd, + bool primary, void *user_data) +{ + if (!mod->flags) { + return; + } + + if (mod->flags & BT_MESH_MOD_BIND_PENDING) { + mod->flags &= ~BT_MESH_MOD_BIND_PENDING; + store_pending_mod_bind(mod, vnd); + } + + if (mod->flags & BT_MESH_MOD_SUB_PENDING) { + mod->flags &= ~BT_MESH_MOD_SUB_PENDING; + store_pending_mod_sub(mod, vnd); + } + + if (mod->flags & BT_MESH_MOD_PUB_PENDING) { + mod->flags &= ~BT_MESH_MOD_PUB_PENDING; + store_pending_mod_pub(mod, vnd); + } +} + +void bt_mesh_model_pending_store(void) +{ + bt_mesh_model_foreach(store_pending_mod, NULL); +} + +void bt_mesh_model_bind_store(struct bt_mesh_model *mod) +{ + mod->flags |= BT_MESH_MOD_BIND_PENDING; + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING); +} + +void bt_mesh_model_sub_store(struct bt_mesh_model *mod) +{ + mod->flags |= BT_MESH_MOD_SUB_PENDING; + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING); +} + +void bt_mesh_model_pub_store(struct bt_mesh_model *mod) +{ + mod->flags |= BT_MESH_MOD_PUB_PENDING; + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING); +} + +int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, + const char *name, const void *data, + size_t data_len) +{ + char path[30]; + char buf[BT_SETTINGS_SIZE(sizeof(struct mod_pub_val))]; + char *val; + int err; + + encode_mod_path(mod, vnd, "data", path, sizeof(path)); + if (name) { + strcat(path, "/"); + strncat(path, name, 8); + } + + if (data_len) { + val = settings_str_from_bytes(data, data_len, buf, sizeof(buf)); + if (!val) { + BT_ERR("Unable to encode model publication as value"); + return -EINVAL; + } + err = settings_save_one(path, val); + } else { + err = settings_save_one(path, NULL); + } + + if (err) { + BT_ERR("Failed to store %s value", path); + } else { + BT_DBG("Stored %s value", path); + } + return err; +} + +static void commit_mod(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, + bool vnd, bool primary, void *user_data) +{ + if (mod->pub && mod->pub->update && + mod->pub->addr != BT_MESH_ADDR_UNASSIGNED) { + int32_t ms = bt_mesh_model_pub_period_get(mod); + + if (ms > 0) { + BT_DBG("Starting publish timer (period %u ms)", ms); + k_delayed_work_submit(&mod->pub->timer, K_MSEC(ms)); + } + } + + if (!IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { + return; + } + + for (int i = 0; i < ARRAY_SIZE(mod->groups); i++) { + if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) { + bt_mesh_lpn_group_add(mod->groups[i]); + } + } +} + +void bt_mesh_model_settings_commit(void) +{ + bt_mesh_model_foreach(commit_mod, NULL); +} + +static struct conf_handler bt_mesh_sig_mod_conf_handler = { + .ch_name = "bt_mesh", + .ch_get = NULL, + .ch_set = sig_mod_set, + .ch_commit = NULL, + .ch_export = NULL, +}; + +static struct conf_handler bt_mesh_vnd_mod_conf_handler = { + .ch_name = "bt_mesh", + .ch_get = NULL, + .ch_set = vnd_mod_set, + .ch_commit = NULL, + .ch_export = NULL, +}; + +void bt_mesh_access_init(void) +{ + int rc; + + rc = conf_register(&bt_mesh_sig_mod_conf_handler); + + SYSINIT_PANIC_ASSERT_MSG(rc == 0, + "Failed to register bt_mesh_access conf"); + rc = conf_register(&bt_mesh_vnd_mod_conf_handler); + + SYSINIT_PANIC_ASSERT_MSG(rc == 0, + "Failed to register bt_mesh_access conf"); +} \ No newline at end of file diff --git a/nimble/host/mesh/src/access.h b/nimble/host/mesh/src/access.h index affba538f2..0bb183c172 100644 --- a/nimble/host/mesh/src/access.h +++ b/nimble/host/mesh/src/access.h @@ -11,14 +11,6 @@ #include "mesh/mesh.h" -/* bt_mesh_model.flags */ -enum { - BT_MESH_MOD_BIND_PENDING = BIT(0), - BT_MESH_MOD_SUB_PENDING = BIT(1), - BT_MESH_MOD_PUB_PENDING = BIT(2), - BT_MESH_MOD_NEXT_IS_PARENT = BIT(3), -}; - /* Tree walk return codes */ enum bt_mesh_walk { BT_MESH_WALK_STOP, @@ -61,4 +53,11 @@ struct bt_mesh_model *bt_mesh_model_get(bool vnd, uint8_t elem_idx, uint8_t mod_ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf); int bt_mesh_comp_register(const struct bt_mesh_comp *comp); + +void bt_mesh_model_pending_store(void); +void bt_mesh_model_bind_store(struct bt_mesh_model *mod); +void bt_mesh_model_sub_store(struct bt_mesh_model *mod); +void bt_mesh_model_pub_store(struct bt_mesh_model *mod); +void bt_mesh_model_settings_commit(void); +void bt_mesh_access_init(void); #endif diff --git a/nimble/host/mesh/src/app_keys.c b/nimble/host/mesh/src/app_keys.c index 9582bbd045..16236009d3 100644 --- a/nimble/host/mesh/src/app_keys.c +++ b/nimble/host/mesh/src/app_keys.c @@ -22,41 +22,176 @@ #include "subnet.h" #define MESH_LOG_MODULE BLE_MESH_LOG + #include "log/log.h" -static struct bt_mesh_app_key apps[CONFIG_BT_MESH_APP_KEY_COUNT] = { +/* Tracking of what storage changes are pending for App Keys. We track this in + * a separate array here instead of within the respective bt_mesh_app_key + * struct itselve, since once a key gets deleted its struct becomes invalid + * and may be reused for other keys. + */ +struct app_key_update { + uint16_t key_idx:12, /* AppKey Index */ + valid:1, /* 1 if this entry is valid, 0 if not */ + clear:1; /* 1 if key needs clearing, 0 if storing */ +}; + +/* AppKey information for persistent storage. */ +struct app_key_val { + uint16_t net_idx; + bool updated; + uint8_t val[2][16]; +} __packed; + +/** Mesh Application Key. */ +struct app_key { + uint16_t net_idx; + uint16_t app_idx; + bool updated; + struct bt_mesh_app_cred { + uint8_t id; + uint8_t val[16]; + } keys[2]; +}; + +static struct app_key_update app_key_updates[CONFIG_BT_MESH_APP_KEY_COUNT]; + +static struct app_key apps[CONFIG_BT_MESH_APP_KEY_COUNT] = { [0 ... (CONFIG_BT_MESH_APP_KEY_COUNT - 1)] = { .app_idx = BT_MESH_KEY_UNUSED, .net_idx = BT_MESH_KEY_UNUSED, } }; -static void app_key_evt(struct bt_mesh_app_key *app, enum bt_mesh_key_evt evt) +static struct app_key *app_get(uint16_t app_idx) { + for (int i = 0; i < ARRAY_SIZE(apps); i++) { + if (apps[i].app_idx == app_idx) { + return &apps[i]; + } + } + + return NULL; +} + +static void clear_app_key(uint16_t app_idx) +{ + char path[20]; + int err; + + BT_DBG("AppKeyIndex 0x%03x", app_idx); + + snprintk(path, sizeof(path), "bt_mesh/AppKey/%x", app_idx); + err = settings_save_one(path, NULL); + if (err) { + BT_ERR("Failed to clear AppKeyIndex 0x%03x", app_idx); + } else { + BT_DBG("Cleared AppKeyIndex 0x%03x", app_idx); + } +} + +static void store_app_key(uint16_t app_idx) +{ + const struct app_key *app; + struct app_key_val key; + char path[20]; + char buf[BT_SETTINGS_SIZE(sizeof(struct app_key_val))]; + int err; + char *str; + + snprintk(path, sizeof(path), "bt_mesh/AppKey/%x", app_idx); + + app = app_get(app_idx); + if (!app) { + BT_WARN("ApKeyIndex 0x%03x not found", app_idx); + return; + } + + key.net_idx = app->net_idx, + key.updated = app->updated, + + memcpy(key.val[0], app->keys[0].val, 16); + memcpy(key.val[1], app->keys[1].val, 16); + str = settings_str_from_bytes(&key, sizeof(key), buf, sizeof(buf)); + + err = settings_save_one(path, str); + if (err) { + BT_ERR("Failed to store AppKey"); + } else { + BT_DBG("Stored AppKey %s value"); + } +} + +static struct app_key_update *app_key_update_find(uint16_t key_idx, + struct app_key_update **free_slot) + { + struct app_key_update *match; int i; - for (i = 0; i < (sizeof(bt_mesh_app_key_cb_list)/sizeof(void *)); i++) { - if (bt_mesh_app_key_cb_list[i]) { - BT_DBG("app_key_evt %d", i); - bt_mesh_app_key_cb_list[i] (app->app_idx, app->net_idx, evt); + match = NULL; + *free_slot = NULL; + + for (i = 0; i < ARRAY_SIZE(app_key_updates); i++) { + struct app_key_update *update = &app_key_updates[i]; + + if (!update->valid) { + *free_slot = update; + continue; + } + + if (update->key_idx == key_idx) { + match = update; } } + + return match; } -struct bt_mesh_app_key *app_get(uint16_t app_idx) +static void update_app_key_settings(uint16_t app_idx, bool store) { - for (int i = 0; i < ARRAY_SIZE(apps); i++) { - if (apps[i].app_idx == app_idx) { - return &apps[i]; + struct app_key_update *update, *free_slot; + uint8_t clear = store ? 0U : 1U; + + BT_DBG("AppKeyIndex 0x%03x", app_idx); + + update = app_key_update_find(app_idx, &free_slot); + if (update) { + update->clear = clear; + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_APP_KEYS_PENDING); + return; + } + + if (!free_slot) { + if (store) { + store_app_key(app_idx); + } else { + clear_app_key(app_idx); } + return; } - return NULL; + free_slot->valid = 1U; + free_slot->key_idx = app_idx; + free_slot->clear = clear; + + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_APP_KEYS_PENDING); +} + +static void app_key_evt(struct app_key *app, enum bt_mesh_key_evt evt) +{ + int i; + + for (i = 0; i < (sizeof(bt_mesh_app_key_cb_list)/sizeof(void *)); i++) { + if (bt_mesh_app_key_cb_list[i]) { + BT_DBG("app_key_evt %d", i); + bt_mesh_app_key_cb_list[i] (app->app_idx, app->net_idx, evt); + } + } } -static struct bt_mesh_app_key *app_key_alloc(uint16_t app_idx) +static struct app_key *app_key_alloc(uint16_t app_idx) { - struct bt_mesh_app_key *app = NULL; + struct app_key *app = NULL; for (int i = 0; i < ARRAY_SIZE(apps); i++) { /* Check for already existing app_key */ @@ -72,12 +207,12 @@ static struct bt_mesh_app_key *app_key_alloc(uint16_t app_idx) return app; } -static void app_key_del(struct bt_mesh_app_key *app) +static void app_key_del(struct app_key *app) { BT_DBG("AppIdx 0x%03x", app->app_idx); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_clear_app_key(app->app_idx); + update_app_key_settings(app->app_idx, false); } app_key_evt(app, BT_MESH_KEY_DELETED); @@ -87,7 +222,7 @@ static void app_key_del(struct bt_mesh_app_key *app) (void)memset(app->keys, 0, sizeof(app->keys)); } -static void app_key_revoke(struct bt_mesh_app_key *app) +static void app_key_revoke(struct app_key *app) { if (!app->updated) { return; @@ -98,7 +233,7 @@ static void app_key_revoke(struct bt_mesh_app_key *app) app->updated = false; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_app_key(app->app_idx); + update_app_key_settings(app->app_idx, true); } app_key_evt(app, BT_MESH_KEY_REVOKED); @@ -112,7 +247,7 @@ static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt) } for (int i = 0; i < ARRAY_SIZE(apps); i++) { - struct bt_mesh_app_key *app = &apps[i]; + struct app_key *app = &apps[i]; if (app->app_idx == BT_MESH_KEY_UNUSED) { continue; @@ -140,7 +275,7 @@ uint8_t bt_mesh_app_key_add(uint16_t app_idx, uint16_t net_idx, bt_mesh_subnet_cb_list[0] = subnet_evt; } - struct bt_mesh_app_key *app; + struct app_key *app; BT_DBG("net_idx 0x%04x app_idx %04x val %s", net_idx, app_idx, bt_hex(key, 16)); @@ -179,7 +314,7 @@ uint8_t bt_mesh_app_key_add(uint16_t app_idx, uint16_t net_idx, if (IS_ENABLED(CONFIG_BT_SETTINGS)) { BT_DBG("Storing AppKey persistently"); - bt_mesh_store_app_key(app->app_idx); + update_app_key_settings(app->app_idx, true); } app_key_evt(app, BT_MESH_KEY_ADDED); @@ -187,22 +322,10 @@ uint8_t bt_mesh_app_key_add(uint16_t app_idx, uint16_t net_idx, return STATUS_SUCCESS; } -struct bt_mesh_app_key *bt_mesh_app_key_get(uint16_t app_idx) -{ - struct bt_mesh_app_key *app; - - app = app_get(app_idx); - if (app) { - return app; - } - - return NULL; -} - uint8_t bt_mesh_app_key_update(uint16_t app_idx, uint16_t net_idx, const uint8_t key[16]) { - struct bt_mesh_app_key *app; + struct app_key *app; struct bt_mesh_subnet *sub; BT_DBG("net_idx 0x%04x app_idx %04x val %s", net_idx, app_idx, @@ -250,7 +373,7 @@ uint8_t bt_mesh_app_key_update(uint16_t app_idx, uint16_t net_idx, if (IS_ENABLED(CONFIG_BT_SETTINGS)) { BT_DBG("Storing AppKey persistently"); - bt_mesh_store_app_key(app->app_idx); + update_app_key_settings(app->app_idx, true); } app_key_evt(app, BT_MESH_KEY_UPDATED); @@ -260,7 +383,7 @@ uint8_t bt_mesh_app_key_update(uint16_t app_idx, uint16_t net_idx, uint8_t bt_mesh_app_key_del(uint16_t app_idx, uint16_t net_idx) { - struct bt_mesh_app_key *app; + struct app_key *app; BT_DBG("AppIdx 0x%03x", app_idx); @@ -288,7 +411,7 @@ uint8_t bt_mesh_app_key_del(uint16_t app_idx, uint16_t net_idx) int bt_mesh_app_key_set(uint16_t app_idx, uint16_t net_idx, const uint8_t old_key[16], const uint8_t new_key[16]) { - struct bt_mesh_app_key *app; + struct app_key *app; app = app_key_alloc(app_idx); if (!app) { @@ -337,7 +460,7 @@ ssize_t bt_mesh_app_keys_get(uint16_t net_idx, uint16_t app_idxs[], size_t max, size_t count = 0; for (int i = 0; i < ARRAY_SIZE(apps); i++) { - struct bt_mesh_app_key *app = &apps[i]; + struct app_key *app = &apps[i]; if (app->app_idx == BT_MESH_KEY_UNUSED) { continue; @@ -366,7 +489,7 @@ int bt_mesh_keys_resolve(struct bt_mesh_msg_ctx *ctx, struct bt_mesh_subnet **sub, const uint8_t *app_key[16], uint8_t *aid) { - struct bt_mesh_app_key *app = NULL; + struct app_key *app = NULL; if (BT_MESH_IS_DEV_KEY(ctx->app_idx)) { /* With device keys, the application has to decide which subnet @@ -462,7 +585,7 @@ uint16_t bt_mesh_app_key_find(bool dev_key, uint8_t aid, } for (i = 0; i < ARRAY_SIZE(apps); i++) { - const struct bt_mesh_app_key *app = &apps[i]; + const struct app_key *app = &apps[i]; const struct bt_mesh_app_cred *cred; if (app->app_idx == BT_MESH_KEY_UNUSED) { @@ -498,10 +621,83 @@ uint16_t bt_mesh_app_key_find(bool dev_key, uint8_t aid, void bt_mesh_app_keys_reset(void) { for (int i = 0; i < ARRAY_SIZE(apps); i++) { - struct bt_mesh_app_key *app = &apps[i]; + struct app_key *app = &apps[i]; if (app->app_idx != BT_MESH_KEY_UNUSED) { app_key_del(app); } } } + +static int app_key_set(int argc, char **argv, char *val) +{ + struct app_key_val key; + uint16_t app_idx; + int len_rd, err; + + BT_DBG("argv[0] %s val %s", argv[0], val ? val : "(null)"); + + app_idx = strtol(argv[0], NULL, 16); + len_rd = strtol(argv[1], NULL, 16); + + + if (!len_rd) { + return 0; + } + + err = settings_bytes_from_str(val, &key, &len_rd); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + + err = bt_mesh_app_key_set(app_idx, key.net_idx, key.val[0], + key.updated ? key.val[1] : NULL); + if (err) { + BT_ERR("Failed to set \'app-key\'"); + return err; + } + + BT_DBG("AppKeyIndex 0x%03x recovered from storage", app_idx); + + return 0; +} + +void bt_mesh_app_key_pending_store(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(app_key_updates); i++) { + struct app_key_update *update = &app_key_updates[i]; + + if (!update->valid) { + continue; + } + + if (update->clear) { + clear_app_key(update->key_idx); + } else { + store_app_key(update->key_idx); + } + + update->valid = 0U; + } +} + +static struct conf_handler bt_mesh_app_key_conf_handler = { + .ch_name = "bt_mesh", + .ch_get = NULL, + .ch_set = app_key_set, + .ch_commit = NULL, + .ch_export = NULL, +}; + +void bt_mesh_app_key_init(void) +{ + int rc; + + rc = conf_register(&bt_mesh_app_key_conf_handler); + + SYSINIT_PANIC_ASSERT_MSG(rc == 0, + "Failed to register bt_mesh_app_key conf"); +} \ No newline at end of file diff --git a/nimble/host/mesh/src/app_keys.h b/nimble/host/mesh/src/app_keys.h index d007b785f6..1c560560de 100644 --- a/nimble/host/mesh/src/app_keys.h +++ b/nimble/host/mesh/src/app_keys.h @@ -10,28 +10,9 @@ #include "mesh/mesh.h" #include "subnet.h" -/** Mesh Application. */ -struct bt_mesh_app_key { - uint16_t net_idx; - uint16_t app_idx; - bool updated; - struct bt_mesh_app_cred { - uint8_t id; - uint8_t val[16]; - } keys[2]; -}; - /** @brief Reset the app keys module. */ void bt_mesh_app_keys_reset(void); -/** @brief Get the application key with the given AppIdx. - * - * @param app_idx App index. - * - * @return The matching application, or NULL if the application isn't known. - */ -struct bt_mesh_app_key *bt_mesh_app_key_get(uint16_t app_idx); - /** @brief Initialize a new application key with the given parameters. * * @param app_idx AppIndex. @@ -78,9 +59,10 @@ uint16_t bt_mesh_app_key_find(bool dev_key, uint8_t aid, const uint8_t key[16], void *cb_data), void *cb_data); -struct bt_mesh_app_key *app_get(uint16_t app_idx); - extern void (*bt_mesh_app_key_cb_list[1]) (uint16_t app_idx, uint16_t net_idx, enum bt_mesh_key_evt evt); +/** @brief Store pending application keys in persistent storage. */ +void bt_mesh_app_key_pending_store(void); +void bt_mesh_app_key_init(void); #endif /* _BT_MESH_APP_KEYS_H_ */ \ No newline at end of file diff --git a/nimble/host/mesh/src/cdb.c b/nimble/host/mesh/src/cdb.c index 60d47dee26..5c7f88d470 100644 --- a/nimble/host/mesh/src/cdb.c +++ b/nimble/host/mesh/src/cdb.c @@ -7,8 +7,9 @@ #define BT_DBG_ENABLED MYNEWT_VAL(BLE_MESH_DEBUG_CDB) #define LOG_MODULE_NAME bt_mesh_cdb #include "log/log.h" +#include -#include "mesh/mesh.h" +#include "cdb_priv.h" #include "net.h" #include "rpl.h" #include "settings.h" @@ -16,6 +17,58 @@ #include "mesh/glue.h" #if MYNEWT_VAL(BLE_MESH_CDB) +/* Tracking of what storage changes are pending for App and Net Keys. We + * track this in a separate array here instead of within the respective + * bt_mesh_app_key and bt_mesh_subnet structs themselves, since once a key + * gets deleted its struct becomes invalid and may be reused for other keys. + */ +struct key_update { + uint16_t key_idx:12, /* AppKey or NetKey Index */ + valid:1, /* 1 if this entry is valid, 0 if not */ + app_key:1, /* 1 if this is an AppKey, 0 if a NetKey */ + clear:1; /* 1 if key needs clearing, 0 if storing */ +}; + +/* Tracking of what storage changes are pending for node settings. */ +struct node_update { + uint16_t addr; + bool clear; +}; + +/* Node information for persistent storage. */ +struct node_val { + uint16_t net_idx; + uint8_t num_elem; + uint8_t flags; +#define F_NODE_CONFIGURED 0x01 + uint8_t uuid[16]; + uint8_t dev_key[16]; +} __packed; + +/* NetKey storage information */ +struct net_key_val { + uint8_t kr_flag:1, + kr_phase:7; + uint8_t val[2][16]; +} __packed; + +/* AppKey information for persistent storage. */ +struct app_key_val { + uint16_t net_idx; + bool updated; + uint8_t val[2][16]; +} __packed; + +/* IV Index & IV Update information for persistent storage. */ +struct net_val { + uint32_t iv_index; + bool iv_update; +} __packed; + +static struct node_update cdb_node_updates[MYNEWT_VAL(BLE_MESH_CDB_NODE_COUNT)]; +static struct key_update cdb_key_updates[MYNEWT_VAL(BLE_MESH_CDB_SUBNET_COUNT) + + MYNEWT_VAL(BLE_MESH_CDB_APP_KEY_COUNT)]; + struct bt_mesh_cdb bt_mesh_cdb = { .nodes = { [0 ... (CONFIG_BT_MESH_NODE_COUNT - 1)] = { @@ -107,6 +160,530 @@ static uint16_t find_lowest_free_addr(uint8_t num_elem) return addr; } +static int cdb_net_set(int argc, char *val) +{ + struct net_val net; + int len, err; + + len = sizeof(net); + err = settings_bytes_from_str(val, &net, &len); + if (err) { + BT_ERR("Failed to set \'cdb_net\'"); + return err; + } + + bt_mesh_cdb.iv_index = net.iv_index; + + if (net.iv_update) { + atomic_set_bit(bt_mesh_cdb.flags, BT_MESH_CDB_IVU_IN_PROGRESS); + } + + atomic_set_bit(bt_mesh_cdb.flags, BT_MESH_CDB_VALID); + + return 0; +} + +static int cdb_node_set(int argc, char *str) +{ + struct bt_mesh_cdb_node *node; + struct node_val val; + uint16_t addr; + int len, err; + + if (argc < 1) { + BT_ERR("Insufficient number of arguments"); + return -ENOENT; + } + + addr = strtol(str, NULL, 16); + len = sizeof(str); + + if (argc < 1) { + BT_DBG("val (null)"); + BT_DBG("Deleting node 0x%04x", addr); + + node = bt_mesh_cdb_node_get(addr); + if (node) { + bt_mesh_cdb_node_del(node, false); + } + + return 0; + } + + err = settings_bytes_from_str(str, &val, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return -EINVAL; + } + + if (len != sizeof(struct node_val)) { + BT_ERR("Invalid length for node_val"); + return -EINVAL; + } + + node = bt_mesh_cdb_node_get(addr); + if (!node) { + node = bt_mesh_cdb_node_alloc(val.uuid, addr, val.num_elem, + val.net_idx); + } + + if (!node) { + BT_ERR("No space for a new node"); + return -ENOMEM; + } + + if (val.flags & F_NODE_CONFIGURED) { + atomic_set_bit(node->flags, BT_MESH_CDB_NODE_CONFIGURED); + } + + memcpy(node->uuid, val.uuid, 16); + memcpy(node->dev_key, val.dev_key, 16); + + BT_DBG("Node 0x%04x recovered from storage", addr); + + return 0; +} + +static int cdb_subnet_set(int argc, char *name) +{ + struct bt_mesh_cdb_subnet *sub; + struct net_key_val key; + uint16_t net_idx; + int len, len_rd, err; + + if (!name) { + BT_ERR("Insufficient number of arguments"); + return -ENOENT; + } + + len_rd = sizeof(sub); + net_idx = strtol(name, NULL, 16); + sub = bt_mesh_cdb_subnet_get(net_idx); + + if (len_rd == 0) { + BT_DBG("val (null)"); + if (!sub) { + BT_ERR("No subnet with NetKeyIndex 0x%03x", net_idx); + return -ENOENT; + } + + BT_DBG("Deleting NetKeyIndex 0x%03x", net_idx); + bt_mesh_cdb_subnet_del(sub, false); + return 0; + } + + len = sizeof(key); + err = settings_bytes_from_str(name, &key, &len); + if (err) { + BT_ERR("Failed to set \'net-key\'"); + return err; + } + + if (sub) { + BT_DBG("Updating existing NetKeyIndex 0x%03x", net_idx); + + sub->kr_phase = key.kr_phase; + memcpy(sub->keys[0].net_key, &key.val[0], 16); + memcpy(sub->keys[1].net_key, &key.val[1], 16); + + return 0; + } + + sub = bt_mesh_cdb_subnet_alloc(net_idx); + if (!sub) { + BT_ERR("No space to allocate a new subnet"); + return -ENOMEM; + } + + sub->kr_phase = key.kr_phase; + memcpy(sub->keys[0].net_key, &key.val[0], 16); + memcpy(sub->keys[1].net_key, &key.val[1], 16); + + BT_DBG("NetKeyIndex 0x%03x recovered from storage", net_idx); + + return 0; +} + +static int cdb_app_key_set(int argc, char *name) +{ + struct bt_mesh_cdb_app_key *app; + struct app_key_val key; + uint16_t app_idx; + int len_rd, err; + + app_idx = strtol(name, NULL, 16); + len_rd = sizeof(key); + + if (len_rd == 0) { + BT_DBG("val (null)"); + BT_DBG("Deleting AppKeyIndex 0x%03x", app_idx); + + app = bt_mesh_cdb_app_key_get(app_idx); + if (app) { + bt_mesh_cdb_app_key_del(app, false); + } + + return 0; + } + + err = settings_bytes_from_str(name, &key, &len_rd); + if (err) { + BT_ERR("Failed to set \'app-key\'"); + return err; + } + + app = bt_mesh_cdb_app_key_get(app_idx); + if (!app) { + app = bt_mesh_cdb_app_key_alloc(key.net_idx, app_idx); + } + + if (!app) { + BT_ERR("No space for a new app key"); + return -ENOMEM; + } + + memcpy(app->keys[0].app_key, key.val[0], 16); + memcpy(app->keys[1].app_key, key.val[1], 16); + + BT_DBG("AppKeyIndex 0x%03x recovered from storage", app_idx); + + return 0; +} + +static int cdb_set(int argc, char **argv, char *name) +{ + int len; + char *next; + + if (argc < 1) { + BT_ERR("Insufficient number of arguments"); + return -ENOENT; + } + + if (!strcmp(name, "Net")) { + return cdb_net_set(1, name); + } + + len = settings_name_next(name, &next); + + if (!next) { + BT_ERR("Insufficient number of arguments"); + return -ENOENT; + } + + if (!strncmp(name, "Node", len)) { + return cdb_node_set(1, next); + } + + if (!strncmp(name, "Subnet", len)) { + return cdb_subnet_set(1, next); + } + + if (!strncmp(name, "AppKey", len)) { + return cdb_app_key_set(1, next); + } + + BT_WARN("Unknown module key %s", name); + return -ENOENT; +} + +static void store_cdb_node(const struct bt_mesh_cdb_node *node) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct node_val))]; + struct node_val val; + char path[30]; + char *str; + int err; + + val.net_idx = node->net_idx; + val.num_elem = node->num_elem; + val.flags = 0; + + if (atomic_test_bit(node->flags, BT_MESH_CDB_NODE_CONFIGURED)) { + val.flags |= F_NODE_CONFIGURED; + } + + memcpy(val.uuid, node->uuid, 16); + memcpy(val.dev_key, node->dev_key, 16); + + snprintk(path, sizeof(path), "bt_mesh/cdb/Node/%x", node->addr); + + str = settings_str_from_bytes(&val, sizeof(val), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode Node as value"); + return; + } + + + err = settings_save_one(path, str); + if (err) { + BT_ERR("Failed to store Node %s value", path); + } else { + BT_DBG("Stored Node %s value", path); + } +} + +static void clear_cdb_node(uint16_t addr) +{ + char path[30]; + int err; + + BT_DBG("Node 0x%04x", addr); + + snprintk(path, sizeof(path), "bt_mesh/cdb/Node/%x", addr); + err = settings_save_one(path, NULL); + if (err) { + BT_ERR("Failed to clear Node 0x%04x", addr); + } else { + BT_DBG("Cleared Node 0x%04x", addr); + } +} + +static void store_cdb_subnet(const struct bt_mesh_cdb_subnet *sub) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct net_key_val))]; + struct net_key_val key; + char path[30]; + int err; + char *str; + + BT_DBG("NetKeyIndex 0x%03x NetKey %s", sub->net_idx, + bt_hex(sub->keys[0].net_key, 16)); + + memcpy(&key.val[0], sub->keys[0].net_key, 16); + memcpy(&key.val[1], sub->keys[1].net_key, 16); + key.kr_flag = 0U; /* Deprecated */ + key.kr_phase = sub->kr_phase; + + snprintk(path, sizeof(path), "bt_mesh/cdb/Subnet/%x", sub->net_idx); + + + str = settings_str_from_bytes(&key, sizeof(key), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode Subnet as value"); + return; + } + err = settings_save_one(path, str); + if (err) { + BT_ERR("Failed to store Subnet value"); + } else { + BT_DBG("Stored Subnet value"); + } +} + +static void clear_cdb_subnet(uint16_t net_idx) +{ + char path[30]; + int err; + + BT_DBG("NetKeyIndex 0x%03x", net_idx); + + snprintk(path, sizeof(path), "bt_mesh/cdb/Subnet/%x", net_idx); + err = settings_save_one(path, NULL); + if (err) { + BT_ERR("Failed to clear NetKeyIndex 0x%03x", net_idx); + } else { + BT_DBG("Cleared NetKeyIndex 0x%03x", net_idx); + } +} + +static void store_cdb_app_key(const struct bt_mesh_cdb_app_key *app) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct app_key_val))]; + struct app_key_val key; + char path[30]; + int err; + char *str; + + key.net_idx = app->net_idx; + key.updated = false; + memcpy(key.val[0], app->keys[0].app_key, 16); + memcpy(key.val[1], app->keys[1].app_key, 16); + + snprintk(path, sizeof(path), "bt_mesh/cdb/AppKey/%x", app->app_idx); + + str = settings_str_from_bytes(&key, sizeof(key), buf, sizeof(buf)); + err = settings_save_one(path, str); + if (err) { + BT_ERR("Failed to store AppKey"); + } else { + BT_DBG("Stored AppKey"); + } +} + +static void clear_cdb_app_key(uint16_t app_idx) +{ + char path[30]; + int err; + + snprintk(path, sizeof(path), "bt_mesh/cdb/AppKey/%x", app_idx); + err = settings_save_one(path, NULL); + if (err) { + BT_ERR("Failed to clear AppKeyIndex 0x%03x", app_idx); + } else { + BT_DBG("Cleared AppKeyIndex 0x%03x", app_idx); + } +} + +static void schedule_cdb_store(int flag) +{ + atomic_set_bit(bt_mesh_cdb.flags, flag); + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CDB_PENDING); +} + +static void update_cdb_net_settings(void) +{ + schedule_cdb_store(BT_MESH_CDB_SUBNET_PENDING); +} + +static struct node_update *cdb_node_update_find(uint16_t addr, + struct node_update **free_slot) +{ + struct node_update *match; + int i; + + match = NULL; + *free_slot = NULL; + + for (i = 0; i < ARRAY_SIZE(cdb_node_updates); i++) { + struct node_update *update = &cdb_node_updates[i]; + + if (update->addr == BT_MESH_ADDR_UNASSIGNED) { + *free_slot = update; + continue; + } + + if (update->addr == addr) { + match = update; + } + } + + return match; +} + +static void update_cdb_node_settings(const struct bt_mesh_cdb_node *node, + bool store) +{ + struct node_update *update, *free_slot; + + BT_DBG("Node 0x%04x", node->addr); + + update = cdb_node_update_find(node->addr, &free_slot); + if (update) { + update->clear = !store; + schedule_cdb_store(BT_MESH_CDB_NODES_PENDING); + return; + } + + if (!free_slot) { + if (store) { + store_cdb_node(node); + } else { + clear_cdb_node(node->addr); + } + return; + } + + free_slot->addr = node->addr; + free_slot->clear = !store; + + schedule_cdb_store(BT_MESH_CDB_NODES_PENDING); +} + +static struct key_update *cdb_key_update_find(bool app_key, uint16_t key_idx, + struct key_update **free_slot) +{ + struct key_update *match; + int i; + + match = NULL; + *free_slot = NULL; + + for (i = 0; i < ARRAY_SIZE(cdb_key_updates); i++) { + struct key_update *update = &cdb_key_updates[i]; + + if (!update->valid) { + *free_slot = update; + continue; + } + + if (update->app_key != app_key) { + continue; + } + + if (update->key_idx == key_idx) { + match = update; + } + } + + return match; +} + +static void update_cdb_subnet_settings(const struct bt_mesh_cdb_subnet *sub, + bool store) +{ + struct key_update *update, *free_slot; + uint8_t clear = store ? 0U : 1U; + + BT_DBG("NetKeyIndex 0x%03x", sub->net_idx); + + update = cdb_key_update_find(false, sub->net_idx, &free_slot); + if (update) { + update->clear = clear; + schedule_cdb_store(BT_MESH_CDB_KEYS_PENDING); + return; + } + + if (!free_slot) { + if (store) { + store_cdb_subnet(sub); + } else { + clear_cdb_subnet(sub->net_idx); + } + return; + } + + free_slot->valid = 1U; + free_slot->key_idx = sub->net_idx; + free_slot->app_key = 0U; + free_slot->clear = clear; + + schedule_cdb_store(BT_MESH_CDB_KEYS_PENDING); +} + +static void update_cdb_app_key_settings(const struct bt_mesh_cdb_app_key *key, + bool store) +{ + struct key_update *update, *free_slot; + uint8_t clear = store ? 0U : 1U; + + BT_DBG("AppKeyIndex 0x%03x", key->app_idx); + + update = cdb_key_update_find(true, key->app_idx, &free_slot); + if (update) { + update->clear = clear; + schedule_cdb_store(BT_MESH_CDB_KEYS_PENDING); + return; + } + + if (!free_slot) { + if (store) { + store_cdb_app_key(key); + } else { + clear_cdb_app_key(key->app_idx); + } + + return; + } + + free_slot->valid = 1U; + free_slot->key_idx = key->app_idx; + free_slot->app_key = 1U; + free_slot->clear = clear; + + schedule_cdb_store(BT_MESH_CDB_KEYS_PENDING); +} + int bt_mesh_cdb_create(const uint8_t key[16]) { struct bt_mesh_cdb_subnet *sub; @@ -125,8 +702,8 @@ int bt_mesh_cdb_create(const uint8_t key[16]) bt_mesh_cdb.iv_index = 0; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_cdb(); - bt_mesh_store_cdb_subnet(sub); + update_cdb_net_settings(); + update_cdb_subnet_settings(sub, true); } return 0; @@ -157,7 +734,7 @@ void bt_mesh_cdb_clear(void) } if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_cdb(); + update_cdb_net_settings(); } } @@ -171,7 +748,7 @@ void bt_mesh_cdb_iv_update(uint32_t iv_index, bool iv_update) iv_update); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_cdb(); + update_cdb_net_settings(); } } @@ -204,7 +781,7 @@ void bt_mesh_cdb_subnet_del(struct bt_mesh_cdb_subnet *sub, bool store) BT_DBG("NetIdx 0x%03x store %u", sub->net_idx, store); if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) { - bt_mesh_clear_cdb_subnet(sub); + update_cdb_subnet_settings(sub, false); } sub->net_idx = BT_MESH_KEY_UNUSED; @@ -226,8 +803,8 @@ struct bt_mesh_cdb_subnet *bt_mesh_cdb_subnet_get(uint16_t net_idx) void bt_mesh_cdb_subnet_store(const struct bt_mesh_cdb_subnet *sub) { - if (MYNEWT_VAL(BLE_MESH_SETTINGS)) { - bt_mesh_store_cdb_subnet(sub); + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + update_cdb_subnet_settings(sub, true); } } @@ -283,7 +860,7 @@ void bt_mesh_cdb_node_del(struct bt_mesh_cdb_node *node, bool store) BT_DBG("Node addr 0x%04x store %u", node->addr, store); if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) { - bt_mesh_clear_cdb_node(node); + update_cdb_node_settings(node, false); } node->addr = BT_MESH_ADDR_UNASSIGNED; @@ -308,8 +885,8 @@ struct bt_mesh_cdb_node *bt_mesh_cdb_node_get(uint16_t addr) void bt_mesh_cdb_node_store(const struct bt_mesh_cdb_node *node) { - if (MYNEWT_VAL(BLE_MESH_SETTINGS)) { - bt_mesh_store_cdb_node(node); + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + update_cdb_node_settings(node, true); } } @@ -356,7 +933,7 @@ void bt_mesh_cdb_app_key_del(struct bt_mesh_cdb_app_key *key, bool store) BT_DBG("AppIdx 0x%03x store %u", key->app_idx, store); if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) { - bt_mesh_clear_cdb_app_key(key); + update_cdb_app_key_settings(key, false); } key->net_idx = BT_MESH_KEY_UNUSED; @@ -381,8 +958,164 @@ struct bt_mesh_cdb_app_key *bt_mesh_cdb_app_key_get(uint16_t app_idx) void bt_mesh_cdb_app_key_store(const struct bt_mesh_cdb_app_key *key) { - if (MYNEWT_VAL(BLE_MESH_SETTINGS)) { - bt_mesh_store_cdb_app_key(key); + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + update_cdb_app_key_settings(key, true); + } +} + +static void clear_cdb_net(void) +{ + char path[30]; + int err; + + snprintk(path, sizeof(path), "bt_mesh/cdb/Net"); + err = settings_save_one(path, NULL); + if (err) { + BT_ERR("Failed to clear Net"); + } else { + BT_DBG("Cleared NetKeyIndex 0x%03x"); + } +} + +static void store_cdb_pending_net(void) +{ + struct net_val net; + int err; + char buf[BT_SETTINGS_SIZE(sizeof(struct net_val))]; + char *str; + + BT_DBG(""); + + net.iv_index = bt_mesh_cdb.iv_index; + net.iv_update = atomic_test_bit(bt_mesh_cdb.flags, + BT_MESH_CDB_IVU_IN_PROGRESS); + + str = settings_str_from_bytes(&net, sizeof(net), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode Network as value"); + return; + } + err = settings_save_one("bt_mesh/cdb/Net", str); + if (err) { + BT_ERR("Failed to store Network value"); + } else { + BT_DBG("Stored Network value"); + } +} + +static void store_cdb_pending_nodes(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cdb_node_updates); ++i) { + struct node_update *update = &cdb_node_updates[i]; + + if (update->addr == BT_MESH_ADDR_UNASSIGNED) { + continue; + } + + BT_DBG("addr: 0x%04x, clear: %d", update->addr, update->clear); + + if (update->clear) { + clear_cdb_node(update->addr); + } else { + struct bt_mesh_cdb_node *node; + + node = bt_mesh_cdb_node_get(update->addr); + if (node) { + store_cdb_node(node); + } else { + BT_WARN("Node 0x%04x not found", update->addr); + } + } + + update->addr = BT_MESH_ADDR_UNASSIGNED; + } +} + +static void store_cdb_pending_keys(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cdb_key_updates); i++) { + struct key_update *update = &cdb_key_updates[i]; + + if (!update->valid) { + continue; + } + + if (update->clear) { + if (update->app_key) { + clear_cdb_app_key(update->key_idx); + } else { + clear_cdb_subnet(update->key_idx); + } + } else { + if (update->app_key) { + struct bt_mesh_cdb_app_key *key; + + key = bt_mesh_cdb_app_key_get(update->key_idx); + if (key) { + store_cdb_app_key(key); + } else { + BT_WARN("AppKeyIndex 0x%03x not found", + update->key_idx); + } + } else { + struct bt_mesh_cdb_subnet *sub; + + sub = bt_mesh_cdb_subnet_get(update->key_idx); + if (sub) { + store_cdb_subnet(sub); + } else { + BT_WARN("NetKeyIndex 0x%03x not found", + update->key_idx); + } + } + } + + update->valid = 0U; + } +} + +void bt_mesh_cdb_pending_store(void) +{ + if (atomic_test_and_clear_bit(bt_mesh_cdb.flags, + BT_MESH_CDB_SUBNET_PENDING)) { + if (atomic_test_bit(bt_mesh_cdb.flags, + BT_MESH_CDB_VALID)) { + store_cdb_pending_net(); + } else { + clear_cdb_net(); + } + } + + if (atomic_test_and_clear_bit(bt_mesh_cdb.flags, + BT_MESH_CDB_NODES_PENDING)) { + store_cdb_pending_nodes(); } + + if (atomic_test_and_clear_bit(bt_mesh_cdb.flags, + BT_MESH_CDB_KEYS_PENDING)) { + store_cdb_pending_keys(); + } +} + +static struct conf_handler bt_mesh_cdb_conf_handler = { + .ch_name = "bt_mesh", + .ch_get = NULL, + .ch_set = cdb_set, + .ch_commit = NULL, + .ch_export = NULL, +}; + +void bt_mesh_cdb_init(void) +{ + int rc; + + rc = conf_register(&bt_mesh_cdb_conf_handler); + + SYSINIT_PANIC_ASSERT_MSG(rc == 0, + "Failed to register bt_mesh_net conf"); } #endif diff --git a/nimble/host/mesh/src/cdb_priv.h b/nimble/host/mesh/src/cdb_priv.h new file mode 100644 index 0000000000..ff865a56fd --- /dev/null +++ b/nimble/host/mesh/src/cdb_priv.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* ommitted `bt_mesh_cdb_node_store` declaration - every header + * includes mesh/mesh.h, which already has it + * void bt_mesh_cdb_node_store(const struct bt_mesh_cdb_node *node); + */ +void bt_mesh_cdb_pending_store(void); +void bt_mesh_cdb_init(void); diff --git a/nimble/host/mesh/src/cfg.c b/nimble/host/mesh/src/cfg.c index 4e14925506..b9daa8fda2 100644 --- a/nimble/host/mesh/src/cfg.c +++ b/nimble/host/mesh/src/cfg.c @@ -15,6 +15,21 @@ #include "cfg.h" #include "mesh/glue.h" +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_CFG) +#define LOG_MODULE_NAME bt_mesh_cfg +#include "log/log.h" + +/* Miscellaneous configuration server model states */ +struct cfg_val { + uint8_t net_transmit; + uint8_t relay; + uint8_t relay_retransmit; + uint8_t beacon; + uint8_t gatt_proxy; + uint8_t frnd; + uint8_t default_ttl; +}; + void bt_mesh_beacon_set(bool beacon) { if (atomic_test_bit(bt_mesh.flags, BT_MESH_BEACON) == beacon) { @@ -31,7 +46,7 @@ void bt_mesh_beacon_set(bool beacon) if (IS_ENABLED(CONFIG_BT_SETTINGS) && atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - bt_mesh_store_cfg(); + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); } } @@ -82,7 +97,7 @@ int bt_mesh_gatt_proxy_set(enum bt_mesh_feat_state gatt_proxy) if (IS_ENABLED(CONFIG_BT_SETTINGS) && atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - bt_mesh_store_cfg(); + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); } return 0; @@ -111,7 +126,7 @@ int bt_mesh_default_ttl_set(uint8_t default_ttl) if (IS_ENABLED(CONFIG_BT_SETTINGS) && atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - bt_mesh_store_cfg(); + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); } return 0; @@ -139,7 +154,7 @@ int bt_mesh_friend_set(enum bt_mesh_feat_state friendship) if (IS_ENABLED(CONFIG_BT_SETTINGS) && atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - bt_mesh_store_cfg(); + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); } if (friendship == BT_MESH_FEATURE_DISABLED) { @@ -168,7 +183,7 @@ void bt_mesh_net_transmit_set(uint8_t xmit) if (IS_ENABLED(CONFIG_BT_SETTINGS) && atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - bt_mesh_store_cfg(); + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); } } @@ -199,7 +214,7 @@ int bt_mesh_relay_set(enum bt_mesh_feat_state relay, uint8_t xmit) if (IS_ENABLED(CONFIG_BT_SETTINGS) && atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - bt_mesh_store_cfg(); + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); } return 0; @@ -236,8 +251,112 @@ bool bt_mesh_fixed_group_match(uint16_t addr) } } +static int cfg_set(int argc, char **argv, char *val) +{ + struct cfg_val cfg; + int len, err; + + BT_DBG("val %s", val ? val : "(null)"); + + if (!val) { + BT_DBG("Cleared configuration state"); + return 0; + } + + len = sizeof(cfg); + err = settings_bytes_from_str(val, &cfg, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + + if (len != sizeof(cfg)) { + BT_ERR("Unexpected value length (%d != %zu)", len, + sizeof(cfg)); + return -EINVAL; + } + + bt_mesh_net_transmit_set(cfg.net_transmit); + bt_mesh_relay_set(cfg.relay, cfg.relay_retransmit); + bt_mesh_beacon_set(cfg.beacon); + bt_mesh_gatt_proxy_set(cfg.gatt_proxy); + bt_mesh_friend_set(cfg.frnd); + bt_mesh_default_ttl_set(cfg.default_ttl); + + BT_DBG("Restored configuration state"); + + return 0; +} + +static void clear_cfg(void) +{ + int err; + + err = settings_save_one("bt_mesh/Cfg", NULL); + if (err) { + BT_ERR("Failed to clear configuration"); + } else { + BT_DBG("Cleared configuration"); + } +} + +static void store_pending_cfg(void) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct cfg_val))]; + struct cfg_val val; + char *str; + int err; + + val.net_transmit = bt_mesh_net_transmit_get(); + val.relay = bt_mesh_relay_get(); + val.relay_retransmit = bt_mesh_relay_retransmit_get(); + val.beacon = bt_mesh_beacon_enabled(); + val.gatt_proxy = bt_mesh_gatt_proxy_get(); + val.frnd = bt_mesh_friend_get(); + val.default_ttl = bt_mesh_default_ttl_get(); + + str = settings_str_from_bytes(&val, sizeof(val), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode configuration as value"); + return; + } + + BT_DBG("Saving configuration as value %s", str); + err = settings_save_one("bt_mesh/Cfg", str); + if (err) { + BT_ERR("Failed to store configuration"); + } else { + BT_DBG("Stored configuration"); + } +} + + +void bt_mesh_cfg_pending_store(void) +{ + if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { + store_pending_cfg(); + } else { + clear_cfg(); + } +} + +static struct conf_handler bt_mesh_cfg_conf_handler = { + .ch_name = "bt_mesh", + .ch_get = NULL, + .ch_set = cfg_set, + .ch_commit = NULL, + .ch_export = NULL, +}; + void bt_mesh_cfg_init(void) { + int rc; + + rc = conf_register(&bt_mesh_cfg_conf_handler); + + SYSINIT_PANIC_ASSERT_MSG(rc == 0, + "Failed to register bt_mesh_settings conf"); + bt_mesh.default_ttl = CONFIG_BT_MESH_DEFAULT_TTL; bt_mesh.net_xmit = BT_MESH_TRANSMIT(CONFIG_BT_MESH_NETWORK_TRANSMIT_COUNT, diff --git a/nimble/host/mesh/src/cfg.h b/nimble/host/mesh/src/cfg.h index 6f58acf8b0..40f7ed92bc 100644 --- a/nimble/host/mesh/src/cfg.h +++ b/nimble/host/mesh/src/cfg.h @@ -5,5 +5,6 @@ */ void bt_mesh_cfg_init(void); +void bt_mesh_cfg_pending_store(void); bool bt_mesh_fixed_group_match(uint16_t addr); \ No newline at end of file diff --git a/nimble/host/mesh/src/cfg_srv.c b/nimble/host/mesh/src/cfg_srv.c index 404f7318d4..4c0da372ba 100644 --- a/nimble/host/mesh/src/cfg_srv.c +++ b/nimble/host/mesh/src/cfg_srv.c @@ -204,7 +204,7 @@ static uint8_t _mod_pub_set(struct bt_mesh_model *model, uint16_t pub_addr, } if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) { - bt_mesh_store_mod_pub(model); + bt_mesh_model_pub_store(model); } return STATUS_SUCCESS; @@ -245,7 +245,7 @@ static uint8_t _mod_pub_set(struct bt_mesh_model *model, uint16_t pub_addr, } if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) { - bt_mesh_store_mod_pub(model); + bt_mesh_model_pub_store(model); } return STATUS_SUCCESS; @@ -273,7 +273,7 @@ uint8_t mod_bind(struct bt_mesh_model *model, uint16_t key_idx) model->keys[i] = key_idx; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_mod_bind(model); + bt_mesh_model_bind_store(model); } return STATUS_SUCCESS; @@ -301,7 +301,7 @@ uint8_t mod_unbind(struct bt_mesh_model *model, uint16_t key_idx, bool store) model->keys[i] = BT_MESH_KEY_UNUSED; if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) { - bt_mesh_store_mod_bind(model); + bt_mesh_model_bind_store(model); } if (model->pub && model->pub->key == key_idx) { @@ -1040,7 +1040,7 @@ static void mod_sub_add(struct bt_mesh_model *model, status = STATUS_SUCCESS; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_mod_sub(mod); + bt_mesh_model_sub_store(mod); } if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { @@ -1110,7 +1110,7 @@ static void mod_sub_del(struct bt_mesh_model *model, *match = BT_MESH_ADDR_UNASSIGNED; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_mod_sub(mod); + bt_mesh_model_sub_store(mod); } } @@ -1181,7 +1181,7 @@ static void mod_sub_overwrite(struct bt_mesh_model *model, status = STATUS_SUCCESS; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_mod_sub(mod); + bt_mesh_model_sub_store(mod); } if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { @@ -1236,7 +1236,7 @@ static void mod_sub_del_all(struct bt_mesh_model *model, NULL); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_mod_sub(mod); + bt_mesh_model_sub_store(mod); } status = STATUS_SUCCESS; @@ -1470,7 +1470,7 @@ static void mod_sub_va_add(struct bt_mesh_model *model, } if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_mod_sub(mod); + bt_mesh_model_sub_store(mod); } status = STATUS_SUCCESS; @@ -1535,7 +1535,7 @@ static void mod_sub_va_del(struct bt_mesh_model *model, *match = BT_MESH_ADDR_UNASSIGNED; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_mod_sub(mod); + bt_mesh_model_sub_store(mod); } status = STATUS_SUCCESS; @@ -1594,7 +1594,7 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, mod->groups[0] = sub_addr; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_mod_sub(mod); + bt_mesh_model_sub_store(mod); } if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { @@ -2492,7 +2492,7 @@ static void mod_reset(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, if (IS_ENABLED(CONFIG_BT_SETTINGS)) { if (clear_count) { - bt_mesh_store_mod_sub(mod); + bt_mesh_model_sub_store(mod); } } diff --git a/nimble/host/mesh/src/heartbeat.c b/nimble/host/mesh/src/heartbeat.c index 09d64594de..656942b426 100644 --- a/nimble/host/mesh/src/heartbeat.c +++ b/nimble/host/mesh/src/heartbeat.c @@ -17,6 +17,16 @@ #include "foundation.h" #include "mesh/glue.h" +/* Heartbeat Publication information for persistent storage. */ +struct hb_pub_val { + uint16_t dst; + uint8_t period; + uint8_t ttl; + uint16_t feat; + uint16_t net_idx:12, + indefinite:1; +}; + struct bt_mesh_hb_cb hb_cb; static struct bt_mesh_hb_pub pub; @@ -215,7 +225,8 @@ uint8_t bt_mesh_hb_pub_set(struct bt_mesh_hb_pub *new_pub) if (IS_ENABLED(CONFIG_BT_SETTINGS) && bt_mesh_is_provisioned()) { - bt_mesh_store_hb_pub(); + bt_mesh_settings_store_schedule( + BT_MESH_SETTINGS_HB_PUB_PENDING); } return STATUS_SUCCESS; @@ -244,7 +255,8 @@ uint8_t bt_mesh_hb_pub_set(struct bt_mesh_hb_pub *new_pub) } if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_hb_pub(); + bt_mesh_settings_store_schedule( + BT_MESH_SETTINGS_HB_PUB_PENDING); } return STATUS_SUCCESS; @@ -356,3 +368,91 @@ void bt_mesh_hb_resume(void) k_delayed_work_submit(&pub_timer, K_NO_WAIT); } } + +static int hb_pub_set(int argc, char **argv, char *val) +{ + struct bt_mesh_hb_pub pub; + struct hb_pub_val hb_val; + int len, err; + BT_DBG("val %s", val ? val : "(null)"); + len = sizeof(hb_val); + err = settings_bytes_from_str(val, &hb_val, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + if (len != sizeof(hb_val)) { + BT_ERR("Unexpected value length (%d != %zu)", len, + sizeof(hb_val)); + return -EINVAL; + } + pub.dst = hb_val.dst; + pub.period = bt_mesh_hb_pwr2(hb_val.period); + pub.ttl = hb_val.ttl; + pub.feat = hb_val.feat; + pub.net_idx = hb_val.net_idx; + if (hb_val.indefinite) { + pub.count = 0xffff; + } else { + pub.count = 0; + } + (void) bt_mesh_hb_pub_set(&pub); + + BT_DBG("Restored heartbeat publication"); + + return 0; +} + +void bt_mesh_hb_pub_pending_store(void) +{ + struct bt_mesh_hb_pub pub; + char buf[BT_SETTINGS_SIZE(sizeof(struct hb_pub_val))]; + struct hb_pub_val val; + int err; + char *str; + + bt_mesh_hb_pub_get(&pub); + if (pub.dst == BT_MESH_ADDR_UNASSIGNED) { + err = settings_save_one("bt_mesh/HBPub", NULL); + } else { + val.indefinite = (pub.count == 0xffff); + val.dst = pub.dst; + val.period = bt_mesh_hb_log(pub.period); + val.ttl = pub.ttl; + val.feat = pub.feat; + val.net_idx = pub.net_idx; + + str = settings_str_from_bytes(&val, sizeof(val), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode configuration as value"); + return; + } + + BT_DBG("Saving configuration as value %s", str); + err = settings_save_one("bt_mesh/HBPub", str); + } + + if (err) { + BT_ERR("Failed to store Heartbeat Publication"); + } else { + BT_DBG("Stored Heartbeat Publication"); + } +} + +static struct conf_handler bt_mesh_hb_pub_conf_handler = { + .ch_name = "bt_mesh", + .ch_get = NULL, + .ch_set = hb_pub_set, + .ch_commit = NULL, + .ch_export = NULL, + }; + +void bt_mesh_hb_pub_init(void) +{ + int rc; + + rc = conf_register(&bt_mesh_hb_pub_conf_handler); + + SYSINIT_PANIC_ASSERT_MSG(rc == 0, + "Failed to register bt_mesh_hb_pub conf"); +} \ No newline at end of file diff --git a/nimble/host/mesh/src/heartbeat.h b/nimble/host/mesh/src/heartbeat.h index 92b0cae9e4..7fcfacf197 100644 --- a/nimble/host/mesh/src/heartbeat.h +++ b/nimble/host/mesh/src/heartbeat.h @@ -39,3 +39,5 @@ void bt_mesh_hb_feature_changed(uint16_t features); uint8_t bt_mesh_hb_pub_set(struct bt_mesh_hb_pub *hb_pub); uint8_t bt_mesh_hb_sub_set(uint16_t src, uint16_t dst, uint32_t period); void bt_mesh_hb_sub_reset_count(void); +void bt_mesh_hb_pub_pending_store(void); +void bt_mesh_hb_pub_init(void); \ No newline at end of file diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c index 10c6fff991..b22dc1363f 100644 --- a/nimble/host/mesh/src/mesh.c +++ b/nimble/host/mesh/src/mesh.c @@ -108,7 +108,7 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, memcpy(node->dev_key, dev_key, 16); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_cdb_node(node); + bt_mesh_cdb_node_store(node); } } @@ -199,7 +199,7 @@ void bt_mesh_reset(void) } if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_clear_net(); + bt_mesh_net_clear(); } memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key)); @@ -338,6 +338,17 @@ int bt_mesh_init(uint8_t own_addr_type, const struct bt_mesh_prov *prov, } #endif + bt_mesh_app_key_init(); + bt_mesh_access_init(); + bt_mesh_hb_pub_init(); + bt_mesh_rpl_init(); + bt_mesh_net_key_init(); +#if CONFIG_BT_MESH_LABEL_COUNT > 0 + bt_mesh_va_init(); +#endif +#if CONFIG_BT_MESH_CDB + bt_mesh_cdb_init(); +#endif bt_mesh_cfg_init(); bt_mesh_net_init(); bt_mesh_trans_init(); diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index bbe186ec8d..76ef9eaef8 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -49,6 +49,31 @@ #define SRC(pdu) (sys_get_be16(&(pdu)[5])) #define DST(pdu) (sys_get_be16(&(pdu)[7])) +/** Define CONFIG_BT_MESH_SEQ_STORE_RATE even if settings are disabled to + * compile the code. + */ +#ifndef CONFIG_BT_SETTINGS +#define CONFIG_BT_MESH_SEQ_STORE_RATE 1 +#endif + +/* Mesh network information for persistent storage. */ +struct net_val { + uint16_t primary_addr; + uint8_t dev_key[16]; +} __packed; + +/* Sequence number information for persistent storage. */ +struct seq_val { + uint8_t val[3]; +} __packed; + +/* IV Index & IV Update information for persistent storage. */ +struct iv_val { + uint32_t iv_index; + uint8_t iv_update:1, + iv_duration:7; +} __packed; + static struct { uint32_t src : 15, /* MSb of source is always 0 */ seq : 17; @@ -112,6 +137,31 @@ static void msg_cache_add(struct bt_mesh_net_rx *rx) msg_cache_next %= ARRAY_SIZE(msg_cache); } +static void store_net(void) +{ + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_NET_PENDING); +} + +static void store_iv(bool only_duration) +{ + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_IV_PENDING); + + if (!only_duration) { + /* Always update Seq whenever IV changes */ + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_SEQ_PENDING); + } +} + +static void store_seq(void) +{ + if (CONFIG_BT_MESH_SEQ_STORE_RATE && + (bt_mesh.seq % CONFIG_BT_MESH_SEQ_STORE_RATE)) { + return; + } + + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_SEQ_PENDING); +} + int bt_mesh_net_create(uint16_t idx, uint8_t flags, const uint8_t key[16], uint32_t iv_index) { @@ -147,9 +197,9 @@ int bt_mesh_net_create(uint16_t idx, uint8_t flags, const uint8_t key[16], if (IS_ENABLED(CONFIG_BT_SETTINGS)) { BT_DBG("Storing network information persistently"); - bt_mesh_store_net(); - bt_mesh_store_subnet(idx); - bt_mesh_store_iv(false); + store_net(); + bt_mesh_subnet_store(idx); + store_iv(false); } return 0; @@ -282,7 +332,7 @@ bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update) } if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_iv(false); + store_iv(false); } return true; @@ -293,7 +343,7 @@ uint32_t bt_mesh_next_seq(void) uint32_t seq = bt_mesh.seq++; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_seq(); + store_seq(); } if (!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) && @@ -822,7 +872,7 @@ static void ivu_refresh(struct ble_npl_event *work) if (bt_mesh.ivu_duration < BT_MESH_IVU_MIN_HOURS) { if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_iv(true); + store_iv(true); } k_delayed_work_submit(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT); @@ -833,14 +883,164 @@ static void ivu_refresh(struct ble_npl_event *work) bt_mesh_beacon_ivu_initiator(true); bt_mesh_net_iv_update(bt_mesh.iv_index, false); } else if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_iv(true); + store_iv(true); + } +} + +static int net_set(int argc, char **argv, char *val) +{ + struct net_val net; + int len, err; + + BT_DBG("val %s", val ? val : "(null)"); + + if (!val) { + bt_mesh_comp_unprovision(); + memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key)); + return 0; + } + + len = sizeof(net); + err = settings_bytes_from_str(val, &net, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + + if (len != sizeof(net)) { + BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(net)); + return -EINVAL; + } + + memcpy(bt_mesh.dev_key, net.dev_key, sizeof(bt_mesh.dev_key)); + bt_mesh_comp_provision(net.primary_addr); + + BT_DBG("Provisioned with primary address 0x%04x", net.primary_addr); + BT_DBG("Recovered DevKey %s", bt_hex(bt_mesh.dev_key, 16)); + + return 0; +} + +static int iv_set(int argc, char **argv, char *val) +{ + struct iv_val iv; + int len, err; + + BT_DBG("val %s", val ? val : "(null)"); + + if (!val) { + bt_mesh.iv_index = 0U; + atomic_clear_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS); + return 0; + } + + len = sizeof(iv); + err = settings_bytes_from_str(val, &iv, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + + if (len != sizeof(iv)) { + BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(iv)); + return -EINVAL; + } + + bt_mesh.iv_index = iv.iv_index; + atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS, iv.iv_update); + bt_mesh.ivu_duration = iv.iv_duration; + + BT_DBG("IV Index 0x%04x (IV Update Flag %u) duration %u hours", + (unsigned) iv.iv_index, iv.iv_update, iv.iv_duration); + + return 0; +} + +static int seq_set(int argc, char **argv, char *val) +{ + struct seq_val seq; + int len, err; + + BT_DBG("val %s", val ? val : "(null)"); + + if (!val) { + bt_mesh.seq = 0; + return 0; + } + + len = sizeof(seq); + err = settings_bytes_from_str(val, &seq, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + + if (len != sizeof(seq)) { + BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(seq)); + return -EINVAL; + } + + bt_mesh.seq = sys_get_le24(seq.val); + + if (CONFIG_BT_MESH_SEQ_STORE_RATE > 0) { + /* Make sure we have a large enough sequence number. We + * subtract 1 so that the first transmission causes a write + * to the settings storage. + */ + bt_mesh.seq += (CONFIG_BT_MESH_SEQ_STORE_RATE - + (bt_mesh.seq % CONFIG_BT_MESH_SEQ_STORE_RATE)); + bt_mesh.seq--; } + + BT_DBG("Sequence Number 0x%06x", bt_mesh.seq); + + return 0; } +static struct conf_handler bt_mesh_net_conf_handler = { + .ch_name = "bt_mesh", + .ch_get = NULL, + .ch_set = net_set, + .ch_commit = NULL, + .ch_export = NULL, +}; + +static struct conf_handler bt_mesh_iv_conf_handler = { + .ch_name = "bt_mesh", + .ch_get = NULL, + .ch_set = iv_set, + .ch_commit = NULL, + .ch_export = NULL, +}; + +static struct conf_handler bt_mesh_seq_conf_handler = { + .ch_name = "bt_mesh", + .ch_get = NULL, + .ch_set = seq_set, + .ch_commit = NULL, + .ch_export = NULL, +}; + void bt_mesh_net_init(void) { int rc; + rc = conf_register(&bt_mesh_net_conf_handler); + + SYSINIT_PANIC_ASSERT_MSG(rc == 0, + "Failed to register bt_mesh_net conf"); + + + rc = conf_register(&bt_mesh_iv_conf_handler); + + SYSINIT_PANIC_ASSERT_MSG(rc == 0, + "Failed to register bt_mesh_iv conf"); + + rc = conf_register(&bt_mesh_seq_conf_handler); + + SYSINIT_PANIC_ASSERT_MSG(rc == 0, + "Failed to register bt_mesh_seq conf"); + k_delayed_work_init(&bt_mesh.ivu_timer, ivu_refresh); k_work_init(&bt_mesh.local_work, bt_mesh_net_local); @@ -852,7 +1052,141 @@ void bt_mesh_net_init(void) assert(rc == 0); rc = os_mbuf_pool_init(&loopback_os_mbuf_pool, &loopback_buf_mempool, - LOOPBACK_MAX_PDU_LEN + BT_MESH_MBUF_HEADER_SIZE, - MYNEWT_VAL(BLE_MESH_LOOPBACK_BUFS)); + LOOPBACK_MAX_PDU_LEN + BT_MESH_MBUF_HEADER_SIZE, + MYNEWT_VAL(BLE_MESH_LOOPBACK_BUFS)); assert(rc == 0); } + +static void clear_iv(void) +{ + int err; + + err = settings_save_one("bt_mesh/IV", NULL); + if (err) { + BT_ERR("Failed to clear IV"); + } else { + BT_DBG("Cleared IV"); + } +} + +static void store_pending_iv(void) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct iv_val))]; + struct iv_val iv; + char *str; + int err; + + iv.iv_index = bt_mesh.iv_index; + iv.iv_update = atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS); + iv.iv_duration = bt_mesh.ivu_duration; + + str = settings_str_from_bytes(&iv, sizeof(iv), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode IV as value"); + return; + } + + BT_DBG("Saving IV as value %s", str); + err = settings_save_one("bt_mesh/IV", str); + if (err) { + BT_ERR("Failed to store IV"); + } else { + BT_DBG("Stored IV"); + } +} + +void bt_mesh_net_pending_iv_store(void) +{ + if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { + store_pending_iv(); + } else { + clear_iv(); + } +} + +static void clear_net(void) +{ + int err; + + err = settings_save_one("bt_mesh/Net", NULL); + if (err) { + BT_ERR("Failed to clear Network"); + } else { + BT_DBG("Cleared Network"); + } +} + +static void store_pending_net(void) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct net_val))]; + struct net_val net; + char *str; + int err; + + BT_DBG("addr 0x%04x DevKey %s", bt_mesh_primary_addr(), + bt_hex(bt_mesh.dev_key, 16)); + + net.primary_addr = bt_mesh_primary_addr(); + memcpy(net.dev_key, bt_mesh.dev_key, 16); + + str = settings_str_from_bytes(&net, sizeof(net), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode Network as value"); + return; + } + + BT_DBG("Saving Network as value %s", str); + err = settings_save_one("bt_mesh/Net", str); + if (err) { + BT_ERR("Failed to store Network"); + } else { + BT_DBG("Stored Network"); + } +} + +void bt_mesh_net_pending_net_store(void) +{ + if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { + store_pending_net(); + } else { + clear_net(); + } +} + +void bt_mesh_net_pending_seq_store(void) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct seq_val))]; + char *str; + struct seq_val seq; + int err; + + sys_put_le24(bt_mesh.seq, seq.val); + + str = settings_str_from_bytes(&seq, sizeof(seq), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode Network as value"); + return; + } + + BT_DBG("Saving Network as value %s", str); + err = settings_save_one("bt_mesh/Seq", str); + if (err) { + BT_ERR("Failed to stor Seq value"); + } else { + BT_DBG("Stored Seq value"); + } +} + +void bt_mesh_net_clear(void) +{ + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_NET_PENDING); + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_IV_PENDING); + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); +} + +void bt_mesh_net_settings_commit(void) +{ + if (bt_mesh.ivu_duration < BT_MESH_IVU_MIN_HOURS) { + k_delayed_work_submit(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT); + } +} diff --git a/nimble/host/mesh/src/net.h b/nimble/host/mesh/src/net.h index 8c501540df..33b491e4b5 100644 --- a/nimble/host/mesh/src/net.h +++ b/nimble/host/mesh/src/net.h @@ -184,17 +184,6 @@ enum { BT_MESH_IVU_TEST, /* IV Update test mode */ BT_MESH_IVU_PENDING, /* Update blocked by SDU in progress */ - /* pending storage actions, must reside within first 32 flags */ - BT_MESH_RPL_PENDING, - BT_MESH_KEYS_PENDING, - BT_MESH_NET_PENDING, - BT_MESH_IV_PENDING, - BT_MESH_SEQ_PENDING, - BT_MESH_HB_PUB_PENDING, - BT_MESH_CFG_PENDING, - BT_MESH_MOD_PENDING, - BT_MESH_VA_PENDING, - /* Feature flags */ BT_MESH_RELAY, BT_MESH_BEACON, @@ -309,7 +298,11 @@ uint32_t bt_mesh_next_seq(void); void bt_mesh_net_init(void); void bt_mesh_net_header_parse(struct os_mbuf *buf, struct bt_mesh_net_rx *rx); - +void bt_mesh_net_pending_net_store(void); +void bt_mesh_net_pending_iv_store(void); +void bt_mesh_net_pending_seq_store(void); +void bt_mesh_net_clear(void); +void bt_mesh_net_settings_commit(void); static inline void send_cb_finalize(const struct bt_mesh_send_cb *cb, void *cb_data) diff --git a/nimble/host/mesh/src/provisioner.c b/nimble/host/mesh/src/provisioner.c index 2e592096e1..3b4b76598d 100644 --- a/nimble/host/mesh/src/provisioner.c +++ b/nimble/host/mesh/src/provisioner.c @@ -541,7 +541,7 @@ static void prov_complete(const uint8_t *data) #if MYNEWT_VAL(BLE_MESH_CDB) if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_cdb_node(node); + bt_mesh_cdb_node_store(node); } #endif diff --git a/nimble/host/mesh/src/rpl.c b/nimble/host/mesh/src/rpl.c index 93c2e1a885..830ab1b01e 100644 --- a/nimble/host/mesh/src/rpl.c +++ b/nimble/host/mesh/src/rpl.c @@ -10,6 +10,7 @@ #define MESH_LOG_MODULE BLE_MESH_RPL_LOG #include "log/log.h" +#include #include "mesh_priv.h" #include "adv.h" @@ -17,8 +18,27 @@ #include "rpl.h" #include "settings.h" +/* Replay Protection List information for persistent storage. */ +struct rpl_val { + uint32_t seq:24, + old_iv:1; +}; + static struct bt_mesh_rpl replay_list[MYNEWT_VAL(BLE_MESH_CRPL)]; +static void schedule_rpl_store(struct bt_mesh_rpl *entry) +{ +#ifdef CONFIG_BT_SETTINGS + entry->store = true; +#endif + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); +} + +static void schedule_rpl_clear(void) +{ + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); +} + void bt_mesh_rpl_update(struct bt_mesh_rpl *rpl, struct bt_mesh_net_rx *rx) { @@ -27,7 +47,7 @@ void bt_mesh_rpl_update(struct bt_mesh_rpl *rpl, rpl->old_iv = rx->old_iv; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_rpl(rpl); + schedule_rpl_store(rpl); } } @@ -95,13 +115,13 @@ void bt_mesh_rpl_clear(void) BT_DBG(""); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_clear_rpl(); + schedule_rpl_clear(); } else { (void)memset(replay_list, 0, sizeof(replay_list)); } } -struct bt_mesh_rpl *bt_mesh_rpl_find(uint16_t src) +static struct bt_mesh_rpl *bt_mesh_rpl_find(uint16_t src) { int i; @@ -114,7 +134,7 @@ struct bt_mesh_rpl *bt_mesh_rpl_find(uint16_t src) return NULL; } -struct bt_mesh_rpl *bt_mesh_rpl_alloc(uint16_t src) +static struct bt_mesh_rpl *bt_mesh_rpl_alloc(uint16_t src) { int i; @@ -128,15 +148,6 @@ struct bt_mesh_rpl *bt_mesh_rpl_alloc(uint16_t src) return NULL; } -void bt_mesh_rpl_foreach(bt_mesh_rpl_func_t func, void *user_data) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(replay_list); i++) { - func(&replay_list[i], user_data); - } -} - void bt_mesh_rpl_reset(void) { int i; @@ -155,8 +166,159 @@ void bt_mesh_rpl_reset(void) } if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_rpl(rpl); + schedule_rpl_store(rpl); } } } +} + +static int rpl_set(int argc, char **argv, char *val) +{ + struct bt_mesh_rpl *entry; + struct rpl_val rpl; + int len, err; + uint16_t src; + + if (argc < 1) { + BT_ERR("Invalid argc (%d)", argc); + return -ENOENT; + } + + BT_DBG("argv[0] %s val %s", argv[0], val ? val : "(null)"); + + src = strtol(argv[0], NULL, 16); + entry = bt_mesh_rpl_find(src); + + if (!val) { + if (entry) { + memset(entry, 0, sizeof(*entry)); + } else { + BT_WARN("Unable to find RPL entry for 0x%04x", src); + } + + return 0; + } + + if (!entry) { + entry = bt_mesh_rpl_alloc(src); + if (!entry) { + BT_ERR("Unable to allocate RPL entry for 0x%04x", src); + return -ENOMEM; + } + } + + len = sizeof(rpl); + err = settings_bytes_from_str(val, &rpl, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + + if (len != sizeof(rpl)) { + BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(rpl)); + return -EINVAL; + } + + entry->seq = rpl.seq; + entry->old_iv = rpl.old_iv; + + BT_DBG("RPL entry for 0x%04x: Seq 0x%06x old_iv %u", entry->src, + (unsigned) entry->seq, entry->old_iv); + return 0; +} + +static void store_rpl(struct bt_mesh_rpl *entry) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct rpl_val))]; + struct rpl_val rpl; + char path[18]; + char *str; + int err; + + BT_DBG("src 0x%04x seq 0x%06x old_iv %u", entry->src, + (unsigned) entry->seq, entry->old_iv); + + rpl.seq = entry->seq; + rpl.old_iv = entry->old_iv; + + str = settings_str_from_bytes(&rpl, sizeof(rpl), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode RPL as value"); + return; + } + + snprintk(path, sizeof(path), "bt_mesh/RPL/%x", entry->src); + + BT_DBG("Saving RPL %s as value %s", path, str); + err = settings_save_one(path, str); + if (err) { + BT_ERR("Failed to store RPL"); + } else { + BT_DBG("Stored RPL"); + } +} + +static void clear_rpl(struct bt_mesh_rpl *rpl) +{ + int err; + char path[18]; + + if (!rpl->src) { + return; + } + + snprintk(path, sizeof(path), "bt_mesh/RPL/%x", rpl->src); + err = settings_save_one(path, NULL); + if (err) { + BT_ERR("Failed to clear RPL"); + } else { + BT_DBG("Cleared RPL"); + } + + (void)memset(rpl, 0, sizeof(*rpl)); +} + +static void store_pending_rpl(struct bt_mesh_rpl *rpl) +{ + BT_DBG(""); + +#ifdef CONFIG_BT_SETTINGS + if (!rpl->store) { + return; + } + + rpl->store = false; +#endif + store_rpl(rpl); +} + +void bt_mesh_rpl_pending_store(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(replay_list); i++) { + if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { + store_pending_rpl(&replay_list[i]); + } else { + clear_rpl(&replay_list[i]); + } + } +} + +static struct conf_handler bt_mesh_rpl_conf_handler = { + .ch_name = "bt_mesh", + .ch_get = NULL, + .ch_set = rpl_set, + .ch_commit = NULL, + .ch_export = NULL, + }; + +void bt_mesh_rpl_init(void) +{ + int rc; + + rc = conf_register(&bt_mesh_rpl_conf_handler); + + SYSINIT_PANIC_ASSERT_MSG(rc == 0, + "Failed to register bt_mesh_rpl conf"); } \ No newline at end of file diff --git a/nimble/host/mesh/src/rpl.h b/nimble/host/mesh/src/rpl.h index 0592712f87..d47484a329 100644 --- a/nimble/host/mesh/src/rpl.h +++ b/nimble/host/mesh/src/rpl.h @@ -23,8 +23,7 @@ void bt_mesh_rpl_reset(void); bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx, struct bt_mesh_rpl **match); void bt_mesh_rpl_clear(void); -struct bt_mesh_rpl *bt_mesh_rpl_find(uint16_t src); -struct bt_mesh_rpl *bt_mesh_rpl_alloc(uint16_t src); -void bt_mesh_rpl_foreach(bt_mesh_rpl_func_t func, void *user_data); void bt_mesh_rpl_update(struct bt_mesh_rpl *rpl, - struct bt_mesh_net_rx *rx); \ No newline at end of file + struct bt_mesh_net_rx *rx); +void bt_mesh_rpl_pending_store(void); +void bt_mesh_rpl_init(void); \ No newline at end of file diff --git a/nimble/host/mesh/src/settings.c b/nimble/host/mesh/src/settings.c index 903230d1b5..3d28ac94da 100644 --- a/nimble/host/mesh/src/settings.c +++ b/nimble/host/mesh/src/settings.c @@ -10,144 +10,25 @@ #if MYNEWT_VAL(BLE_MESH_SETTINGS) #include "mesh_priv.h" -#include "mesh/mesh.h" #include "mesh/glue.h" #include "subnet.h" #include "app_keys.h" #include "net.h" +#include "cdb_priv.h" #include "rpl.h" #include "crypto.h" #include "transport.h" #include "heartbeat.h" #include "access.h" -#include "foundation.h" #include "proxy.h" #include "settings.h" -#include "lpn.h" #include "cfg.h" #include "config/config.h" -/* Tracking of what storage changes are pending for App and Net Keys. We - * track this in a separate array here instead of within the respective - * bt_mesh_app_key and bt_mesh_subnet structs themselves, since once a key - * gets deleted its struct becomes invalid and may be reused for other keys. - */ -struct key_update { - uint16_t key_idx:12, /* AppKey or NetKey Index */ - valid:1, /* 1 if this entry is valid, 0 if not */ - app_key:1, /* 1 if this is an AppKey, 0 if a NetKey */ - clear:1; /* 1 if key needs clearing, 0 if storing */ -}; - -static struct key_update key_updates[CONFIG_BT_MESH_APP_KEY_COUNT + - CONFIG_BT_MESH_SUBNET_COUNT]; - static struct k_delayed_work pending_store; - -/* Mesh network storage information */ -struct net_val { - uint16_t primary_addr; - uint8_t dev_key[16]; -} __packed; - -/* Sequence number storage */ -struct seq_val { - uint8_t val[3]; -} __packed; - -/* Heartbeat Publication storage */ -struct hb_pub_val { - uint16_t dst; - uint8_t period; - uint8_t ttl; - uint16_t feat; - uint16_t net_idx:12, - indefinite:1; -}; - -/* Miscelaneous configuration server model states */ -struct cfg_val { - uint8_t net_transmit; - uint8_t relay; - uint8_t relay_retransmit; - uint8_t beacon; - uint8_t gatt_proxy; - uint8_t frnd; - uint8_t default_ttl; -}; - -/* IV Index & IV Update storage */ -struct iv_val { - uint32_t iv_index; - uint8_t iv_update:1, - iv_duration:7; -} __packed; - -/* Replay Protection List storage */ -struct rpl_val { - uint32_t seq:24, - old_iv:1; -}; - -/* NetKey storage information */ -struct net_key_val { - uint8_t kr_flag:1, - kr_phase:7; - uint8_t val[2][16]; -} __packed; - -/* AppKey storage information */ -struct app_key_val { - uint16_t net_idx; - bool updated; - uint8_t val[2][16]; -} __packed; - -struct mod_pub_val { - uint16_t addr; - uint16_t key; - uint8_t ttl; - uint8_t retransmit; - uint8_t period; - uint8_t period_div:4, - cred:1; -}; - -/* Virtual Address information */ -struct va_val { - uint16_t ref; - uint16_t addr; - uint8_t uuid[16]; -} __packed; - -struct cdb_net_val { - uint32_t iv_index; - bool iv_update; -} __packed; - -/* Node storage information */ -struct node_val { - uint16_t net_idx; - uint8_t num_elem; - uint8_t flags; -#define F_NODE_CONFIGURED 0x01 - uint8_t uuid[16]; - uint8_t dev_key[16]; -} __packed; - -struct node_update { - uint16_t addr; - bool clear; -}; - -#if MYNEWT_VAL(BLE_MESH_CDB) -static struct node_update cdb_node_updates[MYNEWT_VAL(BLE_MESH_CDB_NODE_COUNT)]; -static struct key_update cdb_key_updates[ - MYNEWT_VAL(BLE_MESH_CDB_SUBNET_COUNT) + - MYNEWT_VAL(BLE_MESH_CDB_APP_KEY_COUNT)]; -#endif +static ATOMIC_DEFINE(pending_flags, BT_MESH_SETTINGS_FLAG_COUNT); int settings_name_next(char *name, char **next) { @@ -181,2269 +62,132 @@ int settings_name_next(char *name, char **next) return rc; } -static int net_set(int argc, char **argv, char *val) -{ - struct net_val net; - int len, err; - - BT_DBG("val %s", val ? val : "(null)"); - - if (!val) { - bt_mesh_comp_unprovision(); - memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key)); - return 0; - } - - len = sizeof(net); - err = settings_bytes_from_str(val, &net, &len); - if (err) { - BT_ERR("Failed to decode value %s (err %d)", val, err); - return err; - } - - if (len != sizeof(net)) { - BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(net)); - return -EINVAL; - } - - memcpy(bt_mesh.dev_key, net.dev_key, sizeof(bt_mesh.dev_key)); - bt_mesh_comp_provision(net.primary_addr); - - BT_DBG("Provisioned with primary address 0x%04x", net.primary_addr); - BT_DBG("Recovered DevKey %s", bt_hex(bt_mesh.dev_key, 16)); - - return 0; -} - -static int iv_set(int argc, char **argv, char *val) -{ - struct iv_val iv; - int len, err; - - BT_DBG("val %s", val ? val : "(null)"); - - if (!val) { - bt_mesh.iv_index = 0U; - atomic_clear_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS); - return 0; - } - - len = sizeof(iv); - err = settings_bytes_from_str(val, &iv, &len); - if (err) { - BT_ERR("Failed to decode value %s (err %d)", val, err); - return err; - } - - if (len != sizeof(iv)) { - BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(iv)); - return -EINVAL; - } - - bt_mesh.iv_index = iv.iv_index; - atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS, iv.iv_update); - bt_mesh.ivu_duration = iv.iv_duration; - - BT_DBG("IV Index 0x%04x (IV Update Flag %u) duration %u hours", - (unsigned) iv.iv_index, iv.iv_update, iv.iv_duration); - - return 0; -} - -static int seq_set(int argc, char **argv, char *val) -{ - struct seq_val seq; - int len, err; - - BT_DBG("val %s", val ? val : "(null)"); - - if (!val) { - bt_mesh.seq = 0; - return 0; - } - - len = sizeof(seq); - err = settings_bytes_from_str(val, &seq, &len); - if (err) { - BT_ERR("Failed to decode value %s (err %d)", val, err); - return err; - } - - if (len != sizeof(seq)) { - BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(seq)); - return -EINVAL; - } - - bt_mesh.seq = sys_get_le24(seq.val); - - if (CONFIG_BT_MESH_SEQ_STORE_RATE > 0) { - /* Make sure we have a large enough sequence number. We - * subtract 1 so that the first transmission causes a write - * to the settings storage. - */ - bt_mesh.seq += (CONFIG_BT_MESH_SEQ_STORE_RATE - - (bt_mesh.seq % CONFIG_BT_MESH_SEQ_STORE_RATE)); - bt_mesh.seq--; - } - - BT_DBG("Sequence Number 0x%06x", bt_mesh.seq); - - return 0; -} - -static int rpl_set(int argc, char **argv, char *val) +static int mesh_commit(void) { - struct bt_mesh_rpl *entry; - struct rpl_val rpl; - int len, err; - uint16_t src; - - if (argc < 1) { - BT_ERR("Invalid argc (%d)", argc); - return -ENOENT; - } - - BT_DBG("argv[0] %s val %s", argv[0], val ? val : "(null)"); - - src = strtol(argv[0], NULL, 16); - entry = bt_mesh_rpl_find(src); - - if (!val) { - if (entry) { - memset(entry, 0, sizeof(*entry)); - } else { - BT_WARN("Unable to find RPL entry for 0x%04x", src); - } - + if (!bt_mesh_subnet_next(NULL)) { + /* Nothing to do since we're not yet provisioned */ return 0; } - if (!entry) { - entry = bt_mesh_rpl_alloc(src); - if (!entry) { - BT_ERR("Unable to allocate RPL entry for 0x%04x", src); - return -ENOMEM; - } - } - - len = sizeof(rpl); - err = settings_bytes_from_str(val, &rpl, &len); - if (err) { - BT_ERR("Failed to decode value %s (err %d)", val, err); - return err; - } - - if (len != sizeof(rpl)) { - BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(rpl)); - return -EINVAL; + if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { + bt_mesh_proxy_prov_disable(true); } - entry->seq = rpl.seq; - entry->old_iv = rpl.old_iv; + bt_mesh_net_settings_commit(); + bt_mesh_model_settings_commit(); - BT_DBG("RPL entry for 0x%04x: Seq 0x%06x old_iv %u", entry->src, - (unsigned) entry->seq, entry->old_iv); + atomic_set_bit(bt_mesh.flags, BT_MESH_VALID); + bt_mesh_start(); return 0; } -static int net_key_set(int argc, char **argv, char *val) -{ - struct net_key_val key; - int len, err; - uint16_t net_idx; - - BT_DBG("argv[0] %s val %s", argv[0], val ? val : "(null)"); - - net_idx = strtol(argv[0], NULL, 16); - - len = sizeof(key); - err = settings_bytes_from_str(val, &key, &len); - if (err) { - BT_ERR("Failed to decode value %s (err %d)", val, err); - return err; - } - - if (len != sizeof(key)) { - BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(key)); - return -EINVAL; - } - - BT_DBG("NetKeyIndex 0x%03x recovered from storage", net_idx); - - return bt_mesh_subnet_set( - net_idx, key.kr_phase, key.val[0], - (key.kr_phase != BT_MESH_KR_NORMAL) ? key.val[1] : NULL); -} - -static int app_key_set(int argc, char **argv, char *val) -{ - struct app_key_val key; - uint16_t app_idx; - int len_rd, err; - - BT_DBG("argv[0] %s val %s", argv[0], val ? val : "(null)"); - - app_idx = strtol(argv[0], NULL, 16); - len_rd = strtol(argv[1], NULL, 16); - - if (!len_rd) { - return 0; - } - - err = settings_bytes_from_str(val, &key, &len_rd); - if (err) { - BT_ERR("Failed to decode value %s (err %d)", val, err); - return err; - } - - err = bt_mesh_app_key_set(app_idx, key.net_idx, key.val[0], - key.updated ? key.val[1] : NULL); - if (err) { - BT_ERR("Failed to set \'app-key\'"); - return err; - } - - BT_DBG("AppKeyIndex 0x%03x recovered from storage", app_idx); +/* Pending flags that use K_NO_WAIT as the storage timeout */ +#define NO_WAIT_PENDING_BITS (BIT(BT_MESH_SETTINGS_NET_PENDING) | \ + BIT(BT_MESH_SETTINGS_IV_PENDING) | \ + BIT(BT_MESH_SETTINGS_SEQ_PENDING) | \ + BIT(BT_MESH_SETTINGS_CDB_PENDING)) - return 0; -} +/* Pending flags that use CONFIG_BT_MESH_STORE_TIMEOUT */ +#define GENERIC_PENDING_BITS (BIT(BT_MESH_SETTINGS_NET_KEYS_PENDING) | \ + BIT(BT_MESH_SETTINGS_APP_KEYS_PENDING) | \ + BIT(BT_MESH_SETTINGS_HB_PUB_PENDING) | \ + BIT(BT_MESH_SETTINGS_CFG_PENDING) | \ + BIT(BT_MESH_SETTINGS_MOD_PENDING)) -static int hb_pub_set(int argc, char **argv, char *val) +void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag) { - struct bt_mesh_hb_pub pub; - struct hb_pub_val hb_val; - int len, err; - - BT_DBG("val %s", val ? val : "(null)"); - - len = sizeof(hb_val); - err = settings_bytes_from_str(val, &hb_val, &len); - if (err) { - BT_ERR("Failed to decode value %s (err %d)", val, err); - return err; - } - - if (len != sizeof(hb_val)) { - BT_ERR("Unexpected value length (%d != %zu)", len, - sizeof(hb_val)); - return -EINVAL; - } + int32_t timeout_ms, remaining; - pub.dst = hb_val.dst; - pub.period = bt_mesh_hb_pwr2(hb_val.period); - pub.ttl = hb_val.ttl; - pub.feat = hb_val.feat; - pub.net_idx = hb_val.net_idx; + atomic_set_bit(pending_flags, flag); - if (hb_val.indefinite) { - pub.count = 0xffff; + if (atomic_get(pending_flags) & NO_WAIT_PENDING_BITS) { + timeout_ms = 0; + } else if (atomic_test_bit(pending_flags, + BT_MESH_SETTINGS_RPL_PENDING) && + (!(atomic_get(bt_mesh.flags) & GENERIC_PENDING_BITS) || + (CONFIG_BT_MESH_RPL_STORE_TIMEOUT < + CONFIG_BT_MESH_STORE_TIMEOUT))) { + timeout_ms = CONFIG_BT_MESH_RPL_STORE_TIMEOUT * MSEC_PER_SEC; } else { - pub.count = 0; - } - - (void)bt_mesh_hb_pub_set(&pub); - - BT_DBG("Restored heartbeat publication"); - - return 0; -} - -static int cfg_set(int argc, char **argv, char *val) -{ - struct cfg_val cfg; - int len, err; - - BT_DBG("val %s", val ? val : "(null)"); - - if (!val) { - BT_DBG("Cleared configuration state"); - return 0; - } - - len = sizeof(cfg); - err = settings_bytes_from_str(val, &cfg, &len); - if (err) { - BT_ERR("Failed to decode value %s (err %d)", val, err); - return err; - } - - if (len != sizeof(cfg)) { - BT_ERR("Unexpected value length (%d != %zu)", len, - sizeof(cfg)); - return -EINVAL; - } - - bt_mesh_net_transmit_set(cfg.net_transmit); - bt_mesh_relay_set(cfg.relay, cfg.relay_retransmit); - bt_mesh_beacon_set(cfg.beacon); - bt_mesh_gatt_proxy_set(cfg.gatt_proxy); - bt_mesh_friend_set(cfg.frnd); - bt_mesh_default_ttl_set(cfg.default_ttl); - - BT_DBG("Restored configuration state"); - - return 0; -} - -static int mod_set_bind(struct bt_mesh_model *mod, char *val) -{ - int len, err, i; - - /* Start with empty array regardless of cleared or set value */ - for (i = 0; i < ARRAY_SIZE(mod->keys); i++) { - mod->keys[i] = BT_MESH_KEY_UNUSED; - } - - if (!val) { - BT_DBG("Cleared bindings for model"); - return 0; - } - - len = sizeof(mod->keys); - err = settings_bytes_from_str(val, mod->keys, &len); - if (err) { - BT_ERR("Failed to decode value %s (err %d)", val, err); - return -EINVAL; - } - - BT_DBG("Decoded %u bound keys for model", len / sizeof(mod->keys[0])); - return 0; -} - -static int mod_set_sub(struct bt_mesh_model *mod, char *val) -{ - int len, err; - - /* Start with empty array regardless of cleared or set value */ - memset(mod->groups, 0, sizeof(mod->groups)); - - if (!val) { - BT_DBG("Cleared subscriptions for model"); - return 0; - } - - len = sizeof(mod->groups); - err = settings_bytes_from_str(val, mod->groups, &len); - if (err) { - BT_ERR("Failed to decode value %s (err %d)", val, err); - return -EINVAL; - } - - BT_DBG("Decoded %u subscribed group addresses for model", - len / sizeof(mod->groups[0])); - return 0; -} - -static int mod_set_pub(struct bt_mesh_model *mod, char *val) -{ - struct mod_pub_val pub; - int len, err; - - if (!mod->pub) { - BT_WARN("Model has no publication context!"); - return -EINVAL; + timeout_ms = CONFIG_BT_MESH_STORE_TIMEOUT * MSEC_PER_SEC; } - if (!val) { - mod->pub->addr = BT_MESH_ADDR_UNASSIGNED; - mod->pub->key = 0; - mod->pub->cred = 0; - mod->pub->ttl = 0; - mod->pub->period = 0; - mod->pub->retransmit = 0; - mod->pub->period_div = pub.period_div; - mod->pub->count = 0; - - BT_DBG("Cleared publication for model"); - return 0; - } - - len = sizeof(pub); - err = settings_bytes_from_str(val, &pub, &len); - if (err) { - BT_ERR("Failed to decode value %s (err %d)", val, err); - return -EINVAL; - } - - if (len != sizeof(pub)) { - BT_ERR("Invalid length for model publication"); - return -EINVAL; + remaining = k_delayed_work_remaining_get(&pending_store); + if ((remaining > 0) && remaining < timeout_ms) { + BT_DBG("Not rescheduling due to existing earlier deadline"); + return; } - mod->pub->addr = pub.addr; - mod->pub->key = pub.key; - mod->pub->cred = pub.cred; - mod->pub->ttl = pub.ttl; - mod->pub->period = pub.period; - mod->pub->retransmit = pub.retransmit; - mod->pub->count = 0; - - BT_DBG("Restored model publication, dst 0x%04x app_idx 0x%03x", - pub.addr, pub.key); - - return 0; -} - -static int mod_data_set(struct bt_mesh_model *mod, - char *name, char *len_rd) -{ - char *next; - - settings_name_next(name, &next); + BT_DBG("Waiting %d seconds", timeout_ms / MSEC_PER_SEC); - if (mod->cb && mod->cb->settings_set) { - return mod->cb->settings_set(mod, next, len_rd); - } - - return 0; + k_delayed_work_submit(&pending_store, K_MSEC(timeout_ms)); } - -static int mod_set(bool vnd, int argc, char **argv, char *val) +static void store_pending(struct ble_npl_event *work) { - struct bt_mesh_model *mod; - uint8_t elem_idx, mod_idx; - uint16_t mod_key; - - if (argc < 2) { - BT_ERR("Too small argc (%d)", argc); - return -ENOENT; - } - - mod_key = strtol(argv[0], NULL, 16); - elem_idx = mod_key >> 8; - mod_idx = mod_key; - - BT_DBG("Decoded mod_key 0x%04x as elem_idx %u mod_idx %u", - mod_key, elem_idx, mod_idx); - - mod = bt_mesh_model_get(vnd, elem_idx, mod_idx); - if (!mod) { - BT_ERR("Failed to get model for elem_idx %u mod_idx %u", - elem_idx, mod_idx); - return -ENOENT; + BT_DBG(""); + if (atomic_test_and_clear_bit(pending_flags, + BT_MESH_SETTINGS_RPL_PENDING)) { + bt_mesh_rpl_pending_store(); } - if (!strcmp(argv[1], "bind")) { - return mod_set_bind(mod, val); + if (atomic_test_and_clear_bit(pending_flags, + BT_MESH_SETTINGS_NET_KEYS_PENDING)) { + bt_mesh_subnet_pending_store(); } - if (!strcmp(argv[1], "sub")) { - return mod_set_sub(mod, val); + if (atomic_test_and_clear_bit(pending_flags, + BT_MESH_SETTINGS_APP_KEYS_PENDING)) { + bt_mesh_app_key_pending_store(); } - if (!strcmp(argv[1], "pub")) { - return mod_set_pub(mod, val); + if (atomic_test_and_clear_bit(pending_flags, + BT_MESH_SETTINGS_NET_PENDING)) { + bt_mesh_net_pending_net_store(); } - if (!strcmp(argv[1], "data")) { - return mod_data_set(mod, argv[1], val); + if (atomic_test_and_clear_bit(pending_flags, + BT_MESH_SETTINGS_IV_PENDING)) { + bt_mesh_net_pending_iv_store(); } - BT_WARN("Unknown module key %s", argv[1]); - return -ENOENT; -} - -static int sig_mod_set(int argc, char **argv, char *val) -{ - return mod_set(false, argc, argv, val); -} - -static int vnd_mod_set(int argc, char **argv, char *val) -{ - return mod_set(true, argc, argv, val); -} - -#if CONFIG_BT_MESH_LABEL_COUNT > 0 -static int va_set(int argc, char **argv, char *val) -{ - struct va_val va; - struct bt_mesh_va *lab; - uint16_t index; - int len, err; - - if (argc < 1) { - BT_ERR("Insufficient number of arguments"); - return -ENOENT; + if (atomic_test_and_clear_bit(pending_flags, + BT_MESH_SETTINGS_SEQ_PENDING)) { + bt_mesh_net_pending_seq_store(); } - index = strtol(argv[0], NULL, 16); - - if (val == NULL) { - BT_WARN("Mesh Virtual Address length = 0"); - return 0; + if (atomic_test_and_clear_bit(pending_flags, + BT_MESH_SETTINGS_HB_PUB_PENDING)) { + bt_mesh_hb_pub_pending_store(); } - err = settings_bytes_from_str(val, &va, &len); - if (err) { - BT_ERR("Failed to decode value %s (err %d)", val, err); - return -EINVAL; + if (atomic_test_and_clear_bit(pending_flags, + BT_MESH_SETTINGS_CFG_PENDING)) { + bt_mesh_cfg_pending_store(); } - if (len != sizeof(struct va_val)) { - BT_ERR("Invalid length for virtual address"); - return -EINVAL; + if (atomic_test_and_clear_bit(pending_flags, + BT_MESH_SETTINGS_MOD_PENDING)) { + bt_mesh_model_pending_store(); } - if (va.ref == 0) { - BT_WARN("Ignore Mesh Virtual Address ref = 0"); - return 0; + if (atomic_test_and_clear_bit(pending_flags, + BT_MESH_SETTINGS_VA_PENDING)) { + bt_mesh_va_pending_store(); } - lab = bt_mesh_va_get(index); - if (lab == NULL) { - BT_WARN("Out of labels buffers"); - return -ENOBUFS; +#if IS_ENABLED(CONFIG_BT_MESH_CDB) + if (atomic_test_and_clear_bit(pending_flags, + BT_MESH_SETTINGS_CDB_PENDING)) { + bt_mesh_cdb_pending_store(); } - - memcpy(lab->uuid, va.uuid, 16); - lab->addr = va.addr; - lab->ref = va.ref; - - BT_DBG("Restored Virtual Address, addr 0x%04x ref 0x%04x", - lab->addr, lab->ref); - - return 0; -} #endif - -#if MYNEWT_VAL(BLE_MESH_CDB) -static int cdb_net_set(int argc, char *val) -{ - struct cdb_net_val net; - int len, err; - - len = sizeof(net); - err = settings_bytes_from_str(val, &net, &len); - if (err) { - BT_ERR("Failed to set \'cdb_net\'"); - return err; - } - - bt_mesh_cdb.iv_index = net.iv_index; - - if (net.iv_update) { - atomic_set_bit(bt_mesh_cdb.flags, BT_MESH_CDB_IVU_IN_PROGRESS); - } - - atomic_set_bit(bt_mesh_cdb.flags, BT_MESH_CDB_VALID); - - return 0; -} - -static int cdb_node_set(int argc, char *str) -{ - struct bt_mesh_cdb_node *node; - struct node_val val; - uint16_t addr; - int len, err; - - if (argc < 1) { - BT_ERR("Insufficient number of arguments"); - return -ENOENT; - } - - addr = strtol(str, NULL, 16); - len = sizeof(str); - - if (argc < 1) { - BT_DBG("val (null)"); - BT_DBG("Deleting node 0x%04x", addr); - - node = bt_mesh_cdb_node_get(addr); - if (node) { - bt_mesh_cdb_node_del(node, false); - } - - return 0; - } - - err = settings_bytes_from_str(str, &val, &len); - if (err) { - BT_ERR("Failed to decode value %s (err %d)", val, err); - return -EINVAL; - } - - if (len != sizeof(struct node_val)) { - BT_ERR("Invalid length for node_val"); - return -EINVAL; - } - - node = bt_mesh_cdb_node_get(addr); - if (!node) { - node = bt_mesh_cdb_node_alloc(val.uuid, addr, val.num_elem, - val.net_idx); - } - - if (!node) { - BT_ERR("No space for a new node"); - return -ENOMEM; - } - - if (val.flags & F_NODE_CONFIGURED) { - atomic_set_bit(node->flags, BT_MESH_CDB_NODE_CONFIGURED); - } - - memcpy(node->uuid, val.uuid, 16); - memcpy(node->dev_key, val.dev_key, 16); - - BT_DBG("Node 0x%04x recovered from storage", addr); - - return 0; -} - -static int cdb_subnet_set(int argc, char *name) -{ - struct bt_mesh_cdb_subnet *sub; - struct net_key_val key; - uint16_t net_idx; - int len, len_rd, err; - - if (!name) { - BT_ERR("Insufficient number of arguments"); - return -ENOENT; - } - - len_rd = sizeof(sub); - net_idx = strtol(name, NULL, 16); - sub = bt_mesh_cdb_subnet_get(net_idx); - - if (len_rd == 0) { - BT_DBG("val (null)"); - if (!sub) { - BT_ERR("No subnet with NetKeyIndex 0x%03x", net_idx); - return -ENOENT; - } - - BT_DBG("Deleting NetKeyIndex 0x%03x", net_idx); - bt_mesh_cdb_subnet_del(sub, false); - return 0; - } - - len = sizeof(key); - err = settings_bytes_from_str(name, &key, &len); - if (err) { - BT_ERR("Failed to set \'net-key\'"); - return err; - } - - if (sub) { - BT_DBG("Updating existing NetKeyIndex 0x%03x", net_idx); - - sub->kr_phase = key.kr_phase; - memcpy(sub->keys[0].net_key, &key.val[0], 16); - memcpy(sub->keys[1].net_key, &key.val[1], 16); - - return 0; - } - - sub = bt_mesh_cdb_subnet_alloc(net_idx); - if (!sub) { - BT_ERR("No space to allocate a new subnet"); - return -ENOMEM; - } - - sub->kr_phase = key.kr_phase; - memcpy(sub->keys[0].net_key, &key.val[0], 16); - memcpy(sub->keys[1].net_key, &key.val[1], 16); - - BT_DBG("NetKeyIndex 0x%03x recovered from storage", net_idx); - - return 0; -} - -static int cdb_app_key_set(int argc, char *name) -{ - struct bt_mesh_cdb_app_key *app; - struct app_key_val key; - uint16_t app_idx; - int len_rd, err; - - app_idx = strtol(name, NULL, 16); - len_rd = sizeof(key); - - if (len_rd == 0) { - BT_DBG("val (null)"); - BT_DBG("Deleting AppKeyIndex 0x%03x", app_idx); - - app = bt_mesh_cdb_app_key_get(app_idx); - if (app) { - bt_mesh_cdb_app_key_del(app, false); - } - - return 0; - } - - err = settings_bytes_from_str(name, &key, &len_rd); - if (err) { - BT_ERR("Failed to set \'app-key\'"); - return err; - } - - app = bt_mesh_cdb_app_key_get(app_idx); - if (!app) { - app = bt_mesh_cdb_app_key_alloc(key.net_idx, app_idx); - } - - if (!app) { - BT_ERR("No space for a new app key"); - return -ENOMEM; - } - - memcpy(app->keys[0].app_key, key.val[0], 16); - memcpy(app->keys[1].app_key, key.val[1], 16); - - BT_DBG("AppKeyIndex 0x%03x recovered from storage", app_idx); - - return 0; -} - -static int cdb_set(int argc, char **argv, char *name) -{ - int len; - char *next; - - if (argc < 1) { - BT_ERR("Insufficient number of arguments"); - return -ENOENT; - } - - if (!strcmp(name, "Net")) { - return cdb_net_set(1, name); - } - - - len = settings_name_next(name, &next); - - if (!next) { - BT_ERR("Insufficient number of arguments"); - return -ENOENT; - } - - if (!strncmp(name, "Node", len)) { - return cdb_node_set(1, next); - } - - if (!strncmp(name, "Subnet", len)) { - return cdb_subnet_set(1, next); - } - - if (!strncmp(name, "AppKey", len)) { - return cdb_app_key_set(1, next); - } - - BT_WARN("Unknown module key %s", name); - return -ENOENT; -} -#endif - -const struct mesh_setting { - const char *name; - int (*func)(int argc, char **argv, char *val); -} settings[] = { - { "Net", net_set }, - { "IV", iv_set }, - { "Seq", seq_set }, - { "RPL", rpl_set }, - { "NetKey", net_key_set }, - { "AppKey", app_key_set }, - { "HBPub", hb_pub_set }, - { "Cfg", cfg_set }, - { "s", sig_mod_set }, - { "v", vnd_mod_set }, -#if CONFIG_BT_MESH_LABEL_COUNT > 0 - { "Va", va_set }, -#endif -#if MYNEWT_VAL(BLE_MESH_CDB) - { "cdb", cdb_set }, -#endif -}; - -static int mesh_set(int argc, char **argv, char *val) -{ - int i; - - if (argc < 1) { - BT_ERR("Insufficient number of arguments"); - return -EINVAL; - } - - BT_DBG("argv[0] %s val %s", argv[0], val ? val : "(null)"); - - for (i = 0; i < ARRAY_SIZE(settings); i++) { - if (!strcmp(settings[i].name, argv[0])) { - argc--; - argv++; - - return settings[i].func(argc, argv, val); - } - } - - BT_WARN("No matching handler for key %s", argv[0]); - - return -ENOENT; -} - -static void commit_mod(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, - bool vnd, bool primary, void *user_data) -{ - if (mod->pub && mod->pub->update && - mod->pub->addr != BT_MESH_ADDR_UNASSIGNED) { - int32_t ms = bt_mesh_model_pub_period_get(mod); - if (ms) { - BT_DBG("Starting publish timer (period %u ms)", - (unsigned) ms); - k_delayed_work_submit(&mod->pub->timer, ms); - } - } - - if (!IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { - return; - } - - for (int i = 0; i < ARRAY_SIZE(mod->groups); i++) { - if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) { - bt_mesh_lpn_group_add(mod->groups[i]); - } - } -} - -static int mesh_commit(void) -{ - if (!bt_mesh_subnet_next(NULL)) { - /* Nothing to do since we're not yet provisioned */ - return 0; - } - - if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { - bt_mesh_proxy_prov_disable(true); - } - - if (bt_mesh.ivu_duration < BT_MESH_IVU_MIN_HOURS) { - k_delayed_work_submit(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT); - } - - bt_mesh_model_foreach(commit_mod, NULL); - - atomic_set_bit(bt_mesh.flags, BT_MESH_VALID); - - bt_mesh_start(); - - return 0; -} - -/* Pending flags that use K_NO_WAIT as the storage timeout */ -#define NO_WAIT_PENDING_BITS (BIT(BT_MESH_NET_PENDING) | \ - BIT(BT_MESH_IV_PENDING) | \ - BIT(BT_MESH_SEQ_PENDING)) - -/* Pending flags that use CONFIG_BT_MESH_STORE_TIMEOUT */ -#define GENERIC_PENDING_BITS (BIT(BT_MESH_KEYS_PENDING) | \ - BIT(BT_MESH_HB_PUB_PENDING) | \ - BIT(BT_MESH_CFG_PENDING) | \ - BIT(BT_MESH_MOD_PENDING)) - -static void schedule_store(int flag) -{ - int32_t timeout, remaining; - - atomic_set_bit(bt_mesh.flags, flag); - - if (atomic_get(bt_mesh.flags) & NO_WAIT_PENDING_BITS) { - timeout = K_NO_WAIT; - } else if (atomic_test_bit(bt_mesh.flags, BT_MESH_RPL_PENDING) && - (!(atomic_get(bt_mesh.flags) & GENERIC_PENDING_BITS) || - (CONFIG_BT_MESH_RPL_STORE_TIMEOUT < - CONFIG_BT_MESH_STORE_TIMEOUT))) { - timeout = K_SECONDS(CONFIG_BT_MESH_RPL_STORE_TIMEOUT); - } else { - timeout = K_SECONDS(CONFIG_BT_MESH_STORE_TIMEOUT); - } - - remaining = k_delayed_work_remaining_get(&pending_store); - if (remaining && remaining < timeout) { - BT_DBG("Not rescheduling due to existing earlier deadline"); - return; - } - - BT_DBG("Waiting %d seconds", (int) (timeout / MSEC_PER_SEC)); - - k_delayed_work_submit(&pending_store, timeout); -} - -static void clear_iv(void) -{ - int err; - - err = settings_save_one("bt_mesh/IV", NULL); - if (err) { - BT_ERR("Failed to clear IV"); - } else { - BT_DBG("Cleared IV"); - } -} - -static void clear_net(void) -{ - int err; - - err = settings_save_one("bt_mesh/Net", NULL); - if (err) { - BT_ERR("Failed to clear Network"); - } else { - BT_DBG("Cleared Network"); - } -} - -static void store_pending_net(void) -{ - char buf[BT_SETTINGS_SIZE(sizeof(struct net_val))]; - struct net_val net; - char *str; - int err; - - BT_DBG("addr 0x%04x DevKey %s", bt_mesh_primary_addr(), - bt_hex(bt_mesh.dev_key, 16)); - - net.primary_addr = bt_mesh_primary_addr(); - memcpy(net.dev_key, bt_mesh.dev_key, 16); - - str = settings_str_from_bytes(&net, sizeof(net), buf, sizeof(buf)); - if (!str) { - BT_ERR("Unable to encode Network as value"); - return; - } - - BT_DBG("Saving Network as value %s", str); - err = settings_save_one("bt_mesh/Net", str); - if (err) { - BT_ERR("Failed to store Network"); - } else { - BT_DBG("Stored Network"); - } -} - -void bt_mesh_store_net(void) -{ - schedule_store(BT_MESH_NET_PENDING); -} - -static void store_pending_iv(void) -{ - char buf[BT_SETTINGS_SIZE(sizeof(struct iv_val))]; - struct iv_val iv; - char *str; - int err; - - iv.iv_index = bt_mesh.iv_index; - iv.iv_update = atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS); - iv.iv_duration = bt_mesh.ivu_duration; - - str = settings_str_from_bytes(&iv, sizeof(iv), buf, sizeof(buf)); - if (!str) { - BT_ERR("Unable to encode IV as value"); - return; - } - - BT_DBG("Saving IV as value %s", str); - err = settings_save_one("bt_mesh/IV", str); - if (err) { - BT_ERR("Failed to store IV"); - } else { - BT_DBG("Stored IV"); - } -} - -void bt_mesh_store_iv(bool only_duration) -{ - schedule_store(BT_MESH_IV_PENDING); - - if (!only_duration) { - /* Always update Seq whenever IV changes */ - schedule_store(BT_MESH_SEQ_PENDING); - } -} - -static void store_pending_seq(void) -{ - char buf[BT_SETTINGS_SIZE(sizeof(struct seq_val))]; - struct seq_val seq; - char *str; - int err; - - sys_put_le24(bt_mesh.seq, seq.val); - - str = settings_str_from_bytes(&seq, sizeof(seq), buf, sizeof(buf)); - if (!str) { - BT_ERR("Unable to encode Seq as value"); - return; - } - - BT_DBG("Saving Seq as value %s", str); - err = settings_save_one("bt_mesh/Seq", str); - if (err) { - BT_ERR("Failed to store Seq"); - } else { - BT_DBG("Stored Seq"); - } -} - -void bt_mesh_store_seq(void) -{ - if (CONFIG_BT_MESH_SEQ_STORE_RATE > 1 && - (bt_mesh.seq % CONFIG_BT_MESH_SEQ_STORE_RATE)) { - return; - } - - schedule_store(BT_MESH_SEQ_PENDING); -} - -static void store_rpl(struct bt_mesh_rpl *entry) -{ - char buf[BT_SETTINGS_SIZE(sizeof(struct rpl_val))]; - struct rpl_val rpl; - char path[18]; - char *str; - int err; - - BT_DBG("src 0x%04x seq 0x%06x old_iv %u", entry->src, - (unsigned) entry->seq, entry->old_iv); - - rpl.seq = entry->seq; - rpl.old_iv = entry->old_iv; - - str = settings_str_from_bytes(&rpl, sizeof(rpl), buf, sizeof(buf)); - if (!str) { - BT_ERR("Unable to encode RPL as value"); - return; - } - - snprintk(path, sizeof(path), "bt_mesh/RPL/%x", entry->src); - - BT_DBG("Saving RPL %s as value %s", path, str); - err = settings_save_one(path, str); - if (err) { - BT_ERR("Failed to store RPL"); - } else { - BT_DBG("Stored RPL"); - } -} - -static void clear_rpl(struct bt_mesh_rpl *rpl, void *user_data) -{ - int err; - char path[18]; - - if (!rpl->src) { - return; - } - - snprintk(path, sizeof(path), "bt_mesh/RPL/%x", rpl->src); - err = settings_save_one(path, NULL); - if (err) { - BT_ERR("Failed to clear RPL"); - } else { - BT_DBG("Cleared RPL"); - } - - (void)memset(rpl, 0, sizeof(*rpl)); -} - -static void store_pending_rpl(struct bt_mesh_rpl *rpl, void *user_data) -{ - BT_DBG(""); - - if (rpl->store) { - rpl->store = false; - store_rpl(rpl); - } -} - -static void store_pending_hb_pub(void) -{ - char buf[BT_SETTINGS_SIZE(sizeof(struct hb_pub_val))]; - struct bt_mesh_hb_pub pub; - struct hb_pub_val val; - char *str; - int err; - - bt_mesh_hb_pub_get(&pub); - if (pub.dst == BT_MESH_ADDR_UNASSIGNED) { - str = NULL; - } else { - val.indefinite = (pub.count == 0xffff); - val.dst = pub.dst; - val.period = bt_mesh_hb_log(pub.period); - val.ttl = pub.ttl; - val.feat = pub.feat; - val.net_idx = pub.net_idx; - - str = settings_str_from_bytes(&val, sizeof(val), - buf, sizeof(buf)); - if (!str) { - BT_ERR("Unable to encode hb pub as value"); - return; - } - } - - BT_DBG("Saving Heartbeat Publication as value %s", - str ? str : "(null)"); - err = settings_save_one("bt_mesh/HBPub", str); - if (err) { - BT_ERR("Failed to store Heartbeat Publication"); - } else { - BT_DBG("Stored Heartbeat Publication"); - } -} - -static void store_pending_cfg(void) -{ - char buf[BT_SETTINGS_SIZE(sizeof(struct cfg_val))]; - struct cfg_val val; - char *str; - int err; - - val.net_transmit = bt_mesh_net_transmit_get(); - val.relay = bt_mesh_relay_get(); - val.relay_retransmit = bt_mesh_relay_retransmit_get(); - val.beacon = bt_mesh_beacon_enabled(); - val.gatt_proxy = bt_mesh_gatt_proxy_get(); - val.frnd = bt_mesh_friend_get(); - val.default_ttl = bt_mesh_default_ttl_get(); - - str = settings_str_from_bytes(&val, sizeof(val), buf, sizeof(buf)); - if (!str) { - BT_ERR("Unable to encode configuration as value"); - return; - } - - BT_DBG("Saving configuration as value %s", str); - err = settings_save_one("bt_mesh/Cfg", str); - if (err) { - BT_ERR("Failed to store configuration"); - } else { - BT_DBG("Stored configuration"); - } -} - -static void clear_cfg(void) -{ - int err; - - err = settings_save_one("bt_mesh/Cfg", NULL); - if (err) { - BT_ERR("Failed to clear configuration"); - } else { - BT_DBG("Cleared configuration"); - } -} - -static void clear_app_key(uint16_t app_idx) -{ - char path[20]; - int err; - - BT_DBG("AppKeyIndex 0x%03x", app_idx); - - snprintk(path, sizeof(path), "bt_mesh/AppKey/%x", app_idx); - err = settings_save_one(path, NULL); - if (err) { - BT_ERR("Failed to clear AppKeyIndex 0x%03x", app_idx); - } else { - BT_DBG("Cleared AppKeyIndex 0x%03x", app_idx); - } -} - -static void clear_net_key(uint16_t net_idx) -{ - char path[20]; - int err; - - BT_DBG("NetKeyIndex 0x%03x", net_idx); - - snprintk(path, sizeof(path), "bt_mesh/NetKey/%x", net_idx); - err = settings_save_one(path, NULL); - if (err) { - BT_ERR("Failed to clear NetKeyIndex 0x%03x", net_idx); - } else { - BT_DBG("Cleared NetKeyIndex 0x%03x", net_idx); - } -} - -static void store_subnet(uint16_t net_idx) -{ - const struct bt_mesh_subnet *sub; - struct net_key_val key; - char buf[BT_SETTINGS_SIZE(sizeof(struct app_key_val))]; - char path[20]; - char *str; - int err; - - sub = bt_mesh_subnet_get(net_idx); - if (!sub) { - BT_WARN("NetKeyIndex 0x%03x not found", net_idx); - return; - } - - BT_DBG("NetKeyIndex 0x%03x", net_idx); - - snprintk(path, sizeof(path), "bt_mesh/NetKey/%x", net_idx); - - memcpy(&key.val[0], sub->keys[0].net, 16); - memcpy(&key.val[1], sub->keys[1].net, 16); - key.kr_flag = 0U; /* Deprecated */ - key.kr_phase = sub->kr_phase; - - str = settings_str_from_bytes(&key, sizeof(key), buf, sizeof(buf)); - if (!str) { - BT_ERR("Unable to encode AppKey as value"); - return; - } - - err = settings_save_one(path, str); - if (err) { - BT_ERR("Failed to store NetKey"); - } else { - BT_DBG("Stored NetKey"); - } -} - -static void store_app(uint16_t app_idx) -{ - const struct bt_mesh_app_key *app; - char buf[BT_SETTINGS_SIZE(sizeof(struct app_key_val))]; - struct app_key_val key; - char path[20]; - char *str; - int err; - - snprintk(path, sizeof(path), "bt_mesh/AppKey/%x", app_idx); - - app = bt_mesh_app_key_get(app_idx); - if (!app) { - BT_WARN("ApKeyIndex 0x%03x not found", app_idx); - return; - } - - key.net_idx = app->net_idx, - key.updated = app->updated, - - memcpy(key.val[0], app->keys[0].val, 16); - memcpy(key.val[1], app->keys[1].val, 16); - - str = settings_str_from_bytes(&key, sizeof(key), buf, sizeof(buf)); - if (!str) { - BT_ERR("Unable to encode AppKey as value"); - return; - } - - snprintk(path, sizeof(path), "bt_mesh/AppKey/%x", app->app_idx); - - BT_DBG("Saving AppKey %s as value %s", path, str); - err = settings_save_one(path, str); - if (err) { - BT_ERR("Failed to store AppKey"); - } else { - BT_DBG("Stored AppKey"); - } -} - -static void store_pending_keys(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(key_updates); i++) { - struct key_update *update = &key_updates[i]; - - if (!update->valid) { - continue; - } - - if (update->clear) { - if (update->app_key) { - clear_app_key(update->key_idx); - } else { - clear_net_key(update->key_idx); - } - } else { - store_subnet(update->key_idx); - } - - update->valid = 0; - } -} - -#if MYNEWT_VAL(BLE_MESH_CDB) -static void clear_cdb(void) -{ - int err; - - err = settings_save_one("bt/mesh/cdb/Net", NULL); - if (err) { - BT_ERR("Failed to clear Network"); - } else { - BT_DBG("Cleared Network"); - } -} - -static void store_pending_cdb(void) -{ - char buf[BT_SETTINGS_SIZE(sizeof(struct cdb_net_val))]; - struct cdb_net_val net; - int err; - char *str; - - BT_DBG(""); - - net.iv_index = bt_mesh_cdb.iv_index; - net.iv_update = atomic_test_bit(bt_mesh_cdb.flags, - BT_MESH_CDB_IVU_IN_PROGRESS); - - str = settings_str_from_bytes(&net, sizeof(net), buf, sizeof(buf)); - if (!str) { - BT_ERR("Unable to encode Network as value"); - return; - } - err = settings_save_one("bt/mesh/cdb/Net", str); - if (err) { - BT_ERR("Failed to store Network value"); - } else { - BT_DBG("Stored Network value"); - } -} - -static void store_cdb_node(const struct bt_mesh_cdb_node *node) -{ - char buf[BT_SETTINGS_SIZE(sizeof(struct node_val))]; - struct node_val val; - char path[30]; - char *str; - int err; - - val.net_idx = node->net_idx; - val.num_elem = node->num_elem; - val.flags = 0; - - if (atomic_test_bit(node->flags, BT_MESH_CDB_NODE_CONFIGURED)) { - val.flags |= F_NODE_CONFIGURED; - } - - memcpy(val.uuid, node->uuid, 16); - memcpy(val.dev_key, node->dev_key, 16); - - snprintk(path, sizeof(path), "bt_mesh/cdb/Node/%x", node->addr); - - str = settings_str_from_bytes(&val, sizeof(val), buf, sizeof(buf)); - if (!str) { - BT_ERR("Unable to encode Node as value"); - return; - } - - - err = settings_save_one(path, str); - if (err) { - BT_ERR("Failed to store Node %s value", path); - } else { - BT_DBG("Stored Node %s value", path); - } -} - -static void clear_cdb_node(uint16_t addr) -{ - char path[30]; - int err; - - BT_DBG("Node 0x%04x", addr); - - snprintk(path, sizeof(path), "bt/mesh/cdb/Node/%x", addr); - err = settings_save_one(path, NULL); - if (err) { - BT_ERR("Failed to clear Node 0x%04x", addr); - } else { - BT_DBG("Cleared Node 0x%04x", addr); - } -} - -static void store_pending_cdb_nodes(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(cdb_node_updates); ++i) { - struct node_update *update = &cdb_node_updates[i]; - - if (update->addr == BT_MESH_ADDR_UNASSIGNED) { - continue; - } - - BT_DBG("addr: 0x%04x, clear: %d", update->addr, update->clear); - - if (update->clear) { - clear_cdb_node(update->addr); - } else { - struct bt_mesh_cdb_node *node; - - node = bt_mesh_cdb_node_get(update->addr); - if (node) { - store_cdb_node(node); - } else { - BT_WARN("Node 0x%04x not found", update->addr); - } - } - - update->addr = BT_MESH_ADDR_UNASSIGNED; - } -} - -static void store_cdb_subnet(const struct bt_mesh_cdb_subnet *sub) -{ - char buf[BT_SETTINGS_SIZE(sizeof(struct net_key_val))]; - struct net_key_val key; - char path[30]; - int err; - char *str; - - BT_DBG("NetKeyIndex 0x%03x NetKey %s", sub->net_idx, - bt_hex(sub->keys[0].net_key, 16)); - - memcpy(&key.val[0], sub->keys[0].net_key, 16); - memcpy(&key.val[1], sub->keys[1].net_key, 16); - key.kr_flag = 0U; /* Deprecated */ - key.kr_phase = sub->kr_phase; - - snprintk(path, sizeof(path), "bt/mesh/cdb/Subnet/%x", sub->net_idx); - - - str = settings_str_from_bytes(&key, sizeof(key), buf, sizeof(buf)); - if (!str) { - BT_ERR("Unable to encode Subnet as value"); - return; - } - err = settings_save_one(path, str); - if (err) { - BT_ERR("Failed to store Subnet value"); - } else { - BT_DBG("Stored Subnet value"); - } -} - -static void clear_cdb_subnet(uint16_t net_idx) -{ - char path[30]; - int err; - - BT_DBG("NetKeyIndex 0x%03x", net_idx); - - snprintk(path, sizeof(path), "bt/mesh/cdb/Subnet/%x", net_idx); - err = settings_save_one(path, NULL); - if (err) { - BT_ERR("Failed to clear NetKeyIndex 0x%03x", net_idx); - } else { - BT_DBG("Cleared NetKeyIndex 0x%03x", net_idx); - } -} - -static void store_cdb_app_key(const struct bt_mesh_cdb_app_key *app) -{ - char buf[BT_SETTINGS_SIZE(sizeof(struct app_key_val))]; - struct app_key_val key; - char path[30]; - int err; - char *str; - - key.net_idx = app->net_idx; - key.updated = false; - memcpy(key.val[0], app->keys[0].app_key, 16); - memcpy(key.val[1], app->keys[1].app_key, 16); - - snprintk(path, sizeof(path), "bt/mesh/cdb/AppKey/%x", app->app_idx); - - str = settings_str_from_bytes(&key, sizeof(key), buf, sizeof(buf)); - err = settings_save_one(path, str); - if (err) { - BT_ERR("Failed to store AppKey"); - } else { - BT_DBG("Stored AppKey"); - } -} - -static void clear_cdb_app_key(uint16_t app_idx) -{ - char path[30]; - int err; - - snprintk(path, sizeof(path), "bt/mesh/cdb/AppKey/%x", app_idx); - err = settings_save_one(path, NULL); - if (err) { - BT_ERR("Failed to clear AppKeyIndex 0x%03x", app_idx); - } else { - BT_DBG("Cleared AppKeyIndex 0x%03x", app_idx); - } -} - -static void store_pending_cdb_keys(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(cdb_key_updates); i++) { - struct key_update *update = &cdb_key_updates[i]; - - if (!update->valid) { - continue; - } - - if (update->clear) { - if (update->app_key) { - clear_cdb_app_key(update->key_idx); - } else { - clear_cdb_subnet(update->key_idx); - } - } else { - if (update->app_key) { - struct bt_mesh_cdb_app_key *key; - - key = bt_mesh_cdb_app_key_get(update->key_idx); - if (key) { - store_cdb_app_key(key); - } else { - BT_WARN("AppKeyIndex 0x%03x not found", - update->key_idx); - } - } else { - struct bt_mesh_cdb_subnet *sub; - - sub = bt_mesh_cdb_subnet_get(update->key_idx); - if (sub) { - store_cdb_subnet(sub); - } else { - BT_WARN("NetKeyIndex 0x%03x not found", - update->key_idx); - } - } - } - - update->valid = 0U; - } -} - -static struct node_update *cdb_node_update_find(uint16_t addr, - struct node_update **free_slot) -{ - struct node_update *match; - int i; - - match = NULL; - *free_slot = NULL; - - for (i = 0; i < ARRAY_SIZE(cdb_node_updates); i++) { - struct node_update *update = &cdb_node_updates[i]; - - if (update->addr == BT_MESH_ADDR_UNASSIGNED) { - *free_slot = update; - continue; - } - - if (update->addr == addr) { - match = update; - } - } - - return match; -} -#endif - -static void encode_mod_path(struct bt_mesh_model *mod, bool vnd, - const char *key, char *path, size_t path_len) -{ - uint16_t mod_key = (((uint16_t)mod->elem_idx << 8) | mod->mod_idx); - - if (vnd) { - snprintk(path, path_len, "bt_mesh/v/%x/%s", mod_key, key); - } else { - snprintk(path, path_len, "bt_mesh/s/%x/%s", mod_key, key); - } -} - -static void store_pending_mod_bind(struct bt_mesh_model *mod, bool vnd) -{ - uint16_t keys[CONFIG_BT_MESH_MODEL_KEY_COUNT]; - char buf[BT_SETTINGS_SIZE(sizeof(keys))]; - char path[20]; - int i, count, err; - char *val; - - for (i = 0, count = 0; i < ARRAY_SIZE(mod->keys); i++) { - if (mod->keys[i] != BT_MESH_KEY_UNUSED) { - keys[count++] = mod->keys[i]; - } - } - - if (count) { - val = settings_str_from_bytes(keys, count * sizeof(keys[0]), - buf, sizeof(buf)); - if (!val) { - BT_ERR("Unable to encode model bindings as value"); - return; - } - } else { - val = NULL; - } - - encode_mod_path(mod, vnd, "bind", path, sizeof(path)); - - BT_DBG("Saving %s as %s", path, val ? val : "(null)"); - err = settings_save_one(path, val); - if (err) { - BT_ERR("Failed to store bind"); - } else { - BT_DBG("Stored bind"); - } -} - -static void store_pending_mod_sub(struct bt_mesh_model *mod, bool vnd) -{ - uint16_t groups[CONFIG_BT_MESH_MODEL_GROUP_COUNT]; - char buf[BT_SETTINGS_SIZE(sizeof(groups))]; - char path[20]; - int i, count, err; - char *val; - - for (i = 0, count = 0; i < CONFIG_BT_MESH_MODEL_GROUP_COUNT; i++) { - if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) { - groups[count++] = mod->groups[i]; - } - } - - if (count) { - val = settings_str_from_bytes(groups, count * sizeof(groups[0]), - buf, sizeof(buf)); - if (!val) { - BT_ERR("Unable to encode model subscription as value"); - return; - } - } else { - val = NULL; - } - - encode_mod_path(mod, vnd, "sub", path, sizeof(path)); - - BT_DBG("Saving %s as %s", path, val ? val : "(null)"); - err = settings_save_one(path, val); - if (err) { - BT_ERR("Failed to store sub"); - } else { - BT_DBG("Stored sub"); - } -} - -static void store_pending_mod_pub(struct bt_mesh_model *mod, bool vnd) -{ - char buf[BT_SETTINGS_SIZE(sizeof(struct mod_pub_val))]; - struct mod_pub_val pub; - char path[20]; - char *val; - int err; - - if (!mod->pub || mod->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - val = NULL; - } else { - pub.addr = mod->pub->addr; - pub.key = mod->pub->key; - pub.ttl = mod->pub->ttl; - pub.retransmit = mod->pub->retransmit; - pub.period = mod->pub->period; - pub.period_div = mod->pub->period_div; - pub.cred = mod->pub->cred; - - val = settings_str_from_bytes(&pub, sizeof(pub), - buf, sizeof(buf)); - if (!val) { - BT_ERR("Unable to encode model publication as value"); - return; - } - } - - encode_mod_path(mod, vnd, "pub", path, sizeof(path)); - - BT_DBG("Saving %s as %s", path, val ? val : "(null)"); - err = settings_save_one(path, val); - if (err) { - BT_ERR("Failed to store pub"); - } else { - BT_DBG("Stored pub"); - } -} - -static void store_pending_mod(struct bt_mesh_model *mod, - struct bt_mesh_elem *elem, bool vnd, - bool primary, void *user_data) -{ - if (!mod->flags) { - return; - } - - if (mod->flags & BT_MESH_MOD_BIND_PENDING) { - mod->flags &= ~BT_MESH_MOD_BIND_PENDING; - store_pending_mod_bind(mod, vnd); - } - - if (mod->flags & BT_MESH_MOD_SUB_PENDING) { - mod->flags &= ~BT_MESH_MOD_SUB_PENDING; - store_pending_mod_sub(mod, vnd); - } - - if (mod->flags & BT_MESH_MOD_PUB_PENDING) { - mod->flags &= ~BT_MESH_MOD_PUB_PENDING; - store_pending_mod_pub(mod, vnd); - } -} - -#define IS_VA_DEL(_label) ((_label)->ref == 0) -static void store_pending_va(void) -{ - char buf[BT_SETTINGS_SIZE(sizeof(struct va_val))]; - struct bt_mesh_va *lab; - struct va_val va; - char path[18]; - char *val; - uint16_t i; - int err = 0; - - for (i = 0; (lab = bt_mesh_va_get(i)) != NULL; i++) { - if (!lab->changed) { - continue; - } - - lab->changed = 0U; - - snprintk(path, sizeof(path), "bt_mesh/Va/%x", i); - - if (IS_VA_DEL(lab)) { - val = NULL; - } else { - va.ref = lab->ref; - va.addr = lab->addr; - memcpy(va.uuid, lab->uuid, 16); - - val = settings_str_from_bytes(&va, sizeof(va), - buf, sizeof(buf)); - if (!val) { - BT_ERR("Unable to encode model publication as value"); - return; - } - - err = settings_save_one(path, val); - } - - if (err) { - BT_ERR("Failed to %s %s value (err %d)", - IS_VA_DEL(lab) ? "delete" : "store", path, err); - } else { - BT_DBG("%s %s value", - IS_VA_DEL(lab) ? "Deleted" : "Stored", path); - } - } -} - -static void store_pending(struct ble_npl_event *work) -{ - BT_DBG(""); - - if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_RPL_PENDING)) { - if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - bt_mesh_rpl_foreach(store_pending_rpl, NULL); - } else { - bt_mesh_rpl_foreach(clear_rpl, NULL); - } - } - - if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_KEYS_PENDING)) { - store_pending_keys(); - } - - if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_NET_PENDING)) { - if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - store_pending_net(); - } else { - clear_net(); - } - } - - if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_IV_PENDING)) { - if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - store_pending_iv(); - } else { - clear_iv(); - } - } - - if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_SEQ_PENDING)) { - store_pending_seq(); - } - - if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_HB_PUB_PENDING)) { - store_pending_hb_pub(); - } - - if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_CFG_PENDING)) { - if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { - store_pending_cfg(); - } else { - clear_cfg(); - } - } - - if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_MOD_PENDING)) { - bt_mesh_model_foreach(store_pending_mod, NULL); - } - - if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_VA_PENDING)) { - store_pending_va(); - } - -#if MYNEWT_VAL(BLE_MESH_CDB) - if (IS_ENABLED(CONFIG_BT_MESH_CDB)) { - if (atomic_test_and_clear_bit(bt_mesh_cdb.flags, - BT_MESH_CDB_SUBNET_PENDING)) { - if (atomic_test_bit(bt_mesh_cdb.flags, - BT_MESH_CDB_VALID)) { - store_pending_cdb(); - } else { - clear_cdb(); - } - } - - if (atomic_test_and_clear_bit(bt_mesh_cdb.flags, - BT_MESH_CDB_NODES_PENDING)) { - store_pending_cdb_nodes(); - } - - if (atomic_test_and_clear_bit(bt_mesh_cdb.flags, - BT_MESH_CDB_KEYS_PENDING)) { - store_pending_cdb_keys(); - } - } -#endif -} - -void bt_mesh_store_rpl(struct bt_mesh_rpl *entry) -{ - entry->store = true; - schedule_store(BT_MESH_RPL_PENDING); -} - -static struct key_update *key_update_find(bool app_key, uint16_t key_idx, - struct key_update **free_slot) -{ - struct key_update *match; - int i; - - match = NULL; - *free_slot = NULL; - - for (i = 0; i < ARRAY_SIZE(key_updates); i++) { - struct key_update *update = &key_updates[i]; - - if (!update->valid) { - *free_slot = update; - continue; - } - - if (update->app_key != app_key) { - continue; - } - - if (update->key_idx == key_idx) { - match = update; - } - } - - return match; -} - -void bt_mesh_store_subnet(uint16_t net_idx) -{ - struct key_update *update, *free_slot; - - BT_DBG("NetKeyIndex 0x%03x", net_idx); - - update = key_update_find(false, net_idx, &free_slot); - if (update) { - update->clear = 0; - schedule_store(BT_MESH_KEYS_PENDING); - return; - } - - if (!free_slot) { - store_subnet(net_idx); - return; - } - - free_slot->valid = 1; - free_slot->key_idx = net_idx; - free_slot->app_key = 0; - free_slot->clear = 0; - - schedule_store(BT_MESH_KEYS_PENDING); -} - -void bt_mesh_store_app_key(uint16_t app_idx) -{ - struct key_update *update, *free_slot; - - BT_DBG("AppKeyIndex 0x%03x", app_idx); - - update = key_update_find(true, app_idx, &free_slot); - if (update) { - update->clear = 0; - schedule_store(BT_MESH_KEYS_PENDING); - return; - } - - if (!free_slot) { - store_app(app_idx); - return; - } - - free_slot->valid = 1; - free_slot->key_idx = app_idx; - free_slot->app_key = 1; - free_slot->clear = 0; - - schedule_store(BT_MESH_KEYS_PENDING); -} - -void bt_mesh_store_hb_pub(void) -{ - schedule_store(BT_MESH_HB_PUB_PENDING); -} - -void bt_mesh_store_cfg(void) -{ - schedule_store(BT_MESH_CFG_PENDING); -} - -void bt_mesh_clear_net(void) -{ - schedule_store(BT_MESH_NET_PENDING); - schedule_store(BT_MESH_IV_PENDING); - schedule_store(BT_MESH_CFG_PENDING); -} - -void bt_mesh_clear_subnet(uint16_t net_idx) -{ - struct key_update *update, *free_slot; - - BT_DBG("NetKeyIndex 0x%03x", net_idx); - - update = key_update_find(false, net_idx, &free_slot); - if (update) { - update->clear = 1; - schedule_store(BT_MESH_KEYS_PENDING); - return; - } - - if (!free_slot) { - clear_net_key(net_idx); - return; - } - - free_slot->valid = 1; - free_slot->key_idx = net_idx; - free_slot->app_key = 0; - free_slot->clear = 1; - - schedule_store(BT_MESH_KEYS_PENDING); -} - -void bt_mesh_clear_app_key(uint16_t app_idx) -{ - struct key_update *update, *free_slot; - - BT_DBG("AppKeyIndex 0x%03x", app_idx); - - update = key_update_find(true, app_idx, &free_slot); - if (update) { - update->clear = 1; - schedule_store(BT_MESH_KEYS_PENDING); - return; - } - - if (!free_slot) { - clear_app_key(app_idx); - return; - } - - free_slot->valid = 1; - free_slot->key_idx = app_idx; - free_slot->app_key = 1; - free_slot->clear = 1; - - schedule_store(BT_MESH_KEYS_PENDING); -} - -void bt_mesh_clear_rpl(void) -{ - schedule_store(BT_MESH_RPL_PENDING); -} - -void bt_mesh_store_mod_bind(struct bt_mesh_model *mod) -{ - mod->flags |= BT_MESH_MOD_BIND_PENDING; - schedule_store(BT_MESH_MOD_PENDING); -} - -void bt_mesh_store_mod_sub(struct bt_mesh_model *mod) -{ - mod->flags |= BT_MESH_MOD_SUB_PENDING; - schedule_store(BT_MESH_MOD_PENDING); -} - -void bt_mesh_store_mod_pub(struct bt_mesh_model *mod) -{ - mod->flags |= BT_MESH_MOD_PUB_PENDING; - schedule_store(BT_MESH_MOD_PENDING); -} - - -void bt_mesh_store_label(void) -{ - schedule_store(BT_MESH_VA_PENDING); -} - -#if MYNEWT_VAL(BLE_MESH_CDB) -static void schedule_cdb_store(int flag) -{ - atomic_set_bit(bt_mesh_cdb.flags, flag); - k_delayed_work_submit(&pending_store, K_NO_WAIT); -} - -void bt_mesh_store_cdb(void) -{ - schedule_cdb_store(BT_MESH_CDB_SUBNET_PENDING); -} - -void bt_mesh_store_cdb_node(const struct bt_mesh_cdb_node *node) -{ - struct node_update *update, *free_slot; - - BT_DBG("Node 0x%04x", node->addr); - - update = cdb_node_update_find(node->addr, &free_slot); - if (update) { - update->clear = false; - schedule_cdb_store(BT_MESH_CDB_NODES_PENDING); - return; - } - - if (!free_slot) { - store_cdb_node(node); - return; - } - - free_slot->addr = node->addr; - free_slot->clear = false; - - schedule_cdb_store(BT_MESH_CDB_NODES_PENDING); -} - -void bt_mesh_clear_cdb_node(struct bt_mesh_cdb_node *node) -{ - struct node_update *update, *free_slot; - - BT_DBG("Node 0x%04x", node->addr); - - update = cdb_node_update_find(node->addr, &free_slot); - if (update) { - update->clear = true; - schedule_cdb_store(BT_MESH_CDB_NODES_PENDING); - return; - } - - if (!free_slot) { - clear_cdb_node(node->addr); - return; - } - - free_slot->addr = node->addr; - free_slot->clear = true; - - schedule_cdb_store(BT_MESH_CDB_NODES_PENDING); -} - -/* TODO: Could be shared with key_update_find? */ -static struct key_update *cdb_key_update_find(bool app_key, uint16_t key_idx, - struct key_update **free_slot) -{ - struct key_update *match; - int i; - - match = NULL; - *free_slot = NULL; - - for (i = 0; i < ARRAY_SIZE(cdb_key_updates); i++) { - struct key_update *update = &cdb_key_updates[i]; - - if (!update->valid) { - *free_slot = update; - continue; - } - - if (update->app_key != app_key) { - continue; - } - - if (update->key_idx == key_idx) { - match = update; - } - } - - return match; -} - -void bt_mesh_store_cdb_subnet(const struct bt_mesh_cdb_subnet *sub) -{ - struct key_update *update, *free_slot; - - BT_DBG("NetKeyIndex 0x%03x", sub->net_idx); - - update = cdb_key_update_find(false, sub->net_idx, &free_slot); - if (update) { - update->clear = 0U; - schedule_cdb_store(BT_MESH_CDB_KEYS_PENDING); - return; - } - - if (!free_slot) { - store_cdb_subnet(sub); - return; - } - - free_slot->valid = 1U; - free_slot->key_idx = sub->net_idx; - free_slot->app_key = 0U; - free_slot->clear = 0U; - - schedule_cdb_store(BT_MESH_CDB_KEYS_PENDING); -} - -void bt_mesh_clear_cdb_subnet(struct bt_mesh_cdb_subnet *sub) -{ - struct key_update *update, *free_slot; - - BT_DBG("NetKeyIndex 0x%03x", sub->net_idx); - - update = cdb_key_update_find(false, sub->net_idx, &free_slot); - if (update) { - update->clear = 1U; - schedule_cdb_store(BT_MESH_CDB_KEYS_PENDING); - return; - } - - if (!free_slot) { - clear_cdb_subnet(sub->net_idx); - return; - } - - free_slot->valid = 1U; - free_slot->key_idx = sub->net_idx; - free_slot->app_key = 0U; - free_slot->clear = 1U; - - schedule_cdb_store(BT_MESH_CDB_KEYS_PENDING); -} - -void bt_mesh_store_cdb_app_key(const struct bt_mesh_cdb_app_key *key) -{ - struct key_update *update, *free_slot; - - BT_DBG("AppKeyIndex 0x%03x", key->app_idx); - - update = cdb_key_update_find(true, key->app_idx, &free_slot); - if (update) { - update->clear = 0U; - schedule_cdb_store(BT_MESH_CDB_KEYS_PENDING); - return; - } - - if (!free_slot) { - store_cdb_app_key(key); - return; - } - - free_slot->valid = 1U; - free_slot->key_idx = key->app_idx; - free_slot->app_key = 1U; - free_slot->clear = 0U; - - schedule_cdb_store(BT_MESH_CDB_KEYS_PENDING); -} - -void bt_mesh_clear_cdb_app_key(struct bt_mesh_cdb_app_key *key) -{ - struct key_update *update, *free_slot; - - BT_DBG("AppKeyIndex 0x%03x", key->app_idx); - - update = cdb_key_update_find(true, key->app_idx, &free_slot); - if (update) { - update->clear = 1U; - schedule_cdb_store(BT_MESH_CDB_KEYS_PENDING); - return; - } - - if (!free_slot) { - clear_cdb_app_key(key->app_idx); - return; - } - - free_slot->valid = 1U; - free_slot->key_idx = key->app_idx; - free_slot->app_key = 1U; - free_slot->clear = 1U; - - schedule_cdb_store(BT_MESH_CDB_KEYS_PENDING); -} -#endif - -int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, - const char *name, const void *data, - size_t data_len) -{ - char path[30]; - char buf[BT_SETTINGS_SIZE(sizeof(struct mod_pub_val))]; - char *val; - int err; - - encode_mod_path(mod, vnd, "data", path, sizeof(path)); - if (name) { - strcat(path, "/"); - strncat(path, name, 8); - } - - if (data_len) { - val = settings_str_from_bytes(data, data_len, - buf, sizeof(buf)); - if (!val) { - BT_ERR("Unable to encode model publication as value"); - return -EINVAL; - } - err = settings_save_one(path, val); - } else { - err = settings_save_one(path, NULL); - } - - if (err) { - BT_ERR("Failed to store %s value", path); - } else { - BT_DBG("Stored %s value", path); - } - return err; } static struct conf_handler bt_mesh_settings_conf_handler = { .ch_name = "bt_mesh", .ch_get = NULL, - .ch_set = mesh_set, + .ch_set = NULL, .ch_commit = mesh_commit, .ch_export = NULL, }; diff --git a/nimble/host/mesh/src/settings.h b/nimble/host/mesh/src/settings.h index 9060a14a72..95f78f50ff 100644 --- a/nimble/host/mesh/src/settings.h +++ b/nimble/host/mesh/src/settings.h @@ -3,30 +3,23 @@ * * SPDX-License-Identifier: Apache-2.0 */ +/* Pending storage actions. */ +enum bt_mesh_settings_flag { + BT_MESH_SETTINGS_RPL_PENDING, + BT_MESH_SETTINGS_NET_KEYS_PENDING, + BT_MESH_SETTINGS_APP_KEYS_PENDING, + BT_MESH_SETTINGS_NET_PENDING, + BT_MESH_SETTINGS_IV_PENDING, + BT_MESH_SETTINGS_SEQ_PENDING, + BT_MESH_SETTINGS_HB_PUB_PENDING, + BT_MESH_SETTINGS_CFG_PENDING, + BT_MESH_SETTINGS_MOD_PENDING, + BT_MESH_SETTINGS_VA_PENDING, + BT_MESH_SETTINGS_CDB_PENDING, -void bt_mesh_store_net(void); -void bt_mesh_store_iv(bool only_duration); -void bt_mesh_store_seq(void); -void bt_mesh_store_rpl(struct bt_mesh_rpl *rpl); -void bt_mesh_store_subnet(uint16_t net_idx); -void bt_mesh_store_app_key(uint16_t app_idx); -void bt_mesh_store_hb_pub(void); -void bt_mesh_store_cfg(void); -void bt_mesh_store_mod_bind(struct bt_mesh_model *mod); -void bt_mesh_store_mod_sub(struct bt_mesh_model *mod); -void bt_mesh_store_mod_pub(struct bt_mesh_model *mod); -void bt_mesh_store_label(void); -void bt_mesh_store_cdb(void); -void bt_mesh_store_cdb_node(const struct bt_mesh_cdb_node *node); -void bt_mesh_store_cdb_subnet(const struct bt_mesh_cdb_subnet *sub); -void bt_mesh_store_cdb_app_key(const struct bt_mesh_cdb_app_key *app); - -void bt_mesh_clear_net(void); -void bt_mesh_clear_subnet(uint16_t net_idx); -void bt_mesh_clear_app_key(uint16_t app_idx); -void bt_mesh_clear_rpl(void); -void bt_mesh_clear_cdb_node(struct bt_mesh_cdb_node *node); -void bt_mesh_clear_cdb_subnet(struct bt_mesh_cdb_subnet *sub); -void bt_mesh_clear_cdb_app_key(struct bt_mesh_cdb_app_key *app); + BT_MESH_SETTINGS_FLAG_COUNT, +}; void bt_mesh_settings_init(void); +int settings_name_next(char *name, char **next); +void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag); diff --git a/nimble/host/mesh/src/shell.c b/nimble/host/mesh/src/shell.c index 0a27e274e7..99c4f95b2c 100644 --- a/nimble/host/mesh/src/shell.c +++ b/nimble/host/mesh/src/shell.c @@ -2906,7 +2906,7 @@ static int cmd_cdb_node_add(int argc, char *argv[]) memcpy(node->dev_key, dev_key, 16); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_cdb_node(node); + bt_mesh_cdb_node_store(node); } printk("Added node 0x%04x", addr); @@ -2960,7 +2960,7 @@ static int cmd_cdb_subnet_add(int argc, memcpy(sub->keys[0].net_key, net_key, 16); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_cdb_subnet(sub); + bt_mesh_cdb_subnet_store(sub); } printk("Added Subnet 0x%03x", net_idx); @@ -3016,7 +3016,7 @@ static int cmd_cdb_app_key_add(int argc, memcpy(key->keys[0].app_key, app_key, 16); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_cdb_app_key(key); + bt_mesh_cdb_app_key_store(key); } printk("Added AppKey 0x%03x", app_idx); diff --git a/nimble/host/mesh/src/subnet.c b/nimble/host/mesh/src/subnet.c index d6fcfbeee7..71d7b3d1ab 100644 --- a/nimble/host/mesh/src/subnet.c +++ b/nimble/host/mesh/src/subnet.c @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ - +#include #include "syscfg/syscfg.h" #define MESH_LOG_MODULE BLE_MESH_NET_KEYS_LOG @@ -26,6 +26,26 @@ #include "settings.h" #include "prov.h" +/* Tracking of what storage changes are pending for Net Keys. We track this in + * a separate array here instead of within the respective bt_mesh_subnet + * struct itselve, since once a key gets deleted its struct becomes invalid + * and may be reused for other keys. + */ +struct net_key_update { + uint16_t key_idx:12, /* NetKey Index */ + valid:1, /* 1 if this entry is valid, 0 if not */ + clear:1; /* 1 if key needs clearing, 0 if storing */ +}; + +/* NetKey storage information */ +struct net_key_val { + uint8_t kr_flag:1, + kr_phase:7; + uint8_t val[2][16]; +} __packed; + +static struct net_key_update net_key_updates[CONFIG_BT_MESH_SUBNET_COUNT]; + #ifdef CONFIG_BT_MESH_GATT_PROXY void (*bt_mesh_subnet_cb_list[5]) (struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt); @@ -51,6 +71,85 @@ static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt) } } +static void clear_net_key(uint16_t net_idx) +{ + char path[20]; + int err; + + BT_DBG("NetKeyIndex 0x%03x", net_idx); + + snprintk(path, sizeof(path), "bt_mesh/NetKey/%x", net_idx); + err = settings_save_one(path, NULL); + if (err) { + BT_ERR("Failed to clear NetKeyIndex 0x%03x", net_idx); + } else { + BT_DBG("Cleared NetKeyIndex 0x%03x", net_idx); + } +} + +static void store_subnet(uint16_t net_idx) +{ + const struct bt_mesh_subnet *sub; + struct net_key_val key; + char buf[BT_SETTINGS_SIZE(sizeof(struct net_key_val))]; + char path[20]; + char *str; + int err; + + sub = bt_mesh_subnet_get(net_idx); + if (!sub) { + BT_WARN("NetKeyIndex 0x%03x not found", net_idx); + return; + } + + BT_DBG("NetKeyIndex 0x%03x", net_idx); + + snprintk(path, sizeof(path), "bt_mesh/NetKey/%x", net_idx); + + memcpy(&key.val[0], sub->keys[0].net, 16); + memcpy(&key.val[1], sub->keys[1].net, 16); + key.kr_flag = 0U; /* Deprecated */ + key.kr_phase = sub->kr_phase; + + str = settings_str_from_bytes(&key, sizeof(key), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode AppKey as value"); + return; + } + + err = settings_save_one(path, str); + if (err) { + BT_ERR("Failed to store NetKey"); + } else { + BT_DBG("Stored NetKey"); + } +} + +static struct net_key_update *net_key_update_find(uint16_t key_idx, + struct net_key_update **free_slot) +{ + struct net_key_update *match; + int i; + + match = NULL; + *free_slot = NULL; + + for (i = 0; i < ARRAY_SIZE(net_key_updates); i++) { + struct net_key_update *update = &net_key_updates[i]; + + if (!update->valid) { + *free_slot = update; + continue; + } + + if (update->key_idx == key_idx) { + match = update; + } + } + + return match; +} + uint8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub) { uint8_t flags = 0x00; @@ -66,6 +165,42 @@ uint8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub) return flags; } +static void update_subnet_settings(uint16_t net_idx, bool store) +{ + struct net_key_update *update, *free_slot; + uint8_t clear = store ? 0U : 1U; + + BT_DBG("NetKeyIndex 0x%03x", net_idx); + + update = net_key_update_find(net_idx, &free_slot); + if (update) { + update->clear = clear; + bt_mesh_settings_store_schedule( + BT_MESH_SETTINGS_NET_KEYS_PENDING); + return; + } + + if (!free_slot) { + if (store) { + store_subnet(net_idx); + } else { + clear_net_key(net_idx); + } + return; + } + + free_slot->valid = 1U; + free_slot->key_idx = net_idx; + free_slot->clear = clear; + + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_NET_KEYS_PENDING); +} + +void bt_mesh_subnet_store(uint16_t net_idx) +{ + update_subnet_settings(net_idx, true); +} + static void key_refresh(struct bt_mesh_subnet *sub, uint8_t new_phase) { BT_DBG("Phase 0x%02x -> 0x%02x", sub->kr_phase, new_phase); @@ -97,7 +232,7 @@ static void key_refresh(struct bt_mesh_subnet *sub, uint8_t new_phase) if (IS_ENABLED(CONFIG_BT_SETTINGS)) { BT_DBG("Storing Updated NetKey persistently"); - bt_mesh_store_subnet(sub->net_idx); + bt_mesh_subnet_store(sub->net_idx); } } @@ -139,7 +274,7 @@ static struct bt_mesh_subnet *subnet_alloc(uint16_t net_idx) static void subnet_del(struct bt_mesh_subnet *sub) { if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_clear_subnet(sub->net_idx); + update_subnet_settings(sub->net_idx, false); } bt_mesh_net_loopback_clear(sub->net_idx); @@ -242,7 +377,7 @@ uint8_t bt_mesh_subnet_add(uint16_t net_idx, const uint8_t key[16]) if (IS_ENABLED(CONFIG_BT_SETTINGS)) { BT_DBG("Storing NetKey persistently"); - bt_mesh_store_subnet(sub->net_idx); + bt_mesh_subnet_store(sub->net_idx); } return STATUS_SUCCESS; @@ -664,3 +799,71 @@ bool bt_mesh_net_cred_find(struct bt_mesh_net_rx *rx, struct os_mbuf *in, return false; } + +static int net_key_set(int argc, char **argv, char *val) +{ + struct net_key_val key; + int len, err; + uint16_t net_idx; + + BT_DBG("argv[0] %s val %s", argv[0], val ? val : "(null)"); + + net_idx = strtol(argv[0], NULL, 16); + + len = sizeof(key); + err = settings_bytes_from_str(val, &key, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + + if (len != sizeof(key)) { + BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(key)); + return -EINVAL; + } + + BT_DBG("NetKeyIndex 0x%03x recovered from storage", net_idx); + + return bt_mesh_subnet_set( + net_idx, key.kr_phase, key.val[0], + (key.kr_phase != BT_MESH_KR_NORMAL) ? key.val[1] : NULL); +} + +void bt_mesh_subnet_pending_store(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(net_key_updates); i++) { + struct net_key_update *update = &net_key_updates[i]; + + if (!update->valid) { + continue; + } + + if (update->clear) { + clear_net_key(update->key_idx); + } else { + store_subnet(update->key_idx); + } + + update->valid = 0U; + } +} + +static struct conf_handler bt_mesh_net_key_conf_handler = { + .ch_name = "bt_mesh", + .ch_get = NULL, + .ch_set = net_key_set, + .ch_commit = NULL, + .ch_export = NULL, + }; + +void bt_mesh_net_key_init(void) +{ + int rc; + + rc = conf_register(&bt_mesh_net_key_conf_handler); + + SYSINIT_PANIC_ASSERT_MSG(rc == 0, + "Failed to register bt_mesh_net_key conf"); +} \ No newline at end of file diff --git a/nimble/host/mesh/src/subnet.h b/nimble/host/mesh/src/subnet.h index 7a82999789..b3ac899272 100644 --- a/nimble/host/mesh/src/subnet.h +++ b/nimble/host/mesh/src/subnet.h @@ -194,4 +194,13 @@ bt_mesh_subnet_has_new_key(const struct bt_mesh_subnet *sub) return sub->kr_phase != BT_MESH_KR_NORMAL; } +/** @brief Store the Subnet information in persistent storage. + * + * @param net_idx Network index to store. + */ +void bt_mesh_subnet_store(uint16_t net_idx); + +/** @brief Store the pending Subnets in persistent storage. */ +void bt_mesh_subnet_pending_store(void); +void bt_mesh_net_key_init(void); #endif /* _BLUETOOTH_MESH_SUBNET_H_ */ \ No newline at end of file diff --git a/nimble/host/mesh/src/transport.c b/nimble/host/mesh/src/transport.c index 3582c998bf..721d5005b6 100644 --- a/nimble/host/mesh/src/transport.c +++ b/nimble/host/mesh/src/transport.c @@ -11,6 +11,7 @@ #include #include +#include #include "mesh/mesh.h" #include "mesh/glue.h" @@ -69,6 +70,20 @@ /* How long to wait for available buffers before giving up */ #define BUF_TIMEOUT K_NO_WAIT +struct virtual_addr { + uint16_t ref:15, + changed:1; + uint16_t addr; + uint8_t uuid[16]; +}; + +/* Virtual Address information for persistent storage. */ +struct va_val { + uint16_t ref; + uint16_t addr; + uint8_t uuid[16]; +} __packed; + static struct seg_tx { struct bt_mesh_subnet *sub; void *seg[CONFIG_BT_MESH_TX_SEG_MAX]; @@ -124,7 +139,7 @@ struct k_mem_slab segs = { .num_used = 0 }; -static struct bt_mesh_va virtual_addrs[CONFIG_BT_MESH_LABEL_COUNT]; +static struct virtual_addr virtual_addrs[CONFIG_BT_MESH_LABEL_COUNT]; static int send_unseg(struct bt_mesh_net_tx *tx, struct os_mbuf *sdu, const struct bt_mesh_send_cb *cb, void *cb_data, @@ -1584,6 +1599,11 @@ void bt_mesh_rx_reset(void) } } +static void store_va_label(void) +{ + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_VA_PENDING); +} + void bt_mesh_trans_reset(void) { int i; @@ -1606,7 +1626,7 @@ void bt_mesh_trans_reset(void) bt_mesh_rpl_clear(); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_label(); + store_va_label(); } } @@ -1634,26 +1654,17 @@ void bt_mesh_trans_init(void) } } -struct bt_mesh_va *bt_mesh_va_get(uint16_t index) -{ - if (index >= ARRAY_SIZE(virtual_addrs)) { - return NULL; - } - - return &virtual_addrs[index]; -} - -static inline void va_store(struct bt_mesh_va *store) +static inline void va_store(struct virtual_addr *store) { store->changed = 1U; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_store_label(); + store_va_label(); } } uint8_t bt_mesh_va_add(const uint8_t uuid[16], uint16_t *addr) { - struct bt_mesh_va *va = NULL; + struct virtual_addr *va = NULL; int err; for (int i = 0; i < ARRAY_SIZE(virtual_addrs); i++) { @@ -1695,7 +1706,7 @@ uint8_t bt_mesh_va_add(const uint8_t uuid[16], uint16_t *addr) uint8_t bt_mesh_va_del(const uint8_t uuid[16], uint16_t *addr) { - struct bt_mesh_va *va = NULL; + struct virtual_addr *va = NULL; for (int i = 0; i < ARRAY_SIZE(virtual_addrs); i++) { if (virtual_addrs[i].ref && @@ -1719,19 +1730,6 @@ uint8_t bt_mesh_va_del(const uint8_t uuid[16], uint16_t *addr) return STATUS_SUCCESS; } -struct bt_mesh_va *bt_mesh_va_find(uint8_t uuid[16]) -{ - for (int i = 0; i < ARRAY_SIZE(virtual_addrs); i++) { - if (virtual_addrs[i].ref && - !memcmp(uuid, virtual_addrs[i].uuid, - ARRAY_SIZE(virtual_addrs[i].uuid))) { - return &virtual_addrs[i]; - } - } - - return NULL; -} - uint8_t *bt_mesh_va_label_get(uint16_t addr) { int i; @@ -1750,3 +1748,132 @@ uint8_t *bt_mesh_va_label_get(uint16_t addr) return NULL; } + +static struct virtual_addr *bt_mesh_va_get(uint16_t index) +{ + if (index >= ARRAY_SIZE(virtual_addrs)) { + return NULL; + } + + return &virtual_addrs[index]; +} + +#if CONFIG_BT_MESH_LABEL_COUNT > 0 +static int va_set(int argc, char **argv, char *val) +{ + struct va_val va; + struct virtual_addr *lab; + uint16_t index; + int len, err; + + if (argc < 1) { + BT_ERR("Insufficient number of arguments"); + return -ENOENT; + } + + index = strtol(argv[0], NULL, 16); + + if (val == NULL) { + BT_WARN("Mesh Virtual Address length = 0"); + return 0; + } + + err = settings_bytes_from_str(val, &va, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return -EINVAL; + } + + if (len != sizeof(struct va_val)) { + BT_ERR("Invalid length for virtual address"); + return -EINVAL; + } + + if (va.ref == 0) { + BT_WARN("Ignore Mesh Virtual Address ref = 0"); + return 0; + } + + lab = bt_mesh_va_get(index); + if (lab == NULL) { + BT_WARN("Out of labels buffers"); + return -ENOBUFS; + } + + memcpy(lab->uuid, va.uuid, 16); + lab->addr = va.addr; + lab->ref = va.ref; + + BT_DBG("Restored Virtual Address, addr 0x%04x ref 0x%04x", + lab->addr, lab->ref); + + return 0; +} +#endif + +#define IS_VA_DEL(_label) ((_label)->ref == 0) +void bt_mesh_va_pending_store(void) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct va_val))]; + struct virtual_addr *lab; + struct va_val va; + char path[18]; + char *val; + uint16_t i; + int err = 0; + + for (i = 0; (lab = bt_mesh_va_get(i)) != NULL; i++) { + if (!lab->changed) { + continue; + } + + lab->changed = 0U; + + snprintk(path, sizeof(path), "bt_mesh/Va/%x", i); + + if (IS_VA_DEL(lab)) { + val = NULL; + } else { + va.ref = lab->ref; + va.addr = lab->addr; + memcpy(va.uuid, lab->uuid, 16); + + val = settings_str_from_bytes(&va, sizeof(va), + buf, sizeof(buf)); + if (!val) { + BT_ERR("Unable to encode model publication as value"); + return; + } + + err = settings_save_one(path, val); + } + + if (err) { + BT_ERR("Failed to %s %s value (err %d)", + IS_VA_DEL(lab) ? "delete" : "store", path, err); + } else { + BT_DBG("%s %s value", + IS_VA_DEL(lab) ? "Deleted" : "Stored", path); + } + } +} + +#if CONFIG_BT_MESH_LABEL_COUNT > 0 +static struct conf_handler bt_mesh_va_conf_handler = { + .ch_name = "bt_mesh", + .ch_get = NULL, + .ch_set = va_set, + .ch_commit = NULL, + .ch_export = NULL, + }; + +void bt_mesh_va_init(void) +{ + int rc; + + rc = conf_register(&bt_mesh_va_conf_handler); + + SYSINIT_PANIC_ASSERT_MSG(rc == 0, + "Failed to register bt_mesh_hb_pub conf"); +} +#endif \ No newline at end of file diff --git a/nimble/host/mesh/src/transport.h b/nimble/host/mesh/src/transport.h index bf458e83c8..a1af9a4bd8 100644 --- a/nimble/host/mesh/src/transport.h +++ b/nimble/host/mesh/src/transport.h @@ -79,13 +79,6 @@ struct bt_mesh_ctl_friend_sub_confirm { uint8_t xact; }__attribute__((__packed__)); -struct bt_mesh_va { - uint16_t ref:15, - changed:1; - uint16_t addr; - uint8_t uuid[16]; -}; - bool bt_mesh_tx_in_progress(void); void bt_mesh_rx_reset(void); @@ -102,12 +95,12 @@ void bt_mesh_trans_init(void); void bt_mesh_trans_reset(void); -struct bt_mesh_va *bt_mesh_va_get(uint16_t index); - -struct bt_mesh_va *bt_mesh_va_find(uint8_t uuid[16]); - uint8_t bt_mesh_va_add(const uint8_t uuid[16], uint16_t *addr); uint8_t bt_mesh_va_del(const uint8_t uuid[16], uint16_t *addr); -uint8_t *bt_mesh_va_label_get(uint16_t addr); \ No newline at end of file +uint8_t *bt_mesh_va_label_get(uint16_t addr); + +void bt_mesh_va_pending_store(void); + +void bt_mesh_va_init(void); \ No newline at end of file diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index d110a3888a..99b18c2056 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -58,6 +58,7 @@ syscfg.defs: description: > Mesh Configuration Database [EXPERIMENTAL] value: 0 + restrictions: BLE_MESH_SETTINGS BLE_MESH_CDB_NODE_COUNT: description: > @@ -82,6 +83,12 @@ syscfg.defs: Use this option to enable configuration database debug logs. value: 1 + BLE_MESH_DEBUG_CFG: + description: + Use this option to enable node configuration debug logs for the + Bluetooth Mesh functionality. + value: 1 + BLE_MESH_PROXY: description: > Enable proxy. This is automatically set whenever BLE_MESH_PB_GATT or From 0fa50c3eddf1e7d7523ba996643a5c02fa90411b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 6 Oct 2021 07:49:48 +0200 Subject: [PATCH 0069/1333] host/mesh: Fix mod app key get vnd pass cid instead of CID_NVAL in parameters of mod_member_list_get This is port of 3ff1eb618fd50ecb4328d0f832471caaec7be3ee --- nimble/host/mesh/src/cfg_cli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/cfg_cli.c b/nimble/host/mesh/src/cfg_cli.c index 2df7d70271..f51e07c20e 100644 --- a/nimble/host/mesh/src/cfg_cli.c +++ b/nimble/host/mesh/src/cfg_cli.c @@ -1557,7 +1557,7 @@ int bt_mesh_cfg_mod_app_get_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_a } return mod_member_list_get(OP_VND_MOD_APP_GET, OP_VND_MOD_APP_LIST, - net_idx, addr, elem_addr, mod_id, CID_NVAL, + net_idx, addr, elem_addr, mod_id, cid, status, apps, app_cnt); } From 0c6d730e7aaf3b70c20ec98e47f22852d159c2a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 6 Oct 2021 07:52:58 +0200 Subject: [PATCH 0070/1333] host/mesh: Fix fix mod_sub_get_vnd pass cid instead of CID_NVAL in parameters of mod_member_list_get This is port of 942979b252a46602213656107d6b5b6a5e98615c --- nimble/host/mesh/src/cfg_cli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/cfg_cli.c b/nimble/host/mesh/src/cfg_cli.c index f51e07c20e..6806818d8a 100644 --- a/nimble/host/mesh/src/cfg_cli.c +++ b/nimble/host/mesh/src/cfg_cli.c @@ -1808,7 +1808,7 @@ int bt_mesh_cfg_mod_sub_get_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_a } return mod_member_list_get(OP_MOD_SUB_GET_VND, OP_MOD_SUB_LIST_VND, - net_idx, addr, elem_addr, mod_id, CID_NVAL, + net_idx, addr, elem_addr, mod_id, cid, status, subs, sub_cnt); } From 94b3c4a9d3d3d2f961c21048f8c90696e7823913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 6 Oct 2021 07:59:16 +0200 Subject: [PATCH 0071/1333] host/mesh: Store network at the end of provisioning After #31176, the network would get stored immediately in bt_mesh_net_create, causing the address and devicekey to get stored as their zero-initialized version, as they're only being set in the bt_mesh_comp_provision call, which fires after. This is port of a281d10cff8d0e626fcc31897649f4312c794a4e --- nimble/host/mesh/src/mesh.c | 4 ++++ nimble/host/mesh/src/net.c | 6 ------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c index b22dc1363f..2417872a95 100644 --- a/nimble/host/mesh/src/mesh.c +++ b/nimble/host/mesh/src/mesh.c @@ -134,6 +134,10 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, bt_mesh_lpn_group_add(BT_MESH_ADDR_ALL_NODES); } + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_net_pending_net_store(); + } + bt_mesh_start(); return 0; diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index 76ef9eaef8..692989dd23 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -137,11 +137,6 @@ static void msg_cache_add(struct bt_mesh_net_rx *rx) msg_cache_next %= ARRAY_SIZE(msg_cache); } -static void store_net(void) -{ - bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_NET_PENDING); -} - static void store_iv(bool only_duration) { bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_IV_PENDING); @@ -197,7 +192,6 @@ int bt_mesh_net_create(uint16_t idx, uint8_t flags, const uint8_t key[16], if (IS_ENABLED(CONFIG_BT_SETTINGS)) { BT_DBG("Storing network information persistently"); - store_net(); bt_mesh_subnet_store(idx); store_iv(false); } From ea75a5e683da0f69aeeae926fcd4f7491a151d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 6 Oct 2021 08:05:48 +0200 Subject: [PATCH 0072/1333] host/mesh: Update seqnum when re-encrypting for friend Sets the sequence number when re-encrypting messages from the friend to the lpn. This is port of 512444d863f0e4de69ea600dda37b11f032e9707 --- nimble/host/mesh/src/friend.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimble/host/mesh/src/friend.c b/nimble/host/mesh/src/friend.c index ff34eda9c6..b544a7830a 100644 --- a/nimble/host/mesh/src/friend.c +++ b/nimble/host/mesh/src/friend.c @@ -431,6 +431,9 @@ static int unseg_app_sdu_prepare(struct bt_mesh_friend *frnd, return 0; } + BT_DBG("Re-encrypting friend pdu (SeqNum %06x -> %06x)", + meta.crypto.seq_num, bt_mesh.seq); + err = unseg_app_sdu_unpack(frnd, buf, &meta); if (err) { return err; @@ -446,6 +449,8 @@ static int unseg_app_sdu_prepare(struct bt_mesh_friend *frnd, BT_DBG("Re-encrypting friend pdu (SeqNum %06x -> %06x)", meta.crypto.seq_num, bt_mesh.seq); + meta.crypto.seq_num = bt_mesh.seq; + err = unseg_app_sdu_decrypt(frnd, buf, &meta); if (err) { BT_WARN("Decryption failed! %d", err); From 9a7d9f4a7f7f103b13fecb41466dcfbe8cc57cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 6 Oct 2021 08:24:55 +0200 Subject: [PATCH 0073/1333] host/mesh: Only do label lookup when there are labels Include virtual label's pending_store function in the LABEL_COUNT > 0 compile guard to avoid including dead iteration code in the compilation. This is port of 7039675df13c74e74fb76d4f41cfc7e949c209ad --- nimble/host/mesh/src/transport.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/nimble/host/mesh/src/transport.c b/nimble/host/mesh/src/transport.c index 721d5005b6..0299c98331 100644 --- a/nimble/host/mesh/src/transport.c +++ b/nimble/host/mesh/src/transport.c @@ -1749,6 +1749,7 @@ uint8_t *bt_mesh_va_label_get(uint16_t addr) return NULL; } +#if CONFIG_BT_MESH_LABEL_COUNT > 0 static struct virtual_addr *bt_mesh_va_get(uint16_t index) { if (index >= ARRAY_SIZE(virtual_addrs)) { @@ -1758,7 +1759,6 @@ static struct virtual_addr *bt_mesh_va_get(uint16_t index) return &virtual_addrs[index]; } -#if CONFIG_BT_MESH_LABEL_COUNT > 0 static int va_set(int argc, char **argv, char *val) { struct va_val va; @@ -1809,7 +1809,6 @@ static int va_set(int argc, char **argv, char *val) return 0; } -#endif #define IS_VA_DEL(_label) ((_label)->ref == 0) void bt_mesh_va_pending_store(void) @@ -1857,8 +1856,13 @@ void bt_mesh_va_pending_store(void) } } } +#else +void bt_mesh_va_pending_store(void) +{ + /* Do nothing. */ +} +#endif /* CONFIG_BT_MESH_LABEL_COUNT > 0 */ -#if CONFIG_BT_MESH_LABEL_COUNT > 0 static struct conf_handler bt_mesh_va_conf_handler = { .ch_name = "bt_mesh", .ch_get = NULL, From 135dd1b42edd7e9cf4d9a4f994889a01868b0539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 6 Oct 2021 08:33:16 +0200 Subject: [PATCH 0074/1333] Resolve dead code in store_seg If CONFIG_BT_MESH_SEQ_STORE_RATE is 1, the check in store_seq can be reduced to a simple if (false), and the modulo code does not need to be included in the build. This is port of aef354c6bc3264de9f2a38b8c56ff5253b35912a --- nimble/host/mesh/src/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index 692989dd23..b3e22aad30 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -149,7 +149,7 @@ static void store_iv(bool only_duration) static void store_seq(void) { - if (CONFIG_BT_MESH_SEQ_STORE_RATE && + if (CONFIG_BT_MESH_SEQ_STORE_RATE > 1 && (bt_mesh.seq % CONFIG_BT_MESH_SEQ_STORE_RATE)) { return; } From 097aa7f9a164613e63291243441df9955ed22954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 6 Oct 2021 15:18:32 +0200 Subject: [PATCH 0075/1333] host/mesh: update k_work API Updated k_work API to new behaviour reflected in `glue`. This is port of: 81b9ba3a9b2dd4d5bd3f0966eac9f8f6dad983e6 17831b045f5869b0e57e26caa0441f263d1a5ae6 6a097caa22c769855aba552b50371bafe05ee6b4 5506727bde18bb9afcf4f1b969cd2cc09d7e65f8 --- apps/mesh_badge/src/reel_board.c | 24 ++++----- nimble/host/mesh/include/mesh/access.h | 2 +- nimble/host/mesh/include/mesh/glue.h | 16 +++--- nimble/host/mesh/include/mesh/health_srv.h | 2 +- nimble/host/mesh/src/access.c | 12 ++--- nimble/host/mesh/src/beacon.c | 20 ++++---- nimble/host/mesh/src/cfg_srv.c | 9 ++-- nimble/host/mesh/src/friend.c | 22 ++++---- nimble/host/mesh/src/glue.c | 36 +++++++++++--- nimble/host/mesh/src/health_srv.c | 22 +++----- nimble/host/mesh/src/heartbeat.c | 58 +++++++++++----------- nimble/host/mesh/src/lpn.c | 32 ++++++------ nimble/host/mesh/src/mesh.c | 6 +-- nimble/host/mesh/src/net.c | 8 +-- nimble/host/mesh/src/net.h | 8 +-- nimble/host/mesh/src/pb_adv.c | 20 ++++---- nimble/host/mesh/src/pb_gatt.c | 12 ++--- nimble/host/mesh/src/proxy.c | 14 +++--- nimble/host/mesh/src/settings.c | 25 ++++++---- nimble/host/mesh/src/transport.c | 46 ++++++++--------- 20 files changed, 207 insertions(+), 187 deletions(-) diff --git a/apps/mesh_badge/src/reel_board.c b/apps/mesh_badge/src/reel_board.c index bc8229377f..5e5f6b4088 100644 --- a/apps/mesh_badge/src/reel_board.c +++ b/apps/mesh_badge/src/reel_board.c @@ -49,8 +49,8 @@ struct font_info { static struct os_dev *epd_dev; static bool pressed; static bool stats_view; -static struct k_delayed_work epd_work; -static struct k_delayed_work long_press_work; +static struct k_work_delayable epd_work; +static struct k_work_delayable long_press_work; static struct { int pin; @@ -61,7 +61,7 @@ static struct { { .pin = RGB_LED_BLU, }, }; -struct k_delayed_work led_timer; +struct k_work_delayable led_timer; static size_t print_line(enum font_size font_size, int row, const char *text, size_t len, bool center) @@ -121,7 +121,7 @@ static size_t get_len(enum font_size font, const char *text) void board_blink_leds(void) { - k_delayed_work_submit(&led_timer, K_MSEC(100)); + k_work_reschedule(&led_timer, K_MSEC(100)); } void board_show_text(const char *text, bool center, int32_t duration) @@ -151,7 +151,7 @@ void board_show_text(const char *text, bool center, int32_t duration) cfb_framebuffer_finalize(epd_dev); if (duration != K_FOREVER) { - k_delayed_work_submit(&epd_work, duration); + k_work_reschedule(&epd_work, duration); } } @@ -381,11 +381,11 @@ static void button_interrupt(struct os_event *ev) printk("Button %s\n", pressed ? "pressed" : "released"); if (pressed) { - k_delayed_work_submit(&long_press_work, LONG_PRESS_TIMEOUT); + k_work_reschedule(&long_press_work, LONG_PRESS_TIMEOUT); return; } - k_delayed_work_cancel(&long_press_work); + k_work_cancel_delayable(&long_press_work); if (!mesh_is_initialized()) { return; @@ -441,7 +441,7 @@ static void led_timeout(struct ble_npl_event *work) i = led_cntr++ % ARRAY_SIZE(leds); hal_gpio_write(leds[i].pin, 0); - k_delayed_work_submit(&led_timer, K_MSEC(100)); + k_work_reschedule(&led_timer, K_MSEC(100)); } static int configure_leds(void) @@ -452,7 +452,7 @@ static int configure_leds(void) hal_gpio_init_out(leds[i].pin, 1); } - k_delayed_work_init(&led_timer, led_timeout); + k_work_init_delayable(&led_timer, led_timeout); return 0; } @@ -466,7 +466,7 @@ static int erase_storage(void) void board_refresh_display(void) { - k_delayed_work_submit(&epd_work, K_NO_WAIT); + k_work_reschedule(&epd_work, K_NO_WAIT); } int board_init(void) @@ -494,8 +494,8 @@ int board_init(void) return -EIO; } - k_delayed_work_init(&epd_work, epd_update); - k_delayed_work_init(&long_press_work, long_press); + k_work_init_delayable(&epd_work, epd_update); + k_work_init_delayable(&long_press_work, long_press); pressed = button_is_pressed(); if (pressed) { diff --git a/nimble/host/mesh/include/mesh/access.h b/nimble/host/mesh/include/mesh/access.h index 9f923cb9e4..f12ec85b59 100644 --- a/nimble/host/mesh/include/mesh/access.h +++ b/nimble/host/mesh/include/mesh/access.h @@ -436,7 +436,7 @@ struct bt_mesh_model_pub { int (*update)(struct bt_mesh_model *mod); /** Publish Period Timer. Only for stack-internal use. */ - struct k_delayed_work timer; + struct k_work_delayable timer; }; /** Model callback functions. */ diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index eedaaac92d..34a32aed9c 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -329,22 +329,24 @@ int bt_le_adv_start(const struct ble_gap_adv_params *param, const struct bt_data *sd, size_t sd_len); int bt_le_adv_stop(bool proxy); -struct k_delayed_work { +struct k_work_delayable { struct ble_npl_callout work; }; void k_work_init(struct ble_npl_callout *work, ble_npl_event_fn handler); -void k_delayed_work_init(struct k_delayed_work *w, ble_npl_event_fn *f); -void k_delayed_work_cancel(struct k_delayed_work *w); -bool k_delayed_work_pending(struct k_delayed_work *w); -void k_delayed_work_submit(struct k_delayed_work *w, uint32_t ms); +void k_work_init_delayable(struct k_work_delayable *w, ble_npl_event_fn *f); +void k_work_cancel_delayable(struct k_work_delayable *w); +bool k_work_delayable_is_pending(struct k_work_delayable *w); +void k_work_reschedule(struct k_work_delayable *w, uint32_t ms); int64_t k_uptime_get(void); uint32_t k_uptime_get_32(void); void k_sleep(int32_t duration); void k_work_submit(struct ble_npl_callout *w); void k_work_add_arg(struct ble_npl_callout *w, void *arg); -void k_delayed_work_add_arg(struct k_delayed_work *w, void *arg); -uint32_t k_delayed_work_remaining_get(struct k_delayed_work *w); +void k_work_add_arg_delayable(struct k_work_delayable *w, void *arg); +ble_npl_time_t k_work_delayable_remaining_get(struct k_work_delayable *w); +void k_work_schedule(struct k_work_delayable *w, uint32_t ms); +uint32_t k_ticks_to_ms_floor32(ble_npl_time_t ticks); static inline void net_buf_simple_save(struct os_mbuf *buf, struct net_buf_simple_state *state) diff --git a/nimble/host/mesh/include/mesh/health_srv.h b/nimble/host/mesh/include/mesh/health_srv.h index ad79e368da..980e757486 100644 --- a/nimble/host/mesh/include/mesh/health_srv.h +++ b/nimble/host/mesh/include/mesh/health_srv.h @@ -65,7 +65,7 @@ struct bt_mesh_health_srv { const struct bt_mesh_health_srv_cb *cb; /* Attention Timer state */ - struct k_delayed_work attn_timer; + struct k_work_delayable attn_timer; }; int bt_mesh_fault_update(struct bt_mesh_elem *elem); diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index c6436e85e8..5c12792ecb 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -148,7 +148,7 @@ static void publish_sent(int err, void *user_data) if (delay) { BT_DBG("Publishing next time in %dms", (int) delay); - k_delayed_work_submit(&mod->pub->timer, delay); + k_work_reschedule(&mod->pub->timer, delay); } } @@ -228,7 +228,7 @@ static void mod_publish(struct ble_npl_event *work) /* Continue with normal publication */ if (period_ms) { - k_delayed_work_submit(&pub->timer, period_ms); + k_work_reschedule(&pub->timer, period_ms); } } @@ -301,8 +301,8 @@ static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, if (mod->pub) { mod->pub->mod = mod; - k_delayed_work_init(&mod->pub->timer, mod_publish); - k_delayed_work_add_arg(&mod->pub->timer, mod->pub); + k_work_init_delayable(&mod->pub->timer, mod_publish); + k_work_add_arg_delayable(&mod->pub->timer, mod->pub); } for (i = 0; i < ARRAY_SIZE(mod->keys); i++) { @@ -738,7 +738,7 @@ int bt_mesh_model_publish(struct bt_mesh_model *model) if (pub->count) { BT_WARN("Clearing publish retransmit timer"); - k_delayed_work_cancel(&pub->timer); + k_work_cancel_delayable(&pub->timer); } net_buf_simple_init(sdu, 0); @@ -1249,7 +1249,7 @@ static void commit_mod(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, if (ms > 0) { BT_DBG("Starting publish timer (period %u ms)", ms); - k_delayed_work_submit(&mod->pub->timer, K_MSEC(ms)); + k_work_reschedule(&mod->pub->timer, K_MSEC(ms)); } } diff --git a/nimble/host/mesh/src/beacon.c b/nimble/host/mesh/src/beacon.c index 6a5fc5a1cd..d7be9c5e1c 100644 --- a/nimble/host/mesh/src/beacon.c +++ b/nimble/host/mesh/src/beacon.c @@ -34,7 +34,7 @@ /* 1 transmission, 20ms interval */ #define PROV_XMIT BT_MESH_TRANSMIT(0, 20) -static struct k_delayed_work beacon_timer; +static struct k_work_delayable beacon_timer; static int cache_check(struct bt_mesh_subnet *sub, void *beacon_data) { @@ -230,7 +230,7 @@ static void beacon_send(struct ble_npl_event *work) { /* Don't send anything if we have an active provisioning link */ if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV) && bt_mesh_prov_active()) { - k_delayed_work_submit(&beacon_timer, + k_work_reschedule(&beacon_timer, K_SECONDS(MYNEWT_VAL(BLE_MESH_UNPROV_BEACON_INT))); return; } @@ -244,7 +244,7 @@ static void beacon_send(struct ble_npl_event *work) /* Only resubmit if beaconing is still enabled */ if (bt_mesh_beacon_enabled() || atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR)) { - k_delayed_work_submit(&beacon_timer, + k_work_reschedule(&beacon_timer, PROVISIONED_INTERVAL); } @@ -253,7 +253,7 @@ static void beacon_send(struct ble_npl_event *work) if (IS_ENABLED(BLE_MESH_PB_ADV)) { unprovisioned_beacon_send(); - k_delayed_work_submit(&beacon_timer, + k_work_reschedule(&beacon_timer, K_SECONDS(MYNEWT_VAL(BLE_MESH_UNPROV_BEACON_INT))); } } @@ -430,7 +430,7 @@ void bt_mesh_beacon_init(void) bt_mesh_subnet_cb_list[1] = subnet_evt; } - k_delayed_work_init(&beacon_timer, beacon_send); + k_work_init_delayable(&beacon_timer, beacon_send); } void bt_mesh_beacon_ivu_initiator(bool enable) @@ -438,9 +438,9 @@ void bt_mesh_beacon_ivu_initiator(bool enable) atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_INITIATOR, enable); if (enable) { - k_delayed_work_submit(&beacon_timer, K_NO_WAIT); + k_work_reschedule(&beacon_timer, K_NO_WAIT); } else if (!bt_mesh_beacon_enabled()) { - k_delayed_work_cancel(&beacon_timer); + k_work_cancel_delayable(&beacon_timer); } } @@ -455,18 +455,18 @@ static void subnet_beacon_enable(struct bt_mesh_subnet *sub) void bt_mesh_beacon_enable(void) { if (!bt_mesh_is_provisioned()) { - k_delayed_work_submit(&beacon_timer, K_NO_WAIT); + k_work_reschedule(&beacon_timer, K_NO_WAIT); return; } bt_mesh_subnet_foreach(subnet_beacon_enable); - k_delayed_work_submit(&beacon_timer, K_NO_WAIT); + k_work_reschedule(&beacon_timer, K_NO_WAIT); } void bt_mesh_beacon_disable(void) { if (!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR)) { - k_delayed_work_cancel(&beacon_timer); + k_work_cancel_delayable(&beacon_timer); } } diff --git a/nimble/host/mesh/src/cfg_srv.c b/nimble/host/mesh/src/cfg_srv.c index 4c0da372ba..919c26a94a 100644 --- a/nimble/host/mesh/src/cfg_srv.c +++ b/nimble/host/mesh/src/cfg_srv.c @@ -200,7 +200,7 @@ static uint8_t _mod_pub_set(struct bt_mesh_model *model, uint16_t pub_addr, model->pub->count = 0; if (model->pub->update) { - k_delayed_work_cancel(&model->pub->timer); + k_work_cancel_delayable(&model->pub->timer); } if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) { @@ -238,9 +238,9 @@ static uint8_t _mod_pub_set(struct bt_mesh_model *model, uint16_t pub_addr, BT_DBG("period %u ms", (unsigned) period_ms); if (period_ms > 0) { - k_delayed_work_submit(&model->pub->timer, period_ms); + k_work_reschedule(&model->pub->timer, period_ms); } else { - k_delayed_work_cancel(&model->pub->timer); + k_work_cancel_delayable(&model->pub->timer); } } @@ -2128,7 +2128,8 @@ static void lpn_timeout_get(struct bt_mesh_model *model, goto send_rsp; } - timeout = k_delayed_work_remaining_get(&frnd->timer) / 100; + timeout = k_ticks_to_ms_floor32( + k_work_delayable_remaining_get(&frnd->timer)) / 100; send_rsp: net_buf_simple_add_le24(msg, timeout); diff --git a/nimble/host/mesh/src/friend.c b/nimble/host/mesh/src/friend.c index b544a7830a..402930f9f8 100644 --- a/nimble/host/mesh/src/friend.c +++ b/nimble/host/mesh/src/friend.c @@ -151,7 +151,7 @@ static void friend_clear(struct bt_mesh_friend *frnd) BT_DBG("LPN 0x%04x", frnd->lpn); - k_delayed_work_cancel(&frnd->timer); + k_work_cancel_delayable(&frnd->timer); memset(frnd->cred, 0, sizeof(frnd->cred)); @@ -605,7 +605,7 @@ static void friend_recv_delay(struct bt_mesh_friend *frnd) int32_t delay = recv_delay(frnd); frnd->pending_req = 1; - k_delayed_work_submit(&frnd->timer, K_MSEC(delay)); + k_work_reschedule(&frnd->timer, K_MSEC(delay)); BT_DBG("Waiting RecvDelay of %d ms", delay); } @@ -772,7 +772,7 @@ static void friend_clear_sent(int err, void *user_data) { struct bt_mesh_friend *frnd = user_data; - k_delayed_work_submit(&frnd->clear.timer, + k_work_reschedule(&frnd->clear.timer, K_SECONDS(frnd->clear.repeat_sec)); frnd->clear.repeat_sec *= 2; } @@ -867,7 +867,7 @@ int bt_mesh_friend_clear_cfm(struct bt_mesh_net_rx *rx, return 0; } - k_delayed_work_cancel(&frnd->clear.timer); + k_work_cancel_delayable(&frnd->clear.timer); frnd->clear.frnd = BT_MESH_ADDR_UNASSIGNED; return 0; @@ -1037,7 +1037,7 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) } delay = offer_delay(frnd, rx->ctx.recv_rssi, msg->criteria); - k_delayed_work_submit(&frnd->timer, K_MSEC(delay)); + k_work_reschedule(&frnd->timer, K_MSEC(delay)); enqueue_offer(frnd, rx->ctx.recv_rssi); @@ -1154,12 +1154,12 @@ static void buf_send_end(int err, void *user_data) } if (frnd->established) { - k_delayed_work_submit(&frnd->timer, frnd->poll_to); + k_work_reschedule(&frnd->timer, frnd->poll_to); BT_DBG("Waiting %u ms for next poll", (unsigned) frnd->poll_to); } else { /* Friend offer timeout is 1 second */ - k_delayed_work_submit(&frnd->timer, K_SECONDS(1)); + k_work_reschedule(&frnd->timer, K_SECONDS(1)); BT_DBG("Waiting for first poll"); } } @@ -1322,10 +1322,10 @@ int bt_mesh_friend_init(void) net_buf_slist_init(&frnd->queue); - k_delayed_work_init(&frnd->timer, friend_timeout); - k_delayed_work_add_arg(&frnd->timer, frnd); - k_delayed_work_init(&frnd->clear.timer, clear_timeout); - k_delayed_work_add_arg(&frnd->clear.timer, frnd); + k_work_init_delayable(&frnd->timer, friend_timeout); + k_work_add_arg_delayable(&frnd->timer, frnd); + k_work_init_delayable(&frnd->clear.timer, clear_timeout); + k_work_add_arg_delayable(&frnd->clear.timer, frnd); for (j = 0; j < ARRAY_SIZE(frnd->seg); j++) { net_buf_slist_init(&frnd->seg[j].queue); diff --git a/nimble/host/mesh/src/glue.c b/nimble/host/mesh/src/glue.c index 8862344dca..2059e2a6f4 100644 --- a/nimble/host/mesh/src/glue.c +++ b/nimble/host/mesh/src/glue.c @@ -399,7 +399,7 @@ k_work_init(struct ble_npl_callout *work, ble_npl_event_fn handler) } void -k_delayed_work_init(struct k_delayed_work *w, ble_npl_event_fn *f) +k_work_init_delayable(struct k_work_delayable *w, ble_npl_event_fn *f) { #ifndef MYNEWT ble_npl_callout_init(&w->work, nimble_port_get_dflt_eventq(), f, NULL); @@ -409,25 +409,39 @@ k_delayed_work_init(struct k_delayed_work *w, ble_npl_event_fn *f) } bool -k_delayed_work_pending(struct k_delayed_work *w) +k_work_delayable_is_pending(struct k_work_delayable *w) { return ble_npl_callout_is_active(&w->work); } void -k_delayed_work_cancel(struct k_delayed_work *w) +k_work_cancel_delayable(struct k_work_delayable *w) { ble_npl_callout_stop(&w->work); } void -k_delayed_work_submit(struct k_delayed_work *w, uint32_t ms) +k_work_schedule(struct k_work_delayable *w, uint32_t ms) + { + uint32_t ticks; + + if (ble_npl_time_ms_to_ticks(ms, &ticks) != 0) { + assert(0); + } + ble_npl_callout_reset(&w->work, ticks); +} + +void +k_work_reschedule(struct k_work_delayable *w, uint32_t ms) { uint32_t ticks; if (ble_npl_time_ms_to_ticks(ms, &ticks) != 0) { assert(0); } + if (ms == 0) { + ble_npl_callout_stop(&w->work); + } ble_npl_callout_reset(&w->work, ticks); } @@ -444,13 +458,13 @@ k_work_add_arg(struct ble_npl_callout *w, void *arg) } void -k_delayed_work_add_arg(struct k_delayed_work *w, void *arg) +k_work_add_arg_delayable(struct k_work_delayable *w, void *arg) { k_work_add_arg(&w->work, arg); } -uint32_t -k_delayed_work_remaining_get (struct k_delayed_work *w) +ble_npl_time_t +k_work_delayable_remaining_get (struct k_work_delayable *w) { int sr; ble_npl_time_t t; @@ -461,7 +475,13 @@ k_delayed_work_remaining_get (struct k_delayed_work *w) OS_EXIT_CRITICAL(sr); - return ble_npl_time_ticks_to_ms32(t); + return t; +} + +uint32_t +k_ticks_to_ms_floor32(ble_npl_time_t ticks) +{ + return ble_npl_time_ticks_to_ms32(ticks); } int64_t k_uptime_get(void) diff --git a/nimble/host/mesh/src/health_srv.c b/nimble/host/mesh/src/health_srv.c index dd90533be8..d7436b30a3 100644 --- a/nimble/host/mesh/src/health_srv.c +++ b/nimble/host/mesh/src/health_srv.c @@ -221,7 +221,8 @@ static void send_attention_status(struct bt_mesh_model *model, struct bt_mesh_health_srv *srv = model->user_data; uint8_t time; - time = k_delayed_work_remaining_get(&srv->attn_timer) / 1000; + time = k_ticks_to_ms_floor32( + k_work_delayable_remaining_get(&srv->attn_timer)) / 1000; BT_DBG("%u second%s", time, (time == 1) ? "" : "s"); bt_mesh_model_msg_init(msg, OP_ATTENTION_STATUS); @@ -400,8 +401,8 @@ static int health_srv_init(struct bt_mesh_model *model) model->pub->update = health_pub_update; - k_delayed_work_init(&srv->attn_timer, attention_off); - k_delayed_work_add_arg(&srv->attn_timer, srv); + k_work_init_delayable(&srv->attn_timer, attention_off); + k_work_add_arg_delayable(&srv->attn_timer, srv); srv->model = model; @@ -433,17 +434,8 @@ void bt_mesh_attention(struct bt_mesh_model *model, uint8_t time) srv = model->user_data; } - if (time) { - if (srv->cb && srv->cb->attn_on) { - srv->cb->attn_on(model); - } - - k_delayed_work_submit(&srv->attn_timer, time * 1000); - } else { - k_delayed_work_cancel(&srv->attn_timer); - - if (srv->cb && srv->cb->attn_off) { - srv->cb->attn_off(model); - } + if ((time > 0) && srv->cb && srv->cb->attn_on) { + srv->cb->attn_on(model); } + k_work_reschedule(&srv->attn_timer, K_SECONDS(time)); } diff --git a/nimble/host/mesh/src/heartbeat.c b/nimble/host/mesh/src/heartbeat.c index 656942b426..1d249b4899 100644 --- a/nimble/host/mesh/src/heartbeat.c +++ b/nimble/host/mesh/src/heartbeat.c @@ -31,8 +31,8 @@ struct bt_mesh_hb_cb hb_cb; static struct bt_mesh_hb_pub pub; static struct bt_mesh_hb_sub sub; -static struct k_delayed_work sub_timer; -static struct k_delayed_work pub_timer; +static struct k_work_delayable sub_timer; +static struct k_work_delayable pub_timer; static int64_t sub_remaining(void) { @@ -40,13 +40,15 @@ static int64_t sub_remaining(void) return 0U; } - return k_delayed_work_remaining_get(&sub_timer) / MSEC_PER_SEC; + uint32_t rem_ms = k_ticks_to_ms_floor32( + k_work_delayable_remaining_get(&sub_timer)); + return rem_ms / MSEC_PER_SEC; } static void hb_publish_end_cb(int err, void *cb_data) { if (pub.period && pub.count > 1) { - k_delayed_work_submit(&pub_timer, K_SECONDS(pub.period)); + k_work_reschedule(&pub_timer, K_SECONDS(pub.period)); } if (pub.count != 0xffff) { @@ -148,6 +150,11 @@ static void hb_publish(struct ble_npl_event *work) BT_DBG("hb_pub.count: %u", pub.count); + /* Fast exit if disabled or expired */ + if (pub.period == 0U || pub.count == 0U) { + return; + } + sub = bt_mesh_subnet_get(pub.net_idx); if (!sub) { BT_ERR("No matching subnet for idx 0x%02x", pub.net_idx); @@ -155,10 +162,6 @@ static void hb_publish(struct ble_npl_event *work) return; } - if (pub.count == 0U) { - return; - } - err = heartbeat_send(&publish_cb, NULL); if (err) { hb_publish_end_cb(err, NULL); @@ -185,8 +188,8 @@ int bt_mesh_hb_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) return 0; } - if (!k_delayed_work_pending(&sub_timer)) { - BT_DBG("Heartbeat subscription period expired"); + if (!k_work_delayable_is_pending(&sub_timer)) { + BT_DBG("Heartbeat subscription inactive"); return 0; } @@ -215,7 +218,7 @@ static void pub_disable(void) pub.ttl = 0U; pub.period = 0U; - k_delayed_work_cancel(&pub_timer); + k_work_cancel_delayable(&pub_timer); } uint8_t bt_mesh_hb_pub_set(struct bt_mesh_hb_pub *new_pub) @@ -247,12 +250,11 @@ uint8_t bt_mesh_hb_pub_set(struct bt_mesh_hb_pub *new_pub) /* The first Heartbeat message shall be published as soon as possible * after the Heartbeat Publication Period state has been configured for * periodic publishing. + * + * If the new configuration disables publishing this flushes + * the work item. */ - if (pub.period && pub.count) { - k_delayed_work_submit(&pub_timer, K_NO_WAIT); - } else { - k_delayed_work_cancel(&pub_timer); - } + k_work_reschedule(&pub_timer, K_NO_WAIT); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { bt_mesh_settings_store_schedule( @@ -294,9 +296,7 @@ uint8_t bt_mesh_hb_sub_set(uint16_t src, uint16_t dst, uint32_t period) sub.min_hops = 0U; sub.max_hops = 0U; sub.count = 0U; - sub.period = sub.period - sub_remaining(); - k_delayed_work_cancel(&sub_timer); - notify_sub_end(); + sub.period = 0U; } else if (period) { sub.src = src; sub.dst = dst; @@ -304,16 +304,18 @@ uint8_t bt_mesh_hb_sub_set(uint16_t src, uint16_t dst, uint32_t period) sub.max_hops = 0U; sub.count = 0U; sub.period = period; - k_delayed_work_submit(&sub_timer, K_SECONDS(period)); } else { /* Clearing the period should stop heartbeat subscription * without clearing the parameters, so we can still read them. */ - sub.period = sub.period - sub_remaining(); - k_delayed_work_cancel(&sub_timer); - notify_sub_end(); + sub.period = 0U; } + /* Start the timer, which notifies immediately if the new + * configuration disables the subscription. + */ + k_work_reschedule(&sub_timer, K_SECONDS(sub.period)); + return STATUS_SUCCESS; } @@ -344,28 +346,28 @@ void bt_mesh_hb_feature_changed(uint16_t features) void bt_mesh_hb_init(void) { pub.net_idx = BT_MESH_KEY_UNUSED; - k_delayed_work_init(&pub_timer, hb_publish); - k_delayed_work_init(&sub_timer, sub_end); + k_work_init_delayable(&pub_timer, hb_publish); + k_work_init_delayable(&sub_timer, sub_end); } void bt_mesh_hb_start(void) { if (pub.count && pub.period) { BT_DBG("Starting heartbeat publication"); - k_delayed_work_submit(&pub_timer, K_NO_WAIT); + k_work_reschedule(&pub_timer, K_NO_WAIT); } } void bt_mesh_hb_suspend(void) { - k_delayed_work_cancel(&pub_timer); + (void)k_work_cancel_delayable(&pub_timer); } void bt_mesh_hb_resume(void) { if (pub.period && pub.count) { BT_DBG("Starting heartbeat publication"); - k_delayed_work_submit(&pub_timer, K_NO_WAIT); + k_work_reschedule(&pub_timer, K_NO_WAIT); } } diff --git a/nimble/host/mesh/src/lpn.c b/nimble/host/mesh/src/lpn.c index 45c9004b63..4c6c708ca2 100644 --- a/nimble/host/mesh/src/lpn.c +++ b/nimble/host/mesh/src/lpn.c @@ -182,7 +182,7 @@ static void friend_clear_sent(int err, void *user_data) } lpn_set_state(BT_MESH_LPN_CLEAR); - k_delayed_work_submit(&lpn->timer, FRIEND_REQ_TIMEOUT); + k_work_reschedule(&lpn->timer, FRIEND_REQ_TIMEOUT); } static const struct bt_mesh_send_cb clear_sent_cb = { @@ -230,7 +230,7 @@ static void clear_friendship(bool force, bool disable) bt_mesh_rx_reset(); lpn_set_state(BT_MESH_LPN_DISABLED); - k_delayed_work_cancel(&lpn->timer); + k_work_cancel_delayable(&lpn->timer); if (lpn->clear_success) { lpn->old_friend = BT_MESH_ADDR_UNASSIGNED; @@ -267,7 +267,7 @@ static void clear_friendship(bool force, bool disable) if (!disable) { lpn_set_state(BT_MESH_LPN_DISABLED); - k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT); + k_work_reschedule(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT); return; } @@ -285,10 +285,10 @@ static void friend_req_sent(uint16_t duration, int err, void *user_data) lpn->adv_duration = duration; if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) { - k_delayed_work_submit(&lpn->timer, FRIEND_REQ_WAIT); + k_work_reschedule(&lpn->timer, FRIEND_REQ_WAIT); lpn_set_state(BT_MESH_LPN_REQ_WAIT); } else { - k_delayed_work_submit(&lpn->timer, + k_work_reschedule(&lpn->timer, duration + FRIEND_REQ_TIMEOUT); lpn_set_state(BT_MESH_LPN_WAIT_OFFER); } @@ -362,11 +362,11 @@ static void req_sent(uint16_t duration, int err, void *user_data) /* We start scanning a bit early to elimitate risk of missing * response data due to HCI and other latencies. */ - k_delayed_work_submit(&lpn->timer, + k_work_reschedule(&lpn->timer, LPN_RECV_DELAY - SCAN_LATENCY); } else { lpn_set_state(BT_MESH_LPN_WAIT_UPDATE); - k_delayed_work_submit(&lpn->timer, + k_work_reschedule(&lpn->timer, LPN_RECV_DELAY + duration + lpn->recv_win); } @@ -459,7 +459,7 @@ int bt_mesh_lpn_set(bool enable) } else { if (IS_ENABLED(CONFIG_BT_MESH_LPN_AUTO) && lpn->state == BT_MESH_LPN_TIMER) { - k_delayed_work_cancel(&lpn->timer); + k_work_cancel_delayable(&lpn->timer); lpn_set_state(BT_MESH_LPN_DISABLED); } else { bt_mesh_lpn_disable(false); @@ -484,7 +484,7 @@ static void friend_response_received(struct bt_mesh_lpn *lpn) int32_t timeout = poll_timeout(lpn); - k_delayed_work_submit(&lpn->timer, K_MSEC(timeout)); + k_work_reschedule(&lpn->timer, K_MSEC(timeout)); } void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx) @@ -493,7 +493,7 @@ void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx) if (lpn->state == BT_MESH_LPN_TIMER) { BT_DBG("Restarting establishment timer"); - k_delayed_work_submit(&lpn->timer, LPN_AUTO_TIMEOUT); + k_work_reschedule(&lpn->timer, LPN_AUTO_TIMEOUT); return; } @@ -754,7 +754,7 @@ static void update_timeout(struct bt_mesh_lpn *lpn) BT_WARN("No response from Friend during ReceiveWindow"); bt_mesh_scan_disable(); lpn_set_state(BT_MESH_LPN_ESTABLISHED); - k_delayed_work_submit(&lpn->timer, POLL_RETRY_TIMEOUT); + k_work_reschedule(&lpn->timer, POLL_RETRY_TIMEOUT); } else { if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) { bt_mesh_scan_disable(); @@ -799,7 +799,7 @@ static void lpn_timeout(struct ble_npl_event *work) break; case BT_MESH_LPN_REQ_WAIT: bt_mesh_scan_enable(); - k_delayed_work_submit(&lpn->timer, + k_work_reschedule(&lpn->timer, lpn->adv_duration + FRIEND_REQ_SCAN); lpn_set_state(BT_MESH_LPN_WAIT_OFFER); break; @@ -811,7 +811,7 @@ static void lpn_timeout(struct ble_npl_event *work) lpn->lpn_counter++; lpn_set_state(BT_MESH_LPN_ENABLED); lpn->sent_req = 0U; - k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT); + k_work_reschedule(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT); break; case BT_MESH_LPN_ESTABLISHED: if (lpn->req_attempts < REQ_ATTEMPTS(lpn)) { @@ -834,7 +834,7 @@ static void lpn_timeout(struct ble_npl_event *work) clear_friendship(false, false); break; case BT_MESH_LPN_RECV_DELAY: - k_delayed_work_submit(&lpn->timer, + k_work_reschedule(&lpn->timer, lpn->adv_duration + SCAN_LATENCY + lpn->recv_win); bt_mesh_scan_enable(); @@ -1067,7 +1067,7 @@ int bt_mesh_lpn_init(void) BT_DBG(""); - k_delayed_work_init(&lpn->timer, lpn_timeout); + k_work_init_delayable(&lpn->timer, lpn_timeout); if (lpn->state == BT_MESH_LPN_ENABLED) { if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) { @@ -1083,7 +1083,7 @@ int bt_mesh_lpn_init(void) if (IS_ENABLED(CONFIG_BT_MESH_LPN_AUTO)) { BT_DBG("Waiting %u ms for messages", LPN_AUTO_TIMEOUT); lpn_set_state(BT_MESH_LPN_TIMER); - k_delayed_work_submit(&lpn->timer, LPN_AUTO_TIMEOUT); + k_work_reschedule(&lpn->timer, LPN_AUTO_TIMEOUT); } } diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c index 2417872a95..a9bdb3154c 100644 --- a/nimble/host/mesh/src/mesh.c +++ b/nimble/host/mesh/src/mesh.c @@ -174,7 +174,7 @@ void bt_mesh_reset(void) memset(bt_mesh.flags, 0, sizeof(bt_mesh.flags)); - k_delayed_work_cancel(&bt_mesh.ivu_timer); + k_work_cancel_delayable(&bt_mesh.ivu_timer); bt_mesh_cfg_reset(); @@ -240,7 +240,7 @@ static void model_suspend(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, { if (mod->pub && mod->pub->update) { mod->pub->count = 0; - k_delayed_work_cancel(&mod->pub->timer); + k_work_cancel_delayable(&mod->pub->timer); } } @@ -281,7 +281,7 @@ static void model_resume(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, int32_t period_ms = bt_mesh_model_pub_period_get(mod); if (period_ms) { - k_delayed_work_submit(&mod->pub->timer, period_ms); + k_work_reschedule(&mod->pub->timer, period_ms); } } } diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index b3e22aad30..4c102f7a8c 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -307,7 +307,7 @@ bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update) bt_mesh.seq = 0; } - k_delayed_work_submit(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT); + k_work_reschedule(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT); /* Notify other modules */ if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { @@ -869,7 +869,7 @@ static void ivu_refresh(struct ble_npl_event *work) store_iv(true); } - k_delayed_work_submit(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT); + k_work_reschedule(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT); return; } @@ -1035,7 +1035,7 @@ void bt_mesh_net_init(void) SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_seq conf"); - k_delayed_work_init(&bt_mesh.ivu_timer, ivu_refresh); + k_work_init_delayable(&bt_mesh.ivu_timer, ivu_refresh); k_work_init(&bt_mesh.local_work, bt_mesh_net_local); net_buf_slist_init(&bt_mesh.local_queue); @@ -1181,6 +1181,6 @@ void bt_mesh_net_clear(void) void bt_mesh_net_settings_commit(void) { if (bt_mesh.ivu_duration < BT_MESH_IVU_MIN_HOURS) { - k_delayed_work_submit(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT); + k_work_reschedule(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT); } } diff --git a/nimble/host/mesh/src/net.h b/nimble/host/mesh/src/net.h index 33b491e4b5..9d8f857610 100644 --- a/nimble/host/mesh/src/net.h +++ b/nimble/host/mesh/src/net.h @@ -74,7 +74,7 @@ struct bt_mesh_friend { uint16_t sub_list[FRIEND_SUB_LIST_SIZE]; - struct k_delayed_work timer; + struct k_work_delayable timer; struct bt_mesh_friend_seg { struct net_buf_slist_t queue; @@ -96,7 +96,7 @@ struct bt_mesh_friend { uint32_t start; /* Clear Procedure start */ uint16_t frnd; /* Previous Friend's address */ uint16_t repeat_sec; /* Repeat timeout in seconds */ - struct k_delayed_work timer; /* Repeat timer */ + struct k_work_delayable timer; /* Repeat timer */ } clear; }; @@ -160,7 +160,7 @@ struct bt_mesh_lpn { uint16_t adv_duration; /* Next LPN related action timer */ - struct k_delayed_work timer; + struct k_work_delayable timer; /* Subscribed groups */ uint16_t groups[LPN_GROUPS]; @@ -221,7 +221,7 @@ struct bt_mesh_net { uint8_t default_ttl; /* Timer to track duration in current IV Update state */ - struct k_delayed_work ivu_timer; + struct k_work_delayable ivu_timer; uint8_t dev_key[16]; }; diff --git a/nimble/host/mesh/src/pb_adv.c b/nimble/host/mesh/src/pb_adv.c index 50b8419e10..f4cafab03f 100644 --- a/nimble/host/mesh/src/pb_adv.c +++ b/nimble/host/mesh/src/pb_adv.c @@ -105,11 +105,11 @@ struct pb_adv { void *cb_data; /* Retransmit timer */ - struct k_delayed_work retransmit; + struct k_work_delayable retransmit; } tx; /* Protocol timeout */ - struct k_delayed_work prot_timer; + struct k_work_delayable prot_timer; }; struct prov_rx { @@ -136,7 +136,7 @@ static void buf_sent(int err, void *user_data) } BT_DBG("submit retransmit"); - k_delayed_work_submit(&link.tx.retransmit, RETRANSMIT_TIMEOUT); + k_work_reschedule(&link.tx.retransmit, RETRANSMIT_TIMEOUT); } static struct bt_mesh_send_cb buf_sent_cb = { @@ -181,7 +181,7 @@ static void prov_clear_tx(void) { BT_DBG(""); - k_delayed_work_cancel(&link.tx.retransmit); + k_work_cancel_delayable(&link.tx.retransmit); free_segments(); } @@ -191,7 +191,7 @@ static void reset_adv_link(void) BT_DBG(""); prov_clear_tx(); - k_delayed_work_cancel(&link.prot_timer); + k_work_cancel_delayable(&link.prot_timer); if (atomic_test_bit(link.flags, ADV_PROVISIONER)) { /* Clear everything except the retransmit and protocol timer @@ -258,7 +258,7 @@ static void prov_failed(uint8_t err) static void prov_msg_recv(void) { - k_delayed_work_submit(&link.prot_timer, PROTOCOL_TIMEOUT); + k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT); if (!bt_mesh_fcs_check(link.rx.buf, link.rx.fcs)) { BT_ERR("Incorrect FCS"); @@ -624,7 +624,7 @@ static int bearer_ctl_send(uint8_t op, const void *data, uint8_t data_len, BT_DBG("op 0x%02x data_len %u", op, data_len); prov_clear_tx(); - k_delayed_work_submit(&link.prot_timer, PROTOCOL_TIMEOUT); + k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT); buf = adv_buf_create(reliable ? RETRANSMITS_RELIABLE : RETRANSMITS_UNRELIABLE); @@ -656,7 +656,7 @@ static int prov_send_adv(struct os_mbuf *msg, uint8_t seg_len, seg_id; prov_clear_tx(); - k_delayed_work_submit(&link.prot_timer, PROTOCOL_TIMEOUT); + k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT); start = adv_buf_create(RETRANSMITS_RELIABLE); if (!start) { @@ -864,8 +864,8 @@ static void prov_link_close(enum prov_bearer_link_status status) void pb_adv_init(void) { - k_delayed_work_init(&link.prot_timer, protocol_timeout); - k_delayed_work_init(&link.tx.retransmit, prov_retransmit); + k_work_init_delayable(&link.prot_timer, protocol_timeout); + k_work_init_delayable(&link.tx.retransmit, prov_retransmit); if (!rx_buf) { rx_buf = NET_BUF_SIMPLE(65); diff --git a/nimble/host/mesh/src/pb_gatt.c b/nimble/host/mesh/src/pb_gatt.c index bce7cf6c09..c358e2e43e 100644 --- a/nimble/host/mesh/src/pb_gatt.c +++ b/nimble/host/mesh/src/pb_gatt.c @@ -27,7 +27,7 @@ struct prov_link { uint8_t fcs; /* Expected FCS value */ struct os_mbuf *buf; } rx; - struct k_delayed_work prot_timer; + struct k_work_delayable prot_timer; }; static struct prov_link link; @@ -36,7 +36,7 @@ static void reset_state(void) { link.conn_handle = BLE_HS_CONN_HANDLE_NONE; - k_delayed_work_cancel(&link.prot_timer); + k_work_cancel_delayable(&link.prot_timer); link.rx.buf = bt_mesh_proxy_get_buf(); } @@ -73,7 +73,7 @@ int bt_mesh_pb_gatt_recv(uint16_t conn_handle, struct os_mbuf *buf) return -EINVAL; } - k_delayed_work_submit(&link.prot_timer, PROTOCOL_TIMEOUT); + k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT); link.cb->recv(&pb_gatt, link.cb_data, buf); @@ -89,7 +89,7 @@ int bt_mesh_pb_gatt_open(uint16_t conn_handle) } link.conn_handle = conn_handle; - k_delayed_work_submit(&link.prot_timer, PROTOCOL_TIMEOUT); + k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT); link.cb->link_opened(&pb_gatt, link.cb_data); @@ -131,7 +131,7 @@ static int buf_send(struct os_mbuf *buf, prov_bearer_send_complete_t cb, return -ENOTCONN; } - k_delayed_work_submit(&link.prot_timer, PROTOCOL_TIMEOUT); + k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT); return bt_mesh_proxy_send(link.conn_handle, BT_MESH_PROXY_PROV, buf); } @@ -143,7 +143,7 @@ static void clear_tx(void) void pb_gatt_init(void) { - k_delayed_work_init(&link.prot_timer, protocol_timeout); + k_work_init_delayable(&link.prot_timer, protocol_timeout); } void pb_gatt_reset(void) diff --git a/nimble/host/mesh/src/proxy.c b/nimble/host/mesh/src/proxy.c index d013c79894..515d86e8c3 100644 --- a/nimble/host/mesh/src/proxy.c +++ b/nimble/host/mesh/src/proxy.c @@ -125,7 +125,7 @@ static struct bt_mesh_proxy_client { #if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) struct ble_npl_callout send_beacons; #endif - struct k_delayed_work sar_timer; + struct k_work_delayable sar_timer; struct os_mbuf *buf; } clients[MYNEWT_VAL(BLE_MAX_CONNECTIONS)] = { [0 ... (MYNEWT_VAL(BLE_MAX_CONNECTIONS) - 1)] = { 0 }, @@ -568,7 +568,7 @@ static int proxy_recv(uint16_t conn_handle, uint16_t attr_handle, return -EINVAL; } - k_delayed_work_submit(&client->sar_timer, PROXY_SAR_TIMEOUT); + k_work_reschedule(&client->sar_timer, PROXY_SAR_TIMEOUT); client->msg_type = PDU_TYPE(data); net_buf_simple_add_mem(client->buf, data + 1, len - 1); break; @@ -584,7 +584,7 @@ static int proxy_recv(uint16_t conn_handle, uint16_t attr_handle, return -EINVAL; } - k_delayed_work_submit(&client->sar_timer, PROXY_SAR_TIMEOUT); + k_work_reschedule(&client->sar_timer, PROXY_SAR_TIMEOUT); net_buf_simple_add_mem(client->buf, data + 1, len - 1); break; @@ -599,7 +599,7 @@ static int proxy_recv(uint16_t conn_handle, uint16_t attr_handle, return -EINVAL; } - k_delayed_work_cancel(&client->sar_timer); + k_work_cancel_delayable(&client->sar_timer); net_buf_simple_add_mem(client->buf, data + 1, len - 1); proxy_complete_pdu(client); break; @@ -661,7 +661,7 @@ static void proxy_disconnected(uint16_t conn_handle, int reason) bt_mesh_pb_gatt_close(conn_handle); } - k_delayed_work_cancel(&client->sar_timer); + k_work_cancel_delayable(&client->sar_timer); client->conn_handle = BLE_HS_CONN_HANDLE_NONE; break; } @@ -1543,8 +1543,8 @@ int bt_mesh_proxy_init(void) clients[i].buf = NET_BUF_SIMPLE(CLIENT_BUF_SIZE); clients[i].conn_handle = BLE_HS_CONN_HANDLE_NONE; - k_delayed_work_init(&clients[i].sar_timer, proxy_sar_timeout); - k_delayed_work_add_arg(&clients[i].sar_timer, &clients[i]); + k_work_init_delayable(&clients[i].sar_timer, proxy_sar_timeout); + k_work_add_arg_delayable(&clients[i].sar_timer, &clients[i]); } resolve_svc_handles(); diff --git a/nimble/host/mesh/src/settings.c b/nimble/host/mesh/src/settings.c index 3d28ac94da..19a9c3f87a 100644 --- a/nimble/host/mesh/src/settings.c +++ b/nimble/host/mesh/src/settings.c @@ -27,7 +27,7 @@ #include "config/config.h" -static struct k_delayed_work pending_store; +static struct k_work_delayable pending_store; static ATOMIC_DEFINE(pending_flags, BT_MESH_SETTINGS_FLAG_COUNT); int settings_name_next(char *name, char **next) @@ -97,7 +97,7 @@ static int mesh_commit(void) void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag) { - int32_t timeout_ms, remaining; + int32_t timeout_ms, remaining_ms; atomic_set_bit(pending_flags, flag); @@ -113,15 +113,18 @@ void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag) timeout_ms = CONFIG_BT_MESH_STORE_TIMEOUT * MSEC_PER_SEC; } - remaining = k_delayed_work_remaining_get(&pending_store); - if ((remaining > 0) && remaining < timeout_ms) { - BT_DBG("Not rescheduling due to existing earlier deadline"); - return; + remaining_ms = k_ticks_to_ms_floor32( + k_work_delayable_remaining_get(&pending_store)); + BT_DBG("Waiting %u ms vs rem %u ms", timeout_ms, remaining_ms); + /* If the new deadline is sooner, override any existing + * deadline; otherwise schedule without changing any existing + * deadline. + */ + if (timeout_ms < remaining_ms) { + k_work_reschedule(&pending_store, K_MSEC(timeout_ms)); + } else { + k_work_schedule(&pending_store, K_MSEC(timeout_ms)); } - - BT_DBG("Waiting %d seconds", timeout_ms / MSEC_PER_SEC); - - k_delayed_work_submit(&pending_store, K_MSEC(timeout_ms)); } static void store_pending(struct ble_npl_event *work) { @@ -201,7 +204,7 @@ void bt_mesh_settings_init(void) SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_settings conf"); - k_delayed_work_init(&pending_store, store_pending); + k_work_init_delayable(&pending_store, store_pending); } #endif /* MYNEWT_VAL(BLE_MESH_SETTINGS) */ diff --git a/nimble/host/mesh/src/transport.c b/nimble/host/mesh/src/transport.c index 0299c98331..18e88d7ce5 100644 --- a/nimble/host/mesh/src/transport.c +++ b/nimble/host/mesh/src/transport.c @@ -107,7 +107,7 @@ static struct seg_tx { friend_cred:1; /* Using Friend credentials */ const struct bt_mesh_send_cb *cb; void *cb_data; - struct k_delayed_work retransmit; /* Retransmit timer */ + struct k_work_delayable retransmit; /* Retransmit timer */ } seg_tx[MYNEWT_VAL(BLE_MESH_TX_SEG_MSG_COUNT)]; static struct seg_rx { @@ -125,7 +125,7 @@ static struct seg_rx { uint8_t ttl; uint32_t block; uint32_t last; - struct k_delayed_work ack; + struct k_work_delayable ack; } seg_rx[CONFIG_BT_MESH_RX_SEG_MSG_COUNT]; @@ -248,7 +248,7 @@ static void seg_tx_unblock_check(struct seg_tx *tx) BT_DBG("Unblocked 0x%04x", (uint16_t)(blocked->seq_auth & TRANS_SEQ_ZERO_MASK)); blocked->blocked = false; - k_delayed_work_submit(&blocked->retransmit, 0); + k_work_reschedule(&blocked->retransmit, 0); } } @@ -256,7 +256,7 @@ static void seg_tx_reset(struct seg_tx *tx) { int i; - k_delayed_work_cancel(&tx->retransmit); + k_work_cancel_delayable(&tx->retransmit); tx->cb = NULL; tx->cb_data = NULL; @@ -317,7 +317,7 @@ static void schedule_retransmit(struct seg_tx *tx) * called this from inside bt_mesh_net_send), we should continue the * retransmit immediately, as we just freed up a tx buffer. */ - k_delayed_work_submit(&tx->retransmit, + k_work_reschedule(&tx->retransmit, tx->seg_o ? 0 : K_MSEC(SEG_RETRANSMIT_TIMEOUT(tx))); } @@ -439,7 +439,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) tx->attempts--; end: if (!tx->seg_pending) { - k_delayed_work_submit(&tx->retransmit, + k_work_reschedule(&tx->retransmit, SEG_RETRANSMIT_TIMEOUT(tx)); } @@ -860,7 +860,7 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, return -EINVAL; } - k_delayed_work_cancel(&tx->retransmit); + k_work_cancel_delayable(&tx->retransmit); while ((bit = find_lsb_set(ack))) { if (tx->seg[bit - 1]) { @@ -1094,7 +1094,7 @@ static void seg_rx_reset(struct seg_rx *rx, bool full_reset) BT_DBG("rx %p", rx); - k_delayed_work_cancel(&rx->ack); + k_work_cancel_delayable(&rx->ack); if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && rx->obo && rx->block != BLOCK_COMPLETE(rx->seg_n)) { @@ -1148,7 +1148,7 @@ static void seg_ack(struct ble_npl_event *work) rx->block, rx->obo); timeout = ack_timeout(rx); - k_delayed_work_submit(&rx->ack, K_MSEC(timeout)); + k_work_reschedule(&rx->ack, K_MSEC(timeout)); } static inline bool sdu_len_is_ok(bool ctl, uint8_t seg_n) @@ -1429,11 +1429,11 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx, /* Reset the Incomplete Timer */ rx->last = k_uptime_get_32(); - if (!k_delayed_work_remaining_get(&rx->ack) && + if (!k_work_delayable_remaining_get(&rx->ack) && !bt_mesh_lpn_established()) { int32_t timeout = ack_timeout(rx); - k_delayed_work_submit(&rx->ack, K_MSEC(timeout)); + k_work_reschedule(&rx->ack, K_MSEC(timeout)); } /* Allocated segment here */ @@ -1464,7 +1464,7 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx, *pdu_type = BT_MESH_FRIEND_PDU_COMPLETE; - k_delayed_work_cancel(&rx->ack); + k_work_cancel_delayable(&rx->ack); send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr, net_rx->ctx.send_ttl, seq_auth, rx->block, rx->obo); @@ -1641,16 +1641,16 @@ void bt_mesh_trans_init(void) } for (i = 0; i < ARRAY_SIZE(seg_tx); i++) { - k_delayed_work_init(&seg_tx[i].retransmit, seg_retransmit); - k_delayed_work_add_arg(&seg_tx[i].retransmit, &seg_tx[i]); + k_work_init_delayable(&seg_tx[i].retransmit, seg_retransmit); + k_work_add_arg_delayable(&seg_tx[i].retransmit, &seg_tx[i]); } /* XXX Probably we need mempool for that. * For now we increase MSYS_1_BLOCK_COUNT */ for (i = 0; i < ARRAY_SIZE(seg_rx); i++) { - k_delayed_work_init(&seg_rx[i].ack, seg_ack); - k_delayed_work_add_arg(&seg_rx[i].ack, &seg_rx[i]); + k_work_init_delayable(&seg_rx[i].ack, seg_ack); + k_work_add_arg_delayable(&seg_rx[i].ack, &seg_rx[i]); } } @@ -1856,12 +1856,6 @@ void bt_mesh_va_pending_store(void) } } } -#else -void bt_mesh_va_pending_store(void) -{ - /* Do nothing. */ -} -#endif /* CONFIG_BT_MESH_LABEL_COUNT > 0 */ static struct conf_handler bt_mesh_va_conf_handler = { .ch_name = "bt_mesh", @@ -1880,4 +1874,10 @@ void bt_mesh_va_init(void) SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_hb_pub conf"); } -#endif \ No newline at end of file + +#else +void bt_mesh_va_pending_store(void) +{ + /* Do nothing. */ +} +#endif /* CONFIG_BT_MESH_LABEL_COUNT > 0 */ From 840e92249ad5b0a871a180fe8d325257d7b0f40d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 6 Oct 2021 15:40:04 +0200 Subject: [PATCH 0076/1333] host/mesh: Perform replay check on SeqAuth To prevent the transport layer from accepting duplicate or out of order segmented messages, add an RPL-like check for the SeqAuth of the segmented messages when their context is allocated. This prevents duplicate receives of the same segmented messages in the case where a single source address sends two segmented messages in parallel (to two different addresses): Previously, when receiving two segmented messages, the first message would go through to the access layer, then the second. Then, if the transport layer received any repeated segments for the first message, it would fail to identify the SeqAuth as old, as all its segments were of new sequence numbers, and the "already complete SDU" check would only look at the second message. Thus, the segmented message got processed again and passed to the access layer, even though it was a duplicate. To solve this, we need a mechanism like RPL, but only for the segmented messages' SeqAuth. We cannot re-use the actual RPL mechanism, as it can't support the scenario provoked by the "blocking tx" mechanism in transport. This mechanism allocates the SeqAuth when the message is first passed to the transport layer. The ongoing message that caused the block would keep sending segments with higher sequence numbers than the blocked message got, which will cause the blocked message to fail the RPL check. This patch adds a parallel SeqAuth mechanism to the RPL module, which only deals with the SeqAuth of the segmented messages. This list gets checked when the segmented message is first allocated, in the same manner as the general RPL mechanism. The storage gets hooked into the RPL mechanism, by adding a separate seg field to each RPL entry. This is port of 4fbd0cb0ca6bead0354f54808da3224302d98c28 --- nimble/host/mesh/src/rpl.c | 29 ++++++++++++++++++----------- nimble/host/mesh/src/rpl.h | 16 ++++++++++------ nimble/host/mesh/src/transport.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/nimble/host/mesh/src/rpl.c b/nimble/host/mesh/src/rpl.c index 830ab1b01e..3c4045ca5b 100644 --- a/nimble/host/mesh/src/rpl.c +++ b/nimble/host/mesh/src/rpl.c @@ -25,12 +25,16 @@ struct rpl_val { }; static struct bt_mesh_rpl replay_list[MYNEWT_VAL(BLE_MESH_CRPL)]; +static ATOMIC_DEFINE(store, MYNEWT_VAL(BLE_MESH_CRPL)); + +static inline int rpl_idx(const struct bt_mesh_rpl *rpl) +{ + return rpl - &replay_list[0]; +} static void schedule_rpl_store(struct bt_mesh_rpl *entry) { -#ifdef CONFIG_BT_SETTINGS - entry->store = true; -#endif + atomic_set_bit(store, rpl_idx(entry)); bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); } @@ -42,6 +46,13 @@ static void schedule_rpl_clear(void) void bt_mesh_rpl_update(struct bt_mesh_rpl *rpl, struct bt_mesh_net_rx *rx) { + /* If this is the first message on the new IV index, we should reset it + * to zero to avoid invalid combinations of IV index and seg. + */ + if (rpl->old_iv && !rx->old_iv) { + rpl->seg = 0; + } + rpl->src = rx->ctx.addr; rpl->seq = rx->seq; rpl->old_iv = rx->old_iv; @@ -276,20 +287,16 @@ static void clear_rpl(struct bt_mesh_rpl *rpl) } (void)memset(rpl, 0, sizeof(*rpl)); + atomic_clear_bit(store, rpl_idx(rpl)); } static void store_pending_rpl(struct bt_mesh_rpl *rpl) { BT_DBG(""); -#ifdef CONFIG_BT_SETTINGS - if (!rpl->store) { - return; + if (atomic_test_and_clear_bit(store, rpl_idx(rpl))) { + store_rpl(rpl); } - - rpl->store = false; -#endif - store_rpl(rpl); } void bt_mesh_rpl_pending_store(void) @@ -311,7 +318,7 @@ static struct conf_handler bt_mesh_rpl_conf_handler = { .ch_set = rpl_set, .ch_commit = NULL, .ch_export = NULL, - }; +}; void bt_mesh_rpl_init(void) { diff --git a/nimble/host/mesh/src/rpl.h b/nimble/host/mesh/src/rpl.h index d47484a329..9a1d49ff07 100644 --- a/nimble/host/mesh/src/rpl.h +++ b/nimble/host/mesh/src/rpl.h @@ -8,12 +8,16 @@ */ struct bt_mesh_rpl { - uint16_t src; - bool old_iv; -#if defined(CONFIG_BT_SETTINGS) - bool store; -#endif - uint32_t seq; + uint64_t src:15, + old_iv:1, + seq:24, + /** Sequence authentication value for the previous segmented + * message received from this address. + * + * This value is used to manage the parallel RPL of the + * SeqAuth values in transport. + */ + seg:24; }; typedef void (*bt_mesh_rpl_func_t)(struct bt_mesh_rpl *rpl, diff --git a/nimble/host/mesh/src/transport.c b/nimble/host/mesh/src/transport.c index 18e88d7ce5..643606349c 100644 --- a/nimble/host/mesh/src/transport.c +++ b/nimble/host/mesh/src/transport.c @@ -1263,6 +1263,7 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx, struct seg_rx *rx; uint8_t *hdr = buf->om_data; uint16_t seq_zero; + uint32_t auth_seqnum; uint8_t seg_n; uint8_t seg_o; int err; @@ -1314,6 +1315,7 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx, ((((net_rx->seq & BIT_MASK(14)) - seq_zero)) & BIT_MASK(13)))); + auth_seqnum = *seq_auth & BIT_MASK(24); *seg_count = seg_n + 1; /* Look for old RX sessions */ @@ -1382,6 +1384,28 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx, return -ENOBUFS; } + /* Keep track of the received SeqAuth values received from this address + * and discard segmented messages that are not newer, as described in + * the Bluetooth Mesh specification section 3.5.3.4. + * + * The logic on the first segmented receive is a bit special, since the + * initial value of rpl->seg is 0, which would normally fail the + * comparison check with auth_seqnum: + * - If this is the first time we receive from this source, rpl->src + * will be 0, and we can skip this check. + * - If this is the first time we receive from this source on the new IV + * index, rpl->old_iv will be set, and the check is also skipped. + * - If this is the first segmented message on the new IV index, but we + * have received an unsegmented message already, the unsegmented + * message will have reset rpl->seg to 0, and this message's SeqAuth + * cannot be zero. + */ + if (rpl && rpl->src && auth_seqnum <= rpl->seg && + (!rpl->old_iv || net_rx->old_iv)) { + BT_WARN("Ignoring old SeqAuth 0x%06x", auth_seqnum); + return -EALREADY; + } + /* Look for free slot for a new RX session */ rx = seg_rx_alloc(net_rx, hdr, seq_auth, seg_n); if (!rx) { @@ -1460,6 +1484,12 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx, if (rpl) { bt_mesh_rpl_update(rpl, net_rx); + /* Update the seg, unless it has already been surpassed: + * This needs to happen after rpl_update to ensure that the IV + * update reset logic inside rpl_update doesn't overwrite the + * change. + */ + rpl->seg = MAX(rpl->seg, auth_seqnum); } *pdu_type = BT_MESH_FRIEND_PDU_COMPLETE; From ffbd3587c784f189801c5cad7e528b0def1f1a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 7 Oct 2021 07:37:11 +0200 Subject: [PATCH 0077/1333] host/mesh: Fix restoring fast period divisor from settings The Health Fast Period Divisor is stored within the model publish parameters on the access layer. The opposite part for divisor restoring has been missed. This is port of 73e1c6a77d71f8b51746946f78f0b3525101e1c0 --- nimble/host/mesh/src/access.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index 5c12792ecb..9459da63e5 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -960,6 +960,7 @@ static int mod_set_pub(struct bt_mesh_model *mod, char *val) mod->pub->ttl = pub.ttl; mod->pub->period = pub.period; mod->pub->retransmit = pub.retransmit; + mod->pub->period_div = pub.period_div; mod->pub->count = 0; BT_DBG("Restored model publication, dst 0x%04x app_idx 0x%03x", From 21f1b076af4fcdc10b6d6439c91284c01d1d24e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 7 Oct 2021 07:40:27 +0200 Subject: [PATCH 0078/1333] host/mesh: Send Link Close message when closing link Instead of silently closing the link we should send a Link Close message three times before resetting provisioning state. From Mesh Profile Specification v1.0.1.: ``` 5.3.1.4.3 Link Close message The Link Close message is used to close a link. ``` ``` 5.3.2 Link Establishment procedure The device shall start the link timer, set to 60 seconds, when the link is open. When the link timer expires, then the device shall close the link. ``` ``` 5.3.3 Generic Provisioning behavior If the sender does not receive a Transaction Acknowledgment message within 30 seconds after sending the first message in a transaction, the sender shall cancel the transaction, cancel the provisioning process and close the link. ``` From Mesh Profile Test Specification p6: ``` MESH/PVNR/PBADV/BV-01-C Test Procedure: [...] 6. The IUT is induced to send a Link Close message with the Reason field set to 0x02 to terminate the link. The message is sent at least three times to ensure the message is received by the Lower Tester. ``` This is port of 497d9df96acde1d28f7cd83c786e496e8ea0db67 --- nimble/host/mesh/src/pb_adv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/pb_adv.c b/nimble/host/mesh/src/pb_adv.c index f4cafab03f..1fa4c8e996 100644 --- a/nimble/host/mesh/src/pb_adv.c +++ b/nimble/host/mesh/src/pb_adv.c @@ -589,7 +589,7 @@ static void prov_retransmit(struct ble_npl_event *work) close_link(PROV_BEARER_LINK_STATUS_SUCCESS); } else { BT_WARN("Giving up transaction"); - close_link(PROV_BEARER_LINK_STATUS_TIMEOUT); + prov_link_close(PROV_BEARER_LINK_STATUS_TIMEOUT); } return; From b5e2a3a300da187e1bf3a10a3dbb4cf134a96e71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 7 Oct 2021 08:03:10 +0200 Subject: [PATCH 0079/1333] host/mesh: Rename bt_mesh_cfg_comp_data_get's status param to rsp The first byte of the composition data status message is the returned page index, not the status of the request. This is now reflected in the API. This is port of 9259b199bba0ae982632c36069a472b197627521 --- nimble/host/mesh/include/mesh/cfg_cli.h | 2 +- nimble/host/mesh/src/cfg_cli.c | 10 ++++++---- nimble/host/mesh/src/shell.c | 11 +++++------ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/nimble/host/mesh/include/mesh/cfg_cli.h b/nimble/host/mesh/include/mesh/cfg_cli.h index 368bdfc344..ea1b7e3213 100644 --- a/nimble/host/mesh/include/mesh/cfg_cli.h +++ b/nimble/host/mesh/include/mesh/cfg_cli.h @@ -41,7 +41,7 @@ extern const struct bt_mesh_model_cb bt_mesh_cfg_cli_cb; int bt_mesh_cfg_node_reset(uint16_t net_idx, uint16_t addr, bool *status); int bt_mesh_cfg_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, - uint8_t *status, struct os_mbuf *comp); + uint8_t *rsp, struct os_mbuf *comp); int bt_mesh_cfg_beacon_get(uint16_t net_idx, uint16_t addr, uint8_t *status); diff --git a/nimble/host/mesh/src/cfg_cli.c b/nimble/host/mesh/src/cfg_cli.c index 6806818d8a..ab1f9ec31f 100644 --- a/nimble/host/mesh/src/cfg_cli.c +++ b/nimble/host/mesh/src/cfg_cli.c @@ -25,7 +25,7 @@ #define DUMMY_2_BYTE_OP BT_MESH_MODEL_OP_2(0xff, 0xff) struct comp_data { - uint8_t *status; + uint8_t *page; struct os_mbuf *comp; }; @@ -56,7 +56,9 @@ static void comp_data_status(struct bt_mesh_model *model, param = cli->op_param; - *(param->status) = net_buf_simple_pull_u8(buf); + if (param->page) { + *(param->page) = net_buf_simple_pull_u8(buf); + } to_copy = min(net_buf_simple_tailroom(param->comp), buf->om_len); net_buf_simple_add_mem(param->comp, buf->om_data, to_copy); @@ -807,7 +809,7 @@ static int cli_wait(void) } int bt_mesh_cfg_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, - uint8_t *status, struct os_mbuf *comp) + uint8_t *rsp, struct os_mbuf *comp) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_DEV_COMP_DATA_GET, 1); struct bt_mesh_msg_ctx ctx = { @@ -817,7 +819,7 @@ int bt_mesh_cfg_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, .send_ttl = BT_MESH_TTL_DEFAULT, }; struct comp_data param = { - .status = status, + .page = rsp, .comp = comp, }; int err; diff --git a/nimble/host/mesh/src/shell.c b/nimble/host/mesh/src/shell.c index 99c4f95b2c..4ff2c7edae 100644 --- a/nimble/host/mesh/src/shell.c +++ b/nimble/host/mesh/src/shell.c @@ -998,7 +998,7 @@ struct shell_cmd_help cmd_timeout_help = { static int cmd_get_comp(int argc, char *argv[]) { struct os_mbuf *comp = NET_BUF_SIMPLE(BT_MESH_RX_SDU_MAX); - uint8_t status, page = 0x00; + uint8_t page = 0x00; int err = 0; if (argc > 1) { @@ -1007,16 +1007,15 @@ static int cmd_get_comp(int argc, char *argv[]) net_buf_simple_init(comp, 0); err = bt_mesh_cfg_comp_data_get(net.net_idx, net.dst, page, - &status, comp); + &page, comp); if (err) { printk("Getting composition failed (err %d)\n", err); goto done; } - if (status != 0x00) { - printk("Got non-success status 0x%02x\n", status); - goto done; - } + if (page != 0x00) { + shell_print(shell, "Got page 0x%02x. No parser available.", + page); printk("Got Composition Data for 0x%04x:\n", net.dst); printk("\tCID 0x%04x\n", net_buf_simple_pull_le16(comp)); From 5b4fd3021be60c400b0d233f29c8fcdf8f536b17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 7 Oct 2021 08:40:04 +0200 Subject: [PATCH 0080/1333] host/mesh: Composition data page 0 traversal Adds a parsing mechanism for Composition data page 0 in the Config Client API, and uses it in the shell module to parse the incoming composition data. This is port of b84fee5190cd72e9d31fa820aaa5d8684ad4a11c --- nimble/host/mesh/include/mesh/access.h | 13 +++-- nimble/host/mesh/include/mesh/cfg_cli.h | 36 +++++++++++++ nimble/host/mesh/include/mesh/glue.h | 4 ++ nimble/host/mesh/src/cfg_cli.c | 64 ++++++++++++++++++++++ nimble/host/mesh/src/shell.c | 70 +++++++++++++------------ 5 files changed, 149 insertions(+), 38 deletions(-) diff --git a/nimble/host/mesh/include/mesh/access.h b/nimble/host/mesh/include/mesh/access.h index f12ec85b59..4892e43402 100644 --- a/nimble/host/mesh/include/mesh/access.h +++ b/nimble/host/mesh/include/mesh/access.h @@ -495,14 +495,19 @@ struct bt_mesh_model_cb { void (*const reset)(struct bt_mesh_model *model); }; +/** Vendor model ID */ +struct bt_mesh_mod_id_vnd { + /** Vendor's company ID */ + uint16_t company; + /** Model ID */ + uint16_t id; +}; + /** Abstraction that describes a Mesh Model instance */ struct bt_mesh_model { union { const uint16_t id; - struct { - uint16_t company; - uint16_t id; - } vnd; + const struct bt_mesh_mod_id_vnd vnd; }; /* Internal information, mainly for persistent storage */ diff --git a/nimble/host/mesh/include/mesh/cfg_cli.h b/nimble/host/mesh/include/mesh/cfg_cli.h index ea1b7e3213..745e6b27de 100644 --- a/nimble/host/mesh/include/mesh/cfg_cli.h +++ b/nimble/host/mesh/include/mesh/cfg_cli.h @@ -269,6 +269,42 @@ int bt_mesh_cfg_hb_pub_get(uint16_t net_idx, uint16_t addr, int32_t bt_mesh_cfg_cli_timeout_get(void); void bt_mesh_cfg_cli_timeout_set(int32_t timeout); +struct bt_mesh_comp_p0 { + /** Company ID */ + uint16_t cid; + /** Product ID */ + uint16_t pid; + /** Version ID */ + uint16_t vid; + /** Replay protection list size */ + uint16_t crpl; + /** Supported features, see @ref BT_MESH_FEAT_SUPPORTED. */ + uint16_t feat; + + struct os_mbuf *_buf; +}; + +struct bt_mesh_comp_p0_elem { + /** Element location */ + uint16_t loc; + /** The number of SIG models in this element */ + size_t nsig; + /** The number of vendor models in this element */ + size_t nvnd; + + uint8_t *_buf; +}; + +int bt_mesh_comp_p0_get(struct bt_mesh_comp_p0 *comp, + struct os_mbuf *buf); + +struct bt_mesh_comp_p0_elem *bt_mesh_comp_p0_elem_pull(const struct bt_mesh_comp_p0 *comp, + struct bt_mesh_comp_p0_elem *elem); + +uint16_t bt_mesh_comp_p0_elem_mod(struct bt_mesh_comp_p0_elem *elem, int idx); + +struct bt_mesh_mod_id_vnd bt_mesh_comp_p0_elem_mod_vnd(struct bt_mesh_comp_p0_elem *elem, int idx); + #ifdef __cplusplus } #endif diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index 34a32aed9c..760088b1c2 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -144,6 +144,10 @@ extern "C" { #define ASSERT_NOT_CHAIN(om) (void)(om) #endif +#define CHECKIF(expr) \ + __ASSERT_NO_MSG(!(expr)); \ + if (0) + #define __packed __attribute__((__packed__)) #define MSEC_PER_SEC (1000) diff --git a/nimble/host/mesh/src/cfg_cli.c b/nimble/host/mesh/src/cfg_cli.c index ab1f9ec31f..82e6a82a59 100644 --- a/nimble/host/mesh/src/cfg_cli.c +++ b/nimble/host/mesh/src/cfg_cli.c @@ -2145,4 +2145,68 @@ void bt_mesh_cfg_cli_timeout_set(int32_t timeout) msg_timeout = timeout; } +int bt_mesh_comp_p0_get(struct bt_mesh_comp_p0 *page, + struct os_mbuf *buf) +{ + if (buf->om_len < 10) { + return -EINVAL; + } + + page->cid = net_buf_simple_pull_le16(buf); + page->pid = net_buf_simple_pull_le16(buf); + page->vid = net_buf_simple_pull_le16(buf); + page->crpl = net_buf_simple_pull_le16(buf); + page->feat = net_buf_simple_pull_le16(buf); + page->_buf = buf; + + return 0; +} + +struct bt_mesh_comp_p0_elem *bt_mesh_comp_p0_elem_pull(const struct bt_mesh_comp_p0 *page, + struct bt_mesh_comp_p0_elem *elem) +{ + size_t modlist_size; + + if (page->_buf->om_len < 4) { + return NULL; + } + + elem->loc = net_buf_simple_pull_le16(page->_buf); + elem->nsig = net_buf_simple_pull_u8(page->_buf); + elem->nvnd = net_buf_simple_pull_u8(page->_buf); + + modlist_size = elem->nsig * 2 + elem->nvnd * 4; + + if (page->_buf->om_len < modlist_size) { + return NULL; + } + + elem->_buf = net_buf_simple_pull_mem(page->_buf, modlist_size); + + return elem; +} + +uint16_t bt_mesh_comp_p0_elem_mod(struct bt_mesh_comp_p0_elem *elem, int idx) + { + CHECKIF(idx >= elem->nsig) { + return 0xffff; + } + + return sys_get_le16(&elem->_buf[idx * 2]); +} + +struct bt_mesh_mod_id_vnd bt_mesh_comp_p0_elem_mod_vnd(struct bt_mesh_comp_p0_elem *elem, int idx) + { + CHECKIF(idx >= elem->nvnd) { + return (struct bt_mesh_mod_id_vnd){ 0xffff, 0xffff }; + } + + size_t offset = elem->nsig * 2 + idx * 4; + struct bt_mesh_mod_id_vnd mod = { + .company = sys_get_le16(&elem->_buf[offset]), + .id = sys_get_le16(&elem->_buf[offset + 2]), + }; + + return mod; +} #endif diff --git a/nimble/host/mesh/src/shell.c b/nimble/host/mesh/src/shell.c index 4ff2c7edae..61f1db69e0 100644 --- a/nimble/host/mesh/src/shell.c +++ b/nimble/host/mesh/src/shell.c @@ -997,7 +997,9 @@ struct shell_cmd_help cmd_timeout_help = { static int cmd_get_comp(int argc, char *argv[]) { - struct os_mbuf *comp = NET_BUF_SIMPLE(BT_MESH_RX_SDU_MAX); + struct os_mbuf *buf = NET_BUF_SIMPLE(BT_MESH_RX_SDU_MAX); + struct bt_mesh_comp_p0_elem elem; + struct bt_mesh_comp_p0 comp; uint8_t page = 0x00; int err = 0; @@ -1005,69 +1007,69 @@ static int cmd_get_comp(int argc, char *argv[]) page = strtol(argv[1], NULL, 0); } - net_buf_simple_init(comp, 0); - err = bt_mesh_cfg_comp_data_get(net.net_idx, net.dst, page, - &page, comp); + net_buf_simple_init(buf, 0); + err = bt_mesh_cfg_comp_data_get(net.net_idx, net.dst, page, &page, + buf); if (err) { printk("Getting composition failed (err %d)\n", err); goto done; } if (page != 0x00) { - shell_print(shell, "Got page 0x%02x. No parser available.", + printk("Got page 0x%02x. No parser available.", page); + goto done; + } - printk("Got Composition Data for 0x%04x:\n", net.dst); - printk("\tCID 0x%04x\n", net_buf_simple_pull_le16(comp)); - printk("\tPID 0x%04x\n", net_buf_simple_pull_le16(comp)); - printk("\tVID 0x%04x\n", net_buf_simple_pull_le16(comp)); - printk("\tCRPL 0x%04x\n", net_buf_simple_pull_le16(comp)); - printk("\tFeatures 0x%04x\n", net_buf_simple_pull_le16(comp)); - - while (comp->om_len > 4) { - uint8_t sig, vnd; - uint16_t loc; - int i; - - loc = net_buf_simple_pull_le16(comp); - sig = net_buf_simple_pull_u8(comp); - vnd = net_buf_simple_pull_u8(comp); + err = bt_mesh_comp_p0_get(&comp, buf); + if (err) { + printk("Getting composition failed (err %d)\n", err); + goto done; + } - printk("\n\tElement @ 0x%04x:\n", loc); + printk("Got Composition Data for 0x%04x:", net.dst); + printk("\tCID 0x%04x", comp.cid); + printk("\tPID 0x%04x", comp.pid); + printk("\tVID 0x%04x", comp.vid); + printk("\tCRPL 0x%04x", comp.crpl); + printk("\tFeatures 0x%04x", comp.feat); - if (comp->om_len < ((sig * 2) + (vnd * 4))) { - printk("\t\t...truncated data!\n"); - break; - } + while (bt_mesh_comp_p0_elem_pull(&comp, &elem)) { + int i; - if (sig) { + printk("\tElement @ 0x%04x:", elem.loc); + if (elem.nsig) { printk("\t\tSIG Models:\n"); } else { printk("\t\tNo SIG Models\n"); } - for (i = 0; i < sig; i++) { - uint16_t mod_id = net_buf_simple_pull_le16(comp); + for (i = 0; i < elem.nsig; i++) { + uint16_t mod_id = bt_mesh_comp_p0_elem_mod(&elem, i); printk("\t\t\t0x%04x\n", mod_id); } - if (vnd) { + if (elem.nvnd) { printk("\t\tVendor Models:\n"); } else { printk("\t\tNo Vendor Models\n"); } - for (i = 0; i < vnd; i++) { - uint16_t cid = net_buf_simple_pull_le16(comp); - uint16_t mod_id = net_buf_simple_pull_le16(comp); + for (i = 0; i < elem.nvnd; i++) { + struct bt_mesh_mod_id_vnd mod = + bt_mesh_comp_p0_elem_mod_vnd(&elem, i); - printk("\t\t\tCompany 0x%04x: 0x%04x\n", cid, mod_id); + printk("\t\t\tCompany 0x%04x: 0x%04x", + mod.company, mod.id); } } + if (buf->om_len) { + printk("\t\t...truncated data!"); + } done: - os_mbuf_free_chain(comp); + os_mbuf_free_chain(buf); return err; } From 8fa05b8f2d83e82e9170ebf7bb5eaeb48b1d14f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 7 Oct 2021 13:22:56 +0200 Subject: [PATCH 0081/1333] host/mesh: Introduce acknowledged message API The implementation of blocking calls is common for all the client models. This change reduces the code duplication by introducing new API that helps to manage acknowledged messages. This is port of a94c7e3a23fc1225aec9f13c1e37cc2853f70c82 and c5e4011e29b878fc1771876fc30db0ddcc084829 --- nimble/host/mesh/include/mesh/access.h | 80 +----- nimble/host/mesh/include/mesh/cfg_cli.h | 6 +- nimble/host/mesh/include/mesh/glue.h | 4 + nimble/host/mesh/include/mesh/health_cli.h | 4 +- nimble/host/mesh/include/mesh/mesh.h | 1 + nimble/host/mesh/include/mesh/msg.h | 225 ++++++++++++++++ nimble/host/mesh/src/access.c | 25 -- nimble/host/mesh/src/cfg_cli.c | 300 +++++++++------------ nimble/host/mesh/src/health_cli.c | 106 +++----- nimble/host/mesh/src/msg.c | 83 ++++++ 10 files changed, 482 insertions(+), 352 deletions(-) create mode 100644 nimble/host/mesh/include/mesh/msg.h create mode 100644 nimble/host/mesh/src/msg.c diff --git a/nimble/host/mesh/include/mesh/access.h b/nimble/host/mesh/include/mesh/access.h index 4892e43402..0efee414f8 100644 --- a/nimble/host/mesh/include/mesh/access.h +++ b/nimble/host/mesh/include/mesh/access.h @@ -10,6 +10,8 @@ #ifndef __BT_MESH_ACCESS_H #define __BT_MESH_ACCESS_H +#include "msg.h" + /** * @brief Bluetooth Mesh Access Layer * @defgroup bt_mesh_access Bluetooth Mesh Access Layer @@ -138,33 +140,6 @@ struct bt_mesh_elem { #define BT_MESH_MODEL_ID_LIGHT_LC_SETUPSRV 0x1310 #define BT_MESH_MODEL_ID_LIGHT_LC_CLI 0x1311 -/** Message sending context. */ -struct bt_mesh_msg_ctx { - /** NetKey Index of the subnet to send the message on. */ - uint16_t net_idx; - - /** AppKey Index to encrypt the message with. */ - uint16_t app_idx; - - /** Remote address. */ - uint16_t addr; - - /** Destination address of a received message. Not used for sending. */ - uint16_t recv_dst; - - /** RSSI of received packet. Not used for sending. */ - int8_t recv_rssi; - - /** Received TTL value. Not used for sending. */ - uint8_t recv_ttl; - - /** Force sending reliably by using segment acknowledgement */ - bool send_rel; - - /** TTL, or BT_MESH_TTL_DEFAULT for default TTL. */ - uint8_t send_ttl; -}; - struct bt_mesh_model_op { /* OpCode encoded using the BT_MESH_MODEL_OP_* macros */ const uint32_t opcode; @@ -189,55 +164,6 @@ struct bt_mesh_model_op { /** Helper to define an empty model array */ #define BT_MESH_MODEL_NONE ((struct bt_mesh_model []){}) -/** Length of a short Mesh MIC. */ -#define BT_MESH_MIC_SHORT 4 -/** Length of a long Mesh MIC. */ -#define BT_MESH_MIC_LONG 8 - -/** @def BT_MESH_MODEL_OP_LEN - * - * @brief Helper to determine the length of an opcode. - * - * @param _op Opcode. - */ -#define BT_MESH_MODEL_OP_LEN(_op) ((_op) <= 0xff ? 1 : (_op) <= 0xffff ? 2 : 3) - -/** @def BT_MESH_MODEL_BUF_LEN - * - * @brief Helper for model message buffer length. - * - * Returns the length of a Mesh model message buffer, including the opcode - * length and a short MIC. - * - * @param _op Opcode of the message. - * @param _payload_len Length of the model payload. - */ -#define BT_MESH_MODEL_BUF_LEN(_op, _payload_len) \ - (BT_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BT_MESH_MIC_SHORT) - -/** @def BT_MESH_MODEL_BUF_LEN_LONG_MIC - * - * @brief Helper for model message buffer length. - * - * Returns the length of a Mesh model message buffer, including the opcode - * length and a long MIC. - * - * @param _op Opcode of the message. - * @param _payload_len Length of the model payload. - */ -#define BT_MESH_MODEL_BUF_LEN_LONG_MIC(_op, _payload_len) \ - (BT_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BT_MESH_MIC_LONG) - -/** @def BT_MESH_MODEL_BUF_DEFINE - * - * @brief Define a Mesh model message buffer using @ref NET_BUF_SIMPLE. - * - * @param _op Opcode of the message. - * @param _payload_len Length of the model message payload. - */ -#define BT_MESH_MODEL_BUF(_op, _payload_len) \ - NET_BUF_SIMPLE(BT_MESH_MODEL_BUF_LEN(_op, (_payload_len))) - /** @def BT_MESH_MODEL_CB * * @brief Composition data SIG model entry with callback functions. @@ -544,8 +470,6 @@ struct bt_mesh_send_cb { void (*end)(int err, void *cb_data); }; -void bt_mesh_model_msg_init(struct os_mbuf *msg, uint32_t opcode); - /** Special TTL value to request using configured default TTL */ #define BT_MESH_TTL_DEFAULT 0xff diff --git a/nimble/host/mesh/include/mesh/cfg_cli.h b/nimble/host/mesh/include/mesh/cfg_cli.h index 745e6b27de..c117066d27 100644 --- a/nimble/host/mesh/include/mesh/cfg_cli.h +++ b/nimble/host/mesh/include/mesh/cfg_cli.h @@ -24,11 +24,7 @@ extern "C" { /** Mesh Configuration Client Model Context */ struct bt_mesh_cfg_cli { struct bt_mesh_model *model; - - struct k_sem op_sync; - uint32_t op_pending; - void *op_param; - uint16_t op_addr; + struct bt_mesh_msg_ack_ctx ack_ctx; }; extern const struct bt_mesh_model_op bt_mesh_cfg_cli_op[]; diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index 760088b1c2..9dfd051096 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -478,6 +478,10 @@ static inline void k_sem_give(struct k_sem *sem) ble_npl_sem_release(sem); } +static inline void k_sem_reset(struct k_sem *sem) +{ + ble_npl_sem_init(sem, 0); +} /* Helpers to access the storage array, since we don't have access to its * type at this point anymore. */ diff --git a/nimble/host/mesh/include/mesh/health_cli.h b/nimble/host/mesh/include/mesh/health_cli.h index e9efe4b1f9..cb14ee6bcd 100644 --- a/nimble/host/mesh/include/mesh/health_cli.h +++ b/nimble/host/mesh/include/mesh/health_cli.h @@ -29,9 +29,7 @@ struct bt_mesh_health_cli { uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count); - struct k_sem op_sync; - uint32_t op_pending; - void *op_param; + struct bt_mesh_msg_ack_ctx ack_ctx; }; extern const struct bt_mesh_model_op bt_mesh_health_cli_op[]; diff --git a/nimble/host/mesh/include/mesh/mesh.h b/nimble/host/mesh/include/mesh/mesh.h index 83390ec4ce..c644d0bb0b 100644 --- a/nimble/host/mesh/include/mesh/mesh.h +++ b/nimble/host/mesh/include/mesh/mesh.h @@ -15,6 +15,7 @@ #include "os/os_mbuf.h" #include "glue.h" +#include "msg.h" #include "access.h" #include "main.h" #include "cfg.h" diff --git a/nimble/host/mesh/include/mesh/msg.h b/nimble/host/mesh/include/mesh/msg.h new file mode 100644 index 0000000000..0cc00ff35b --- /dev/null +++ b/nimble/host/mesh/include/mesh/msg.h @@ -0,0 +1,225 @@ +/** @file + * @brief Bluetooth Mesh Message APIs. + */ + +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_MSG_H_ +#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_MSG_H_ + +/** + * @brief Bluetooth Mesh Message API + * @defgroup bt_mesh_msg Bluetooth Mesh Message API + * @ingroup bt_mesh + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Length of a short Mesh MIC. */ +#define BT_MESH_MIC_SHORT 4 +/** Length of a long Mesh MIC. */ +#define BT_MESH_MIC_LONG 8 + +/** @def BT_MESH_MODEL_OP_LEN + * + * @brief Helper to determine the length of an opcode. + * + * @param _op Opcode. + */ +#define BT_MESH_MODEL_OP_LEN(_op) ((_op) <= 0xff ? 1 : (_op) <= 0xffff ? 2 : 3) + + +/** @def BT_MESH_MODEL_BUF_LEN + * + * @brief Helper for model message buffer length. + * + * Returns the length of a Mesh model message buffer, including the opcode + * length and a short MIC. + * + * @param _op Opcode of the message. + * @param _payload_len Length of the model payload. + */ +#define BT_MESH_MODEL_BUF_LEN(_op, _payload_len) \ + (BT_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BT_MESH_MIC_SHORT) + + +/** @def BT_MESH_MODEL_BUF_LEN_LONG_MIC + * + * @brief Helper for model message buffer length. + * + * Returns the length of a Mesh model message buffer, including the opcode + * length and a long MIC. + * + * @param _op Opcode of the message. + * @param _payload_len Length of the model payload. + */ +#define BT_MESH_MODEL_BUF_LEN_LONG_MIC(_op, _payload_len) \ + (BT_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BT_MESH_MIC_LONG) + + +/** @def BT_MESH_MODEL_BUF_DEFINE + * + * @brief Define a Mesh model message buffer using @ref NET_BUF_SIMPLE_DEFINE. + * + * @param _buf Buffer name. + * @param _op Opcode of the message. + * @param _payload_len Length of the model message payload. + */ +#define BT_MESH_MODEL_BUF(_op, _payload_len) \ + NET_BUF_SIMPLE(BT_MESH_MODEL_BUF_LEN(_op, (_payload_len))) + + +/** Message sending context. */ +struct bt_mesh_msg_ctx { + /** NetKey Index of the subnet to send the message on. */ + uint16_t net_idx; + + /** AppKey Index to encrypt the message with. */ + uint16_t app_idx; + + /** Remote address. */ + uint16_t addr; + + /** Destination address of a received message. Not used for sending. */ + uint16_t recv_dst; + + /** RSSI of received packet. Not used for sending. */ + int8_t recv_rssi; + + /** Received TTL value. Not used for sending. */ + uint8_t recv_ttl; + + /** Force sending reliably by using segment acknowledgment */ + bool send_rel; + + /** TTL, or BT_MESH_TTL_DEFAULT for default TTL. */ + uint8_t send_ttl; +}; + +/** @brief Initialize a model message. + * + * Clears the message buffer contents, and encodes the given opcode. + * The message buffer will be ready for filling in payload data. + * + * @param msg Message buffer. + * @param opcode Opcode to encode. + */ +void bt_mesh_model_msg_init(struct os_mbuf *msg, uint32_t opcode); + +/** + * Acknowledged message context for tracking the status of model messages pending a response. + */ +struct bt_mesh_msg_ack_ctx { + struct k_sem sem; /**< Sync semaphore. */ + uint32_t op; /**< Opcode we're waiting for. */ + uint16_t dst; /**< Address of the node that should respond. */ + void *user_data; /**< User specific parameter. */ +}; + +/** @brief Initialize an acknowledged message context. + * + * Initializes semaphore used for synchronization between @ref bt_mesh_msg_ack_ctx_wait and + * @ref bt_mesh_msg_ack_ctx_rx calls. Call this function before using @ref bt_mesh_msg_ack_ctx. + * + * @param ack Acknowledged message context to initialize. + */ +static inline void bt_mesh_msg_ack_ctx_init(struct bt_mesh_msg_ack_ctx *ack) +{ + k_sem_init(&ack->sem, 0, 1); +} + +/** @brief Reset the synchronization semaphore in an acknowledged message context. + * + * This function aborts call to @ref bt_mesh_msg_ack_ctx_wait. + * + * @param ack Acknowledged message context to be reset. + */ +static inline void bt_mesh_msg_ack_ctx_reset(struct bt_mesh_msg_ack_ctx *ack) +{ + k_sem_reset(&ack->sem); +} + +/** @brief Clear parameters of an acknowledged message context. + * + * This function clears the opcode, remote address and user data set + * by @ref bt_mesh_msg_ack_ctx_prepare. + * + * @param ack Acknowledged message context to be cleared. + */ +void bt_mesh_msg_ack_ctx_clear(struct bt_mesh_msg_ack_ctx *ack); + +/** @brief Prepare an acknowledged message context for the incoming message to wait. + * + * This function sets the opcode, remote address of the incoming message and stores the user data. + * Use this function before calling @ref bt_mesh_msg_ack_ctx_wait. + * + * @param ack Acknowledged message context to prepare. + * @param op The message OpCode. + * @param dst Destination address of the message. + * @param user_data User data for the acknowledged message context. + * + * @return 0 on success, or (negative) error code on failure. + */ +int bt_mesh_msg_ack_ctx_prepare(struct bt_mesh_msg_ack_ctx *ack, + uint32_t op, uint16_t dst, void *user_data); +/** @brief Check if the acknowledged message context is initialized with an opcode. + * + * @param ack Acknowledged message context. + * + * @return true if the acknowledged message context is initialized with an opcode, + * false otherwise. + */ +static inline bool bt_mesh_msg_ack_ctx_busy(struct bt_mesh_msg_ack_ctx *ack) +{ + return (ack->op != 0); +} + +/** @brief Wait for a message acknowledge. + * + * This function blocks execution until @ref bt_mesh_msg_ack_ctx_rx is called or by timeout. + * + * @param ack Acknowledged message context of the message to wait for. + * @param timeout Wait timeout. + * + * @return 0 on success, or (negative) error code on failure. + */ +int bt_mesh_msg_ack_ctx_wait(struct bt_mesh_msg_ack_ctx *ack, int32_t timeout); + +/** @brief Mark a message as acknowledged. + * + * This function unblocks call to @ref bt_mesh_msg_ack_ctx_wait. + * + * @param ack Context of a message to be acknowledged. + */ +static inline void bt_mesh_msg_ack_ctx_rx(struct bt_mesh_msg_ack_ctx *ack) +{ + k_sem_give(&ack->sem); +} + +/** @brief Check if an opcode and address of a message matches the expected one. + * + * @param ack Acknowledged message context to be checked. + * @param op OpCode of the incoming message. + * @param addr Source address of the incoming message. + * @param user_data If not NULL, returns a user data stored in the acknowledged message context + * by @ref bt_mesh_msg_ack_ctx_prepare. + * + * @return true if the incoming message matches the expected one, false otherwise. + */ +bool bt_mesh_msg_ack_ctx_match(const struct bt_mesh_msg_ack_ctx *ack, + uint32_t op, uint16_t addr, void **user_data); + +#ifdef __cplusplus +} +#endif +/** + * @} + */ +#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_MSG_H_ */ \ No newline at end of file diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index 9459da63e5..7211777d11 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -631,31 +631,6 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) } } -void bt_mesh_model_msg_init(struct os_mbuf *msg, uint32_t opcode) -{ - net_buf_simple_init(msg, 0); - - switch (BT_MESH_MODEL_OP_LEN(opcode)) { - case 1: - net_buf_simple_add_u8(msg, opcode); - break; - case 2: - net_buf_simple_add_be16(msg, opcode); - break; - case 3: - net_buf_simple_add_u8(msg, ((opcode >> 16) & 0xff)); - /* Using LE for the CID since the model layer is defined as - * little-endian in the mesh spec and using BT_MESH_MODEL_OP_3 - * will declare the opcode in this way. - */ - net_buf_simple_add_le16(msg, opcode & 0xffff); - break; - default: - BT_WARN("Unknown opcode format"); - break; - } -} - static int model_send(struct bt_mesh_model *model, struct bt_mesh_net_tx *tx, bool implicit_bind, struct os_mbuf *msg, diff --git a/nimble/host/mesh/src/cfg_cli.c b/nimble/host/mesh/src/cfg_cli.c index 82e6a82a59..dc56f992d5 100644 --- a/nimble/host/mesh/src/cfg_cli.c +++ b/nimble/host/mesh/src/cfg_cli.c @@ -33,11 +33,6 @@ static int32_t msg_timeout = K_SECONDS(5); static struct bt_mesh_cfg_cli *cli; -static inline bool cli_response_check(uint32_t resp_opcode, uint16_t resp_addr) -{ - return cli->op_pending == resp_opcode && cli->op_addr == resp_addr; -} - static void comp_data_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) @@ -49,20 +44,18 @@ static void comp_data_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_DEV_COMP_DATA_STATUS, ctx->addr)) { - BT_WARN("Unexpected Composition Data Status"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_DEV_COMP_DATA_STATUS, ctx->addr, + (void **)¶m)) { return; } - param = cli->op_param; - if (param->page) { *(param->page) = net_buf_simple_pull_u8(buf); } to_copy = min(net_buf_simple_tailroom(param->comp), buf->om_len); net_buf_simple_add_mem(param->comp, buf->om_data, to_copy); - k_sem_give(&cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } static void state_status_u8(struct bt_mesh_model *model, @@ -76,16 +69,14 @@ static void state_status_u8(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(expect_status, ctx->addr)) { - BT_WARN("Unexpected Status (0x%08x != 0x%08x)", - (unsigned) cli->op_pending, (unsigned) expect_status); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, expect_status, ctx->addr, + (void **)&status)) { return; } - status = cli->op_param; *status = net_buf_simple_pull_u8(buf); - k_sem_give(&cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } static void beacon_status(struct bt_mesh_model *model, @@ -131,16 +122,15 @@ static void relay_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_RELAY_STATUS, ctx->addr)) { - BT_WARN("Unexpected Relay Status message"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_RELAY_STATUS, ctx->addr, + (void **)¶m)) { return; } - param = cli->op_param; *param->status = net_buf_simple_pull_u8(buf); *param->transmit = net_buf_simple_pull_u8(buf); - k_sem_give(&cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } static void net_transmit_status(struct bt_mesh_model *model, @@ -153,15 +143,14 @@ static void net_transmit_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_NET_TRANSMIT_STATUS, ctx->addr)) { - BT_WARN("Unexpected Net Transmit Status message"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NET_TRANSMIT_STATUS, ctx->addr, + (void **)&status)) { return; } - status = cli->op_param; *status = net_buf_simple_pull_u8(buf); - k_sem_give(&cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } struct net_key_param { @@ -181,15 +170,14 @@ static void net_key_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_NET_KEY_STATUS, ctx->addr)) { - BT_WARN("Unexpected Net Key Status message"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NET_KEY_STATUS, ctx->addr, + (void **)¶m)) { return; } status = net_buf_simple_pull_u8(buf); net_idx = net_buf_simple_pull_le16(buf) & 0xfff; - param = cli->op_param; if (param->net_idx != net_idx) { BT_WARN("Net Key Status key index does not match"); return; @@ -199,7 +187,7 @@ static void net_key_status(struct bt_mesh_model *model, *param->status = status; } - k_sem_give(&cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } struct net_key_list_param { @@ -218,13 +206,11 @@ static void net_key_list(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_NET_KEY_LIST, ctx->addr)) { - BT_WARN("Unexpected Net Key List message"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NET_KEY_LIST, ctx->addr, + (void **)¶m)) { return; } - param = cli->op_param; - for (i = 0; i < *param->key_cnt && buf->om_len >= 3; i += 2) { key_idx_unpack(buf, ¶m->keys[i], ¶m->keys[i + 1]); } @@ -235,7 +221,7 @@ static void net_key_list(struct bt_mesh_model *model, *param->key_cnt = i; - k_sem_give(&cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } static void node_reset_status(struct bt_mesh_model *model, @@ -245,17 +231,15 @@ static void node_reset_status(struct bt_mesh_model *model, BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x", ctx->net_idx, ctx->app_idx, ctx->addr); - if (!cli_response_check(OP_NODE_RESET_STATUS, ctx->addr)) { - BT_WARN("Unexpected Node Reset Status message"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NODE_RESET_STATUS, ctx->addr, + (void **)¶m)) { return; } - param = cli->op_param; - if (param) { *param = true; } - k_sem_give(&cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } struct app_key_param { @@ -276,15 +260,14 @@ static void app_key_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_APP_KEY_STATUS, ctx->addr)) { - BT_WARN("Unexpected App Key Status message"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_APP_KEY_STATUS, ctx->addr, + (void **)¶m)) { return; } status = net_buf_simple_pull_u8(buf); key_idx_unpack(buf, &net_idx, &app_idx); - param = cli->op_param; if (param->net_idx != net_idx || param->app_idx != app_idx) { BT_WARN("App Key Status key indices did not match"); return; @@ -294,7 +277,7 @@ static void app_key_status(struct bt_mesh_model *model, *param->status = status; } - k_sem_give(&cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } struct app_key_list_param { @@ -317,15 +300,14 @@ static void app_key_list(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_APP_KEY_LIST, ctx->addr)) { - BT_WARN("Unexpected App Key List message"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_APP_KEY_LIST, ctx->addr, + (void **)¶m)) { return; } status = net_buf_simple_pull_u8(buf); net_idx = net_buf_simple_pull_le16(buf) & 0xfff; - param = cli->op_param; if (param->net_idx != net_idx) { BT_WARN("App Key List Net Key index did not match"); return; @@ -344,7 +326,7 @@ static void app_key_list(struct bt_mesh_model *model, *param->status = status; } - k_sem_give(&cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } struct mod_app_param { @@ -367,8 +349,8 @@ static void mod_app_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_MOD_APP_STATUS, ctx->addr)) { - BT_WARN("Unexpected Model App Status message"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_APP_STATUS, ctx->addr, + (void **)¶m)) { return; } @@ -384,7 +366,6 @@ static void mod_app_status(struct bt_mesh_model *model, mod_id = net_buf_simple_pull_le16(buf); - param = cli->op_param; if (param->elem_addr != elem_addr || param->mod_app_idx != mod_app_idx || param->mod_id != mod_id || param->cid != cid) { @@ -396,7 +377,7 @@ static void mod_app_status(struct bt_mesh_model *model, *param->status = status; } - k_sem_give(&cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } struct mod_member_list_param { @@ -409,9 +390,9 @@ struct mod_member_list_param { }; static void mod_member_list_handle(struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf, bool vnd) + struct os_mbuf *buf, bool vnd, + struct mod_member_list_param *param) { - struct mod_member_list_param *param; uint16_t elem_addr, mod_id, cid; uint8_t status; int i; @@ -424,7 +405,6 @@ static void mod_member_list_handle(struct bt_mesh_msg_ctx *ctx, mod_id = net_buf_simple_pull_le16(buf); - param = cli->op_param; if (param->elem_addr != elem_addr || param->mod_id != mod_id || (vnd && param->cid != cid)) { BT_WARN("Model Member List parameters did not match"); @@ -445,39 +425,43 @@ static void mod_member_list_handle(struct bt_mesh_msg_ctx *ctx, *param->status = status; } - k_sem_give(&cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } static void mod_app_list(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { + struct mod_member_list_param *param; + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_SIG_MOD_APP_LIST, ctx->addr)) { - BT_WARN("Unexpected Model App List message"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_SIG_MOD_APP_LIST, ctx->addr, + (void **)¶m)) { return; } - mod_member_list_handle(ctx, buf, false); + mod_member_list_handle(ctx, buf, false, param); } static void mod_app_list_vnd(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { + struct mod_member_list_param *param; + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_VND_MOD_APP_LIST, ctx->addr)) { - BT_WARN("Unexpected Model App List Vendor message"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_VND_MOD_APP_LIST, ctx->addr, + (void **)¶m)) { return; } - mod_member_list_handle(ctx, buf, true); + mod_member_list_handle(ctx, buf, true, param); } struct mod_pub_param { @@ -500,12 +484,12 @@ static void mod_pub_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_MOD_PUB_STATUS, ctx->addr)) { + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_PUB_STATUS, ctx->addr, + (void **)¶m)) { BT_WARN("Unexpected Model Pub Status message"); return; } - param = cli->op_param; if (param->cid != CID_NVAL) { if (buf->om_len < 14) { BT_WARN("Unexpected Mod Pub Status with SIG Model"); @@ -552,7 +536,7 @@ static void mod_pub_status(struct bt_mesh_model *model, param->pub->transmit = net_buf_simple_pull_u8(buf); } - k_sem_give(&cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } struct mod_sub_param { @@ -576,8 +560,8 @@ static void mod_sub_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_MOD_SUB_STATUS, ctx->addr)) { - BT_WARN("Unexpected Model Subscription Status message"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_SUB_STATUS, ctx->addr, + (void **)¶m)) { return; } @@ -593,7 +577,6 @@ static void mod_sub_status(struct bt_mesh_model *model, mod_id = net_buf_simple_pull_le16(buf); - param = cli->op_param; if (param->elem_addr != elem_addr || param->mod_id != mod_id || (param->expect_sub && *param->expect_sub != sub_addr) || param->cid != cid) { @@ -609,39 +592,43 @@ static void mod_sub_status(struct bt_mesh_model *model, *param->status = status; } - k_sem_give(&cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } static void mod_sub_list(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { + struct mod_member_list_param *param; + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_MOD_SUB_LIST, ctx->addr)) { - BT_WARN("Unexpected Model Subscription List message"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_SUB_LIST, ctx->addr, + (void **)¶m)) { return; } - mod_member_list_handle(ctx, buf, false); + mod_member_list_handle(ctx, buf, false, param); } static void mod_sub_list_vnd(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { + struct mod_member_list_param *param; + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_MOD_SUB_LIST_VND, ctx->addr)) { - BT_WARN("Unexpected Model Subscription List Vendor message"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_SUB_LIST_VND, ctx->addr, + (void **)¶m)) { return; } - mod_member_list_handle(ctx, buf, true); + mod_member_list_handle(ctx, buf, true,param); } struct hb_sub_param { @@ -659,13 +646,11 @@ static void hb_sub_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_HEARTBEAT_SUB_STATUS, ctx->addr)) { - BT_WARN("Unexpected Heartbeat Subscription Status message"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_HEARTBEAT_SUB_STATUS, ctx->addr, + (void **)¶m)) { return; } - param = cli->op_param; - *param->status = net_buf_simple_pull_u8(buf); param->sub->src = net_buf_simple_pull_le16(buf); @@ -675,7 +660,7 @@ static void hb_sub_status(struct bt_mesh_model *model, param->sub->min = net_buf_simple_pull_u8(buf); param->sub->max = net_buf_simple_pull_u8(buf); - k_sem_give(&cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } struct hb_pub_param { @@ -693,13 +678,11 @@ static void hb_pub_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!cli_response_check(OP_HEARTBEAT_PUB_STATUS, ctx->addr)) { - BT_WARN("Unexpected Heartbeat Publication Status message"); + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_HEARTBEAT_PUB_STATUS, ctx->addr, + (void **)¶m)) { return; } - param = cli->op_param; - *param->status = net_buf_simple_pull_u8(buf); if (param->pub) { @@ -711,7 +694,7 @@ static void hb_pub_status(struct bt_mesh_model *model, param->pub->net_idx = net_buf_simple_pull_u8(buf); } - k_sem_give(&cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = { @@ -762,7 +745,7 @@ static int cfg_cli_init(struct bt_mesh_model *model) */ model->keys[0] = BT_MESH_KEY_DEV_ANY; - k_sem_init(&cli->op_sync, 0, 1); + bt_mesh_msg_ack_ctx_init(&cli->ack_ctx); return 0; } @@ -778,34 +761,7 @@ static int cli_prepare(void *param, uint32_t op, uint16_t addr) return -EINVAL; } - if (cli->op_pending) { - BT_WARN("Another synchronous operation pending"); - return -EBUSY; - } - - cli->op_param = param; - cli->op_pending = op; - cli->op_addr = addr; - - return 0; -} - -static void cli_reset(void) -{ - cli->op_pending = 0; - cli->op_param = NULL; - cli->op_addr = BT_MESH_ADDR_UNASSIGNED; -} - -static int cli_wait(void) -{ - int err; - - err = k_sem_take(&cli->op_sync, msg_timeout); - - cli_reset(); - - return err; + return bt_mesh_msg_ack_ctx_prepare(&cli->ack_ctx, op, addr, param); } int bt_mesh_cfg_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, @@ -835,11 +791,11 @@ int bt_mesh_cfg_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -867,11 +823,11 @@ static int get_state_u8(uint16_t net_idx, uint16_t addr, uint32_t op, uint32_t r err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -900,11 +856,11 @@ static int set_state_u8(uint16_t net_idx, uint16_t addr, uint32_t op, uint32_t r err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -999,11 +955,11 @@ int bt_mesh_cfg_relay_get(uint16_t net_idx, uint16_t addr, uint8_t *status, err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -1037,11 +993,11 @@ int bt_mesh_cfg_relay_set(uint16_t net_idx, uint16_t addr, uint8_t new_relay, err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -1075,16 +1031,16 @@ int bt_mesh_cfg_net_key_add(uint16_t net_idx, uint16_t addr, uint16_t key_net_id err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } if (!status) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -1116,12 +1072,12 @@ int bt_mesh_cfg_net_key_get(uint16_t net_idx, uint16_t addr, uint16_t *keys, err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); return err; } os_mbuf_free_chain(msg); - return cli_wait(); + return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); } int bt_mesh_cfg_net_key_del(uint16_t net_idx, uint16_t addr, @@ -1151,16 +1107,16 @@ int bt_mesh_cfg_net_key_del(uint16_t net_idx, uint16_t addr, err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } if (!status) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -1196,16 +1152,16 @@ int bt_mesh_cfg_app_key_add(uint16_t net_idx, uint16_t addr, uint16_t key_net_id err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } if (!status) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -1237,16 +1193,16 @@ int bt_mesh_cfg_node_reset(uint16_t net_idx, uint16_t addr, bool *status) err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } if (!status) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); if (err) { @@ -1287,12 +1243,12 @@ int bt_mesh_cfg_app_key_get(uint16_t net_idx, uint16_t addr, uint16_t key_net_id if (err) { BT_ERR("model_send() failed (err %d)", err); os_mbuf_free_chain(msg); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); return err; } os_mbuf_free_chain(msg); - return cli_wait(); + return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); } int bt_mesh_cfg_app_key_del(uint16_t net_idx, uint16_t addr, @@ -1325,18 +1281,18 @@ int bt_mesh_cfg_app_key_del(uint16_t net_idx, uint16_t addr, if (err) { BT_ERR("model_send() failed (err %d)", err); os_mbuf_free_chain(msg); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); return err; } if (!status) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); os_mbuf_free_chain(msg); return 0; } os_mbuf_free_chain(msg); - return cli_wait(); + return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); } static int mod_app_bind(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, @@ -1377,16 +1333,16 @@ static int mod_app_bind(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } if (!status) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -1449,12 +1405,12 @@ static int mod_app_unbind(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } if (!status) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); err = 0; goto done; } @@ -1464,7 +1420,7 @@ static int mod_app_unbind(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, if (err) { return err; } else { - return cli_wait(); + return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); } } @@ -1531,11 +1487,11 @@ static int mod_member_list_get(uint32_t op, uint32_t expect_op, uint16_t net_idx err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -1600,17 +1556,17 @@ static int mod_sub(uint32_t op, uint16_t net_idx, uint16_t addr, uint16_t elem_a err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } if (!status) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); err = 0; goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -1715,16 +1671,16 @@ static int mod_sub_va(uint32_t op, uint16_t net_idx, uint16_t addr, uint16_t ele err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } if (!status) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -1852,16 +1808,16 @@ static int mod_pub_get(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } if (!status) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -1929,16 +1885,16 @@ static int mod_pub_set(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } if (!status) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -1992,16 +1948,16 @@ int bt_mesh_cfg_hb_sub_set(uint16_t net_idx, uint16_t addr, err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } if (!status) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -2033,16 +1989,16 @@ int bt_mesh_cfg_hb_sub_get(uint16_t net_idx, uint16_t addr, err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } if (!status) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -2079,16 +2035,16 @@ int bt_mesh_cfg_hb_pub_set(uint16_t net_idx, uint16_t addr, err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } if (!status) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -2120,16 +2076,16 @@ int bt_mesh_cfg_hb_pub_get(uint16_t net_idx, uint16_t addr, err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } if (!status) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; diff --git a/nimble/host/mesh/src/health_cli.c b/nimble/host/mesh/src/health_cli.c index 76d639c5f3..c6057c5643 100644 --- a/nimble/host/mesh/src/health_cli.c +++ b/nimble/host/mesh/src/health_cli.c @@ -45,13 +45,11 @@ static void health_fault_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (health_cli->op_pending != OP_HEALTH_FAULT_STATUS) { - BT_WARN("Unexpected Health Fault Status message"); + if (!bt_mesh_msg_ack_ctx_match(&health_cli->ack_ctx, OP_HEALTH_FAULT_STATUS, ctx->addr, + (void **)¶m)) { return; } - param = health_cli->op_param; - test_id = net_buf_simple_pull_u8(buf); if (param->expect_test_id && test_id != *param->expect_test_id) { BT_WARN("Health fault with unexpected Test ID"); @@ -76,7 +74,7 @@ static void health_fault_status(struct bt_mesh_model *model, memcpy(param->faults, buf->om_data, *param->fault_count); - k_sem_give(&health_cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&health_cli->ack_ctx); } static void health_current_status(struct bt_mesh_model *model, @@ -119,16 +117,14 @@ static void health_period_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (health_cli->op_pending != OP_HEALTH_PERIOD_STATUS) { - BT_WARN("Unexpected Health Period Status message"); + if (!bt_mesh_msg_ack_ctx_match(&health_cli->ack_ctx, OP_HEALTH_PERIOD_STATUS, ctx->addr, + (void **)¶m)) { return; } - param = health_cli->op_param; - *param->divisor = net_buf_simple_pull_u8(buf); - k_sem_give(&health_cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&health_cli->ack_ctx); } struct health_attention_param { @@ -145,18 +141,16 @@ static void health_attention_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (health_cli->op_pending != OP_ATTENTION_STATUS) { - BT_WARN("Unexpected Health Attention Status message"); + if (!bt_mesh_msg_ack_ctx_match(&health_cli->ack_ctx, OP_ATTENTION_STATUS, ctx->addr, + (void **)¶m)) { return; } - param = health_cli->op_param; - if (param->attention) { *param->attention = net_buf_simple_pull_u8(buf); } - k_sem_give(&health_cli->op_sync); + bt_mesh_msg_ack_ctx_rx(&health_cli->ack_ctx); } const struct bt_mesh_model_op bt_mesh_health_cli_op[] = { @@ -167,39 +161,14 @@ const struct bt_mesh_model_op bt_mesh_health_cli_op[] = { BT_MESH_MODEL_OP_END, }; -static int cli_prepare(void *param, uint32_t op) +static int cli_prepare(void *param, uint32_t op, uint16_t addr) { if (!health_cli) { BT_ERR("No available Health Client context!"); return -EINVAL; } - if (health_cli->op_pending) { - BT_WARN("Another synchronous operation pending"); - return -EBUSY; - } - - health_cli->op_param = param; - health_cli->op_pending = op; - - return 0; -} - -static void cli_reset(void) -{ - health_cli->op_pending = 0; - health_cli->op_param = NULL; -} - -static int cli_wait(void) -{ - int err; - - err = k_sem_take(&health_cli->op_sync, msg_timeout); - - cli_reset(); - - return err; + return bt_mesh_msg_ack_ctx_prepare(&health_cli->ack_ctx, op, addr, param); } int bt_mesh_health_attention_get(uint16_t addr, uint16_t app_idx, uint8_t *attention) @@ -215,7 +184,7 @@ int bt_mesh_health_attention_get(uint16_t addr, uint16_t app_idx, uint8_t *atten }; int err; - err = cli_prepare(¶m, OP_ATTENTION_STATUS); + err = cli_prepare(¶m, OP_ATTENTION_STATUS, addr); if (err) { goto done; } @@ -225,11 +194,11 @@ int bt_mesh_health_attention_get(uint16_t addr, uint16_t app_idx, uint8_t *atten err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&health_cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -249,7 +218,7 @@ int bt_mesh_health_attention_set(uint16_t addr, uint16_t app_idx, uint8_t attent }; int err; - err = cli_prepare(¶m, OP_ATTENTION_STATUS); + err = cli_prepare(¶m, OP_ATTENTION_STATUS, addr); if (err) { goto done; } @@ -265,16 +234,16 @@ int bt_mesh_health_attention_set(uint16_t addr, uint16_t app_idx, uint8_t attent err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx); goto done; } if (!updated_attention) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&health_cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -293,7 +262,7 @@ int bt_mesh_health_period_get(uint16_t addr, uint16_t app_idx, uint8_t *divisor) }; int err; - err = cli_prepare(¶m, OP_HEALTH_PERIOD_STATUS); + err = cli_prepare(¶m, OP_HEALTH_PERIOD_STATUS, addr); if (err) { goto done; } @@ -303,11 +272,11 @@ int bt_mesh_health_period_get(uint16_t addr, uint16_t app_idx, uint8_t *divisor) err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&health_cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -327,7 +296,7 @@ int bt_mesh_health_period_set(uint16_t addr, uint16_t app_idx, uint8_t divisor, }; int err; - err = cli_prepare(¶m, OP_HEALTH_PERIOD_STATUS); + err = cli_prepare(¶m, OP_HEALTH_PERIOD_STATUS, addr); if (err) { goto done; } @@ -343,16 +312,16 @@ int bt_mesh_health_period_set(uint16_t addr, uint16_t app_idx, uint8_t divisor, err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx); goto done; } if (!updated_divisor) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&health_cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -376,7 +345,7 @@ int bt_mesh_health_fault_test(uint16_t addr, uint16_t app_idx, uint16_t cid, }; int err; - err = cli_prepare(¶m, OP_HEALTH_FAULT_STATUS); + err = cli_prepare(¶m, OP_HEALTH_FAULT_STATUS, addr); if (err) { goto done; } @@ -393,16 +362,16 @@ int bt_mesh_health_fault_test(uint16_t addr, uint16_t app_idx, uint16_t cid, err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx); goto done; } if (!faults) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&health_cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -426,7 +395,7 @@ int bt_mesh_health_fault_clear(uint16_t addr, uint16_t app_idx, uint16_t cid, }; int err; - err = cli_prepare(¶m, OP_HEALTH_FAULT_STATUS); + err = cli_prepare(¶m, OP_HEALTH_FAULT_STATUS, addr); if (err) { goto done; } @@ -442,16 +411,16 @@ int bt_mesh_health_fault_clear(uint16_t addr, uint16_t app_idx, uint16_t cid, err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx); goto done; } if (!test_id) { - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&health_cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -475,7 +444,7 @@ int bt_mesh_health_fault_get(uint16_t addr, uint16_t app_idx, uint16_t cid, }; int err; - err = cli_prepare(¶m, OP_HEALTH_FAULT_STATUS); + err = cli_prepare(¶m, OP_HEALTH_FAULT_STATUS, addr); if (err) { goto done; } @@ -486,11 +455,11 @@ int bt_mesh_health_fault_get(uint16_t addr, uint16_t app_idx, uint16_t cid, err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL); if (err) { BT_ERR("model_send() failed (err %d)", err); - cli_reset(); + bt_mesh_msg_ack_ctx_clear(&health_cli->ack_ctx); goto done; } - err = cli_wait(); + err = bt_mesh_msg_ack_ctx_wait(&health_cli->ack_ctx, K_MSEC(msg_timeout)); done: os_mbuf_free_chain(msg); return err; @@ -533,13 +502,12 @@ static int health_cli_init(struct bt_mesh_model *model) cli = model->user_data; cli->model = model; - k_sem_init(&cli->op_sync, 0, 1); - /* Set the default health client pointer */ if (!health_cli) { health_cli = cli; } + bt_mesh_msg_ack_ctx_init(&health_cli->ack_ctx); return 0; } diff --git a/nimble/host/mesh/src/msg.c b/nimble/host/mesh/src/msg.c new file mode 100644 index 0000000000..853a0f43dc --- /dev/null +++ b/nimble/host/mesh/src/msg.c @@ -0,0 +1,83 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "mesh/mesh.h" + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_ACCESS) +#define LOG_MODULE_NAME bt_mesh_msg + +void bt_mesh_model_msg_init(struct os_mbuf *msg, uint32_t opcode) +{ + net_buf_simple_init(msg, 0); + + switch (BT_MESH_MODEL_OP_LEN(opcode)) { + case 1: + net_buf_simple_add_u8(msg, opcode); + break; + case 2: + net_buf_simple_add_be16(msg, opcode); + break; + case 3: + net_buf_simple_add_u8(msg, ((opcode >> 16) & 0xff)); + /* Using LE for the CID since the model layer is defined as + * little-endian in the mesh spec and using BT_MESH_MODEL_OP_3 + * will declare the opcode in this way. + */ + net_buf_simple_add_le16(msg, opcode & 0xffff); + break; + default: + BT_WARN("Unknown opcode format"); + break; + } +} + +void bt_mesh_msg_ack_ctx_clear(struct bt_mesh_msg_ack_ctx *ack) +{ + ack->op = 0U; + ack->user_data = NULL; + ack->dst = BT_MESH_ADDR_UNASSIGNED; +} + +int bt_mesh_msg_ack_ctx_prepare(struct bt_mesh_msg_ack_ctx *ack, + uint32_t op, uint16_t dst, void *user_data) +{ + if (ack->op) { + BT_WARN("Another synchronous operation pending"); + return -EBUSY; + } + + ack->op = op; + ack->user_data = user_data; + ack->dst = dst; + + return 0; +} + +int bt_mesh_msg_ack_ctx_wait(struct bt_mesh_msg_ack_ctx *ack, int32_t timeout) +{ + int err; + + err = k_sem_take(&ack->sem, timeout); + bt_mesh_msg_ack_ctx_clear(ack); + + return err; + } + +bool bt_mesh_msg_ack_ctx_match(const struct bt_mesh_msg_ack_ctx *ack, + uint32_t op, uint16_t addr, void **user_data) +{ + if (ack->op != op || (BT_MESH_ADDR_IS_UNICAST(ack->dst) && ack->dst != addr)) { + return false; + } + + if (user_data != NULL) { + *user_data = ack->user_data; + } + + return true; +} \ No newline at end of file From f173ca2cc71d83da8659ac9b3dc3c7c442bc63f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 7 Oct 2021 14:55:28 +0200 Subject: [PATCH 0082/1333] host/mesh: Rework publication timer Periodic publication would previously build and send the first publication inside the bt_mesh_model_pub() function, before cancelling and rescheduling the next publication. The timer handler would only handle retransmissions, and would abandon the rest of the publication event if one of the packets failed to send. This design has three issues: - If the initial timer cancel fails, the publication would interfer with the periodic publication management, which might skip an event or send too many packets. - If any of the messages fail to publish, the full publication event would be abandoned. This is not predictable or expected from the API. - bt_mesh_model_pub() required 384 bytes of stack to build the message, which has to be factored into all calling threads. This patch moves all transmission into the publication timer by replacing k_work_cancel with a single k_work_reschedule(K_NO_WAIT). It also changes the error recovery behavior to attempt to finish the full publication event even if some of the transmissions fail. This is port of 820cfc52adc728a727a33a182a2d360af86ecdd9 --- nimble/host/mesh/include/mesh/access.h | 12 +- nimble/host/mesh/src/access.c | 176 ++++++++++--------------- nimble/host/mesh/src/cfg_srv.c | 8 +- nimble/host/mesh/src/mesh.c | 8 +- 4 files changed, 88 insertions(+), 116 deletions(-) diff --git a/nimble/host/mesh/include/mesh/access.h b/nimble/host/mesh/include/mesh/access.h index 0efee414f8..c3f36f43a0 100644 --- a/nimble/host/mesh/include/mesh/access.h +++ b/nimble/host/mesh/include/mesh/access.h @@ -310,17 +310,17 @@ struct bt_mesh_model_pub { /** The model the context belongs to. Initialized by the stack. */ struct bt_mesh_model *mod; - uint16_t addr; /**< Publish Address. */ - uint16_t key; /**< Publish AppKey Index. */ + uint16_t addr; /**< Publish Address. */ + uint16_t key:12, /**< Publish AppKey Index. */ + cred:1, /**< Friendship Credentials Flag. */ + send_rel:1, /**< Force reliable sending (segment acks) */ + fast_period:1; /**< Use FastPeriodDivisor */ uint8_t ttl; /**< Publish Time to Live. */ uint8_t retransmit; /**< Retransmit Count & Interval Steps. */ uint8_t period; /**< Publish Period. */ uint8_t period_div:4, /**< Divisor for the Period. */ - cred:1, /**< Friendship Credentials Flag. */ - send_rel:1, - fast_period:1,/**< Use FastPeriodDivisor */ - count:3; /**< Retransmissions left. */ + count:4; uint32_t period_start; /**< Start of the current period. */ diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index 7211777d11..1c34b2ec2a 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -148,7 +148,7 @@ static void publish_sent(int err, void *user_data) if (delay) { BT_DBG("Publishing next time in %dms", (int) delay); - k_work_reschedule(&mod->pub->timer, delay); + k_work_schedule(&mod->pub->timer, delay); } } @@ -159,6 +159,7 @@ static void publish_start(uint16_t duration, int err, void *user_data) if (err) { BT_ERR("Failed to publish: err %d", err); + publish_sent(err, user_data); return; } @@ -173,7 +174,7 @@ static const struct bt_mesh_send_cb pub_sent_cb = { .end = publish_sent, }; -static int publish_retransmit(struct bt_mesh_model *mod) +static int publish_transmit(struct bt_mesh_model *mod) { struct os_mbuf *sdu = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); struct bt_mesh_model_pub *pub = mod->pub; @@ -192,67 +193,68 @@ static int publish_retransmit(struct bt_mesh_model *mod) net_buf_simple_init(sdu, 0); net_buf_simple_add_mem(sdu, pub->msg->om_data, pub->msg->om_len); - pub->count--; - err = bt_mesh_trans_send(&tx, sdu, &pub_sent_cb, mod); os_mbuf_free_chain(sdu); return err; } -static void publish_retransmit_end(int err, struct bt_mesh_model_pub *pub) +static int pub_period_start(struct bt_mesh_model_pub *pub) { - /* Cancel all retransmits for this publish attempt */ - pub->count = 0U; - /* Make sure the publish timer gets reset */ - publish_sent(err, pub->mod); + int err; + + pub->count = BT_MESH_PUB_TRANSMIT_COUNT(pub->retransmit); + + if (!pub->update) { + return 0; + } + + err = pub->update(pub->mod); + if (err) { + /* Skip this publish attempt. */ + BT_DBG("Update failed, skipping publish (err: %d)", err); + pub->count = 0; + pub->period_start = k_uptime_get_32(); + publish_sent(err, pub); + return err; + } + + return 0; } static void mod_publish(struct ble_npl_event *work) { struct bt_mesh_model_pub *pub = ble_npl_event_get_arg(work); - int32_t period_ms; int err; - BT_DBG(""); + if (pub->addr == BT_MESH_ADDR_UNASSIGNED || + atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) { + /* Publication is no longer active, but the cancellation of the + * delayed work failed. Abandon recurring timer. + */ + return; + } - period_ms = bt_mesh_model_pub_period_get(pub->mod); - BT_DBG("period %u ms", (unsigned) period_ms); + BT_DBG(""); if (pub->count) { - err = publish_retransmit(pub->mod); + pub->count--; + } else { + /* First publication in this period */ + err = pub_period_start(pub); if (err) { - BT_ERR("Failed to retransmit (err %d)", err); - - pub->count = 0; - - /* Continue with normal publication */ - if (period_ms) { - k_work_reschedule(&pub->timer, period_ms); - } + return; } - - return; } - if (!period_ms) { - return; - } - - __ASSERT_NO_MSG(pub->update != NULL); - - err = pub->update(pub->mod); + err = publish_transmit(pub->mod); if (err) { - /* Cancel this publish attempt. */ - BT_DBG("Update failed, skipping publish (err: %d)", err); - pub->period_start = k_uptime_get_32(); - publish_retransmit_end(err, pub); - return; - } + BT_ERR("Failed to publish (err %d)", err); + if (pub->count == BT_MESH_PUB_TRANSMIT_COUNT(pub->retransmit)) { + pub->period_start = k_uptime_get_32(); + } - err = bt_mesh_model_publish(pub->mod); - if (err) { - BT_ERR("Publishing failed (err %d)", err); + publish_sent(err, pub->mod); } } @@ -631,13 +633,17 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) } } -static int model_send(struct bt_mesh_model *model, - struct bt_mesh_net_tx *tx, bool implicit_bind, - struct os_mbuf *msg, - const struct bt_mesh_send_cb *cb, void *cb_data) +int bt_mesh_model_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *msg, + const struct bt_mesh_send_cb *cb, void *cb_data) { - BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx->ctx->net_idx, - tx->ctx->app_idx, tx->ctx->addr); + struct bt_mesh_net_tx tx = { + .ctx = ctx, + .src = bt_mesh_model_elem(model)->addr, + }; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx.ctx->net_idx, + tx.ctx->app_idx, tx.ctx->addr); BT_DBG("len %u: %s", msg->om_len, bt_hex(msg->om_data, msg->om_len)); if (!bt_mesh_is_provisioned()) { @@ -645,95 +651,51 @@ static int model_send(struct bt_mesh_model *model, return -EAGAIN; } - if (net_buf_simple_tailroom(msg) < 4) { - BT_ERR("Not enough tailroom for TransMIC"); + if (!model_has_key(model, tx.ctx->app_idx)) { + BT_ERR("Model not bound to AppKey 0x%04x", tx.ctx->app_idx); return -EINVAL; } - if (msg->om_len > BT_MESH_TX_SDU_MAX - 4) { - BT_ERR("Too big message"); - return -EMSGSIZE; - } - - if (!implicit_bind && !model_has_key(model, tx->ctx->app_idx)) { - BT_ERR("Model not bound to AppKey 0x%04x", tx->ctx->app_idx); - return -EINVAL; - } - - return bt_mesh_trans_send(tx, msg, cb, cb_data); -} - -int bt_mesh_model_send(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *msg, - const struct bt_mesh_send_cb *cb, void *cb_data) -{ - struct bt_mesh_net_tx tx = { - .ctx = ctx, - .src = bt_mesh_model_elem(model)->addr, - }; - - return model_send(model, &tx, false, msg, cb, cb_data); + return bt_mesh_trans_send(&tx, msg, cb, cb_data); } int bt_mesh_model_publish(struct bt_mesh_model *model) { - int err; - struct os_mbuf *sdu = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); struct bt_mesh_model_pub *pub = model->pub; if (!pub) { - err = -ENOTSUP; - goto done; + return -ENOTSUP; } - struct bt_mesh_msg_ctx ctx = { - .addr = pub->addr, - .send_ttl = pub->ttl, - .send_rel = pub->send_rel, - .app_idx = pub->key, - }; - struct bt_mesh_net_tx tx = { - .ctx = &ctx, - .src = bt_mesh_model_elem(model)->addr, - }; - BT_DBG(""); if (pub->addr == BT_MESH_ADDR_UNASSIGNED) { - err = -EADDRNOTAVAIL; - goto done; + return -EADDRNOTAVAIL; } - if (pub->msg->om_len + 4 > BT_MESH_TX_SDU_MAX) { + if (!pub->msg || !pub->msg->om_len) { + BT_ERR("No publication message"); + return -EINVAL; + } + + if (pub->msg->om_len + BT_MESH_MIC_SHORT > BT_MESH_TX_SDU_MAX) { BT_ERR("Message does not fit maximum SDU size"); - err = -EMSGSIZE; - goto done; + return -EMSGSIZE; } if (pub->count) { BT_WARN("Clearing publish retransmit timer"); - k_work_cancel_delayable(&pub->timer); } - net_buf_simple_init(sdu, 0); - net_buf_simple_add_mem(sdu, pub->msg->om_data, pub->msg->om_len); - - tx.friend_cred = pub->cred; - - pub->count = BT_MESH_PUB_TRANSMIT_COUNT(pub->retransmit); + /* Account for initial transmission */ + pub->count = BT_MESH_PUB_TRANSMIT_COUNT(pub->retransmit) + 1; BT_DBG("Publish Retransmit Count %u Interval %ums", pub->count, BT_MESH_PUB_TRANSMIT_INT(pub->retransmit)); - err = model_send(model, &tx, true, sdu, &pub_sent_cb, model); - if (err) { - publish_retransmit_end(err, pub); - } + k_work_reschedule(&pub->timer, K_NO_WAIT); -done: - os_mbuf_free_chain(sdu); - return err; + return 0; } struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem, @@ -1225,7 +1187,7 @@ static void commit_mod(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, if (ms > 0) { BT_DBG("Starting publish timer (period %u ms)", ms); - k_work_reschedule(&mod->pub->timer, K_MSEC(ms)); + k_work_schedule(&mod->pub->timer, K_MSEC(ms)); } } diff --git a/nimble/host/mesh/src/cfg_srv.c b/nimble/host/mesh/src/cfg_srv.c index 919c26a94a..158970c250 100644 --- a/nimble/host/mesh/src/cfg_srv.c +++ b/nimble/host/mesh/src/cfg_srv.c @@ -200,7 +200,10 @@ static uint8_t _mod_pub_set(struct bt_mesh_model *model, uint16_t pub_addr, model->pub->count = 0; if (model->pub->update) { - k_work_cancel_delayable(&model->pub->timer); + /* If this fails, the timer will check pub->addr and + * exit without transmitting. + */ + (void)k_work_cancel_delayable(&model->pub->timer); } if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) { @@ -240,6 +243,9 @@ static uint8_t _mod_pub_set(struct bt_mesh_model *model, uint16_t pub_addr, if (period_ms > 0) { k_work_reschedule(&model->pub->timer, period_ms); } else { + /* If this fails, publication will stop after the + * ongoing set of retransmits. + */ k_work_cancel_delayable(&model->pub->timer); } } diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c index a9bdb3154c..ae01888351 100644 --- a/nimble/host/mesh/src/mesh.c +++ b/nimble/host/mesh/src/mesh.c @@ -240,7 +240,10 @@ static void model_suspend(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, { if (mod->pub && mod->pub->update) { mod->pub->count = 0; - k_work_cancel_delayable(&mod->pub->timer); + /* If this fails, the work handler will check the suspend call + * and exit without transmitting. + */ + (void)k_work_cancel_delayable(&mod->pub->timer); } } @@ -281,7 +284,8 @@ static void model_resume(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, int32_t period_ms = bt_mesh_model_pub_period_get(mod); if (period_ms) { - k_work_reschedule(&mod->pub->timer, period_ms); + k_work_reschedule(&mod->pub->timer, + K_MSEC(period_ms)); } } } From a24783923040895d29c3f2b4f5d57959c7ffaf11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 7 Oct 2021 14:57:44 +0200 Subject: [PATCH 0083/1333] host/mesh: Transport length checks should account for MIC The Transport layer would previously rely on the access layer to check whether there's room for the full message and a MIC in the available buffer space, and its own checks would ignore the MIC. This should be handled by the Transport layer checks, so the access layer doesn't have to. This is port of 5c6df442ff1dcbeaf4115f866a10a91a7f97225f --- nimble/host/mesh/src/transport.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nimble/host/mesh/src/transport.c b/nimble/host/mesh/src/transport.c index 643606349c..4d528bf941 100644 --- a/nimble/host/mesh/src/transport.c +++ b/nimble/host/mesh/src/transport.c @@ -630,12 +630,12 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct os_mbuf *msg, return -EINVAL; } - if (msg->om_len > BT_MESH_TX_SDU_MAX) { - BT_ERR("Not enough segment buffers for length %u", msg->om_len); + if (msg->om_len > BT_MESH_TX_SDU_MAX - BT_MESH_MIC_SHORT) { + BT_ERR("Message too big: %u", msg->om_len); return -EMSGSIZE; } - if (net_buf_simple_tailroom(msg) < 4) { + if (net_buf_simple_tailroom(msg) < BT_MESH_MIC_SHORT) { BT_ERR("Insufficient tailroom for Transport MIC"); return -EINVAL; } From 92b86e8404b1ee5bcf6b25dd5306a07e86758010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 7 Oct 2021 14:59:29 +0200 Subject: [PATCH 0084/1333] host/mesh: Report configured LPNTimeout in cfg_srv Changes lpn_timeout_get behavior in the config server to report the configured LPN timeout, instead of the currently remaining timeout time. According to the Bluetooth Mesh Profile specification, section 4.2.21, the PollTimeout list is a list of the PollTimeout timer values, and according to table 4.32 in this section, values 1-9 are prohibited. Although this is not explicitly stated, this indicates that the PollTimeout value is the configured poll timeout time - not the time remaining until the timeout value expires. This patch changes the implementation to reflect this. This is port of bf942bdf9abb0d7bed83f6297ccb79d443e85d69 --- nimble/host/mesh/src/cfg_srv.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/nimble/host/mesh/src/cfg_srv.c b/nimble/host/mesh/src/cfg_srv.c index 158970c250..35a00bd9e5 100644 --- a/nimble/host/mesh/src/cfg_srv.c +++ b/nimble/host/mesh/src/cfg_srv.c @@ -2106,8 +2106,8 @@ static void lpn_timeout_get(struct bt_mesh_model *model, { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_LPN_TIMEOUT_STATUS, 5); struct bt_mesh_friend *frnd; + int32_t timeout_steps; uint16_t lpn_addr; - int32_t timeout; lpn_addr = net_buf_simple_pull_le16(buf); @@ -2124,21 +2124,21 @@ static void lpn_timeout_get(struct bt_mesh_model *model, net_buf_simple_add_le16(msg, lpn_addr); if (!IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { - timeout = 0; + timeout_steps = 0; goto send_rsp; } frnd = bt_mesh_friend_find(BT_MESH_KEY_ANY, lpn_addr, true, true); if (!frnd) { - timeout = 0; + timeout_steps = 0; goto send_rsp; } - timeout = k_ticks_to_ms_floor32( - k_work_delayable_remaining_get(&frnd->timer)) / 100; + /* PollTimeout should be reported in steps of 100ms. */ + timeout_steps = frnd->poll_to / 100; send_rsp: - net_buf_simple_add_le24(msg, timeout); + net_buf_simple_add_le24(msg, timeout_steps); if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send LPN PollTimeout Status"); From a1faca303de159e0c2b9a1d26598ce3b23f27a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 7 Oct 2021 15:22:09 +0200 Subject: [PATCH 0085/1333] host/mesh: Convert beacon timer to delayable work Moves the beacon_enabled check in the beacon work handler to check the beacon flag before sending anything, in case a cancel call fails. This is port of 286d9c22cd96121c2bbef437fee6212e84aacb99 --- nimble/host/mesh/src/beacon.c | 54 +++++++++++++++++------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/nimble/host/mesh/src/beacon.c b/nimble/host/mesh/src/beacon.c index d7be9c5e1c..2b678f9008 100644 --- a/nimble/host/mesh/src/beacon.c +++ b/nimble/host/mesh/src/beacon.c @@ -228,33 +228,30 @@ static void update_beacon_observation(void) static void beacon_send(struct ble_npl_event *work) { - /* Don't send anything if we have an active provisioning link */ - if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV) && bt_mesh_prov_active()) { - k_work_reschedule(&beacon_timer, - K_SECONDS(MYNEWT_VAL(BLE_MESH_UNPROV_BEACON_INT))); - return; - } BT_DBG(""); if (bt_mesh_is_provisioned()) { + if (!bt_mesh_beacon_enabled() && + !atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR)) { + return; + } + update_beacon_observation(); (void)bt_mesh_subnet_find(secure_beacon_send, NULL); - /* Only resubmit if beaconing is still enabled */ - if (bt_mesh_beacon_enabled() || - atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR)) { - k_work_reschedule(&beacon_timer, - PROVISIONED_INTERVAL); - } + k_work_schedule(&beacon_timer, PROVISIONED_INTERVAL); return; } if (IS_ENABLED(BLE_MESH_PB_ADV)) { - unprovisioned_beacon_send(); - k_work_reschedule(&beacon_timer, - K_SECONDS(MYNEWT_VAL(BLE_MESH_UNPROV_BEACON_INT))); + /* Don't send anything if we have an active provisioning link */ + if (!bt_mesh_prov_active()) { + unprovisioned_beacon_send(); + } + + k_work_schedule(&beacon_timer, K_SECONDS(MYNEWT_VAL(BLE_MESH_UNPROV_BEACON_INT))); } } @@ -426,7 +423,7 @@ static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt) void bt_mesh_beacon_init(void) { - if (!bt_mesh_subnet_cb_list[1]) { + if (!bt_mesh_subnet_cb_list[1]) { bt_mesh_subnet_cb_list[1] = subnet_evt; } @@ -437,11 +434,16 @@ void bt_mesh_beacon_ivu_initiator(bool enable) { atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_INITIATOR, enable); - if (enable) { - k_work_reschedule(&beacon_timer, K_NO_WAIT); - } else if (!bt_mesh_beacon_enabled()) { - k_work_cancel_delayable(&beacon_timer); - } + /* Fire the beacon handler straight away if it's not already pending - + * in which case we'll fire according to the ongoing periodic sending. + * If beacons are disabled, the handler will exit early. + * + * An alternative solution would be to check whether beacons are enabled + * here, and cancel if not. As the cancel operation may fail, we would + * still have to implement an early exit mechanism, so we might as well + * just use this every time. + */ + k_work_schedule(&beacon_timer, K_NO_WAIT); } static void subnet_beacon_enable(struct bt_mesh_subnet *sub) @@ -454,19 +456,17 @@ static void subnet_beacon_enable(struct bt_mesh_subnet *sub) void bt_mesh_beacon_enable(void) { - if (!bt_mesh_is_provisioned()) { - k_work_reschedule(&beacon_timer, K_NO_WAIT); - return; + if (bt_mesh_is_provisioned()) { + bt_mesh_subnet_foreach(subnet_beacon_enable); } - bt_mesh_subnet_foreach(subnet_beacon_enable); - k_work_reschedule(&beacon_timer, K_NO_WAIT); } void bt_mesh_beacon_disable(void) { if (!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR)) { - k_work_cancel_delayable(&beacon_timer); + /* If this fails, we'll do an early exit in the work handler. */ + (void)k_work_cancel_delayable(&beacon_timer); } } From f715ad64dadca9916bd6603d5d48e3bed161d292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 7 Oct 2021 15:26:28 +0200 Subject: [PATCH 0086/1333] host/mesh: move lpn logic for msg_received inside lpn.c The Transport layer implements some checks surrounding the lpn_msg_received call, with an accompanying comment that explains the logic. Move this inside the msg_received call instead. This is port of 777718ea6e3e0f59c61f404285bb75960bf3af96 --- nimble/host/mesh/src/lpn.c | 8 ++++++++ nimble/host/mesh/src/lpn.h | 9 --------- nimble/host/mesh/src/transport.c | 16 ++-------------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/nimble/host/mesh/src/lpn.c b/nimble/host/mesh/src/lpn.c index 4c6c708ca2..ad6cfe4d25 100644 --- a/nimble/host/mesh/src/lpn.c +++ b/nimble/host/mesh/src/lpn.c @@ -501,6 +501,14 @@ void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx) return; } + /* If the message was a Friend control message, it's possible that a + * Poll was already queued for sending. In this case, we're already in + * a different state. + */ + if (lpn->state != BT_MESH_LPN_WAIT_UPDATE) { + return; + } + if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) { BT_WARN("Unexpected message withouth a preceding Poll"); return; diff --git a/nimble/host/mesh/src/lpn.h b/nimble/host/mesh/src/lpn.h index 90de2ca086..cb2e1f2fef 100644 --- a/nimble/host/mesh/src/lpn.h +++ b/nimble/host/mesh/src/lpn.h @@ -47,15 +47,6 @@ static inline bool bt_mesh_lpn_waiting_update(void) #endif } -static inline bool bt_mesh_lpn_timer(void) -{ -#if MYNEWT_VAL(BLE_MESH_LOW_POWER) && MYNEWT_VAL(BLE_MESH_LPN_AUTO) - return (bt_mesh.lpn.state == BT_MESH_LPN_TIMER); -#else - return false; -#endif -} - void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx); void bt_mesh_lpn_group_add(uint16_t group); diff --git a/nimble/host/mesh/src/transport.c b/nimble/host/mesh/src/transport.c index 4d528bf941..aae72bf378 100644 --- a/nimble/host/mesh/src/transport.c +++ b/nimble/host/mesh/src/transport.c @@ -1586,20 +1586,8 @@ int bt_mesh_trans_recv(struct os_mbuf *buf, struct bt_mesh_net_rx *rx) err = trans_unseg(buf, rx, &seq_auth); } - /* Notify LPN state machine so a Friend Poll will be sent. If the - * message was a Friend Update it's possible that a Poll was already - * queued for sending, however that's fine since then the - * bt_mesh_lpn_waiting_update() function will return false: - * we still need to go through the actual sending to the bearer and - * wait for ReceiveDelay before transitioning to WAIT_UPDATE state. - * Another situation where we want to notify the LPN state machine - * is if it's configured to use an automatic Friendship establishment - * timer, in which case we want to reset the timer at this point. - * - */ - if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && - (bt_mesh_lpn_timer() || - (bt_mesh_lpn_established() && bt_mesh_lpn_waiting_update()))) { + /* Notify LPN state machine so a Friend Poll will be sent. */ + if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { bt_mesh_lpn_msg_received(rx); } From ceefdcb8a9c8c596b804d73b85179e36dfdb2979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 07:56:34 +0200 Subject: [PATCH 0087/1333] hoat/mesh: Provisioning output count number should be at least 1 When selecting a random count for blink, beep or vibrate, the Bluetooth Mesh Profile Specification v1.0.1, section 5.4.2.4 states: "the device shall select a random integer between 0 and 10 to the power of the Authentication Size exclusive". This means that if size is 1, the integer should be in the range 1-9, while the implementation chose an integer in the range 0-9. Reduce the range and add 1 to the num to correct this for these actions. This is port of 3656f7f60972dc03aa00071d21028f7b582e7765 --- nimble/host/mesh/src/prov.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/prov.c b/nimble/host/mesh/src/prov.c index 170fc1d099..d44d8ec030 100644 --- a/nimble/host/mesh/src/prov.c +++ b/nimble/host/mesh/src/prov.c @@ -161,7 +161,19 @@ int bt_mesh_prov_auth(uint8_t method, uint8_t action, uint8_t size) uint32_t num; bt_rand(&num, sizeof(num)); - num %= div[size - 1]; + + if (output == BT_MESH_BLINK || + output == BT_MESH_BEEP || + output == BT_MESH_VIBRATE) { + /* According to the Bluetooth Mesh Profile + * Specification Section 5.4.2.4, blink, beep + * and vibrate should be a random integer + * between 0 and 10^size, *exclusive*: + */ + num = (num % (div[size - 1] - 1)) + 1; + } else { + num %= div[size - 1]; + } sys_put_be32(num, &bt_mesh_prov_link.auth[12]); memset(bt_mesh_prov_link.auth, 0, 12); From 6f1e5f23860bd6dfafcab3310e611d96a5a4604b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 08:00:30 +0200 Subject: [PATCH 0088/1333] host/mesh: Add friend_is_allocated utility Friend structure allocaction logic is implemented over and over throughout the friend module. Move it into a static utility function for readability. This is port of 0f5b5f74acbfefaee23b5172da2c1aa0807553d0 --- nimble/host/mesh/src/friend.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/nimble/host/mesh/src/friend.c b/nimble/host/mesh/src/friend.c index 402930f9f8..a1662a3179 100644 --- a/nimble/host/mesh/src/friend.c +++ b/nimble/host/mesh/src/friend.c @@ -72,6 +72,11 @@ static struct bt_mesh_adv *adv_alloc(int id) return &adv_pool[id].adv; } +static bool friend_is_allocated(const struct bt_mesh_friend *frnd) +{ + return frnd->subnet != NULL; +} + static bool is_lpn_unicast(struct bt_mesh_friend *frnd, uint16_t addr) { if (frnd->lpn == BT_MESH_ADDR_UNASSIGNED) { @@ -91,7 +96,7 @@ struct bt_mesh_friend *bt_mesh_friend_find(uint16_t net_idx, uint16_t lpn_addr, for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; - if (valid && !frnd->subnet) { + if (valid && !friend_is_allocated(frnd)) { continue; } @@ -193,7 +198,7 @@ void bt_mesh_friends_clear(void) for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; - if (!frnd->subnet) { + if (!friend_is_allocated(frnd)) { continue; } @@ -212,7 +217,7 @@ void bt_mesh_friend_sec_update(uint16_t net_idx) for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; - if (!frnd->subnet) { + if (!friend_is_allocated(frnd)) { continue; } @@ -548,7 +553,7 @@ static struct os_mbuf *encode_update(struct bt_mesh_friend *frnd, uint8_t md) struct os_mbuf *sdu = NET_BUF_SIMPLE(1 + sizeof(*upd)); struct os_mbuf *buf; - __ASSERT_NO_MSG(frnd->subnet); + __ASSERT_NO_MSG(friend_is_allocated(frnd)); BT_DBG("lpn 0x%04x md 0x%02x", frnd->lpn, md); From dec5e2ccf500c51a2b79d6c747576e5dca55a41e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 08:10:12 +0200 Subject: [PATCH 0089/1333] host/mesh: Core delayable work updates Switch to the new API in friend, net and main. This is port of 38609d34e09dccd4998f55e97dbfa5bb90dfa635 --- nimble/host/mesh/src/friend.c | 17 ++++++++++++++--- nimble/host/mesh/src/net.c | 4 ++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/nimble/host/mesh/src/friend.c b/nimble/host/mesh/src/friend.c index a1662a3179..13ce285d51 100644 --- a/nimble/host/mesh/src/friend.c +++ b/nimble/host/mesh/src/friend.c @@ -156,7 +156,7 @@ static void friend_clear(struct bt_mesh_friend *frnd) BT_DBG("LPN 0x%04x", frnd->lpn); - k_work_cancel_delayable(&frnd->timer); + (void)k_work_cancel_delayable(&frnd->timer); memset(frnd->cred, 0, sizeof(frnd->cred)); @@ -816,6 +816,11 @@ static void clear_timeout(struct ble_npl_event *work) struct bt_mesh_friend *frnd = ble_npl_event_get_arg(work); uint32_t duration; + if (frnd->clear.frnd == BT_MESH_ADDR_UNASSIGNED) { + /* Failed cancelling timer, return early. */ + return; + } + BT_DBG("LPN 0x%04x (old) Friend 0x%04x", frnd->lpn, frnd->clear.frnd); duration = k_uptime_get_32() - frnd->clear.start; @@ -872,7 +877,8 @@ int bt_mesh_friend_clear_cfm(struct bt_mesh_net_rx *rx, return 0; } - k_work_cancel_delayable(&frnd->clear.timer); + /* If this fails, the unassigned check will make the handler return early. */ + (void)k_work_cancel_delayable(&frnd->clear.timer); frnd->clear.frnd = BT_MESH_ADDR_UNASSIGNED; return 0; @@ -1159,7 +1165,8 @@ static void buf_send_end(int err, void *user_data) } if (frnd->established) { - k_work_reschedule(&frnd->timer, frnd->poll_to); + /* Always restart poll timeout timer after sending */ + k_work_reschedule(&frnd->timer, K_MSEC(frnd->poll_to)); BT_DBG("Waiting %u ms for next poll", (unsigned) frnd->poll_to); } else { @@ -1211,6 +1218,10 @@ static void friend_timeout(struct ble_npl_event *work) uint8_t md; + if (!friend_is_allocated(frnd)) { + return; + } + __ASSERT_NO_MSG(frnd->pending_buf == 0); BT_DBG("lpn 0x%04x send_last %u last %p", frnd->lpn, diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index 4c102f7a8c..e8d3c471d4 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -856,6 +856,10 @@ void bt_mesh_net_recv(struct os_mbuf *data, int8_t rssi, static void ivu_refresh(struct ble_npl_event *work) { + if (!bt_mesh_is_provisioned()) { + return; + } + bt_mesh.ivu_duration = MIN(UINT8_MAX, bt_mesh.ivu_duration + BT_MESH_IVU_HOURS); From a5d34c82e42f8cf5d5516e64f314f36c73b4b43f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 08:22:51 +0200 Subject: [PATCH 0090/1333] host/mesh: Mesh: pb_adv: update delayable work Switch to the new API. Consolidates reliable sending logic for the first transmission and the retransmit into one. Adds check for link active in protocol timeout. This is port of 45e5914ce90bdb424aa16c5e87cbe1a0f16c5b82 --- nimble/host/mesh/src/pb_adv.c | 43 +++++++++++++++++------------------ 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/nimble/host/mesh/src/pb_adv.c b/nimble/host/mesh/src/pb_adv.c index 1fa4c8e996..eed19eacc9 100644 --- a/nimble/host/mesh/src/pb_adv.c +++ b/nimble/host/mesh/src/pb_adv.c @@ -181,7 +181,12 @@ static void prov_clear_tx(void) { BT_DBG(""); - k_work_cancel_delayable(&link.tx.retransmit); + /* If this fails, the work handler will not find any buffers to send, + * and return without rescheduling. The work handler also checks the + * LINK_ACTIVE flag, so if this call is part of reset_adv_link, it'll + * exit early. + */ + (void)k_work_cancel_delayable(&link.tx.retransmit); free_segments(); } @@ -191,7 +196,10 @@ static void reset_adv_link(void) BT_DBG(""); prov_clear_tx(); - k_work_cancel_delayable(&link.prot_timer); + /* If this fails, the work handler will exit early on the LINK_ACTIVE + * check. + */ + (void)k_work_cancel_delayable(&link.prot_timer); if (atomic_test_bit(link.flags, ADV_PROVISIONER)) { /* Clear everything except the retransmit and protocol timer @@ -279,6 +287,10 @@ static void prov_msg_recv(void) static void protocol_timeout(struct ble_npl_event *work) { + if (!atomic_test_bit(link.flags, ADV_LINK_ACTIVE)) { + return; + } + BT_DBG(""); link.rx.seg = 0U; @@ -553,6 +565,12 @@ static void send_reliable(void) break; } + if (BT_MESH_ADV(buf)->busy) { + continue; + } + + BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + if (i + 1 < ARRAY_SIZE(link.tx.buf) && link.tx.buf[i + 1]) { bt_mesh_adv_send(buf, NULL, NULL); } else { @@ -564,7 +582,6 @@ static void send_reliable(void) static void prov_retransmit(struct ble_npl_event *work) { int32_t timeout_ms; - int i; BT_DBG(""); @@ -595,25 +612,7 @@ static void prov_retransmit(struct ble_npl_event *work) return; } - for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) { - struct os_mbuf *buf = link.tx.buf[i]; - - if (!buf) { - break; - } - - if (BT_MESH_ADV(buf)->busy) { - continue; - } - - BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); - - if (i + 1 < ARRAY_SIZE(link.tx.buf) && link.tx.buf[i + 1]) { - bt_mesh_adv_send(buf, NULL, NULL); - } else { - bt_mesh_adv_send(buf, &buf_sent_cb, NULL); - } - } + send_reliable(); } static int bearer_ctl_send(uint8_t op, const void *data, uint8_t data_len, From ee0dc5e70d7cb0696bdf7f37f3741b54fa763b9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 08:25:17 +0200 Subject: [PATCH 0091/1333] host/mesh: pb_gatt: update delayable work Switch to the new API. Adds a link check to the protocol timeout to ensure the link is still active. This is port of 3cba9613a43a7026104ba338666c6b61c41037e7 --- nimble/host/mesh/src/pb_gatt.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/pb_gatt.c b/nimble/host/mesh/src/pb_gatt.c index c358e2e43e..bd119c15ef 100644 --- a/nimble/host/mesh/src/pb_gatt.c +++ b/nimble/host/mesh/src/pb_gatt.c @@ -36,7 +36,8 @@ static void reset_state(void) { link.conn_handle = BLE_HS_CONN_HANDLE_NONE; - k_work_cancel_delayable(&link.prot_timer); + /* If this fails, the protocol timeout handler will exit early. */ + (void)k_work_cancel_delayable(&link.prot_timer); link.rx.buf = bt_mesh_proxy_get_buf(); } @@ -54,6 +55,11 @@ static void link_closed(enum prov_bearer_link_status status) static void protocol_timeout(struct ble_npl_event *work) { + if (!link.conn_handle) { + /* Already disconnected */ + return; + } + BT_DBG("Protocol timeout"); link_closed(PROV_BEARER_LINK_STATUS_TIMEOUT); From 3918bd9e9cf135cab2ff173a584e80daa2f8497f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 08:30:39 +0200 Subject: [PATCH 0092/1333] host/mesh: proxy: update delayable work Switch to the new API. Adds check for a pending buffer in the SAR timeout handler. This is port of 1577fec8511d18778e39e0edb952cf468ff0735c --- nimble/host/mesh/src/proxy.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/nimble/host/mesh/src/proxy.c b/nimble/host/mesh/src/proxy.c index 515d86e8c3..042c1f6c9b 100644 --- a/nimble/host/mesh/src/proxy.c +++ b/nimble/host/mesh/src/proxy.c @@ -424,17 +424,21 @@ static void proxy_sar_timeout(struct ble_npl_event *work) { struct bt_mesh_proxy_client *client; int rc; - - BT_WARN("Proxy SAR timeout"); - client = ble_npl_event_get_arg(work); - assert(client != NULL); - if ((client->conn_handle != BLE_HS_CONN_HANDLE_NONE)) { - rc = ble_gap_terminate(client->conn_handle, - BLE_ERR_REM_USER_CONN_TERM); - assert(rc == 0); + if (!client->conn_handle) { + return; } + + if (!client->buf->om_len) { + BT_DBG("No pending Proxy SAR message"); + return; + } + + BT_WARN("Proxy SAR timeout"); + rc = ble_gap_terminate(client->conn_handle, + BLE_ERR_REM_USER_CONN_TERM); + assert(rc == 0); } void bt_mesh_proxy_beacon_send(struct bt_mesh_subnet *sub) @@ -599,7 +603,10 @@ static int proxy_recv(uint16_t conn_handle, uint16_t attr_handle, return -EINVAL; } - k_work_cancel_delayable(&client->sar_timer); + /* If this fails, the work handler exits early, as there's no + * active SAR buffer. + */ + (void)k_work_cancel_delayable(&client->sar_timer); net_buf_simple_add_mem(client->buf, data + 1, len - 1); proxy_complete_pdu(client); break; @@ -661,7 +668,10 @@ static void proxy_disconnected(uint16_t conn_handle, int reason) bt_mesh_pb_gatt_close(conn_handle); } - k_work_cancel_delayable(&client->sar_timer); + /* If this fails, the work handler exits early, as + * there's no active connection. + */ + (void)k_work_cancel_delayable(&client->sar_timer); client->conn_handle = BLE_HS_CONN_HANDLE_NONE; break; } From 5af4b9d4c48c800b8ce2da2595de37e08a3a57b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 08:40:47 +0200 Subject: [PATCH 0093/1333] host/mesh: transport: update delayable work Switch to the new API. Adds early exits for the ack and retransmit timers, and replaces a remaining_time() + submit() call with schedule(). This is port of 4e6cb116f87bb2ff0ece7d8f968adac4dd2c9b3d --- nimble/host/mesh/src/transport.c | 45 +++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/nimble/host/mesh/src/transport.c b/nimble/host/mesh/src/transport.c index aae72bf378..b1d41dbf53 100644 --- a/nimble/host/mesh/src/transport.c +++ b/nimble/host/mesh/src/transport.c @@ -256,7 +256,8 @@ static void seg_tx_reset(struct seg_tx *tx) { int i; - k_work_cancel_delayable(&tx->retransmit); + /* If this call fails, the handler will exit early, as nack_count is 0. */ + (void)k_work_cancel_delayable(&tx->retransmit); tx->cb = NULL; tx->cb_data = NULL; @@ -318,7 +319,8 @@ static void schedule_retransmit(struct seg_tx *tx) * retransmit immediately, as we just freed up a tx buffer. */ k_work_reschedule(&tx->retransmit, - tx->seg_o ? 0 : K_MSEC(SEG_RETRANSMIT_TIMEOUT(tx))); + tx->seg_o ? K_NO_WAIT : + K_MSEC(SEG_RETRANSMIT_TIMEOUT(tx))); } static void seg_send_start(uint16_t duration, int err, void *user_data) @@ -440,7 +442,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) end: if (!tx->seg_pending) { k_work_reschedule(&tx->retransmit, - SEG_RETRANSMIT_TIMEOUT(tx)); + K_MSEC(SEG_RETRANSMIT_TIMEOUT(tx))); } tx->sending = 0U; @@ -860,8 +862,6 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, return -EINVAL; } - k_work_cancel_delayable(&tx->retransmit); - while ((bit = find_lsb_set(ack))) { if (tx->seg[bit - 1]) { BT_DBG("seg %u/%u acked", bit - 1, tx->seg_n); @@ -872,7 +872,11 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, } if (tx->nack_count) { - seg_tx_send_unacked(tx); + /* According to the Bluetooth Mesh Profile specification, + * section 3.5.3.3, we should reset the retransmit timer and + * retransmit immediately when receiving a valid ack message: + */ + k_work_reschedule(&tx->retransmit, K_NO_WAIT); } else { BT_DBG("SDU TX complete"); seg_tx_complete(tx, 0); @@ -1094,7 +1098,10 @@ static void seg_rx_reset(struct seg_rx *rx, bool full_reset) BT_DBG("rx %p", rx); - k_work_cancel_delayable(&rx->ack); + /* If this fails, the handler will exit early on the next execution, as + * it checks rx->in_use. + */ + (void)k_work_cancel_delayable(&rx->ack); if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && rx->obo && rx->block != BLOCK_COMPLETE(rx->seg_n)) { @@ -1131,6 +1138,16 @@ static void seg_ack(struct ble_npl_event *work) struct seg_rx *rx = ble_npl_event_get_arg(work); int32_t timeout; + if (!rx->in_use || rx->block == BLOCK_COMPLETE(rx->seg_n)) { + /* Cancellation of this timer may have failed. If it fails as + * part of seg_reset, in_use will be false. + * If it fails as part of the processing of a fully received + * SDU, the ack is already being sent from the receive handler, + * and the timer based ack sending can be ignored. + */ + return; + } + BT_DBG("rx %p", rx); if (k_uptime_get_32() - rx->last > K_SECONDS(60)) { @@ -1148,7 +1165,7 @@ static void seg_ack(struct ble_npl_event *work) rx->block, rx->obo); timeout = ack_timeout(rx); - k_work_reschedule(&rx->ack, K_MSEC(timeout)); + k_work_schedule(&rx->ack, K_MSEC(timeout)); } static inline bool sdu_len_is_ok(bool ctl, uint8_t seg_n) @@ -1453,11 +1470,10 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx, /* Reset the Incomplete Timer */ rx->last = k_uptime_get_32(); - if (!k_work_delayable_remaining_get(&rx->ack) && - !bt_mesh_lpn_established()) { + if (!bt_mesh_lpn_established()) { int32_t timeout = ack_timeout(rx); - - k_work_reschedule(&rx->ack, K_MSEC(timeout)); + /* Should only start ack timer if it isn't running already: */ + k_work_schedule(&rx->ack, K_MSEC(timeout)); } /* Allocated segment here */ @@ -1494,7 +1510,10 @@ static int trans_seg(struct os_mbuf *buf, struct bt_mesh_net_rx *net_rx, *pdu_type = BT_MESH_FRIEND_PDU_COMPLETE; - k_work_cancel_delayable(&rx->ack); + /* If this fails, the work handler will either exit early because the + * block is fully received, or rx->in_use is false. + */ + (void)k_work_cancel_delayable(&rx->ack); send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr, net_rx->ctx.send_ttl, seq_auth, rx->block, rx->obo); From 7d0aa8d6e3f3cfb6f57a27c8356b423feeb52071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 08:43:37 +0200 Subject: [PATCH 0094/1333] host/mesh: Allow to be NODE when PROVISIONER is enabled When PROVISIONER and CDB is enabled then IUT couldn't be a NODE. This patch fixes this by not returning an error when CDB is not configured. This is useful especially in testing environment, when all the features are compiled in and we can choose role in runtime. This is port of b9c8d270ab642ae18c83aad66ab5e1d962de74d3 --- nimble/host/mesh/src/mesh.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c index ae01888351..4ff992d53c 100644 --- a/nimble/host/mesh/src/mesh.c +++ b/nimble/host/mesh/src/mesh.c @@ -69,18 +69,12 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, * FIXME: * Should net_key and iv_index be over-ridden? */ - if (IS_ENABLED(BLE_MESH_CDB)) { + if (IS_ENABLED(CONFIG_BT_MESH_CDB) && + atomic_test_bit(bt_mesh_cdb.flags, BT_MESH_CDB_VALID)) { const struct bt_mesh_comp *comp; const struct bt_mesh_prov *prov; struct bt_mesh_cdb_node *node; - if (!atomic_test_bit(bt_mesh_cdb.flags, - BT_MESH_CDB_VALID)) { - BT_ERR("No valid network"); - atomic_clear_bit(bt_mesh.flags, BT_MESH_VALID); - return -EINVAL; - } - comp = bt_mesh_comp_get(); if (comp == NULL) { BT_ERR("Failed to get node composition"); From 517f819191529f6ee25fd7f62a64d5a47b872b0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 11:24:36 +0200 Subject: [PATCH 0095/1333] host/mesh: Add option to include bt name in scan rsp Sometimes it may be needed to know device name when proxy feature is enabled. This commit adds an option to include device name in scan response. This is port of a335c755a70fd279a221a24fa944ea21d231bad4 --- nimble/host/mesh/src/proxy.c | 71 +++++++++++++++++++++++++++++------- nimble/host/mesh/syscfg.yml | 6 +++ 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/nimble/host/mesh/src/proxy.c b/nimble/host/mesh/src/proxy.c index 042c1f6c9b..44c3376a0e 100644 --- a/nimble/host/mesh/src/proxy.c +++ b/nimble/host/mesh/src/proxy.c @@ -88,19 +88,27 @@ ble_uuid16_t BT_UUID_MESH_PROXY_DATA_OUT = BLE_UUID16_INIT(0x2ade); #define CLIENT_BUF_SIZE 65 -static const struct ble_gap_adv_params slow_adv_param = { - .conn_mode = (BLE_GAP_CONN_MODE_UND), +#if MYNEWT_VAL(BLE_MESH_PROXY_USE_DEVICE_NAME) +#define ADV_OPT_USE_NAME BT_LE_ADV_OPT_USE_NAME +#else +#define ADV_OPT_USE_NAME 0 +#endif + +#define ADV_OPT_PROV \ + .conn_mode = (BLE_GAP_CONN_MODE_UND), \ .disc_mode = (BLE_GAP_DISC_MODE_GEN), - .itvl_min = BT_GAP_ADV_SLOW_INT_MIN, - .itvl_max = BT_GAP_ADV_SLOW_INT_MAX, -}; -static const struct ble_gap_adv_params fast_adv_param = { - .conn_mode = (BLE_GAP_CONN_MODE_UND), +#define ADV_OPT_PROXY \ + .conn_mode = (BLE_GAP_CONN_MODE_UND), \ .disc_mode = (BLE_GAP_DISC_MODE_GEN), - .itvl_min = BT_GAP_ADV_FAST_INT_MIN_2, + +#define ADV_SLOW_INT \ + .itvl_min = BT_GAP_ADV_SLOW_INT_MIN, \ + .itvl_max = BT_GAP_ADV_SLOW_INT_MAX, + +#define ADV_FAST_INT \ + .itvl_min = BT_GAP_ADV_FAST_INT_MIN_2, \ .itvl_max = BT_GAP_ADV_FAST_INT_MAX_2, -}; static bool proxy_adv_enabled; @@ -1123,6 +1131,21 @@ static const struct bt_data net_id_ad[] = { static int node_id_adv(struct bt_mesh_subnet *sub) { + struct ble_gap_adv_params fast_adv_param = { + ADV_OPT_PROXY + ADV_FAST_INT + }; +#if ADV_OPT_USE_NAME + const char *name = CONFIG_BT_DEVICE_NAME; + size_t name_len = strlen(name); + struct bt_data sd = { + .type = BT_DATA_NAME_COMPLETE, + .data_len = name_len, + .data = (void *)name + }; +#else + struct bt_data *sd = NULL; +#endif uint8_t tmp[16]; int err; @@ -1148,7 +1171,7 @@ static int node_id_adv(struct bt_mesh_subnet *sub) memcpy(proxy_svc_data + 3, tmp + 8, 8); err = bt_le_adv_start(&fast_adv_param, node_id_ad, - ARRAY_SIZE(node_id_ad), NULL, 0); + ARRAY_SIZE(node_id_ad), sd, 0); if (err) { BT_WARN("Failed to advertise using Node ID (err %d)", err); return err; @@ -1161,6 +1184,21 @@ static int node_id_adv(struct bt_mesh_subnet *sub) static int net_id_adv(struct bt_mesh_subnet *sub) { + struct ble_gap_adv_params slow_adv_param = { + ADV_OPT_PROXY + ADV_SLOW_INT + }; +#if ADV_OPT_USE_NAME + const char *name = CONFIG_BT_DEVICE_NAME; + size_t name_len = strlen(name); + struct bt_data sd = { + .type = BT_DATA_NAME_COMPLETE, + .data_len = name_len, + .data = (void *)name + }; +#else + struct bt_data *sd = NULL; +#endif int err; BT_DBG(""); @@ -1171,9 +1209,8 @@ static int net_id_adv(struct bt_mesh_subnet *sub) bt_hex(sub->keys[SUBNET_KEY_TX_IDX(sub)].net_id, 8)); memcpy(proxy_svc_data + 3, sub->keys[SUBNET_KEY_TX_IDX(sub)].net_id, 8); - err = bt_le_adv_start(&slow_adv_param, net_id_ad, - ARRAY_SIZE(net_id_ad), NULL, 0); + ARRAY_SIZE(net_id_ad), sd, 0); if (err) { BT_WARN("Failed to advertise using Network ID (err %d)", err); return err; @@ -1360,12 +1397,20 @@ int32_t bt_mesh_proxy_adv_start(void) #if (MYNEWT_VAL(BLE_MESH_PB_GATT)) if (!bt_mesh_is_provisioned()) { const struct ble_gap_adv_params *param; - struct bt_data prov_sd[2]; + struct ble_gap_adv_params fast_adv_param = { + ADV_OPT_PROV + ADV_FAST_INT + }; + struct bt_data prov_sd[1]; size_t prov_sd_len; if (prov_fast_adv) { param = &fast_adv_param; } else { + struct ble_gap_adv_params slow_adv_param = { + ADV_OPT_PROV + ADV_SLOW_INT + }; param = &slow_adv_param; } diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index 99b18c2056..241ea8f276 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -136,6 +136,12 @@ syscfg.defs: node supports. value: 1 + BLE_MESH_PROXY_USE_DEVICE_NAME: + description: > + Include Bluetooth device name in scan response + value: 0 + restrictions: BLE_MESH_GATT_PROXY + BLE_MESH_SUBNET_COUNT: description: > This option specifies how many subnets a Mesh network can From cf8f35298817f3434bc4fe8bb00687583dda8fd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 11:30:19 +0200 Subject: [PATCH 0096/1333] host/mesh: Fix incorrect flag check in mesh settings This bug was introduced in PR #31176, where setting's flags were moved out from bt_mesh.flags to pending_flags. This is port of 3ae0f96acb67aafe1e13a545e7a1b86159103733 --- nimble/host/mesh/src/settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/settings.c b/nimble/host/mesh/src/settings.c index 19a9c3f87a..3c74c3863c 100644 --- a/nimble/host/mesh/src/settings.c +++ b/nimble/host/mesh/src/settings.c @@ -105,7 +105,7 @@ void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag) timeout_ms = 0; } else if (atomic_test_bit(pending_flags, BT_MESH_SETTINGS_RPL_PENDING) && - (!(atomic_get(bt_mesh.flags) & GENERIC_PENDING_BITS) || + (!(atomic_get(pending_flags) & GENERIC_PENDING_BITS) || (CONFIG_BT_MESH_RPL_STORE_TIMEOUT < CONFIG_BT_MESH_STORE_TIMEOUT))) { timeout_ms = CONFIG_BT_MESH_RPL_STORE_TIMEOUT * MSEC_PER_SEC; From 373a6fb5c3b4dc96f46fc3f2b969eb49e179cb4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 11:31:40 +0200 Subject: [PATCH 0097/1333] host/mesh: Add VA flag to generic pending flags This adds BT_MESH_SETTINGS_VA_PENDING to GENERIC_PENDING_BITS as it should be stored by CONFIG_BT_MESH_STORE_TIMEOUT. This is port of 22fabefdf2c112d4d5bfe214ddf512bb41ada6e9 --- nimble/host/mesh/src/settings.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/settings.c b/nimble/host/mesh/src/settings.c index 3c74c3863c..b8938d4543 100644 --- a/nimble/host/mesh/src/settings.c +++ b/nimble/host/mesh/src/settings.c @@ -93,7 +93,8 @@ static int mesh_commit(void) BIT(BT_MESH_SETTINGS_APP_KEYS_PENDING) | \ BIT(BT_MESH_SETTINGS_HB_PUB_PENDING) | \ BIT(BT_MESH_SETTINGS_CFG_PENDING) | \ - BIT(BT_MESH_SETTINGS_MOD_PENDING)) + BIT(BT_MESH_SETTINGS_MOD_PENDING) | \ + BIT(BT_MESH_SETTINGS_VA_PENDING)) void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag) { From 452d1a5543a20b3507ad61b5ac705c92ed61f0ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 11:38:10 +0200 Subject: [PATCH 0098/1333] host/mesh: Change friend_cred decision point to friend selection The network layer previously decided to use the friend credentials if there was an established friendship. During the friendship setup phase, the friendship is not considered established until the LPN receives the first friend poll. Before this happens, the LPN should send a friend poll message, encrypted with the friendship credentials. This wrongly gets encrypted with the master credentials. Change the decision point to whether the LPN has selected a friend, which happens after the friend offer, and before the friend poll. This will remain set for the duration of the friendship. This is port of 878043aff19c1c7468a55fa332fa695fbb6bf154 --- nimble/host/mesh/src/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index e8d3c471d4..f1e44b0503 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -389,7 +389,7 @@ static void bt_mesh_net_local(struct ble_npl_event *work) static const struct bt_mesh_net_cred *net_tx_cred_get(struct bt_mesh_net_tx *tx) { #if IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) - if (tx->friend_cred && bt_mesh_lpn_established()) { + if (tx->friend_cred && bt_mesh.lpn.frnd) { return &bt_mesh.lpn.cred[SUBNET_KEY_TX_IDX(tx->sub)]; } #endif From 03076b3eb9f5c9de73542fe7adc64165ce73d50c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 11:39:42 +0200 Subject: [PATCH 0099/1333] host/mesh: Pass correct pointer to publish_sent This commit fixes a bug where incorrect pointer passed to publish_sent in access.c caused bus fault. This is port of 8717a0f6787421c0adb566a6b20495a34f76f1d5 --- nimble/host/mesh/src/access.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index 1c34b2ec2a..85717aa51b 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -215,7 +215,7 @@ static int pub_period_start(struct bt_mesh_model_pub *pub) BT_DBG("Update failed, skipping publish (err: %d)", err); pub->count = 0; pub->period_start = k_uptime_get_32(); - publish_sent(err, pub); + publish_sent(err, pub->mod); return err; } From 275ea539a85daafba2b941fe89e4ede11b064526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 12:07:14 +0200 Subject: [PATCH 0100/1333] host/mesh: Remove outated RPL entry from persistent storage This commit fixes a bug where outdated RPL entries might not be removed properly from the persistent storage making those entries dead. This is port of 1b129c50c2fdb4d7e8a270356dd5fba623deb1cc --- nimble/host/mesh/src/rpl.c | 59 +++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/nimble/host/mesh/src/rpl.c b/nimble/host/mesh/src/rpl.c index 3c4045ca5b..b767752c86 100644 --- a/nimble/host/mesh/src/rpl.c +++ b/nimble/host/mesh/src/rpl.c @@ -32,6 +32,27 @@ static inline int rpl_idx(const struct bt_mesh_rpl *rpl) return rpl - &replay_list[0]; } +static void clear_rpl(struct bt_mesh_rpl *rpl) +{ + int err; + char path[18]; + + if (!rpl->src) { + return; + } + + snprintk(path, sizeof(path), "bt_mesh/RPL/%x", rpl->src); + err = settings_save_one(path, NULL); + if (err) { + BT_ERR("Failed to clear RPL"); + } else { + BT_DBG("Cleared RPL"); + } + + (void)memset(rpl, 0, sizeof(*rpl)); + atomic_clear_bit(store, rpl_idx(rpl)); +} + static void schedule_rpl_store(struct bt_mesh_rpl *entry) { atomic_set_bit(store, rpl_idx(entry)); @@ -171,13 +192,16 @@ void bt_mesh_rpl_reset(void) if (rpl->src) { if (rpl->old_iv) { - (void)memset(rpl, 0, sizeof(*rpl)); + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + clear_rpl(rpl); + } else { + (void)memset(rpl, 0, sizeof(*rpl)); + } } else { rpl->old_iv = true; - } - - if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - schedule_rpl_store(rpl); + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + schedule_rpl_store(rpl); + } } } } @@ -246,6 +270,10 @@ static void store_rpl(struct bt_mesh_rpl *entry) char *str; int err; + if (!entry->src) { + return; + } + BT_DBG("src 0x%04x seq 0x%06x old_iv %u", entry->src, (unsigned) entry->seq, entry->old_iv); @@ -269,27 +297,6 @@ static void store_rpl(struct bt_mesh_rpl *entry) } } -static void clear_rpl(struct bt_mesh_rpl *rpl) -{ - int err; - char path[18]; - - if (!rpl->src) { - return; - } - - snprintk(path, sizeof(path), "bt_mesh/RPL/%x", rpl->src); - err = settings_save_one(path, NULL); - if (err) { - BT_ERR("Failed to clear RPL"); - } else { - BT_DBG("Cleared RPL"); - } - - (void)memset(rpl, 0, sizeof(*rpl)); - atomic_clear_bit(store, rpl_idx(rpl)); -} - static void store_pending_rpl(struct bt_mesh_rpl *rpl) { BT_DBG(""); From e9567a603483f44a54b59917e9adafea4a15710f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 12:08:55 +0200 Subject: [PATCH 0101/1333] host/mesh: Don't reset PB ADV reliable timer on retransmit The send_reliable function was reused in multiple places as part of the k_delayed_work changes for Bluetooth Mesh in #33782. This function contains a line that resets the start timer, causing prov_retransmit to continously move the goal post for when to give up sending. Extract this line out of the send_reliable function, and put it along with the other link.tx initialization in bearer_ctl_send and prov_send_adv. This is port of 85ad497c39ecf6d12bea31241d774cf300d620c2 --- nimble/host/mesh/src/pb_adv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/host/mesh/src/pb_adv.c b/nimble/host/mesh/src/pb_adv.c index eed19eacc9..405a1530a9 100644 --- a/nimble/host/mesh/src/pb_adv.c +++ b/nimble/host/mesh/src/pb_adv.c @@ -556,8 +556,6 @@ static void send_reliable(void) { int i; - link.tx.start = k_uptime_get(); - for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) { struct os_mbuf *buf = link.tx.buf[i]; @@ -638,6 +636,7 @@ static int bearer_ctl_send(uint8_t op, const void *data, uint8_t data_len, net_buf_add_mem(buf, data, data_len); if (reliable) { + link.tx.start = k_uptime_get(); link.tx.buf[0] = buf; send_reliable(); } else { @@ -673,6 +672,7 @@ static int prov_send_adv(struct os_mbuf *msg, link.tx.buf[0] = start; link.tx.cb = cb; link.tx.cb_data = cb_data; + link.tx.start = k_uptime_get(); BT_DBG("xact_id: 0x%x len: %u", link.tx.id, msg->om_len); From 026cbf947c9813fc0cec9fd148c7db3dcbc7d437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 12:10:24 +0200 Subject: [PATCH 0102/1333] host/mesh: Reject identical public keys This commit address Erratum E10395 and Errata Correction E16350 to ensure that public keys exchanged between Provisioner and a device aren't identical. This is port of 33fafe1e2f41e5b61b1dc71f9ad0d8cb0930607f --- nimble/host/mesh/src/provisioner.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/provisioner.c b/nimble/host/mesh/src/provisioner.c index 3b4b76598d..9e8df89375 100644 --- a/nimble/host/mesh/src/provisioner.c +++ b/nimble/host/mesh/src/provisioner.c @@ -385,8 +385,11 @@ static void prov_dh_key_cb(const uint8_t dhkey[32]) static void prov_dh_key_gen(void) { - uint8_t remote_pk_le[64], *remote_pk; + uint8_t remote_pk_le[64]; + const uint8_t *remote_pk; + const uint8_t *local_pk; + local_pk = &bt_mesh_prov_link.conf_inputs[17]; remote_pk = &bt_mesh_prov_link.conf_inputs[81]; /* Copy remote key in little-endian for bt_dh_key_gen(). @@ -396,6 +399,12 @@ static void prov_dh_key_gen(void) sys_memcpy_swap(remote_pk_le, remote_pk, 32); sys_memcpy_swap(&remote_pk_le[32], &remote_pk[32], 32); + if (!memcmp(local_pk, remote_pk, 64)) { + BT_ERR("Public keys are identical"); + prov_fail(PROV_ERR_NVAL_FMT); + return; + } + if (bt_dh_key_gen(remote_pk_le, prov_dh_key_cb)) { BT_ERR("Failed to generate DHKey"); prov_fail(PROV_ERR_UNEXP_ERR); From 9e4cd9ae78002c1de84667b6969447ce8c5de722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 12:36:02 +0200 Subject: [PATCH 0103/1333] host/mesh: Add OOB Public Key support for provisionee role This commit allows an unprovisioned device to exchange its public key using out-of-band techology (see MeshPRFv1.0.1, table 5.19 and section 5.4.2.3). For in-band public key exchange, the mesh stack uses HCI commands to generate public and private keys, and DH key. This, however, doesn't work for OOB public key exchange since there is no command to generate DH key with a private key provided by an application. Therefore, this commit adds direct usage of TinyCrypto into the mesh stack for DH key generation for OOB public key support. This is port of 0335d5fb0147b70f31a5f05c0d776adfff04ccc4 --- nimble/host/mesh/include/mesh/main.h | 17 ++++++ nimble/host/mesh/src/prov.h | 1 + nimble/host/mesh/src/prov_device.c | 84 +++++++++++++++++++++++----- nimble/host/mesh/syscfg.yml | 5 ++ 4 files changed, 92 insertions(+), 15 deletions(-) diff --git a/nimble/host/mesh/include/mesh/main.h b/nimble/host/mesh/include/mesh/main.h index 2bcb05c830..213950b17b 100644 --- a/nimble/host/mesh/include/mesh/main.h +++ b/nimble/host/mesh/include/mesh/main.h @@ -101,6 +101,23 @@ struct bt_mesh_prov { /** Out of Band information field. */ bt_mesh_prov_oob_info_t oob_info; + /** Pointer to Public Key in big-endian for OOB public key type support. + * + * Remember to enable @option{CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY} + * when initializing this parameter. + * + * Must be used together with @ref bt_mesh_prov::private_key_be. + */ + const uint8_t *public_key_be; + /** Pointer to Private Key in big-endian for OOB public key type support. + * + * Remember to enable @option{CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY} + * when initializing this parameter. + * + * Must be used together with @ref bt_mesh_prov::public_key_be. + */ + const uint8_t *private_key_be; + /** Static OOB value */ const uint8_t *static_val; /** Static OOB value length */ diff --git a/nimble/host/mesh/src/prov.h b/nimble/host/mesh/src/prov.h index 89f027256a..d300b1d5c6 100644 --- a/nimble/host/mesh/src/prov.h +++ b/nimble/host/mesh/src/prov.h @@ -75,6 +75,7 @@ enum { WAIT_CONFIRM, /* Wait for send confirm */ WAIT_AUTH, /* Wait for auth response */ OOB_STATIC_KEY, /* OOB Static Authentication */ + WAIT_DH_KEY, /* Wait for DH Key */ NUM_FLAGS, }; diff --git a/nimble/host/mesh/src/prov_device.c b/nimble/host/mesh/src/prov_device.c index 38a96e7a6b..b7828fa311 100644 --- a/nimble/host/mesh/src/prov_device.c +++ b/nimble/host/mesh/src/prov_device.c @@ -76,8 +76,9 @@ static void prov_invite(const uint8_t *data) /* Supported algorithms - FIPS P-256 Eliptic Curve */ net_buf_simple_add_be16(buf, BIT(PROV_ALG_P256)); - /* Public Key Type, Only "No OOB" Public Key is supported */ - net_buf_simple_add_u8(buf, PUB_KEY_NO_OOB); + /* Public Key Type */ + net_buf_simple_add_u8(buf, + bt_mesh_prov->public_key_be == NULL ? PUB_KEY_NO_OOB : PUB_KEY_OOB); /* Static OOB Type */ net_buf_simple_add_u8(buf, bt_mesh_prov->static_val ? BIT(0) : 0x00); @@ -118,12 +119,16 @@ static void prov_start(const uint8_t *data) return; } - if (data[1] != PUB_KEY_NO_OOB) { + if (data[1] == PUB_KEY_OOB && + !(MYNEWT_VAL(BLE_MESH_PROV_OOB_PUBLIC_KEY) && + bt_mesh_prov->public_key_be)) { BT_ERR("Invalid public key type: 0x%02x", data[1]); prov_fail(PROV_ERR_NVAL_FMT); return; } + atomic_set_bit_to(bt_mesh_prov_link.flags, OOB_PUB_KEY, data[1] == PUB_KEY_OOB); + memcpy(&bt_mesh_prov_link.conf_inputs[12], data, 5); bt_mesh_prov_link.expect = PROV_PUB_KEY; @@ -216,6 +221,16 @@ static void public_key_sent(int err, void *cb_data) } } +static void start_auth(void) +{ + if (atomic_test_bit(bt_mesh_prov_link.flags, WAIT_NUMBER) || + atomic_test_bit(bt_mesh_prov_link.flags, WAIT_STRING)) { + bt_mesh_prov_link.expect = PROV_NO_PDU; /* Wait for input */ + } else { + bt_mesh_prov_link.expect = PROV_CONFIRM; + } +} + static void send_pub_key(void) { struct os_mbuf *buf = PROV_BUF(65); @@ -244,11 +259,18 @@ static void send_pub_key(void) return; } - if (atomic_test_bit(bt_mesh_prov_link.flags, WAIT_NUMBER) || - atomic_test_bit(bt_mesh_prov_link.flags, WAIT_STRING)) { - bt_mesh_prov_link.expect = PROV_NO_PDU; /* Wait for input */ - } else { - bt_mesh_prov_link.expect = PROV_CONFIRM; + start_auth(); +} + +static void dh_key_gen_complete(void) +{ + BT_DBG("DHkey: %s", bt_hex(bt_mesh_prov_link.dhkey, 32)); + + if (!atomic_test_and_clear_bit(bt_mesh_prov_link.flags, WAIT_DH_KEY) && + atomic_test_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY)) { + send_confirm(); + } else if (!atomic_test_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY)) { + send_pub_key(); } } @@ -264,16 +286,31 @@ static void prov_dh_key_cb(const uint8_t dhkey[32]) sys_memcpy_swap(bt_mesh_prov_link.dhkey, dhkey, 32); - BT_DBG("DHkey: %s", bt_hex(bt_mesh_prov_link.dhkey, 32)); - - send_pub_key(); + dh_key_gen_complete(); } static void prov_dh_key_gen(void) { - uint8_t remote_pk_le[64], *remote_pk; + const uint8_t *remote_pk; + uint8_t remote_pk_le[64]; remote_pk = &bt_mesh_prov_link.conf_inputs[17]; + if (MYNEWT_VAL(BLE_MESH_PROV_OOB_PUBLIC_KEY) && + atomic_test_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY)) { + if (uECC_valid_public_key(remote_pk, &curve_secp256r1)) { + BT_ERR("Public key is not valid"); + } else if (uECC_shared_secret(remote_pk, bt_mesh_prov->private_key_be, + bt_mesh_prov_link.dhkey, + &curve_secp256r1) != TC_CRYPTO_SUCCESS) { + BT_ERR("DHKey generation failed"); + } else { + dh_key_gen_complete(); + return; + } + + prov_fail(PROV_ERR_UNEXP_ERR); + return; + } /* Copy remote key in little-endian for bt_dh_key_gen(). * X and Y halves are swapped independently. The bt_dh_key_gen() @@ -295,7 +332,21 @@ static void prov_pub_key(const uint8_t *data) /* PublicKeyProvisioner */ memcpy(&bt_mesh_prov_link.conf_inputs[17], data, 64); - if (!bt_pub_key_get()) { + if (MYNEWT_VAL(BLE_MESH_PROV_OOB_PUBLIC_KEY) && + atomic_test_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY)) { + if (!bt_mesh_prov->public_key_be || !bt_mesh_prov->private_key_be) { + BT_ERR("Public or private key is not ready"); + prov_fail(PROV_ERR_UNEXP_ERR); + return; + } + + /* No swap needed since user provides public key in big-endian */ + memcpy(&bt_mesh_prov_link.conf_inputs[81], bt_mesh_prov->public_key_be, 64); + + atomic_set_bit(bt_mesh_prov_link.flags, WAIT_DH_KEY); + + start_auth(); + } else if (!bt_pub_key_get()) { /* Clear retransmit timer */ bt_mesh_prov_link.bearer->clear_tx(); atomic_set_bit(bt_mesh_prov_link.flags, WAIT_PUB_KEY); @@ -390,7 +441,9 @@ static void prov_confirm(const uint8_t *data) notify_input_complete(); - send_confirm(); + if (!atomic_test_and_clear_bit(bt_mesh_prov_link.flags, WAIT_DH_KEY)) { + send_confirm(); + } } static inline bool is_pb_gatt(void) @@ -492,7 +545,8 @@ static void prov_data(const uint8_t *data) static void local_input_complete(void) { - if (atomic_test_bit(bt_mesh_prov_link.flags, PUB_KEY_SENT)) { + if (atomic_test_bit(bt_mesh_prov_link.flags, PUB_KEY_SENT) || + atomic_test_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY)) { send_input_complete(); } else { atomic_set_bit(bt_mesh_prov_link.flags, INPUT_COMPLETE); diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index 241ea8f276..d9bb70d7bc 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -23,6 +23,11 @@ syscfg.defs: BLE_MESH_PB_ADV or BLE_MESH_PB_GATT is set. value: 1 + BLE_MESH_PROV_OOB_PUBLIC_KEY: + description: > + Enable this option if public key is to be exchanged via Out of Band (OOB) technology. + value: 0 + BLE_MESH_PB_ADV: description: > Enable this option to allow the device to be provisioned over From d9413d20fb9ce4a1ab76cd9ad1261ce01660c864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Oct 2021 12:38:07 +0200 Subject: [PATCH 0104/1333] host/mesh: Fix setting remote public key in provisioner This aligns provisioner and provisionee APIs in terms of endianess of public key provided by an application. This is port of f5ba999257e977688e7eae6a36a554ceed51d95f --- nimble/host/mesh/include/mesh/main.h | 2 +- nimble/host/mesh/src/provisioner.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/nimble/host/mesh/include/mesh/main.h b/nimble/host/mesh/include/mesh/main.h index 213950b17b..dff5eb1db8 100644 --- a/nimble/host/mesh/include/mesh/main.h +++ b/nimble/host/mesh/include/mesh/main.h @@ -287,7 +287,7 @@ int bt_mesh_input_number(uint32_t num); /** @brief Provide Device public key. * - * @param public_key Device public key. + * @param public_key Device public key in big-endian. * * @return Zero on success or (negative) error code otherwise. */ diff --git a/nimble/host/mesh/src/provisioner.c b/nimble/host/mesh/src/provisioner.c index 9e8df89375..7a8c40d8f6 100644 --- a/nimble/host/mesh/src/provisioner.c +++ b/nimble/host/mesh/src/provisioner.c @@ -724,8 +724,7 @@ int bt_mesh_prov_remote_pub_key_set(const uint8_t public_key[64]) } /* Swap X and Y halves independently to big-endian */ - memcpy(&bt_mesh_prov_link.conf_inputs[81], public_key, 32); - memcpy(&bt_mesh_prov_link.conf_inputs[81 + 32], &public_key[32], 32); + memcpy(&bt_mesh_prov_link.conf_inputs[81], public_key, 64); return 0; } From 23217d8622c2e6389a4c55e59d777fd0aec982b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 11 Oct 2021 07:01:03 +0200 Subject: [PATCH 0105/1333] host/mesh: Add API to manually store pending RPL entries The current approach with storing RPL by timeout doesn't solve all issues as the node may loss power before the timer is fired. In addition to that this may wear out flash quickly if short timeout is used. This change adds an API to store the pending RPL entry upon user request. Additional Kconfig option allows to completely disable timer so that the whole storing relies on the user. The mesh stack still stays responsible for outdating RPL entries in case of IV Index update as this happens implicitly for the user. This is port of 65f798a00abb6bbb7c51091e754b926d15405d14 --- nimble/host/mesh/include/mesh/main.h | 13 +++++++++++ nimble/host/mesh/src/rpl.c | 34 ++++++++++++++++++++++++---- nimble/host/mesh/src/rpl.h | 1 - nimble/host/mesh/src/settings.c | 16 ++++++++----- nimble/host/mesh/src/settings.h | 1 + nimble/host/mesh/syscfg.yml | 26 +++++++++++++-------- 6 files changed, 70 insertions(+), 21 deletions(-) diff --git a/nimble/host/mesh/include/mesh/main.h b/nimble/host/mesh/include/mesh/main.h index dff5eb1db8..d196522dea 100644 --- a/nimble/host/mesh/include/mesh/main.h +++ b/nimble/host/mesh/include/mesh/main.h @@ -565,6 +565,19 @@ void bt_mesh_lpn_set_cb(void (*cb)(uint16_t friend_addr, bool established)); */ int bt_mesh_friend_terminate(uint16_t lpn_addr); +/** @brief Store pending RPL entry(ies) in the persistent storage. + * + * This API allows the user to store pending RPL entry(ies) in the persistent + * storage without waiting for the timeout. + * + * @note When flash is used as the persistent storage, calling this API too + * frequently may wear it out. + * + * @param addr Address of the node which RPL entry needs to be stored or + * @ref BT_MESH_ADDR_ALL_NODES to store all pending RPL entries. + */ +void bt_mesh_rpl_pending_store(uint16_t addr); + #ifdef __cplusplus } #endif diff --git a/nimble/host/mesh/src/rpl.c b/nimble/host/mesh/src/rpl.c index b767752c86..bf5743e417 100644 --- a/nimble/host/mesh/src/rpl.c +++ b/nimble/host/mesh/src/rpl.c @@ -53,10 +53,17 @@ static void clear_rpl(struct bt_mesh_rpl *rpl) atomic_clear_bit(store, rpl_idx(rpl)); } -static void schedule_rpl_store(struct bt_mesh_rpl *entry) +static void schedule_rpl_store(struct bt_mesh_rpl *entry, bool force) { atomic_set_bit(store, rpl_idx(entry)); bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); + if (force +#ifdef CONFIG_BT_MESH_RPL_STORE_TIMEOUT + || CONFIG_BT_MESH_RPL_STORE_TIMEOUT >= 0 +#endif + ) { + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); + } } static void schedule_rpl_clear(void) @@ -79,7 +86,7 @@ void bt_mesh_rpl_update(struct bt_mesh_rpl *rpl, rpl->old_iv = rx->old_iv; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - schedule_rpl_store(rpl); + schedule_rpl_store(rpl, false); } } @@ -200,7 +207,7 @@ void bt_mesh_rpl_reset(void) } else { rpl->old_iv = true; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - schedule_rpl_store(rpl); + schedule_rpl_store(rpl, true); } } } @@ -306,16 +313,35 @@ static void store_pending_rpl(struct bt_mesh_rpl *rpl) } } -void bt_mesh_rpl_pending_store(void) +void bt_mesh_rpl_pending_store(uint16_t addr) { int i; + if (!IS_ENABLED(CONFIG_BT_SETTINGS) || + (!BT_MESH_ADDR_IS_UNICAST(addr) && + addr != BT_MESH_ADDR_ALL_NODES)) { + return; + } + + if (addr == BT_MESH_ADDR_ALL_NODES) { + bt_mesh_settings_store_cancel(BT_MESH_SETTINGS_RPL_PENDING); + } + for (i = 0; i < ARRAY_SIZE(replay_list); i++) { + if (addr != BT_MESH_ADDR_ALL_NODES && + addr != replay_list[i].src) { + continue; + } + if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { store_pending_rpl(&replay_list[i]); } else { clear_rpl(&replay_list[i]); } + + if (addr != BT_MESH_ADDR_ALL_NODES) { + break; + } } } diff --git a/nimble/host/mesh/src/rpl.h b/nimble/host/mesh/src/rpl.h index 9a1d49ff07..b79ce887d4 100644 --- a/nimble/host/mesh/src/rpl.h +++ b/nimble/host/mesh/src/rpl.h @@ -29,5 +29,4 @@ bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx, void bt_mesh_rpl_clear(void); void bt_mesh_rpl_update(struct bt_mesh_rpl *rpl, struct bt_mesh_net_rx *rx); -void bt_mesh_rpl_pending_store(void); void bt_mesh_rpl_init(void); \ No newline at end of file diff --git a/nimble/host/mesh/src/settings.c b/nimble/host/mesh/src/settings.c index b8938d4543..5ec6d71e9e 100644 --- a/nimble/host/mesh/src/settings.c +++ b/nimble/host/mesh/src/settings.c @@ -104,11 +104,9 @@ void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag) if (atomic_get(pending_flags) & NO_WAIT_PENDING_BITS) { timeout_ms = 0; - } else if (atomic_test_bit(pending_flags, - BT_MESH_SETTINGS_RPL_PENDING) && - (!(atomic_get(pending_flags) & GENERIC_PENDING_BITS) || - (CONFIG_BT_MESH_RPL_STORE_TIMEOUT < - CONFIG_BT_MESH_STORE_TIMEOUT))) { + } else if (CONFIG_BT_MESH_RPL_STORE_TIMEOUT >= 0 && + atomic_test_bit(pending_flags, BT_MESH_SETTINGS_RPL_PENDING) && + !(atomic_get(pending_flags) & GENERIC_PENDING_BITS)) { timeout_ms = CONFIG_BT_MESH_RPL_STORE_TIMEOUT * MSEC_PER_SEC; } else { timeout_ms = CONFIG_BT_MESH_STORE_TIMEOUT * MSEC_PER_SEC; @@ -127,12 +125,18 @@ void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag) k_work_schedule(&pending_store, K_MSEC(timeout_ms)); } } + +void bt_mesh_settings_store_cancel(enum bt_mesh_settings_flag flag) +{ + atomic_clear_bit(pending_flags, flag); +} + static void store_pending(struct ble_npl_event *work) { BT_DBG(""); if (atomic_test_and_clear_bit(pending_flags, BT_MESH_SETTINGS_RPL_PENDING)) { - bt_mesh_rpl_pending_store(); + bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES); } if (atomic_test_and_clear_bit(pending_flags, diff --git a/nimble/host/mesh/src/settings.h b/nimble/host/mesh/src/settings.h index 95f78f50ff..73105fb345 100644 --- a/nimble/host/mesh/src/settings.h +++ b/nimble/host/mesh/src/settings.h @@ -23,3 +23,4 @@ enum bt_mesh_settings_flag { void bt_mesh_settings_init(void); int settings_name_next(char *name, char **next); void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag); +void bt_mesh_settings_store_cancel(enum bt_mesh_settings_flag flag); diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index d9bb70d7bc..d0ba860a33 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -619,16 +619,22 @@ syscfg.defs: BLE_MESH_RPL_STORE_TIMEOUT: description: > - This value defines in seconds how soon the RPL gets written to - persistent storage after a change occurs. If the node receives - messages frequently it may make sense to have this set to a - large value, whereas if the RPL gets updated infrequently a - value as low as 0 (write immediately) may make sense. Note that - if the node operates a security sensitive use case, and there's - a risk of sudden power loss, it may be a security vulnerability - to set this value to anything else than 0 (a power loss before - writing to storage exposes the node to potential message - replay attacks). + Minimum interval after which unsaved RPL entries are updated in storage + + This value defines in seconds how soon unsaved RPL entries + gets written to the persistent storage. Setting this value + to a large number may lead to security vulnerabilities if a node + gets powered off before the timer is fired. When flash is used + as the persistent storage setting this value to a low number + may wear out flash sooner or later. However, if the RPL gets + updated infrequently a value as low as 0 (write immediately) + may make sense. Setting this value to -1 will disable this timer. + In this case, a user is responsible to store pending RPL entries + using @ref bt_mesh_rpl_pending_store. In the mean time, when + IV Index is updated, the outdated RPL entries will still be + stored by @ref BT_MESH_STORE_TIMEOUT. Finding the right balance + between this timeout and calling @ref bt_mesh_rpl_pending_store + may reduce a risk of security vulnerability and flash wear out. value: 5 BLE_MESH_DEVICE_NAME: From 9dc019d6cd1d28ee3ba4693170be642679f9c206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 11 Oct 2021 15:56:50 +0200 Subject: [PATCH 0106/1333] host/mesh: Add proxy send callback Zephyr Bluetooth Mesh did not check whether the proxy message was actually sent out, so that the response message could not be received during reset. This is port of 7531d2e3c8ffa73c9e1d1fcf33d2b26991ea5f8c --- nimble/host/mesh/src/adv.c | 9 ---- nimble/host/mesh/src/adv.h | 10 ++++ nimble/host/mesh/src/cfg_srv.c | 35 +++++++------ nimble/host/mesh/src/net.c | 5 +- nimble/host/mesh/src/pb_gatt.c | 18 ++++++- nimble/host/mesh/src/proxy.c | 93 ++++++++++++++++------------------ nimble/host/mesh/src/proxy.h | 17 +++---- 7 files changed, 99 insertions(+), 88 deletions(-) diff --git a/nimble/host/mesh/src/adv.c b/nimble/host/mesh/src/adv.c index 7e0e1927fa..a9afb42fd8 100644 --- a/nimble/host/mesh/src/adv.c +++ b/nimble/host/mesh/src/adv.c @@ -66,15 +66,6 @@ static struct bt_mesh_adv *adv_alloc(int id) return &adv_pool[id]; } -static inline void adv_send_start(uint16_t duration, int err, - const struct bt_mesh_send_cb *cb, - void *cb_data) -{ - if (cb && cb->start) { - cb->start(duration, err, cb_data); - } -} - static inline void adv_send_end(int err, const struct bt_mesh_send_cb *cb, void *cb_data) { diff --git a/nimble/host/mesh/src/adv.h b/nimble/host/mesh/src/adv.h index 6dd2c8107c..ba6d3c8d7f 100644 --- a/nimble/host/mesh/src/adv.h +++ b/nimble/host/mesh/src/adv.h @@ -34,6 +34,16 @@ enum bt_mesh_adv_type typedef void (*bt_mesh_adv_func_t)(struct os_mbuf *buf, uint16_t duration, int err, void *user_data); + +static inline void adv_send_start(uint16_t duration, int err, + const struct bt_mesh_send_cb *cb, + void *cb_data) +{ + if (cb && cb->start) { + cb->start(duration, err, cb_data); + } +} + struct bt_mesh_adv { /** Fragments associated with this buffer. */ struct os_mbuf *frags; diff --git a/nimble/host/mesh/src/cfg_srv.c b/nimble/host/mesh/src/cfg_srv.c index 35a00bd9e5..201af6a88a 100644 --- a/nimble/host/mesh/src/cfg_srv.c +++ b/nimble/host/mesh/src/cfg_srv.c @@ -2023,11 +2023,27 @@ static void mod_app_get(struct bt_mesh_model *model, os_mbuf_free_chain(msg); } +static void reset_send_start(uint16_t duration, int err, void *cb_data) +{ + if (err) { + BT_ERR("Sending Node Reset Status failed (err %d)", err); + bt_mesh_reset(); + } +} + +static void reset_send_end(int err, void *cb_data) +{ + bt_mesh_reset(); +} + static void node_reset(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - static struct bt_mesh_proxy_idle_cb proxy_idle = {.cb = bt_mesh_reset}; + static const struct bt_mesh_send_cb reset_cb = { + .start = reset_send_start, + .end = reset_send_end, + }; struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NODE_RESET_STATUS, 0); @@ -2035,26 +2051,13 @@ static void node_reset(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - bt_mesh_model_msg_init(msg, OP_NODE_RESET_STATUS); - /* Send the response first since we wont have any keys left to - * send it later. - */ - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + if (bt_mesh_model_send(model, ctx, msg, &reset_cb, NULL)) { BT_ERR("Unable to send Node Reset Status"); } - if (!IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { - bt_mesh_reset(); - return; - } - - /* If the response goes to a proxy node, we'll wait for the sending to - * complete before moving on. - */ - bt_mesh_proxy_on_idle(&proxy_idle); - os_mbuf_free_chain(msg); + os_mbuf_free_chain(msg); } static void send_friend_status(struct bt_mesh_model *model, diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index f1e44b0503..386f4d0f8c 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -534,12 +534,13 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct os_mbuf *buf, goto done; } + BT_MESH_ADV(buf)->cb = cb; + BT_MESH_ADV(buf)->cb_data = cb_data; + /* Deliver to GATT Proxy Clients if necessary. */ if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && bt_mesh_proxy_relay(buf, tx->ctx->addr) && BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { - /* Notify completion if this only went through the Mesh Proxy */ - send_cb_finalize(cb, cb_data); err = 0; goto done; diff --git a/nimble/host/mesh/src/pb_gatt.c b/nimble/host/mesh/src/pb_gatt.c index bd119c15ef..fb04963219 100644 --- a/nimble/host/mesh/src/pb_gatt.c +++ b/nimble/host/mesh/src/pb_gatt.c @@ -15,10 +15,16 @@ #include "adv.h" #include "prov.h" +struct prov_bearer_send_cb { + prov_bearer_send_complete_t cb; + void *cb_data; +}; + struct prov_link { uint16_t conn_handle; const struct prov_bearer_cb *cb; void *cb_data; + struct prov_bearer_send_cb comp; struct { uint8_t id; /* Transaction ID */ uint8_t prev_id; /* Previous Transaction ID */ @@ -130,6 +136,13 @@ static int link_accept(const struct prov_bearer_cb *cb, void *cb_data) return 0; } +static void buf_send_end(uint16_t conn_handle, void *user_data) +{ + if (link.comp.cb) { + link.comp.cb(0, link.comp.cb_data); + } +} + static int buf_send(struct os_mbuf *buf, prov_bearer_send_complete_t cb, void *cb_data) { @@ -137,9 +150,12 @@ static int buf_send(struct os_mbuf *buf, prov_bearer_send_complete_t cb, return -ENOTCONN; } + link.comp.cb = cb; + link.comp.cb_data = cb_data; + k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT); - return bt_mesh_proxy_send(link.conn_handle, BT_MESH_PROXY_PROV, buf); + return bt_mesh_pb_gatt_send(link.conn_handle, buf, buf_send_end, NULL); } static void clear_tx(void) diff --git a/nimble/host/mesh/src/proxy.c b/nimble/host/mesh/src/proxy.c index 44c3376a0e..e05cbb5830 100644 --- a/nimble/host/mesh/src/proxy.c +++ b/nimble/host/mesh/src/proxy.c @@ -139,9 +139,6 @@ static struct bt_mesh_proxy_client { [0 ... (MYNEWT_VAL(BLE_MAX_CONNECTIONS) - 1)] = { 0 }, }; -static sys_slist_t idle_waiters; -static atomic_t pending_notifications; - /* Track which service is enabled */ static enum { MESH_GATT_NONE, @@ -213,7 +210,8 @@ static struct bt_mesh_proxy_client *find_client(uint16_t conn_handle) static struct bt_mesh_subnet *beacon_sub; static int proxy_segment_and_send(uint16_t conn_handle, uint8_t type, - struct os_mbuf *msg); + struct os_mbuf *msg, + void (*end)(uint16_t, void *), void *user_data); static int filter_set(struct bt_mesh_proxy_client *client, struct os_mbuf *buf) @@ -328,7 +326,8 @@ static void send_filter_status(struct bt_mesh_proxy_client *client, return; } - err = proxy_segment_and_send(client->conn_handle, BT_MESH_PROXY_CONFIG, buf); + err = proxy_segment_and_send(client->conn_handle, BT_MESH_PROXY_CONFIG, buf, + NULL, NULL); if (err) { BT_ERR("Failed to send proxy cfg message (err %d)", err); } @@ -407,7 +406,8 @@ static int beacon_send(uint16_t conn_handle, struct bt_mesh_subnet *sub) net_buf_simple_init(buf, 1); bt_mesh_beacon_create(sub, buf); - rc = proxy_segment_and_send(conn_handle, BT_MESH_PROXY_BEACON, buf); + rc = proxy_segment_and_send(conn_handle, BT_MESH_PROXY_BEACON, buf, + NULL, NULL); os_mbuf_free_chain(buf); return rc; } @@ -953,10 +953,19 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client, return false; } +static void buf_send_end(uint16_t conn_handle, void *user_data) +{ + struct os_mbuf *buf = user_data; + + net_buf_unref(buf); +} + bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) { + const struct bt_mesh_send_cb *cb = BT_MESH_ADV(buf)->cb; + void *cb_data = BT_MESH_ADV(buf)->cb_data; bool relayed = false; - int i; + int i, err; BT_DBG("%u bytes to dst 0x%04x", buf->om_len, dst); @@ -972,6 +981,11 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) continue; } + if (client->filter_type == PROV) { + BT_ERR("Invalid PDU type for Proxy Client"); + return -EINVAL; + } + /* Proxy PDU sending modifies the original buffer, * so we need to make a copy. */ @@ -979,7 +993,14 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) net_buf_simple_init(msg, 1); net_buf_simple_add_mem(msg, buf->om_data, buf->om_len); - bt_mesh_proxy_send(client->conn_handle, BT_MESH_PROXY_NET_PDU, msg); + err = proxy_segment_and_send(client->conn_handle, BT_MESH_PROXY_NET_PDU, + msg, buf_send_end, net_buf_ref(buf)); + + adv_send_start(0, err, cb, cb_data); + if (err) { + BT_ERR("Failed to send proxy message (err %d)", err); + continue; + } os_mbuf_free_chain(msg); relayed = true; } @@ -989,22 +1010,9 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) #endif /* MYNEWT_VAL(BLE_MESH_GATT_PROXY) */ -static void notify_complete(void) -{ - sys_snode_t *n; - - if (atomic_dec(&pending_notifications) > 1) { - return; - } - - BT_DBG(""); - - while ((n = sys_slist_get(&idle_waiters))) { - CONTAINER_OF(n, struct bt_mesh_proxy_idle_cb, n)->cb(); - } -} - -static int proxy_send(uint16_t conn_handle, const void *data, uint16_t len) +static int proxy_send(uint16_t conn_handle, + const void *data, uint16_t len, + void (*end)(uint16_t, void *), void *user_data) { struct os_mbuf *om; int err = 0; @@ -1016,7 +1024,7 @@ static int proxy_send(uint16_t conn_handle, const void *data, uint16_t len) om = ble_hs_mbuf_from_flat(data, len); assert(om); err = ble_gattc_notify_custom(conn_handle, svc_handles.proxy_data_out_h, om); - notify_complete(); + /* We do not pass cb into ble_gattc_notify_custom - execute it at the end */ } #endif @@ -1025,19 +1033,16 @@ static int proxy_send(uint16_t conn_handle, const void *data, uint16_t len) om = ble_hs_mbuf_from_flat(data, len); assert(om); err = ble_gattc_notify_custom(conn_handle, svc_handles.prov_data_out_h, om); - notify_complete(); } #endif - if (!err) { - atomic_inc(&pending_notifications); - } - + end(conn_handle, user_data); return err; } static int proxy_segment_and_send(uint16_t conn_handle, uint8_t type, - struct os_mbuf *msg) + struct os_mbuf *msg, + void (*end)(uint16_t, void *), void *user_data) { uint16_t mtu; @@ -1048,30 +1053,30 @@ static int proxy_segment_and_send(uint16_t conn_handle, uint8_t type, mtu = ble_att_mtu(conn_handle) - 3; if (mtu > msg->om_len) { net_buf_simple_push_u8(msg, PDU_HDR(SAR_COMPLETE, type)); - return proxy_send(conn_handle, msg->om_data, msg->om_len); + return proxy_send(conn_handle, msg->om_data, msg->om_len, end, user_data); } net_buf_simple_push_u8(msg, PDU_HDR(SAR_FIRST, type)); - proxy_send(conn_handle, msg->om_data, mtu); + proxy_send(conn_handle, msg->om_data, mtu, NULL, NULL); net_buf_simple_pull_mem(msg, mtu); while (msg->om_len) { if (msg->om_len + 1 < mtu) { net_buf_simple_push_u8(msg, PDU_HDR(SAR_LAST, type)); - proxy_send(conn_handle, msg->om_data, msg->om_len); + proxy_send(conn_handle, msg->om_data, msg->om_len, end, user_data); break; } net_buf_simple_push_u8(msg, PDU_HDR(SAR_CONT, type)); - proxy_send(conn_handle, msg->om_data, mtu); + proxy_send(conn_handle, msg->om_data, mtu, NULL, NULL); net_buf_simple_pull_mem(msg, mtu); } return 0; } -int bt_mesh_proxy_send(uint16_t conn_handle, uint8_t type, - struct os_mbuf *msg) +int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, + void (*end)(uint16_t, void *), void *user_data) { struct bt_mesh_proxy_client *client = find_client(conn_handle); @@ -1080,12 +1085,12 @@ int bt_mesh_proxy_send(uint16_t conn_handle, uint8_t type, return -ENOTCONN; } - if ((client->filter_type == PROV) != (type == BT_MESH_PROXY_PROV)) { + if (client->filter_type == PROV) { BT_ERR("Invalid PDU type for Proxy Client"); return -EINVAL; } - return proxy_segment_and_send(conn_handle, type, msg); + return proxy_segment_and_send(conn_handle, BT_MESH_PROXY_PROV, buf, end, user_data); } #if (MYNEWT_VAL(BLE_MESH_PB_GATT)) @@ -1610,14 +1615,4 @@ int bt_mesh_proxy_init(void) return 0; } -void bt_mesh_proxy_on_idle(struct bt_mesh_proxy_idle_cb *cb) -{ - if (!atomic_get(&pending_notifications)) { - cb->cb(); - return; - } - - sys_slist_append(&idle_waiters, &cb->n); -} - #endif /* MYNEWT_VAL(BLE_MESH_PROXY) */ diff --git a/nimble/host/mesh/src/proxy.h b/nimble/host/mesh/src/proxy.h index ebade45ab6..27124901f2 100644 --- a/nimble/host/mesh/src/proxy.h +++ b/nimble/host/mesh/src/proxy.h @@ -6,8 +6,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __PROXY_H__ -#define __PROXY_H__ +#ifndef ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROXY_H_ +#define ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROXY_H_ + +int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, + void (*end)(uint16_t, void *), void *user_data); #define BT_MESH_PROXY_NET_PDU 0x00 #define BT_MESH_PROXY_BEACON 0x01 @@ -17,13 +20,6 @@ #include "mesh/mesh.h" #include "mesh/slist.h" -struct bt_mesh_proxy_idle_cb { - sys_snode_t n; - void (*cb)(void); -}; - -int bt_mesh_proxy_send(uint16_t conn_handle, uint8_t type, struct os_mbuf *msg); - int bt_mesh_proxy_prov_enable(void); int bt_mesh_proxy_prov_disable(bool disconnect); @@ -45,8 +41,7 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst); void bt_mesh_proxy_addr_add(struct os_mbuf *buf, uint16_t addr); int bt_mesh_proxy_init(void); -void bt_mesh_proxy_on_idle(struct bt_mesh_proxy_idle_cb *cb); int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg); -#endif +#endif /* ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROXY_H_ */ From e8a42b4fd1a335e00ddf6de248e3b97ad23582c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 11 Oct 2021 16:12:20 +0200 Subject: [PATCH 0107/1333] host/mesh: Increase default CDB node count The old default of 1 makes provisioner devices useless, as they can only provision themselves before they run out of space. This is port of f2579cb3f26bde3050306401de9cd2837c94024f --- nimble/host/mesh/syscfg.yml | 2 +- porting/examples/linux_blemesh/include/syscfg/syscfg.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index d0ba860a33..f992500d02 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -69,7 +69,7 @@ syscfg.defs: description: > This option specifies how many nodes each network can at most save in the configuration database. - value: 1 + value: 8 BLE_MESH_CDB_SUBNET_COUNT: description: > diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index a3df8b6ea0..2fd5232b94 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -1041,7 +1041,7 @@ #endif #ifndef MYNEWT_VAL_BLE_MESH_CDB_NODE_COUNT -#define MYNEWT_VAL_BLE_MESH_CDB_NODE_COUNT (1) +#define MYNEWT_VAL_BLE_MESH_CDB_NODE_COUNT (8) #endif #ifndef MYNEWT_VAL_BLE_MESH_CDB_APP_KEY_COUNT From e0f018c52c5a6f1d9975e5817753f54891882b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 11 Oct 2021 16:18:04 +0200 Subject: [PATCH 0108/1333] host/mesh: sequence number limit config Set sequence number limit by Kconfig This is port of f6d7f8f36fffdf2b311252eee54f765d854a51b7 --- nimble/host/mesh/include/mesh/glue.h | 1 + nimble/host/mesh/src/net.c | 2 +- nimble/host/mesh/syscfg.yml | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index 9dfd051096..4edefd9f54 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -431,6 +431,7 @@ static inline unsigned int find_msb_set(uint32_t op) #define CONFIG_BT_MESH_APP_KEY_COUNT MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT) #define CONFIG_BT_MESH_SUBNET_COUNT MYNEWT_VAL(BLE_MESH_SUBNET_COUNT) #define CONFIG_BT_MESH_STORE_TIMEOUT MYNEWT_VAL(BLE_MESH_STORE_TIMEOUT) +#define CONFIG_BT_MESH_IV_UPDATE_SEQ_LIMIT MYNEWT_VAL(BLE_MESH_IV_UPDATE_SEQ_LIMIT) #define CONFIG_BT_MESH_IVU_DIVIDER MYNEWT_VAL(BLE_MESH_IVU_DIVIDER) #define CONFIG_BT_DEVICE_NAME MYNEWT_VAL(BLE_MESH_DEVICE_NAME) #define CONFIG_BT_RX_SEG_MAX MYNEWT_VAL(BLE_MESH_RX_SEG_MAX) diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index 386f4d0f8c..b8136e99bd 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -39,7 +39,7 @@ #define LOOPBACK_BUF_SUB(buf) (*(struct bt_mesh_subnet **)net_buf_user_data(buf)) /* Seq limit after IV Update is triggered */ -#define IV_UPDATE_SEQ_LIMIT 8000000 +#define IV_UPDATE_SEQ_LIMIT CONFIG_BT_MESH_IV_UPDATE_SEQ_LIMIT #define IVI(pdu) ((pdu)[0] >> 7) #define NID(pdu) ((pdu)[0] & 0x7f) diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index f992500d02..c0ebac5bd2 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -214,6 +214,11 @@ syscfg.defs: absolutely necessary value: 768 + BLE_MESH_IV_UPDATE_SEQ_LIMIT: + description: > + This option specifies the sequence number value to start iv update. + value: 0x800000 + BLE_MESH_IVU_DIVIDER: description: > When the IV Update state enters Normal operation or IV Update From 53d610b73d133b47a90717937a643485a34324a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 11 Oct 2021 16:21:30 +0200 Subject: [PATCH 0109/1333] host/mesh: Fix missing proxy send status Add an error judgment during `proxy_send` to avoid missing `net_buf_unref`. This is port of c45ec6fc0da1d5c183d9b2628ef2fdab60b0c978 --- nimble/host/mesh/src/proxy.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/nimble/host/mesh/src/proxy.c b/nimble/host/mesh/src/proxy.c index e05cbb5830..bc62f2b036 100644 --- a/nimble/host/mesh/src/proxy.c +++ b/nimble/host/mesh/src/proxy.c @@ -999,6 +999,12 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) adv_send_start(0, err, cb, cb_data); if (err) { BT_ERR("Failed to send proxy message (err %d)", err); + /* If segment_and_send() fails the buf_send_end() callback will + * not be called, so we need to clear the user data (net_buf, + * which is just opaque data to segment_and send) reference given + * to segment_and_send() here. + */ + net_buf_unref(buf); continue; } os_mbuf_free_chain(msg); @@ -1044,6 +1050,7 @@ static int proxy_segment_and_send(uint16_t conn_handle, uint8_t type, struct os_mbuf *msg, void (*end)(uint16_t, void *), void *user_data) { + int err; uint16_t mtu; BT_DBG("conn_handle %d type 0x%02x len %u: %s", conn_handle, type, msg->om_len, @@ -1057,18 +1064,27 @@ static int proxy_segment_and_send(uint16_t conn_handle, uint8_t type, } net_buf_simple_push_u8(msg, PDU_HDR(SAR_FIRST, type)); - proxy_send(conn_handle, msg->om_data, mtu, NULL, NULL); + err = proxy_send(conn_handle, msg->om_data, mtu, NULL, NULL); + if (err) { + return err; + } net_buf_simple_pull_mem(msg, mtu); while (msg->om_len) { if (msg->om_len + 1 < mtu) { net_buf_simple_push_u8(msg, PDU_HDR(SAR_LAST, type)); - proxy_send(conn_handle, msg->om_data, msg->om_len, end, user_data); + err = proxy_send(conn_handle, msg->om_data, msg->om_len, end, user_data); + if (err) { + return err; + } break; } net_buf_simple_push_u8(msg, PDU_HDR(SAR_CONT, type)); - proxy_send(conn_handle, msg->om_data, mtu, NULL, NULL); + err = proxy_send(conn_handle, msg->om_data, mtu, NULL, NULL); + if (err) { + return err; + } net_buf_simple_pull_mem(msg, mtu); } From c3a4b94f6f34e2be00ee8f4dacd42f58015a91a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 11 Oct 2021 16:22:25 +0200 Subject: [PATCH 0110/1333] host/mesh: comp pointer check comp data pointer check before using This is port of d466a807ee20670e90169eb2ad36996210277893 --- nimble/host/mesh/src/access.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index 85717aa51b..79f4be7b45 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -328,7 +328,7 @@ int bt_mesh_comp_register(const struct bt_mesh_comp *comp) int err; /* There must be at least one element */ - if (!comp->elem_count) { + if (!comp || !comp->elem_count) { return -EINVAL; } From 4b0e34959271c031df8f8669dee7dcc09cb89374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 11 Oct 2021 16:24:13 +0200 Subject: [PATCH 0111/1333] host/mesh: Update SNB beacon before sending it Authentication value must be recalculated before sending it. This is port of 5513b86864e3ccd3de710724308e46abbcaa44af --- nimble/host/mesh/src/net.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index b8136e99bd..865747b048 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -314,13 +314,13 @@ bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update) bt_mesh_friend_sec_update(BT_MESH_KEY_ANY); } + bt_mesh_subnet_foreach(bt_mesh_beacon_update); + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED) { bt_mesh_proxy_beacon_send(NULL); } - bt_mesh_subnet_foreach(bt_mesh_beacon_update); - if (MYNEWT_VAL(BLE_MESH_CDB)) { bt_mesh_cdb_iv_update(iv_index, iv_update); } From 7baecc0fa49593c0cca8e12c874fd423655d85c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 11 Oct 2021 16:36:40 +0200 Subject: [PATCH 0112/1333] host/mesh: Fix regression in PB-ADV After #35702, the provisioner is unable to mark a link as closed, as it depends on the send_end callback to be called, so it can start its timer. PB-Adv keeps a reference to the buffers of reliable messages, which prevents this callback to be invoked, as the buffer destructor is never called. Move scheduling of the retransmit timer to the initial transmission, and replace the timer based LINK_CLOSE message tx duration with a message counting solution. This is port of 534177b2ca02f52ad04d8da08167a3e847242de7 --- nimble/host/mesh/src/pb_adv.c | 118 ++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 55 deletions(-) diff --git a/nimble/host/mesh/src/pb_adv.c b/nimble/host/mesh/src/pb_adv.c index 405a1530a9..3e136a2070 100644 --- a/nimble/host/mesh/src/pb_adv.c +++ b/nimble/host/mesh/src/pb_adv.c @@ -55,10 +55,10 @@ /* Acked messages, will do retransmissions manually, taking acks into account: */ #define RETRANSMITS_RELIABLE 0 -/* Unacked messages: */ -#define RETRANSMITS_UNRELIABLE 2 /* PDU acks: */ #define RETRANSMITS_ACK 2 +/* Link close retransmits: */ +#define RETRANSMITS_LINK_CLOSE 2 enum { ADV_LINK_ACTIVE, /* Link has been opened */ @@ -126,20 +126,27 @@ static void link_open(struct prov_rx *rx, struct os_mbuf *buf); static void link_ack(struct prov_rx *rx, struct os_mbuf *buf); static void link_close(struct prov_rx *rx, struct os_mbuf *buf); static void prov_link_close(enum prov_bearer_link_status status); +static void close_link(enum prov_bearer_link_status status); static void buf_sent(int err, void *user_data) { BT_DBG("buf_send"); - if (!link.tx.buf[0]) { + if (atomic_test_and_clear_bit(link.flags, ADV_LINK_CLOSING)) { + close_link(PROV_BEARER_LINK_STATUS_SUCCESS); return; } +} - BT_DBG("submit retransmit"); - k_work_reschedule(&link.tx.retransmit, RETRANSMIT_TIMEOUT); +static void buf_start(uint16_t duration, int err, void *user_data) +{ + if (err) { + buf_sent(err, user_data); + } } static struct bt_mesh_send_cb buf_sent_cb = { + .start = buf_start, .end = buf_sent, }; @@ -569,18 +576,14 @@ static void send_reliable(void) BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (i + 1 < ARRAY_SIZE(link.tx.buf) && link.tx.buf[i + 1]) { - bt_mesh_adv_send(buf, NULL, NULL); - } else { - bt_mesh_adv_send(buf, &buf_sent_cb, NULL); - } + bt_mesh_adv_send(buf, NULL, NULL); } + + k_work_reschedule(&link.tx.retransmit, RETRANSMIT_TIMEOUT); } static void prov_retransmit(struct ble_npl_event *work) { - int32_t timeout_ms; - BT_DBG(""); if (!atomic_test_bit(link.flags, ADV_LINK_ACTIVE)) { @@ -588,45 +591,25 @@ static void prov_retransmit(struct ble_npl_event *work) return; } - /* - * According to mesh profile spec (5.3.1.4.3), the close message should - * be restransmitted at least three times. Retransmit the link_close - * message until CLOSING_TIMEOUT has elapsed. - */ - if (atomic_test_bit(link.flags, ADV_LINK_CLOSING)) { - timeout_ms = CLOSING_TIMEOUT; - } else { - timeout_ms = TRANSACTION_TIMEOUT; - } - - if (k_uptime_get() - link.tx.start > timeout_ms) { - if (atomic_test_bit(link.flags, ADV_LINK_CLOSING)) { - close_link(PROV_BEARER_LINK_STATUS_SUCCESS); - } else { - BT_WARN("Giving up transaction"); - prov_link_close(PROV_BEARER_LINK_STATUS_TIMEOUT); - } - + if (k_uptime_get() - link.tx.start > TRANSACTION_TIMEOUT) { + BT_WARN("Giving up transaction"); + prov_link_close(PROV_BEARER_LINK_STATUS_FAIL); return; } send_reliable(); } -static int bearer_ctl_send(uint8_t op, const void *data, uint8_t data_len, - bool reliable) +static struct os_mbuf *ctl_buf_create(uint8_t op, const void *data, uint8_t data_len, + uint8_t retransmits) { struct os_mbuf *buf; BT_DBG("op 0x%02x data_len %u", op, data_len); - prov_clear_tx(); - k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT); - - buf = adv_buf_create(reliable ? RETRANSMITS_RELIABLE : - RETRANSMITS_UNRELIABLE); + buf = adv_buf_create(retransmits); if (!buf) { - return -ENOBUFS; + return NULL; } net_buf_add_be32(buf, link.id); @@ -634,16 +617,35 @@ static int bearer_ctl_send(uint8_t op, const void *data, uint8_t data_len, net_buf_add_u8(buf, 0x00); net_buf_add_u8(buf, GPC_CTL(op)); net_buf_add_mem(buf, data, data_len); + return buf; +} - if (reliable) { - link.tx.start = k_uptime_get(); - link.tx.buf[0] = buf; - send_reliable(); - } else { - bt_mesh_adv_send(buf, &buf_sent_cb, NULL); - net_buf_unref(buf); +static int bearer_ctl_send(struct os_mbuf *buf) +{ + if (!buf) { + return -ENOMEM; + } + prov_clear_tx(); + k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT); + + link.tx.start = k_uptime_get(); + link.tx.buf[0] = buf; + send_reliable(); + + return 0; + } + +static int bearer_ctl_send_unacked(struct os_mbuf *buf) +{ + if (!buf) { + return -ENOMEM; } + prov_clear_tx(); + k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT); + + bt_mesh_adv_send(buf, &buf_sent_cb, NULL); + net_buf_unref(buf); return 0; } @@ -720,6 +722,8 @@ static int prov_send_adv(struct os_mbuf *msg, static void link_open(struct prov_rx *rx, struct os_mbuf *buf) { + int err; + BT_DBG("len %u", buf->om_len); if (buf->om_len < 16) { @@ -729,13 +733,14 @@ static void link_open(struct prov_rx *rx, struct os_mbuf *buf) if (atomic_test_bit(link.flags, ADV_LINK_ACTIVE)) { /* Send another link ack if the provisioner missed the last */ - if (link.id == rx->link_id) { - BT_DBG("Resending link ack"); - bearer_ctl_send(LINK_ACK, NULL, 0, false); - } else { + if (link.id != rx->link_id) { BT_DBG("Ignoring bearer open: link already active"); + return; } + BT_DBG("Resending link ack"); + /* Ignore errors, message will be attempted again if we keep receiving link open: */ + (void)bearer_ctl_send_unacked(ctl_buf_create(LINK_ACK, NULL, 0, RETRANSMITS_ACK)); return; } @@ -748,7 +753,11 @@ static void link_open(struct prov_rx *rx, struct os_mbuf *buf) atomic_set_bit(link.flags, ADV_LINK_ACTIVE); net_buf_simple_reset(link.rx.buf); - bearer_ctl_send(LINK_ACK, NULL, 0, false); + err = bearer_ctl_send_unacked(ctl_buf_create(LINK_ACK, NULL, 0, RETRANSMITS_ACK)); + if (err) { + reset_adv_link(); + return; + } link.cb->link_opened(&pb_adv, link.cb_data); } @@ -828,9 +837,7 @@ static int prov_link_open(const uint8_t uuid[16], int32_t timeout, net_buf_simple_reset(link.rx.buf); - bearer_ctl_send(LINK_OPEN, uuid, 16, true); - - return 0; + return bearer_ctl_send(ctl_buf_create(LINK_OPEN, uuid, 16, RETRANSMITS_RELIABLE)); } static int prov_link_accept(const struct prov_bearer_cb *cb, void *cb_data) @@ -858,7 +865,8 @@ static void prov_link_close(enum prov_bearer_link_status status) return; } - bearer_ctl_send(LINK_CLOSE, &status, 1, true); + /* Ignore errors, the link will time out eventually if this doesn't get sent */ + bearer_ctl_send_unacked(ctl_buf_create(LINK_CLOSE, &status, 1, RETRANSMITS_LINK_CLOSE)); } void pb_adv_init(void) From 2dad0b9f2f9fcc9a83ac4ab563136cd9e0701964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 12 Oct 2021 07:32:30 +0200 Subject: [PATCH 0113/1333] host/mesh: Check the CID field before opcode compare Bluetooth Mesh Vendor model hava company id field. Accordin MeshPRFV1.0.1 3.7.3.1 Operation codes. The 3-octet opcodes are used for manufacturer-specific opcodes. The company identifiers are 16-bit values defined by the Bluetooth SIG and are coded into the second and third octets of the 3-octet opcodes. Therefore, we can speed up the search process by checking whether CID fields match, rather than comparing opcodes one by one. This is port of cc0abee3db739413f2498d465386ab5a8bf7c1eb --- nimble/host/mesh/include/mesh/glue.h | 1 + nimble/host/mesh/src/access.c | 78 ++++++++++++++++++------ nimble/host/mesh/syscfg.yml | 6 ++ porting/targets/linux_blemesh/syscfg.yml | 1 + 4 files changed, 67 insertions(+), 19 deletions(-) diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index 4edefd9f54..ec0e609a0b 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -439,6 +439,7 @@ static inline unsigned int find_msb_set(uint32_t op) #define CONFIG_BT_MESH_RX_SEG_MAX MYNEWT_VAL(BLE_MESH_RX_SEG_MAX) #define CONFIG_BT_MESH_RX_SEG_MSG_COUNT MYNEWT_VAL(BLE_MESH_RX_SEG_MSG_COUNT) #define CONFIG_BT_MESH_LABEL_COUNT MYNEWT_VAL(BLE_MESH_LABEL_COUNT) +#define CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE MYNEWT_VAL(BLE_MESH_MODEL_VND_MSG_CID_FORCE) #define CONFIG_BT_MESH_NODE_COUNT MYNEWT_VAL(BLE_MESH_CDB_NODE_COUNT) #define CONFIG_BT_GATT_PROXY_ENABLED MYNEWT_VAL(BLE_MESH_GATT_PROXY_ENABLED) #define CONFIG_BT_MESH_DEFAULT_TTL MYNEWT_VAL(BLE_MESH_DEFAULT_TTL) diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index 79f4be7b45..359d8c4e27 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -291,6 +291,30 @@ struct bt_mesh_model *bt_mesh_model_get(bool vnd, uint8_t elem_idx, uint8_t mod_ } } +#if defined(CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE) +static int bt_mesh_vnd_mod_msg_cid_check(struct bt_mesh_model *mod) +{ + uint16_t cid; + const struct bt_mesh_model_op *op; + + for (op = mod->op; op->func; op++) { + cid = (uint16_t)(op->opcode & 0xffff); + + if (cid == mod->vnd.company) { + continue; + } + + BT_ERR("Invalid vendor model(company:0x%04x" + " id:0x%04x) message opcode 0x%08x", + mod->vnd.company, mod->vnd.id, op->opcode); + + return -EINVAL; + } + + return 0; +} +#endif + static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) { @@ -314,6 +338,13 @@ static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, mod->elem_idx = elem - dev_comp->elem; if (vnd) { mod->mod_idx = mod - elem->vnd_models; + + if (CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE) { + *err = bt_mesh_vnd_mod_msg_cid_check(mod); + if (*err) { + return; + } + } } else { mod->mod_idx = mod - elem->models; } @@ -509,15 +540,37 @@ static bool model_has_dst(struct bt_mesh_model *mod, uint16_t dst) return mod->elem_idx == 0; } -static const struct bt_mesh_model_op *find_op(struct bt_mesh_model *models, - uint8_t model_count, uint32_t opcode, - struct bt_mesh_model **model) +static const struct bt_mesh_model_op *find_op(struct bt_mesh_elem *elem, + uint32_t opcode, struct bt_mesh_model **model) { uint8_t i; + uint8_t count; + /* This value shall not be used in shipping end products. */ + uint32_t cid = UINT32_MAX; + struct bt_mesh_model *models; + + /* SIG models cannot contain 3-byte (vendor) OpCodes, and + * vendor models cannot contain SIG (1- or 2-byte) OpCodes, so + * we only need to do the lookup in one of the model lists. + */ + if (BT_MESH_MODEL_OP_LEN(opcode) < 3) { + models = elem->models; + count = elem->model_count; + } else { + models = elem->vnd_models; + count = elem->vnd_model_count; + + cid = (uint16_t)(opcode & 0xffff); + } - for (i = 0; i < model_count; i++) { + for (i = 0U; i < count; i++) { const struct bt_mesh_model_op *op; + if (CONFIG_BT_MESH_MODEL_VND_MSG_CID_FORCE && + cid != UINT32_MAX && + cid != models[i].vnd.company) { + continue; + } *model = &models[i]; for (op = (*model)->op; op->func; op++) { @@ -571,10 +624,9 @@ static int get_opcode(struct os_mbuf *buf, uint32_t *opcode) void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) { - struct bt_mesh_model *models, *model; + struct bt_mesh_model *model; const struct bt_mesh_model_op *op; uint32_t opcode; - uint8_t count; int i; BT_DBG("app_idx 0x%04x src 0x%04x dst 0x%04x", rx->ctx.app_idx, @@ -589,22 +641,10 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) BT_DBG("OpCode 0x%08x", (unsigned) opcode); for (i = 0; i < dev_comp->elem_count; i++) { - struct bt_mesh_elem *elem = &dev_comp->elem[i]; struct net_buf_simple_state state; - /* SIG models cannot contain 3-byte (vendor) OpCodes, and - * vendor models cannot contain SIG (1- or 2-byte) OpCodes, so - * we only need to do the lookup in one of the model lists. - */ - if (BT_MESH_MODEL_OP_LEN(opcode) < 3) { - models = elem->models; - count = elem->model_count; - } else { - models = elem->vnd_models; - count = elem->vnd_model_count; - } + op = find_op(&dev_comp->elem[i], opcode, &model); - op = find_op(models, count, opcode, &model); if (!op) { BT_DBG("No OpCode 0x%08x for elem %d", opcode, i); continue; diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index c0ebac5bd2..dcde094443 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -171,6 +171,12 @@ syscfg.defs: at most be subscribed to. value: 1 + BLE_MESH_MODEL_VND_MSG_CID_FORCE: + description: > + This option forces vendor model to use messages for the + corresponding CID field. + value: 1 + BLE_MESH_LABEL_COUNT: description: > This option specifies how many Label UUIDs can be stored. diff --git a/porting/targets/linux_blemesh/syscfg.yml b/porting/targets/linux_blemesh/syscfg.yml index efc4150b4c..8ef7972184 100644 --- a/porting/targets/linux_blemesh/syscfg.yml +++ b/porting/targets/linux_blemesh/syscfg.yml @@ -34,6 +34,7 @@ syscfg.vals: BLE_MESH_LABEL_COUNT: 2 BLE_MESH_SUBNET_COUNT: 2 BLE_MESH_MODEL_GROUP_COUNT: 2 + BLE_MESH_MODEL_VND_MSG_CID_FORCE: 1 BLE_MESH_APP_KEY_COUNT: 4 BLE_MESH_IV_UPDATE_TEST: 1 BLE_MESH_TESTING: 1 From de8d513602e27644b4af09b81215ac43a2c4805f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 12 Oct 2021 07:35:49 +0200 Subject: [PATCH 0114/1333] host/mesh: Restore default device configuration on reset This commit fixes an issue where bt_mesh_reset() call just erases all mesh flags set at the initialization instead of restoring them and thus disabling some features until the board reboot. This is port of 6c9411656c3a282155f9b9f780da95b2767649bb --- nimble/host/mesh/src/cfg.c | 2 +- nimble/host/mesh/src/cfg.h | 2 +- nimble/host/mesh/src/cfg_srv.c | 2 +- nimble/host/mesh/src/foundation.h | 2 +- nimble/host/mesh/src/mesh.c | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/nimble/host/mesh/src/cfg.c b/nimble/host/mesh/src/cfg.c index b9daa8fda2..9ed212abc4 100644 --- a/nimble/host/mesh/src/cfg.c +++ b/nimble/host/mesh/src/cfg.c @@ -348,7 +348,7 @@ static struct conf_handler bt_mesh_cfg_conf_handler = { .ch_export = NULL, }; -void bt_mesh_cfg_init(void) +void bt_mesh_cfg_default_set(void) { int rc; diff --git a/nimble/host/mesh/src/cfg.h b/nimble/host/mesh/src/cfg.h index 40f7ed92bc..0bd7ad39c6 100644 --- a/nimble/host/mesh/src/cfg.h +++ b/nimble/host/mesh/src/cfg.h @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -void bt_mesh_cfg_init(void); +void bt_mesh_cfg_default_set(void); void bt_mesh_cfg_pending_store(void); bool bt_mesh_fixed_group_match(uint16_t addr); \ No newline at end of file diff --git a/nimble/host/mesh/src/cfg_srv.c b/nimble/host/mesh/src/cfg_srv.c index 201af6a88a..734faa7c8f 100644 --- a/nimble/host/mesh/src/cfg_srv.c +++ b/nimble/host/mesh/src/cfg_srv.c @@ -2511,7 +2511,7 @@ static void mod_reset(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, } } -void bt_mesh_cfg_reset(void) +void bt_mesh_model_reset(void) { bt_mesh_model_foreach(mod_reset, NULL); } diff --git a/nimble/host/mesh/src/foundation.h b/nimble/host/mesh/src/foundation.h index 012afbbb07..21734047ec 100644 --- a/nimble/host/mesh/src/foundation.h +++ b/nimble/host/mesh/src/foundation.h @@ -115,7 +115,7 @@ #define STATUS_UNSPECIFIED 0x10 #define STATUS_INVALID_BINDING 0x11 -void bt_mesh_cfg_reset(void); +void bt_mesh_model_reset(void); void bt_mesh_attention(struct bt_mesh_model *model, uint8_t time); diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c index 4ff992d53c..3dfba16763 100644 --- a/nimble/host/mesh/src/mesh.c +++ b/nimble/host/mesh/src/mesh.c @@ -170,8 +170,8 @@ void bt_mesh_reset(void) k_work_cancel_delayable(&bt_mesh.ivu_timer); - bt_mesh_cfg_reset(); - + bt_mesh_model_reset(); + bt_mesh_cfg_default_set(); bt_mesh_trans_reset(); bt_mesh_app_keys_reset(); bt_mesh_net_keys_reset(); @@ -351,7 +351,7 @@ int bt_mesh_init(uint8_t own_addr_type, const struct bt_mesh_prov *prov, #if CONFIG_BT_MESH_CDB bt_mesh_cdb_init(); #endif - bt_mesh_cfg_init(); + bt_mesh_cfg_default_set(); bt_mesh_net_init(); bt_mesh_trans_init(); bt_mesh_hb_init(); From 115e911619048f8f1db4136cda4ae5368ff7648b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 13 Oct 2021 12:41:48 +0200 Subject: [PATCH 0115/1333] host/mesh: Modularizing the proxy The Bluetooth proxy feature includes proxy client and proxy server. In addition to the proxy pdu message used above, pb-gatt also uses the same proxy pdu message. Currently zephyr bluetooth mesh couples them in one file. A file at the separation is called gatt_services.c, which is used to contain Mesh Provisioning Service and Mesh Proxy Service. Another file in the separation is called proxy_msg.c, which is used to process Proxy pdu messages. Also according to Trond's suggestion: Rename `CONFIG_BT_MESH_PROXY` to `CONFIG_BT_MESH_GATT`. Create an additional promptless entry `CONFIG_BT_MESH_GATT_SERVER` that selects `CONFIG_BT_MESH_GATT` and is selected by `CONFIG_BT_MESH_GATT_PROXY` or `CONFIG_BT_MESH_PB_GATT`. Create additional `CONFIG_BT_MESH_PROXY` used to represent proxy feature (also include proxy client). This is port of 3a559e972a415449cb577a35aed3e0514bba77df, 7b2e51881c8eab839b4a8f1e914a7accb6fe1598 and 3d2ad8e653b533d83ebf31b672d52922bca2d481 --- .../mesh/src/{proxy.c => gatt_services.c} | 1420 +++++++---------- nimble/host/mesh/src/proxy.h | 6 +- nimble/host/mesh/src/proxy_msg.c | 231 +++ nimble/host/mesh/src/proxy_msg.h | 47 + nimble/host/mesh/syscfg.yml | 12 + 5 files changed, 908 insertions(+), 808 deletions(-) rename nimble/host/mesh/src/{proxy.c => gatt_services.c} (70%) create mode 100644 nimble/host/mesh/src/proxy_msg.c create mode 100644 nimble/host/mesh/src/proxy_msg.h diff --git a/nimble/host/mesh/src/proxy.c b/nimble/host/mesh/src/gatt_services.c similarity index 70% rename from nimble/host/mesh/src/proxy.c rename to nimble/host/mesh/src/gatt_services.c index bc62f2b036..38f5ee1147 100644 --- a/nimble/host/mesh/src/proxy.c +++ b/nimble/host/mesh/src/gatt_services.c @@ -2,32 +2,28 @@ /* * Copyright (c) 2017 Intel Corporation + * Copyright (c) 2021 Lingao Meng * * SPDX-License-Identifier: Apache-2.0 */ -#include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_PROXY_LOG +#define BT_DBG_ENABLED CONFIG_BT_MESH_DEBUG_PROXY +#define LOG_MODULE_NAME bt_mesh_gatt -#if MYNEWT_VAL(BLE_MESH_PROXY) - -#include "mesh/mesh.h" -#include "host/ble_att.h" -#include "services/gatt/ble_svc_gatt.h" #include "../../host/src/ble_hs_priv.h" +#include "services/gatt/ble_svc_gatt.h" #include "mesh_priv.h" #include "adv.h" #include "net.h" #include "rpl.h" +#include "transport.h" #include "prov.h" #include "beacon.h" #include "foundation.h" #include "access.h" #include "proxy.h" - -#define PDU_TYPE(data) (data[0] & BIT_MASK(6)) -#define PDU_SAR(data) (data[0] >> 6) +#include "proxy_msg.h" #define BT_UUID_16_ENCODE(w16) \ (((w16) >> 0) & 0xFF), \ @@ -38,15 +34,8 @@ */ #define PROXY_SAR_TIMEOUT K_SECONDS(20) -#define SAR_COMPLETE 0x00 -#define SAR_FIRST 0x01 -#define SAR_CONT 0x02 -#define SAR_LAST 0x03 +#define CLIENT_BUF_SIZE 65 -#define CFG_FILTER_SET 0x00 -#define CFG_FILTER_ADD 0x01 -#define CFG_FILTER_REMOVE 0x02 -#define CFG_FILTER_STATUS 0x03 /** @def BT_UUID_MESH_PROV * @brief Mesh Provisioning Service @@ -84,44 +73,64 @@ ble_uuid16_t BT_UUID_MESH_PROXY_DATA_IN = BLE_UUID16_INIT(0x2add); ble_uuid16_t BT_UUID_MESH_PROXY_DATA_OUT = BLE_UUID16_INIT(0x2ade); #define BT_UUID_MESH_PROXY_DATA_OUT_VAL 0x2ade -#define PDU_HDR(sar, type) (sar << 6 | (type & BIT_MASK(6))) - -#define CLIENT_BUF_SIZE 65 +#if CONFIG_BT_MESH_DEBUG_USE_ID_ADDR +#define ADV_OPT_USE_IDENTITY BT_LE_ADV_OPT_USE_IDENTITY +#else +#define ADV_OPT_USE_IDENTITY 0 +#endif -#if MYNEWT_VAL(BLE_MESH_PROXY_USE_DEVICE_NAME) +#if CONFIG_BT_MESH_PROXY_USE_DEVICE_NAME #define ADV_OPT_USE_NAME BT_LE_ADV_OPT_USE_NAME #else #define ADV_OPT_USE_NAME 0 #endif #define ADV_OPT_PROV \ - .conn_mode = (BLE_GAP_CONN_MODE_UND), \ - .disc_mode = (BLE_GAP_DISC_MODE_GEN), +.conn_mode = (BLE_GAP_CONN_MODE_UND), \ +.disc_mode = (BLE_GAP_DISC_MODE_GEN), #define ADV_OPT_PROXY \ - .conn_mode = (BLE_GAP_CONN_MODE_UND), \ - .disc_mode = (BLE_GAP_DISC_MODE_GEN), +.conn_mode = (BLE_GAP_CONN_MODE_UND), \ +.disc_mode = (BLE_GAP_DISC_MODE_GEN), #define ADV_SLOW_INT \ - .itvl_min = BT_GAP_ADV_SLOW_INT_MIN, \ - .itvl_max = BT_GAP_ADV_SLOW_INT_MAX, +.itvl_min = BT_GAP_ADV_SLOW_INT_MIN, \ +.itvl_max = BT_GAP_ADV_SLOW_INT_MAX, #define ADV_FAST_INT \ - .itvl_min = BT_GAP_ADV_FAST_INT_MIN_2, \ - .itvl_max = BT_GAP_ADV_FAST_INT_MAX_2, +.itvl_min = BT_GAP_ADV_FAST_INT_MIN_2, \ +.itvl_max = BT_GAP_ADV_FAST_INT_MAX_2, -static bool proxy_adv_enabled; +static bool gatt_adv_enabled; -#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) +static struct { + uint16_t proxy_h; + uint16_t proxy_data_out_h; + uint16_t prov_h; + uint16_t prov_data_in_h; + uint16_t prov_data_out_h; +} svc_handles; + +#if MYNEWT_VAL(BLE_MESH_GATT_PROXY) static void proxy_send_beacons(struct ble_npl_event *work); -#endif +static void proxy_filter_recv(uint16_t conn_handle, + struct bt_mesh_net_rx *rx, struct os_mbuf *buf); +#endif /* CONFIG_BT_MESH_GATT_PROXY */ -#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) +#if MYNEWT_VAL(BLE_MESH_PB_GATT) static bool prov_fast_adv; +#endif /* CONFIG_BT_MESH_PB_GATT */ + +static int proxy_send(uint16_t conn_handle, + const void *data, uint16_t len, + void (*end)(uint16_t, void *), void *user_data); + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + static bool prov_fast_adv; #endif static struct bt_mesh_proxy_client { - uint16_t conn_handle; + struct bt_mesh_proxy_role cli; uint16_t filter[MYNEWT_VAL(BLE_MESH_PROXY_FILTER_SIZE)]; enum __packed { NONE, @@ -129,16 +138,22 @@ static struct bt_mesh_proxy_client { BLACKLIST, PROV, } filter_type; - uint8_t msg_type; -#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) +#if MYNEWT_VAL(BLE_MESH_GATT_PROXY) struct ble_npl_callout send_beacons; -#endif - struct k_work_delayable sar_timer; - struct os_mbuf *buf; -} clients[MYNEWT_VAL(BLE_MAX_CONNECTIONS)] = { - [0 ... (MYNEWT_VAL(BLE_MAX_CONNECTIONS) - 1)] = { 0 }, +#endif /* CONFIG_BT_MESH_GATT_PROXY */ +} clients[CONFIG_BT_MAX_CONN] = { + [0 ... (CONFIG_BT_MAX_CONN - 1)] = { + .cli.cb = { + .send = proxy_send, +#if MYNEWT_VAL(BLE_MESH_GATT_PROXY) + .recv = proxy_filter_recv, +#endif /* CONFIG_BT_MESH_GATT_PROXY */ + }, + }, }; +//static uint8_t __noinit client_buf_data[CLIENT_BUF_SIZE * CONFIG_BT_MAX_CONN]; + /* Track which service is enabled */ static enum { MESH_GATT_NONE, @@ -146,73 +161,55 @@ static enum { MESH_GATT_PROXY, } gatt_svc = MESH_GATT_NONE; -static struct { - uint16_t proxy_h; - uint16_t proxy_data_out_h; - uint16_t prov_h; - uint16_t prov_data_in_h; - uint16_t prov_data_out_h; -} svc_handles; +static int conn_count; -static void resolve_svc_handles(void) +static struct bt_mesh_proxy_client *find_client(uint16_t conn_handle) { - int rc; + int i; - /* Either all handles are already resolved, or none of them */ - if (svc_handles.prov_data_out_h) { - return; + for (i = 0; i < ARRAY_SIZE(clients); i++) { + if (clients[i].cli.conn_handle == conn_handle) { + return &clients[i]; + } } - /* - * We assert if attribute is not found since at this stage all attributes - * shall be already registered and thus shall be found. - */ - - rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), - &svc_handles.proxy_h); - assert(rc == 0); + return NULL; +} - rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), - BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL), - NULL, &svc_handles.proxy_data_out_h); - assert(rc == 0); +#define ATTR_IS_PROV(attr) (attr->user_data != NULL) - rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), - &svc_handles.prov_h); - assert(rc == 0); +static ssize_t gatt_recv(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + struct bt_mesh_proxy_client *client = find_client(conn_handle); + const uint8_t *data = ctxt->om->om_data; + uint16_t len = ctxt->om->om_len; - rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), - BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL), - NULL, &svc_handles.prov_data_in_h); - assert(rc == 0); + client = find_client(conn_handle); - rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), - BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL), - NULL, &svc_handles.prov_data_out_h); - assert(rc == 0); -} + if (!client) { + return -ENOTCONN; + } -static struct bt_mesh_proxy_client *find_client(uint16_t conn_handle) -{ - int i; + if (len < 1) { + BT_WARN("Too small Proxy PDU"); + return -EINVAL; + } - for (i = 0; i < ARRAY_SIZE(clients); i++) { - if (clients[i].conn_handle == conn_handle) { - return &clients[i]; - } + if ((attr_handle == svc_handles.prov_data_in_h) != + (PDU_TYPE(data) == BT_MESH_PROXY_PROV)) { + BT_WARN("Proxy PDU type doesn't match GATT service"); + return -EINVAL; } - return NULL; + return bt_mesh_proxy_msg_recv(&client->cli, data, len); } -#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + +#if defined(CONFIG_BT_MESH_GATT_PROXY) /* Next subnet in queue to be advertised */ static struct bt_mesh_subnet *beacon_sub; -static int proxy_segment_and_send(uint16_t conn_handle, uint8_t type, - struct os_mbuf *msg, - void (*end)(uint16_t, void *), void *user_data); - static int filter_set(struct bt_mesh_proxy_client *client, struct os_mbuf *buf) { @@ -227,17 +224,17 @@ static int filter_set(struct bt_mesh_proxy_client *client, BT_DBG("type 0x%02x", type); switch (type) { - case 0x00: - memset(client->filter, 0, sizeof(client->filter)); - client->filter_type = WHITELIST; - break; - case 0x01: - memset(client->filter, 0, sizeof(client->filter)); - client->filter_type = BLACKLIST; - break; - default: - BT_WARN("Prohibited Filter Type 0x%02x", type); - return -EINVAL; + case 0x00: + (void)memset(client->filter, 0, sizeof(client->filter)); + client->filter_type = WHITELIST; + break; + case 0x01: + (void)memset(client->filter, 0, sizeof(client->filter)); + client->filter_type = BLACKLIST; + break; + default: + BT_WARN("Prohibited Filter Type 0x%02x", type); + return -EINVAL; } return 0; @@ -310,7 +307,7 @@ static void send_filter_status(struct bt_mesh_proxy_client *client, net_buf_simple_add_u8(buf, 0x01); } - for (filter_size = 0, i = 0; i < ARRAY_SIZE(client->filter); i++) { + for (filter_size = 0U, i = 0; i < ARRAY_SIZE(client->filter); i++) { if (client->filter[i] != BT_MESH_ADDR_UNASSIGNED) { filter_size++; } @@ -326,79 +323,55 @@ static void send_filter_status(struct bt_mesh_proxy_client *client, return; } - err = proxy_segment_and_send(client->conn_handle, BT_MESH_PROXY_CONFIG, buf, - NULL, NULL); + err = bt_mesh_proxy_msg_send(&client->cli, BT_MESH_PROXY_CONFIG, + buf, NULL, NULL); if (err) { BT_ERR("Failed to send proxy cfg message (err %d)", err); } } -static void proxy_cfg(struct bt_mesh_proxy_client *client) +static void proxy_filter_recv(uint16_t conn_handle, + struct bt_mesh_net_rx *rx, struct os_mbuf *buf) { - struct os_mbuf *buf = NET_BUF_SIMPLE(BT_MESH_NET_MAX_PDU_LEN); - struct bt_mesh_net_rx rx; + struct bt_mesh_proxy_client *client; uint8_t opcode; - int err; - - err = bt_mesh_net_decode(client->buf, BT_MESH_NET_IF_PROXY_CFG, - &rx, buf); - if (err) { - BT_ERR("Failed to decode Proxy Configuration (err %d)", err); - goto done; - } - - rx.local_match = 1U; - if (bt_mesh_rpl_check(&rx, NULL)) { - BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", - rx.ctx.addr, rx.ctx.recv_dst, rx.seq); - goto done; - } - - /* Remove network headers */ - net_buf_simple_pull_mem(buf, BT_MESH_NET_HDR_LEN); - - BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); - - if (buf->om_len < 1) { - BT_WARN("Too short proxy configuration PDU"); - goto done; + client = find_client(conn_handle); + if (!client) { + return; } opcode = net_buf_simple_pull_u8(buf); switch (opcode) { case CFG_FILTER_SET: filter_set(client, buf); - send_filter_status(client, &rx, buf); + send_filter_status(client, rx, buf); break; - case CFG_FILTER_ADD: - while (buf->om_len >= 2) { - uint16_t addr; + case CFG_FILTER_ADD: + while (buf->om_len >= 2) { + uint16_t addr; - addr = net_buf_simple_pull_be16(buf); - filter_add(client, addr); - } - send_filter_status(client, &rx, buf); - break; - case CFG_FILTER_REMOVE: - while (buf->om_len >= 2) { - uint16_t addr; + addr = net_buf_simple_pull_be16(buf); + filter_add(client, addr); + } + send_filter_status(client, rx, buf); + break; + case CFG_FILTER_REMOVE: + while (buf->om_len >= 2) { + uint16_t addr; - addr = net_buf_simple_pull_be16(buf); - filter_remove(client, addr); - } - send_filter_status(client, &rx, buf); - break; - default: - BT_WARN("Unhandled configuration OpCode 0x%02x", opcode); - break; + addr = net_buf_simple_pull_be16(buf); + filter_remove(client, addr); + } + send_filter_status(client, rx, buf); + break; + default: + BT_WARN("Unhandled configuration OpCode 0x%02x", opcode); + break; } - -done: - os_mbuf_free_chain(buf); } -static int beacon_send(uint16_t conn_handle, struct bt_mesh_subnet *sub) +static int beacon_send(struct bt_mesh_proxy_client *client, struct bt_mesh_subnet *sub) { struct os_mbuf *buf = NET_BUF_SIMPLE(23); int rc; @@ -406,7 +379,7 @@ static int beacon_send(uint16_t conn_handle, struct bt_mesh_subnet *sub) net_buf_simple_init(buf, 1); bt_mesh_beacon_create(sub, buf); - rc = proxy_segment_and_send(conn_handle, BT_MESH_PROXY_BEACON, buf, + rc = bt_mesh_proxy_msg_send(&client->cli, BT_MESH_PROXY_BEACON, buf, NULL, NULL); os_mbuf_free_chain(buf); return rc; @@ -416,7 +389,7 @@ static int send_beacon_cb(struct bt_mesh_subnet *sub, void *cb_data) { struct bt_mesh_proxy_client *client = cb_data; - return beacon_send(client->conn_handle, sub); + return beacon_send(client, sub); } static void proxy_send_beacons(struct ble_npl_event *work) @@ -428,27 +401,6 @@ static void proxy_send_beacons(struct ble_npl_event *work) (void)bt_mesh_subnet_find(send_beacon_cb, client); } -static void proxy_sar_timeout(struct ble_npl_event *work) -{ - struct bt_mesh_proxy_client *client; - int rc; - client = ble_npl_event_get_arg(work); - - if (!client->conn_handle) { - return; - } - - if (!client->buf->om_len) { - BT_DBG("No pending Proxy SAR message"); - return; - } - - BT_WARN("Proxy SAR timeout"); - rc = ble_gap_terminate(client->conn_handle, - BLE_ERR_REM_USER_CONN_TERM); - assert(rc == 0); -} - void bt_mesh_proxy_beacon_send(struct bt_mesh_subnet *sub) { int i; @@ -460,8 +412,8 @@ void bt_mesh_proxy_beacon_send(struct bt_mesh_subnet *sub) } for (i = 0; i < ARRAY_SIZE(clients); i++) { - if (clients[i].conn_handle != BLE_HS_CONN_HANDLE_NONE) { - beacon_send(clients[i].conn_handle, sub); + if (clients[i].cli.conn_handle) { + beacon_send(&clients[i], sub); } } } @@ -475,14 +427,15 @@ static void node_id_start(struct bt_mesh_subnet *sub) void bt_mesh_proxy_identity_start(struct bt_mesh_subnet *sub) { node_id_start(sub); + /* Prioritize the recently enabled subnet */ beacon_sub = sub; } void bt_mesh_proxy_identity_stop(struct bt_mesh_subnet *sub) -{ + { sub->node_id = BT_MESH_NODE_IDENTITY_STOPPED; - sub->node_id_start = 0; + sub->node_id_start = 0U; } int bt_mesh_proxy_identity_enable(void) @@ -500,306 +453,250 @@ int bt_mesh_proxy_identity_enable(void) return 0; } -#endif /* GATT_PROXY */ - -static void proxy_complete_pdu(struct bt_mesh_proxy_client *client) -{ - switch (client->msg_type) { -#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) - case BT_MESH_PROXY_NET_PDU: - BT_INFO("Mesh Network PDU"); - bt_mesh_net_recv(client->buf, 0, BT_MESH_NET_IF_PROXY); - break; - case BT_MESH_PROXY_BEACON: - BT_INFO("Mesh Beacon PDU"); - bt_mesh_beacon_recv(client->buf); - break; - case BT_MESH_PROXY_CONFIG: - BT_INFO("Mesh Configuration PDU"); - proxy_cfg(client); - break; -#endif -#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) - case BT_MESH_PROXY_PROV: - BT_INFO("Mesh Provisioning PDU"); - bt_mesh_pb_gatt_recv(client->conn_handle, client->buf); - break; -#endif - default: - BT_WARN("Unhandled Message Type 0x%02x", client->msg_type); - break; - } +#define ID_TYPE_NET 0x00 +#define ID_TYPE_NODE 0x01 - net_buf_simple_init(client->buf, 0); -} +#define NODE_ID_LEN 19 +#define NET_ID_LEN 11 -static int proxy_recv(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, void *arg) -{ - struct bt_mesh_proxy_client *client = find_client(conn_handle); - const uint8_t *data = ctxt->om->om_data; - uint16_t len = ctxt->om->om_len; +#define NODE_ID_TIMEOUT (CONFIG_BT_MESH_NODE_ID_TIMEOUT * MSEC_PER_SEC) - client = find_client(conn_handle); +static uint8_t proxy_svc_data[NODE_ID_LEN] = { + BT_UUID_16_ENCODE(BT_UUID_MESH_PROXY_VAL), +}; - if (!client) { - return -ENOTCONN; - } +static const struct bt_data node_id_ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA_BYTES(BT_DATA_UUID16_ALL, + BT_UUID_16_ENCODE(BT_UUID_MESH_PROXY_VAL)), + BT_DATA(BT_DATA_SVC_DATA16, proxy_svc_data, NODE_ID_LEN), +}; - if (len < 1) { - BT_WARN("Too small Proxy PDU"); - return -EINVAL; - } +static const struct bt_data net_id_ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA_BYTES(BT_DATA_UUID16_ALL, + BT_UUID_16_ENCODE(BT_UUID_MESH_PROXY_VAL)), + BT_DATA(BT_DATA_SVC_DATA16, proxy_svc_data, NET_ID_LEN), +}; - if ((attr_handle == svc_handles.prov_data_in_h) != - (PDU_TYPE(data) == BT_MESH_PROXY_PROV)) { - BT_WARN("Proxy PDU type doesn't match GATT service"); - return -EINVAL; - } +static int node_id_adv(struct bt_mesh_subnet *sub) +{ + struct ble_gap_adv_params fast_adv_param = { + ADV_OPT_PROXY + ADV_FAST_INT + }; +#if ADV_OPT_USE_NAME + const char *name = CONFIG_BT_DEVICE_NAME; + size_t name_len = strlen(name); + struct bt_data sd = { + .type = BT_DATA_NAME_COMPLETE, + .data_len = name_len, + .data = (void *)name + }; +#else + struct bt_data *sd = NULL; +#endif + uint8_t tmp[16]; + int err; - if (len - 1 > net_buf_simple_tailroom(client->buf)) { - BT_WARN("Too big proxy PDU"); - return -EINVAL; - } + BT_DBG(""); - switch (PDU_SAR(data)) { - case SAR_COMPLETE: - if (client->buf->om_len) { - BT_WARN("Complete PDU while a pending incomplete one"); - return -EINVAL; - } + proxy_svc_data[2] = ID_TYPE_NODE; - client->msg_type = PDU_TYPE(data); - net_buf_simple_add_mem(client->buf, data + 1, len - 1); - proxy_complete_pdu(client); - break; + err = bt_rand(proxy_svc_data + 11, 8); + if (err) { + return err; + } - case SAR_FIRST: - if (client->buf->om_len) { - BT_WARN("First PDU while a pending incomplete one"); - return -EINVAL; - } + (void)memset(tmp, 0, 6); + memcpy(tmp + 6, proxy_svc_data + 11, 8); + sys_put_be16(bt_mesh_primary_addr(), tmp + 14); - k_work_reschedule(&client->sar_timer, PROXY_SAR_TIMEOUT); - client->msg_type = PDU_TYPE(data); - net_buf_simple_add_mem(client->buf, data + 1, len - 1); - break; + err = bt_encrypt_be(sub->keys[SUBNET_KEY_TX_IDX(sub)].identity, tmp, + tmp); + if (err) { + return err; + } - case SAR_CONT: - if (!client->buf->om_len) { - BT_WARN("Continuation with no prior data"); - return -EINVAL; - } + memcpy(proxy_svc_data + 3, tmp + 8, 8); - if (client->msg_type != PDU_TYPE(data)) { - BT_WARN("Unexpected message type in continuation"); - return -EINVAL; - } + err = bt_le_adv_start(&fast_adv_param, node_id_ad, + ARRAY_SIZE(node_id_ad), sd, 0); + if (err) { + BT_WARN("Failed to advertise using Node ID (err %d)", err); + return err; + } - k_work_reschedule(&client->sar_timer, PROXY_SAR_TIMEOUT); - net_buf_simple_add_mem(client->buf, data + 1, len - 1); - break; + return 0; +} - case SAR_LAST: - if (!client->buf->om_len) { - BT_WARN("Last SAR PDU with no prior data"); - return -EINVAL; - } - - if (client->msg_type != PDU_TYPE(data)) { - BT_WARN("Unexpected message type in last SAR PDU"); - return -EINVAL; - } - - /* If this fails, the work handler exits early, as there's no - * active SAR buffer. - */ - (void)k_work_cancel_delayable(&client->sar_timer); - net_buf_simple_add_mem(client->buf, data + 1, len - 1); - proxy_complete_pdu(client); - break; - } - - return len; -} - -static int conn_count; - -static void proxy_connected(uint16_t conn_handle) +static int net_id_adv(struct bt_mesh_subnet *sub) { - struct bt_mesh_proxy_client *client; - int i; - - BT_INFO("conn_handle %d", conn_handle); + struct ble_gap_adv_params slow_adv_param = { + ADV_OPT_PROXY + ADV_SLOW_INT + }; +#if ADV_OPT_USE_NAME + const char *name = CONFIG_BT_DEVICE_NAME; + size_t name_len = strlen(name); + struct bt_data sd = { + .type = BT_DATA_NAME_COMPLETE, + .data_len = name_len, + .data = (void *)name + }; +#else + struct bt_data *sd = NULL; +#endif + int err; - conn_count++; + BT_DBG(""); - /* Since we use ADV_OPT_ONE_TIME */ - proxy_adv_enabled = false; + proxy_svc_data[2] = ID_TYPE_NET; - /* Try to re-enable advertising in case it's possible */ - if (conn_count < CONFIG_BT_MAX_CONN) { - bt_mesh_adv_update(); - } + BT_DBG("Advertising with NetId %s", + bt_hex(sub->keys[SUBNET_KEY_TX_IDX(sub)].net_id, 8)); - for (client = NULL, i = 0; i < ARRAY_SIZE(clients); i++) { - if (clients[i].conn_handle == BLE_HS_CONN_HANDLE_NONE) { - client = &clients[i]; - break; - } - } + memcpy(proxy_svc_data + 3, sub->keys[SUBNET_KEY_TX_IDX(sub)].net_id, 8); - if (!client) { - BT_ERR("No free Proxy Client objects"); - return; + err = bt_le_adv_start(&slow_adv_param, net_id_ad, + ARRAY_SIZE(net_id_ad), sd, 0); + if (err) { + BT_WARN("Failed to advertise using Network ID (err %d)", err); + return err; } - client->conn_handle = conn_handle; - client->filter_type = NONE; - memset(client->filter, 0, sizeof(client->filter)); - net_buf_simple_init(client->buf, 0); + return 0; } -static void proxy_disconnected(uint16_t conn_handle, int reason) +static bool advertise_subnet(struct bt_mesh_subnet *sub) { - int i; - - BT_DBG("conn handle %u reason 0x%02x", conn_handle, reason); - conn_count--; + if (sub->net_idx == BT_MESH_KEY_UNUSED) { + return false; + } - for (i = 0; i < ARRAY_SIZE(clients); i++) { - struct bt_mesh_proxy_client *client = &clients[i]; + return (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING || + bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED); +} - if (client->conn_handle == conn_handle) { - if ((MYNEWT_VAL(BLE_MESH_PB_GATT)) && - client->filter_type == PROV) { - bt_mesh_pb_gatt_close(conn_handle); - } +static struct bt_mesh_subnet *next_sub(void) +{ + struct bt_mesh_subnet *sub = NULL; - /* If this fails, the work handler exits early, as - * there's no active connection. - */ - (void)k_work_cancel_delayable(&client->sar_timer); - client->conn_handle = BLE_HS_CONN_HANDLE_NONE; - break; + if (!beacon_sub) { + beacon_sub = bt_mesh_subnet_next(NULL); + if (!beacon_sub) { + /* No valid subnets */ + return NULL; } } - bt_mesh_adv_update(); + sub = beacon_sub; + do { + if (advertise_subnet(sub)) { + beacon_sub = sub; + return sub; + } + + sub = bt_mesh_subnet_next(sub); + } while (sub != beacon_sub); + + /* No subnets to advertise on */ + return NULL; } -struct os_mbuf *bt_mesh_proxy_get_buf(void) +static int sub_count_cb(struct bt_mesh_subnet *sub, void *cb_data) { - struct os_mbuf *buf = clients[0].buf; + int *count = cb_data; - if (buf != NULL) { - net_buf_simple_init(buf, 0); + if (advertise_subnet(sub)) { + (*count)++; } - return buf; + return 0; } -#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) -static void prov_ccc_write(uint16_t conn_handle) +static int sub_count(void) { - struct bt_mesh_proxy_client *client; - - BT_DBG("conn_handle %d", conn_handle); + int count = 0; - /* If a connection exists there must be a client */ - client = find_client(conn_handle); - __ASSERT(client, "No client for connection"); + (void)bt_mesh_subnet_find(sub_count_cb, &count); - if (client->filter_type == NONE) { - client->filter_type = PROV; - bt_mesh_pb_gatt_open(conn_handle); - } + return count; } -int bt_mesh_proxy_prov_enable(void) +static int gatt_proxy_advertise(struct bt_mesh_subnet *sub) { - uint16_t handle; - int rc; - int i; + int32_t remaining = K_FOREVER; + int subnet_count; BT_DBG(""); - if (gatt_svc == MESH_GATT_PROV) { - return -EALREADY; + if (conn_count == CONFIG_BT_MAX_CONN) { + BT_DBG("Connectable advertising deferred (max connections %d)", conn_count); + return -ENOMEM; } - if (gatt_svc != MESH_GATT_NONE) { - return -EBUSY; + sub = beacon_sub ? beacon_sub : bt_mesh_subnet_next(beacon_sub); + if (!sub) { + BT_WARN("No subnets to advertise on"); + return -ENOENT; } - rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle); - assert(rc == 0); - ble_gatts_svc_set_visibility(handle, 1); - /* FIXME: figure out end handle */ - ble_svc_gatt_changed(svc_handles.prov_h, 0xffff); - - gatt_svc = MESH_GATT_PROV; - prov_fast_adv = true; + if (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING) { + uint32_t active = k_uptime_get_32() - sub->node_id_start; - for (i = 0; i < ARRAY_SIZE(clients); i++) { - if (clients[i].conn_handle != BLE_HS_CONN_HANDLE_NONE) { - clients[i].filter_type = PROV; + if (active < NODE_ID_TIMEOUT) { + remaining = NODE_ID_TIMEOUT - active; + BT_DBG("Node ID active for %u ms, %d ms remaining", + (unsigned) active, (int) remaining); + node_id_adv(sub); + } else { + bt_mesh_proxy_identity_stop(sub); + BT_DBG("Node ID stopped"); } } + if (sub->node_id == BT_MESH_NODE_IDENTITY_STOPPED) { + net_id_adv(sub); + } - return 0; -} - -int bt_mesh_proxy_prov_disable(bool disconnect) -{ - uint16_t handle; - int rc; - int i; - - BT_DBG(""); + subnet_count = sub_count(); + BT_DBG("sub_count %u", subnet_count); + if (subnet_count > 1) { + int32_t max_timeout; - if (gatt_svc == MESH_GATT_NONE) { - return -EALREADY; - } + /* We use NODE_ID_TIMEOUT as a starting point since it may + * be less than 60 seconds. Divide this period into at least + * 6 slices, but make sure that a slice is at least one + * second long (to avoid excessive rotation). + */ + max_timeout = NODE_ID_TIMEOUT / max(subnet_count, 6); + max_timeout = max(max_timeout, K_SECONDS(1)); - if (gatt_svc != MESH_GATT_PROV) { - return -EBUSY; + if (remaining > max_timeout || remaining < 0) { + remaining = max_timeout; + } } - rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle); - assert(rc == 0); - ble_gatts_svc_set_visibility(handle, 0); - /* FIXME: figure out end handle */ - ble_svc_gatt_changed(svc_handles.prov_h, 0xffff); - - gatt_svc = MESH_GATT_NONE; + BT_DBG("Advertising %d ms for net_idx 0x%04x", + (int) remaining, sub->net_idx); - for (i = 0; i < ARRAY_SIZE(clients); i++) { - struct bt_mesh_proxy_client *client = &clients[i]; + beacon_sub = bt_mesh_subnet_next(beacon_sub); - if ((client->conn_handle == BLE_HS_CONN_HANDLE_NONE) - || (client->filter_type != PROV)) { - continue; - } + return remaining; +} - if (disconnect) { - rc = ble_gap_terminate(client->conn_handle, - BLE_ERR_REM_USER_CONN_TERM); - assert(rc == 0); - } else { - bt_mesh_pb_gatt_close(client->conn_handle); - client->filter_type = NONE; +static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt) +{ + if (evt == BT_MESH_KEY_DELETED) { + if (sub == beacon_sub) { + beacon_sub = NULL; } + } else { + bt_mesh_proxy_beacon_send(sub); } - - bt_mesh_adv_update(); - - return 0; } -#endif /* MYNEWT_VAL(BLE_MESH_PB_GATT) */ -#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) static void proxy_ccc_write(uint16_t conn_handle) { struct bt_mesh_proxy_client *client; @@ -841,11 +738,10 @@ int bt_mesh_proxy_gatt_enable(void) gatt_svc = MESH_GATT_PROXY; for (i = 0; i < ARRAY_SIZE(clients); i++) { - if (clients[i].conn_handle != BLE_HS_CONN_HANDLE_NONE) { + if (clients[i].cli.conn_handle != BLE_HS_CONN_HANDLE_NONE) { clients[i].filter_type = WHITELIST; } } - return 0; } @@ -859,11 +755,11 @@ void bt_mesh_proxy_gatt_disconnect(void) for (i = 0; i < ARRAY_SIZE(clients); i++) { struct bt_mesh_proxy_client *client = &clients[i]; - if ((client->conn_handle != BLE_HS_CONN_HANDLE_NONE) && + if ((client->cli.conn_handle != BLE_HS_CONN_HANDLE_NONE) && (client->filter_type == WHITELIST || client->filter_type == BLACKLIST)) { client->filter_type = NONE; - rc = ble_gap_terminate(client->conn_handle, + rc = ble_gap_terminate(client->cli.conn_handle, BLE_ERR_REM_USER_CONN_TERM); assert(rc == 0); } @@ -874,7 +770,6 @@ int bt_mesh_proxy_gatt_disable(void) { uint16_t handle; int rc; - BT_DBG(""); if (gatt_svc == MESH_GATT_NONE) { @@ -892,7 +787,6 @@ int bt_mesh_proxy_gatt_disable(void) ble_gatts_svc_set_visibility(handle, 0); /* FIXME: figure out end handle */ ble_svc_gatt_changed(svc_handles.proxy_h, 0xffff); - gatt_svc = MESH_GATT_NONE; return 0; @@ -900,17 +794,8 @@ int bt_mesh_proxy_gatt_disable(void) void bt_mesh_proxy_addr_add(struct os_mbuf *buf, uint16_t addr) { - struct bt_mesh_proxy_client *client = NULL; - int i; - - for (i = 0; i < ARRAY_SIZE(clients); i++) { - client = &clients[i]; - if (client->buf == buf) { - break; - } - } - - assert(client); + struct bt_mesh_proxy_client *client = + CONTAINER_OF(buf, struct bt_mesh_proxy_client, cli.buf); BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr); @@ -973,7 +858,7 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) struct bt_mesh_proxy_client *client = &clients[i]; struct os_mbuf *msg; - if (client->conn_handle == BLE_HS_CONN_HANDLE_NONE) { + if (client->cli.conn_handle == BLE_HS_CONN_HANDLE_NONE) { continue; } @@ -993,12 +878,13 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) net_buf_simple_init(msg, 1); net_buf_simple_add_mem(msg, buf->om_data, buf->om_len); - err = proxy_segment_and_send(client->conn_handle, BT_MESH_PROXY_NET_PDU, + err = bt_mesh_proxy_msg_send(&client->cli, BT_MESH_PROXY_NET_PDU, msg, buf_send_end, net_buf_ref(buf)); adv_send_start(0, err, cb, cb_data); if (err) { BT_ERR("Failed to send proxy message (err %d)", err); + /* If segment_and_send() fails the buf_send_end() callback will * not be called, so we need to clear the user data (net_buf, * which is just opaque data to segment_and send) reference given @@ -1014,354 +900,282 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) return relayed; } -#endif /* MYNEWT_VAL(BLE_MESH_GATT_PROXY) */ -static int proxy_send(uint16_t conn_handle, - const void *data, uint16_t len, - void (*end)(uint16_t, void *), void *user_data) +static void proxy_sar_timeout(struct ble_npl_event *work) { - struct os_mbuf *om; - int err = 0; + struct bt_mesh_proxy_role *role; + int rc; + role = ble_npl_event_get_arg(work); - BT_DBG("%u bytes: %s", len, bt_hex(data, len)); -#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) - if (gatt_svc == MESH_GATT_PROXY) { - om = ble_hs_mbuf_from_flat(data, len); - assert(om); - err = ble_gattc_notify_custom(conn_handle, svc_handles.proxy_data_out_h, om); - /* We do not pass cb into ble_gattc_notify_custom - execute it at the end */ - } -#endif + BT_WARN("Proxy SAR timeout"); -#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) - if (gatt_svc == MESH_GATT_PROV) { - om = ble_hs_mbuf_from_flat(data, len); - assert(om); - err = ble_gattc_notify_custom(conn_handle, svc_handles.prov_data_out_h, om); + if (role->conn_handle) { + rc = ble_gap_terminate(role->conn_handle, + BLE_ERR_REM_USER_CONN_TERM); + assert(rc == 0); } -#endif - - end(conn_handle, user_data); - return err; } +#endif /* CONFIG_BT_MESH_GATT_PROXY */ -static int proxy_segment_and_send(uint16_t conn_handle, uint8_t type, - struct os_mbuf *msg, - void (*end)(uint16_t, void *), void *user_data) +static void gatt_connected(uint16_t conn_handle) { - int err; - uint16_t mtu; - - BT_DBG("conn_handle %d type 0x%02x len %u: %s", conn_handle, type, msg->om_len, - bt_hex(msg->om_data, msg->om_len)); + struct bt_mesh_proxy_client *client; - /* ATT_MTU - OpCode (1 byte) - Handle (2 bytes) */ - mtu = ble_att_mtu(conn_handle) - 3; - if (mtu > msg->om_len) { - net_buf_simple_push_u8(msg, PDU_HDR(SAR_COMPLETE, type)); - return proxy_send(conn_handle, msg->om_data, msg->om_len, end, user_data); - } + BT_DBG("conn %d", conn_handle); - net_buf_simple_push_u8(msg, PDU_HDR(SAR_FIRST, type)); - err = proxy_send(conn_handle, msg->om_data, mtu, NULL, NULL); - if (err) { - return err; - } - net_buf_simple_pull_mem(msg, mtu); + conn_count++; - while (msg->om_len) { - if (msg->om_len + 1 < mtu) { - net_buf_simple_push_u8(msg, PDU_HDR(SAR_LAST, type)); - err = proxy_send(conn_handle, msg->om_data, msg->om_len, end, user_data); - if (err) { - return err; - } - break; - } + /* Since we use ADV_OPT_ONE_TIME */ + gatt_adv_enabled = false; - net_buf_simple_push_u8(msg, PDU_HDR(SAR_CONT, type)); - err = proxy_send(conn_handle, msg->om_data, mtu, NULL, NULL); - if (err) { - return err; - } - net_buf_simple_pull_mem(msg, mtu); + /* Try to re-enable advertising in case it's possible */ + if (conn_count < CONFIG_BT_MAX_CONN) { + bt_mesh_adv_update(); } - return 0; -} - -int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, - void (*end)(uint16_t, void *), void *user_data) -{ - struct bt_mesh_proxy_client *client = find_client(conn_handle); - + client = find_client(BLE_HS_CONN_HANDLE_NONE); if (!client) { - BT_ERR("No Proxy Client found"); - return -ENOTCONN; - } - - if (client->filter_type == PROV) { - BT_ERR("Invalid PDU type for Proxy Client"); - return -EINVAL; + BT_ERR("No free Proxy Client objects"); + return; } - return proxy_segment_and_send(conn_handle, BT_MESH_PROXY_PROV, buf, end, user_data); + client->cli.conn_handle = conn_handle; + client->filter_type = NONE; + (void)memset(client->filter, 0, sizeof(client->filter)); + net_buf_simple_init(client->cli.buf, 0); } -#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) -static uint8_t prov_svc_data[20] = { - BT_UUID_16_ENCODE(BT_UUID_MESH_PROV_VAL), -}; - -static const struct bt_data prov_ad[] = { - BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), - BT_DATA_BYTES(BT_DATA_UUID16_ALL, - BT_UUID_16_ENCODE(BT_UUID_MESH_PROV_VAL)), - BT_DATA(BT_DATA_SVC_DATA16, prov_svc_data, sizeof(prov_svc_data)), -}; -#endif /* PB_GATT */ +static void gatt_disconnected(uint16_t conn_handle, uint8_t reason) +{ + int i; -#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + BT_DBG("conn handle %u reason 0x%02x", conn_handle, reason); -#define ID_TYPE_NET 0x00 -#define ID_TYPE_NODE 0x01 + conn_count--; -#define NODE_ID_LEN 19 -#define NET_ID_LEN 11 + for (i = 0; i < ARRAY_SIZE(clients); i++) { + struct bt_mesh_proxy_client *client = &clients[i]; -#define NODE_ID_TIMEOUT K_SECONDS(CONFIG_BT_MESH_NODE_ID_TIMEOUT) + if (client->cli.conn_handle != conn_handle) { + continue; + } -static uint8_t proxy_svc_data[NODE_ID_LEN] = { - BT_UUID_16_ENCODE(BT_UUID_MESH_PROXY_VAL), -}; + if ((MYNEWT_VAL(BLE_MESH_PB_GATT)) && + client->filter_type == PROV) { + bt_mesh_pb_gatt_close(conn_handle); + } -static const struct bt_data node_id_ad[] = { - BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), - BT_DATA_BYTES(BT_DATA_UUID16_ALL, - BT_UUID_16_ENCODE(BT_UUID_MESH_PROXY_VAL)), - BT_DATA(BT_DATA_SVC_DATA16, proxy_svc_data, NODE_ID_LEN), -}; + /* If this fails, the work handler exits early, as + * there's no active connection. + */ + (void)k_work_cancel_delayable(&client->cli.sar_timer); + client->cli.conn_handle = BLE_HS_CONN_HANDLE_NONE; + break; + } -static const struct bt_data net_id_ad[] = { - BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), - BT_DATA_BYTES(BT_DATA_UUID16_ALL, - BT_UUID_16_ENCODE(BT_UUID_MESH_PROXY_VAL)), - BT_DATA(BT_DATA_SVC_DATA16, proxy_svc_data, NET_ID_LEN), -}; + bt_mesh_adv_update(); +} -static int node_id_adv(struct bt_mesh_subnet *sub) +struct os_mbuf *bt_mesh_proxy_get_buf(void) { - struct ble_gap_adv_params fast_adv_param = { - ADV_OPT_PROXY - ADV_FAST_INT - }; -#if ADV_OPT_USE_NAME - const char *name = CONFIG_BT_DEVICE_NAME; - size_t name_len = strlen(name); - struct bt_data sd = { - .type = BT_DATA_NAME_COMPLETE, - .data_len = name_len, - .data = (void *)name - }; -#else - struct bt_data *sd = NULL; -#endif - uint8_t tmp[16]; - int err; - - BT_DBG(""); + struct os_mbuf *buf = clients[0].cli.buf; - proxy_svc_data[2] = ID_TYPE_NODE; - - err = bt_rand(proxy_svc_data + 11, 8); - if (err) { - return err; + if (buf != NULL) { + net_buf_simple_init(buf, 0); } - memset(tmp, 0, 6); - memcpy(tmp + 6, proxy_svc_data + 11, 8); - sys_put_be16(bt_mesh_primary_addr(), tmp + 14); - - err = bt_encrypt_be(sub->keys[SUBNET_KEY_TX_IDX(sub)].identity, tmp, - tmp); - if (err) { - return err; - } + return buf; +} - memcpy(proxy_svc_data + 3, tmp + 8, 8); +#if defined(CONFIG_BT_MESH_PB_GATT) +static void prov_ccc_write(uint16_t conn_handle) +{ + struct bt_mesh_proxy_client *client; - err = bt_le_adv_start(&fast_adv_param, node_id_ad, - ARRAY_SIZE(node_id_ad), sd, 0); - if (err) { - BT_WARN("Failed to advertise using Node ID (err %d)", err); - return err; - } + BT_DBG("conn_handle %d", conn_handle); - proxy_adv_enabled = true; + /* If a connection exists there must be a client */ + client = find_client(conn_handle); + __ASSERT(client, "No client for connection"); - return 0; + if (client->filter_type == NONE) { + client->filter_type = PROV; + bt_mesh_pb_gatt_open(conn_handle); + } } -static int net_id_adv(struct bt_mesh_subnet *sub) +static int +dummy_access_cb(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) { - struct ble_gap_adv_params slow_adv_param = { - ADV_OPT_PROXY - ADV_SLOW_INT - }; -#if ADV_OPT_USE_NAME - const char *name = CONFIG_BT_DEVICE_NAME; - size_t name_len = strlen(name); - struct bt_data sd = { - .type = BT_DATA_NAME_COMPLETE, - .data_len = name_len, - .data = (void *)name - }; -#else - struct bt_data *sd = NULL; -#endif - int err; - - BT_DBG(""); + /* + * We should never never enter this callback - it's attached to notify-only + * characteristic which are notified directly from mbuf. And we can't pass + * NULL as access_cb because gatts will assert on init... + */ + BLE_HS_DBG_ASSERT(0); + return 0; +} - proxy_svc_data[2] = ID_TYPE_NET; +static const struct ble_gatt_svc_def svc_defs [] = { + { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), + .characteristics = (struct ble_gatt_chr_def[]) { { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_IN_VAL), + .access_cb = gatt_recv, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + }, { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL), + .access_cb = dummy_access_cb, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + .characteristics = (struct ble_gatt_chr_def[]) { { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL), + .access_cb = gatt_recv, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + }, { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL), + .access_cb = dummy_access_cb, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, { + 0, /* No more services. */ + }, +}; - BT_DBG("Advertising with NetId %s", - bt_hex(sub->keys[SUBNET_KEY_TX_IDX(sub)].net_id, 8)); +int bt_mesh_proxy_svcs_register(void) +{ + int rc; - memcpy(proxy_svc_data + 3, sub->keys[SUBNET_KEY_TX_IDX(sub)].net_id, 8); - err = bt_le_adv_start(&slow_adv_param, net_id_ad, - ARRAY_SIZE(net_id_ad), sd, 0); - if (err) { - BT_WARN("Failed to advertise using Network ID (err %d)", err); - return err; - } + rc = ble_gatts_count_cfg(svc_defs); + assert(rc == 0); - proxy_adv_enabled = true; + rc = ble_gatts_add_svcs(svc_defs); + assert(rc == 0); return 0; } -static bool advertise_subnet(struct bt_mesh_subnet *sub) +int bt_mesh_proxy_prov_enable(void) { - if (sub->net_idx == BT_MESH_KEY_UNUSED) { - return false; - } - - return (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING || - bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED); -} + uint16_t handle; + int rc; + int i; -static struct bt_mesh_subnet *next_sub(void) -{ - struct bt_mesh_subnet *sub = NULL; + BT_DBG(""); - if (!beacon_sub) { - beacon_sub = bt_mesh_subnet_next(NULL); - if (!beacon_sub) { - /* No valid subnets */ - return NULL; - } + if (gatt_svc == MESH_GATT_PROV) { + return -EALREADY; } - sub = beacon_sub; - do { - if (advertise_subnet(sub)) { - beacon_sub = sub; - return sub; - } - - sub = bt_mesh_subnet_next(sub); - } while (sub != beacon_sub); - - /* No subnets to advertise on */ + if (gatt_svc != MESH_GATT_NONE) { + return -EBUSY; + } - return NULL; -} + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle); + assert(rc == 0); + ble_gatts_svc_set_visibility(handle, 1); + /* FIXME: figure out end handle */ + ble_svc_gatt_changed(svc_handles.prov_h, 0xffff); -static int sub_count_cb(struct bt_mesh_subnet *sub, void *cb_data) -{ - int *count = cb_data; + gatt_svc = MESH_GATT_PROV; + prov_fast_adv = true; - if (advertise_subnet(sub)) { - (*count)++; + for (i = 0; i < ARRAY_SIZE(clients); i++) { + if (clients[i].cli.conn_handle != BLE_HS_CONN_HANDLE_NONE) { + clients[i].filter_type = PROV; + } } - return 0; -} - -static int sub_count(void) -{ - int count = 0; - (void)bt_mesh_subnet_find(sub_count_cb, &count); - return count; + return 0; } -static int32_t gatt_proxy_advertise(struct bt_mesh_subnet *sub) +int bt_mesh_proxy_prov_disable(bool disconnect) { - int32_t remaining = K_FOREVER; - int subnet_count; + uint16_t handle; + int rc; + int i; BT_DBG(""); - if (conn_count == CONFIG_BT_MAX_CONN) { - BT_DBG("Connectable advertising deferred (max connections %d)", conn_count); - return -ENOMEM; + if (gatt_svc == MESH_GATT_NONE) { + return -EALREADY; } - sub = beacon_sub ? beacon_sub : bt_mesh_subnet_next(beacon_sub); - if (!sub) { - BT_WARN("No subnets to advertise on"); - return -ENOENT; + if (gatt_svc != MESH_GATT_PROV) { + return -EBUSY; } - if (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING) { - uint32_t active = k_uptime_get_32() - sub->node_id_start; + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle); + assert(rc == 0); + ble_gatts_svc_set_visibility(handle, 0); + /* FIXME: figure out end handle */ + ble_svc_gatt_changed(svc_handles.prov_h, 0xffff); - if (active < NODE_ID_TIMEOUT) { - remaining = NODE_ID_TIMEOUT - active; - BT_DBG("Node ID active for %u ms, %d ms remaining", - (unsigned) active, (int) remaining); - node_id_adv(sub); + gatt_svc = MESH_GATT_NONE; + + for (i = 0; i < ARRAY_SIZE(clients); i++) { + struct bt_mesh_proxy_client *client = &clients[i]; + + if (client->cli.conn_handle == BLE_HS_CONN_HANDLE_NONE + || client->filter_type != PROV) { + continue; + } + + if (disconnect) { + rc = ble_gap_terminate(client->cli.conn_handle, + BLE_ERR_REM_USER_CONN_TERM); + assert(rc == 0); } else { - bt_mesh_proxy_identity_stop(sub); - BT_DBG("Node ID stopped"); + bt_mesh_pb_gatt_close(client->cli.conn_handle); + client->filter_type = NONE; } } - if (sub->node_id == BT_MESH_NODE_IDENTITY_STOPPED) { - net_id_adv(sub); - } + bt_mesh_adv_update(); - subnet_count = sub_count(); - BT_DBG("sub_count %u", subnet_count); - if (subnet_count > 1) { - int32_t max_timeout; + return 0; +} - /* We use NODE_ID_TIMEOUT as a starting point since it may - * be less than 60 seconds. Divide this period into at least - * 6 slices, but make sure that a slice is at least one - * second long (to avoid excessive rotation). - */ - max_timeout = NODE_ID_TIMEOUT / max(subnet_count, 6); - max_timeout = max(max_timeout, K_SECONDS(1)); +static uint8_t prov_svc_data[20] = { + BT_UUID_16_ENCODE(BT_UUID_MESH_PROV_VAL), +}; - if (remaining > max_timeout || remaining < 0) { - remaining = max_timeout; - } - } +static const struct bt_data prov_ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA_BYTES(BT_DATA_UUID16_ALL, + BT_UUID_16_ENCODE(BT_UUID_MESH_PROV_VAL)), + BT_DATA(BT_DATA_SVC_DATA16, prov_svc_data, sizeof(prov_svc_data)), +}; - BT_DBG("Advertising %d ms for net_idx 0x%04x", - (int) remaining, sub->net_idx); +int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, + void (*end)(uint16_t, void *), void *user_data) +{ + struct bt_mesh_proxy_client *client = find_client(conn_handle); - beacon_sub = bt_mesh_subnet_next(beacon_sub); + if (!client) { + BT_ERR("No Proxy Client found"); + return -ENOTCONN; + } - return remaining; + if (client->filter_type != PROV) { + BT_ERR("Invalid PDU type for Proxy Client"); + return -EINVAL; + } + + return bt_mesh_proxy_msg_send(&client->cli, BT_MESH_PROXY_PROV, buf, end, user_data); } -#endif /* GATT_PROXY */ -#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) static size_t gatt_prov_adv_create(struct bt_data prov_sd[2]) { const struct bt_mesh_prov *prov = bt_mesh_prov_get(); @@ -1405,7 +1219,37 @@ static size_t gatt_prov_adv_create(struct bt_data prov_sd[2]) return prov_sd_len; } -#endif /* PB_GATT */ +#endif /* CONFIG_BT_MESH_PB_GATT */ + +static int proxy_send(uint16_t conn_handle, + const void *data, uint16_t len, + void (*end)(uint16_t, void *), void *user_data) +{ + struct os_mbuf *om; + int err = 0; + + BT_DBG("%u bytes: %s", len, bt_hex(data, len)); + +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + if (gatt_svc == MESH_GATT_PROXY) { + om = ble_hs_mbuf_from_flat(data, len); + assert(om); + err = ble_gattc_notify_custom(conn_handle, svc_handles.proxy_data_out_h, om); + /* We do not pass cb into ble_gattc_notify_custom - execute it at the end */ + } +#endif + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + if (gatt_svc == MESH_GATT_PROV) { + om = ble_hs_mbuf_from_flat(data, len); + assert(om); + err = ble_gattc_notify_custom(conn_handle, svc_handles.prov_data_out_h, om); + } +#endif + + end(conn_handle, user_data); + return err; +} int32_t bt_mesh_proxy_adv_start(void) { @@ -1439,7 +1283,7 @@ int32_t bt_mesh_proxy_adv_start(void) if (bt_le_adv_start(param, prov_ad, ARRAY_SIZE(prov_ad), prov_sd, prov_sd_len) == 0) { - proxy_adv_enabled = true; + gatt_adv_enabled = true; /* Advertise 60 seconds using fast interval */ if (prov_fast_adv) { @@ -1459,36 +1303,6 @@ int32_t bt_mesh_proxy_adv_start(void) return K_FOREVER; } -void bt_mesh_proxy_adv_stop(void) -{ - int err; - - BT_DBG("adv_enabled %u", proxy_adv_enabled); - - if (!proxy_adv_enabled) { - return; - } - - err = bt_le_adv_stop(true); - if (err) { - BT_ERR("Failed to stop advertising (err %d)", err); - } else { - proxy_adv_enabled = false; - } -} - -#if defined(CONFIG_BT_MESH_GATT_PROXY) -static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt) -{ - if (evt == BT_MESH_KEY_DELETED) { - if (sub == beacon_sub) { - beacon_sub = NULL; - } - } else { - bt_mesh_proxy_beacon_send(sub); - } -} -#endif static void ble_mesh_handle_connect(struct ble_gap_event *event, void *arg) { @@ -1513,7 +1327,7 @@ static void ble_mesh_handle_connect(struct ble_gap_event *event, void *arg) } #else if (event->type == BLE_GAP_EVENT_CONNECT) { - proxy_connected(event->connect.conn_handle); + gatt_connected(event->connect.conn_handle); } #endif } @@ -1521,10 +1335,10 @@ static void ble_mesh_handle_connect(struct ble_gap_event *event, void *arg) int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) { if ((event->type == BLE_GAP_EVENT_CONNECT) || - (event->type == BLE_GAP_EVENT_ADV_COMPLETE)) { + (event->type == BLE_GAP_EVENT_ADV_COMPLETE)) { ble_mesh_handle_connect(event, arg); } else if (event->type == BLE_GAP_EVENT_DISCONNECT) { - proxy_disconnected(event->disconnect.conn.conn_handle, + gatt_disconnected(event->disconnect.conn.conn_handle, event->disconnect.reason); } else if (event->type == BLE_GAP_EVENT_SUBSCRIBE) { if (event->subscribe.attr_handle == svc_handles.proxy_data_out_h) { @@ -1532,7 +1346,7 @@ int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) proxy_ccc_write(event->subscribe.conn_handle); #endif } else if (event->subscribe.attr_handle == - svc_handles.prov_data_out_h) { + svc_handles.prov_data_out_h) { #if (MYNEWT_VAL(BLE_MESH_PB_GATT)) prov_ccc_write(event->subscribe.conn_handle); #endif @@ -1542,93 +1356,89 @@ int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) return 0; } -static int -dummy_access_cb(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, void *arg) + +void bt_mesh_proxy_adv_stop(void) { - /* - * We should never never enter this callback - it's attached to notify-only - * characteristic which are notified directly from mbuf. And we can't pass - * NULL as access_cb because gatts will assert on init... - */ - BLE_HS_DBG_ASSERT(0); - return 0; -} + int err; -static const struct ble_gatt_svc_def svc_defs [] = { - { - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), - .characteristics = (struct ble_gatt_chr_def[]) { { - .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_IN_VAL), - .access_cb = proxy_recv, - .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, - }, { - .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL), - .access_cb = dummy_access_cb, - .flags = BLE_GATT_CHR_F_NOTIFY, - }, { - 0, /* No more characteristics in this service. */ - } }, - }, { - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), - .characteristics = (struct ble_gatt_chr_def[]) { { - .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL), - .access_cb = proxy_recv, - .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, - }, { - .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL), - .access_cb = dummy_access_cb, - .flags = BLE_GATT_CHR_F_NOTIFY, - }, { - 0, /* No more characteristics in this service. */ - } }, - }, { - 0, /* No more services. */ - }, -}; + BT_DBG("adv_enabled %u", gatt_adv_enabled); -int bt_mesh_proxy_svcs_register(void) + if (!gatt_adv_enabled) { + return; + } + + err = bt_le_adv_stop(true); + if (err) { + BT_ERR("Failed to stop advertising (err %d)", err); + } else { + gatt_adv_enabled = false; + } +} + +static void resolve_svc_handles(void) { int rc; - rc = ble_gatts_count_cfg(svc_defs); + /* Either all handles are already resolved, or none of them */ + if (svc_handles.prov_data_out_h) { + return; + } + + /* + * We assert if attribute is not found since at this stage all attributes + * shall be already registered and thus shall be found. + */ + + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), + &svc_handles.proxy_h); assert(rc == 0); - rc = ble_gatts_add_svcs(svc_defs); + rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), + BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL), + NULL, &svc_handles.proxy_data_out_h); assert(rc == 0); - return 0; + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + &svc_handles.prov_h); + assert(rc == 0); + + rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL), + NULL, &svc_handles.prov_data_in_h); + assert(rc == 0); + + rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL), + NULL, &svc_handles.prov_data_out_h); + assert(rc == 0); } + int bt_mesh_proxy_init(void) { - int i; + int i; -#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) - if (!bt_mesh_subnet_cb_list[4]) { - bt_mesh_subnet_cb_list[4] = subnet_evt; - } -#endif + #if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + if (!bt_mesh_subnet_cb_list[4]) { + bt_mesh_subnet_cb_list[4] = subnet_evt; + } + #endif - for (i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); ++i) { -#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) - k_work_init(&clients[i].send_beacons, proxy_send_beacons); -#endif - clients[i].buf = NET_BUF_SIMPLE(CLIENT_BUF_SIZE); - clients[i].conn_handle = BLE_HS_CONN_HANDLE_NONE; + for (i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); ++i) { + #if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + k_work_init(&clients[i].send_beacons, proxy_send_beacons); + #endif + clients[i].cli.buf = NET_BUF_SIMPLE(CLIENT_BUF_SIZE); + clients[i].cli.conn_handle = BLE_HS_CONN_HANDLE_NONE; - k_work_init_delayable(&clients[i].sar_timer, proxy_sar_timeout); - k_work_add_arg_delayable(&clients[i].sar_timer, &clients[i]); - } + k_work_init_delayable(&clients[i].cli.sar_timer, proxy_sar_timeout); + k_work_add_arg_delayable(&clients[i].cli.sar_timer, &clients[i]); + } - resolve_svc_handles(); + resolve_svc_handles(); - ble_gatts_svc_set_visibility(svc_handles.proxy_h, 0); - ble_gatts_svc_set_visibility(svc_handles.prov_h, 0); + ble_gatts_svc_set_visibility(svc_handles.proxy_h, 0); + ble_gatts_svc_set_visibility(svc_handles.prov_h, 0); return 0; -} - -#endif /* MYNEWT_VAL(BLE_MESH_PROXY) */ +} \ No newline at end of file diff --git a/nimble/host/mesh/src/proxy.h b/nimble/host/mesh/src/proxy.h index 27124901f2..2ddb834ea1 100644 --- a/nimble/host/mesh/src/proxy.h +++ b/nimble/host/mesh/src/proxy.h @@ -9,9 +9,6 @@ #ifndef ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROXY_H_ #define ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROXY_H_ -int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, - void (*end)(uint16_t, void *), void *user_data); - #define BT_MESH_PROXY_NET_PDU 0x00 #define BT_MESH_PROXY_BEACON 0x01 #define BT_MESH_PROXY_CONFIG 0x02 @@ -20,6 +17,9 @@ int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, #include "mesh/mesh.h" #include "mesh/slist.h" +int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, + void (*end)(uint16_t, void *), void *user_data); + int bt_mesh_proxy_prov_enable(void); int bt_mesh_proxy_prov_disable(bool disconnect); diff --git a/nimble/host/mesh/src/proxy_msg.c b/nimble/host/mesh/src/proxy_msg.c new file mode 100644 index 0000000000..4c4d694029 --- /dev/null +++ b/nimble/host/mesh/src/proxy_msg.c @@ -0,0 +1,231 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * Copyright (c) 2021 Lingao Meng + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "syscfg/syscfg.h" +#define MESH_LOG_MODULE BLE_MESH_PROXY_LOG + +#if MYNEWT_VAL(BLE_MESH_PROXY) + +#include "mesh/mesh.h" +#include "host/ble_att.h" +#include "services/gatt/ble_svc_gatt.h" +#include "../../host/src/ble_hs_priv.h" + +#include "mesh_priv.h" +#include "adv.h" +#include "net.h" +#include "rpl.h" +#include "prov.h" +#include "beacon.h" +#include "foundation.h" +#include "access.h" +#include "proxy.h" +#include "proxy_msg.h" + +#define PDU_SAR(data) (data[0] >> 6) + +#define BT_UUID_16_ENCODE(w16) \ + (((w16) >> 0) & 0xFF), \ + (((w16) >> 8) & 0xFF) +/* Mesh Profile 1.0 Section 6.6: + * "The timeout for the SAR transfer is 20 seconds. When the timeout + * expires, the Proxy Server shall disconnect." + */ +#define PROXY_SAR_TIMEOUT K_SECONDS(20) + +#define SAR_COMPLETE 0x00 +#define SAR_FIRST 0x01 +#define SAR_CONT 0x02 +#define SAR_LAST 0x03 + +#define PDU_HDR(sar, type) (sar << 6 | (type & BIT_MASK(6))) + + +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) +static void proxy_cfg(struct bt_mesh_proxy_role *role) +{ + struct os_mbuf *buf = NET_BUF_SIMPLE(BT_MESH_NET_MAX_PDU_LEN); + struct bt_mesh_net_rx rx; + int err; + + err = bt_mesh_net_decode(role->buf, BT_MESH_NET_IF_PROXY_CFG, + &rx, buf); + if (err) { + BT_ERR("Failed to decode Proxy Configuration (err %d)", err); + goto done; + } + + rx.local_match = 1U; + + if (bt_mesh_rpl_check(&rx, NULL)) { + BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", + rx.ctx.addr, rx.ctx.recv_dst, rx.seq); + goto done; + } + + /* Remove network headers */ + net_buf_simple_pull_mem(buf, BT_MESH_NET_HDR_LEN); + + BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + + if (buf->om_len < 1) { + BT_WARN("Too short proxy configuration PDU"); + goto done; + } + + role->cb.recv(role->conn_handle, &rx, buf); +done: + os_mbuf_free_chain(buf); +} +#endif /* GATT_PROXY */ + +static void proxy_complete_pdu(struct bt_mesh_proxy_role *role) +{ + switch (role->msg_type) { +#if defined(CONFIG_BT_MESH_PROXY) + case BT_MESH_PROXY_NET_PDU: + BT_INFO("Mesh Network PDU"); + bt_mesh_net_recv(role->buf, 0, BT_MESH_NET_IF_PROXY); + break; + case BT_MESH_PROXY_BEACON: + BT_INFO("Mesh Beacon PDU"); + bt_mesh_beacon_recv(role->buf); + break; + case BT_MESH_PROXY_CONFIG: + BT_INFO("Mesh Configuration PDU"); + proxy_cfg(role); + break; +#endif +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + case BT_MESH_PROXY_PROV: + BT_INFO("Mesh Provisioning PDU"); + bt_mesh_pb_gatt_recv(role->conn_handle, role->buf); + break; +#endif + default: + BT_WARN("Unhandled Message Type 0x%02x", role->msg_type); + break; + } + + net_buf_simple_init(role->buf, 0); +} + +ssize_t bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, + const void *buf, uint16_t len) +{ + const uint8_t *data = buf; + + switch (PDU_SAR(data)) { + case SAR_COMPLETE: + if (role->buf->om_len) { + BT_WARN("Complete PDU while a pending incomplete one"); + return -EINVAL; + } + + role->msg_type = PDU_TYPE(data); + net_buf_simple_add_mem(role->buf, data + 1, len - 1); + proxy_complete_pdu(role); + break; + + case SAR_FIRST: + if (role->buf->om_len) { + BT_WARN("First PDU while a pending incomplete one"); + return -EINVAL; + } + + k_work_reschedule(&role->sar_timer, PROXY_SAR_TIMEOUT); + role->msg_type = PDU_TYPE(data); + net_buf_simple_add_mem(role->buf, data + 1, len - 1); + break; + + case SAR_CONT: + if (!role->buf->om_len) { + BT_WARN("Continuation with no prior data"); + return -EINVAL; + } + + if (role->msg_type != PDU_TYPE(data)) { + BT_WARN("Unexpected message type in continuation"); + return -EINVAL; + } + + k_work_reschedule(&role->sar_timer, PROXY_SAR_TIMEOUT); + net_buf_simple_add_mem(role->buf, data + 1, len - 1); + break; + + case SAR_LAST: + if (!role->buf->om_len) { + BT_WARN("Last SAR PDU with no prior data"); + return -EINVAL; + } + + if (role->msg_type != PDU_TYPE(data)) { + BT_WARN("Unexpected message type in last SAR PDU"); + return -EINVAL; + } + + /* If this fails, the work handler exits early, as there's no + * active SAR buffer. + */ + (void)k_work_cancel_delayable(&role->sar_timer); + net_buf_simple_add_mem(role->buf, data + 1, len - 1); + proxy_complete_pdu(role); + break; + } + + return len; +} + +int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, + struct os_mbuf *msg, + void (*end)(uint16_t, void *), void *user_data) +{ + int err; + uint16_t mtu; + uint16_t conn_handle = role->conn_handle; + + BT_DBG("conn_handle %d type 0x%02x len %u: %s", conn_handle, type, msg->om_len, + bt_hex(msg->om_data, msg->om_len)); + + /* ATT_MTU - OpCode (1 byte) - Handle (2 bytes) */ + mtu = ble_att_mtu(conn_handle) - 3; + if (mtu > msg->om_len) { + net_buf_simple_push_u8(msg, PDU_HDR(SAR_COMPLETE, type)); + return role->cb.send(conn_handle, msg->om_data, msg->om_len, end, user_data); + } + + net_buf_simple_push_u8(msg, PDU_HDR(SAR_FIRST, type)); + err = role->cb.send(conn_handle, msg->om_data, mtu, NULL, NULL); + if (err) { + return err; + } + net_buf_simple_pull_mem(msg, mtu); + + while (msg->om_len) { + if (msg->om_len + 1 < mtu) { + net_buf_simple_push_u8(msg, PDU_HDR(SAR_LAST, type)); + err = role->cb.send(conn_handle, msg->om_data, msg->om_len, end, user_data); + if (err) { + return err; + } + break; + } + + net_buf_simple_push_u8(msg, PDU_HDR(SAR_CONT, type)); + err = role->cb.send(conn_handle, msg->om_data, mtu, NULL, NULL); + if (err) { + return err; + } + net_buf_simple_pull_mem(msg, mtu); + } + + return 0; +} + +#endif /* MYNEWT_VAL(BLE_MESH_PROXY) */ diff --git a/nimble/host/mesh/src/proxy_msg.h b/nimble/host/mesh/src/proxy_msg.h new file mode 100644 index 0000000000..2a9f046c99 --- /dev/null +++ b/nimble/host/mesh/src/proxy_msg.h @@ -0,0 +1,47 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * Copyright (c) 2021 Lingao Meng + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROXY_MSG_H_ +#define ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROXY_MSG_H_ + +#define PDU_TYPE(data) (data[0] & BIT_MASK(6)) +#define CFG_FILTER_SET 0x00 +#define CFG_FILTER_ADD 0x01 +#define CFG_FILTER_REMOVE 0x02 +#define CFG_FILTER_STATUS 0x03 + +#define PDU_HDR(sar, type) (sar << 6 | (type & BIT_MASK(6))) + +typedef int (*proxy_send_cb_t)(uint16_t conn_handle, + const void *data, uint16_t len, + void (*end)(uint16_t, void *), void *user_data); + +typedef void (*proxy_recv_cb_t)(uint16_t conn_handle, + struct bt_mesh_net_rx *rx, struct os_mbuf *buf); + +struct bt_mesh_proxy_role { + uint16_t conn_handle; + uint8_t msg_type; + + struct { + proxy_send_cb_t send; + proxy_recv_cb_t recv; + } cb; + + struct k_work_delayable sar_timer; + struct os_mbuf *buf; +}; + +ssize_t bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, + const void *buf, uint16_t len); +int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, + struct os_mbuf *msg, void (*end)(uint16_t, void *), void *user_data); +void bt_mesh_proxy_msg_init(struct bt_mesh_proxy_role *role); + +#endif /* ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROXY_MSG_H_ */ diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index dcde094443..58d227c691 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -100,11 +100,20 @@ syscfg.defs: BLE_MESH_GATT_PROXY is set. value: 0 + BLE_MESH_GATT: + value: 1 + + BLE_MESH_GATT_SERVER: + value: 1 + restrictions: BLE_MESH_GATT + BLE_MESH_PB_GATT: description: > Enable this option to allow the device to be provisioned over the GATT bearer. value: 1 + restrictions: + - '(BLE_MESH_GATT_SERVER && BLE_MESH_PROV)' BLE_MESH_GATT_PROXY: description: > @@ -112,6 +121,8 @@ syscfg.defs: i.e. the ability to act as a proxy between a Mesh GATT Client and a Mesh network. value: 1 + restrictions: + - '(BLE_MESH_GATT_SERVER && BLE_MESH_PROXY)' BLE_MESH_GATT_PROXY_ENABLED: description: > @@ -140,6 +151,7 @@ syscfg.defs: This option specifies how many Proxy Filter entries the local node supports. value: 1 + restrictions: BLE_MESH_GATT_SERVER BLE_MESH_PROXY_USE_DEVICE_NAME: description: > From 610fbc4005b0869b8ce4cee2aba9ea59b5a2c6d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 13 Oct 2021 16:07:08 +0200 Subject: [PATCH 0116/1333] host/mesh: Add return value for opcode callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` 3.7.3.4 Message error procedure When receiving a message that is not understood by an element, it shall ignore the message. Note: A message can be falsely identified as a valid message, passing the NetMIC and TransMIC authentication using a known network key and application key even though that message was sent using different keys. The decryption of that message using the wrong keys would result in a message that is not understood by the element. The probability of such a situation occurring is small but not insignificant. A message that is not understood includes messages that have one or more of the following conditions: • The application opcode is unknown by the receiving element. • The access message size for the application opcode is incorrect. • The application parameters contain values that are currently Prohibited. Note: An element that sends an acknowledged message that is not understood by a peer node will not receive any response message. ``` This is port of b9422ea9f3f937e2d95b72ba993b9dbae901916d --- nimble/host/mesh/include/mesh/access.h | 6 +- nimble/host/mesh/src/access.c | 2 +- nimble/host/mesh/src/cfg_cli.c | 223 ++++++----- nimble/host/mesh/src/cfg_srv.c | 524 ++++++++++++++----------- nimble/host/mesh/src/health_cli.c | 40 +- nimble/host/mesh/src/health_srv.c | 94 +++-- nimble/host/mesh/src/model_cli.c | 12 +- nimble/host/mesh/src/model_srv.c | 64 +-- 8 files changed, 555 insertions(+), 410 deletions(-) diff --git a/nimble/host/mesh/include/mesh/access.h b/nimble/host/mesh/include/mesh/access.h index c3f36f43a0..de64f74f38 100644 --- a/nimble/host/mesh/include/mesh/access.h +++ b/nimble/host/mesh/include/mesh/access.h @@ -148,9 +148,9 @@ struct bt_mesh_model_op { const size_t min_len; /* Message handler for the opcode */ - void (*const func)(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf); + int (*const func)(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf); }; #define BT_MESH_MODEL_OP_1(b0) (b0) diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index 359d8c4e27..95e199c8dc 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -668,7 +668,7 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) * receive the message. */ net_buf_simple_save(buf, &state); - op->func(model, &rx->ctx, buf); + (void)op->func(model, &rx->ctx, buf); net_buf_simple_restore(buf, &state); } } diff --git a/nimble/host/mesh/src/cfg_cli.c b/nimble/host/mesh/src/cfg_cli.c index dc56f992d5..a1a88f0acb 100644 --- a/nimble/host/mesh/src/cfg_cli.c +++ b/nimble/host/mesh/src/cfg_cli.c @@ -33,9 +33,9 @@ static int32_t msg_timeout = K_SECONDS(5); static struct bt_mesh_cfg_cli *cli; -static void comp_data_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int comp_data_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct comp_data *param; size_t to_copy; @@ -46,7 +46,7 @@ static void comp_data_status(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_DEV_COMP_DATA_STATUS, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } if (param->page) { @@ -56,12 +56,14 @@ static void comp_data_status(struct bt_mesh_model *model, net_buf_simple_add_mem(param->comp, buf->om_data, to_copy); bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; } -static void state_status_u8(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf*buf, - uint32_t expect_status) +static int state_status_u8(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf, + uint32_t expect_status) { uint8_t *status; @@ -71,40 +73,42 @@ static void state_status_u8(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, expect_status, ctx->addr, (void **)&status)) { - return; + return -ENOENT; } *status = net_buf_simple_pull_u8(buf); bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; } -static void beacon_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int beacon_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { - state_status_u8(model, ctx, buf, OP_BEACON_STATUS); + return state_status_u8(model, ctx, buf, OP_BEACON_STATUS); } -static void ttl_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf*buf) +static int ttl_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) { - state_status_u8(model, ctx, buf, OP_DEFAULT_TTL_STATUS); + return state_status_u8(model, ctx, buf, OP_DEFAULT_TTL_STATUS); } -static void friend_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf*buf) +static int friend_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) { - state_status_u8(model, ctx, buf, OP_FRIEND_STATUS); + return state_status_u8(model, ctx, buf, OP_FRIEND_STATUS); } -static void gatt_proxy_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf*buf) +static int gatt_proxy_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) { - state_status_u8(model, ctx, buf, OP_GATT_PROXY_STATUS); + return state_status_u8(model, ctx, buf, OP_GATT_PROXY_STATUS); } struct relay_param { @@ -112,9 +116,9 @@ struct relay_param { uint8_t *transmit; }; -static void relay_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf*buf) +static int relay_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) { struct relay_param *param; @@ -124,18 +128,20 @@ static void relay_status(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_RELAY_STATUS, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } *param->status = net_buf_simple_pull_u8(buf); *param->transmit = net_buf_simple_pull_u8(buf); bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; } -static void net_transmit_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int net_transmit_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint8_t *status; @@ -145,12 +151,14 @@ static void net_transmit_status(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NET_TRANSMIT_STATUS, ctx->addr, (void **)&status)) { - return; + return -ENOENT; } *status = net_buf_simple_pull_u8(buf); bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; } struct net_key_param { @@ -158,9 +166,9 @@ struct net_key_param { uint16_t net_idx; }; -static void net_key_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int net_key_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct net_key_param *param; uint16_t net_idx; @@ -172,7 +180,7 @@ static void net_key_status(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NET_KEY_STATUS, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } status = net_buf_simple_pull_u8(buf); @@ -180,7 +188,7 @@ static void net_key_status(struct bt_mesh_model *model, if (param->net_idx != net_idx) { BT_WARN("Net Key Status key index does not match"); - return; + return -ENOENT; } if (param->status) { @@ -188,6 +196,8 @@ static void net_key_status(struct bt_mesh_model *model, } bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; } struct net_key_list_param { @@ -195,9 +205,9 @@ struct net_key_list_param { size_t *key_cnt; }; -static void net_key_list(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int net_key_list(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct net_key_list_param *param; int i; @@ -208,7 +218,7 @@ static void net_key_list(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NET_KEY_LIST, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } for (i = 0; i < *param->key_cnt && buf->om_len >= 3; i += 2) { @@ -222,10 +232,13 @@ static void net_key_list(struct bt_mesh_model *model, *param->key_cnt = i; bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; } -static void node_reset_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) +static int node_reset_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { bool *param = NULL; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x", @@ -233,13 +246,15 @@ static void node_reset_status(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NODE_RESET_STATUS, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } if (param) { *param = true; } bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; } struct app_key_param { @@ -248,9 +263,9 @@ struct app_key_param { uint16_t app_idx; }; -static void app_key_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf*buf) +static int app_key_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) { struct app_key_param *param; uint16_t net_idx, app_idx; @@ -262,7 +277,7 @@ static void app_key_status(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_APP_KEY_STATUS, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } status = net_buf_simple_pull_u8(buf); @@ -270,7 +285,7 @@ static void app_key_status(struct bt_mesh_model *model, if (param->net_idx != net_idx || param->app_idx != app_idx) { BT_WARN("App Key Status key indices did not match"); - return; + return -ENOENT; } if (param->status) { @@ -278,6 +293,8 @@ static void app_key_status(struct bt_mesh_model *model, } bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; } struct app_key_list_param { @@ -287,9 +304,9 @@ struct app_key_list_param { size_t *key_cnt; }; -static void app_key_list(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int app_key_list(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct app_key_list_param *param; uint16_t net_idx; @@ -302,7 +319,7 @@ static void app_key_list(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_APP_KEY_LIST, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } status = net_buf_simple_pull_u8(buf); @@ -310,7 +327,7 @@ static void app_key_list(struct bt_mesh_model *model, if (param->net_idx != net_idx) { BT_WARN("App Key List Net Key index did not match"); - return; + return -ENOENT; } for (i = 0; i < *param->key_cnt && buf->om_len >= 3; i += 2) { @@ -327,6 +344,8 @@ static void app_key_list(struct bt_mesh_model *model, } bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; } struct mod_app_param { @@ -337,9 +356,9 @@ struct mod_app_param { uint16_t cid; }; -static void mod_app_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf*buf) +static int mod_app_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) { uint16_t elem_addr, mod_app_idx, mod_id, cid; struct mod_app_param *param; @@ -351,7 +370,7 @@ static void mod_app_status(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_APP_STATUS, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } status = net_buf_simple_pull_u8(buf); @@ -370,7 +389,7 @@ static void mod_app_status(struct bt_mesh_model *model, param->mod_app_idx != mod_app_idx || param->mod_id != mod_id || param->cid != cid) { BT_WARN("Model App Status parameters did not match"); - return; + return -ENOENT; } if (param->status) { @@ -378,6 +397,8 @@ static void mod_app_status(struct bt_mesh_model *model, } bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; } struct mod_member_list_param { @@ -389,9 +410,9 @@ struct mod_member_list_param { size_t *member_cnt; }; -static void mod_member_list_handle(struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf, bool vnd, - struct mod_member_list_param *param) +static int mod_member_list_handle(struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf, bool vnd, + struct mod_member_list_param *param) { uint16_t elem_addr, mod_id, cid; uint8_t status; @@ -408,12 +429,12 @@ static void mod_member_list_handle(struct bt_mesh_msg_ctx *ctx, if (param->elem_addr != elem_addr || param->mod_id != mod_id || (vnd && param->cid != cid)) { BT_WARN("Model Member List parameters did not match"); - return; + return -ENOENT; } if (buf->om_len % 2) { BT_WARN("Model Member List invalid length"); - return; + return -ENOENT; } for (i = 0; i < *param->member_cnt && buf->om_len; i++) { @@ -426,9 +447,11 @@ static void mod_member_list_handle(struct bt_mesh_msg_ctx *ctx, } bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; } -static void mod_app_list(struct bt_mesh_model *model, +static int mod_app_list(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -440,13 +463,13 @@ static void mod_app_list(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_SIG_MOD_APP_LIST, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } - mod_member_list_handle(ctx, buf, false, param); + return mod_member_list_handle(ctx, buf, false, param); } -static void mod_app_list_vnd(struct bt_mesh_model *model, +static int mod_app_list_vnd(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -458,10 +481,10 @@ static void mod_app_list_vnd(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_VND_MOD_APP_LIST, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } - mod_member_list_handle(ctx, buf, true, param); + return mod_member_list_handle(ctx, buf, true, param); } struct mod_pub_param { @@ -472,7 +495,7 @@ struct mod_pub_param { struct bt_mesh_cfg_mod_pub *pub; }; -static void mod_pub_status(struct bt_mesh_model *model, +static int mod_pub_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf*buf) { @@ -487,13 +510,13 @@ static void mod_pub_status(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_PUB_STATUS, ctx->addr, (void **)¶m)) { BT_WARN("Unexpected Model Pub Status message"); - return; + return -ENOENT; } if (param->cid != CID_NVAL) { if (buf->om_len < 14) { BT_WARN("Unexpected Mod Pub Status with SIG Model"); - return; + return -ENOENT; } cid = sys_get_le16(&buf->om_data[10]); @@ -501,7 +524,7 @@ static void mod_pub_status(struct bt_mesh_model *model, } else { if (buf->om_len > 12) { BT_WARN("Unexpected Mod Pub Status with Vendor Model"); - return; + return -ENOENT; } cid = CID_NVAL; @@ -510,7 +533,7 @@ static void mod_pub_status(struct bt_mesh_model *model, if (mod_id != param->mod_id || cid != param->cid) { BT_WARN("Mod Pub Model ID or Company ID mismatch"); - return; + return -ENOENT; } status = net_buf_simple_pull_u8(buf); @@ -519,7 +542,7 @@ static void mod_pub_status(struct bt_mesh_model *model, if (elem_addr != param->elem_addr) { BT_WARN("Model Pub Status for unexpected element (0x%04x)", elem_addr); - return; + return -ENOENT; } if (param->status) { @@ -537,6 +560,8 @@ static void mod_pub_status(struct bt_mesh_model *model, } bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; } struct mod_sub_param { @@ -548,9 +573,9 @@ struct mod_sub_param { uint16_t cid; }; -static void mod_sub_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf*buf) +static int mod_sub_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) { uint16_t elem_addr, sub_addr, mod_id, cid; struct mod_sub_param *param; @@ -562,7 +587,7 @@ static void mod_sub_status(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_SUB_STATUS, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } status = net_buf_simple_pull_u8(buf); @@ -581,7 +606,7 @@ static void mod_sub_status(struct bt_mesh_model *model, (param->expect_sub && *param->expect_sub != sub_addr) || param->cid != cid) { BT_WARN("Model Subscription Status parameters did not match"); - return; + return -ENOENT; } if (param->sub_addr) { @@ -593,11 +618,13 @@ static void mod_sub_status(struct bt_mesh_model *model, } bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; } -static void mod_sub_list(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int mod_sub_list(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct mod_member_list_param *param; @@ -607,13 +634,13 @@ static void mod_sub_list(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_SUB_LIST, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } - mod_member_list_handle(ctx, buf, false, param); + return mod_member_list_handle(ctx, buf, false, param); } -static void mod_sub_list_vnd(struct bt_mesh_model *model, +static int mod_sub_list_vnd(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -625,10 +652,10 @@ static void mod_sub_list_vnd(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_SUB_LIST_VND, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } - mod_member_list_handle(ctx, buf, true,param); + return mod_member_list_handle(ctx, buf, true,param); } struct hb_sub_param { @@ -636,9 +663,9 @@ struct hb_sub_param { struct bt_mesh_cfg_hb_sub *sub; }; -static void hb_sub_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf*buf) +static int hb_sub_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) { struct hb_sub_param *param; @@ -648,7 +675,7 @@ static void hb_sub_status(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_HEARTBEAT_SUB_STATUS, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } *param->status = net_buf_simple_pull_u8(buf); @@ -661,6 +688,8 @@ static void hb_sub_status(struct bt_mesh_model *model, param->sub->max = net_buf_simple_pull_u8(buf); bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; } struct hb_pub_param { @@ -668,7 +697,7 @@ struct hb_pub_param { struct bt_mesh_cfg_hb_pub *pub; }; -static void hb_pub_status(struct bt_mesh_model *model, +static int hb_pub_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -680,7 +709,7 @@ static void hb_pub_status(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_HEARTBEAT_PUB_STATUS, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } *param->status = net_buf_simple_pull_u8(buf); @@ -695,6 +724,8 @@ static void hb_pub_status(struct bt_mesh_model *model, } bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; } const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = { diff --git a/nimble/host/mesh/src/cfg_srv.c b/nimble/host/mesh/src/cfg_srv.c index 734faa7c8f..f5518fd12e 100644 --- a/nimble/host/mesh/src/cfg_srv.c +++ b/nimble/host/mesh/src/cfg_srv.c @@ -109,12 +109,13 @@ static int comp_get_page_0(struct os_mbuf *buf) return 0; } -static void dev_comp_data_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int dev_comp_data_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct os_mbuf *sdu = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); uint8_t page; + int err; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, @@ -129,7 +130,8 @@ static void dev_comp_data_get(struct bt_mesh_model *model, bt_mesh_model_msg_init(sdu, OP_DEV_COMP_DATA_STATUS); net_buf_simple_add_u8(sdu, page); - if (comp_get_page_0(sdu) < 0) { + err = comp_get_page_0(sdu); + if (err) { BT_ERR("Unable to get composition page 0"); goto done; } @@ -140,6 +142,7 @@ static void dev_comp_data_get(struct bt_mesh_model *model, done: os_mbuf_free_chain(sdu); + return err; } static struct bt_mesh_model *get_model(struct bt_mesh_elem *elem, @@ -319,10 +322,10 @@ uint8_t mod_unbind(struct bt_mesh_model *model, uint16_t key_idx, bool store) return STATUS_SUCCESS; } -static void send_app_key_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - uint8_t status, - uint16_t app_idx, uint16_t net_idx) +static int send_app_key_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + uint8_t status, + uint16_t app_idx, uint16_t net_idx) { struct os_mbuf *msg = NET_BUF_SIMPLE( BT_MESH_MODEL_BUF_LEN(OP_APP_KEY_STATUS, 4)); @@ -336,11 +339,12 @@ static void send_app_key_status(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + return 0; } -static void app_key_add(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int app_key_add(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint16_t key_net_idx, key_app_idx; uint8_t status; @@ -351,10 +355,10 @@ static void app_key_add(struct bt_mesh_model *model, status = bt_mesh_app_key_add(key_app_idx, key_net_idx, buf->om_data); - send_app_key_status(model, ctx, status, key_app_idx, key_net_idx); + return send_app_key_status(model, ctx, status, key_app_idx, key_net_idx); } -static void app_key_update(struct bt_mesh_model *model, +static int app_key_update(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -367,7 +371,7 @@ static void app_key_update(struct bt_mesh_model *model, status = bt_mesh_app_key_update(key_app_idx, key_net_idx, buf->om_data); BT_DBG("status 0x%02x", status); - send_app_key_status(model, ctx, status, key_app_idx, key_net_idx); + return send_app_key_status(model, ctx, status, key_app_idx, key_net_idx); } static void mod_app_key_del(struct bt_mesh_model *mod, @@ -387,9 +391,9 @@ static void app_key_evt(uint16_t app_idx, uint16_t net_idx, } } -static void app_key_del(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int app_key_del(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint16_t key_net_idx, key_app_idx; uint8_t status; @@ -400,15 +404,15 @@ static void app_key_del(struct bt_mesh_model *model, status = bt_mesh_app_key_del(key_app_idx, key_net_idx); - send_app_key_status(model, ctx, status, key_app_idx, key_net_idx); + return send_app_key_status(model, ctx, status, key_app_idx, key_net_idx); } /* Index list length: 3 bytes for every pair and 2 bytes for an odd idx */ #define IDX_LEN(num) (((num) / 2) * 3 + ((num) % 2) * 2) -static void app_key_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int app_key_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_APP_KEY_LIST, @@ -418,10 +422,12 @@ static void app_key_get(struct bt_mesh_model *model, uint8_t status; ssize_t count; int i; + int err = 0; get_idx = net_buf_simple_pull_le16(buf); if (get_idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", get_idx); + err = -EINVAL; goto done; } @@ -461,10 +467,11 @@ static void app_key_get(struct bt_mesh_model *model, } done: - os_mbuf_free_chain(msg); + os_mbuf_free_chain(msg); + return err; } -static void beacon_get(struct bt_mesh_model *model, +static int beacon_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -480,13 +487,16 @@ static void beacon_get(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Config Beacon Status response"); } + + return 0; os_mbuf_free_chain(msg); } -static void beacon_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int beacon_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { + int err = 0; struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_BEACON_STATUS, 1); BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", @@ -495,6 +505,7 @@ static void beacon_set(struct bt_mesh_model *model, if (buf->om_data[0] != 0x00 && buf->om_data[0] != 0x01) { BT_WARN("Invalid Config Beacon value 0x%02x", buf->om_data[0]); + err = -EINVAL; goto done; } @@ -509,12 +520,12 @@ static void beacon_set(struct bt_mesh_model *model, done: os_mbuf_free_chain(msg); - + return err; } -static void default_ttl_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int default_ttl_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_DEFAULT_TTL_STATUS, 1); @@ -530,12 +541,12 @@ static void default_ttl_get(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); - + return 0; } -static void default_ttl_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int default_ttl_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_DEFAULT_TTL_STATUS, 1); int err; @@ -559,9 +570,10 @@ static void default_ttl_set(struct bt_mesh_model *model, done: os_mbuf_free_chain(msg); + return err; } -static void send_gatt_proxy_status(struct bt_mesh_model *model, +static int send_gatt_proxy_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_GATT_PROXY_STATUS, 1); @@ -575,20 +587,21 @@ static void send_gatt_proxy_status(struct bt_mesh_model *model, os_mbuf_free_chain(msg); + return 0; } -static void gatt_proxy_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int gatt_proxy_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - send_gatt_proxy_status(model, ctx); + return send_gatt_proxy_status(model, ctx); } -static void gatt_proxy_set(struct bt_mesh_model *model, +static int gatt_proxy_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -598,15 +611,15 @@ static void gatt_proxy_set(struct bt_mesh_model *model, if (buf->om_data[0] != 0x00 && buf->om_data[0] != 0x01) { BT_WARN("Invalid GATT Proxy value 0x%02x", buf->om_data[0]); - return; + return -EINVAL; } (void)bt_mesh_gatt_proxy_set(buf->om_data[0]); - send_gatt_proxy_status(model, ctx); + return send_gatt_proxy_status(model, ctx); } -static void net_transmit_get(struct bt_mesh_model *model, +static int net_transmit_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -625,11 +638,12 @@ static void net_transmit_get(struct bt_mesh_model *model, os_mbuf_free_chain(msg); + return 0; } -static void net_transmit_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int net_transmit_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NET_TRANSMIT_STATUS, 1); @@ -651,9 +665,11 @@ static void net_transmit_set(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + + return 0; } -static void relay_get(struct bt_mesh_model *model, +static int relay_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -673,13 +689,15 @@ static void relay_get(struct bt_mesh_model *model, os_mbuf_free_chain(msg); + return 0; } -static void relay_set(struct bt_mesh_model *model, +static int relay_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_RELAY_STATUS, 2); + int err = 0; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, @@ -687,6 +705,7 @@ static void relay_set(struct bt_mesh_model *model, if (buf->om_data[0] != 0x00 && buf->om_data[0] != 0x01) { BT_WARN("Invalid Relay value 0x%02x", buf->om_data[0]); + err = -EINVAL; goto done; } @@ -702,14 +721,14 @@ static void relay_set(struct bt_mesh_model *model, done: os_mbuf_free_chain(msg); - + return err; } -static void send_mod_pub_status(struct bt_mesh_model *cfg_mod, - struct bt_mesh_msg_ctx *ctx, - uint16_t elem_addr, uint16_t pub_addr, - bool vnd, struct bt_mesh_model *mod, - uint8_t status, uint8_t *mod_id) +static int send_mod_pub_status(struct bt_mesh_model *cfg_mod, + struct bt_mesh_msg_ctx *ctx, + uint16_t elem_addr, uint16_t pub_addr, + bool vnd, struct bt_mesh_model *mod, + uint8_t status, uint8_t *mod_id) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_PUB_STATUS, 14); @@ -743,11 +762,12 @@ static void send_mod_pub_status(struct bt_mesh_model *cfg_mod, } os_mbuf_free_chain(msg); + return 0; } -static void mod_pub_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int mod_pub_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint16_t elem_addr, pub_addr = 0; struct bt_mesh_model *mod; @@ -758,7 +778,7 @@ static void mod_pub_get(struct bt_mesh_model *model, elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); - return; + return -EINVAL; } mod_id = buf->om_data; @@ -788,11 +808,11 @@ static void mod_pub_get(struct bt_mesh_model *model, status = STATUS_SUCCESS; send_status: - send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, - status, mod_id); + return send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, + status, mod_id); } -static void mod_pub_set(struct bt_mesh_model *model, +static int mod_pub_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -806,7 +826,7 @@ static void mod_pub_set(struct bt_mesh_model *model, elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); - return; + return -EINVAL; } pub_addr = net_buf_simple_pull_le16(buf); @@ -817,7 +837,7 @@ static void mod_pub_set(struct bt_mesh_model *model, pub_ttl = net_buf_simple_pull_u8(buf); if (pub_ttl > BT_MESH_TTL_MAX && pub_ttl != BT_MESH_TTL_DEFAULT) { BT_ERR("Invalid TTL value 0x%02x", pub_ttl); - return; + return -EINVAL; } pub_period = net_buf_simple_pull_u8(buf); @@ -850,8 +870,8 @@ static void mod_pub_set(struct bt_mesh_model *model, pub_period, retransmit, true); send_status: - send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, - status, mod_id); + return send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, + status, mod_id); } static size_t mod_sub_list_clear(struct bt_mesh_model *mod) @@ -886,9 +906,9 @@ static size_t mod_sub_list_clear(struct bt_mesh_model *mod) return clear_count; } -static void mod_pub_va_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int mod_pub_va_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint8_t retransmit, status, pub_ttl, pub_period, cred_flag; uint16_t elem_addr, pub_addr, pub_app_idx; @@ -901,7 +921,7 @@ static void mod_pub_va_set(struct bt_mesh_model *model, elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); - return; + return -EINVAL; } label_uuid = net_buf_simple_pull_mem(buf, 16); @@ -911,7 +931,7 @@ static void mod_pub_va_set(struct bt_mesh_model *model, pub_ttl = net_buf_simple_pull_u8(buf); if (pub_ttl > BT_MESH_TTL_MAX && pub_ttl != BT_MESH_TTL_DEFAULT) { BT_ERR("Invalid TTL value 0x%02x", pub_ttl); - return; + return -EINVAL; } pub_period = net_buf_simple_pull_u8(buf); @@ -953,14 +973,14 @@ static void mod_pub_va_set(struct bt_mesh_model *model, } send_status: - send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, - status, mod_id); + return send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, + status, mod_id); } -static void send_mod_sub_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, uint8_t status, - uint16_t elem_addr, uint16_t sub_addr, uint8_t *mod_id, - bool vnd) +static int send_mod_sub_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, uint8_t status, + uint16_t elem_addr, uint16_t sub_addr, uint8_t *mod_id, + bool vnd) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_SUB_STATUS, 9); @@ -984,11 +1004,13 @@ static void send_mod_sub_status(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + + return 0; } -static void mod_sub_add(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int mod_sub_add(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint16_t elem_addr, sub_addr; struct bt_mesh_model *mod; @@ -1001,7 +1023,7 @@ static void mod_sub_add(struct bt_mesh_model *model, elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); - return; + return -EINVAL; } sub_addr = net_buf_simple_pull_le16(buf); @@ -1055,13 +1077,13 @@ static void mod_sub_add(struct bt_mesh_model *model, send_status: - send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, - mod_id, vnd); + return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, + mod_id, vnd); } -static void mod_sub_del(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int mod_sub_del(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint16_t elem_addr, sub_addr; struct bt_mesh_model *mod; @@ -1074,7 +1096,7 @@ static void mod_sub_del(struct bt_mesh_model *model, elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); - return; + return -EINVAL; } sub_addr = net_buf_simple_pull_le16(buf); @@ -1121,8 +1143,8 @@ static void mod_sub_del(struct bt_mesh_model *model, } send_status: - send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, - mod_id, vnd); + return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, + mod_id, vnd); } static enum bt_mesh_walk mod_sub_clear_visitor(struct bt_mesh_model *mod, @@ -1137,9 +1159,9 @@ static enum bt_mesh_walk mod_sub_clear_visitor(struct bt_mesh_model *mod, return BT_MESH_WALK_CONTINUE; } -static void mod_sub_overwrite(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int mod_sub_overwrite(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint16_t elem_addr, sub_addr; struct bt_mesh_model *mod; @@ -1151,7 +1173,7 @@ static void mod_sub_overwrite(struct bt_mesh_model *model, elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); - return; + return -EINVAL; } sub_addr = net_buf_simple_pull_le16(buf); @@ -1199,13 +1221,13 @@ static void mod_sub_overwrite(struct bt_mesh_model *model, send_status: - send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, + return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, mod_id, vnd); } -static void mod_sub_del_all(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int mod_sub_del_all(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct bt_mesh_model *mod; struct bt_mesh_elem *elem; @@ -1217,7 +1239,7 @@ static void mod_sub_del_all(struct bt_mesh_model *model, elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); - return; + return -EINVAL; } BT_DBG("elem_addr 0x%04x", elem_addr); @@ -1248,8 +1270,8 @@ static void mod_sub_del_all(struct bt_mesh_model *model, status = STATUS_SUCCESS; send_status: - send_mod_sub_status(model, ctx, status, elem_addr, - BT_MESH_ADDR_UNASSIGNED, mod_id, vnd); + return send_mod_sub_status(model, ctx, status, elem_addr, + BT_MESH_ADDR_UNASSIGNED, mod_id, vnd); } struct mod_sub_list_ctx { @@ -1289,19 +1311,21 @@ static enum bt_mesh_walk mod_sub_list_visitor(struct bt_mesh_model *mod, return BT_MESH_WALK_CONTINUE; } -static void mod_sub_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int mod_sub_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct os_mbuf *msg = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); struct mod_sub_list_ctx visit_ctx; struct bt_mesh_model *mod; struct bt_mesh_elem *elem; uint16_t addr, id; + int err = 0; addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(addr)) { BT_WARN("Prohibited element address"); + err = -EINVAL; goto done; } @@ -1345,21 +1369,24 @@ static void mod_sub_get(struct bt_mesh_model *model, done: os_mbuf_free_chain(msg); + return err; } -static void mod_sub_get_vnd(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int mod_sub_get_vnd(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct os_mbuf *msg = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); struct mod_sub_list_ctx visit_ctx; struct bt_mesh_model *mod; struct bt_mesh_elem *elem; uint16_t company, addr, id; + int err = 0; addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(addr)) { BT_WARN("Prohibited element address"); + err = -EINVAL; goto done; } @@ -1407,11 +1434,12 @@ static void mod_sub_get_vnd(struct bt_mesh_model *model, done: os_mbuf_free_chain(msg); + return err; } -static void mod_sub_va_add(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int mod_sub_va_add(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint16_t elem_addr, sub_addr; struct bt_mesh_model *mod; @@ -1425,7 +1453,7 @@ static void mod_sub_va_add(struct bt_mesh_model *model, elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); - return; + return -EINVAL; } label_uuid = net_buf_simple_pull_mem(buf, 16); @@ -1482,13 +1510,13 @@ static void mod_sub_va_add(struct bt_mesh_model *model, status = STATUS_SUCCESS; send_status: - send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, - mod_id, vnd); + return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, + mod_id, vnd); } -static void mod_sub_va_del(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int mod_sub_va_del(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint16_t elem_addr, sub_addr; struct bt_mesh_model *mod; @@ -1502,7 +1530,7 @@ static void mod_sub_va_del(struct bt_mesh_model *model, elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); - return; + return -EINVAL; } label_uuid = net_buf_simple_pull_mem(buf, 16); @@ -1550,13 +1578,13 @@ static void mod_sub_va_del(struct bt_mesh_model *model, } send_status: - send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, - mod_id, vnd); + return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, + mod_id, vnd); } -static void mod_sub_va_overwrite(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int mod_sub_va_overwrite(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint16_t elem_addr, sub_addr = BT_MESH_ADDR_UNASSIGNED; struct bt_mesh_model *mod; @@ -1569,7 +1597,7 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); - return; + return -EINVAL; } label_uuid = net_buf_simple_pull_mem(buf, 16); @@ -1612,13 +1640,13 @@ static void mod_sub_va_overwrite(struct bt_mesh_model *model, } send_status: - send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, - mod_id, vnd); + return send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, + mod_id, vnd); } -static void send_net_key_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - uint16_t idx, uint8_t status) +static int send_net_key_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + uint16_t idx, uint8_t status) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NET_KEY_STATUS, 3); @@ -1632,9 +1660,11 @@ static void send_net_key_status(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + + return 0; } -static void net_key_add(struct bt_mesh_model *model, +static int net_key_add(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1644,18 +1674,18 @@ static void net_key_add(struct bt_mesh_model *model, idx = net_buf_simple_pull_le16(buf); if (idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", idx); - return; + return -EINVAL; } BT_DBG("idx 0x%04x", idx); status = bt_mesh_subnet_add(idx, buf->om_data); - send_net_key_status(model, ctx, idx, status); + return send_net_key_status(model, ctx, idx, status); } -static void net_key_update(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int net_key_update(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint8_t status; uint16_t idx; @@ -1663,24 +1693,24 @@ static void net_key_update(struct bt_mesh_model *model, idx = net_buf_simple_pull_le16(buf); if (idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", idx); - return; + return -EINVAL; } status = bt_mesh_subnet_update(idx, buf->om_data); - send_net_key_status(model, ctx, idx, status); + return send_net_key_status(model, ctx, idx, status); } -static void net_key_del(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int net_key_del(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint16_t del_idx; del_idx = net_buf_simple_pull_le16(buf); if (del_idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", del_idx); - return; + return -EINVAL; } BT_DBG("idx 0x%04x", del_idx); @@ -1689,19 +1719,18 @@ static void net_key_del(struct bt_mesh_model *model, * The NetKey List must contain a minimum of one NetKey. */ if (ctx->net_idx == del_idx) { - send_net_key_status(model, ctx, del_idx, + return send_net_key_status(model, ctx, del_idx, STATUS_CANNOT_REMOVE); - return; } - bt_mesh_subnet_del(del_idx); + (void)bt_mesh_subnet_del(del_idx); - send_net_key_status(model, ctx, del_idx, STATUS_SUCCESS); + return send_net_key_status(model, ctx, del_idx, STATUS_SUCCESS); } -static void net_key_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int net_key_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NET_KEY_LIST, @@ -1730,12 +1759,13 @@ static void net_key_get(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + return 0; } -static void send_node_id_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - uint8_t status, - uint16_t net_idx, uint8_t node_id) +static int send_node_id_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + uint8_t status, + uint16_t net_idx, uint8_t node_id) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NODE_IDENTITY_STATUS, 4); @@ -1749,11 +1779,13 @@ static void send_node_id_status(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + + return 0; } -static void node_identity_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int node_identity_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { enum bt_mesh_feat_state node_id; uint8_t status; @@ -1766,17 +1798,17 @@ static void node_identity_get(struct bt_mesh_model *model, idx = net_buf_simple_pull_le16(buf); if (idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", idx); - return; + return -EINVAL; } status = bt_mesh_subnet_node_id_get(idx, &node_id); - send_node_id_status(model, ctx, status, idx, node_id); + return send_node_id_status(model, ctx, status, idx, node_id); } -static void node_identity_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int node_identity_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint8_t node_id, status; uint16_t idx; @@ -1788,30 +1820,28 @@ static void node_identity_set(struct bt_mesh_model *model, idx = net_buf_simple_pull_le16(buf); if (idx > 0xfff) { BT_WARN("Invalid NetKeyIndex 0x%04x", idx); - return; + return -EINVAL; } node_id = net_buf_simple_pull_u8(buf); if (node_id != 0x00 && node_id != 0x01) { BT_WARN("Invalid Node ID value 0x%02x", node_id); - return; + return -EINVAL; } status = bt_mesh_subnet_node_id_set(idx, node_id); if (status == STATUS_INVALID_NETKEY) { - send_node_id_status(model, ctx, status, idx, - BT_MESH_NODE_IDENTITY_STOPPED); - return; + return send_node_id_status(model, ctx, status, idx, + BT_MESH_NODE_IDENTITY_STOPPED); } if (status == STATUS_FEAT_NOT_SUPP) { /* Should return success, even if feature isn't supported: */ - send_node_id_status(model, ctx, STATUS_SUCCESS, idx, - BT_MESH_NODE_IDENTITY_NOT_SUPPORTED); - return; + return send_node_id_status(model, ctx, STATUS_SUCCESS, idx, + BT_MESH_NODE_IDENTITY_NOT_SUPPORTED); } - send_node_id_status(model, ctx, status, idx, node_id); + return send_node_id_status(model, ctx, status, idx, node_id); } static void create_mod_app_status(struct os_mbuf *msg, @@ -1832,9 +1862,9 @@ static void create_mod_app_status(struct os_mbuf *msg, } } -static void mod_app_bind(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int mod_app_bind(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_APP_STATUS, 9); uint16_t elem_addr, key_app_idx; @@ -1842,10 +1872,12 @@ static void mod_app_bind(struct bt_mesh_model *model, struct bt_mesh_elem *elem; uint8_t *mod_id, status; bool vnd; + int err = 0; elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); + err = -EINVAL; goto done; } @@ -1889,13 +1921,14 @@ static void mod_app_bind(struct bt_mesh_model *model, } done: - os_mbuf_free_chain(msg); + os_mbuf_free_chain(msg); + return err; } -static void mod_app_unbind(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int mod_app_unbind(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_APP_STATUS, 9); uint16_t elem_addr, key_app_idx; @@ -1903,10 +1936,12 @@ static void mod_app_unbind(struct bt_mesh_model *model, struct bt_mesh_elem *elem; uint8_t *mod_id, status; bool vnd; + int err = 0; elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); + err = -EINVAL; goto done; } @@ -1943,14 +1978,16 @@ static void mod_app_unbind(struct bt_mesh_model *model, } done: - os_mbuf_free_chain(msg); + os_mbuf_free_chain(msg); + + return err; } #define KEY_LIST_LEN (MYNEWT_VAL(BLE_MESH_MODEL_KEY_COUNT) * 2) -static void mod_app_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int mod_app_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct os_mbuf *msg = NET_BUF_SIMPLE(max(BT_MESH_MODEL_BUF_LEN(OP_VND_MOD_APP_LIST, 9 + KEY_LIST_LEN), @@ -1962,10 +1999,12 @@ static void mod_app_get(struct bt_mesh_model *model, uint8_t *mod_id, status; uint16_t elem_addr; bool vnd; + int err = 0; elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); + err = -EINVAL; goto done; } @@ -2021,6 +2060,8 @@ static void mod_app_get(struct bt_mesh_model *model, done: os_mbuf_free_chain(msg); + + return err; } static void reset_send_start(uint16_t duration, int err, void *cb_data) @@ -2036,9 +2077,9 @@ static void reset_send_end(int err, void *cb_data) bt_mesh_reset(); } -static void node_reset(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int node_reset(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { static const struct bt_mesh_send_cb reset_cb = { .start = reset_send_start, @@ -2058,10 +2099,12 @@ static void node_reset(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + + return 0; } -static void send_friend_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx) +static int send_friend_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_FRIEND_STATUS, 1); @@ -2071,23 +2114,26 @@ static void send_friend_status(struct bt_mesh_model *model, if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { BT_ERR("Unable to send Friend Status"); } - os_mbuf_free_chain(msg); + + os_mbuf_free_chain(msg); + + return 0; } -static void friend_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int friend_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - send_friend_status(model, ctx); + return send_friend_status(model, ctx); } -static void friend_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int friend_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, @@ -2095,22 +2141,23 @@ static void friend_set(struct bt_mesh_model *model, if (buf->om_data[0] != 0x00 && buf->om_data[0] != 0x01) { BT_WARN("Invalid Friend value 0x%02x", buf->om_data[0]); - return; + return -EINVAL; } (void)bt_mesh_friend_set(buf->om_data[0]); - send_friend_status(model, ctx); + return send_friend_status(model, ctx); } -static void lpn_timeout_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int lpn_timeout_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_LPN_TIMEOUT_STATUS, 5); struct bt_mesh_friend *frnd; int32_t timeout_steps; uint16_t lpn_addr; + int err = 0; lpn_addr = net_buf_simple_pull_le16(buf); @@ -2120,6 +2167,7 @@ static void lpn_timeout_get(struct bt_mesh_model *model, /* check if it's the address of the Low Power Node? */ if (!BT_MESH_ADDR_IS_UNICAST(lpn_addr)) { BT_WARN("Invalid LPNAddress; ignoring msg"); + err = -EINVAL; goto done; } @@ -2149,11 +2197,13 @@ static void lpn_timeout_get(struct bt_mesh_model *model, done: os_mbuf_free_chain(msg); + + return err; } -static void send_krp_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - uint16_t idx, uint8_t phase, uint8_t status) +static int send_krp_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + uint16_t idx, uint8_t phase, uint8_t status) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_KRP_STATUS, 4); @@ -2168,10 +2218,12 @@ static void send_krp_status(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + + return 0; } -static void krp_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int krp_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint8_t kr_phase, status; uint16_t idx; @@ -2179,18 +2231,18 @@ static void krp_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, idx = net_buf_simple_pull_le16(buf); if (idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", idx); - return; + return -EINVAL; } BT_DBG("idx 0x%04x", idx); status = bt_mesh_subnet_kr_phase_get(idx, &kr_phase); - send_krp_status(model, ctx, idx, kr_phase, status); + return send_krp_status(model, ctx, idx, kr_phase, status); } -static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint8_t phase, status; uint16_t idx; @@ -2200,16 +2252,16 @@ static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, if (idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", idx); - return; + return -EINVAL; } status = bt_mesh_subnet_kr_phase_set(idx, &phase); if (status == STATUS_CANNOT_UPDATE) { BT_ERR("Invalid kr phase transition 0x%02x", phase); - return; + return -EINVAL; } - send_krp_status(model, ctx, idx, phase, status); + return send_krp_status(model, ctx, idx, phase, status); } static uint8_t hb_pub_count_log(uint16_t val) @@ -2234,9 +2286,9 @@ struct hb_pub_param { uint16_t net_idx; } __packed; -static void hb_pub_send_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, uint8_t status, - const struct bt_mesh_hb_pub *pub) +static int hb_pub_send_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, uint8_t status, + const struct bt_mesh_hb_pub *pub) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEARTBEAT_PUB_STATUS, 10); @@ -2258,9 +2310,11 @@ static void hb_pub_send_status(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + + return 0; } -static void heartbeat_pub_get(struct bt_mesh_model *model, +static int heartbeat_pub_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -2270,12 +2324,12 @@ static void heartbeat_pub_get(struct bt_mesh_model *model, bt_mesh_hb_pub_get(&pub); - hb_pub_send_status(model, ctx, STATUS_SUCCESS, &pub); + return hb_pub_send_status(model, ctx, STATUS_SUCCESS, &pub); } -static void heartbeat_pub_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int heartbeat_pub_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct hb_pub_param *param = (void *)buf->om_data; struct bt_mesh_hb_pub pub; @@ -2308,22 +2362,22 @@ static void heartbeat_pub_set(struct bt_mesh_model *model, if (param->ttl > BT_MESH_TTL_MAX && param->ttl != BT_MESH_TTL_DEFAULT) { BT_ERR("Invalid TTL value 0x%02x", param->ttl); - return; + return -EINVAL; } if (pub.net_idx > 0xfff) { BT_ERR("Invalid NetKeyIndex 0x%04x", pub.net_idx); - return; + return -EINVAL; } status = bt_mesh_hb_pub_set(&pub); rsp: - hb_pub_send_status(model, ctx, status, &pub); + return hb_pub_send_status(model, ctx, status, &pub); } -static void hb_sub_send_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - const struct bt_mesh_hb_sub *sub) +static int hb_sub_send_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + const struct bt_mesh_hb_sub *sub) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEARTBEAT_SUB_STATUS, 9); BT_DBG("src 0x%04x ", ctx->addr); @@ -2344,11 +2398,13 @@ static void hb_sub_send_status(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + + return 0; } -static void heartbeat_sub_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int heartbeat_sub_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct bt_mesh_hb_sub sub; @@ -2356,17 +2412,18 @@ static void heartbeat_sub_get(struct bt_mesh_model *model, bt_mesh_hb_sub_get(&sub); - hb_sub_send_status(model, ctx, &sub); + return hb_sub_send_status(model, ctx, &sub); } -static void heartbeat_sub_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int heartbeat_sub_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { uint8_t period_log, status; struct bt_mesh_hb_sub sub; uint16_t sub_src, sub_dst; uint32_t period; + int err; BT_DBG("src 0x%04x", ctx->addr); @@ -2379,7 +2436,7 @@ static void heartbeat_sub_set(struct bt_mesh_model *model, if (period_log > 0x11) { BT_WARN("Prohibited subscription period 0x%02x", period_log); - return; + return -EINVAL; } period = bt_mesh_hb_pwr2(period_log); @@ -2389,7 +2446,7 @@ static void heartbeat_sub_set(struct bt_mesh_model *model, /* All errors are caused by invalid packets, which should be * ignored. */ - return; + return -EINVAL; } bt_mesh_hb_sub_get(&sub); @@ -2401,7 +2458,10 @@ static void heartbeat_sub_set(struct bt_mesh_model *model, sub.min_hops = BT_MESH_TTL_MAX; } - hb_sub_send_status(model, ctx, &sub); + err = hb_sub_send_status(model, ctx, &sub); + if (err) { + return err; + } /* MESH/NODE/CFG/HBS/BV-02-C expects us to return previous * count value and then reset it to 0. @@ -2410,6 +2470,8 @@ static void heartbeat_sub_set(struct bt_mesh_model *model, sub.dst != BT_MESH_ADDR_UNASSIGNED && !period) { bt_mesh_hb_sub_reset_count(); } + + return 0; } const struct bt_mesh_model_op bt_mesh_cfg_srv_op[] = { diff --git a/nimble/host/mesh/src/health_cli.c b/nimble/host/mesh/src/health_cli.c index c6057c5643..2be41d313e 100644 --- a/nimble/host/mesh/src/health_cli.c +++ b/nimble/host/mesh/src/health_cli.c @@ -33,9 +33,9 @@ struct health_fault_param { size_t *fault_count; }; -static void health_fault_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int health_fault_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct health_fault_param *param; uint8_t test_id; @@ -47,19 +47,19 @@ static void health_fault_status(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&health_cli->ack_ctx, OP_HEALTH_FAULT_STATUS, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } test_id = net_buf_simple_pull_u8(buf); if (param->expect_test_id && test_id != *param->expect_test_id) { BT_WARN("Health fault with unexpected Test ID"); - return; + return -ENOENT; } cid = net_buf_simple_pull_le16(buf); if (cid != param->cid) { BT_WARN("Health fault with unexpected Company ID"); - return; + return -ENOENT; } if (param->test_id) { @@ -75,11 +75,13 @@ static void health_fault_status(struct bt_mesh_model *model, memcpy(param->faults, buf->om_data, *param->fault_count); bt_mesh_msg_ack_ctx_rx(&health_cli->ack_ctx); + + return 0; } -static void health_current_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int health_current_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct bt_mesh_health_cli *cli = model->user_data; uint8_t test_id; @@ -97,19 +99,21 @@ static void health_current_status(struct bt_mesh_model *model, if (!cli->current_status) { BT_WARN("No Current Status callback available"); - return; + return 0; } cli->current_status(cli, ctx->addr, test_id, cid, buf->om_data, buf->om_len); + + return 0; } struct health_period_param { uint8_t *divisor; }; -static void health_period_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int health_period_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct health_period_param *param; @@ -119,19 +123,21 @@ static void health_period_status(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&health_cli->ack_ctx, OP_HEALTH_PERIOD_STATUS, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } *param->divisor = net_buf_simple_pull_u8(buf); bt_mesh_msg_ack_ctx_rx(&health_cli->ack_ctx); + + return 0; } struct health_attention_param { uint8_t *attention; }; -static void health_attention_status(struct bt_mesh_model *model, +static int health_attention_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -143,7 +149,7 @@ static void health_attention_status(struct bt_mesh_model *model, if (!bt_mesh_msg_ack_ctx_match(&health_cli->ack_ctx, OP_ATTENTION_STATUS, ctx->addr, (void **)¶m)) { - return; + return -ENOENT; } if (param->attention) { @@ -151,6 +157,8 @@ static void health_attention_status(struct bt_mesh_model *model, } bt_mesh_msg_ack_ctx_rx(&health_cli->ack_ctx); + + return 0; } const struct bt_mesh_model_op bt_mesh_health_cli_op[] = { diff --git a/nimble/host/mesh/src/health_srv.c b/nimble/host/mesh/src/health_srv.c index d7436b30a3..c1b0dd884f 100644 --- a/nimble/host/mesh/src/health_srv.c +++ b/nimble/host/mesh/src/health_srv.c @@ -67,7 +67,6 @@ static size_t health_get_current(struct bt_mesh_model *mod, uint8_t *test_id, *company_ptr; uint16_t company_id; uint8_t fault_count; - int err; bt_mesh_model_msg_init(msg, OP_HEALTH_CURRENT_STATUS); @@ -77,6 +76,8 @@ static size_t health_get_current(struct bt_mesh_model *mod, if (srv->cb && srv->cb->fault_get_cur) { fault_count = net_buf_simple_tailroom(msg); + int err; + err = srv->cb->fault_get_cur(mod, test_id, &company_id, net_buf_simple_tail(msg), &fault_count); @@ -99,9 +100,9 @@ static size_t health_get_current(struct bt_mesh_model *mod, return fault_count; } -static void health_fault_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int health_fault_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct os_mbuf *sdu = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); uint16_t company_id; @@ -117,11 +118,13 @@ static void health_fault_get(struct bt_mesh_model *model, } os_mbuf_free_chain(sdu); + + return 0; } -static void health_fault_clear_unrel(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int health_fault_clear_unrel(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct bt_mesh_health_srv *srv = model->user_data; uint16_t company_id; @@ -131,13 +134,15 @@ static void health_fault_clear_unrel(struct bt_mesh_model *model, BT_DBG("company_id 0x%04x", company_id); if (srv->cb && srv->cb->fault_clear) { - srv->cb->fault_clear(model, company_id); + return srv->cb->fault_clear(model, company_id); } + + return 0; } -static void health_fault_clear(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int health_fault_clear(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct os_mbuf *sdu = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); struct bt_mesh_health_srv *srv = model->user_data; @@ -148,7 +153,12 @@ static void health_fault_clear(struct bt_mesh_model *model, BT_DBG("company_id 0x%04x", company_id); if (srv->cb && srv->cb->fault_clear) { - srv->cb->fault_clear(model, company_id); + int err; + + err = srv->cb->fault_clear(model, company_id); + if (err) { + return err; + } } health_get_registered(model, company_id, sdu); @@ -158,9 +168,11 @@ static void health_fault_clear(struct bt_mesh_model *model, } os_mbuf_free_chain(sdu); + + return 0; } -static void health_fault_test_unrel(struct bt_mesh_model *model, +static int health_fault_test_unrel(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -174,18 +186,21 @@ static void health_fault_test_unrel(struct bt_mesh_model *model, BT_DBG("test 0x%02x company 0x%04x", test_id, company_id); if (srv->cb && srv->cb->fault_test) { - srv->cb->fault_test(model, test_id, company_id); + return srv->cb->fault_test(model, test_id, company_id); } + + return 0; } -static void health_fault_test(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int health_fault_test(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { struct os_mbuf *sdu = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); struct bt_mesh_health_srv *srv = model->user_data; uint16_t company_id; uint8_t test_id; + int err = 0; BT_DBG(""); @@ -195,11 +210,10 @@ static void health_fault_test(struct bt_mesh_model *model, BT_DBG("test 0x%02x company 0x%04x", test_id, company_id); if (srv->cb && srv->cb->fault_test) { - int err; - err = srv->cb->fault_test(model, test_id, company_id); if (err) { BT_WARN("Running fault test failed with err %d", err); + goto done; } } @@ -212,10 +226,12 @@ static void health_fault_test(struct bt_mesh_model *model, done: os_mbuf_free_chain(sdu); + + return err; } -static void send_attention_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx) +static int send_attention_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_ATTENTION_STATUS, 1); struct bt_mesh_health_srv *srv = model->user_data; @@ -234,18 +250,20 @@ static void send_attention_status(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + + return 0; } -static void attention_get(struct bt_mesh_model *model, +static int attention_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { BT_DBG(""); - send_attention_status(model, ctx); + return send_attention_status(model, ctx); } -static void attention_set_unrel(struct bt_mesh_model *model, +static int attention_set_unrel(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -256,20 +274,22 @@ static void attention_set_unrel(struct bt_mesh_model *model, BT_DBG("%u second%s", time, (time == 1) ? "" : "s"); bt_mesh_attention(model, time); + + return 0; } -static void attention_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct os_mbuf *buf) +static int attention_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { BT_DBG(""); attention_set_unrel(model, ctx, buf); - send_attention_status(model, ctx); + return send_attention_status(model, ctx); } -static void send_health_period_status(struct bt_mesh_model *model, +static int send_health_period_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_HEALTH_PERIOD_STATUS, 1); @@ -283,18 +303,20 @@ static void send_health_period_status(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + + return 0; } -static void health_period_get(struct bt_mesh_model *model, +static int health_period_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { BT_DBG(""); - send_health_period_status(model, ctx); + return send_health_period_status(model, ctx); } -static void health_period_set_unrel(struct bt_mesh_model *model, +static int health_period_set_unrel(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -303,15 +325,17 @@ static void health_period_set_unrel(struct bt_mesh_model *model, period = net_buf_simple_pull_u8(buf); if (period > 15) { BT_WARN("Prohibited period value %u", period); - return; + return -EINVAL; } BT_DBG("period %u", period); model->pub->period_div = period; + + return 0; } -static void health_period_set(struct bt_mesh_model *model, +static int health_period_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -319,7 +343,7 @@ static void health_period_set(struct bt_mesh_model *model, health_period_set_unrel(model, ctx, buf); - send_health_period_status(model, ctx); + return send_health_period_status(model, ctx); } const struct bt_mesh_model_op bt_mesh_health_srv_op[] = { diff --git a/nimble/host/mesh/src/model_cli.c b/nimble/host/mesh/src/model_cli.c index 9755ec1fd9..fd052426a1 100644 --- a/nimble/host/mesh/src/model_cli.c +++ b/nimble/host/mesh/src/model_cli.c @@ -26,7 +26,7 @@ struct gen_level_param { int16_t *level; }; -static void gen_onoff_status(struct bt_mesh_model *model, +static int gen_onoff_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -41,7 +41,7 @@ static void gen_onoff_status(struct bt_mesh_model *model, if (cli->op_pending != OP_GEN_ONOFF_STATUS) { BT_WARN("Unexpected Generic OnOff Status message"); - return; + return -ENOENT; } param = cli->op_param; @@ -54,9 +54,11 @@ static void gen_onoff_status(struct bt_mesh_model *model, BT_DBG("state: %d", state); k_sem_give(&cli->op_sync); + + return 0; } -static void gen_level_status(struct bt_mesh_model *model, +static int gen_level_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -71,7 +73,7 @@ static void gen_level_status(struct bt_mesh_model *model, if (cli->op_pending != OP_GEN_LEVEL_STATUS) { BT_WARN("Unexpected Generic LEVEL Status message"); - return; + return -EINVAL; } param = cli->op_param; @@ -84,6 +86,8 @@ static void gen_level_status(struct bt_mesh_model *model, BT_DBG("level: %d", level); k_sem_give(&cli->op_sync); + + return 0; } const struct bt_mesh_model_op gen_onoff_cli_op[] = { diff --git a/nimble/host/mesh/src/model_srv.c b/nimble/host/mesh/src/model_srv.c index b6f34360aa..96981cbab6 100644 --- a/nimble/host/mesh/src/model_srv.c +++ b/nimble/host/mesh/src/model_srv.c @@ -15,9 +15,10 @@ static struct bt_mesh_gen_onoff_srv *gen_onoff_srv; static struct bt_mesh_gen_level_srv *gen_level_srv; static struct bt_mesh_light_lightness_srv *light_lightness_srv; -static void gen_onoff_status(struct bt_mesh_model *model, +static int gen_onoff_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { + int err; struct bt_mesh_gen_onoff_srv *cb = model->user_data; struct os_mbuf *msg = NET_BUF_SIMPLE(3); uint8_t *state; @@ -30,23 +31,26 @@ static void gen_onoff_status(struct bt_mesh_model *model, BT_DBG("state: %d", *state); - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + err = bt_mesh_model_send(model, ctx, msg, NULL, NULL); + if (err) { BT_ERR("Send status failed"); } os_mbuf_free_chain(msg); + + return err; } -static void gen_onoff_get(struct bt_mesh_model *model, +static int gen_onoff_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { BT_DBG(""); - gen_onoff_status(model, ctx); + return gen_onoff_status(model, ctx); } -static void gen_onoff_set_unack(struct bt_mesh_model *model, +static int gen_onoff_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -58,23 +62,26 @@ static void gen_onoff_set_unack(struct bt_mesh_model *model, BT_DBG("state: %d", state); if (cb && cb->set) { - cb->set(model, state); + return cb->set(model, state); } + + return 0; } -static void gen_onoff_set(struct bt_mesh_model *model, +static int gen_onoff_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { BT_DBG(""); gen_onoff_set_unack(model, ctx, buf); - gen_onoff_status(model, ctx); + return gen_onoff_status(model, ctx); } -static void gen_level_status(struct bt_mesh_model *model, +static int gen_level_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { + int err; struct bt_mesh_gen_level_srv *cb = model->user_data; struct os_mbuf *msg = NET_BUF_SIMPLE(4); int16_t *level; @@ -87,23 +94,25 @@ static void gen_level_status(struct bt_mesh_model *model, BT_DBG("level: %d", *level); - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + err = bt_mesh_model_send(model, ctx, msg, NULL, NULL); + if (err) { BT_ERR("Send status failed"); } os_mbuf_free_chain(msg); + return err; } -static void gen_level_get(struct bt_mesh_model *model, +static int gen_level_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { BT_DBG(""); - gen_level_status(model, ctx); + return gen_level_status(model, ctx); } -static void gen_level_set_unack(struct bt_mesh_model *model, +static int gen_level_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { struct bt_mesh_gen_level_srv *cb = model->user_data; @@ -113,21 +122,24 @@ static void gen_level_set_unack(struct bt_mesh_model *model, BT_DBG("level: %d", level); if (cb && cb->set) { - cb->set(model, level); + return cb->set(model, level); } + + return 0; } -static void gen_level_set(struct bt_mesh_model *model, +static int gen_level_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { gen_level_set_unack(model, ctx, buf); - gen_level_status(model, ctx); + return gen_level_status(model, ctx); } -static void light_lightness_status(struct bt_mesh_model *model, +static int light_lightness_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { + int err; struct bt_mesh_light_lightness_srv *cb = model->user_data; struct os_mbuf *msg = NET_BUF_SIMPLE(4); int16_t *lightness; @@ -140,23 +152,25 @@ static void light_lightness_status(struct bt_mesh_model *model, BT_DBG("lightness: %d", *lightness); - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + err = bt_mesh_model_send(model, ctx, msg, NULL, NULL); + if (err) { BT_ERR("Send status failed"); } os_mbuf_free_chain(msg); + return err; } -static void light_lightness_get(struct bt_mesh_model *model, +static int light_lightness_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { BT_DBG(""); - light_lightness_status(model, ctx); + return light_lightness_status(model, ctx); } -static void light_lightness_set_unack(struct bt_mesh_model *model, +static int light_lightness_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { struct bt_mesh_light_lightness_srv *cb = model->user_data; @@ -166,16 +180,18 @@ static void light_lightness_set_unack(struct bt_mesh_model *model, BT_DBG("lightness: %d", lightness); if (cb && cb->set) { - cb->set(model, lightness); + return cb->set(model, lightness); } + + return 0; } -static void light_lightness_set(struct bt_mesh_model *model, +static int light_lightness_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { light_lightness_set_unack(model, ctx, buf); - light_lightness_status(model, ctx); + return light_lightness_status(model, ctx); } const struct bt_mesh_model_op gen_onoff_srv_op[] = { From d278a2d4433a611520fc98ade418057ddcbb2a7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 13 Oct 2021 16:30:11 +0200 Subject: [PATCH 0117/1333] host/mesh: Add msg length check for Cfg and Health models According to spec we should ignore messages with incorrect msg size. This patch adds a check to every opcode handler. This is port of ca53e86f67c5bf0e21ec5ed6701f1a1801d8766a --- nimble/host/mesh/include/mesh/access.h | 15 ++- nimble/host/mesh/src/access.c | 6 +- nimble/host/mesh/src/cfg_cli.c | 103 +++++++++------- nimble/host/mesh/src/cfg_srv.c | 159 +++++++++++++++++-------- nimble/host/mesh/src/health_cli.c | 8 +- nimble/host/mesh/src/health_srv.c | 36 ++++-- 6 files changed, 216 insertions(+), 111 deletions(-) diff --git a/nimble/host/mesh/include/mesh/access.h b/nimble/host/mesh/include/mesh/access.h index de64f74f38..e20cf70086 100644 --- a/nimble/host/mesh/include/mesh/access.h +++ b/nimble/host/mesh/include/mesh/access.h @@ -11,6 +11,7 @@ #define __BT_MESH_ACCESS_H #include "msg.h" +#include /** * @brief Bluetooth Mesh Access Layer @@ -144,8 +145,13 @@ struct bt_mesh_model_op { /* OpCode encoded using the BT_MESH_MODEL_OP_* macros */ const uint32_t opcode; - /* Minimum required message length */ - const size_t min_len; + /** Message length. If the message has variable length then this value + * indicates minimum message length and should be positive. Handler + * function should verify precise length based on the contents of the + * message. If the message has fixed length then this value should + * be negative. Use BT_MESH_LEN_* macros when defining this value. + */ + const ssize_t len; /* Message handler for the opcode */ int (*const func)(struct bt_mesh_model *model, @@ -157,6 +163,11 @@ struct bt_mesh_model_op { #define BT_MESH_MODEL_OP_2(b0, b1) (((b0) << 8) | (b1)) #define BT_MESH_MODEL_OP_3(b0, cid) ((((b0) << 16) | 0xc00000) | (cid)) +/** Macro for encoding exact message length for fixed-length messages. */ +#define BT_MESH_LEN_EXACT(len) (-len) +/** Macro for encoding minimum message length for variable-length messages. */ +#define BT_MESH_LEN_MIN(len) (len) + #define BT_MESH_MODEL_OP_END { 0, 0, NULL } #define BT_MESH_MODEL_NO_OPS ((struct bt_mesh_model_op []) \ { BT_MESH_MODEL_OP_END }) diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index 95e199c8dc..c0f8632e54 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -658,9 +658,13 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) continue; } - if (buf->om_len < op->min_len) { + if ((op->len >= 0) && (buf->om_len < (size_t)op->len)) { BT_ERR("Too short message for OpCode 0x%08x", opcode); continue; + } else if ((op->len < 0) && (buf->om_len != (size_t)(-op->len))) { + BT_ERR("Invalid message size for OpCode 0x%08x", + opcode); + continue; } /* The callback will likely parse the buffer, so diff --git a/nimble/host/mesh/src/cfg_cli.c b/nimble/host/mesh/src/cfg_cli.c index a1a88f0acb..99a7c1685a 100644 --- a/nimble/host/mesh/src/cfg_cli.c +++ b/nimble/host/mesh/src/cfg_cli.c @@ -143,22 +143,7 @@ static int net_transmit_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - uint8_t *status; - - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, - bt_hex(buf->om_data, buf->om_len)); - - if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NET_TRANSMIT_STATUS, ctx->addr, - (void **)&status)) { - return -ENOENT; - } - - *status = net_buf_simple_pull_u8(buf); - - bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); - - return 0; + return state_status_u8(model, ctx, buf, OP_NET_TRANSMIT_STATUS); } struct net_key_param { @@ -229,6 +214,11 @@ static int net_key_list(struct bt_mesh_model *model, param->keys[i++] = net_buf_simple_pull_le16(buf) & 0xfff; } + if (buf->om_len > 0) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + *param->key_cnt = i; bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); @@ -241,11 +231,11 @@ static int node_reset_status(struct bt_mesh_model *model, struct os_mbuf *buf) { bool *param = NULL; - BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x", - ctx->net_idx, ctx->app_idx, ctx->addr); + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x", ctx->net_idx, + ctx->app_idx, ctx->addr); - if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NODE_RESET_STATUS, ctx->addr, - (void **)¶m)) { + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NODE_RESET_STATUS, + ctx->addr, (void **)¶m)) { return -ENOENT; } @@ -338,6 +328,11 @@ static int app_key_list(struct bt_mesh_model *model, param->keys[i++] = net_buf_simple_pull_le16(buf) & 0xfff; } + if (buf->om_len > 0U) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EINVAL; + } + *param->key_cnt = i; if (param->status) { *param->status = status; @@ -368,6 +363,11 @@ static int mod_app_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); + if ((buf->om_len != 7U) && (buf->om_len != 9U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_APP_STATUS, ctx->addr, (void **)¶m)) { return -ENOENT; @@ -418,6 +418,11 @@ static int mod_member_list_handle(struct bt_mesh_msg_ctx *ctx, uint8_t status; int i; + if ((vnd && buf->om_len < 7U) || (buf->om_len < 5U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + status = net_buf_simple_pull_u8(buf); elem_addr = net_buf_simple_pull_le16(buf); if (vnd) { @@ -432,9 +437,9 @@ static int mod_member_list_handle(struct bt_mesh_msg_ctx *ctx, return -ENOENT; } - if (buf->om_len % 2) { - BT_WARN("Model Member List invalid length"); - return -ENOENT; + if (buf->om_len % 2U) { + BT_ERR("Model Member List invalid length"); + return -EMSGSIZE; } for (i = 0; i < *param->member_cnt && buf->om_len; i++) { @@ -507,6 +512,11 @@ static int mod_pub_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); + if ((buf->om_len != 12U) && (buf->om_len != 14U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EINVAL; + } + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_PUB_STATUS, ctx->addr, (void **)¶m)) { BT_WARN("Unexpected Model Pub Status message"); @@ -585,6 +595,11 @@ static int mod_sub_status(struct bt_mesh_model *model, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); + if ((buf->om_len != 7U) && (buf->om_len != 9U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EINVAL; + } + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_MOD_SUB_STATUS, ctx->addr, (void **)¶m)) { return -ENOENT; @@ -729,27 +744,27 @@ static int hb_pub_status(struct bt_mesh_model *model, } const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = { - { OP_DEV_COMP_DATA_STATUS, 15, comp_data_status }, - { OP_BEACON_STATUS, 1, beacon_status }, - { OP_DEFAULT_TTL_STATUS, 1, ttl_status }, - { OP_FRIEND_STATUS, 1, friend_status }, - { OP_GATT_PROXY_STATUS, 1, gatt_proxy_status }, - { OP_RELAY_STATUS, 2, relay_status }, - { OP_NET_TRANSMIT_STATUS, 1, net_transmit_status }, - { OP_NET_KEY_STATUS, 3, net_key_status }, - { OP_NET_KEY_LIST, 0, net_key_list }, - { OP_APP_KEY_STATUS, 4, app_key_status }, - { OP_APP_KEY_LIST, 3, app_key_list }, - { OP_MOD_APP_STATUS, 7, mod_app_status }, - { OP_SIG_MOD_APP_LIST, 5, mod_app_list}, - { OP_VND_MOD_APP_LIST, 7, mod_app_list_vnd}, - { OP_MOD_PUB_STATUS, 12, mod_pub_status }, - { OP_MOD_SUB_STATUS, 7, mod_sub_status }, - { OP_MOD_SUB_LIST, 5, mod_sub_list}, - { OP_MOD_SUB_LIST_VND, 7, mod_sub_list_vnd}, - { OP_HEARTBEAT_SUB_STATUS, 9, hb_sub_status }, - { OP_HEARTBEAT_PUB_STATUS, 10, hb_pub_status }, - { OP_NODE_RESET_STATUS, 0, node_reset_status}, + { OP_DEV_COMP_DATA_STATUS, BT_MESH_LEN_MIN(15), comp_data_status }, + { OP_BEACON_STATUS, BT_MESH_LEN_EXACT(1), beacon_status }, + { OP_DEFAULT_TTL_STATUS, BT_MESH_LEN_EXACT(1), ttl_status }, + { OP_FRIEND_STATUS, BT_MESH_LEN_EXACT(1), friend_status }, + { OP_GATT_PROXY_STATUS, BT_MESH_LEN_EXACT(1), gatt_proxy_status }, + { OP_RELAY_STATUS, BT_MESH_LEN_EXACT(2), relay_status }, + { OP_NET_TRANSMIT_STATUS, BT_MESH_LEN_EXACT(1), net_transmit_status }, + { OP_NET_KEY_STATUS, BT_MESH_LEN_EXACT(3), net_key_status }, + { OP_NET_KEY_LIST, BT_MESH_LEN_MIN(0), net_key_list }, + { OP_APP_KEY_STATUS, BT_MESH_LEN_EXACT(4), app_key_status }, + { OP_APP_KEY_LIST, BT_MESH_LEN_MIN(3), app_key_list }, + { OP_MOD_APP_STATUS, BT_MESH_LEN_MIN(7), mod_app_status }, + { OP_SIG_MOD_APP_LIST, BT_MESH_LEN_MIN(5), mod_app_list }, + { OP_VND_MOD_APP_LIST, BT_MESH_LEN_MIN(7), mod_app_list_vnd }, + { OP_MOD_PUB_STATUS, BT_MESH_LEN_MIN(12), mod_pub_status }, + { OP_MOD_SUB_STATUS, BT_MESH_LEN_MIN(7), mod_sub_status }, + { OP_MOD_SUB_LIST, BT_MESH_LEN_MIN(5), mod_sub_list }, + { OP_MOD_SUB_LIST_VND, BT_MESH_LEN_MIN(7), mod_sub_list_vnd }, + { OP_HEARTBEAT_SUB_STATUS, BT_MESH_LEN_EXACT(9), hb_sub_status }, + { OP_HEARTBEAT_PUB_STATUS, BT_MESH_LEN_EXACT(10), hb_pub_status }, + { OP_NODE_RESET_STATUS, BT_MESH_LEN_EXACT(0), node_reset_status }, BT_MESH_MODEL_OP_END, }; diff --git a/nimble/host/mesh/src/cfg_srv.c b/nimble/host/mesh/src/cfg_srv.c index f5518fd12e..4a63be7e70 100644 --- a/nimble/host/mesh/src/cfg_srv.c +++ b/nimble/host/mesh/src/cfg_srv.c @@ -775,6 +775,11 @@ static int mod_pub_get(struct bt_mesh_model *model, uint8_t *mod_id, status; bool vnd; + if ((buf->om_len != 4U) && (buf->om_len != 6U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); @@ -823,6 +828,11 @@ static int mod_pub_set(struct bt_mesh_model *model, uint8_t *mod_id; bool vnd; + if ((buf->om_len != 11U) && (buf->om_len != 13U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); @@ -918,6 +928,11 @@ static int mod_pub_va_set(struct bt_mesh_model *model, uint8_t *mod_id; bool vnd; + if ((buf->om_len != 25U) && (buf->om_len != 27U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); @@ -1020,6 +1035,11 @@ static int mod_sub_add(struct bt_mesh_model *model, uint16_t *entry; bool vnd; + if ((buf->om_len != 6U) && (buf->om_len != 8U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); @@ -1093,6 +1113,11 @@ static int mod_sub_del(struct bt_mesh_model *model, uint8_t status; bool vnd; + if ((buf->om_len != 6U) && (buf->om_len != 8U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); @@ -1170,6 +1195,11 @@ static int mod_sub_overwrite(struct bt_mesh_model *model, uint8_t status; bool vnd; + if ((buf->om_len != 6U) && (buf->om_len != 8U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); @@ -1236,6 +1266,11 @@ static int mod_sub_del_all(struct bt_mesh_model *model, uint8_t status; bool vnd; + if ((buf->om_len != 4U) && (buf->om_len != 6U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); @@ -1450,6 +1485,11 @@ static int mod_sub_va_add(struct bt_mesh_model *model, uint8_t status; bool vnd; + if ((buf->om_len != 20U) && (buf->om_len != 22U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); @@ -1527,6 +1567,11 @@ static int mod_sub_va_del(struct bt_mesh_model *model, uint8_t status; bool vnd; + if ((buf->om_len != 20U) && (buf->om_len != 22U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); @@ -1594,6 +1639,11 @@ static int mod_sub_va_overwrite(struct bt_mesh_model *model, uint8_t status; bool vnd; + if ((buf->om_len != 20U) && (buf->om_len != 22U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); @@ -1874,6 +1924,11 @@ static int mod_app_bind(struct bt_mesh_model *model, bool vnd; int err = 0; + if ((buf->om_len != 6U) && (buf->om_len != 8U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); @@ -1938,6 +1993,11 @@ static int mod_app_unbind(struct bt_mesh_model *model, bool vnd; int err = 0; + if ((buf->om_len != 6U) && (buf->om_len != 8U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); @@ -2001,6 +2061,11 @@ static int mod_app_get(struct bt_mesh_model *model, bool vnd; int err = 0; + if ((buf->om_len != 4U) && (buf->om_len != 6U)) { + BT_ERR("The message size for the application opcode is incorrect."); + return -EMSGSIZE; + } + elem_addr = net_buf_simple_pull_le16(buf); if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { BT_WARN("Prohibited element address"); @@ -2475,53 +2540,53 @@ static int heartbeat_sub_set(struct bt_mesh_model *model, } const struct bt_mesh_model_op bt_mesh_cfg_srv_op[] = { - { OP_DEV_COMP_DATA_GET, 1, dev_comp_data_get }, - { OP_APP_KEY_ADD, 19, app_key_add }, - { OP_APP_KEY_UPDATE, 19, app_key_update }, - { OP_APP_KEY_DEL, 3, app_key_del }, - { OP_APP_KEY_GET, 2, app_key_get }, - { OP_BEACON_GET, 0, beacon_get }, - { OP_BEACON_SET, 1, beacon_set }, - { OP_DEFAULT_TTL_GET, 0, default_ttl_get }, - { OP_DEFAULT_TTL_SET, 1, default_ttl_set }, - { OP_GATT_PROXY_GET, 0, gatt_proxy_get }, - { OP_GATT_PROXY_SET, 1, gatt_proxy_set }, - { OP_NET_TRANSMIT_GET, 0, net_transmit_get }, - { OP_NET_TRANSMIT_SET, 1, net_transmit_set }, - { OP_RELAY_GET, 0, relay_get }, - { OP_RELAY_SET, 2, relay_set }, - { OP_MOD_PUB_GET, 4, mod_pub_get }, - { OP_MOD_PUB_SET, 11, mod_pub_set }, - { OP_MOD_PUB_VA_SET, 24, mod_pub_va_set }, - { OP_MOD_SUB_ADD, 6, mod_sub_add }, - { OP_MOD_SUB_VA_ADD, 20, mod_sub_va_add }, - { OP_MOD_SUB_DEL, 6, mod_sub_del }, - { OP_MOD_SUB_VA_DEL, 20, mod_sub_va_del }, - { OP_MOD_SUB_OVERWRITE, 6, mod_sub_overwrite }, - { OP_MOD_SUB_VA_OVERWRITE, 20, mod_sub_va_overwrite }, - { OP_MOD_SUB_DEL_ALL, 4, mod_sub_del_all }, - { OP_MOD_SUB_GET, 4, mod_sub_get }, - { OP_MOD_SUB_GET_VND, 6, mod_sub_get_vnd }, - { OP_NET_KEY_ADD, 18, net_key_add }, - { OP_NET_KEY_UPDATE, 18, net_key_update }, - { OP_NET_KEY_DEL, 2, net_key_del }, - { OP_NET_KEY_GET, 0, net_key_get }, - { OP_NODE_IDENTITY_GET, 2, node_identity_get }, - { OP_NODE_IDENTITY_SET, 3, node_identity_set }, - { OP_MOD_APP_BIND, 6, mod_app_bind }, - { OP_MOD_APP_UNBIND, 6, mod_app_unbind }, - { OP_SIG_MOD_APP_GET, 4, mod_app_get }, - { OP_VND_MOD_APP_GET, 6, mod_app_get }, - { OP_NODE_RESET, 0, node_reset }, - { OP_FRIEND_GET, 0, friend_get }, - { OP_FRIEND_SET, 1, friend_set }, - { OP_LPN_TIMEOUT_GET, 2, lpn_timeout_get }, - { OP_KRP_GET, 2, krp_get }, - { OP_KRP_SET, 3, krp_set }, - { OP_HEARTBEAT_PUB_GET, 0, heartbeat_pub_get }, - { OP_HEARTBEAT_PUB_SET, 9, heartbeat_pub_set }, - { OP_HEARTBEAT_SUB_GET, 0, heartbeat_sub_get }, - { OP_HEARTBEAT_SUB_SET, 5, heartbeat_sub_set }, + { OP_DEV_COMP_DATA_GET, BT_MESH_LEN_EXACT(1), dev_comp_data_get }, + { OP_APP_KEY_ADD, BT_MESH_LEN_EXACT(19), app_key_add }, + { OP_APP_KEY_UPDATE, BT_MESH_LEN_EXACT(19), app_key_update }, + { OP_APP_KEY_DEL, BT_MESH_LEN_EXACT(3), app_key_del }, + { OP_APP_KEY_GET, BT_MESH_LEN_EXACT(2), app_key_get }, + { OP_BEACON_GET, BT_MESH_LEN_EXACT(0), beacon_get }, + { OP_BEACON_SET, BT_MESH_LEN_EXACT(1), beacon_set }, + { OP_DEFAULT_TTL_GET, BT_MESH_LEN_EXACT(0), default_ttl_get }, + { OP_DEFAULT_TTL_SET, BT_MESH_LEN_EXACT(1), default_ttl_set }, + { OP_GATT_PROXY_GET, BT_MESH_LEN_EXACT(0), gatt_proxy_get }, + { OP_GATT_PROXY_SET, BT_MESH_LEN_EXACT(1), gatt_proxy_set }, + { OP_NET_TRANSMIT_GET, BT_MESH_LEN_EXACT(0), net_transmit_get }, + { OP_NET_TRANSMIT_SET, BT_MESH_LEN_EXACT(1), net_transmit_set }, + { OP_RELAY_GET, BT_MESH_LEN_EXACT(0), relay_get }, + { OP_RELAY_SET, BT_MESH_LEN_EXACT(2), relay_set }, + { OP_MOD_PUB_GET, BT_MESH_LEN_MIN(4), mod_pub_get }, + { OP_MOD_PUB_SET, BT_MESH_LEN_MIN(11), mod_pub_set }, + { OP_MOD_PUB_VA_SET, BT_MESH_LEN_MIN(25), mod_pub_va_set }, + { OP_MOD_SUB_ADD, BT_MESH_LEN_MIN(6), mod_sub_add }, + { OP_MOD_SUB_VA_ADD, BT_MESH_LEN_MIN(20), mod_sub_va_add }, + { OP_MOD_SUB_DEL, BT_MESH_LEN_MIN(6), mod_sub_del }, + { OP_MOD_SUB_VA_DEL, BT_MESH_LEN_MIN(20), mod_sub_va_del }, + { OP_MOD_SUB_OVERWRITE, BT_MESH_LEN_MIN(6), mod_sub_overwrite }, + { OP_MOD_SUB_VA_OVERWRITE, BT_MESH_LEN_MIN(20), mod_sub_va_overwrite }, + { OP_MOD_SUB_DEL_ALL, BT_MESH_LEN_MIN(4), mod_sub_del_all }, + { OP_MOD_SUB_GET, BT_MESH_LEN_EXACT(4), mod_sub_get }, + { OP_MOD_SUB_GET_VND, BT_MESH_LEN_EXACT(6), mod_sub_get_vnd }, + { OP_NET_KEY_ADD, BT_MESH_LEN_EXACT(18), net_key_add }, + { OP_NET_KEY_UPDATE, BT_MESH_LEN_EXACT(18), net_key_update }, + { OP_NET_KEY_DEL, BT_MESH_LEN_EXACT(2), net_key_del }, + { OP_NET_KEY_GET, BT_MESH_LEN_EXACT(0), net_key_get }, + { OP_NODE_IDENTITY_GET, BT_MESH_LEN_EXACT(2), node_identity_get }, + { OP_NODE_IDENTITY_SET, BT_MESH_LEN_EXACT(3), node_identity_set }, + { OP_MOD_APP_BIND, BT_MESH_LEN_MIN(6), mod_app_bind }, + { OP_MOD_APP_UNBIND, BT_MESH_LEN_MIN(6), mod_app_unbind }, + { OP_SIG_MOD_APP_GET, BT_MESH_LEN_MIN(4), mod_app_get }, + { OP_VND_MOD_APP_GET, BT_MESH_LEN_MIN(6), mod_app_get }, + { OP_NODE_RESET, BT_MESH_LEN_EXACT(0), node_reset }, + { OP_FRIEND_GET, BT_MESH_LEN_EXACT(0), friend_get }, + { OP_FRIEND_SET, BT_MESH_LEN_EXACT(1), friend_set }, + { OP_LPN_TIMEOUT_GET, BT_MESH_LEN_EXACT(2), lpn_timeout_get }, + { OP_KRP_GET, BT_MESH_LEN_EXACT(2), krp_get }, + { OP_KRP_SET, BT_MESH_LEN_EXACT(3), krp_set }, + { OP_HEARTBEAT_PUB_GET, BT_MESH_LEN_EXACT(0), heartbeat_pub_get }, + { OP_HEARTBEAT_PUB_SET, BT_MESH_LEN_EXACT(9), heartbeat_pub_set }, + { OP_HEARTBEAT_SUB_GET, BT_MESH_LEN_EXACT(0), heartbeat_sub_get }, + { OP_HEARTBEAT_SUB_SET, BT_MESH_LEN_EXACT(5), heartbeat_sub_set }, BT_MESH_MODEL_OP_END, }; diff --git a/nimble/host/mesh/src/health_cli.c b/nimble/host/mesh/src/health_cli.c index 2be41d313e..8424e4200d 100644 --- a/nimble/host/mesh/src/health_cli.c +++ b/nimble/host/mesh/src/health_cli.c @@ -162,10 +162,10 @@ static int health_attention_status(struct bt_mesh_model *model, } const struct bt_mesh_model_op bt_mesh_health_cli_op[] = { - { OP_HEALTH_FAULT_STATUS, 3, health_fault_status }, - { OP_HEALTH_CURRENT_STATUS, 3, health_current_status }, - { OP_HEALTH_PERIOD_STATUS, 1, health_period_status }, - { OP_ATTENTION_STATUS, 1, health_attention_status }, + { OP_HEALTH_FAULT_STATUS, BT_MESH_LEN_MIN(3), health_fault_status }, + { OP_HEALTH_CURRENT_STATUS, BT_MESH_LEN_MIN(3), health_current_status }, + { OP_HEALTH_PERIOD_STATUS, BT_MESH_LEN_EXACT(1), health_period_status }, + { OP_ATTENTION_STATUS, BT_MESH_LEN_EXACT(1), health_attention_status }, BT_MESH_MODEL_OP_END, }; diff --git a/nimble/host/mesh/src/health_srv.c b/nimble/host/mesh/src/health_srv.c index c1b0dd884f..4065d24f83 100644 --- a/nimble/host/mesh/src/health_srv.c +++ b/nimble/host/mesh/src/health_srv.c @@ -282,9 +282,14 @@ static int attention_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { + int err; + BT_DBG(""); - attention_set_unrel(model, ctx, buf); + err = attention_set_unrel(model, ctx, buf); + if (err) { + return err; + } return send_attention_status(model, ctx); } @@ -339,25 +344,30 @@ static int health_period_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { + int err; + BT_DBG(""); - health_period_set_unrel(model, ctx, buf); + err = health_period_set_unrel(model, ctx, buf); + if (err) { + return err; + } return send_health_period_status(model, ctx); } const struct bt_mesh_model_op bt_mesh_health_srv_op[] = { - { OP_HEALTH_FAULT_GET, 2, health_fault_get }, - { OP_HEALTH_FAULT_CLEAR, 2, health_fault_clear }, - { OP_HEALTH_FAULT_CLEAR_UNREL, 2, health_fault_clear_unrel }, - { OP_HEALTH_FAULT_TEST, 3, health_fault_test }, - { OP_HEALTH_FAULT_TEST_UNREL, 3, health_fault_test_unrel }, - { OP_HEALTH_PERIOD_GET, 0, health_period_get }, - { OP_HEALTH_PERIOD_SET, 1, health_period_set }, - { OP_HEALTH_PERIOD_SET_UNREL, 1, health_period_set_unrel }, - { OP_ATTENTION_GET, 0, attention_get }, - { OP_ATTENTION_SET, 1, attention_set }, - { OP_ATTENTION_SET_UNREL, 1, attention_set_unrel }, + { OP_HEALTH_FAULT_GET, BT_MESH_LEN_EXACT(2), health_fault_get }, + { OP_HEALTH_FAULT_CLEAR, BT_MESH_LEN_EXACT(2), health_fault_clear }, + { OP_HEALTH_FAULT_CLEAR_UNREL, BT_MESH_LEN_EXACT(2), health_fault_clear_unrel }, + { OP_HEALTH_FAULT_TEST, BT_MESH_LEN_EXACT(3), health_fault_test }, + { OP_HEALTH_FAULT_TEST_UNREL, BT_MESH_LEN_EXACT(3), health_fault_test_unrel }, + { OP_HEALTH_PERIOD_GET, BT_MESH_LEN_EXACT(0), health_period_get }, + { OP_HEALTH_PERIOD_SET, BT_MESH_LEN_EXACT(1), health_period_set }, + { OP_HEALTH_PERIOD_SET_UNREL, BT_MESH_LEN_EXACT(1), health_period_set_unrel }, + { OP_ATTENTION_GET, BT_MESH_LEN_EXACT(0), attention_get }, + { OP_ATTENTION_SET, BT_MESH_LEN_EXACT(1), attention_set }, + { OP_ATTENTION_SET_UNREL, BT_MESH_LEN_EXACT(1), attention_set_unrel }, BT_MESH_MODEL_OP_END, }; From 1aedcf177779e4faf69d0883f42097a71c19a4ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 08:13:07 +0200 Subject: [PATCH 0118/1333] host/mesh: Provisioning PDU length defines Adds length defines for all provisioning PDUs and uses them to split prov_link.conf_inputs into separate fields. This is port of abcbfed6c3ef857626724674cd524ed58da9ef5b --- nimble/host/mesh/include/mesh/glue.h | 2 +- nimble/host/mesh/src/prov.c | 26 +++++++++------- nimble/host/mesh/src/prov.h | 24 +++++++++++++-- nimble/host/mesh/src/prov_device.c | 42 +++++++++++++------------- nimble/host/mesh/src/provisioner.c | 44 ++++++++++++++-------------- 5 files changed, 82 insertions(+), 56 deletions(-) diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index ec0e609a0b..2261504a01 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -538,7 +538,7 @@ settings_load(void) #endif /* MYNEWT_VAL(MYNEWT_VAL_BLE_MESH_SETTINGS) */ -#define BUILD_ASSERT(cond) _Static_assert(cond, "") +#define BUILD_ASSERT(cond, msg) _Static_assert(cond, msg) /* Memory slabs/blocks */ diff --git a/nimble/host/mesh/src/prov.c b/nimble/host/mesh/src/prov.c index d44d8ec030..1f5a9eaf7e 100644 --- a/nimble/host/mesh/src/prov.c +++ b/nimble/host/mesh/src/prov.c @@ -25,6 +25,10 @@ struct bt_mesh_prov_link bt_mesh_prov_link; const struct bt_mesh_prov *bt_mesh_prov; +/* Verify specification defined length: */ +BUILD_ASSERT(sizeof(bt_mesh_prov_link.conf_inputs) == 145, + "Confirmation inputs shall be 145 bytes"); + static void pub_key_ready(const uint8_t *pkey) { if (!pkey) { @@ -45,7 +49,7 @@ int bt_mesh_prov_reset_state(void (*func)(const uint8_t key[64])) pub_key_cb.func = func ? func : pub_key_ready; /* Disable Attention Timer if it was set */ - if (bt_mesh_prov_link.conf_inputs[0]) { + if (bt_mesh_prov_link.conf_inputs.invite[0]) { bt_mesh_attention(NULL, 0); } @@ -252,16 +256,16 @@ static void prov_recv(const struct prov_bearer *bearer, void *cb_data, struct os_mbuf *buf) { static const uint8_t op_len[10] = { - [PROV_INVITE] = 1, - [PROV_CAPABILITIES] = 11, - [PROV_START] = 5, - [PROV_PUB_KEY] = 64, - [PROV_INPUT_COMPLETE] = 0, - [PROV_CONFIRM] = 16, - [PROV_RANDOM] = 16, - [PROV_DATA] = 33, - [PROV_COMPLETE] = 0, - [PROV_FAILED] = 1, + [PROV_INVITE] = PDU_LEN_INVITE, + [PROV_CAPABILITIES] = PDU_LEN_CAPABILITIES, + [PROV_START] = PDU_LEN_START, + [PROV_PUB_KEY] = PDU_LEN_PUB_KEY, + [PROV_INPUT_COMPLETE] = PDU_LEN_INPUT_COMPLETE, + [PROV_CONFIRM] = PDU_LEN_CONFIRM, + [PROV_RANDOM] = PDU_LEN_RANDOM, + [PROV_DATA] = PDU_LEN_DATA, + [PROV_COMPLETE] = PDU_LEN_COMPLETE, + [PROV_FAILED] = PDU_LEN_FAILED, }; uint8_t type = buf->om_data[0]; diff --git a/nimble/host/mesh/src/prov.h b/nimble/host/mesh/src/prov.h index d300b1d5c6..5c42528c6d 100644 --- a/nimble/host/mesh/src/prov.h +++ b/nimble/host/mesh/src/prov.h @@ -56,10 +56,23 @@ #define PROV_NO_PDU 0xff +#define PDU_LEN_INVITE 1 +#define PDU_LEN_CAPABILITIES 11 +#define PDU_LEN_START 5 +#define PDU_LEN_PUB_KEY 64 +#define PDU_LEN_INPUT_COMPLETE 0 +#define PDU_LEN_CONFIRM 16 +#define PDU_LEN_RANDOM 16 +#define PDU_LEN_DATA 33 +#define PDU_LEN_COMPLETE 0 +#define PDU_LEN_FAILED 1 + +#define PDU_OP_LEN 1 + #define PROV_ALG_P256 0x00 #define PROV_BUF(len) \ - NET_BUF_SIMPLE(PROV_BEARER_BUF_HEADROOM + len) + NET_BUF_SIMPLE(PROV_BEARER_BUF_HEADROOM + PDU_OP_LEN + len) enum { WAIT_PUB_KEY, /* Waiting for local PubKey to be generated */ @@ -111,7 +124,14 @@ struct bt_mesh_prov_link { uint8_t conf_salt[16]; /* ConfirmationSalt */ uint8_t conf_key[16]; /* ConfirmationKey */ - uint8_t conf_inputs[145]; /* ConfirmationInputs */ + /* ConfirmationInput fields: */ + struct { + uint8_t invite[PDU_LEN_INVITE]; + uint8_t capabilities[PDU_LEN_CAPABILITIES]; + uint8_t start[PDU_LEN_START]; + uint8_t pub_key_provisioner[PDU_LEN_PUB_KEY]; /* big-endian */ + uint8_t pub_key_device[PDU_LEN_PUB_KEY]; /* big-endian */ + } conf_inputs; uint8_t prov_salt[16]; /* Provisioning Salt */ }; diff --git a/nimble/host/mesh/src/prov_device.c b/nimble/host/mesh/src/prov_device.c index b7828fa311..737e216cb2 100644 --- a/nimble/host/mesh/src/prov_device.c +++ b/nimble/host/mesh/src/prov_device.c @@ -32,7 +32,7 @@ static int reset_state(void) static void prov_send_fail_msg(uint8_t err) { - struct os_mbuf *buf = PROV_BUF(2); + struct os_mbuf *buf = PROV_BUF(PDU_LEN_FAILED); BT_DBG("%u", err); @@ -58,7 +58,7 @@ static void prov_fail(uint8_t reason) static void prov_invite(const uint8_t *data) { - struct os_mbuf *buf = PROV_BUF(12); + struct os_mbuf *buf = PROV_BUF(PDU_LEN_CAPABILITIES); BT_DBG("Attention Duration: %u seconds", data[0]); @@ -66,7 +66,7 @@ static void prov_invite(const uint8_t *data) bt_mesh_attention(NULL, data[0]); } - bt_mesh_prov_link.conf_inputs[0] = data[0]; + memcpy(bt_mesh_prov_link.conf_inputs.invite, data, PDU_LEN_INVITE); bt_mesh_prov_buf_init(buf, PROV_CAPABILITIES); @@ -95,7 +95,7 @@ static void prov_invite(const uint8_t *data) /* Input OOB Action */ net_buf_simple_add_be16(buf, bt_mesh_prov->input_actions); - memcpy(&bt_mesh_prov_link.conf_inputs[1], &buf->om_data[1], 11); + memcpy(bt_mesh_prov_link.conf_inputs.capabilities, &buf->om_data[1], PDU_LEN_CAPABILITIES); if (bt_mesh_prov_send(buf, NULL)) { BT_ERR("Failed to send capabilities"); @@ -129,7 +129,7 @@ static void prov_start(const uint8_t *data) atomic_set_bit_to(bt_mesh_prov_link.flags, OOB_PUB_KEY, data[1] == PUB_KEY_OOB); - memcpy(&bt_mesh_prov_link.conf_inputs[12], data, 5); + memcpy(bt_mesh_prov_link.conf_inputs.start, data, PDU_LEN_START); bt_mesh_prov_link.expect = PROV_PUB_KEY; @@ -150,14 +150,15 @@ static void prov_start(const uint8_t *data) static void send_confirm(void) { - struct os_mbuf *cfm = PROV_BUF(17); + struct os_mbuf *cfm = PROV_BUF(PDU_LEN_CONFIRM); - BT_DBG("ConfInputs[0] %s", bt_hex(bt_mesh_prov_link.conf_inputs, 64)); - BT_DBG("ConfInputs[64] %s", bt_hex(&bt_mesh_prov_link.conf_inputs[64], 64)); - BT_DBG("ConfInputs[128] %s", bt_hex(&bt_mesh_prov_link.conf_inputs[128], 17)); + uint8_t *inputs = (uint8_t *)&bt_mesh_prov_link.conf_inputs; - if (bt_mesh_prov_conf_salt(bt_mesh_prov_link.conf_inputs, - bt_mesh_prov_link.conf_salt)) { + BT_DBG("ConfInputs[0] %s", bt_hex(inputs, 64)); + BT_DBG("ConfInputs[64] %s", bt_hex(&inputs[64], 64)); + BT_DBG("ConfInputs[128] %s", bt_hex(&inputs[128], 17)); + + if (bt_mesh_prov_conf_salt(inputs, bt_mesh_prov_link.conf_salt)) { BT_ERR("Unable to generate confirmation salt"); prov_fail(PROV_ERR_UNEXP_ERR); return; @@ -202,7 +203,7 @@ static void send_confirm(void) static void send_input_complete(void) { - struct os_mbuf *buf = PROV_BUF(1); + struct os_mbuf *buf = PROV_BUF(PDU_LEN_INPUT_COMPLETE); bt_mesh_prov_buf_init(buf, PROV_INPUT_COMPLETE); if (bt_mesh_prov_send(buf, NULL)) { @@ -233,7 +234,7 @@ static void start_auth(void) static void send_pub_key(void) { - struct os_mbuf *buf = PROV_BUF(65); + struct os_mbuf *buf = PROV_BUF(PDU_LEN_PUB_KEY); const uint8_t *key; key = bt_pub_key_get(); @@ -251,8 +252,8 @@ static void send_pub_key(void) sys_memcpy_swap(net_buf_simple_add(buf, 32), key, 32); sys_memcpy_swap(net_buf_simple_add(buf, 32), &key[32], 32); - /* PublicKeyRemote */ - memcpy(&bt_mesh_prov_link.conf_inputs[81], &buf->om_data[1], 64); + /* PublicKeyDevice */ + memcpy(bt_mesh_prov_link.conf_inputs.pub_key_device, &buf->om_data[1], PDU_LEN_PUB_KEY); if (bt_mesh_prov_send(buf, public_key_sent)) { BT_ERR("Failed to send Public Key"); @@ -294,7 +295,7 @@ static void prov_dh_key_gen(void) const uint8_t *remote_pk; uint8_t remote_pk_le[64]; - remote_pk = &bt_mesh_prov_link.conf_inputs[17]; + remote_pk = bt_mesh_prov_link.conf_inputs.pub_key_provisioner; if (MYNEWT_VAL(BLE_MESH_PROV_OOB_PUBLIC_KEY) && atomic_test_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY)) { if (uECC_valid_public_key(remote_pk, &curve_secp256r1)) { @@ -330,7 +331,7 @@ static void prov_pub_key(const uint8_t *data) BT_DBG("Remote Public Key: %s", bt_hex(data, 64)); /* PublicKeyProvisioner */ - memcpy(&bt_mesh_prov_link.conf_inputs[17], data, 64); + memcpy(bt_mesh_prov_link.conf_inputs.pub_key_provisioner, data, PDU_LEN_PUB_KEY); if (MYNEWT_VAL(BLE_MESH_PROV_OOB_PUBLIC_KEY) && atomic_test_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY)) { @@ -341,7 +342,8 @@ static void prov_pub_key(const uint8_t *data) } /* No swap needed since user provides public key in big-endian */ - memcpy(&bt_mesh_prov_link.conf_inputs[81], bt_mesh_prov->public_key_be, 64); + memcpy(bt_mesh_prov_link.conf_inputs.pub_key_device, bt_mesh_prov->public_key_be, + PDU_LEN_PUB_KEY); atomic_set_bit(bt_mesh_prov_link.flags, WAIT_DH_KEY); @@ -382,7 +384,7 @@ static void notify_input_complete(void) static void send_random(void) { - struct os_mbuf *rnd = PROV_BUF(17); + struct os_mbuf *rnd = PROV_BUF(PDU_LEN_RANDOM); bt_mesh_prov_buf_init(rnd, PROV_RANDOM); net_buf_simple_add_mem(rnd, bt_mesh_prov_link.rand, 16); @@ -454,7 +456,7 @@ static inline bool is_pb_gatt(void) static void prov_data(const uint8_t *data) { - struct os_mbuf *msg = PROV_BUF(1); + struct os_mbuf *msg = PROV_BUF(PDU_LEN_COMPLETE); uint8_t session_key[16]; uint8_t nonce[13]; uint8_t dev_key[16]; diff --git a/nimble/host/mesh/src/provisioner.c b/nimble/host/mesh/src/provisioner.c index 7a8c40d8f6..bbf5eb658d 100644 --- a/nimble/host/mesh/src/provisioner.c +++ b/nimble/host/mesh/src/provisioner.c @@ -65,14 +65,15 @@ static void prov_fail(uint8_t reason) static void send_invite(void) { - struct os_mbuf *inv = PROV_BUF(2); + struct os_mbuf *inv = PROV_BUF(PDU_LEN_INVITE); BT_DBG(""); bt_mesh_prov_buf_init(inv, PROV_INVITE); net_buf_simple_add_u8(inv, prov_device.attention_duration); - bt_mesh_prov_link.conf_inputs[0] = prov_device.attention_duration; + memcpy(bt_mesh_prov_link.conf_inputs.invite, &prov_device.attention_duration, + PDU_LEN_INVITE); if (bt_mesh_prov_send(inv, NULL)) { BT_ERR("Failed to send invite"); @@ -96,15 +97,14 @@ static void send_start(void) { BT_DBG(""); uint8_t method, action; - struct os_mbuf *start = PROV_BUF(6); + struct os_mbuf *start = PROV_BUF(PDU_LEN_START); - const uint8_t *data = &bt_mesh_prov_link.conf_inputs[1 + 3]; + bool oob_pub_key = bt_mesh_prov_link.conf_inputs.capabilities[3] == PUB_KEY_OOB; bt_mesh_prov_buf_init(start, PROV_START); net_buf_simple_add_u8(start, PROV_ALG_P256); - if (atomic_test_bit(bt_mesh_prov_link.flags, REMOTE_PUB_KEY) && - *data == PUB_KEY_OOB) { + if (atomic_test_bit(bt_mesh_prov_link.flags, REMOTE_PUB_KEY) && oob_pub_key) { net_buf_simple_add_u8(start, PUB_KEY_OOB); atomic_set_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY); } else { @@ -137,7 +137,7 @@ static void send_start(void) net_buf_simple_add_u8(start, bt_mesh_prov_link.oob_size); - memcpy(&bt_mesh_prov_link.conf_inputs[12], &start->om_data[1], 5); + memcpy(bt_mesh_prov_link.conf_inputs.invite, &start->om_data[1], PDU_LEN_INVITE); if (bt_mesh_prov_auth(method, action, bt_mesh_prov_link.oob_size) < 0) { BT_ERR("Invalid authentication method: 0x%02x; " @@ -251,7 +251,7 @@ static void prov_capabilities(const uint8_t *data) return; } #endif - memcpy(&bt_mesh_prov_link.conf_inputs[1], data, 11); + memcpy(bt_mesh_prov_link.conf_inputs.capabilities, data, PDU_LEN_CAPABILITIES); if (bt_mesh_prov->capabilities) { bt_mesh_prov->capabilities(&caps); @@ -267,14 +267,14 @@ static void prov_capabilities(const uint8_t *data) static void send_confirm(void) { - struct os_mbuf *cfm = PROV_BUF(17); + struct os_mbuf *cfm = PROV_BUF(PDU_LEN_CONFIRM); + uint8_t *inputs = (uint8_t *)&bt_mesh_prov_link.conf_inputs; - BT_DBG("ConfInputs[0] %s", bt_hex(bt_mesh_prov_link.conf_inputs, 64)); - BT_DBG("ConfInputs[64] %s", bt_hex(&bt_mesh_prov_link.conf_inputs[64], 64)); - BT_DBG("ConfInputs[128] %s", bt_hex(&bt_mesh_prov_link.conf_inputs[128], 17)); + BT_DBG("ConfInputs[0] %s", bt_hex(inputs, 64)); + BT_DBG("ConfInputs[64] %s", bt_hex(&inputs[64], 64)); + BT_DBG("ConfInputs[128] %s", bt_hex(&inputs[128], 17)); - if (bt_mesh_prov_conf_salt(bt_mesh_prov_link.conf_inputs, - bt_mesh_prov_link.conf_salt)) { + if (bt_mesh_prov_conf_salt(inputs, bt_mesh_prov_link.conf_salt)) { BT_ERR("Unable to generate confirmation salt"); prov_fail(PROV_ERR_UNEXP_ERR); return; @@ -330,7 +330,7 @@ static void public_key_sent(int err, void *cb_data) static void send_pub_key(void) { - struct os_mbuf *buf = PROV_BUF(65); + struct os_mbuf *buf = PROV_BUF(PDU_LEN_PUB_KEY); const uint8_t *key; key = bt_pub_key_get(); @@ -349,7 +349,7 @@ static void send_pub_key(void) sys_memcpy_swap(net_buf_simple_add(buf, 32), &key[32], 32); /* PublicKeyProvisioner */ - memcpy(&bt_mesh_prov_link.conf_inputs[17], &buf->om_data[1], 64); + memcpy(bt_mesh_prov_link.conf_inputs.pub_key_provisioner, &buf->om_data[1], PDU_LEN_PUB_KEY); if (bt_mesh_prov_send(buf, public_key_sent)) { BT_ERR("Failed to send Public Key"); @@ -389,8 +389,8 @@ static void prov_dh_key_gen(void) const uint8_t *remote_pk; const uint8_t *local_pk; - local_pk = &bt_mesh_prov_link.conf_inputs[17]; - remote_pk = &bt_mesh_prov_link.conf_inputs[81]; + local_pk = bt_mesh_prov_link.conf_inputs.pub_key_provisioner; + remote_pk = bt_mesh_prov_link.conf_inputs.pub_key_device; /* Copy remote key in little-endian for bt_dh_key_gen(). * X and Y halves are swapped independently. The bt_dh_key_gen() @@ -422,7 +422,7 @@ static void prov_pub_key(const uint8_t *data) atomic_set_bit(bt_mesh_prov_link.flags, REMOTE_PUB_KEY); /* PublicKeyDevice */ - memcpy(&bt_mesh_prov_link.conf_inputs[81], data, 64); + memcpy(bt_mesh_prov_link.conf_inputs.pub_key_device, data, 64); bt_mesh_prov_link.bearer->clear_tx(); prov_dh_key_gen(); @@ -464,7 +464,7 @@ static void prov_input_complete(const uint8_t *data) static void send_prov_data(void) { - struct os_mbuf *pdu = PROV_BUF(34); + struct os_mbuf *pdu = PROV_BUF(PDU_LEN_DATA); #if MYNEWT_VAL(BLE_MESH_CDB) struct bt_mesh_cdb_subnet *sub; #endif @@ -565,7 +565,7 @@ static void prov_complete(const uint8_t *data) static void send_random(void) { - struct os_mbuf *rnd = PROV_BUF(17); + struct os_mbuf *rnd = PROV_BUF(PDU_LEN_RANDOM); bt_mesh_prov_buf_init(rnd, PROV_RANDOM); net_buf_simple_add_mem(rnd, bt_mesh_prov_link.rand, 16); @@ -724,7 +724,7 @@ int bt_mesh_prov_remote_pub_key_set(const uint8_t public_key[64]) } /* Swap X and Y halves independently to big-endian */ - memcpy(&bt_mesh_prov_link.conf_inputs[81], public_key, 64); + memcpy(bt_mesh_prov_link.conf_inputs.pub_key_device, public_key, PDU_LEN_PUB_KEY); return 0; } From db0bd740f36870390b28944370db88dcc9c829e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 09:12:05 +0200 Subject: [PATCH 0119/1333] host/mesh: Update advertising duration calculation Zephyr Bluetooth Low Energy Controller for mesh stack uses pre-emptible continuous scanning, allowing advertising events to be transmitted without delay when advertising is enabled. No need to compensate with scan window duration. Zephyr Bluetooth Low Energy Controller built for nRF51x SoCs use CONFIG_BT_CTLR_LOW_LAT=y, and continuous scanning cannot be pre-empted, hence, scanning will block advertising events from being transmitted. Increase the advertising duration by the amount of scan window duration to compensate for the blocked advertising events. This is port of 52db419e7a35b18b054182efe0671c90fef5cad3 --- nimble/host/mesh/src/adv.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/adv.c b/nimble/host/mesh/src/adv.c index a9afb42fd8..b3d6290819 100644 --- a/nimble/host/mesh/src/adv.c +++ b/nimble/host/mesh/src/adv.c @@ -96,9 +96,28 @@ static inline void adv_send(struct os_mbuf *buf) duration = ((BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1) * (adv_int + 10)); #else - duration = (MESH_SCAN_WINDOW_MS + + /* Zephyr Bluetooth Low Energy Controller for mesh stack uses + * pre-emptible continuous scanning, allowing advertising events to be + * transmitted without delay when advertising is enabled. No need to + * compensate with scan window duration. + * An advertising event could be delayed by upto one interval when + * advertising is stopped and started in quick succession, hence add + * advertising interval to the total advertising duration. + */ + duration = (adv_int + ((BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1) * (adv_int + 10))); + + /* Zephyr Bluetooth Low Energy Controller built for nRF51x SoCs use + * CONFIG_BT_CTLR_LOW_LAT=y, and continuous scanning cannot be + * pre-empted, hence, scanning will block advertising events from + * being transmitted. Increase the advertising duration by the + * amount of scan window duration to compensate for the blocked + * advertising events. + */ + if (MYNEWT_VAL(BSP_NRF51)) { + duration += BT_MESH_SCAN_WINDOW_MS; + } #endif BT_DBG("type %u om_len %u: %s", BT_MESH_ADV(buf)->type, From 1828e5cbd69f751290b0b1a2c172300f1f20a403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 09:17:41 +0200 Subject: [PATCH 0120/1333] host/mesh: Provisioning Start Fix Resolves provisioning start process This is port of 6b67a568c9ee2d0cc6da7d7e518ebf2933c57077 --- nimble/host/mesh/src/provisioner.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/host/mesh/src/provisioner.c b/nimble/host/mesh/src/provisioner.c index bbf5eb658d..54cc1f0d94 100644 --- a/nimble/host/mesh/src/provisioner.c +++ b/nimble/host/mesh/src/provisioner.c @@ -3,6 +3,7 @@ /* * Copyright (c) 2017 Intel Corporation * Copyright (c) 2020 Lingao Meng + * Copyright (c) 2021 Manulytica Limited * * SPDX-License-Identifier: Apache-2.0 */ @@ -104,6 +105,8 @@ static void send_start(void) bt_mesh_prov_buf_init(start, PROV_START); net_buf_simple_add_u8(start, PROV_ALG_P256); + memcpy(bt_mesh_prov_link.conf_inputs.start, &start->om_data[1], PDU_LEN_START); + if (atomic_test_bit(bt_mesh_prov_link.flags, REMOTE_PUB_KEY) && oob_pub_key) { net_buf_simple_add_u8(start, PUB_KEY_OOB); atomic_set_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY); From 7b0d31393a8be7e5712341a9e37574bf01e4c915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 09:33:44 +0200 Subject: [PATCH 0121/1333] host/mesh: Added support for application access to mesh messages Added bt_mesh_msg_send() which can be used by the application to directly send model layer messages without local instantiation of related models. Also added bt_mesh_msg_cb_set() which allows the application to recieve mesh model layer messages without local instantiation of related models. Added bt_mesh_has_addr() which returns a bool. For unicast addresses, this returns whether or not bt_mesh_elem_find() was successfull. If the above mentioned bt_mesh_msg_cb_set() has been used by the application to set a message callback, this returns true so that the stack attempts to push every model message up to the application via the callback. If no callback has been set, group addresses are searched to see if the stack should pass the message up the stack to an instantiated model. These changes allow applications that do not or can not instantiate models to interface with models in a mesh network. This is applicable to applications which act as a Bluetooth mesh gateway, sniffer, debugger, network monitoring, non-mesh relay/extender, etc. In app_keys.c friend.c net.c bt_mesh_elem_find() is used only to determine the existance of an address. The full return value of bt_mesh_elem_find() is unecessary and so was replaced by the above mentioned bt_mesh_has_addr() function in these instances. Simplified bt_mesh_elem_find() by removing the search through group address. Since the above mentioned bt_mesh_has_addr() function handles instances where group addresses must be searched, it was no longer necessary to preform this search in this function. This is port of 7a2b248b9804cc59a62b3b7dcdf00f9475ef64e1 --- nimble/host/mesh/src/access.c | 84 +++++++++++++++++++++++---------- nimble/host/mesh/src/access.h | 28 ++++++++++- nimble/host/mesh/src/app_keys.c | 2 +- nimble/host/mesh/src/friend.c | 6 +-- nimble/host/mesh/src/net.c | 6 +-- nimble/host/mesh/syscfg.yml | 7 +++ 6 files changed, 100 insertions(+), 33 deletions(-) diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index c0f8632e54..42a5185e44 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -48,6 +48,7 @@ struct mod_pub_val { static const struct bt_mesh_comp *dev_comp; static uint16_t dev_primary_addr; +static void (*msg_cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf); void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, @@ -485,24 +486,67 @@ struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr) { uint16_t index; + if (!BT_MESH_ADDR_IS_UNICAST(addr)) { + return NULL; + } + + index = addr - dev_comp->elem[0].addr; + if (index >= dev_comp->elem_count) { + return NULL; + } + + return &dev_comp->elem[index]; +} + +bool bt_mesh_has_addr(uint16_t addr) +{ + uint16_t index; + if (BT_MESH_ADDR_IS_UNICAST(addr)) { - index = (addr - dev_comp->elem[0].addr); - if (index < dev_comp->elem_count) { - return &dev_comp->elem[index]; - } else { - return NULL; - } + return bt_mesh_elem_find(addr) != NULL; + } + + if (MYNEWT_VAL(BLE_MESH_ACCESS_LAYER_MSG) && msg_cb) { + return true; } for (index = 0; index < dev_comp->elem_count; index++) { struct bt_mesh_elem *elem = &dev_comp->elem[index]; if (bt_mesh_elem_find_group(elem, addr)) { - return elem; + return true; } } - return NULL; + return false; +} + +#if MYNEWT_VAL(BLE_MESH_ACCESS_LAYER_MSG) +void bt_mesh_msg_cb_set(void (*cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf)) +{ + msg_cb = cb; +} +#endif + +int bt_mesh_msg_send(struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf, uint16_t src_addr, + const struct bt_mesh_send_cb *cb, void *cb_data) +{ + struct bt_mesh_net_tx tx = { + .ctx = ctx, + .src = src_addr, + }; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx.ctx->net_idx, + tx.ctx->app_idx, tx.ctx->addr); + BT_DBG("len %u: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + + if (!bt_mesh_is_provisioned()) { + BT_ERR("Local node is not yet provisioned"); + return -EAGAIN; + } + + return bt_mesh_trans_send(&tx, buf, cb, cb_data); } uint8_t bt_mesh_elem_count(void) @@ -675,32 +719,22 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) (void)op->func(model, &rx->ctx, buf); net_buf_simple_restore(buf, &state); } + + if (MYNEWT_VAL(BLE_MESH_ACCESS_LAYER_MSG) && msg_cb) { + msg_cb(opcode, &rx->ctx, buf); + } } int bt_mesh_model_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *msg, const struct bt_mesh_send_cb *cb, void *cb_data) { - struct bt_mesh_net_tx tx = { - .ctx = ctx, - .src = bt_mesh_model_elem(model)->addr, - }; - - BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx.ctx->net_idx, - tx.ctx->app_idx, tx.ctx->addr); - BT_DBG("len %u: %s", msg->om_len, bt_hex(msg->om_data, msg->om_len)); - - if (!bt_mesh_is_provisioned()) { - BT_ERR("Local node is not yet provisioned"); - return -EAGAIN; - } - - if (!model_has_key(model, tx.ctx->app_idx)) { - BT_ERR("Model not bound to AppKey 0x%04x", tx.ctx->app_idx); + if (!model_has_key(model, ctx->app_idx)) { + BT_ERR("Model not bound to AppKey 0x%04x", ctx->app_idx); return -EINVAL; } - return bt_mesh_trans_send(&tx, msg, cb, cb_data); + return bt_mesh_msg_send(ctx, msg, bt_mesh_model_elem(model)->addr, cb, cb_data); } int bt_mesh_model_publish(struct bt_mesh_model *model) diff --git a/nimble/host/mesh/src/access.h b/nimble/host/mesh/src/access.h index 0bb183c172..033fe9f937 100644 --- a/nimble/host/mesh/src/access.h +++ b/nimble/host/mesh/src/access.h @@ -21,9 +21,11 @@ void bt_mesh_elem_register(struct bt_mesh_elem *elem, uint8_t count); uint8_t bt_mesh_elem_count(void); -/* Find local element based on unicast or group address */ +/* Find local element based on unicast address */ struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr); +bool bt_mesh_has_addr(uint16_t addr); + struct bt_mesh_model *bt_mesh_model_root(struct bt_mesh_model *mod); void bt_mesh_model_tree_walk(struct bt_mesh_model *root, enum bt_mesh_walk (*cb)(struct bt_mesh_model *mod, @@ -59,5 +61,29 @@ void bt_mesh_model_bind_store(struct bt_mesh_model *mod); void bt_mesh_model_sub_store(struct bt_mesh_model *mod); void bt_mesh_model_pub_store(struct bt_mesh_model *mod); void bt_mesh_model_settings_commit(void); + +/** @brief Register a callback function hook for mesh model messages. + * + * Register a callback function to act as a hook for recieving mesh model layer messages + * directly to the application without having instantiated the relevant models. + * + * @param cb A pointer to the callback function. + */ +void bt_mesh_msg_cb_set(void (*cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf)); + +/** @brief Send a mesh model message. + * + * Send a mesh model layer message out into the mesh network without having instantiated + * the relevant mesh models. + * + * @param ctx The Bluetooth mesh message context. + * @param buf The message payload. + * + * @return 0 on success or negative error code on failure. + */ +int bt_mesh_msg_send(struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf, uint16_t src_addr, + const struct bt_mesh_send_cb *cb, void *cb_data); + void bt_mesh_access_init(void); #endif diff --git a/nimble/host/mesh/src/app_keys.c b/nimble/host/mesh/src/app_keys.c index 16236009d3..4a0aebc062 100644 --- a/nimble/host/mesh/src/app_keys.c +++ b/nimble/host/mesh/src/app_keys.c @@ -502,7 +502,7 @@ int bt_mesh_keys_resolve(struct bt_mesh_msg_ctx *ctx, } if (ctx->app_idx == BT_MESH_KEY_DEV_REMOTE && - !bt_mesh_elem_find(ctx->addr)) { + !bt_mesh_has_addr(ctx->addr)) { struct bt_mesh_cdb_node *node; if (!IS_ENABLED(CONFIG_BT_MESH_CDB)) { diff --git a/nimble/host/mesh/src/friend.c b/nimble/host/mesh/src/friend.c index 13ce285d51..685e26f54c 100644 --- a/nimble/host/mesh/src/friend.c +++ b/nimble/host/mesh/src/friend.c @@ -489,7 +489,7 @@ static int encrypt_friend_pdu(struct bt_mesh_friend *frnd, struct os_mbuf *buf, src = sys_get_be16(&buf->om_data[5]); - if (bt_mesh_elem_find(src)) { + if (bt_mesh_has_addr(src)) { uint32_t seq; if (FRIEND_ADV(buf)->app_idx != BT_MESH_KEY_UNUSED) { @@ -1043,7 +1043,7 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) (unsigned) frnd->poll_to); if (BT_MESH_ADDR_IS_UNICAST(frnd->clear.frnd) && - !bt_mesh_elem_find(frnd->clear.frnd)) { + !bt_mesh_has_addr(frnd->clear.frnd)) { clear_procedure_start(frnd); } @@ -1424,7 +1424,7 @@ static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd, * this rx function. These packets have already been added to the * queue, and should be ignored. */ - if (bt_mesh_elem_find(rx->ctx.addr)) { + if (bt_mesh_has_addr(rx->ctx.addr)) { return; } diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index 865747b048..62fcc41e33 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -506,7 +506,7 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct os_mbuf *buf, /* Deliver to local network interface if necessary */ if (bt_mesh_fixed_group_match(tx->ctx->addr) || - bt_mesh_elem_find(tx->ctx->addr)) { + bt_mesh_has_addr(tx->ctx->addr)) { err = loopback(tx, buf->om_data, buf->om_len); /* Local unicast messages should not go out to network */ @@ -604,7 +604,7 @@ static bool net_decrypt(struct bt_mesh_net_rx *rx, struct os_mbuf *in, return false; } - if (bt_mesh_elem_find(rx->ctx.addr)) { + if (bt_mesh_has_addr(rx->ctx.addr)) { BT_DBG("Dropping locally originated packet"); return false; } @@ -815,7 +815,7 @@ void bt_mesh_net_recv(struct os_mbuf *data, int8_t rssi, net_buf_simple_save(buf, &state); rx.local_match = (bt_mesh_fixed_group_match(rx.ctx.recv_dst) || - bt_mesh_elem_find(rx.ctx.recv_dst)); + bt_mesh_has_addr(rx.ctx.recv_dst)); if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY)) && net_if == BT_MESH_NET_IF_PROXY) { diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index 58d227c691..3677791a0d 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -153,6 +153,13 @@ syscfg.defs: value: 1 restrictions: BLE_MESH_GATT_SERVER + BLE_MESH_ACCESS_LAYER_MSG: + descryption: > + This option allows the applicaiton to directly access + Bluetooth access layer messages without the need to + instantiate Bluetooth mesh models. + value: 1 + BLE_MESH_PROXY_USE_DEVICE_NAME: description: > Include Bluetooth device name in scan response From 94a721301ac77c03fa304f82fe00d255aa18033e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 10:37:38 +0200 Subject: [PATCH 0122/1333] host/mesh: Add missing Configuration Client API Add missing API: - Delete all group addresses in a SIG model's subscription list - Update a network key - Update an application key - Get/Set Node Identity parameters - Set virtual addtess for a SIG model - Get/Set Key Refresh Procedures This is port of 22aafd422cea80ba2426b8be7cb59806278ebdd9 --- nimble/host/mesh/include/mesh/cfg_cli.h | 32 +- nimble/host/mesh/include/mesh/glue.h | 1 + nimble/host/mesh/src/cfg_cli.c | 519 +++++++++++++++++++++++- nimble/host/mesh/src/glue.c | 14 + 4 files changed, 560 insertions(+), 6 deletions(-) diff --git a/nimble/host/mesh/include/mesh/cfg_cli.h b/nimble/host/mesh/include/mesh/cfg_cli.h index c117066d27..0bf7cdd70d 100644 --- a/nimble/host/mesh/include/mesh/cfg_cli.h +++ b/nimble/host/mesh/include/mesh/cfg_cli.h @@ -41,6 +41,12 @@ int bt_mesh_cfg_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, int bt_mesh_cfg_beacon_get(uint16_t net_idx, uint16_t addr, uint8_t *status); +int bt_mesh_cfg_krp_get(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx, + uint8_t *status, uint8_t *phase); + +int bt_mesh_cfg_krp_set(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx, + uint8_t transition, uint8_t *status, uint8_t *phase); + int bt_mesh_cfg_beacon_set(uint16_t net_idx, uint16_t addr, uint8_t val, uint8_t *status); int bt_mesh_cfg_ttl_get(uint16_t net_idx, uint16_t addr, uint8_t *ttl); @@ -153,7 +159,8 @@ int bt_mesh_cfg_mod_app_get_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_a #define BT_MESH_PUB_PERIOD_10MIN(steps) (((steps) & BIT_MASK(6)) | (3 << 6)) struct bt_mesh_cfg_mod_pub { - uint16_t addr; + uint16_t addr; + const uint8_t *uuid; uint16_t app_idx; bool cred_flag; uint8_t ttl; @@ -262,6 +269,29 @@ int bt_mesh_cfg_hb_pub_set(uint16_t net_idx, uint16_t addr, int bt_mesh_cfg_hb_pub_get(uint16_t net_idx, uint16_t addr, struct bt_mesh_cfg_hb_pub *pub, uint8_t *status); +int bt_mesh_cfg_mod_sub_del_all(uint16_t net_idx, uint16_t addr, + uint16_t elem_addr, uint16_t mod_id, + uint8_t *status); + +int bt_mesh_cfg_net_key_update(uint16_t net_idx, uint16_t addr, + uint16_t key_net_idx, const uint8_t net_key[16], + uint8_t *status); + +int bt_mesh_cfg_app_key_update(uint16_t net_idx, uint16_t addr, + uint16_t key_net_idx, uint16_t key_app_idx, + const uint8_t app_key[16], uint8_t *status); + +int bt_mesh_cfg_node_identity_set(uint16_t net_idx, uint16_t addr, + uint16_t key_net_idx, uint8_t new_identity, + uint8_t *status, uint8_t *identity); + +int bt_mesh_cfg_node_identity_get(uint16_t net_idx, uint16_t addr, + uint16_t key_net_idx, uint8_t *status, + uint8_t *identity); + +int bt_mesh_cfg_lpn_timeout_get(uint16_t net_idx, uint16_t addr, + uint16_t unicast_addr, int32_t *polltimeout); + int32_t bt_mesh_cfg_cli_timeout_get(void); void bt_mesh_cfg_cli_timeout_set(int32_t timeout); diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index 2261504a01..955aeb38ed 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -250,6 +250,7 @@ void * net_buf_ref(struct os_mbuf *om); void net_buf_unref(struct os_mbuf *om); uint16_t net_buf_simple_pull_le16(struct os_mbuf *om); uint16_t net_buf_simple_pull_be16(struct os_mbuf *om); +uint32_t net_buf_simple_pull_le24(struct os_mbuf *om); uint32_t net_buf_simple_pull_be32(struct os_mbuf *om); uint32_t net_buf_simple_pull_le32(struct os_mbuf *om); uint8_t net_buf_simple_pull_u8(struct os_mbuf *om); diff --git a/nimble/host/mesh/src/cfg_cli.c b/nimble/host/mesh/src/cfg_cli.c index 99a7c1685a..c3d5fbcf59 100644 --- a/nimble/host/mesh/src/cfg_cli.c +++ b/nimble/host/mesh/src/cfg_cli.c @@ -111,6 +111,55 @@ static int gatt_proxy_status(struct bt_mesh_model *model, return state_status_u8(model, ctx, buf, OP_GATT_PROXY_STATUS); } +static int transmit_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + return state_status_u8(model, ctx, buf, OP_NET_TRANSMIT_STATUS); +} + + struct krp_param { + uint8_t *status; + uint16_t net_idx; + uint8_t *phase; +}; + +static int krp_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct krp_param *param; + uint16_t net_idx; + uint8_t status, phase; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_KRP_STATUS, ctx->addr, + (void **)¶m)) { + return -ENOENT; + } + + status = net_buf_simple_pull_u8(buf); + net_idx = net_buf_simple_pull_le16(buf) & 0xfff; + phase = net_buf_simple_pull_u8(buf); + + if (param->net_idx != net_idx) { + return -ENOENT; + } + + if (param && param->status) { + *param->status = status; + } + + if (param && param->phase) { + *param->phase = phase; + } + + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; +} + struct relay_param { uint8_t *status; uint8_t *transmit; @@ -743,6 +792,87 @@ static int hb_pub_status(struct bt_mesh_model *model, return 0; } +struct node_idt_param { + uint8_t *status; + uint16_t net_idx; + uint8_t *identity; +}; + +static int node_identity_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct node_idt_param *param; + uint16_t net_idx, identity; + uint8_t status; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_NODE_IDENTITY_STATUS, + ctx->addr, (void **)¶m)) { + return -ENOENT; + } + + status = net_buf_simple_pull_u8(buf); + net_idx = net_buf_simple_pull_le16(buf) & 0xfff; + identity = net_buf_simple_pull_u8(buf); + + if (param && param->status) { + *param->status = status; + } + + if (param->net_idx != net_idx) { + return -ENOENT; + } + + if (param && param->identity) { + *param->identity = identity; + } + + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; +} + +struct lpn_timeout_param { + uint16_t unicast_addr; + int32_t *polltimeout; +}; + +static int lpn_timeout_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct lpn_timeout_param *param; + uint16_t unicast_addr; + int32_t polltimeout; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_LPN_TIMEOUT_STATUS, ctx->addr, + (void **)¶m)) { + return -ENOENT; + } + + unicast_addr = net_buf_simple_pull_le16(buf); + polltimeout = net_buf_simple_pull_le24(buf); + + if (param->unicast_addr != unicast_addr) { + return -ENOENT; + } + + if (param && param->polltimeout) { + *param->polltimeout = polltimeout; + } + + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + + return 0; +} + const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = { { OP_DEV_COMP_DATA_STATUS, BT_MESH_LEN_MIN(15), comp_data_status }, { OP_BEACON_STATUS, BT_MESH_LEN_EXACT(1), beacon_status }, @@ -765,6 +895,10 @@ const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = { { OP_HEARTBEAT_SUB_STATUS, BT_MESH_LEN_EXACT(9), hb_sub_status }, { OP_HEARTBEAT_PUB_STATUS, BT_MESH_LEN_EXACT(10), hb_pub_status }, { OP_NODE_RESET_STATUS, BT_MESH_LEN_EXACT(0), node_reset_status }, + { OP_NODE_IDENTITY_STATUS, BT_MESH_LEN_EXACT(4), node_identity_status}, + { OP_LPN_TIMEOUT_STATUS, BT_MESH_LEN_EXACT(5), lpn_timeout_status }, + { OP_NET_TRANSMIT_STATUS, BT_MESH_LEN_EXACT(1), transmit_status}, + { OP_KRP_STATUS, BT_MESH_LEN_EXACT(4), krp_status}, BT_MESH_MODEL_OP_END, }; @@ -918,6 +1052,75 @@ int bt_mesh_cfg_beacon_get(uint16_t net_idx, uint16_t addr, uint8_t *status) status); } +int bt_mesh_cfg_krp_get(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx, + uint8_t *status, uint8_t *phase) +{ + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_KRP_GET, 2); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV_REMOTE, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct krp_param param = { + .status = status, + .phase = phase, + }; + int err; + + err = cli_prepare(¶m, OP_KRP_STATUS, addr); + if (err) { + return err; + } + + bt_mesh_model_msg_init(msg, OP_KRP_GET); + net_buf_simple_add_le16(msg, key_net_idx); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); + return err; + } + + return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); +} + +int bt_mesh_cfg_krp_set(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx, + uint8_t transition, uint8_t *status, uint8_t *phase) +{ + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_KRP_SET, 3); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV_REMOTE, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct krp_param param = { + .status = status, + .phase = phase, + }; + int err; + + err = cli_prepare(¶m, OP_KRP_STATUS, addr); + if (err) { + return err; + } + + bt_mesh_model_msg_init(msg, OP_KRP_SET); + net_buf_simple_add_le16(msg, key_net_idx); + net_buf_simple_add_u8(msg, transition); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); + return err; + } + + return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); +} + int bt_mesh_cfg_beacon_set(uint16_t net_idx, uint16_t addr, uint8_t val, uint8_t *status) { return set_state_u8(net_idx, addr, OP_BEACON_SET, OP_BEACON_STATUS, @@ -1092,6 +1295,47 @@ int bt_mesh_cfg_net_key_add(uint16_t net_idx, uint16_t addr, uint16_t key_net_id return err; } +int bt_mesh_cfg_net_key_update(uint16_t net_idx, uint16_t addr, + uint16_t key_net_idx, const uint8_t net_key[16], + uint8_t *status) +{ + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NET_KEY_UPDATE, 18); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV_REMOTE, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct net_key_param param = { + .status = status, + .net_idx = key_net_idx, + }; + int err; + + err = cli_prepare(¶m, OP_NET_KEY_STATUS, addr); + if (err) { + return err; + } + + bt_mesh_model_msg_init(msg, OP_NET_KEY_UPDATE); + net_buf_simple_add_le16(msg, key_net_idx); + net_buf_simple_add_mem(msg, net_key, 16); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); + return err; + } + + if (!status) { + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); + return 0; + } + + return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); +} + int bt_mesh_cfg_net_key_get(uint16_t net_idx, uint16_t addr, uint16_t *keys, size_t *key_cnt) { @@ -1213,6 +1457,48 @@ int bt_mesh_cfg_app_key_add(uint16_t net_idx, uint16_t addr, uint16_t key_net_id return err; } +int bt_mesh_cfg_app_key_update(uint16_t net_idx, uint16_t addr, + uint16_t key_net_idx, uint16_t key_app_idx, + const uint8_t app_key[16], uint8_t *status) +{ + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_APP_KEY_UPDATE, 19); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV_REMOTE, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct app_key_param param = { + .status = status, + .net_idx = key_net_idx, + .app_idx = key_app_idx, + }; + int err; + + err = cli_prepare(¶m, OP_APP_KEY_STATUS, addr); + if (err) { + return err; + } + + bt_mesh_model_msg_init(msg, OP_APP_KEY_UPDATE); + key_idx_pack(msg, key_net_idx, key_app_idx); + net_buf_simple_add_mem(msg, app_key, 16); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); + return err; + } + + if (!status) { + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); + return 0; + } + + return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); +} + int bt_mesh_cfg_node_reset(uint16_t net_idx, uint16_t addr, bool *status) { struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NODE_RESET, 0); @@ -1644,6 +1930,49 @@ int bt_mesh_cfg_mod_sub_del(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, mod_id, CID_NVAL, status); } +int bt_mesh_cfg_mod_sub_del_all(uint16_t net_idx, uint16_t addr, + uint16_t elem_addr, uint16_t mod_id, + uint8_t *status) +{ + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_SUB_DEL_ALL, 6); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV_REMOTE, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct mod_sub_param param = { + .status = status, + .elem_addr = elem_addr, + .mod_id = mod_id, + .cid = CID_NVAL, + }; + int err; + + err = cli_prepare(¶m, OP_MOD_SUB_STATUS, addr); + if (err) { + return err; + } + + bt_mesh_model_msg_init(msg, OP_MOD_SUB_DEL_ALL); + net_buf_simple_add_le16(msg, elem_addr); + net_buf_simple_add_le16(msg, mod_id); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); + return err; + } + + if (!status) { + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); + return 0; + } + + return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); +} + int bt_mesh_cfg_mod_sub_del_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t sub_addr, uint16_t mod_id, uint16_t cid, uint8_t *status) @@ -1946,23 +2275,86 @@ static int mod_pub_set(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, return err; } +static int mod_pub_va_set(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, + uint16_t mod_id, uint16_t cid, + struct bt_mesh_cfg_mod_pub *pub, uint8_t *status) +{ + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_PUB_VA_SET, 27); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV_REMOTE, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct mod_pub_param param = { + .mod_id = mod_id, + .cid = cid, + .elem_addr = elem_addr, + .status = status, + .pub = pub, + }; + int err; + + err = cli_prepare(¶m, OP_MOD_PUB_STATUS, addr); + if (err) { + return err; + } + BT_DBG("app_idx 0x%04x", pub->app_idx); + bt_mesh_model_msg_init(msg, OP_MOD_PUB_VA_SET); + + net_buf_simple_add_le16(msg, elem_addr); + net_buf_simple_add_mem(msg, pub->uuid, 16); + net_buf_simple_add_le16(msg, (pub->app_idx | (pub->cred_flag << 12))); + net_buf_simple_add_u8(msg, pub->ttl); + net_buf_simple_add_u8(msg, pub->period); + net_buf_simple_add_u8(msg, pub->transmit); + + if (cid != CID_NVAL) { + net_buf_simple_add_le16(msg, cid); + } + + net_buf_simple_add_le16(msg, mod_id); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); + return err; + } + + if (!status) { + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); + return 0; + } + + return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); +} + + int bt_mesh_cfg_mod_pub_set(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t mod_id, struct bt_mesh_cfg_mod_pub *pub, uint8_t *status) { - return mod_pub_set(net_idx, addr, elem_addr, mod_id, CID_NVAL, - pub, status); + if (pub->uuid) { + return mod_pub_va_set(net_idx, addr, elem_addr, mod_id, CID_NVAL, pub, status); + } else { + return mod_pub_set(net_idx, addr, elem_addr, mod_id, CID_NVAL, pub, status); + } } int bt_mesh_cfg_mod_pub_set_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, - uint16_t mod_id, uint16_t cid, - struct bt_mesh_cfg_mod_pub *pub, uint8_t *status) + uint16_t mod_id, uint16_t cid, struct bt_mesh_cfg_mod_pub *pub, + uint8_t *status) { if (cid == CID_NVAL) { return -EINVAL; } - return mod_pub_set(net_idx, addr, elem_addr, mod_id, cid, pub, status); + if (pub->uuid) { + return mod_pub_va_set(net_idx, addr, elem_addr, mod_id, cid, pub, status); + } else { + return mod_pub_set(net_idx, addr, elem_addr, mod_id, cid, pub, status); + } } int bt_mesh_cfg_hb_sub_set(uint16_t net_idx, uint16_t addr, @@ -2137,6 +2529,123 @@ int bt_mesh_cfg_hb_pub_get(uint16_t net_idx, uint16_t addr, return err; } +int bt_mesh_cfg_node_identity_set(uint16_t net_idx, uint16_t addr, + uint16_t key_net_idx, uint8_t new_identity, + uint8_t *status, uint8_t *identity) +{ + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NODE_IDENTITY_SET, 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV_REMOTE, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct node_idt_param param = { + .status = status, + .net_idx = key_net_idx, + .identity = identity, + }; + int err; + + err = cli_prepare(¶m, OP_NODE_IDENTITY_STATUS, addr); + if (err) { + return err; + } + + bt_mesh_model_msg_init(msg, OP_NODE_IDENTITY_SET); + net_buf_simple_add_le16(msg, key_net_idx); + net_buf_simple_add_u8(msg, new_identity); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); + return err; + } + + if (!status) { + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); + return 0; + } + + return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); +} + +int bt_mesh_cfg_node_identity_get(uint16_t net_idx, uint16_t addr, + uint16_t key_net_idx, uint8_t *status, + uint8_t *identity) +{ + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_NODE_IDENTITY_GET, 2); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV_REMOTE, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct node_idt_param param = { + .status = status, + .net_idx = key_net_idx, + .identity = identity, + }; + int err; + + err = cli_prepare(¶m, OP_NODE_IDENTITY_STATUS, addr); + if (err) { + return err; + } + + bt_mesh_model_msg_init(msg, OP_NODE_IDENTITY_GET); + net_buf_simple_add_le16(msg, key_net_idx); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); + return err; + } + + if (!status) { + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); + return 0; + } + + return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); +} + +int bt_mesh_cfg_lpn_timeout_get(uint16_t net_idx, uint16_t addr, + uint16_t unicast_addr, int32_t *polltimeout) +{ + struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_LPN_TIMEOUT_GET, 2); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV_REMOTE, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct lpn_timeout_param param = { + .unicast_addr = unicast_addr, + .polltimeout = polltimeout, + }; + int err; + + err = cli_prepare(¶m, OP_LPN_TIMEOUT_STATUS, addr); + if (err) { + return err; + } + + bt_mesh_model_msg_init(msg, OP_LPN_TIMEOUT_GET); + net_buf_simple_add_le16(msg, unicast_addr); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); + return err; + } + + return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); +} + int32_t bt_mesh_cfg_cli_timeout_get(void) { return msg_timeout; diff --git a/nimble/host/mesh/src/glue.c b/nimble/host/mesh/src/glue.c index 2059e2a6f4..e79c43b284 100644 --- a/nimble/host/mesh/src/glue.c +++ b/nimble/host/mesh/src/glue.c @@ -142,6 +142,20 @@ net_buf_simple_pull_le16(struct os_mbuf *om) return val; } +uint32_t +net_buf_simple_pull_le24(struct os_mbuf *om) +{ + uint16_t val; + struct os_mbuf *old = om; + + om = os_mbuf_pullup(om, sizeof(val)); + assert(om == old); + val = get_le24(om->om_data); + os_mbuf_adj(om, sizeof(val)); + + return val; +} + uint16_t net_buf_simple_pull_be16(struct os_mbuf *om) { From 842153b06ec61022911e31f82b40997e45df0324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 10:39:18 +0200 Subject: [PATCH 0123/1333] host/mesh: Fix Health Client Model Assigning a value to the msg_timeout parameter. This is port of a279ff3958aca2d2d665710d0b4f35a1cc8417b3 --- nimble/host/mesh/src/health_cli.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/host/mesh/src/health_cli.c b/nimble/host/mesh/src/health_cli.c index 8424e4200d..caa70215b7 100644 --- a/nimble/host/mesh/src/health_cli.c +++ b/nimble/host/mesh/src/health_cli.c @@ -509,6 +509,7 @@ static int health_cli_init(struct bt_mesh_model *model) cli = model->user_data; cli->model = model; + msg_timeout = 2 * MSEC_PER_SEC; /* Set the default health client pointer */ if (!health_cli) { From 1939344ab78a4a1a358bdf01dfab53483b889001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 10:44:10 +0200 Subject: [PATCH 0124/1333] host/mesh: fix label logging in mod_sub_va --- nimble/host/mesh/src/cfg_cli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/cfg_cli.c b/nimble/host/mesh/src/cfg_cli.c index c3d5fbcf59..f0f2ba8426 100644 --- a/nimble/host/mesh/src/cfg_cli.c +++ b/nimble/host/mesh/src/cfg_cli.c @@ -2030,7 +2030,7 @@ static int mod_sub_va(uint32_t op, uint16_t net_idx, uint16_t addr, uint16_t ele } BT_DBG("net_idx 0x%04x addr 0x%04x elem_addr 0x%04x label %s", - net_idx, addr, elem_addr, label); + net_idx, addr, elem_addr, bt_hex(label, 16)); BT_DBG("mod_id 0x%04x cid 0x%04x", mod_id, cid); bt_mesh_model_msg_init(msg, op); From 623c14de1c650e81406525ac287a838279ef5f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 10:46:18 +0200 Subject: [PATCH 0125/1333] host/mesh: Add pointer conversion for prov->uri `prov_sd[0].data` and `prov->uri` have different point type. This is port of 9042f76b8b8abd349ada9daf7cfd3272491055db --- nimble/host/mesh/src/gatt_services.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/gatt_services.c b/nimble/host/mesh/src/gatt_services.c index 38f5ee1147..b74e596fe5 100644 --- a/nimble/host/mesh/src/gatt_services.c +++ b/nimble/host/mesh/src/gatt_services.c @@ -1196,7 +1196,7 @@ static size_t gatt_prov_adv_create(struct bt_data prov_sd[2]) } else { prov_sd[0].type = BT_DATA_URI; prov_sd[0].data_len = uri_len; - prov_sd[0].data = (void *)prov->uri; + prov_sd[0].data = (const uint8_t *)prov->uri; sd_space -= 2 + uri_len; prov_sd_len++; } From df601cfcbdab6bfa5546c70d46ba914181333b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 11:06:09 +0200 Subject: [PATCH 0126/1333] host/mesh: Refactor Mesh Model Extensions The existing extension tree does not support all the features that are defined by the specification (e.g. multiple parents). This patch approaches this problem by defining a circular single-linked list of extension models. So for a given model, all models that are on the same list as that model are in some extension relationship with that model. All models on a list represent a single connected component of an extension graph but without defining specific relationships between each pair of models. This list is used to manage a shared subscription list as per the Mesh Profile Specification: ```4.2.4 Subscription List Within an element, each model has a separate instance of a Subscription List, unless the model extends another model on that element. Instances of models that extend other models (i.e., all models within an extension relation tree) shall share a single instance of a Subscription List per element. ``` This is port of e167ca653907ff0979e38636009913bce8cd7374 --- nimble/host/mesh/include/mesh/access.h | 29 ++++--- nimble/host/mesh/src/access.c | 112 ++++++++++++------------- nimble/host/mesh/src/access.h | 10 +-- nimble/host/mesh/src/cfg_srv.c | 21 ++--- 4 files changed, 80 insertions(+), 92 deletions(-) diff --git a/nimble/host/mesh/include/mesh/access.h b/nimble/host/mesh/include/mesh/access.h index e20cf70086..6c7c542690 100644 --- a/nimble/host/mesh/include/mesh/access.h +++ b/nimble/host/mesh/include/mesh/access.h @@ -467,11 +467,10 @@ struct bt_mesh_model { const struct bt_mesh_model_cb * const cb; #if MYNEWT_VAL(BLE_MESH_MODEL_EXTENSIONS) - /* Pointer to the next model in a model extension tree. */ + /* Pointer to the next model in a model extension list. */ struct bt_mesh_model *next; - /* Pointer to the first model this model extends. */ - struct bt_mesh_model *extends; #endif + /* Model-specific user data */ void *user_data; }; @@ -581,25 +580,31 @@ int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, * Mesh models may be extended to reuse their functionality, forming a more * complex model. A Mesh model may extend any number of models, in any element. * The extensions may also be nested, ie a model that extends another may itself - * be extended. Extensions may not be cyclical, and a model can only be extended - * by one other model. + * be extended. * - * A set of models that extend each other form a model extension tree. + * A set of models that extend each other form a model extension list. * - * All models in an extension tree share one subscription list per element. The + * All models in an extension list share one subscription list per element. The * access layer will utilize the combined subscription list of all models in an - * extension tree and element, giving the models extended subscription list + * extension list and element, giving the models extended subscription list * capacity. * - * @param[in] mod Mesh model. - * @param[in] base_mod The model being extended. + * @param extending_mod Mesh model that is extending the base model. + * @param base_mod The model being extended. * * @retval 0 Successfully extended the base_mod model. - * @retval -EALREADY The base_mod model is already extended. */ -int bt_mesh_model_extend(struct bt_mesh_model *mod, +int bt_mesh_model_extend(struct bt_mesh_model *extending_mod, struct bt_mesh_model *base_mod); +/** @brief Check if model is extended by another model. + * + * @param model The model to check. + * + * @retval true If model is extended by another model, otherwise false + */ +bool bt_mesh_model_is_extended(struct bt_mesh_model *model); + /** Node Composition */ struct bt_mesh_comp { uint16_t cid; diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index 42a5185e44..f528e4878a 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -32,7 +32,7 @@ enum { BT_MESH_MOD_BIND_PENDING = BIT(0), BT_MESH_MOD_SUB_PENDING = BIT(1), BT_MESH_MOD_PUB_PENDING = BIT(2), - BT_MESH_MOD_NEXT_IS_PARENT = BIT(3), + BT_MESH_MOD_EXTENDED = BIT(3), }; /* Model publication information for persistent storage. */ @@ -421,8 +421,7 @@ struct find_group_visitor_ctx { uint16_t addr; }; -static enum bt_mesh_walk find_group_mod_visitor(struct bt_mesh_model *mod, - uint32_t depth, void *user_data) +static enum bt_mesh_walk find_group_mod_visitor(struct bt_mesh_model *mod, void *user_data) { struct find_group_visitor_ctx *ctx = user_data; @@ -447,8 +446,7 @@ uint16_t *bt_mesh_model_find_group(struct bt_mesh_model **mod, uint16_t addr) .addr = addr, }; - bt_mesh_model_tree_walk(bt_mesh_model_root(*mod), - find_group_mod_visitor, &ctx); + bt_mesh_model_extensions_walk(*mod, find_group_mod_visitor, &ctx); *mod = ctx.mod; return ctx.entry; @@ -810,73 +808,62 @@ const struct bt_mesh_comp *bt_mesh_comp_get(void) return dev_comp; } -struct bt_mesh_model *bt_mesh_model_root(struct bt_mesh_model *mod) +void bt_mesh_model_extensions_walk(struct bt_mesh_model *model, + enum bt_mesh_walk (*cb)(struct bt_mesh_model *mod, + void *user_data), + void *user_data) { -#ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS - while (mod->next) { - mod = mod->next; +#ifndef CONFIG_BT_MESH_MODEL_EXTENSIONS + (void)cb(model, user_data); + return; +#else + struct bt_mesh_model *it; + + if (model->next == NULL) { + (void)cb(model, user_data); + return; } -#endif - return mod; -} - -void bt_mesh_model_tree_walk(struct bt_mesh_model *root, - enum bt_mesh_walk (*cb)(struct bt_mesh_model *mod, - uint32_t depth, - void *user_data), - void *user_data) -{ - struct bt_mesh_model *m = root; - int depth = 0; - /* 'skip' is set to true when we ascend from child to parent node. - * In that case, we want to skip calling the callback on the parent - * node and we don't want to descend onto a child node as those - * nodes have already been visited. - */ - bool skip = false; - - do { - if (!skip && - cb(m, (uint32_t)depth, user_data) == BT_MESH_WALK_STOP) { + for (it = model; (it != NULL) && (it->next != model); it = it->next) { + if (cb(it, user_data) == BT_MESH_WALK_STOP) { return; } -#if MYNEWT_VAL(BLE_MESH_MODEL_EXTENSIONS) - if (!skip && m->extends) { - m = m->extends; - depth++; - } else if (m->flags & BT_MESH_MOD_NEXT_IS_PARENT) { - m = m->next; - depth--; - skip = true; - } else { - m = m->next; - skip = false; - } + } #endif - } while (m && depth > 0); } #if MYNEWT_VAL(BLE_MESH_MODEL_EXTENSIONS) -int bt_mesh_model_extend(struct bt_mesh_model *mod, - struct bt_mesh_model *base_mod) +int bt_mesh_model_extend(struct bt_mesh_model *extending_mod, struct bt_mesh_model *base_mod) { - /* Form a cyclical LCRS tree: - * The extends-pointer points to the first child, and the next-pointer - * points to the next sibling. The last sibling is marked by the - * BT_MESH_MOD_NEXT_IS_PARENT flag, and its next-pointer points back to - * the parent. This way, the whole tree is accessible from any node. - * - * We add children (extend them) by inserting them as the first child. - */ - if (base_mod->next) { - return -EALREADY; + struct bt_mesh_model *a = extending_mod; + struct bt_mesh_model *b = base_mod; + struct bt_mesh_model *a_next = a->next; + struct bt_mesh_model *b_next = b->next; + struct bt_mesh_model *it; + + base_mod->flags |= BT_MESH_MOD_EXTENDED; + + if (a == b) { + return 0; + } + + /* Check if a's list contains b */ + for (it = a; (it != NULL) && (it->next != a); it = it->next) { + if (it == b) { + return 0; + } } - if (mod->extends) { - base_mod->next = mod->extends; + /* Merge lists */ + if (a_next) { + b->next = a_next; } else { - base_mod->next = mod; - base_mod->flags |= BT_MESH_MOD_NEXT_IS_PARENT; + b->next = a; + } + + if (b_next) { + a->next = b_next; + } else { + a->next = b; } mod->extends = base_mod; @@ -884,6 +871,11 @@ int bt_mesh_model_extend(struct bt_mesh_model *mod, } #endif +bool bt_mesh_model_is_extended(struct bt_mesh_model *model) +{ + return model->flags & BT_MESH_MOD_EXTENDED; +} + static int mod_set_bind(struct bt_mesh_model *mod, char *val) { int len, err, i; diff --git a/nimble/host/mesh/src/access.h b/nimble/host/mesh/src/access.h index 033fe9f937..34ac248792 100644 --- a/nimble/host/mesh/src/access.h +++ b/nimble/host/mesh/src/access.h @@ -26,12 +26,10 @@ struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr); bool bt_mesh_has_addr(uint16_t addr); -struct bt_mesh_model *bt_mesh_model_root(struct bt_mesh_model *mod); -void bt_mesh_model_tree_walk(struct bt_mesh_model *root, - enum bt_mesh_walk (*cb)(struct bt_mesh_model *mod, - uint32_t depth, - void *user_data), - void *user_data); +void bt_mesh_model_extensions_walk(struct bt_mesh_model *root, + enum bt_mesh_walk (*cb)(struct bt_mesh_model *mod, + void *user_data), + void *user_data); uint16_t *bt_mesh_model_find_group(struct bt_mesh_model **mod, uint16_t addr); diff --git a/nimble/host/mesh/src/cfg_srv.c b/nimble/host/mesh/src/cfg_srv.c index 4a63be7e70..11a1e4dffc 100644 --- a/nimble/host/mesh/src/cfg_srv.c +++ b/nimble/host/mesh/src/cfg_srv.c @@ -1172,8 +1172,7 @@ static int mod_sub_del(struct bt_mesh_model *model, mod_id, vnd); } -static enum bt_mesh_walk mod_sub_clear_visitor(struct bt_mesh_model *mod, - uint32_t depth, void *user_data) +static enum bt_mesh_walk mod_sub_clear_visitor(struct bt_mesh_model *mod, void *user_data) { if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { bt_mesh_lpn_group_del(mod->groups, ARRAY_SIZE(mod->groups)); @@ -1232,8 +1231,7 @@ static int mod_sub_overwrite(struct bt_mesh_model *model, } if (ARRAY_SIZE(mod->groups) > 0) { - bt_mesh_model_tree_walk(bt_mesh_model_root(mod), - mod_sub_clear_visitor, NULL); + bt_mesh_model_extensions_walk(mod, mod_sub_clear_visitor, NULL); mod->groups[0] = sub_addr; status = STATUS_SUCCESS; @@ -1295,8 +1293,7 @@ static int mod_sub_del_all(struct bt_mesh_model *model, goto send_status; } - bt_mesh_model_tree_walk(bt_mesh_model_root(mod), mod_sub_clear_visitor, - NULL); + bt_mesh_model_extensions_walk(mod, mod_sub_clear_visitor, NULL); if (IS_ENABLED(CONFIG_BT_SETTINGS)) { bt_mesh_model_sub_store(mod); @@ -1314,8 +1311,7 @@ struct mod_sub_list_ctx { struct os_mbuf *msg; }; -static enum bt_mesh_walk mod_sub_list_visitor(struct bt_mesh_model *mod, - uint32_t depth, void *ctx) +static enum bt_mesh_walk mod_sub_list_visitor(struct bt_mesh_model *mod, void *ctx) { struct mod_sub_list_ctx *visit = ctx; int count = 0; @@ -1393,8 +1389,7 @@ static int mod_sub_get(struct bt_mesh_model *model, visit_ctx.msg = msg; visit_ctx.elem_idx = mod->elem_idx; - bt_mesh_model_tree_walk(bt_mesh_model_root(mod), mod_sub_list_visitor, - &visit_ctx); + bt_mesh_model_extensions_walk(mod, mod_sub_list_visitor, &visit_ctx); send_list: if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { @@ -1458,8 +1453,7 @@ static int mod_sub_get_vnd(struct bt_mesh_model *model, visit_ctx.msg = msg; visit_ctx.elem_idx = mod->elem_idx; - bt_mesh_model_tree_walk(bt_mesh_model_root(mod), mod_sub_list_visitor, - &visit_ctx); + bt_mesh_model_extensions_walk(mod, mod_sub_list_visitor, &visit_ctx); send_list: if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { @@ -1673,8 +1667,7 @@ static int mod_sub_va_overwrite(struct bt_mesh_model *model, if (ARRAY_SIZE(mod->groups) > 0) { status = bt_mesh_va_add(label_uuid, &sub_addr); if (status == STATUS_SUCCESS) { - bt_mesh_model_tree_walk(bt_mesh_model_root(mod), - mod_sub_clear_visitor, NULL); + bt_mesh_model_extensions_walk(mod, mod_sub_clear_visitor, NULL); mod->groups[0] = sub_addr; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { From c7ce0fff207a01ef9750e3a6ad41ce662fbf2191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 11:07:13 +0200 Subject: [PATCH 0127/1333] host/mesh: Mark as internal function Marks funcs:`show_faults` as internal, avoiding conflict. This is port of 3911ce8d40be50649a77465b641de28119219b7e --- nimble/host/mesh/src/shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/shell.c b/nimble/host/mesh/src/shell.c index 61f1db69e0..b0a1b4d2a1 100644 --- a/nimble/host/mesh/src/shell.c +++ b/nimble/host/mesh/src/shell.c @@ -169,7 +169,7 @@ static struct bt_mesh_cfg_cli cfg_cli = { #endif /* MYNEWT_VAL(BLE_MESH_CFG_CLI) */ #if MYNEWT_VAL(BLE_MESH_HEALTH_CLI) -void show_faults(uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count) +static void show_faults(uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count) { size_t i; From 28a82ad50adef5b82ea4a876ecb0d656cf737a10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 12:31:01 +0200 Subject: [PATCH 0128/1333] host/mesh: Add defines for ECC key lengths Adds defines for ECC public keys, private keys, DH keys and key coordinates. Replaces raw numbers throughout. This is port of 8ab219cde5a2d7a87e8d7704a92ffa838cd7473a --- nimble/host/mesh/include/mesh/glue.h | 17 ++++++++++++++--- nimble/host/mesh/include/mesh/main.h | 2 +- nimble/host/mesh/src/prov.c | 2 +- nimble/host/mesh/src/prov.h | 4 ++-- nimble/host/mesh/src/prov_device.c | 21 +++++++++++---------- nimble/host/mesh/src/provisioner.c | 28 +++++++++++++++------------- 6 files changed, 44 insertions(+), 30 deletions(-) diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index 955aeb38ed..944402f725 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -51,6 +51,17 @@ extern "C" { #endif +/** Key size used in Bluetooth's ECC domain. */ +#define BT_ECC_KEY_SIZE 32 + /** Length of a Bluetooth ECC public key coordinate. */ +#define BT_PUB_KEY_COORD_LEN (BT_ECC_KEY_SIZE) + /** Length of a Bluetooth ECC public key. */ +#define BT_PUB_KEY_LEN (2 * (BT_PUB_KEY_COORD_LEN)) + /** Length of a Bluetooth ECC private key. */ +#define BT_PRIV_KEY_LEN (BT_ECC_KEY_SIZE) + /** Length of a Bluetooth Diffie-Hellman key. */ +#define BT_DH_KEY_LEN (BT_ECC_KEY_SIZE) + /** @brief Helper to declare elements of bt_data arrays * * This macro is mainly for creating an array of struct bt_data @@ -310,13 +321,13 @@ struct bt_pub_key_cb { * * @param key The local public key, or NULL in case of no key. */ - void (*func)(const uint8_t key[64]); + void (*func)(const uint8_t key[BT_PUB_KEY_LEN]); struct bt_pub_key_cb *_next; }; -typedef void (*bt_dh_key_cb_t)(const uint8_t key[32]); -int bt_dh_key_gen(const uint8_t remote_pk[64], bt_dh_key_cb_t cb); +typedef void (*bt_dh_key_cb_t)(const uint8_t key[BT_DH_KEY_LEN]); +int bt_dh_key_gen(const uint8_t remote_pk[BT_PUB_KEY_LEN], bt_dh_key_cb_t cb); int bt_pub_key_gen(struct bt_pub_key_cb *new_cb); uint8_t *bt_pub_key_get(void); int bt_rand(void *buf, size_t len); diff --git a/nimble/host/mesh/include/mesh/main.h b/nimble/host/mesh/include/mesh/main.h index d196522dea..6e9d2e629d 100644 --- a/nimble/host/mesh/include/mesh/main.h +++ b/nimble/host/mesh/include/mesh/main.h @@ -291,7 +291,7 @@ int bt_mesh_input_number(uint32_t num); * * @return Zero on success or (negative) error code otherwise. */ -int bt_mesh_prov_remote_pub_key_set(const uint8_t public_key[64]); +int bt_mesh_prov_remote_pub_key_set(const uint8_t public_key[BT_PUB_KEY_LEN]); /** @brief Use Input OOB authentication. * diff --git a/nimble/host/mesh/src/prov.c b/nimble/host/mesh/src/prov.c index 1f5a9eaf7e..64ad656c41 100644 --- a/nimble/host/mesh/src/prov.c +++ b/nimble/host/mesh/src/prov.c @@ -38,7 +38,7 @@ static void pub_key_ready(const uint8_t *pkey) BT_DBG("Local public key ready"); } -int bt_mesh_prov_reset_state(void (*func)(const uint8_t key[64])) +int bt_mesh_prov_reset_state(void (*func)(const uint8_t key[BT_PUB_KEY_LEN])) { BT_DBG("bt_mesh_prov_reset_state"); diff --git a/nimble/host/mesh/src/prov.h b/nimble/host/mesh/src/prov.h index 5c42528c6d..9202275fbd 100644 --- a/nimble/host/mesh/src/prov.h +++ b/nimble/host/mesh/src/prov.h @@ -117,7 +117,7 @@ struct bt_mesh_prov_link { uint8_t oob_size; /* Authen size */ uint8_t auth[16]; /* Authen value */ - uint8_t dhkey[32]; /* Calculated DHKey */ + uint8_t dhkey[BT_DH_KEY_LEN]; /* Calculated DHKey */ uint8_t expect; /* Next expected PDU */ uint8_t conf[16]; /* Remote Confirmation */ uint8_t rand[16]; /* Local Random */ @@ -150,7 +150,7 @@ static inline void bt_mesh_prov_buf_init(struct os_mbuf *buf, uint8_t type) net_buf_simple_add_u8(buf, type); } -int bt_mesh_prov_reset_state(void (*func)(const uint8_t key[64])); +int bt_mesh_prov_reset_state(void (*func)(const uint8_t key[BT_PUB_KEY_LEN])); bool bt_mesh_prov_active(void); diff --git a/nimble/host/mesh/src/prov_device.c b/nimble/host/mesh/src/prov_device.c index 737e216cb2..1562860c5e 100644 --- a/nimble/host/mesh/src/prov_device.c +++ b/nimble/host/mesh/src/prov_device.c @@ -244,13 +244,13 @@ static void send_pub_key(void) return; } - BT_DBG("Local Public Key: %s", bt_hex(key, 64)); + BT_DBG("Local Public Key: %s", bt_hex(key, BT_PUB_KEY_LEN)); bt_mesh_prov_buf_init(buf, PROV_PUB_KEY); /* Swap X and Y halves independently to big-endian */ - sys_memcpy_swap(net_buf_simple_add(buf, 32), key, 32); - sys_memcpy_swap(net_buf_simple_add(buf, 32), &key[32], 32); + sys_memcpy_swap(net_buf_simple_add(buf, BT_PUB_KEY_COORD_LEN), key, BT_PUB_KEY_COORD_LEN); + sys_memcpy_swap(net_buf_simple_add(buf, BT_PUB_KEY_COORD_LEN), &key[BT_PUB_KEY_COORD_LEN], 32); /* PublicKeyDevice */ memcpy(bt_mesh_prov_link.conf_inputs.pub_key_device, &buf->om_data[1], PDU_LEN_PUB_KEY); @@ -265,7 +265,7 @@ static void send_pub_key(void) static void dh_key_gen_complete(void) { - BT_DBG("DHkey: %s", bt_hex(bt_mesh_prov_link.dhkey, 32)); + BT_DBG("DHkey: %s", bt_hex(bt_mesh_prov_link.dhkey, BT_DH_KEY_LEN)); if (!atomic_test_and_clear_bit(bt_mesh_prov_link.flags, WAIT_DH_KEY) && atomic_test_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY)) { @@ -275,7 +275,7 @@ static void dh_key_gen_complete(void) } } -static void prov_dh_key_cb(const uint8_t dhkey[32]) +static void prov_dh_key_cb(const uint8_t dhkey[BT_DH_KEY_LEN]) { BT_DBG("%p", dhkey); @@ -285,7 +285,7 @@ static void prov_dh_key_cb(const uint8_t dhkey[32]) return; } - sys_memcpy_swap(bt_mesh_prov_link.dhkey, dhkey, 32); + sys_memcpy_swap(bt_mesh_prov_link.dhkey, dhkey, BT_DH_KEY_LEN); dh_key_gen_complete(); } @@ -293,7 +293,7 @@ static void prov_dh_key_cb(const uint8_t dhkey[32]) static void prov_dh_key_gen(void) { const uint8_t *remote_pk; - uint8_t remote_pk_le[64]; + uint8_t remote_pk_le[BT_PUB_KEY_LEN]; remote_pk = bt_mesh_prov_link.conf_inputs.pub_key_provisioner; if (MYNEWT_VAL(BLE_MESH_PROV_OOB_PUBLIC_KEY) && @@ -317,8 +317,9 @@ static void prov_dh_key_gen(void) * X and Y halves are swapped independently. The bt_dh_key_gen() * will also take care of validating the remote public key. */ - sys_memcpy_swap(remote_pk_le, remote_pk, 32); - sys_memcpy_swap(&remote_pk_le[32], &remote_pk[32], 32); + sys_memcpy_swap(remote_pk_le, remote_pk, BT_PUB_KEY_COORD_LEN); + sys_memcpy_swap(&remote_pk_le[BT_PUB_KEY_COORD_LEN], &remote_pk[BT_PUB_KEY_COORD_LEN], + BT_PUB_KEY_COORD_LEN); if (bt_dh_key_gen(remote_pk_le, prov_dh_key_cb)) { BT_ERR("Failed to generate DHKey"); @@ -328,7 +329,7 @@ static void prov_dh_key_gen(void) static void prov_pub_key(const uint8_t *data) { - BT_DBG("Remote Public Key: %s", bt_hex(data, 64)); + BT_DBG("Remote Public Key: %s", bt_hex(data, BT_PUB_KEY_LEN)); /* PublicKeyProvisioner */ memcpy(bt_mesh_prov_link.conf_inputs.pub_key_provisioner, data, PDU_LEN_PUB_KEY); diff --git a/nimble/host/mesh/src/provisioner.c b/nimble/host/mesh/src/provisioner.c index 54cc1f0d94..edc9bbe03f 100644 --- a/nimble/host/mesh/src/provisioner.c +++ b/nimble/host/mesh/src/provisioner.c @@ -343,13 +343,14 @@ static void send_pub_key(void) return; } - BT_DBG("Local Public Key: %s", bt_hex(key, 64)); + BT_DBG("Local Public Key: %s", bt_hex(key, BT_PUB_KEY_LEN)); bt_mesh_prov_buf_init(buf, PROV_PUB_KEY); /* Swap X and Y halves independently to big-endian */ - sys_memcpy_swap(net_buf_simple_add(buf, 32), key, 32); - sys_memcpy_swap(net_buf_simple_add(buf, 32), &key[32], 32); + sys_memcpy_swap(net_buf_simple_add(buf, BT_PUB_KEY_COORD_LEN), key, BT_PUB_KEY_COORD_LEN); + sys_memcpy_swap(net_buf_simple_add(buf, BT_PUB_KEY_COORD_LEN), &key[BT_PUB_KEY_COORD_LEN], + BT_PUB_KEY_COORD_LEN); /* PublicKeyProvisioner */ memcpy(bt_mesh_prov_link.conf_inputs.pub_key_provisioner, &buf->om_data[1], PDU_LEN_PUB_KEY); @@ -362,7 +363,7 @@ static void send_pub_key(void) bt_mesh_prov_link.expect = PROV_PUB_KEY; } -static void prov_dh_key_cb(const uint8_t dhkey[32]) +static void prov_dh_key_cb(const uint8_t dhkey[BT_DH_KEY_LEN]) { BT_DBG("%p", dhkey); @@ -372,9 +373,9 @@ static void prov_dh_key_cb(const uint8_t dhkey[32]) return; } - sys_memcpy_swap(bt_mesh_prov_link.dhkey, dhkey, 32); + sys_memcpy_swap(bt_mesh_prov_link.dhkey, dhkey, BT_DH_KEY_LEN); - BT_DBG("DHkey: %s", bt_hex(bt_mesh_prov_link.dhkey, 32)); + BT_DBG("DHkey: %s", bt_hex(bt_mesh_prov_link.dhkey, BT_DH_KEY_LEN)); if (atomic_test_bit(bt_mesh_prov_link.flags, WAIT_STRING) || atomic_test_bit(bt_mesh_prov_link.flags, WAIT_NUMBER) || @@ -388,7 +389,7 @@ static void prov_dh_key_cb(const uint8_t dhkey[32]) static void prov_dh_key_gen(void) { - uint8_t remote_pk_le[64]; + uint8_t remote_pk_le[BT_PUB_KEY_LEN]; const uint8_t *remote_pk; const uint8_t *local_pk; @@ -399,10 +400,11 @@ static void prov_dh_key_gen(void) * X and Y halves are swapped independently. The bt_dh_key_gen() * will also take care of validating the remote public key. */ - sys_memcpy_swap(remote_pk_le, remote_pk, 32); - sys_memcpy_swap(&remote_pk_le[32], &remote_pk[32], 32); + sys_memcpy_swap(remote_pk_le, remote_pk, BT_PUB_KEY_COORD_LEN); + sys_memcpy_swap(&remote_pk_le[BT_PUB_KEY_COORD_LEN], &remote_pk[BT_PUB_KEY_COORD_LEN], + BT_PUB_KEY_COORD_LEN); - if (!memcmp(local_pk, remote_pk, 64)) { + if (!memcmp(local_pk, remote_pk, BT_PUB_KEY_LEN)) { BT_ERR("Public keys are identical"); prov_fail(PROV_ERR_NVAL_FMT); return; @@ -420,12 +422,12 @@ static void prov_dh_key_gen(void) static void prov_pub_key(const uint8_t *data) { - BT_DBG("Remote Public Key: %s", bt_hex(data, 64)); + BT_DBG("Remote Public Key: %s", bt_hex(data, BT_PUB_KEY_LEN)); atomic_set_bit(bt_mesh_prov_link.flags, REMOTE_PUB_KEY); /* PublicKeyDevice */ - memcpy(bt_mesh_prov_link.conf_inputs.pub_key_device, data, 64); + memcpy(bt_mesh_prov_link.conf_inputs.pub_key_device, data, BT_PUB_KEY_LEN); bt_mesh_prov_link.bearer->clear_tx(); prov_dh_key_gen(); @@ -716,7 +718,7 @@ int bt_mesh_auth_method_set_none(void) return 0; } -int bt_mesh_prov_remote_pub_key_set(const uint8_t public_key[64]) +int bt_mesh_prov_remote_pub_key_set(const uint8_t public_key[BT_PUB_KEY_LEN]) { if (public_key == NULL) { return -EINVAL; From 00a5f55713f095a2fc3e871ac51294410eaf171d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 12:32:04 +0200 Subject: [PATCH 0129/1333] host/mesh: Fixes Same appkey add to multi netkey The latest MESH.TS 1.0.1.2 4.15.10 Appkey List Procedures MESH/NODE/CFG/AKL/BI-04-C Verify that the IUT can respond to an Config AppKey Add message with NetKeyIndex and AppKeyIndex already stored. 6. Repeat step 1 with the same AppKey, the same AppKeyIndex, but NetKeyIndex field set to 0x001. 7. The Lower Tester expects the IUT to respond with an Config AppKey Status message with the Status field set to 0x04 (Invalid NetKey) and the NetKeyIndex and AppKeyIndex values equal to those sent in step 5. This is port of 6bf35fa7491f3240e7097dc735392cb12df4bf7c --- nimble/host/mesh/src/app_keys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/app_keys.c b/nimble/host/mesh/src/app_keys.c index 4a0aebc062..e13245af8a 100644 --- a/nimble/host/mesh/src/app_keys.c +++ b/nimble/host/mesh/src/app_keys.c @@ -291,7 +291,7 @@ uint8_t bt_mesh_app_key_add(uint16_t app_idx, uint16_t net_idx, if (app->app_idx == app_idx) { if (app->net_idx != net_idx) { - return STATUS_INVALID_BINDING; + return STATUS_INVALID_NETKEY; } if (memcmp(key, app->keys[0].val, 16)) { From f4dfb41f500a66b86ee83ea4ec3a74cb6ec75cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 12:37:53 +0200 Subject: [PATCH 0130/1333] host/mesh: Clarify name length in bt_mesh_model_data_store Name length can't be longer than 8 bytes. This needs to be clarified in the bt_mesh_model_data_store() documentation. This is port of 538f97f73711c73f8a6e6478d461978e3cf2c295 --- nimble/host/mesh/include/mesh/access.h | 12 +++++++----- nimble/host/mesh/include/mesh/glue.h | 2 ++ nimble/host/mesh/src/access.c | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/nimble/host/mesh/include/mesh/access.h b/nimble/host/mesh/include/mesh/access.h index 6c7c542690..f552b584c2 100644 --- a/nimble/host/mesh/include/mesh/access.h +++ b/nimble/host/mesh/include/mesh/access.h @@ -564,16 +564,18 @@ static inline bool bt_mesh_model_in_primary(const struct bt_mesh_model *mod) /** @brief Immediately store the model's user data in persistent storage. * - * @param mod Mesh model. - * @param vnd This is a vendor model. - * @param name Name/key of the settings item. - * @param data Model data to store, or NULL to delete any model data. + * @param mod Mesh model. + * @param vnd This is a vendor model. + * @param name Name/key of the settings item. Only + * @ref SETTINGS_MAX_DIR_DEPTH bytes will be used at most. + * @param data Model data to store, or NULL to delete any model data. * @param data_len Length of the model data. * * @return 0 on success, or (negative) error code on failure. */ int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, - const char *name, const void *data, size_t data_len); + const char *name, const void *data, + size_t data_len); /** @brief Let a model extend another. * diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index 944402f725..a54bdbff35 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -51,6 +51,8 @@ extern "C" { #endif +#define SETTINGS_MAX_DIR_DEPTH 8 /* max depth of settings tree */ + /** Key size used in Bluetooth's ECC domain. */ #define BT_ECC_KEY_SIZE 32 /** Length of a Bluetooth ECC public key coordinate. */ diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index f528e4878a..95af908d77 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -1226,7 +1226,7 @@ int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, encode_mod_path(mod, vnd, "data", path, sizeof(path)); if (name) { strcat(path, "/"); - strncat(path, name, 8); + strncat(path, name, SETTINGS_MAX_DIR_DEPTH); } if (data_len) { From a88ee9256edca0a4e14fc2346ba99b4213122520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 12:42:17 +0200 Subject: [PATCH 0131/1333] host/mesh: Add API to discard subscription in vendor model This commit adds missing API that allows to discard the Subscription List of a vendor model. This is port of 0e9d66897062b0de41a0522b5a836e2ec5b008bc --- nimble/host/mesh/include/mesh/cfg_cli.h | 4 ++ nimble/host/mesh/src/cfg_cli.c | 74 +++++++++++-------------- 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/nimble/host/mesh/include/mesh/cfg_cli.h b/nimble/host/mesh/include/mesh/cfg_cli.h index 0bf7cdd70d..86716f3162 100644 --- a/nimble/host/mesh/include/mesh/cfg_cli.h +++ b/nimble/host/mesh/include/mesh/cfg_cli.h @@ -273,6 +273,10 @@ int bt_mesh_cfg_mod_sub_del_all(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t mod_id, uint8_t *status); +int bt_mesh_cfg_mod_sub_del_all_vnd(uint16_t net_idx, uint16_t addr, + uint16_t elem_addr, uint16_t mod_id, + uint16_t cid, uint8_t *status); + int bt_mesh_cfg_net_key_update(uint16_t net_idx, uint16_t addr, uint16_t key_net_idx, const uint8_t net_key[16], uint8_t *status); diff --git a/nimble/host/mesh/src/cfg_cli.c b/nimble/host/mesh/src/cfg_cli.c index f0f2ba8426..d8d335fe3d 100644 --- a/nimble/host/mesh/src/cfg_cli.c +++ b/nimble/host/mesh/src/cfg_cli.c @@ -1877,7 +1877,10 @@ static int mod_sub(uint32_t op, uint16_t net_idx, uint16_t addr, uint16_t elem_a bt_mesh_model_msg_init(msg, op); net_buf_simple_add_le16(msg, elem_addr); - net_buf_simple_add_le16(msg, sub_addr); + + if (sub_addr != BT_MESH_ADDR_UNASSIGNED) { + net_buf_simple_add_le16(msg, sub_addr); + } if (cid != CID_NVAL) { net_buf_simple_add_le16(msg, cid); @@ -1907,6 +1910,10 @@ static int mod_sub(uint32_t op, uint16_t net_idx, uint16_t addr, uint16_t elem_a int bt_mesh_cfg_mod_sub_add(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t sub_addr, uint16_t mod_id, uint8_t *status) { + if (!BT_MESH_ADDR_IS_GROUP(sub_addr)) { + return -EINVAL; + } + return mod_sub(OP_MOD_SUB_ADD, net_idx, addr, elem_addr, sub_addr, mod_id, CID_NVAL, status); } @@ -1915,7 +1922,7 @@ int bt_mesh_cfg_mod_sub_add_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_a uint16_t sub_addr, uint16_t mod_id, uint16_t cid, uint8_t *status) { - if (cid == CID_NVAL) { + if (!BT_MESH_ADDR_IS_GROUP(sub_addr) || cid == CID_NVAL) { return -EINVAL; } @@ -1926,6 +1933,10 @@ int bt_mesh_cfg_mod_sub_add_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_a int bt_mesh_cfg_mod_sub_del(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t sub_addr, uint16_t mod_id, uint8_t *status) { + if (!BT_MESH_ADDR_IS_GROUP(sub_addr)) { + return -EINVAL; + } + return mod_sub(OP_MOD_SUB_DEL, net_idx, addr, elem_addr, sub_addr, mod_id, CID_NVAL, status); } @@ -1934,50 +1945,15 @@ int bt_mesh_cfg_mod_sub_del_all(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t mod_id, uint8_t *status) { - struct os_mbuf *msg = BT_MESH_MODEL_BUF(OP_MOD_SUB_DEL_ALL, 6); - struct bt_mesh_msg_ctx ctx = { - .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV_REMOTE, - .addr = addr, - .send_ttl = BT_MESH_TTL_DEFAULT, - }; - struct mod_sub_param param = { - .status = status, - .elem_addr = elem_addr, - .mod_id = mod_id, - .cid = CID_NVAL, - }; - int err; - - err = cli_prepare(¶m, OP_MOD_SUB_STATUS, addr); - if (err) { - return err; - } - - bt_mesh_model_msg_init(msg, OP_MOD_SUB_DEL_ALL); - net_buf_simple_add_le16(msg, elem_addr); - net_buf_simple_add_le16(msg, mod_id); - - err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); - if (err) { - BT_ERR("model_send() failed (err %d)", err); - bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); - return err; - } - - if (!status) { - bt_mesh_msg_ack_ctx_clear(&cli->ack_ctx); - return 0; - } - - return bt_mesh_msg_ack_ctx_wait(&cli->ack_ctx, K_MSEC(msg_timeout)); + return mod_sub(OP_MOD_SUB_DEL_ALL, net_idx, addr, elem_addr, + BT_MESH_ADDR_UNASSIGNED, mod_id, CID_NVAL, status); } int bt_mesh_cfg_mod_sub_del_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t sub_addr, uint16_t mod_id, uint16_t cid, uint8_t *status) { - if (cid == CID_NVAL) { + if (!BT_MESH_ADDR_IS_GROUP(sub_addr) || cid == CID_NVAL) { return -EINVAL; } @@ -1985,9 +1961,25 @@ int bt_mesh_cfg_mod_sub_del_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_a mod_id, cid, status); } +int bt_mesh_cfg_mod_sub_del_all_vnd(uint16_t net_idx, uint16_t addr, + uint16_t elem_addr, uint16_t mod_id, + uint16_t cid, uint8_t *status) +{ + if (cid == CID_NVAL) { + return -EINVAL; + } + + return mod_sub(OP_MOD_SUB_DEL_ALL, net_idx, addr, elem_addr, + BT_MESH_ADDR_UNASSIGNED, mod_id, cid, status); +} + int bt_mesh_cfg_mod_sub_overwrite(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t sub_addr, uint16_t mod_id, uint8_t *status) { + if (!BT_MESH_ADDR_IS_GROUP(sub_addr)) { + return -EINVAL; + } + return mod_sub(OP_MOD_SUB_OVERWRITE, net_idx, addr, elem_addr, sub_addr, mod_id, CID_NVAL, status); } @@ -1996,7 +1988,7 @@ int bt_mesh_cfg_mod_sub_overwrite_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t sub_addr, uint16_t mod_id, uint16_t cid, uint8_t *status) { - if (cid == CID_NVAL) { + if (!BT_MESH_ADDR_IS_GROUP(sub_addr) || cid == CID_NVAL) { return -EINVAL; } From 1942a4ea3289518bd374cb068e0e8b3e19ca72cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 12:44:36 +0200 Subject: [PATCH 0132/1333] host/mesh: Fix IVU duration counter update When device is first provisioned with IV Update flag is set to 0, it should wait for minimum of 96 hours before going into IV Update In Progress state. Such limit does not apply, if device is provisioned with IV Update flag is set to 1. This is port of f868ca3497227c290a8bfea1c64130eb26dcb287 --- nimble/host/mesh/src/mesh.c | 1 + nimble/host/mesh/src/net.c | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c index 3dfba16763..0d9c21e668 100644 --- a/nimble/host/mesh/src/mesh.c +++ b/nimble/host/mesh/src/mesh.c @@ -164,6 +164,7 @@ void bt_mesh_reset(void) } bt_mesh.iv_index = 0U; + bt_mesh.ivu_duration = 0; bt_mesh.seq = 0U; memset(bt_mesh.flags, 0, sizeof(bt_mesh.flags)); diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index 62fcc41e33..50f36a3e3a 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -184,11 +184,13 @@ int bt_mesh_net_create(uint16_t idx, uint8_t flags, const uint8_t key[16], atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS, BT_MESH_IV_UPDATE(flags)); - /* Set minimum required hours, since the 96-hour minimum requirement - * doesn't apply straight after provisioning (since we can't know how - * long has actually passed since the network changed its state). + /* If IV Update is already in progress, set minimum required hours, + * since the 96-hour minimum requirement doesn't apply in this case straight + * after provisioning. */ - bt_mesh.ivu_duration = BT_MESH_IVU_MIN_HOURS; + if (BT_MESH_IV_UPDATE(flags)) { + bt_mesh.ivu_duration = BT_MESH_IVU_MIN_HOURS; + } if (IS_ENABLED(CONFIG_BT_SETTINGS)) { BT_DBG("Storing network information persistently"); From 83e1654263e20e60f71315d335877ac6fcec7c1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 13:20:52 +0200 Subject: [PATCH 0133/1333] host/mesh: Use separate net_bufs for bt_mesh_app_decrypt in friend unseg_app_sdu_decrypt decrypts messages in place using a single net_buf. While this is safe in terms of data access, the buffer state is manipulated with the assumption that they're two different buffers, and the output buffer's length field is increased at the end. When assertions are enabled and the pdu length is 11 or 12 bytes, this triggers the net_buf length assert, as the decrypt function attempts to add the pdu length to the out buffer, with the assumption that it was reset before decryption was started. Create a separate output buffer with len = 0 to avoid triggering the assert. Improve readability of the unseg_app_sdu functions to highlight the need for the additional buffer. This is port of 69fcaaa5927e475e5749bf4a1e035ad18de0f796 --- nimble/host/mesh/include/mesh/glue.h | 2 ++ nimble/host/mesh/src/friend.c | 21 ++++++++++++++------- nimble/host/mesh/src/glue.c | 8 ++++++++ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index a54bdbff35..1e7f842202 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -373,6 +373,8 @@ static inline void net_buf_simple_save(struct os_mbuf *buf, state->len = buf->om_len; } +void net_buf_simple_clone(const struct os_mbuf *original, struct os_mbuf *clone); + static inline void net_buf_simple_restore(struct os_mbuf *buf, struct net_buf_simple_state *state) { diff --git a/nimble/host/mesh/src/friend.c b/nimble/host/mesh/src/friend.c index 685e26f54c..e614e74974 100644 --- a/nimble/host/mesh/src/friend.c +++ b/nimble/host/mesh/src/friend.c @@ -390,15 +390,21 @@ static int unseg_app_sdu_decrypt(struct bt_mesh_friend *frnd, const struct unseg_app_sdu_meta *meta) { struct net_buf_simple_state state; + struct os_mbuf *in = NET_BUF_SIMPLE(BT_MESH_RX_SDU_MAX); + struct os_mbuf *out = NET_BUF_SIMPLE(BT_MESH_RX_SDU_MAX); int err; - BT_DBG(""); - net_buf_simple_save(buf, &state); - net_buf_simple_pull_mem(buf, 10); - buf->om_len -= 4; + /* Direct the input buffer at the Upper Transport Access PDU, accounting for + * the network header and the 1 byte lower transport header + */ + net_buf_simple_clone(buf, in); + net_buf_simple_pull(buf, BT_MESH_NET_HDR_LEN); + net_buf_simple_pull(buf, 1); + in->om_len -= BT_MESH_MIC_SHORT;; - err = bt_mesh_app_decrypt(meta->key, &meta->crypto, buf, buf); + net_buf_simple_clone(in, out); + err = bt_mesh_app_decrypt(meta->key, &meta->crypto, in, out); net_buf_simple_restore(buf, &state); net_buf_unref(buf); @@ -415,8 +421,9 @@ static int unseg_app_sdu_encrypt(struct bt_mesh_friend *frnd, BT_DBG(""); net_buf_simple_save(buf, &state); - net_buf_simple_pull_mem(buf, 10); - buf->om_len -= 4; + net_buf_simple_pull_mem(buf, BT_MESH_NET_HDR_LEN); + net_buf_simple_pull_mem(buf, 1); + buf->om_len -= BT_MESH_MIC_SHORT; err = bt_mesh_app_encrypt(meta->key, &meta->crypto, buf); diff --git a/nimble/host/mesh/src/glue.c b/nimble/host/mesh/src/glue.c index e79c43b284..4e4715f2f0 100644 --- a/nimble/host/mesh/src/glue.c +++ b/nimble/host/mesh/src/glue.c @@ -112,6 +112,14 @@ net_buf_unref(struct os_mbuf *om) os_mbuf_free_chain(om); } + +void net_buf_simple_clone(const struct os_mbuf *original, + struct os_mbuf *clone) +{ + memcpy(clone, original, sizeof(struct os_mbuf)); +} + + int bt_encrypt_be(const uint8_t *key, const uint8_t *plaintext, uint8_t *enc_data) { From 344e1c269f1805ac3fd0a873e12910854a15860a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 13:26:16 +0200 Subject: [PATCH 0134/1333] host/mesh: Verify that all stored mesh entries removed This ensures that all mesh settings were removed from persistent storage after node reset. This is port of cd294c12c3ea604cc706c22414f798a7eafac859 --- nimble/host/mesh/src/net.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index 50f36a3e3a..521a9859ed 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -1161,20 +1161,29 @@ void bt_mesh_net_pending_seq_store(void) struct seq_val seq; int err; - sys_put_le24(bt_mesh.seq, seq.val); + if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { + sys_put_le24(bt_mesh.seq, seq.val); - str = settings_str_from_bytes(&seq, sizeof(seq), buf, sizeof(buf)); - if (!str) { - BT_ERR("Unable to encode Network as value"); - return; - } + str = settings_str_from_bytes(&seq, sizeof(seq), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode Network as value"); + return; + } - BT_DBG("Saving Network as value %s", str); - err = settings_save_one("bt_mesh/Seq", str); - if (err) { - BT_ERR("Failed to stor Seq value"); + BT_DBG("Saving Network as value %s", str); + err = settings_save_one("bt_mesh/Seq", str); + if (err) { + BT_ERR("Failed to stor Seq value"); + } else { + BT_DBG("Stored Seq value"); + } } else { - BT_DBG("Stored Seq value"); + err = settings_save_one("bt_mesh/Seq", NULL); + if (err) { + BT_ERR("Failed to clear Seq value"); + } else { + BT_DBG("Cleared Seq value"); + } } } @@ -1183,6 +1192,7 @@ void bt_mesh_net_clear(void) bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_NET_PENDING); bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_IV_PENDING); bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_SEQ_PENDING); } void bt_mesh_net_settings_commit(void) From 0904bcb6f2f6e66b30154616b86e930c9f6aba55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 13:30:21 +0200 Subject: [PATCH 0135/1333] host/mesh: Remove krp param check param can never be NULL, so this check is redundant. Coverity complains about this, as the param variable is accessed before the check, which would be wrong if param could be NULL. This is port of fd6f51c4104e02f16c23ca1eee3ab747ab7143ef --- nimble/host/mesh/src/cfg_cli.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/nimble/host/mesh/src/cfg_cli.c b/nimble/host/mesh/src/cfg_cli.c index d8d335fe3d..3560052b4c 100644 --- a/nimble/host/mesh/src/cfg_cli.c +++ b/nimble/host/mesh/src/cfg_cli.c @@ -134,8 +134,7 @@ static int krp_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, bt_hex(buf->om_data, buf->om_len)); - if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_KRP_STATUS, ctx->addr, - (void **)¶m)) { + if (!bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_KRP_STATUS, ctx->addr, (void **)¶m)) { return -ENOENT; } @@ -147,11 +146,11 @@ static int krp_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, return -ENOENT; } - if (param && param->status) { + if (param->status) { *param->status = status; } - if (param && param->phase) { + if (param->phase) { *param->phase = phase; } From 7f54ce9d01a637063eda19cb2c9f48fbea088dd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 13:31:33 +0200 Subject: [PATCH 0136/1333] host/mesh: Remove lpn timeout param check param can never be NULL here, so the check is redundant. Coverity is complaining because param is accessed before the NULL check. This is port of 4eb047d1afdbb159527b821552be6d79e84fb1e4 --- nimble/host/mesh/src/cfg_cli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/cfg_cli.c b/nimble/host/mesh/src/cfg_cli.c index 3560052b4c..773bafa709 100644 --- a/nimble/host/mesh/src/cfg_cli.c +++ b/nimble/host/mesh/src/cfg_cli.c @@ -863,7 +863,7 @@ static int lpn_timeout_status(struct bt_mesh_model *model, struct bt_mesh_msg_ct return -ENOENT; } - if (param && param->polltimeout) { + if (param->polltimeout) { *param->polltimeout = polltimeout; } From fea8bf015e2275e8cacef160bb7a828a02b284d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 13:32:39 +0200 Subject: [PATCH 0137/1333] host/mesh: Initialize UUID in shell's mod_pub_set PR #35774 introduced a uuid field in the bt_mesh_cfg_mod_pub structure. The shell does not initialize this pointer before passing it to the access layer. Add a line to initialize this pointer. This is port of c5757ca4a104c8207cfa6244c4a128cef2bda9b5 --- nimble/host/mesh/src/shell.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/host/mesh/src/shell.c b/nimble/host/mesh/src/shell.c index b0a1b4d2a1..95b1907f79 100644 --- a/nimble/host/mesh/src/shell.c +++ b/nimble/host/mesh/src/shell.c @@ -2002,6 +2002,7 @@ static int mod_pub_set(uint16_t addr, uint16_t mod_id, uint16_t cid, char *argv[ int err; pub.addr = strtoul(argv[0], NULL, 0); + pub.uuid = NULL; pub.app_idx = strtoul(argv[1], NULL, 0); pub.cred_flag = str2bool(argv[2]); pub.ttl = strtoul(argv[3], NULL, 0); From 6b22633683a132773ae120992fffd81f5066473e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 13:38:38 +0200 Subject: [PATCH 0138/1333] host/mesh: Fail provisioning when RFU values are used When Public Key field is set to RFU value then we should send Provisioning Fail with Invalid Format error. This is port of f51cf9ab869b194f040435fa171f0e9b4f33de98 --- nimble/host/mesh/src/prov_device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nimble/host/mesh/src/prov_device.c b/nimble/host/mesh/src/prov_device.c index 1562860c5e..ab387c3681 100644 --- a/nimble/host/mesh/src/prov_device.c +++ b/nimble/host/mesh/src/prov_device.c @@ -119,9 +119,9 @@ static void prov_start(const uint8_t *data) return; } - if (data[1] == PUB_KEY_OOB && - !(MYNEWT_VAL(BLE_MESH_PROV_OOB_PUBLIC_KEY) && - bt_mesh_prov->public_key_be)) { + if (data[1] > PUB_KEY_OOB || + (data[1] == PUB_KEY_OOB && + (!MYNEWT_VAL(BLE_MESH_PROV_OOB_PUBLIC_KEY) || !bt_mesh_prov->public_key_be))) { BT_ERR("Invalid public key type: 0x%02x", data[1]); prov_fail(PROV_ERR_NVAL_FMT); return; From 3d2eb2677cd4f1634902b62f0652d53792c9c707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 14:11:37 +0200 Subject: [PATCH 0139/1333] host/mesh: Fix friend buf send end not called. As frnd->last will keep reference, so that net buffer destructor function will not be call. This is port of ecc7ca1b698bd2d3b7f043c945980b909cc3e4a7 --- nimble/host/mesh/src/friend.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/nimble/host/mesh/src/friend.c b/nimble/host/mesh/src/friend.c index e614e74974..dc7d78425f 100644 --- a/nimble/host/mesh/src/friend.c +++ b/nimble/host/mesh/src/friend.c @@ -42,8 +42,6 @@ static struct os_mempool friend_buf_mempool; #define NET_BUF_FRAGS BIT(0) -#define FRIEND_ADV(buf) CONTAINER_OF(BT_MESH_ADV(buf), struct friend_adv, adv) - /* PDUs from Friend to the LPN should only be transmitted once with the * smallest possible interval (20ms). */ @@ -62,14 +60,15 @@ struct friend_pdu_info { }; static struct friend_adv { - struct bt_mesh_adv adv; uint16_t app_idx; } adv_pool[FRIEND_BUF_COUNT]; -static struct bt_mesh_adv *adv_alloc(int id) +#define FRIEND_ADV(buf) (*(struct friend_adv **)net_buf_user_data(buf)) + +static struct friend_adv *adv_alloc(int id) { adv_pool[id].app_idx = BT_MESH_KEY_UNUSED; - return &adv_pool[id].adv; + return &adv_pool[id]; } static bool friend_is_allocated(const struct bt_mesh_friend *frnd) @@ -161,11 +160,6 @@ static void friend_clear(struct bt_mesh_friend *frnd) memset(frnd->cred, 0, sizeof(frnd->cred)); if (frnd->last) { - /* Cancel the sending if necessary */ - if (frnd->pending_buf) { - BT_MESH_ADV(frnd->last)->busy = 0; - } - net_buf_unref(frnd->last); frnd->last = NULL; } @@ -314,13 +308,13 @@ static struct os_mbuf *create_friend_pdu(struct bt_mesh_friend *frnd, { struct os_mbuf *buf; - buf = bt_mesh_adv_create_from_pool(&friend_os_mbuf_pool, adv_alloc, - BT_MESH_ADV_DATA, - FRIEND_XMIT, K_NO_WAIT); + buf = os_mbuf_get_pkthdr(&friend_os_mbuf_pool, BT_MESH_ADV_USER_DATA_SIZE); if (!buf) { return NULL; } + FRIEND_ADV(buf) = adv_alloc(net_buf_id(buf)); + net_buf_add_u8(buf, (info->iv_index & 1) << 7); /* Will be reset in encryption */ if (info->ctl) { @@ -1222,7 +1216,7 @@ static void friend_timeout(struct ble_npl_event *work) .start = buf_send_start, .end = buf_send_end, }; - + struct os_mbuf *buf; uint8_t md; if (!friend_is_allocated(frnd)) { @@ -1271,9 +1265,17 @@ static void friend_timeout(struct ble_npl_event *work) frnd->queue_size--; send_last: + buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, FRIEND_XMIT, K_NO_WAIT); + if (!buf) { + BT_ERR("Unable to allocate friend adv buffer"); + return; + } + + net_buf_add_mem(buf, frnd->last->om_data, frnd->last->om_len); frnd->pending_req = 0; frnd->pending_buf = 1; - bt_mesh_adv_send(frnd->last, &buf_sent_cb, frnd); + bt_mesh_adv_send(buf, &buf_sent_cb, frnd); + net_buf_unref(buf); } static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt) From c3ec6128e05b174009c4e29dbbbb2ffd9ff5e524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 14:17:12 +0200 Subject: [PATCH 0140/1333] host/mesh: Check if app key is bound in Model Publication Set Th Configuration Server should respond with and Invalid AppKey Index status code when the AppKey identified by AppKeyIndex is not known to the node or is not bound to the model identified by the ModelIdentifier. This is port of 343c0bd2d38e70bb627f5dff3db8a37360f112f9 --- nimble/host/mesh/src/access.c | 6 +++--- nimble/host/mesh/src/access.h | 1 + nimble/host/mesh/src/cfg_srv.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index 95af908d77..33169a7501 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -552,7 +552,7 @@ uint8_t bt_mesh_elem_count(void) return dev_comp->elem_count; } -static bool model_has_key(struct bt_mesh_model *mod, uint16_t key) +bool bt_mesh_model_has_key(struct bt_mesh_model *mod, uint16_t key) { int i; @@ -692,7 +692,7 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) continue; } - if (!model_has_key(model, rx->ctx.app_idx)) { + if (!bt_mesh_model_has_key(model, rx->ctx.app_idx)) { continue; } @@ -727,7 +727,7 @@ int bt_mesh_model_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *msg, const struct bt_mesh_send_cb *cb, void *cb_data) { - if (!model_has_key(model, ctx->app_idx)) { + if (!bt_mesh_model_has_key(model, ctx->app_idx)) { BT_ERR("Model not bound to AppKey 0x%04x", ctx->app_idx); return -EINVAL; } diff --git a/nimble/host/mesh/src/access.h b/nimble/host/mesh/src/access.h index 34ac248792..217f4abe0f 100644 --- a/nimble/host/mesh/src/access.h +++ b/nimble/host/mesh/src/access.h @@ -25,6 +25,7 @@ uint8_t bt_mesh_elem_count(void); struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr); bool bt_mesh_has_addr(uint16_t addr); +bool bt_mesh_model_has_key(struct bt_mesh_model *mod, uint16_t key); void bt_mesh_model_extensions_walk(struct bt_mesh_model *root, enum bt_mesh_walk (*cb)(struct bt_mesh_model *mod, diff --git a/nimble/host/mesh/src/cfg_srv.c b/nimble/host/mesh/src/cfg_srv.c index 11a1e4dffc..2af24370e3 100644 --- a/nimble/host/mesh/src/cfg_srv.c +++ b/nimble/host/mesh/src/cfg_srv.c @@ -216,7 +216,7 @@ static uint8_t _mod_pub_set(struct bt_mesh_model *model, uint16_t pub_addr, return STATUS_SUCCESS; } - if (!bt_mesh_app_key_exists(app_idx)) { + if (!bt_mesh_app_key_exists(app_idx) || !bt_mesh_model_has_key(model, app_idx)) { return STATUS_INVALID_APPKEY; } From 0d6e6c4040ae4460f0ae9852ee4c26b5fb24570c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 14:19:22 +0200 Subject: [PATCH 0141/1333] host/mesh: Verify if Remote confirmation is not identical MESH/PVNR/PROV/BI-18-C verifies that the IUT rejects invalid Confirmation Value. This is port of 88b60f31c74aa2a35d4869bc4ec463c52fc1f451 --- nimble/host/mesh/src/prov.h | 2 +- nimble/host/mesh/src/provisioner.c | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/nimble/host/mesh/src/prov.h b/nimble/host/mesh/src/prov.h index 9202275fbd..b287fb2a00 100644 --- a/nimble/host/mesh/src/prov.h +++ b/nimble/host/mesh/src/prov.h @@ -119,7 +119,7 @@ struct bt_mesh_prov_link { uint8_t dhkey[BT_DH_KEY_LEN]; /* Calculated DHKey */ uint8_t expect; /* Next expected PDU */ - uint8_t conf[16]; /* Remote Confirmation */ + uint8_t conf[16]; /* Local/Remote Confirmation */ uint8_t rand[16]; /* Local Random */ uint8_t conf_salt[16]; /* ConfirmationSalt */ diff --git a/nimble/host/mesh/src/provisioner.c b/nimble/host/mesh/src/provisioner.c index edc9bbe03f..e5cb22ffaa 100644 --- a/nimble/host/mesh/src/provisioner.c +++ b/nimble/host/mesh/src/provisioner.c @@ -306,12 +306,14 @@ static void send_confirm(void) if (bt_mesh_prov_conf(bt_mesh_prov_link.conf_key, bt_mesh_prov_link.rand, bt_mesh_prov_link.auth, - net_buf_simple_add(cfm, 16))) { + bt_mesh_prov_link.conf)) { BT_ERR("Unable to generate confirmation value"); prov_fail(PROV_ERR_UNEXP_ERR); return; } + net_buf_simple_add_mem(cfm, bt_mesh_prov_link.conf, 16); + if (bt_mesh_prov_send(cfm, NULL)) { BT_ERR("Failed to send Provisioning Confirm"); return; @@ -625,6 +627,12 @@ static void prov_confirm(const uint8_t *data) { BT_DBG("Remote Confirm: %s", bt_hex(data, 16)); + if (!memcmp(data, bt_mesh_prov_link.conf, 16)) { + BT_ERR("Confirm value is identical to ours, rejecting."); + prov_fail(PROV_ERR_CFM_FAILED); + return; + } + memcpy(bt_mesh_prov_link.conf, data, 16); send_random(); From c1b087a4c5ecae8195827771b3d482510858ea47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 14:23:28 +0200 Subject: [PATCH 0142/1333] host/mesh: Inclusive terminology Implements the Bluetooth appropriate language mapping for the Bluetooth mesh subsystem. Changes the following terms: - Master security credentials -> Flooding security credentials - Whitelist filter -> Accept filter - Blacklist filter -> Reject filter - Removes CDB's NODE_BLACKLISTED, which was not in use. This is port of 035d877967cbaa43d8d8d73344450a1a9ed5d1f8 --- nimble/host/mesh/include/mesh/cdb.h | 1 - nimble/host/mesh/src/friend.c | 4 ++-- nimble/host/mesh/src/gatt_services.c | 26 +++++++++++++------------- nimble/host/mesh/src/lpn.c | 2 +- nimble/host/mesh/src/net.c | 2 +- 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/nimble/host/mesh/include/mesh/cdb.h b/nimble/host/mesh/include/mesh/cdb.h index 440390cd62..444fb5d295 100644 --- a/nimble/host/mesh/include/mesh/cdb.h +++ b/nimble/host/mesh/include/mesh/cdb.h @@ -22,7 +22,6 @@ enum { BT_MESH_CDB_NODE_CONFIGURED, - BT_MESH_CDB_NODE_BLACKLISTED, BT_MESH_CDB_NODE_FLAG_COUNT }; diff --git a/nimble/host/mesh/src/friend.c b/nimble/host/mesh/src/friend.c index dc7d78425f..475fbd54e4 100644 --- a/nimble/host/mesh/src/friend.c +++ b/nimble/host/mesh/src/friend.c @@ -474,14 +474,14 @@ static int unseg_app_sdu_prepare(struct bt_mesh_friend *frnd, } static int encrypt_friend_pdu(struct bt_mesh_friend *frnd, struct os_mbuf *buf, - bool master_cred) + bool flooding_cred) { const struct bt_mesh_net_cred *cred; uint32_t iv_index; uint16_t src; int err; - if (master_cred) { + if (flooding_cred) { cred = &frnd->subnet->keys[SUBNET_KEY_TX_IDX(frnd->subnet)] .msg; } else { diff --git a/nimble/host/mesh/src/gatt_services.c b/nimble/host/mesh/src/gatt_services.c index b74e596fe5..40b2165c76 100644 --- a/nimble/host/mesh/src/gatt_services.c +++ b/nimble/host/mesh/src/gatt_services.c @@ -134,8 +134,8 @@ static struct bt_mesh_proxy_client { uint16_t filter[MYNEWT_VAL(BLE_MESH_PROXY_FILTER_SIZE)]; enum __packed { NONE, - WHITELIST, - BLACKLIST, + ACCEPT, + REJECT, PROV, } filter_type; #if MYNEWT_VAL(BLE_MESH_GATT_PROXY) @@ -226,11 +226,11 @@ static int filter_set(struct bt_mesh_proxy_client *client, switch (type) { case 0x00: (void)memset(client->filter, 0, sizeof(client->filter)); - client->filter_type = WHITELIST; + client->filter_type = ACCEPT; break; case 0x01: (void)memset(client->filter, 0, sizeof(client->filter)); - client->filter_type = BLACKLIST; + client->filter_type = REJECT; break; default: BT_WARN("Prohibited Filter Type 0x%02x", type); @@ -301,7 +301,7 @@ static void send_filter_status(struct bt_mesh_proxy_client *client, net_buf_simple_add_u8(buf, CFG_FILTER_STATUS); - if (client->filter_type == WHITELIST) { + if (client->filter_type == ACCEPT) { net_buf_simple_add_u8(buf, 0x00); } else { net_buf_simple_add_u8(buf, 0x01); @@ -707,7 +707,7 @@ static void proxy_ccc_write(uint16_t conn_handle) __ASSERT(client, "No client for connection"); if (client->filter_type == NONE) { - client->filter_type = WHITELIST; + client->filter_type = ACCEPT; k_work_add_arg(&client->send_beacons, client); k_work_submit(&client->send_beacons); } @@ -739,7 +739,7 @@ int bt_mesh_proxy_gatt_enable(void) for (i = 0; i < ARRAY_SIZE(clients); i++) { if (clients[i].cli.conn_handle != BLE_HS_CONN_HANDLE_NONE) { - clients[i].filter_type = WHITELIST; + clients[i].filter_type = ACCEPT; } } return 0; @@ -756,8 +756,8 @@ void bt_mesh_proxy_gatt_disconnect(void) struct bt_mesh_proxy_client *client = &clients[i]; if ((client->cli.conn_handle != BLE_HS_CONN_HANDLE_NONE) && - (client->filter_type == WHITELIST || - client->filter_type == BLACKLIST)) { + (client->filter_type == ACCEPT || + client->filter_type == REJECT)) { client->filter_type = NONE; rc = ble_gap_terminate(client->cli.conn_handle, BLE_ERR_REM_USER_CONN_TERM); @@ -799,9 +799,9 @@ void bt_mesh_proxy_addr_add(struct os_mbuf *buf, uint16_t addr) BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr); - if (client->filter_type == WHITELIST) { + if (client->filter_type == ACCEPT) { filter_add(client, addr); - } else if (client->filter_type == BLACKLIST) { + } else if (client->filter_type == REJECT) { filter_remove(client, addr); } } @@ -813,7 +813,7 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client, BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr); - if (client->filter_type == BLACKLIST) { + if (client->filter_type == REJECT) { for (i = 0; i < ARRAY_SIZE(client->filter); i++) { if (client->filter[i] == addr) { return false; @@ -827,7 +827,7 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client, return true; } - if (client->filter_type == WHITELIST) { + if (client->filter_type == ACCEPT) { for (i = 0; i < ARRAY_SIZE(client->filter); i++) { if (client->filter[i] == addr) { return true; diff --git a/nimble/host/mesh/src/lpn.c b/nimble/host/mesh/src/lpn.c index ad6cfe4d25..1d2f229e6b 100644 --- a/nimble/host/mesh/src/lpn.c +++ b/nimble/host/mesh/src/lpn.c @@ -980,7 +980,7 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx, if (!lpn->established) { /* This is normally checked on the transport layer, however - * in this state we're also still accepting master + * in this state we're also still accepting flooding * credentials so we need to ensure the right ones (Friend * Credentials) were used for this message. */ diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index 521a9859ed..e5391bf21c 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -704,7 +704,7 @@ static void bt_mesh_net_relay(struct os_mbuf *sbuf, bt_hex(buf->om_data, buf->om_len)); /* When the Friend node relays message for lpn, the message will be - * retransmitted using the managed master security credentials and + * retransmitted using the managed flooding security credentials and * the Network PDU shall be retransmitted to all network interfaces. */ if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && From 15c0ff03daab703eedf1fbb67c7a0d5325920d2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 14:28:41 +0200 Subject: [PATCH 0143/1333] host/mesh: Return ETIMEDOUT if k_sem_take call times out EAGAIN is used in some other places in the code, e.g. if node is not provisioned when a model tries to send a message. This change helps to differentiated if the acknowledged message timed out from other failers. This is port of e40998a4e48bd792843043bbcfa7849c9ce78358 --- nimble/host/mesh/src/msg.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/msg.c b/nimble/host/mesh/src/msg.c index 853a0f43dc..230a2ab434 100644 --- a/nimble/host/mesh/src/msg.c +++ b/nimble/host/mesh/src/msg.c @@ -65,9 +65,13 @@ int bt_mesh_msg_ack_ctx_wait(struct bt_mesh_msg_ack_ctx *ack, int32_t timeout) err = k_sem_take(&ack->sem, timeout); bt_mesh_msg_ack_ctx_clear(ack); - return err; + if (err == -EAGAIN) { + return -ETIMEDOUT; } + return err; +} + bool bt_mesh_msg_ack_ctx_match(const struct bt_mesh_msg_ack_ctx *ack, uint32_t op, uint16_t addr, void **user_data) { From 58c2a94ffb207ca33bb6a70e75359e530bd9d9a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 15:02:57 +0200 Subject: [PATCH 0144/1333] host/mesh: Refactoring provisioning to make all OOB auth working The current implementation has hidden dependencies that break OOB authentication if provisioner does not have the configured input or output fields used for device capabilities. It didn't allow to pass several OOB authentication cases. After refactoring provisioner behavior is independent to provisionee settings. This is port of 6f2516d9a7bdb4537d044f7776e524b3e95101d0 --- nimble/host/mesh/src/prov.c | 201 +++++++++++++++++++---------- nimble/host/mesh/src/prov.h | 4 +- nimble/host/mesh/src/prov_device.c | 5 +- nimble/host/mesh/src/provisioner.c | 32 +---- 4 files changed, 147 insertions(+), 95 deletions(-) diff --git a/nimble/host/mesh/src/prov.c b/nimble/host/mesh/src/prov.c index 64ad656c41..cdadbb45ba 100644 --- a/nimble/host/mesh/src/prov.c +++ b/nimble/host/mesh/src/prov.c @@ -99,10 +99,98 @@ static bt_mesh_input_action_t input_action(uint8_t action) } } -int bt_mesh_prov_auth(uint8_t method, uint8_t action, uint8_t size) +static int check_output_auth(bt_mesh_output_action_t output, uint8_t size) +{ + if (!output) { + return -EINVAL; + } + + if (!(bt_mesh_prov->output_actions & output)) { + return -EINVAL; + } + + if (size > bt_mesh_prov->output_size) { + return -EINVAL; + } + + return 0; +} + +static int check_input_auth(bt_mesh_input_action_t input, uint8_t size) +{ + if (!input) { + return -EINVAL; + } + + if (!(bt_mesh_prov->input_actions & input)) { + return -EINVAL; + } + + if (size > bt_mesh_prov->input_size) { + return -EINVAL; + } + + return 0; +} + +static void get_auth_string(char *str, uint8_t size) +{ + uint64_t value; + + bt_rand(&value, sizeof(value)); + + static const char characters[36] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + for (int i = 0; i < size; i++) { + /* pull base-36 digits: */ + int idx = value % 36; + + value = value / 36; + str[i] = characters[idx]; + } + + str[size] = '\0'; + + memcpy(bt_mesh_prov_link.auth, str, size); + memset(bt_mesh_prov_link.auth + size, 0, + sizeof(bt_mesh_prov_link.auth) - size); +} + +static uint32_t get_auth_number(bt_mesh_output_action_t output, + bt_mesh_input_action_t input, uint8_t size) + { + const uint32_t divider[PROV_IO_OOB_SIZE_MAX] = { 10, 100, 1000, 10000, + 100000, 1000000, 10000000, 100000000 }; + uint32_t num = 0; + + bt_rand(&num, sizeof(num)); + + if (output == BT_MESH_BLINK || + output == BT_MESH_BEEP || + output == BT_MESH_VIBRATE || + input == BT_MESH_PUSH || + input == BT_MESH_TWIST) { + /* According to the Bluetooth Mesh Profile + * Specification Section 5.4.2.4, blink, beep + * vibrate, push and twist should be a random integer + * between 0 and 10^size, *exclusive*: + */ + num = (num % (divider[size - 1] - 1)) + 1; + } else { + num %= divider[size - 1]; + } + + sys_put_be32(num, &bt_mesh_prov_link.auth[12]); + memset(bt_mesh_prov_link.auth, 0, 12); + + return num; + } + +int bt_mesh_prov_auth(bool is_provisioner, uint8_t method, uint8_t action, uint8_t size) { bt_mesh_output_action_t output; bt_mesh_input_action_t input; + int err; switch (method) { case AUTH_METHOD_NO_OOB: @@ -123,89 +211,63 @@ int bt_mesh_prov_auth(uint8_t method, uint8_t action, uint8_t size) case AUTH_METHOD_OUTPUT: output = output_action(action); - if (!output) { - return -EINVAL; - } + if (is_provisioner) { + if (output == BT_MESH_DISPLAY_STRING) { + input = BT_MESH_ENTER_STRING; + atomic_set_bit(bt_mesh_prov_link.flags, WAIT_STRING); + } else { + input = BT_MESH_ENTER_NUMBER; + atomic_set_bit(bt_mesh_prov_link.flags, WAIT_NUMBER); + } - if (!(bt_mesh_prov->output_actions & output)) { - return -EINVAL; + return bt_mesh_prov->input(input, size); } - if (size > bt_mesh_prov->output_size) { - return -EINVAL; + err = check_output_auth(output, size); + if (err) { + return err; } - atomic_set_bit(bt_mesh_prov_link.flags, NOTIFY_INPUT_COMPLETE); - if (output == BT_MESH_DISPLAY_STRING) { - unsigned char str[9]; - uint8_t i; - - bt_rand(str, size); - - /* Normalize to '0' .. '9' & 'A' .. 'Z' */ - for (i = 0; i < size; i++) { - str[i] %= 36; - if (str[i] < 10) { - str[i] += '0'; - } else { - str[i] += 'A' - 10; - } - } - str[size] = '\0'; - - memcpy(bt_mesh_prov_link.auth, str, size); - memset(bt_mesh_prov_link.auth + size, 0, - sizeof(bt_mesh_prov_link.auth) - size); - - return bt_mesh_prov->output_string((char *)str); - } else { - uint32_t div[8] = { 10, 100, 1000, 10000, 100000, - 1000000, 10000000, 100000000 }; - uint32_t num; - - bt_rand(&num, sizeof(num)); - - if (output == BT_MESH_BLINK || - output == BT_MESH_BEEP || - output == BT_MESH_VIBRATE) { - /* According to the Bluetooth Mesh Profile - * Specification Section 5.4.2.4, blink, beep - * and vibrate should be a random integer - * between 0 and 10^size, *exclusive*: - */ - num = (num % (div[size - 1] - 1)) + 1; - } else { - num %= div[size - 1]; - } + char str[9]; - sys_put_be32(num, &bt_mesh_prov_link.auth[12]); - memset(bt_mesh_prov_link.auth, 0, 12); - - return bt_mesh_prov->output_number(output, num); + atomic_set_bit(bt_mesh_prov_link.flags, NOTIFY_INPUT_COMPLETE); + get_auth_string(str, size); + return bt_mesh_prov->output_string(str); } + atomic_set_bit(bt_mesh_prov_link.flags, NOTIFY_INPUT_COMPLETE); + return bt_mesh_prov->output_number(output, + get_auth_number(output, BT_MESH_NO_INPUT, size)); case AUTH_METHOD_INPUT: input = input_action(action); - if (!input) { - return -EINVAL; - } + if (!is_provisioner) { + err = check_input_auth(input, size); + if (err) { + return err; + } - if (!(bt_mesh_prov->input_actions & input)) { - return -EINVAL; - } + if (input == BT_MESH_ENTER_STRING) { + atomic_set_bit(bt_mesh_prov_link.flags, WAIT_STRING); + } else { + atomic_set_bit(bt_mesh_prov_link.flags, WAIT_NUMBER); + } - if (size > bt_mesh_prov->input_size) { - return -EINVAL; + return bt_mesh_prov->input(input, size); } if (input == BT_MESH_ENTER_STRING) { - atomic_set_bit(bt_mesh_prov_link.flags, WAIT_STRING); - } else { - atomic_set_bit(bt_mesh_prov_link.flags, WAIT_NUMBER); + char str[9]; + + atomic_set_bit(bt_mesh_prov_link.flags, NOTIFY_INPUT_COMPLETE); + get_auth_string(str, size); + return bt_mesh_prov->output_string(str); } - return bt_mesh_prov->input(input, size); + atomic_set_bit(bt_mesh_prov_link.flags, NOTIFY_INPUT_COMPLETE); + output = BT_MESH_DISPLAY_NUMBER; + return bt_mesh_prov->output_number(output, + get_auth_number(BT_MESH_NO_OUTPUT, input, size)); default: return -EINVAL; @@ -231,11 +293,16 @@ int bt_mesh_input_string(const char *str) { BT_DBG("%s", str); + if (strlen(str) > PROV_IO_OOB_SIZE_MAX || + strlen(str) > bt_mesh_prov_link.oob_size) { + return -ENOTSUP; + } + if (!atomic_test_and_clear_bit(bt_mesh_prov_link.flags, WAIT_STRING)) { return -EINVAL; } - strncpy((char *)bt_mesh_prov_link.auth, str, bt_mesh_prov->input_size); + strcpy((char *)bt_mesh_prov_link.auth, str); bt_mesh_prov_link.role->input_complete(); diff --git a/nimble/host/mesh/src/prov.h b/nimble/host/mesh/src/prov.h index b287fb2a00..d18ee0ebb7 100644 --- a/nimble/host/mesh/src/prov.h +++ b/nimble/host/mesh/src/prov.h @@ -71,6 +71,8 @@ #define PROV_ALG_P256 0x00 +#define PROV_IO_OOB_SIZE_MAX 8 /* in bytes */ + #define PROV_BUF(len) \ NET_BUF_SIMPLE(PROV_BEARER_BUF_HEADROOM + PDU_OP_LEN + len) @@ -154,7 +156,7 @@ int bt_mesh_prov_reset_state(void (*func)(const uint8_t key[BT_PUB_KEY_LEN])); bool bt_mesh_prov_active(void); -int bt_mesh_prov_auth(uint8_t method, uint8_t action, uint8_t size); +int bt_mesh_prov_auth(bool is_provisioner, uint8_t method, uint8_t action, uint8_t size); int bt_mesh_pb_gatt_open(uint16_t conn_handle); int bt_mesh_pb_gatt_close(uint16_t conn_handle); diff --git a/nimble/host/mesh/src/prov_device.c b/nimble/host/mesh/src/prov_device.c index ab387c3681..5931444348 100644 --- a/nimble/host/mesh/src/prov_device.c +++ b/nimble/host/mesh/src/prov_device.c @@ -132,8 +132,11 @@ static void prov_start(const uint8_t *data) memcpy(bt_mesh_prov_link.conf_inputs.start, data, PDU_LEN_START); bt_mesh_prov_link.expect = PROV_PUB_KEY; + bt_mesh_prov_link.oob_method = data[2]; + bt_mesh_prov_link.oob_action = data[3]; + bt_mesh_prov_link.oob_size = data[4]; - if (bt_mesh_prov_auth(data[2], data[3], data[4]) < 0) { + if (bt_mesh_prov_auth(false, data[2], data[3], data[4]) < 0) { BT_ERR("Invalid authentication method: 0x%02x; " "action: 0x%02x; size: 0x%02x", data[2], data[3], data[4]); diff --git a/nimble/host/mesh/src/provisioner.c b/nimble/host/mesh/src/provisioner.c index e5cb22ffaa..f4278e110b 100644 --- a/nimble/host/mesh/src/provisioner.c +++ b/nimble/host/mesh/src/provisioner.c @@ -97,7 +97,6 @@ static void start_sent(int err, void *cb_data) static void send_start(void) { BT_DBG(""); - uint8_t method, action; struct os_mbuf *start = PROV_BUF(PDU_LEN_START); bool oob_pub_key = bt_mesh_prov_link.conf_inputs.capabilities[3] == PUB_KEY_OOB; @@ -114,26 +113,6 @@ static void send_start(void) net_buf_simple_add_u8(start, PUB_KEY_NO_OOB); } - if (bt_mesh_prov_link.oob_method == AUTH_METHOD_INPUT) { - method = AUTH_METHOD_OUTPUT; - if (bt_mesh_prov_link.oob_action == INPUT_OOB_STRING) { - action = OUTPUT_OOB_STRING; - } else { - action = OUTPUT_OOB_NUMBER; - } - - } else if (bt_mesh_prov_link.oob_method == AUTH_METHOD_OUTPUT) { - method = AUTH_METHOD_INPUT; - if (bt_mesh_prov_link.oob_action == OUTPUT_OOB_STRING) { - action = INPUT_OOB_STRING; - } else { - action = INPUT_OOB_NUMBER; - } - } else { - method = bt_mesh_prov_link.oob_method; - action = 0x00; - } - net_buf_simple_add_u8(start, bt_mesh_prov_link.oob_method); net_buf_simple_add_u8(start, bt_mesh_prov_link.oob_action); @@ -142,10 +121,11 @@ static void send_start(void) memcpy(bt_mesh_prov_link.conf_inputs.invite, &start->om_data[1], PDU_LEN_INVITE); - if (bt_mesh_prov_auth(method, action, bt_mesh_prov_link.oob_size) < 0) { + if (bt_mesh_prov_auth(true, bt_mesh_prov_link.oob_method, + bt_mesh_prov_link.oob_action, bt_mesh_prov_link.oob_size) < 0) { BT_ERR("Invalid authentication method: 0x%02x; " - "action: 0x%02x; size: 0x%02x", method, - action, bt_mesh_prov_link.oob_size); + "action: 0x%02x; size: 0x%02x", bt_mesh_prov_link.oob_method, + bt_mesh_prov_link.oob_action, bt_mesh_prov_link.oob_size); return; } @@ -686,7 +666,7 @@ static void prov_set_method(uint8_t method, uint8_t action, uint8_t size) int bt_mesh_auth_method_set_input(bt_mesh_input_action_t action, uint8_t size) { - if (!action || !size || size > 8) { + if (!action || !size || size > PROV_IO_OOB_SIZE_MAX) { return -EINVAL; } @@ -696,7 +676,7 @@ int bt_mesh_auth_method_set_input(bt_mesh_input_action_t action, uint8_t size) int bt_mesh_auth_method_set_output(bt_mesh_output_action_t action, uint8_t size) { - if (!action || !size || size > 8) { + if (!action || !size || size > PROV_IO_OOB_SIZE_MAX) { return -EINVAL; } From 16450e8603d1da37e5c0690dd77e80ba65bd7ded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 14 Oct 2021 15:11:01 +0200 Subject: [PATCH 0145/1333] host/mesh: Delete bt_mesh_proxy_prov_disable parameter. we will no longer need the additional `disconnect` parameter, such as we only process gatt database from disconnect handler. This is port of 412e7da951db24768a17c46c51661714bfc17d00 --- nimble/host/mesh/src/gatt_services.c | 57 ++++++++++------------------ nimble/host/mesh/src/mesh.c | 32 ++++++---------- nimble/host/mesh/src/prov_device.c | 6 ++- nimble/host/mesh/src/proxy.h | 2 +- nimble/host/mesh/src/settings.c | 2 +- 5 files changed, 39 insertions(+), 60 deletions(-) diff --git a/nimble/host/mesh/src/gatt_services.c b/nimble/host/mesh/src/gatt_services.c index 40b2165c76..600946eeeb 100644 --- a/nimble/host/mesh/src/gatt_services.c +++ b/nimble/host/mesh/src/gatt_services.c @@ -948,32 +948,34 @@ static void gatt_connected(uint16_t conn_handle) static void gatt_disconnected(uint16_t conn_handle, uint8_t reason) { - int i; - BT_DBG("conn handle %u reason 0x%02x", conn_handle, reason); + struct bt_mesh_proxy_client *client; conn_count--; - for (i = 0; i < ARRAY_SIZE(clients); i++) { - struct bt_mesh_proxy_client *client = &clients[i]; + client = find_client(conn_handle); + if (!client) { + BT_WARN("No Gatt Client found"); + return; + } - if (client->cli.conn_handle != conn_handle) { - continue; - } + if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && client->filter_type == PROV) { + bt_mesh_pb_gatt_close(conn_handle); + client->filter_type = NONE; - if ((MYNEWT_VAL(BLE_MESH_PB_GATT)) && - client->filter_type == PROV) { - bt_mesh_pb_gatt_close(conn_handle); + if (bt_mesh_is_provisioned() && + IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && + bt_mesh_gatt_proxy_get() != BT_MESH_GATT_PROXY_NOT_SUPPORTED) { + (void)bt_mesh_proxy_gatt_enable(); } - - /* If this fails, the work handler exits early, as - * there's no active connection. - */ - (void)k_work_cancel_delayable(&client->cli.sar_timer); - client->cli.conn_handle = BLE_HS_CONN_HANDLE_NONE; - break; } + /* If this fails, the work handler exits early, as + * there's no active connection. + */ + (void)k_work_cancel_delayable(&client->cli.sar_timer); + client->cli.conn_handle = BLE_HS_CONN_HANDLE_NONE; + bt_mesh_adv_update(); } @@ -1100,11 +1102,10 @@ int bt_mesh_proxy_prov_enable(void) return 0; } -int bt_mesh_proxy_prov_disable(bool disconnect) +int bt_mesh_proxy_prov_disable(void) { uint16_t handle; int rc; - int i; BT_DBG(""); @@ -1124,24 +1125,6 @@ int bt_mesh_proxy_prov_disable(bool disconnect) gatt_svc = MESH_GATT_NONE; - for (i = 0; i < ARRAY_SIZE(clients); i++) { - struct bt_mesh_proxy_client *client = &clients[i]; - - if (client->cli.conn_handle == BLE_HS_CONN_HANDLE_NONE - || client->filter_type != PROV) { - continue; - } - - if (disconnect) { - rc = ble_gap_terminate(client->cli.conn_handle, - BLE_ERR_REM_USER_CONN_TERM); - assert(rc == 0); - } else { - bt_mesh_pb_gatt_close(client->cli.conn_handle); - client->filter_type = NONE; - } - } - bt_mesh_adv_update(); return 0; diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c index 0d9c21e668..b4d658f71d 100644 --- a/nimble/host/mesh/src/mesh.c +++ b/nimble/host/mesh/src/mesh.c @@ -44,7 +44,6 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, uint8_t flags, uint32_t iv_index, uint16_t addr, const uint8_t dev_key[16]) { - bool pb_gatt_enabled; int err; BT_INFO("Primary Element: 0x%04x", addr); @@ -55,16 +54,6 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, return -EALREADY; } - if ((MYNEWT_VAL(BLE_MESH_PB_GATT))) { - if (bt_mesh_proxy_prov_disable(false) == 0) { - pb_gatt_enabled = true; - } else { - pb_gatt_enabled = false; - } - } else { - pb_gatt_enabled = false; - } - /* * FIXME: * Should net_key and iv_index be over-ridden? @@ -110,10 +99,6 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, if (err) { atomic_clear_bit(bt_mesh.flags, BT_MESH_VALID); - if (MYNEWT_VAL(BLE_MESH_PB_GATT) && pb_gatt_enabled) { - (void)bt_mesh_proxy_prov_enable(); - } - return err; } @@ -194,7 +179,7 @@ void bt_mesh_reset(void) } if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY))) { - bt_mesh_proxy_gatt_disable(); + (void)bt_mesh_proxy_gatt_disable(); } if (IS_ENABLED(CONFIG_BT_SETTINGS)) { @@ -385,10 +370,17 @@ int bt_mesh_start(void) bt_mesh_beacon_disable(); } - if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && - bt_mesh_gatt_proxy_get() != BT_MESH_GATT_PROXY_NOT_SUPPORTED) { - bt_mesh_proxy_gatt_enable(); - bt_mesh_adv_update(); + /* For PB-GATT provision, will enable in le disconnect handler. */ + if (bt_mesh_prov_link.bearer->type == BT_MESH_PROV_ADV) { + if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { + (void)bt_mesh_proxy_prov_disable(); + } + + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && + bt_mesh_gatt_proxy_get() != BT_MESH_GATT_PROXY_NOT_SUPPORTED) { + (void)bt_mesh_proxy_gatt_enable(); + bt_mesh_adv_update(); + } } if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { diff --git a/nimble/host/mesh/src/prov_device.c b/nimble/host/mesh/src/prov_device.c index 5931444348..312ecc514b 100644 --- a/nimble/host/mesh/src/prov_device.c +++ b/nimble/host/mesh/src/prov_device.c @@ -614,6 +614,10 @@ int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers) return -EALREADY; } + if (bt_mesh_prov_active()) { + return -EBUSY; + } + if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV) && (bearers & BT_MESH_PROV_ADV)) { bt_mesh_beacon_disable(); @@ -622,7 +626,7 @@ int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers) if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && (bearers & BT_MESH_PROV_GATT)) { - bt_mesh_proxy_prov_disable(true); + (void)bt_mesh_proxy_prov_disable(); } return 0; diff --git a/nimble/host/mesh/src/proxy.h b/nimble/host/mesh/src/proxy.h index 2ddb834ea1..7a79cef5e1 100644 --- a/nimble/host/mesh/src/proxy.h +++ b/nimble/host/mesh/src/proxy.h @@ -21,7 +21,7 @@ int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, void (*end)(uint16_t, void *), void *user_data); int bt_mesh_proxy_prov_enable(void); -int bt_mesh_proxy_prov_disable(bool disconnect); +int bt_mesh_proxy_prov_disable(void); int bt_mesh_proxy_gatt_enable(void); int bt_mesh_proxy_gatt_disable(void); diff --git a/nimble/host/mesh/src/settings.c b/nimble/host/mesh/src/settings.c index 5ec6d71e9e..cc9fd630f5 100644 --- a/nimble/host/mesh/src/settings.c +++ b/nimble/host/mesh/src/settings.c @@ -70,7 +70,7 @@ static int mesh_commit(void) } if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { - bt_mesh_proxy_prov_disable(true); + (void)bt_mesh_proxy_prov_disable(); } bt_mesh_net_settings_commit(); From 2d7536ef6042602705ab704d7ddf82ca26772c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 20 Oct 2021 07:08:22 +0200 Subject: [PATCH 0146/1333] host/mesh: Extended advertising support Adds support for extended advertiser commands in the mesh. This doubles throughput for common packet sending, and significantly improves timing accuracy for the Friend and Low Power features. The proxy module's advertisement control has been moved inside the adv module to abstract away the different advertiser modes. The extended advertiser mode does not need an advertising thread to operate, and ends up with a net reduction in RAM usage. This is port of 81bf99145ab712997d4b8db6ba37538f9de3bc46 --- nimble/host/mesh/include/mesh/glue.h | 80 +++++- nimble/host/mesh/src/adv.c | 226 +---------------- nimble/host/mesh/src/adv.h | 32 +++ nimble/host/mesh/src/adv_ext.c | 354 +++++++++++++++++++++++++++ nimble/host/mesh/src/adv_legacy.c | 240 ++++++++++++++++++ nimble/host/mesh/src/gatt_services.c | 117 ++++----- nimble/host/mesh/src/glue.c | 37 ++- nimble/host/mesh/src/mesh.c | 8 + nimble/host/mesh/src/pb_adv.c | 16 ++ nimble/host/mesh/src/proxy.h | 3 +- nimble/host/mesh/syscfg.yml | 31 +++ 11 files changed, 836 insertions(+), 308 deletions(-) create mode 100644 nimble/host/mesh/src/adv_ext.c create mode 100644 nimble/host/mesh/src/adv_legacy.c diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index 1e7f842202..422f2b8018 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -258,6 +258,12 @@ static inline void net_buf_simple_reset(struct os_mbuf *om) net_buf_simple_init(om, 0); } +struct bt_le_ext_adv_start_param { + uint16_t timeout; + + uint8_t num_events; +}; + void net_buf_put(struct ble_npl_eventq *fifo, struct os_mbuf *buf); void * net_buf_ref(struct os_mbuf *om); void net_buf_unref(struct os_mbuf *om); @@ -328,6 +334,74 @@ struct bt_pub_key_cb { struct bt_pub_key_cb *_next; }; +/** LE Advertising Parameters. */ +struct bt_le_adv_param { + /** + * @brief Local identity. + * + * @note When extended advertising @kconfig{CONFIG_BT_EXT_ADV} is not + * enabled or not supported by the controller it is not possible + * to scan and advertise simultaneously using two different + * random addresses. + */ + uint8_t id; + + /** + * @brief Advertising Set Identifier, valid range 0x00 - 0x0f. + * + * @note Requires @ref BT_LE_ADV_OPT_EXT_ADV + **/ + uint8_t sid; + + /** + * @brief Secondary channel maximum skip count. + * + * Maximum advertising events the advertiser can skip before it must + * send advertising data on the secondary advertising channel. + * + * @note Requires @ref BT_LE_ADV_OPT_EXT_ADV + */ + uint8_t secondary_max_skip; + + /** Bit-field of advertising options */ + uint32_t options; + + /** Minimum Advertising Interval (N * 0.625 milliseconds) + * Minimum Advertising Interval shall be less than or equal to the + * Maximum Advertising Interval. The Minimum Advertising Interval and + * Maximum Advertising Interval should not be the same value (as stated + * in Bluetooth Core Spec 5.2, section 7.8.5) + * Range: 0x0020 to 0x4000 + */ + uint32_t interval_min; + + /** Maximum Advertising Interval (N * 0.625 milliseconds) + * Minimum Advertising Interval shall be less than or equal to the + * Maximum Advertising Interval. The Minimum Advertising Interval and + * Maximum Advertising Interval should not be the same value (as stated + * in Bluetooth Core Spec 5.2, section 7.8.5) + * Range: 0x0020 to 0x4000 + */ + uint32_t interval_max; + + /** + * @brief Directed advertising to peer + * + * When this parameter is set the advertiser will send directed + * advertising to the remote device. + * + * The advertising type will either be high duty cycle, or low duty + * cycle if the BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY option is enabled. + * When using @ref BT_LE_ADV_OPT_EXT_ADV then only low duty cycle is + * allowed. + * + * In case of connectable high duty cycle if the connection could not + * be established within the timeout the connected() callback will be + * called with the status set to @ref BT_HCI_ERR_ADV_TIMEOUT. + */ + const bt_addr_le_t *peer; +}; + typedef void (*bt_dh_key_cb_t)(const uint8_t key[BT_DH_KEY_LEN]); int bt_dh_key_gen(const uint8_t remote_pk[BT_PUB_KEY_LEN], bt_dh_key_cb_t cb); int bt_pub_key_gen(struct bt_pub_key_cb *new_cb); @@ -343,9 +417,11 @@ int bt_ccm_encrypt(const uint8_t key[16], uint8_t nonce[13], const uint8_t *enc_ uint8_t *plaintext, size_t mic_size); void bt_mesh_register_gatt(void); int bt_le_adv_start(const struct ble_gap_adv_params *param, + int64_t duration, const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len); -int bt_le_adv_stop(bool proxy); + +int bt_le_adv_stop(); struct k_work_delayable { struct ble_npl_callout work; @@ -358,6 +434,7 @@ bool k_work_delayable_is_pending(struct k_work_delayable *w); void k_work_reschedule(struct k_work_delayable *w, uint32_t ms); int64_t k_uptime_get(void); uint32_t k_uptime_get_32(void); +int64_t k_uptime_delta(int64_t *reftime); void k_sleep(int32_t duration); void k_work_submit(struct ble_npl_callout *w); void k_work_add_arg(struct ble_npl_callout *w, void *arg); @@ -428,6 +505,7 @@ static inline unsigned int find_msb_set(uint32_t op) #define CONFIG_BT_MESH_PROV_DEVICE BLE_MESH_PROV_DEVICE #define CONFIG_BT_MESH_CDB BLE_MESH_CDB #define CONFIG_BT_MESH_DEBUG_CFG BLE_MESH_DEBUG_CFG +#define CONFIG_BT_MESH_DEBUG_ADV BLE_MESH_DEBUG_ADV /* Above flags are used with IS_ENABLED macro */ #define IS_ENABLED(config) MYNEWT_VAL(config) diff --git a/nimble/host/mesh/src/adv.c b/nimble/host/mesh/src/adv.c index b3d6290819..0b0205cbc2 100644 --- a/nimble/host/mesh/src/adv.c +++ b/nimble/host/mesh/src/adv.c @@ -13,7 +13,6 @@ #include "mesh/mesh.h" #include "host/ble_hs_adv.h" #include "host/ble_gap.h" -#include "nimble/hci_common.h" #include "mesh/porting.h" #include "adv.h" @@ -23,42 +22,21 @@ #include "prov.h" #include "proxy.h" -/* Convert from ms to 0.625ms units */ -#define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5) - /* Window and Interval are equal for continuous scanning */ -#define MESH_SCAN_INTERVAL_MS 30 -#define MESH_SCAN_WINDOW_MS 30 -#define MESH_SCAN_INTERVAL ADV_SCAN_UNIT(MESH_SCAN_INTERVAL_MS) -#define MESH_SCAN_WINDOW ADV_SCAN_UNIT(MESH_SCAN_WINDOW_MS) - -/* Pre-5.0 controllers enforce a minimum interval of 100ms - * whereas 5.0+ controllers can go down to 20ms. - */ -#define ADV_INT_DEFAULT_MS 100 -#define ADV_INT_FAST_MS 20 +#define MESH_SCAN_INTERVAL BT_MESH_ADV_SCAN_UNIT(BT_MESH_SCAN_INTERVAL_MS) +#define MESH_SCAN_WINDOW BT_MESH_ADV_SCAN_UNIT(BT_MESH_SCAN_WINDOW_MS) -static int32_t adv_int_min = ADV_INT_DEFAULT_MS; +const uint8_t bt_mesh_adv_type[BT_MESH_ADV_TYPES] = { + [BT_MESH_ADV_PROV] = BT_DATA_MESH_PROV, + [BT_MESH_ADV_DATA] = BT_DATA_MESH_MESSAGE, + [BT_MESH_ADV_BEACON] = BT_DATA_MESH_BEACON, + [BT_MESH_ADV_URI] = BT_DATA_URI, +}; -/* TinyCrypt PRNG consumes a lot of stack space, so we need to have - * an increased call stack whenever it's used. - */ -#if MYNEWT -OS_TASK_STACK_DEFINE(g_blemesh_stack, MYNEWT_VAL(BLE_MESH_ADV_STACK_SIZE)); -struct os_task adv_task; -#endif - -static struct ble_npl_eventq adv_queue; extern uint8_t g_mesh_addr_type; -static int adv_initialized = false; - -static os_membuf_t adv_buf_mem[OS_MEMPOOL_SIZE( - MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT), - BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE)]; struct os_mbuf_pool adv_os_mbuf_pool; -static struct os_mempool adv_buf_mempool; - +static struct ble_npl_eventq bt_mesh_adv_queue; static struct bt_mesh_adv adv_pool[CONFIG_BT_MESH_ADV_BUF_COUNT]; static struct bt_mesh_adv *adv_alloc(int id) @@ -66,153 +44,6 @@ static struct bt_mesh_adv *adv_alloc(int id) return &adv_pool[id]; } -static inline void adv_send_end(int err, const struct bt_mesh_send_cb *cb, - void *cb_data) -{ - if (cb && cb->end) { - cb->end(err, cb_data); - } -} - -static inline void adv_send(struct os_mbuf *buf) -{ - static const uint8_t adv_type[] = { - [BT_MESH_ADV_PROV] = BLE_HS_ADV_TYPE_MESH_PROV, - [BT_MESH_ADV_DATA] = BLE_HS_ADV_TYPE_MESH_MESSAGE, - [BT_MESH_ADV_BEACON] = BLE_HS_ADV_TYPE_MESH_BEACON, - [BT_MESH_ADV_URI] = BLE_HS_ADV_TYPE_URI, -} ; - - const struct bt_mesh_send_cb *cb = BT_MESH_ADV(buf)->cb; - void *cb_data = BT_MESH_ADV(buf)->cb_data; - struct ble_gap_adv_params param = { 0 }; - uint16_t duration, adv_int; - struct bt_data ad; - int err; - - adv_int = max(adv_int_min, - BT_MESH_TRANSMIT_INT(BT_MESH_ADV(buf)->xmit)); -#if MYNEWT_VAL(BLE_CONTROLLER) - duration = ((BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1) * - (adv_int + 10)); -#else - /* Zephyr Bluetooth Low Energy Controller for mesh stack uses - * pre-emptible continuous scanning, allowing advertising events to be - * transmitted without delay when advertising is enabled. No need to - * compensate with scan window duration. - * An advertising event could be delayed by upto one interval when - * advertising is stopped and started in quick succession, hence add - * advertising interval to the total advertising duration. - */ - duration = (adv_int + - ((BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1) * - (adv_int + 10))); - - /* Zephyr Bluetooth Low Energy Controller built for nRF51x SoCs use - * CONFIG_BT_CTLR_LOW_LAT=y, and continuous scanning cannot be - * pre-empted, hence, scanning will block advertising events from - * being transmitted. Increase the advertising duration by the - * amount of scan window duration to compensate for the blocked - * advertising events. - */ - if (MYNEWT_VAL(BSP_NRF51)) { - duration += BT_MESH_SCAN_WINDOW_MS; - } -#endif - - BT_DBG("type %u om_len %u: %s", BT_MESH_ADV(buf)->type, - buf->om_len, bt_hex(buf->om_data, buf->om_len)); - BT_DBG("count %u interval %ums duration %ums", - BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1, adv_int, - duration); - - ad.type = adv_type[BT_MESH_ADV(buf)->type]; - ad.data_len = buf->om_len; - ad.data = buf->om_data; - - param.itvl_min = ADV_SCAN_UNIT(adv_int); - param.itvl_max = param.itvl_min; - param.conn_mode = BLE_GAP_CONN_MODE_NON; - - err = bt_le_adv_start(¶m, &ad, 1, NULL, 0); - net_buf_unref(buf); - adv_send_start(duration, err, cb, cb_data); - if (err) { - BT_ERR("Advertising failed: err %d", err); - return; - } - - BT_DBG("Advertising started. Sleeping %u ms", duration); - - k_sleep(K_MSEC(duration)); - - err = bt_le_adv_stop(false); - adv_send_end(err, cb, cb_data); - if (err) { - BT_ERR("Stopping advertising failed: err %d", err); - return; - } - - BT_DBG("Advertising stopped"); -} - -void -mesh_adv_thread(void *args) -{ - static struct ble_npl_event *ev; - struct os_mbuf *buf; -#if (MYNEWT_VAL(BLE_MESH_PROXY)) - int32_t timeout; -#endif - - BT_DBG("started"); - - while (1) { -#if (MYNEWT_VAL(BLE_MESH_PROXY)) - ev = ble_npl_eventq_get(&adv_queue, 0); - while (!ev) { - timeout = bt_mesh_proxy_adv_start(); - BT_DBG("Proxy Advertising up to %d ms", (int) timeout); - - // FIXME: should we redefine K_SECONDS macro instead in glue? - if (timeout != K_FOREVER) { - timeout = ble_npl_time_ms_to_ticks32(timeout); - } - - ev = ble_npl_eventq_get(&adv_queue, timeout); - bt_mesh_proxy_adv_stop(); - } -#else - ev = ble_npl_eventq_get(&adv_queue, BLE_NPL_TIME_FOREVER); -#endif - - if (!ev || !ble_npl_event_get_arg(ev)) { - continue; - } - - buf = ble_npl_event_get_arg(ev); - - /* busy == 0 means this was canceled */ - if (BT_MESH_ADV(buf)->busy) { - BT_MESH_ADV(buf)->busy = 0; - adv_send(buf); - } else { - net_buf_unref(buf); - } - - /* os_sched(NULL); */ - } -} - -void bt_mesh_adv_update(void) -{ - static struct ble_npl_event ev = { }; - - BT_DBG(""); - - ble_npl_eventq_put(&adv_queue, &ev); -} - struct os_mbuf *bt_mesh_adv_create_from_pool(struct os_mbuf_pool *pool, bt_mesh_adv_alloc_t get_id, enum bt_mesh_adv_type type, @@ -262,7 +93,8 @@ void bt_mesh_adv_send(struct os_mbuf *buf, const struct bt_mesh_send_cb *cb, BT_MESH_ADV(buf)->cb_data = cb_data; BT_MESH_ADV(buf)->busy = 1; - net_buf_put(&adv_queue, net_buf_ref(buf)); + net_buf_put(&bt_mesh_adv_queue, net_buf_ref(buf)); + bt_mesh_adv_buf_ready(); } static void bt_mesh_scan_cb(const bt_addr_le_t *addr, int8_t rssi, @@ -316,42 +148,6 @@ static void bt_mesh_scan_cb(const bt_addr_le_t *addr, int8_t rssi, } } -void bt_mesh_adv_init(void) -{ - int rc; - - /* Advertising should only be initialized once. Calling - * os_task init the second time will result in an assert. */ - if (adv_initialized) { - return; - } - - rc = os_mempool_init(&adv_buf_mempool, MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT), - BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE, - adv_buf_mem, "adv_buf_pool"); - assert(rc == 0); - - rc = os_mbuf_pool_init(&adv_os_mbuf_pool, &adv_buf_mempool, - BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE, - MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT)); - assert(rc == 0); - - ble_npl_eventq_init(&adv_queue); - -#if MYNEWT - os_task_init(&adv_task, "mesh_adv", mesh_adv_thread, NULL, - MYNEWT_VAL(BLE_MESH_ADV_TASK_PRIO), OS_WAIT_FOREVER, - g_blemesh_stack, MYNEWT_VAL(BLE_MESH_ADV_STACK_SIZE)); -#endif - - /* For BT5 controllers we can have fast advertising interval */ - if (ble_hs_hci_get_hci_version() >= BLE_HCI_VER_BCS_5_0) { - adv_int_min = ADV_INT_FAST_MS; - } - - adv_initialized = true; -} - int ble_adv_gap_mesh_cb(struct ble_gap_event *event, void *arg) { diff --git a/nimble/host/mesh/src/adv.h b/nimble/host/mesh/src/adv.h index ba6d3c8d7f..9412bb0ce9 100644 --- a/nimble/host/mesh/src/adv.h +++ b/nimble/host/mesh/src/adv.h @@ -14,6 +14,10 @@ #define BT_MESH_ADV(om) (*(struct bt_mesh_adv **) OS_MBUF_USRHDR(om)) +#define BT_MESH_ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5) +#define BT_MESH_SCAN_INTERVAL_MS 30 +#define BT_MESH_SCAN_WINDOW_MS 30 + #define BT_MESH_ADV_DATA_SIZE 31 /* The user data is a pointer (4 bytes) to struct bt_mesh_adv */ @@ -23,12 +27,17 @@ BT_MESH_ADV_USER_DATA_SIZE +\ sizeof(struct os_mbuf)) +/* We declare it as extern here to share it between 'adv' and 'adv_legacy' */ +extern struct os_mbuf_pool adv_os_mbuf_pool; + enum bt_mesh_adv_type { BT_MESH_ADV_PROV, BT_MESH_ADV_DATA, BT_MESH_ADV_BEACON, BT_MESH_ADV_URI, + + BT_MESH_ADV_TYPES, }; typedef void (*bt_mesh_adv_func_t)(struct os_mbuf *buf, uint16_t duration, @@ -82,6 +91,29 @@ void bt_mesh_adv_init(void); int bt_mesh_scan_enable(void); int bt_mesh_scan_disable(void); +int bt_mesh_adv_enable(void); + +void bt_mesh_adv_buf_ready(void); + +int bt_mesh_adv_start(const struct ble_gap_adv_params *param, int32_t duration, + const struct bt_data *ad, size_t ad_len, + const struct bt_data *sd, size_t sd_len); + +static inline void bt_mesh_adv_send_start(uint16_t duration, int err, + const struct bt_mesh_send_cb *cb, + void *cb_data) +{ + if (cb && cb->start) { + cb->start(duration, err, cb_data); + } +} +static inline void bt_mesh_adv_send_end( + int err, const struct bt_mesh_send_cb *cb, void *cb_data) +{ + if (cb && cb->end) { + cb->end(err, cb_data); + } +} int ble_adv_gap_mesh_cb(struct ble_gap_event *event, void *arg); #endif diff --git a/nimble/host/mesh/src/adv_ext.c b/nimble/host/mesh/src/adv_ext.c new file mode 100644 index 0000000000..2dd7d13666 --- /dev/null +++ b/nimble/host/mesh/src/adv_ext.c @@ -0,0 +1,354 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2018 Nordic Semiconductor ASA + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define MESH_LOG_MODULE BLE_MESH_ADV_LOG +#define LOG_MODULE_NAME bt_mesh_adv_ext + + +#include "adv.h" +#include "net.h" +#include "proxy.h" +#include "syscfg/syscfg.h" +#include "host/ble_gap.h" + +#if MYNEWT_VAL(BLE_MESH_ADV_EXT) +/* Convert from ms to 0.625ms units */ +#define ADV_INT_FAST_MS 20 +#define BT_ID_DEFAULT 0 + +static struct ble_gap_ext_adv_params adv_param = { + .itvl_min = BT_MESH_ADV_SCAN_UNIT(ADV_INT_FAST_MS), + .itvl_max = BT_MESH_ADV_SCAN_UNIT(ADV_INT_FAST_MS), +}; + +bool ext_adv_configured = false; +static struct ble_npl_eventq bt_mesh_adv_queue; + +enum { + /** Controller is currently advertising */ + ADV_FLAG_ACTIVE, + /** Currently performing proxy advertising */ + ADV_FLAG_PROXY, + /** The send-call has been scheduled. */ + ADV_FLAG_SCHEDULED, + /** Custom adv params have been set, we need to update the parameters on + * the next send. + */ + ADV_FLAG_UPDATE_PARAMS, + + /* Number of adv flags. */ + ADV_FLAGS_NUM +}; + +static struct { + ATOMIC_DEFINE(flags, ADV_FLAGS_NUM); + struct bt_le_ext_adv *instance; + const struct bt_mesh_send_cb *cb; + void *cb_data; + int64_t timestamp; + struct k_work_delayable work; +} adv; + + +static void schedule_send(void) +{ + int64_t timestamp = adv.timestamp; + int64_t delta; + + if (atomic_test_and_clear_bit(adv.flags, ADV_FLAG_PROXY)) { + ble_gap_ext_adv_stop(BT_ID_DEFAULT); + atomic_clear_bit(adv.flags, ADV_FLAG_ACTIVE); + } + + if (atomic_test_bit(adv.flags, ADV_FLAG_ACTIVE) || + atomic_test_and_set_bit(adv.flags, ADV_FLAG_SCHEDULED)) { + return; + } + + /* The controller will send the next advertisement immediately. + * Introduce a delay here to avoid sending the next mesh packet closer + * to the previous packet than what's permitted by the specification. + */ + delta = k_uptime_delta(×tamp); + k_work_reschedule(&adv.work, K_MSEC(ADV_INT_FAST_MS - delta)); +} + +static int +ble_mesh_ext_adv_event_handler(struct ble_gap_event *event, void *arg) +{ + int64_t duration; + + switch (event->type) { + case BLE_GAP_EVENT_CONNECT: + if (atomic_test_and_clear_bit(adv.flags, ADV_FLAG_PROXY)) { + atomic_clear_bit(adv.flags, ADV_FLAG_ACTIVE); + schedule_send(); + } + break; + case BLE_GAP_EVENT_ADV_COMPLETE: + /* Calling k_uptime_delta on a timestamp moves it to the current time. + * This is essential here, as schedule_send() uses the end of the event + * as a reference to avoid sending the next advertisement too soon. + */ + duration = k_uptime_delta(&adv.timestamp); + + BT_DBG("Advertising stopped after %u ms", (uint32_t)duration); + + atomic_clear_bit(adv.flags, ADV_FLAG_ACTIVE); + + if (!atomic_test_and_clear_bit(adv.flags, ADV_FLAG_PROXY)) { + bt_mesh_adv_send_end(0, adv.cb, adv.cb_data); + } + + schedule_send(); + break; + default: + return 0; + } + return 0; +} + +static int adv_start(const struct ble_gap_ext_adv_params *param, + uint32_t timeout, + const struct bt_data *ad, size_t ad_len, + const struct bt_data *sd, size_t sd_len) +{ + int err; + struct os_mbuf *ad_data; + struct os_mbuf *sd_data; + + ad_data = os_msys_get_pkthdr(BLE_HS_ADV_MAX_SZ, 0); + assert(ad_data); + sd_data = os_msys_get_pkthdr(BLE_HS_ADV_MAX_SZ, 0); + assert(sd_data); + if (!adv.instance) { + BT_ERR("Mesh advertiser not enabled"); + err = -ENODEV; + goto error; + } + + if (atomic_test_and_set_bit(adv.flags, ADV_FLAG_ACTIVE)) { + BT_ERR("Advertiser is busy"); + err = -EBUSY; + goto error; + } + + if (atomic_test_bit(adv.flags, ADV_FLAG_UPDATE_PARAMS)) { + err = ble_gap_ext_adv_configure(BT_ID_DEFAULT, param, NULL, + ble_mesh_ext_adv_event_handler, NULL); + if (err) { + BT_ERR("Failed updating adv params: %d", err); + atomic_clear_bit(adv.flags, ADV_FLAG_ACTIVE); + goto error; + } + + atomic_set_bit_to(adv.flags, ADV_FLAG_UPDATE_PARAMS, + param != &adv_param); + } + + assert(ad_data); + err = os_mbuf_append(ad_data, ad, ad_len); + if (err) { + goto error; + } + + err = ble_gap_ext_adv_set_data(BT_ID_DEFAULT, ad_data); + if (err) { + BT_ERR("Failed setting adv data: %d", err); + atomic_clear_bit(adv.flags, ADV_FLAG_ACTIVE); + goto error; + } + + err = os_mbuf_append(sd_data, sd, sd_len); + if (err) { + goto error; + } + err = ble_gap_ext_adv_rsp_set_data(BT_ID_DEFAULT, sd_data); + if (err) { + BT_ERR("Failed setting scan response data: %d", err); + atomic_clear_bit(adv.flags, ADV_FLAG_ACTIVE); + goto error; + } + + adv.timestamp = k_uptime_get(); + + err = ble_gap_ext_adv_start(BT_ID_DEFAULT, timeout, 0); + if (err) { + BT_ERR("Advertising failed: err %d", err); + atomic_clear_bit(adv.flags, ADV_FLAG_ACTIVE); + } + +error: + if (ad_data) { + os_mbuf_free_chain(ad_data); + } + + if (sd_data) { + os_mbuf_free_chain(sd_data); + } + return err; +} + +static int buf_send(struct os_mbuf *buf) +{ + static const uint8_t bt_mesh_adv_type[] = { + [BT_MESH_ADV_PROV] = BLE_HS_ADV_TYPE_MESH_PROV, + [BT_MESH_ADV_DATA] = BLE_HS_ADV_TYPE_MESH_MESSAGE, + [BT_MESH_ADV_BEACON] = BLE_HS_ADV_TYPE_MESH_BEACON, + [BT_MESH_ADV_URI] = BLE_HS_ADV_TYPE_URI, + }; + + struct bt_le_ext_adv_start_param start = { + .num_events = + BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1, + }; + uint16_t duration, adv_int; + struct bt_data ad; + int err; + + adv_int = MAX(ADV_INT_FAST_MS, + BT_MESH_TRANSMIT_INT(BT_MESH_ADV(buf)->xmit)); + /* Upper boundary estimate: */ + duration = start.num_events * (adv_int + 10); + + BT_DBG("type %u len %u: %s", BT_MESH_ADV(buf)->type, + buf->om_len, bt_hex(buf->om_data, buf->om_len)); + BT_DBG("count %u interval %ums duration %ums", + BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1, adv_int, + duration); + + ad.type = bt_mesh_adv_type[BT_MESH_ADV(buf)->type]; + ad.data_len = buf->om_len; + ad.data = buf->om_data; + + /* Only update advertising parameters if they're different */ + if (adv_param.itvl_min != BT_MESH_ADV_SCAN_UNIT(adv_int)) { + adv_param.itvl_min = BT_MESH_ADV_SCAN_UNIT(adv_int); + adv_param.itvl_max = adv_param.itvl_min; + atomic_set_bit(adv.flags, ADV_FLAG_UPDATE_PARAMS); + } + + adv.cb = BT_MESH_ADV(buf)->cb; + adv.cb_data = BT_MESH_ADV(buf)->cb_data; + + err = adv_start(&adv_param, duration, &ad, 1, NULL, 0); + net_buf_unref(buf); + bt_mesh_adv_send_start(duration, err, adv.cb, adv.cb_data); + + return err; +} + +static void send_pending_adv(struct ble_npl_event *work) +{ + struct os_mbuf *buf; + int err; + + atomic_clear_bit(adv.flags, ADV_FLAG_SCHEDULED); + + while ((buf = net_buf_get(&bt_mesh_adv_queue, K_NO_WAIT))) { + /* busy == 0 means this was canceled */ + if (!BT_MESH_ADV(buf)->busy) { + net_buf_unref(buf); + continue; + } + + BT_MESH_ADV(buf)->busy = 0U; + err = buf_send(buf); + if (!err) { + return; /* Wait for advertising to finish */ + } + } + + /* No more pending buffers */ + if (MYNEWT_VAL(BLE_MESH_GATT_SERVER)) { + BT_DBG("Proxy Advertising"); + err = bt_mesh_proxy_adv_start(); + if (!err) { + atomic_set_bit(adv.flags, ADV_FLAG_PROXY); + } + } +} + +void bt_mesh_adv_update(void) +{ + BT_DBG(""); + + schedule_send(); +} + +void bt_mesh_adv_buf_ready(void) +{ + schedule_send(); +} + +void bt_mesh_adv_init(void) +{ + k_work_init_delayable(&adv.work, send_pending_adv); +} + +int bt_mesh_adv_enable(void) +{ + struct ble_gap_ext_adv_params params; + ble_addr_t addr; + int rc; + + if (ext_adv_configured) { + /* Already initialized */ + return 0; + } + + params.itvl_min = BT_MESH_ADV_SCAN_UNIT(ADV_INT_FAST_MS); + params.itvl_max = BT_MESH_ADV_SCAN_UNIT(ADV_INT_FAST_MS); + + if (MYNEWT_VAL(BLE_MESH_DEBUG_USE_ID_ADDR)) { + params.own_addr_type = BLE_OWN_ADDR_PUBLIC; + } else { + params.own_addr_type = BLE_OWN_ADDR_RANDOM; + /* set random (NRPA) address for instance */ + rc = ble_hs_id_gen_rnd(1, &addr); + assert (rc == 0); + + rc = ble_gap_ext_adv_set_addr(BT_ID_DEFAULT, &addr ); + assert (rc == 0); + } + + params.primary_phy = BLE_HCI_LE_PHY_1M; + params.secondary_phy = BLE_HCI_LE_PHY_1M; + params.tx_power = 127; + params.sid = 4; + + rc = ble_gap_ext_adv_configure(BT_ID_DEFAULT, ¶ms, NULL, + ble_mesh_ext_adv_event_handler, NULL); + if (rc == 0) { + ext_adv_configured = true; + } + + return rc; +} + +int bt_mesh_adv_start(const struct ble_gap_adv_params *param, int32_t duration, + const struct bt_data *ad, size_t ad_len, + const struct bt_data *sd, size_t sd_len) +{ + static uint32_t adv_timeout; + struct ble_gap_ext_adv_params params = { + .itvl_min = param->itvl_min, + .itvl_max = param->itvl_max + }; + + /* In NimBLE duration is in ms, not 10ms units */ + adv_timeout = (duration == BLE_HS_FOREVER) ? 0 : duration; + + BT_DBG("Start advertising %d ms", duration); + + atomic_set_bit(adv.flags, ADV_FLAG_UPDATE_PARAMS); + + return adv_start(¶ms, adv_timeout, ad, ad_len, sd, sd_len); +} +#endif diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c new file mode 100644 index 0000000000..c07da896c6 --- /dev/null +++ b/nimble/host/mesh/src/adv_legacy.c @@ -0,0 +1,240 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2018 Nordic Semiconductor ASA + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define MESH_LOG_MODULE BLE_MESH_ADV_LOG +#define LOG_MODULE_NAME bt_mesh_adv_legacy + +#include "adv.h" +#include "net.h" +#include "foundation.h" +#include "beacon.h" +#include "prov.h" +#include "proxy.h" + +#if MYNEWT_VAL(BLE_MESH_ADV_LEGACY) +/* Convert from ms to 0.625ms units */ +#define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5) + +/* Pre-5.0 controllers enforce a minimum interval of 100ms + * whereas 5.0+ controllers can go down to 20ms. + */ +#define ADV_INT_DEFAULT_MS 100 +#define ADV_INT_FAST_MS 20 + +static int32_t adv_int_min = ADV_INT_DEFAULT_MS; + +#if !MYNEWT_VAL(BLE_EXT_ADV) +static int adv_initialized = false; +/* TinyCrypt PRNG consumes a lot of stack space, so we need to have + * an increased call stack whenever it's used. + */ +#if MYNEWT +OS_TASK_STACK_DEFINE(g_blemesh_stack, MYNEWT_VAL(BLE_MESH_ADV_STACK_SIZE)); +struct os_task adv_task; +#endif +static os_membuf_t adv_buf_mem[OS_MEMPOOL_SIZE( + MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT), + BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE)]; +static struct os_mempool adv_buf_mempool; +#endif +static struct ble_npl_eventq adv_queue; + +static inline void adv_send(struct os_mbuf *buf) +{ + static const uint8_t adv_type[] = { + [BT_MESH_ADV_PROV] = BLE_HS_ADV_TYPE_MESH_PROV, + [BT_MESH_ADV_DATA] = BLE_HS_ADV_TYPE_MESH_MESSAGE, + [BT_MESH_ADV_BEACON] = BLE_HS_ADV_TYPE_MESH_BEACON, + [BT_MESH_ADV_URI] = BLE_HS_ADV_TYPE_URI, + }; + const struct bt_mesh_send_cb *cb = BT_MESH_ADV(buf)->cb; + void *cb_data = BT_MESH_ADV(buf)->cb_data; + struct ble_gap_adv_params param = { 0 }; + uint16_t duration, adv_int; + struct bt_data ad; + int err; + + adv_int = max(adv_int_min, + BT_MESH_TRANSMIT_INT(BT_MESH_ADV(buf)->xmit)); +#if MYNEWT_VAL(BLE_CONTROLLER) + duration = ((BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1) * + (adv_int + 10)); +#else + /* Zephyr Bluetooth Low Energy Controller for mesh stack uses + * pre-emptible continuous scanning, allowing advertising events to be + * transmitted without delay when advertising is enabled. No need to + * compensate with scan window duration. + * An advertising event could be delayed by upto one interval when + * advertising is stopped and started in quick succession, hence add + * advertising interval to the total advertising duration. + */ + duration = (adv_int + + ((BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1) * + (adv_int + 10))); + + /* Zephyr Bluetooth Low Energy Controller built for nRF51x SoCs use + * CONFIG_BT_CTLR_LOW_LAT=y, and continuous scanning cannot be + * pre-empted, hence, scanning will block advertising events from + * being transmitted. Increase the advertising duration by the + * amount of scan window duration to compensate for the blocked + * advertising events. + */ + if (MYNEWT_VAL(BSP_NRF51)) { + duration += BT_MESH_SCAN_WINDOW_MS; + } +#endif + + BT_DBG("type %u om_len %u: %s", BT_MESH_ADV(buf)->type, + buf->om_len, bt_hex(buf->om_data, buf->om_len)); + BT_DBG("count %u interval %ums duration %ums", + BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1, adv_int, + duration); + + ad.type = adv_type[BT_MESH_ADV(buf)->type]; + ad.data_len = buf->om_len; + ad.data = buf->om_data; + + param.itvl_min = ADV_SCAN_UNIT(adv_int); + param.itvl_max = param.itvl_min; + param.conn_mode = BLE_GAP_CONN_MODE_NON; + + err = bt_le_adv_start(¶m, duration, &ad, 1, NULL, 0); + + net_buf_unref(buf); + adv_send_start(duration, err, cb, cb_data); + if (err) { + BT_ERR("Advertising failed: err %d", err); + return; + } + + BT_DBG("Advertising started. Sleeping %u ms", duration); + + k_sleep(K_MSEC(duration)); + + err = bt_le_adv_stop(); + bt_mesh_adv_send_end(err, cb, cb_data); + if (err) { + BT_ERR("Stopping advertising failed: err %d", err); + return; + } + + BT_DBG("Advertising stopped"); +} + +void +adv_thread(void *args) +{ + static struct ble_npl_event *ev; + struct os_mbuf *buf; +#if (MYNEWT_VAL(BLE_MESH_PROXY)) + int32_t timeout; +#endif + + BT_DBG("started"); + + while (1) { +#if (MYNEWT_VAL(BLE_MESH_PROXY)) + ev = ble_npl_eventq_get(&adv_queue, 0); + while (!ev) { + timeout = bt_mesh_proxy_adv_start(); + BT_DBG("Proxy Advertising up to %d ms", (int) timeout); + + // FIXME: should we redefine K_SECONDS macro instead in glue? + if (timeout != K_FOREVER) { + timeout = ble_npl_time_ms_to_ticks32(timeout); + } + + ev = ble_npl_eventq_get(&adv_queue, timeout); + bt_le_adv_stop(); + } +#else + ev = ble_npl_eventq_get(&adv_queue, BLE_NPL_TIME_FOREVER); +#endif + + if (!ev || !ble_npl_event_get_arg(ev)) { + continue; + } + + buf = ble_npl_event_get_arg(ev); + + /* busy == 0 means this was canceled */ + if (BT_MESH_ADV(buf)->busy) { + BT_MESH_ADV(buf)->busy = 0; + adv_send(buf); + } else { + net_buf_unref(buf); + } + + /* os_sched(NULL); */ + } +} + +void bt_mesh_adv_update(void) +{ + static struct ble_npl_event ev = { }; + + BT_DBG(""); + + ble_npl_eventq_put(&adv_queue, &ev); +} + +void bt_mesh_adv_buf_ready(void) +{ + /* Will be handled automatically */ +} + +void bt_mesh_adv_init(void) +{ + int rc; + + /* Advertising should only be initialized once. Calling + * os_task init the second time will result in an assert. */ + if (adv_initialized) { + return; + } + + rc = os_mempool_init(&adv_buf_mempool, MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT), + BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE, + adv_buf_mem, "adv_buf_pool"); + assert(rc == 0); + + rc = os_mbuf_pool_init(&adv_os_mbuf_pool, &adv_buf_mempool, + BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE, + MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT)); + assert(rc == 0); + + ble_npl_eventq_init(&adv_queue); + +#if MYNEWT + os_task_init(&adv_task, "mesh_adv", adv_thread, NULL, + MYNEWT_VAL(BLE_MESH_ADV_TASK_PRIO), OS_WAIT_FOREVER, + g_blemesh_stack, MYNEWT_VAL(BLE_MESH_ADV_STACK_SIZE)); +#endif + + /* For BT5 controllers we can have fast advertising interval */ + if (ble_hs_hci_get_hci_version() >= BLE_HCI_VER_BCS_5_0) { + adv_int_min = ADV_INT_FAST_MS; + } + + adv_initialized = true; +} + +int bt_mesh_adv_enable(void) +{ + /* Dummy function - in legacy adv thread is started on init*/ + return 0; +} + +int bt_mesh_adv_start(const struct ble_gap_adv_params *param, int32_t duration, + const struct bt_data *ad, size_t ad_len, + const struct bt_data *sd, size_t sd_len) +{ + return bt_le_adv_start(param, duration, ad, ad_len, sd, sd_len); +} +#endif \ No newline at end of file diff --git a/nimble/host/mesh/src/gatt_services.c b/nimble/host/mesh/src/gatt_services.c index 600946eeeb..40909b6964 100644 --- a/nimble/host/mesh/src/gatt_services.c +++ b/nimble/host/mesh/src/gatt_services.c @@ -101,8 +101,6 @@ ble_uuid16_t BT_UUID_MESH_PROXY_DATA_OUT = BLE_UUID16_INIT(0x2ade); .itvl_min = BT_GAP_ADV_FAST_INT_MIN_2, \ .itvl_max = BT_GAP_ADV_FAST_INT_MAX_2, -static bool gatt_adv_enabled; - static struct { uint16_t proxy_h; uint16_t proxy_data_out_h; @@ -479,7 +477,7 @@ static const struct bt_data net_id_ad[] = { BT_DATA(BT_DATA_SVC_DATA16, proxy_svc_data, NET_ID_LEN), }; -static int node_id_adv(struct bt_mesh_subnet *sub) +static int node_id_adv(struct bt_mesh_subnet *sub, int32_t duration) { struct ble_gap_adv_params fast_adv_param = { ADV_OPT_PROXY @@ -520,7 +518,7 @@ static int node_id_adv(struct bt_mesh_subnet *sub) memcpy(proxy_svc_data + 3, tmp + 8, 8); - err = bt_le_adv_start(&fast_adv_param, node_id_ad, + err = bt_le_adv_start(&fast_adv_param, duration, node_id_ad, ARRAY_SIZE(node_id_ad), sd, 0); if (err) { BT_WARN("Failed to advertise using Node ID (err %d)", err); @@ -530,7 +528,7 @@ static int node_id_adv(struct bt_mesh_subnet *sub) return 0; } -static int net_id_adv(struct bt_mesh_subnet *sub) +static int net_id_adv(struct bt_mesh_subnet *sub, int32_t duration) { struct ble_gap_adv_params slow_adv_param = { ADV_OPT_PROXY @@ -558,7 +556,7 @@ static int net_id_adv(struct bt_mesh_subnet *sub) memcpy(proxy_svc_data + 3, sub->keys[SUBNET_KEY_TX_IDX(sub)].net_id, 8); - err = bt_le_adv_start(&slow_adv_param, net_id_ad, + err = bt_le_adv_start(&slow_adv_param, duration, net_id_ad, ARRAY_SIZE(net_id_ad), sd, 0); if (err) { BT_WARN("Failed to advertise using Network ID (err %d)", err); @@ -628,6 +626,7 @@ static int gatt_proxy_advertise(struct bt_mesh_subnet *sub) { int32_t remaining = K_FOREVER; int subnet_count; + int err = -EBUSY; BT_DBG(""); @@ -642,24 +641,6 @@ static int gatt_proxy_advertise(struct bt_mesh_subnet *sub) return -ENOENT; } - if (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING) { - uint32_t active = k_uptime_get_32() - sub->node_id_start; - - if (active < NODE_ID_TIMEOUT) { - remaining = NODE_ID_TIMEOUT - active; - BT_DBG("Node ID active for %u ms, %d ms remaining", - (unsigned) active, (int) remaining); - node_id_adv(sub); - } else { - bt_mesh_proxy_identity_stop(sub); - BT_DBG("Node ID stopped"); - } - } - - if (sub->node_id == BT_MESH_NODE_IDENTITY_STOPPED) { - net_id_adv(sub); - } - subnet_count = sub_count(); BT_DBG("sub_count %u", subnet_count); if (subnet_count > 1) { @@ -678,12 +659,30 @@ static int gatt_proxy_advertise(struct bt_mesh_subnet *sub) } } + if (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING) { + uint32_t active = k_uptime_get_32() - sub->node_id_start; + + if (active < NODE_ID_TIMEOUT) { + remaining = NODE_ID_TIMEOUT - active; + BT_DBG("Node ID active for %u ms, %d ms remaining", + active, remaining); + err = node_id_adv(sub, remaining); + } else { + bt_mesh_proxy_identity_stop(sub); + BT_DBG("Node ID stopped"); + } + } + + if (sub->node_id == BT_MESH_NODE_IDENTITY_STOPPED) { + err = net_id_adv(sub, remaining); + } + BT_DBG("Advertising %d ms for net_idx 0x%04x", (int) remaining, sub->net_idx); beacon_sub = bt_mesh_subnet_next(beacon_sub); - return remaining; + return err; } static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt) @@ -926,9 +925,6 @@ static void gatt_connected(uint16_t conn_handle) conn_count++; - /* Since we use ADV_OPT_ONE_TIME */ - gatt_adv_enabled = false; - /* Try to re-enable advertising in case it's possible */ if (conn_count < CONFIG_BT_MAX_CONN) { bt_mesh_adv_update(); @@ -1234,12 +1230,12 @@ static int proxy_send(uint16_t conn_handle, return err; } -int32_t bt_mesh_proxy_adv_start(void) +int bt_mesh_proxy_adv_start(void) { BT_DBG(""); if (gatt_svc == MESH_GATT_NONE) { - return K_FOREVER; + return -ENOENT; } #if (MYNEWT_VAL(BLE_MESH_PB_GATT)) @@ -1249,30 +1245,32 @@ int32_t bt_mesh_proxy_adv_start(void) ADV_OPT_PROV ADV_FAST_INT }; + struct ble_gap_adv_params slow_adv_param = { + ADV_OPT_PROV + ADV_SLOW_INT + }; struct bt_data prov_sd[1]; size_t prov_sd_len; - - if (prov_fast_adv) { - param = &fast_adv_param; - } else { - struct ble_gap_adv_params slow_adv_param = { - ADV_OPT_PROV - ADV_SLOW_INT - }; - param = &slow_adv_param; - } + int err; prov_sd_len = gatt_prov_adv_create(prov_sd); - - if (bt_le_adv_start(param, prov_ad, ARRAY_SIZE(prov_ad), - prov_sd, prov_sd_len) == 0) { - gatt_adv_enabled = true; - - /* Advertise 60 seconds using fast interval */ - if (prov_fast_adv) { + if (!prov_fast_adv) { + param = &slow_adv_param; + return bt_mesh_adv_start(param, + K_FOREVER, prov_ad, + ARRAY_SIZE(prov_ad), prov_sd, + prov_sd_len); + } else { + param = &fast_adv_param; + err = bt_mesh_adv_start(param, + (60 * MSEC_PER_SEC), prov_ad, + ARRAY_SIZE(prov_ad), prov_sd, + prov_sd_len); + if (!err) { prov_fast_adv = false; - return K_SECONDS(60); } + + return err; } } #endif /* PB_GATT */ @@ -1283,7 +1281,7 @@ int32_t bt_mesh_proxy_adv_start(void) } #endif /* GATT_PROXY */ - return K_FOREVER; + return -ENOTSUP; } @@ -1306,7 +1304,7 @@ static void ble_mesh_handle_connect(struct ble_gap_event *event, void *arg) return; } - proxy_connected(event->adv_complete.conn_handle); + gatt_connected(event->adv_complete.conn_handle); } #else if (event->type == BLE_GAP_EVENT_CONNECT) { @@ -1339,25 +1337,6 @@ int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) return 0; } - -void bt_mesh_proxy_adv_stop(void) -{ - int err; - - BT_DBG("adv_enabled %u", gatt_adv_enabled); - - if (!gatt_adv_enabled) { - return; - } - - err = bt_le_adv_stop(true); - if (err) { - BT_ERR("Failed to stop advertising (err %d)", err); - } else { - gatt_adv_enabled = false; - } -} - static void resolve_svc_handles(void) { int rc; diff --git a/nimble/host/mesh/src/glue.c b/nimble/host/mesh/src/glue.c index 4e4715f2f0..8a9ff39cea 100644 --- a/nimble/host/mesh/src/glue.c +++ b/nimble/host/mesh/src/glue.c @@ -517,6 +517,17 @@ uint32_t k_uptime_get_32(void) return k_uptime_get(); } +int64_t k_uptime_delta(int64_t *reftime) +{ + int64_t uptime, delta; + + uptime = k_uptime_get(); + delta = uptime - *reftime; + *reftime = uptime; + + return delta; +} + void k_sleep(int32_t duration) { uint32_t ticks; @@ -672,6 +683,7 @@ ble_adv_conf_adv_instance(const struct ble_gap_adv_params *param, int *instance) int bt_le_adv_start(const struct ble_gap_adv_params *param, + int64_t duration, const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len) { @@ -737,7 +749,7 @@ bt_le_adv_start(const struct ble_gap_adv_params *param, } /*TODO: We could use duration and max events in the future */ - err = ble_gap_ext_adv_start(instance, 0, 0); + err = ble_gap_ext_adv_start(instance, duration, 0); return err; error: @@ -747,28 +759,11 @@ bt_le_adv_start(const struct ble_gap_adv_params *param, return err; } - -int bt_le_adv_stop(bool proxy) -{ -#if MYNEWT_VAL(BLE_MESH_PROXY) - int rc; - - if (proxy) { - rc = ble_gap_ext_adv_stop(BT_MESH_ADV_GATT_INST); - } else { - rc = ble_gap_ext_adv_stop(BT_MESH_ADV_INST); - } - - return rc; -#else - return ble_gap_ext_adv_stop(BT_MESH_ADV_INST); -#endif -} - #else int bt_le_adv_start(const struct ble_gap_adv_params *param, + int64_t duration, const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len) { @@ -802,7 +797,7 @@ bt_le_adv_start(const struct ble_gap_adv_params *param, } } - err = ble_gap_adv_start(g_mesh_addr_type, NULL, BLE_HS_FOREVER, param, + err = ble_gap_adv_start(g_mesh_addr_type, NULL, duration, param, NULL, NULL); if (err) { BT_ERR("Advertising failed: err %d", err); @@ -812,7 +807,7 @@ bt_le_adv_start(const struct ble_gap_adv_params *param, return 0; } -int bt_le_adv_stop(bool proxy) +int bt_le_adv_stop() { return ble_gap_adv_stop(); } diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c index b4d658f71d..32697c1d1b 100644 --- a/nimble/host/mesh/src/mesh.c +++ b/nimble/host/mesh/src/mesh.c @@ -364,6 +364,14 @@ static void model_start(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, int bt_mesh_start(void) { + int err; + + err = bt_mesh_adv_enable(); + if (err) { + BT_ERR("Failed enabling advertiser"); + return err; + } + if (bt_mesh_beacon_enabled()) { bt_mesh_beacon_enable(); } else { diff --git a/nimble/host/mesh/src/pb_adv.c b/nimble/host/mesh/src/pb_adv.c index 3e136a2070..1fa2c35b24 100644 --- a/nimble/host/mesh/src/pb_adv.c +++ b/nimble/host/mesh/src/pb_adv.c @@ -821,8 +821,16 @@ void bt_mesh_pb_adv_recv(struct os_mbuf *buf) static int prov_link_open(const uint8_t uuid[16], int32_t timeout, const struct prov_bearer_cb *cb, void *cb_data) { + int err; + BT_DBG("uuid %s", bt_hex(uuid, 16)); + err = bt_mesh_adv_enable(); + if (err) { + BT_ERR("Failed enabling advertiser"); + return err; + } + if (atomic_test_and_set_bit(link.flags, ADV_LINK_ACTIVE)) { return -EBUSY; } @@ -842,6 +850,14 @@ static int prov_link_open(const uint8_t uuid[16], int32_t timeout, static int prov_link_accept(const struct prov_bearer_cb *cb, void *cb_data) { + int err; + + err = bt_mesh_adv_enable(); + if (err) { + BT_ERR("Failed enabling advertiser"); + return err; + } + if (atomic_test_bit(link.flags, ADV_LINK_ACTIVE)) { return -EBUSY; } diff --git a/nimble/host/mesh/src/proxy.h b/nimble/host/mesh/src/proxy.h index 7a79cef5e1..cf9cb87a08 100644 --- a/nimble/host/mesh/src/proxy.h +++ b/nimble/host/mesh/src/proxy.h @@ -31,8 +31,7 @@ void bt_mesh_proxy_beacon_send(struct bt_mesh_subnet *sub); struct os_mbuf *bt_mesh_proxy_get_buf(void); -int32_t bt_mesh_proxy_adv_start(void); -void bt_mesh_proxy_adv_stop(void); +int bt_mesh_proxy_adv_start(void); void bt_mesh_proxy_identity_start(struct bt_mesh_subnet *sub); void bt_mesh_proxy_identity_stop(struct bt_mesh_subnet *sub); diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index 3677791a0d..9ca21a7f77 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -232,6 +232,37 @@ syscfg.defs: supported outgoing segment count (BT_MESH_TX_SEG_MAX). value: 6 + BLE_MESH_ADV: + description: > + Advertiser mode + value: 1 + + BLE_MESH_ADV_LEGACY: + description: > + Use legacy advertising commands for mesh sending. Legacy + advertising is significantly slower than the extended advertising, but + is supported by all controllers. + value: 1 + restrictions: + - "BLE_MESH_ADV if 0" + - "!BLE_MESH_ADV_EXT" + + BLE_MESH_ADV_EXT: + description: > + Use extended advertising commands for operating the advertiser. + Extended advertising is faster and uses less memory than legacy + advertising, but isn't supported by all controllers. + value: 0 + restrictions: + - "BLE_MESH_ADV if 0" + - "!BLE_MESH_ADV_LEGACY" + - "BLE_EXT_ADV" + + BLE_MESH_DEBUG_USE_ID_ADDR: + description: > + Use ID address for mesh advertisements, use random address otherwise. + value: 0 + BLE_MESH_ADV_STACK_SIZE: description: > Mesh advertiser thread stack size. From efafc215d1384d2a05320c12abd71f1a1dbc176d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 20 Oct 2021 08:17:15 +0200 Subject: [PATCH 0147/1333] host/mesh: Reconstructing adv callback logic The adv callback logic is reconstructed to coexist with proxy send callback. This is port of a63f2d8d608a249967975628aeaba23684a5aed7 --- nimble/host/mesh/src/adv.h | 25 +++++++++++++++++-------- nimble/host/mesh/src/adv_ext.c | 18 ++++++++++-------- nimble/host/mesh/src/adv_legacy.c | 12 +++++------- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/nimble/host/mesh/src/adv.h b/nimble/host/mesh/src/adv.h index 9412bb0ce9..14be8f84f3 100644 --- a/nimble/host/mesh/src/adv.h +++ b/nimble/host/mesh/src/adv.h @@ -61,7 +61,9 @@ struct bt_mesh_adv { void *cb_data; uint8_t type:2, - busy:1; + started:1, + busy:1; + uint8_t xmit; uint8_t flags; @@ -100,19 +102,26 @@ int bt_mesh_adv_start(const struct ble_gap_adv_params *param, int32_t duration, const struct bt_data *sd, size_t sd_len); static inline void bt_mesh_adv_send_start(uint16_t duration, int err, - const struct bt_mesh_send_cb *cb, - void *cb_data) + struct bt_mesh_adv *adv) { - if (cb && cb->start) { - cb->start(duration, err, cb_data); + if (!adv->started) { + adv->started = 1; + + if (adv->cb && adv->cb->start) { + adv->cb->start(duration, err, adv->cb_data); + } + + if (err) { + adv->cb = NULL; + } } } static inline void bt_mesh_adv_send_end( - int err, const struct bt_mesh_send_cb *cb, void *cb_data) + int err, struct bt_mesh_adv const *adv) { - if (cb && cb->end) { - cb->end(err, cb_data); + if (adv->started && adv->cb && adv->cb->end) { + adv->cb->end(err, adv->cb_data); } } int ble_adv_gap_mesh_cb(struct ble_gap_event *event, void *arg); diff --git a/nimble/host/mesh/src/adv_ext.c b/nimble/host/mesh/src/adv_ext.c index 2dd7d13666..25f31a237e 100644 --- a/nimble/host/mesh/src/adv_ext.c +++ b/nimble/host/mesh/src/adv_ext.c @@ -49,8 +49,7 @@ enum { static struct { ATOMIC_DEFINE(flags, ADV_FLAGS_NUM); struct bt_le_ext_adv *instance; - const struct bt_mesh_send_cb *cb; - void *cb_data; + struct os_mbuf *buf; int64_t timestamp; struct k_work_delayable work; } adv; @@ -103,7 +102,7 @@ ble_mesh_ext_adv_event_handler(struct ble_gap_event *event, void *arg) atomic_clear_bit(adv.flags, ADV_FLAG_ACTIVE); if (!atomic_test_and_clear_bit(adv.flags, ADV_FLAG_PROXY)) { - bt_mesh_adv_send_end(0, adv.cb, adv.cb_data); + net_buf_unref(adv.buf); } schedule_send(); @@ -234,12 +233,12 @@ static int buf_send(struct os_mbuf *buf) atomic_set_bit(adv.flags, ADV_FLAG_UPDATE_PARAMS); } - adv.cb = BT_MESH_ADV(buf)->cb; - adv.cb_data = BT_MESH_ADV(buf)->cb_data; - err = adv_start(&adv_param, duration, &ad, 1, NULL, 0); - net_buf_unref(buf); - bt_mesh_adv_send_start(duration, err, adv.cb, adv.cb_data); + if (!err) { + adv.buf = net_buf_ref(buf); + } + + bt_mesh_adv_send_start(duration, err, BT_MESH_ADV(buf)); return err; } @@ -260,6 +259,9 @@ static void send_pending_adv(struct ble_npl_event *work) BT_MESH_ADV(buf)->busy = 0U; err = buf_send(buf); + + net_buf_unref(buf); + if (!err) { return; /* Wait for advertising to finish */ } diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index c07da896c6..80ea76a915 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -53,8 +53,7 @@ static inline void adv_send(struct os_mbuf *buf) [BT_MESH_ADV_BEACON] = BLE_HS_ADV_TYPE_MESH_BEACON, [BT_MESH_ADV_URI] = BLE_HS_ADV_TYPE_URI, }; - const struct bt_mesh_send_cb *cb = BT_MESH_ADV(buf)->cb; - void *cb_data = BT_MESH_ADV(buf)->cb_data; + struct ble_gap_adv_params param = { 0 }; uint16_t duration, adv_int; struct bt_data ad; @@ -106,8 +105,8 @@ static inline void adv_send(struct os_mbuf *buf) err = bt_le_adv_start(¶m, duration, &ad, 1, NULL, 0); - net_buf_unref(buf); - adv_send_start(duration, err, cb, cb_data); + + bt_mesh_adv_send_start(duration, err, BT_MESH_ADV(buf)); if (err) { BT_ERR("Advertising failed: err %d", err); return; @@ -118,7 +117,6 @@ static inline void adv_send(struct os_mbuf *buf) k_sleep(K_MSEC(duration)); err = bt_le_adv_stop(); - bt_mesh_adv_send_end(err, cb, cb_data); if (err) { BT_ERR("Stopping advertising failed: err %d", err); return; @@ -167,10 +165,10 @@ adv_thread(void *args) if (BT_MESH_ADV(buf)->busy) { BT_MESH_ADV(buf)->busy = 0; adv_send(buf); - } else { - net_buf_unref(buf); } + net_buf_unref(buf); + /* os_sched(NULL); */ } } From 2f5ce02fb9c0dc13f4104742e821362aed995536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 21 Oct 2021 13:05:01 +0200 Subject: [PATCH 0148/1333] host/mesh: Split gatt services to pb-gatt and proxy Split gatt services to pb-gatt-srv and proxy-srv. This is port of b2889903a3afb65bf88e82637452c14c59661a83 and c057a69a2c7bdbb9b2162d8f041411d13c238b37 --- nimble/host/mesh/include/mesh/glue.h | 1 + nimble/host/mesh/src/adv_ext.c | 21 +- nimble/host/mesh/src/adv_legacy.c | 12 +- nimble/host/mesh/src/glue.c | 28 + nimble/host/mesh/src/mesh.c | 12 +- nimble/host/mesh/src/pb_gatt.c | 11 +- nimble/host/mesh/src/pb_gatt_srv.c | 447 ++++++++++++++ nimble/host/mesh/src/pb_gatt_srv.h | 26 + nimble/host/mesh/src/prov_device.c | 3 +- nimble/host/mesh/src/proxy.h | 42 +- nimble/host/mesh/src/proxy_msg.h | 5 + .../mesh/src/{gatt_services.c => proxy_srv.c} | 552 ++---------------- nimble/host/mesh/src/settings.c | 3 +- nimble/host/mesh/syscfg.yml | 4 +- 14 files changed, 636 insertions(+), 531 deletions(-) create mode 100644 nimble/host/mesh/src/pb_gatt_srv.c create mode 100644 nimble/host/mesh/src/pb_gatt_srv.h rename nimble/host/mesh/src/{gatt_services.c => proxy_srv.c} (60%) diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index 422f2b8018..588e79a487 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -406,6 +406,7 @@ typedef void (*bt_dh_key_cb_t)(const uint8_t key[BT_DH_KEY_LEN]); int bt_dh_key_gen(const uint8_t remote_pk[BT_PUB_KEY_LEN], bt_dh_key_cb_t cb); int bt_pub_key_gen(struct bt_pub_key_cb *new_cb); uint8_t *bt_pub_key_get(void); +void bt_conn_get_info(struct ble_hs_conn *conn, struct ble_gap_conn_desc *desc); int bt_rand(void *buf, size_t len); const char * bt_hex(const void *buf, size_t len); int bt_encrypt_be(const uint8_t *key, const uint8_t *plaintext, uint8_t *enc_data); diff --git a/nimble/host/mesh/src/adv_ext.c b/nimble/host/mesh/src/adv_ext.c index 25f31a237e..364fb249b3 100644 --- a/nimble/host/mesh/src/adv_ext.c +++ b/nimble/host/mesh/src/adv_ext.c @@ -14,6 +14,7 @@ #include "adv.h" #include "net.h" #include "proxy.h" +#include "pb_gatt_srv.h" #include "syscfg/syscfg.h" #include "host/ble_gap.h" @@ -267,13 +268,23 @@ static void send_pending_adv(struct ble_npl_event *work) } } + if (!MYNEWT_VAL(BLE_MESH_GATT_SERVER)) { + return; + } + /* No more pending buffers */ - if (MYNEWT_VAL(BLE_MESH_GATT_SERVER)) { - BT_DBG("Proxy Advertising"); - err = bt_mesh_proxy_adv_start(); - if (!err) { - atomic_set_bit(adv.flags, ADV_FLAG_PROXY); + if (bt_mesh_is_provisioned()) { + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { + err = bt_mesh_pb_gatt_adv_start(); + BT_DBG("Proxy Advertising"); } + } else if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { + err = bt_mesh_prov_adv_start(); + BT_DBG("PB-GATT Advertising"); + } + + if (!err) { + atomic_set_bit(adv.flags, ADV_FLAG_PROXY); } } diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index 80ea76a915..9506c08baf 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -16,6 +16,7 @@ #include "beacon.h" #include "prov.h" #include "proxy.h" +#include "pb_gatt_srv.h" #if MYNEWT_VAL(BLE_MESH_ADV_LEGACY) /* Convert from ms to 0.625ms units */ @@ -140,8 +141,15 @@ adv_thread(void *args) #if (MYNEWT_VAL(BLE_MESH_PROXY)) ev = ble_npl_eventq_get(&adv_queue, 0); while (!ev) { - timeout = bt_mesh_proxy_adv_start(); - BT_DBG("Proxy Advertising up to %d ms", (int) timeout); + if (bt_mesh_is_provisioned()) { + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { + timeout = bt_mesh_proxy_adv_start(); + BT_DBG("Proxy Advertising up to %d ms", (int) timeout); + } + } else if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { + timeout = bt_mesh_pb_gatt_adv_start(); + BT_DBG("PB-GATT Advertising up to %d ms", (int) timeout); + } // FIXME: should we redefine K_SECONDS macro instead in glue? if (timeout != K_FOREVER) { diff --git a/nimble/host/mesh/src/glue.c b/nimble/host/mesh/src/glue.c index 8a9ff39cea..80f9b7e75e 100644 --- a/nimble/host/mesh/src/glue.c +++ b/nimble/host/mesh/src/glue.c @@ -22,6 +22,7 @@ #include "mesh/glue.h" #include "adv.h" +#include "../src/ble_hs_conn_priv.h" #ifndef MYNEWT #include "nimble/nimble_port.h" #endif @@ -555,6 +556,33 @@ bt_dh_key_gen(const uint8_t remote_pk[64], bt_dh_key_cb_t cb) return 0; } +void +bt_conn_get_info(struct ble_hs_conn *conn, + struct ble_gap_conn_desc *desc) +{ + struct ble_hs_conn_addrs addrs; + + ble_hs_conn_addrs(conn, &addrs); + + desc->our_id_addr = addrs.our_id_addr; + desc->peer_id_addr = addrs.peer_id_addr; + desc->our_ota_addr = addrs.our_ota_addr; + desc->peer_ota_addr = addrs.peer_ota_addr; + + desc->conn_handle = conn->bhc_handle; + desc->conn_itvl = conn->bhc_itvl; + desc->conn_latency = conn->bhc_latency; + desc->supervision_timeout = conn->bhc_supervision_timeout; + desc->master_clock_accuracy = conn->bhc_master_clock_accuracy; + desc->sec_state = conn->bhc_sec_state; + + if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) { + desc->role = BLE_GAP_ROLE_MASTER; + } else { + desc->role = BLE_GAP_ROLE_SLAVE; + } +} + int bt_rand(void *buf, size_t len) { diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c index 32697c1d1b..1ac4d02641 100644 --- a/nimble/host/mesh/src/mesh.c +++ b/nimble/host/mesh/src/mesh.c @@ -35,6 +35,7 @@ #include "shell.h" #include "mesh_priv.h" #include "settings.h" +#include "pb_gatt_srv.h" uint8_t g_mesh_addr_type; @@ -315,7 +316,7 @@ int bt_mesh_init(uint8_t own_addr_type, const struct bt_mesh_prov *prov, return err; } -#if (MYNEWT_VAL(BLE_MESH_PROXY)) +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) bt_mesh_proxy_init(); #endif @@ -378,14 +379,13 @@ int bt_mesh_start(void) bt_mesh_beacon_disable(); } - /* For PB-GATT provision, will enable in le disconnect handler. */ - if (bt_mesh_prov_link.bearer->type == BT_MESH_PROV_ADV) { + if (!IS_ENABLED(CONFIG_BT_MESH_PROV) || !bt_mesh_prov_active() || + bt_mesh_prov_link.bearer->type == BT_MESH_PROV_ADV) { if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { - (void)bt_mesh_proxy_prov_disable(); + (void)bt_mesh_pb_gatt_disable(); } - if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && - bt_mesh_gatt_proxy_get() != BT_MESH_GATT_PROXY_NOT_SUPPORTED) { + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { (void)bt_mesh_proxy_gatt_enable(); bt_mesh_adv_update(); } diff --git a/nimble/host/mesh/src/pb_gatt.c b/nimble/host/mesh/src/pb_gatt.c index fb04963219..761ebb0a54 100644 --- a/nimble/host/mesh/src/pb_gatt.c +++ b/nimble/host/mesh/src/pb_gatt.c @@ -6,6 +6,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ + #define MESH_LOG_MODULE BLE_MESH_PROV_LOG #include "mesh/mesh.h" @@ -14,7 +15,10 @@ #include "proxy.h" #include "adv.h" #include "prov.h" +#include "syscfg/syscfg.h" +#include "pb_gatt_srv.h" +#if MYNEWT_VAL(BLE_MESH_PB_GATT) struct prov_bearer_send_cb { prov_bearer_send_complete_t cb; void *cb_data; @@ -45,7 +49,7 @@ static void reset_state(void) /* If this fails, the protocol timeout handler will exit early. */ (void)k_work_cancel_delayable(&link.prot_timer); - link.rx.buf = bt_mesh_proxy_get_buf(); + link.rx.buf = bt_mesh_pb_gatt_get_buf(); } static void link_closed(enum prov_bearer_link_status status) @@ -127,7 +131,7 @@ int bt_mesh_pb_gatt_close(uint16_t conn_handle) static int link_accept(const struct prov_bearer_cb *cb, void *cb_data) { - (void)bt_mesh_proxy_prov_enable(); + (void)bt_mesh_pb_gatt_enable(); bt_mesh_adv_update(); link.cb = cb; @@ -177,4 +181,5 @@ const struct prov_bearer pb_gatt = { .link_accept = link_accept, .send = buf_send, .clear_tx = clear_tx, -}; \ No newline at end of file +}; +#endif \ No newline at end of file diff --git a/nimble/host/mesh/src/pb_gatt_srv.c b/nimble/host/mesh/src/pb_gatt_srv.c new file mode 100644 index 0000000000..7cb3257ccd --- /dev/null +++ b/nimble/host/mesh/src/pb_gatt_srv.c @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2017 Intel Corporation + * Copyright (c) 2021 Lingao Meng + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define MESH_LOG_MODULE BLE_MESH_PROV_LOG + +#include "mesh_priv.h" +#include "adv.h" +#include "net.h" +#include "rpl.h" +#include "transport.h" +#include "prov.h" +#include "beacon.h" +#include "foundation.h" +#include "access.h" +#include "proxy.h" +#include "proxy_msg.h" +#include "pb_gatt_srv.h" +#include "syscfg/syscfg.h" +#include "services/gatt/ble_svc_gatt.h" +#include "../../host/src/ble_hs_priv.h" + +#if MYNEWT_VAL(BLE_MESH_PB_GATT) +#define CLIENT_BUF_SIZE 66 + +/** @def BT_UUID_MESH_PROV + * @brief Mesh Provisioning Service + */ +ble_uuid16_t BT_UUID_MESH_PROV = BLE_UUID16_INIT(0x1827); +#define BT_UUID_MESH_PROV_VAL 0x1827 +/** @def BT_UUID_MESH_PROXY + * @brief Mesh Proxy Service + */ +ble_uuid16_t BT_UUID_MESH_PROXY = BLE_UUID16_INIT(0x1828); +#define BT_UUID_MESH_PROXY_VAL 0x1828 +/** @def BT_UUID_GATT_CCC + * @brief GATT Client Characteristic Configuration + */ +ble_uuid16_t BT_UUID_GATT_CCC = BLE_UUID16_INIT(0x2902); +#define BT_UUID_GATT_CCC_VAL 0x2902 +/** @def BT_UUID_MESH_PROV_DATA_IN + * @brief Mesh Provisioning Data In + */ +ble_uuid16_t BT_UUID_MESH_PROV_DATA_IN = BLE_UUID16_INIT(0x2adb); +#define BT_UUID_MESH_PROV_DATA_IN_VAL 0x2adb +/** @def BT_UUID_MESH_PROV_DATA_OUT + * @brief Mesh Provisioning Data Out + */ +ble_uuid16_t BT_UUID_MESH_PROV_DATA_OUT = BLE_UUID16_INIT(0x2adc); +#define BT_UUID_MESH_PROV_DATA_OUT_VAL 0x2adc +/** @def BT_UUID_MESH_PROXY_DATA_IN + * @brief Mesh Proxy Data In + */ +ble_uuid16_t BT_UUID_MESH_PROXY_DATA_IN = BLE_UUID16_INIT(0x2add); +#define BT_UUID_MESH_PROXY_DATA_IN_VAL 0x2add +/** @def BT_UUID_MESH_PROXY_DATA_OUT + * @brief Mesh Proxy Data Out + */ +ble_uuid16_t BT_UUID_MESH_PROXY_DATA_OUT = BLE_UUID16_INIT(0x2ade); +#define BT_UUID_MESH_PROXY_DATA_OUT_VAL 0x2ade +#define BT_UUID_16_ENCODE(w16) \ + (((w16) >> 0) & 0xFF), \ + (((w16) >> 8) & 0xFF) + +static bool prov_fast_adv; + +static struct { + uint16_t proxy_h; + uint16_t proxy_data_out_h; + uint16_t prov_h; + uint16_t prov_data_in_h; + uint16_t prov_data_out_h; +} svc_handles; + +static int gatt_send(uint16_t conn_handle, + const void *data, uint16_t len, + void (*end)(uint16_t, void *), void *user_data); + +static struct bt_mesh_proxy_role cli = { + .cb.send = gatt_send, +}; + +static bool service_registered; + +static ssize_t gatt_recv(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + const uint8_t *data = ctxt->om->om_data; + uint16_t len = ctxt->om->om_len; + + + if (conn_handle != cli.conn_handle) { + return -ENOTCONN; + } + + if (len < 1) { + BT_WARN("Too small Proxy PDU"); + return -EINVAL; + } + + if (PDU_TYPE(data) == BT_MESH_PROXY_PROV) { + BT_WARN("Proxy PDU type doesn't match GATT service"); + return -EINVAL; + } + + return bt_mesh_proxy_msg_recv(&cli, data, len); +} + +void gatt_connected_pb_gatt(uint16_t conn_handle, uint8_t err) +{ + struct ble_gap_conn_desc info; + struct ble_hs_conn *conn; + + conn = ble_hs_conn_find(conn_handle); + bt_conn_get_info(conn, &info); + if (info.role != BLE_GAP_ROLE_SLAVE || + !service_registered || bt_mesh_is_provisioned()) { + return; + } + + cli.conn_handle = conn_handle; + + BT_DBG("conn %p err 0x%02x", (void *)conn, err); + + net_buf_simple_reset(cli.buf); +} + +void gatt_disconnected_pb_gatt(uint16_t conn_handle, uint8_t reason) +{ + struct ble_gap_conn_desc info; + + struct ble_hs_conn *conn; + + conn = ble_hs_conn_find(conn_handle); + bt_conn_get_info(conn, &info); + if (info.role != BLE_GAP_ROLE_SLAVE || + !service_registered) { + return; + } + + if (cli.conn_handle != conn_handle) { + BT_WARN("No PB-GATT Client found"); + return; + } + + BT_DBG("conn %p reason 0x%02x", (void *)conn, reason); + + bt_mesh_pb_gatt_close(conn_handle); + + if (bt_mesh_is_provisioned()) { + (void)bt_mesh_pb_gatt_disable(); + + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { + (void)bt_mesh_proxy_gatt_enable(); + } + } + + cli.conn_handle = BLE_HS_CONN_HANDLE_NONE; + + bt_mesh_adv_update(); +} + +int prov_ccc_write(uint16_t conn_handle, uint8_t type) +{ + if (cli.conn_handle != conn_handle) { + BT_ERR("No PB-GATT Client found"); + return -ENOTCONN; + } + + if (type != BLE_GAP_EVENT_NOTIFY_RX) { + BT_WARN("Client wrote instead enabling notify"); + return BT_GATT_ERR(EINVAL); + } + + bt_mesh_pb_gatt_open(conn_handle); + + return 0; +} + +/* Mesh Provisioning Service Declaration */ +struct os_mbuf *bt_mesh_pb_gatt_get_buf(void) +{ + struct os_mbuf *buf = cli.buf; + + if (buf != NULL) { + net_buf_simple_init(buf, 0); + } + + return buf; +} + +static int +dummy_access_cb(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + /* + * We should never never enter this callback - it's attached to notify-only + * characteristic which are notified directly from mbuf. And we can't pass + * NULL as access_cb because gatts will assert on init... + */ + BLE_HS_DBG_ASSERT(0); + return 0; +} + +static const struct ble_gatt_svc_def svc_defs [] = { + { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), + .characteristics = (struct ble_gatt_chr_def[]) { { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_IN_VAL), + .access_cb = gatt_recv, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + }, { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL), + .access_cb = dummy_access_cb, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + .characteristics = (struct ble_gatt_chr_def[]) { { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL), + .access_cb = gatt_recv, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + }, { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL), + .access_cb = dummy_access_cb, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, { + 0, /* No more services. */ + }, +}; + +void resolve_svc_handles(void) +{ + int rc; + + /* Either all handles are already resolved, or none of them */ + if (svc_handles.prov_data_out_h) { + return; + } + + /* + * We assert if attribute is not found since at this stage all attributes + * shall be already registered and thus shall be found. + */ + + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), + &svc_handles.proxy_h); + assert(rc == 0); + + rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), + BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL), + NULL, &svc_handles.proxy_data_out_h); + assert(rc == 0); + + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + &svc_handles.prov_h); + assert(rc == 0); + + rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL), + NULL, &svc_handles.prov_data_in_h); + assert(rc == 0); + + rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL), + NULL, &svc_handles.prov_data_out_h); + assert(rc == 0); +} + + +int bt_mesh_proxy_svcs_register(void) +{ + int rc; + + rc = ble_gatts_count_cfg(svc_defs); + assert(rc == 0); + + rc = ble_gatts_add_svcs(svc_defs); + assert(rc == 0); + + return 0; +} + +int bt_mesh_pb_gatt_enable(void) +{ + int rc; + uint16_t handle; + BT_DBG(""); + + if (bt_mesh_is_provisioned()) { + return -ENOTSUP; + } + + if (service_registered) { + return -EBUSY; + } + + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle); + assert(rc == 0); + ble_gatts_svc_set_visibility(handle, 1); + /* FIXME: figure out end handle */ + ble_svc_gatt_changed(svc_handles.prov_h, 0xffff); + + service_registered = true; + prov_fast_adv = true; + + return 0; +} + +int bt_mesh_pb_gatt_disable(void) +{ + uint16_t handle; + int rc; + + BT_DBG(""); + + if (!service_registered) { + return -EALREADY; + } + + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle); + assert(rc == 0); + ble_gatts_svc_set_visibility(handle, 0); + /* FIXME: figure out end handle */ + ble_svc_gatt_changed(svc_handles.prov_h, 0xffff); + service_registered = false; + + bt_mesh_adv_update(); + + return 0; +} + +static uint8_t prov_svc_data[20] = { + BT_UUID_16_ENCODE(BT_UUID_MESH_PROV_VAL), +}; + +static const struct bt_data prov_ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA_BYTES(BT_DATA_UUID16_ALL, + BT_UUID_16_ENCODE(BT_UUID_MESH_PROV_VAL)), + BT_DATA(BT_DATA_SVC_DATA16, prov_svc_data, sizeof(prov_svc_data)), +}; + +int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, + void (*end)(uint16_t, void *), void *user_data) +{ + if (cli.conn_handle != conn_handle) { + BT_ERR("No PB-GATT Client found"); + return -ENOTCONN; + } + + return bt_mesh_proxy_msg_send(&cli, BT_MESH_PROXY_PROV, buf, end, user_data); +} + +static size_t gatt_prov_adv_create(struct bt_data prov_sd[1]) +{ + const struct bt_mesh_prov *prov = bt_mesh_prov_get(); + size_t uri_len; + + memcpy(prov_svc_data + 2, prov->uuid, 16); + sys_put_be16(prov->oob_info, prov_svc_data + 18); + + if (!prov->uri) { + return 0; + } + + uri_len = strlen(prov->uri); + if (uri_len > 29) { + /* There's no way to shorten an URI */ + BT_WARN("Too long URI to fit advertising packet"); + return 0; + } + + prov_sd[0].type = BT_DATA_URI; + prov_sd[0].data_len = uri_len; + prov_sd[0].data = (const uint8_t *)prov->uri; + + return 1; +} + +static int gatt_send(uint16_t conn_handle, + const void *data, uint16_t len, + void (*end)(uint16_t, void *), void *user_data) +{ + struct os_mbuf *om; + int err = 0; + + BT_DBG("%u bytes: %s", len, bt_hex(data, len)); + om = ble_hs_mbuf_from_flat(data, len); + assert(om); + err = ble_gattc_notify_custom(conn_handle, svc_handles.prov_data_out_h, om); + /* We do not pass cb into ble_gattc_notify_custom - execute it at the end */ + + end(conn_handle, user_data); + + return err; +} + +int bt_mesh_pb_gatt_adv_start(void) +{ + BT_DBG(""); + + if (!service_registered || bt_mesh_is_provisioned()) { + return -ENOTSUP; + } + + struct ble_gap_adv_params fast_adv_param = { + ADV_OPT_PROV + ADV_FAST_INT + }; + struct bt_data prov_sd[1]; + size_t prov_sd_len; + int err; + + prov_sd_len = gatt_prov_adv_create(prov_sd); + + if (!prov_fast_adv) { + struct ble_gap_adv_params slow_adv_param = { + ADV_OPT_PROV + ADV_SLOW_INT + }; + + return bt_mesh_adv_start(&slow_adv_param, K_FOREVER, prov_ad, + ARRAY_SIZE(prov_ad), prov_sd, prov_sd_len); + } + + /* Advertise 60 seconds using fast interval */ + err = bt_mesh_adv_start(&fast_adv_param, (60 * MSEC_PER_SEC), + prov_ad, ARRAY_SIZE(prov_ad), + prov_sd, prov_sd_len); + if (!err) { + prov_fast_adv = false; + } + + return err; +} +#endif \ No newline at end of file diff --git a/nimble/host/mesh/src/pb_gatt_srv.h b/nimble/host/mesh/src/pb_gatt_srv.h new file mode 100644 index 0000000000..561f2225e9 --- /dev/null +++ b/nimble/host/mesh/src/pb_gatt_srv.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2017 Intel Corporation + * Copyright (c) 2021 Lingao Meng + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __PB_GATT_SRV_H__ +#define __PB_GATT_SRV_H__ + +int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, + void (*end)(uint16_t, void *), void *user_data); + +int bt_mesh_pb_gatt_enable(void); +int bt_mesh_pb_gatt_disable(void); + +struct os_mbuf *bt_mesh_pb_gatt_get_buf(void); + +int prov_ccc_write(uint16_t conn_handle, uint8_t type); +void gatt_disconnected_pb_gatt(uint16_t conn_handle, uint8_t err); +void gatt_connected_pb_gatt(uint16_t conn_handle, uint8_t err); +void resolve_svc_handles(void); + +int bt_mesh_pb_gatt_adv_start(void); + +#endif /* __PB_GATT_SRV_H__ */ \ No newline at end of file diff --git a/nimble/host/mesh/src/prov_device.c b/nimble/host/mesh/src/prov_device.c index 312ecc514b..9d48547e3d 100644 --- a/nimble/host/mesh/src/prov_device.c +++ b/nimble/host/mesh/src/prov_device.c @@ -21,6 +21,7 @@ #include "proxy.h" #include "prov.h" #include "settings.h" +#include "pb_gatt_srv.h" static void send_pub_key(void); static void pub_key_ready(const uint8_t *pkey); @@ -626,7 +627,7 @@ int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers) if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && (bearers & BT_MESH_PROV_GATT)) { - (void)bt_mesh_proxy_prov_disable(); + (void)bt_mesh_pb_gatt_disable(); } return 0; diff --git a/nimble/host/mesh/src/proxy.h b/nimble/host/mesh/src/proxy.h index cf9cb87a08..196f540b2e 100644 --- a/nimble/host/mesh/src/proxy.h +++ b/nimble/host/mesh/src/proxy.h @@ -6,22 +6,36 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROXY_H_ -#define ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROXY_H_ +#ifndef __PROXY_H__ +#define __PROXY_H__ -#define BT_MESH_PROXY_NET_PDU 0x00 -#define BT_MESH_PROXY_BEACON 0x01 -#define BT_MESH_PROXY_CONFIG 0x02 -#define BT_MESH_PROXY_PROV 0x03 +#if CONFIG_BT_MESH_DEBUG_USE_ID_ADDR +#define ADV_OPT_USE_IDENTITY BT_LE_ADV_OPT_USE_IDENTITY +#else +#define ADV_OPT_USE_IDENTITY 0 +#endif -#include "mesh/mesh.h" -#include "mesh/slist.h" +#if CONFIG_BT_MESH_PROXY_USE_DEVICE_NAME +#define ADV_OPT_USE_NAME BT_LE_ADV_OPT_USE_NAME +#else +#define ADV_OPT_USE_NAME 0 +#endif -int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, - void (*end)(uint16_t, void *), void *user_data); +#define ADV_OPT_PROV \ +.conn_mode = (BLE_GAP_CONN_MODE_UND), \ +.disc_mode = (BLE_GAP_DISC_MODE_GEN), -int bt_mesh_proxy_prov_enable(void); -int bt_mesh_proxy_prov_disable(void); +#define ADV_OPT_PROXY \ +.conn_mode = (BLE_GAP_CONN_MODE_UND), \ +.disc_mode = (BLE_GAP_DISC_MODE_GEN), + +#define ADV_SLOW_INT \ +.itvl_min = BT_GAP_ADV_SLOW_INT_MIN, \ +.itvl_max = BT_GAP_ADV_SLOW_INT_MAX, + +#define ADV_FAST_INT \ +.itvl_min = BT_GAP_ADV_FAST_INT_MIN_2, \ +.itvl_max = BT_GAP_ADV_FAST_INT_MAX_2, int bt_mesh_proxy_gatt_enable(void); int bt_mesh_proxy_gatt_disable(void); @@ -29,8 +43,6 @@ void bt_mesh_proxy_gatt_disconnect(void); void bt_mesh_proxy_beacon_send(struct bt_mesh_subnet *sub); -struct os_mbuf *bt_mesh_proxy_get_buf(void); - int bt_mesh_proxy_adv_start(void); void bt_mesh_proxy_identity_start(struct bt_mesh_subnet *sub); @@ -43,4 +55,4 @@ int bt_mesh_proxy_init(void); int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg); -#endif /* ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROXY_H_ */ +#endif /* __PROXY_H__ */ diff --git a/nimble/host/mesh/src/proxy_msg.h b/nimble/host/mesh/src/proxy_msg.h index 2a9f046c99..662fadb8f5 100644 --- a/nimble/host/mesh/src/proxy_msg.h +++ b/nimble/host/mesh/src/proxy_msg.h @@ -16,6 +16,11 @@ #define CFG_FILTER_REMOVE 0x02 #define CFG_FILTER_STATUS 0x03 +#define BT_MESH_PROXY_NET_PDU 0x00 +#define BT_MESH_PROXY_BEACON 0x01 +#define BT_MESH_PROXY_CONFIG 0x02 +#define BT_MESH_PROXY_PROV 0x03 + #define PDU_HDR(sar, type) (sar << 6 | (type & BIT_MASK(6))) typedef int (*proxy_send_cb_t)(uint16_t conn_handle, diff --git a/nimble/host/mesh/src/gatt_services.c b/nimble/host/mesh/src/proxy_srv.c similarity index 60% rename from nimble/host/mesh/src/gatt_services.c rename to nimble/host/mesh/src/proxy_srv.c index 40909b6964..de096d07a7 100644 --- a/nimble/host/mesh/src/gatt_services.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -24,82 +24,14 @@ #include "access.h" #include "proxy.h" #include "proxy_msg.h" +#include "pb_gatt_srv.h" + +#define BT_UUID_MESH_PROXY_VAL 0x1828 +#define CLIENT_BUF_SIZE 66 #define BT_UUID_16_ENCODE(w16) \ (((w16) >> 0) & 0xFF), \ (((w16) >> 8) & 0xFF) -/* Mesh Profile 1.0 Section 6.6: - * "The timeout for the SAR transfer is 20 seconds. When the timeout - * expires, the Proxy Server shall disconnect." - */ -#define PROXY_SAR_TIMEOUT K_SECONDS(20) - -#define CLIENT_BUF_SIZE 65 - - -/** @def BT_UUID_MESH_PROV - * @brief Mesh Provisioning Service - */ -ble_uuid16_t BT_UUID_MESH_PROV = BLE_UUID16_INIT(0x1827); -#define BT_UUID_MESH_PROV_VAL 0x1827 -/** @def BT_UUID_MESH_PROXY - * @brief Mesh Proxy Service - */ -ble_uuid16_t BT_UUID_MESH_PROXY = BLE_UUID16_INIT(0x1828); -#define BT_UUID_MESH_PROXY_VAL 0x1828 -/** @def BT_UUID_GATT_CCC - * @brief GATT Client Characteristic Configuration - */ -ble_uuid16_t BT_UUID_GATT_CCC = BLE_UUID16_INIT(0x2902); -#define BT_UUID_GATT_CCC_VAL 0x2902 -/** @def BT_UUID_MESH_PROV_DATA_IN - * @brief Mesh Provisioning Data In - */ -ble_uuid16_t BT_UUID_MESH_PROV_DATA_IN = BLE_UUID16_INIT(0x2adb); -#define BT_UUID_MESH_PROV_DATA_IN_VAL 0x2adb -/** @def BT_UUID_MESH_PROV_DATA_OUT - * @brief Mesh Provisioning Data Out - */ -ble_uuid16_t BT_UUID_MESH_PROV_DATA_OUT = BLE_UUID16_INIT(0x2adc); -#define BT_UUID_MESH_PROV_DATA_OUT_VAL 0x2adc -/** @def BT_UUID_MESH_PROXY_DATA_IN - * @brief Mesh Proxy Data In - */ -ble_uuid16_t BT_UUID_MESH_PROXY_DATA_IN = BLE_UUID16_INIT(0x2add); -#define BT_UUID_MESH_PROXY_DATA_IN_VAL 0x2add -/** @def BT_UUID_MESH_PROXY_DATA_OUT - * @brief Mesh Proxy Data Out - */ -ble_uuid16_t BT_UUID_MESH_PROXY_DATA_OUT = BLE_UUID16_INIT(0x2ade); -#define BT_UUID_MESH_PROXY_DATA_OUT_VAL 0x2ade - -#if CONFIG_BT_MESH_DEBUG_USE_ID_ADDR -#define ADV_OPT_USE_IDENTITY BT_LE_ADV_OPT_USE_IDENTITY -#else -#define ADV_OPT_USE_IDENTITY 0 -#endif - -#if CONFIG_BT_MESH_PROXY_USE_DEVICE_NAME -#define ADV_OPT_USE_NAME BT_LE_ADV_OPT_USE_NAME -#else -#define ADV_OPT_USE_NAME 0 -#endif - -#define ADV_OPT_PROV \ -.conn_mode = (BLE_GAP_CONN_MODE_UND), \ -.disc_mode = (BLE_GAP_DISC_MODE_GEN), - -#define ADV_OPT_PROXY \ -.conn_mode = (BLE_GAP_CONN_MODE_UND), \ -.disc_mode = (BLE_GAP_DISC_MODE_GEN), - -#define ADV_SLOW_INT \ -.itvl_min = BT_GAP_ADV_SLOW_INT_MIN, \ -.itvl_max = BT_GAP_ADV_SLOW_INT_MAX, - -#define ADV_FAST_INT \ -.itvl_min = BT_GAP_ADV_FAST_INT_MIN_2, \ -.itvl_max = BT_GAP_ADV_FAST_INT_MAX_2, static struct { uint16_t proxy_h; @@ -109,23 +41,14 @@ static struct { uint16_t prov_data_out_h; } svc_handles; -#if MYNEWT_VAL(BLE_MESH_GATT_PROXY) static void proxy_send_beacons(struct ble_npl_event *work); static void proxy_filter_recv(uint16_t conn_handle, struct bt_mesh_net_rx *rx, struct os_mbuf *buf); -#endif /* CONFIG_BT_MESH_GATT_PROXY */ - -#if MYNEWT_VAL(BLE_MESH_PB_GATT) -static bool prov_fast_adv; -#endif /* CONFIG_BT_MESH_PB_GATT */ static int proxy_send(uint16_t conn_handle, const void *data, uint16_t len, void (*end)(uint16_t, void *), void *user_data); -#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) - static bool prov_fast_adv; -#endif static struct bt_mesh_proxy_client { struct bt_mesh_proxy_role cli; @@ -136,28 +59,17 @@ static struct bt_mesh_proxy_client { REJECT, PROV, } filter_type; -#if MYNEWT_VAL(BLE_MESH_GATT_PROXY) struct ble_npl_callout send_beacons; -#endif /* CONFIG_BT_MESH_GATT_PROXY */ } clients[CONFIG_BT_MAX_CONN] = { [0 ... (CONFIG_BT_MAX_CONN - 1)] = { .cli.cb = { .send = proxy_send, -#if MYNEWT_VAL(BLE_MESH_GATT_PROXY) .recv = proxy_filter_recv, -#endif /* CONFIG_BT_MESH_GATT_PROXY */ }, }, }; -//static uint8_t __noinit client_buf_data[CLIENT_BUF_SIZE * CONFIG_BT_MAX_CONN]; - -/* Track which service is enabled */ -static enum { - MESH_GATT_NONE, - MESH_GATT_PROV, - MESH_GATT_PROXY, -} gatt_svc = MESH_GATT_NONE; +static bool service_registered; static int conn_count; @@ -174,37 +86,6 @@ static struct bt_mesh_proxy_client *find_client(uint16_t conn_handle) return NULL; } -#define ATTR_IS_PROV(attr) (attr->user_data != NULL) - -static ssize_t gatt_recv(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, void *arg) -{ - struct bt_mesh_proxy_client *client = find_client(conn_handle); - const uint8_t *data = ctxt->om->om_data; - uint16_t len = ctxt->om->om_len; - - client = find_client(conn_handle); - - if (!client) { - return -ENOTCONN; - } - - if (len < 1) { - BT_WARN("Too small Proxy PDU"); - return -EINVAL; - } - - if ((attr_handle == svc_handles.prov_data_in_h) != - (PDU_TYPE(data) == BT_MESH_PROXY_PROV)) { - BT_WARN("Proxy PDU type doesn't match GATT service"); - return -EINVAL; - } - - return bt_mesh_proxy_msg_recv(&client->cli, data, len); -} - - -#if defined(CONFIG_BT_MESH_GATT_PROXY) /* Next subnet in queue to be advertised */ static struct bt_mesh_subnet *beacon_sub; @@ -720,11 +601,11 @@ int bt_mesh_proxy_gatt_enable(void) BT_DBG(""); - if (gatt_svc == MESH_GATT_PROXY) { - return -EALREADY; + if (bt_mesh_is_provisioned()) { + return -ENOTSUP; } - if (gatt_svc != MESH_GATT_NONE) { + if (service_registered) { return -EBUSY; } @@ -734,7 +615,7 @@ int bt_mesh_proxy_gatt_enable(void) /* FIXME: figure out end handle */ ble_svc_gatt_changed(svc_handles.proxy_h, 0xffff); - gatt_svc = MESH_GATT_PROXY; + service_registered = true; for (i = 0; i < ARRAY_SIZE(clients); i++) { if (clients[i].cli.conn_handle != BLE_HS_CONN_HANDLE_NONE) { @@ -771,14 +652,10 @@ int bt_mesh_proxy_gatt_disable(void) int rc; BT_DBG(""); - if (gatt_svc == MESH_GATT_NONE) { + if (!service_registered) { return -EALREADY; } - if (gatt_svc != MESH_GATT_PROXY) { - return -EBUSY; - } - bt_mesh_proxy_gatt_disconnect(); rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), &handle); @@ -786,7 +663,7 @@ int bt_mesh_proxy_gatt_disable(void) ble_gatts_svc_set_visibility(handle, 0); /* FIXME: figure out end handle */ ble_svc_gatt_changed(svc_handles.proxy_h, 0xffff); - gatt_svc = MESH_GATT_NONE; + service_registered = false; return 0; } @@ -865,11 +742,6 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) continue; } - if (client->filter_type == PROV) { - BT_ERR("Invalid PDU type for Proxy Client"); - return -EINVAL; - } - /* Proxy PDU sending modifies the original buffer, * so we need to make a copy. */ @@ -915,12 +787,19 @@ static void proxy_sar_timeout(struct ble_npl_event *work) assert(rc == 0); } } -#endif /* CONFIG_BT_MESH_GATT_PROXY */ static void gatt_connected(uint16_t conn_handle) { struct bt_mesh_proxy_client *client; + struct ble_gap_conn_desc info; + struct ble_hs_conn *conn; + conn = ble_hs_conn_find(conn_handle); + bt_conn_get_info(conn, &info); + if (info.role != BLE_GAP_ROLE_SLAVE || + !service_registered) { + return; + } BT_DBG("conn %d", conn_handle); conn_count++; @@ -955,17 +834,6 @@ static void gatt_disconnected(uint16_t conn_handle, uint8_t reason) return; } - if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && client->filter_type == PROV) { - bt_mesh_pb_gatt_close(conn_handle); - client->filter_type = NONE; - - if (bt_mesh_is_provisioned() && - IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && - bt_mesh_gatt_proxy_get() != BT_MESH_GATT_PROXY_NOT_SUPPORTED) { - (void)bt_mesh_proxy_gatt_enable(); - } - } - /* If this fails, the work handler exits early, as * there's no active connection. */ @@ -975,231 +843,6 @@ static void gatt_disconnected(uint16_t conn_handle, uint8_t reason) bt_mesh_adv_update(); } -struct os_mbuf *bt_mesh_proxy_get_buf(void) -{ - struct os_mbuf *buf = clients[0].cli.buf; - - if (buf != NULL) { - net_buf_simple_init(buf, 0); - } - - return buf; -} - -#if defined(CONFIG_BT_MESH_PB_GATT) -static void prov_ccc_write(uint16_t conn_handle) -{ - struct bt_mesh_proxy_client *client; - - BT_DBG("conn_handle %d", conn_handle); - - /* If a connection exists there must be a client */ - client = find_client(conn_handle); - __ASSERT(client, "No client for connection"); - - if (client->filter_type == NONE) { - client->filter_type = PROV; - bt_mesh_pb_gatt_open(conn_handle); - } -} - -static int -dummy_access_cb(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, void *arg) -{ - /* - * We should never never enter this callback - it's attached to notify-only - * characteristic which are notified directly from mbuf. And we can't pass - * NULL as access_cb because gatts will assert on init... - */ - BLE_HS_DBG_ASSERT(0); - return 0; -} - -static const struct ble_gatt_svc_def svc_defs [] = { - { - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), - .characteristics = (struct ble_gatt_chr_def[]) { { - .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_IN_VAL), - .access_cb = gatt_recv, - .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, - }, { - .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL), - .access_cb = dummy_access_cb, - .flags = BLE_GATT_CHR_F_NOTIFY, - }, { - 0, /* No more characteristics in this service. */ - } }, - }, { - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), - .characteristics = (struct ble_gatt_chr_def[]) { { - .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL), - .access_cb = gatt_recv, - .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, - }, { - .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL), - .access_cb = dummy_access_cb, - .flags = BLE_GATT_CHR_F_NOTIFY, - }, { - 0, /* No more characteristics in this service. */ - } }, - }, { - 0, /* No more services. */ - }, -}; - -int bt_mesh_proxy_svcs_register(void) -{ - int rc; - - rc = ble_gatts_count_cfg(svc_defs); - assert(rc == 0); - - rc = ble_gatts_add_svcs(svc_defs); - assert(rc == 0); - - return 0; -} - -int bt_mesh_proxy_prov_enable(void) -{ - uint16_t handle; - int rc; - int i; - - BT_DBG(""); - - if (gatt_svc == MESH_GATT_PROV) { - return -EALREADY; - } - - if (gatt_svc != MESH_GATT_NONE) { - return -EBUSY; - } - - rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle); - assert(rc == 0); - ble_gatts_svc_set_visibility(handle, 1); - /* FIXME: figure out end handle */ - ble_svc_gatt_changed(svc_handles.prov_h, 0xffff); - - gatt_svc = MESH_GATT_PROV; - prov_fast_adv = true; - - for (i = 0; i < ARRAY_SIZE(clients); i++) { - if (clients[i].cli.conn_handle != BLE_HS_CONN_HANDLE_NONE) { - clients[i].filter_type = PROV; - } - } - - - return 0; -} - -int bt_mesh_proxy_prov_disable(void) -{ - uint16_t handle; - int rc; - - BT_DBG(""); - - if (gatt_svc == MESH_GATT_NONE) { - return -EALREADY; - } - - if (gatt_svc != MESH_GATT_PROV) { - return -EBUSY; - } - - rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle); - assert(rc == 0); - ble_gatts_svc_set_visibility(handle, 0); - /* FIXME: figure out end handle */ - ble_svc_gatt_changed(svc_handles.prov_h, 0xffff); - - gatt_svc = MESH_GATT_NONE; - - bt_mesh_adv_update(); - - return 0; -} - -static uint8_t prov_svc_data[20] = { - BT_UUID_16_ENCODE(BT_UUID_MESH_PROV_VAL), -}; - -static const struct bt_data prov_ad[] = { - BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), - BT_DATA_BYTES(BT_DATA_UUID16_ALL, - BT_UUID_16_ENCODE(BT_UUID_MESH_PROV_VAL)), - BT_DATA(BT_DATA_SVC_DATA16, prov_svc_data, sizeof(prov_svc_data)), -}; - -int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, - void (*end)(uint16_t, void *), void *user_data) -{ - struct bt_mesh_proxy_client *client = find_client(conn_handle); - - if (!client) { - BT_ERR("No Proxy Client found"); - return -ENOTCONN; - } - - if (client->filter_type != PROV) { - BT_ERR("Invalid PDU type for Proxy Client"); - return -EINVAL; - } - - return bt_mesh_proxy_msg_send(&client->cli, BT_MESH_PROXY_PROV, buf, end, user_data); -} - -static size_t gatt_prov_adv_create(struct bt_data prov_sd[2]) -{ - const struct bt_mesh_prov *prov = bt_mesh_prov_get(); - const char *name = CONFIG_BT_DEVICE_NAME; - size_t name_len = strlen(name); - size_t prov_sd_len = 0; - size_t sd_space = 31; - - memcpy(prov_svc_data + 2, prov->uuid, 16); - sys_put_be16(prov->oob_info, prov_svc_data + 18); - - if (prov->uri) { - size_t uri_len = strlen(prov->uri); - - if (uri_len > 29) { - /* There's no way to shorten an URI */ - BT_WARN("Too long URI to fit advertising packet"); - } else { - prov_sd[0].type = BT_DATA_URI; - prov_sd[0].data_len = uri_len; - prov_sd[0].data = (const uint8_t *)prov->uri; - sd_space -= 2 + uri_len; - prov_sd_len++; - } - } - - if (sd_space > 2 && name_len > 0) { - sd_space -= 2; - - if (sd_space < name_len) { - prov_sd[prov_sd_len].type = BT_DATA_NAME_SHORTENED; - prov_sd[prov_sd_len].data_len = sd_space; - } else { - prov_sd[prov_sd_len].type = BT_DATA_NAME_COMPLETE; - prov_sd[prov_sd_len].data_len = name_len; - } - - prov_sd[prov_sd_len].data = (void *)name; - prov_sd_len++; - } - - return prov_sd_len; -} -#endif /* CONFIG_BT_MESH_PB_GATT */ - static int proxy_send(uint16_t conn_handle, const void *data, uint16_t len, void (*end)(uint16_t, void *), void *user_data) @@ -1209,22 +852,10 @@ static int proxy_send(uint16_t conn_handle, BT_DBG("%u bytes: %s", len, bt_hex(data, len)); -#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) - if (gatt_svc == MESH_GATT_PROXY) { - om = ble_hs_mbuf_from_flat(data, len); - assert(om); - err = ble_gattc_notify_custom(conn_handle, svc_handles.proxy_data_out_h, om); - /* We do not pass cb into ble_gattc_notify_custom - execute it at the end */ - } -#endif - -#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) - if (gatt_svc == MESH_GATT_PROV) { - om = ble_hs_mbuf_from_flat(data, len); - assert(om); - err = ble_gattc_notify_custom(conn_handle, svc_handles.prov_data_out_h, om); - } -#endif + om = ble_hs_mbuf_from_flat(data, len); + assert(om); + err = ble_gattc_notify_custom(conn_handle, svc_handles.proxy_data_out_h, om); + /* We do not pass cb into ble_gattc_notify_custom - execute it at the end */ end(conn_handle, user_data); return err; @@ -1234,54 +865,11 @@ int bt_mesh_proxy_adv_start(void) { BT_DBG(""); - if (gatt_svc == MESH_GATT_NONE) { - return -ENOENT; + if (!service_registered || !bt_mesh_is_provisioned()) { + return -ENOTSUP; } -#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) - if (!bt_mesh_is_provisioned()) { - const struct ble_gap_adv_params *param; - struct ble_gap_adv_params fast_adv_param = { - ADV_OPT_PROV - ADV_FAST_INT - }; - struct ble_gap_adv_params slow_adv_param = { - ADV_OPT_PROV - ADV_SLOW_INT - }; - struct bt_data prov_sd[1]; - size_t prov_sd_len; - int err; - - prov_sd_len = gatt_prov_adv_create(prov_sd); - if (!prov_fast_adv) { - param = &slow_adv_param; - return bt_mesh_adv_start(param, - K_FOREVER, prov_ad, - ARRAY_SIZE(prov_ad), prov_sd, - prov_sd_len); - } else { - param = &fast_adv_param; - err = bt_mesh_adv_start(param, - (60 * MSEC_PER_SEC), prov_ad, - ARRAY_SIZE(prov_ad), prov_sd, - prov_sd_len); - if (!err) { - prov_fast_adv = false; - } - - return err; - } - } -#endif /* PB_GATT */ - -#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) - if (bt_mesh_is_provisioned()) { - return gatt_proxy_advertise(next_sub()); - } -#endif /* GATT_PROXY */ - - return -ENOTSUP; + return gatt_proxy_advertise(next_sub()); } @@ -1305,10 +893,17 @@ static void ble_mesh_handle_connect(struct ble_gap_event *event, void *arg) } gatt_connected(event->adv_complete.conn_handle); +#if MYNEWT_VAL(BLE_MESH_PB_GATT) + gatt_connected_pb_gatt(event->adv_complete.conn_handle, + event->adv_complete.status); +#endif } #else if (event->type == BLE_GAP_EVENT_CONNECT) { gatt_connected(event->connect.conn_handle); +#if MYNEWT_VAL(BLE_MESH_PB_GATT) + gatt_connected_pb_gatt(event->connect.conn_handle, event->connect.status); +#endif } #endif } @@ -1321,6 +916,10 @@ int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) } else if (event->type == BLE_GAP_EVENT_DISCONNECT) { gatt_disconnected(event->disconnect.conn.conn_handle, event->disconnect.reason); +#if MYNEWT_VAL(BLE_MESH_PB_GATT) + gatt_disconnected_pb_gatt(event->disconnect.conn.conn_handle, + event->disconnect.reason); +#endif } else if (event->type == BLE_GAP_EVENT_SUBSCRIBE) { if (event->subscribe.attr_handle == svc_handles.proxy_data_out_h) { #if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) @@ -1329,7 +928,7 @@ int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) } else if (event->subscribe.attr_handle == svc_handles.prov_data_out_h) { #if (MYNEWT_VAL(BLE_MESH_PB_GATT)) - prov_ccc_write(event->subscribe.conn_handle); + prov_ccc_write(event->subscribe.conn_handle, event->type); #endif } } @@ -1337,70 +936,31 @@ int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) return 0; } -static void resolve_svc_handles(void) -{ - int rc; - - /* Either all handles are already resolved, or none of them */ - if (svc_handles.prov_data_out_h) { - return; - } - - /* - * We assert if attribute is not found since at this stage all attributes - * shall be already registered and thus shall be found. - */ - - rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), - &svc_handles.proxy_h); - assert(rc == 0); - - rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), - BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL), - NULL, &svc_handles.proxy_data_out_h); - assert(rc == 0); - - rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), - &svc_handles.prov_h); - assert(rc == 0); - - rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), - BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL), - NULL, &svc_handles.prov_data_in_h); - assert(rc == 0); - - rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), - BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL), - NULL, &svc_handles.prov_data_out_h); - assert(rc == 0); -} - - int bt_mesh_proxy_init(void) { - int i; + int i; - #if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) - if (!bt_mesh_subnet_cb_list[4]) { - bt_mesh_subnet_cb_list[4] = subnet_evt; - } - #endif +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + if (!bt_mesh_subnet_cb_list[4]) { + bt_mesh_subnet_cb_list[4] = subnet_evt; + } +#endif - for (i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); ++i) { - #if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) - k_work_init(&clients[i].send_beacons, proxy_send_beacons); - #endif - clients[i].cli.buf = NET_BUF_SIMPLE(CLIENT_BUF_SIZE); - clients[i].cli.conn_handle = BLE_HS_CONN_HANDLE_NONE; + for (i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); ++i) { +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + k_work_init(&clients[i].send_beacons, proxy_send_beacons); +#endif + clients[i].cli.buf = NET_BUF_SIMPLE(CLIENT_BUF_SIZE); + clients[i].cli.conn_handle = BLE_HS_CONN_HANDLE_NONE; - k_work_init_delayable(&clients[i].cli.sar_timer, proxy_sar_timeout); - k_work_add_arg_delayable(&clients[i].cli.sar_timer, &clients[i]); - } + k_work_init_delayable(&clients[i].cli.sar_timer, proxy_sar_timeout); + k_work_add_arg_delayable(&clients[i].cli.sar_timer, &clients[i]); + } - resolve_svc_handles(); + resolve_svc_handles(); - ble_gatts_svc_set_visibility(svc_handles.proxy_h, 0); - ble_gatts_svc_set_visibility(svc_handles.prov_h, 0); + ble_gatts_svc_set_visibility(svc_handles.proxy_h, 0); + ble_gatts_svc_set_visibility(svc_handles.prov_h, 0); return 0; } \ No newline at end of file diff --git a/nimble/host/mesh/src/settings.c b/nimble/host/mesh/src/settings.c index cc9fd630f5..cddf025f92 100644 --- a/nimble/host/mesh/src/settings.c +++ b/nimble/host/mesh/src/settings.c @@ -20,6 +20,7 @@ #include "transport.h" #include "heartbeat.h" #include "access.h" +#include "pb_gatt_srv.h" #include "proxy.h" #include "settings.h" #include "cfg.h" @@ -70,7 +71,7 @@ static int mesh_commit(void) } if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { - (void)bt_mesh_proxy_prov_disable(); + (void)bt_mesh_pb_gatt_disable(); } bt_mesh_net_settings_commit(); diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index 9ca21a7f77..f0c3ffdc29 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -150,8 +150,8 @@ syscfg.defs: descryption: > This option specifies how many Proxy Filter entries the local node supports. - value: 1 - restrictions: BLE_MESH_GATT_SERVER + value: 3 + restrictions: BLE_MESH_GATT_PROXY BLE_MESH_ACCESS_LAYER_MSG: descryption: > From 6c5fd1cdbbe18d789f9ac174e2d9c1eaa396c4ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 21 Oct 2021 13:08:20 +0200 Subject: [PATCH 0149/1333] host/mesh: Remove unnecessary prov buf get function Remove `bt_mesh_pb_gatt_get_buf`. This is port of a88aac2a7f107d89bd5727b01d21febfb20cc13f --- nimble/host/mesh/src/pb_gatt.c | 3 --- nimble/host/mesh/src/pb_gatt_srv.c | 10 ---------- nimble/host/mesh/src/pb_gatt_srv.h | 2 -- 3 files changed, 15 deletions(-) diff --git a/nimble/host/mesh/src/pb_gatt.c b/nimble/host/mesh/src/pb_gatt.c index 761ebb0a54..6a215e1d3a 100644 --- a/nimble/host/mesh/src/pb_gatt.c +++ b/nimble/host/mesh/src/pb_gatt.c @@ -35,7 +35,6 @@ struct prov_link { uint8_t seg; /* Bit-field of unreceived segments */ uint8_t last_seg; /* Last segment (to check length) */ uint8_t fcs; /* Expected FCS value */ - struct os_mbuf *buf; } rx; struct k_work_delayable prot_timer; }; @@ -48,8 +47,6 @@ static void reset_state(void) /* If this fails, the protocol timeout handler will exit early. */ (void)k_work_cancel_delayable(&link.prot_timer); - - link.rx.buf = bt_mesh_pb_gatt_get_buf(); } static void link_closed(enum prov_bearer_link_status status) diff --git a/nimble/host/mesh/src/pb_gatt_srv.c b/nimble/host/mesh/src/pb_gatt_srv.c index 7cb3257ccd..cf13cd9f23 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.c +++ b/nimble/host/mesh/src/pb_gatt_srv.c @@ -181,16 +181,6 @@ int prov_ccc_write(uint16_t conn_handle, uint8_t type) } /* Mesh Provisioning Service Declaration */ -struct os_mbuf *bt_mesh_pb_gatt_get_buf(void) -{ - struct os_mbuf *buf = cli.buf; - - if (buf != NULL) { - net_buf_simple_init(buf, 0); - } - - return buf; -} static int dummy_access_cb(uint16_t conn_handle, uint16_t attr_handle, diff --git a/nimble/host/mesh/src/pb_gatt_srv.h b/nimble/host/mesh/src/pb_gatt_srv.h index 561f2225e9..364f53553e 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.h +++ b/nimble/host/mesh/src/pb_gatt_srv.h @@ -14,8 +14,6 @@ int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, int bt_mesh_pb_gatt_enable(void); int bt_mesh_pb_gatt_disable(void); -struct os_mbuf *bt_mesh_pb_gatt_get_buf(void); - int prov_ccc_write(uint16_t conn_handle, uint8_t type); void gatt_disconnected_pb_gatt(uint16_t conn_handle, uint8_t err); void gatt_connected_pb_gatt(uint16_t conn_handle, uint8_t err); From 29d5a85f8bac49b951d796895dfe8b97a89e78ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 21 Oct 2021 13:17:29 +0200 Subject: [PATCH 0150/1333] host/mesh: Move command buffer to proxy_msg.c Move command buffer alloc to proxy_msg.c. This is port of d831d8a7d3637e330a0dc28c6787e242b75c4f0f --- nimble/host/mesh/src/mesh.c | 4 ---- nimble/host/mesh/src/pb_gatt_srv.c | 4 ---- nimble/host/mesh/src/proxy.h | 2 -- nimble/host/mesh/src/proxy_msg.c | 38 ++++++++++++++++++++++++++++++ nimble/host/mesh/src/proxy_srv.c | 5 ++-- 5 files changed, 40 insertions(+), 13 deletions(-) diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c index 1ac4d02641..ccdfed37fd 100644 --- a/nimble/host/mesh/src/mesh.c +++ b/nimble/host/mesh/src/mesh.c @@ -316,10 +316,6 @@ int bt_mesh_init(uint8_t own_addr_type, const struct bt_mesh_prov *prov, return err; } -#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) - bt_mesh_proxy_init(); -#endif - #if (MYNEWT_VAL(BLE_MESH_PROV)) err = bt_mesh_prov_init(prov); if (err) { diff --git a/nimble/host/mesh/src/pb_gatt_srv.c b/nimble/host/mesh/src/pb_gatt_srv.c index cf13cd9f23..64b59c5ed8 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.c +++ b/nimble/host/mesh/src/pb_gatt_srv.c @@ -24,8 +24,6 @@ #include "../../host/src/ble_hs_priv.h" #if MYNEWT_VAL(BLE_MESH_PB_GATT) -#define CLIENT_BUF_SIZE 66 - /** @def BT_UUID_MESH_PROV * @brief Mesh Provisioning Service */ @@ -124,8 +122,6 @@ void gatt_connected_pb_gatt(uint16_t conn_handle, uint8_t err) cli.conn_handle = conn_handle; BT_DBG("conn %p err 0x%02x", (void *)conn, err); - - net_buf_simple_reset(cli.buf); } void gatt_disconnected_pb_gatt(uint16_t conn_handle, uint8_t reason) diff --git a/nimble/host/mesh/src/proxy.h b/nimble/host/mesh/src/proxy.h index 196f540b2e..a92afaada4 100644 --- a/nimble/host/mesh/src/proxy.h +++ b/nimble/host/mesh/src/proxy.h @@ -51,8 +51,6 @@ void bt_mesh_proxy_identity_stop(struct bt_mesh_subnet *sub); bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst); void bt_mesh_proxy_addr_add(struct os_mbuf *buf, uint16_t addr); -int bt_mesh_proxy_init(void); - int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg); #endif /* __PROXY_H__ */ diff --git a/nimble/host/mesh/src/proxy_msg.c b/nimble/host/mesh/src/proxy_msg.c index 4c4d694029..5459815b47 100644 --- a/nimble/host/mesh/src/proxy_msg.c +++ b/nimble/host/mesh/src/proxy_msg.c @@ -46,6 +46,17 @@ #define PDU_HDR(sar, type) (sar << 6 | (type & BIT_MASK(6))) +#define PB_GATT_BUF_LEN_MAX 66 +#define PROXY_BUF_LEN_MAX 30 + +#if defined(CONFIG_BT_MESH_PB_GATT) +#define PROXY_MSG_FIRST_BUF_LEN PB_GATT_BUF_LEN_MAX +#else +#define PROXY_MSG_FIRST_BUF_LEN PROXY_BUF_LEN_MAX +#endif + +static uint8_t bufs[PROXY_MSG_FIRST_BUF_LEN + + ((CONFIG_BT_MAX_CONN - 1) * PROXY_BUF_LEN_MAX)]; #if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) static void proxy_cfg(struct bt_mesh_proxy_role *role) @@ -228,4 +239,31 @@ int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, return 0; } +void bt_mesh_proxy_msg_init(struct bt_mesh_proxy_role *role) +{ + uint8_t i, len; + uint8_t *buf; + + /* Check if buf has been allocated, in this way, we no longer need + * to repeat the operation. + */ + if (role->buf->om_data) { + net_buf_simple_reset(role->buf); + return; + } + + i = role->conn_handle; + if (!i) { + len = PROXY_MSG_FIRST_BUF_LEN; + buf = bufs; + } else { + len = PROXY_BUF_LEN_MAX; + buf = &bufs[PROXY_MSG_FIRST_BUF_LEN + (PROXY_BUF_LEN_MAX * (i - 1))]; + } + + net_buf_simple_init_with_data(role->buf, buf, len); + + net_buf_simple_reset(role->buf); +} + #endif /* MYNEWT_VAL(BLE_MESH_PROXY) */ diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index de096d07a7..28e61959ec 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -818,7 +818,8 @@ static void gatt_connected(uint16_t conn_handle) client->cli.conn_handle = conn_handle; client->filter_type = NONE; (void)memset(client->filter, 0, sizeof(client->filter)); - net_buf_simple_init(client->cli.buf, 0); + + bt_mesh_proxy_msg_init(&client->cli); } static void gatt_disconnected(uint16_t conn_handle, uint8_t reason) @@ -950,8 +951,6 @@ int bt_mesh_proxy_init(void) #if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) k_work_init(&clients[i].send_beacons, proxy_send_beacons); #endif - clients[i].cli.buf = NET_BUF_SIMPLE(CLIENT_BUF_SIZE); - clients[i].cli.conn_handle = BLE_HS_CONN_HANDLE_NONE; k_work_init_delayable(&clients[i].cli.sar_timer, proxy_sar_timeout); k_work_add_arg_delayable(&clients[i].cli.sar_timer, &clients[i]); From 6048746f830bdd3b2dbafbe2cc1d36421b07b051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 21 Oct 2021 13:49:44 +0200 Subject: [PATCH 0151/1333] host/mesh: Move proxy complete message to seperate role Move proxy complete message to seperate role. This is port of bc1d6580dc00bb09a8460f55460cf6c0bddb519d --- nimble/host/mesh/src/pb_gatt_srv.c | 19 +++++++- nimble/host/mesh/src/proxy_msg.c | 75 ++---------------------------- nimble/host/mesh/src/proxy_msg.h | 5 +- nimble/host/mesh/src/proxy_srv.c | 60 ++++++++++++++++++++++-- 4 files changed, 82 insertions(+), 77 deletions(-) diff --git a/nimble/host/mesh/src/pb_gatt_srv.c b/nimble/host/mesh/src/pb_gatt_srv.c index 64b59c5ed8..cbdd247a46 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.c +++ b/nimble/host/mesh/src/pb_gatt_srv.c @@ -73,14 +73,31 @@ static struct { uint16_t prov_data_out_h; } svc_handles; +static void proxy_complete_pdu(struct bt_mesh_proxy_role *role); static int gatt_send(uint16_t conn_handle, const void *data, uint16_t len, void (*end)(uint16_t, void *), void *user_data); static struct bt_mesh_proxy_role cli = { - .cb.send = gatt_send, + .cb = { + .send = gatt_send, + .recv = proxy_complete_pdu, + }, }; +static void proxy_complete_pdu(struct bt_mesh_proxy_role *role) +{ + switch (role->msg_type) { + case BT_MESH_PROXY_PROV: + BT_DBG("Mesh Provisioning PDU"); + bt_mesh_pb_gatt_recv(role->conn_handle, role->buf); + break; + default: + BT_WARN("Unhandled Message Type 0x%02x", role->msg_type); + break; + } +} + static bool service_registered; static ssize_t gatt_recv(uint16_t conn_handle, uint16_t attr_handle, diff --git a/nimble/host/mesh/src/proxy_msg.c b/nimble/host/mesh/src/proxy_msg.c index 5459815b47..e8770e2010 100644 --- a/nimble/host/mesh/src/proxy_msg.c +++ b/nimble/host/mesh/src/proxy_msg.c @@ -58,75 +58,6 @@ static uint8_t bufs[PROXY_MSG_FIRST_BUF_LEN + ((CONFIG_BT_MAX_CONN - 1) * PROXY_BUF_LEN_MAX)]; -#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) -static void proxy_cfg(struct bt_mesh_proxy_role *role) -{ - struct os_mbuf *buf = NET_BUF_SIMPLE(BT_MESH_NET_MAX_PDU_LEN); - struct bt_mesh_net_rx rx; - int err; - - err = bt_mesh_net_decode(role->buf, BT_MESH_NET_IF_PROXY_CFG, - &rx, buf); - if (err) { - BT_ERR("Failed to decode Proxy Configuration (err %d)", err); - goto done; - } - - rx.local_match = 1U; - - if (bt_mesh_rpl_check(&rx, NULL)) { - BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", - rx.ctx.addr, rx.ctx.recv_dst, rx.seq); - goto done; - } - - /* Remove network headers */ - net_buf_simple_pull_mem(buf, BT_MESH_NET_HDR_LEN); - - BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); - - if (buf->om_len < 1) { - BT_WARN("Too short proxy configuration PDU"); - goto done; - } - - role->cb.recv(role->conn_handle, &rx, buf); -done: - os_mbuf_free_chain(buf); -} -#endif /* GATT_PROXY */ - -static void proxy_complete_pdu(struct bt_mesh_proxy_role *role) -{ - switch (role->msg_type) { -#if defined(CONFIG_BT_MESH_PROXY) - case BT_MESH_PROXY_NET_PDU: - BT_INFO("Mesh Network PDU"); - bt_mesh_net_recv(role->buf, 0, BT_MESH_NET_IF_PROXY); - break; - case BT_MESH_PROXY_BEACON: - BT_INFO("Mesh Beacon PDU"); - bt_mesh_beacon_recv(role->buf); - break; - case BT_MESH_PROXY_CONFIG: - BT_INFO("Mesh Configuration PDU"); - proxy_cfg(role); - break; -#endif -#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) - case BT_MESH_PROXY_PROV: - BT_INFO("Mesh Provisioning PDU"); - bt_mesh_pb_gatt_recv(role->conn_handle, role->buf); - break; -#endif - default: - BT_WARN("Unhandled Message Type 0x%02x", role->msg_type); - break; - } - - net_buf_simple_init(role->buf, 0); -} - ssize_t bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, const void *buf, uint16_t len) { @@ -141,7 +72,8 @@ ssize_t bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, role->msg_type = PDU_TYPE(data); net_buf_simple_add_mem(role->buf, data + 1, len - 1); - proxy_complete_pdu(role); + role->cb.recv(role); + net_buf_simple_reset(role->buf); break; case SAR_FIRST: @@ -186,7 +118,8 @@ ssize_t bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, */ (void)k_work_cancel_delayable(&role->sar_timer); net_buf_simple_add_mem(role->buf, data + 1, len - 1); - proxy_complete_pdu(role); + role->cb.recv(role); + net_buf_simple_reset(role->buf); break; } diff --git a/nimble/host/mesh/src/proxy_msg.h b/nimble/host/mesh/src/proxy_msg.h index 662fadb8f5..fd8736e44f 100644 --- a/nimble/host/mesh/src/proxy_msg.h +++ b/nimble/host/mesh/src/proxy_msg.h @@ -23,12 +23,13 @@ #define PDU_HDR(sar, type) (sar << 6 | (type & BIT_MASK(6))) +struct bt_mesh_proxy_role; + typedef int (*proxy_send_cb_t)(uint16_t conn_handle, const void *data, uint16_t len, void (*end)(uint16_t, void *), void *user_data); -typedef void (*proxy_recv_cb_t)(uint16_t conn_handle, - struct bt_mesh_net_rx *rx, struct os_mbuf *buf); +typedef void (*proxy_recv_cb_t)(struct bt_mesh_proxy_role *role); struct bt_mesh_proxy_role { uint16_t conn_handle; diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index 28e61959ec..1234757977 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -42,8 +42,7 @@ static struct { } svc_handles; static void proxy_send_beacons(struct ble_npl_event *work); -static void proxy_filter_recv(uint16_t conn_handle, - struct bt_mesh_net_rx *rx, struct os_mbuf *buf); +static void proxy_complete_pdu(struct bt_mesh_proxy_role *role); static int proxy_send(uint16_t conn_handle, const void *data, uint16_t len, @@ -64,7 +63,7 @@ static struct bt_mesh_proxy_client { [0 ... (CONFIG_BT_MAX_CONN - 1)] = { .cli.cb = { .send = proxy_send, - .recv = proxy_filter_recv, + .recv = proxy_complete_pdu, }, }, }; @@ -250,6 +249,61 @@ static void proxy_filter_recv(uint16_t conn_handle, } } +static void proxy_cfg(struct bt_mesh_proxy_role *role) +{ + struct os_mbuf *buf = NET_BUF_SIMPLE(BT_MESH_NET_MAX_PDU_LEN); + struct bt_mesh_net_rx rx; + int err; + + err = bt_mesh_net_decode(role->buf, BT_MESH_NET_IF_PROXY_CFG, + &rx, buf); + if (err) { + BT_ERR("Failed to decode Proxy Configuration (err %d)", err); + return; + } + + rx.local_match = 1U; + + if (bt_mesh_rpl_check(&rx, NULL)) { + BT_WARN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", + rx.ctx.addr, rx.ctx.recv_dst, rx.seq); + return; + } + + /* Remove network headers */ + net_buf_simple_pull(buf, BT_MESH_NET_HDR_LEN); + + BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + + if (buf->om_len < 1) { + BT_WARN("Too short proxy configuration PDU"); + return; + } + + proxy_filter_recv(role->conn_handle, &rx, buf); + } + + static void proxy_complete_pdu(struct bt_mesh_proxy_role *role) + { + switch (role->msg_type) { + case BT_MESH_PROXY_NET_PDU: + BT_DBG("Mesh Network PDU"); + bt_mesh_net_recv(role->buf, 0, BT_MESH_NET_IF_PROXY); + break; + case BT_MESH_PROXY_BEACON: + BT_DBG("Mesh Beacon PDU"); + bt_mesh_beacon_recv(role->buf); + break; + case BT_MESH_PROXY_CONFIG: + BT_DBG("Mesh Configuration PDU"); + proxy_cfg(role); + break; + default: + BT_WARN("Unhandled Message Type 0x%02x", role->msg_type); + break; + } +} + static int beacon_send(struct bt_mesh_proxy_client *client, struct bt_mesh_subnet *sub) { struct os_mbuf *buf = NET_BUF_SIMPLE(23); From a162826831c950a13484f3624ae417858c8a7066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 21 Oct 2021 15:00:26 +0200 Subject: [PATCH 0152/1333] host/mesh: Move bt_mesh_proxy_role to proxy_msg.c Mesh bt_mesh_proxy_role structure to proxy_msg.c This is port of 22b234cf03f1139a431b0b1c9a820fe8c9d75e82 --- nimble/host/mesh/src/pb_gatt_srv.c | 42 +++++------- nimble/host/mesh/src/proxy_msg.c | 39 ++++++++++- nimble/host/mesh/src/proxy_msg.h | 18 ++++- nimble/host/mesh/src/proxy_srv.c | 104 +++++++++-------------------- 4 files changed, 104 insertions(+), 99 deletions(-) diff --git a/nimble/host/mesh/src/pb_gatt_srv.c b/nimble/host/mesh/src/pb_gatt_srv.c index cbdd247a46..a6a9c0616c 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.c +++ b/nimble/host/mesh/src/pb_gatt_srv.c @@ -73,19 +73,13 @@ static struct { uint16_t prov_data_out_h; } svc_handles; -static void proxy_complete_pdu(struct bt_mesh_proxy_role *role); static int gatt_send(uint16_t conn_handle, const void *data, uint16_t len, void (*end)(uint16_t, void *), void *user_data); -static struct bt_mesh_proxy_role cli = { - .cb = { - .send = gatt_send, - .recv = proxy_complete_pdu, - }, -}; +static struct bt_mesh_proxy_role *cli; -static void proxy_complete_pdu(struct bt_mesh_proxy_role *role) +static void proxy_msg_recv(struct bt_mesh_proxy_role *role) { switch (role->msg_type) { case BT_MESH_PROXY_PROV: @@ -105,9 +99,10 @@ static ssize_t gatt_recv(uint16_t conn_handle, uint16_t attr_handle, { const uint8_t *data = ctxt->om->om_data; uint16_t len = ctxt->om->om_len; + struct bt_mesh_proxy_client *client = find_client(conn_handle); - if (conn_handle != cli.conn_handle) { + if (conn_handle != cli->conn_handle) { return -ENOTCONN; } @@ -121,7 +116,7 @@ static ssize_t gatt_recv(uint16_t conn_handle, uint16_t attr_handle, return -EINVAL; } - return bt_mesh_proxy_msg_recv(&cli, data, len); + return bt_mesh_proxy_msg_recv(client->cli, data, len); } void gatt_connected_pb_gatt(uint16_t conn_handle, uint8_t err) @@ -136,7 +131,7 @@ void gatt_connected_pb_gatt(uint16_t conn_handle, uint8_t err) return; } - cli.conn_handle = conn_handle; + cli = bt_mesh_proxy_role_setup(conn_handle, gatt_send, proxy_msg_recv); BT_DBG("conn %p err 0x%02x", (void *)conn, err); } @@ -154,31 +149,26 @@ void gatt_disconnected_pb_gatt(uint16_t conn_handle, uint8_t reason) return; } - if (cli.conn_handle != conn_handle) { - BT_WARN("No PB-GATT Client found"); - return; - } + cli = NULL; BT_DBG("conn %p reason 0x%02x", (void *)conn, reason); bt_mesh_pb_gatt_close(conn_handle); - if (bt_mesh_is_provisioned()) { - (void)bt_mesh_pb_gatt_disable(); - - if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { - (void)bt_mesh_proxy_gatt_enable(); - } + if (!bt_mesh_is_provisioned()) { + return; } - cli.conn_handle = BLE_HS_CONN_HANDLE_NONE; + (void)bt_mesh_pb_gatt_disable(); - bt_mesh_adv_update(); + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { + (void)bt_mesh_proxy_gatt_enable(); + } } int prov_ccc_write(uint16_t conn_handle, uint8_t type) { - if (cli.conn_handle != conn_handle) { + if (cli->conn_handle != conn_handle) { BT_ERR("No PB-GATT Client found"); return -ENOTCONN; } @@ -357,12 +347,12 @@ static const struct bt_data prov_ad[] = { int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, void (*end)(uint16_t, void *), void *user_data) { - if (cli.conn_handle != conn_handle) { + if (!cli || cli->conn_handle != conn_handle) { BT_ERR("No PB-GATT Client found"); return -ENOTCONN; } - return bt_mesh_proxy_msg_send(&cli, BT_MESH_PROXY_PROV, buf, end, user_data); + return bt_mesh_proxy_msg_send(cli, BT_MESH_PROXY_PROV, buf, end, user_data); } static size_t gatt_prov_adv_create(struct bt_data prov_sd[1]) diff --git a/nimble/host/mesh/src/proxy_msg.c b/nimble/host/mesh/src/proxy_msg.c index e8770e2010..09064d3728 100644 --- a/nimble/host/mesh/src/proxy_msg.c +++ b/nimble/host/mesh/src/proxy_msg.c @@ -58,6 +58,8 @@ static uint8_t bufs[PROXY_MSG_FIRST_BUF_LEN + ((CONFIG_BT_MAX_CONN - 1) * PROXY_BUF_LEN_MAX)]; +static struct bt_mesh_proxy_role roles[CONFIG_BT_MAX_CONN]; + ssize_t bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, const void *buf, uint16_t len) { @@ -172,7 +174,7 @@ int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, return 0; } -void bt_mesh_proxy_msg_init(struct bt_mesh_proxy_role *role) +static void proxy_msg_init(struct bt_mesh_proxy_role *role) { uint8_t i, len; uint8_t *buf; @@ -199,4 +201,39 @@ void bt_mesh_proxy_msg_init(struct bt_mesh_proxy_role *role) net_buf_simple_reset(role->buf); } +struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(uint16_t conn_handle, + proxy_send_cb_t send, + proxy_recv_cb_t recv) +{ + struct bt_mesh_proxy_role *role; + + role = &roles[conn_handle]; + + role->conn_handle = conn_handle; + proxy_msg_init(role); + + role->cb.recv = recv; + role->cb.send = send; + + return role; +} + +void gatt_disconnected_proxy_msg(uint16_t conn_handle, uint8_t reason) +{ + struct bt_mesh_proxy_role *role; + + BT_DBG("conn_handle %d reason 0x%02x", conn_handle, reason); + + role = &roles[conn_handle]; + + /* If this fails, the work handler exits early, as + * there's no active connection. + */ + (void)k_work_cancel_delayable(&role->sar_timer); + + role->conn_handle = BLE_HS_CONN_HANDLE_NONE; + + bt_mesh_adv_update(); +} + #endif /* MYNEWT_VAL(BLE_MESH_PROXY) */ diff --git a/nimble/host/mesh/src/proxy_msg.h b/nimble/host/mesh/src/proxy_msg.h index fd8736e44f..54940b25cc 100644 --- a/nimble/host/mesh/src/proxy_msg.h +++ b/nimble/host/mesh/src/proxy_msg.h @@ -44,10 +44,26 @@ struct bt_mesh_proxy_role { struct os_mbuf *buf; }; +struct bt_mesh_proxy_client { + struct bt_mesh_proxy_role *cli; + uint16_t filter[MYNEWT_VAL(BLE_MESH_PROXY_FILTER_SIZE)]; + enum __packed { + NONE, + ACCEPT, + REJECT, + PROV, + } filter_type; + struct ble_npl_callout send_beacons; +}; + ssize_t bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, const void *buf, uint16_t len); int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, struct os_mbuf *msg, void (*end)(uint16_t, void *), void *user_data); void bt_mesh_proxy_msg_init(struct bt_mesh_proxy_role *role); - +void gatt_disconnected_proxy_msg(uint16_t conn_handle, uint8_t reason); +struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(uint16_t conn_handle, + proxy_send_cb_t send, + proxy_recv_cb_t recv); +struct bt_mesh_proxy_client *find_client(uint16_t conn_handle); #endif /* ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROXY_MSG_H_ */ diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index 1234757977..62b6cc3856 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -42,47 +42,21 @@ static struct { } svc_handles; static void proxy_send_beacons(struct ble_npl_event *work); -static void proxy_complete_pdu(struct bt_mesh_proxy_role *role); static int proxy_send(uint16_t conn_handle, const void *data, uint16_t len, void (*end)(uint16_t, void *), void *user_data); -static struct bt_mesh_proxy_client { - struct bt_mesh_proxy_role cli; - uint16_t filter[MYNEWT_VAL(BLE_MESH_PROXY_FILTER_SIZE)]; - enum __packed { - NONE, - ACCEPT, - REJECT, - PROV, - } filter_type; - struct ble_npl_callout send_beacons; -} clients[CONFIG_BT_MAX_CONN] = { - [0 ... (CONFIG_BT_MAX_CONN - 1)] = { - .cli.cb = { - .send = proxy_send, - .recv = proxy_complete_pdu, - }, - }, -}; +static struct bt_mesh_proxy_client clients[CONFIG_BT_MAX_CONN]; static bool service_registered; static int conn_count; -static struct bt_mesh_proxy_client *find_client(uint16_t conn_handle) +struct bt_mesh_proxy_client *find_client(uint16_t conn_handle) { - int i; - - for (i = 0; i < ARRAY_SIZE(clients); i++) { - if (clients[i].cli.conn_handle == conn_handle) { - return &clients[i]; - } - } - - return NULL; + return &clients[conn_handle]; } /* Next subnet in queue to be advertised */ @@ -201,7 +175,7 @@ static void send_filter_status(struct bt_mesh_proxy_client *client, return; } - err = bt_mesh_proxy_msg_send(&client->cli, BT_MESH_PROXY_CONFIG, + err = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_CONFIG, buf, NULL, NULL); if (err) { BT_ERR("Failed to send proxy cfg message (err %d)", err); @@ -215,9 +189,6 @@ static void proxy_filter_recv(uint16_t conn_handle, uint8_t opcode; client = find_client(conn_handle); - if (!client) { - return; - } opcode = net_buf_simple_pull_u8(buf); switch (opcode) { @@ -283,8 +254,8 @@ static void proxy_cfg(struct bt_mesh_proxy_role *role) proxy_filter_recv(role->conn_handle, &rx, buf); } - static void proxy_complete_pdu(struct bt_mesh_proxy_role *role) - { +static void proxy_msg_recv(struct bt_mesh_proxy_role *role) +{ switch (role->msg_type) { case BT_MESH_PROXY_NET_PDU: BT_DBG("Mesh Network PDU"); @@ -312,7 +283,7 @@ static int beacon_send(struct bt_mesh_proxy_client *client, struct bt_mesh_subne net_buf_simple_init(buf, 1); bt_mesh_beacon_create(sub, buf); - rc = bt_mesh_proxy_msg_send(&client->cli, BT_MESH_PROXY_BEACON, buf, + rc = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_BEACON, buf, NULL, NULL); os_mbuf_free_chain(buf); return rc; @@ -345,7 +316,7 @@ void bt_mesh_proxy_beacon_send(struct bt_mesh_subnet *sub) } for (i = 0; i < ARRAY_SIZE(clients); i++) { - if (clients[i].cli.conn_handle) { + if (clients[i].cli) { beacon_send(&clients[i], sub); } } @@ -638,7 +609,6 @@ static void proxy_ccc_write(uint16_t conn_handle) BT_DBG("conn_handle %d", conn_handle); client = find_client(conn_handle); - __ASSERT(client, "No client for connection"); if (client->filter_type == NONE) { client->filter_type = ACCEPT; @@ -672,7 +642,7 @@ int bt_mesh_proxy_gatt_enable(void) service_registered = true; for (i = 0; i < ARRAY_SIZE(clients); i++) { - if (clients[i].cli.conn_handle != BLE_HS_CONN_HANDLE_NONE) { + if (clients[i].cli->conn_handle != BLE_HS_CONN_HANDLE_NONE) { clients[i].filter_type = ACCEPT; } } @@ -689,11 +659,11 @@ void bt_mesh_proxy_gatt_disconnect(void) for (i = 0; i < ARRAY_SIZE(clients); i++) { struct bt_mesh_proxy_client *client = &clients[i]; - if ((client->cli.conn_handle != BLE_HS_CONN_HANDLE_NONE) && + if ((client->cli->conn_handle != BLE_HS_CONN_HANDLE_NONE) && (client->filter_type == ACCEPT || client->filter_type == REJECT)) { client->filter_type = NONE; - rc = ble_gap_terminate(client->cli.conn_handle, + rc = ble_gap_terminate(client->cli->conn_handle, BLE_ERR_REM_USER_CONN_TERM); assert(rc == 0); } @@ -724,8 +694,11 @@ int bt_mesh_proxy_gatt_disable(void) void bt_mesh_proxy_addr_add(struct os_mbuf *buf, uint16_t addr) { - struct bt_mesh_proxy_client *client = - CONTAINER_OF(buf, struct bt_mesh_proxy_client, cli.buf); + struct bt_mesh_proxy_client *client; + struct bt_mesh_proxy_role *cli = + CONTAINER_OF(buf, struct bt_mesh_proxy_role, buf); + + client = find_client(cli->conn_handle); BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr); @@ -788,7 +761,7 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) struct bt_mesh_proxy_client *client = &clients[i]; struct os_mbuf *msg; - if (client->cli.conn_handle == BLE_HS_CONN_HANDLE_NONE) { + if (client->cli->conn_handle == BLE_HS_CONN_HANDLE_NONE) { continue; } @@ -803,7 +776,7 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) net_buf_simple_init(msg, 1); net_buf_simple_add_mem(msg, buf->om_data, buf->om_len); - err = bt_mesh_proxy_msg_send(&client->cli, BT_MESH_PROXY_NET_PDU, + err = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_NET_PDU, msg, buf_send_end, net_buf_ref(buf)); adv_send_start(0, err, cb, cb_data); @@ -858,22 +831,18 @@ static void gatt_connected(uint16_t conn_handle) conn_count++; - /* Try to re-enable advertising in case it's possible */ - if (conn_count < CONFIG_BT_MAX_CONN) { - bt_mesh_adv_update(); - } - - client = find_client(BLE_HS_CONN_HANDLE_NONE); - if (!client) { - BT_ERR("No free Proxy Client objects"); - return; - } + client = find_client(conn_handle); - client->cli.conn_handle = conn_handle; client->filter_type = NONE; (void)memset(client->filter, 0, sizeof(client->filter)); - bt_mesh_proxy_msg_init(&client->cli); + client->cli = bt_mesh_proxy_role_setup(conn_handle, proxy_send, + proxy_msg_recv); + + /* Try to re-enable advertising in case it's possible */ + if (conn_count < CONFIG_BT_MAX_CONN) { + bt_mesh_adv_update(); + } } static void gatt_disconnected(uint16_t conn_handle, uint8_t reason) @@ -884,18 +853,7 @@ static void gatt_disconnected(uint16_t conn_handle, uint8_t reason) conn_count--; client = find_client(conn_handle); - if (!client) { - BT_WARN("No Gatt Client found"); - return; - } - - /* If this fails, the work handler exits early, as - * there's no active connection. - */ - (void)k_work_cancel_delayable(&client->cli.sar_timer); - client->cli.conn_handle = BLE_HS_CONN_HANDLE_NONE; - - bt_mesh_adv_update(); + client->cli = NULL; } static int proxy_send(uint16_t conn_handle, @@ -974,6 +932,10 @@ int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) #if MYNEWT_VAL(BLE_MESH_PB_GATT) gatt_disconnected_pb_gatt(event->disconnect.conn.conn_handle, event->disconnect.reason); +#endif +#if MYNEWT_VAL(BLE_MESH_PROXY) + gatt_disconnected_proxy_msg(event->disconnect.conn.conn_handle, + event->disconnect.reason); #endif } else if (event->type == BLE_GAP_EVENT_SUBSCRIBE) { if (event->subscribe.attr_handle == svc_handles.proxy_data_out_h) { @@ -1006,8 +968,8 @@ int bt_mesh_proxy_init(void) k_work_init(&clients[i].send_beacons, proxy_send_beacons); #endif - k_work_init_delayable(&clients[i].cli.sar_timer, proxy_sar_timeout); - k_work_add_arg_delayable(&clients[i].cli.sar_timer, &clients[i]); + k_work_init_delayable(&clients[i].cli->sar_timer, proxy_sar_timeout); + k_work_add_arg_delayable(&clients[i].cli->sar_timer, &clients[i]); } resolve_svc_handles(); From 66e6dfdfed0b5e6ce842f5fb29fa16f142b098e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 21 Oct 2021 15:09:25 +0200 Subject: [PATCH 0153/1333] host/mesh: Reflect disconnect logic to separate roles remove section ordering to use code more readable. This is port of 3f68692069be9253796822a98dd328d76925a234 --- nimble/host/mesh/src/pb_gatt_srv.c | 10 ++-------- nimble/host/mesh/src/proxy_srv.c | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/nimble/host/mesh/src/pb_gatt_srv.c b/nimble/host/mesh/src/pb_gatt_srv.c index a6a9c0616c..cb68bda374 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.c +++ b/nimble/host/mesh/src/pb_gatt_srv.c @@ -155,14 +155,8 @@ void gatt_disconnected_pb_gatt(uint16_t conn_handle, uint8_t reason) bt_mesh_pb_gatt_close(conn_handle); - if (!bt_mesh_is_provisioned()) { - return; - } - - (void)bt_mesh_pb_gatt_disable(); - - if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { - (void)bt_mesh_proxy_gatt_enable(); + if (bt_mesh_is_provisioned()) { + (void)bt_mesh_pb_gatt_disable(); } } diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index 62b6cc3856..5fb7a9b04d 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -847,11 +847,22 @@ static void gatt_connected(uint16_t conn_handle) static void gatt_disconnected(uint16_t conn_handle, uint8_t reason) { - BT_DBG("conn handle %u reason 0x%02x", conn_handle, reason); + struct ble_gap_conn_desc info; struct bt_mesh_proxy_client *client; + struct ble_hs_conn *conn; - conn_count--; + conn = ble_hs_conn_find(conn_handle); + bt_conn_get_info(conn, &info); + if (info.role != BLE_GAP_ROLE_SLAVE) { + return; + } + if (!service_registered && bt_mesh_is_provisioned()) { + (void)bt_mesh_proxy_gatt_enable(); + return; + } + + conn_count--; client = find_client(conn_handle); client->cli = NULL; } From ff2abc057d121824467dd15883acf2ecdebfa738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 21 Oct 2021 15:34:48 +0200 Subject: [PATCH 0154/1333] host/mesh: Add seperate config for pb-gatt dev name Add seperate config to control whether device name include in pb-gatt advertising scan response data. This is port of 355b18c43e8962190515e61efd770921ed3a7074 --- nimble/host/mesh/src/pb_gatt_srv.c | 23 ++++++++++++++++++++++- nimble/host/mesh/src/proxy.h | 14 -------------- nimble/host/mesh/src/proxy_msg.h | 1 - nimble/host/mesh/src/proxy_srv.c | 15 +++++++++++++-- nimble/host/mesh/syscfg.yml | 6 ++++++ 5 files changed, 41 insertions(+), 18 deletions(-) diff --git a/nimble/host/mesh/src/pb_gatt_srv.c b/nimble/host/mesh/src/pb_gatt_srv.c index cb68bda374..55900e188e 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.c +++ b/nimble/host/mesh/src/pb_gatt_srv.c @@ -23,6 +23,16 @@ #include "services/gatt/ble_svc_gatt.h" #include "../../host/src/ble_hs_priv.h" +#if defined(CONFIG_BT_MESH_PB_GATT_USE_DEVICE_NAME) +#define ADV_OPT_USE_NAME BT_LE_ADV_OPT_USE_NAME +#else +#define ADV_OPT_USE_NAME 0 +#endif + +#define ADV_OPT_PROV \ +.conn_mode = (BLE_GAP_CONN_MODE_UND), \ +.disc_mode = (BLE_GAP_DISC_MODE_GEN), + #if MYNEWT_VAL(BLE_MESH_PB_GATT) /** @def BT_UUID_MESH_PROV * @brief Mesh Provisioning Service @@ -405,7 +415,18 @@ int bt_mesh_pb_gatt_adv_start(void) ADV_OPT_PROV ADV_FAST_INT }; - struct bt_data prov_sd[1]; +#if ADV_OPT_USE_NAME + const char *name = CONFIG_BT_DEVICE_NAME; + size_t name_len = strlen(name); + struct bt_data prov_sd = { + .type = BT_DATA_NAME_COMPLETE, + .data_len = name_len, + .data = (void *)name + }; +#else + struct bt_data *prov_sd = NULL; +#endif + size_t prov_sd_len; int err; diff --git a/nimble/host/mesh/src/proxy.h b/nimble/host/mesh/src/proxy.h index a92afaada4..f84fa424f6 100644 --- a/nimble/host/mesh/src/proxy.h +++ b/nimble/host/mesh/src/proxy.h @@ -15,20 +15,6 @@ #define ADV_OPT_USE_IDENTITY 0 #endif -#if CONFIG_BT_MESH_PROXY_USE_DEVICE_NAME -#define ADV_OPT_USE_NAME BT_LE_ADV_OPT_USE_NAME -#else -#define ADV_OPT_USE_NAME 0 -#endif - -#define ADV_OPT_PROV \ -.conn_mode = (BLE_GAP_CONN_MODE_UND), \ -.disc_mode = (BLE_GAP_DISC_MODE_GEN), - -#define ADV_OPT_PROXY \ -.conn_mode = (BLE_GAP_CONN_MODE_UND), \ -.disc_mode = (BLE_GAP_DISC_MODE_GEN), - #define ADV_SLOW_INT \ .itvl_min = BT_GAP_ADV_SLOW_INT_MIN, \ .itvl_max = BT_GAP_ADV_SLOW_INT_MAX, diff --git a/nimble/host/mesh/src/proxy_msg.h b/nimble/host/mesh/src/proxy_msg.h index 54940b25cc..38e9ebc110 100644 --- a/nimble/host/mesh/src/proxy_msg.h +++ b/nimble/host/mesh/src/proxy_msg.h @@ -51,7 +51,6 @@ struct bt_mesh_proxy_client { NONE, ACCEPT, REJECT, - PROV, } filter_type; struct ble_npl_callout send_beacons; }; diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index 5fb7a9b04d..b60cf3d64b 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -26,6 +26,17 @@ #include "proxy_msg.h" #include "pb_gatt_srv.h" +#if defined(CONFIG_BT_MESH_PROXY_USE_DEVICE_NAME) +#define ADV_OPT_USE_NAME BT_LE_ADV_OPT_USE_NAME +#else +#define ADV_OPT_USE_NAME 0 +#endif + +#define ADV_OPT_PROXY \ +.conn_mode = (BLE_GAP_CONN_MODE_UND), \ +.disc_mode = (BLE_GAP_DISC_MODE_GEN), + + #define BT_UUID_MESH_PROXY_VAL 0x1828 #define CLIENT_BUF_SIZE 66 @@ -642,7 +653,7 @@ int bt_mesh_proxy_gatt_enable(void) service_registered = true; for (i = 0; i < ARRAY_SIZE(clients); i++) { - if (clients[i].cli->conn_handle != BLE_HS_CONN_HANDLE_NONE) { + if (clients[i].cli) { clients[i].filter_type = ACCEPT; } } @@ -659,7 +670,7 @@ void bt_mesh_proxy_gatt_disconnect(void) for (i = 0; i < ARRAY_SIZE(clients); i++) { struct bt_mesh_proxy_client *client = &clients[i]; - if ((client->cli->conn_handle != BLE_HS_CONN_HANDLE_NONE) && + if ((client->cli) && (client->filter_type == ACCEPT || client->filter_type == REJECT)) { client->filter_type = NONE; diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index f0c3ffdc29..1ada38806d 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -115,6 +115,12 @@ syscfg.defs: restrictions: - '(BLE_MESH_GATT_SERVER && BLE_MESH_PROV)' + BLE_MESH_PB_GATT_USE_DEVICE_NAME: + description: > + This option includes GAP device name in scan response when + the PB-GATT is enabled. + value: 1 + BLE_MESH_GATT_PROXY: description: > This option enables support for the Mesh GATT Proxy Service, From 4dc1b67ed76708ed0ea0663c51c3223377a7e609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 21 Oct 2021 15:36:46 +0200 Subject: [PATCH 0155/1333] host/mesh: Use common buf size for all conn Use common buffer size for all bluetooth mesh connection. This is port of 4fcf5496071fad53e43cd756c65b812a1421840b --- nimble/host/mesh/src/proxy_msg.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/nimble/host/mesh/src/proxy_msg.c b/nimble/host/mesh/src/proxy_msg.c index 09064d3728..27d53c484d 100644 --- a/nimble/host/mesh/src/proxy_msg.c +++ b/nimble/host/mesh/src/proxy_msg.c @@ -50,12 +50,12 @@ #define PROXY_BUF_LEN_MAX 30 #if defined(CONFIG_BT_MESH_PB_GATT) -#define PROXY_MSG_FIRST_BUF_LEN PB_GATT_BUF_LEN_MAX +#define PROXY_MSG_BUF_LEN PB_GATT_BUF_LEN_MAX #else -#define PROXY_MSG_FIRST_BUF_LEN PROXY_BUF_LEN_MAX +#define PROXY_MSG_BUF_LEN PROXY_BUF_LEN_MAX #endif -static uint8_t bufs[PROXY_MSG_FIRST_BUF_LEN + +static uint8_t bufs[CONFIG_BT_MAX_CONN + ((CONFIG_BT_MAX_CONN - 1) * PROXY_BUF_LEN_MAX)]; static struct bt_mesh_proxy_role roles[CONFIG_BT_MAX_CONN]; @@ -176,8 +176,6 @@ int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, static void proxy_msg_init(struct bt_mesh_proxy_role *role) { - uint8_t i, len; - uint8_t *buf; /* Check if buf has been allocated, in this way, we no longer need * to repeat the operation. @@ -187,16 +185,9 @@ static void proxy_msg_init(struct bt_mesh_proxy_role *role) return; } - i = role->conn_handle; - if (!i) { - len = PROXY_MSG_FIRST_BUF_LEN; - buf = bufs; - } else { - len = PROXY_BUF_LEN_MAX; - buf = &bufs[PROXY_MSG_FIRST_BUF_LEN + (PROXY_BUF_LEN_MAX * (i - 1))]; - } - - net_buf_simple_init_with_data(role->buf, buf, len); + net_buf_simple_init_with_data(role->buf, + &bufs[role->conn_handle * PROXY_MSG_BUF_LEN], + PROXY_MSG_BUF_LEN); net_buf_simple_reset(role->buf); } From ed2e5ae2aea790f5fc76dc627a3fe742892bfe1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 22 Oct 2021 07:39:21 +0200 Subject: [PATCH 0156/1333] host/mesh: Move proxy message size to kconfig Add `BT_MESH_PROXY_MSG_LEN` to config proxy message length This is port of 5ddbdcedd0046d4f3d541667579c029afd8d01a9 --- nimble/host/mesh/include/mesh/glue.h | 1 + nimble/host/mesh/src/cfg.c | 3 +-- nimble/host/mesh/src/proxy_msg.c | 17 ++++------------- nimble/host/mesh/syscfg.yml | 11 +++++++++++ 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index 588e79a487..44631f3e57 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -547,6 +547,7 @@ static inline unsigned int find_msb_set(uint32_t op) #define CONFIG_BT_MESH_RELAY MYNEWT_VAL(BLE_MESH_RELAY) #define CONFIG_BT_MESH_RELAY_RETRANSMIT_COUNT MYNEWT_VAL(BLE_MESH_RELAY_RETRANSMIT_COUNT) #define CONFIG_BT_MESH_GATT_PROXY_ENABLED MYNEWT_VAL(BLE_MESH_GATT_PROXY_ENABLED) +#define CONFIG_BT_MESH_PROXY_MSG_LEN MYNEWT_VAL(BLE_MESH_PROXY_MSG_LEN) #define printk console_printf diff --git a/nimble/host/mesh/src/cfg.c b/nimble/host/mesh/src/cfg.c index 9ed212abc4..e866cb7911 100644 --- a/nimble/host/mesh/src/cfg.c +++ b/nimble/host/mesh/src/cfg.c @@ -15,8 +15,7 @@ #include "cfg.h" #include "mesh/glue.h" -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_CFG) -#define LOG_MODULE_NAME bt_mesh_cfg +#define MESH_LOG_MODULE BLE_MESH_LOG #include "log/log.h" /* Miscellaneous configuration server model states */ diff --git a/nimble/host/mesh/src/proxy_msg.c b/nimble/host/mesh/src/proxy_msg.c index 27d53c484d..aa9fd5e817 100644 --- a/nimble/host/mesh/src/proxy_msg.c +++ b/nimble/host/mesh/src/proxy_msg.c @@ -46,17 +46,7 @@ #define PDU_HDR(sar, type) (sar << 6 | (type & BIT_MASK(6))) -#define PB_GATT_BUF_LEN_MAX 66 -#define PROXY_BUF_LEN_MAX 30 - -#if defined(CONFIG_BT_MESH_PB_GATT) -#define PROXY_MSG_BUF_LEN PB_GATT_BUF_LEN_MAX -#else -#define PROXY_MSG_BUF_LEN PROXY_BUF_LEN_MAX -#endif - -static uint8_t bufs[CONFIG_BT_MAX_CONN + - ((CONFIG_BT_MAX_CONN - 1) * PROXY_BUF_LEN_MAX)]; +static uint8_t bufs[CONFIG_BT_MAX_CONN * CONFIG_BT_MESH_PROXY_MSG_LEN]; static struct bt_mesh_proxy_role roles[CONFIG_BT_MAX_CONN]; @@ -186,8 +176,9 @@ static void proxy_msg_init(struct bt_mesh_proxy_role *role) } net_buf_simple_init_with_data(role->buf, - &bufs[role->conn_handle * PROXY_MSG_BUF_LEN], - PROXY_MSG_BUF_LEN); + &bufs[role->conn_handle * + CONFIG_BT_MESH_PROXY_MSG_LEN], + CONFIG_BT_MESH_PROXY_MSG_LEN); net_buf_simple_reset(role->buf); } diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index 1ada38806d..eb79b04947 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -103,6 +103,12 @@ syscfg.defs: BLE_MESH_GATT: value: 1 + BLE_MESH_PROXY_MSG_LEN: + description: > + Integer value + value: + restrictions: BLE_MESH_GATT + BLE_MESH_GATT_SERVER: value: 1 restrictions: BLE_MESH_GATT @@ -970,3 +976,8 @@ syscfg.vals.BLE_MESH_PB_GATT: syscfg.vals.BLE_MESH_PB_ADV: BLE_MESH_PROV: 1 + +syscfg.vals.'BLE_MESH_PB_GATT': + BLE_MESH_PROXY_MSG_LEN: 66 +syscfg.vals.'BLE_MESH_GATT_PROXY': + BLE_MESH_PROXY_MSG_LEN: 33 \ No newline at end of file From 804a6642fb5026a5b6199efcb19a12229b37a15f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 22 Oct 2021 07:53:59 +0200 Subject: [PATCH 0157/1333] host/mesh: cleanup log modules --- nimble/host/mesh/src/adv_ext.c | 1 - nimble/host/mesh/src/adv_legacy.c | 1 - nimble/host/mesh/src/cdb.c | 3 +-- nimble/host/mesh/src/msg.c | 3 --- nimble/host/mesh/src/proxy_srv.c | 3 +-- 5 files changed, 2 insertions(+), 9 deletions(-) diff --git a/nimble/host/mesh/src/adv_ext.c b/nimble/host/mesh/src/adv_ext.c index 364fb249b3..a531863f76 100644 --- a/nimble/host/mesh/src/adv_ext.c +++ b/nimble/host/mesh/src/adv_ext.c @@ -8,7 +8,6 @@ */ #define MESH_LOG_MODULE BLE_MESH_ADV_LOG -#define LOG_MODULE_NAME bt_mesh_adv_ext #include "adv.h" diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index 9506c08baf..eed3456ddf 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -8,7 +8,6 @@ */ #define MESH_LOG_MODULE BLE_MESH_ADV_LOG -#define LOG_MODULE_NAME bt_mesh_adv_legacy #include "adv.h" #include "net.h" diff --git a/nimble/host/mesh/src/cdb.c b/nimble/host/mesh/src/cdb.c index 5c7f88d470..f92ece6090 100644 --- a/nimble/host/mesh/src/cdb.c +++ b/nimble/host/mesh/src/cdb.c @@ -4,8 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define BT_DBG_ENABLED MYNEWT_VAL(BLE_MESH_DEBUG_CDB) -#define LOG_MODULE_NAME bt_mesh_cdb +#define MESH_LOG_MODULE BLE_MESH_LOG #include "log/log.h" #include diff --git a/nimble/host/mesh/src/msg.c b/nimble/host/mesh/src/msg.c index 230a2ab434..f75082cb96 100644 --- a/nimble/host/mesh/src/msg.c +++ b/nimble/host/mesh/src/msg.c @@ -8,9 +8,6 @@ #include "mesh/mesh.h" -#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_ACCESS) -#define LOG_MODULE_NAME bt_mesh_msg - void bt_mesh_model_msg_init(struct os_mbuf *msg, uint32_t opcode) { net_buf_simple_init(msg, 0); diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index b60cf3d64b..e0883a67ed 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -7,8 +7,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define BT_DBG_ENABLED CONFIG_BT_MESH_DEBUG_PROXY -#define LOG_MODULE_NAME bt_mesh_gatt +#define MESH_LOG_MODULE BLE_MESH_PROXY_LOG #include "../../host/src/ble_hs_priv.h" #include "services/gatt/ble_svc_gatt.h" From 2745cf4708d5985e92984e24db46d7892a292bf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 22 Oct 2021 07:55:40 +0200 Subject: [PATCH 0158/1333] host/mesh: logging public key in big endian Local public key has been logged in little endian but remote public key in big endian. That has been changed. Both are logged in big endian to be able to compare in logs. This is port of 797c17436bd071e71fdc58584e6741d9d5ebb332 --- nimble/host/mesh/src/prov_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/host/mesh/src/prov_device.c b/nimble/host/mesh/src/prov_device.c index 9d48547e3d..e9e2d2b122 100644 --- a/nimble/host/mesh/src/prov_device.c +++ b/nimble/host/mesh/src/prov_device.c @@ -248,14 +248,14 @@ static void send_pub_key(void) return; } - BT_DBG("Local Public Key: %s", bt_hex(key, BT_PUB_KEY_LEN)); - bt_mesh_prov_buf_init(buf, PROV_PUB_KEY); /* Swap X and Y halves independently to big-endian */ sys_memcpy_swap(net_buf_simple_add(buf, BT_PUB_KEY_COORD_LEN), key, BT_PUB_KEY_COORD_LEN); sys_memcpy_swap(net_buf_simple_add(buf, BT_PUB_KEY_COORD_LEN), &key[BT_PUB_KEY_COORD_LEN], 32); + BT_DBG("Local Public Key: %s", bt_hex(buf->om_data + 1, BT_PUB_KEY_LEN)); + /* PublicKeyDevice */ memcpy(bt_mesh_prov_link.conf_inputs.pub_key_device, &buf->om_data[1], PDU_LEN_PUB_KEY); From 267eed3ca7adcd1d18b7de790359424acfc6639d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 22 Oct 2021 07:58:41 +0200 Subject: [PATCH 0159/1333] host/mesh: Missed IV update cannot be captured It seems that if the IV update is missed, a node cannot recover it until the IV index has increased to a value greater than Node's Last known IV + 1. This is port of c1e053c9b3789b613771b68ba521b1b2585517c6 --- nimble/host/mesh/src/net.c | 42 +++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index e5391bf21c..f994bcc747 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -85,6 +85,15 @@ struct bt_mesh_net bt_mesh = { .local_queue = STAILQ_HEAD_INITIALIZER(bt_mesh.local_queue), }; +/* Mesh Profile Specification 3.10.6 + * The node shall not execute more than one IV Index Recovery within a period of + * 192 hours. + * + * Mark that the IV Index Recovery has been done to prevent two recoveries to be + * done before a normal IV Index update has been completed within 96h+96h. + */ +static bool ivi_was_recovered; + static struct os_mbuf_pool loopback_os_mbuf_pool; static struct os_mempool loopback_buf_mempool; os_membuf_t loopback_mbuf_membuf[ @@ -259,24 +268,24 @@ bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update) return false; } - if (iv_index > bt_mesh.iv_index + 1) { + if ((iv_index > bt_mesh.iv_index + 1) || + (iv_index == bt_mesh.iv_index + 1 && !iv_update)) { + if (ivi_was_recovered) { + BT_ERR("IV Index Recovery before minimum delay"); + return false; + } + /* The Mesh profile specification allows to initiate an + * IV Index Recovery procedure if previous IV update has + * been missed. This allows the node to remain + * functional. + */ BT_WARN("Performing IV Index Recovery"); + ivi_was_recovered = true; bt_mesh_rpl_clear(); bt_mesh.iv_index = iv_index; bt_mesh.seq = 0; goto do_update; } - - if (iv_index == bt_mesh.iv_index + 1 && !iv_update) { - BT_WARN("Ignoring new index in normal mode"); - return false; - } - - if (!iv_update) { - /* Nothing to do */ - BT_DBG("Already in Normal state"); - return false; - } } if (!(IS_ENABLED(CONFIG_BT_MESH_IV_UPDATE_TEST) && @@ -294,21 +303,22 @@ bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update) return false; } -do_update: - atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS, iv_update); - bt_mesh.ivu_duration = 0U; - if (iv_update) { bt_mesh.iv_index = iv_index; BT_DBG("IV Update state entered. New index 0x%08x", (unsigned) bt_mesh.iv_index); bt_mesh_rpl_reset(); + ivi_was_recovered = false; } else { BT_DBG("Normal mode entered"); bt_mesh.seq = 0; } +do_update: + atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS, iv_update); + bt_mesh.ivu_duration = 0U; + k_work_reschedule(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT); /* Notify other modules */ From f757df8e70ad7339465b418785bdcbf8cea8678c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 22 Oct 2021 08:10:28 +0200 Subject: [PATCH 0160/1333] host/mesh: Fix crash on disconnect bt_mesh_proxy_role_setup() is called conditionally when peer is connected and gatt_disconnected() is always called. This leads to unbalance in role->conn reference count and crash. Instead of hot-fixing this in gatt_disconnected(), this commit adds proper bt_mesh_proxy_role_cleanup() API that is called by roles implementations if cleanup is needed. This is port of 088fac76ed65a6cb8c367a89fae53d0e4bea2763 --- nimble/host/mesh/src/pb_gatt_srv.c | 5 ++++- nimble/host/mesh/src/proxy_msg.c | 7 +------ nimble/host/mesh/src/proxy_msg.h | 2 +- nimble/host/mesh/src/proxy_srv.c | 9 ++++----- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/nimble/host/mesh/src/pb_gatt_srv.c b/nimble/host/mesh/src/pb_gatt_srv.c index 55900e188e..d04948262d 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.c +++ b/nimble/host/mesh/src/pb_gatt_srv.c @@ -159,7 +159,10 @@ void gatt_disconnected_pb_gatt(uint16_t conn_handle, uint8_t reason) return; } - cli = NULL; + if (cli) { + bt_mesh_proxy_role_cleanup(cli); + cli = NULL; + } BT_DBG("conn %p reason 0x%02x", (void *)conn, reason); diff --git a/nimble/host/mesh/src/proxy_msg.c b/nimble/host/mesh/src/proxy_msg.c index aa9fd5e817..91b4ba694a 100644 --- a/nimble/host/mesh/src/proxy_msg.c +++ b/nimble/host/mesh/src/proxy_msg.c @@ -200,13 +200,8 @@ struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(uint16_t conn_handle, return role; } -void gatt_disconnected_proxy_msg(uint16_t conn_handle, uint8_t reason) +void bt_mesh_proxy_role_cleanup(struct bt_mesh_proxy_role *role) { - struct bt_mesh_proxy_role *role; - - BT_DBG("conn_handle %d reason 0x%02x", conn_handle, reason); - - role = &roles[conn_handle]; /* If this fails, the work handler exits early, as * there's no active connection. diff --git a/nimble/host/mesh/src/proxy_msg.h b/nimble/host/mesh/src/proxy_msg.h index 38e9ebc110..befdb1f351 100644 --- a/nimble/host/mesh/src/proxy_msg.h +++ b/nimble/host/mesh/src/proxy_msg.h @@ -60,7 +60,7 @@ ssize_t bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, struct os_mbuf *msg, void (*end)(uint16_t, void *), void *user_data); void bt_mesh_proxy_msg_init(struct bt_mesh_proxy_role *role); -void gatt_disconnected_proxy_msg(uint16_t conn_handle, uint8_t reason); +void bt_mesh_proxy_role_cleanup(struct bt_mesh_proxy_role *role); struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(uint16_t conn_handle, proxy_send_cb_t send, proxy_recv_cb_t recv); diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index e0883a67ed..dae61a4a1f 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -874,7 +874,10 @@ static void gatt_disconnected(uint16_t conn_handle, uint8_t reason) conn_count--; client = find_client(conn_handle); - client->cli = NULL; + if (client->cli) { + bt_mesh_proxy_role_cleanup(client->cli); + client->cli = NULL; + } } static int proxy_send(uint16_t conn_handle, @@ -953,10 +956,6 @@ int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) #if MYNEWT_VAL(BLE_MESH_PB_GATT) gatt_disconnected_pb_gatt(event->disconnect.conn.conn_handle, event->disconnect.reason); -#endif -#if MYNEWT_VAL(BLE_MESH_PROXY) - gatt_disconnected_proxy_msg(event->disconnect.conn.conn_handle, - event->disconnect.reason); #endif } else if (event->type == BLE_GAP_EVENT_SUBSCRIBE) { if (event->subscribe.attr_handle == svc_handles.proxy_data_out_h) { From 6617c2970493e05dbb921bc20c7d9a3fe08b5c52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 22 Oct 2021 08:12:43 +0200 Subject: [PATCH 0161/1333] host/mesh: Model extensions walk stops before last model When reaching the last model in the circular extension linked list, the walker would abandon the walk before checking the last model. This makes us skip models when checking the subscription list, potentially causing incoming messages to be wrongfully ignored. This is port of cd89f4239368b106fbfab9555cf445fbc00203a2 --- nimble/host/mesh/src/access.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index 33169a7501..6df342afea 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -819,11 +819,11 @@ void bt_mesh_model_extensions_walk(struct bt_mesh_model *model, #else struct bt_mesh_model *it; - if (model->next == NULL) { - (void)cb(model, user_data); + if (cb(model, user_data) == BT_MESH_WALK_STOP || !model->next) { return; } - for (it = model; (it != NULL) && (it->next != model); it = it->next) { + /* List is circular. Step through all models until we reach the start: */ + for (it = model->next; it != model; it = it->next) { if (cb(it, user_data) == BT_MESH_WALK_STOP) { return; } From 82ccdbce6f513f2beabf62336fc46d549f888cc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 22 Oct 2021 08:58:34 +0200 Subject: [PATCH 0162/1333] host/mesh: post-sync fixes This resolves some build errors introduced after sync with Zephyr. --- nimble/host/mesh/src/access.c | 1 - nimble/host/mesh/src/adv_legacy.c | 3 +-- nimble/host/mesh/src/glue.c | 5 ++--- nimble/host/mesh/src/proxy_srv.c | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index 6df342afea..28402885c6 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -866,7 +866,6 @@ int bt_mesh_model_extend(struct bt_mesh_model *extending_mod, struct bt_mesh_mod a->next = b; } - mod->extends = base_mod; return 0; } #endif diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index eed3456ddf..ab8a921619 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -15,6 +15,7 @@ #include "beacon.h" #include "prov.h" #include "proxy.h" +#include "mesh/glue.h" #include "pb_gatt_srv.h" #if MYNEWT_VAL(BLE_MESH_ADV_LEGACY) @@ -29,7 +30,6 @@ static int32_t adv_int_min = ADV_INT_DEFAULT_MS; -#if !MYNEWT_VAL(BLE_EXT_ADV) static int adv_initialized = false; /* TinyCrypt PRNG consumes a lot of stack space, so we need to have * an increased call stack whenever it's used. @@ -42,7 +42,6 @@ static os_membuf_t adv_buf_mem[OS_MEMPOOL_SIZE( MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT), BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE)]; static struct os_mempool adv_buf_mempool; -#endif static struct ble_npl_eventq adv_queue; static inline void adv_send(struct os_mbuf *buf) diff --git a/nimble/host/mesh/src/glue.c b/nimble/host/mesh/src/glue.c index 80f9b7e75e..c7b2cc16f8 100644 --- a/nimble/host/mesh/src/glue.c +++ b/nimble/host/mesh/src/glue.c @@ -834,14 +834,13 @@ bt_le_adv_start(const struct ble_gap_adv_params *param, return 0; } +#endif int bt_le_adv_stop() { - return ble_gap_adv_stop(); + return ble_gap_adv_stop(); } -#endif - #if MYNEWT_VAL(BLE_MESH_PROXY) int bt_mesh_proxy_svcs_register(void); #endif diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index dae61a4a1f..7fa297fa7b 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -932,7 +932,7 @@ static void ble_mesh_handle_connect(struct ble_gap_event *event, void *arg) gatt_connected(event->adv_complete.conn_handle); #if MYNEWT_VAL(BLE_MESH_PB_GATT) gatt_connected_pb_gatt(event->adv_complete.conn_handle, - event->adv_complete.status); + event->adv_complete.reason); #endif } #else From 489bb3a92550e53e8e0bb6ce6315e64f362b4d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 22 Oct 2021 08:59:35 +0200 Subject: [PATCH 0163/1333] apps/blemesh: fix build after introducing return codes in models This applies to both blemesh, blemesh_models_example_1 and blemesh_models_example_2 --- apps/blemesh/src/main.c | 58 +- apps/blemesh_models_example_1/src/main.c | 39 +- .../src/device_composition.c | 501 +++++++++++------- .../src/device_composition.h | 12 +- 4 files changed, 377 insertions(+), 233 deletions(-) diff --git a/apps/blemesh/src/main.c b/apps/blemesh/src/main.c index 65270554b3..56d0476f86 100644 --- a/apps/blemesh/src/main.c +++ b/apps/blemesh/src/main.c @@ -144,11 +144,12 @@ static struct bt_mesh_model_pub gen_onoff_pub; static uint8_t gen_on_off_state; static int16_t gen_level_state; -static void gen_onoff_status(struct bt_mesh_model *model, +static int gen_onoff_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { struct os_mbuf *msg = NET_BUF_SIMPLE(3); uint8_t *status; + int rc; console_printf("#mesh-onoff STATUS\n"); @@ -156,23 +157,25 @@ static void gen_onoff_status(struct bt_mesh_model *model, status = net_buf_simple_add(msg, 1); *status = gen_on_off_state; - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + rc = bt_mesh_model_send(model, ctx, msg, NULL, NULL); + if (rc) { console_printf("#mesh-onoff STATUS: send status failed\n"); } os_mbuf_free_chain(msg); + return rc; } -static void gen_onoff_get(struct bt_mesh_model *model, +static int gen_onoff_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { console_printf("#mesh-onoff GET\n"); - gen_onoff_status(model, ctx); + return gen_onoff_status(model, ctx); } -static void gen_onoff_set(struct bt_mesh_model *model, +static int gen_onoff_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -181,10 +184,10 @@ static void gen_onoff_set(struct bt_mesh_model *model, gen_on_off_state = buf->om_data[0]; hal_gpio_write(LED_2, !gen_on_off_state); - gen_onoff_status(model, ctx); + return gen_onoff_status(model, ctx); } -static void gen_onoff_set_unack(struct bt_mesh_model *model, +static int gen_onoff_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -192,6 +195,7 @@ static void gen_onoff_set_unack(struct bt_mesh_model *model, gen_on_off_state = buf->om_data[0]; hal_gpio_write(LED_2, !gen_on_off_state); + return 0; } static const struct bt_mesh_model_op gen_onoff_op[] = { @@ -201,48 +205,56 @@ static const struct bt_mesh_model_op gen_onoff_op[] = { BT_MESH_MODEL_OP_END, }; -static void gen_level_status(struct bt_mesh_model *model, +static int gen_level_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { struct os_mbuf *msg = NET_BUF_SIMPLE(4); + int rc; console_printf("#mesh-level STATUS\n"); bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x08)); net_buf_simple_add_le16(msg, gen_level_state); - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + rc = bt_mesh_model_send(model, ctx, msg, NULL, NULL); + if (rc) { console_printf("#mesh-level STATUS: send status failed\n"); } os_mbuf_free_chain(msg); + return rc; } -static void gen_level_get(struct bt_mesh_model *model, +static int gen_level_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { console_printf("#mesh-level GET\n"); - gen_level_status(model, ctx); + return gen_level_status(model, ctx); } -static void gen_level_set(struct bt_mesh_model *model, +static int gen_level_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { int16_t level; + int rc; level = (int16_t) net_buf_simple_pull_le16(buf); console_printf("#mesh-level SET: level=%d\n", level); - gen_level_status(model, ctx); + rc = gen_level_status(model, ctx); + if (rc) { + return rc; + } gen_level_state = level; console_printf("#mesh-level: level=%d\n", gen_level_state); + return 0; } -static void gen_level_set_unack(struct bt_mesh_model *model, +static int gen_level_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -253,9 +265,10 @@ static void gen_level_set_unack(struct bt_mesh_model *model, gen_level_state = level; console_printf("#mesh-level: level=%d\n", gen_level_state); + return 0; } -static void gen_delta_set(struct bt_mesh_model *model, +static int gen_delta_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -268,9 +281,10 @@ static void gen_delta_set(struct bt_mesh_model *model, gen_level_state += delta_level; console_printf("#mesh-level: level=%d\n", gen_level_state); + return 0; } -static void gen_delta_set_unack(struct bt_mesh_model *model, +static int gen_delta_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -281,18 +295,21 @@ static void gen_delta_set_unack(struct bt_mesh_model *model, gen_level_state += delta_level; console_printf("#mesh-level: level=%d\n", gen_level_state); + return 0; } -static void gen_move_set(struct bt_mesh_model *model, +static int gen_move_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { + return 0; } -static void gen_move_set_unack(struct bt_mesh_model *model, +static int gen_move_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { + return 0; } static const struct bt_mesh_model_op gen_level_op[] = { @@ -317,11 +334,12 @@ static struct bt_mesh_model root_models[] = { static struct bt_mesh_model_pub vnd_model_pub; -static void vnd_model_recv(struct bt_mesh_model *model, +static int vnd_model_recv(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { struct os_mbuf *msg = NET_BUF_SIMPLE(3); + int rc; console_printf("#vendor-model-recv\n"); @@ -331,11 +349,13 @@ static void vnd_model_recv(struct bt_mesh_model *model, bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_3(0x01, CID_VENDOR)); os_mbuf_append(msg, buf->om_data, buf->om_len); + rc = bt_mesh_model_send(model, ctx, msg, NULL, NULL); if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { console_printf("#vendor-model-recv: send rsp failed\n"); } os_mbuf_free_chain(msg); + return rc; } static const struct bt_mesh_model_op vnd_model_op[] = { diff --git a/apps/blemesh_models_example_1/src/main.c b/apps/blemesh_models_example_1/src/main.c index 736d4d32bf..80a69c7052 100644 --- a/apps/blemesh_models_example_1/src/main.c +++ b/apps/blemesh_models_example_1/src/main.c @@ -68,19 +68,19 @@ #define BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x03) #define BT_MESH_MODEL_OP_GEN_ONOFF_STATUS BT_MESH_MODEL_OP_2(0x82, 0x04) -static void gen_onoff_set(struct bt_mesh_model *model, +static int gen_onoff_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf); -static void gen_onoff_set_unack(struct bt_mesh_model *model, +static int gen_onoff_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf); -static void gen_onoff_get(struct bt_mesh_model *model, +static int gen_onoff_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf); -static void gen_onoff_status(struct bt_mesh_model *model, +static int gen_onoff_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf); @@ -318,26 +318,29 @@ static uint16_t primary_net_idx; * */ -static void gen_onoff_get(struct bt_mesh_model *model, +static int gen_onoff_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); struct onoff_state *state = model->user_data; + int rc; BT_INFO("addr 0x%04x onoff 0x%02x", bt_mesh_model_elem(model)->addr, state->current); bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_ONOFF_STATUS); net_buf_simple_add_u8(msg, state->current); - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + rc = bt_mesh_model_send(model, ctx, msg, NULL, NULL); + if (rc) { BT_ERR("Unable to send On Off Status response"); } os_mbuf_free_chain(msg); + return rc; } -static void gen_onoff_set_unack(struct bt_mesh_model *model, +static int gen_onoff_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -372,23 +375,34 @@ static void gen_onoff_set_unack(struct bt_mesh_model *model, BT_MESH_MODEL_OP_GEN_ONOFF_STATUS); net_buf_simple_add_u8(msg, state->current); err = bt_mesh_model_publish(model); - if (err) { + if (err != 0) { BT_ERR("bt_mesh_model_publish err %d", err); + return err; } } + return 0; } -static void gen_onoff_set(struct bt_mesh_model *model, +static int gen_onoff_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { BT_INFO(""); + int rc; + + rc = gen_onoff_set_unack(model, ctx, buf); + if (rc != 0) { + return rc; + } - gen_onoff_set_unack(model, ctx, buf); - gen_onoff_get(model, ctx, buf); + rc = gen_onoff_get(model, ctx, buf); + if (rc != 0) { + return rc; + } + return 0; } -static void gen_onoff_status(struct bt_mesh_model *model, +static int gen_onoff_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -398,6 +412,7 @@ static void gen_onoff_status(struct bt_mesh_model *model, BT_INFO("Node 0x%04x OnOff status from 0x%04x with state 0x%02x", bt_mesh_model_elem(model)->addr, ctx->addr, state); + return 0; } static int output_number(bt_mesh_output_action_t action, uint32_t number) diff --git a/apps/blemesh_models_example_2/src/device_composition.c b/apps/blemesh_models_example_2/src/device_composition.c index 5dfeaf8ed5..40ede50126 100644 --- a/apps/blemesh_models_example_2/src/device_composition.c +++ b/apps/blemesh_models_example_2/src/device_composition.c @@ -147,7 +147,7 @@ static struct bt_mesh_elem elements[]; /* message handlers (Start) */ /* Generic OnOff Server message handlers */ -static void gen_onoff_get(struct bt_mesh_model *model, +static int gen_onoff_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -168,16 +168,17 @@ static void gen_onoff_get(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + return 0; } -void gen_onoff_publish(struct bt_mesh_model *model) +int gen_onoff_publish(struct bt_mesh_model *model) { int err; struct os_mbuf *msg = model->pub->msg; struct generic_onoff_state *state = model->user_data; if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - return; + return 0; } bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_ONOFF_STATUS); @@ -193,21 +194,23 @@ void gen_onoff_publish(struct bt_mesh_model *model) if (err) { printk("bt_mesh_model_publish err %d\n", err); } + return err; } -static void gen_onoff_set_unack(struct bt_mesh_model *model, +static int gen_onoff_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { uint8_t tid, onoff, tt, delay; int64_t now; + int err; struct generic_onoff_state *state = model->user_data; onoff = net_buf_simple_pull_u8(buf); tid = net_buf_simple_pull_u8(buf); if (onoff > STATE_ON) { - return; + return 0; } now = k_uptime_get(); @@ -215,7 +218,7 @@ static void gen_onoff_set_unack(struct bt_mesh_model *model, state->last_src_addr == ctx->addr && state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { - return; + return 0; } switch (buf->om_len) { @@ -226,13 +229,13 @@ static void gen_onoff_set_unack(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -247,8 +250,7 @@ static void gen_onoff_set_unack(struct bt_mesh_model *model, if (state->target_onoff != state->onoff) { onoff_tt_values(state, tt, delay); } else { - gen_onoff_publish(model); - return; + return gen_onoff_publish(model); } /* For Instantaneous Transition */ @@ -257,23 +259,28 @@ static void gen_onoff_set_unack(struct bt_mesh_model *model, } state->transition->just_started = true; - gen_onoff_publish(model); + err = gen_onoff_publish(model); onoff_handler(state); + if (err) { + return err; + } + return 0; } -static void gen_onoff_set(struct bt_mesh_model *model, +static int gen_onoff_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { uint8_t tid, onoff, tt, delay; int64_t now; + int rc; struct generic_onoff_state *state = model->user_data; onoff = net_buf_simple_pull_u8(buf); tid = net_buf_simple_pull_u8(buf); if (onoff > STATE_ON) { - return; + return 0; } now = k_uptime_get(); @@ -281,8 +288,8 @@ static void gen_onoff_set(struct bt_mesh_model *model, state->last_src_addr == ctx->addr && state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { - gen_onoff_get(model, ctx, buf); - return; + rc = gen_onoff_get(model, ctx, buf); + return rc; } switch (buf->om_len) { @@ -293,13 +300,13 @@ static void gen_onoff_set(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -315,8 +322,8 @@ static void gen_onoff_set(struct bt_mesh_model *model, onoff_tt_values(state, tt, delay); } else { gen_onoff_get(model, ctx, buf); - gen_onoff_publish(model); - return; + rc = gen_onoff_publish(model); + return rc; } /* For Instantaneous Transition */ @@ -326,12 +333,13 @@ static void gen_onoff_set(struct bt_mesh_model *model, state->transition->just_started = true; gen_onoff_get(model, ctx, buf); - gen_onoff_publish(model); + rc = gen_onoff_publish(model); onoff_handler(state); + return rc; } /* Generic OnOff Client message handlers */ -static void gen_onoff_status(struct bt_mesh_model *model, +static int gen_onoff_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -342,10 +350,11 @@ static void gen_onoff_status(struct bt_mesh_model *model, printk("Target OnOff = %02x\n", net_buf_simple_pull_u8(buf)); printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf)); } + return 0; } /* Generic Level Server message handlers */ -static void gen_level_get(struct bt_mesh_model *model, +static int gen_level_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -366,16 +375,17 @@ static void gen_level_get(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + return 0; } -void gen_level_publish(struct bt_mesh_model *model) +int gen_level_publish(struct bt_mesh_model *model) { int err; struct os_mbuf *msg = model->pub->msg; struct generic_level_state *state = model->user_data; if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - return; + return 0; } bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS); @@ -391,9 +401,10 @@ void gen_level_publish(struct bt_mesh_model *model) if (err) { printk("bt_mesh_model_publish err %d\n", err); } + return err; } -static void gen_level_set_unack(struct bt_mesh_model *model, +static int gen_level_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -410,7 +421,7 @@ static void gen_level_set_unack(struct bt_mesh_model *model, state->last_src_addr == ctx->addr && state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { - return; + return 0; } switch (buf->om_len) { @@ -421,13 +432,13 @@ static void gen_level_set_unack(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -443,7 +454,7 @@ static void gen_level_set_unack(struct bt_mesh_model *model, level_tt_values(state, tt, delay); } else { gen_level_publish(model); - return; + return 0; } /* For Instantaneous Transition */ @@ -463,9 +474,10 @@ static void gen_level_set_unack(struct bt_mesh_model *model, transition_type = LEVEL_TEMP_TT; level_temp_handler(state); } + return 0; } -static void gen_level_set(struct bt_mesh_model *model, +static int gen_level_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -483,7 +495,7 @@ static void gen_level_set(struct bt_mesh_model *model, state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { gen_level_get(model, ctx, buf); - return; + return 0; } switch (buf->om_len) { @@ -494,13 +506,13 @@ static void gen_level_set(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -517,7 +529,7 @@ static void gen_level_set(struct bt_mesh_model *model, } else { gen_level_get(model, ctx, buf); gen_level_publish(model); - return; + return 0; } /* For Instantaneous Transition */ @@ -538,9 +550,10 @@ static void gen_level_set(struct bt_mesh_model *model, transition_type = LEVEL_TEMP_TT; level_temp_handler(state); } + return 0; } -static void gen_delta_set_unack(struct bt_mesh_model *model, +static int gen_delta_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -559,7 +572,7 @@ static void gen_delta_set_unack(struct bt_mesh_model *model, (now - state->last_msg_timestamp <= K_SECONDS(6))) { if (state->last_delta == delta) { - return; + return 0; } tmp32 = state->last_level + delta; @@ -576,13 +589,13 @@ static void gen_delta_set_unack(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -605,8 +618,7 @@ static void gen_delta_set_unack(struct bt_mesh_model *model, if (state->target_level != state->level) { level_tt_values(state, tt, delay); } else { - gen_level_publish(model); - return; + return gen_level_publish(model); } /* For Instantaneous Transition */ @@ -627,9 +639,10 @@ static void gen_delta_set_unack(struct bt_mesh_model *model, transition_type = LEVEL_TEMP_TT_DELTA; level_temp_handler(state); } + return 0; } -static void gen_delta_set(struct bt_mesh_model *model, +static int gen_delta_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -649,7 +662,7 @@ static void gen_delta_set(struct bt_mesh_model *model, if (state->last_delta == delta) { gen_level_get(model, ctx, buf); - return; + return 0; } tmp32 = state->last_level + delta; @@ -666,13 +679,13 @@ static void gen_delta_set(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -697,7 +710,7 @@ static void gen_delta_set(struct bt_mesh_model *model, } else { gen_level_get(model, ctx, buf); gen_level_publish(model); - return; + return 0; } /* For Instantaneous Transition */ @@ -718,14 +731,16 @@ static void gen_delta_set(struct bt_mesh_model *model, transition_type = LEVEL_TEMP_TT_DELTA; level_temp_handler(state); } + return 0; } -static void gen_level_move_get(struct bt_mesh_model *model, +static int gen_level_move_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 5 + 4); struct generic_level_state *state = model->user_data; + int rc; bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS); net_buf_simple_add_le16(msg, state->level); @@ -740,21 +755,23 @@ static void gen_level_move_get(struct bt_mesh_model *model, net_buf_simple_add_u8(msg, UNKNOWN_VALUE); } - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + rc = bt_mesh_model_send(model, ctx, msg, NULL, NULL); + if (rc) { printk("Unable to send GEN_LEVEL_SRV Status response\n"); } os_mbuf_free_chain(msg); + return rc; } -static void gen_level_move_publish(struct bt_mesh_model *model) +static int gen_level_move_publish(struct bt_mesh_model *model) { int err; struct os_mbuf *msg = model->pub->msg; struct generic_level_state *state = model->user_data; if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - return; + return 0; } bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_GEN_LEVEL_STATUS); @@ -774,9 +791,10 @@ static void gen_level_move_publish(struct bt_mesh_model *model) if (err) { printk("bt_mesh_model_publish err %d\n", err); } + return err; } -static void gen_move_set_unack(struct bt_mesh_model *model, +static int gen_move_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -785,6 +803,7 @@ static void gen_move_set_unack(struct bt_mesh_model *model, int32_t tmp32; int64_t now; struct generic_level_state *state = model->user_data; + int rc; delta = (int16_t) net_buf_simple_pull_le16(buf); tid = net_buf_simple_pull_u8(buf); @@ -794,7 +813,7 @@ static void gen_move_set_unack(struct bt_mesh_model *model, state->last_src_addr == ctx->addr && state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { - return; + return 0; } switch (buf->om_len) { @@ -805,13 +824,13 @@ static void gen_move_set_unack(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -835,16 +854,16 @@ static void gen_move_set_unack(struct bt_mesh_model *model, if (state->target_level != state->level) { level_tt_values(state, tt, delay); } else { - gen_level_move_publish(model); - return; + rc = gen_level_move_publish(model); + return rc; } if (state->transition->counter == 0) { - return; + return 0; } state->transition->just_started = true; - gen_level_move_publish(model); + rc = gen_level_move_publish(model); if (bt_mesh_model_elem(model)->addr == elements[0].addr) { /* Root element */ @@ -855,9 +874,10 @@ static void gen_move_set_unack(struct bt_mesh_model *model, transition_type = LEVEL_TEMP_TT_MOVE; level_temp_handler(state); } + return rc; } -static void gen_move_set(struct bt_mesh_model *model, +static int gen_move_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -866,6 +886,7 @@ static void gen_move_set(struct bt_mesh_model *model, int32_t tmp32; int64_t now; struct generic_level_state *state = model->user_data; + int rc; delta = (int16_t) net_buf_simple_pull_le16(buf); tid = net_buf_simple_pull_u8(buf); @@ -875,8 +896,8 @@ static void gen_move_set(struct bt_mesh_model *model, state->last_src_addr == ctx->addr && state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { - gen_level_move_get(model, ctx, buf); - return; + rc = gen_level_move_get(model, ctx, buf); + return rc; } switch (buf->om_len) { @@ -887,13 +908,13 @@ static void gen_move_set(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -918,17 +939,17 @@ static void gen_move_set(struct bt_mesh_model *model, level_tt_values(state, tt, delay); } else { gen_level_move_get(model, ctx, buf); - gen_level_move_publish(model); - return; + rc = gen_level_move_publish(model); + return rc; } if (state->transition->counter == 0) { - return; + return 0; } state->transition->just_started = true; gen_level_move_get(model, ctx, buf); - gen_level_move_publish(model); + rc = gen_level_move_publish(model); if (bt_mesh_model_elem(model)->addr == elements[0].addr) { /* Root element */ @@ -939,10 +960,11 @@ static void gen_move_set(struct bt_mesh_model *model, transition_type = LEVEL_TEMP_TT_MOVE; level_temp_handler(state); } + return rc; } /* Generic Level Client message handlers */ -static void gen_level_status(struct bt_mesh_model *model, +static int gen_level_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -953,10 +975,11 @@ static void gen_level_status(struct bt_mesh_model *model, printk("Target Level = %04x\n", net_buf_simple_pull_le16(buf)); printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf)); } + return 0; } /* Generic Default Transition Time Server message handlers */ -static void gen_def_trans_time_get(struct bt_mesh_model *model, +static int gen_def_trans_time_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -971,16 +994,17 @@ static void gen_def_trans_time_get(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + return 0; } -static void gen_def_trans_time_publish(struct bt_mesh_model *model) +static int gen_def_trans_time_publish(struct bt_mesh_model *model) { int err; struct os_mbuf *msg = model->pub->msg; struct gen_def_trans_time_state *state = model->user_data; if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - return; + return 0; } bt_mesh_model_msg_init(msg, BT_MESH_MODEL_GEN_DEF_TRANS_TIME_STATUS); @@ -990,6 +1014,7 @@ static void gen_def_trans_time_publish(struct bt_mesh_model *model) if (err) { printk("bt_mesh_model_publish err %d\n", err); } + return err; } static bool gen_def_trans_time_setunack(struct bt_mesh_model *model, @@ -1017,71 +1042,78 @@ static bool gen_def_trans_time_setunack(struct bt_mesh_model *model, return true; } -static void gen_def_trans_time_set_unack(struct bt_mesh_model *model, +static int gen_def_trans_time_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { if (gen_def_trans_time_setunack(model, ctx, buf) == true) { - gen_def_trans_time_publish(model); + return gen_def_trans_time_publish(model); } + return 0; } -static void gen_def_trans_time_set(struct bt_mesh_model *model, +static int gen_def_trans_time_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { if (gen_def_trans_time_setunack(model, ctx, buf) == true) { gen_def_trans_time_get(model, ctx, buf); - gen_def_trans_time_publish(model); + return gen_def_trans_time_publish(model); } + return 0; } /* Generic Default Transition Time Client message handlers */ -static void gen_def_trans_time_status(struct bt_mesh_model *model, +static int gen_def_trans_time_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { printk("Acknownledgement from GEN_DEF_TT_SRV\n"); printk("Transition Time = %02x\n", net_buf_simple_pull_u8(buf)); + return 0; } /* Generic Power OnOff Server message handlers */ -static void gen_onpowerup_get(struct bt_mesh_model *model, +static int gen_onpowerup_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); struct generic_onpowerup_state *state = model->user_data; + int rc; bt_mesh_model_msg_init(msg, BT_MESH_MODEL_GEN_ONPOWERUP_STATUS); net_buf_simple_add_u8(msg, state->onpowerup); - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + rc = bt_mesh_model_send(model, ctx, msg, NULL, NULL); + if (rc) { printk("Unable to send GEN_POWER_ONOFF_SRV Status response\n"); } os_mbuf_free_chain(msg); + return rc; } /* Generic Power OnOff Client message handlers */ -static void gen_onpowerup_status(struct bt_mesh_model *model, +static int gen_onpowerup_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { printk("Acknownledgement from GEN_POWER_ONOFF_SRV\n"); printk("OnPowerUp = %02x\n", net_buf_simple_pull_u8(buf)); + return 0; } /* Generic Power OnOff Setup Server message handlers */ -static void gen_onpowerup_publish(struct bt_mesh_model *model) +static int gen_onpowerup_publish(struct bt_mesh_model *model) { int err; struct os_mbuf *msg = model->pub->msg; struct generic_onpowerup_state *state = model->user_data; if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - return; + return 0; } bt_mesh_model_msg_init(msg, BT_MESH_MODEL_GEN_ONPOWERUP_STATUS); @@ -1091,6 +1123,7 @@ static void gen_onpowerup_publish(struct bt_mesh_model *model) if (err) { printk("bt_mesh_model_publish err %d\n", err); } + return err; } static bool gen_onpowerup_setunack(struct bt_mesh_model *model, @@ -1117,32 +1150,35 @@ static bool gen_onpowerup_setunack(struct bt_mesh_model *model, return true; } -static void gen_onpowerup_set_unack(struct bt_mesh_model *model, +static int gen_onpowerup_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { if (gen_onpowerup_setunack(model, ctx, buf) == true) { - gen_onpowerup_publish(model); + return gen_onpowerup_publish(model); } + return 0; } -static void gen_onpowerup_set(struct bt_mesh_model *model, +static int gen_onpowerup_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { if (gen_onpowerup_setunack(model, ctx, buf) == true) { gen_onpowerup_get(model, ctx, buf); - gen_onpowerup_publish(model); + return gen_onpowerup_publish(model); } + return 0; } /* Vendor Model message handlers*/ -static void vnd_get(struct bt_mesh_model *model, +static int vnd_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { struct os_mbuf *msg = NET_BUF_SIMPLE(3 + 6 + 4); struct vendor_state *state = model->user_data; + int err; /* This is dummy response for demo purpose */ state->response = 0xA578FEB3; @@ -1151,14 +1187,16 @@ static void vnd_get(struct bt_mesh_model *model, net_buf_simple_add_le16(msg, state->current); net_buf_simple_add_le32(msg, state->response); - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + err = bt_mesh_model_send(model, ctx, msg, NULL, NULL); + if (err) { printk("Unable to send VENDOR Status response\n"); } os_mbuf_free_chain(msg); + return err; } -static void vnd_set_unack(struct bt_mesh_model *model, +static int vnd_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1175,7 +1213,7 @@ static void vnd_set_unack(struct bt_mesh_model *model, state->last_src_addr == ctx->addr && state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { - return; + return 0; } state->last_tid = tid; @@ -1193,27 +1231,37 @@ static void vnd_set_unack(struct bt_mesh_model *model, /* LED2 Off */ hal_gpio_write(led_device[1], 1); } + return 0; } -static void vnd_set(struct bt_mesh_model *model, +static int vnd_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - vnd_set_unack(model, ctx, buf); - vnd_get(model, ctx, buf); + int rc; + rc = vnd_set_unack(model, ctx, buf); + if (rc) { + return rc; + } + rc = vnd_get(model, ctx, buf); + if (rc) { + return rc; + } + return 0; } -static void vnd_status(struct bt_mesh_model *model, +static int vnd_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { printk("Acknownledgement from Vendor\n"); printk("cmd = %04x\n", net_buf_simple_pull_le16(buf)); printk("response = %08lx\n", net_buf_simple_pull_le32(buf)); + return 0; } /* Light Lightness Server message handlers */ -static void light_lightness_get(struct bt_mesh_model *model, +static int light_lightness_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1234,16 +1282,17 @@ static void light_lightness_get(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + return 0; } -void light_lightness_publish(struct bt_mesh_model *model) +int light_lightness_publish(struct bt_mesh_model *model) { int err; struct os_mbuf *msg = model->pub->msg; struct light_lightness_state *state = model->user_data; if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - return; + return 0; } bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_LIGHTNESS_STATUS); @@ -1259,9 +1308,10 @@ void light_lightness_publish(struct bt_mesh_model *model) if (err) { printk("bt_mesh_model_publish err %d\n", err); } + return err; } -static void light_lightness_set_unack(struct bt_mesh_model *model, +static int light_lightness_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1278,7 +1328,7 @@ static void light_lightness_set_unack(struct bt_mesh_model *model, state->last_src_addr == ctx->addr && state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { - return; + return 0; } switch (buf->om_len) { @@ -1289,13 +1339,13 @@ static void light_lightness_set_unack(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -1318,7 +1368,7 @@ static void light_lightness_set_unack(struct bt_mesh_model *model, light_lightness_actual_tt_values(state, tt, delay); } else { light_lightness_publish(model); - return; + return 0; } /* For Instantaneous Transition */ @@ -1329,9 +1379,10 @@ static void light_lightness_set_unack(struct bt_mesh_model *model, state->transition->just_started = true; light_lightness_publish(model); light_lightness_actual_handler(state); + return 0; } -static void light_lightness_set(struct bt_mesh_model *model, +static int light_lightness_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1339,6 +1390,7 @@ static void light_lightness_set(struct bt_mesh_model *model, uint16_t actual; int64_t now; struct light_lightness_state *state = model->user_data; + int rc; actual = net_buf_simple_pull_le16(buf); tid = net_buf_simple_pull_u8(buf); @@ -1348,8 +1400,7 @@ static void light_lightness_set(struct bt_mesh_model *model, state->last_src_addr == ctx->addr && state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { - light_lightness_get(model, ctx, buf); - return; + return light_lightness_get(model, ctx, buf); } switch (buf->om_len) { @@ -1360,13 +1411,13 @@ static void light_lightness_set(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -1388,9 +1439,9 @@ static void light_lightness_set(struct bt_mesh_model *model, if (state->target_actual != state->actual) { light_lightness_actual_tt_values(state, tt, delay); } else { - light_lightness_get(model, ctx, buf); + rc = light_lightness_get(model, ctx, buf); light_lightness_publish(model); - return; + return rc; } /* For Instantaneous Transition */ @@ -1402,9 +1453,10 @@ static void light_lightness_set(struct bt_mesh_model *model, light_lightness_get(model, ctx, buf); light_lightness_publish(model); light_lightness_actual_handler(state); + return 0; } -static void light_lightness_linear_get(struct bt_mesh_model *model, +static int light_lightness_linear_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1426,16 +1478,17 @@ static void light_lightness_linear_get(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + return 0; } -void light_lightness_linear_publish(struct bt_mesh_model *model) +int light_lightness_linear_publish(struct bt_mesh_model *model) { int err; struct os_mbuf *msg = model->pub->msg; struct light_lightness_state *state = model->user_data; if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - return; + return 0; } bt_mesh_model_msg_init(msg, @@ -1452,9 +1505,10 @@ void light_lightness_linear_publish(struct bt_mesh_model *model) if (err) { printk("bt_mesh_model_publish err %d\n", err); } + return err; } -static void light_lightness_linear_set_unack(struct bt_mesh_model *model, +static int light_lightness_linear_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1471,7 +1525,7 @@ static void light_lightness_linear_set_unack(struct bt_mesh_model *model, state->last_src_addr == ctx->addr && state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { - return; + return 0; } switch (buf->om_len) { @@ -1482,13 +1536,13 @@ static void light_lightness_linear_set_unack(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -1504,7 +1558,7 @@ static void light_lightness_linear_set_unack(struct bt_mesh_model *model, light_lightness_linear_tt_values(state, tt, delay); } else { light_lightness_linear_publish(model); - return; + return 0; } /* For Instantaneous Transition */ @@ -1515,9 +1569,10 @@ static void light_lightness_linear_set_unack(struct bt_mesh_model *model, state->transition->just_started = true; light_lightness_linear_publish(model); light_lightness_linear_handler(state); + return 0; } -static void light_lightness_linear_set(struct bt_mesh_model *model, +static int light_lightness_linear_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1525,6 +1580,7 @@ static void light_lightness_linear_set(struct bt_mesh_model *model, uint16_t linear; int64_t now; struct light_lightness_state *state = model->user_data; + int rc; linear = net_buf_simple_pull_le16(buf); tid = net_buf_simple_pull_u8(buf); @@ -1534,8 +1590,7 @@ static void light_lightness_linear_set(struct bt_mesh_model *model, state->last_src_addr == ctx->addr && state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { - light_lightness_linear_get(model, ctx, buf); - return; + return light_lightness_linear_get(model, ctx, buf); } switch (buf->om_len) { @@ -1546,13 +1601,13 @@ static void light_lightness_linear_set(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -1567,9 +1622,9 @@ static void light_lightness_linear_set(struct bt_mesh_model *model, if (state->target_linear != state->linear) { light_lightness_linear_tt_values(state, tt, delay); } else { - light_lightness_linear_get(model, ctx, buf); + rc = light_lightness_linear_get(model, ctx, buf); light_lightness_linear_publish(model); - return; + return rc; } /* For Instantaneous Transition */ @@ -1581,9 +1636,10 @@ static void light_lightness_linear_set(struct bt_mesh_model *model, light_lightness_linear_get(model, ctx, buf); light_lightness_linear_publish(model); light_lightness_linear_handler(state); + return 0; } -static void light_lightness_last_get(struct bt_mesh_model *model, +static int light_lightness_last_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1598,9 +1654,10 @@ static void light_lightness_last_get(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + return 0; } -static void light_lightness_default_get(struct bt_mesh_model *model, +static int light_lightness_default_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1616,9 +1673,10 @@ static void light_lightness_default_get(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + return 0; } -static void light_lightness_range_get(struct bt_mesh_model *model, +static int light_lightness_range_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1637,18 +1695,19 @@ static void light_lightness_range_get(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + return 0; } /* Light Lightness Setup Server message handlers */ -static void light_lightness_default_publish(struct bt_mesh_model *model) +static int light_lightness_default_publish(struct bt_mesh_model *model) { int err; struct os_mbuf *msg = model->pub->msg; struct light_lightness_state *state = model->user_data; if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - return; + return 0; } bt_mesh_model_msg_init(msg, @@ -1659,9 +1718,10 @@ static void light_lightness_default_publish(struct bt_mesh_model *model) if (err) { printk("bt_mesh_model_publish err %d\n", err); } + return err; } -static void light_lightness_default_set_unack(struct bt_mesh_model *model, +static int light_lightness_default_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1679,26 +1739,37 @@ static void light_lightness_default_set_unack(struct bt_mesh_model *model, save_on_flash(LIGHTNESS_TEMP_DEF_STATE); } - light_lightness_default_publish(model); + return light_lightness_default_publish(model); } -static void light_lightness_default_set(struct bt_mesh_model *model, +static int light_lightness_default_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - light_lightness_default_set_unack(model, ctx, buf); - light_lightness_default_get(model, ctx, buf); - light_lightness_default_publish(model); + int rc; + rc = light_lightness_default_set_unack(model, ctx, buf); + if (rc) { + return rc; + } + rc = light_lightness_default_get(model, ctx, buf); + if (rc) { + return rc; + } + rc = light_lightness_default_publish(model); + if (rc) { + return rc; + } + return 0; } -static void light_lightness_range_publish(struct bt_mesh_model *model) +static int light_lightness_range_publish(struct bt_mesh_model *model) { int err; struct os_mbuf *msg = model->pub->msg; struct light_lightness_state *state = model->user_data; if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - return; + return 0; } bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_LIGHTNESS_RANGE_STATUS); @@ -1710,6 +1781,7 @@ static void light_lightness_range_publish(struct bt_mesh_model *model) if (err) { printk("bt_mesh_model_publish err %d\n", err); } + return err; } static bool light_lightness_range_setunack(struct bt_mesh_model *model, @@ -1748,27 +1820,36 @@ static bool light_lightness_range_setunack(struct bt_mesh_model *model, return true; } -static void light_lightness_range_set_unack(struct bt_mesh_model *model, +static int light_lightness_range_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { if (light_lightness_range_setunack(model, ctx, buf) == true) { - light_lightness_range_publish(model); + return light_lightness_range_publish(model); } + return 0; } -static void light_lightness_range_set(struct bt_mesh_model *model, +static int light_lightness_range_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { + int rc; if (light_lightness_range_setunack(model, ctx, buf) == true) { - light_lightness_range_get(model, ctx, buf); - light_lightness_range_publish(model); + rc = light_lightness_range_get(model, ctx, buf); + if (rc) { + return rc; + } + rc = light_lightness_range_publish(model); + if (rc) { + return rc; + } } + return 0; } /* Light Lightness Client message handlers */ -static void light_lightness_status(struct bt_mesh_model *model, +static int light_lightness_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1780,9 +1861,10 @@ static void light_lightness_status(struct bt_mesh_model *model, net_buf_simple_pull_le16(buf)); printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf)); } + return 0; } -static void light_lightness_linear_status(struct bt_mesh_model *model, +static int light_lightness_linear_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1794,25 +1876,28 @@ static void light_lightness_linear_status(struct bt_mesh_model *model, net_buf_simple_pull_le16(buf)); printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf)); } + return 0; } -static void light_lightness_last_status(struct bt_mesh_model *model, +static int light_lightness_last_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { printk("Acknownledgement from LIGHT_LIGHTNESS_SRV (Last)\n"); printk("Lightness = %04x\n", net_buf_simple_pull_le16(buf)); + return 0; } -static void light_lightness_default_status(struct bt_mesh_model *model, +static int light_lightness_default_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { printk("Acknownledgement from LIGHT_LIGHTNESS_SRV (Default)\n"); printk("Lightness = %04x\n", net_buf_simple_pull_le16(buf)); + return 0; } -static void light_lightness_range_status(struct bt_mesh_model *model, +static int light_lightness_range_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1820,10 +1905,11 @@ static void light_lightness_range_status(struct bt_mesh_model *model, printk("Status Code = %02x\n", net_buf_simple_pull_u8(buf)); printk("Range Min = %04x\n", net_buf_simple_pull_le16(buf)); printk("Range Max = %04x\n", net_buf_simple_pull_le16(buf)); + return 0; } /* Light CTL Server message handlers */ -static void light_ctl_get(struct bt_mesh_model *model, +static int light_ctl_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1846,16 +1932,17 @@ static void light_ctl_get(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + return 0; } -void light_ctl_publish(struct bt_mesh_model *model) +int light_ctl_publish(struct bt_mesh_model *model) { int err; struct os_mbuf *msg = model->pub->msg; struct light_ctl_state *state = model->user_data; if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - return; + return 0; } bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_CTL_STATUS); @@ -1877,9 +1964,10 @@ void light_ctl_publish(struct bt_mesh_model *model) if (err) { printk("bt_mesh_model_publish err %d\n", err); } + return err; } -static void light_ctl_set_unack(struct bt_mesh_model *model, +static int light_ctl_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1895,7 +1983,7 @@ static void light_ctl_set_unack(struct bt_mesh_model *model, tid = net_buf_simple_pull_u8(buf); if (temp < TEMP_MIN || temp > TEMP_MAX) { - return; + return 0; } now = k_uptime_get(); @@ -1903,7 +1991,7 @@ static void light_ctl_set_unack(struct bt_mesh_model *model, state->last_src_addr == ctx->addr && state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { - return; + return 0; } switch (buf->om_len) { @@ -1914,13 +2002,13 @@ static void light_ctl_set_unack(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -1947,7 +2035,7 @@ static void light_ctl_set_unack(struct bt_mesh_model *model, light_ctl_tt_values(state, tt, delay); } else { light_ctl_publish(model); - return; + return 0; } /* For Instantaneous Transition */ @@ -1960,9 +2048,10 @@ static void light_ctl_set_unack(struct bt_mesh_model *model, state->transition->just_started = true; light_ctl_publish(model); light_ctl_handler(state); + return 0; } -static void light_ctl_set(struct bt_mesh_model *model, +static int light_ctl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -1978,7 +2067,7 @@ static void light_ctl_set(struct bt_mesh_model *model, tid = net_buf_simple_pull_u8(buf); if (temp < TEMP_MIN || temp > TEMP_MAX) { - return; + return 0; } now = k_uptime_get(); @@ -1987,7 +2076,7 @@ static void light_ctl_set(struct bt_mesh_model *model, state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { light_ctl_get(model, ctx, buf); - return; + return 0; } switch (buf->om_len) { @@ -1998,13 +2087,13 @@ static void light_ctl_set(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -2032,7 +2121,7 @@ static void light_ctl_set(struct bt_mesh_model *model, } else { light_ctl_get(model, ctx, buf); light_ctl_publish(model); - return; + return 0; } /* For Instantaneous Transition */ @@ -2046,14 +2135,16 @@ static void light_ctl_set(struct bt_mesh_model *model, light_ctl_get(model, ctx, buf); light_ctl_publish(model); light_ctl_handler(state); + return 0; } -static void light_ctl_temp_range_get(struct bt_mesh_model *model, +static int light_ctl_temp_range_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 5 + 4); struct light_ctl_state *state = model->user_data; + int rc; state->status_code = RANGE_SUCCESSFULLY_UPDATED; @@ -2062,42 +2153,47 @@ static void light_ctl_temp_range_get(struct bt_mesh_model *model, net_buf_simple_add_le16(msg, state->temp_range_min); net_buf_simple_add_le16(msg, state->temp_range_max); - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + rc = bt_mesh_model_send(model, ctx, msg, NULL, NULL); + if (rc) { printk("Unable to send LightCTL Temp Range Status response\n"); } os_mbuf_free_chain(msg); + return rc; } -static void light_ctl_default_get(struct bt_mesh_model *model, +static int light_ctl_default_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 6 + 4); struct light_ctl_state *state = model->user_data; + int rc; bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_CTL_DEFAULT_STATUS); net_buf_simple_add_le16(msg, state->lightness_def); net_buf_simple_add_le16(msg, state->temp_def); net_buf_simple_add_le16(msg, state->delta_uv_def); - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + rc = bt_mesh_model_send(model, ctx, msg, NULL, NULL); + if (rc) { printk("Unable to send LightCTL Default Status response\n"); } os_mbuf_free_chain(msg); + return rc; } /* Light CTL Setup Server message handlers */ -static void light_ctl_default_publish(struct bt_mesh_model *model) +static int light_ctl_default_publish(struct bt_mesh_model *model) { int err; struct os_mbuf *msg = model->pub->msg; struct light_ctl_state *state = model->user_data; if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - return; + return 0; } bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_CTL_DEFAULT_STATUS); @@ -2109,6 +2205,7 @@ static void light_ctl_default_publish(struct bt_mesh_model *model) if (err) { printk("bt_mesh_model_publish err %d\n", err); } + return err; } static bool light_ctl_default_setunack(struct bt_mesh_model *model, @@ -2147,33 +2244,35 @@ static bool light_ctl_default_setunack(struct bt_mesh_model *model, return true; } -static void light_ctl_default_set_unack(struct bt_mesh_model *model, +static int light_ctl_default_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { if (light_ctl_default_setunack(model, ctx, buf) == true) { - light_ctl_default_publish(model); + return light_ctl_default_publish(model); } + return 0; } -static void light_ctl_default_set(struct bt_mesh_model *model, +static int light_ctl_default_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { if (light_ctl_default_setunack(model, ctx, buf) == true) { light_ctl_default_get(model, ctx, buf); - light_ctl_default_publish(model); + return light_ctl_default_publish(model); } + return 0; } -static void light_ctl_temp_range_publish(struct bt_mesh_model *model) +static int light_ctl_temp_range_publish(struct bt_mesh_model *model) { int err; struct os_mbuf *msg = model->pub->msg; struct light_ctl_state *state = model->user_data; if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - return; + return 0; } bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_CTL_TEMP_RANGE_STATUS); @@ -2185,6 +2284,7 @@ static void light_ctl_temp_range_publish(struct bt_mesh_model *model) if (err) { printk("bt_mesh_model_publish err %d\n", err); } + return err; } static bool light_ctl_temp_range_setunack(struct bt_mesh_model *model, @@ -2225,27 +2325,29 @@ static bool light_ctl_temp_range_setunack(struct bt_mesh_model *model, return true; } -static void light_ctl_temp_range_set_unack(struct bt_mesh_model *model, +static int light_ctl_temp_range_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { if (light_ctl_temp_range_setunack(model, ctx, buf) == true) { - light_ctl_temp_range_publish(model); + return light_ctl_temp_range_publish(model); } + return 0; } -static void light_ctl_temp_range_set(struct bt_mesh_model *model, +static int light_ctl_temp_range_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { if (light_ctl_temp_range_setunack(model, ctx, buf) == true) { light_ctl_temp_range_get(model, ctx, buf); - light_ctl_temp_range_publish(model); + return light_ctl_temp_range_publish(model); } + return 0; } /* Light CTL Client message handlers */ -static void light_ctl_status(struct bt_mesh_model *model, +static int light_ctl_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -2261,9 +2363,10 @@ static void light_ctl_status(struct bt_mesh_model *model, net_buf_simple_pull_le16(buf)); printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf)); } + return 0; } -static void light_ctl_temp_range_status(struct bt_mesh_model *model, +static int light_ctl_temp_range_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -2271,9 +2374,10 @@ static void light_ctl_temp_range_status(struct bt_mesh_model *model, printk("Status Code = %02x\n", net_buf_simple_pull_u8(buf)); printk("Range Min = %04x\n", net_buf_simple_pull_le16(buf)); printk("Range Max = %04x\n", net_buf_simple_pull_le16(buf)); + return 0; } -static void light_ctl_temp_status(struct bt_mesh_model *model, +static int light_ctl_temp_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -2290,9 +2394,10 @@ static void light_ctl_temp_status(struct bt_mesh_model *model, net_buf_simple_pull_le16(buf)); printk("Remaining Time = %02x\n", net_buf_simple_pull_u8(buf)); } + return 0; } -static void light_ctl_default_status(struct bt_mesh_model *model, +static int light_ctl_default_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -2300,10 +2405,11 @@ static void light_ctl_default_status(struct bt_mesh_model *model, printk("Lightness = %04x\n", net_buf_simple_pull_le16(buf)); printk("Temperature = %04x\n", net_buf_simple_pull_le16(buf)); printk("Delta UV = %04x\n", net_buf_simple_pull_le16(buf)); + return 0; } /* Light CTL Temp. Server message handlers */ -static void light_ctl_temp_get(struct bt_mesh_model *model, +static int light_ctl_temp_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -2326,16 +2432,17 @@ static void light_ctl_temp_get(struct bt_mesh_model *model, } os_mbuf_free_chain(msg); + return 0; } -void light_ctl_temp_publish(struct bt_mesh_model *model) +int light_ctl_temp_publish(struct bt_mesh_model *model) { int err; struct os_mbuf *msg = model->pub->msg; struct light_ctl_state *state = model->user_data; if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { - return; + return 0; } bt_mesh_model_msg_init(msg, BT_MESH_MODEL_LIGHT_CTL_TEMP_STATUS); @@ -2353,9 +2460,10 @@ void light_ctl_temp_publish(struct bt_mesh_model *model) if (err) { printk("bt_mesh_model_publish err %d\n", err); } + return err; } -static void light_ctl_temp_set_unack(struct bt_mesh_model *model, +static int light_ctl_temp_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -2370,7 +2478,7 @@ static void light_ctl_temp_set_unack(struct bt_mesh_model *model, tid = net_buf_simple_pull_u8(buf); if (temp < TEMP_MIN || temp > TEMP_MAX) { - return; + return 0; } now = k_uptime_get(); @@ -2378,7 +2486,7 @@ static void light_ctl_temp_set_unack(struct bt_mesh_model *model, state->last_src_addr == ctx->addr && state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { - return; + return 0; } switch (buf->om_len) { @@ -2389,13 +2497,13 @@ static void light_ctl_temp_set_unack(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -2420,7 +2528,7 @@ static void light_ctl_temp_set_unack(struct bt_mesh_model *model, light_ctl_temp_tt_values(state, tt, delay); } else { light_ctl_temp_publish(model); - return; + return 0; } /* For Instantaneous Transition */ @@ -2432,9 +2540,10 @@ static void light_ctl_temp_set_unack(struct bt_mesh_model *model, state->transition->just_started = true; light_ctl_temp_publish(model); light_ctl_temp_handler(state); + return 0; } -static void light_ctl_temp_set(struct bt_mesh_model *model, +static int light_ctl_temp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -2449,7 +2558,7 @@ static void light_ctl_temp_set(struct bt_mesh_model *model, tid = net_buf_simple_pull_u8(buf); if (temp < TEMP_MIN || temp > TEMP_MAX) { - return; + return 0; } now = k_uptime_get(); @@ -2457,8 +2566,7 @@ static void light_ctl_temp_set(struct bt_mesh_model *model, state->last_src_addr == ctx->addr && state->last_dst_addr == ctx->recv_dst && (now - state->last_msg_timestamp <= K_SECONDS(6))) { - light_ctl_temp_get(model, ctx, buf); - return; + return light_ctl_temp_get(model, ctx, buf); } switch (buf->om_len) { @@ -2469,13 +2577,13 @@ static void light_ctl_temp_set(struct bt_mesh_model *model, case 0x02: /* Optional fields are available */ tt = net_buf_simple_pull_u8(buf); if ((tt & 0x3F) == 0x3F) { - return; + return 0; } delay = net_buf_simple_pull_u8(buf); break; default: - return; + return 0; } *ptr_counter = 0; @@ -2501,7 +2609,7 @@ static void light_ctl_temp_set(struct bt_mesh_model *model, } else { light_ctl_temp_get(model, ctx, buf); light_ctl_temp_publish(model); - return; + return 0; } /* For Instantaneous Transition */ @@ -2514,6 +2622,7 @@ static void light_ctl_temp_set(struct bt_mesh_model *model, light_ctl_temp_get(model, ctx, buf); light_ctl_temp_publish(model); light_ctl_temp_handler(state); + return 0; } /* message handlers (End) */ diff --git a/apps/blemesh_models_example_2/src/device_composition.h b/apps/blemesh_models_example_2/src/device_composition.h index d0f054ee2b..1b5bf5f72a 100644 --- a/apps/blemesh_models_example_2/src/device_composition.h +++ b/apps/blemesh_models_example_2/src/device_composition.h @@ -167,11 +167,11 @@ extern struct bt_mesh_model s0_models[]; extern const struct bt_mesh_comp comp; -void gen_onoff_publish(struct bt_mesh_model *model); -void gen_level_publish(struct bt_mesh_model *model); -void light_lightness_publish(struct bt_mesh_model *model); -void light_lightness_linear_publish(struct bt_mesh_model *model); -void light_ctl_publish(struct bt_mesh_model *model); -void light_ctl_temp_publish(struct bt_mesh_model *model); +int gen_onoff_publish(struct bt_mesh_model *model); +int gen_level_publish(struct bt_mesh_model *model); +int light_lightness_publish(struct bt_mesh_model *model); +int light_lightness_linear_publish(struct bt_mesh_model *model); +int light_ctl_publish(struct bt_mesh_model *model); +int light_ctl_temp_publish(struct bt_mesh_model *model); #endif From 039e3ca80e7e333dc9b726c6f4da1eaebdfe3265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 25 Oct 2021 10:09:15 +0200 Subject: [PATCH 0164/1333] host/mesh: add preprocessor directives for persistent storage After `settings` module was split among others it's necessary to compile methods depending on peristent storage only when it's enabled. --- nimble/host/mesh/src/access.c | 6 ++++++ nimble/host/mesh/src/app_keys.c | 14 ++++++++++++++ nimble/host/mesh/src/cfg.c | 5 ++++- nimble/host/mesh/src/heartbeat.c | 6 +++++- nimble/host/mesh/src/net.c | 10 ++++++++++ nimble/host/mesh/src/pb_gatt_srv.c | 2 +- nimble/host/mesh/src/proxy_msg.c | 2 +- nimble/host/mesh/src/proxy_msg.h | 2 +- nimble/host/mesh/src/rpl.c | 16 ++++++++++++++++ nimble/host/mesh/src/subnet.c | 18 +++++++++++++++++- nimble/host/mesh/src/transport.c | 6 ++++++ 11 files changed, 81 insertions(+), 6 deletions(-) diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index 28402885c6..e498910dbd 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -875,6 +875,7 @@ bool bt_mesh_model_is_extended(struct bt_mesh_model *model) return model->flags & BT_MESH_MOD_EXTENDED; } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static int mod_set_bind(struct bt_mesh_model *mod, char *val) { int len, err, i; @@ -1246,6 +1247,7 @@ int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, } return err; } +#endif static void commit_mod(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data) @@ -1276,6 +1278,7 @@ void bt_mesh_model_settings_commit(void) bt_mesh_model_foreach(commit_mod, NULL); } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static struct conf_handler bt_mesh_sig_mod_conf_handler = { .ch_name = "bt_mesh", .ch_get = NULL, @@ -1291,9 +1294,11 @@ static struct conf_handler bt_mesh_vnd_mod_conf_handler = { .ch_commit = NULL, .ch_export = NULL, }; +#endif void bt_mesh_access_init(void) { + #if MYNEWT_VAL(BLE_MESH_SETTINGS) int rc; rc = conf_register(&bt_mesh_sig_mod_conf_handler); @@ -1304,4 +1309,5 @@ void bt_mesh_access_init(void) SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_access conf"); + #endif } \ No newline at end of file diff --git a/nimble/host/mesh/src/app_keys.c b/nimble/host/mesh/src/app_keys.c index e13245af8a..97589968d9 100644 --- a/nimble/host/mesh/src/app_keys.c +++ b/nimble/host/mesh/src/app_keys.c @@ -76,6 +76,7 @@ static struct app_key *app_get(uint16_t app_idx) static void clear_app_key(uint16_t app_idx) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) char path[20]; int err; @@ -88,10 +89,12 @@ static void clear_app_key(uint16_t app_idx) } else { BT_DBG("Cleared AppKeyIndex 0x%03x", app_idx); } +#endif } static void store_app_key(uint16_t app_idx) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) const struct app_key *app; struct app_key_val key; char path[20]; @@ -120,8 +123,10 @@ static void store_app_key(uint16_t app_idx) } else { BT_DBG("Stored AppKey %s value"); } +#endif } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static struct app_key_update *app_key_update_find(uint16_t key_idx, struct app_key_update **free_slot) { @@ -146,9 +151,11 @@ static struct app_key_update *app_key_update_find(uint16_t key_idx, return match; } +#endif static void update_app_key_settings(uint16_t app_idx, bool store) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) struct app_key_update *update, *free_slot; uint8_t clear = store ? 0U : 1U; @@ -175,6 +182,7 @@ static void update_app_key_settings(uint16_t app_idx, bool store) free_slot->clear = clear; bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_APP_KEYS_PENDING); +#endif } static void app_key_evt(struct app_key *app, enum bt_mesh_key_evt evt) @@ -629,6 +637,7 @@ void bt_mesh_app_keys_reset(void) } } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static int app_key_set(int argc, char **argv, char *val) { struct app_key_val key; @@ -662,6 +671,7 @@ static int app_key_set(int argc, char **argv, char *val) return 0; } +#endif void bt_mesh_app_key_pending_store(void) { @@ -684,6 +694,7 @@ void bt_mesh_app_key_pending_store(void) } } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static struct conf_handler bt_mesh_app_key_conf_handler = { .ch_name = "bt_mesh", .ch_get = NULL, @@ -691,13 +702,16 @@ static struct conf_handler bt_mesh_app_key_conf_handler = { .ch_commit = NULL, .ch_export = NULL, }; +#endif void bt_mesh_app_key_init(void) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) int rc; rc = conf_register(&bt_mesh_app_key_conf_handler); SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_app_key conf"); +#endif } \ No newline at end of file diff --git a/nimble/host/mesh/src/cfg.c b/nimble/host/mesh/src/cfg.c index e866cb7911..ec68cac7b7 100644 --- a/nimble/host/mesh/src/cfg.c +++ b/nimble/host/mesh/src/cfg.c @@ -250,6 +250,7 @@ bool bt_mesh_fixed_group_match(uint16_t addr) } } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static int cfg_set(int argc, char **argv, char *val) { struct cfg_val cfg; @@ -329,7 +330,6 @@ static void store_pending_cfg(void) } } - void bt_mesh_cfg_pending_store(void) { if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { @@ -346,15 +346,18 @@ static struct conf_handler bt_mesh_cfg_conf_handler = { .ch_commit = NULL, .ch_export = NULL, }; +#endif void bt_mesh_cfg_default_set(void) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) int rc; rc = conf_register(&bt_mesh_cfg_conf_handler); SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_settings conf"); +#endif bt_mesh.default_ttl = CONFIG_BT_MESH_DEFAULT_TTL; bt_mesh.net_xmit = diff --git a/nimble/host/mesh/src/heartbeat.c b/nimble/host/mesh/src/heartbeat.c index 1d249b4899..50cfdb6d5b 100644 --- a/nimble/host/mesh/src/heartbeat.c +++ b/nimble/host/mesh/src/heartbeat.c @@ -371,6 +371,7 @@ void bt_mesh_hb_resume(void) } } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static int hb_pub_set(int argc, char **argv, char *val) { struct bt_mesh_hb_pub pub; @@ -447,14 +448,17 @@ static struct conf_handler bt_mesh_hb_pub_conf_handler = { .ch_set = hb_pub_set, .ch_commit = NULL, .ch_export = NULL, - }; +}; +#endif void bt_mesh_hb_pub_init(void) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) int rc; rc = conf_register(&bt_mesh_hb_pub_conf_handler); SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_hb_pub conf"); +#endif } \ No newline at end of file diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index f994bcc747..a36160d778 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -148,22 +148,26 @@ static void msg_cache_add(struct bt_mesh_net_rx *rx) static void store_iv(bool only_duration) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_IV_PENDING); if (!only_duration) { /* Always update Seq whenever IV changes */ bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_SEQ_PENDING); } +#endif } static void store_seq(void) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) if (CONFIG_BT_MESH_SEQ_STORE_RATE > 1 && (bt_mesh.seq % CONFIG_BT_MESH_SEQ_STORE_RATE)) { return; } bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_SEQ_PENDING); +#endif } int bt_mesh_net_create(uint16_t idx, uint8_t flags, const uint8_t key[16], @@ -898,6 +902,7 @@ static void ivu_refresh(struct ble_npl_event *work) } } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static int net_set(int argc, char **argv, char *val) { struct net_val net; @@ -1031,11 +1036,13 @@ static struct conf_handler bt_mesh_seq_conf_handler = { .ch_commit = NULL, .ch_export = NULL, }; +#endif void bt_mesh_net_init(void) { int rc; +#if MYNEWT_VAL(BLE_MESH_SETTINGS) rc = conf_register(&bt_mesh_net_conf_handler); SYSINIT_PANIC_ASSERT_MSG(rc == 0, @@ -1051,6 +1058,7 @@ void bt_mesh_net_init(void) SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_seq conf"); +#endif k_work_init_delayable(&bt_mesh.ivu_timer, ivu_refresh); @@ -1068,6 +1076,7 @@ void bt_mesh_net_init(void) assert(rc == 0); } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static void clear_iv(void) { int err; @@ -1204,6 +1213,7 @@ void bt_mesh_net_clear(void) bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_CFG_PENDING); bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_SEQ_PENDING); } +#endif void bt_mesh_net_settings_commit(void) { diff --git a/nimble/host/mesh/src/pb_gatt_srv.c b/nimble/host/mesh/src/pb_gatt_srv.c index d04948262d..94dcd174a8 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.c +++ b/nimble/host/mesh/src/pb_gatt_srv.c @@ -104,7 +104,7 @@ static void proxy_msg_recv(struct bt_mesh_proxy_role *role) static bool service_registered; -static ssize_t gatt_recv(uint16_t conn_handle, uint16_t attr_handle, +static int gatt_recv(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { const uint8_t *data = ctxt->om->om_data; diff --git a/nimble/host/mesh/src/proxy_msg.c b/nimble/host/mesh/src/proxy_msg.c index 91b4ba694a..1ed3acdc51 100644 --- a/nimble/host/mesh/src/proxy_msg.c +++ b/nimble/host/mesh/src/proxy_msg.c @@ -50,7 +50,7 @@ static uint8_t bufs[CONFIG_BT_MAX_CONN * CONFIG_BT_MESH_PROXY_MSG_LEN]; static struct bt_mesh_proxy_role roles[CONFIG_BT_MAX_CONN]; -ssize_t bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, +int bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, const void *buf, uint16_t len) { const uint8_t *data = buf; diff --git a/nimble/host/mesh/src/proxy_msg.h b/nimble/host/mesh/src/proxy_msg.h index befdb1f351..0e06c5cae5 100644 --- a/nimble/host/mesh/src/proxy_msg.h +++ b/nimble/host/mesh/src/proxy_msg.h @@ -55,7 +55,7 @@ struct bt_mesh_proxy_client { struct ble_npl_callout send_beacons; }; -ssize_t bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, +int bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, const void *buf, uint16_t len); int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, struct os_mbuf *msg, void (*end)(uint16_t, void *), void *user_data); diff --git a/nimble/host/mesh/src/rpl.c b/nimble/host/mesh/src/rpl.c index bf5743e417..6fd08b2feb 100644 --- a/nimble/host/mesh/src/rpl.c +++ b/nimble/host/mesh/src/rpl.c @@ -34,6 +34,7 @@ static inline int rpl_idx(const struct bt_mesh_rpl *rpl) static void clear_rpl(struct bt_mesh_rpl *rpl) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) int err; char path[18]; @@ -51,10 +52,12 @@ static void clear_rpl(struct bt_mesh_rpl *rpl) (void)memset(rpl, 0, sizeof(*rpl)); atomic_clear_bit(store, rpl_idx(rpl)); +#endif } static void schedule_rpl_store(struct bt_mesh_rpl *entry, bool force) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) atomic_set_bit(store, rpl_idx(entry)); bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); if (force @@ -64,11 +67,14 @@ static void schedule_rpl_store(struct bt_mesh_rpl *entry, bool force) ) { bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); } +#endif } static void schedule_rpl_clear(void) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); +#endif } void bt_mesh_rpl_update(struct bt_mesh_rpl *rpl, @@ -160,6 +166,7 @@ void bt_mesh_rpl_clear(void) } } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static struct bt_mesh_rpl *bt_mesh_rpl_find(uint16_t src) { int i; @@ -186,6 +193,7 @@ static struct bt_mesh_rpl *bt_mesh_rpl_alloc(uint16_t src) return NULL; } +#endif void bt_mesh_rpl_reset(void) { @@ -214,6 +222,7 @@ void bt_mesh_rpl_reset(void) } } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static int rpl_set(int argc, char **argv, char *val) { struct bt_mesh_rpl *entry; @@ -268,9 +277,11 @@ static int rpl_set(int argc, char **argv, char *val) (unsigned) entry->seq, entry->old_iv); return 0; } +#endif static void store_rpl(struct bt_mesh_rpl *entry) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) char buf[BT_SETTINGS_SIZE(sizeof(struct rpl_val))]; struct rpl_val rpl; char path[18]; @@ -302,6 +313,7 @@ static void store_rpl(struct bt_mesh_rpl *entry) } else { BT_DBG("Stored RPL"); } +#endif } static void store_pending_rpl(struct bt_mesh_rpl *rpl) @@ -345,6 +357,7 @@ void bt_mesh_rpl_pending_store(uint16_t addr) } } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static struct conf_handler bt_mesh_rpl_conf_handler = { .ch_name = "bt_mesh", .ch_get = NULL, @@ -352,13 +365,16 @@ static struct conf_handler bt_mesh_rpl_conf_handler = { .ch_commit = NULL, .ch_export = NULL, }; +#endif void bt_mesh_rpl_init(void) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) int rc; rc = conf_register(&bt_mesh_rpl_conf_handler); SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_rpl conf"); +#endif } \ No newline at end of file diff --git a/nimble/host/mesh/src/subnet.c b/nimble/host/mesh/src/subnet.c index 71d7b3d1ab..14aa8623f7 100644 --- a/nimble/host/mesh/src/subnet.c +++ b/nimble/host/mesh/src/subnet.c @@ -73,6 +73,7 @@ static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt) static void clear_net_key(uint16_t net_idx) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) char path[20]; int err; @@ -85,10 +86,12 @@ static void clear_net_key(uint16_t net_idx) } else { BT_DBG("Cleared NetKeyIndex 0x%03x", net_idx); } +#endif } static void store_subnet(uint16_t net_idx) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) const struct bt_mesh_subnet *sub; struct net_key_val key; char buf[BT_SETTINGS_SIZE(sizeof(struct net_key_val))]; @@ -123,8 +126,10 @@ static void store_subnet(uint16_t net_idx) } else { BT_DBG("Stored NetKey"); } +#endif } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static struct net_key_update *net_key_update_find(uint16_t key_idx, struct net_key_update **free_slot) { @@ -149,6 +154,7 @@ static struct net_key_update *net_key_update_find(uint16_t key_idx, return match; } +#endif uint8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub) { @@ -167,6 +173,7 @@ uint8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub) static void update_subnet_settings(uint16_t net_idx, bool store) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) struct net_key_update *update, *free_slot; uint8_t clear = store ? 0U : 1U; @@ -194,12 +201,15 @@ static void update_subnet_settings(uint16_t net_idx, bool store) free_slot->clear = clear; bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_NET_KEYS_PENDING); +#endif } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) void bt_mesh_subnet_store(uint16_t net_idx) { update_subnet_settings(net_idx, true); } +#endif static void key_refresh(struct bt_mesh_subnet *sub, uint8_t new_phase) { @@ -800,6 +810,7 @@ bool bt_mesh_net_cred_find(struct bt_mesh_net_rx *rx, struct os_mbuf *in, return false; } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static int net_key_set(int argc, char **argv, char *val) { struct net_key_val key; @@ -828,6 +839,7 @@ static int net_key_set(int argc, char **argv, char *val) net_idx, key.kr_phase, key.val[0], (key.kr_phase != BT_MESH_KR_NORMAL) ? key.val[1] : NULL); } +#endif void bt_mesh_subnet_pending_store(void) { @@ -850,20 +862,24 @@ void bt_mesh_subnet_pending_store(void) } } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static struct conf_handler bt_mesh_net_key_conf_handler = { .ch_name = "bt_mesh", .ch_get = NULL, .ch_set = net_key_set, .ch_commit = NULL, .ch_export = NULL, - }; +}; +#endif void bt_mesh_net_key_init(void) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) int rc; rc = conf_register(&bt_mesh_net_key_conf_handler); SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_net_key conf"); +#endif } \ No newline at end of file diff --git a/nimble/host/mesh/src/transport.c b/nimble/host/mesh/src/transport.c index b1d41dbf53..d563c9fa05 100644 --- a/nimble/host/mesh/src/transport.c +++ b/nimble/host/mesh/src/transport.c @@ -1638,7 +1638,9 @@ void bt_mesh_rx_reset(void) static void store_va_label(void) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_VA_PENDING); +#endif } void bt_mesh_trans_reset(void) @@ -1787,6 +1789,7 @@ uint8_t *bt_mesh_va_label_get(uint16_t addr) } #if CONFIG_BT_MESH_LABEL_COUNT > 0 +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static struct virtual_addr *bt_mesh_va_get(uint16_t index) { if (index >= ARRAY_SIZE(virtual_addrs)) { @@ -1901,15 +1904,18 @@ static struct conf_handler bt_mesh_va_conf_handler = { .ch_commit = NULL, .ch_export = NULL, }; +#endif void bt_mesh_va_init(void) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) int rc; rc = conf_register(&bt_mesh_va_conf_handler); SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_hb_pub conf"); +#endif } #else From 04d723ed0595fa9c36696fcfd63ae61714a84a8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 25 Oct 2021 13:03:08 +0200 Subject: [PATCH 0165/1333] host/mesh: define Low Latency mode for non-NimBLE controller This fixes build for porting --- nimble/host/mesh/src/adv_legacy.c | 8 +++++++- porting/examples/linux_blemesh/include/syscfg/syscfg.h | 5 +++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index ab8a921619..837eaa736d 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -22,6 +22,12 @@ /* Convert from ms to 0.625ms units */ #define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5) +#if (MYNEWT_VAL(BSP_NRF51) && !MYNEWT_VAL(BLE_CONTROLLER)) +#define CONFIG_BT_CTLR_LOW_LAT 1 +#else +#define CONFIG_BT_CTLR_LOW_LAT 0 +#endif + /* Pre-5.0 controllers enforce a minimum interval of 100ms * whereas 5.0+ controllers can go down to 20ms. */ @@ -83,7 +89,7 @@ static inline void adv_send(struct os_mbuf *buf) * amount of scan window duration to compensate for the blocked * advertising events. */ - if (MYNEWT_VAL(BSP_NRF51)) { + if (CONFIG_BT_CTLR_LOW_LAT) { duration += BT_MESH_SCAN_WINDOW_MS; } #endif diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 2fd5232b94..e132d4c065 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -1013,6 +1013,11 @@ #define MYNEWT_VAL_BLE_MESH_OOB_OUTPUT_SIZE (4) #endif + +#ifndef MYNEWT_VAL_BSP_NRF51 +#define MYNEWT_VAL_BSP_NRF51 (0) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_PB_ADV #define MYNEWT_VAL_BLE_MESH_PB_ADV (1) From 7914dbd984780c9b1adecf18030398faf6a0beb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 25 Oct 2021 13:05:59 +0200 Subject: [PATCH 0166/1333] porting/blemesh: add missing defs Added defs included in Mesh sync --- .../linux_blemesh/include/syscfg/syscfg.h | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index e132d4c065..61cc3f20e2 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -1013,6 +1013,37 @@ #define MYNEWT_VAL_BLE_MESH_OOB_OUTPUT_SIZE (4) #endif +#ifndef MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN +#if MYNEWT_VAL_BLE_MESH_PB_GATT +#define MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN (66) +#elif MYNEWT_VAL_BLE_MESH_GATT_PROXY +#define MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN (33) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_MODEL_VND_MSG_CID_FORCE +#define MYNEWT_VAL_BLE_MESH_MODEL_VND_MSG_CID_FORCE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ACCESS_LAYER_MSG +#define MYNEWT_VAL_BLE_MESH_ACCESS_LAYER_MSG (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_IV_UPDATE_SEQ_LIMIT +#define MYNEWT_VAL_BLE_MESH_IV_UPDATE_SEQ_LIMIT (0x800000) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROV_OOB_PUBLIC_KEY +#define MYNEWT_VAL_BLE_MESH_PROV_OOB_PUBLIC_KEY (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ADV_EXT +#define MYNEWT_VAL_BLE_MESH_ADV_EXT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ADV_LEGACY +#define MYNEWT_VAL_BLE_MESH_ADV_LEGACY (1) +#endif #ifndef MYNEWT_VAL_BSP_NRF51 #define MYNEWT_VAL_BSP_NRF51 (0) From 6f6fc995e58d190cd42f5afb38be947fbc1002d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 25 Oct 2021 13:06:41 +0200 Subject: [PATCH 0167/1333] host/mesh: make mesh adv thread method name consistent with porting --- nimble/host/mesh/src/adv_legacy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index 837eaa736d..e9d41a1cdf 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -131,7 +131,7 @@ static inline void adv_send(struct os_mbuf *buf) } void -adv_thread(void *args) +mesh_adv_thread(void *args) { static struct ble_npl_event *ev; struct os_mbuf *buf; @@ -222,7 +222,7 @@ void bt_mesh_adv_init(void) ble_npl_eventq_init(&adv_queue); #if MYNEWT - os_task_init(&adv_task, "mesh_adv", adv_thread, NULL, + os_task_init(&adv_task, "mesh_adv", mesh_adv_thread, NULL, MYNEWT_VAL(BLE_MESH_ADV_TASK_PRIO), OS_WAIT_FOREVER, g_blemesh_stack, MYNEWT_VAL(BLE_MESH_ADV_STACK_SIZE)); #endif From 5b71db8b5d91303f56aaf0e3b69682157fcc66be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 25 Oct 2021 14:41:21 +0200 Subject: [PATCH 0168/1333] host/mesh: fix mesh advertising thread Cleans up `bt_mesh_adv_queue` after sync --- nimble/host/mesh/src/adv.c | 3 ++- nimble/host/mesh/src/adv.h | 1 + nimble/host/mesh/src/adv_ext.c | 2 +- nimble/host/mesh/src/adv_legacy.c | 11 +++++------ 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/nimble/host/mesh/src/adv.c b/nimble/host/mesh/src/adv.c index 0b0205cbc2..c6274167a2 100644 --- a/nimble/host/mesh/src/adv.c +++ b/nimble/host/mesh/src/adv.c @@ -36,7 +36,8 @@ const uint8_t bt_mesh_adv_type[BT_MESH_ADV_TYPES] = { extern uint8_t g_mesh_addr_type; struct os_mbuf_pool adv_os_mbuf_pool; -static struct ble_npl_eventq bt_mesh_adv_queue; +struct ble_npl_eventq bt_mesh_adv_queue; + static struct bt_mesh_adv adv_pool[CONFIG_BT_MESH_ADV_BUF_COUNT]; static struct bt_mesh_adv *adv_alloc(int id) diff --git a/nimble/host/mesh/src/adv.h b/nimble/host/mesh/src/adv.h index 14be8f84f3..f531390d4d 100644 --- a/nimble/host/mesh/src/adv.h +++ b/nimble/host/mesh/src/adv.h @@ -29,6 +29,7 @@ /* We declare it as extern here to share it between 'adv' and 'adv_legacy' */ extern struct os_mbuf_pool adv_os_mbuf_pool; +extern struct ble_npl_eventq bt_mesh_adv_queue; enum bt_mesh_adv_type { diff --git a/nimble/host/mesh/src/adv_ext.c b/nimble/host/mesh/src/adv_ext.c index a531863f76..680a9ca77e 100644 --- a/nimble/host/mesh/src/adv_ext.c +++ b/nimble/host/mesh/src/adv_ext.c @@ -28,7 +28,7 @@ static struct ble_gap_ext_adv_params adv_param = { }; bool ext_adv_configured = false; -static struct ble_npl_eventq bt_mesh_adv_queue; +struct ble_npl_eventq bt_mesh_adv_queue; enum { /** Controller is currently advertising */ diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index e9d41a1cdf..0eece40fa2 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -48,7 +48,6 @@ static os_membuf_t adv_buf_mem[OS_MEMPOOL_SIZE( MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT), BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE)]; static struct os_mempool adv_buf_mempool; -static struct ble_npl_eventq adv_queue; static inline void adv_send(struct os_mbuf *buf) { @@ -143,7 +142,7 @@ mesh_adv_thread(void *args) while (1) { #if (MYNEWT_VAL(BLE_MESH_PROXY)) - ev = ble_npl_eventq_get(&adv_queue, 0); + ev = ble_npl_eventq_get(&bt_mesh_adv_queue, 0); while (!ev) { if (bt_mesh_is_provisioned()) { if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { @@ -160,11 +159,11 @@ mesh_adv_thread(void *args) timeout = ble_npl_time_ms_to_ticks32(timeout); } - ev = ble_npl_eventq_get(&adv_queue, timeout); + ev = ble_npl_eventq_get(&bt_mesh_adv_queue, timeout); bt_le_adv_stop(); } #else - ev = ble_npl_eventq_get(&adv_queue, BLE_NPL_TIME_FOREVER); + ev = ble_npl_eventq_get(&bt_mesh_adv_queue, BLE_NPL_TIME_FOREVER); #endif if (!ev || !ble_npl_event_get_arg(ev)) { @@ -191,7 +190,7 @@ void bt_mesh_adv_update(void) BT_DBG(""); - ble_npl_eventq_put(&adv_queue, &ev); + ble_npl_eventq_put(&bt_mesh_adv_queue, &ev); } void bt_mesh_adv_buf_ready(void) @@ -219,7 +218,7 @@ void bt_mesh_adv_init(void) MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT)); assert(rc == 0); - ble_npl_eventq_init(&adv_queue); + ble_npl_eventq_init(&bt_mesh_adv_queue); #if MYNEWT os_task_init(&adv_task, "mesh_adv", mesh_adv_thread, NULL, From 649fad1f2163a2d6f5c0e4998fe131fc51d6f1eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 26 Oct 2021 08:50:22 +0200 Subject: [PATCH 0169/1333] host/mesh: fix mesh_adv_thread Solved issues with adv_timeout. --- nimble/host/mesh/src/adv_legacy.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index 0eece40fa2..0698c356c7 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -48,6 +48,7 @@ static os_membuf_t adv_buf_mem[OS_MEMPOOL_SIZE( MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT), BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE)]; static struct os_mempool adv_buf_mempool; +static int32_t adv_timeout; static inline void adv_send(struct os_mbuf *buf) { @@ -134,9 +135,6 @@ mesh_adv_thread(void *args) { static struct ble_npl_event *ev; struct os_mbuf *buf; -#if (MYNEWT_VAL(BLE_MESH_PROXY)) - int32_t timeout; -#endif BT_DBG("started"); @@ -144,22 +142,21 @@ mesh_adv_thread(void *args) #if (MYNEWT_VAL(BLE_MESH_PROXY)) ev = ble_npl_eventq_get(&bt_mesh_adv_queue, 0); while (!ev) { + /* Adv timeout may be set by a call from proxy + * to bt_mesh_adv_start: + */ + adv_timeout = K_FOREVER; if (bt_mesh_is_provisioned()) { if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { - timeout = bt_mesh_proxy_adv_start(); - BT_DBG("Proxy Advertising up to %d ms", (int) timeout); + (void)bt_mesh_proxy_adv_start(); + BT_DBG("Proxy Advertising up to %d ms", (int) adv_timeout); } } else if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { - timeout = bt_mesh_pb_gatt_adv_start(); - BT_DBG("PB-GATT Advertising up to %d ms", (int) timeout); - } - - // FIXME: should we redefine K_SECONDS macro instead in glue? - if (timeout != K_FOREVER) { - timeout = ble_npl_time_ms_to_ticks32(timeout); + (void)bt_mesh_pb_gatt_adv_start(); + BT_DBG("PB-GATT Advertising up to %d ms", (int) adv_timeout); } - ev = ble_npl_eventq_get(&bt_mesh_adv_queue, timeout); + ev = ble_npl_eventq_get(&bt_mesh_adv_queue, adv_timeout); bt_le_adv_stop(); } #else @@ -244,6 +241,7 @@ int bt_mesh_adv_start(const struct ble_gap_adv_params *param, int32_t duration, const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len) { + adv_timeout = duration; return bt_le_adv_start(param, duration, ad, ad_len, sd, sd_len); } #endif \ No newline at end of file From d22137b28603e210ce314c3989c7040cd11879d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 28 Oct 2021 15:14:23 +0200 Subject: [PATCH 0170/1333] host/mesh: fix Extended Adv for mesh Fixes build and advertising. --- nimble/host/mesh/src/adv.c | 5 +++ nimble/host/mesh/src/adv.h | 2 + nimble/host/mesh/src/adv_ext.c | 65 +++++++++++-------------------- nimble/host/mesh/src/adv_legacy.c | 5 +-- 4 files changed, 30 insertions(+), 47 deletions(-) diff --git a/nimble/host/mesh/src/adv.c b/nimble/host/mesh/src/adv.c index c6274167a2..d7a8c123c9 100644 --- a/nimble/host/mesh/src/adv.c +++ b/nimble/host/mesh/src/adv.c @@ -38,6 +38,11 @@ extern uint8_t g_mesh_addr_type; struct os_mbuf_pool adv_os_mbuf_pool; struct ble_npl_eventq bt_mesh_adv_queue; +os_membuf_t adv_buf_mem[OS_MEMPOOL_SIZE( + MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT), + BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE)]; +struct os_mempool adv_buf_mempool; + static struct bt_mesh_adv adv_pool[CONFIG_BT_MESH_ADV_BUF_COUNT]; static struct bt_mesh_adv *adv_alloc(int id) diff --git a/nimble/host/mesh/src/adv.h b/nimble/host/mesh/src/adv.h index f531390d4d..aa83a47b86 100644 --- a/nimble/host/mesh/src/adv.h +++ b/nimble/host/mesh/src/adv.h @@ -30,6 +30,8 @@ /* We declare it as extern here to share it between 'adv' and 'adv_legacy' */ extern struct os_mbuf_pool adv_os_mbuf_pool; extern struct ble_npl_eventq bt_mesh_adv_queue; +extern struct os_mempool adv_buf_mempool; +extern os_membuf_t adv_buf_mem[]; enum bt_mesh_adv_type { diff --git a/nimble/host/mesh/src/adv_ext.c b/nimble/host/mesh/src/adv_ext.c index 680a9ca77e..07c693dea1 100644 --- a/nimble/host/mesh/src/adv_ext.c +++ b/nimble/host/mesh/src/adv_ext.c @@ -28,7 +28,6 @@ static struct ble_gap_ext_adv_params adv_param = { }; bool ext_adv_configured = false; -struct ble_npl_eventq bt_mesh_adv_queue; enum { /** Controller is currently advertising */ @@ -273,13 +272,13 @@ static void send_pending_adv(struct ble_npl_event *work) /* No more pending buffers */ if (bt_mesh_is_provisioned()) { - if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { - err = bt_mesh_pb_gatt_adv_start(); - BT_DBG("Proxy Advertising"); - } + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { + err = bt_mesh_proxy_adv_start(); + BT_DBG("Proxy Advertising"); + } } else if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { - err = bt_mesh_prov_adv_start(); - BT_DBG("PB-GATT Advertising"); + err = bt_mesh_pb_gatt_adv_start(); + BT_DBG("PB-GATT Advertising"); } if (!err) { @@ -301,47 +300,27 @@ void bt_mesh_adv_buf_ready(void) void bt_mesh_adv_init(void) { - k_work_init_delayable(&adv.work, send_pending_adv); -} + int rc; -int bt_mesh_adv_enable(void) -{ - struct ble_gap_ext_adv_params params; - ble_addr_t addr; - int rc; + rc = os_mempool_init(&adv_buf_mempool, MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT), + BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE, + adv_buf_mem, "adv_buf_pool"); + assert(rc == 0); - if (ext_adv_configured) { - /* Already initialized */ - return 0; - } + rc = os_mbuf_pool_init(&adv_os_mbuf_pool, &adv_buf_mempool, + BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE, + MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT)); + assert(rc == 0); - params.itvl_min = BT_MESH_ADV_SCAN_UNIT(ADV_INT_FAST_MS); - params.itvl_max = BT_MESH_ADV_SCAN_UNIT(ADV_INT_FAST_MS); + ble_npl_eventq_init(&bt_mesh_adv_queue); - if (MYNEWT_VAL(BLE_MESH_DEBUG_USE_ID_ADDR)) { - params.own_addr_type = BLE_OWN_ADDR_PUBLIC; - } else { - params.own_addr_type = BLE_OWN_ADDR_RANDOM; - /* set random (NRPA) address for instance */ - rc = ble_hs_id_gen_rnd(1, &addr); - assert (rc == 0); - - rc = ble_gap_ext_adv_set_addr(BT_ID_DEFAULT, &addr ); - assert (rc == 0); - } - - params.primary_phy = BLE_HCI_LE_PHY_1M; - params.secondary_phy = BLE_HCI_LE_PHY_1M; - params.tx_power = 127; - params.sid = 4; - - rc = ble_gap_ext_adv_configure(BT_ID_DEFAULT, ¶ms, NULL, - ble_mesh_ext_adv_event_handler, NULL); - if (rc == 0) { - ext_adv_configured = true; - } + k_work_init_delayable(&adv.work, send_pending_adv); +} - return rc; +int bt_mesh_adv_enable(void) +{ + /* No need to initialize extended advertiser instance here */ + return 0; } int bt_mesh_adv_start(const struct ble_gap_adv_params *param, int32_t duration, diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index 0698c356c7..afbfc2fcde 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -44,10 +44,7 @@ static int adv_initialized = false; OS_TASK_STACK_DEFINE(g_blemesh_stack, MYNEWT_VAL(BLE_MESH_ADV_STACK_SIZE)); struct os_task adv_task; #endif -static os_membuf_t adv_buf_mem[OS_MEMPOOL_SIZE( - MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT), - BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE)]; -static struct os_mempool adv_buf_mempool; + static int32_t adv_timeout; static inline void adv_send(struct os_mbuf *buf) From 1cc3b1daae87c8679b5e9824b4e544245fc0eae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 29 Oct 2021 14:18:53 +0200 Subject: [PATCH 0171/1333] host/mesh: post-sync fixes part 2 --- nimble/host/mesh/src/adv_legacy.c | 45 ++++++++-------- nimble/host/mesh/src/friend.c | 17 +++--- nimble/host/mesh/src/glue.c | 27 +++++----- nimble/host/mesh/src/mesh.c | 4 ++ nimble/host/mesh/src/pb_gatt.c | 9 +--- nimble/host/mesh/src/pb_gatt_srv.c | 57 ++++++++++++-------- nimble/host/mesh/src/pb_gatt_srv.h | 11 +++- nimble/host/mesh/src/proxy.h | 9 ++++ nimble/host/mesh/src/proxy_msg.c | 33 +++++++++--- nimble/host/mesh/src/proxy_msg.h | 6 +-- nimble/host/mesh/src/proxy_srv.c | 86 ++++++++++++------------------ 11 files changed, 167 insertions(+), 137 deletions(-) diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index afbfc2fcde..94065bc9bf 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -105,6 +105,8 @@ static inline void adv_send(struct os_mbuf *buf) param.itvl_max = param.itvl_min; param.conn_mode = BLE_GAP_CONN_MODE_NON; + int64_t time = k_uptime_get(); + err = bt_le_adv_start(¶m, duration, &ad, 1, NULL, 0); @@ -124,7 +126,7 @@ static inline void adv_send(struct os_mbuf *buf) return; } - BT_DBG("Advertising stopped"); + BT_DBG("Advertising stopped (%u ms)", (uint32_t) k_uptime_delta(&time)); } void @@ -136,30 +138,29 @@ mesh_adv_thread(void *args) BT_DBG("started"); while (1) { -#if (MYNEWT_VAL(BLE_MESH_PROXY)) - ev = ble_npl_eventq_get(&bt_mesh_adv_queue, 0); - while (!ev) { - /* Adv timeout may be set by a call from proxy - * to bt_mesh_adv_start: - */ - adv_timeout = K_FOREVER; - if (bt_mesh_is_provisioned()) { - if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { - (void)bt_mesh_proxy_adv_start(); - BT_DBG("Proxy Advertising up to %d ms", (int) adv_timeout); + if (MYNEWT_VAL(BLE_MESH_GATT_SERVER)) { + ev = ble_npl_eventq_get(&bt_mesh_adv_queue, 0); + while (!ev) { + /* Adv timeout may be set by a call from proxy + * to bt_mesh_adv_start: + */ + adv_timeout = K_FOREVER; + if (bt_mesh_is_provisioned()) { + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { + bt_mesh_proxy_adv_start(); + BT_DBG("Proxy Advertising up to %d ms", (int) adv_timeout); + } + } else if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { + bt_mesh_pb_gatt_adv_start(); + BT_DBG("PB-GATT Advertising up to %d ms", (int) adv_timeout); } - } else if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { - (void)bt_mesh_pb_gatt_adv_start(); - BT_DBG("PB-GATT Advertising up to %d ms", (int) adv_timeout); - } - ev = ble_npl_eventq_get(&bt_mesh_adv_queue, adv_timeout); - bt_le_adv_stop(); + ev = ble_npl_eventq_get(&bt_mesh_adv_queue, adv_timeout); + bt_le_adv_stop(); + } + } else { + ev = ble_npl_eventq_get(&bt_mesh_adv_queue, BLE_NPL_TIME_FOREVER); } -#else - ev = ble_npl_eventq_get(&bt_mesh_adv_queue, BLE_NPL_TIME_FOREVER); -#endif - if (!ev || !ble_npl_event_get_arg(ev)) { continue; } diff --git a/nimble/host/mesh/src/friend.c b/nimble/host/mesh/src/friend.c index 475fbd54e4..c7603a8d94 100644 --- a/nimble/host/mesh/src/friend.c +++ b/nimble/host/mesh/src/friend.c @@ -60,15 +60,16 @@ struct friend_pdu_info { }; static struct friend_adv { + struct bt_mesh_adv adv; uint16_t app_idx; } adv_pool[FRIEND_BUF_COUNT]; -#define FRIEND_ADV(buf) (*(struct friend_adv **)net_buf_user_data(buf)) +#define FRIEND_ADV(buf) CONTAINER_OF(BT_MESH_ADV(buf), struct friend_adv, adv) -static struct friend_adv *adv_alloc(int id) +static struct bt_mesh_adv *adv_alloc(int id) { adv_pool[id].app_idx = BT_MESH_KEY_UNUSED; - return &adv_pool[id]; + return &adv_pool[id].adv; } static bool friend_is_allocated(const struct bt_mesh_friend *frnd) @@ -308,13 +309,13 @@ static struct os_mbuf *create_friend_pdu(struct bt_mesh_friend *frnd, { struct os_mbuf *buf; - buf = os_mbuf_get_pkthdr(&friend_os_mbuf_pool, BT_MESH_ADV_USER_DATA_SIZE); + buf = bt_mesh_adv_create_from_pool(&friend_os_mbuf_pool, adv_alloc, + BT_MESH_ADV_DATA, + FRIEND_XMIT, K_NO_WAIT); if (!buf) { return NULL; } - FRIEND_ADV(buf) = adv_alloc(net_buf_id(buf)); - net_buf_add_u8(buf, (info->iv_index & 1) << 7); /* Will be reset in encryption */ if (info->ctl) { @@ -538,8 +539,8 @@ static struct os_mbuf *encode_friend_ctl(struct bt_mesh_friend *frnd, info.src = bt_mesh_primary_addr(); info.dst = frnd->lpn; - info.ctl = 1; - info.ttl = 0; + info.ctl = 1U; + info.ttl = 0U; memset(info.seq, 0, sizeof(info.seq)); diff --git a/nimble/host/mesh/src/glue.c b/nimble/host/mesh/src/glue.c index c7b2cc16f8..7a811210f3 100644 --- a/nimble/host/mesh/src/glue.c +++ b/nimble/host/mesh/src/glue.c @@ -105,6 +105,10 @@ net_buf_unref(struct os_mbuf *om) } adv = BT_MESH_ADV(om); + if (adv->started && adv->cb && adv->cb->end) { + adv->cb->end(0, adv->cb_data); + } + if (--adv->ref_cnt > 0) { return; } @@ -154,13 +158,13 @@ net_buf_simple_pull_le16(struct os_mbuf *om) uint32_t net_buf_simple_pull_le24(struct os_mbuf *om) { - uint16_t val; + uint32_t val; struct os_mbuf *old = om; - om = os_mbuf_pullup(om, sizeof(val)); + om = os_mbuf_pullup(om, 3); assert(om == old); val = get_le24(om->om_data); - os_mbuf_adj(om, sizeof(val)); + os_mbuf_adj(om, 3); return val; } @@ -445,7 +449,7 @@ k_work_cancel_delayable(struct k_work_delayable *w) void k_work_schedule(struct k_work_delayable *w, uint32_t ms) - { +{ uint32_t ticks; if (ble_npl_time_ms_to_ticks(ms, &ticks) != 0) { @@ -457,15 +461,12 @@ k_work_schedule(struct k_work_delayable *w, uint32_t ms) void k_work_reschedule(struct k_work_delayable *w, uint32_t ms) { - uint32_t ticks; + uint32_t ticks; - if (ble_npl_time_ms_to_ticks(ms, &ticks) != 0) { - assert(0); - } - if (ms == 0) { - ble_npl_callout_stop(&w->work); - } - ble_npl_callout_reset(&w->work, ticks); + if (ble_npl_time_ms_to_ticks(ms, &ticks) != 0) { + assert(0); + } + ble_npl_callout_reset(&w->work, ticks); } void @@ -825,7 +826,7 @@ bt_le_adv_start(const struct ble_gap_adv_params *param, } } - err = ble_gap_adv_start(g_mesh_addr_type, NULL, duration, param, + err = ble_gap_adv_start(g_mesh_addr_type, NULL, BLE_HS_FOREVER, param, NULL, NULL); if (err) { BT_ERR("Advertising failed: err %d", err); diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c index ccdfed37fd..6ab71e8b11 100644 --- a/nimble/host/mesh/src/mesh.c +++ b/nimble/host/mesh/src/mesh.c @@ -316,6 +316,10 @@ int bt_mesh_init(uint8_t own_addr_type, const struct bt_mesh_prov *prov, return err; } +#if (MYNEWT_VAL(BLE_MESH_PROXY)) + bt_mesh_proxy_init(); +#endif + #if (MYNEWT_VAL(BLE_MESH_PROV)) err = bt_mesh_prov_init(prov); if (err) { diff --git a/nimble/host/mesh/src/pb_gatt.c b/nimble/host/mesh/src/pb_gatt.c index 6a215e1d3a..906abd2fc9 100644 --- a/nimble/host/mesh/src/pb_gatt.c +++ b/nimble/host/mesh/src/pb_gatt.c @@ -137,13 +137,6 @@ static int link_accept(const struct prov_bearer_cb *cb, void *cb_data) return 0; } -static void buf_send_end(uint16_t conn_handle, void *user_data) -{ - if (link.comp.cb) { - link.comp.cb(0, link.comp.cb_data); - } -} - static int buf_send(struct os_mbuf *buf, prov_bearer_send_complete_t cb, void *cb_data) { @@ -156,7 +149,7 @@ static int buf_send(struct os_mbuf *buf, prov_bearer_send_complete_t cb, k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT); - return bt_mesh_pb_gatt_send(link.conn_handle, buf, buf_send_end, NULL); + return bt_mesh_pb_gatt_send(link.conn_handle, buf); } static void clear_tx(void) diff --git a/nimble/host/mesh/src/pb_gatt_srv.c b/nimble/host/mesh/src/pb_gatt_srv.c index 94dcd174a8..61fadb6fca 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.c +++ b/nimble/host/mesh/src/pb_gatt_srv.c @@ -75,17 +75,11 @@ ble_uuid16_t BT_UUID_MESH_PROXY_DATA_OUT = BLE_UUID16_INIT(0x2ade); static bool prov_fast_adv; -static struct { - uint16_t proxy_h; - uint16_t proxy_data_out_h; - uint16_t prov_h; - uint16_t prov_data_in_h; - uint16_t prov_data_out_h; -} svc_handles; +struct svc_handles svc_handles; +static atomic_t pending_notifications; static int gatt_send(uint16_t conn_handle, - const void *data, uint16_t len, - void (*end)(uint16_t, void *), void *user_data); + const void *data, uint16_t len); static struct bt_mesh_proxy_role *cli; @@ -104,15 +98,34 @@ static void proxy_msg_recv(struct bt_mesh_proxy_role *role) static bool service_registered; -static int gatt_recv(uint16_t conn_handle, uint16_t attr_handle, +static int gatt_recv_proxy(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { const uint8_t *data = ctxt->om->om_data; uint16_t len = ctxt->om->om_len; struct bt_mesh_proxy_client *client = find_client(conn_handle); + if (len < 1) { + BT_WARN("Too small Proxy PDU"); + return -EINVAL; + } + + if (PDU_TYPE(data) == BT_MESH_PROXY_PROV) { + BT_WARN("Proxy PDU type doesn't match GATT service"); + return -EINVAL; + } + + return bt_mesh_proxy_msg_recv(client->cli, data, len); +} + +static int gatt_recv_prov(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + const uint8_t *data = ctxt->om->om_data; + uint16_t len = ctxt->om->om_len; if (conn_handle != cli->conn_handle) { + BT_WARN("conn_handle != cli->conn_handle"); return -ENOTCONN; } @@ -121,12 +134,12 @@ static int gatt_recv(uint16_t conn_handle, uint16_t attr_handle, return -EINVAL; } - if (PDU_TYPE(data) == BT_MESH_PROXY_PROV) { + if (PDU_TYPE(data) != BT_MESH_PROXY_PROV) { BT_WARN("Proxy PDU type doesn't match GATT service"); return -EINVAL; } - return bt_mesh_proxy_msg_recv(client->cli, data, len); + return bt_mesh_proxy_msg_recv(cli, data, len); } void gatt_connected_pb_gatt(uint16_t conn_handle, uint8_t err) @@ -180,7 +193,7 @@ int prov_ccc_write(uint16_t conn_handle, uint8_t type) return -ENOTCONN; } - if (type != BLE_GAP_EVENT_NOTIFY_RX) { + if (type != BLE_GAP_EVENT_SUBSCRIBE) { BT_WARN("Client wrote instead enabling notify"); return BT_GATT_ERR(EINVAL); } @@ -211,7 +224,7 @@ static const struct ble_gatt_svc_def svc_defs [] = { .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), .characteristics = (struct ble_gatt_chr_def[]) { { .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_IN_VAL), - .access_cb = gatt_recv, + .access_cb = gatt_recv_proxy, .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, }, { .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL), @@ -225,7 +238,7 @@ static const struct ble_gatt_svc_def svc_defs [] = { .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), .characteristics = (struct ble_gatt_chr_def[]) { { .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL), - .access_cb = gatt_recv, + .access_cb = gatt_recv_prov, .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, }, { .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL), @@ -351,15 +364,14 @@ static const struct bt_data prov_ad[] = { BT_DATA(BT_DATA_SVC_DATA16, prov_svc_data, sizeof(prov_svc_data)), }; -int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, - void (*end)(uint16_t, void *), void *user_data) +int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf) { if (!cli || cli->conn_handle != conn_handle) { BT_ERR("No PB-GATT Client found"); return -ENOTCONN; } - return bt_mesh_proxy_msg_send(cli, BT_MESH_PROXY_PROV, buf, end, user_data); + return bt_mesh_proxy_msg_send(cli, BT_MESH_PROXY_PROV, buf); } static size_t gatt_prov_adv_create(struct bt_data prov_sd[1]) @@ -389,8 +401,7 @@ static size_t gatt_prov_adv_create(struct bt_data prov_sd[1]) } static int gatt_send(uint16_t conn_handle, - const void *data, uint16_t len, - void (*end)(uint16_t, void *), void *user_data) + const void *data, uint16_t len) { struct os_mbuf *om; int err = 0; @@ -399,9 +410,11 @@ static int gatt_send(uint16_t conn_handle, om = ble_hs_mbuf_from_flat(data, len); assert(om); err = ble_gattc_notify_custom(conn_handle, svc_handles.prov_data_out_h, om); - /* We do not pass cb into ble_gattc_notify_custom - execute it at the end */ + notify_complete(); - end(conn_handle, user_data); + if (!err) { + atomic_inc(&pending_notifications); + } return err; } diff --git a/nimble/host/mesh/src/pb_gatt_srv.h b/nimble/host/mesh/src/pb_gatt_srv.h index 364f53553e..816089477c 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.h +++ b/nimble/host/mesh/src/pb_gatt_srv.h @@ -8,8 +8,7 @@ #ifndef __PB_GATT_SRV_H__ #define __PB_GATT_SRV_H__ -int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, - void (*end)(uint16_t, void *), void *user_data); +int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf); int bt_mesh_pb_gatt_enable(void); int bt_mesh_pb_gatt_disable(void); @@ -21,4 +20,12 @@ void resolve_svc_handles(void); int bt_mesh_pb_gatt_adv_start(void); +extern struct svc_handles { + uint16_t proxy_h; + uint16_t proxy_data_out_h; + uint16_t prov_h; + uint16_t prov_data_in_h; + uint16_t prov_data_out_h; +} svc_handles; + #endif /* __PB_GATT_SRV_H__ */ \ No newline at end of file diff --git a/nimble/host/mesh/src/proxy.h b/nimble/host/mesh/src/proxy.h index f84fa424f6..42530293e9 100644 --- a/nimble/host/mesh/src/proxy.h +++ b/nimble/host/mesh/src/proxy.h @@ -9,6 +9,8 @@ #ifndef __PROXY_H__ #define __PROXY_H__ +#include "mesh/slist.h" + #if CONFIG_BT_MESH_DEBUG_USE_ID_ADDR #define ADV_OPT_USE_IDENTITY BT_LE_ADV_OPT_USE_IDENTITY #else @@ -23,6 +25,12 @@ .itvl_min = BT_GAP_ADV_FAST_INT_MIN_2, \ .itvl_max = BT_GAP_ADV_FAST_INT_MAX_2, +struct bt_mesh_proxy_idle_cb { + sys_snode_t n; + void (*cb)(void); +}; + +void notify_complete(void); int bt_mesh_proxy_gatt_enable(void); int bt_mesh_proxy_gatt_disable(void); void bt_mesh_proxy_gatt_disconnect(void); @@ -38,5 +46,6 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst); void bt_mesh_proxy_addr_add(struct os_mbuf *buf, uint16_t addr); int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg); +int bt_mesh_proxy_init(void); #endif /* __PROXY_H__ */ diff --git a/nimble/host/mesh/src/proxy_msg.c b/nimble/host/mesh/src/proxy_msg.c index 1ed3acdc51..44613af16d 100644 --- a/nimble/host/mesh/src/proxy_msg.c +++ b/nimble/host/mesh/src/proxy_msg.c @@ -50,6 +50,22 @@ static uint8_t bufs[CONFIG_BT_MAX_CONN * CONFIG_BT_MESH_PROXY_MSG_LEN]; static struct bt_mesh_proxy_role roles[CONFIG_BT_MAX_CONN]; +static void proxy_sar_timeout(struct ble_npl_event *work) +{ + struct bt_mesh_proxy_role *role; + int rc; + role = ble_npl_event_get_arg(work); + + + BT_WARN("Proxy SAR timeout"); + + if (role->conn_handle) { + rc = ble_gap_terminate(role->conn_handle, + BLE_ERR_REM_USER_CONN_TERM); + assert(rc == 0); + } +} + int bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, const void *buf, uint16_t len) { @@ -119,8 +135,7 @@ int bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, } int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, - struct os_mbuf *msg, - void (*end)(uint16_t, void *), void *user_data) + struct os_mbuf *msg) { int err; uint16_t mtu; @@ -133,11 +148,11 @@ int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, mtu = ble_att_mtu(conn_handle) - 3; if (mtu > msg->om_len) { net_buf_simple_push_u8(msg, PDU_HDR(SAR_COMPLETE, type)); - return role->cb.send(conn_handle, msg->om_data, msg->om_len, end, user_data); + return role->cb.send(conn_handle, msg->om_data, msg->om_len); } net_buf_simple_push_u8(msg, PDU_HDR(SAR_FIRST, type)); - err = role->cb.send(conn_handle, msg->om_data, mtu, NULL, NULL); + err = role->cb.send(conn_handle, msg->om_data, mtu); if (err) { return err; } @@ -146,7 +161,7 @@ int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, while (msg->om_len) { if (msg->om_len + 1 < mtu) { net_buf_simple_push_u8(msg, PDU_HDR(SAR_LAST, type)); - err = role->cb.send(conn_handle, msg->om_data, msg->om_len, end, user_data); + err = role->cb.send(conn_handle, msg->om_data, msg->om_len); if (err) { return err; } @@ -154,7 +169,7 @@ int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, } net_buf_simple_push_u8(msg, PDU_HDR(SAR_CONT, type)); - err = role->cb.send(conn_handle, msg->om_data, mtu, NULL, NULL); + err = role->cb.send(conn_handle, msg->om_data, mtu); if (err) { return err; } @@ -170,17 +185,21 @@ static void proxy_msg_init(struct bt_mesh_proxy_role *role) /* Check if buf has been allocated, in this way, we no longer need * to repeat the operation. */ - if (role->buf->om_data) { + if (role->buf != NULL) { net_buf_simple_reset(role->buf); return; } + role->buf = NET_BUF_SIMPLE(CONFIG_BT_MESH_PROXY_MSG_LEN); net_buf_simple_init_with_data(role->buf, &bufs[role->conn_handle * CONFIG_BT_MESH_PROXY_MSG_LEN], CONFIG_BT_MESH_PROXY_MSG_LEN); net_buf_simple_reset(role->buf); + + k_work_init_delayable(&role->sar_timer, proxy_sar_timeout); + k_work_add_arg_delayable(&role->sar_timer, role); } struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(uint16_t conn_handle, diff --git a/nimble/host/mesh/src/proxy_msg.h b/nimble/host/mesh/src/proxy_msg.h index 0e06c5cae5..349ebcdf4a 100644 --- a/nimble/host/mesh/src/proxy_msg.h +++ b/nimble/host/mesh/src/proxy_msg.h @@ -26,8 +26,7 @@ struct bt_mesh_proxy_role; typedef int (*proxy_send_cb_t)(uint16_t conn_handle, - const void *data, uint16_t len, - void (*end)(uint16_t, void *), void *user_data); + const void *data, uint16_t len); typedef void (*proxy_recv_cb_t)(struct bt_mesh_proxy_role *role); @@ -57,8 +56,7 @@ struct bt_mesh_proxy_client { int bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, const void *buf, uint16_t len); -int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, - struct os_mbuf *msg, void (*end)(uint16_t, void *), void *user_data); +int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, struct os_mbuf *msg); void bt_mesh_proxy_msg_init(struct bt_mesh_proxy_role *role); void bt_mesh_proxy_role_cleanup(struct bt_mesh_proxy_role *role); struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(uint16_t conn_handle, diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index 7fa297fa7b..f634f400e2 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -9,6 +9,8 @@ #define MESH_LOG_MODULE BLE_MESH_PROXY_LOG +#include "mesh/slist.h" +#include "mesh/mesh.h" #include "../../host/src/ble_hs_priv.h" #include "services/gatt/ble_svc_gatt.h" @@ -43,19 +45,13 @@ (((w16) >> 0) & 0xFF), \ (((w16) >> 8) & 0xFF) -static struct { - uint16_t proxy_h; - uint16_t proxy_data_out_h; - uint16_t prov_h; - uint16_t prov_data_in_h; - uint16_t prov_data_out_h; -} svc_handles; +static sys_slist_t idle_waiters; +static atomic_t pending_notifications; static void proxy_send_beacons(struct ble_npl_event *work); static int proxy_send(uint16_t conn_handle, - const void *data, uint16_t len, - void (*end)(uint16_t, void *), void *user_data); + const void *data, uint16_t len); static struct bt_mesh_proxy_client clients[CONFIG_BT_MAX_CONN]; @@ -185,8 +181,7 @@ static void send_filter_status(struct bt_mesh_proxy_client *client, return; } - err = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_CONFIG, - buf, NULL, NULL); + err = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_CONFIG, buf); if (err) { BT_ERR("Failed to send proxy cfg message (err %d)", err); } @@ -262,7 +257,7 @@ static void proxy_cfg(struct bt_mesh_proxy_role *role) } proxy_filter_recv(role->conn_handle, &rx, buf); - } +} static void proxy_msg_recv(struct bt_mesh_proxy_role *role) { @@ -293,8 +288,7 @@ static int beacon_send(struct bt_mesh_proxy_client *client, struct bt_mesh_subne net_buf_simple_init(buf, 1); bt_mesh_beacon_create(sub, buf); - rc = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_BEACON, buf, - NULL, NULL); + rc = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_BEACON, buf); os_mbuf_free_chain(buf); return rc; } @@ -434,7 +428,7 @@ static int node_id_adv(struct bt_mesh_subnet *sub, int32_t duration) memcpy(proxy_svc_data + 3, tmp + 8, 8); - err = bt_le_adv_start(&fast_adv_param, duration, node_id_ad, + err = bt_mesh_adv_start(&fast_adv_param, duration, node_id_ad, ARRAY_SIZE(node_id_ad), sd, 0); if (err) { BT_WARN("Failed to advertise using Node ID (err %d)", err); @@ -472,7 +466,7 @@ static int net_id_adv(struct bt_mesh_subnet *sub, int32_t duration) memcpy(proxy_svc_data + 3, sub->keys[SUBNET_KEY_TX_IDX(sub)].net_id, 8); - err = bt_le_adv_start(&slow_adv_param, duration, net_id_ad, + err = bt_mesh_adv_start(&slow_adv_param, duration, net_id_ad, ARRAY_SIZE(net_id_ad), sd, 0); if (err) { BT_WARN("Failed to advertise using Network ID (err %d)", err); @@ -635,7 +629,7 @@ int bt_mesh_proxy_gatt_enable(void) BT_DBG(""); - if (bt_mesh_is_provisioned()) { + if (!bt_mesh_is_provisioned()) { return -ENOTSUP; } @@ -751,13 +745,6 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client, return false; } -static void buf_send_end(uint16_t conn_handle, void *user_data) -{ - struct os_mbuf *buf = user_data; - - net_buf_unref(buf); -} - bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) { const struct bt_mesh_send_cb *cb = BT_MESH_ADV(buf)->cb; @@ -787,7 +774,7 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) net_buf_simple_add_mem(msg, buf->om_data, buf->om_len); err = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_NET_PDU, - msg, buf_send_end, net_buf_ref(buf)); + msg); adv_send_start(0, err, cb, cb_data); if (err) { @@ -808,23 +795,6 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) return relayed; } - -static void proxy_sar_timeout(struct ble_npl_event *work) -{ - struct bt_mesh_proxy_role *role; - int rc; - role = ble_npl_event_get_arg(work); - - - BT_WARN("Proxy SAR timeout"); - - if (role->conn_handle) { - rc = ble_gap_terminate(role->conn_handle, - BLE_ERR_REM_USER_CONN_TERM); - assert(rc == 0); - } -} - static void gatt_connected(uint16_t conn_handle) { struct bt_mesh_proxy_client *client; @@ -880,9 +850,23 @@ static void gatt_disconnected(uint16_t conn_handle, uint8_t reason) } } +void notify_complete(void) +{ + sys_snode_t *n; + + if (atomic_dec(&pending_notifications) > 1) { + return; + } + + BT_DBG(""); + + while ((n = sys_slist_get(&idle_waiters))) { + CONTAINER_OF(n, struct bt_mesh_proxy_idle_cb, n)->cb(); + } +} + static int proxy_send(uint16_t conn_handle, - const void *data, uint16_t len, - void (*end)(uint16_t, void *), void *user_data) + const void *data, uint16_t len) { struct os_mbuf *om; int err = 0; @@ -892,9 +876,12 @@ static int proxy_send(uint16_t conn_handle, om = ble_hs_mbuf_from_flat(data, len); assert(om); err = ble_gattc_notify_custom(conn_handle, svc_handles.proxy_data_out_h, om); - /* We do not pass cb into ble_gattc_notify_custom - execute it at the end */ + notify_complete(); + + if (!err) { + atomic_inc(&pending_notifications); + } - end(conn_handle, user_data); return err; } @@ -948,7 +935,7 @@ static void ble_mesh_handle_connect(struct ble_gap_event *event, void *arg) int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) { if ((event->type == BLE_GAP_EVENT_CONNECT) || - (event->type == BLE_GAP_EVENT_ADV_COMPLETE)) { + (event->type == BLE_GAP_EVENT_ADV_COMPLETE)) { ble_mesh_handle_connect(event, arg); } else if (event->type == BLE_GAP_EVENT_DISCONNECT) { gatt_disconnected(event->disconnect.conn.conn_handle, @@ -963,7 +950,7 @@ int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) proxy_ccc_write(event->subscribe.conn_handle); #endif } else if (event->subscribe.attr_handle == - svc_handles.prov_data_out_h) { + svc_handles.prov_data_out_h) { #if (MYNEWT_VAL(BLE_MESH_PB_GATT)) prov_ccc_write(event->subscribe.conn_handle, event->type); #endif @@ -987,9 +974,6 @@ int bt_mesh_proxy_init(void) #if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) k_work_init(&clients[i].send_beacons, proxy_send_beacons); #endif - - k_work_init_delayable(&clients[i].cli->sar_timer, proxy_sar_timeout); - k_work_add_arg_delayable(&clients[i].cli->sar_timer, &clients[i]); } resolve_svc_handles(); From 40dddfdfc368059c888305f8a904fab310dc2bcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 9 Nov 2021 10:01:50 +0100 Subject: [PATCH 0172/1333] host/mesh: BLE_MESH_CDB should not require BLE_MESH_SETTINGS --- nimble/host/mesh/src/cdb.c | 22 ++++++++++++++++++++++ nimble/host/mesh/syscfg.yml | 1 - 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/cdb.c b/nimble/host/mesh/src/cdb.c index f92ece6090..98084ee3d0 100644 --- a/nimble/host/mesh/src/cdb.c +++ b/nimble/host/mesh/src/cdb.c @@ -159,6 +159,7 @@ static uint16_t find_lowest_free_addr(uint8_t num_elem) return addr; } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static int cdb_net_set(int argc, char *val) { struct net_val net; @@ -385,9 +386,11 @@ static int cdb_set(int argc, char **argv, char *name) BT_WARN("Unknown module key %s", name); return -ENOENT; } +#endif static void store_cdb_node(const struct bt_mesh_cdb_node *node) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) char buf[BT_SETTINGS_SIZE(sizeof(struct node_val))]; struct node_val val; char path[30]; @@ -420,10 +423,12 @@ static void store_cdb_node(const struct bt_mesh_cdb_node *node) } else { BT_DBG("Stored Node %s value", path); } +#endif } static void clear_cdb_node(uint16_t addr) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) char path[30]; int err; @@ -436,10 +441,12 @@ static void clear_cdb_node(uint16_t addr) } else { BT_DBG("Cleared Node 0x%04x", addr); } +#endif } static void store_cdb_subnet(const struct bt_mesh_cdb_subnet *sub) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) char buf[BT_SETTINGS_SIZE(sizeof(struct net_key_val))]; struct net_key_val key; char path[30]; @@ -468,10 +475,12 @@ static void store_cdb_subnet(const struct bt_mesh_cdb_subnet *sub) } else { BT_DBG("Stored Subnet value"); } +#endif } static void clear_cdb_subnet(uint16_t net_idx) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) char path[30]; int err; @@ -484,10 +493,12 @@ static void clear_cdb_subnet(uint16_t net_idx) } else { BT_DBG("Cleared NetKeyIndex 0x%03x", net_idx); } +#endif } static void store_cdb_app_key(const struct bt_mesh_cdb_app_key *app) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) char buf[BT_SETTINGS_SIZE(sizeof(struct app_key_val))]; struct app_key_val key; char path[30]; @@ -508,10 +519,12 @@ static void store_cdb_app_key(const struct bt_mesh_cdb_app_key *app) } else { BT_DBG("Stored AppKey"); } +#endif } static void clear_cdb_app_key(uint16_t app_idx) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) char path[30]; int err; @@ -522,6 +535,7 @@ static void clear_cdb_app_key(uint16_t app_idx) } else { BT_DBG("Cleared AppKeyIndex 0x%03x", app_idx); } +#endif } static void schedule_cdb_store(int flag) @@ -964,6 +978,7 @@ void bt_mesh_cdb_app_key_store(const struct bt_mesh_cdb_app_key *key) static void clear_cdb_net(void) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) char path[30]; int err; @@ -974,10 +989,12 @@ static void clear_cdb_net(void) } else { BT_DBG("Cleared NetKeyIndex 0x%03x"); } +#endif } static void store_cdb_pending_net(void) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) struct net_val net; int err; char buf[BT_SETTINGS_SIZE(sizeof(struct net_val))]; @@ -1000,6 +1017,7 @@ static void store_cdb_pending_net(void) } else { BT_DBG("Stored Network value"); } +#endif } static void store_cdb_pending_nodes(void) @@ -1100,6 +1118,7 @@ void bt_mesh_cdb_pending_store(void) } } +#if MYNEWT_VAL(BLE_MESH_SETTINGS) static struct conf_handler bt_mesh_cdb_conf_handler = { .ch_name = "bt_mesh", .ch_get = NULL, @@ -1107,14 +1126,17 @@ static struct conf_handler bt_mesh_cdb_conf_handler = { .ch_commit = NULL, .ch_export = NULL, }; +#endif void bt_mesh_cdb_init(void) { +#if MYNEWT_VAL(BLE_MESH_SETTINGS) int rc; rc = conf_register(&bt_mesh_cdb_conf_handler); SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_net conf"); +#endif } #endif diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index eb79b04947..ae8190f859 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -63,7 +63,6 @@ syscfg.defs: description: > Mesh Configuration Database [EXPERIMENTAL] value: 0 - restrictions: BLE_MESH_SETTINGS BLE_MESH_CDB_NODE_COUNT: description: > From 5cc57dee076ca4613134e3b916e81f08ec4d59b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 9 Nov 2021 10:15:49 +0100 Subject: [PATCH 0173/1333] porting: fix blemesh build after mesh sync --- porting/examples/linux_blemesh/ble.c | 46 ++++++++++++------- .../linux_blemesh/include/syscfg/syscfg.h | 4 ++ 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/porting/examples/linux_blemesh/ble.c b/porting/examples/linux_blemesh/ble.c index deaef5a462..7a64eac9ea 100644 --- a/porting/examples/linux_blemesh/ble.c +++ b/porting/examples/linux_blemesh/ble.c @@ -142,11 +142,12 @@ static struct bt_mesh_model_pub gen_onoff_pub; static uint8_t gen_on_off_state; static int16_t gen_level_state; -static void gen_onoff_status(struct bt_mesh_model *model, +static int gen_onoff_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { struct os_mbuf *msg = NET_BUF_SIMPLE(3); uint8_t *status; + int rc; console_printf("#mesh-onoff STATUS\n"); @@ -154,23 +155,25 @@ static void gen_onoff_status(struct bt_mesh_model *model, status = net_buf_simple_add(msg, 1); *status = gen_on_off_state; - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + rc = bt_mesh_model_send(model, ctx, msg, NULL, NULL); + if (rc) { console_printf("#mesh-onoff STATUS: send status failed\n"); } os_mbuf_free_chain(msg); + return rc; } -static void gen_onoff_get(struct bt_mesh_model *model, +static int gen_onoff_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { console_printf("#mesh-onoff GET\n"); - gen_onoff_status(model, ctx); + return gen_onoff_status(model, ctx); } -static void gen_onoff_set(struct bt_mesh_model *model, +static int gen_onoff_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -178,16 +181,17 @@ static void gen_onoff_set(struct bt_mesh_model *model, gen_on_off_state = buf->om_data[0]; - gen_onoff_status(model, ctx); + return gen_onoff_status(model, ctx); } -static void gen_onoff_set_unack(struct bt_mesh_model *model, +static int gen_onoff_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { console_printf("#mesh-onoff SET-UNACK\n"); gen_on_off_state = buf->om_data[0]; + return 0; } static const struct bt_mesh_model_op gen_onoff_op[] = { @@ -214,16 +218,17 @@ static void gen_level_status(struct bt_mesh_model *model, os_mbuf_free_chain(msg); } -static void gen_level_get(struct bt_mesh_model *model, +static int gen_level_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { console_printf("#mesh-level GET\n"); gen_level_status(model, ctx); + return 0; } -static void gen_level_set(struct bt_mesh_model *model, +static int gen_level_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -236,9 +241,10 @@ static void gen_level_set(struct bt_mesh_model *model, gen_level_state = level; console_printf("#mesh-level: level=%d\n", gen_level_state); + return 0; } -static void gen_level_set_unack(struct bt_mesh_model *model, +static int gen_level_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -249,9 +255,10 @@ static void gen_level_set_unack(struct bt_mesh_model *model, gen_level_state = level; console_printf("#mesh-level: level=%d\n", gen_level_state); + return 0; } -static void gen_delta_set(struct bt_mesh_model *model, +static int gen_delta_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -264,9 +271,10 @@ static void gen_delta_set(struct bt_mesh_model *model, gen_level_state += delta_level; console_printf("#mesh-level: level=%d\n", gen_level_state); + return 0; } -static void gen_delta_set_unack(struct bt_mesh_model *model, +static int gen_delta_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { @@ -277,18 +285,21 @@ static void gen_delta_set_unack(struct bt_mesh_model *model, gen_level_state += delta_level; console_printf("#mesh-level: level=%d\n", gen_level_state); + return 0; } -static void gen_move_set(struct bt_mesh_model *model, +static int gen_move_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { + return 0; } -static void gen_move_set_unack(struct bt_mesh_model *model, +static int gen_move_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { + return 0; } static const struct bt_mesh_model_op gen_level_op[] = { @@ -313,11 +324,12 @@ static struct bt_mesh_model root_models[] = { static struct bt_mesh_model_pub vnd_model_pub; -static void vnd_model_recv(struct bt_mesh_model *model, +static int vnd_model_recv(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { struct os_mbuf *msg = NET_BUF_SIMPLE(3); + int rc; console_printf("#vendor-model-recv\n"); @@ -327,11 +339,13 @@ static void vnd_model_recv(struct bt_mesh_model *model, bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_3(0x01, CID_VENDOR)); os_mbuf_append(msg, buf->om_data, buf->om_len); - if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + rc = bt_mesh_model_send(model, ctx, msg, NULL, NULL); + if (rc) { console_printf("#vendor-model-recv: send rsp failed\n"); } os_mbuf_free_chain(msg); + return rc; } static const struct bt_mesh_model_op vnd_model_op[] = { diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 61cc3f20e2..5a5288f52e 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -1260,6 +1260,10 @@ #define MYNEWT_VAL_BLE_MESH_GATT_PROXY_ENABLED (1) #endif +#ifndef MYNEWT_VAL_BLE_MESH_GATT_SERVER +#define MYNEWT_VAL_BLE_MESH_GATT_SERVER (1) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_FRIEND_ENABLED #define MYNEWT_VAL_BLE_MESH_FRIEND_ENABLED (1) #endif From b9c20addd87f1692ea27600ede82f641c77315be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 9 Nov 2021 17:33:31 +0100 Subject: [PATCH 0174/1333] host/mesh: make all files have single empty line at the end --- nimble/host/mesh/include/mesh/cdb.h | 2 +- nimble/host/mesh/include/mesh/cfg.h | 2 +- nimble/host/mesh/include/mesh/heartbeat.h | 2 +- nimble/host/mesh/include/mesh/msg.h | 2 +- nimble/host/mesh/src/access.c | 2 +- nimble/host/mesh/src/adv_legacy.c | 2 +- nimble/host/mesh/src/app_keys.c | 2 +- nimble/host/mesh/src/app_keys.h | 2 +- nimble/host/mesh/src/cfg.c | 2 +- nimble/host/mesh/src/cfg.h | 2 +- nimble/host/mesh/src/heartbeat.c | 2 +- nimble/host/mesh/src/heartbeat.h | 2 +- nimble/host/mesh/src/light_model.c | 1 - nimble/host/mesh/src/model_cli.c | 1 - nimble/host/mesh/src/msg.c | 2 +- nimble/host/mesh/src/pb_gatt.c | 2 +- nimble/host/mesh/src/pb_gatt_srv.c | 2 +- nimble/host/mesh/src/pb_gatt_srv.h | 2 +- nimble/host/mesh/src/provisioner.h | 2 +- nimble/host/mesh/src/proxy_srv.c | 2 +- nimble/host/mesh/src/rpl.c | 2 +- nimble/host/mesh/src/rpl.h | 2 +- nimble/host/mesh/src/subnet.c | 2 +- nimble/host/mesh/src/subnet.h | 2 +- nimble/host/mesh/src/transport.h | 2 +- nimble/host/mesh/syscfg.yml | 2 +- 26 files changed, 24 insertions(+), 26 deletions(-) diff --git a/nimble/host/mesh/include/mesh/cdb.h b/nimble/host/mesh/include/mesh/cdb.h index 444fb5d295..fa691eb642 100644 --- a/nimble/host/mesh/include/mesh/cdb.h +++ b/nimble/host/mesh/include/mesh/cdb.h @@ -262,4 +262,4 @@ struct bt_mesh_cdb_app_key *bt_mesh_cdb_app_key_get(uint16_t app_idx); */ void bt_mesh_cdb_app_key_store(const struct bt_mesh_cdb_app_key *key); -#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_CDB_H_ */ \ No newline at end of file +#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_CDB_H_ */ diff --git a/nimble/host/mesh/include/mesh/cfg.h b/nimble/host/mesh/include/mesh/cfg.h index 6fd69266ea..422ef3e661 100644 --- a/nimble/host/mesh/include/mesh/cfg.h +++ b/nimble/host/mesh/include/mesh/cfg.h @@ -488,4 +488,4 @@ ssize_t bt_mesh_app_keys_get(uint16_t net_idx, uint16_t app_idxs[], size_t max, * @} */ -#endif /* _BT_MESH_CFG_H_ */ \ No newline at end of file +#endif /* _BT_MESH_CFG_H_ */ diff --git a/nimble/host/mesh/include/mesh/heartbeat.h b/nimble/host/mesh/include/mesh/heartbeat.h index b9990f6fdc..2e4986094d 100644 --- a/nimble/host/mesh/include/mesh/heartbeat.h +++ b/nimble/host/mesh/include/mesh/heartbeat.h @@ -120,4 +120,4 @@ extern struct bt_mesh_hb_cb hb_cb; * @} */ -#endif /* _BLUETOOTH_MESH_HEARTBEAT_H_ */ \ No newline at end of file +#endif /* _BLUETOOTH_MESH_HEARTBEAT_H_ */ diff --git a/nimble/host/mesh/include/mesh/msg.h b/nimble/host/mesh/include/mesh/msg.h index 0cc00ff35b..e327545b12 100644 --- a/nimble/host/mesh/include/mesh/msg.h +++ b/nimble/host/mesh/include/mesh/msg.h @@ -222,4 +222,4 @@ bool bt_mesh_msg_ack_ctx_match(const struct bt_mesh_msg_ack_ctx *ack, /** * @} */ -#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_MSG_H_ */ \ No newline at end of file +#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_MSG_H_ */ diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index e498910dbd..2c07b09478 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -1310,4 +1310,4 @@ void bt_mesh_access_init(void) SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_access conf"); #endif -} \ No newline at end of file +} diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index 94065bc9bf..5bebff8960 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -242,4 +242,4 @@ int bt_mesh_adv_start(const struct ble_gap_adv_params *param, int32_t duration, adv_timeout = duration; return bt_le_adv_start(param, duration, ad, ad_len, sd, sd_len); } -#endif \ No newline at end of file +#endif diff --git a/nimble/host/mesh/src/app_keys.c b/nimble/host/mesh/src/app_keys.c index 97589968d9..acc51f2a60 100644 --- a/nimble/host/mesh/src/app_keys.c +++ b/nimble/host/mesh/src/app_keys.c @@ -714,4 +714,4 @@ void bt_mesh_app_key_init(void) SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_app_key conf"); #endif -} \ No newline at end of file +} diff --git a/nimble/host/mesh/src/app_keys.h b/nimble/host/mesh/src/app_keys.h index 1c560560de..3ef9ce7c8f 100644 --- a/nimble/host/mesh/src/app_keys.h +++ b/nimble/host/mesh/src/app_keys.h @@ -65,4 +65,4 @@ extern void (*bt_mesh_app_key_cb_list[1]) (uint16_t app_idx, uint16_t net_idx, /** @brief Store pending application keys in persistent storage. */ void bt_mesh_app_key_pending_store(void); void bt_mesh_app_key_init(void); -#endif /* _BT_MESH_APP_KEYS_H_ */ \ No newline at end of file +#endif /* _BT_MESH_APP_KEYS_H_ */ diff --git a/nimble/host/mesh/src/cfg.c b/nimble/host/mesh/src/cfg.c index ec68cac7b7..282aefaf43 100644 --- a/nimble/host/mesh/src/cfg.c +++ b/nimble/host/mesh/src/cfg.c @@ -385,4 +385,4 @@ void bt_mesh_cfg_default_set(void) if (CONFIG_BT_MESH_FRIEND_ENABLED) { atomic_set_bit(bt_mesh.flags, BT_MESH_FRIEND); } -} \ No newline at end of file +} diff --git a/nimble/host/mesh/src/cfg.h b/nimble/host/mesh/src/cfg.h index 0bd7ad39c6..4901655f57 100644 --- a/nimble/host/mesh/src/cfg.h +++ b/nimble/host/mesh/src/cfg.h @@ -7,4 +7,4 @@ void bt_mesh_cfg_default_set(void); void bt_mesh_cfg_pending_store(void); -bool bt_mesh_fixed_group_match(uint16_t addr); \ No newline at end of file +bool bt_mesh_fixed_group_match(uint16_t addr); diff --git a/nimble/host/mesh/src/heartbeat.c b/nimble/host/mesh/src/heartbeat.c index 50cfdb6d5b..faf2f76611 100644 --- a/nimble/host/mesh/src/heartbeat.c +++ b/nimble/host/mesh/src/heartbeat.c @@ -461,4 +461,4 @@ void bt_mesh_hb_pub_init(void) SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_hb_pub conf"); #endif -} \ No newline at end of file +} diff --git a/nimble/host/mesh/src/heartbeat.h b/nimble/host/mesh/src/heartbeat.h index 7fcfacf197..a036366637 100644 --- a/nimble/host/mesh/src/heartbeat.h +++ b/nimble/host/mesh/src/heartbeat.h @@ -40,4 +40,4 @@ uint8_t bt_mesh_hb_pub_set(struct bt_mesh_hb_pub *hb_pub); uint8_t bt_mesh_hb_sub_set(uint16_t src, uint16_t dst, uint32_t period); void bt_mesh_hb_sub_reset_count(void); void bt_mesh_hb_pub_pending_store(void); -void bt_mesh_hb_pub_init(void); \ No newline at end of file +void bt_mesh_hb_pub_init(void); diff --git a/nimble/host/mesh/src/light_model.c b/nimble/host/mesh/src/light_model.c index bc4792c637..e7199519bb 100644 --- a/nimble/host/mesh/src/light_model.c +++ b/nimble/host/mesh/src/light_model.c @@ -55,4 +55,3 @@ int light_model_light_lightness_set(struct bt_mesh_model *model, int16_t lightne { return light_model_gen_level_set(model, lightness); } - diff --git a/nimble/host/mesh/src/model_cli.c b/nimble/host/mesh/src/model_cli.c index fd052426a1..22f9b99ee8 100644 --- a/nimble/host/mesh/src/model_cli.c +++ b/nimble/host/mesh/src/model_cli.c @@ -302,4 +302,3 @@ int bt_mesh_gen_level_set(uint16_t net_idx, uint16_t addr, uint16_t app_idx, os_mbuf_free_chain(msg); return err; } - diff --git a/nimble/host/mesh/src/msg.c b/nimble/host/mesh/src/msg.c index f75082cb96..b788ffe1e9 100644 --- a/nimble/host/mesh/src/msg.c +++ b/nimble/host/mesh/src/msg.c @@ -81,4 +81,4 @@ bool bt_mesh_msg_ack_ctx_match(const struct bt_mesh_msg_ack_ctx *ack, } return true; -} \ No newline at end of file +} diff --git a/nimble/host/mesh/src/pb_gatt.c b/nimble/host/mesh/src/pb_gatt.c index 906abd2fc9..9a0d7091e1 100644 --- a/nimble/host/mesh/src/pb_gatt.c +++ b/nimble/host/mesh/src/pb_gatt.c @@ -172,4 +172,4 @@ const struct prov_bearer pb_gatt = { .send = buf_send, .clear_tx = clear_tx, }; -#endif \ No newline at end of file +#endif diff --git a/nimble/host/mesh/src/pb_gatt_srv.c b/nimble/host/mesh/src/pb_gatt_srv.c index 61fadb6fca..ee37819d5c 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.c +++ b/nimble/host/mesh/src/pb_gatt_srv.c @@ -468,4 +468,4 @@ int bt_mesh_pb_gatt_adv_start(void) return err; } -#endif \ No newline at end of file +#endif diff --git a/nimble/host/mesh/src/pb_gatt_srv.h b/nimble/host/mesh/src/pb_gatt_srv.h index 816089477c..a5ebce5283 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.h +++ b/nimble/host/mesh/src/pb_gatt_srv.h @@ -28,4 +28,4 @@ extern struct svc_handles { uint16_t prov_data_out_h; } svc_handles; -#endif /* __PB_GATT_SRV_H__ */ \ No newline at end of file +#endif /* __PB_GATT_SRV_H__ */ diff --git a/nimble/host/mesh/src/provisioner.h b/nimble/host/mesh/src/provisioner.h index ccda47efed..315bde299f 100644 --- a/nimble/host/mesh/src/provisioner.h +++ b/nimble/host/mesh/src/provisioner.h @@ -7,4 +7,4 @@ */ int bt_mesh_pb_adv_open(const uint8_t uuid[16], uint16_t net_idx, uint16_t addr, - uint8_t attention_duration); \ No newline at end of file + uint8_t attention_duration); diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index f634f400e2..3507d0a45a 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -982,4 +982,4 @@ int bt_mesh_proxy_init(void) ble_gatts_svc_set_visibility(svc_handles.prov_h, 0); return 0; -} \ No newline at end of file +} diff --git a/nimble/host/mesh/src/rpl.c b/nimble/host/mesh/src/rpl.c index 6fd08b2feb..3a54414cea 100644 --- a/nimble/host/mesh/src/rpl.c +++ b/nimble/host/mesh/src/rpl.c @@ -377,4 +377,4 @@ void bt_mesh_rpl_init(void) SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_rpl conf"); #endif -} \ No newline at end of file +} diff --git a/nimble/host/mesh/src/rpl.h b/nimble/host/mesh/src/rpl.h index b79ce887d4..9d110d9dab 100644 --- a/nimble/host/mesh/src/rpl.h +++ b/nimble/host/mesh/src/rpl.h @@ -29,4 +29,4 @@ bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx, void bt_mesh_rpl_clear(void); void bt_mesh_rpl_update(struct bt_mesh_rpl *rpl, struct bt_mesh_net_rx *rx); -void bt_mesh_rpl_init(void); \ No newline at end of file +void bt_mesh_rpl_init(void); diff --git a/nimble/host/mesh/src/subnet.c b/nimble/host/mesh/src/subnet.c index 14aa8623f7..9108cc471f 100644 --- a/nimble/host/mesh/src/subnet.c +++ b/nimble/host/mesh/src/subnet.c @@ -882,4 +882,4 @@ void bt_mesh_net_key_init(void) SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to register bt_mesh_net_key conf"); #endif -} \ No newline at end of file +} diff --git a/nimble/host/mesh/src/subnet.h b/nimble/host/mesh/src/subnet.h index b3ac899272..b64177d364 100644 --- a/nimble/host/mesh/src/subnet.h +++ b/nimble/host/mesh/src/subnet.h @@ -203,4 +203,4 @@ void bt_mesh_subnet_store(uint16_t net_idx); /** @brief Store the pending Subnets in persistent storage. */ void bt_mesh_subnet_pending_store(void); void bt_mesh_net_key_init(void); -#endif /* _BLUETOOTH_MESH_SUBNET_H_ */ \ No newline at end of file +#endif /* _BLUETOOTH_MESH_SUBNET_H_ */ diff --git a/nimble/host/mesh/src/transport.h b/nimble/host/mesh/src/transport.h index a1af9a4bd8..ad7a59f236 100644 --- a/nimble/host/mesh/src/transport.h +++ b/nimble/host/mesh/src/transport.h @@ -103,4 +103,4 @@ uint8_t *bt_mesh_va_label_get(uint16_t addr); void bt_mesh_va_pending_store(void); -void bt_mesh_va_init(void); \ No newline at end of file +void bt_mesh_va_init(void); diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index ae8190f859..ca74cdff7d 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -979,4 +979,4 @@ syscfg.vals.BLE_MESH_PB_ADV: syscfg.vals.'BLE_MESH_PB_GATT': BLE_MESH_PROXY_MSG_LEN: 66 syscfg.vals.'BLE_MESH_GATT_PROXY': - BLE_MESH_PROXY_MSG_LEN: 33 \ No newline at end of file + BLE_MESH_PROXY_MSG_LEN: 33 From 3ac500716892d2395c616b8937030bc0aef9ee65 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Wed, 17 Nov 2021 11:53:47 +0100 Subject: [PATCH 0175/1333] targets: Rename pca10095 target Target nordic_pca10095-blehci was defined for nordic_pca10095_net bsp. Name suggested that nordic_pca10095 is being used. This just changes target name to avoid confusion. --- .../pkg.yml | 2 +- .../syscfg.yml | 0 .../target.yml | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename targets/{nordic_pca10095-blehci => nordic_pca10095_net-blehci}/pkg.yml (95%) rename targets/{nordic_pca10095-blehci => nordic_pca10095_net-blehci}/syscfg.yml (100%) rename targets/{nordic_pca10095-blehci => nordic_pca10095_net-blehci}/target.yml (100%) diff --git a/targets/nordic_pca10095-blehci/pkg.yml b/targets/nordic_pca10095_net-blehci/pkg.yml similarity index 95% rename from targets/nordic_pca10095-blehci/pkg.yml rename to targets/nordic_pca10095_net-blehci/pkg.yml index 3b72abe1bc..af24376a83 100644 --- a/targets/nordic_pca10095-blehci/pkg.yml +++ b/targets/nordic_pca10095_net-blehci/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: targets/nordic_pca10095-blehci +pkg.name: targets/nordic_pca10095_net-blehci pkg.type: target pkg.description: Sample target for BLE controller on NRF5340 pkg.author: "Apache Mynewt " diff --git a/targets/nordic_pca10095-blehci/syscfg.yml b/targets/nordic_pca10095_net-blehci/syscfg.yml similarity index 100% rename from targets/nordic_pca10095-blehci/syscfg.yml rename to targets/nordic_pca10095_net-blehci/syscfg.yml diff --git a/targets/nordic_pca10095-blehci/target.yml b/targets/nordic_pca10095_net-blehci/target.yml similarity index 100% rename from targets/nordic_pca10095-blehci/target.yml rename to targets/nordic_pca10095_net-blehci/target.yml From 57eb4237aed7f2345eb970a9a5278ea2ee2f3280 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Fri, 19 Nov 2021 08:41:08 +0100 Subject: [PATCH 0176/1333] transport/usb: Drop events when not mounted If controller sends events before USB transport is ready event will be added to events queue but later interface initialization will clear queue without sending notification that event was sent to host. This change drops events generated by controller (most likely first NOP) if host is not connected yet. --- nimble/transport/usb/src/ble_hci_usb.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimble/transport/usb/src/ble_hci_usb.c b/nimble/transport/usb/src/ble_hci_usb.c index 3f87856f11..8160536b95 100644 --- a/nimble/transport/usb/src/ble_hci_usb.c +++ b/nimble/transport/usb/src/ble_hci_usb.c @@ -285,6 +285,11 @@ ble_hci_trans_ll_evt_tx(uint8_t *hci_ev) assert(hci_ev != NULL); + if (!tud_ready()) { + ble_hci_trans_buf_free(hci_ev); + return 0; + } + pkt = os_memblock_get(&ble_hci_pkt_pool); if (pkt == NULL) { ble_hci_trans_buf_free(hci_ev); From f44ab19694bfcb5824fef58471b586e20086992b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 18 Nov 2021 07:41:49 +0100 Subject: [PATCH 0177/1333] host/l2cap_sig: MPS on any channel cannot be decreased If reconfiguration request contains >1 CID and MPS value is reduced for only one of them this request should still fail. This is affecting L2CAP/ECFC/BI-04-C --- nimble/host/src/ble_l2cap_sig.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index 2a36161998..b74f88a4d0 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -796,10 +796,6 @@ ble_l2cap_sig_credit_base_reconfig_req_rx(uint16_t conn_handle, if (chan[i]->peer_coc_mps > req->mps) { reduction_mps++; - if (reduction_mps > 1) { - rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_REDUCTION_MPS_NOT_ALLOWED); - goto failed; - } } if (chan[i]->coc_tx.mtu > req->mtu) { @@ -808,6 +804,11 @@ ble_l2cap_sig_credit_base_reconfig_req_rx(uint16_t conn_handle, } } + if (reduction_mps > 0 && cid_cnt > 1) { + rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_REDUCTION_MPS_NOT_ALLOWED); + goto failed; + } + ble_hs_unlock(); for (i = 0; i < cid_cnt; i++) { From 3fe2fd9f578957b23d1dc0c987664c1989830a55 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 16 Nov 2021 13:17:20 +0100 Subject: [PATCH 0178/1333] Revert "l2cap: implement echo request-response procedure" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit ddf8043d1b97f1600aa88c53bd935d0fc9b22c9c. Unfortunatelly this procedure is not allowed on LE transport. This is affecting L2CAP/LE/REJ/BI-02-C [Command Reject – Reserved PDU Codes] qualification test case. --- nimble/host/include/host/ble_l2cap.h | 22 ----- nimble/host/src/ble_l2cap.c | 7 -- nimble/host/src/ble_l2cap_sig.c | 120 +-------------------------- nimble/host/src/ble_l2cap_sig_priv.h | 2 - 4 files changed, 1 insertion(+), 150 deletions(-) diff --git a/nimble/host/include/host/ble_l2cap.h b/nimble/host/include/host/ble_l2cap.h index 5c5383b261..aef9682cc4 100644 --- a/nimble/host/include/host/ble_l2cap.h +++ b/nimble/host/include/host/ble_l2cap.h @@ -246,8 +246,6 @@ struct ble_l2cap_chan_info { typedef int ble_l2cap_event_fn(struct ble_l2cap_event *event, void *arg); -typedef void ble_l2cap_ping_fn(uint16_t conn_handle, uint32_t rtt_ms, - struct os_mbuf *om); uint16_t ble_l2cap_get_conn_handle(struct ble_l2cap_chan *chan); int ble_l2cap_create_server(uint16_t psm, uint16_t mtu, @@ -261,26 +259,6 @@ int ble_l2cap_send(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_tx); int ble_l2cap_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx); int ble_l2cap_get_chan_info(struct ble_l2cap_chan *chan, struct ble_l2cap_chan_info *chan_info); -/** - * Send an ECHO_REQ packet over the L2CAP signalling channel for the given - * connection - * - * @param conn_handle Connection handle - * @param cb Function called once the corresponding ECHO_RSP is - * received. May be NULL. - * @param data User payload appended to the ECHO_REQ packet, may be - * NULL - * @param data_len Length of @p data in bytes. Set to 0 to omit any user - * payload - * - * @return 0 on success - * BLE_HS_EBADDATA if given payload is invalid - * BLE_HS_ENOMEM if request packet cannot be allocated - * BLE_HS_ENOTCONN if not connected - */ -int ble_l2cap_ping(uint16_t conn_handle, ble_l2cap_ping_fn cb, - const void *data, uint16_t data_len); - #ifdef __cplusplus } #endif diff --git a/nimble/host/src/ble_l2cap.c b/nimble/host/src/ble_l2cap.c index a2c5156339..2bc50e0e93 100644 --- a/nimble/host/src/ble_l2cap.c +++ b/nimble/host/src/ble_l2cap.c @@ -178,13 +178,6 @@ ble_l2cap_get_chan_info(struct ble_l2cap_chan *chan, struct ble_l2cap_chan_info return 0; } -int -ble_l2cap_ping(uint16_t conn_handle, ble_l2cap_ping_fn cb, - const void *data, uint16_t data_len) -{ - return ble_l2cap_sig_ping(conn_handle, cb, data, data_len); -} - int ble_l2cap_enhanced_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index b74f88a4d0..f34c20b8bb 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -60,7 +60,6 @@ #define BLE_L2CAP_SIG_PROC_OP_RECONFIG 2 #define BLE_L2CAP_SIG_PROC_OP_DISCONNECT 3 #define BLE_L2CAP_SIG_PROC_OP_MAX 4 -#define BLE_L2CAP_SIG_PROC_OP_PING 5 #if MYNEWT_VAL(BLE_L2CAP_ENHANCED_COC) #define BLE_L2CAP_ECOC_MIN_MTU (64) @@ -98,10 +97,6 @@ struct ble_l2cap_sig_proc { uint16_t new_mtu; } reconfig; #endif - struct { - ble_l2cap_ping_fn *cb; - ble_npl_time_t time_sent; - } ping; }; }; @@ -117,10 +112,6 @@ static ble_l2cap_sig_rx_fn ble_l2cap_sig_rx_noop; static ble_l2cap_sig_rx_fn ble_l2cap_sig_update_req_rx; static ble_l2cap_sig_rx_fn ble_l2cap_sig_update_rsp_rx; static ble_l2cap_sig_rx_fn ble_l2cap_sig_rx_reject; -#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 -static ble_l2cap_sig_rx_fn ble_l2cap_sig_echo_req; -static ble_l2cap_sig_rx_fn ble_l2cap_sig_echo_rsp; -#endif #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 static ble_l2cap_sig_rx_fn ble_l2cap_sig_coc_req_rx; @@ -154,10 +145,7 @@ static ble_l2cap_sig_rx_fn * const ble_l2cap_sig_dispatch[] = { [BLE_L2CAP_SIG_OP_CONFIG_RSP] = ble_l2cap_sig_rx_noop, [BLE_L2CAP_SIG_OP_DISCONN_REQ] = ble_l2cap_sig_disc_req_rx, [BLE_L2CAP_SIG_OP_DISCONN_RSP] = ble_l2cap_sig_disc_rsp_rx, -#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 - [BLE_L2CAP_SIG_OP_ECHO_REQ] = ble_l2cap_sig_echo_req, - [BLE_L2CAP_SIG_OP_ECHO_RSP] = ble_l2cap_sig_echo_rsp, -#endif + [BLE_L2CAP_SIG_OP_ECHO_RSP] = ble_l2cap_sig_rx_noop, [BLE_L2CAP_SIG_OP_INFO_RSP] = ble_l2cap_sig_rx_noop, [BLE_L2CAP_SIG_OP_CREATE_CHAN_RSP] = ble_l2cap_sig_rx_noop, [BLE_L2CAP_SIG_OP_MOVE_CHAN_RSP] = ble_l2cap_sig_rx_noop, @@ -1651,58 +1639,6 @@ ble_l2cap_sig_disc_rsp_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, return 0; } -static int -ble_l2cap_sig_echo_req(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, - struct os_mbuf **om) -{ - void *rsp; - struct os_mbuf *txom; - struct ble_l2cap_sig_hdr *rsp_hdr; - int rc; - - /* we temporarily set size to 0 as we do not want to allocate additional - * space yet */ - rsp = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_ECHO_RSP, - hdr->identifier, 0, &txom); - if (rsp == NULL) { - return BLE_HS_ENOMEM; - } - rc = os_mbuf_appendfrom(txom, *om, 0, OS_MBUF_PKTLEN(*om)); - if (rc != 0) { - os_mbuf_free_chain(txom); - return BLE_HS_ENOMEM; - } - /* after copying the request payload into the response, we need to adjust - * the size field in the header to the actual value */ - rsp_hdr = (struct ble_l2cap_sig_hdr *)txom->om_data; - rsp_hdr->length = htole16(OS_MBUF_PKTLEN(*om)); - - return ble_l2cap_sig_tx(conn_handle, txom); -} - -static int -ble_l2cap_sig_echo_rsp(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, - struct os_mbuf **om) -{ - struct ble_l2cap_sig_proc *proc; - uint32_t rtt_ms; - - proc = ble_l2cap_sig_proc_extract(conn_handle, BLE_L2CAP_SIG_PROC_OP_PING, - hdr->identifier); - if (proc == NULL) { - return BLE_HS_ENOENT; - } - - if (proc->ping.cb != NULL) { - ble_npl_time_t now = ble_npl_time_get(); - rtt_ms = ble_npl_time_ticks_to_ms32(now - proc->ping.time_sent); - proc->ping.cb(conn_handle, rtt_ms, *om); - ble_l2cap_sig_proc_free(proc); - } - - return 0; -} - int ble_l2cap_sig_disconnect(struct ble_l2cap_chan *chan) { @@ -1940,60 +1876,6 @@ ble_l2cap_sig_extract_expired(struct ble_l2cap_sig_proc_list *dst_list) return next_exp_in; } -int -ble_l2cap_sig_ping(uint16_t conn_handle, ble_l2cap_ping_fn cb, - const void *data, uint16_t data_len) -{ - struct ble_l2cap_sig_proc *proc; - struct os_mbuf *txom; - void *req; - struct ble_l2cap_sig_hdr *hdr; - int rc; - - if ((data_len > 0) && (data == NULL)) { - return BLE_HS_EBADDATA; - } - - ble_hs_lock(); - proc = ble_l2cap_sig_proc_alloc(); - ble_hs_unlock(); - - if (!proc) { - return BLE_HS_ENOMEM; - } - - /* allocate and fill procedure context */ - proc->op = BLE_L2CAP_SIG_PROC_OP_PING; - proc->id = ble_l2cap_sig_next_id(); - proc->conn_handle = conn_handle; - proc->ping.cb = cb; - proc->ping.time_sent = ble_npl_time_get(); - - /* allocate signalling packet and copy payload into packet */ - req = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_ECHO_REQ, - proc->id, 0, &txom); - if (req == NULL) { - ble_l2cap_sig_proc_free(proc); - return BLE_HS_ENOMEM; - } - if (data_len > 0) { - rc = os_mbuf_append(txom, data, data_len); - if (rc != 0) { - os_mbuf_free_chain(txom); - ble_l2cap_sig_proc_free(proc); - return BLE_HS_ENOMEM; - } - /* adjust the size field in the signalling header */ - hdr = (struct ble_l2cap_sig_hdr *)txom->om_data; - hdr->length = htole16(data_len); - } - - - rc = ble_l2cap_sig_tx(proc->conn_handle, txom); - ble_l2cap_sig_process_status(proc, rc); - return rc; -} - void ble_l2cap_sig_conn_broken(uint16_t conn_handle, int reason) { diff --git a/nimble/host/src/ble_l2cap_sig_priv.h b/nimble/host/src/ble_l2cap_sig_priv.h index 55b37cd206..a698cd0d8f 100644 --- a/nimble/host/src/ble_l2cap_sig_priv.h +++ b/nimble/host/src/ble_l2cap_sig_priv.h @@ -172,8 +172,6 @@ ble_l2cap_sig_coc_reconfig(uint16_t conn_handle, struct ble_l2cap_chan *chans[], } #endif -int ble_l2cap_sig_ping(uint16_t conn_handle, ble_l2cap_ping_fn cb, - const void *data, uint16_t data_len); void ble_l2cap_sig_conn_broken(uint16_t conn_handle, int reason); int32_t ble_l2cap_sig_timer(void); struct ble_l2cap_chan *ble_l2cap_sig_create_chan(uint16_t conn_handle); From 89ac67032e382a0c9a92b0798d1e877d252f6f00 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 9 Nov 2021 15:03:54 +0100 Subject: [PATCH 0179/1333] nimble/ll: Use 'vs' for vendor specific HCI consistently --- nimble/controller/include/controller/ble_ll.h | 2 +- nimble/controller/include/controller/ble_ll_ctrl.h | 6 +++--- nimble/controller/src/ble_ll_ctrl.c | 10 ++++++---- nimble/controller/src/ble_ll_hci_ev.c | 14 +++++++------- nimble/controller/syscfg.yml | 8 ++++++-- nimble/include/nimble/hci_common.h | 4 ++-- 6 files changed, 25 insertions(+), 19 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 556883422c..dfda8cfeb4 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -48,7 +48,7 @@ extern "C" { if (hal_debugger_connected()) { \ assert(0);\ } else {\ - ble_ll_hci_ev_send_vendor_err(__FILE__, __LINE__); \ + ble_ll_hci_ev_send_vs_assert(__FILE__, __LINE__); \ while(1) {}\ }\ } diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index bd38e583e9..62e1a53569 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -315,9 +315,9 @@ int ble_ll_hci_ev_phy_update(struct ble_ll_conn_sm *connsm, uint8_t status); void ble_ll_calc_session_key(struct ble_ll_conn_sm *connsm); void ble_ll_ctrl_phy_update_proc_complete(struct ble_ll_conn_sm *connsm); void ble_ll_ctrl_initiate_dle(struct ble_ll_conn_sm *connsm); -void ble_ll_hci_ev_send_vendor_err(const char *file, uint32_t line); -void ble_ll_hci_ev_send_llcp_trace(uint8_t type, uint16_t handle, uint16_t count, - void *pdu, size_t length); +void ble_ll_hci_ev_send_vs_assert(const char *file, uint32_t line); +void ble_ll_hci_ev_send_vs_llcp_trace(uint8_t type, uint16_t handle, uint16_t count, + void *pdu, size_t length); uint8_t ble_ll_ctrl_phy_tx_transition_get(uint8_t phy_mask); uint8_t ble_ll_ctrl_phy_from_phy_mask(uint8_t phy_mask); diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index b6c6036ec1..94d73a9bb5 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -2469,8 +2469,9 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) opcode = dptr[2]; #if MYNEWT_VAL(BLE_LL_HCI_LLCP_TRACE) - ble_ll_hci_ev_send_llcp_trace(0x03, connsm->conn_handle, connsm->event_cntr, - &dptr[2], len); + ble_ll_hci_ev_send_vs_llcp_trace(0x03, connsm->conn_handle, + connsm->event_cntr, + &dptr[2], len); #endif /* @@ -2803,8 +2804,9 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) uint8_t opcode; #if MYNEWT_VAL(BLE_LL_HCI_LLCP_TRACE) - ble_ll_hci_ev_send_llcp_trace(0x04, connsm->conn_handle, connsm->event_cntr, - txpdu->om_data, txpdu->om_len); + ble_ll_hci_ev_send_vs_llcp_trace(0x04, connsm->conn_handle, + connsm->event_cntr, + txpdu->om_data, txpdu->om_len); #endif rc = 0; diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index ccbb1aa94d..9d6c39ecc0 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -493,9 +493,9 @@ ble_ll_hci_ev_sca_update(struct ble_ll_conn_sm *connsm, uint8_t status, #endif void -ble_ll_hci_ev_send_vendor_err(const char *file, uint32_t line) +ble_ll_hci_ev_send_vs_assert(const char *file, uint32_t line) { - struct ble_hci_ev_vendor_debug *ev; + struct ble_hci_ev_vs_debug *ev; struct ble_hci_ev *hci_ev; unsigned int str_len; bool skip = true; @@ -510,7 +510,7 @@ ble_ll_hci_ev_send_vendor_err(const char *file, uint32_t line) hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); if (hci_ev) { - hci_ev->opcode = BLE_HCI_EVCODE_VENDOR_DEBUG; + hci_ev->opcode = BLE_HCI_EVCODE_VS_DEBUG; hci_ev->length = sizeof(*ev); ev = (void *) hci_ev->data; @@ -554,15 +554,15 @@ ble_ll_hci_ev_send_vendor_err(const char *file, uint32_t line) #if MYNEWT_VAL(BLE_LL_HCI_LLCP_TRACE) void -ble_ll_hci_ev_send_llcp_trace(uint8_t type, uint16_t handle, uint16_t count, - void *pdu, size_t length) +ble_ll_hci_ev_send_vs_llcp_trace(uint8_t type, uint16_t handle, uint16_t count, + void *pdu, size_t length) { - struct ble_hci_ev_vendor_debug *ev; + struct ble_hci_ev_vs_debug *ev; struct ble_hci_ev *hci_ev; hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); if (hci_ev) { - hci_ev->opcode = BLE_HCI_EVCODE_VENDOR_DEBUG; + hci_ev->opcode = BLE_HCI_EVCODE_VS_DEBUG; hci_ev->length = sizeof(*ev) + 8 + length; ev = (void *) hci_ev->data; diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index de6e688c6d..d60e18fc25 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -348,7 +348,7 @@ syscfg.defs: depending on specified HCI command length. value: 0 - BLE_LL_VND_EVENT_ON_ASSERT: + BLE_LL_HCI_VS_EVENT_ON_ASSERT: description: > This options enables controller to send a vendor-specific event on an assertion in controller code. The event contains file name and @@ -438,6 +438,10 @@ syscfg.defs: description: use BLE_LL_SCA instead value: 60 deprecated: 1 + BLE_LL_VND_EVENT_ON_ASSERT: + description: use BLE_LL_HCI_VS_EVENT_ON_ASSERT + value: 0 + deprecated: 1 # defunct settings (to be removed eventually) BLE_DEVICE: @@ -466,7 +470,7 @@ syscfg.vals.BLE_LL_CFG_FEAT_LL_EXT_ADV: # Enable vendor event on assert in standalone build to make failed assertions in # controller code visible when connected to external host syscfg.vals.!BLE_HOST: - BLE_LL_VND_EVENT_ON_ASSERT: 1 + BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 syscfg.restrictions: - OS_CPUTIME_FREQ == 32768 diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 9acb76238f..b6f9869a71 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1446,8 +1446,8 @@ struct ble_hci_ev_auth_pyld_tmo { #define BLE_HCI_EVCODE_SAM_STATUS_CHG (0x58) -#define BLE_HCI_EVCODE_VENDOR_DEBUG (0xFF) -struct ble_hci_ev_vendor_debug { +#define BLE_HCI_EVCODE_VS_DEBUG (0xFF) +struct ble_hci_ev_vs_debug { uint8_t id; uint8_t data[0]; } __attribute__((packed)); From b8ddf0fe06dfc7c717d183c9202eab2283421d06 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 5 Nov 2021 11:42:06 +0100 Subject: [PATCH 0180/1333] nimble/ll: Add support for vs hci commands registration This adds API to allow registration of custom HCI VS commands. --- .../include/controller/ble_ll_hci.h | 18 +++ nimble/controller/src/ble_ll.c | 5 + nimble/controller/src/ble_ll_hci.c | 44 +------ nimble/controller/src/ble_ll_hci_priv.h | 37 ++++++ nimble/controller/src/ble_ll_hci_vs.c | 119 ++++++++++++++++++ nimble/controller/syscfg.yml | 5 + 6 files changed, 186 insertions(+), 42 deletions(-) create mode 100644 nimble/controller/src/ble_ll_hci_priv.h create mode 100644 nimble/controller/src/ble_ll_hci_vs.c diff --git a/nimble/controller/include/controller/ble_ll_hci.h b/nimble/controller/include/controller/ble_ll_hci.h index 6a9e48e537..9f3fc9503f 100644 --- a/nimble/controller/include/controller/ble_ll_hci.h +++ b/nimble/controller/include/controller/ble_ll_hci.h @@ -43,6 +43,20 @@ extern const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN]; typedef void (*ble_ll_hci_post_cmd_complete_cb)(void); +#if MYNEWT_VAL(BLE_HCI_VS) +typedef int (* ble_ll_hci_vs_cb_t)(uint16_t ocf, + const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen); + +#define BLE_LL_HCI_VS_CMD(_ocf, _cb) { .ocf = (_ocf), .cb = (_cb) } + +struct ble_ll_hci_vs_cmd { + uint16_t ocf; + ble_ll_hci_vs_cb_t cb; + SLIST_ENTRY(ble_ll_hci_vs_cmd) link; +}; +#endif + /* Initialize LL HCI */ void ble_ll_hci_init(void); @@ -68,6 +82,10 @@ bool ble_ll_hci_adv_mode_ext(void); /* Get TX power compensation rounded to integer dB */ int8_t ble_ll_get_tx_pwr_compensation(void); +#if MYNEWT_VAL(BLE_HCI_VS) +void ble_ll_hci_vs_register(struct ble_ll_hci_vs_cmd *cmds, uint32_t num_cmds); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 5305e162bc..16c2242c22 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -45,6 +45,7 @@ #include "controller/ble_ll_trace.h" #include "controller/ble_ll_sync.h" #include "ble_ll_conn_priv.h" +#include "ble_ll_hci_priv.h" #include "ble_ll_priv.h" #if MYNEWT_VAL(BLE_LL_DTM) @@ -1731,6 +1732,10 @@ ble_ll_init(void) ble_ll_dtm_init(); #endif +#if MYNEWT_VAL(BLE_HCI_VS) + ble_ll_hci_vs_init(); +#endif + #if MYNEWT /* Initialize the LL task */ os_task_init(&g_ble_ll_task, "ble_ll", ble_ll_task, NULL, diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index c2603c989d..0e92939133 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -36,6 +36,7 @@ #include "controller/ble_ll_iso.h" #include "ble_ll_priv.h" #include "ble_ll_conn_priv.h" +#include "ble_ll_hci_priv.h" #if MYNEWT_VAL(BLE_LL_DTM) #include "ble_ll_dtm_priv.h" @@ -1525,47 +1526,6 @@ ble_ll_hci_status_params_cmd_proc(const uint8_t *cmdbuf, uint8_t len, return rc; } -#if MYNEWT_VAL(BLE_HCI_VS) -static int -ble_ll_hci_vs_rd_static_addr(uint8_t *rspbuf, uint8_t *rsplen) -{ - struct ble_hci_vs_rd_static_addr_rp *rsp = (void *) rspbuf; - ble_addr_t addr; - - if (ble_hw_get_static_addr(&addr) < 0) { - return BLE_ERR_UNSPECIFIED; - } - - memcpy(rsp->addr, addr.val, sizeof(rsp->addr)); - - *rsplen = sizeof(*rsp); - return BLE_ERR_SUCCESS; -} - -static int -ble_ll_hci_vs_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, - uint8_t *rspbuf, uint8_t *rsplen) -{ - int rc; - - /* Assume error; if all pass rc gets set to 0 */ - rc = BLE_ERR_INV_HCI_CMD_PARMS; - - switch (ocf) { - case BLE_HCI_OCF_VS_RD_STATIC_ADDR: - if (len == 0) { - rc = ble_ll_hci_vs_rd_static_addr(rspbuf, rsplen); - } - break; - default: - rc = BLE_ERR_UNKNOWN_HCI_CMD; - break; - } - - return rc; -} -#endif - /** * Called to process an HCI command from the host. * @@ -1625,7 +1585,7 @@ ble_ll_hci_cmd_proc(struct ble_npl_event *ev) case BLE_HCI_OGF_LE: rc = ble_ll_hci_le_cmd_proc(cmd->data, cmd->length, ocf, rspbuf, &rsplen, &post_cb); break; -#if MYNEWT_VAL(BLE_HCI_VS) +#if MYNEWT_VAL(BLE_LL_HCI_VS) case BLE_HCI_OGF_VENDOR: rc = ble_ll_hci_vs_cmd_proc(cmd->data, cmd->length, ocf, rspbuf, &rsplen); break; diff --git a/nimble/controller/src/ble_ll_hci_priv.h b/nimble/controller/src/ble_ll_hci_priv.h new file mode 100644 index 0000000000..f289dc1035 --- /dev/null +++ b/nimble/controller/src/ble_ll_hci_priv.h @@ -0,0 +1,37 @@ +/* + * 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_BLE_LL_HCI_PRIV_ +#define H_BLE_LL_HCI_PRIV_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if MYNEWT_VAL(BLE_HCI_VS) +void ble_ll_hci_vs_init(void); +int ble_ll_hci_vs_cmd_proc(const uint8_t *cmdbuf, uint8_t cmdlen, uint16_t ocf, + uint8_t *rspbuf, uint8_t *rsplen); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* H_BLE_LL_HCI_ */ diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c new file mode 100644 index 0000000000..8903525ec9 --- /dev/null +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -0,0 +1,119 @@ +/* + * 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. + */ + +#include +#include "syscfg/syscfg.h" +#include "controller/ble_ll.h" +#include "controller/ble_ll_hci.h" +#include "controller/ble_hw.h" + +#if MYNEWT_VAL(BLE_LL_HCI_VS) + +SLIST_HEAD(ble_ll_hci_vs_list, ble_ll_hci_vs_cmd); +static struct ble_ll_hci_vs_list g_ble_ll_hci_vs_list; + +static int +ble_ll_hci_vs_rd_static_addr(uint16_t ocf, + const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + struct ble_hci_vs_rd_static_addr_rp *rsp = (void *) rspbuf; + ble_addr_t addr; + + if (cmdlen != 0) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (ble_hw_get_static_addr(&addr) < 0) { + return BLE_ERR_UNSPECIFIED; + } + + memcpy(rsp->addr, addr.val, sizeof(rsp->addr)); + + *rsplen = sizeof(*rsp); + + return BLE_ERR_SUCCESS; +} + +static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { + BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_RD_STATIC_ADDR, + ble_ll_hci_vs_rd_static_addr), +}; + +static struct ble_ll_hci_vs_cmd * +ble_ll_hci_vs_find_by_ocf(uint16_t ocf) +{ + struct ble_ll_hci_vs_cmd *entry; + + entry = SLIST_FIRST(&g_ble_ll_hci_vs_list); + while (entry) { + if (entry->ocf == ocf) { + return entry; + } + + entry = SLIST_NEXT(entry, link); + } + + return NULL; +} + +int +ble_ll_hci_vs_cmd_proc(const uint8_t *cmdbuf, uint8_t cmdlen, uint16_t ocf, + uint8_t *rspbuf, uint8_t *rsplen) +{ + struct ble_ll_hci_vs_cmd *cmd; + int rc; + + cmd = ble_ll_hci_vs_find_by_ocf(ocf); + if (!cmd) { + rc = BLE_ERR_UNKNOWN_HCI_CMD; + } else { + rc = cmd->cb(ocf, cmdbuf, cmdlen, rspbuf, rsplen); + } + + return rc; +} + +void +ble_ll_hci_vs_register(struct ble_ll_hci_vs_cmd *cmds, uint32_t num_cmds) +{ + uint32_t i; + + /* Assume all cmds are registered early on init, so just assert in case of + * invalid request since it means something is wrong with the code itself. + */ + + for (i = 0; i < num_cmds; i++, cmds++) { + BLE_LL_ASSERT(cmds->cb != NULL); + BLE_LL_ASSERT(ble_ll_hci_vs_find_by_ocf(cmds->ocf) == NULL); + + SLIST_INSERT_HEAD(&g_ble_ll_hci_vs_list, cmds, link); + } +} + +void +ble_ll_hci_vs_init(void) +{ + SLIST_INIT(&g_ble_ll_hci_vs_list); + + ble_ll_hci_vs_register(g_ble_ll_hci_vs_cmds, + ARRAY_SIZE(g_ble_ll_hci_vs_cmds)); +} + +#endif diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index d60e18fc25..d799e1c757 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -348,6 +348,11 @@ syscfg.defs: depending on specified HCI command length. value: 0 + BLE_LL_HCI_VS: + description: > + Enables support for vendor-specific HCI commands. + value: MYNEWT_VAL(BLE_HCI_VS) + BLE_LL_HCI_VS_EVENT_ON_ASSERT: description: > This options enables controller to send a vendor-specific event on From 51c0f770ee92b3605029f24e4433bfde39c8314b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 4 Nov 2021 17:21:39 +0100 Subject: [PATCH 0181/1333] nimble/phy/nrf: Remove workrounds for ifs on LE Coded BLE_PHY_CODED_RX_IFS_EXTRA_MARGIN was added with initial implementation for LE Coded to workaround problems with some early releases of devices that could not keep ifs timing properly. We do not want it anymore, all devices should have ifs implemented properly in 2021 already. --- nimble/drivers/nrf52/src/ble_phy.c | 11 ----------- nimble/drivers/nrf52/syscfg.yml | 10 ---------- 2 files changed, 21 deletions(-) diff --git a/nimble/drivers/nrf52/src/ble_phy.c b/nimble/drivers/nrf52/src/ble_phy.c index 6c520ab8b8..7085e78c68 100644 --- a/nimble/drivers/nrf52/src/ble_phy.c +++ b/nimble/drivers/nrf52/src/ble_phy.c @@ -703,17 +703,6 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) * by waiting 1 usec more. */ end_time += 1; -#if MYNEWT_VAL(BLE_PHY_CODED_RX_IFS_EXTRA_MARGIN) > 0 - if ((phy == BLE_PHY_MODE_CODED_125KBPS) || - (phy == BLE_PHY_MODE_CODED_500KBPS)) { - /* - * Some controllers exceed T_IFS when transmitting on coded phy - * so let's wait a bit longer to be able to talk to them if this - * workaround is enabled. - */ - end_time += MYNEWT_VAL(BLE_PHY_CODED_RX_IFS_EXTRA_MARGIN); - } -#endif } else { /* * RX shall start no later than wfr_usecs after RX enabled. diff --git a/nimble/drivers/nrf52/syscfg.yml b/nimble/drivers/nrf52/syscfg.yml index ce5123721a..bb6a2e1ba0 100644 --- a/nimble/drivers/nrf52/syscfg.yml +++ b/nimble/drivers/nrf52/syscfg.yml @@ -22,16 +22,6 @@ syscfg.defs: Enable SystemView tracing module for radio driver. value: 0 - BLE_PHY_CODED_RX_IFS_EXTRA_MARGIN: - description: > - This defines additional margin for T_IFS tolerance while in - RX on coded phy to allow maintaining connections with some - controllers that exceed proper T_IFS (150 usecs) by more - than allowed 2 usecs. - This value shall be only used for debugging purposes. It is - strongly recommended to keep this settings at default value - to ensure compliance with specification. - value: 0 BLE_PHY_DBG_TIME_TXRXEN_READY_PIN: description: > When set to proper GPIO pin number, this pin will be set From 0ef8d590db8bc741f3e25610c6e3e6d11dba2c6c Mon Sep 17 00:00:00 2001 From: Kaka1234-ai <73267746+Kaka1234-ai@users.noreply.github.com> Date: Thu, 18 Nov 2021 10:26:25 +0800 Subject: [PATCH 0182/1333] nimble/ll: Fix master SCA in LE Connection Complete Event MCA in LE (Enhanced) Connection Complete Event is valid only for peripheral role (5.3 V4 Part E 7.7.6.5.1). --- nimble/controller/src/ble_ll_conn_hci.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 7e47377381..6489af0d5b 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -200,7 +200,9 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, enh_ev->conn_itvl = htole16(connsm->conn_itvl); enh_ev->conn_latency = htole16(connsm->slave_latency); enh_ev->supervision_timeout = htole16(connsm->supervision_tmo); - enh_ev->mca = connsm->master_sca; + if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + enh_ev->mca = connsm->master_sca; + } } ble_ll_hci_event_send(hci_ev); @@ -225,7 +227,9 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, ev->conn_itvl = htole16(connsm->conn_itvl); ev->conn_latency = htole16(connsm->slave_latency); ev->supervision_timeout = htole16(connsm->supervision_tmo); - ev->mca = connsm->master_sca; + if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + ev->mca = connsm->master_sca; + } } ble_ll_hci_event_send(hci_ev); From 10a7493c0f12e1b428c5becdfd2c13495827ba1a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 25 Nov 2021 13:47:28 +0100 Subject: [PATCH 0183/1333] nimble/ll: Fix include guards for HCI_VS --- nimble/controller/include/controller/ble_ll_hci.h | 4 ++-- nimble/controller/src/ble_ll.c | 2 +- nimble/controller/src/ble_ll_hci_priv.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_hci.h b/nimble/controller/include/controller/ble_ll_hci.h index 9f3fc9503f..a9ea3bb055 100644 --- a/nimble/controller/include/controller/ble_ll_hci.h +++ b/nimble/controller/include/controller/ble_ll_hci.h @@ -43,7 +43,7 @@ extern const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN]; typedef void (*ble_ll_hci_post_cmd_complete_cb)(void); -#if MYNEWT_VAL(BLE_HCI_VS) +#if MYNEWT_VAL(BLE_LL_HCI_VS) typedef int (* ble_ll_hci_vs_cb_t)(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen); @@ -82,7 +82,7 @@ bool ble_ll_hci_adv_mode_ext(void); /* Get TX power compensation rounded to integer dB */ int8_t ble_ll_get_tx_pwr_compensation(void); -#if MYNEWT_VAL(BLE_HCI_VS) +#if MYNEWT_VAL(BLE_LL_HCI_VS) void ble_ll_hci_vs_register(struct ble_ll_hci_vs_cmd *cmds, uint32_t num_cmds); #endif diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 16c2242c22..b5a527abb8 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1732,7 +1732,7 @@ ble_ll_init(void) ble_ll_dtm_init(); #endif -#if MYNEWT_VAL(BLE_HCI_VS) +#if MYNEWT_VAL(BLE_LL_HCI_VS) ble_ll_hci_vs_init(); #endif diff --git a/nimble/controller/src/ble_ll_hci_priv.h b/nimble/controller/src/ble_ll_hci_priv.h index f289dc1035..af67e0a1a3 100644 --- a/nimble/controller/src/ble_ll_hci_priv.h +++ b/nimble/controller/src/ble_ll_hci_priv.h @@ -24,7 +24,7 @@ extern "C" { #endif -#if MYNEWT_VAL(BLE_HCI_VS) +#if MYNEWT_VAL(BLE_LL_HCI_VS) void ble_ll_hci_vs_init(void); int ble_ll_hci_vs_cmd_proc(const uint8_t *cmdbuf, uint8_t cmdlen, uint16_t ocf, uint8_t *rspbuf, uint8_t *rsplen); From f1d2cbd8d3f7fa0a15840f91b78446be9f1cc3c1 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 25 Nov 2021 13:47:43 +0100 Subject: [PATCH 0184/1333] porting/riot: Refresh syscfg --- porting/npl/riot/include/syscfg/syscfg.h | 73 ++++++++++++++++++++---- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 480616b819..24b49da51d 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0 + * This file was generated by Apache newt version: 1.10.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -18,16 +18,16 @@ /*** Repository @apache-mynewt-core info */ #ifndef MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_CORE -#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_CORE ("58d4be4b8e33dd4738a2a0c1c2016a9195542833") +#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_CORE ("49ac781dfadbeecfd03d60bcaac15617744783b7-dirty") #endif #ifndef MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_CORE -#define MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_CORE ("0.0.1") +#define MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_CORE ("0.0.0") #endif /*** Repository @apache-mynewt-mcumgr info */ #ifndef MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_MCUMGR -#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_MCUMGR ("12b496e37caf20a45ab5aee4209b06c5d79ef9b1") +#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_MCUMGR ("b03a5d43ef6640d4f8858f59140b256a0ee4e772-dirty") #endif #ifndef MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_MCUMGR @@ -36,22 +36,58 @@ /*** Repository @apache-mynewt-nimble info */ #ifndef MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_NIMBLE -#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_NIMBLE ("99de1340e7fbdee6a604415972bd24ec5117a78d") +#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_NIMBLE ("846dda1f93c05aaf38281925b256fdbd5044492d-dirty") #endif #ifndef MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_NIMBLE #define MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_NIMBLE ("0.0.0") #endif +/*** Repository @bsim info */ +#ifndef MYNEWT_VAL_REPO_HASH_BSIM +#define MYNEWT_VAL_REPO_HASH_BSIM ("8c5297423a7602b2c0bf47c64c2ac22d55d646ac") +#endif + +#ifndef MYNEWT_VAL_REPO_VERSION_BSIM +#define MYNEWT_VAL_REPO_VERSION_BSIM ("0.0.0") +#endif + /*** Repository @mcuboot info */ #ifndef MYNEWT_VAL_REPO_HASH_MCUBOOT -#define MYNEWT_VAL_REPO_HASH_MCUBOOT ("137d79717764ed32d5da4b4b301f32f81b2bf40f") +#define MYNEWT_VAL_REPO_HASH_MCUBOOT ("d4c2d15c3ef524333abf7f1e5839265ad5055d96") #endif #ifndef MYNEWT_VAL_REPO_VERSION_MCUBOOT #define MYNEWT_VAL_REPO_VERSION_MCUBOOT ("0.0.0") #endif +/*** Repository @mynewt_runtime info */ +#ifndef MYNEWT_VAL_REPO_HASH_MYNEWT_RUNTIME +#define MYNEWT_VAL_REPO_HASH_MYNEWT_RUNTIME ("17c53cd08300587cb5b6e5647566799eff2de198") +#endif + +#ifndef MYNEWT_VAL_REPO_VERSION_MYNEWT_RUNTIME +#define MYNEWT_VAL_REPO_VERSION_MYNEWT_RUNTIME ("0.0.0") +#endif + +/*** Repository @onsemi info */ +#ifndef MYNEWT_VAL_REPO_HASH_ONSEMI +#define MYNEWT_VAL_REPO_HASH_ONSEMI ("a3bf406b581c1aba025b8fe9472a6d8628e94e53") +#endif + +#ifndef MYNEWT_VAL_REPO_VERSION_ONSEMI +#define MYNEWT_VAL_REPO_VERSION_ONSEMI ("0.0.0") +#endif + +/*** Repository @tinyusb info */ +#ifndef MYNEWT_VAL_REPO_HASH_TINYUSB +#define MYNEWT_VAL_REPO_HASH_TINYUSB ("aa1a5a11c7729548957e5d8baf1c18ba7a333d14") +#endif + +#ifndef MYNEWT_VAL_REPO_VERSION_TINYUSB +#define MYNEWT_VAL_REPO_VERSION_TINYUSB ("0.0.0") +#endif + /*** @apache-mynewt-core/compiler/arm-none-eabi-m4 */ @@ -1016,8 +1052,8 @@ #define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_RFMGMT (-1) #endif -#ifndef MYNEWT_VAL_BLE_LL_DEBUG_GPIO_SCHED_ITEM_CB -#define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_SCHED_ITEM_CB (-1) +#ifndef MYNEWT_VAL_BLE_LL_DEBUG_GPIO_SCHED_ITEM +#define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_SCHED_ITEM (-1) #endif #ifndef MYNEWT_VAL_BLE_LL_DEBUG_GPIO_SCHED_RUN @@ -1045,6 +1081,19 @@ #define MYNEWT_VAL_BLE_LL_HCI_LLCP_TRACE (0) #endif +/* Value copied from BLE_HCI_VS */ +#ifndef MYNEWT_VAL_BLE_LL_HCI_VS +#define MYNEWT_VAL_BLE_LL_HCI_VS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_ON_ASSERT +#define MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_ON_ASSERT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_STATS_ON_RESET +#define MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_STATS_ON_RESET (0) +#endif + #ifndef MYNEWT_VAL_BLE_LL_MASTER_SCA #define MYNEWT_VAL_BLE_LL_MASTER_SCA (4) #endif @@ -1077,6 +1126,10 @@ #define MYNEWT_VAL_BLE_LL_PRIO (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_PUBLIC_DEV_ADDR +#define MYNEWT_VAL_BLE_LL_PUBLIC_DEV_ADDR (0x000000000000) +#endif + #ifndef MYNEWT_VAL_BLE_LL_RESOLV_LIST_SIZE #define MYNEWT_VAL_BLE_LL_RESOLV_LIST_SIZE (4) #endif @@ -1170,10 +1223,6 @@ #endif /*** @apache-mynewt-nimble/nimble/drivers/nrf52 */ -#ifndef MYNEWT_VAL_BLE_PHY_CODED_RX_IFS_EXTRA_MARGIN -#define MYNEWT_VAL_BLE_PHY_CODED_RX_IFS_EXTRA_MARGIN (0) -#endif - #ifndef MYNEWT_VAL_BLE_PHY_DBG_TIME_ADDRESS_END_PIN #define MYNEWT_VAL_BLE_PHY_DBG_TIME_ADDRESS_END_PIN (-1) #endif From 8d912e27c2bf4bfd4196b82299084b552281ec05 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 30 Nov 2021 09:42:51 +0100 Subject: [PATCH 0185/1333] nimble/ll: Fix os_cputime comparisons in ll_adv Need to use macros, otherwise it won't work as expected... --- nimble/controller/src/ble_ll_adv.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 88c4ae12b1..64a3b4034c 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1527,7 +1527,8 @@ ble_ll_adv_aux_schedule_next(struct ble_ll_adv_sm *advsm) * scheduled aux will fit inside duration. If not, remove it from scheduler * so advertising will stop after current aux. */ - if (advsm->duration && (aux_next->sch.end_time > advsm->adv_end_time)) { + if (advsm->duration && + CPUTIME_GT(aux_next->sch.end_time, advsm->adv_end_time)) { ble_ll_sched_rmv_elem(&aux_next->sch); } } @@ -1657,7 +1658,7 @@ ble_ll_adv_aux_schedule(struct ble_ll_adv_sm *advsm) * not start extended advertising event which we cannot finish in time. */ if (advsm->duration && - (AUX_CURRENT(advsm)->sch.end_time > advsm->adv_end_time)) { + CPUTIME_GT(AUX_CURRENT(advsm)->sch.end_time, advsm->adv_end_time)) { ble_ll_adv_sm_stop_timeout(advsm); } } @@ -2414,8 +2415,8 @@ ble_ll_adv_periodic_schedule_next(struct ble_ll_adv_sm *advsm) sync_next); /* if we are pass advertising interval, drop chain */ - if (sch->end_time > advsm->periodic_adv_event_start_time + - advsm->periodic_adv_itvl_ticks) { + if (CPUTIME_GT(sch->end_time, advsm->periodic_adv_event_start_time + + advsm->periodic_adv_itvl_ticks)) { STATS_INC(ble_ll_stats, periodic_chain_drop_event); ble_ll_sched_rmv_elem(&sync->sch); ble_npl_eventq_put(&g_ble_ll_data.ll_evq, @@ -4730,7 +4731,8 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) /* If we're past aux (unlikely, but can happen), just drop an event */ if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) && advsm->aux_active && - advsm->adv_pdu_start_time > AUX_CURRENT(advsm)->start_time) { + CPUTIME_GT(advsm->adv_pdu_start_time, + AUX_CURRENT(advsm)->start_time)) { ble_ll_adv_drop_event(advsm); return; } @@ -4742,7 +4744,7 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) /* check if advertising timed out */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (advsm->duration && - advsm->adv_pdu_start_time >= advsm->adv_end_time) { + CPUTIME_GEQ(advsm->adv_pdu_start_time, advsm->adv_end_time)) { /* Legacy PDUs need to be stop here. * For ext adv it will be stopped when AUX is done (unless it was * dropped so check if AUX is active here as well). @@ -4756,7 +4758,7 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) } #else if ((advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) && - (advsm->adv_pdu_start_time >= advsm->adv_end_time)) { + CPUTIME_GEQ(advsm->adv_pdu_start_time, advsm->adv_end_time)) { ble_ll_adv_sm_stop_timeout(advsm); return; } @@ -4860,7 +4862,8 @@ ble_ll_adv_sec_done(struct ble_ll_adv_sm *advsm) ble_ll_scan_chk_resume(); /* Check if advertising timed out */ - if (advsm->duration && (advsm->adv_pdu_start_time >= advsm->adv_end_time)) { + if (advsm->duration && + CPUTIME_GEQ(advsm->adv_pdu_start_time, advsm->adv_end_time)) { ble_ll_adv_sm_stop_timeout(advsm); return; } From afd677efd275d18f76be25da04a5da9cba4e66f6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 30 Nov 2021 16:00:56 +0100 Subject: [PATCH 0186/1333] nimble/ll: Move BLE_PUBLIC_DEV_ADDR to deprecated settings --- nimble/controller/syscfg.yml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index d799e1c757..7c33242716 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -315,15 +315,6 @@ syscfg.defs: Note: this setting should only be used for testing purposes, it is not intended for production builds. value: 0x000000000000 - BLE_PUBLIC_DEV_ADDR: - description: > - Allows the target or app to override the public device address - used by the controller. If all zero, the controller will - attempt to retrieve the public device address from its - chip specific location. If non-zero, this address will - be used. - value: "(uint8_t[6]){0x00, 0x00, 0x00, 0x00, 0x00, 0x00}" - deprecated: 1 BLE_LL_DTM: description: > @@ -447,6 +438,10 @@ syscfg.defs: description: use BLE_LL_HCI_VS_EVENT_ON_ASSERT value: 0 deprecated: 1 + BLE_PUBLIC_DEV_ADDR: + description: use BLE_LL_PUBLIC_DEV_ADDR + value: "(uint8_t[6]){0x00, 0x00, 0x00, 0x00, 0x00, 0x00}" + deprecated: 1 # defunct settings (to be removed eventually) BLE_DEVICE: From a17ed2a1da2f5850bb33ac65b18334c8104ac5bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 1 Dec 2021 14:56:24 +0100 Subject: [PATCH 0187/1333] host/mesh: fix bt_mesh_proxy_relay client->cli can be NULL - and this should be checked, not connection handle. --- nimble/host/mesh/src/proxy_srv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index 3507d0a45a..dcbabfa296 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -758,7 +758,7 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) struct bt_mesh_proxy_client *client = &clients[i]; struct os_mbuf *msg; - if (client->cli->conn_handle == BLE_HS_CONN_HANDLE_NONE) { + if (!client->cli) { continue; } From bc142016bdef082ba7997aea09aec1c1e4db0104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 23 Nov 2021 13:31:16 +0100 Subject: [PATCH 0188/1333] host/mesh: fix loopback in net net_buf structure in Zephyr has field user_data, which was wrongly ported as os_mbuf->om_data. To stick with porting net_buf as os_mbuf we can base on old Zephyr's implementation, which was changed in commit dd09cbc1c455ab1e067b53f46bee7b6d50689bbc. Before it, user_data was part of data buffer of net_buf. We can implement this the same way, so data_buf is last N octets of os_mbuf->om_data. Accomodate mbuf allocation and freeing to NimBLE. --- nimble/host/mesh/src/net.c | 4 ++-- nimble/host/mesh/src/net.h | 7 ++++++- nimble/host/mesh/syscfg.yml | 5 +++++ porting/examples/linux_blemesh/include/syscfg/syscfg.h | 4 ++++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index a36160d778..229e40546e 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -398,7 +398,7 @@ static void bt_mesh_net_local(struct ble_npl_event *work) rx.ctx.addr, rx.seq, sub); (void) bt_mesh_trans_recv(buf, &rx); - net_buf_unref(buf); + os_mbuf_free_chain(buf); } } @@ -480,7 +480,7 @@ static int loopback(const struct bt_mesh_net_tx *tx, const uint8_t *data, { struct os_mbuf *buf; - buf = os_mbuf_get_pkthdr(&loopback_os_mbuf_pool, 0); + buf = os_mbuf_get_pkthdr(&loopback_os_mbuf_pool, BT_MESH_NET_HDR_LEN); if (!buf) { BT_WARN("Unable to allocate loopback"); return -ENOMEM; diff --git a/nimble/host/mesh/src/net.h b/nimble/host/mesh/src/net.h index 9d8f857610..b8147b4d86 100644 --- a/nimble/host/mesh/src/net.h +++ b/nimble/host/mesh/src/net.h @@ -271,7 +271,12 @@ extern struct bt_mesh_net bt_mesh; static inline void *net_buf_user_data(const struct os_mbuf *buf) { - return (void *)buf->om_data; + /* In Zephyr at the end of net_buf (which is ported as os_mbuf) is place + * for user_data, which is array of octets, just like os_mbuf's om_data. Let's just + * use last octets (starting at start of om_data + total size of data mbuf can hold - + * intended user_data size) of om_data as Zephyr's user_data. + */ + return (void *)(buf->om_data + buf->om_omp->omp_databuf_len - MYNEWT_VAL(BLE_MESH_NET_BUF_USER_DATA_SIZE)); } int bt_mesh_net_create(uint16_t idx, uint8_t flags, const uint8_t key[16], diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index ca74cdff7d..c75828d243 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -233,6 +233,11 @@ syscfg.defs: but has a different purpose. value: 10 + BLE_MESH_NET_BUF_USER_DATA_SIZE: + description: > + Number of octets that are used as user_data at the end of os_mbufs + value: 4 + BLE_MESH_ADV_BUF_COUNT: description: > Number of advertising buffers available. This should be chosen diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 5a5288f52e..5d21359010 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -772,6 +772,10 @@ #endif /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_NET_BUF_USER_DATA_SIZE +#define MYNEWT_VAL_BLE_MESH_NET_BUF_USER_DATA_SIZE (4) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT #define MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT (20) #endif From 6b40986a1f508881aea3cbdd8c497627fd3180b3 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 7 Dec 2021 12:15:16 +0100 Subject: [PATCH 0189/1333] porting: Allow to build with -Wcast-align It is expected that mbuf structures are properly aligned so we can just cast to void pointer here and silence warning. --- porting/nimble/include/os/os_mbuf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/porting/nimble/include/os/os_mbuf.h b/porting/nimble/include/os/os_mbuf.h index 771ea76159..bee47d0bbf 100644 --- a/porting/nimble/include/os/os_mbuf.h +++ b/porting/nimble/include/os/os_mbuf.h @@ -133,11 +133,11 @@ struct os_mqueue { /** Get a packet header pointer given an mbuf pointer */ #define OS_MBUF_PKTHDR(__om) ((struct os_mbuf_pkthdr *) \ - ((uint8_t *)&(__om)->om_data + sizeof(struct os_mbuf))) + (void *)((uint8_t *)&(__om)->om_data + sizeof(struct os_mbuf))) /** Given a mbuf packet header pointer, return a pointer to the mbuf */ #define OS_MBUF_PKTHDR_TO_MBUF(__hdr) \ - (struct os_mbuf *)((uint8_t *)(__hdr) - sizeof(struct os_mbuf)) + (struct os_mbuf *)(void *)((uint8_t *)(__hdr) - sizeof(struct os_mbuf)) /** * Gets the length of an entire mbuf chain. The specified mbuf must have a From 5e94b1b85a798ff17ad3ccc0879d676a11deae6f Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 6 Dec 2021 16:16:58 +0100 Subject: [PATCH 0190/1333] nimble/ll: Fix not validating no-param HCI commands sizes If command has no input parameters its size should be verified before passing it to handler function. --- nimble/controller/src/ble_ll_hci.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 0e92939133..c59137a884 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1152,10 +1152,14 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, #endif #endif case BLE_HCI_OCF_LE_RD_TRANSMIT_POWER: - rc = ble_ll_read_tx_power(rspbuf, rsplen); + if (len == 0) { + rc = ble_ll_read_tx_power(rspbuf, rsplen); + } break; case BLE_HCI_OCF_LE_RD_RF_PATH_COMPENSATION: - rc = ble_ll_read_rf_path_compensation(rspbuf, rsplen); + if (len == 0) { + rc = ble_ll_read_rf_path_compensation(rspbuf, rsplen); + } break; case BLE_HCI_OCF_LE_WR_RF_PATH_COMPENSATION: rc = ble_ll_write_rf_path_compensation(cmdbuf, len); @@ -1217,7 +1221,9 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, rc = ble_ll_iso_remove_iso_data_path(cmdbuf, len); break; case BLE_HCI_OCF_LE_RD_BUF_SIZE_V2: - rc = ble_ll_hci_le_read_bufsize_v2(rspbuf, rsplen); + if (len == 0) { + rc = ble_ll_hci_le_read_bufsize_v2(rspbuf, rsplen); + } break; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO_TEST) From 64b74026961663f9172f90559f75975808ebae62 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 6 Dec 2021 16:18:24 +0100 Subject: [PATCH 0191/1333] nimble/ll: Fix typo in ble_ll_read_rf_path_compensation ;; are not needed here --- nimble/controller/src/ble_ll_hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index c59137a884..e3e558e612 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -786,7 +786,7 @@ ble_ll_read_rf_path_compensation(uint8_t *rspbuf, uint8_t *rsplen) rsp->rx_path_compensation = htole16(rx_path_pwr_compensation); rsp->tx_path_compensation = htole16(tx_path_pwr_compensation); - *rsplen = sizeof(*rsp);; + *rsplen = sizeof(*rsp); return BLE_ERR_SUCCESS; } From 96df59e1deca6c5bf90b18fe7d7fd144353c0806 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 6 Dec 2021 10:58:34 +0100 Subject: [PATCH 0192/1333] nimble/transport: Fix ble_ll_hw_error declaration in UART transport ble_ll_hw_error() is defined as taking no arguments. --- nimble/transport/uart/src/ble_hci_uart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/transport/uart/src/ble_hci_uart.c b/nimble/transport/uart/src/ble_hci_uart.c index cbb6dd4259..2cad55a7d9 100644 --- a/nimble/transport/uart/src/ble_hci_uart.c +++ b/nimble/transport/uart/src/ble_hci_uart.c @@ -55,7 +55,7 @@ /* XXX: for now, define this here */ #if MYNEWT_VAL(BLE_CONTROLLER) extern void ble_ll_data_buffer_overflow(void); -extern void ble_ll_hw_error(uint8_t err); +extern void ble_ll_hw_error(void); static const uint8_t ble_hci_uart_reset_cmd[4] = { 0x01, 0x03, 0x0C, 0x00 }; #endif @@ -400,7 +400,7 @@ ble_hci_uart_sync_lost(void) ble_hci_uart_state.rx_cmd.cur = 0; ble_hci_uart_state.rx_cmd.data = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - ble_ll_hw_error(BLE_HW_ERR_HCI_SYNC_LOSS); + ble_ll_hw_error(); ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_SYNC_LOSS; } #endif From 7a6c64774faaa373310e21886ba979f253898b8c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 8 Dec 2021 13:21:11 +0100 Subject: [PATCH 0193/1333] nimble/ll: Fix supported commands bitmask --- nimble/controller/src/ble_ll_supp_cmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_supp_cmd.c b/nimble/controller/src/ble_ll_supp_cmd.c index cae9eb7dd1..6ceeaebb02 100644 --- a/nimble/controller/src/ble_ll_supp_cmd.c +++ b/nimble/controller/src/ble_ll_supp_cmd.c @@ -483,9 +483,9 @@ /* Octet 44 */ #if MYNEWT_VAL(BLE_VERSION) >= 52 -#define BLE_SUPP_CMD_LE_SET_HOST_FEATURE (1 << 0) +#define BLE_SUPP_CMD_LE_SET_HOST_FEATURE (1 << 1) #else -#define BLE_SUPP_CMD_LE_SET_HOST_FEATURE (0 << 0) +#define BLE_SUPP_CMD_LE_SET_HOST_FEATURE (0 << 1) #endif #define BLE_LL_SUPP_CMD_OCTET_44 \ ( \ From 3b029a774bc09ba092924421534691212c43af58 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 8 Dec 2021 13:07:38 +0100 Subject: [PATCH 0194/1333] nimble/ll: Always send hci_cs for unknown command Core 5.3, Vol 4, Part E, 4.5 states that sending hci_cc vs. hci_cs is vendor specific so we always send hci_cs for all commands since we already do this for LE commands. --- nimble/controller/src/ble_ll_hci.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index e3e558e612..7bbc6774c5 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1266,11 +1266,8 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, * This code is here because we add 256 to the return code to denote * that the reply to this command should be command status (as opposed to * command complete). - * - * For unknown HCI command let us return always command status as per - * specification Bluetooth 5, Vol. 2, Chapter 4.4 */ - if (ble_ll_hci_le_cmd_send_cmd_status(ocf) || rc == BLE_ERR_UNKNOWN_HCI_CMD) { + if (ble_ll_hci_le_cmd_send_cmd_status(ocf)) { rc += (BLE_ERR_MAX + 1); } @@ -1602,6 +1599,13 @@ ble_ll_hci_cmd_proc(struct ble_npl_event *ev) break; } + /* We always send command status for unknown command + * ref: Core 5.3, Vol 4, Part E, 4.5 + */ + if (rc == BLE_ERR_UNKNOWN_HCI_CMD) { + rc += (BLE_ERR_MAX + 1); + } + /* If no response is generated, we free the buffers */ BLE_LL_ASSERT(rc >= 0); if (rc <= BLE_ERR_MAX) { From a6009432de27b9e0ea5e1f95dba4d82d5412ac9f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 25 Nov 2021 12:45:23 +0100 Subject: [PATCH 0195/1333] nimble/ll: Add missing scan resume Need to always resume scan on rx_pkt_in... --- nimble/controller/src/ble_ll_scan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 47b7d0bd7f..6e78f3245d 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1942,6 +1942,7 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd } #endif if (ptype > max_pdu_type) { + ble_ll_scan_chk_resume(); return; } From 67d30b63b373f6d16f1d1caf22a9af73415be229 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 25 Nov 2021 12:45:46 +0100 Subject: [PATCH 0196/1333] nimble/phy/nrf: Move rx_end to disabled event This moves handling of PDU RX end from EVENT_END to EVENT_DISABLED. This will allow to run our phy on BabbleSim and also seems to simplify code a bit. EVENT_DISABLED happens almost immediately after EVENT_END, so on real it happens while ble_phy_isr is being executed and is simply ignored. However, on BabbleSim code is executed as if time was paused which means that no other event can occur when ble_phy_isr is being executed, i.e. it will be called after we return from isr and simulation code can trigger subsequent events. If rx_end configures transition to TX and thus enables interrupt on EVENT_DISABLED, we will handle that during an event that is triggered for RX - basically we handle tx_end before TX even started. Using EVENT_DISABLED for both TX and RX resolves this issue. We still use timer capture on EVENT_END for transition timing so this has no effect on that calculations, and since EVENT_DISABLED occurs just a fraction of microsecond after EVENT_END, execution timings are also not affected. --- nimble/drivers/nrf52/src/ble_phy.c | 61 +++++++++++++----------------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/nimble/drivers/nrf52/src/ble_phy.c b/nimble/drivers/nrf52/src/ble_phy.c index 7085e78c68..6aa898b327 100644 --- a/nimble/drivers/nrf52/src/ble_phy.c +++ b/nimble/drivers/nrf52/src/ble_phy.c @@ -730,9 +730,6 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) /* Enable wait for response PPI */ NRF_PPI->CHENSET = (PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk); - /* Enable the disabled interrupt so we time out on events compare */ - NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk; - /* * It may happen that if CPU is halted for a brief moment (e.g. during flash * erase or write), TIMER0 already counted past CC[3] and thus wfr will not @@ -860,7 +857,8 @@ ble_phy_rx_xcvr_setup(void) RADIO_SHORTS_ADDRESS_RSSISTART_Msk | RADIO_SHORTS_DISABLED_RSSISTOP_Msk; - NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk; + NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk | + RADIO_INTENSET_DISABLED_Msk; } /** @@ -874,7 +872,6 @@ ble_phy_tx_end_isr(void) uint8_t was_encrypted; uint8_t transition; uint32_t rx_time; - uint32_t wfr_time; /* Store PHY on which we've just transmitted smth */ tx_phy_mode = g_ble_phy_data.phy_cur_phy_mode; @@ -886,13 +883,6 @@ ble_phy_tx_end_isr(void) /* Better be in TX state! */ assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX); - /* Clear events and clear interrupt on disabled event */ - NRF_RADIO->EVENTS_DISABLED = 0; - NRF_RADIO->INTENCLR = RADIO_INTENCLR_DISABLED_Msk; - NRF_RADIO->EVENTS_END = 0; - wfr_time = NRF_RADIO->SHORTS; - (void)wfr_time; - #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) /* * XXX: not sure what to do. We had a HW error during transmission. @@ -982,10 +972,6 @@ ble_phy_rx_end_isr(void) uint32_t tx_time; struct ble_mbuf_hdr *ble_hdr; - /* Clear events and clear interrupt */ - NRF_RADIO->EVENTS_END = 0; - NRF_RADIO->INTENCLR = RADIO_INTENCLR_END_Msk; - /* Disable automatic RXEN */ NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk; @@ -1116,9 +1102,9 @@ ble_phy_rx_start_isr(void) /* Clear events and clear interrupt */ NRF_RADIO->EVENTS_ADDRESS = 0; + NRF_RADIO->INTENCLR = RADIO_INTENCLR_ADDRESS_Msk; - /* Clear wfr timer channels and DISABLED interrupt */ - NRF_RADIO->INTENCLR = RADIO_INTENCLR_DISABLED_Msk | RADIO_INTENCLR_ADDRESS_Msk; + /* Clear wfr timer channels */ NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk; /* Initialize the ble mbuf header */ @@ -1210,7 +1196,6 @@ ble_phy_rx_start_isr(void) if (rc >= 0) { /* Set rx started flag and enable rx end ISR */ g_ble_phy_data.phy_rx_started = 1; - NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk; } else { /* Disable PHY */ ble_phy_disable(); @@ -1256,28 +1241,36 @@ ble_phy_isr(void) } } - /* Check for disabled event. This only happens for transmits now */ + /* Handle disabled event. This is enabled for both TX and RX. On RX, we + * need to check phy_rx_started flag to make sure we actually were receiving + * a PDU, otherwise this is due to wfr. + */ if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) { - if (g_ble_phy_data.phy_state == BLE_PHY_STATE_RX) { - NRF_RADIO->EVENTS_DISABLED = 0; - ble_ll_wfr_timer_exp(NULL); - } else if (g_ble_phy_data.phy_state == BLE_PHY_STATE_IDLE) { - assert(0); - } else { + BLE_LL_ASSERT(NRF_RADIO->EVENTS_END || + ((g_ble_phy_data.phy_state == BLE_PHY_STATE_RX) && + !g_ble_phy_data.phy_rx_started)); + NRF_RADIO->EVENTS_END = 0; + NRF_RADIO->EVENTS_DISABLED = 0; + NRF_RADIO->INTENCLR = RADIO_INTENCLR_DISABLED_Msk; + + switch (g_ble_phy_data.phy_state) { + case BLE_PHY_STATE_RX: + if (g_ble_phy_data.phy_rx_started) { + ble_phy_rx_end_isr(); + } else { + ble_ll_wfr_timer_exp(NULL); + } + break; + case BLE_PHY_STATE_TX: ble_phy_tx_end_isr(); + break; + default: + BLE_LL_ASSERT(0); } } - /* Receive packet end (we dont enable this for transmit) */ - if ((irq_en & RADIO_INTENCLR_END_Msk) && NRF_RADIO->EVENTS_END) { - ble_phy_rx_end_isr(); - } - g_ble_phy_data.phy_transition_late = 0; - /* Ensures IRQ is cleared */ - irq_en = NRF_RADIO->SHORTS; - /* Count # of interrupts */ STATS_INC(ble_phy_stats, phy_isrs); From e744a88bf8f106f45492066b635b21985d3ebc07 Mon Sep 17 00:00:00 2001 From: Marceau Fillon Date: Wed, 24 Nov 2021 17:49:16 +1100 Subject: [PATCH 0197/1333] host/ble_att_svr: Reset handles index on attributes reset. --- nimble/host/src/ble_att_svr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 9af0e0d043..468768ac02 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -2671,6 +2671,8 @@ ble_att_svr_reset(void) ble_att_svr_entry_free(entry); } + ble_att_svr_id = 0; + /* Note: prep entries do not get freed here because it is assumed there are * no established connections. */ From 1969ca31127775a1895f2767d4bb3c4f53493662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 19 Nov 2021 08:04:52 +0100 Subject: [PATCH 0198/1333] host/l2cap: disconnect peer that sends L2CAP packets with hdr len > mtu Rest of the checks disconnects peer if SDU size exceeds MTU, but value in header is OK. We should also disconnect if PDU lenght in L2CAP packet header exceeds it, regardles of how much data it actually contains, not just return error. This is affecting L2CAP/LE/CFC/BV-26-C and L2CAP/ECFC/BV-33-C --- nimble/host/src/ble_l2cap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_l2cap.c b/nimble/host/src/ble_l2cap.c index 2bc50e0e93..bfbdadfcd6 100644 --- a/nimble/host/src/ble_l2cap.c +++ b/nimble/host/src/ble_l2cap.c @@ -393,8 +393,11 @@ ble_l2cap_rx(struct ble_hs_conn *conn, } if (l2cap_hdr.len > ble_l2cap_get_mtu(chan)) { - /* More data then we expected on the channel */ + /* More data than we expected on the channel. + * Disconnect peer with invalid behaviour + */ rc = BLE_HS_EBADDATA; + ble_l2cap_disconnect(chan); goto err; } From de56c3a41af98d26e56a21a7902bc6e6a54dd10f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 25 Nov 2021 09:34:20 +0100 Subject: [PATCH 0199/1333] host/l2cap_sig: do not permit duplicated CID in connect response If peer sends L2CAP connect response with duplicated DCID connection should not be created on that channel and existing channel of this CID shall be disconnected. This is affecting L2CAP/ECFC/BV-29-C --- nimble/host/src/ble_l2cap_sig.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index f34c20b8bb..3033e05dd5 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -1048,6 +1048,7 @@ ble_l2cap_sig_credit_base_con_rsp_rx(uint16_t conn_handle, struct ble_hs_conn *conn; int rc; int i; + uint16_t duplicated_cids[5] = {}; #if !BLE_MONITOR BLE_HS_LOG(DEBUG, "L2CAP LE COC connection response received\n"); @@ -1093,6 +1094,12 @@ ble_l2cap_sig_credit_base_con_rsp_rx(uint16_t conn_handle, chan->dcid = 0; continue; } + if (ble_hs_conn_chan_find_by_dcid(conn, rsp->dcids[i])) { + duplicated_cids[i] = rsp->dcids[i]; + chan->dcid = 0; + continue; + } + chan->peer_coc_mps = le16toh(rsp->mps); chan->dcid = le16toh(rsp->dcids[i]); chan->coc_tx.mtu = le16toh(rsp->mtu); @@ -1104,6 +1111,16 @@ ble_l2cap_sig_credit_base_con_rsp_rx(uint16_t conn_handle, ble_hs_unlock(); done: + for (i = 0; i < 5; i++){ + if (duplicated_cids[i] != 0){ + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + chan = ble_hs_conn_chan_find_by_dcid(conn, duplicated_cids[i]); + ble_hs_unlock(); + rc = ble_l2cap_sig_disconnect(chan); + } + } + ble_l2cap_sig_coc_connect_cb(proc, rc); ble_l2cap_sig_proc_free(proc); From d7c18041d75970a2a13af2a644a437b43a3d58c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 25 Nov 2021 09:37:09 +0100 Subject: [PATCH 0200/1333] apps/bttester: mark L2CAP channel as used in connect This will prevent returning same channel every time in `get_free_channel()`. --- apps/bttester/src/l2cap.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/bttester/src/l2cap.c b/apps/bttester/src/l2cap.c index b9b97ec199..35e746d5cf 100644 --- a/apps/bttester/src/l2cap.c +++ b/apps/bttester/src/l2cap.c @@ -398,7 +398,7 @@ static void connect(uint8_t *data, uint16_t len) ble_addr_t *addr = (void *) data; uint16_t mtu = htole16(cmd->mtu); int rc; - int i; + int i, j; SYS_LOG_DBG("connect: type: %d addr: %s", addr->type, bt_hex(addr->val, 6)); @@ -420,6 +420,8 @@ static void connect(uint8_t *data, uint16_t len) SYS_LOG_ERR("No free channels"); goto fail; } + /* temporarily mark channel as used to select next one */ + chan->state = 1; rp->chan_ids[i] = chan->chan_id; @@ -430,6 +432,15 @@ static void connect(uint8_t *data, uint16_t len) } } + /* mark selected channels as unused again */ + for (i = 0; i < cmd->num; i++) { + for (j = 0; j < CHANNELS; j++) { + if (rp->chan_ids[i] == channels[j].chan_id) { + channels[j].state = 0; + } + } + } + if (cmd->num == 1) { rc = ble_l2cap_connect(desc.conn_handle, htole16(cmd->psm), mtu, sdu_rx[0], From 5b6352364ba44d8fc93e1394d308f99efe782bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 25 Nov 2021 09:38:31 +0100 Subject: [PATCH 0201/1333] app/bttester: do not send L2CAP disconnection event if error in connect There is a little need of sending such event: created connection is confirmed connection event; if no such event is received, the connection can be considered not established. Disconnected event shall be sent only for disconnection. By removing disconnected_cb call on connect error we avoid calling it for not established channel, for example when DCID in connection response was a duplicate of already connected one. This would trigger the assert `assert(channel != NULL);`. --- apps/bttester/src/l2cap.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/bttester/src/l2cap.c b/apps/bttester/src/l2cap.c index 35e746d5cf..27cc6a9a6e 100644 --- a/apps/bttester/src/l2cap.c +++ b/apps/bttester/src/l2cap.c @@ -259,8 +259,6 @@ tester_l2cap_event(struct ble_l2cap_event *event, void *arg) if (event->connect.status) { console_printf("LE COC error: %d\n", event->connect.status); - disconnected_cb(event->connect.conn_handle, - event->connect.chan, &chan_info, arg); return 0; } From 8c6f70425ba2d697044d4b12201744b26cc47a92 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Mon, 22 Nov 2021 14:12:34 +0100 Subject: [PATCH 0202/1333] apps: Update transport selection method Transport package should not be included directly. Instead, nimble/transport should be included and BLE_HCI_TRANSPORT syscfg value should specify transport, and this will include correct package. This commit changes nimble/transport/ram to nimble/transport in all applications that still have deprecated way of transport selection. Default value of BLE_HCI_TRANSPORT is ram so syscfg.yml for targets does not need to be updated. --- apps/blehr/pkg.yml | 2 +- apps/blemesh/pkg.yml | 2 +- apps/blemesh_light/pkg.yml | 2 +- apps/blemesh_models_example_1/pkg.yml | 2 +- apps/blemesh_models_example_2/pkg.yml | 2 +- apps/blemesh_shell/pkg.yml | 2 +- apps/blestress/pkg.yml | 2 +- apps/bttester/pkg.yml | 2 +- apps/ext_advertiser/pkg.yml | 2 +- apps/mesh_badge/pkg.yml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/blehr/pkg.yml b/apps/blehr/pkg.yml index b91ba3775b..395134faba 100644 --- a/apps/blehr/pkg.yml +++ b/apps/blehr/pkg.yml @@ -37,4 +37,4 @@ pkg.deps: - nimble/host/services/gap - nimble/host/services/gatt - nimble/host/store/config - - nimble/transport/ram + - nimble/transport diff --git a/apps/blemesh/pkg.yml b/apps/blemesh/pkg.yml index c70565423c..8a2af6874c 100644 --- a/apps/blemesh/pkg.yml +++ b/apps/blemesh/pkg.yml @@ -34,4 +34,4 @@ pkg.deps: - nimble/host/services/gap - nimble/host/services/gatt - nimble/host/store/config - - nimble/transport/ram + - nimble/transport diff --git a/apps/blemesh_light/pkg.yml b/apps/blemesh_light/pkg.yml index 75a60df7bb..bfc1ad233a 100644 --- a/apps/blemesh_light/pkg.yml +++ b/apps/blemesh_light/pkg.yml @@ -34,4 +34,4 @@ pkg.deps: - nimble/host/services/gap - nimble/host/services/gatt - nimble/host/store/config - - nimble/transport/ram + - nimble/transport diff --git a/apps/blemesh_models_example_1/pkg.yml b/apps/blemesh_models_example_1/pkg.yml index 451f37a11c..cd11834c5f 100644 --- a/apps/blemesh_models_example_1/pkg.yml +++ b/apps/blemesh_models_example_1/pkg.yml @@ -31,4 +31,4 @@ pkg.deps: - nimble/host - nimble/host/services/gap - nimble/host/services/gatt - - nimble/transport/ram + - nimble/transport diff --git a/apps/blemesh_models_example_2/pkg.yml b/apps/blemesh_models_example_2/pkg.yml index ee2be6da2a..684d85bad8 100644 --- a/apps/blemesh_models_example_2/pkg.yml +++ b/apps/blemesh_models_example_2/pkg.yml @@ -33,7 +33,7 @@ pkg.deps: - nimble/host - nimble/host/services/gap - nimble/host/services/gatt - - nimble/transport/ram + - nimble/transport pkg.lflags: - -DFLOAT_SUPPORT diff --git a/apps/blemesh_shell/pkg.yml b/apps/blemesh_shell/pkg.yml index e4852f6fa5..2e7064cf90 100644 --- a/apps/blemesh_shell/pkg.yml +++ b/apps/blemesh_shell/pkg.yml @@ -34,4 +34,4 @@ pkg.deps: - nimble/host/services/gap - nimble/host/services/gatt - nimble/host/store/config - - nimble/transport/ram + - nimble/transport diff --git a/apps/blestress/pkg.yml b/apps/blestress/pkg.yml index b23358c564..d4c52d247c 100644 --- a/apps/blestress/pkg.yml +++ b/apps/blestress/pkg.yml @@ -36,4 +36,4 @@ pkg.deps: - "@apache-mynewt-nimble/nimble/host/services/gap" - "@apache-mynewt-nimble/nimble/host/services/gatt" - "@apache-mynewt-nimble/nimble/host/store/config" - - "@apache-mynewt-nimble/nimble/transport/ram" + - "@apache-mynewt-nimble/nimble/transport" diff --git a/apps/bttester/pkg.yml b/apps/bttester/pkg.yml index ba2b7fb1be..39405aa051 100644 --- a/apps/bttester/pkg.yml +++ b/apps/bttester/pkg.yml @@ -38,7 +38,7 @@ pkg.deps: - "@apache-mynewt-nimble/nimble/host/services/gatt" - "@apache-mynewt-nimble/nimble/host/services/dis" - "@apache-mynewt-nimble/nimble/host/store/config" - - "@apache-mynewt-nimble/nimble/transport/ram" + - "@apache-mynewt-nimble/nimble/transport" - "@apache-mynewt-core/hw/drivers/uart" - "@apache-mynewt-core/hw/drivers/rtt" diff --git a/apps/ext_advertiser/pkg.yml b/apps/ext_advertiser/pkg.yml index 097764b206..b9f9e54728 100644 --- a/apps/ext_advertiser/pkg.yml +++ b/apps/ext_advertiser/pkg.yml @@ -31,7 +31,7 @@ pkg.deps: - nimble/host/services/gap - nimble/host/services/gatt - nimble/host/store/config - - nimble/transport/ram + - nimble/transport - "@apache-mynewt-core/kernel/os" - "@apache-mynewt-core/sys/console/full" - "@apache-mynewt-core/sys/log/full" diff --git a/apps/mesh_badge/pkg.yml b/apps/mesh_badge/pkg.yml index 0718236f6a..802b86bab4 100644 --- a/apps/mesh_badge/pkg.yml +++ b/apps/mesh_badge/pkg.yml @@ -36,4 +36,4 @@ pkg.deps: - nimble/host/services/gap - nimble/host/services/gatt - nimble/host/store/config - - nimble/transport/ram + - nimble/transport From d3a1acd3ffe9d2eaae8bed26630553d4bff1fc53 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 17 Dec 2021 15:23:37 +0100 Subject: [PATCH 0203/1333] nimble/ll: Compile out not enabled GAP roles This gives some FLASH and RAM savings for applications that use only subset of GAP roles. LL features are also tuned depending on selected GAP roles. Examples of FLASH and RAM usage: BLE_ROLE_CENTRAL: 1 BLE_ROLE_PERIPHERAL: 1 BLE_ROLE_BROADCASTER: 1 BLE_ROLE_OBSERVER: 1 56122 19661 @apache-mynewt-nimble_nimble_controller.a BLE_ROLE_CENTRAL: 0 BLE_ROLE_PERIPHERAL: 1 BLE_ROLE_BROADCASTER: 1 BLE_ROLE_OBSERVER: 1 51344 19589 @apache-mynewt-nimble_nimble_controller.a BLE_ROLE_CENTRAL: 0 BLE_ROLE_PERIPHERAL: 1 BLE_ROLE_BROADCASTER: 1 BLE_ROLE_OBSERVER: 0 35694 15232 @apache-mynewt-nimble_nimble_controller.a BLE_ROLE_CENTRAL: 1 BLE_ROLE_PERIPHERAL: 0 BLE_ROLE_BROADCASTER: 1 BLE_ROLE_OBSERVER: 1 53338 19593 @apache-mynewt-nimble_nimble_controller.a BLE_ROLE_CENTRAL: 1 BLE_ROLE_PERIPHERAL: 0 BLE_ROLE_BROADCASTER: 0 BLE_ROLE_OBSERVER: 1 42040 12925 @apache-mynewt-nimble_nimble_controller.a BLE_ROLE_CENTRAL: 0 BLE_ROLE_PERIPHERAL: 0 BLE_ROLE_BROADCASTER: 1 BLE_ROLE_OBSERVER: 1 34800 12525 @apache-mynewt-nimble_nimble_controller.a BLE_ROLE_CENTRAL: 0 BLE_ROLE_PERIPHERAL: 0 BLE_ROLE_BROADCASTER: 1 BLE_ROLE_OBSERVER: 0 19126 8168 @apache-mynewt-nimble_nimble_controller.a --- nimble/controller/include/controller/ble_ll.h | 18 ++ .../include/controller/ble_ll_conn.h | 14 ++ .../include/controller/ble_ll_scan.h | 8 + nimble/controller/src/ble_ll.c | 114 ++++++++-- nimble/controller/src/ble_ll_adv.c | 52 ++++- nimble/controller/src/ble_ll_conn.c | 154 +++++++++++--- nimble/controller/src/ble_ll_conn_hci.c | 67 +++++- nimble/controller/src/ble_ll_conn_priv.h | 2 + nimble/controller/src/ble_ll_ctrl.c | 196 ++++++++++++++---- nimble/controller/src/ble_ll_hci.c | 51 ++++- nimble/controller/src/ble_ll_resolv.c | 25 ++- nimble/controller/src/ble_ll_scan.c | 58 +++++- nimble/controller/src/ble_ll_scan_aux.c | 19 +- nimble/controller/src/ble_ll_sched.c | 87 ++++++-- nimble/controller/src/ble_ll_supp_cmd.c | 87 +++++++- nimble/controller/src/ble_ll_sync.c | 2 +- nimble/controller/src/ble_ll_whitelist.c | 18 +- nimble/controller/syscfg.yml | 36 +++- nimble/syscfg.yml | 1 + nimble/transport/uart/src/ble_hci_uart.c | 2 + 20 files changed, 860 insertions(+), 151 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index dfda8cfeb4..898907a19d 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -108,11 +108,13 @@ struct ble_ll_obj /* Current Link Layer state */ uint8_t ll_state; +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) /* Number of ACL data packets supported */ uint8_t ll_num_acl_pkts; /* ACL data packet size */ uint16_t ll_acl_pkt_size; +#endif /* Preferred PHY's */ uint8_t ll_pref_tx_phys; @@ -129,14 +131,18 @@ struct ble_ll_obj struct ble_ll_pkt_q ll_rx_pkt_q; /* Packet transmit queue */ +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) struct ble_npl_event ll_tx_pkt_ev; +#endif struct ble_ll_pkt_q ll_tx_pkt_q; +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) /* Data buffer overflow event */ struct ble_npl_event ll_dbuf_overflow_ev; /* Number of completed packets event */ struct ble_npl_event ll_comp_pkt_ev; +#endif /* HW error callout */ struct ble_npl_callout ll_hw_err_timer; @@ -214,12 +220,24 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats; /* States */ #define BLE_LL_STATE_STANDBY (0) +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) #define BLE_LL_STATE_ADV (1) +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) #define BLE_LL_STATE_SCANNING (2) +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define BLE_LL_STATE_CONNECTION (4) +#endif +#if MYNEWT_VAL(BLE_LL_DTM) #define BLE_LL_STATE_DTM (5) +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) && MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) #define BLE_LL_STATE_SYNC (6) +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) && MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) #define BLE_LL_STATE_SCAN_AUX (7) +#endif /* LL Features */ #define BLE_LL_FEAT_LE_ENCRYPTION (0x0000000001) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 7128dcb966..c3073c6e7d 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -34,8 +34,13 @@ extern "C" { /* Roles */ #define BLE_LL_CONN_ROLE_NONE (0) + +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define BLE_LL_CONN_ROLE_MASTER (1) +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) #define BLE_LL_CONN_ROLE_SLAVE (2) +#endif /* Connection states */ #define BLE_LL_CONN_STATE_IDLE (0) @@ -370,8 +375,17 @@ struct ble_ll_conn_sm #define CONN_F_AUX_CONN_REQ(csm) ((csm)->csmflags.cfbit.aux_conn_req) /* Role */ +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define CONN_IS_MASTER(csm) (csm->conn_role == BLE_LL_CONN_ROLE_MASTER) +#else +#define CONN_IS_MASTER(csm) (false) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) #define CONN_IS_SLAVE(csm) (csm->conn_role == BLE_LL_CONN_ROLE_SLAVE) +#else +#define CONN_IS_SLAVE(csm) (false) +#endif /* * Given a handle, returns an active connection state machine (or NULL if the diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index 77f9fa4265..a44e431379 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -152,14 +152,18 @@ struct ble_ll_scan_sm struct ble_ll_scan_phy *scanp_next; struct ble_ll_scan_phy scan_phys[BLE_LL_SCAN_PHY_NUMBER]; +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Connection sm for initiator scan */ struct ble_ll_conn_sm *connsm; +#endif }; /* Scan types */ #define BLE_SCAN_TYPE_PASSIVE (BLE_HCI_SCAN_TYPE_PASSIVE) #define BLE_SCAN_TYPE_ACTIVE (BLE_HCI_SCAN_TYPE_ACTIVE) +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define BLE_SCAN_TYPE_INITIATE (2) +#endif /*---- HCI ----*/ /* Set scanning parameters */ @@ -219,7 +223,11 @@ uint8_t *ble_ll_scan_get_local_rpa(void); void ble_ll_scan_sm_stop(int chk_disable); /* Resume scanning */ +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) void ble_ll_scan_chk_resume(void); +#else +static inline void ble_ll_scan_chk_resume(void) { }; +#endif /* Called when wait for response timer expires in scanning mode */ void ble_ll_scan_wfr_timer_exp(void); diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index b5a527abb8..0560b61da4 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -226,8 +226,10 @@ STATS_NAME_START(ble_ll_stats) STATS_NAME_END(ble_ll_stats) static void ble_ll_event_rx_pkt(struct ble_npl_event *ev); +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) static void ble_ll_event_tx_pkt(struct ble_npl_event *ev); static void ble_ll_event_dbuf_overflow(struct ble_npl_event *ev); +#endif #if MYNEWT @@ -579,10 +581,23 @@ ble_ll_set_random_addr(const uint8_t *cmdbuf, uint8_t len, bool hci_adv_ext) * Test specification extends this also to initiating. */ - if (g_ble_ll_conn_create_sm.connsm || ble_ll_scan_enabled() || - (!hci_adv_ext && ble_ll_adv_enabled())) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + if (g_ble_ll_conn_create_sm.connsm) { + return BLE_ERR_CMD_DISALLOWED; + } +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) + if (ble_ll_scan_enabled()){ return BLE_ERR_CMD_DISALLOWED; } +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) + if (!hci_adv_ext && ble_ll_adv_enabled()) { + return BLE_ERR_CMD_DISALLOWED; + } +#endif if (!ble_ll_is_valid_random_addr(cmd->addr)) { return BLE_ERR_INV_HCI_CMD_PARMS; @@ -591,12 +606,14 @@ ble_ll_set_random_addr(const uint8_t *cmdbuf, uint8_t len, bool hci_adv_ext) memcpy(g_random_addr, cmd->addr, BLE_DEV_ADDR_LEN); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) /* For instance 0 we need same address if legacy advertising might be * used. If extended advertising is in use than this command doesn't * affect instance 0. */ if (!hci_adv_ext) ble_ll_adv_set_random_addr(cmd->addr, 0); +#endif #endif return BLE_ERR_SUCCESS; @@ -670,18 +687,23 @@ ble_ll_wfr_timer_exp(void *arg) /* If we have started a reception, there is nothing to do here */ if (!rx_start) { switch (lls) { +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) case BLE_LL_STATE_ADV: ble_ll_adv_wfr_timer_exp(); break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_STATE_CONNECTION: ble_ll_conn_wfr_timer_exp(); break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) case BLE_LL_STATE_SCANNING: ble_ll_scan_wfr_timer_exp(); break; -#if MYNEWT_VAL(BLE_LL_DTM) - case BLE_LL_STATE_DTM: - ble_ll_dtm_wfr_timer_exp(); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + case BLE_LL_STATE_SCAN_AUX: + ble_ll_scan_aux_wfr_timer_exp(); break; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) @@ -689,9 +711,10 @@ ble_ll_wfr_timer_exp(void *arg) ble_ll_sync_wfr_timer_exp(); break; #endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - case BLE_LL_STATE_SCAN_AUX: - ble_ll_scan_aux_wfr_timer_exp(); +#endif +#if MYNEWT_VAL(BLE_LL_DTM) + case BLE_LL_STATE_DTM: + ble_ll_dtm_wfr_timer_exp(); break; #endif default: @@ -708,6 +731,7 @@ ble_ll_wfr_timer_exp(void *arg) * Context: Link layer task * */ +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) static void ble_ll_tx_pkt_in(void) { @@ -747,6 +771,7 @@ ble_ll_tx_pkt_in(void) ble_ll_conn_tx_pkt_in(om, handle, length); } } +#endif /** * Count Link Layer statistics for received PDUs @@ -763,7 +788,12 @@ ble_ll_count_rx_stats(struct ble_mbuf_hdr *hdr, uint16_t len, uint8_t pdu_type) bool connection_data; crcok = BLE_MBUF_HDR_CRC_OK(hdr); + +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) connection_data = (BLE_MBUF_HDR_RX_STATE(hdr) == BLE_LL_STATE_CONNECTION); +#else + connection_data = false; +#endif #if MYNEWT_VAL(BLE_LL_DTM) /* Reuse connection stats for DTM */ @@ -830,22 +860,22 @@ ble_ll_rx_pkt_in(void) /* Process the data or advertising pdu */ /* Process the PDU */ switch (BLE_MBUF_HDR_RX_STATE(ble_hdr)) { +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_STATE_CONNECTION: ble_ll_conn_rx_data_pdu(m, ble_hdr); /* m is going to be free by function above */ m = NULL; break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) case BLE_LL_STATE_ADV: ble_ll_adv_rx_pkt_in(pdu_type, rxbuf, ble_hdr); break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) case BLE_LL_STATE_SCANNING: ble_ll_scan_rx_pkt_in(pdu_type, m, ble_hdr); break; -#if MYNEWT_VAL(BLE_LL_DTM) - case BLE_LL_STATE_DTM: - ble_ll_dtm_rx_pkt_in(m, ble_hdr); - break; -#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) case BLE_LL_STATE_SYNC: ble_ll_sync_rx_pkt_in(m, ble_hdr); @@ -855,6 +885,12 @@ ble_ll_rx_pkt_in(void) case BLE_LL_STATE_SCAN_AUX: ble_ll_scan_aux_rx_pkt_in(m, ble_hdr); break; +#endif +#endif +#if MYNEWT_VAL(BLE_LL_DTM) + case BLE_LL_STATE_DTM: + ble_ll_dtm_rx_pkt_in(m, ble_hdr); + break; #endif default: /* Any other state should never occur */ @@ -883,6 +919,7 @@ ble_ll_rx_pdu_in(struct os_mbuf *rxpdu) ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_data.ll_rx_pkt_ev); } +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) /** * Called to put a packet on the Link Layer transmit packet queue. * @@ -913,6 +950,7 @@ ble_ll_data_buffer_overflow(void) { ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_data.ll_dbuf_overflow_ev); } +#endif /** * Called when a HW error occurs. @@ -970,20 +1008,20 @@ ble_ll_rx_start(uint8_t *rxbuf, uint8_t chan, struct ble_mbuf_hdr *rxhdr) pdu_type); switch (g_ble_ll_data.ll_state) { +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_STATE_CONNECTION: rc = ble_ll_conn_rx_isr_start(rxhdr, ble_phy_access_addr_get()); break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTERL) case BLE_LL_STATE_ADV: rc = ble_ll_adv_rx_isr_start(pdu_type); break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) case BLE_LL_STATE_SCANNING: rc = ble_ll_scan_rx_isr_start(pdu_type, &rxhdr->rxinfo.flags); break; -#if MYNEWT_VAL(BLE_LL_DTM) - case BLE_LL_STATE_DTM: - rc = ble_ll_dtm_rx_isr_start(rxhdr, ble_phy_access_addr_get()); - break; -#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) case BLE_LL_STATE_SYNC: rc = ble_ll_sync_rx_isr_start(pdu_type, rxhdr); @@ -993,6 +1031,12 @@ ble_ll_rx_start(uint8_t *rxbuf, uint8_t chan, struct ble_mbuf_hdr *rxhdr) case BLE_LL_STATE_SCAN_AUX: rc = ble_ll_scan_aux_rx_isr_start(pdu_type, rxhdr); break; +#endif +#endif +#if MYNEWT_VAL(BLE_LL_DTM) + case BLE_LL_STATE_DTM: + rc = ble_ll_dtm_rx_isr_start(rxhdr, ble_phy_access_addr_get()); + break; #endif default: /* Should not be in this state! */ @@ -1044,12 +1088,14 @@ ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) } #endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (BLE_MBUF_HDR_RX_STATE(rxhdr) == BLE_LL_STATE_CONNECTION) { rc = ble_ll_conn_rx_isr_end(rxbuf, rxhdr); return rc; } +#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) if (BLE_MBUF_HDR_RX_STATE(rxhdr) == BLE_LL_STATE_SYNC) { rc = ble_ll_sync_rx_isr_end(rxbuf, rxhdr); return rc; @@ -1097,6 +1143,7 @@ ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) /* Hand packet to the appropriate state machine (if crc ok) */ rxpdu = NULL; switch (BLE_MBUF_HDR_RX_STATE(rxhdr)) { +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) case BLE_LL_STATE_ADV: if (!badpkt) { rxpdu = ble_ll_rxpdu_alloc(len + BLE_LL_PDU_HDR_LEN); @@ -1106,6 +1153,8 @@ ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) } rc = ble_ll_adv_rx_isr_end(pdu_type, rxpdu, crcok); break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) case BLE_LL_STATE_SCANNING: if (!badpkt) { rxpdu = ble_ll_rxpdu_alloc(len + BLE_LL_PDU_HDR_LEN); @@ -1125,6 +1174,7 @@ ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) } rc = ble_ll_scan_aux_rx_isr_end(rxpdu, crcok); break; +#endif #endif default: rc = -1; @@ -1181,6 +1231,7 @@ ble_ll_event_rx_pkt(struct ble_npl_event *ev) ble_ll_rx_pkt_in(); } +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) static void ble_ll_event_tx_pkt(struct ble_npl_event *ev) { @@ -1198,6 +1249,7 @@ ble_ll_event_comp_pkts(struct ble_npl_event *ev) { ble_ll_conn_num_comp_pkts_event_send(NULL); } +#endif /** * Link Layer task. @@ -1314,9 +1366,11 @@ ble_ll_set_host_feat(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (!SLIST_EMPTY(&g_ble_ll_conn_active_list)) { return BLE_ERR_CMD_DISALLOWED; } +#endif if ((cmd->bit_num > 0x3F) || (cmd->val > 1)) { return BLE_ERR_INV_HCI_CMD_PARMS; @@ -1423,19 +1477,23 @@ ble_ll_reset(void) OS_ENTER_CRITICAL(sr); ble_phy_disable(); ble_ll_sched_stop(); +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) ble_ll_scan_reset(); +#endif ble_ll_rfmgmt_reset(); OS_EXIT_CRITICAL(sr); +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) /* Stop any advertising */ ble_ll_adv_reset(); +#endif #if MYNEWT_VAL(BLE_LL_DTM) ble_ll_dtm_reset(); #endif /* Stop sync */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) ble_ll_sync_reset(); #endif @@ -1450,8 +1508,10 @@ ble_ll_reset(void) g_ble_ll_data.ll_pref_tx_phys = 0; g_ble_ll_data.ll_pref_rx_phys = 0; +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Reset connection module */ ble_ll_conn_module_reset(); +#endif /* All this does is re-initialize the event masks so call the hci init */ ble_ll_hci_init(); @@ -1612,9 +1672,11 @@ ble_ll_init(void) /* Get pointer to global data object */ lldata = &g_ble_ll_data; +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) /* Set acl pkt size and number */ lldata->ll_num_acl_pkts = MYNEWT_VAL(BLE_ACL_BUF_COUNT); lldata->ll_acl_pkt_size = MYNEWT_VAL(BLE_ACL_BUF_SIZE); +#endif /* Initialize eventq */ ble_npl_eventq_init(&lldata->ll_evq); @@ -1625,11 +1687,15 @@ ble_ll_init(void) /* Initialize transmit (from host) and receive packet (from phy) event */ ble_npl_event_init(&lldata->ll_rx_pkt_ev, ble_ll_event_rx_pkt, NULL); +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) ble_npl_event_init(&lldata->ll_tx_pkt_ev, ble_ll_event_tx_pkt, NULL); +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) /* Initialize data buffer overflow event and completed packets */ ble_npl_event_init(&lldata->ll_dbuf_overflow_ev, ble_ll_event_dbuf_overflow, NULL); ble_npl_event_init(&lldata->ll_comp_pkt_ev, ble_ll_event_comp_pkts, NULL); +#endif /* Initialize the HW error timer */ ble_npl_callout_init(&g_ble_ll_data.ll_hw_err_timer, @@ -1643,14 +1709,20 @@ ble_ll_init(void) /* Init the scheduler */ ble_ll_sched_init(); +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) /* Initialize advertiser */ ble_ll_adv_init(); +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) /* Initialize a scanner */ ble_ll_scan_init(); +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) /* Initialize the connection module */ ble_ll_conn_module_init(); +#endif /* Set the supported features. NOTE: we always support extended reject. */ features = BLE_LL_FEAT_EXTENDED_REJ; @@ -1696,8 +1768,10 @@ ble_ll_init(void) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) features |= BLE_LL_FEAT_PERIODIC_ADV; +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) ble_ll_sync_init(); #endif +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) features |= BLE_LL_FEAT_SYNC_TRANS_RECV; diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 64a3b4034c..8a6cd1fe56 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -42,6 +42,8 @@ #include "controller/ble_ll_rfmgmt.h" #include "ble_ll_conn_priv.h" +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) + /* XXX: TODO * 1) Need to look at advertising and scan request PDUs. Do I allocate these * once? Do I use a different pool for smaller ones? Do I statically declare @@ -118,7 +120,9 @@ struct ble_ll_adv_sm struct os_mbuf *new_adv_data; struct os_mbuf *scan_rsp_data; struct os_mbuf *new_scan_rsp_data; +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) uint8_t *conn_comp_ev; +#endif struct ble_npl_event adv_txdone_ev; struct ble_ll_sched_item adv_sch; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) @@ -954,6 +958,7 @@ struct aux_conn_rsp_data { * * @param advsm */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) static uint8_t ble_ll_adv_aux_conn_rsp_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) @@ -1002,6 +1007,7 @@ ble_ll_adv_aux_conn_rsp_pdu_make(uint8_t *dptr, void *pducb_arg, return pdulen; } #endif +#endif /** * Called to indicate the advertising event is over. @@ -1750,6 +1756,7 @@ ble_ll_adv_set_adv_params(const uint8_t *cmdbuf, uint8_t len) adv_filter_policy = cmd->filter_policy; switch (cmd->type) { +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD: adv_filter_policy = BLE_HCI_ADV_FILT_NONE; memcpy(advsm->peer_addr, cmd->peer_addr, BLE_DEV_ADDR_LEN); @@ -1769,6 +1776,7 @@ ble_ll_adv_set_adv_params(const uint8_t *cmdbuf, uint8_t len) case BLE_HCI_ADV_TYPE_ADV_IND: props = BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_IND; break; +#endif case BLE_HCI_ADV_TYPE_ADV_NONCONN_IND: props = BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_NONCONN; break; @@ -1935,11 +1943,13 @@ ble_ll_adv_sm_stop(struct ble_ll_adv_sm *advsm) ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &advsm->adv_sec_txdone_ev); #endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) /* If there is an event buf we need to free it */ if (advsm->conn_comp_ev) { ble_hci_trans_buf_free(advsm->conn_comp_ev); advsm->conn_comp_ev = NULL; } +#endif ble_ll_adv_active_chanset_clear(advsm); @@ -1962,6 +1972,7 @@ ble_ll_adv_sm_stop_timeout(struct ble_ll_adv_sm *advsm) } #endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) /* * For high duty directed advertising we need to send connection * complete event with proper status @@ -1971,6 +1982,7 @@ ble_ll_adv_sm_stop_timeout(struct ble_ll_adv_sm *advsm) advsm->conn_comp_ev, advsm); advsm->conn_comp_ev = NULL; } +#endif /* Disable advertising */ ble_ll_adv_sm_stop(advsm); @@ -1992,11 +2004,13 @@ ble_ll_adv_sm_stop_limit_reached(struct ble_ll_adv_sm *advsm) * be used if HD directed advertising was terminated before timeout due to * events count limit. For now just use same code as with duration timeout. */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) { ble_ll_conn_comp_event_send(NULL, BLE_ERR_DIR_ADV_TMO, advsm->conn_comp_ev, advsm); advsm->conn_comp_ev = NULL; } +#endif /* Disable advertising */ ble_ll_adv_sm_stop(advsm); @@ -2629,7 +2643,6 @@ ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm) { uint8_t adv_chan; uint8_t *addr; - uint8_t *evbuf; uint32_t start_delay_us; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) uint32_t access_addr; @@ -2657,16 +2670,17 @@ ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm) * Get an event with which to send the connection complete event if * this is connectable */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) { /* We expect this to be NULL but if not we wont allocate one... */ if (advsm->conn_comp_ev == NULL) { - evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); - if (!evbuf) { + advsm->conn_comp_ev = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + if (!advsm->conn_comp_ev) { return BLE_ERR_MEM_CAPACITY; } - advsm->conn_comp_ev = evbuf; } } +#endif /* Set advertising address */ if ((advsm->own_addr_type & 1) == 0) { @@ -3282,9 +3296,11 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, /* if legacy bit is set possible values are limited */ switch (props) { +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_IND: case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_LD_DIR: case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_HD_DIR: +#endif case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_SCAN: case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_NONCONN: break; @@ -3293,6 +3309,12 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, goto done; } } else { +#if !MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) { + rc = BLE_ERR_INV_HCI_CMD_PARMS; + goto done; + } +#endif /* HD directed advertising allowed only on legacy PDUs */ if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) { rc = BLE_ERR_INV_HCI_CMD_PARMS; @@ -4096,6 +4118,7 @@ ble_ll_adv_periodic_set_info_transfer(const uint8_t *cmdbuf, uint8_t len, * @param [in] addr_type Public address (0) or random address (1). * @return Return 1 if already connected, 0 otherwise. */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) static int ble_ll_adv_already_connected(const uint8_t* addr, uint8_t addr_type) { @@ -4118,6 +4141,7 @@ ble_ll_adv_already_connected(const uint8_t* addr, uint8_t addr_type) return 0; } +#endif /** * Called when the LL receives a scan request or connection request @@ -4143,9 +4167,11 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu) uint8_t *peer; struct ble_mbuf_hdr *ble_hdr; struct ble_ll_adv_sm *advsm; +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) struct aux_conn_rsp_data rsp_data; #endif +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) struct ble_ll_resolv_entry *rl; #endif @@ -4252,6 +4278,7 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu) STATS_INC(ble_ll_stats, scan_rsp_txg); } } else if (pdu_type == BLE_ADV_PDU_TYPE_AUX_CONNECT_REQ) { +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) /* See if the device is already connected */ if (ble_ll_adv_already_connected(peer, peer_addr_type)) { return -1; @@ -4284,6 +4311,7 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu) ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD); STATS_INC(ble_ll_stats, aux_conn_rsp_tx); } +#endif #endif } @@ -4300,6 +4328,7 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu) * * @return 0: no connection started. 1: connection started */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) static int ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, struct ble_mbuf_hdr *hdr, struct ble_ll_adv_sm *advsm) @@ -4390,6 +4419,7 @@ ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, struct ble_mbuf_hdr *hdr, return valid; } +#endif /** * Called on phy rx pdu end when in advertising state. @@ -4498,9 +4528,11 @@ ble_ll_adv_rx_pkt_in(uint8_t ptype, uint8_t *rxbuf, struct ble_mbuf_hdr *hdr) adv_event_over = 1; if (BLE_MBUF_HDR_CRC_OK(hdr)) { if (ptype == BLE_ADV_PDU_TYPE_CONNECT_IND) { +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (ble_ll_adv_conn_req_rxd(rxbuf, hdr, advsm)) { adv_event_over = 0; } +#endif } else { if ((ptype == BLE_ADV_PDU_TYPE_SCAN_REQ) && (hdr->rxinfo.flags & BLE_MBUF_HDR_F_SCAN_RSP_TXD)) { @@ -4937,11 +4969,11 @@ ble_ll_adv_can_chg_whitelist(void) * * @return uint8_t* Pointer to event buffer */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) void ble_ll_adv_send_conn_comp_ev(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) { - uint8_t *evbuf; struct ble_ll_adv_sm *advsm; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) @@ -4950,12 +4982,11 @@ ble_ll_adv_send_conn_comp_ev(struct ble_ll_conn_sm *connsm, advsm = &g_ble_ll_adv_sm[0]; #endif - evbuf = advsm->conn_comp_ev; - assert(evbuf != NULL); + assert(advsm->conn_comp_ev != NULL); + ble_ll_conn_comp_event_send(connsm, BLE_ERR_SUCCESS, advsm->conn_comp_ev, + advsm); advsm->conn_comp_ev = NULL; - ble_ll_conn_comp_event_send(connsm, BLE_ERR_SUCCESS, evbuf, advsm); - #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) ble_ll_hci_ev_le_csa(connsm); #endif @@ -4967,6 +4998,7 @@ ble_ll_adv_send_conn_comp_ev(struct ble_ll_conn_sm *connsm, } #endif } +#endif /** * Returns the local resolvable private address currently being using by @@ -5128,3 +5160,5 @@ ble_ll_adv_init(void) ble_ll_adv_sm_init(&g_ble_ll_adv_sm[i]); } } + +#endif diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 30a381e1ec..2fb65869ef 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -117,6 +117,11 @@ extern void bletest_completed_pkt(uint16_t handle); * 1) The current connection event has not ended but a schedule item starts */ +/* Global LL connection parameters */ +struct ble_ll_conn_global_params g_ble_ll_conn_params; + +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + /* This is a dummy structure we use for the empty PDU */ struct ble_ll_empty_pdu { @@ -130,18 +135,19 @@ struct ble_ll_empty_pdu #error "Maximum # of connections is 254" #endif +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Global connection complete event. Used when initiating */ uint8_t *g_ble_ll_conn_comp_ev; - -/* Global LL connection parameters */ -struct ble_ll_conn_global_params g_ble_ll_conn_params; +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) /* Global default sync transfer params */ struct ble_ll_conn_sync_transfer_params g_ble_ll_conn_sync_transfer_params; #endif +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) struct ble_ll_conn_create_sm g_ble_ll_conn_create_sm; +#endif /* Pointer to current connection */ struct ble_ll_conn_sm *g_ble_ll_conn_cur_sm; @@ -443,6 +449,7 @@ ble_ll_conn_itvl_to_ticks(uint32_t itvl, uint32_t *itvl_ticks, * * @return uint8_t* */ +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) static uint8_t * ble_ll_init_get_conn_comp_ev(void) { @@ -454,6 +461,7 @@ ble_ll_init_get_conn_comp_ev(void) return evbuf; } +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) /** @@ -701,6 +709,7 @@ ble_ll_conn_start_rx_encrypt(void *arg) !CONN_IS_MASTER(connsm)); } +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) static void ble_ll_conn_start_rx_unencrypt(void *arg) { @@ -710,6 +719,7 @@ ble_ll_conn_start_rx_unencrypt(void *arg) CONN_F_ENCRYPTED(connsm) = 0; ble_phy_encrypt_disable(); } +#endif static void ble_ll_conn_txend_encrypt(void *arg) @@ -721,6 +731,7 @@ ble_ll_conn_txend_encrypt(void *arg) ble_ll_conn_current_sm_over(connsm); } +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) static void ble_ll_conn_rxend_unencrypt(void *arg) { @@ -730,6 +741,7 @@ ble_ll_conn_rxend_unencrypt(void *arg) CONN_F_ENCRYPTED(connsm) = 0; ble_ll_conn_current_sm_over(connsm); } +#endif static void ble_ll_conn_continue_rx_encrypt(void *arg) @@ -978,7 +990,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) * packets can be let go. */ if (nextpkthdr && !ble_ll_ctrl_enc_allowed_pdu_tx(nextpkthdr) - && ((connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) || + && (CONN_IS_MASTER(connsm) || !ble_ll_ctrl_is_start_enc_rsp(m))) { nextpkthdr = NULL; } @@ -1025,7 +1037,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) /* We will allow a next packet if it itself is allowed */ pkthdr = OS_MBUF_PKTHDR(connsm->cur_tx_pdu); if (nextpkthdr && !ble_ll_ctrl_enc_allowed_pdu_tx(nextpkthdr) - && ((connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) || + && (CONN_IS_MASTER(connsm) || !ble_ll_ctrl_is_start_enc_rsp(connsm->cur_tx_pdu))) { nextpkthdr = NULL; } @@ -1094,9 +1106,11 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) ble_ll_pdu_tx_time_get(next_txlen, tx_phy_mode) + ble_ll_pdu_tx_time_get(cur_txlen, tx_phy_mode); +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { ticks += (BLE_LL_IFS + connsm->eff_max_rx_time); } +#endif ticks = os_cputime_usecs_to_ticks(ticks); if (CPUTIME_LT(os_cputime_get32() + ticks, next_event_time)) { @@ -1152,7 +1166,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) * overrun next scheduled item. */ if ((connsm->csmflags.cfbit.terminate_ind_rxd) || - ((connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) && (md == 0) && + (CONN_IS_SLAVE(connsm) && (md == 0) && (connsm->cons_rxd_bad_crc == 0) && ((connsm->last_rxd_hdr_byte & BLE_LL_DATA_HDR_MD_MASK) == 0) && !ble_ll_ctrl_is_terminate_ind(hdr_byte, m->om_data[0]))) { @@ -1205,7 +1219,17 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) * The slave sends the PAUSE_ENC_RSP encrypted. The master sends * it unencrypted (note that link was already set unencrypted). */ - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: + CONN_F_ENCRYPTED(connsm) = 0; + connsm->enc_data.enc_state = CONN_ENC_S_PAUSED; + connsm->enc_data.tx_encrypted = 0; + ble_phy_encrypt_disable(); + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: CONN_F_ENCRYPTED(connsm) = 1; connsm->enc_data.tx_encrypted = 1; ble_phy_encrypt_enable(connsm->enc_data.tx_pkt_cntr, @@ -1217,11 +1241,11 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) } else { txend_func = ble_ll_conn_rxend_unencrypt; } - } else { - CONN_F_ENCRYPTED(connsm) = 0; - connsm->enc_data.enc_state = CONN_ENC_S_PAUSED; - connsm->enc_data.tx_encrypted = 0; - ble_phy_encrypt_disable(); + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } } else { /* If encrypted set packet counter */ @@ -1278,7 +1302,9 @@ static int ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) { int rc; +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) uint32_t usecs; +#endif uint32_t start; struct ble_ll_conn_sm *connsm; @@ -1319,7 +1345,9 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) ble_phy_mode_set(connsm->phy_data.tx_phy_mode, connsm->phy_data.rx_phy_mode); #endif - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: /* Set start time of transmission */ start = sch->start_time + g_ble_ll_sched_offset_ticks; rc = ble_phy_tx_set_start_time(start, sch->remainder); @@ -1345,7 +1373,10 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) STATS_INC(ble_ll_conn_stats, conn_ev_late); rc = BLE_LL_SCHED_STATE_DONE; } - } else { + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) if (CONN_F_ENCRYPTED(connsm)) { ble_phy_encrypt_enable(connsm->enc_data.rx_pkt_cntr, @@ -1401,6 +1432,11 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) /* Set next wakeup time to connection event end time */ rc = BLE_LL_SCHED_STATE_RUNNING; } + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } if (rc == BLE_LL_SCHED_STATE_DONE) { @@ -1432,6 +1468,7 @@ static int ble_ll_conn_can_send_next_pdu(struct ble_ll_conn_sm *connsm, uint32_t begtime, uint32_t add_usecs) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) int rc; uint16_t rem_bytes; uint32_t ticks; @@ -1487,6 +1524,9 @@ ble_ll_conn_can_send_next_pdu(struct ble_ll_conn_sm *connsm, uint32_t begtime, } return rc; +#else + return 1; +#endif } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) @@ -1527,6 +1567,7 @@ ble_ll_conn_auth_pyld_timer_start(struct ble_ll_conn_sm *connsm) } #endif +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) static void ble_ll_conn_master_common_init(struct ble_ll_conn_sm *connsm) { @@ -1588,6 +1629,7 @@ ble_ll_conn_master_init(struct ble_ll_conn_sm *connsm, connsm->min_ce_len = cc_params->min_ce_len; connsm->max_ce_len = cc_params->max_ce_len; } +#endif #if (BLE_LL_BT5_PHY_SUPPORTED == 1) @@ -1643,6 +1685,7 @@ ble_ll_conn_init_phy(struct ble_ll_conn_sm *connsm, int phy) #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) static void ble_ll_conn_create_set_params(struct ble_ll_conn_sm *connsm, uint8_t phy) { @@ -1658,6 +1701,7 @@ ble_ll_conn_create_set_params(struct ble_ll_conn_sm *connsm, uint8_t phy) connsm->conn_itvl_usecs = cc_params->conn_itvl_usecs; } #endif +#endif static void ble_ll_conn_set_csa(struct ble_ll_conn_sm *connsm, bool chsel) @@ -1998,8 +2042,10 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) { uint16_t latency; uint32_t itvl; +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) uint32_t cur_ww; uint32_t max_ww; +#endif struct ble_ll_conn_upd_req *upd; uint32_t ticks; uint32_t usecs; @@ -2012,7 +2058,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) ble_ll_ctrl_terminate_start(connsm); } - if (CONN_F_TERMINATE_STARTED(connsm) && (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE)) { + if (CONN_F_TERMINATE_STARTED(connsm) && CONN_IS_SLAVE(connsm)) { /* Some of the devices waits whole connection interval to ACK our * TERMINATE_IND sent as a Slave. Since we are here it means we are still waiting for ACK. * Make sure we catch it in next connection event. @@ -2072,8 +2118,8 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) /* Set flag so we send connection update event */ upd = &connsm->conn_update_req; - if ((connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) || - ((connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) && + if (CONN_IS_MASTER(connsm) || + (CONN_IS_SLAVE(connsm) && IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ)) || (connsm->conn_itvl != upd->interval) || (connsm->slave_latency != upd->latency) || @@ -2208,6 +2254,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) #else itvl = MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * BLE_LL_SCHED_TICKS_PER_SLOT; #endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { cur_ww = ble_ll_utils_calc_window_widening(connsm->anchor_point, @@ -2221,6 +2268,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) connsm->slave_cur_window_widening = cur_ww; itvl += os_cputime_usecs_to_ticks(cur_ww + connsm->slave_cur_tx_win_usecs); } +#endif itvl -= g_ble_ll_sched_offset_ticks; connsm->ce_end_time = connsm->anchor_point + itvl; @@ -2246,9 +2294,13 @@ static int ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) { int rc; +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) uint8_t *evbuf; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) uint32_t endtime; uint32_t usecs; +#endif /* XXX: TODO this assumes we received in 1M phy */ @@ -2273,6 +2325,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) * the transmit window offset from the end of the connection request. */ rc = 1; +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { /* * With a 32.768 kHz crystal we dont care about the remaining usecs @@ -2334,6 +2387,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) } } } +#endif /* Send connection complete event to inform host of connection */ if (rc) { @@ -2350,9 +2404,9 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) CONN_F_CTRLR_PHY_UPDATE(connsm) = 1; } #endif - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { - ble_ll_adv_send_conn_comp_ev(connsm, rxhdr); - } else { + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: evbuf = ble_ll_init_get_conn_comp_ev(); ble_ll_conn_comp_event_send(connsm, BLE_ERR_SUCCESS, evbuf, NULL); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) @@ -2368,6 +2422,16 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) * if it has some additional features to use. */ ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG); + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: + ble_ll_adv_send_conn_comp_ev(connsm, rxhdr); + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } } @@ -2676,6 +2740,7 @@ ble_ll_conn_event_halt(void) } } +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) int ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu, struct ble_ll_scan_addr_data *addrd, @@ -2793,8 +2858,10 @@ ble_ll_conn_created_on_legacy(struct os_mbuf *rxpdu, ble_ll_conn_master_start(BLE_PHY_1M, csa, addrd, targeta); } +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) void ble_ll_conn_created_on_aux(struct os_mbuf *rxpdu, struct ble_ll_scan_addr_data *addrd, @@ -2814,6 +2881,7 @@ ble_ll_conn_created_on_aux(struct os_mbuf *rxpdu, ble_ll_conn_master_start(phy, 1, addrd, targeta); } +#endif #endif /* BLE_LL_CFG_FEAT_LL_EXT_ADV */ /** @@ -2984,11 +3052,13 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) * If we are a slave, we can only start to use slave latency * once we have received a NESN of 1 from the master */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { if (hdr_byte & BLE_LL_DATA_HDR_NESN_MASK) { connsm->csmflags.cfbit.allow_slave_latency = 1; } } +#endif /* * Discard the received PDU if the sequence number is the same @@ -3172,11 +3242,21 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) if (connsm->cons_rxd_bad_crc >= 2) { reply = 0; } else { - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: reply = CONN_F_LAST_TXD_MD(connsm); - } else { + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: /* A slave always responds with a packet */ reply = 1; + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } } } else { @@ -3290,7 +3370,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) #if (BLE_LL_BT5_PHY_SUPPORTED == 1) if (BLE_LL_LLID_IS_CTRL(hdr_byte) && - (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) && + CONN_IS_SLAVE(connsm) && (opcode == BLE_LL_CTRL_PHY_UPDATE_IND)) { connsm->phy_tx_transition = ble_ll_ctrl_phy_tx_transition_get(rxbuf[3]); @@ -3315,11 +3395,21 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) connsm->rxd_disconnect_reason = rxbuf[3]; } - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: reply = CONN_F_LAST_TXD_MD(connsm) || (hdr_byte & BLE_LL_DATA_HDR_MD_MASK); - } else { + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: /* A slave always replies */ reply = 1; + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } } @@ -3407,9 +3497,11 @@ ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm *connsm, struct os_mbuf *om, lifo = 1; break; case BLE_LL_CTRL_PAUSE_ENC_RSP: +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { lifo = 1; } +#endif break; case BLE_LL_CTRL_ENC_REQ: case BLE_LL_CTRL_ENC_RSP: @@ -3480,7 +3572,7 @@ ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t length) os_mbuf_free_chain(om); } } - +#endif /** * Called to set the global channel mask that we use for all connections. * @@ -3490,7 +3582,9 @@ ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t length) void ble_ll_conn_set_global_chanmap(uint8_t num_used_chans, const uint8_t *chanmap) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) struct ble_ll_conn_sm *connsm; +#endif struct ble_ll_conn_global_params *conn_params; /* Do nothing if same channel map */ @@ -3503,14 +3597,17 @@ ble_ll_conn_set_global_chanmap(uint8_t num_used_chans, const uint8_t *chanmap) conn_params->num_used_chans = num_used_chans; memcpy(conn_params->master_chan_map, chanmap, BLE_LL_CONN_CHMAP_LEN); +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Perform channel map update */ SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) { if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_CHAN_MAP_UPD); } } +#endif } +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /** * Called when a device has received a connect request while advertising and * the connect request has passed the advertising filter policy and is for @@ -3524,6 +3621,7 @@ ble_ll_conn_set_global_chanmap(uint8_t num_used_chans, const uint8_t *chanmap) * * @return 0: connection not started; 1 connecton started */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) int ble_ll_conn_slave_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr, bool force_csa2) @@ -3642,6 +3740,7 @@ ble_ll_conn_slave_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr, STATS_INC(ble_ll_conn_stats, slave_rxd_bad_conn_req_params); return 0; } +#endif #define MAX_TIME_UNCODED(_maxbytes) \ ble_ll_pdu_tx_time_get(_maxbytes + BLE_LL_DATA_MIC_LEN, \ @@ -3672,6 +3771,7 @@ ble_ll_conn_module_reset(void) ble_ll_conn_end(connsm, BLE_ERR_SUCCESS); } +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Free the global connection complete event if there is one */ if (g_ble_ll_conn_comp_ev) { ble_hci_trans_buf_free(g_ble_ll_conn_comp_ev); @@ -3680,6 +3780,7 @@ ble_ll_conn_module_reset(void) /* Reset connection we are attempting to create */ g_ble_ll_conn_create_sm.connsm = NULL; +#endif /* Now go through and end all the connections */ while (1) { @@ -3791,3 +3892,4 @@ ble_ll_conn_module_init(void) /* Call reset to finish reset of initialization */ ble_ll_conn_module_reset(); } +#endif diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 6489af0d5b..2e50713e84 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -34,6 +34,8 @@ #include "controller/ble_ll_adv.h" #include "ble_ll_conn_priv.h" +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + /* * Used to limit the rate at which we send the number of completed packets * event to the host. This is the os time at which we can send an event. @@ -158,7 +160,9 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, enh_ev->peer_addr_type = connsm->peer_addr_type; memcpy(enh_ev->peer_addr, connsm->peer_addr, BLE_DEV_ADDR_LEN); - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: if (connsm->inita_identity_used) { /* We used identity address in CONNECT_IND which can be just * fine if @@ -173,8 +177,16 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, } else { rpa = NULL; } - } else { + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: rpa = ble_ll_adv_get_local_rpa(advsm); + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } if (rpa) { @@ -189,20 +201,33 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, #endif if (enh_ev->peer_addr_type > BLE_HCI_CONN_PEER_ADDR_RANDOM) { - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: rpa = ble_ll_scan_get_peer_rpa(); - } else { + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: rpa = ble_ll_adv_get_peer_rpa(advsm); + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } + memcpy(enh_ev->peer_rpa, rpa, BLE_DEV_ADDR_LEN); } enh_ev->conn_itvl = htole16(connsm->conn_itvl); enh_ev->conn_latency = htole16(connsm->slave_latency); enh_ev->supervision_timeout = htole16(connsm->supervision_tmo); +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { enh_ev->mca = connsm->master_sca; } +#endif } ble_ll_hci_event_send(hci_ev); @@ -227,9 +252,11 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, ev->conn_itvl = htole16(connsm->conn_itvl); ev->conn_latency = htole16(connsm->slave_latency); ev->supervision_timeout = htole16(connsm->supervision_tmo); +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { ev->mca = connsm->master_sca; } +#endif } ble_ll_hci_event_send(hci_ev); @@ -826,10 +853,12 @@ ble_ll_conn_hci_read_rem_features(const uint8_t *cmdbuf, uint8_t len) */ if (!connsm->csmflags.cfbit.rxd_features && !IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG)) { +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if ((connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) && !(ble_ll_read_supp_features() & BLE_LL_FEAT_SLAVE_INIT)) { return BLE_ERR_CMD_DISALLOWED; } +#endif ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG); } @@ -880,9 +909,11 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) /* See if this feature is supported on both sides */ if ((connsm->conn_features & BLE_LL_FEAT_CONN_PARM_REQ) == 0) { +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { return BLE_ERR_UNSUPP_REM_FEATURE; } +#endif ctrl_proc = BLE_LL_CTRL_PROC_CONN_UPDATE; } else { ctrl_proc = BLE_LL_CTRL_PROC_CONN_PARAM_REQ; @@ -895,14 +926,24 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) * slave. */ if (connsm->csmflags.cfbit.awaiting_host_reply) { - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { - return BLE_ERR_LMP_COLLISION; - } else { + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: connsm->csmflags.cfbit.awaiting_host_reply = 0; /* XXX: If this fails no reject ind will be sent! */ ble_ll_ctrl_reject_ind_send(connsm, connsm->host_reply_opcode, BLE_ERR_LMP_COLLISION); + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: + return BLE_ERR_LMP_COLLISION; + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } } @@ -910,11 +951,13 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) * If we are a slave and the master has initiated the channel map * update procedure we should deny the slave request for now. */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->csmflags.cfbit.chanmap_update_scheduled) { if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { return BLE_ERR_DIFF_TRANS_COLL; } } +#endif /* Retrieve command data */ hcu = &connsm->conn_param_req; @@ -1301,6 +1344,7 @@ ble_ll_conn_hci_rd_chan_map(const uint8_t *cmdbuf, uint8_t len, *rsplen = sizeof(*rsp); return rc; } +#endif /** * Called when the host issues the LE command "set host channel classification" @@ -1334,6 +1378,8 @@ ble_ll_conn_hci_set_chan_class(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_SUCCESS; } +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) int ble_ll_conn_hci_set_data_len(const uint8_t *cmdbuf, uint8_t len, @@ -1421,8 +1467,10 @@ ble_ll_conn_hci_le_start_encrypt(const uint8_t *cmdbuf, uint8_t len) connsm = ble_ll_conn_find_active_conn(le16toh(cmd->conn_handle)); if (!connsm) { rc = BLE_ERR_UNK_CONN_ID; +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) } else if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { rc = BLE_ERR_UNSPECIFIED; +#endif } else if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_ENCRYPT) { /* * The specification does not say what to do here but the host should @@ -1475,11 +1523,13 @@ ble_ll_conn_hci_le_ltk_reply(const uint8_t *cmdbuf, uint8_t len, goto ltk_key_cmd_complete; } +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Should never get this if we are a master! */ if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { rc = BLE_ERR_UNSPECIFIED; goto ltk_key_cmd_complete; } +#endif /* The connection should be awaiting a reply. If not, just discard */ if (connsm->enc_data.enc_state != CONN_ENC_S_LTK_REQ_WAIT) { @@ -1532,11 +1582,13 @@ ble_ll_conn_hci_le_ltk_neg_reply(const uint8_t *cmdbuf, uint8_t len, goto ltk_key_cmd_complete; } +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Should never get this if we are a master! */ if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { rc = BLE_ERR_UNSPECIFIED; goto ltk_key_cmd_complete; } +#endif /* The connection should be awaiting a reply. If not, just discard */ if (connsm->enc_data.enc_state != CONN_ENC_S_LTK_REQ_WAIT) { @@ -1916,3 +1968,4 @@ ble_ll_set_default_sync_transfer_params(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_SUCCESS; } #endif +#endif diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index d1a4a3e884..73e4106074 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -64,6 +64,7 @@ struct ble_ll_conn_global_params { uint8_t master_chan_map[BLE_LL_CONN_CHMAP_LEN]; uint8_t num_used_chans; +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) uint8_t supp_max_tx_octets; uint8_t supp_max_rx_octets; uint8_t conn_init_max_tx_octets; @@ -74,6 +75,7 @@ struct ble_ll_conn_global_params uint16_t conn_init_max_tx_time_coded; uint16_t supp_max_tx_time; uint16_t supp_max_rx_time; +#endif }; extern struct ble_ll_conn_global_params g_ble_ll_conn_params; diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 94d73a9bb5..432045e675 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -31,6 +31,8 @@ #include "controller/ble_ll_sync.h" #include "ble_ll_conn_priv.h" +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + /* To use spec sample data for testing */ #undef BLE_LL_ENCRYPT_USE_TEST_DATA @@ -314,8 +316,7 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * update the connection parameters. This means that the previous * check is all we need for a master (when receiving a request). */ - if ((connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) || - (opcode == BLE_LL_CTRL_CONN_PARM_RSP)) { + if (CONN_IS_SLAVE(connsm) || (opcode == BLE_LL_CTRL_CONN_PARM_RSP)) { /* * Not sure what to do about the slave. It is possible that the * current connection parameters are not the same ones as the local host @@ -488,11 +489,13 @@ ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t * break; case BLE_LL_CTRL_CONN_PARM_REQ: BLE_LL_CONN_CLEAR_FEATURE(connsm, BLE_LL_FEAT_CONN_PARM_REQ); +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { ble_ll_ctrl_conn_upd_make(connsm, rspdata, NULL); connsm->reject_reason = BLE_ERR_SUCCESS; return BLE_LL_CTRL_CONN_UPDATE_IND; } +#endif /* note: fall-through intentional */ case BLE_LL_CTRL_CONN_PARM_RSP: ctrl_proc = BLE_LL_CTRL_PROC_CONN_PARAM_REQ; @@ -674,6 +677,7 @@ ble_ll_ctrl_phy_update_proc_complete(struct ble_ll_conn_sm *connsm) } } +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /** * * There is probably a better way for the controller to choose which PHY use. @@ -713,6 +717,7 @@ ble_ll_ctrl_find_new_phy(uint8_t phy_mask_prefs) * @param ctrdata: Pointer to where CtrData of UPDATE_IND pdu starts * @param slave_req flag denoting if slave requested this. 0: no 1:yes */ + static void ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t *ctrdata, int slave_req) @@ -729,10 +734,12 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, rx_phys = dptr[1]; /* If we are master, check if slave requested symmetric PHY */ +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { is_slave_sym = tx_phys == rx_phys; is_slave_sym &= __builtin_popcount(tx_phys) == 1; } +#endif /* Get m_to_s and s_to_m masks */ if (slave_req) { @@ -818,6 +825,7 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, ctrdata[1] = s_to_m; put_le16(ctrdata + 2, instant); } +#endif /** * Create a LL_PHY_REQ or LL_PHY_RSP pdu @@ -872,7 +880,9 @@ ble_ll_ctrl_rx_phy_req(struct ble_ll_conn_sm *connsm, uint8_t *req, err = ble_ll_ctrl_proc_with_instant_initiated(connsm, BLE_LL_CTRL_PROC_PHY_UPDATE); - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: if (err) { ble_ll_ctrl_rej_ext_ind_make(BLE_LL_CTRL_PHY_REQ, err, rsp); rsp_opcode = BLE_LL_CTRL_REJECT_IND_EXT; @@ -885,7 +895,10 @@ ble_ll_ctrl_rx_phy_req(struct ble_ll_conn_sm *connsm, uint8_t *req, ble_ll_ctrl_phy_update_ind_make(connsm, req, rsp, 1); rsp_opcode = BLE_LL_CTRL_PHY_UPDATE_IND; } - } else { + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: /* XXX: deal with other control procedures that we need to stop */ if (err) { if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_PHY_UPDATE) { @@ -913,7 +926,13 @@ ble_ll_ctrl_rx_phy_req(struct ble_ll_conn_sm *connsm, uint8_t *req, /* Start response timer */ connsm->cur_ctrl_proc = BLE_LL_CTRL_PROC_PHY_UPDATE; ble_ll_ctrl_start_rsp_timer(connsm); + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } + return rsp_opcode; } @@ -933,7 +952,10 @@ ble_ll_ctrl_rx_phy_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t rsp_opcode; rsp_opcode = BLE_ERR_MAX; - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_PHY_UPDATE) { ble_ll_ctrl_phy_update_ind_make(connsm, dptr, rsp, 0); ble_npl_callout_stop(&connsm->ctrl_proc_rsp_timer); @@ -946,8 +968,16 @@ ble_ll_ctrl_rx_phy_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * * XXX: TODO count some stat? */ - } else { + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: rsp_opcode = BLE_LL_CTRL_UNKNOWN_RSP; + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } /* NOTE: slave should never receive one of these */ @@ -976,9 +1006,11 @@ ble_ll_ctrl_rx_phy_update_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr) uint16_t instant; uint16_t delta; +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { return BLE_LL_CTRL_UNKNOWN_RSP; } +#endif /* * Reception stops the procedure response timer but does not @@ -1434,9 +1466,11 @@ static uint8_t ble_ll_ctrl_rx_enc_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t *rspdata) { - if (connsm->conn_role != BLE_LL_CONN_ROLE_SLAVE) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { return BLE_LL_CTRL_UNKNOWN_RSP; } +#endif connsm->enc_data.enc_state = CONN_ENC_S_ENC_RSP_TO_BE_SENT; @@ -1479,15 +1513,27 @@ ble_ll_ctrl_rx_start_enc_req(struct ble_ll_conn_sm *connsm) /* Only master should receive start enc request */ rc = BLE_ERR_MAX; - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: /* We only want to send a START_ENC_RSP if we havent yet */ if (connsm->enc_data.enc_state == CONN_ENC_S_START_ENC_REQ_WAIT) { connsm->enc_data.enc_state = CONN_ENC_S_START_ENC_RSP_WAIT; rc = BLE_LL_CTRL_START_ENC_RSP; } - } else { + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: rc = BLE_LL_CTRL_UNKNOWN_RSP; + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } + return rc; } @@ -1502,7 +1548,7 @@ ble_ll_ctrl_rx_pause_enc_req(struct ble_ll_conn_sm *connsm) * ignore it... */ rc = BLE_ERR_MAX; - if ((connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) && + if (CONN_IS_SLAVE(connsm) && (connsm->enc_data.enc_state == CONN_ENC_S_ENCRYPTED)) { rc = BLE_LL_CTRL_PAUSE_ENC_RSP; } else { @@ -1525,16 +1571,28 @@ ble_ll_ctrl_rx_pause_enc_rsp(struct ble_ll_conn_sm *connsm) { int rc; - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: rc = BLE_LL_CTRL_PAUSE_ENC_RSP; - } else if (connsm->enc_data.enc_state == CONN_ENC_S_PAUSE_ENC_RSP_WAIT) { - /* Master sends back unencrypted LL_PAUSE_ENC_RSP. - * From this moment encryption is paused. - */ - rc = BLE_ERR_MAX; - connsm->enc_data.enc_state = CONN_ENC_S_PAUSED; - } else { - rc = BLE_LL_CTRL_UNKNOWN_RSP; + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: + if (connsm->enc_data.enc_state == CONN_ENC_S_PAUSE_ENC_RSP_WAIT) { + /* Master sends back unencrypted LL_PAUSE_ENC_RSP. + * From this moment encryption is paused. + */ + rc = BLE_ERR_MAX; + connsm->enc_data.enc_state = CONN_ENC_S_PAUSED; + } else { + rc = BLE_LL_CTRL_UNKNOWN_RSP; + } + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } return rc; @@ -1559,9 +1617,9 @@ ble_ll_ctrl_rx_start_enc_rsp(struct ble_ll_conn_sm *connsm) return BLE_ERR_MAX; } - /* If master, we are done. Stop control procedure and sent event to host */ - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { - + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_ENCRYPT); /* We are encrypted */ @@ -1570,7 +1628,10 @@ ble_ll_ctrl_rx_start_enc_rsp(struct ble_ll_conn_sm *connsm) ble_ll_conn_auth_pyld_timer_start(connsm); #endif rc = BLE_ERR_MAX; - } else { + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: /* Procedure has completed but slave needs to send START_ENC_RSP */ rc = BLE_LL_CTRL_START_ENC_RSP; @@ -1578,6 +1639,11 @@ ble_ll_ctrl_rx_start_enc_rsp(struct ble_ll_conn_sm *connsm) if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_ENCRYPT) { ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_ENCRYPT); } + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } /* @@ -1692,14 +1758,24 @@ ble_ll_ctrl_conn_param_reply(struct ble_ll_conn_sm *connsm, uint8_t *rsp, { uint8_t rsp_opcode; - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { - /* Create a connection parameter response */ - ble_ll_ctrl_conn_param_pdu_make(connsm, rsp + 1, req); - rsp_opcode = BLE_LL_CTRL_CONN_PARM_RSP; - } else { + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: /* Create a connection update pdu */ ble_ll_ctrl_conn_upd_make(connsm, rsp + 1, req); rsp_opcode = BLE_LL_CTRL_CONN_UPDATE_IND; + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: + /* Create a connection parameter response */ + ble_ll_ctrl_conn_param_pdu_make(connsm, rsp + 1, req); + rsp_opcode = BLE_LL_CTRL_CONN_PARM_RSP; + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } return rsp_opcode; @@ -1732,14 +1808,24 @@ ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, switch (connsm->cur_ctrl_proc) { case BLE_LL_CTRL_PROC_CONN_PARAM_REQ: if (opcode == BLE_LL_CTRL_REJECT_IND_EXT) { - /* As a master we should send connection update indication in this point */ - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + switch (connsm->conn_role) { + #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: + /* As a master we should send connection update indication in this point */ rsp_opcode = BLE_LL_CTRL_CONN_UPDATE_IND; ble_ll_ctrl_conn_upd_make(connsm, rspdata, NULL); connsm->reject_reason = BLE_ERR_SUCCESS; - } else { + break; + #endif + #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ); ble_ll_hci_ev_conn_update(connsm, ble_error); + break; + #endif + default: + BLE_LL_ASSERT(0); + break; } } break; @@ -1792,9 +1878,11 @@ ble_ll_ctrl_rx_conn_update(struct ble_ll_conn_sm *connsm, uint8_t *dptr) struct ble_ll_conn_upd_req *reqdata; /* Only a slave should receive this */ +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { return BLE_LL_CTRL_UNKNOWN_RSP; } +#endif /* Retrieve parameters */ reqdata = &connsm->conn_update_req; @@ -1913,12 +2001,12 @@ ble_ll_ctrl_rx_feature_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * requests if we are a slave. */ if (opcode == BLE_LL_CTRL_SLAVE_FEATURE_REQ) { - if (connsm->conn_role != BLE_LL_CONN_ROLE_MASTER) { + if (!CONN_IS_MASTER(connsm)) { return BLE_LL_CTRL_UNKNOWN_RSP; } } else { /* XXX: not sure this is correct but do it anyway */ - if (connsm->conn_role != BLE_LL_CONN_ROLE_SLAVE) { + if (!CONN_IS_SLAVE(connsm)) { return BLE_LL_CTRL_UNKNOWN_RSP; } } @@ -2018,15 +2106,24 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * transaction collision error code. */ if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ)) { - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { - ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ); - ble_ll_hci_ev_conn_update(connsm, BLE_ERR_LMP_COLLISION); - } else { + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: /* The master sends reject ind ext w/error code 0x23 */ rsp_opcode = BLE_LL_CTRL_REJECT_IND_EXT; rspbuf[1] = BLE_LL_CTRL_CONN_PARM_REQ; rspbuf[2] = BLE_ERR_LMP_COLLISION; return rsp_opcode; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: + ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ); + ble_ll_hci_ev_conn_update(connsm, BLE_ERR_LMP_COLLISION); + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } } @@ -2034,6 +2131,7 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * If we are a master and we currently performing a channel map * update procedure we need to return an error */ +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if ((connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) && (connsm->csmflags.cfbit.chanmap_update_scheduled)) { rsp_opcode = BLE_LL_CTRL_REJECT_IND_EXT; @@ -2041,6 +2139,7 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, rspbuf[2] = BLE_ERR_DIFF_TRANS_COLL; return rsp_opcode; } +#endif /* Process the received connection parameter request */ rsp_opcode = ble_ll_ctrl_conn_param_pdu_proc(connsm, dptr, rspbuf, @@ -2055,9 +2154,11 @@ ble_ll_ctrl_rx_conn_param_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t rsp_opcode; /* A slave should never receive this response */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { return BLE_LL_CTRL_UNKNOWN_RSP; } +#endif /* * This case should never happen! It means that the slave initiated a @@ -2131,9 +2232,11 @@ ble_ll_ctrl_rx_chanmap_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr) uint16_t instant; uint16_t conn_events; +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { return BLE_LL_CTRL_UNKNOWN_RSP; } +#endif /* If instant is in the past, we have to end the connection */ instant = get_le16(dptr + BLE_LL_CONN_CHMAP_LEN); @@ -2188,10 +2291,20 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc) ble_ll_ctrl_chanmap_req_make(connsm, ctrdata); break; case BLE_LL_CTRL_PROC_FEATURE_XCHG: - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: opcode = BLE_LL_CTRL_FEATURE_REQ; - } else { + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: opcode = BLE_LL_CTRL_SLAVE_FEATURE_REQ; + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } put_le64(ctrdata, ble_ll_read_supp_features()); break; @@ -2849,6 +2962,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) connsm->enc_data.enc_state = CONN_ENC_S_LTK_REQ_WAIT; connsm->csmflags.cfbit.send_ltk_req = 1; break; +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_CTRL_START_ENC_RSP: if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { connsm->enc_data.enc_state = CONN_ENC_S_ENCRYPTED; @@ -2863,7 +2977,9 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) } break; #endif +#endif #if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_CTRL_PHY_REQ: if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { connsm->phy_tx_transition = @@ -2871,6 +2987,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) connsm->phy_data.req_pref_tx_phys_mask); } break; +#endif case BLE_LL_CTRL_PHY_UPDATE_IND: connsm->phy_tx_transition = ble_ll_ctrl_phy_tx_transition_get(txpdu->om_data[2]); @@ -2890,3 +3007,4 @@ ble_ll_ctrl_init_conn_sm(struct ble_ll_conn_sm *connsm) ble_npl_callout_init(&connsm->ctrl_proc_rsp_timer, &g_ble_ll_data.ll_evq, ble_ll_ctrl_proc_rsp_timer_cb, connsm); } +#endif diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 7bbc6774c5..d368672914 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -322,8 +322,14 @@ ble_ll_hci_le_read_bufsize(uint8_t *rspbuf, uint8_t *rsplen) { struct ble_hci_le_rd_buf_size_rp *rp = (void *) rspbuf; +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) rp->data_len = htole16(g_ble_ll_data.ll_acl_pkt_size); rp->data_packets = g_ble_ll_data.ll_num_acl_pkts; +#else + /* TODO check if can just not support this command */ + rp->data_len = 0; + rp->data_packets = 0; +#endif *rsplen = sizeof(*rp); return BLE_ERR_SUCCESS; @@ -410,6 +416,7 @@ ble_ll_hci_chk_phy_masks(uint8_t all_phys, uint8_t tx_phys, uint8_t rx_phys, * * @return int */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) static int ble_ll_hci_le_set_def_phy(const uint8_t *cmdbuf, uint8_t len) { @@ -426,6 +433,7 @@ ble_ll_hci_le_set_def_phy(const uint8_t *cmdbuf, uint8_t len) return rc; } #endif +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) /** @@ -658,6 +666,7 @@ ble_ll_hci_le_cmd_send_cmd_status(uint16_t ocf) } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) /** HCI LE read maximum advertising data length command. Returns the controllers * max supported advertising data length; * @@ -695,6 +704,7 @@ ble_ll_adv_rd_sup_adv_sets(uint8_t *rspbuf, uint8_t *rsplen) *rsplen = sizeof(*rsp); return BLE_ERR_SUCCESS; } +#endif static bool ble_ll_is_valid_adv_mode(uint8_t ocf) @@ -887,6 +897,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, rc = ble_ll_set_random_addr(cmdbuf, len, false); #endif break; +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) case BLE_HCI_OCF_LE_SET_ADV_PARAMS: rc = ble_ll_adv_set_adv_params(cmdbuf, len); break; @@ -904,12 +915,15 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, case BLE_HCI_OCF_LE_SET_ADV_ENABLE: rc = ble_ll_hci_adv_set_enable(cmdbuf, len); break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) case BLE_HCI_OCF_LE_SET_SCAN_PARAMS: rc = ble_ll_scan_hci_set_params(cmdbuf, len); break; case BLE_HCI_OCF_LE_SET_SCAN_ENABLE: rc = ble_ll_scan_hci_set_enable(cmdbuf, len); break; +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_HCI_OCF_LE_CREATE_CONN: rc = ble_ll_conn_hci_create(cmdbuf, len); break; @@ -918,6 +932,8 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, rc = ble_ll_conn_create_cancel(cb); } break; +#endif +#endif case BLE_HCI_OCF_LE_RD_WHITE_LIST_SIZE: if (len == 0) { rc = ble_ll_whitelist_read_size(rspbuf, rsplen); @@ -934,18 +950,22 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, case BLE_HCI_OCF_LE_RMV_WHITE_LIST: rc = ble_ll_whitelist_rmv(cmdbuf, len); break; +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_HCI_OCF_LE_CONN_UPDATE: rc = ble_ll_conn_hci_update(cmdbuf, len); break; +#endif case BLE_HCI_OCF_LE_SET_HOST_CHAN_CLASS: rc = ble_ll_conn_hci_set_chan_class(cmdbuf, len); break; +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_HCI_OCF_LE_RD_CHAN_MAP: rc = ble_ll_conn_hci_rd_chan_map(cmdbuf, len, rspbuf, rsplen); break; case BLE_HCI_OCF_LE_RD_REM_FEAT: rc = ble_ll_conn_hci_read_rem_features(cmdbuf, len); break; +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) case BLE_HCI_OCF_LE_ENCRYPT: rc = ble_ll_hci_le_encrypt(cmdbuf, len, rspbuf, rsplen); @@ -957,15 +977,19 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, } break; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_HCI_OCF_LE_START_ENCRYPT: rc = ble_ll_conn_hci_le_start_encrypt(cmdbuf, len); break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_HCI_OCF_LE_LT_KEY_REQ_REPLY: rc = ble_ll_conn_hci_le_ltk_reply(cmdbuf, len, rspbuf, rsplen); break; case BLE_HCI_OCF_LE_LT_KEY_REQ_NEG_REPLY: rc = ble_ll_conn_hci_le_ltk_neg_reply(cmdbuf, len, rspbuf, rsplen); break; +#endif #endif case BLE_HCI_OCF_LE_RD_SUPP_STATES : if (len == 0) { @@ -985,12 +1009,14 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, } break; #endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_HCI_OCF_LE_REM_CONN_PARAM_RR: rc = ble_ll_conn_hci_param_rr(cmdbuf, len, rspbuf, rsplen); break; case BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR: rc = ble_ll_conn_hci_param_nrr(cmdbuf, len, rspbuf, rsplen); break; +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) case BLE_HCI_OCF_LE_SET_DATA_LEN: rc = ble_ll_conn_hci_set_data_len(cmdbuf, len, rspbuf, rsplen); @@ -1042,6 +1068,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, break; #endif #if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_HCI_OCF_LE_RD_PHY: rc = ble_ll_conn_hci_le_rd_phy(cmdbuf, len, rspbuf, rsplen); break; @@ -1052,6 +1079,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, rc = ble_ll_conn_hci_le_set_phy(cmdbuf, len); break; #endif +#endif #if MYNEWT_VAL(BLE_LL_DTM) case BLE_HCI_OCF_LE_RX_TEST_V2: rc = ble_ll_hci_dtm_rx_test_v2(cmdbuf, len); @@ -1060,6 +1088,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, rc = ble_ll_hci_dtm_tx_test_v2(cmdbuf, len); break; #endif +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) case BLE_HCI_OCF_LE_SET_ADV_SET_RND_ADDR: rc = ble_ll_adv_hci_set_random_addr(cmdbuf, len); @@ -1106,6 +1135,8 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, break; #endif #endif +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) case BLE_HCI_OCF_LE_SET_EXT_SCAN_PARAM: rc = ble_ll_scan_hci_set_ext_params(cmdbuf, len); @@ -1113,10 +1144,12 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, case BLE_HCI_OCF_LE_SET_EXT_SCAN_ENABLE: rc = ble_ll_scan_hci_set_ext_enable(cmdbuf, len); break; +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_HCI_OCF_LE_EXT_CREATE_CONN: rc = ble_ll_conn_hci_ext_create(cmdbuf, len); break; #endif +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) case BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC: rc = ble_ll_sync_create(cmdbuf, len); @@ -1150,6 +1183,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, rc = ble_ll_sync_receive_enable(cmdbuf, len); break; #endif +#endif #endif case BLE_HCI_OCF_LE_RD_TRANSMIT_POWER: if (len == 0) { @@ -1170,12 +1204,16 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, break; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) case BLE_HCI_OCF_LE_PERIODIC_ADV_SYNC_TRANSFER: rc = ble_ll_sync_transfer(cmdbuf, len, rspbuf, rsplen); break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) case BLE_HCI_OCF_LE_PERIODIC_ADV_SET_INFO_TRANSFER: rc = ble_ll_adv_periodic_set_info_transfer(cmdbuf, len, rspbuf, rsplen); break; +#endif case BLE_HCI_OCF_LE_PERIODIC_ADV_SYNC_TRANSFER_PARAMS: rc = ble_ll_set_sync_transfer_params(cmdbuf, len, rspbuf, rsplen); break; @@ -1274,6 +1312,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, return rc; } +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) static int ble_ll_hci_disconnect(const uint8_t *cmdbuf, uint8_t len) { @@ -1293,6 +1332,7 @@ ble_ll_hci_disconnect(const uint8_t *cmdbuf, uint8_t len) return ble_ll_conn_hci_disconnect_cmd(cmd); } +#endif /** * Process a link control command sent from the host to the controller. The HCI @@ -1313,18 +1353,18 @@ ble_ll_hci_link_ctrl_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf) int rc; switch (ocf) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_HCI_OCF_DISCONNECT_CMD: rc = ble_ll_hci_disconnect(cmdbuf, len); /* Send command status instead of command complete */ rc += (BLE_ERR_MAX + 1); break; - case BLE_HCI_OCF_RD_REM_VER_INFO: rc = ble_ll_conn_hci_rd_rem_ver_cmd(cmdbuf, len); /* Send command status instead of command complete */ rc += (BLE_ERR_MAX + 1); break; - +#endif default: rc = BLE_ERR_UNKNOWN_HCI_CMD; break; @@ -1518,9 +1558,11 @@ ble_ll_hci_status_params_cmd_proc(const uint8_t *cmdbuf, uint8_t len, int rc; switch (ocf) { +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_HCI_OCF_RD_RSSI: rc = ble_ll_conn_hci_rd_rssi(cmdbuf, len, rspbuf, rsplen); break; +#endif default: rc = BLE_ERR_UNKNOWN_HCI_CMD; break; @@ -1705,7 +1747,12 @@ ble_ll_hci_cmd_rx(uint8_t *cmdbuf, void *arg) int ble_ll_hci_acl_rx(struct os_mbuf *om, void *arg) { +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) ble_ll_acl_data_in(om); +#else + /* host should never send ACL in that case but if it does just ignore it */ + os_mbuf_free_chain(om); +#endif return 0; } diff --git a/nimble/controller/src/ble_ll_resolv.c b/nimble/controller/src/ble_ll_resolv.c index f85e26a8ad..86f8ea7830 100644 --- a/nimble/controller/src/ble_ll_resolv.c +++ b/nimble/controller/src/ble_ll_resolv.c @@ -50,14 +50,31 @@ struct ble_ll_resolv_entry g_ble_ll_resolv_list[MYNEWT_VAL(BLE_LL_RESOLV_LIST_SI static int ble_ll_is_controller_busy(void) { -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) if (ble_ll_sync_enabled()) { return 1; } #endif - return ble_ll_adv_enabled() || ble_ll_scan_enabled() || - g_ble_ll_conn_create_sm.connsm; +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) + if (ble_ll_adv_enabled()) { + return 1; + } +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) + if (ble_ll_scan_enabled()) { + return 1; + } +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + if (g_ble_ll_conn_create_sm.connsm) { + return 1; + } +#endif + + return 0; } /** * Called to determine if a change is allowed to the resolving list at this @@ -155,7 +172,9 @@ ble_ll_resolv_rpa_timer_cb(struct ble_npl_event *ev) ble_npl_callout_reset(&g_ble_ll_resolv_data.rpa_timer, g_ble_ll_resolv_data.rpa_tmo); +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) ble_ll_adv_rpa_timeout(); +#endif } /** diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 6e78f3245d..987ab463ff 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -43,6 +43,8 @@ #include "controller/ble_ll_sync.h" #include "ble_ll_conn_priv.h" +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) + /* * XXX: * 1) I think I can guarantee that we dont process things out of order if @@ -879,7 +881,9 @@ ble_ll_scan_sm_stop(int chk_disable) OS_ENTER_CRITICAL(sr); +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) scansm->connsm = NULL; +#endif /* Disable scanning state machine */ scansm->scan_enabled = 0; @@ -1087,12 +1091,20 @@ ble_ll_scan_event_proc(struct ble_npl_event *ev) */ start_scan = inside_window; switch (ble_ll_state_get()) { +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) case BLE_LL_STATE_ADV: +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_STATE_CONNECTION: +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) case BLE_LL_STATE_SYNC: +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) case BLE_LL_STATE_SCAN_AUX: start_scan = false; break; +#endif case BLE_LL_STATE_SCANNING: /* Must disable PHY since we will move to a new channel */ ble_phy_disable(); @@ -1184,6 +1196,7 @@ ble_ll_scan_rx_isr_start(uint8_t pdu_type, uint16_t *rxflags) } break; #endif +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_SCAN_TYPE_INITIATE: if ((pdu_type == BLE_ADV_PDU_TYPE_ADV_IND) || (pdu_type == BLE_ADV_PDU_TYPE_ADV_DIRECT_IND)) { @@ -1197,6 +1210,7 @@ ble_ll_scan_rx_isr_start(uint8_t pdu_type, uint16_t *rxflags) } #endif break; +#endif default: break; } @@ -1342,6 +1356,7 @@ ble_ll_scan_rx_filter(uint8_t own_addr_type, uint8_t scan_filt_policy, return 0; } +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) int ble_ll_scan_rx_check_init(struct ble_ll_scan_addr_data *addrd) { @@ -1364,6 +1379,7 @@ ble_ll_scan_rx_check_init(struct ble_ll_scan_addr_data *addrd) return 0; } +#endif static int ble_ll_scan_rx_isr_end_on_adv(uint8_t pdu_type, uint8_t *rxbuf, @@ -1388,6 +1404,7 @@ ble_ll_scan_rx_isr_end_on_adv(uint8_t pdu_type, uint8_t *rxbuf, return 0; } +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if ((scanp->scan_type == BLE_SCAN_TYPE_INITIATE) && !(scansm->scan_filt_policy & 0x01)) { rc = ble_ll_scan_rx_check_init(addrd); @@ -1395,6 +1412,7 @@ ble_ll_scan_rx_isr_end_on_adv(uint8_t pdu_type, uint8_t *rxbuf, return 0; } } +#endif rxinfo->flags |= BLE_MBUF_HDR_F_DEVMATCH; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) @@ -1415,10 +1433,19 @@ ble_ll_scan_rx_isr_end_on_adv(uint8_t pdu_type, uint8_t *rxbuf, /* Allow responding to all PDUs when initiating since unwanted PDUs were * already filtered out in isr_start. */ - return ((scanp->scan_type == BLE_SCAN_TYPE_ACTIVE) && - ((pdu_type == BLE_ADV_PDU_TYPE_ADV_IND) || - (pdu_type == BLE_ADV_PDU_TYPE_ADV_SCAN_IND))) || - (scanp->scan_type == BLE_SCAN_TYPE_INITIATE); + if ((scanp->scan_type == BLE_SCAN_TYPE_ACTIVE) && + ((pdu_type == BLE_ADV_PDU_TYPE_ADV_IND) || + (pdu_type == BLE_ADV_PDU_TYPE_ADV_SCAN_IND))) { + return 1; + } + +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + if (scanp->scan_type == BLE_SCAN_TYPE_INITIATE) { + return 1; + } +#endif + + return 0; } static int @@ -1599,12 +1626,14 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) return 0; } break; +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_SCAN_TYPE_INITIATE: if (ble_ll_conn_send_connect_req(rxpdu, &addrd, 0) == 0) { hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CONNECT_IND_TXD; return 0; } break; +#endif } } @@ -1924,14 +1953,15 @@ ble_ll_scan_rx_pkt_in_on_legacy(uint8_t pdu_type, struct os_mbuf *om, void ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hdr) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) struct ble_mbuf_hdr_rxinfo *rxinfo; + uint8_t *targeta; +#endif struct ble_ll_scan_sm *scansm; struct ble_ll_scan_addr_data addrd; - uint8_t *targeta; uint8_t max_pdu_type; scansm = &g_ble_ll_scan_sm; - rxinfo = &hdr->rxinfo; /* Ignore PDUs we do not expect here */ max_pdu_type = BLE_ADV_PDU_TYPE_ADV_SCAN_IND; @@ -1954,7 +1984,10 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd } #endif - if (scansm->scanp->scan_type == BLE_SCAN_TYPE_INITIATE) { + switch (scansm->scanp->scan_type) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_SCAN_TYPE_INITIATE: + rxinfo = &hdr->rxinfo; if (rxinfo->flags & BLE_MBUF_HDR_F_CONNECT_IND_TXD) { /* We need to keep original TargetA in case it was resolved, so rl * can be updated properly. @@ -1967,8 +2000,11 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd ble_ll_conn_created_on_legacy(om, &addrd, targeta); return; } - } else { + break; +#endif + default: ble_ll_scan_rx_pkt_in_on_legacy(ptype, om, hdr, &addrd); + break; } ble_ll_scan_chk_resume(); @@ -2290,6 +2326,7 @@ ble_ll_scan_set_enable(uint8_t enable, uint8_t filter_dups, uint16_t period, /* if already enable we just need to update parameters */ if (scansm->scan_enabled) { /* Controller does not allow initiating and scanning.*/ +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) { scanp_phy = &scansm->scan_phys[i]; if (scanp_phy->configured && @@ -2297,6 +2334,7 @@ ble_ll_scan_set_enable(uint8_t enable, uint8_t filter_dups, uint16_t period, return BLE_ERR_CMD_DISALLOWED; } } +#endif #if MYNEWT_VAL(BLE_LL_NUM_SCAN_DUP_ADVS) /* update filter policy */ @@ -2426,6 +2464,7 @@ ble_ll_scan_can_chg_whitelist(void) return rc; } +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) int ble_ll_scan_initiator_start(struct ble_ll_conn_sm *connsm, uint8_t ext, struct ble_ll_conn_create_scan *cc_scan) @@ -2504,6 +2543,7 @@ ble_ll_scan_initiator_start(struct ble_ll_conn_sm *connsm, uint8_t ext, return rc; } +#endif /** * Checks to see if the scanner is enabled. @@ -2679,3 +2719,5 @@ ble_ll_scan_init(void) ble_ll_scan_aux_init(); #endif } + +#endif diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index f1e56bd3eb..69ab10cde9 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -19,7 +19,7 @@ #include -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) && MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) #include #include @@ -670,9 +670,11 @@ ble_ll_scan_aux_break_ev(struct ble_npl_event *ev) void ble_ll_scan_aux_break(struct ble_ll_scan_aux_data *aux) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (aux->flags & BLE_LL_SCAN_AUX_F_W4_CONNECT_RSP) { ble_ll_conn_send_connect_req_cancel(); } +#endif ble_npl_event_init(&aux->break_ev, ble_ll_scan_aux_break_ev, aux); ble_ll_event_send(&aux->break_ev); @@ -1069,9 +1071,11 @@ ble_ll_scan_aux_rx_isr_end_on_ext(struct ble_ll_scan_sm *scansm, aux->adi = adi; aux->flags |= BLE_LL_SCAN_AUX_F_HAS_ADI; +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (aux->scan_type == BLE_SCAN_TYPE_INITIATE) { aux->flags |= BLE_LL_SCAN_AUX_F_CONNECTABLE; } +#endif if (do_match) { aux->flags |= BLE_LL_SCAN_AUX_F_MATCHED; @@ -1304,6 +1308,7 @@ ble_ll_scan_aux_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) goto done; } +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if ((aux->scan_type == BLE_SCAN_TYPE_INITIATE) && !(scan_filt_policy & 0x01)) { rc = ble_ll_scan_rx_check_init(&addrd); @@ -1312,6 +1317,7 @@ ble_ll_scan_aux_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) goto done; } } +#endif aux->flags |= BLE_LL_SCAN_AUX_F_MATCHED; @@ -1330,6 +1336,7 @@ ble_ll_scan_aux_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) return 0; } break; +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_SCAN_TYPE_INITIATE: if (ble_ll_conn_send_connect_req(rxpdu, &addrd, 1) == 0) { /* AUX_CONNECT_REQ sent, keep PHY enabled to continue */ @@ -1341,6 +1348,9 @@ ble_ll_scan_aux_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) rxinfo->flags |= BLE_MBUF_HDR_F_IGNORED; } break; +#endif + default: + break; } done: @@ -1456,7 +1466,7 @@ ble_ll_scan_aux_sync_check(struct os_mbuf *rxpdu, } #endif - +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) static int ble_ll_scan_aux_check_connect_rsp(uint8_t *rxbuf, struct ble_ll_scan_pdu_data *pdu_data, @@ -1586,6 +1596,7 @@ ble_ll_scan_aux_rx_pkt_in_for_initiator(struct os_mbuf *rxpdu, } ble_ll_scan_aux_free(aux); } +#endif void ble_ll_scan_aux_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr) @@ -1604,10 +1615,12 @@ ble_ll_scan_aux_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr) BLE_LL_ASSERT(aux); +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (aux->scan_type == BLE_SCAN_TYPE_INITIATE) { ble_ll_scan_aux_rx_pkt_in_for_initiator(rxpdu, rxhdr); return; } +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) sync_check = ble_ll_sync_enabled() && @@ -1745,4 +1758,4 @@ ble_ll_scan_aux_init(void) BLE_LL_ASSERT(err == 0); } -#endif /* BLE_LL_CFG_FEAT_LL_EXT_ADV */ \ No newline at end of file +#endif /* BLE_LL_CFG_FEAT_LL_EXT_ADV */ diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 0a9be9c8ae..fe47dbc620 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -112,7 +112,9 @@ ble_ll_sched_preempt(struct ble_ll_sched_item *sch, { struct ble_ll_sched_item *entry; struct ble_ll_sched_item *next; +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) struct ble_ll_conn_sm *connsm; +#endif entry = first; @@ -123,25 +125,33 @@ ble_ll_sched_preempt(struct ble_ll_sched_item *sch, entry->enqueued = 0; switch (entry->sched_type) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_SCHED_TYPE_CONN: connsm = (struct ble_ll_conn_sm *)entry->cb_arg; ble_ll_event_send(&connsm->conn_ev_end); break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) case BLE_LL_SCHED_TYPE_ADV: ble_ll_adv_event_rmvd_from_sched(entry->cb_arg); break; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) case BLE_LL_SCHED_TYPE_SCAN_AUX: ble_ll_scan_aux_break(entry->cb_arg); break; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) case BLE_LL_SCHED_TYPE_PERIODIC: ble_ll_adv_periodic_rmvd_from_sched(entry->cb_arg); break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) case BLE_LL_SCHED_TYPE_SYNC: ble_ll_sync_rmvd_from_sched(entry->cb_arg); break; #endif +#endif #endif default: BLE_LL_ASSERT(0); @@ -302,16 +312,17 @@ ble_ll_sched_is_overlap(struct ble_ll_sched_item *s1, static int ble_ll_sched_overlaps_current(struct ble_ll_sched_item *sch) { - int rc; + int rc = 0; +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) uint32_t ce_end_time; - rc = 0; if (ble_ll_state_get() == BLE_LL_STATE_CONNECTION) { ce_end_time = ble_ll_conn_get_ce_end_time(); if (CPUTIME_GT(ce_end_time, sch->start_time)) { rc = 1; } } +#endif return rc; } @@ -334,7 +345,9 @@ int ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) { struct ble_ll_sched_item *sch; +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) uint32_t usecs; +#endif os_sr_t sr; int rc; @@ -343,13 +356,24 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) /* Set schedule start and end times */ sch->start_time = connsm->anchor_point - g_ble_ll_sched_offset_ticks; - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_MASTER: + sch->remainder = connsm->anchor_point_usecs; + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_SLAVE: usecs = connsm->slave_cur_window_widening; sch->start_time -= (os_cputime_usecs_to_ticks(usecs) + 1); sch->remainder = 0; - } else { - sch->remainder = connsm->anchor_point_usecs; + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } + sch->end_time = connsm->ce_end_time; /* Better be past current time or we just leave */ @@ -802,7 +826,7 @@ usecs_to_ticks_fast(uint32_t usecs) } #endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) /* * Determines if the schedule item overlaps the currently running schedule * item. This function cares about connection and sync. @@ -815,9 +839,11 @@ ble_ll_sched_sync_overlaps_current(struct ble_ll_sched_item *sch) state = ble_ll_state_get(); switch (state) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_STATE_CONNECTION: end_time = ble_ll_conn_get_ce_end_time(); break; +#endif case BLE_LL_STATE_SYNC: end_time = ble_ll_sync_get_event_end_time(); break; @@ -1037,10 +1063,24 @@ ble_ll_sched_adv_resched_pdu(struct ble_ll_sched_item *sch) OS_ENTER_CRITICAL(sr); lls = ble_ll_state_get(); - if ((lls == BLE_LL_STATE_ADV) || (lls == BLE_LL_STATE_CONNECTION) || - (lls == BLE_LL_STATE_SYNC)) { + switch(lls) { +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) + case BLE_LL_STATE_ADV: OS_EXIT_CRITICAL(sr); return -1; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_STATE_CONNECTION: + OS_EXIT_CRITICAL(sr); + return -1; +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) + case BLE_LL_STATE_SYNC: + OS_EXIT_CRITICAL(sr); + return -1; +#endif + default: + break; } rc = ble_ll_sched_insert(sch, 0, preempt_none); @@ -1161,25 +1201,40 @@ ble_ll_sched_execute_item(struct ble_ll_sched_item *sch) /* We have to disable the PHY no matter what */ ble_phy_disable(); - if (lls == BLE_LL_STATE_SCANNING) { + switch (lls) { +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) + case BLE_LL_STATE_SCANNING: ble_ll_state_set(BLE_LL_STATE_STANDBY); ble_ll_scan_halt(); - } else if (lls == BLE_LL_STATE_ADV) { - STATS_INC(ble_ll_stats, sched_state_adv_errs); - ble_ll_adv_halt(); + break; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) - } else if (lls == BLE_LL_STATE_SYNC) { + case BLE_LL_STATE_SYNC: STATS_INC(ble_ll_stats, sched_state_sync_errs); ble_ll_sync_halt(); + break; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - } else if (lls == BLE_LL_STATE_SCAN_AUX) { + case BLE_LL_STATE_SCAN_AUX: ble_ll_state_set(BLE_LL_STATE_STANDBY); ble_ll_scan_aux_halt(); + break; #endif - } else { +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) + case BLE_LL_STATE_ADV: + STATS_INC(ble_ll_stats, sched_state_adv_errs); + ble_ll_adv_halt(); + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_STATE_CONNECTION: STATS_INC(ble_ll_stats, sched_state_conn_errs); ble_ll_conn_event_halt(); + break; +#endif + default: + BLE_LL_ASSERT(0); + break; } sched: diff --git a/nimble/controller/src/ble_ll_supp_cmd.c b/nimble/controller/src/ble_ll_supp_cmd.c index 6ceeaebb02..2fc0d7d3af 100644 --- a/nimble/controller/src/ble_ll_supp_cmd.c +++ b/nimble/controller/src/ble_ll_supp_cmd.c @@ -27,7 +27,11 @@ #include "controller/ble_ll_hci.h" /* Octet 0 */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define BLE_SUPP_CMD_DISCONNECT (1 << 5) +#else +#define BLE_SUPP_CMD_DISCONNECT (0 << 5) +#endif #define BLE_LL_SUPP_CMD_OCTET_0 (BLE_SUPP_CMD_DISCONNECT) /* Octet 5 */ @@ -64,7 +68,12 @@ /* Octet 15 */ #define BLE_SUPP_CMD_RD_BD_ADDR (1 << 1) + +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define BLE_SUPP_CMD_RD_RSSI (1 << 5) +#else +#define BLE_SUPP_CMD_RD_RSSI (0 << 5) +#endif #define BLE_LL_SUPP_CMD_OCTET_15 \ ( \ @@ -77,9 +86,15 @@ #define BLE_SUPP_CMD_LE_RD_BUF_SIZE (1 << 1) #define BLE_SUPP_CMD_LE_RD_LOC_FEAT (1 << 2) #define BLE_SUPP_CMD_LE_SET_RAND_ADDR (1 << 4) +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) #define BLE_SUPP_CMD_LE_SET_ADV_PARAMS (1 << 5) #define BLE_SUPP_CMD_LE_SET_ADV_TX_PWR (1 << 6) #define BLE_SUPP_CMD_LE_SET_ADV_DATA (1 << 7) +#else +#define BLE_SUPP_CMD_LE_SET_ADV_PARAMS (0 << 5) +#define BLE_SUPP_CMD_LE_SET_ADV_TX_PWR (0 << 6) +#define BLE_SUPP_CMD_LE_SET_ADV_DATA (0 << 7) +#endif #define BLE_LL_SUPP_CMD_OCTET_25 \ ( \ @@ -93,12 +108,28 @@ ) /* Octet 26 */ +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) #define BLE_SUPP_CMD_LE_SET_SCAN_RSP_DATA (1 << 0) #define BLE_SUPP_CMD_LE_SET_ADV_ENABLE (1 << 1) +#else +#define BLE_SUPP_CMD_LE_SET_SCAN_RSP_DATA (0 << 0) +#define BLE_SUPP_CMD_LE_SET_ADV_ENABLE (0 << 1) +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) #define BLE_SUPP_CMD_LE_SET_SCAN_PARAMS (1 << 2) #define BLE_SUPP_CMD_LE_SET_SCAN_ENABLE (1 << 3) +#else +#define BLE_SUPP_CMD_LE_SET_SCAN_PARAMS (0 << 2) +#define BLE_SUPP_CMD_LE_SET_SCAN_ENABLE (0 << 3) +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define BLE_SUPP_CMD_LE_CREATE_CONN (1 << 4) #define BLE_SUPP_CMD_LE_CREATE_CONN_CANCEL (1 << 5) +#else +#define BLE_SUPP_CMD_LE_CREATE_CONN (0 << 4) +#define BLE_SUPP_CMD_LE_CREATE_CONN_CANCEL (0 << 5) + +#endif #define BLE_SUPP_CMD_LE_RD_WHITELIST_SIZE (1 << 6) #define BLE_SUPP_CMD_LE_CLR_WHITELIST (1 << 7) @@ -117,10 +148,19 @@ /* Octet 27 */ #define BLE_SUPP_CMD_LE_ADD_DEV_WHITELIST (1 << 0) #define BLE_SUPP_CMD_LE_RMV_DEV_WHITELIST (1 << 1) +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define BLE_SUPP_CMD_LE_CONN_UPDATE (1 << 2) +#else +#define BLE_SUPP_CMD_LE_CONN_UPDATE (0 << 2) +#endif #define BLE_SUPP_CMD_LE_SET_HOST_CHAN_CLASS (1 << 3) +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define BLE_SUPP_CMD_LE_RD_CHAN_MAP (1 << 4) #define BLE_SUPP_CMD_LE_RD_REM_USED_FEAT (1 << 5) +#else +#define BLE_SUPP_CMD_LE_RD_CHAN_MAP (0 << 4) +#define BLE_SUPP_CMD_LE_RD_REM_USED_FEAT (0 << 5) +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) #define BLE_SUPP_CMD_LE_ENCRYPT (1 << 6) #else @@ -142,10 +182,19 @@ /* Octet 28 */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define BLE_SUPP_CMD_LE_START_ENCRYPT (1 << 0) +#else +#define BLE_SUPP_CMD_LE_START_ENCRYPT (0 << 0) +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) #define BLE_SUPP_CMD_LE_LTK_REQ_REPLY (1 << 1) #define BLE_SUPP_CMD_LE_LTK_REQ_NEG_REPLY (1 << 2) #else +#define BLE_SUPP_CMD_LE_LTK_REQ_REPLY (0 << 1) +#define BLE_SUPP_CMD_LE_LTK_REQ_NEG_REPLY (0 << 2) +#endif +#else #define BLE_SUPP_CMD_LE_START_ENCRYPT (0 << 0) #define BLE_SUPP_CMD_LE_LTK_REQ_REPLY (0 << 1) #define BLE_SUPP_CMD_LE_LTK_REQ_NEG_REPLY (0 << 2) @@ -175,6 +224,7 @@ ) /* Octet 33 */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define BLE_SUPP_CMD_LE_REM_CONN_PRR (1 << 4) #define BLE_SUPP_CMD_LE_REM_CONN_PRNR (1 << 5) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) @@ -184,6 +234,13 @@ #define BLE_SUPP_CMD_LE_SET_DATALEN (0 << 6) #define BLE_SUPP_CMD_LE_RD_SUGG_DATALEN (0 << 7) #endif +#else +#define BLE_SUPP_CMD_LE_REM_CONN_PRR (0 << 4) +#define BLE_SUPP_CMD_LE_REM_CONN_PRNR (0 << 5) +#define BLE_SUPP_CMD_LE_SET_DATALEN (0 << 6) +#define BLE_SUPP_CMD_LE_RD_SUGG_DATALEN (0 << 7) +#endif + #define BLE_LL_SUPP_CMD_OCTET_33 \ ( \ @@ -194,11 +251,15 @@ ) /* Octet 34 */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) #define BLE_SUPP_CMD_LE_WR_SUGG_DATALEN (1 << 0) #else #define BLE_SUPP_CMD_LE_WR_SUGG_DATALEN (0 << 0) #endif +#else +#define BLE_SUPP_CMD_LE_WR_SUGG_DATALEN (0 << 0) +#endif #define BLE_SUPP_CMD_LE_READ_LOCAL_P256_PK (0 << 1) #define BLE_SUPP_CMD_LE_GENERATE_DH_KEY (0 << 2) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) @@ -239,6 +300,7 @@ #endif #define BLE_SUPP_CMD_LE_RD_MAX_DATALEN (1 << 3) #if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define BLE_SUPP_CMD_LE_READ_PHY (1 << 4) #define BLE_SUPP_CMD_LE_SET_DEFAULT_PHY (1 << 5) #define BLE_SUPP_CMD_LE_SET_PHY (1 << 6) @@ -247,6 +309,11 @@ #define BLE_SUPP_CMD_LE_SET_DEFAULT_PHY (0 << 5) #define BLE_SUPP_CMD_LE_SET_PHY (0 << 6) #endif +#else +#define BLE_SUPP_CMD_LE_READ_PHY (0 << 4) +#define BLE_SUPP_CMD_LE_SET_DEFAULT_PHY (0 << 5) +#define BLE_SUPP_CMD_LE_SET_PHY (0 << 6) +#endif #if MYNEWT_VAL(BLE_LL_DTM) #define BLE_SUPP_CMD_LE_ENHANCED_RX_TEST (1 << 7) @@ -273,7 +340,7 @@ #define BLE_SUPP_CMD_LE_ENHANCED_TX_TEST (0 << 0) #endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) #define BLE_SUPP_CMD_LE_SET_ADVS_RAND_ADDR (1 << 1) #define BLE_SUPP_CMD_LE_SET_EXT_ADV_PARAM (1 << 2) #define BLE_SUPP_CMD_LE_SET_EXT_ADV_DATA (1 << 3) @@ -304,14 +371,14 @@ ) /* Octet 37 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) #define BLE_SUPP_CMD_LE_REMOVE_ADVS (1 << 0) #define BLE_SUPP_CMD_LE_CLEAR_ADVS (1 << 1) #else #define BLE_SUPP_CMD_LE_REMOVE_ADVS (0 << 0) #define BLE_SUPP_CMD_LE_CLEAR_ADVS (0 << 1) #endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) #define BLE_SUPP_CMD_LE_SET_PADV_PARAM (1 << 2) #define BLE_SUPP_CMD_LE_SET_PADV_DATA (1 << 3) #define BLE_SUPP_CMD_LE_SET_PADV_ENABLE (1 << 4) @@ -321,10 +388,19 @@ #define BLE_SUPP_CMD_LE_SET_PADV_ENABLE (0 << 4) #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) #define BLE_SUPP_CMD_LE_SET_EXT_SCAN_PARAM (1 << 5) #define BLE_SUPP_CMD_LE_SET_EXT_SCAN_ENABLE (1 << 6) +#else +#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_PARAM (0 << 5) +#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_ENABLE (0 << 6) +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define BLE_SUPP_CMD_LE_EXT_CREATE_CONN (1 << 7) #else +#define BLE_SUPP_CMD_LE_EXT_CREATE_CONN (0 << 7) +#endif +#else #define BLE_SUPP_CMD_LE_SET_EXT_SCAN_PARAM (0 << 5) #define BLE_SUPP_CMD_LE_SET_EXT_SCAN_ENABLE (0 << 6) #define BLE_SUPP_CMD_LE_EXT_CREATE_CONN (0 << 7) @@ -343,7 +419,7 @@ ) /* Octet 38 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) #define BLE_SUPP_CMD_LE_PADV_CREATE_SYNC (1 << 0) #define BLE_SUPP_CMD_LE_PADV_CREATE_SYNC_C (1 << 1) #define BLE_SUPP_CMD_LE_PADV_TERMINATE_SYNC (1 << 2) @@ -391,7 +467,8 @@ ) /* Octet 40 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_VERSION) >= 51 +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_VERSION) >= 51 && \ + MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) #define BLE_SUPP_CMD_LE_PADV_RECV_ENABLE (1 << 5) #else #define BLE_SUPP_CMD_LE_PADV_RECV_ENABLE (0 << 5) diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 4b2004953d..7b6208ce11 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -41,7 +41,7 @@ #include "stats/stats.h" -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) /* defines number of events that can be lost during sync establishment * before failed to be established error is reported diff --git a/nimble/controller/src/ble_ll_whitelist.c b/nimble/controller/src/ble_ll_whitelist.c index 04ec6428b5..12d841a7f8 100644 --- a/nimble/controller/src/ble_ll_whitelist.c +++ b/nimble/controller/src/ble_ll_whitelist.c @@ -48,8 +48,6 @@ struct ble_ll_whitelist_entry g_ble_ll_whitelist[BLE_LL_WHITELIST_SIZE]; static int ble_ll_whitelist_chg_allowed(void) { - int rc; - /* * This command is not allowed if: * -> advertising uses the whitelist and we are currently advertising. @@ -57,11 +55,19 @@ ble_ll_whitelist_chg_allowed(void) * -> initiating uses whitelist and a LE create connection command is in * progress */ - rc = 1; - if (!ble_ll_adv_can_chg_whitelist() || !ble_ll_scan_can_chg_whitelist()) { - rc = 0; +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) + if (ble_ll_adv_can_chg_whitelist()) { + return 1; } - return rc; +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) + if (ble_ll_scan_can_chg_whitelist()) { + return 1; + } +#endif + + return 0; } /** diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 7c33242716..62c9c4ad9d 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -23,6 +23,30 @@ syscfg.defs: this setting shall not be overriden. value: 1 + BLE_LL_ROLE_CENTRAL: + description: 'Enables controller support for the Central role.' + value: MYNEWT_VAL(BLE_ROLE_CENTRAL) + restrictions: + - 'BLE_LL_ROLE_OBSERVER if 1' + + BLE_LL_ROLE_PERIPHERAL: + description: 'Enables controller support for the Peripheral role.' + value: MYNEWT_VAL(BLE_ROLE_PERIPHERAL) + restrictions: + - 'BLE_LL_ROLE_BROADCASTER if 1' + + BLE_LL_ROLE_BROADCASTER: + description: 'Enables controller support for the Broadcaster role.' + value: MYNEWT_VAL(BLE_ROLE_BROADCASTER) + restrictions: + - 'BLE_LL_ROLE_OBSERVER if 0' + + BLE_LL_ROLE_OBSERVER: + description: 'Enables controller support for the Observer role.' + value: MYNEWT_VAL(BLE_ROLE_OBSERVER) + restrictions: + - 'BLE_LL_ROLE_BROADCASTER if 0' + BLE_HW_WHITELIST_ENABLE: description: > Used to enable hardware white list @@ -184,21 +208,21 @@ syscfg.defs: description: > This option enables/disables encryption support in the controller. This option saves both both code and RAM. - value: '1' + value: 'MYNEWT_VAL_BLE_LL_ROLE_CENTRAL || MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL' BLE_LL_CFG_FEAT_CONN_PARAM_REQ: description: > This option enables/disables the connection parameter request procedure. This is implemented in the controller but is disabled by default. - value: '1' + value: 'MYNEWT_VAL_BLE_LL_ROLE_CENTRAL || MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL' BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG: description: > This option allows a slave to initiate the feature exchange procedure. This feature is implemented but currently has no impact on code or ram size - value: '1' + value: 'MYNEWT_VAL_BLE_LL_ROLE_CENTRAL || MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL' BLE_LL_CFG_FEAT_LE_PING: description: > @@ -213,7 +237,7 @@ syscfg.defs: the controller. If enabled, the controller is allowed to change the size of tx/rx pdu's used in a connection. This option has only minor impact on code size and non on RAM. - value: '1' + value: 'MYNEWT_VAL_BLE_LL_ROLE_CENTRAL || MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL' BLE_LL_CFG_FEAT_LL_PRIVACY: description: > @@ -248,8 +272,6 @@ syscfg.defs: This option is used to enable/disable support for Periodic Advertising Feature. value: MYNEWT_VAL(BLE_PERIODIC_ADV) - restrictions: - - 'BLE_LL_CFG_FEAT_LL_EXT_ADV if 1' BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_CNT: description: > @@ -273,6 +295,8 @@ syscfg.defs: limit number of ACL packets sent at once from controller to avoid congestion on HCI transport if feature is also supported by host. value: 0 + restrictions: + - '(BLE_ROLE_CENTRAL || BLE_ROLE_PERIPHERAL) if 1' BLE_LL_CFG_FEAT_LL_SCA_UPDATE: description: > diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index b5cfc585d6..32fbaf9872 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -67,6 +67,7 @@ syscfg.defs: value: 0 restrictions: - 'BLE_PERIODIC_ADV if 1' + - '(BLE_ROLE_CENTRAL || BLE_ROLE_PERIPHERAL) if 1' BLE_EXT_ADV_MAX_SIZE: description: > diff --git a/nimble/transport/uart/src/ble_hci_uart.c b/nimble/transport/uart/src/ble_hci_uart.c index 2cad55a7d9..ac49b30b07 100644 --- a/nimble/transport/uart/src/ble_hci_uart.c +++ b/nimble/transport/uart/src/ble_hci_uart.c @@ -755,7 +755,9 @@ ble_hci_uart_rx_skip_acl(uint8_t data) if (rxd_bytes == ble_hci_uart_state.rx_acl.len) { /* XXX: I dont like this but for now this denotes controller only */ #if MYNEWT_VAL(BLE_CONTROLLER) +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) ble_ll_data_buffer_overflow(); +#endif #endif ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_NONE; } From f4dd2f34f81ddd4fc638ce31694d207d8bd788ea Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 21 Dec 2021 17:31:56 +0100 Subject: [PATCH 0204/1333] nimble/ll: Set LE supported states based on enabled roles This also fix claiming support for concurrent scanning and initiating which is not supported by LL yet. --- nimble/controller/src/ble_ll.c | 207 ++++++++++++++++++++++++++------- 1 file changed, 165 insertions(+), 42 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 0560b61da4..56e81a6697 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -65,48 +65,171 @@ */ /* Supported states */ -#define BLE_LL_S_NCA (0x00000000001) -#define BLE_LL_S_SA (0x00000000002) -#define BLE_LL_S_CA (0x00000000004) -#define BLE_LL_S_HDCA (0x00000000008) -#define BLE_LL_S_PS (0x00000000010) -#define BLE_LL_S_AS (0x00000000020) -#define BLE_LL_S_INIT (0x00000000040) -#define BLE_LL_S_SLAVE (0x00000000080) -#define BLE_LL_S_NCA_PS (0x00000000100) -#define BLE_LL_S_SA_PS (0x00000000200) -#define BLE_LL_S_CA_PS (0x00000000400) -#define BLE_LL_S_HDCA_PS (0x00000000800) -#define BLE_LL_S_NCA_AS (0x00000001000) -#define BLE_LL_S_SA_AS (0x00000002000) -#define BLE_LL_S_CA_AS (0x00000004000) -#define BLE_LL_S_HDCA_AS (0x00000008000) -#define BLE_LL_S_NCA_INIT (0x00000010000) -#define BLE_LL_S_SA_INIT (0x00000020000) -#define BLE_LL_S_NCA_MASTER (0x00000040000) -#define BLE_LL_S_SA_MASTER (0x00000080000) -#define BLE_LL_S_NCA_SLAVE (0x00000100000) -#define BLE_LL_S_SA_SLAVE (0x00000200000) -#define BLE_LL_S_PS_INIT (0x00000400000) -#define BLE_LL_S_AS_INIT (0x00000800000) -#define BLE_LL_S_PS_MASTER (0x00001000000) -#define BLE_LL_S_AS_MASTER (0x00002000000) -#define BLE_LL_S_PS_SLAVE (0x00004000000) -#define BLE_LL_S_AS_SLAVE (0x00008000000) -#define BLE_LL_S_INIT_MASTER (0x00010000000) -#define BLE_LL_S_LDCA (0x00020000000) -#define BLE_LL_S_LDCA_PS (0x00040000000) -#define BLE_LL_S_LDCA_AS (0x00080000000) -#define BLE_LL_S_CA_INIT (0x00100000000) -#define BLE_LL_S_HDCA_INIT (0x00200000000) -#define BLE_LL_S_LDCA_INIT (0x00400000000) -#define BLE_LL_S_CA_MASTER (0x00800000000) -#define BLE_LL_S_HDCA_MASTER (0x01000000000) -#define BLE_LL_S_LDCA_MASTER (0x02000000000) -#define BLE_LL_S_CA_SLAVE (0x04000000000) -#define BLE_LL_S_HDCA_SLAVE (0x08000000000) -#define BLE_LL_S_LDCA_SLAVE (0x10000000000) -#define BLE_LL_S_INIT_SLAVE (0x20000000000) +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) +#define BLE_LL_S_NCA ((uint64_t)1 << 0) +#define BLE_LL_S_SA ((uint64_t)1 << 1) +#else +#define BLE_LL_S_NCA ((uint64_t)0 << 0) +#define BLE_LL_S_SA ((uint64_t)0 << 1) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) +#define BLE_LL_S_CA ((uint64_t)1 << 2) +#define BLE_LL_S_HDCA ((uint64_t)1 << 3) +#else +#define BLE_LL_S_CA ((uint64_t)0 << 2) +#define BLE_LL_S_HDCA ((uint64_t)0 << 3) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) +#define BLE_LL_S_PS ((uint64_t)1 << 4) +#define BLE_LL_S_AS ((uint64_t)1 << 5) +#else +#define BLE_LL_S_PS ((uint64_t)0 << 4) +#define BLE_LL_S_AS ((uint64_t)0 << 5) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) +#define BLE_LL_S_INIT ((uint64_t)1 << 6) +#else +#define BLE_LL_S_INIT ((uint64_t)0 << 6) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) +#define BLE_LL_S_SLAVE ((uint64_t)1 << 7) +#else +#define BLE_LL_S_SLAVE ((uint64_t)0 << 7) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) +#define BLE_LL_S_NCA_PS ((uint64_t)1 << 8) +#define BLE_LL_S_SA_PS ((uint64_t)1 << 9) +#else +#define BLE_LL_S_NCA_PS ((uint64_t)0 << 8) +#define BLE_LL_S_SA_PS ((uint64_t)0 << 9) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) +#define BLE_LL_S_CA_PS ((uint64_t)1 << 10) +#define BLE_LL_S_HDCA_PS ((uint64_t)1 << 11) +#else +#define BLE_LL_S_CA_PS ((uint64_t)0 << 10) +#define BLE_LL_S_HDCA_PS ((uint64_t)0 << 11) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) +#define BLE_LL_S_NCA_AS ((uint64_t)1 << 12) +#define BLE_LL_S_SA_AS ((uint64_t)1 << 13) +#else +#define BLE_LL_S_NCA_AS ((uint64_t)0 << 12) +#define BLE_LL_S_SA_AS ((uint64_t)0 << 13) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) +#define BLE_LL_S_CA_AS ((uint64_t)1 << 14) +#define BLE_LL_S_HDCA_AS ((uint64_t)1 << 15) +#else +#define BLE_LL_S_CA_AS ((uint64_t)0 << 14) +#define BLE_LL_S_HDCA_AS ((uint64_t)0 << 15) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) && MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) +#define BLE_LL_S_NCA_INIT ((uint64_t)1 << 16) +#define BLE_LL_S_SA_INIT ((uint64_t)1 << 17) +#define BLE_LL_S_NCA_MASTER ((uint64_t)1 << 18) +#define BLE_LL_S_SA_MASTER ((uint64_t)1 << 19) +#else +#define BLE_LL_S_NCA_INIT ((uint64_t)0 << 16) +#define BLE_LL_S_SA_INIT ((uint64_t)0 << 17) +#define BLE_LL_S_NCA_MASTER ((uint64_t)0 << 18) +#define BLE_LL_S_SA_MASTER ((uint64_t)0 << 19) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) && MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) +#define BLE_LL_S_NCA_SLAVE ((uint64_t)1 << 20) +#define BLE_LL_S_SA_SLAVE ((uint64_t)1 << 21) +#else +#define BLE_LL_S_NCA_SLAVE ((uint64_t)0 << 20) +#define BLE_LL_S_SA_SLAVE ((uint64_t)0 << 21) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) && MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) +/* We do not support passive scanning while initiating yet */ +#define BLE_LL_S_PS_INIT ((uint64_t)0 << 22) +/* We do not support active scanning while initiating yet */ +#define BLE_LL_S_AS_INIT ((uint64_t)0 << 23) +#define BLE_LL_S_PS_MASTER ((uint64_t)1 << 24) +#define BLE_LL_S_AS_MASTER ((uint64_t)1 << 25) +#else +#define BLE_LL_S_PS_INIT ((uint64_t)0 << 22) +#define BLE_LL_S_AS_INIT ((uint64_t)0 << 23) +#define BLE_LL_S_PS_MASTER ((uint64_t)0 << 24) +#define BLE_LL_S_AS_MASTER ((uint64_t)0 << 25) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) && MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) +#define BLE_LL_S_PS_SLAVE ((uint64_t)1 << 26) +#define BLE_LL_S_AS_SLAVE ((uint64_t)1 << 27) +#else +#define BLE_LL_S_PS_SLAVE ((uint64_t)0 << 26) +#define BLE_LL_S_AS_SLAVE ((uint64_t)0 << 27) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) +#define BLE_LL_S_INIT_MASTER ((uint64_t)1 << 28) +#else +#define BLE_LL_S_INIT_MASTER ((uint64_t)0 << 28) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) +#define BLE_LL_S_LDCA ((uint64_t)1 << 29) +#else +#define BLE_LL_S_LDCA ((uint64_t)0 << 29) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) +#define BLE_LL_S_LDCA_PS ((uint64_t)1 << 30) +#define BLE_LL_S_LDCA_AS ((uint64_t)1 << 31) +#else +#define BLE_LL_S_LDCA_PS ((uint64_t)0 << 30) +#define BLE_LL_S_LDCA_AS ((uint64_t)0 << 31) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) && MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) +#define BLE_LL_S_CA_INIT ((uint64_t)1 << 32) +#define BLE_LL_S_HDCA_INIT ((uint64_t)1 << 33) +#define BLE_LL_S_LDCA_INIT ((uint64_t)1 << 34) +#else +#define BLE_LL_S_CA_INIT ((uint64_t)0 << 32) +#define BLE_LL_S_HDCA_INIT ((uint64_t)0 << 33) +#define BLE_LL_S_LDCA_INIT ((uint64_t)0 << 34) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) +#define BLE_LL_S_CA_MASTER ((uint64_t)1 << 35) +#define BLE_LL_S_HDCA_MASTER ((uint64_t)1 << 36) +#define BLE_LL_S_LDCA_MASTER ((uint64_t)1 << 37) +#else +#define BLE_LL_S_CA_MASTER ((uint64_t)0 << 35) +#define BLE_LL_S_HDCA_MASTER ((uint64_t)0 << 36) +#define BLE_LL_S_LDCA_MASTER ((uint64_t)0 << 37) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) +#define BLE_LL_S_CA_SLAVE ((uint64_t)1 << 38) +#define BLE_LL_S_HDCA_SLAVE ((uint64_t)1 << 39) +#define BLE_LL_S_LDCA_SLAVE ((uint64_t)1 << 40) +#else +#define BLE_LL_S_CA_SLAVE ((uint64_t)0 << 38) +#define BLE_LL_S_HDCA_SLAVE ((uint64_t)0 << 39) +#define BLE_LL_S_LDCA_SLAVE ((uint64_t)0 << 40) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) && MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) +#define BLE_LL_S_INIT_SLAVE ((uint64_t)1 << 41) +#else +#define BLE_LL_S_INIT_SLAVE ((uint64_t)0 << 41) +#endif #define BLE_LL_SUPPORTED_STATES \ ( \ From ee6ba614c81cb83f4f6ae3b559e142344e8ec0ef Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 14 Dec 2021 15:18:33 +0100 Subject: [PATCH 0205/1333] nimble: Allow to configure BLE version 5.3 Core Specification 5.3 is available for some time already. --- nimble/include/nimble/hci_common.h | 6 +++++- nimble/syscfg.yml | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index b6f9869a71..7369518874 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1828,6 +1828,7 @@ struct ble_hci_ev_le_subev_biginfo_adv_report { #define BLE_HCI_VER_BCS_5_0 (9) #define BLE_HCI_VER_BCS_5_1 (10) #define BLE_HCI_VER_BCS_5_2 (11) +#define BLE_HCI_VER_BCS_5_3 (12) #define BLE_LMP_VER_BCS_1_0b (0) #define BLE_LMP_VER_BCS_1_1 (1) @@ -1841,6 +1842,7 @@ struct ble_hci_ev_le_subev_biginfo_adv_report { #define BLE_LMP_VER_BCS_5_0 (9) #define BLE_LMP_VER_BCS_5_1 (10) #define BLE_LMP_VER_BCS_5_2 (11) +#define BLE_LMP_VER_BCS_5_3 (12) /* selected HCI and LMP version */ #if MYNEWT_VAL(BLE_VERSION) == 50 @@ -1852,7 +1854,9 @@ struct ble_hci_ev_le_subev_biginfo_adv_report { #elif MYNEWT_VAL(BLE_VERSION) == 52 #define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_5_2 #define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_5_2 - +#elif MYNEWT_VAL(BLE_VERSION) == 53 +#define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_5_3 +#define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_5_3 #endif #define BLE_HCI_DATA_HDR_SZ 4 diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index 32fbaf9872..0e87c0647d 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -80,7 +80,7 @@ syscfg.defs: This allows to configure supported Bluetooth Core version. Some features may not be available if version is too low. Version is integer for easy comparison. - range: 50, 51, 52 + range: 50, 51, 52, 53 value: 50 BLE_ISO: description: > From f771348a4ee7b5fd757aec810ebb0766cc300efc Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 6 Dec 2021 16:30:45 +0100 Subject: [PATCH 0206/1333] ports: Build NimBLE with 32-bit environment Some code in NimBLE assumes that pointers are 4 bytes. Until this is properly fixed build with -m32 to make sure resulting binary is no misbehaving. --- .travis.yml | 1 + porting/examples/dummy/Makefile | 3 ++- porting/examples/linux/Makefile | 2 +- porting/examples/linux_blemesh/Makefile | 2 +- porting/nimble/Makefile.defs | 5 ++++- 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0b59e7a862..185ca35507 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,7 @@ _addons: &addon_conf packages: - gcc-multilib - gcc-7-multilib + - g++-multilib go: - "1.16" diff --git a/porting/examples/dummy/Makefile b/porting/examples/dummy/Makefile index 861934f7f0..1c38ac4a3c 100644 --- a/porting/examples/dummy/Makefile +++ b/porting/examples/dummy/Makefile @@ -60,6 +60,7 @@ OBJ := $(SRC:.c=.o) TINYCRYPT_OBJ := $(TINYCRYPT_SRC:.c=.o) CFLAGS := $(NIMBLE_CFLAGS) +LDFLAGS := $(NIMBLE_LDFLAGS) .PHONY: all clean .DEFAULT: all @@ -76,4 +77,4 @@ $(TINYCRYPT_OBJ): CFLAGS+=$(TINYCRYPT_CFLAGS) $(CC) -c $(addprefix -I, $(INC)) $(CFLAGS) -o $@ $< dummy: $(OBJ) $(TINYCRYPT_OBJ) - $(CC) -o $@ $^ + $(CC) -o $@ $^ $(LDFLAGS) diff --git a/porting/examples/linux/Makefile b/porting/examples/linux/Makefile index 11f4ebc308..c3eee16cb5 100644 --- a/porting/examples/linux/Makefile +++ b/porting/examples/linux/Makefile @@ -81,7 +81,7 @@ CFLAGS = \ -D_GNU_SOURCE \ $(NULL) -LIBS := -lrt -lpthread -lstdc++ +LIBS := $(NIMBLE_LDFLAGS) -lrt -lpthread -lstdc++ .PHONY: all clean .DEFAULT: all diff --git a/porting/examples/linux_blemesh/Makefile b/porting/examples/linux_blemesh/Makefile index c1518e0e4d..67783f2766 100644 --- a/porting/examples/linux_blemesh/Makefile +++ b/porting/examples/linux_blemesh/Makefile @@ -83,7 +83,7 @@ CFLAGS = \ -D_GNU_SOURCE \ $(NULL) -LIBS := -lrt -lpthread -lstdc++ +LIBS := $(NIMBLE_LDFLAGS) -lrt -lpthread -lstdc++ .PHONY: all clean .DEFAULT: all diff --git a/porting/nimble/Makefile.defs b/porting/nimble/Makefile.defs index 5bab893fde..78f73fbc9b 100644 --- a/porting/nimble/Makefile.defs +++ b/porting/nimble/Makefile.defs @@ -19,7 +19,10 @@ ifeq (,$(NIMBLE_ROOT)) $(error NIMBLE_ROOT shall be defined) endif -NIMBLE_CFLAGS := +# For now this is required as there are places in NimBLE +# assumingthat pointer is 4 bytes long. +NIMBLE_CFLAGS := -m32 +NIMBLE_LDFLAGS := -m32 NIMBLE_INCLUDE := \ $(NIMBLE_ROOT)/nimble/include \ From 605ade16f7793e6c691b73436538ac588d7d0754 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 23 Dec 2021 14:26:36 +0100 Subject: [PATCH 0207/1333] nimble/ports: Use native BSP for test targets Dummy BSP could be getting out of sync with Mynewt BSP leading to compile errors. --- porting/targets/dummy_bsp/bsp.yml | 56 --------------------- porting/targets/dummy_bsp/include/bsp/bsp.h | 31 ------------ porting/targets/dummy_bsp/pkg.yml | 27 ---------- porting/targets/linux/target.yml | 2 +- porting/targets/linux_blemesh/target.yml | 2 +- porting/targets/nuttx/target.yml | 2 +- porting/targets/porting_default/syscfg.yml | 3 ++ porting/targets/porting_default/target.yml | 2 +- 8 files changed, 7 insertions(+), 118 deletions(-) delete mode 100644 porting/targets/dummy_bsp/bsp.yml delete mode 100644 porting/targets/dummy_bsp/include/bsp/bsp.h delete mode 100644 porting/targets/dummy_bsp/pkg.yml create mode 100644 porting/targets/porting_default/syscfg.yml diff --git a/porting/targets/dummy_bsp/bsp.yml b/porting/targets/dummy_bsp/bsp.yml deleted file mode 100644 index ecd1d42041..0000000000 --- a/porting/targets/dummy_bsp/bsp.yml +++ /dev/null @@ -1,56 +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. -# - -bsp.name: "dummy" -bsp.url: -bsp.maker: -bsp.arch: dummy -bsp.compiler: "@apache-mynewt-core/compiler/sim" - -bsp.flash_map: - areas: - # System areas. - FLASH_AREA_BOOTLOADER: - device: 0 - offset: 0x00000000 - size: 32kB - FLASH_AREA_IMAGE_0: - device: 0 - offset: 0x0000c000 - size: 472kB - FLASH_AREA_IMAGE_1: - device: 0 - offset: 0x00082000 - size: 472kB - FLASH_AREA_IMAGE_SCRATCH: - device: 0 - offset: 0x000f8000 - size: 16kB - - # User areas. - FLASH_AREA_REBOOT_LOG: - user_id: 0 - device: 0 - offset: 0x00008000 - size: 16kB - FLASH_AREA_NFFS: - user_id: 1 - device: 0 - offset: 0x000fc000 - size: 16kB diff --git a/porting/targets/dummy_bsp/include/bsp/bsp.h b/porting/targets/dummy_bsp/include/bsp/bsp.h deleted file mode 100644 index 69e8b1cfbb..0000000000 --- a/porting/targets/dummy_bsp/include/bsp/bsp.h +++ /dev/null @@ -1,31 +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_BSP_H -#define H_BSP_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* H_BSP_H */ diff --git a/porting/targets/dummy_bsp/pkg.yml b/porting/targets/dummy_bsp/pkg.yml deleted file mode 100644 index 8b8484960a..0000000000 --- a/porting/targets/dummy_bsp/pkg.yml +++ /dev/null @@ -1,27 +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. -# - -pkg.name: porting/targets/dummy_bsp -pkg.type: bsp -pkg.description: A dummy BSP definition -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: -pkg.cflags: -pkg.deps: diff --git a/porting/targets/linux/target.yml b/porting/targets/linux/target.yml index 9ab4152c9d..7145d70386 100644 --- a/porting/targets/linux/target.yml +++ b/porting/targets/linux/target.yml @@ -16,5 +16,5 @@ # under the License. # target.app: "porting/targets/dummy_app" -target.bsp: "porting/targets/dummy_bsp" +target.bsp: "@apache-mynewt-core/hw/bsp/native" target.build_profile: "debug" diff --git a/porting/targets/linux_blemesh/target.yml b/porting/targets/linux_blemesh/target.yml index 83eb415886..4b9a4dab8b 100644 --- a/porting/targets/linux_blemesh/target.yml +++ b/porting/targets/linux_blemesh/target.yml @@ -17,5 +17,5 @@ # target.app: "porting/targets/dummy_app" -target.bsp: "porting/targets/dummy_bsp" +target.bsp: "@apache-mynewt-core/hw/bsp/native" target.build_profile: "debug" diff --git a/porting/targets/nuttx/target.yml b/porting/targets/nuttx/target.yml index 9ab4152c9d..7145d70386 100644 --- a/porting/targets/nuttx/target.yml +++ b/porting/targets/nuttx/target.yml @@ -16,5 +16,5 @@ # under the License. # target.app: "porting/targets/dummy_app" -target.bsp: "porting/targets/dummy_bsp" +target.bsp: "@apache-mynewt-core/hw/bsp/native" target.build_profile: "debug" diff --git a/porting/targets/porting_default/syscfg.yml b/porting/targets/porting_default/syscfg.yml new file mode 100644 index 0000000000..d0aff807f2 --- /dev/null +++ b/porting/targets/porting_default/syscfg.yml @@ -0,0 +1,3 @@ +syscfg.vals: + BLE_SOCK_USE_TCP: 0 + BLE_SOCK_USE_LINUX_BLUE: 1 diff --git a/porting/targets/porting_default/target.yml b/porting/targets/porting_default/target.yml index 83eb415886..4b9a4dab8b 100644 --- a/porting/targets/porting_default/target.yml +++ b/porting/targets/porting_default/target.yml @@ -17,5 +17,5 @@ # target.app: "porting/targets/dummy_app" -target.bsp: "porting/targets/dummy_bsp" +target.bsp: "@apache-mynewt-core/hw/bsp/native" target.build_profile: "debug" From 4a008c8344d74e8a25edecd1a6c518238e01d474 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 23 Dec 2021 14:29:55 +0100 Subject: [PATCH 0208/1333] nimble/mesh: Fix bt_mesh_beacon_auth declaration net_id is 8 bytes long. --- nimble/host/mesh/src/crypto.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/crypto.h b/nimble/host/mesh/src/crypto.h index 637d13e724..dbdedf1fd6 100644 --- a/nimble/host/mesh/src/crypto.h +++ b/nimble/host/mesh/src/crypto.h @@ -70,7 +70,7 @@ static inline int bt_mesh_beacon_key(const uint8_t net_key[16], } int bt_mesh_beacon_auth(const uint8_t beacon_key[16], uint8_t flags, - const uint8_t net_id[16], uint32_t iv_index, + const uint8_t net_id[8], uint32_t iv_index, uint8_t auth[8]); static inline int bt_mesh_app_id(const uint8_t app_key[16], uint8_t app_id[1]) From c79a7abbbdcc091136efba684380ada38d1e0ab2 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 23 Dec 2021 14:30:30 +0100 Subject: [PATCH 0209/1333] nimble/mesh: Fix bt_mesh_keys_resolve declaration app_key is expected to be a pointer to pointer and not artay of pointers. --- nimble/host/mesh/src/app_keys.c | 2 +- nimble/host/mesh/src/app_keys.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/host/mesh/src/app_keys.c b/nimble/host/mesh/src/app_keys.c index acc51f2a60..cfe82576ab 100644 --- a/nimble/host/mesh/src/app_keys.c +++ b/nimble/host/mesh/src/app_keys.c @@ -495,7 +495,7 @@ ssize_t bt_mesh_app_keys_get(uint16_t net_idx, uint16_t app_idxs[], size_t max, int bt_mesh_keys_resolve(struct bt_mesh_msg_ctx *ctx, struct bt_mesh_subnet **sub, - const uint8_t *app_key[16], uint8_t *aid) + const uint8_t **app_key, uint8_t *aid) { struct app_key *app = NULL; diff --git a/nimble/host/mesh/src/app_keys.h b/nimble/host/mesh/src/app_keys.h index 3ef9ce7c8f..40df664506 100644 --- a/nimble/host/mesh/src/app_keys.h +++ b/nimble/host/mesh/src/app_keys.h @@ -41,7 +41,7 @@ int bt_mesh_app_key_set(uint16_t app_idx, uint16_t net_idx, */ int bt_mesh_keys_resolve(struct bt_mesh_msg_ctx *ctx, struct bt_mesh_subnet **sub, - const uint8_t *app_key[16], uint8_t *aid); + const uint8_t **app_key, uint8_t *aid); /** @brief Iterate through all matching application keys and call @c cb on each. * From a724f0b9befa398a17337a979d07f26a8be60d27 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 23 Dec 2021 14:31:42 +0100 Subject: [PATCH 0210/1333] nimble/mesh: Fix garbage in debug log meta was used uninitialed in this log. --- nimble/host/mesh/src/friend.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/nimble/host/mesh/src/friend.c b/nimble/host/mesh/src/friend.c index c7603a8d94..4ce0bbdece 100644 --- a/nimble/host/mesh/src/friend.c +++ b/nimble/host/mesh/src/friend.c @@ -438,9 +438,6 @@ static int unseg_app_sdu_prepare(struct bt_mesh_friend *frnd, return 0; } - BT_DBG("Re-encrypting friend pdu (SeqNum %06x -> %06x)", - meta.crypto.seq_num, bt_mesh.seq); - err = unseg_app_sdu_unpack(frnd, buf, &meta); if (err) { return err; From 984566d9760c6f71ee2121ffdbf99ba6ad6de8f7 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 23 Dec 2021 14:32:42 +0100 Subject: [PATCH 0211/1333] nimble/transport: Fix unused variable in socket transport btaddr is not used anywhere in ble_hci_sock_cmdevt_tx function. --- nimble/transport/socket/src/ble_hci_socket.c | 1 - 1 file changed, 1 deletion(-) diff --git a/nimble/transport/socket/src/ble_hci_socket.c b/nimble/transport/socket/src/ble_hci_socket.c index 44de8fed53..b444a24032 100644 --- a/nimble/transport/socket/src/ble_hci_socket.c +++ b/nimble/transport/socket/src/ble_hci_socket.c @@ -333,7 +333,6 @@ ble_hci_sock_acl_tx(struct os_mbuf *om) static int ble_hci_sock_cmdevt_tx(uint8_t *hci_ev, uint8_t h4_type) { - uint8_t btaddr[6]; struct msghdr msg; struct iovec iov[8]; int len; From 3a6ab21ad4f9e731f69e380f5422d98c9ad296b8 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 23 Dec 2021 14:33:46 +0100 Subject: [PATCH 0212/1333] nimble/ports: Refresh syscfg --- .../examples/linux/include/logcfg/logcfg.h | 9 +- .../examples/linux/include/syscfg/syscfg.h | 143 ++++-- .../linux/include/sysflash/sysflash.h | 2 +- .../linux_blemesh/include/logcfg/logcfg.h | 72 +-- .../linux_blemesh/include/syscfg/syscfg.h | 451 +++++++++++------- .../linux_blemesh/include/sysflash/sysflash.h | 2 +- .../examples/nuttx/include/logcfg/logcfg.h | 9 +- .../examples/nuttx/include/syscfg/syscfg.h | 191 ++++---- .../nuttx/include/sysflash/sysflash.h | 2 +- porting/nimble/include/logcfg/logcfg.h | 9 +- porting/nimble/include/syscfg/syscfg.h | 149 ++++-- porting/nimble/include/sysflash/sysflash.h | 2 +- porting/npl/riot/include/logcfg/logcfg.h | 9 +- porting/npl/riot/include/syscfg/syscfg.h | 103 +--- porting/npl/riot/include/sysflash/sysflash.h | 2 +- 15 files changed, 689 insertions(+), 466 deletions(-) diff --git a/porting/examples/linux/include/logcfg/logcfg.h b/porting/examples/linux/include/logcfg/logcfg.h index 837cdeac1f..fab4d812fc 100644 --- a/porting/examples/linux/include/logcfg/logcfg.h +++ b/porting/examples/linux/include/logcfg/logcfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0-dev + * This file was generated by Apache newt version: 1.10.0-dev */ #ifndef H_MYNEWT_LOGCFG_ @@ -22,11 +22,4 @@ #define DFLT_LOG_CRITICAL(...) MODLOG_CRITICAL(0, __VA_ARGS__) #define DFLT_LOG_DISABLED(...) MODLOG_DISABLED(0, __VA_ARGS__) -#define MFG_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_INFO(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_WARN(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_ERROR(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_CRITICAL(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_DISABLED(...) MODLOG_DISABLED(128, __VA_ARGS__) - #endif diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index 8363336eed..fc9ef468fc 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0-dev + * This file was generated by Apache newt version: 1.10.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -28,11 +28,20 @@ #define MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG (0) #endif +/*** @apache-mynewt-core/hw/bsp/native */ +#ifndef MYNEWT_VAL_BSP_SIMULATED +#define MYNEWT_VAL_BSP_SIMULATED (1) +#endif + /*** @apache-mynewt-core/hw/hal */ #ifndef MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS #define MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS (1) #endif +#ifndef MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT +#define MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT (0) +#endif + #ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ #define MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ (16) #endif @@ -45,10 +54,47 @@ #define MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES (0) #endif +#ifndef MYNEWT_VAL_HAL_SBRK +#define MYNEWT_VAL_HAL_SBRK (1) +#endif + #ifndef MYNEWT_VAL_HAL_SYSTEM_RESET_CB #define MYNEWT_VAL_HAL_SYSTEM_RESET_CB (0) #endif +/*** @apache-mynewt-core/hw/mcu/native */ +#ifndef MYNEWT_VAL_I2C_0 +#define MYNEWT_VAL_I2C_0 (0) +#endif + +#ifndef MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE +#define MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE (1) +#endif + +#ifndef MYNEWT_VAL_MCU_FLASH_STYLE_NORDIC +#define MYNEWT_VAL_MCU_FLASH_STYLE_NORDIC (0) +#endif + +#ifndef MYNEWT_VAL_MCU_FLASH_STYLE_ST +#define MYNEWT_VAL_MCU_FLASH_STYLE_ST (1) +#endif + +#ifndef MYNEWT_VAL_MCU_NATIVE +#define MYNEWT_VAL_MCU_NATIVE (1) +#endif + +#ifndef MYNEWT_VAL_MCU_NATIVE_USE_SIGNALS +#define MYNEWT_VAL_MCU_NATIVE_USE_SIGNALS (1) +#endif + +#ifndef MYNEWT_VAL_MCU_TIMER_POLLER_PRIO +#define MYNEWT_VAL_MCU_TIMER_POLLER_PRIO (0) +#endif + +#ifndef MYNEWT_VAL_MCU_UART_POLLER_PRIO +#define MYNEWT_VAL_MCU_UART_POLLER_PRIO (1) +#endif + /*** @apache-mynewt-core/kernel/os */ #ifndef MYNEWT_VAL_FLOAT_USER #define MYNEWT_VAL_FLOAT_USER (0) @@ -94,6 +140,10 @@ #define MYNEWT_VAL_OS_COREDUMP (0) #endif +#ifndef MYNEWT_VAL_OS_COREDUMP_CB +#define MYNEWT_VAL_OS_COREDUMP_CB (0) +#endif + #ifndef MYNEWT_VAL_OS_CPUTIME_FREQ #define MYNEWT_VAL_OS_CPUTIME_FREQ (1000000) #endif @@ -102,8 +152,9 @@ #define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (0) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_CRASH_FILE_LINE -#define MYNEWT_VAL_OS_CRASH_FILE_LINE (0) +#define MYNEWT_VAL_OS_CRASH_FILE_LINE (1) #endif #ifndef MYNEWT_VAL_OS_CRASH_LOG @@ -142,8 +193,9 @@ #define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX (600000) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN -#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (100) +#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (1) #endif #ifndef MYNEWT_VAL_OS_MAIN_STACK_SIZE @@ -210,6 +262,11 @@ #define MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME (0) #endif +/* Overridden by @apache-mynewt-core/hw/mcu/native (defined by @apache-mynewt-core/kernel/os) */ +#ifndef MYNEWT_VAL_OS_TICKS_PER_SEC +#define MYNEWT_VAL_OS_TICKS_PER_SEC (100) +#endif + #ifndef MYNEWT_VAL_OS_TIME_DEBUG #define MYNEWT_VAL_OS_TIME_DEBUG (0) #endif @@ -226,6 +283,33 @@ #define MYNEWT_VAL_WATCHDOG_INTERVAL (30000) #endif +/*** @apache-mynewt-core/net/ip/native_sockets */ +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX +#define MYNEWT_VAL_NATIVE_SOCKETS_MAX (8) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX_UDP +#define MYNEWT_VAL_NATIVE_SOCKETS_MAX_UDP (2048) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_POLL_INTERVAL_MS +#define MYNEWT_VAL_NATIVE_SOCKETS_POLL_INTERVAL_MS (200) +#endif + +#undef MYNEWT_VAL_NATIVE_SOCKETS_POLL_ITVL + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_PRIO +#define MYNEWT_VAL_NATIVE_SOCKETS_PRIO (2) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_STACK_SZ +#define MYNEWT_VAL_NATIVE_SOCKETS_STACK_SZ (4096) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE +#define MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE (200) +#endif + /*** @apache-mynewt-core/sys/console/stub */ #ifndef MYNEWT_VAL_CONSOLE_UART_BAUD #define MYNEWT_VAL_CONSOLE_UART_BAUD (115200) @@ -244,8 +328,12 @@ #define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10) #endif +#ifndef MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG +#define MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG (0) +#endif + #ifndef MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE -#define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (2) +#define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (9) #endif /*** @apache-mynewt-core/sys/log/common */ @@ -300,23 +388,6 @@ #define MYNEWT_VAL_LOG_LEVEL (0) #endif -/*** @apache-mynewt-core/sys/mfg */ -#ifndef MYNEWT_VAL_MFG_LOG_LVL -#define MYNEWT_VAL_MFG_LOG_LVL (15) -#endif - -#ifndef MYNEWT_VAL_MFG_LOG_MODULE -#define MYNEWT_VAL_MFG_LOG_MODULE (128) -#endif - -#ifndef MYNEWT_VAL_MFG_MAX_MMRS -#define MYNEWT_VAL_MFG_MAX_MMRS (2) -#endif - -#ifndef MYNEWT_VAL_MFG_SYSINIT_STAGE -#define MYNEWT_VAL_MFG_SYSINIT_STAGE (100) -#endif - /*** @apache-mynewt-core/sys/sys */ #ifndef MYNEWT_VAL_DEBUG_PANIC_ENABLED #define MYNEWT_VAL_DEBUG_PANIC_ENABLED (1) @@ -344,12 +415,14 @@ #define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE -#define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (0) +#define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (1) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_MESSAGE -#define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (0) +#define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (1) #endif /*** @apache-mynewt-core/util/rwlock */ @@ -366,6 +439,10 @@ #define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (31) #endif +#ifndef MYNEWT_VAL_BLE_HCI_VS +#define MYNEWT_VAL_BLE_HCI_VS (0) +#endif + #ifndef MYNEWT_VAL_BLE_ISO #define MYNEWT_VAL_BLE_ISO (0) #endif @@ -735,16 +812,16 @@ #define MYNEWT_VAL_BLE_SM_SC (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY -#define MYNEWT_VAL_BLE_SM_SC_ONLY (0) +#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS +#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif #ifndef MYNEWT_VAL_BLE_SM_SC_LVL #define MYNEWT_VAL_BLE_SM_SC_LVL (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS -#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) +#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY +#define MYNEWT_VAL_BLE_SM_SC_ONLY (0) #endif #ifndef MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST @@ -993,19 +1070,19 @@ #endif #ifndef MYNEWT_VAL_ARCH_NAME -#define MYNEWT_VAL_ARCH_NAME ("dummy") +#define MYNEWT_VAL_ARCH_NAME ("sim") #endif -#ifndef MYNEWT_VAL_ARCH_dummy -#define MYNEWT_VAL_ARCH_dummy (1) +#ifndef MYNEWT_VAL_ARCH_sim +#define MYNEWT_VAL_ARCH_sim (1) #endif #ifndef MYNEWT_VAL_BSP_NAME -#define MYNEWT_VAL_BSP_NAME ("dummy_bsp") +#define MYNEWT_VAL_BSP_NAME ("native") #endif -#ifndef MYNEWT_VAL_BSP_dummy_bsp -#define MYNEWT_VAL_BSP_dummy_bsp (1) +#ifndef MYNEWT_VAL_BSP_native +#define MYNEWT_VAL_BSP_native (1) #endif #ifndef MYNEWT_VAL_NEWT_FEATURE_LOGCFG diff --git a/porting/examples/linux/include/sysflash/sysflash.h b/porting/examples/linux/include/sysflash/sysflash.h index ab1341b25d..28391ca66a 100644 --- a/porting/examples/linux/include/sysflash/sysflash.h +++ b/porting/examples/linux/include/sysflash/sysflash.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0-dev + * This file was generated by Apache newt version: 1.10.0-dev */ #ifndef H_MYNEWT_SYSFLASH_ diff --git a/porting/examples/linux_blemesh/include/logcfg/logcfg.h b/porting/examples/linux_blemesh/include/logcfg/logcfg.h index 798418dabb..c3b5cdf400 100644 --- a/porting/examples/linux_blemesh/include/logcfg/logcfg.h +++ b/porting/examples/linux_blemesh/include/logcfg/logcfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0-dev + * This file was generated by Apache newt version: 1.10.0-dev */ #ifndef H_MYNEWT_LOGCFG_ @@ -50,6 +50,13 @@ #define BLE_MESH_FRIEND_LOG_CRITICAL(...) MODLOG_CRITICAL(14, __VA_ARGS__) #define BLE_MESH_FRIEND_LOG_DISABLED(...) MODLOG_DISABLED(14, __VA_ARGS__) +#define BLE_MESH_HEARTBEAT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_HEARTBEAT_LOG_INFO(...) MODLOG_INFO(26, __VA_ARGS__) +#define BLE_MESH_HEARTBEAT_LOG_WARN(...) MODLOG_WARN(26, __VA_ARGS__) +#define BLE_MESH_HEARTBEAT_LOG_ERROR(...) MODLOG_ERROR(26, __VA_ARGS__) +#define BLE_MESH_HEARTBEAT_LOG_CRITICAL(...) MODLOG_CRITICAL(26, __VA_ARGS__) +#define BLE_MESH_HEARTBEAT_LOG_DISABLED(...) MODLOG_DISABLED(26, __VA_ARGS__) + #define BLE_MESH_LOG_DEBUG(...) IGNORE(__VA_ARGS__) #define BLE_MESH_LOG_INFO(...) MODLOG_INFO(9, __VA_ARGS__) #define BLE_MESH_LOG_WARN(...) MODLOG_WARN(9, __VA_ARGS__) @@ -71,6 +78,13 @@ #define BLE_MESH_MODEL_LOG_CRITICAL(...) MODLOG_CRITICAL(16, __VA_ARGS__) #define BLE_MESH_MODEL_LOG_DISABLED(...) MODLOG_DISABLED(16, __VA_ARGS__) +#define BLE_MESH_NET_KEYS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_NET_KEYS_LOG_INFO(...) MODLOG_INFO(23, __VA_ARGS__) +#define BLE_MESH_NET_KEYS_LOG_WARN(...) MODLOG_WARN(23, __VA_ARGS__) +#define BLE_MESH_NET_KEYS_LOG_ERROR(...) MODLOG_ERROR(23, __VA_ARGS__) +#define BLE_MESH_NET_KEYS_LOG_CRITICAL(...) MODLOG_CRITICAL(23, __VA_ARGS__) +#define BLE_MESH_NET_KEYS_LOG_DISABLED(...) MODLOG_DISABLED(23, __VA_ARGS__) + #define BLE_MESH_NET_LOG_DEBUG(...) IGNORE(__VA_ARGS__) #define BLE_MESH_NET_LOG_INFO(...) MODLOG_INFO(17, __VA_ARGS__) #define BLE_MESH_NET_LOG_WARN(...) MODLOG_WARN(17, __VA_ARGS__) @@ -78,6 +92,20 @@ #define BLE_MESH_NET_LOG_CRITICAL(...) MODLOG_CRITICAL(17, __VA_ARGS__) #define BLE_MESH_NET_LOG_DISABLED(...) MODLOG_DISABLED(17, __VA_ARGS__) +#define BLE_MESH_PROVISIONER_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_PROVISIONER_LOG_INFO(...) MODLOG_INFO(25, __VA_ARGS__) +#define BLE_MESH_PROVISIONER_LOG_WARN(...) MODLOG_WARN(25, __VA_ARGS__) +#define BLE_MESH_PROVISIONER_LOG_ERROR(...) MODLOG_ERROR(25, __VA_ARGS__) +#define BLE_MESH_PROVISIONER_LOG_CRITICAL(...) MODLOG_CRITICAL(25, __VA_ARGS__) +#define BLE_MESH_PROVISIONER_LOG_DISABLED(...) MODLOG_DISABLED(25, __VA_ARGS__) + +#define BLE_MESH_PROV_DEVICE_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_PROV_DEVICE_LOG_INFO(...) MODLOG_INFO(24, __VA_ARGS__) +#define BLE_MESH_PROV_DEVICE_LOG_WARN(...) MODLOG_WARN(24, __VA_ARGS__) +#define BLE_MESH_PROV_DEVICE_LOG_ERROR(...) MODLOG_ERROR(24, __VA_ARGS__) +#define BLE_MESH_PROV_DEVICE_LOG_CRITICAL(...) MODLOG_CRITICAL(24, __VA_ARGS__) +#define BLE_MESH_PROV_DEVICE_LOG_DISABLED(...) MODLOG_DISABLED(24, __VA_ARGS__) + #define BLE_MESH_PROV_LOG_DEBUG(...) IGNORE(__VA_ARGS__) #define BLE_MESH_PROV_LOG_INFO(...) MODLOG_INFO(18, __VA_ARGS__) #define BLE_MESH_PROV_LOG_WARN(...) MODLOG_WARN(18, __VA_ARGS__) @@ -92,6 +120,13 @@ #define BLE_MESH_PROXY_LOG_CRITICAL(...) MODLOG_CRITICAL(19, __VA_ARGS__) #define BLE_MESH_PROXY_LOG_DISABLED(...) MODLOG_DISABLED(19, __VA_ARGS__) +#define BLE_MESH_RPL_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_MESH_RPL_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__) +#define BLE_MESH_RPL_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__) +#define BLE_MESH_RPL_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__) +#define BLE_MESH_RPL_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__) +#define BLE_MESH_RPL_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__) + #define BLE_MESH_SETTINGS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) #define BLE_MESH_SETTINGS_LOG_INFO(...) MODLOG_INFO(20, __VA_ARGS__) #define BLE_MESH_SETTINGS_LOG_WARN(...) MODLOG_WARN(20, __VA_ARGS__) @@ -106,34 +141,6 @@ #define BLE_MESH_TRANS_LOG_CRITICAL(...) MODLOG_CRITICAL(21, __VA_ARGS__) #define BLE_MESH_TRANS_LOG_DISABLED(...) MODLOG_DISABLED(21, __VA_ARGS__) -#define BLE_MESH_RPL_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_RPL_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__) -#define BLE_MESH_RPL_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__) -#define BLE_MESH_RPL_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__) -#define BLE_MESH_RPL_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__) -#define BLE_MESH_RPL_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__) - -#define BLE_MESH_NET_KEYS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_NET_KEYS_LOG_INFO(...) MODLOG_INFO(23, __VA_ARGS__) -#define BLE_MESH_NET_KEYS_LOG_WARN(...) MODLOG_WARN(23, __VA_ARGS__) -#define BLE_MESH_NET_KEYS_LOG_ERROR(...) MODLOG_ERROR(23, __VA_ARGS__) -#define BLE_MESH_NET_KEYS_LOG_CRITICAL(...) MODLOG_CRITICAL(23, __VA_ARGS__) -#define BLE_MESH_NET_KEYS_LOG_DISABLED(...) MODLOG_DISABLED(23, __VA_ARGS__) - -#define BLE_MESH_PROV_DEVICE_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_PROV_DEVICE_LOG_INFO(...) MODLOG_INFO(24, __VA_ARGS__) -#define BLE_MESH_PROV_DEVICE_LOG_WARN(...) MODLOG_WARN(24, __VA_ARGS__) -#define BLE_MESH_PROV_DEVICE_LOG_ERROR(...) MODLOG_ERROR(24, __VA_ARGS__) -#define BLE_MESH_PROV_DEVICE_LOG_CRITICAL(...) MODLOG_CRITICAL(24, __VA_ARGS__) -#define BLE_MESH_PROV_DEVICE_LOG_DISABLED(...) MODLOG_DISABLED(24, __VA_ARGS__) - -#define BLE_MESH_HEARTBEAT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_HEARTBEAT_LOG_INFO(...) MODLOG_INFO(25, __VA_ARGS__) -#define BLE_MESH_HEARTBEAT_LOG_WARN(...) MODLOG_WARN(25, __VA_ARGS__) -#define BLE_MESH_HEARTBEAT_LOG_ERROR(...) MODLOG_ERROR(25, __VA_ARGS__) -#define BLE_MESH_HEARTBEAT_LOG_CRITICAL(...) MODLOG_CRITICAL(25, __VA_ARGS__) -#define BLE_MESH_HEARTBEAT_LOG_DISABLED(...) MODLOG_DISABLED(25, __VA_ARGS__) - #define DFLT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) #define DFLT_LOG_INFO(...) MODLOG_INFO(0, __VA_ARGS__) #define DFLT_LOG_WARN(...) MODLOG_WARN(0, __VA_ARGS__) @@ -141,11 +148,4 @@ #define DFLT_LOG_CRITICAL(...) MODLOG_CRITICAL(0, __VA_ARGS__) #define DFLT_LOG_DISABLED(...) MODLOG_DISABLED(0, __VA_ARGS__) -#define MFG_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_INFO(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_WARN(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_ERROR(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_CRITICAL(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_DISABLED(...) MODLOG_DISABLED(128, __VA_ARGS__) - #endif diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 5d21359010..3f9258d896 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0-dev + * This file was generated by Apache newt version: 1.10.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -28,11 +28,20 @@ #define MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG (0) #endif +/*** @apache-mynewt-core/hw/bsp/native */ +#ifndef MYNEWT_VAL_BSP_SIMULATED +#define MYNEWT_VAL_BSP_SIMULATED (1) +#endif + /*** @apache-mynewt-core/hw/hal */ #ifndef MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS #define MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS (1) #endif +#ifndef MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT +#define MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT (0) +#endif + #ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ #define MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ (16) #endif @@ -45,10 +54,47 @@ #define MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES (0) #endif +#ifndef MYNEWT_VAL_HAL_SBRK +#define MYNEWT_VAL_HAL_SBRK (1) +#endif + #ifndef MYNEWT_VAL_HAL_SYSTEM_RESET_CB #define MYNEWT_VAL_HAL_SYSTEM_RESET_CB (0) #endif +/*** @apache-mynewt-core/hw/mcu/native */ +#ifndef MYNEWT_VAL_I2C_0 +#define MYNEWT_VAL_I2C_0 (0) +#endif + +#ifndef MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE +#define MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE (1) +#endif + +#ifndef MYNEWT_VAL_MCU_FLASH_STYLE_NORDIC +#define MYNEWT_VAL_MCU_FLASH_STYLE_NORDIC (0) +#endif + +#ifndef MYNEWT_VAL_MCU_FLASH_STYLE_ST +#define MYNEWT_VAL_MCU_FLASH_STYLE_ST (1) +#endif + +#ifndef MYNEWT_VAL_MCU_NATIVE +#define MYNEWT_VAL_MCU_NATIVE (1) +#endif + +#ifndef MYNEWT_VAL_MCU_NATIVE_USE_SIGNALS +#define MYNEWT_VAL_MCU_NATIVE_USE_SIGNALS (1) +#endif + +#ifndef MYNEWT_VAL_MCU_TIMER_POLLER_PRIO +#define MYNEWT_VAL_MCU_TIMER_POLLER_PRIO (0) +#endif + +#ifndef MYNEWT_VAL_MCU_UART_POLLER_PRIO +#define MYNEWT_VAL_MCU_UART_POLLER_PRIO (1) +#endif + /*** @apache-mynewt-core/kernel/os */ #ifndef MYNEWT_VAL_FLOAT_USER #define MYNEWT_VAL_FLOAT_USER (0) @@ -95,6 +141,10 @@ #define MYNEWT_VAL_OS_COREDUMP (0) #endif +#ifndef MYNEWT_VAL_OS_COREDUMP_CB +#define MYNEWT_VAL_OS_COREDUMP_CB (0) +#endif + #ifndef MYNEWT_VAL_OS_CPUTIME_FREQ #define MYNEWT_VAL_OS_CPUTIME_FREQ (1000000) #endif @@ -103,8 +153,9 @@ #define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (0) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_CRASH_FILE_LINE -#define MYNEWT_VAL_OS_CRASH_FILE_LINE (0) +#define MYNEWT_VAL_OS_CRASH_FILE_LINE (1) #endif #ifndef MYNEWT_VAL_OS_CRASH_LOG @@ -143,8 +194,9 @@ #define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX (600000) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN -#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (100) +#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (1) #endif #ifndef MYNEWT_VAL_OS_MAIN_STACK_SIZE @@ -211,6 +263,11 @@ #define MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME (0) #endif +/* Overridden by @apache-mynewt-core/hw/mcu/native (defined by @apache-mynewt-core/kernel/os) */ +#ifndef MYNEWT_VAL_OS_TICKS_PER_SEC +#define MYNEWT_VAL_OS_TICKS_PER_SEC (100) +#endif + #ifndef MYNEWT_VAL_OS_TIME_DEBUG #define MYNEWT_VAL_OS_TIME_DEBUG (0) #endif @@ -227,6 +284,33 @@ #define MYNEWT_VAL_WATCHDOG_INTERVAL (30000) #endif +/*** @apache-mynewt-core/net/ip/native_sockets */ +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX +#define MYNEWT_VAL_NATIVE_SOCKETS_MAX (8) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX_UDP +#define MYNEWT_VAL_NATIVE_SOCKETS_MAX_UDP (2048) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_POLL_INTERVAL_MS +#define MYNEWT_VAL_NATIVE_SOCKETS_POLL_INTERVAL_MS (200) +#endif + +#undef MYNEWT_VAL_NATIVE_SOCKETS_POLL_ITVL + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_PRIO +#define MYNEWT_VAL_NATIVE_SOCKETS_PRIO (2) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_STACK_SZ +#define MYNEWT_VAL_NATIVE_SOCKETS_STACK_SZ (4096) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE +#define MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE (200) +#endif + /*** @apache-mynewt-core/sys/console/stub */ #ifndef MYNEWT_VAL_CONSOLE_UART_BAUD #define MYNEWT_VAL_CONSOLE_UART_BAUD (115200) @@ -245,8 +329,12 @@ #define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10) #endif +#ifndef MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG +#define MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG (0) +#endif + #ifndef MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE -#define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (2) +#define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (9) #endif /*** @apache-mynewt-core/sys/log/common */ @@ -301,23 +389,6 @@ #define MYNEWT_VAL_LOG_LEVEL (0) #endif -/*** @apache-mynewt-core/sys/mfg */ -#ifndef MYNEWT_VAL_MFG_LOG_LVL -#define MYNEWT_VAL_MFG_LOG_LVL (15) -#endif - -#ifndef MYNEWT_VAL_MFG_LOG_MODULE -#define MYNEWT_VAL_MFG_LOG_MODULE (128) -#endif - -#ifndef MYNEWT_VAL_MFG_MAX_MMRS -#define MYNEWT_VAL_MFG_MAX_MMRS (2) -#endif - -#ifndef MYNEWT_VAL_MFG_SYSINIT_STAGE -#define MYNEWT_VAL_MFG_SYSINIT_STAGE (100) -#endif - /*** @apache-mynewt-core/sys/sys */ #ifndef MYNEWT_VAL_DEBUG_PANIC_ENABLED #define MYNEWT_VAL_DEBUG_PANIC_ENABLED (1) @@ -345,12 +416,14 @@ #define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE -#define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (0) +#define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (1) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_MESSAGE -#define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (0) +#define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (1) #endif /*** @apache-mynewt-core/util/rwlock */ @@ -367,6 +440,10 @@ #define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (31) #endif +#ifndef MYNEWT_VAL_BLE_HCI_VS +#define MYNEWT_VAL_BLE_HCI_VS (0) +#endif + #ifndef MYNEWT_VAL_BLE_ISO #define MYNEWT_VAL_BLE_ISO (0) #endif @@ -738,16 +815,16 @@ #define MYNEWT_VAL_BLE_SM_SC (1) #endif -#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY -#define MYNEWT_VAL_BLE_SM_SC_ONLY (0) +#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS +#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif #ifndef MYNEWT_VAL_BLE_SM_SC_LVL #define MYNEWT_VAL_BLE_SM_SC_LVL (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS -#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) +#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY +#define MYNEWT_VAL_BLE_SM_SC_ONLY (0) #endif #ifndef MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST @@ -763,6 +840,10 @@ #endif /*** @apache-mynewt-nimble/nimble/host/mesh */ +#ifndef MYNEWT_VAL_BLE_MESH_ACCESS_LAYER_MSG +#define MYNEWT_VAL_BLE_MESH_ACCESS_LAYER_MSG (1) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_ACCESS_LOG_LVL #define MYNEWT_VAL_BLE_MESH_ACCESS_LOG_LVL (1) #endif @@ -771,15 +852,23 @@ #define MYNEWT_VAL_BLE_MESH_ACCESS_LOG_MOD (10) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ -#ifndef MYNEWT_VAL_BLE_MESH_NET_BUF_USER_DATA_SIZE -#define MYNEWT_VAL_BLE_MESH_NET_BUF_USER_DATA_SIZE (4) +#ifndef MYNEWT_VAL_BLE_MESH_ADV +#define MYNEWT_VAL_BLE_MESH_ADV (1) #endif +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT #define MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT (20) #endif +#ifndef MYNEWT_VAL_BLE_MESH_ADV_EXT +#define MYNEWT_VAL_BLE_MESH_ADV_EXT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ADV_LEGACY +#define MYNEWT_VAL_BLE_MESH_ADV_LEGACY (1) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_ADV_LOG_LVL #define MYNEWT_VAL_BLE_MESH_ADV_LOG_LVL (1) #endif @@ -788,6 +877,10 @@ #define MYNEWT_VAL_BLE_MESH_ADV_LOG_MOD (11) #endif +#ifndef MYNEWT_VAL_BLE_MESH_ADV_STACK_SIZE +#define MYNEWT_VAL_BLE_MESH_ADV_STACK_SIZE (768) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_ADV_TASK_PRIO #define MYNEWT_VAL_BLE_MESH_ADV_TASK_PRIO (9) #endif @@ -797,6 +890,10 @@ #define MYNEWT_VAL_BLE_MESH_APP_KEY_COUNT (4) #endif +#ifndef MYNEWT_VAL_BLE_MESH_BEACON_ENABLED +#define MYNEWT_VAL_BLE_MESH_BEACON_ENABLED (1) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_BEACON_LOG_LVL #define MYNEWT_VAL_BLE_MESH_BEACON_LOG_LVL (1) #endif @@ -805,6 +902,22 @@ #define MYNEWT_VAL_BLE_MESH_BEACON_LOG_MOD (12) #endif +#ifndef MYNEWT_VAL_BLE_MESH_CDB +#define MYNEWT_VAL_BLE_MESH_CDB (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_CDB_APP_KEY_COUNT +#define MYNEWT_VAL_BLE_MESH_CDB_APP_KEY_COUNT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_CDB_NODE_COUNT +#define MYNEWT_VAL_BLE_MESH_CDB_NODE_COUNT (8) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_CDB_SUBNET_COUNT +#define MYNEWT_VAL_BLE_MESH_CDB_SUBNET_COUNT (1) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_CFG_CLI #define MYNEWT_VAL_BLE_MESH_CFG_CLI (1) @@ -822,6 +935,22 @@ #define MYNEWT_VAL_BLE_MESH_CRYPTO_LOG_MOD (13) #endif +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_CDB +#define MYNEWT_VAL_BLE_MESH_DEBUG_CDB (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_CFG +#define MYNEWT_VAL_BLE_MESH_DEBUG_CFG (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_USE_ID_ADDR +#define MYNEWT_VAL_BLE_MESH_DEBUG_USE_ID_ADDR (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_DEFAULT_TTL +#define MYNEWT_VAL_BLE_MESH_DEFAULT_TTL (7) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_DEVICE_NAME #define MYNEWT_VAL_BLE_MESH_DEVICE_NAME ("nimble-mesh-node") #endif @@ -835,6 +964,10 @@ #define MYNEWT_VAL_BLE_MESH_FRIEND (1) #endif +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_ENABLED +#define MYNEWT_VAL_BLE_MESH_FRIEND_ENABLED (1) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_FRIEND_LOG_LVL #define MYNEWT_VAL_BLE_MESH_FRIEND_LOG_LVL (1) #endif @@ -863,19 +996,43 @@ #define MYNEWT_VAL_BLE_MESH_FRIEND_SUB_LIST_SIZE (3) #endif +#ifndef MYNEWT_VAL_BLE_MESH_GATT +#define MYNEWT_VAL_BLE_MESH_GATT (1) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_GATT_PROXY #define MYNEWT_VAL_BLE_MESH_GATT_PROXY (1) #endif +#ifndef MYNEWT_VAL_BLE_MESH_GATT_PROXY_ENABLED +#define MYNEWT_VAL_BLE_MESH_GATT_PROXY_ENABLED (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_GATT_SERVER +#define MYNEWT_VAL_BLE_MESH_GATT_SERVER (1) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_HEALTH_CLI #define MYNEWT_VAL_BLE_MESH_HEALTH_CLI (0) #endif +#ifndef MYNEWT_VAL_BLE_MESH_HEARTBEAT_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_HEARTBEAT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_HEARTBEAT_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_HEARTBEAT_LOG_MOD (26) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_IVU_DIVIDER #define MYNEWT_VAL_BLE_MESH_IVU_DIVIDER (4) #endif +#ifndef MYNEWT_VAL_BLE_MESH_IV_UPDATE_SEQ_LIMIT +#define MYNEWT_VAL_BLE_MESH_IV_UPDATE_SEQ_LIMIT (0x800000) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_IV_UPDATE_TEST #define MYNEWT_VAL_BLE_MESH_IV_UPDATE_TEST (1) @@ -894,6 +1051,10 @@ #define MYNEWT_VAL_BLE_MESH_LOG_MOD (9) #endif +#ifndef MYNEWT_VAL_BLE_MESH_LOOPBACK_BUFS +#define MYNEWT_VAL_BLE_MESH_LOOPBACK_BUFS (3) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_LOW_POWER #define MYNEWT_VAL_BLE_MESH_LOW_POWER (1) @@ -924,10 +1085,6 @@ #define MYNEWT_VAL_BLE_MESH_LPN_GROUPS (10) #endif -#ifndef MYNEWT_VAL_BLE_MESH_LPN_SUB_ALL_NODES_ADDR -#define MYNEWT_VAL_BLE_MESH_LPN_SUB_ALL_NODES_ADDR (1) -#endif - #ifndef MYNEWT_VAL_BLE_MESH_LPN_INIT_POLL_TIMEOUT #define MYNEWT_VAL_BLE_MESH_LPN_INIT_POLL_TIMEOUT (MYNEWT_VAL_BLE_MESH_LPN_POLL_TIMEOUT) #endif @@ -960,6 +1117,10 @@ #define MYNEWT_VAL_BLE_MESH_LPN_SCAN_LATENCY (10) #endif +#ifndef MYNEWT_VAL_BLE_MESH_LPN_SUB_ALL_NODES_ADDR +#define MYNEWT_VAL_BLE_MESH_LPN_SUB_ALL_NODES_ADDR (0) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_MODEL_EXTENSIONS #define MYNEWT_VAL_BLE_MESH_MODEL_EXTENSIONS (0) #endif @@ -981,10 +1142,35 @@ #define MYNEWT_VAL_BLE_MESH_MODEL_LOG_MOD (16) #endif +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_MODEL_VND_MSG_CID_FORCE +#define MYNEWT_VAL_BLE_MESH_MODEL_VND_MSG_CID_FORCE (1) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_MSG_CACHE_SIZE #define MYNEWT_VAL_BLE_MESH_MSG_CACHE_SIZE (10) #endif +#ifndef MYNEWT_VAL_BLE_MESH_NETWORK_TRANSMIT_COUNT +#define MYNEWT_VAL_BLE_MESH_NETWORK_TRANSMIT_COUNT (2) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_NETWORK_TRANSMIT_INTERVAL +#define MYNEWT_VAL_BLE_MESH_NETWORK_TRANSMIT_INTERVAL (20) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_NET_BUF_USER_DATA_SIZE +#define MYNEWT_VAL_BLE_MESH_NET_BUF_USER_DATA_SIZE (4) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_NET_KEYS_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_NET_KEYS_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_NET_KEYS_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_NET_KEYS_LOG_MOD (23) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_NET_LOG_LVL #define MYNEWT_VAL_BLE_MESH_NET_LOG_LVL (1) #endif @@ -993,10 +1179,6 @@ #define MYNEWT_VAL_BLE_MESH_NET_LOG_MOD (17) #endif -#ifndef MYNEWT_VAL_BLE_MESH_NODE_COUNT -#define MYNEWT_VAL_BLE_MESH_NODE_COUNT (1) -#endif - #ifndef MYNEWT_VAL_BLE_MESH_NODE_ID_TIMEOUT #define MYNEWT_VAL_BLE_MESH_NODE_ID_TIMEOUT (60) #endif @@ -1017,75 +1199,51 @@ #define MYNEWT_VAL_BLE_MESH_OOB_OUTPUT_SIZE (4) #endif -#ifndef MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN -#if MYNEWT_VAL_BLE_MESH_PB_GATT -#define MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN (66) -#elif MYNEWT_VAL_BLE_MESH_GATT_PROXY -#define MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN (33) -#endif -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_MODEL_VND_MSG_CID_FORCE -#define MYNEWT_VAL_BLE_MESH_MODEL_VND_MSG_CID_FORCE (1) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_ACCESS_LAYER_MSG -#define MYNEWT_VAL_BLE_MESH_ACCESS_LAYER_MSG (1) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_IV_UPDATE_SEQ_LIMIT -#define MYNEWT_VAL_BLE_MESH_IV_UPDATE_SEQ_LIMIT (0x800000) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_PROV_OOB_PUBLIC_KEY -#define MYNEWT_VAL_BLE_MESH_PROV_OOB_PUBLIC_KEY (0) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_ADV_EXT -#define MYNEWT_VAL_BLE_MESH_ADV_EXT (0) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_ADV_LEGACY -#define MYNEWT_VAL_BLE_MESH_ADV_LEGACY (1) -#endif - -#ifndef MYNEWT_VAL_BSP_NRF51 -#define MYNEWT_VAL_BSP_NRF51 (0) -#endif - /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_PB_ADV #define MYNEWT_VAL_BLE_MESH_PB_ADV (1) #endif +#ifndef MYNEWT_VAL_BLE_MESH_PB_ADV_RETRANS_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_PB_ADV_RETRANS_TIMEOUT (500) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_PB_GATT #define MYNEWT_VAL_BLE_MESH_PB_GATT (1) #endif +#ifndef MYNEWT_VAL_BLE_MESH_PB_GATT_USE_DEVICE_NAME +#define MYNEWT_VAL_BLE_MESH_PB_GATT_USE_DEVICE_NAME (1) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_PROV #define MYNEWT_VAL_BLE_MESH_PROV (1) #endif #ifndef MYNEWT_VAL_BLE_MESH_PROVISIONER -#define MYNEWT_VAL_BLE_MESH_PROVISIONER (0) +#define MYNEWT_VAL_BLE_MESH_PROVISIONER (1) #endif -#ifndef MYNEWT_VAL_BLE_MESH_CDB -#define MYNEWT_VAL_BLE_MESH_CDB (0) +#ifndef MYNEWT_VAL_BLE_MESH_PROVISIONER_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_PROVISIONER_LOG_LVL (1) #endif -#ifndef MYNEWT_VAL_BLE_MESH_CDB_SUBNET_COUNT -#define MYNEWT_VAL_BLE_MESH_CDB_SUBNET_COUNT (1) +#ifndef MYNEWT_VAL_BLE_MESH_PROVISIONER_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_PROVISIONER_LOG_MOD (25) #endif -#ifndef MYNEWT_VAL_BLE_MESH_CDB_NODE_COUNT -#define MYNEWT_VAL_BLE_MESH_CDB_NODE_COUNT (8) +#ifndef MYNEWT_VAL_BLE_MESH_PROV_DEVICE +#define MYNEWT_VAL_BLE_MESH_PROV_DEVICE (1) #endif -#ifndef MYNEWT_VAL_BLE_MESH_CDB_APP_KEY_COUNT -#define MYNEWT_VAL_BLE_MESH_CDB_APP_KEY_COUNT (1) +#ifndef MYNEWT_VAL_BLE_MESH_PROV_DEVICE_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_PROV_DEVICE_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROV_DEVICE_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_PROV_DEVICE_LOG_MOD (24) #endif #ifndef MYNEWT_VAL_BLE_MESH_PROV_LOG_LVL @@ -1096,13 +1254,17 @@ #define MYNEWT_VAL_BLE_MESH_PROV_LOG_MOD (18) #endif +#ifndef MYNEWT_VAL_BLE_MESH_PROV_OOB_PUBLIC_KEY +#define MYNEWT_VAL_BLE_MESH_PROV_OOB_PUBLIC_KEY (0) +#endif + /* Overridden by @apache-mynewt-nimble/nimble/host/mesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_PROXY #define MYNEWT_VAL_BLE_MESH_PROXY (1) #endif #ifndef MYNEWT_VAL_BLE_MESH_PROXY_FILTER_SIZE -#define MYNEWT_VAL_BLE_MESH_PROXY_FILTER_SIZE (1) +#define MYNEWT_VAL_BLE_MESH_PROXY_FILTER_SIZE (3) #endif #ifndef MYNEWT_VAL_BLE_MESH_PROXY_LOG_LVL @@ -1113,17 +1275,43 @@ #define MYNEWT_VAL_BLE_MESH_PROXY_LOG_MOD (19) #endif +/* Overridden by @apache-mynewt-nimble/nimble/host/mesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN +#define MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN (66) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROXY_USE_DEVICE_NAME +#define MYNEWT_VAL_BLE_MESH_PROXY_USE_DEVICE_NAME (0) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_RELAY #define MYNEWT_VAL_BLE_MESH_RELAY (1) #endif -#ifndef MYNEWT_VAL_BLE_MESH_RPL_STORE_TIMEOUT -#define MYNEWT_VAL_BLE_MESH_RPL_STORE_TIMEOUT (5) +/* Value copied from BLE_MESH_RELAY */ +#ifndef MYNEWT_VAL_BLE_MESH_RELAY_ENABLED +#define MYNEWT_VAL_BLE_MESH_RELAY_ENABLED (1) #endif -#ifndef MYNEWT_VAL_BLE_MESH_SEG_BUFS -#define MYNEWT_VAL_BLE_MESH_SEG_BUFS (72) +#ifndef MYNEWT_VAL_BLE_MESH_RELAY_RETRANSMIT_COUNT +#define MYNEWT_VAL_BLE_MESH_RELAY_RETRANSMIT_COUNT (2) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_RELAY_RETRANSMIT_INTERVAL +#define MYNEWT_VAL_BLE_MESH_RELAY_RETRANSMIT_INTERVAL (20) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_RPL_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_RPL_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_RPL_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_RPL_LOG_MOD (22) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_RPL_STORE_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_RPL_STORE_TIMEOUT (5) #endif #ifndef MYNEWT_VAL_BLE_MESH_RX_SEG_MAX @@ -1134,6 +1322,10 @@ #define MYNEWT_VAL_BLE_MESH_RX_SEG_MSG_COUNT (2) #endif +#ifndef MYNEWT_VAL_BLE_MESH_SEG_BUFS +#define MYNEWT_VAL_BLE_MESH_SEG_BUFS (64) +#endif + #ifndef MYNEWT_VAL_BLE_MESH_SEG_RETRANSMIT_ATTEMPTS #define MYNEWT_VAL_BLE_MESH_SEG_RETRANSMIT_ATTEMPTS (4) #endif @@ -1194,90 +1386,29 @@ #define MYNEWT_VAL_BLE_MESH_TRANS_LOG_MOD (21) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ -#ifndef MYNEWT_VAL_BLE_MESH_RPL_LOG_LVL -#define MYNEWT_VAL_BLE_MESH_RPL_LOG_LVL (1) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_RPL_LOG_MOD -#define MYNEWT_VAL_BLE_MESH_RPL_LOG_MOD (22) -#endif - /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_MAX #define MYNEWT_VAL_BLE_MESH_TX_SEG_MAX (6) #endif -#ifndef MYNEWT_VAL_BLE_MESH_RX_SEG_MSG_COUNT -#define MYNEWT_VAL_BLE_MESH_RX_SEG_MSG_COUNT (3) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_UNPROV_BEACON_INT -#define MYNEWT_VAL_BLE_MESH_UNPROV_BEACON_INT (5) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_PB_ADV_RETRANS_TIMEOUT -#define MYNEWT_VAL_BLE_MESH_PB_ADV_RETRANS_TIMEOUT (500) -#endif - #ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_MSG_COUNT -#define MYNEWT_VAL_BLE_MESH_TX_SEG_MSG_COUNT (4) +#define MYNEWT_VAL_BLE_MESH_TX_SEG_MSG_COUNT (1) #endif #ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_RETRANS_COUNT #define MYNEWT_VAL_BLE_MESH_TX_SEG_RETRANS_COUNT (4) #endif -#ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_RETRANS_TIMEOUT_UNICAST -#define MYNEWT_VAL_BLE_MESH_TX_SEG_RETRANS_TIMEOUT_UNICAST (400) -#endif - #ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_RETRANS_TIMEOUT_GROUP #define MYNEWT_VAL_BLE_MESH_TX_SEG_RETRANS_TIMEOUT_GROUP (50) #endif -#ifndef MYNEWT_VAL_BLE_MESH_LOOPBACK_BUFS -#define MYNEWT_VAL_BLE_MESH_LOOPBACK_BUFS (3) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_DEFAULT_TTL -#define MYNEWT_VAL_BLE_MESH_DEFAULT_TTL (7) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_NETWORK_TRANSMIT_COUNT -#define MYNEWT_VAL_BLE_MESH_NETWORK_TRANSMIT_COUNT (2) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_NETWORK_TRANSMIT_INTERVAL -#define MYNEWT_VAL_BLE_MESH_NETWORK_TRANSMIT_INTERVAL (20) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_RELAY_RETRANSMIT_COUNT -#define MYNEWT_VAL_BLE_MESH_RELAY_RETRANSMIT_COUNT (2) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_BEACON_ENABLED -#define MYNEWT_VAL_BLE_MESH_BEACON_ENABLED (1) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_GATT_PROXY_ENABLED -#define MYNEWT_VAL_BLE_MESH_GATT_PROXY_ENABLED (1) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_GATT_SERVER -#define MYNEWT_VAL_BLE_MESH_GATT_SERVER (1) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_ENABLED -#define MYNEWT_VAL_BLE_MESH_FRIEND_ENABLED (1) -#endif - -#ifndef MYNEWT_VAL_BLE_MESH_RELAY_ENABLED -#define MYNEWT_VAL_BLE_MESH_RELAY_ENABLED (1) +#ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_RETRANS_TIMEOUT_UNICAST +#define MYNEWT_VAL_BLE_MESH_TX_SEG_RETRANS_TIMEOUT_UNICAST (400) #endif -#ifndef MYNEWT_VAL_BLE_MESH_RELAY_RETRANSMIT_INTERVAL -#define MYNEWT_VAL_BLE_MESH_RELAY_RETRANSMIT_INTERVAL (20) +#ifndef MYNEWT_VAL_BLE_MESH_UNPROV_BEACON_INT +#define MYNEWT_VAL_BLE_MESH_UNPROV_BEACON_INT (5) #endif /*** @apache-mynewt-nimble/nimble/host/services/ans */ @@ -1514,19 +1645,19 @@ #endif #ifndef MYNEWT_VAL_ARCH_NAME -#define MYNEWT_VAL_ARCH_NAME ("dummy") +#define MYNEWT_VAL_ARCH_NAME ("sim") #endif -#ifndef MYNEWT_VAL_ARCH_dummy -#define MYNEWT_VAL_ARCH_dummy (1) +#ifndef MYNEWT_VAL_ARCH_sim +#define MYNEWT_VAL_ARCH_sim (1) #endif #ifndef MYNEWT_VAL_BSP_NAME -#define MYNEWT_VAL_BSP_NAME ("dummy_bsp") +#define MYNEWT_VAL_BSP_NAME ("native") #endif -#ifndef MYNEWT_VAL_BSP_dummy_bsp -#define MYNEWT_VAL_BSP_dummy_bsp (1) +#ifndef MYNEWT_VAL_BSP_native +#define MYNEWT_VAL_BSP_native (1) #endif #ifndef MYNEWT_VAL_NEWT_FEATURE_LOGCFG diff --git a/porting/examples/linux_blemesh/include/sysflash/sysflash.h b/porting/examples/linux_blemesh/include/sysflash/sysflash.h index ab1341b25d..28391ca66a 100644 --- a/porting/examples/linux_blemesh/include/sysflash/sysflash.h +++ b/porting/examples/linux_blemesh/include/sysflash/sysflash.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0-dev + * This file was generated by Apache newt version: 1.10.0-dev */ #ifndef H_MYNEWT_SYSFLASH_ diff --git a/porting/examples/nuttx/include/logcfg/logcfg.h b/porting/examples/nuttx/include/logcfg/logcfg.h index 837cdeac1f..fab4d812fc 100644 --- a/porting/examples/nuttx/include/logcfg/logcfg.h +++ b/porting/examples/nuttx/include/logcfg/logcfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0-dev + * This file was generated by Apache newt version: 1.10.0-dev */ #ifndef H_MYNEWT_LOGCFG_ @@ -22,11 +22,4 @@ #define DFLT_LOG_CRITICAL(...) MODLOG_CRITICAL(0, __VA_ARGS__) #define DFLT_LOG_DISABLED(...) MODLOG_DISABLED(0, __VA_ARGS__) -#define MFG_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_INFO(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_WARN(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_ERROR(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_CRITICAL(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_DISABLED(...) MODLOG_DISABLED(128, __VA_ARGS__) - #endif diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index c8ad4e4976..1f5be13597 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0-dev + * This file was generated by Apache newt version: 1.10.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -15,86 +15,84 @@ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val - -/*** Repository @apache-mynewt-core info */ -#ifndef MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_CORE -#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_CORE ("4d75fc41bd7ead84638ebbfad4841d5effb296dd") +/*** @apache-mynewt-core/crypto/tinycrypt */ +#ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE +#define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) #endif -#ifndef MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_CORE -#define MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_CORE ("0.0.1") +#ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME +#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME ("trng") #endif -/*** Repository @apache-mynewt-mcumgr info */ -#ifndef MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_MCUMGR -#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_MCUMGR ("8d087a7e0e5485394419d10051606c92d68d2111") +#ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG +#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG (0) #endif -#ifndef MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_MCUMGR -#define MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_MCUMGR ("0.0.0") +/*** @apache-mynewt-core/hw/bsp/native */ +#ifndef MYNEWT_VAL_BSP_SIMULATED +#define MYNEWT_VAL_BSP_SIMULATED (1) #endif -/*** Repository @apache-mynewt-nimble info */ -#ifndef MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_NIMBLE -#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_NIMBLE ("37dceb35df57ff41a6c31f79290512df2fde7064") +/*** @apache-mynewt-core/hw/hal */ +#ifndef MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS +#define MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS (1) #endif -#ifndef MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_NIMBLE -#define MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_NIMBLE ("0.0.0") +#ifndef MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT +#define MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT (0) #endif -/*** Repository @mcuboot info */ -#ifndef MYNEWT_VAL_REPO_HASH_MCUBOOT -#define MYNEWT_VAL_REPO_HASH_MCUBOOT ("03d96ad1f6dd77d47ffca72ade9377acb8559115-dirty") +#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ +#define MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ (16) #endif -#ifndef MYNEWT_VAL_REPO_VERSION_MCUBOOT -#define MYNEWT_VAL_REPO_VERSION_MCUBOOT ("0.0.0") +#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_ERASES +#define MYNEWT_VAL_HAL_FLASH_VERIFY_ERASES (0) #endif -/*** Repository @my_project info */ -#ifndef MYNEWT_VAL_REPO_HASH_MY_PROJECT -#define MYNEWT_VAL_REPO_HASH_MY_PROJECT ("37dceb35df57ff41a6c31f79290512df2fde7064") +#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES +#define MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES (0) #endif -#ifndef MYNEWT_VAL_REPO_VERSION_MY_PROJECT -#define MYNEWT_VAL_REPO_VERSION_MY_PROJECT ("0.0.0") +#ifndef MYNEWT_VAL_HAL_SBRK +#define MYNEWT_VAL_HAL_SBRK (1) #endif +#ifndef MYNEWT_VAL_HAL_SYSTEM_RESET_CB +#define MYNEWT_VAL_HAL_SYSTEM_RESET_CB (0) +#endif - -/*** @apache-mynewt-core/crypto/tinycrypt */ -#ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE -#define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) +/*** @apache-mynewt-core/hw/mcu/native */ +#ifndef MYNEWT_VAL_I2C_0 +#define MYNEWT_VAL_I2C_0 (0) #endif -#ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME -#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME ("trng") +#ifndef MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE +#define MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE (1) #endif -#ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG -#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG (0) +#ifndef MYNEWT_VAL_MCU_FLASH_STYLE_NORDIC +#define MYNEWT_VAL_MCU_FLASH_STYLE_NORDIC (0) #endif -/*** @apache-mynewt-core/hw/hal */ -#ifndef MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS -#define MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS (1) +#ifndef MYNEWT_VAL_MCU_FLASH_STYLE_ST +#define MYNEWT_VAL_MCU_FLASH_STYLE_ST (1) #endif -#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ -#define MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ (16) +#ifndef MYNEWT_VAL_MCU_NATIVE +#define MYNEWT_VAL_MCU_NATIVE (1) #endif -#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_ERASES -#define MYNEWT_VAL_HAL_FLASH_VERIFY_ERASES (0) +#ifndef MYNEWT_VAL_MCU_NATIVE_USE_SIGNALS +#define MYNEWT_VAL_MCU_NATIVE_USE_SIGNALS (1) #endif -#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES -#define MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES (0) +#ifndef MYNEWT_VAL_MCU_TIMER_POLLER_PRIO +#define MYNEWT_VAL_MCU_TIMER_POLLER_PRIO (0) #endif -#ifndef MYNEWT_VAL_HAL_SYSTEM_RESET_CB -#define MYNEWT_VAL_HAL_SYSTEM_RESET_CB (0) +#ifndef MYNEWT_VAL_MCU_UART_POLLER_PRIO +#define MYNEWT_VAL_MCU_UART_POLLER_PRIO (1) #endif /*** @apache-mynewt-core/kernel/os */ @@ -142,6 +140,10 @@ #define MYNEWT_VAL_OS_COREDUMP (0) #endif +#ifndef MYNEWT_VAL_OS_COREDUMP_CB +#define MYNEWT_VAL_OS_COREDUMP_CB (0) +#endif + #ifndef MYNEWT_VAL_OS_CPUTIME_FREQ #define MYNEWT_VAL_OS_CPUTIME_FREQ (1000000) #endif @@ -150,8 +152,9 @@ #define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (0) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_CRASH_FILE_LINE -#define MYNEWT_VAL_OS_CRASH_FILE_LINE (0) +#define MYNEWT_VAL_OS_CRASH_FILE_LINE (1) #endif #ifndef MYNEWT_VAL_OS_CRASH_LOG @@ -190,8 +193,9 @@ #define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX (600000) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN -#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (100) +#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (1) #endif #ifndef MYNEWT_VAL_OS_MAIN_STACK_SIZE @@ -258,6 +262,11 @@ #define MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME (0) #endif +/* Overridden by @apache-mynewt-core/hw/mcu/native (defined by @apache-mynewt-core/kernel/os) */ +#ifndef MYNEWT_VAL_OS_TICKS_PER_SEC +#define MYNEWT_VAL_OS_TICKS_PER_SEC (100) +#endif + #ifndef MYNEWT_VAL_OS_TIME_DEBUG #define MYNEWT_VAL_OS_TIME_DEBUG (0) #endif @@ -274,6 +283,33 @@ #define MYNEWT_VAL_WATCHDOG_INTERVAL (30000) #endif +/*** @apache-mynewt-core/net/ip/native_sockets */ +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX +#define MYNEWT_VAL_NATIVE_SOCKETS_MAX (8) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX_UDP +#define MYNEWT_VAL_NATIVE_SOCKETS_MAX_UDP (2048) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_POLL_INTERVAL_MS +#define MYNEWT_VAL_NATIVE_SOCKETS_POLL_INTERVAL_MS (200) +#endif + +#undef MYNEWT_VAL_NATIVE_SOCKETS_POLL_ITVL + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_PRIO +#define MYNEWT_VAL_NATIVE_SOCKETS_PRIO (2) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_STACK_SZ +#define MYNEWT_VAL_NATIVE_SOCKETS_STACK_SZ (4096) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE +#define MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE (200) +#endif + /*** @apache-mynewt-core/sys/console/stub */ #ifndef MYNEWT_VAL_CONSOLE_UART_BAUD #define MYNEWT_VAL_CONSOLE_UART_BAUD (115200) @@ -292,8 +328,12 @@ #define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10) #endif +#ifndef MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG +#define MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG (0) +#endif + #ifndef MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE -#define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (2) +#define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (9) #endif /*** @apache-mynewt-core/sys/log/common */ @@ -348,23 +388,6 @@ #define MYNEWT_VAL_LOG_LEVEL (2) #endif -/*** @apache-mynewt-core/sys/mfg */ -#ifndef MYNEWT_VAL_MFG_LOG_LVL -#define MYNEWT_VAL_MFG_LOG_LVL (15) -#endif - -#ifndef MYNEWT_VAL_MFG_LOG_MODULE -#define MYNEWT_VAL_MFG_LOG_MODULE (128) -#endif - -#ifndef MYNEWT_VAL_MFG_MAX_MMRS -#define MYNEWT_VAL_MFG_MAX_MMRS (2) -#endif - -#ifndef MYNEWT_VAL_MFG_SYSINIT_STAGE -#define MYNEWT_VAL_MFG_SYSINIT_STAGE (100) -#endif - /*** @apache-mynewt-core/sys/sys */ #ifndef MYNEWT_VAL_DEBUG_PANIC_ENABLED #define MYNEWT_VAL_DEBUG_PANIC_ENABLED (1) @@ -392,12 +415,14 @@ #define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE -#define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (0) +#define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (1) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_MESSAGE -#define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (0) +#define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (1) #endif /*** @apache-mynewt-core/util/rwlock */ @@ -414,6 +439,10 @@ #define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (31) #endif +#ifndef MYNEWT_VAL_BLE_HCI_VS +#define MYNEWT_VAL_BLE_HCI_VS (0) +#endif + #ifndef MYNEWT_VAL_BLE_ISO #define MYNEWT_VAL_BLE_ISO (0) #endif @@ -785,16 +814,16 @@ #define MYNEWT_VAL_BLE_SM_SC (1) #endif -#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY -#define MYNEWT_VAL_BLE_SM_SC_ONLY (0) +#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS +#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif #ifndef MYNEWT_VAL_BLE_SM_SC_LVL #define MYNEWT_VAL_BLE_SM_SC_LVL (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS -#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) +#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY +#define MYNEWT_VAL_BLE_SM_SC_ONLY (0) #endif #ifndef MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST @@ -1023,16 +1052,10 @@ #define MYNEWT_VAL_BLE_SOCK_TCP_PORT (14433) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE #define MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/transport/socket) */ -#ifndef MYNEWT_VAL_BLE_SOCK_USE_NUTTX -#define MYNEWT_VAL_BLE_SOCK_USE_NUTTX (1) -#endif - /* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_TCP #define MYNEWT_VAL_BLE_SOCK_USE_TCP (0) @@ -1048,19 +1071,19 @@ #endif #ifndef MYNEWT_VAL_ARCH_NAME -#define MYNEWT_VAL_ARCH_NAME ("dummy") +#define MYNEWT_VAL_ARCH_NAME ("sim") #endif -#ifndef MYNEWT_VAL_ARCH_dummy -#define MYNEWT_VAL_ARCH_dummy (1) +#ifndef MYNEWT_VAL_ARCH_sim +#define MYNEWT_VAL_ARCH_sim (1) #endif #ifndef MYNEWT_VAL_BSP_NAME -#define MYNEWT_VAL_BSP_NAME ("dummy_bsp") +#define MYNEWT_VAL_BSP_NAME ("native") #endif -#ifndef MYNEWT_VAL_BSP_dummy_bsp -#define MYNEWT_VAL_BSP_dummy_bsp (1) +#ifndef MYNEWT_VAL_BSP_native +#define MYNEWT_VAL_BSP_native (1) #endif #ifndef MYNEWT_VAL_NEWT_FEATURE_LOGCFG diff --git a/porting/examples/nuttx/include/sysflash/sysflash.h b/porting/examples/nuttx/include/sysflash/sysflash.h index ab1341b25d..28391ca66a 100644 --- a/porting/examples/nuttx/include/sysflash/sysflash.h +++ b/porting/examples/nuttx/include/sysflash/sysflash.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0-dev + * This file was generated by Apache newt version: 1.10.0-dev */ #ifndef H_MYNEWT_SYSFLASH_ diff --git a/porting/nimble/include/logcfg/logcfg.h b/porting/nimble/include/logcfg/logcfg.h index 837cdeac1f..fab4d812fc 100644 --- a/porting/nimble/include/logcfg/logcfg.h +++ b/porting/nimble/include/logcfg/logcfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0-dev + * This file was generated by Apache newt version: 1.10.0-dev */ #ifndef H_MYNEWT_LOGCFG_ @@ -22,11 +22,4 @@ #define DFLT_LOG_CRITICAL(...) MODLOG_CRITICAL(0, __VA_ARGS__) #define DFLT_LOG_DISABLED(...) MODLOG_DISABLED(0, __VA_ARGS__) -#define MFG_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_INFO(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_WARN(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_ERROR(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_CRITICAL(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_DISABLED(...) MODLOG_DISABLED(128, __VA_ARGS__) - #endif diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index cfc10edb54..a16c528191 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0-dev + * This file was generated by Apache newt version: 1.10.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -28,11 +28,20 @@ #define MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG (0) #endif +/*** @apache-mynewt-core/hw/bsp/native */ +#ifndef MYNEWT_VAL_BSP_SIMULATED +#define MYNEWT_VAL_BSP_SIMULATED (1) +#endif + /*** @apache-mynewt-core/hw/hal */ #ifndef MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS #define MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS (1) #endif +#ifndef MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT +#define MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT (0) +#endif + #ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ #define MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ (16) #endif @@ -45,10 +54,47 @@ #define MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES (0) #endif +#ifndef MYNEWT_VAL_HAL_SBRK +#define MYNEWT_VAL_HAL_SBRK (1) +#endif + #ifndef MYNEWT_VAL_HAL_SYSTEM_RESET_CB #define MYNEWT_VAL_HAL_SYSTEM_RESET_CB (0) #endif +/*** @apache-mynewt-core/hw/mcu/native */ +#ifndef MYNEWT_VAL_I2C_0 +#define MYNEWT_VAL_I2C_0 (0) +#endif + +#ifndef MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE +#define MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE (1) +#endif + +#ifndef MYNEWT_VAL_MCU_FLASH_STYLE_NORDIC +#define MYNEWT_VAL_MCU_FLASH_STYLE_NORDIC (0) +#endif + +#ifndef MYNEWT_VAL_MCU_FLASH_STYLE_ST +#define MYNEWT_VAL_MCU_FLASH_STYLE_ST (1) +#endif + +#ifndef MYNEWT_VAL_MCU_NATIVE +#define MYNEWT_VAL_MCU_NATIVE (1) +#endif + +#ifndef MYNEWT_VAL_MCU_NATIVE_USE_SIGNALS +#define MYNEWT_VAL_MCU_NATIVE_USE_SIGNALS (1) +#endif + +#ifndef MYNEWT_VAL_MCU_TIMER_POLLER_PRIO +#define MYNEWT_VAL_MCU_TIMER_POLLER_PRIO (0) +#endif + +#ifndef MYNEWT_VAL_MCU_UART_POLLER_PRIO +#define MYNEWT_VAL_MCU_UART_POLLER_PRIO (1) +#endif + /*** @apache-mynewt-core/kernel/os */ #ifndef MYNEWT_VAL_FLOAT_USER #define MYNEWT_VAL_FLOAT_USER (0) @@ -94,6 +140,10 @@ #define MYNEWT_VAL_OS_COREDUMP (0) #endif +#ifndef MYNEWT_VAL_OS_COREDUMP_CB +#define MYNEWT_VAL_OS_COREDUMP_CB (0) +#endif + #ifndef MYNEWT_VAL_OS_CPUTIME_FREQ #define MYNEWT_VAL_OS_CPUTIME_FREQ (1000000) #endif @@ -102,8 +152,9 @@ #define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (0) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_CRASH_FILE_LINE -#define MYNEWT_VAL_OS_CRASH_FILE_LINE (0) +#define MYNEWT_VAL_OS_CRASH_FILE_LINE (1) #endif #ifndef MYNEWT_VAL_OS_CRASH_LOG @@ -142,8 +193,9 @@ #define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX (600000) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN -#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (100) +#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (1) #endif #ifndef MYNEWT_VAL_OS_MAIN_STACK_SIZE @@ -210,6 +262,11 @@ #define MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME (0) #endif +/* Overridden by @apache-mynewt-core/hw/mcu/native (defined by @apache-mynewt-core/kernel/os) */ +#ifndef MYNEWT_VAL_OS_TICKS_PER_SEC +#define MYNEWT_VAL_OS_TICKS_PER_SEC (100) +#endif + #ifndef MYNEWT_VAL_OS_TIME_DEBUG #define MYNEWT_VAL_OS_TIME_DEBUG (0) #endif @@ -226,6 +283,33 @@ #define MYNEWT_VAL_WATCHDOG_INTERVAL (30000) #endif +/*** @apache-mynewt-core/net/ip/native_sockets */ +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX +#define MYNEWT_VAL_NATIVE_SOCKETS_MAX (8) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX_UDP +#define MYNEWT_VAL_NATIVE_SOCKETS_MAX_UDP (2048) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_POLL_INTERVAL_MS +#define MYNEWT_VAL_NATIVE_SOCKETS_POLL_INTERVAL_MS (200) +#endif + +#undef MYNEWT_VAL_NATIVE_SOCKETS_POLL_ITVL + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_PRIO +#define MYNEWT_VAL_NATIVE_SOCKETS_PRIO (2) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_STACK_SZ +#define MYNEWT_VAL_NATIVE_SOCKETS_STACK_SZ (4096) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE +#define MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE (200) +#endif + /*** @apache-mynewt-core/sys/console/stub */ #ifndef MYNEWT_VAL_CONSOLE_UART_BAUD #define MYNEWT_VAL_CONSOLE_UART_BAUD (115200) @@ -244,8 +328,12 @@ #define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10) #endif +#ifndef MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG +#define MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG (0) +#endif + #ifndef MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE -#define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (2) +#define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (9) #endif /*** @apache-mynewt-core/sys/log/common */ @@ -299,23 +387,6 @@ #define MYNEWT_VAL_LOG_LEVEL (255) #endif -/*** @apache-mynewt-core/sys/mfg */ -#ifndef MYNEWT_VAL_MFG_LOG_LVL -#define MYNEWT_VAL_MFG_LOG_LVL (15) -#endif - -#ifndef MYNEWT_VAL_MFG_LOG_MODULE -#define MYNEWT_VAL_MFG_LOG_MODULE (128) -#endif - -#ifndef MYNEWT_VAL_MFG_MAX_MMRS -#define MYNEWT_VAL_MFG_MAX_MMRS (2) -#endif - -#ifndef MYNEWT_VAL_MFG_SYSINIT_STAGE -#define MYNEWT_VAL_MFG_SYSINIT_STAGE (100) -#endif - /*** @apache-mynewt-core/sys/sys */ #ifndef MYNEWT_VAL_DEBUG_PANIC_ENABLED #define MYNEWT_VAL_DEBUG_PANIC_ENABLED (1) @@ -343,12 +414,14 @@ #define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE -#define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (0) +#define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (1) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_MESSAGE -#define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (0) +#define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (1) #endif /*** @apache-mynewt-core/util/rwlock */ @@ -365,6 +438,10 @@ #define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (31) #endif +#ifndef MYNEWT_VAL_BLE_HCI_VS +#define MYNEWT_VAL_BLE_HCI_VS (0) +#endif + #ifndef MYNEWT_VAL_BLE_ISO #define MYNEWT_VAL_BLE_ISO (0) #endif @@ -734,16 +811,16 @@ #define MYNEWT_VAL_BLE_SM_SC (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY -#define MYNEWT_VAL_BLE_SM_SC_ONLY (0) +#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS +#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif #ifndef MYNEWT_VAL_BLE_SM_SC_LVL #define MYNEWT_VAL_BLE_SM_SC_LVL (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS -#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) +#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY +#define MYNEWT_VAL_BLE_SM_SC_ONLY (0) #endif #ifndef MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST @@ -970,12 +1047,14 @@ #define MYNEWT_VAL_BLE_SOCK_TCP_PORT (14433) #endif +/* Overridden by @apache-mynewt-nimble/porting/targets/porting_default (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE -#define MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE (0) +#define MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE (1) #endif +/* Overridden by @apache-mynewt-nimble/porting/targets/porting_default (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_TCP -#define MYNEWT_VAL_BLE_SOCK_USE_TCP (1) +#define MYNEWT_VAL_BLE_SOCK_USE_TCP (0) #endif /*** newt */ @@ -988,19 +1067,19 @@ #endif #ifndef MYNEWT_VAL_ARCH_NAME -#define MYNEWT_VAL_ARCH_NAME ("dummy") +#define MYNEWT_VAL_ARCH_NAME ("sim") #endif -#ifndef MYNEWT_VAL_ARCH_dummy -#define MYNEWT_VAL_ARCH_dummy (1) +#ifndef MYNEWT_VAL_ARCH_sim +#define MYNEWT_VAL_ARCH_sim (1) #endif #ifndef MYNEWT_VAL_BSP_NAME -#define MYNEWT_VAL_BSP_NAME ("dummy_bsp") +#define MYNEWT_VAL_BSP_NAME ("native") #endif -#ifndef MYNEWT_VAL_BSP_dummy_bsp -#define MYNEWT_VAL_BSP_dummy_bsp (1) +#ifndef MYNEWT_VAL_BSP_native +#define MYNEWT_VAL_BSP_native (1) #endif #ifndef MYNEWT_VAL_NEWT_FEATURE_LOGCFG diff --git a/porting/nimble/include/sysflash/sysflash.h b/porting/nimble/include/sysflash/sysflash.h index ab1341b25d..28391ca66a 100644 --- a/porting/nimble/include/sysflash/sysflash.h +++ b/porting/nimble/include/sysflash/sysflash.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0-dev + * This file was generated by Apache newt version: 1.10.0-dev */ #ifndef H_MYNEWT_SYSFLASH_ diff --git a/porting/npl/riot/include/logcfg/logcfg.h b/porting/npl/riot/include/logcfg/logcfg.h index 837cdeac1f..fab4d812fc 100644 --- a/porting/npl/riot/include/logcfg/logcfg.h +++ b/porting/npl/riot/include/logcfg/logcfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0-dev + * This file was generated by Apache newt version: 1.10.0-dev */ #ifndef H_MYNEWT_LOGCFG_ @@ -22,11 +22,4 @@ #define DFLT_LOG_CRITICAL(...) MODLOG_CRITICAL(0, __VA_ARGS__) #define DFLT_LOG_DISABLED(...) MODLOG_DISABLED(0, __VA_ARGS__) -#define MFG_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_INFO(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_WARN(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_ERROR(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_CRITICAL(...) IGNORE(__VA_ARGS__) -#define MFG_LOG_DISABLED(...) MODLOG_DISABLED(128, __VA_ARGS__) - #endif diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 24b49da51d..538c8213b4 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -15,81 +15,6 @@ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val - -/*** Repository @apache-mynewt-core info */ -#ifndef MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_CORE -#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_CORE ("49ac781dfadbeecfd03d60bcaac15617744783b7-dirty") -#endif - -#ifndef MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_CORE -#define MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_CORE ("0.0.0") -#endif - -/*** Repository @apache-mynewt-mcumgr info */ -#ifndef MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_MCUMGR -#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_MCUMGR ("b03a5d43ef6640d4f8858f59140b256a0ee4e772-dirty") -#endif - -#ifndef MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_MCUMGR -#define MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_MCUMGR ("0.0.0") -#endif - -/*** Repository @apache-mynewt-nimble info */ -#ifndef MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_NIMBLE -#define MYNEWT_VAL_REPO_HASH_APACHE_MYNEWT_NIMBLE ("846dda1f93c05aaf38281925b256fdbd5044492d-dirty") -#endif - -#ifndef MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_NIMBLE -#define MYNEWT_VAL_REPO_VERSION_APACHE_MYNEWT_NIMBLE ("0.0.0") -#endif - -/*** Repository @bsim info */ -#ifndef MYNEWT_VAL_REPO_HASH_BSIM -#define MYNEWT_VAL_REPO_HASH_BSIM ("8c5297423a7602b2c0bf47c64c2ac22d55d646ac") -#endif - -#ifndef MYNEWT_VAL_REPO_VERSION_BSIM -#define MYNEWT_VAL_REPO_VERSION_BSIM ("0.0.0") -#endif - -/*** Repository @mcuboot info */ -#ifndef MYNEWT_VAL_REPO_HASH_MCUBOOT -#define MYNEWT_VAL_REPO_HASH_MCUBOOT ("d4c2d15c3ef524333abf7f1e5839265ad5055d96") -#endif - -#ifndef MYNEWT_VAL_REPO_VERSION_MCUBOOT -#define MYNEWT_VAL_REPO_VERSION_MCUBOOT ("0.0.0") -#endif - -/*** Repository @mynewt_runtime info */ -#ifndef MYNEWT_VAL_REPO_HASH_MYNEWT_RUNTIME -#define MYNEWT_VAL_REPO_HASH_MYNEWT_RUNTIME ("17c53cd08300587cb5b6e5647566799eff2de198") -#endif - -#ifndef MYNEWT_VAL_REPO_VERSION_MYNEWT_RUNTIME -#define MYNEWT_VAL_REPO_VERSION_MYNEWT_RUNTIME ("0.0.0") -#endif - -/*** Repository @onsemi info */ -#ifndef MYNEWT_VAL_REPO_HASH_ONSEMI -#define MYNEWT_VAL_REPO_HASH_ONSEMI ("a3bf406b581c1aba025b8fe9472a6d8628e94e53") -#endif - -#ifndef MYNEWT_VAL_REPO_VERSION_ONSEMI -#define MYNEWT_VAL_REPO_VERSION_ONSEMI ("0.0.0") -#endif - -/*** Repository @tinyusb info */ -#ifndef MYNEWT_VAL_REPO_HASH_TINYUSB -#define MYNEWT_VAL_REPO_HASH_TINYUSB ("aa1a5a11c7729548957e5d8baf1c18ba7a333d14") -#endif - -#ifndef MYNEWT_VAL_REPO_VERSION_TINYUSB -#define MYNEWT_VAL_REPO_VERSION_TINYUSB ("0.0.0") -#endif - - - /*** @apache-mynewt-core/compiler/arm-none-eabi-m4 */ #ifndef MYNEWT_VAL_HARDFLOAT #define MYNEWT_VAL_HARDFLOAT (0) @@ -945,7 +870,7 @@ #endif #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_CONN_PARAM_REQ -#define MYNEWT_VAL_BLE_LL_CFG_FEAT_CONN_PARAM_REQ (1) +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_CONN_PARAM_REQ (MYNEWT_VAL_BLE_LL_ROLE_CENTRAL || MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL) #endif #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL @@ -1024,7 +949,7 @@ #endif #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG -#define MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG (1) +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG (MYNEWT_VAL_BLE_LL_ROLE_CENTRAL || MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL) #endif /* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ @@ -1090,10 +1015,6 @@ #define MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_ON_ASSERT (0) #endif -#ifndef MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_STATS_ON_RESET -#define MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_STATS_ON_RESET (0) -#endif - #ifndef MYNEWT_VAL_BLE_LL_MASTER_SCA #define MYNEWT_VAL_BLE_LL_MASTER_SCA (4) #endif @@ -1143,6 +1064,26 @@ #define MYNEWT_VAL_BLE_LL_RNG_BUFSIZE (32) #endif +/* Value copied from BLE_ROLE_BROADCASTER */ +#ifndef MYNEWT_VAL_BLE_LL_ROLE_BROADCASTER +#define MYNEWT_VAL_BLE_LL_ROLE_BROADCASTER (1) +#endif + +/* Value copied from BLE_ROLE_CENTRAL */ +#ifndef MYNEWT_VAL_BLE_LL_ROLE_CENTRAL +#define MYNEWT_VAL_BLE_LL_ROLE_CENTRAL (1) +#endif + +/* Value copied from BLE_ROLE_OBSERVER */ +#ifndef MYNEWT_VAL_BLE_LL_ROLE_OBSERVER +#define MYNEWT_VAL_BLE_LL_ROLE_OBSERVER (1) +#endif + +/* Value copied from BLE_ROLE_PERIPHERAL */ +#ifndef MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL +#define MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL (1) +#endif + /* Value copied from BLE_LL_OUR_SCA */ #ifndef MYNEWT_VAL_BLE_LL_SCA #define MYNEWT_VAL_BLE_LL_SCA (60) diff --git a/porting/npl/riot/include/sysflash/sysflash.h b/porting/npl/riot/include/sysflash/sysflash.h index ab1341b25d..28391ca66a 100644 --- a/porting/npl/riot/include/sysflash/sysflash.h +++ b/porting/npl/riot/include/sysflash/sysflash.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.9.0-dev + * This file was generated by Apache newt version: 1.10.0-dev */ #ifndef H_MYNEWT_SYSFLASH_ From 52d47ada52152cf232092a60cfb7186755c44fc2 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 11 Jan 2022 00:31:03 +0100 Subject: [PATCH 0213/1333] nimble/ll: Fix rx in advertising state This typo caused advertising to break on 1st received req PDU... --- nimble/controller/src/ble_ll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 56e81a6697..99e8594640 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1136,7 +1136,7 @@ ble_ll_rx_start(uint8_t *rxbuf, uint8_t chan, struct ble_mbuf_hdr *rxhdr) rc = ble_ll_conn_rx_isr_start(rxhdr, ble_phy_access_addr_get()); break; #endif -#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTERL) +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) case BLE_LL_STATE_ADV: rc = ble_ll_adv_rx_isr_start(pdu_type); break; From 0741f19599f87e1818dd00182caae3c2c9343875 Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Tue, 14 Dec 2021 11:19:53 +0100 Subject: [PATCH 0214/1333] host/gap: improve API for legacy adv for EXT_ADV:=1 The possible combination of options when setting legacy_pdu:=1 in `struct ble_gap_ext_adv_params` was not obvious to API users. This commit improves the API by i) adding accoring documentation and ii) adding a validity check into ble_gap_ext_adv_params_tx(). --- nimble/host/include/host/ble_gap.h | 14 +++++++++++++- nimble/host/src/ble_gap.c | 19 ++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index af9c978bcc..63ae900da5 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -1160,7 +1160,19 @@ struct ble_gap_ext_adv_params { /** If perform high-duty directed advertising */ unsigned int high_duty_directed:1; - /** If use legacy PDUs for advertising */ + /** If use legacy PDUs for advertising. + * + * Valid combinations of the connectable, scannable, directed, + * high_duty_directed options with the legcy_pdu flag are: + * - IND -> legacy_pdu + connectable + scannable + * - LD_DIR -> legacy_pdu + connectable + directed + * - HD_DIR -> legacy_pdu + connectable + directed + high_duty_directed + * - SCAN -> legacy_pdu + scannable + * - NONCONN -> legacy_pdu + * + * Any other combination of these options combined with the legacy_pdu flag + * are invalid. + */ unsigned int legacy_pdu:1; /** If perform anonymous advertising */ diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 8f7e5ca60a..3d8f3038ae 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -2692,15 +2692,28 @@ ble_gap_ext_adv_params_tx(uint8_t instance, if (params->high_duty_directed) { cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED; } - if (params->legacy_pdu) { - cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY; - } if (params->anonymous) { cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV; } if (params->include_tx_power) { cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR; } + if (params->legacy_pdu) { + cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY; + + /* check right away if the applied configuration is valid before handing + * the command to the controller to improve error reporting */ + switch (cmd.props) { + case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_IND: + case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_LD_DIR: + case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_HD_DIR: + case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_SCAN: + case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_NONCONN: + break; + default: + return BLE_HS_EINVAL; + } + } /* Fill optional fields if application did not specify them. */ if (params->itvl_min == 0 && params->itvl_max == 0) { From f83627a31d52bd23a63bebfa623b50484840a947 Mon Sep 17 00:00:00 2001 From: Jakub Date: Mon, 10 Jan 2022 10:36:22 +0100 Subject: [PATCH 0215/1333] nimble/include: fixed vendor command description Proper OGF for vendor specific cmd: 0x3F --- nimble/include/nimble/hci_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 7369518874..4851fd06da 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1061,7 +1061,7 @@ struct ble_hci_le_set_host_feat_cp { uint8_t val; } __attribute__((packed)); -/* --- Vendor specific commands (OGF 0x00FF) */ +/* --- Vendor specific commands (OGF 0x003F) */ #define BLE_HCI_OCF_VS_RD_STATIC_ADDR (0x0001) struct ble_hci_vs_rd_static_addr_rp { uint8_t addr[6]; From 7e368a9e16d477f69665b19758c214ca565ecd99 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 17 Jan 2022 16:42:33 +0100 Subject: [PATCH 0216/1333] nimble/phy/nrf: Add support for reading Ublox BMD-345 public address The BMD-345 modules are preprogrammed from the factory with a unique public Bluetooth device address stored in the CUSTOMER[0] and CUSTOMER[1] registers of the User Information Configuration Registers (UICR). --- nimble/drivers/nrf52/src/ble_hw.c | 18 ++++++++++++++++++ nimble/drivers/nrf52/syscfg.yml | 7 +++++++ 2 files changed, 25 insertions(+) diff --git a/nimble/drivers/nrf52/src/ble_hw.c b/nimble/drivers/nrf52/src/ble_hw.c index 8ab24eba5a..79a7772852 100644 --- a/nimble/drivers/nrf52/src/ble_hw.c +++ b/nimble/drivers/nrf52/src/ble_hw.c @@ -69,6 +69,22 @@ ble_hw_get_public_addr(ble_addr_t *addr) uint32_t addr_high; uint32_t addr_low; +#if MYNEWT_VAL(BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR) + /* + * The BMD-345 modules are preprogrammed from the factory with a unique public + * The Bluetooth device address stored in the CUSTOMER[0] and CUSTOMER[1] + * registers of the User Information Configuration Registers (UICR). + * The Bluetooth device address consists of the IEEE Organizationally Unique + * Identifier (OUI) combined with the hexadecimal digits that are printed on + * a 2D barcode and in human-readable text on the module label.The Bluetooth + * device address is stored in little endian format. The most significant + * bytes of the CUSTOMER[1] register are 0xFF to complete the 32-bit register. + */ + + /* Copy into device address. We can do this because we know platform */ + addr_low = NRF_UICR->CUSTOMER[0]; + addr_high = NRF_UICR->CUSTOMER[1]; +#else /* Does FICR have a public address */ if ((NRF_FICR->DEVICEADDRTYPE & 1) != 0) { return -1; @@ -77,6 +93,8 @@ ble_hw_get_public_addr(ble_addr_t *addr) /* Copy into device address. We can do this because we know platform */ addr_low = NRF_FICR->DEVICEADDR[0]; addr_high = NRF_FICR->DEVICEADDR[1]; +#endif + memcpy(addr->val, &addr_low, 4); memcpy(&addr->val[4], &addr_high, 2); addr->type = BLE_ADDR_PUBLIC; diff --git a/nimble/drivers/nrf52/syscfg.yml b/nimble/drivers/nrf52/syscfg.yml index bb6a2e1ba0..3bd49708ca 100644 --- a/nimble/drivers/nrf52/syscfg.yml +++ b/nimble/drivers/nrf52/syscfg.yml @@ -63,3 +63,10 @@ syscfg.defs: - nRF52840 Engineering C - nRF52840 Rev 1 (final silicon) value: 1 + + BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR: + description: > + Ublox BMD-345 modules come with public address preprogrammed + in UICR register. If enabled public address will be read from + custom UICR instead of FICR register. + value: 0 From 567855623bacdf7f034f6a5bec2401a6bb271c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 14 Jan 2022 12:48:11 +0100 Subject: [PATCH 0217/1333] apps/btshell: fix build on 'native' bsp strl* methods are not always available, let's use snprintf() for string copy/concat actions in parse_dev_addr, as it allows us to keep buffer overflow control and NULL termination of string. --- apps/btshell/src/cmd.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index a0452d22eb..6cb2713518 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -98,16 +98,19 @@ parse_dev_addr(const char *prefix, const struct kv_pair *addr_types, { char name[32]; int rc; + int written = 0; if (!prefix) { name[0] = '\0'; } else { - if (strlcpy(name, prefix, sizeof(name)) >= sizeof(name)) { + written = snprintf(name, sizeof(name) - 1, "%s", prefix); + if (written >= sizeof(name) || written < 0) { return EINVAL; } } - if (strlcat(name, "addr", sizeof(name)) >= sizeof(name)) { + written = snprintf(name + written, sizeof(name) - written - 1, "%s", "addr"); + if (written >= sizeof(name) || written < 0) { return EINVAL; } rc = parse_arg_addr(name, addr); @@ -116,7 +119,8 @@ parse_dev_addr(const char *prefix, const struct kv_pair *addr_types, return rc; } else if (rc == EAGAIN) { /* address found, but no type provided */ - if (strlcat(name, "_type", sizeof(name)) >= sizeof(name)) { + written = snprintf(name + written, sizeof(name) - written - 1, "%s", "_type"); + if (written >= sizeof(name) || written < 0) { return EINVAL; } addr->type = parse_arg_kv(name, addr_types, &rc); @@ -130,7 +134,8 @@ parse_dev_addr(const char *prefix, const struct kv_pair *addr_types, return rc; } else { /* full address found, but let's just make sure there is no type arg */ - if (strlcat(name, "_type", sizeof(name)) >= sizeof(name)) { + written = snprintf(name + written, sizeof(name) - written, "%s", "_type"); + if (written >= sizeof(name) || written < 0) { return EINVAL; } if (parse_arg_extract(name)) { From c33c87b1f3bef53e768c078d13c22d18fa89c475 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Thu, 17 Dec 2020 14:11:52 +0100 Subject: [PATCH 0218/1333] targets: Add blehci over USB for pca10056 --- targets/nordic_pca10056-blehci-usb/pkg.yml | 9 +++++++++ targets/nordic_pca10056-blehci-usb/syscfg.yml | 6 ++++++ targets/nordic_pca10056-blehci-usb/target.yml | 3 +++ 3 files changed, 18 insertions(+) create mode 100644 targets/nordic_pca10056-blehci-usb/pkg.yml create mode 100644 targets/nordic_pca10056-blehci-usb/syscfg.yml create mode 100644 targets/nordic_pca10056-blehci-usb/target.yml diff --git a/targets/nordic_pca10056-blehci-usb/pkg.yml b/targets/nordic_pca10056-blehci-usb/pkg.yml new file mode 100644 index 0000000000..772dd75ebe --- /dev/null +++ b/targets/nordic_pca10056-blehci-usb/pkg.yml @@ -0,0 +1,9 @@ +pkg.name: "targets/nordic_pca10056-blehci-usb" +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: + +pkg.deps: + - "@apache-mynewt-core/hw/usb/tinyusb" + - "@apache-mynewt-core/hw/usb/tinyusb/std_descriptors" diff --git a/targets/nordic_pca10056-blehci-usb/syscfg.yml b/targets/nordic_pca10056-blehci-usb/syscfg.yml new file mode 100644 index 0000000000..e664792eaa --- /dev/null +++ b/targets/nordic_pca10056-blehci-usb/syscfg.yml @@ -0,0 +1,6 @@ +syscfg.vals: + BLE_HCI_TRANSPORT: usb + USBD_BTH: 1 + + USBD_PID: 0xC01A + USBD_VID: 0xC0CA diff --git a/targets/nordic_pca10056-blehci-usb/target.yml b/targets/nordic_pca10056-blehci-usb/target.yml new file mode 100644 index 0000000000..39f4c8c447 --- /dev/null +++ b/targets/nordic_pca10056-blehci-usb/target.yml @@ -0,0 +1,3 @@ +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: debug From 75c1ef374941fae809801798f1dd92fd0383ab6b Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Fri, 17 Dec 2021 13:05:49 +0100 Subject: [PATCH 0219/1333] apps: remove use of deprecated BLE_PUBLIC_DEV_ADDR ble_hs_id_copy_addr() is used whenever deprecated value was used for getting public address. --- apps/blecsc/syscfg.yml | 2 +- apps/blehr/syscfg.yml | 2 +- apps/blestress/src/rx_stress.c | 3 ++- apps/bttester/src/gap.c | 17 ++--------------- nimble/host/mesh/src/shell.c | 5 ++--- targets/dialog_cmac/syscfg.yml | 2 +- 6 files changed, 9 insertions(+), 22 deletions(-) diff --git a/apps/blecsc/syscfg.yml b/apps/blecsc/syscfg.yml index ecf4b25f15..abf899691d 100644 --- a/apps/blecsc/syscfg.yml +++ b/apps/blecsc/syscfg.yml @@ -32,7 +32,7 @@ syscfg.vals: CONFIG_FCB: 1 # Set public device address. - BLE_PUBLIC_DEV_ADDR: ((uint8_t[6]){0xcc, 0xbb, 0xaa, 0x33, 0x22, 0x11}) + BLE_LL_PUBLIC_DEV_ADDR: 0x1122aabb33cc # Set device appearance to Cycling Speed and Cadence Sensor BLE_SVC_GAP_APPEARANCE: BLE_SVC_GAP_APPEARANCE_CYC_SPEED_AND_CADENCE_SENSOR diff --git a/apps/blehr/syscfg.yml b/apps/blehr/syscfg.yml index 5f047041e1..98cf255428 100644 --- a/apps/blehr/syscfg.yml +++ b/apps/blehr/syscfg.yml @@ -32,7 +32,7 @@ syscfg.vals: CONFIG_FCB: 1 # Set public device address. - BLE_PUBLIC_DEV_ADDR: ((uint8_t[6]){0xcc, 0xbb, 0xaa, 0x33, 0x22, 0x11}) + BLE_LL_PUBLIC_DEV_ADDR: 0x1122aabb33cc # Whether to save data to sys/config, or just keep it in RAM. BLE_STORE_CONFIG_PERSIST: 0 diff --git a/apps/blestress/src/rx_stress.c b/apps/blestress/src/rx_stress.c index 50415ea4e6..a9d9cda09a 100644 --- a/apps/blestress/src/rx_stress.c +++ b/apps/blestress/src/rx_stress.c @@ -155,7 +155,8 @@ rx_stress_simple_adv(struct rx_stress_adv_set *adv_set) assert (rc == 0); if (own_addr_type == 0) { - memcpy(addr.val, MYNEWT_VAL(BLE_PUBLIC_DEV_ADDR), 6); + rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, addr.val, NULL); + assert (rc == 0); } else { rc = ble_hs_id_gen_rnd(1, &addr); assert (rc == 0); diff --git a/apps/bttester/src/gap.c b/apps/bttester/src/gap.c index 63150e2877..75adeb9fc0 100644 --- a/apps/bttester/src/gap.c +++ b/apps/bttester/src/gap.c @@ -166,18 +166,6 @@ static void controller_index_list(uint8_t *data, uint16_t len) BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); } -static int check_pub_addr_unassigned(void) -{ -#ifdef ARCH_sim - return 0; -#else - uint8_t zero_addr[BLE_DEV_ADDR_LEN] = { 0 }; - - return memcmp(MYNEWT_VAL(BLE_PUBLIC_DEV_ADDR), - zero_addr, BLE_DEV_ADDR_LEN) == 0; -#endif -} - static void controller_info(uint8_t *data, uint16_t len) { struct gap_read_controller_info_rp rp; @@ -212,15 +200,14 @@ static void controller_info(uint8_t *data, uint16_t len) supported_settings |= BIT(GAP_SETTINGS_PRIVACY); memcpy(rp.address, addr.val, sizeof(rp.address)); } else { - if (check_pub_addr_unassigned()) { + rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, rp.address, NULL); + if (rc) { own_addr_type = BLE_OWN_ADDR_RANDOM; memcpy(rp.address, addr.val, sizeof(rp.address)); supported_settings |= BIT(GAP_SETTINGS_STATIC_ADDRESS); current_settings |= BIT(GAP_SETTINGS_STATIC_ADDRESS); } else { own_addr_type = BLE_OWN_ADDR_PUBLIC; - memcpy(rp.address, MYNEWT_VAL(BLE_PUBLIC_DEV_ADDR), - sizeof(rp.address)); } } diff --git a/nimble/host/mesh/src/shell.c b/nimble/host/mesh/src/shell.c index 95b1907f79..e905231081 100644 --- a/nimble/host/mesh/src/shell.c +++ b/nimble/host/mesh/src/shell.c @@ -707,10 +707,9 @@ static int check_pub_addr_unassigned(void) #ifdef ARCH_sim return 0; #else - uint8_t zero_addr[BLE_DEV_ADDR_LEN] = { 0 }; + uint8_t addr[BLE_DEV_ADDR_LEN]; - return memcmp(MYNEWT_VAL(BLE_PUBLIC_DEV_ADDR), - zero_addr, BLE_DEV_ADDR_LEN) == 0; + return ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, addr, NULL) != 0; #endif } diff --git a/targets/dialog_cmac/syscfg.yml b/targets/dialog_cmac/syscfg.yml index b94427ac22..3a8895d7db 100644 --- a/targets/dialog_cmac/syscfg.yml +++ b/targets/dialog_cmac/syscfg.yml @@ -32,4 +32,4 @@ syscfg.vals: BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY: 150 # NOTE: set public address in target settings - # BLE_PUBLIC_DEV_ADDR: "(uint8_t[6]){0xff, 0xff, 0xff, 0xff, 0xff, 0xff}" + # BLE_LL_PUBLIC_DEV_ADDR: 0xffffffffffff From c13d0b478ba93015e625838b33fbcb17b81e81f3 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Fri, 17 Dec 2021 13:39:07 +0100 Subject: [PATCH 0220/1333] apps: Remove controller direct dependency Direct dependency on controller is incorrect when controller runs on another core. --- apps/blecsc/pkg.yml | 1 - apps/blehr/pkg.yml | 1 - apps/blemesh/pkg.yml | 1 - apps/blemesh_light/pkg.yml | 1 - apps/blemesh_models_example_1/pkg.yml | 1 - apps/blemesh_models_example_2/pkg.yml | 1 - apps/blemesh_shell/pkg.yml | 1 - apps/blestress/pkg.yml | 1 - apps/bttester/pkg.yml | 1 - apps/ext_advertiser/pkg.yml | 1 - apps/mesh_badge/pkg.yml | 1 - 11 files changed, 11 deletions(-) diff --git a/apps/blecsc/pkg.yml b/apps/blecsc/pkg.yml index 828ff301ee..a2119c1b35 100644 --- a/apps/blecsc/pkg.yml +++ b/apps/blecsc/pkg.yml @@ -32,7 +32,6 @@ pkg.deps: - "@apache-mynewt-core/sys/stats/full" - "@apache-mynewt-core/sys/sysinit" - "@apache-mynewt-core/sys/id" - - nimble/controller - nimble/host - nimble/host/services/gap - nimble/host/services/gatt diff --git a/apps/blehr/pkg.yml b/apps/blehr/pkg.yml index 395134faba..8212f8f6a2 100644 --- a/apps/blehr/pkg.yml +++ b/apps/blehr/pkg.yml @@ -32,7 +32,6 @@ pkg.deps: - "@apache-mynewt-core/sys/stats/full" - "@apache-mynewt-core/sys/sysinit" - "@apache-mynewt-core/sys/id" - - nimble/controller - nimble/host - nimble/host/services/gap - nimble/host/services/gatt diff --git a/apps/blemesh/pkg.yml b/apps/blemesh/pkg.yml index 8a2af6874c..afe419b57b 100644 --- a/apps/blemesh/pkg.yml +++ b/apps/blemesh/pkg.yml @@ -29,7 +29,6 @@ pkg.deps: - "@apache-mynewt-core/sys/log/modlog" - "@apache-mynewt-core/sys/stats/full" - "@apache-mynewt-core/sys/shell" - - nimble/controller - nimble/host - nimble/host/services/gap - nimble/host/services/gatt diff --git a/apps/blemesh_light/pkg.yml b/apps/blemesh_light/pkg.yml index bfc1ad233a..46b6d6c3d1 100644 --- a/apps/blemesh_light/pkg.yml +++ b/apps/blemesh_light/pkg.yml @@ -29,7 +29,6 @@ pkg.deps: - "@apache-mynewt-core/sys/log/modlog" - "@apache-mynewt-core/sys/stats/full" - "@apache-mynewt-core/sys/shell" - - nimble/controller - nimble/host - nimble/host/services/gap - nimble/host/services/gatt diff --git a/apps/blemesh_models_example_1/pkg.yml b/apps/blemesh_models_example_1/pkg.yml index cd11834c5f..b8d77c4e47 100644 --- a/apps/blemesh_models_example_1/pkg.yml +++ b/apps/blemesh_models_example_1/pkg.yml @@ -27,7 +27,6 @@ pkg.deps: - "@apache-mynewt-core/sys/console/full" - "@apache-mynewt-core/sys/log/full" - "@apache-mynewt-core/sys/stats/full" - - nimble/controller - nimble/host - nimble/host/services/gap - nimble/host/services/gatt diff --git a/apps/blemesh_models_example_2/pkg.yml b/apps/blemesh_models_example_2/pkg.yml index 684d85bad8..020a9616da 100644 --- a/apps/blemesh_models_example_2/pkg.yml +++ b/apps/blemesh_models_example_2/pkg.yml @@ -29,7 +29,6 @@ pkg.deps: - "@apache-mynewt-core/sys/stats/full" - "@apache-mynewt-core/encoding/base64" - "@apache-mynewt-core/sys/config" - - nimble/controller - nimble/host - nimble/host/services/gap - nimble/host/services/gatt diff --git a/apps/blemesh_shell/pkg.yml b/apps/blemesh_shell/pkg.yml index 2e7064cf90..f472fdf2aa 100644 --- a/apps/blemesh_shell/pkg.yml +++ b/apps/blemesh_shell/pkg.yml @@ -29,7 +29,6 @@ pkg.deps: - "@apache-mynewt-core/sys/log/modlog" - "@apache-mynewt-core/sys/stats/full" - "@apache-mynewt-core/sys/shell" - - nimble/controller - nimble/host - nimble/host/services/gap - nimble/host/services/gatt diff --git a/apps/blestress/pkg.yml b/apps/blestress/pkg.yml index d4c52d247c..53f99ed944 100644 --- a/apps/blestress/pkg.yml +++ b/apps/blestress/pkg.yml @@ -30,7 +30,6 @@ pkg.deps: - "@apache-mynewt-core/sys/log/full" - "@apache-mynewt-core/sys/stats/full" - "@apache-mynewt-core/sys/id" - - "@apache-mynewt-nimble/nimble/controller" - "@apache-mynewt-nimble/nimble/host" - "@apache-mynewt-nimble/nimble/host/util" - "@apache-mynewt-nimble/nimble/host/services/gap" diff --git a/apps/bttester/pkg.yml b/apps/bttester/pkg.yml index 39405aa051..270dc7e882 100644 --- a/apps/bttester/pkg.yml +++ b/apps/bttester/pkg.yml @@ -31,7 +31,6 @@ pkg.deps: - "@apache-mynewt-core/sys/log/modlog" - "@apache-mynewt-core/sys/stats/full" - "@apache-mynewt-core/sys/shell" - - "@apache-mynewt-nimble/nimble/controller" - "@apache-mynewt-nimble/nimble/host" - "@apache-mynewt-nimble/nimble/host/util" - "@apache-mynewt-nimble/nimble/host/services/gap" diff --git a/apps/ext_advertiser/pkg.yml b/apps/ext_advertiser/pkg.yml index b9f9e54728..5a60b2270b 100644 --- a/apps/ext_advertiser/pkg.yml +++ b/apps/ext_advertiser/pkg.yml @@ -25,7 +25,6 @@ pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: pkg.deps: - - nimble/controller - nimble/host - nimble/host/util - nimble/host/services/gap diff --git a/apps/mesh_badge/pkg.yml b/apps/mesh_badge/pkg.yml index 802b86bab4..96a42ba6a7 100644 --- a/apps/mesh_badge/pkg.yml +++ b/apps/mesh_badge/pkg.yml @@ -31,7 +31,6 @@ pkg.deps: - "@apache-mynewt-core/sys/log/modlog" - "@apache-mynewt-core/sys/stats/full" - "@apache-mynewt-core/sys/shell" - - nimble/controller - nimble/host - nimble/host/services/gap - nimble/host/services/gatt From 05538bc66db58c5fb676d1f62a9ad8f99ed6cb74 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 11 Jan 2022 15:35:35 +0100 Subject: [PATCH 0221/1333] nimble/ll: Add support for PA/LNA This adds some definitions for PA/LNA support. The actual support is implemented in phy and front-end driver. --- .../include/controller/ble_ll_plna.h | 45 +++++++++++++++++++ nimble/controller/pkg.yml | 4 ++ nimble/controller/src/ble_ll.c | 9 ++++ nimble/controller/syscfg.yml | 19 ++++++++ 4 files changed, 77 insertions(+) create mode 100644 nimble/controller/include/controller/ble_ll_plna.h diff --git a/nimble/controller/include/controller/ble_ll_plna.h b/nimble/controller/include/controller/ble_ll_plna.h new file mode 100644 index 0000000000..c4fb65ea98 --- /dev/null +++ b/nimble/controller/include/controller/ble_ll_plna.h @@ -0,0 +1,45 @@ +/* + * 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_BLE_LL_PLNA_ +#define H_BLE_LL_PLNA_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(BLE_LL_PA) +void ble_ll_plna_pa_init(void); +void ble_ll_plna_pa_enable(void); +void ble_ll_plna_pa_disable(void); +#endif + +#if MYNEWT_VAL(BLE_LL_LNA) +void ble_ll_plna_lna_init(void); +void ble_ll_plna_lna_enable(void); +void ble_ll_plna_lna_disable(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* H_BLE_LL_PLNA_ */ diff --git a/nimble/controller/pkg.yml b/nimble/controller/pkg.yml index 96c636798b..9661bb31e8 100644 --- a/nimble/controller/pkg.yml +++ b/nimble/controller/pkg.yml @@ -29,6 +29,10 @@ pkg.req_apis: - ble_driver - ble_transport - stats +pkg.req_apis.BLE_LL_PA: + - ble_ll_pa +pkg.req_apis.BLE_LL_LNA: + - ble_ll_lna pkg.deps: - "@apache-mynewt-core/kernel/os" diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 99e8594640..f21f55ce07 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -44,6 +44,7 @@ #include "controller/ble_ll_rfmgmt.h" #include "controller/ble_ll_trace.h" #include "controller/ble_ll_sync.h" +#include "controller/ble_ll_plna.h" #include "ble_ll_conn_priv.h" #include "ble_ll_hci_priv.h" #include "ble_ll_priv.h" @@ -1656,6 +1657,14 @@ ble_ll_reset(void) ble_ll_resolv_list_reset(); #endif + +#if MYNEWT_VAL(BLE_LL_PA) + ble_ll_plna_pa_init(); +#endif +#if MYNEWT_VAL(BLE_LL_LNA) + ble_ll_plna_lna_init(); +#endif + /* Re-initialize the PHY */ rc = ble_phy_init(); diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 62c9c4ad9d..41384cb5b4 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -375,6 +375,23 @@ syscfg.defs: line number where assertion occured. value: 0 + BLE_LL_PA: + description: Enable PA support + value: 0 + BLE_LL_PA_GPIO: + description: > + GPIO pin number to control PA. Pin is set to high state when PA + should be enabled. + value: -1 + BLE_LL_LNA: + description: Enable LNA support + value: 0 + BLE_LL_LNA_GPIO: + description: > + GPIO pin number to control LNA. Pin is set to high state when LNA + should be enabled. + value: -1 + BLE_LL_SYSINIT_STAGE: description: > Sysinit stage for the NimBLE controller. @@ -499,3 +516,5 @@ syscfg.vals.!BLE_HOST: syscfg.restrictions: - OS_CPUTIME_FREQ == 32768 - BLE_LL_PUBLIC_DEV_ADDR <= 0xffffffffffff + - BLE_LL_PA == 0 || BLE_LL_PA_GPIO >= 0 + - BLE_LL_LNA == 0 || BLE_LL_LNA_GPIO >= 0 From 9ef71450430ee0b2f3bfae902a2212fdadb8d375 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 11 Jan 2022 15:37:38 +0100 Subject: [PATCH 0222/1333] nimble/phy/nrf: Add support for PA/LNA on nRF52xxx This adds support for PA/LNA on nRF52 phy. PA/LNA is controlled using PPI CH6 (enable) and CH7 (disable). At the moment no separate timestamp is used to enable PA/LNA in advance, it's simply enabled just after ramp-up. This should be fine for front-end modules with short switch on time like SKY66112 (<800ns). --- nimble/drivers/nrf52/src/ble_phy.c | 144 ++++++++++++++++++++++++----- 1 file changed, 122 insertions(+), 22 deletions(-) diff --git a/nimble/drivers/nrf52/src/ble_phy.c b/nimble/drivers/nrf52/src/ble_phy.c index 6aa898b327..3c7b62690b 100644 --- a/nimble/drivers/nrf52/src/ble_phy.c +++ b/nimble/drivers/nrf52/src/ble_phy.c @@ -29,6 +29,7 @@ #include "controller/ble_phy.h" #include "controller/ble_phy_trace.h" #include "controller/ble_ll.h" +#include "controller/ble_ll_plna.h" #include "nrfx.h" #if MYNEWT #include "mcu/nrf52_clock.h" @@ -49,9 +50,11 @@ * using PPI somewhere else. * * Pre-programmed channels: CH20, CH21, CH23, CH25, CH31 - * Regular channels: CH4, CH5 and optionally CH17, CH18, CH19 + * Regular channels: CH4, CH5 and optionally CH6, CH7, CH17, CH18, CH19 * - CH4 = cancel wfr timer on address match * - CH5 = disable radio on wfr timer expiry + * - CH6 = PA/LNA control (enable) + * - CH7 = PA/LNA control (disable) * - CH17 = (optional) gpio debug for radio ramp-up * - CH18 = (optional) gpio debug for wfr timer RX enabled * - CH19 = (optional) gpio debug for wfr timer radio disabled @@ -277,6 +280,27 @@ struct nrf_ccm_data struct nrf_ccm_data g_nrf_ccm_data; #endif +static int g_ble_phy_gpiote_idx; + +#if MYNEWT_VAL(BLE_LL_PA) || MYNEWT_VAL(BLE_LL_LNA) + +#define PLNA_SINGLE_GPIO \ + (!MYNEWT_VAL(BLE_LL_PA) || !MYNEWT_VAL(BLE_LL_LNA) || \ + (MYNEWT_VAL(BLE_LL_PA_GPIO) == MYNEWT_VAL(BLE_LL_LNA_GPIO))) + +#if PLNA_SINGLE_GPIO +static uint8_t plna_idx; +#else +#if MYNEWT_VAL(BLE_LL_PA) +static uint8_t plna_pa_idx; +#endif +#if MYNEWT_VAL(BLE_LL_LNA) +static uint8_t plna_lna_idx; +#endif +#endif + +#endif + static void ble_phy_apply_errata_102_106_107(void) { @@ -400,6 +424,36 @@ ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode) } #endif +static void +ble_phy_plna_enable_pa(void) +{ +#if MYNEWT_VAL(BLE_LL_PA) + ble_ll_plna_pa_enable(); + +#if !PLNA_SINGLE_GPIO + NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[plna_pa_idx]); + NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[plna_pa_idx]); +#endif + + NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; +#endif +} + +static void +ble_phy_plna_enable_lna(void) +{ +#if MYNEWT_VAL(BLE_LL_LNA) + ble_ll_plna_lna_enable(); + +#if !PLNA_SINGLE_GPIO + NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[plna_lna_idx]); + NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[plna_lna_idx]); +#endif + + NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; +#endif +} + int ble_phy_get_cur_phy(void) { @@ -925,6 +979,8 @@ ble_phy_tx_end_isr(void) NRF_TIMER0->CC[0] = rx_time; NRF_TIMER0->EVENTS_COMPARE[0] = 0; NRF_PPI->CHENSET = PPI_CHEN_CH21_Msk; + + ble_phy_plna_enable_lna(); } else { /* * XXX: not sure we need to stop the timer here all the time. Or that @@ -1053,6 +1109,8 @@ ble_phy_rx_end_isr(void) NRF_TIMER0->EVENTS_COMPARE[0] = 0; NRF_PPI->CHENSET = PPI_CHEN_CH20_Msk; + ble_phy_plna_enable_pa(); + /* * XXX: Hack warning! * @@ -1255,6 +1313,10 @@ ble_phy_isr(void) switch (g_ble_phy_data.phy_state) { case BLE_PHY_STATE_RX: +#if MYNEWT_VAL(BLE_LL_LNA) + NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; + ble_ll_plna_lna_disable(); +#endif if (g_ble_phy_data.phy_rx_started) { ble_phy_rx_end_isr(); } else { @@ -1262,6 +1324,10 @@ ble_phy_isr(void) } break; case BLE_PHY_STATE_TX: +#if MYNEWT_VAL(BLE_LL_PA) + NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; + ble_ll_plna_pa_disable(); +#endif ble_phy_tx_end_isr(); break; default: @@ -1278,13 +1344,17 @@ ble_phy_isr(void) } #if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 -static inline void -ble_phy_dbg_time_setup_gpiote(int index, int pin) + MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \ + MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 || \ + MYNEWT_VAL(BLE_LL_PA) || \ + MYNEWT_VAL(BLE_LL_LNA) +static int +ble_phy_gpiote_configure(int pin) { NRF_GPIO_Type *port; + g_ble_phy_gpiote_idx--; + #if NRF52840_XXAA port = pin > 31 ? NRF_P1 : NRF_P0; pin &= 0x1f; @@ -1296,7 +1366,7 @@ ble_phy_dbg_time_setup_gpiote(int index, int pin) port->DIRSET = (1 << pin); port->OUTCLR = (1 << pin); - NRF_GPIOTE->CONFIG[index] = + NRF_GPIOTE->CONFIG[g_ble_phy_gpiote_idx] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | ((pin & 0x1F) << GPIOTE_CONFIG_PSEL_Pos) | #if NRF52840_XXAA @@ -1304,13 +1374,17 @@ ble_phy_dbg_time_setup_gpiote(int index, int pin) #else 0; #endif + + BLE_LL_ASSERT(g_ble_phy_gpiote_idx >= 0); + + return g_ble_phy_gpiote_idx; } #endif static void ble_phy_dbg_time_setup(void) { - int gpiote_idx __attribute__((unused)) = 8; + int idx __attribute__((unused)); /* * We setup GPIOTE starting from last configuration index to minimize risk @@ -1319,44 +1393,41 @@ ble_phy_dbg_time_setup(void) */ #if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 - ble_phy_dbg_time_setup_gpiote(--gpiote_idx, - MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); + idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); NRF_PPI->CH[17].EEP = (uint32_t)&(NRF_RADIO->EVENTS_READY); - NRF_PPI->CH[17].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[gpiote_idx]); + NRF_PPI->CH[17].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx]); NRF_PPI->CHENSET = PPI_CHEN_CH17_Msk; /* CH[20] and PPI CH[21] are on to trigger TASKS_TXEN or TASKS_RXEN */ - NRF_PPI->FORK[20].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[gpiote_idx]); - NRF_PPI->FORK[21].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[gpiote_idx]); + NRF_PPI->FORK[20].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx]); + NRF_PPI->FORK[21].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx]); #endif #if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 - ble_phy_dbg_time_setup_gpiote(--gpiote_idx, - MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); + idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); /* CH[26] and CH[27] are always on for EVENT_ADDRESS and EVENT_END */ - NRF_PPI->FORK[26].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[gpiote_idx]); - NRF_PPI->FORK[27].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[gpiote_idx]); + NRF_PPI->FORK[26].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx]); + NRF_PPI->FORK[27].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx]); #endif #if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 - ble_phy_dbg_time_setup_gpiote(--gpiote_idx, - MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); + idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); #if NRF52840_XXAA NRF_PPI->CH[18].EEP = (uint32_t)&(NRF_RADIO->EVENTS_RXREADY); #else NRF_PPI->CH[18].EEP = (uint32_t)&(NRF_RADIO->EVENTS_READY); #endif - NRF_PPI->CH[18].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[gpiote_idx]); + NRF_PPI->CH[18].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx]); NRF_PPI->CH[19].EEP = (uint32_t)&(NRF_RADIO->EVENTS_DISABLED); - NRF_PPI->CH[19].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[gpiote_idx]); + NRF_PPI->CH[19].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx]); NRF_PPI->CHENSET = PPI_CHEN_CH18_Msk | PPI_CHEN_CH19_Msk; /* CH[4] and CH[5] are always on for wfr */ - NRF_PPI->FORK[4].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[gpiote_idx]); - NRF_PPI->FORK[5].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[gpiote_idx]); + NRF_PPI->FORK[4].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx]); + NRF_PPI->FORK[5].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx]); #endif } @@ -1372,6 +1443,8 @@ ble_phy_init(void) { int rc; + g_ble_phy_gpiote_idx = 8; + /* Default phy to use is 1M */ g_ble_phy_data.phy_cur_phy_mode = BLE_PHY_MODE_1M; g_ble_phy_data.phy_tx_phy_mode = BLE_PHY_MODE_1M; @@ -1455,6 +1528,27 @@ ble_phy_init(void) NRF_PPI->CH[5].EEP = (uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[3]); NRF_PPI->CH[5].TEP = (uint32_t)&(NRF_RADIO->TASKS_DISABLE); +#if MYNEWT_VAL(BLE_LL_PA) || MYNEWT_VAL(BLE_LL_LNA) +#if PLNA_SINGLE_GPIO + plna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO)); + NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[plna_idx]); + NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[plna_idx]); +#else +#if MYNEWT_VAL(BLE_LL_PA) + plna_pa_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO)); + NRF_GPIOTE->TASKS_CLR[plna_pa_idx] = 1; +#endif +#if MYNEWT_VAL(BLE_LL_LNA) + plna_lna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_LNA_GPIO)); + NRF_GPIOTE->TASKS_CLR[plna_lna_idx] = 1; +#endif +#endif + + NRF_PPI->CH[6].EEP = (uint32_t)&(NRF_RADIO->EVENTS_READY); + NRF_PPI->CH[7].EEP = (uint32_t)&(NRF_RADIO->EVENTS_DISABLED); + NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; +#endif + /* Set isr in vector table and enable interrupt */ #ifndef RIOT_VERSION NVIC_SetPriority(RADIO_IRQn, 0); @@ -1617,7 +1711,10 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) /* Enable PPI to automatically start TXEN */ NRF_PPI->CHENSET = PPI_CHEN_CH20_Msk; rc = 0; + + ble_phy_plna_enable_pa(); } + return rc; } @@ -1662,6 +1759,8 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) /* Enable PPI to automatically start RXEN */ NRF_PPI->CHENSET = PPI_CHEN_CH21_Msk; + ble_phy_plna_enable_lna(); + /* Start rx */ rc = ble_phy_rx(); @@ -1959,6 +2058,7 @@ ble_phy_disable_irq_and_ppi(void) NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | PPI_CHEN_CH20_Msk | PPI_CHEN_CH21_Msk | PPI_CHEN_CH23_Msk | PPI_CHEN_CH25_Msk | PPI_CHEN_CH31_Msk; + NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; NVIC_ClearPendingIRQ(RADIO_IRQn); g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE; } From 854f362c85a00d8759195c09103b18a9f0c7df5f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 11 Jan 2022 15:37:49 +0100 Subject: [PATCH 0223/1333] nimble/plna: Add driver for SKY66112 This adds support for SKY66112 front-end module (PA/LNA). CTX and CRX signals are controller by phy and shall be configured using LL syscfg settings for PA/LNA. Other signals can be configured via GPIO or simply driven externally to spare GPIO pins. It's possible to use PA or LNA only, in such case CPS signal has to be driven via GPIO. --- nimble/drivers/plna/sky66112/pkg.yml | 31 ++++++ nimble/drivers/plna/sky66112/src/sky66112.c | 117 ++++++++++++++++++++ nimble/drivers/plna/sky66112/syscfg.yml | 66 +++++++++++ 3 files changed, 214 insertions(+) create mode 100644 nimble/drivers/plna/sky66112/pkg.yml create mode 100644 nimble/drivers/plna/sky66112/src/sky66112.c create mode 100644 nimble/drivers/plna/sky66112/syscfg.yml diff --git a/nimble/drivers/plna/sky66112/pkg.yml b/nimble/drivers/plna/sky66112/pkg.yml new file mode 100644 index 0000000000..c3cb0fd322 --- /dev/null +++ b/nimble/drivers/plna/sky66112/pkg.yml @@ -0,0 +1,31 @@ +# +# 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: nimble/drivers/plna/sky66112 +pkg.description: Driver for SKY66112 front-end module +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" +pkg.apis: + - ble_ll_pa + - ble_ll_lna +pkg.deps: + - nimble/controller + +pkg.init: + sky66112_init: 999 diff --git a/nimble/drivers/plna/sky66112/src/sky66112.c b/nimble/drivers/plna/sky66112/src/sky66112.c new file mode 100644 index 0000000000..09afe5f96e --- /dev/null +++ b/nimble/drivers/plna/sky66112/src/sky66112.c @@ -0,0 +1,117 @@ +/* + * 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. + */ + +#include +#include +#include "syscfg/syscfg.h" +#include "hal/hal_gpio.h" +#include "controller/ble_ll_plna.h" + +#define NO_BYPASS \ + ((MYNEWT_VAL(SKY66112_TX_BYPASS) >= 0) && \ + (MYNEWT_VAL(SKY66112_RX_BYPASS) >= 0)) + +static void +sky66112_bypass(uint8_t enabled) +{ + if (NO_BYPASS) { + return; + } + + hal_gpio_write(MYNEWT_VAL(SKY66112_PIN_CPS), enabled); +} + +void +ble_ll_plna_pa_init(void) +{ + /* Nothing to do here */ +} + +void +ble_ll_plna_pa_enable(void) +{ + if (!MYNEWT_VAL(SKY66112_TX_BYPASS)) { + sky66112_bypass(0); + } +} + +void +ble_ll_plna_pa_disable(void) +{ + if (!MYNEWT_VAL(SKY66112_TX_BYPASS)) { + sky66112_bypass(1); + } +} + +void +ble_ll_plna_lna_init(void) +{ + /* Nothing to do here */ +} + +void +ble_ll_plna_lna_enable(void) +{ + if (!MYNEWT_VAL(SKY66112_RX_BYPASS)) { + sky66112_bypass(0); + } +} + +void +ble_ll_plna_lna_disable(void) +{ + if (!MYNEWT_VAL(SKY66112_RX_BYPASS)) { + sky66112_bypass(1); + } +} + +void +sky66112_init(void) +{ + int pin; + + /* Use CRX and CTX to enable sleep mode */ + pin = MYNEWT_VAL(SKY66112_PIN_CSD); + if (pin >= 0) { + hal_gpio_init_out(pin, 1); + } + + pin = MYNEWT_VAL(SKY66112_PIN_CPS); + if (NO_BYPASS) { + /* Disable bypass */ + if (pin >= 0) { + hal_gpio_init_out(pin, 0); + } + } else { + /* Enable bypass, we'll disable it when needed */ + assert(pin >= 0); + hal_gpio_init_out(pin, 1); + } + + pin = MYNEWT_VAL(SKY66112_PIN_CHL); + if (pin >= 0) { + hal_gpio_init_out(pin, MYNEWT_VAL(SKY66112_TX_HP_MODE)); + } + + /* Select ANT1 */ + pin = MYNEWT_VAL(SKY66112_PIN_SEL); + if (pin >= 0) { + hal_gpio_init_out(pin, 0); + } +} diff --git a/nimble/drivers/plna/sky66112/syscfg.yml b/nimble/drivers/plna/sky66112/syscfg.yml new file mode 100644 index 0000000000..50434553a0 --- /dev/null +++ b/nimble/drivers/plna/sky66112/syscfg.yml @@ -0,0 +1,66 @@ +# 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. +# + +syscfg.defs: + SKY66112_PIN_CSD: + description: > + GPIO pin number to control CSD signal. + When set to '-1', pin state will not be changed and it should be + driven externally. + value: -1 + SKY66112_PIN_CPS: + description: > + GPIO pin number to control CPS signal. + When set to '-1', pin state will not be changed and it should be + driven externally. + value: -1 + SKY66112_PIN_CHL: + description: > + GPIO pin number to control CHL signal. + When set to '-1', pin state will not be changed and it should be + driven externally. + value: -1 + SKY66112_PIN_SEL: + description: > + GPIO pin number to control SEL signal. + When set to '-1', pin state will not be changed and it should be + driven externally. + value: -1 + SKY66112_TX_HP_MODE: + description: > + Enables high-power mode for TX. + Only valid if CHL signal is controller by driver. + value: 0 + SKY66112_TX_BYPASS: + description: > + Enables bypass for TX which effectively disables operation as PA. + Only valid if CPS signal is controller by driver. + value: 0 + SKY66112_RX_BYPASS: + description: > + Enables bypass for RX which effectively disables operation as PA. + Only valid if CPS signal is controller by driver. + value: 0 + +syscfg.vals.!BLE_LL_PA: + # Enable TX bypass by default if PA is disabled + SKY66112_TX_BYPASS: 1 + +syscfg.vals.!BLE_LL_LNA: + # Enable RX bypass by default if LNA is disabled + SKY66112_RX_BYPASS: 1 From 984e879f1781b0cd42ce6dc5ea4c60de3beb1776 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 14 Jan 2022 10:07:27 +0100 Subject: [PATCH 0224/1333] ll/nrf5340: Add support for PHY GPIO debug --- nimble/drivers/nrf5340/src/ble_phy.c | 153 +++++++++++++++++++++++++++ nimble/drivers/nrf5340/syscfg.yml | 39 +++++++ 2 files changed, 192 insertions(+) diff --git a/nimble/drivers/nrf5340/src/ble_phy.c b/nimble/drivers/nrf5340/src/ble_phy.c index e07bbaa11f..12be202db5 100644 --- a/nimble/drivers/nrf5340/src/ble_phy.c +++ b/nimble/drivers/nrf5340/src/ble_phy.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,8 @@ * DPPI somewhere else. * TODO maybe we could reduce number of used channels if we reuse same channel * for mutually exclusive events but for now make it simpler to debug. + * + * Optionally channels 6,7,8 are used for GPIO DBG. */ #define DPPI_CH_TIMER0_EVENTS_COMPARE_0 0 @@ -82,6 +85,39 @@ #define DPPI_SUBSCRIBE_CCM_TASKS_CRYPT(_enable) ((DPPI_CH_RADIO_EVENTS_ADDRESS << CCM_SUBSCRIBE_CRYPT_CHIDX_Pos) | \ ((_enable) << CCM_SUBSCRIBE_CRYPT_EN_Pos)) +/* used for GPIO DBG */ +#define DPPI_CH_RADIO_EVENTS_READY 6 +#define DPPI_CH_RADIO_EVENTS_RXREADY 7 +#define DPPI_CH_RADIO_EVENTS_DISABLED 8 + +#define DPPI_CH_ENABLE_RADIO_EVENTS_READY DPPIC_CHEN_CH6_Msk +#define DPPI_CH_ENABLE_RADIO_EVENTS_RXREADY DPPIC_CHEN_CH7_Msk +#define DPPI_CH_ENABLE_RADIO_EVENTS_DISABLED DPPIC_CHEN_CH8_Msk + +#define DPPI_PUBLISH_RADIO_EVENTS_READY ((DPPI_CH_RADIO_EVENTS_READY << RADIO_PUBLISH_READY_CHIDX_Pos) | \ + (RADIO_PUBLISH_READY_EN_Enabled << RADIO_PUBLISH_READY_EN_Pos)) +#define DPPI_PUBLISH_RADIO_EVENTS_RXREADY ((DPPI_CH_RADIO_EVENTS_RXREADY << RADIO_PUBLISH_RXREADY_CHIDX_Pos) | \ + (RADIO_PUBLISH_RXREADY_EN_Enabled << RADIO_PUBLISH_RXREADY_EN_Pos)) +#define DPPI_PUBLISH_RADIO_EVENTS_DISABLED ((DPPI_CH_RADIO_EVENTS_DISABLED << RADIO_PUBLISH_DISABLED_CHIDX_Pos) | \ + (RADIO_PUBLISH_DISABLED_EN_Enabled << RADIO_PUBLISH_DISABLED_EN_Pos)) + +#define DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_TXRXEN ((DPPI_CH_TIMER0_EVENTS_COMPARE_0 << GPIOTE_SUBSCRIBE_SET_CHIDX_Pos) | \ + (1 << GPIOTE_SUBSCRIBE_SET_EN_Pos)) +#define DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_ADDRESS ((DPPI_CH_RADIO_EVENTS_ADDRESS << GPIOTE_SUBSCRIBE_SET_CHIDX_Pos) | \ + (1 << GPIOTE_SUBSCRIBE_SET_EN_Pos)) +#define DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_END ((DPPI_CH_RADIO_EVENTS_END << GPIOTE_SUBSCRIBE_CLR_CHIDX_Pos) | \ + (1 << GPIOTE_SUBSCRIBE_CLR_EN_Pos)) +#define DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_READY ((DPPI_CH_RADIO_EVENTS_READY << GPIOTE_SUBSCRIBE_CLR_CHIDX_Pos) | \ + (1 << GPIOTE_SUBSCRIBE_CLR_EN_Pos)) +#define DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_RXREADY ((DPPI_CH_RADIO_EVENTS_RXREADY << GPIOTE_SUBSCRIBE_SET_CHIDX_Pos) | \ + (1 << GPIOTE_SUBSCRIBE_SET_EN_Pos)) +#define DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_DISABLED ((DPPI_CH_RADIO_EVENTS_DISABLED << GPIOTE_SUBSCRIBE_CLR_CHIDX_Pos) | \ + (1 << GPIOTE_SUBSCRIBE_CLR_EN_Pos)) +#define DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_CAPTURE3 ((DPPI_CH_TIMER0_EVENTS_COMPARE_3 << GPIOTE_SUBSCRIBE_CLR_CHIDX_Pos) | \ + (1 << GPIOTE_SUBSCRIBE_CLR_EN_Pos)) +#define DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_ADDRESS ((DPPI_CH_RADIO_EVENTS_ADDRESS << GPIOTE_SUBSCRIBE_CLR_CHIDX_Pos) | \ + (1 << GPIOTE_SUBSCRIBE_CLR_EN_Pos)) + extern uint8_t g_nrf_num_irks; extern uint32_t g_nrf_irk_list[]; @@ -1179,6 +1215,84 @@ ble_phy_isr(void) os_trace_isr_exit(); } +#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \ + MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \ + MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 +static inline void +ble_phy_dbg_time_setup_gpiote(int index, int pin) +{ + NRF_GPIO_Type *port; + + port = pin > 31 ? NRF_P1_NS : NRF_P0_NS; + pin &= 0x1f; + + /* Configure GPIO directly to avoid dependency to hal_gpio (for porting) */ + port->DIRSET = (1 << pin); + port->OUTCLR = (1 << pin); + + NRF_GPIOTE_NS->CONFIG[index] = + (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | + ((pin & 0x1F) << GPIOTE_CONFIG_PSEL_Pos) | + ((port == NRF_P1_NS) << GPIOTE_CONFIG_PORT_Pos); +} +#endif + +static void +ble_phy_dbg_time_setup(void) +{ + int gpiote_idx __attribute__((unused)) = 8; + + /* + * We setup GPIOTE starting from last configuration index to minimize risk + * of conflict with GPIO setup via hal. It's not great solution, but since + * this is just debugging code we can live with this. + */ + +#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 + ble_phy_dbg_time_setup_gpiote(--gpiote_idx, + MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); + + NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_TXRXEN; + NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_READY; + + /* Publish RADIO->EVENTS_READY */ + NRF_RADIO_NS->PUBLISH_READY = DPPI_PUBLISH_RADIO_EVENTS_READY; + NRF_DPPIC_NS->CHENSET = DPPI_CH_ENABLE_RADIO_EVENTS_READY; + +#endif + +#if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 + ble_phy_dbg_time_setup_gpiote(--gpiote_idx, + MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); + + NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_ADDRESS; + NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_END; +#endif + +#if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 + ble_phy_dbg_time_setup_gpiote(--gpiote_idx, + MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); + + NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_RXREADY; + + /* TODO figure out how (if?) to subscribe task to multiple DPPI channels + * Currently only last one is working. Also using multiple GPIOTE for same + * PIN doesn't work... + */ + NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_DISABLED; + NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_ADDRESS; + NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_CAPTURE3; + + /* Publish RADIO->EVENTS_RXREADY */ + NRF_RADIO_NS->PUBLISH_RXREADY = DPPI_PUBLISH_RADIO_EVENTS_RXREADY; + NRF_DPPIC_NS->CHENSET = DPPI_CH_ENABLE_RADIO_EVENTS_RXREADY; + + /* Publish RADIO->EVENTS_DISABLED */ + NRF_RADIO_NS->PUBLISH_DISABLED = DPPI_CH_ENABLE_RADIO_EVENTS_DISABLED; + NRF_DPPIC_NS->CHENSET = DPPI_CH_ENABLE_RADIO_EVENTS_DISABLED; +#endif +} + int ble_phy_init(void) { @@ -1296,6 +1410,8 @@ ble_phy_init(void) g_ble_phy_data.phy_stats_initialized = 1; } + ble_phy_dbg_time_setup(); + return 0; } @@ -1725,6 +1841,41 @@ ble_phy_restart_rx(void) ble_phy_rx(); } +static void +ble_phy_dbg_clear_pins(void) +{ +#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \ + MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \ + MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 + NRF_GPIO_Type *port; + int pin; + +#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 + pin = MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN); + port = pin > 31 ? NRF_P1_NS : NRF_P0_NS; + pin &= 0x1f; + + port->OUTCLR = (1 << pin); +#endif + +#if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 + pin = MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN); + port = pin > 31 ? NRF_P1_NS : NRF_P0_NS; + pin &= 0x1f; + + port->OUTCLR = (1 << pin); +#endif + +#if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 + pin = MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN); + port = pin > 31 ? NRF_P1_NS : NRF_P0_NS; + pin &= 0x1f; + + port->OUTCLR = (1 << pin); +#endif +#endif +} + void ble_phy_disable(void) { @@ -1732,6 +1883,8 @@ ble_phy_disable(void) ble_phy_stop_usec_timer(); ble_phy_disable_irq_and_ppi(); + + ble_phy_dbg_clear_pins(); } uint32_t diff --git a/nimble/drivers/nrf5340/syscfg.yml b/nimble/drivers/nrf5340/syscfg.yml index dd8b93047c..ed82f6d604 100644 --- a/nimble/drivers/nrf5340/syscfg.yml +++ b/nimble/drivers/nrf5340/syscfg.yml @@ -21,3 +21,42 @@ syscfg.defs: description: > Enable SystemView tracing module for radio driver. value: 0 + + BLE_PHY_DBG_TIME_TXRXEN_READY_PIN: + description: > + When set to proper GPIO pin number, this pin will be set + to high state when radio is enabled (TASKS_TXEN or TASKS_RXEN) + and back to low state on radio EVENTS_READY. + This can be used to measure radio ram-up time. + + Note: + GPIO control for selected pin needs to be assigned to Network + Core, configure IPC_NRF5340_NET_GPIO in ipc_nrf5340 driver on + Application Core. + value: -1 + + BLE_PHY_DBG_TIME_ADDRESS_END_PIN: + description: > + When set to proper GPIO pin number, this pin will be set + to high state on radio EVENTS_ADDRESS and back to low state + on radio EVENTS_END. + This can be used to measure radio pipeline delays. + + Note: + GPIO control for selected pin needs to be assigned to Network + Core, configure IPC_NRF5340_NET_GPIO in ipc_nrf5340 driver on + Application Core. + value: -1 + + BLE_PHY_DBG_TIME_WFR_PIN: + description: > + When set to proper GPIO pin number, this pin will be set + to high state on radio EVENTS_RXREADY and back to low + state when wfr timer expires. + This can be used to check if wfr is calculated properly. + + Note: + GPIO control for selected pin needs to be assigned to Network + Core, configure IPC_NRF5340_NET_GPIO in ipc_nrf5340 driver on + Application Core. + value: -1 From ff51d481cc1e2f16f124ce545a7510e42fb1b033 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 28 Dec 2021 15:12:42 +0100 Subject: [PATCH 0225/1333] nimble/ll: Add VS command for setting transmit power This command allows to override TX power configured with BLE_LL_TX_PWR_DBM syscfg value. If 0xff is provided BLE_LL_TX_PWR_DBM TX power is restored. --- nimble/controller/src/ble_ll.c | 4 +- nimble/controller/src/ble_ll_adv.c | 9 +-- nimble/controller/src/ble_ll_hci_vs.c | 85 +++++++++++++++++++++++++++ nimble/controller/src/ble_ll_priv.h | 2 + nimble/controller/syscfg.yml | 4 +- nimble/include/nimble/hci_common.h | 14 ++++- 6 files changed, 111 insertions(+), 7 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index f21f55ce07..1e378bc61b 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -65,6 +65,8 @@ * right thing to do. */ +int8_t g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); + /* Supported states */ #if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) #define BLE_LL_S_NCA ((uint64_t)1 << 0) @@ -1391,7 +1393,7 @@ ble_ll_task(void *arg) ble_phy_init(); /* Set output power to 1mW (0 dBm) */ - ble_phy_txpwr_set(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); + ble_phy_txpwr_set(g_ble_ll_tx_power); /* Register callback for transport */ ble_hci_trans_cfg_ll(ble_ll_hci_cmd_rx, NULL, ble_ll_hci_acl_rx, NULL); diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 8a6cd1fe56..db17dc4c22 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -41,6 +41,7 @@ #include "controller/ble_ll_utils.h" #include "controller/ble_ll_rfmgmt.h" #include "ble_ll_conn_priv.h" +#include "ble_ll_priv.h" #if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) @@ -1023,7 +1024,7 @@ ble_ll_adv_tx_done(void *arg) struct ble_ll_adv_sm *advsm; /* reset power to max after advertising */ - ble_phy_txpwr_set(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); + ble_phy_txpwr_set(g_ble_ll_tx_power); advsm = (struct ble_ll_adv_sm *)arg; @@ -1687,7 +1688,7 @@ ble_ll_adv_halt(void) ble_ll_trace_u32(BLE_LL_TRACE_ID_ADV_HALT, advsm->adv_instance); - ble_phy_txpwr_set(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); + ble_phy_txpwr_set(g_ble_ll_tx_power); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) if (advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING) { @@ -2112,8 +2113,8 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) static void ble_ll_adv_sync_tx_done(struct ble_ll_adv_sm *advsm) { - /* reset power to max after advertising */ - ble_phy_txpwr_set(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); + /* reset power to default after advertising */ + ble_phy_txpwr_set(g_ble_ll_tx_power); /* for sync we trace a no pri nor sec set */ ble_ll_trace_u32x2(BLE_LL_TRACE_ID_ADV_TXDONE, advsm->adv_instance, 0); diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index 8903525ec9..f2057ea428 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -21,7 +21,12 @@ #include "syscfg/syscfg.h" #include "controller/ble_ll.h" #include "controller/ble_ll_hci.h" +#include "controller/ble_ll_sync.h" +#include "controller/ble_ll_adv.h" +#include "controller/ble_ll_scan.h" #include "controller/ble_hw.h" +#include "ble_ll_conn_priv.h" +#include "ble_ll_priv.h" #if MYNEWT_VAL(BLE_LL_HCI_VS) @@ -51,9 +56,89 @@ ble_ll_hci_vs_rd_static_addr(uint16_t ocf, return BLE_ERR_SUCCESS; } +/* disallow changing TX power if there is any radio activity + * note: we could allow to change it if there is no TX activity (eg only + * passive scan or sync) but lets just keep this simple for now + */ +static int +ble_ll_hci_vs_is_controller_busy(void) +{ +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + struct ble_ll_conn_sm *cur; + int i = 0; +#endif + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) + if (ble_ll_sync_enabled()) { + return 1; + } +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) + if (ble_ll_adv_enabled()) { + return 1; + } +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) + if (ble_ll_scan_enabled()) { + return 1; + } +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + if (g_ble_ll_conn_create_sm.connsm) { + return 1; + } +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + STAILQ_FOREACH(cur, &g_ble_ll_conn_free_list, free_stqe) { + i++; + } + + /* check if all connection objects are free */ + if (i < MYNEWT_VAL(BLE_MAX_CONNECTIONS)) { + return 1; + } +#endif + + return 0; +} + +static int +ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_vs_set_tx_pwr_cp *cmd = (const void *) cmdbuf; + struct ble_hci_vs_set_tx_pwr_rp *rsp = (void *) rspbuf; + + if (cmdlen != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (ble_ll_hci_vs_is_controller_busy()) { + return BLE_ERR_CMD_DISALLOWED; + } + + if (cmd->tx_power == 127) { + /* restore reset default */ + g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); + } else { + g_ble_ll_tx_power = ble_phy_txpower_round(cmd->tx_power); + } + + rsp->tx_power = g_ble_ll_tx_power; + *rsplen = sizeof(*rsp); + + return BLE_ERR_SUCCESS; +} + static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_RD_STATIC_ADDR, ble_ll_hci_vs_rd_static_addr), + BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_TX_PWR, + ble_ll_hci_vs_set_tx_power), }; static struct ble_ll_hci_vs_cmd * diff --git a/nimble/controller/src/ble_ll_priv.h b/nimble/controller/src/ble_ll_priv.h index 900950ef64..ca8e082958 100644 --- a/nimble/controller/src/ble_ll_priv.h +++ b/nimble/controller/src/ble_ll_priv.h @@ -24,6 +24,8 @@ extern "C" { #endif +extern int8_t g_ble_ll_tx_power; + #ifdef MYNEWT #include "syscfg/syscfg.h" diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 41384cb5b4..afb3859708 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -68,7 +68,9 @@ syscfg.defs: range: 0..500 BLE_LL_TX_PWR_DBM: - description: 'Transmit power level.' + description: > + Default Transmit power level (in dBm). Actual transmit power + may be rounded up or down depending on used radio. value: '0' BLE_LL_NUM_COMP_PKT_ITVL_MS: diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 4851fd06da..e4830833b3 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1062,11 +1062,23 @@ struct ble_hci_le_set_host_feat_cp { } __attribute__((packed)); /* --- Vendor specific commands (OGF 0x003F) */ -#define BLE_HCI_OCF_VS_RD_STATIC_ADDR (0x0001) +/* Read Random Static Address */ +#define BLE_HCI_OCF_VS_RD_STATIC_ADDR (0x0001) struct ble_hci_vs_rd_static_addr_rp { uint8_t addr[6]; } __attribute__((packed)); +/* Set default transmit power. Actual selected TX power is returned + * in reply. Setting 0xff restores controller reset default. + */ +#define BLE_HCI_OCF_VS_SET_TX_PWR (0x0002) +struct ble_hci_vs_set_tx_pwr_cp { + int8_t tx_power; +} __attribute__((packed)); +struct ble_hci_vs_set_tx_pwr_rp { + int8_t tx_power; +} __attribute__((packed)); + /* Command Specific Definitions */ /* --- Set controller to host flow control (OGF 0x03, OCF 0x0031) --- */ #define BLE_HCI_CTLR_TO_HOST_FC_OFF (0) From 35a560341c294c0d626a7d5fcd17126f9e2e1b17 Mon Sep 17 00:00:00 2001 From: Yeming Li <625466940@qq.com> Date: Fri, 31 Dec 2021 15:40:18 +0800 Subject: [PATCH 0226/1333] nimble/ll: Adjust start time of the first anchor point of connection Set the start_time of the first anchor point of new connection to entry->end_time+1. For the 32768 Hz crystal in nrf chip, 1 tick is 30.517us. The connection state machine use anchor point to store the cpu ticks and anchor_point_usec to store the remainder. Therefore, to compensate the inaccuracy of the crystal, the ticks of anchor_point will be add with 1 once the value of anchor_point_usec exceed 31. If two connections have same connection interval, the time difference between the two start of schedule item will decreased 1, which lead to an overlap. To prevent this from happenning, we set the start_time of sch to 1 cpu tick after the end_time of entry. --- nimble/controller/src/ble_ll_sched.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index fe47dbc620..cd60014d67 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -237,7 +237,19 @@ ble_ll_sched_insert(struct ble_ll_sched_item *sch, uint32_t max_delay, } } else { preempt_first = NULL; - sch->start_time = entry->end_time; + /* + * For the 32768 Hz crystal in nrf chip, 1 tick is 30.517us. + * The connection state machine use anchor point to store the + * cpu ticks and anchor_point_usec to store the remainder. + * Therefore, to compensate the inaccuracy of the crystal, the + * ticks of anchor_point will be add with 1 once the value of + * anchor_point_usec exceed 31. If two connections have same + * connection interval, the time difference between the two + * start of schedule item will decreased 1, which lead to + * an overlap. To prevent this from happenning, we set the + * start_time of sch to 1 cpu tick after the end_time of entry. + */ + sch->start_time = entry->end_time + 1; if ((max_delay == 0) || CPUTIME_GEQ(sch->start_time, max_start_time)) { From 63edf82b826be155e866f948b21205ce20fd1c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 2 Dec 2021 10:36:26 +0100 Subject: [PATCH 0227/1333] host/mesh: make bt_le_adv_start match Zephyr API During sync `duration` argument was introduced, which is not intended to be in `bt_le_adv_start` - duration of advertising is managed by events in bt_mesh_adv_queue. --- nimble/host/mesh/include/mesh/glue.h | 1 - nimble/host/mesh/src/adv_legacy.c | 5 ++--- nimble/host/mesh/src/glue.c | 4 +--- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index 44631f3e57..58e3e2d8de 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -418,7 +418,6 @@ int bt_ccm_encrypt(const uint8_t key[16], uint8_t nonce[13], const uint8_t *enc_ uint8_t *plaintext, size_t mic_size); void bt_mesh_register_gatt(void); int bt_le_adv_start(const struct ble_gap_adv_params *param, - int64_t duration, const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len); diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index 5bebff8960..32ebeb60d9 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -107,8 +107,7 @@ static inline void adv_send(struct os_mbuf *buf) int64_t time = k_uptime_get(); - err = bt_le_adv_start(¶m, duration, &ad, 1, NULL, 0); - + err = bt_le_adv_start(¶m, &ad, 1, NULL, 0); bt_mesh_adv_send_start(duration, err, BT_MESH_ADV(buf)); if (err) { @@ -240,6 +239,6 @@ int bt_mesh_adv_start(const struct ble_gap_adv_params *param, int32_t duration, const struct bt_data *sd, size_t sd_len) { adv_timeout = duration; - return bt_le_adv_start(param, duration, ad, ad_len, sd, sd_len); + return bt_le_adv_start(param, ad, ad_len, sd, sd_len); } #endif diff --git a/nimble/host/mesh/src/glue.c b/nimble/host/mesh/src/glue.c index 7a811210f3..c00af9477e 100644 --- a/nimble/host/mesh/src/glue.c +++ b/nimble/host/mesh/src/glue.c @@ -712,7 +712,6 @@ ble_adv_conf_adv_instance(const struct ble_gap_adv_params *param, int *instance) int bt_le_adv_start(const struct ble_gap_adv_params *param, - int64_t duration, const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len) { @@ -778,7 +777,7 @@ bt_le_adv_start(const struct ble_gap_adv_params *param, } /*TODO: We could use duration and max events in the future */ - err = ble_gap_ext_adv_start(instance, duration, 0); + err = ble_gap_ext_adv_start(instance, 0, 0); return err; error: @@ -792,7 +791,6 @@ bt_le_adv_start(const struct ble_gap_adv_params *param, int bt_le_adv_start(const struct ble_gap_adv_params *param, - int64_t duration, const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len) { From 43a74391e0407df5d37472d5697adec54759a438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 2 Dec 2021 10:38:45 +0100 Subject: [PATCH 0228/1333] host/mesh: fix handling of bt_mesh_adv_queue in mesh_adv_thread `ble_npl_eventq_get` is waiting for events for duration in tick units, not ms. This means that we're waiting OS_TICKS_PER_SEC times to long and catch events that are meant to be missed. --- nimble/host/mesh/src/adv_legacy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index 32ebeb60d9..e495dd614c 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -154,7 +154,7 @@ mesh_adv_thread(void *args) BT_DBG("PB-GATT Advertising up to %d ms", (int) adv_timeout); } - ev = ble_npl_eventq_get(&bt_mesh_adv_queue, adv_timeout); + ev = ble_npl_eventq_get(&bt_mesh_adv_queue, ble_npl_time_ms_to_ticks32(adv_timeout)); bt_le_adv_stop(); } } else { From 30370ffb57ac10e39b0124b6d5a103f260c1f0a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 18 Jan 2022 15:08:33 +0100 Subject: [PATCH 0229/1333] host/ble_gattc: Cancel prepered writes if data doesn't match in response If data received in ble_gattc_write_long_rx_prep() doesn't match data sent in prepare write request we need not only return error in function, but also send ATT_Execute_Write_Response with flag set to BLE_ATT_EXEC_WRITE_F_CANCEL. This is affecting GATT/CL/GAW/BI-32-C --- nimble/host/src/ble_gattc.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index 74a2837ad7..b43a0af03c 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -3765,17 +3765,20 @@ ble_gattc_write_long_rx_prep(struct ble_gattc_proc *proc, proc->write_long.length) != 0) { rc = BLE_HS_EBADDATA; - goto err; - } - /* Send follow-up request. */ - proc->write_long.attr.offset += OS_MBUF_PKTLEN(om); - rc = ble_gattc_write_long_resume(proc); - if (rc != 0) { + /* if data doesn't match up send cancel write */ + ble_att_clt_tx_exec_write(proc->conn_handle, BLE_ATT_EXEC_WRITE_F_CANCEL); goto err; - } + } else { + /* Send follow-up request. */ + proc->write_long.attr.offset += OS_MBUF_PKTLEN(om); + rc = ble_gattc_write_long_resume(proc); + if (rc != 0) { + goto err; + } - return 0; + return 0; + } err: /* XXX: Might need to cancel pending writes. */ From 403ae02652075f89b71e19736b78834c7fcc1ebe Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Mon, 22 Nov 2021 09:50:16 +0100 Subject: [PATCH 0230/1333] transport: Add bridge transport blehci application is for controller only build with external interface. In case of dual-core MCUs (NRF5340, DA1469x) controller runs on second core that may not be able to operate on external interface. To be able to run blehci like application on dual-core systems, application side has to route traffic from external interface transport to internal transport. So far only one transport package was used, for bridge configuration application must include two transport packages. To facilitate this: - transport package has BLE_HCI_BRIDGE that is set to 1 for dual-core bridge configuration - common syscfg values defined for in all transports are moved to transport package (BLE_HCI_EVT_HI_BUF_COUNT..) - syscfg definitions present in all transport packages are converted to syscfg values - DA1469x and NRF5340 transports in bridge configuration will NOT create buffers for commands and events they relay on external transport provided buffers --- nimble/transport/da1469x/syscfg.yml | 30 +++--------- .../cmac_driver/diag/src/cmac_diag.c | 2 +- .../include/cmac_driver/cmac_shared.h | 4 +- .../transport/dialog_cmac/cmac_driver/pkg.yml | 3 ++ .../dialog_cmac/cmac_driver/src/cmac_mbox.c | 4 +- .../dialog_cmac/cmac_driver/src/cmac_rand.c | 2 +- .../dialog_cmac/cmac_driver/src/cmac_shared.c | 6 +-- .../dialog_cmac/src/ble_hci_cmac_common.c | 8 ++++ .../dialog_cmac/src/ble_hci_cmac_hs.c | 2 +- .../dialog_cmac/src/ble_hci_trans_h4.c | 10 ++-- nimble/transport/dialog_cmac/syscfg.yml | 30 +++--------- nimble/transport/emspi/syscfg.yml | 31 ++++-------- .../transport/nrf5340/src/nrf5340_ble_hci.c | 23 ++++++--- nimble/transport/nrf5340/syscfg.yml | 33 ++++--------- nimble/transport/pkg.yml | 6 +++ nimble/transport/ram/syscfg.yml | 29 +++-------- nimble/transport/socket/syscfg.yml | 27 ++++------- nimble/transport/syscfg.yml | 48 +++++++++++++++++++ nimble/transport/uart/src/ble_hci_uart.c | 16 ++++--- nimble/transport/uart/syscfg.yml | 25 +++------- nimble/transport/usb/syscfg.yml | 25 +++------- 21 files changed, 167 insertions(+), 197 deletions(-) diff --git a/nimble/transport/da1469x/syscfg.yml b/nimble/transport/da1469x/syscfg.yml index 4ea9da9b36..2ce8cd3cf2 100644 --- a/nimble/transport/da1469x/syscfg.yml +++ b/nimble/transport/da1469x/syscfg.yml @@ -16,28 +16,12 @@ # under the License. # -syscfg.defs: - BLE_HCI_EVT_HI_BUF_COUNT: - description: 'Number of high-priority event buffers.' - value: 2 +syscfg.vals.'!BLE_HCI_BRIDGE && !BLE_EXT_ADV': + BLE_HCI_EVT_HI_BUF_COUNT: 2 + BLE_HCI_EVT_LO_BUF_COUNT: 8 + BLE_HCI_EVT_BUF_SIZE: 70 + BLE_ACL_BUF_COUNT: 4 + BLE_ACL_BUF_SIZE: 255 - BLE_HCI_EVT_LO_BUF_COUNT: - description: 'Number of low-priority event buffers.' - value: 8 - - BLE_HCI_EVT_BUF_SIZE: - description: 'Size of each event buffer, in bytes.' - value: 70 - - BLE_ACL_BUF_COUNT: - description: 'The number of ACL data buffers' - value: 4 - - BLE_ACL_BUF_SIZE: - description: > - This is the maximum size of the data portion of HCI ACL data - packets. It does not include the HCI data header (of 4 bytes). - value: 255 - -syscfg.vals.BLE_EXT_ADV: +syscfg.vals.'!BLE_HCI_BRIDGE && BLE_EXT_ADV': BLE_HCI_EVT_BUF_SIZE: 274 diff --git a/nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c b/nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c index 4f75470654..0a4e27e6d5 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c +++ b/nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c @@ -20,7 +20,7 @@ #include "syscfg/syscfg.h" #include "mcu/mcu.h" -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) void cmac_diag_setup_host(void) { diff --git a/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h b/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h index 90b5827dd4..4e37bb8b82 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h +++ b/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h @@ -131,7 +131,7 @@ struct cmac_shared_data { uint8_t mbox_c2s_buf[ MYNEWT_VAL(CMAC_MBOX_SIZE_C2S) ]; }; -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) extern volatile struct cmac_shared_data *g_cmac_shared_data; #elif MYNEWT_VAL(BLE_CONTROLLER) extern volatile struct cmac_shared_data g_cmac_shared_data; @@ -161,7 +161,7 @@ void cmac_rand_set_isr_cb(cmac_rand_isr_cb_t cb); void cmac_shared_init(void); void cmac_shared_sync(void); -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) #define CMAC_SHARED_LOCK_VAL 0x40000000 #elif MYNEWT_VAL(BLE_CONTROLLER) #define CMAC_SHARED_LOCK_VAL 0xc0000000 diff --git a/nimble/transport/dialog_cmac/cmac_driver/pkg.yml b/nimble/transport/dialog_cmac/cmac_driver/pkg.yml index 5b4a212914..00200b65a7 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/pkg.yml +++ b/nimble/transport/dialog_cmac/cmac_driver/pkg.yml @@ -37,3 +37,6 @@ pkg.post_link_cmds.BLE_CONTROLLER: pkg.pre_link_cmds.BLE_HOST: scripts/build_libcmac.sh: 100 + +pkg.pre_link_cmds.BLE_HCI_BRIDGE: + scripts/build_libcmac.sh: 100 diff --git a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c index 9594dbe900..88764c4dfc 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c +++ b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c @@ -49,7 +49,7 @@ cmac_mbox_set_write_notif_cb(cmac_mbox_write_notif_cb *cb) int cmac_mbox_read(void) { -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_c2s; uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data->mbox_c2s_buf; const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_C2S); @@ -96,7 +96,7 @@ cmac_mbox_read(void) int cmac_mbox_write(const void *data, uint16_t len) { -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_s2c; uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data->mbox_s2c_buf; const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_S2C); diff --git a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c index 67a315f96e..10810972ca 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c +++ b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c @@ -26,7 +26,7 @@ #include "os/os_arch.h" #include "os/os.h" -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) int cmac_rand_is_active(void) { diff --git a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c index 24640ca475..a4f2e37f56 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c +++ b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c @@ -34,7 +34,7 @@ #define min(_a, _b) ((_a) < (_b) ? (_a) : (_b)) #endif -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) volatile struct cmac_shared_data *g_cmac_shared_data; #include "mcu/da1469x_clock.h" #define MCU_DIAG_SER(_x) @@ -45,7 +45,7 @@ volatile struct cmac_shared_data g_cmac_shared_data __attribute__((section(" void cmac_shared_init(void) { -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) g_cmac_shared_data = (void *)(MCU_MEM_SYSRAM_START_ADDRESS + MEMCTRL->CMI_SHARED_BASE_REG); @@ -77,7 +77,7 @@ cmac_shared_sync(void) * to wait until CMAC finished initialization as otherwise host may start * sending HCI packets which will timeout as there is no one to read them. */ -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) assert(g_cmac_shared_data->magic_sys == 0); while (g_cmac_shared_data->magic_cmac != CMAC_SHARED_MAGIC_CMAC); diff --git a/nimble/transport/dialog_cmac/src/ble_hci_cmac_common.c b/nimble/transport/dialog_cmac/src/ble_hci_cmac_common.c index 665b62166b..5a41ee6313 100644 --- a/nimble/transport/dialog_cmac/src/ble_hci_cmac_common.c +++ b/nimble/transport/dialog_cmac/src/ble_hci_cmac_common.c @@ -41,6 +41,7 @@ BLE_MBUF_MEMBLOCK_OVERHEAD + \ BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT) +#if !MYNEWT_VAL(BLE_HCI_BRIDGE) static uint8_t ble_hci_pool_cmd_mempool_buf[ OS_MEMPOOL_BYTES(HCI_CMD_COUNT, BLE_HCI_TRANS_CMD_SZ)]; static struct os_mempool ble_hci_pool_cmd_mempool; @@ -54,6 +55,7 @@ static uint8_t ble_hci_pool_evt_lo_mempool_buf[ OS_MEMPOOL_BYTES(MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE))]; static struct os_mempool ble_hci_pool_evt_lo_mempool; +#endif static uint8_t ble_hci_pool_acl_mempool_buf[ OS_MEMPOOL_BYTES(MYNEWT_VAL(BLE_ACL_BUF_COUNT), @@ -66,6 +68,7 @@ __attribute__((weak)) void ble_hci_trans_notify_free(void); static os_mempool_put_fn *g_ble_hci_pool_acl_mempool_put_cb; static void *g_ble_hci_pool_acl_mempool_put_arg; +#if !MYNEWT_VAL(BLE_HCI_BRIDGE) int ble_hci_trans_reset(void) { @@ -117,6 +120,7 @@ ble_hci_trans_buf_free(uint8_t *buf) ble_hci_trans_notify_free(); } +#endif struct os_mbuf * ble_hci_cmac_alloc_acl_mbuf(void) @@ -147,6 +151,7 @@ ble_hci_cmac_free_acl_cb(struct os_mempool_ext *mpe, void *data, void *arg) } +#if !MYNEWT_VAL(BLE_HCI_BRIDGE) int ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg) { @@ -155,6 +160,7 @@ ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg) return 0; } +#endif void ble_hci_cmac_init(void) @@ -163,6 +169,7 @@ ble_hci_cmac_init(void) SYSINIT_ASSERT_ACTIVE(); +#if !MYNEWT_VAL(BLE_HCI_BRIDGE) rc = os_mempool_init(&ble_hci_pool_cmd_mempool, HCI_CMD_COUNT, BLE_HCI_TRANS_CMD_SZ, ble_hci_pool_cmd_mempool_buf, "ble_hci_cmd"); @@ -179,6 +186,7 @@ ble_hci_cmac_init(void) MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), ble_hci_pool_evt_lo_mempool_buf, "ble_hci_evt_lo"); SYSINIT_PANIC_ASSERT(rc == 0); +#endif rc = os_mempool_ext_init(&ble_hci_pool_acl_mempool, MYNEWT_VAL(BLE_ACL_BUF_COUNT), POOL_ACL_BLOCK_SIZE, diff --git a/nimble/transport/dialog_cmac/src/ble_hci_cmac_hs.c b/nimble/transport/dialog_cmac/src/ble_hci_cmac_hs.c index 1164fe7186..172fc87952 100644 --- a/nimble/transport/dialog_cmac/src/ble_hci_cmac_hs.c +++ b/nimble/transport/dialog_cmac/src/ble_hci_cmac_hs.c @@ -21,7 +21,7 @@ #include #include "syscfg/syscfg.h" -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) #include "cmac_driver/cmac_shared.h" #include "cmac_driver/cmac_host.h" diff --git a/nimble/transport/dialog_cmac/src/ble_hci_trans_h4.c b/nimble/transport/dialog_cmac/src/ble_hci_trans_h4.c index 74da391239..628ae75d96 100644 --- a/nimble/transport/dialog_cmac/src/ble_hci_trans_h4.c +++ b/nimble/transport/dialog_cmac/src/ble_hci_trans_h4.c @@ -64,7 +64,7 @@ ble_hci_trans_h4_rxs_start(struct ble_hci_trans_h4_rx_state *rxs, uint8_t pkt_ty case BLE_HCI_TRANS_H4_PKT_TYPE_ACL: rxs->min_len = 4; break; -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) case BLE_HCI_TRANS_H4_PKT_TYPE_EVT: rxs->min_len = 2; break; @@ -95,7 +95,7 @@ static int ble_hci_trans_h4_rx_state_w4_header(struct ble_hci_trans_h4_rx_state *rxs, struct input_buffer *ib) { -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) int pool; #endif int rc; @@ -127,7 +127,7 @@ ble_hci_trans_h4_rx_state_w4_header(struct ble_hci_trans_h4_rx_state *rxs, os_mbuf_append(rxs->om, rxs->hdr, rxs->len); rxs->expected_len = get_le16(&rxs->hdr[2]) + 4; break; -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) case BLE_HCI_TRANS_H4_PKT_TYPE_EVT: pool = BLE_HCI_TRANS_BUF_EVT_HI; if (rxs->hdr[0] == BLE_HCI_EVCODE_LE_META) { @@ -194,7 +194,7 @@ ble_hci_trans_h4_rx_state_w4_payload(struct ble_hci_trans_h4_rx_state *rxs, #if MYNEWT_VAL(BLE_CONTROLLER) case BLE_HCI_TRANS_H4_PKT_TYPE_CMD: #endif -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) case BLE_HCI_TRANS_H4_PKT_TYPE_EVT: #endif if (rxs->buf) { @@ -240,7 +240,7 @@ ble_hci_trans_h4_rx_state_completed(struct ble_hci_trans_h4_rx_state *rxs, #if MYNEWT_VAL(BLE_CONTROLLER) case BLE_HCI_TRANS_H4_PKT_TYPE_CMD: #endif -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) case BLE_HCI_TRANS_H4_PKT_TYPE_EVT: #endif if (rxs->buf) { diff --git a/nimble/transport/dialog_cmac/syscfg.yml b/nimble/transport/dialog_cmac/syscfg.yml index c44773efcd..54607fd814 100644 --- a/nimble/transport/dialog_cmac/syscfg.yml +++ b/nimble/transport/dialog_cmac/syscfg.yml @@ -16,28 +16,12 @@ # under the License. # -syscfg.defs: - BLE_HCI_EVT_HI_BUF_COUNT: - description: 'Number of high-priority event buffers.' - value: 2 +syscfg.vals.'!BLE_HCI_BRIDGE && !(BLE_EXT_ADV || BLE_LL_CFG_FEAT_LL_EXT_ADV)': + BLE_HCI_EVT_HI_BUF_COUNT: 2 + BLE_HCI_EVT_LO_BUF_COUNT: 8 + BLE_HCI_EVT_BUF_SIZE: 70 + BLE_ACL_BUF_COUNT: 4 + BLE_ACL_BUF_SIZE: 255 - BLE_HCI_EVT_LO_BUF_COUNT: - description: 'Number of low-priority event buffers.' - value: 8 - - BLE_HCI_EVT_BUF_SIZE: - description: 'Size of each event buffer, in bytes.' - value: 70 - - BLE_ACL_BUF_COUNT: - description: 'The number of ACL data buffers' - value: 4 - - BLE_ACL_BUF_SIZE: - description: > - This is the maximum size of the data portion of HCI ACL data - packets. It does not include the HCI data header (of 4 bytes). - value: 255 - -syscfg.vals.'BLE_EXT_ADV || BLE_LL_CFG_FEAT_LL_EXT_ADV': +syscfg.vals.'!BLE_HCI_BRIDGE && (BLE_EXT_ADV || BLE_LL_CFG_FEAT_LL_EXT_ADV)': BLE_HCI_EVT_BUF_SIZE: 257 diff --git a/nimble/transport/emspi/syscfg.yml b/nimble/transport/emspi/syscfg.yml index 4751271b0d..501175467a 100644 --- a/nimble/transport/emspi/syscfg.yml +++ b/nimble/transport/emspi/syscfg.yml @@ -28,28 +28,6 @@ syscfg.defs: # This is a host-only transport. - BLE_HOST - BLE_HCI_EVT_HI_BUF_COUNT: - description: 'Number of high-priority event buffers.' - value: 2 - - BLE_HCI_EVT_LO_BUF_COUNT: - description: 'Number of low-priority event buffers.' - value: 8 - - BLE_HCI_EVT_BUF_SIZE: - description: 'Size of each event buffer, in bytes.' - value: 70 - - BLE_ACL_BUF_COUNT: - description: 'The number of ACL data buffers' - value: 4 - - BLE_ACL_BUF_SIZE: - description: > - This is the maximum size of the data portion of HCI ACL data - packets. It does not include the HCI data header (of 4 bytes). - value: 255 - BLE_HCI_ACL_OUT_COUNT: description: > This count is used in creating a pool of elements used by the @@ -95,5 +73,12 @@ syscfg.defs: Sysinit stage for the EMSPI BLE transport. value: 100 -syscfg.vals.BLE_EXT_ADV: +syscfg.vals.'!BLE_HCI_BRIDGE && BLE_EXT_ADV': BLE_HCI_EVT_BUF_SIZE: 257 + +syscfg.vals.'!BLE_HCI_BRIDGE && !BLE_EXT_ADV': + BLE_HCI_EVT_HI_BUF_COUNT: 2 + BLE_HCI_EVT_LO_BUF_COUNT: 8 + BLE_HCI_EVT_BUF_SIZE: 70 + BLE_ACL_BUF_COUNT: 4 + BLE_ACL_BUF_SIZE: 255 diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index 9bf956b56b..fe93c0fd6e 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -39,7 +39,7 @@ #define IPC_RX_CHANNEL 1 #endif -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) #define IPC_TX_CHANNEL 1 #define IPC_RX_CHANNEL 0 #endif @@ -49,7 +49,7 @@ struct nrf5340_ble_hci_api { ble_hci_trans_rx_cmd_fn *cmd_cb; void *cmd_arg; #endif -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) ble_hci_trans_rx_cmd_fn *evt_cb; void *evt_arg; #endif @@ -73,6 +73,7 @@ struct nrf5340_ble_hci_pool_cmd { bool allocated; }; +#if !MYNEWT_VAL(BLE_HCI_BRIDGE) /* * If controller-to-host flow control is enabled we need to hold an extra command * buffer for HCI_Host_Number_Of_Completed_Packets which can be sent at any time. @@ -98,6 +99,8 @@ static uint8_t nrf5340_ble_hci_pool_evt_lo_buf[OS_MEMPOOL_BYTES( MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE))]; static struct os_mempool nrf5340_ble_hci_pool_evt_lo; +#endif + /* Pool for ACL data */ static uint8_t nrf5340_ble_hci_pool_acl_buf[OS_MEMPOOL_BYTES( MYNEWT_VAL(BLE_ACL_BUF_COUNT), @@ -111,12 +114,14 @@ static struct nrf5340_ble_hci_api nrf5340_ble_hci_api; /* State of RX currently in progress (needs to reassemble frame) */ static struct nrf5340_ble_hci_rx_data nrf5340_ble_hci_rx_data; +#if !MYNEWT_VAL(BLE_HCI_BRIDGE) int ble_hci_trans_reset(void) { /* XXX Should we do something with RF and/or BLE core? */ return 0; } +#endif static int ble_hci_trans_acl_tx(struct os_mbuf *om) @@ -177,7 +182,7 @@ ble_hci_trans_ll_acl_tx(struct os_mbuf *om) } #endif -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) void ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *evt_cb, void *evt_arg, ble_hci_trans_rx_acl_fn *acl_cb, void *acl_arg) @@ -212,6 +217,7 @@ ble_hci_trans_hs_acl_tx(struct os_mbuf *om) } #endif +#if !MYNEWT_VAL(BLE_HCI_BRIDGE) uint8_t * ble_hci_trans_buf_alloc(int type) { @@ -255,12 +261,13 @@ ble_hci_trans_buf_free(uint8_t *buf) assert(rc == 0); } } +#endif static void nrf5340_ble_hci_trans_rx_process(int channel) { struct nrf5340_ble_hci_rx_data *rxd = &nrf5340_ble_hci_rx_data; -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) int pool = BLE_HCI_TRANS_BUF_EVT_HI; #endif int rc; @@ -274,7 +281,7 @@ nrf5340_ble_hci_trans_rx_process(int channel) #if MYNEWT_VAL(BLE_CONTROLLER) assert((rxd->type == HCI_PKT_ACL) || (rxd->type == HCI_PKT_CMD)); #endif -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) assert((rxd->type == HCI_PKT_ACL) || (rxd->type == HCI_PKT_EVT)); #endif break; @@ -312,7 +319,7 @@ nrf5340_ble_hci_trans_rx_process(int channel) rxd->type = HCI_PKT_NONE; break; #endif -#if MYNEWT_VAL(BLE_HOST) +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) case HCI_PKT_EVT: /* header */ if (rxd->len < 2) { @@ -433,6 +440,7 @@ nrf5340_ble_hci_trans_rx(int channel, void *user_data) } } +#if !MYNEWT_VAL(BLE_HCI_BRIDGE) int ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg) { @@ -441,6 +449,7 @@ ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg) return 0; } +#endif void nrf5340_ble_hci_init(void) @@ -460,6 +469,7 @@ nrf5340_ble_hci_init(void) MYNEWT_VAL(BLE_ACL_BUF_COUNT)); SYSINIT_PANIC_ASSERT(rc == 0); +#if !MYNEWT_VAL(BLE_HCI_BRIDGE) rc = os_mempool_init(&nrf5340_ble_hci_pool_evt_hi, MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), @@ -479,6 +489,7 @@ nrf5340_ble_hci_init(void) nrf5340_ble_hci_pool_cmd_mempool_buf, "nrf5340_ble_hci_pool_cmd_mempool"); SYSINIT_PANIC_ASSERT(rc == 0); +#endif ipc_nrf5340_recv(IPC_RX_CHANNEL, nrf5340_ble_hci_trans_rx, NULL); } diff --git a/nimble/transport/nrf5340/syscfg.yml b/nimble/transport/nrf5340/syscfg.yml index 1417bbc03d..a12e0c3736 100644 --- a/nimble/transport/nrf5340/syscfg.yml +++ b/nimble/transport/nrf5340/syscfg.yml @@ -17,34 +17,21 @@ # syscfg.defs: - BLE_HCI_EVT_HI_BUF_COUNT: - description: 'Number of high-priority event buffers.' - value: 2 - - BLE_HCI_EVT_LO_BUF_COUNT: - description: 'Number of low-priority event buffers.' - value: 8 - - BLE_HCI_EVT_BUF_SIZE: - description: 'Size of each event buffer, in bytes.' - value: 70 - - BLE_ACL_BUF_COUNT: - description: 'The number of ACL data buffers' - value: 4 - - BLE_ACL_BUF_SIZE: - description: > - This is the maximum size of the data portion of HCI ACL data - packets. It does not include the HCI data header (of 4 bytes). - value: 255 - BLE_TRANS_NRF5340_SYSINIT_STAGE: description: > Sysinit stage for the RAM BLE transport. value: 100 -syscfg.vals.BLE_EXT_ADV: +syscfg.vals.'!BLE_HCI_BRIDGE: + BLE_HCI_EVT_HI_BUF_COUNT: 2 + BLE_HCI_EVT_LO_BUF_COUNT: 8 + BLE_ACL_BUF_COUNT: 4 + BLE_ACL_BUF_SIZE: 255 + +syscfg.vals.'!BLE_HCI_BRIDGE && !BLE_EXT_ADV': + BLE_HCI_EVT_BUF_SIZE: 70 + +syscfg.vals.'!BLE_HCI_BRIDGE && BLE_EXT_ADV': BLE_HCI_EVT_BUF_SIZE: 257 syscfg.restrictions: diff --git a/nimble/transport/pkg.yml b/nimble/transport/pkg.yml index 8174286d06..5484002ebc 100644 --- a/nimble/transport/pkg.yml +++ b/nimble/transport/pkg.yml @@ -52,3 +52,9 @@ pkg.deps.'BLE_HCI_TRANSPORT == "usb"': pkg.deps.'BLE_HCI_TRANSPORT == "nrf5340"': - nimble/transport/nrf5340 + +pkg.deps.'BLE_HCI_BRIDGE_TRANSPORT == "nrf5340"': + - nimble/transport/nrf5340 + +pkg.deps.'BLE_HCI_BRIDGE_TRANSPORT == "dialog_cmac"': + - nimble/transport/dialog_cmac diff --git a/nimble/transport/ram/syscfg.yml b/nimble/transport/ram/syscfg.yml index cbb57163ad..6286dfe722 100644 --- a/nimble/transport/ram/syscfg.yml +++ b/nimble/transport/ram/syscfg.yml @@ -17,32 +17,17 @@ # syscfg.defs: - BLE_HCI_EVT_HI_BUF_COUNT: - description: 'Number of high-priority event buffers.' - value: 2 - - BLE_HCI_EVT_LO_BUF_COUNT: - description: 'Number of low-priority event buffers.' - value: 8 - - BLE_HCI_EVT_BUF_SIZE: - description: 'Size of each event buffer, in bytes.' - value: 70 - - BLE_ACL_BUF_COUNT: - description: 'The number of ACL data buffers' - value: 4 - - BLE_ACL_BUF_SIZE: - description: > - This is the maximum size of the data portion of HCI ACL data - packets. It does not include the HCI data header (of 4 bytes). - value: 65535 - BLE_TRANS_RAM_SYSINIT_STAGE: description: > Sysinit stage for the RAM BLE transport. value: 100 +syscfg.vals: + BLE_HCI_EVT_HI_BUF_COUNT: 2 + BLE_HCI_EVT_LO_BUF_COUNT: 8 + BLE_HCI_EVT_BUF_SIZE: 70 + BLE_ACL_BUF_COUNT: 4 + BLE_ACL_BUF_SIZE: 65535 + syscfg.vals.BLE_EXT_ADV: BLE_HCI_EVT_BUF_SIZE: 257 diff --git a/nimble/transport/socket/syscfg.yml b/nimble/transport/socket/syscfg.yml index 2050f64692..9c8fa583d6 100644 --- a/nimble/transport/socket/syscfg.yml +++ b/nimble/transport/socket/syscfg.yml @@ -17,24 +17,6 @@ # syscfg.defs: - BLE_HCI_EVT_BUF_SIZE: - description: 'The size of the allocated event buffers' - value: 70 - BLE_HCI_EVT_HI_BUF_COUNT: - description: 'The number of high priority event buffers' - value: 8 - BLE_HCI_EVT_LO_BUF_COUNT: - description: 'The number of low priority event buffers' - value: 8 - BLE_ACL_BUF_COUNT: - description: 'The number of ACL data buffers' - value: 24 - BLE_ACL_BUF_SIZE: - description: > - This is the maximum size of the data portion of HCI ACL data - packets. It does not include the HCI data header (of 4 bytes). - value: 255 - BLE_HCI_ACL_OUT_COUNT: description: > This count is used in creating a pool of elements used by the @@ -75,5 +57,12 @@ syscfg.defs: Sysinit stage for the socket BLE transport. value: 500 -syscfg.vals.BLE_EXT_ADV: +syscfg.vals.'!BLE_HCI_BRIDGE && BLE_EXT_ADV': BLE_HCI_EVT_BUF_SIZE: 257 + +syscfg.vals.'!BLE_HCI_BRIDGE && !BLE_EXT_ADV': + BLE_HCI_EVT_BUF_SIZE: 70 + BLE_HCI_EVT_HI_BUF_COUNT: 8 + BLE_HCI_EVT_LO_BUF_COUNT: 8 + BLE_ACL_BUF_COUNT: 24 + BLE_ACL_BUF_SIZE: 255 diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml index 5bec6adf4d..7eed69ba4e 100644 --- a/nimble/transport/syscfg.yml +++ b/nimble/transport/syscfg.yml @@ -37,6 +37,47 @@ syscfg.defs: - usb # USB - nrf5340 # nRF5340 + BLE_HCI_BRIDGE_TRANSPORT: + description: > + Selects HCI transport to be included in bridge configuration build. + This applies to multi core configurations where controller runs + on separate core and main core forwards HCI traffic to external host. + This has virtually the same effect as including package dependency + manually, but it allows to easily override HCI transport package in + application or target settings. + This is the transport + value: + choices: + - dialog_cmac # Dialog CMAC via shared memory + - nrf5340 # nRF5340 + + BLE_HCI_BRIDGE: + description: > + External interface (UART/USB/Socket) bridged to second core controller. + value: 0 + + BLE_HCI_EVT_HI_BUF_COUNT: + description: 'Number of high-priority event buffers.' + value: + + BLE_HCI_EVT_LO_BUF_COUNT: + description: 'Number of low-priority event buffers.' + value: + + BLE_HCI_EVT_BUF_SIZE: + description: 'Size of each event buffer, in bytes.' + value: + + BLE_ACL_BUF_COUNT: + description: 'The number of ACL data buffers' + value: + + BLE_ACL_BUF_SIZE: + description: > + This is the maximum size of the data portion of HCI ACL data + packets. + value: + # Deprecated settings BLE_HCI_TRANSPORT_NIMBLE_BUILTIN: description: Use BLE_HCI_TRANSPORT instead. @@ -69,3 +110,10 @@ syscfg.vals.BLE_HCI_TRANSPORT_SOCKET: BLE_HCI_TRANSPORT: socket syscfg.vals.BLE_HCI_TRANSPORT_EMSPI: BLE_HCI_TRANSPORT: emspi + +syscfg.vals.'(MCU_TARGET == "DA14691" || MCU_TARGET == "DA14695" || MCU_TARGET == "DA14697" || MCU_TARGET == "DA14699")': + BLE_HCI_BRIDGE_TRANSPORT: dialog_cmac + +syscfg.vals.'(MCU_TARGET == "nRF5340_APP")': + BLE_HCI_BRIDGE_TRANSPORT: nrf5340 + diff --git a/nimble/transport/uart/src/ble_hci_uart.c b/nimble/transport/uart/src/ble_hci_uart.c index ac49b30b07..cc796c0005 100644 --- a/nimble/transport/uart/src/ble_hci_uart.c +++ b/nimble/transport/uart/src/ble_hci_uart.c @@ -53,7 +53,7 @@ */ /* XXX: for now, define this here */ -#if MYNEWT_VAL(BLE_CONTROLLER) +#if MYNEWT_VAL(BLE_CONTROLLER) || MYNEWT_VAL(BLE_HCI_BRIDGE) extern void ble_ll_data_buffer_overflow(void); extern void ble_ll_hw_error(void); @@ -385,7 +385,7 @@ ble_hci_uart_tx_char(void *arg) return rc; } -#if MYNEWT_VAL(BLE_CONTROLLER) +#if MYNEWT_VAL(BLE_CONTROLLER) || MYNEWT_VAL(BLE_HCI_BRIDGE) /** * HCI uart sync lost. * @@ -418,7 +418,7 @@ ble_hci_uart_rx_pkt_type(uint8_t data) switch (ble_hci_uart_state.rx_type) { /* Host should never receive a command! */ -#if MYNEWT_VAL(BLE_CONTROLLER) +#if MYNEWT_VAL(BLE_CONTROLLER) || MYNEWT_VAL(BLE_HCI_BRIDGE) case BLE_HCI_UART_H4_CMD: ble_hci_uart_state.rx_cmd.len = 0; ble_hci_uart_state.rx_cmd.cur = 0; @@ -458,7 +458,7 @@ ble_hci_uart_rx_pkt_type(uint8_t data) break; default: -#if MYNEWT_VAL(BLE_CONTROLLER) +#if MYNEWT_VAL(BLE_CONTROLLER) || MYNEWT_VAL(BLE_HCI_BRIDGE) /* * If we receive an unknown HCI packet type this is considered a loss * of sync. @@ -477,7 +477,7 @@ ble_hci_uart_rx_pkt_type(uint8_t data) return 0; } -#if MYNEWT_VAL(BLE_CONTROLLER) +#if MYNEWT_VAL(BLE_CONTROLLER) || MYNEWT_VAL(BLE_HCI_BRIDGE) /** * HCI uart sync loss. * @@ -708,7 +708,7 @@ ble_hci_uart_rx_acl(uint8_t data) */ if (pktlen > MYNEWT_VAL(BLE_ACL_BUF_SIZE)) { os_mbuf_free_chain(ble_hci_uart_state.rx_acl.buf); -#if MYNEWT_VAL(BLE_CONTROLLER) +#if MYNEWT_VAL(BLE_CONTROLLER) || MYNEWT_VAL(BLE_HCI_BRIDGE) ble_hci_uart_sync_lost(); #else /* @@ -769,7 +769,7 @@ ble_hci_uart_rx_char(void *arg, uint8_t data) switch (ble_hci_uart_state.rx_type) { case BLE_HCI_UART_H4_NONE: return ble_hci_uart_rx_pkt_type(data); -#if MYNEWT_VAL(BLE_CONTROLLER) +#if MYNEWT_VAL(BLE_CONTROLLER) || MYNEWT_VAL(BLE_HCI_BRIDGE) case BLE_HCI_UART_H4_CMD: ble_hci_uart_rx_cmd(data); return 0; @@ -898,6 +898,7 @@ ble_hci_trans_ll_acl_tx(struct os_mbuf *om) return rc; } +#if MYNEWT_VAL(BLE_HOST) /** * Sends an HCI command from the host to the controller. * @@ -955,6 +956,7 @@ ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb, { ble_hci_uart_set_rx_cbs(cmd_cb, cmd_arg, acl_cb, acl_arg); } +#endif /** * Configures the HCI transport to operate with a host. The transport will diff --git a/nimble/transport/uart/syscfg.yml b/nimble/transport/uart/syscfg.yml index 43486a8bfe..7eff9517c1 100644 --- a/nimble/transport/uart/syscfg.yml +++ b/nimble/transport/uart/syscfg.yml @@ -17,24 +17,6 @@ # syscfg.defs: - BLE_HCI_EVT_BUF_SIZE: - description: 'The size of the allocated event buffers' - value: 70 - BLE_HCI_EVT_HI_BUF_COUNT: - description: 'The number of high priority event buffers' - value: 8 - BLE_HCI_EVT_LO_BUF_COUNT: - description: 'The number of low priority event buffers' - value: 8 - BLE_ACL_BUF_COUNT: - description: 'The number of ACL data buffers' - value: 12 - BLE_ACL_BUF_SIZE: - description: > - This is the maximum size of the data portion of HCI ACL data - packets. It does not include the HCI data header (of 4 bytes). - value: 255 - BLE_HCI_ACL_OUT_COUNT: description: > This count is used in creating a pool of elements used by the @@ -70,3 +52,10 @@ syscfg.defs: syscfg.vals.BLE_EXT_ADV: BLE_HCI_EVT_BUF_SIZE: 257 + +syscfg.vals: + BLE_HCI_EVT_BUF_SIZE: 70 + BLE_HCI_EVT_HI_BUF_COUNT: 8 + BLE_HCI_EVT_LO_BUF_COUNT: 8 + BLE_ACL_BUF_COUNT: 12 + BLE_ACL_BUF_SIZE: 255 diff --git a/nimble/transport/usb/syscfg.yml b/nimble/transport/usb/syscfg.yml index ebc261a23d..38effde60c 100644 --- a/nimble/transport/usb/syscfg.yml +++ b/nimble/transport/usb/syscfg.yml @@ -17,24 +17,6 @@ # syscfg.defs: - BLE_HCI_EVT_BUF_SIZE: - description: 'The size of the allocated event buffers' - value: 70 - BLE_HCI_EVT_HI_BUF_COUNT: - description: 'The number of high priority event buffers' - value: 8 - BLE_HCI_EVT_LO_BUF_COUNT: - description: 'The number of low priority event buffers' - value: 8 - BLE_ACL_BUF_COUNT: - description: 'The number of ACL data buffers' - value: 12 - BLE_ACL_BUF_SIZE: - description: > - This is the maximum size of the data portion of HCI ACL data - packets. It does not include the HCI data header (of 4 bytes). - value: 255 - BLE_HCI_ACL_OUT_COUNT: description: > This count is used in creating a pool of elements used by the @@ -53,5 +35,12 @@ syscfg.defs: syscfg.vals.BLE_EXT_ADV: BLE_HCI_EVT_BUF_SIZE: 257 +syscfg.vals: + BLE_HCI_EVT_BUF_SIZE: 70 + BLE_HCI_EVT_HI_BUF_COUNT: 8 + BLE_HCI_EVT_LO_BUF_COUNT: 8 + BLE_ACL_BUF_COUNT: 12 + BLE_ACL_BUF_SIZE: 255 + syscfg.restrictions: - '!BLE_HOST' From 11b8107a371351a3adbad5dfe32571b07f9d4aab Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Mon, 22 Nov 2021 10:25:18 +0100 Subject: [PATCH 0231/1333] apps: Add blehcibridge application This application is equivalent of blehci for dual-core MCUs. It allows to forward traffic from external transport (USB/UART) to BLE core via internal transport. --- apps/blehcibridge/pkg.yml | 40 +++++++++++++++++++++ apps/blehcibridge/src/main.c | 69 ++++++++++++++++++++++++++++++++++++ apps/blehcibridge/syscfg.yml | 36 +++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 apps/blehcibridge/pkg.yml create mode 100644 apps/blehcibridge/src/main.c create mode 100644 apps/blehcibridge/syscfg.yml diff --git a/apps/blehcibridge/pkg.yml b/apps/blehcibridge/pkg.yml new file mode 100644 index 0000000000..9d170a89f3 --- /dev/null +++ b/apps/blehcibridge/pkg.yml @@ -0,0 +1,40 @@ +# 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: apps/blehcibridge +pkg.type: app +pkg.description: BLE controller application exposing HCI over external interface +pkg.author: "Jerzy Kasenberg " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - "@apache-mynewt-core/sys/log/stub" + - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/kernel/os" + - "@apache-mynewt-core/sys/shell" + - nimble/transport + +pkg.req_apis: + - ble_transport + +pkg.deps.'CONSOLE_MODE=="full"': + - "@apache-mynewt-core/sys/console/full" +pkg.deps.'CONSOLE_MODE=="minimal": + - "@apache-mynewt-core/sys/console/minimal" +pkg.deps.'CONSOLE_MODE=="stub": + - "@apache-mynewt-core/sys/console/stub" diff --git a/apps/blehcibridge/src/main.c b/apps/blehcibridge/src/main.c new file mode 100644 index 0000000000..620cc37121 --- /dev/null +++ b/apps/blehcibridge/src/main.c @@ -0,0 +1,69 @@ +/* + * 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. + */ + +#include +#include +#include + +static int +forward_cmd_to_controller(uint8_t *cmdbuf, void *arg) +{ + (void)arg; + + return ble_hci_trans_hs_cmd_tx(cmdbuf); +} + +int +forward_acl_to_controller(struct os_mbuf *om, void *arg) +{ + (void)arg; + + return ble_hci_trans_hs_acl_tx(om); +} + +static int +forward_evt_to_host(uint8_t *hci_ev, void *arg) +{ + (void)arg; + + return ble_hci_trans_ll_evt_tx(hci_ev); +} + +int +forward_acl_to_host(struct os_mbuf *om, void *arg) +{ + (void)arg; + + return ble_hci_trans_ll_acl_tx(om); +} + +int +main(void) +{ + /* Initialize OS */ + sysinit(); + + ble_hci_trans_cfg_hs(forward_evt_to_host, NULL, forward_acl_to_host, NULL); + ble_hci_trans_cfg_ll(forward_cmd_to_controller, NULL, forward_acl_to_controller, NULL); + + while (1) { + os_eventq_run(os_eventq_dflt_get()); + } + return 0; +} diff --git a/apps/blehcibridge/syscfg.yml b/apps/blehcibridge/syscfg.yml new file mode 100644 index 0000000000..146ab52642 --- /dev/null +++ b/apps/blehcibridge/syscfg.yml @@ -0,0 +1,36 @@ +# 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. +# + +syscfg.defs: + CONSOLE_MODE: + description: Which console to use + value: stub + choices: + - full + - minimal + - stub + +syscfg.vals: + # Default task settings + OS_MAIN_STACK_SIZE: 64 + # Use USB transport by default + BLE_HCI_TRANSPORT: usb + + SHELL_TASK: 1 + + BLE_HCI_BRIDGE: 1 From 4386bb4c2cde5f4977cab0d4975f9ff818c18391 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Mon, 22 Nov 2021 14:12:34 +0100 Subject: [PATCH 0232/1333] apps: Update transport selection method Transport package should not be included directly. Instead, nimble/transport should be included and BLE_HCI_TRANSPORT syscfv value should specify transport, and this will include correct package. This commit changes nimble/transport/ram to nimble/transport in all applications that still have deprecated way of transport selection. --- nimble/controller/test/pkg.yml | 2 +- nimble/controller/test/syscfg.yml | 1 + nimble/host/test/pkg.yml | 2 +- nimble/host/test/syscfg.yml | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/nimble/controller/test/pkg.yml b/nimble/controller/test/pkg.yml index ea72881149..1b06a5b576 100644 --- a/nimble/controller/test/pkg.yml +++ b/nimble/controller/test/pkg.yml @@ -31,4 +31,4 @@ pkg.deps.SELFTEST: - "@apache-mynewt-core/sys/log/full" - "@apache-mynewt-core/sys/stats/stub" - nimble/drivers/native - - nimble/transport/ram + - nimble/transport diff --git a/nimble/controller/test/syscfg.yml b/nimble/controller/test/syscfg.yml index 6edad438bb..4448a0e66f 100644 --- a/nimble/controller/test/syscfg.yml +++ b/nimble/controller/test/syscfg.yml @@ -23,3 +23,4 @@ syscfg.vals: MCU_TIMER_POLLER_PRIO: 1 MCU_UART_POLLER_PRIO: 2 NATIVE_SOCKETS_PRIO: 3 + BLE_HCI_TRANSPORT: ram diff --git a/nimble/host/test/pkg.yml b/nimble/host/test/pkg.yml index dd1ad18bf3..cb5d97cfb3 100644 --- a/nimble/host/test/pkg.yml +++ b/nimble/host/test/pkg.yml @@ -31,4 +31,4 @@ pkg.deps.SELFTEST: - "@apache-mynewt-core/sys/console/stub" - "@apache-mynewt-core/sys/log/full" - "@apache-mynewt-core/sys/stats/stub" - - nimble/transport/ram + - nimble/transport diff --git a/nimble/host/test/syscfg.yml b/nimble/host/test/syscfg.yml index 6307398e4c..45bc638b62 100644 --- a/nimble/host/test/syscfg.yml +++ b/nimble/host/test/syscfg.yml @@ -29,3 +29,4 @@ syscfg.vals: CONFIG_FCB: 1 BLE_VERSION: 52 BLE_L2CAP_ENHANCED_COC: 1 + BLE_HCI_TRANSPORT: ram From 390744d836658c2eecd32e8883fa9d072f4d1c65 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Mon, 22 Nov 2021 15:05:21 +0100 Subject: [PATCH 0233/1333] transport: Bridge build workaround Function ble_ll_data_buffer_overflow() and ble_ll_hw_error() are executed from host code, but those are controller functions. They would only work when host and controller runs on same CPU. In bridge build when controller code can't be executed this way two transports (nrf5340/dialog_cmac) provide those functions so UART can be used in bridge configuration. This is just workaround till functions are implemented or other way of signaling those errors is established. --- .../dialog_cmac/src/ble_hci_cmac_hs.c | 21 +++++++++++++++++++ .../transport/nrf5340/src/nrf5340_ble_hci.c | 21 +++++++++++++++++++ nimble/transport/usb/pkg.yml | 1 + 3 files changed, 43 insertions(+) diff --git a/nimble/transport/dialog_cmac/src/ble_hci_cmac_hs.c b/nimble/transport/dialog_cmac/src/ble_hci_cmac_hs.c index 172fc87952..266637f78e 100644 --- a/nimble/transport/dialog_cmac/src/ble_hci_cmac_hs.c +++ b/nimble/transport/dialog_cmac/src/ble_hci_cmac_hs.c @@ -41,6 +41,27 @@ static struct ble_hci_cmac_hs_api g_ble_hci_cmac_hs_api; static struct ble_hci_trans_h4_rx_state g_ble_hci_cmac_hs_rx_state; static bool g_ble_hci_cmac_hs_read_err; +#if MYNEWT_VAL(BLE_HCI_BRIDGE) +/* + * TODO: Remove/fix functions ble_ll_data_buffer_overflow() ble_ll_hw_error() + * Following two functions are added to allowed build of HCI bridge configurations. + * Those functions are only used by UART transport, in RAM transport configuration + * they can be called directly in bridge mode controller code is on other core + * and those can't be called. + */ +void +ble_ll_data_buffer_overflow(void) +{ + +} + +void +ble_ll_hw_error(uint8_t err) +{ + (void)err; +} +#endif + static int ble_hci_cmac_hs_frame_cb(uint8_t pkt_type, void *data) { diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index fe93c0fd6e..41f164edb2 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -123,6 +123,27 @@ ble_hci_trans_reset(void) } #endif +#if MYNEWT_VAL(BLE_HCI_BRIDGE) +/* + * TODO: Remove/fix functions ble_ll_data_buffer_overflow() ble_ll_hw_error() + * Following two functions are added to allowed build of HCI bridge configurations. + * Those functions are only used by UART transport, in RAM transport configuration + * they can be called directly in bridge mode controller code is on other core + * and those can't be called. + */ +void +ble_ll_data_buffer_overflow(void) +{ + +} + +void +ble_ll_hw_error(uint8_t err) +{ + (void)err; +} +#endif + static int ble_hci_trans_acl_tx(struct os_mbuf *om) { diff --git a/nimble/transport/usb/pkg.yml b/nimble/transport/usb/pkg.yml index 49317c97d5..c4c314c867 100644 --- a/nimble/transport/usb/pkg.yml +++ b/nimble/transport/usb/pkg.yml @@ -31,6 +31,7 @@ pkg.deps: - "@apache-mynewt-core/kernel/os" - "@apache-mynewt-core/util/mem" - nimble + - "@apache-mynewt-core/hw/usb/tinyusb" pkg.apis: - ble_transport From a47a0112439e32fab6304c3e0eb6814dae864a59 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 19 Jan 2022 10:29:51 +0100 Subject: [PATCH 0234/1333] nimble/phy/nrf53: Fix clearing debug pins Pins controlled by GPIOTE can be only cleared by GPIOTE... --- nimble/drivers/nrf5340/src/ble_phy.c | 46 ++++++++++++---------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/nimble/drivers/nrf5340/src/ble_phy.c b/nimble/drivers/nrf5340/src/ble_phy.c index 12be202db5..53daab59a4 100644 --- a/nimble/drivers/nrf5340/src/ble_phy.c +++ b/nimble/drivers/nrf5340/src/ble_phy.c @@ -298,6 +298,16 @@ struct nrf_ccm_data { static struct nrf_ccm_data nrf_ccm_data; #endif +#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 +static uint8_t phy_dbg_txrxen_ready_idx; +#endif +#if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 +static uint8_t phy_dbg_address_end_idx; +#endif +#if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 +static uint8_t phy_dbg_wfr_idx; +#endif + #if (BLE_LL_BT5_PHY_SUPPORTED == 1) uint32_t @@ -1249,7 +1259,8 @@ ble_phy_dbg_time_setup(void) */ #if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 - ble_phy_dbg_time_setup_gpiote(--gpiote_idx, + phy_dbg_txrxen_ready_idx = --gpiote_idx; + ble_phy_dbg_time_setup_gpiote(gpiote_idx, MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_TXRXEN; @@ -1262,7 +1273,8 @@ ble_phy_dbg_time_setup(void) #endif #if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 - ble_phy_dbg_time_setup_gpiote(--gpiote_idx, + phy_dbg_address_end_idx = --gpiote_idx; + ble_phy_dbg_time_setup_gpiote(gpiote_idx, MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_ADDRESS; @@ -1270,7 +1282,8 @@ ble_phy_dbg_time_setup(void) #endif #if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 - ble_phy_dbg_time_setup_gpiote(--gpiote_idx, + phy_dbg_wfr_idx = --gpiote_idx; + ble_phy_dbg_time_setup_gpiote(gpiote_idx, MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_RXREADY; @@ -1844,35 +1857,14 @@ ble_phy_restart_rx(void) static void ble_phy_dbg_clear_pins(void) { -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 - NRF_GPIO_Type *port; - int pin; - #if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 - pin = MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN); - port = pin > 31 ? NRF_P1_NS : NRF_P0_NS; - pin &= 0x1f; - - port->OUTCLR = (1 << pin); + NRF_GPIOTE_NS->TASKS_CLR[phy_dbg_txrxen_ready_idx] = 1; #endif - #if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 - pin = MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN); - port = pin > 31 ? NRF_P1_NS : NRF_P0_NS; - pin &= 0x1f; - - port->OUTCLR = (1 << pin); + NRF_GPIOTE_NS->TASKS_CLR[phy_dbg_address_end_idx] = 1; #endif - #if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 - pin = MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN); - port = pin > 31 ? NRF_P1_NS : NRF_P0_NS; - pin &= 0x1f; - - port->OUTCLR = (1 << pin); -#endif + NRF_GPIOTE_NS->TASKS_CLR[phy_dbg_wfr_idx] = 1; #endif } From 8051721553ef24deefee57774cdd563552c70a92 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 26 Jan 2022 17:45:32 +0100 Subject: [PATCH 0235/1333] nimble/phy/nrf53: Add workaround for anomaly 117 --- nimble/drivers/nrf5340/src/ble_phy.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/drivers/nrf5340/src/ble_phy.c b/nimble/drivers/nrf5340/src/ble_phy.c index 53daab59a4..2b21afb438 100644 --- a/nimble/drivers/nrf5340/src/ble_phy.c +++ b/nimble/drivers/nrf5340/src/ble_phy.c @@ -326,21 +326,25 @@ ble_phy_mode_apply(uint8_t phy_mode) switch (phy_mode) { case BLE_PHY_MODE_1M: NRF_RADIO_NS->MODE = RADIO_MODE_MODE_Ble_1Mbit; + *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0080); NRF_RADIO_NS->PCNF0 = NRF_PCNF0_1M; break; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) case BLE_PHY_MODE_2M: NRF_RADIO_NS->MODE = RADIO_MODE_MODE_Ble_2Mbit; + *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0084); NRF_RADIO_NS->PCNF0 = NRF_PCNF0_2M; break; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) case BLE_PHY_MODE_CODED_125KBPS: NRF_RADIO_NS->MODE = RADIO_MODE_MODE_Ble_LR125Kbit; + *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0080); NRF_RADIO_NS->PCNF0 = NRF_PCNF0_CODED; break; case BLE_PHY_MODE_CODED_500KBPS: NRF_RADIO_NS->MODE = RADIO_MODE_MODE_Ble_LR500Kbit; + *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0080); NRF_RADIO_NS->PCNF0 = NRF_PCNF0_CODED; break; #endif From 1ca036b0cf732b91aa0c05ec5f693ba607633c12 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 26 Jan 2022 17:50:57 +0100 Subject: [PATCH 0236/1333] nimble/hs: Fix startup without central and peripheral supported There's no need to read buffers size if both central and peripheral roles are not supported. Also host will fail to start if controller does not ale support those roles since HCI command is not supported in such case. --- nimble/host/src/ble_hs_startup.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c index 83026ac18b..60441826a0 100644 --- a/nimble/host/src/ble_hs_startup.c +++ b/nimble/host/src/ble_hs_startup.c @@ -86,6 +86,7 @@ ble_hs_startup_le_read_sup_f_tx(void) return 0; } +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_PERIPHERAL) static int ble_hs_startup_le_read_buf_sz_tx(uint16_t *out_pktlen, uint8_t *out_max_pkts) { @@ -155,6 +156,7 @@ ble_hs_startup_read_buf_sz(void) return 0; } +#endif static int ble_hs_startup_read_bd_addr(void) @@ -343,10 +345,12 @@ ble_hs_startup_go(void) return rc; } +#if MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_PERIPHERAL) rc = ble_hs_startup_read_buf_sz(); if (rc != 0) { return rc; } +#endif rc = ble_hs_startup_le_read_sup_f_tx(); if (rc != 0) { From d020a20d80599e18a9c652e0aedc152b8bf27b73 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 26 Jan 2022 17:45:58 +0100 Subject: [PATCH 0237/1333] nimble/ll: Fix assert on aux scan hci_ev_next was never set to NULL so in case last PDU in chain was fragmented an assert was triggered since on last chunk (i.e. completed) we expect hci_ev_next to be NULL. --- nimble/controller/src/ble_ll_scan_aux.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 69ab10cde9..9504771d95 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -577,6 +577,7 @@ ble_ll_hci_ev_send_ext_adv_report(struct os_mbuf *rxpdu, ble_ll_hci_event_send(*hci_ev); *hci_ev = hci_ev_next; + hci_ev_next = NULL; } while ((offset < data_len) && *hci_ev); return truncated ? -1 : 0; From 0aa6ed4cf5154113580165312674ab6dac1254d8 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 26 Jan 2022 17:55:38 +0100 Subject: [PATCH 0238/1333] nimble/ll: Fix HCI event on assert We should use new syscfg in BLE_LL_ASSERT macro definition. Also let's use value of old syscfg as default value for new one since the old one is deprecated, not defunct (yet). --- nimble/controller/include/controller/ble_ll.h | 2 +- nimble/controller/syscfg.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 898907a19d..f4b8517a8d 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -39,7 +39,7 @@ extern "C" { #error 32.768kHz clock required #endif -#if defined(MYNEWT) && MYNEWT_VAL(BLE_LL_VND_EVENT_ON_ASSERT) +#if defined(MYNEWT) && MYNEWT_VAL(BLE_LL_HCI_VS_EVENT_ON_ASSERT) #ifdef NDEBUG #define BLE_LL_ASSERT(cond) (void(0)) #else diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index afb3859708..bb4631195f 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -375,7 +375,7 @@ syscfg.defs: This options enables controller to send a vendor-specific event on an assertion in controller code. The event contains file name and line number where assertion occured. - value: 0 + value: MYNEWT_VAL(BLE_LL_VND_EVENT_ON_ASSERT) BLE_LL_PA: description: Enable PA support From 2a062faff3b1659668ab2d3c686be2db44a79035 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 26 Jan 2022 17:57:41 +0100 Subject: [PATCH 0239/1333] nimble/ll: Change remaining asserts to BLE_LL_ASSERT --- nimble/controller/src/ble_ll.c | 2 +- nimble/controller/src/ble_ll_adv.c | 114 ++++++++++++++--------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 1e378bc61b..ce82c0d6f9 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1403,7 +1403,7 @@ ble_ll_task(void *arg) while (1) { ev = ble_npl_eventq_get(&g_ble_ll_data.ll_evq, BLE_NPL_TIME_FOREVER); - assert(ev); + BLE_LL_ASSERT(ev); ble_npl_event_run(ev); } } diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index db17dc4c22..bd85eabd1b 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -267,7 +267,7 @@ ble_ll_adv_active_chanset_set_pri(struct ble_ll_adv_sm *advsm) os_sr_t sr; OS_ENTER_CRITICAL(sr); - assert((advsm->flags & BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK) == 0); + BLE_LL_ASSERT((advsm->flags & BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK) == 0); advsm->flags &= ~BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK; advsm->flags |= 0x10; OS_EXIT_CRITICAL(sr); @@ -280,7 +280,7 @@ ble_ll_adv_active_chanset_set_sec(struct ble_ll_adv_sm *advsm) os_sr_t sr; OS_ENTER_CRITICAL(sr); - assert((advsm->flags & BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK) == 0); + BLE_LL_ASSERT((advsm->flags & BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK) == 0); advsm->flags &= ~BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK; advsm->flags |= 0x20; OS_EXIT_CRITICAL(sr); @@ -482,7 +482,7 @@ ble_ll_adv_legacy_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) } /* An invalid advertising data length indicates a memory overwrite */ - assert(adv_data_len <= BLE_ADV_LEGACY_DATA_MAX_LEN); + BLE_LL_ASSERT(adv_data_len <= BLE_ADV_LEGACY_DATA_MAX_LEN); /* Set the PDU length in the state machine (includes header) */ advsm->adv_pdu_len = pdulen + BLE_LL_PDU_HDR_LEN; @@ -549,7 +549,7 @@ ble_ll_adv_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) advsm = pducb_arg; - assert(ble_ll_adv_active_chanset_is_pri(advsm)); + BLE_LL_ASSERT(ble_ll_adv_active_chanset_is_pri(advsm)); if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) { return ble_ll_adv_legacy_pdu_make(dptr, advsm, hdr_byte); } @@ -718,8 +718,8 @@ ble_ll_adv_aux_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) advsm = pducb_arg; aux = AUX_CURRENT(advsm); - assert(!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)); - assert(ble_ll_adv_active_chanset_is_sec(advsm)); + BLE_LL_ASSERT(!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)); + BLE_LL_ASSERT(ble_ll_adv_active_chanset_is_sec(advsm)); /* It's the same for AUX_ADV_IND and AUX_CHAIN_IND */ pdu_type = BLE_ADV_PDU_TYPE_AUX_ADV_IND; @@ -821,10 +821,10 @@ ble_ll_adv_aux_scannable_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_b advsm = pducb_arg; - assert(!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)); - assert(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE); - assert(advsm->aux_first_pdu); - assert(ble_ll_adv_active_chanset_is_sec(advsm)); + BLE_LL_ASSERT(!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)); + BLE_LL_ASSERT(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE); + BLE_LL_ASSERT(advsm->aux_first_pdu); + BLE_LL_ASSERT(ble_ll_adv_active_chanset_is_sec(advsm)); pdu_type = BLE_ADV_PDU_TYPE_AUX_ADV_IND; @@ -899,7 +899,7 @@ ble_ll_adv_scan_rsp_legacy_pdu_make(uint8_t *dptr, void *pducb_arg, /* Make sure that the length is valid */ scan_rsp_len = SCAN_RSP_DATA_LEN(advsm); - assert(scan_rsp_len <= BLE_SCAN_RSP_LEGACY_DATA_MAX_LEN); + BLE_LL_ASSERT(scan_rsp_len <= BLE_SCAN_RSP_LEGACY_DATA_MAX_LEN); /* Set BLE transmit header */ pdulen = BLE_DEV_ADDR_LEN + scan_rsp_len; @@ -1037,7 +1037,7 @@ ble_ll_adv_tx_done(void *arg) } else if (ble_ll_adv_active_chanset_is_sec(advsm)) { ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_sec_txdone_ev); } else { - assert(0); + BLE_LL_ASSERT(0); } #else ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev); @@ -1109,7 +1109,7 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch) /* Set channel */ rc = ble_phy_setchan(advsm->adv_chan, BLE_ACCESS_ADDR_ADV, BLE_LL_CRCINIT_ADV); - assert(rc == 0); + BLE_LL_ASSERT(rc == 0); #if (BLE_LL_BT5_PHY_SUPPORTED == 1) /* Set phy mode */ @@ -1256,7 +1256,7 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch) aux = AUX_CURRENT(advsm); rc = ble_phy_setchan(aux->chan, BLE_ACCESS_ADDR_ADV, BLE_LL_CRCINIT_ADV); - assert(rc == 0); + BLE_LL_ASSERT(rc == 0); #if (BLE_LL_BT5_PHY_SUPPORTED == 1) /* Set phy mode */ @@ -1362,9 +1362,9 @@ ble_ll_adv_aux_calculate(struct ble_ll_adv_sm *advsm, uint8_t hdr_len; bool chainable; - assert(!aux->sch.enqueued); - assert((AUX_DATA_LEN(advsm) > aux_data_offset) || - (AUX_DATA_LEN(advsm) == 0 && aux_data_offset == 0)); + BLE_LL_ASSERT(!aux->sch.enqueued); + BLE_LL_ASSERT((AUX_DATA_LEN(advsm) > aux_data_offset) || + (AUX_DATA_LEN(advsm) == 0 && aux_data_offset == 0)); aux->aux_data_offset = aux_data_offset; aux->aux_data_len = 0; @@ -1461,7 +1461,7 @@ ble_ll_adv_aux_calculate(struct ble_ll_adv_sm *advsm, aux->aux_data_len -= BLE_LL_EXT_ADV_AUX_PTR_SIZE; /* PDU payload should be full if chained */ - assert(hdr_len + aux->aux_data_len == BLE_LL_MAX_PAYLOAD_LEN); + BLE_LL_ASSERT(hdr_len + aux->aux_data_len == BLE_LL_MAX_PAYLOAD_LEN); } aux->payload_len = hdr_len + aux->aux_data_len; @@ -1486,12 +1486,12 @@ ble_ll_adv_aux_schedule_next(struct ble_ll_adv_sm *advsm) uint16_t next_aux_data_offset; uint32_t max_usecs; - assert(advsm->aux_active); + BLE_LL_ASSERT(advsm->aux_active); aux = AUX_CURRENT(advsm); aux_next = AUX_NEXT(advsm); - assert(!aux_next->sch.enqueued); + BLE_LL_ASSERT(!aux_next->sch.enqueued); /* * Do not schedule next aux if current aux is no longer scheduled since we @@ -1511,10 +1511,10 @@ ble_ll_adv_aux_schedule_next(struct ble_ll_adv_sm *advsm) next_aux_data_offset = aux->aux_data_offset + aux->aux_data_len; - assert(AUX_DATA_LEN(advsm) >= next_aux_data_offset); + BLE_LL_ASSERT(AUX_DATA_LEN(advsm) >= next_aux_data_offset); rem_aux_data_len = AUX_DATA_LEN(advsm) - next_aux_data_offset; - assert(rem_aux_data_len > 0); + BLE_LL_ASSERT(rem_aux_data_len > 0); ble_ll_adv_aux_calculate(advsm, aux_next, next_aux_data_offset); max_usecs = ble_ll_pdu_tx_time_get(aux_next->payload_len, advsm->sec_phy); @@ -1547,9 +1547,9 @@ ble_ll_adv_aux_schedule_first(struct ble_ll_adv_sm *advsm) struct ble_ll_sched_item *sch; uint32_t max_usecs; - assert(!advsm->aux_active); - assert(!advsm->aux[0].sch.enqueued); - assert(!advsm->aux[1].sch.enqueued); + BLE_LL_ASSERT(!advsm->aux_active); + BLE_LL_ASSERT(!advsm->aux[0].sch.enqueued); + BLE_LL_ASSERT(!advsm->aux[1].sch.enqueued); advsm->aux_active = 1; advsm->aux_index = 0; @@ -1608,9 +1608,9 @@ ble_ll_adv_aux_set_start_time(struct ble_ll_adv_sm *advsm) uint32_t adv_event_dur; uint8_t chans; - assert(!advsm->aux_active); - assert(!advsm->aux[0].sch.enqueued); - assert(!advsm->aux[1].sch.enqueued); + BLE_LL_ASSERT(!advsm->aux_active); + BLE_LL_ASSERT(!advsm->aux[0].sch.enqueued); + BLE_LL_ASSERT(!advsm->aux[1].sch.enqueued); assert(advsm->adv_chanmask > 0 && advsm->adv_chanmask <= BLE_HCI_ADV_CHANMASK_DEF); @@ -2057,8 +2057,8 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) advsm = pducb_arg; sync = SYNC_CURRENT(advsm); - assert(!ble_ll_adv_active_chanset_is_sec(advsm)); - assert(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING); + BLE_LL_ASSERT(!ble_ll_adv_active_chanset_is_sec(advsm)); + BLE_LL_ASSERT(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING); /* It's the same for AUX_SYNC_IND and AUX_CHAIN_IND */ pdu_type = BLE_ADV_PDU_TYPE_AUX_SYNC_IND; @@ -2119,8 +2119,8 @@ ble_ll_adv_sync_tx_done(struct ble_ll_adv_sm *advsm) /* for sync we trace a no pri nor sec set */ ble_ll_trace_u32x2(BLE_LL_TRACE_ID_ADV_TXDONE, advsm->adv_instance, 0); - assert(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING); - assert(!ble_ll_adv_active_chanset_is_sec(advsm)); + BLE_LL_ASSERT(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING); + BLE_LL_ASSERT(!ble_ll_adv_active_chanset_is_sec(advsm)); ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_periodic_txdone_ev); @@ -2177,7 +2177,7 @@ ble_ll_adv_sync_tx_start_cb(struct ble_ll_sched_item *sch) rc = ble_phy_setchan(sync->chan, advsm->periodic_access_addr, advsm->periodic_crcinit); - assert(rc == 0); + BLE_LL_ASSERT(rc == 0); #if (BLE_LL_BT5_PHY_SUPPORTED == 1) /* Set phy mode */ @@ -2232,9 +2232,9 @@ ble_ll_adv_sync_calculate(struct ble_ll_adv_sm *advsm, uint16_t rem_sync_data_len; uint8_t hdr_len; - assert(!sync->sch.enqueued); - assert((SYNC_DATA_LEN(advsm) > sync_data_offset) || - (SYNC_DATA_LEN(advsm) == 0 && sync_data_offset == 0)); + BLE_LL_ASSERT(!sync->sch.enqueued); + BLE_LL_ASSERT((SYNC_DATA_LEN(advsm) > sync_data_offset) || + (SYNC_DATA_LEN(advsm) == 0 && sync_data_offset == 0)); sync->sync_data_offset = sync_data_offset; sync->sync_data_len = 0; @@ -2284,7 +2284,7 @@ ble_ll_adv_sync_calculate(struct ble_ll_adv_sm *advsm, sync->sync_data_len -= BLE_LL_EXT_ADV_AUX_PTR_SIZE; /* PDU payload should be full if chained */ - assert(hdr_len + sync->sync_data_len == BLE_LL_MAX_PAYLOAD_LEN); + BLE_LL_ASSERT(hdr_len + sync->sync_data_len == BLE_LL_MAX_PAYLOAD_LEN); } sync->payload_len = hdr_len + sync->sync_data_len; @@ -2300,9 +2300,9 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm, uint8_t chan; int rc; - assert(!advsm->periodic_sync_active); - assert(!advsm->periodic_sync[0].sch.enqueued); - assert(!advsm->periodic_sync[1].sch.enqueued); + BLE_LL_ASSERT(!advsm->periodic_sync_active); + BLE_LL_ASSERT(!advsm->periodic_sync[0].sch.enqueued); + BLE_LL_ASSERT(!advsm->periodic_sync[1].sch.enqueued); advsm->periodic_sync_active = 1; advsm->periodic_sync_index = 0; @@ -2375,12 +2375,12 @@ ble_ll_adv_periodic_schedule_next(struct ble_ll_adv_sm *advsm) uint32_t max_usecs; uint8_t chan; - assert(advsm->periodic_sync_active); + BLE_LL_ASSERT(advsm->periodic_sync_active); sync = SYNC_CURRENT(advsm); sync_next = SYNC_NEXT(advsm); - assert(!sync_next->sch.enqueued); + BLE_LL_ASSERT(!sync_next->sch.enqueued); /* * Do not schedule next sync if current sync is no longer scheduled since we @@ -2400,10 +2400,10 @@ ble_ll_adv_periodic_schedule_next(struct ble_ll_adv_sm *advsm) next_sync_data_offset = sync->sync_data_offset + sync->sync_data_len; - assert(SYNC_DATA_LEN(advsm) >= next_sync_data_offset); + BLE_LL_ASSERT(SYNC_DATA_LEN(advsm) >= next_sync_data_offset); rem_sync_data_len = SYNC_DATA_LEN(advsm) - next_sync_data_offset; - assert(rem_sync_data_len > 0); + BLE_LL_ASSERT(rem_sync_data_len > 0); /* we use separate counter for chaining */ chan = ble_ll_utils_calc_dci_csa2(advsm->periodic_chain_event_cntr++, @@ -2494,9 +2494,9 @@ ble_ll_adv_periodic_done(struct ble_ll_adv_sm *advsm) struct ble_ll_adv_sync *sync; struct ble_ll_adv_sync *sync_next; - assert(advsm->periodic_adv_enabled); - assert(advsm->periodic_adv_active); - assert(advsm->periodic_sync_active); + BLE_LL_ASSERT(advsm->periodic_adv_enabled); + BLE_LL_ASSERT(advsm->periodic_adv_active); + BLE_LL_ASSERT(advsm->periodic_sync_active); ble_ll_rfmgmt_release(); @@ -2890,7 +2890,7 @@ ble_ll_adv_update_data_mbuf(struct os_mbuf **omp, bool new_data, uint16_t maxlen } } - assert(om); + BLE_LL_ASSERT(om); if (OS_MBUF_PKTLEN(om) + datalen > maxlen) { os_mbuf_free_chain(om); @@ -4461,7 +4461,7 @@ ble_ll_adv_rx_isr_end(uint8_t pdu_type, struct os_mbuf *rxpdu, int crcok) if (ble_ll_adv_active_chanset_is_sec(g_ble_ll_cur_adv_sm)) { rxhdr->rxinfo.flags |= BLE_MBUF_HDR_F_EXT_ADV_SEC; } else { - assert(ble_ll_adv_active_chanset_is_pri(g_ble_ll_cur_adv_sm)); + BLE_LL_ASSERT(ble_ll_adv_active_chanset_is_pri(g_ble_ll_cur_adv_sm)); } #endif if (crcok) { @@ -4622,7 +4622,7 @@ ble_ll_adv_reschedule_event(struct ble_ll_adv_sm *advsm) uint32_t max_delay_ticks; int rc; - assert(advsm->adv_enabled); + BLE_LL_ASSERT(advsm->adv_enabled); sch = &advsm->adv_sch; @@ -4673,7 +4673,7 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) uint32_t tick_itvl; uint32_t start_time; - assert(advsm->adv_enabled); + BLE_LL_ASSERT(advsm->adv_enabled); ble_ll_rfmgmt_release(); @@ -4856,8 +4856,8 @@ ble_ll_adv_sec_done(struct ble_ll_adv_sm *advsm) struct ble_ll_adv_aux *aux; struct ble_ll_adv_aux *aux_next; - assert(advsm->adv_enabled); - assert(advsm->aux_active); + BLE_LL_ASSERT(advsm->adv_enabled); + BLE_LL_ASSERT(advsm->aux_active); aux = AUX_CURRENT(advsm); aux_next = AUX_NEXT(advsm); @@ -4923,12 +4923,12 @@ ble_ll_adv_make_done(struct ble_ll_adv_sm *advsm, struct ble_mbuf_hdr *hdr) { #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (BLE_MBUF_HDR_EXT_ADV_SEC(hdr)) { - assert(!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)); - assert(ble_ll_adv_active_chanset_is_sec(advsm)); + BLE_LL_ASSERT(!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)); + BLE_LL_ASSERT(ble_ll_adv_active_chanset_is_sec(advsm)); ble_ll_adv_active_chanset_clear(advsm); ble_ll_adv_sec_done(advsm); } else { - assert(ble_ll_adv_active_chanset_is_pri(advsm)); + BLE_LL_ASSERT(ble_ll_adv_active_chanset_is_pri(advsm)); ble_ll_adv_active_chanset_clear(advsm); ble_ll_adv_done(advsm); } @@ -4983,7 +4983,7 @@ ble_ll_adv_send_conn_comp_ev(struct ble_ll_conn_sm *connsm, advsm = &g_ble_ll_adv_sm[0]; #endif - assert(advsm->conn_comp_ev != NULL); + BLE_LL_ASSERT(advsm->conn_comp_ev != NULL); ble_ll_conn_comp_event_send(connsm, BLE_ERR_SUCCESS, advsm->conn_comp_ev, advsm); advsm->conn_comp_ev = NULL; From 291dbc11b9ac91c27b9156ce9d8d46ebc63942cb Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 28 Jan 2022 13:45:22 +0100 Subject: [PATCH 0240/1333] nimble/transport/cmac: Fix configuration Default values always to both non-extadv and extadv builds, the only difference is event buffer size. --- nimble/transport/dialog_cmac/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/transport/dialog_cmac/syscfg.yml b/nimble/transport/dialog_cmac/syscfg.yml index 54607fd814..190c2ca8a8 100644 --- a/nimble/transport/dialog_cmac/syscfg.yml +++ b/nimble/transport/dialog_cmac/syscfg.yml @@ -16,7 +16,7 @@ # under the License. # -syscfg.vals.'!BLE_HCI_BRIDGE && !(BLE_EXT_ADV || BLE_LL_CFG_FEAT_LL_EXT_ADV)': +syscfg.vals.'!BLE_HCI_BRIDGE: BLE_HCI_EVT_HI_BUF_COUNT: 2 BLE_HCI_EVT_LO_BUF_COUNT: 8 BLE_HCI_EVT_BUF_SIZE: 70 From 95dff0b6e64519c1c789c8765d60a3824e5fb7c4 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 31 Jan 2022 16:57:07 +0100 Subject: [PATCH 0241/1333] Add mailmap --- .mailmap | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .mailmap diff --git a/.mailmap b/.mailmap new file mode 100644 index 0000000000..c1458fc5b5 --- /dev/null +++ b/.mailmap @@ -0,0 +1,8 @@ +Christopher Collins +Marko Kiiskila +Vipul Rahane +Vipul Rahane +Vipul Rahane +Will San Filippo +Will San Filippo + From e91e56ce4be1d4b4c6138f75c4d4391a1696763d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 31 Jan 2022 15:53:34 +0100 Subject: [PATCH 0242/1333] nimble/ll: Fix check when setting per adv data If periodic advertising instance is enabled, an attempt to set data with flag other than 'complete' shall return 'command disallowed'. This fixes HCI/DDI/BI-14-C. --- nimble/controller/src/ble_ll_adv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index bd85eabd1b..813db385b1 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -3870,6 +3870,10 @@ ble_ll_adv_periodic_set_data(const uint8_t *cmdbuf, uint8_t len) switch (cmd->operation) { case BLE_HCI_LE_SET_DATA_OPER_LAST: case BLE_HCI_LE_SET_DATA_OPER_INT: + if (advsm->periodic_adv_enabled) { + return BLE_ERR_CMD_DISALLOWED; + } + if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_DATA_INCOMPLETE)) { return BLE_ERR_INV_HCI_CMD_PARMS; } @@ -3877,10 +3881,6 @@ ble_ll_adv_periodic_set_data(const uint8_t *cmdbuf, uint8_t len) if (!advsm->periodic_adv_data || !cmd->adv_data_len) { return BLE_ERR_INV_HCI_CMD_PARMS; } - - if (advsm->periodic_adv_enabled) { - return BLE_ERR_CMD_DISALLOWED; - } break; case BLE_HCI_LE_SET_DATA_OPER_FIRST: if (advsm->periodic_adv_enabled) { From 23f22953c859a5c1dc594e506060a657cf3c1e3d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 1 Feb 2022 09:47:38 +0100 Subject: [PATCH 0243/1333] nimble/transport/cmac: Fix typo --- nimble/transport/dialog_cmac/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/transport/dialog_cmac/syscfg.yml b/nimble/transport/dialog_cmac/syscfg.yml index 190c2ca8a8..c67df3dc0f 100644 --- a/nimble/transport/dialog_cmac/syscfg.yml +++ b/nimble/transport/dialog_cmac/syscfg.yml @@ -16,7 +16,7 @@ # under the License. # -syscfg.vals.'!BLE_HCI_BRIDGE: +syscfg.vals.'!BLE_HCI_BRIDGE': BLE_HCI_EVT_HI_BUF_COUNT: 2 BLE_HCI_EVT_LO_BUF_COUNT: 8 BLE_HCI_EVT_BUF_SIZE: 70 From b8c1d516d9c7d4c8c41a55f940f2a4f23bbac9bf Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 1 Feb 2022 10:58:25 +0100 Subject: [PATCH 0244/1333] nimble/phy/cmac: Fix unexpected match on resolving list During scan window we restart rx after PDU without reinitializing phy, this means we do not reenable resolving list. On CMAC this means flags in resolver are not cleared so once we matched one device, we will return match for all subsequent devices in that window. So we just need to clear flag before starting any rx. --- nimble/drivers/dialog_cmac/src/ble_hw.c | 6 ++++++ nimble/drivers/dialog_cmac/src/ble_hw_priv.h | 1 + nimble/drivers/dialog_cmac/src/ble_phy.c | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/nimble/drivers/dialog_cmac/src/ble_hw.c b/nimble/drivers/dialog_cmac/src/ble_hw.c index 98c8144bb4..763de8dcfa 100644 --- a/nimble/drivers/dialog_cmac/src/ble_hw.c +++ b/nimble/drivers/dialog_cmac/src/ble_hw.c @@ -305,6 +305,12 @@ ble_hw_resolv_proc_disable(void) NVIC_DisableIRQ(CRYPTO_IRQn); } +void +ble_hw_resolv_proc_reset(const uint8_t *addr) +{ + g_ble_hw_resolv_proc.f_match = 0; +} + void ble_hw_resolv_proc_start(const uint8_t *addr) { diff --git a/nimble/drivers/dialog_cmac/src/ble_hw_priv.h b/nimble/drivers/dialog_cmac/src/ble_hw_priv.h index 627994ffcf..7595a20856 100644 --- a/nimble/drivers/dialog_cmac/src/ble_hw_priv.h +++ b/nimble/drivers/dialog_cmac/src/ble_hw_priv.h @@ -24,6 +24,7 @@ void ble_hw_resolv_proc_enable(void); void ble_hw_resolv_proc_disable(void); +void ble_hw_resolv_proc_reset(void); void ble_hw_resolv_proc_start(const uint8_t *addr); #endif /* _BLE_HW_PRIV_H_ */ diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index 212d19b671..1b1d821dfe 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -1347,6 +1347,10 @@ ble_phy_rx_setup_xcvr(void) { uint8_t rf_chan = g_ble_phy_chan_to_rf[g_ble_phy_data.channel]; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + ble_hw_resolv_proc_reset(); +#endif + CMAC->CM_EV_SET_REG = CMAC_CM_EV_SET_REG_EV1C_CALLBACK_VALID_SET_Msk; ble_rf_setup_rx(rf_chan, g_ble_phy_data.phy_mode_rx); From 7491ac024dd9d728032f018f6577488e59cf3431 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 31 Jan 2022 15:53:44 +0100 Subject: [PATCH 0245/1333] nimble/transport/cmac: Flush UART on CMAC error When CMAC is used with HCI bridge over UART we should wait for all data to be flushed from UART before asserting on error, otherwise we will lose debug events. --- .../include/cmac_driver/cmac_shared.h | 1 + .../dialog_cmac/cmac_driver/src/cmac_host.c | 49 +++++++++++++++++++ .../dialog_cmac/cmac_driver/src/cmac_mbox.c | 12 +++++ 3 files changed, 62 insertions(+) diff --git a/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h b/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h index 4e37bb8b82..da3a3cf612 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h +++ b/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h @@ -142,6 +142,7 @@ typedef int (cmac_mbox_read_cb)(const void *data, uint16_t len); typedef void (cmac_mbox_write_notif_cb)(void); void cmac_mbox_set_read_cb(cmac_mbox_read_cb *cb); void cmac_mbox_set_write_notif_cb(cmac_mbox_write_notif_cb *cb); +int cmac_mbox_has_data(void); int cmac_mbox_read(void); int cmac_mbox_write(const void *data, uint16_t len); diff --git a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c index df81c582bb..965db1398c 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c +++ b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c @@ -65,6 +65,13 @@ static struct os_event g_cmac_host_rand_ev = { static void cmac_host_rand_chk_fill(void); +#if MYNEWT_VAL(BLE_HCI_BRIDGE) && MYNEWT_VAL_CHOICE(BLE_HCI_TRANSPORT, uart) +static void cmac_host_error_w4flush(struct os_event *ev); +static struct os_event g_cmac_host_error_ev = { + .ev_cb = cmac_host_error_w4flush +}; +#endif + static void cmac2sys_isr(void) { @@ -105,6 +112,14 @@ cmac2sys_isr(void) for (;;); } #endif + +#if MYNEWT_VAL(BLE_HCI_BRIDGE) && MYNEWT_VAL_CHOICE(BLE_HCI_TRANSPORT, uart) + NVIC_DisableIRQ(CMAC2SYS_IRQn); + /* Wait until UART is flushed and then assert */ + cmac_host_error_w4flush(NULL); + return; +#endif + /* XXX CMAC is in error state, need to recover */ assert(0); return; @@ -147,6 +162,40 @@ cmac_host_rand_chk_fill(void) } } +#if MYNEWT_VAL(BLE_HCI_BRIDGE) && MYNEWT_VAL_CHOICE(BLE_HCI_TRANSPORT, uart) +#if MYNEWT_VAL(BLE_HCI_UART_PORT) < 0 || MYNEWT_VAL(BLE_HCI_UART_PORT) > 2 +#error Invalid BLE_HCI_UART_PORT +#endif +static void +cmac_host_error_w4flush(struct os_event *ev) +{ + static UART_Type * const regs[] = { + (void *)UART, + (void *)UART2, + (void *)UART3 + }; + + if (!ev) { + /* Move to task context, we do not want to spin in interrupt */ + os_eventq_put(os_eventq_dflt_get(), &g_cmac_host_error_ev); + return; + } + + do { + cmac_mbox_read(); + while ((regs[MYNEWT_VAL(BLE_HCI_UART_PORT)]->UART_LSR_REG & + UART_UART_LSR_REG_UART_TEMT_Msk) == 0) { + /* Wait until both FIFO and shift registers are empty */ + } + } while (cmac_mbox_has_data()); + + /* Reset CMAC */ + CRG_TOP->CLK_RADIO_REG |= CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Msk; + + assert(0); +} +#endif + void cmac_host_signal2cmac(void) { diff --git a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c index 88764c4dfc..36f4e25e1c 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c +++ b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c @@ -46,6 +46,18 @@ cmac_mbox_set_write_notif_cb(cmac_mbox_write_notif_cb *cb) g_cmac_mbox_write_notif_cb = cb; } +int +cmac_mbox_has_data(void) +{ +#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) + volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_c2s; +#else + volatile struct cmac_mbox *mbox = &g_cmac_shared_data.mbox_s2c; +#endif + + return mbox->rd_off != mbox->wr_off; +} + int cmac_mbox_read(void) { From b46b2b46bd84a8279de47aab2fdb8e5000da8f24 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 28 Jan 2022 15:34:34 +0100 Subject: [PATCH 0246/1333] nimble/plna: Fix bypass on SKY66112 --- nimble/drivers/plna/sky66112/src/sky66112.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/drivers/plna/sky66112/src/sky66112.c b/nimble/drivers/plna/sky66112/src/sky66112.c index 09afe5f96e..4a849fbb58 100644 --- a/nimble/drivers/plna/sky66112/src/sky66112.c +++ b/nimble/drivers/plna/sky66112/src/sky66112.c @@ -24,8 +24,8 @@ #include "controller/ble_ll_plna.h" #define NO_BYPASS \ - ((MYNEWT_VAL(SKY66112_TX_BYPASS) >= 0) && \ - (MYNEWT_VAL(SKY66112_RX_BYPASS) >= 0)) + ((MYNEWT_VAL(SKY66112_TX_BYPASS) == 0) && \ + (MYNEWT_VAL(SKY66112_RX_BYPASS) == 0)) static void sky66112_bypass(uint8_t enabled) From 22b38ccab9bb037ab5738a250cb21660d6a65248 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 28 Jan 2022 00:43:20 +0100 Subject: [PATCH 0247/1333] nimble/ll: Add ll_tmr This adds generic API for LL timer which replaces explicit os_cputime usage in LL. Short term, this allows for more consistent and simpler code since new API introduces few helpers to perform add/sub operations on timers with proper usecs wrapping. Long term, this will allow LL to work natively with timers that are not based on 32768Hz clock, as e.g. Dialog CMAC. --- nimble/controller/include/controller/ble_ll.h | 14 +- .../include/controller/ble_ll_rfmgmt.h | 4 +- .../include/controller/ble_ll_scan.h | 4 +- .../include/controller/ble_ll_tmr.h | 159 ++++++++++++++++++ nimble/controller/src/ble_ll.c | 1 - nimble/controller/src/ble_ll_adv.c | 96 +++++------ nimble/controller/src/ble_ll_conn.c | 101 ++++------- nimble/controller/src/ble_ll_ctrl.c | 4 +- nimble/controller/src/ble_ll_dtm.c | 19 +-- nimble/controller/src/ble_ll_rfmgmt.c | 26 +-- nimble/controller/src/ble_ll_scan.c | 32 ++-- nimble/controller/src/ble_ll_sched.c | 124 +++++--------- nimble/controller/src/ble_ll_sync.c | 52 ++---- nimble/controller/src/ble_ll_utils.c | 3 +- nimble/drivers/nrf52/src/ble_phy.c | 2 + 15 files changed, 344 insertions(+), 297 deletions(-) create mode 100644 nimble/controller/include/controller/ble_ll_tmr.h diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index f4b8517a8d..d148fbe9dc 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -21,7 +21,6 @@ #define H_BLE_LL_ #include "stats/stats.h" -#include "os/os_cputime.h" #include "nimble/nimble_opt.h" #include "nimble/nimble_npl.h" #include "controller/ble_phy.h" @@ -30,6 +29,9 @@ #include "controller/ble_ll_ctrl.h" #include "hal/hal_system.h" #endif +#ifdef RIOT_VERSION +#include "hal/hal_timer.h" +#endif #ifdef __cplusplus extern "C" { @@ -123,9 +125,6 @@ struct ble_ll_obj /* Task event queue */ struct ble_npl_eventq ll_evq; - /* Wait for response timer */ - struct hal_timer ll_wfr_timer; - /* Packet receive queue (and event). Holds received packets from PHY */ struct ble_npl_event ll_rx_pkt_ev; struct ble_ll_pkt_q ll_rx_pkt_q; @@ -612,13 +611,6 @@ ble_ll_get_addr_type(uint8_t txrxflag) return BLE_HCI_ADV_OWN_ADDR_PUBLIC; } -/* Convert usecs to ticks and round up to nearest tick */ -static inline uint32_t -ble_ll_usecs_to_ticks_round_up(uint32_t usecs) -{ - return os_cputime_usecs_to_ticks(usecs + 30); -} - #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) /* LTK 0x4C68384139F574D836BCF34E9DFB01BF */ extern const uint8_t g_bletest_LTK[]; diff --git a/nimble/controller/include/controller/ble_ll_rfmgmt.h b/nimble/controller/include/controller/ble_ll_rfmgmt.h index 5e2d636ff8..1aa1c4bb4a 100644 --- a/nimble/controller/include/controller/ble_ll_rfmgmt.h +++ b/nimble/controller/include/controller/ble_ll_rfmgmt.h @@ -24,6 +24,8 @@ extern "C" { #endif +#include "controller/ble_ll_tmr.h" + void ble_ll_rfmgmt_init(void); #if MYNEWT_VAL(BLE_LL_RFMGMT_ENABLE_TIME) > 0 @@ -51,7 +53,7 @@ static inline void ble_ll_rfmgmt_reset(void) { } static inline void ble_ll_rfmgmt_scan_changed(bool e, uint32_t n) { } static inline void ble_ll_rfmgmt_sched_changed(struct ble_ll_sched_item *f) { } static inline void ble_ll_rfmgmt_release(void) { } -static inline uint32_t ble_ll_rfmgmt_enable_now(void) { return os_cputime_get32(); } +static inline uint32_t ble_ll_rfmgmt_enable_now(void) { return ble_ll_tmr_get(); } static inline bool ble_ll_rfmgmt_is_enabled(void) { return true; } #endif diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index a44e431379..34bcd60b17 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -21,7 +21,7 @@ #define H_BLE_LL_SCAN_ #include "controller/ble_ll_sched.h" -#include "hal/hal_timer.h" +#include "controller/ble_ll_tmr.h" #include "syscfg/syscfg.h" #include "nimble/nimble_npl.h" @@ -135,7 +135,7 @@ struct ble_ll_scan_sm uint16_t backoff_count; uint32_t scan_win_start_time; struct ble_npl_event scan_sched_ev; - struct hal_timer scan_timer; + struct ble_ll_tmr scan_timer; struct ble_npl_event scan_interrupted_ev; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) diff --git a/nimble/controller/include/controller/ble_ll_tmr.h b/nimble/controller/include/controller/ble_ll_tmr.h new file mode 100644 index 0000000000..9dd6ab477c --- /dev/null +++ b/nimble/controller/include/controller/ble_ll_tmr.h @@ -0,0 +1,159 @@ +/* + * 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_BLE_LL_TMR_ +#define H_BLE_LL_TMR_ + +#include "os/os_cputime.h" +#include "controller/ble_ll.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define USECS_PER_TICK (31) + +#define LL_TMR_LT(_t1, _t2) ((int32_t)((_t1) - (_t2)) < 0) +#define LL_TMR_GT(_t1, _t2) ((int32_t)((_t1) - (_t2)) > 0) +#define LL_TMR_GEQ(_t1, _t2) ((int32_t)((_t1) - (_t2)) >= 0) +#define LL_TMR_LEQ(_t1, _t2) ((int32_t)((_t1) - (_t2)) <= 0) + +typedef void (ble_ll_tmr_cb)(void *arg); + +struct ble_ll_tmr { + struct hal_timer t; +}; + +static inline uint32_t +ble_ll_tmr_get(void) +{ + return os_cputime_get32(); +} + +static inline uint32_t +ble_ll_tmr_t2u(uint32_t ticks) +{ + return os_cputime_ticks_to_usecs(ticks); +} + +static inline uint32_t +ble_ll_tmr_u2t(uint32_t usecs) +{ + if (usecs <= 31249) { + return (usecs * 137439) / 4194304; + } + + return os_cputime_usecs_to_ticks(usecs); +} + +static inline uint32_t +ble_ll_tmr_u2t_up(uint32_t usecs) +{ + return ble_ll_tmr_u2t(usecs + (USECS_PER_TICK - 1)); +} + +static inline uint32_t +ble_ll_tmr_u2t_r(uint32_t usecs, uint8_t *rem_us) +{ + uint32_t ticks; + + ticks = ble_ll_tmr_u2t(usecs); + *rem_us = usecs - ble_ll_tmr_t2u(ticks); + if (*rem_us == USECS_PER_TICK) { + *rem_us = 0; + ticks++; + } + + return ticks; +} + +static inline void +ble_ll_tmr_add(uint32_t *ticks, uint8_t *rem_us, uint32_t usecs) +{ + uint32_t t_ticks; + uint8_t t_rem_us; + + t_ticks = ble_ll_tmr_u2t_r(usecs, &t_rem_us); + + *ticks += t_ticks; + *rem_us += t_rem_us; + if (*rem_us >= USECS_PER_TICK) { + *rem_us -= USECS_PER_TICK; + *ticks += 1; + } +} + +static inline void +ble_ll_tmr_add_u(uint32_t *ticks, uint8_t *rem_us, uint8_t usecs) +{ + BLE_LL_ASSERT(usecs < USECS_PER_TICK); + + *rem_us += usecs; + if (*rem_us >= USECS_PER_TICK) { + *rem_us -= USECS_PER_TICK; + *ticks += 1; + } +} + +static inline void +ble_ll_tmr_sub(uint32_t *ticks, uint8_t *rem_us, uint32_t usecs) +{ + uint32_t t_ticks; + uint8_t t_rem_us; + + if (usecs <= *rem_us) { + *rem_us -= usecs; + return; + } + + usecs -= *rem_us; + *rem_us = 0; + + t_ticks = ble_ll_tmr_u2t_r(usecs, &t_rem_us); + if (t_rem_us) { + t_ticks += 1; + *rem_us = USECS_PER_TICK - t_rem_us; + } + + *ticks -= t_ticks; +} + +static inline void +ble_ll_tmr_init(struct ble_ll_tmr *tmr, ble_ll_tmr_cb *cb, void *arg) +{ + os_cputime_timer_init(&tmr->t, cb, arg); +} + +static inline void +ble_ll_tmr_start(struct ble_ll_tmr *tmr, uint32_t tgt) +{ + os_cputime_timer_start(&tmr->t, tgt); +} + +static inline void +ble_ll_tmr_stop(struct ble_ll_tmr *tmr) +{ + os_cputime_timer_stop(&tmr->t); +} + +#ifdef __cplusplus +} +#endif + +#endif /* H_BLE_LL_TMR_ */ \ No newline at end of file diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index ce82c0d6f9..34c0c772bf 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -24,7 +24,6 @@ #include "sysinit/sysinit.h" #include "syscfg/syscfg.h" #include "os/os.h" -#include "os/os_cputime.h" #include "stats/stats.h" #include "nimble/ble.h" #include "nimble/nimble_opt.h" diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 813db385b1..caa817ee1a 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -22,7 +22,6 @@ #include #include "syscfg/syscfg.h" #include "os/os.h" -#include "os/os_cputime.h" #include "ble/xcvr.h" #include "nimble/ble.h" #include "nimble/nimble_opt.h" @@ -37,6 +36,7 @@ #include "controller/ble_ll_scan.h" #include "controller/ble_ll_whitelist.h" #include "controller/ble_ll_resolv.h" +#include "controller/ble_ll_tmr.h" #include "controller/ble_ll_trace.h" #include "controller/ble_ll_utils.h" #include "controller/ble_ll_rfmgmt.h" @@ -587,7 +587,7 @@ ble_ll_adv_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) /* AuxPtr */ if (AUX_CURRENT(advsm)->sch.enqueued) { - offset = os_cputime_ticks_to_usecs(AUX_CURRENT(advsm)->start_time - advsm->adv_pdu_start_time); + offset = ble_ll_tmr_t2u(AUX_CURRENT(advsm)->start_time - advsm->adv_pdu_start_time); } else { offset = 0; } @@ -620,11 +620,11 @@ ble_ll_adv_put_syncinfo(struct ble_ll_adv_sm *advsm, conn_cnt = connsm->event_cntr; /* get anchor for conn event that is before periodic_adv_event_start_time */ - while (CPUTIME_GT(anchor, advsm->periodic_adv_event_start_time)) { + while (LL_TMR_GT(anchor, advsm->periodic_adv_event_start_time)) { ble_ll_conn_get_anchor(connsm, --conn_cnt, &anchor, &anchor_usecs); } - offset = os_cputime_ticks_to_usecs(advsm->periodic_adv_event_start_time - anchor); + offset = ble_ll_tmr_t2u(advsm->periodic_adv_event_start_time - anchor); offset -= anchor_usecs; offset += advsm->periodic_adv_event_start_time_remainder; @@ -639,12 +639,12 @@ ble_ll_adv_put_syncinfo(struct ble_ll_adv_sm *advsm, * happen if advertising event is interleaved with periodic advertising * event (when chaining). */ - while (CPUTIME_GT(AUX_CURRENT(advsm)->start_time, anchor)) { + while (LL_TMR_GT(AUX_CURRENT(advsm)->start_time, anchor)) { anchor += advsm->periodic_adv_itvl_ticks; event_cnt_off++; } - offset = os_cputime_ticks_to_usecs(anchor - AUX_CURRENT(advsm)->start_time); + offset = ble_ll_tmr_t2u(anchor - AUX_CURRENT(advsm)->start_time); offset += advsm->periodic_adv_event_start_time_remainder; offset += advsm->periodic_adv_itvl_rem_usec; } @@ -776,10 +776,10 @@ ble_ll_adv_aux_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) */ offset = 0; } else if (advsm->rx_ble_hdr) { - offset = os_cputime_ticks_to_usecs(AUX_NEXT(advsm)->start_time - advsm->rx_ble_hdr->beg_cputime); + offset = ble_ll_tmr_t2u(AUX_NEXT(advsm)->start_time - advsm->rx_ble_hdr->beg_cputime); offset -= (advsm->rx_ble_hdr->rem_usecs + ble_ll_pdu_tx_time_get(12, advsm->sec_phy) + BLE_LL_IFS); } else { - offset = os_cputime_ticks_to_usecs(AUX_NEXT(advsm)->start_time - aux->start_time); + offset = ble_ll_tmr_t2u(AUX_NEXT(advsm)->start_time - aux->start_time); } ble_ll_adv_put_aux_ptr(AUX_NEXT(advsm)->chan, advsm->sec_phy, @@ -1226,8 +1226,7 @@ ble_ll_adv_set_sched(struct ble_ll_adv_sm *advsm) sch->start_time = advsm->adv_pdu_start_time - g_ble_ll_sched_offset_ticks; sch->remainder = 0; - sch->end_time = advsm->adv_pdu_start_time + - ble_ll_usecs_to_ticks_round_up(max_usecs); + sch->end_time = advsm->adv_pdu_start_time + ble_ll_tmr_u2t_up(max_usecs); } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) @@ -1520,13 +1519,13 @@ ble_ll_adv_aux_schedule_next(struct ble_ll_adv_sm *advsm) max_usecs = ble_ll_pdu_tx_time_get(aux_next->payload_len, advsm->sec_phy); aux_next->start_time = aux->sch.end_time + - ble_ll_usecs_to_ticks_round_up(BLE_LL_MAFS + MYNEWT_VAL(BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY)); + ble_ll_tmr_u2t_up(BLE_LL_MAFS + + MYNEWT_VAL(BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY)); sch = &aux_next->sch; sch->start_time = aux_next->start_time - g_ble_ll_sched_offset_ticks; sch->remainder = 0; - sch->end_time = aux_next->start_time + - ble_ll_usecs_to_ticks_round_up(max_usecs); + sch->end_time = aux_next->start_time + ble_ll_tmr_u2t_up(max_usecs); ble_ll_sched_adv_new(&aux_next->sch, ble_ll_adv_aux_scheduled, aux_next); /* @@ -1535,7 +1534,7 @@ ble_ll_adv_aux_schedule_next(struct ble_ll_adv_sm *advsm) * so advertising will stop after current aux. */ if (advsm->duration && - CPUTIME_GT(aux_next->sch.end_time, advsm->adv_end_time)) { + LL_TMR_GT(aux_next->sch.end_time, advsm->adv_end_time)) { ble_ll_sched_rmv_elem(&aux_next->sch); } } @@ -1595,7 +1594,7 @@ ble_ll_adv_aux_schedule_first(struct ble_ll_adv_sm *advsm) sch = &aux->sch; sch->start_time = aux->start_time - g_ble_ll_sched_offset_ticks; sch->remainder = 0; - sch->end_time = aux->start_time + ble_ll_usecs_to_ticks_round_up(max_usecs); + sch->end_time = aux->start_time + ble_ll_tmr_u2t_up(max_usecs); ble_ll_sched_adv_new(sch, ble_ll_adv_aux_scheduled, aux); } @@ -1641,7 +1640,8 @@ ble_ll_adv_aux_set_start_time(struct ble_ll_adv_sm *advsm) adv_event_dur = (adv_pdu_dur * chans) + (9 * (chans - 1)); advsm->aux[0].start_time = advsm->adv_event_start_time + adv_event_dur + - ble_ll_usecs_to_ticks_round_up(BLE_LL_MAFS + MYNEWT_VAL(BLE_LL_SCHED_AUX_MAFS_DELAY)); + ble_ll_tmr_u2t_up(BLE_LL_MAFS + + MYNEWT_VAL(BLE_LL_SCHED_AUX_MAFS_DELAY)); } static void @@ -1665,7 +1665,7 @@ ble_ll_adv_aux_schedule(struct ble_ll_adv_sm *advsm) * not start extended advertising event which we cannot finish in time. */ if (advsm->duration && - CPUTIME_GT(AUX_CURRENT(advsm)->sch.end_time, advsm->adv_end_time)) { + LL_TMR_GT(AUX_CURRENT(advsm)->sch.end_time, advsm->adv_end_time)) { ble_ll_adv_sm_stop_timeout(advsm); } } @@ -2031,14 +2031,14 @@ ble_ll_adv_scheduled(struct ble_ll_adv_sm *advsm, uint32_t sch_start, void *arg) */ if (advsm->duration) { advsm->adv_end_time = advsm->adv_event_start_time + - os_cputime_usecs_to_ticks(advsm->duration * 10000); + ble_ll_tmr_u2t(advsm->duration * 10000); } #else /* Set the time at which we must end directed, high-duty cycle advertising. */ if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) { advsm->adv_end_time = advsm->adv_event_start_time + - os_cputime_usecs_to_ticks(BLE_LL_ADV_STATE_HD_MAX * 1000); + ble_ll_tmr_u2t(BLE_LL_ADV_STATE_HD_MAX * 1000); } #endif } @@ -2085,7 +2085,8 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) */ offset = 0; } else { - offset = os_cputime_ticks_to_usecs(SYNC_NEXT(advsm)->start_time - sync->start_time); + offset = ble_ll_tmr_t2u(SYNC_NEXT(advsm)->start_time - + sync->start_time); } ble_ll_adv_put_aux_ptr(SYNC_NEXT(advsm)->chan, advsm->sec_phy, @@ -2327,15 +2328,13 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm, sch = &sync->sch; - advsm->periodic_adv_event_start_time_remainder += advsm->periodic_adv_itvl_rem_usec; - if (advsm->periodic_adv_event_start_time_remainder >= 31) { - advsm->periodic_adv_event_start_time++; - advsm->periodic_adv_event_start_time_remainder -= 31; - } + ble_ll_tmr_add_u(&advsm->periodic_adv_event_start_time, + &advsm->periodic_adv_event_start_time_remainder, + advsm->periodic_adv_itvl_rem_usec); sch->start_time = advsm->periodic_adv_event_start_time; sch->remainder = advsm->periodic_adv_event_start_time_remainder; - sch->end_time = sch->start_time + ble_ll_usecs_to_ticks_round_up(max_usecs); + sch->end_time = sch->start_time + ble_ll_tmr_u2t_up(max_usecs); sch->start_time -= g_ble_ll_sched_offset_ticks; rc = ble_ll_sched_periodic_adv(sch, first_pdu); @@ -2415,22 +2414,22 @@ ble_ll_adv_periodic_schedule_next(struct ble_ll_adv_sm *advsm) max_usecs = ble_ll_pdu_tx_time_get(sync_next->payload_len, advsm->sec_phy); sync_next->start_time = sync->sch.end_time + - ble_ll_usecs_to_ticks_round_up(BLE_LL_MAFS + MYNEWT_VAL(BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY)); + ble_ll_tmr_u2t_up(BLE_LL_MAFS + + MYNEWT_VAL(BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY)); sch = &sync_next->sch; sch->start_time = sync_next->start_time - g_ble_ll_sched_offset_ticks; /* adjust for previous packets remainder */ sch->remainder = sync->sch.remainder; - sch->end_time = sync_next->start_time + - ble_ll_usecs_to_ticks_round_up(max_usecs); + sch->end_time = sync_next->start_time + ble_ll_tmr_u2t_up(max_usecs); /* here we can use ble_ll_sched_adv_new as we don't care about timing */ ble_ll_sched_adv_new(&sync_next->sch, ble_ll_adv_sync_next_scheduled, sync_next); /* if we are pass advertising interval, drop chain */ - if (CPUTIME_GT(sch->end_time, advsm->periodic_adv_event_start_time + + if (LL_TMR_GT(sch->end_time, advsm->periodic_adv_event_start_time + advsm->periodic_adv_itvl_ticks)) { STATS_INC(ble_ll_stats, periodic_chain_drop_event); ble_ll_sched_rmv_elem(&sync->sch); @@ -2532,7 +2531,6 @@ static void ble_ll_adv_sm_start_periodic(struct ble_ll_adv_sm *advsm) { uint32_t usecs; - uint32_t ticks; /* * The Advertising DID is not required to change when a SyncInfo field is @@ -2560,21 +2558,16 @@ ble_ll_adv_sm_start_periodic(struct ble_ll_adv_sm *advsm) advsm->periodic_crcinit = ble_ll_rand() & 0xffffff; usecs = (uint32_t)advsm->periodic_adv_itvl_max * BLE_LL_ADV_PERIODIC_ITVL; - ticks = os_cputime_usecs_to_ticks(usecs); - advsm->periodic_adv_itvl_rem_usec = (usecs - os_cputime_ticks_to_usecs(ticks)); - if (advsm->periodic_adv_itvl_rem_usec == 31) { - advsm->periodic_adv_itvl_rem_usec = 0; - ticks++; - } - advsm->periodic_adv_itvl_ticks = ticks; + advsm->periodic_adv_itvl_ticks = ble_ll_tmr_u2t_r(usecs, + &advsm->periodic_adv_itvl_rem_usec); /* There is no point in starting periodic advertising until next advertising * event since SyncInfo is needed for synchronization */ advsm->periodic_adv_event_start_time_remainder = 0; advsm->periodic_adv_event_start_time = advsm->adv_pdu_start_time + - os_cputime_usecs_to_ticks(advsm->adv_itvl_usecs + 5000); + ble_ll_tmr_u2t(advsm->adv_itvl_usecs + 5000); ble_ll_adv_sync_schedule(advsm, true); } @@ -2747,8 +2740,8 @@ ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm) earliest_start_time = ble_ll_rfmgmt_enable_now(); start_delay_us = ble_ll_rand() % (BLE_LL_ADV_DELAY_MS_MAX * 1000); - advsm->adv_pdu_start_time = os_cputime_get32() + - os_cputime_usecs_to_ticks(start_delay_us); + advsm->adv_pdu_start_time = ble_ll_tmr_get() + + ble_ll_tmr_u2t(start_delay_us); ble_ll_adv_set_sched(advsm); @@ -3760,8 +3753,8 @@ ble_ll_adv_periodic_check_data_itvl(uint16_t payload_len, uint16_t props, pdu_len = ble_ll_adv_sync_get_pdu_len(payload_len, &offset, props); max_usecs += ble_ll_pdu_tx_time_get(pdu_len, phy); - max_usecs += ble_ll_usecs_to_ticks_round_up(BLE_LL_MAFS + - MYNEWT_VAL(BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY)); + max_usecs += ble_ll_tmr_u2t_up(BLE_LL_MAFS + + MYNEWT_VAL(BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY)); } itvl_usecs = (uint32_t)itvl * BLE_LL_ADV_PERIODIC_ITVL; @@ -4630,8 +4623,7 @@ ble_ll_adv_reschedule_event(struct ble_ll_adv_sm *advsm) if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) { max_delay_ticks = 0; } else { - max_delay_ticks = - os_cputime_usecs_to_ticks(BLE_LL_ADV_DELAY_MS_MAX * 1000); + max_delay_ticks = ble_ll_tmr_u2t(BLE_LL_ADV_DELAY_MS_MAX * 1000); } rc = ble_ll_sched_adv_reschedule(sch, max_delay_ticks); @@ -4718,7 +4710,7 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) * add the random advDelay as the scheduling code will do that. */ itvl = advsm->adv_itvl_usecs; - tick_itvl = os_cputime_usecs_to_ticks(itvl); + tick_itvl = ble_ll_tmr_u2t(itvl); advsm->adv_event_start_time += tick_itvl; advsm->adv_pdu_start_time = advsm->adv_event_start_time; @@ -4728,7 +4720,7 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) */ start_time = advsm->adv_pdu_start_time - g_ble_ll_sched_offset_ticks; - delta_t = (int32_t)(start_time - os_cputime_get32()); + delta_t = (int32_t)(start_time - ble_ll_tmr_get()); if (delta_t < 0) { /* * NOTE: we just the same interval that we calculated earlier. @@ -4757,14 +4749,14 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) * We will transmit right away. Set next pdu start time to now * plus a xcvr start delay just so we dont count late adv starts */ - advsm->adv_pdu_start_time = os_cputime_get32() + + advsm->adv_pdu_start_time = ble_ll_tmr_get() + g_ble_ll_sched_offset_ticks; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) /* If we're past aux (unlikely, but can happen), just drop an event */ if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) && advsm->aux_active && - CPUTIME_GT(advsm->adv_pdu_start_time, + LL_TMR_GT(advsm->adv_pdu_start_time, AUX_CURRENT(advsm)->start_time)) { ble_ll_adv_drop_event(advsm); return; @@ -4777,7 +4769,7 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) /* check if advertising timed out */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (advsm->duration && - CPUTIME_GEQ(advsm->adv_pdu_start_time, advsm->adv_end_time)) { + LL_TMR_GEQ(advsm->adv_pdu_start_time, advsm->adv_end_time)) { /* Legacy PDUs need to be stop here. * For ext adv it will be stopped when AUX is done (unless it was * dropped so check if AUX is active here as well). @@ -4791,7 +4783,7 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) } #else if ((advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) && - CPUTIME_GEQ(advsm->adv_pdu_start_time, advsm->adv_end_time)) { + LL_TMR_GEQ(advsm->adv_pdu_start_time, advsm->adv_end_time)) { ble_ll_adv_sm_stop_timeout(advsm); return; } @@ -4896,7 +4888,7 @@ ble_ll_adv_sec_done(struct ble_ll_adv_sm *advsm) /* Check if advertising timed out */ if (advsm->duration && - CPUTIME_GEQ(advsm->adv_pdu_start_time, advsm->adv_end_time)) { + LL_TMR_GEQ(advsm->adv_pdu_start_time, advsm->adv_end_time)) { ble_ll_adv_sm_stop_timeout(advsm); return; } diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 2fb65869ef..d3579ed2d9 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -23,7 +23,6 @@ #include #include "syscfg/syscfg.h" #include "os/os.h" -#include "os/os_cputime.h" #include "nimble/ble.h" #include "nimble/hci_common.h" #include "nimble/ble_hci_trans.h" @@ -37,6 +36,7 @@ #include "controller/ble_ll_adv.h" #include "controller/ble_ll_trace.h" #include "controller/ble_ll_rfmgmt.h" +#include "controller/ble_ll_tmr.h" #include "controller/ble_phy.h" #include "controller/ble_ll_utils.h" #include "ble_ll_conn_priv.h" @@ -428,19 +428,7 @@ void ble_ll_conn_itvl_to_ticks(uint32_t itvl, uint32_t *itvl_ticks, uint8_t *itvl_usecs) { - uint32_t ticks; - uint32_t usecs; - - usecs = itvl * BLE_LL_CONN_ITVL_USECS; - ticks = os_cputime_usecs_to_ticks(usecs); - usecs = usecs - os_cputime_ticks_to_usecs(ticks); - if (usecs == 31) { - usecs = 0; - ++ticks; - } - - *itvl_ticks = ticks; - *itvl_usecs = usecs; + *itvl_ticks = ble_ll_tmr_u2t_r(itvl * BLE_LL_CONN_ITVL_USECS, itvl_usecs); } /** @@ -495,7 +483,7 @@ ble_ll_conn_is_lru(struct ble_ll_conn_sm *s1, struct ble_ll_conn_sm *s2) int rc; /* Set time that we last serviced the schedule */ - if (CPUTIME_LT(s1->last_scheduled, s2->last_scheduled)) { + if (LL_TMR_LT(s1->last_scheduled, s2->last_scheduled)) { rc = 1; } else { rc = 0; @@ -518,7 +506,7 @@ ble_ll_conn_get_ce_end_time(void) if (g_ble_ll_conn_cur_sm) { ce_end_time = g_ble_ll_conn_cur_sm->ce_end_time; } else { - ce_end_time = os_cputime_get32(); + ce_end_time = ble_ll_tmr_get(); } return ce_end_time; } @@ -779,17 +767,17 @@ ble_ll_conn_get_next_sched_time(struct ble_ll_conn_sm *connsm) #else uint32_t ce_end; uint32_t next_sched_time; + uint8_t rem_us; /* Calculate time at which next connection event will start */ /* NOTE: We dont care if this time is tick short. */ ce_end = connsm->anchor_point + connsm->conn_itvl_ticks - g_ble_ll_sched_offset_ticks; - if ((connsm->anchor_point_usecs + connsm->conn_itvl_usecs) >= 31) { - ++ce_end; - } + rem_us = connsm->anchor_point_usecs; + ble_ll_tmr_add_u(&ce_end, &rem_us, connsm->conn_itvl_usecs); if (ble_ll_sched_next_time(&next_sched_time)) { - if (CPUTIME_LT(next_sched_time, ce_end)) { + if (LL_TMR_LT(next_sched_time, ce_end)) { ce_end = next_sched_time; } } @@ -1112,8 +1100,8 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) } #endif - ticks = os_cputime_usecs_to_ticks(ticks); - if (CPUTIME_LT(os_cputime_get32() + ticks, next_event_time)) { + ticks = ble_ll_tmr_u2t(ticks); + if (LL_TMR_LT(ble_ll_tmr_get() + ticks, next_event_time)) { md = 1; } } @@ -1447,7 +1435,7 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) } /* Set time that we last serviced the schedule */ - connsm->last_scheduled = os_cputime_get32(); + connsm->last_scheduled = ble_ll_tmr_get(); return rc; } @@ -1517,7 +1505,7 @@ ble_ll_conn_can_send_next_pdu(struct ble_ll_conn_sm *connsm, uint32_t begtime, usecs += (BLE_LL_IFS * 2) + connsm->eff_max_rx_time; ticks = (uint32_t)(next_sched_time - begtime); - allowed_usecs = os_cputime_ticks_to_usecs(ticks); + allowed_usecs = ble_ll_tmr_t2u(ticks); if ((usecs + add_usecs) >= allowed_usecs) { rc = 0; } @@ -2004,26 +1992,19 @@ void ble_ll_conn_get_anchor(struct ble_ll_conn_sm *connsm, uint16_t conn_event, uint32_t *anchor, uint8_t *anchor_usecs) { - uint32_t ticks; uint32_t itvl; itvl = (connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS); + *anchor = connsm->anchor_point; + *anchor_usecs = connsm->anchor_point_usecs; + if ((int16_t)(conn_event - connsm->event_cntr) < 0) { itvl *= connsm->event_cntr - conn_event; - ticks = os_cputime_usecs_to_ticks(itvl); - *anchor = connsm->anchor_point - ticks; + ble_ll_tmr_sub(anchor, anchor_usecs, itvl); } else { itvl *= conn_event - connsm->event_cntr; - ticks = os_cputime_usecs_to_ticks(itvl); - *anchor = connsm->anchor_point + ticks; - } - - *anchor_usecs = connsm->anchor_point_usecs; - *anchor_usecs += (itvl - os_cputime_ticks_to_usecs(ticks)); - if (*anchor_usecs >= 31) { - (*anchor)++; - *anchor_usecs -= 31; + ble_ll_tmr_add(anchor, anchor_usecs, itvl); } } #endif @@ -2047,7 +2028,6 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) uint32_t max_ww; #endif struct ble_ll_conn_upd_req *upd; - uint32_t ticks; uint32_t usecs; /* XXX: deal with connection request procedure here as well */ @@ -2096,15 +2076,11 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) /* We can use pre-calculated values for one interval if latency is 1. */ if (latency == 1) { connsm->anchor_point += connsm->conn_itvl_ticks; - connsm->anchor_point_usecs += connsm->conn_itvl_usecs; + ble_ll_tmr_add_u(&connsm->anchor_point, &connsm->anchor_point_usecs, + connsm->conn_itvl_usecs); } else { - ticks = os_cputime_usecs_to_ticks(itvl); - connsm->anchor_point += ticks; - connsm->anchor_point_usecs += (itvl - os_cputime_ticks_to_usecs(ticks)); - } - if (connsm->anchor_point_usecs >= 31) { - ++connsm->anchor_point; - connsm->anchor_point_usecs -= 31; + ble_ll_tmr_add(&connsm->anchor_point, &connsm->anchor_point_usecs, + itvl); } /* @@ -2140,14 +2116,8 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) if (upd->winoffset != 0) { usecs = upd->winoffset * BLE_LL_CONN_ITVL_USECS; - ticks = os_cputime_usecs_to_ticks(usecs); - connsm->anchor_point += ticks; - usecs = usecs - os_cputime_ticks_to_usecs(ticks); - connsm->anchor_point_usecs += usecs; - if (connsm->anchor_point_usecs >= 31) { - ++connsm->anchor_point; - connsm->anchor_point_usecs -= 31; - } + ble_ll_tmr_add(&connsm->anchor_point, &connsm->anchor_point_usecs, + usecs); } /* Reset the starting point of the connection supervision timeout */ @@ -2266,7 +2236,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) } cur_ww += BLE_LL_JITTER_USECS; connsm->slave_cur_window_widening = cur_ww; - itvl += os_cputime_usecs_to_ticks(cur_ww + connsm->slave_cur_tx_win_usecs); + itvl += ble_ll_tmr_u2t(cur_ww + connsm->slave_cur_tx_win_usecs); } #endif itvl -= g_ble_ll_sched_offset_ticks; @@ -2298,7 +2268,6 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) uint8_t *evbuf; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - uint32_t endtime; uint32_t usecs; #endif @@ -2311,7 +2280,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) connsm->csmflags.cfbit.pkt_rxd = 0; /* Consider time created the last scheduled time */ - connsm->last_scheduled = os_cputime_get32(); + connsm->last_scheduled = ble_ll_tmr_get(); /* * Set the last rxd pdu time since this is where we want to start the @@ -2356,25 +2325,22 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) } /* Anchor point is cputime. */ - endtime = os_cputime_usecs_to_ticks(usecs); - connsm->anchor_point = rxhdr->beg_cputime + endtime; - connsm->anchor_point_usecs = usecs - os_cputime_ticks_to_usecs(endtime); - if (connsm->anchor_point_usecs == 31) { - ++connsm->anchor_point; - connsm->anchor_point_usecs = 0; - } + connsm->anchor_point = rxhdr->beg_cputime; + connsm->anchor_point_usecs = 0; + ble_ll_tmr_add(&connsm->anchor_point, &connsm->anchor_point_usecs, + usecs); connsm->slave_cur_tx_win_usecs = connsm->tx_win_size * BLE_LL_CONN_TX_WIN_USECS; #if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) connsm->ce_end_time = connsm->anchor_point + g_ble_ll_sched_data.sch_ticks_per_period + - os_cputime_usecs_to_ticks(connsm->slave_cur_tx_win_usecs) + 1; + ble_ll_tmr_u2t(connsm->slave_cur_tx_win_usecs) + 1; #else connsm->ce_end_time = connsm->anchor_point + (MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * BLE_LL_SCHED_TICKS_PER_SLOT) - + os_cputime_usecs_to_ticks(connsm->slave_cur_tx_win_usecs) + 1; + + ble_ll_tmr_u2t(connsm->slave_cur_tx_win_usecs) + 1; #endif connsm->slave_cur_window_widening = BLE_LL_JITTER_USECS; @@ -2571,7 +2537,7 @@ ble_ll_conn_event_end(struct ble_npl_event *ev) ble_err = BLE_ERR_CONN_SPVN_TMO; } /* XXX: Convert to ticks to usecs calculation instead??? */ - tmo = os_cputime_usecs_to_ticks(tmo); + tmo = ble_ll_tmr_u2t(tmo); if ((int32_t)(connsm->anchor_point - connsm->last_rxd_pdu_cputime) >= tmo) { ble_ll_conn_end(connsm, ble_err); return; @@ -3264,8 +3230,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) connsm->cons_rxd_bad_crc = 0; /* Set last valid received pdu time (resets supervision timer) */ - connsm->last_rxd_pdu_cputime = begtime + - os_cputime_usecs_to_ticks(add_usecs); + connsm->last_rxd_pdu_cputime = begtime + ble_ll_tmr_u2t(add_usecs); /* * Check for valid LLID before proceeding. We have seen some weird diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 432045e675..78cf0756d6 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -29,6 +29,7 @@ #include "controller/ble_ll_trace.h" #include "controller/ble_hw.h" #include "controller/ble_ll_sync.h" +#include "controller/ble_ll_tmr.h" #include "ble_ll_conn_priv.h" #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) @@ -2439,8 +2440,7 @@ ble_ll_ctrl_terminate_start(struct ble_ll_conn_sm *connsm) /* Set terminate "timeout" */ usecs = connsm->supervision_tmo * BLE_HCI_CONN_SPVN_TMO_UNITS * 1000; - connsm->terminate_timeout = os_cputime_get32() + - os_cputime_usecs_to_ticks(usecs); + connsm->terminate_timeout = ble_ll_tmr_get() + ble_ll_tmr_u2t(usecs); } } diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index 8c9167799a..2c787da88e 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -29,6 +29,7 @@ #include "controller/ble_phy.h" #include "controller/ble_ll_sched.h" #include "controller/ble_ll_rfmgmt.h" +#include "controller/ble_ll_tmr.h" #include "ble_ll_dtm_priv.h" STATS_SECT_START(ble_ll_dtm_stats) @@ -153,11 +154,8 @@ ble_ll_dtm_set_next(struct dtm_ctx *ctx) struct ble_ll_sched_item *sch = &ctx->sch; ctx->pdu_start_ticks += ctx->itvl_ticks; - ctx->pdu_start_usecs += ctx->itvl_rem_usec; - if (ctx->pdu_start_usecs >= 31) { - ctx->pdu_start_ticks++; - ctx->pdu_start_usecs -= 31; - } + ble_ll_tmr_add_u(&ctx->pdu_start_ticks, &ctx->pdu_start_usecs, + ctx->itvl_rem_usec); sch->start_time = ctx->pdu_start_ticks; sch->remainder = ctx->pdu_start_usecs; @@ -278,7 +276,6 @@ ble_ll_dtm_calculate_itvl(struct dtm_ctx *ctx, uint8_t len, { uint32_t l; uint32_t itvl_usec; - uint32_t itvl_ticks; /* Calculate interval as per spec Bluetooth 5.0 Vol 6. Part F, 4.1.6 */ l = ble_ll_pdu_tx_time_get(len + BLE_LL_PDU_HDR_LEN, phy_mode); @@ -290,13 +287,7 @@ ble_ll_dtm_calculate_itvl(struct dtm_ctx *ctx, uint8_t len, } #endif - itvl_ticks = os_cputime_usecs_to_ticks(itvl_usec); - ctx->itvl_rem_usec = (itvl_usec - os_cputime_ticks_to_usecs(itvl_ticks)); - if (ctx->itvl_rem_usec == 31) { - ctx->itvl_rem_usec = 0; - ++itvl_ticks; - } - ctx->itvl_ticks = itvl_ticks; + ctx->itvl_ticks = ble_ll_tmr_u2t_r(itvl_usec, &ctx->itvl_rem_usec); } static int @@ -410,7 +401,7 @@ ble_ll_dtm_rx_start(void) #endif OS_ENTER_CRITICAL(sr); - rc = ble_phy_rx_set_start_time(os_cputime_get32(), 0); + rc = ble_phy_rx_set_start_time(ble_ll_tmr_get(), 0); OS_EXIT_CRITICAL(sr); if (rc && rc != BLE_PHY_ERR_RX_LATE) { return rc; diff --git a/nimble/controller/src/ble_ll_rfmgmt.c b/nimble/controller/src/ble_ll_rfmgmt.c index 986645f4a1..f73f6b3dfa 100644 --- a/nimble/controller/src/ble_ll_rfmgmt.c +++ b/nimble/controller/src/ble_ll_rfmgmt.c @@ -22,11 +22,11 @@ #include #include #include "syscfg/syscfg.h" -#include "os/os_cputime.h" #include "controller/ble_phy.h" #include "controller/ble_ll.h" #include "controller/ble_ll_sched.h" #include "controller/ble_ll_rfmgmt.h" +#include "controller/ble_ll_tmr.h" #include "ble_ll_priv.h" #if MYNEWT_VAL(BLE_LL_RFMGMT_ENABLE_TIME) > 0 @@ -41,7 +41,7 @@ struct ble_ll_rfmgmt_data { enum ble_ll_rfmgmt_state state; uint16_t ticks_to_enabled; - struct hal_timer timer; + struct ble_ll_tmr timer; bool timer_scheduled; uint32_t timer_scheduled_at; @@ -64,7 +64,7 @@ ble_ll_rfmgmt_enable(void) if (g_ble_ll_rfmgmt_data.state == RFMGMT_STATE_OFF) { g_ble_ll_rfmgmt_data.state = RFMGMT_STATE_ENABLING; - g_ble_ll_rfmgmt_data.enabled_at = os_cputime_get32(); + g_ble_ll_rfmgmt_data.enabled_at = ble_ll_tmr_get(); ble_phy_rfclk_enable(); BLE_LL_DEBUG_GPIO(RFMGMT, 1); } @@ -101,7 +101,7 @@ ble_ll_rfmgmt_timer_reschedule(void) enable_at = rfmgmt->enable_sched_at; } else { rfmgmt->timer_scheduled = false; - os_cputime_timer_stop(&rfmgmt->timer); + ble_ll_tmr_stop(&rfmgmt->timer); return; } @@ -118,7 +118,7 @@ ble_ll_rfmgmt_timer_reschedule(void) } rfmgmt->timer_scheduled = false; - os_cputime_timer_stop(&rfmgmt->timer); + ble_ll_tmr_stop(&rfmgmt->timer); } /* @@ -128,14 +128,14 @@ ble_ll_rfmgmt_timer_reschedule(void) * such case it's absolutely harmless since we already have clock enabled * and this will do nothing. */ - if (CPUTIME_LEQ(enable_at, os_cputime_get32())) { + if (CPUTIME_LEQ(enable_at, ble_ll_tmr_get())) { ble_ll_rfmgmt_enable(); return; } rfmgmt->timer_scheduled = true; rfmgmt->timer_scheduled_at = enable_at; - os_cputime_timer_start(&rfmgmt->timer, enable_at); + ble_ll_tmr_start(&rfmgmt->timer, enable_at); } static void @@ -156,7 +156,7 @@ ble_ll_rfmgmt_release_ev(struct ble_npl_event *ev) OS_ENTER_CRITICAL(sr); - now = os_cputime_get32(); + now = ble_ll_tmr_get(); can_disable = true; lls = ble_ll_state_get(); @@ -191,7 +191,7 @@ ble_ll_rfmgmt_ticks_to_enabled(void) rem_ticks = rfmgmt->ticks_to_enabled; break; case RFMGMT_STATE_ENABLING: - now = os_cputime_get32(); + now = ble_ll_tmr_get(); if (CPUTIME_LT(now, rfmgmt->enabled_at + rfmgmt->ticks_to_enabled)) { rem_ticks = rfmgmt->enabled_at + rfmgmt->ticks_to_enabled - now; break; @@ -220,10 +220,10 @@ ble_ll_rfmgmt_init(void) rfmgmt->state = RFMGMT_STATE_OFF; rfmgmt->ticks_to_enabled = - ble_ll_usecs_to_ticks_round_up(MYNEWT_VAL(BLE_LL_RFMGMT_ENABLE_TIME)); + ble_ll_tmr_u2t_up(MYNEWT_VAL(BLE_LL_RFMGMT_ENABLE_TIME)); rfmgmt->timer_scheduled = false; - os_cputime_timer_init(&rfmgmt->timer, ble_ll_rfmgmt_timer_exp, NULL); + ble_ll_tmr_init(&rfmgmt->timer, ble_ll_rfmgmt_timer_exp, NULL); ble_npl_event_init(&rfmgmt->release_ev, ble_ll_rfmgmt_release_ev, NULL); } @@ -235,7 +235,7 @@ ble_ll_rfmgmt_reset(void) rfmgmt->timer_scheduled = false; rfmgmt->timer_scheduled_at = 0; - os_cputime_timer_stop(&rfmgmt->timer); + ble_ll_tmr_stop(&rfmgmt->timer); ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &rfmgmt->release_ev); @@ -312,7 +312,7 @@ ble_ll_rfmgmt_enable_now(void) ble_ll_rfmgmt_enable(); if (rfmgmt->state == RFMGMT_STATE_ENABLED) { - enabled_at = os_cputime_get32(); + enabled_at = ble_ll_tmr_get(); } else { enabled_at = rfmgmt->enabled_at + rfmgmt->ticks_to_enabled + 1; } diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 987ab463ff..f96aae6ba8 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -23,7 +23,6 @@ #include #include "syscfg/syscfg.h" #include "os/os.h" -#include "os/os_cputime.h" #include "nimble/ble.h" #include "nimble/hci_common.h" #include "nimble/ble_hci_trans.h" @@ -35,6 +34,7 @@ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) #include "controller/ble_ll_scan_aux.h" #endif +#include "controller/ble_ll_tmr.h" #include "controller/ble_ll_hci.h" #include "controller/ble_ll_whitelist.h" #include "controller/ble_ll_resolv.h" @@ -138,7 +138,7 @@ ble_ll_scan_start(struct ble_ll_scan_sm *scansm); static inline uint32_t ble_ll_scan_time_hci_to_ticks(uint16_t value) { - return os_cputime_usecs_to_ticks(value * BLE_HCI_SCAN_ITVL); + return ble_ll_tmr_u2t(value * BLE_HCI_SCAN_ITVL); } /* See Vol 6 Part B Section 4.4.3.2. Active scanning backoff */ @@ -182,7 +182,7 @@ ble_ll_scan_refresh_nrpa(struct ble_ll_scan_sm *scansm) ble_npl_time_t now; now = ble_npl_time_get(); - if (CPUTIME_GEQ(now, scansm->scan_nrpa_timer)) { + if (LL_TMR_GEQ(now, scansm->scan_nrpa_timer)) { /* Generate new NRPA */ ble_ll_rand_data_get(scansm->scan_nrpa, BLE_DEV_ADDR_LEN); scansm->scan_nrpa[5] &= ~0xc0; @@ -781,7 +781,7 @@ ble_ll_scan_start(struct ble_ll_scan_sm *scansm) ble_phy_mode_set(phy_mode, phy_mode); #endif - rc = ble_phy_rx_set_start_time(os_cputime_get32() + + rc = ble_phy_rx_set_start_time(ble_ll_tmr_get() + g_ble_ll_sched_offset_ticks, 0); if (!rc || rc == BLE_PHY_ERR_RX_LATE) { /* If we are late here, it is still OK because we keep scanning. @@ -824,7 +824,7 @@ ble_ll_scan_move_window_to(struct ble_ll_scan_phy *scanp, uint32_t time) */ end_time = scanp->timing.start_time + scanp->timing.window; - while (CPUTIME_GEQ(time, end_time)) { + while (LL_TMR_GEQ(time, end_time)) { scanp->timing.start_time += scanp->timing.interval; scanp->scan_chan = ble_ll_scan_get_next_adv_prim_chan(scanp->scan_chan); end_time = scanp->timing.start_time + scanp->timing.window; @@ -846,8 +846,8 @@ ble_ll_scan_is_inside_window(struct ble_ll_scan_phy *scanp, uint32_t time) return true; } - return CPUTIME_GEQ(time, start_time) && - CPUTIME_LT(time, start_time + scanp->timing.window); + return LL_TMR_GEQ(time, start_time) && + LL_TMR_LT(time, start_time + scanp->timing.window); } /** @@ -862,7 +862,7 @@ ble_ll_scan_sm_stop(int chk_disable) /* Stop the scanning timer */ scansm = &g_ble_ll_scan_sm; - os_cputime_timer_stop(&scansm->scan_timer); + ble_ll_tmr_stop(&scansm->scan_timer); /* Only set state if we are currently in a scan window */ if (chk_disable) { @@ -965,7 +965,7 @@ ble_ll_scan_sm_start(struct ble_ll_scan_sm *scansm) } /* Start scan at 1st window */ - os_cputime_timer_start(&scansm->scan_timer, scanp->timing.start_time); + ble_ll_tmr_start(&scansm->scan_timer, scanp->timing.start_time); return BLE_ERR_SUCCESS; } @@ -1025,7 +1025,7 @@ ble_ll_scan_event_proc(struct ble_npl_event *ev) OS_ENTER_CRITICAL(sr); if (!scansm->scan_enabled) { - os_cputime_timer_stop(&scansm->scan_timer); + ble_ll_tmr_stop(&scansm->scan_timer); ble_ll_rfmgmt_scan_changed(false, 0); ble_ll_rfmgmt_release(); OS_EXIT_CRITICAL(sr); @@ -1040,7 +1040,7 @@ ble_ll_scan_event_proc(struct ble_npl_event *ev) return; } - now = os_cputime_get32(); + now = ble_ll_tmr_get(); inside_window = ble_ll_scan_is_inside_window(scanp, now); @@ -1054,8 +1054,8 @@ ble_ll_scan_event_proc(struct ble_npl_event *ev) * inside window or has next window earlier than current PHY. */ if (!inside_window && - ((inside_window_next || CPUTIME_LEQ(scanp_next->timing.start_time, - scanp->timing.start_time)))) { + ((inside_window_next || LL_TMR_LEQ(scanp_next->timing.start_time, + scanp->timing.start_time)))) { scansm->scanp = scanp_next; scansm->scanp_next = scanp; scanp = scansm->scanp; @@ -1126,7 +1126,7 @@ ble_ll_scan_event_proc(struct ble_npl_event *ev) } OS_EXIT_CRITICAL(sr); - os_cputime_timer_start(&scansm->scan_timer, next_proc_time); + ble_ll_tmr_start(&scansm->scan_timer, next_proc_time); } /** @@ -1675,7 +1675,7 @@ ble_ll_scan_chk_resume(void) return; } - now = os_cputime_get32(); + now = ble_ll_tmr_get(); if (ble_ll_state_get() == BLE_LL_STATE_STANDBY && ble_ll_scan_is_inside_window(scansm->scanp, now)) { /* Turn on the receiver and set state */ @@ -2643,7 +2643,7 @@ ble_ll_scan_common_init(void) #endif /* Initialize scanning timer */ - os_cputime_timer_init(&scansm->scan_timer, ble_ll_scan_timer_cb, scansm); + ble_ll_tmr_init(&scansm->scan_timer, ble_ll_scan_timer_cb, scansm); /* Initialize extended scan timers */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index cd60014d67..94b45e89ea 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -20,7 +20,6 @@ #include #include #include -#include "os/os_cputime.h" #include "ble/xcvr.h" #include "controller/ble_phy.h" #include "controller/ble_ll.h" @@ -30,13 +29,14 @@ #include "controller/ble_ll_scan_aux.h" #include "controller/ble_ll_rfmgmt.h" #include "controller/ble_ll_trace.h" +#include "controller/ble_ll_tmr.h" #include "controller/ble_ll_sync.h" #include "ble_ll_priv.h" #include "ble_ll_conn_priv.h" #define BLE_LL_SCHED_MAX_DELAY_ANY (0x7fffffff) -static struct hal_timer g_ble_ll_sched_timer; +static struct ble_ll_tmr g_ble_ll_sched_timer; uint8_t g_ble_ll_sched_offset_ticks; @@ -102,8 +102,8 @@ ble_ll_sched_check_overlap(struct ble_ll_sched_item *sch1, /* Note: item ranges are defined as [start, end) so items do not overlap * if one item starts at the same time as another ends. */ - return CPUTIME_GT(sch1->end_time, sch2->start_time) && - CPUTIME_GT(sch2->end_time, sch1->start_time); + return LL_TMR_GT(sch1->end_time, sch2->start_time) && + LL_TMR_GT(sch2->end_time, sch1->start_time); } static void @@ -171,7 +171,7 @@ ble_ll_sched_q_head_changed(void) g_ble_ll_sched_q_head_changed = 1; - os_cputime_timer_stop(&g_ble_ll_sched_timer); + ble_ll_tmr_stop(&g_ble_ll_sched_timer); } static inline void @@ -190,7 +190,7 @@ ble_ll_sched_restart(void) ble_ll_rfmgmt_sched_changed(first); if (first) { - os_cputime_timer_start(&g_ble_ll_sched_timer, first->start_time); + ble_ll_tmr_start(&g_ble_ll_sched_timer, first->start_time); } } @@ -219,7 +219,7 @@ ble_ll_sched_insert(struct ble_ll_sched_item *sch, uint32_t max_delay, } TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { - if (CPUTIME_LEQ(sch->end_time, entry->start_time)) { + if (LL_TMR_LEQ(sch->end_time, entry->start_time)) { TAILQ_INSERT_BEFORE(entry, sch, link); sch->enqueued = 1; goto done; @@ -251,7 +251,7 @@ ble_ll_sched_insert(struct ble_ll_sched_item *sch, uint32_t max_delay, */ sch->start_time = entry->end_time + 1; - if ((max_delay == 0) || CPUTIME_GEQ(sch->start_time, + if ((max_delay == 0) || LL_TMR_GEQ(sch->start_time, max_start_time)) { sch->enqueued = 0; goto done; @@ -301,14 +301,14 @@ ble_ll_sched_is_overlap(struct ble_ll_sched_item *s1, int rc; rc = 1; - if (CPUTIME_LT(s1->start_time, s2->start_time)) { + if (LL_TMR_LT(s1->start_time, s2->start_time)) { /* Make sure this event does not overlap current event */ - if (CPUTIME_LEQ(s1->end_time, s2->start_time)) { + if (LL_TMR_LEQ(s1->end_time, s2->start_time)) { rc = 0; } } else { /* Check for overlap */ - if (CPUTIME_GEQ(s1->start_time, s2->end_time)) { + if (LL_TMR_GEQ(s1->start_time, s2->end_time)) { rc = 0; } } @@ -330,7 +330,7 @@ ble_ll_sched_overlaps_current(struct ble_ll_sched_item *sch) if (ble_ll_state_get() == BLE_LL_STATE_CONNECTION) { ce_end_time = ble_ll_conn_get_ce_end_time(); - if (CPUTIME_GT(ce_end_time, sch->start_time)) { + if (LL_TMR_GT(ce_end_time, sch->start_time)) { rc = 1; } } @@ -377,7 +377,7 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_CONN_ROLE_SLAVE: usecs = connsm->slave_cur_window_widening; - sch->start_time -= (os_cputime_usecs_to_ticks(usecs) + 1); + sch->start_time -= (ble_ll_tmr_u2t(usecs) + 1); sch->remainder = 0; break; #endif @@ -389,7 +389,7 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) sch->end_time = connsm->ce_end_time; /* Better be past current time or we just leave */ - if (CPUTIME_LT(sch->start_time, os_cputime_get32())) { + if (LL_TMR_LT(sch->start_time, ble_ll_tmr_get())) { return -1; } @@ -491,8 +491,8 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, * wont be listening. We could do better calculation if we wanted to use * a transmit window of 1 as opposed to 2, but for now we dont care. */ - dur = os_cputime_usecs_to_ticks(g_ble_ll_sched_data.sch_ticks_per_period); - adv_rxend = os_cputime_get32(); + dur = ble_ll_tmr_u2t(g_ble_ll_sched_data.sch_ticks_per_period); + adv_rxend = ble_ll_tmr_get(); if (ble_hdr->rxinfo.channel >= BLE_PHY_NUM_DATA_CHANS) { /* * We received packet on advertising channel which means this is a legacy @@ -584,14 +584,14 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, rc = 0; connsm->tx_win_off = MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET); } else { - os_cputime_timer_stop(&g_ble_ll_sched_timer); + ble_ll_tmr_stop(&g_ble_ll_sched_timer); TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { /* Set these because overlap function needs them to be set */ sch->start_time = earliest_start; sch->end_time = earliest_end; /* We can insert if before entry in list */ - if (CPUTIME_LEQ(sch->end_time, entry->start_time)) { + if (LL_TMR_LEQ(sch->end_time, entry->start_time)) { if ((earliest_start - initial_start) <= itvl_t) { rc = 0; TAILQ_INSERT_BEFORE(entry, sch, link); @@ -623,7 +623,7 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, * the transmit window slightly since the window size is currently * 2 when using a 32768 crystal. */ - dur = os_cputime_ticks_to_usecs(earliest_start - initial_start); + dur = ble_ll_tmr_t2u(earliest_start - initial_start); connsm->tx_win_off = dur / BLE_LL_CONN_TX_OFF_USECS; } } @@ -650,7 +650,7 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, OS_EXIT_CRITICAL(sr); - os_cputime_timer_start(&g_ble_ll_sched_timer, sch->start_time); + ble_ll_tmr_start(&g_ble_ll_sched_timer, sch->start_time); return rc; } @@ -712,7 +712,7 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, * wont be listening. We could do better calculation if we wanted to use * a transmit window of 1 as opposed to 2, but for now we dont care. */ - adv_rxend = os_cputime_get32(); + adv_rxend = ble_ll_tmr_get(); if (ble_hdr->rxinfo.channel >= BLE_PHY_NUM_DATA_CHANS) { /* * We received packet on advertising channel which means this is a legacy @@ -762,8 +762,7 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, rc = ble_ll_sched_insert(sch, max_delay, preempt_none); if (rc == 0) { - connsm->tx_win_off = os_cputime_ticks_to_usecs(sch->start_time - - orig_start_time) / + connsm->tx_win_off = ble_ll_tmr_t2u(sch->start_time - orig_start_time) / BLE_LL_CONN_TX_OFF_USECS; connsm->anchor_point = sch->start_time + g_ble_ll_sched_offset_ticks; @@ -807,7 +806,7 @@ ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm) * usecs to ticks could be off by up to 1 tick. */ sch->start_time = connsm->anchor_point - g_ble_ll_sched_offset_ticks - - os_cputime_usecs_to_ticks(connsm->slave_cur_window_widening) - 1; + ble_ll_tmr_u2t(connsm->slave_cur_window_widening) - 1; sch->end_time = connsm->ce_end_time; sch->remainder = 0; @@ -822,22 +821,6 @@ ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm) return rc; } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -static inline uint32_t -usecs_to_ticks_fast(uint32_t usecs) -{ - uint32_t ticks; - - if (usecs <= 31249) { - ticks = (usecs * 137439) / 4194304; - } else { - ticks = os_cputime_usecs_to_ticks(usecs); - } - - return ticks; -} -#endif - #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) /* * Determines if the schedule item overlaps the currently running schedule @@ -863,7 +846,7 @@ ble_ll_sched_sync_overlaps_current(struct ble_ll_sched_item *sch) return 0; } - return CPUTIME_GT(end_time, sch->start_time); + return LL_TMR_GT(end_time, sch->start_time); } int @@ -873,31 +856,20 @@ ble_ll_sched_sync_reschedule(struct ble_ll_sched_item *sch, int8_t phy_mode) { uint8_t start_time_rem_usecs; - uint8_t window_rem_usecs; - uint32_t window_ticks; uint32_t start_time; uint32_t end_time; uint32_t dur; int rc = 0; os_sr_t sr; - window_ticks = os_cputime_usecs_to_ticks(window_widening); - window_rem_usecs = window_widening - os_cputime_ticks_to_usecs(window_ticks); - - /* adjust for subtraction */ - anchor_point_usecs += 31; - anchor_point--; + start_time = anchor_point; + start_time_rem_usecs = anchor_point_usecs; - start_time = anchor_point - window_ticks; - start_time_rem_usecs = anchor_point_usecs - window_rem_usecs; - if (start_time_rem_usecs >= 31) { - start_time++; - start_time_rem_usecs -= 31; - } + ble_ll_tmr_sub(&start_time, &start_time_rem_usecs, window_widening); dur = ble_ll_pdu_tx_time_get(MYNEWT_VAL(BLE_LL_SCHED_SCAN_SYNC_PDU_LEN), phy_mode); - end_time = start_time + os_cputime_usecs_to_ticks(dur); + end_time = start_time + ble_ll_tmr_u2t(dur); start_time -= g_ble_ll_sched_offset_ticks; @@ -907,7 +879,7 @@ ble_ll_sched_sync_reschedule(struct ble_ll_sched_item *sch, sch->end_time = end_time; /* Better be past current time or we just leave */ - if (CPUTIME_LEQ(sch->start_time, os_cputime_get32())) { + if (LL_TMR_LEQ(sch->start_time, ble_ll_tmr_get())) { return -1; } @@ -932,28 +904,21 @@ ble_ll_sched_sync(struct ble_ll_sched_item *sch, uint32_t beg_cputime, uint32_t rem_usecs, uint32_t offset, int8_t phy_mode) { - uint32_t start_time_rem_usecs; - uint32_t off_rem_usecs; + uint8_t start_time_rem_usecs; uint32_t start_time; - uint32_t off_ticks; uint32_t end_time; uint32_t dur; os_sr_t sr; int rc = 0; - off_ticks = usecs_to_ticks_fast(offset); - off_rem_usecs = offset - os_cputime_ticks_to_usecs(off_ticks); + start_time = beg_cputime; + start_time_rem_usecs = rem_usecs; - start_time = beg_cputime + off_ticks; - start_time_rem_usecs = rem_usecs + off_rem_usecs; - if (start_time_rem_usecs >= 31) { - start_time++; - start_time_rem_usecs -= 31; - } + ble_ll_tmr_add(&start_time, &start_time_rem_usecs, offset); dur = ble_ll_pdu_tx_time_get(MYNEWT_VAL(BLE_LL_SCHED_SCAN_SYNC_PDU_LEN), phy_mode); - end_time = start_time + usecs_to_ticks_fast(dur); + end_time = start_time + ble_ll_tmr_u2t(dur); start_time -= g_ble_ll_sched_offset_ticks; @@ -1042,7 +1007,7 @@ ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch, if (rc == 0) { next = TAILQ_NEXT(sch, link); if (next) { - if (CPUTIME_LT(next->start_time, max_end_time)) { + if (LL_TMR_LT(next->start_time, max_end_time)) { max_end_time = next->start_time; } rand_ticks = max_end_time - sch->end_time; @@ -1198,7 +1163,7 @@ ble_ll_sched_execute_item(struct ble_ll_sched_item *sch) lls = ble_ll_state_get(); - ble_ll_trace_u32x3(BLE_LL_TRACE_ID_SCHED, lls, os_cputime_get32(), + ble_ll_trace_u32x3(BLE_LL_TRACE_ID_SCHED, lls, ble_ll_tmr_get(), sch->start_time); if (lls == BLE_LL_STATE_STANDBY) { @@ -1282,7 +1247,7 @@ ble_ll_sched_run(void *arg) int32_t dt; /* Make sure we have passed the start time of the first event */ - dt = (int32_t)(os_cputime_get32() - sch->start_time); + dt = (int32_t)(ble_ll_tmr_get() - sch->start_time); if (dt > g_ble_ll_sched_max_late) { g_ble_ll_sched_max_late = dt; } @@ -1343,12 +1308,12 @@ ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time, int rc; offset_us += pdu_time_rem; - offset_ticks = usecs_to_ticks_fast(offset_us); + offset_ticks = ble_ll_tmr_u2t(offset_us); sch->start_time = pdu_time + offset_ticks - g_ble_ll_sched_offset_ticks; - sch->remainder = offset_us - os_cputime_ticks_to_usecs(offset_ticks); + sch->remainder = offset_us - ble_ll_tmr_t2u(offset_ticks); /* TODO: make some sane slot reservation */ - sch->end_time = sch->start_time + usecs_to_ticks_fast(5000); + sch->end_time = sch->start_time + ble_ll_tmr_u2t(5000); OS_ENTER_CRITICAL(sr); @@ -1389,7 +1354,7 @@ int ble_ll_sched_dtm(struct ble_ll_sched_item *sch) void ble_ll_sched_stop(void) { - os_cputime_timer_stop(&g_ble_ll_sched_timer); + ble_ll_tmr_stop(&g_ble_ll_sched_timer); } /** @@ -1417,16 +1382,15 @@ ble_ll_sched_init(void) * This is the offset from the start of the scheduled item until the actual * tx/rx should occur, in ticks. We also "round up" to the nearest tick. */ - g_ble_ll_sched_offset_ticks = - (uint8_t) os_cputime_usecs_to_ticks(XCVR_TX_SCHED_DELAY_USECS + 30); + g_ble_ll_sched_offset_ticks = ble_ll_tmr_u2t_up(XCVR_TX_SCHED_DELAY_USECS); /* Initialize cputimer for the scheduler */ - os_cputime_timer_init(&g_ble_ll_sched_timer, ble_ll_sched_run, NULL); + ble_ll_tmr_init(&g_ble_ll_sched_timer, ble_ll_sched_run, NULL); #if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) memset(&g_ble_ll_sched_data, 0, sizeof(struct ble_ll_sched_obj)); g_ble_ll_sched_data.sch_ticks_per_period = - os_cputime_usecs_to_ticks(MYNEWT_VAL(BLE_LL_USECS_PER_PERIOD)); + ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_USECS_PER_PERIOD)); g_ble_ll_sched_data.sch_ticks_per_epoch = BLE_LL_SCHED_PERIODS * g_ble_ll_sched_data.sch_ticks_per_period; #endif diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 7b6208ce11..31e99840df 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -32,6 +32,7 @@ #include "controller/ble_ll_scan.h" #include "controller/ble_ll_resolv.h" #include "controller/ble_ll_rfmgmt.h" +#include "controller/ble_ll_tmr.h" #include "nimble/ble.h" #include "nimble/hci_common.h" @@ -837,7 +838,7 @@ ble_ll_sync_get_event_end_time(void) if (g_ble_ll_sync_sm_current) { end_time = g_ble_ll_sync_sm_current->sch.end_time; } else { - end_time = os_cputime_get32(); + end_time = ble_ll_tmr_get(); } return end_time; } @@ -1138,14 +1139,12 @@ ble_ll_sync_next_event(struct ble_ll_sync_sm *sm, uint32_t cur_ww_adjust) { uint32_t cur_ww; uint32_t max_ww; - uint32_t ticks; uint32_t itvl; - uint8_t usecs; uint16_t skip = sm->skip; /* don't skip if are establishing sync or we missed last event */ if (skip && ((sm->flags & BLE_LL_SYNC_SM_FLAG_ESTABLISHING) || - CPUTIME_LT(sm->last_anchor_point, sm->anchor_point))) { + LL_TMR_LT(sm->last_anchor_point, sm->anchor_point))) { skip = 0; } @@ -1153,19 +1152,12 @@ ble_ll_sync_next_event(struct ble_ll_sync_sm *sm, uint32_t cur_ww_adjust) * interval if not skipping */ if (skip == 0) { - ticks = sm->itvl_ticks; - usecs = sm->itvl_usecs; + sm->anchor_point += sm->itvl_ticks; + ble_ll_tmr_add_u(&sm->anchor_point, &sm->anchor_point_usecs, + sm->itvl_usecs); } else { itvl = sm->itvl * BLE_LL_SYNC_ITVL_USECS * (1 + skip); - ticks = os_cputime_usecs_to_ticks(itvl); - usecs = itvl - os_cputime_ticks_to_usecs(ticks); - } - - sm->anchor_point += ticks; - sm->anchor_point_usecs += usecs; - if (sm->anchor_point_usecs >= 31) { - sm->anchor_point++; - sm->anchor_point_usecs -= 31; + ble_ll_tmr_add(&sm->anchor_point, &sm->anchor_point_usecs, itvl); } /* Set event counter to the next event */ @@ -1212,7 +1204,7 @@ ble_ll_sync_next_event(struct ble_ll_sync_sm *sm, uint32_t cur_ww_adjust) * BLE_LL_SYNC_ESTABLISH_CNT events before failing regardless of timeout */ if (!(sm->flags & BLE_LL_SYNC_SM_FLAG_ESTABLISHING)) { - if (CPUTIME_GT(sm->anchor_point - os_cputime_usecs_to_ticks(cur_ww), + if (LL_TMR_GT(sm->anchor_point - ble_ll_tmr_u2t(cur_ww), sm->last_anchor_point + sm->timeout )) { return -1; } @@ -1378,13 +1370,7 @@ ble_ll_sync_info_event(struct ble_ll_scan_addr_data *addrd, /* precalculate interval ticks and usecs */ usecs = sm->itvl * BLE_LL_SYNC_ITVL_USECS; - sm->itvl_ticks = os_cputime_usecs_to_ticks(usecs); - sm->itvl_usecs = (uint8_t)(usecs - - os_cputime_ticks_to_usecs(sm->itvl_ticks)); - if (sm->itvl_usecs == 31) { - sm->itvl_usecs = 0; - sm->itvl_ticks++; - } + sm->itvl_ticks = ble_ll_tmr_u2t_r(usecs, &sm->itvl_usecs); /* Channels Mask (37 bits) */ sm->chanmap[0] = syncinfo[4]; @@ -1417,7 +1403,7 @@ ble_ll_sync_info_event(struct ble_ll_scan_addr_data *addrd, } /* from now on we only need timeout in ticks */ - sm->timeout = os_cputime_usecs_to_ticks(sm->timeout); + sm->timeout = ble_ll_tmr_u2t(sm->timeout); sm->phy_mode = rxhdr->rxinfo.phy_mode; sm->window_widening = BLE_LL_JITTER_USECS; @@ -1906,7 +1892,7 @@ ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, } /* set params from transfer */ - sm->timeout = os_cputime_usecs_to_ticks(sync_timeout); + sm->timeout = ble_ll_tmr_u2t(sync_timeout); sm->skip = max_skip; sm->sync_pending_cnt = BLE_LL_SYNC_ESTABLISH_CNT; sm->transfer_id = get_le16(sync_ind); /* first two bytes */ @@ -1936,13 +1922,7 @@ ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, sm->itvl = itvl; /* precalculate interval ticks and usecs */ - sm->itvl_ticks = os_cputime_usecs_to_ticks(itvl_usecs); - sm->itvl_usecs = (uint8_t)(itvl_usecs - - os_cputime_ticks_to_usecs(sm->itvl_ticks)); - if (sm->itvl_usecs == 31) { - sm->itvl_usecs = 0; - sm->itvl_ticks++; - } + sm->itvl_ticks = ble_ll_tmr_u2t_r(itvl_usecs, &sm->itvl_usecs); /* Channels Mask (37 bits) */ sm->chanmap[0] = syncinfo[4]; @@ -1997,8 +1977,8 @@ ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, sync_anchor, sca); /* spin until we get anchor in future */ - future = os_cputime_get32() + g_ble_ll_sched_offset_ticks; - while (CPUTIME_LT(sm->anchor_point, future)) { + future = ble_ll_tmr_get() + g_ble_ll_sched_offset_ticks; + while (LL_TMR_LT(sm->anchor_point, future)) { if (ble_ll_sync_next_event(sm, ww_adjust) < 0) { /* release SM if this failed */ ble_ll_sync_transfer_received(sm, BLE_ERR_CONN_ESTABLISHMENT); @@ -2040,11 +2020,11 @@ ble_ll_sync_put_syncinfo(struct ble_ll_sync_sm *syncsm, conn_cnt = connsm->event_cntr; /* get anchor for conn event that is before periodic_adv_event_start_time */ - while (CPUTIME_GT(anchor, syncsm->anchor_point)) { + while (LL_TMR_GT(anchor, syncsm->anchor_point)) { ble_ll_conn_get_anchor(connsm, --conn_cnt, &anchor, &anchor_usecs); } - offset = os_cputime_ticks_to_usecs(syncsm->anchor_point - anchor); + offset = ble_ll_tmr_t2u(syncsm->anchor_point - anchor); offset -= anchor_usecs; offset += syncsm->anchor_point_usecs; diff --git a/nimble/controller/src/ble_ll_utils.c b/nimble/controller/src/ble_ll_utils.c index ccdf37759c..e2fe50c2b5 100644 --- a/nimble/controller/src/ble_ll_utils.c +++ b/nimble/controller/src/ble_ll_utils.c @@ -21,6 +21,7 @@ #include #include "nimble/ble.h" #include "controller/ble_ll.h" +#include "controller/ble_ll_tmr.h" #include "controller/ble_ll_utils.h" /* 37 bits require 5 bytes */ @@ -291,7 +292,7 @@ ble_ll_utils_calc_window_widening(uint32_t anchor_point, time_since_last_anchor = (int32_t)(anchor_point - last_anchor_point); if (time_since_last_anchor > 0) { - delta_msec = os_cputime_ticks_to_usecs(time_since_last_anchor) / 1000; + delta_msec = ble_ll_tmr_t2u(time_since_last_anchor) / 1000; total_sca_ppm = g_ble_sca_ppm_tbl[master_sca] + MYNEWT_VAL(BLE_LL_SCA); window_widening = (total_sca_ppm * delta_msec) / 1000; } diff --git a/nimble/drivers/nrf52/src/ble_phy.c b/nimble/drivers/nrf52/src/ble_phy.c index 3c7b62690b..7a12bb5016 100644 --- a/nimble/drivers/nrf52/src/ble_phy.c +++ b/nimble/drivers/nrf52/src/ble_phy.c @@ -22,6 +22,8 @@ #include #include "syscfg/syscfg.h" #include "os/os.h" +/* Keep os_cputime explicitly to enable build on non-Mynewt platforms */ +#include "os/os_cputime.h" #include "ble/xcvr.h" #include "nimble/ble.h" #include "nimble/nimble_opt.h" From 7cac65c0ecd55179fcd70a5305c7ac1f3e79968f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 28 Jan 2022 14:41:18 +0100 Subject: [PATCH 0248/1333] nimble/ll: Add support for non-32768 os_cputime freq This removes restrictions to force 32768Hz clock for os_cputime and uses explicit convertions from usecs to ticks instead of precalculated values. --- nimble/controller/include/controller/ble_ll.h | 4 ---- .../include/controller/ble_ll_sched.h | 1 - .../include/controller/ble_ll_tmr.h | 12 +++++++++- nimble/controller/src/ble_ll_conn.c | 8 ++++--- nimble/controller/src/ble_ll_sched.c | 23 ++++++++++--------- nimble/controller/syscfg.yml | 1 - 6 files changed, 28 insertions(+), 21 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index d148fbe9dc..c51d41014b 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -37,10 +37,6 @@ extern "C" { #endif -#if MYNEWT_VAL(OS_CPUTIME_FREQ) != 32768 -#error 32.768kHz clock required -#endif - #if defined(MYNEWT) && MYNEWT_VAL(BLE_LL_HCI_VS_EVENT_ON_ASSERT) #ifdef NDEBUG #define BLE_LL_ASSERT(cond) (void(0)) diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index 45e148cbd6..4ce687e35c 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -26,7 +26,6 @@ extern "C" { /* Time per BLE scheduler slot */ #define BLE_LL_SCHED_USECS_PER_SLOT (1250) -#define BLE_LL_SCHED_TICKS_PER_SLOT (41) /* 1 tick = 30.517 usecs */ /* * Worst case time needed for scheduled advertising item. This is the longest diff --git a/nimble/controller/include/controller/ble_ll_tmr.h b/nimble/controller/include/controller/ble_ll_tmr.h index 9dd6ab477c..2d79427b63 100644 --- a/nimble/controller/include/controller/ble_ll_tmr.h +++ b/nimble/controller/include/controller/ble_ll_tmr.h @@ -27,7 +27,8 @@ extern "C" { #endif -#define USECS_PER_TICK (31) +#define USECS_PER_TICK ((1000000 + MYNEWT_VAL(OS_CPUTIME_FREQ) - 1) / \ + MYNEWT_VAL(OS_CPUTIME_FREQ)) #define LL_TMR_LT(_t1, _t2) ((int32_t)((_t1) - (_t2)) < 0) #define LL_TMR_GT(_t1, _t2) ((int32_t)((_t1) - (_t2)) > 0) @@ -49,15 +50,24 @@ ble_ll_tmr_get(void) static inline uint32_t ble_ll_tmr_t2u(uint32_t ticks) { +#if MYNEWT_VAL(OS_CPUTIME_FREQ) == 31250 + return ticks * 32; +#endif + return os_cputime_ticks_to_usecs(ticks); } static inline uint32_t ble_ll_tmr_u2t(uint32_t usecs) { +#if MYNEWT_VAL(OS_CPUTIME_FREQ) == 31250 + return usecs / 32; +#endif +#if MYNEWT_VAL(OS_CPUTIME_FREQ) == 32768 if (usecs <= 31249) { return (usecs * 137439) / 4194304; } +#endif return os_cputime_usecs_to_ticks(usecs); } diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index d3579ed2d9..7e3baab1a6 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2222,7 +2222,8 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) #if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) itvl = g_ble_ll_sched_data.sch_ticks_per_period; #else - itvl = MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * BLE_LL_SCHED_TICKS_PER_SLOT; + itvl = ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * + BLE_LL_SCHED_USECS_PER_SLOT); #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { @@ -2339,8 +2340,9 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) #else connsm->ce_end_time = connsm->anchor_point + - (MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * BLE_LL_SCHED_TICKS_PER_SLOT) - + ble_ll_tmr_u2t(connsm->slave_cur_tx_win_usecs) + 1; + ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * + BLE_LL_SCHED_USECS_PER_SLOT + + connsm->slave_cur_tx_win_usecs) + 1; #endif connsm->slave_cur_window_widening = BLE_LL_JITTER_USECS; diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 94b45e89ea..0ba6a89b43 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -718,7 +718,7 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, * We received packet on advertising channel which means this is a legacy * PDU on 1 Mbps - we do as described above. */ - earliest_start = adv_rxend + 57; + earliest_start = adv_rxend + ble_ll_tmr_u2t(1752); } else { /* * The calculations are similar as above. @@ -731,27 +731,28 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, * */ if (ble_hdr->rxinfo.phy == BLE_PHY_1M) { - // 150 + 352 + 2500 = 3002us = 98.37 ticks - earliest_start = adv_rxend + 98; + /* 150 + 352 + 2500 = 3002us */ + earliest_start = adv_rxend + ble_ll_tmr_u2t(3002); } else if (ble_hdr->rxinfo.phy == BLE_PHY_2M) { - // 150 + 180 + 2500 = 2830us = 92.73 ticks - earliest_start = adv_rxend + 93; + /* 150 + 180 + 2500 = 2830us */ + earliest_start = adv_rxend + ble_ll_tmr_u2t(2830); } else if (ble_hdr->rxinfo.phy == BLE_PHY_CODED) { - // 150 + 2896 + 3750 = 6796us = 222.69 ticks - earliest_start = adv_rxend + 223; + /* 150 + 2896 + 3750 = 6796us */ + earliest_start = adv_rxend + ble_ll_tmr_u2t(6796); } else { BLE_LL_ASSERT(0); } } sch->start_time = earliest_start - g_ble_ll_sched_offset_ticks; - sch->end_time = earliest_start + MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * - BLE_LL_SCHED_TICKS_PER_SLOT; + sch->end_time = earliest_start + + ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * + BLE_LL_SCHED_USECS_PER_SLOT); orig_start_time = sch->start_time; - min_win_offset = MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET) * - BLE_LL_SCHED_TICKS_PER_SLOT; + min_win_offset = ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET) * + BLE_LL_SCHED_USECS_PER_SLOT); sch->start_time += min_win_offset; sch->end_time += min_win_offset; diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index bb4631195f..9f17350e44 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -516,7 +516,6 @@ syscfg.vals.!BLE_HOST: BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 syscfg.restrictions: - - OS_CPUTIME_FREQ == 32768 - BLE_LL_PUBLIC_DEV_ADDR <= 0xffffffffffff - BLE_LL_PA == 0 || BLE_LL_PA_GPIO >= 0 - BLE_LL_LNA == 0 || BLE_LL_LNA_GPIO >= 0 From 1f2acea2e92d3e49bc5b27a4f785741ffaf03947 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 4 Feb 2022 15:41:41 +0100 Subject: [PATCH 0249/1333] nimble/ll: Fix not using configured TX power for advertising If TX power was tuned with HCI VS command, advertising was using default value anyway. --- nimble/controller/src/ble_ll_adv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index caa817ee1a..61f305947f 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1806,7 +1806,7 @@ ble_ll_adv_set_adv_params(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } - advsm->adv_txpwr = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); + advsm->adv_txpwr = g_ble_ll_tx_power; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) if (cmd->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { @@ -2783,7 +2783,7 @@ ble_ll_adv_read_txpwr(uint8_t *rspbuf, uint8_t *rsplen) { struct ble_hci_le_rd_adv_chan_txpwr_rp *rsp = (void *) rspbuf; - rsp->power_level = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); + rsp->power_level = g_ble_ll_tx_power; *rsplen = sizeof(*rsp); return BLE_ERR_SUCCESS; @@ -3416,7 +3416,7 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, if (cmd->tx_power == 127) { /* no preference */ - advsm->adv_txpwr = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); + advsm->adv_txpwr = g_ble_ll_tx_power; } else { advsm->adv_txpwr = ble_phy_txpower_round(cmd->tx_power); } From 9fd5540802b01e102dd822f03d97c365766040a9 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Thu, 3 Feb 2022 15:32:03 +0530 Subject: [PATCH 0250/1333] Add checks in defination of macro MIN / MAX, if they already not present --- nimble/host/mesh/include/mesh/glue.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index 58e3e2d8de..36b82cf5dd 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -308,8 +308,14 @@ void net_buf_reserve(struct os_mbuf *om, size_t reserve); #define BT_GATT_CCC_NOTIFY BLE_GATT_CHR_PROP_NOTIFY +#ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + /** Description of different data types that can be encoded into * advertising data. Used to form arrays that are passed to the * bt_le_adv_start() function. From aaab1d64e692d470b977daf6e7b826bff1b865b5 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 4 Feb 2022 17:20:44 +0100 Subject: [PATCH 0251/1333] nimble/ll: Fix build --- nimble/controller/src/ble_ll_sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 0ba6a89b43..8f9a2d5c28 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -524,7 +524,7 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, } } earliest_start += MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET) * - BLE_LL_SCHED_TICKS_PER_SLOT; + BLE_LL_SCHED_USECS_PER_SLOT; itvl_t = connsm->conn_itvl_ticks; /* We have to find a place for this schedule */ From 3596504a10ff6b1a8c65c6e22bb6a34bbb3cb581 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 5 Feb 2022 12:26:39 +0100 Subject: [PATCH 0252/1333] nimble/ll: Fix sca update handling We should use new sca in connsm... --- nimble/controller/src/ble_ll_ctrl.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 78cf0756d6..919f4a571f 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1110,7 +1110,12 @@ static uint8_t ble_ll_ctrl_rx_sca_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t *rsp) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + connsm->master_sca = dptr[0]; + } + ble_ll_ctrl_sca_req_rsp_make(connsm, rsp); + return BLE_LL_CTRL_CLOCK_ACCURACY_RSP; } @@ -1128,8 +1133,14 @@ ble_ll_ctrl_rx_sca_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr) if (connsm->cur_ctrl_proc != BLE_LL_CTRL_PROC_SCA_UPDATE) { return BLE_LL_CTRL_UNKNOWN_RSP; } + + if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + connsm->master_sca = dptr[0]; + } + ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_SCA_UPDATE); ble_ll_hci_ev_sca_update(connsm, BLE_ERR_SUCCESS, dptr[0]); + return BLE_ERR_MAX; } From 9ebd589701071a1501e2b1ba3f1fad807dfa421c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 7 Feb 2022 13:12:54 +0100 Subject: [PATCH 0253/1333] nimble/ll: Fix sca hci command parsing --- nimble/controller/src/ble_ll_conn_hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 2e50713e84..bee9a5621b 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1619,7 +1619,7 @@ ble_ll_conn_req_peer_sca(const uint8_t *cmdbuf, uint8_t len, const struct ble_hci_le_request_peer_sca_cp *params = (const void *)cmdbuf; struct ble_ll_conn_sm *connsm; - connsm = ble_ll_conn_find_active_conn(params->conn_handle); + connsm = ble_ll_conn_find_active_conn(le16toh(params->conn_handle)); if (!connsm) { return BLE_ERR_UNK_CONN_ID; } From 0d0be633dcdd2b9b09da3657a77c6861cd62e77c Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Thu, 3 Feb 2022 12:48:20 +0800 Subject: [PATCH 0254/1333] fix error: variable 'len' is used uninitialized when NDEBUG is defined Signed-off-by: Xiang Xiao --- nimble/transport/socket/src/ble_hci_socket.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/transport/socket/src/ble_hci_socket.c b/nimble/transport/socket/src/ble_hci_socket.c index b444a24032..8a7338980f 100644 --- a/nimble/transport/socket/src/ble_hci_socket.c +++ b/nimble/transport/socket/src/ble_hci_socket.c @@ -357,6 +357,7 @@ ble_hci_sock_cmdevt_tx(uint8_t *hci_ev, uint8_t h4_type) STATS_INC(hci_sock_stats, oevt); } else { assert(0); + return BLE_ERR_UNKNOWN_HCI_CMD; } iov[1].iov_len = len; From 6cf644a191af5f100abc541da40c8952cea6e715 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 2 Feb 2022 15:56:49 +0100 Subject: [PATCH 0255/1333] nimble/phy/nrf53: Refactor DPPI macros This replaces bunch of DPPI macros with simple ones that take channel number as parameter. Since we have one event published per channel, it makes it easy to read code since you can easily see which task is triggered by which event. --- nimble/drivers/nrf5340/src/ble_phy.c | 190 ++++++++++----------------- 1 file changed, 67 insertions(+), 123 deletions(-) diff --git a/nimble/drivers/nrf5340/src/ble_phy.c b/nimble/drivers/nrf5340/src/ble_phy.c index 2b21afb438..550aea292c 100644 --- a/nimble/drivers/nrf5340/src/ble_phy.c +++ b/nimble/drivers/nrf5340/src/ble_phy.c @@ -34,6 +34,11 @@ #include #include +#define DPPI_CH_PUB(_ch) (((DPPI_CH_ ## _ch) & 0xff) | (1 << 31)) +#define DPPI_CH_SUB(_ch) (((DPPI_CH_ ## _ch) & 0xff) | (1 << 31)) +#define DPPI_CH_UNSUB(_ch) (((DPPI_CH_ ## _ch) & 0xff) | (0 << 31)) +#define DPPI_CH_MASK(_ch) (1 << (DPPI_CH_ ## _ch)) + /* * NOTE: This code uses 0-5 DPPI channels so care should be taken when using * DPPI somewhere else. @@ -49,74 +54,13 @@ #define DPPI_CH_RADIO_EVENTS_BCMATCH 3 #define DPPI_CH_RADIO_EVENTS_ADDRESS 4 #define DPPI_CH_RTC0_EVENTS_COMPARE_0 5 - -#define DPPI_CH_ENABLE_ALL (DPPIC_CHEN_CH0_Msk | DPPIC_CHEN_CH1_Msk | DPPIC_CHEN_CH2_Msk | \ - DPPIC_CHEN_CH3_Msk | DPPIC_CHEN_CH4_Msk | DPPIC_CHEN_CH5_Msk) - -#define DPPI_PUBLISH_TIMER0_EVENTS_COMPARE_0 ((DPPI_CH_TIMER0_EVENTS_COMPARE_0 << TIMER_PUBLISH_COMPARE_CHIDX_Pos) | \ - (TIMER_PUBLISH_COMPARE_EN_Enabled << TIMER_PUBLISH_COMPARE_EN_Pos)) -#define DPPI_PUBLISH_TIMER0_EVENTS_COMPARE_3 ((DPPI_CH_TIMER0_EVENTS_COMPARE_3 << TIMER_PUBLISH_COMPARE_CHIDX_Pos) | \ - (TIMER_PUBLISH_COMPARE_EN_Enabled << TIMER_PUBLISH_COMPARE_EN_Pos)) -#define DPPI_PUBLISH_RADIO_EVENTS_END ((DPPI_CH_RADIO_EVENTS_END << RADIO_PUBLISH_END_CHIDX_Pos) | \ - (RADIO_PUBLISH_END_EN_Enabled << RADIO_PUBLISH_END_EN_Pos)) -#define DPPI_PUBLISH_RADIO_EVENTS_BCMATCH ((DPPI_CH_RADIO_EVENTS_BCMATCH << RADIO_PUBLISH_BCMATCH_CHIDX_Pos) | \ - (RADIO_PUBLISH_BCMATCH_EN_Enabled << RADIO_PUBLISH_BCMATCH_EN_Pos)) -#define DPPI_PUBLISH_RADIO_EVENTS_ADDRESS ((DPPI_CH_RADIO_EVENTS_ADDRESS << RADIO_PUBLISH_ADDRESS_CHIDX_Pos) | \ - (RADIO_PUBLISH_ADDRESS_EN_Enabled << RADIO_PUBLISH_ADDRESS_EN_Pos)) -#define DPPI_PUBLISH_RTC0_EVENTS_COMPARE_0 ((DPPI_CH_RTC0_EVENTS_COMPARE_0 << RTC_PUBLISH_COMPARE_CHIDX_Pos) | \ - (RTC_PUBLISH_COMPARE_EN_Enabled << RTC_PUBLISH_COMPARE_EN_Pos)) - -#define DPPI_SUBSCRIBE_TIMER0_TASKS_START(_enable) ((DPPI_CH_RTC0_EVENTS_COMPARE_0 << TIMER_SUBSCRIBE_START_CHIDX_Pos) | \ - ((_enable) << TIMER_SUBSCRIBE_START_EN_Pos)) -#define DPPI_SUBSCRIBE_TIMER0_TASKS_CAPTURE1(_enable) ((DPPI_CH_RADIO_EVENTS_ADDRESS << TIMER_SUBSCRIBE_CAPTURE_CHIDX_Pos) | \ - ((_enable) << TIMER_SUBSCRIBE_CAPTURE_EN_Pos)) -#define DPPI_SUBSCRIBE_TIMER0_TASKS_CAPTURE2(_enable) ((DPPI_CH_RADIO_EVENTS_END << TIMER_SUBSCRIBE_CAPTURE_CHIDX_Pos) | \ - ((_enable) << TIMER_SUBSCRIBE_CAPTURE_EN_Pos)) -#define DPPI_SUBSCRIBE_TIMER0_TASKS_CAPTURE3(_enable) ((DPPI_CH_RADIO_EVENTS_ADDRESS << TIMER_SUBSCRIBE_CAPTURE_CHIDX_Pos) | \ - ((_enable) << TIMER_SUBSCRIBE_CAPTURE_EN_Pos)) -#define DPPI_SUBSCRIBE_RADIO_TASKS_DISABLE(_enable) ((DPPI_CH_TIMER0_EVENTS_COMPARE_3 << RADIO_SUBSCRIBE_DISABLE_CHIDX_Pos) | \ - ((_enable) << RADIO_SUBSCRIBE_DISABLE_EN_Pos)) -#define DPPI_SUBSCRIBE_RADIO_TASKS_RXEN(_enable) ((DPPI_CH_TIMER0_EVENTS_COMPARE_0 << RADIO_SUBSCRIBE_RXEN_CHIDX_Pos) | \ - ((_enable) << RADIO_SUBSCRIBE_RXEN_EN_Pos)) -#define DPPI_SUBSCRIBE_RADIO_TASKS_TXEN(_enable) ((DPPI_CH_TIMER0_EVENTS_COMPARE_0 << RADIO_SUBSCRIBE_TXEN_CHIDX_Pos) | \ - ((_enable) << RADIO_SUBSCRIBE_TXEN_EN_Pos)) -#define DPPI_SUBSCRIBE_AAR_TASKS_START(_enable) ((DPPI_CH_RADIO_EVENTS_BCMATCH << AAR_SUBSCRIBE_START_CHIDX_Pos) | \ - ((_enable) << AAR_SUBSCRIBE_START_EN_Pos)) -#define DPPI_SUBSCRIBE_CCM_TASKS_CRYPT(_enable) ((DPPI_CH_RADIO_EVENTS_ADDRESS << CCM_SUBSCRIBE_CRYPT_CHIDX_Pos) | \ - ((_enable) << CCM_SUBSCRIBE_CRYPT_EN_Pos)) - /* used for GPIO DBG */ #define DPPI_CH_RADIO_EVENTS_READY 6 #define DPPI_CH_RADIO_EVENTS_RXREADY 7 #define DPPI_CH_RADIO_EVENTS_DISABLED 8 -#define DPPI_CH_ENABLE_RADIO_EVENTS_READY DPPIC_CHEN_CH6_Msk -#define DPPI_CH_ENABLE_RADIO_EVENTS_RXREADY DPPIC_CHEN_CH7_Msk -#define DPPI_CH_ENABLE_RADIO_EVENTS_DISABLED DPPIC_CHEN_CH8_Msk - -#define DPPI_PUBLISH_RADIO_EVENTS_READY ((DPPI_CH_RADIO_EVENTS_READY << RADIO_PUBLISH_READY_CHIDX_Pos) | \ - (RADIO_PUBLISH_READY_EN_Enabled << RADIO_PUBLISH_READY_EN_Pos)) -#define DPPI_PUBLISH_RADIO_EVENTS_RXREADY ((DPPI_CH_RADIO_EVENTS_RXREADY << RADIO_PUBLISH_RXREADY_CHIDX_Pos) | \ - (RADIO_PUBLISH_RXREADY_EN_Enabled << RADIO_PUBLISH_RXREADY_EN_Pos)) -#define DPPI_PUBLISH_RADIO_EVENTS_DISABLED ((DPPI_CH_RADIO_EVENTS_DISABLED << RADIO_PUBLISH_DISABLED_CHIDX_Pos) | \ - (RADIO_PUBLISH_DISABLED_EN_Enabled << RADIO_PUBLISH_DISABLED_EN_Pos)) - -#define DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_TXRXEN ((DPPI_CH_TIMER0_EVENTS_COMPARE_0 << GPIOTE_SUBSCRIBE_SET_CHIDX_Pos) | \ - (1 << GPIOTE_SUBSCRIBE_SET_EN_Pos)) -#define DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_ADDRESS ((DPPI_CH_RADIO_EVENTS_ADDRESS << GPIOTE_SUBSCRIBE_SET_CHIDX_Pos) | \ - (1 << GPIOTE_SUBSCRIBE_SET_EN_Pos)) -#define DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_END ((DPPI_CH_RADIO_EVENTS_END << GPIOTE_SUBSCRIBE_CLR_CHIDX_Pos) | \ - (1 << GPIOTE_SUBSCRIBE_CLR_EN_Pos)) -#define DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_READY ((DPPI_CH_RADIO_EVENTS_READY << GPIOTE_SUBSCRIBE_CLR_CHIDX_Pos) | \ - (1 << GPIOTE_SUBSCRIBE_CLR_EN_Pos)) -#define DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_RXREADY ((DPPI_CH_RADIO_EVENTS_RXREADY << GPIOTE_SUBSCRIBE_SET_CHIDX_Pos) | \ - (1 << GPIOTE_SUBSCRIBE_SET_EN_Pos)) -#define DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_DISABLED ((DPPI_CH_RADIO_EVENTS_DISABLED << GPIOTE_SUBSCRIBE_CLR_CHIDX_Pos) | \ - (1 << GPIOTE_SUBSCRIBE_CLR_EN_Pos)) -#define DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_CAPTURE3 ((DPPI_CH_TIMER0_EVENTS_COMPARE_3 << GPIOTE_SUBSCRIBE_CLR_CHIDX_Pos) | \ - (1 << GPIOTE_SUBSCRIBE_CLR_EN_Pos)) -#define DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_ADDRESS ((DPPI_CH_RADIO_EVENTS_ADDRESS << GPIOTE_SUBSCRIBE_CLR_CHIDX_Pos) | \ - (1 << GPIOTE_SUBSCRIBE_CLR_EN_Pos)) +#define DPPI_CH_ENABLE_ALL (DPPIC_CHEN_CH0_Msk | DPPIC_CHEN_CH1_Msk | DPPIC_CHEN_CH2_Msk | \ + DPPIC_CHEN_CH3_Msk | DPPIC_CHEN_CH4_Msk | DPPIC_CHEN_CH5_Msk) extern uint8_t g_nrf_num_irks; extern uint32_t g_nrf_irk_list[]; @@ -562,7 +506,7 @@ ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx) NRF_RTC0_NS->EVTENSET = RTC_EVTENSET_COMPARE0_Msk; /* Enable PPI */ - NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_SUBSCRIBE_TIMER0_TASKS_START(1); + NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_CH_SUB(RTC0_EVENTS_COMPARE_0); /* Store the cputime at which we set the RTC */ g_ble_phy_data.phy_start_cputime = cputime; @@ -598,7 +542,7 @@ ble_phy_set_start_now(void) NRF_RTC0_NS->EVTENSET = RTC_EVTENSET_COMPARE0_Msk; /* Enable PPI */ - NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_SUBSCRIBE_TIMER0_TASKS_START(1); + NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_CH_SUB(RTC0_EVENTS_COMPARE_0); /* * Store the cputime at which we set the RTC @@ -663,8 +607,8 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) NRF_TIMER0_NS->EVENTS_COMPARE[3] = 0; /* Subscribe for wait for response events */ - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_SUBSCRIBE_TIMER0_TASKS_CAPTURE3(1); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_SUBSCRIBE_RADIO_TASKS_DISABLE(1); + NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); + NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_3); /* Enable the disabled interrupt so we time out on events compare */ NRF_RADIO_NS->INTENSET = RADIO_INTENSET_DISABLED_Msk; @@ -684,8 +628,8 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) NRF_TIMER0_NS->TASKS_CAPTURE[1] = 1; if (NRF_TIMER0_NS->CC[1] > NRF_TIMER0_NS->CC[3]) { /* Unsubscribe from wfr events */ - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_SUBSCRIBE_TIMER0_TASKS_CAPTURE3(0); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_SUBSCRIBE_RADIO_TASKS_DISABLE(0); + NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); + NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); NRF_RADIO_NS->TASKS_DISABLE = 1; } @@ -743,7 +687,7 @@ ble_phy_rx_xcvr_setup(void) NRF_CCM_NS->TASKS_KSGEN = 1; /* Subscribe to radio address event */ - NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_SUBSCRIBE_CCM_TASKS_CRYPT(1); + NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); } else { NRF_RADIO_NS->PACKETPTR = (uint32_t)dptr; } @@ -767,8 +711,8 @@ ble_phy_rx_xcvr_setup(void) #endif /* Turn off trigger TXEN on output compare match and AAR on bcmatch */ - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_SUBSCRIBE_RADIO_TASKS_TXEN(0); - NRF_AAR_NS->SUBSCRIBE_START = DPPI_SUBSCRIBE_AAR_TASKS_START(0); + NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); + NRF_AAR_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RADIO_EVENTS_BCMATCH); /* Reset the rx started flag. Used for the wait for response */ g_ble_phy_data.phy_rx_started = 0; @@ -878,16 +822,16 @@ ble_phy_tx_end_isr(void) NRF_TIMER0_NS->EVENTS_COMPARE[0] = 0; /* Start radio on timer */ - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_SUBSCRIBE_RADIO_TASKS_RXEN(1); + NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); } else { NRF_TIMER0_NS->TASKS_STOP = 1; NRF_TIMER0_NS->TASKS_SHUTDOWN = 1; - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_SUBSCRIBE_TIMER0_TASKS_CAPTURE3(0); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_SUBSCRIBE_RADIO_TASKS_DISABLE(0); - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_SUBSCRIBE_RADIO_TASKS_TXEN(0); - NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_SUBSCRIBE_TIMER0_TASKS_START(0); + NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); + NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); + NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); + NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RTC0_EVENTS_COMPARE_0); assert(transition == BLE_PHY_TRANSITION_NONE); } @@ -931,7 +875,7 @@ ble_phy_rx_end_isr(void) NRF_RADIO_NS->INTENCLR = RADIO_INTENCLR_END_Msk; /* Disable automatic RXEN */ - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_SUBSCRIBE_RADIO_TASKS_RXEN(0); + NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); /* Set RSSI and CRC status flag in header */ ble_hdr = &g_ble_phy_data.rxhdr; @@ -1011,7 +955,7 @@ ble_phy_rx_end_isr(void) NRF_TIMER0_NS->EVENTS_COMPARE[0] = 0; /* Enable automatic TX */ - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_SUBSCRIBE_RADIO_TASKS_TXEN(1); + NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); /* * XXX: Hack warning! @@ -1027,7 +971,7 @@ ble_phy_rx_end_isr(void) */ NRF_TIMER0_NS->TASKS_CAPTURE[3] = 1; if (NRF_TIMER0_NS->CC[3] > NRF_TIMER0_NS->CC[0]) { - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_SUBSCRIBE_RADIO_TASKS_TXEN(0); + NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); g_ble_phy_data.phy_transition_late = 1; } @@ -1066,8 +1010,8 @@ ble_phy_rx_start_isr(void) /* Clear wfr timer channels and DISABLED interrupt */ NRF_RADIO_NS->INTENCLR = RADIO_INTENCLR_DISABLED_Msk | RADIO_INTENCLR_ADDRESS_Msk; - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_SUBSCRIBE_TIMER0_TASKS_CAPTURE3(0); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_SUBSCRIBE_RADIO_TASKS_DISABLE(0); + NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); + NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); /* Initialize the ble mbuf header */ ble_hdr = &g_ble_phy_data.rxhdr; @@ -1142,7 +1086,7 @@ ble_phy_rx_start_isr(void) /* Trigger AAR after last bit of AdvA is received */ NRF_RADIO_NS->EVENTS_BCMATCH = 0; - NRF_AAR_NS->SUBSCRIBE_START = DPPI_SUBSCRIBE_AAR_TASKS_START(1); + NRF_AAR_NS->SUBSCRIBE_START = DPPI_CH_SUB(RADIO_EVENTS_BCMATCH); NRF_RADIO_NS->BCC = (BLE_LL_PDU_HDR_LEN + adva_offset + BLE_DEV_ADDR_LEN) * 8 + g_ble_phy_data.phy_bcc_offset; } @@ -1267,12 +1211,12 @@ ble_phy_dbg_time_setup(void) ble_phy_dbg_time_setup_gpiote(gpiote_idx, MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); - NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_TXRXEN; - NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_READY; + NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); + NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); /* Publish RADIO->EVENTS_READY */ - NRF_RADIO_NS->PUBLISH_READY = DPPI_PUBLISH_RADIO_EVENTS_READY; - NRF_DPPIC_NS->CHENSET = DPPI_CH_ENABLE_RADIO_EVENTS_READY; + NRF_RADIO_NS->PUBLISH_READY = DPPI_CH_PUB(RADIO_EVENTS_READY); + NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_READY); #endif @@ -1281,8 +1225,8 @@ ble_phy_dbg_time_setup(void) ble_phy_dbg_time_setup_gpiote(gpiote_idx, MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); - NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_ADDRESS; - NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_END; + NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); + NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_CH_SUB(RADIO_EVENTS_END); #endif #if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 @@ -1290,23 +1234,23 @@ ble_phy_dbg_time_setup(void) ble_phy_dbg_time_setup_gpiote(gpiote_idx, MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); - NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_SET_RXREADY; + NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_CH_SUB(RADIO_EVENTS_RXREADY); /* TODO figure out how (if?) to subscribe task to multiple DPPI channels * Currently only last one is working. Also using multiple GPIOTE for same * PIN doesn't work... */ - NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_DISABLED; - NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_ADDRESS; - NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_SUBSCRIBE_GPIOTE_TASKS_CLR_CAPTURE3; + NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); + NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); + NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_3); /* Publish RADIO->EVENTS_RXREADY */ - NRF_RADIO_NS->PUBLISH_RXREADY = DPPI_PUBLISH_RADIO_EVENTS_RXREADY; - NRF_DPPIC_NS->CHENSET = DPPI_CH_ENABLE_RADIO_EVENTS_RXREADY; + NRF_RADIO_NS->PUBLISH_RXREADY = DPPI_CH_PUB(RADIO_EVENTS_READY); + NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_RXREADY); /* Publish RADIO->EVENTS_DISABLED */ - NRF_RADIO_NS->PUBLISH_DISABLED = DPPI_CH_ENABLE_RADIO_EVENTS_DISABLED; - NRF_DPPIC_NS->CHENSET = DPPI_CH_ENABLE_RADIO_EVENTS_DISABLED; + NRF_RADIO_NS->PUBLISH_DISABLED = DPPI_CH_PUB(RADIO_EVENTS_DISABLED); + NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_DISABLED); #endif } @@ -1390,19 +1334,19 @@ ble_phy_init(void) NRF_TIMER0_NS->PRESCALER = 4; /* gives us 1 MHz */ /* Publish events */ - NRF_TIMER0_NS->PUBLISH_COMPARE[0] = DPPI_PUBLISH_TIMER0_EVENTS_COMPARE_0; - NRF_TIMER0_NS->PUBLISH_COMPARE[3] = DPPI_PUBLISH_TIMER0_EVENTS_COMPARE_3; - NRF_RADIO_NS->PUBLISH_END = DPPI_PUBLISH_RADIO_EVENTS_END; - NRF_RADIO_NS->PUBLISH_BCMATCH = DPPI_PUBLISH_RADIO_EVENTS_BCMATCH; - NRF_RADIO_NS->PUBLISH_ADDRESS = DPPI_PUBLISH_RADIO_EVENTS_ADDRESS; - NRF_RTC0_NS->PUBLISH_COMPARE[0] = DPPI_PUBLISH_RTC0_EVENTS_COMPARE_0; + NRF_TIMER0_NS->PUBLISH_COMPARE[0] = DPPI_CH_PUB(TIMER0_EVENTS_COMPARE_0); + NRF_TIMER0_NS->PUBLISH_COMPARE[3] = DPPI_CH_PUB(TIMER0_EVENTS_COMPARE_3); + NRF_RADIO_NS->PUBLISH_END = DPPI_CH_PUB(RADIO_EVENTS_END); + NRF_RADIO_NS->PUBLISH_BCMATCH = DPPI_CH_PUB(RADIO_EVENTS_BCMATCH); + NRF_RADIO_NS->PUBLISH_ADDRESS = DPPI_CH_PUB(RADIO_EVENTS_ADDRESS); + NRF_RTC0_NS->PUBLISH_COMPARE[0] = DPPI_CH_PUB(RTC0_EVENTS_COMPARE_0); /* Enable channels we publish on */ NRF_DPPIC_NS->CHENSET = DPPI_CH_ENABLE_ALL; /* Captures tx/rx start in timer0 cc 1 and tx/rx end in timer0 cc 2 */ - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[1] = DPPI_SUBSCRIBE_TIMER0_TASKS_CAPTURE1(1); - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[2] = DPPI_SUBSCRIBE_TIMER0_TASKS_CAPTURE2(1); + NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[1] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); + NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[2] = DPPI_CH_SUB(RADIO_EVENTS_END); /* Set isr in vector table and enable interrupt */ #ifndef RIOT_VERSION @@ -1464,7 +1408,7 @@ ble_phy_rx(void) ble_phy_rx_xcvr_setup(); /* task to start RX should be subscribed here */ - assert(NRF_RADIO_NS->SUBSCRIBE_RXEN & DPPI_SUBSCRIBE_RADIO_TASKS_RXEN(1)); + assert(NRF_RADIO_NS->SUBSCRIBE_RXEN & DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0)); return 0; } @@ -1494,7 +1438,7 @@ ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir) void ble_phy_encrypt_disable(void) { - NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_SUBSCRIBE_CCM_TASKS_CRYPT(0); + NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); NRF_CCM_NS->TASKS_STOP = 1; NRF_CCM_NS->EVENTS_ERROR = 0; NRF_CCM_NS->ENABLE = CCM_ENABLE_ENABLE_Disabled; @@ -1524,7 +1468,7 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) /* XXX: This should not be necessary, but paranoia is good! */ /* Clear timer0 compare to RXEN since we are transmitting */ - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_SUBSCRIBE_RADIO_TASKS_RXEN(0); + NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); if (ble_phy_set_start_time(cputime, rem_usecs, true) != 0) { STATS_INC(ble_phy_stats, tx_late); @@ -1532,7 +1476,7 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) rc = BLE_PHY_ERR_TX_LATE; } else { /* Enable PPI to automatically start TXEN */ - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_SUBSCRIBE_RADIO_TASKS_TXEN(1); + NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); rc = 0; } return rc; @@ -1552,7 +1496,7 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) /* XXX: This should not be necessary, but paranoia is good! */ /* Clear timer0 compare to TXEN since we are transmitting */ - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_SUBSCRIBE_RADIO_TASKS_TXEN(0); + NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); if (ble_phy_set_start_time(cputime, rem_usecs, false) != 0) { STATS_INC(ble_phy_stats, rx_late); @@ -1564,7 +1508,7 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) } /* Enable PPI to automatically start RXEN */ - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_SUBSCRIBE_RADIO_TASKS_RXEN(1); + NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); /* Start rx */ rc = ble_phy_rx(); @@ -1610,10 +1554,10 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) * paranoid, and if you are going to clear one, might as well clear them * all. */ - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_SUBSCRIBE_TIMER0_TASKS_CAPTURE3(0); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_SUBSCRIBE_RADIO_TASKS_DISABLE(0); - NRF_AAR_NS->SUBSCRIBE_START = DPPI_SUBSCRIBE_AAR_TASKS_START(0); - NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_SUBSCRIBE_CCM_TASKS_CRYPT(0); + NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); + NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); + NRF_AAR_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RADIO_EVENTS_BCMATCH); + NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) if (g_ble_phy_data.phy_encrypted) { @@ -1833,13 +1777,13 @@ ble_phy_disable_irq_and_ppi(void) NRF_RADIO_NS->SHORTS = 0; NRF_RADIO_NS->TASKS_DISABLE = 1; - NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_SUBSCRIBE_TIMER0_TASKS_START(0); - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_SUBSCRIBE_TIMER0_TASKS_CAPTURE3(0); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_SUBSCRIBE_RADIO_TASKS_DISABLE(0); - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_SUBSCRIBE_RADIO_TASKS_TXEN(0); - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_SUBSCRIBE_RADIO_TASKS_RXEN(0); - NRF_AAR_NS->SUBSCRIBE_START = DPPI_SUBSCRIBE_AAR_TASKS_START(0); - NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_SUBSCRIBE_CCM_TASKS_CRYPT(0); + NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RTC0_EVENTS_COMPARE_0); + NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); + NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); + NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); + NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); + NRF_AAR_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RADIO_EVENTS_BCMATCH); + NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); NVIC_ClearPendingIRQ(RADIO_IRQn); g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE; @@ -1853,7 +1797,7 @@ ble_phy_restart_rx(void) ble_phy_set_start_now(); /* Enable PPI to automatically start RXEN */ - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_SUBSCRIBE_RADIO_TASKS_RXEN(1); + NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); ble_phy_rx(); } From 6076f0336e133ca114f00e33385c4a82bb7e2063 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 3 Feb 2022 11:49:47 +0100 Subject: [PATCH 0256/1333] nimble/phy/nrf53: Port 67d30b63 to nRF53 --- nimble/drivers/nrf5340/src/ble_phy.c | 65 +++++++++++++--------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/nimble/drivers/nrf5340/src/ble_phy.c b/nimble/drivers/nrf5340/src/ble_phy.c index 550aea292c..aa0d95769e 100644 --- a/nimble/drivers/nrf5340/src/ble_phy.c +++ b/nimble/drivers/nrf5340/src/ble_phy.c @@ -610,9 +610,6 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_3); - /* Enable the disabled interrupt so we time out on events compare */ - NRF_RADIO_NS->INTENSET = RADIO_INTENSET_DISABLED_Msk; - /* * It may happen that if CPU is halted for a brief moment (e.g. during flash * erase or write), TIMER0 already counted past CC[3] and thus wfr will not @@ -746,7 +743,8 @@ ble_phy_rx_xcvr_setup(void) RADIO_SHORTS_ADDRESS_RSSISTART_Msk | RADIO_SHORTS_DISABLED_RSSISTOP_Msk; - NRF_RADIO_NS->INTENSET = RADIO_INTENSET_ADDRESS_Msk; + NRF_RADIO_NS->INTENSET = RADIO_INTENSET_ADDRESS_Msk | + RADIO_INTENSET_DISABLED_Msk; } /** @@ -760,7 +758,6 @@ ble_phy_tx_end_isr(void) uint8_t was_encrypted; uint8_t transition; uint32_t rx_time; - uint32_t wfr_time; /* Store PHY on which we've just transmitted smth */ tx_phy_mode = g_ble_phy_data.phy_cur_phy_mode; @@ -772,13 +769,6 @@ ble_phy_tx_end_isr(void) /* Better be in TX state! */ assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX); - /* Clear events and clear interrupt on disabled event */ - NRF_RADIO_NS->EVENTS_DISABLED = 0; - NRF_RADIO_NS->INTENCLR = RADIO_INTENCLR_DISABLED_Msk; - NRF_RADIO_NS->EVENTS_END = 0; - wfr_time = NRF_RADIO_NS->SHORTS; - (void)wfr_time; - #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) /* * XXX: not sure what to do. We had a HW error during transmission. @@ -870,10 +860,6 @@ ble_phy_rx_end_isr(void) uint32_t tx_time; struct ble_mbuf_hdr *ble_hdr; - /* Clear events and clear interrupt */ - NRF_RADIO_NS->EVENTS_END = 0; - NRF_RADIO_NS->INTENCLR = RADIO_INTENCLR_END_Msk; - /* Disable automatic RXEN */ NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); @@ -1007,9 +993,9 @@ ble_phy_rx_start_isr(void) /* Clear events and clear interrupt */ NRF_RADIO_NS->EVENTS_ADDRESS = 0; + NRF_RADIO_NS->INTENCLR = RADIO_INTENCLR_ADDRESS_Msk; /* Clear wfr timer channels and DISABLED interrupt */ - NRF_RADIO_NS->INTENCLR = RADIO_INTENCLR_DISABLED_Msk | RADIO_INTENCLR_ADDRESS_Msk; NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); @@ -1099,7 +1085,6 @@ ble_phy_rx_start_isr(void) if (rc >= 0) { /* Set rx started flag and enable rx end ISR */ g_ble_phy_data.phy_rx_started = 1; - NRF_RADIO_NS->INTENSET = RADIO_INTENSET_END_Msk; } else { /* Disable PHY */ ble_phy_disable(); @@ -1145,28 +1130,36 @@ ble_phy_isr(void) } } - /* Check for disabled event. This only happens for transmits now */ - if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO_NS->EVENTS_DISABLED) { - if (g_ble_phy_data.phy_state == BLE_PHY_STATE_RX) { - NRF_RADIO_NS->EVENTS_DISABLED = 0; - ble_ll_wfr_timer_exp(NULL); - } else if (g_ble_phy_data.phy_state == BLE_PHY_STATE_IDLE) { - assert(0); - } else { - ble_phy_tx_end_isr(); + /* Handle disabled event. This is enabled for both TX and RX. On RX, we + * need to check phy_rx_started flag to make sure we actually were receiving + * a PDU, otherwise this is due to wfr. + */ + if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && + NRF_RADIO_NS->EVENTS_DISABLED) { + BLE_LL_ASSERT(NRF_RADIO_NS->EVENTS_END || + ((g_ble_phy_data.phy_state == BLE_PHY_STATE_RX) && + !g_ble_phy_data.phy_rx_started)); + NRF_RADIO_NS->EVENTS_END = 0; + NRF_RADIO_NS->EVENTS_DISABLED = 0; + NRF_RADIO_NS->INTENCLR = RADIO_INTENCLR_DISABLED_Msk; + + switch (g_ble_phy_data.phy_state) { + case BLE_PHY_STATE_RX: + if (g_ble_phy_data.phy_rx_started) { + ble_phy_rx_end_isr(); + } else { + ble_ll_wfr_timer_exp(NULL); + } + break; + case BLE_PHY_STATE_TX: + ble_phy_tx_end_isr(); + break; + default: + BLE_LL_ASSERT(0); } } - /* Receive packet end (we dont enable this for transmit) */ - if ((irq_en & RADIO_INTENCLR_END_Msk) && NRF_RADIO_NS->EVENTS_END) { - ble_phy_rx_end_isr(); - } - g_ble_phy_data.phy_transition_late = 0; - - /* Ensures IRQ is cleared */ - irq_en = NRF_RADIO_NS->SHORTS; - /* Count # of interrupts */ STATS_INC(ble_phy_stats, phy_isrs); From 9f571c8dd7fc66e130ed7318b26b3bd5044aa7b6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 2 Feb 2022 14:56:53 +0100 Subject: [PATCH 0257/1333] nimble/phy/nrf53: Add PA/LNA support This is basically port of 9ef71450 to nRF53 and DPPI. --- nimble/drivers/nrf5340/src/ble_phy.c | 204 ++++++++++++++++++++++----- 1 file changed, 168 insertions(+), 36 deletions(-) diff --git a/nimble/drivers/nrf5340/src/ble_phy.c b/nimble/drivers/nrf5340/src/ble_phy.c index aa0d95769e..8ec90cdae3 100644 --- a/nimble/drivers/nrf5340/src/ble_phy.c +++ b/nimble/drivers/nrf5340/src/ble_phy.c @@ -27,6 +27,7 @@ #include #include #include +#include "controller/ble_ll_plna.h" #include #include @@ -39,13 +40,9 @@ #define DPPI_CH_UNSUB(_ch) (((DPPI_CH_ ## _ch) & 0xff) | (0 << 31)) #define DPPI_CH_MASK(_ch) (1 << (DPPI_CH_ ## _ch)) -/* - * NOTE: This code uses 0-5 DPPI channels so care should be taken when using - * DPPI somewhere else. - * TODO maybe we could reduce number of used channels if we reuse same channel - * for mutually exclusive events but for now make it simpler to debug. - * - * Optionally channels 6,7,8 are used for GPIO DBG. +/* Channels 0..5 are always used. + * Channels 6 and 7 are used for PA/LNA (optionally). + * Channels 6..8 are used for GPIO debugging (optionally). */ #define DPPI_CH_TIMER0_EVENTS_COMPARE_0 0 @@ -54,14 +51,16 @@ #define DPPI_CH_RADIO_EVENTS_BCMATCH 3 #define DPPI_CH_RADIO_EVENTS_ADDRESS 4 #define DPPI_CH_RTC0_EVENTS_COMPARE_0 5 -/* used for GPIO DBG */ #define DPPI_CH_RADIO_EVENTS_READY 6 -#define DPPI_CH_RADIO_EVENTS_RXREADY 7 -#define DPPI_CH_RADIO_EVENTS_DISABLED 8 +#define DPPI_CH_RADIO_EVENTS_DISABLED 7 +#define DPPI_CH_RADIO_EVENTS_RXREADY 8 #define DPPI_CH_ENABLE_ALL (DPPIC_CHEN_CH0_Msk | DPPIC_CHEN_CH1_Msk | DPPIC_CHEN_CH2_Msk | \ DPPIC_CHEN_CH3_Msk | DPPIC_CHEN_CH4_Msk | DPPIC_CHEN_CH5_Msk) +#define DPPI_CH_MASK_PLNA (DPPI_CH_MASK(RADIO_EVENTS_READY) | \ + DPPI_CH_MASK(RADIO_EVENTS_DISABLED)) + extern uint8_t g_nrf_num_irks; extern uint32_t g_nrf_irk_list[]; @@ -242,6 +241,27 @@ struct nrf_ccm_data { static struct nrf_ccm_data nrf_ccm_data; #endif +static int g_ble_phy_gpiote_idx; + +#if MYNEWT_VAL(BLE_LL_PA) || MYNEWT_VAL(BLE_LL_LNA) + +#define PLNA_SINGLE_GPIO \ + (!MYNEWT_VAL(BLE_LL_PA) || !MYNEWT_VAL(BLE_LL_LNA) || \ + (MYNEWT_VAL(BLE_LL_PA_GPIO) == MYNEWT_VAL(BLE_LL_LNA_GPIO))) + +#if PLNA_SINGLE_GPIO +static uint8_t plna_idx; +#else +#if MYNEWT_VAL(BLE_LL_PA) +static uint8_t plna_pa_idx; +#endif +#if MYNEWT_VAL(BLE_LL_LNA) +static uint8_t plna_lna_idx; +#endif +#endif + +#endif + #if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 static uint8_t phy_dbg_txrxen_ready_idx; #endif @@ -307,6 +327,62 @@ ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode) g_ble_phy_data.phy_rx_phy_mode = rx_phy_mode; } +static void +ble_phy_plna_enable_pa(void) +{ +#if MYNEWT_VAL(BLE_LL_PA) + ble_ll_plna_pa_enable(); + +#if PLNA_SINGLE_GPIO + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); +#else + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); +#endif +#endif +} + +static void +ble_phy_plna_disable_pa(void) +{ +#if MYNEWT_VAL(BLE_LL_PA) + ble_ll_plna_pa_disable(); + +#if PLNA_SINGLE_GPIO + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); +#else + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); +#endif +#endif +} + +static void +ble_phy_plna_enable_lna(void) +{ +#if MYNEWT_VAL(BLE_LL_LNA) + ble_ll_plna_lna_enable(); + +#if PLNA_SINGLE_GPIO + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); +#else + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); +#endif +#endif +} + +static void +ble_phy_plna_disable_lna(void) +{ +#if MYNEWT_VAL(BLE_LL_LNA) + ble_ll_plna_lna_disable(); + +#if PLNA_SINGLE_GPIO + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); +#else + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); +#endif +#endif +} + int ble_phy_get_cur_phy(void) { @@ -814,6 +890,7 @@ ble_phy_tx_end_isr(void) /* Start radio on timer */ NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); + ble_phy_plna_enable_lna(); } else { NRF_TIMER0_NS->TASKS_STOP = 1; NRF_TIMER0_NS->TASKS_SHUTDOWN = 1; @@ -943,6 +1020,8 @@ ble_phy_rx_end_isr(void) /* Enable automatic TX */ NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); + ble_phy_plna_enable_pa(); + /* * XXX: Hack warning! * @@ -1145,6 +1224,7 @@ ble_phy_isr(void) switch (g_ble_phy_data.phy_state) { case BLE_PHY_STATE_RX: + ble_phy_plna_disable_lna(); if (g_ble_phy_data.phy_rx_started) { ble_phy_rx_end_isr(); } else { @@ -1152,6 +1232,7 @@ ble_phy_isr(void) } break; case BLE_PHY_STATE_TX: + ble_phy_plna_disable_pa(); ble_phy_tx_end_isr(); break; default: @@ -1167,13 +1248,17 @@ ble_phy_isr(void) } #if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 -static inline void -ble_phy_dbg_time_setup_gpiote(int index, int pin) + MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \ + MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 || \ + MYNEWT_VAL(BLE_LL_PA) || \ + MYNEWT_VAL(BLE_LL_LNA) +static int +ble_phy_gpiote_configure(int pin) { NRF_GPIO_Type *port; + g_ble_phy_gpiote_idx--; + port = pin > 31 ? NRF_P1_NS : NRF_P0_NS; pin &= 0x1f; @@ -1181,17 +1266,21 @@ ble_phy_dbg_time_setup_gpiote(int index, int pin) port->DIRSET = (1 << pin); port->OUTCLR = (1 << pin); - NRF_GPIOTE_NS->CONFIG[index] = - (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | - ((pin & 0x1F) << GPIOTE_CONFIG_PSEL_Pos) | - ((port == NRF_P1_NS) << GPIOTE_CONFIG_PORT_Pos); + NRF_GPIOTE_NS->CONFIG[g_ble_phy_gpiote_idx] = + (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | + ((pin & 0x1F) << GPIOTE_CONFIG_PSEL_Pos) | + ((port == NRF_P1_NS) << GPIOTE_CONFIG_PORT_Pos); + + BLE_LL_ASSERT(g_ble_phy_gpiote_idx >= 0); + + return g_ble_phy_gpiote_idx; } #endif static void ble_phy_dbg_time_setup(void) { - int gpiote_idx __attribute__((unused)) = 8; + int idx __attribute__((unused)) = 8; /* * We setup GPIOTE starting from last configuration index to minimize risk @@ -1200,12 +1289,11 @@ ble_phy_dbg_time_setup(void) */ #if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 - phy_dbg_txrxen_ready_idx = --gpiote_idx; - ble_phy_dbg_time_setup_gpiote(gpiote_idx, - MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); + idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); + phy_dbg_txrxen_ready_idx = idx; - NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_SET[idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); + NRF_GPIOTE_NS->SUBSCRIBE_CLR[idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); /* Publish RADIO->EVENTS_READY */ NRF_RADIO_NS->PUBLISH_READY = DPPI_CH_PUB(RADIO_EVENTS_READY); @@ -1214,28 +1302,26 @@ ble_phy_dbg_time_setup(void) #endif #if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 - phy_dbg_address_end_idx = --gpiote_idx; - ble_phy_dbg_time_setup_gpiote(gpiote_idx, - MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); + idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); + phy_dbg_address_end_idx = idx; - NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_CH_SUB(RADIO_EVENTS_END); + NRF_GPIOTE_NS->SUBSCRIBE_SET[idx] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); + NRF_GPIOTE_NS->SUBSCRIBE_CLR[idx] = DPPI_CH_SUB(RADIO_EVENTS_END); #endif #if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 - phy_dbg_wfr_idx = --gpiote_idx; - ble_phy_dbg_time_setup_gpiote(gpiote_idx, - MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); + idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); + phy_dbg_wfr_idx = idx; - NRF_GPIOTE_NS->SUBSCRIBE_SET[gpiote_idx] = DPPI_CH_SUB(RADIO_EVENTS_RXREADY); + NRF_GPIOTE_NS->SUBSCRIBE_SET[idx] = DPPI_CH_SUB(RADIO_EVENTS_RXREADY); /* TODO figure out how (if?) to subscribe task to multiple DPPI channels * Currently only last one is working. Also using multiple GPIOTE for same * PIN doesn't work... */ - NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[gpiote_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_3); + NRF_GPIOTE_NS->SUBSCRIBE_CLR[idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); + NRF_GPIOTE_NS->SUBSCRIBE_CLR[idx] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); + NRF_GPIOTE_NS->SUBSCRIBE_CLR[idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_3); /* Publish RADIO->EVENTS_RXREADY */ NRF_RADIO_NS->PUBLISH_RXREADY = DPPI_CH_PUB(RADIO_EVENTS_READY); @@ -1252,6 +1338,8 @@ ble_phy_init(void) { int rc; + g_ble_phy_gpiote_idx = 8; + /* Default phy to use is 1M */ g_ble_phy_data.phy_cur_phy_mode = BLE_PHY_MODE_1M; g_ble_phy_data.phy_tx_phy_mode = BLE_PHY_MODE_1M; @@ -1341,6 +1429,35 @@ ble_phy_init(void) NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[1] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[2] = DPPI_CH_SUB(RADIO_EVENTS_END); +#if MYNEWT_VAL(BLE_LL_PA) || MYNEWT_VAL(BLE_LL_LNA) + /* We keep both channels enabled and CLR task subscribed all the time. It's + * enough to just (un)subscribe SET task when needed. + * TODO: figure out if this affects power consumption + */ + +#if PLNA_SINGLE_GPIO + plna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO)); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_CLR[plna_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); + NRF_GPIOTE_NS->TASKS_CLR[plna_idx] = 1; +#else +#if MYNEWT_VAL(BLE_LL_PA) + plna_pa_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO)); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_CLR[plna_pa_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); + NRF_GPIOTE_NS->TASKS_CLR[plna_pa_idx] = 1; +#endif +#if MYNEWT_VAL(BLE_LL_LNA) + plna_lna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_LNA_GPIO)); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_CLR[plna_lna_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); + NRF_GPIOTE_NS->TASKS_CLR[plna_lna_idx] = 1; +#endif +#endif + + NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK_PLNA; +#endif + /* Set isr in vector table and enable interrupt */ #ifndef RIOT_VERSION NVIC_SetPriority(RADIO_IRQn, 0); @@ -1471,6 +1588,8 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) /* Enable PPI to automatically start TXEN */ NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); rc = 0; + + ble_phy_plna_enable_pa(); } return rc; } @@ -1503,6 +1622,8 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) /* Enable PPI to automatically start RXEN */ NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); + ble_phy_plna_enable_lna(); + /* Start rx */ rc = ble_phy_rx(); @@ -1778,6 +1899,17 @@ ble_phy_disable_irq_and_ppi(void) NRF_AAR_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RADIO_EVENTS_BCMATCH); NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); +#if PLNA_SINGLE_GPIO + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); +#else +#if MYNEWT_VAL(BLE_LL_PA) + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); +#endif +#if MYNEWT_VAL(BLE_LL_LNA) + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); +#endif +#endif + NVIC_ClearPendingIRQ(RADIO_IRQn); g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE; } From a82be4f1570a8eee42e04b243dd861286b24dc5f Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 8 Feb 2022 12:44:41 +0100 Subject: [PATCH 0258/1333] nimble: Allow to define offset for HCI VS commands This allows to tune starting offset for NimBLE VS HCI commands. --- nimble/include/nimble/hci_common.h | 4 ++-- nimble/syscfg.yml | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index e4830833b3..32d06b60fb 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1063,7 +1063,7 @@ struct ble_hci_le_set_host_feat_cp { /* --- Vendor specific commands (OGF 0x003F) */ /* Read Random Static Address */ -#define BLE_HCI_OCF_VS_RD_STATIC_ADDR (0x0001) +#define BLE_HCI_OCF_VS_RD_STATIC_ADDR (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0001)) struct ble_hci_vs_rd_static_addr_rp { uint8_t addr[6]; } __attribute__((packed)); @@ -1071,7 +1071,7 @@ struct ble_hci_vs_rd_static_addr_rp { /* Set default transmit power. Actual selected TX power is returned * in reply. Setting 0xff restores controller reset default. */ -#define BLE_HCI_OCF_VS_SET_TX_PWR (0x0002) +#define BLE_HCI_OCF_VS_SET_TX_PWR (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0002)) struct ble_hci_vs_set_tx_pwr_cp { int8_t tx_power; } __attribute__((packed)); diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index 0e87c0647d..2d2d329278 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -101,6 +101,13 @@ syscfg.defs: Enables support for NimBLE specific vendor HCI commands value: 0 + BLE_HCI_VS_OCF_OFFSET: + description: > + This defines starting offset for NimBLE specific vendor HCI commands. + Purpose of this is to improve compatibility with other custom + implementations. + value: 0 + # Allow periodic sync transfer only if 5.1 or higher syscfg.restrictions: - "'BLE_PERIODIC_ADV_SYNC_TRANSFER == 0' || 'BLE_VERSION >= 51'" From a1e03722aee25f7756badc22a47091b04baeb68e Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 9 Feb 2022 08:46:12 +0100 Subject: [PATCH 0259/1333] nimble/porting: Fix ports targets Those are used to generate configurations for port so make sure all MYNEWT_VAL are properly included. --- nimble/transport/socket/syscfg.yml | 4 ++++ porting/targets/linux/pkg.yml | 2 +- porting/targets/linux/syscfg.yml | 1 + porting/targets/linux_blemesh/pkg.yml | 2 +- porting/targets/linux_blemesh/syscfg.yml | 1 + porting/targets/nuttx/pkg.yml | 2 +- porting/targets/nuttx/syscfg.yml | 2 +- porting/targets/porting_default/pkg.yml | 2 +- porting/targets/porting_default/syscfg.yml | 1 + porting/targets/riot/pkg.yml | 2 +- porting/targets/riot/syscfg.yml | 3 ++- 11 files changed, 15 insertions(+), 7 deletions(-) diff --git a/nimble/transport/socket/syscfg.yml b/nimble/transport/socket/syscfg.yml index 9c8fa583d6..63b9cddff1 100644 --- a/nimble/transport/socket/syscfg.yml +++ b/nimble/transport/socket/syscfg.yml @@ -43,6 +43,10 @@ syscfg.defs: description: 'linux kernel device' value: 0 + BLE_SOCK_USE_NUTTX: + description: 'Use NuttX socket' + value: 0 + BLE_SOCK_TASK_PRIO: description: 'Priority of the HCI socket task.' type: task_priority diff --git a/porting/targets/linux/pkg.yml b/porting/targets/linux/pkg.yml index c819a83c1c..72018c87e7 100644 --- a/porting/targets/linux/pkg.yml +++ b/porting/targets/linux/pkg.yml @@ -28,7 +28,7 @@ pkg.deps: - "@apache-mynewt-core/sys/log/stub" - "@apache-mynewt-core/sys/stats/stub" - "@apache-mynewt-nimble/nimble/host" - - "@apache-mynewt-nimble/nimble/transport/socket" + - "@apache-mynewt-nimble/nimble/transport" - "@apache-mynewt-nimble/nimble/host/services/ans" - "@apache-mynewt-nimble/nimble/host/services/bas" - "@apache-mynewt-nimble/nimble/host/services/dis" diff --git a/porting/targets/linux/syscfg.yml b/porting/targets/linux/syscfg.yml index 603e586c87..5778ee7d47 100644 --- a/porting/targets/linux/syscfg.yml +++ b/porting/targets/linux/syscfg.yml @@ -17,6 +17,7 @@ # syscfg.vals: + BLE_HCI_TRANSPORT: socket BLE_SOCK_USE_TCP: 0 BLE_SOCK_USE_LINUX_BLUE: 1 BLE_SOCK_TASK_PRIO: 3 diff --git a/porting/targets/linux_blemesh/pkg.yml b/porting/targets/linux_blemesh/pkg.yml index 3cbe09a4b6..14cb2d916c 100644 --- a/porting/targets/linux_blemesh/pkg.yml +++ b/porting/targets/linux_blemesh/pkg.yml @@ -28,7 +28,7 @@ pkg.deps: - "@apache-mynewt-core/sys/log/stub" - "@apache-mynewt-core/sys/stats/stub" - "@apache-mynewt-nimble/nimble/host" - - "@apache-mynewt-nimble/nimble/transport/socket" + - "@apache-mynewt-nimble/nimble/transport" - "@apache-mynewt-nimble/nimble/host/services/ans" - "@apache-mynewt-nimble/nimble/host/services/bas" - "@apache-mynewt-nimble/nimble/host/services/dis" diff --git a/porting/targets/linux_blemesh/syscfg.yml b/porting/targets/linux_blemesh/syscfg.yml index 8ef7972184..5e644d462a 100644 --- a/porting/targets/linux_blemesh/syscfg.yml +++ b/porting/targets/linux_blemesh/syscfg.yml @@ -43,6 +43,7 @@ syscfg.vals: BLE_MESH_SETTINGS: 0 CONFIG_NFFS: 0 + BLE_HCI_TRANSPORT: socket BLE_SOCK_USE_TCP: 0 BLE_SOCK_USE_LINUX_BLUE: 1 BLE_SOCK_TASK_PRIO: 3 diff --git a/porting/targets/nuttx/pkg.yml b/porting/targets/nuttx/pkg.yml index e105cd6308..fb6c01451b 100644 --- a/porting/targets/nuttx/pkg.yml +++ b/porting/targets/nuttx/pkg.yml @@ -28,7 +28,7 @@ pkg.deps: - "@apache-mynewt-core/sys/log/stub" - "@apache-mynewt-core/sys/stats/stub" - "@apache-mynewt-nimble/nimble/host" -- "@apache-mynewt-nimble/nimble/transport/socket" +- "@apache-mynewt-nimble/nimble/transport" - "@apache-mynewt-nimble/nimble/host/services/ans" - "@apache-mynewt-nimble/nimble/host/services/bas" - "@apache-mynewt-nimble/nimble/host/services/dis" diff --git a/porting/targets/nuttx/syscfg.yml b/porting/targets/nuttx/syscfg.yml index fdfa7b5924..d2c6de7bb4 100644 --- a/porting/targets/nuttx/syscfg.yml +++ b/porting/targets/nuttx/syscfg.yml @@ -17,6 +17,7 @@ # syscfg.vals: + BLE_HCI_TRANSPORT: socket BLE_SOCK_USE_TCP: 0 BLE_SOCK_USE_NUTTX: 1 BLE_SOCK_TASK_PRIO: 3 @@ -25,4 +26,3 @@ syscfg.vals: LOG_LEVEL: 2 BLE_SM_LEGACY: 1 BLE_SM_SC: 1 - diff --git a/porting/targets/porting_default/pkg.yml b/porting/targets/porting_default/pkg.yml index 44a34ba097..8b7aab0e34 100644 --- a/porting/targets/porting_default/pkg.yml +++ b/porting/targets/porting_default/pkg.yml @@ -28,7 +28,7 @@ pkg.deps: - "@apache-mynewt-core/sys/log/stub" - "@apache-mynewt-core/sys/stats/stub" - "@apache-mynewt-nimble/nimble/host" - - "@apache-mynewt-nimble/nimble/transport/socket" + - "@apache-mynewt-nimble/nimble/transport" - "@apache-mynewt-nimble/nimble/host/services/ans" - "@apache-mynewt-nimble/nimble/host/services/bas" - "@apache-mynewt-nimble/nimble/host/services/dis" diff --git a/porting/targets/porting_default/syscfg.yml b/porting/targets/porting_default/syscfg.yml index d0aff807f2..3ffd4c279d 100644 --- a/porting/targets/porting_default/syscfg.yml +++ b/porting/targets/porting_default/syscfg.yml @@ -1,3 +1,4 @@ syscfg.vals: + BLE_HCI_TRANSPORT: socket BLE_SOCK_USE_TCP: 0 BLE_SOCK_USE_LINUX_BLUE: 1 diff --git a/porting/targets/riot/pkg.yml b/porting/targets/riot/pkg.yml index 7d1a3243bd..e57c47c293 100644 --- a/porting/targets/riot/pkg.yml +++ b/porting/targets/riot/pkg.yml @@ -28,7 +28,7 @@ pkg.deps: - "@apache-mynewt-core/sys/log/stub" - "@apache-mynewt-core/sys/stats/stub" - "@apache-mynewt-nimble/nimble/host" + - "@apache-mynewt-nimble/nimble/transport" - "@apache-mynewt-nimble/nimble/controller" - - "@apache-mynewt-nimble/nimble/transport/ram" - "@apache-mynewt-nimble/nimble/host/services/gap" - "@apache-mynewt-nimble/nimble/host/services/gatt" diff --git a/porting/targets/riot/syscfg.yml b/porting/targets/riot/syscfg.yml index 8359eaa7c9..1d6939c1be 100644 --- a/porting/targets/riot/syscfg.yml +++ b/porting/targets/riot/syscfg.yml @@ -31,6 +31,7 @@ syscfg.vals: BLE_SM_LEGACY: 0 BLE_SM_SC: 0 BLE_MAX_PERIODIC_SYNCS: 0 + BLE_HCI_TRANSPORT: ram MSYS_1_BLOCK_COUNT: 5 MSYS_1_BLOCK_SIZE: 88 - XTAL_32768: 1 + MCU_LFCLK_SOURCE: LFXO From 4ac4eeca3ab17d46b2ab6565f8fdf9f2eee11f2c Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 8 Feb 2022 15:17:38 +0100 Subject: [PATCH 0260/1333] nimble/ports: Refresh syscfg --- .../examples/linux/include/syscfg/syscfg.h | 87 +++++++++++++- .../linux_blemesh/include/syscfg/syscfg.h | 89 ++++++++++++++- .../examples/nuttx/include/syscfg/syscfg.h | 88 +++++++++++++- porting/nimble/include/syscfg/syscfg.h | 87 +++++++++++++- porting/npl/riot/include/syscfg/syscfg.h | 107 +++++++++++++++++- 5 files changed, 439 insertions(+), 19 deletions(-) diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index fc9ef468fc..31d3835a9a 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -443,6 +443,10 @@ #define MYNEWT_VAL_BLE_HCI_VS (0) #endif +#ifndef MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET +#define MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET (0) +#endif + #ifndef MYNEWT_VAL_BLE_ISO #define MYNEWT_VAL_BLE_ISO (0) #endif @@ -1003,31 +1007,104 @@ #define MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/transport/socket */ +/*** @apache-mynewt-nimble/nimble/transport */ +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_ACL_BUF_COUNT #define MYNEWT_VAL_BLE_ACL_BUF_COUNT (24) #endif +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_ACL_BUF_SIZE #define MYNEWT_VAL_BLE_ACL_BUF_SIZE (255) #endif -#ifndef MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT -#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12) +#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE +#define MYNEWT_VAL_BLE_HCI_BRIDGE (0) #endif +#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac +#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 +#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 (0) +#endif +#undef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT + +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE #define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70) #endif +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT #define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (8) #endif +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT #define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8) #endif +/* Overridden by @apache-mynewt-nimble/porting/targets/linux (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__custom +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__custom (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__ram +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__ram (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__socket +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__socket (1) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__uart +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__uart (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__usb +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__usb (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT +#define MYNEWT_VAL_BLE_HCI_TRANSPORT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_UART +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_UART (0) +#endif + +/*** @apache-mynewt-nimble/nimble/transport/socket */ +#ifndef MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT +#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12) +#endif + #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif @@ -1055,6 +1132,10 @@ #define MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE (1) #endif +#ifndef MYNEWT_VAL_BLE_SOCK_USE_NUTTX +#define MYNEWT_VAL_BLE_SOCK_USE_NUTTX (0) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/linux (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_TCP #define MYNEWT_VAL_BLE_SOCK_USE_TCP (0) diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 3f9258d896..976151a4ee 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -444,6 +444,10 @@ #define MYNEWT_VAL_BLE_HCI_VS (0) #endif +#ifndef MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET +#define MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET (0) +#endif + #ifndef MYNEWT_VAL_BLE_ISO #define MYNEWT_VAL_BLE_ISO (0) #endif @@ -1277,7 +1281,7 @@ /* Overridden by @apache-mynewt-nimble/nimble/host/mesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN -#define MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN (66) +#define MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN (33) #endif #ifndef MYNEWT_VAL_BLE_MESH_PROXY_USE_DEVICE_NAME @@ -1578,31 +1582,104 @@ #define MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/transport/socket */ +/*** @apache-mynewt-nimble/nimble/transport */ +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_ACL_BUF_COUNT #define MYNEWT_VAL_BLE_ACL_BUF_COUNT (24) #endif +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_ACL_BUF_SIZE #define MYNEWT_VAL_BLE_ACL_BUF_SIZE (255) #endif -#ifndef MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT -#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12) +#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE +#define MYNEWT_VAL_BLE_HCI_BRIDGE (0) #endif +#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac +#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 +#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 (0) +#endif +#undef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT + +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE #define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70) #endif +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT #define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (8) #endif +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT #define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8) #endif +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__custom +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__custom (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__ram +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__ram (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__socket +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__socket (1) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__uart +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__uart (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__usb +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__usb (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT +#define MYNEWT_VAL_BLE_HCI_TRANSPORT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_UART +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_UART (0) +#endif + +/*** @apache-mynewt-nimble/nimble/transport/socket */ +#ifndef MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT +#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12) +#endif + #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif @@ -1630,6 +1707,10 @@ #define MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE (1) #endif +#ifndef MYNEWT_VAL_BLE_SOCK_USE_NUTTX +#define MYNEWT_VAL_BLE_SOCK_USE_NUTTX (0) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_TCP #define MYNEWT_VAL_BLE_SOCK_USE_TCP (0) diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index 1f5be13597..9269e3a8b8 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -443,6 +443,10 @@ #define MYNEWT_VAL_BLE_HCI_VS (0) #endif +#ifndef MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET +#define MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET (0) +#endif + #ifndef MYNEWT_VAL_BLE_ISO #define MYNEWT_VAL_BLE_ISO (0) #endif @@ -1005,31 +1009,104 @@ #define MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/transport/socket */ +/*** @apache-mynewt-nimble/nimble/transport */ +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_ACL_BUF_COUNT #define MYNEWT_VAL_BLE_ACL_BUF_COUNT (24) #endif +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_ACL_BUF_SIZE #define MYNEWT_VAL_BLE_ACL_BUF_SIZE (255) #endif -#ifndef MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT -#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12) +#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE +#define MYNEWT_VAL_BLE_HCI_BRIDGE (0) #endif +#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac +#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 +#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 (0) +#endif +#undef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT + +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE #define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70) #endif +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT #define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (8) #endif +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT #define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8) #endif +/* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__custom +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__custom (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__ram +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__ram (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__socket +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__socket (1) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__uart +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__uart (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__usb +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__usb (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT +#define MYNEWT_VAL_BLE_HCI_TRANSPORT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_UART +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_UART (0) +#endif + +/*** @apache-mynewt-nimble/nimble/transport/socket */ +#ifndef MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT +#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12) +#endif + #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif @@ -1056,6 +1133,11 @@ #define MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE (0) #endif +/* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/transport/socket) */ +#ifndef MYNEWT_VAL_BLE_SOCK_USE_NUTTX +#define MYNEWT_VAL_BLE_SOCK_USE_NUTTX (1) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_TCP #define MYNEWT_VAL_BLE_SOCK_USE_TCP (0) diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index a16c528191..98c0775f0b 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -442,6 +442,10 @@ #define MYNEWT_VAL_BLE_HCI_VS (0) #endif +#ifndef MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET +#define MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET (0) +#endif + #ifndef MYNEWT_VAL_BLE_ISO #define MYNEWT_VAL_BLE_ISO (0) #endif @@ -1002,31 +1006,104 @@ #define MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/transport/socket */ +/*** @apache-mynewt-nimble/nimble/transport */ +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_ACL_BUF_COUNT #define MYNEWT_VAL_BLE_ACL_BUF_COUNT (24) #endif +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_ACL_BUF_SIZE #define MYNEWT_VAL_BLE_ACL_BUF_SIZE (255) #endif -#ifndef MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT -#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12) +#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE +#define MYNEWT_VAL_BLE_HCI_BRIDGE (0) #endif +#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac +#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 +#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 (0) +#endif +#undef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT + +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE #define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70) #endif +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT #define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (8) #endif +/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT #define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8) #endif +/* Overridden by @apache-mynewt-nimble/porting/targets/porting_default (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__custom +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__custom (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__ram +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__ram (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__socket +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__socket (1) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__uart +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__uart (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__usb +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__usb (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT +#define MYNEWT_VAL_BLE_HCI_TRANSPORT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_UART +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_UART (0) +#endif + +/*** @apache-mynewt-nimble/nimble/transport/socket */ +#ifndef MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT +#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12) +#endif + #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif @@ -1052,6 +1129,10 @@ #define MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE (1) #endif +#ifndef MYNEWT_VAL_BLE_SOCK_USE_NUTTX +#define MYNEWT_VAL_BLE_SOCK_USE_NUTTX (0) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/porting_default (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_TCP #define MYNEWT_VAL_BLE_SOCK_USE_TCP (0) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 538c8213b4..a581a6d113 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -144,7 +144,7 @@ #define MYNEWT_VAL_MCU_ICACHE_ENABLED (0) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_MCU_LFCLK_SOURCE__LFRC #define MYNEWT_VAL_MCU_LFCLK_SOURCE__LFRC (0) #endif @@ -451,9 +451,8 @@ #undef MYNEWT_VAL_UART_1_PIN_TX -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_XTAL_32768 -#define MYNEWT_VAL_XTAL_32768 (1) +#define MYNEWT_VAL_XTAL_32768 (0) #endif #ifndef MYNEWT_VAL_XTAL_32768_SYNTH @@ -798,6 +797,10 @@ #define MYNEWT_VAL_BLE_HCI_VS (1) #endif +#ifndef MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET +#define MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET (0) +#endif + #ifndef MYNEWT_VAL_BLE_ISO #define MYNEWT_VAL_BLE_ISO (0) #endif @@ -1011,10 +1014,19 @@ #define MYNEWT_VAL_BLE_LL_HCI_VS (1) #endif +/* Value copied from BLE_LL_VND_EVENT_ON_ASSERT */ #ifndef MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_ON_ASSERT #define MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_ON_ASSERT (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_LNA +#define MYNEWT_VAL_BLE_LL_LNA (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_LNA_GPIO +#define MYNEWT_VAL_BLE_LL_LNA_GPIO (-1) +#endif + #ifndef MYNEWT_VAL_BLE_LL_MASTER_SCA #define MYNEWT_VAL_BLE_LL_MASTER_SCA (4) #endif @@ -1043,6 +1055,14 @@ #define MYNEWT_VAL_BLE_LL_OUR_SCA (60) #endif +#ifndef MYNEWT_VAL_BLE_LL_PA +#define MYNEWT_VAL_BLE_LL_PA (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_PA_GPIO +#define MYNEWT_VAL_BLE_LL_PA_GPIO (-1) +#endif + #ifndef MYNEWT_VAL_BLE_LL_PRIO #define MYNEWT_VAL_BLE_LL_PRIO (0) #endif @@ -1188,6 +1208,10 @@ #define MYNEWT_VAL_BLE_PHY_SYSVIEW (0) #endif +#ifndef MYNEWT_VAL_BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR +#define MYNEWT_VAL_BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR (0) +#endif + /*** @apache-mynewt-nimble/nimble/host */ #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) @@ -1581,29 +1605,100 @@ #define MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE (302) #endif -/*** @apache-mynewt-nimble/nimble/transport/ram */ -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/transport/ram) */ +/*** @apache-mynewt-nimble/nimble/transport */ +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_ACL_BUF_COUNT #define MYNEWT_VAL_BLE_ACL_BUF_COUNT (24) #endif +/* Overridden by @apache-mynewt-nimble/nimble/transport/ram (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_ACL_BUF_SIZE #define MYNEWT_VAL_BLE_ACL_BUF_SIZE (65535) #endif +#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE +#define MYNEWT_VAL_BLE_HCI_BRIDGE (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac +#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 +#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 (0) +#endif +#undef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT + +/* Overridden by @apache-mynewt-nimble/nimble/transport/ram (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE #define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/transport/ram) */ +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT #define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (2) #endif +/* Overridden by @apache-mynewt-nimble/nimble/transport/ram (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT #define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8) #endif +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__custom +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__custom (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__ram +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__ram (1) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__socket +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__socket (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__uart +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__uart (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__usb +#define MYNEWT_VAL_BLE_HCI_TRANSPORT__usb (0) +#endif +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT +#define MYNEWT_VAL_BLE_HCI_TRANSPORT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_UART +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_UART (0) +#endif + +/*** @apache-mynewt-nimble/nimble/transport/ram */ #ifndef MYNEWT_VAL_BLE_TRANS_RAM_SYSINIT_STAGE #define MYNEWT_VAL_BLE_TRANS_RAM_SYSINIT_STAGE (100) #endif From 957edb7233a2c42eaeed61e3e1139373c600e5a3 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 7 Feb 2022 12:47:19 +0100 Subject: [PATCH 0261/1333] nimble/ll: Update LL features list to 5.3 --- nimble/controller/include/controller/ble_ll.h | 79 ++++++++++--------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index c51d41014b..3b7e37626c 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -235,42 +235,46 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats; #endif /* LL Features */ -#define BLE_LL_FEAT_LE_ENCRYPTION (0x0000000001) -#define BLE_LL_FEAT_CONN_PARM_REQ (0x0000000002) -#define BLE_LL_FEAT_EXTENDED_REJ (0x0000000004) -#define BLE_LL_FEAT_SLAVE_INIT (0x0000000008) -#define BLE_LL_FEAT_LE_PING (0x0000000010) -#define BLE_LL_FEAT_DATA_LEN_EXT (0x0000000020) -#define BLE_LL_FEAT_LL_PRIVACY (0x0000000040) -#define BLE_LL_FEAT_EXT_SCAN_FILT (0x0000000080) -#define BLE_LL_FEAT_LE_2M_PHY (0x0000000100) -#define BLE_LL_FEAT_STABLE_MOD_ID_TX (0x0000000200) -#define BLE_LL_FEAT_STABLE_MOD_ID_RX (0x0000000400) -#define BLE_LL_FEAT_LE_CODED_PHY (0x0000000800) -#define BLE_LL_FEAT_EXT_ADV (0x0000001000) -#define BLE_LL_FEAT_PERIODIC_ADV (0x0000002000) -#define BLE_LL_FEAT_CSA2 (0x0000004000) -#define BLE_LL_FEAT_LE_POWER_CLASS_1 (0x0000008000) -#define BLE_LL_FEAT_MIN_USED_CHAN (0x0000010000) -#define BLE_LL_FEAT_CTE_REQ (0x0000020000) -#define BLE_LL_FEAT_CTE_RSP (0x0000040000) -#define BLE_LL_FEAT_CTE_TX (0x0000080000) -#define BLE_LL_FEAT_CTE_RX (0x0000100000) -#define BLE_LL_FEAT_CTE_AOD (0x0000200000) -#define BLE_LL_FEAT_CTE_AOA (0x0000400000) -#define BLE_LL_FEAT_CTE_RECV (0x0000800000) -#define BLE_LL_FEAT_SYNC_TRANS_SEND (0x0001000000) -#define BLE_LL_FEAT_SYNC_TRANS_RECV (0x0002000000) -#define BLE_LL_FEAT_SCA_UPDATE (0x0004000000) -#define BLE_LL_FEAT_REM_PKEY (0x0008000000) -#define BLE_LL_FEAT_CIS_MASTER (0x0010000000) -#define BLE_LL_FEAT_CIS_SLAVE (0x0020000000) -#define BLE_LL_FEAT_ISO_BROADCASTER (0x0040000000) -#define BLE_LL_FEAT_SYNC_RECV (0x0080000000) -#define BLE_LL_FEAT_ISO_HOST_SUPPORT (0x0100000000) -#define BLE_LL_FEAT_POWER_CTRL_REQ (0x0200000000) -#define BLE_LL_FEAT_POWER_CHANGE_IND (0x0400000000) -#define BLE_LL_FEAT_PATH_LOSS_MON (0x0800000000) +#define BLE_LL_FEAT_LE_ENCRYPTION (0x0000000001) +#define BLE_LL_FEAT_CONN_PARM_REQ (0x0000000002) +#define BLE_LL_FEAT_EXTENDED_REJ (0x0000000004) +#define BLE_LL_FEAT_SLAVE_INIT (0x0000000008) +#define BLE_LL_FEAT_LE_PING (0x0000000010) +#define BLE_LL_FEAT_DATA_LEN_EXT (0x0000000020) +#define BLE_LL_FEAT_LL_PRIVACY (0x0000000040) +#define BLE_LL_FEAT_EXT_SCAN_FILT (0x0000000080) +#define BLE_LL_FEAT_LE_2M_PHY (0x0000000100) +#define BLE_LL_FEAT_STABLE_MOD_ID_TX (0x0000000200) +#define BLE_LL_FEAT_STABLE_MOD_ID_RX (0x0000000400) +#define BLE_LL_FEAT_LE_CODED_PHY (0x0000000800) +#define BLE_LL_FEAT_EXT_ADV (0x0000001000) +#define BLE_LL_FEAT_PERIODIC_ADV (0x0000002000) +#define BLE_LL_FEAT_CSA2 (0x0000004000) +#define BLE_LL_FEAT_LE_POWER_CLASS_1 (0x0000008000) +#define BLE_LL_FEAT_MIN_USED_CHAN (0x0000010000) +#define BLE_LL_FEAT_CTE_REQ (0x0000020000) +#define BLE_LL_FEAT_CTE_RSP (0x0000040000) +#define BLE_LL_FEAT_CTE_TX (0x0000080000) +#define BLE_LL_FEAT_CTE_RX (0x0000100000) +#define BLE_LL_FEAT_CTE_AOD (0x0000200000) +#define BLE_LL_FEAT_CTE_AOA (0x0000400000) +#define BLE_LL_FEAT_CTE_RECV (0x0000800000) +#define BLE_LL_FEAT_SYNC_TRANS_SEND (0x0001000000) +#define BLE_LL_FEAT_SYNC_TRANS_RECV (0x0002000000) +#define BLE_LL_FEAT_SCA_UPDATE (0x0004000000) +#define BLE_LL_FEAT_REM_PKEY (0x0008000000) +#define BLE_LL_FEAT_CIS_MASTER (0x0010000000) +#define BLE_LL_FEAT_CIS_SLAVE (0x0020000000) +#define BLE_LL_FEAT_ISO_BROADCASTER (0x0040000000) +#define BLE_LL_FEAT_SYNC_RECV (0x0080000000) +#define BLE_LL_FEAT_CIS_HOST (0x0100000000) +#define BLE_LL_FEAT_POWER_CTRL_REQ (0x0200000000) +#define BLE_LL_FEAT_POWER_CHANGE_IND (0x0400000000) +#define BLE_LL_FEAT_PATH_LOSS_MON (0x0800000000) +#define BLE_LL_FEAT_PERIODIC_ADV_ADI (0x1000000000) +#define BLE_LL_FEAT_CONN_SUBRATING (0x2000000000) +#define BLE_LL_FEAT_CONN_SUBRATING_HOST (0x4000000000) +#define BLE_LL_FEAT_CHANNEL_CLASS (0x8000000000) /* This is initial mask, so if feature exchange will not happen, * but host will want to use this procedure, we will try. If not @@ -281,7 +285,8 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats; #define BLE_LL_CONN_CLEAR_FEATURE(connsm, feature) (connsm->conn_features &= ~(feature)) /* All the features which can be controlled by the Host */ -#define BLE_LL_HOST_CONTROLLED_FEATURES (BLE_LL_FEAT_ISO_HOST_SUPPORT) +#define BLE_LL_HOST_CONTROLLED_FEATURES (BLE_LL_FEAT_CIS_HOST | \ + BLE_LL_FEAT_CONN_SUBRATING_HOST) /* LL timing */ #define BLE_LL_IFS (150) /* usecs */ From 55cedd2060bcbcacf6d87fcb0111b3b8946453b9 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 7 Feb 2022 16:53:47 +0100 Subject: [PATCH 0262/1333] nimble/ll: Update LLC PDU defs to 5.3 --- .../controller/include/controller/ble_ll_ctrl.h | 17 ++++++++++++++++- nimble/controller/src/ble_ll_ctrl.c | 17 ++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index 62e1a53569..047d3493d9 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -91,9 +91,16 @@ extern "C" { #define BLE_LL_CTRL_CIS_RSP (0x20) #define BLE_LL_CTRL_CIS_IND (0x21) #define BLE_LL_CTRL_CIS_TERMINATE_IND (0x22) +#define BLE_LL_CTRL_POWER_CONTROL_REQ (0x23) +#define BLE_LL_CTRL_POWER_CONTROL_RSP (0x24) +#define BLE_LL_CTRL_POWER_CHANGE_IND (0x25) +#define BLE_LL_CTRL_SUBRATE_REQ (0x26) +#define BLE_LL_CTRL_SUBRATE_IND (0x27) +#define BLE_LL_CTRL_CHAN_REPORTING_IND (0x28) +#define BLE_LL_CTRL_CHAN_STATUS_IND (0x29) /* Maximum opcode value */ -#define BLE_LL_CTRL_OPCODES (BLE_LL_CTRL_CIS_TERMINATE_IND + 1) +#define BLE_LL_CTRL_OPCODES (BLE_LL_CTRL_CHAN_STATUS_IND + 1) extern const uint8_t g_ble_ll_ctrl_pkt_lengths[BLE_LL_CTRL_OPCODES]; @@ -275,6 +282,14 @@ struct ble_ll_len_req #define BLE_LL_CTRL_CIS_IND_LEN (15) #define BLE_LL_CTRL_CIS_TERMINATE_LEN (3) +#define BLE_LL_CTRL_POWER_CONTROL_REQ_LEN (3) +#define BLE_LL_CTRL_POWER_CONTROL_RSP_LEN (4) +#define BLE_LL_CTRL_POWER_CHANGE_IND_LEN (4) +#define BLE_LL_CTRL_SUBRATE_REQ_LEN (10) +#define BLE_LL_CTRL_SUBRATE_IND_LEN (10) +#define BLE_LL_CTRL_CHAN_REPORTING_IND_LEN (3) +#define BLE_LL_CTRL_CHAN_STATUS_IND_LEN (10) + /* API */ struct ble_ll_conn_sm; void ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc); diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 919f4a571f..aef2d021bc 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -118,7 +118,14 @@ const uint8_t g_ble_ll_ctrl_pkt_lengths[BLE_LL_CTRL_OPCODES] = BLE_LL_CTRL_CIS_REQ_LEN, BLE_LL_CTRL_CIS_RSP_LEN, BLE_LL_CTRL_CIS_IND_LEN, - BLE_LL_CTRL_CIS_TERMINATE_LEN + BLE_LL_CTRL_CIS_TERMINATE_LEN, + BLE_LL_CTRL_POWER_CONTROL_REQ_LEN, + BLE_LL_CTRL_POWER_CONTROL_RSP_LEN, + BLE_LL_CTRL_POWER_CHANGE_IND_LEN, + BLE_LL_CTRL_SUBRATE_REQ_LEN, + BLE_LL_CTRL_SUBRATE_IND_LEN, + BLE_LL_CTRL_CHAN_REPORTING_IND_LEN, + BLE_LL_CTRL_CHAN_STATUS_IND_LEN, }; /** @@ -2565,8 +2572,8 @@ ble_ll_ctrl_chk_proc_start(struct ble_ll_conn_sm *connsm) int ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) { - uint32_t features; - uint32_t feature; + uint64_t features; + uint64_t feature; uint8_t len; uint8_t opcode; uint8_t rsp_opcode; @@ -2662,6 +2669,10 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) case BLE_LL_CTRL_PERIODIC_SYNC_IND: feature = BLE_LL_FEAT_SYNC_TRANS_RECV; break; + case BLE_LL_CTRL_SUBRATE_REQ: + case BLE_LL_CTRL_SUBRATE_IND: + feature = BLE_LL_FEAT_CONN_SUBRATING; + break; default: feature = 0; break; From 4edf16ff27bb876eab0dee4e0bf43f1138ef8eba Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 7 Feb 2022 16:46:28 +0100 Subject: [PATCH 0263/1333] nimble/ll: Update role names to 5.3 This only changes code, comments will be changed in separate commit. --- nimble/controller/include/controller/ble_ll.h | 6 +- .../include/controller/ble_ll_conn.h | 24 +-- .../include/controller/ble_ll_ctrl.h | 4 +- .../include/controller/ble_ll_sched.h | 6 +- .../include/controller/ble_ll_utils.h | 2 +- .../controller/include/controller/ble_phy.h | 2 +- nimble/controller/src/ble_ll.c | 110 +++++----- nimble/controller/src/ble_ll_adv.c | 13 +- nimble/controller/src/ble_ll_conn.c | 203 +++++++++--------- nimble/controller/src/ble_ll_conn_hci.c | 46 ++-- nimble/controller/src/ble_ll_conn_priv.h | 14 +- nimble/controller/src/ble_ll_ctrl.c | 114 +++++----- nimble/controller/src/ble_ll_hci_ev.c | 2 +- nimble/controller/src/ble_ll_sched.c | 18 +- nimble/controller/src/ble_ll_utils.c | 4 +- nimble/controller/syscfg.yml | 7 +- nimble/drivers/nrf5340/src/ble_phy.c | 4 +- 17 files changed, 291 insertions(+), 288 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 3b7e37626c..fb731abd5b 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -238,7 +238,7 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats; #define BLE_LL_FEAT_LE_ENCRYPTION (0x0000000001) #define BLE_LL_FEAT_CONN_PARM_REQ (0x0000000002) #define BLE_LL_FEAT_EXTENDED_REJ (0x0000000004) -#define BLE_LL_FEAT_SLAVE_INIT (0x0000000008) +#define BLE_LL_FEAT_PERIPH_INIT (0x0000000008) #define BLE_LL_FEAT_LE_PING (0x0000000010) #define BLE_LL_FEAT_DATA_LEN_EXT (0x0000000020) #define BLE_LL_FEAT_LL_PRIVACY (0x0000000040) @@ -263,8 +263,8 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats; #define BLE_LL_FEAT_SYNC_TRANS_RECV (0x0002000000) #define BLE_LL_FEAT_SCA_UPDATE (0x0004000000) #define BLE_LL_FEAT_REM_PKEY (0x0008000000) -#define BLE_LL_FEAT_CIS_MASTER (0x0010000000) -#define BLE_LL_FEAT_CIS_SLAVE (0x0020000000) +#define BLE_LL_FEAT_CIS_CENTRAL (0x0010000000) +#define BLE_LL_FEAT_CIS_PERIPH (0x0020000000) #define BLE_LL_FEAT_ISO_BROADCASTER (0x0040000000) #define BLE_LL_FEAT_SYNC_RECV (0x0080000000) #define BLE_LL_FEAT_CIS_HOST (0x0100000000) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index c3073c6e7d..cd219cb9ac 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -36,10 +36,10 @@ extern "C" { #define BLE_LL_CONN_ROLE_NONE (0) #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_LL_CONN_ROLE_MASTER (1) +#define BLE_LL_CONN_ROLE_CENTRAL (1) #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) -#define BLE_LL_CONN_ROLE_SLAVE (2) +#define BLE_LL_CONN_ROLE_PERIPHERAL (2) #endif /* Connection states */ @@ -106,8 +106,8 @@ union ble_ll_conn_sm_flags { uint32_t terminate_ind_txd:1; uint32_t terminate_ind_rxd:1; uint32_t terminate_ind_rxd_acked:1; - uint32_t allow_slave_latency:1; - uint32_t slave_set_last_anchor:1; + uint32_t allow_periph_latency:1; + uint32_t periph_set_last_anchor:1; uint32_t awaiting_host_reply:1; uint32_t terminate_started:1; uint32_t conn_update_sched:1; @@ -249,7 +249,7 @@ struct ble_ll_conn_sm /* connection event mgmt */ uint8_t reject_reason; uint8_t host_reply_opcode; - uint8_t master_sca; + uint8_t central_sca; uint8_t tx_win_size; uint8_t cur_ctrl_proc; uint8_t disconnect_reason; @@ -273,7 +273,7 @@ struct ble_ll_conn_sm /* Connection timing */ uint16_t conn_itvl; - uint16_t slave_latency; + uint16_t periph_latency; uint16_t supervision_tmo; uint16_t min_ce_len; uint16_t max_ce_len; @@ -283,8 +283,8 @@ struct ble_ll_conn_sm uint8_t conn_itvl_usecs; uint32_t conn_itvl_ticks; uint32_t last_anchor_point; /* Slave only */ - uint32_t slave_cur_tx_win_usecs; - uint32_t slave_cur_window_widening; + uint32_t periph_cur_tx_win_usecs; + uint32_t periph_cur_window_widening; uint32_t last_rxd_pdu_cputime; /* Used exclusively for supervision timer */ /* @@ -376,15 +376,15 @@ struct ble_ll_conn_sm /* Role */ #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define CONN_IS_MASTER(csm) (csm->conn_role == BLE_LL_CONN_ROLE_MASTER) +#define CONN_IS_CENTRAL(csm) (csm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) #else -#define CONN_IS_MASTER(csm) (false) +#define CONN_IS_CENTRAL(csm) (false) #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) -#define CONN_IS_SLAVE(csm) (csm->conn_role == BLE_LL_CONN_ROLE_SLAVE) +#define CONN_IS_PERIPHERAL(csm) (csm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) #else -#define CONN_IS_SLAVE(csm) (false) +#define CONN_IS_PERIPHERAL(csm) (false) #endif /* diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index 047d3493d9..ebac33d56c 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -70,7 +70,7 @@ extern "C" { #define BLE_LL_CTRL_PAUSE_ENC_RSP (0x0B) #define BLE_LL_CTRL_VERSION_IND (0x0C) #define BLE_LL_CTRL_REJECT_IND (0x0D) -#define BLE_LL_CTRL_SLAVE_FEATURE_REQ (0x0E) +#define BLE_LL_CTRL_PERIPH_FEATURE_REQ (0x0E) #define BLE_LL_CTRL_CONN_PARM_REQ (0x0F) #define BLE_LL_CTRL_CONN_PARM_RSP (0x10) #define BLE_LL_CTRL_REJECT_IND_EXT (0x11) @@ -205,7 +205,7 @@ struct ble_ll_version_ind * LL control slave feature req * -> 8 bytes of data containing features supported by device. */ -#define BLE_LL_CTRL_SLAVE_FEATURE_REQ_LEN (8) +#define BLE_LL_CTRL_PERIPH_FEATURE_REQ_LEN (8) /* LL control connection param req and connection param rsp */ struct ble_ll_conn_params diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index 4ce687e35c..56399d2e9e 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -143,11 +143,11 @@ void ble_ll_sched_rmv_elem_type(uint8_t type, sched_remove_cb_func remove_cb); /* Schedule a new master connection */ struct ble_ll_conn_sm; -int ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, - struct ble_mbuf_hdr *ble_hdr, uint8_t pyld_len); +int ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, + struct ble_mbuf_hdr *ble_hdr, uint8_t pyld_len); /* Schedule a new slave connection */ -int ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm); +int ble_ll_sched_conn_periph_new(struct ble_ll_conn_sm *connsm); struct ble_ll_adv_sm; typedef void ble_ll_sched_adv_new_cb(struct ble_ll_adv_sm *advsm, diff --git a/nimble/controller/include/controller/ble_ll_utils.h b/nimble/controller/include/controller/ble_ll_utils.h index 248309009b..e0b1646793 100644 --- a/nimble/controller/include/controller/ble_ll_utils.h +++ b/nimble/controller/include/controller/ble_ll_utils.h @@ -26,4 +26,4 @@ uint8_t ble_ll_utils_calc_dci_csa2(uint16_t event_cntr, uint16_t channel_id, uint8_t ble_ll_utils_calc_num_used_chans(const uint8_t *chanmap); uint32_t ble_ll_utils_calc_window_widening(uint32_t anchor_point, uint32_t last_anchor_point, - uint8_t master_sca); + uint8_t central_sca); diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index 47f3afd4ec..3d32bd68ba 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -164,7 +164,7 @@ uint32_t ble_phy_access_addr_get(void); /* Enable encryption */ void ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key, - uint8_t is_master); + uint8_t is_central); /* Disable encryption */ void ble_phy_encrypt_disable(void); diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 34c0c772bf..ec40925d66 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -98,9 +98,9 @@ int8_t g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) -#define BLE_LL_S_SLAVE ((uint64_t)1 << 7) +#define BLE_LL_S_PERIPH ((uint64_t)1 << 7) #else -#define BLE_LL_S_SLAVE ((uint64_t)0 << 7) +#define BLE_LL_S_PERIPH ((uint64_t)0 << 7) #endif #if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) @@ -138,21 +138,21 @@ int8_t g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); #if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) && MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define BLE_LL_S_NCA_INIT ((uint64_t)1 << 16) #define BLE_LL_S_SA_INIT ((uint64_t)1 << 17) -#define BLE_LL_S_NCA_MASTER ((uint64_t)1 << 18) -#define BLE_LL_S_SA_MASTER ((uint64_t)1 << 19) +#define BLE_LL_S_NCA_CENTRAL ((uint64_t)1 << 18) +#define BLE_LL_S_SA_CENTRAL ((uint64_t)1 << 19) #else #define BLE_LL_S_NCA_INIT ((uint64_t)0 << 16) #define BLE_LL_S_SA_INIT ((uint64_t)0 << 17) -#define BLE_LL_S_NCA_MASTER ((uint64_t)0 << 18) -#define BLE_LL_S_SA_MASTER ((uint64_t)0 << 19) +#define BLE_LL_S_NCA_CENTRAL ((uint64_t)0 << 18) +#define BLE_LL_S_SA_CENTRAL ((uint64_t)0 << 19) #endif #if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) && MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) -#define BLE_LL_S_NCA_SLAVE ((uint64_t)1 << 20) -#define BLE_LL_S_SA_SLAVE ((uint64_t)1 << 21) +#define BLE_LL_S_NCA_PERIPH ((uint64_t)1 << 20) +#define BLE_LL_S_SA_PERIPH ((uint64_t)1 << 21) #else -#define BLE_LL_S_NCA_SLAVE ((uint64_t)0 << 20) -#define BLE_LL_S_SA_SLAVE ((uint64_t)0 << 21) +#define BLE_LL_S_NCA_PERIPH ((uint64_t)0 << 20) +#define BLE_LL_S_SA_PERIPH ((uint64_t)0 << 21) #endif #if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) && MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) @@ -160,27 +160,27 @@ int8_t g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); #define BLE_LL_S_PS_INIT ((uint64_t)0 << 22) /* We do not support active scanning while initiating yet */ #define BLE_LL_S_AS_INIT ((uint64_t)0 << 23) -#define BLE_LL_S_PS_MASTER ((uint64_t)1 << 24) -#define BLE_LL_S_AS_MASTER ((uint64_t)1 << 25) +#define BLE_LL_S_PS_CENTRAL ((uint64_t)1 << 24) +#define BLE_LL_S_AS_CENTRAL ((uint64_t)1 << 25) #else #define BLE_LL_S_PS_INIT ((uint64_t)0 << 22) #define BLE_LL_S_AS_INIT ((uint64_t)0 << 23) -#define BLE_LL_S_PS_MASTER ((uint64_t)0 << 24) -#define BLE_LL_S_AS_MASTER ((uint64_t)0 << 25) +#define BLE_LL_S_PS_CENTRAL ((uint64_t)0 << 24) +#define BLE_LL_S_AS_CENTRAL ((uint64_t)0 << 25) #endif #if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) && MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) -#define BLE_LL_S_PS_SLAVE ((uint64_t)1 << 26) -#define BLE_LL_S_AS_SLAVE ((uint64_t)1 << 27) +#define BLE_LL_S_PS_PERIPH ((uint64_t)1 << 26) +#define BLE_LL_S_AS_PERIPH ((uint64_t)1 << 27) #else -#define BLE_LL_S_PS_SLAVE ((uint64_t)0 << 26) -#define BLE_LL_S_AS_SLAVE ((uint64_t)0 << 27) +#define BLE_LL_S_PS_PERIPH ((uint64_t)0 << 26) +#define BLE_LL_S_AS_PERIPH ((uint64_t)0 << 27) #endif #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_LL_S_INIT_MASTER ((uint64_t)1 << 28) +#define BLE_LL_S_INIT_CENTRAL ((uint64_t)1 << 28) #else -#define BLE_LL_S_INIT_MASTER ((uint64_t)0 << 28) +#define BLE_LL_S_INIT_CENTRAL ((uint64_t)0 << 28) #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) @@ -208,29 +208,29 @@ int8_t g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); #endif #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_LL_S_CA_MASTER ((uint64_t)1 << 35) -#define BLE_LL_S_HDCA_MASTER ((uint64_t)1 << 36) -#define BLE_LL_S_LDCA_MASTER ((uint64_t)1 << 37) +#define BLE_LL_S_CA_CENTRAL ((uint64_t)1 << 35) +#define BLE_LL_S_HDCA_CENTRAL ((uint64_t)1 << 36) +#define BLE_LL_S_LDCA_CENTRAL ((uint64_t)1 << 37) #else -#define BLE_LL_S_CA_MASTER ((uint64_t)0 << 35) -#define BLE_LL_S_HDCA_MASTER ((uint64_t)0 << 36) -#define BLE_LL_S_LDCA_MASTER ((uint64_t)0 << 37) +#define BLE_LL_S_CA_CENTRAL ((uint64_t)0 << 35) +#define BLE_LL_S_HDCA_CENTRAL ((uint64_t)0 << 36) +#define BLE_LL_S_LDCA_CENTRAL ((uint64_t)0 << 37) #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) -#define BLE_LL_S_CA_SLAVE ((uint64_t)1 << 38) -#define BLE_LL_S_HDCA_SLAVE ((uint64_t)1 << 39) -#define BLE_LL_S_LDCA_SLAVE ((uint64_t)1 << 40) +#define BLE_LL_S_CA_PERIPH ((uint64_t)1 << 38) +#define BLE_LL_S_HDCA_PERIPH ((uint64_t)1 << 39) +#define BLE_LL_S_LDCA_PERIPH ((uint64_t)1 << 40) #else -#define BLE_LL_S_CA_SLAVE ((uint64_t)0 << 38) -#define BLE_LL_S_HDCA_SLAVE ((uint64_t)0 << 39) -#define BLE_LL_S_LDCA_SLAVE ((uint64_t)0 << 40) +#define BLE_LL_S_CA_PERIPH ((uint64_t)0 << 38) +#define BLE_LL_S_HDCA_PERIPH ((uint64_t)0 << 39) +#define BLE_LL_S_LDCA_PERIPH ((uint64_t)0 << 40) #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) && MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_LL_S_INIT_SLAVE ((uint64_t)1 << 41) +#define BLE_LL_S_INIT_PERIPH ((uint64_t)1 << 41) #else -#define BLE_LL_S_INIT_SLAVE ((uint64_t)0 << 41) +#define BLE_LL_S_INIT_PERIPH ((uint64_t)0 << 41) #endif #define BLE_LL_SUPPORTED_STATES \ @@ -242,7 +242,7 @@ int8_t g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); BLE_LL_S_PS | \ BLE_LL_S_AS | \ BLE_LL_S_INIT | \ - BLE_LL_S_SLAVE | \ + BLE_LL_S_PERIPH | \ BLE_LL_S_NCA_PS | \ BLE_LL_S_SA_PS | \ BLE_LL_S_CA_PS | \ @@ -253,30 +253,30 @@ int8_t g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); BLE_LL_S_HDCA_AS | \ BLE_LL_S_NCA_INIT | \ BLE_LL_S_SA_INIT | \ - BLE_LL_S_NCA_MASTER | \ - BLE_LL_S_SA_MASTER | \ - BLE_LL_S_NCA_SLAVE | \ - BLE_LL_S_SA_SLAVE | \ + BLE_LL_S_NCA_CENTRAL | \ + BLE_LL_S_SA_CENTRAL | \ + BLE_LL_S_NCA_PERIPH | \ + BLE_LL_S_SA_PERIPH | \ BLE_LL_S_PS_INIT | \ BLE_LL_S_AS_INIT | \ - BLE_LL_S_PS_MASTER | \ - BLE_LL_S_AS_MASTER | \ - BLE_LL_S_PS_SLAVE | \ - BLE_LL_S_AS_SLAVE | \ - BLE_LL_S_INIT_MASTER | \ + BLE_LL_S_PS_CENTRAL | \ + BLE_LL_S_AS_CENTRAL | \ + BLE_LL_S_PS_PERIPH | \ + BLE_LL_S_AS_PERIPH | \ + BLE_LL_S_INIT_CENTRAL | \ BLE_LL_S_LDCA | \ BLE_LL_S_LDCA_PS | \ BLE_LL_S_LDCA_AS | \ BLE_LL_S_CA_INIT | \ BLE_LL_S_HDCA_INIT | \ BLE_LL_S_LDCA_INIT | \ - BLE_LL_S_CA_MASTER | \ - BLE_LL_S_HDCA_MASTER | \ - BLE_LL_S_LDCA_MASTER | \ - BLE_LL_S_CA_SLAVE | \ - BLE_LL_S_HDCA_SLAVE | \ - BLE_LL_S_LDCA_SLAVE | \ - BLE_LL_S_INIT_SLAVE) + BLE_LL_S_CA_CENTRAL | \ + BLE_LL_S_HDCA_CENTRAL | \ + BLE_LL_S_LDCA_CENTRAL | \ + BLE_LL_S_CA_PERIPH | \ + BLE_LL_S_HDCA_PERIPH | \ + BLE_LL_S_LDCA_PERIPH | \ + BLE_LL_S_INIT_PERIPH) /* The global BLE LL data object */ struct ble_ll_obj g_ble_ll_data; @@ -1866,8 +1866,8 @@ ble_ll_init(void) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_CONN_PARAM_REQ) features |= BLE_LL_FEAT_CONN_PARM_REQ; #endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG) - features |= BLE_LL_FEAT_SLAVE_INIT; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_PERIPH_INIT_FEAT_XCHG) + features |= BLE_LL_FEAT_PERIPH_INIT; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) features |= BLE_LL_FEAT_LE_ENCRYPTION; @@ -1916,8 +1916,8 @@ ble_ll_init(void) #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) - features |= BLE_LL_FEAT_CIS_MASTER; - features |= BLE_LL_FEAT_CIS_SLAVE; + features |= BLE_LL_FEAT_CIS_CENTRAL; + features |= BLE_LL_FEAT_CIS_PERIPH; features |= BLE_LL_FEAT_ISO_BROADCASTER; features |= BLE_LL_FEAT_ISO_HOST_SUPPORT; #endif diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 61f305947f..5f024da99a 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1374,10 +1374,10 @@ ble_ll_adv_aux_calculate(struct ble_ll_adv_sm *advsm, aux->chan = ble_ll_utils_calc_dci_csa2(advsm->event_cntr++, advsm->channel_id, g_ble_ll_conn_params.num_used_chans, - g_ble_ll_conn_params.master_chan_map); + g_ble_ll_conn_params.central_chan_map); #else aux->chan = ble_ll_utils_remapped_channel(ble_ll_rand() % BLE_PHY_NUM_DATA_CHANS, - g_ble_ll_conn_params.master_chan_map); + g_ble_ll_conn_params.central_chan_map); #endif rem_aux_data_len = AUX_DATA_LEN(advsm) - aux_data_offset; @@ -2546,7 +2546,7 @@ ble_ll_adv_sm_start_periodic(struct ble_ll_adv_sm *advsm) advsm->periodic_adv_active = 1; /* keep channel map since we cannot change it later on */ - memcpy(advsm->periodic_chanmap, g_ble_ll_conn_params.master_chan_map, + memcpy(advsm->periodic_chanmap, g_ble_ll_conn_params.central_chan_map, BLE_LL_CONN_CHMAP_LEN); advsm->periodic_num_used_chans = g_ble_ll_conn_params.num_used_chans; advsm->periodic_event_cntr = 0; @@ -4118,7 +4118,7 @@ ble_ll_adv_already_connected(const uint8_t* addr, uint8_t addr_type) { struct ble_ll_conn_sm *connsm; - /* extracted from ble_ll_conn_slave_start function */ + /* extracted from ble_ll_conn_periph_start function */ SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) { if (!memcmp(&connsm->peer_addr, addr, BLE_DEV_ADDR_LEN)) { if (addr_type == BLE_ADDR_RANDOM) { @@ -4401,8 +4401,9 @@ ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, struct ble_mbuf_hdr *hdr, #endif /* Try to start slave connection. If successful, stop advertising */ - valid = ble_ll_conn_slave_start(rxbuf, addr_type, hdr, - !(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)); + valid = ble_ll_conn_periph_start(rxbuf, addr_type, hdr, + !(advsm->props & + BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)); if (valid) { /* stop advertising only if not transmitting connection response */ if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD)) { diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 7e3baab1a6..7824f1df0a 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -170,8 +170,8 @@ STATS_SECT_START(ble_ll_conn_stats) STATS_SECT_ENTRY(no_free_conn_sm) STATS_SECT_ENTRY(rx_data_pdu_no_conn) STATS_SECT_ENTRY(rx_data_pdu_bad_aa) - STATS_SECT_ENTRY(slave_rxd_bad_conn_req_params) - STATS_SECT_ENTRY(slave_ce_failures) + STATS_SECT_ENTRY(periph_rxd_bad_conn_req_params) + STATS_SECT_ENTRY(periph_ce_failures) STATS_SECT_ENTRY(data_pdu_rx_dup) STATS_SECT_ENTRY(data_pdu_txg) STATS_SECT_ENTRY(data_pdu_txf) @@ -203,8 +203,8 @@ STATS_NAME_START(ble_ll_conn_stats) STATS_NAME(ble_ll_conn_stats, no_free_conn_sm) STATS_NAME(ble_ll_conn_stats, rx_data_pdu_no_conn) STATS_NAME(ble_ll_conn_stats, rx_data_pdu_bad_aa) - STATS_NAME(ble_ll_conn_stats, slave_rxd_bad_conn_req_params) - STATS_NAME(ble_ll_conn_stats, slave_ce_failures) + STATS_NAME(ble_ll_conn_stats, periph_rxd_bad_conn_req_params) + STATS_NAME(ble_ll_conn_stats, periph_ce_failures) STATS_NAME(ble_ll_conn_stats, data_pdu_rx_dup) STATS_NAME(ble_ll_conn_stats, data_pdu_txg) STATS_NAME(ble_ll_conn_stats, data_pdu_txf) @@ -694,7 +694,7 @@ ble_ll_conn_start_rx_encrypt(void *arg) ble_phy_encrypt_enable(connsm->enc_data.rx_pkt_cntr, connsm->enc_data.iv, connsm->enc_data.enc_block.cipher_text, - !CONN_IS_MASTER(connsm)); + !CONN_IS_CENTRAL(connsm)); } #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) @@ -738,7 +738,7 @@ ble_ll_conn_continue_rx_encrypt(void *arg) connsm = (struct ble_ll_conn_sm *)arg; ble_phy_encrypt_set_pkt_cntr(connsm->enc_data.rx_pkt_cntr, - !CONN_IS_MASTER(connsm)); + !CONN_IS_CENTRAL(connsm)); } #endif @@ -963,9 +963,9 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) * LL_ENC_RSP is sent. */ if (((connsm->enc_data.enc_state > CONN_ENC_S_ENCRYPTED) && - CONN_IS_MASTER(connsm)) || + CONN_IS_CENTRAL(connsm)) || ((connsm->enc_data.enc_state > CONN_ENC_S_ENC_RSP_TO_BE_SENT) && - CONN_IS_SLAVE(connsm))) { + CONN_IS_PERIPHERAL(connsm))) { if (!ble_ll_ctrl_enc_allowed_pdu_tx(pkthdr)) { CONN_F_EMPTY_PDU_TXD(connsm) = 1; goto conn_tx_pdu; @@ -978,7 +978,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) * packets can be let go. */ if (nextpkthdr && !ble_ll_ctrl_enc_allowed_pdu_tx(nextpkthdr) - && (CONN_IS_MASTER(connsm) || + && (CONN_IS_CENTRAL(connsm) || !ble_ll_ctrl_is_start_enc_rsp(m))) { nextpkthdr = NULL; } @@ -1025,7 +1025,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) /* We will allow a next packet if it itself is allowed */ pkthdr = OS_MBUF_PKTHDR(connsm->cur_tx_pdu); if (nextpkthdr && !ble_ll_ctrl_enc_allowed_pdu_tx(nextpkthdr) - && (CONN_IS_MASTER(connsm) || + && (CONN_IS_CENTRAL(connsm) || !ble_ll_ctrl_is_start_enc_rsp(connsm->cur_tx_pdu))) { nextpkthdr = NULL; } @@ -1095,7 +1095,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) ble_ll_pdu_tx_time_get(cur_txlen, tx_phy_mode); #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { ticks += (BLE_LL_IFS + connsm->eff_max_rx_time); } #endif @@ -1154,7 +1154,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) * overrun next scheduled item. */ if ((connsm->csmflags.cfbit.terminate_ind_rxd) || - (CONN_IS_SLAVE(connsm) && (md == 0) && + (CONN_IS_PERIPHERAL(connsm) && (md == 0) && (connsm->cons_rxd_bad_crc == 0) && ((connsm->last_rxd_hdr_byte & BLE_LL_DATA_HDR_MD_MASK) == 0) && !ble_ll_ctrl_is_terminate_ind(hdr_byte, m->om_data[0]))) { @@ -1187,7 +1187,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) ble_phy_encrypt_enable(connsm->enc_data.tx_pkt_cntr, connsm->enc_data.iv, connsm->enc_data.enc_block.cipher_text, - CONN_IS_MASTER(connsm)); + CONN_IS_CENTRAL(connsm)); } else if (is_ctrl && (opcode == BLE_LL_CTRL_START_ENC_REQ)) { /* * Only the slave sends this and it gets sent unencrypted but @@ -1209,7 +1209,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) */ switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: CONN_F_ENCRYPTED(connsm) = 0; connsm->enc_data.enc_state = CONN_ENC_S_PAUSED; connsm->enc_data.tx_encrypted = 0; @@ -1217,13 +1217,13 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: + case BLE_LL_CONN_ROLE_PERIPHERAL: CONN_F_ENCRYPTED(connsm) = 1; connsm->enc_data.tx_encrypted = 1; ble_phy_encrypt_enable(connsm->enc_data.tx_pkt_cntr, connsm->enc_data.iv, connsm->enc_data.enc_block.cipher_text, - CONN_IS_MASTER(connsm)); + CONN_IS_CENTRAL(connsm)); if (txend_func == NULL) { txend_func = ble_ll_conn_start_rx_unencrypt; } else { @@ -1240,7 +1240,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) if (CONN_F_ENCRYPTED(connsm)) { connsm->enc_data.tx_encrypted = 1; ble_phy_encrypt_set_pkt_cntr(connsm->enc_data.tx_pkt_cntr, - CONN_IS_MASTER(connsm)); + CONN_IS_CENTRAL(connsm)); if (txend_func == NULL) { txend_func = ble_ll_conn_continue_rx_encrypt; } @@ -1335,7 +1335,7 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: /* Set start time of transmission */ start = sch->start_time + g_ble_ll_sched_offset_ticks; rc = ble_phy_tx_set_start_time(start, sch->remainder); @@ -1364,7 +1364,7 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: + case BLE_LL_CONN_ROLE_PERIPHERAL: #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) if (CONN_F_ENCRYPTED(connsm)) { ble_phy_encrypt_enable(connsm->enc_data.rx_pkt_cntr, @@ -1381,14 +1381,14 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) rc = ble_phy_rx_set_start_time(start, sch->remainder); if (rc) { /* End the connection event as we have no more buffers */ - STATS_INC(ble_ll_conn_stats, slave_ce_failures); + STATS_INC(ble_ll_conn_stats, periph_ce_failures); rc = BLE_LL_SCHED_STATE_DONE; } else { /* * Set flag that tells slave to set last anchor point if a packet * has been received. */ - connsm->csmflags.cfbit.slave_set_last_anchor = 1; + connsm->csmflags.cfbit.periph_set_last_anchor = 1; /* * Set the wait for response time. The anchor point is when we @@ -1414,8 +1414,8 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) * 2) The address rx time and jitter is accounted for in the * phy function */ - usecs = connsm->slave_cur_tx_win_usecs + 61 + - (2 * connsm->slave_cur_window_widening); + usecs = connsm->periph_cur_tx_win_usecs + 61 + + (2 * connsm->periph_cur_window_widening); ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_RX, 0, usecs); /* Set next wakeup time to connection event end time */ rc = BLE_LL_SCHED_STATE_RUNNING; @@ -1475,7 +1475,7 @@ ble_ll_conn_can_send_next_pdu(struct ble_ll_conn_sm *connsm, uint32_t begtime, #endif rc = 1; - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { /* Get next scheduled item time */ next_sched_time = ble_ll_conn_get_next_sched_time(connsm); @@ -1557,11 +1557,11 @@ ble_ll_conn_auth_pyld_timer_start(struct ble_ll_conn_sm *connsm) #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) static void -ble_ll_conn_master_common_init(struct ble_ll_conn_sm *connsm) +ble_ll_conn_central_common_init(struct ble_ll_conn_sm *connsm) { - /* Set master role */ - connsm->conn_role = BLE_LL_CONN_ROLE_MASTER; + /* Set central role */ + connsm->conn_role = BLE_LL_CONN_ROLE_CENTRAL; /* Set default ce parameters */ @@ -1571,14 +1571,14 @@ ble_ll_conn_master_common_init(struct ble_ll_conn_sm *connsm) */ connsm->tx_win_size = BLE_LL_CONN_TX_WIN_MIN + 1; connsm->tx_win_off = 0; - connsm->master_sca = BLE_LL_SCA_ENUM; + connsm->central_sca = BLE_LL_SCA_ENUM; /* Hop increment is a random value between 5 and 16. */ connsm->hop_inc = (ble_ll_rand() % 12) + 5; /* Set channel map to map requested by host */ connsm->num_used_chans = g_ble_ll_conn_params.num_used_chans; - memcpy(connsm->chanmap, g_ble_ll_conn_params.master_chan_map, + memcpy(connsm->chanmap, g_ble_ll_conn_params.central_chan_map, BLE_LL_CONN_CHMAP_LEN); /* Calculate random access address and crc initialization value */ @@ -1598,12 +1598,12 @@ ble_ll_conn_master_common_init(struct ble_ll_conn_sm *connsm) * @param hcc */ void -ble_ll_conn_master_init(struct ble_ll_conn_sm *connsm, - struct ble_ll_conn_create_scan *cc_scan, - struct ble_ll_conn_create_params *cc_params) +ble_ll_conn_central_init(struct ble_ll_conn_sm *connsm, + struct ble_ll_conn_create_scan *cc_scan, + struct ble_ll_conn_create_params *cc_params) { - ble_ll_conn_master_common_init(connsm); + ble_ll_conn_central_common_init(connsm); connsm->own_addr_type = cc_scan->own_addr_type; memcpy(&connsm->peer_addr, &cc_scan->peer_addr, BLE_DEV_ADDR_LEN); @@ -1612,7 +1612,7 @@ ble_ll_conn_master_init(struct ble_ll_conn_sm *connsm, connsm->conn_itvl = cc_params->conn_itvl; connsm->conn_itvl_ticks = cc_params->conn_itvl_ticks; connsm->conn_itvl_usecs = cc_params->conn_itvl_usecs; - connsm->slave_latency = cc_params->conn_latency; + connsm->periph_latency = cc_params->conn_latency; connsm->supervision_tmo = cc_params->supervision_timeout; connsm->min_ce_len = cc_params->min_ce_len; connsm->max_ce_len = cc_params->max_ce_len; @@ -1681,7 +1681,7 @@ ble_ll_conn_create_set_params(struct ble_ll_conn_sm *connsm, uint8_t phy) cc_params = &g_ble_ll_conn_create_sm.params[phy - 1]; - connsm->slave_latency = cc_params->conn_latency; + connsm->periph_latency = cc_params->conn_latency; connsm->supervision_tmo = cc_params->supervision_timeout; connsm->conn_itvl = cc_params->conn_itvl; @@ -2038,12 +2038,12 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) ble_ll_ctrl_terminate_start(connsm); } - if (CONN_F_TERMINATE_STARTED(connsm) && CONN_IS_SLAVE(connsm)) { + if (CONN_F_TERMINATE_STARTED(connsm) && CONN_IS_PERIPHERAL(connsm)) { /* Some of the devices waits whole connection interval to ACK our * TERMINATE_IND sent as a Slave. Since we are here it means we are still waiting for ACK. * Make sure we catch it in next connection event. */ - connsm->slave_latency = 0; + connsm->periph_latency = 0; } /* @@ -2061,12 +2061,12 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) /* Set event counter to the next connection event that we will tx/rx in */ itvl = connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS; latency = 1; - if (connsm->csmflags.cfbit.allow_slave_latency && + if (connsm->csmflags.cfbit.allow_periph_latency && !connsm->csmflags.cfbit.conn_update_sched && !CONN_F_PHY_UPDATE_SCHED(connsm) && !connsm->csmflags.cfbit.chanmap_update_scheduled) { if (connsm->csmflags.cfbit.pkt_rxd) { - latency += connsm->slave_latency; + latency += connsm->periph_latency; itvl = itvl * latency; } } @@ -2094,19 +2094,19 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) /* Set flag so we send connection update event */ upd = &connsm->conn_update_req; - if (CONN_IS_MASTER(connsm) || - (CONN_IS_SLAVE(connsm) && + if (CONN_IS_CENTRAL(connsm) || + (CONN_IS_PERIPHERAL(connsm) && IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ)) || - (connsm->conn_itvl != upd->interval) || - (connsm->slave_latency != upd->latency) || + (connsm->conn_itvl != upd->interval) || + (connsm->periph_latency != upd->latency) || (connsm->supervision_tmo != upd->timeout)) { connsm->csmflags.cfbit.host_expects_upd_event = 1; } connsm->supervision_tmo = upd->timeout; - connsm->slave_latency = upd->latency; + connsm->periph_latency = upd->latency; connsm->tx_win_size = upd->winsize; - connsm->slave_cur_tx_win_usecs = + connsm->periph_cur_tx_win_usecs = connsm->tx_win_size * BLE_LL_CONN_TX_WIN_USECS; connsm->tx_win_off = upd->winoffset; connsm->conn_itvl = upd->interval; @@ -2216,8 +2216,8 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) } /* - * Calculate ce end time. For a slave, we need to add window widening and - * the transmit window if we still have one. + * Calculate ce end time. For a peripgheral, we need to add window widening + * and the transmit window if we still have one. */ #if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) itvl = g_ble_ll_sched_data.sch_ticks_per_period; @@ -2226,18 +2226,18 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) BLE_LL_SCHED_USECS_PER_SLOT); #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { cur_ww = ble_ll_utils_calc_window_widening(connsm->anchor_point, connsm->last_anchor_point, - connsm->master_sca); + connsm->central_sca); max_ww = (connsm->conn_itvl * (BLE_LL_CONN_ITVL_USECS/2)) - BLE_LL_IFS; if (cur_ww >= max_ww) { return -1; } cur_ww += BLE_LL_JITTER_USECS; - connsm->slave_cur_window_widening = cur_ww; - itvl += ble_ll_tmr_u2t(cur_ww + connsm->slave_cur_tx_win_usecs); + connsm->periph_cur_window_widening = cur_ww; + itvl += ble_ll_tmr_u2t(cur_ww + connsm->periph_cur_tx_win_usecs); } #endif itvl -= g_ble_ll_sched_offset_ticks; @@ -2296,7 +2296,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) */ rc = 1; #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { /* * With a 32.768 kHz crystal we dont care about the remaining usecs * when setting last anchor point. The only thing last anchor is used @@ -2331,23 +2331,22 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) ble_ll_tmr_add(&connsm->anchor_point, &connsm->anchor_point_usecs, usecs); - connsm->slave_cur_tx_win_usecs = + connsm->periph_cur_tx_win_usecs = connsm->tx_win_size * BLE_LL_CONN_TX_WIN_USECS; #if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) connsm->ce_end_time = connsm->anchor_point + g_ble_ll_sched_data.sch_ticks_per_period + - ble_ll_tmr_u2t(connsm->slave_cur_tx_win_usecs) + 1; + ble_ll_tmr_u2t(connsm->periph_cur_tx_win_usecs) + 1; #else connsm->ce_end_time = connsm->anchor_point + ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * BLE_LL_SCHED_USECS_PER_SLOT + - connsm->slave_cur_tx_win_usecs) + 1; + connsm->periph_cur_tx_win_usecs) + 1; #endif - connsm->slave_cur_window_widening = BLE_LL_JITTER_USECS; /* Start the scheduler for the first connection event */ - while (ble_ll_sched_slave_new(connsm)) { + while (ble_ll_sched_conn_periph_new(connsm)) { if (ble_ll_conn_next_event(connsm)) { STATS_INC(ble_ll_conn_stats, cant_set_sched); rc = 0; @@ -2374,7 +2373,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) #endif switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: evbuf = ble_ll_init_get_conn_comp_ev(); ble_ll_conn_comp_event_send(connsm, BLE_ERR_SUCCESS, evbuf, NULL); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) @@ -2384,8 +2383,8 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) /* * Initiate features exchange * - * XXX we do this only as a master as it was observed that sending - * LL_SLAVE_FEATURE_REQ after connection breaks some recent iPhone + * XXX we do this only as a central as it was observed that sending + * LL_PERIPH_FEATURE_REQ after connection breaks some recent iPhone * models; for slave just assume master will initiate features xchg * if it has some additional features to use. */ @@ -2393,7 +2392,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: + case BLE_LL_CONN_ROLE_PERIPHERAL: ble_ll_adv_send_conn_comp_ev(connsm, rxhdr); break; #endif @@ -2472,7 +2471,7 @@ ble_ll_conn_event_end(struct ble_npl_event *ev) * usecs to 0 since we dont need to listen in the transmit window. */ if (connsm->csmflags.cfbit.pkt_rxd) { - connsm->slave_cur_tx_win_usecs = 0; + connsm->periph_cur_tx_win_usecs = 0; } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) @@ -2679,10 +2678,10 @@ ble_ll_conn_tx_connect_ind_pducb(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_by dptr[7] = connsm->tx_win_size; put_le16(dptr + 8, connsm->tx_win_off); put_le16(dptr + 10, connsm->conn_itvl); - put_le16(dptr + 12, connsm->slave_latency); + put_le16(dptr + 12, connsm->periph_latency); put_le16(dptr + 14, connsm->supervision_tmo); memcpy(dptr + 16, &connsm->chanmap, BLE_LL_CONN_CHMAP_LEN); - dptr[21] = connsm->hop_inc | (connsm->master_sca << 5); + dptr[21] = connsm->hop_inc | (connsm->central_sca << 5); *hdr_byte = pdu_data->hdr_byte; @@ -2736,7 +2735,7 @@ ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu, } #endif - if (ble_ll_sched_master_new(connsm, rxhdr, 0)) { + if (ble_ll_sched_conn_central_new(connsm, rxhdr, 0)) { return -1; } @@ -2778,8 +2777,8 @@ ble_ll_conn_send_connect_req_cancel(void) } static void -ble_ll_conn_master_start(uint8_t phy, uint8_t csa, - struct ble_ll_scan_addr_data *addrd, uint8_t *targeta) +ble_ll_conn_central_start(uint8_t phy, uint8_t csa, + struct ble_ll_scan_addr_data *addrd, uint8_t *targeta) { struct ble_ll_conn_sm *connsm; @@ -2824,7 +2823,7 @@ ble_ll_conn_created_on_legacy(struct os_mbuf *rxpdu, rxbuf = rxpdu->om_data; csa = rxbuf[0] & BLE_ADV_PDU_HDR_CHSEL_MASK; - ble_ll_conn_master_start(BLE_PHY_1M, csa, addrd, targeta); + ble_ll_conn_central_start(BLE_PHY_1M, csa, addrd, targeta); } #endif @@ -2847,7 +2846,7 @@ ble_ll_conn_created_on_aux(struct os_mbuf *rxpdu, phy = BLE_PHY_1M; #endif - ble_ll_conn_master_start(phy, 1, addrd, targeta); + ble_ll_conn_central_start(phy, 1, addrd, targeta); } #endif #endif /* BLE_LL_CFG_FEAT_LL_EXT_ADV */ @@ -2925,8 +2924,8 @@ ble_ll_conn_rx_isr_start(struct ble_mbuf_hdr *rxhdr, uint32_t aa) connsm->conn_state = BLE_LL_CONN_STATE_ESTABLISHED; /* Set anchor point (and last) if 1st rxd frame in connection event */ - if (connsm->csmflags.cfbit.slave_set_last_anchor) { - connsm->csmflags.cfbit.slave_set_last_anchor = 0; + if (connsm->csmflags.cfbit.periph_set_last_anchor) { + connsm->csmflags.cfbit.periph_set_last_anchor = 0; connsm->last_anchor_point = rxhdr->beg_cputime; connsm->anchor_point = connsm->last_anchor_point; connsm->anchor_point_usecs = rxhdr->rem_usecs; @@ -2991,9 +2990,9 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) * Reference: Core 5.0, Vol 6, Part B, 5.1.3.1 */ if ((connsm->enc_data.enc_state > CONN_ENC_S_PAUSE_ENC_RSP_WAIT && - CONN_IS_MASTER(connsm)) || + CONN_IS_CENTRAL(connsm)) || (connsm->enc_data.enc_state >= CONN_ENC_S_ENC_RSP_TO_BE_SENT && - CONN_IS_SLAVE(connsm))) { + CONN_IS_PERIPHERAL(connsm))) { if (!ble_ll_ctrl_enc_allowed_pdu_rx(rxpdu)) { ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC); goto conn_rx_data_pdu_end; @@ -3021,9 +3020,9 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) * once we have received a NESN of 1 from the master */ #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { if (hdr_byte & BLE_LL_DATA_HDR_NESN_MASK) { - connsm->csmflags.cfbit.allow_slave_latency = 1; + connsm->csmflags.cfbit.allow_periph_latency = 1; } } #endif @@ -3212,13 +3211,13 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) } else { switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: reply = CONN_F_LAST_TXD_MD(connsm); break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: - /* A slave always responds with a packet */ + case BLE_LL_CONN_ROLE_PERIPHERAL: + /* A peripheral always responds with a packet */ reply = 1; break; #endif @@ -3337,7 +3336,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) #if (BLE_LL_BT5_PHY_SUPPORTED == 1) if (BLE_LL_LLID_IS_CTRL(hdr_byte) && - CONN_IS_SLAVE(connsm) && + CONN_IS_PERIPHERAL(connsm) && (opcode == BLE_LL_CTRL_PHY_UPDATE_IND)) { connsm->phy_tx_transition = ble_ll_ctrl_phy_tx_transition_get(rxbuf[3]); @@ -3364,13 +3363,13 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: reply = CONN_F_LAST_TXD_MD(connsm) || (hdr_byte & BLE_LL_DATA_HDR_MD_MASK); break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: - /* A slave always replies */ + case BLE_LL_CONN_ROLE_PERIPHERAL: + /* A peripheral always replies */ reply = 1; break; #endif @@ -3465,7 +3464,7 @@ ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm *connsm, struct os_mbuf *om, break; case BLE_LL_CTRL_PAUSE_ENC_RSP: #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { lifo = 1; } #endif @@ -3556,18 +3555,18 @@ ble_ll_conn_set_global_chanmap(uint8_t num_used_chans, const uint8_t *chanmap) /* Do nothing if same channel map */ conn_params = &g_ble_ll_conn_params; - if (!memcmp(conn_params->master_chan_map, chanmap, BLE_LL_CONN_CHMAP_LEN)) { + if (!memcmp(conn_params->central_chan_map, chanmap, BLE_LL_CONN_CHMAP_LEN)) { return; } /* Change channel map and cause channel map update procedure to start */ conn_params->num_used_chans = num_used_chans; - memcpy(conn_params->master_chan_map, chanmap, BLE_LL_CONN_CHMAP_LEN); + memcpy(conn_params->central_chan_map, chanmap, BLE_LL_CONN_CHMAP_LEN); #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Perform channel map update */ SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) { - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_CHAN_MAP_UPD); } } @@ -3590,8 +3589,8 @@ ble_ll_conn_set_global_chanmap(uint8_t num_used_chans, const uint8_t *chanmap) */ #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) int -ble_ll_conn_slave_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr, - bool force_csa2) +ble_ll_conn_periph_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr, + bool force_csa2) { int rc; uint32_t temp; @@ -3634,26 +3633,26 @@ ble_ll_conn_slave_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr, connsm->tx_win_size = dptr[7]; connsm->tx_win_off = get_le16(dptr + 8); connsm->conn_itvl = get_le16(dptr + 10); - connsm->slave_latency = get_le16(dptr + 12); + connsm->periph_latency = get_le16(dptr + 12); connsm->supervision_tmo = get_le16(dptr + 14); memcpy(&connsm->chanmap, dptr + 16, BLE_LL_CONN_CHMAP_LEN); connsm->hop_inc = dptr[21] & 0x1F; - connsm->master_sca = dptr[21] >> 5; + connsm->central_sca = dptr[21] >> 5; /* Error check parameters */ if ((connsm->tx_win_off > connsm->conn_itvl) || (connsm->conn_itvl < BLE_HCI_CONN_ITVL_MIN) || (connsm->conn_itvl > BLE_HCI_CONN_ITVL_MAX) || (connsm->tx_win_size < BLE_LL_CONN_TX_WIN_MIN) || - (connsm->slave_latency > BLE_LL_CONN_SLAVE_LATENCY_MAX)) { - goto err_slave_start; + (connsm->periph_latency > BLE_LL_CONN_PERIPH_LATENCY_MAX)) { + goto err_periph_start; } /* Slave latency cannot cause a supervision timeout */ - temp = (connsm->slave_latency + 1) * (connsm->conn_itvl * 2) * - BLE_LL_CONN_ITVL_USECS; + temp = (connsm->periph_latency + 1) * (connsm->conn_itvl * 2) * + BLE_LL_CONN_ITVL_USECS; if ((connsm->supervision_tmo * 10000) <= temp ) { - goto err_slave_start; + goto err_periph_start; } /* @@ -3665,7 +3664,7 @@ ble_ll_conn_slave_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr, temp = 8; } if (connsm->tx_win_size > temp) { - goto err_slave_start; + goto err_periph_start; } /* Set the address of device that we are connecting with */ @@ -3675,14 +3674,14 @@ ble_ll_conn_slave_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr, /* Calculate number of used channels; make sure it meets min requirement */ connsm->num_used_chans = ble_ll_utils_calc_num_used_chans(connsm->chanmap); if (connsm->num_used_chans < 2) { - goto err_slave_start; + goto err_periph_start; } ble_ll_conn_itvl_to_ticks(connsm->conn_itvl, &connsm->conn_itvl_ticks, &connsm->conn_itvl_usecs); /* Start the connection state machine */ - connsm->conn_role = BLE_LL_CONN_ROLE_SLAVE; + connsm->conn_role = BLE_LL_CONN_ROLE_PERIPHERAL; ble_ll_conn_sm_new(connsm); #if (BLE_LL_BT5_PHY_SUPPORTED == 1) @@ -3702,9 +3701,9 @@ ble_ll_conn_slave_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr, } return rc; -err_slave_start: +err_periph_start: STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe); - STATS_INC(ble_ll_conn_stats, slave_rxd_bad_conn_req_params); + STATS_INC(ble_ll_conn_stats, periph_rxd_bad_conn_req_params); return 0; } #endif @@ -3791,8 +3790,8 @@ ble_ll_conn_module_reset(void) /* Mask in all channels by default */ conn_params->num_used_chans = BLE_PHY_NUM_DATA_CHANS; - memset(conn_params->master_chan_map, 0xff, BLE_LL_CONN_CHMAP_LEN - 1); - conn_params->master_chan_map[4] = 0x1f; + memset(conn_params->central_chan_map, 0xff, BLE_LL_CONN_CHMAP_LEN - 1); + conn_params->central_chan_map[4] = 0x1f; /* Reset statistics */ STATS_RESET(ble_ll_conn_stats); diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index bee9a5621b..8a90ed763f 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -162,7 +162,7 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: if (connsm->inita_identity_used) { /* We used identity address in CONNECT_IND which can be just * fine if @@ -180,7 +180,7 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: + case BLE_LL_CONN_ROLE_PERIPHERAL: rpa = ble_ll_adv_get_local_rpa(advsm); break; #endif @@ -203,12 +203,12 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, if (enh_ev->peer_addr_type > BLE_HCI_CONN_PEER_ADDR_RANDOM) { switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: rpa = ble_ll_scan_get_peer_rpa(); break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: + case BLE_LL_CONN_ROLE_PERIPHERAL: rpa = ble_ll_adv_get_peer_rpa(advsm); break; #endif @@ -221,11 +221,11 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, } enh_ev->conn_itvl = htole16(connsm->conn_itvl); - enh_ev->conn_latency = htole16(connsm->slave_latency); + enh_ev->conn_latency = htole16(connsm->periph_latency); enh_ev->supervision_timeout = htole16(connsm->supervision_tmo); #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { - enh_ev->mca = connsm->master_sca; + if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { + enh_ev->mca = connsm->central_sca; } #endif } @@ -250,11 +250,11 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, ev->peer_addr_type = connsm->peer_addr_type; memcpy(ev->peer_addr, connsm->peer_addr, BLE_DEV_ADDR_LEN); ev->conn_itvl = htole16(connsm->conn_itvl); - ev->conn_latency = htole16(connsm->slave_latency); + ev->conn_latency = htole16(connsm->periph_latency); ev->supervision_timeout = htole16(connsm->supervision_tmo); #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { - ev->mca = connsm->master_sca; + if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { + ev->mca = connsm->central_sca; } #endif } @@ -583,7 +583,7 @@ ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len) } /* Initialize state machine in master role and start state machine */ - ble_ll_conn_master_init(connsm, &cc_scan, &cc_params); + ble_ll_conn_central_init(connsm, &cc_scan, &cc_params); ble_ll_conn_sm_new(connsm); /* Start scanning */ @@ -771,8 +771,8 @@ ble_ll_conn_hci_ext_create(const uint8_t *cmdbuf, uint8_t len) } /* Initialize state machine in master role and start state machine */ - ble_ll_conn_master_init(connsm, &cc_scan, - &g_ble_ll_conn_create_sm.params[0]); + ble_ll_conn_central_init(connsm, &cc_scan, + &g_ble_ll_conn_create_sm.params[0]); ble_ll_conn_sm_new(connsm); /* Start scanning */ @@ -854,8 +854,8 @@ ble_ll_conn_hci_read_rem_features(const uint8_t *cmdbuf, uint8_t len) if (!connsm->csmflags.cfbit.rxd_features && !IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG)) { #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - if ((connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) && - !(ble_ll_read_supp_features() & BLE_LL_FEAT_SLAVE_INIT)) { + if ((connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) && + !(ble_ll_read_supp_features() & BLE_LL_FEAT_PERIPH_INIT)) { return BLE_ERR_CMD_DISALLOWED; } #endif @@ -910,7 +910,7 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) /* See if this feature is supported on both sides */ if ((connsm->conn_features & BLE_LL_FEAT_CONN_PARM_REQ) == 0) { #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { return BLE_ERR_UNSUPP_REM_FEATURE; } #endif @@ -928,7 +928,7 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) if (connsm->csmflags.cfbit.awaiting_host_reply) { switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: connsm->csmflags.cfbit.awaiting_host_reply = 0; /* XXX: If this fails no reject ind will be sent! */ @@ -937,7 +937,7 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: + case BLE_LL_CONN_ROLE_PERIPHERAL: return BLE_ERR_LMP_COLLISION; break; #endif @@ -953,7 +953,7 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) */ #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->csmflags.cfbit.chanmap_update_scheduled) { - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { return BLE_ERR_DIFF_TRANS_COLL; } } @@ -1468,7 +1468,7 @@ ble_ll_conn_hci_le_start_encrypt(const uint8_t *cmdbuf, uint8_t len) if (!connsm) { rc = BLE_ERR_UNK_CONN_ID; #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - } else if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + } else if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { rc = BLE_ERR_UNSPECIFIED; #endif } else if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_ENCRYPT) { @@ -1525,7 +1525,7 @@ ble_ll_conn_hci_le_ltk_reply(const uint8_t *cmdbuf, uint8_t len, #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Should never get this if we are a master! */ - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { rc = BLE_ERR_UNSPECIFIED; goto ltk_key_cmd_complete; } @@ -1584,7 +1584,7 @@ ble_ll_conn_hci_le_ltk_neg_reply(const uint8_t *cmdbuf, uint8_t len, #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Should never get this if we are a master! */ - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { rc = BLE_ERR_UNSPECIFIED; goto ltk_key_cmd_complete; } @@ -1717,7 +1717,7 @@ ble_ll_conn_hci_wr_auth_pyld_tmo(const uint8_t *cmdbuf, uint8_t len, */ tmo = le16toh(cmd->tmo); min_tmo = (uint32_t)connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS; - min_tmo *= (connsm->slave_latency + 1); + min_tmo *= (connsm->periph_latency + 1); min_tmo /= 10000; if (tmo < min_tmo) { diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index 73e4106074..c51aef90eb 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -47,7 +47,7 @@ extern "C" { #define BLE_LL_CONN_TX_OFF_USECS (1250) #define BLE_LL_CONN_CE_USECS (625) #define BLE_LL_CONN_TX_WIN_MIN (1) /* in tx win units */ -#define BLE_LL_CONN_SLAVE_LATENCY_MAX (499) +#define BLE_LL_CONN_PERIPH_LATENCY_MAX (499) /* Connection handle range */ #define BLE_LL_CONN_MAX_CONN_HANDLE (0x0EFF) @@ -62,7 +62,7 @@ extern "C" { /* Global Link Layer connection parameters */ struct ble_ll_conn_global_params { - uint8_t master_chan_map[BLE_LL_CONN_CHMAP_LEN]; + uint8_t central_chan_map[BLE_LL_CONN_CHMAP_LEN]; uint8_t num_used_chans; #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) uint8_t supp_max_tx_octets; @@ -154,16 +154,16 @@ void ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err); void ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm *connsm, struct os_mbuf *om, uint8_t hdr_byte, uint16_t length); struct ble_ll_conn_sm *ble_ll_conn_sm_get(void); -void ble_ll_conn_master_init(struct ble_ll_conn_sm *connsm, - struct ble_ll_conn_create_scan *cc_scan, - struct ble_ll_conn_create_params *cc_params); +void ble_ll_conn_central_init(struct ble_ll_conn_sm *connsm, + struct ble_ll_conn_create_scan *cc_scan, + struct ble_ll_conn_create_params *cc_params); struct ble_ll_conn_sm *ble_ll_conn_find_active_conn(uint16_t handle); void ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm); /* Advertising interface */ -int ble_ll_conn_slave_start(uint8_t *rxbuf, uint8_t pat, - struct ble_mbuf_hdr *rxhdr, bool force_csa2); +int ble_ll_conn_periph_start(uint8_t *rxbuf, uint8_t pat, + struct ble_mbuf_hdr *rxhdr, bool force_csa2); /* Link Layer interface */ void ble_ll_conn_module_init(void); diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index aef2d021bc..609fc5db94 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -98,7 +98,7 @@ const uint8_t g_ble_ll_ctrl_pkt_lengths[BLE_LL_CTRL_OPCODES] = BLE_LL_CTRL_PAUSE_ENC_RSP_LEN, BLE_LL_CTRL_VERSION_IND_LEN, BLE_LL_CTRL_REJ_IND_LEN, - BLE_LL_CTRL_SLAVE_FEATURE_REQ_LEN, + BLE_LL_CTRL_PERIPH_FEATURE_REQ_LEN, BLE_LL_CTRL_CONN_PARAMS_LEN, BLE_LL_CTRL_CONN_PARAMS_LEN, BLE_LL_CTRL_REJECT_IND_EXT_LEN, @@ -311,7 +311,7 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr, if ((connsm->conn_itvl >= req->interval_min) && (connsm->conn_itvl <= req->interval_max) && (connsm->supervision_tmo == req->timeout) && - (connsm->slave_latency == req->latency)) { + (connsm->periph_latency == req->latency)) { indicate = 0; goto conn_parm_req_do_indicate; } @@ -324,7 +324,7 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * update the connection parameters. This means that the previous * check is all we need for a master (when receiving a request). */ - if (CONN_IS_SLAVE(connsm) || (opcode == BLE_LL_CTRL_CONN_PARM_RSP)) { + if (CONN_IS_PERIPHERAL(connsm) || (opcode == BLE_LL_CTRL_CONN_PARM_RSP)) { /* * Not sure what to do about the slave. It is possible that the * current connection parameters are not the same ones as the local host @@ -408,7 +408,7 @@ ble_ll_ctrl_conn_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld, * request will actually get sent. We add one more event plus the * minimum as per the spec of 6 connection events. */ - instant = connsm->event_cntr + connsm->slave_latency + 6 + 1; + instant = connsm->event_cntr + connsm->periph_latency + 6 + 1; /* * XXX: This should change in the future, but for now we will just @@ -491,14 +491,14 @@ ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t * case BLE_LL_CTRL_CONN_UPDATE_IND: ctrl_proc = BLE_LL_CTRL_PROC_CONN_UPDATE; break; - case BLE_LL_CTRL_SLAVE_FEATURE_REQ: + case BLE_LL_CTRL_PERIPH_FEATURE_REQ: ctrl_proc = BLE_LL_CTRL_PROC_FEATURE_XCHG; - BLE_LL_CONN_CLEAR_FEATURE(connsm, BLE_LL_FEAT_SLAVE_INIT); + BLE_LL_CONN_CLEAR_FEATURE(connsm, BLE_LL_FEAT_PERIPH_INIT); break; case BLE_LL_CTRL_CONN_PARM_REQ: BLE_LL_CONN_CLEAR_FEATURE(connsm, BLE_LL_FEAT_CONN_PARM_REQ); #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { ble_ll_ctrl_conn_upd_make(connsm, rspdata, NULL); connsm->reject_reason = BLE_ERR_SUCCESS; return BLE_LL_CTRL_CONN_UPDATE_IND; @@ -723,19 +723,19 @@ ble_ll_ctrl_find_new_phy(uint8_t phy_mask_prefs) * @param connsm Pointer to connection state machine * @param dptr Pointer to PHY_REQ or PHY_RSP data. * @param ctrdata: Pointer to where CtrData of UPDATE_IND pdu starts - * @param slave_req flag denoting if slave requested this. 0: no 1:yes + * @param periph_req flag denoting if slave requested this. 0: no 1:yes */ static void ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, - uint8_t *ctrdata, int slave_req) + uint8_t *ctrdata, int periph_req) { uint8_t m_to_s; uint8_t s_to_m; uint8_t tx_phys; uint8_t rx_phys; uint16_t instant; - uint8_t is_slave_sym = 0; + uint8_t is_periph_sym = 0; /* Get preferences from PDU */ tx_phys = dptr[0]; @@ -743,14 +743,14 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, /* If we are master, check if slave requested symmetric PHY */ #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { - is_slave_sym = tx_phys == rx_phys; - is_slave_sym &= __builtin_popcount(tx_phys) == 1; + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + is_periph_sym = tx_phys == rx_phys; + is_periph_sym &= __builtin_popcount(tx_phys) == 1; } #endif /* Get m_to_s and s_to_m masks */ - if (slave_req) { + if (periph_req) { m_to_s = connsm->phy_data.host_pref_tx_phys_mask & rx_phys; s_to_m = connsm->phy_data.host_pref_rx_phys_mask & tx_phys; } else { @@ -758,7 +758,7 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, s_to_m = connsm->phy_data.req_pref_rx_phys_mask & tx_phys; } - if (is_slave_sym) { + if (is_periph_sym) { /* * If either s_to_m or m_to_s is 0, it means for at least one direction * requested PHY is not our preferred one so make sure we keep current @@ -811,7 +811,7 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, instant = 0; } else { /* Determine instant we will use. 6 more is minimum */ - instant = connsm->event_cntr + connsm->slave_latency + 6 + 1; + instant = connsm->event_cntr + connsm->periph_latency + 6 + 1; connsm->phy_instant = instant; CONN_F_PHY_UPDATE_SCHED(connsm) = 1; @@ -890,7 +890,7 @@ ble_ll_ctrl_rx_phy_req(struct ble_ll_conn_sm *connsm, uint8_t *req, switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: if (err) { ble_ll_ctrl_rej_ext_ind_make(BLE_LL_CTRL_PHY_REQ, err, rsp); rsp_opcode = BLE_LL_CTRL_REJECT_IND_EXT; @@ -906,7 +906,7 @@ ble_ll_ctrl_rx_phy_req(struct ble_ll_conn_sm *connsm, uint8_t *req, break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: + case BLE_LL_CONN_ROLE_PERIPHERAL: /* XXX: deal with other control procedures that we need to stop */ if (err) { if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_PHY_UPDATE) { @@ -963,7 +963,7 @@ ble_ll_ctrl_rx_phy_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_PHY_UPDATE) { ble_ll_ctrl_phy_update_ind_make(connsm, dptr, rsp, 0); ble_npl_callout_stop(&connsm->ctrl_proc_rsp_timer); @@ -979,7 +979,7 @@ ble_ll_ctrl_rx_phy_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: + case BLE_LL_CONN_ROLE_PERIPHERAL: rsp_opcode = BLE_LL_CTRL_UNKNOWN_RSP; break; #endif @@ -1015,7 +1015,7 @@ ble_ll_ctrl_rx_phy_update_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr) uint16_t delta; #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { return BLE_LL_CTRL_UNKNOWN_RSP; } #endif @@ -1117,8 +1117,8 @@ static uint8_t ble_ll_ctrl_rx_sca_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t *rsp) { - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { - connsm->master_sca = dptr[0]; + if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { + connsm->central_sca = dptr[0]; } ble_ll_ctrl_sca_req_rsp_make(connsm, rsp); @@ -1141,8 +1141,8 @@ ble_ll_ctrl_rx_sca_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr) return BLE_LL_CTRL_UNKNOWN_RSP; } - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { - connsm->master_sca = dptr[0]; + if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { + connsm->central_sca = dptr[0]; } ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_SCA_UPDATE); @@ -1486,7 +1486,7 @@ ble_ll_ctrl_rx_enc_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t *rspdata) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { return BLE_LL_CTRL_UNKNOWN_RSP; } #endif @@ -1535,7 +1535,7 @@ ble_ll_ctrl_rx_start_enc_req(struct ble_ll_conn_sm *connsm) switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: /* We only want to send a START_ENC_RSP if we havent yet */ if (connsm->enc_data.enc_state == CONN_ENC_S_START_ENC_REQ_WAIT) { connsm->enc_data.enc_state = CONN_ENC_S_START_ENC_RSP_WAIT; @@ -1544,7 +1544,7 @@ ble_ll_ctrl_rx_start_enc_req(struct ble_ll_conn_sm *connsm) break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: + case BLE_LL_CONN_ROLE_PERIPHERAL: rc = BLE_LL_CTRL_UNKNOWN_RSP; break; #endif @@ -1567,7 +1567,7 @@ ble_ll_ctrl_rx_pause_enc_req(struct ble_ll_conn_sm *connsm) * ignore it... */ rc = BLE_ERR_MAX; - if (CONN_IS_SLAVE(connsm) && + if (CONN_IS_PERIPHERAL(connsm) && (connsm->enc_data.enc_state == CONN_ENC_S_ENCRYPTED)) { rc = BLE_LL_CTRL_PAUSE_ENC_RSP; } else { @@ -1592,12 +1592,12 @@ ble_ll_ctrl_rx_pause_enc_rsp(struct ble_ll_conn_sm *connsm) switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: rc = BLE_LL_CTRL_PAUSE_ENC_RSP; break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: + case BLE_LL_CONN_ROLE_PERIPHERAL: if (connsm->enc_data.enc_state == CONN_ENC_S_PAUSE_ENC_RSP_WAIT) { /* Master sends back unencrypted LL_PAUSE_ENC_RSP. * From this moment encryption is paused. @@ -1638,7 +1638,7 @@ ble_ll_ctrl_rx_start_enc_rsp(struct ble_ll_conn_sm *connsm) switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_ENCRYPT); /* We are encrypted */ @@ -1650,7 +1650,7 @@ ble_ll_ctrl_rx_start_enc_rsp(struct ble_ll_conn_sm *connsm) break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: + case BLE_LL_CONN_ROLE_PERIPHERAL: /* Procedure has completed but slave needs to send START_ENC_RSP */ rc = BLE_LL_CTRL_START_ENC_RSP; @@ -1750,11 +1750,11 @@ static void ble_ll_ctrl_chanmap_req_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld) { /* Copy channel map that host desires into request */ - memcpy(pyld, g_ble_ll_conn_params.master_chan_map, BLE_LL_CONN_CHMAP_LEN); + memcpy(pyld, g_ble_ll_conn_params.central_chan_map, BLE_LL_CONN_CHMAP_LEN); memcpy(connsm->req_chanmap, pyld, BLE_LL_CONN_CHMAP_LEN); /* Place instant into request */ - connsm->chanmap_instant = connsm->event_cntr + connsm->slave_latency + 6 + 1; + connsm->chanmap_instant = connsm->event_cntr + connsm->periph_latency + 6 + 1; put_le16(pyld + BLE_LL_CONN_CHMAP_LEN, connsm->chanmap_instant); /* Set scheduled flag */ @@ -1779,14 +1779,14 @@ ble_ll_ctrl_conn_param_reply(struct ble_ll_conn_sm *connsm, uint8_t *rsp, switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: /* Create a connection update pdu */ ble_ll_ctrl_conn_upd_make(connsm, rsp + 1, req); rsp_opcode = BLE_LL_CTRL_CONN_UPDATE_IND; break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: + case BLE_LL_CONN_ROLE_PERIPHERAL: /* Create a connection parameter response */ ble_ll_ctrl_conn_param_pdu_make(connsm, rsp + 1, req); rsp_opcode = BLE_LL_CTRL_CONN_PARM_RSP; @@ -1829,7 +1829,7 @@ ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, if (opcode == BLE_LL_CTRL_REJECT_IND_EXT) { switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: /* As a master we should send connection update indication in this point */ rsp_opcode = BLE_LL_CTRL_CONN_UPDATE_IND; ble_ll_ctrl_conn_upd_make(connsm, rspdata, NULL); @@ -1837,7 +1837,7 @@ ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: + case BLE_LL_CONN_ROLE_PERIPHERAL: ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ); ble_ll_hci_ev_conn_update(connsm, ble_error); break; @@ -1898,7 +1898,7 @@ ble_ll_ctrl_rx_conn_update(struct ble_ll_conn_sm *connsm, uint8_t *dptr) /* Only a slave should receive this */ #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { return BLE_LL_CTRL_UNKNOWN_RSP; } #endif @@ -2019,13 +2019,13 @@ ble_ll_ctrl_rx_feature_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * Only accept slave feature requests if we are a master and feature * requests if we are a slave. */ - if (opcode == BLE_LL_CTRL_SLAVE_FEATURE_REQ) { - if (!CONN_IS_MASTER(connsm)) { + if (opcode == BLE_LL_CTRL_PERIPH_FEATURE_REQ) { + if (!CONN_IS_CENTRAL(connsm)) { return BLE_LL_CTRL_UNKNOWN_RSP; } } else { /* XXX: not sure this is correct but do it anyway */ - if (!CONN_IS_SLAVE(connsm)) { + if (!CONN_IS_PERIPHERAL(connsm)) { return BLE_LL_CTRL_UNKNOWN_RSP; } } @@ -2127,7 +2127,7 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ)) { switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: /* The master sends reject ind ext w/error code 0x23 */ rsp_opcode = BLE_LL_CTRL_REJECT_IND_EXT; rspbuf[1] = BLE_LL_CTRL_CONN_PARM_REQ; @@ -2135,7 +2135,7 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, return rsp_opcode; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: + case BLE_LL_CONN_ROLE_PERIPHERAL: ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ); ble_ll_hci_ev_conn_update(connsm, BLE_ERR_LMP_COLLISION); break; @@ -2151,7 +2151,7 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * update procedure we need to return an error */ #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - if ((connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) && + if ((connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) && (connsm->csmflags.cfbit.chanmap_update_scheduled)) { rsp_opcode = BLE_LL_CTRL_REJECT_IND_EXT; rspbuf[1] = BLE_LL_CTRL_CONN_PARM_REQ; @@ -2174,7 +2174,7 @@ ble_ll_ctrl_rx_conn_param_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, /* A slave should never receive this response */ #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { return BLE_LL_CTRL_UNKNOWN_RSP; } #endif @@ -2252,7 +2252,7 @@ ble_ll_ctrl_rx_chanmap_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr) uint16_t conn_events; #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { return BLE_LL_CTRL_UNKNOWN_RSP; } #endif @@ -2312,13 +2312,13 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc) case BLE_LL_CTRL_PROC_FEATURE_XCHG: switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: opcode = BLE_LL_CTRL_FEATURE_REQ; break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: - opcode = BLE_LL_CTRL_SLAVE_FEATURE_REQ; + case BLE_LL_CONN_ROLE_PERIPHERAL: + opcode = BLE_LL_CTRL_PERIPH_FEATURE_REQ; break; #endif default: @@ -2645,8 +2645,8 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) case BLE_LL_CTRL_LENGTH_REQ: feature = BLE_LL_FEAT_DATA_LEN_EXT; break; - case BLE_LL_CTRL_SLAVE_FEATURE_REQ: - feature = BLE_LL_FEAT_SLAVE_INIT; + case BLE_LL_CTRL_PERIPH_FEATURE_REQ: + feature = BLE_LL_FEAT_PERIPH_INIT; break; case BLE_LL_CTRL_CONN_PARM_REQ: case BLE_LL_CTRL_CONN_PARM_RSP: @@ -2759,7 +2759,7 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) case BLE_LL_CTRL_VERSION_IND: rsp_opcode = ble_ll_ctrl_rx_version_ind(connsm, dptr, rspdata); break; - case BLE_LL_CTRL_SLAVE_FEATURE_REQ: + case BLE_LL_CTRL_PERIPH_FEATURE_REQ: rsp_opcode = ble_ll_ctrl_rx_feature_req(connsm, dptr, rspbuf, opcode); break; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) @@ -2986,7 +2986,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) break; #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_CTRL_START_ENC_RSP: - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { connsm->enc_data.enc_state = CONN_ENC_S_ENCRYPTED; if (CONN_F_LE_PING_SUPP(connsm)) { ble_ll_conn_auth_pyld_timer_start(connsm); @@ -2994,7 +2994,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) } break; case BLE_LL_CTRL_PAUSE_ENC_RSP: - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { connsm->enc_data.enc_state = CONN_ENC_S_PAUSE_ENC_RSP_WAIT; } break; @@ -3003,7 +3003,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) #if (BLE_LL_BT5_PHY_SUPPORTED == 1) #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_CTRL_PHY_REQ: - if (connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { connsm->phy_tx_transition = ble_ll_ctrl_phy_tx_transition_get( connsm->phy_data.req_pref_tx_phys_mask); diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index 9d6c39ecc0..c39a833477 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -117,7 +117,7 @@ ble_ll_hci_ev_conn_update(struct ble_ll_conn_sm *connsm, uint8_t status) ev->status = status; ev->conn_handle = htole16(connsm->conn_handle); ev->conn_itvl = htole16(connsm->conn_itvl); - ev->conn_latency = htole16(connsm->slave_latency); + ev->conn_latency = htole16(connsm->periph_latency); ev->supervision_timeout = htole16(connsm->supervision_tmo); ble_ll_hci_event_send(hci_ev); diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 8f9a2d5c28..4a7051cc6d 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -370,13 +370,13 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) sch->start_time = connsm->anchor_point - g_ble_ll_sched_offset_ticks; switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_MASTER: + case BLE_LL_CONN_ROLE_CENTRAL: sch->remainder = connsm->anchor_point_usecs; break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_SLAVE: - usecs = connsm->slave_cur_window_widening; + case BLE_LL_CONN_ROLE_PERIPHERAL: + usecs = connsm->periph_cur_window_widening; sch->start_time -= (ble_ll_tmr_u2t(usecs) + 1); sch->remainder = 0; break; @@ -422,8 +422,8 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) */ #if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) int -ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, - struct ble_mbuf_hdr *ble_hdr, uint8_t pyld_len) +ble_ll_sched_central_new(struct ble_ll_conn_sm *connsm, + struct ble_mbuf_hdr *ble_hdr, uint8_t pyld_len) { int rc; os_sr_t sr; @@ -656,8 +656,8 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, } #else int -ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, - struct ble_mbuf_hdr *ble_hdr, uint8_t pyld_len) +ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, + struct ble_mbuf_hdr *ble_hdr, uint8_t pyld_len) { struct ble_ll_sched_item *sch; uint32_t orig_start_time; @@ -790,7 +790,7 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm, * @return int */ int -ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm) +ble_ll_sched_conn_periph_new(struct ble_ll_conn_sm *connsm) { struct ble_ll_sched_item *sch; os_sr_t sr; @@ -807,7 +807,7 @@ ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm) * usecs to ticks could be off by up to 1 tick. */ sch->start_time = connsm->anchor_point - g_ble_ll_sched_offset_ticks - - ble_ll_tmr_u2t(connsm->slave_cur_window_widening) - 1; + ble_ll_tmr_u2t(connsm->periph_cur_window_widening) - 1; sch->end_time = connsm->ce_end_time; sch->remainder = 0; diff --git a/nimble/controller/src/ble_ll_utils.c b/nimble/controller/src/ble_ll_utils.c index e2fe50c2b5..66ca3e27a8 100644 --- a/nimble/controller/src/ble_ll_utils.c +++ b/nimble/controller/src/ble_ll_utils.c @@ -281,7 +281,7 @@ ble_ll_utils_calc_dci_csa2(uint16_t event_cntr, uint16_t channel_id, uint32_t ble_ll_utils_calc_window_widening(uint32_t anchor_point, uint32_t last_anchor_point, - uint8_t master_sca) + uint8_t central_sca) { uint32_t total_sca_ppm; uint32_t window_widening; @@ -293,7 +293,7 @@ ble_ll_utils_calc_window_widening(uint32_t anchor_point, time_since_last_anchor = (int32_t)(anchor_point - last_anchor_point); if (time_since_last_anchor > 0) { delta_msec = ble_ll_tmr_t2u(time_since_last_anchor) / 1000; - total_sca_ppm = g_ble_sca_ppm_tbl[master_sca] + MYNEWT_VAL(BLE_LL_SCA); + total_sca_ppm = g_ble_sca_ppm_tbl[central_sca] + MYNEWT_VAL(BLE_LL_SCA); window_widening = (total_sca_ppm * delta_msec) / 1000; } diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 9f17350e44..e628a8aa57 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -219,7 +219,7 @@ syscfg.defs: by default. value: 'MYNEWT_VAL_BLE_LL_ROLE_CENTRAL || MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL' - BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG: + BLE_LL_CFG_FEAT_PERIPH_INIT_FEAT_XCHG: description: > This option allows a slave to initiate the feature exchange procedure. This feature is implemented but currently has no impact @@ -503,7 +503,10 @@ syscfg.defs: description: use BLE_LL_SCA instead value: 4 defunct: 1 - + BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG: + description: Superseded by BLE_LL_CFG_FEAT_PERIPH_INIT_FEAT_XCHG + value: 0 + defaunt: 1 syscfg.vals.BLE_LL_CFG_FEAT_LL_EXT_ADV: BLE_LL_CFG_FEAT_LE_CSA2: 1 diff --git a/nimble/drivers/nrf5340/src/ble_phy.c b/nimble/drivers/nrf5340/src/ble_phy.c index 8ec90cdae3..9734e88783 100644 --- a/nimble/drivers/nrf5340/src/ble_phy.c +++ b/nimble/drivers/nrf5340/src/ble_phy.c @@ -1526,12 +1526,12 @@ ble_phy_rx(void) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) void ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key, - uint8_t is_master) + uint8_t is_central) { memcpy(nrf_ccm_data.key, key, 16); nrf_ccm_data.pkt_counter = pkt_counter; memcpy(nrf_ccm_data.iv, iv, 8); - nrf_ccm_data.dir_bit = is_master; + nrf_ccm_data.dir_bit = is_central; g_ble_phy_data.phy_encrypted = 1; /* Enable the module (AAR cannot be on while CCM on) */ NRF_AAR_NS->ENABLE = AAR_ENABLE_ENABLE_Disabled; From cd1706b91722dc13c710541b7d11e470c1dd80b3 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 8 Feb 2022 13:24:51 +0100 Subject: [PATCH 0264/1333] nimble/ll: Fix master/slave in comments --- nimble/controller/src/ble_ll_adv.c | 2 +- nimble/controller/src/ble_ll_conn.c | 64 +++++++++---------- nimble/controller/src/ble_ll_conn_hci.c | 24 ++++---- nimble/controller/src/ble_ll_ctrl.c | 82 ++++++++++++------------- nimble/controller/src/ble_ll_sched.c | 42 ++++++------- nimble/controller/src/ble_ll_sync.c | 2 +- 6 files changed, 108 insertions(+), 108 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 5f024da99a..d8d251bae3 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -4400,7 +4400,7 @@ ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, struct ble_mbuf_hdr *hdr, } #endif - /* Try to start slave connection. If successful, stop advertising */ + /* Try to start peripheral connection. If successful, stop advertising */ valid = ble_ll_conn_periph_start(rxbuf, addr_type, hdr, !(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)); diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 7824f1df0a..33a666aeba 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -62,8 +62,8 @@ extern void bletest_completed_pkt(uint16_t handle); * 2) Make sure we check incoming data packets for size and all that. You * know, supported octets and all that. For both rx and tx. * - * 3) Make sure we are setting the schedule end time properly for both slave - * and master. We should just set this to the end of the connection event. + * 3) Make sure we are setting the schedule end time properly for both peripheral + * and central. We should just set this to the end of the connection event. * We might want to guarantee a IFS time as well since the next event needs * to be scheduled prior to the start of the event to account for the time it * takes to get a frame ready (which is pretty much the IFS time). @@ -83,15 +83,15 @@ extern void bletest_completed_pkt(uint16_t handle); * * 8) Right now I use a fixed definition for required slots. CHange this. * - * 10) See what connection state machine elements are purely master and - * purely slave. We can make a union of them. + * 10) See what connection state machine elements are purely central and + * purely peripheral. We can make a union of them. * * 11) Not sure I am dealing with the connection terminate timeout perfectly. * I may extend a connection event too long although if it is always in terms * of connection events I am probably fine. Checking at end that the next * connection event will occur past terminate timeould would be fine. * - * 12) When a slave receives a data packet in a connection it has to send a + * 12) When a peripheral receives a data packet in a connection it has to send a * response. Well, it should. If this packet will overrun the next scheduled * event, what should we do? Transmit anyway? Not transmit? For now, we just * transmit. @@ -666,7 +666,7 @@ ble_ll_conn_wfr_timer_exp(void) } /** - * Callback for slave when it transmits a data pdu and the connection event + * Callback for peripheral when it transmits a data pdu and the connection event * ends after the transmission. * * Context: Interrupt @@ -973,8 +973,8 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) /* * We will allow a next packet if it itself is allowed or we are - * a slave and we are sending the START_ENC_RSP. The master has - * to wait to receive the START_ENC_RSP from the slave before + * a peripheral and we are sending the START_ENC_RSP. The central has + * to wait to receive the START_ENC_RSP from the peripheral before * packets can be let go. */ if (nextpkthdr && !ble_ll_ctrl_enc_allowed_pdu_tx(nextpkthdr) @@ -1064,7 +1064,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) * -> wait IFS, send the next frame. * -> wait IFS, receive a maximum size frame. * - * For slave: + * For peripheral: * -> wait IFS, send current frame. * -> wait IFS, receive maximum size frame. * -> wait IFS, send next frame. @@ -1141,13 +1141,13 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) ble_hdr->txinfo.hdr_byte = hdr_byte; /* - * If we are a slave, check to see if this transmission will end the + * If we are a peripheral, check to see if this transmission will end the * connection event. We will end the connection event if we have * received a valid frame with the more data bit set to 0 and we dont * have more data. * - * XXX: for a slave, we dont check to see if we can: - * -> wait IFS, rx frame from master (either big or small). + * XXX: for a peripheral, we dont check to see if we can: + * -> wait IFS, rx frame from central (either big or small). * -> wait IFS, send empty pdu or next pdu. * * We could do this. Now, we just keep going and hope that we dont @@ -1179,7 +1179,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) if (is_ctrl && (opcode == BLE_LL_CTRL_START_ENC_RSP)) { /* - * Both master and slave send the START_ENC_RSP encrypted and receive + * Both central and peripheral send the START_ENC_RSP encrypted and receive * encrypted */ CONN_F_ENCRYPTED(connsm) = 1; @@ -1190,7 +1190,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) CONN_IS_CENTRAL(connsm)); } else if (is_ctrl && (opcode == BLE_LL_CTRL_START_ENC_REQ)) { /* - * Only the slave sends this and it gets sent unencrypted but + * Only the peripheral sends this and it gets sent unencrypted but * we receive encrypted */ CONN_F_ENCRYPTED(connsm) = 0; @@ -1204,7 +1204,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) } } else if (is_ctrl && (opcode == BLE_LL_CTRL_PAUSE_ENC_RSP)) { /* - * The slave sends the PAUSE_ENC_RSP encrypted. The master sends + * The peripheral sends the PAUSE_ENC_RSP encrypted. The central sends * it unencrypted (note that link was already set unencrypted). */ switch (connsm->conn_role) { @@ -1376,7 +1376,7 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) } #endif - /* XXX: what is this really for the slave? */ + /* XXX: what is this really for the peripheral? */ start = sch->start_time + g_ble_ll_sched_offset_ticks; rc = ble_phy_rx_set_start_time(start, sch->remainder); if (rc) { @@ -1385,14 +1385,14 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) rc = BLE_LL_SCHED_STATE_DONE; } else { /* - * Set flag that tells slave to set last anchor point if a packet + * Set flag that tells peripheral to set last anchor point if a packet * has been received. */ connsm->csmflags.cfbit.periph_set_last_anchor = 1; /* * Set the wait for response time. The anchor point is when we - * expect the master to start transmitting. Worst-case, we expect + * expect the central to start transmitting. Worst-case, we expect * to hear a reply within the anchor point plus: * -> current tx window size * -> current window widening amount (includes +/- 16 usec jitter) @@ -1441,9 +1441,9 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) /** * Called to determine if the device is allowed to send the next pdu in the - * connection event. This will always return 'true' if we are a slave. If we - * are a master, we must be able to send the next fragment and get a minimum - * sized response from the slave. + * connection event. This will always return 'true' if we are a peripheral. If we + * are a central, we must be able to send the next fragment and get a minimum + * sized response from the peripheral. * * Context: Interrupt context (rx end isr). * @@ -1590,7 +1590,7 @@ ble_ll_conn_central_common_init(struct ble_ll_conn_sm *connsm) } /** * Called when a create connection command has been received. This initializes - * a connection state machine in the master role. + * a connection state machine in the central role. * * NOTE: Must be called before the state machine is started * @@ -1715,7 +1715,7 @@ ble_ll_conn_set_csa(struct ble_ll_conn_sm *connsm, bool chsel) /** * Create a new connection state machine. This is done once per * connection when the HCI command "create connection" is issued to the - * controller or when a slave receives a connect request. + * controller or when a peripheral receives a connect request. * * Context: Link Layer task * @@ -2053,9 +2053,9 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) */ /* - * XXX TODO: I think this is technically incorrect. We can allow slave + * XXX TODO: I think this is technically incorrect. We can allow peripheral * latency if we are doing one of these updates as long as we - * know that the master has received the ACK to the PDU that set + * know that the central has received the ACK to the PDU that set * the instant */ /* Set event counter to the next connection event that we will tx/rx in */ @@ -2140,9 +2140,9 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) ((int16_t)(connsm->chanmap_instant - connsm->event_cntr) <= 0)) { /* XXX: there is a chance that the control packet is still on - * the queue of the master. This means that we never successfully + * the queue of the central. This means that we never successfully * transmitted update request. Would end up killing connection - on slave side. Could ignore it or see if still enqueued. */ + on peripheral side. Could ignore it or see if still enqueued. */ connsm->num_used_chans = ble_ll_utils_calc_num_used_chans(connsm->req_chanmap); memcpy(connsm->chanmap, connsm->req_chanmap, BLE_LL_CONN_CHMAP_LEN); @@ -2290,7 +2290,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) connsm->last_rxd_pdu_cputime = connsm->last_scheduled; /* - * Set first connection event time. If slave the endtime is the receive end + * Set first connection event time. If peripheral the endtime is the receive end * time of the connect request. The actual connection starts 1.25 msecs plus * the transmit window offset from the end of the connection request. */ @@ -2385,7 +2385,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) * * XXX we do this only as a central as it was observed that sending * LL_PERIPH_FEATURE_REQ after connection breaks some recent iPhone - * models; for slave just assume master will initiate features xchg + * models; for peripheral just assume central will initiate features xchg * if it has some additional features to use. */ ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG); @@ -3016,8 +3016,8 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) connsm->conn_rssi = hdr->rxinfo.rssi; /* - * If we are a slave, we can only start to use slave latency - * once we have received a NESN of 1 from the master + * If we are a peripheral, we can only start to use peripheral latency + * once we have received a NESN of 1 from the central */ #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { @@ -3577,7 +3577,7 @@ ble_ll_conn_set_global_chanmap(uint8_t num_used_chans, const uint8_t *chanmap) /** * Called when a device has received a connect request while advertising and * the connect request has passed the advertising filter policy and is for - * us. This will start a connection in the slave role assuming that we dont + * us. This will start a connection in the peripheral role assuming that we dont * already have a connection with this device and that the connect request * parameters are valid. * diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 8a90ed763f..6664458909 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -582,7 +582,7 @@ ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_CONN_LIMIT; } - /* Initialize state machine in master role and start state machine */ + /* Initialize state machine in central role and start state machine */ ble_ll_conn_central_init(connsm, &cc_scan, &cc_params); ble_ll_conn_sm_new(connsm); @@ -770,7 +770,7 @@ ble_ll_conn_hci_ext_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_CONN_LIMIT; } - /* Initialize state machine in master role and start state machine */ + /* Initialize state machine in central role and start state machine */ ble_ll_conn_central_init(connsm, &cc_scan, &g_ble_ll_conn_create_sm.params[0]); ble_ll_conn_sm_new(connsm); @@ -886,7 +886,7 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) struct hci_conn_update *hcu; /* - * XXX: must deal with slave not supporting this feature and using + * XXX: must deal with peripheral not supporting this feature and using * conn update! Right now, we only check if WE support the connection * parameters request procedure. We dont check if the remote does. * We should also be able to deal with sending the parameter request, @@ -920,10 +920,10 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) } /* - * If we are a slave and the master has initiated the procedure already - * we should deny the slave request for now. If we are a master and the - * slave has initiated the procedure, we need to send a reject to the - * slave. + * If we are a peripheral and the central has initiated the procedure already + * we should deny the peripheral request for now. If we are a central and the + * peripheral has initiated the procedure, we need to send a reject to the + * peripheral. */ if (connsm->csmflags.cfbit.awaiting_host_reply) { switch (connsm->conn_role) { @@ -948,8 +948,8 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) } /* - * If we are a slave and the master has initiated the channel map - * update procedure we should deny the slave request for now. + * If we are a peripheral and the central has initiated the channel map + * update procedure we should deny the peripheral request for now. */ #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->csmflags.cfbit.chanmap_update_scheduled) { @@ -1524,7 +1524,7 @@ ble_ll_conn_hci_le_ltk_reply(const uint8_t *cmdbuf, uint8_t len, } #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - /* Should never get this if we are a master! */ + /* Should never get this if we are a central! */ if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { rc = BLE_ERR_UNSPECIFIED; goto ltk_key_cmd_complete; @@ -1583,7 +1583,7 @@ ble_ll_conn_hci_le_ltk_neg_reply(const uint8_t *cmdbuf, uint8_t len, } #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - /* Should never get this if we are a master! */ + /* Should never get this if we are a central! */ if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { rc = BLE_ERR_UNSPECIFIED; goto ltk_key_cmd_complete; @@ -1713,7 +1713,7 @@ ble_ll_conn_hci_wr_auth_pyld_tmo(const uint8_t *cmdbuf, uint8_t len, } else { /* * The timeout is in units of 10 msecs. We need to make sure that the - * timeout is greater than or equal to connItvl * (1 + slaveLatency) + * timeout is greater than or equal to connItvl * (1 + peripheralLatency) */ tmo = le16toh(cmd->tmo); min_tmo = (uint32_t)connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS; diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 609fc5db94..62272d7120 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -319,14 +319,14 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr, /* * A change has been requested. Is it within the values specified by - * the host? Note that for a master we will not be processing a - * connect param request from a slave if we are currently trying to + * the host? Note that for a central we will not be processing a + * connect param request from a peripheral if we are currently trying to * update the connection parameters. This means that the previous - * check is all we need for a master (when receiving a request). + * check is all we need for a central (when receiving a request). */ if (CONN_IS_PERIPHERAL(connsm) || (opcode == BLE_LL_CTRL_CONN_PARM_RSP)) { /* - * Not sure what to do about the slave. It is possible that the + * Not sure what to do about the peripheral. It is possible that the * current connection parameters are not the same ones as the local host * has provided? Not sure what to do here. Do we need to remember what * host sent us? For now, I will assume that we need to remember what @@ -403,7 +403,7 @@ ble_ll_ctrl_conn_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld, /* * Set instant. We set the instant to the current event counter plus - * the amount of slave latency as the slave may not be listening + * the amount of peripheral latency as the peripheral may not be listening * at every connection interval and we are not sure when the connect * request will actually get sent. We add one more event plus the * minimum as per the spec of 6 connection events. @@ -723,7 +723,7 @@ ble_ll_ctrl_find_new_phy(uint8_t phy_mask_prefs) * @param connsm Pointer to connection state machine * @param dptr Pointer to PHY_REQ or PHY_RSP data. * @param ctrdata: Pointer to where CtrData of UPDATE_IND pdu starts - * @param periph_req flag denoting if slave requested this. 0: no 1:yes + * @param periph_req flag denoting if peripheral requested this. 0: no 1:yes */ static void @@ -741,7 +741,7 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, tx_phys = dptr[0]; rx_phys = dptr[1]; - /* If we are master, check if slave requested symmetric PHY */ + /* If we are central, check if peripheral requested symmetric PHY */ #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { is_periph_sym = tx_phys == rx_phys; @@ -765,9 +765,9 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * PHY in both directions * * Core 5.2, Vol 6, PartB, 5.1.10 - * If the slave specified a single PHY in both the TX_PHYS and - * RX_PHYS fields and both fields are the same, the master shall - * either select the PHY specified by the slave for both directions + * If the peripheral specified a single PHY in both the TX_PHYS and + * RX_PHYS fields and both fields are the same, the central shall + * either select the PHY specified by the peripheral for both directions * or shall leave both directions unchanged. */ if ((s_to_m == 0) || (m_to_s == 0)) { @@ -924,7 +924,7 @@ ble_ll_ctrl_rx_phy_req(struct ble_ll_conn_sm *connsm, uint8_t *req, /* XXX: TODO: if we started another procedure with an instant * why are we doing this? Need to look into this.*/ - /* Respond to master's phy update procedure */ + /* Respond to central's phy update procedure */ CONN_F_PEER_PHY_UPDATE(connsm) = 1; ble_ll_ctrl_phy_req_rsp_make(connsm, rsp); rsp_opcode = BLE_LL_CTRL_PHY_RSP; @@ -988,7 +988,7 @@ ble_ll_ctrl_rx_phy_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, break; } - /* NOTE: slave should never receive one of these */ + /* NOTE: peripheral should never receive one of these */ return rsp_opcode; } @@ -996,7 +996,7 @@ ble_ll_ctrl_rx_phy_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, /** * Called when a LL_PHY_UPDATE_IND pdu is received * - * NOTE: slave is the only device that should receive this. + * NOTE: peripheral is the only device that should receive this. * * @param connsm * @param dptr @@ -1044,8 +1044,8 @@ ble_ll_ctrl_rx_phy_update_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr) } else { no_change = 0; /* - * NOTE: from the slaves perspective, the m to s phy is the one - * that the slave will receive on; s to m is the one it will + * NOTE: from the peripherals perspective, the m to s phy is the one + * that the peripheral will receive on; s to m is the one it will * transmit on */ new_rx_phy = ble_ll_ctrl_phy_from_phy_mask(new_m_to_s_mask); @@ -1239,7 +1239,7 @@ ble_ll_calc_session_key(struct ble_ll_conn_sm *connsm) * XXX: the current code may actually allow some control pdu's to be sent * in states where they shouldnt. I dont expect those states to occur so I * dont try to check for them but we could do more... for example there are - * different PDUs allowed for master/slave and TX/RX + * different PDUs allowed for central/peripheral and TX/RX * * @param llid * @param opcode @@ -1398,7 +1398,7 @@ ble_ll_ctrl_cis_create(struct ble_ll_conn_sm *connsm, uint8_t *dptr) * IVm (4) * * The random number and encrypted diversifier come from the host command. - * Controller generates master portion of SDK and IV. + * Controller generates central portion of SDK and IV. * * NOTE: this function does not set the LL data pdu header nor does it * set the opcode in the buffer. @@ -1428,7 +1428,7 @@ ble_ll_ctrl_enc_req_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr) } /** - * Called when LL_ENC_RSP is received by the master. + * Called when LL_ENC_RSP is received by the central. * * Context: Link Layer Task. * @@ -1436,7 +1436,7 @@ ble_ll_ctrl_enc_req_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr) * SKDs (8) * IVs (4) * - * The master now has the long term key (from the start encrypt command) + * The central now has the long term key (from the start encrypt command) * and the SKD (stored in the plain text encryption block). From this the * sessionKey is generated. * @@ -1462,7 +1462,7 @@ ble_ll_ctrl_rx_enc_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr) /** * Called when we have received a LL control encryption request PDU. This - * should only be received by a slave. + * should only be received by a peripheral. * * The LL_ENC_REQ PDU format is: * Rand (8) @@ -1474,7 +1474,7 @@ ble_ll_ctrl_rx_enc_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr) * but it could be a reject ind. Note that the caller of this function * will send the REJECT_IND_EXT if supported by remote. * - * NOTE: if this is received by a master we will silently discard the PDU + * NOTE: if this is received by a central we will silently discard the PDU * (denoted by return BLE_ERR_MAX). * * @param connsm @@ -1530,7 +1530,7 @@ ble_ll_ctrl_rx_start_enc_req(struct ble_ll_conn_sm *connsm) { int rc; - /* Only master should receive start enc request */ + /* Only central should receive start enc request */ rc = BLE_ERR_MAX; switch (connsm->conn_role) { @@ -1651,7 +1651,7 @@ ble_ll_ctrl_rx_start_enc_rsp(struct ble_ll_conn_sm *connsm) #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_CONN_ROLE_PERIPHERAL: - /* Procedure has completed but slave needs to send START_ENC_RSP */ + /* Procedure has completed but peripheral needs to send START_ENC_RSP */ rc = BLE_LL_CTRL_START_ENC_RSP; /* Stop timer if it was started when sending START_ENC_REQ */ @@ -1667,7 +1667,7 @@ ble_ll_ctrl_rx_start_enc_rsp(struct ble_ll_conn_sm *connsm) /* * XXX: for now, a Slave sends this event when it receivest the - * START_ENC_RSP from the master. It might be technically incorrect + * START_ENC_RSP from the central. It might be technically incorrect * to send it before we transmit our own START_ENC_RSP. */ ble_ll_hci_ev_encrypt_chg(connsm, BLE_ERR_SUCCESS); @@ -1830,7 +1830,7 @@ ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_CONN_ROLE_CENTRAL: - /* As a master we should send connection update indication in this point */ + /* As a central we should send connection update indication in this point */ rsp_opcode = BLE_LL_CTRL_CONN_UPDATE_IND; ble_ll_ctrl_conn_upd_make(connsm, rspdata, NULL); connsm->reject_reason = BLE_ERR_SUCCESS; @@ -1896,7 +1896,7 @@ ble_ll_ctrl_rx_conn_update(struct ble_ll_conn_sm *connsm, uint8_t *dptr) uint16_t conn_events; struct ble_ll_conn_upd_req *reqdata; - /* Only a slave should receive this */ + /* Only a peripheral should receive this */ #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { return BLE_LL_CTRL_UNKNOWN_RSP; @@ -1996,7 +1996,7 @@ ble_ll_ctrl_update_features(struct ble_ll_conn_sm *connsm, uint8_t *feat) } /** - * Called when we receive a feature request or a slave initiated feature + * Called when we receive a feature request or a peripheral initiated feature * request. * * @@ -2016,8 +2016,8 @@ ble_ll_ctrl_rx_feature_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint64_t our_feat; /* - * Only accept slave feature requests if we are a master and feature - * requests if we are a slave. + * Only accept peripheral feature requests if we are a central and feature + * requests if we are a peripheral. */ if (opcode == BLE_LL_CTRL_PERIPH_FEATURE_REQ) { if (!CONN_IS_CENTRAL(connsm)) { @@ -2106,7 +2106,7 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, return BLE_ERR_MAX; } - /* XXX: remember to deal with this on the master: if the slave has + /* XXX: remember to deal with this on the central: if the peripheral has * initiated a procedure we may have received its connection parameter * update request and have signaled the host with an event. If that * is the case, we will need to drop the host command when we get it @@ -2116,19 +2116,19 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * be pending (a connection update) that will cause collisions and the behavior below. */ /* - * Check for procedure collision (Vol 6 PartB 5.3). If we are a slave - * and we receive a request we "consider the slave initiated + * Check for procedure collision (Vol 6 PartB 5.3). If we are a peripheral + * and we receive a request we "consider the peripheral initiated * procedure as complete". This means send a connection update complete * event (with error). * - * If a master, we send reject with a + * If a central, we send reject with a * transaction collision error code. */ if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ)) { switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_CONN_ROLE_CENTRAL: - /* The master sends reject ind ext w/error code 0x23 */ + /* The central sends reject ind ext w/error code 0x23 */ rsp_opcode = BLE_LL_CTRL_REJECT_IND_EXT; rspbuf[1] = BLE_LL_CTRL_CONN_PARM_REQ; rspbuf[2] = BLE_ERR_LMP_COLLISION; @@ -2147,7 +2147,7 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, } /* - * If we are a master and we currently performing a channel map + * If we are a central and we currently performing a channel map * update procedure we need to return an error */ #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) @@ -2172,7 +2172,7 @@ ble_ll_ctrl_rx_conn_param_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, { uint8_t rsp_opcode; - /* A slave should never receive this response */ + /* A peripheral should never receive this response */ #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { return BLE_LL_CTRL_UNKNOWN_RSP; @@ -2180,9 +2180,9 @@ ble_ll_ctrl_rx_conn_param_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, #endif /* - * This case should never happen! It means that the slave initiated a - * procedure and the master initiated one as well. If we do get in this - * state just clear the awaiting reply. The slave will hopefully stop its + * This case should never happen! It means that the peripheral initiated a + * procedure and the central initiated one as well. If we do get in this + * state just clear the awaiting reply. The peripheral will hopefully stop its * procedure when we reply. */ if (connsm->csmflags.cfbit.awaiting_host_reply) { @@ -2562,7 +2562,7 @@ ble_ll_ctrl_chk_proc_start(struct ble_ll_conn_sm *connsm) * NOTE: this function uses the received PDU for the response in some cases. If * the received PDU is not used it needs to be freed here. * - * XXX: may want to check, for both master and slave, whether the control + * XXX: may want to check, for both central and peripheral, whether the control * pdu should be received by that role. Might make for less code... * Context: Link Layer * @@ -2954,7 +2954,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) case BLE_LL_CTRL_REJECT_IND_EXT: if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_CONN_PARAM_REQ) { /* If rejecting opcode is BLE_LL_CTRL_PROC_CONN_PARAM_REQ and - * reason is LMP collision that means we are master on the link and + * reason is LMP collision that means we are central on the link and * peer wanted to start procedure which we already started. * Let's wait for response and do not close procedure. */ if (txpdu->om_data[1] == BLE_LL_CTRL_CONN_PARM_REQ && diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 4a7051cc6d..b7d8cf6d0e 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -410,7 +410,7 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) } /** - * Called to schedule a connection when the current role is master. + * Called to schedule a connection when the current role is central. * * Context: Interrupt * @@ -452,8 +452,8 @@ ble_ll_sched_central_new(struct ble_ll_conn_sm *connsm, /* XXX: * The calculations for the 32kHz crystal bear alot of explanation. The - * earliest possible time that the master can start the connection with a - * slave is 1.25 msecs from the end of the connection request. The + * earliest possible time that the central can start the connection with a + * peripheral is 1.25 msecs from the end of the connection request. The * connection request is sent an IFS time from the end of the advertising * packet that was received plus the time it takes to send the connection * request. At 1 Mbps, this is 1752 usecs, or 57.41 ticks. Using 57 ticks @@ -462,32 +462,32 @@ ble_ll_sched_central_new(struct ble_ll_conn_sm *connsm, * the advertising PDU is 'now' (we call os_cputime_get32). We dont know * how much time it will take to service the ISR but if we are more than the * rx to tx time of the chip we will not be successful transmitting the - * connect request. All this means is that we presume that the slave will + * connect request. All this means is that we presume that the peripheral will * receive the connect request later than we expect but no earlier than * 13 usecs before (this is important). * * The code then attempts to schedule the connection at the * earliest time although this may not be possible. When the actual - * schedule start time is determined, the master has to determine if this + * schedule start time is determined, the central has to determine if this * time is more than a transmit window offset interval (1.25 msecs). The - * master has to tell the slave how many transmit window offsets there are + * central has to tell the peripheral how many transmit window offsets there are * from the earliest possible time to when the actual transmit start will * occur. Later in this function you will see the calculation. The actual * transmission start has to occur within the transmit window. The transmit * window interval is in units of 1.25 msecs and has to be at least 1. To - * make things a bit easier (but less power efficient for the slave), we + * make things a bit easier (but less power efficient for the peripheral), we * use a transmit window of 2. We do this because we dont quite know the * exact start of the transmission and if we are too early or too late we * could miss the transmit window. A final note: the actual transmission * start (the anchor point) is sched offset ticks from the schedule start * time. We dont add this to the calculation when calculating the window * offset. The reason we dont do this is we want to insure we transmit - * after the window offset we tell the slave. For example, say we think + * after the window offset we tell the peripheral. For example, say we think * we are transmitting 1253 usecs from the earliest start. This would cause * us to send a transmit window offset of 1. Since we are actually - * transmitting earlier than the slave thinks we could end up transmitting + * transmitting earlier than the peripheral thinks we could end up transmitting * before the window offset. Transmitting later is fine since we have the - * transmit window to do so. Transmitting before is bad, since the slave + * transmit window to do so. Transmitting before is bad, since the peripheral * wont be listening. We could do better calculation if we wanted to use * a transmit window of 1 as opposed to 2, but for now we dont care. */ @@ -673,8 +673,8 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, /* XXX: * The calculations for the 32kHz crystal bear alot of explanation. The - * earliest possible time that the master can start the connection with a - * slave is 1.25 msecs from the end of the connection request. The + * earliest possible time that the central can start the connection with a + * peripheral is 1.25 msecs from the end of the connection request. The * connection request is sent an IFS time from the end of the advertising * packet that was received plus the time it takes to send the connection * request. At 1 Mbps, this is 1752 usecs, or 57.41 ticks. Using 57 ticks @@ -683,32 +683,32 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, * the advertising PDU is 'now' (we call os_cputime_get32). We dont know * how much time it will take to service the ISR but if we are more than the * rx to tx time of the chip we will not be successful transmitting the - * connect request. All this means is that we presume that the slave will + * connect request. All this means is that we presume that the peripheral will * receive the connect request later than we expect but no earlier than * 13 usecs before (this is important). * * The code then attempts to schedule the connection at the * earliest time although this may not be possible. When the actual - * schedule start time is determined, the master has to determine if this + * schedule start time is determined, the central has to determine if this * time is more than a transmit window offset interval (1.25 msecs). The - * master has to tell the slave how many transmit window offsets there are + * central has to tell the peripheral how many transmit window offsets there are * from the earliest possible time to when the actual transmit start will * occur. Later in this function you will see the calculation. The actual * transmission start has to occur within the transmit window. The transmit * window interval is in units of 1.25 msecs and has to be at least 1. To - * make things a bit easier (but less power efficient for the slave), we + * make things a bit easier (but less power efficient for the peripheral), we * use a transmit window of 2. We do this because we dont quite know the * exact start of the transmission and if we are too early or too late we * could miss the transmit window. A final note: the actual transmission * start (the anchor point) is sched offset ticks from the schedule start * time. We dont add this to the calculation when calculating the window * offset. The reason we dont do this is we want to insure we transmit - * after the window offset we tell the slave. For example, say we think + * after the window offset we tell the peripheral. For example, say we think * we are transmitting 1253 usecs from the earliest start. This would cause * us to send a transmit window offset of 1. Since we are actually - * transmitting earlier than the slave thinks we could end up transmitting + * transmitting earlier than the peripheral thinks we could end up transmitting * before the window offset. Transmitting later is fine since we have the - * transmit window to do so. Transmitting before is bad, since the slave + * transmit window to do so. Transmitting before is bad, since the peripheral * wont be listening. We could do better calculation if we wanted to use * a transmit window of 1 as opposed to 2, but for now we dont care. */ @@ -781,7 +781,7 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, #endif /** - * Schedules a slave connection for the first time. + * Schedules a peripheral connection for the first time. * * Context: Link Layer * @@ -801,7 +801,7 @@ ble_ll_sched_conn_periph_new(struct ble_ll_conn_sm *connsm) /* Set schedule start and end times */ /* - * XXX: for now, we dont care about anchor point usecs for the slave. It + * XXX: for now, we dont care about anchor point usecs for the peripheral. It * does not matter if we turn on the receiver up to one tick before w * need to. We also subtract one extra tick since the conversion from * usecs to ticks could be off by up to 1 tick. diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 31e99840df..8912cec587 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -900,7 +900,7 @@ ble_ll_sync_schedule_chain(struct ble_ll_sync_sm *sm, struct ble_mbuf_hdr *hdr, return -1; } - /* chain should use same PHY as master PDU */ + /* chain should use same PHY as central PDU */ if (phy != ble_ll_sync_phy_mode_to_aux_phy(sm->phy_mode)) { return -1; } From d6f70f115c4cc4d8f948134c8576d63ca31ff781 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 9 Feb 2022 16:32:41 +0100 Subject: [PATCH 0265/1333] nimble/ll: Deprecate BLE_LL_EXT_ADV_AUX_PTR_CNT This should be deprecated after scanner refactor. --- nimble/controller/syscfg.yml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index e628a8aa57..b565ce444d 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -326,13 +326,7 @@ syscfg.defs: description: > Number of auxiliary advertising segments that can be scanned concurrently (Core 5.2, Vol 6, Part B, 4.4.2.2.2). - value: 8 - - BLE_LL_EXT_ADV_AUX_PTR_CNT: - description: > - This option configure a max number of scheduled outstanding auxiliary - packets for receive on secondary advertising channel. - value: 0 + value: MYNEWT_VAL(BLE_LL_EXT_ADV_AUX_PTR_CNT) BLE_LL_PUBLIC_DEV_ADDR: description: > @@ -485,6 +479,10 @@ syscfg.defs: description: use BLE_LL_PUBLIC_DEV_ADDR value: "(uint8_t[6]){0x00, 0x00, 0x00, 0x00, 0x00, 0x00}" deprecated: 1 + BLE_LL_EXT_ADV_AUX_PTR_CNT: + description: use BLE_LL_SCAN_AUX_SEGMENT_CNT + value: 0 + deprecated: 1 # defunct settings (to be removed eventually) BLE_DEVICE: @@ -511,7 +509,7 @@ syscfg.defs: syscfg.vals.BLE_LL_CFG_FEAT_LL_EXT_ADV: BLE_LL_CFG_FEAT_LE_CSA2: 1 BLE_HW_WHITELIST_ENABLE: 0 - BLE_LL_EXT_ADV_AUX_PTR_CNT: 5 + BLE_LL_SCAN_AUX_SEGMENT_CNT: 8 # Enable vendor event on assert in standalone build to make failed assertions in # controller code visible when connected to external host From 5d67e47985a6f0a46e082ad84a0f0dbbec277eff Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 28 Jan 2022 15:33:51 +0100 Subject: [PATCH 0266/1333] nimble/phy/cmac: Use 31250 tps timer This adjusts phy to 31250 tps timer used in LL on CMAC. --- nimble/drivers/dialog_cmac/src/ble_phy.c | 108 ++++++++--------------- 1 file changed, 36 insertions(+), 72 deletions(-) diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index 1b1d821dfe..e36a31c4ef 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -258,9 +258,7 @@ struct ble_phy_data { #endif uint32_t access_addr; /* Current access address */ uint32_t crc_init; - uint32_t llt_at_cputime; - uint32_t cputime_at_llt; - uint64_t start_llt; + uint64_t llt_rx_start; struct ble_mbuf_hdr rxhdr; ble_phy_tx_end_func txend_cb; void *txend_arg; @@ -454,24 +452,6 @@ SW_MAC_IRQHandler(void) MCU_DIAG_SER('s'); } -static inline uint32_t -ble_phy_convert_and_record_start_time(uint32_t cputime, uint8_t rem_usecs) -{ - uint64_t ll_val; - - ll_val = cmac_timer_convert_hal2llt(cputime); - - /* - * Since we just converted cputime to the LL timer, record both these - * values as they will be used to calculate packet reception start time. - */ - g_ble_phy_data.cputime_at_llt = cputime; - g_ble_phy_data.llt_at_cputime = ll_val; - g_ble_phy_data.start_llt = ll_val + rem_usecs; - - return ll_val; -} - static inline void ble_phy_sw_mac_handover(uint8_t exc) { @@ -525,12 +505,8 @@ ble_phy_rx_end_isr(void) static bool ble_phy_rx_start_isr(void) { - uint32_t llt32; - uint32_t llt_10_0; - uint32_t llt_10_0_mask; + uint64_t llt; uint32_t timestamp; - uint32_t ticks; - uint32_t usecs; struct ble_mbuf_hdr *ble_hdr; /* Initialize the ble mbuf header */ @@ -565,44 +541,31 @@ ble_phy_rx_start_isr(void) timestamp = CMAC->CM_TS1_REG; assert((timestamp & CMAC_CM_TS1_REG_TS1_DIRTY_Msk) != 0); - /* Get the LL timer (only need 32 bits) */ - llt32 = cmac_timer_read32(); + llt = cmac_timer_read37(); - /* - * We assume that the timestamp was set within 11 bits, or 2047 usecs, of - * when we read the ll timer. We assume this because we need to calculate - * the LL timer value at the timestamp. If the low 11 bits of the LL timer - * are greater than the timestamp, it means that the upper bits of the - * timestamp are correct. If the timestamp value is greater, it means the - * timer wrapped the 11 bits and we need to adjust the LL timer value. + /* Captured timestamp has only 11lsb, we use current LL timer value to + * calculate 37-bit timestamp. To do this we will replace 11 lsb of current + * LL timer value with captured value, but we need to check if msb of + * captured timestamp (i.e. 11) is the same as in current LL timer value. + * If not, it means 10 lsb of LL timer value wrapped around since timestamp + * was captured and we need to adjust LL timer value. This assumes that + * LL timer value was read no later than 1024 usecs from timestamp capture, + * but that's fine since isr should be triggered immediately after capture. */ - llt_10_0_mask = (CMAC_CM_TS1_REG_TS1_TIMER1_9_0_Msk | - CMAC_CM_TS1_REG_TS1_TIMER1_10_Msk); - timestamp &= llt_10_0_mask; - llt_10_0 = llt32 & llt_10_0_mask; - llt32 &= ~llt_10_0_mask; - if (timestamp > llt_10_0) { - llt32 -= 2048; + if (((uint32_t)llt ^ timestamp) & (1 << 10)) { + llt -= 1024; } - llt32 |= timestamp; + llt &= ~((uint64_t)0x3ff); + llt |= timestamp & 0x3ff; - /* Actual RX start time needs to account for preamble and access address */ - llt32 -= g_ble_phy_mode_pkt_start_off[g_ble_phy_data.phy_mode_rx] + - g_ble_phy_data.path_delay_rx; - - if (llt32 < g_ble_phy_data.llt_at_cputime) { - g_ble_phy_data.llt_at_cputime -= 31; - g_ble_phy_data.cputime_at_llt--; - } - - /* - * We now have the LL timer when the packet was received. Get the cputime - * and the leftover usecs. + /* Timestamp is captured after access address so we need to adjust rx start + * time accordingly. */ - usecs = llt32 - g_ble_phy_data.llt_at_cputime; - ticks = os_cputime_usecs_to_ticks(usecs); - ble_hdr->beg_cputime = g_ble_phy_data.cputime_at_llt + ticks; - ble_hdr->rem_usecs = usecs - os_cputime_ticks_to_usecs(ticks); + llt -= g_ble_phy_mode_pkt_start_off[g_ble_phy_data.phy_mode_rx] + + g_ble_phy_data.path_delay_rx; + + ble_hdr->beg_cputime = llt >> 5; + ble_hdr->rem_usecs = llt & 0x1f; return true; } @@ -1180,7 +1143,7 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) CMAC->CM_EV_LINKUP_REG = CMAC_CM_EV_LINKUP_REG_LU_CORR_TMR_LD_2_CORR_START_Msk; } else { wfr_usecs += aa_time; - llt = g_ble_phy_data.start_llt; + llt = g_ble_phy_data.llt_rx_start; /* * wfr is outside range of CORR_WINDOW so we need to use LLT to start @@ -1380,7 +1343,8 @@ ble_phy_rx(void) int ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) { - uint32_t ll_val32; + uint64_t llt_rx_start; + uint32_t llt32; int32_t time_till_start; int rc = 0; @@ -1394,21 +1358,22 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) ble_phy_rx(); - /* Get LL timer at cputime */ - ll_val32 = ble_phy_convert_and_record_start_time(cputime, rem_usecs); - - /* Add remaining usecs to get exact receive start time */ - ll_val32 += rem_usecs; + /* Store LLT value at RX start, we'll need this to set wfr */ + llt_rx_start = (uint64_t)cputime * 32 + rem_usecs; + g_ble_phy_data.llt_rx_start = llt_rx_start; - /* Adjust start time for rx delays */ - ll_val32 -= PHY_DELAY_POWER_UP_RX - g_ble_phy_data.path_delay_rx; + /* Adjust start time for rx delays. + * Note: we can use 32lsb for remaining calculations. + */ + llt32 = llt_rx_start; + llt32 -= PHY_DELAY_POWER_UP_RX - g_ble_phy_data.path_delay_rx; __disable_irq(); - CMAC->CM_LL_TIMER1_9_0_EQ_X_REG = ll_val32; + CMAC->CM_LL_TIMER1_9_0_EQ_X_REG = llt32; CMAC->CM_EV_LINKUP_REG = CMAC_CM_EV_LINKUP_REG_LU_FRAME_START_2_TMR1_9_0_EQ_X_Msk; - time_till_start = (int32_t)(ll_val32 - cmac_timer_read32()); + time_till_start = (int32_t)(llt32 - cmac_timer_read32()); if (time_till_start <= 0) { /* * Possible we missed the frame start! If we have, we need to start @@ -1520,8 +1485,7 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) ble_rf_configure(); ble_rf_setup_tx(rf_chan, g_ble_phy_data.phy_mode_tx); - ll_val32 = ble_phy_convert_and_record_start_time(cputime, rem_usecs); - ll_val32 += rem_usecs; + ll_val32 = cputime * 32 + rem_usecs; ll_val32 -= PHY_DELAY_POWER_UP_TX + g_ble_phy_data.path_delay_tx; /* we can schedule TX only up to 1023us in advance */ assert((int32_t)(ll_val32 - cmac_timer_read32()) < 1024); From dbed9d46d551847f7580c22a1e56f088dfb47941 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 2 Feb 2022 10:49:17 +0100 Subject: [PATCH 0267/1333] nimble/phy/cmac: Fix race on rx-tx On rx-tx transition we disable Frame and Field interrupts so they do not mess up tx setup process - they are reenabled in ble_phy_tx. However, after recent optimizations we are sometimes too fast and ble_phy_tx can be called before interrupts are disabled. This means there's nothing to enable interrupts again and this will trigger a CMAC error since we are not processing interrupts on time. To fix this we add flag to check whether ble_phy_tx already finished setup so there's no need to disable interrupts on transition. --- nimble/drivers/dialog_cmac/src/ble_phy.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index e36a31c4ef..9c9d878911 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -262,6 +262,7 @@ struct ble_phy_data { struct ble_mbuf_hdr rxhdr; ble_phy_tx_end_func txend_cb; void *txend_arg; + uint8_t phy_tx_set; }; static struct ble_phy_data g_ble_phy_data; @@ -647,6 +648,8 @@ ble_phy_irq_frame_tx_exc_bs_stop(void) CMAC_CM_EV_LINKUP_REG_LU_FRAME_START_2_NONE_Msk; } + g_ble_phy_data.phy_tx_set = 0; + if (g_ble_phy_data.txend_cb) { ble_phy_sw_mac_handover(SW_MAC_EXC_TXEND_CB); return; @@ -897,13 +900,16 @@ ble_phy_irq_frame_rx_exc_phy_to_idle_4this(void) #endif rf_chan = g_ble_phy_chan_to_rf[g_ble_phy_data.channel]; ble_rf_setup_tx(rf_chan, g_ble_phy_data.phy_mode_tx); + g_ble_phy_data.phy_state = BLE_PHY_STATE_TX; /* We do not want FIELD/FRAME interrupts until ble_phy_tx() has pushed all * fields. */ - NVIC_DisableIRQ(FRAME_IRQn); - NVIC_DisableIRQ(FIELD_IRQn); + if (!g_ble_phy_data.phy_tx_set) { + NVIC_DisableIRQ(FRAME_IRQn); + NVIC_DisableIRQ(FIELD_IRQn); + } } static void @@ -1278,6 +1284,7 @@ ble_phy_disable(void) NVIC_EnableIRQ(FIELD_IRQn); g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE; + g_ble_phy_data.phy_tx_set = 0; } static void @@ -1460,6 +1467,8 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) rc = BLE_ERR_SUCCESS; } + g_ble_phy_data.phy_tx_set = 1; + /* Now we can handle BS_CTRL */ NVIC_EnableIRQ(FRAME_IRQn); NVIC_EnableIRQ(FIELD_IRQn); From 5dda37cd7b9b9c368e2ab4782f01d93478f6fe6e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 14 Feb 2022 10:49:44 +0100 Subject: [PATCH 0268/1333] nimble/transport/uart: Remove unused deps --- nimble/transport/uart/pkg.yml | 1 - nimble/transport/uart/src/ble_hci_uart.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/nimble/transport/uart/pkg.yml b/nimble/transport/uart/pkg.yml index 9568137392..fd16a083a8 100644 --- a/nimble/transport/uart/pkg.yml +++ b/nimble/transport/uart/pkg.yml @@ -28,7 +28,6 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/hw/hal" - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/util/mem" - nimble pkg.apis: diff --git a/nimble/transport/uart/src/ble_hci_uart.c b/nimble/transport/uart/src/ble_hci_uart.c index cc796c0005..0b6e0e5ecc 100644 --- a/nimble/transport/uart/src/ble_hci_uart.c +++ b/nimble/transport/uart/src/ble_hci_uart.c @@ -27,8 +27,6 @@ #include "os/os_cputime.h" #include "bsp/bsp.h" #include "os/os.h" -#include "mem/mem.h" -#include "hal/hal_gpio.h" #include "hal/hal_uart.h" /* BLE */ From bf31ad05b7e560821a2a8764842b06e080a54614 Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Tue, 2 Nov 2021 15:36:10 +0100 Subject: [PATCH 0269/1333] ble_ll: Add BabbleSim support Co-authored-by: Jakub Rotkiewicz --- nimble/controller/src/ble_ll.c | 4 + nimble/controller/src/ble_ll_rand.c | 7 + nimble/drivers/nrf52/src/ble_hw.c | 24 ++- nimble/drivers/nrf52/src/ble_phy.c | 243 ++++++++++++++++++---------- 4 files changed, 182 insertions(+), 96 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index ec40925d66..5d3cb63bbd 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -358,12 +358,16 @@ static void ble_ll_event_dbuf_overflow(struct ble_npl_event *ev); #if MYNEWT +#if BABBLESIM +#define BLE_LL_STACK_SIZE (4000) +#else /* The BLE LL task data structure */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) #define BLE_LL_STACK_SIZE (120) #else #define BLE_LL_STACK_SIZE (90) #endif +#endif struct os_task g_ble_ll_task; diff --git a/nimble/controller/src/ble_ll_rand.c b/nimble/controller/src/ble_ll_rand.c index 8aa7127160..06e5d12bcf 100644 --- a/nimble/controller/src/ble_ll_rand.c +++ b/nimble/controller/src/ble_ll_rand.c @@ -33,6 +33,10 @@ #include "trng/trng.h" #endif +#if BABBLESIM +extern void tm_tick(void); +#endif + #if MYNEWT_VAL(TRNG) static struct trng_dev *g_trng; #else @@ -116,6 +120,9 @@ ble_ll_rand_data_get(uint8_t *buf, uint8_t len) while ((g_ble_ll_rnum_data.rnd_size < len) && (g_ble_ll_rnum_data.rnd_size < MYNEWT_VAL(BLE_LL_RNG_BUFSIZE))) { /* Spin here */ +#if BABBLESIM + tm_tick(); +#endif } } } diff --git a/nimble/drivers/nrf52/src/ble_hw.c b/nimble/drivers/nrf52/src/ble_hw.c index 79a7772852..ef4c28b008 100644 --- a/nimble/drivers/nrf52/src/ble_hw.c +++ b/nimble/drivers/nrf52/src/ble_hw.c @@ -34,6 +34,8 @@ #include #endif #include "os/os_trace_api.h" +#include +#include "hal/nrf_ecb.h" /* Total number of resolving list elements */ #define BLE_HW_RESOLV_LIST_SIZE (16) @@ -44,6 +46,10 @@ static uint8_t g_ble_hw_whitelist_mask; /* Random number generator isr callback */ ble_rng_isr_cb_t g_ble_rng_isr_cb; +#if BABBLESIM +extern void tm_tick(void); +#endif + /* If LL privacy is enabled, allocate memory for AAR */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) @@ -263,14 +269,14 @@ ble_hw_encrypt_block(struct ble_encryption_block *ecb) uint32_t err; /* Stop ECB */ - NRF_ECB->TASKS_STOPECB = 1; + nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STOPECB); /* XXX: does task stop clear these counters? Anyway to do this quicker? */ NRF_ECB->EVENTS_ENDECB = 0; NRF_ECB->EVENTS_ERRORECB = 0; NRF_ECB->ECBDATAPTR = (uint32_t)ecb; /* Start ECB */ - NRF_ECB->TASKS_STARTECB = 1; + nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STARTECB); /* Wait till error or done */ rc = 0; @@ -283,6 +289,9 @@ ble_hw_encrypt_block(struct ble_encryption_block *ecb) } break; } +#if BABBLESIM + tm_tick(); +#endif } return rc; @@ -300,7 +309,7 @@ ble_rng_isr(void) /* No callback? Clear and disable interrupts */ if (g_ble_rng_isr_cb == NULL) { - NRF_RNG->INTENCLR = 1; + nrf_rng_int_disable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK); NRF_RNG->EVENTS_VALRDY = 0; (void)NRF_RNG->SHORTS; os_trace_isr_exit(); @@ -365,10 +374,11 @@ ble_hw_rng_start(void) /* No need for interrupt if there is no callback */ OS_ENTER_CRITICAL(sr); NRF_RNG->EVENTS_VALRDY = 0; + if (g_ble_rng_isr_cb) { - NRF_RNG->INTENSET = 1; + nrf_rng_int_enable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK); } - NRF_RNG->TASKS_START = 1; + nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_START); OS_EXIT_CRITICAL(sr); return 0; @@ -386,8 +396,8 @@ ble_hw_rng_stop(void) /* No need for interrupt if there is no callback */ OS_ENTER_CRITICAL(sr); - NRF_RNG->INTENCLR = 1; - NRF_RNG->TASKS_STOP = 1; + nrf_rng_int_disable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK); + nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_STOP); NRF_RNG->EVENTS_VALRDY = 0; OS_EXIT_CRITICAL(sr); diff --git a/nimble/drivers/nrf52/src/ble_phy.c b/nimble/drivers/nrf52/src/ble_phy.c index 7a12bb5016..6752413318 100644 --- a/nimble/drivers/nrf52/src/ble_phy.c +++ b/nimble/drivers/nrf52/src/ble_phy.c @@ -20,6 +20,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include "syscfg/syscfg.h" #include "os/os.h" /* Keep os_cputime explicitly to enable build on non-Mynewt platforms */ @@ -47,6 +53,10 @@ #endif #endif +#if BABBLESIM +extern void tm_tick(void); +#endif + /* * NOTE: This code uses a couple of PPI channels so care should be taken when * using PPI somewhere else. @@ -165,6 +175,37 @@ static const uint16_t g_ble_phy_mode_pkt_start_off[BLE_PHY_NUM_MODE] = { /* Radio ramp-up times in usecs (fast mode) */ #define BLE_PHY_T_TXENFAST (XCVR_TX_RADIO_RAMPUP_USECS) #define BLE_PHY_T_RXENFAST (XCVR_RX_RADIO_RAMPUP_USECS) + +#if BABBLESIM +/* delay between EVENTS_READY and start of tx */ +static const uint8_t g_ble_phy_t_txdelay[BLE_PHY_NUM_MODE] = { + [BLE_PHY_MODE_1M] = 0, + [BLE_PHY_MODE_2M] = 3, + [BLE_PHY_MODE_CODED_125KBPS] = 5, + [BLE_PHY_MODE_CODED_500KBPS] = 5 +}; +/* delay between EVENTS_END and end of txd packet */ +static const uint8_t g_ble_phy_t_txenddelay[BLE_PHY_NUM_MODE] = { + [BLE_PHY_MODE_1M] = 1, + [BLE_PHY_MODE_2M] = 3, + [BLE_PHY_MODE_CODED_125KBPS] = 9, + [BLE_PHY_MODE_CODED_500KBPS] = 3 +}; +/* delay between rxd access address (w/ TERM1 for coded) and EVENTS_ADDRESS */ +static const uint8_t g_ble_phy_t_rxaddrdelay[BLE_PHY_NUM_MODE] = { + [BLE_PHY_MODE_1M] = 9, + [BLE_PHY_MODE_2M] = 2, + [BLE_PHY_MODE_CODED_125KBPS] = 17, + [BLE_PHY_MODE_CODED_500KBPS] = 17 +}; +/* delay between end of rxd packet and EVENTS_END */ +static const uint8_t g_ble_phy_t_rxenddelay[BLE_PHY_NUM_MODE] = { + [BLE_PHY_MODE_1M] = 9, + [BLE_PHY_MODE_2M] = 2, + [BLE_PHY_MODE_CODED_125KBPS] = 27, + [BLE_PHY_MODE_CODED_500KBPS] = 22 +}; +#else /* delay between EVENTS_READY and start of tx */ static const uint8_t g_ble_phy_t_txdelay[BLE_PHY_NUM_MODE] = { [BLE_PHY_MODE_1M] = 4, @@ -193,6 +234,7 @@ static const uint8_t g_ble_phy_t_rxenddelay[BLE_PHY_NUM_MODE] = { [BLE_PHY_MODE_CODED_125KBPS] = 27, [BLE_PHY_MODE_CODED_500KBPS] = 22 }; +#endif /* Statistics */ STATS_SECT_START(ble_phy_stats) @@ -303,6 +345,7 @@ static uint8_t plna_lna_idx; #endif +#ifndef BABBLESIM static void ble_phy_apply_errata_102_106_107(void) { @@ -313,6 +356,7 @@ ble_phy_apply_errata_102_106_107(void) *(volatile uint32_t *)0x40001774 = ((*(volatile uint32_t *)0x40001774) & 0xfffffffe) | 0x01000000; } +#endif #if (BLE_LL_BT5_PHY_SUPPORTED == 1) @@ -527,6 +571,11 @@ ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu) rem_len -= copy_len; block_rem_len -= copy_len; +#if BABBLESIM + memcpy(dst, src, copy_len); + dst += copy_len; + src += copy_len; +#else __asm__ volatile (".syntax unified \n" " mov r4, %[len] \n" " b 2f \n" @@ -541,6 +590,7 @@ ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu) : : "r3", "r4", "memory" ); +#endif if ((rem_len < 4) && (block_rem_len >= rem_len)) { break; @@ -553,6 +603,10 @@ ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu) /* Copy remaining bytes, if any, to last mbuf */ om->om_len += rem_len; + +#if BABBLESIM + memcpy(dst, src, rem_len); +#else __asm__ volatile (".syntax unified \n" " b 2f \n" "1: ldrb r3, [%[src], %[len]] \n" @@ -563,6 +617,7 @@ ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu) : [dst] "r" (dst), [src] "r" (src) : "r3", "memory" ); +#endif /* Copy header */ memcpy(BLE_MBUF_HDR_PTR(rxpdu), &g_ble_phy_data.rxhdr, @@ -587,6 +642,9 @@ nrf_wait_disabled(void) while (NRF_RADIO->STATE == state) { /* If this fails, something is really wrong. Should last * no more than 6 usecs */ +#if BABBLESIM + tm_tick(); +#endif } } } @@ -658,17 +716,17 @@ ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx) } /* Clear and set TIMER0 to fire off at proper time */ - NRF_TIMER0->TASKS_CLEAR = 1; - NRF_TIMER0->CC[0] = rem_usecs; + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CLEAR); + nrf_timer_cc_set(NRF_TIMER0, 0, rem_usecs); NRF_TIMER0->EVENTS_COMPARE[0] = 0; /* Set RTC compare to start TIMER0 */ NRF_RTC0->EVENTS_COMPARE[0] = 0; - NRF_RTC0->CC[0] = next_cc; - NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE0_Msk; + nrf_rtc_cc_set(NRF_RTC0, 0, next_cc); + nrf_rtc_event_enable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); /* Enable PPI */ - NRF_PPI->CHENSET = PPI_CHEN_CH31_Msk; + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH31_Msk); /* Store the cputime at which we set the RTC */ g_ble_phy_data.phy_start_cputime = cputime; @@ -688,8 +746,8 @@ ble_phy_set_start_now(void) * Set TIMER0 to fire immediately. We can't set CC to 0 as compare will not * occur in such case. */ - NRF_TIMER0->TASKS_CLEAR = 1; - NRF_TIMER0->CC[0] = 1; + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CLEAR); + nrf_timer_cc_set(NRF_TIMER0, 0, 1); NRF_TIMER0->EVENTS_COMPARE[0] = 0; /* @@ -700,12 +758,11 @@ ble_phy_set_start_now(void) */ now = os_cputime_get32(); NRF_RTC0->EVENTS_COMPARE[0] = 0; - NRF_RTC0->CC[0] = now + 3; - NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE0_Msk; + nrf_rtc_cc_set(NRF_RTC0, 0, now + 3); + nrf_rtc_event_enable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); /* Enable PPI */ - NRF_PPI->CHENSET = PPI_CHEN_CH31_Msk; - + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH31_Msk); /* * Store the cputime at which we set the RTC * @@ -780,11 +837,11 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) end_time += g_ble_phy_t_rxaddrdelay[phy]; /* wfr_secs is the time from rxen until timeout */ - NRF_TIMER0->CC[3] = end_time; + nrf_timer_cc_set(NRF_TIMER0, 3, end_time); NRF_TIMER0->EVENTS_COMPARE[3] = 0; /* Enable wait for response PPI */ - NRF_PPI->CHENSET = (PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk); + nrf_ppi_channels_enable(NRF_PPI, (PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk)); /* * It may happen that if CPU is halted for a brief moment (e.g. during flash @@ -798,10 +855,10 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) * CC[1] is only used as a reference on RX start, we do not need it here so * it can be used to read TIMER0 counter. */ - NRF_TIMER0->TASKS_CAPTURE[1] = 1; + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE1); if (NRF_TIMER0->CC[1] > NRF_TIMER0->CC[3]) { - NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk; - NRF_RADIO->TASKS_DISABLE = 1; + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk); + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); } } @@ -854,8 +911,8 @@ ble_phy_rx_xcvr_setup(void) NRF_CCM->SHORTS = 0; NRF_CCM->EVENTS_ERROR = 0; NRF_CCM->EVENTS_ENDCRYPT = 0; - NRF_CCM->TASKS_KSGEN = 1; - NRF_PPI->CHENSET = PPI_CHEN_CH25_Msk; + nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH25_Msk); } else { NRF_RADIO->PACKETPTR = (uint32_t)dptr; } @@ -879,7 +936,7 @@ ble_phy_rx_xcvr_setup(void) #endif /* Turn off trigger TXEN on output compare match and AAR on bcmatch */ - NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk | PPI_CHEN_CH23_Msk; + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk | PPI_CHEN_CH23_Msk); /* Reset the rx started flag. Used for the wait for response */ g_ble_phy_data.phy_rx_started = 0; @@ -901,7 +958,7 @@ ble_phy_rx_xcvr_setup(void) #endif /* I want to know when 1st byte received (after address) */ - NRF_RADIO->BCC = 8 + g_ble_phy_data.phy_bcc_offset; /* in bits */ + nrf_radio_bcc_set(NRF_RADIO, 8 + g_ble_phy_data.phy_bcc_offset); /* in bits */ NRF_RADIO->EVENTS_ADDRESS = 0; NRF_RADIO->EVENTS_DEVMATCH = 0; NRF_RADIO->EVENTS_BCMATCH = 0; @@ -913,8 +970,8 @@ ble_phy_rx_xcvr_setup(void) RADIO_SHORTS_ADDRESS_RSSISTART_Msk | RADIO_SHORTS_DISABLED_RSSISTOP_Msk; - NRF_RADIO->INTENSET = RADIO_INTENSET_ADDRESS_Msk | - RADIO_INTENSET_DISABLED_Msk; + nrf_radio_int_enable(NRF_RADIO, RADIO_INTENSET_ADDRESS_Msk | + RADIO_INTENSET_DISABLED_Msk); } /** @@ -978,9 +1035,9 @@ ble_phy_tx_end_isr(void) /* Start listening a bit earlier due to allowed active clock accuracy */ rx_time -= 2; - NRF_TIMER0->CC[0] = rx_time; + nrf_timer_cc_set(NRF_TIMER0, 0, rx_time); NRF_TIMER0->EVENTS_COMPARE[0] = 0; - NRF_PPI->CHENSET = PPI_CHEN_CH21_Msk; + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); ble_phy_plna_enable_lna(); } else { @@ -988,10 +1045,10 @@ ble_phy_tx_end_isr(void) * XXX: not sure we need to stop the timer here all the time. Or that * it should be stopped here. */ - NRF_TIMER0->TASKS_STOP = 1; + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP); NRF_TIMER0->TASKS_SHUTDOWN = 1; - NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | - PPI_CHEN_CH20_Msk | PPI_CHEN_CH31_Msk; + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | + PPI_CHEN_CH20_Msk | PPI_CHEN_CH31_Msk); assert(transition == BLE_PHY_TRANSITION_NONE); } } @@ -1031,7 +1088,7 @@ ble_phy_rx_end_isr(void) struct ble_mbuf_hdr *ble_hdr; /* Disable automatic RXEN */ - NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk; + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH21_Msk); /* Set RSSI and CRC status flag in header */ ble_hdr = &g_ble_phy_data.rxhdr; @@ -1107,9 +1164,9 @@ ble_phy_rx_end_isr(void) /* Adjust for delay between EVENT_READY and actual TX start time */ tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; - NRF_TIMER0->CC[0] = tx_time; + nrf_timer_cc_set(NRF_TIMER0, 0, tx_time); NRF_TIMER0->EVENTS_COMPARE[0] = 0; - NRF_PPI->CHENSET = PPI_CHEN_CH20_Msk; + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); ble_phy_plna_enable_pa(); @@ -1125,9 +1182,9 @@ ble_phy_rx_end_isr(void) * * Note: CC[3] is used only for wfr which we do not need here. */ - NRF_TIMER0->TASKS_CAPTURE[3] = 1; + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) { - NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk; + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk); g_ble_phy_data.phy_transition_late = 1; } @@ -1162,10 +1219,10 @@ ble_phy_rx_start_isr(void) /* Clear events and clear interrupt */ NRF_RADIO->EVENTS_ADDRESS = 0; - NRF_RADIO->INTENCLR = RADIO_INTENCLR_ADDRESS_Msk; + nrf_radio_int_disable(NRF_RADIO, RADIO_INTENCLR_ADDRESS_Msk); /* Clear wfr timer channels */ - NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk; + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk); /* Initialize the ble mbuf header */ ble_hdr = &g_ble_phy_data.rxhdr; @@ -1221,10 +1278,14 @@ ble_phy_rx_start_isr(void) * something is wrong! */ if (state == RADIO_STATE_STATE_Disabled) { - NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL; + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); NRF_RADIO->SHORTS = 0; return false; } + +#if BABBLESIM + tm_tick(); +#endif } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) @@ -1243,9 +1304,9 @@ ble_phy_rx_start_isr(void) /* Trigger AAR after last bit of AdvA is received */ NRF_RADIO->EVENTS_BCMATCH = 0; - NRF_PPI->CHENSET = PPI_CHEN_CH23_Msk; - NRF_RADIO->BCC = (BLE_LL_PDU_HDR_LEN + adva_offset + BLE_DEV_ADDR_LEN) * 8 + - g_ble_phy_data.phy_bcc_offset; + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH23_Msk); + nrf_radio_bcc_set(NRF_RADIO, (BLE_LL_PDU_HDR_LEN + adva_offset + + BLE_DEV_ADDR_LEN) * 8 + g_ble_phy_data.phy_bcc_offset); } #endif @@ -1276,7 +1337,7 @@ ble_phy_isr(void) os_trace_isr_enter(); /* Read irq register to determine which interrupts are enabled */ - irq_en = NRF_RADIO->INTENCLR; + irq_en = NRF_RADIO->INTENSET; /* * NOTE: order of checking is important! Possible, if things get delayed, @@ -1311,7 +1372,7 @@ ble_phy_isr(void) !g_ble_phy_data.phy_rx_started)); NRF_RADIO->EVENTS_END = 0; NRF_RADIO->EVENTS_DISABLED = 0; - NRF_RADIO->INTENCLR = RADIO_INTENCLR_DISABLED_Msk; + nrf_radio_int_disable(NRF_RADIO, RADIO_INTENCLR_DISABLED_Msk); switch (g_ble_phy_data.phy_state) { case BLE_PHY_STATE_RX: @@ -1397,39 +1458,40 @@ ble_phy_dbg_time_setup(void) #if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); - NRF_PPI->CH[17].EEP = (uint32_t)&(NRF_RADIO->EVENTS_READY); - NRF_PPI->CH[17].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx]); - NRF_PPI->CHENSET = PPI_CHEN_CH17_Msk; + nrf_ppi_channel_endpoint_setup(NRF_PPI, 17, (uint32_t)&(NRF_RADIO->EVENTS_READY), + (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH17_Msk); /* CH[20] and PPI CH[21] are on to trigger TASKS_TXEN or TASKS_RXEN */ - NRF_PPI->FORK[20].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx]); - NRF_PPI->FORK[21].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx]); + nrf_ppi_fork_endpoint_setup(NRF_PPI, 20, (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); + nrf_ppi_fork_endpoint_setup(NRF_PPI, 21, (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); #endif #if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); /* CH[26] and CH[27] are always on for EVENT_ADDRESS and EVENT_END */ - NRF_PPI->FORK[26].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx]); - NRF_PPI->FORK[27].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx]); + nrf_ppi_fork_endpoint_setup(NRF_PPI, 26, (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); + nrf_ppi_fork_endpoint_setup(NRF_PPI, 27, (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); #endif #if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); #if NRF52840_XXAA - NRF_PPI->CH[18].EEP = (uint32_t)&(NRF_RADIO->EVENTS_RXREADY); + nrf_ppi_channel_endpoint_setup(NRF_PPI, 18, (uint32_t)&(NRF_RADIO->EVENTS_RXREADY), + (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); #else - NRF_PPI->CH[18].EEP = (uint32_t)&(NRF_RADIO->EVENTS_READY); + nrf_ppi_channel_endpoint_setup(NRF_PPI, 18, (uint32_t)&(NRF_RADIO->EVENTS_READY), + (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); #endif - NRF_PPI->CH[18].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx]); - NRF_PPI->CH[19].EEP = (uint32_t)&(NRF_RADIO->EVENTS_DISABLED); - NRF_PPI->CH[19].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx]); - NRF_PPI->CHENSET = PPI_CHEN_CH18_Msk | PPI_CHEN_CH19_Msk; + nrf_ppi_channel_endpoint_setup(NRF_PPI, 19, (uint32_t)&(NRF_RADIO->EVENTS_DISABLED), + (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH18_Msk | PPI_CHEN_CH19_Msk); /* CH[4] and CH[5] are always on for wfr */ - NRF_PPI->FORK[4].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx]); - NRF_PPI->FORK[5].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx]); + nrf_ppi_fork_endpoint_setup(NRF_PPI, 4, (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); + nrf_ppi_fork_endpoint_setup(NRF_PPI, 5, (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); #endif } @@ -1458,11 +1520,11 @@ ble_phy_init(void) g_ble_phy_data.phy_chan = BLE_PHY_NUM_CHANS; /* Toggle peripheral power to reset (just in case) */ - NRF_RADIO->POWER = 0; - NRF_RADIO->POWER = 1; + nrf_radio_power_set(NRF_RADIO, false); + nrf_radio_power_set(NRF_RADIO, true); /* Disable all interrupts */ - NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL; + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); /* Set configuration registers */ NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit; @@ -1492,10 +1554,10 @@ ble_phy_init(void) NRF_RADIO->TIFS = BLE_LL_IFS; /* Captures tx/rx start in timer0 cc 1 and tx/rx end in timer0 cc 2 */ - NRF_PPI->CHENSET = PPI_CHEN_CH26_Msk | PPI_CHEN_CH27_Msk; + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH26_Msk | PPI_CHEN_CH27_Msk); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - NRF_CCM->INTENCLR = 0xffffffff; + nrf_ccm_int_disable(NRF_CCM, 0xffffffff); NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; NRF_CCM->EVENTS_ERROR = 0; memset(g_nrf_encrypt_scratchpad, 0, sizeof(g_nrf_encrypt_scratchpad)); @@ -1504,7 +1566,7 @@ ble_phy_init(void) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) g_ble_phy_data.phy_aar_scratch = 0; NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; - NRF_AAR->INTENCLR = 0xffffffff; + nrf_aar_int_disable(NRF_AAR, 0xffffffff); NRF_AAR->EVENTS_END = 0; NRF_AAR->EVENTS_RESOLVED = 0; NRF_AAR->EVENTS_NOTRESOLVED = 0; @@ -1512,7 +1574,7 @@ ble_phy_init(void) #endif /* TIMER0 setup for PHY when using RTC */ - NRF_TIMER0->TASKS_STOP = 1; + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP); NRF_TIMER0->TASKS_SHUTDOWN = 1; NRF_TIMER0->BITMODE = 3; /* 32-bit timer */ NRF_TIMER0->MODE = 0; /* Timer mode */ @@ -1525,10 +1587,12 @@ ble_phy_init(void) * Channel 5: TIMER0 CC[3] to TASKS_DISABLE on radio. This is the wait * for response timer. */ - NRF_PPI->CH[4].EEP = (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS); - NRF_PPI->CH[4].TEP = (uint32_t)&(NRF_TIMER0->TASKS_CAPTURE[3]); - NRF_PPI->CH[5].EEP = (uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[3]); - NRF_PPI->CH[5].TEP = (uint32_t)&(NRF_RADIO->TASKS_DISABLE); + nrf_ppi_channel_endpoint_setup(NRF_PPI, NRF_PPI_CHANNEL4, + (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS), + (uint32_t)&(NRF_TIMER0->TASKS_CAPTURE[3])); + nrf_ppi_channel_endpoint_setup(NRF_PPI, NRF_PPI_CHANNEL5, + (uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[3]), + (uint32_t)&(NRF_RADIO->TASKS_DISABLE)); #if MYNEWT_VAL(BLE_LL_PA) || MYNEWT_VAL(BLE_LL_LNA) #if PLNA_SINGLE_GPIO @@ -1606,7 +1670,7 @@ ble_phy_rx(void) } /* Make sure all interrupts are disabled */ - NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL; + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); /* Clear events prior to enabling receive */ NRF_RADIO->EVENTS_END = 0; @@ -1656,8 +1720,8 @@ ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir) void ble_phy_encrypt_disable(void) { - NRF_PPI->CHENCLR = PPI_CHEN_CH25_Msk; - NRF_CCM->TASKS_STOP = 1; + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH25_Msk); + nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_STOP); NRF_CCM->EVENTS_ERROR = 0; NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled; @@ -1703,7 +1767,7 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) /* XXX: This should not be necessary, but paranoia is good! */ /* Clear timer0 compare to RXEN since we are transmitting */ - NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk; + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH21_Msk); if (ble_phy_set_start_time(cputime, rem_usecs, true) != 0) { STATS_INC(ble_phy_stats, tx_late); @@ -1711,7 +1775,7 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) rc = BLE_PHY_ERR_TX_LATE; } else { /* Enable PPI to automatically start TXEN */ - NRF_PPI->CHENSET = PPI_CHEN_CH20_Msk; + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); rc = 0; ble_phy_plna_enable_pa(); @@ -1747,7 +1811,7 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) /* XXX: This should not be necessary, but paranoia is good! */ /* Clear timer0 compare to TXEN since we are transmitting */ - NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk; + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk); if (ble_phy_set_start_time(cputime, rem_usecs, false) != 0) { STATS_INC(ble_phy_stats, rx_late); @@ -1759,7 +1823,7 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) } /* Enable PPI to automatically start RXEN */ - NRF_PPI->CHENSET = PPI_CHEN_CH21_Msk; + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); ble_phy_plna_enable_lna(); @@ -1807,8 +1871,8 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) * paranoid, and if you are going to clear one, might as well clear them * all. */ - NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | PPI_CHEN_CH23_Msk | - PPI_CHEN_CH25_Msk; + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | + PPI_CHEN_CH23_Msk | PPI_CHEN_CH25_Msk); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) if (g_ble_phy_data.phy_encrypted) { @@ -1844,7 +1908,7 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) /* Start key-stream generation and encryption (via short) */ if (g_ble_phy_data.phy_encrypted) { - NRF_CCM->TASKS_KSGEN = 1; + nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); } #endif @@ -1858,7 +1922,7 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) /* Enable shortcuts for transmit start/end. */ shortcuts = RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_READY_START_Msk; NRF_RADIO->SHORTS = shortcuts; - NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk; + nrf_radio_int_enable(NRF_RADIO, RADIO_INTENSET_DISABLED_Msk); /* Set the PHY transition */ g_ble_phy_data.phy_transition = end_trans; @@ -1970,8 +2034,9 @@ ble_phy_set_access_addr(uint32_t access_addr) g_ble_phy_data.phy_access_address = access_addr; +#ifndef BABBLESIM ble_phy_apply_errata_102_106_107(); - +#endif return 0; } @@ -2038,9 +2103,9 @@ ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit) static void ble_phy_stop_usec_timer(void) { - NRF_TIMER0->TASKS_STOP = 1; + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP); NRF_TIMER0->TASKS_SHUTDOWN = 1; - NRF_RTC0->EVTENCLR = RTC_EVTENSET_COMPARE0_Msk; + nrf_rtc_event_disable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); } /** @@ -2054,13 +2119,13 @@ ble_phy_stop_usec_timer(void) static void ble_phy_disable_irq_and_ppi(void) { - NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL; + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); NRF_RADIO->SHORTS = 0; - NRF_RADIO->TASKS_DISABLE = 1; - NRF_PPI->CHENCLR = PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | PPI_CHEN_CH20_Msk | - PPI_CHEN_CH21_Msk | PPI_CHEN_CH23_Msk | - PPI_CHEN_CH25_Msk | PPI_CHEN_CH31_Msk; - NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | + PPI_CHEN_CH20_Msk | PPI_CHEN_CH21_Msk | PPI_CHEN_CH23_Msk | + PPI_CHEN_CH25_Msk | PPI_CHEN_CH31_Msk); + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk); NVIC_ClearPendingIRQ(RADIO_IRQn); g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE; } @@ -2073,7 +2138,7 @@ ble_phy_restart_rx(void) ble_phy_set_start_now(); /* Enable PPI to automatically start RXEN */ - NRF_PPI->CHENSET = PPI_CHEN_CH21_Msk; + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); ble_phy_rx(); } @@ -2185,7 +2250,7 @@ ble_phy_rfclk_enable(void) #if MYNEWT nrf52_clock_hfxo_request(); #else - NRF_CLOCK->TASKS_HFCLKSTART = 1; + nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART); #endif } @@ -2195,6 +2260,6 @@ ble_phy_rfclk_disable(void) #if MYNEWT nrf52_clock_hfxo_release(); #else - NRF_CLOCK->TASKS_HFCLKSTOP = 1; + nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); #endif } From 9abe36cc3c489370deb75fd9c265505fae82c656 Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Thu, 25 Nov 2021 18:05:43 +0100 Subject: [PATCH 0270/1333] babblesim: Add babblesim pkg Co-authored-by: Jakub Rotkiewicz Co-authored-by: Andrzej Kaczmarek --- babblesim/.gitignore | 3 + babblesim/README.md | 1 + babblesim/core/include/argparse.h | 30 + babblesim/core/include/cmsis.h | 51 + babblesim/core/include/core_cm4.h | 27 + babblesim/core/include/time_machine.h | 48 + babblesim/core/pkg.yml | 37 + babblesim/core/src/argparse.c | 153 +++ babblesim/core/src/cmsis.c | 85 ++ babblesim/core/src/irq_handler.c | 74 ++ babblesim/core/src/main_config.c | 79 ++ babblesim/core/src/time_machine.c | 255 +++++ babblesim/hw/babblesim/pkg.yml | 44 + babblesim/hw/babblesim/scripts/pre_build1.sh | 69 ++ babblesim/hw/bsp/nrf52_bsim/bsp.yml | 60 ++ babblesim/hw/bsp/nrf52_bsim/include/bsp/bsp.h | 91 ++ .../hw/bsp/nrf52_bsim/include/os/os_arch.h | 64 ++ babblesim/hw/bsp/nrf52_bsim/include/os/sim.h | 60 ++ .../bsp/nrf52_bsim/nordic_pca10040_debug.cmd | 22 + .../bsp/nrf52_bsim/nordic_pca10040_debug.sh | 45 + .../nrf52_bsim/nordic_pca10040_download.cmd | 22 + .../nrf52_bsim/nordic_pca10040_download.sh | 40 + babblesim/hw/bsp/nrf52_bsim/pkg.yml | 37 + .../nrf52_bsim/src/arch/bsim_arch/os_arch.c | 110 ++ .../src/arch/bsim_arch/os_arch_stack_frame.s | 104 ++ .../nrf52_bsim/src/arch/bsim_arch/sim_priv.h | 44 + .../src/arch/bsim_arch/sim_sched_gen.c | 240 +++++ .../src/arch/bsim_arch/sim_sched_nosig.c | 238 +++++ .../src/arch/bsim_arch/sim_sched_sig.c | 288 ++++++ .../src/arch/bsim_arch/startup_nrf52_bsim.c | 231 +++++ babblesim/hw/bsp/nrf52_bsim/src/hal_bsp.c | 175 ++++ babblesim/hw/bsp/nrf52_bsim/src/sbrk.c | 59 ++ babblesim/hw/bsp/nrf52_bsim/syscfg.yml | 73 ++ .../nrf52_bsim/include/mcu/cmsis_nvic.h | 28 + .../nordic/nrf52_bsim/include/mcu/cortex_m4.h | 34 + .../mcu/nordic/nrf52_bsim/include/mcu/mcu.h | 69 ++ .../nordic/nrf52_bsim/include/mcu/mcu_sim.h | 38 + .../nrf52_bsim/include/mcu/nrf52_clock.h | 50 + .../nordic/nrf52_bsim/include/mcu/nrf52_hal.h | 101 ++ .../nrf52_bsim/include/mcu/nrf52_periph.h | 33 + babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml | 29 + .../mcu/nordic/nrf52_bsim/src/hal_os_tick.c | 226 +++++ .../nordic/nrf52_bsim/src/hal_reset_cause.c | 47 + .../hw/mcu/nordic/nrf52_bsim/src/hal_system.c | 128 +++ .../hw/mcu/nordic/nrf52_bsim/src/hal_timer.c | 949 ++++++++++++++++++ .../hw/mcu/nordic/nrf52_bsim/src/hal_uart.c | 478 +++++++++ .../mcu/nordic/nrf52_bsim/src/hal_watchdog.c | 36 + .../nordic/nrf52_bsim/src/native_uart_cfg.c | 248 +++++ .../nrf52_bsim/src/native_uart_cfg_priv.h | 31 + .../mcu/nordic/nrf52_bsim/src/nrf52_clock.c | 103 ++ .../mcu/nordic/nrf52_bsim/src/system_nrf52.c | 37 + babblesim/hw/mcu/nordic/nrf52_bsim/syscfg.yml | 526 ++++++++++ babblesim/libc/LICENSE | 133 +++ babblesim/libc/pkg.yml | 28 + babblesim/libc/src/strlcat.c | 30 + babblesim/libc/src/strlcpy.c | 26 + babblesim/nrfx/pkg.yml | 37 + babblesim/nrfx/scripts/link_nrfx.sh | 24 + 58 files changed, 6428 insertions(+) create mode 100644 babblesim/.gitignore create mode 100644 babblesim/README.md create mode 100644 babblesim/core/include/argparse.h create mode 100644 babblesim/core/include/cmsis.h create mode 100644 babblesim/core/include/core_cm4.h create mode 100644 babblesim/core/include/time_machine.h create mode 100644 babblesim/core/pkg.yml create mode 100644 babblesim/core/src/argparse.c create mode 100644 babblesim/core/src/cmsis.c create mode 100644 babblesim/core/src/irq_handler.c create mode 100644 babblesim/core/src/main_config.c create mode 100644 babblesim/core/src/time_machine.c create mode 100644 babblesim/hw/babblesim/pkg.yml create mode 100755 babblesim/hw/babblesim/scripts/pre_build1.sh create mode 100644 babblesim/hw/bsp/nrf52_bsim/bsp.yml create mode 100644 babblesim/hw/bsp/nrf52_bsim/include/bsp/bsp.h create mode 100644 babblesim/hw/bsp/nrf52_bsim/include/os/os_arch.h create mode 100644 babblesim/hw/bsp/nrf52_bsim/include/os/sim.h create mode 100755 babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_debug.cmd create mode 100755 babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_debug.sh create mode 100755 babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_download.cmd create mode 100755 babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_download.sh create mode 100644 babblesim/hw/bsp/nrf52_bsim/pkg.yml create mode 100644 babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch.c create mode 100644 babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch_stack_frame.s create mode 100644 babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_priv.h create mode 100644 babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_gen.c create mode 100644 babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_nosig.c create mode 100644 babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_sig.c create mode 100644 babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/startup_nrf52_bsim.c create mode 100644 babblesim/hw/bsp/nrf52_bsim/src/hal_bsp.c create mode 100644 babblesim/hw/bsp/nrf52_bsim/src/sbrk.c create mode 100644 babblesim/hw/bsp/nrf52_bsim/syscfg.yml create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/cmsis_nvic.h create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/cortex_m4.h create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/mcu.h create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/mcu_sim.h create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/nrf52_clock.h create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/nrf52_hal.h create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/nrf52_periph.h create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_os_tick.c create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_reset_cause.c create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_system.c create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_timer.c create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_uart.c create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_watchdog.c create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/src/native_uart_cfg.c create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/src/native_uart_cfg_priv.h create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/src/nrf52_clock.c create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/src/system_nrf52.c create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/syscfg.yml create mode 100644 babblesim/libc/LICENSE create mode 100644 babblesim/libc/pkg.yml create mode 100644 babblesim/libc/src/strlcat.c create mode 100644 babblesim/libc/src/strlcpy.c create mode 100644 babblesim/nrfx/pkg.yml create mode 100755 babblesim/nrfx/scripts/link_nrfx.sh diff --git a/babblesim/.gitignore b/babblesim/.gitignore new file mode 100644 index 0000000000..78e34f10a1 --- /dev/null +++ b/babblesim/.gitignore @@ -0,0 +1,3 @@ +hw/babblesim/components +hw/babblesim/src +nrfx/src \ No newline at end of file diff --git a/babblesim/README.md b/babblesim/README.md new file mode 100644 index 0000000000..c9ba3ef370 --- /dev/null +++ b/babblesim/README.md @@ -0,0 +1 @@ +BabbleSim support for Apache NimBLE diff --git a/babblesim/core/include/argparse.h b/babblesim/core/include/argparse.h new file mode 100644 index 0000000000..7f98b02822 --- /dev/null +++ b/babblesim/core/include/argparse.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017 Oticon A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef BSIM_NRF_ARGS_H +#define BSIM_NRF_ARGS_H + +#include +#include "NRF_hw_args.h" +#include "bs_cmd_line.h" +#include "bs_cmd_line_typical.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct nrf52_bsim_args_t { + BS_BASIC_DEVICE_OPTIONS_FIELDS + nrf_hw_sub_args_t nrf_hw; +}; + +struct nrf52_bsim_args_t *nrfbsim_argsparse(int argc, char *argv[]); +void nrfbsim_register_args(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/babblesim/core/include/cmsis.h b/babblesim/core/include/cmsis.h new file mode 100644 index 0000000000..8f9a6a3d4c --- /dev/null +++ b/babblesim/core/include/cmsis.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020 Oticon A/S + * Copyright (c) 2021 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * This header defines replacements for inline + * ARM Cortex-M CMSIS intrinsics. + */ + +#ifndef BOARDS_POSIX_NRF52_BSIM_CMSIS_H +#define BOARDS_POSIX_NRF52_BSIM_CMSIS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Implement the following ARM intrinsics as no-op: + * - ARM Data Synchronization Barrier + * - ARM Data Memory Synchronization Barrier + * - ARM Instruction Synchronization Barrier + * - ARM No Operation + */ +#ifndef __DMB +#define __DMB() +#endif + +#ifndef __DSB +#define __DSB() +#endif + +#ifndef __ISB +#define __ISB() +#endif + +#ifndef __NOP +#define __NOP() +#endif + +void NVIC_SystemReset(void); +void __disable_irq(void); +void __enable_irq(void); +uint32_t __get_PRIMASK(void); + +#ifdef __cplusplus +} +#endif + +#endif /* BOARDS_POSIX_NRF52_BSIM_CMSIS_H */ diff --git a/babblesim/core/include/core_cm4.h b/babblesim/core/include/core_cm4.h new file mode 100644 index 0000000000..ef8f9c3fb9 --- /dev/null +++ b/babblesim/core/include/core_cm4.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020 Oticon A/S + * Copyright (c) 2021 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _BSIM_CORE_CM4_H +#define _BSIM_CORE_CM4_H + +#include + +/* Include the original ext_NRF52_hw_models core_cm4.h */ +#include <../HW_models/core_cm4.h> + +/* Add missing function definitions */ +extern void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority); +extern void NVIC_EnableIRQ(IRQn_Type IRQn); +extern void NVIC_DisableIRQ(IRQn_Type IRQn); + +void __WFI(void); + +#ifndef __REV +#define __REV __builtin_bswap32 +#endif + +#endif diff --git a/babblesim/core/include/time_machine.h b/babblesim/core/include/time_machine.h new file mode 100644 index 0000000000..da28d01399 --- /dev/null +++ b/babblesim/core/include/time_machine.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017 Oticon A/S + * Copyright (c) 2021 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _TIME_MACHINE_H +#define _TIME_MACHINE_H + +#include "bs_types.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +extern bs_time_t now; +bs_time_t tm_get_abs_time(void); +bs_time_t tm_get_hw_time(void); +bs_time_t tm_hw_time_to_abs_time(bs_time_t hwtime); +bs_time_t tm_abs_time_to_hw_time(bs_time_t abstime); + +void tm_reset_hw_times(void); + +void tm_find_next_timer_to_trigger(void); +bs_time_t tm_get_next_timer_abstime(void); + +void tm_update_last_phy_sync_time(bs_time_t abs_time); + +void tm_set_phy_max_resync_offset(bs_time_t offset_in_us); + +void tm_run_forever(void); + +void tm_sleep_until_hw_time(bs_time_t hw_time); + +void tm_sleep_until_abs_time(bs_time_t time); + +void tm_start(void); + +void tm_tick(void); + +void tm_tick_limited(bs_time_t max_time_diff); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/babblesim/core/pkg.yml b/babblesim/core/pkg.yml new file mode 100644 index 0000000000..3b0c2e9a67 --- /dev/null +++ b/babblesim/core/pkg.yml @@ -0,0 +1,37 @@ +# +# 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: babblesim/core +pkg.type: sdk +pkg.description: time machine, irq handeler, core +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - "@apache-mynewt-core/kernel/os" + - "@apache-mynewt-nimble/nimble/controller" + - "@apache-mynewt-nimble/nimble/transport" + - "babblesim/hw/babblesim" + +pkg.req_apis: + - ble_transport + +pkg.init: + bsim_start: 9999 diff --git a/babblesim/core/src/argparse.c b/babblesim/core/src/argparse.c new file mode 100644 index 0000000000..68f13de433 --- /dev/null +++ b/babblesim/core/src/argparse.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2017 Oticon A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "bs_tracing.h" +#include "bs_oswrap.h" +#include "bs_dump_files.h" +#include "argparse.h" +#include "NRF_hw_args.h" +#include "bs_cmd_line.h" +#include "bs_dynargs.h" +#include "bs_cmd_line_typical.h" +#include "NRF_HWLowL.h" + +static bs_args_struct_t *args_struct; +static struct nrf52_bsim_args_t arg; +const char *bogus_sim_id = "bogus"; + +static void cmd_trace_lvl_found(char *argv, int offset) +{ + bs_trace_set_level(arg.verb); +} + +static void cmd_gdev_nbr_found(char *argv, int offset) +{ + bs_trace_set_prefix_dev(arg.global_device_nbr); +} + +static bool nosim; +static void cmd_nosim_found(char *argv, int offset) +{ + hwll_set_nosim(true); +} + +static void print_no_sim_warning(void) +{ + bs_trace_warning("Neither simulation id or the device number " + "have been set. I assume you want to run " + "without a BabbleSim phy (-nosim)\n"); + bs_trace_warning("If this is not what you wanted, check with " + "--help how to set them\n"); + bs_trace_raw(3, "setting sim_id to 'bogus', device number to 0 " + "and nosim\n"); +} + +void nrfbsim_register_args(void) +{ +#define args (&arg) + /* This define is quite ugly, but allows reusing the definitions + * provided by the utils library */ + static bs_args_struct_t args_struct_toadd[] = { + ARG_TABLE_S_ID, + ARG_TABLE_P_ID_2G4, + ARG_TABLE_DEV_NBR, + ARG_TABLE_GDEV_NBR, + ARG_TABLE_VERB, + ARG_TABLE_SEED, + ARG_TABLE_COLOR, + ARG_TABLE_NOCOLOR, + ARG_TABLE_FORCECOLOR, + _NRF_HW_SUB_CMD_ARG_STRUCT, + /* + * Fields: + * manual, mandatory, switch, + * option_name, var_name, type, + * destination, callback, + * description + */ + {false, false, true, + "nosim", "", 'b', + (void *)&nosim, cmd_nosim_found, + "(debug feature) Do not connect to the phy"}, + BS_DUMP_FILES_ARGS, + {true, false, false, + "argsmain", "arg", 'l', + NULL, NULL, + "The arguments that follow will be passed to main (default)"}, + ARG_TABLE_ENDMARKER + }; +#undef args + + bs_add_dynargs(&args_struct, args_struct_toadd); +} + +/** + * Check the arguments provided in the command line: set args based on it or + * defaults, and check they are correct + */ +struct nrf52_bsim_args_t *nrfbsim_argsparse(int argc, char *argv[]) +{ + bs_args_set_defaults(args_struct); + arg.verb = 2; + bs_trace_set_level(arg.verb); + nrf_hw_sub_cmline_set_defaults(&arg.nrf_hw); + static const char default_phy[] = "2G4"; + + for (int i = 1; i < argc; i++) { + if (bs_is_option(argv[i], "argsmain", 0)) { + continue; + } + + if (!bs_args_parse_one_arg(argv[i], args_struct)) { + bs_args_print_switches_help(args_struct); + bs_trace_error_line("Incorrect option %s\n", + argv[i]); + } + } + + /** + * If the user did not set the simulation id or device number + * we assume he wanted to run with nosim (but warn him) + */ + if ((!nosim) && (arg.s_id == NULL) && (arg.device_nbr == UINT_MAX)) { + print_no_sim_warning(); + nosim = true; + hwll_set_nosim(true); + } + if (nosim) { + if (arg.s_id == NULL) { + arg.s_id = (char *)bogus_sim_id; + } + if (arg.device_nbr == UINT_MAX) { + arg.device_nbr = 0; + } + } + + if (arg.device_nbr == UINT_MAX) { + bs_args_print_switches_help(args_struct); + bs_trace_error_line("The command line option " + "needs to be set\n"); + } + if (arg.global_device_nbr == UINT_MAX) { + arg.global_device_nbr = arg.device_nbr; + bs_trace_set_prefix_dev(arg.global_device_nbr); + } + if (!arg.s_id) { + bs_args_print_switches_help(args_struct); + bs_trace_error_line("The command line option " + "needs to be set\n"); + } + if (!arg.p_id) { + arg.p_id = (char *)default_phy; + } + + if (arg.rseed == UINT_MAX) { + arg.rseed = 0x1000 + arg.device_nbr; + } + return &arg; +} diff --git a/babblesim/core/src/cmsis.c b/babblesim/core/src/cmsis.c new file mode 100644 index 0000000000..622676c881 --- /dev/null +++ b/babblesim/core/src/cmsis.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * Copyright (c) 2020 Oticon A/S + * Copyright (c) 2021 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "irq_ctrl.h" + +#include "irq_sources.h" +#include +#include "cmsis.h" +#include "os/sim.h" + +#include +#include +#include +#include "irq_sources.h" +#include +#include "cmsis.h" + +extern void (* systemVectors[256])(void); + +/* + * Replacement for ARMs NVIC functions() + */ +void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + hw_irq_ctrl_raise_im_from_sw(IRQn); +} + +void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + hw_irq_ctrl_clear_irq(IRQn); +} + +void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + hw_irq_ctrl_disable_irq(IRQn); +} + +void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + hw_irq_ctrl_enable_irq(IRQn); +} + +void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + hw_irq_ctrl_prio_set(IRQn, priority); +} + +uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + return hw_irq_ctrl_get_prio(IRQn); +} + +void NVIC_SystemReset(void) +{ + inner_main_clean_up(1); +} + +/* + * Replacements for some other CMSIS functions + */ +void __enable_irq(void) +{ + hw_irq_ctrl_change_lock(false); +} + +void __disable_irq(void) +{ + hw_irq_ctrl_change_lock(true); +} + +uint32_t __get_PRIMASK(void) +{ + return hw_irq_ctrl_get_current_lock(); +} + +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + systemVectors[(int32_t)IRQn + 16] = (void(*)(void))vector; +} diff --git a/babblesim/core/src/irq_handler.c b/babblesim/core/src/irq_handler.c new file mode 100644 index 0000000000..805d7ecdc3 --- /dev/null +++ b/babblesim/core/src/irq_handler.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2017 Oticon A/S + * + * SPDX-License-Identifier: Apache-2.0 + * + * SW side of the IRQ handling + */ + +#include +#include "irq_ctrl.h" +#include "irq_sources.h" +#include "os/sim.h" + +static int currently_running_irq = -1; +extern void (* const systemVectors[256])(void); + +/** + * When an interrupt is raised, this function is called to handle it and, if + * needed, swap to a re-enabled thread + * + * Note that even that this function is executing in a Zephyr thread, it is + * effectively the model of the interrupt controller passing context to the IRQ + * handler and therefore its priority handling + */ + +void posix_interrupt_raised(void) +{ + uint64_t irq_lock; + int irq_nbr; + + irq_lock = hw_irq_ctrl_get_current_lock(); + + if (irq_lock) { + /* "spurious" wakes can happen with interrupts locked */ + return; + } + + while ((irq_nbr = hw_irq_ctrl_get_highest_prio_irq()) != -1) { + int last_current_running_prio = hw_irq_ctrl_get_cur_prio(); + int last_running_irq = currently_running_irq; + + hw_irq_ctrl_set_cur_prio(hw_irq_ctrl_get_prio(irq_nbr)); + hw_irq_ctrl_clear_irq(irq_nbr); + + currently_running_irq = irq_nbr; + systemVectors[irq_nbr + 16](); + currently_running_irq = last_running_irq; + + hw_irq_ctrl_set_cur_prio(last_current_running_prio); + } +} + +/** + * Thru this function the IRQ controller can raise an immediate interrupt which + * will interrupt the SW itself + * (this function should only be called from the HW model code, from SW threads) + */ +void posix_irq_handler_im_from_sw(void) +{ + int sr = 0; + + sr = sig_block_irq_on(); + /* + * if a higher priority interrupt than the possibly currently running is + * pending we go immediately into irq_handler() to vector into its + * handler + */ + if (hw_irq_ctrl_get_highest_prio_irq() != -1) { + posix_interrupt_raised(); + } + if (sr) { + sig_unblock_irq_off(); + } +} diff --git a/babblesim/core/src/main_config.c b/babblesim/core/src/main_config.c new file mode 100644 index 0000000000..4116e07978 --- /dev/null +++ b/babblesim/core/src/main_config.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017-2018 Oticon A/S + * Copyright (c) 2021 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "NRF_HW_model_top.h" +#include "NRF_HWLowL.h" +#include "bs_tracing.h" +#include "bs_symbols.h" +#include "bs_types.h" +#include "bs_rand_main.h" +#include "bs_pc_backchannel.h" +#include "bs_dump_files.h" +#include "argparse.h" +#include "time_machine.h" +#include "os/mynewt.h" +#include +#include "os/sim.h" + +uint global_device_nbr; +struct nrf52_bsim_args_t *args; + +void +bst_tick(bs_time_t time) +{ + return; +} + +uint8_t +inner_main_clean_up(int exit_code) +{ + hwll_terminate_simulation(); + nrf_hw_models_free_all(); + bs_dump_files_close_all(); + + bs_clean_back_channels(); + return 0; +} + +uint8_t +main_clean_up_trace_wrap(void) +{ + return inner_main_clean_up(0); +} + +void +bsim_init(int argc, char** argv, int (*main_fn)(int argc, char **arg)) +{ + setvbuf(stdout, NULL, _IOLBF, 512); + setvbuf(stderr, NULL, _IOLBF, 512); + + bs_trace_register_cleanup_function(main_clean_up_trace_wrap); + bs_trace_register_time_function(tm_get_abs_time); + + nrf_hw_pre_init(); + nrfbsim_register_args(); + + args = nrfbsim_argsparse(argc, argv); + global_device_nbr = args->global_device_nbr; + + bs_read_function_names_from_Tsymbols(argv[0]); + + nrf_hw_initialize(&args->nrf_hw); + os_init(main_fn); + os_start(); +} + +void +bsim_start(void) +{ + bs_trace_raw(9, "%s: Connecting to phy...\n", __func__); + hwll_connect_to_phy(args->device_nbr, args->s_id, args->p_id); + bs_trace_raw(9, "%s: Connected\n", __func__); + + bs_random_init(args->rseed); + bs_dump_files_open(args->s_id, args->global_device_nbr); +} diff --git a/babblesim/core/src/time_machine.c b/babblesim/core/src/time_machine.c new file mode 100644 index 0000000000..38b3f424a5 --- /dev/null +++ b/babblesim/core/src/time_machine.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2017-2018 Oticon A/S + * Copyright (c) 2021 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "NRF_HW_model_top.h" +#include "NRF_HWLowL.h" +#include "bs_tracing.h" +#include "bs_types.h" +#include "bs_utils.h" +#include +#include +#include +#include +#include + +/* Note: All timers are relative to hw_time and NOT to 'now' */ +extern bs_time_t timer_nrf_main_timer; + +/* The events priorities are as in this list from top to bottom + * Priority being which timer executes first if several trigger at the same + * instant + */ +static enum { + NRF_HW_MAIN_TIMER = 0, + NUMBER_OF_TIMERS, + NONE +} next_timer_index = NONE; + +static bs_time_t *Timer_list[NUMBER_OF_TIMERS] = { + &timer_nrf_main_timer, +}; +static bs_time_t next_timer_time = TIME_NEVER; + +/* + * Current absolute time of this device, as the device knows it. + * It is never reset: + */ +bs_time_t now; +/* Current time the HW of this device things it is */ +static bs_time_t hw_time; +/* + * Offset between the current absolute time of the device and the HW time + * That is, the absolute time when the HW_time got reset + */ +static bs_time_t hw_time_delta; + +/* Last time we synchronized with the bsim PHY, in device abs time */ +static bs_time_t last_bsim_phy_sync_time; + +#define BSIM_DEFAULT_PHY_MAX_RESYNC_OFFSET 1000000 +/* At least every second we will inform the simulator about our timing */ +static bs_time_t max_resync_offset = BSIM_DEFAULT_PHY_MAX_RESYNC_OFFSET; + +/** + * Set the maximum amount of time the device will spend without talking + * (synching) with the phy. + * This does not change the functional behavior of the Zephyr code or of the + * radio emulation, and it is only relevant if special test code running in the + * device interacts behind the scenes with other devices test code. + * Setting for example a value of 5ms will ensure that this device time + * will never be more than 5ms away from the phy. Setting it in all devices + * to 5ms would then ensure no device time is farther apart than 5ms from any + * other. + * + * Note that setting low values has a performance penalty. + */ +void +tm_set_phy_max_resync_offset(bs_time_t offset_in_us) +{ + max_resync_offset = offset_in_us; +} + +/** + * Return the absolute current time (no HW model except the RADIO + * should look into this) + */ +bs_time_t +tm_get_abs_time(void) +{ + return now; +} + +/** + * Return the current HW time + */ +bs_time_t +tm_get_hw_time(void) +{ + return hw_time; +} + +bs_time_t +posix_get_hw_cycle(void) +{ + return tm_get_hw_time(); +} + +/** + * Reset the HW time + */ +static void +tm_reset_hw_time(void) +{ + hw_time = 0; + hw_time_delta = now; + if (now != 0) { + bs_trace_error_line("Reset not supposed to happen after " + "initialization\n"); + } +} + +/** + * Update the current hw_time value given the absolute time + */ +INLINE void +tm_update_HW_time(void) +{ + hw_time = now - hw_time_delta; +} + +/* + * Reset the HW time + */ +void +tm_reset_hw_times(void) +{ + tm_reset_hw_time(); +} + +/** + * Advance the internal time values of this device until time + */ +void +tm_sleep_until_abs_time(bs_time_t time) +{ + if (time >= now) { + /* + * Ensure that at least we sync with the phy + * every max_resync_offset + */ + if (time > last_bsim_phy_sync_time + max_resync_offset) { + hwll_sync_time_with_phy(time); + last_bsim_phy_sync_time = time; + } + + now = time; + } else { + /* LCOV_EXCL_START */ + bs_trace_warning_manual_time_line(now, "next_time_time " + "corrupted (%"PRItime"<= %"PRItime", timer idx=%i)\n", + time, now, next_timer_index); + /* LCOV_EXCL_STOP */ + } + tm_update_HW_time(); +} + +/** + * Keep track of the last time we synchronized the time with the scheduler + */ +void +tm_update_last_phy_sync_time(bs_time_t abs_time) +{ + last_bsim_phy_sync_time = abs_time; +} + +/** + * Advance the internal time values of this device + * until the HW time reaches hw_time + */ +void +tm_sleep_until_hw_time(bs_time_t hw_time) +{ + bs_time_t next_time = TIME_NEVER; + + if (hw_time != TIME_NEVER) { + next_time = hw_time + hw_time_delta; + } + + tm_sleep_until_abs_time(next_time); +} + +/** + * Look into all timers and update next_timer accordingly + * To be called each time a "timed process" updates its timer + */ +void +tm_find_next_timer_to_trigger(void) +{ + next_timer_time = *Timer_list[0]; + next_timer_index = 0; + + for (uint i = 1; i < NUMBER_OF_TIMERS; i++) { + if (next_timer_time > *Timer_list[i]) { + next_timer_time = *Timer_list[i]; + next_timer_index = i; + } + } +} + +bs_time_t +tm_get_next_timer_abstime(void) +{ + return next_timer_time + hw_time_delta; +} + +bs_time_t +tm_hw_time_to_abs_time(bs_time_t hwtime) +{ + if (hwtime == TIME_NEVER) { + return TIME_NEVER; + } + return hwtime + hw_time_delta; +} + +bs_time_t +tm_abs_time_to_hw_time(bs_time_t abstime) +{ + if (abstime == TIME_NEVER) { + return TIME_NEVER; + } + return abstime - hw_time_delta; +} + +void +tm_tick_limited(bs_time_t max_time_diff) +{ + bs_time_t time_to_wait; + + if (max_time_diff != TIME_NEVER && now + max_time_diff < next_timer_time) { + time_to_wait = now + max_time_diff; + } else { + time_to_wait = next_timer_time; + } + + tm_sleep_until_hw_time(time_to_wait); + switch (next_timer_index) { + case NRF_HW_MAIN_TIMER: + nrf_hw_some_timer_reached(); + break; + default: + bs_trace_error_time_line("next_timer_index " + "corrupted\n"); + break; + } + tm_find_next_timer_to_trigger(); +} + +void +tm_tick(void) +{ + tm_tick_limited(TIME_NEVER); +} diff --git a/babblesim/hw/babblesim/pkg.yml b/babblesim/hw/babblesim/pkg.yml new file mode 100644 index 0000000000..ad28efbcb2 --- /dev/null +++ b/babblesim/hw/babblesim/pkg.yml @@ -0,0 +1,44 @@ +# +# 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: babblesim/hw/babblesim +pkg.description: BabbleSim stuff +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" + +pkg.type: sdk + +pkg.include_dirs: + - components/ext_NRF52_hw_models/src/nrfx/mdk_replacements + - components/ext_NRF52_hw_models/src/HW_models + - components/ext_NRF52_hw_models/src/nrfx_config + - components/ext_NRF52_hw_models/src/nrfx/nrfx_replacements + - components/libUtilv1/src/ + - components/libPhyComv1/src/ + - components/libRandv2/src/ + - components/ext_libCryptov1/src/ + +pkg.src_dirs: + - src + +pkg.pre_build_cmds: + scripts/pre_build1.sh: 1 + +pkg.lflags: + - -ldl \ No newline at end of file diff --git a/babblesim/hw/babblesim/scripts/pre_build1.sh b/babblesim/hw/babblesim/scripts/pre_build1.sh new file mode 100755 index 0000000000..3f3fec5add --- /dev/null +++ b/babblesim/hw/babblesim/scripts/pre_build1.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# +# 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. +# + +if [ -z ${BSIM_COMPONENTS_PATH+x} ]; then + echo "This board requires the BabbleSim simulator. Please set" \ + "the environment variable BSIM_COMPONENTS_PATH to point to its components" \ + "folder. More information can be found in" \ + "https://babblesim.github.io/folder_structure_and_env.html" + exit 1 +fi + +if [ -z ${BSIM_OUT_PATH+x} ]; then + echo "This board requires the BabbleSim simulator. Please set" \ + "the environment variable BSIM_OUT_PATH to point to the folder where the" \ + "simulator is compiled to. More information can be found in" \ + "https://babblesim.github.io/folder_structure_and_env.html" + exit 1 +fi + +if [[ -d "$(pwd)/components" ]] +then + echo "Babblesim components: Directory exists. Removing and linking again..." + rm -r $(pwd)/components +else + echo "Babblesim components: Linking components..." +fi + +ln -nsf $BSIM_OUT_PATH/components + +if [[ -d "$(pwd)/src" ]] +then + echo "Babblesim libraries src: Directory exists. Removing and linking again..." + rm -r $(pwd)/src +else + echo "Babblesim components: Linking components..." +fi + +mkdir -p src +ln -nsf $BSIM_OUT_PATH/components + +# Create links to all .32.a files +# find $BSIM_OUT_PATH/lib/$lib -name "*.32.a" -type f -exec ln -t src -nsf {} \; + +# Copy all .32.a files +find $BSIM_OUT_PATH/lib/$lib -name "*.32.a" -type f -exec cp -t src -f {} \; + +# XXX: Workaround for bad linking by newt. Sometimes newt will link +# nrf weak functions from nrf_hal_originals.o instead of their BabbleSim +# replacements inside libNRF52_hw_models.32.a. But as long as the other +# weak functions, that do not have their replacements, are not used, +# we can just remove the file from the .a library here. +ar d src/libNRF52_hw_models.32.a nrf_hal_originals.o diff --git a/babblesim/hw/bsp/nrf52_bsim/bsp.yml b/babblesim/hw/bsp/nrf52_bsim/bsp.yml new file mode 100644 index 0000000000..edd2189d16 --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/bsp.yml @@ -0,0 +1,60 @@ +# +# 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. +# + +bsp.name: "nRF52 DK" +bsp.url: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52-DK +bsp.maker: "Nordic Semiconductor" +bsp.arch: bsim_arch +bsp.compiler: "@apache-mynewt-core/compiler/sim" +bsp.downloadscript: "hw/bsp/nrf52_bsim/nordic_pca10040_download.sh" +bsp.debugscript: "hw/bsp/nrf52_bsim/nordic_pca10040_debug.sh" +bsp.downloadscript.WINDOWS.OVERWRITE: "hw/bsp/nrf52_bsim/nordic_pca10040_download.cmd" +bsp.debugscript.WINDOWS.OVERWRITE: "hw/bsp/nrf52_bsim/nordic_pca10040_debug.cmd" + +bsp.flash_map: + areas: + # System areas. + FLASH_AREA_BOOTLOADER: + device: 0 + offset: 0x00000000 + size: 16kB + FLASH_AREA_IMAGE_0: + device: 0 + offset: 0x00008000 + size: 232kB + FLASH_AREA_IMAGE_1: + device: 0 + offset: 0x00042000 + size: 232kB + FLASH_AREA_IMAGE_SCRATCH: + device: 0 + offset: 0x0007c000 + size: 4kB + + # User areas. + FLASH_AREA_REBOOT_LOG: + user_id: 0 + device: 0 + offset: 0x00004000 + size: 16kB + FLASH_AREA_NFFS: + user_id: 1 + device: 0 + offset: 0x0007d000 + size: 12kB diff --git a/babblesim/hw/bsp/nrf52_bsim/include/bsp/bsp.h b/babblesim/hw/bsp/nrf52_bsim/include/bsp/bsp.h new file mode 100644 index 0000000000..c096b887c2 --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/include/bsp/bsp.h @@ -0,0 +1,91 @@ +/* + * 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_BSP_H +#define H_BSP_H + +#include + +#include "os/mynewt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Define special stackos sections */ +#define sec_data_core __attribute__((section(".data.core"))) +#define sec_bss_core __attribute__((section(".bss.core"))) +#define sec_bss_nz_core __attribute__((section(".bss.core.nz"))) + +/* More convenient section placement macros. */ +#define bssnz_t sec_bss_nz_core + +extern uint8_t _ram_start; +#define RAM_SIZE 0x10000 + +/* LED pins */ +#define LED_1 (17) +#define LED_2 (18) +#define LED_3 (19) +#define LED_4 (20) +#define LED_BLINK_PIN (LED_1) + +/* Buttons */ +#define BUTTON_1 (13) +#define BUTTON_2 (14) +#define BUTTON_3 (15) +#define BUTTON_4 (16) + +/* Arduino pins */ +#define ARDUINO_PIN_D0 11 +#define ARDUINO_PIN_D1 12 +#define ARDUINO_PIN_D2 13 +#define ARDUINO_PIN_D3 14 +#define ARDUINO_PIN_D4 15 +#define ARDUINO_PIN_D5 16 +#define ARDUINO_PIN_D6 17 +#define ARDUINO_PIN_D7 18 +#define ARDUINO_PIN_D8 19 +#define ARDUINO_PIN_D9 20 +#define ARDUINO_PIN_D10 22 +#define ARDUINO_PIN_D11 23 +#define ARDUINO_PIN_D12 24 +#define ARDUINO_PIN_D13 25 +#define ARDUINO_PIN_A0 3 +#define ARDUINO_PIN_A1 4 +#define ARDUINO_PIN_A2 28 +#define ARDUINO_PIN_A3 29 +#define ARDUINO_PIN_A4 30 +#define ARDUINO_PIN_A5 31 + +#define ARDUINO_PIN_RX ARDUINO_PIN_D0 +#define ARDUINO_PIN_TX ARDUINO_PIN_D1 + +#define ARDUINO_PIN_SCL 27 +#define ARDUINO_PIN_SDA 26 + +#define ARDUINO_PIN_SCK ARDUINO_PIN_D13 +#define ARDUINO_PIN_MOSI ARDUINO_PIN_D11 +#define ARDUINO_PIN_MISO ARDUINO_PIN_D12 + +#ifdef __cplusplus +} +#endif + +#endif /* H_BSP_H */ diff --git a/babblesim/hw/bsp/nrf52_bsim/include/os/os_arch.h b/babblesim/hw/bsp/nrf52_bsim/include/os/os_arch.h new file mode 100644 index 0000000000..32bc97bcb2 --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/include/os/os_arch.h @@ -0,0 +1,64 @@ +/* + * 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 _OS_ARCH_ARM_H +#define _OS_ARCH_ARM_H + +#include +#include "syscfg/syscfg.h" +#include "mcu/cmsis_nvic.h" +#include "mcu/cortex_m4.h" +#include +#include "mcu/mcu_sim.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* CPU status register */ +typedef uint32_t os_sr_t; + +/* Stack element */ +typedef uint32_t os_stack_t; + +struct stack_frame; +void os_arch_frame_init(struct stack_frame *sf); + +/* Stack sizes for common OS tasks */ +#define OS_SANITY_STACK_SIZE (2000) +#if MYNEWT_VAL(OS_SYSVIEW) +#define OS_IDLE_STACK_SIZE (80) +#else +#define OS_IDLE_STACK_SIZE (4000) +#endif + +static inline int +os_arch_in_isr(void) +{ + return hw_irq_ctrl_get_irq_status(); +} + +/* Include common arch definitions and APIs */ +#include "os/arch/common.h" + +#ifdef __cplusplus +} +#endif + +#endif /* _OS_ARCH_ARM_H */ diff --git a/babblesim/hw/bsp/nrf52_bsim/include/os/sim.h b/babblesim/hw/bsp/nrf52_bsim/include/os/sim.h new file mode 100644 index 0000000000..3d8837b810 --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/include/os/sim.h @@ -0,0 +1,60 @@ +/* + * 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_KERNEL_SIM_ +#define H_KERNEL_SIM_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "os/mynewt.h" +#include "mcu/mcu_sim.h" +struct os_task; +struct stack_frame; + +struct stack_frame { + int sf_mainsp; /* stack on which main() is executing */ + sigjmp_buf sf_jb; + struct os_task *sf_task; +}; + +void sim_task_start(struct stack_frame *sf, int rc); +os_stack_t *sim_task_stack_init(struct os_task *t, os_stack_t *stack_top, + int size); +os_error_t sim_os_start(void); +void sim_os_stop(void); +os_error_t sim_os_init(void); +void sim_ctx_sw(struct os_task *next_t); +os_sr_t sim_save_sr(void); +void sim_restore_sr(os_sr_t osr); +int sim_in_critical(void); +void sim_tick_idle(os_time_t ticks); +int sig_block_irq_on(); +void sig_unblock_irq_off(); + +uint8_t inner_main_clean_up(int exit_code); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_debug.cmd b/babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_debug.cmd new file mode 100755 index 0000000000..3444fd3279 --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_debug.cmd @@ -0,0 +1,22 @@ +@rem +@rem Licensed to the Apache Software Foundation (ASF) under one +@rem or more contributor license agreements. See the NOTICE file +@rem distributed with this work for additional information +@rem regarding copyright ownership. The ASF licenses this file +@rem to you under the Apache License, Version 2.0 (the +@rem "License"); you may not use this file except in compliance +@rem with the License. You may obtain a copy of the License at +@rem +@rem http://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, +@rem software distributed under the License is distributed on an +@rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@rem KIND, either express or implied. See the License for the +@rem specific language governing permissions and limitations +@rem under the License. +@rem + +@rem Execute a shell with a script of the same name and .sh extension + +@bash "%~dp0%~n0.sh" diff --git a/babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_debug.sh b/babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_debug.sh new file mode 100755 index 0000000000..1e248e4e6a --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_debug.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# 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. +# + +# Called with following variables set: +# - CORE_PATH is absolute path to @apache-mynewt-core +# - BSP_PATH is absolute path to hw/bsp/bsp_name +# - BIN_BASENAME is the path to prefix to target binary, +# .elf appended to name is the ELF file +# - FEATURES holds the target features string +# - EXTRA_JTAG_CMD holds extra parameters to pass to jtag software +# - RESET set if target should be reset when attaching +# - NO_GDB set if we should not start gdb to debug +# + +. $CORE_PATH/hw/scripts/jlink.sh + +FILE_NAME=$BIN_BASENAME.elf + +if [ $# -gt 2 ]; then + SPLIT_ELF_NAME=$3.elf + # TODO -- this magic number 0x42000 is the location of the second image + # slot. we should either get this from a flash map file or somehow learn + # this from the image itself + EXTRA_GDB_CMDS="add-symbol-file $SPLIT_ELF_NAME 0x8000 -readnow" +fi + +JLINK_DEV="nRF52" + +jlink_debug diff --git a/babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_download.cmd b/babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_download.cmd new file mode 100755 index 0000000000..3444fd3279 --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_download.cmd @@ -0,0 +1,22 @@ +@rem +@rem Licensed to the Apache Software Foundation (ASF) under one +@rem or more contributor license agreements. See the NOTICE file +@rem distributed with this work for additional information +@rem regarding copyright ownership. The ASF licenses this file +@rem to you under the Apache License, Version 2.0 (the +@rem "License"); you may not use this file except in compliance +@rem with the License. You may obtain a copy of the License at +@rem +@rem http://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, +@rem software distributed under the License is distributed on an +@rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@rem KIND, either express or implied. See the License for the +@rem specific language governing permissions and limitations +@rem under the License. +@rem + +@rem Execute a shell with a script of the same name and .sh extension + +@bash "%~dp0%~n0.sh" diff --git a/babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_download.sh b/babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_download.sh new file mode 100755 index 0000000000..08d45b4641 --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/nordic_pca10040_download.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# 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. + +# Called with following variables set: +# - CORE_PATH is absolute path to @apache-mynewt-core +# - BSP_PATH is absolute path to hw/bsp/bsp_name +# - BIN_BASENAME is the path to prefix to target binary, +# .elf appended to name is the ELF file +# - IMAGE_SLOT is the image slot to download to (for non-mfg-image, non-boot) +# - FEATURES holds the target features string +# - EXTRA_JTAG_CMD holds extra parameters to pass to jtag software +# - MFG_IMAGE is "1" if this is a manufacturing image +# - FLASH_OFFSET contains the flash offset to download to +# - BOOT_LOADER is set if downloading a bootloader + +. $CORE_PATH/hw/scripts/jlink.sh + +if [ "$MFG_IMAGE" ]; then + FLASH_OFFSET=0x0 +fi + +JLINK_DEV="nRF52" + +common_file_to_load +jlink_load diff --git a/babblesim/hw/bsp/nrf52_bsim/pkg.yml b/babblesim/hw/bsp/nrf52_bsim/pkg.yml new file mode 100644 index 0000000000..6662a76dd3 --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/pkg.yml @@ -0,0 +1,37 @@ +# +# 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: babblesim/hw/bsp/nrf52_bsim +pkg.type: bsp +pkg.description: nRF52 on BabbleSim +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" + +pkg.cflags: + - '-DNRF52832_XXAA' + - '-DBABBLESIM' + +pkg.cflags.HARDFLOAT: + - -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +pkg.deps: + - "@apache-mynewt-core/hw/drivers/uart/uart_hal" + - "babblesim/hw/mcu/nordic/nrf52_bsim" + - "babblesim/hw/babblesim" + - "babblesim/core" diff --git a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch.c b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch.c new file mode 100644 index 0000000000..6700e90a6a --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch.c @@ -0,0 +1,110 @@ +/* + * 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. + */ + +#include "os/mynewt.h" +#include "os/sim.h" +#include "sim_priv.h" +#include + +/* + * From HAL_CM4.s + */ +extern void SVC_Handler(void); +extern void PendSV_Handler(void); +extern void SysTick_Handler(void); + +/* + * Assert that 'sf_mainsp' and 'sf_jb' are at the specific offsets where + * os_arch_frame_init() expects them to be. + */ +CTASSERT(offsetof(struct stack_frame, sf_mainsp) == 0); +CTASSERT(offsetof(struct stack_frame, sf_jb) == 4); + +void +os_arch_task_start(struct stack_frame *sf, int rc) +{ + sim_task_start(sf, rc); +} + +os_stack_t * +os_arch_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size) +{ + return sim_task_stack_init(t, stack_top, size); +} + +os_error_t +os_arch_os_start(void) +{ + return sim_os_start(); +} + +void +os_arch_os_stop(void) +{ + sim_os_stop(); +} + +void +PendSV_Handler(void) +{ + sim_switch_tasks(); +} + +os_error_t +os_arch_os_init(void) +{ + NVIC_SetVector(PendSV_IRQn, (uint32_t)PendSV_Handler); + return sim_os_init(); +} + +void +os_arch_ctx_sw(struct os_task *next_t) +{ + sim_ctx_sw(next_t); +} + +os_sr_t +os_arch_save_sr(void) +{ + sim_save_sr(); + return hw_irq_ctrl_change_lock(1); +} + +void +os_arch_restore_sr(os_sr_t osr) +{ + hw_irq_ctrl_change_lock(osr); + sim_restore_sr(osr); +} + + +int +os_arch_in_critical(void) +{ + return sim_in_critical(); +} + +void +__assert_func(const char *file, int line, const char *func, const char *e) +{ +#if MYNEWT_VAL(OS_ASSERT_CB) + os_assert_cb(); +#endif + _Exit(1); +} diff --git a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch_stack_frame.s b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch_stack_frame.s new file mode 100644 index 0000000000..81e5c066ed --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch_stack_frame.s @@ -0,0 +1,104 @@ +/* + * 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. + */ + +#if defined MN_LINUX +#define sigsetjmp __sigsetjmp +#define CNAME(x) x +#elif defined MN_OSX +#define sigsetjmp sigsetjmp +#define CNAME(x) _ ## x +#elif defined MN_FreeBSD +#define sigsetjmp sigsetjmp +#define CNAME(x) x +#else +#error "unsupported platform" +#endif + + .text + .code32 + .p2align 4, 0x90 /* align on 16-byte boundary and fill with NOPs */ + + .globl CNAME(os_arch_frame_init) + .globl _os_arch_frame_init + /* + * void os_arch_frame_init(struct stack_frame *sf) + */ +CNAME(os_arch_frame_init): + push %ebp /* function prologue for backtrace */ + mov %esp,%ebp + push %esi /* save %esi before using it as a tmpreg */ + + /* + * At this point we are executing on the main() stack: + * ---------------- + * stack_frame ptr 0xc(%esp) + * ---------------- + * return address 0x8(%esp) + * ---------------- + * saved ebp 0x4(%esp) + * ---------------- + * saved esi 0x0(%esp) + * ---------------- + */ + movl 0xc(%esp),%esi /* %esi = 'sf' */ + movl %esp,0x0(%esi) /* sf->mainsp = %esp */ + + /* + * Switch the stack so the stack pointer stored in 'sf->sf_jb' points + * to the task stack. This is slightly complicated because OS X wants + * the incoming stack pointer to be 16-byte aligned. + * + * ---------------- + * sf (other fields) + * ---------------- + * sf (sf_jb) 0x4(%esi) + * ---------------- + * sf (sf_mainsp) 0x0(%esi) + * ---------------- + * alignment padding variable (0 to 12 bytes) + * ---------------- + * savemask (0) 0x4(%esp) + * ---------------- + * pointer to sf_jb 0x0(%esp) + * ---------------- + */ + movl %esi,%esp + subl $0x8,%esp /* make room for sigsetjmp() arguments */ + andl $0xfffffff0,%esp /* align %esp on 16-byte boundary */ + leal 0x4(%esi),%eax /* %eax = &sf->sf_jb */ + movl %eax,0x0(%esp) + movl $0, 0x4(%esp) + call CNAME(sigsetjmp) /* sigsetjmp(sf->sf_jb, 0) */ + test %eax,%eax + jne 1f + movl 0x0(%esi),%esp /* switch back to the main() stack */ + pop %esi + pop %ebp + ret /* return to os_arch_task_stack_init() */ +1: + lea 2f,%ecx + push %ecx /* retaddr */ + push $0 /* frame pointer */ + movl %esp,%ebp /* handcrafted prologue for backtrace */ + push %eax /* rc */ + push %esi /* sf */ + call CNAME(os_arch_task_start) /* os_arch_task_start(sf, rc) */ + /* never returns */ +2: + nop diff --git a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_priv.h b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_priv.h new file mode 100644 index 0000000000..39984dfc22 --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_priv.h @@ -0,0 +1,44 @@ +/* + * 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_SIM_PRIV_ +#define H_SIM_PRIV_ + +#include +#include "os/mynewt.h" +#include "mcu/mcu_sim.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define OS_USEC_PER_TICK (1000000 / OS_TICKS_PER_SEC) + +void sim_switch_tasks(void); +void sim_tick(void); +void sim_signals_init(void); +void sim_signals_cleanup(void); + +extern pid_t sim_pid; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_gen.c b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_gen.c new file mode 100644 index 0000000000..b3c192fcd7 --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_gen.c @@ -0,0 +1,240 @@ +/* + * 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. + */ + +/** + * This file contains code that is shared by both sim implementations (signals + * and no-signals). + */ + +#include "os/mynewt.h" + +#include + +#ifdef __APPLE__ +#define _XOPEN_SOURCE +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include "os/sim.h" +#include "sim_priv.h" + +#define sim_setjmp(__jb) sigsetjmp(__jb, 0) +#define sim_longjmp(__jb, __ret) siglongjmp(__jb, __ret) + +pid_t sim_pid; + +void +sim_switch_tasks(void) +{ + struct os_task *t, *next_t; + struct stack_frame *sf; + int rc; + + OS_ASSERT_CRITICAL(); + + t = os_sched_get_current_task(); + next_t = os_sched_next_task(); + if (t == next_t) { + /* + * Context switch not needed - just return. + */ + return; + } + + if (t) { + sf = (struct stack_frame *) t->t_stackptr; + + rc = sim_setjmp(sf->sf_jb); + if (rc != 0) { + OS_ASSERT_CRITICAL(); + return; + } + } + + os_sched_ctx_sw_hook(next_t); + + os_sched_set_current_task(next_t); + + sf = (struct stack_frame *) next_t->t_stackptr; + sim_longjmp(sf->sf_jb, 1); +} + +void +sim_tick(void) +{ + struct timeval time_now, time_diff; + int ticks; + + static struct timeval time_last; + static int time_inited; + + OS_ASSERT_CRITICAL(); + + if (!time_inited) { + gettimeofday(&time_last, NULL); + time_inited = 1; + } + + gettimeofday(&time_now, NULL); + if (timercmp(&time_now, &time_last, <)) { + /* + * System time going backwards. + */ + time_last = time_now; + } else { + timersub(&time_now, &time_last, &time_diff); + + ticks = time_diff.tv_sec * OS_TICKS_PER_SEC; + ticks += time_diff.tv_usec / OS_USEC_PER_TICK; + + /* + * Update 'time_last' but account for the remainder usecs that did not + * contribute towards whole 'ticks'. + */ + time_diff.tv_sec = 0; + time_diff.tv_usec %= OS_USEC_PER_TICK; + timersub(&time_now, &time_diff, &time_last); + + os_time_advance(ticks); + } +} + +#define OS_TICK_PRIO 7 + +static void +sim_start_timer(void) +{ + /* Intitialize and start system clock timer */ + os_tick_init(OS_TICKS_PER_SEC, OS_TICK_PRIO); +} + +static void +sim_stop_timer(void) +{ + struct itimerval it; + int rc; + + memset(&it, 0, sizeof(it)); + + rc = setitimer(ITIMER_REAL, &it, NULL); + assert(rc == 0); +} + +/* + * Called from 'os_arch_frame_init()' when setjmp returns indirectly via + * longjmp. The return value of setjmp is passed to this function as 'rc'. + */ +void +sim_task_start(struct stack_frame *sf, int rc) +{ + struct os_task *task; + + /* + * Interrupts are disabled when a task starts executing. This happens in + * two different ways: + * - via sim_os_start() for the first task. + * - via os_sched() for all other tasks. + * + * Enable interrupts before starting the task. + */ + OS_EXIT_CRITICAL(0); + + task = sf->sf_task; + task->t_func(task->t_arg); + + /* A task handler should never return. */ + assert(0); +} + +os_stack_t * +sim_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size) +{ + struct stack_frame *sf; + + sf = (struct stack_frame *) ((uint8_t *) stack_top - sizeof(*sf)); + sf->sf_task = t; + + os_arch_frame_init(sf); + + return ((os_stack_t *)sf); +} + +os_error_t +sim_os_start(void) +{ + struct stack_frame *sf; + struct os_task *t; + os_sr_t sr; + + /* + * Disable interrupts before enabling any interrupt sources. Pending + * interrupts will be recognized when the first task starts executing. + */ + OS_ENTER_CRITICAL(sr); + assert(sr == 0); + + /* Enable the interrupt sources */ + sim_start_timer(); + + t = os_sched_next_task(); + os_sched_set_current_task(t); + + g_os_started = 1; + + sf = (struct stack_frame *) t->t_stackptr; + sim_longjmp(sf->sf_jb, 1); + + return 0; +} + +/** + * Stops the tick timer and clears the "started" flag. This function is only + * implemented for sim. + */ +void +sim_os_stop(void) +{ + sim_stop_timer(); + sim_signals_cleanup(); + g_os_started = 0; +} + +os_error_t +sim_os_init(void) +{ + sim_pid = getpid(); + g_current_task = NULL; + + STAILQ_INIT(&g_os_task_list); + TAILQ_INIT(&g_os_run_list); + TAILQ_INIT(&g_os_sleep_list); + + sim_signals_init(); + + os_init_idle_task(); + + return OS_OK; +} diff --git a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_nosig.c b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_nosig.c new file mode 100644 index 0000000000..fadb712adb --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_nosig.c @@ -0,0 +1,238 @@ +/* + * 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. + */ + +/** + * This file implements the "no-signals" version of sim. This implementation + * does not use signals to perform context switches. This is the less correct + * version of sim: the OS tick timer only runs while the idle task is active. + * Therefore, a sleeping high-priority task will not preempt a low-priority + * task due to a timing event (e.g., delay or callout expired). However, this + * version of sim does not suffer from the stability issues that affect the + * "signals" implementation. + * + * To use this version of sim, disable the MCU_NATIVE_USE_SIGNALS syscfg + * setting. + */ + +#include "os/mynewt.h" + +#if !MYNEWT_VAL(MCU_NATIVE_USE_SIGNALS) + +#include + +#ifdef __APPLE__ +#define _XOPEN_SOURCE +#endif + +#include +#include +#include +#include +#include +#include +#include +#include "sim_priv.h" + +static sigset_t nosigs; +static sigset_t suspsigs; /* signals delivered in sigsuspend() */ + +static int ctx_sw_pending; +static int interrupts_enabled = 1; + +void +sim_ctx_sw(struct os_task *next_t) +{ + if (interrupts_enabled) { + /* Perform the context switch immediately. */ + sim_switch_tasks(); + } else { + /* Remember that we want to perform a context switch. Perform it when + * interrupts are re-enabled. + */ + ctx_sw_pending = 1; + } +} + +/* + * Enter a critical section. + * + * Returns 1 if interrupts were already disabled; 0 otherwise. + */ +os_sr_t +sim_save_sr(void) +{ + if (!interrupts_enabled) { + return 1; + } + + interrupts_enabled = 0; + return 0; +} + +void +sim_restore_sr(os_sr_t osr) +{ + OS_ASSERT_CRITICAL(); + assert(osr == 0 || osr == 1); + + if (osr == 1) { + /* Exiting a nested critical section */ + return; + } + + if (ctx_sw_pending) { + /* A context switch was requested while interrupts were disabled. + * Perform it now that interrupts are enabled again. + */ + ctx_sw_pending = 0; + sim_switch_tasks(); + } + interrupts_enabled = 1; +} + +int +sim_in_critical(void) +{ + return !interrupts_enabled; +} + +/** + * Unblocks the SIGALRM signal that is delivered by the OS tick timer. + */ +static void +unblock_timer(void) +{ + sigset_t sigs; + int rc; + + sigemptyset(&sigs); + sigaddset(&sigs, SIGALRM); + + rc = sigprocmask(SIG_UNBLOCK, &sigs, NULL); + assert(rc == 0); +} + +/** + * Blocks the SIGALRM signal that is delivered by the OS tick timer. + */ +static void +block_timer(void) +{ + sigset_t sigs; + int rc; + + sigemptyset(&sigs); + sigaddset(&sigs, SIGALRM); + + rc = sigprocmask(SIG_BLOCK, &sigs, NULL); + assert(rc == 0); +} + +static void +sig_handler_alrm(int sig) +{ + /* Wake the idle task. */ + sigaddset(&suspsigs, sig); +} + +void +sim_tick_idle(os_time_t ticks) +{ + int rc; + struct itimerval it; + + OS_ASSERT_CRITICAL(); + + if (ticks > 0) { + /* + * Enter tickless regime and set the timer to fire after 'ticks' + * worth of time has elapsed. + */ + it.it_value.tv_sec = ticks / OS_TICKS_PER_SEC; + it.it_value.tv_usec = (ticks % OS_TICKS_PER_SEC) * OS_USEC_PER_TICK; + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = OS_USEC_PER_TICK; + rc = setitimer(ITIMER_REAL, &it, NULL); + assert(rc == 0); + } + + unblock_timer(); + + sigemptyset(&suspsigs); + sigsuspend(&nosigs); /* Wait for a signal to wake us up */ + + block_timer(); + + /* + * Call handlers for signals delivered to the process during sigsuspend(). + * The SIGALRM handler is called before any other handlers to ensure that + * OS time is always correct. + */ + if (sigismember(&suspsigs, SIGALRM)) { + sim_tick(); + } + + if (ticks > 0) { + /* + * Enable the periodic timer interrupt. + */ + it.it_value.tv_sec = 0; + it.it_value.tv_usec = OS_USEC_PER_TICK; + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = OS_USEC_PER_TICK; + rc = setitimer(ITIMER_REAL, &it, NULL); + assert(rc == 0); + } +} + +void +sim_signals_init(void) +{ + sigset_t sigset_alrm; + struct sigaction sa; + int error; + + block_timer(); + + sigemptyset(&nosigs); + + sigemptyset(&sigset_alrm); + sigaddset(&sigset_alrm, SIGALRM); + + memset(&sa, 0, sizeof sa); + sa.sa_handler = sig_handler_alrm; + sa.sa_mask = sigset_alrm; + sa.sa_flags = SA_RESTART; + error = sigaction(SIGALRM, &sa, NULL); + assert(error == 0); +} + +void +sim_signals_cleanup(void) +{ + int error; + struct sigaction sa; + + memset(&sa, 0, sizeof sa); + sa.sa_handler = SIG_DFL; + error = sigaction(SIGALRM, &sa, NULL); + assert(error == 0); +} + +#endif /* !MYNEWT_VAL(MCU_NATIVE_USE_SIGNALS) */ diff --git a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_sig.c b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_sig.c new file mode 100644 index 0000000000..c26abcea03 --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_sig.c @@ -0,0 +1,288 @@ +/* + * 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. + */ + +/** + * This file implements the "signals" version of sim. This implementation uses + * signals to perform context switches. This is the more correct version of + * sim: the OS tick timer will cause a high-priority task to preempt a + * low-priority task. Unfortunately, there are stability issues because a task + * can be preempted while it is in the middle of a system call, potentially + * causing deadlock or memory corruption. + * + * To use this version of sim, enable the MCU_NATIVE_USE_SIGNALS syscfg + * setting. + */ + +#include "os/mynewt.h" + +#if MYNEWT_VAL(MCU_NATIVE_USE_SIGNALS) + +#include "sim_priv.h" + +#include + +#ifdef __APPLE__ +#define _XOPEN_SOURCE +#endif + +#include +#include +#include +#include +#include +#include +#include + +static bool suspended; /* process is blocked in sigsuspend() */ +static sigset_t suspsigs; /* signals delivered in sigsuspend() */ +static sigset_t allsigs; +static sigset_t nosigs; + +static int in_irq; +int counter = 0; + +int +sig_block_irq_on() +{ + int error; + + counter++; + + error = sigprocmask(SIG_BLOCK, &allsigs, NULL); + + in_irq = 1; + assert(error == 0); + return 1; +} + +void +sig_unblock_irq_off() +{ + int error; + + in_irq = 0; + + if (counter > 0) { + counter--; + return; + } + + error = sigprocmask(SIG_UNBLOCK, &allsigs, NULL); + assert(error == 0); + +} + +void +sim_ctx_sw(struct os_task *next_t) +{ + /* + * gdb will stop execution of the program on most signals (e.g. SIGUSR1) + * whereas it passes SIGURG to the process without any special settings. + */ + kill(sim_pid, SIGURG); +} + +static void +ctxsw_handler(int sig) +{ + assert(in_irq==0); + OS_ASSERT_CRITICAL(); + + /* + * Just record that this handler was called when the process was blocked. + * The handler will be called after sigsuspend() returns in the correct + * order. + */ + if (suspended) { + sigaddset(&suspsigs, sig); + } else { + sim_switch_tasks(); + } +} + +/* + * Disable signals and enter a critical section. + * + * Returns 1 if signals were already blocked and 0 otherwise. + */ +os_sr_t +sim_save_sr(void) +{ + int error; + sigset_t omask; + + counter++; + + error = sigprocmask(SIG_BLOCK, &allsigs, &omask); + assert(error == 0); + + /* + * If any one of the signals in 'allsigs' is present in 'omask' then + * we are already inside a critical section. + */ + return (sigismember(&omask, SIGURG)); +} + +void +sim_restore_sr(os_sr_t osr) +{ + int error; + + OS_ASSERT_CRITICAL(); + assert(osr == 0 || osr == 1); + + if (counter > 0) { + counter--; + } + + if (osr == 1 || in_irq == 1 || counter > 0) { + /* Exiting a nested critical section */ + return; + } + + error = sigprocmask(SIG_UNBLOCK, &allsigs, NULL); + assert(error == 0); +} + +int +sim_in_critical(void) +{ + int error; + sigset_t omask; + + error = sigprocmask(SIG_SETMASK, NULL, &omask); + assert(error == 0); + + /* + * If any one of the signals in 'allsigs' is present in 'omask' then + * we are already inside a critical section. + */ + return (sigismember(&omask, SIGURG)); +} + +static struct { + int num; + void (*handler)(int sig); +} signals[] = { +// { SIGALRM, timer_handler }, + { SIGURG, ctxsw_handler }, +}; + +#define NUMSIGS (sizeof(signals)/sizeof(signals[0])) + +void +sim_tick_idle(os_time_t ticks) +{ + int i, rc, sig; + struct itimerval it; + void (*handler)(int sig); + + OS_ASSERT_CRITICAL(); + + if (ticks > 0) { + /* + * Enter tickless regime and set the timer to fire after 'ticks' + * worth of time has elapsed. + */ + it.it_value.tv_sec = ticks / OS_TICKS_PER_SEC; + it.it_value.tv_usec = (ticks % OS_TICKS_PER_SEC) * OS_USEC_PER_TICK; + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = OS_USEC_PER_TICK; + rc = setitimer(ITIMER_REAL, &it, NULL); + assert(rc == 0); + } + + suspended = true; + sigemptyset(&suspsigs); + sigsuspend(&nosigs); /* Wait for a signal to wake us up */ + suspended = false; + + /* + * Call handlers for signals delivered to the process during sigsuspend(). + * The SIGALRM handler is called before any other handlers to ensure that + * OS time is always correct. + */ + if (sigismember(&suspsigs, SIGALRM)) { + sim_tick(); + } + for (i = 0; i < NUMSIGS; i++) { + sig = signals[i].num; + handler = signals[i].handler; + if (sig != SIGALRM && sigismember(&suspsigs, sig)) { + handler(sig); + } + } + + if (ticks > 0) { + /* + * Enable the periodic timer interrupt. + */ + it.it_value.tv_sec = 0; + it.it_value.tv_usec = OS_USEC_PER_TICK; + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = OS_USEC_PER_TICK; + rc = setitimer(ITIMER_REAL, &it, NULL); + assert(rc == 0); + } +} + +void +sim_signals_init(void) +{ + int i, error; + struct sigaction sa; + + sigemptyset(&nosigs); + sigemptyset(&allsigs); + for (i = 0; i < NUMSIGS; i++) { + sigaddset(&allsigs, signals[i].num); + } + + for (i = 0; i < NUMSIGS; i++) { + memset(&sa, 0, sizeof sa); + sa.sa_handler = signals[i].handler; + sa.sa_mask = allsigs; + sa.sa_flags = SA_RESTART; + error = sigaction(signals[i].num, &sa, NULL); + assert(error == 0); + } + + /* + * We use SIGALRM as a proxy for 'allsigs' to check if we are inside + * a critical section (for e.g. see sim_in_critical()). Make sure + * that SIGALRM is indeed present in 'allsigs'. + */ +// assert(sigismember(&allsigs, SIGALRM)); +} + +void +sim_signals_cleanup(void) +{ + int i, error; + struct sigaction sa; + + for (i = 0; i < NUMSIGS; i++) { + memset(&sa, 0, sizeof sa); + sa.sa_handler = SIG_DFL; + error = sigaction(signals[i].num, &sa, NULL); + assert(error == 0); + } +} + +#endif /* MYNEWT_VAL(MCU_NATIVE_USE_SIGNALS) */ diff --git a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/startup_nrf52_bsim.c b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/startup_nrf52_bsim.c new file mode 100644 index 0000000000..d4810689bc --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/startup_nrf52_bsim.c @@ -0,0 +1,231 @@ +/* + * 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. + */ + +#include "nrf.h" + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! Weak symbol reference. */ +#define WEAK __attribute__ ((weak)) + +/************************************************************************************************** + Functions +**************************************************************************************************/ + +extern void SystemInit(void); +static void SystemDefaultHandler(void); + +/* Core vectors. */ +void WEAK Reset_Handler(void); +void WEAK NMI_Handler(void); +void WEAK HardFault_Handler(void); +void WEAK MemoryManagement_Handler(void); +void WEAK BusFault_Handler(void); +void WEAK UsageFault_Handler(void); +void WEAK SVC_Handler(void); +void WEAK DebugMon_Handler(void); +void WEAK PendSV_Handler(void); +void WEAK SysTick_Handler(void); +void WEAK POWER_CLOCK_IRQHandler(void); +void WEAK RADIO_IRQHandler(void); +void WEAK UARTE0_UART0_IRQHandler(void); +void WEAK SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler(void); +void WEAK SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler(void); +void WEAK NFCT_IRQHandler(void); +void WEAK GPIOTE_IRQHandler(void); +void WEAK SAADC_IRQHandler(void); +void WEAK TIMER0_IRQHandler(void); +void WEAK TIMER1_IRQHandler(void); +void WEAK TIMER2_IRQHandler(void); +void WEAK RTC0_IRQHandler(void); +void WEAK TEMP_IRQHandler(void); +void WEAK RNG_IRQHandler(void); +void WEAK ECB_IRQHandler(void); +void WEAK CCM_AAR_IRQHandler(void); +void WEAK WDT_IRQHandler(void); +void WEAK RTC1_IRQHandler(void); +void WEAK QDEC_IRQHandler(void); +void WEAK COMP_LPCOMP_IRQHandler(void); +void WEAK SWI0_EGU0_IRQHandler(void); +void WEAK SWI1_EGU1_IRQHandler(void); +void WEAK SWI2_EGU2_IRQHandler(void); +void WEAK SWI3_EGU3_IRQHandler(void); +void WEAK SWI4_EGU4_IRQHandler(void); +void WEAK SWI5_EGU5_IRQHandler(void); +void WEAK TIMER3_IRQHandler(void); +void WEAK TIMER4_IRQHandler(void); +void WEAK PWM0_IRQHandler(void); +void WEAK PDM_IRQHandler(void); +void WEAK MWU_IRQHandler(void); +void WEAK PWM1_IRQHandler(void); +void WEAK PWM2_IRQHandler(void); +void WEAK SPIM2_SPIS2_SPI2_IRQHandler(void); +void WEAK RTC2_IRQHandler(void); +void WEAK I2S_IRQHandler(void); +void WEAK FPU_IRQHandler(void); + +/* Assign default weak references. Override these values by defining a new function with the same name. */ +#pragma weak NMI_Handler = SystemDefaultHandler +#pragma weak HardFault_Handler = SystemDefaultHandler +#pragma weak MemoryManagement_Handler = SystemDefaultHandler +#pragma weak BusFault_Handler = SystemDefaultHandler +#pragma weak UsageFault_Handler = SystemDefaultHandler +#pragma weak SVC_Handler = SystemDefaultHandler +#pragma weak DebugMon_Handler = SystemDefaultHandler +#pragma weak PendSV_Handler = SystemDefaultHandler +#pragma weak SysTick_Handler = SystemDefaultHandler +#pragma weak POWER_CLOCK_IRQHandler = SystemDefaultHandler +#pragma weak RADIO_IRQHandler = SystemDefaultHandler +#pragma weak UARTE0_UART0_IRQHandler = SystemDefaultHandler +#pragma weak SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler = SystemDefaultHandler +#pragma weak SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler = SystemDefaultHandler +#pragma weak NFCT_IRQHandler = SystemDefaultHandler +#pragma weak GPIOTE_IRQHandler = SystemDefaultHandler +#pragma weak SAADC_IRQHandler = SystemDefaultHandler +#pragma weak TIMER0_IRQHandler = SystemDefaultHandler +#pragma weak TIMER1_IRQHandler = SystemDefaultHandler +#pragma weak TIMER2_IRQHandler = SystemDefaultHandler +#pragma weak RTC0_IRQHandler = SystemDefaultHandler +#pragma weak TEMP_IRQHandler = SystemDefaultHandler +#pragma weak RNG_IRQHandler = SystemDefaultHandler +#pragma weak ECB_IRQHandler = SystemDefaultHandler +#pragma weak CCM_AAR_IRQHandler = SystemDefaultHandler +#pragma weak WDT_IRQHandler = SystemDefaultHandler +#pragma weak RTC1_IRQHandler = SystemDefaultHandler +#pragma weak QDEC_IRQHandler = SystemDefaultHandler +#pragma weak COMP_LPCOMP_IRQHandler = SystemDefaultHandler +#pragma weak SWI0_EGU0_IRQHandler = SystemDefaultHandler +#pragma weak SWI1_EGU1_IRQHandler = SystemDefaultHandler +#pragma weak SWI2_EGU2_IRQHandler = SystemDefaultHandler +#pragma weak SWI3_EGU3_IRQHandler = SystemDefaultHandler +#pragma weak SWI4_EGU4_IRQHandler = SystemDefaultHandler +#pragma weak SWI5_EGU5_IRQHandler = SystemDefaultHandler +#pragma weak TIMER3_IRQHandler = SystemDefaultHandler +#pragma weak TIMER4_IRQHandler = SystemDefaultHandler +#pragma weak PWM0_IRQHandler = SystemDefaultHandler +#pragma weak PDM_IRQHandler = SystemDefaultHandler +#pragma weak MWU_IRQHandler = SystemDefaultHandler +#pragma weak PWM1_IRQHandler = SystemDefaultHandler +#pragma weak PWM2_IRQHandler = SystemDefaultHandler +#pragma weak SPIM2_SPIS2_SPI2_IRQHandler = SystemDefaultHandler +#pragma weak RTC2_IRQHandler = SystemDefaultHandler +#pragma weak I2S_IRQHandler = SystemDefaultHandler +#pragma weak FPU_IRQHandler = SystemDefaultHandler + +/************************************************************************************************** + Global variables +**************************************************************************************************/ + +/*! Core vector table */ +void (* systemVectors[256])(void) = +{ + 0, /* 0: The initial stack pointer */ + Reset_Handler, /* 1: The reset handler */ + NMI_Handler, /* 2: The NMI handler */ + HardFault_Handler, /* 3: The hard fault handler */ + MemoryManagement_Handler, /* 4: The MPU fault handler */ + BusFault_Handler, /* 5: The bus fault handler */ + UsageFault_Handler, /* 6: The usage fault handler */ + 0, /* 7: Reserved */ + 0, /* 8: Reserved */ + 0, /* 9: Reserved */ + 0, /* 10: Reserved */ + SVC_Handler, /* 11: SVCall handler */ + DebugMon_Handler, /* 12: Debug monitor handler */ + 0, /* 13: Reserved */ + PendSV_Handler, /* 14: The PendSV handler */ + SysTick_Handler, /* 15: The SysTick handler */ + + /* External interrupts */ + POWER_CLOCK_IRQHandler, /* 16: POWER_CLOCK */ + RADIO_IRQHandler, /* 17: RADIO */ + UARTE0_UART0_IRQHandler, /* 18: UART0 */ + SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler, /* 19: SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 */ + SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler, /* 20: SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1 */ + NFCT_IRQHandler, /* 21: NFCT */ + GPIOTE_IRQHandler, /* 22: GPIOTE */ + SAADC_IRQHandler, /* 23: SAADC */ + TIMER0_IRQHandler, /* 24: TIMER0 */ + TIMER1_IRQHandler, /* 25: TIMER1 */ + TIMER2_IRQHandler, /* 26: TIMER2 */ + RTC0_IRQHandler, /* 27: RTC0 */ + TEMP_IRQHandler, /* 28: TEMP */ + RNG_IRQHandler, /* 29: RNG */ + ECB_IRQHandler, /* 30: ECB */ + CCM_AAR_IRQHandler, /* 31: CCM_AAR */ + WDT_IRQHandler, /* 32: WDT */ + RTC1_IRQHandler, /* 33: RTC1 */ + QDEC_IRQHandler, /* 34: QDEC */ + COMP_LPCOMP_IRQHandler, /* 35: COMP_LPCOMP */ + SWI0_EGU0_IRQHandler, /* 36: SWI0_EGU0 */ + SWI1_EGU1_IRQHandler, /* 37: SWI1_EGU1 */ + SWI2_EGU2_IRQHandler, /* 38: SWI2_EGU2 */ + SWI3_EGU3_IRQHandler, /* 39: SWI3_EGU3 */ + SWI4_EGU4_IRQHandler, /* 40: SWI4_EGU4 */ + SWI5_EGU5_IRQHandler, /* 41: SWI5_EGU5 */ + TIMER3_IRQHandler, /* 42: TIMER3 */ + TIMER4_IRQHandler, /* 43: TIMER4 */ + PWM0_IRQHandler, /* 44: PWM0 */ + PDM_IRQHandler, /* 45: PDM */ + 0, /* 46: Reserved */ + 0, /* 47: Reserved */ + MWU_IRQHandler, /* 48: MWU */ + PWM1_IRQHandler, /* 49: PWM1 */ + PWM2_IRQHandler, /* 50: PWM2 */ + SPIM2_SPIS2_SPI2_IRQHandler, /* 51: SPIM2_SPIS2_SPI2 */ + RTC2_IRQHandler, /* 52: RTC2 */ + I2S_IRQHandler, /* 53: I2S */ + FPU_IRQHandler, /* 54: FPU */ + 0, /* 55: Reserved */ + 0, /* 56: Reserved */ + 0, /* 57: Reserved */ + 0, /* 58: Reserved */ + 0, /* 59: Reserved */ + 0, /* 60: Reserved */ + 0, /* 61: Reserved */ + 0, /* 62: Reserved */ + 0 /* 63: Reserved */ + /* 64..127: Reserved */ +}; + +/*************************************************************************************************/ +/*! + * \brief Reset handler. + */ +/*************************************************************************************************/ +void Reset_Handler(void) +{ + /* Core initialization. */ + SystemInit(); +} + +/*************************************************************************************************/ +/*! + * \brief Default vector handler. + * + * \param None. + */ +/*************************************************************************************************/ +static void SystemDefaultHandler(void) +{ + volatile unsigned int forever = 1; + while (forever); +} diff --git a/babblesim/hw/bsp/nrf52_bsim/src/hal_bsp.c b/babblesim/hw/bsp/nrf52_bsim/src/hal_bsp.c new file mode 100644 index 0000000000..4250249e53 --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/src/hal_bsp.c @@ -0,0 +1,175 @@ +/* + * 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. + */ + +#include +#include +#include +#include "os/mynewt.h" +#include "nrfx.h" +#include "flash_map/flash_map.h" +#include "hal/hal_bsp.h" +#include "hal/hal_flash.h" +#include "hal/hal_system.h" +#include "mcu/nrf52_hal.h" +#include "mcu/nrf52_periph.h" +#include "bsp/bsp.h" +#include "defs/sections.h" +#include "uart_hal/uart_hal.h" +#include "uart/uart.h" +#if MYNEWT_VAL(ENC_FLASH_DEV) +#include +#endif + +/* + * What memory to include in coredump. + */ +static const struct hal_bsp_mem_dump dump_cfg[] = { + [0] = { + .hbmd_start = &_ram_start, + .hbmd_size = RAM_SIZE + } +}; + +#if MYNEWT_VAL(ENC_FLASH_DEV) +static sec_data_secret struct eflash_nrf5x_dev enc_flash_dev0 = { + .end_dev = { + .efd_hal = { + .hf_itf = &enc_flash_funcs, + }, + .efd_hwdev = &nrf52k_flash_dev + } +}; +#endif + +const struct hal_flash * +hal_bsp_flash_dev(uint8_t id) +{ +// /* +// * Internal flash mapped to id 0. +// */ +// if (id == 0) { +// return &nrf52k_flash_dev; +// } +//#if MYNEWT_VAL(ENC_FLASH_DEV) +// if (id == 1) { +// return &enc_flash_dev0.end_dev.efd_hal; +// } +//#endif + return NULL; +} + +const struct hal_bsp_mem_dump * +hal_bsp_core_dump(int *area_cnt) +{ + *area_cnt = sizeof(dump_cfg) / sizeof(dump_cfg[0]); + return dump_cfg; +} + +int +hal_bsp_power_state(int state) +{ + return (0); +} + +/** + * Returns the configured priority for the given interrupt. If no priority + * configured, return the priority passed in + * + * @param irq_num + * @param pri + * + * @return uint32_t + */ +uint32_t +hal_bsp_get_nvic_priority(int irq_num, uint32_t pri) +{ + uint32_t cfg_pri; + + switch (irq_num) { + /* Radio gets highest priority */ + case RADIO_IRQn: + cfg_pri = 0; + break; + default: + cfg_pri = pri; + } + return cfg_pri; +} + +static void +nrf52_periph_create_timers(void) +{ + int rc; + + (void)rc; + +#if MYNEWT_VAL(TIMER_0) + rc = hal_timer_init(0, NULL); + assert(rc == 0); +#endif +#if MYNEWT_VAL(TIMER_1) + rc = hal_timer_init(1, NULL); + assert(rc == 0); +#endif +#if MYNEWT_VAL(TIMER_2) + rc = hal_timer_init(2, NULL); + assert(rc == 0); +#endif +#if MYNEWT_VAL(TIMER_3) + rc = hal_timer_init(3, NULL); + assert(rc == 0); +#endif +#if MYNEWT_VAL(TIMER_4) + rc = hal_timer_init(4, NULL); + assert(rc == 0); +#endif +#if MYNEWT_VAL(TIMER_5) + rc = hal_timer_init(5, NULL); + assert(rc == 0); +#endif + +#if MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0 + rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ)); + assert(rc == 0); +#endif +} + +static struct uart_dev os_bsp_uart0; + +void +hal_bsp_init(void) +{ + /* Make sure system clocks have started */ + hal_system_clock_start(); + + /* Create all available nRF52840 peripherals */ +// nrf52_periph_create(); + nrf52_periph_create_timers(); + + int rc; + + rc = os_dev_create((struct os_dev *) &os_bsp_uart0, "uart0", + OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *) NULL); + assert(rc == 0); +} + +void +hal_bsp_deinit(void) +{ +} diff --git a/babblesim/hw/bsp/nrf52_bsim/src/sbrk.c b/babblesim/hw/bsp/nrf52_bsim/src/sbrk.c new file mode 100644 index 0000000000..5df43c9519 --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/src/sbrk.c @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#include + +/* put these in the data section so they are not cleared by _start */ +static char *sbrkBase __attribute__ ((section (".data"))); +static char *sbrkLimit __attribute__ ((section (".data"))); +static char *brk __attribute__ ((section (".data"))); + +void +_sbrkInit(char *base, char *limit) { + sbrkBase = base; + sbrkLimit = limit; + brk = base; +} + +void * +_sbrk(int incr) +{ + void *prev_brk; + + if (incr < 0) { + /* Returning memory to the heap. */ + incr = -incr; + if (brk - incr < sbrkBase) { + prev_brk = (void *)-1; + } else { + prev_brk = brk; + brk -= incr; + } + } else { + /* Allocating memory from the heap. */ + if (sbrkLimit - brk >= incr) { + prev_brk = brk; + brk += incr; + } else { + prev_brk = (void *)-1; + } + } + + return prev_brk; +} diff --git a/babblesim/hw/bsp/nrf52_bsim/syscfg.yml b/babblesim/hw/bsp/nrf52_bsim/syscfg.yml new file mode 100644 index 0000000000..0e9eb607a9 --- /dev/null +++ b/babblesim/hw/bsp/nrf52_bsim/syscfg.yml @@ -0,0 +1,73 @@ +# 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. +# + +syscfg.defs: + BSP_NRF52: + description: 'Set to indicate that BSP has NRF52' + value: 1 + SOFT_PWM: + description: 'Enable soft PWM' + value: 0 + ENC_FLASH_DEV: + description: 'Encrypting flash driver over interal flash for testing' + value: 0 + UARTBB_0: + description: 'Enable bit-banger UART 0' + value: 0 + RAM_RESIDENT: + description: 'Compile app to be loaded to RAM' + value: 0 + +syscfg.vals: + OS_MAIN_STACK_SIZE: 8000 + BLE_HCI_TRANSPORT: uart + MCU_TIMER_POLLER_PRIO: 0 + BLE_LL_PRIO: 1 + MCU_UART_POLLER_PRIO: 2 + + # Enable nRF52832 MCU + MCU_TARGET: nRF52832 + # Set default pins for peripherals + UART_0_PIN_TX: 6 + UART_0_PIN_RX: 8 + UART_0_PIN_RTS: 5 + UART_0_PIN_CTS: 7 + SPI_0_MASTER_PIN_SCK: 23 + SPI_0_MASTER_PIN_MOSI: 24 + SPI_0_MASTER_PIN_MISO: 25 + SPI_0_SLAVE_PIN_SCK: 23 + SPI_0_SLAVE_PIN_MOSI: 24 + SPI_0_SLAVE_PIN_MISO: 25 + SPI_0_SLAVE_PIN_SS: 22 + I2C_0_PIN_SCL: 27 + I2C_0_PIN_SDA: 26 + + CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS + REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG + NFFS_FLASH_AREA: FLASH_AREA_NFFS + COREDUMP_FLASH_AREA: FLASH_AREA_IMAGE_1 + MCU_DCDC_ENABLED: 1 + MCU_LFCLK_SOURCE: LFXO + BOOT_SERIAL_DETECT_PIN: 13 # Button 1 + +syscfg.vals.BLE_CONTROLLER: + TIMER_0: 0 + TIMER_5: 1 + OS_CPUTIME_FREQ: 32768 + OS_CPUTIME_TIMER_NUM: 5 + BLE_LL_RFMGMT_ENABLE_TIME: 1500 diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/cmsis_nvic.h b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/cmsis_nvic.h new file mode 100644 index 0000000000..11a812d337 --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/cmsis_nvic.h @@ -0,0 +1,28 @@ +/* mbed Microcontroller Library - cmsis_nvic + * Copyright (c) 2009-2011 ARM Limited. All rights reserved. + * + * CMSIS-style functionality to support dynamic vectors + */ + +#ifndef MBED_CMSIS_NVIC_H +#define MBED_CMSIS_NVIC_H + +#include +#include "nrf.h" + +#define NVIC_NUM_VECTORS (16 + 38) // CORE + MCU Peripherals +#define NVIC_USER_IRQ_OFFSET 16 + +#ifdef __cplusplus +extern "C" { +#endif + +void NVIC_Relocate(void); +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); +uint32_t NVIC_GetVector(IRQn_Type IRQn); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/cortex_m4.h b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/cortex_m4.h new file mode 100644 index 0000000000..93f2044473 --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/cortex_m4.h @@ -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. + */ + +#ifndef __MCU_CORTEX_M4_H__ +#define __MCU_CORTEX_M4_H__ + +#include "nrf.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __MCU_CORTEX_M4_H__ */ diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/mcu.h b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/mcu.h new file mode 100644 index 0000000000..1950c85fde --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/mcu.h @@ -0,0 +1,69 @@ +/* + * 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 __MCU_MCU_H_ +#define __MCU_MCU_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Defines for naming GPIOs. NOTE: the nordic chip docs use numeric labels for + * ports. Port A corresponds to Port 0, B to 1, etc. The nrf52832 has only one + * port and thus uses pins 0 - 31. The nrf52840 has two ports but Port 1 only + * has 16 pins. + */ +#define MCU_GPIO_PORTA(pin) ((0 * 16) + (pin)) +#define MCU_GPIO_PORTB(pin) ((1 * 16) + (pin)) + +#if NRF52 + +#define MCU_SYSVIEW_INTERRUPTS \ + "I#1=Reset,I#2=MNI,I#3=HardFault,I#4=MemoryMgmt,I#5=BusFault,I#6=UsageFault," \ + "I#11=SVCall,I#12=DebugMonitor,I#14=PendSV,I#15=SysTick," \ + "I#16=POWER_CLOCK,I#17=RADIO,I#18=UARTE0_UART0,I#19=SPIx0_TWIx0," \ + "I#20=SPIx1_TWIx1,I#21=NFCT,I#22=GPIOTE,I#23=SAADC," \ + "I#24=TIMER0,I#25=TIMER1,I#26=TIMER2,I#27=RTC0,I#28=TEMP,I#29=RNG,I#30=ECB," \ + "I#31=CCM_AAR,I#32=WDT,I#33=RTC1,I#34=QDEC,I#35=COMP_LPCOMP,I#36=SWI0_EGU0," \ + "I#37=SWI1_EGU1,I#38=SWI2_EGU2,I#39=SWI3_EGU3,I#40=SWI4_EGU4,I#41=SWI5_EGU5," \ + "I#42=TIMER3,I#43=TIMER4,I#44=PWM0,I#45=PDM,I#48=MWU,I#49=PWM1,I#50=PWM2," \ + "I#51=SPIx2,I#52=RTC2,I#53=I2S,I#54=FPU" + +#elif NRF52840_XXAA + +#define MCU_SYSVIEW_INTERRUPTS \ + "I#1=Reset,I#2=MNI,I#3=HardFault,I#4=MemoryMgmt,I#5=BusFault,I#6=UsageFault," \ + "I#11=SVCall,I#12=DebugMonitor,I#14=PendSV,I#15=SysTick," \ + "I#16=POWER_CLOCK,I#17=RADIO,I#18=UARTE0_UART0,I#19=SPIx0_TWIx0," \ + "I#20=SPIx1_TWIx1,I#21=NFCT,I#22=GPIOTE,I#23=SAADC," \ + "I#24=TIMER0,I#25=TIMER1,I#26=TIMER2,I#27=RTC0,I#28=TEMP,I#29=RNG,I#30=ECB," \ + "I#31=CCM_AAR,I#32=WDT,I#33=RTC1,I#34=QDEC,I#35=COMP_LPCOMP,I#36=SWI0_EGU0," \ + "I#37=SWI1_EGU1,I#38=SWI2_EGU2,I#39=SWI3_EGU3,I#40=SWI4_EGU4,I#41=SWI5_EGU5," \ + "I#42=TIMER3,I#43=TIMER4,I#44=PWM0,I#45=PDM,I#48=MWU,I#49=PWM1,I#50=PWM2," \ + "I#51=SPIx2,I#52=RTC2,I#53=I2S,I#54=FPU,I#55=USBD," \ + "I#56=UARTE1,I#57=QSPI,I#58=CRYPTOCELL,I#61=PWM3,I#63=SPIM3" + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __MCU_MCU_H_ */ diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/mcu_sim.h b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/mcu_sim.h new file mode 100644 index 0000000000..26f6cb9842 --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/mcu_sim.h @@ -0,0 +1,38 @@ +/* + * 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 __MCU_SIM_H__ +#define __MCU_SIM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +extern char *native_flash_file; +extern char *native_uart_log_file; +extern const char *native_uart_dev_strs[]; + +void mcu_sim_parse_args(int argc, char **argv); + +void static inline hal_debug_break(void) {} + +#ifdef __cplusplus +} +#endif + +#endif /* __MCU_SIM_H__ */ diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/nrf52_clock.h b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/nrf52_clock.h new file mode 100644 index 0000000000..d86aa98bf2 --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/nrf52_clock.h @@ -0,0 +1,50 @@ +/* + * 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_NRF52_CLOCK_ +#define H_NRF52_CLOCK_ + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * Request HFXO clock be turned on. Note that each request must have a + * corresponding release. + * + * @return int 0: hfxo was already on. 1: hfxo was turned on. + */ +int nrf52_clock_hfxo_request(void); + +/** + * Release the HFXO; caller no longer needs the HFXO to be turned on. Each call + * to release should have been preceeded by a corresponding call to request the + * HFXO + * + * + * @return int 0: HFXO not stopped by this call (others using it) 1: HFXO + * stopped. + */ +int nrf52_clock_hfxo_release(void); + +#ifdef __cplusplus +} +#endif + +#endif /* H_NRF52_CLOCK_ */ diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/nrf52_hal.h b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/nrf52_hal.h new file mode 100644 index 0000000000..df9a016542 --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/nrf52_hal.h @@ -0,0 +1,101 @@ +/* + * 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_NRF52_HAL_ +#define H_NRF52_HAL_ + +#include "cmsis.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Helper functions to enable/disable interrupts. */ +#define __HAL_DISABLE_INTERRUPTS(x) \ + do { \ + x = __get_PRIMASK(); \ + __disable_irq(); \ + } while(0); + +#define __HAL_ENABLE_INTERRUPTS(x) \ + do { \ + if (!x) { \ + __enable_irq(); \ + } \ + } while(0); + +struct nrf52_uart_cfg { + int8_t suc_pin_tx; /* pins for IO */ + int8_t suc_pin_rx; + int8_t suc_pin_rts; + int8_t suc_pin_cts; +}; +const struct nrf52_uart_cfg *bsp_uart_config(void); + +struct nrf52_hal_i2c_cfg { + int scl_pin; + int sda_pin; + uint32_t i2c_frequency; +}; +struct hal_flash; +extern const struct hal_flash nrf52k_flash_dev; +extern const struct hal_flash nrf52k_qspi_dev; + +/* SPI configuration (used for both master and slave) */ +struct nrf52_hal_spi_cfg { + uint8_t sck_pin; + uint8_t mosi_pin; + uint8_t miso_pin; + uint8_t ss_pin; +}; + +/* + * GPIO pin mapping + * + * The logical GPIO pin numbers (0 to N) are mapped to ports in the following + * manner: + * pins 0 - 31: Port 0 + * pins 32 - 48: Port 1. + * + * The nrf52832 has only one port with 32 pins. The nrf52840 has 48 pins and + * uses two ports. + * + * NOTE: in order to save code space, there is no checking done to see if the + * user specifies a pin that is not used by the processor. If an invalid pin + * number is used unexpected and/or erroneous behavior will result. + */ +#if defined(NRF52832_XXAA) || defined(NRF52810_XXAA) || defined(NRF52811_XXAA) +#define HAL_GPIO_INDEX(pin) (pin) +#define HAL_GPIO_PORT(pin) (NRF_P0) +#define HAL_GPIO_MASK(pin) (1 << pin) +#define HAL_GPIOTE_PIN_MASK GPIOTE_CONFIG_PSEL_Msk +#endif + +#ifdef NRF52840_XXAA +#define HAL_GPIO_INDEX(pin) ((pin) & 0x1F) +#define HAL_GPIO_PORT(pin) ((pin) > 31 ? NRF_P1 : NRF_P0) +#define HAL_GPIO_MASK(pin) (1 << HAL_GPIO_INDEX(pin)) +#define HAL_GPIOTE_PIN_MASK (0x3FUL << GPIOTE_CONFIG_PSEL_Pos) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* H_NRF52_HAL_ */ diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/nrf52_periph.h b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/nrf52_periph.h new file mode 100644 index 0000000000..0e49371bad --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/nrf52_periph.h @@ -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. + */ + +#ifndef H_NRF52_PERIPH_ +#define H_NRF52_PERIPH_ + +#ifdef __cplusplus + extern "C" { +#endif + +void nrf52_periph_create(void); + +#ifdef __cplusplus +} +#endif + +#endif /* H_NRF52_PERIPH_ */ diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml b/babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml new file mode 100644 index 0000000000..4f332acbab --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml @@ -0,0 +1,29 @@ +# +# 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: babblesim/hw/mcu/nordic/nrf52_bsim +pkg.description: nRF52 on BabbleSim +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" + +pkg.deps: + - "babblesim/nrfx" + +pkg.deps.BLE_CONTROLLER: + - "@apache-mynewt-nimble/nimble/drivers/nrf52" diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_os_tick.c b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_os_tick.c new file mode 100644 index 0000000000..a2d7170ab7 --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_os_tick.c @@ -0,0 +1,226 @@ +/* + * 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. + */ + +#include +#include "os/mynewt.h" +#include "hal/hal_os_tick.h" +#include "nrf.h" +#include "mcu/cmsis_nvic.h" +#include "mcu/mcu_sim.h" +#include +#include +#include +#include +#include + +/* The OS scheduler requires a low-frequency timer. */ +#if MYNEWT_VAL(OS_SCHEDULING) && !MYNEWT_VAL(MCU_LFCLK_SOURCE) + #error The OS scheduler requires a low-frequency timer; configure MCU_LFCLK_SOURCE +#endif + +#define RTC_FREQ 32768 /* in Hz */ +#define OS_TICK_TIMER NRF_RTC1 +#define OS_TICK_IRQ RTC1_IRQn +#define OS_TICK_CMPREG 3 /* generate timer interrupt */ +#define RTC_COMPARE_INT_MASK(ccreg) (1UL << ((ccreg) + 16)) + +struct hal_os_tick +{ + int ticks_per_ostick; + os_time_t max_idle_ticks; + uint32_t lastocmp; +}; + +struct hal_os_tick g_hal_os_tick; + +/* + * Implement (x - y) where the range of both 'x' and 'y' is limited to 24-bits. + * + * For example: + * + * sub24(0, 0xffffff) = 1 + * sub24(0xffffff, 0xfffffe) = 1 + * sub24(0xffffff, 0) = -1 + * sub24(0x7fffff, 0) = 8388607 + * sub24(0x800000, 0) = -8388608 + */ +static inline int +sub24(uint32_t x, uint32_t y) +{ + int result; + + assert(x <= 0xffffff); + assert(y <= 0xffffff); + + result = x - y; + if (result & 0x800000) { + return (result | 0xff800000); + } else { + return (result & 0x007fffff); + } +} + +static inline uint32_t +nrf52_os_tick_counter(void) +{ + return nrf_rtc_counter_get(OS_TICK_TIMER); +} + +static inline void +nrf52_os_tick_set_ocmp(uint32_t ocmp) +{ + int delta; + uint32_t counter; + + OS_ASSERT_CRITICAL(); + while (1) { + ocmp &= 0xffffff; + nrf_rtc_cc_set(OS_TICK_TIMER, OS_TICK_CMPREG, ocmp); + counter = nrf52_os_tick_counter(); + /* + * From nRF52 Product specification + * + * - If Counter is 'N' writing (N) or (N + 1) to CC register + * may not trigger a compare event. + * + * - If Counter is 'N' writing (N + 2) to CC register is guaranteed + * to trigger a compare event at 'N + 2'. + */ + delta = sub24(ocmp, counter); + if (delta > 2) { + break; + } + ocmp += g_hal_os_tick.ticks_per_ostick; + } +} + +static void +nrf52_timer_handler(void) +{ + int delta; + int ticks; + os_sr_t sr; + uint32_t counter; + + os_trace_isr_enter(); + OS_ENTER_CRITICAL(sr); + + /* Calculate elapsed ticks and advance OS time. */ + + counter = nrf52_os_tick_counter(); + delta = sub24(counter, g_hal_os_tick.lastocmp); + ticks = delta / g_hal_os_tick.ticks_per_ostick; + os_time_advance(ticks); + + /* Clear timer interrupt */ + OS_TICK_TIMER->EVENTS_COMPARE[OS_TICK_CMPREG] = 0; + + /* Update the time associated with the most recent tick */ + g_hal_os_tick.lastocmp = (g_hal_os_tick.lastocmp + + (ticks * g_hal_os_tick.ticks_per_ostick)) & 0xffffff; + + /* Update the output compare to interrupt at the next tick */ + nrf52_os_tick_set_ocmp(g_hal_os_tick.lastocmp + g_hal_os_tick.ticks_per_ostick); + + OS_EXIT_CRITICAL(sr); + os_trace_isr_exit(); +} + +/* Wait For Interrupt */ +void +__WFI(void) +{ + while (hw_irq_ctrl_get_irq_status() == 0) { + tm_tick(); + } +} + +void +os_tick_idle(os_time_t ticks) +{ + uint32_t ocmp; + + OS_ASSERT_CRITICAL(); + + if (ticks > 0) { + /* + * Enter tickless regime during long idle durations. + */ + if (ticks > g_hal_os_tick.max_idle_ticks) { + ticks = g_hal_os_tick.max_idle_ticks; + } + ocmp = g_hal_os_tick.lastocmp + (ticks*g_hal_os_tick.ticks_per_ostick); + nrf52_os_tick_set_ocmp(ocmp); + } + + __WFI(); + + if (ticks > 0) { + /* + * Update OS time before anything else when coming out of + * the tickless regime. + */ + nrf52_timer_handler(); + } +} + +extern void nrf_rtc_regw_sideeffects(int i); + +void +os_tick_init(uint32_t os_ticks_per_sec, int prio) +{ + uint32_t sr; + + assert(RTC_FREQ % os_ticks_per_sec == 0); + + g_hal_os_tick.lastocmp = 0; + g_hal_os_tick.ticks_per_ostick = RTC_FREQ / os_ticks_per_sec; + + /* + * The maximum number of OS ticks allowed to elapse during idle is + * limited to 1/4th the number of timer ticks before the 24-bit counter + * rolls over. + */ + g_hal_os_tick.max_idle_ticks = (1UL << 22) / g_hal_os_tick.ticks_per_ostick; + + /* disable interrupts */ + OS_ENTER_CRITICAL(sr); + + /* Set isr in vector table and enable interrupt */ + NVIC_SetPriority(OS_TICK_IRQ, prio); + NVIC_SetVector(OS_TICK_IRQ, (uint32_t)nrf52_timer_handler); + NVIC_EnableIRQ(OS_TICK_IRQ); + + /* + * Program the OS_TICK_TIMER to operate at 32KHz and trigger an output + * compare interrupt at a rate of 'os_ticks_per_sec'. + */ + nrf_rtc_task_trigger(OS_TICK_TIMER, NRF_RTC_TASK_STOP); + nrf_rtc_task_trigger(OS_TICK_TIMER, NRF_RTC_TASK_CLEAR); + nrf_rtc_event_disable(OS_TICK_TIMER, 0xffffffff); + nrf_rtc_int_disable(OS_TICK_TIMER, 0xffffffff); + nrf_rtc_int_enable(OS_TICK_TIMER, RTC_COMPARE_INT_MASK(OS_TICK_CMPREG)); + + OS_TICK_TIMER->EVENTS_COMPARE[OS_TICK_CMPREG] = 0; + nrf_rtc_cc_set(OS_TICK_TIMER, OS_TICK_CMPREG, g_hal_os_tick.ticks_per_ostick); + + nrf_rtc_task_trigger(OS_TICK_TIMER, NRF_RTC_TASK_START); + + OS_EXIT_CRITICAL(sr); +} diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_reset_cause.c b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_reset_cause.c new file mode 100644 index 0000000000..32182c1ecd --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_reset_cause.c @@ -0,0 +1,47 @@ +/* + * 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. + */ + +#include +#include "hal/hal_system.h" + +enum hal_reset_reason +hal_reset_cause(void) +{ + static enum hal_reset_reason reason; + uint32_t reg; + + if (reason) { + return reason; + } + reg = NRF_POWER->RESETREAS; + + if (reg & (POWER_RESETREAS_DOG_Msk | POWER_RESETREAS_LOCKUP_Msk)) { + reason = HAL_RESET_WATCHDOG; + } else if (reg & POWER_RESETREAS_SREQ_Msk) { + reason = HAL_RESET_SOFT; + } else if (reg & POWER_RESETREAS_RESETPIN_Msk) { + reason = HAL_RESET_PIN; + } else if (reg & POWER_RESETREAS_OFF_Msk) { + reason = HAL_RESET_SYS_OFF_INT; + } else { + reason = HAL_RESET_POR; /* could also be brownout */ + } + NRF_POWER->RESETREAS = reg; + return reason; +} diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_system.c b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_system.c new file mode 100644 index 0000000000..4f46f34697 --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_system.c @@ -0,0 +1,128 @@ +/* + * 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. + */ + +#include "syscfg/syscfg.h" +#include "hal/hal_system.h" +#include "hal/hal_debug.h" +#include "nrf.h" +#include "cmsis.h" +#include "mcu/mcu_sim.h" +#include "hal/nrf_clock.h" + +/** + * Function called at startup. Called after BSS and .data initialized but + * prior to the _start function. + * + * NOTE: this function is called by both the bootloader and the application. + * If you add code here that you do not want executed in either case you need + * to conditionally compile it using the config variable BOOT_LOADER (will + * be set to 1 in case of bootloader build) + * + */ +void +hal_system_init(void) +{ +#if MYNEWT_VAL(MCU_DCDC_ENABLED) + NRF_POWER->DCDCEN = 1; +#endif +} + +void +hal_system_reset(void) +{ + +#if MYNEWT_VAL(HAL_SYSTEM_RESET_CB) + hal_system_reset_cb(); +#endif + + while (1) { + HAL_DEBUG_BREAK(); + NVIC_SystemReset(); + } +} + +int +hal_debugger_connected(void) +{ + return 0; +} + +/** + * hal system clock start + * + * Makes sure the LFCLK and/or HFCLK is started. + */ +void +hal_system_clock_start(void) +{ +#if MYNEWT_VAL(MCU_LFCLK_SOURCE) + uint32_t regmsk; + uint32_t regval; + uint32_t clksrc; + + regmsk = CLOCK_LFCLKSTAT_STATE_Msk | CLOCK_LFCLKSTAT_SRC_Msk; + regval = CLOCK_LFCLKSTAT_STATE_Running << CLOCK_LFCLKSTAT_STATE_Pos; + +#if MYNEWT_VAL_CHOICE(MCU_LFCLK_SOURCE, LFXO) + regval |= CLOCK_LFCLKSTAT_SRC_Xtal << CLOCK_LFCLKSTAT_SRC_Pos; + clksrc = CLOCK_LFCLKSRC_SRC_Xtal; +#elif MYNEWT_VAL_CHOICE(MCU_LFCLK_SOURCE, LFSYNTH) + regval |= CLOCK_LFCLKSTAT_SRC_Synth << CLOCK_LFCLKSTAT_SRC_Pos; + clksrc = CLOCK_LFCLKSRC_SRC_Synth; +#elif MYNEWT_VAL_CHOICE(MCU_LFCLK_SOURCE, LFRC) + regval |= CLOCK_LFCLKSTAT_SRC_RC << CLOCK_LFCLKSTAT_SRC_Pos; + clksrc = CLOCK_LFCLKSRC_SRC_RC; +#else + #error Unknown LFCLK source selected +#endif + +#if MYNEWT_VAL_CHOICE(MCU_LFCLK_SOURCE, LFSYNTH) + /* Must turn on HFLCK for synthesized 32768 crystal */ + nrf52_clock_hfxo_request(); +#else + /* Make sure HFCLK is stopped */ + nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); +#endif + + /* Check if this clock source is already running */ + if ((NRF_CLOCK_regs.LFCLKSTAT & regmsk) != regval) { + + nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTOP); + NRF_CLOCK_regs.EVENTS_LFCLKSTARTED = 0; + NRF_CLOCK_regs.LFCLKSRC = clksrc; + nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTART); + + /* Wait here till started! */ +// while (1) { +// if (NRF_CLOCK_regs.EVENTS_LFCLKSTARTED) { +// if ((NRF_CLOCK_regs.LFCLKSTAT & regmsk) == regval) { +// break; +// } +// } +// } + } +#endif +} + + +void* +NRF_RADIO_BASE_FUN(void) +{ + return NULL; +} diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_timer.c b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_timer.c new file mode 100644 index 0000000000..0e3d914c98 --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_timer.c @@ -0,0 +1,949 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include "os/mynewt.h" +#include "mcu/cmsis_nvic.h" +#include "hal/hal_timer.h" +#include "nrf.h" +#include "mcu/nrf52_hal.h" +#include "mcu/nrf52_clock.h" +#include "hal/nrf_timer.h" + +/* IRQ prototype */ +typedef void (*hal_timer_irq_handler_t)(void); + +/* User CC 2 for reading counter, CC 3 for timer isr */ +#define NRF_TIMER_CC_READ (NRF_TIMER_CC_CHANNEL2) +#define NRF_TIMER_CC_INT (3) + +/* Output compare 2 used for RTC timers */ +#define NRF_RTC_TIMER_CC_INT (2) + +/* Maximum number of hal timers used */ +#define NRF52_HAL_TIMER_MAX (6) + +/* Maximum timer frequency */ +#define NRF52_MAX_TIMER_FREQ (16000000) + +struct nrf52_hal_timer { + uint8_t tmr_enabled; + uint8_t tmr_irq_num; + uint8_t tmr_rtc; + uint8_t tmr_pad; + uint32_t tmr_cntr; + uint32_t timer_isrs; + uint32_t tmr_freq; + void *tmr_reg; + TAILQ_HEAD(hal_timer_qhead, hal_timer) hal_timer_q; +}; + +#if MYNEWT_VAL(TIMER_0) +struct nrf52_hal_timer nrf52_hal_timer0; +#endif +#if MYNEWT_VAL(TIMER_1) +struct nrf52_hal_timer nrf52_hal_timer1; +#endif +#if MYNEWT_VAL(TIMER_2) +struct nrf52_hal_timer nrf52_hal_timer2; +#endif +#if MYNEWT_VAL(TIMER_3) +struct nrf52_hal_timer nrf52_hal_timer3; +#endif +#if MYNEWT_VAL(TIMER_4) +struct nrf52_hal_timer nrf52_hal_timer4; +#endif +#if MYNEWT_VAL(TIMER_5) +struct nrf52_hal_timer nrf52_hal_timer5; +#endif + +static const struct nrf52_hal_timer *nrf52_hal_timers[NRF52_HAL_TIMER_MAX] = { +#if MYNEWT_VAL(TIMER_0) + &nrf52_hal_timer0, +#else + NULL, +#endif +#if MYNEWT_VAL(TIMER_1) + &nrf52_hal_timer1, +#else + NULL, +#endif +#if MYNEWT_VAL(TIMER_2) + &nrf52_hal_timer2, +#else + NULL, +#endif +#if MYNEWT_VAL(TIMER_3) + &nrf52_hal_timer3, +#else + NULL, +#endif +#if MYNEWT_VAL(TIMER_4) + &nrf52_hal_timer4, +#else + NULL, +#endif +#if MYNEWT_VAL(TIMER_5) + &nrf52_hal_timer5 +#else + NULL +#endif +}; + +/* Resolve timer number into timer structure */ +#define NRF52_HAL_TIMER_RESOLVE(__n, __v) \ + if ((__n) >= NRF52_HAL_TIMER_MAX) { \ + rc = EINVAL; \ + goto err; \ + } \ + (__v) = (struct nrf52_hal_timer *) nrf52_hal_timers[(__n)]; \ + if ((__v) == NULL) { \ + rc = EINVAL; \ + goto err; \ + } + +/* Interrupt mask for interrupt enable/clear */ +#define NRF_TIMER_INT_MASK(x) ((1 << (uint32_t)(x)) << 16) + +static uint32_t +nrf_read_timer_cntr(NRF_TIMER_Type *hwtimer) +{ + uint32_t tcntr; + + /* Force a capture of the timer into 'cntr' capture channel; read it */ + nrf_timer_task_trigger(hwtimer, NRF_TIMER_TASK_CAPTURE2); + tcntr = hwtimer->CC[NRF_TIMER_CC_READ]; + + return tcntr; +} + +/** + * nrf timer set ocmp + * + * Set the OCMP used by the timer to the desired expiration tick + * + * NOTE: Must be called with interrupts disabled. + * + * @param timer Pointer to timer. + */ +static void +nrf_timer_set_ocmp(struct nrf52_hal_timer *bsptimer, uint32_t expiry) +{ + int32_t delta_t; + uint32_t temp; + uint32_t cntr; + NRF_TIMER_Type *hwtimer; + NRF_RTC_Type *rtctimer; + + if (bsptimer->tmr_rtc) { + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + nrf_rtc_int_disable(rtctimer, NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT)); + temp = bsptimer->tmr_cntr; + cntr = nrf_rtc_counter_get(rtctimer); + if (rtctimer->EVENTS_OVRFLW) { + temp += (1UL << 24); + cntr = nrf_rtc_counter_get(rtctimer); + } + temp |= cntr; + delta_t = (int32_t)(expiry - temp); + + /* + * The nRF52xxx documentation states that COMPARE event is guaranteed + * only if value written to CC register is at least 2 greater than the + * current counter value. We also need to account for possible extra + * tick during calculations so effectively any delta less than 3 needs + * to be handled differently. TICK event is used to have interrupt on + * each subsequent tick so we won't miss any and in case we detected + * mentioned extra tick during calculations, interrupt is triggered + * immediately. Delta 0 or less means we should always fire immediately. + */ + if (delta_t < 1) { + nrf_rtc_int_disable(rtctimer, RTC_INTENCLR_TICK_Msk); + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } else if (delta_t < 3 && 0) { + nrf_rtc_int_enable(rtctimer, RTC_INTENSET_TICK_Msk); + if (nrf_rtc_counter_get(rtctimer) != cntr) { + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } + } else { + nrf_rtc_int_disable(rtctimer, RTC_INTENCLR_TICK_Msk); + + if (delta_t < (1UL << 24)) { + nrf_rtc_cc_set(rtctimer, NRF_RTC_TIMER_CC_INT, expiry & 0x00ffffff); + } else { + /* CC too far ahead. Just make sure we set compare far ahead */ + nrf_rtc_cc_set(rtctimer, NRF_RTC_TIMER_CC_INT, cntr + (1UL << 23)); + } + nrf_rtc_int_enable(rtctimer, NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT)); + } + } else { + hwtimer = bsptimer->tmr_reg; + + /* Disable ocmp interrupt and set new value */ + nrf_timer_int_disable(hwtimer, NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT)); + + /* Set output compare register to timer expiration */ + nrf_timer_cc_set(hwtimer, NRF_TIMER_CC_INT, expiry); + + /* Clear interrupt flag */ + hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT] = 0; + + /* Enable the output compare interrupt */ + nrf_timer_int_enable(hwtimer, NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT)); + + /* Force interrupt to occur as we may have missed it */ + if ((int32_t)(nrf_read_timer_cntr(hwtimer) - expiry) >= 0) { + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } + } +} + +/* Disable output compare used for timer */ +static void +nrf_timer_disable_ocmp(NRF_TIMER_Type *hwtimer) +{ + nrf_timer_int_disable(hwtimer, NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT)); +} + +static void +nrf_rtc_disable_ocmp(NRF_RTC_Type *rtctimer) +{ + nrf_rtc_int_disable(rtctimer, NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT)); + nrf_rtc_int_disable(rtctimer, RTC_INTENCLR_TICK_Msk); +} + +static uint32_t +hal_timer_read_bsptimer(struct nrf52_hal_timer *bsptimer) +{ + uint32_t low32; + uint32_t ctx; + uint32_t tcntr; + NRF_RTC_Type *rtctimer; + + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + __HAL_DISABLE_INTERRUPTS(ctx); + tcntr = bsptimer->tmr_cntr; + low32 = nrf_rtc_counter_get(rtctimer); + if (rtctimer->EVENTS_OVRFLW) { + tcntr += (1UL << 24); + bsptimer->tmr_cntr = tcntr; + low32 = nrf_rtc_counter_get(rtctimer); + rtctimer->EVENTS_OVRFLW = 0; + NVIC_SetPendingIRQ(bsptimer->tmr_irq_num); + } + tcntr |= low32; + __HAL_ENABLE_INTERRUPTS(ctx); + + return tcntr; +} + +#if (MYNEWT_VAL(TIMER_0) || MYNEWT_VAL(TIMER_1) || MYNEWT_VAL(TIMER_2) || \ + MYNEWT_VAL(TIMER_3) || MYNEWT_VAL(TIMER_4) || MYNEWT_VAL(TIMER_5)) +/** + * hal timer chk queue + * + * + * @param bsptimer + */ +static void +hal_timer_chk_queue(struct nrf52_hal_timer *bsptimer) +{ + uint32_t tcntr; + uint32_t ctx; + struct hal_timer *timer; + + /* disable interrupts */ + __HAL_DISABLE_INTERRUPTS(ctx); + while ((timer = TAILQ_FIRST(&bsptimer->hal_timer_q)) != NULL) { + if (bsptimer->tmr_rtc) { + tcntr = hal_timer_read_bsptimer(bsptimer); + } else { + tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg); + } + if ((int32_t)(tcntr - timer->expiry) >= 0) { + TAILQ_REMOVE(&bsptimer->hal_timer_q, timer, link); + timer->link.tqe_prev = NULL; + timer->cb_func(timer->cb_arg); + } else { + break; + } + } + + /* Any timers left on queue? If so, we need to set OCMP */ + timer = TAILQ_FIRST(&bsptimer->hal_timer_q); + if (timer) { + nrf_timer_set_ocmp(bsptimer, timer->expiry); + } else { + if (bsptimer->tmr_rtc) { + nrf_rtc_disable_ocmp((NRF_RTC_Type *)bsptimer->tmr_reg); + } else { + nrf_timer_disable_ocmp(bsptimer->tmr_reg); + } + } + __HAL_ENABLE_INTERRUPTS(ctx); +} +#endif + +/** + * hal timer irq handler + * + * Generic HAL timer irq handler. + * + * @param tmr + */ +/** + * hal timer irq handler + * + * This is the global timer interrupt routine. + * + */ +#if (MYNEWT_VAL(TIMER_0) || MYNEWT_VAL(TIMER_1) || MYNEWT_VAL(TIMER_2) || \ + MYNEWT_VAL(TIMER_3) || MYNEWT_VAL(TIMER_4)) + +static void +hal_timer_irq_handler(struct nrf52_hal_timer *bsptimer) +{ + uint32_t compare; + NRF_TIMER_Type *hwtimer; + + os_trace_isr_enter(); + + /* Check interrupt source. If set, clear them */ + hwtimer = bsptimer->tmr_reg; + compare = hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT]; + if (compare) { + hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT] = 0; + } + + /* XXX: make these stats? */ + /* Count # of timer isrs */ + ++bsptimer->timer_isrs; + + /* + * NOTE: we dont check the 'compare' variable here due to how the timer + * is implemented on this chip. There is no way to force an output + * compare, so if we are late setting the output compare (i.e. the timer + * counter is already passed the output compare value), we use the NVIC + * to set a pending interrupt. This means that there will be no compare + * flag set, so all we do is check to see if the compare interrupt is + * enabled. + */ + if (hwtimer->INTENCLR & NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT)) { + hal_timer_chk_queue(bsptimer); + /* XXX: Recommended by nordic to make sure interrupts are cleared */ + compare = hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT]; + } + + os_trace_isr_exit(); +} +#endif + +#if MYNEWT_VAL(TIMER_5) +static void +hal_rtc_timer_irq_handler(struct nrf52_hal_timer *bsptimer) +{ + uint32_t overflow; + uint32_t compare; + uint32_t tick; + NRF_RTC_Type *rtctimer; + + os_trace_isr_enter(); + + /* Check interrupt source. If set, clear them */ + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + compare = rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT]; + if (compare) { + rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT] = 0; + } + + tick = rtctimer->EVENTS_TICK; + if (tick) { + rtctimer->EVENTS_TICK = 0; + } + + overflow = rtctimer->EVENTS_OVRFLW; + if (overflow) { + rtctimer->EVENTS_OVRFLW = 0; + bsptimer->tmr_cntr += (1UL << 24); + } + + /* Count # of timer isrs */ + ++bsptimer->timer_isrs; + + /* + * NOTE: we dont check the 'compare' variable here due to how the timer + * is implemented on this chip. There is no way to force an output + * compare, so if we are late setting the output compare (i.e. the timer + * counter is already passed the output compare value), we use the NVIC + * to set a pending interrupt. This means that there will be no compare + * flag set, so all we do is check to see if the compare interrupt is + * enabled. + */ + hal_timer_chk_queue(bsptimer); + + /* Recommended by nordic to make sure interrupts are cleared */ + compare = rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT]; + + os_trace_isr_exit(); +} +#endif + +#if MYNEWT_VAL(TIMER_0) +void +nrf52_timer0_irq_handler(void) +{ + hal_timer_irq_handler(&nrf52_hal_timer0); +} +#endif + +#if MYNEWT_VAL(TIMER_1) +void +nrf52_timer1_irq_handler(void) +{ + hal_timer_irq_handler(&nrf52_hal_timer1); +} +#endif + +#if MYNEWT_VAL(TIMER_2) +void +nrf52_timer2_irq_handler(void) +{ + hal_timer_irq_handler(&nrf52_hal_timer2); +} +#endif + +#if MYNEWT_VAL(TIMER_3) +void +nrf52_timer3_irq_handler(void) +{ + hal_timer_irq_handler(&nrf52_hal_timer3); +} +#endif + +#if MYNEWT_VAL(TIMER_4) +void +nrf52_timer4_irq_handler(void) +{ + hal_timer_irq_handler(&nrf52_hal_timer4); +} +#endif + +#if MYNEWT_VAL(TIMER_5) +void +nrf52_timer5_irq_handler(void) +{ + hal_rtc_timer_irq_handler(&nrf52_hal_timer5); +} +#endif + +/** + * hal timer init + * + * Initialize platform specific timer items + * + * @param timer_num Timer number to initialize + * @param cfg Pointer to platform specific configuration + * + * @return int 0: success; error code otherwise + */ +int +hal_timer_init(int timer_num, void *cfg) +{ + int rc; + uint8_t irq_num; + struct nrf52_hal_timer *bsptimer; + void *hwtimer; + hal_timer_irq_handler_t irq_isr; + + NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer); + + /* If timer is enabled do not allow init */ + if (bsptimer->tmr_enabled) { + rc = EINVAL; + goto err; + } + + switch (timer_num) { +#if MYNEWT_VAL(TIMER_0) + case 0: + irq_num = TIMER0_IRQn; + hwtimer = NRF_TIMER0; + irq_isr = nrf52_timer0_irq_handler; + break; +#endif +#if MYNEWT_VAL(TIMER_1) + case 1: + irq_num = TIMER1_IRQn; + hwtimer = NRF_TIMER1; + irq_isr = nrf52_timer1_irq_handler; + break; +#endif +#if MYNEWT_VAL(TIMER_2) + case 2: + irq_num = TIMER2_IRQn; + hwtimer = NRF_TIMER2; + irq_isr = nrf52_timer2_irq_handler; + break; +#endif +#if MYNEWT_VAL(TIMER_3) + case 3: + irq_num = TIMER3_IRQn; + hwtimer = NRF_TIMER3; + irq_isr = nrf52_timer3_irq_handler; + break; +#endif +#if MYNEWT_VAL(TIMER_4) + case 4: + irq_num = TIMER4_IRQn; + hwtimer = NRF_TIMER4; + irq_isr = nrf52_timer4_irq_handler; + break; +#endif +#if MYNEWT_VAL(TIMER_5) + case 5: + irq_num = RTC0_IRQn; + hwtimer = NRF_RTC0; + irq_isr = nrf52_timer5_irq_handler; + bsptimer->tmr_rtc = 1; + break; +#endif + default: + hwtimer = NULL; + break; + } + + if (hwtimer == NULL) { + rc = EINVAL; + goto err; + } + + bsptimer->tmr_reg = hwtimer; + bsptimer->tmr_irq_num = irq_num; + + /* Disable IRQ, set priority and set vector in table */ + NVIC_DisableIRQ(irq_num); + NVIC_SetPriority(irq_num, (1 << __NVIC_PRIO_BITS) - 1); + NVIC_SetVector(irq_num, (uint32_t)irq_isr); + + return 0; + +err: + return rc; +} + +/** + * hal timer config + * + * Configure a timer to run at the desired frequency. This starts the timer. + * + * @param timer_num + * @param freq_hz + * + * @return int + */ +int +hal_timer_config(int timer_num, uint32_t freq_hz) +{ + int rc; + uint8_t prescaler; + uint32_t ctx; + uint32_t div; + uint32_t min_delta; + uint32_t max_delta; + struct nrf52_hal_timer *bsptimer; + NRF_TIMER_Type *hwtimer; +#if MYNEWT_VAL(TIMER_5) + NRF_RTC_Type *rtctimer; +#endif + + NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer); + +#if MYNEWT_VAL(TIMER_5) + if (timer_num == 5) { + /* NOTE: we only allow the RTC frequency to be set at 32768 */ + if (bsptimer->tmr_enabled || (freq_hz != 32768) || + (bsptimer->tmr_reg == NULL)) { + rc = EINVAL; + goto err; + } + + bsptimer->tmr_freq = freq_hz; + bsptimer->tmr_enabled = 1; + + __HAL_DISABLE_INTERRUPTS(ctx); + + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + + /* Stop the timer first */ + nrf_rtc_task_trigger(rtctimer, NRF_RTC_TASK_STOP); + nrf_rtc_task_trigger(rtctimer, NRF_RTC_TASK_CLEAR); + + /* Always no prescaler */ + rtctimer->PRESCALER = 0; + + /* Clear overflow events and set overflow interrupt */ + rtctimer->EVENTS_OVRFLW = 0; + nrf_rtc_int_enable(rtctimer, RTC_INTENSET_OVRFLW_Msk); + + /* Start the timer */ + nrf_rtc_task_trigger(rtctimer, NRF_RTC_TASK_START); + /* Set isr in vector table and enable interrupt */ + NVIC_EnableIRQ(bsptimer->tmr_irq_num); + + __HAL_ENABLE_INTERRUPTS(ctx); + return 0; + } +#endif + + /* Set timer to desired frequency */ + div = NRF52_MAX_TIMER_FREQ / freq_hz; + + /* + * Largest prescaler is 2^9 and must make sure frequency not too high. + * If hwtimer is NULL it means that the timer was not initialized prior + * to call. + */ + if (bsptimer->tmr_enabled || (div == 0) || (div > 512) || + (bsptimer->tmr_reg == NULL)) { + rc = EINVAL; + goto err; + } + + if (div == 1) { + prescaler = 0; + } else { + /* Find closest prescaler */ + for (prescaler = 1; prescaler < 10; ++prescaler) { + if (div <= (1 << prescaler)) { + min_delta = div - (1 << (prescaler - 1)); + max_delta = (1 << prescaler) - div; + if (min_delta < max_delta) { + prescaler -= 1; + } + break; + } + } + } + + /* Now set the actual frequency */ + bsptimer->tmr_freq = NRF52_MAX_TIMER_FREQ / (1 << prescaler); + bsptimer->tmr_enabled = 1; + + /* disable interrupts */ + __HAL_DISABLE_INTERRUPTS(ctx); + +#if MYNEWT_VAL_CHOICE(MCU_HFCLK_SOURCE, HFXO) + /* Make sure HFXO is started */ + nrf52_clock_hfxo_request(); +#endif + hwtimer = bsptimer->tmr_reg; + + /* Stop the timer first */ + nrf_timer_task_trigger(hwtimer, NRF_TIMER_TASK_STOP); + nrf_timer_task_trigger(hwtimer, NRF_TIMER_TASK_CLEAR); + + /* Put the timer in timer mode using 32 bits. */ + nrf_timer_mode_set(hwtimer, NRF_TIMER_MODE_TIMER); + hwtimer->BITMODE = TIMER_BITMODE_BITMODE_32Bit; + + /* Set the pre-scalar */ + hwtimer->PRESCALER = prescaler; + + /* Start the timer */ + nrf_timer_task_trigger(hwtimer, NRF_TIMER_TASK_START); + + NVIC_EnableIRQ(bsptimer->tmr_irq_num); + + __HAL_ENABLE_INTERRUPTS(ctx); + + return 0; + +err: + return rc; +} + +/** + * hal timer deinit + * + * De-initialize a HW timer. + * + * @param timer_num + * + * @return int + */ +int +hal_timer_deinit(int timer_num) +{ + int rc; + uint32_t ctx; + struct nrf52_hal_timer *bsptimer; + NRF_TIMER_Type *hwtimer; + NRF_RTC_Type *rtctimer; + + rc = 0; + NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer); + + __HAL_DISABLE_INTERRUPTS(ctx); + if (bsptimer->tmr_rtc) { + rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg; + nrf_rtc_int_disable(rtctimer, NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT)); + nrf_rtc_task_trigger(rtctimer, NRF_RTC_TASK_STOP); + } else { + hwtimer = (NRF_TIMER_Type *)bsptimer->tmr_reg; + nrf_timer_int_disable(hwtimer, NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT)); + hwtimer->TASKS_SHUTDOWN = 1; + } + bsptimer->tmr_enabled = 0; + bsptimer->tmr_reg = NULL; + +#if MYNEWT_VAL_CHOICE(MCU_HFCLK_SOURCE, HFXO) + if (timer_num != 5) { + nrf52_clock_hfxo_release(); + } +#endif + __HAL_ENABLE_INTERRUPTS(ctx); + +err: + return rc; +} + +/** + * hal timer get resolution + * + * Get the resolution of the timer. This is the timer period, in nanoseconds + * + * @param timer_num + * + * @return uint32_t The + */ +uint32_t +hal_timer_get_resolution(int timer_num) +{ + int rc; + uint32_t resolution; + struct nrf52_hal_timer *bsptimer; + + NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer); + + resolution = 1000000000 / bsptimer->tmr_freq; + return resolution; + +err: + rc = 0; + return rc; +} + +/** + * hal timer read + * + * Returns the timer counter. NOTE: if the timer is a 16-bit timer, only + * the lower 16 bits are valid. If the timer is a 64-bit timer, only the + * low 32-bits are returned. + * + * @return uint32_t The timer counter register. + */ +uint32_t +hal_timer_read(int timer_num) +{ + int rc; + uint32_t tcntr; + struct nrf52_hal_timer *bsptimer; + + NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer); + if (bsptimer->tmr_rtc) { + tcntr = hal_timer_read_bsptimer(bsptimer); + } else { + tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg); + } + + return tcntr; + + /* Assert here since there is no invalid return code */ +err: + assert(0); + rc = 0; + return rc; +} + +/** + * hal timer delay + * + * Blocking delay for n ticks + * + * @param timer_num + * @param ticks + * + * @return int 0 on success; error code otherwise. + */ +int +hal_timer_delay(int timer_num, uint32_t ticks) +{ + uint32_t until; + + until = hal_timer_read(timer_num) + ticks; + while ((int32_t)(hal_timer_read(timer_num) - until) <= 0) { + /* Loop here till finished */ + } + + return 0; +} + +/** + * + * Initialize the HAL timer structure with the callback and the callback + * argument. Also initializes the HW specific timer pointer. + * + * @param cb_func + * + * @return int + */ +int +hal_timer_set_cb(int timer_num, struct hal_timer *timer, hal_timer_cb cb_func, + void *arg) +{ + int rc; + struct nrf52_hal_timer *bsptimer; + + NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer); + + timer->cb_func = cb_func; + timer->cb_arg = arg; + timer->link.tqe_prev = NULL; + timer->bsp_timer = bsptimer; + + rc = 0; + +err: + return rc; +} + +int +hal_timer_start(struct hal_timer *timer, uint32_t ticks) +{ + int rc; + uint32_t tick; + struct nrf52_hal_timer *bsptimer; + + /* Set the tick value at which the timer should expire */ + bsptimer = (struct nrf52_hal_timer *)timer->bsp_timer; + if (bsptimer->tmr_rtc) { + tick = hal_timer_read_bsptimer(bsptimer) + ticks; + } else { + tick = nrf_read_timer_cntr(bsptimer->tmr_reg) + ticks; + } + rc = hal_timer_start_at(timer, tick); + return rc; +} + +int +hal_timer_start_at(struct hal_timer *timer, uint32_t tick) +{ + uint32_t ctx; + struct hal_timer *entry; + struct nrf52_hal_timer *bsptimer; + + if ((timer == NULL) || (timer->link.tqe_prev != NULL) || + (timer->cb_func == NULL)) { + return EINVAL; + } + bsptimer = (struct nrf52_hal_timer *)timer->bsp_timer; + timer->expiry = tick; + + __HAL_DISABLE_INTERRUPTS(ctx); + + if (TAILQ_EMPTY(&bsptimer->hal_timer_q)) { + TAILQ_INSERT_HEAD(&bsptimer->hal_timer_q, timer, link); + } else { + TAILQ_FOREACH(entry, &bsptimer->hal_timer_q, link) { + if ((int32_t)(timer->expiry - entry->expiry) < 0) { + TAILQ_INSERT_BEFORE(entry, timer, link); + break; + } + } + if (!entry) { + TAILQ_INSERT_TAIL(&bsptimer->hal_timer_q, timer, link); + } + } + + /* If this is the head, we need to set new OCMP */ + if (timer == TAILQ_FIRST(&bsptimer->hal_timer_q)) { + nrf_timer_set_ocmp(bsptimer, timer->expiry); + } + + __HAL_ENABLE_INTERRUPTS(ctx); + + return 0; +} + +/** + * hal timer stop + * + * Stop a timer. + * + * @param timer + * + * @return int + */ +int +hal_timer_stop(struct hal_timer *timer) +{ + uint32_t ctx; + int reset_ocmp; + struct hal_timer *entry; + struct nrf52_hal_timer *bsptimer; + + if (timer == NULL) { + return EINVAL; + } + + bsptimer = (struct nrf52_hal_timer *)timer->bsp_timer; + + __HAL_DISABLE_INTERRUPTS(ctx); + + if (timer->link.tqe_prev != NULL) { + reset_ocmp = 0; + if (timer == TAILQ_FIRST(&bsptimer->hal_timer_q)) { + /* If first on queue, we will need to reset OCMP */ + entry = TAILQ_NEXT(timer, link); + reset_ocmp = 1; + } + TAILQ_REMOVE(&bsptimer->hal_timer_q, timer, link); + timer->link.tqe_prev = NULL; + if (reset_ocmp) { + if (entry) { + nrf_timer_set_ocmp((struct nrf52_hal_timer *)entry->bsp_timer, + entry->expiry); + } else { + if (bsptimer->tmr_rtc) { + nrf_rtc_disable_ocmp((NRF_RTC_Type *)bsptimer->tmr_reg); + } else { + nrf_timer_disable_ocmp(bsptimer->tmr_reg); + } + } + } + } + + __HAL_ENABLE_INTERRUPTS(ctx); + + return 0; +} diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_uart.c b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_uart.c new file mode 100644 index 0000000000..41ac9b1db4 --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_uart.c @@ -0,0 +1,478 @@ +/* + * 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. + */ + +#include "os/mynewt.h" +#include "hal/hal_uart.h" +#include "bsp/bsp.h" + +#ifdef MN_LINUX +#include +#endif +#ifdef MN_OSX +#include +#endif +#ifdef MN_FreeBSD +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mcu/mcu_sim.h" +#include "native_uart_cfg_priv.h" +#include "syscfg/syscfg.h" + +#define UART_CNT 2 + +#if MYNEWT_VAL(CONSOLE_UART_TX_BUF_SIZE) +#define UART_MAX_BYTES_PER_POLL MYNEWT_VAL(CONSOLE_UART_TX_BUF_SIZE) - 2 +#else +#define UART_MAX_BYTES_PER_POLL 64 +#endif +#define UART_POLLER_STACK_SZ OS_STACK_ALIGN(1024) + +struct uart { + int u_open; + int u_fd; + int u_tx_run; + int u_rx_char; + hal_uart_rx_char u_rx_func; + hal_uart_tx_char u_tx_func; + hal_uart_tx_done u_tx_done; + void *u_func_arg; +}; + +const char *native_uart_dev_strs[UART_CNT]; + +/* + * XXXX should try to use O_ASYNC/SIGIO for byte arrival notification, + * so we wouldn't need an OS for pseudo ttys. + */ +char *native_uart_log_file = NULL; +static int uart_log_fd = -1; + +static struct uart uarts[UART_CNT]; +static int uart_poller_running; +static struct os_task uart_poller_task; +static os_stack_t uart_poller_stack[UART_POLLER_STACK_SZ]; + +static void +uart_open_log(void) +{ + if (native_uart_log_file && uart_log_fd < 0) { + uart_log_fd = open(native_uart_log_file, O_WRONLY | O_CREAT | O_TRUNC, + 0666); + assert(uart_log_fd >= 0); + } +} + +static void +uart_log_data(struct uart *u, int istx, uint8_t data) +{ + static struct { + struct uart *uart; + int istx; + uint32_t time; + int chars_in_line; + } state = { + .uart = NULL, + .istx = 0 + }; + uint32_t now; + char tmpbuf[32]; + int len; + + if (uart_log_fd < 0) { + return; + } + now = os_time_get(); + if (state.uart) { + if (u != state.uart || now != state.time || istx != state.istx) { + /* + * End current printout. + */ + if (write(uart_log_fd, "\n", 1) != 1) { + assert(0); + } + state.uart = NULL; + } else { + if (state.chars_in_line == 8) { + if (write(uart_log_fd, "\n\t", 2) != 2) { + assert(0); + } + state.chars_in_line = 0; + } + len = snprintf(tmpbuf, sizeof(tmpbuf), "%c (%02x) ", + isalnum(data) ? data : '?', data); + if (write(uart_log_fd, tmpbuf, len) != len) { + assert(0); + } + state.chars_in_line++; + } + } + if (u && state.uart == NULL) { + len = snprintf(tmpbuf, sizeof(tmpbuf), "%u:uart%d %s\n\t%c (%02x) ", + now, u - uarts, istx ? "tx" : "rx", isalnum(data) ? data : '?', data); + if (write(uart_log_fd, tmpbuf, len) != len) { + assert(0); + } + state.chars_in_line = 1; + state.uart = u; + state.istx = istx; + state.time = now; + } +} + +static int +uart_transmit_char(struct uart *uart) +{ + int sr; + int rc; + char ch; + + OS_ENTER_CRITICAL(sr); + rc = uart->u_tx_func(uart->u_func_arg); + if (rc < 0) { + /* + * No more data to send. + */ + uart->u_tx_run = 0; + if (uart->u_tx_done) { + uart->u_tx_done(uart->u_func_arg); + } + OS_EXIT_CRITICAL(sr); + return 0; + } + ch = rc; + uart_log_data(uart, 1, ch); + OS_EXIT_CRITICAL(sr); + rc = write(uart->u_fd, &ch, 1); + if (rc <= 0) { + /* XXX EOF/error, what now? */ + return -1; + } + return 0; +} + +static void +uart_poller(void *arg) +{ + int i; + int rc; + int bytes; + int sr; + int didwork; + unsigned char ch; + struct uart *uart; + + while (1) { + for (i = 0; i < UART_CNT; i++) { + if (!uarts[i].u_open) { + continue; + } + uart = &uarts[i]; + + for (bytes = 0; bytes < UART_MAX_BYTES_PER_POLL; bytes++) { + didwork = 0; + if (uart->u_tx_run) { + uart_transmit_char(uart); + didwork = 1; + } + if (uart->u_rx_char < 0) { + rc = read(uart->u_fd, &ch, 1); + if (rc == 0) { + /* XXX EOF, what now? */ + assert(0); + } else if (rc > 0) { + uart->u_rx_char = ch; + } + } + if (uart->u_rx_char >= 0) { + OS_ENTER_CRITICAL(sr); + uart_log_data(uart, 0, uart->u_rx_char); + rc = uart->u_rx_func(uart->u_func_arg, uart->u_rx_char); + /* Delivered */ + if (rc >= 0) { + uart->u_rx_char = -1; + didwork = 1; + } + OS_EXIT_CRITICAL(sr); + } + if (!didwork) { + break; + } + } + } + uart_log_data(NULL, 0, 0); + os_time_delay(OS_TICKS_PER_SEC / 100); + } +} + +static void +set_nonblock(int fd) +{ + int flags; + + flags = fcntl(fd, F_GETFL); + if (flags == -1) { + const char msg[] = "fcntl(F_GETFL) fail"; + write(1, msg, sizeof(msg)); + return; + } + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { + const char msg[] = "fcntl(F_SETFL) fail"; + write(1, msg, sizeof(msg)); + return; + } +} + +static int +uart_pty_set_attr(int fd) +{ + struct termios tios; + + if (tcgetattr(fd, &tios)) { + const char msg[] = "tcgetattr() failed"; + write(1, msg, sizeof(msg)); + return -1; + } + + tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); + tios.c_cflag |= CS8 | CREAD; + tios.c_iflag = IGNPAR; + tios.c_oflag = 0; + tios.c_lflag = 0; + if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { + const char msg[] = "tcsetattr() failed"; + write(1, msg, sizeof(msg)); + return -1; + } + return 0; +} + +static int +uart_pty(int port) +{ + int fd; + int loop_slave; + char pty_name[32]; + char msg[64]; + + if (openpty(&fd, &loop_slave, pty_name, NULL, NULL) < 0) { + const char msg[] = "openpty() failed"; + write(1, msg, sizeof(msg)); + return -1; + } + + if (uart_pty_set_attr(loop_slave)) { + goto err; + } + + snprintf(msg, sizeof(msg), "uart%d at %s\n", port, pty_name); + write(1, msg, strlen(msg)); + return fd; + err: + close(fd); + close(loop_slave); + return -1; +} + +/** + * Opens an external device terminal (/dev/cu.<...>). + */ +static int +uart_open_dev(int port, int32_t baudrate, uint8_t databits, + uint8_t stopbits, enum hal_uart_parity parity, + enum hal_uart_flow_ctl flow_ctl) +{ + const char *filename; + int fd; + int rc; + + filename = native_uart_dev_strs[port]; + assert(filename != NULL); + + fd = open(filename, O_RDWR); + if (fd < 0) { + return -1; + } + + rc = uart_dev_set_attr(fd, baudrate, databits, + stopbits, parity, flow_ctl); + if (rc != 0) { + close(fd); + return rc; + } + + dprintf(1, "uart%d at %s\n", port, filename); + + return fd; +} + +void +hal_uart_start_tx(int port) +{ + int sr; + + if (port >= UART_CNT || uarts[port].u_open == 0) { + return; + } + OS_ENTER_CRITICAL(sr); + uarts[port].u_tx_run = 1; + if (!os_started()) { + /* + * XXX this is a hack. + */ + uart_transmit_char(&uarts[port]); + } + OS_EXIT_CRITICAL(sr); +} + +void +hal_uart_start_rx(int port) +{ + /* nothing to do here */ +} + +void +hal_uart_blocking_tx(int port, uint8_t data) +{ + if (port >= UART_CNT || uarts[port].u_open == 0) { + return; + } + + /* XXX: Count statistics and add error checking here. */ + (void) write(uarts[port].u_fd, &data, sizeof(data)); +} + +int +hal_uart_init_cbs(int port, hal_uart_tx_char tx_func, hal_uart_tx_done tx_done, + hal_uart_rx_char rx_func, void *arg) +{ + struct uart *uart; + int rc; + + if (port >= UART_CNT) { + return -1; + } + + uart = &uarts[port]; + if (uart->u_open) { + return -1; + } + uart->u_tx_func = tx_func; + uart->u_tx_done = tx_done; + uart->u_rx_func = rx_func; + uart->u_func_arg = arg; + uart->u_rx_char = -1; + + if (!uart_poller_running) { + uart_poller_running = 1; + rc = os_task_init(&uart_poller_task, "uartpoll", uart_poller, NULL, + MYNEWT_VAL(MCU_UART_POLLER_PRIO), OS_WAIT_FOREVER, uart_poller_stack, + UART_POLLER_STACK_SZ); + assert(rc == 0); + } + return 0; +} + +int +hal_uart_config(int port, int32_t baudrate, uint8_t databits, uint8_t stopbits, + enum hal_uart_parity parity, enum hal_uart_flow_ctl flow_ctl) +{ + struct uart *uart; + + if (port >= UART_CNT) { + return -1; + } + + uart = &uarts[port]; + if (uart->u_open) { + return -1; + } + + if (native_uart_dev_strs[port] == NULL) { + uart->u_fd = uart_pty(port); + } else { + uart->u_fd = uart_open_dev(port, baudrate, databits, stopbits, + parity, flow_ctl); + } + + if (uart->u_fd < 0) { + return -1; + } + set_nonblock(uart->u_fd); + + + uart_open_log(); + uart->u_open = 1; + return 0; +} + +int +hal_uart_close(int port) +{ + struct uart *uart; + int rc; + + if (port >= UART_CNT) { + rc = -1; + goto err; + } + + uart = &uarts[port]; + if (!uart->u_open) { + rc = -1; + goto err; + } + + close(uart->u_fd); + + uart->u_open = 0; + return (0); + err: + return (rc); +} + +int +hal_uart_init(int port, void *arg) +{ + return (0); +} + +int +uart_set_dev(int port, const char *dev_str) +{ + if (port < 0 || port >= UART_CNT) { + return SYS_EINVAL; + } + + if (uarts[port].u_open) { + return SYS_EBUSY; + } + + native_uart_dev_strs[port] = dev_str; + + return 0; +} diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_watchdog.c b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_watchdog.c new file mode 100644 index 0000000000..d94c7e332a --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_watchdog.c @@ -0,0 +1,36 @@ +/* + * 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. + */ + +#include "hal/hal_watchdog.h" + +int +hal_watchdog_init(uint32_t expire_msecs) +{ + return (0); +} + +void +hal_watchdog_enable(void) +{ +} + +void +hal_watchdog_tickle(void) +{ +} diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/src/native_uart_cfg.c b/babblesim/hw/mcu/nordic/nrf52_bsim/src/native_uart_cfg.c new file mode 100644 index 0000000000..5e38ac7bf4 --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/src/native_uart_cfg.c @@ -0,0 +1,248 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include + +/* B0 defined in bits/termios.h collides with nrfx/mdk/nrf52.h */ +#undef B0 + +#include "os/mynewt.h" +#include "native_uart_cfg_priv.h" + +/* uint64 is used here to accommodate speed_t, whatever that is. */ +static const uint64_t uart_baud_table[][2] = { +#ifdef B50 + { 50, B50 }, +#endif +#ifdef B75 + { 75, B75 }, +#endif +#ifdef B110 + { 110, B110 }, +#endif +#ifdef B134 + { 134, B134 }, +#endif +#ifdef B150 + { 150, B150 }, +#endif +#ifdef B200 + { 200, B200 }, +#endif +#ifdef B300 + { 300, B300 }, +#endif +#ifdef B600 + { 600, B600 }, +#endif +#ifdef B1200 + { 1200, B1200 }, +#endif +#ifdef B1800 + { 1800, B1800 }, +#endif +#ifdef B2400 + { 2400, B2400 }, +#endif +#ifdef B4800 + { 4800, B4800 }, +#endif +#ifdef B9600 + { 9600, B9600 }, +#endif +#ifdef B19200 + { 19200, B19200 }, +#endif +#ifdef B38400 + { 38400, B38400 }, +#endif +#ifdef B57600 + { 57600, B57600 }, +#endif +#ifdef B115200 + { 115200, B115200 }, +#endif +#ifdef B230400 + { 230400, B230400 }, +#endif +#ifdef B460800 + { 460800, B460800 }, +#endif +#ifdef B500000 + { 500000, B500000 }, +#endif +#ifdef B576000 + { 576000, B576000 }, +#endif +#ifdef B921600 + { 921600, B921600 }, +#endif +#ifdef B1000000 + { 1000000, B1000000 }, +#endif +#ifdef B1152000 + { 1152000, B1152000 }, +#endif +#ifdef B1500000 + { 1500000, B1500000 }, +#endif +#ifdef B2000000 + { 2000000, B2000000 }, +#endif +#ifdef B2500000 + { 2500000, B2500000 }, +#endif +#ifdef B3000000 + { 3000000, B3000000 }, +#endif +#ifdef B3500000 + { 3500000, B3500000 }, +#endif +#ifdef B3710000 + { 3710000, B3710000 }, +#endif +#ifdef B4000000 + { 4000000, B4000000 }, +#endif +}; +#define UART_BAUD_TABLE_SZ (sizeof uart_baud_table / sizeof uart_baud_table[0]) + +/** + * Returns 0 on failure. + */ +speed_t +uart_baud_to_speed(int_least32_t baud) +{ + int i; + + for (i = 0; i < UART_BAUD_TABLE_SZ; i++) { + if (uart_baud_table[i][0] == baud) { + return uart_baud_table[i][1]; + } + } + + return 0; +} + +/** + * Configures an external device terminal (/dev/cu.<...>). + */ +int +uart_dev_set_attr(int fd, int32_t baudrate, uint8_t databits, + uint8_t stopbits, enum hal_uart_parity parity, + enum hal_uart_flow_ctl flow_ctl) +{ + struct termios tty; + speed_t speed; + int rc; + + assert(fd >= 0); + + memset(&tty, 0, sizeof(tty)); + cfmakeraw(&tty); + + speed = uart_baud_to_speed(baudrate); + if (speed == 0) { + fprintf(stderr, "invalid baud rate: %d\n", (int)baudrate); + assert(0); + } + + tty.c_cflag |= (speed | CLOCAL | CREAD); + + /* Set flow control. */ + switch (flow_ctl) { + case HAL_UART_FLOW_CTL_NONE: + tty.c_cflag &= ~CRTSCTS; + break; + + case HAL_UART_FLOW_CTL_RTS_CTS: + tty.c_cflag |= CRTSCTS; + break; + + default: + fprintf(stderr, "invalid flow control setting: %d\n", flow_ctl); + return -1; + } + + errno = 0; + rc = cfsetospeed(&tty, speed); + if (rc != 0) { + fprintf(stderr, "cfsetospeed failed; %d (%s) baudrate=%d\n", + errno, strerror(errno), (int)baudrate); + return -1; + } + + errno = 0; + rc = cfsetispeed(&tty, speed); + if (rc != 0) { + fprintf(stderr, "cfsetispeed failed; %d (%s) baudrate=%d\n", + errno, strerror(errno), (int)baudrate); + return -1; + } + + switch (databits) { + case 7: + tty.c_cflag |= CS7; + + switch (parity) { + case HAL_UART_PARITY_ODD: + tty.c_cflag |= PARENB; + tty.c_cflag |= PARODD; + tty.c_cflag &= ~CSTOPB; + tty.c_cflag &= ~CSIZE; + break; + + case HAL_UART_PARITY_EVEN: + tty.c_cflag |= PARENB; + tty.c_cflag &= ~PARODD; + tty.c_cflag &= ~CSTOPB; + tty.c_cflag &= ~CSIZE; + break; + + default: + return SYS_EINVAL; + } + + case 8: + if (parity != HAL_UART_PARITY_NONE) { + return SYS_EINVAL; + } + tty.c_cflag |= CS8; + tty.c_cflag &= ~PARENB; + tty.c_cflag &= ~CSTOPB; + tty.c_cflag &= ~CSIZE; + break; + + default: + return SYS_EINVAL; + } + + rc = tcsetattr(fd, TCSANOW, &tty); + if (rc != 0) { + fprintf(stderr, "tcsetattr failed; %d (%s)\n", errno, strerror(errno)); + return -1; + } + + return 0; +} diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/src/native_uart_cfg_priv.h b/babblesim/hw/mcu/nordic/nrf52_bsim/src/native_uart_cfg_priv.h new file mode 100644 index 0000000000..786a68addf --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/src/native_uart_cfg_priv.h @@ -0,0 +1,31 @@ +/* + * 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_NATIVE_UART_CFG_PRIV_ +#define H_NATIVE_UART_CFG_PRIV_ + +#include +#include "hal/hal_uart.h" + +speed_t uart_baud_to_speed(int_least32_t baud); +int uart_dev_set_attr(int fd, int32_t baudrate, uint8_t databits, + uint8_t stopbits, enum hal_uart_parity parity, + enum hal_uart_flow_ctl flow_ctl); + +#endif diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/src/nrf52_clock.c b/babblesim/hw/mcu/nordic/nrf52_bsim/src/nrf52_clock.c new file mode 100644 index 0000000000..25ccc7fdd3 --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/src/nrf52_clock.c @@ -0,0 +1,103 @@ +/* + * 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. + */ +#include +#include +#include +#include +#include "mcu/nrf52_hal.h" +#include "nrfx.h" +#include "syscfg/syscfg.h" +#include "os/os.h" + +static uint8_t nrf52_clock_hfxo_refcnt; + +/** + * Request HFXO clock be turned on. Note that each request must have a + * corresponding release. + * + * @return int 0: hfxo was already on. 1: hfxo was turned on. + */ +int +nrf52_clock_hfxo_request(void) +{ + int started; + uint32_t ctx; + +#if MYNEWT_VAL_CHOICE(MCU_HFCLK_SOURCE, HFINT) + /* Cannot enable/disable hfxo if it is not present */ + assert(0); +#endif + + started = 0; + __HAL_DISABLE_INTERRUPTS(ctx); + assert(nrf52_clock_hfxo_refcnt < 0xff); + if (nrf52_clock_hfxo_refcnt == 0) { + /* Check the current STATE and SRC of HFCLK */ + if ((NRF_CLOCK->HFCLKSTAT & + (CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk)) != + (CLOCK_HFCLKSTAT_SRC_Xtal << CLOCK_HFCLKSTAT_SRC_Pos | + CLOCK_HFCLKSTAT_STATE_Running << CLOCK_HFCLKSTAT_STATE_Pos)) { + NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; + nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART); + while (!NRF_CLOCK->EVENTS_HFCLKSTARTED) { +#if BABBLESIM + tm_tick(); +#endif + } + } + started = 1; + } + ++nrf52_clock_hfxo_refcnt; + __HAL_ENABLE_INTERRUPTS(ctx); + + return started; +} + +/** + * Release the HFXO. This means that the caller no longer needs the HFXO to be + * turned on. Each call to release should have been preceeded by a corresponding + * call to request the HFXO + * + * + * @return int 0: HFXO not stopped by this call (others using it) 1: HFXO + * stopped. + */ +int +nrf52_clock_hfxo_release(void) +{ + int stopped; + uint32_t ctx; + +#if MYNEWT_VAL_CHOICE(MCU_HFCLK_SOURCE, HFINT) + /* Cannot enable/disable hfxo if it is not present */ + assert(0); +#endif + + stopped = 0; + __HAL_DISABLE_INTERRUPTS(ctx); + assert(nrf52_clock_hfxo_refcnt != 0); + --nrf52_clock_hfxo_refcnt; + if (nrf52_clock_hfxo_refcnt == 0) { + nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); + stopped = 1; + } + __HAL_ENABLE_INTERRUPTS(ctx); + + return stopped; +} diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/src/system_nrf52.c b/babblesim/hw/mcu/nordic/nrf52_bsim/src/system_nrf52.c new file mode 100644 index 0000000000..00224cdc06 --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/src/system_nrf52.c @@ -0,0 +1,37 @@ +/* Copyright (c) 2012 ARM LIMITED + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of ARM nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "mcu/cmsis_nvic.h" +#include "nrf.h" + + +void SystemInit(void) +{ +} diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/syscfg.yml b/babblesim/hw/mcu/nordic/nrf52_bsim/syscfg.yml new file mode 100644 index 0000000000..b1bc4b874e --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/syscfg.yml @@ -0,0 +1,526 @@ +# 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. +# + +syscfg.defs: + MCU_TARGET: + description: > + Specifies target MCU, shall be set by BSP. + value: + restrictions: + - $notnull + choices: + - nRF52810 + - nRF52811 + - nRF52832 + - nRF52840 + + MCU_FLASH_MIN_WRITE_SIZE: + description: > + Specifies the required alignment for internal flash writes. + Used internally by the newt tool. + value: 1 + + MCU_DCDC_ENABLED: + description: > + Specifies whether or not to enable DC/DC regulator. This requires + external circuitry so is defined to be zero by default and + expected to be overridden by the BSP. + value: 0 + + MCU_HFCLK_SOURCE: + description: > + Selected source for high frequency clock (HFCLK). + Selecting HFXO will still mostly use the HFINT but will switch to HFXO when requested (BLE, certain timers, etc...) + Selecting HFINT should only be used in the case where an external 32MHz crystal oscillator is not present. + value: HFXO + choices: + - HFXO + - HFINT + restrictions: + - '(MCU_HFCLK_SOURCE == "HFXO") || (MCU_LFCLK_SOURCE != "LFSYNTH")' + + MCU_LFCLK_SOURCE: + description: > + Selected source for low frequency clock (LFCLK). + value: + choices: + - LFRC # 32.768 kHz RC oscillator + - LFXO # 32.768 kHz crystal oscillator + - LFSYNTH # 32.768 kHz synthesized from HFCLK + + MCU_I2C_RECOVERY_DELAY_USEC: + description: > + Time to wait for activity on SCL line after triggering start task + before restarting TWI controller. This is to recover from state + where controller is unresponsive due to glitch on I2C bus. + Note: Default value seems to work fine, but may need to be tuned. + value: 100 + + MCU_BUS_DRIVER_I2C_USE_TWIM: + description: > + Enables usage of i2c_nrf52_twim bus driver for I2C. + If disabled, standard i2c_hal driver is used. + value: 0 + + MCU_GPIO_USE_PORT_EVENT: + description: > + When enabled, hal_gpio will use GPIOTE PORT event instead of PIN + events for interrupts. This mode may be less accurate (i.e. pulse + length needs to be longer in order to be detected) but it reduces + power consumption since it does not require HFCLK to be running. + Refer to nRF52xxx Product Specification document for more details. + value: 0 + + MCU_DEBUG_IGNORE_BKPT: + description: > + When enabled, asm(bkpt) will be ignored. If not set, it will hit + the breakpoint wherever it gets called, For example, reset and crash + value: 0 + + +# MCU peripherals definitions + I2C_0: + description: 'Enable nRF52xxx I2C (TWI) 0' + value: 0 + restrictions: + - '!(SPI_0_MASTER && ((MCU_TARGET == "nrf52832") || (MCU_TARGET == "nrf52840")))' + - '!(SPI_0_SLAVE && ((MCU_TARGET == "nrf52832") || (MCU_TARGET == "nrf52840")))' + - '!(SPI_1_MASTER && (MCU_TARGET == "nrf52811"))' + - '!(SPI_1_SLAVE && (MCU_TARGET == "nrf52811"))' + I2C_0_PIN_SCL: + description: 'SCL pin for I2C_0' + value: '' + I2C_0_PIN_SDA: + description: 'SDA pin for I2C_0' + value: '' + I2C_0_FREQ_KHZ: + description: 'Frequency [kHz] for I2C_0' + value: 100 + + I2C_1: + description: 'Enable nRF52xxx I2C (TWI) 1' + value: 0 + restrictions: + - "!SPI_1_MASTER" + - "!SPI_1_SLAVE" + I2C_1_PIN_SCL: + description: 'SCL pin for I2C_1' + value: '' + I2C_1_PIN_SDA: + description: 'SDA pin for I2C_1' + value: '' + I2C_1_FREQ_KHZ: + description: 'Frequency [kHz] for I2C_1' + value: 100 + + SPI_0_MASTER: + description: 'Enable nRF52xxx SPI Master 0' + value: 0 + restrictions: + - "!SPI_0_SLAVE" + - '!(I2C_0 && ((MCU_TARGET == "nrf52832") || (MCU_TARGET == "nrf52840")))' + SPI_0_MASTER_PIN_SCK: + description: 'SCK pin for SPI_0_MASTER' + value: '' + SPI_0_MASTER_PIN_MOSI: + description: 'MOSI pin for SPI_0_MASTER' + value: '' + SPI_0_MASTER_PIN_MISO: + description: 'MISO pin for SPI_0_MASTER' + value: '' + + SPI_0_SLAVE: + description: 'Enable nRF52xxx SPI Slave 0' + value: 0 + restrictions: + - "!SPI_0_MASTER" + - '!(I2C_0 && ((MCU_TARGET == "nrf52832") || (MCU_TARGET == "nrf52840")))' + SPI_0_SLAVE_PIN_SCK: + description: 'SCK pin for SPI_0_SLAVE' + value: '' + SPI_0_SLAVE_PIN_MOSI: + description: 'MOSI pin for SPI_0_SLAVE' + value: '' + SPI_0_SLAVE_PIN_MISO: + description: 'MISO pin for SPI_0_SLAVE' + value: '' + SPI_0_SLAVE_PIN_SS: + description: 'SS pin for SPI_0_SLAVE' + value: '' + + SPI_1_MASTER: + description: 'Enable nRF52xxx SPI Master 1' + value: 0 + restrictions: + - "!SPI_1_SLAVE" + - '!(I2C_1 && ((MCU_TARGET == "nrf52832") || (MCU_TARGET == "nrf52840")))' + - '!(I2C_0 && ((MCU_TARGET == "nrf52811")))' + SPI_1_MASTER_PIN_SCK: + description: 'SCK pin for SPI_1_MASTER' + value: '' + SPI_1_MASTER_PIN_MOSI: + description: 'MOSI pin for SPI_1_MASTER' + value: '' + SPI_1_MASTER_PIN_MISO: + description: 'MISO pin for SPI_1_MASTER' + value: '' + + SPI_1_SLAVE: + description: 'Enable nRF52xxx SPI Slave 1' + value: 0 + restrictions: + - "!SPI_1_MASTER" + - '!(I2C_1 && ((MCU_TARGET == "nrf52832") || (MCU_TARGET == "nrf52840")))' + - '!(I2C_0 && ((MCU_TARGET == "nrf52811")))' + SPI_1_SLAVE_PIN_SCK: + description: 'SCK pin for SPI_1_SLAVE' + value: '' + SPI_1_SLAVE_PIN_MOSI: + description: 'MOSI pin for SPI_1_SLAVE' + value: '' + SPI_1_SLAVE_PIN_MISO: + description: 'MISO pin for SPI_1_SLAVE' + value: '' + SPI_1_SLAVE_PIN_SS: + description: 'SS pin for SPI_1_SLAVE' + value: '' + + SPI_2_MASTER: + description: 'Enable nRF52xxx SPI Master 2' + value: 0 + restrictions: + - "!SPI_2_SLAVE" + SPI_2_MASTER_PIN_SCK: + description: 'SCK pin for SPI_2_MASTER' + value: '' + SPI_2_MASTER_PIN_MOSI: + description: 'MOSI pin for SPI_2_MASTER' + value: '' + SPI_2_MASTER_PIN_MISO: + description: 'MISO pin for SPI_2_MASTER' + value: '' + + SPI_2_SLAVE: + description: 'Enable nRF52xxx SPI Slave 2' + value: 0 + restrictions: + - "!SPI_2_MASTER" + SPI_2_SLAVE_PIN_SCK: + description: 'SCK pin for SPI_2_SLAVE' + value: '' + SPI_2_SLAVE_PIN_MOSI: + description: 'MOSI pin for SPI_2_SLAVE' + value: '' + SPI_2_SLAVE_PIN_MISO: + description: 'MISO pin for SPI_2_SLAVE' + value: '' + SPI_2_SLAVE_PIN_SS: + description: 'SS pin for SPI_2_SLAVE' + value: '' + + SPI_3_MASTER: + description: 'Enable nRF52xxx SPI Master 3' + value: 0 + restrictions: + - 'MCU_TARGET == "nRF52840" || !SPI_3_MASTER' + SPI_3_MASTER_PIN_SCK: + description: 'SCK pin for SPI_3_MASTER' + value: '' + SPI_3_MASTER_PIN_MOSI: + description: 'MOSI pin for SPI_3_MASTER' + value: '' + SPI_3_MASTER_PIN_MISO: + description: 'MISO pin for SPI_3_MASTER' + value: '' + + ADC_0: + description: 'Enable nRF52xxx ADC 0' + value: 0 + + ADC_0_REFMV_0: + description: 'reference mV in AREF0 if used' + value: 0 + + PWM_0: + description: 'Enable nRF52xxx PWM 0' + value: 0 + PWM_1: + description: 'Enable nRF52xxx PWM 1' + value: 0 + PWM_2: + description: 'Enable nRF52xxx PWM 2' + value: 0 + PWM_3: + description: 'Enable nRF52xxx PWM 3' + value: 0 + restrictions: + - 'MCU_TARGET == "nRF52840" || !PWM_3' + + TRNG: + description: 'Enable nRF52xxx TRNG' + value: 0 + + CRYPTO: + description: 'Enable nRF52xxx CRYPTO' + value: 0 + + UART_0: + description: 'Enable nRF52xxx UART0' + value: 1 + UART_0_PIN_TX: + description: 'TX pin for UART0' + value: '' + UART_0_PIN_RX: + description: 'RX pin for UART0' + value: '' + UART_0_PIN_RTS: + description: 'RTS pin for UART0' + value: -1 + UART_0_PIN_CTS: + description: 'CTS pin for UART0' + value: -1 + + UART_1: + description: 'Enable nRF52xxx UART1' + value: 0 + restrictions: + - 'MCU_TARGET == "nRF52840" || !UART_1' + UART_1_PIN_TX: + description: 'TX pin for UART1' + value: '' + UART_1_PIN_RX: + description: 'RX pin for UART1' + value: '' + UART_1_PIN_RTS: + description: 'RTS pin for UART1' + value: -1 + UART_1_PIN_CTS: + description: 'CTS pin for UART1' + value: -1 + + TEMP: + description: 'Enable nRF52xxx internal temperature mesurement' + value: 0 + + TIMER_0: + description: 'Enable nRF52xxx Timer 0' + value: 1 + TIMER_1: + description: 'Enable nRF52xxx Timer 1' + value: 0 + TIMER_2: + description: 'Enable nRF52xxx Timer 2' + value: 0 + TIMER_3: + description: 'Enable nRF52xxx Timer 3' + value: 0 + TIMER_4: + description: 'Enable nRF52xxx Timer 4' + value: 0 + TIMER_5: + description: 'Enable nRF52xxx RTC 0' + value: 0 + + QSPI_ENABLE: + description: 'NRF52 QSPI' + value: 0 + + QSPI_READOC: + description: > + QSPI Command to use + 0 - 0x09 Fast Read + 1 - 0x3B Fast Read Dual Output + 2 - 0xBB Fast Read Dual I/O + 3 - 0x6B Fast Read Quad Output + 4 - 0xEB Fast Read Quad I/O + value: 0 + QSPI_WRITEOC: + description: > + QSPI Command to use + 0 - 0x02 Page program + 1 - 0xA2 Page program Dual Data + 2 - 0x32 Page program Quad Data + 3 - 0x38 Page program Quad I/O + value: 0 + QSPI_ADDRMODE: + description: 'Address lentgh 0=24 bits, 1=32 bits' + value: 0 + QSPI_DPMCONFIG: + description: 'Deep power mode enable' + value: 0 + QSPI_SCK_DELAY: + description: > + Minimum amount of time that the CSN pin must stay high + before it can go low again. Value is specified in number of 16 + MHz periods (62.5 ns). + value: 0 + QSPI_SCK_FREQ: + description: '32MHz clock divider (0-31). Clock = 32MHz / (1+divider)' + value: 0 + QSPI_SPI_MODE: + description: 'SPI 0=Mode0 or 1=Mode3' + value: 0 + + QSPI_FLASH_SECTOR_SIZE: + description: 'QSPI sector size. In most cases it should be 4096.' + value: 0 + QSPI_FLASH_PAGE_SIZE: + description: > + QSPI page size. Writes can only be performed to one page at a time. + In most cases it should be 256. + value: 0 + + QSPI_FLASH_SECTOR_COUNT: + description: 'QSPI sector count' + value: -1 + QSPI_PIN_CS: + description: 'CS pin for QSPI' + value: -1 + QSPI_PIN_SCK: + description: 'SCK pin for QSPI' + value: -1 + QSPI_PIN_DIO0: + description: 'DIO0 pin for QSPI' + value: -1 + QSPI_PIN_DIO1: + description: 'DIO1 pin for QSPI' + value: -1 + QSPI_PIN_DIO2: + description: 'DIO2 pin for QSPI' + value: -1 + QSPI_PIN_DIO3: + description: 'DIO3 pin for QSPI' + value: -1 + + NFC_PINS_AS_GPIO: + description: 'Use NFC pins as GPIOs instead of NFC functionality' + value: 1 + + GPIO_AS_PIN_RESET: + description: 'Enable pin reset' + value: 0 + +# Deprecated settings + + MCU_NRF52832: + description: Use MCU_TARGET instead + value: 0 + restrictions: + - "!MCU_NRF52840" + deprecated: 1 + MCU_NRF52840: + description: Use MCU_TARGET instead + value: 0 + restrictions: + - "!MCU_NRF52832" + deprecated: 1 + + XTAL_32768: + description: Use MCU_LFCLK_SOURCE instead + value: 0 + restrictions: + - "!XTAL_RC" + - "!XTAL_32768_SYNTH" + deprecated: 1 + XTAL_RC: + description: Use MCU_LFCLK_SOURCE instead + value: 0 + restrictions: + - "!XTAL_32768" + - "!XTAL_32768_SYNTH" + deprecated: 1 + XTAL_32768_SYNTH: + description: Use MCU_LFCLK_SOURCE instead + value: 0 + restrictions: + - "!XTAL_32768" + - "!XTAL_RC" + deprecated: 1 + + MCU_NATIVE_USE_SIGNALS: + description: > + Whether to use POSIX signals to implement context switches. Valid + values are as follows: + 1: More correctness; less stability. The OS tick timer will + cause a high-priority task to preempt a low-priority task. + This causes stability issues because a task can be preempted + while it is in the middle of a system call, potentially + causing deadlock or memory corruption. + + 0: Less correctness; more stability. The OS tick timer only + runs while the idle task is active. Therefore, a sleeping + high-priority task will not preempt a low-priority task due + to a timing event (e.g., delay or callout expired). + However, this version of sim does not suffer from the + stability issues that affect the "signals" implementation. + + Unit tests should use 1. Long-running sim processes should use 0. + + value: 1 + MCU_NATIVE: + description: > + Set to indicate that we are using native mcu. + value: 1 + MCU_FLASH_STYLE_ST: + description: Emulated flash layout is similar to one in STM32. + value: 1 + restrictions: + - "!MCU_FLASH_STYLE_NORDIC" + MCU_FLASH_STYLE_NORDIC: + description: > + Emulated flash layout is similar to one in NRF51/2 and SAMD21. + value: 0 + restrictions: + - "!MCU_FLASH_STYLE_ST" + MCU_UART_POLLER_PRIO: + description: 'Priority of native UART poller task.' + type: task_priority + value: 1 + MCU_TIMER_POLLER_PRIO: + description: 'Priority of native HAL timer task.' + type: task_priority + value: 0 + +syscfg.vals: + OS_TICKS_PER_SEC: 128 + +syscfg.vals.MCU_NRF52832: + MCU_TARGET: nRF52832 +syscfg.vals.MCU_NRF52840: + MCU_TARGET: nRF52840 + +syscfg.vals.XTAL_32768: + MCU_LFCLK_SOURCE: LFXO +syscfg.vals.XTAL_RC: + MCU_LFCLK_SOURCE: LFRC +syscfg.vals.XTAL_32768_SYNTH: + MCU_LFCLK_SOURCE: LFSYNTH + +syscfg.restrictions: + - "!I2C_0 || (I2C_0_PIN_SCL && I2C_0_PIN_SDA)" + - "!I2C_1 || (I2C_1_PIN_SCL && I2C_1_PIN_SDA)" + - "!SPI_0_MASTER || (SPI_0_MASTER_PIN_SCK && SPI_0_MASTER_PIN_MOSI && SPI_0_MASTER_PIN_MISO)" + - "!SPI_1_MASTER || (SPI_1_MASTER_PIN_SCK && SPI_1_MASTER_PIN_MOSI && SPI_1_MASTER_PIN_MISO)" + - "!SPI_2_MASTER || (SPI_2_MASTER_PIN_SCK && SPI_2_MASTER_PIN_MOSI && SPI_2_MASTER_PIN_MISO)" + - "!SPI_3_MASTER || (SPI_3_MASTER_PIN_SCK && SPI_3_MASTER_PIN_MOSI && SPI_3_MASTER_PIN_MISO)" + - "!SPI_0_SLAVE || (SPI_0_SLAVE_PIN_SCK && SPI_0_SLAVE_PIN_MOSI && SPI_0_SLAVE_PIN_MISO && SPI_0_SLAVE_PIN_SS)" + - "!SPI_1_SLAVE || (SPI_1_SLAVE_PIN_SCK && SPI_1_SLAVE_PIN_MOSI && SPI_1_SLAVE_PIN_MISO && SPI_1_SLAVE_PIN_SS)" + - "!SPI_2_SLAVE || (SPI_2_SLAVE_PIN_SCK && SPI_2_SLAVE_PIN_MOSI && SPI_2_SLAVE_PIN_MISO && SPI_2_SLAVE_PIN_SS)" + - "!UART_0 || (UART_0_PIN_TX && UART_0_PIN_RX)" + - "!UART_1 || (UART_1_PIN_TX && UART_1_PIN_RX)" + - "(OS_TICKS_PER_SEC == 128 || OS_TICKS_PER_SEC == 256 || OS_TICKS_PER_SEC == 512 || OS_TICKS_PER_SEC == 1024)" diff --git a/babblesim/libc/LICENSE b/babblesim/libc/LICENSE new file mode 100644 index 0000000000..b7915742b4 --- /dev/null +++ b/babblesim/libc/LICENSE @@ -0,0 +1,133 @@ +Baselibc is based on klibc 1.5.23 and tinyprintf modules. +None of the GPL-licensed parts of klibc are used. + +Baselibc is licensed under the BSD license: + +Copyright (c) 2012 Petteri Aimonen +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Kustaa Nyholm or SpareTimeLabs nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The original licenses of the modules are included below: + +------------------ Tinyprintf license ------------------ + +Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Kustaa Nyholm or SpareTimeLabs nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +------------------- klibc license ------------------------- +This license applies to all files in directory and its subdirectories, +unless otherwise noted in individual files. + + +Some files are derived from files derived from the include/ directory +of the Linux kernel, and are licensed under the terms of the GNU +General Public License, version 2, as released by the Free Software +Foundation, Inc.; incorporated herein by reference. +[These files are not included in the baselibc.] + + ----- + +Some files are derived from files copyrighted by the Regents of The +University of California, and are available under the following +license: + +Note: The advertising clause in the license appearing on BSD Unix +files was officially rescinded by the Director of the Office of +Technology Licensing of the University of California on July 22 +1999. He states that clause 3 is "hereby deleted in its entirety." + + * Copyright (c) + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + +For all remaining files [of klibc], the following license applies: + + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * Any copyright notice(s) and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/babblesim/libc/pkg.yml b/babblesim/libc/pkg.yml new file mode 100644 index 0000000000..297bfa9f8f --- /dev/null +++ b/babblesim/libc/pkg.yml @@ -0,0 +1,28 @@ +# +# 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: babblesim/libc +pkg.type: sdk +pkg.description: Functions from apache-mynewt-core/libc that not exists in Linux system. +pkg.author: "Codecoup" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - "@apache-mynewt-core/kernel/os" diff --git a/babblesim/libc/src/strlcat.c b/babblesim/libc/src/strlcat.c new file mode 100644 index 0000000000..6d95087055 --- /dev/null +++ b/babblesim/libc/src/strlcat.c @@ -0,0 +1,30 @@ +/* + * strlcat.c + */ + +#include + +size_t strlcat(char *dst, const char *src, size_t size) +{ + size_t bytes = 0; + char *q = dst; + const char *p = src; + char ch; + + while (bytes < size && *q) { + q++; + bytes++; + } + if (bytes == size) + return (bytes + strlen(src)); + + while ((ch = *p++)) { + if (bytes + 1 < size) + *q++ = ch; + + bytes++; + } + + *q = '\0'; + return bytes; +} diff --git a/babblesim/libc/src/strlcpy.c b/babblesim/libc/src/strlcpy.c new file mode 100644 index 0000000000..3ec8fd2dfd --- /dev/null +++ b/babblesim/libc/src/strlcpy.c @@ -0,0 +1,26 @@ +/* + * strlcpy.c + */ + +#include + +size_t strlcpy(char *dst, const char *src, size_t size) +{ + size_t bytes = 0; + char *q = dst; + const char *p = src; + char ch; + + while ((ch = *p++)) { + if (bytes + 1 < size) + *q++ = ch; + + bytes++; + } + + /* If size == 0 there is no space for a final null... */ + if (size) + *q = '\0'; + + return bytes; +} diff --git a/babblesim/nrfx/pkg.yml b/babblesim/nrfx/pkg.yml new file mode 100644 index 0000000000..54a385e2c6 --- /dev/null +++ b/babblesim/nrfx/pkg.yml @@ -0,0 +1,37 @@ +# +# 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: babblesim/nrfx +pkg.description: nrfx wrapper for BabbleSim +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" +pkg.type: sdk + +pkg.cflags: -std=gnu99 +pkg.include_dirs: + - src/ + - src/drivers/ + - src/hal/ + - src/mdk/ + +pkg.deps: + - "@apache-mynewt-core/hw/hal" + +pkg.pre_build_cmds: + scripts/link_nrfx.sh: 1 diff --git a/babblesim/nrfx/scripts/link_nrfx.sh b/babblesim/nrfx/scripts/link_nrfx.sh new file mode 100755 index 0000000000..2b59847eb0 --- /dev/null +++ b/babblesim/nrfx/scripts/link_nrfx.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# +# 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. +# + +mkdir -p ./src/ +for f in nrfx.h drivers hal mdk; do + ln -sfn ${NRFX_BASE}/${f} ./src/${f} +done \ No newline at end of file From d81f0708339ce2a8a5c7b6dfc8a1fbc0091be6b6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sun, 13 Feb 2022 19:30:49 +0100 Subject: [PATCH 0271/1333] apps/blehci: Add support for BabbleSim --- apps/blehci/src/main.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/apps/blehci/src/main.c b/apps/blehci/src/main.c index 040c1572cb..e97e54270f 100644 --- a/apps/blehci/src/main.c +++ b/apps/blehci/src/main.c @@ -17,11 +17,10 @@ * under the License. */ -#include #include "os/mynewt.h" -int -main(void) +static int +main_fn(int argc, char **argv) { /* Initialize OS */ sysinit(); @@ -31,3 +30,16 @@ main(void) } return 0; } + +int +main(int argc, char **argv) +{ +#if BABBLESIM + extern void bsim_init(int argc, char** argv, void *main_fn); + bsim_init(argc, argv, main_fn); +#else + main_fn(argc, argv); +#endif + + return 0; +} \ No newline at end of file From 32281f273908e75593e920d1e04e6954f9fe7732 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 15 Feb 2022 16:41:06 +0100 Subject: [PATCH 0272/1333] travis: Allow ports build to fail This is temporary until issues with RIOT are resolved. --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 185ca35507..7567ce3e05 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,11 @@ git: depth: false matrix: + allow_failures: + - env: + - TEST=BUILD_PORTS + - VM_AMOUNT=1 + - TARGET_SET=1 include: # Style checking - os: linux From cb76bcdbea0be1cedb3551b3bb0a15c19a62b4dd Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 14 Feb 2022 12:06:05 +0100 Subject: [PATCH 0273/1333] apps: Add main() wrappers for BabbleSim --- apps/blecent/src/main.c | 17 +++++++++++++++-- apps/bleprph/src/main.c | 17 +++++++++++++++-- apps/btshell/src/main.c | 17 +++++++++++++++-- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/apps/blecent/src/main.c b/apps/blecent/src/main.c index 788f21158e..7f1c5f151c 100644 --- a/apps/blecent/src/main.c +++ b/apps/blecent/src/main.c @@ -495,8 +495,8 @@ blecent_on_sync(void) * * @return int NOTE: this function should never return! */ -int -main(void) +static int +main_fn(int argc, char **argv) { int rc; @@ -523,3 +523,16 @@ main(void) return 0; } + +int +main(int argc, char **argv) +{ +#if BABBLESIM + extern void bsim_init(int argc, char** argv, void *main_fn); + bsim_init(argc, argv, main_fn); +#else + main_fn(argc, argv); +#endif + + return 0; +} diff --git a/apps/bleprph/src/main.c b/apps/bleprph/src/main.c index 66f9baccb4..60a3aea9dc 100644 --- a/apps/bleprph/src/main.c +++ b/apps/bleprph/src/main.c @@ -302,8 +302,8 @@ bleprph_on_sync(void) * * @return int NOTE: this function should never return! */ -int -main(void) +static int +main_fn(int argc, char **argv) { #if MYNEWT_VAL(BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM) >= 0 struct image_version ver; @@ -357,3 +357,16 @@ main(void) } return 0; } + +int +main(int argc, char **argv) +{ +#if BABBLESIM + extern void bsim_init(int argc, char** argv, void *main_fn); + bsim_init(argc, argv, main_fn); +#else + main_fn(argc, argv); +#endif + + return 0; +} diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index 99f0a7979f..f4f864e7fa 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -2557,8 +2557,8 @@ btshell_init_ext_adv_restart(void) * * @return int NOTE: this function should never return! */ -int -main(int argc, char **argv) +static int +main_fn(int argc, char **argv) { int rc; @@ -2634,3 +2634,16 @@ main(int argc, char **argv) return 0; } + +int +main(int argc, char **argv) +{ +#if BABBLESIM + extern void bsim_init(int argc, char** argv, void *main_fn); + bsim_init(argc, argv, main_fn); +#else + main_fn(argc, argv); +#endif + + return 0; +} From 06a19ab940c6c35943477e3cacf0108b6053ca33 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 14 Feb 2022 12:27:16 +0100 Subject: [PATCH 0274/1333] babblesim: Add hal_flash and hal_hw_id This allows to run more apps on BabbleSim, e.g. blecent and bleprph. --- babblesim/hw/bsp/nrf52_bsim/src/hal_bsp.c | 33 +- babblesim/hw/bsp/nrf52_bsim/syscfg.yml | 1 - .../nrf52_bsim/include/mcu/native_bsp.h | 34 +++ .../hw/mcu/nordic/nrf52_bsim/src/hal_flash.c | 289 ++++++++++++++++++ .../hw/mcu/nordic/nrf52_bsim/src/hal_hw_id.c | 73 +++++ .../nordic/nrf52_bsim/src/hal_native_priv.h | 27 ++ babblesim/hw/mcu/nordic/nrf52_bsim/syscfg.yml | 4 +- 7 files changed, 432 insertions(+), 29 deletions(-) create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/native_bsp.h create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_flash.c create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_hw_id.c create mode 100644 babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_native_priv.h diff --git a/babblesim/hw/bsp/nrf52_bsim/src/hal_bsp.c b/babblesim/hw/bsp/nrf52_bsim/src/hal_bsp.c index 4250249e53..821e9ed27f 100644 --- a/babblesim/hw/bsp/nrf52_bsim/src/hal_bsp.c +++ b/babblesim/hw/bsp/nrf52_bsim/src/hal_bsp.c @@ -28,13 +28,11 @@ #include "hal/hal_system.h" #include "mcu/nrf52_hal.h" #include "mcu/nrf52_periph.h" +#include "mcu/native_bsp.h" #include "bsp/bsp.h" #include "defs/sections.h" #include "uart_hal/uart_hal.h" #include "uart/uart.h" -#if MYNEWT_VAL(ENC_FLASH_DEV) -#include -#endif /* * What memory to include in coredump. @@ -46,32 +44,15 @@ static const struct hal_bsp_mem_dump dump_cfg[] = { } }; -#if MYNEWT_VAL(ENC_FLASH_DEV) -static sec_data_secret struct eflash_nrf5x_dev enc_flash_dev0 = { - .end_dev = { - .efd_hal = { - .hf_itf = &enc_flash_funcs, - }, - .efd_hwdev = &nrf52k_flash_dev - } -}; -#endif - const struct hal_flash * hal_bsp_flash_dev(uint8_t id) { -// /* -// * Internal flash mapped to id 0. -// */ -// if (id == 0) { -// return &nrf52k_flash_dev; -// } -//#if MYNEWT_VAL(ENC_FLASH_DEV) -// if (id == 1) { -// return &enc_flash_dev0.end_dev.efd_hal; -// } -//#endif - return NULL; + switch (id) { + case 0: + return &native_flash_dev; + default: + return NULL; + } } const struct hal_bsp_mem_dump * diff --git a/babblesim/hw/bsp/nrf52_bsim/syscfg.yml b/babblesim/hw/bsp/nrf52_bsim/syscfg.yml index 0e9eb607a9..2070c69e14 100644 --- a/babblesim/hw/bsp/nrf52_bsim/syscfg.yml +++ b/babblesim/hw/bsp/nrf52_bsim/syscfg.yml @@ -35,7 +35,6 @@ syscfg.defs: syscfg.vals: OS_MAIN_STACK_SIZE: 8000 - BLE_HCI_TRANSPORT: uart MCU_TIMER_POLLER_PRIO: 0 BLE_LL_PRIO: 1 MCU_UART_POLLER_PRIO: 2 diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/native_bsp.h b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/native_bsp.h new file mode 100644 index 0000000000..dd794871a8 --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/native_bsp.h @@ -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. + */ +#ifndef H_NATIVE_BSP_ +#define H_NATIVE_BSP_ + +#ifdef __cplusplus +extern "C" { +#endif + +extern const struct hal_flash native_flash_dev; + +int uart_set_dev(int port, const char *dev_str); + +#ifdef __cplusplus +} +#endif + +#endif /* H_NATIVE_BSP_ */ diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_flash.c b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_flash.c new file mode 100644 index 0000000000..b39b5158ce --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_flash.c @@ -0,0 +1,289 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "os/mynewt.h" + +#include "hal/hal_flash_int.h" +#include "mcu/mcu_sim.h" + +char *native_flash_file; +static int file = -1; +static void *file_loc; + +static int native_flash_init(const struct hal_flash *dev); +static int native_flash_read(const struct hal_flash *dev, uint32_t address, + void *dst, uint32_t length); +static int native_flash_write(const struct hal_flash *dev, uint32_t address, + const void *src, uint32_t length); +static int native_flash_erase_sector(const struct hal_flash *dev, + uint32_t sector_address); +static int native_flash_sector_info(const struct hal_flash *dev, int idx, + uint32_t *address, uint32_t *size); + +static const struct hal_flash_funcs native_flash_funcs = { + .hff_read = native_flash_read, + .hff_write = native_flash_write, + .hff_erase_sector = native_flash_erase_sector, + .hff_sector_info = native_flash_sector_info, + .hff_init = native_flash_init +}; + +#if MYNEWT_VAL(MCU_FLASH_STYLE_ST) +static const uint32_t native_flash_sectors[] = { + 0x00000000, /* 16 * 1024 */ + 0x00004000, /* 16 * 1024 */ + 0x00008000, /* 16 * 1024 */ + 0x0000c000, /* 16 * 1024 */ + 0x00010000, /* 64 * 1024 */ + 0x00020000, /* 128 * 1024 */ + 0x00040000, /* 128 * 1024 */ + 0x00060000, /* 128 * 1024 */ + 0x00080000, /* 128 * 1024 */ + 0x000a0000, /* 128 * 1024 */ + 0x000c0000, /* 128 * 1024 */ + 0x000e0000, /* 128 * 1024 */ +}; +#elif MYNEWT_VAL(MCU_FLASH_STYLE_NORDIC) +static uint32_t native_flash_sectors[1024 * 1024 / 2048]; +#else +#error "Need to specify either MCU_FLASH_STYLE_NORDIC or MCU_FLASH_STYLE_ST" +#endif + +#define FLASH_NUM_AREAS (int)(sizeof native_flash_sectors / \ + sizeof native_flash_sectors[0]) + +const struct hal_flash native_flash_dev = { + .hf_itf = &native_flash_funcs, + .hf_base_addr = 0, + .hf_size = 1024 * 1024, + .hf_sector_cnt = FLASH_NUM_AREAS, + .hf_align = MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE), + .hf_erased_val = 0xff, +}; + +static void +flash_native_erase(uint32_t addr, uint32_t len) +{ + memset(file_loc + addr, 0xff, len); +} + +static void +flash_native_file_open(char *name) +{ + int created = 0; + char tmpl[] = "/tmp/native_flash.XXXXXX"; + + extern int ftruncate(int fd, off_t length); + + if (file != -1) { + close(file); + file = -1; + } + + if (name) { + file = open(name, O_RDWR); + if (file < 0) { + file = open(name, O_RDWR | O_CREAT, 0660); + assert(file > 0); + created = 1; + } + } else { + file = mkstemp(tmpl); + assert(file > 0); + created = 1; + } + + if (created) { + if (ftruncate(file, native_flash_dev.hf_size) < 0) { + assert(0); + } + } + + if (file_loc != NULL) { + munmap(file_loc, native_flash_dev.hf_size); + } + + file_loc = mmap(0, native_flash_dev.hf_size, + PROT_READ | PROT_WRITE, MAP_SHARED, file, 0); + assert(file_loc != MAP_FAILED); + if (created) { + flash_native_erase(0, native_flash_dev.hf_size); + } + + /* If using a temporary file, unlink it immediately. */ + if (name == NULL) { + remove(tmpl); + } +} + +static void +flash_native_ensure_file_open(void) +{ + if (file == 0) { + flash_native_file_open(NULL); + } +} + +static int +flash_native_write_internal(uint32_t address, const void *src, uint32_t length, + int allow_overwrite) +{ + static uint8_t buf[256]; + uint32_t cur; + uint32_t end; + int chunk_sz; + int rc; + int i; + + if (length == 0) { + return 0; + } + + end = address + length; + + flash_native_ensure_file_open(); + + cur = address; + while (cur < end) { + if (end - cur < sizeof buf) { + chunk_sz = end - cur; + } else { + chunk_sz = sizeof buf; + } + + /* Ensure data is not being overwritten. */ + if (!allow_overwrite) { + rc = native_flash_read(NULL, cur, buf, chunk_sz); + assert(rc == 0); + for (i = 0; i < chunk_sz; i++) { + assert(buf[i] == 0xff); + } + } + + cur += chunk_sz; + } + + memcpy((char *)file_loc + address, src, length); + + return 0; +} + +static int +native_flash_write(const struct hal_flash *dev, uint32_t address, + const void *src, uint32_t length) +{ + assert(address % native_flash_dev.hf_align == 0); + return flash_native_write_internal(address, src, length, 0); +} + +int +flash_native_memset(uint32_t offset, uint8_t c, uint32_t len) +{ + memset(file_loc + offset, c, len); + return 0; +} + +static int +native_flash_read(const struct hal_flash *dev, uint32_t address, void *dst, + uint32_t length) +{ + flash_native_ensure_file_open(); + memcpy(dst, (char *)file_loc + address, length); + + return 0; +} + +static int +find_area(uint32_t address) +{ + int i; + + for (i = 0; i < FLASH_NUM_AREAS; i++) { + if (native_flash_sectors[i] == address) { + return i; + } + } + + return -1; +} + +static int +flash_sector_len(int sector) +{ + uint32_t end; + + if (sector == FLASH_NUM_AREAS - 1) { + end = native_flash_dev.hf_size + native_flash_sectors[0]; + } else { + end = native_flash_sectors[sector + 1]; + } + return end - native_flash_sectors[sector]; +} + +static int +native_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address) +{ + int area_id; + uint32_t len; + + flash_native_ensure_file_open(); + + area_id = find_area(sector_address); + if (area_id == -1) { + return -1; + } + len = flash_sector_len(area_id); + flash_native_erase(sector_address, len); + return 0; +} + +static int +native_flash_sector_info(const struct hal_flash *dev, int idx, + uint32_t *address, uint32_t *size) +{ + assert(idx < FLASH_NUM_AREAS); + + *address = native_flash_sectors[idx]; + *size = flash_sector_len(idx); + return 0; +} + +static int +native_flash_init(const struct hal_flash *dev) +{ + //if (native_flash_file) { + flash_native_file_open(native_flash_file); + //} +#if MYNEWT_VAL(MCU_FLASH_STYLE_NORDIC) + int i; + + for (i = 0; i < FLASH_NUM_AREAS; i++) { + native_flash_sectors[i] = i * 2048; + } +#endif + return 0; +} diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_hw_id.c b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_hw_id.c new file mode 100644 index 0000000000..09e39801d1 --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_hw_id.c @@ -0,0 +1,73 @@ +/* + * 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. + */ + +#include +#include + +#include "hal/hal_bsp.h" + +#include "hal_native_priv.h" + +#ifndef min +#define min(a, b) ((a)<(b)?(a):(b)) +#endif + +static uint8_t hal_hw_id[HAL_BSP_MAX_ID_LEN]; +static uint8_t hal_hw_id_len; + +int +hal_bsp_hw_id_len(void) +{ + if (hal_hw_id_len != 0) { + return hal_hw_id_len; + } else { + return HAL_BSP_MAX_ID_LEN; + } +} + +/* + * This can be used as the unique hardware identifier for the platform, as + * it's supposed to be unique for this particular MCU. + */ +int +hal_bsp_hw_id(uint8_t *id, int max_len) +{ + if (hal_hw_id_len) { + if (max_len > hal_hw_id_len) { + max_len = hal_hw_id_len; + } + memcpy(id, hal_hw_id, max_len); + return max_len; + } + if (max_len > HAL_BSP_MAX_ID_LEN) { + max_len = HAL_BSP_MAX_ID_LEN; + } + memset(id, 0x42, max_len); + return max_len; +} + +void +hal_bsp_set_hw_id(const uint8_t *id, int len) +{ + if (len > HAL_BSP_MAX_ID_LEN) { + len = HAL_BSP_MAX_ID_LEN; + } + hal_hw_id_len = len; + memcpy(hal_hw_id, id, len); +} diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_native_priv.h b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_native_priv.h new file mode 100644 index 0000000000..1060053769 --- /dev/null +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_native_priv.h @@ -0,0 +1,27 @@ +/* + * 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 __HAL_NATIVE_PRIV_H__ +#define __HAL_NATIVE_PRIV_H__ + +#include + +void hal_bsp_set_hw_id(const uint8_t *id, int len); + +#endif /* __HAL_NATIVE_PRIV_H__ */ diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/syscfg.yml b/babblesim/hw/mcu/nordic/nrf52_bsim/syscfg.yml index b1bc4b874e..d6b6695904 100644 --- a/babblesim/hw/mcu/nordic/nrf52_bsim/syscfg.yml +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/syscfg.yml @@ -478,13 +478,13 @@ syscfg.defs: value: 1 MCU_FLASH_STYLE_ST: description: Emulated flash layout is similar to one in STM32. - value: 1 + value: 0 restrictions: - "!MCU_FLASH_STYLE_NORDIC" MCU_FLASH_STYLE_NORDIC: description: > Emulated flash layout is similar to one in NRF51/2 and SAMD21. - value: 0 + value: 1 restrictions: - "!MCU_FLASH_STYLE_ST" MCU_UART_POLLER_PRIO: From 883f953476645a05491a3071dd0bbb2bf34c31e9 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 16 Feb 2022 09:52:34 +0100 Subject: [PATCH 0275/1333] babblesim: Add sample targets --- babblesim/targets/blecent/pkg.yml | 23 +++++++++++++++++++++++ babblesim/targets/blecent/syscfg.yml | 20 ++++++++++++++++++++ babblesim/targets/blecent/target.yml | 21 +++++++++++++++++++++ babblesim/targets/blehci/pkg.yml | 23 +++++++++++++++++++++++ babblesim/targets/blehci/syscfg.yml | 21 +++++++++++++++++++++ babblesim/targets/blehci/target.yml | 21 +++++++++++++++++++++ babblesim/targets/bleprph/pkg.yml | 23 +++++++++++++++++++++++ babblesim/targets/bleprph/syscfg.yml | 20 ++++++++++++++++++++ babblesim/targets/bleprph/target.yml | 21 +++++++++++++++++++++ babblesim/targets/btshell/pkg.yml | 23 +++++++++++++++++++++++ babblesim/targets/btshell/syscfg.yml | 20 ++++++++++++++++++++ babblesim/targets/btshell/target.yml | 21 +++++++++++++++++++++ 12 files changed, 257 insertions(+) create mode 100644 babblesim/targets/blecent/pkg.yml create mode 100644 babblesim/targets/blecent/syscfg.yml create mode 100644 babblesim/targets/blecent/target.yml create mode 100644 babblesim/targets/blehci/pkg.yml create mode 100644 babblesim/targets/blehci/syscfg.yml create mode 100644 babblesim/targets/blehci/target.yml create mode 100644 babblesim/targets/bleprph/pkg.yml create mode 100644 babblesim/targets/bleprph/syscfg.yml create mode 100644 babblesim/targets/bleprph/target.yml create mode 100644 babblesim/targets/btshell/pkg.yml create mode 100644 babblesim/targets/btshell/syscfg.yml create mode 100644 babblesim/targets/btshell/target.yml diff --git a/babblesim/targets/blecent/pkg.yml b/babblesim/targets/blecent/pkg.yml new file mode 100644 index 0000000000..451821938c --- /dev/null +++ b/babblesim/targets/blecent/pkg.yml @@ -0,0 +1,23 @@ +# 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: babblesim/targets/blecent +pkg.type: target +pkg.descrption: Sample target for running blecent on BabbleSim +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" diff --git a/babblesim/targets/blecent/syscfg.yml b/babblesim/targets/blecent/syscfg.yml new file mode 100644 index 0000000000..eb7d46edb5 --- /dev/null +++ b/babblesim/targets/blecent/syscfg.yml @@ -0,0 +1,20 @@ +# 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. +# + +syscfg.vals: + BLE_LL_PUBLIC_DEV_ADDR: 0xbabb1e000002 diff --git a/babblesim/targets/blecent/target.yml b/babblesim/targets/blecent/target.yml new file mode 100644 index 0000000000..b4e69674a2 --- /dev/null +++ b/babblesim/targets/blecent/target.yml @@ -0,0 +1,21 @@ +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blecent" +target.bsp: "@apache-mynewt-nimble/babblesim/hw/bsp/nrf52_bsim" +target.build_profile: debug diff --git a/babblesim/targets/blehci/pkg.yml b/babblesim/targets/blehci/pkg.yml new file mode 100644 index 0000000000..c8cdf78c2d --- /dev/null +++ b/babblesim/targets/blehci/pkg.yml @@ -0,0 +1,23 @@ +# 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: babblesim/targets/blehci +pkg.type: target +pkg.descrption: Sample target for running blehci on BabbleSim +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" diff --git a/babblesim/targets/blehci/syscfg.yml b/babblesim/targets/blehci/syscfg.yml new file mode 100644 index 0000000000..aec4c4a4ab --- /dev/null +++ b/babblesim/targets/blehci/syscfg.yml @@ -0,0 +1,21 @@ +# 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. +# + +syscfg.vals: + BLE_LL_PUBLIC_DEV_ADDR: 0xbabb1e000001 + BLE_HCI_TRANSPORT: uart diff --git a/babblesim/targets/blehci/target.yml b/babblesim/targets/blehci/target.yml new file mode 100644 index 0000000000..23953eb8a1 --- /dev/null +++ b/babblesim/targets/blehci/target.yml @@ -0,0 +1,21 @@ +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-nimble/babblesim/hw/bsp/nrf52_bsim" +target.build_profile: debug diff --git a/babblesim/targets/bleprph/pkg.yml b/babblesim/targets/bleprph/pkg.yml new file mode 100644 index 0000000000..e8209bd317 --- /dev/null +++ b/babblesim/targets/bleprph/pkg.yml @@ -0,0 +1,23 @@ +# 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: babblesim/targets/bleprph +pkg.type: target +pkg.descrption: Sample target for running bleprph on BabbleSim +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" diff --git a/babblesim/targets/bleprph/syscfg.yml b/babblesim/targets/bleprph/syscfg.yml new file mode 100644 index 0000000000..279d94a2c6 --- /dev/null +++ b/babblesim/targets/bleprph/syscfg.yml @@ -0,0 +1,20 @@ +# 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. +# + +syscfg.vals: + BLE_LL_PUBLIC_DEV_ADDR: 0xbabb1e000003 diff --git a/babblesim/targets/bleprph/target.yml b/babblesim/targets/bleprph/target.yml new file mode 100644 index 0000000000..e7a0854313 --- /dev/null +++ b/babblesim/targets/bleprph/target.yml @@ -0,0 +1,21 @@ +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/bleprph" +target.bsp: "@apache-mynewt-nimble/babblesim/hw/bsp/nrf52_bsim" +target.build_profile: debug diff --git a/babblesim/targets/btshell/pkg.yml b/babblesim/targets/btshell/pkg.yml new file mode 100644 index 0000000000..cc0b4bc2ff --- /dev/null +++ b/babblesim/targets/btshell/pkg.yml @@ -0,0 +1,23 @@ +# 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: babblesim/targets/btshell +pkg.type: target +pkg.descrption: Sample target for running btshell on BabbleSim +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" diff --git a/babblesim/targets/btshell/syscfg.yml b/babblesim/targets/btshell/syscfg.yml new file mode 100644 index 0000000000..152a6652b7 --- /dev/null +++ b/babblesim/targets/btshell/syscfg.yml @@ -0,0 +1,20 @@ +# 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. +# + +syscfg.vals: + BLE_LL_PUBLIC_DEV_ADDR: 0xbabb1e000004 diff --git a/babblesim/targets/btshell/target.yml b/babblesim/targets/btshell/target.yml new file mode 100644 index 0000000000..3545e2d8c0 --- /dev/null +++ b/babblesim/targets/btshell/target.yml @@ -0,0 +1,21 @@ +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-nimble/babblesim/hw/bsp/nrf52_bsim" +target.build_profile: debug From 1084fdb1581672310eec4b936952c57fa1fd88f2 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 16 Feb 2022 11:09:12 +0100 Subject: [PATCH 0276/1333] babblesim: Add uart1 This allows to have e.g. console and ble_monitor enabled at the same time. --- babblesim/hw/bsp/nrf52_bsim/src/hal_bsp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/babblesim/hw/bsp/nrf52_bsim/src/hal_bsp.c b/babblesim/hw/bsp/nrf52_bsim/src/hal_bsp.c index 821e9ed27f..502f9a9277 100644 --- a/babblesim/hw/bsp/nrf52_bsim/src/hal_bsp.c +++ b/babblesim/hw/bsp/nrf52_bsim/src/hal_bsp.c @@ -132,6 +132,7 @@ nrf52_periph_create_timers(void) } static struct uart_dev os_bsp_uart0; +static struct uart_dev os_bsp_uart1; void hal_bsp_init(void) @@ -148,6 +149,9 @@ hal_bsp_init(void) rc = os_dev_create((struct os_dev *) &os_bsp_uart0, "uart0", OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *) NULL); assert(rc == 0); + rc = os_dev_create((struct os_dev *) &os_bsp_uart1, "uart1", + OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *) NULL); + assert(rc == 0); } void From b1b164657cbe78410da85a665b8dd7d66d5988cd Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 16 Feb 2022 11:09:44 +0100 Subject: [PATCH 0277/1333] nimble/monitor: Add support for BabbleSim --- nimble/host/src/ble_monitor.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/nimble/host/src/ble_monitor.c b/nimble/host/src/ble_monitor.c index e6db48b825..b86e7771f8 100644 --- a/nimble/host/src/ble_monitor.c +++ b/nimble/host/src/ble_monitor.c @@ -25,6 +25,11 @@ #error "Cannot enable monitor over UART and RTT at the same time!" #endif +#ifdef BABBLESIM +#define _GNU_SOURCE +#include +#endif + #include #include #include @@ -258,6 +263,7 @@ monitor_write_header(uint16_t opcode, uint16_t len) monitor_write(&ts_hdr, sizeof(ts_hdr)); } +#ifndef BABBLESIM static size_t btmon_write(FILE *instance, const char *bp, size_t n) { @@ -271,6 +277,7 @@ static FILE *btmon = (FILE *) &(struct File) { .write = btmon_write, }, }; +#endif #if MYNEWT_VAL(BLE_MONITOR_RTT) && MYNEWT_VAL(BLE_MONITOR_RTT_BUFFERED) static void @@ -436,9 +443,24 @@ ble_monitor_log(int level, const char *fmt, ...) monitor_write(&ulog, sizeof(ulog)); monitor_write(id, sizeof(id)); +#ifdef BABBLESIM + do { + char *tmp; + int len; + + va_start(va, fmt); + len = vasprintf(&tmp, fmt, va); + assert(len >= 0); + va_end(va); + + monitor_write(tmp, len); + free(tmp); + } while (0); +#else va_start(va, fmt); vfprintf(btmon, fmt, va); va_end(va); +#endif /* null-terminate string */ monitor_write("", 1); From b0c69ce9d443b2be3a6871d4d722e2292b62b051 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 16 Feb 2022 12:55:48 +0100 Subject: [PATCH 0278/1333] babblesim: Remove local libc This does not seem to be used anymore. --- babblesim/libc/LICENSE | 133 ----------------------------------- babblesim/libc/pkg.yml | 28 -------- babblesim/libc/src/strlcat.c | 30 -------- babblesim/libc/src/strlcpy.c | 26 ------- 4 files changed, 217 deletions(-) delete mode 100644 babblesim/libc/LICENSE delete mode 100644 babblesim/libc/pkg.yml delete mode 100644 babblesim/libc/src/strlcat.c delete mode 100644 babblesim/libc/src/strlcpy.c diff --git a/babblesim/libc/LICENSE b/babblesim/libc/LICENSE deleted file mode 100644 index b7915742b4..0000000000 --- a/babblesim/libc/LICENSE +++ /dev/null @@ -1,133 +0,0 @@ -Baselibc is based on klibc 1.5.23 and tinyprintf modules. -None of the GPL-licensed parts of klibc are used. - -Baselibc is licensed under the BSD license: - -Copyright (c) 2012 Petteri Aimonen -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Kustaa Nyholm or SpareTimeLabs nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The original licenses of the modules are included below: - ------------------- Tinyprintf license ------------------ - -Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Kustaa Nyholm or SpareTimeLabs nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -------------------- klibc license ------------------------- -This license applies to all files in directory and its subdirectories, -unless otherwise noted in individual files. - - -Some files are derived from files derived from the include/ directory -of the Linux kernel, and are licensed under the terms of the GNU -General Public License, version 2, as released by the Free Software -Foundation, Inc.; incorporated herein by reference. -[These files are not included in the baselibc.] - - ----- - -Some files are derived from files copyrighted by the Regents of The -University of California, and are available under the following -license: - -Note: The advertising clause in the license appearing on BSD Unix -files was officially rescinded by the Director of the Office of -Technology Licensing of the University of California on July 22 -1999. He states that clause 3 is "hereby deleted in its entirety." - - * Copyright (c) - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - -For all remaining files [of klibc], the following license applies: - - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * Any copyright notice(s) and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/babblesim/libc/pkg.yml b/babblesim/libc/pkg.yml deleted file mode 100644 index 297bfa9f8f..0000000000 --- a/babblesim/libc/pkg.yml +++ /dev/null @@ -1,28 +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. -# - -pkg.name: babblesim/libc -pkg.type: sdk -pkg.description: Functions from apache-mynewt-core/libc that not exists in Linux system. -pkg.author: "Codecoup" -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - -pkg.deps: - - "@apache-mynewt-core/kernel/os" diff --git a/babblesim/libc/src/strlcat.c b/babblesim/libc/src/strlcat.c deleted file mode 100644 index 6d95087055..0000000000 --- a/babblesim/libc/src/strlcat.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * strlcat.c - */ - -#include - -size_t strlcat(char *dst, const char *src, size_t size) -{ - size_t bytes = 0; - char *q = dst; - const char *p = src; - char ch; - - while (bytes < size && *q) { - q++; - bytes++; - } - if (bytes == size) - return (bytes + strlen(src)); - - while ((ch = *p++)) { - if (bytes + 1 < size) - *q++ = ch; - - bytes++; - } - - *q = '\0'; - return bytes; -} diff --git a/babblesim/libc/src/strlcpy.c b/babblesim/libc/src/strlcpy.c deleted file mode 100644 index 3ec8fd2dfd..0000000000 --- a/babblesim/libc/src/strlcpy.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * strlcpy.c - */ - -#include - -size_t strlcpy(char *dst, const char *src, size_t size) -{ - size_t bytes = 0; - char *q = dst; - const char *p = src; - char ch; - - while ((ch = *p++)) { - if (bytes + 1 < size) - *q++ = ch; - - bytes++; - } - - /* If size == 0 there is no space for a final null... */ - if (size) - *q = '\0'; - - return bytes; -} From 2332051c615e04a5e6e785544c61694e9976f2b7 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 15 Feb 2022 18:20:08 +0100 Subject: [PATCH 0279/1333] babblesim: Use pthreads instead of setlongjmp for tasks This changes tasks handling to native threads instead of setlongjmp() which resolves issue with calling the setlongjmp() from nested signal handlers but also simplifies code, makes debugging much easier and can work nicely with e.g. Valgrind. Each task is wrapped in a thread and all threads are synchronized on a global mutex to make sure only one task executes at any time. If context switch is requested (this is always done via os_sched() in critical section), a flag is set to indicate pending context switch which will be handled after exiting from critical setion and handling all other pending interrupts. This mimics the way it's done on a real hardware. --- babblesim/core/src/irq_handler.c | 6 - babblesim/core/src/main_config.c | 5 + .../nrf52_bsim/src/arch/bsim_arch/os_arch.c | 133 +++++--- .../src/arch/bsim_arch/os_arch_stack_frame.s | 104 ------- .../nrf52_bsim/src/arch/bsim_arch/sim_priv.h | 44 --- .../src/arch/bsim_arch/sim_sched_gen.c | 240 --------------- .../src/arch/bsim_arch/sim_sched_nosig.c | 238 --------------- .../src/arch/bsim_arch/sim_sched_sig.c | 288 ------------------ babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml | 3 + 9 files changed, 104 insertions(+), 957 deletions(-) delete mode 100644 babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch_stack_frame.s delete mode 100644 babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_priv.h delete mode 100644 babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_gen.c delete mode 100644 babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_nosig.c delete mode 100644 babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_sig.c diff --git a/babblesim/core/src/irq_handler.c b/babblesim/core/src/irq_handler.c index 805d7ecdc3..f72aaf2411 100644 --- a/babblesim/core/src/irq_handler.c +++ b/babblesim/core/src/irq_handler.c @@ -57,9 +57,6 @@ void posix_interrupt_raised(void) */ void posix_irq_handler_im_from_sw(void) { - int sr = 0; - - sr = sig_block_irq_on(); /* * if a higher priority interrupt than the possibly currently running is * pending we go immediately into irq_handler() to vector into its @@ -68,7 +65,4 @@ void posix_irq_handler_im_from_sw(void) if (hw_irq_ctrl_get_highest_prio_irq() != -1) { posix_interrupt_raised(); } - if (sr) { - sig_unblock_irq_off(); - } } diff --git a/babblesim/core/src/main_config.c b/babblesim/core/src/main_config.c index 4116e07978..ef8cb04d2e 100644 --- a/babblesim/core/src/main_config.c +++ b/babblesim/core/src/main_config.c @@ -5,6 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include "NRF_HW_model_top.h" #include "NRF_HWLowL.h" #include "bs_tracing.h" @@ -65,6 +66,10 @@ bsim_init(int argc, char** argv, int (*main_fn)(int argc, char **arg)) nrf_hw_initialize(&args->nrf_hw); os_init(main_fn); os_start(); + + while (1) { + sleep(1); + } } void diff --git a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch.c b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch.c index 6700e90a6a..8277ae7cae 100644 --- a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch.c +++ b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch.c @@ -17,72 +17,129 @@ * under the License. */ -#include "os/mynewt.h" -#include "os/sim.h" -#include "sim_priv.h" +#define _GNU_SOURCE +#include +#include +#include +#include #include -/* - * From HAL_CM4.s - */ -extern void SVC_Handler(void); -extern void PendSV_Handler(void); -extern void SysTick_Handler(void); +static pthread_mutex_t bsim_ctx_sw_mutex = PTHREAD_MUTEX_INITIALIZER; +static int bsim_pend_sv; -/* - * Assert that 'sf_mainsp' and 'sf_jb' are at the specific offsets where - * os_arch_frame_init() expects them to be. - */ -CTASSERT(offsetof(struct stack_frame, sf_mainsp) == 0); -CTASSERT(offsetof(struct stack_frame, sf_jb) == 4); +struct task_info { + pthread_t tid; + pthread_cond_t cond; + void *arg; +}; -void -os_arch_task_start(struct stack_frame *sf, int rc) +static void * +task_wrapper(void *arg) { - sim_task_start(sf, rc); + struct os_task *me = arg; + struct task_info *ti = me->t_arg; + + pthread_mutex_lock(&bsim_ctx_sw_mutex); + if (g_current_task != me) { + pthread_cond_wait(&ti->cond, &bsim_ctx_sw_mutex); + assert(g_current_task == me); + } + + me->t_func(ti->arg); + + assert(0); } os_stack_t * os_arch_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size) { - return sim_task_stack_init(t, stack_top, size); + struct task_info *ti; + int err; + + ti = calloc(1, sizeof(*ti)); + + pthread_cond_init(&ti->cond, NULL); + ti->arg = t->t_arg; + t->t_arg = ti; + + err = pthread_create(&ti->tid, NULL, task_wrapper, t); + assert(err == 0); + + pthread_setname_np(ti->tid, t->t_name); + + return stack_top; } os_error_t os_arch_os_start(void) { - return sim_os_start(); -} + struct os_task *next_t; + struct task_info *ti; -void -os_arch_os_stop(void) -{ - sim_os_stop(); -} + os_tick_init(OS_TICKS_PER_SEC, 7); -void -PendSV_Handler(void) -{ - sim_switch_tasks(); + next_t = os_sched_next_task(); + assert(next_t); + os_sched_set_current_task(next_t); + + g_os_started = 1; + + ti = next_t->t_arg; + pthread_cond_signal(&ti->cond); + + return 0; } os_error_t os_arch_os_init(void) { - NVIC_SetVector(PendSV_IRQn, (uint32_t)PendSV_Handler); - return sim_os_init(); + STAILQ_INIT(&g_os_task_list); + TAILQ_INIT(&g_os_run_list); + TAILQ_INIT(&g_os_sleep_list); + + os_init_idle_task(); + + return OS_OK; } void os_arch_ctx_sw(struct os_task *next_t) { - sim_ctx_sw(next_t); + os_sched_ctx_sw_hook(next_t); + bsim_pend_sv = 1; +} + +static void +do_ctx_sw(void) +{ + struct os_task *next_t; + struct os_task *me; + struct task_info *ti, *next_ti; + + next_t = os_sched_next_task(); + assert(next_t); + + bsim_pend_sv = 0; + + assert(g_current_task); + me = g_current_task; + ti = me->t_arg; + + if (me == next_t) { + return; + } + + g_current_task = next_t; + next_ti = g_current_task->t_arg; + + pthread_cond_signal(&next_ti->cond); + pthread_cond_wait(&ti->cond, &bsim_ctx_sw_mutex); + assert(g_current_task == me); } os_sr_t os_arch_save_sr(void) { - sim_save_sr(); return hw_irq_ctrl_change_lock(1); } @@ -90,14 +147,16 @@ void os_arch_restore_sr(os_sr_t osr) { hw_irq_ctrl_change_lock(osr); - sim_restore_sr(osr); -} + if (!osr && bsim_pend_sv) { + do_ctx_sw(); + } +} int os_arch_in_critical(void) { - return sim_in_critical(); + return hw_irq_ctrl_get_current_lock(); } void diff --git a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch_stack_frame.s b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch_stack_frame.s deleted file mode 100644 index 81e5c066ed..0000000000 --- a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch_stack_frame.s +++ /dev/null @@ -1,104 +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. - */ - -#if defined MN_LINUX -#define sigsetjmp __sigsetjmp -#define CNAME(x) x -#elif defined MN_OSX -#define sigsetjmp sigsetjmp -#define CNAME(x) _ ## x -#elif defined MN_FreeBSD -#define sigsetjmp sigsetjmp -#define CNAME(x) x -#else -#error "unsupported platform" -#endif - - .text - .code32 - .p2align 4, 0x90 /* align on 16-byte boundary and fill with NOPs */ - - .globl CNAME(os_arch_frame_init) - .globl _os_arch_frame_init - /* - * void os_arch_frame_init(struct stack_frame *sf) - */ -CNAME(os_arch_frame_init): - push %ebp /* function prologue for backtrace */ - mov %esp,%ebp - push %esi /* save %esi before using it as a tmpreg */ - - /* - * At this point we are executing on the main() stack: - * ---------------- - * stack_frame ptr 0xc(%esp) - * ---------------- - * return address 0x8(%esp) - * ---------------- - * saved ebp 0x4(%esp) - * ---------------- - * saved esi 0x0(%esp) - * ---------------- - */ - movl 0xc(%esp),%esi /* %esi = 'sf' */ - movl %esp,0x0(%esi) /* sf->mainsp = %esp */ - - /* - * Switch the stack so the stack pointer stored in 'sf->sf_jb' points - * to the task stack. This is slightly complicated because OS X wants - * the incoming stack pointer to be 16-byte aligned. - * - * ---------------- - * sf (other fields) - * ---------------- - * sf (sf_jb) 0x4(%esi) - * ---------------- - * sf (sf_mainsp) 0x0(%esi) - * ---------------- - * alignment padding variable (0 to 12 bytes) - * ---------------- - * savemask (0) 0x4(%esp) - * ---------------- - * pointer to sf_jb 0x0(%esp) - * ---------------- - */ - movl %esi,%esp - subl $0x8,%esp /* make room for sigsetjmp() arguments */ - andl $0xfffffff0,%esp /* align %esp on 16-byte boundary */ - leal 0x4(%esi),%eax /* %eax = &sf->sf_jb */ - movl %eax,0x0(%esp) - movl $0, 0x4(%esp) - call CNAME(sigsetjmp) /* sigsetjmp(sf->sf_jb, 0) */ - test %eax,%eax - jne 1f - movl 0x0(%esi),%esp /* switch back to the main() stack */ - pop %esi - pop %ebp - ret /* return to os_arch_task_stack_init() */ -1: - lea 2f,%ecx - push %ecx /* retaddr */ - push $0 /* frame pointer */ - movl %esp,%ebp /* handcrafted prologue for backtrace */ - push %eax /* rc */ - push %esi /* sf */ - call CNAME(os_arch_task_start) /* os_arch_task_start(sf, rc) */ - /* never returns */ -2: - nop diff --git a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_priv.h b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_priv.h deleted file mode 100644 index 39984dfc22..0000000000 --- a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_priv.h +++ /dev/null @@ -1,44 +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_SIM_PRIV_ -#define H_SIM_PRIV_ - -#include -#include "os/mynewt.h" -#include "mcu/mcu_sim.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define OS_USEC_PER_TICK (1000000 / OS_TICKS_PER_SEC) - -void sim_switch_tasks(void); -void sim_tick(void); -void sim_signals_init(void); -void sim_signals_cleanup(void); - -extern pid_t sim_pid; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_gen.c b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_gen.c deleted file mode 100644 index b3c192fcd7..0000000000 --- a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_gen.c +++ /dev/null @@ -1,240 +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. - */ - -/** - * This file contains code that is shared by both sim implementations (signals - * and no-signals). - */ - -#include "os/mynewt.h" - -#include - -#ifdef __APPLE__ -#define _XOPEN_SOURCE -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include "os/sim.h" -#include "sim_priv.h" - -#define sim_setjmp(__jb) sigsetjmp(__jb, 0) -#define sim_longjmp(__jb, __ret) siglongjmp(__jb, __ret) - -pid_t sim_pid; - -void -sim_switch_tasks(void) -{ - struct os_task *t, *next_t; - struct stack_frame *sf; - int rc; - - OS_ASSERT_CRITICAL(); - - t = os_sched_get_current_task(); - next_t = os_sched_next_task(); - if (t == next_t) { - /* - * Context switch not needed - just return. - */ - return; - } - - if (t) { - sf = (struct stack_frame *) t->t_stackptr; - - rc = sim_setjmp(sf->sf_jb); - if (rc != 0) { - OS_ASSERT_CRITICAL(); - return; - } - } - - os_sched_ctx_sw_hook(next_t); - - os_sched_set_current_task(next_t); - - sf = (struct stack_frame *) next_t->t_stackptr; - sim_longjmp(sf->sf_jb, 1); -} - -void -sim_tick(void) -{ - struct timeval time_now, time_diff; - int ticks; - - static struct timeval time_last; - static int time_inited; - - OS_ASSERT_CRITICAL(); - - if (!time_inited) { - gettimeofday(&time_last, NULL); - time_inited = 1; - } - - gettimeofday(&time_now, NULL); - if (timercmp(&time_now, &time_last, <)) { - /* - * System time going backwards. - */ - time_last = time_now; - } else { - timersub(&time_now, &time_last, &time_diff); - - ticks = time_diff.tv_sec * OS_TICKS_PER_SEC; - ticks += time_diff.tv_usec / OS_USEC_PER_TICK; - - /* - * Update 'time_last' but account for the remainder usecs that did not - * contribute towards whole 'ticks'. - */ - time_diff.tv_sec = 0; - time_diff.tv_usec %= OS_USEC_PER_TICK; - timersub(&time_now, &time_diff, &time_last); - - os_time_advance(ticks); - } -} - -#define OS_TICK_PRIO 7 - -static void -sim_start_timer(void) -{ - /* Intitialize and start system clock timer */ - os_tick_init(OS_TICKS_PER_SEC, OS_TICK_PRIO); -} - -static void -sim_stop_timer(void) -{ - struct itimerval it; - int rc; - - memset(&it, 0, sizeof(it)); - - rc = setitimer(ITIMER_REAL, &it, NULL); - assert(rc == 0); -} - -/* - * Called from 'os_arch_frame_init()' when setjmp returns indirectly via - * longjmp. The return value of setjmp is passed to this function as 'rc'. - */ -void -sim_task_start(struct stack_frame *sf, int rc) -{ - struct os_task *task; - - /* - * Interrupts are disabled when a task starts executing. This happens in - * two different ways: - * - via sim_os_start() for the first task. - * - via os_sched() for all other tasks. - * - * Enable interrupts before starting the task. - */ - OS_EXIT_CRITICAL(0); - - task = sf->sf_task; - task->t_func(task->t_arg); - - /* A task handler should never return. */ - assert(0); -} - -os_stack_t * -sim_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size) -{ - struct stack_frame *sf; - - sf = (struct stack_frame *) ((uint8_t *) stack_top - sizeof(*sf)); - sf->sf_task = t; - - os_arch_frame_init(sf); - - return ((os_stack_t *)sf); -} - -os_error_t -sim_os_start(void) -{ - struct stack_frame *sf; - struct os_task *t; - os_sr_t sr; - - /* - * Disable interrupts before enabling any interrupt sources. Pending - * interrupts will be recognized when the first task starts executing. - */ - OS_ENTER_CRITICAL(sr); - assert(sr == 0); - - /* Enable the interrupt sources */ - sim_start_timer(); - - t = os_sched_next_task(); - os_sched_set_current_task(t); - - g_os_started = 1; - - sf = (struct stack_frame *) t->t_stackptr; - sim_longjmp(sf->sf_jb, 1); - - return 0; -} - -/** - * Stops the tick timer and clears the "started" flag. This function is only - * implemented for sim. - */ -void -sim_os_stop(void) -{ - sim_stop_timer(); - sim_signals_cleanup(); - g_os_started = 0; -} - -os_error_t -sim_os_init(void) -{ - sim_pid = getpid(); - g_current_task = NULL; - - STAILQ_INIT(&g_os_task_list); - TAILQ_INIT(&g_os_run_list); - TAILQ_INIT(&g_os_sleep_list); - - sim_signals_init(); - - os_init_idle_task(); - - return OS_OK; -} diff --git a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_nosig.c b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_nosig.c deleted file mode 100644 index fadb712adb..0000000000 --- a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_nosig.c +++ /dev/null @@ -1,238 +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. - */ - -/** - * This file implements the "no-signals" version of sim. This implementation - * does not use signals to perform context switches. This is the less correct - * version of sim: the OS tick timer only runs while the idle task is active. - * Therefore, a sleeping high-priority task will not preempt a low-priority - * task due to a timing event (e.g., delay or callout expired). However, this - * version of sim does not suffer from the stability issues that affect the - * "signals" implementation. - * - * To use this version of sim, disable the MCU_NATIVE_USE_SIGNALS syscfg - * setting. - */ - -#include "os/mynewt.h" - -#if !MYNEWT_VAL(MCU_NATIVE_USE_SIGNALS) - -#include - -#ifdef __APPLE__ -#define _XOPEN_SOURCE -#endif - -#include -#include -#include -#include -#include -#include -#include -#include "sim_priv.h" - -static sigset_t nosigs; -static sigset_t suspsigs; /* signals delivered in sigsuspend() */ - -static int ctx_sw_pending; -static int interrupts_enabled = 1; - -void -sim_ctx_sw(struct os_task *next_t) -{ - if (interrupts_enabled) { - /* Perform the context switch immediately. */ - sim_switch_tasks(); - } else { - /* Remember that we want to perform a context switch. Perform it when - * interrupts are re-enabled. - */ - ctx_sw_pending = 1; - } -} - -/* - * Enter a critical section. - * - * Returns 1 if interrupts were already disabled; 0 otherwise. - */ -os_sr_t -sim_save_sr(void) -{ - if (!interrupts_enabled) { - return 1; - } - - interrupts_enabled = 0; - return 0; -} - -void -sim_restore_sr(os_sr_t osr) -{ - OS_ASSERT_CRITICAL(); - assert(osr == 0 || osr == 1); - - if (osr == 1) { - /* Exiting a nested critical section */ - return; - } - - if (ctx_sw_pending) { - /* A context switch was requested while interrupts were disabled. - * Perform it now that interrupts are enabled again. - */ - ctx_sw_pending = 0; - sim_switch_tasks(); - } - interrupts_enabled = 1; -} - -int -sim_in_critical(void) -{ - return !interrupts_enabled; -} - -/** - * Unblocks the SIGALRM signal that is delivered by the OS tick timer. - */ -static void -unblock_timer(void) -{ - sigset_t sigs; - int rc; - - sigemptyset(&sigs); - sigaddset(&sigs, SIGALRM); - - rc = sigprocmask(SIG_UNBLOCK, &sigs, NULL); - assert(rc == 0); -} - -/** - * Blocks the SIGALRM signal that is delivered by the OS tick timer. - */ -static void -block_timer(void) -{ - sigset_t sigs; - int rc; - - sigemptyset(&sigs); - sigaddset(&sigs, SIGALRM); - - rc = sigprocmask(SIG_BLOCK, &sigs, NULL); - assert(rc == 0); -} - -static void -sig_handler_alrm(int sig) -{ - /* Wake the idle task. */ - sigaddset(&suspsigs, sig); -} - -void -sim_tick_idle(os_time_t ticks) -{ - int rc; - struct itimerval it; - - OS_ASSERT_CRITICAL(); - - if (ticks > 0) { - /* - * Enter tickless regime and set the timer to fire after 'ticks' - * worth of time has elapsed. - */ - it.it_value.tv_sec = ticks / OS_TICKS_PER_SEC; - it.it_value.tv_usec = (ticks % OS_TICKS_PER_SEC) * OS_USEC_PER_TICK; - it.it_interval.tv_sec = 0; - it.it_interval.tv_usec = OS_USEC_PER_TICK; - rc = setitimer(ITIMER_REAL, &it, NULL); - assert(rc == 0); - } - - unblock_timer(); - - sigemptyset(&suspsigs); - sigsuspend(&nosigs); /* Wait for a signal to wake us up */ - - block_timer(); - - /* - * Call handlers for signals delivered to the process during sigsuspend(). - * The SIGALRM handler is called before any other handlers to ensure that - * OS time is always correct. - */ - if (sigismember(&suspsigs, SIGALRM)) { - sim_tick(); - } - - if (ticks > 0) { - /* - * Enable the periodic timer interrupt. - */ - it.it_value.tv_sec = 0; - it.it_value.tv_usec = OS_USEC_PER_TICK; - it.it_interval.tv_sec = 0; - it.it_interval.tv_usec = OS_USEC_PER_TICK; - rc = setitimer(ITIMER_REAL, &it, NULL); - assert(rc == 0); - } -} - -void -sim_signals_init(void) -{ - sigset_t sigset_alrm; - struct sigaction sa; - int error; - - block_timer(); - - sigemptyset(&nosigs); - - sigemptyset(&sigset_alrm); - sigaddset(&sigset_alrm, SIGALRM); - - memset(&sa, 0, sizeof sa); - sa.sa_handler = sig_handler_alrm; - sa.sa_mask = sigset_alrm; - sa.sa_flags = SA_RESTART; - error = sigaction(SIGALRM, &sa, NULL); - assert(error == 0); -} - -void -sim_signals_cleanup(void) -{ - int error; - struct sigaction sa; - - memset(&sa, 0, sizeof sa); - sa.sa_handler = SIG_DFL; - error = sigaction(SIGALRM, &sa, NULL); - assert(error == 0); -} - -#endif /* !MYNEWT_VAL(MCU_NATIVE_USE_SIGNALS) */ diff --git a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_sig.c b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_sig.c deleted file mode 100644 index c26abcea03..0000000000 --- a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/sim_sched_sig.c +++ /dev/null @@ -1,288 +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. - */ - -/** - * This file implements the "signals" version of sim. This implementation uses - * signals to perform context switches. This is the more correct version of - * sim: the OS tick timer will cause a high-priority task to preempt a - * low-priority task. Unfortunately, there are stability issues because a task - * can be preempted while it is in the middle of a system call, potentially - * causing deadlock or memory corruption. - * - * To use this version of sim, enable the MCU_NATIVE_USE_SIGNALS syscfg - * setting. - */ - -#include "os/mynewt.h" - -#if MYNEWT_VAL(MCU_NATIVE_USE_SIGNALS) - -#include "sim_priv.h" - -#include - -#ifdef __APPLE__ -#define _XOPEN_SOURCE -#endif - -#include -#include -#include -#include -#include -#include -#include - -static bool suspended; /* process is blocked in sigsuspend() */ -static sigset_t suspsigs; /* signals delivered in sigsuspend() */ -static sigset_t allsigs; -static sigset_t nosigs; - -static int in_irq; -int counter = 0; - -int -sig_block_irq_on() -{ - int error; - - counter++; - - error = sigprocmask(SIG_BLOCK, &allsigs, NULL); - - in_irq = 1; - assert(error == 0); - return 1; -} - -void -sig_unblock_irq_off() -{ - int error; - - in_irq = 0; - - if (counter > 0) { - counter--; - return; - } - - error = sigprocmask(SIG_UNBLOCK, &allsigs, NULL); - assert(error == 0); - -} - -void -sim_ctx_sw(struct os_task *next_t) -{ - /* - * gdb will stop execution of the program on most signals (e.g. SIGUSR1) - * whereas it passes SIGURG to the process without any special settings. - */ - kill(sim_pid, SIGURG); -} - -static void -ctxsw_handler(int sig) -{ - assert(in_irq==0); - OS_ASSERT_CRITICAL(); - - /* - * Just record that this handler was called when the process was blocked. - * The handler will be called after sigsuspend() returns in the correct - * order. - */ - if (suspended) { - sigaddset(&suspsigs, sig); - } else { - sim_switch_tasks(); - } -} - -/* - * Disable signals and enter a critical section. - * - * Returns 1 if signals were already blocked and 0 otherwise. - */ -os_sr_t -sim_save_sr(void) -{ - int error; - sigset_t omask; - - counter++; - - error = sigprocmask(SIG_BLOCK, &allsigs, &omask); - assert(error == 0); - - /* - * If any one of the signals in 'allsigs' is present in 'omask' then - * we are already inside a critical section. - */ - return (sigismember(&omask, SIGURG)); -} - -void -sim_restore_sr(os_sr_t osr) -{ - int error; - - OS_ASSERT_CRITICAL(); - assert(osr == 0 || osr == 1); - - if (counter > 0) { - counter--; - } - - if (osr == 1 || in_irq == 1 || counter > 0) { - /* Exiting a nested critical section */ - return; - } - - error = sigprocmask(SIG_UNBLOCK, &allsigs, NULL); - assert(error == 0); -} - -int -sim_in_critical(void) -{ - int error; - sigset_t omask; - - error = sigprocmask(SIG_SETMASK, NULL, &omask); - assert(error == 0); - - /* - * If any one of the signals in 'allsigs' is present in 'omask' then - * we are already inside a critical section. - */ - return (sigismember(&omask, SIGURG)); -} - -static struct { - int num; - void (*handler)(int sig); -} signals[] = { -// { SIGALRM, timer_handler }, - { SIGURG, ctxsw_handler }, -}; - -#define NUMSIGS (sizeof(signals)/sizeof(signals[0])) - -void -sim_tick_idle(os_time_t ticks) -{ - int i, rc, sig; - struct itimerval it; - void (*handler)(int sig); - - OS_ASSERT_CRITICAL(); - - if (ticks > 0) { - /* - * Enter tickless regime and set the timer to fire after 'ticks' - * worth of time has elapsed. - */ - it.it_value.tv_sec = ticks / OS_TICKS_PER_SEC; - it.it_value.tv_usec = (ticks % OS_TICKS_PER_SEC) * OS_USEC_PER_TICK; - it.it_interval.tv_sec = 0; - it.it_interval.tv_usec = OS_USEC_PER_TICK; - rc = setitimer(ITIMER_REAL, &it, NULL); - assert(rc == 0); - } - - suspended = true; - sigemptyset(&suspsigs); - sigsuspend(&nosigs); /* Wait for a signal to wake us up */ - suspended = false; - - /* - * Call handlers for signals delivered to the process during sigsuspend(). - * The SIGALRM handler is called before any other handlers to ensure that - * OS time is always correct. - */ - if (sigismember(&suspsigs, SIGALRM)) { - sim_tick(); - } - for (i = 0; i < NUMSIGS; i++) { - sig = signals[i].num; - handler = signals[i].handler; - if (sig != SIGALRM && sigismember(&suspsigs, sig)) { - handler(sig); - } - } - - if (ticks > 0) { - /* - * Enable the periodic timer interrupt. - */ - it.it_value.tv_sec = 0; - it.it_value.tv_usec = OS_USEC_PER_TICK; - it.it_interval.tv_sec = 0; - it.it_interval.tv_usec = OS_USEC_PER_TICK; - rc = setitimer(ITIMER_REAL, &it, NULL); - assert(rc == 0); - } -} - -void -sim_signals_init(void) -{ - int i, error; - struct sigaction sa; - - sigemptyset(&nosigs); - sigemptyset(&allsigs); - for (i = 0; i < NUMSIGS; i++) { - sigaddset(&allsigs, signals[i].num); - } - - for (i = 0; i < NUMSIGS; i++) { - memset(&sa, 0, sizeof sa); - sa.sa_handler = signals[i].handler; - sa.sa_mask = allsigs; - sa.sa_flags = SA_RESTART; - error = sigaction(signals[i].num, &sa, NULL); - assert(error == 0); - } - - /* - * We use SIGALRM as a proxy for 'allsigs' to check if we are inside - * a critical section (for e.g. see sim_in_critical()). Make sure - * that SIGALRM is indeed present in 'allsigs'. - */ -// assert(sigismember(&allsigs, SIGALRM)); -} - -void -sim_signals_cleanup(void) -{ - int i, error; - struct sigaction sa; - - for (i = 0; i < NUMSIGS; i++) { - memset(&sa, 0, sizeof sa); - sa.sa_handler = SIG_DFL; - error = sigaction(signals[i].num, &sa, NULL); - assert(error == 0); - } -} - -#endif /* MYNEWT_VAL(MCU_NATIVE_USE_SIGNALS) */ diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml b/babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml index 4f332acbab..10069a2e6b 100644 --- a/babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml @@ -22,6 +22,9 @@ pkg.description: nRF52 on BabbleSim pkg.author: "Apache Mynewt " pkg.homepage: "http://mynewt.apache.org/" +pkg.lflags: + - -lpthread + pkg.deps: - "babblesim/nrfx" From a63418cc12ce97780a3f4792aaeb5bec02d3dd45 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 17 Feb 2022 07:02:44 +0100 Subject: [PATCH 0280/1333] babblesim: Rework sdk package This moves all external components to separate sdk package. We'll link both bsim components and nrfx there and setup include paths. --- babblesim/.gitignore | 3 -- babblesim/core/pkg.yml | 9 +---- babblesim/hw/bsp/nrf52_bsim/pkg.yml | 6 +-- babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml | 2 +- babblesim/nrfx/pkg.yml | 37 ------------------- babblesim/sdk/.gitignore | 3 ++ babblesim/{hw/babblesim => sdk}/pkg.yml | 33 +++++++++-------- .../scripts/link_babblesim.sh} | 30 ++------------- babblesim/{nrfx => sdk}/scripts/link_nrfx.sh | 5 +-- 9 files changed, 32 insertions(+), 96 deletions(-) delete mode 100644 babblesim/.gitignore delete mode 100644 babblesim/nrfx/pkg.yml create mode 100644 babblesim/sdk/.gitignore rename babblesim/{hw/babblesim => sdk}/pkg.yml (74%) rename babblesim/{hw/babblesim/scripts/pre_build1.sh => sdk/scripts/link_babblesim.sh} (70%) rename babblesim/{nrfx => sdk}/scripts/link_nrfx.sh (89%) diff --git a/babblesim/.gitignore b/babblesim/.gitignore deleted file mode 100644 index 78e34f10a1..0000000000 --- a/babblesim/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -hw/babblesim/components -hw/babblesim/src -nrfx/src \ No newline at end of file diff --git a/babblesim/core/pkg.yml b/babblesim/core/pkg.yml index 3b0c2e9a67..1a1ec76629 100644 --- a/babblesim/core/pkg.yml +++ b/babblesim/core/pkg.yml @@ -18,20 +18,15 @@ # pkg.name: babblesim/core -pkg.type: sdk pkg.description: time machine, irq handeler, core pkg.author: "Apache Mynewt " pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: pkg.deps: - - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-nimble/nimble/controller" - - "@apache-mynewt-nimble/nimble/transport" - - "babblesim/hw/babblesim" + - "babblesim/sdk" -pkg.req_apis: - - ble_transport +pkg.cflags: -std=gnu99 pkg.init: bsim_start: 9999 diff --git a/babblesim/hw/bsp/nrf52_bsim/pkg.yml b/babblesim/hw/bsp/nrf52_bsim/pkg.yml index 6662a76dd3..e22e767452 100644 --- a/babblesim/hw/bsp/nrf52_bsim/pkg.yml +++ b/babblesim/hw/bsp/nrf52_bsim/pkg.yml @@ -31,7 +31,7 @@ pkg.cflags.HARDFLOAT: - -mfloat-abi=hard -mfpu=fpv4-sp-d16 pkg.deps: - - "@apache-mynewt-core/hw/drivers/uart/uart_hal" - - "babblesim/hw/mcu/nordic/nrf52_bsim" - - "babblesim/hw/babblesim" - "babblesim/core" + - "babblesim/hw/mcu/nordic/nrf52_bsim" + - "@apache-mynewt-core/hw/drivers/uart/uart_hal" + - "@apache-mynewt-nimble/nimble/controller" diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml b/babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml index 10069a2e6b..99e59a26c1 100644 --- a/babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml @@ -26,7 +26,7 @@ pkg.lflags: - -lpthread pkg.deps: - - "babblesim/nrfx" + - "babblesim/core" pkg.deps.BLE_CONTROLLER: - "@apache-mynewt-nimble/nimble/drivers/nrf52" diff --git a/babblesim/nrfx/pkg.yml b/babblesim/nrfx/pkg.yml deleted file mode 100644 index 54a385e2c6..0000000000 --- a/babblesim/nrfx/pkg.yml +++ /dev/null @@ -1,37 +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. -# - -pkg.name: babblesim/nrfx -pkg.description: nrfx wrapper for BabbleSim -pkg.author: "Apache Mynewt " -pkg.homepage: "https://mynewt.apache.org/" -pkg.type: sdk - -pkg.cflags: -std=gnu99 -pkg.include_dirs: - - src/ - - src/drivers/ - - src/hal/ - - src/mdk/ - -pkg.deps: - - "@apache-mynewt-core/hw/hal" - -pkg.pre_build_cmds: - scripts/link_nrfx.sh: 1 diff --git a/babblesim/sdk/.gitignore b/babblesim/sdk/.gitignore new file mode 100644 index 0000000000..b269fe6291 --- /dev/null +++ b/babblesim/sdk/.gitignore @@ -0,0 +1,3 @@ +components +nrfx +src \ No newline at end of file diff --git a/babblesim/hw/babblesim/pkg.yml b/babblesim/sdk/pkg.yml similarity index 74% rename from babblesim/hw/babblesim/pkg.yml rename to babblesim/sdk/pkg.yml index ad28efbcb2..a542a3044e 100644 --- a/babblesim/hw/babblesim/pkg.yml +++ b/babblesim/sdk/pkg.yml @@ -17,28 +17,31 @@ # under the License. # -pkg.name: babblesim/hw/babblesim -pkg.description: BabbleSim stuff +pkg.name: babblesim/sdk +pkg.type: sdk +pkg.description: External files required to build BabbleSim pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" +pkg.homepage: "https://mynewt.apache.org/" -pkg.type: sdk +pkg.cflags: -std=gnu99 pkg.include_dirs: - - components/ext_NRF52_hw_models/src/nrfx/mdk_replacements - - components/ext_NRF52_hw_models/src/HW_models - components/ext_NRF52_hw_models/src/nrfx_config - components/ext_NRF52_hw_models/src/nrfx/nrfx_replacements - - components/libUtilv1/src/ - - components/libPhyComv1/src/ - - components/libRandv2/src/ - - components/ext_libCryptov1/src/ - -pkg.src_dirs: - - src + - components/ext_NRF52_hw_models/src/nrfx/mdk_replacements + - components/ext_NRF52_hw_models/src/HW_models + - components/libUtilv1/src + - components/libPhyComv1/src + - components/libRandv2/src + - components/ext_libCryptov1/src + - nrfx + - nrfx/drivers + - nrfx/hal + - nrfx/mdk pkg.pre_build_cmds: - scripts/pre_build1.sh: 1 + scripts/link_babblesim.sh: 1 + scripts/link_nrfx.sh: 2 pkg.lflags: - - -ldl \ No newline at end of file + - -ldl diff --git a/babblesim/hw/babblesim/scripts/pre_build1.sh b/babblesim/sdk/scripts/link_babblesim.sh similarity index 70% rename from babblesim/hw/babblesim/scripts/pre_build1.sh rename to babblesim/sdk/scripts/link_babblesim.sh index 3f3fec5add..9254a18a72 100755 --- a/babblesim/hw/babblesim/scripts/pre_build1.sh +++ b/babblesim/sdk/scripts/link_babblesim.sh @@ -34,36 +34,14 @@ if [ -z ${BSIM_OUT_PATH+x} ]; then exit 1 fi -if [[ -d "$(pwd)/components" ]] -then - echo "Babblesim components: Directory exists. Removing and linking again..." - rm -r $(pwd)/components -else - echo "Babblesim components: Linking components..." -fi - -ln -nsf $BSIM_OUT_PATH/components - -if [[ -d "$(pwd)/src" ]] -then - echo "Babblesim libraries src: Directory exists. Removing and linking again..." - rm -r $(pwd)/src -else - echo "Babblesim components: Linking components..." -fi - -mkdir -p src -ln -nsf $BSIM_OUT_PATH/components - -# Create links to all .32.a files -# find $BSIM_OUT_PATH/lib/$lib -name "*.32.a" -type f -exec ln -t src -nsf {} \; +ln -sfn "${BSIM_COMPONENTS_PATH}" ./components -# Copy all .32.a files -find $BSIM_OUT_PATH/lib/$lib -name "*.32.a" -type f -exec cp -t src -f {} \; +mkdir -p ./src/ +cp "${BSIM_OUT_PATH}"/lib/*.32.a ./src/ # XXX: Workaround for bad linking by newt. Sometimes newt will link # nrf weak functions from nrf_hal_originals.o instead of their BabbleSim # replacements inside libNRF52_hw_models.32.a. But as long as the other # weak functions, that do not have their replacements, are not used, # we can just remove the file from the .a library here. -ar d src/libNRF52_hw_models.32.a nrf_hal_originals.o +ar d ./src/libNRF52_hw_models.32.a nrf_hal_originals.o diff --git a/babblesim/nrfx/scripts/link_nrfx.sh b/babblesim/sdk/scripts/link_nrfx.sh similarity index 89% rename from babblesim/nrfx/scripts/link_nrfx.sh rename to babblesim/sdk/scripts/link_nrfx.sh index 2b59847eb0..6bc894e29c 100755 --- a/babblesim/nrfx/scripts/link_nrfx.sh +++ b/babblesim/sdk/scripts/link_nrfx.sh @@ -18,7 +18,4 @@ # under the License. # -mkdir -p ./src/ -for f in nrfx.h drivers hal mdk; do - ln -sfn ${NRFX_BASE}/${f} ./src/${f} -done \ No newline at end of file +ln -sfn ${NRFX_BASE} ./nrfx From eb5d27899d90072515066123329118c1553ac657 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 17 Feb 2022 15:26:50 +0100 Subject: [PATCH 0281/1333] nimble/ll: Fix scan proc handling Fall-through for ll_state was not handled properly after some changes and this means scan proc could disable phy mid-event. --- nimble/controller/src/ble_ll_scan.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index f96aae6ba8..b04138d1e3 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1093,17 +1093,23 @@ ble_ll_scan_event_proc(struct ble_npl_event *ev) switch (ble_ll_state_get()) { #if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) case BLE_LL_STATE_ADV: + start_scan = false; + break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_STATE_CONNECTION: + start_scan = false; + break; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) case BLE_LL_STATE_SYNC: + start_scan = false; + break; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) case BLE_LL_STATE_SCAN_AUX: - start_scan = false; - break; + start_scan = false; + break; #endif case BLE_LL_STATE_SCANNING: /* Must disable PHY since we will move to a new channel */ From f3e4de75f20d7ebad683c20747e627be76335030 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Thu, 17 Feb 2022 14:38:46 +0100 Subject: [PATCH 0282/1333] apps/blehci: Allow full console So far blehci always used console/stub. For debugging purpose it may be useful to enable console without modifying blehci application pkg.deps. mynewt-core package sys/console provides a easy way to select one of the console implementations via syscfg value. Default console variant is still stub so there is no change in functionality unless target is updated with other console variant --- apps/blehci/pkg.yml | 2 +- apps/blehci/syscfg.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/blehci/pkg.yml b/apps/blehci/pkg.yml index 06e6189468..2c63a04911 100644 --- a/apps/blehci/pkg.yml +++ b/apps/blehci/pkg.yml @@ -23,7 +23,7 @@ pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: pkg.deps: - - "@apache-mynewt-core/sys/console/stub" + - "@apache-mynewt-core/sys/console" - "@apache-mynewt-core/sys/log/stub" - "@apache-mynewt-core/sys/stats/full" - "@apache-mynewt-core/kernel/os" diff --git a/apps/blehci/syscfg.yml b/apps/blehci/syscfg.yml index 48a02005ac..ee806237f6 100644 --- a/apps/blehci/syscfg.yml +++ b/apps/blehci/syscfg.yml @@ -21,3 +21,5 @@ syscfg.vals: OS_MAIN_STACK_SIZE: 64 # Use UART transport by default BLE_HCI_TRANSPORT: uart + # Stub console + CONSOLE_MODE: stub From e58e71271bcf62b3648c010bafd4c2afcb4f3495 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Fri, 18 Feb 2022 09:02:20 +0100 Subject: [PATCH 0283/1333] apps/blehcibridge: Update console selection methode CONSOLE_MODE syscfg value is now present in mynewt-core package sys/console. Now blehcibridge uses this way to select console instead of private one. Variable name stayed the same so there is no need to update targets. --- apps/blehcibridge/pkg.yml | 8 +------- apps/blehcibridge/syscfg.yml | 11 ++--------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/apps/blehcibridge/pkg.yml b/apps/blehcibridge/pkg.yml index 9d170a89f3..5acd2e7b0a 100644 --- a/apps/blehcibridge/pkg.yml +++ b/apps/blehcibridge/pkg.yml @@ -23,6 +23,7 @@ pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: pkg.deps: + - "@apache-mynewt-core/sys/console" - "@apache-mynewt-core/sys/log/stub" - "@apache-mynewt-core/sys/stats/full" - "@apache-mynewt-core/kernel/os" @@ -31,10 +32,3 @@ pkg.deps: pkg.req_apis: - ble_transport - -pkg.deps.'CONSOLE_MODE=="full"': - - "@apache-mynewt-core/sys/console/full" -pkg.deps.'CONSOLE_MODE=="minimal": - - "@apache-mynewt-core/sys/console/minimal" -pkg.deps.'CONSOLE_MODE=="stub": - - "@apache-mynewt-core/sys/console/stub" diff --git a/apps/blehcibridge/syscfg.yml b/apps/blehcibridge/syscfg.yml index 146ab52642..203ec25df5 100644 --- a/apps/blehcibridge/syscfg.yml +++ b/apps/blehcibridge/syscfg.yml @@ -16,20 +16,13 @@ # under the License. # -syscfg.defs: - CONSOLE_MODE: - description: Which console to use - value: stub - choices: - - full - - minimal - - stub - syscfg.vals: # Default task settings OS_MAIN_STACK_SIZE: 64 # Use USB transport by default BLE_HCI_TRANSPORT: usb + # Stub console + CONSOLE_MODE: stub SHELL_TASK: 1 From fd3b1466d71d18908ad870a1982516e812747fd8 Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Mon, 6 Dec 2021 10:47:19 +0100 Subject: [PATCH 0284/1333] bsim: Add EDTT hci test app adopted from Zephyr. --- babblesim/edtt/hci_test/pkg.yml | 32 + babblesim/edtt/hci_test/src/main.c | 45 + babblesim/edtt/hci_test/syscfg.yml | 30 + .../edtt/hci_transport/include/ble_hci_edtt.h | 35 + .../edtt/hci_transport/include/commands.h | 242 ++++ .../edtt/hci_transport/include/edtt_driver.h | 38 + babblesim/edtt/hci_transport/pkg.yml | 35 + .../edtt/hci_transport/src/ble_hci_edtt.c | 1149 +++++++++++++++++ .../edtt/hci_transport/src/edtt_driver_bsim.c | 286 ++++ babblesim/edtt/hci_transport/syscfg.yml | 49 + babblesim/hw/bsp/nrf52_bsim/syscfg.yml | 2 +- babblesim/targets/edtthci/pkg.yml | 24 + babblesim/targets/edtthci/syscfg.yml | 55 + babblesim/targets/edtthci/target.yml | 22 + 14 files changed, 2043 insertions(+), 1 deletion(-) create mode 100644 babblesim/edtt/hci_test/pkg.yml create mode 100644 babblesim/edtt/hci_test/src/main.c create mode 100644 babblesim/edtt/hci_test/syscfg.yml create mode 100644 babblesim/edtt/hci_transport/include/ble_hci_edtt.h create mode 100644 babblesim/edtt/hci_transport/include/commands.h create mode 100644 babblesim/edtt/hci_transport/include/edtt_driver.h create mode 100644 babblesim/edtt/hci_transport/pkg.yml create mode 100644 babblesim/edtt/hci_transport/src/ble_hci_edtt.c create mode 100644 babblesim/edtt/hci_transport/src/edtt_driver_bsim.c create mode 100644 babblesim/edtt/hci_transport/syscfg.yml create mode 100644 babblesim/targets/edtthci/pkg.yml create mode 100644 babblesim/targets/edtthci/syscfg.yml create mode 100644 babblesim/targets/edtthci/target.yml diff --git a/babblesim/edtt/hci_test/pkg.yml b/babblesim/edtt/hci_test/pkg.yml new file mode 100644 index 0000000000..6f1dd4bbbe --- /dev/null +++ b/babblesim/edtt/hci_test/pkg.yml @@ -0,0 +1,32 @@ +# +# 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: babblesim/edtt/hci_test +pkg.type: app +pkg.description: nRF52 on BabbleSim - EDTT tester +pkg.author: "Codecoup" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - "@apache-mynewt-core/sys/console/stub" + - "@apache-mynewt-core/sys/log/stub" + - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/kernel/os" + - nimble/transport + - babblesim/edtt/hci_transport diff --git a/babblesim/edtt/hci_test/src/main.c b/babblesim/edtt/hci_test/src/main.c new file mode 100644 index 0000000000..0ca152cfc2 --- /dev/null +++ b/babblesim/edtt/hci_test/src/main.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 Codecoup + * + * 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. + */ + +#include "os/mynewt.h" +#include "ble_hci_edtt.h" + +static int +main_fn(int argc, char **argv) +{ + sysinit(); + + edtt_init(); + + while (1) { + os_eventq_run(os_eventq_dflt_get()); + } + return 0; +} + +int +main(int argc, char **argv) +{ + extern void bsim_init(int argc, char** argv, void *main_fn); + bsim_init(argc, argv, main_fn); + + return 0; +} diff --git a/babblesim/edtt/hci_test/syscfg.yml b/babblesim/edtt/hci_test/syscfg.yml new file mode 100644 index 0000000000..bdf21e78d2 --- /dev/null +++ b/babblesim/edtt/hci_test/syscfg.yml @@ -0,0 +1,30 @@ +# +# 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. +# + +syscfg.vals: + BLE_HOST: 0 + BLE_HCI_TRANSPORT: custom + + # EDTT requires 0x123456789ABC address for first device + # and 0x456789ABCDEF for second + BLE_LL_PUBLIC_DEV_ADDR: 0x123456789ABC +# BLE_LL_PUBLIC_DEV_ADDR: 0x456789ABCDEF + + # For LL/CON/ADV/BV-09-C, LL/CON/ADV/BV-10-C + BLE_LL_CFG_FEAT_LE_CSA2: 1 diff --git a/babblesim/edtt/hci_transport/include/ble_hci_edtt.h b/babblesim/edtt/hci_transport/include/ble_hci_edtt.h new file mode 100644 index 0000000000..d590b11d0b --- /dev/null +++ b/babblesim/edtt/hci_transport/include/ble_hci_edtt.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Codecoup + * + * 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_BLE_HCI_EDTT_ +#define H_BLE_HCI_EDTT_ + +#ifdef __cplusplus +extern "C" { +#endif + +int edtt_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/babblesim/edtt/hci_transport/include/commands.h b/babblesim/edtt/hci_transport/include/commands.h new file mode 100644 index 0000000000..d0f8cce2a9 --- /dev/null +++ b/babblesim/edtt/hci_transport/include/commands.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2019 Oticon A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef EDDT_APP_COMMANDS_H +#define EDDT_APP_COMMANDS_H + +enum commands_t { + CMD_NOTHING = 0, + CMD_ECHO_REQ, + CMD_ECHO_RSP, + CMD_INQUIRE_REQ, + CMD_INQUIRE_RSP, + CMD_DISCONNECT_REQ, + CMD_DISCONNECT_RSP, + CMD_READ_REMOTE_VERSION_INFORMATION_REQ, + CMD_READ_REMOTE_VERSION_INFORMATION_RSP, + CMD_SET_EVENT_MASK_REQ, + CMD_SET_EVENT_MASK_RSP, + CMD_RESET_REQ, + CMD_RESET_RSP, + CMD_READ_TRANSMIT_POWER_LEVEL_REQ, + CMD_READ_TRANSMIT_POWER_LEVEL_RSP, + CMD_SET_CONTROLLER_TO_HOST_FLOW_CONTROL_REQ, + CMD_SET_CONTROLLER_TO_HOST_FLOW_CONTROL_RSP, + CMD_HOST_BUFFER_SIZE_REQ, + CMD_HOST_BUFFER_SIZE_RSP, + CMD_HOST_NUMBER_OF_COMPLETED_PACKETS_REQ, + CMD_HOST_NUMBER_OF_COMPLETED_PACKETS_RSP, + CMD_SET_EVENT_MASK_PAGE_2_REQ, + CMD_SET_EVENT_MASK_PAGE_2_RSP, + CMD_WRITE_LE_HOST_SUPPORT_REQ, + CMD_WRITE_LE_HOST_SUPPORT_RSP, + CMD_READ_AUTHENTICATED_PAYLOAD_TIMEOUT_REQ, + CMD_READ_AUTHENTICATED_PAYLOAD_TIMEOUT_RSP, + CMD_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_REQ, + CMD_WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT_RSP, + CMD_READ_LOCAL_VERSION_INFORMATION_REQ, + CMD_READ_LOCAL_VERSION_INFORMATION_RSP, + CMD_READ_LOCAL_SUPPORTED_COMMANDS_REQ, + CMD_READ_LOCAL_SUPPORTED_COMMANDS_RSP, + CMD_READ_LOCAL_SUPPORTED_FEATURES_REQ, + CMD_READ_LOCAL_SUPPORTED_FEATURES_RSP, + CMD_READ_BUFFER_SIZE_REQ, + CMD_READ_BUFFER_SIZE_RSP, + CMD_READ_BD_ADDR_REQ, + CMD_READ_BD_ADDR_RSP, + CMD_READ_RSSI_REQ, + CMD_READ_RSSI_RSP, + CMD_LE_SET_EVENT_MASK_REQ, + CMD_LE_SET_EVENT_MASK_RSP, + CMD_LE_READ_BUFFER_SIZE_REQ, + CMD_LE_READ_BUFFER_SIZE_RSP, + CMD_LE_READ_LOCAL_SUPPORTED_FEATURES_REQ, + CMD_LE_READ_LOCAL_SUPPORTED_FEATURES_RSP, + CMD_LE_SET_RANDOM_ADDRESS_REQ, + CMD_LE_SET_RANDOM_ADDRESS_RSP, + CMD_LE_SET_ADVERTISING_PARAMETERS_REQ, + CMD_LE_SET_ADVERTISING_PARAMETERS_RSP, + CMD_LE_READ_ADVERTISING_CHANNEL_TX_POWER_REQ, + CMD_LE_READ_ADVERTISING_CHANNEL_TX_POWER_RSP, + CMD_LE_SET_ADVERTISING_DATA_REQ, + CMD_LE_SET_ADVERTISING_DATA_RSP, + CMD_LE_SET_SCAN_RESPONSE_DATA_REQ, + CMD_LE_SET_SCAN_RESPONSE_DATA_RSP, + CMD_LE_SET_ADVERTISING_ENABLE_REQ, + CMD_LE_SET_ADVERTISING_ENABLE_RSP, + CMD_LE_SET_SCAN_PARAMETERS_REQ, + CMD_LE_SET_SCAN_PARAMETERS_RSP, + CMD_LE_SET_SCAN_ENABLE_REQ, + CMD_LE_SET_SCAN_ENABLE_RSP, + CMD_LE_CREATE_CONNECTION_REQ, + CMD_LE_CREATE_CONNECTION_RSP, + CMD_LE_CREATE_CONNECTION_CANCEL_REQ, + CMD_LE_CREATE_CONNECTION_CANCEL_RSP, + CMD_LE_READ_FILTER_ACCEPT_LIST_SIZE_REQ, + CMD_LE_READ_FILTER_ACCEPT_LIST_SIZE_RSP, + CMD_LE_CLEAR_FILTER_ACCEPT_LIST_REQ, + CMD_LE_CLEAR_FILTER_ACCEPT_LIST_RSP, + CMD_LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST_REQ, + CMD_LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST_RSP, + CMD_LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST_REQ, + CMD_LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST_RSP, + CMD_LE_CONNECTION_UPDATE_REQ, + CMD_LE_CONNECTION_UPDATE_RSP, + CMD_LE_SET_HOST_CHANNEL_CLASSIFICATION_REQ, + CMD_LE_SET_HOST_CHANNEL_CLASSIFICATION_RSP, + CMD_LE_READ_CHANNEL_MAP_REQ, + CMD_LE_READ_CHANNEL_MAP_RSP, + CMD_LE_READ_REMOTE_FEATURES_REQ, + CMD_LE_READ_REMOTE_FEATURES_RSP, + CMD_LE_ENCRYPT_REQ, + CMD_LE_ENCRYPT_RSP, + CMD_LE_RAND_REQ, + CMD_LE_RAND_RSP, + CMD_LE_START_ENCRYPTION_REQ, + CMD_LE_START_ENCRYPTION_RSP, + CMD_LE_LONG_TERM_KEY_REQUEST_REPLY_REQ, + CMD_LE_LONG_TERM_KEY_REQUEST_REPLY_RSP, + CMD_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_REQ, + CMD_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_RSP, + CMD_LE_READ_SUPPORTED_STATES_REQ, + CMD_LE_READ_SUPPORTED_STATES_RSP, + CMD_LE_RECEIVER_TEST_REQ, + CMD_LE_RECEIVER_TEST_RSP, + CMD_LE_TRANSMITTER_TEST_REQ, + CMD_LE_TRANSMITTER_TEST_RSP, + CMD_LE_TEST_END_REQ, + CMD_LE_TEST_END_RSP, + CMD_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_REQ, + CMD_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY_RSP, + CMD_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_REQ, + CMD_LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY_RSP, + CMD_LE_SET_DATA_LENGTH_REQ, + CMD_LE_SET_DATA_LENGTH_RSP, + CMD_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_REQ, + CMD_LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH_RSP, + CMD_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_REQ, + CMD_LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH_RSP, + CMD_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND_REQ, + CMD_LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND_RSP, + CMD_LE_GENERATE_DHKEY_COMMAND_REQ, + CMD_LE_GENERATE_DHKEY_COMMAND_RSP, + CMD_LE_ADD_DEVICE_TO_RESOLVING_LIST_REQ, + CMD_LE_ADD_DEVICE_TO_RESOLVING_LIST_RSP, + CMD_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_REQ, + CMD_LE_REMOVE_DEVICE_FROM_RESOLVING_LIST_RSP, + CMD_LE_CLEAR_RESOLVING_LIST_REQ, + CMD_LE_CLEAR_RESOLVING_LIST_RSP, + CMD_LE_READ_RESOLVING_LIST_SIZE_REQ, + CMD_LE_READ_RESOLVING_LIST_SIZE_RSP, + CMD_LE_READ_PEER_RESOLVABLE_ADDRESS_REQ, + CMD_LE_READ_PEER_RESOLVABLE_ADDRESS_RSP, + CMD_LE_READ_LOCAL_RESOLVABLE_ADDRESS_REQ, + CMD_LE_READ_LOCAL_RESOLVABLE_ADDRESS_RSP, + CMD_LE_SET_ADDRESS_RESOLUTION_ENABLE_REQ, + CMD_LE_SET_ADDRESS_RESOLUTION_ENABLE_RSP, + CMD_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_REQ, + CMD_LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT_RSP, + CMD_LE_READ_MAXIMUM_DATA_LENGTH_REQ, + CMD_LE_READ_MAXIMUM_DATA_LENGTH_RSP, + CMD_LE_READ_PHY_REQ, + CMD_LE_READ_PHY_RSP, + CMD_LE_SET_DEFAULT_PHY_REQ, + CMD_LE_SET_DEFAULT_PHY_RSP, + CMD_LE_SET_PHY_REQ, + CMD_LE_SET_PHY_RSP, + CMD_LE_ENHANCED_RECEIVER_TEST_REQ, + CMD_LE_ENHANCED_RECEIVER_TEST_RSP, + CMD_LE_ENHANCED_TRANSMITTER_TEST_REQ, + CMD_LE_ENHANCED_TRANSMITTER_TEST_RSP, + CMD_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_REQ, + CMD_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_RSP, + CMD_LE_SET_EXTENDED_ADVERTISING_DATA_REQ, + CMD_LE_SET_EXTENDED_ADVERTISING_DATA_RSP, + CMD_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_REQ, + CMD_LE_SET_EXTENDED_SCAN_RESPONSE_DATA_RSP, + CMD_LE_SET_EXTENDED_ADVERTISING_ENABLE_REQ, + CMD_LE_SET_EXTENDED_ADVERTISING_ENABLE_RSP, + CMD_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_REQ, + CMD_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH_RSP, + CMD_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_REQ, + CMD_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS_RSP, + CMD_LE_REMOVE_ADVERTISING_SET_REQ, + CMD_LE_REMOVE_ADVERTISING_SET_RSP, + CMD_LE_CLEAR_ADVERTISING_SETS_REQ, + CMD_LE_CLEAR_ADVERTISING_SETS_RSP, + CMD_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_REQ, + CMD_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_RSP, + CMD_LE_SET_PERIODIC_ADVERTISING_DATA_REQ, + CMD_LE_SET_PERIODIC_ADVERTISING_DATA_RSP, + CMD_LE_SET_PERIODIC_ADVERTISING_ENABLE_REQ, + CMD_LE_SET_PERIODIC_ADVERTISING_ENABLE_RSP, + CMD_LE_SET_EXTENDED_SCAN_PARAMETERS_REQ, + CMD_LE_SET_EXTENDED_SCAN_PARAMETERS_RSP, + CMD_LE_SET_EXTENDED_SCAN_ENABLE_REQ, + CMD_LE_SET_EXTENDED_SCAN_ENABLE_RSP, + CMD_LE_EXTENDED_CREATE_CONNECTION_REQ, + CMD_LE_EXTENDED_CREATE_CONNECTION_RSP, + CMD_LE_PERIODIC_ADVERTISING_CREATE_SYNC_REQ, + CMD_LE_PERIODIC_ADVERTISING_CREATE_SYNC_RSP, + CMD_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_REQ, + CMD_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL_RSP, + CMD_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_REQ, + CMD_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC_RSP, + CMD_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_REQ, + CMD_LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST_RSP, + CMD_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_REQ, + CMD_LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST_RSP, + CMD_LE_CLEAR_PERIODIC_ADVERTISER_LIST_REQ, + CMD_LE_CLEAR_PERIODIC_ADVERTISER_LIST_RSP, + CMD_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_REQ, + CMD_LE_READ_PERIODIC_ADVERTISER_LIST_SIZE_RSP, + CMD_LE_READ_TRANSMIT_POWER_REQ, + CMD_LE_READ_TRANSMIT_POWER_RSP, + CMD_LE_READ_RF_PATH_COMPENSATION_REQ, + CMD_LE_READ_RF_PATH_COMPENSATION_RSP, + CMD_LE_WRITE_RF_PATH_COMPENSATION_REQ, + CMD_LE_WRITE_RF_PATH_COMPENSATION_RSP, + CMD_LE_SET_PRIVACY_MODE_REQ, + CMD_LE_SET_PRIVACY_MODE_RSP, + CMD_WRITE_BD_ADDR_REQ, + CMD_WRITE_BD_ADDR_RSP, + CMD_FLUSH_EVENTS_REQ, + CMD_FLUSH_EVENTS_RSP, + CMD_HAS_EVENT_REQ, + CMD_HAS_EVENT_RSP, + CMD_GET_EVENT_REQ, + CMD_GET_EVENT_RSP, + CMD_LE_FLUSH_DATA_REQ, + CMD_LE_FLUSH_DATA_RSP, + CMD_LE_DATA_READY_REQ, + CMD_LE_DATA_READY_RSP, + CMD_LE_DATA_WRITE_REQ, + CMD_LE_DATA_WRITE_RSP, + CMD_LE_DATA_READ_REQ, + CMD_LE_DATA_READ_RSP, + CMD_GATT_SERVICE_SET_REQ, + CMD_GATT_SERVICE_SET_RSP, + CMD_GATT_SERVICE_NOTIFY_REQ, + CMD_GATT_SERVICE_NOTIFY_RSP, + CMD_GATT_SERVICE_INDICATE_REQ, + CMD_GATT_SERVICE_INDICATE_RSP, + CMD_GAP_ADVERTISING_MODE_REQ, + CMD_GAP_ADVERTISING_MODE_RSP, + CMD_GAP_ADVERTISING_DATA_REQ, + CMD_GAP_ADVERTISING_DATA_RSP, + CMD_GAP_SCANNING_MODE_REQ, + CMD_GAP_SCANNING_MODE_RSP, + CMD_READ_STATIC_ADDRESSES_REQ, + CMD_READ_STATIC_ADDRESSES_RSP, + CMD_READ_KEY_HIERARCHY_ROOTS_REQ, + CMD_READ_KEY_HIERARCHY_ROOTS_RSP, + CMD_GAP_READ_IRK_REQ, + CMD_GAP_READ_IRK_RSP, + CMD_GAP_ROLE_REQ, + CMD_GAP_ROLE_RSP +}; + +#endif /* EDDT_APP_COMMANDS_H */ diff --git a/babblesim/edtt/hci_transport/include/edtt_driver.h b/babblesim/edtt/hci_transport/include/edtt_driver.h new file mode 100644 index 0000000000..3b7d253346 --- /dev/null +++ b/babblesim/edtt/hci_transport/include/edtt_driver.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019 Oticon A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef EDTT_DRIVER_H +#define EDTT_DRIVER_H + +#include +#include + +#define EDTTT_NONBLOCK 0 +#define EDTTT_BLOCK 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Generic EDTT interface + */ +bool edtt_start(void); +bool edtt_stop(void); +int edtt_read(uint8_t *ptr, size_t size, int flags); +int edtt_write(uint8_t *ptr, size_t size, int flags); + +/** + * Exclusive functions for the BabbleSim driver + */ +void enable_edtt_mode(void); +void set_edtt_autoshutdown(bool mode); + +#ifdef __cplusplus +} +#endif + +#endif /* EDTT_DRIVER_H */ diff --git a/babblesim/edtt/hci_transport/pkg.yml b/babblesim/edtt/hci_transport/pkg.yml new file mode 100644 index 0000000000..8e1dd9f25e --- /dev/null +++ b/babblesim/edtt/hci_transport/pkg.yml @@ -0,0 +1,35 @@ +# +# 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: babblesim/edtt/hci_transport +pkg.description: Provides communication with EDTT bridge over named pipes +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.deps: + - "@apache-mynewt-core/sys/console/stub" + - "@apache-mynewt-core/sys/log/stub" + - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/kernel/os" + - nimble/controller + +pkg.apis: + - ble_transport + +pkg.init: + ble_hci_edtt_init: 500 diff --git a/babblesim/edtt/hci_transport/src/ble_hci_edtt.c b/babblesim/edtt/hci_transport/src/ble_hci_edtt.c new file mode 100644 index 0000000000..57cdc3bb8c --- /dev/null +++ b/babblesim/edtt/hci_transport/src/ble_hci_edtt.c @@ -0,0 +1,1149 @@ +/* + * Copyright (c) 2019 Oticon A/S + * Copyright (c) 2021 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "sysinit/sysinit.h" +#include "syscfg/syscfg.h" +#include "os/os_cputime.h" +#include "os/os.h" + +/* BLE */ +#include "nimble/ble.h" +#include "nimble/hci_common.h" +#include "nimble/ble_hci_trans.h" + +#include "bs_symbols.h" +#include "bs_types.h" +#include "time_machine.h" +#include "ble_hci_edtt.h" +#include "edtt_driver.h" +#include "commands.h" + +#define BLE_HCI_EDTT_EVT_COUNT \ + (MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT) + MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT)) + +#define BLE_HCI_EDTT_NONE 0x00 +#define BLE_HCI_EDTT_CMD 0x01 +#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 */ +static ble_hci_trans_rx_cmd_fn *ble_hci_edtt_rx_cmd_cb; +static void *ble_hci_edtt_rx_cmd_arg; +static ble_hci_trans_rx_acl_fn *ble_hci_edtt_rx_acl_cb; +static void *ble_hci_edtt_rx_acl_arg; + +/* Memory pool for hci events (high prio). 16 blocks x 70 bytes */ +static struct os_mempool ble_hci_edtt_evt_hi_pool; +static os_membuf_t ble_hci_edtt_evt_hi_buf[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), + MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) +]; + +/* Memory pool for hci events (low prio). 16 blocks x 70 bytes */ +static struct os_mempool ble_hci_edtt_evt_lo_pool; +static os_membuf_t ble_hci_edtt_evt_lo_buf[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), + MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) +]; + +/* Memory pool for hci commands. Only 1 block, so supports only 1 command at once. */ +static struct os_mempool ble_hci_edtt_cmd_pool; +static os_membuf_t ble_hci_edtt_cmd_buf[ + OS_MEMPOOL_SIZE(1, BLE_HCI_TRANS_CMD_SZ) +]; + +/* + * The MBUF payload size must accommodate the HCI data header size plus the + * maximum ACL data packet length. The ACL block size is the size of the + * mbufs we will allocate. + */ +#define ACL_BLOCK_SIZE OS_ALIGN(MYNEWT_VAL(BLE_ACL_BUF_SIZE) \ + + BLE_MBUF_MEMBLOCK_OVERHEAD \ + + BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT) + +/* mbuf pool for acl data. 15 buffers x (255 bytes + some hdrs len) */ +static struct os_mbuf_pool ble_hci_edtt_acl_mbuf_pool; +static struct os_mempool_ext ble_hci_edtt_acl_pool; +static os_membuf_t ble_hci_edtt_acl_buf[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ACL_BUF_COUNT), + ACL_BLOCK_SIZE) +]; + +/* A packet for queueing EDTT/HCI commands and events */ +struct ble_hci_edtt_pkt { + 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 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]; + +#if EDTT_HCI_LOGS +extern unsigned int global_device_nbr; +static FILE *fptr; + +static void +log_hex_array(uint8_t *buf, int len) +{ + int i; + for (i = 0; i < len; i++) { + fprintf(fptr, "%02X ", buf[i]); + } +} + +static void +log_hci_cmd(uint16_t opcode, uint8_t *buf, int len) +{ + if (fptr) { + fprintf(fptr, "> %llu %02d %02d ", now, BLE_HCI_OCF(opcode), (BLE_HCI_OGF(opcode))); + log_hex_array(buf, len); + fputs("\n\n", fptr); + fflush(fptr); + } +} + +static void +log_hci_evt(struct ble_hci_ev *hdr) +{ + if (fptr) { + fprintf(fptr, "< %llu %02d ", now, hdr->opcode); + log_hex_array(hdr->data, hdr->length); + fputs("\n\n", fptr); + fflush(fptr); + } +} + +static void +log_hci_init() +{ + int flen = (int) strlen(MYNEWT_VAL(EDTT_HCI_LOG_FILE)) + 7; + char *fpath = (char *) calloc(flen, sizeof(char)); + sprintf(fpath, "%s_%02d.log", MYNEWT_VAL(EDTT_HCI_LOG_FILE), global_device_nbr); + fptr = fopen(fpath, "w"); + free(fpath); +} +#endif + +/** + * Allocates a buffer (mbuf) for ACL operation. + * + * @return The allocated buffer on success; + * NULL on buffer exhaustion. + */ +static struct os_mbuf * +ble_hci_trans_acl_buf_alloc(void) +{ + struct os_mbuf *m; + uint8_t usrhdr_len; + +#if MYNEWT_VAL(BLE_CONTROLLER) + usrhdr_len = sizeof(struct ble_mbuf_hdr); +#else + usrhdr_len = 0; +#endif + + m = os_mbuf_get_pkthdr(&ble_hci_edtt_acl_mbuf_pool, usrhdr_len); + return m; +} + +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) { + os_mbuf_free_chain(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->type = BLE_HCI_EDTT_ACL; + pkt->data = om; + + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&rx_queue, pkt, next); + OS_EXIT_CRITICAL(sr); + + return 0; +} + +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->type = edtt_type; + pkt->data = hci_ev; + + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&rx_queue, pkt, next); + OS_EXIT_CRITICAL(sr); + + return 0; +} + +static void +ble_hci_edtt_set_rx_cbs(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_rx_cmd_cb = cmd_cb; + ble_hci_edtt_rx_cmd_arg = cmd_arg; + ble_hci_edtt_rx_acl_cb = acl_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. + * + * @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 *cmd) +{ + int rc; + + rc = ble_hci_edtt_cmdevt_tx(cmd, BLE_HCI_EDTT_EVT); + return rc; +} + +/** + * 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) +{ + int rc; + + rc = ble_hci_edtt_acl_tx(om); + return rc; +} + +int +ble_hci_trans_hs_cmd_tx(uint8_t *cmd) +{ + int rc; + + rc = ble_hci_edtt_cmdevt_tx(cmd, BLE_HCI_EDTT_CMD); + return rc; +} + +int +ble_hci_trans_hs_acl_tx(struct os_mbuf *om) +{ + int rc; + + rc = ble_hci_edtt_acl_tx(om); + return rc; +} + +/** + * 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) { + uint8_t *buf; + + switch (type) { + case BLE_HCI_TRANS_BUF_CMD: + buf = os_memblock_get(&ble_hci_edtt_cmd_pool); + break; + case BLE_HCI_TRANS_BUF_EVT_HI: + buf = os_memblock_get(&ble_hci_edtt_evt_hi_pool); + if (buf == NULL) { + /* If no high-priority event buffers remain, try to grab a + * low-priority one. + */ + buf = os_memblock_get(&ble_hci_edtt_evt_lo_pool); + } + break; + + case BLE_HCI_TRANS_BUF_EVT_LO: + buf = os_memblock_get(&ble_hci_edtt_evt_lo_pool); + break; + + default: + assert(0); + buf = NULL; + } + + return buf; +} + +/** + * 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) +{ + int rc; + + /* + * XXX: this may look a bit odd, but the controller uses the command + * buffer to send back the command complete/status as an immediate + * response to the command. This was done to insure that the controller + * could always send back one of these events when a command was received. + * Thus, we check to see which pool the buffer came from so we can free + * it to the appropriate pool + */ + if (os_memblock_from(&ble_hci_edtt_evt_hi_pool, buf)) { + rc = os_memblock_put(&ble_hci_edtt_evt_hi_pool, buf); + assert(rc == 0); + } 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 { + assert(os_memblock_from(&ble_hci_edtt_cmd_pool, buf)); + rc = os_memblock_put(&ble_hci_edtt_cmd_pool, buf); + assert(rc == 0); + } +} + +int +ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg) +{ + ble_hci_edtt_acl_pool.mpe_put_cb = cb; + ble_hci_edtt_acl_pool.mpe_put_arg = arg; + return 0; +} + +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_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 + */ +static void +read_excess_bytes(uint16_t size) +{ + if (size > 0) { + uint8_t buffer[size]; + + edtt_read((uint8_t *) buffer, size, EDTTT_BLOCK); + bs_trace_raw_time(3, "command size wrong! (%u extra bytes removed)", size); + } +} + +/** + * @brief Provide an error response when an HCI command send failed + */ +static void +error_response(int error) +{ + uint16_t response = waiting_response; + int le_error = error; + uint16_t size = sizeof(le_error); + + edtt_write((uint8_t *) &response, sizeof(response), EDTTT_BLOCK); + edtt_write((uint8_t *) &size, sizeof(size), EDTTT_BLOCK); + edtt_write((uint8_t *) &le_error, sizeof(le_error), EDTTT_BLOCK); + waiting_response = CMD_NOTHING; + waiting_opcode = 0; +} + +/** + * @brief Allocate buffer for HCI command, fill in parameters and send the + * command + */ +static int +send_hci_cmd_to_ctrl(uint16_t opcode, uint8_t param_len, uint16_t response) { + struct ble_hci_cmd *buf; + int err = 0; + waiting_response = response; + waiting_opcode = opcode; + + buf = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); + + if (buf != NULL) { + buf->opcode = opcode; + buf->length = param_len; + + if (param_len) { + edtt_read((uint8_t *) buf->data, param_len, EDTTT_BLOCK); + } + +#if EDTT_HCI_LOGS + log_hci_cmd(opcode, buf->data, param_len); +#endif + + err = ble_hci_edtt_rx_cmd_cb((uint8_t *) buf, NULL); + if (err) { + ble_hci_trans_buf_free((uint8_t *) buf); + bs_trace_raw_time(3, "Failed to send HCI command %d (err %d)", opcode, err); + error_response(err); + } + } else { + bs_trace_raw_time(3, "Failed to create buffer for HCI command 0x%04x", opcode); + error_response(-1); + } + return err; +} + +/** + * @brief Echo function - echo input received + */ +static void +echo(uint16_t size) +{ + uint16_t response = CMD_ECHO_RSP; + + edtt_write((uint8_t *) &response, sizeof(response), EDTTT_BLOCK); + edtt_write((uint8_t *) &size, sizeof(size), EDTTT_BLOCK); + + if (size > 0) { + uint8_t buff[size]; + + edtt_read(buff, size, EDTTT_BLOCK); + edtt_write(buff, size, EDTTT_BLOCK); + } +} + +/** + * @brief Handle Command Complete HCI event + */ +static void +command_complete(struct ble_hci_ev *hdr) +{ + struct ble_hci_ev_command_complete *evt = (void *) hdr->data; + uint16_t response = waiting_response; + uint16_t size = hdr->length - sizeof(evt->num_packets) - sizeof(evt->opcode); + + if (evt->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); + waiting_opcode = 0; + } else { + bs_trace_raw_time(5, "Not waiting for 0x(%04x) command status," + " expected 0x(%04x)", evt->opcode, waiting_opcode); + } +} + +/** + * @brief Handle Command Status HCI event + */ +static void +command_status(struct ble_hci_ev *buf) +{ + struct ble_hci_ev_command_status *evt = (void *) buf->data; + uint16_t opcode = evt->opcode; + uint16_t response = waiting_response; + uint16_t size; + + size = buf->length - sizeof(evt->num_packets) - sizeof(evt->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); + waiting_opcode = 0; + } else { + bs_trace_raw_time(5, "Not waiting for 0x(%04x) command status," + " expected 0x(%04x)", opcode, waiting_opcode); + } +} + +/** + * @brief Remove an event from the event queue + */ +static void +discard_event(void) +{ + struct ble_hci_edtt_pkt *evt = edtt_pkt_get(&event_queue, K_FOREVER); + edtt_pkt_dequeue_and_free(&event_queue, evt); + m_events--; +} + +/** + * @brief Allocate and store an event in the event queue + */ +static struct ble_hci_edtt_pkt * +queue_event(struct ble_hci_ev *buf) +{ + struct ble_hci_edtt_pkt *evt; + + 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; + + STAILQ_INSERT_TAIL(&event_queue, evt, next); + m_events++; + } + return evt; +} + +/** + * @brief Thread to service events and ACL data packets from the HCI input queue + */ +static void +service_events(void) +{ + struct ble_hci_edtt_pkt *rx_pkt, *evt_pkt, *data_pkt; + struct ble_hci_ev *hdr; + struct os_mbuf *om; + + rx_pkt = edtt_pkt_get(&rx_queue, K_NO_WAIT); + if (rx_pkt == NULL) { + return; + } + + if (rx_pkt->type == BLE_HCI_EDTT_EVT) { + hdr = (void *) rx_pkt->data; + +#if EDTT_HCI_LOGS + log_hci_evt(hdr); +#endif + + /* Prepare and send EDTT events */ + switch (hdr->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); + 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); + 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; + 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); + } + } + + /* 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); +} + +/** + * @brief Flush all HCI events from the input-copy queue + */ +static void +flush_events(uint16_t size) +{ + uint16_t response = CMD_FLUSH_EVENTS_RSP; + struct ble_hci_edtt_pkt *buf; + + while ((buf = edtt_pkt_get(&event_queue, K_NO_WAIT))) { + edtt_pkt_dequeue_and_free(&event_queue, buf); + m_events--; + } + read_excess_bytes(size); + size = 0; + + edtt_write((uint8_t *)&response, sizeof(response), EDTTT_BLOCK); + edtt_write((uint8_t *)&size, sizeof(size), EDTTT_BLOCK); +} + +/** + * @brief Get next available HCI event from the input-copy queue + */ +static void +get_event(uint16_t size) +{ + uint16_t response = CMD_GET_EVENT_RSP; + struct ble_hci_edtt_pkt *pkt; + struct ble_hci_ev *hdr; + + read_excess_bytes(size); + size = 0; + + edtt_write((uint8_t *)&response, sizeof(response), EDTTT_BLOCK); + pkt = edtt_pkt_get(&event_queue, K_FOREVER); + + if (pkt) { + hdr = pkt->data; + size = sizeof(pkt->timestamp) + sizeof(*hdr) + hdr->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_pkt_dequeue_and_free(&event_queue, pkt); + m_events--; + } else { + edtt_write((uint8_t *)&size, sizeof(size), EDTTT_BLOCK); + } +} + +/** + * @brief Get next available HCI events from the input-copy queue + */ +static void +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; + + read_excess_bytes(size); + size = 0; + + edtt_write((uint8_t *)&response, sizeof(response), EDTTT_BLOCK); + 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; + + 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_pkt_dequeue_and_free(&event_queue, pkt); + m_events--; + } +} + +/** + * @brief Check whether an HCI event is available in the input-copy queue + */ +static void +has_event(uint16_t size) +{ + struct has_event_resp { + uint16_t response; + uint16_t size; + uint8_t count; + } __attribute__((packed)); + struct has_event_resp le_response = { + .response = CMD_HAS_EVENT_RSP, + .size = 1, + .count = m_events + }; + + if (size > 0) { + read_excess_bytes(size); + } + edtt_write((uint8_t *) &le_response, sizeof(le_response), EDTTT_BLOCK); +} + +/** + * @brief Flush all ACL Data Packages from the input-copy queue + */ +static void +le_flush_data(uint16_t size) +{ + uint16_t response = CMD_LE_FLUSH_DATA_RSP; + struct ble_hci_edtt_pkt *buf; + + while ((buf = edtt_pkt_get(&data_queue, K_NO_WAIT))) { + edtt_pkt_dequeue_and_free(&data_queue, buf); + } + read_excess_bytes(size); + size = 0; + + edtt_write((uint8_t *)&response, sizeof(response), EDTTT_BLOCK); + edtt_write((uint8_t *)&size, sizeof(size), EDTTT_BLOCK); +} + +/** + * @brief Check whether an ACL Data Package is available in the input-copy queue + */ +static void +le_data_ready(uint16_t size) +{ + struct has_data_resp { + uint16_t response; + uint16_t size; + uint8_t empty; + } __attribute__((packed)); + struct has_data_resp le_response = { + .response = CMD_LE_DATA_READY_RSP, + .size = 1, + .empty = 0 + }; + + if (size > 0) { + read_excess_bytes(size); + } + + if (STAILQ_EMPTY(&data_queue)) { + le_response.empty = 1; + } + + edtt_write((uint8_t *) &le_response, sizeof(le_response), EDTTT_BLOCK); +} + +/** + * @brief Get next available HCI Data Package from the input-copy queue + */ +static void +le_data_read(uint16_t size) +{ + uint16_t response = CMD_LE_DATA_READ_RSP; + struct ble_hci_edtt_pkt *pkt; + struct os_mbuf *om; + + read_excess_bytes(size); + size = 0; + + edtt_write((uint8_t *)&response, sizeof(response), EDTTT_BLOCK); + pkt = edtt_pkt_get(&data_queue, K_FOREVER); + + if (pkt) { + om = pkt->data; + size = OS_MBUF_PKTLEN(om); + edtt_write((uint8_t *)&size, sizeof(size), EDTTT_BLOCK); + + while (om != NULL) { + edtt_write((uint8_t *)om->om_data, om->om_len, EDTTT_BLOCK); + om = SLIST_NEXT(om, om_next); + } + + om = pkt->data; + os_mbuf_free_chain(om); + } else { + edtt_write((uint8_t *)&size, sizeof(size), EDTTT_BLOCK); + } +} + +/** + * @brief Write ACL Data Package to the Controller + */ +static void +le_data_write(uint16_t size) +{ + struct data_write_resp { + uint16_t code; + uint16_t size; + uint8_t status; + } __attribute__((packed)); + struct data_write_resp response = { + .code = CMD_LE_DATA_WRITE_RSP, + .size = 1, + .status = 0 + }; + struct os_mbuf *om; + struct hci_data_hdr hdr; + 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; + + if (size >= hdr_length) { + edtt_read(om->om_data, hdr_length, EDTTT_BLOCK); + size -= hdr_length; + } + + err = ble_hci_edtt_rx_acl_cb(om, NULL); + if (err) { + bs_trace_raw_time(3, "Failed to send ACL Data (err %d)", err); + } + } else { + err = -2; /* Failed to allocate data buffer */ + bs_trace_raw_time(3, "Failed to create buffer for ACL Data."); + } + } else { + /* Size too small for header (handle and data length) */ + err = -3; + } + read_excess_bytes(size); + + response.status = err; + edtt_write((uint8_t *) &response, sizeof(response), EDTTT_BLOCK); +} + +static void +fake_set_public_address() +{ + struct ble_hci_ev_command_complete *ev; + struct ble_hci_ev *hci_ev; + waiting_opcode = BT_HCI_OP_VS_WRITE_BD_ADDR; + waiting_response = CMD_WRITE_BD_ADDR_RSP; + + hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + if (hci_ev) { + hci_ev->opcode = BLE_HCI_EVCODE_COMMAND_COMPLETE; + hci_ev->length = sizeof(*ev); + ev = (void *) hci_ev->data; + + ev->num_packets = 1; + ev->opcode = waiting_opcode; + ev->status = 0; + ble_hci_edtt_cmdevt_tx((uint8_t *) hci_ev, BLE_HCI_EDTT_EVT); + } +} + +/* Reads and executes EDTT commands. */ +static void +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; + + /* Initialize and start EDTT system */ + enable_edtt_mode(); + set_edtt_autoshutdown(true); + edtt_start(); + +#if EDTT_HCI_LOGS + log_hci_init(); +#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 *) &size, sizeof(size), EDTTT_BLOCK); + + bs_trace_raw_time(4, "command 0x%04X received (size %u) " + "events=%u\n", + command, size, m_events); + + switch (command) { + case CMD_ECHO_REQ: + echo(size); + break; + case CMD_FLUSH_EVENTS_REQ: + flush_events(size); + break; + case CMD_HAS_EVENT_REQ: + has_event(size); + break; + case CMD_GET_EVENT_REQ: { + uint8_t multiple; + + edtt_read((uint8_t *) &multiple, sizeof(multiple), EDTTT_BLOCK); + if (multiple) + get_events(--size); + else + get_event(--size); + } + break; + case CMD_LE_FLUSH_DATA_REQ: + le_flush_data(size); + break; + case CMD_LE_DATA_READY_REQ: + le_data_ready(size); + break; + case CMD_LE_DATA_WRITE_REQ: + le_data_write(size); + break; + case CMD_LE_DATA_READ_REQ: + le_data_read(size); + break; + case CMD_WRITE_BD_ADDR_REQ: + 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); + } + break; + default: + if (size >= 2) { + edtt_read((uint8_t *) &opcode, sizeof(opcode), EDTTT_BLOCK); + send_hci_cmd_to_ctrl(opcode, size - 2, command + 1); + } + } + } +} + +int +edtt_init(void) +{ + 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); + } + return 0; +} + +/** + * Initializes the EDTT HCI transport module. + * + * @return 0 on success; + * A BLE_ERR_[...] error code on failure. + */ +void +ble_hci_edtt_init(void) +{ + int rc; + + /* Ensure this function only gets called by sysinit. */ + SYSINIT_ASSERT_ACTIVE(); + + rc = os_mempool_ext_init(&ble_hci_edtt_acl_pool, + MYNEWT_VAL(BLE_ACL_BUF_COUNT), + ACL_BLOCK_SIZE, + ble_hci_edtt_acl_buf, + "ble_hci_edtt_acl_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = os_mbuf_pool_init(&ble_hci_edtt_acl_mbuf_pool, + &ble_hci_edtt_acl_pool.mpe_mp, + ACL_BLOCK_SIZE, + MYNEWT_VAL(BLE_ACL_BUF_COUNT)); + SYSINIT_PANIC_ASSERT(rc == 0); + + /* + * Create memory pool of HCI command buffers. NOTE: we currently dont + * allow this to be configured. The controller will only allow one + * outstanding command. We decided to keep this a pool in case we allow + * allow the controller to handle more than one outstanding command. + */ + rc = os_mempool_init(&ble_hci_edtt_cmd_pool, + 1, + BLE_HCI_TRANS_CMD_SZ, + ble_hci_edtt_cmd_buf, + "ble_hci_edtt_cmd_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = os_mempool_init(&ble_hci_edtt_evt_hi_pool, + MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), + MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), + ble_hci_edtt_evt_hi_buf, + "ble_hci_edtt_evt_hi_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = os_mempool_init(&ble_hci_edtt_evt_lo_pool, + MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), + MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), + ble_hci_edtt_evt_lo_buf, + "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); +} diff --git a/babblesim/edtt/hci_transport/src/edtt_driver_bsim.c b/babblesim/edtt/hci_transport/src/edtt_driver_bsim.c new file mode 100644 index 0000000000..0e291ea49f --- /dev/null +++ b/babblesim/edtt/hci_transport/src/edtt_driver_bsim.c @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2019 Oticon A/S + * Copyright (c) 2021 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "bs_tracing.h" +#include "bs_oswrap.h" +#include "bs_pc_base_fifo_user.h" + +#include +#include "edtt_driver.h" + +/* Recheck if something arrived from the EDTT every 5ms */ +#define EDTT_IF_RECHECK_DELTA 5 /* ms */ + +/* We want the runs to be deterministic => we want to resync with the Phy + * before we retry any read so the bridge device may also run + */ +#define EDTT_SIMU_RESYNC_TIME_WITH_EDTT \ + (EDTT_IF_RECHECK_DELTA * 1000 - 1) + +static int edtt_mode_enabled = 0; + +/* In this mode, when the EDTTool closes the FIFO we automatically terminate + * this simulated device. If false, we just continue running + */ +static int edtt_autoshutdown; + +#define TO_DEVICE 0 +#define TO_BRIDGE 1 +static int fifo[2] = { -1, -1 }; +static char *fifo_path[2] = {NULL, NULL}; + +extern unsigned int global_device_nbr; + +static void edttd_clean_up(void); +static void edptd_create_fifo_if(void); +static int fifo_low_level_read(uint8_t *bufptr, int size); + +bool edtt_start(void) +{ + if (edtt_mode_enabled == false) { + /* otherwise we don't try to open the EDTT interface */ + return true; + } + + edptd_create_fifo_if(); + + extern void tm_set_phy_max_resync_offset(uint64_t offset_in_us); + tm_set_phy_max_resync_offset(EDTT_SIMU_RESYNC_TIME_WITH_EDTT); + return true; +} + +bool edtt_stop(void) +{ + if (edtt_mode_enabled == false) { + /* otherwise we don't try to open the EDTT interface */ + return true; + } + + bs_trace_raw(9, "EDTTT: %s called\n", __func__); + edttd_clean_up(); + edtt_mode_enabled = false; + return true; +} + +static void +print_hex_array(int lvl, uint8_t *buf, int len) +{ + char str[2*len]; + char *p = str; + int i; + for (i = 0; i < len; i++) { + if (i > 0) *p++ = ' '; + sprintf(p++, "%02X", buf[i]); + } + *p = '\n'; + bs_trace_raw(lvl, str); +} + +/** + * Attempt to read size bytes thru the EDTT IF into the buffer <*ptr> + * can be set to EDTTT_BLOCK or EDTTT_NONBLOCK + * + * If set to EDTTT_BLOCK it will block the calling thread until + * bytes have been read or the interface has been closed. + * If set to EDTTT_NONBLOCK it returns as soon as there is no more data to be + * read + * + * Returns the amount of read bytes, or -1 on error + */ +int edtt_read(uint8_t *ptr, size_t size, int flags) +{ + uint8_t *buf = ptr; + + if (edtt_mode_enabled == false) { + return -1; + } + + bs_trace_raw_time(8, "EDTT: Asked to read %i bytes\n", size); + int read = 0; + + while (size > 0) { + int received_bytes; + + received_bytes = fifo_low_level_read(ptr, size); + if (received_bytes < 0) { + return -1; + } else if (received_bytes > 0) { + size -= received_bytes; + ptr += received_bytes; + read += received_bytes; + } else { + if (flags & EDTTT_BLOCK) { + bs_trace_raw_time(9, "EDTT: No enough data yet," + "sleeping for %i ms\n", + EDTT_IF_RECHECK_DELTA); + tm_tick_limited(6000); + } else { + bs_trace_raw_time(9, "EDTT: No enough data yet," + "returning\n"); + break; + } + } + } + + if (read > 0) { + bs_trace_raw_time(8, "Read %i bytes:\n", read); + print_hex_array(8, buf, read); + } + return read; +} + +/** + * Write bytes from toward the EDTTool + * + * is ignored in this driver, all writes to the tool are + * instantaneous + */ +int edtt_write(uint8_t *ptr, size_t size, int flags) +{ + if (edtt_mode_enabled == false) { + return -1; + } + + bs_trace_raw_time(6, "EDTT: Asked to write %i bytes: ", size); + print_hex_array(6, ptr, size); + + if (write(fifo[TO_BRIDGE], ptr, size) != size) { + if (errno == EPIPE) { + bs_trace_error_line("EDTT IF suddenly closed by other " + "end\n"); + } + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { + bs_trace_error_line("EDTT IF to bridge filled up (FIFO " + "size needs to be increased)\n"); + } + bs_trace_error_line("EDTT IF: Unexpected error on write\n"); + } + return size; +} + +/* + * Applications may want to enable the EDTT interface only in some + * cases. By default it is not enabled in this driver. This function + * must be called once before starting it to do so + */ +void enable_edtt_mode(void) +{ + edtt_mode_enabled = true; +} + +/** + * Automatically terminate this device execution once the EDTTool disconnects + */ +void set_edtt_autoshutdown(bool Mode) +{ + edtt_autoshutdown = Mode; +} + +static void edptd_create_fifo_if(void) +{ + int flags; + + bs_trace_raw_time(9, "Bringing EDTT IF up (waiting for other side)\n"); + + if (pb_com_path == NULL) { + bs_trace_error_line("Not connected to Phy." + "EDTT IF cannot be brough up\n"); + } + + /* At this point we have connected to the Phy so the COM folder does + * already exist + * also SIGPIPE is already ignored + */ + + fifo_path[TO_DEVICE] = (char *)bs_calloc(pb_com_path_length + 30, + sizeof(char)); + fifo_path[TO_BRIDGE] = (char *)bs_calloc(pb_com_path_length + 30, + sizeof(char)); + sprintf(fifo_path[TO_DEVICE], "%s/Device%i.PTTin", + pb_com_path, global_device_nbr); + sprintf(fifo_path[TO_BRIDGE], "%s/Device%i.PTTout", + pb_com_path, global_device_nbr); + + if ((pb_create_fifo_if_not_there(fifo_path[TO_DEVICE]) != 0) + || (pb_create_fifo_if_not_there(fifo_path[TO_BRIDGE]) != 0)) { + bs_trace_error_line("Couldnt create FIFOs for EDTT IF\n"); + } + + /* we block here until the bridge opens its end */ + fifo[TO_BRIDGE] = open(fifo_path[TO_BRIDGE], O_WRONLY); + if (fifo[TO_BRIDGE] == -1) { + bs_trace_error_line("Couldn't create FIFOs for EDTT IF\n"); + } + + flags = fcntl(fifo[TO_BRIDGE], F_GETFL); + flags |= O_NONBLOCK; + fcntl(fifo[TO_BRIDGE], F_SETFL, flags); + + /* we will block here until the bridge opens its end */ + fifo[TO_DEVICE] = open(fifo_path[TO_DEVICE], O_RDONLY); + if (fifo[TO_DEVICE] == -1) { + bs_trace_error_line("Couldn't create FIFOs for EDTT IF\n"); + } + + flags = fcntl(fifo[TO_DEVICE], F_GETFL); + flags |= O_NONBLOCK; + fcntl(fifo[TO_DEVICE], F_SETFL, flags); +} + +static void edttd_clean_up(void) +{ + for (int dir = TO_DEVICE ; dir <= TO_BRIDGE ; dir++) { + if (fifo_path[dir]) { + if (fifo[dir] != -1) { + close(fifo[dir]); + remove(fifo_path[dir]); + fifo[dir] = -1; + } + free(fifo_path[dir]); + fifo_path[dir] = NULL; + } + } + if (pb_com_path != NULL) { + rmdir(pb_com_path); + } +} + +static int fifo_low_level_read(uint8_t *bufptr, int size) +{ + int received_bytes = read(fifo[TO_DEVICE], bufptr, size); + + if ((received_bytes == -1) && (errno == EAGAIN)) { + return 0; + } else if (received_bytes == EOF || received_bytes == 0) { + /*The FIFO was closed by the bridge*/ + if (edtt_autoshutdown) { + bs_trace_raw_time(3, "EDTT: FIFO closed " + "(ptt_autoshutdown==true) =>" + " Terminate\n"); + edttd_clean_up(); + bs_trace_exit_line("\n"); + } else { + bs_trace_raw_time(3, "EDTT: FIFO closed " + "(ptt_autoshutdown==false) => We close " + "the FIFOs and move on\n"); + edttd_clean_up(); + edtt_mode_enabled = false; + return -1; + } + } else if (received_bytes == -1) { + bs_trace_error_line("EDTT: Unexpected error\n"); + } + + return received_bytes; +} diff --git a/babblesim/edtt/hci_transport/syscfg.yml b/babblesim/edtt/hci_transport/syscfg.yml new file mode 100644 index 0000000000..b203361d03 --- /dev/null +++ b/babblesim/edtt/hci_transport/syscfg.yml @@ -0,0 +1,49 @@ +# +# 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. +# + +syscfg.defs: + EDTT_HCI_LOG_FILE: + description: > + Path to the HCI log file. Skip file extension + because device id and .log will be appended. + value: "hci_logs" + EDTT_HCI_LOGS: + description: Turn on HCI commands logging. + value: 0 + EDTT_POLLER_PRIO: + description: 'Priority of native EDTT poller task.' + type: task_priority + value: 2 + + BLE_HCI_ACL_OUT_COUNT: + description: > + This count is used in creating a pool of elements used by the + code to enqueue various elements. In the case of the controller + only HCI, this number should be equal to the number of mbufs in + the msys pool. For host only, it is really dependent on the + number of ACL buffers that the controller tells the host it + has. + value: 12 + +syscfg.vals: + BLE_ACL_BUF_COUNT: 32 + BLE_ACL_BUF_SIZE: 255 + BLE_HCI_EVT_BUF_SIZE: 257 + BLE_HCI_EVT_HI_BUF_COUNT: 32 + BLE_HCI_EVT_LO_BUF_COUNT: 32 diff --git a/babblesim/hw/bsp/nrf52_bsim/syscfg.yml b/babblesim/hw/bsp/nrf52_bsim/syscfg.yml index 2070c69e14..8558c5d304 100644 --- a/babblesim/hw/bsp/nrf52_bsim/syscfg.yml +++ b/babblesim/hw/bsp/nrf52_bsim/syscfg.yml @@ -37,7 +37,7 @@ syscfg.vals: OS_MAIN_STACK_SIZE: 8000 MCU_TIMER_POLLER_PRIO: 0 BLE_LL_PRIO: 1 - MCU_UART_POLLER_PRIO: 2 + MCU_UART_POLLER_PRIO: 9 # Enable nRF52832 MCU MCU_TARGET: nRF52832 diff --git a/babblesim/targets/edtthci/pkg.yml b/babblesim/targets/edtthci/pkg.yml new file mode 100644 index 0000000000..a08f47b86c --- /dev/null +++ b/babblesim/targets/edtthci/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: babblesim/targets/edtthci +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: diff --git a/babblesim/targets/edtthci/syscfg.yml b/babblesim/targets/edtthci/syscfg.yml new file mode 100644 index 0000000000..972659e39f --- /dev/null +++ b/babblesim/targets/edtthci/syscfg.yml @@ -0,0 +1,55 @@ +# +# 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. +# + +syscfg.vals: + # EDTT requires 0x123456789ABC address for the first device + # and 0x456789ABCDEF for the second one + BLE_LL_PUBLIC_DEV_ADDR: 0x123456789ABC # d=1 + # BLE_LL_PUBLIC_DEV_ADDR: 0x456789ABCDEF # d=2 + + EDTT_HCI_LOG_FILE: ("hci_logs") + EDTT_HCI_LOGS: 1 + + BLE_LL_CFG_FEAT_LE_ENCRYPTION: 1 + BLE_LL_CFG_FEAT_CONN_PARAM_REQ: 1 + BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG: 1 + BLE_LL_CFG_FEAT_LE_PING: 1 + BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 + BLE_LL_CFG_FEAT_LL_PRIVACY: 1 + BLE_LL_CFG_FEAT_LE_CSA2: 1 + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 +# BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 # not modeled in bsim + BLE_LL_CFG_FEAT_LL_EXT_ADV: 1 + BLE_LL_CFG_FEAT_LL_PERIODIC_ADV: 1 + BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER: 1 + BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL: 1 + BLE_LL_CFG_FEAT_LL_SCA_UPDATE: 1 + + BLE_ROLE_CENTRAL: 1 + BLE_ROLE_PERIPHERAL: 1 + BLE_ROLE_BROADCASTER: 1 + BLE_ROLE_OBSERVER: 1 + + BLE_VERSION: 52 + BLE_CONTROLLER: 1 + BLE_LL_ROLE_CENTRAL: 1 + BLE_LL_ROLE_PERIPHERAL: 1 + BLE_LL_ROLE_BROADCASTER: 1 + BLE_LL_ROLE_OBSERVER: 1 + BLE_HW_WHITELIST_ENABLE: 1 diff --git a/babblesim/targets/edtthci/target.yml b/babblesim/targets/edtthci/target.yml new file mode 100644 index 0000000000..3990ba4e70 --- /dev/null +++ b/babblesim/targets/edtthci/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/babblesim/edtt/hci_test" +target.bsp: "@apache-mynewt-nimble/babblesim/hw/bsp/nrf52_bsim" +target.build_profile: debug From 894d5321688903f9788f3993d6a4ce458ec4b5ce Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 21 Feb 2022 15:30:41 +0100 Subject: [PATCH 0285/1333] babblesim: Remove sbrk We do not need it since this works natively with libc. --- babblesim/hw/bsp/nrf52_bsim/src/sbrk.c | 59 -------------------------- babblesim/hw/bsp/nrf52_bsim/syscfg.yml | 1 + 2 files changed, 1 insertion(+), 59 deletions(-) delete mode 100644 babblesim/hw/bsp/nrf52_bsim/src/sbrk.c diff --git a/babblesim/hw/bsp/nrf52_bsim/src/sbrk.c b/babblesim/hw/bsp/nrf52_bsim/src/sbrk.c deleted file mode 100644 index 5df43c9519..0000000000 --- a/babblesim/hw/bsp/nrf52_bsim/src/sbrk.c +++ /dev/null @@ -1,59 +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. - */ - -#include - -/* put these in the data section so they are not cleared by _start */ -static char *sbrkBase __attribute__ ((section (".data"))); -static char *sbrkLimit __attribute__ ((section (".data"))); -static char *brk __attribute__ ((section (".data"))); - -void -_sbrkInit(char *base, char *limit) { - sbrkBase = base; - sbrkLimit = limit; - brk = base; -} - -void * -_sbrk(int incr) -{ - void *prev_brk; - - if (incr < 0) { - /* Returning memory to the heap. */ - incr = -incr; - if (brk - incr < sbrkBase) { - prev_brk = (void *)-1; - } else { - prev_brk = brk; - brk -= incr; - } - } else { - /* Allocating memory from the heap. */ - if (sbrkLimit - brk >= incr) { - prev_brk = brk; - brk += incr; - } else { - prev_brk = (void *)-1; - } - } - - return prev_brk; -} diff --git a/babblesim/hw/bsp/nrf52_bsim/syscfg.yml b/babblesim/hw/bsp/nrf52_bsim/syscfg.yml index 8558c5d304..b10d21dd36 100644 --- a/babblesim/hw/bsp/nrf52_bsim/syscfg.yml +++ b/babblesim/hw/bsp/nrf52_bsim/syscfg.yml @@ -34,6 +34,7 @@ syscfg.defs: value: 0 syscfg.vals: + HAL_SBRK: 0 OS_MAIN_STACK_SIZE: 8000 MCU_TIMER_POLLER_PRIO: 0 BLE_LL_PRIO: 1 From b3990580fb8a7eba88223489f8a9b54a141f1c0c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 3 Feb 2022 17:05:20 +0100 Subject: [PATCH 0286/1333] nimble/ll: Remove strict conn scheduling This removes strict scheduling code as we'll add new, more configurable implementation instead. --- .../include/controller/ble_ll_conn.h | 4 - .../include/controller/ble_ll_sched.h | 33 -- nimble/controller/src/ble_ll_conn.c | 27 +- nimble/controller/src/ble_ll_sched.c | 296 ------------------ nimble/controller/syscfg.yml | 33 +- 5 files changed, 13 insertions(+), 380 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index cd219cb9ac..015bac7597 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -230,10 +230,6 @@ struct ble_ll_conn_sm uint8_t last_unmapped_chan; uint8_t num_used_chans; -#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) - uint8_t period_occ_mask; /* mask: period 0 = 0x01, period 3 = 0x08 */ -#endif - /* Ack/Flow Control */ uint8_t tx_seqnum; /* note: can be 1 bit */ uint8_t next_exp_seqnum; /* note: can be 1 bit */ diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index 56399d2e9e..b3f7d19fdf 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -79,39 +79,6 @@ extern uint8_t g_ble_ll_sched_offset_ticks; struct ble_ll_sched_item; typedef int (*sched_cb_func)(struct ble_ll_sched_item *sch); typedef void (*sched_remove_cb_func)(struct ble_ll_sched_item *sch); -/* - * Strict connection scheduling (for the master) is different than how - * connections are normally scheduled. With strict connection scheduling we - * introduce the concept of a "period". A period is a collection of slots. Each - * slot is 1.25 msecs in length. The number of slots in a period is determined - * by the syscfg value BLE_LL_CONN_INIT_SLOTS. A collection of periods is called - * an epoch. The length of an epoch is determined by the number of connections - * (BLE_MAX_CONNECTIONS plus BLE_LL_ADD_STRICT_SCHED_PERIODS). Connections - * will be scheduled at period boundaries. Any scanning/initiating/advertising - * will be done in unused periods, if possible. - */ -#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) -#define BLE_LL_SCHED_PERIODS (MYNEWT_VAL(BLE_MAX_CONNECTIONS) + \ - MYNEWT_VAL(BLE_LL_ADD_STRICT_SCHED_PERIODS)) - -struct ble_ll_sched_obj -{ - uint8_t sch_num_occ_periods; - uint32_t sch_occ_period_mask; - uint32_t sch_ticks_per_period; - uint32_t sch_ticks_per_epoch; - uint32_t sch_epoch_start; -}; - -extern struct ble_ll_sched_obj g_ble_ll_sched_data; - -/* - * XXX: TODO: - * -> How do we know epoch start is up to date? Not wrapped? - * -> for now, only do this with no more than 32 connections. - * -> Do not let initiating occur if no empty sched slots - */ -#endif /* * Schedule item diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 33a666aeba..f3e40a2442 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -761,10 +761,6 @@ ble_ll_conn_continue_rx_encrypt(void *arg) static uint32_t ble_ll_conn_get_next_sched_time(struct ble_ll_conn_sm *connsm) { -#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) - uint32_t ce_end; - ce_end = connsm->ce_end_time; -#else uint32_t ce_end; uint32_t next_sched_time; uint8_t rem_us; @@ -781,7 +777,6 @@ ble_ll_conn_get_next_sched_time(struct ble_ll_conn_sm *connsm) ce_end = next_sched_time; } } -#endif return ce_end; } @@ -1934,16 +1929,6 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err) /* Make sure events off queue */ ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &connsm->conn_ev_end); -#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) - /* Remove from occupied periods */ - OS_ENTER_CRITICAL(sr); - BLE_LL_ASSERT(g_ble_ll_sched_data.sch_num_occ_periods > 0); - BLE_LL_ASSERT(g_ble_ll_sched_data.sch_occ_period_mask & connsm->period_occ_mask); - --g_ble_ll_sched_data.sch_num_occ_periods; - g_ble_ll_sched_data.sch_occ_period_mask &= ~connsm->period_occ_mask; - OS_EXIT_CRITICAL(sr); -#endif - /* Connection state machine is now idle */ connsm->conn_state = BLE_LL_CONN_STATE_IDLE; @@ -2219,12 +2204,9 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) * Calculate ce end time. For a peripgheral, we need to add window widening * and the transmit window if we still have one. */ -#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) - itvl = g_ble_ll_sched_data.sch_ticks_per_period; -#else itvl = ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * BLE_LL_SCHED_USECS_PER_SLOT); -#endif + #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { @@ -2333,17 +2315,10 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) connsm->periph_cur_tx_win_usecs = connsm->tx_win_size * BLE_LL_CONN_TX_WIN_USECS; -#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) - connsm->ce_end_time = connsm->anchor_point + - g_ble_ll_sched_data.sch_ticks_per_period + - ble_ll_tmr_u2t(connsm->periph_cur_tx_win_usecs) + 1; - -#else connsm->ce_end_time = connsm->anchor_point + ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * BLE_LL_SCHED_USECS_PER_SLOT + connsm->periph_cur_tx_win_usecs) + 1; -#endif /* Start the scheduler for the first connection event */ while (ble_ll_sched_conn_periph_new(connsm)) { diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index b7d8cf6d0e..14c8753d00 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -64,10 +64,6 @@ typedef int (* ble_ll_sched_preempt_cb_t)(struct ble_ll_sched_item *sch, static TAILQ_HEAD(ll_sched_qhead, ble_ll_sched_item) g_ble_ll_sched_q; static uint8_t g_ble_ll_sched_q_head_changed; -#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) -struct ble_ll_sched_obj g_ble_ll_sched_data; -#endif - static int preempt_any(struct ble_ll_sched_item *sch, struct ble_ll_sched_item *item) @@ -284,39 +280,6 @@ ble_ll_sched_insert(struct ble_ll_sched_item *sch, uint32_t max_delay, return sch->enqueued ? 0 : -1; } -#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) -/** - * Checks if two events in the schedule will overlap in time. NOTE: consecutive - * schedule items can end and start at the same time. - * - * @param s1 - * @param s2 - * - * @return int 0: dont overlap 1:overlap - */ -static int -ble_ll_sched_is_overlap(struct ble_ll_sched_item *s1, - struct ble_ll_sched_item *s2) -{ - int rc; - - rc = 1; - if (LL_TMR_LT(s1->start_time, s2->start_time)) { - /* Make sure this event does not overlap current event */ - if (LL_TMR_LEQ(s1->end_time, s2->start_time)) { - rc = 0; - } - } else { - /* Check for overlap */ - if (LL_TMR_GEQ(s1->start_time, s2->end_time)) { - rc = 0; - } - } - - return rc; -} -#endif - /* * Determines if the schedule item overlaps the currently running schedule * item. We only care about connection schedule items @@ -338,21 +301,6 @@ ble_ll_sched_overlaps_current(struct ble_ll_sched_item *sch) return rc; } -#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) -static struct ble_ll_sched_item * -ble_ll_sched_insert_if_empty(struct ble_ll_sched_item *sch) -{ - struct ble_ll_sched_item *entry; - - entry = TAILQ_FIRST(&g_ble_ll_sched_q); - if (!entry) { - TAILQ_INSERT_HEAD(&g_ble_ll_sched_q, sch, link); - sch->enqueued = 1; - } - return entry; -} -#endif - int ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) { @@ -420,241 +368,6 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) * * @return int */ -#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) -int -ble_ll_sched_central_new(struct ble_ll_conn_sm *connsm, - struct ble_mbuf_hdr *ble_hdr, uint8_t pyld_len) -{ - int rc; - os_sr_t sr; - uint32_t initial_start; - uint32_t earliest_start; - uint32_t earliest_end; - uint32_t dur; - uint32_t itvl_t; - uint32_t adv_rxend; - int i; - uint32_t tpp; - uint32_t tse; - uint32_t np; - uint32_t cp; - uint32_t tick_in_period; - - struct ble_ll_sched_item *entry; - struct ble_ll_sched_item *sch; - - /* Better have a connsm */ - BLE_LL_ASSERT(connsm != NULL); - - /* Get schedule element from connection */ - rc = -1; - sch = &connsm->conn_sch; - - /* XXX: - * The calculations for the 32kHz crystal bear alot of explanation. The - * earliest possible time that the central can start the connection with a - * peripheral is 1.25 msecs from the end of the connection request. The - * connection request is sent an IFS time from the end of the advertising - * packet that was received plus the time it takes to send the connection - * request. At 1 Mbps, this is 1752 usecs, or 57.41 ticks. Using 57 ticks - * makes us off ~13 usecs. Since we dont want to actually calculate the - * receive end time tick (this would take too long), we assume the end of - * the advertising PDU is 'now' (we call os_cputime_get32). We dont know - * how much time it will take to service the ISR but if we are more than the - * rx to tx time of the chip we will not be successful transmitting the - * connect request. All this means is that we presume that the peripheral will - * receive the connect request later than we expect but no earlier than - * 13 usecs before (this is important). - * - * The code then attempts to schedule the connection at the - * earliest time although this may not be possible. When the actual - * schedule start time is determined, the central has to determine if this - * time is more than a transmit window offset interval (1.25 msecs). The - * central has to tell the peripheral how many transmit window offsets there are - * from the earliest possible time to when the actual transmit start will - * occur. Later in this function you will see the calculation. The actual - * transmission start has to occur within the transmit window. The transmit - * window interval is in units of 1.25 msecs and has to be at least 1. To - * make things a bit easier (but less power efficient for the peripheral), we - * use a transmit window of 2. We do this because we dont quite know the - * exact start of the transmission and if we are too early or too late we - * could miss the transmit window. A final note: the actual transmission - * start (the anchor point) is sched offset ticks from the schedule start - * time. We dont add this to the calculation when calculating the window - * offset. The reason we dont do this is we want to insure we transmit - * after the window offset we tell the peripheral. For example, say we think - * we are transmitting 1253 usecs from the earliest start. This would cause - * us to send a transmit window offset of 1. Since we are actually - * transmitting earlier than the peripheral thinks we could end up transmitting - * before the window offset. Transmitting later is fine since we have the - * transmit window to do so. Transmitting before is bad, since the peripheral - * wont be listening. We could do better calculation if we wanted to use - * a transmit window of 1 as opposed to 2, but for now we dont care. - */ - dur = ble_ll_tmr_u2t(g_ble_ll_sched_data.sch_ticks_per_period); - adv_rxend = ble_ll_tmr_get(); - if (ble_hdr->rxinfo.channel >= BLE_PHY_NUM_DATA_CHANS) { - /* - * We received packet on advertising channel which means this is a legacy - * PDU on 1 Mbps - we do as described above. - */ - earliest_start = adv_rxend + 57; - } else { - /* - * The calculations are similar as above. - * - * We received packet on data channel which means this is AUX_ADV_IND - * received on secondary adv channel. We can schedule first packet at - * the earliest after "T_IFS + AUX_CONNECT_REQ + transmitWindowDelay". - * AUX_CONNECT_REQ and transmitWindowDelay times vary depending on which - * PHY we received on. - * - */ - if (ble_hdr->rxinfo.phy == BLE_PHY_1M) { - // 150 + 352 + 2500 = 3002us = 98.37 ticks - earliest_start = adv_rxend + 98; - } else if (ble_hdr->rxinfo.phy == BLE_PHY_2M) { - // 150 + 180 + 2500 = 2830us = 92.73 ticks - earliest_start = adv_rxend + 93; - } else if (ble_hdr->rxinfo.phy == BLE_PHY_CODED) { - // 150 + 2896 + 3750 = 6796us = 222.69 ticks - earliest_start = adv_rxend + 223; - } else { - BLE_LL_ASSERT(0); - } - } - earliest_start += MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET) * - BLE_LL_SCHED_USECS_PER_SLOT; - itvl_t = connsm->conn_itvl_ticks; - - /* We have to find a place for this schedule */ - OS_ENTER_CRITICAL(sr); - - /* - * Are there any allocated periods? If not, set epoch start to earliest - * time - */ - if (g_ble_ll_sched_data.sch_num_occ_periods == 0) { - g_ble_ll_sched_data.sch_epoch_start = earliest_start; - cp = 0; - } else { - /* - * Earliest start must occur on period boundary. - * (tse = ticks since epoch) - */ - tpp = g_ble_ll_sched_data.sch_ticks_per_period; - tse = earliest_start - g_ble_ll_sched_data.sch_epoch_start; - np = tse / tpp; - cp = np % BLE_LL_SCHED_PERIODS; - tick_in_period = tse - (np * tpp); - if (tick_in_period != 0) { - ++cp; - if (cp == BLE_LL_SCHED_PERIODS) { - cp = 0; - } - earliest_start += (tpp - tick_in_period); - } - - /* Now find first un-occupied period starting from cp */ - for (i = 0; i < BLE_LL_SCHED_PERIODS; ++i) { - if (g_ble_ll_sched_data.sch_occ_period_mask & (1 << cp)) { - ++cp; - if (cp == BLE_LL_SCHED_PERIODS) { - cp = 0; - } - earliest_start += tpp; - } else { - /* not occupied */ - break; - } - } - /* Should never happen but if it does... */ - if (i == BLE_LL_SCHED_PERIODS) { - OS_EXIT_CRITICAL(sr); - return rc; - } - } - - sch->start_time = earliest_start; - initial_start = earliest_start; - earliest_end = earliest_start + dur; - - if (!ble_ll_sched_insert_if_empty(sch)) { - /* Nothing in schedule. Schedule as soon as possible */ - rc = 0; - connsm->tx_win_off = MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET); - } else { - ble_ll_tmr_stop(&g_ble_ll_sched_timer); - TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) { - /* Set these because overlap function needs them to be set */ - sch->start_time = earliest_start; - sch->end_time = earliest_end; - - /* We can insert if before entry in list */ - if (LL_TMR_LEQ(sch->end_time, entry->start_time)) { - if ((earliest_start - initial_start) <= itvl_t) { - rc = 0; - TAILQ_INSERT_BEFORE(entry, sch, link); - } - break; - } - - /* Check for overlapping events */ - if (ble_ll_sched_is_overlap(sch, entry)) { - /* Earliest start is end of this event since we overlap */ - earliest_start = entry->end_time; - earliest_end = earliest_start + dur; - } - } - - /* Must be able to schedule within one connection interval */ - if (!entry) { - if ((earliest_start - initial_start) <= itvl_t) { - rc = 0; - TAILQ_INSERT_TAIL(&g_ble_ll_sched_q, sch, link); - } - } - - if (!rc) { - /* calculate number of window offsets. Each offset is 1.25 ms */ - sch->enqueued = 1; - /* - * NOTE: we dont add sched offset ticks as we want to under-estimate - * the transmit window slightly since the window size is currently - * 2 when using a 32768 crystal. - */ - dur = ble_ll_tmr_t2u(earliest_start - initial_start); - connsm->tx_win_off = dur / BLE_LL_CONN_TX_OFF_USECS; - } - } - - if (!rc) { - sch->start_time = earliest_start; - sch->end_time = earliest_end; - /* - * Since we have the transmit window to transmit in, we dont need - * to set the anchor point usecs; just transmit to the nearest tick. - */ - connsm->anchor_point = earliest_start + g_ble_ll_sched_offset_ticks; - connsm->anchor_point_usecs = 0; - connsm->ce_end_time = earliest_end; - connsm->period_occ_mask = (1 << cp); - g_ble_ll_sched_data.sch_occ_period_mask |= connsm->period_occ_mask; - ++g_ble_ll_sched_data.sch_num_occ_periods; - } - - - /* Get head of list to restart timer */ - sch = TAILQ_FIRST(&g_ble_ll_sched_q); - ble_ll_rfmgmt_sched_changed(sch); - - OS_EXIT_CRITICAL(sr); - - ble_ll_tmr_start(&g_ble_ll_sched_timer, sch->start_time); - - return rc; -} -#else int ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *ble_hdr, uint8_t pyld_len) @@ -778,7 +491,6 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, return rc; } -#endif /** * Schedules a peripheral connection for the first time. @@ -1388,14 +1100,6 @@ ble_ll_sched_init(void) /* Initialize cputimer for the scheduler */ ble_ll_tmr_init(&g_ble_ll_sched_timer, ble_ll_sched_run, NULL); -#if MYNEWT_VAL(BLE_LL_STRICT_CONN_SCHEDULING) - memset(&g_ble_ll_sched_data, 0, sizeof(struct ble_ll_sched_obj)); - g_ble_ll_sched_data.sch_ticks_per_period = - ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_USECS_PER_PERIOD)); - g_ble_ll_sched_data.sch_ticks_per_epoch = BLE_LL_SCHED_PERIODS * - g_ble_ll_sched_data.sch_ticks_per_period; -#endif - g_ble_ll_sched_q_head_changed = 0; return 0; diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index b565ce444d..8ecdd2c641 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -146,27 +146,6 @@ syscfg.defs: ensure interoperability with such devices set this value to 2 (or more). value: '0' - # Strict scheduling - BLE_LL_STRICT_CONN_SCHEDULING: - description: > - Forces the scheduler on a central to schedule connections in fixed - time intervals called periods. If set to 0, the scheduler is not forced - to do this. If set to 1, the scheduler will only schedule connections at - period boundaries. See comments in ble_ll_sched.h for more details. - value: '0' - - BLE_LL_ADD_STRICT_SCHED_PERIODS: - description: > - The number of additional periods that will be allocated for strict - scheduling. The total # of periods allocated for strict scheduling - will be equal to the number of connections plus this number. - value: '0' - - BLE_LL_USECS_PER_PERIOD: - description: > - The number of usecs per period. - value: '3250' - # The number of random bytes to store BLE_LL_RNG_BUFSIZE: description: > @@ -505,6 +484,18 @@ syscfg.defs: description: Superseded by BLE_LL_CFG_FEAT_PERIPH_INIT_FEAT_XCHG value: 0 defaunt: 1 + BLE_LL_STRICT_CONN_SCHEDULING: + description: Superseded by BLE_LL_CONN_STRICT_SCHED + value: 0 + defunct: 1 + BLE_LL_ADD_STRICT_SCHED_PERIODS: + description: Superseded by BLE_LL_CONN_STRICT_SCHED + value: 0 + defunct: 1 + BLE_LL_USECS_PER_PERIOD: + description: Superseded by BLE_LL_CONN_STRICT_SCHED + value: 0 + defunct: 1 syscfg.vals.BLE_LL_CFG_FEAT_LL_EXT_ADV: BLE_LL_CFG_FEAT_LE_CSA2: 1 From bc196758299f20044f3032342d847a45552e9f84 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 4 Feb 2022 14:03:19 +0100 Subject: [PATCH 0287/1333] nimble/ll: Add conn_move_anchor Central can move anchor to e.g. optimize scheduling. --- .../include/controller/ble_ll_conn.h | 4 +++ .../include/controller/ble_ll_ctrl.h | 3 +- nimble/controller/src/ble_ll_conn.c | 35 ++++++++++++++++--- nimble/controller/src/ble_ll_conn_hci.c | 10 +++--- nimble/controller/src/ble_ll_ctrl.c | 17 ++++----- 5 files changed, 51 insertions(+), 18 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 015bac7597..9075e7e8c0 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -397,6 +397,10 @@ uint8_t ble_ll_conn_calc_dci(struct ble_ll_conn_sm *conn, uint16_t latency); void ble_ll_conn_get_anchor(struct ble_ll_conn_sm *connsm, uint16_t conn_event, uint32_t *anchor, uint8_t *anchor_usecs); +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) +int ble_ll_conn_move_anchor(struct ble_ll_conn_sm *connsm, uint16_t offset); +#endif + struct ble_ll_scan_addr_data; struct ble_ll_scan_pdu_data; diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index ebac33d56c..423d13af3a 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -292,7 +292,8 @@ struct ble_ll_len_req /* API */ struct ble_ll_conn_sm; -void ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc); +void ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc, + void *data); void ble_ll_ctrl_proc_stop(struct ble_ll_conn_sm *connsm, int ctrl_proc); int ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om); void ble_ll_ctrl_chk_proc_start(struct ble_ll_conn_sm *connsm); diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index f3e40a2442..0243577b01 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -416,7 +416,7 @@ ble_ll_conn_chk_phy_upd_start(struct ble_ll_conn_sm *csm) } else { csm->phy_data.req_pref_tx_phys_mask = csm->phy_data.host_pref_tx_phys_mask; csm->phy_data.req_pref_rx_phys_mask = csm->phy_data.host_pref_rx_phys_mask; - ble_ll_ctrl_proc_start(csm, BLE_LL_CTRL_PROC_PHY_UPDATE); + ble_ll_ctrl_proc_start(csm, BLE_LL_CTRL_PROC_PHY_UPDATE, NULL); rc = 0; } @@ -1530,7 +1530,7 @@ ble_ll_conn_auth_pyld_timer_cb(struct ble_npl_event *ev) connsm = (struct ble_ll_conn_sm *)ble_npl_event_get_arg(ev); ble_ll_auth_pyld_tmo_event_send(connsm); - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_LE_PING); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_LE_PING, NULL); ble_ll_conn_auth_pyld_timer_start(connsm); } @@ -1994,6 +1994,32 @@ ble_ll_conn_get_anchor(struct ble_ll_conn_sm *connsm, uint16_t conn_event, } #endif +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) +int +ble_ll_conn_move_anchor(struct ble_ll_conn_sm *connsm, uint16_t offset) +{ + struct ble_ll_conn_params cp = { }; + + BLE_LL_ASSERT(connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL); + + if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ) || + IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_UPDATE)) { + return -1; + } + + /* Keep parameters, we just want to move anchor */ + cp.interval_max = connsm->conn_itvl; + cp.interval_min = connsm->conn_itvl; + cp.latency = connsm->periph_latency; + cp.timeout = connsm->supervision_tmo; + cp.offset0 = offset; + + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_CONN_UPDATE, &cp); + + return 0; +} +#endif + /** * Called to move to the next connection event. * @@ -2363,7 +2389,8 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) * models; for peripheral just assume central will initiate features xchg * if it has some additional features to use. */ - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG, + NULL); break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) @@ -3542,7 +3569,7 @@ ble_ll_conn_set_global_chanmap(uint8_t num_used_chans, const uint8_t *chanmap) /* Perform channel map update */ SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) { if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_CHAN_MAP_UPD); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_CHAN_MAP_UPD, NULL); } } #endif diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 6664458909..cd3deaeffb 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -860,7 +860,7 @@ ble_ll_conn_hci_read_rem_features(const uint8_t *cmdbuf, uint8_t len) } #endif - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG, NULL); } connsm->csmflags.cfbit.pending_hci_rd_features = 1; @@ -980,7 +980,7 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) hcu->handle = handle; /* Start the control procedure */ - ble_ll_ctrl_proc_start(connsm, ctrl_proc); + ble_ll_ctrl_proc_start(connsm, ctrl_proc, NULL); } return rc; @@ -1257,7 +1257,7 @@ ble_ll_conn_hci_rd_rem_ver_cmd(const uint8_t *cmdbuf, uint8_t len) * be queued before the command status. */ if (!connsm->csmflags.cfbit.version_ind_sent) { - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_VERSION_XCHG); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_VERSION_XCHG, NULL); } else { connsm->pending_ctrl_procs |= (1 << BLE_LL_CTRL_PROC_VERSION_XCHG); } @@ -1483,7 +1483,7 @@ ble_ll_conn_hci_le_start_encrypt(const uint8_t *cmdbuf, uint8_t len) connsm->enc_data.host_rand_num = le64toh(cmd->rand); connsm->enc_data.enc_div = le16toh(cmd->div); swap_buf(connsm->enc_data.enc_block.key, cmd->ltk, 16); - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_ENCRYPT); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_ENCRYPT, NULL); rc = BLE_ERR_SUCCESS; } @@ -1633,7 +1633,7 @@ ble_ll_conn_req_peer_sca(const uint8_t *cmdbuf, uint8_t len, return BLE_ERR_CTLR_BUSY; } - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SCA_UPDATE); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SCA_UPDATE, NULL); return 0; } diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 62272d7120..a153a5794e 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1960,7 +1960,7 @@ ble_ll_ctrl_initiate_dle(struct ble_ll_conn_sm *connsm) return; } - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_DATA_LEN_UPD); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_DATA_LEN_UPD, NULL); } static void @@ -2284,7 +2284,7 @@ ble_ll_ctrl_rx_chanmap_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr) * @param ctrl_proc */ static struct os_mbuf * -ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc) +ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc, void *data) { uint8_t len; uint8_t opcode; @@ -2303,7 +2303,7 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc) switch (ctrl_proc) { case BLE_LL_CTRL_PROC_CONN_UPDATE: opcode = BLE_LL_CTRL_CONN_UPDATE_IND; - ble_ll_ctrl_conn_upd_make(connsm, ctrdata, NULL); + ble_ll_ctrl_conn_upd_make(connsm, ctrdata, data); break; case BLE_LL_CTRL_PROC_CHAN_MAP_UPD: opcode = BLE_LL_CTRL_CHANNEL_MAP_REQ; @@ -2452,7 +2452,7 @@ ble_ll_ctrl_terminate_start(struct ble_ll_conn_sm *connsm) BLE_LL_ASSERT(connsm->disconnect_reason != 0); ctrl_proc = BLE_LL_CTRL_PROC_TERMINATE; - om = ble_ll_ctrl_proc_init(connsm, ctrl_proc); + om = ble_ll_ctrl_proc_init(connsm, ctrl_proc, NULL); if (om) { CONN_F_TERMINATE_STARTED(connsm) = 1; @@ -2472,7 +2472,8 @@ ble_ll_ctrl_terminate_start(struct ble_ll_conn_sm *connsm) * @param connsm Pointer to connection state machine. */ void -ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc) +ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc, + void *data) { struct os_mbuf *om; @@ -2481,7 +2482,7 @@ ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc) om = NULL; if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_IDLE) { /* Initiate the control procedure. */ - om = ble_ll_ctrl_proc_init(connsm, ctrl_proc); + om = ble_ll_ctrl_proc_init(connsm, ctrl_proc, data); if (om) { /* Set the current control procedure */ connsm->cur_ctrl_proc = ctrl_proc; @@ -2548,7 +2549,7 @@ ble_ll_ctrl_chk_proc_start(struct ble_ll_conn_sm *connsm) ble_ll_hci_ev_rd_rem_ver(connsm, BLE_ERR_SUCCESS); CLR_PENDING_CTRL_PROC(connsm, i); } else { - ble_ll_ctrl_proc_start(connsm, i); + ble_ll_ctrl_proc_start(connsm, i, NULL); break; } } @@ -2863,7 +2864,7 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) if (restart_encryption) { /* XXX: what happens if this fails? Meaning we cant allocate mbuf? */ - ble_ll_ctrl_proc_init(connsm, BLE_LL_CTRL_PROC_ENCRYPT); + ble_ll_ctrl_proc_init(connsm, BLE_LL_CTRL_PROC_ENCRYPT, NULL); } #endif } From 22f5201717bd5709d65f371aae775bbb8bc77935 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 3 Feb 2022 23:40:45 +0100 Subject: [PATCH 0288/1333] nimble/ll: Add new connection strict scheduling (css) This adds new connection strict scheduling code. The idea is based on old code, but it was rewritten from scratch to allow more control over scheduling. Scheduling policy in css mode is defined by slot duration and number of slots per period (which implicitly defined period duration). Each connection in central role is only scheduled on slot boundary and has connection interval equal to period duration. This means there can be up to number-of-slots connection in central role established. The main difference to the previous implementation is more control over slot allocation for each connection. In particular, it's possible to assing an arbitrary slot index to each connection and thus adjust max connection event for each connection, depending on requirements. --- .../include/controller/ble_ll_conn.h | 6 + .../include/controller/ble_ll_sched.h | 8 + nimble/controller/src/ble_ll_conn.c | 186 +++++++++++++++++- nimble/controller/src/ble_ll_conn_hci.c | 47 +++++ nimble/controller/src/ble_ll_conn_priv.h | 13 ++ nimble/controller/src/ble_ll_ctrl.c | 10 + nimble/controller/src/ble_ll_sched.c | 138 ++++++++++++- nimble/controller/syscfg.yml | 21 ++ 8 files changed, 417 insertions(+), 12 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 9075e7e8c0..133824ba34 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -351,6 +351,12 @@ struct ble_ll_conn_sm uint16_t sync_transfer_skip; uint32_t sync_transfer_sync_timeout; #endif + +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + uint16_t css_slot_idx; + uint16_t css_slot_idx_pending; + uint8_t css_period_idx; +#endif }; /* Flags */ diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index b3f7d19fdf..a79262a78b 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -175,6 +175,14 @@ void ble_ll_sched_stop(void); int ble_ll_sched_dtm(struct ble_ll_sched_item *sch); #endif +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) +void ble_ll_sched_css_set_params(uint32_t slot_us, uint32_t period_slots); +void ble_ll_sched_css_set_conn_anchor(struct ble_ll_conn_sm *connsm); +uint32_t ble_ll_sched_css_get_slot_us(void); +uint32_t ble_ll_sched_css_get_period_slots(void); +uint32_t ble_ll_sched_css_get_conn_interval_us(void); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 0243577b01..6bd97585e7 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -46,6 +46,10 @@ extern void bletest_completed_pkt(uint16_t handle); #endif +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) +struct ble_ll_conn_sm *g_ble_ll_conn_css_ref; +#endif + /* XXX TODO * 1) I think if we are initiating and we already have a connection with * a device that we will still try and connect to it. Fix this. @@ -388,6 +392,97 @@ ble_ll_conn_cth_flow_process_cmd(const uint8_t *cmdbuf) } #endif + +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) +static uint16_t g_ble_ll_conn_css_next_slot = BLE_LL_CONN_CSS_NO_SLOT; + +void +ble_ll_conn_css_set_next_slot(uint16_t slot_idx) +{ + g_ble_ll_conn_css_next_slot = slot_idx; +} + +uint16_t +ble_ll_conn_css_get_next_slot(void) +{ + struct ble_ll_conn_sm *connsm; + uint16_t slot_idx = 0; + + if (g_ble_ll_conn_css_next_slot != BLE_LL_CONN_CSS_NO_SLOT) { + return g_ble_ll_conn_css_next_slot; + } + + /* CSS connections are sorted in active conn list so just need to find 1st + * free value. + */ + SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) { + if ((connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) && + (connsm->css_slot_idx != slot_idx) && + (connsm->css_slot_idx_pending != slot_idx)) { + break; + } + slot_idx++; + } + + if (slot_idx >= ble_ll_sched_css_get_period_slots()) { + slot_idx = BLE_LL_CONN_CSS_NO_SLOT; + } + + return slot_idx; +} + +int +ble_ll_conn_css_is_slot_busy(uint16_t slot_idx) +{ + struct ble_ll_conn_sm *connsm; + + SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) { + if ((connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) && + ((connsm->css_slot_idx == slot_idx) || + (connsm->css_slot_idx_pending == slot_idx))) { + return 1; + } + } + + return 0; +} + +int +ble_ll_conn_css_move(struct ble_ll_conn_sm *connsm, uint16_t slot_idx) +{ + int16_t slot_diff; + uint32_t offset; + int rc; + + /* Assume connsm and slot_idx are valid */ + BLE_LL_ASSERT(connsm->conn_state != BLE_LL_CONN_STATE_IDLE); + BLE_LL_ASSERT(connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL); + BLE_LL_ASSERT((slot_idx < ble_ll_sched_css_get_period_slots()) || + (slot_idx != BLE_LL_CONN_CSS_NO_SLOT)); + + slot_diff = slot_idx - connsm->css_slot_idx; + + if (slot_diff > 0) { + offset = slot_diff * ble_ll_sched_css_get_slot_us() / + BLE_LL_CONN_ITVL_USECS; + } else { + offset = (ble_ll_sched_css_get_period_slots() + slot_diff) * + ble_ll_sched_css_get_slot_us() / BLE_LL_CONN_ITVL_USECS; + } + + if (offset >= 0xffff) { + return -1; + } + + rc = ble_ll_conn_move_anchor(connsm, offset); + if (!rc) { + connsm->css_slot_idx_pending = slot_idx; + } + + return rc; +} +#endif + #if (BLE_LL_BT5_PHY_SUPPORTED == 1) /** * Checks to see if we should start a PHY update procedure @@ -1720,6 +1815,10 @@ void ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) { struct ble_ll_conn_global_params *conn_params; +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + struct ble_ll_conn_sm *connsm_css_prev = NULL; + struct ble_ll_conn_sm *connsm_css; +#endif /* Reset following elements */ connsm->csmflags.conn_flags = 0; @@ -1813,7 +1912,35 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) #endif /* Add to list of active connections */ +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + /* We will insert sorted by css_slot_idx to make finding free slot + * easier. + */ + SLIST_FOREACH(connsm_css, &g_ble_ll_conn_active_list, act_sle) { + if ((connsm_css->conn_role == BLE_LL_CONN_ROLE_CENTRAL) && + (connsm_css->css_slot_idx > connsm->css_slot_idx)) { + if (connsm_css_prev) { + SLIST_INSERT_AFTER(connsm_css_prev, connsm, act_sle); + } + break; + } + connsm_css_prev = connsm_css; + } + + if (!connsm_css_prev) { + /* List was empty or need to insert before 1st connection */ + SLIST_INSERT_HEAD(&g_ble_ll_conn_active_list, connsm, act_sle); + } else if (!connsm_css) { + /* Insert at the end of list */ + SLIST_INSERT_AFTER(connsm_css_prev, connsm, act_sle); + } + } else { + SLIST_INSERT_HEAD(&g_ble_ll_conn_active_list, connsm, act_sle); + } +#else SLIST_INSERT_HEAD(&g_ble_ll_conn_active_list, connsm, act_sle); +#endif } void @@ -1903,6 +2030,20 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err) /* Remove from the active connection list */ SLIST_REMOVE(&g_ble_ll_conn_active_list, connsm, ble_ll_conn_sm, act_sle); +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + /* If current connection was reference for CSS, we need to find another + * one. It does not matter which one we'll pick. + */ + if (connsm == g_ble_ll_conn_css_ref) { + SLIST_FOREACH(g_ble_ll_conn_css_ref, &g_ble_ll_conn_active_list, + act_sle) { + if (g_ble_ll_conn_css_ref->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + break; + } + } + } +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) ble_ll_conn_cth_flow_free_credit(connsm, connsm->cth_flow_pending); #endif @@ -2039,6 +2180,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) uint32_t max_ww; #endif struct ble_ll_conn_upd_req *upd; + uint8_t skip_anchor_calc = 0; uint32_t usecs; /* XXX: deal with connection request procedure here as well */ @@ -2083,15 +2225,32 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) } connsm->event_cntr += latency; - /* Set next connection event start time */ - /* We can use pre-calculated values for one interval if latency is 1. */ - if (latency == 1) { - connsm->anchor_point += connsm->conn_itvl_ticks; - ble_ll_tmr_add_u(&connsm->anchor_point, &connsm->anchor_point_usecs, - connsm->conn_itvl_usecs); - } else { - ble_ll_tmr_add(&connsm->anchor_point, &connsm->anchor_point_usecs, - itvl); +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + connsm->css_period_idx += latency; + + /* If this is non-reference connection, we set anchor from reference + * instead of calculating manually. + */ + if (g_ble_ll_conn_css_ref != connsm) { + ble_ll_sched_css_set_conn_anchor(connsm); + skip_anchor_calc = 1; + } + } +#endif + + if (!skip_anchor_calc) { + /* Calculate next anchor point for connection. + * We can use pre-calculated values for one interval if latency is 1. + */ + if (latency == 1) { + connsm->anchor_point += connsm->conn_itvl_ticks; + ble_ll_tmr_add_u(&connsm->anchor_point, &connsm->anchor_point_usecs, + connsm->conn_itvl_usecs); + } else { + ble_ll_tmr_add(&connsm->anchor_point, &connsm->anchor_point_usecs, + itvl); + } } /* @@ -2134,6 +2293,15 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) /* Reset the starting point of the connection supervision timeout */ connsm->last_rxd_pdu_cputime = connsm->anchor_point; +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + BLE_LL_ASSERT(connsm->css_slot_idx_pending != + BLE_LL_CONN_CSS_NO_SLOT); + connsm->css_slot_idx = connsm->css_slot_idx_pending; + connsm->css_slot_idx_pending = BLE_LL_CONN_CSS_NO_SLOT; + } +#endif + /* Reset update scheduled flag */ connsm->csmflags.cfbit.conn_update_sched = 0; } diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index cd3deaeffb..ac212550f8 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -513,6 +513,9 @@ ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len) struct ble_ll_conn_sm *connsm; uint16_t conn_itvl_min; uint16_t conn_itvl_max; +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + uint16_t css_slot_idx; +#endif int rc; if (len < sizeof(*cmd)) { @@ -529,6 +532,14 @@ ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_CMD_DISALLOWED; } + +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + css_slot_idx = ble_ll_conn_css_get_next_slot(); + if (css_slot_idx == BLE_LL_CONN_CSS_NO_SLOT) { + return BLE_ERR_MEM_CAPACITY; + } +#endif + cc_scan.own_addr_type = cmd->own_addr_type; cc_scan.filter_policy = cmd->filter_policy; if (cc_scan.filter_policy == 0) { @@ -560,7 +571,15 @@ ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + cc_params.conn_itvl = ble_ll_sched_css_get_conn_interval_us(); + if ((cc_params.conn_itvl < conn_itvl_min) || + (cc_params.conn_itvl > conn_itvl_max)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } +#else cc_params.conn_itvl = conn_itvl_max; +#endif cc_params.conn_latency = le16toh(cmd->conn_latency); cc_params.supervision_timeout = le16toh(cmd->tmo); cc_params.min_ce_len = le16toh(cmd->min_ce); @@ -582,6 +601,11 @@ ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_CONN_LIMIT; } +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + connsm->css_slot_idx = css_slot_idx; + connsm->css_slot_idx_pending = BLE_LL_CONN_CSS_NO_SLOT; +#endif + /* Initialize state machine in central role and start state machine */ ble_ll_conn_central_init(connsm, &cc_scan, &cc_params); ble_ll_conn_sm_new(connsm); @@ -640,7 +664,15 @@ ble_ll_conn_hci_ext_create_parse_params(const struct conn_params *params, return BLE_ERR_INV_HCI_CMD_PARMS; } +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + cc_params->conn_itvl = ble_ll_sched_css_get_conn_interval_us(); + if ((cc_params->conn_itvl < conn_itvl_min) || + (cc_params->conn_itvl > conn_itvl_max)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } +#else cc_params->conn_itvl = conn_itvl_max; +#endif cc_params->conn_latency = le16toh(params->conn_latency); cc_params->supervision_timeout = le16toh(params->supervision_timeout); cc_params->min_ce_len = le16toh(params->min_ce); @@ -699,6 +731,9 @@ ble_ll_conn_hci_ext_create(const uint8_t *cmdbuf, uint8_t len) struct ble_ll_conn_create_params *cc_params_fb; struct ble_ll_conn_sm *connsm; const struct init_phy *init_phy; +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + uint16_t css_slot_idx; +#endif int rc; /* validate length */ @@ -717,6 +752,13 @@ ble_ll_conn_hci_ext_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_CMD_DISALLOWED; } +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + css_slot_idx = ble_ll_conn_css_get_next_slot(); + if (css_slot_idx == BLE_LL_CONN_CSS_NO_SLOT) { + return BLE_ERR_MEM_CAPACITY; + } +#endif + cc_scan.own_addr_type = cmd->own_addr_type; cc_scan.filter_policy = cmd->filter_policy; if (cc_scan.filter_policy == 0) { @@ -770,6 +812,11 @@ ble_ll_conn_hci_ext_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_CONN_LIMIT; } +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + connsm->css_slot_idx = css_slot_idx; + connsm->css_slot_idx_pending = BLE_LL_CONN_CSS_NO_SLOT; +#endif + /* Initialize state machine in central role and start state machine */ ble_ll_conn_central_init(connsm, &cc_scan, &g_ble_ll_conn_create_sm.params[0]); diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index c51aef90eb..3d49f4983a 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -59,6 +59,10 @@ extern "C" { #define BLE_LL_CONN_DEF_AUTH_PYLD_TMO (3000) #define BLE_LL_CONN_AUTH_PYLD_OS_TMO(x) ble_npl_time_ms_to_ticks32((x) * 10) +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) +#define BLE_LL_CONN_CSS_NO_SLOT (UINT16_MAX) +#endif + /* Global Link Layer connection parameters */ struct ble_ll_conn_global_params { @@ -127,6 +131,7 @@ struct ble_ll_conn_create_sm { }; extern struct ble_ll_conn_create_sm g_ble_ll_conn_create_sm; +extern struct ble_ll_conn_sm *g_ble_ll_conn_css_ref; /* Generic interface */ struct ble_ll_len_req; @@ -250,6 +255,14 @@ int ble_ll_set_sync_transfer_params(const uint8_t *cmdbuf, uint8_t len, int ble_ll_set_default_sync_transfer_params(const uint8_t *cmdbuf, uint8_t len); #endif +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) +void ble_ll_conn_css_set_next_slot(uint16_t slot_idx); +uint16_t ble_ll_conn_css_get_next_slot(void); +int ble_ll_conn_css_is_slot_busy(uint16_t slot_idx); +int ble_ll_conn_css_move(struct ble_ll_conn_sm *connsm, uint16_t slot_idx); + +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index a153a5794e..5212cb5c7a 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -2106,6 +2106,16 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, return BLE_ERR_MAX; } +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + /* Reject any attempts to change connection parameters by peripheral */ + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + rsp_opcode = BLE_LL_CTRL_REJECT_IND_EXT; + rspbuf[1] = BLE_LL_CTRL_CONN_PARM_REQ; + rspbuf[2] = BLE_ERR_UNSUPPORTED; + return rsp_opcode; + } +#endif + /* XXX: remember to deal with this on the central: if the peripheral has * initiated a procedure we may have received its connection parameter * update request and have signaled the host with an event. If that diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 14c8753d00..eb9ed8bfcb 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -45,6 +45,22 @@ int32_t g_ble_ll_sched_max_late; int32_t g_ble_ll_sched_max_early; #endif +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) +struct ble_ll_sched_css { + uint32_t slot_us; + uint32_t period_slots; + uint32_t period_anchor_ticks; + uint8_t period_anchor_rem_us; + uint8_t period_anchor_idx; + uint16_t period_anchor_slot_idx; +}; + +static struct ble_ll_sched_css g_ble_ll_sched_css = { + .slot_us = MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_SLOT_US), + .period_slots = MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_PERIOD_SLOTS), +}; +#endif + typedef int (* ble_ll_sched_preempt_cb_t)(struct ble_ll_sched_item *sch, struct ble_ll_sched_item *item); @@ -304,6 +320,9 @@ ble_ll_sched_overlaps_current(struct ble_ll_sched_item *sch) int ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) { +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + struct ble_ll_sched_css *css = &g_ble_ll_sched_css; +#endif struct ble_ll_sched_item *sch; #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) uint32_t usecs; @@ -349,6 +368,17 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm) } rc = ble_ll_sched_insert(sch, 0, preempt_any_except_conn); +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + /* Store new anchor point for strict scheduling if successfully scheduled + * reference connection. + */ + if ((rc == 0) && (connsm == g_ble_ll_conn_css_ref)) { + css->period_anchor_idx = connsm->css_period_idx; + css->period_anchor_slot_idx = connsm->css_slot_idx; + css->period_anchor_ticks = connsm->anchor_point; + css->period_anchor_rem_us = connsm->anchor_point_usecs; + } +#endif OS_EXIT_CRITICAL(sr); @@ -372,10 +402,16 @@ int ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *ble_hdr, uint8_t pyld_len) { +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + struct ble_ll_sched_css *css = &g_ble_ll_sched_css; + struct ble_ll_conn_sm *connsm_ref; +#endif struct ble_ll_sched_item *sch; uint32_t orig_start_time; uint32_t earliest_start; +#if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) uint32_t min_win_offset; +#endif uint32_t max_delay; uint32_t adv_rxend; os_sr_t sr; @@ -457,20 +493,60 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, } } + orig_start_time = earliest_start - g_ble_ll_sched_offset_ticks; + +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + uint8_t rem_us; + + OS_ENTER_CRITICAL(sr); + + connsm_ref = g_ble_ll_conn_css_ref; + if (!connsm_ref) { + g_ble_ll_conn_css_ref = connsm; + + css->period_anchor_slot_idx = connsm->css_slot_idx; + css->period_anchor_idx = 0; + css->period_anchor_ticks = adv_rxend; + css->period_anchor_rem_us = 0; + + connsm->css_period_idx = 1; + } else { + connsm->css_period_idx = css->period_anchor_idx + 1; + } + + ble_ll_sched_css_set_conn_anchor(connsm); + + sch->start_time = connsm->anchor_point - g_ble_ll_sched_offset_ticks; + sch->remainder = connsm->anchor_point_usecs; + + OS_EXIT_CRITICAL(sr); + + sch->end_time = sch->start_time; + rem_us = sch->remainder; + ble_ll_tmr_add(&sch->end_time, &rem_us, ble_ll_sched_css_get_period_slots()); + if (rem_us == 0) { + sch->end_time--; + } + + max_delay = 0; + +#else + sch->start_time = earliest_start - g_ble_ll_sched_offset_ticks; sch->end_time = earliest_start + ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * BLE_LL_SCHED_USECS_PER_SLOT); - orig_start_time = sch->start_time; - min_win_offset = ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET) * BLE_LL_SCHED_USECS_PER_SLOT); sch->start_time += min_win_offset; sch->end_time += min_win_offset; + sch->remainder = 0; max_delay = connsm->conn_itvl_ticks - min_win_offset; +#endif + OS_ENTER_CRITICAL(sr); rc = ble_ll_sched_insert(sch, max_delay, preempt_none); @@ -480,7 +556,7 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, BLE_LL_CONN_TX_OFF_USECS; connsm->anchor_point = sch->start_time + g_ble_ll_sched_offset_ticks; - connsm->anchor_point_usecs = 0; + connsm->anchor_point_usecs = sch->remainder; connsm->ce_end_time = sch->end_time; } @@ -1104,3 +1180,59 @@ ble_ll_sched_init(void) return 0; } + +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) +void +ble_ll_sched_css_set_params(uint32_t slot_us, uint32_t period_slots) +{ + g_ble_ll_sched_css.slot_us = slot_us; + g_ble_ll_sched_css.period_slots = period_slots; +} + +void +ble_ll_sched_css_set_conn_anchor(struct ble_ll_conn_sm *connsm) +{ + struct ble_ll_sched_css *css = &g_ble_ll_sched_css; + int8_t period_diff; + int16_t slot_diff; + int32_t diff; + + period_diff = connsm->css_period_idx - css->period_anchor_idx; + slot_diff = connsm->css_slot_idx - css->period_anchor_slot_idx; + + diff = (period_diff * ble_ll_sched_css_get_period_slots() + slot_diff) * + ble_ll_sched_css_get_slot_us(); + + connsm->anchor_point = css->period_anchor_ticks; + connsm->anchor_point_usecs = css->period_anchor_rem_us; + + if (diff < 0) { + ble_ll_tmr_sub(&connsm->anchor_point, &connsm->anchor_point_usecs, + -diff); + } else if (diff > 0) { + ble_ll_tmr_add(&connsm->anchor_point, &connsm->anchor_point_usecs, + diff); + } +} + +inline uint32_t +ble_ll_sched_css_get_slot_us(void) +{ + return g_ble_ll_sched_css.slot_us; +} + +inline uint32_t +ble_ll_sched_css_get_period_slots(void) +{ + return g_ble_ll_sched_css.period_slots; +} + +inline uint32_t +ble_ll_sched_css_get_conn_interval_us(void) +{ + return ble_ll_sched_css_get_period_slots() * + ble_ll_sched_css_get_slot_us() / + BLE_LL_CONN_ITVL_USECS; +} + +#endif diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 8ecdd2c641..de6b5ea830 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -146,6 +146,27 @@ syscfg.defs: ensure interoperability with such devices set this value to 2 (or more). value: '0' + BLE_LL_CONN_STRICT_SCHED: + description: > + Enable connection strict scheduling (css). + In css mode, connections in central role are scheduled in fixed time + intervals called periods. Each period is divided into an arbitrary + number of slots and each connection anchor point is always scheduled + at slot boundary. This means (assuming only central connections are + active) it's possible to reliably schedule up to number-of-slots + connections each at period-duration interval, each connection will + be allocated at least one slot in each connection event. + value: 0 + BLE_LL_CONN_STRICT_SCHED_SLOT_US: + description: > + Slot duration in microseconds. Shall be multiply of 1250us. + value: 3750 + BLE_LL_CONN_STRICT_SCHED_PERIOD_SLOTS: + description: > + Number of slots per period. Duration of slot determines connection + interval used for each connection in central role. + value: 8 + # The number of random bytes to store BLE_LL_RNG_BUFSIZE: description: > From bf275cf3bacf934bd2fe676fce218ec4613246e5 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 4 Feb 2022 01:12:29 +0100 Subject: [PATCH 0289/1333] nimble/ll: Add HCI VS command to control css This adds hci vs command to control css parameters. The command has few sub-commands that allow to: - set slot duration and slots per period parameter - set slot allocation for next requested connection - set slot allocation for existing connection Reconfiguration of css parameters can only be done only if there are no active connections so we do not need to bother with moving existing connections around. --- nimble/controller/src/ble_ll_hci_vs.c | 133 ++++++++++++++++++++++++++ nimble/controller/syscfg.yml | 3 + nimble/include/nimble/hci_common.h | 22 +++++ 3 files changed, 158 insertions(+) diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index f2057ea428..5049b3994c 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -134,11 +134,144 @@ ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, return BLE_ERR_SUCCESS; } + +#if MYNEWT_VAL(BLE_LL_HCI_VS_CONN_STRICT_SCHED) +static int +ble_ll_hci_vs_css_configure(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_vs_css_configure_cp *cmd = (const void *)cmdbuf; + uint32_t slot_us; + uint32_t period_slots; + + if (cmdlen != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (!SLIST_EMPTY(&g_ble_ll_conn_active_list)) { + return BLE_ERR_CTLR_BUSY; + } + + slot_us = le32toh(cmd->slot_us); + period_slots = le32toh(cmd->period_slots); + + if (slot_us % BLE_LL_CONN_ITVL_USECS) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if ((slot_us == 0) || (period_slots == 0)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + ble_ll_sched_css_set_params(slot_us, period_slots); + + return BLE_ERR_SUCCESS; +} + +static int +ble_ll_hci_vs_css_set_next_slot(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_vs_css_set_next_slot_cp *cmd = (const void *)cmdbuf; + uint16_t slot_idx; + + if (cmdlen != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + slot_idx = le16toh(cmd->slot_idx); + if ((slot_idx >= ble_ll_sched_css_get_period_slots()) && + (slot_idx != BLE_LL_CONN_CSS_NO_SLOT)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (ble_ll_conn_css_is_slot_busy(slot_idx)) { + return BLE_ERR_CTLR_BUSY; + } + + ble_ll_conn_css_set_next_slot(slot_idx); + + return BLE_ERR_SUCCESS; +} + +static int +ble_ll_hci_vs_css_set_conn_slot(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_vs_css_set_conn_slot_cp *cmd = (const void *)cmdbuf; + struct ble_ll_conn_sm *connsm; + uint16_t conn_handle; + uint16_t slot_idx; + + if (cmdlen != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + slot_idx = le16toh(cmd->slot_idx); + if ((slot_idx >= ble_ll_sched_css_get_period_slots()) && + (slot_idx != BLE_LL_CONN_CSS_NO_SLOT)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (ble_ll_conn_css_is_slot_busy(slot_idx)) { + return BLE_ERR_CTLR_BUSY; + } + + conn_handle = le16toh(cmd->conn_handle); + connsm = ble_ll_conn_find_active_conn(conn_handle); + if (!connsm) { + return BLE_ERR_UNK_CONN_ID; + } + + if (connsm->css_slot_idx_pending != BLE_LL_CONN_CSS_NO_SLOT) { + return BLE_ERR_DIFF_TRANS_COLL; + } + + if (connsm->css_slot_idx == slot_idx) { + return BLE_ERR_CMD_DISALLOWED; + } + + if (ble_ll_conn_css_move(connsm, slot_idx) < 0) { + return BLE_ERR_CTLR_BUSY; + } + + return BLE_ERR_SUCCESS; +} + +static int +ble_ll_hci_vs_css(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_vs_css_cp *cmd = (const void *)cmdbuf; + + if (cmdlen < sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + *rsplen = 0; + + switch (cmd->opcode) { + case BLE_HCI_VS_CSS_OP_CONFIGURE: + return ble_ll_hci_vs_css_configure(cmdbuf, cmdlen, rspbuf, rsplen); + case BLE_HCI_VS_CSS_OP_SET_NEXT_SLOT: + return ble_ll_hci_vs_css_set_next_slot(cmdbuf, cmdlen, rspbuf, rsplen); + case BLE_HCI_VS_CSS_OP_SET_CONN_SLOT: + return ble_ll_hci_vs_css_set_conn_slot(cmdbuf, cmdlen, rspbuf, rsplen); + } + + return BLE_ERR_INV_HCI_CMD_PARMS; +} +#endif + static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_RD_STATIC_ADDR, ble_ll_hci_vs_rd_static_addr), BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_TX_PWR, ble_ll_hci_vs_set_tx_power), +#if MYNEWT_VAL(BLE_LL_HCI_VS_CONN_STRICT_SCHED) + BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_CSS, + ble_ll_hci_vs_css), +#endif }; static struct ble_ll_hci_vs_cmd * diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index de6b5ea830..8f08dd7886 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -363,6 +363,9 @@ syscfg.defs: description: > Enables support for vendor-specific HCI commands. value: MYNEWT_VAL(BLE_HCI_VS) + BLE_LL_HCI_VS_CONN_STRICT_SCHED: + description: xxx + value: 0 BLE_LL_HCI_VS_EVENT_ON_ASSERT: description: > diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 32d06b60fb..8faebe479e 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1079,6 +1079,28 @@ struct ble_hci_vs_set_tx_pwr_rp { int8_t tx_power; } __attribute__((packed)); +#define BLE_HCI_OCF_VS_CSS (0x0003) +struct ble_hci_vs_css_cp { + uint8_t opcode; +} __attribute__((packed)); +#define BLE_HCI_VS_CSS_OP_CONFIGURE 0x01 +struct ble_hci_vs_css_configure_cp { + uint8_t opcode; + uint32_t slot_us; + uint32_t period_slots; +} __attribute__((packed)); +#define BLE_HCI_VS_CSS_OP_SET_NEXT_SLOT 0x02 +struct ble_hci_vs_css_set_next_slot_cp { + uint8_t opcode; + uint16_t slot_idx; +} __attribute__((packed)); +#define BLE_HCI_VS_CSS_OP_SET_CONN_SLOT 0x03 +struct ble_hci_vs_css_set_conn_slot_cp { + uint8_t opcode; + uint16_t conn_handle; + uint16_t slot_idx; +} __attribute__((packed)); + /* Command Specific Definitions */ /* --- Set controller to host flow control (OGF 0x03, OCF 0x0031) --- */ #define BLE_HCI_CTLR_TO_HOST_FC_OFF (0) From 8e7cbbba3a2a90f08176274bb3f4d35eeb148090 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 4 Feb 2022 20:43:01 +0100 Subject: [PATCH 0290/1333] nimble/ll: Add fixed css option In fixed mode css always uses slot duration and slots per period configured with syscfg, configuration hci vs command is not included. This allows for some compile-time optimizations. --- .../include/controller/ble_ll_sched.h | 23 +++++++++++++++++++ nimble/controller/src/ble_ll_hci_vs.c | 4 ++++ nimble/controller/src/ble_ll_sched.c | 8 +++++++ nimble/controller/syscfg.yml | 6 +++++ 4 files changed, 41 insertions(+) diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index a79262a78b..a65b5d4307 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -176,12 +176,35 @@ int ble_ll_sched_dtm(struct ble_ll_sched_item *sch); #endif #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) +#if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) void ble_ll_sched_css_set_params(uint32_t slot_us, uint32_t period_slots); +#endif void ble_ll_sched_css_set_conn_anchor(struct ble_ll_conn_sm *connsm); +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) +static inline uint32_t +ble_ll_sched_css_get_slot_us(void) +{ + return MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_SLOT_US); +} + +static inline uint32_t +ble_ll_sched_css_get_period_slots(void) +{ + return MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_PERIOD_SLOTS); +} + +static inline uint32_t +ble_ll_sched_css_get_conn_interval_us(void) +{ + return ble_ll_sched_css_get_period_slots() * + ble_ll_sched_css_get_slot_us() / 1250; +} +#else uint32_t ble_ll_sched_css_get_slot_us(void); uint32_t ble_ll_sched_css_get_period_slots(void); uint32_t ble_ll_sched_css_get_conn_interval_us(void); #endif +#endif #ifdef __cplusplus } diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index 5049b3994c..2b3909206d 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -136,6 +136,7 @@ ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, #if MYNEWT_VAL(BLE_LL_HCI_VS_CONN_STRICT_SCHED) +#if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) static int ble_ll_hci_vs_css_configure(const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen) @@ -167,6 +168,7 @@ ble_ll_hci_vs_css_configure(const uint8_t *cmdbuf, uint8_t cmdlen, return BLE_ERR_SUCCESS; } +#endif static int ble_ll_hci_vs_css_set_next_slot(const uint8_t *cmdbuf, uint8_t cmdlen, @@ -251,8 +253,10 @@ ble_ll_hci_vs_css(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, *rsplen = 0; switch (cmd->opcode) { +#if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) case BLE_HCI_VS_CSS_OP_CONFIGURE: return ble_ll_hci_vs_css_configure(cmdbuf, cmdlen, rspbuf, rsplen); +#endif case BLE_HCI_VS_CSS_OP_SET_NEXT_SLOT: return ble_ll_hci_vs_css_set_next_slot(cmdbuf, cmdlen, rspbuf, rsplen); case BLE_HCI_VS_CSS_OP_SET_CONN_SLOT: diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index eb9ed8bfcb..40139a807a 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -47,8 +47,10 @@ int32_t g_ble_ll_sched_max_early; #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) struct ble_ll_sched_css { +#if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) uint32_t slot_us; uint32_t period_slots; +#endif uint32_t period_anchor_ticks; uint8_t period_anchor_rem_us; uint8_t period_anchor_idx; @@ -56,8 +58,10 @@ struct ble_ll_sched_css { }; static struct ble_ll_sched_css g_ble_ll_sched_css = { +#if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) .slot_us = MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_SLOT_US), .period_slots = MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_PERIOD_SLOTS), +#endif }; #endif @@ -1182,12 +1186,14 @@ ble_ll_sched_init(void) } #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) +#if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) void ble_ll_sched_css_set_params(uint32_t slot_us, uint32_t period_slots) { g_ble_ll_sched_css.slot_us = slot_us; g_ble_ll_sched_css.period_slots = period_slots; } +#endif void ble_ll_sched_css_set_conn_anchor(struct ble_ll_conn_sm *connsm) @@ -1215,6 +1221,7 @@ ble_ll_sched_css_set_conn_anchor(struct ble_ll_conn_sm *connsm) } } +#if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) inline uint32_t ble_ll_sched_css_get_slot_us(void) { @@ -1234,5 +1241,6 @@ ble_ll_sched_css_get_conn_interval_us(void) ble_ll_sched_css_get_slot_us() / BLE_LL_CONN_ITVL_USECS; } +#endif #endif diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 8f08dd7886..ec1ef935bc 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -157,6 +157,12 @@ syscfg.defs: connections each at period-duration interval, each connection will be allocated at least one slot in each connection event. value: 0 + BLE_LL_CONN_STRICT_SCHED_FIXED: + description: > + Enable fixed mode for connection strict scheduling, i.e. slot duration + and slots per period values are fixed to syscfg values and cannot + be changed in runtime. This allows for some compile-time optimizations. + value: 0 BLE_LL_CONN_STRICT_SCHED_SLOT_US: description: > Slot duration in microseconds. Shall be multiply of 1250us. From ee4735d358a9ec4874d75959af5293fc521f4584 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 21 Feb 2022 23:27:02 +0100 Subject: [PATCH 0291/1333] nimble/ll: Fix InitA handling in connection requests As per Core 5.3, Vol 6, Part B, 6.4: > The Link Layer should not set the InitA field to the same value as > the TargetA field in the received advertising PDU. This was apparently omitted during init refactor, so need to bring it back. Also simplify generating InitA in case we use RPA and TargetA is not present - we do not need to lookup for an item in RL since this is already done by filtering code and we can just use rpa_index. --- .../include/controller/ble_ll_conn.h | 7 +- nimble/controller/src/ble_ll_conn.c | 84 +++++++++---------- 2 files changed, 45 insertions(+), 46 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 133824ba34..70d6b4918f 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -413,10 +413,9 @@ struct ble_ll_scan_pdu_data; uint8_t ble_ll_conn_tx_connect_ind_pducb(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte); void ble_ll_conn_prepare_connect_ind(struct ble_ll_conn_sm *connsm, - struct ble_ll_scan_pdu_data *pdu_data, - uint8_t adva_type, uint8_t *adva, - uint8_t inita_type, uint8_t *inita, - int rpa_index, uint8_t channel); + struct ble_ll_scan_pdu_data *pdu_data, + struct ble_ll_scan_addr_data *addrd, + uint8_t channel); /* Send CONNECT_IND/AUX_CONNECT_REQ */ int ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu, diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 6bd97585e7..df015e9d08 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2740,15 +2740,12 @@ ble_ll_conn_event_end(struct ble_npl_event *ev) void ble_ll_conn_prepare_connect_ind(struct ble_ll_conn_sm *connsm, struct ble_ll_scan_pdu_data *pdu_data, - uint8_t adva_type, uint8_t *adva, - uint8_t inita_type, uint8_t *inita, - int rpa_index, uint8_t channel) + struct ble_ll_scan_addr_data *addrd, + uint8_t channel) { uint8_t hdr; uint8_t *addr; - #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - int is_rpa; struct ble_ll_resolv_entry *rl; #endif @@ -2761,19 +2758,45 @@ ble_ll_conn_prepare_connect_ind(struct ble_ll_conn_sm *connsm, } #endif - if (adva_type) { + if (addrd->adva_type) { /* Set random address */ hdr |= BLE_ADV_PDU_HDR_RXADD_MASK; } - if (inita) { - memcpy(pdu_data->inita, inita, BLE_DEV_ADDR_LEN); - if (inita_type) { + if (addrd->targeta) { +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + if (addrd->targeta_resolved) { + if (connsm->own_addr_type > BLE_OWN_ADDR_RANDOM) { + /* If TargetA was resolved we should reply with a different RPA + * in InitA (see Core 5.3, Vol 6, Part B, 6.4). + */ + BLE_LL_ASSERT(addrd->rpa_index >= 0); + rl = &g_ble_ll_resolv_list[addrd->rpa_index]; + hdr |= BLE_ADV_PDU_HDR_TXADD_RAND; + ble_ll_resolv_get_priv_addr(rl, 1, pdu_data->inita); + } else { + /* Host does not want us to use RPA so use identity */ + if ((connsm->own_addr_type & 1) == 0) { + memcpy(pdu_data->inita, g_dev_addr, BLE_DEV_ADDR_LEN); + } else { + hdr |= BLE_ADV_PDU_HDR_TXADD_RAND; + memcpy(pdu_data->inita, g_random_addr, BLE_DEV_ADDR_LEN); + } + } + } else { + memcpy(pdu_data->inita, addrd->targeta, BLE_DEV_ADDR_LEN); + if (addrd->targeta_type) { + hdr |= BLE_ADV_PDU_HDR_TXADD_RAND; + } + } +#else + memcpy(pdu_data->inita, addrd->targeta, BLE_DEV_ADDR_LEN); + if (addrd->targeta_type) { hdr |= BLE_ADV_PDU_HDR_TXADD_RAND; } +#endif } else { /* Get pointer to our device address */ - connsm = g_ble_ll_conn_create_sm.connsm; if ((connsm->own_addr_type & 1) == 0) { addr = g_dev_addr; } else { @@ -2783,27 +2806,13 @@ ble_ll_conn_prepare_connect_ind(struct ble_ll_conn_sm *connsm, /* XXX: do this ahead of time? Calculate the local rpa I mean */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - if (connsm->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { - rl = NULL; - is_rpa = ble_ll_is_rpa(adva, adva_type); - if (is_rpa) { - if (rpa_index >= 0) { - rl = &g_ble_ll_resolv_list[rpa_index]; - } - } else { - /* we look for RL entry to generate local RPA regardless if - * resolving is enabled or not (as this is is for local RPA - * not peer RPA) - */ - rl = ble_ll_resolv_list_find(adva, adva_type); - } - - /* - * If peer in on resolving list, we use RPA generated with Local IRK - * from resolving list entry. In other case, we need to use our identity - * address (see Core 5.0, Vol 6, Part B, section 6.4). + if ((connsm->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) && + (addrd->rpa_index >= 0)) { + /* We are using RPA and advertiser was on our resolving list, so + * we'll use RPA to reply (see Core 5.3, Vol 6, Part B, 6.4). */ - if (rl && rl->rl_has_local) { + rl = &g_ble_ll_resolv_list[addrd->rpa_index]; + if (rl->rl_has_local) { hdr |= BLE_ADV_PDU_HDR_TXADD_RAND; ble_ll_resolv_get_priv_addr(rl, 1, pdu_data->inita); addr = NULL; @@ -2818,7 +2827,7 @@ ble_ll_conn_prepare_connect_ind(struct ble_ll_conn_sm *connsm, } } - memcpy(pdu_data->adva, adva, BLE_DEV_ADDR_LEN); + memcpy(pdu_data->adva, addrd->adva, BLE_DEV_ADDR_LEN); pdu_data->hdr_byte = hdr; } @@ -2885,7 +2894,6 @@ ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu, { struct ble_ll_conn_sm *connsm; struct ble_mbuf_hdr *rxhdr; - int8_t rpa_index; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) uint8_t phy; #endif @@ -2909,15 +2917,8 @@ ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu, return -1; } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - rpa_index = addrd->rpa_index; -#else - rpa_index = -1; -#endif - ble_ll_conn_prepare_connect_ind(connsm, ble_ll_scan_get_pdu_data(), - addrd->adva_type, addrd->adva, - addrd->targeta_type, addrd->targeta, - rpa_index, rxhdr->rxinfo.channel); + ble_ll_conn_prepare_connect_ind(connsm, ble_ll_scan_get_pdu_data(), addrd, + rxhdr->rxinfo.channel); ble_phy_set_txend_cb(NULL, NULL); rc = ble_phy_tx(ble_ll_conn_tx_connect_ind_pducb, connsm, @@ -2971,7 +2972,6 @@ ble_ll_conn_central_start(uint8_t phy, uint8_t csa, if (addrd->targeta_resolved) { BLE_LL_ASSERT(addrd->rpa_index >= 0); BLE_LL_ASSERT(targeta); - ble_ll_resolv_set_local_rpa(addrd->rpa_index, targeta); } #endif From a58ff76b2903f50e386f106650f5f6a57debb7a8 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 22 Feb 2022 18:02:02 +0100 Subject: [PATCH 0292/1333] nimble/ll: Make phy selection more configurable --- .../include/controller/ble_ll_conn.h | 10 +-- nimble/controller/src/ble_ll.c | 14 +++- nimble/controller/src/ble_ll_conn.c | 78 ++++++++++--------- nimble/controller/src/ble_ll_conn_hci.c | 8 +- nimble/controller/src/ble_ll_conn_priv.h | 2 +- nimble/controller/src/ble_ll_ctrl.c | 25 ++---- nimble/controller/syscfg.yml | 18 +++++ 7 files changed, 88 insertions(+), 67 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 70d6b4918f..136ab9d645 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -162,11 +162,11 @@ struct ble_ll_conn_phy_data uint32_t cur_rx_phy: 2; uint32_t new_tx_phy: 2; uint32_t new_rx_phy: 2; - uint32_t host_pref_tx_phys_mask: 3; - uint32_t host_pref_rx_phys_mask: 3; - uint32_t req_pref_tx_phys_mask: 3; - uint32_t req_pref_rx_phys_mask: 3; - uint32_t phy_options: 2; + uint32_t pref_mask_tx: 3; + uint32_t pref_mask_rx: 3; + uint32_t pref_mask_tx_req: 3; + uint32_t pref_mask_rx_req: 3; + uint32_t pref_opts: 2; } __attribute__((packed)); #define CONN_CUR_TX_PHY_MASK(csm) (1 << ((csm)->phy_data.cur_tx_phy - 1)) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 5d3cb63bbd..73b3db40eb 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1597,6 +1597,7 @@ ble_ll_validate_task(void) int ble_ll_reset(void) { + uint8_t phy_mask; int rc; os_sr_t sr; @@ -1634,8 +1635,17 @@ ble_ll_reset(void) STATS_RESET(ble_ll_stats); /* Reset any preferred PHYs */ - g_ble_ll_data.ll_pref_tx_phys = 0; - g_ble_ll_data.ll_pref_rx_phys = 0; + phy_mask = BLE_PHY_MASK_1M; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) + phy_mask |= BLE_PHY_MASK_2M; +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) + phy_mask |= BLE_PHY_MASK_CODED; +#endif + phy_mask &= MYNEWT_VAL(BLE_LL_CONN_PHY_DEFAULT_PREF_MASK); + BLE_LL_ASSERT(phy_mask); + g_ble_ll_data.ll_pref_tx_phys = phy_mask; + g_ble_ll_data.ll_pref_rx_phys = phy_mask; #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Reset connection module */ diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index df015e9d08..cbfcc1a25d 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -484,38 +484,40 @@ ble_ll_conn_css_move(struct ble_ll_conn_sm *connsm, uint16_t slot_idx) #endif #if (BLE_LL_BT5_PHY_SUPPORTED == 1) -/** - * Checks to see if we should start a PHY update procedure - * - * If current phy is not one of the preferred we need to start control - * procedure. - * - * XXX: we could also decide to change the PHY if RSSI is really good - * and we are currently at 1Mbps or lower data rate and we could use - * a higher data rate. - * - * @param connsm - * @return 0: success; -1: no phy update procedure started - */ -int -ble_ll_conn_chk_phy_upd_start(struct ble_ll_conn_sm *csm) +static inline int +ble_ll_conn_phy_should_update(uint8_t pref_mask, uint8_t curr_mask) { - int rc; +#if MYNEWT_VAL(BLE_LL_CONN_PHY_PREFER_2M) + /* Should change to 2M if preferred, but not active */ + if ((pref_mask & BLE_PHY_MASK_2M) && (curr_mask != BLE_PHY_MASK_2M)) { + return 1; + } +#endif - /* If no host preferences or */ - if (((csm->phy_data.host_pref_tx_phys_mask == 0) && - (csm->phy_data.host_pref_rx_phys_mask == 0)) || - ((csm->phy_data.host_pref_tx_phys_mask & CONN_CUR_TX_PHY_MASK(csm)) && - (csm->phy_data.host_pref_rx_phys_mask & CONN_CUR_RX_PHY_MASK(csm)))) { - rc = -1; - } else { - csm->phy_data.req_pref_tx_phys_mask = csm->phy_data.host_pref_tx_phys_mask; - csm->phy_data.req_pref_rx_phys_mask = csm->phy_data.host_pref_rx_phys_mask; - ble_ll_ctrl_proc_start(csm, BLE_LL_CTRL_PROC_PHY_UPDATE, NULL); - rc = 0; + /* Should change to active phy is not preferred */ + if ((curr_mask & pref_mask) == 0) { + return 1; } - return rc; + return 0; +} + +int +ble_ll_conn_phy_update_if_needed(struct ble_ll_conn_sm *connsm) +{ + if (!ble_ll_conn_phy_should_update(connsm->phy_data.pref_mask_tx, + CONN_CUR_TX_PHY_MASK(connsm)) && + !ble_ll_conn_phy_should_update(connsm->phy_data.pref_mask_rx, + CONN_CUR_RX_PHY_MASK(connsm))) { + return -1; + } + + connsm->phy_data.pref_mask_tx_req = connsm->phy_data.pref_mask_tx; + connsm->phy_data.pref_mask_rx_req = connsm->phy_data.pref_mask_rx; + + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_PHY_UPDATE, NULL); + + return 0; } #endif @@ -952,7 +954,7 @@ ble_ll_conn_adjust_pyld_len(struct ble_ll_conn_sm *connsm, uint16_t pyld_len) if (connsm->phy_tx_transition) { phy_mode = ble_ll_phy_to_phy_mode(connsm->phy_tx_transition, - connsm->phy_data.phy_options); + connsm->phy_data.pref_opts); } else { phy_mode = connsm->phy_data.tx_phy_mode; } @@ -1847,11 +1849,11 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) connsm->phy_data.cur_rx_phy = BLE_PHY_1M; connsm->phy_data.tx_phy_mode = BLE_PHY_MODE_1M; connsm->phy_data.rx_phy_mode = BLE_PHY_MODE_1M; - connsm->phy_data.req_pref_tx_phys_mask = 0; - connsm->phy_data.req_pref_rx_phys_mask = 0; - connsm->phy_data.host_pref_tx_phys_mask = g_ble_ll_data.ll_pref_tx_phys; - connsm->phy_data.host_pref_rx_phys_mask = g_ble_ll_data.ll_pref_rx_phys; - connsm->phy_data.phy_options = 0; + connsm->phy_data.pref_mask_tx_req = 0; + connsm->phy_data.pref_mask_rx_req = 0; + connsm->phy_data.pref_mask_tx = g_ble_ll_data.ll_pref_tx_phys; + connsm->phy_data.pref_mask_rx = g_ble_ll_data.ll_pref_rx_phys; + connsm->phy_data.pref_opts = 0; connsm->phy_tx_transition = 0; #endif @@ -2343,14 +2345,14 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) connsm->phy_data.cur_tx_phy = connsm->phy_data.new_tx_phy; connsm->phy_data.tx_phy_mode = ble_ll_phy_to_phy_mode(connsm->phy_data.cur_tx_phy, - connsm->phy_data.phy_options); + connsm->phy_data.pref_opts); } if (connsm->phy_data.new_rx_phy) { connsm->phy_data.cur_rx_phy = connsm->phy_data.new_rx_phy; connsm->phy_data.rx_phy_mode = ble_ll_phy_to_phy_mode(connsm->phy_data.cur_rx_phy, - connsm->phy_data.phy_options); + connsm->phy_data.pref_opts); } /* Clear flags and set flag to send event at next instant */ @@ -2527,7 +2529,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) /* Send connection complete event to inform host of connection */ if (rc) { -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if (BLE_LL_BT5_PHY_SUPPORTED == 1) && MYNEWT_VAL(BLE_LL_CONN_PHY_INIT_UPDATE) /* * If we have default phy preferences and they are different than * the current PHY's in use, start update procedure. @@ -2536,7 +2538,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) * XXX: should we attempt to start this without knowing if * the other side can support it? */ - if (!ble_ll_conn_chk_phy_upd_start(connsm)) { + if (!ble_ll_conn_phy_update_if_needed(connsm)) { CONN_F_CTRLR_PHY_UPDATE(connsm) = 1; } #endif diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index ac212550f8..6d821d39d1 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1872,9 +1872,9 @@ ble_ll_conn_hci_le_set_phy(const uint8_t *cmdbuf, uint8_t len) goto phy_cmd_param_err; } - connsm->phy_data.phy_options = phy_options & 0x03; - connsm->phy_data.host_pref_tx_phys_mask = tx_phys, - connsm->phy_data.host_pref_rx_phys_mask = rx_phys; + connsm->phy_data.pref_opts = phy_options & 0x03; + connsm->phy_data.pref_mask_tx = tx_phys, + connsm->phy_data.pref_mask_rx = rx_phys; /* * The host preferences override the default phy preferences. Currently, @@ -1900,7 +1900,7 @@ ble_ll_conn_hci_le_set_phy(const uint8_t *cmdbuf, uint8_t len) CONN_F_HOST_PHY_UPDATE(connsm) = 1; } else { /* Check if we should start phy update procedure */ - if (!ble_ll_conn_chk_phy_upd_start(connsm)) { + if (!ble_ll_conn_phy_update_if_needed(connsm)) { CONN_F_HOST_PHY_UPDATE(connsm) = 1; } else { /* diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index 3d49f4983a..c2c1a0a486 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -244,7 +244,7 @@ int ble_ll_hci_acl_rx(struct os_mbuf *om, void *arg); int ble_ll_conn_hci_le_rd_phy(const uint8_t *cmdbuf, uint8_t len, uint8_t *rsp, uint8_t *rsplen); int ble_ll_conn_hci_le_set_phy(const uint8_t *cmdbuf, uint8_t len); -int ble_ll_conn_chk_phy_upd_start(struct ble_ll_conn_sm *connsm); +int ble_ll_conn_phy_update_if_needed(struct ble_ll_conn_sm *connsm); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) int ble_ll_conn_hci_ext_create(const uint8_t *cmdbuf, uint8_t len); #endif diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 5212cb5c7a..c30f4e3eb3 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -672,7 +672,7 @@ ble_ll_ctrl_phy_update_proc_complete(struct ble_ll_conn_sm *connsm) /* Must check if we need to start host procedure */ if (chk_host_phy) { if (CONN_F_HOST_PHY_UPDATE(connsm)) { - if (ble_ll_conn_chk_phy_upd_start(connsm)) { + if (ble_ll_conn_phy_update_if_needed(connsm)) { CONN_F_HOST_PHY_UPDATE(connsm) = 0; } else { chk_proc_stop = 0; @@ -751,11 +751,11 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, /* Get m_to_s and s_to_m masks */ if (periph_req) { - m_to_s = connsm->phy_data.host_pref_tx_phys_mask & rx_phys; - s_to_m = connsm->phy_data.host_pref_rx_phys_mask & tx_phys; + m_to_s = connsm->phy_data.pref_mask_tx & rx_phys; + s_to_m = connsm->phy_data.pref_mask_rx & tx_phys; } else { - m_to_s = connsm->phy_data.req_pref_tx_phys_mask & rx_phys; - s_to_m = connsm->phy_data.req_pref_rx_phys_mask & tx_phys; + m_to_s = connsm->phy_data.pref_mask_tx_req & rx_phys; + s_to_m = connsm->phy_data.pref_mask_rx_req & tx_phys; } if (is_periph_sym) { @@ -844,17 +844,8 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, static void ble_ll_ctrl_phy_req_rsp_make(struct ble_ll_conn_sm *connsm, uint8_t *ctrdata) { - /* If no preference we use current phy */ - if (connsm->phy_data.host_pref_tx_phys_mask == 0) { - ctrdata[0] = CONN_CUR_TX_PHY_MASK(connsm); - } else { - ctrdata[0] = connsm->phy_data.host_pref_tx_phys_mask; - } - if (connsm->phy_data.host_pref_rx_phys_mask == 0) { - ctrdata[1] = CONN_CUR_RX_PHY_MASK(connsm); - } else { - ctrdata[1] = connsm->phy_data.host_pref_rx_phys_mask; - } + ctrdata[0] = connsm->phy_data.pref_mask_tx; + ctrdata[1] = connsm->phy_data.pref_mask_rx; } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE) @@ -3017,7 +3008,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { connsm->phy_tx_transition = ble_ll_ctrl_phy_tx_transition_get( - connsm->phy_data.req_pref_tx_phys_mask); + connsm->phy_data.pref_mask_tx_req); } break; #endif diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index ec1ef935bc..a312ab3f12 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -103,6 +103,24 @@ syscfg.defs: description: 'Size of the resolving list.' value: '4' + BLE_LL_CONN_PHY_DEFAULT_PREF_MASK: + description: > + Default PHY preference mask used if no HCI LE Set Preferred PHY + was received. + value: 0x07 + BLE_LL_CONN_PHY_PREFER_2M: + description: > + If enabled, LL will always attempt to switch to 2M PHY if present + in preferred mask even if active PHY is also allowed by that mask. + Otherwise LL will not attempt to switch PHY as long as active PHY + is present in preferred mask. + value: 0 + BLE_LL_CONN_PHY_INIT_UPDATE: + description: > + If enabled, LL will attempt to switch PHY (depending on preferences + mask set) after connection was established. + value: 0 + # Data length management definitions for connections. These define the # maximum size of the PDU's that will be sent and/or received in a # connection. From 0a680598f0c7c20dd626bf3689c5fa35554cbd51 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 22 Feb 2022 18:02:39 +0100 Subject: [PATCH 0293/1333] nimble/ll: Update peer RPA during scan We need to keep track of peer RPA during scan so it can be retrieved by host using LE Read Peer Resolvable Address at any time. --- nimble/controller/src/ble_ll_scan.c | 7 +++++++ nimble/controller/src/ble_ll_scan_aux.c | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index b04138d1e3..46e1cb66cd 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1931,6 +1931,13 @@ ble_ll_scan_rx_pkt_in_on_legacy(uint8_t pdu_type, struct os_mbuf *om, ble_ll_scan_get_addr_data_from_legacy(pdu_type, rxbuf, addrd); ble_ll_scan_rx_pkt_in_restore_addr_data(hdr, addrd); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + if (addrd->adva_resolved) { + BLE_LL_ASSERT(addrd->rpa_index >= 0); + ble_ll_resolv_set_peer_rpa(addrd->rpa_index, addrd->adva); + } +#endif + send_hci_report = !scansm->scan_filt_dups || !ble_ll_scan_dup_check_legacy(addrd->adv_addr_type, addrd->adv_addr, diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 9504771d95..933c3f712b 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -1669,6 +1669,13 @@ ble_ll_scan_aux_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr) } #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + if (addrd.adva_resolved) { + BLE_LL_ASSERT(addrd.rpa_index >= 0); + ble_ll_resolv_set_peer_rpa(addrd.rpa_index, addrd.adva); + } +#endif + scan_duplicate = ble_ll_scan_get_filt_dups() && ble_ll_scan_dup_check_ext(addrd.adv_addr_type, addrd.adv_addr, true, aux->adi); From 7bf2623c5b7c4b36a9db3be1ffaefc0e1d737a56 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 22 Feb 2022 20:53:37 +0100 Subject: [PATCH 0294/1333] nimble/ll: Do not validate random address The Core spec does not mention anywhere that we should validate if random address has proper bits set so we can skip that part. We only assume that all-zeroes means random is not set, just as we do for public. --- nimble/controller/include/controller/ble_ll.h | 2 -- nimble/controller/src/ble_ll.c | 12 ++++-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index fb731abd5b..97233e9c3b 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -478,8 +478,6 @@ void ble_ll_init(void); /* Reset the Link Layer */ int ble_ll_reset(void); -int ble_ll_is_valid_public_addr(const uint8_t *addr); - /* 'Boolean' function returning true if address is a valid random address */ int ble_ll_is_valid_random_addr(const uint8_t *addr); diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 73b3db40eb..362d4669a6 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -594,8 +594,8 @@ ble_ll_addr_subtype(const uint8_t *addr, uint8_t addr_type) } } -int -ble_ll_is_valid_public_addr(const uint8_t *addr) +static int +ble_ll_is_valid_addr(const uint8_t *addr) { int i; @@ -661,13 +661,13 @@ ble_ll_is_valid_own_addr_type(uint8_t own_addr_type, const uint8_t *random_addr) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) case BLE_HCI_ADV_OWN_ADDR_PRIV_PUB: #endif - rc = ble_ll_is_valid_public_addr(g_dev_addr); + rc = ble_ll_is_valid_addr(g_dev_addr); break; case BLE_HCI_ADV_OWN_ADDR_RANDOM: #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) case BLE_HCI_ADV_OWN_ADDR_PRIV_RAND: #endif - rc = ble_ll_is_valid_random_addr(random_addr); + rc = ble_ll_is_valid_addr(random_addr); break; default: rc = 0; @@ -728,10 +728,6 @@ ble_ll_set_random_addr(const uint8_t *cmdbuf, uint8_t len, bool hci_adv_ext) } #endif - if (!ble_ll_is_valid_random_addr(cmd->addr)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - memcpy(g_random_addr, cmd->addr, BLE_DEV_ADDR_LEN); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) From 646f7757fdd1a4f8ac5a0fcb7b1dcc0ff353a145 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 23 Feb 2022 16:59:52 +0100 Subject: [PATCH 0295/1333] nimble/ll: Fix verification on periodic adv enable Enabling periodic advertising before parameters are set should return "command disallowed" since we do no supprt vendor-specific default parameters. This fixes HCI/DDI/BV-07-C. --- nimble/controller/src/ble_ll_adv.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index d8d251bae3..d65789a4e4 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -3969,6 +3969,10 @@ ble_ll_adv_periodic_enable(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_CMD_DISALLOWED; } + if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_CONFIGURED)) { + return BLE_ERR_CMD_DISALLOWED; + } + /* If Enable is set to 0x01 and the length of the periodic advertising * data is greater than the maximum that the Controller can transmit * within the chosen periodicadvertising interval, the Controller shall From fa3fd20b79d0151878d384a37369eb994d8638a2 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 23 Feb 2022 17:01:42 +0100 Subject: [PATCH 0296/1333] nimble/ll: Fix race on create connection If AUX_CONNECT_RSP is invalid we should immediately remove connection from scheduler, then we can do other stuff. In other case, we may be a bit too late and scheduler will fire already scheduled connection event for a connection that is not created. --- nimble/controller/src/ble_ll_scan_aux.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 933c3f712b..c637be7111 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -1567,8 +1567,9 @@ ble_ll_scan_aux_rx_pkt_in_for_initiator(struct os_mbuf *rxpdu, aux = rxinfo->user_data; if (rxinfo->flags & BLE_MBUF_HDR_F_IGNORED) { + ble_ll_scan_aux_free(aux); ble_ll_scan_chk_resume(); - goto done; + return; } if (!(rxinfo->flags & BLE_MBUF_HDR_F_CONNECT_RSP_RXD)) { @@ -1582,19 +1583,14 @@ ble_ll_scan_aux_rx_pkt_in_for_initiator(struct os_mbuf *rxpdu, if (ble_ll_scan_aux_check_connect_rsp(rxpdu->om_data, ble_ll_scan_get_pdu_data(), &addrd) < 0) { + ble_ll_conn_send_connect_req_cancel(); + ble_ll_scan_aux_free(aux); ble_ll_scan_chk_resume(); - goto done; + return; } - aux->flags &= ~BLE_LL_SCAN_AUX_F_W4_CONNECT_RSP; - ble_ll_scan_sm_stop(0); ble_ll_conn_created_on_aux(rxpdu, &addrd, aux->targeta); - -done: - if (aux->flags & BLE_LL_SCAN_AUX_F_W4_CONNECT_RSP) { - ble_ll_conn_send_connect_req_cancel(); - } ble_ll_scan_aux_free(aux); } #endif From cc4dae19d3e44845febc558fbb3506a70f2a2da9 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 23 Feb 2022 23:59:32 +0100 Subject: [PATCH 0297/1333] nimble/ll: Do not allow duplicated connections This fixes LL/CON/INI/BI-03-C. --- .../include/controller/ble_ll_conn.h | 2 ++ nimble/controller/src/ble_ll_adv.c | 33 +------------------ nimble/controller/src/ble_ll_conn.c | 15 +++++++++ nimble/controller/src/ble_ll_conn_hci.c | 7 ++++ 4 files changed, 25 insertions(+), 32 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 136ab9d645..a75457ec23 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -395,6 +395,8 @@ struct ble_ll_conn_sm * */ struct ble_ll_conn_sm *ble_ll_conn_find_active_conn(uint16_t handle); +struct ble_ll_conn_sm *ble_ll_conn_find_by_peer_addr(const uint8_t* addr, + uint8_t addr_type); /* required for unit testing */ uint8_t ble_ll_conn_calc_dci(struct ble_ll_conn_sm *conn, uint16_t latency); diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index d65789a4e4..feafadccce 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -4110,37 +4110,6 @@ ble_ll_adv_periodic_set_info_transfer(const uint8_t *cmdbuf, uint8_t len, #endif #endif -/** - * Says whether the specified address is already connected or not. - * @param [in] addr The peer address. - * @param [in] addr_type Public address (0) or random address (1). - * @return Return 1 if already connected, 0 otherwise. - */ -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) -static int -ble_ll_adv_already_connected(const uint8_t* addr, uint8_t addr_type) -{ - struct ble_ll_conn_sm *connsm; - - /* extracted from ble_ll_conn_periph_start function */ - SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) { - if (!memcmp(&connsm->peer_addr, addr, BLE_DEV_ADDR_LEN)) { - if (addr_type == BLE_ADDR_RANDOM) { - if (connsm->peer_addr_type & 1) { - return 1; - } - } else { - if ((connsm->peer_addr_type & 1) == 0) { - return 1; - } - } - } - } - - return 0; -} -#endif - /** * Called when the LL receives a scan request or connection request * @@ -4278,7 +4247,7 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu) } else if (pdu_type == BLE_ADV_PDU_TYPE_AUX_CONNECT_REQ) { #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) /* See if the device is already connected */ - if (ble_ll_adv_already_connected(peer, peer_addr_type)) { + if (ble_ll_conn_find_by_peer_addr(peer, peer_addr_type)) { return -1; } diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index cbfcc1a25d..e383435148 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -483,6 +483,21 @@ ble_ll_conn_css_move(struct ble_ll_conn_sm *connsm, uint16_t slot_idx) } #endif +struct ble_ll_conn_sm * +ble_ll_conn_find_by_peer_addr(const uint8_t *addr, uint8_t addr_type) +{ + struct ble_ll_conn_sm *connsm; + + SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) { + if (!memcmp(&connsm->peer_addr, addr, BLE_DEV_ADDR_LEN) && + !((connsm->peer_addr_type ^ addr_type) & 1)) { + return connsm; + } + } + + return NULL; +} + #if (BLE_LL_BT5_PHY_SUPPORTED == 1) static inline int ble_ll_conn_phy_should_update(uint8_t pref_mask, uint8_t curr_mask) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 6d821d39d1..bcc98a5e89 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -532,6 +532,9 @@ ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_CMD_DISALLOWED; } + if (ble_ll_conn_find_by_peer_addr(cmd->peer_addr, cmd->peer_addr_type)) { + return BLE_ERR_ACL_CONN_EXISTS; + } #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) css_slot_idx = ble_ll_conn_css_get_next_slot(); @@ -752,6 +755,10 @@ ble_ll_conn_hci_ext_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_CMD_DISALLOWED; } + if (ble_ll_conn_find_by_peer_addr(cmd->peer_addr, cmd->peer_addr_type)) { + return BLE_ERR_ACL_CONN_EXISTS; + } + #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) css_slot_idx = ble_ll_conn_css_get_next_slot(); if (css_slot_idx == BLE_LL_CONN_CSS_NO_SLOT) { From 51cb4dca67d0ad55bf92379050a223e20e538cd2 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 24 Feb 2022 00:01:46 +0100 Subject: [PATCH 0298/1333] nimble/ll: Rename func to match other one --- .../include/controller/ble_ll_conn.h | 7 +--- nimble/controller/src/ble_ll_adv.c | 2 +- nimble/controller/src/ble_ll_conn.c | 8 ++--- nimble/controller/src/ble_ll_conn_hci.c | 36 +++++++++---------- nimble/controller/src/ble_ll_conn_priv.h | 2 +- nimble/controller/src/ble_ll_sync.c | 2 +- 6 files changed, 26 insertions(+), 31 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index a75457ec23..ec13d00946 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -389,12 +389,7 @@ struct ble_ll_conn_sm #define CONN_IS_PERIPHERAL(csm) (false) #endif -/* - * Given a handle, returns an active connection state machine (or NULL if the - * handle does not exist - * - */ -struct ble_ll_conn_sm *ble_ll_conn_find_active_conn(uint16_t handle); +struct ble_ll_conn_sm *ble_ll_conn_find_by_handle(uint16_t handle); struct ble_ll_conn_sm *ble_ll_conn_find_by_peer_addr(const uint8_t* addr, uint8_t addr_type); diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index feafadccce..070c89ce58 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -4084,7 +4084,7 @@ ble_ll_adv_periodic_set_info_transfer(const uint8_t *cmdbuf, uint8_t len, goto done; } - connsm = ble_ll_conn_find_active_conn(handle); + connsm = ble_ll_conn_find_by_handle(handle); if (!connsm) { rc = BLE_ERR_UNK_CONN_ID; goto done; diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index e383435148..0d41d10c44 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -384,7 +384,7 @@ ble_ll_conn_cth_flow_process_cmd(const uint8_t *cmdbuf) * case we can simply ignore command for that connection since credits * are returned by LL already. */ - connsm = ble_ll_conn_find_active_conn(cp->h[i].handle); + connsm = ble_ll_conn_find_by_handle(cp->h[i].handle); if (connsm) { ble_ll_conn_cth_flow_free_credit(connsm, cp->h[i].count); } @@ -670,7 +670,7 @@ ble_ll_conn_current_sm_over(struct ble_ll_conn_sm *connsm) * @return struct ble_ll_conn_sm* */ struct ble_ll_conn_sm * -ble_ll_conn_find_active_conn(uint16_t handle) +ble_ll_conn_find_by_handle(uint16_t handle) { struct ble_ll_conn_sm *connsm; @@ -3146,7 +3146,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) /* XXX: there is a chance that the connection was thrown away and re-used before processing packets here. Fix this. */ /* We better have a connection state machine */ - connsm = ble_ll_conn_find_active_conn(hdr->rxinfo.handle); + connsm = ble_ll_conn_find_by_handle(hdr->rxinfo.handle); if (!connsm) { STATS_INC(ble_ll_conn_stats, no_conn_sm); goto conn_rx_data_pdu_end; @@ -3704,7 +3704,7 @@ ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t length) /* See if we have an active matching connection handle */ conn_handle = handle & 0x0FFF; - connsm = ble_ll_conn_find_active_conn(conn_handle); + connsm = ble_ll_conn_find_by_handle(conn_handle); if (connsm) { /* Construct LL header in buffer (NOTE: pb already checked) */ pb = handle & 0x3000; diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index bcc98a5e89..97d242134b 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -891,7 +891,7 @@ ble_ll_conn_hci_read_rem_features(const uint8_t *cmdbuf, uint8_t len) } /* If no connection handle exit with error */ - connsm = ble_ll_conn_find_active_conn(le16toh(cmd->conn_handle)); + connsm = ble_ll_conn_find_by_handle(le16toh(cmd->conn_handle)); if (!connsm) { return BLE_ERR_UNK_CONN_ID; } @@ -950,7 +950,7 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) /* If no connection handle exit with error */ handle = le16toh(cmd->conn_handle); - connsm = ble_ll_conn_find_active_conn(handle); + connsm = ble_ll_conn_find_by_handle(handle); if (!connsm) { return BLE_ERR_UNK_CONN_ID; } @@ -1066,7 +1066,7 @@ ble_ll_conn_hci_param_rr(const uint8_t *cmdbuf, uint8_t len, } /* If we dont have a handle we cant do anything */ - connsm = ble_ll_conn_find_active_conn(handle); + connsm = ble_ll_conn_find_by_handle(handle); if (!connsm) { rc = BLE_ERR_UNK_CONN_ID; goto done; @@ -1132,7 +1132,7 @@ ble_ll_conn_hci_param_nrr(const uint8_t *cmdbuf, uint8_t len, } /* If we dont have a handle we cant do anything */ - connsm = ble_ll_conn_find_active_conn(handle); + connsm = ble_ll_conn_find_by_handle(handle); if (!connsm) { rc = BLE_ERR_UNK_CONN_ID; goto done; @@ -1244,7 +1244,7 @@ ble_ll_conn_hci_disconnect_cmd(const struct ble_hci_lc_disconnect_cp *cmd) case BLE_ERR_UNSUPP_REM_FEATURE: case BLE_ERR_UNIT_KEY_PAIRING: case BLE_ERR_CONN_PARMS: - connsm = ble_ll_conn_find_active_conn(handle); + connsm = ble_ll_conn_find_by_handle(handle); if (connsm) { /* Do not allow command if we are in process of disconnecting */ if (connsm->disconnect_reason) { @@ -1293,7 +1293,7 @@ ble_ll_conn_hci_rd_rem_ver_cmd(const uint8_t *cmdbuf, uint8_t len) } /* Check for valid parameters */ - connsm = ble_ll_conn_find_active_conn(le16toh(cmd->conn_handle)); + connsm = ble_ll_conn_find_by_handle(le16toh(cmd->conn_handle)); if (!connsm) { return BLE_ERR_UNK_CONN_ID; } @@ -1343,7 +1343,7 @@ ble_ll_conn_hci_rd_rssi(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uin rsp->handle = cmd->handle; - connsm = ble_ll_conn_find_active_conn(le16toh(cmd->handle)); + connsm = ble_ll_conn_find_by_handle(le16toh(cmd->handle)); if (!connsm) { rsp->rssi = 127; rc = BLE_ERR_UNK_CONN_ID; @@ -1380,7 +1380,7 @@ ble_ll_conn_hci_rd_chan_map(const uint8_t *cmdbuf, uint8_t len, } handle = le16toh(cmd->conn_handle); - connsm = ble_ll_conn_find_active_conn(handle); + connsm = ble_ll_conn_find_by_handle(handle); if (!connsm) { rc = BLE_ERR_UNK_CONN_ID; memset(rsp->chan_map, 0, sizeof(rsp->chan_map)); @@ -1453,7 +1453,7 @@ ble_ll_conn_hci_set_data_len(const uint8_t *cmdbuf, uint8_t len, /* Find connection */ handle = le16toh(cmd->conn_handle); - connsm = ble_ll_conn_find_active_conn(handle); + connsm = ble_ll_conn_find_by_handle(handle); if (!connsm) { rc = BLE_ERR_UNK_CONN_ID; goto done; @@ -1518,7 +1518,7 @@ ble_ll_conn_hci_le_start_encrypt(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } - connsm = ble_ll_conn_find_active_conn(le16toh(cmd->conn_handle)); + connsm = ble_ll_conn_find_by_handle(le16toh(cmd->conn_handle)); if (!connsm) { rc = BLE_ERR_UNK_CONN_ID; #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) @@ -1571,7 +1571,7 @@ ble_ll_conn_hci_le_ltk_reply(const uint8_t *cmdbuf, uint8_t len, /* Find connection handle */ handle = le16toh(cmd->conn_handle); - connsm = ble_ll_conn_find_active_conn(handle); + connsm = ble_ll_conn_find_by_handle(handle); if (!connsm) { rc = BLE_ERR_UNK_CONN_ID; goto ltk_key_cmd_complete; @@ -1630,7 +1630,7 @@ ble_ll_conn_hci_le_ltk_neg_reply(const uint8_t *cmdbuf, uint8_t len, /* Find connection handle */ handle = le16toh(cmd->conn_handle); - connsm = ble_ll_conn_find_active_conn(handle); + connsm = ble_ll_conn_find_by_handle(handle); if (!connsm) { rc = BLE_ERR_UNK_CONN_ID; goto ltk_key_cmd_complete; @@ -1673,7 +1673,7 @@ ble_ll_conn_req_peer_sca(const uint8_t *cmdbuf, uint8_t len, const struct ble_hci_le_request_peer_sca_cp *params = (const void *)cmdbuf; struct ble_ll_conn_sm *connsm; - connsm = ble_ll_conn_find_active_conn(le16toh(params->conn_handle)); + connsm = ble_ll_conn_find_by_handle(le16toh(params->conn_handle)); if (!connsm) { return BLE_ERR_UNK_CONN_ID; } @@ -1718,7 +1718,7 @@ ble_ll_conn_hci_rd_auth_pyld_tmo(const uint8_t *cmdbuf, uint8_t len, } handle = le16toh(cmd->conn_handle); - connsm = ble_ll_conn_find_active_conn(handle); + connsm = ble_ll_conn_find_by_handle(handle); if (!connsm) { rc = BLE_ERR_UNK_CONN_ID; rsp->tmo = 0; @@ -1761,7 +1761,7 @@ ble_ll_conn_hci_wr_auth_pyld_tmo(const uint8_t *cmdbuf, uint8_t len, handle = le16toh(cmd->conn_handle); - connsm = ble_ll_conn_find_active_conn(handle); + connsm = ble_ll_conn_find_by_handle(handle); if (!connsm) { rc = BLE_ERR_UNK_CONN_ID; } else { @@ -1814,7 +1814,7 @@ ble_ll_conn_hci_le_rd_phy(const uint8_t *cmdbuf, uint8_t len, } handle = le16toh(cmd->conn_handle); - connsm = ble_ll_conn_find_active_conn(handle); + connsm = ble_ll_conn_find_by_handle(handle); if (!connsm) { rsp->tx_phy = 0; rsp->rx_phy = 0; @@ -1854,7 +1854,7 @@ ble_ll_conn_hci_le_set_phy(const uint8_t *cmdbuf, uint8_t len) } handle = le16toh(cmd->conn_handle); - connsm = ble_ll_conn_find_active_conn(handle); + connsm = ble_ll_conn_find_by_handle(handle); if (!connsm) { return BLE_ERR_UNK_CONN_ID; } @@ -1965,7 +1965,7 @@ ble_ll_set_sync_transfer_params(const uint8_t *cmdbuf, uint8_t len, goto done; } - connsm = ble_ll_conn_find_active_conn(le16toh(cmd->conn_handle)); + connsm = ble_ll_conn_find_by_handle(le16toh(cmd->conn_handle)); if (!connsm) { rc = BLE_ERR_UNK_CONN_ID; goto done; diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index c2c1a0a486..7541f642af 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -163,7 +163,7 @@ void ble_ll_conn_central_init(struct ble_ll_conn_sm *connsm, struct ble_ll_conn_create_scan *cc_scan, struct ble_ll_conn_create_params *cc_params); -struct ble_ll_conn_sm *ble_ll_conn_find_active_conn(uint16_t handle); +struct ble_ll_conn_sm *ble_ll_conn_find_by_handle(uint16_t handle); void ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm); /* Advertising interface */ diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 8912cec587..e5ef0efe5e 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -2177,7 +2177,7 @@ ble_ll_sync_transfer(const uint8_t *cmdbuf, uint8_t len, goto done; } - connsm = ble_ll_conn_find_active_conn(handle); + connsm = ble_ll_conn_find_by_handle(handle); if (!connsm) { rc = BLE_ERR_UNK_CONN_ID; OS_EXIT_CRITICAL(sr); From 0ea070d09f96e20643ae37119addf61152bc9e6c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 24 Feb 2022 13:51:26 +0100 Subject: [PATCH 0299/1333] nimble/ll: Verify hop increment in CONNECT_IND We should ignore CONNECT_IND with invalid hop increment value. This fixes LL/DDI/ADV/BI-07-C. --- nimble/controller/src/ble_ll_conn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 0d41d10c44..398b4e2af7 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3831,7 +3831,8 @@ ble_ll_conn_periph_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr (connsm->conn_itvl < BLE_HCI_CONN_ITVL_MIN) || (connsm->conn_itvl > BLE_HCI_CONN_ITVL_MAX) || (connsm->tx_win_size < BLE_LL_CONN_TX_WIN_MIN) || - (connsm->periph_latency > BLE_LL_CONN_PERIPH_LATENCY_MAX)) { + (connsm->periph_latency > BLE_LL_CONN_PERIPH_LATENCY_MAX) || + (connsm->hop_inc < 5) || (connsm->hop_inc > 16)) { goto err_periph_start; } From 93b3ab71dc94a4cde14d91c65b5869e5a28ba5e3 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 24 Feb 2022 12:55:57 +0100 Subject: [PATCH 0300/1333] nimble/ll: Check MIC on every PDU We should check for MIC failure before any other checks to detect failures even on corrupted PDUs. This fixes LL/SEC/PER/BI-04-C. --- nimble/controller/src/ble_ll_conn.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 398b4e2af7..d1725f2fc6 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3161,6 +3161,15 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) acl_len = rxbuf[1]; llid = hdr_byte & BLE_LL_DATA_HDR_LLID_MASK; + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) + if (BLE_MBUF_HDR_MIC_FAILURE(hdr)) { + STATS_INC(ble_ll_conn_stats, mic_failures); + ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC); + goto conn_rx_data_pdu_end; + } +#endif + /* * Check that the LLID and payload length are reasonable. * Empty payload is only allowed for LLID == 01b. @@ -3232,18 +3241,6 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) goto conn_rx_data_pdu_end; } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - /* - * XXX: should we check to see if we are in a state where we - * might expect to get an encrypted PDU? - */ - if (BLE_MBUF_HDR_MIC_FAILURE(hdr)) { - STATS_INC(ble_ll_conn_stats, mic_failures); - ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC); - goto conn_rx_data_pdu_end; - } -#endif - if (llid == BLE_LL_LLID_CTRL) { /* Process control frame */ STATS_INC(ble_ll_conn_stats, rx_ctrl_pdus); From c3fee3ad34639557c4121b376231b163fcbff365 Mon Sep 17 00:00:00 2001 From: supperthomas <78900636@qq.com> Date: Thu, 24 Feb 2022 21:10:12 +0800 Subject: [PATCH 0301/1333] nimble/hs: fix the LE Supported feature mask when set the features we set the htole64 in ble_ll_hci.c.It will match the value about it --- nimble/host/src/ble_hs_startup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c index 60441826a0..96e4e655cc 100644 --- a/nimble/host/src/ble_hs_startup.c +++ b/nimble/host/src/ble_hs_startup.c @@ -40,7 +40,7 @@ ble_hs_startup_read_sup_f_tx(void) /* for now we don't use it outside of init sequence so check this here * LE Supported (Controller) byte 4, bit 6 */ - if (!(rsp.features & 0x0000006000000000)) { + if (!(le64toh(rsp.features) & 0x0000006000000000)) { BLE_HS_LOG(ERROR, "Controller doesn't support LE\n"); return BLE_HS_ECONTROLLER; } From 0eca76bbcc21a32bf813862d6d04b4d5ac83940b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 22 Feb 2022 18:02:17 +0100 Subject: [PATCH 0302/1333] nimble/phy/nrf: Update timings for BabbleSim Only 1M and 2M are supported, no need for LE Coded. --- nimble/drivers/nrf52/src/ble_phy.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/nimble/drivers/nrf52/src/ble_phy.c b/nimble/drivers/nrf52/src/ble_phy.c index 6752413318..dc8ba4e7ab 100644 --- a/nimble/drivers/nrf52/src/ble_phy.c +++ b/nimble/drivers/nrf52/src/ble_phy.c @@ -179,31 +179,23 @@ static const uint16_t g_ble_phy_mode_pkt_start_off[BLE_PHY_NUM_MODE] = { #if BABBLESIM /* delay between EVENTS_READY and start of tx */ static const uint8_t g_ble_phy_t_txdelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 0, - [BLE_PHY_MODE_2M] = 3, - [BLE_PHY_MODE_CODED_125KBPS] = 5, - [BLE_PHY_MODE_CODED_500KBPS] = 5 + [BLE_PHY_MODE_1M] = 1, + [BLE_PHY_MODE_2M] = 1, }; /* delay between EVENTS_END and end of txd packet */ static const uint8_t g_ble_phy_t_txenddelay[BLE_PHY_NUM_MODE] = { [BLE_PHY_MODE_1M] = 1, - [BLE_PHY_MODE_2M] = 3, - [BLE_PHY_MODE_CODED_125KBPS] = 9, - [BLE_PHY_MODE_CODED_500KBPS] = 3 + [BLE_PHY_MODE_2M] = 1, }; /* delay between rxd access address (w/ TERM1 for coded) and EVENTS_ADDRESS */ static const uint8_t g_ble_phy_t_rxaddrdelay[BLE_PHY_NUM_MODE] = { [BLE_PHY_MODE_1M] = 9, - [BLE_PHY_MODE_2M] = 2, - [BLE_PHY_MODE_CODED_125KBPS] = 17, - [BLE_PHY_MODE_CODED_500KBPS] = 17 + [BLE_PHY_MODE_2M] = 5, }; /* delay between end of rxd packet and EVENTS_END */ static const uint8_t g_ble_phy_t_rxenddelay[BLE_PHY_NUM_MODE] = { [BLE_PHY_MODE_1M] = 9, - [BLE_PHY_MODE_2M] = 2, - [BLE_PHY_MODE_CODED_125KBPS] = 27, - [BLE_PHY_MODE_CODED_500KBPS] = 22 + [BLE_PHY_MODE_2M] = 5, }; #else /* delay between EVENTS_READY and start of tx */ From c1382c62054a3400f90b5131be34daac219c9c10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 24 Feb 2022 17:15:39 +0100 Subject: [PATCH 0303/1333] apps: enable UART Flow Control in bttester This prevents data loss when RTT logs collection is enabled un Upper Tester side. --- apps/bttester/syscfg.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index f00afeb10f..330e38d0b8 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -89,6 +89,7 @@ syscfg.vals: BLE_MONITOR_RTT: 1 CONSOLE_RTT: 0 CONSOLE_UART: 0 + CONSOLE_UART_FLOW_CONTROL: UART_FLOW_CTL_RTS_CTS RTT_NUM_BUFFERS_UP: 0 RTT_NUM_BUFFERS_DOWN: 0 From 811d2a55d1e902b05d6c3c94e35567818a5d8d04 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 21 Feb 2022 16:38:21 +0100 Subject: [PATCH 0304/1333] babblesim: Add command line arg to specify bdaddr This allows to set public bdaddr using -A or --bdaddr command line option. Accepted formats are both XX:XX:XX:XX:XX:XX and 0xXXXXXXXXXXXX. --- babblesim/core/src/argparse.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/babblesim/core/src/argparse.c b/babblesim/core/src/argparse.c index 68f13de433..c1b6cdafd2 100644 --- a/babblesim/core/src/argparse.c +++ b/babblesim/core/src/argparse.c @@ -15,6 +15,7 @@ #include "bs_dynargs.h" #include "bs_cmd_line_typical.h" #include "NRF_HWLowL.h" +#include "controller/ble_ll.h" static bs_args_struct_t *args_struct; static struct nrf52_bsim_args_t arg; @@ -36,6 +37,28 @@ static void cmd_nosim_found(char *argv, int offset) hwll_set_nosim(true); } +static void cmd_bdaddr_found(char *argv, int offset) +{ + union { + uint64_t u64; + uint8_t u8[8]; + } bdaddr; + char *endptr; + + if (sscanf(&argv[offset], "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", + &bdaddr.u8[5], &bdaddr.u8[4], &bdaddr.u8[3], &bdaddr.u8[2], + &bdaddr.u8[1], &bdaddr.u8[0]) < 6) { + bdaddr.u64 = strtoull(&argv[offset], &endptr, 0); + if (*endptr) { + return; + } + + bdaddr.u64 = htole64(bdaddr.u64); + } + + ble_ll_set_public_addr(bdaddr.u8); +} + static void print_no_sim_warning(void) { bs_trace_warning("Neither simulation id or the device number " @@ -70,6 +93,9 @@ void nrfbsim_register_args(void) * destination, callback, * description */ + { false, false , false, + "A", "bdaddr", 's', + NULL, cmd_bdaddr_found, "Device public address"}, {false, false, true, "nosim", "", 'b', (void *)&nosim, cmd_nosim_found, From 810ef5e9230a3641c5bfa9c886c91b4de38beec8 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 21 Feb 2022 20:45:07 +0100 Subject: [PATCH 0305/1333] 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. --- .../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 57cdc3bb8c..b77f3c8380 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 #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 0e291ea49f..5fce52633a 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 #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 b10d21dd36..5a45e9d08a 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 From 52deeedff1d66d2105d353997b43f603670e5ec9 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 21 Feb 2022 22:07:01 +0100 Subject: [PATCH 0306/1333] 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 b77f3c8380..4c1662a7ff 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: From 3923f1bb1e9a29c6d71819fa5e228669629943cf Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 22 Feb 2022 01:10:19 +0100 Subject: [PATCH 0307/1333] babblesim/edtt: Fix le_data_read --- .../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 4c1662a7ff..d1ff77baf7 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); From 045c3d19cd5dfd4a6601ef814c41aea9dfdc0879 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 22 Feb 2022 02:18:45 +0100 Subject: [PATCH 0308/1333] 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. --- .../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 d1ff77baf7..36db846fa8 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; From def9fd043744c72d7e35aa81a6a592e941531bb2 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 25 Feb 2022 12:05:46 +0100 Subject: [PATCH 0309/1333] nimble/ll: Do not nak PDU with RFU LLID We can handle such PDU in isr, it will be then ignored in LL. This fixes LL/CON/CEN/BI-14-C and LL/CON/PER/BI-17-C. --- nimble/controller/src/ble_ll_conn.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index d1725f2fc6..c2739f15dd 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3417,16 +3417,6 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) /* Set last valid received pdu time (resets supervision timer) */ connsm->last_rxd_pdu_cputime = begtime + ble_ll_tmr_u2t(add_usecs); - /* - * Check for valid LLID before proceeding. We have seen some weird - * things with the PHY where the CRC is OK but we dont have a valid - * LLID. This should really never happen but if it does we will just - * bail. An error stat will get incremented at the LL. - */ - if ((hdr_byte & BLE_LL_DATA_HDR_LLID_MASK) == 0) { - goto conn_exit; - } - /* Set last received header byte */ connsm->last_rxd_hdr_byte = hdr_byte; From 426c71bf3f17f6ef05ccc0634496bffc6b55f96a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 25 Feb 2022 14:53:18 +0100 Subject: [PATCH 0310/1333] nimble/ll: Fix checking AUX_CONNECT_RSP We should compare TargetA type in AUX_CONNECT_RSP to TxAdd bit in AUX_CONNECT_REQ. --- nimble/controller/src/ble_ll_scan_aux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index c637be7111..ed5ca815c1 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -1547,7 +1547,7 @@ ble_ll_scan_aux_check_connect_rsp(uint8_t *rxbuf, } #endif /* BLE_LL_CFG_FEAT_LL_PRIVACY */ - if ((targeta_type != !!(pdu_data->hdr_byte & BLE_ADV_PDU_HDR_RXADD_MASK)) || + if ((targeta_type != !!(pdu_data->hdr_byte & BLE_ADV_PDU_HDR_TXADD_MASK)) || (memcmp(targeta, pdu_data->inita, 6) != 0)) { return -1; } From 6d59b9c1cf315162a5aff131e346f1221379a738 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Tue, 8 Mar 2022 10:06:19 +0100 Subject: [PATCH 0311/1333] pkg.yml: make non-executable --- apps/central/pkg.yml | 0 apps/peripheral/pkg.yml | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 apps/central/pkg.yml mode change 100755 => 100644 apps/peripheral/pkg.yml diff --git a/apps/central/pkg.yml b/apps/central/pkg.yml old mode 100755 new mode 100644 diff --git a/apps/peripheral/pkg.yml b/apps/peripheral/pkg.yml old mode 100755 new mode 100644 From e2b73b4f327b66a3c4acb52cbbb60e27a4a35194 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Tue, 8 Mar 2022 10:13:45 +0100 Subject: [PATCH 0312/1333] includes: remove duplicate includes (remove 2nd) --- apps/btshell/src/main.c | 1 - apps/central/src/main.c | 1 - apps/scanner/src/main.c | 1 - babblesim/core/src/cmsis.c | 4 ---- nimble/controller/src/ble_ll_rfmgmt.c | 1 - nimble/drivers/dialog_cmac/src/ble_hw.c | 1 - nimble/drivers/dialog_cmac/src/ble_phy.c | 1 - nimble/host/mesh/src/pb_adv.c | 1 - nimble/host/mesh/src/pb_gatt.c | 1 - nimble/host/src/ble_att_cmd.c | 1 - nimble/host/src/ble_hs_priv.h | 1 - nimble/host/src/ble_uuid.c | 1 - 12 files changed, 15 deletions(-) diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index f4f864e7fa..7741050144 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -25,7 +25,6 @@ #include "bsp/bsp.h" #include "log/log.h" #include "stats/stats.h" -#include "bsp/bsp.h" #include "hal/hal_gpio.h" #include "console/console.h" #include "btshell.h" diff --git a/apps/central/src/main.c b/apps/central/src/main.c index b2370359bf..c088b947f2 100755 --- a/apps/central/src/main.c +++ b/apps/central/src/main.c @@ -22,7 +22,6 @@ #include "console/console.h" #include "host/ble_hs.h" #include "host/util/util.h" -#include "console/console.h" #include "log/log.h" static uint8_t g_own_addr_type; diff --git a/apps/scanner/src/main.c b/apps/scanner/src/main.c index d21bba4bbe..5158d0d5cb 100644 --- a/apps/scanner/src/main.c +++ b/apps/scanner/src/main.c @@ -22,7 +22,6 @@ #include "console/console.h" #include "host/ble_hs.h" #include "host/util/util.h" -#include "console/console.h" #include "log/log.h" /* scan_event() calls scan(), so forward declaration is required */ diff --git a/babblesim/core/src/cmsis.c b/babblesim/core/src/cmsis.c index 622676c881..9beb329091 100644 --- a/babblesim/core/src/cmsis.c +++ b/babblesim/core/src/cmsis.c @@ -14,12 +14,8 @@ #include "cmsis.h" #include "os/sim.h" -#include #include #include -#include "irq_sources.h" -#include -#include "cmsis.h" extern void (* systemVectors[256])(void); diff --git a/nimble/controller/src/ble_ll_rfmgmt.c b/nimble/controller/src/ble_ll_rfmgmt.c index f73f6b3dfa..1877b61952 100644 --- a/nimble/controller/src/ble_ll_rfmgmt.c +++ b/nimble/controller/src/ble_ll_rfmgmt.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "syscfg/syscfg.h" #include "controller/ble_phy.h" #include "controller/ble_ll.h" diff --git a/nimble/drivers/dialog_cmac/src/ble_hw.c b/nimble/drivers/dialog_cmac/src/ble_hw.c index 763de8dcfa..a2724b687d 100644 --- a/nimble/drivers/dialog_cmac/src/ble_hw.c +++ b/nimble/drivers/dialog_cmac/src/ble_hw.c @@ -24,7 +24,6 @@ #include "controller/ble_hw.h" #include "CMAC.h" #include "cmac_driver/cmac_shared.h" -#include "mcu/mcu.h" #include "tinycrypt/aes.h" static struct tc_aes_key_sched_struct g_ctx; diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index 9c9d878911..1e6a3c9999 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -24,7 +24,6 @@ #include #include -#include #include "nimble/ble.h" #include "mcu/mcu.h" #include "mcu/cmac_timer.h" diff --git a/nimble/host/mesh/src/pb_adv.c b/nimble/host/mesh/src/pb_adv.c index 1fa2c35b24..35a02b0dc0 100644 --- a/nimble/host/mesh/src/pb_adv.c +++ b/nimble/host/mesh/src/pb_adv.c @@ -20,7 +20,6 @@ #include "adv.h" #include "crypto.h" #include "beacon.h" -#include "prov.h" #include "mesh/glue.h" #define GPCF(gpc) (gpc & 0x03) diff --git a/nimble/host/mesh/src/pb_gatt.c b/nimble/host/mesh/src/pb_gatt.c index 9a0d7091e1..865356eeb5 100644 --- a/nimble/host/mesh/src/pb_gatt.c +++ b/nimble/host/mesh/src/pb_gatt.c @@ -14,7 +14,6 @@ #include "net.h" #include "proxy.h" #include "adv.h" -#include "prov.h" #include "syscfg/syscfg.h" #include "pb_gatt_srv.h" diff --git a/nimble/host/src/ble_att_cmd.c b/nimble/host/src/ble_att_cmd.c index e7192351c5..6669392f1e 100644 --- a/nimble/host/src/ble_att_cmd.c +++ b/nimble/host/src/ble_att_cmd.c @@ -24,7 +24,6 @@ #include "ble_hs_priv.h" #include "host/ble_att.h" #include "host/ble_uuid.h" -#include "ble_hs_priv.h" #if NIMBLE_BLE_CONNECT void * diff --git a/nimble/host/src/ble_hs_priv.h b/nimble/host/src/ble_hs_priv.h index 538d07a972..a57ec3cc86 100644 --- a/nimble/host/src/ble_hs_priv.h +++ b/nimble/host/src/ble_hs_priv.h @@ -29,7 +29,6 @@ #include "ble_hs_hci_priv.h" #include "ble_hs_atomic_priv.h" #include "ble_hs_conn_priv.h" -#include "ble_hs_atomic_priv.h" #include "ble_hs_mbuf_priv.h" #include "ble_hs_startup_priv.h" #include "ble_l2cap_priv.h" diff --git a/nimble/host/src/ble_uuid.c b/nimble/host/src/ble_uuid.c index 16352cf6e0..acf016a136 100644 --- a/nimble/host/src/ble_uuid.c +++ b/nimble/host/src/ble_uuid.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "os/os_mbuf.h" #include "nimble/ble.h" #include "ble_hs_priv.h" From fae820b5fc0f2522ba04ffc124c551961834ed56 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Tue, 8 Mar 2022 10:29:27 +0100 Subject: [PATCH 0313/1333] controller: include own header --- nimble/controller/src/ble_ll_conn.c | 1 + nimble/controller/src/ble_ll_trace.c | 1 + 2 files changed, 2 insertions(+) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index c2739f15dd..f3d903d1a4 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -27,6 +27,7 @@ #include "nimble/hci_common.h" #include "nimble/ble_hci_trans.h" #include "controller/ble_ll.h" +#include "controller/ble_ll_conn.h" #include "controller/ble_ll_hci.h" #include "controller/ble_ll_scan.h" #include "controller/ble_ll_whitelist.h" diff --git a/nimble/controller/src/ble_ll_trace.c b/nimble/controller/src/ble_ll_trace.c index 330b3d4c6a..625d73dd15 100644 --- a/nimble/controller/src/ble_ll_trace.c +++ b/nimble/controller/src/ble_ll_trace.c @@ -20,6 +20,7 @@ #include #include "syscfg/syscfg.h" #include "os/os_trace_api.h" +#include "controller/ble_ll_trace.h" #if MYNEWT_VAL(BLE_LL_SYSVIEW) From 9e63f5258b4b30d900d628d2f118bfa8bc5c80cb Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Tue, 8 Mar 2022 10:35:38 +0100 Subject: [PATCH 0314/1333] ble_hw: remove legacy functions (only present here) --- nimble/controller/include/controller/ble_hw.h | 6 ------ nimble/controller/include/controller/ble_phy.h | 3 --- 2 files changed, 9 deletions(-) diff --git a/nimble/controller/include/controller/ble_hw.h b/nimble/controller/include/controller/ble_hw.h index cf2930761a..394c3a173c 100644 --- a/nimble/controller/include/controller/ble_hw.h +++ b/nimble/controller/include/controller/ble_hw.h @@ -94,12 +94,6 @@ void ble_hw_resolv_list_rmv(int index); /* Returns the size of the whitelist in HW */ uint8_t ble_hw_resolv_list_size(void); -/* Enable the resolving list */ -void ble_hw_resolv_list_enable(void); - -/* Disables resolving list devices */ -void ble_hw_resolv_list_disable(void); - /* Returns index of resolved address; -1 if not resolved */ int ble_hw_resolv_list_match(void); diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index 3d32bd68ba..44e8809b28 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -83,9 +83,6 @@ typedef void (*ble_phy_tx_end_func)(void *arg); /* Initialize the PHY */ int ble_phy_init(void); -/* Reset the PHY */ -int ble_phy_reset(void); - /* Set the PHY channel */ int ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit); From 5edbd1dba3865b0fc5def0d147765ed38ac615da Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Tue, 8 Mar 2022 10:45:03 +0100 Subject: [PATCH 0315/1333] drivers: include your own header --- nimble/drivers/nrf5340/src/ble_phy_trace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/drivers/nrf5340/src/ble_phy_trace.c b/nimble/drivers/nrf5340/src/ble_phy_trace.c index 6967c3f779..dad7867907 100644 --- a/nimble/drivers/nrf5340/src/ble_phy_trace.c +++ b/nimble/drivers/nrf5340/src/ble_phy_trace.c @@ -20,6 +20,7 @@ #include #include #include +#include "controller/ble_phy_trace.h" #if MYNEWT_VAL(BLE_PHY_SYSVIEW) From a9e4b68d45a22f729f4a911e83d7ee5336ff78d8 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Tue, 8 Mar 2022 11:13:54 +0100 Subject: [PATCH 0316/1333] host: include own header(s) --- nimble/host/include/host/ble_hs_stop.h | 2 +- nimble/host/src/ble_att.c | 1 + nimble/host/src/ble_att_svr.c | 1 + nimble/host/src/ble_gap.c | 2 ++ nimble/host/src/ble_gattc.c | 1 + nimble/host/src/ble_gatts.c | 1 + nimble/host/src/ble_gatts_lcl.c | 1 + nimble/host/src/ble_hs.c | 1 + nimble/host/src/ble_hs_log.c | 1 + nimble/host/src/ble_hs_mbuf.c | 1 + nimble/host/src/ble_hs_stop.c | 3 ++- nimble/host/src/ble_ibeacon.c | 1 + nimble/host/src/ble_l2cap.c | 1 + 13 files changed, 15 insertions(+), 2 deletions(-) diff --git a/nimble/host/include/host/ble_hs_stop.h b/nimble/host/include/host/ble_hs_stop.h index d16c9c27bc..e4feb62bff 100644 --- a/nimble/host/include/host/ble_hs_stop.h +++ b/nimble/host/include/host/ble_hs_stop.h @@ -64,7 +64,7 @@ struct ble_hs_stop_listener { * BLE_HS_EALREADY: Host already stopped; the * provided callback does *not* get called. */ -int ble_hs_stop(struct ble_hs_stop_listener *listener, +int ble_hs_stop(struct ble_hs_stop_listener *listener, ble_hs_stop_fn *fn, void *arg); #endif diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index 8aab7f9190..5f119ac1cc 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -20,6 +20,7 @@ #include #include #include "ble_hs_priv.h" +#include "host/ble_att.h" #if NIMBLE_BLE_CONNECT static uint16_t ble_att_preferred_mtu_val; diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 468768ac02..73e258decb 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -21,6 +21,7 @@ #include #include #include "os/os.h" +#include "host/ble_att.h" #include "nimble/ble.h" #include "host/ble_uuid.h" #include "ble_hs_priv.h" diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 3d8f3038ae..621a88a0fc 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -21,9 +21,11 @@ #include #include #include "nimble/nimble_opt.h" +#include "host/ble_gap.h" #include "host/ble_hs_adv.h" #include "host/ble_hs_hci.h" #include "ble_hs_priv.h" +#include "ble_gap_priv.h" #if MYNEWT #include "bsp/bsp.h" diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index b43a0af03c..b0535fb816 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -56,6 +56,7 @@ #include #include "os/os_mempool.h" #include "nimble/ble.h" +#include "host/ble_gatt.h" #include "host/ble_uuid.h" #include "host/ble_gap.h" #include "ble_hs_priv.h" diff --git a/nimble/host/src/ble_gatts.c b/nimble/host/src/ble_gatts.c index 83402e7242..93809caa41 100644 --- a/nimble/host/src/ble_gatts.c +++ b/nimble/host/src/ble_gatts.c @@ -21,6 +21,7 @@ #include #include #include "nimble/ble.h" +#include "host/ble_gatt.h" #include "host/ble_uuid.h" #include "host/ble_store.h" #include "ble_hs_priv.h" diff --git a/nimble/host/src/ble_gatts_lcl.c b/nimble/host/src/ble_gatts_lcl.c index 938d736223..f824e9000a 100644 --- a/nimble/host/src/ble_gatts_lcl.c +++ b/nimble/host/src/ble_gatts_lcl.c @@ -19,6 +19,7 @@ #include #include +#include "host/ble_gatt.h" #include "host/ble_uuid.h" #include "console/console.h" #include "nimble/ble.h" diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index 9f39c8e66d..5e5c6442c9 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -24,6 +24,7 @@ #include "syscfg/syscfg.h" #include "stats/stats.h" #include "nimble/ble_hci_trans.h" +#include "host/ble_hs.h" #include "ble_hs_priv.h" #include "ble_monitor_priv.h" #include "nimble/nimble_npl.h" diff --git a/nimble/host/src/ble_hs_log.c b/nimble/host/src/ble_hs_log.c index 7ec69469eb..0670dca6ee 100644 --- a/nimble/host/src/ble_hs_log.c +++ b/nimble/host/src/ble_hs_log.c @@ -19,6 +19,7 @@ #include "os/os.h" #include "host/ble_hs.h" +#include "host/ble_hs_log.h" struct log ble_hs_log; diff --git a/nimble/host/src/ble_hs_mbuf.c b/nimble/host/src/ble_hs_mbuf.c index 6e920f94fe..f4d6a790f9 100644 --- a/nimble/host/src/ble_hs_mbuf.c +++ b/nimble/host/src/ble_hs_mbuf.c @@ -18,6 +18,7 @@ */ #include "host/ble_hs.h" +#include "host/ble_hs_mbuf.h" #include "ble_hs_priv.h" /** diff --git a/nimble/host/src/ble_hs_stop.c b/nimble/host/src/ble_hs_stop.c index b90d3ec6fc..e48fff389c 100644 --- a/nimble/host/src/ble_hs_stop.c +++ b/nimble/host/src/ble_hs_stop.c @@ -21,6 +21,7 @@ #include "sysinit/sysinit.h" #include "syscfg/syscfg.h" #include "ble_hs_priv.h" +#include "host/ble_hs_stop.h" #include "nimble/nimble_npl.h" #ifndef MYNEWT #include "nimble/nimble_port.h" @@ -217,7 +218,7 @@ ble_hs_stop_begin(struct ble_hs_stop_listener *listener, } int -ble_hs_stop(struct ble_hs_stop_listener *listener, +ble_hs_stop(struct ble_hs_stop_listener *listener, ble_hs_stop_fn *fn, void *arg) { int rc; diff --git a/nimble/host/src/ble_ibeacon.c b/nimble/host/src/ble_ibeacon.c index 0c6ef99d5b..bbd353cc98 100644 --- a/nimble/host/src/ble_ibeacon.c +++ b/nimble/host/src/ble_ibeacon.c @@ -19,6 +19,7 @@ #include #include "host/ble_hs_adv.h" +#include "host/ble_ibeacon.h" #include "ble_hs_priv.h" #define BLE_IBEACON_MFG_DATA_SIZE 25 diff --git a/nimble/host/src/ble_l2cap.c b/nimble/host/src/ble_l2cap.c index bfbdadfcd6..fb1a617613 100644 --- a/nimble/host/src/ble_l2cap.c +++ b/nimble/host/src/ble_l2cap.c @@ -21,6 +21,7 @@ #include #include "syscfg/syscfg.h" #include "os/os.h" +#include "host/ble_l2cap.h" #include "nimble/ble.h" #include "nimble/hci_common.h" #include "ble_hs_priv.h" From efe0217ad088aa6f1cfe90a4342cd4fd57134102 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Tue, 1 Mar 2022 15:20:15 +0100 Subject: [PATCH 0317/1333] transport/nrf5340: Fix IPC race condition ipc_nrf5340_recv was called in nrf_5340_ble_hci_init(), this function enabled BLE IPC channel if though host transport did not register yet. If that jump to NULL pointer happens. To prevent this IPC channel is configured after transport callbacks are setup. And only then interrupt is enabled for BLE IPC channel. --- nimble/transport/nrf5340/src/nrf5340_ble_hci.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index 41f164edb2..df5571ece9 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -168,6 +168,8 @@ ble_hci_trans_acl_tx(struct os_mbuf *om) return (rc < 0) ? BLE_ERR_MEM_CAPACITY : 0; } +static void nrf5340_ble_hci_trans_rx(int channel, void *user_data); + #if MYNEWT_VAL(BLE_CONTROLLER) void ble_hci_trans_cfg_ll(ble_hci_trans_rx_cmd_fn *cmd_cb, void *cmd_arg, @@ -177,6 +179,8 @@ ble_hci_trans_cfg_ll(ble_hci_trans_rx_cmd_fn *cmd_cb, void *cmd_arg, nrf5340_ble_hci_api.cmd_arg = cmd_arg; nrf5340_ble_hci_api.acl_cb = acl_cb; nrf5340_ble_hci_api.acl_arg = acl_arg; + + ipc_nrf5340_recv(IPC_RX_CHANNEL, nrf5340_ble_hci_trans_rx, NULL); } int @@ -212,6 +216,8 @@ ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *evt_cb, void *evt_arg, nrf5340_ble_hci_api.evt_arg = evt_arg; nrf5340_ble_hci_api.acl_cb = acl_cb; nrf5340_ble_hci_api.acl_arg = acl_arg; + + ipc_nrf5340_recv(IPC_RX_CHANNEL, nrf5340_ble_hci_trans_rx, NULL); } int @@ -511,6 +517,4 @@ nrf5340_ble_hci_init(void) "nrf5340_ble_hci_pool_cmd_mempool"); SYSINIT_PANIC_ASSERT(rc == 0); #endif - - ipc_nrf5340_recv(IPC_RX_CHANNEL, nrf5340_ble_hci_trans_rx, NULL); } From cd89a8ee30779602f82ab47c67ba7cd23b0a8a22 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Tue, 8 Mar 2022 16:05:48 +0100 Subject: [PATCH 0318/1333] nrf5340: dont depend on mynewt.h, but only on sysinit.h --- nimble/transport/nrf5340/src/nrf5340_ble_hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index df5571ece9..1f510e8a68 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include #include From 808ee41aee06e9f62812203b17d61a691d34caab Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 8 Mar 2022 15:43:46 +0100 Subject: [PATCH 0319/1333] nimble/ll: Add HCI Reset to supported commands Looks like bit for HCI Reset was not set in supported commands bitmask. --- nimble/controller/src/ble_ll_supp_cmd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_supp_cmd.c b/nimble/controller/src/ble_ll_supp_cmd.c index 2fc0d7d3af..f6dab06494 100644 --- a/nimble/controller/src/ble_ll_supp_cmd.c +++ b/nimble/controller/src/ble_ll_supp_cmd.c @@ -36,7 +36,12 @@ /* Octet 5 */ #define BLE_SUPP_CMD_SET_EVENT_MASK (1 << 6) -#define BLE_LL_SUPP_CMD_OCTET_5 (BLE_SUPP_CMD_SET_EVENT_MASK) +#define BLE_SUPP_CMD_RESET (1 << 7) +#define BLE_LL_SUPP_CMD_OCTET_5 \ +( \ + BLE_SUPP_CMD_SET_EVENT_MASK | \ + BLE_SUPP_CMD_RESET \ +) /* Octet 10 */ #define BLE_SUPP_CMD_RD_TX_PWR (0 << 2) From 6faa4027dea1d1ed58e344a7eba938ca308242e1 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 28 Feb 2022 11:05:06 +0100 Subject: [PATCH 0320/1333] nimble/ll: Optimize num used channels calculation Using single loop and uint32 should be more efficient than nested loops with uint8. --- .../include/controller/ble_ll_utils.h | 2 +- nimble/controller/src/ble_ll_utils.c | 37 +++++++------------ 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_utils.h b/nimble/controller/include/controller/ble_ll_utils.h index e0b1646793..48d76a6c32 100644 --- a/nimble/controller/include/controller/ble_ll_utils.h +++ b/nimble/controller/include/controller/ble_ll_utils.h @@ -23,7 +23,7 @@ uint32_t ble_ll_utils_calc_access_addr(void); uint8_t ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap); uint8_t ble_ll_utils_calc_dci_csa2(uint16_t event_cntr, uint16_t channel_id, uint8_t num_used_chans, const uint8_t *chanmap); -uint8_t ble_ll_utils_calc_num_used_chans(const uint8_t *chanmap); +uint8_t ble_ll_utils_calc_num_used_chans(const uint8_t *chan_map); uint32_t ble_ll_utils_calc_window_widening(uint32_t anchor_point, uint32_t last_anchor_point, uint8_t central_sca); diff --git a/nimble/controller/src/ble_ll_utils.c b/nimble/controller/src/ble_ll_utils.c index 66ca3e27a8..c31262680a 100644 --- a/nimble/controller/src/ble_ll_utils.c +++ b/nimble/controller/src/ble_ll_utils.c @@ -182,32 +182,23 @@ ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap) } uint8_t -ble_ll_utils_calc_num_used_chans(const uint8_t *chmap) +ble_ll_utils_calc_num_used_chans(const uint8_t *chan_map) { - int i; - int j; - uint8_t mask; - uint8_t chanbyte; - uint8_t used_channels; - - used_channels = 0; - for (i = 0; i < BLE_LL_CHMAP_LEN; ++i) { - chanbyte = chmap[i]; - if (chanbyte) { - if (chanbyte == 0xff) { - used_channels += 8; - } else { - mask = 0x01; - for (j = 0; j < 8; ++j) { - if (chanbyte & mask) { - ++used_channels; - } - mask <<= 1; - } - } + uint32_t u32 = 0; + uint32_t num_used_chans = 0; + unsigned idx; + + for (idx = 0; idx < 37; idx++) { + if ((idx % 8) == 0) { + u32 = chan_map[idx / 8]; } + if (u32 & 1) { + num_used_chans++; + } + u32 >>= 1; } - return used_channels; + + return num_used_chans; } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) From 21628969837beb9fa36f90817da0c00542a9cf1d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 28 Feb 2022 11:19:57 +0100 Subject: [PATCH 0321/1333] nimble/ll: Optimize CSA2 perm for Thumb2 Thumb2 has dedicated instructions for reversing bit and byte order so CSA2 permutation can be computed in 2 simple instructions. Also using uint32 for parameters means we skip zero-extending value every second instruction. --- nimble/controller/src/ble_ll_utils.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/nimble/controller/src/ble_ll_utils.c b/nimble/controller/src/ble_ll_utils.c index c31262680a..7b3a863de8 100644 --- a/nimble/controller/src/ble_ll_utils.c +++ b/nimble/controller/src/ble_ll_utils.c @@ -202,10 +202,22 @@ ble_ll_utils_calc_num_used_chans(const uint8_t *chan_map) } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) -static uint16_t -ble_ll_utils_csa2_perm(uint16_t in) +#if __thumb2__ +static inline uint32_t +ble_ll_utils_csa2_perm(uint32_t val) { - uint16_t out = 0; + __asm__ volatile (".syntax unified \n" + "rbit %[val], %[val] \n" + "rev %[val], %[val] \n" + : [val] "+r" (val)); + + return val; +} +#else +static uint32_t +ble_ll_utils_csa2_perm(uint32_t in) +{ + uint32_t out = 0; int i; for (i = 0; i < 8; i++) { @@ -218,6 +230,7 @@ ble_ll_utils_csa2_perm(uint16_t in) return out; } +#endif static uint16_t ble_ll_utils_csa2_prng(uint16_t counter, uint16_t ch_id) From 742bf62ea8f4a32a5c32440c13aee9c11f54e909 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 28 Feb 2022 11:37:25 +0100 Subject: [PATCH 0322/1333] nimble/ll: Refactor CSA2 prng a bit Prng calculates prn_e, but we also need prn_s (for iso subevents) which is genreated before final xor in prng. Add helper to calculate prn_s and make prng use it. Also split mam to separate helper just to make it look nicer. --- nimble/controller/src/ble_ll_utils.c | 36 ++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/nimble/controller/src/ble_ll_utils.c b/nimble/controller/src/ble_ll_utils.c index 7b3a863de8..ee25f8365d 100644 --- a/nimble/controller/src/ble_ll_utils.c +++ b/nimble/controller/src/ble_ll_utils.c @@ -232,23 +232,39 @@ ble_ll_utils_csa2_perm(uint32_t in) } #endif +static inline uint32_t +ble_ll_utils_csa2_mam(uint32_t a, uint32_t b) +{ + return (17 * a + b) % 65536; +} + static uint16_t -ble_ll_utils_csa2_prng(uint16_t counter, uint16_t ch_id) +ble_ll_utils_csa2_prn_s(uint16_t counter, uint16_t ch_id) { - uint16_t prn_e; + uint32_t prn_s; + + prn_s = counter ^ ch_id; - prn_e = counter ^ ch_id; + prn_s = ble_ll_utils_csa2_perm(prn_s); + prn_s = ble_ll_utils_csa2_mam(prn_s, ch_id); - prn_e = ble_ll_utils_csa2_perm(prn_e); - prn_e = (prn_e * 17) + ch_id; + prn_s = ble_ll_utils_csa2_perm(prn_s); + prn_s = ble_ll_utils_csa2_mam(prn_s, ch_id); - prn_e = ble_ll_utils_csa2_perm(prn_e); - prn_e = (prn_e * 17) + ch_id; + prn_s = ble_ll_utils_csa2_perm(prn_s); + prn_s = ble_ll_utils_csa2_mam(prn_s, ch_id); - prn_e = ble_ll_utils_csa2_perm(prn_e); - prn_e = (prn_e * 17) + ch_id; + return prn_s; +} + +static uint16_t +ble_ll_utils_csa2_prng(uint16_t counter, uint16_t ch_id) +{ + uint16_t prn_s; + uint16_t prn_e; - prn_e = prn_e ^ ch_id; + prn_s = ble_ll_utils_csa2_prn_s(counter, ch_id); + prn_e = prn_s ^ ch_id; return prn_e; } From d9c921a81527fe2787ab71a7b6364ae30ae44c5a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 28 Feb 2022 11:42:12 +0100 Subject: [PATCH 0323/1333] nimble/ll: Add generic helpers to calculate/remap chan_idx for CSA2 For events we calculate unmapped chan_idx from prn_e value and then remap it if necessary. For subevents we only need to calculate index of chan_idx on used channels list. --- nimble/controller/src/ble_ll_utils.c | 69 ++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/nimble/controller/src/ble_ll_utils.c b/nimble/controller/src/ble_ll_utils.c index ee25f8365d..c2edb0d875 100644 --- a/nimble/controller/src/ble_ll_utils.c +++ b/nimble/controller/src/ble_ll_utils.c @@ -269,6 +269,75 @@ ble_ll_utils_csa2_prng(uint16_t counter, uint16_t ch_id) return prn_e; } +/* Find remap_idx for given chan_idx */ +static uint16_t +ble_ll_utils_csa2_chan2remap(uint16_t chan_idx, const uint8_t *chan_map) +{ + uint16_t remap_idx = 0; + uint32_t u32 = 0; + unsigned idx; + + for (idx = 0; idx < 37; idx++) { + if ((idx % 8) == 0) { + u32 = chan_map[idx / 8]; + } + if (u32 & 1) { + if (idx == chan_idx) { + return remap_idx; + } + remap_idx++; + } + u32 >>= 1; + } + + BLE_LL_ASSERT(0); + + return 0; +} + +/* Find chan_idx at given remap_idx */ +static uint16_t +ble_ll_utils_csa2_remap2chan(uint16_t remap_idx, const uint8_t *chan_map) +{ + uint32_t u32 = 0; + unsigned idx; + + for (idx = 0; idx < 37; idx++) { + if ((idx % 8) == 0) { + u32 = chan_map[idx / 8]; + } + if (u32 & 1) { + if (!remap_idx) { + return idx; + } + remap_idx--; + } + u32 >>= 1; + } + + BLE_LL_ASSERT(0); + + return 0; +} + +static uint16_t +ble_ll_utils_csa2_calc_chan_idx(uint16_t prn_e, uint8_t num_used_chans, + const uint8_t *chanm_map, uint16_t *remap_idx) +{ + uint16_t chan_idx; + + chan_idx = prn_e % 37; + if (chanm_map[chan_idx / 8] & (1 << (chan_idx % 8))) { + *remap_idx = ble_ll_utils_csa2_chan2remap(chan_idx, chanm_map); + return chan_idx; + } + + *remap_idx = (num_used_chans * prn_e) / 65536; + chan_idx = ble_ll_utils_csa2_remap2chan(*remap_idx, chanm_map); + + return chan_idx; +} + uint8_t ble_ll_utils_calc_dci_csa2(uint16_t event_cntr, uint16_t channel_id, uint8_t num_used_chans, const uint8_t *chanmap) From ad36fd84d50df3d859c6ebaca0dd1f746b51fa98 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 28 Feb 2022 11:49:14 +0100 Subject: [PATCH 0324/1333] nimble/ll: Use common helper to calculate chan_idx for dci --- .../include/controller/ble_ll_utils.h | 6 ++ nimble/controller/src/ble_ll_utils.c | 63 ++++++++++++++----- 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_utils.h b/nimble/controller/include/controller/ble_ll_utils.h index 48d76a6c32..12d14edb0e 100644 --- a/nimble/controller/include/controller/ble_ll_utils.h +++ b/nimble/controller/include/controller/ble_ll_utils.h @@ -23,6 +23,12 @@ uint32_t ble_ll_utils_calc_access_addr(void); uint8_t ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap); uint8_t ble_ll_utils_calc_dci_csa2(uint16_t event_cntr, uint16_t channel_id, uint8_t num_used_chans, const uint8_t *chanmap); +uint16_t ble_ll_utils_dci_iso_event(uint16_t counter, uint16_t chan_id, + uint16_t *prn_sub_lu, uint8_t num_used_chans, + const uint8_t *chan_map, uint16_t *remap_idx); +uint16_t ble_ll_utils_dci_iso_subevent(uint16_t chan_id, uint16_t *prn_sub_lu, + uint8_t num_used_chans, const uint8_t *chan_map, + uint16_t *remap_idx); uint8_t ble_ll_utils_calc_num_used_chans(const uint8_t *chan_map); uint32_t ble_ll_utils_calc_window_widening(uint32_t anchor_point, uint32_t last_anchor_point, diff --git a/nimble/controller/src/ble_ll_utils.c b/nimble/controller/src/ble_ll_utils.c index c2edb0d875..1b2857665e 100644 --- a/nimble/controller/src/ble_ll_utils.c +++ b/nimble/controller/src/ble_ll_utils.c @@ -342,28 +342,61 @@ uint8_t ble_ll_utils_calc_dci_csa2(uint16_t event_cntr, uint16_t channel_id, uint8_t num_used_chans, const uint8_t *chanmap) { - uint16_t channel_unmapped; - uint8_t remap_index; - uint16_t prn_e; - uint8_t bitpos; + uint16_t chan_idx; + uint16_t remap_idx; prn_e = ble_ll_utils_csa2_prng(event_cntr, channel_id); - channel_unmapped = prn_e % 37; + chan_idx = ble_ll_utils_csa2_calc_chan_idx(prn_e, num_used_chans, chanmap, + &remap_idx); - /* - * If unmapped channel is the channel index of a used channel it is used - * as channel index. - */ - bitpos = 1 << (channel_unmapped & 0x07); - if (chanmap[channel_unmapped >> 3] & bitpos) { - return channel_unmapped; - } + return chan_idx; +} + +uint16_t +ble_ll_utils_dci_iso_event(uint16_t counter, uint16_t chan_id, + uint16_t *prn_sub_lu, uint8_t num_used_chans, + const uint8_t *chan_map, uint16_t *remap_idx) +{ + uint16_t prn_s; + uint16_t prn_e; + uint16_t chan_idx; + + prn_s = ble_ll_utils_csa2_prn_s(counter, chan_id); + prn_e = prn_s ^ chan_id; - remap_index = (num_used_chans * prn_e) / 0x10000; + *prn_sub_lu = prn_s; - return ble_ll_utils_remapped_channel(remap_index, chanmap); + chan_idx = ble_ll_utils_csa2_calc_chan_idx(prn_e, num_used_chans, chan_map, + remap_idx); + + return chan_idx; +} + +uint16_t +ble_ll_utils_dci_iso_subevent(uint16_t chan_id, uint16_t *prn_sub_lu, + uint8_t num_used_chans, const uint8_t *chan_map, + uint16_t *remap_idx) +{ + uint16_t prn_sub_se; + uint16_t chan_idx; + uint16_t d; + + *prn_sub_lu = ble_ll_utils_csa2_perm(*prn_sub_lu); + *prn_sub_lu = ble_ll_utils_csa2_mam(*prn_sub_lu, chan_id); + prn_sub_se = *prn_sub_lu ^ chan_id; + + /* Core 5.3, Vol 6, Part B, 4.5.8.3.6 (enjoy!) */ + /* TODO optimize this somehow */ + d = max(1, max(min(3, num_used_chans - 5), + min(11, (num_used_chans - 10) / 2))); + *remap_idx = (*remap_idx + d + prn_sub_se * + (num_used_chans - 2 * d + 1) / 65536) % num_used_chans; + + chan_idx = ble_ll_utils_csa2_remap2chan(*remap_idx, chan_map); + + return chan_idx; } #endif From 4e69f781b597fccfe1f87a28cc0d7f8fd43f6322 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 28 Feb 2022 11:52:47 +0100 Subject: [PATCH 0325/1333] nimble/ll: Rename util to calculate common CSA2 dci Just to have it consistent with iso utils. --- .../include/controller/ble_ll_utils.h | 4 ++-- nimble/controller/src/ble_ll_adv.c | 24 +++++++++---------- nimble/controller/src/ble_ll_conn.c | 4 ++-- nimble/controller/src/ble_ll_sync.c | 12 +++++----- nimble/controller/src/ble_ll_utils.c | 8 +++---- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_utils.h b/nimble/controller/include/controller/ble_ll_utils.h index 12d14edb0e..ae8abfb36e 100644 --- a/nimble/controller/include/controller/ble_ll_utils.h +++ b/nimble/controller/include/controller/ble_ll_utils.h @@ -21,8 +21,8 @@ uint32_t ble_ll_utils_calc_access_addr(void); uint8_t ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap); -uint8_t ble_ll_utils_calc_dci_csa2(uint16_t event_cntr, uint16_t channel_id, - uint8_t num_used_chans, const uint8_t *chanmap); +uint8_t ble_ll_utils_dci_csa2(uint16_t counter, uint16_t chan_id, + uint8_t num_used_chans, const uint8_t *chan_map); uint16_t ble_ll_utils_dci_iso_event(uint16_t counter, uint16_t chan_id, uint16_t *prn_sub_lu, uint8_t num_used_chans, const uint8_t *chan_map, uint16_t *remap_idx); diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 070c89ce58..bc04c8f0bc 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1371,10 +1371,10 @@ ble_ll_adv_aux_calculate(struct ble_ll_adv_sm *advsm, aux->ext_hdr = 0; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) - aux->chan = ble_ll_utils_calc_dci_csa2(advsm->event_cntr++, - advsm->channel_id, - g_ble_ll_conn_params.num_used_chans, - g_ble_ll_conn_params.central_chan_map); + aux->chan = ble_ll_utils_dci_csa2(advsm->event_cntr++, + advsm->channel_id, + g_ble_ll_conn_params.num_used_chans, + g_ble_ll_conn_params.central_chan_map); #else aux->chan = ble_ll_utils_remapped_channel(ble_ll_rand() % BLE_PHY_NUM_DATA_CHANS, g_ble_ll_conn_params.central_chan_map); @@ -2316,10 +2316,10 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm, * Preincrement event counter as we later send this in PDU so make sure * same values are used */ - chan = ble_ll_utils_calc_dci_csa2(++advsm->periodic_event_cntr, - advsm->periodic_channel_id, - advsm->periodic_num_used_chans, - advsm->periodic_chanmap); + chan = ble_ll_utils_dci_csa2(++advsm->periodic_event_cntr, + advsm->periodic_channel_id, + advsm->periodic_num_used_chans, + advsm->periodic_chanmap); ble_ll_adv_sync_calculate(advsm, sync, 0, chan); @@ -2405,10 +2405,10 @@ ble_ll_adv_periodic_schedule_next(struct ble_ll_adv_sm *advsm) BLE_LL_ASSERT(rem_sync_data_len > 0); /* we use separate counter for chaining */ - chan = ble_ll_utils_calc_dci_csa2(advsm->periodic_chain_event_cntr++, - advsm->periodic_channel_id, - advsm->periodic_num_used_chans, - advsm->periodic_chanmap); + chan = ble_ll_utils_dci_csa2(advsm->periodic_chain_event_cntr++, + advsm->periodic_channel_id, + advsm->periodic_num_used_chans, + advsm->periodic_chanmap); ble_ll_adv_sync_calculate(advsm, sync_next, next_sync_data_offset, chan); max_usecs = ble_ll_pdu_tx_time_get(sync_next->payload_len, advsm->sec_phy); diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index f3d903d1a4..c41c35b103 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -747,8 +747,8 @@ ble_ll_conn_calc_dci(struct ble_ll_conn_sm *conn, uint16_t latency) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) if (CONN_F_CSA2_SUPP(conn)) { - return ble_ll_utils_calc_dci_csa2(conn->event_cntr, conn->channel_id, - conn->num_used_chans, conn->chanmap); + return ble_ll_utils_dci_csa2(conn->event_cntr, conn->channel_id, + conn->num_used_chans, conn->chanmap); } #endif diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index e5ef0efe5e..43f328e3be 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -1178,8 +1178,8 @@ ble_ll_sync_next_event(struct ble_ll_sync_sm *sm, uint32_t cur_ww_adjust) } /* Calculate channel index of next event */ - sm->chan_index = ble_ll_utils_calc_dci_csa2(sm->event_cntr, sm->channel_id, - sm->num_used_chans, sm->chanmap); + sm->chan_index = ble_ll_utils_dci_csa2(sm->event_cntr, sm->channel_id, + sm->num_used_chans, sm->chanmap); cur_ww = ble_ll_utils_calc_window_widening(sm->anchor_point, sm->last_anchor_point, @@ -1409,8 +1409,8 @@ ble_ll_sync_info_event(struct ble_ll_scan_addr_data *addrd, sm->window_widening = BLE_LL_JITTER_USECS; /* Calculate channel index of first event */ - sm->chan_index = ble_ll_utils_calc_dci_csa2(sm->event_cntr, sm->channel_id, - sm->num_used_chans, sm->chanmap); + sm->chan_index = ble_ll_utils_dci_csa2(sm->event_cntr, sm->channel_id, + sm->num_used_chans, sm->chanmap); if (ble_ll_sched_sync(&sm->sch, rxhdr->beg_cputime, rxhdr->rem_usecs, offset, sm->phy_mode)) { @@ -1957,8 +1957,8 @@ ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, sm->phy_mode = phy_mode; /* Calculate channel index of first event */ - sm->chan_index = ble_ll_utils_calc_dci_csa2(sm->event_cntr, sm->channel_id, - sm->num_used_chans, sm->chanmap); + sm->chan_index = ble_ll_utils_dci_csa2(sm->event_cntr, sm->channel_id, + sm->num_used_chans, sm->chanmap); /* get anchor for specified conn event */ conn_event_count = get_le16(sync_ind + 20); diff --git a/nimble/controller/src/ble_ll_utils.c b/nimble/controller/src/ble_ll_utils.c index 1b2857665e..a2507ad288 100644 --- a/nimble/controller/src/ble_ll_utils.c +++ b/nimble/controller/src/ble_ll_utils.c @@ -339,16 +339,16 @@ ble_ll_utils_csa2_calc_chan_idx(uint16_t prn_e, uint8_t num_used_chans, } uint8_t -ble_ll_utils_calc_dci_csa2(uint16_t event_cntr, uint16_t channel_id, - uint8_t num_used_chans, const uint8_t *chanmap) +ble_ll_utils_dci_csa2(uint16_t counter, uint16_t chan_id, + uint8_t num_used_chans, const uint8_t *chan_map) { uint16_t prn_e; uint16_t chan_idx; uint16_t remap_idx; - prn_e = ble_ll_utils_csa2_prng(event_cntr, channel_id); + prn_e = ble_ll_utils_csa2_prng(counter, chan_id); - chan_idx = ble_ll_utils_csa2_calc_chan_idx(prn_e, num_used_chans, chanmap, + chan_idx = ble_ll_utils_csa2_calc_chan_idx(prn_e, num_used_chans, chan_map, &remap_idx); return chan_idx; From 899c4fa880f6d7379d9a45edf1921537d2a139a4 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 28 Feb 2022 10:20:57 +0100 Subject: [PATCH 0326/1333] nimble/ll: Add unit test for CSA2 (ISO) --- nimble/controller/test/src/ble_ll_csa2_test.c | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) diff --git a/nimble/controller/test/src/ble_ll_csa2_test.c b/nimble/controller/test/src/ble_ll_csa2_test.c index 5261eb5beb..566500e36a 100644 --- a/nimble/controller/test/src/ble_ll_csa2_test.c +++ b/nimble/controller/test/src/ble_ll_csa2_test.c @@ -22,6 +22,7 @@ #include "testutil/testutil.h" #include "controller/ble_ll_test.h" #include "controller/ble_ll_conn.h" +#include "controller/ble_ll_utils.h" #include "ble_ll_csa2_test.h" TEST_CASE_SELF(ble_ll_csa2_test_1) @@ -108,8 +109,179 @@ TEST_CASE_SELF(ble_ll_csa2_test_2) TEST_ASSERT(rc == 34); } +TEST_CASE_SELF(ble_ll_csa2_test_3) +{ + uint8_t chan_map[5]; + uint8_t num_used_chans; + uint16_t chan_id; + uint16_t prn_sub_lu; + uint16_t chan_idx; + uint16_t remap_idx; + + /* Sample data: Core 5.3, Vol 6, Part C, 3.1 */ + chan_map[0] = 0xff; + chan_map[1] = 0xff; + chan_map[2] = 0xff; + chan_map[3] = 0xff; + chan_map[4] = 0x1f; + num_used_chans = ble_ll_utils_calc_num_used_chans(chan_map); + TEST_ASSERT(num_used_chans == 37); + chan_id = 0x305f; + + chan_idx = ble_ll_utils_dci_iso_event(0, chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 56857); + TEST_ASSERT(chan_idx == 25); + TEST_ASSERT(remap_idx == 25); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 11710); + TEST_ASSERT(chan_idx == 1); + TEST_ASSERT(remap_idx == 1); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 16649); + TEST_ASSERT(chan_idx == 16); + TEST_ASSERT(remap_idx == 16); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 38198); + TEST_ASSERT(chan_idx == 36); + TEST_ASSERT(remap_idx == 36); + + chan_idx = ble_ll_utils_dci_iso_event(1, chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 1685); + TEST_ASSERT(chan_idx == 20); + TEST_ASSERT(remap_idx == 20); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 20925); + TEST_ASSERT(chan_idx == 36); + TEST_ASSERT(remap_idx == 36); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 11081); + TEST_ASSERT(chan_idx == 12); + TEST_ASSERT(remap_idx == 12); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 48920); + TEST_ASSERT(chan_idx == 34); + TEST_ASSERT(remap_idx == 34); + + chan_idx = ble_ll_utils_dci_iso_event(2, chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 38301); + TEST_ASSERT(chan_idx == 6); + TEST_ASSERT(remap_idx == 6); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 6541); + TEST_ASSERT(chan_idx == 18); + TEST_ASSERT(remap_idx == 18); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 14597); + TEST_ASSERT(chan_idx == 32); + TEST_ASSERT(remap_idx == 32); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 62982); + TEST_ASSERT(chan_idx == 21); + TEST_ASSERT(remap_idx == 21); + + chan_idx = ble_ll_utils_dci_iso_event(3, chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 27475); + TEST_ASSERT(chan_idx == 21); + TEST_ASSERT(remap_idx == 21); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 40400); + TEST_ASSERT(chan_idx == 4); + TEST_ASSERT(remap_idx == 4); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 30015); + TEST_ASSERT(chan_idx == 22); + TEST_ASSERT(remap_idx == 22); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 49818); + TEST_ASSERT(chan_idx == 8); + TEST_ASSERT(remap_idx == 8); + + /* Sample data: Core 5.3, Vol 6, Part C, 3.2 */ + chan_map[0] = 0x00; + chan_map[1] = 0x06; + chan_map[2] = 0xe0; + chan_map[3] = 0x00; + chan_map[4] = 0x1e; + num_used_chans = ble_ll_utils_calc_num_used_chans(chan_map); + TEST_ASSERT(num_used_chans == 9); + chan_id = 0x305f; + + chan_idx = ble_ll_utils_dci_iso_event(6, chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 10975); + TEST_ASSERT(chan_idx == 23); + TEST_ASSERT(remap_idx == 4); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 14383); + TEST_ASSERT(chan_idx == 35); + TEST_ASSERT(remap_idx == 7); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 28946); + TEST_ASSERT(chan_idx == 21); + TEST_ASSERT(remap_idx == 2); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 61038); + TEST_ASSERT(chan_idx == 36); + TEST_ASSERT(remap_idx == 8); + + chan_idx = ble_ll_utils_dci_iso_event(7, chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 5490); + TEST_ASSERT(chan_idx == 9); + TEST_ASSERT(remap_idx == 0); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 4108); + TEST_ASSERT(chan_idx == 22); + TEST_ASSERT(remap_idx == 3); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 45462); + TEST_ASSERT(chan_idx == 36); + TEST_ASSERT(remap_idx == 8); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 64381); + TEST_ASSERT(chan_idx == 33); + TEST_ASSERT(remap_idx == 5); + + chan_idx = ble_ll_utils_dci_iso_event(8, chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 46970); + TEST_ASSERT(chan_idx == 34); + TEST_ASSERT(remap_idx == 6); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 7196); + TEST_ASSERT(chan_idx == 9); + TEST_ASSERT(remap_idx == 0); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 33054); + TEST_ASSERT(chan_idx == 33); + TEST_ASSERT(remap_idx == 5); + + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + TEST_ASSERT((prn_sub_lu ^ chan_id) == 42590); + TEST_ASSERT(chan_idx == 10); + TEST_ASSERT(remap_idx == 1); +} + TEST_SUITE(ble_ll_csa2_test_suite) { ble_ll_csa2_test_1(); ble_ll_csa2_test_2(); + ble_ll_csa2_test_3(); } From a59d9a4416d2471330936d31cb92fb8cf3ea6982 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 11 Mar 2022 10:55:43 +0100 Subject: [PATCH 0327/1333] travis: Remove newt test on osx We moved to more recent OSX version that do not support 32-bit images anymore co can't do "newt test" on osx. --- .travis.yml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7567ce3e05..d3dd9742b8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -102,25 +102,6 @@ matrix: - VM_AMOUNT=1 - TARGET_SET=1 - # newt test all - - os: osx - osx_image: xcode9.2 - env: - - TEST=TEST_ALL - - VM_AMOUNT=3 - - TARGET_SET=1 - - os: osx - osx_image: xcode9.2 - env: - - TEST=TEST_ALL - - VM_AMOUNT=3 - - TARGET_SET=2 - - os: osx - osx_image: xcode9.2 - env: - - TEST=TEST_ALL - - VM_AMOUNT=3 - - TARGET_SET=3 - os: windows env: - TEST=BUILD_TARGETS_WINDOWS From 788fd3e378940bf72b2240a14afbd2eedcf778c9 Mon Sep 17 00:00:00 2001 From: Jakub Date: Thu, 23 Sep 2021 12:24:32 +0200 Subject: [PATCH 0328/1333] apps/bttester: set filter accept list Receive addrs and save them to filter accept list. Fix for GAP/CONN/ACEP/BV-04-C test. --- apps/bttester/src/bttester.h | 5 +++++ apps/bttester/src/gap.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/apps/bttester/src/bttester.h b/apps/bttester/src/bttester.h index 4a8fc47142..4bf7485779 100644 --- a/apps/bttester/src/bttester.h +++ b/apps/bttester/src/bttester.h @@ -320,6 +320,11 @@ struct gap_set_mitm_cmd { uint8_t mitm; } __packed; +#define GAP_SET_FILTER_ACCEPT_LIST 0x1c +struct gap_set_filter_accept_list_cmd { + uint8_t list_len; + ble_addr_t addrs[]; +} __packed; /* events */ #define GAP_EV_NEW_SETTINGS 0x80 struct gap_new_settings_ev { diff --git a/apps/bttester/src/gap.c b/apps/bttester/src/gap.c index 75adeb9fc0..ce6cf33dbf 100644 --- a/apps/bttester/src/gap.c +++ b/apps/bttester/src/gap.c @@ -1230,10 +1230,15 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg) static void connect(const uint8_t *data, uint16_t len) { uint8_t status = BTP_STATUS_SUCCESS; + ble_addr_t *addr = (ble_addr_t *) data; SYS_LOG_DBG(""); - if (ble_gap_connect(own_addr_type, (ble_addr_t *) data, 0, + if (ble_addr_cmp(BLE_ADDR_ANY, addr) == 0) { + addr = NULL; + } + + if (ble_gap_connect(own_addr_type, addr, 0, &dflt_conn_params, gap_event_cb, NULL)) { status = BTP_STATUS_FAILED; } @@ -1574,6 +1579,27 @@ static void set_mitm(const uint8_t *data, uint16_t len) CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } +static void set_filter_accept_list(const uint8_t *data, uint16_t len) +{ + uint8_t status = BTP_STATUS_SUCCESS; + struct gap_set_filter_accept_list_cmd *tmp = + (struct gap_set_filter_accept_list_cmd *) data; + + SYS_LOG_DBG(""); + + /* + * Check if the nb of bytes received matches the len of addrs list. + * Then set the filter accept list. + */ + if (((len - sizeof(tmp->list_len))/sizeof(ble_addr_t) != + tmp->list_len) || ble_gap_wl_set(tmp->addrs, tmp->list_len)) { + status = BTP_STATUS_FAILED; + } + + tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_FILTER_ACCEPT_LIST, + CONTROLLER_INDEX, status); +} + void tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len) { @@ -1665,6 +1691,9 @@ void tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data, case GAP_SET_MITM: set_mitm(data, len); return; + case GAP_SET_FILTER_ACCEPT_LIST: + set_filter_accept_list(data, len); + return; default: tester_rsp(BTP_SERVICE_ID_GAP, opcode, index, BTP_STATUS_UNKNOWN_CMD); From d185f627552b18ef2626f903c6aa6a56f9ac8d92 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 9 Mar 2022 12:37:14 +0100 Subject: [PATCH 0329/1333] nimble/ll: Add fake dual mode option This adds option to enable some hacks to allow controller to be initialized by dual-mode host. It basically fakes some HCI commands that we do not support since they are not relevant for LE or replies for commands that we do support but need to be updated for BR/EDR features. This allows for NimBLE controller to be used as a Bluetooth controller e.g. in Windows 10, at least to some extent. This option is not intended to be used for production setup, it should be only used for testing purposes. --- nimble/controller/src/ble_ll_hci.c | 67 ++++++++++++++++++++++++++++++ nimble/controller/syscfg.hbd.yml | 25 +++++++++++ nimble/controller/syscfg.yml | 4 ++ 3 files changed, 96 insertions(+) create mode 100644 nimble/controller/syscfg.hbd.yml diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index d368672914..3dfc4a0476 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1571,6 +1571,62 @@ ble_ll_hci_status_params_cmd_proc(const uint8_t *cmdbuf, uint8_t len, return rc; } +#if MYNEWT_VAL(BLE_LL_HBD_FAKE_DUAL_MODE) +static int +ble_ll_hci_cmd_fake_dual_mode(uint16_t opcode, uint8_t *cmdbuf, uint8_t len, + uint8_t *rspbuf, uint8_t *rsplen) +{ + int rc; + + switch (opcode) { + case BLE_HCI_OP(BLE_HCI_OGF_LINK_CTRL, 0x01): /* Inquiry */ + rc = BLE_ERR_MAX + 1; + break; + case BLE_HCI_OP(BLE_HCI_OGF_LINK_CTRL, 0x02): /* Inquiry Cancel */ + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x13): /* Write Local Name */ + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x18): /* Write Page Timeout */ + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x1a): /* Write Scan Enable */ + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x1c): /* Write Page Scan Activity */ + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x1e): /* Write Inquiry Scan Activity */ + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x20): /* Write Authentication Enable */ + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x24): /* Write Class Of Device */ + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x33): /* Host Buffer Size */ + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x45): /* Write Inquiry Mode */ + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x52): /* Write Extended Inquiry Response */ + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x6d): /* Write LE Host Support */ + rc = 0; + break; + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x58): /* Read Inquiry Response Transmit Power Level */ + rspbuf[0] = 0x04; + *rsplen = 1; + rc = 0; + break; + case BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT): + put_le64(rspbuf, 0x877bffdbfe0ffebf); + *rsplen = 8; + rc = 0; + break; + case BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_BUF_SIZE): + put_le16(rspbuf, 255); + rspbuf[2] = 0; + put_le16(rspbuf + 3, 4); + put_le16(rspbuf + 5, 0); + *rsplen = 7; + rc = 0; + break; + case BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_SUPP_STATES): + put_le64(rspbuf, 0x000003ffffffffff); + *rsplen = 8; + rc = 0; + break; + default: + rc = -1; + } + + return rc; +} +#endif + /** * Called to process an HCI command from the host. * @@ -1614,6 +1670,14 @@ ble_ll_hci_cmd_proc(struct ble_npl_event *ev) /* Assume response length is zero */ rsplen = 0; +#if MYNEWT_VAL(BLE_LL_HBD_FAKE_DUAL_MODE) + rc = ble_ll_hci_cmd_fake_dual_mode(opcode, cmd->data, cmd->length, + rspbuf, &rsplen); + if (rc >= 0) { + goto send_cc_cs; + } +#endif + switch (ogf) { case BLE_HCI_OGF_LINK_CTRL: rc = ble_ll_hci_link_ctrl_cmd_proc(cmd->data, cmd->length, ocf); @@ -1648,6 +1712,9 @@ ble_ll_hci_cmd_proc(struct ble_npl_event *ev) rc += (BLE_ERR_MAX + 1); } +#if MYNEWT_VAL(BLE_LL_HBD_FAKE_DUAL_MODE) +send_cc_cs: +#endif /* If no response is generated, we free the buffers */ BLE_LL_ASSERT(rc >= 0); if (rc <= BLE_ERR_MAX) { diff --git a/nimble/controller/syscfg.hbd.yml b/nimble/controller/syscfg.hbd.yml new file mode 100644 index 0000000000..d5a05e1444 --- /dev/null +++ b/nimble/controller/syscfg.hbd.yml @@ -0,0 +1,25 @@ +# 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. +# + +syscfg.defs: + BLE_LL_HBD_FAKE_DUAL_MODE: + description: > + This enables hacks to allow initialize controler as dual-mode + device. It can be initialized and used by Windows 10 to some + extent. + value: 0 diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index a312ab3f12..a9b4321c09 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -559,3 +559,7 @@ syscfg.restrictions: - BLE_LL_PUBLIC_DEV_ADDR <= 0xffffffffffff - BLE_LL_PA == 0 || BLE_LL_PA_GPIO >= 0 - BLE_LL_LNA == 0 || BLE_LL_LNA_GPIO >= 0 + +$import: + # "Here be dragons" settings + - "@apache-mynewt-nimble/nimble/controller/syscfg.hbd.yml" From a8e4aeb87e79641a5ea046ba7cf900d1729dae26 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 3 Mar 2022 16:10:31 +0100 Subject: [PATCH 0330/1333] nimble/transport: Add common HCI H4 code This can be shared by UART, CMAC and nRF5340. --- .../hci_h4/include/nimble/transport/hci_h4.h | 68 ++++ nimble/transport/common/hci_h4/pkg.yml | 26 ++ nimble/transport/common/hci_h4/src/hci_h4.c | 304 ++++++++++++++++++ 3 files changed, 398 insertions(+) create mode 100644 nimble/transport/common/hci_h4/include/nimble/transport/hci_h4.h create mode 100644 nimble/transport/common/hci_h4/pkg.yml create mode 100644 nimble/transport/common/hci_h4/src/hci_h4.c diff --git a/nimble/transport/common/hci_h4/include/nimble/transport/hci_h4.h b/nimble/transport/common/hci_h4/include/nimble/transport/hci_h4.h new file mode 100644 index 0000000000..139160a545 --- /dev/null +++ b/nimble/transport/common/hci_h4/include/nimble/transport/hci_h4.h @@ -0,0 +1,68 @@ +/* + * 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 _HCI_H4_H_ +#define _HCI_H4_H_ + +#include + +#define HCI_H4_NONE 0x00 +#define HCI_H4_CMD 0x01 +#define HCI_H4_ACL 0x02 +#define HCI_H4_EVT 0x04 +#define HCI_H4_ISO 0x05 + +typedef void *(hci_h4_alloc_cmd)(void); +typedef void *(hci_h4_alloc_evt)(int); +typedef struct os_mbuf *(hci_h4_alloc_acl)(void); + +struct hci_h4_allocators { + hci_h4_alloc_cmd *cmd; + hci_h4_alloc_acl *acl; + hci_h4_alloc_evt *evt; +}; + +extern const struct hci_h4_allocators hci_h4_allocs_from_ll; +extern const struct hci_h4_allocators hci_h4_allocs_from_hs; + +typedef int (hci_h4_frame_cb)(uint8_t pkt_type, void *data); + +struct hci_h4_sm { + uint8_t state; + uint8_t pkt_type; + uint8_t min_len; + uint16_t len; + uint16_t exp_len; + uint8_t hdr[4]; + union { + uint8_t *buf; + struct os_mbuf *om; + }; + + const struct hci_h4_allocators *allocs; + hci_h4_frame_cb *frame_cb; +}; + +void hci_h4_sm_init(struct hci_h4_sm *h4sm, + const struct hci_h4_allocators *allocs, + hci_h4_frame_cb *frame_cb); + +int hci_h4_sm_rx(struct hci_h4_sm *h4sm, const uint8_t *buf, uint16_t len); + +#endif /* _HCI_H4_H_ */ diff --git a/nimble/transport/common/hci_h4/pkg.yml b/nimble/transport/common/hci_h4/pkg.yml new file mode 100644 index 0000000000..24c4b58071 --- /dev/null +++ b/nimble/transport/common/hci_h4/pkg.yml @@ -0,0 +1,26 @@ +# +# 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: nimble/transport/common/hci_h4 +pkg.description: HCI H4 protocol +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" + +pkg.deps: + - nimble diff --git a/nimble/transport/common/hci_h4/src/hci_h4.c b/nimble/transport/common/hci_h4/src/hci_h4.c new file mode 100644 index 0000000000..ac76ab0319 --- /dev/null +++ b/nimble/transport/common/hci_h4/src/hci_h4.c @@ -0,0 +1,304 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HCI_H4_SM_W4_PKT_TYPE 0 +#define HCI_H4_SM_W4_HEADER 1 +#define HCI_H4_SM_W4_PAYLOAD 2 +#define HCI_H4_SM_COMPLETED 3 + +const struct hci_h4_allocators hci_h4_allocs_from_ll = { + .acl = ble_transport_alloc_acl_from_ll, + .evt = ble_transport_alloc_evt, +}; +const struct hci_h4_allocators hci_h4_allocs_from_hs = { + .cmd = ble_transport_alloc_cmd, + .acl = ble_transport_alloc_acl_from_hs, +}; + +struct hci_h4_input_buffer { + const uint8_t *buf; + uint16_t len; +}; + +static void +hci_h4_frame_start(struct hci_h4_sm *rxs, uint8_t pkt_type) +{ + rxs->pkt_type = pkt_type; + rxs->len = 0; + rxs->exp_len = 0; + + switch (rxs->pkt_type) { + case HCI_H4_CMD: + rxs->min_len = 3; + break; + case HCI_H4_ACL: + rxs->min_len = 4; + break; + case HCI_H4_EVT: + rxs->min_len = 2; + break; + default: + /* XXX sync loss */ + assert(0); + break; + } +} + +static int +hci_h4_ib_consume(struct hci_h4_input_buffer *ib, uint16_t len) +{ + assert(ib->len >= len); + + ib->buf += len; + ib->len -= len; + + return len; +} + +static int +hci_h4_ib_pull_min_len(struct hci_h4_sm *rxs, + struct hci_h4_input_buffer *ib) +{ + uint16_t len; + + len = min(ib->len, rxs->min_len - rxs->len); + memcpy(&rxs->hdr[rxs->len], ib->buf, len); + + rxs->len += len; + hci_h4_ib_consume(ib, len); + + return rxs->len != rxs->min_len; +} + +static int +hci_h4_sm_w4_header(struct hci_h4_sm *h4sm, struct hci_h4_input_buffer *ib) +{ + int rc; + + rc = hci_h4_ib_pull_min_len(h4sm, ib); + if (rc) { + /* need more data */ + return 1; + } + + switch (h4sm->pkt_type) { + case HCI_H4_CMD: + assert(h4sm->allocs && h4sm->allocs->cmd); + h4sm->buf = h4sm->allocs->cmd(); + if (!h4sm->buf) { + return -1; + } + + memcpy(h4sm->buf, h4sm->hdr, h4sm->len); + h4sm->exp_len = h4sm->hdr[2] + 3; + break; + case HCI_H4_ACL: + assert(h4sm->allocs && h4sm->allocs->acl); + h4sm->om = h4sm->allocs->acl(); + if (!h4sm->om) { + return -1; + } + + os_mbuf_append(h4sm->om, h4sm->hdr, h4sm->len); + h4sm->exp_len = get_le16(&h4sm->hdr[2]) + 4; + break; + case HCI_H4_EVT: + if (h4sm->hdr[0] == BLE_HCI_EVCODE_LE_META) { + /* For LE Meta event we need 3 bytes to parse header */ + h4sm->min_len = 3; + rc = hci_h4_ib_pull_min_len(h4sm, ib); + if (rc) { + /* need more data */ + return 1; + } + } + + /* TODO lo/hi pool? */ + + assert(h4sm->allocs && h4sm->allocs->evt); + h4sm->buf = h4sm->allocs->evt(0); + if (!h4sm->buf) { + return -1; + } + + memcpy(h4sm->buf, h4sm->hdr, h4sm->len); + + h4sm->exp_len = h4sm->hdr[1] + 2; + break; + default: + assert(0); + break; + } + + return 0; +} + +static int +hci_h4_sm_w4_payload(struct hci_h4_sm *h4sm, + struct hci_h4_input_buffer *ib) +{ + uint16_t mbuf_len; + uint16_t len; + int rc; + + len = min(ib->len, h4sm->exp_len - h4sm->len); + + switch (h4sm->pkt_type) { + case HCI_H4_CMD: + case HCI_H4_EVT: + if (h4sm->buf) { + memcpy(&h4sm->buf[h4sm->len], ib->buf, len); + } + break; + case HCI_H4_ACL: + assert(h4sm->om); + + mbuf_len = OS_MBUF_PKTLEN(h4sm->om); + rc = os_mbuf_append(h4sm->om, ib->buf, len); + if (rc) { + /* Some data may already be appended so need to adjust h4sm only by + * the size of appended data. + */ + len = OS_MBUF_PKTLEN(h4sm->om) - mbuf_len; + h4sm->len += len; + hci_h4_ib_consume(ib, len); + + return -1; + } + break; + default: + assert(0); + break; + } + + h4sm->len += len; + hci_h4_ib_consume(ib, len); + + /* return 1 if need more data */ + return h4sm->len != h4sm->exp_len; +} + +static void +hci_h4_sm_completed(struct hci_h4_sm *h4sm) +{ + int rc; + + switch (h4sm->pkt_type) { + case HCI_H4_CMD: + case HCI_H4_EVT: + if (h4sm->buf) { + assert(h4sm->frame_cb); + rc = h4sm->frame_cb(h4sm->pkt_type, h4sm->buf); + if (rc != 0) { + ble_transport_free(h4sm->buf); + } + h4sm->buf = NULL; + } + break; + case HCI_H4_ACL: + if (h4sm->om) { + assert(h4sm->frame_cb); + rc = h4sm->frame_cb(h4sm->pkt_type, h4sm->om); + if (rc != 0) { + os_mbuf_free_chain(h4sm->om); + } + h4sm->om = NULL; + } + break; + default: + assert(0); + break; + } +} + +int +hci_h4_sm_rx(struct hci_h4_sm *h4sm, const uint8_t *buf, uint16_t len) +{ + struct hci_h4_input_buffer ib = { + .buf = buf, + .len = len, + }; + + int rc = 0; + while (ib.len && (rc >= 0)) { + rc = 0; + switch (h4sm->state) { + case HCI_H4_SM_W4_PKT_TYPE: + hci_h4_frame_start(h4sm, ib.buf[0]); + hci_h4_ib_consume(&ib, 1); + h4sm->state = HCI_H4_SM_W4_HEADER; + /* no break */ + case HCI_H4_SM_W4_HEADER: + rc = hci_h4_sm_w4_header(h4sm, &ib); + if (rc) { + break; + } + h4sm->state = HCI_H4_SM_W4_PAYLOAD; + /* no break */ + case HCI_H4_SM_W4_PAYLOAD: + rc = hci_h4_sm_w4_payload(h4sm, &ib); + if (rc) { + break; + } + h4sm->state = HCI_H4_SM_COMPLETED; + /* no break */ + case HCI_H4_SM_COMPLETED: + hci_h4_sm_completed(h4sm); + h4sm->state = HCI_H4_SM_W4_PKT_TYPE; + break; + default: + assert(0); + break; + } + } + + /* Calculate consumed bytes + * + * Note: we should always consume some bytes unless there is an oom error. + * It's also possible that we have an oom error but already consumed some + * data, in such case just return success and error will be returned on next + * pass. + */ + len = len - ib.len; + if (len == 0) { + assert(rc < 0); + return -1; + } + + return len; +} + +void +hci_h4_sm_init(struct hci_h4_sm *h4sm, const struct hci_h4_allocators *allocs, + hci_h4_frame_cb *frame_cb) +{ + memset(h4sm, 0, sizeof(*h4sm)); + h4sm->allocs = allocs; + h4sm->frame_cb = frame_cb; +} From d5201cb83bf0a5f3b9788b0721b656fb22a96223 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 3 Mar 2022 18:07:56 +0100 Subject: [PATCH 0331/1333] nimble/transport: Add common code for new HCI transport --- nimble/include/nimble/ble_hci_trans.h | 192 ----------------- nimble/transport/include/nimble/transport.h | 55 +++++ nimble/transport/pkg.yml | 48 ++--- nimble/transport/src/transport.c | 217 ++++++++++++++++++++ nimble/transport/syscfg.defunct.yml | 40 ++++ nimble/transport/syscfg.yml | 153 ++++++-------- 6 files changed, 394 insertions(+), 311 deletions(-) delete mode 100644 nimble/include/nimble/ble_hci_trans.h create mode 100644 nimble/transport/include/nimble/transport.h create mode 100644 nimble/transport/src/transport.c create mode 100644 nimble/transport/syscfg.defunct.yml diff --git a/nimble/include/nimble/ble_hci_trans.h b/nimble/include/nimble/ble_hci_trans.h deleted file mode 100644 index e8d3ec0311..0000000000 --- a/nimble/include/nimble/ble_hci_trans.h +++ /dev/null @@ -1,192 +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_ - -#include -#include "os/os_mempool.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct os_mbuf; - -#define BLE_HCI_TRANS_CMD_SZ 260 - -/*** Type of buffers for holding commands and events. */ -/** - * Controller-to-host event buffers. Events have one of two priorities: - * o Low-priority (BLE_HCI_TRANS_BUF_EVT_LO) - * o High-priority (BLE_HCI_TRANS_BUF_EVT_HI) - * - * Low-priority event buffers are only used for advertising reports. If there - * are no free low-priority event buffers, then an incoming advertising report - * will get dropped. - * - * High-priority event buffers are for everything except advertising reports. - * If there are no free high-priority event buffers, a request to allocate one - * will try to allocate a low-priority buffer instead. - * - * If you want all events to be given equal treatment, then you should allocate - * low-priority events only. - * - * Event priorities solve the problem of critical events getting dropped due to - * a flood of advertising reports. This solution is likely temporary: when - * HCI flow control is added, event priorities may become obsolete. - * - * Not all transports distinguish between low and high priority events. If the - * transport does not have separate settings for low and high buffer counts, - * then it treats all events with equal priority. - */ -#define BLE_HCI_TRANS_BUF_EVT_LO 1 -#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 a callback to get executed whenever an ACL data packet is freed. - * The function is called immediately before the free occurs. - * - * @param cb The callback to configure. - * @param arg An optional argument to pass to the callback. - * - * @return 0 on success; - * BLE_ERR_UNSUPPORTED if the transport does not - * support this operation. - */ -int ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg); - -/** - * 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 evt_cb The callback to execute upon receiving an HCI - * event. - * @param evt_arg Optional argument to pass to the event - * 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 *evt_cb, - void *evt_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); - -#ifdef __cplusplus -} -#endif - -#endif /* H_HCI_TRANSPORT_ */ diff --git a/nimble/transport/include/nimble/transport.h b/nimble/transport/include/nimble/transport.h new file mode 100644 index 0000000000..98dba30c60 --- /dev/null +++ b/nimble/transport/include/nimble/transport.h @@ -0,0 +1,55 @@ +/* + * 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_NIMBLE_TRANSPORT_ +#define H_NIMBLE_TRANSPORT_ + +#ifdef __cplusplus +extern "C" { +#endif + +struct os_mbuf; + +/* Init functions to be implemented for transport acting as HS/LL side */ +extern void ble_transport_ll_init(void); +extern void ble_transport_hs_init(void); + +/* APIs to be implemented by HS/LL side of transports */ +extern int ble_transport_to_ll_cmd(void *buf); +extern int ble_transport_to_ll_acl(struct os_mbuf *om); +extern int ble_transport_to_hs_evt(void *buf); +extern int ble_transport_to_hs_acl(struct os_mbuf *om); + +/* Allocators for supported data types */ +void *ble_transport_alloc_cmd(void); +void *ble_transport_alloc_evt(int discardable); +struct os_mbuf *ble_transport_alloc_acl_from_hs(void); +struct os_mbuf *ble_transport_alloc_acl_from_ll(void); + +/* Generic deallocator for cmd/evt buffers */ +void ble_transport_free(void *buf); + +/* Register put callback on acl_from_ll mbufs (for ll-hs flow control) */ +int ble_transport_register_put_acl_from_ll_cb(os_mempool_put_fn *cb); + +#ifdef __cplusplus +} +#endif + +#endif /* H_NIMBLE_TRANSPORT_ */ diff --git a/nimble/transport/pkg.yml b/nimble/transport/pkg.yml index 5484002ebc..287ed974a1 100644 --- a/nimble/transport/pkg.yml +++ b/nimble/transport/pkg.yml @@ -25,36 +25,26 @@ pkg.keywords: - ble - bluetooth -pkg.deps.'BLE_HCI_TRANSPORT == "builtin"': - - nimble/transport/ram - - nimble/controller - -pkg.deps.'BLE_HCI_TRANSPORT == "emspi"': - - nimble/transport/emspi - -pkg.deps.'BLE_HCI_TRANSPORT == "ram"': - - nimble/transport/ram - -pkg.deps.'BLE_HCI_TRANSPORT == "socket"': - - nimble/transport/socket +pkg.apis: + - ble_transport -pkg.deps.'BLE_HCI_TRANSPORT == "uart"': - - nimble/transport/uart - -pkg.deps.'BLE_HCI_TRANSPORT == "da1469x"': - - nimble/transport/da1469x - -pkg.deps.'BLE_HCI_TRANSPORT == "dialog_cmac"': +pkg.deps.'BLE_TRANSPORT_HS == "native"': + - nimble/host +pkg.deps.'BLE_TRANSPORT_LL == "native"': + - nimble/controller +pkg.deps.'BLE_TRANSPORT_HS == "dialog_cmac" || BLE_TRANSPORT_LL == "dialog_cmac"': - nimble/transport/dialog_cmac - -pkg.deps.'BLE_HCI_TRANSPORT == "usb"': - - nimble/transport/usb - -pkg.deps.'BLE_HCI_TRANSPORT == "nrf5340"': - - nimble/transport/nrf5340 - -pkg.deps.'BLE_HCI_BRIDGE_TRANSPORT == "nrf5340"': +pkg.deps.'BLE_TRANSPORT_HS == "nrf5340" || BLE_TRANSPORT_LL == "nrf5340"': - nimble/transport/nrf5340 +pkg.deps.'BLE_TRANSPORT_HS == "uart"': + - nimble/transport/uart +pkg.deps.'BLE_TRANSPORT_HS == "usb"': + - nimble/transport/usb -pkg.deps.'BLE_HCI_BRIDGE_TRANSPORT == "dialog_cmac"': - - nimble/transport/dialog_cmac +pkg.init: + ble_transport_init: 250 + ble_transport_hs_init: + - $after:ble_transport_init + - $before:ble_transport_ll_init + ble_transport_ll_init: + - $after:ble_transport_hs_init diff --git a/nimble/transport/src/transport.c b/nimble/transport/src/transport.c new file mode 100644 index 0000000000..7c868f12ad --- /dev/null +++ b/nimble/transport/src/transport.c @@ -0,0 +1,217 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define OMP_FLAG_FROM_HS (0x01) +#define OMP_FLAG_FROM_LL (0x02) +#define OMP_FLAG_FROM_MASK (0x03) + +#if MYNEWT_VAL(BLE_HS_FLOW_CTRL) || \ + MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) +#define POOL_CMD_COUNT (2) +#else +#define POOL_CMD_COUNT (1) +#endif +#define POOL_CMD_SIZE (258) + +#define POOL_EVT_COUNT (MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT)) +#define POOL_EVT_LO_COUNT (MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT)) +#define POOL_EVT_SIZE (MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE)) + +#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_LL, native) && \ + MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, native) +#define POOL_ACL_COUNT (0) +#elif !MYNEWT_VAL_CHOICE(BLE_TRANSPORT_LL, native) && \ + !MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, native) +#define POOL_ACL_COUNT ((MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_HS_COUNT)) + \ + (MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT))) +#elif MYNEWT_VAL_CHOICE(BLE_TRANSPORT_LL, native) +#define POOL_ACL_COUNT (MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_HS_COUNT)) +#else +#define POOL_ACL_COUNT (MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT)) +#endif +#define POOL_ACL_SIZE (OS_ALIGN( MYNEWT_VAL(BLE_TRANSPORT_ACL_SIZE) + \ + BLE_MBUF_MEMBLOCK_OVERHEAD + \ + BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT)) + +static uint8_t pool_cmd_buf[ OS_MEMPOOL_BYTES(POOL_CMD_COUNT, POOL_CMD_SIZE) ]; +static struct os_mempool pool_cmd; + +static uint8_t pool_evt_buf[ OS_MEMPOOL_BYTES(POOL_EVT_COUNT, POOL_EVT_SIZE) ]; +static struct os_mempool pool_evt; + +static uint8_t pool_evt_lo_buf[ OS_MEMPOOL_BYTES(POOL_EVT_LO_COUNT, POOL_EVT_SIZE) ]; +static struct os_mempool pool_evt_lo; + +static uint8_t pool_acl_buf[ OS_MEMPOOL_BYTES(POOL_ACL_COUNT, POOL_ACL_SIZE) ]; +static struct os_mempool_ext pool_acl; +static struct os_mbuf_pool mpool_acl; + +static os_mempool_put_fn *transport_put_acl_from_ll_cb; + +void * +ble_transport_alloc_cmd(void) +{ + return os_memblock_get(&pool_cmd); +} + +void * +ble_transport_alloc_evt(int discarcable) +{ + void *buf; + + if (discarcable) { + buf = os_memblock_get(&pool_evt_lo); + } else { + buf = os_memblock_get(&pool_evt); + if (!buf) { + buf = os_memblock_get(&pool_evt_lo); + } + } + + return buf; +} + +struct os_mbuf * +ble_transport_alloc_acl_from_hs(void) +{ + struct os_mbuf *om; + struct os_mbuf_pkthdr *pkthdr; + uint16_t usrhdr_len; + +#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_LL, native) + usrhdr_len = sizeof(struct ble_mbuf_hdr); +#else + usrhdr_len = 0; +#endif + + om = os_mbuf_get_pkthdr(&mpool_acl, usrhdr_len); + if (om) { + pkthdr = OS_MBUF_PKTHDR(om); + pkthdr->omp_flags = OMP_FLAG_FROM_HS; + } + + return om; +} + +struct os_mbuf * +ble_transport_alloc_acl_from_ll(void) +{ + struct os_mbuf *om; + struct os_mbuf_pkthdr *pkthdr; + + om = os_mbuf_get_pkthdr(&mpool_acl, 0); + if (om) { + pkthdr = OS_MBUF_PKTHDR(om); + pkthdr->omp_flags = OMP_FLAG_FROM_LL; + } + + return om; +} + +void +ble_transport_free(void *buf) +{ + if (os_memblock_from(&pool_cmd, buf)) { + os_memblock_put(&pool_cmd, buf); + } else if (os_memblock_from(&pool_evt, buf)) { + os_memblock_put(&pool_evt, buf); + } else if (os_memblock_from(&pool_evt_lo, buf)) { + os_memblock_put(&pool_evt_lo, buf); + } else { + assert(0); + } +} + +static os_error_t +ble_transport_acl_put(struct os_mempool_ext *mpe, void *data, void *arg) +{ + struct os_mbuf *om; + struct os_mbuf_pkthdr *pkthdr; + os_error_t err; + + om = data; + pkthdr = OS_MBUF_PKTHDR(om); + + switch (pkthdr->omp_flags & OMP_FLAG_FROM_MASK) { + case OMP_FLAG_FROM_LL: + if (transport_put_acl_from_ll_cb) { + return transport_put_acl_from_ll_cb(mpe, data, arg); + } + break; + case OMP_FLAG_FROM_HS: + break; + default: + assert(0); + break; + } + + err = os_memblock_put_from_cb(&mpe->mpe_mp, data); + if (err) { + return err; + } + + return 0; +} + +void +ble_transport_init(void) +{ + int rc; + + SYSINIT_ASSERT_ACTIVE(); + + rc = os_mempool_init(&pool_cmd, POOL_CMD_COUNT, POOL_CMD_SIZE, + pool_cmd_buf, "transport_pool_cmd"); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = os_mempool_init(&pool_evt, POOL_EVT_COUNT, POOL_EVT_SIZE, + pool_evt_buf, "transport_pool_evt"); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = os_mempool_init(&pool_evt_lo, POOL_EVT_LO_COUNT, POOL_EVT_SIZE, + pool_evt_lo_buf, "transport_pool_evt_lo"); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = os_mempool_ext_init(&pool_acl, POOL_ACL_COUNT, POOL_ACL_SIZE, + pool_acl_buf, "transport_pool_acl"); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = os_mbuf_pool_init(&mpool_acl, &pool_acl.mpe_mp, + POOL_ACL_SIZE, POOL_ACL_COUNT); + SYSINIT_PANIC_ASSERT(rc == 0); + + pool_acl.mpe_put_cb = ble_transport_acl_put; +} + +int +ble_transport_register_put_acl_from_ll_cb(os_mempool_put_fn (*cb)) +{ + transport_put_acl_from_ll_cb = cb; + + return 0; +} diff --git a/nimble/transport/syscfg.defunct.yml b/nimble/transport/syscfg.defunct.yml new file mode 100644 index 0000000000..dc18ef4155 --- /dev/null +++ b/nimble/transport/syscfg.defunct.yml @@ -0,0 +1,40 @@ +# 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. +# + +syscfg.defs: + BLE_HCI_TRANSPORT: + description: see doc/transport.md + defunct: 1 + BLE_HCI_BRIDGE: + description: see doc/transport.md + defunct: 1 + BLE_HCI_EVT_HI_BUF_COUNT: + description: use BLE_TRANSPORT_EVT_COUNT + defunct: 1 + BLE_HCI_EVT_LO_BUF_COUNT: + description: use BLE_TRANSPORT_EVT_DISCARDABLE_COUNT + defunct: 1 + BLE_HCI_EVT_BUF_SIZE: + description: use BLE_TRANSPORT_EVT_SIZE + defunct: 1 + BLE_ACL_BUF_COUNT: + description: use BLE_TRANSPORT_ACL_COUNT + defunct: 1 + BLE_ACL_BUF_SIZE: + description: use BLE_TRANSPORT_ACL_SIZE + defunct: 1 diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml index 7eed69ba4e..d2404e1418 100644 --- a/nimble/transport/syscfg.yml +++ b/nimble/transport/syscfg.yml @@ -17,103 +17,76 @@ # syscfg.defs: - BLE_HCI_TRANSPORT: + BLE_TRANSPORT: 1 + + BLE_TRANSPORT_HS: description: > - Selects HCI transport to be included in build. - This has virtually the same effect as including package dependency - manually, but it allows to easily override HCI transport package in - application or target settings. - value: builtin - restrictions: $notnull + Select HCI transport used towards host. + "native" means NimBLE host is running on the same core and no + transport is required. + value: native choices: - - builtin # Built-in NimBLE controller and RAM transport - - custom # Custom transport, has to be included manually by user - - ram # RAM transport - - uart # UART HCI H4 transport - - socket # Socket transport (for native builds) - - emspi # SPI transport for EM Microelectionic controllers - - da1469x # Dialog DA1469x integrated controller - - dialog_cmac # Dialog CMAC via shared memory - - usb # USB - - nrf5340 # nRF5340 - - BLE_HCI_BRIDGE_TRANSPORT: + - native + - dialog_cmac + - nrf5340 + - uart + - usb + - custom + BLE_TRANSPORT_LL: description: > - Selects HCI transport to be included in bridge configuration build. - This applies to multi core configurations where controller runs - on separate core and main core forwards HCI traffic to external host. - This has virtually the same effect as including package dependency - manually, but it allows to easily override HCI transport package in - application or target settings. - This is the transport - value: + Select HCI transport used towards controller. + "native" means NimBLE controller is running on the same core and no + transport is required. + value: native choices: - - dialog_cmac # Dialog CMAC via shared memory - - nrf5340 # nRF5340 + - native + - dialog_cmac + - nrf5340 + - custom - BLE_HCI_BRIDGE: + BLE_TRANSPORT_ACL_COUNT: description: > - External interface (UART/USB/Socket) bridged to second core controller. - value: 0 - - BLE_HCI_EVT_HI_BUF_COUNT: - description: 'Number of high-priority event buffers.' - value: - - BLE_HCI_EVT_LO_BUF_COUNT: - description: 'Number of low-priority event buffers.' - value: - - BLE_HCI_EVT_BUF_SIZE: - description: 'Size of each event buffer, in bytes.' - value: - - BLE_ACL_BUF_COUNT: - description: 'The number of ACL data buffers' - value: - - BLE_ACL_BUF_SIZE: + Number of ACL buffers available in transport. This determines + number of buffers used by host/controller for flow control. + Buffers pool is allocated for each non-native transport side + selected, unless overriden by BLE_TRANSPORT_ACL_FROM_[HS|LL]_COUNT. + value: 10 + BLE_TRANSPORT_ACL_SIZE: + description: Size of each buffer in ACL pool. + value: 255 + BLE_TRANSPORT_EVT_COUNT: description: > - This is the maximum size of the data portion of HCI ACL data - packets. - value: - -# Deprecated settings - BLE_HCI_TRANSPORT_NIMBLE_BUILTIN: - description: Use BLE_HCI_TRANSPORT instead. - value: 0 - deprecated: 1 - BLE_HCI_TRANSPORT_EMSPI: - description: Use BLE_HCI_TRANSPORT instead. - value: 0 - deprecated: 1 - BLE_HCI_TRANSPORT_RAM: - description: Use BLE_HCI_TRANSPORT instead. - value: 0 - deprecated: 1 - BLE_HCI_TRANSPORT_SOCKET: - description: Use BLE_HCI_TRANSPORT instead. - value: 0 - deprecated: 1 - BLE_HCI_TRANSPORT_UART: - description: Use BLE_HCI_TRANSPORT instead. - value: 0 - deprecated: 1 - -syscfg.vals.BLE_HCI_TRANSPORT_NIMBLE_BUILTIN: - BLE_HCI_TRANSPORT: builtin -syscfg.vals.BLE_HCI_TRANSPORT_RAM: - BLE_HCI_TRANSPORT: ram -syscfg.vals.BLE_HCI_TRANSPORT_UART: - BLE_HCI_TRANSPORT: uart -syscfg.vals.BLE_HCI_TRANSPORT_SOCKET: - BLE_HCI_TRANSPORT: socket -syscfg.vals.BLE_HCI_TRANSPORT_EMSPI: - BLE_HCI_TRANSPORT: emspi + Number of event buffers available in transport. + value: 4 + BLE_TRANSPORT_EVT_DISCARDABLE_COUNT: + description: > + Number of discardable event buffers available in transport. + Discardable event buffers are used for events that can be safely + dropped by controller if there's no free buffer available, e.g. + advertising reports. + value: 16 + BLE_TRANSPORT_EVT_SIZE: + description: > + Size of each buffer in events pool. This applies to both regular + and discardable buffers. Value is automatically adjusted if + extended advertising is enabled so in most cases it's better to + leave it at default settings. + value: 70 -syscfg.vals.'(MCU_TARGET == "DA14691" || MCU_TARGET == "DA14695" || MCU_TARGET == "DA14697" || MCU_TARGET == "DA14699")': - BLE_HCI_BRIDGE_TRANSPORT: dialog_cmac + BLE_TRANSPORT_ACL_FROM_HS_COUNT: + description: > + Overrides BLE_TRANSPORT_ACL_COUNT on host side, i.e. number + of ACL buffers available for host. + value: MYNEWT_VAL(BLE_TRANSPORT_ACL_COUNT) + BLE_TRANSPORT_ACL_FROM_LL_COUNT: + description: > + Overrides BLE_TRANSPORT_ACL_COUNT on controller side, i.e. number + of ACL buffers available for controller. + value: MYNEWT_VAL(BLE_TRANSPORT_ACL_COUNT) -syscfg.vals.'(MCU_TARGET == "nRF5340_APP")': - BLE_HCI_BRIDGE_TRANSPORT: nrf5340 +# import defunct settings from separate file to reduce clutter in main file +$import: + - "@apache-mynewt-nimble/nimble/transport/syscfg.defunct.yml" +syscfg.vals."BLE_EXT_ADV || BLE_LL_CFG_FEAT_LL_EXT_ADV": + BLE_TRANSPORT_EVT_SIZE: 257 From bb32f04b702e4cbf6f02ccff60d2ba5c9f94ad14 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 7 Mar 2022 14:50:51 +0100 Subject: [PATCH 0332/1333] nimble/doc: Add documentation for HCI transport --- nimble/doc/transport.md | 189 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 nimble/doc/transport.md diff --git a/nimble/doc/transport.md b/nimble/doc/transport.md new file mode 100644 index 0000000000..cd14993ae8 --- /dev/null +++ b/nimble/doc/transport.md @@ -0,0 +1,189 @@ + + +# NimBLE HCI transport + +## Overview + +Transport is split into host (HS) and controller (LL) sides. Those do not +necessarily represent actual host/controller, they can be just interfaces to +external host (e.g. UART or USB) or controller (e.g.IPC to LL running on +another core). + +``` ++----------+ +----------+ +| cmd pool | | evt pool | ++----------+ +----------+ +| acl pool | | acl pool | ++----------+ +----------+ + || || ++----+ +----+ +| | <--- ble_transport_to_ll_acl ---- | | +| | <--- ble_transport_to_ll_evt ---- | | +| HS | | LL | +| | ---- ble_transport_to_ll_cmd ---> | | +| | ---- ble_transport_to_ll_acl ---> | | ++----+ +----+ +``` + +HS side allocates buffers for HCI commands and ACL data from dedicated pools +using `ble_transport_alloc_cmd` and `ble_transport_alloc_acl_from_hs` calls +respectively, then sends them to LL side using `ble_transport_to_ll_cmd` and +`ble_transport_to_ll_acl`. + +Similarly, LL side allocates buffers for HCI events and ACL data from dedicated +pools using `ble_transport_alloc_evt` and `ble_transport_alloc_acl_from_ll` +calls respectively, then sends them to HS side using `ble_transport_to_hs_evt` +and `ble_transport_to_hs_acl`. + +Both HCI command and events buffers are freed using `ble_transport_free`, ACL +data are freed as regular `os_mbuf`. + +Selecting `native` transport for either HS or LL side will use actual NimBLE +host or controller respectively directly instead of transport implementation. +Both NimBLE host and controller do not use decidated pools for ACL data and +allocate data directly from msys pool - relevant ACL pools will be disabled +automatically. + +Actual transport implementation for each side can be set using `BLE_TRANSPORT_HS` +and `BLE_TRANSPORT_LL` syscfg for HS and LL sides respectively. Selecting +transport in either direction will automatically add dependencies to required +transport implementation packages, there's no need to do this manually. +Selecting `native` transport for HS and/or LL side will automatically add +dependencies to NimBLE host and/or controller packages. + +The order of initialization is defined as follows: +- `ble_transport_init` - generic transport initialization +- `ble_transport_hs_init` - HS side initialization +- `ble_transport_ll_init` - LL side initialization + +Initialization functions for HS and LL sides shall be implemented by transport +implementation. There's no need to define those functions as sysinit stages +since this is already done by generic transport implementation along with +proper dependencies. + + +## Application configuration + +To ensure that application can be easily run on different BSPs, it's strongly +recommended not to put hard dependencies to any transport in `pkg.yml` and +use automatic dependencies instead. That means an application that uses NimBLE +host should only include `nimble/host` in its dependencies (i.e. no direct +dependency to `nimble/controler` or any transport implementation). This will +pull `nimble/transport` automatically, force `BLE_TRANSPORT_HS: native` and +allow changing LL side using `BLE_TRANSPORT_LL` to any supported controller. + + +## Multicore SoCs + +On multicore SoCs with dedicated application and network cores (e.g. nRF5340, +DA1469x) NimBLE host and controller will run on different cores. In such setup +application core uses LL transport implementation instead of an actual NimBLE +controller and similarly network core uses HS transport implementation instead +of NimBLE host. Both sides of transport implementation are provided by the same +transport, e.g. `nrf5340` for nRF5340 or `dialog_cmac` for DA1469x, and exchange +data via IPC. This process is transparent from application point of view, +assuming it's properly configured (see above). + +``` + Application core | Network core ++----+ +----+ | +----+ +----+ +| | | LL | | | HS | | | +| | <- acl/evt -- | | | | | <- acl/evt -- | | +| HS | | tr | <- ipc -> | tr | | LL | +| | -- cmd/acl -> | an | | | an | -- cmd/acl -> | | +| | | sp | | | sp | | | ++----+ +----+ | +----+ +----+ +``` + + +## Build configurations + +### Combined build + +This setup runs both NimBLE host and controller on the same core. It's a typical +configuration when running application on SoCs like nRF51 or nRF52. + +Note: this is the default configuration, no need to set it explicitly. + +```yaml +BLE_TRANSPORT_HS: native +BLE_TRANSPORT_LL: native +``` + +### Controller-only build + +This setup makes NimBLE controller accessible to external host connected via +e.g. UART or USB, so it can be used as an external Bluetooth LE controller. +The controller runs on the same core as external interface. It's typically +used with `blehci` application running on SoCs like nRF51 or nRF52. + +```yaml +BLE_TRANSPORT_HS: uart +BLE_TRANSPORT_LL: native +``` + + +### Multicore build + +This is a variant of combined build but with NimBLE host and controller running +on different cores, like e.g. nRF5340 or DA1469x. Application core can run +any application while network core runs `blehci`. + +Note: BSPs for nRF5340 and DA1469x will automatically select proper transport + for LL side if NimBLE host or transport is included in build, so usually + there's no need to configure manually. + +#### Application core +```yaml +BLE_TRANSPORT_HS: native +BLE_TRANSPORT_LL: dialog_cmac +``` + +#### Network core +```yaml +BLE_TRANSPORT_HS: dialog_cmac +BLE_TRANSPORT_LL: native +``` + + +### Bridge build + +This is a variant of controller-only build but with NimBLE controller running +on different core than external interface used to access it, like e.g. nRF5340 +or DA1469x. In this setup both cores run `blehci` application. + +Note: BSPs for nRF5340 and DA1469x will automatically select proper transport + for LL side if NimBLE host or transport is included in build, so usually + there's only need to select required transport for external interface on + application core. + +#### Application core +```yaml +BLE_TRANSPORT_HS: uart +BLE_TRANSPORT_LL: nrf5340 +``` + +#### Network core +```yaml +BLE_TRANSPORT_HS: nrf5340 +BLE_TRANSPORT_LL: native +``` From 83535eda40b1aca0cd111fe188f4b125a68d4773 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 3 Mar 2022 18:09:47 +0100 Subject: [PATCH 0333/1333] nimble/ll: Update to new transport --- .../include/controller/ble_ll_hci.h | 3 +- nimble/controller/pkg.yml | 4 +- nimble/controller/src/ble_ll.c | 29 ++++++++++++--- nimble/controller/src/ble_ll_adv.c | 5 +-- nimble/controller/src/ble_ll_conn.c | 8 ++-- nimble/controller/src/ble_ll_conn_hci.c | 13 +++---- nimble/controller/src/ble_ll_hci.c | 7 ++-- nimble/controller/src/ble_ll_hci_ev.c | 37 +++++++++---------- nimble/controller/src/ble_ll_scan.c | 9 ++--- nimble/controller/src/ble_ll_scan_aux.c | 7 ++-- nimble/controller/src/ble_ll_sync.c | 27 +++++++------- nimble/controller/syscfg.yml | 7 +--- nimble/include/nimble/hci_common.h | 5 ++- 13 files changed, 84 insertions(+), 77 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_hci.h b/nimble/controller/include/controller/ble_ll_hci.h index a9ea3bb055..f45aa3ae1b 100644 --- a/nimble/controller/include/controller/ble_ll_hci.h +++ b/nimble/controller/include/controller/ble_ll_hci.h @@ -25,13 +25,14 @@ extern "C" { #endif #include "nimble/hci_common.h" +#include "nimble/transport.h" /* For supported commands */ #define BLE_LL_SUPP_CMD_LEN (45) extern const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN]; /* The largest event the controller will send. */ -#define BLE_LL_MAX_EVT_LEN MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE) +#define BLE_LL_MAX_EVT_LEN MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE) /* * This determines the number of outstanding commands allowed from the diff --git a/nimble/controller/pkg.yml b/nimble/controller/pkg.yml index 9661bb31e8..702f3d8932 100644 --- a/nimble/controller/pkg.yml +++ b/nimble/controller/pkg.yml @@ -37,6 +37,4 @@ pkg.req_apis.BLE_LL_LNA: pkg.deps: - "@apache-mynewt-core/kernel/os" - nimble - -pkg.init: - ble_ll_init: 'MYNEWT_VAL(BLE_LL_SYSINIT_STAGE)' + - nimble/transport diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 362d4669a6..73168b43c9 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -28,7 +28,7 @@ #include "nimble/ble.h" #include "nimble/nimble_opt.h" #include "nimble/hci_common.h" -#include "nimble/ble_hci_trans.h" +#include "nimble/transport.h" #include "controller/ble_hw.h" #include "controller/ble_phy.h" #include "controller/ble_phy_trace.h" @@ -1394,9 +1394,6 @@ ble_ll_task(void *arg) /* Set output power to 1mW (0 dBm) */ ble_phy_txpwr_set(g_ble_ll_tx_power); - /* Register callback for transport */ - ble_hci_trans_cfg_ll(ble_ll_hci_cmd_rx, NULL, ble_ll_hci_acl_rx, NULL); - /* Tell the host that we are ready to receive packets */ ble_ll_hci_send_noop(); @@ -1817,8 +1814,8 @@ ble_ll_init(void) #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) /* Set acl pkt size and number */ - lldata->ll_num_acl_pkts = MYNEWT_VAL(BLE_ACL_BUF_COUNT); - lldata->ll_acl_pkt_size = MYNEWT_VAL(BLE_ACL_BUF_SIZE); + lldata->ll_num_acl_pkts = MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_HS_COUNT); + lldata->ll_acl_pkt_size = MYNEWT_VAL(BLE_TRANSPORT_ACL_SIZE); #endif /* Initialize eventq */ @@ -1967,3 +1964,23 @@ ble_ll_init(void) #endif } + +/* Transport APIs for LL side */ + +int +ble_transport_to_ll_cmd(void *buf) +{ + return ble_ll_hci_cmd_rx(buf, NULL); +} + +int +ble_transport_to_ll_acl(struct os_mbuf *om) +{ + return ble_ll_hci_acl_rx(om, NULL); +} + +void +ble_transport_ll_init(void) +{ + ble_ll_init(); +} diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index bc04c8f0bc..b3cf5f9860 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -26,7 +26,6 @@ #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" @@ -1947,7 +1946,7 @@ ble_ll_adv_sm_stop(struct ble_ll_adv_sm *advsm) #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) /* If there is an event buf we need to free it */ if (advsm->conn_comp_ev) { - ble_hci_trans_buf_free(advsm->conn_comp_ev); + ble_transport_free(advsm->conn_comp_ev); advsm->conn_comp_ev = NULL; } #endif @@ -2668,7 +2667,7 @@ ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm) if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) { /* We expect this to be NULL but if not we wont allocate one... */ if (advsm->conn_comp_ev == NULL) { - advsm->conn_comp_ev = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + advsm->conn_comp_ev = ble_transport_alloc_evt(0); if (!advsm->conn_comp_ev) { return BLE_ERR_MEM_CAPACITY; } diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index c41c35b103..138f9284f6 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -25,7 +25,7 @@ #include "os/os.h" #include "nimble/ble.h" #include "nimble/hci_common.h" -#include "nimble/ble_hci_trans.h" +#include "nimble/transport.h" #include "controller/ble_ll.h" #include "controller/ble_ll_conn.h" #include "controller/ble_ll_hci.h" @@ -306,7 +306,7 @@ ble_ll_conn_cth_flow_error_fn(struct ble_npl_event *ev) struct ble_hci_ev_command_complete *hci_ev_cp; uint16_t opcode; - hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (!hci_ev) { /* Not much we can do anyway... */ return; @@ -3261,7 +3261,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) acl_hdr = (llid << 12) | connsm->conn_handle; put_le16(rxbuf, acl_hdr); put_le16(rxbuf + 2, acl_len); - ble_hci_trans_ll_acl_tx(rxpdu); + ble_transport_to_hs_acl(rxpdu); } /* NOTE: we dont free the mbuf since we handed it off! */ @@ -3916,7 +3916,7 @@ ble_ll_conn_module_reset(void) #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Free the global connection complete event if there is one */ if (g_ble_ll_conn_comp_ev) { - ble_hci_trans_buf_free(g_ble_ll_conn_comp_ev); + ble_transport_free(g_ble_ll_conn_comp_ev); g_ble_ll_conn_comp_ev = NULL; } diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 97d242134b..82abdcb1ba 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -24,7 +24,6 @@ #include "os/os.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_utils.h" #include "controller/ble_ll_hci.h" @@ -76,7 +75,7 @@ ble_ll_init_alloc_conn_comp_ev(void) rc = 0; evbuf = g_ble_ll_conn_comp_ev; if (evbuf == NULL) { - evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + evbuf = ble_transport_alloc_evt(0); if (!evbuf) { rc = -1; } else { @@ -263,7 +262,7 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, return; } - ble_hci_trans_buf_free(evbuf); + ble_transport_free(evbuf); } /** @@ -299,7 +298,7 @@ ble_ll_conn_num_comp_pkts_event_send(struct ble_ll_conn_sm *connsm) * entire active list every time. */ if (connsm->completed_pkts) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_NUM_COMP_PKTS; hci_ev->length = sizeof(*ev); @@ -333,7 +332,7 @@ ble_ll_conn_num_comp_pkts_event_send(struct ble_ll_conn_sm *connsm) (connsm->completed_pkts || !STAILQ_EMPTY(&connsm->conn_txq))) { /* If no buffer, get one, If cant get one, leave. */ if (!hci_ev) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (!hci_ev) { break; } @@ -389,7 +388,7 @@ ble_ll_auth_pyld_tmo_event_send(struct ble_ll_conn_sm *connsm) struct ble_hci_ev *hci_ev; if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_AUTH_PYLD_TMO)) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_AUTH_PYLD_TMO; hci_ev->length = sizeof(*ev); @@ -418,7 +417,7 @@ ble_ll_disconn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t reason) struct ble_hci_ev *hci_ev; if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_DISCONN_CMP)) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_DISCONN_CMP; hci_ev->length = sizeof(*ev); diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 3dfc4a0476..bc9160f133 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -24,7 +24,6 @@ #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_ll_adv.h" #include "controller/ble_ll_scan.h" @@ -108,7 +107,7 @@ ble_ll_hci_event_send(struct ble_hci_ev *hci_ev) STATS_INC(ble_ll_stats, hci_events_sent); /* Send the event to the host */ - rc = ble_hci_trans_ll_evt_tx((uint8_t *)hci_ev); + rc = ble_transport_to_hs_evt(hci_ev); BLE_LL_DEBUG_GPIO(HCI_EV, 0); @@ -125,7 +124,7 @@ ble_ll_hci_send_noop(void) struct ble_hci_ev_command_complete_nop *ev; struct ble_hci_ev *hci_ev; - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { /* Create a command complete event with a NO-OP opcode */ hci_ev->opcode = BLE_HCI_EVCODE_COMMAND_COMPLETE; @@ -1792,7 +1791,7 @@ ble_ll_hci_cmd_rx(uint8_t *cmdbuf, void *arg) if ((ogf == BLE_HCI_OGF_CTLR_BASEBAND) && (ocf == BLE_HCI_OCF_CB_HOST_NUM_COMP_PKTS)) { ble_ll_conn_cth_flow_process_cmd(cmdbuf); - ble_hci_trans_buf_free(cmdbuf); + ble_transport_free(cmdbuf); return 0; } #endif diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index c39a833477..8543d98925 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -22,7 +22,6 @@ #include "syscfg/syscfg.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" @@ -44,7 +43,7 @@ ble_ll_hci_ev_datalen_chg(struct ble_ll_conn_sm *connsm) struct ble_hci_ev *hci_ev; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_DATA_LEN_CHG)) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_LE_META; hci_ev->length = sizeof(*ev); @@ -76,7 +75,7 @@ ble_ll_hci_ev_rem_conn_parm_req(struct ble_ll_conn_sm *connsm, struct ble_hci_ev *hci_ev; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ)) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_LE_META; hci_ev->length = sizeof(*ev); @@ -107,7 +106,7 @@ ble_ll_hci_ev_conn_update(struct ble_ll_conn_sm *connsm, uint8_t status) struct ble_hci_ev *hci_ev; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE)) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_LE_META; hci_ev->length = sizeof(*ev); @@ -135,7 +134,7 @@ ble_ll_hci_ev_encrypt_chg(struct ble_ll_conn_sm *connsm, uint8_t status) if (CONN_F_ENC_CHANGE_SENT(connsm) == 0) { if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_ENCRYPT_CHG)) { - hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_ENCRYPT_CHG; hci_ev->length = sizeof(*ev_enc_chf); @@ -154,7 +153,7 @@ ble_ll_hci_ev_encrypt_chg(struct ble_ll_conn_sm *connsm, uint8_t status) } if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_ENC_KEY_REFRESH)) { - hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_ENC_KEY_REFRESH; hci_ev->length = sizeof(*ev_key_refresh); @@ -181,7 +180,7 @@ ble_ll_hci_ev_ltk_req(struct ble_ll_conn_sm *connsm) int rc; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_LT_KEY_REQ)) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_LE_META; hci_ev->length = sizeof(*ev); @@ -215,7 +214,7 @@ ble_ll_hci_ev_rd_rem_used_feat(struct ble_ll_conn_sm *connsm, uint8_t status) struct ble_hci_ev *hci_ev; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT)) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_LE_META; hci_ev->length = sizeof(*ev); @@ -239,7 +238,7 @@ ble_ll_hci_ev_rd_rem_ver(struct ble_ll_conn_sm *connsm, uint8_t status) struct ble_hci_ev *hci_ev; if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP)) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP; hci_ev->length = sizeof(*ev); @@ -272,7 +271,7 @@ ble_ll_hci_ev_hw_err(uint8_t hw_err) rc = 0; if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_HW_ERROR)) { - hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_HW_ERROR; hci_ev->length = sizeof(*ev); @@ -295,7 +294,7 @@ ble_ll_hci_ev_databuf_overflow(void) struct ble_hci_ev *hci_ev; if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_DATA_BUF_OVERFLOW)) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_DATA_BUF_OVERFLOW; hci_ev->length = sizeof(*ev); @@ -321,7 +320,7 @@ ble_ll_hci_ev_le_csa(struct ble_ll_conn_sm *connsm) struct ble_hci_ev *hci_ev; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_CHAN_SEL_ALG)) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_LE_META; hci_ev->length = sizeof(*ev); @@ -350,7 +349,7 @@ ble_ll_hci_ev_send_scan_req_recv(uint8_t adv_handle, const uint8_t *peer, struct ble_hci_ev *hci_ev; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD)) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_LE_META; hci_ev->length = sizeof(*ev); @@ -379,7 +378,7 @@ ble_ll_hci_ev_send_scan_timeout(void) struct ble_hci_ev *hci_ev; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_SCAN_TIMEOUT)) { - hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_LE_META; hci_ev->length = sizeof(*ev); @@ -406,7 +405,7 @@ ble_ll_hci_ev_send_adv_set_terminated(uint8_t status, uint8_t adv_handle, struct ble_hci_ev *hci_ev; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED)) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_LE_META; hci_ev->length = sizeof(*ev); @@ -440,7 +439,7 @@ ble_ll_hci_ev_phy_update(struct ble_ll_conn_sm *connsm, uint8_t status) rc = 0; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_PHY_UPDATE_COMPLETE)) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_LE_META; hci_ev->length = sizeof(*ev); @@ -473,7 +472,7 @@ ble_ll_hci_ev_sca_update(struct ble_ll_conn_sm *connsm, uint8_t status, return; } - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (!hci_ev) { return; } @@ -508,7 +507,7 @@ ble_ll_hci_ev_send_vs_assert(const char *file, uint32_t line) */ max_len = BLE_HCI_MAX_DATA_LEN - sizeof(*ev) - 6; - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_VS_DEBUG; hci_ev->length = sizeof(*ev); @@ -560,7 +559,7 @@ ble_ll_hci_ev_send_vs_llcp_trace(uint8_t type, uint16_t handle, uint16_t count, struct ble_hci_ev_vs_debug *ev; struct ble_hci_ev *hci_ev; - hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + hci_ev = ble_transport_alloc_evt(1); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_VS_DEBUG; hci_ev->length = sizeof(*ev) + 8 + length; diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 46e1cb66cd..27c0feaa40 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -25,7 +25,6 @@ #include "os/os.h" #include "nimble/ble.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" @@ -327,7 +326,7 @@ ble_ll_scan_get_ext_adv_report(struct ext_adv_report *copy_from) struct ext_adv_report *report; struct ble_hci_ev *hci_ev; - hci_ev = ( void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + hci_ev = ble_transport_alloc_evt(1); if (!hci_ev) { return NULL; } @@ -512,7 +511,7 @@ ble_ll_hci_send_legacy_ext_adv_report(uint8_t evtype, break; default: BLE_LL_ASSERT(0); - ble_hci_trans_buf_free((uint8_t *) hci_ev); + ble_transport_free(hci_ev); return -1; } @@ -557,7 +556,7 @@ ble_ll_hci_send_adv_report(uint8_t evtype, return -1; } - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + hci_ev = ble_transport_alloc_evt(1); if (!hci_ev) { return -1; } @@ -594,7 +593,7 @@ ble_ll_hci_send_dir_adv_report(const uint8_t *addr, uint8_t addr_type, return -1; } - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + hci_ev = ble_transport_alloc_evt(1); if (!hci_ev) { return -1; } diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index ed5ca815c1..ce2ac07285 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -28,7 +28,6 @@ #include "os/os.h" #include "nimble/ble.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" @@ -230,7 +229,7 @@ ble_ll_hci_ev_alloc_ext_adv_report_for_aux(struct ble_ll_scan_addr_data *addrd, struct ext_adv_report *report; struct ble_hci_ev *hci_ev; - hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + hci_ev = ble_transport_alloc_evt(1); if (!hci_ev) { return NULL; } @@ -286,7 +285,7 @@ ble_ll_hci_ev_dup_ext_adv_report(struct ble_hci_ev *hci_ev_src) struct ext_adv_report *report; struct ble_hci_ev *hci_ev; - hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + hci_ev = ble_transport_alloc_evt(1); if (!hci_ev) { return NULL; } @@ -639,7 +638,7 @@ ble_ll_hci_ev_send_ext_adv_report_for_ext(struct os_mbuf *rxpdu, return; } - hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + hci_ev = ble_transport_alloc_evt(1); if (!hci_ev) { return; } diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 43f328e3be..0adc67b799 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -36,7 +36,6 @@ #include "nimble/ble.h" #include "nimble/hci_common.h" -#include "nimble/ble_hci_trans.h" #include "ble_ll_conn_priv.h" @@ -201,7 +200,7 @@ ble_ll_sync_sm_clear(struct ble_ll_sync_sm *sm) } if (sm->next_report) { - ble_hci_trans_buf_free(sm->next_report); + ble_transport_free(sm->next_report); } if (g_ble_ll_sync_sm_current == sm) { @@ -333,7 +332,7 @@ ble_ll_sync_transfer_received(struct ble_ll_sync_sm *sm, uint8_t status) ble_ll_hci_event_send(hci_ev); } else { - ble_hci_trans_buf_free(sm->transfer_received_ev); + ble_transport_free(sm->transfer_received_ev); } sm->transfer_received_ev = NULL; @@ -371,7 +370,7 @@ ble_ll_sync_est_event_success(struct ble_ll_sync_sm *sm) ble_ll_hci_event_send(hci_ev); } else { - ble_hci_trans_buf_free(g_ble_ll_sync_create_comp_ev); + ble_transport_free(g_ble_ll_sync_create_comp_ev); } g_ble_ll_sync_create_comp_ev = NULL; @@ -399,7 +398,7 @@ ble_ll_sync_est_event_failed(uint8_t status) ble_ll_hci_event_send(hci_ev); } else { - ble_hci_trans_buf_free(g_ble_ll_sync_create_comp_ev); + ble_transport_free(g_ble_ll_sync_create_comp_ev); } g_ble_ll_sync_create_comp_ev = NULL; @@ -412,7 +411,7 @@ ble_ll_sync_lost_event(struct ble_ll_sync_sm *sm) struct ble_hci_ev *hci_ev; if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_LOST)) { - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_LE_META; hci_ev->length = sizeof(*ev); @@ -642,7 +641,7 @@ ble_ll_sync_send_truncated_per_adv_rpt(struct ble_ll_sync_sm *sm, uint8_t *evbuf if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT) || (sm->flags & BLE_LL_SYNC_SM_FLAG_DISABLED)) { - ble_hci_trans_buf_free(evbuf); + ble_transport_free(evbuf); return; } @@ -679,7 +678,7 @@ ble_ll_sync_send_per_adv_rpt(struct ble_ll_sync_sm *sm, struct os_mbuf *rxpdu, hci_ev = (void *) sm->next_report; sm->next_report = NULL; } else { - hci_ev = (void * )ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + hci_ev = ble_transport_alloc_evt(1); if (!hci_ev) { goto done; } @@ -714,7 +713,7 @@ ble_ll_sync_send_per_adv_rpt(struct ble_ll_sync_sm *sm, struct os_mbuf *rxpdu, /* Need another event for next fragment of this PDU */ if (offset < datalen) { - hci_ev_next = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + hci_ev_next = ble_transport_alloc_evt(1); if (hci_ev_next) { ev->data_status = BLE_HCI_PERIODIC_DATA_STATUS_INCOMPLETE; } else { @@ -725,7 +724,7 @@ ble_ll_sync_send_per_adv_rpt(struct ble_ll_sync_sm *sm, struct os_mbuf *rxpdu, if (aux) { if (aux_scheduled) { /* if we scheduled aux, we need buffer for next report */ - hci_ev_next = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + hci_ev_next = ble_transport_alloc_evt(1); if (hci_ev_next) { ev->data_status = BLE_HCI_PERIODIC_DATA_STATUS_INCOMPLETE; } else { @@ -1517,7 +1516,7 @@ ble_ll_sync_create(const uint8_t *cmdbuf, uint8_t len) } /* reserve buffer for sync complete event */ - g_ble_ll_sync_create_comp_ev = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + g_ble_ll_sync_create_comp_ev = ble_transport_alloc_evt(0); if (!g_ble_ll_sync_create_comp_ev) { return BLE_ERR_MEM_CAPACITY; } @@ -1527,7 +1526,7 @@ ble_ll_sync_create(const uint8_t *cmdbuf, uint8_t len) /* reserve 1 SM for created sync */ sm = ble_ll_sync_reserve(); if (!sm) { - ble_hci_trans_buf_free(g_ble_ll_sync_create_comp_ev); + ble_transport_free(g_ble_ll_sync_create_comp_ev); g_ble_ll_sync_create_comp_ev = NULL; OS_EXIT_CRITICAL(sr); return BLE_ERR_MEM_CAPACITY; @@ -1789,7 +1788,7 @@ ble_ll_sync_transfer_get(const uint8_t *addr, uint8_t addr_type, uint8_t sid) if (!sm->flags) { /* allocate event for transfer received event */ - sm->transfer_received_ev = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + sm->transfer_received_ev = ble_transport_alloc_evt(0); if (!sm->transfer_received_ev) { break; } @@ -2246,7 +2245,7 @@ ble_ll_sync_reset(void) g_ble_ll_sync_sm_current = NULL; if (g_ble_ll_sync_create_comp_ev) { - ble_hci_trans_buf_free(g_ble_ll_sync_create_comp_ev); + ble_transport_free(g_ble_ll_sync_create_comp_ev); g_ble_ll_sync_create_comp_ev = NULL; } } diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index a9b4321c09..ebf7e1dde6 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -17,11 +17,7 @@ # syscfg.defs: - BLE_CONTROLLER: - description: > - Indicates that NimBLE controller is present. The default value for - this setting shall not be overriden. - value: 1 + BLE_CONTROLLER: 1 BLE_LL_ROLE_CENTRAL: description: 'Enables controller support for the Central role.' @@ -556,6 +552,7 @@ syscfg.vals.!BLE_HOST: BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 syscfg.restrictions: + - BLE_TRANSPORT_LL == "native" - BLE_LL_PUBLIC_DEV_ADDR <= 0xffffffffffff - BLE_LL_PA == 0 || BLE_LL_PA_GPIO >= 0 - BLE_LL_LNA == 0 || BLE_LL_LNA_GPIO >= 0 diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 8faebe479e..eb5165c0a4 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -21,13 +21,14 @@ #define H_BLE_HCI_COMMON_ #include "ble.h" +#include "nimble/transport.h" #ifdef __cplusplus extern "C" { #endif -#define BLE_HCI_MAX_DATA_LEN (MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE) - \ - sizeof(struct ble_hci_ev)) +#define BLE_HCI_MAX_DATA_LEN (MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE) - \ + sizeof(struct ble_hci_ev)) /* Generic command header */ struct ble_hci_cmd { From 0cb011790f5507676f424e6679cd522a96f42c3e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 4 Mar 2022 15:47:34 +0100 Subject: [PATCH 0334/1333] nimble/host: Update to new transport --- nimble/host/pkg.yml | 4 +--- nimble/host/src/ble_hs.c | 40 ++++++++++++++++++------------- nimble/host/src/ble_hs_flow.c | 17 ++++++------- nimble/host/src/ble_hs_hci.c | 8 +++---- nimble/host/src/ble_hs_hci_cmd.c | 5 ++-- nimble/host/src/ble_hs_hci_evt.c | 5 ++-- nimble/host/src/ble_hs_hci_priv.h | 2 +- nimble/host/syscfg.yml | 3 +++ 8 files changed, 43 insertions(+), 41 deletions(-) diff --git a/nimble/host/pkg.yml b/nimble/host/pkg.yml index a063a0b636..b28979269e 100644 --- a/nimble/host/pkg.yml +++ b/nimble/host/pkg.yml @@ -30,6 +30,7 @@ pkg.deps: - "@apache-mynewt-core/sys/log/modlog" - "@apache-mynewt-core/util/mem" - nimble + - nimble/transport pkg.deps.BLE_SM_LEGACY: - "@apache-mynewt-core/crypto/tinycrypt" @@ -48,8 +49,5 @@ pkg.req_apis: - console - stats -pkg.init: - ble_hs_init: 'MYNEWT_VAL(BLE_HS_SYSINIT_STAGE)' - pkg.down.BLE_HS_STOP_ON_SHUTDOWN: ble_hs_shutdown: 200 diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index 5e5c6442c9..ba601b6136 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -23,7 +23,6 @@ #include "sysinit/sysinit.h" #include "syscfg/syscfg.h" #include "stats/stats.h" -#include "nimble/ble_hci_trans.h" #include "host/ble_hs.h" #include "ble_hs_priv.h" #include "ble_monitor_priv.h" @@ -32,9 +31,7 @@ #include "nimble/nimble_port.h" #endif -#define BLE_HS_HCI_EVT_COUNT \ - (MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT) + \ - MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT)) +#define BLE_HS_HCI_EVT_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) static void ble_hs_event_rx_hci_ev(struct ble_npl_event *ev); #if NIMBLE_BLE_CONNECT @@ -370,12 +367,6 @@ ble_hs_reset(void) ble_hs_sync_state = 0; - /* Reset transport. Assume success; there is nothing we can do in case of - * failure. If the transport failed to reset, the host will reset itself - * again when it fails to sync with the controller. - */ - (void)ble_hci_trans_reset(); - ble_hs_clear_rx_queue(); /* Clear adverising and scanning states. */ @@ -499,7 +490,7 @@ ble_hs_sched_start(void) static void ble_hs_event_rx_hci_ev(struct ble_npl_event *ev) { - const struct ble_hci_ev *hci_ev; + struct ble_hci_ev *hci_ev; int rc; hci_ev = ble_npl_event_get_arg(ev); @@ -573,7 +564,7 @@ ble_hs_enqueue_hci_event(uint8_t *hci_evt) ev = os_memblock_get(&ble_hs_hci_ev_pool); if (ev == NULL) { - ble_hci_trans_buf_free(hci_evt); + ble_transport_free(hci_evt); } else { ble_npl_event_init(ev, ble_hs_event_rx_hci_ev, hci_evt); ble_npl_eventq_put(ble_hs_evq, ev); @@ -709,7 +700,7 @@ ble_hs_tx_data(struct os_mbuf *om) ble_monitor_send_om(BLE_MONITOR_OPCODE_ACL_TX_PKT, om); #endif - return ble_hci_trans_hs_acl_tx(om); + return ble_transport_to_ll_acl(om); } void @@ -793,9 +784,6 @@ ble_hs_init(void) ble_hs_evq_set(nimble_port_get_dflt_eventq()); #endif - /* Configure the HCI transport to communicate with a host. */ - ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL); - #if BLE_MONITOR rc = ble_monitor_init(); SYSINIT_PANIC_ASSERT(rc == 0); @@ -818,3 +806,23 @@ ble_hs_init(void) ble_monitor_new_index(0, (uint8_t[6]){ }, "nimble0"); #endif } + +/* Transport APIs for HS side */ + +int +ble_transport_to_hs_evt(void *buf) +{ + return ble_hs_hci_rx_evt(buf, NULL); +} + +int +ble_transport_to_hs_acl(struct os_mbuf *om) +{ + return ble_hs_rx_data(om, NULL); +} + +void +ble_transport_hs_init(void) +{ + ble_hs_init(); +} diff --git a/nimble/host/src/ble_hs_flow.c b/nimble/host/src/ble_hs_flow.c index 1eabba9e0c..acd754a3fb 100644 --- a/nimble/host/src/ble_hs_flow.c +++ b/nimble/host/src/ble_hs_flow.c @@ -18,7 +18,6 @@ */ #include "syscfg/syscfg.h" -#include "nimble/ble_hci_trans.h" #include "ble_hs_priv.h" #if MYNEWT_VAL(BLE_HS_FLOW_CTRL) @@ -41,7 +40,7 @@ static ble_npl_event_fn ble_hs_flow_event_cb; static struct ble_npl_event ble_hs_flow_ev; /* Connection handle associated with each mbuf in ACL pool */ -static uint16_t ble_hs_flow_mbuf_conn_handle[ MYNEWT_VAL(BLE_ACL_BUF_COUNT) ]; +static uint16_t ble_hs_flow_mbuf_conn_handle[ MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT) ]; static inline int ble_hs_flow_mbuf_index(const struct os_mbuf *om) @@ -136,7 +135,7 @@ ble_hs_flow_inc_completed_pkts(struct ble_hs_conn *conn) conn->bhc_completed_pkts++; ble_hs_flow_num_completed_pkts++; - if (ble_hs_flow_num_completed_pkts > MYNEWT_VAL(BLE_ACL_BUF_COUNT)) { + if (ble_hs_flow_num_completed_pkts > MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT)) { ble_hs_sched_reset(BLE_HS_ECONTROLLER); return; } @@ -144,7 +143,8 @@ ble_hs_flow_inc_completed_pkts(struct ble_hs_conn *conn) /* If the number of free buffers is at or below the configured threshold, * send an immediate number-of-copmleted-packets event. */ - num_free = MYNEWT_VAL(BLE_ACL_BUF_COUNT) - ble_hs_flow_num_completed_pkts; + num_free = MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT) - + ble_hs_flow_num_completed_pkts; if (num_free <= MYNEWT_VAL(BLE_HS_FLOW_CTRL_THRESH)) { ble_npl_eventq_put(ble_hs_evq_get(), &ble_hs_flow_ev); ble_npl_callout_stop(&ble_hs_flow_timer); @@ -230,16 +230,13 @@ ble_hs_flow_startup(void) #if MYNEWT_VAL(BLE_HS_FLOW_CTRL) struct ble_hci_cb_ctlr_to_host_fc_cp enable_cmd; struct ble_hci_cb_host_buf_size_cp buf_size_cmd = { - .acl_data_len = htole16(MYNEWT_VAL(BLE_ACL_BUF_SIZE)), - .acl_num = htole16(MYNEWT_VAL(BLE_ACL_BUF_COUNT)), + .acl_data_len = htole16(MYNEWT_VAL(BLE_TRANSPORT_ACL_SIZE)), + .acl_num = htole16(MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT)), }; int rc; ble_npl_event_init(&ble_hs_flow_ev, ble_hs_flow_event_cb, NULL); - /* Assume failure. */ - ble_hci_trans_set_acl_free_cb(NULL, NULL); - #if MYNEWT_VAL(SELFTEST) ble_npl_callout_stop(&ble_hs_flow_timer); #endif @@ -266,7 +263,7 @@ ble_hs_flow_startup(void) /* Flow control successfully enabled. */ ble_hs_flow_num_completed_pkts = 0; - ble_hci_trans_set_acl_free_cb(ble_hs_flow_acl_free, NULL); + ble_transport_register_put_acl_from_ll_cb(ble_hs_flow_acl_free); ble_npl_callout_init(&ble_hs_flow_timer, ble_hs_evq_get(), ble_hs_flow_event_cb, NULL); #endif diff --git a/nimble/host/src/ble_hs_hci.c b/nimble/host/src/ble_hs_hci.c index 53d36473b6..2157610249 100644 --- a/nimble/host/src/ble_hs_hci.c +++ b/nimble/host/src/ble_hs_hci.c @@ -22,7 +22,6 @@ #include #include "os/os.h" #include "mem/mem.h" -#include "nimble/ble_hci_trans.h" #include "host/ble_monitor.h" #include "ble_hs_priv.h" #include "ble_monitor_priv.h" @@ -269,8 +268,7 @@ ble_hs_hci_wait_for_ack(void) if (ble_hs_hci_phony_ack_cb == NULL) { rc = BLE_HS_ETIMEOUT_HCI; } else { - ble_hs_hci_ack = - (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); + ble_hs_hci_ack = ble_transport_alloc_cmd(); BLE_HS_DBG_ASSERT(ble_hs_hci_ack != NULL); rc = ble_hs_hci_phony_ack_cb((void *)ble_hs_hci_ack, 260); } @@ -351,7 +349,7 @@ ble_hs_hci_cmd_tx(uint16_t opcode, const void *cmd, uint8_t cmd_len, done: if (ble_hs_hci_ack != NULL) { - ble_hci_trans_buf_free((uint8_t *) ble_hs_hci_ack); + ble_transport_free((uint8_t *) ble_hs_hci_ack); ble_hs_hci_ack = NULL; } @@ -364,7 +362,7 @@ ble_hs_hci_rx_ack(uint8_t *ack_ev) { if (ble_npl_sem_get_count(&ble_hs_hci_sem) > 0) { /* This ack is unexpected; ignore it. */ - ble_hci_trans_buf_free(ack_ev); + ble_transport_free(ack_ev); return; } BLE_HS_DBG_ASSERT(ble_hs_hci_ack == NULL); diff --git a/nimble/host/src/ble_hs_hci_cmd.c b/nimble/host/src/ble_hs_hci_cmd.c index a0fd1ceac4..33e1ae8bde 100644 --- a/nimble/host/src/ble_hs_hci_cmd.c +++ b/nimble/host/src/ble_hs_hci_cmd.c @@ -23,7 +23,6 @@ #include #include "os/os.h" #include "nimble/hci_common.h" -#include "nimble/ble_hci_trans.h" #include "host/ble_monitor.h" #include "ble_hs_priv.h" #include "ble_monitor_priv.h" @@ -38,7 +37,7 @@ ble_hs_hci_cmd_transport(struct ble_hci_cmd *cmd) cmd->length + sizeof(*cmd)); #endif - rc = ble_hci_trans_hs_cmd_tx((uint8_t *) cmd); + rc = ble_transport_to_ll_cmd(cmd); switch (rc) { case 0: return 0; @@ -57,7 +56,7 @@ ble_hs_hci_cmd_send(uint16_t opcode, uint8_t len, const void *cmddata) struct ble_hci_cmd *cmd; int rc; - cmd = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); + cmd = ble_transport_alloc_cmd(); BLE_HS_DBG_ASSERT(cmd != NULL); cmd->opcode = htole16(opcode); diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 108ee645cd..3dba0bf658 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -22,7 +22,6 @@ #include #include "os/os.h" #include "nimble/hci_common.h" -#include "nimble/ble_hci_trans.h" #include "host/ble_gap.h" #include "host/ble_monitor.h" #include "ble_hs_priv.h" @@ -795,7 +794,7 @@ ble_hs_hci_evt_le_phy_update_complete(uint8_t subevent, const void *data, #endif int -ble_hs_hci_evt_process(const struct ble_hci_ev *ev) +ble_hs_hci_evt_process(struct ble_hci_ev *ev) { const struct ble_hs_hci_evt_dispatch_entry *entry; int rc; @@ -812,7 +811,7 @@ ble_hs_hci_evt_process(const struct ble_hci_ev *ev) rc = entry->cb(ev->opcode, ev->data, ev->length); } - ble_hci_trans_buf_free((uint8_t *) ev); + ble_transport_free(ev); return rc; } diff --git a/nimble/host/src/ble_hs_hci_priv.h b/nimble/host/src/ble_hs_hci_priv.h index 11e544f18f..47f3200817 100644 --- a/nimble/host/src/ble_hs_hci_priv.h +++ b/nimble/host/src/ble_hs_hci_priv.h @@ -105,7 +105,7 @@ int ble_hs_hci_util_set_data_len(uint16_t conn_handle, uint16_t tx_octets, uint16_t tx_time); int ble_hs_hci_util_data_hdr_strip(struct os_mbuf *om, struct hci_data_hdr *out_hdr); -int ble_hs_hci_evt_process(const struct ble_hci_ev *ev); +int ble_hs_hci_evt_process(struct ble_hci_ev *ev); int ble_hs_hci_cmd_send_buf(uint16_t opcode, const void *buf, uint8_t buf_len); int ble_hs_hci_set_buf_sz(uint16_t pktlen, uint16_t max_pkts); diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index c814ba5695..5f67c446de 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -497,3 +497,6 @@ syscfg.logs: syscfg.vals.BLE_MESH: BLE_SM_SC: 1 + +syscfg.restrictions: + - BLE_TRANSPORT_HS == "native" From ef597cc4b87059dd754c483e8a9e3a73d0291b24 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 3 Mar 2022 18:05:44 +0100 Subject: [PATCH 0335/1333] nimble/transport: Update Dialog CMAC transport --- nimble/transport/dialog_cmac/.gitignore | 2 - .../cmac_driver/diag/src/cmac_diag.c | 46 ++- .../include/cmac_driver/cmac_shared.h | 12 +- .../transport/dialog_cmac/cmac_driver/pkg.yml | 5 +- .../dialog_cmac/cmac_driver/src/cmac_host.c | 10 +- .../dialog_cmac/cmac_driver/src/cmac_mbox.c | 26 +- .../dialog_cmac/cmac_driver/src/cmac_rand.c | 2 +- .../dialog_cmac/cmac_driver/src/cmac_shared.c | 24 +- .../dialog_cmac/cmac_driver/syscfg.yml | 2 +- nimble/transport/dialog_cmac/pkg.yml | 5 +- .../dialog_cmac/src/ble_hci_cmac_common.c | 202 ----------- .../dialog_cmac/src/ble_hci_cmac_hs.c | 174 --------- .../dialog_cmac/src/ble_hci_cmac_ll.c | 146 -------- .../dialog_cmac/src/ble_hci_cmac_priv.h | 29 -- .../dialog_cmac/src/ble_hci_trans_h4.c | 332 ------------------ .../dialog_cmac/src/ble_hci_trans_h4.h | 49 --- nimble/transport/dialog_cmac/src/hci_cmac.c | 213 +++++++++++ nimble/transport/dialog_cmac/syscfg.yml | 27 -- 18 files changed, 274 insertions(+), 1032 deletions(-) delete mode 100644 nimble/transport/dialog_cmac/.gitignore delete mode 100644 nimble/transport/dialog_cmac/src/ble_hci_cmac_common.c delete mode 100644 nimble/transport/dialog_cmac/src/ble_hci_cmac_hs.c delete mode 100644 nimble/transport/dialog_cmac/src/ble_hci_cmac_ll.c delete mode 100644 nimble/transport/dialog_cmac/src/ble_hci_cmac_priv.h delete mode 100644 nimble/transport/dialog_cmac/src/ble_hci_trans_h4.c delete mode 100644 nimble/transport/dialog_cmac/src/ble_hci_trans_h4.h create mode 100644 nimble/transport/dialog_cmac/src/hci_cmac.c delete mode 100644 nimble/transport/dialog_cmac/syscfg.yml diff --git a/nimble/transport/dialog_cmac/.gitignore b/nimble/transport/dialog_cmac/.gitignore deleted file mode 100644 index bba9f995af..0000000000 --- a/nimble/transport/dialog_cmac/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/src/libble_stack_da1469x.a - diff --git a/nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c b/nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c index 0a4e27e6d5..83299038d4 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c +++ b/nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c @@ -20,30 +20,6 @@ #include "syscfg/syscfg.h" #include "mcu/mcu.h" -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) -void -cmac_diag_setup_host(void) -{ - /* Setup pins for diagnostic signals */ - mcu_gpio_set_pin_function(42, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAG0); /* DIAG_0 @ P1.10 */ - mcu_gpio_set_pin_function(43, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAG1); /* DIAG_1 @ P1.11 */ - mcu_gpio_set_pin_function(44, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAG2); /* DIAG_2 @ P1.12 */ - mcu_gpio_set_pin_function(24, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_3 @ P0.24 */ - mcu_gpio_set_pin_function(21, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_4 @ P0.21 */ - mcu_gpio_set_pin_function(20, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_5 @ P0.20 */ - mcu_gpio_set_pin_function(19, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_6 @ P0.19 */ - mcu_gpio_set_pin_function(18, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_7 @ P0.18 */ - mcu_gpio_set_pin_function(31, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_8 @ P0.31 */ - mcu_gpio_set_pin_function(30, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_9 @ P0.30 */ - mcu_gpio_set_pin_function(29, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_10 @ P0.29 */ - mcu_gpio_set_pin_function(28, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_11 @ P0.28 */ - mcu_gpio_set_pin_function(27, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_12 @ P0.27 */ - mcu_gpio_set_pin_function(26, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_13 @ P0.26 */ - mcu_gpio_set_pin_function(38, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_14 @ P1.06 */ - mcu_gpio_set_pin_function(41, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_15 @ P1.09 */ -} -#endif - #if MYNEWT_VAL(BLE_CONTROLLER) void cmac_diag_setup_cmac(void) @@ -65,4 +41,26 @@ cmac_diag_setup_cmac(void) MCU_DIAG_MAP(14, 4, SLEEPING); MCU_DIAG_MAP(15, 8, LL_TIMER1_00); } +#else +void +cmac_diag_setup_host(void) +{ + /* Setup pins for diagnostic signals */ + mcu_gpio_set_pin_function(42, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAG0); /* DIAG_0 @ P1.10 */ + mcu_gpio_set_pin_function(43, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAG1); /* DIAG_1 @ P1.11 */ + mcu_gpio_set_pin_function(44, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAG2); /* DIAG_2 @ P1.12 */ + mcu_gpio_set_pin_function(24, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_3 @ P0.24 */ + mcu_gpio_set_pin_function(21, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_4 @ P0.21 */ + mcu_gpio_set_pin_function(20, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_5 @ P0.20 */ + mcu_gpio_set_pin_function(19, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_6 @ P0.19 */ + mcu_gpio_set_pin_function(18, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_7 @ P0.18 */ + mcu_gpio_set_pin_function(31, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_8 @ P0.31 */ + mcu_gpio_set_pin_function(30, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_9 @ P0.30 */ + mcu_gpio_set_pin_function(29, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_10 @ P0.29 */ + mcu_gpio_set_pin_function(28, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_11 @ P0.28 */ + mcu_gpio_set_pin_function(27, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_12 @ P0.27 */ + mcu_gpio_set_pin_function(26, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_13 @ P0.26 */ + mcu_gpio_set_pin_function(38, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_14 @ P1.06 */ + mcu_gpio_set_pin_function(41, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_15 @ P1.09 */ +} #endif diff --git a/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h b/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h index da3a3cf612..887af25872 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h +++ b/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h @@ -131,10 +131,10 @@ struct cmac_shared_data { uint8_t mbox_c2s_buf[ MYNEWT_VAL(CMAC_MBOX_SIZE_C2S) ]; }; -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) -extern volatile struct cmac_shared_data *g_cmac_shared_data; -#elif MYNEWT_VAL(BLE_CONTROLLER) +#if MYNEWT_VAL(BLE_CONTROLLER) extern volatile struct cmac_shared_data g_cmac_shared_data; +#else +extern volatile struct cmac_shared_data *g_cmac_shared_data; #endif /* cmac_mbox */ @@ -162,10 +162,10 @@ void cmac_rand_set_isr_cb(cmac_rand_isr_cb_t cb); void cmac_shared_init(void); void cmac_shared_sync(void); -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) -#define CMAC_SHARED_LOCK_VAL 0x40000000 -#elif MYNEWT_VAL(BLE_CONTROLLER) +#if MYNEWT_VAL(BLE_CONTROLLER) #define CMAC_SHARED_LOCK_VAL 0xc0000000 +#else +#define CMAC_SHARED_LOCK_VAL 0x40000000 #endif static inline void diff --git a/nimble/transport/dialog_cmac/cmac_driver/pkg.yml b/nimble/transport/dialog_cmac/cmac_driver/pkg.yml index 00200b65a7..1fa003abb2 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/pkg.yml +++ b/nimble/transport/dialog_cmac/cmac_driver/pkg.yml @@ -35,8 +35,5 @@ pkg.ign_files.BLE_CONTROLLER: pkg.post_link_cmds.BLE_CONTROLLER: scripts/create_cmac_bin.sh: 100 -pkg.pre_link_cmds.BLE_HOST: - scripts/build_libcmac.sh: 100 - -pkg.pre_link_cmds.BLE_HCI_BRIDGE: +pkg.pre_link_cmds.!BLE_CONTROLLER: scripts/build_libcmac.sh: 100 diff --git a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c index 965db1398c..cdb00060ae 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c +++ b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c @@ -65,7 +65,7 @@ static struct os_event g_cmac_host_rand_ev = { static void cmac_host_rand_chk_fill(void); -#if MYNEWT_VAL(BLE_HCI_BRIDGE) && MYNEWT_VAL_CHOICE(BLE_HCI_TRANSPORT, uart) +#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, uart) static void cmac_host_error_w4flush(struct os_event *ev); static struct os_event g_cmac_host_error_ev = { .ev_cb = cmac_host_error_w4flush @@ -113,7 +113,7 @@ cmac2sys_isr(void) } #endif -#if MYNEWT_VAL(BLE_HCI_BRIDGE) && MYNEWT_VAL_CHOICE(BLE_HCI_TRANSPORT, uart) +#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, uart) NVIC_DisableIRQ(CMAC2SYS_IRQn); /* Wait until UART is flushed and then assert */ cmac_host_error_w4flush(NULL); @@ -162,8 +162,8 @@ cmac_host_rand_chk_fill(void) } } -#if MYNEWT_VAL(BLE_HCI_BRIDGE) && MYNEWT_VAL_CHOICE(BLE_HCI_TRANSPORT, uart) -#if MYNEWT_VAL(BLE_HCI_UART_PORT) < 0 || MYNEWT_VAL(BLE_HCI_UART_PORT) > 2 +#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, uart) +#if MYNEWT_VAL(BLE_TRANSPORT_UART_PORT) < 0 || MYNEWT_VAL(BLE_TRANSPORT_UART_PORT) > 2 #error Invalid BLE_HCI_UART_PORT #endif static void @@ -183,7 +183,7 @@ cmac_host_error_w4flush(struct os_event *ev) do { cmac_mbox_read(); - while ((regs[MYNEWT_VAL(BLE_HCI_UART_PORT)]->UART_LSR_REG & + while ((regs[MYNEWT_VAL(BLE_TRANSPORT_UART_PORT)]->UART_LSR_REG & UART_UART_LSR_REG_UART_TEMT_Msk) == 0) { /* Wait until both FIFO and shift registers are empty */ } diff --git a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c index 36f4e25e1c..d2ee9ac9b2 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c +++ b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c @@ -49,10 +49,10 @@ cmac_mbox_set_write_notif_cb(cmac_mbox_write_notif_cb *cb) int cmac_mbox_has_data(void) { -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) - volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_c2s; -#else +#if MYNEWT_VAL(BLE_CONTROLLER) volatile struct cmac_mbox *mbox = &g_cmac_shared_data.mbox_s2c; +#else + volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_c2s; #endif return mbox->rd_off != mbox->wr_off; @@ -61,14 +61,14 @@ cmac_mbox_has_data(void) int cmac_mbox_read(void) { -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) - volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_c2s; - uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data->mbox_c2s_buf; - const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_C2S); -#else +#if MYNEWT_VAL(BLE_CONTROLLER) volatile struct cmac_mbox *mbox = &g_cmac_shared_data.mbox_s2c; uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data.mbox_s2c_buf; const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_S2C); +#else + volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_c2s; + uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data->mbox_c2s_buf; + const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_C2S); #endif uint16_t rd_off; uint16_t wr_off; @@ -108,14 +108,14 @@ cmac_mbox_read(void) int cmac_mbox_write(const void *data, uint16_t len) { -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) - volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_s2c; - uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data->mbox_s2c_buf; - const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_S2C); -#else +#if MYNEWT_VAL(BLE_CONTROLLER) volatile struct cmac_mbox *mbox = &g_cmac_shared_data.mbox_c2s; uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data.mbox_c2s_buf; const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_C2S); +#else + volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_s2c; + uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data->mbox_s2c_buf; + const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_S2C); #endif uint16_t rd_off; uint16_t wr_off; diff --git a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c index 10810972ca..dbb93e9254 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c +++ b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c @@ -26,7 +26,7 @@ #include "os/os_arch.h" #include "os/os.h" -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) +#if !MYNEWT_VAL(BLE_CONTROLLER) int cmac_rand_is_active(void) { diff --git a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c index a4f2e37f56..cd7984afa8 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c +++ b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c @@ -34,18 +34,18 @@ #define min(_a, _b) ((_a) < (_b) ? (_a) : (_b)) #endif -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) +#if MYNEWT_VAL(BLE_CONTROLLER) +volatile struct cmac_shared_data g_cmac_shared_data __attribute__((section(".shdata"))); +#else volatile struct cmac_shared_data *g_cmac_shared_data; #include "mcu/da1469x_clock.h" #define MCU_DIAG_SER(_x) -#elif MYNEWT_VAL(BLE_CONTROLLER) -volatile struct cmac_shared_data g_cmac_shared_data __attribute__((section(".shdata"))); #endif void cmac_shared_init(void) { -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) +#if !MYNEWT_VAL(BLE_CONTROLLER) g_cmac_shared_data = (void *)(MCU_MEM_SYSRAM_START_ADDRESS + MEMCTRL->CMI_SHARED_BASE_REG); @@ -77,15 +77,6 @@ cmac_shared_sync(void) * to wait until CMAC finished initialization as otherwise host may start * sending HCI packets which will timeout as there is no one to read them. */ -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) - assert(g_cmac_shared_data->magic_sys == 0); - - while (g_cmac_shared_data->magic_cmac != CMAC_SHARED_MAGIC_CMAC); - g_cmac_shared_data->magic_sys = CMAC_SHARED_MAGIC_SYS; - - NVIC_EnableIRQ(CMAC2SYS_IRQn); -#endif - #if MYNEWT_VAL(BLE_CONTROLLER) assert(g_cmac_shared_data.magic_cmac == 0); @@ -94,5 +85,12 @@ cmac_shared_sync(void) NVIC_SetPriority(SYS2CMAC_IRQn, 3); NVIC_EnableIRQ(SYS2CMAC_IRQn); +#else + assert(g_cmac_shared_data->magic_sys == 0); + + while (g_cmac_shared_data->magic_cmac != CMAC_SHARED_MAGIC_CMAC); + g_cmac_shared_data->magic_sys = CMAC_SHARED_MAGIC_SYS; + + NVIC_EnableIRQ(CMAC2SYS_IRQn); #endif } diff --git a/nimble/transport/dialog_cmac/cmac_driver/syscfg.yml b/nimble/transport/dialog_cmac/cmac_driver/syscfg.yml index a382c42447..6ff3b4408b 100644 --- a/nimble/transport/dialog_cmac/cmac_driver/syscfg.yml +++ b/nimble/transport/dialog_cmac/cmac_driver/syscfg.yml @@ -100,5 +100,5 @@ syscfg.defs: priority. value: 0 -syscfg.restrictions.BLE_HOST: +syscfg.restrictions.!BLE_CONTROLLER: - TRNG diff --git a/nimble/transport/dialog_cmac/pkg.yml b/nimble/transport/dialog_cmac/pkg.yml index ef8fc1ee43..2c02d7e7ca 100644 --- a/nimble/transport/dialog_cmac/pkg.yml +++ b/nimble/transport/dialog_cmac/pkg.yml @@ -26,11 +26,8 @@ pkg.keywords: - bluetooth pkg.deps: - - nimble + - nimble/transport/common/hci_h4 - nimble/transport/dialog_cmac/cmac_driver pkg.apis: - ble_transport - -pkg.init: - ble_hci_cmac_init: 100 diff --git a/nimble/transport/dialog_cmac/src/ble_hci_cmac_common.c b/nimble/transport/dialog_cmac/src/ble_hci_cmac_common.c deleted file mode 100644 index 5a41ee6313..0000000000 --- a/nimble/transport/dialog_cmac/src/ble_hci_cmac_common.c +++ /dev/null @@ -1,202 +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. - */ - -#include -#include - -#include "syscfg/syscfg.h" -#include "os/mynewt.h" -#include "nimble/ble.h" -#include "nimble/ble_hci_trans.h" -#include "nimble/hci_common.h" -#include "ble_hci_cmac_priv.h" - -/* - * If controller-to-host flow control is enabled we need to hold an extra command - * buffer for HCI_Host_Number_Of_Completed_Packets which can be sent at any time. - */ -#if MYNEWT_VAL(BLE_HS_FLOW_CTRL) || MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) -#define HCI_CMD_COUNT 2 -#else -#define HCI_CMD_COUNT 1 -#endif - -#define POOL_ACL_BLOCK_SIZE OS_ALIGN(MYNEWT_VAL(BLE_ACL_BUF_SIZE) + \ - BLE_MBUF_MEMBLOCK_OVERHEAD + \ - BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT) - -#if !MYNEWT_VAL(BLE_HCI_BRIDGE) -static uint8_t ble_hci_pool_cmd_mempool_buf[ - OS_MEMPOOL_BYTES(HCI_CMD_COUNT, BLE_HCI_TRANS_CMD_SZ)]; -static struct os_mempool ble_hci_pool_cmd_mempool; - -static uint8_t ble_hci_pool_evt_hi_mempool_buf[ - OS_MEMPOOL_BYTES(MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE))]; -static struct os_mempool ble_hci_pool_evt_hi_mempool; - -static uint8_t ble_hci_pool_evt_lo_mempool_buf[ - OS_MEMPOOL_BYTES(MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE))]; -static struct os_mempool ble_hci_pool_evt_lo_mempool; -#endif - -static uint8_t ble_hci_pool_acl_mempool_buf[ - OS_MEMPOOL_BYTES(MYNEWT_VAL(BLE_ACL_BUF_COUNT), - POOL_ACL_BLOCK_SIZE)]; -static struct os_mempool_ext ble_hci_pool_acl_mempool; -static struct os_mbuf_pool ble_hci_pool_acl_mbuf_pool; - -__attribute__((weak)) void ble_hci_trans_notify_free(void); - -static os_mempool_put_fn *g_ble_hci_pool_acl_mempool_put_cb; -static void *g_ble_hci_pool_acl_mempool_put_arg; - -#if !MYNEWT_VAL(BLE_HCI_BRIDGE) -int -ble_hci_trans_reset(void) -{ - return 0; -} - -uint8_t * -ble_hci_trans_buf_alloc(int type) -{ - uint8_t *buf; - - switch (type) { - case BLE_HCI_TRANS_BUF_CMD: - buf = os_memblock_get(&ble_hci_pool_cmd_mempool); - break; - case BLE_HCI_TRANS_BUF_EVT_HI: - buf = os_memblock_get(&ble_hci_pool_evt_hi_mempool); - if (buf) { - break; - } - /* no break */ - case BLE_HCI_TRANS_BUF_EVT_LO: - buf = os_memblock_get(&ble_hci_pool_evt_lo_mempool); - break; - default: - assert(0); - buf = NULL; - } - - return buf; -} - -void -ble_hci_trans_buf_free(uint8_t *buf) -{ - int rc; - - if (os_memblock_from(&ble_hci_pool_cmd_mempool, buf)) { - rc = os_memblock_put(&ble_hci_pool_cmd_mempool, buf); - assert(rc == 0); - } else if (os_memblock_from(&ble_hci_pool_evt_hi_mempool, buf)) { - rc = os_memblock_put(&ble_hci_pool_evt_hi_mempool, buf); - assert(rc == 0); - } else { - assert(os_memblock_from(&ble_hci_pool_evt_lo_mempool, buf)); - rc = os_memblock_put(&ble_hci_pool_evt_lo_mempool, buf); - assert(rc == 0); - } - - ble_hci_trans_notify_free(); -} -#endif - -struct os_mbuf * -ble_hci_cmac_alloc_acl_mbuf(void) -{ - return os_mbuf_get_pkthdr(&ble_hci_pool_acl_mbuf_pool, - sizeof(struct ble_mbuf_hdr)); -} - -static os_error_t -ble_hci_cmac_free_acl_cb(struct os_mempool_ext *mpe, void *data, void *arg) -{ - int rc; - - if (g_ble_hci_pool_acl_mempool_put_cb) { - rc = g_ble_hci_pool_acl_mempool_put_cb(mpe, data, - g_ble_hci_pool_acl_mempool_put_arg); - } else { - rc = os_memblock_put_from_cb(&mpe->mpe_mp, data); - } - - if (rc != 0) { - return rc; - } - - ble_hci_trans_notify_free(); - - return 0; -} - - -#if !MYNEWT_VAL(BLE_HCI_BRIDGE) -int -ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg) -{ - g_ble_hci_pool_acl_mempool_put_cb = cb; - g_ble_hci_pool_acl_mempool_put_arg = arg; - - return 0; -} -#endif - -void -ble_hci_cmac_init(void) -{ - int rc; - - SYSINIT_ASSERT_ACTIVE(); - -#if !MYNEWT_VAL(BLE_HCI_BRIDGE) - rc = os_mempool_init(&ble_hci_pool_cmd_mempool, - HCI_CMD_COUNT, BLE_HCI_TRANS_CMD_SZ, - ble_hci_pool_cmd_mempool_buf, "ble_hci_cmd"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&ble_hci_pool_evt_hi_mempool, - MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - ble_hci_pool_evt_hi_mempool_buf, "ble_hci_evt_hi"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&ble_hci_pool_evt_lo_mempool, - MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - ble_hci_pool_evt_lo_mempool_buf, "ble_hci_evt_lo"); - SYSINIT_PANIC_ASSERT(rc == 0); -#endif - - rc = os_mempool_ext_init(&ble_hci_pool_acl_mempool, - MYNEWT_VAL(BLE_ACL_BUF_COUNT), POOL_ACL_BLOCK_SIZE, - ble_hci_pool_acl_mempool_buf, "ble_hci_acl"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mbuf_pool_init(&ble_hci_pool_acl_mbuf_pool, - &ble_hci_pool_acl_mempool.mpe_mp, POOL_ACL_BLOCK_SIZE, - MYNEWT_VAL(BLE_ACL_BUF_COUNT)); - SYSINIT_PANIC_ASSERT(rc == 0); - - ble_hci_pool_acl_mempool.mpe_put_cb = ble_hci_cmac_free_acl_cb; -} diff --git a/nimble/transport/dialog_cmac/src/ble_hci_cmac_hs.c b/nimble/transport/dialog_cmac/src/ble_hci_cmac_hs.c deleted file mode 100644 index 266637f78e..0000000000 --- a/nimble/transport/dialog_cmac/src/ble_hci_cmac_hs.c +++ /dev/null @@ -1,174 +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. - */ - -#include -#include -#include "syscfg/syscfg.h" - -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) - -#include "cmac_driver/cmac_shared.h" -#include "cmac_driver/cmac_host.h" -#include "nimble/ble_hci_trans.h" -#include "os/os_mbuf.h" -#include "ble_hci_trans_h4.h" -#include "ble_hci_cmac_priv.h" - -struct ble_hci_cmac_hs_api { - ble_hci_trans_rx_cmd_fn *evt_cb; - void *evt_arg; - ble_hci_trans_rx_acl_fn *acl_cb; - void *acl_arg; -}; - -static struct ble_hci_cmac_hs_api g_ble_hci_cmac_hs_api; -static struct ble_hci_trans_h4_rx_state g_ble_hci_cmac_hs_rx_state; -static bool g_ble_hci_cmac_hs_read_err; - -#if MYNEWT_VAL(BLE_HCI_BRIDGE) -/* - * TODO: Remove/fix functions ble_ll_data_buffer_overflow() ble_ll_hw_error() - * Following two functions are added to allowed build of HCI bridge configurations. - * Those functions are only used by UART transport, in RAM transport configuration - * they can be called directly in bridge mode controller code is on other core - * and those can't be called. - */ -void -ble_ll_data_buffer_overflow(void) -{ - -} - -void -ble_ll_hw_error(uint8_t err) -{ - (void)err; -} -#endif - -static int -ble_hci_cmac_hs_frame_cb(uint8_t pkt_type, void *data) -{ - int rc; - - switch (pkt_type) { - case BLE_HCI_TRANS_H4_PKT_TYPE_ACL: - rc = g_ble_hci_cmac_hs_api.acl_cb(data, g_ble_hci_cmac_hs_api.acl_arg); - break; - case BLE_HCI_TRANS_H4_PKT_TYPE_EVT: - rc = g_ble_hci_cmac_hs_api.evt_cb(data, g_ble_hci_cmac_hs_api.evt_arg); - break; - default: - assert(0); - break; - } - - return rc; -} - -static int -ble_hci_cmac_hs_mbox_read_cb(const void *data, uint16_t len) -{ - int rlen; - os_sr_t sr; - - rlen = ble_hci_trans_h4_rx(&g_ble_hci_cmac_hs_rx_state, data, len, - ble_hci_cmac_hs_frame_cb); - if (rlen < 0) { - /* - * There was oom error, we need to wait for buffer to be freed and - * trigger another read. - */ - OS_ENTER_CRITICAL(sr); - g_ble_hci_cmac_hs_read_err = true; - OS_EXIT_CRITICAL(sr); - } - - return rlen; -} - -static void -ble_hci_cmac_hs_mbox_write_notif_cb(void) -{ - cmac_host_signal2cmac(); -} - -int -ble_hci_trans_hs_cmd_tx(uint8_t *cmd) -{ - uint8_t pkt_type = BLE_HCI_TRANS_H4_PKT_TYPE_CMD; - - cmac_mbox_write(&pkt_type, sizeof(pkt_type)); - cmac_mbox_write(cmd, cmd[2] + 3); - - ble_hci_trans_buf_free(cmd); - - return 0; -} - -int -ble_hci_trans_hs_acl_tx(struct os_mbuf *om) -{ - uint8_t pkt_type = BLE_HCI_TRANS_H4_PKT_TYPE_ACL; - struct os_mbuf *om_next; - - cmac_mbox_write(&pkt_type, sizeof(pkt_type)); - - while (om) { - om_next = SLIST_NEXT(om, om_next); - - cmac_mbox_write(om->om_data, om->om_len); - - os_mbuf_free(om); - om = om_next; - } - - return 0; -} - -void -ble_hci_trans_notify_free(void) -{ - os_sr_t sr; - - OS_ENTER_CRITICAL(sr); - if (g_ble_hci_cmac_hs_read_err) { - g_ble_hci_cmac_hs_read_err = false; - /* Just trigger an interrupt, it will trigger read */ - NVIC_SetPendingIRQ(CMAC2SYS_IRQn); - } - OS_EXIT_CRITICAL(sr); -} - -void -ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *evt_cb, void *evt_arg, - ble_hci_trans_rx_acl_fn *acl_cb, void *acl_arg) -{ - g_ble_hci_cmac_hs_api.evt_cb = evt_cb; - g_ble_hci_cmac_hs_api.evt_arg = evt_arg; - g_ble_hci_cmac_hs_api.acl_cb = acl_cb; - g_ble_hci_cmac_hs_api.acl_arg = acl_arg; - - /* We can now handle data from CMAC, initialize it */ - cmac_mbox_set_read_cb(ble_hci_cmac_hs_mbox_read_cb); - cmac_mbox_set_write_notif_cb(ble_hci_cmac_hs_mbox_write_notif_cb); - cmac_host_init(); -} - -#endif diff --git a/nimble/transport/dialog_cmac/src/ble_hci_cmac_ll.c b/nimble/transport/dialog_cmac/src/ble_hci_cmac_ll.c deleted file mode 100644 index 6b49158ad9..0000000000 --- a/nimble/transport/dialog_cmac/src/ble_hci_cmac_ll.c +++ /dev/null @@ -1,146 +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. - */ - -#include "syscfg/syscfg.h" - -#if MYNEWT_VAL(BLE_CONTROLLER) - -#if !MYNEWT_VAL(MCU_DEBUG_DSER_BLE_HCI_CMAC_LL) -#define MCU_DIAG_SER_DISABLE -#endif - -#include -#include -#include "mcu/mcu.h" -#include "cmac_driver/cmac_shared.h" -#include "nimble/ble_hci_trans.h" -#include "os/os_mbuf.h" -#include "ble_hci_trans_h4.h" -#include "ble_hci_cmac_priv.h" - -struct ble_hci_cmac_ll_api { - ble_hci_trans_rx_cmd_fn *cmd_cb; - void *cmd_arg; - ble_hci_trans_rx_acl_fn *acl_cb; - void *acl_arg; -}; - -static struct ble_hci_cmac_ll_api g_ble_hci_cmac_ll_api; -static struct ble_hci_trans_h4_rx_state g_ble_hci_cmac_ll_rx_state; - -static int -ble_hci_cmac_ll_frame_cb(uint8_t pkt_type, void *data) -{ - int rc; - - MCU_DIAG_SER('F'); - - switch (pkt_type) { - case BLE_HCI_TRANS_H4_PKT_TYPE_CMD: - rc = g_ble_hci_cmac_ll_api.cmd_cb(data, g_ble_hci_cmac_ll_api.cmd_arg); - break; - case BLE_HCI_TRANS_H4_PKT_TYPE_ACL: - rc = g_ble_hci_cmac_ll_api.acl_cb(data, g_ble_hci_cmac_ll_api.acl_arg); - break; - default: - assert(0); - break; - } - - return rc; -} - -static int -ble_hci_cmac_ll_mbox_read_cb(const void *data, uint16_t len) -{ - int rlen; - - MCU_DIAG_SER('R'); - rlen = ble_hci_trans_h4_rx(&g_ble_hci_cmac_ll_rx_state, data, len, - ble_hci_cmac_ll_frame_cb); - - /* There should be no oom on LL side due to flow control used */ - assert(rlen >= 0); - - return rlen; -} - -static void -ble_hci_cmac_ll_mbox_write_notif_cb(void) -{ - MCU_DIAG_SER('W'); - CMAC->CM_EV_SET_REG = CMAC_CM_EV_SET_REG_EV1C_CMAC2SYS_IRQ_SET_Msk; -} - -int -ble_hci_trans_ll_evt_tx(uint8_t *evt) -{ - uint8_t pkt_type = BLE_HCI_TRANS_H4_PKT_TYPE_EVT; - os_sr_t sr; - - OS_ENTER_CRITICAL(sr); - - cmac_mbox_write(&pkt_type, sizeof(pkt_type)); - cmac_mbox_write(evt, evt[1] + 2); - - ble_hci_trans_buf_free(evt); - - OS_EXIT_CRITICAL(sr); - - return 0; -} - -int -ble_hci_trans_ll_acl_tx(struct os_mbuf *om) -{ - uint8_t pkt_type = BLE_HCI_TRANS_H4_PKT_TYPE_ACL; - struct os_mbuf *om_next; - - cmac_mbox_write(&pkt_type, sizeof(pkt_type)); - - while (om) { - om_next = SLIST_NEXT(om, om_next); - - cmac_mbox_write(om->om_data, om->om_len); - - os_mbuf_free(om); - om = om_next; - } - - return 0; -} - -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) -{ - g_ble_hci_cmac_ll_api.cmd_cb = cmd_cb; - g_ble_hci_cmac_ll_api.cmd_arg = cmd_arg; - g_ble_hci_cmac_ll_api.acl_cb = acl_cb; - g_ble_hci_cmac_ll_api.acl_arg = acl_arg; - - /* Setup callbacks for mailboxes */ - cmac_mbox_set_read_cb(ble_hci_cmac_ll_mbox_read_cb); - cmac_mbox_set_write_notif_cb(ble_hci_cmac_ll_mbox_write_notif_cb); - - /* Synchronize with SYS */ - cmac_shared_sync(); -} - -#endif diff --git a/nimble/transport/dialog_cmac/src/ble_hci_cmac_priv.h b/nimble/transport/dialog_cmac/src/ble_hci_cmac_priv.h deleted file mode 100644 index 451053c303..0000000000 --- a/nimble/transport/dialog_cmac/src/ble_hci_cmac_priv.h +++ /dev/null @@ -1,29 +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 _BLE_HCI_CMAC_PRIV_H_ -#define _BLE_HCI_CMAC_PRIV_H_ - -#include "os/os_mbuf.h" - -struct os_mbuf *ble_hci_cmac_alloc_acl_mbuf(void); - -void ble_hci_trans_notify_free(void); - -#endif /* _BLE_HCI_CMAC_PRIV_H_ */ diff --git a/nimble/transport/dialog_cmac/src/ble_hci_trans_h4.c b/nimble/transport/dialog_cmac/src/ble_hci_trans_h4.c deleted file mode 100644 index 628ae75d96..0000000000 --- a/nimble/transport/dialog_cmac/src/ble_hci_trans_h4.c +++ /dev/null @@ -1,332 +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. - */ - -#include -#include -#include -#include "syscfg/syscfg.h" -#include "os/os_mbuf.h" -#include "nimble/ble_hci_trans.h" -#include "nimble/hci_common.h" -#include "ble_hci_trans_h4.h" -#include "ble_hci_cmac_priv.h" - -#define RXS_STATE_W4_PKT_TYPE 0 -#define RXS_STATE_W4_HEADER 1 -#define RXS_STATE_W4_PAYLOAD 2 -#define RXS_STATE_COMPLETED 3 - -struct input_buffer { - const uint8_t *buf; - uint16_t len; -}; - -static int -ble_hci_trans_h4_ib_adjust(struct input_buffer *ib, uint16_t len) -{ - assert(ib->len >= len); - - ib->buf += len; - ib->len -= len; - - return len; -} - -static void -ble_hci_trans_h4_rxs_start(struct ble_hci_trans_h4_rx_state *rxs, uint8_t pkt_type) -{ - rxs->pkt_type = pkt_type; - rxs->len = 0; - rxs->expected_len = 0; - - switch (rxs->pkt_type) { -#if MYNEWT_VAL(BLE_CONTROLLER) - case BLE_HCI_TRANS_H4_PKT_TYPE_CMD: - rxs->min_len = 3; - break; -#endif - case BLE_HCI_TRANS_H4_PKT_TYPE_ACL: - rxs->min_len = 4; - break; -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) - case BLE_HCI_TRANS_H4_PKT_TYPE_EVT: - rxs->min_len = 2; - break; -#endif - default: - /* XXX sync loss */ - assert(0); - break; - } -} - -static int -ble_hci_trans_h4_pull_min_len(struct ble_hci_trans_h4_rx_state *rxs, - struct input_buffer *ib) -{ - uint16_t len; - - len = min(ib->len, rxs->min_len - rxs->len); - memcpy(&rxs->hdr[rxs->len], ib->buf, len); - - rxs->len += len; - ble_hci_trans_h4_ib_adjust(ib, len); - - return rxs->len != rxs->min_len; -} - -static int -ble_hci_trans_h4_rx_state_w4_header(struct ble_hci_trans_h4_rx_state *rxs, - struct input_buffer *ib) -{ -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) - int pool; -#endif - int rc; - - rc = ble_hci_trans_h4_pull_min_len(rxs, ib); - if (rc) { - /* need more data */ - return 1; - } - - switch (rxs->pkt_type) { -#if MYNEWT_VAL(BLE_CONTROLLER) - case BLE_HCI_TRANS_H4_PKT_TYPE_CMD: - rxs->buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - if (!rxs->buf) { - return -1; - } - - memcpy(rxs->buf, rxs->hdr, rxs->len); - rxs->expected_len = rxs->hdr[2] + 3; - break; -#endif - case BLE_HCI_TRANS_H4_PKT_TYPE_ACL: - rxs->om = ble_hci_cmac_alloc_acl_mbuf(); - if (!rxs->om) { - return -1; - } - - os_mbuf_append(rxs->om, rxs->hdr, rxs->len); - rxs->expected_len = get_le16(&rxs->hdr[2]) + 4; - break; -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) - case BLE_HCI_TRANS_H4_PKT_TYPE_EVT: - pool = BLE_HCI_TRANS_BUF_EVT_HI; - if (rxs->hdr[0] == BLE_HCI_EVCODE_LE_META) { - /* For LE Meta event we need 3 bytes to parse header */ - rxs->min_len = 3; - rc = ble_hci_trans_h4_pull_min_len(rxs, ib); - if (rc) { - /* need more data */ - return 1; - } - - /* Advertising reports shall be allocated from low-prio pool */ - if ((rxs->hdr[2] == BLE_HCI_LE_SUBEV_ADV_RPT) || - (rxs->hdr[2] == BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) { - pool = BLE_HCI_TRANS_BUF_EVT_LO; - } - } - - /* - * XXX Events originally allocated from hi-pool can use lo-pool as - * fallback and cannot be dropped. Events allocated from lo-pool - * can be dropped to avoid oom while scanning which means that - * any advertising or extended advertising report can be silently - * discarded by transport. While this is perfectly fine for legacy - * advertising, for extended advertising it means we can drop start - * or end of chain report and host won't be able to reassemble - * chain properly... so just need to make sure pool on host side is - * large enough to catch up with controller. - */ - rxs->buf = ble_hci_trans_buf_alloc(pool); - if (!rxs->buf && pool == BLE_HCI_TRANS_BUF_EVT_HI) { - rxs->buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); - if (!rxs->buf) { - return -1; - } - } - - if (rxs->buf) { - memcpy(rxs->buf, rxs->hdr, rxs->len); - } - - rxs->expected_len = rxs->hdr[1] + 2; - break; -#endif - default: - assert(0); - break; - } - - return 0; -} - -static int -ble_hci_trans_h4_rx_state_w4_payload(struct ble_hci_trans_h4_rx_state *rxs, - struct input_buffer *ib) -{ - uint16_t mbuf_len; - uint16_t len; - int rc; - - len = min(ib->len, rxs->expected_len - rxs->len); - - switch (rxs->pkt_type) { -#if MYNEWT_VAL(BLE_CONTROLLER) - case BLE_HCI_TRANS_H4_PKT_TYPE_CMD: -#endif -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) - case BLE_HCI_TRANS_H4_PKT_TYPE_EVT: -#endif - if (rxs->buf) { - memcpy(&rxs->buf[rxs->len], ib->buf, len); - } - break; - case BLE_HCI_TRANS_H4_PKT_TYPE_ACL: - assert(rxs->om); - - mbuf_len = OS_MBUF_PKTLEN(rxs->om); - rc = os_mbuf_append(rxs->om, ib->buf, len); - if (rc) { - /* - * Some data may already be appended so need to adjust rxs only by - * the size of appended data. - */ - len = OS_MBUF_PKTLEN(rxs->om) - mbuf_len; - rxs->len += len; - ble_hci_trans_h4_ib_adjust(ib, len); - - return -1; - } - break; - default: - assert(0); - break; - } - - rxs->len += len; - ble_hci_trans_h4_ib_adjust(ib, len); - - /* return 1 if need more data */ - return rxs->len != rxs->expected_len; -} - -static void -ble_hci_trans_h4_rx_state_completed(struct ble_hci_trans_h4_rx_state *rxs, - ble_hci_trans_h4_frame_cb *frame_cb) -{ - int rc; - - switch (rxs->pkt_type) { -#if MYNEWT_VAL(BLE_CONTROLLER) - case BLE_HCI_TRANS_H4_PKT_TYPE_CMD: -#endif -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) - case BLE_HCI_TRANS_H4_PKT_TYPE_EVT: -#endif - if (rxs->buf) { - rc = frame_cb(rxs->pkt_type, rxs->buf); - if (rc != 0) { - ble_hci_trans_buf_free(rxs->buf); - } - rxs->buf = NULL; - } - break; - case BLE_HCI_TRANS_H4_PKT_TYPE_ACL: - if (rxs->om) { - rc = frame_cb(rxs->pkt_type, rxs->om); - if (rc != 0) { - os_mbuf_free_chain(rxs->om); - } - rxs->om = NULL; - } - break; - default: - assert(0); - break; - } -} - -int -ble_hci_trans_h4_rx(struct ble_hci_trans_h4_rx_state *rxs, const uint8_t *buf, - uint16_t len, ble_hci_trans_h4_frame_cb *frame_cb) -{ - struct input_buffer ib = { - .buf = buf, - .len = len, - }; - int rc = 0; - - while (ib.len && (rc >= 0)) { - rc = 0; - switch (rxs->state) { - case RXS_STATE_W4_PKT_TYPE: - ble_hci_trans_h4_rxs_start(rxs, ib.buf[0]); - ble_hci_trans_h4_ib_adjust(&ib, 1); - rxs->state = RXS_STATE_W4_HEADER; - /* no break */ - - case RXS_STATE_W4_HEADER: - rc = ble_hci_trans_h4_rx_state_w4_header(rxs, &ib); - if (rc) { - break; - } - rxs->state = RXS_STATE_W4_PAYLOAD; - /* no break */ - - case RXS_STATE_W4_PAYLOAD: - rc = ble_hci_trans_h4_rx_state_w4_payload(rxs, &ib); - if (rc) { - break; - } - rxs->state = RXS_STATE_COMPLETED; - /* no break */ - - case RXS_STATE_COMPLETED: - ble_hci_trans_h4_rx_state_completed(rxs, frame_cb); - rxs->state = RXS_STATE_W4_PKT_TYPE; - break; - - default: - assert(0); - /* consume all remaining data */ - ble_hci_trans_h4_ib_adjust(&ib, ib.len); - break; - } - } - - /* - * Calculate consumed bytes - * - * Note: we should always consume some bytes unless there is an oom error. - * It's also possible that we have an oom error but already consumed some - * data, in such case just return success and error will be returned on next - * pass. - */ - len = len - ib.len; - if (len == 0) { - assert(rc < 0); - return -1; - } - - return len; -} diff --git a/nimble/transport/dialog_cmac/src/ble_hci_trans_h4.h b/nimble/transport/dialog_cmac/src/ble_hci_trans_h4.h deleted file mode 100644 index 5b83f6b001..0000000000 --- a/nimble/transport/dialog_cmac/src/ble_hci_trans_h4.h +++ /dev/null @@ -1,49 +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 _BLE_HCI_TRANS_H4_H_ -#define _BLE_HCI_TRANS_H4_H_ - -#include - -#define BLE_HCI_TRANS_H4_PKT_TYPE_NONE 0x00 -#define BLE_HCI_TRANS_H4_PKT_TYPE_CMD 0x01 -#define BLE_HCI_TRANS_H4_PKT_TYPE_ACL 0x02 -#define BLE_HCI_TRANS_H4_PKT_TYPE_EVT 0x04 - -struct ble_hci_trans_h4_rx_state { - uint8_t state; - uint8_t pkt_type; - uint8_t min_len; - uint16_t len; - uint16_t expected_len; - uint8_t hdr[4]; - union { - uint8_t *buf; - struct os_mbuf *om; - }; -}; - -typedef int (ble_hci_trans_h4_frame_cb)(uint8_t pkt_type, void *data); - -int ble_hci_trans_h4_rx(struct ble_hci_trans_h4_rx_state *rxs, - const uint8_t *buf, uint16_t len, - ble_hci_trans_h4_frame_cb *frame_cb); - -#endif /* _BLE_HCI_TRANS_H4_H_ */ diff --git a/nimble/transport/dialog_cmac/src/hci_cmac.c b/nimble/transport/dialog_cmac/src/hci_cmac.c new file mode 100644 index 0000000000..254e0db0ca --- /dev/null +++ b/nimble/transport/dialog_cmac/src/hci_cmac.c @@ -0,0 +1,213 @@ +/* + * 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. + */ + +#include +#include +#include +#if MYNEWT_VAL(BLE_CONTROLLER) +/* to enable dser diag */ +#include +#endif /* BLE_CONTROLLER */ +#include +#if !MYNEWT_VAL(BLE_CONTROLLER) +#include +#endif /* !BLE_CONTROLLER */ +#include +#include +#include +#include + +static struct hci_h4_sm hci_cmac_h4sm; + +static int +hci_cmac_acl_tx(struct os_mbuf *om) +{ + uint8_t pkt_type = HCI_H4_ACL; + struct os_mbuf *om_next; + + cmac_mbox_write(&pkt_type, sizeof(pkt_type)); + + while (om) { + om_next = SLIST_NEXT(om, om_next); + + cmac_mbox_write(om->om_data, om->om_len); + + os_mbuf_free(om); + om = om_next; + } + + return 0; +} + +#if !MYNEWT_VAL(BLE_CONTROLLER) +static int +hci_cmac_hs_frame_cb(uint8_t pkt_type, void *data) +{ + int rc; + + switch (pkt_type) { + case HCI_H4_ACL: + rc = ble_transport_to_hs_acl(data); + break; + case HCI_H4_EVT: + rc = ble_transport_to_hs_evt(data); + break; + default: + assert(0); + break; + } + + return rc; +} + +static int +hci_cmac_hs_mbox_read_cb(const void *data, uint16_t len) +{ + int rlen; + + rlen = hci_h4_sm_rx(&hci_cmac_h4sm, data, len); + assert(rlen >= 0); + + return rlen; +} + +static void +hci_cmac_hs_mbox_write_notif_cb(void) +{ + cmac_host_signal2cmac(); +} + +void +ble_transport_ll_init(void) +{ + hci_h4_sm_init(&hci_cmac_h4sm, &hci_h4_allocs_from_ll, hci_cmac_hs_frame_cb); + + /* We can now handle data from CMAC, initialize it */ + cmac_mbox_set_read_cb(hci_cmac_hs_mbox_read_cb); + cmac_mbox_set_write_notif_cb(hci_cmac_hs_mbox_write_notif_cb); + cmac_host_init(); +} +#endif /* !BLE_CONTROLLER */ + +#if MYNEWT_VAL(BLE_CONTROLLER) +#if !MYNEWT_VAL(MCU_DEBUG_DSER_BLE_HCI_CMAC_LL) +#define MCU_DIAG_SER_DISABLE +#endif + +static int +hci_cmac_ll_frame_cb(uint8_t pkt_type, void *data) +{ + int rc; + + switch (pkt_type) { + case HCI_H4_CMD: + rc = ble_transport_to_ll_cmd(data); + break; + case HCI_H4_ACL: + rc = ble_transport_to_ll_acl(data); + break; + default: + assert(0); + break; + } + + return rc; +} + +static int +hci_cmac_ll_mbox_read_cb(const void *data, uint16_t len) +{ + int rlen; + + MCU_DIAG_SER('R'); + rlen = hci_h4_sm_rx(&hci_cmac_h4sm, data, len); + assert(rlen >= 0); + + return rlen; +} + +static void +hci_cmac_ll_mbox_write_notif_cb(void) +{ + MCU_DIAG_SER('W'); + CMAC->CM_EV_SET_REG = CMAC_CM_EV_SET_REG_EV1C_CMAC2SYS_IRQ_SET_Msk; +} + +void +ble_transport_hs_init(void) +{ + hci_h4_sm_init(&hci_cmac_h4sm, &hci_h4_allocs_from_hs, hci_cmac_ll_frame_cb); + + /* Setup callbacks for mailboxes */ + cmac_mbox_set_read_cb(hci_cmac_ll_mbox_read_cb); + cmac_mbox_set_write_notif_cb(hci_cmac_ll_mbox_write_notif_cb); + + /* Synchronize with SYS */ + cmac_shared_sync(); +} +#endif + +#if !MYNEWT_VAL(BLE_CONTROLLER) +int +ble_transport_to_ll_cmd(void *buf) +{ + uint8_t pkt_type = HCI_H4_CMD; + uint8_t *cmd = buf; + + cmac_mbox_write(&pkt_type, sizeof(pkt_type)); + cmac_mbox_write(cmd, cmd[2] + 3); + + ble_transport_free(buf); + + return 0; +} + +int +ble_transport_to_ll_acl(struct os_mbuf *om) +{ + return hci_cmac_acl_tx(om); +} +#endif + +#if MYNEWT_VAL(BLE_CONTROLLER) +int +ble_transport_to_hs_acl(struct os_mbuf *om) +{ + return hci_cmac_acl_tx(om); +} + +int +ble_transport_to_hs_evt(void *buf) +{ + uint8_t pkt_type = HCI_H4_EVT; + uint8_t *evt = buf; + os_sr_t sr; + + OS_ENTER_CRITICAL(sr); + + cmac_mbox_write(&pkt_type, sizeof(pkt_type)); + cmac_mbox_write(evt, evt[1] + 2); + + ble_transport_free(buf); + + OS_EXIT_CRITICAL(sr); + + return 0; +} +#endif /* BLE_CONTROLLER */ diff --git a/nimble/transport/dialog_cmac/syscfg.yml b/nimble/transport/dialog_cmac/syscfg.yml deleted file mode 100644 index c67df3dc0f..0000000000 --- a/nimble/transport/dialog_cmac/syscfg.yml +++ /dev/null @@ -1,27 +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. -# - -syscfg.vals.'!BLE_HCI_BRIDGE': - BLE_HCI_EVT_HI_BUF_COUNT: 2 - BLE_HCI_EVT_LO_BUF_COUNT: 8 - BLE_HCI_EVT_BUF_SIZE: 70 - BLE_ACL_BUF_COUNT: 4 - BLE_ACL_BUF_SIZE: 255 - -syscfg.vals.'!BLE_HCI_BRIDGE && (BLE_EXT_ADV || BLE_LL_CFG_FEAT_LL_EXT_ADV)': - BLE_HCI_EVT_BUF_SIZE: 257 From 33c1ece041095dd93d039d2b68997b13b0efceb0 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 3 Mar 2022 18:05:55 +0100 Subject: [PATCH 0336/1333] nimble/transport: Update nRF5340 transport --- nimble/transport/nrf5340/pkg.yml | 6 +- .../transport/nrf5340/src/nrf5340_ble_hci.c | 492 +++--------------- 2 files changed, 79 insertions(+), 419 deletions(-) diff --git a/nimble/transport/nrf5340/pkg.yml b/nimble/transport/nrf5340/pkg.yml index 4db567c81f..73dfcf9e50 100644 --- a/nimble/transport/nrf5340/pkg.yml +++ b/nimble/transport/nrf5340/pkg.yml @@ -27,12 +27,10 @@ pkg.keywords: - nrf5340 pkg.deps: - - "@apache-mynewt-nimble/nimble" + - nimble + - nimble/transport/common/hci_h4 - "@apache-mynewt-core/kernel/os" - "@apache-mynewt-core/hw/drivers/ipc_nrf5340" pkg.apis: - ble_transport - -pkg.init: - nrf5340_ble_hci_init: 'MYNEWT_VAL(BLE_TRANS_NRF5340_SYSINIT_STAGE)' diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index 1f510e8a68..eee27c9b62 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -21,133 +21,24 @@ #include #include #include -#include -#include #include - -#define HCI_PKT_NONE 0x00 -#define HCI_PKT_CMD 0x01 -#define HCI_PKT_ACL 0x02 -#define HCI_PKT_EVT 0x04 - -#define POOL_ACL_BLOCK_SIZE OS_ALIGN(MYNEWT_VAL(BLE_ACL_BUF_SIZE) + \ - BLE_MBUF_MEMBLOCK_OVERHEAD + \ - BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT) +#include +#include #if MYNEWT_VAL(BLE_CONTROLLER) #define IPC_TX_CHANNEL 0 #define IPC_RX_CHANNEL 1 -#endif - -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) +#else #define IPC_TX_CHANNEL 1 #define IPC_RX_CHANNEL 0 #endif -struct nrf5340_ble_hci_api { -#if MYNEWT_VAL(BLE_CONTROLLER) - ble_hci_trans_rx_cmd_fn *cmd_cb; - void *cmd_arg; -#endif -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) - ble_hci_trans_rx_cmd_fn *evt_cb; - void *evt_arg; -#endif - ble_hci_trans_rx_acl_fn *acl_cb; - void *acl_arg; -}; - -struct nrf5340_ble_hci_rx_data { - uint8_t type; - uint8_t hdr[4]; - uint16_t len; - uint16_t expected_len; - union { - uint8_t *buf; - struct os_mbuf *om; - }; -}; - -struct nrf5340_ble_hci_pool_cmd { - uint8_t cmd[BLE_HCI_TRANS_CMD_SZ]; - bool allocated; -}; - -#if !MYNEWT_VAL(BLE_HCI_BRIDGE) -/* - * If controller-to-host flow control is enabled we need to hold an extra command - * buffer for HCI_Host_Number_Of_Completed_Packets which can be sent at any time. - */ -#if MYNEWT_VAL(BLE_HS_FLOW_CTRL) || MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) -#define HCI_CMD_COUNT 2 -#else -#define HCI_CMD_COUNT 1 -#endif - -static uint8_t nrf5340_ble_hci_pool_cmd_mempool_buf[OS_MEMPOOL_BYTES( - HCI_CMD_COUNT, - BLE_HCI_TRANS_CMD_SZ)]; -static struct os_mempool nrf5340_ble_hci_pool_cmd_mempool; - -/* Pools for HCI events (high and low priority) */ -static uint8_t nrf5340_ble_hci_pool_evt_hi_buf[OS_MEMPOOL_BYTES( - MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE))]; -static struct os_mempool nrf5340_ble_hci_pool_evt_hi; -static uint8_t nrf5340_ble_hci_pool_evt_lo_buf[OS_MEMPOOL_BYTES( - MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE))]; -static struct os_mempool nrf5340_ble_hci_pool_evt_lo; - -#endif - -/* Pool for ACL data */ -static uint8_t nrf5340_ble_hci_pool_acl_buf[OS_MEMPOOL_BYTES( - MYNEWT_VAL(BLE_ACL_BUF_COUNT), - POOL_ACL_BLOCK_SIZE)]; -static struct os_mempool_ext nrf5340_ble_hci_pool_acl; -static struct os_mbuf_pool nrf5340_ble_hci_pool_acl_mbuf; - -/* Interface to host/ll */ -static struct nrf5340_ble_hci_api nrf5340_ble_hci_api; - -/* State of RX currently in progress (needs to reassemble frame) */ -static struct nrf5340_ble_hci_rx_data nrf5340_ble_hci_rx_data; - -#if !MYNEWT_VAL(BLE_HCI_BRIDGE) -int -ble_hci_trans_reset(void) -{ - /* XXX Should we do something with RF and/or BLE core? */ - return 0; -} -#endif - -#if MYNEWT_VAL(BLE_HCI_BRIDGE) -/* - * TODO: Remove/fix functions ble_ll_data_buffer_overflow() ble_ll_hw_error() - * Following two functions are added to allowed build of HCI bridge configurations. - * Those functions are only used by UART transport, in RAM transport configuration - * they can be called directly in bridge mode controller code is on other core - * and those can't be called. - */ -void -ble_ll_data_buffer_overflow(void) -{ - -} - -void -ble_ll_hw_error(uint8_t err) -{ - (void)err; -} -#endif +static struct hci_h4_sm hci_nrf5340_h4sm; static int -ble_hci_trans_acl_tx(struct os_mbuf *om) +nrf5340_ble_hci_acl_tx(struct os_mbuf *om) { - uint8_t ind = HCI_PKT_ACL; + uint8_t ind = HCI_H4_ACL; struct os_mbuf *x; int rc; @@ -168,25 +59,66 @@ ble_hci_trans_acl_tx(struct os_mbuf *om) return (rc < 0) ? BLE_ERR_MEM_CAPACITY : 0; } -static void nrf5340_ble_hci_trans_rx(int channel, void *user_data); +static int +nrf5340_ble_hci_frame_cb(uint8_t pkt_type, void *data) +{ + int rc; + switch (pkt_type) { #if MYNEWT_VAL(BLE_CONTROLLER) -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) + case HCI_H4_CMD: + rc = ble_transport_to_ll_cmd(data); + break; +#endif + case HCI_H4_ACL: +#if MYNEWT_VAL(BLE_CONTROLLER) + rc = ble_transport_to_ll_acl(data); +#else + rc = ble_transport_to_hs_acl(data); +#endif + break; +#if !MYNEWT_VAL(BLE_CONTROLLER) + case HCI_H4_EVT: + rc = ble_transport_to_hs_evt(data); + break; +#endif + default: + assert(0); + break; + } + + return rc; +} + +static void +nrf5340_ble_hci_trans_rx(int channel, void *user_data) +{ + uint8_t byte; + int rlen; + + while (ipc_nrf5340_available(channel) > 0) { + rlen = ipc_nrf5340_read(channel, &byte, 1); + assert(rlen == 1); + + rlen = hci_h4_sm_rx(&hci_nrf5340_h4sm, &byte, 1); + assert(rlen == 1); + } +} + +static void +nrf5340_ble_hci_init(void) { - nrf5340_ble_hci_api.cmd_cb = cmd_cb; - nrf5340_ble_hci_api.cmd_arg = cmd_arg; - nrf5340_ble_hci_api.acl_cb = acl_cb; - nrf5340_ble_hci_api.acl_arg = acl_arg; + SYSINIT_ASSERT_ACTIVE(); ipc_nrf5340_recv(IPC_RX_CHANNEL, nrf5340_ble_hci_trans_rx, NULL); } +#if MYNEWT_VAL(BLE_CONTROLLER) int -ble_hci_trans_ll_evt_tx(uint8_t *hci_ev) +ble_transport_to_hs_evt(void *buf) { - uint8_t ind = HCI_PKT_EVT; + uint8_t ind = HCI_H4_EVT; + uint8_t* hci_ev = buf; int len = 2 + hci_ev[1]; int rc; @@ -195,35 +127,32 @@ ble_hci_trans_ll_evt_tx(uint8_t *hci_ev) rc = ipc_nrf5340_send(IPC_TX_CHANNEL, hci_ev, len); } - ble_hci_trans_buf_free(hci_ev); + ble_transport_free(buf); return (rc < 0) ? BLE_ERR_MEM_CAPACITY : 0; } int -ble_hci_trans_ll_acl_tx(struct os_mbuf *om) +ble_transport_to_hs_acl(struct os_mbuf *om) { - return ble_hci_trans_acl_tx(om); + return nrf5340_ble_hci_acl_tx(om); } -#endif -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) void -ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *evt_cb, void *evt_arg, - ble_hci_trans_rx_acl_fn *acl_cb, void *acl_arg) +ble_transport_hs_init(void) { - nrf5340_ble_hci_api.evt_cb = evt_cb; - nrf5340_ble_hci_api.evt_arg = evt_arg; - nrf5340_ble_hci_api.acl_cb = acl_cb; - nrf5340_ble_hci_api.acl_arg = acl_arg; - - ipc_nrf5340_recv(IPC_RX_CHANNEL, nrf5340_ble_hci_trans_rx, NULL); + hci_h4_sm_init(&hci_nrf5340_h4sm, &hci_h4_allocs_from_hs, + nrf5340_ble_hci_frame_cb); + nrf5340_ble_hci_init(); } +#endif /* BLE_CONTROLLER */ +#if !MYNEWT_VAL(BLE_CONTROLLER) int -ble_hci_trans_hs_cmd_tx(uint8_t *cmd) +ble_transport_to_ll_cmd(void *buf) { - uint8_t ind = HCI_PKT_CMD; + uint8_t ind = HCI_H4_CMD; + uint8_t *cmd = buf; int len = 3 + cmd[2]; int rc; @@ -232,289 +161,22 @@ ble_hci_trans_hs_cmd_tx(uint8_t *cmd) rc = ipc_nrf5340_send(IPC_TX_CHANNEL, cmd, len); } - ble_hci_trans_buf_free(cmd); + ble_transport_free(buf); return (rc < 0) ? BLE_ERR_MEM_CAPACITY : 0; } int -ble_hci_trans_hs_acl_tx(struct os_mbuf *om) +ble_transport_to_ll_acl(struct os_mbuf *om) { - return ble_hci_trans_acl_tx(om); -} -#endif - -#if !MYNEWT_VAL(BLE_HCI_BRIDGE) -uint8_t * -ble_hci_trans_buf_alloc(int type) -{ - uint8_t *buf; - - switch (type) { - case BLE_HCI_TRANS_BUF_CMD: - buf = os_memblock_get(&nrf5340_ble_hci_pool_cmd_mempool); - break; - case BLE_HCI_TRANS_BUF_EVT_HI: - buf = os_memblock_get(&nrf5340_ble_hci_pool_evt_hi); - if (buf) { - break; - } - /* no break */ - case BLE_HCI_TRANS_BUF_EVT_LO: - buf = os_memblock_get(&nrf5340_ble_hci_pool_evt_lo); - break; - default: - assert(0); - buf = NULL; - } - - return buf; + return nrf5340_ble_hci_acl_tx(om); } void -ble_hci_trans_buf_free(uint8_t *buf) -{ - int rc; - - if (os_memblock_from(&nrf5340_ble_hci_pool_cmd_mempool, buf)) { - rc = os_memblock_put(&nrf5340_ble_hci_pool_cmd_mempool, buf); - assert(rc == 0); - } else if (os_memblock_from(&nrf5340_ble_hci_pool_evt_hi, buf)) { - rc = os_memblock_put(&nrf5340_ble_hci_pool_evt_hi, buf); - assert(rc == 0); - } else { - assert(os_memblock_from(&nrf5340_ble_hci_pool_evt_lo, buf)); - rc = os_memblock_put(&nrf5340_ble_hci_pool_evt_lo, buf); - assert(rc == 0); - } -} -#endif - -static void -nrf5340_ble_hci_trans_rx_process(int channel) +ble_transport_ll_init(void) { - struct nrf5340_ble_hci_rx_data *rxd = &nrf5340_ble_hci_rx_data; -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) - int pool = BLE_HCI_TRANS_BUF_EVT_HI; -#endif - int rc; - - switch (rxd->type) { - case HCI_PKT_NONE: - ipc_nrf5340_read(channel, &rxd->type, 1); - rxd->len = 0; - rxd->expected_len = 0; - -#if MYNEWT_VAL(BLE_CONTROLLER) - assert((rxd->type == HCI_PKT_ACL) || (rxd->type == HCI_PKT_CMD)); -#endif -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) - assert((rxd->type == HCI_PKT_ACL) || (rxd->type == HCI_PKT_EVT)); -#endif - break; -#if MYNEWT_VAL(BLE_CONTROLLER) - case HCI_PKT_CMD: - /* header */ - if (rxd->len < 3) { - rxd->len += ipc_nrf5340_read(channel, &rxd->hdr[rxd->len], - 3 - rxd->len); - if (rxd->len < 3) { - break; - } - } - - if (rxd->expected_len == 0) { - rxd->buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - memcpy(rxd->buf, rxd->hdr, rxd->len); - - rxd->expected_len = 3 + rxd->hdr[2]; - } - - if (rxd->len < rxd->expected_len) { - rxd->len += ipc_nrf5340_read(channel, &rxd->buf[rxd->len], - rxd->expected_len - rxd->len); - if (rxd->len < rxd->expected_len) { - break; - } - } - - rc = nrf5340_ble_hci_api.cmd_cb(rxd->buf, nrf5340_ble_hci_api.cmd_arg); - if (rc != 0) { - ble_hci_trans_buf_free(rxd->buf); - } - - rxd->type = HCI_PKT_NONE; - break; -#endif -#if MYNEWT_VAL(BLE_HOST) || MYNEWT_VAL(BLE_HCI_BRIDGE) - case HCI_PKT_EVT: - /* header */ - if (rxd->len < 2) { - rxd->len += ipc_nrf5340_read(channel, &rxd->hdr[rxd->len], - 2 - rxd->len); - if (rxd->len < 2) { - break; - } - } - - if (rxd->hdr[0] == BLE_HCI_EVCODE_LE_META) { - if (rxd->len < 3) { - /* For LE Meta event we need 3 bytes to parse header */ - rxd->len += ipc_nrf5340_read(channel, &rxd->hdr[rxd->len], 1); - if (rxd->len < 3) { - break; - } - } - - /* Advertising reports shall be allocated from low-prio pool */ - if ((rxd->hdr[2] == BLE_HCI_LE_SUBEV_ADV_RPT) || - (rxd->hdr[2] == BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) { - pool = BLE_HCI_TRANS_BUF_EVT_LO; - } - } - - if (rxd->expected_len == 0) { - rxd->buf = ble_hci_trans_buf_alloc(pool); - if (!rxd->buf) { - /* - * Only care about valid buffer when shall be allocated from - * high-prio pool, otherwise NULL is fine and we'll just skip - * this event. - */ - if (pool != BLE_HCI_TRANS_BUF_EVT_LO) { - rxd->buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); - } - } - - rxd->expected_len = 2 + rxd->hdr[1]; - - /* copy header */ - if (rxd->buf) { - memcpy(rxd->buf, rxd->hdr, rxd->len); - } - } - - if (rxd->buf) { - rxd->len += ipc_nrf5340_read(channel, &rxd->buf[rxd->len], - rxd->expected_len - rxd->len); - if (rxd->len < rxd->expected_len) { - break; - } - - rc = nrf5340_ble_hci_api.evt_cb(rxd->buf, - nrf5340_ble_hci_api.evt_arg); - if (rc != 0) { - ble_hci_trans_buf_free(rxd->buf); - } - } else { - rxd->len += ipc_nrf5340_consume(channel, - rxd->expected_len - rxd->len); - if (rxd->len < rxd->expected_len) { - break; - } - } - - rxd->type = HCI_PKT_NONE; - break; -#endif - case HCI_PKT_ACL: - if (rxd->len < 4) { - rxd->len += ipc_nrf5340_read(channel, &rxd->hdr[rxd->len], - 4 - rxd->len); - if (rxd->len < 4) { - break; - } - } - - /* Parse header and allocate proper buffer if not done yet */ - if (rxd->expected_len == 0) { - rxd->om = os_mbuf_get_pkthdr(&nrf5340_ble_hci_pool_acl_mbuf, - sizeof(struct ble_mbuf_hdr)); - if (!rxd->om) { - /* TODO not much we can do here... */ - assert(0); - } - - os_mbuf_append(rxd->om, rxd->hdr, rxd->len); - rxd->expected_len = get_le16(&rxd->hdr[2]) + 4; - } - - if (rxd->len != rxd->expected_len) { - rxd->len += ipc_nrf5340_read_om(channel, rxd->om, - rxd->expected_len - rxd->len); - } - - if (rxd->len == rxd->expected_len) { - rc = nrf5340_ble_hci_api.acl_cb(rxd->om, - nrf5340_ble_hci_api.acl_arg); - if (rc != 0) { - os_mbuf_free_chain(rxd->om); - } - rxd->type = HCI_PKT_NONE; - } - break; - default: - assert(0); - break; - } -} - -static void -nrf5340_ble_hci_trans_rx(int channel, void *user_data) -{ - while (ipc_nrf5340_available(channel) > 0) { - nrf5340_ble_hci_trans_rx_process(channel); - } -} - -#if !MYNEWT_VAL(BLE_HCI_BRIDGE) -int -ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg) -{ - nrf5340_ble_hci_pool_acl.mpe_put_cb = cb; - nrf5340_ble_hci_pool_acl.mpe_put_arg = arg; - - return 0; -} -#endif - -void -nrf5340_ble_hci_init(void) -{ - int rc; - - SYSINIT_ASSERT_ACTIVE(); - - rc = os_mempool_ext_init(&nrf5340_ble_hci_pool_acl, - MYNEWT_VAL(BLE_ACL_BUF_COUNT), POOL_ACL_BLOCK_SIZE, - nrf5340_ble_hci_pool_acl_buf, - "nrf5340_ble_hci_pool_acl"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mbuf_pool_init(&nrf5340_ble_hci_pool_acl_mbuf, - &nrf5340_ble_hci_pool_acl.mpe_mp, POOL_ACL_BLOCK_SIZE, - MYNEWT_VAL(BLE_ACL_BUF_COUNT)); - SYSINIT_PANIC_ASSERT(rc == 0); - -#if !MYNEWT_VAL(BLE_HCI_BRIDGE) - rc = os_mempool_init(&nrf5340_ble_hci_pool_evt_hi, - MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - nrf5340_ble_hci_pool_evt_hi_buf, - "nrf5340_ble_hci_pool_evt_hi"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&nrf5340_ble_hci_pool_evt_lo, - MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - nrf5340_ble_hci_pool_evt_lo_buf, - "nrf5340_ble_hci_pool_evt_lo"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&nrf5340_ble_hci_pool_cmd_mempool, - HCI_CMD_COUNT, BLE_HCI_TRANS_CMD_SZ, - nrf5340_ble_hci_pool_cmd_mempool_buf, - "nrf5340_ble_hci_pool_cmd_mempool"); - SYSINIT_PANIC_ASSERT(rc == 0); -#endif + hci_h4_sm_init(&hci_nrf5340_h4sm, &hci_h4_allocs_from_ll, + nrf5340_ble_hci_frame_cb); + nrf5340_ble_hci_init(); } +#endif /* !BLE_CONTROLLER */ From aefb9d4a90effefc77500e8968eafd3f336c7d06 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 3 Mar 2022 18:06:04 +0100 Subject: [PATCH 0337/1333] nimble/transport: Update UART transport --- .../include/transport/uart/ble_hci_uart.h | 33 - nimble/transport/uart/pkg.yml | 11 +- nimble/transport/uart/src/ble_hci_uart.c | 1187 ----------------- nimble/transport/uart/src/hci_uart.c | 247 ++++ nimble/transport/uart/syscfg.yml | 62 +- 5 files changed, 270 insertions(+), 1270 deletions(-) delete mode 100644 nimble/transport/uart/include/transport/uart/ble_hci_uart.h delete mode 100644 nimble/transport/uart/src/ble_hci_uart.c create mode 100644 nimble/transport/uart/src/hci_uart.c diff --git a/nimble/transport/uart/include/transport/uart/ble_hci_uart.h b/nimble/transport/uart/include/transport/uart/ble_hci_uart.h deleted file mode 100644 index e5e1084107..0000000000 --- a/nimble/transport/uart/include/transport/uart/ble_hci_uart.h +++ /dev/null @@ -1,33 +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_BLE_HCI_UART_ -#define H_BLE_HCI_UART_ - -#ifdef __cplusplus -extern "C" { -#endif - -void ble_hci_uart_init(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/nimble/transport/uart/pkg.yml b/nimble/transport/uart/pkg.yml index fd16a083a8..2802961d90 100644 --- a/nimble/transport/uart/pkg.yml +++ b/nimble/transport/uart/pkg.yml @@ -18,20 +18,15 @@ # pkg.name: nimble/transport/uart -pkg.description: XXX +pkg.description: HCI H4 transport over UART pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth +pkg.homepage: "https://mynewt.apache.org/" pkg.deps: - "@apache-mynewt-core/hw/hal" - "@apache-mynewt-core/kernel/os" - nimble + - nimble/transport/common/hci_h4 pkg.apis: - ble_transport - -pkg.init: - ble_hci_uart_init: 'MYNEWT_VAL(BLE_TRANS_UART_SYSINIT_STAGE)' diff --git a/nimble/transport/uart/src/ble_hci_uart.c b/nimble/transport/uart/src/ble_hci_uart.c deleted file mode 100644 index 0b6e0e5ecc..0000000000 --- a/nimble/transport/uart/src/ble_hci_uart.c +++ /dev/null @@ -1,1187 +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. - */ - -#include -#include -#include -#include -#include -#include "sysinit/sysinit.h" -#include "syscfg/syscfg.h" -#include "os/os_cputime.h" -#include "bsp/bsp.h" -#include "os/os.h" -#include "hal/hal_uart.h" - -/* BLE */ -#include "nimble/ble.h" -#include "nimble/nimble_opt.h" -#include "nimble/hci_common.h" -#include "nimble/ble_hci_trans.h" - -#include "transport/uart/ble_hci_uart.h" - -#define BLE_HCI_UART_EVT_COUNT \ - (MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT) + MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT)) - -/*** - * NOTES: - * The UART HCI transport doesn't use event buffer priorities. All incoming - * and outgoing events use buffers from the same pool. - * - * The "skip" definitions are here so that when buffers cannot be allocated, - * the command or acl packets are simply skipped so that the HCI interface - * does not lose synchronization and resets dont (necessarily) occur. - */ - -/* XXX: for now, define this here */ -#if MYNEWT_VAL(BLE_CONTROLLER) || MYNEWT_VAL(BLE_HCI_BRIDGE) -extern void ble_ll_data_buffer_overflow(void); -extern void ble_ll_hw_error(void); - -static const uint8_t ble_hci_uart_reset_cmd[4] = { 0x01, 0x03, 0x0C, 0x00 }; -#endif - -/*** - * NOTES: - * The "skip" definitions are here so that when buffers cannot be allocated, - * the command or acl packets are simply skipped so that the HCI interface - * does not lose synchronization and resets dont (necessarily) occur. - */ -#define BLE_HCI_UART_H4_NONE 0x00 -#define BLE_HCI_UART_H4_CMD 0x01 -#define BLE_HCI_UART_H4_ACL 0x02 -#define BLE_HCI_UART_H4_SCO 0x03 -#define BLE_HCI_UART_H4_EVT 0x04 -#define BLE_HCI_UART_H4_SYNC_LOSS 0x80 -#define BLE_HCI_UART_H4_SKIP_CMD 0x81 -#define BLE_HCI_UART_H4_SKIP_ACL 0x82 -#define BLE_HCI_UART_H4_LE_EVT 0x83 -#define BLE_HCI_UART_H4_SKIP_EVT 0x84 - -static ble_hci_trans_rx_cmd_fn *ble_hci_uart_rx_cmd_cb; -static void *ble_hci_uart_rx_cmd_arg; - -static ble_hci_trans_rx_acl_fn *ble_hci_uart_rx_acl_cb; -static void *ble_hci_uart_rx_acl_arg; - -static struct os_mempool ble_hci_uart_evt_hi_pool; -static os_membuf_t ble_hci_uart_evt_hi_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) -]; - -static struct os_mempool ble_hci_uart_evt_lo_pool; -static os_membuf_t ble_hci_uart_evt_lo_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) -]; - -static struct os_mempool ble_hci_uart_cmd_pool; -static os_membuf_t ble_hci_uart_cmd_buf[ - OS_MEMPOOL_SIZE(1, BLE_HCI_TRANS_CMD_SZ) -]; - -static struct os_mbuf_pool ble_hci_uart_acl_mbuf_pool; -static struct os_mempool_ext ble_hci_uart_acl_pool; - -/* - * The MBUF payload size must accommodate the HCI data header size plus the - * maximum ACL data packet length. The ACL block size is the size of the - * mbufs we will allocate. - */ -#define ACL_BLOCK_SIZE OS_ALIGN(MYNEWT_VAL(BLE_ACL_BUF_SIZE) \ - + BLE_MBUF_MEMBLOCK_OVERHEAD \ - + BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT) - -static os_membuf_t ble_hci_uart_acl_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ACL_BUF_COUNT), - ACL_BLOCK_SIZE) -]; - -/** - * A packet to be sent over the UART. This can be a command, an event, or ACL - * data. - */ -struct ble_hci_uart_pkt { - STAILQ_ENTRY(ble_hci_uart_pkt) next; - void *data; - uint8_t type; -}; - -static struct os_mempool ble_hci_uart_pkt_pool; -static os_membuf_t ble_hci_uart_pkt_buf[ - OS_MEMPOOL_SIZE(BLE_HCI_UART_EVT_COUNT + 1 + - MYNEWT_VAL(BLE_HCI_ACL_OUT_COUNT), - sizeof (struct ble_hci_uart_pkt)) -]; - -/** - * An incoming or outgoing command or event. - */ -struct ble_hci_uart_cmd { - uint8_t *data; /* Pointer to ble_hci_uart_cmd data */ - uint16_t cur; /* Number of bytes read/written */ - uint16_t len; /* Total number of bytes to read/write */ -}; - -/** - * An incoming ACL data packet. - */ -struct ble_hci_uart_acl { - struct os_mbuf *buf; /* Buffer containing the data */ - uint8_t *dptr; /* Pointer to where bytes should be placed */ - uint16_t len; /* Target size when buf is considered complete */ - uint16_t rxd_bytes; /* current count of bytes received for packet */ -}; - -/** - * Structure for transmitting ACL packets over UART - * - */ -struct ble_hci_uart_h4_acl_tx -{ - uint8_t *dptr; - struct os_mbuf *tx_acl; -}; - -static struct { - /*** State of data received over UART. */ - uint8_t rx_type; /* Pending packet type. 0 means nothing pending */ - union { - struct ble_hci_uart_cmd rx_cmd; - struct ble_hci_uart_acl rx_acl; - }; - - /*** State of data transmitted over UART. */ - uint8_t tx_type; /* Pending packet type. 0 means nothing pending */ - uint16_t rem_tx_len; /* Used for acl tx only currently */ - union { - struct ble_hci_uart_cmd tx_cmd; - struct ble_hci_uart_h4_acl_tx tx_pkt; - }; - STAILQ_HEAD(, ble_hci_uart_pkt) tx_pkts; /* Packet queue to send to UART */ -} ble_hci_uart_state; - -/** - * Allocates a buffer (mbuf) for ACL operation. - * - * @return The allocated buffer on success; - * NULL on buffer exhaustion. - */ -static struct os_mbuf * -ble_hci_trans_acl_buf_alloc(void) -{ - struct os_mbuf *m; - uint8_t usrhdr_len; - -#if MYNEWT_VAL(BLE_CONTROLLER) - usrhdr_len = sizeof(struct ble_mbuf_hdr); -#else - usrhdr_len = 0; -#endif - - m = os_mbuf_get_pkthdr(&ble_hci_uart_acl_mbuf_pool, usrhdr_len); - return m; -} - -static int -ble_hci_uart_acl_tx(struct os_mbuf *om) -{ - struct ble_hci_uart_pkt *pkt; - os_sr_t sr; - - /* If this packet is zero length, just free it */ - if (OS_MBUF_PKTLEN(om) == 0) { - os_mbuf_free_chain(om); - return 0; - } - - pkt = os_memblock_get(&ble_hci_uart_pkt_pool); - if (pkt == NULL) { - os_mbuf_free_chain(om); - return BLE_ERR_MEM_CAPACITY; - } - - pkt->type = BLE_HCI_UART_H4_ACL; - pkt->data = om; - - OS_ENTER_CRITICAL(sr); - STAILQ_INSERT_TAIL(&ble_hci_uart_state.tx_pkts, pkt, next); - OS_EXIT_CRITICAL(sr); - - hal_uart_start_tx(MYNEWT_VAL(BLE_HCI_UART_PORT)); - - return 0; -} - -static int -ble_hci_uart_cmdevt_tx(uint8_t *hci_ev, uint8_t h4_type) -{ - struct ble_hci_uart_pkt *pkt; - os_sr_t sr; - - pkt = os_memblock_get(&ble_hci_uart_pkt_pool); - if (pkt == NULL) { - ble_hci_trans_buf_free(hci_ev); - return BLE_ERR_MEM_CAPACITY; - } - - pkt->type = h4_type; - pkt->data = hci_ev; - - OS_ENTER_CRITICAL(sr); - STAILQ_INSERT_TAIL(&ble_hci_uart_state.tx_pkts, pkt, next); - OS_EXIT_CRITICAL(sr); - - hal_uart_start_tx(MYNEWT_VAL(BLE_HCI_UART_PORT)); - - return 0; -} - -/** - * @return The packet type to transmit on success; - * -1 if there is nothing to send. - */ -static int -ble_hci_uart_tx_pkt_type(void) -{ - struct ble_hci_uart_pkt *pkt; - struct os_mbuf *om; - os_sr_t sr; - int rc; - - OS_ENTER_CRITICAL(sr); - - pkt = STAILQ_FIRST(&ble_hci_uart_state.tx_pkts); - if (!pkt) { - OS_EXIT_CRITICAL(sr); - return -1; - } - - STAILQ_REMOVE(&ble_hci_uart_state.tx_pkts, pkt, ble_hci_uart_pkt, next); - - OS_EXIT_CRITICAL(sr); - - rc = pkt->type; - switch (pkt->type) { - case BLE_HCI_UART_H4_CMD: - ble_hci_uart_state.tx_type = BLE_HCI_UART_H4_CMD; - ble_hci_uart_state.tx_cmd.data = pkt->data; - ble_hci_uart_state.tx_cmd.cur = 0; - ble_hci_uart_state.tx_cmd.len = ble_hci_uart_state.tx_cmd.data[2] + - sizeof(struct ble_hci_cmd); - break; - - case BLE_HCI_UART_H4_EVT: - ble_hci_uart_state.tx_type = BLE_HCI_UART_H4_EVT; - ble_hci_uart_state.tx_cmd.data = pkt->data; - ble_hci_uart_state.tx_cmd.cur = 0; - ble_hci_uart_state.tx_cmd.len = ble_hci_uart_state.tx_cmd.data[1] + - sizeof(struct ble_hci_ev); - break; - - case BLE_HCI_UART_H4_ACL: - ble_hci_uart_state.tx_type = BLE_HCI_UART_H4_ACL; - om = (struct os_mbuf *)pkt->data; - /* NOTE: first mbuf must have non-zero length */ - os_mbuf_trim_front(om); - ble_hci_uart_state.tx_pkt.tx_acl = om; - ble_hci_uart_state.tx_pkt.dptr = om->om_data; - ble_hci_uart_state.rem_tx_len = OS_MBUF_PKTLEN(om); - break; - - default: - rc = -1; - break; - } - - os_memblock_put(&ble_hci_uart_pkt_pool, pkt); - - return rc; -} - -/** - * @return The byte to transmit on success; - * -1 if there is nothing to send. - */ -static int -ble_hci_uart_tx_char(void *arg) -{ - uint8_t u8; - int rc; - struct os_mbuf *om; - - switch (ble_hci_uart_state.tx_type) { - case BLE_HCI_UART_H4_NONE: /* No pending packet, pick one from the queue */ - rc = ble_hci_uart_tx_pkt_type(); - break; - - case BLE_HCI_UART_H4_CMD: - case BLE_HCI_UART_H4_EVT: - rc = ble_hci_uart_state.tx_cmd.data[ble_hci_uart_state.tx_cmd.cur++]; - - if (ble_hci_uart_state.tx_cmd.cur == ble_hci_uart_state.tx_cmd.len) { - ble_hci_trans_buf_free(ble_hci_uart_state.tx_cmd.data); - ble_hci_uart_state.tx_type = BLE_HCI_UART_H4_NONE; - } - break; - - case BLE_HCI_UART_H4_ACL: - /* Copy the first unsent byte from the tx buffer and remove it from the - * source. - */ - u8 = ble_hci_uart_state.tx_pkt.dptr[0]; - --ble_hci_uart_state.rem_tx_len; - if (ble_hci_uart_state.rem_tx_len == 0) { - os_mbuf_free_chain(ble_hci_uart_state.tx_pkt.tx_acl); - ble_hci_uart_state.tx_type = BLE_HCI_UART_H4_NONE; - } else { - om = ble_hci_uart_state.tx_pkt.tx_acl; - --om->om_len; - if (om->om_len == 0) { - /* Remove and free any zero mbufs */ - while ((om != NULL) && (om->om_len == 0)) { - ble_hci_uart_state.tx_pkt.tx_acl = SLIST_NEXT(om, om_next); - os_mbuf_free(om); - om = ble_hci_uart_state.tx_pkt.tx_acl; - } - /* NOTE: om should never be NULL! What to do? */ - if (om == NULL) { - assert(0); - ble_hci_uart_state.tx_type = BLE_HCI_UART_H4_NONE; - } else { - ble_hci_uart_state.tx_pkt.dptr = om->om_data; - } - } else { - ble_hci_uart_state.tx_pkt.dptr++; - } - } - rc = u8; - break; - default: - rc = -1; - break; - } - - return rc; -} - -#if MYNEWT_VAL(BLE_CONTROLLER) || MYNEWT_VAL(BLE_HCI_BRIDGE) -/** - * HCI uart sync lost. - * - * This occurs when the controller receives an invalid packet type or a length - * field that is out of range. The controller needs to send a HW error to the - * host and wait to find a LL reset command. - */ -static void -ble_hci_uart_sync_lost(void) -{ - ble_hci_uart_state.rx_cmd.len = 0; - ble_hci_uart_state.rx_cmd.cur = 0; - ble_hci_uart_state.rx_cmd.data = - ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - ble_ll_hw_error(); - ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_SYNC_LOSS; -} -#endif - -/** - * @return The type of packet to follow success; - * -1 if there is no valid packet to receive. - */ -static int -ble_hci_uart_rx_pkt_type(uint8_t data) -{ - struct os_mbuf *m; - - ble_hci_uart_state.rx_type = data; - - switch (ble_hci_uart_state.rx_type) { - /* Host should never receive a command! */ -#if MYNEWT_VAL(BLE_CONTROLLER) || MYNEWT_VAL(BLE_HCI_BRIDGE) - case BLE_HCI_UART_H4_CMD: - ble_hci_uart_state.rx_cmd.len = 0; - ble_hci_uart_state.rx_cmd.cur = 0; - ble_hci_uart_state.rx_cmd.data = - ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - if (ble_hci_uart_state.rx_cmd.data == NULL) { - ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_SKIP_CMD; - } - break; -#endif - - /* Controller should never receive an event */ -#if MYNEWT_VAL(BLE_HOST) - case BLE_HCI_UART_H4_EVT: - /* - * The event code is unknown at the moment. Depending on event priority, - * buffer *shall* be allocated from ble_hci_uart_evt_hi_pool - * or "may* be allocated from ble_hci_uart_evt_lo_pool. - * Thus do not allocate the buffer yet. - */ - ble_hci_uart_state.rx_cmd.data = NULL; - ble_hci_uart_state.rx_cmd.len = 0; - ble_hci_uart_state.rx_cmd.cur = 0; - break; -#endif - - case BLE_HCI_UART_H4_ACL: - ble_hci_uart_state.rx_acl.len = 0; - ble_hci_uart_state.rx_acl.rxd_bytes = 0; - m = ble_hci_trans_acl_buf_alloc(); - if (m) { - ble_hci_uart_state.rx_acl.dptr = m->om_data; - } else { - ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_SKIP_ACL; - } - ble_hci_uart_state.rx_acl.buf = m; - break; - - default: -#if MYNEWT_VAL(BLE_CONTROLLER) || MYNEWT_VAL(BLE_HCI_BRIDGE) - /* - * If we receive an unknown HCI packet type this is considered a loss - * of sync. - */ - ble_hci_uart_sync_lost(); -#else - /* - * XXX: not sure what to do about host in this case. Just go back to - * none for now. - */ - ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_NONE; -#endif - break; - } - - return 0; -} - -#if MYNEWT_VAL(BLE_CONTROLLER) || MYNEWT_VAL(BLE_HCI_BRIDGE) -/** - * HCI uart sync loss. - * - * Find a LL reset command in the byte stream. The LL reset command is a - * sequence of 4 bytes: - * 0x01 HCI Packet Type = HCI CMD - * 0x03 OCF for reset command - * 0x0C OGF for reset command (0x03 shifted left by two bits as the OGF - * occupies the uopper 6 bits of this byte. - * 0x00 Parameter length of reset command (no parameters). - * - * @param data Byte received over serial port - */ -void -ble_hci_uart_rx_sync_loss(uint8_t data) -{ - int rc; - int index; - - /* - * If we couldnt allocate a command buffer (should not occur but - * possible) try to allocate one on each received character. If we get - * a reset and buffer is not available we have to ignore reset. - */ - if (ble_hci_uart_state.rx_cmd.data == NULL) { - ble_hci_uart_state.rx_cmd.data = - ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - } - - index = ble_hci_uart_state.rx_cmd.cur; - if (data == ble_hci_uart_reset_cmd[index]) { - if (index == 3) { - if (ble_hci_uart_state.rx_cmd.data == NULL) { - index = 0; - } else { - assert(ble_hci_uart_rx_cmd_cb != NULL); - ble_hci_uart_state.rx_cmd.data[0] = 0x03; - ble_hci_uart_state.rx_cmd.data[1] = 0x0C; - ble_hci_uart_state.rx_cmd.data[2] = 0x00; - rc = ble_hci_uart_rx_cmd_cb(ble_hci_uart_state.rx_cmd.data, - ble_hci_uart_rx_cmd_arg); - if (rc != 0) { - ble_hci_trans_buf_free(ble_hci_uart_state.rx_cmd.data); - } - ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_NONE; - } - } else { - ++index; - } - } else { - index = 0; - } - - ble_hci_uart_state.rx_cmd.cur = index; -} - -static void -ble_hci_uart_rx_cmd(uint8_t data) -{ - int rc; - - ble_hci_uart_state.rx_cmd.data[ble_hci_uart_state.rx_cmd.cur++] = data; - - if (ble_hci_uart_state.rx_cmd.cur < sizeof(struct ble_hci_cmd)) { - return; - } - - if (ble_hci_uart_state.rx_cmd.cur == sizeof(struct ble_hci_cmd)) { - ble_hci_uart_state.rx_cmd.len = ble_hci_uart_state.rx_cmd.data[2] + - sizeof(struct ble_hci_cmd); - } - - if (ble_hci_uart_state.rx_cmd.cur == ble_hci_uart_state.rx_cmd.len) { - assert(ble_hci_uart_rx_cmd_cb != NULL); - rc = ble_hci_uart_rx_cmd_cb(ble_hci_uart_state.rx_cmd.data, - ble_hci_uart_rx_cmd_arg); - if (rc != 0) { - ble_hci_trans_buf_free(ble_hci_uart_state.rx_cmd.data); - } - ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_NONE; - } -} - -static void -ble_hci_uart_rx_skip_cmd(uint8_t data) -{ - ble_hci_uart_state.rx_cmd.cur++; - - if (ble_hci_uart_state.rx_cmd.cur < sizeof(struct ble_hci_cmd)) { - return; - } - - if (ble_hci_uart_state.rx_cmd.cur == sizeof(struct ble_hci_cmd)) { - ble_hci_uart_state.rx_cmd.len = data + sizeof(struct ble_hci_cmd); - } - - if (ble_hci_uart_state.rx_cmd.cur == ble_hci_uart_state.rx_cmd.len) { - /* - * XXX: for now we simply skip the command and do nothing. This - * should not happen but at least we retain HCI synch. The host - * can decide what to do in this case. It may be appropriate for - * the controller to attempt to send back a command complete or - * command status in this case. - */ - ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_NONE; - } -} -#endif - -#if MYNEWT_VAL(BLE_HOST) -static inline void -ble_hci_uart_rx_evt_cb(void) -{ - int rc; - - if (ble_hci_uart_state.rx_cmd.cur == ble_hci_uart_state.rx_cmd.len) { - assert(ble_hci_uart_rx_cmd_cb != NULL); - rc = ble_hci_uart_rx_cmd_cb(ble_hci_uart_state.rx_cmd.data, - ble_hci_uart_rx_cmd_arg); - if (rc != 0) { - ble_hci_trans_buf_free(ble_hci_uart_state.rx_cmd.data); - } - ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_NONE; - } -} - -static void -ble_hci_uart_rx_evt(uint8_t data) -{ - /* Determine event priority to allocate buffer */ - if (!ble_hci_uart_state.rx_cmd.data) { - /* In case of LE Meta Event priority might be still unknown */ - if (data == BLE_HCI_EVCODE_LE_META) { - ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_LE_EVT; - ble_hci_uart_state.rx_cmd.cur++; - return; - } - - ble_hci_uart_state.rx_cmd.data = - ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); - assert(ble_hci_uart_state.rx_cmd.data != NULL); - } - - ble_hci_uart_state.rx_cmd.data[ble_hci_uart_state.rx_cmd.cur++] = data; - - if (ble_hci_uart_state.rx_cmd.cur < sizeof(struct ble_hci_ev)) { - return; - } - - if (ble_hci_uart_state.rx_cmd.cur == sizeof(struct ble_hci_ev)) { - ble_hci_uart_state.rx_cmd.len = ble_hci_uart_state.rx_cmd.data[1] + - sizeof(struct ble_hci_ev); - } - - ble_hci_uart_rx_evt_cb(); -} - -static void -ble_hci_uart_rx_le_evt(uint8_t data) -{ - ble_hci_uart_state.rx_cmd.cur++; - - if (ble_hci_uart_state.rx_cmd.cur == sizeof(struct ble_hci_ev)) { - /* LE Meta Event parameter length is never 0 */ - assert(data != 0); - ble_hci_uart_state.rx_cmd.len = data + sizeof(struct ble_hci_ev); - return; - } - - /* Determine event priority to allocate buffer */ - if (!ble_hci_uart_state.rx_cmd.data) { - /* Determine event priority to allocate buffer */ - if (data == BLE_HCI_LE_SUBEV_ADV_RPT || - data == BLE_HCI_LE_SUBEV_EXT_ADV_RPT) { - ble_hci_uart_state.rx_cmd.data = - ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); - if (ble_hci_uart_state.rx_cmd.data == NULL) { - ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_SKIP_EVT; - return; - } - } else { - ble_hci_uart_state.rx_cmd.data = - ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); - assert(ble_hci_uart_state.rx_cmd.data != NULL); - } - - ble_hci_uart_state.rx_cmd.data[0] = BLE_HCI_EVCODE_LE_META; - ble_hci_uart_state.rx_cmd.data[1] = - ble_hci_uart_state.rx_cmd.len - sizeof(struct ble_hci_ev); - } - - ble_hci_uart_state.rx_cmd.data[ble_hci_uart_state.rx_cmd.cur - 1] = data; - ble_hci_uart_rx_evt_cb(); -} - -static void -ble_hci_uart_rx_skip_evt(uint8_t data) -{ - if (++ble_hci_uart_state.rx_cmd.cur == ble_hci_uart_state.rx_cmd.len) { - ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_NONE; - } -} -#endif - -static void -ble_hci_uart_rx_acl(uint8_t data) -{ - uint16_t rxd_bytes; - uint16_t pktlen; - - rxd_bytes = ble_hci_uart_state.rx_acl.rxd_bytes; - ble_hci_uart_state.rx_acl.dptr[rxd_bytes] = data; - ++rxd_bytes; - ble_hci_uart_state.rx_acl.rxd_bytes = rxd_bytes; - - if (rxd_bytes < BLE_HCI_DATA_HDR_SZ) { - return; - } - - if (rxd_bytes == BLE_HCI_DATA_HDR_SZ) { - pktlen = ble_hci_uart_state.rx_acl.dptr[3]; - pktlen = (pktlen << 8) + ble_hci_uart_state.rx_acl.dptr[2]; - ble_hci_uart_state.rx_acl.len = pktlen + BLE_HCI_DATA_HDR_SZ; - - /* - * Data portion cannot exceed data length of acl buffer. If it does - * this is considered to be a loss of sync. - */ - if (pktlen > MYNEWT_VAL(BLE_ACL_BUF_SIZE)) { - os_mbuf_free_chain(ble_hci_uart_state.rx_acl.buf); -#if MYNEWT_VAL(BLE_CONTROLLER) || MYNEWT_VAL(BLE_HCI_BRIDGE) - ble_hci_uart_sync_lost(); -#else - /* - * XXX: not sure what to do about host in this case. Just go back to - * none for now. - */ - ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_NONE; -#endif - } - } - - if (rxd_bytes == ble_hci_uart_state.rx_acl.len) { - assert(ble_hci_uart_rx_acl_cb != NULL); - /* XXX: can this callback fail? What if it does? */ - OS_MBUF_PKTLEN(ble_hci_uart_state.rx_acl.buf) = rxd_bytes; - ble_hci_uart_state.rx_acl.buf->om_len = rxd_bytes; - ble_hci_uart_rx_acl_cb(ble_hci_uart_state.rx_acl.buf, - ble_hci_uart_rx_acl_arg); - ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_NONE; - } -} - -static void -ble_hci_uart_rx_skip_acl(uint8_t data) -{ - uint16_t rxd_bytes; - uint16_t pktlen; - - rxd_bytes = ble_hci_uart_state.rx_acl.rxd_bytes; - ++rxd_bytes; - ble_hci_uart_state.rx_acl.rxd_bytes = rxd_bytes; - - if (rxd_bytes == (BLE_HCI_DATA_HDR_SZ - 1)) { - ble_hci_uart_state.rx_acl.len = data; - return; - } - - if (rxd_bytes == BLE_HCI_DATA_HDR_SZ) { - pktlen = data; - pktlen = (pktlen << 8) + ble_hci_uart_state.rx_acl.len; - ble_hci_uart_state.rx_acl.len = pktlen + BLE_HCI_DATA_HDR_SZ; - } - - if (rxd_bytes == ble_hci_uart_state.rx_acl.len) { -/* XXX: I dont like this but for now this denotes controller only */ -#if MYNEWT_VAL(BLE_CONTROLLER) -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - ble_ll_data_buffer_overflow(); -#endif -#endif - ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_NONE; - } -} - -static int -ble_hci_uart_rx_char(void *arg, uint8_t data) -{ - switch (ble_hci_uart_state.rx_type) { - case BLE_HCI_UART_H4_NONE: - return ble_hci_uart_rx_pkt_type(data); -#if MYNEWT_VAL(BLE_CONTROLLER) || MYNEWT_VAL(BLE_HCI_BRIDGE) - case BLE_HCI_UART_H4_CMD: - ble_hci_uart_rx_cmd(data); - return 0; - case BLE_HCI_UART_H4_SKIP_CMD: - ble_hci_uart_rx_skip_cmd(data); - return 0; - case BLE_HCI_UART_H4_SYNC_LOSS: - ble_hci_uart_rx_sync_loss(data); - return 0; -#endif -#if MYNEWT_VAL(BLE_HOST) - case BLE_HCI_UART_H4_EVT: - ble_hci_uart_rx_evt(data); - return 0; - case BLE_HCI_UART_H4_LE_EVT: - ble_hci_uart_rx_le_evt(data); - return 0; - case BLE_HCI_UART_H4_SKIP_EVT: - ble_hci_uart_rx_skip_evt(data); - return 0; -#endif - case BLE_HCI_UART_H4_ACL: - ble_hci_uart_rx_acl(data); - return 0; - case BLE_HCI_UART_H4_SKIP_ACL: - ble_hci_uart_rx_skip_acl(data); - return 0; - default: - /* This should never happen! */ - assert(0); - return 0; - } -} - -static void -ble_hci_uart_set_rx_cbs(ble_hci_trans_rx_cmd_fn *cmd_cb, - void *cmd_arg, - ble_hci_trans_rx_acl_fn *acl_cb, - void *acl_arg) -{ - ble_hci_uart_rx_cmd_cb = cmd_cb; - ble_hci_uart_rx_cmd_arg = cmd_arg; - ble_hci_uart_rx_acl_cb = acl_cb; - ble_hci_uart_rx_acl_arg = acl_arg; -} - -static void -ble_hci_uart_free_pkt(uint8_t type, uint8_t *cmdevt, struct os_mbuf *acl) -{ - switch (type) { - case BLE_HCI_UART_H4_NONE: - break; - - case BLE_HCI_UART_H4_CMD: - case BLE_HCI_UART_H4_EVT: - ble_hci_trans_buf_free(cmdevt); - break; - - case BLE_HCI_UART_H4_ACL: - os_mbuf_free_chain(acl); - break; - - default: - assert(0); - break; - } -} - -static int -ble_hci_uart_config(void) -{ - int rc; - - rc = hal_uart_init_cbs(MYNEWT_VAL(BLE_HCI_UART_PORT), - ble_hci_uart_tx_char, NULL, - ble_hci_uart_rx_char, NULL); - if (rc != 0) { - return BLE_ERR_UNSPECIFIED; - } - - rc = hal_uart_config(MYNEWT_VAL(BLE_HCI_UART_PORT), - MYNEWT_VAL(BLE_HCI_UART_BAUD), - MYNEWT_VAL(BLE_HCI_UART_DATA_BITS), - MYNEWT_VAL(BLE_HCI_UART_STOP_BITS), - MYNEWT_VAL(BLE_HCI_UART_PARITY), - MYNEWT_VAL(BLE_HCI_UART_FLOW_CTRL)); - if (rc != 0) { - return BLE_ERR_HW_FAIL; - } - - return 0; -} - -/** - * 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 *cmd) -{ - int rc; - - rc = ble_hci_uart_cmdevt_tx(cmd, BLE_HCI_UART_H4_EVT); - return rc; -} - -/** - * 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) -{ - int rc; - - rc = ble_hci_uart_acl_tx(om); - return rc; -} - -#if MYNEWT_VAL(BLE_HOST) -/** - * 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) -{ - int rc; - - rc = ble_hci_uart_cmdevt_tx(cmd, BLE_HCI_UART_H4_CMD); - return rc; -} - -/** - * 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) -{ - int rc; - - rc = ble_hci_uart_acl_tx(om); - return rc; -} - -/** - * Configures the HCI transport to call the specified callback upon receiving - * HCI packets from the controller. This function should only be called by by - * host. - * - * @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) -{ - ble_hci_uart_set_rx_cbs(cmd_cb, cmd_arg, acl_cb, acl_arg); -} -#endif - -/** - * 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_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_uart_set_rx_cbs(cmd_cb, cmd_arg, acl_cb, acl_arg); -} - -/** - * 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) -{ - uint8_t *buf; - - switch (type) { - case BLE_HCI_TRANS_BUF_CMD: - buf = os_memblock_get(&ble_hci_uart_cmd_pool); - break; - case BLE_HCI_TRANS_BUF_EVT_HI: - buf = os_memblock_get(&ble_hci_uart_evt_hi_pool); - if (buf == NULL) { - /* If no high-priority event buffers remain, try to grab a - * low-priority one. - */ - buf = os_memblock_get(&ble_hci_uart_evt_lo_pool); - } - break; - - case BLE_HCI_TRANS_BUF_EVT_LO: - buf = os_memblock_get(&ble_hci_uart_evt_lo_pool); - break; - - default: - assert(0); - buf = NULL; - } - - return buf; -} - -/** - * 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) -{ - int rc; - - /* - * XXX: this may look a bit odd, but the controller uses the command - * buffer to send back the command complete/status as an immediate - * response to the command. This was done to insure that the controller - * could always send back one of these events when a command was received. - * Thus, we check to see which pool the buffer came from so we can free - * it to the appropriate pool - */ - if (os_memblock_from(&ble_hci_uart_evt_hi_pool, buf)) { - rc = os_memblock_put(&ble_hci_uart_evt_hi_pool, buf); - assert(rc == 0); - } else if (os_memblock_from(&ble_hci_uart_evt_lo_pool, buf)) { - rc = os_memblock_put(&ble_hci_uart_evt_lo_pool, buf); - assert(rc == 0); - } else { - assert(os_memblock_from(&ble_hci_uart_cmd_pool, buf)); - rc = os_memblock_put(&ble_hci_uart_cmd_pool, buf); - assert(rc == 0); - } -} - -/** - * Configures a callback to get executed whenever an ACL data packet is freed. - * The function is called in lieu of actually freeing the packet. - * - * @param cb The callback to configure. - * - * @return 0 on success. - */ -int -ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg) -{ - ble_hci_uart_acl_pool.mpe_put_cb = cb; - ble_hci_uart_acl_pool.mpe_put_arg = arg; - return 0; -} - -/** - * Resets the HCI UART transport to a clean state. Frees all buffers and - * reconfigures the UART. - * - * @return 0 on success; - * A BLE_ERR_[...] error code on failure. - */ -int -ble_hci_trans_reset(void) -{ - struct ble_hci_uart_pkt *pkt; - int rc; - - /* Close the UART to prevent race conditions as the buffers are freed. */ - rc = hal_uart_close(MYNEWT_VAL(BLE_HCI_UART_PORT)); - if (rc != 0) { - return BLE_ERR_HW_FAIL; - } - - ble_hci_uart_free_pkt(ble_hci_uart_state.rx_type, - ble_hci_uart_state.rx_cmd.data, - ble_hci_uart_state.rx_acl.buf); - ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_NONE; - - ble_hci_uart_free_pkt(ble_hci_uart_state.tx_type, - ble_hci_uart_state.tx_cmd.data, - ble_hci_uart_state.tx_pkt.tx_acl); - ble_hci_uart_state.tx_type = BLE_HCI_UART_H4_NONE; - - while ((pkt = STAILQ_FIRST(&ble_hci_uart_state.tx_pkts)) != NULL) { - STAILQ_REMOVE(&ble_hci_uart_state.tx_pkts, pkt, ble_hci_uart_pkt, - next); - ble_hci_uart_free_pkt(pkt->type, pkt->data, pkt->data); - os_memblock_put(&ble_hci_uart_pkt_pool, pkt); - } - - /* Reopen the UART. */ - rc = ble_hci_uart_config(); - if (rc != 0) { - return rc; - } - - return 0; -} - -/** - * Initializes the UART HCI transport module. - * - * @return 0 on success; - * A BLE_ERR_[...] error code on failure. - */ -void -ble_hci_uart_init(void) -{ - int rc; - - /* Ensure this function only gets called by sysinit. */ - SYSINIT_ASSERT_ACTIVE(); - - rc = os_mempool_ext_init(&ble_hci_uart_acl_pool, - MYNEWT_VAL(BLE_ACL_BUF_COUNT), - ACL_BLOCK_SIZE, - ble_hci_uart_acl_buf, - "ble_hci_uart_acl_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mbuf_pool_init(&ble_hci_uart_acl_mbuf_pool, - &ble_hci_uart_acl_pool.mpe_mp, - ACL_BLOCK_SIZE, - MYNEWT_VAL(BLE_ACL_BUF_COUNT)); - SYSINIT_PANIC_ASSERT(rc == 0); - - /* - * Create memory pool of HCI command buffers. NOTE: we currently dont - * allow this to be configured. The controller will only allow one - * outstanding command. We decided to keep this a pool in case we allow - * allow the controller to handle more than one outstanding command. - */ - rc = os_mempool_init(&ble_hci_uart_cmd_pool, - 1, - BLE_HCI_TRANS_CMD_SZ, - ble_hci_uart_cmd_buf, - "ble_hci_uart_cmd_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&ble_hci_uart_evt_hi_pool, - MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - ble_hci_uart_evt_hi_buf, - "ble_hci_uart_evt_hi_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&ble_hci_uart_evt_lo_pool, - MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - ble_hci_uart_evt_lo_buf, - "ble_hci_uart_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_uart_pkt_pool, - BLE_HCI_UART_EVT_COUNT + 1 + - MYNEWT_VAL(BLE_HCI_ACL_OUT_COUNT), - sizeof (struct ble_hci_uart_pkt), - ble_hci_uart_pkt_buf, - "ble_hci_uart_pkt_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = ble_hci_uart_config(); - SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failure configuring UART HCI"); - - memset(&ble_hci_uart_state, 0, sizeof ble_hci_uart_state); - STAILQ_INIT(&ble_hci_uart_state.tx_pkts); -} diff --git a/nimble/transport/uart/src/hci_uart.c b/nimble/transport/uart/src/hci_uart.c new file mode 100644 index 0000000000..9ffcc90f1f --- /dev/null +++ b/nimble/transport/uart/src/hci_uart.c @@ -0,0 +1,247 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include "os/os_mbuf.h" +#include "os/os_mempool.h" +#include "hal/hal_uart.h" +#include "nimble/transport.h" +#include "nimble/transport/hci_h4.h" + +#define TX_Q_SIZE (MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT) + \ + MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) + \ + MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT)) + +struct hci_uart_tx { + uint8_t type; + uint8_t sent_type; + uint16_t len; + uint16_t idx; + + struct os_mbuf *om; + uint8_t *buf; + + STAILQ_ENTRY(hci_uart_tx) tx_q_next; +}; + +static STAILQ_HEAD(, hci_uart_tx) tx_q; + +static struct os_mempool pool_tx_q; +static uint8_t pool_tx_q_buf[ OS_MEMPOOL_BYTES(TX_Q_SIZE, + sizeof(struct hci_uart_tx)) ]; + +struct hci_h4_sm hci_uart_h4sm; + +static int +hci_uart_frame_cb(uint8_t pkt_type, void *data) +{ + switch (pkt_type) { + case HCI_H4_CMD: + return ble_transport_to_ll_cmd(data); + case HCI_H4_ACL: + return ble_transport_to_ll_acl(data); + default: + assert(0); + break; + } + + return -1; +} + +static int +hci_uart_rx_char(void *arg, uint8_t data) +{ + hci_h4_sm_rx(&hci_uart_h4sm, &data, 1); + + return 0; +} + +static int +hci_uart_tx_char(void *arg) +{ + struct hci_uart_tx *tx; + uint8_t ch; + os_sr_t sr; + + OS_ENTER_CRITICAL(sr); + tx = STAILQ_FIRST(&tx_q); + OS_EXIT_CRITICAL(sr); + if (!tx) { + return -1; + } + + if (!tx->sent_type) { + tx->sent_type = 1; + return tx->type; + } + + switch (tx->type) { + case HCI_H4_EVT: + ch = tx->buf[tx->idx]; + tx->idx++; + if (tx->idx == tx->len) { + ble_transport_free(tx->buf); + OS_ENTER_CRITICAL(sr); + STAILQ_REMOVE_HEAD(&tx_q, tx_q_next); + OS_EXIT_CRITICAL(sr); + os_memblock_put(&pool_tx_q, tx); + } + break; + case HCI_H4_ACL: + os_mbuf_copydata(tx->om, 0, 1, &ch); + os_mbuf_adj(tx->om, 1); + tx->len--; + if (tx->len == 0) { + os_mbuf_free_chain(tx->om); + OS_ENTER_CRITICAL(sr); + STAILQ_REMOVE_HEAD(&tx_q, tx_q_next); + OS_EXIT_CRITICAL(sr); + os_memblock_put(&pool_tx_q, tx); + } + break; + default: + assert(0); + OS_ENTER_CRITICAL(sr); + STAILQ_REMOVE_HEAD(&tx_q, tx_q_next); + OS_EXIT_CRITICAL(sr); + os_memblock_put(&pool_tx_q, tx); + } + + return ch; +} + +static int +hci_uart_configure(void) +{ + enum hal_uart_parity parity; + enum hal_uart_flow_ctl flowctl; + int rc; + + rc = hal_uart_init_cbs(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT), + hci_uart_tx_char, NULL, + hci_uart_rx_char, NULL); + if (rc != 0) { + return -1; + } + + if (MYNEWT_VAL_CHOICE(BLE_TRANSPORT_UART_PARITY, odd)) { + parity = HAL_UART_PARITY_ODD; + } else if (MYNEWT_VAL_CHOICE(BLE_TRANSPORT_UART_PARITY, even)) { + parity = HAL_UART_PARITY_EVEN; + } else { + parity = HAL_UART_PARITY_NONE; + } + + if (MYNEWT_VAL_CHOICE(BLE_TRANSPORT_UART_FLOW_CONTROL, rtscts)) { + flowctl = HAL_UART_FLOW_CTL_RTS_CTS; + } else { + flowctl = HAL_UART_FLOW_CTL_NONE; + } + + rc = hal_uart_config(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT), + MYNEWT_VAL(BLE_TRANSPORT_UART_BAUDRATE), + MYNEWT_VAL(BLE_TRANSPORT_UART_DATA_BITS), + MYNEWT_VAL(BLE_TRANSPORT_UART_STOP_BITS), + parity, flowctl); + if (rc != 0) { + return -1; + } + + return 0; +} + +int +ble_transport_to_hs_evt(void *buf) +{ + struct hci_uart_tx *txe; + os_sr_t sr; + + txe = os_memblock_get(&pool_tx_q); + if (!txe) { + assert(0); + return -ENOMEM; + } + + txe->type = HCI_H4_EVT; + txe->sent_type = 0; + txe->len = 2 + ((uint8_t *)buf)[1]; + txe->buf = buf; + txe->idx = 0; + txe->om = NULL; + + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&tx_q, txe, tx_q_next); + OS_EXIT_CRITICAL(sr); + + hal_uart_start_tx(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT)); + + return 0; +} + +int +ble_transport_to_hs_acl(struct os_mbuf *om) +{ + struct hci_uart_tx *txe; + os_sr_t sr; + + txe = os_memblock_get(&pool_tx_q); + if (!txe) { + assert(0); + return -ENOMEM; + } + + txe->type = HCI_H4_ACL; + txe->sent_type = 0; + txe->len = 2 + OS_MBUF_PKTLEN(om); + txe->idx = 0; + txe->buf = NULL; + txe->om = om; + + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&tx_q, txe, tx_q_next); + OS_EXIT_CRITICAL(sr); + + hal_uart_start_tx(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT)); + + return 0; +} + +void +ble_transport_hs_init(void) +{ + int rc; + + SYSINIT_ASSERT_ACTIVE(); + + rc = hci_uart_configure(); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = os_mempool_init(&pool_tx_q, TX_Q_SIZE, sizeof(struct hci_uart_tx), + pool_tx_q_buf, "hci_uart_tx_q"); + SYSINIT_PANIC_ASSERT(rc == 0); + + hci_h4_sm_init(&hci_uart_h4sm, &hci_h4_allocs_from_hs, hci_uart_frame_cb); + + STAILQ_INIT(&tx_q); +} diff --git a/nimble/transport/uart/syscfg.yml b/nimble/transport/uart/syscfg.yml index 7eff9517c1..21d21777e9 100644 --- a/nimble/transport/uart/syscfg.yml +++ b/nimble/transport/uart/syscfg.yml @@ -17,45 +17,23 @@ # syscfg.defs: - BLE_HCI_ACL_OUT_COUNT: - description: > - This count is used in creating a pool of elements used by the - code to enqueue various elements. In the case of the controller - only HCI, this number should be equal to the number of mbufs in - the msys pool. For host only, it is really dependent on the - number of ACL buffers that the controller tells the host it - has. - value: 12 - - BLE_HCI_UART_PORT: - description: 'The uart to use for the HCI uart interface' - value: 0 - BLE_HCI_UART_BAUD: - description: 'The baud rate of the HCI uart interface' - value: 1000000 - BLE_HCI_UART_DATA_BITS: - description: 'Number of data bits used for HCI uart interface' - value: 8 - BLE_HCI_UART_STOP_BITS: - description: 'Number of stop bits used for HCI uart interface' - value: 1 - BLE_HCI_UART_PARITY: - description: 'Parity used for HCI uart interface' - value: HAL_UART_PARITY_NONE - BLE_HCI_UART_FLOW_CTRL: - description: 'Flow control used for HCI uart interface' - value: HAL_UART_FLOW_CTL_RTS_CTS - BLE_TRANS_UART_SYSINIT_STAGE: - description: > - Sysinit stage for the UART BLE transport. - value: 500 - -syscfg.vals.BLE_EXT_ADV: - BLE_HCI_EVT_BUF_SIZE: 257 - -syscfg.vals: - BLE_HCI_EVT_BUF_SIZE: 70 - BLE_HCI_EVT_HI_BUF_COUNT: 8 - BLE_HCI_EVT_LO_BUF_COUNT: 8 - BLE_ACL_BUF_COUNT: 12 - BLE_ACL_BUF_SIZE: 255 + BLE_TRANSPORT_UART_PORT: + description: UART index to use for HCI interface + value: 0 + BLE_TRANSPORT_UART_BAUDRATE: + description: Baudrate on UART + value: 1000000 + BLE_TRANSPORT_UART_DATA_BITS: + description: Number of data bits on UART + value: 8 + BLE_TRANSPORT_UART_STOP_BITS: + description: Number of stop bits on UART + value: 1 + BLE_TRANSPORT_UART_PARITY: + description: Parity on UART + value: none + choices: none,even,odd + BLE_TRANSPORT_UART_FLOW_CONTROL: + description: Flow control on UART + choices: off,rtscts + value: rtscts From 10958b3ec9ba6feeea5a68cc1dac282eac446ddd Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 3 Mar 2022 18:06:15 +0100 Subject: [PATCH 0338/1333] nimble/transport: Update USB transport --- nimble/transport/nrf5340/syscfg.yml | 38 ----- nimble/transport/usb/pkg.yml | 3 - nimble/transport/usb/src/ble_hci_usb.c | 218 ++++--------------------- nimble/transport/usb/syscfg.yml | 18 -- 4 files changed, 35 insertions(+), 242 deletions(-) delete mode 100644 nimble/transport/nrf5340/syscfg.yml diff --git a/nimble/transport/nrf5340/syscfg.yml b/nimble/transport/nrf5340/syscfg.yml deleted file mode 100644 index a12e0c3736..0000000000 --- a/nimble/transport/nrf5340/syscfg.yml +++ /dev/null @@ -1,38 +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. -# - -syscfg.defs: - BLE_TRANS_NRF5340_SYSINIT_STAGE: - description: > - Sysinit stage for the RAM BLE transport. - value: 100 - -syscfg.vals.'!BLE_HCI_BRIDGE: - BLE_HCI_EVT_HI_BUF_COUNT: 2 - BLE_HCI_EVT_LO_BUF_COUNT: 8 - BLE_ACL_BUF_COUNT: 4 - BLE_ACL_BUF_SIZE: 255 - -syscfg.vals.'!BLE_HCI_BRIDGE && !BLE_EXT_ADV': - BLE_HCI_EVT_BUF_SIZE: 70 - -syscfg.vals.'!BLE_HCI_BRIDGE && BLE_EXT_ADV': - BLE_HCI_EVT_BUF_SIZE: 257 - -syscfg.restrictions: - - '!(BLE_HOST && BLE_CONTROLLER)' diff --git a/nimble/transport/usb/pkg.yml b/nimble/transport/usb/pkg.yml index c4c314c867..199afe6126 100644 --- a/nimble/transport/usb/pkg.yml +++ b/nimble/transport/usb/pkg.yml @@ -35,6 +35,3 @@ pkg.deps: pkg.apis: - ble_transport - -pkg.init: - ble_hci_usb_init: 'MYNEWT_VAL(BLE_TRANS_USB_SYSINIT_STAGE)' diff --git a/nimble/transport/usb/src/ble_hci_usb.c b/nimble/transport/usb/src/ble_hci_usb.c index 8160536b95..6518cd9481 100644 --- a/nimble/transport/usb/src/ble_hci_usb.c +++ b/nimble/transport/usb/src/ble_hci_usb.c @@ -25,78 +25,20 @@ #include "mem/mem.h" #include "nimble/ble.h" -#include "nimble/ble_hci_trans.h" #include "nimble/hci_common.h" +#include "nimble/transport.h" #include -/* - * The MBUF payload size must accommodate the HCI data header size plus the - * maximum ACL data packet length. The ACL block size is the size of the - * mbufs we will allocate. - */ -#define ACL_BLOCK_SIZE OS_ALIGN(MYNEWT_VAL(BLE_ACL_BUF_SIZE) \ - + BLE_MBUF_MEMBLOCK_OVERHEAD \ - + BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT) - -struct usb_ble_hci_pool_cmd { - uint8_t cmd[BLE_HCI_TRANS_CMD_SZ]; - bool allocated; -}; - -/* (Pseudo)pool for HCI commands */ -static struct usb_ble_hci_pool_cmd usb_ble_hci_pool_cmd; - -static ble_hci_trans_rx_cmd_fn *ble_hci_usb_rx_cmd_ll_cb; -static void *ble_hci_usb_rx_cmd_ll_arg; - -static ble_hci_trans_rx_acl_fn *ble_hci_usb_rx_acl_ll_cb; -static void *ble_hci_usb_rx_acl_ll_arg; - -static struct os_mempool ble_hci_usb_evt_hi_pool; -static os_membuf_t ble_hci_usb_evt_hi_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) -]; - -static struct os_mempool ble_hci_usb_evt_lo_pool; -static os_membuf_t ble_hci_usb_evt_lo_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) -]; - -static uint8_t ble_hci_pool_acl_mempool_buf[ - OS_MEMPOOL_BYTES(MYNEWT_VAL(BLE_ACL_BUF_COUNT), - ACL_BLOCK_SIZE)]; -static struct os_mempool ble_hci_pool_acl_mempool; -static struct os_mbuf_pool ble_hci_pool_acl_mbuf_pool; - static struct os_mbuf *incoming_acl_data; -static struct os_mbuf * -ble_hci_trans_acl_buf_alloc(void) -{ - struct os_mbuf *m; - - m = os_mbuf_get_pkthdr(&ble_hci_pool_acl_mbuf_pool, - sizeof(struct ble_mbuf_hdr)); - return m; -} +#define TX_Q_SIZE (MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT) + \ + MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) + \ + MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT)) -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_usb_rx_cmd_ll_cb = cmd_cb; - ble_hci_usb_rx_cmd_ll_arg = cmd_arg; - ble_hci_usb_rx_acl_ll_cb = acl_cb; - ble_hci_usb_rx_acl_ll_arg = acl_arg; -} #define BLE_HCI_USB_EVT_COUNT \ - (MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT) + MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT)) + (MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT)) /** * A packet to be sent over the USB. This can be a command, an event, or ACL @@ -107,11 +49,9 @@ struct ble_hci_pkt { void *data; }; -static struct os_mempool ble_hci_pkt_pool; -static os_membuf_t ble_hci_pkt_buf[ - OS_MEMPOOL_SIZE(BLE_HCI_USB_EVT_COUNT + 1 + - MYNEWT_VAL(BLE_HCI_ACL_OUT_COUNT), - sizeof(struct ble_hci_pkt))]; +static struct os_mempool pool_tx_q; +static os_membuf_t pool_tx_q_buf[ OS_MEMPOOL_SIZE(TX_Q_SIZE, + sizeof(struct ble_hci_pkt)) ]; struct tx_queue { STAILQ_HEAD(, ble_hci_pkt) queue; @@ -151,7 +91,7 @@ tud_bt_acl_data_sent_cb(uint16_t sent_bytes) STAILQ_REMOVE_HEAD(&ble_hci_tx_acl_queue.queue, next); next_acl = STAILQ_FIRST(&ble_hci_tx_acl_queue.queue); OS_EXIT_CRITICAL(sr); - os_memblock_put(&ble_hci_pkt_pool, curr_acl); + os_memblock_put(&pool_tx_q, curr_acl); if (next_acl != NULL) { om = next_acl->data; } @@ -178,13 +118,13 @@ tud_bt_event_sent_cb(uint16_t sent_bytes) assert(hci_ev != NULL && hci_ev[1] + sizeof(struct ble_hci_ev) == sent_bytes); - ble_hci_trans_buf_free(hci_ev); + ble_transport_free(hci_ev); OS_ENTER_CRITICAL(sr); STAILQ_REMOVE_HEAD(&ble_hci_tx_evt_queue.queue, next); next_evt = STAILQ_FIRST(&ble_hci_tx_evt_queue.queue); OS_EXIT_CRITICAL(sr); - os_memblock_put(&ble_hci_pkt_pool, curr_evt); + os_memblock_put(&pool_tx_q, curr_evt); if (next_evt != NULL) { hci_ev = next_evt->data; @@ -201,10 +141,11 @@ tud_bt_acl_data_received_cb(void *acl_data, uint16_t data_len) int rc; if (om == NULL) { - om = ble_hci_trans_acl_buf_alloc(); + om = ble_transport_alloc_acl_from_hs(); assert(om != NULL); } - assert(om->om_len + data_len <= MYNEWT_VAL(BLE_ACL_BUF_SIZE) + BLE_HCI_DATA_HDR_SZ); + assert(om->om_len + data_len <= MYNEWT_VAL(BLE_TRANSPORT_ACL_SIZE) + + BLE_HCI_DATA_HDR_SZ); os_mbuf_append(om, acl_data, data_len); incoming_acl_data = om; @@ -213,7 +154,7 @@ tud_bt_acl_data_received_cb(void *acl_data, uint16_t data_len) len = data[2] + (data[3] << 8) + BLE_HCI_DATA_HDR_SZ; if (incoming_acl_data->om_len >= len) { incoming_acl_data = NULL; - rc = ble_hci_usb_rx_acl_ll_cb(om, ble_hci_usb_rx_acl_ll_arg); + rc = ble_transport_to_ll_acl(om); (void)rc; } } @@ -225,17 +166,14 @@ tud_bt_hci_cmd_cb(void *hci_cmd, size_t cmd_len) uint8_t *buf; int rc = -1; - assert(ble_hci_usb_rx_cmd_ll_cb); - if (ble_hci_usb_rx_cmd_ll_cb) { - buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - assert(buf != NULL); - memcpy(buf, hci_cmd, min(cmd_len, BLE_HCI_TRANS_CMD_SZ)); + buf = ble_transport_alloc_cmd(); + assert(buf != NULL); + memcpy(buf, hci_cmd, min(cmd_len, 258)); - rc = ble_hci_usb_rx_cmd_ll_cb(buf, ble_hci_usb_rx_cmd_ll_arg); - } + rc = ble_transport_to_ll_cmd(buf); if (rc != 0) { - ble_hci_trans_buf_free(buf); + ble_transport_free(buf); } } @@ -252,7 +190,7 @@ ble_hci_trans_ll_tx(struct tx_queue *queue, struct os_mbuf *om) return 0; } - pkt = os_memblock_get(&ble_hci_pkt_pool); + pkt = os_memblock_get(&pool_tx_q); if (pkt == NULL) { os_mbuf_free_chain(om); return BLE_ERR_MEM_CAPACITY; @@ -270,29 +208,24 @@ ble_hci_trans_ll_tx(struct tx_queue *queue, struct os_mbuf *om) return 0; } -int -ble_hci_trans_ll_acl_tx(struct os_mbuf *om) -{ - return ble_hci_trans_ll_tx(&ble_hci_tx_acl_queue, om); -} - -int -ble_hci_trans_ll_evt_tx(uint8_t *hci_ev) +static int +ble_hci_trans_ll_evt_tx(void *buf) { struct ble_hci_pkt *pkt; + uint8_t *hci_ev = buf; os_sr_t sr; bool first; assert(hci_ev != NULL); if (!tud_ready()) { - ble_hci_trans_buf_free(hci_ev); + ble_transport_free(hci_ev); return 0; } - pkt = os_memblock_get(&ble_hci_pkt_pool); + pkt = os_memblock_get(&pool_tx_q); if (pkt == NULL) { - ble_hci_trans_buf_free(hci_ev); + ble_transport_free(hci_ev); return BLE_ERR_MEM_CAPACITY; } @@ -308,108 +241,27 @@ ble_hci_trans_ll_evt_tx(uint8_t *hci_ev) return 0; } -uint8_t * -ble_hci_trans_buf_alloc(int type) -{ - uint8_t *buf; - - switch (type) { - case BLE_HCI_TRANS_BUF_CMD: - assert(!usb_ble_hci_pool_cmd.allocated); - usb_ble_hci_pool_cmd.allocated = 1; - buf = usb_ble_hci_pool_cmd.cmd; - break; - - case BLE_HCI_TRANS_BUF_EVT_HI: - buf = os_memblock_get(&ble_hci_usb_evt_hi_pool); - if (buf == NULL) { - /* If no high-priority event buffers remain, try to grab a - * low-priority one. - */ - buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); - } - break; - - case BLE_HCI_TRANS_BUF_EVT_LO: - buf = os_memblock_get(&ble_hci_usb_evt_lo_pool); - break; - - default: - assert(0); - buf = NULL; - } - - return buf; -} - -void -ble_hci_trans_buf_free(uint8_t *buf) +int +ble_transport_to_hs_acl(struct os_mbuf *om) { - int rc; - - /* XXX: this may look a bit odd, but the controller uses the command - * buffer to send back the command complete/status as an immediate - * response to the command. This was done to insure that the controller - * could always send back one of these events when a command was received. - * Thus, we check to see which pool the buffer came from so we can free - * it to the appropriate pool - */ - if (os_memblock_from(&ble_hci_usb_evt_hi_pool, buf)) { - rc = os_memblock_put(&ble_hci_usb_evt_hi_pool, buf); - assert(rc == 0); - } else if (os_memblock_from(&ble_hci_usb_evt_lo_pool, buf)) { - rc = os_memblock_put(&ble_hci_usb_evt_lo_pool, buf); - assert(rc == 0); - } else { - assert(usb_ble_hci_pool_cmd.allocated); - usb_ble_hci_pool_cmd.allocated = 0; - } - (void)rc; + return ble_hci_trans_ll_tx(&ble_hci_tx_acl_queue, om); } int -ble_hci_trans_reset(void) +ble_transport_to_hs_evt(void *buf) { - return 0; + return ble_hci_trans_ll_evt_tx(buf); } void -ble_hci_usb_init(void) +ble_transport_hs_init(void) { int rc; /* Ensure this function only gets called by sysinit. */ SYSINIT_ASSERT_ACTIVE(); - rc = mem_init_mbuf_pool(ble_hci_pool_acl_mempool_buf, &ble_hci_pool_acl_mempool, &ble_hci_pool_acl_mbuf_pool, - MYNEWT_VAL(BLE_ACL_BUF_COUNT), ACL_BLOCK_SIZE, "ble_hci_acl"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&ble_hci_usb_evt_hi_pool, - MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - ble_hci_usb_evt_hi_buf, - "ble_hci_usb_evt_hi_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&ble_hci_usb_evt_lo_pool, - MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - ble_hci_usb_evt_lo_buf, - "ble_hci_usb_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_pkt_pool, - BLE_HCI_USB_EVT_COUNT + 1 + - MYNEWT_VAL(BLE_HCI_ACL_OUT_COUNT), - sizeof (struct ble_hci_pkt), - ble_hci_pkt_buf, - "ble_hci_usb_pkt_pool"); + rc = os_mempool_init(&pool_tx_q, TX_Q_SIZE, sizeof(struct ble_hci_pkt), + pool_tx_q_buf, "ble_hci_usb_tx_q"); SYSINIT_PANIC_ASSERT(rc == 0); } diff --git a/nimble/transport/usb/syscfg.yml b/nimble/transport/usb/syscfg.yml index 38effde60c..17ef649be5 100644 --- a/nimble/transport/usb/syscfg.yml +++ b/nimble/transport/usb/syscfg.yml @@ -26,21 +26,3 @@ syscfg.defs: number of ACL buffers that the controller tells the host it has. value: 12 - - BLE_TRANS_USB_SYSINIT_STAGE: - description: > - Sysinit stage for the USB BLE transport. - value: 500 - -syscfg.vals.BLE_EXT_ADV: - BLE_HCI_EVT_BUF_SIZE: 257 - -syscfg.vals: - BLE_HCI_EVT_BUF_SIZE: 70 - BLE_HCI_EVT_HI_BUF_COUNT: 8 - BLE_HCI_EVT_LO_BUF_COUNT: 8 - BLE_ACL_BUF_COUNT: 12 - BLE_ACL_BUF_SIZE: 255 - -syscfg.restrictions: - - '!BLE_HOST' From 74d8f03a1a10b5261fac035fd61712084a9a7c64 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 10 Mar 2022 12:48:35 +0100 Subject: [PATCH 0339/1333] nimble/transport: Update socket transport This only works for external controller, external host can be implemented if needed (not sure who would use that though). --- nimble/transport/pkg.yml | 2 + nimble/transport/socket/src/ble_hci_socket.c | 270 +++---------------- nimble/transport/socket/syscfg.yml | 20 -- nimble/transport/syscfg.yml | 1 + 4 files changed, 41 insertions(+), 252 deletions(-) diff --git a/nimble/transport/pkg.yml b/nimble/transport/pkg.yml index 287ed974a1..e5dad56aca 100644 --- a/nimble/transport/pkg.yml +++ b/nimble/transport/pkg.yml @@ -36,6 +36,8 @@ pkg.deps.'BLE_TRANSPORT_HS == "dialog_cmac" || BLE_TRANSPORT_LL == "dialog_cmac" - nimble/transport/dialog_cmac pkg.deps.'BLE_TRANSPORT_HS == "nrf5340" || BLE_TRANSPORT_LL == "nrf5340"': - nimble/transport/nrf5340 +pkg.deps.'BLE_TRANSPORT_LL == "socket"': + - nimble/transport/socket pkg.deps.'BLE_TRANSPORT_HS == "uart"': - nimble/transport/uart pkg.deps.'BLE_TRANSPORT_HS == "usb"': diff --git a/nimble/transport/socket/src/ble_hci_socket.c b/nimble/transport/socket/src/ble_hci_socket.c index 8a7338980f..ee974ec3f3 100644 --- a/nimble/transport/socket/src/ble_hci_socket.c +++ b/nimble/transport/socket/src/ble_hci_socket.c @@ -85,7 +85,7 @@ struct sockaddr_hci { #include "nimble/nimble_opt.h" #include "nimble/hci_common.h" #include "nimble/nimble_npl.h" -#include "nimble/ble_hci_trans.h" +#include "nimble/transport.h" #include "socket/ble_hci_socket.h" /*** @@ -155,45 +155,6 @@ struct os_task ble_sock_task; #endif -static struct os_mempool ble_hci_sock_evt_hi_pool; -static os_membuf_t ble_hci_sock_evt_hi_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) -]; - -static struct os_mempool ble_hci_sock_evt_lo_pool; -static os_membuf_t ble_hci_sock_evt_lo_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) -]; - -static struct os_mempool ble_hci_sock_cmd_pool; -static os_membuf_t ble_hci_sock_cmd_buf[ - OS_MEMPOOL_SIZE(1, BLE_HCI_TRANS_CMD_SZ) -]; - -static struct os_mempool ble_hci_sock_acl_pool; -static struct os_mbuf_pool ble_hci_sock_acl_mbuf_pool; - -#define ACL_BLOCK_SIZE OS_ALIGN(MYNEWT_VAL(BLE_ACL_BUF_SIZE) \ - + BLE_MBUF_MEMBLOCK_OVERHEAD \ - + BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT) -/* - * The MBUF payload size must accommodate the HCI data header size plus the - * maximum ACL data packet length. The ACL block size is the size of the - * mbufs we will allocate. - */ - -static os_membuf_t ble_hci_sock_acl_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ACL_BUF_COUNT), - ACL_BLOCK_SIZE) -]; - -static ble_hci_trans_rx_cmd_fn *ble_hci_sock_rx_cmd_cb; -static void *ble_hci_sock_rx_cmd_arg; -static ble_hci_trans_rx_acl_fn *ble_hci_sock_rx_acl_cb; -static void *ble_hci_sock_rx_acl_arg; - static struct ble_hci_sock_state { int sock; struct ble_npl_eventq evq; @@ -212,26 +173,6 @@ static int s_ble_hci_device = MYNEWT_VAL(BLE_SOCK_LINUX_DEV); static int s_ble_hci_device = 0; #endif -/** - * Allocates a buffer (mbuf) for ACL operation. - * - * @return The allocated buffer on success; - * NULL on buffer exhaustion. - */ -static struct os_mbuf * -ble_hci_trans_acl_buf_alloc(void) -{ - struct os_mbuf *m; - - /* - * XXX: note that for host only there would be no need to allocate - * a user header. Address this later. - */ - m = os_mbuf_get_pkthdr(&ble_hci_sock_acl_mbuf_pool, - sizeof(struct ble_mbuf_hdr)); - return m; -} - #if MYNEWT_VAL(BLE_SOCK_USE_LINUX_BLUE) static int ble_hci_sock_acl_tx(struct os_mbuf *om) @@ -365,7 +306,7 @@ ble_hci_sock_cmdevt_tx(uint8_t *hci_ev, uint8_t h4_type) STATS_INCN(hci_sock_stats, obytes, len + 1); i = sendmsg(ble_hci_sock_state.sock, &msg, 0); - ble_hci_trans_buf_free(hci_ev); + ble_transport_free(hci_ev); if (i != len + 1) { if (i < 0) { dprintf(1, "sendmsg() failed : %d\n", errno); @@ -468,17 +409,17 @@ ble_hci_sock_rx_msg(void) } STATS_INC(hci_sock_stats, imsg); STATS_INC(hci_sock_stats, icmd); - data = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); + data = ble_transport_alloc_cmd(); if (!data) { STATS_INC(hci_sock_stats, ierr); break; } memcpy(data, &bhss->rx_data[1], len - 1); OS_ENTER_CRITICAL(sr); - rc = ble_hci_sock_rx_cmd_cb(data, ble_hci_sock_rx_cmd_arg); + rc = ble_transport_to_ll_cmd(data); OS_EXIT_CRITICAL(sr); if (rc) { - ble_hci_trans_buf_free(data); + ble_transport_free(data); STATS_INC(hci_sock_stats, ierr); break; } @@ -495,17 +436,17 @@ ble_hci_sock_rx_msg(void) } STATS_INC(hci_sock_stats, imsg); STATS_INC(hci_sock_stats, ievt); - data = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + data = ble_transport_alloc_evt(0); if (!data) { STATS_INC(hci_sock_stats, ierr); break; } memcpy(data, &bhss->rx_data[1], len - 1); OS_ENTER_CRITICAL(sr); - rc = ble_hci_sock_rx_cmd_cb(data, ble_hci_sock_rx_cmd_arg); + rc = ble_transport_to_hs_evt(data); OS_EXIT_CRITICAL(sr); if (rc) { - ble_hci_trans_buf_free(data); + ble_transport_free(data); STATS_INC(hci_sock_stats, ierr); return 0; } @@ -522,7 +463,11 @@ ble_hci_sock_rx_msg(void) } STATS_INC(hci_sock_stats, imsg); STATS_INC(hci_sock_stats, iacl); - m = ble_hci_trans_acl_buf_alloc(); +#if MYNEWT_VAL(BLE_CONTROLLER) + m = ble_transport_alloc_acl_from_hs(); +#else + m = ble_transport_alloc_acl_from_ll(); +#endif if (!m) { STATS_INC(hci_sock_stats, imem); break; @@ -533,7 +478,11 @@ ble_hci_sock_rx_msg(void) break; } OS_ENTER_CRITICAL(sr); - ble_hci_sock_rx_acl_cb(m, ble_hci_sock_rx_acl_arg); +#if MYNEWT_VAL(BLE_CONTROLLER) + ble_transport_to_ll_acl(m); +#else + ble_transport_to_hs_acl(m); +#endif OS_EXIT_CRITICAL(sr); break; default: @@ -785,129 +734,6 @@ ble_hci_trans_hs_acl_tx(struct os_mbuf *om) return ble_hci_sock_acl_tx(om); } -/** - * Configures the HCI transport to call the specified callback upon receiving - * HCI packets from the controller. This function should only be called by by - * host. - * - * @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) -{ - ble_hci_sock_rx_cmd_cb = cmd_cb; - ble_hci_sock_rx_cmd_arg = cmd_arg; - ble_hci_sock_rx_acl_cb = acl_cb; - ble_hci_sock_rx_acl_arg = 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_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_sock_rx_cmd_cb = cmd_cb; - ble_hci_sock_rx_cmd_arg = cmd_arg; - ble_hci_sock_rx_acl_cb = acl_cb; - ble_hci_sock_rx_acl_arg = acl_arg; -} - -/** - * 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) -{ - uint8_t *buf; - - switch (type) { - case BLE_HCI_TRANS_BUF_CMD: - buf = os_memblock_get(&ble_hci_sock_cmd_pool); - break; - case BLE_HCI_TRANS_BUF_EVT_HI: - buf = os_memblock_get(&ble_hci_sock_evt_hi_pool); - if (buf == NULL) { - /* If no high-priority event buffers remain, try to grab a - * low-priority one. - */ - buf = os_memblock_get(&ble_hci_sock_evt_lo_pool); - } - break; - - case BLE_HCI_TRANS_BUF_EVT_LO: - buf = os_memblock_get(&ble_hci_sock_evt_lo_pool); - break; - - default: - assert(0); - buf = NULL; - } - - return buf; -} - -/** - * 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) -{ - int rc; - - /* - * XXX: this may look a bit odd, but the controller uses the command - * buffer to send back the command complete/status as an immediate - * response to the command. This was done to insure that the controller - * could always send back one of these events when a command was received. - * Thus, we check to see which pool the buffer came from so we can free - * it to the appropriate pool - */ - if (os_memblock_from(&ble_hci_sock_evt_hi_pool, buf)) { - rc = os_memblock_put(&ble_hci_sock_evt_hi_pool, buf); - assert(rc == 0); - } else if (os_memblock_from(&ble_hci_sock_evt_lo_pool, buf)) { - rc = os_memblock_put(&ble_hci_sock_evt_lo_pool, buf); - assert(rc == 0); - } else { - assert(os_memblock_from(&ble_hci_sock_cmd_pool, buf)); - rc = os_memblock_put(&ble_hci_sock_cmd_pool, buf); - assert(rc == 0); - } -} - /** * Resets the HCI UART transport to a clean state. Frees all buffers and * reconfigures the UART. @@ -997,46 +823,6 @@ ble_hci_sock_init(void) ble_hci_sock_init_task(); ble_npl_event_init(&ble_hci_sock_state.ev, ble_hci_sock_rx_ev, NULL); - rc = os_mempool_init(&ble_hci_sock_acl_pool, - MYNEWT_VAL(BLE_ACL_BUF_COUNT), - ACL_BLOCK_SIZE, - ble_hci_sock_acl_buf, - "ble_hci_sock_acl_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mbuf_pool_init(&ble_hci_sock_acl_mbuf_pool, - &ble_hci_sock_acl_pool, - ACL_BLOCK_SIZE, - MYNEWT_VAL(BLE_ACL_BUF_COUNT)); - SYSINIT_PANIC_ASSERT(rc == 0); - - /* - * Create memory pool of HCI command buffers. NOTE: we currently dont - * allow this to be configured. The controller will only allow one - * outstanding command. We decided to keep this a pool in case we allow - * allow the controller to handle more than one outstanding command. - */ - rc = os_mempool_init(&ble_hci_sock_cmd_pool, - 1, - BLE_HCI_TRANS_CMD_SZ, - &ble_hci_sock_cmd_buf, - "ble_hci_sock_cmd_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&ble_hci_sock_evt_hi_pool, - MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - &ble_hci_sock_evt_hi_buf, - "ble_hci_sock_evt_hi_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&ble_hci_sock_evt_lo_pool, - MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - ble_hci_sock_evt_lo_buf, - "ble_hci_sock_evt_lo_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - rc = ble_hci_sock_config(); SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failure configuring socket HCI"); @@ -1045,3 +831,23 @@ ble_hci_sock_init(void) STATS_NAME_INIT_PARMS(hci_sock_stats), "hci_socket"); SYSINIT_PANIC_ASSERT(rc == 0); } + +void +ble_transport_ll_init(void) +{ + ble_hci_sock_init(); +} + +int +ble_transport_to_ll_acl(struct os_mbuf *om) +{ + return ble_hci_trans_hs_acl_tx(om); +} + +int +ble_transport_to_ll_cmd(void *buf) +{ + return ble_hci_trans_hs_cmd_tx(buf); +} + +/* TODO: add ll-to-hs side if needed */ diff --git a/nimble/transport/socket/syscfg.yml b/nimble/transport/socket/syscfg.yml index 63b9cddff1..c74f056c5d 100644 --- a/nimble/transport/socket/syscfg.yml +++ b/nimble/transport/socket/syscfg.yml @@ -17,16 +17,6 @@ # syscfg.defs: - BLE_HCI_ACL_OUT_COUNT: - description: > - This count is used in creating a pool of elements used by the - code to enqueue various elements. In the case of the controller - only HCI, this number should be equal to the number of mbufs in - the msys pool. For host only, it is really dependent on the - number of ACL buffers that the controller tells the host it - has. - value: 12 - BLE_SOCK_USE_TCP: description: 'Use TCP socket, connects to BLE_SOCK_TCP_PORT' value: 1 @@ -60,13 +50,3 @@ syscfg.defs: description: > Sysinit stage for the socket BLE transport. value: 500 - -syscfg.vals.'!BLE_HCI_BRIDGE && BLE_EXT_ADV': - BLE_HCI_EVT_BUF_SIZE: 257 - -syscfg.vals.'!BLE_HCI_BRIDGE && !BLE_EXT_ADV': - BLE_HCI_EVT_BUF_SIZE: 70 - BLE_HCI_EVT_HI_BUF_COUNT: 8 - BLE_HCI_EVT_LO_BUF_COUNT: 8 - BLE_ACL_BUF_COUNT: 24 - BLE_ACL_BUF_SIZE: 255 diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml index d2404e1418..cb9e07e7ff 100644 --- a/nimble/transport/syscfg.yml +++ b/nimble/transport/syscfg.yml @@ -42,6 +42,7 @@ syscfg.defs: - native - dialog_cmac - nrf5340 + - socket - custom BLE_TRANSPORT_ACL_COUNT: From 1311466f04ec51b675ed23feda5abd05161c086a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 10 Mar 2022 14:42:57 +0100 Subject: [PATCH 0340/1333] nimble/transport: Update emspi transport --- nimble/transport/emspi/src/ble_hci_emspi.c | 317 ++------------------- nimble/transport/emspi/syscfg.yml | 10 - nimble/transport/pkg.yml | 2 + nimble/transport/syscfg.yml | 1 + 4 files changed, 32 insertions(+), 298 deletions(-) diff --git a/nimble/transport/emspi/src/ble_hci_emspi.c b/nimble/transport/emspi/src/ble_hci_emspi.c index 61fe96b2b3..e49d3d48a3 100644 --- a/nimble/transport/emspi/src/ble_hci_emspi.c +++ b/nimble/transport/emspi/src/ble_hci_emspi.c @@ -35,23 +35,12 @@ #include "nimble/ble.h" #include "nimble/nimble_opt.h" #include "nimble/hci_common.h" -#include "nimble/ble_hci_trans.h" +#include "nimble/transport.h" #include "transport/emspi/ble_hci_emspi.h" #include "am_mcu_apollo.h" -/*** - * NOTES: - * The emspi HCI transport doesn't use event buffer priorities. All incoming - * and outgoing events use buffers from the same pool. - * - */ - -#define BLE_HCI_EMSPI_PKT_EVT_COUNT \ - (MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT) + \ - MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT)) - #define BLE_HCI_EMSPI_PKT_NONE 0x00 #define BLE_HCI_EMSPI_PKT_CMD 0x01 #define BLE_HCI_EMSPI_PKT_ACL 0x02 @@ -71,46 +60,6 @@ static struct os_eventq ble_hci_emspi_evq; static struct os_task ble_hci_emspi_task; static os_stack_t ble_hci_emspi_stack[MYNEWT_VAL(BLE_HCI_EMSPI_STACK_SIZE)]; -static ble_hci_trans_rx_cmd_fn *ble_hci_emspi_rx_cmd_cb; -static void *ble_hci_emspi_rx_cmd_arg; - -static ble_hci_trans_rx_acl_fn *ble_hci_emspi_rx_acl_cb; -static void *ble_hci_emspi_rx_acl_arg; - -static struct os_mempool ble_hci_emspi_evt_hi_pool; -static os_membuf_t ble_hci_emspi_evt_hi_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) -]; - -static struct os_mempool ble_hci_emspi_evt_lo_pool; -static os_membuf_t ble_hci_emspi_evt_lo_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) -]; - -static struct os_mempool ble_hci_emspi_cmd_pool; -static os_membuf_t ble_hci_emspi_cmd_buf[ - OS_MEMPOOL_SIZE(1, BLE_HCI_TRANS_CMD_SZ) -]; - -static struct os_mbuf_pool ble_hci_emspi_acl_mbuf_pool; -static struct os_mempool_ext ble_hci_emspi_acl_pool; - -/* - * The MBUF payload size must accommodate the HCI data header size plus the - * maximum ACL data packet length. The ACL block size is the size of the - * mbufs we will allocate. - */ -#define ACL_BLOCK_SIZE OS_ALIGN(MYNEWT_VAL(BLE_ACL_BUF_SIZE) \ - + BLE_MBUF_MEMBLOCK_OVERHEAD \ - + BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT) - -static os_membuf_t ble_hci_emspi_acl_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ACL_BUF_COUNT), - ACL_BLOCK_SIZE) -]; - /** * A packet to be sent over the EMSPI. This can be a command, an event, or ACL * data. @@ -124,8 +73,7 @@ STAILQ_HEAD(, ble_hci_emspi_pkt) ble_hci_emspi_tx_q; static struct os_mempool ble_hci_emspi_pkt_pool; static os_membuf_t ble_hci_emspi_pkt_buf[ - OS_MEMPOOL_SIZE(BLE_HCI_EMSPI_PKT_EVT_COUNT + 1 + - MYNEWT_VAL(BLE_HCI_ACL_OUT_COUNT), + OS_MEMPOOL_SIZE(1 + MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_HS_COUNT), sizeof (struct ble_hci_emspi_pkt)) ]; @@ -286,18 +234,6 @@ ble_hci_emspi_rx(uint8_t *data, int max_len) return rc; } -/** - * Allocates a buffer (mbuf) for ACL operation. - * - * @return The allocated buffer on success; - * NULL on buffer exhaustion. - */ -static struct os_mbuf * -ble_hci_trans_acl_buf_alloc(void) -{ - return os_mbuf_get_pkthdr(&ble_hci_emspi_acl_mbuf_pool, 0); -} - /** * Transmits an ACL data packet to the controller. The caller relinquishes the * specified mbuf, regardless of return status. @@ -344,7 +280,7 @@ ble_hci_emspi_cmdevt_tx(uint8_t *cmd_buf, uint8_t pkt_type) pkt = os_memblock_get(&ble_hci_emspi_pkt_pool); if (pkt == NULL) { - ble_hci_trans_buf_free(cmd_buf); + ble_transport_free(cmd_buf); return BLE_ERR_MEM_CAPACITY; } @@ -449,7 +385,7 @@ ble_hci_emspi_tx_pkt(void) switch (pkt->type) { case BLE_HCI_EMSPI_PKT_CMD: rc = ble_hci_emspi_tx_cmd(pkt->data); - ble_hci_trans_buf_free(pkt->data); + ble_transport_free(pkt->data); break; case BLE_HCI_EMSPI_PKT_ACL: @@ -477,7 +413,7 @@ ble_hci_emspi_rx_evt(void) /* XXX: we should not assert if host cannot allocate an event. Need * to determine what to do here. */ - data = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + data = ble_transport_alloc_evt(0); assert(data != NULL); rc = ble_hci_emspi_rx(data, sizeof(struct ble_hci_ev)); @@ -493,8 +429,7 @@ ble_hci_emspi_rx_evt(void) } } - assert(ble_hci_emspi_rx_cmd_cb != NULL); - ble_hci_emspi_rx_cmd_cb(data, ble_hci_emspi_rx_cmd_arg); + rc = ble_transport_to_hs_evt(data); if (rc != 0) { goto err; } @@ -502,7 +437,7 @@ ble_hci_emspi_rx_evt(void) return 0; err: - ble_hci_trans_buf_free(data); + ble_transport_free(data); return rc; } @@ -516,7 +451,7 @@ ble_hci_emspi_rx_acl(void) /* XXX: we should not assert if host cannot allocate an mbuf. Need to * determine what to do here. */ - om = ble_hci_trans_acl_buf_alloc(); + om = ble_transport_alloc_acl_from_ll(); assert(om != NULL); rc = ble_hci_emspi_rx(om->om_data, BLE_HCI_DATA_HDR_SZ); @@ -525,7 +460,7 @@ ble_hci_emspi_rx_acl(void) } len = get_le16(om->om_data + 2); - if (len > MYNEWT_VAL(BLE_ACL_BUF_SIZE)) { + if (len > MYNEWT_VAL(BLE_TRANSPORT_ACL_SIZE)) { /* * Data portion cannot exceed data length of acl buffer. If it does * this is considered to be a loss of sync. @@ -544,8 +479,7 @@ ble_hci_emspi_rx_acl(void) OS_MBUF_PKTLEN(om) = BLE_HCI_DATA_HDR_SZ + len; om->om_len = BLE_HCI_DATA_HDR_SZ + len; - assert(ble_hci_emspi_rx_cmd_cb != NULL); - rc = ble_hci_emspi_rx_acl_cb(om, ble_hci_emspi_rx_acl_arg); + rc = ble_transport_to_hs_acl(om); if (rc != 0) { goto err; } @@ -586,18 +520,6 @@ ble_hci_emspi_rx_pkt(void) } } -static void -ble_hci_emspi_set_rx_cbs(ble_hci_trans_rx_cmd_fn *cmd_cb, - void *cmd_arg, - ble_hci_trans_rx_acl_fn *acl_cb, - void *acl_arg) -{ - ble_hci_emspi_rx_cmd_cb = cmd_cb; - ble_hci_emspi_rx_cmd_arg = cmd_arg; - ble_hci_emspi_rx_acl_cb = acl_cb; - ble_hci_emspi_rx_acl_arg = acl_arg; -} - static void ble_hci_emspi_free_pkt(uint8_t type, uint8_t *cmdevt, struct os_mbuf *acl) { @@ -607,7 +529,7 @@ ble_hci_emspi_free_pkt(uint8_t type, uint8_t *cmdevt, struct os_mbuf *acl) case BLE_HCI_EMSPI_PKT_CMD: case BLE_HCI_EMSPI_PKT_EVT: - ble_hci_trans_buf_free(cmdevt); + ble_transport_free(cmdevt); break; case BLE_HCI_EMSPI_PKT_ACL: @@ -620,24 +542,6 @@ ble_hci_emspi_free_pkt(uint8_t type, uint8_t *cmdevt, struct os_mbuf *acl) } } -/** - * Unsupported. This is a host-only transport. - */ -int -ble_hci_trans_ll_evt_tx(uint8_t *cmd) -{ - return BLE_ERR_UNSUPPORTED; -} - -/** - * Unsupported. This is a host-only transport. - */ -int -ble_hci_trans_ll_acl_tx(struct os_mbuf *om) -{ - return BLE_ERR_UNSUPPORTED; -} - /** * Sends an HCI command from the host to the controller. * @@ -673,134 +577,6 @@ ble_hci_trans_hs_acl_tx(struct os_mbuf *om) return rc; } -/** - * Configures the HCI transport to call the specified callback upon receiving - * HCI packets from the controller. This function should only be called by by - * host. - * - * @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) -{ - ble_hci_emspi_set_rx_cbs(cmd_cb, cmd_arg, acl_cb, 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_ll(ble_hci_trans_rx_cmd_fn *cmd_cb, - void *cmd_arg, - ble_hci_trans_rx_acl_fn *acl_cb, - void *acl_arg) -{ - /* Unsupported. */ - assert(0); -} - -/** - * 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) -{ - uint8_t *buf; - - switch (type) { - case BLE_HCI_TRANS_BUF_CMD: - buf = os_memblock_get(&ble_hci_emspi_cmd_pool); - break; - case BLE_HCI_TRANS_BUF_EVT_HI: - buf = os_memblock_get(&ble_hci_emspi_evt_hi_pool); - if (buf == NULL) { - /* If no high-priority event buffers remain, try to grab a - * low-priority one. - */ - buf = os_memblock_get(&ble_hci_emspi_evt_lo_pool); - } - break; - - case BLE_HCI_TRANS_BUF_EVT_LO: - buf = os_memblock_get(&ble_hci_emspi_evt_lo_pool); - break; - - default: - assert(0); - buf = NULL; - } - - return buf; -} - -/** - * 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) -{ - int rc; - - if (buf != NULL) { - if (os_memblock_from(&ble_hci_emspi_evt_hi_pool, buf)) { - rc = os_memblock_put(&ble_hci_emspi_evt_hi_pool, buf); - assert(rc == 0); - } else if (os_memblock_from(&ble_hci_emspi_evt_lo_pool, buf)) { - rc = os_memblock_put(&ble_hci_emspi_evt_lo_pool, buf); - assert(rc == 0); - } else { - assert(os_memblock_from(&ble_hci_emspi_cmd_pool, buf)); - rc = os_memblock_put(&ble_hci_emspi_cmd_pool, buf); - assert(rc == 0); - } - } -} - -/** - * Configures a callback to get executed whenever an ACL data packet is freed. - * The function is called in lieu of actually freeing the packet. - * - * @param cb The callback to configure. - * - * @return 0 on success. - */ -int -ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg) -{ - ble_hci_emspi_acl_pool.mpe_put_cb = cb; - ble_hci_emspi_acl_pool.mpe_put_arg = arg; - return 0; -} - /** * Resets the HCI UART transport to a clean state. Frees all buffers and * reconfigures the UART. @@ -875,69 +651,22 @@ ble_hci_emspi_init_hw(void) hal_gpio_write(MYNEWT_VAL(BLE_HCI_EMSPI_RESET_PIN), 1); } -/** - * Initializes the UART HCI transport module. - * - * @return 0 on success; - * A BLE_ERR_[...] error code on failure. - */ void -ble_hci_emspi_init(void) +ble_transport_ll_init(void) { int rc; /* Ensure this function only gets called by sysinit. */ SYSINIT_ASSERT_ACTIVE(); - rc = os_mempool_ext_init(&ble_hci_emspi_acl_pool, - MYNEWT_VAL(BLE_ACL_BUF_COUNT), - ACL_BLOCK_SIZE, - ble_hci_emspi_acl_buf, - "ble_hci_emspi_acl_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mbuf_pool_init(&ble_hci_emspi_acl_mbuf_pool, - &ble_hci_emspi_acl_pool.mpe_mp, - ACL_BLOCK_SIZE, - MYNEWT_VAL(BLE_ACL_BUF_COUNT)); - SYSINIT_PANIC_ASSERT(rc == 0); - - /* - * Create memory pool of HCI command buffers. NOTE: we currently dont - * allow this to be configured. The controller will only allow one - * outstanding command. We decided to keep this a pool in case we allow - * allow the controller to handle more than one outstanding command. - */ - rc = os_mempool_init(&ble_hci_emspi_cmd_pool, - 1, - BLE_HCI_TRANS_CMD_SZ, - ble_hci_emspi_cmd_buf, - "ble_hci_emspi_cmd_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&ble_hci_emspi_evt_hi_pool, - MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - ble_hci_emspi_evt_hi_buf, - "ble_hci_emspi_evt_hi_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&ble_hci_emspi_evt_lo_pool, - MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - ble_hci_emspi_evt_lo_buf, - "ble_hci_emspi_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. + * buffers should be, at least, 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_emspi_pkt_pool, - BLE_HCI_EMSPI_PKT_EVT_COUNT + 1 + - MYNEWT_VAL(BLE_HCI_ACL_OUT_COUNT), + rc = os_mempool_init(&ble_hci_emspi_pkt_pool, 1 + + MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_HS_COUNT), sizeof (struct ble_hci_emspi_pkt), ble_hci_emspi_pkt_buf, "ble_hci_emspi_pkt_pool"); @@ -955,3 +684,15 @@ ble_hci_emspi_init(void) MYNEWT_VAL(BLE_HCI_EMSPI_STACK_SIZE)); SYSINIT_PANIC_ASSERT(rc == 0); } + +int +ble_transport_to_ll_cmd(void *buf) +{ + return ble_hci_emspi_cmdevt_tx(buf, BLE_HCI_EMSPI_PKT_CMD); +} + +int +ble_transport_to_ll_acl(struct os_mbuf *om) +{ + return ble_hci_emspi_acl_tx(om); +} \ No newline at end of file diff --git a/nimble/transport/emspi/syscfg.yml b/nimble/transport/emspi/syscfg.yml index 501175467a..05e6e14b10 100644 --- a/nimble/transport/emspi/syscfg.yml +++ b/nimble/transport/emspi/syscfg.yml @@ -72,13 +72,3 @@ syscfg.defs: description: > Sysinit stage for the EMSPI BLE transport. value: 100 - -syscfg.vals.'!BLE_HCI_BRIDGE && BLE_EXT_ADV': - BLE_HCI_EVT_BUF_SIZE: 257 - -syscfg.vals.'!BLE_HCI_BRIDGE && !BLE_EXT_ADV': - BLE_HCI_EVT_HI_BUF_COUNT: 2 - BLE_HCI_EVT_LO_BUF_COUNT: 8 - BLE_HCI_EVT_BUF_SIZE: 70 - BLE_ACL_BUF_COUNT: 4 - BLE_ACL_BUF_SIZE: 255 diff --git a/nimble/transport/pkg.yml b/nimble/transport/pkg.yml index e5dad56aca..bedcb160e8 100644 --- a/nimble/transport/pkg.yml +++ b/nimble/transport/pkg.yml @@ -32,6 +32,8 @@ pkg.deps.'BLE_TRANSPORT_HS == "native"': - nimble/host pkg.deps.'BLE_TRANSPORT_LL == "native"': - nimble/controller +pkg.deps.'BLE_TRANSPORT_LL == "emspi"': + - nimble/transport/emspi pkg.deps.'BLE_TRANSPORT_HS == "dialog_cmac" || BLE_TRANSPORT_LL == "dialog_cmac"': - nimble/transport/dialog_cmac pkg.deps.'BLE_TRANSPORT_HS == "nrf5340" || BLE_TRANSPORT_LL == "nrf5340"': diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml index cb9e07e7ff..5f61a0193d 100644 --- a/nimble/transport/syscfg.yml +++ b/nimble/transport/syscfg.yml @@ -40,6 +40,7 @@ syscfg.defs: value: native choices: - native + - emspi - dialog_cmac - nrf5340 - socket From 4ba36ff76fa5e448bcc72c927e94a1340707f40b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 3 Mar 2022 18:06:48 +0100 Subject: [PATCH 0341/1333] nimble/transport: Remove RAM transport Not needed anymore, "native" transport does not need any extra code. --- .../ram/include/transport/ram/ble_hci_ram.h | 35 --- nimble/transport/ram/pkg.yml | 36 --- nimble/transport/ram/src/ble_hci_ram.c | 238 ------------------ nimble/transport/ram/syscfg.yml | 33 --- 4 files changed, 342 deletions(-) delete mode 100644 nimble/transport/ram/include/transport/ram/ble_hci_ram.h delete mode 100644 nimble/transport/ram/pkg.yml delete mode 100644 nimble/transport/ram/src/ble_hci_ram.c delete mode 100644 nimble/transport/ram/syscfg.yml diff --git a/nimble/transport/ram/include/transport/ram/ble_hci_ram.h b/nimble/transport/ram/include/transport/ram/ble_hci_ram.h deleted file mode 100644 index 3c37e329c1..0000000000 --- a/nimble/transport/ram/include/transport/ram/ble_hci_ram.h +++ /dev/null @@ -1,35 +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_BLE_HCI_RAM_ -#define H_BLE_HCI_RAM_ - -#include "nimble/ble_hci_trans.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void ble_hci_ram_init(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/nimble/transport/ram/pkg.yml b/nimble/transport/ram/pkg.yml deleted file mode 100644 index bb8397bf36..0000000000 --- a/nimble/transport/ram/pkg.yml +++ /dev/null @@ -1,36 +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. -# - -pkg.name: nimble/transport/ram -pkg.description: XXX -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth - -pkg.deps: - - "@apache-mynewt-core/kernel/os" - - nimble - -pkg.apis: - - ble_transport - -pkg.init: - ble_hci_ram_init: 'MYNEWT_VAL(BLE_TRANS_RAM_SYSINIT_STAGE)' diff --git a/nimble/transport/ram/src/ble_hci_ram.c b/nimble/transport/ram/src/ble_hci_ram.c deleted file mode 100644 index 3f10e9df73..0000000000 --- a/nimble/transport/ram/src/ble_hci_ram.c +++ /dev/null @@ -1,238 +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. - */ - -#include -#include -#include -#include "syscfg/syscfg.h" -#include "sysinit/sysinit.h" -#include "os/os.h" -#include "mem/mem.h" -#include "nimble/ble.h" -#include "nimble/ble_hci_trans.h" -#include "transport/ram/ble_hci_ram.h" - -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_cmd_pool; -static os_membuf_t ble_hci_ram_cmd_buf[ - OS_MEMPOOL_SIZE(1, BLE_HCI_TRANS_CMD_SZ) -]; - -static struct os_mempool ble_hci_ram_evt_hi_pool; -static os_membuf_t ble_hci_ram_evt_hi_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) -]; - -static struct os_mempool ble_hci_ram_evt_lo_pool; -static os_membuf_t ble_hci_ram_evt_lo_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) -]; - -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_CMD: - buf = os_memblock_get(&ble_hci_ram_cmd_pool); - break; - - case BLE_HCI_TRANS_BUF_EVT_HI: - buf = os_memblock_get(&ble_hci_ram_evt_hi_pool); - if (buf == NULL) { - /* If no high-priority event buffers remain, try to grab a - * low-priority one. - */ - buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); - } - break; - - case BLE_HCI_TRANS_BUF_EVT_LO: - buf = os_memblock_get(&ble_hci_ram_evt_lo_pool); - break; - - default: - assert(0); - buf = NULL; - } - - return buf; -} - -void -ble_hci_trans_buf_free(uint8_t *buf) -{ - int rc; - - /* XXX: this may look a bit odd, but the controller uses the command - * buffer to send back the command complete/status as an immediate - * response to the command. This was done to insure that the controller - * could always send back one of these events when a command was received. - * Thus, we check to see which pool the buffer came from so we can free - * it to the appropriate pool - */ - if (os_memblock_from(&ble_hci_ram_evt_hi_pool, buf)) { - rc = os_memblock_put(&ble_hci_ram_evt_hi_pool, buf); - assert(rc == 0); - } else if (os_memblock_from(&ble_hci_ram_evt_lo_pool, buf)) { - rc = os_memblock_put(&ble_hci_ram_evt_lo_pool, buf); - assert(rc == 0); - } else { - assert(os_memblock_from(&ble_hci_ram_cmd_pool, buf)); - rc = os_memblock_put(&ble_hci_ram_cmd_pool, buf); - assert(rc == 0); - } -} - -/** - * Unsupported; the RAM transport does not have a dedicated ACL data packet - * pool. - */ -int -ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_hci_trans_reset(void) -{ - /* No work to do. All allocated buffers are owned by the host or - * controller, and they will get freed by their owners. - */ - return 0; -} - -void -ble_hci_ram_init(void) -{ - int rc; - - /* Ensure this function only gets called by sysinit. */ - SYSINIT_ASSERT_ACTIVE(); - - /* - * Create memory pool of HCI command buffers. NOTE: we currently dont - * allow this to be configured. The controller will only allow one - * outstanding command. We decided to keep this a pool in case we allow - * allow the controller to handle more than one outstanding command. - */ - rc = os_mempool_init(&ble_hci_ram_cmd_pool, - 1, - BLE_HCI_TRANS_CMD_SZ, - ble_hci_ram_cmd_buf, - "ble_hci_ram_cmd_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&ble_hci_ram_evt_hi_pool, - MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - ble_hci_ram_evt_hi_buf, - "ble_hci_ram_evt_hi_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&ble_hci_ram_evt_lo_pool, - MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - ble_hci_ram_evt_lo_buf, - "ble_hci_ram_evt_lo_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); -} diff --git a/nimble/transport/ram/syscfg.yml b/nimble/transport/ram/syscfg.yml deleted file mode 100644 index 6286dfe722..0000000000 --- a/nimble/transport/ram/syscfg.yml +++ /dev/null @@ -1,33 +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. -# - -syscfg.defs: - BLE_TRANS_RAM_SYSINIT_STAGE: - description: > - Sysinit stage for the RAM BLE transport. - value: 100 - -syscfg.vals: - BLE_HCI_EVT_HI_BUF_COUNT: 2 - BLE_HCI_EVT_LO_BUF_COUNT: 8 - BLE_HCI_EVT_BUF_SIZE: 70 - BLE_ACL_BUF_COUNT: 4 - BLE_ACL_BUF_SIZE: 65535 - -syscfg.vals.BLE_EXT_ADV: - BLE_HCI_EVT_BUF_SIZE: 257 From 0e2bb74f816d0534f4a44b9359c1320a6d391013 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 5 Mar 2022 17:37:34 +0100 Subject: [PATCH 0342/1333] nimble/transport: Remove da1469x transport We do not need transport for proprietary controller provided by Dialog since we can run our own controller on CMAC. --- nimble/transport/da1469x/.gitignore | 2 - nimble/transport/da1469x/README | 13 - .../include/cmac_driver/cmac_host.h | 37 -- nimble/transport/da1469x/cmac_driver/pkg.yml | 27 -- .../cmac_driver/scripts/build_libcmac.sh | 51 --- .../da1469x/cmac_driver/src/cmac_host.c | 326 ---------------- .../transport/da1469x/cmac_driver/syscfg.yml | 23 -- nimble/transport/da1469x/pkg.yml | 38 -- .../transport/da1469x/src/da1469x_ble_hci.c | 368 ------------------ nimble/transport/da1469x/syscfg.yml | 27 -- 10 files changed, 912 deletions(-) delete mode 100644 nimble/transport/da1469x/.gitignore delete mode 100644 nimble/transport/da1469x/README delete mode 100644 nimble/transport/da1469x/cmac_driver/include/cmac_driver/cmac_host.h delete mode 100644 nimble/transport/da1469x/cmac_driver/pkg.yml delete mode 100755 nimble/transport/da1469x/cmac_driver/scripts/build_libcmac.sh delete mode 100644 nimble/transport/da1469x/cmac_driver/src/cmac_host.c delete mode 100644 nimble/transport/da1469x/cmac_driver/syscfg.yml delete mode 100644 nimble/transport/da1469x/pkg.yml delete mode 100644 nimble/transport/da1469x/src/da1469x_ble_hci.c delete mode 100644 nimble/transport/da1469x/syscfg.yml diff --git a/nimble/transport/da1469x/.gitignore b/nimble/transport/da1469x/.gitignore deleted file mode 100644 index bba9f995af..0000000000 --- a/nimble/transport/da1469x/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/src/libble_stack_da1469x.a - diff --git a/nimble/transport/da1469x/README b/nimble/transport/da1469x/README deleted file mode 100644 index b30a01c48a..0000000000 --- a/nimble/transport/da1469x/README +++ /dev/null @@ -1,13 +0,0 @@ -Integrated BLE Controller (CMAC) requires a binary firmware to be loaded. Such -firmware is distributed by Dialog Semiconductor in SDK package which has to be -obtained separately, see: -https://www.dialog-semiconductor.com/products/da1469x-product-family - -Firmware is available as part of following library in SDK package: -sdk/interfaces/ble/binaries/DA1469x-Release/libble_stack_da1469x.a - -By default, CMAC driver will look for this file in its package root directory -(i.e. nimble/transport/da1469x/cmac_driver) but this can be changed using -CMAC_IMAGE_FILE_NAME syscfg variable. - -Current version of CMAC driver was tested with SDK version 10.0.4.66. diff --git a/nimble/transport/da1469x/cmac_driver/include/cmac_driver/cmac_host.h b/nimble/transport/da1469x/cmac_driver/include/cmac_driver/cmac_host.h deleted file mode 100644 index f623a48a99..0000000000 --- a/nimble/transport/da1469x/cmac_driver/include/cmac_driver/cmac_host.h +++ /dev/null @@ -1,37 +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 __CMAC_HOST_H_ -#define __CMAC_HOST_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef int (* cmac_mbox_read_cb)(const uint8_t *, uint16_t len); - -void cmac_host_init(void); -void cmac_mbox_write(const uint8_t *buf, size_t len); -void cmac_mbox_set_read_cb(cmac_mbox_read_cb cb); - -#ifdef __cplusplus -} -#endif - -#endif /* __CMAC_HOST_H_ */ diff --git a/nimble/transport/da1469x/cmac_driver/pkg.yml b/nimble/transport/da1469x/cmac_driver/pkg.yml deleted file mode 100644 index 90a8931865..0000000000 --- a/nimble/transport/da1469x/cmac_driver/pkg.yml +++ /dev/null @@ -1,27 +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. -# - -pkg.name: nimble/transport/da1469x/cmac_driver -pkg.description: Driver for Dialog's BLE controller -pkg.author: -pkg.homepage: -pkg.keywords: - -pkg.pre_link_cmds.BLE_HOST: - scripts/build_libcmac.sh: 100 diff --git a/nimble/transport/da1469x/cmac_driver/scripts/build_libcmac.sh b/nimble/transport/da1469x/cmac_driver/scripts/build_libcmac.sh deleted file mode 100755 index 659c2b9f34..0000000000 --- a/nimble/transport/da1469x/cmac_driver/scripts/build_libcmac.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash - -# 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. - -if [ ! -f ${MYNEWT_VAL_CMAC_IMAGE_FILE_NAME} ]; then - >&2 echo ERROR: BLE stack library not found. Please check nimble/transport/da1469x/README for details. - exit 1 -fi - -OBJCOPY=${MYNEWT_OBJCOPY_PATH} -AR=${MYNEWT_AR_PATH} -LIBBLE_A=$(readlink -e ${MYNEWT_VAL_CMAC_IMAGE_FILE_NAME}) -LIBCMAC_A=${MYNEWT_USER_SRC_DIR}/libcmac.a - -BASENAME_ROM=cmac.rom -BASENAME_RAM=cmac.ram - -cd ${MYNEWT_USER_WORK_DIR} - -# Extract firmware binary from .a since we do not need to link all other -# objects with our image. -${AR} x ${LIBBLE_A} cmac_fw.c.obj -${OBJCOPY} -O binary --only-section=.cmi_fw_area cmac_fw.c.obj cmac.bin - -# We need separate copies for RAM and ROM image since section names are derived -# from file names. For now files are the same, but it would be possible to -# link ROM image without data and shared sections which contains zeroes anyway. -cp cmac.bin ${BASENAME_ROM}.bin -cp cmac.bin ${BASENAME_RAM}.bin - -# Convert both binaries to objects and create archive to link -${OBJCOPY} -I binary -O elf32-littlearm -B armv8-m.main \ - --rename-section .data=.libcmac.rom ${BASENAME_ROM}.bin ${BASENAME_ROM}.o -${OBJCOPY} -I binary -O elf32-littlearm -B armv8-m.main \ - --rename-section .data=.libcmac.ram ${BASENAME_RAM}.bin ${BASENAME_RAM}.o -${AR} -rcs ${LIBCMAC_A} ${BASENAME_ROM}.o ${BASENAME_RAM}.o diff --git a/nimble/transport/da1469x/cmac_driver/src/cmac_host.c b/nimble/transport/da1469x/cmac_driver/src/cmac_host.c deleted file mode 100644 index 0bfb715e55..0000000000 --- a/nimble/transport/da1469x/cmac_driver/src/cmac_host.c +++ /dev/null @@ -1,326 +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. - */ - -#include -#include -#include -#include -#include "os/os.h" -#include "mcu/cmsis_nvic.h" -#include "mcu/da1469x_lpclk.h" -#include "mcu/da1469x_hal.h" -#include "mcu/da1469x_pdc.h" -#include "mcu/mcu.h" -#include "cmac_driver/cmac_host.h" - -#define CMAC_SYM_CONFIG ((void *)(0x00818f20 + MEMCTRL->CMI_CODE_BASE_REG)) -#define CMAC_SYM_CONFIG_DYN ((void *)(0x00821af8 + MEMCTRL->CMI_CODE_BASE_REG)) -#define CMAC_SYM_MBOX_RX ((void *)(0x008216b0 + MEMCTRL->CMI_CODE_BASE_REG)) -#define CMAC_SYM_MBOX_TX ((void *)(0x008218b0 + MEMCTRL->CMI_CODE_BASE_REG)) - -#define CMAC_MBOX_SIZE 504 -#define CMAC_MBOX_F_RESET 0x0008 -#define CMAC_MBOX_F_WRITEPENDING 0x0010 - -struct cmac_config { - uint8_t bdaddr[6]; /* Device address */ - - uint8_t rf_calibration_delay; - - uint8_t lp_clock_freq; /* Sleep clock frequency (0 = 32768Hz, 1 = 32000Hz) */ - uint16_t lp_clock_sca; /* Sleep clock accuracy [ppm] */ - - uint16_t rx_buf_len; /* RX buffer size */ - uint16_t tx_buf_len; /* TX buffer size */ - bool initial_length_req; - - /* Channel assessment algorithm settings */ - uint16_t chan_assess_itvl; - uint8_t chan_assess_itvl_mult; - int8_t chan_assess_min_rssi; - uint16_t chan_assess_pkt_num; - uint16_t chan_assess_bad_pkt_num; - - /* Calibration settings */ - uint8_t system_tcs_length; - uint8_t synth_tcs_length; - uint8_t rfcu_tcs_length; - - uint8_t default_tx_power; /* Default TX power for connection/advertising */ - bool filter_dup_ov_discard; /* Discard unknown devices when filter buffer is full */ - bool use_hp_1m; - bool use_hp_2m; -}; - -struct cmac_config_dynamic { - bool enable_sleep; /* Enable sleep */ - - /* More options here, don't care now */ -}; - -struct cmac_mbox { - volatile uint16_t magic; - volatile uint16_t flags; - volatile uint16_t wr_off; - volatile uint16_t rd_off; - uint8_t data[CMAC_MBOX_SIZE]; -}; - -/* CMAC data */ -extern char _binary_cmac_rom_bin_start[]; -extern char _binary_cmac_rom_bin_end; -extern char _binary_cmac_ram_bin_start[]; -extern char _binary_cmac_ram_bin_end; - -struct cmac_image_info { - uint32_t _dummy1; - uint32_t size_rom; - uint32_t _dummy2; - uint32_t magic; - uint32_t _dummy3[5]; -}; - -/* Mailboxes for SYS<->CMAC communication */ -static struct cmac_mbox *cmac_mbox_rx; -static struct cmac_mbox *cmac_mbox_tx; - -/* PDC entry for waking up CMAC */ -static int8_t g_cmac_host_pdc_sys2cmac; -/* PDC entry for waking up M33 */ -static int8_t g_cmac_host_pdc_cmac2sys; -/* Callback for data ready from CMAC */ -static cmac_mbox_read_cb g_cmac_mbox_read_cb; - -static inline void -cmac_host_signal2cmac(void) -{ - da1469x_pdc_set(g_cmac_host_pdc_sys2cmac); -} - -static void -cmac2sys_isr(void) -{ - uint16_t wr_off; - uint16_t rd_off; - uint16_t chunk; - uint16_t len; - - os_trace_isr_enter(); - - /* Clear CMAC2SYS interrupt */ - *(volatile uint32_t *)0x40002000 = 2; - - if (*(volatile uint32_t *)0x40002000 & 0x1c00) { - /* XXX CMAC is in error state, need to recover */ - assert(0); - } - - if (cmac_mbox_rx->flags & CMAC_MBOX_F_RESET) { - cmac_mbox_rx->flags &= ~CMAC_MBOX_F_RESET; - goto done; - } - - if (!g_cmac_mbox_read_cb) { - cmac_mbox_rx->rd_off = cmac_mbox_rx->wr_off; - goto done; - } - - do { - rd_off = cmac_mbox_rx->rd_off; - wr_off = cmac_mbox_rx->wr_off; - - if (rd_off <= wr_off) { - chunk = wr_off - rd_off; - } else { - chunk = CMAC_MBOX_SIZE - rd_off; - } - - while (chunk) { - len = g_cmac_mbox_read_cb(&cmac_mbox_rx->data[rd_off], chunk); - - rd_off += len; - chunk -= len; - }; - - cmac_mbox_rx->rd_off = rd_off % CMAC_MBOX_SIZE; - } while (cmac_mbox_rx->rd_off != cmac_mbox_rx->wr_off); - -done: - - if (cmac_mbox_rx->flags & CMAC_MBOX_F_WRITEPENDING) { - cmac_host_signal2cmac(); - } - - os_trace_isr_exit(); -} - -static void -cmac_host_lpclk_cb(uint32_t freq) -{ - struct cmac_config_dynamic *cmac_config_dyn; - - cmac_config_dyn = CMAC_SYM_CONFIG_DYN; - cmac_config_dyn->enable_sleep = freq == 32768; -} - -void -cmac_mbox_write(const uint8_t *buf, size_t len) -{ - uint16_t wr_off; - uint16_t rd_off; - uint16_t chunk; - uint32_t primask; - - __HAL_DISABLE_INTERRUPTS(primask); - - while (len) { - rd_off = cmac_mbox_tx->rd_off; - wr_off = cmac_mbox_tx->wr_off; - - if (rd_off > wr_off) { - chunk = min(len, rd_off - wr_off); - } else { - chunk = min(len, CMAC_MBOX_SIZE - wr_off); - } - - if (chunk == 0) { - continue; - } - - memcpy(&cmac_mbox_tx->data[wr_off], buf, chunk); - - wr_off += chunk; - cmac_mbox_tx->wr_off = wr_off % CMAC_MBOX_SIZE; - - cmac_host_signal2cmac(); - - len -= chunk; - buf += chunk; - } - - __HAL_ENABLE_INTERRUPTS(primask); -} - -void -cmac_mbox_set_read_cb(cmac_mbox_read_cb cb) -{ - g_cmac_mbox_read_cb = cb; -} - -void -cmac_host_init(void) -{ - struct cmac_image_info ii; - uint32_t cmac_rom_size; - uint32_t cmac_ram_size; - struct cmac_config *cmac_config; - struct cmac_config_dynamic *cmac_config_dyn; - - /* Add PDC entry to wake up CMAC from M33 */ - g_cmac_host_pdc_sys2cmac = da1469x_pdc_add(MCU_PDC_TRIGGER_MAC_TIMER, - MCU_PDC_MASTER_CMAC, - MCU_PDC_EN_XTAL); - da1469x_pdc_set(g_cmac_host_pdc_sys2cmac); - da1469x_pdc_ack(g_cmac_host_pdc_sys2cmac); - - /* Add PDC entry to wake up M33 from CMAC, if does not exist yet */ - g_cmac_host_pdc_cmac2sys = da1469x_pdc_find(MCU_PDC_TRIGGER_COMBO, - MCU_PDC_MASTER_M33, 0); - if (g_cmac_host_pdc_cmac2sys < 0) { - g_cmac_host_pdc_cmac2sys = da1469x_pdc_add(MCU_PDC_TRIGGER_COMBO, - MCU_PDC_MASTER_M33, - MCU_PDC_EN_XTAL); - da1469x_pdc_set(g_cmac_host_pdc_cmac2sys); - da1469x_pdc_ack(g_cmac_host_pdc_cmac2sys); - } - - /* Enable Radio LDO */ - CRG_TOP->POWER_CTRL_REG |= CRG_TOP_POWER_CTRL_REG_LDO_RADIO_ENABLE_Msk; - - /* Enable CMAC, but keep it in reset */ - CRG_TOP->CLK_RADIO_REG = (1 << CRG_TOP_CLK_RADIO_REG_RFCU_ENABLE_Pos) | - (1 << CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Pos) | - (0 << CRG_TOP_CLK_RADIO_REG_CMAC_CLK_SEL_Pos) | - (1 << CRG_TOP_CLK_RADIO_REG_CMAC_CLK_ENABLE_Pos) | - (0 << CRG_TOP_CLK_RADIO_REG_CMAC_DIV_Pos); - - /* Calculate size of ROM and RAM area (for now they should be the same) */ - cmac_rom_size = &_binary_cmac_rom_bin_end - &_binary_cmac_rom_bin_start[0]; - cmac_ram_size = &_binary_cmac_ram_bin_end - &_binary_cmac_ram_bin_start[0]; - assert(cmac_rom_size == cmac_ram_size); - - /* Load image header and check if image can be loaded */ - memcpy(&ii, &_binary_cmac_rom_bin_start, sizeof(ii)); - assert(ii.magic == 0x43414d43); /* "CMAC" */ - - /* Copy CMAC image to RAM */ - memset(&_binary_cmac_ram_bin_start, 0, cmac_ram_size); - memcpy(&_binary_cmac_ram_bin_start, &_binary_cmac_rom_bin_start[sizeof(ii)], - ii.size_rom); - - /* - * Setup memory controller for CMAC - * Code and data are set to the same address initially since CMAC will - * update data address on init. Also shared address is updated on init. - */ - MEMCTRL->CMI_CODE_BASE_REG = (uint32_t)&_binary_cmac_ram_bin_start; - MEMCTRL->CMI_DATA_BASE_REG = MEMCTRL->CMI_CODE_BASE_REG; - MEMCTRL->CMI_SHARED_BASE_REG = 0; - MEMCTRL->CMI_END_REG = (uint32_t)&_binary_cmac_ram_bin_end; - - /* Symbols below are in shared memory, can update them now */ - cmac_config = CMAC_SYM_CONFIG; - cmac_config_dyn = CMAC_SYM_CONFIG_DYN; - cmac_mbox_rx = CMAC_SYM_MBOX_RX; - cmac_mbox_tx = CMAC_SYM_MBOX_TX; - - /* Update CMAC configuration */ - cmac_config->lp_clock_freq = 0; - cmac_config->lp_clock_sca = 50; - cmac_config->rx_buf_len = 251 + 11; - cmac_config->tx_buf_len = 251 + 11; - cmac_config->initial_length_req = 0; - cmac_config->system_tcs_length = 0; - cmac_config->synth_tcs_length = 0; - cmac_config->rfcu_tcs_length = 0; - cmac_config->default_tx_power = 4; - cmac_config_dyn->enable_sleep = false; - - /* Release CMAC from reset */ - CRG_TOP->CLK_RADIO_REG &= ~CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Msk; - - /* Wait for CMAC to update registers */ - while (MEMCTRL->CMI_DATA_BASE_REG == MEMCTRL->CMI_CODE_BASE_REG); - while (MEMCTRL->CMI_SHARED_BASE_REG != (MEMCTRL->CMI_END_REG & 0xfffffc00)); - - /* Initialize mailboxes and sync with CMAC */ - cmac_mbox_tx->flags = CMAC_MBOX_F_RESET; - cmac_mbox_tx->wr_off = 0; - cmac_mbox_tx->rd_off = 0; - cmac_mbox_tx->magic = 0xa55a; - while (cmac_mbox_rx->magic != 0xa55a); - - NVIC_SetVector(CMAC2SYS_IRQn, (uint32_t)cmac2sys_isr); - NVIC_SetPriority(CMAC2SYS_IRQn, 0); - NVIC_EnableIRQ(CMAC2SYS_IRQn); - - cmac_host_signal2cmac(); - - da1469x_lpclk_register_cmac_cb(cmac_host_lpclk_cb); -} diff --git a/nimble/transport/da1469x/cmac_driver/syscfg.yml b/nimble/transport/da1469x/cmac_driver/syscfg.yml deleted file mode 100644 index be2e62d900..0000000000 --- a/nimble/transport/da1469x/cmac_driver/syscfg.yml +++ /dev/null @@ -1,23 +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. -# - -syscfg.defs: - CMAC_IMAGE_FILE_NAME: - description: > - Path to library with CMAC firmware. See README for details. - value: "libble_stack_da1469x.a" diff --git a/nimble/transport/da1469x/pkg.yml b/nimble/transport/da1469x/pkg.yml deleted file mode 100644 index 5d9b533cfb..0000000000 --- a/nimble/transport/da1469x/pkg.yml +++ /dev/null @@ -1,38 +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. -# - -pkg.name: nimble/transport/da1469x -pkg.description: HCI transport for DA1469x -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth - -pkg.deps: - - "@apache-mynewt-nimble/nimble" - - "@apache-mynewt-nimble/nimble/transport/da1469x/cmac_driver" - - "@apache-mynewt-core/kernel/os" - -pkg.apis: - - ble_transport - -pkg.init: - da1469x_ble_hci_init: 100 - da1469x_ble_hci_cmac_init: 201 diff --git a/nimble/transport/da1469x/src/da1469x_ble_hci.c b/nimble/transport/da1469x/src/da1469x_ble_hci.c deleted file mode 100644 index 971d0cd047..0000000000 --- a/nimble/transport/da1469x/src/da1469x_ble_hci.c +++ /dev/null @@ -1,368 +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. - */ - -#include -#include -#include "os/mynewt.h" -#include "nimble/ble.h" -#include "nimble/ble_hci_trans.h" -#include "nimble/hci_common.h" -#include "cmac_driver/cmac_host.h" - -#define HCI_PKT_NONE 0x00 -#define HCI_PKT_CMD 0x01 -#define HCI_PKT_ACL 0x02 -#define HCI_PKT_EVT 0x04 - -#define POOL_ACL_BLOCK_SIZE \ - OS_ALIGN(MYNEWT_VAL(BLE_ACL_BUF_SIZE) + \ - BLE_MBUF_MEMBLOCK_OVERHEAD + \ - BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT) - -struct da1469x_ble_hci_host_api { - ble_hci_trans_rx_cmd_fn *evt_cb; - void *evt_arg; - ble_hci_trans_rx_acl_fn *acl_cb; - void *acl_arg; -}; - -struct da1469x_ble_hci_rx_data { - uint8_t type; - uint8_t hdr[4]; - uint8_t min_len; - uint16_t len; - uint16_t expected_len; - union { - uint8_t *buf; - struct os_mbuf *om; - }; -}; - -struct da1469x_ble_hci_pool_cmd { - uint8_t cmd[BLE_HCI_TRANS_CMD_SZ]; - bool allocated; -}; - -/* (Pseudo)pool for HCI commands */ -static struct da1469x_ble_hci_pool_cmd da1469x_ble_hci_pool_cmd; - -/* Pools for HCI events (high and low priority) */ -static uint8_t da1469x_ble_hci_pool_evt_hi_buf[ OS_MEMPOOL_BYTES( - MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) ]; -static struct os_mempool da1469x_ble_hci_pool_evt_hi; -static uint8_t da1469x_ble_hci_pool_evt_lo_buf[ OS_MEMPOOL_BYTES( - MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) ]; -static struct os_mempool da1469x_ble_hci_pool_evt_lo; - -/* Pool for ACL data */ -static uint8_t da1469x_ble_hci_pool_acl_buf[ OS_MEMPOOL_BYTES( - MYNEWT_VAL(BLE_ACL_BUF_COUNT), - POOL_ACL_BLOCK_SIZE) ]; -static struct os_mempool da1469x_ble_hci_pool_acl; -static struct os_mbuf_pool da1469x_ble_hci_pool_acl_mbuf; - -/* Interface to host */ -static struct da1469x_ble_hci_host_api da1469x_ble_hci_host_api; - -/* State of RX currently in progress (needs to reassemble frame) */ -static struct da1469x_ble_hci_rx_data da1469x_ble_hci_rx_data; - -int -ble_hci_trans_reset(void) -{ - /* XXX Should we do something with RF and/or BLE core? */ - return 0; -} - -void -ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *evt_cb, void *evt_arg, - ble_hci_trans_rx_acl_fn *acl_cb, void *acl_arg) -{ - da1469x_ble_hci_host_api.evt_cb = evt_cb; - da1469x_ble_hci_host_api.evt_arg = evt_arg; - da1469x_ble_hci_host_api.acl_cb = acl_cb; - da1469x_ble_hci_host_api.acl_arg = acl_arg; -} - -uint8_t * -ble_hci_trans_buf_alloc(int type) -{ - uint8_t *buf; - - switch (type) { - case BLE_HCI_TRANS_BUF_CMD: - assert(!da1469x_ble_hci_pool_cmd.allocated); - da1469x_ble_hci_pool_cmd.allocated = 1; - buf = da1469x_ble_hci_pool_cmd.cmd; - break; - case BLE_HCI_TRANS_BUF_EVT_HI: - buf = os_memblock_get(&da1469x_ble_hci_pool_evt_hi); - if (buf) { - break; - } - /* no break */ - case BLE_HCI_TRANS_BUF_EVT_LO: - buf = os_memblock_get(&da1469x_ble_hci_pool_evt_lo); - break; - default: - assert(0); - buf = NULL; - } - - return buf; -} - -void -ble_hci_trans_buf_free(uint8_t *buf) -{ - int rc; - - if (buf == da1469x_ble_hci_pool_cmd.cmd) { - assert(da1469x_ble_hci_pool_cmd.allocated); - da1469x_ble_hci_pool_cmd.allocated = 0; - } else if (os_memblock_from(&da1469x_ble_hci_pool_evt_hi, buf)) { - rc = os_memblock_put(&da1469x_ble_hci_pool_evt_hi, buf); - assert(rc == 0); - } else { - assert(os_memblock_from(&da1469x_ble_hci_pool_evt_lo, buf)); - rc = os_memblock_put(&da1469x_ble_hci_pool_evt_lo, buf); - assert(rc == 0); - } -} - -int -ble_hci_trans_hs_cmd_tx(uint8_t *cmd) -{ - uint8_t ind = HCI_PKT_CMD; - int len = 3 + cmd[2]; - - cmac_mbox_write(&ind, 1); - cmac_mbox_write(cmd, len); - - ble_hci_trans_buf_free(cmd); - - return 0; -} - -int -ble_hci_trans_hs_acl_tx(struct os_mbuf *om) -{ - uint8_t ind = HCI_PKT_ACL; - struct os_mbuf *x; - - cmac_mbox_write(&ind, 1); - - x = om; - while (x) { - cmac_mbox_write(x->om_data, x->om_len); - x = SLIST_NEXT(x, om_next); - } - - os_mbuf_free_chain(om); - - return 0; -} - -static int -da1469x_ble_hci_trans_ll_rx(const uint8_t *buf, uint16_t len) -{ - struct da1469x_ble_hci_rx_data *rxd = &da1469x_ble_hci_rx_data; - void *data; - int pool = BLE_HCI_TRANS_BUF_EVT_HI; - int rc; - - assert(len); - - if (rxd->type == HCI_PKT_NONE) { - rxd->type = buf[0]; - rxd->len = 0; - rxd->expected_len = 0; - - switch (rxd->type) { - case HCI_PKT_ACL: - rxd->min_len = 4; - break; - case HCI_PKT_EVT: - rxd->min_len = 2; - break; - default: - assert(0); - break; - } - - return 1; - } - - /* Ensure we have minimum length of bytes required to process header */ - if (rxd->len < rxd->min_len) { - len = min(len, rxd->min_len - rxd->len); - memcpy(&rxd->hdr[rxd->len], buf, len); - rxd->len += len; - return len; - } - - /* Parse header and allocate proper buffer if not done yet */ - if (rxd->expected_len == 0) { - switch (rxd->type) { - case HCI_PKT_ACL: - data = os_mbuf_get_pkthdr(&da1469x_ble_hci_pool_acl_mbuf, - sizeof(struct ble_mbuf_hdr)); - if (!data) { - return 0; - } - - rxd->om = data; - os_mbuf_append(rxd->om, rxd->hdr, rxd->len); - rxd->expected_len = get_le16(&rxd->hdr[2]) + 4; - break; - case HCI_PKT_EVT: - if (rxd->hdr[0] == BLE_HCI_EVCODE_LE_META) { - /* For LE Meta event we need 3 bytes to parse header */ - if (rxd->min_len < 3) { - rxd->min_len = 3; - return 0; - } - - /* Advertising reports shall be allocated from low-prio pool */ - if ((rxd->hdr[2] == BLE_HCI_LE_SUBEV_ADV_RPT) || - (rxd->hdr[2] == BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) { - pool = BLE_HCI_TRANS_BUF_EVT_LO; - } - } - - data = ble_hci_trans_buf_alloc(pool); - if (!data) { - /* - * Only care about valid buffer when shall be allocated from - * high-prio pool, otherwise NULL is fine and we'll just skip - * this event. - */ - if (pool != BLE_HCI_TRANS_BUF_EVT_LO) { - data = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); - if (!data) { - return 0; - } - } - } - - rxd->buf = data; - memcpy(rxd->buf, rxd->hdr, rxd->len); - rxd->expected_len = rxd->hdr[1] + 2; - break; - default: - assert(0); - return len; - } - } - - len = min(len, rxd->expected_len - rxd->len); - - switch (rxd->type) { - case HCI_PKT_ACL: - os_mbuf_append(rxd->om, buf, len); - rxd->len += len; - - if (rxd->len == rxd->expected_len) { - rc = da1469x_ble_hci_host_api.acl_cb(rxd->om, - da1469x_ble_hci_host_api.acl_arg); - if (rc != 0) { - os_mbuf_free_chain(rxd->om); - } - rxd->type = HCI_PKT_NONE; - } - break; - case HCI_PKT_EVT: - if (rxd->buf) { - memcpy(&rxd->buf[rxd->len], buf, len); - } - rxd->len += len; - - if (rxd->len == rxd->expected_len) { - /* - * XXX for unknown reason at startup controller sends command - * complete for a vendor specific command which we never sent - * and this messes up with our ack code - just discard this - * event - */ - if ((rxd->buf[0] == 0x0E) && (get_le16(&rxd->buf[3]) == 0xfc11)) { - ble_hci_trans_buf_free(rxd->buf); - } else if (rxd->buf) { - rc = da1469x_ble_hci_host_api.evt_cb(rxd->buf, - da1469x_ble_hci_host_api.evt_arg); - if (rc != 0) { - ble_hci_trans_buf_free(rxd->buf); - } - } - rxd->type = HCI_PKT_NONE; - } - break; - default: - assert(0); - break; - } - - return len; -} - -static int -da1469x_ble_hci_read_cb(const uint8_t *buf, uint16_t len) -{ - return da1469x_ble_hci_trans_ll_rx(buf, len); -} - -void -da1469x_ble_hci_init(void) -{ - int rc; - - SYSINIT_ASSERT_ACTIVE(); - - rc = os_mempool_init(&da1469x_ble_hci_pool_acl, MYNEWT_VAL(BLE_ACL_BUF_COUNT), - POOL_ACL_BLOCK_SIZE, da1469x_ble_hci_pool_acl_buf, - "da1469x_ble_hci_pool_acl"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mbuf_pool_init(&da1469x_ble_hci_pool_acl_mbuf, - &da1469x_ble_hci_pool_acl, POOL_ACL_BLOCK_SIZE, - MYNEWT_VAL(BLE_ACL_BUF_COUNT)); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&da1469x_ble_hci_pool_evt_hi, - MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - da1469x_ble_hci_pool_evt_hi_buf, - "da1469x_ble_hci_pool_evt_hi"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&da1469x_ble_hci_pool_evt_lo, - MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - da1469x_ble_hci_pool_evt_lo_buf, - "da1469x_ble_hci_pool_evt_lo"); - SYSINIT_PANIC_ASSERT(rc == 0); -} - -void -da1469x_ble_hci_cmac_init(void) -{ - cmac_mbox_set_read_cb(da1469x_ble_hci_read_cb); - cmac_host_init(); -} diff --git a/nimble/transport/da1469x/syscfg.yml b/nimble/transport/da1469x/syscfg.yml deleted file mode 100644 index 2ce8cd3cf2..0000000000 --- a/nimble/transport/da1469x/syscfg.yml +++ /dev/null @@ -1,27 +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. -# - -syscfg.vals.'!BLE_HCI_BRIDGE && !BLE_EXT_ADV': - BLE_HCI_EVT_HI_BUF_COUNT: 2 - BLE_HCI_EVT_LO_BUF_COUNT: 8 - BLE_HCI_EVT_BUF_SIZE: 70 - BLE_ACL_BUF_COUNT: 4 - BLE_ACL_BUF_SIZE: 255 - -syscfg.vals.'!BLE_HCI_BRIDGE && BLE_EXT_ADV': - BLE_HCI_EVT_BUF_SIZE: 274 From b44ec408820cb18c9d1ff4b6efac84322016d279 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 9 Mar 2022 22:53:20 +0100 Subject: [PATCH 0343/1333] nimble/transport: Add internal flow control This adds support for internal flow control that can be implemented by transports that work on multi-core systems (e.g. nRF5340). --- nimble/controller/src/ble_ll_conn.c | 14 +++++++++ nimble/transport/include/nimble/transport.h | 6 ++++ nimble/transport/nrf5340/syscfg.yml | 20 +++++++++++++ nimble/transport/src/transport.c | 33 +++++++++++---------- 4 files changed, 58 insertions(+), 15 deletions(-) create mode 100644 nimble/transport/nrf5340/syscfg.yml diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 138f9284f6..3be8f66fa2 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3269,6 +3269,10 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) /* Free buffer */ conn_rx_data_pdu_end: +#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) + ble_transport_int_flow_ctl_put(); +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) /* Need to give credit back if we allocated one for this PDU */ if (hdr->rxinfo.flags & BLE_MBUF_HDR_F_CONN_CREDIT) { @@ -3329,6 +3333,16 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) alloc_rxpdu = false; } +#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) + /* Do not alloc PDU if there are no free buffers in transport. We'll nak + * this PDU in LL. + */ + if (alloc_rxpdu && BLE_LL_LLID_IS_DATA(hdr_byte) && (rx_pyld_len > 0) && + !ble_transport_int_flow_ctl_get()) { + alloc_rxpdu = false; + } +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) /* * If flow control is enabled, we need to have credit available for each diff --git a/nimble/transport/include/nimble/transport.h b/nimble/transport/include/nimble/transport.h index 98dba30c60..7149d8710f 100644 --- a/nimble/transport/include/nimble/transport.h +++ b/nimble/transport/include/nimble/transport.h @@ -48,6 +48,12 @@ void ble_transport_free(void *buf); /* Register put callback on acl_from_ll mbufs (for ll-hs flow control) */ int ble_transport_register_put_acl_from_ll_cb(os_mempool_put_fn *cb); +#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) +/* To be implemented if transport supports internal flow control between cores */ +extern int ble_transport_int_flow_ctl_get(void); +extern void ble_transport_int_flow_ctl_put(void); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/transport/nrf5340/syscfg.yml b/nimble/transport/nrf5340/syscfg.yml new file mode 100644 index 0000000000..e8334f2a0a --- /dev/null +++ b/nimble/transport/nrf5340/syscfg.yml @@ -0,0 +1,20 @@ +# 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. +# + +syscfg.defs: + BLE_TRANSPORT_INT_FLOW_CTL: 1 diff --git a/nimble/transport/src/transport.c b/nimble/transport/src/transport.c index 7c868f12ad..1eea5adcee 100644 --- a/nimble/transport/src/transport.c +++ b/nimble/transport/src/transport.c @@ -152,30 +152,33 @@ ble_transport_acl_put(struct os_mempool_ext *mpe, void *data, void *arg) { struct os_mbuf *om; struct os_mbuf_pkthdr *pkthdr; + bool do_put; + bool from_ll; os_error_t err; om = data; pkthdr = OS_MBUF_PKTHDR(om); - switch (pkthdr->omp_flags & OMP_FLAG_FROM_MASK) { - case OMP_FLAG_FROM_LL: - if (transport_put_acl_from_ll_cb) { - return transport_put_acl_from_ll_cb(mpe, data, arg); - } - break; - case OMP_FLAG_FROM_HS: - break; - default: - assert(0); - break; + do_put = true; + from_ll = (pkthdr->omp_flags & OMP_FLAG_FROM_MASK) == OMP_FLAG_FROM_LL; + err = 0; + + if (from_ll && transport_put_acl_from_ll_cb) { + err = transport_put_acl_from_ll_cb(mpe, data, arg); + do_put = false; } - err = os_memblock_put_from_cb(&mpe->mpe_mp, data); - if (err) { - return err; + if (do_put) { + err = os_memblock_put_from_cb(&mpe->mpe_mp, data); } - return 0; +#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) + if (from_ll && !err) { + ble_transport_int_flow_ctl_put(); + } +#endif + + return err; } void From f5a26ab05c55b4dd5d54f62e5001577743e8f8e0 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 5 Mar 2022 17:34:03 +0100 Subject: [PATCH 0344/1333] babblesim/edtt: Update EDTT transport --- babblesim/edtt/hci_test/syscfg.yml | 4 +- babblesim/edtt/hci_transport/pkg.yml | 5 +- .../edtt/hci_transport/src/ble_hci_edtt.c | 277 ++---------------- babblesim/edtt/hci_transport/syscfg.yml | 21 +- 4 files changed, 32 insertions(+), 275 deletions(-) diff --git a/babblesim/edtt/hci_test/syscfg.yml b/babblesim/edtt/hci_test/syscfg.yml index bdf21e78d2..8a7909a6af 100644 --- a/babblesim/edtt/hci_test/syscfg.yml +++ b/babblesim/edtt/hci_test/syscfg.yml @@ -18,8 +18,8 @@ # syscfg.vals: - BLE_HOST: 0 - BLE_HCI_TRANSPORT: custom + BLE_TRANSPORT_LL: native + BLE_TRANSPORT_HS: custom # EDTT requires 0x123456789ABC address for first device # and 0x456789ABCDEF for second diff --git a/babblesim/edtt/hci_transport/pkg.yml b/babblesim/edtt/hci_transport/pkg.yml index 8e1dd9f25e..8ad24cd3c6 100644 --- a/babblesim/edtt/hci_transport/pkg.yml +++ b/babblesim/edtt/hci_transport/pkg.yml @@ -28,8 +28,11 @@ pkg.deps: - "@apache-mynewt-core/kernel/os" - nimble/controller +# allows to override settings from nimble/transport +pkg.subpriority: 1 + pkg.apis: - ble_transport pkg.init: - ble_hci_edtt_init: 500 + ble_hci_edtt_init: 249 diff --git a/babblesim/edtt/hci_transport/src/ble_hci_edtt.c b/babblesim/edtt/hci_transport/src/ble_hci_edtt.c index 36db846fa8..aa70f056a4 100644 --- a/babblesim/edtt/hci_transport/src/ble_hci_edtt.c +++ b/babblesim/edtt/hci_transport/src/ble_hci_edtt.c @@ -17,7 +17,6 @@ /* BLE */ #include "nimble/ble.h" #include "nimble/hci_common.h" -#include "nimble/ble_hci_trans.h" #include "bs_symbols.h" #include "bs_types.h" @@ -26,9 +25,6 @@ #include "edtt_driver.h" #include "commands.h" -#define BLE_HCI_EDTT_EVT_COUNT \ - (MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT) + MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT)) - #define BLE_HCI_EDTT_NONE 0x00 #define BLE_HCI_EDTT_CMD 0x01 #define BLE_HCI_EDTT_ACL 0x02 @@ -36,49 +32,6 @@ #define BT_HCI_OP_VS_WRITE_BD_ADDR 0xFC06 -/* Callbacks for sending commands and acl data to ble_ll task */ -static ble_hci_trans_rx_cmd_fn *ble_hci_edtt_rx_cmd_cb; -static void *ble_hci_edtt_rx_cmd_arg; -static ble_hci_trans_rx_acl_fn *ble_hci_edtt_rx_acl_cb; -static void *ble_hci_edtt_rx_acl_arg; - -/* Memory pool for hci events (high prio). 16 blocks x 70 bytes */ -static struct os_mempool ble_hci_edtt_evt_hi_pool; -static os_membuf_t ble_hci_edtt_evt_hi_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) -]; - -/* Memory pool for hci events (low prio). 16 blocks x 70 bytes */ -static struct os_mempool ble_hci_edtt_evt_lo_pool; -static os_membuf_t ble_hci_edtt_evt_lo_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) -]; - -/* Memory pool for hci commands. Only 1 block, so supports only 1 command at once. */ -static struct os_mempool ble_hci_edtt_cmd_pool; -static os_membuf_t ble_hci_edtt_cmd_buf[ - OS_MEMPOOL_SIZE(1, BLE_HCI_TRANS_CMD_SZ) -]; - -/* - * The MBUF payload size must accommodate the HCI data header size plus the - * maximum ACL data packet length. The ACL block size is the size of the - * mbufs we will allocate. - */ -#define ACL_BLOCK_SIZE OS_ALIGN(MYNEWT_VAL(BLE_ACL_BUF_SIZE) \ - + BLE_MBUF_MEMBLOCK_OVERHEAD \ - + BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT) - -/* mbuf pool for acl data. 15 buffers x (255 bytes + some hdrs len) */ -static struct os_mbuf_pool ble_hci_edtt_acl_mbuf_pool; -static struct os_mempool_ext ble_hci_edtt_acl_pool; -static os_membuf_t ble_hci_edtt_acl_buf[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ACL_BUF_COUNT), - ACL_BLOCK_SIZE) -]; - /* A packet for queueing EDTT/HCI commands and events */ struct ble_hci_edtt_pkt { struct os_event ev; @@ -145,28 +98,6 @@ log_hci_init() } #endif -/** - * Allocates a buffer (mbuf) for ACL operation. - * - * @return The allocated buffer on success; - * NULL on buffer exhaustion. - */ -static struct os_mbuf * -ble_hci_trans_acl_buf_alloc(void) -{ - struct os_mbuf *m; - uint8_t usrhdr_len; - -#if MYNEWT_VAL(BLE_CONTROLLER) - usrhdr_len = sizeof(struct ble_mbuf_hdr); -#else - usrhdr_len = 0; -#endif - - m = os_mbuf_get_pkthdr(&ble_hci_edtt_acl_mbuf_pool, usrhdr_len); - return m; -} - static int ble_hci_edtt_acl_tx(struct os_mbuf *om) { @@ -201,18 +132,6 @@ ble_hci_edtt_cmdevt_tx(uint8_t *hci_ev, uint8_t edtt_type) return 0; } -static void -ble_hci_edtt_set_rx_cbs(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_rx_cmd_cb = cmd_cb; - ble_hci_edtt_rx_cmd_arg = cmd_arg; - ble_hci_edtt_rx_acl_cb = acl_cb; - ble_hci_edtt_rx_acl_arg = acl_arg; -} - /** * Sends an HCI event from the controller to the host. * @@ -223,12 +142,9 @@ ble_hci_edtt_set_rx_cbs(ble_hci_trans_rx_cmd_fn *cmd_cb, * A BLE_ERR_[...] error code on failure. */ int -ble_hci_trans_ll_evt_tx(uint8_t *cmd) +ble_transport_to_hs_evt(void *buf) { - int rc; - - rc = ble_hci_edtt_cmdevt_tx(cmd, BLE_HCI_EDTT_EVT); - return rc; + return ble_hci_edtt_cmdevt_tx(buf, BLE_HCI_EDTT_EVT); } /** @@ -240,120 +156,9 @@ ble_hci_trans_ll_evt_tx(uint8_t *cmd) * A BLE_ERR_[...] error code on failure. */ int -ble_hci_trans_ll_acl_tx(struct os_mbuf *om) +ble_transport_to_hs_acl(struct os_mbuf *om) { - int rc; - - rc = ble_hci_edtt_acl_tx(om); - return rc; -} - -int -ble_hci_trans_hs_cmd_tx(uint8_t *cmd) -{ - int rc; - - rc = ble_hci_edtt_cmdevt_tx(cmd, BLE_HCI_EDTT_CMD); - return rc; -} - -int -ble_hci_trans_hs_acl_tx(struct os_mbuf *om) -{ - int rc; - - rc = ble_hci_edtt_acl_tx(om); - return rc; -} - -/** - * 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) { - uint8_t *buf; - - switch (type) { - case BLE_HCI_TRANS_BUF_CMD: - buf = os_memblock_get(&ble_hci_edtt_cmd_pool); - break; - case BLE_HCI_TRANS_BUF_EVT_HI: - buf = os_memblock_get(&ble_hci_edtt_evt_hi_pool); - if (buf == NULL) { - /* If no high-priority event buffers remain, try to grab a - * low-priority one. - */ - buf = os_memblock_get(&ble_hci_edtt_evt_lo_pool); - } - break; - - case BLE_HCI_TRANS_BUF_EVT_LO: - buf = os_memblock_get(&ble_hci_edtt_evt_lo_pool); - break; - - default: - assert(0); - buf = NULL; - } - - return buf; -} - -/** - * 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) -{ - int rc; - - /* - * XXX: this may look a bit odd, but the controller uses the command - * buffer to send back the command complete/status as an immediate - * response to the command. This was done to insure that the controller - * could always send back one of these events when a command was received. - * Thus, we check to see which pool the buffer came from so we can free - * it to the appropriate pool - */ - if (os_memblock_from(&ble_hci_edtt_evt_hi_pool, buf)) { - rc = os_memblock_put(&ble_hci_edtt_evt_hi_pool, buf); - assert(rc == 0); - } 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 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); - } -} - -int -ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg) -{ - ble_hci_edtt_acl_pool.mpe_put_cb = cb; - ble_hci_edtt_acl_pool.mpe_put_arg = arg; - return 0; -} - -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_edtt_set_rx_cbs(cmd_cb, cmd_arg, acl_cb, acl_arg); + return ble_hci_edtt_acl_tx(om); } /** @@ -398,8 +203,7 @@ send_hci_cmd_to_ctrl(uint16_t opcode, uint8_t param_len, uint16_t response) { waiting_response = response; waiting_opcode = opcode; - buf = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - + buf = ble_transport_alloc_cmd(); if (buf != NULL) { buf->opcode = opcode; buf->length = param_len; @@ -412,9 +216,9 @@ send_hci_cmd_to_ctrl(uint16_t opcode, uint8_t param_len, uint16_t response) { log_hci_cmd(opcode, buf->data, param_len); #endif - err = ble_hci_edtt_rx_cmd_cb((uint8_t *) buf, NULL); + err = ble_transport_to_ll_cmd(buf); if (err) { - ble_hci_trans_buf_free((uint8_t *) buf); + ble_transport_free(buf); bs_trace_raw_time(3, "Failed to send HCI command %d (err %d)", opcode, err); error_response(err); } @@ -454,7 +258,9 @@ command_complete(struct ble_hci_ev *evt) uint16_t response = waiting_response; uint16_t size = evt->length - sizeof(evt_cc->num_packets) - sizeof(evt_cc->opcode); - if (evt_cc->opcode == waiting_opcode) { + if (evt_cc->opcode == 0) { + /* ignore nop */ + } else 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); @@ -507,7 +313,7 @@ static void free_event(struct ble_hci_edtt_pkt *pkt) { assert(pkt); - ble_hci_trans_buf_free((void *)pkt->data); + ble_transport_free(pkt->data); free(pkt); } @@ -553,9 +359,10 @@ 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); + /* max evt size is always 257 */ + evt_copy = ble_transport_alloc_evt(0); + memcpy(evt_copy, evt, 257); + ble_transport_free(evt); return evt_copy; } @@ -598,14 +405,14 @@ service_events(void *arg) 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); + ble_transport_free(evt); } else { queue_event(evt); } break; case BLE_HCI_OPCODE_NOP: /* Ignore noop bytes from Link layer */ - ble_hci_trans_buf_free((void *)evt); + ble_transport_free(evt); break; default: /* Queue HCI events. We will send them to EDTT @@ -831,7 +638,7 @@ le_data_write(uint16_t size) int err; if (size >= sizeof(hdr)) { - om = ble_hci_trans_acl_buf_alloc(); + om = ble_transport_alloc_acl_from_hs(); if (om) { edtt_read((void *)&hdr, sizeof(hdr), EDTTT_BLOCK); size -= sizeof(hdr); @@ -848,7 +655,7 @@ le_data_write(uint16_t size) os_mbuf_append(om, tmp, hdr.hdh_len); } - err = ble_hci_edtt_rx_acl_cb(om, NULL); + err = ble_transport_to_ll_acl(om); if (err) { bs_trace_raw_time(3, "Failed to send ACL Data (err %d)", err); } @@ -874,7 +681,7 @@ fake_write_bd_addr_cc() waiting_opcode = BT_HCI_OP_VS_WRITE_BD_ADDR; waiting_response = CMD_WRITE_BD_ADDR_RSP; - hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { hci_ev->opcode = BLE_HCI_EVCODE_COMMAND_COMPLETE; hci_ev->length = sizeof(*ev); @@ -997,53 +804,9 @@ edtt_init(void) void ble_hci_edtt_init(void) { - int rc; - /* Ensure this function only gets called by sysinit. */ SYSINIT_ASSERT_ACTIVE(); - rc = os_mempool_ext_init(&ble_hci_edtt_acl_pool, - MYNEWT_VAL(BLE_ACL_BUF_COUNT), - ACL_BLOCK_SIZE, - ble_hci_edtt_acl_buf, - "ble_hci_edtt_acl_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mbuf_pool_init(&ble_hci_edtt_acl_mbuf_pool, - &ble_hci_edtt_acl_pool.mpe_mp, - ACL_BLOCK_SIZE, - MYNEWT_VAL(BLE_ACL_BUF_COUNT)); - SYSINIT_PANIC_ASSERT(rc == 0); - - /* - * Create memory pool of HCI command buffers. NOTE: we currently dont - * allow this to be configured. The controller will only allow one - * outstanding command. We decided to keep this a pool in case we allow - * allow the controller to handle more than one outstanding command. - */ - rc = os_mempool_init(&ble_hci_edtt_cmd_pool, - 1, - BLE_HCI_TRANS_CMD_SZ, - ble_hci_edtt_cmd_buf, - "ble_hci_edtt_cmd_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&ble_hci_edtt_evt_hi_pool, - MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - ble_hci_edtt_evt_hi_buf, - "ble_hci_edtt_evt_hi_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&ble_hci_edtt_evt_lo_pool, - MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - ble_hci_edtt_evt_lo_buf, - "ble_hci_edtt_evt_lo_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failure configuring edtt HCI"); - 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/syscfg.yml b/babblesim/edtt/hci_transport/syscfg.yml index b203361d03..ad12f7b5bc 100644 --- a/babblesim/edtt/hci_transport/syscfg.yml +++ b/babblesim/edtt/hci_transport/syscfg.yml @@ -31,19 +31,10 @@ syscfg.defs: type: task_priority value: 2 - BLE_HCI_ACL_OUT_COUNT: - description: > - This count is used in creating a pool of elements used by the - code to enqueue various elements. In the case of the controller - only HCI, this number should be equal to the number of mbufs in - the msys pool. For host only, it is really dependent on the - number of ACL buffers that the controller tells the host it - has. - value: 12 - syscfg.vals: - BLE_ACL_BUF_COUNT: 32 - BLE_ACL_BUF_SIZE: 255 - BLE_HCI_EVT_BUF_SIZE: 257 - BLE_HCI_EVT_HI_BUF_COUNT: 32 - BLE_HCI_EVT_LO_BUF_COUNT: 32 + BLE_TRANSPORT_ACL_COUNT: 32 + BLE_TRANSPORT_EVT_COUNT: 64 + +syscfg.restrictions: + - BLE_TRANSPORT_HS == "custom" + - BLE_TRANSPORT_LL == "native" \ No newline at end of file From e9a4a4fce2982c3b38c1548e6fb6010ff0a9a638 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 8 Mar 2022 07:38:47 +0100 Subject: [PATCH 0345/1333] apps: Update to new transport We do not need depedency to nimble/transport, this is automatically included by nimble/host. --- apps/advertiser/pkg.yml | 2 +- apps/blecent/pkg.yml | 1 - apps/blecsc/pkg.yml | 1 - apps/blehr/pkg.yml | 1 - apps/blemesh/pkg.yml | 1 - apps/blemesh_light/pkg.yml | 1 - apps/blemesh_models_example_1/pkg.yml | 1 - apps/blemesh_models_example_2/pkg.yml | 1 - apps/blemesh_shell/pkg.yml | 1 - apps/bleprph/pkg.yml | 1 - apps/blestress/pkg.yml | 1 - apps/btshell/pkg.yml | 1 - apps/bttester/pkg.yml | 1 - apps/central/pkg.yml | 1 - apps/ext_advertiser/pkg.yml | 1 - apps/mesh_badge/pkg.yml | 1 - apps/peripheral/pkg.yml | 2 -- apps/scanner/pkg.yml | 1 - 18 files changed, 1 insertion(+), 19 deletions(-) diff --git a/apps/advertiser/pkg.yml b/apps/advertiser/pkg.yml index 662e282e8b..ad6f133d59 100644 --- a/apps/advertiser/pkg.yml +++ b/apps/advertiser/pkg.yml @@ -28,6 +28,6 @@ pkg.deps: - "@apache-mynewt-core/sys/log/full" - "@apache-mynewt-core/sys/stats/full" - "@apache-mynewt-core/sys/log/modlog" + - "@apache-mynewt-nimble/nimble/host" - "@apache-mynewt-nimble/nimble/host/util" - "@apache-mynewt-nimble/nimble/host/services/gap" - - "@apache-mynewt-nimble/nimble/transport" diff --git a/apps/blecent/pkg.yml b/apps/blecent/pkg.yml index 12d539e6dd..86e3f01690 100644 --- a/apps/blecent/pkg.yml +++ b/apps/blecent/pkg.yml @@ -33,4 +33,3 @@ pkg.deps: - nimble/host/services/gap - nimble/host/services/gatt - nimble/host/store/config - - nimble/transport diff --git a/apps/blecsc/pkg.yml b/apps/blecsc/pkg.yml index a2119c1b35..d3768fc7f9 100644 --- a/apps/blecsc/pkg.yml +++ b/apps/blecsc/pkg.yml @@ -36,4 +36,3 @@ pkg.deps: - nimble/host/services/gap - nimble/host/services/gatt - nimble/host/store/config - - nimble/transport diff --git a/apps/blehr/pkg.yml b/apps/blehr/pkg.yml index 8212f8f6a2..ace633b16e 100644 --- a/apps/blehr/pkg.yml +++ b/apps/blehr/pkg.yml @@ -36,4 +36,3 @@ pkg.deps: - nimble/host/services/gap - nimble/host/services/gatt - nimble/host/store/config - - nimble/transport diff --git a/apps/blemesh/pkg.yml b/apps/blemesh/pkg.yml index afe419b57b..19fb478230 100644 --- a/apps/blemesh/pkg.yml +++ b/apps/blemesh/pkg.yml @@ -33,4 +33,3 @@ pkg.deps: - nimble/host/services/gap - nimble/host/services/gatt - nimble/host/store/config - - nimble/transport diff --git a/apps/blemesh_light/pkg.yml b/apps/blemesh_light/pkg.yml index 46b6d6c3d1..bb37ffb5ff 100644 --- a/apps/blemesh_light/pkg.yml +++ b/apps/blemesh_light/pkg.yml @@ -33,4 +33,3 @@ pkg.deps: - nimble/host/services/gap - nimble/host/services/gatt - nimble/host/store/config - - nimble/transport diff --git a/apps/blemesh_models_example_1/pkg.yml b/apps/blemesh_models_example_1/pkg.yml index b8d77c4e47..44e2d79cbc 100644 --- a/apps/blemesh_models_example_1/pkg.yml +++ b/apps/blemesh_models_example_1/pkg.yml @@ -30,4 +30,3 @@ pkg.deps: - nimble/host - nimble/host/services/gap - nimble/host/services/gatt - - nimble/transport diff --git a/apps/blemesh_models_example_2/pkg.yml b/apps/blemesh_models_example_2/pkg.yml index 020a9616da..194b5546c4 100644 --- a/apps/blemesh_models_example_2/pkg.yml +++ b/apps/blemesh_models_example_2/pkg.yml @@ -32,7 +32,6 @@ pkg.deps: - nimble/host - nimble/host/services/gap - nimble/host/services/gatt - - nimble/transport pkg.lflags: - -DFLOAT_SUPPORT diff --git a/apps/blemesh_shell/pkg.yml b/apps/blemesh_shell/pkg.yml index f472fdf2aa..a7e457ed10 100644 --- a/apps/blemesh_shell/pkg.yml +++ b/apps/blemesh_shell/pkg.yml @@ -33,4 +33,3 @@ pkg.deps: - nimble/host/services/gap - nimble/host/services/gatt - nimble/host/store/config - - nimble/transport diff --git a/apps/bleprph/pkg.yml b/apps/bleprph/pkg.yml index 38b6e4451d..0bb0d9d0bb 100644 --- a/apps/bleprph/pkg.yml +++ b/apps/bleprph/pkg.yml @@ -42,4 +42,3 @@ pkg.deps: - nimble/host/services/gatt - nimble/host/store/config - nimble/host/util - - nimble/transport diff --git a/apps/blestress/pkg.yml b/apps/blestress/pkg.yml index 53f99ed944..21013eb58a 100644 --- a/apps/blestress/pkg.yml +++ b/apps/blestress/pkg.yml @@ -35,4 +35,3 @@ pkg.deps: - "@apache-mynewt-nimble/nimble/host/services/gap" - "@apache-mynewt-nimble/nimble/host/services/gatt" - "@apache-mynewt-nimble/nimble/host/store/config" - - "@apache-mynewt-nimble/nimble/transport" diff --git a/apps/btshell/pkg.yml b/apps/btshell/pkg.yml index be6d68548f..abbee73c7e 100644 --- a/apps/btshell/pkg.yml +++ b/apps/btshell/pkg.yml @@ -34,7 +34,6 @@ pkg.deps: - nimble/host/services/gatt - nimble/host/store/config - nimble/host/util - - nimble/transport pkg.deps.BTSHELL_ANS: - nimble/host/services/ans diff --git a/apps/bttester/pkg.yml b/apps/bttester/pkg.yml index 270dc7e882..219e529810 100644 --- a/apps/bttester/pkg.yml +++ b/apps/bttester/pkg.yml @@ -37,7 +37,6 @@ pkg.deps: - "@apache-mynewt-nimble/nimble/host/services/gatt" - "@apache-mynewt-nimble/nimble/host/services/dis" - "@apache-mynewt-nimble/nimble/host/store/config" - - "@apache-mynewt-nimble/nimble/transport" - "@apache-mynewt-core/hw/drivers/uart" - "@apache-mynewt-core/hw/drivers/rtt" diff --git a/apps/central/pkg.yml b/apps/central/pkg.yml index c10ad93336..5f5b27a971 100644 --- a/apps/central/pkg.yml +++ b/apps/central/pkg.yml @@ -31,4 +31,3 @@ pkg.deps: - "@apache-mynewt-nimble/nimble/host" - "@apache-mynewt-nimble/nimble/host/util/" - "@apache-mynewt-nimble/nimble/host/store/config" - - "@apache-mynewt-nimble/nimble/transport" diff --git a/apps/ext_advertiser/pkg.yml b/apps/ext_advertiser/pkg.yml index 5a60b2270b..32df4efc10 100644 --- a/apps/ext_advertiser/pkg.yml +++ b/apps/ext_advertiser/pkg.yml @@ -30,7 +30,6 @@ pkg.deps: - nimble/host/services/gap - nimble/host/services/gatt - nimble/host/store/config - - nimble/transport - "@apache-mynewt-core/kernel/os" - "@apache-mynewt-core/sys/console/full" - "@apache-mynewt-core/sys/log/full" diff --git a/apps/mesh_badge/pkg.yml b/apps/mesh_badge/pkg.yml index 96a42ba6a7..d1276a51cf 100644 --- a/apps/mesh_badge/pkg.yml +++ b/apps/mesh_badge/pkg.yml @@ -35,4 +35,3 @@ pkg.deps: - nimble/host/services/gap - nimble/host/services/gatt - nimble/host/store/config - - nimble/transport diff --git a/apps/peripheral/pkg.yml b/apps/peripheral/pkg.yml index 6167edabcd..d5c862c810 100644 --- a/apps/peripheral/pkg.yml +++ b/apps/peripheral/pkg.yml @@ -33,5 +33,3 @@ pkg.deps: - "@apache-mynewt-nimble/nimble/host/util/" - "@apache-mynewt-nimble/nimble/host/services/gap" - "@apache-mynewt-nimble/nimble/host/store/config" - - "@apache-mynewt-nimble/nimble/transport" - diff --git a/apps/scanner/pkg.yml b/apps/scanner/pkg.yml index 15c2adbbff..442ab9db64 100644 --- a/apps/scanner/pkg.yml +++ b/apps/scanner/pkg.yml @@ -32,4 +32,3 @@ pkg.deps: - "@apache-mynewt-nimble/nimble/host" - "@apache-mynewt-nimble/nimble/host/util/" - "@apache-mynewt-nimble/nimble/host/store/config" - - "@apache-mynewt-nimble/nimble/transport" \ No newline at end of file From 1118fe21fe2f79d1116aaeb38d873855054205be Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 3 Mar 2022 18:08:26 +0100 Subject: [PATCH 0346/1333] apps/blehci: Update configuration for new transport Dependency to nimble/controller is not needed since blehci can now run on both app (as a bridge to net core) and net core. For non-netcore build we select UART by default, otherwise keep whatever default was set by BSP. --- apps/blehci/pkg.yml | 1 - apps/blehci/syscfg.yml | 6 ++++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/blehci/pkg.yml b/apps/blehci/pkg.yml index 2c63a04911..e385d7da5d 100644 --- a/apps/blehci/pkg.yml +++ b/apps/blehci/pkg.yml @@ -27,7 +27,6 @@ pkg.deps: - "@apache-mynewt-core/sys/log/stub" - "@apache-mynewt-core/sys/stats/full" - "@apache-mynewt-core/kernel/os" - - nimble/controller - nimble/transport pkg.req_apis: diff --git a/apps/blehci/syscfg.yml b/apps/blehci/syscfg.yml index ee806237f6..ec20e68963 100644 --- a/apps/blehci/syscfg.yml +++ b/apps/blehci/syscfg.yml @@ -19,7 +19,9 @@ syscfg.vals: # Default task settings OS_MAIN_STACK_SIZE: 64 - # Use UART transport by default - BLE_HCI_TRANSPORT: uart # Stub console CONSOLE_MODE: stub + +syscfg.vals.'!BLE_TRANSPORT_NETCORE': + # Use UART by default if not built on netcore + BLE_TRANSPORT_HS: uart From fc4b2deaad4c36f6f6c0e00d000c8e9d37fb886d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 8 Mar 2022 07:54:03 +0100 Subject: [PATCH 0347/1333] apps/blehcibridge: Remove app There's no need for separate bridge app, blehci can now work as a bridge using new transport architecture. --- apps/blehcibridge/pkg.yml | 34 ------------------ apps/blehcibridge/src/main.c | 69 ------------------------------------ apps/blehcibridge/syscfg.yml | 29 --------------- 3 files changed, 132 deletions(-) delete mode 100644 apps/blehcibridge/pkg.yml delete mode 100644 apps/blehcibridge/src/main.c delete mode 100644 apps/blehcibridge/syscfg.yml diff --git a/apps/blehcibridge/pkg.yml b/apps/blehcibridge/pkg.yml deleted file mode 100644 index 5acd2e7b0a..0000000000 --- a/apps/blehcibridge/pkg.yml +++ /dev/null @@ -1,34 +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. -# -pkg.name: apps/blehcibridge -pkg.type: app -pkg.description: BLE controller application exposing HCI over external interface -pkg.author: "Jerzy Kasenberg " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - -pkg.deps: - - "@apache-mynewt-core/sys/console" - - "@apache-mynewt-core/sys/log/stub" - - "@apache-mynewt-core/sys/stats/full" - - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/shell" - - nimble/transport - -pkg.req_apis: - - ble_transport diff --git a/apps/blehcibridge/src/main.c b/apps/blehcibridge/src/main.c deleted file mode 100644 index 620cc37121..0000000000 --- a/apps/blehcibridge/src/main.c +++ /dev/null @@ -1,69 +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. - */ - -#include -#include -#include - -static int -forward_cmd_to_controller(uint8_t *cmdbuf, void *arg) -{ - (void)arg; - - return ble_hci_trans_hs_cmd_tx(cmdbuf); -} - -int -forward_acl_to_controller(struct os_mbuf *om, void *arg) -{ - (void)arg; - - return ble_hci_trans_hs_acl_tx(om); -} - -static int -forward_evt_to_host(uint8_t *hci_ev, void *arg) -{ - (void)arg; - - return ble_hci_trans_ll_evt_tx(hci_ev); -} - -int -forward_acl_to_host(struct os_mbuf *om, void *arg) -{ - (void)arg; - - return ble_hci_trans_ll_acl_tx(om); -} - -int -main(void) -{ - /* Initialize OS */ - sysinit(); - - ble_hci_trans_cfg_hs(forward_evt_to_host, NULL, forward_acl_to_host, NULL); - ble_hci_trans_cfg_ll(forward_cmd_to_controller, NULL, forward_acl_to_controller, NULL); - - while (1) { - os_eventq_run(os_eventq_dflt_get()); - } - return 0; -} diff --git a/apps/blehcibridge/syscfg.yml b/apps/blehcibridge/syscfg.yml deleted file mode 100644 index 203ec25df5..0000000000 --- a/apps/blehcibridge/syscfg.yml +++ /dev/null @@ -1,29 +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. -# - -syscfg.vals: - # Default task settings - OS_MAIN_STACK_SIZE: 64 - # Use USB transport by default - BLE_HCI_TRANSPORT: usb - # Stub console - CONSOLE_MODE: stub - - SHELL_TASK: 1 - - BLE_HCI_BRIDGE: 1 From d7e5d6fc35748b1e97d51e5aa3b263ca48d22dfb Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 10 Mar 2022 11:21:18 +0100 Subject: [PATCH 0348/1333] nimble/test: Update for new transport --- nimble/controller/test/syscfg.yml | 1 - nimble/host/test/pkg.yml | 3 +++ nimble/host/test/src/ble_hs_hci_test.c | 4 ++-- nimble/host/test/src/ble_hs_test_util.c | 23 +++++++++++---------- nimble/host/test/src/ble_hs_test_util_hci.c | 6 ++---- nimble/host/test/src/ble_os_test.c | 1 - nimble/host/test/syscfg.yml | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/nimble/controller/test/syscfg.yml b/nimble/controller/test/syscfg.yml index 4448a0e66f..6edad438bb 100644 --- a/nimble/controller/test/syscfg.yml +++ b/nimble/controller/test/syscfg.yml @@ -23,4 +23,3 @@ syscfg.vals: MCU_TIMER_POLLER_PRIO: 1 MCU_UART_POLLER_PRIO: 2 NATIVE_SOCKETS_PRIO: 3 - BLE_HCI_TRANSPORT: ram diff --git a/nimble/host/test/pkg.yml b/nimble/host/test/pkg.yml index cb5d97cfb3..1698043e4f 100644 --- a/nimble/host/test/pkg.yml +++ b/nimble/host/test/pkg.yml @@ -32,3 +32,6 @@ pkg.deps.SELFTEST: - "@apache-mynewt-core/sys/log/full" - "@apache-mynewt-core/sys/stats/stub" - nimble/transport + +pkg.apis: + - ble_driver diff --git a/nimble/host/test/src/ble_hs_hci_test.c b/nimble/host/test/src/ble_hs_hci_test.c index 5f72742c63..8dd7c7777c 100644 --- a/nimble/host/test/src/ble_hs_hci_test.c +++ b/nimble/host/test/src/ble_hs_hci_test.c @@ -21,7 +21,7 @@ #include #include #include "nimble/hci_common.h" -#include "nimble/ble_hci_trans.h" +#include "nimble/transport.h" #include "ble_hs_test.h" #include "testutil/testutil.h" #include "ble_hs_test_util.h" @@ -34,7 +34,7 @@ TEST_CASE_SELF(ble_hs_hci_test_event_bad) int rc; /*** Invalid event code. */ - buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + buf = ble_transport_alloc_evt(0); TEST_ASSERT_FATAL(buf != NULL); buf[0] = 0xff; diff --git a/nimble/host/test/src/ble_hs_test_util.c b/nimble/host/test/src/ble_hs_test_util.c index 5ee17e7676..6a838169b1 100644 --- a/nimble/host/test/src/ble_hs_test_util.c +++ b/nimble/host/test/src/ble_hs_test_util.c @@ -24,11 +24,9 @@ #include "testutil/testutil.h" #include "nimble/ble.h" #include "nimble/hci_common.h" -#include "nimble/ble_hci_trans.h" #include "host/ble_hs_adv.h" #include "host/ble_hs_id.h" #include "store/config/ble_store_config.h" -#include "transport/ram/ble_hci_ram.h" #include "ble_hs_test_util.h" /* Our global device address. */ @@ -1850,18 +1848,18 @@ ble_hs_test_util_assert_mbufs_freed( TEST_ASSERT(count == ble_hs_test_util_num_mbufs()); } -static int -ble_hs_test_util_pkt_txed(struct os_mbuf *om, void *arg) +int +ble_transport_to_ll_acl(struct os_mbuf *om) { ble_hs_test_util_prev_tx_enqueue(om); return 0; } -static int -ble_hs_test_util_hci_txed(uint8_t *cmdbuf, void *arg) +int +ble_transport_to_ll_cmd(void *buf) { - ble_hs_test_util_hci_out_enqueue(cmdbuf); - ble_hci_trans_buf_free(cmdbuf); + ble_hs_test_util_hci_out_enqueue(buf); + ble_transport_free(buf); return 0; } @@ -2003,9 +2001,6 @@ ble_hs_test_util_init_no_sysinit_no_start(void) ble_hs_hci_set_phony_ack_cb(NULL); - ble_hci_trans_cfg_ll(ble_hs_test_util_hci_txed, NULL, - ble_hs_test_util_pkt_txed, NULL); - ble_hs_test_util_hci_ack_set_startup(); ble_hs_enabled_state = BLE_HS_ENABLED_STATE_OFF; @@ -2046,3 +2041,9 @@ ble_hs_test_util_init(void) /* Clear random address. */ ble_hs_id_rnd_reset(); } + +void +ble_transport_ll_init(void) +{ + /* nothing here */ +} \ No newline at end of file diff --git a/nimble/host/test/src/ble_hs_test_util_hci.c b/nimble/host/test/src/ble_hs_test_util_hci.c index a53c5d9fc5..e8054c2ffa 100644 --- a/nimble/host/test/src/ble_hs_test_util_hci.c +++ b/nimble/host/test/src/ble_hs_test_util_hci.c @@ -20,7 +20,6 @@ #include "testutil/testutil.h" #include "nimble/ble.h" #include "nimble/hci_common.h" -#include "transport/ram/ble_hci_ram.h" #include "ble_hs_test_util.h" #define BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN (5) @@ -522,14 +521,13 @@ ble_hs_test_util_hci_rx_evt(uint8_t *evt) totlen = BLE_HCI_EVENT_HDR_LEN + evt[1]; TEST_ASSERT_FATAL(totlen <= UINT8_MAX + BLE_HCI_EVENT_HDR_LEN); - evbuf = ble_hci_trans_buf_alloc( - BLE_HCI_TRANS_BUF_EVT_LO); + evbuf = ble_transport_alloc_evt(1); TEST_ASSERT_FATAL(evbuf != NULL); memcpy(evbuf, evt, totlen); if (os_started()) { - rc = ble_hci_trans_ll_evt_tx(evbuf); + rc = ble_transport_to_hs_evt(evbuf); } else { rc = ble_hs_hci_evt_process((void *)evbuf); } diff --git a/nimble/host/test/src/ble_os_test.c b/nimble/host/test/src/ble_os_test.c index fa57571b44..6588c67986 100644 --- a/nimble/host/test/src/ble_os_test.c +++ b/nimble/host/test/src/ble_os_test.c @@ -21,7 +21,6 @@ #include "os/os.h" #include "testutil/testutil.h" #include "nimble/hci_common.h" -#include "nimble/ble_hci_trans.h" #include "ble_hs_test.h" #include "host/ble_gap.h" #include "ble_hs_test_util.h" diff --git a/nimble/host/test/syscfg.yml b/nimble/host/test/syscfg.yml index 45bc638b62..031b6c8ba1 100644 --- a/nimble/host/test/syscfg.yml +++ b/nimble/host/test/syscfg.yml @@ -29,4 +29,4 @@ syscfg.vals: CONFIG_FCB: 1 BLE_VERSION: 52 BLE_L2CAP_ENHANCED_COC: 1 - BLE_HCI_TRANSPORT: ram + BLE_TRANSPORT_LL: custom From fd62bd71f9266a0fb7eb0783c611ac6220fbc02c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 10 Mar 2022 12:50:14 +0100 Subject: [PATCH 0349/1333] porting: Update for new HCI transport Adds required files to build, updates Linux sample app and also regenerate syscfg.h. --- .../examples/linux/include/syscfg/syscfg.h | 130 ++++++------- .../linux_blemesh/include/syscfg/syscfg.h | 130 ++++++------- .../examples/nuttx/include/syscfg/syscfg.h | 130 ++++++------- porting/nimble/Makefile.defs | 2 + porting/nimble/include/syscfg/syscfg.h | 130 ++++++------- porting/nimble/src/nimble_port.c | 6 +- porting/npl/riot/include/syscfg/syscfg.h | 180 +++++++++++------- porting/targets/linux/syscfg.yml | 2 +- porting/targets/linux_blemesh/syscfg.yml | 2 +- porting/targets/nuttx/syscfg.yml | 2 +- porting/targets/porting_default/syscfg.yml | 2 +- porting/targets/riot/syscfg.yml | 5 +- 12 files changed, 370 insertions(+), 351 deletions(-) diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index 31d3835a9a..903163ad61 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -15,7 +15,6 @@ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val -/*** @apache-mynewt-core/crypto/tinycrypt */ #ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE #define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) #endif @@ -1008,103 +1007,98 @@ #endif /*** @apache-mynewt-nimble/nimble/transport */ -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_ACL_BUF_COUNT -#define MYNEWT_VAL_BLE_ACL_BUF_COUNT (24) -#endif +#undef MYNEWT_VAL_BLE_ACL_BUF_COUNT -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_ACL_BUF_SIZE -#define MYNEWT_VAL_BLE_ACL_BUF_SIZE (255) -#endif +#undef MYNEWT_VAL_BLE_ACL_BUF_SIZE -#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE -#define MYNEWT_VAL_BLE_HCI_BRIDGE (0) -#endif +#undef MYNEWT_VAL_BLE_HCI_BRIDGE -#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac -#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac (0) -#endif -#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 -#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 (0) +#undef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE + +#undef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT + +#undef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT + +#undef MYNEWT_VAL_BLE_HCI_TRANSPORT + +#ifndef MYNEWT_VAL_BLE_TRANSPORT +#define MYNEWT_VAL_BLE_TRANSPORT (1) #endif -#undef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE -#define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT (10) #endif -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT -#define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (8) +/* Value copied from BLE_TRANSPORT_ACL_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT (10) #endif -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT -#define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8) +/* Value copied from BLE_TRANSPORT_ACL_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT (10) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (255) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__custom -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__custom (0) + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT (4) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x (0) + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT (16) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac (0) + +/* Overridden by @apache-mynewt-nimble/nimble/transport (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (257) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi (0) + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__custom +#define MYNEWT_VAL_BLE_TRANSPORT_HS__custom (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac +#define MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__ram -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__ram (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__native +#define MYNEWT_VAL_BLE_TRANSPORT_HS__native (1) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__socket -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__socket (1) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340 +#define MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340 (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__uart -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__uart (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__uart +#define MYNEWT_VAL_BLE_TRANSPORT_HS__uart (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__usb -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__usb (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__usb +#define MYNEWT_VAL_BLE_TRANSPORT_HS__usb (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT -#define MYNEWT_VAL_BLE_HCI_TRANSPORT (1) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS +#define MYNEWT_VAL_BLE_TRANSPORT_HS (1) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI (0) +/* Overridden by @apache-mynewt-nimble/porting/targets/linux (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__custom +#define MYNEWT_VAL_BLE_TRANSPORT_LL__custom (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac +#define MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__native +#define MYNEWT_VAL_BLE_TRANSPORT_LL__native (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340 +#define MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340 (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_UART -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_UART (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__socket +#define MYNEWT_VAL_BLE_TRANSPORT_LL__socket (1) #endif - -/*** @apache-mynewt-nimble/nimble/transport/socket */ -#ifndef MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT -#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL +#define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif +/*** @apache-mynewt-nimble/nimble/transport/socket */ #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 976151a4ee..550ce53985 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -15,7 +15,6 @@ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val -/*** @apache-mynewt-core/crypto/tinycrypt */ #ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE #define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) #endif @@ -1583,103 +1582,98 @@ #endif /*** @apache-mynewt-nimble/nimble/transport */ -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_ACL_BUF_COUNT -#define MYNEWT_VAL_BLE_ACL_BUF_COUNT (24) -#endif +#undef MYNEWT_VAL_BLE_ACL_BUF_COUNT -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_ACL_BUF_SIZE -#define MYNEWT_VAL_BLE_ACL_BUF_SIZE (255) -#endif +#undef MYNEWT_VAL_BLE_ACL_BUF_SIZE -#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE -#define MYNEWT_VAL_BLE_HCI_BRIDGE (0) -#endif +#undef MYNEWT_VAL_BLE_HCI_BRIDGE -#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac -#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac (0) -#endif -#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 -#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 (0) +#undef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE + +#undef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT + +#undef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT + +#undef MYNEWT_VAL_BLE_HCI_TRANSPORT + +#ifndef MYNEWT_VAL_BLE_TRANSPORT +#define MYNEWT_VAL_BLE_TRANSPORT (1) #endif -#undef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE -#define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT (10) #endif -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT -#define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (8) +/* Value copied from BLE_TRANSPORT_ACL_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT (10) #endif -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT -#define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8) +/* Value copied from BLE_TRANSPORT_ACL_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT (10) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (255) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__custom -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__custom (0) + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT (4) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x (0) + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT (16) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac (0) + +/* Overridden by @apache-mynewt-nimble/nimble/transport (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (257) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi (0) + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__custom +#define MYNEWT_VAL_BLE_TRANSPORT_HS__custom (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac +#define MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__ram -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__ram (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__native +#define MYNEWT_VAL_BLE_TRANSPORT_HS__native (1) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__socket -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__socket (1) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340 +#define MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340 (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__uart -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__uart (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__uart +#define MYNEWT_VAL_BLE_TRANSPORT_HS__uart (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__usb -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__usb (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__usb +#define MYNEWT_VAL_BLE_TRANSPORT_HS__usb (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT -#define MYNEWT_VAL_BLE_HCI_TRANSPORT (1) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS +#define MYNEWT_VAL_BLE_TRANSPORT_HS (1) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI (0) +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__custom +#define MYNEWT_VAL_BLE_TRANSPORT_LL__custom (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac +#define MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__native +#define MYNEWT_VAL_BLE_TRANSPORT_LL__native (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340 +#define MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340 (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_UART -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_UART (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__socket +#define MYNEWT_VAL_BLE_TRANSPORT_LL__socket (1) #endif - -/*** @apache-mynewt-nimble/nimble/transport/socket */ -#ifndef MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT -#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL +#define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif +/*** @apache-mynewt-nimble/nimble/transport/socket */ #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index 9269e3a8b8..11fa149d65 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -15,7 +15,6 @@ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val -/*** @apache-mynewt-core/crypto/tinycrypt */ #ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE #define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) #endif @@ -1010,103 +1009,98 @@ #endif /*** @apache-mynewt-nimble/nimble/transport */ -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_ACL_BUF_COUNT -#define MYNEWT_VAL_BLE_ACL_BUF_COUNT (24) -#endif +#undef MYNEWT_VAL_BLE_ACL_BUF_COUNT -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_ACL_BUF_SIZE -#define MYNEWT_VAL_BLE_ACL_BUF_SIZE (255) -#endif +#undef MYNEWT_VAL_BLE_ACL_BUF_SIZE -#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE -#define MYNEWT_VAL_BLE_HCI_BRIDGE (0) -#endif +#undef MYNEWT_VAL_BLE_HCI_BRIDGE -#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac -#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac (0) -#endif -#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 -#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 (0) +#undef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE + +#undef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT + +#undef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT + +#undef MYNEWT_VAL_BLE_HCI_TRANSPORT + +#ifndef MYNEWT_VAL_BLE_TRANSPORT +#define MYNEWT_VAL_BLE_TRANSPORT (1) #endif -#undef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE -#define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT (10) #endif -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT -#define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (8) +/* Value copied from BLE_TRANSPORT_ACL_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT (10) #endif -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT -#define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8) +/* Value copied from BLE_TRANSPORT_ACL_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT (10) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (255) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__custom -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__custom (0) + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT (4) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x (0) + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT (16) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac (0) + +/* Overridden by @apache-mynewt-nimble/nimble/transport (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (257) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi (0) + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__custom +#define MYNEWT_VAL_BLE_TRANSPORT_HS__custom (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac +#define MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__ram -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__ram (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__native +#define MYNEWT_VAL_BLE_TRANSPORT_HS__native (1) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__socket -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__socket (1) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340 +#define MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340 (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__uart -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__uart (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__uart +#define MYNEWT_VAL_BLE_TRANSPORT_HS__uart (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__usb -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__usb (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__usb +#define MYNEWT_VAL_BLE_TRANSPORT_HS__usb (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT -#define MYNEWT_VAL_BLE_HCI_TRANSPORT (1) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS +#define MYNEWT_VAL_BLE_TRANSPORT_HS (1) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI (0) +/* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__custom +#define MYNEWT_VAL_BLE_TRANSPORT_LL__custom (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac +#define MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__native +#define MYNEWT_VAL_BLE_TRANSPORT_LL__native (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340 +#define MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340 (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_UART -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_UART (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__socket +#define MYNEWT_VAL_BLE_TRANSPORT_LL__socket (1) #endif - -/*** @apache-mynewt-nimble/nimble/transport/socket */ -#ifndef MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT -#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL +#define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif +/*** @apache-mynewt-nimble/nimble/transport/socket */ #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif diff --git a/porting/nimble/Makefile.defs b/porting/nimble/Makefile.defs index 78f73fbc9b..ad458970fe 100644 --- a/porting/nimble/Makefile.defs +++ b/porting/nimble/Makefile.defs @@ -38,6 +38,7 @@ NIMBLE_INCLUDE := \ $(NIMBLE_ROOT)/nimble/host/services/tps/include \ $(NIMBLE_ROOT)/nimble/host/store/ram/include \ $(NIMBLE_ROOT)/nimble/host/util/include \ + $(NIMBLE_ROOT)/nimble/transport/include \ $(NIMBLE_ROOT)/porting/nimble/include \ $(NULL) @@ -55,6 +56,7 @@ NIMBLE_SRC := \ $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/lls/src/*.c)) \ $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/tps/src/*.c)) \ $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/store/ram/src/*.c)) \ + $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/transport/src/*.c)) \ $(NULL) ifneq (,$(NIMBLE_CFG_CONTROLLER)) diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index 98c0775f0b..55a7c8b321 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -15,7 +15,6 @@ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val -/*** @apache-mynewt-core/crypto/tinycrypt */ #ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE #define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) #endif @@ -1007,103 +1006,98 @@ #endif /*** @apache-mynewt-nimble/nimble/transport */ -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_ACL_BUF_COUNT -#define MYNEWT_VAL_BLE_ACL_BUF_COUNT (24) -#endif +#undef MYNEWT_VAL_BLE_ACL_BUF_COUNT -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_ACL_BUF_SIZE -#define MYNEWT_VAL_BLE_ACL_BUF_SIZE (255) -#endif +#undef MYNEWT_VAL_BLE_ACL_BUF_SIZE -#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE -#define MYNEWT_VAL_BLE_HCI_BRIDGE (0) -#endif +#undef MYNEWT_VAL_BLE_HCI_BRIDGE -#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac -#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac (0) -#endif -#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 -#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 (0) +#undef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE + +#undef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT + +#undef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT + +#undef MYNEWT_VAL_BLE_HCI_TRANSPORT + +#ifndef MYNEWT_VAL_BLE_TRANSPORT +#define MYNEWT_VAL_BLE_TRANSPORT (1) #endif -#undef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE -#define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT (10) #endif -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT -#define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (8) +/* Value copied from BLE_TRANSPORT_ACL_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT (10) #endif -/* Overridden by @apache-mynewt-nimble/nimble/transport/socket (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT -#define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8) +/* Value copied from BLE_TRANSPORT_ACL_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT (10) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/porting_default (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (255) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__custom -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__custom (0) + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT (4) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x (0) + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT (16) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac (0) + +/* Overridden by @apache-mynewt-nimble/nimble/transport (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (257) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi (0) + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__custom +#define MYNEWT_VAL_BLE_TRANSPORT_HS__custom (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac +#define MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__ram -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__ram (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__native +#define MYNEWT_VAL_BLE_TRANSPORT_HS__native (1) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__socket -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__socket (1) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340 +#define MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340 (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__uart -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__uart (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__uart +#define MYNEWT_VAL_BLE_TRANSPORT_HS__uart (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__usb -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__usb (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__usb +#define MYNEWT_VAL_BLE_TRANSPORT_HS__usb (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT -#define MYNEWT_VAL_BLE_HCI_TRANSPORT (1) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS +#define MYNEWT_VAL_BLE_TRANSPORT_HS (1) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI (0) +/* Overridden by @apache-mynewt-nimble/porting/targets/porting_default (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__custom +#define MYNEWT_VAL_BLE_TRANSPORT_LL__custom (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac +#define MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__native +#define MYNEWT_VAL_BLE_TRANSPORT_LL__native (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340 +#define MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340 (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_UART -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_UART (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__socket +#define MYNEWT_VAL_BLE_TRANSPORT_LL__socket (1) #endif - -/*** @apache-mynewt-nimble/nimble/transport/socket */ -#ifndef MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT -#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL +#define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif +/*** @apache-mynewt-nimble/nimble/transport/socket */ #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif diff --git a/porting/nimble/src/nimble_port.c b/porting/nimble/src/nimble_port.c index d4824d0b37..2a81fd63fc 100644 --- a/porting/nimble/src/nimble_port.c +++ b/porting/nimble/src/nimble_port.c @@ -40,8 +40,10 @@ nimble_port_init(void) /* Initialize the global memory pool */ os_mempool_module_init(); os_msys_init(); + /* Initialize transport */ + ble_transport_init(); /* Initialize the host */ - ble_hs_init(); + ble_transport_hs_init(); #if NIMBLE_CFG_CONTROLLER ble_hci_ram_init(); @@ -49,7 +51,7 @@ nimble_port_init(void) hal_timer_init(5, NULL); os_cputime_init(32768); #endif - ble_ll_init(); + ble_transport_ll_init(); #endif } diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index a581a6d113..d7493392ff 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -15,7 +15,6 @@ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val -/*** @apache-mynewt-core/compiler/arm-none-eabi-m4 */ #ifndef MYNEWT_VAL_HARDFLOAT #define MYNEWT_VAL_HARDFLOAT (0) #endif @@ -109,6 +108,11 @@ #define MYNEWT_VAL_MCU_BUS_DRIVER_I2C_USE_TWIM (0) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_MCU_COMMON_STARTUP +#define MYNEWT_VAL_MCU_COMMON_STARTUP (1) +#endif + /* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_MCU_DCDC_ENABLED #define MYNEWT_VAL_MCU_DCDC_ENABLED (1) @@ -951,8 +955,12 @@ #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_SCA_UPDATE (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_PERIPH_INIT_FEAT_XCHG +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_PERIPH_INIT_FEAT_XCHG (MYNEWT_VAL_BLE_LL_ROLE_CENTRAL || MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL) +#endif + #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG -#define MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG (MYNEWT_VAL_BLE_LL_ROLE_CENTRAL || MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL) +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG (0) #endif /* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ @@ -968,6 +976,34 @@ #define MYNEWT_VAL_BLE_LL_CONN_INIT_SLOTS (4) #endif +#ifndef MYNEWT_VAL_BLE_LL_CONN_PHY_DEFAULT_PREF_MASK +#define MYNEWT_VAL_BLE_LL_CONN_PHY_DEFAULT_PREF_MASK (0x07) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_PHY_INIT_UPDATE +#define MYNEWT_VAL_BLE_LL_CONN_PHY_INIT_UPDATE (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_PHY_PREFER_2M +#define MYNEWT_VAL_BLE_LL_CONN_PHY_PREFER_2M (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED +#define MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED_FIXED +#define MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED_FIXED (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED_PERIOD_SLOTS +#define MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED_PERIOD_SLOTS (8) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED_SLOT_US +#define MYNEWT_VAL_BLE_LL_CONN_STRICT_SCHED_SLOT_US (3750) +#endif + #ifndef MYNEWT_VAL_BLE_LL_DEBUG_GPIO_HCI_CMD #define MYNEWT_VAL_BLE_LL_DEBUG_GPIO_HCI_CMD (-1) #endif @@ -1005,6 +1041,10 @@ #define MYNEWT_VAL_BLE_LL_EXT_ADV_AUX_PTR_CNT (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_HBD_FAKE_DUAL_MODE +#define MYNEWT_VAL_BLE_LL_HBD_FAKE_DUAL_MODE (0) +#endif + #ifndef MYNEWT_VAL_BLE_LL_HCI_LLCP_TRACE #define MYNEWT_VAL_BLE_LL_HCI_LLCP_TRACE (0) #endif @@ -1014,6 +1054,10 @@ #define MYNEWT_VAL_BLE_LL_HCI_VS (1) #endif +#ifndef MYNEWT_VAL_BLE_LL_HCI_VS_CONN_STRICT_SCHED +#define MYNEWT_VAL_BLE_LL_HCI_VS_CONN_STRICT_SCHED (0) +#endif + /* Value copied from BLE_LL_VND_EVENT_ON_ASSERT */ #ifndef MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_ON_ASSERT #define MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_ON_ASSERT (0) @@ -1109,8 +1153,9 @@ #define MYNEWT_VAL_BLE_LL_SCA (60) #endif +/* Value copied from BLE_LL_EXT_ADV_AUX_PTR_CNT */ #ifndef MYNEWT_VAL_BLE_LL_SCAN_AUX_SEGMENT_CNT -#define MYNEWT_VAL_BLE_LL_SCAN_AUX_SEGMENT_CNT (8) +#define MYNEWT_VAL_BLE_LL_SCAN_AUX_SEGMENT_CNT (0) #endif #ifndef MYNEWT_VAL_BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY @@ -1156,7 +1201,7 @@ #endif #ifndef MYNEWT_VAL_BLE_LL_USECS_PER_PERIOD -#define MYNEWT_VAL_BLE_LL_USECS_PER_PERIOD (3250) +#define MYNEWT_VAL_BLE_LL_USECS_PER_PERIOD (0) #endif #ifndef MYNEWT_VAL_BLE_LL_VND_EVENT_ON_ASSERT @@ -1606,101 +1651,96 @@ #endif /*** @apache-mynewt-nimble/nimble/transport */ -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_ACL_BUF_COUNT -#define MYNEWT_VAL_BLE_ACL_BUF_COUNT (24) -#endif +#undef MYNEWT_VAL_BLE_ACL_BUF_COUNT -/* Overridden by @apache-mynewt-nimble/nimble/transport/ram (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_ACL_BUF_SIZE -#define MYNEWT_VAL_BLE_ACL_BUF_SIZE (65535) -#endif +#undef MYNEWT_VAL_BLE_ACL_BUF_SIZE -#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE -#define MYNEWT_VAL_BLE_HCI_BRIDGE (0) -#endif +#undef MYNEWT_VAL_BLE_HCI_BRIDGE + +#undef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE -#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac -#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__dialog_cmac (0) +#undef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT + +#undef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT + +#undef MYNEWT_VAL_BLE_HCI_TRANSPORT + +#ifndef MYNEWT_VAL_BLE_TRANSPORT +#define MYNEWT_VAL_BLE_TRANSPORT (1) #endif -#ifndef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 -#define MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT__nrf5340 (0) + +/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT (24) #endif -#undef MYNEWT_VAL_BLE_HCI_BRIDGE_TRANSPORT -/* Overridden by @apache-mynewt-nimble/nimble/transport/ram (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE -#define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70) +/* Value copied from BLE_TRANSPORT_ACL_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT (24) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT -#define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (2) +/* Value copied from BLE_TRANSPORT_ACL_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT (24) #endif -/* Overridden by @apache-mynewt-nimble/nimble/transport/ram (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT -#define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (255) #endif /* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/transport) */ -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__builtin (0) -#endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__custom -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__custom (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT (2) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__da1469x (0) + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT (16) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__dialog_cmac (0) + +/* Overridden by @apache-mynewt-nimble/nimble/transport (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (257) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__emspi (0) + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__custom +#define MYNEWT_VAL_BLE_TRANSPORT_HS__custom (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__nrf5340 (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac +#define MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__ram -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__ram (1) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__native +#define MYNEWT_VAL_BLE_TRANSPORT_HS__native (1) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__socket -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__socket (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340 +#define MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340 (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__uart -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__uart (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__uart +#define MYNEWT_VAL_BLE_TRANSPORT_HS__uart (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT__usb -#define MYNEWT_VAL_BLE_HCI_TRANSPORT__usb (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__usb +#define MYNEWT_VAL_BLE_TRANSPORT_HS__usb (0) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT -#define MYNEWT_VAL_BLE_HCI_TRANSPORT (1) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS +#define MYNEWT_VAL_BLE_TRANSPORT_HS (1) #endif -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__custom +#define MYNEWT_VAL_BLE_TRANSPORT_LL__custom (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac +#define MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__native +#define MYNEWT_VAL_BLE_TRANSPORT_LL__native (1) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340 +#define MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340 (0) #endif - -#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_UART -#define MYNEWT_VAL_BLE_HCI_TRANSPORT_UART (0) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__socket +#define MYNEWT_VAL_BLE_TRANSPORT_LL__socket (0) #endif - -/*** @apache-mynewt-nimble/nimble/transport/ram */ -#ifndef MYNEWT_VAL_BLE_TRANS_RAM_SYSINIT_STAGE -#define MYNEWT_VAL_BLE_TRANS_RAM_SYSINIT_STAGE (100) +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL +#define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif /*** newt */ diff --git a/porting/targets/linux/syscfg.yml b/porting/targets/linux/syscfg.yml index 5778ee7d47..e5faa62775 100644 --- a/porting/targets/linux/syscfg.yml +++ b/porting/targets/linux/syscfg.yml @@ -17,7 +17,7 @@ # syscfg.vals: - BLE_HCI_TRANSPORT: socket + BLE_TRANSPORT_LL: socket BLE_SOCK_USE_TCP: 0 BLE_SOCK_USE_LINUX_BLUE: 1 BLE_SOCK_TASK_PRIO: 3 diff --git a/porting/targets/linux_blemesh/syscfg.yml b/porting/targets/linux_blemesh/syscfg.yml index 5e644d462a..b5e48f4400 100644 --- a/porting/targets/linux_blemesh/syscfg.yml +++ b/porting/targets/linux_blemesh/syscfg.yml @@ -43,7 +43,7 @@ syscfg.vals: BLE_MESH_SETTINGS: 0 CONFIG_NFFS: 0 - BLE_HCI_TRANSPORT: socket + BLE_TRANSPORT_LL: socket BLE_SOCK_USE_TCP: 0 BLE_SOCK_USE_LINUX_BLUE: 1 BLE_SOCK_TASK_PRIO: 3 diff --git a/porting/targets/nuttx/syscfg.yml b/porting/targets/nuttx/syscfg.yml index d2c6de7bb4..98ec29bf34 100644 --- a/porting/targets/nuttx/syscfg.yml +++ b/porting/targets/nuttx/syscfg.yml @@ -17,7 +17,7 @@ # syscfg.vals: - BLE_HCI_TRANSPORT: socket + BLE_TRANSPORT_LL: socket BLE_SOCK_USE_TCP: 0 BLE_SOCK_USE_NUTTX: 1 BLE_SOCK_TASK_PRIO: 3 diff --git a/porting/targets/porting_default/syscfg.yml b/porting/targets/porting_default/syscfg.yml index 3ffd4c279d..7c6db1ae67 100644 --- a/porting/targets/porting_default/syscfg.yml +++ b/porting/targets/porting_default/syscfg.yml @@ -1,4 +1,4 @@ syscfg.vals: - BLE_HCI_TRANSPORT: socket + BLE_TRANSPORT_LL: socket BLE_SOCK_USE_TCP: 0 BLE_SOCK_USE_LINUX_BLUE: 1 diff --git a/porting/targets/riot/syscfg.yml b/porting/targets/riot/syscfg.yml index 1d6939c1be..380c219e1b 100644 --- a/porting/targets/riot/syscfg.yml +++ b/porting/targets/riot/syscfg.yml @@ -17,9 +17,9 @@ # syscfg.vals: - BLE_ACL_BUF_COUNT: 24 BLE_HCI_VS: 1 - BLE_HCI_EVT_HI_BUF_COUNT: 2 + BLE_TRANSPORT_ACL_COUNT: 24 + BLE_TRANSPORT_EVT_COUNT: 2 BLE_HW_WHITELIST_ENABLE: 0 BLE_LL_CFG_FEAT_DATA_LEN_EXT: 0 BLE_LL_CFG_FEAT_LE_CSA2: 1 @@ -31,7 +31,6 @@ syscfg.vals: BLE_SM_LEGACY: 0 BLE_SM_SC: 0 BLE_MAX_PERIODIC_SYNCS: 0 - BLE_HCI_TRANSPORT: ram MSYS_1_BLOCK_COUNT: 5 MSYS_1_BLOCK_SIZE: 88 MCU_LFCLK_SOURCE: LFXO From 1b9d48d58087e8ef431934d59442673e631f066f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 10 Mar 2022 15:18:53 +0100 Subject: [PATCH 0350/1333] nimble/transport: Move BLE_MONITOR to transport This allows to use monitor feature without host present. --- nimble/controller/src/ble_ll.c | 4 +- nimble/host/pkg.yml | 3 - nimble/host/src/ble_hs.c | 27 +------ nimble/host/src/ble_hs_hci.c | 8 --- nimble/host/src/ble_hs_hci_cmd.c | 7 -- nimble/host/src/ble_hs_hci_evt.c | 1 - nimble/host/src/ble_hs_priv.h | 1 - nimble/host/src/ble_l2cap_sig.c | 1 - nimble/host/syscfg.yml | 38 ---------- nimble/transport/dialog_cmac/src/hci_cmac.c | 8 +-- nimble/transport/emspi/src/ble_hci_emspi.c | 4 +- nimble/transport/include/nimble/transport.h | 23 +++--- .../include/nimble/transport/monitor.h} | 38 ++++++++-- .../transport/include/nimble/transport_impl.h | 47 ++++++++++++ .../transport/nrf5340/src/nrf5340_ble_hci.c | 8 +-- nimble/transport/pkg.yml | 6 ++ nimble/transport/socket/src/ble_hci_socket.c | 4 +- .../ble_monitor.c => transport/src/monitor.c} | 72 ++++++++++++++----- .../src/monitor_priv.h} | 2 - nimble/transport/syscfg.monitor.yml | 58 +++++++++++++++ nimble/transport/syscfg.yml | 3 +- nimble/transport/uart/src/hci_uart.c | 4 +- nimble/transport/usb/src/ble_hci_usb.c | 4 +- 23 files changed, 229 insertions(+), 142 deletions(-) rename nimble/{host/include/host/ble_monitor.h => transport/include/nimble/transport/monitor.h} (60%) create mode 100644 nimble/transport/include/nimble/transport_impl.h rename nimble/{host/src/ble_monitor.c => transport/src/monitor.c} (88%) rename nimble/{host/src/ble_monitor_priv.h => transport/src/monitor_priv.h} (99%) create mode 100644 nimble/transport/syscfg.monitor.yml diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 73168b43c9..84b8a4e1c9 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1968,13 +1968,13 @@ ble_ll_init(void) /* Transport APIs for LL side */ int -ble_transport_to_ll_cmd(void *buf) +ble_transport_to_ll_cmd_impl(void *buf) { return ble_ll_hci_cmd_rx(buf, NULL); } int -ble_transport_to_ll_acl(struct os_mbuf *om) +ble_transport_to_ll_acl_impl(struct os_mbuf *om) { return ble_ll_hci_acl_rx(om, NULL); } diff --git a/nimble/host/pkg.yml b/nimble/host/pkg.yml index b28979269e..c069283cf0 100644 --- a/nimble/host/pkg.yml +++ b/nimble/host/pkg.yml @@ -38,9 +38,6 @@ pkg.deps.BLE_SM_LEGACY: pkg.deps.BLE_SM_SC: - "@apache-mynewt-core/crypto/tinycrypt" -pkg.deps.BLE_MONITOR_RTT: - - "@apache-mynewt-core/hw/drivers/rtt" - pkg.deps.BLE_MESH: - nimble/host/mesh diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index ba601b6136..13b6fe29e4 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -25,7 +25,6 @@ #include "stats/stats.h" #include "host/ble_hs.h" #include "ble_hs_priv.h" -#include "ble_monitor_priv.h" #include "nimble/nimble_npl.h" #ifndef MYNEWT #include "nimble/nimble_port.h" @@ -220,10 +219,6 @@ ble_hs_process_rx_data_queue(void) struct os_mbuf *om; while ((om = ble_mqueue_get(&ble_hs_rx_q)) != NULL) { -#if BLE_MONITOR - ble_monitor_send_om(BLE_MONITOR_OPCODE_ACL_RX_PKT, om); -#endif - ble_hs_hci_evt_acl_process(om); } } @@ -498,11 +493,6 @@ ble_hs_event_rx_hci_ev(struct ble_npl_event *ev) rc = os_memblock_put(&ble_hs_hci_ev_pool, ev); BLE_HS_DBG_ASSERT_EVAL(rc == 0); -#if BLE_MONITOR - ble_monitor_send(BLE_MONITOR_OPCODE_EVENT_PKT, hci_ev, - hci_ev->length + sizeof(*hci_ev)); -#endif - ble_hs_hci_evt_process(hci_ev); } @@ -696,10 +686,6 @@ ble_hs_rx_data(struct os_mbuf *om, void *arg) int ble_hs_tx_data(struct os_mbuf *om) { -#if BLE_MONITOR - ble_monitor_send_om(BLE_MONITOR_OPCODE_ACL_TX_PKT, om); -#endif - return ble_transport_to_ll_acl(om); } @@ -784,11 +770,6 @@ ble_hs_init(void) ble_hs_evq_set(nimble_port_get_dflt_eventq()); #endif -#if BLE_MONITOR - rc = ble_monitor_init(); - SYSINIT_PANIC_ASSERT(rc == 0); -#endif - /* Enqueue the start event to the default event queue. Using the default * queue ensures the event won't run until the end of main(). This allows * the application to configure this package in the meantime. @@ -801,22 +782,18 @@ ble_hs_init(void) ble_npl_eventq_put(nimble_port_get_dflt_eventq(), &ble_hs_ev_start_stage1); #endif #endif - -#if BLE_MONITOR - ble_monitor_new_index(0, (uint8_t[6]){ }, "nimble0"); -#endif } /* Transport APIs for HS side */ int -ble_transport_to_hs_evt(void *buf) +ble_transport_to_hs_evt_impl(void *buf) { return ble_hs_hci_rx_evt(buf, NULL); } int -ble_transport_to_hs_acl(struct os_mbuf *om) +ble_transport_to_hs_acl_impl(struct os_mbuf *om) { return ble_hs_rx_data(om, NULL); } diff --git a/nimble/host/src/ble_hs_hci.c b/nimble/host/src/ble_hs_hci.c index 2157610249..0624e387d1 100644 --- a/nimble/host/src/ble_hs_hci.c +++ b/nimble/host/src/ble_hs_hci.c @@ -22,9 +22,7 @@ #include #include "os/os.h" #include "mem/mem.h" -#include "host/ble_monitor.h" #include "ble_hs_priv.h" -#include "ble_monitor_priv.h" #define BLE_HCI_CMD_TIMEOUT_MS 2000 @@ -278,12 +276,6 @@ ble_hs_hci_wait_for_ack(void) switch (rc) { case 0: BLE_HS_DBG_ASSERT(ble_hs_hci_ack != NULL); - -#if BLE_MONITOR - ble_monitor_send(BLE_MONITOR_OPCODE_EVENT_PKT, (void *) ble_hs_hci_ack, - sizeof(*ble_hs_hci_ack) + ble_hs_hci_ack->length); -#endif - break; case OS_TIMEOUT: rc = BLE_HS_ETIMEOUT_HCI; diff --git a/nimble/host/src/ble_hs_hci_cmd.c b/nimble/host/src/ble_hs_hci_cmd.c index 33e1ae8bde..689cb1765b 100644 --- a/nimble/host/src/ble_hs_hci_cmd.c +++ b/nimble/host/src/ble_hs_hci_cmd.c @@ -23,20 +23,13 @@ #include #include "os/os.h" #include "nimble/hci_common.h" -#include "host/ble_monitor.h" #include "ble_hs_priv.h" -#include "ble_monitor_priv.h" static int ble_hs_hci_cmd_transport(struct ble_hci_cmd *cmd) { int rc; -#if BLE_MONITOR - ble_monitor_send(BLE_MONITOR_OPCODE_COMMAND_PKT, cmd, - cmd->length + sizeof(*cmd)); -#endif - rc = ble_transport_to_ll_cmd(cmd); switch (rc) { case 0: diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 3dba0bf658..62de50e0b9 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -23,7 +23,6 @@ #include "os/os.h" #include "nimble/hci_common.h" #include "host/ble_gap.h" -#include "host/ble_monitor.h" #include "ble_hs_priv.h" _Static_assert(sizeof (struct hci_data_hdr) == BLE_HCI_DATA_HDR_SZ, diff --git a/nimble/host/src/ble_hs_priv.h b/nimble/host/src/ble_hs_priv.h index a57ec3cc86..044b30cc91 100644 --- a/nimble/host/src/ble_hs_priv.h +++ b/nimble/host/src/ble_hs_priv.h @@ -42,7 +42,6 @@ #include "ble_hs_periodic_sync_priv.h" #include "ble_uuid_priv.h" #include "host/ble_hs.h" -#include "host/ble_monitor.h" #include "nimble/nimble_opt.h" #include "stats/stats.h" #ifdef __cplusplus diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index 3033e05dd5..5263852785 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -45,7 +45,6 @@ #include #include #include "nimble/ble.h" -#include "host/ble_monitor.h" #include "ble_hs_priv.h" #if NIMBLE_BLE_CONNECT diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index 5f67c446de..ce2acc48dd 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -44,44 +44,6 @@ syscfg.defs: simulator. value: 1 - # Monitor interface settings - BLE_MONITOR_UART: - description: Enables monitor interface over UART - value: 0 - BLE_MONITOR_UART_DEV: - description: Monitor interface UART device - value: '"uart0"' - BLE_MONITOR_UART_BAUDRATE: - description: Baudrate for monitor interface UART - value: 1000000 - BLE_MONITOR_UART_BUFFER_SIZE: - description: > - Monitor interface ringbuffer size for UART. - This value should be a power of 2. - value: 64 - BLE_MONITOR_RTT: - description: Enables monitor interface over RTT - value: 0 - BLE_MONITOR_RTT_BUFFER_NAME: - description: Monitor interface upstream buffer name - value: '"btmonitor"' - BLE_MONITOR_RTT_BUFFER_SIZE: - description: Monitor interface upstream buffer size - value: 256 - BLE_MONITOR_RTT_BUFFERED: - description: > - Enables buffering when using monitor interface over RTT. The data - are written to RTT once complete packet is created in intermediate - buffer. This allows to skip complete packet if there is not enough - space in RTT buffer (e.g. there is no reader connected). If disabled, - monitor will simply block waiting for RTT to free space in buffer. - value: 1 - BLE_MONITOR_CONSOLE_BUFFER_SIZE: - description: > - Size of internal buffer for console output. Any line exceeding this - length value will be split. - value: 128 - # L2CAP settings. BLE_L2CAP_MAX_CHANS: description: > diff --git a/nimble/transport/dialog_cmac/src/hci_cmac.c b/nimble/transport/dialog_cmac/src/hci_cmac.c index 254e0db0ca..e0702a03b0 100644 --- a/nimble/transport/dialog_cmac/src/hci_cmac.c +++ b/nimble/transport/dialog_cmac/src/hci_cmac.c @@ -165,7 +165,7 @@ ble_transport_hs_init(void) #if !MYNEWT_VAL(BLE_CONTROLLER) int -ble_transport_to_ll_cmd(void *buf) +ble_transport_to_ll_cmd_impl(void *buf) { uint8_t pkt_type = HCI_H4_CMD; uint8_t *cmd = buf; @@ -179,7 +179,7 @@ ble_transport_to_ll_cmd(void *buf) } int -ble_transport_to_ll_acl(struct os_mbuf *om) +ble_transport_to_ll_acl_impl(struct os_mbuf *om) { return hci_cmac_acl_tx(om); } @@ -187,13 +187,13 @@ ble_transport_to_ll_acl(struct os_mbuf *om) #if MYNEWT_VAL(BLE_CONTROLLER) int -ble_transport_to_hs_acl(struct os_mbuf *om) +ble_transport_to_hs_acl_impl(struct os_mbuf *om) { return hci_cmac_acl_tx(om); } int -ble_transport_to_hs_evt(void *buf) +ble_transport_to_hs_evt_impl(void *buf) { uint8_t pkt_type = HCI_H4_EVT; uint8_t *evt = buf; diff --git a/nimble/transport/emspi/src/ble_hci_emspi.c b/nimble/transport/emspi/src/ble_hci_emspi.c index e49d3d48a3..d07820f7bb 100644 --- a/nimble/transport/emspi/src/ble_hci_emspi.c +++ b/nimble/transport/emspi/src/ble_hci_emspi.c @@ -686,13 +686,13 @@ ble_transport_ll_init(void) } int -ble_transport_to_ll_cmd(void *buf) +ble_transport_to_ll_cmd_impl(void *buf) { return ble_hci_emspi_cmdevt_tx(buf, BLE_HCI_EMSPI_PKT_CMD); } int -ble_transport_to_ll_acl(struct os_mbuf *om) +ble_transport_to_ll_acl_impl(struct os_mbuf *om) { return ble_hci_emspi_acl_tx(om); } \ No newline at end of file diff --git a/nimble/transport/include/nimble/transport.h b/nimble/transport/include/nimble/transport.h index 7149d8710f..9e0eb66951 100644 --- a/nimble/transport/include/nimble/transport.h +++ b/nimble/transport/include/nimble/transport.h @@ -24,17 +24,10 @@ extern "C" { #endif -struct os_mbuf; - -/* Init functions to be implemented for transport acting as HS/LL side */ -extern void ble_transport_ll_init(void); -extern void ble_transport_hs_init(void); +#include +#include -/* APIs to be implemented by HS/LL side of transports */ -extern int ble_transport_to_ll_cmd(void *buf); -extern int ble_transport_to_ll_acl(struct os_mbuf *om); -extern int ble_transport_to_hs_evt(void *buf); -extern int ble_transport_to_hs_acl(struct os_mbuf *om); +struct os_mbuf; /* Allocators for supported data types */ void *ble_transport_alloc_cmd(void); @@ -48,11 +41,11 @@ void ble_transport_free(void *buf); /* Register put callback on acl_from_ll mbufs (for ll-hs flow control) */ int ble_transport_register_put_acl_from_ll_cb(os_mempool_put_fn *cb); -#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) -/* To be implemented if transport supports internal flow control between cores */ -extern int ble_transport_int_flow_ctl_get(void); -extern void ble_transport_int_flow_ctl_put(void); -#endif +/* Send data to hs/ll side */ +int ble_transport_to_ll_cmd(void *buf); +int ble_transport_to_ll_acl(struct os_mbuf *om); +int ble_transport_to_hs_evt(void *buf); +int ble_transport_to_hs_acl(struct os_mbuf *om); #ifdef __cplusplus } diff --git a/nimble/host/include/host/ble_monitor.h b/nimble/transport/include/nimble/transport/monitor.h similarity index 60% rename from nimble/host/include/host/ble_monitor.h rename to nimble/transport/include/nimble/transport/monitor.h index 61722f7dbc..6b56f123b2 100644 --- a/nimble/host/include/host/ble_monitor.h +++ b/nimble/transport/include/nimble/transport/monitor.h @@ -22,16 +22,46 @@ #include -#undef BLE_MONITOR -#define BLE_MONITOR (MYNEWT_VAL(BLE_MONITOR_UART) || MYNEWT_VAL(BLE_MONITOR_RTT)) - #ifdef __cplusplus extern "C" { #endif +#define BLE_MONITOR (MYNEWT_VAL(BLE_MONITOR_RTT) || \ + MYNEWT_VAL(BLE_MONITOR_UART)) + +#if BLE_MONITOR int ble_monitor_log(int level, const char *fmt, ...); +#else +static inline int +ble_monitor_log(int level, const char *fmt, ...) +{ + return 0; +} + +static inline int +ble_transport_to_ll_cmd(void *buf) +{ + return ble_transport_to_ll_cmd_impl(buf); +} -int ble_monitor_out(int c); +static inline int +ble_transport_to_ll_acl(struct os_mbuf *om) +{ + return ble_transport_to_ll_acl_impl(om); +} + +static inline int +ble_transport_to_hs_evt(void *buf) +{ + return ble_transport_to_hs_evt_impl(buf); +} + +static inline int +ble_transport_to_hs_acl(struct os_mbuf *om) +{ + return ble_transport_to_hs_acl_impl(om); +} +#endif /* BLE_MONITOR */ #ifdef __cplusplus } diff --git a/nimble/transport/include/nimble/transport_impl.h b/nimble/transport/include/nimble/transport_impl.h new file mode 100644 index 0000000000..61d8cd68a3 --- /dev/null +++ b/nimble/transport/include/nimble/transport_impl.h @@ -0,0 +1,47 @@ +/* + * 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_NIMBLE_TRANSPORT_IMPL_ +#define H_NIMBLE_TRANSPORT_IMPL_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Init functions to be implemented for transport acting as HS/LL side */ +extern void ble_transport_ll_init(void); +extern void ble_transport_hs_init(void); + +/* APIs to be implemented by HS/LL side of transports */ +extern int ble_transport_to_ll_cmd_impl(void *buf); +extern int ble_transport_to_ll_acl_impl(struct os_mbuf *om); +extern int ble_transport_to_hs_evt_impl(void *buf); +extern int ble_transport_to_hs_acl_impl(struct os_mbuf *om); + +#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) +/* To be implemented if transport supports internal flow control between cores */ +extern int ble_transport_int_flow_ctl_get(void); +extern void ble_transport_int_flow_ctl_put(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* H_NIMBLE_TRANSPORT_IMPL_ */ diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index eee27c9b62..111c048039 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -115,7 +115,7 @@ nrf5340_ble_hci_init(void) #if MYNEWT_VAL(BLE_CONTROLLER) int -ble_transport_to_hs_evt(void *buf) +ble_transport_to_hs_evt_impl(void *buf) { uint8_t ind = HCI_H4_EVT; uint8_t* hci_ev = buf; @@ -133,7 +133,7 @@ ble_transport_to_hs_evt(void *buf) } int -ble_transport_to_hs_acl(struct os_mbuf *om) +ble_transport_to_hs_acl_impl(struct os_mbuf *om) { return nrf5340_ble_hci_acl_tx(om); } @@ -149,7 +149,7 @@ ble_transport_hs_init(void) #if !MYNEWT_VAL(BLE_CONTROLLER) int -ble_transport_to_ll_cmd(void *buf) +ble_transport_to_ll_cmd_impl(void *buf) { uint8_t ind = HCI_H4_CMD; uint8_t *cmd = buf; @@ -167,7 +167,7 @@ ble_transport_to_ll_cmd(void *buf) } int -ble_transport_to_ll_acl(struct os_mbuf *om) +ble_transport_to_ll_acl_impl(struct os_mbuf *om) { return nrf5340_ble_hci_acl_tx(om); } diff --git a/nimble/transport/pkg.yml b/nimble/transport/pkg.yml index bedcb160e8..12b9f40acb 100644 --- a/nimble/transport/pkg.yml +++ b/nimble/transport/pkg.yml @@ -45,6 +45,9 @@ pkg.deps.'BLE_TRANSPORT_HS == "uart"': pkg.deps.'BLE_TRANSPORT_HS == "usb"': - nimble/transport/usb +pkg.deps.BLE_MONITOR_RTT: + - "@apache-mynewt-core/hw/drivers/rtt" + pkg.init: ble_transport_init: 250 ble_transport_hs_init: @@ -52,3 +55,6 @@ pkg.init: - $before:ble_transport_ll_init ble_transport_ll_init: - $after:ble_transport_hs_init + +pkg.init.'BLE_MONITOR_RTT || BLE_MONITOR_UART': + ble_monitor_init: $before:ble_transport_init diff --git a/nimble/transport/socket/src/ble_hci_socket.c b/nimble/transport/socket/src/ble_hci_socket.c index ee974ec3f3..5dd1d17df7 100644 --- a/nimble/transport/socket/src/ble_hci_socket.c +++ b/nimble/transport/socket/src/ble_hci_socket.c @@ -839,13 +839,13 @@ ble_transport_ll_init(void) } int -ble_transport_to_ll_acl(struct os_mbuf *om) +ble_transport_to_ll_acl_impl(struct os_mbuf *om) { return ble_hci_trans_hs_acl_tx(om); } int -ble_transport_to_ll_cmd(void *buf) +ble_transport_to_ll_cmd_impl(void *buf) { return ble_hci_trans_hs_cmd_tx(buf); } diff --git a/nimble/host/src/ble_monitor.c b/nimble/transport/src/monitor.c similarity index 88% rename from nimble/host/src/ble_monitor.c rename to nimble/transport/src/monitor.c index b86e7771f8..88309149bc 100644 --- a/nimble/host/src/ble_monitor.c +++ b/nimble/transport/src/monitor.c @@ -17,13 +17,9 @@ * under the License. */ -#include "host/ble_monitor.h" +#include -#if BLE_MONITOR - -#if MYNEWT_VAL(BLE_MONITOR_UART) && MYNEWT_VAL(BLE_MONITOR_RTT) -#error "Cannot enable monitor over UART and RTT at the same time!" -#endif +#if MYNEWT_VAL(BLE_MONITOR_RTT) || MYNEWT_VAL(BLE_MONITOR_UART) #ifdef BABBLESIM #define _GNU_SOURCE @@ -41,8 +37,10 @@ #if MYNEWT_VAL(BLE_MONITOR_RTT) #include "rtt/SEGGER_RTT.h" #endif -#include "ble_hs_priv.h" -#include "ble_monitor_priv.h" +#include +#include +#include +#include "monitor_priv.h" struct ble_npl_mutex lock; @@ -297,9 +295,11 @@ drops_tmp_cb(struct ble_npl_event *ev) } #endif -int +void ble_monitor_init(void) { + SYSINIT_ASSERT_ACTIVE(); + #if MYNEWT_VAL(BLE_MONITOR_UART) struct uart_conf uc = { .uc_speed = MYNEWT_VAL(BLE_MONITOR_UART_BAUDRATE), @@ -314,14 +314,12 @@ ble_monitor_init(void) uart = (struct uart_dev *)os_dev_open(MYNEWT_VAL(BLE_MONITOR_UART_DEV), OS_TIMEOUT_NEVER, &uc); - if (!uart) { - return -1; - } + SYSINIT_PANIC_ASSERT(uart); #endif #if MYNEWT_VAL(BLE_MONITOR_RTT) #if MYNEWT_VAL(BLE_MONITOR_RTT_BUFFERED) - ble_npl_callout_init(&rtt_drops.tmo, ble_hs_evq_get(), drops_tmp_cb, NULL); + ble_npl_callout_init(&rtt_drops.tmo, ble_npl_eventq_dflt_get(), drops_tmp_cb, NULL); /* Initialize types in header (we won't touch them later) */ rtt_drops.drops_hdr.type_cmd = BLE_MONITOR_EXTHDR_COMMAND_DROPS; @@ -339,14 +337,14 @@ ble_monitor_init(void) SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL); #endif - if (rtt_index < 0) { - return -1; - } + SYSINIT_PANIC_ASSERT(rtt_index >= 0); #endif ble_npl_mutex_init(&lock); - return 0; +#if BLE_MONITOR + ble_monitor_new_index(0, (uint8_t[6]){ }, "nimble0"); +#endif } int @@ -492,4 +490,42 @@ ble_monitor_out(int c) return c; } -#endif +int +ble_transport_to_ll_cmd(void *buf) +{ + struct ble_hci_cmd *cmd = buf; + + ble_monitor_send(BLE_MONITOR_OPCODE_COMMAND_PKT, buf, cmd->length + + sizeof(*cmd)); + + return ble_transport_to_ll_cmd_impl(buf); +} + +int +ble_transport_to_ll_acl(struct os_mbuf *om) +{ + ble_monitor_send_om(BLE_MONITOR_OPCODE_ACL_TX_PKT, om); + + return ble_transport_to_ll_acl_impl(om); +} + +int +ble_transport_to_hs_acl(struct os_mbuf *om) +{ + ble_monitor_send_om(BLE_MONITOR_OPCODE_ACL_RX_PKT, om); + + return ble_transport_to_hs_acl_impl(om); +} + +int +ble_transport_to_hs_evt(void *buf) +{ + struct ble_hci_ev *ev = buf; + + ble_monitor_send(BLE_MONITOR_OPCODE_EVENT_PKT, buf, ev->length + + sizeof(*ev)); + + return ble_transport_to_hs_evt_impl(buf); +} + +#endif /* MYNEWT_VAL(BLE_MONITOR_RTT) || MYNEWT_VAL(BLE_MONITOR_UART) */ diff --git a/nimble/host/src/ble_monitor_priv.h b/nimble/transport/src/monitor_priv.h similarity index 99% rename from nimble/host/src/ble_monitor_priv.h rename to nimble/transport/src/monitor_priv.h index 935787040f..0fb96509d9 100644 --- a/nimble/host/src/ble_monitor_priv.h +++ b/nimble/transport/src/monitor_priv.h @@ -85,8 +85,6 @@ struct ble_monitor_user_logging { uint8_t ident_len; } __attribute__((packed)); -int ble_monitor_init(void); - int ble_monitor_send(uint16_t opcode, const void *data, size_t len); int ble_monitor_send_om(uint16_t opcode, const struct os_mbuf *om); diff --git a/nimble/transport/syscfg.monitor.yml b/nimble/transport/syscfg.monitor.yml new file mode 100644 index 0000000000..7cfbc416fd --- /dev/null +++ b/nimble/transport/syscfg.monitor.yml @@ -0,0 +1,58 @@ +# 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. +# + +syscfg.defs: + BLE_MONITOR_UART: + description: Enables monitor interface over UART + value: 0 + BLE_MONITOR_UART_DEV: + description: Monitor interface UART device + value: '"uart0"' + BLE_MONITOR_UART_BAUDRATE: + description: Baudrate for monitor interface UART + value: 1000000 + BLE_MONITOR_UART_BUFFER_SIZE: + description: > + Monitor interface ringbuffer size for UART. + This value should be a power of 2. + value: 64 + BLE_MONITOR_RTT: + description: Enables monitor interface over RTT + value: 0 + BLE_MONITOR_RTT_BUFFER_NAME: + description: Monitor interface upstream buffer name + value: '"btmonitor"' + BLE_MONITOR_RTT_BUFFER_SIZE: + description: Monitor interface upstream buffer size + value: 256 + BLE_MONITOR_RTT_BUFFERED: + description: > + Enables buffering when using monitor interface over RTT. The data + are written to RTT once complete packet is created in intermediate + buffer. This allows to skip complete packet if there is not enough + space in RTT buffer (e.g. there is no reader connected). If disabled, + monitor will simply block waiting for RTT to free space in buffer. + value: 1 + BLE_MONITOR_CONSOLE_BUFFER_SIZE: + description: > + Size of internal buffer for console output. Any line exceeding this + length value will be split. + value: 128 + +syscfg.restrictions: + - '!(BLE_MONITOR_UART && BLE_MONITOR_RTT)' diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml index 5f61a0193d..4985250fd0 100644 --- a/nimble/transport/syscfg.yml +++ b/nimble/transport/syscfg.yml @@ -86,8 +86,9 @@ syscfg.defs: of ACL buffers available for controller. value: MYNEWT_VAL(BLE_TRANSPORT_ACL_COUNT) -# import defunct settings from separate file to reduce clutter in main file +# import monitor and defunct settings from separate file to reduce clutter in main file $import: + - "@apache-mynewt-nimble/nimble/transport/syscfg.monitor.yml" - "@apache-mynewt-nimble/nimble/transport/syscfg.defunct.yml" syscfg.vals."BLE_EXT_ADV || BLE_LL_CFG_FEAT_LL_EXT_ADV": diff --git a/nimble/transport/uart/src/hci_uart.c b/nimble/transport/uart/src/hci_uart.c index 9ffcc90f1f..f44b9904cf 100644 --- a/nimble/transport/uart/src/hci_uart.c +++ b/nimble/transport/uart/src/hci_uart.c @@ -172,7 +172,7 @@ hci_uart_configure(void) } int -ble_transport_to_hs_evt(void *buf) +ble_transport_to_hs_evt_impl(void *buf) { struct hci_uart_tx *txe; os_sr_t sr; @@ -200,7 +200,7 @@ ble_transport_to_hs_evt(void *buf) } int -ble_transport_to_hs_acl(struct os_mbuf *om) +ble_transport_to_hs_acl_impl(struct os_mbuf *om) { struct hci_uart_tx *txe; os_sr_t sr; diff --git a/nimble/transport/usb/src/ble_hci_usb.c b/nimble/transport/usb/src/ble_hci_usb.c index 6518cd9481..01c60b88d9 100644 --- a/nimble/transport/usb/src/ble_hci_usb.c +++ b/nimble/transport/usb/src/ble_hci_usb.c @@ -242,13 +242,13 @@ ble_hci_trans_ll_evt_tx(void *buf) } int -ble_transport_to_hs_acl(struct os_mbuf *om) +ble_transport_to_hs_acl_impl(struct os_mbuf *om) { return ble_hci_trans_ll_tx(&ble_hci_tx_acl_queue, om); } int -ble_transport_to_hs_evt(void *buf) +ble_transport_to_hs_evt_impl(void *buf) { return ble_hci_trans_ll_evt_tx(buf); } From f1a5658408eed1a78f8e17a83c6e44e8d25686fd Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 17 Mar 2022 10:14:22 +0100 Subject: [PATCH 0351/1333] targets: Update to new transport --- targets/dialog_cmac/syscfg.yml | 2 +- targets/nordic_pca10056-blehci-usb/syscfg.yml | 2 +- targets/nordic_pca10095_net-blehci/syscfg.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/targets/dialog_cmac/syscfg.yml b/targets/dialog_cmac/syscfg.yml index 3a8895d7db..71a109a286 100644 --- a/targets/dialog_cmac/syscfg.yml +++ b/targets/dialog_cmac/syscfg.yml @@ -22,7 +22,7 @@ syscfg.vals: MCU_SLP_TIMER: 1 MCU_SLP_TIMER_32K_ONLY: 1 - BLE_HCI_TRANSPORT: dialog_cmac + BLE_TRANSPORT_HS: dialog_cmac # LL recommended settings (decreasing timing values is not recommended) BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL: 1 diff --git a/targets/nordic_pca10056-blehci-usb/syscfg.yml b/targets/nordic_pca10056-blehci-usb/syscfg.yml index e664792eaa..f2579c14f7 100644 --- a/targets/nordic_pca10056-blehci-usb/syscfg.yml +++ b/targets/nordic_pca10056-blehci-usb/syscfg.yml @@ -1,5 +1,5 @@ syscfg.vals: - BLE_HCI_TRANSPORT: usb + BLE_TRANSPORT_HS: usb USBD_BTH: 1 USBD_PID: 0xC01A diff --git a/targets/nordic_pca10095_net-blehci/syscfg.yml b/targets/nordic_pca10095_net-blehci/syscfg.yml index 4a4a1ba069..b679e9ae7a 100644 --- a/targets/nordic_pca10095_net-blehci/syscfg.yml +++ b/targets/nordic_pca10095_net-blehci/syscfg.yml @@ -18,7 +18,7 @@ # syscfg.vals: - BLE_HCI_TRANSPORT: nrf5340 + BLE_TRANSPORT_HS: nrf5340 MSYS_1_BLOCK_COUNT: 12 MSYS_1_BLOCK_SIZE: 292 From 847c04726899801b5fae11efb34e2e94089401c2 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 17 Mar 2022 12:05:05 +0100 Subject: [PATCH 0352/1333] nimble/transport: Fix typo --- nimble/transport/src/transport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/transport/src/transport.c b/nimble/transport/src/transport.c index 1eea5adcee..0a641a807b 100644 --- a/nimble/transport/src/transport.c +++ b/nimble/transport/src/transport.c @@ -80,11 +80,11 @@ ble_transport_alloc_cmd(void) } void * -ble_transport_alloc_evt(int discarcable) +ble_transport_alloc_evt(int discardable) { void *buf; - if (discarcable) { + if (discardable) { buf = os_memblock_get(&pool_evt_lo); } else { buf = os_memblock_get(&pool_evt); From a8d2fa406338e73c34303a089346d14a388980a0 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 17 Mar 2022 12:08:12 +0100 Subject: [PATCH 0353/1333] apps/btshell: Fix build --- apps/btshell/src/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index 7741050144..e6f2f565df 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -33,7 +33,6 @@ /* BLE */ #include "nimble/ble.h" #include "nimble/nimble_opt.h" -#include "nimble/ble_hci_trans.h" #include "host/ble_hs.h" #include "host/ble_hs_adv.h" #include "host/ble_uuid.h" From 336eff834ebc7cd7685fe1daf754e37473edca5b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 18 Mar 2022 16:40:44 +0100 Subject: [PATCH 0354/1333] nimble/host: Fix tests compilation This fix build regression after BLE_MONITOR was moved to transport. --- nimble/host/test/src/ble_hs_test_util.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nimble/host/test/src/ble_hs_test_util.c b/nimble/host/test/src/ble_hs_test_util.c index 6a838169b1..c336ddf923 100644 --- a/nimble/host/test/src/ble_hs_test_util.c +++ b/nimble/host/test/src/ble_hs_test_util.c @@ -1849,14 +1849,14 @@ ble_hs_test_util_assert_mbufs_freed( } int -ble_transport_to_ll_acl(struct os_mbuf *om) +ble_transport_to_ll_acl_impl(struct os_mbuf *om) { ble_hs_test_util_prev_tx_enqueue(om); return 0; } int -ble_transport_to_ll_cmd(void *buf) +ble_transport_to_ll_cmd_impl(void *buf) { ble_hs_test_util_hci_out_enqueue(buf); ble_transport_free(buf); @@ -2046,4 +2046,4 @@ void ble_transport_ll_init(void) { /* nothing here */ -} \ No newline at end of file +} From ade6169bb27bb7005f55a5a9decbe8d11d2ddf74 Mon Sep 17 00:00:00 2001 From: baohongde <1256181400@qq.com> Date: Sun, 29 Aug 2021 15:57:53 +0800 Subject: [PATCH 0355/1333] Change GATT notify/indicate from gattc to gatts --- apps/blecsc/src/gatt_svr.c | 4 +- apps/blehr/src/main.c | 2 +- apps/blestress/src/rx_stress.c | 8 +-- apps/bttester/src/gatt.c | 4 +- nimble/host/include/host/ble_gatt.h | 21 +++++++ nimble/host/mesh/src/pb_gatt_srv.c | 2 +- nimble/host/mesh/src/proxy_srv.c | 2 +- nimble/host/services/ans/src/ble_svc_ans.c | 4 +- nimble/host/services/bleuart/src/bleuart.c | 2 +- nimble/host/src/ble_att_clt.c | 2 +- nimble/host/src/ble_gatt_priv.h | 2 +- nimble/host/src/ble_gattc.c | 66 +++++++++++++++----- nimble/host/src/ble_gatts.c | 10 +-- nimble/host/test/src/ble_gatt_conn_test.c | 4 +- nimble/host/test/src/ble_gatts_notify_test.c | 4 +- 15 files changed, 98 insertions(+), 39 deletions(-) diff --git a/apps/blecsc/src/gatt_svr.c b/apps/blecsc/src/gatt_svr.c index e66aa9a8b0..0c178c0ca7 100644 --- a/apps/blecsc/src/gatt_svr.c +++ b/apps/blecsc/src/gatt_svr.c @@ -264,7 +264,7 @@ gatt_svr_chr_access_sc_control_point(uint16_t conn_handle, } #endif - rc = ble_gattc_indicate_custom(conn_handle, csc_control_point_handle, + rc = ble_gatts_indicate_custom(conn_handle, csc_control_point_handle, om_indication); return rc; @@ -321,7 +321,7 @@ gatt_svr_chr_notify_csc_measurement(uint16_t conn_handle) om = ble_hs_mbuf_from_flat(data_buf, data_offset); - rc = ble_gattc_notify_custom(conn_handle, csc_measurement_handle, om); + rc = ble_gatts_notify_custom(conn_handle, csc_measurement_handle, om); return rc; } diff --git a/apps/blehr/src/main.c b/apps/blehr/src/main.c index bf0f3f302c..e09349fa51 100644 --- a/apps/blehr/src/main.c +++ b/apps/blehr/src/main.c @@ -146,7 +146,7 @@ blehr_tx_hrate(struct os_event *ev) om = ble_hs_mbuf_from_flat(hrm, sizeof(hrm)); - rc = ble_gattc_notify_custom(conn_handle, hrs_hrm_handle, om); + rc = ble_gatts_notify_custom(conn_handle, hrs_hrm_handle, om); assert(rc == 0); blehr_tx_hrate_reset(); diff --git a/apps/blestress/src/rx_stress.c b/apps/blestress/src/rx_stress.c index a9d9cda09a..2761196ca9 100644 --- a/apps/blestress/src/rx_stress.c +++ b/apps/blestress/src/rx_stress.c @@ -1005,7 +1005,7 @@ rx_stress_12_gap_event(struct ble_gap_event *event, void *arg) rx_stress_ctx->begin_us = os_get_uptime_usec(); om = os_msys_get_pkthdr(om_len, 0); stress_fill_mbuf_with_pattern(om, om_len); - rc = ble_gattc_indicate_custom(rx_stress_ctx->conn_handle, hrs_hrm_handle, + rc = ble_gatts_indicate_custom(rx_stress_ctx->conn_handle, hrs_hrm_handle, om); assert(rc == 0); return 0; @@ -1020,7 +1020,7 @@ rx_stress_13_notify_ev_func(struct ble_npl_event *ev) int rc; om = ble_hs_mbuf_from_flat(test_6_pattern, 10); - rc = ble_gattc_notify_custom(rx_stress_ctx->conn_handle, + rc = ble_gatts_notify_custom(rx_stress_ctx->conn_handle, hrs_hrm_handle, om); assert(rc == 0); @@ -1142,7 +1142,7 @@ rx_stress_14_gap_event(struct ble_gap_event *event, void *arg) /* Notify data pattern */ om = ble_hs_mbuf_from_flat(test_6_pattern, bytes_num); - rc = ble_gattc_notify_custom(rx_stress_ctx->conn_handle, + rc = ble_gatts_notify_custom(rx_stress_ctx->conn_handle, hrs_hrm_handle, om); assert(rc == 0); @@ -1459,7 +1459,7 @@ rx_stress_main_task_fn(void *arg) if (i == 7 || i == 8 || i == 13) { /* 7,8: PHY update tests cause that the device during the next test * will stuck somewhere and will reset. Skip them for now. - * 13: Should work after fixing ble_gattc_notify_custom (nimble issue on GitHub)*/ + * 13: Should work after fixing ble_gatts_notify_custom (nimble issue on GitHub)*/ continue; } /* Start test. */ diff --git a/apps/bttester/src/gatt.c b/apps/bttester/src/gatt.c index d40de262bc..130d9f1ee8 100644 --- a/apps/bttester/src/gatt.c +++ b/apps/bttester/src/gatt.c @@ -1978,12 +1978,12 @@ void notify_test(struct os_event *ev) om = ble_hs_mbuf_from_flat(ntf, sizeof(ntf)); if (notify_state) { - rc = ble_gattc_notify_custom(myconn_handle, notify_handle, om); + rc = ble_gatts_notify_custom(myconn_handle, notify_handle, om); assert(rc == 0); } if (indicate_state) { - rc = ble_gattc_indicate_custom(myconn_handle, notify_handle, om); + rc = ble_gatts_indicate_custom(myconn_handle, notify_handle, om); assert(rc == 0); } } diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index b06344fc2e..312126f532 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -470,6 +470,12 @@ int ble_gattc_write_reliable(uint16_t conn_handle, * * @return 0 on success; nonzero on failure. */ +int ble_gatts_notify_custom(uint16_t conn_handle, uint16_t att_handle, + struct os_mbuf *om); + +/** + * Deprecated. Should not be used. Use ble_gatts_notify_custom instead. + */ int ble_gattc_notify_custom(uint16_t conn_handle, uint16_t att_handle, struct os_mbuf *om); @@ -485,6 +491,11 @@ int ble_gattc_notify_custom(uint16_t conn_handle, uint16_t att_handle, * * @return 0 on success; nonzero on failure. */ +int ble_gatts_notify(uint16_t conn_handle, uint16_t chr_val_handle); + +/** + * Deprecated. Should not be used. Use ble_gatts_notify instead. + */ int ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle); /** @@ -501,6 +512,11 @@ int ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle); * * @return 0 on success; nonzero on failure. */ +int ble_gatts_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, + struct os_mbuf *txom); +/** + * Deprecated. Should not be used. Use ble_gatts_indicate_custom instead. + */ int ble_gattc_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, struct os_mbuf *txom); @@ -516,6 +532,11 @@ int ble_gattc_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, * * @return 0 on success; nonzero on failure. */ +int ble_gatts_indicate(uint16_t conn_handle, uint16_t chr_val_handle); + +/** + * Deprecated. Should not be used. Use ble_gatts_indicate instead. + */ int ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle); int ble_gattc_init(void); diff --git a/nimble/host/mesh/src/pb_gatt_srv.c b/nimble/host/mesh/src/pb_gatt_srv.c index ee37819d5c..fb629f7185 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.c +++ b/nimble/host/mesh/src/pb_gatt_srv.c @@ -409,7 +409,7 @@ static int gatt_send(uint16_t conn_handle, BT_DBG("%u bytes: %s", len, bt_hex(data, len)); om = ble_hs_mbuf_from_flat(data, len); assert(om); - err = ble_gattc_notify_custom(conn_handle, svc_handles.prov_data_out_h, om); + err = ble_gatts_notify_custom(conn_handle, svc_handles.prov_data_out_h, om); notify_complete(); if (!err) { diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index dcbabfa296..72ed3b55f7 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -875,7 +875,7 @@ static int proxy_send(uint16_t conn_handle, om = ble_hs_mbuf_from_flat(data, len); assert(om); - err = ble_gattc_notify_custom(conn_handle, svc_handles.proxy_data_out_h, om); + err = ble_gatts_notify_custom(conn_handle, svc_handles.proxy_data_out_h, om); notify_complete(); if (!err) { diff --git a/nimble/host/services/ans/src/ble_svc_ans.c b/nimble/host/services/ans/src/ble_svc_ans.c index 5b64f18c44..df1e0764ad 100644 --- a/nimble/host/services/ans/src/ble_svc_ans.c +++ b/nimble/host/services/ans/src/ble_svc_ans.c @@ -390,7 +390,7 @@ ble_svc_ans_new_alert_notify(uint8_t cat_id, const char * info_str) memcpy(&ble_svc_ans_new_alert_val[2], info_str, info_str_len); } } - return ble_gattc_notify(ble_svc_ans_conn_handle, + return ble_gatts_notify(ble_svc_ans_conn_handle, ble_svc_ans_new_alert_val_handle); } @@ -407,7 +407,7 @@ ble_svc_ans_unr_alert_notify(uint8_t cat_id) { ble_svc_ans_unr_alert_stat[0] = cat_id; ble_svc_ans_unr_alert_stat[1] = ble_svc_ans_unr_alert_cnt[cat_id]; - return ble_gattc_notify(ble_svc_ans_conn_handle, + return ble_gatts_notify(ble_svc_ans_conn_handle, ble_svc_ans_unr_alert_val_handle); } diff --git a/nimble/host/services/bleuart/src/bleuart.c b/nimble/host/services/bleuart/src/bleuart.c index 1585635286..5703224509 100644 --- a/nimble/host/services/bleuart/src/bleuart.c +++ b/nimble/host/services/bleuart/src/bleuart.c @@ -165,7 +165,7 @@ bleuart_uart_read(void) if (!om) { return; } - ble_gattc_notify_custom(g_console_conn_handle, + ble_gatts_notify_custom(g_console_conn_handle, g_bleuart_attr_read_handle, om); off = 0; break; diff --git a/nimble/host/src/ble_att_clt.c b/nimble/host/src/ble_att_clt.c index 1a76297518..a36cf3aa0a 100644 --- a/nimble/host/src/ble_att_clt.c +++ b/nimble/host/src/ble_att_clt.c @@ -952,7 +952,7 @@ ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom) #endif /* No payload. */ - ble_gattc_rx_indicate_rsp(conn_handle); + ble_gatts_rx_indicate_rsp(conn_handle); return 0; } diff --git a/nimble/host/src/ble_gatt_priv.h b/nimble/host/src/ble_gatt_priv.h index 4a59635b82..2b1705a10f 100644 --- a/nimble/host/src/ble_gatt_priv.h +++ b/nimble/host/src/ble_gatt_priv.h @@ -125,7 +125,7 @@ void ble_gattc_rx_prep_write_rsp(uint16_t conn_handle, int status, uint16_t handle, uint16_t offset, struct os_mbuf **rxom); void ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, int status); -void ble_gattc_rx_indicate_rsp(uint16_t conn_handle); +void ble_gatts_rx_indicate_rsp(uint16_t conn_handle); void ble_gattc_rx_find_info_idata(uint16_t conn_handle, struct ble_att_find_info_idata *idata); void ble_gattc_rx_find_info_complete(uint16_t conn_handle, int status); diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index b0535fb816..e4bd0a42ee 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -233,7 +233,7 @@ static ble_gattc_err_fn ble_gattc_read_mult_err; static ble_gattc_err_fn ble_gattc_write_err; static ble_gattc_err_fn ble_gattc_write_long_err; static ble_gattc_err_fn ble_gattc_write_reliable_err; -static ble_gattc_err_fn ble_gattc_indicate_err; +static ble_gattc_err_fn ble_gatts_indicate_err; static ble_gattc_err_fn * const ble_gattc_err_dispatch[BLE_GATT_OP_CNT] = { [BLE_GATT_OP_MTU] = ble_gattc_mtu_err, @@ -250,7 +250,7 @@ static ble_gattc_err_fn * const ble_gattc_err_dispatch[BLE_GATT_OP_CNT] = { [BLE_GATT_OP_WRITE] = ble_gattc_write_err, [BLE_GATT_OP_WRITE_LONG] = ble_gattc_write_long_err, [BLE_GATT_OP_WRITE_RELIABLE] = ble_gattc_write_reliable_err, - [BLE_GATT_OP_INDICATE] = ble_gattc_indicate_err, + [BLE_GATT_OP_INDICATE] = ble_gatts_indicate_err, }; /** @@ -308,7 +308,7 @@ static ble_gattc_tmo_fn ble_gattc_read_mult_tmo; static ble_gattc_tmo_fn ble_gattc_write_tmo; static ble_gattc_tmo_fn ble_gattc_write_long_tmo; static ble_gattc_tmo_fn ble_gattc_write_reliable_tmo; -static ble_gattc_tmo_fn ble_gattc_indicate_tmo; +static ble_gattc_tmo_fn ble_gatts_indicate_tmo; static ble_gattc_tmo_fn * const ble_gattc_tmo_dispatch[BLE_GATT_OP_CNT] = { @@ -326,7 +326,7 @@ ble_gattc_tmo_dispatch[BLE_GATT_OP_CNT] = { [BLE_GATT_OP_WRITE] = ble_gattc_write_tmo, [BLE_GATT_OP_WRITE_LONG] = ble_gattc_write_long_tmo, [BLE_GATT_OP_WRITE_RELIABLE] = ble_gattc_write_reliable_tmo, - [BLE_GATT_OP_INDICATE] = ble_gattc_indicate_tmo, + [BLE_GATT_OP_INDICATE] = ble_gatts_indicate_tmo, }; /** @@ -4153,7 +4153,7 @@ ble_gattc_write_reliable(uint16_t conn_handle, *****************************************************************************/ int -ble_gattc_notify_custom(uint16_t conn_handle, uint16_t chr_val_handle, +ble_gatts_notify_custom(uint16_t conn_handle, uint16_t chr_val_handle, struct os_mbuf *txom) { #if !MYNEWT_VAL(BLE_GATT_NOTIFY) @@ -4203,8 +4203,18 @@ ble_gattc_notify_custom(uint16_t conn_handle, uint16_t chr_val_handle, return rc; } +/** + * Deprecated. Should not be used. Use ble_gatts_notify_custom instead. + */ int -ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle) +ble_gattc_notify_custom(uint16_t conn_handle, uint16_t chr_val_handle, + struct os_mbuf *txom) +{ + return ble_gatts_notify_custom(conn_handle, chr_val_handle, txom); +} + +int +ble_gatts_notify(uint16_t conn_handle, uint16_t chr_val_handle) { #if !MYNEWT_VAL(BLE_GATT_NOTIFY) return BLE_HS_ENOTSUP; @@ -4212,11 +4222,20 @@ ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle) int rc; - rc = ble_gattc_notify_custom(conn_handle, chr_val_handle, NULL); + rc = ble_gatts_notify_custom(conn_handle, chr_val_handle, NULL); return rc; } +/** + * Deprecated. Should not be used. Use ble_gatts_notify instead. + */ +int +ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle) +{ + return ble_gatts_notify(conn_handle, chr_val_handle); +} + /***************************************************************************** * $indicate * *****************************************************************************/ @@ -4228,7 +4247,7 @@ ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle) * error status to the application. */ static void -ble_gattc_indicate_err(struct ble_gattc_proc *proc, int status, +ble_gatts_indicate_err(struct ble_gattc_proc *proc, int status, uint16_t att_handle) { int rc; @@ -4252,7 +4271,7 @@ ble_gattc_indicate_err(struct ble_gattc_proc *proc, int status, } static void -ble_gattc_indicate_tmo(struct ble_gattc_proc *proc) +ble_gatts_indicate_tmo(struct ble_gattc_proc *proc) { BLE_HS_DBG_ASSERT(!ble_hs_locked_by_cur_task()); ble_gattc_dbg_assert_proc_not_inserted(proc); @@ -4266,7 +4285,7 @@ ble_gattc_indicate_tmo(struct ble_gattc_proc *proc) * proc. */ static void -ble_gattc_indicate_rx_rsp(struct ble_gattc_proc *proc) +ble_gatts_indicate_rx_rsp(struct ble_gattc_proc *proc) { int rc; @@ -4297,7 +4316,7 @@ ble_gatts_indicate_fail_notconn(uint16_t conn_handle) } int -ble_gattc_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, +ble_gatts_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, struct os_mbuf *txom) { #if !MYNEWT_VAL(BLE_GATT_INDICATE) @@ -4369,10 +4388,29 @@ ble_gattc_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, return rc; } +/** + * Deprecated. Should not be used. Use ble_gatts_indicate_custom instead. + */ +int +ble_gattc_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, + struct os_mbuf *txom) +{ + return ble_gatts_indicate_custom(conn_handle, chr_val_handle, txom); +} + +int +ble_gatts_indicate(uint16_t conn_handle, uint16_t chr_val_handle) +{ + return ble_gatts_indicate_custom(conn_handle, chr_val_handle, NULL); +} + +/** + * Deprecated. Should not be used. Use ble_gatts_indicate instead. + */ int ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle) { - return ble_gattc_indicate_custom(conn_handle, chr_val_handle, NULL); + return ble_gatts_indicate(conn_handle, chr_val_handle); } /***************************************************************************** @@ -4743,7 +4781,7 @@ ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, int status) * active GATT procedure. */ void -ble_gattc_rx_indicate_rsp(uint16_t conn_handle) +ble_gatts_rx_indicate_rsp(uint16_t conn_handle) { #if !NIMBLE_BLE_ATT_CLT_INDICATE return; @@ -4754,7 +4792,7 @@ ble_gattc_rx_indicate_rsp(uint16_t conn_handle) proc = ble_gattc_extract_first_by_conn_op(conn_handle, BLE_GATT_OP_INDICATE); if (proc != NULL) { - ble_gattc_indicate_rx_rsp(proc); + ble_gatts_indicate_rx_rsp(proc); ble_gattc_process_status(proc, BLE_HS_EDONE); } } diff --git a/nimble/host/src/ble_gatts.c b/nimble/host/src/ble_gatts.c index 93809caa41..6732bc1662 100644 --- a/nimble/host/src/ble_gatts.c +++ b/nimble/host/src/ble_gatts.c @@ -1397,7 +1397,7 @@ ble_gatts_send_next_indicate(uint16_t conn_handle) return BLE_HS_ENOENT; } - rc = ble_gattc_indicate(conn_handle, chr_val_handle); + rc = ble_gatts_indicate(conn_handle, chr_val_handle); if (rc != 0) { return rc; } @@ -1635,11 +1635,11 @@ ble_gatts_tx_notifications_one_chr(uint16_t chr_val_handle) break; case BLE_ATT_OP_NOTIFY_REQ: - ble_gattc_notify(conn_handle, chr_val_handle); + ble_gatts_notify(conn_handle, chr_val_handle); break; case BLE_ATT_OP_INDICATE_REQ: - ble_gattc_indicate(conn_handle, chr_val_handle); + ble_gatts_indicate(conn_handle, chr_val_handle); break; default: @@ -1782,7 +1782,7 @@ ble_gatts_bonding_restored(uint16_t conn_handle) break; case BLE_ATT_OP_NOTIFY_REQ: - rc = ble_gattc_notify(conn_handle, cccd_value.chr_val_handle); + rc = ble_gatts_notify(conn_handle, cccd_value.chr_val_handle); if (rc == 0) { cccd_value.value_changed = 0; ble_store_write_cccd(&cccd_value); @@ -1790,7 +1790,7 @@ ble_gatts_bonding_restored(uint16_t conn_handle) break; case BLE_ATT_OP_INDICATE_REQ: - ble_gattc_indicate(conn_handle, cccd_value.chr_val_handle); + ble_gatts_indicate(conn_handle, cccd_value.chr_val_handle); break; default: diff --git a/nimble/host/test/src/ble_gatt_conn_test.c b/nimble/host/test/src/ble_gatt_conn_test.c index 8d95f74337..5cb94ce828 100644 --- a/nimble/host/test/src/ble_gatt_conn_test.c +++ b/nimble/host/test/src/ble_gatt_conn_test.c @@ -485,7 +485,7 @@ TEST_CASE_SELF(ble_gatt_conn_test_disconnect) 3, &attr, 1, ble_gatt_conn_test_write_rel_cb, &write_rel_arg); TEST_ASSERT_FATAL(rc == 0); - rc = ble_gattc_indicate(3, attr_handle); + rc = ble_gatts_indicate(3, attr_handle); TEST_ASSERT_FATAL(rc == 0); /*** Start the procedures. */ @@ -732,7 +732,7 @@ TEST_CASE_SELF(ble_gatt_conn_test_timeout) /*** Indication. */ ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL); - rc = ble_gattc_indicate(1, attr_handle); + rc = ble_gatts_indicate(1, attr_handle); TEST_ASSERT_FATAL(rc == 0); ble_gatt_conn_test_util_timeout(1, NULL); diff --git a/nimble/host/test/src/ble_gatts_notify_test.c b/nimble/host/test/src/ble_gatts_notify_test.c index 6e04ac3626..254ac4407b 100644 --- a/nimble/host/test/src/ble_gatts_notify_test.c +++ b/nimble/host/test/src/ble_gatts_notify_test.c @@ -586,7 +586,7 @@ TEST_CASE_SELF(ble_gatts_notify_test_n) om = ble_hs_mbuf_from_flat(fourbytes, sizeof fourbytes); TEST_ASSERT_FATAL(om != NULL); - rc = ble_gattc_notify_custom(conn_handle, + rc = ble_gatts_notify_custom(conn_handle, ble_gatts_notify_test_chr_1_def_handle + 1, om); TEST_ASSERT_FATAL(rc == 0); @@ -675,7 +675,7 @@ TEST_CASE_SELF(ble_gatts_notify_test_i) om = ble_hs_mbuf_from_flat(fourbytes, sizeof fourbytes); TEST_ASSERT_FATAL(om != NULL); - rc = ble_gattc_indicate_custom(conn_handle, + rc = ble_gatts_indicate_custom(conn_handle, ble_gatts_notify_test_chr_1_def_handle + 1, om); TEST_ASSERT_FATAL(rc == 0); From adc6b036466584b707cb73cf288d148f907d53f8 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 21 Mar 2022 18:18:15 +0100 Subject: [PATCH 0356/1333] nimble/transport/nrf53: Fix slow reads from IPC Reading byte-by-byte from IPC to H4 is terribly slow, we should use new API that can return pointer to an IPC buffer and read directly from there. --- nimble/transport/nrf5340/src/nrf5340_ble_hci.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index 111c048039..fc9fec7c25 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -93,15 +93,14 @@ nrf5340_ble_hci_frame_cb(uint8_t pkt_type, void *data) static void nrf5340_ble_hci_trans_rx(int channel, void *user_data) { - uint8_t byte; - int rlen; - - while (ipc_nrf5340_available(channel) > 0) { - rlen = ipc_nrf5340_read(channel, &byte, 1); - assert(rlen == 1); - - rlen = hci_h4_sm_rx(&hci_nrf5340_h4sm, &byte, 1); - assert(rlen == 1); + uint8_t *buf; + int len; + + len = ipc_nrf5340_available_buf(channel, (void **)&buf); + while (len > 0) { + len = hci_h4_sm_rx(&hci_nrf5340_h4sm, buf, len); + ipc_nrf5340_consume(channel, len); + len = ipc_nrf5340_available_buf(channel, (void **)&buf); } } From 31c2e74807b0ad62ddb372046059bfceec89ad9c Mon Sep 17 00:00:00 2001 From: Tian Zeng Date: Tue, 15 Feb 2022 14:34:08 -0500 Subject: [PATCH 0357/1333] Apollo 3 nimBLE support --- nimble/transport/apollo3/pkg.yml | 46 +++ .../transport/apollo3/src/apollo3_ble_hci.c | 351 ++++++++++++++++++ nimble/transport/apollo3/syscfg.yml | 37 ++ nimble/transport/pkg.yml | 2 + nimble/transport/syscfg.yml | 1 + 5 files changed, 437 insertions(+) create mode 100644 nimble/transport/apollo3/pkg.yml create mode 100644 nimble/transport/apollo3/src/apollo3_ble_hci.c create mode 100644 nimble/transport/apollo3/syscfg.yml diff --git a/nimble/transport/apollo3/pkg.yml b/nimble/transport/apollo3/pkg.yml new file mode 100644 index 0000000000..6706344380 --- /dev/null +++ b/nimble/transport/apollo3/pkg.yml @@ -0,0 +1,46 @@ +# +# 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: nimble/transport/apollo3 +pkg.description: > + HCI transport for Ambiq Apollo3 + The BLE subsystem implemented on Apollo3 is a fully integrated system which is accessed + via the BLE interface block, and provides autonomous clock and power management. + The subsystem has a 32-bit core which runs from a 32 MHz oscillator, and is dedicated + to running the lower portion of the BLE stack with a standard Host Controller interface (HCI). + This core does not support user programming, as all user code runs on the main Cortex M4 processor. + Software leverages the fully HCI compliant interface for Bluetooth operation. + A series of proprietary HCI commands are also leveraged to provide additional performance and low power operation. + The BLE controller and host can be configured to support up to seven simultaneous connections on chip revision A1 (4 on chip revision B0). + Secure connections and extended packet length are also supported. + See the Apollo3 Datasheet for a full description of the BLE subsystem. +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - ble + - bluetooth + - apollo3 + +pkg.deps: + - nimble + - nimble/transport/common/hci_h4 + - "@apache-mynewt-core/kernel/os" + +pkg.apis: + - ble_transport diff --git a/nimble/transport/apollo3/src/apollo3_ble_hci.c b/nimble/transport/apollo3/src/apollo3_ble_hci.c new file mode 100644 index 0000000000..34b6266ddb --- /dev/null +++ b/nimble/transport/apollo3/src/apollo3_ble_hci.c @@ -0,0 +1,351 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include "am_mcu_apollo.h" + +#define HCI_CMD_HDR_LEN (3) /*!< \brief Command packet header length */ + +/* Tx power level in dBm. */ +typedef enum { + TX_POWER_LEVEL_MINUS_10P0_dBm = 0x4, + TX_POWER_LEVEL_MINUS_5P0_dBm = 0x5, + TX_POWER_LEVEL_0P0_dBm = 0x8, + TX_POWER_LEVEL_PLUS_3P0_dBm = 0xF, + TX_POWER_LEVEL_INVALID = 0x10, +} txPowerLevel_t; + +/* Structure for holding outgoing HCI packets. */ +typedef struct { + uint32_t len; + uint32_t data[MYNEWT_VAL(BLE_TRANSPORT_APOLLO3_MAX_TX_PACKET) / sizeof(uint32_t)]; +} hci_drv_write_t; + +uint32_t g_read_buf[MYNEWT_VAL(BLE_TRANSPORT_APOLLO3_MAX_RX_PACKET) / sizeof(uint32_t)]; + +/* BLE module handle for Ambiq HAL functions */ +void *ble_handle; + +uint8_t g_ble_mac_address[6] = {0}; + +static struct hci_h4_sm hci_apollo3_h4sm; + +static void +apollo3_ble_hci_trans_rx_process(void) +{ + uint32_t len; + int rlen; + uint8_t *buf = (uint8_t *)g_read_buf; + + am_hal_ble_blocking_hci_read(ble_handle, (uint32_t *)buf, &len); + + /* NOTE: Ambiq Apollo3 controller does not have local supported lmp features implemented + * The command will always return 0 so we overwrite the buffer here + */ + if(buf[4] == 0x03 && buf[5] == 0x10 && len == 15) { + memset(&buf[11], 0x60, sizeof(uint8_t)); + } + + rlen = hci_h4_sm_rx(&hci_apollo3_h4sm, buf, len); + assert(rlen >= 0); +} + +/* Interrupt handler that looks for BLECIRQ. This gets set by BLE core when there is something to read */ +static void +apollo3_hci_int(void) +{ + uint32_t int_status; + + /* Read and clear the interrupt status. */ + int_status = am_hal_ble_int_status(ble_handle, true); + am_hal_ble_int_clear(ble_handle, int_status); + + /* Handle any DMA or Command Complete interrupts. */ + am_hal_ble_int_service(ble_handle, int_status); + + /* If this was a BLEIRQ interrupt, attempt to start a read operation. */ + if (int_status & AM_HAL_BLE_INT_BLECIRQ) + { + /* Lower WAKE */ + am_hal_ble_wakeup_set(ble_handle, 0); + + /* Call read function to pull in data from controller */ + apollo3_ble_hci_trans_rx_process(); + } + else { + assert(0); + } +} + +/* Boot the radio. */ +uint32_t +apollo3_hci_radio_boot(bool is_cold_boot) +{ + uint32_t xtal_retry_cnt = 0; + uint32_t am_boot_status; + am_hal_mcuctrl_device_t device_info; + am_hal_ble_config_t ble_config = + { + /* Configure the HCI interface clock for 6 MHz */ + .ui32SpiClkCfg = AM_HAL_BLE_HCI_CLK_DIV8, + + /* Set HCI read and write thresholds to 32 bytes each. */ + .ui32ReadThreshold = 32, + .ui32WriteThreshold = 32, + + /* The MCU will supply the clock to the BLE core. */ + .ui32BleClockConfig = AM_HAL_BLE_CORE_MCU_CLK, + + /* Note: These settings only apply to Apollo3 A1/A2 silicon, not B0 silicon. + * Default settings for expected BLE clock drift (measured in PPM). + */ + .ui32ClockDrift = 0, + .ui32SleepClockDrift = 50, + + /* Default setting - AGC Enabled */ + .bAgcEnabled = true, + + /* Default setting - Sleep Algo enabled */ + .bSleepEnabled = true, + + /* Apply the default patches when am_hal_ble_boot() is called. */ + .bUseDefaultPatches = true, + }; + + /* Configure and enable the BLE interface. */ + am_boot_status = AM_HAL_STATUS_FAIL; + while (am_boot_status != AM_HAL_STATUS_SUCCESS) { + am_hal_pwrctrl_low_power_init(); + am_hal_ble_initialize(0, &ble_handle); + am_hal_ble_power_control(ble_handle, AM_HAL_BLE_POWER_ACTIVE); + + am_hal_ble_config(ble_handle, &ble_config); + + /* + * Delay 1s for 32768Hz clock stability. This isn't required unless this is + * our first run immediately after a power-up. + */ + if (is_cold_boot) { + os_time_delay(OS_TICKS_PER_SEC); + } + + /* Attempt to boot the radio. */ + am_boot_status = am_hal_ble_boot(ble_handle); + + /* Check our status, exit if radio is running */ + if (am_boot_status == AM_HAL_STATUS_SUCCESS) { + break; + } + else if (am_boot_status == AM_HAL_BLE_32K_CLOCK_UNSTABLE) { + /* If the radio is running, but the clock looks bad, we can try to restart. */ + am_hal_ble_power_control(ble_handle, AM_HAL_BLE_POWER_OFF); + am_hal_ble_deinitialize(ble_handle); + + /* We won't restart forever. After we hit the maximum number of retries, we'll just return with failure. */ + if (xtal_retry_cnt++ < MYNEWT_VAL(BLE_TRANSPORT_APOLLO3_MAX_XTAL_RETRIES)) { + os_time_delay(OS_TICKS_PER_SEC); + } + else { + return SYS_EUNKNOWN; + } + } + else { + am_hal_ble_power_control(ble_handle, AM_HAL_BLE_POWER_OFF); + am_hal_ble_deinitialize(ble_handle); + /* + * If the radio failed for some reason other than 32K Clock + * instability, we should just report the failure and return. + */ + return SYS_EUNKNOWN; + } + } + + /* Set the BLE TX Output power to 0dBm. */ + am_hal_ble_tx_power_set(ble_handle, TX_POWER_LEVEL_0P0_dBm); + + /* Enable interrupts for the BLE module. */ + am_hal_ble_int_clear(ble_handle, (AM_HAL_BLE_INT_CMDCMP | + AM_HAL_BLE_INT_DCMP | + AM_HAL_BLE_INT_BLECIRQ)); + + am_hal_ble_int_enable(ble_handle, (AM_HAL_BLE_INT_CMDCMP | + AM_HAL_BLE_INT_DCMP | + AM_HAL_BLE_INT_BLECIRQ)); + + /* When it's is_cold_boot, it will use Apollo's Device ID to form Bluetooth address. */ + if (is_cold_boot) { + am_hal_mcuctrl_info_get(AM_HAL_MCUCTRL_INFO_DEVICEID, &device_info); + + /* Bluetooth address formed by ChipID1 (32 bits) and ChipID0 (8-23 bits). */ + memcpy(g_ble_mac_address, &device_info.ui32ChipID1, sizeof(device_info.ui32ChipID1)); + + /* ui32ChipID0 bit 8-31 is test time during chip manufacturing */ + g_ble_mac_address[4] = (device_info.ui32ChipID0 >> 8) & 0xFF; + g_ble_mac_address[5] = (device_info.ui32ChipID0 >> 16) & 0xFF; + } + + NVIC_EnableIRQ(BLE_IRQn); + + return 0; +} + +/* Wake update helper function */ +static void +apollo3_update_wake(void) +{ + AM_CRITICAL_BEGIN; + + /* Set WAKE if there's something in the write queue, but not if SPISTATUS or IRQ is high. */ + if ((BLEIFn(0)->BSTATUS_b.SPISTATUS == 0) && (BLEIF->BSTATUS_b.BLEIRQ == false)) { + am_hal_ble_wakeup_set(ble_handle, 1); + + /* If we've set wakeup, but IRQ came up at the same time, we should just lower WAKE again. */ + if (BLEIF->BSTATUS_b.BLEIRQ == true) { + am_hal_ble_wakeup_set(ble_handle, 0); + } + } + + AM_CRITICAL_END; +} + +/* + * Function used by the BLE stack to send HCI messages to the BLE controller. + * The payload is placed into a queue and the controller is turned on. When it is ready + * an interrupt will fire to handle sending a message + */ +static uint8_t +apollo3_hci_write(uint8_t type, uint16_t len, uint8_t *data) +{ + uint8_t *write_ptr; + hci_drv_write_t write_buf; + + /* comparison compensates for the type byte at index 0. */ + if (len > (MYNEWT_VAL(BLE_TRANSPORT_APOLLO3_MAX_TX_PACKET)-1)) { + return 0; + } + + /* Set all of the fields in the hci write structure. */ + write_buf.len = len + 1; + + write_ptr = (uint8_t *) write_buf.data; + + *write_ptr++ = type; + + for (uint32_t i = 0; i < len; i++) { + write_ptr[i] = data[i]; + } + + /* Wake up the BLE controller. */ + apollo3_update_wake(); + + /* Wait on SPI status before writing */ + while (BLEIFn(0)->BSTATUS_b.SPISTATUS) { + os_time_delay(1); + } + + am_hal_ble_blocking_hci_write(ble_handle, AM_HAL_BLE_RAW, write_buf.data, write_buf.len); + + return 0; +} + +static int +apollo3_ble_hci_acl_tx(struct os_mbuf *om) +{ + struct os_mbuf *x; + int rc = 0; + + x = om; + while (x) { + rc = apollo3_hci_write(HCI_H4_ACL, x->om_len, x->om_data); + if (rc < 0) { + break; + } + x = SLIST_NEXT(x, om_next); + } + + os_mbuf_free_chain(om); + + return (rc < 0) ? BLE_ERR_MEM_CAPACITY : 0; +} + +static int +apollo3_ble_hci_frame_cb(uint8_t pkt_type, void *data) +{ + int rc; + + switch (pkt_type) { + case HCI_H4_ACL: + rc = ble_transport_to_hs_acl(data); + break; + case HCI_H4_EVT: + rc = ble_transport_to_hs_evt(data); + break; + default: + assert(0); + break; + } + + return rc; +} + +static void +apollo3_ble_hci_init(void) +{ + SYSINIT_ASSERT_ACTIVE(); + + /* Enable interrupt to handle read based on BLECIRQ */ + NVIC_SetVector(BLE_IRQn, (uint32_t)apollo3_hci_int); + + /* Initial coldboot configuration */ + apollo3_hci_radio_boot(1); +} + +int +ble_transport_to_ll_cmd_impl(void *buf) +{ + int rc; + uint8_t *cmd = buf; + int len = HCI_CMD_HDR_LEN + cmd[2]; + + rc = apollo3_hci_write(HCI_H4_CMD, len, cmd); + + ble_transport_free(cmd); + + return (rc < 0) ? BLE_ERR_MEM_CAPACITY : 0; +} + +int +ble_transport_to_ll_acl_impl(struct os_mbuf *om) +{ + return apollo3_ble_hci_acl_tx(om); +} + +void +ble_transport_ll_init(void) +{ + hci_h4_sm_init(&hci_apollo3_h4sm, &hci_h4_allocs_from_ll, + apollo3_ble_hci_frame_cb); + apollo3_ble_hci_init(); +} \ No newline at end of file diff --git a/nimble/transport/apollo3/syscfg.yml b/nimble/transport/apollo3/syscfg.yml new file mode 100644 index 0000000000..82e9f545de --- /dev/null +++ b/nimble/transport/apollo3/syscfg.yml @@ -0,0 +1,37 @@ +# 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. +# + +syscfg.defs: + BLE_TRANSPORT_APOLLO3_MAX_TX_PACKET: + description: > + Maximum TX packet size to controller in bytes. + value: 256 + + BLE_TRANSPORT_APOLLO3_MAX_RX_PACKET: + description: > + Maximum RX packet size from controller in bytes. + value: 256 + + BLE_TRANSPORT_APOLLO3_MAX_XTAL_RETRIES: + description: > + Maximum number of retries to boot radio when clock is found to be unstable. + value: 10 + +syscfg.restrictions: + - '!BLE_CONTROLLER' + - '!BLE_HS_FLOW_CTRL' diff --git a/nimble/transport/pkg.yml b/nimble/transport/pkg.yml index 12b9f40acb..5fbcbd21f4 100644 --- a/nimble/transport/pkg.yml +++ b/nimble/transport/pkg.yml @@ -44,6 +44,8 @@ pkg.deps.'BLE_TRANSPORT_HS == "uart"': - nimble/transport/uart pkg.deps.'BLE_TRANSPORT_HS == "usb"': - nimble/transport/usb +pkg.deps.'BLE_TRANSPORT_LL == "apollo3"': + - nimble/transport/apollo3 pkg.deps.BLE_MONITOR_RTT: - "@apache-mynewt-core/hw/drivers/rtt" diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml index 4985250fd0..e69b0ef67c 100644 --- a/nimble/transport/syscfg.yml +++ b/nimble/transport/syscfg.yml @@ -44,6 +44,7 @@ syscfg.defs: - dialog_cmac - nrf5340 - socket + - apollo3 - custom BLE_TRANSPORT_ACL_COUNT: From 8272e8baba107ac9f457f7464164709c6c52743b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 22 Mar 2022 21:56:36 +0100 Subject: [PATCH 0358/1333] porting: Fix dummy build Dummy transport is no longer needed, use socket transport instead. --- porting/examples/dummy/Makefile | 2 + porting/nimble/include/sysinit/sysinit.h | 3 +- porting/npl/dummy/src/hci_dummy.c | 250 ----------------------- 3 files changed, 4 insertions(+), 251 deletions(-) delete mode 100644 porting/npl/dummy/src/hci_dummy.c diff --git a/porting/examples/dummy/Makefile b/porting/examples/dummy/Makefile index 1c38ac4a3c..6e2f061d27 100644 --- a/porting/examples/dummy/Makefile +++ b/porting/examples/dummy/Makefile @@ -46,6 +46,7 @@ include $(NIMBLE_ROOT)/porting/nimble/Makefile.defs SRC = \ $(wildcard $(NIMBLE_ROOT)/porting/npl/dummy/src/*.c) \ $(NIMBLE_SRC) \ + $(wildcard $(NIMBLE_ROOT)/nimble/transport/socket/src/*.c) \ $(TINYCRYPT_SRC) \ main.c \ @@ -53,6 +54,7 @@ SRC = \ INC = \ $(NIMBLE_ROOT)/porting/npl/dummy/include \ $(NIMBLE_INCLUDE) \ + $(NIMBLE_ROOT)/nimble/transport/socket/include \ $(TINYCRYPT_INCLUDE) \ $(INCLUDE) \ diff --git a/porting/nimble/include/sysinit/sysinit.h b/porting/nimble/include/sysinit/sysinit.h index d2a806ab86..3ff5334b01 100644 --- a/porting/nimble/include/sysinit/sysinit.h +++ b/porting/nimble/include/sysinit/sysinit.h @@ -28,7 +28,8 @@ extern "C" { #define SYSINIT_ASSERT_ACTIVE() -#define SYSINIT_PANIC_ASSERT(rc) assert(rc); +#define SYSINIT_PANIC_ASSERT(rc) assert(rc) +#define SYSINIT_PANIC_ASSERT_MSG(rc, msg) assert(rc) #ifdef __cplusplus } diff --git a/porting/npl/dummy/src/hci_dummy.c b/porting/npl/dummy/src/hci_dummy.c deleted file mode 100644 index 78fffe951b..0000000000 --- a/porting/npl/dummy/src/hci_dummy.c +++ /dev/null @@ -1,250 +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. - */ - -#include -#include -#include -#include "syscfg/syscfg.h" -#include "sysinit/sysinit.h" -#include "os/os_mempool.h" -#include "nimble/ble.h" -#include "nimble/ble_hci_trans.h" -#include "nimble/hci_common.h" - -/* HCI packet types */ -#define HCI_PKT_CMD 0x01 -#define HCI_PKT_ACL 0x02 -#define HCI_PKT_EVT 0x04 -#define HCI_PKT_GTL 0x05 - -/* Buffers for HCI commands data */ -static uint8_t trans_buf_cmd[BLE_HCI_TRANS_CMD_SZ]; -static uint8_t trans_buf_cmd_allocd; - -/* Buffers for HCI events data */ -static uint8_t trans_buf_evt_hi_pool_buf[ OS_MEMPOOL_BYTES( - MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) ]; -static struct os_mempool trans_buf_evt_hi_pool; -static uint8_t trans_buf_evt_lo_pool_buf[ OS_MEMPOOL_BYTES( - MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)) ]; -static struct os_mempool trans_buf_evt_lo_pool; - -/* Buffers for HCI ACL data */ -#define ACL_POOL_BLOCK_SIZE OS_ALIGN(MYNEWT_VAL(BLE_ACL_BUF_SIZE) + \ - BLE_MBUF_MEMBLOCK_OVERHEAD + \ - BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT) -static uint8_t trans_buf_acl_pool_buf[ OS_MEMPOOL_BYTES( - MYNEWT_VAL(BLE_ACL_BUF_COUNT), - ACL_POOL_BLOCK_SIZE) ]; -static struct os_mempool trans_buf_acl_pool; -static struct os_mbuf_pool trans_buf_acl_mbuf_pool; - -/* Host interface */ -static ble_hci_trans_rx_cmd_fn *trans_rx_cmd_cb; -static void *trans_rx_cmd_arg; -static ble_hci_trans_rx_acl_fn *trans_rx_acl_cb; -static void *trans_rx_acl_arg; - -/* Called by NimBLE host to reset HCI transport state (i.e. on host reset) */ -int -ble_hci_trans_reset(void) -{ - return 0; -} - -/* Called by NimBLE host to setup callbacks from HCI transport */ -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) -{ - trans_rx_cmd_cb = cmd_cb; - trans_rx_cmd_arg = cmd_arg; - trans_rx_acl_cb = acl_cb; - trans_rx_acl_arg = acl_arg; -} - -/* - * Called by NimBLE host to allocate buffer for HCI Command packet. - * Called by HCI transport to allocate buffer for HCI Event packet. - */ -uint8_t * -ble_hci_trans_buf_alloc(int type) -{ - uint8_t *buf; - - switch (type) { - case BLE_HCI_TRANS_BUF_CMD: - assert(!trans_buf_cmd_allocd); - trans_buf_cmd_allocd = 1; - buf = trans_buf_cmd; - break; - case BLE_HCI_TRANS_BUF_EVT_HI: - buf = os_memblock_get(&trans_buf_evt_hi_pool); - if (buf) { - break; - } - /* no break */ - case BLE_HCI_TRANS_BUF_EVT_LO: - buf = os_memblock_get(&trans_buf_evt_lo_pool); - break; - default: - assert(0); - buf = NULL; - } - - return buf; -} - -/* - * Called by NimBLE host to free buffer allocated for HCI Event packet. - * Called by HCI transport to free buffer allocated for HCI Command packet. - */ -void -ble_hci_trans_buf_free(uint8_t *buf) -{ - int rc; - - if (buf == trans_buf_cmd) { - assert(trans_buf_cmd_allocd); - trans_buf_cmd_allocd = 0; - } else if (os_memblock_from(&trans_buf_evt_hi_pool, buf)) { - rc = os_memblock_put(&trans_buf_evt_hi_pool, buf); - assert(rc == 0); - } else { - assert(os_memblock_from(&trans_buf_evt_lo_pool, buf)); - rc = os_memblock_put(&trans_buf_evt_lo_pool, buf); - assert(rc == 0); - } -} - -/* Called by NimBLE host to send HCI Command packet over HCI transport */ -int -ble_hci_trans_hs_cmd_tx(uint8_t *cmd) -{ - uint8_t *buf = cmd; - - /* - * TODO Send HCI Command packet somewhere. - * Buffer pointed by 'cmd' contains complete HCI Command packet as defined - * by Core spec. - */ - - ble_hci_trans_buf_free(buf); - - return 0; -} - -/* Called by NimBLE host to send HCI ACL Data packet over HCI transport */ -int -ble_hci_trans_hs_acl_tx(struct os_mbuf *om) -{ - uint8_t *buf = om->om_data; - - /* - * TODO Send HCI ACL Data packet somewhere. - * mbuf pointed by 'om' contains complete HCI ACL Data packet as defined - * by Core spec. - */ - (void)buf; - - os_mbuf_free_chain(om); - - return 0; -} - -/* Called by application to send HCI ACL Data packet to host */ -int -hci_transport_send_acl_to_host(uint8_t *buf, uint16_t size) -{ - struct os_mbuf *trans_mbuf; - int rc; - - trans_mbuf = os_mbuf_get_pkthdr(&trans_buf_acl_mbuf_pool, - sizeof(struct ble_mbuf_hdr)); - os_mbuf_append(trans_mbuf, buf, size); - rc = trans_rx_acl_cb(trans_mbuf, trans_rx_acl_arg); - - return rc; -} - -/* Called by application to send HCI Event packet to host */ -int -hci_transport_send_evt_to_host(uint8_t *buf, uint8_t size) -{ - uint8_t *trans_buf; - int rc; - - /* Allocate LE Advertising Report Event from lo pool only */ - if ((buf[0] == BLE_HCI_EVCODE_LE_META) && - (buf[2] == BLE_HCI_LE_SUBEV_ADV_RPT)) { - trans_buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); - if (!trans_buf) { - /* Skip advertising report if we're out of memory */ - return 0; - } - } else { - trans_buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); - } - - memcpy(trans_buf, buf, size); - - rc = trans_rx_cmd_cb(trans_buf, trans_rx_cmd_arg); - if (rc != 0) { - ble_hci_trans_buf_free(trans_buf); - } - - return rc; -} - -/* Called by application to initialize transport structures */ -int -hci_transport_init(void) -{ - int rc; - - trans_buf_cmd_allocd = 0; - - rc = os_mempool_init(&trans_buf_acl_pool, MYNEWT_VAL(BLE_ACL_BUF_COUNT), - ACL_POOL_BLOCK_SIZE, trans_buf_acl_pool_buf, - "dummy_hci_acl_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mbuf_pool_init(&trans_buf_acl_mbuf_pool, &trans_buf_acl_pool, - ACL_POOL_BLOCK_SIZE, - MYNEWT_VAL(BLE_ACL_BUF_COUNT)); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&trans_buf_evt_hi_pool, - MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - trans_buf_evt_hi_pool_buf, - "dummy_hci_hci_evt_hi_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&trans_buf_evt_lo_pool, - MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), - MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), - trans_buf_evt_lo_pool_buf, - "dummy_hci_hci_evt_lo_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - return 0; -} From d6fd95b184fb5778e28c4333f71621d9f368a815 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 23 Mar 2022 14:55:40 +0100 Subject: [PATCH 0359/1333] nimble/ll: Fix missing Read Remote Version Info in supported commands Read Remote Version Information command bit was not set in supported HCI commands bitmask. --- nimble/controller/src/ble_ll_supp_cmd.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_supp_cmd.c b/nimble/controller/src/ble_ll_supp_cmd.c index f6dab06494..6903c8d201 100644 --- a/nimble/controller/src/ble_ll_supp_cmd.c +++ b/nimble/controller/src/ble_ll_supp_cmd.c @@ -34,6 +34,14 @@ #endif #define BLE_LL_SUPP_CMD_OCTET_0 (BLE_SUPP_CMD_DISCONNECT) +/* Octet 2*/ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) +#define BLE_SUPP_CMD_READ_REM_VER_INFO (1 << 7) +#else +#define BLE_SUPP_CMD_READ_REM_VER_INFO (0 << 7) +#endif +#define BLE_LL_SUPP_CMD_OCTET_2 (BLE_SUPP_CMD_READ_REM_VER_INFO) + /* Octet 5 */ #define BLE_SUPP_CMD_SET_EVENT_MASK (1 << 6) #define BLE_SUPP_CMD_RESET (1 << 7) @@ -579,7 +587,7 @@ const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN] = { BLE_LL_SUPP_CMD_OCTET_0, /* Octet 0 */ 0, - 0, + BLE_LL_SUPP_CMD_OCTET_2, /* Octet 2 */ 0, 0, BLE_LL_SUPP_CMD_OCTET_5, From 30ba351a6ed6ab800f4d2dbc9be99795b0be107e Mon Sep 17 00:00:00 2001 From: mkasenberg Date: Fri, 25 Mar 2022 07:08:42 +0100 Subject: [PATCH 0360/1333] docs/btshell: Fix name of show-addr command --- docs/btshell/btshell_api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/btshell/btshell_api.rst b/docs/btshell/btshell_api.rst index 49605bf41c..28a1021c51 100644 --- a/docs/btshell/btshell_api.rst +++ b/docs/btshell/btshell_api.rst @@ -48,11 +48,11 @@ For example: set addr_type=public addr=01:02:03:04:05:06 set addr_type=random addr=c1:aa:bb:cc:dd:ee -The address configuration can be viewed with the ``gatt-show-addr`` command, as follows: +The address configuration can be viewed with the ``show-addr`` command, as follows: :: - gatt-show-addr + show-addr public_id_addr=01:02:03:04:05:06 random_id_addr=c1:aa:bb:cc:dd:ee Initiate a direct connection to a device From 3a4ca9eb7edd25ff3d082bbeb77617d2f08dc856 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 28 Mar 2022 14:04:59 +0200 Subject: [PATCH 0361/1333] nimble/ll: Fix internal flow control for conn We need free credit if: in isr: credit is allocated but ll->hs flow control blocked allocation in task: credit was allocated for mbuf being freed (e.g. we allocate credits only for non-empty PDUs so we should not free a credit if this is an empty PDU) --- nimble/controller/src/ble_ll_conn.c | 16 ++++++++++++---- nimble/include/nimble/ble.h | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 3be8f66fa2..9bbcfd4f44 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3270,7 +3270,9 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) /* Free buffer */ conn_rx_data_pdu_end: #if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) - ble_transport_int_flow_ctl_put(); + if (hdr->rxinfo.flags & BLE_MBUF_HDR_F_CONN_CREDIT_INT) { + ble_transport_int_flow_ctl_put(); + } #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) @@ -3337,9 +3339,12 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) /* Do not alloc PDU if there are no free buffers in transport. We'll nak * this PDU in LL. */ - if (alloc_rxpdu && BLE_LL_LLID_IS_DATA(hdr_byte) && (rx_pyld_len > 0) && - !ble_transport_int_flow_ctl_get()) { - alloc_rxpdu = false; + if (alloc_rxpdu && BLE_LL_LLID_IS_DATA(hdr_byte) && (rx_pyld_len > 0)) { + if (ble_transport_int_flow_ctl_get()) { + rxhdr->rxinfo.flags |= BLE_MBUF_HDR_F_CONN_CREDIT_INT; + } else { + alloc_rxpdu = false; + } } #endif @@ -3355,6 +3360,9 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) if (ble_ll_conn_cth_flow_alloc_credit(connsm)) { rxhdr->rxinfo.flags |= BLE_MBUF_HDR_F_CONN_CREDIT; } else { +#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) + ble_transport_int_flow_ctl_put(); +#endif alloc_rxpdu = false; } } diff --git a/nimble/include/nimble/ble.h b/nimble/include/nimble/ble.h index d349afebb0..bbf2275388 100644 --- a/nimble/include/nimble/ble.h +++ b/nimble/include/nimble/ble.h @@ -93,6 +93,7 @@ struct ble_mbuf_hdr_rxinfo #define BLE_MBUF_HDR_F_CONNECT_RSP_RXD (0x0008) #define BLE_MBUF_HDR_F_CONN_CREDIT (0x8000) #define BLE_MBUF_HDR_F_IGNORED (0x8000) +#define BLE_MBUF_HDR_F_CONN_CREDIT_INT (0x4000) #define BLE_MBUF_HDR_F_SCAN_REQ_TXD (0x4000) #define BLE_MBUF_HDR_F_INITA_RESOLVED (0x2000) #define BLE_MBUF_HDR_F_TARGETA_RESOLVED (0x2000) From 62335b4a69de105e1efb127c43bc8c0ccf23a228 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 31 Mar 2022 20:24:53 +0200 Subject: [PATCH 0362/1333] nimble/transport: Fix typo --- nimble/transport/uart/src/hci_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/transport/uart/src/hci_uart.c b/nimble/transport/uart/src/hci_uart.c index f44b9904cf..42206f58b0 100644 --- a/nimble/transport/uart/src/hci_uart.c +++ b/nimble/transport/uart/src/hci_uart.c @@ -213,7 +213,7 @@ ble_transport_to_hs_acl_impl(struct os_mbuf *om) txe->type = HCI_H4_ACL; txe->sent_type = 0; - txe->len = 2 + OS_MBUF_PKTLEN(om); + txe->len = OS_MBUF_PKTLEN(om); txe->idx = 0; txe->buf = NULL; txe->om = om; From f46b50a9f9d51c7c84dde7ed58a8ab36445d7e8b Mon Sep 17 00:00:00 2001 From: Michal Narajowski Date: Wed, 6 Apr 2022 12:18:10 +0200 Subject: [PATCH 0363/1333] ll: Fix recolv typo --- nimble/controller/src/ble_ll_resolv.c | 8 ++++---- nimble/include/nimble/hci_common.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/nimble/controller/src/ble_ll_resolv.c b/nimble/controller/src/ble_ll_resolv.c index 86f8ea7830..a972fe3de8 100644 --- a/nimble/controller/src/ble_ll_resolv.c +++ b/nimble/controller/src/ble_ll_resolv.c @@ -474,8 +474,8 @@ int ble_ll_resolv_peer_addr_rd(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen) { - const struct ble_hci_le_rd_peer_recolv_addr_cp *cmd = (const void *) cmdbuf; - struct ble_hci_le_rd_peer_recolv_addr_rp *rsp = (void *) rspbuf; + const struct ble_hci_le_rd_peer_resolv_addr_cp *cmd = (const void *) cmdbuf; + struct ble_hci_le_rd_peer_resolv_addr_rp *rsp = (void *) rspbuf; struct ble_ll_resolv_entry *rl; int rc; @@ -500,8 +500,8 @@ int ble_ll_resolv_local_addr_rd(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen) { - const struct ble_hci_le_rd_local_recolv_addr_cp *cmd = (const void *) cmdbuf; - struct ble_hci_le_rd_local_recolv_addr_rp *rsp = (void *) rspbuf; + const struct ble_hci_le_rd_local_resolv_addr_cp *cmd = (const void *) cmdbuf; + struct ble_hci_le_rd_local_resolv_addr_rp *rsp = (void *) rspbuf; struct ble_ll_resolv_entry *rl; int rc; diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index eb5165c0a4..7d1c3ac902 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -483,20 +483,20 @@ struct ble_hci_le_rd_resolv_list_size_rp { } __attribute__((packed)); #define BLE_HCI_OCF_LE_RD_PEER_RESOLV_ADDR (0x002B) -struct ble_hci_le_rd_peer_recolv_addr_cp { +struct ble_hci_le_rd_peer_resolv_addr_cp { uint8_t peer_addr_type; uint8_t peer_id_addr[6]; } __attribute__((packed)); -struct ble_hci_le_rd_peer_recolv_addr_rp { +struct ble_hci_le_rd_peer_resolv_addr_rp { uint8_t rpa[6]; } __attribute__((packed)); #define BLE_HCI_OCF_LE_RD_LOCAL_RESOLV_ADDR (0x002C) -struct ble_hci_le_rd_local_recolv_addr_cp { +struct ble_hci_le_rd_local_resolv_addr_cp { uint8_t peer_addr_type; uint8_t peer_id_addr[6]; } __attribute__((packed)); -struct ble_hci_le_rd_local_recolv_addr_rp { +struct ble_hci_le_rd_local_resolv_addr_rp { uint8_t rpa[6]; } __attribute__((packed)); From a6767eafec8cd207a69fc74e968d4b870ca9ecec Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 6 Apr 2022 16:45:11 +0200 Subject: [PATCH 0364/1333] nimble/ll: Optimize BLE_LL_ASSERT BLE_LL_ASSERT() now calls ble_ll_assert() which decides whether to break or send hci_vs event. This significantly reduces code size since there's no need to include all the branches and calls for each BLE_LL_ASSERT. Also for hci_vs we only need base file name (i.e. without path) so we can strip it - __buildiin_strrchr is evaluated during compilation. This reduces code size for debug build with all features enabled by 5K. --- nimble/controller/include/controller/ble_ll.h | 10 ++++------ nimble/controller/src/ble_ll.c | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 97233e9c3b..14fdcc7d70 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -41,14 +41,12 @@ extern "C" { #ifdef NDEBUG #define BLE_LL_ASSERT(cond) (void(0)) #else +void ble_ll_assert(const char *file, unsigned line) __attribute((noreturn)); +#define BLE_LL_FILE (__builtin_strrchr(__FILE__, '/') ? \ + __builtin_strrchr (__FILE__, '/') + 1 : __FILE__) #define BLE_LL_ASSERT(cond) \ if (!(cond)) { \ - if (hal_debugger_connected()) { \ - assert(0);\ - } else {\ - ble_ll_hci_ev_send_vs_assert(__FILE__, __LINE__); \ - while(1) {}\ - }\ + ble_ll_assert(BLE_LL_FILE, __LINE__); \ } #endif #else diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 84b8a4e1c9..f7ab7751a6 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1764,6 +1764,20 @@ ble_ll_is_addr_empty(const uint8_t *addr) return memcmp(addr, BLE_ADDR_ANY, BLE_DEV_ADDR_LEN) == 0; } +#if MYNEWT_VAL(BLE_LL_HCI_VS_EVENT_ON_ASSERT) +void +ble_ll_assert(const char *file, unsigned line) +{ + if (hal_debugger_connected()) { + __BKPT(0); + } else { + ble_ll_hci_ev_send_vs_assert(file, line); \ + } + + while (1); +} +#endif + /** * Initialize the Link Layer. Should be called only once * From 136bd2248ac360b5b03701c531fa6bb00222882f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 6 Apr 2022 15:16:22 +0200 Subject: [PATCH 0365/1333] nimble/transport/h4: Drop legacy advertising events on overflow --- nimble/transport/common/hci_h4/src/hci_h4.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/nimble/transport/common/hci_h4/src/hci_h4.c b/nimble/transport/common/hci_h4/src/hci_h4.c index ac76ab0319..2e86c1dec1 100644 --- a/nimble/transport/common/hci_h4/src/hci_h4.c +++ b/nimble/transport/common/hci_h4/src/hci_h4.c @@ -139,15 +139,23 @@ hci_h4_sm_w4_header(struct hci_h4_sm *h4sm, struct hci_h4_input_buffer *ib) } } - /* TODO lo/hi pool? */ - assert(h4sm->allocs && h4sm->allocs->evt); - h4sm->buf = h4sm->allocs->evt(0); - if (!h4sm->buf) { - return -1; + + /* We can drop legacy advertising events if there's no free buffer in + * discardable pool. + */ + if (h4sm->hdr[2] == BLE_HCI_LE_SUBEV_ADV_RPT) { + h4sm->buf = h4sm->allocs->evt(1); + } else { + h4sm->buf = h4sm->allocs->evt(0); + if (!h4sm->buf) { + return -1; + } } - memcpy(h4sm->buf, h4sm->hdr, h4sm->len); + if (h4sm->buf) { + memcpy(h4sm->buf, h4sm->hdr, h4sm->len); + } h4sm->exp_len = h4sm->hdr[1] + 2; break; From 2a0379d50774aa266d9cdd793b80a00bf7ad81f9 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 6 Apr 2022 15:17:13 +0200 Subject: [PATCH 0366/1333] nimble/transport/h4: Assert on H4 failure We can't recover from H4 failure so let's just assert for now, it will be easier to spot the issue. --- nimble/transport/common/hci_h4/src/hci_h4.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/transport/common/hci_h4/src/hci_h4.c b/nimble/transport/common/hci_h4/src/hci_h4.c index 2e86c1dec1..cb09134296 100644 --- a/nimble/transport/common/hci_h4/src/hci_h4.c +++ b/nimble/transport/common/hci_h4/src/hci_h4.c @@ -264,6 +264,7 @@ hci_h4_sm_rx(struct hci_h4_sm *h4sm, const uint8_t *buf, uint16_t len) /* no break */ case HCI_H4_SM_W4_HEADER: rc = hci_h4_sm_w4_header(h4sm, &ib); + assert(rc >= 0); if (rc) { break; } @@ -271,6 +272,7 @@ hci_h4_sm_rx(struct hci_h4_sm *h4sm, const uint8_t *buf, uint16_t len) /* no break */ case HCI_H4_SM_W4_PAYLOAD: rc = hci_h4_sm_w4_payload(h4sm, &ib); + assert(rc >= 0); if (rc) { break; } From d2539b118926806386c725d2484d21ff30505699 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 7 Feb 2022 13:11:33 +0100 Subject: [PATCH 0367/1333] nimble/ll: Add helpers to check/add peer features --- .../include/controller/ble_ll_conn.h | 26 +++++++++++++++++++ nimble/controller/src/ble_ll_adv.c | 2 +- nimble/controller/src/ble_ll_conn.c | 6 ++--- nimble/controller/src/ble_ll_conn_hci.c | 4 +-- nimble/controller/src/ble_ll_ctrl.c | 2 +- nimble/controller/src/ble_ll_sync.c | 8 ++---- 6 files changed, 35 insertions(+), 13 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index ec13d00946..aaa72fb1e1 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -389,6 +389,32 @@ struct ble_ll_conn_sm #define CONN_IS_PERIPHERAL(csm) (false) #endif +static inline int +ble_ll_conn_rem_feature_check(struct ble_ll_conn_sm *connsm, uint64_t feature) +{ + uint8_t byte_idx; + + /* 8 lsb are conn features */ + feature >>= 8; + + byte_idx = __builtin_ctzll(feature) / 8; + return connsm->remote_features[byte_idx] & (feature >> (byte_idx * 8)); +} + + +static inline void +ble_ll_conn_rem_feature_add(struct ble_ll_conn_sm *connsm, uint64_t feature) +{ + uint8_t byte_idx; + + /* 8 lsb are conn features */ + feature >>= 8; + + byte_idx = __builtin_ctzll(feature) / 8; + connsm->remote_features[byte_idx] |= (feature >> (byte_idx * 8)); +} + + struct ble_ll_conn_sm *ble_ll_conn_find_by_handle(uint16_t handle); struct ble_ll_conn_sm *ble_ll_conn_find_by_peer_addr(const uint8_t* addr, uint8_t addr_type); diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index b3cf5f9860..1aaeeb4d89 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -4094,7 +4094,7 @@ ble_ll_adv_periodic_set_info_transfer(const uint8_t *cmdbuf, uint8_t len, * * Allow initiate LL procedure only if remote supports it. */ - if (!(connsm->remote_features[2] & (BLE_LL_FEAT_SYNC_TRANS_RECV >> (8 * 3)))) { + if (!ble_ll_conn_rem_feature_check(connsm, BLE_LL_FEAT_SYNC_TRANS_RECV)) { rc = BLE_ERR_UNSUPP_REM_FEATURE; goto done; } diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 9bbcfd4f44..6d13109508 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1763,7 +1763,7 @@ ble_ll_conn_init_phy(struct ble_ll_conn_sm *connsm, int phy) connsm->rem_max_tx_time = BLE_LL_CONN_SUPP_TIME_MIN_CODED; connsm->rem_max_rx_time = BLE_LL_CONN_SUPP_TIME_MIN_CODED; /* Assume peer does support coded */ - connsm->remote_features[0] |= (BLE_LL_FEAT_LE_CODED_PHY >> 8); + ble_ll_conn_rem_feature_add(connsm, BLE_LL_FEAT_LE_CODED_PHY); } else { connsm->max_tx_time = conngp->conn_init_max_tx_time_uncoded; connsm->max_rx_time = BLE_LL_CONN_SUPP_TIME_MAX_UNCODED; @@ -2389,8 +2389,8 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) */ if (((connsm->phy_data.cur_tx_phy == BLE_PHY_CODED) || (connsm->phy_data.cur_rx_phy == BLE_PHY_CODED)) && - !(connsm->remote_features[0] & (BLE_LL_FEAT_LE_CODED_PHY >> 8))) { - connsm->remote_features[0] |= (BLE_LL_FEAT_LE_CODED_PHY >> 8); + !ble_ll_conn_rem_feature_check(connsm, BLE_LL_FEAT_LE_CODED_PHY)) { + ble_ll_conn_rem_feature_add(connsm, BLE_LL_FEAT_LE_CODED_PHY); connsm->max_rx_time = BLE_LL_CONN_SUPP_TIME_MAX_CODED; ble_ll_ctrl_initiate_dle(connsm); } diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 82abdcb1ba..08ee42057d 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1476,7 +1476,7 @@ ble_ll_conn_hci_set_data_len(const uint8_t *cmdbuf, uint8_t len, connsm->host_req_max_tx_time = txtime; /* If peer does not support coded, we cannot use value larger than 2120us */ - if (!(connsm->remote_features[0] & (BLE_LL_FEAT_LE_CODED_PHY >> 8))) { + if (!ble_ll_conn_rem_feature_check(connsm, BLE_LL_FEAT_LE_CODED_PHY)) { txtime = min(txtime, BLE_LL_CONN_SUPP_TIME_MAX_UNCODED); } #endif @@ -1677,7 +1677,7 @@ ble_ll_conn_req_peer_sca(const uint8_t *cmdbuf, uint8_t len, return BLE_ERR_UNK_CONN_ID; } - if (!(connsm->remote_features[2] & (BLE_LL_FEAT_SCA_UPDATE >> 24))) { + if (!ble_ll_conn_rem_feature_check(connsm, BLE_LL_FEAT_SCA_UPDATE)) { return BLE_ERR_UNSUPP_REM_FEATURE; } diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index c30f4e3eb3..04b935432d 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1970,7 +1970,7 @@ ble_ll_ctrl_update_features(struct ble_ll_conn_sm *connsm, uint8_t *feat) * LE Coded PHY. However, once we know that peer does support it we can * update those values to ones applicable for coded PHY. */ - if (connsm->remote_features[0] & (BLE_LL_FEAT_LE_CODED_PHY >> 8)) { + if (ble_ll_conn_rem_feature_check(connsm, BLE_LL_FEAT_LE_CODED_PHY)) { if (connsm->host_req_max_tx_time) { connsm->max_tx_time = max(connsm->max_tx_time, connsm->host_req_max_tx_time); diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 0adc67b799..72da2d970d 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -2183,12 +2183,8 @@ ble_ll_sync_transfer(const uint8_t *cmdbuf, uint8_t len, goto done; } - /* TODO should not need to shift - * byte 3 (0 byte is conn_feature) , bit 1 - * - * Allow initiate LL procedure only if remote supports it. - */ - if (!(connsm->remote_features[2] & (BLE_LL_FEAT_SYNC_TRANS_RECV >> (8 * 3)))) { + /* Allow initiate LL procedure only if remote supports it. */ + if (!ble_ll_conn_rem_feature_check(connsm, BLE_LL_FEAT_SYNC_TRANS_RECV)) { rc = BLE_ERR_UNSUPP_REM_FEATURE; goto done; } From d95165ce75d566b0b6f52fe762d0df139fc3ed59 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 8 Feb 2022 14:06:12 +0100 Subject: [PATCH 0368/1333] nimble/ll: Add calculations for subrated conn events This adds basic calculations to support subrated connection events. If feature is disabled, we always use subrate_factor=1 and most of the additional code is compiled out. --- .../include/controller/ble_ll_conn.h | 9 +- nimble/controller/src/ble_ll_conn.c | 95 +++++++++++++++---- nimble/controller/syscfg.yml | 9 ++ 3 files changed, 91 insertions(+), 22 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index aaa72fb1e1..85f59bcf8f 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -269,7 +269,6 @@ struct ble_ll_conn_sm /* Connection timing */ uint16_t conn_itvl; - uint16_t periph_latency; uint16_t supervision_tmo; uint16_t min_ce_len; uint16_t max_ce_len; @@ -283,6 +282,14 @@ struct ble_ll_conn_sm uint32_t periph_cur_window_widening; uint32_t last_rxd_pdu_cputime; /* Used exclusively for supervision timer */ + uint16_t periph_latency; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + uint16_t subrate_base_event; + uint16_t subrate_factor; + uint16_t cont_num; + uint16_t last_pdu_event; +#endif + /* * Used to mark that identity address was used as InitA */ diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 6d13109508..b328296d76 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1853,6 +1853,13 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) connsm->conn_rssi = BLE_LL_CONN_UNKNOWN_RSSI; connsm->inita_identity_used = 0; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + connsm->subrate_base_event = 0; + connsm->subrate_factor = 1; + connsm->cont_num = 0; + connsm->last_pdu_event = 0; +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) connsm->sync_transfer_sync_timeout = g_ble_ll_conn_sync_transfer_params.sync_timeout_us; connsm->sync_transfer_mode = g_ble_ll_conn_sync_transfer_params.mode; @@ -2191,8 +2198,8 @@ ble_ll_conn_move_anchor(struct ble_ll_conn_sm *connsm, uint16_t offset) static int ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) { - uint16_t latency; - uint32_t itvl; + uint32_t conn_itvl_us; + uint32_t ce_duration; #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) uint32_t cur_ww; uint32_t max_ww; @@ -2200,6 +2207,12 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) struct ble_ll_conn_upd_req *upd; uint8_t skip_anchor_calc = 0; uint32_t usecs; + uint8_t use_periph_latency; + uint16_t base_event_cntr; + uint16_t next_event_cntr; + uint8_t next_is_subrated; + uint16_t subrate_factor; + uint16_t event_cntr_diff; /* XXX: deal with connection request procedure here as well */ ble_ll_conn_chk_csm_flags(connsm); @@ -2217,6 +2230,22 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) connsm->periph_latency = 0; } + next_is_subrated = 1; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + base_event_cntr = connsm->subrate_base_event; + subrate_factor = connsm->subrate_factor; + + if ((connsm->cont_num > 0) && + (connsm->event_cntr + 1 == connsm->subrate_base_event + + connsm->subrate_factor) && + (connsm->event_cntr - connsm->last_pdu_event < connsm->cont_num)) { + next_is_subrated = 0; + } +#else + base_event_cntr = connsm->event_cntr; + subrate_factor = 1; +#endif + /* * XXX: TODO Probably want to add checks to see if we need to start * a control procedure here as an instant may have prevented us from @@ -2230,22 +2259,39 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) * the instant */ /* Set event counter to the next connection event that we will tx/rx in */ - itvl = connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS; - latency = 1; - if (connsm->csmflags.cfbit.allow_periph_latency && - !connsm->csmflags.cfbit.conn_update_sched && - !CONN_F_PHY_UPDATE_SCHED(connsm) && - !connsm->csmflags.cfbit.chanmap_update_scheduled) { - if (connsm->csmflags.cfbit.pkt_rxd) { - latency += connsm->periph_latency; - itvl = itvl * latency; + + use_periph_latency = next_is_subrated && + connsm->csmflags.cfbit.allow_periph_latency && + !connsm->csmflags.cfbit.conn_update_sched && + !connsm->csmflags.cfbit.phy_update_sched && + !connsm->csmflags.cfbit.chanmap_update_scheduled && + connsm->csmflags.cfbit.pkt_rxd; + + if (next_is_subrated) { + next_event_cntr = base_event_cntr + subrate_factor; + if (use_periph_latency) { + next_event_cntr += subrate_factor * connsm->periph_latency; } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + /* Make this our next base event. This is technically incorrect, because + * subrate base event is determined by LL_SUBRATE_IND and shall only be + * changed if counter wrapped, but that does not really matter as once + * set it's only used internally. + */ + connsm->subrate_base_event = next_event_cntr; +#endif + } else { + next_event_cntr = connsm->event_cntr + 1; } - connsm->event_cntr += latency; + + event_cntr_diff = next_event_cntr - connsm->event_cntr; + BLE_LL_ASSERT(event_cntr_diff > 0); + + connsm->event_cntr = next_event_cntr; #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { - connsm->css_period_idx += latency; + connsm->css_period_idx += event_cntr_diff; /* If this is non-reference connection, we set anchor from reference * instead of calculating manually. @@ -2261,13 +2307,15 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) /* Calculate next anchor point for connection. * We can use pre-calculated values for one interval if latency is 1. */ - if (latency == 1) { + if (event_cntr_diff == 1) { connsm->anchor_point += connsm->conn_itvl_ticks; ble_ll_tmr_add_u(&connsm->anchor_point, &connsm->anchor_point_usecs, connsm->conn_itvl_usecs); } else { + conn_itvl_us = connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS; + ble_ll_tmr_add(&connsm->anchor_point, &connsm->anchor_point_usecs, - itvl); + conn_itvl_us * event_cntr_diff); } } @@ -2399,7 +2447,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) #endif /* Calculate data channel index of next connection event */ - connsm->data_chan_index = ble_ll_conn_calc_dci(connsm, latency); + connsm->data_chan_index = ble_ll_conn_calc_dci(connsm, event_cntr_diff); /* * If we are trying to terminate connection, check if next wake time is @@ -2416,8 +2464,8 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) * Calculate ce end time. For a peripgheral, we need to add window widening * and the transmit window if we still have one. */ - itvl = ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * - BLE_LL_SCHED_USECS_PER_SLOT); + ce_duration = ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * + BLE_LL_SCHED_USECS_PER_SLOT); #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { @@ -2431,11 +2479,12 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) } cur_ww += BLE_LL_JITTER_USECS; connsm->periph_cur_window_widening = cur_ww; - itvl += ble_ll_tmr_u2t(cur_ww + connsm->periph_cur_tx_win_usecs); + ce_duration += ble_ll_tmr_u2t(cur_ww + + connsm->periph_cur_tx_win_usecs); } #endif - itvl -= g_ble_ll_sched_offset_ticks; - connsm->ce_end_time = connsm->anchor_point + itvl; + ce_duration -= g_ble_ll_sched_offset_ticks; + connsm->ce_end_time = connsm->anchor_point + ce_duration; return 0; } @@ -3162,6 +3211,10 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) acl_len = rxbuf[1]; llid = hdr_byte & BLE_LL_DATA_HDR_LLID_MASK; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + connsm->last_pdu_event = connsm->event_cntr; +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) if (BLE_MBUF_HDR_MIC_FAILURE(hdr)) { diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index ebf7e1dde6..1cd433553e 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -327,6 +327,15 @@ syscfg.defs: restrictions: - '(BLE_VERSION >= 52) if 1' + BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE: + description: > + Enables support LE Enhanced Connection Update. + This allows to use Conenction Subrate Update and Connection Subrate + Request procedures to modify subrate paramters for a connection. + value: 0 + restrictions: + - '(BLE_VERSION >= 53) if 1' + BLE_LL_CFG_FEAT_LL_ISO: description: > This option is used to enable/disable support for LE Isochronous Channels From 7a79799238e9d9c9d2cc57130f08276b5642e3d1 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 8 Feb 2022 16:01:55 +0100 Subject: [PATCH 0369/1333] nimble/ll: Add Connection Subrate Request/Update procedures --- .../include/controller/ble_ll_conn.h | 36 ++++ .../include/controller/ble_ll_ctrl.h | 5 +- .../include/controller/ble_ll_utils.h | 4 + nimble/controller/src/ble_ll.c | 4 + nimble/controller/src/ble_ll_conn.c | 166 +++++++++++++++- nimble/controller/src/ble_ll_conn_priv.h | 7 + nimble/controller/src/ble_ll_ctrl.c | 179 ++++++++++++++++++ 7 files changed, 395 insertions(+), 6 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 85f59bcf8f..a50e6e6948 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -132,6 +132,8 @@ union ble_ll_conn_sm_flags { uint32_t rxd_features:1; uint32_t pending_hci_rd_features:1; uint32_t pending_initiate_dle:1; + uint32_t subrate_trans:1; + uint32_t subrate_ind_txd:1; } cfbit; uint32_t conn_flags; } __attribute__((packed)); @@ -183,6 +185,22 @@ struct hci_conn_update uint16_t max_ce_len; }; +struct ble_ll_conn_subrate_params { + uint16_t subrate_factor; + uint16_t subrate_base_event; + uint16_t periph_latency; + uint16_t cont_num; + uint16_t supervision_tmo; +}; + +struct ble_ll_conn_subrate_req_params { + uint16_t subrate_min; + uint16_t subrate_max; + uint16_t max_latency; + uint16_t cont_num; + uint16_t supervision_tmo; +}; + /* Connection state machine */ struct ble_ll_conn_sm { @@ -284,10 +302,21 @@ struct ble_ll_conn_sm uint16_t periph_latency; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + uint16_t acc_subrate_min; + uint16_t acc_subrate_max; + uint16_t acc_max_latency; + uint16_t acc_cont_num; + uint16_t acc_supervision_tmo; + uint16_t subrate_base_event; uint16_t subrate_factor; uint16_t cont_num; uint16_t last_pdu_event; + + union { + struct ble_ll_conn_subrate_params subrate_trans; + struct ble_ll_conn_subrate_req_params subrate_req; + }; #endif /* @@ -464,6 +493,13 @@ void ble_ll_conn_created_on_aux(struct os_mbuf *rxpdu, uint8_t *targeta); #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) +int ble_ll_conn_subrate_req_llcp(struct ble_ll_conn_sm *connsm, + struct ble_ll_conn_subrate_req_params *srp); +void ble_ll_conn_subrate_set(struct ble_ll_conn_sm *connsm, + struct ble_ll_conn_subrate_params *sp); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index 423d13af3a..17300dc2ae 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -41,7 +41,9 @@ extern "C" { #define BLE_LL_CTRL_PROC_PHY_UPDATE (9) #define BLE_LL_CTRL_PROC_SCA_UPDATE (10) #define BLE_LL_CTRL_PROC_CIS_CREATE (11) -#define BLE_LL_CTRL_PROC_NUM (12) +#define BLE_LL_CTRL_PROC_SUBRATE_REQ (12) +#define BLE_LL_CTRL_PROC_SUBRATE_UPDATE (13) +#define BLE_LL_CTRL_PROC_NUM (14) #define BLE_LL_CTRL_PROC_IDLE (255) /* Checks if a particular control procedure is running */ @@ -307,6 +309,7 @@ int ble_ll_ctrl_reject_ind_send(struct ble_ll_conn_sm *connsm, int ble_ll_ctrl_start_enc_send(struct ble_ll_conn_sm *connsm); int ble_ll_ctrl_enc_allowed_pdu_rx(struct os_mbuf *rxpdu); int ble_ll_ctrl_enc_allowed_pdu_tx(struct os_mbuf_pkthdr *pkthdr); +int ble_ll_ctrl_tx_start(struct ble_ll_conn_sm *connsm, struct os_mbuf *txpdu); int ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm); int ble_ll_ctrl_is_start_enc_rsp(struct os_mbuf *txpdu); diff --git a/nimble/controller/include/controller/ble_ll_utils.h b/nimble/controller/include/controller/ble_ll_utils.h index ae8abfb36e..16b91a0cb8 100644 --- a/nimble/controller/include/controller/ble_ll_utils.h +++ b/nimble/controller/include/controller/ble_ll_utils.h @@ -19,6 +19,10 @@ #include +#define INT16_GT(_a, _b) ((int16_t)((_a) - (_b)) > 0) +#define INT16_LT(_a, _b) ((int16_t)((_a) - (_b)) < 0) +#define INT16_LTE(_a, _b) ((int16_t)((_a) - (_b)) <= 0) + uint32_t ble_ll_utils_calc_access_addr(void); uint8_t ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap); uint8_t ble_ll_utils_dci_csa2(uint16_t counter, uint16_t chan_id, diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index f7ab7751a6..b9d9d7b149 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1943,6 +1943,10 @@ ble_ll_init(void) features |= BLE_LL_FEAT_ISO_HOST_SUPPORT; #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + features |= BLE_LL_FEAT_CONN_SUBRATING; +#endif + lldata->ll_supp_features = features; /* Initialize random number generation */ diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index b328296d76..4c60c4613a 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "syscfg/syscfg.h" #include "os/os.h" #include "nimble/ble.h" @@ -948,6 +949,17 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm) } } #endif + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + if (connsm->csmflags.cfbit.subrate_ind_txd) { + ble_ll_conn_subrate_set(connsm, &connsm->subrate_trans); + connsm->subrate_trans.subrate_factor = 0; + ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_SUBRATE_UPDATE); + connsm->csmflags.cfbit.subrate_ind_txd = 0; + } +#endif /* BLE_LL_CTRL_SUBRATE_IND */ +#endif /* BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE */ } /** @@ -1109,6 +1121,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) pktlen = pkthdr->omp_len; if (llid == BLE_LL_LLID_CTRL) { cur_txlen = pktlen; + ble_ll_ctrl_tx_start(connsm, m); } else { cur_txlen = ble_ll_conn_adjust_pyld_len(connsm, pktlen); } @@ -1689,6 +1702,14 @@ ble_ll_conn_central_common_init(struct ble_ll_conn_sm *connsm) memcpy(connsm->chanmap, g_ble_ll_conn_params.central_chan_map, BLE_LL_CONN_CHMAP_LEN); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + connsm->acc_subrate_min = g_ble_ll_conn_params.acc_subrate_min; + connsm->acc_subrate_max = g_ble_ll_conn_params.acc_subrate_max; + connsm->acc_max_latency = g_ble_ll_conn_params.acc_max_latency; + connsm->acc_cont_num = g_ble_ll_conn_params.acc_cont_num; + connsm->acc_supervision_tmo = g_ble_ll_conn_params.acc_supervision_tmo; +#endif + /* Calculate random access address and crc initialization value */ connsm->access_addr = ble_ll_utils_calc_access_addr(); connsm->crcinit = ble_ll_rand() & 0xffffff; @@ -2213,6 +2234,12 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) uint8_t next_is_subrated; uint16_t subrate_factor; uint16_t event_cntr_diff; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + struct ble_ll_conn_subrate_params *cstp; + uint16_t trans_next_event_cntr; + uint16_t subrate_conn_upd_event_cntr; +#endif + /* XXX: deal with connection request procedure here as well */ ble_ll_conn_chk_csm_flags(connsm); @@ -2272,18 +2299,63 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) if (use_periph_latency) { next_event_cntr += subrate_factor * connsm->periph_latency; } + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) - /* Make this our next base event. This is technically incorrect, because - * subrate base event is determined by LL_SUBRATE_IND and shall only be - * changed if counter wrapped, but that does not really matter as once - * set it's only used internally. + /* If we are in subrate transition mode, we should also listen on + * subrated connection events based on new parameters. */ - connsm->subrate_base_event = next_event_cntr; + if (connsm->csmflags.cfbit.subrate_trans) { + BLE_LL_ASSERT(CONN_IS_CENTRAL(connsm)); + + cstp = &connsm->subrate_trans; + trans_next_event_cntr = cstp->subrate_base_event; + while (INT16_LTE(trans_next_event_cntr, connsm->event_cntr)) { + trans_next_event_cntr += cstp->subrate_factor; + } + cstp->subrate_base_event = trans_next_event_cntr; + + if (INT16_LT(trans_next_event_cntr, next_event_cntr)) { + next_event_cntr = trans_next_event_cntr; + next_is_subrated = 0; + } + } #endif } else { next_event_cntr = connsm->event_cntr + 1; } + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + /* If connection update is scheduled, peripheral shall listen at instant + * and one connection event before instant regardless of subrating. + */ + if (CONN_IS_PERIPHERAL(connsm) && + connsm->csmflags.cfbit.conn_update_sched && + (connsm->subrate_factor > 1)) { + subrate_conn_upd_event_cntr = connsm->conn_update_req.instant - 1; + if (connsm->event_cntr == subrate_conn_upd_event_cntr) { + subrate_conn_upd_event_cntr++; + } + + if (INT16_GT(next_event_cntr, subrate_conn_upd_event_cntr)) { + next_event_cntr = subrate_conn_upd_event_cntr; + next_is_subrated = 0; + } + } + + /* Set next connection event as a subrate base event if that connection + * event is a subrated event, this simplifies calculations later. + * Note that according to spec base event should only be changed on + * wrap-around, but since we only use this value internally we can use any + * valid value. + */ + if (next_is_subrated || + (connsm->subrate_base_event + + connsm->subrate_factor == next_event_cntr)) { + connsm->subrate_base_event = next_event_cntr; + } +#endif + event_cntr_diff = next_event_cntr - connsm->event_cntr; BLE_LL_ASSERT(event_cntr_diff > 0); @@ -2339,6 +2411,14 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) connsm->csmflags.cfbit.host_expects_upd_event = 1; } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + if (connsm->conn_itvl != upd->interval) { + connsm->subrate_base_event = connsm->event_cntr; + connsm->subrate_factor = 1; + connsm->cont_num = 0; + } +#endif + connsm->supervision_tmo = upd->timeout; connsm->periph_latency = upd->latency; connsm->tx_win_size = upd->winsize; @@ -3959,6 +4039,74 @@ ble_ll_conn_periph_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr } #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) +int +ble_ll_conn_subrate_req_llcp(struct ble_ll_conn_sm *connsm, + struct ble_ll_conn_subrate_req_params *srp) +{ + BLE_LL_ASSERT(connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL); + + if ((srp->subrate_min < 0x0001) || (srp->subrate_min > 0x01f4) || + (srp->subrate_max < 0x0001) || (srp->subrate_max > 0x01f4) || + (srp->max_latency > 0x01f3) || (srp->cont_num > 0x01f3) || + (srp->supervision_tmo < 0x000a) || (srp->supervision_tmo > 0x0c80)) { + return -EINVAL; + } + + if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_CONN_PARAM_REQ) { + return -EBUSY; + } + + if ((srp->max_latency > connsm->acc_max_latency) || + (srp->supervision_tmo > connsm->acc_supervision_tmo) || + (srp->subrate_max < connsm->acc_subrate_min) || + (srp->subrate_min > connsm->acc_subrate_max) || + ((connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS * srp->subrate_min * + (srp->max_latency + 1)) * 2 >= srp->supervision_tmo * + BLE_HCI_CONN_SPVN_TMO_UNITS * 1000)) { + return -EINVAL; + } + + connsm->subrate_trans.subrate_factor = min(connsm->acc_subrate_max, + srp->subrate_max); + connsm->subrate_trans.subrate_base_event = connsm->event_cntr; + connsm->subrate_trans.periph_latency = min(connsm->acc_max_latency, + srp->max_latency); + connsm->subrate_trans.cont_num = min(max(connsm->acc_cont_num, + srp->cont_num), + connsm->subrate_trans.subrate_factor - 1); + connsm->subrate_trans.supervision_tmo = min(connsm->supervision_tmo, + srp->supervision_tmo); + + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SUBRATE_UPDATE, NULL); + + return 0; +} + +void +ble_ll_conn_subrate_set(struct ble_ll_conn_sm *connsm, + struct ble_ll_conn_subrate_params *sp) +{ + int16_t event_cntr_diff; + int16_t subrate_events_diff; + + /* Assume parameters were checked by caller */ + + connsm->subrate_factor = sp->subrate_factor; + connsm->subrate_base_event = sp->subrate_base_event; + connsm->periph_latency = sp->periph_latency; + connsm->cont_num = sp->cont_num; + connsm->supervision_tmo = sp->supervision_tmo; + + /* Let's update subrate base event to "latest" one */ + event_cntr_diff = connsm->event_cntr - connsm->subrate_base_event; + subrate_events_diff = event_cntr_diff / connsm->subrate_factor; + connsm->subrate_base_event += connsm->subrate_factor * subrate_events_diff; + + /* TODO send hci event */ +} +#endif + #define MAX_TIME_UNCODED(_maxbytes) \ ble_ll_pdu_tx_time_get(_maxbytes + BLE_LL_DATA_MIC_LEN, \ BLE_PHY_MODE_1M); @@ -4044,6 +4192,14 @@ ble_ll_conn_module_reset(void) memset(conn_params->central_chan_map, 0xff, BLE_LL_CONN_CHMAP_LEN - 1); conn_params->central_chan_map[4] = 0x1f; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + conn_params->acc_subrate_min = 0x0001; + conn_params->acc_subrate_max = 0x0001; + conn_params->acc_max_latency = 0x0000; + conn_params->acc_cont_num = 0x0000; + conn_params->acc_supervision_tmo = 0x0c80; +#endif + /* Reset statistics */ STATS_RESET(ble_ll_conn_stats); diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index 7541f642af..c05e1955bf 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -79,6 +79,13 @@ struct ble_ll_conn_global_params uint16_t conn_init_max_tx_time_coded; uint16_t supp_max_tx_time; uint16_t supp_max_rx_time; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + uint16_t acc_subrate_min; + uint16_t acc_subrate_max; + uint16_t acc_max_latency; + uint16_t acc_cont_num; + uint16_t acc_supervision_tmo; +#endif #endif }; extern struct ble_ll_conn_global_params g_ble_ll_conn_params; diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 04b935432d..f29d3154f4 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "syscfg/syscfg.h" #include "nimble/ble.h" #include "nimble/nimble_opt.h" @@ -408,7 +409,12 @@ ble_ll_ctrl_conn_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld, * request will actually get sent. We add one more event plus the * minimum as per the spec of 6 connection events. */ +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + instant = connsm->subrate_base_event + 6 * connsm->subrate_factor * + (connsm->periph_latency + 1); +#else instant = connsm->event_cntr + connsm->periph_latency + 6 + 1; +#endif /* * XXX: This should change in the future, but for now we will just @@ -1144,6 +1150,126 @@ ble_ll_ctrl_rx_sca_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr) #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) +static void +ble_ll_ctrl_subrate_req_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld, + struct ble_ll_conn_subrate_req_params *srp) +{ + put_le16(pyld + 0, srp->subrate_min); + put_le16(pyld + 2, srp->subrate_max); + put_le16(pyld + 4, srp->max_latency); + put_le16(pyld + 6, srp->cont_num); + put_le16(pyld + 8, srp->supervision_tmo); +} + +static void +ble_ll_ctrl_subrate_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld, + struct ble_ll_conn_subrate_params *sp) +{ + put_le16(pyld + 0, sp->subrate_factor); + put_le16(pyld + 2, sp->subrate_base_event); + put_le16(pyld + 4, sp->periph_latency); + put_le16(pyld + 6, sp->cont_num); + put_le16(pyld + 8, sp->supervision_tmo); +} + +static uint8_t +ble_ll_ctrl_rx_subrate_req(struct ble_ll_conn_sm *connsm, uint8_t *req, + uint8_t *rsp) +{ + struct ble_ll_conn_subrate_req_params params; + struct ble_ll_conn_subrate_req_params *srp = ¶ms; + uint8_t err; + int rc; + +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { + return BLE_LL_CTRL_UNKNOWN_RSP; + } +#endif + + if ((ble_ll_read_supp_features() & BLE_LL_FEAT_CONN_SUBRATING_HOST) == 0) { + ble_ll_ctrl_rej_ext_ind_make(BLE_LL_CTRL_SUBRATE_REQ, + BLE_ERR_UNSUPP_REM_FEATURE, rsp); + return BLE_LL_CTRL_REJECT_IND_EXT; + } + + srp->subrate_min = get_le16(req + 0); + srp->subrate_max = get_le16(req + 2); + srp->max_latency = get_le16(req + 4); + srp->cont_num = get_le16(req + 6); + srp->supervision_tmo = get_le16(req + 8); + + rc = ble_ll_conn_subrate_req_llcp(connsm, srp); + if (rc < 0) { + if (rc == -EINVAL) { + err = BLE_ERR_INV_LMP_LL_PARM; + } else if (rc == -ENOTSUP) { + err = BLE_ERR_UNSUPP_REM_FEATURE; + } else if (rc == -EBUSY) { + err = BLE_ERR_DIFF_TRANS_COLL; + } else { + err = BLE_ERR_UNSPECIFIED; + } + + ble_ll_ctrl_rej_ext_ind_make(BLE_LL_CTRL_SUBRATE_REQ, err, rsp); + + return BLE_LL_CTRL_REJECT_IND_EXT; + } + + return BLE_ERR_MAX; +} + +static uint8_t +ble_ll_ctrl_rx_subrate_ind(struct ble_ll_conn_sm *connsm, uint8_t *req, + uint8_t *rsp) +{ + struct ble_ll_conn_subrate_params params; + struct ble_ll_conn_subrate_params *sp = ¶ms; + uint32_t t1, t2; + +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + return BLE_LL_CTRL_UNKNOWN_RSP; + } +#endif + + sp->subrate_factor = get_le16(req + 0); + sp->subrate_base_event = get_le16(req + 2); + sp->periph_latency = get_le16(req + 4); + sp->cont_num = get_le16(req + 6); + sp->supervision_tmo = get_le16(req + 8); + + /* This is probably not really useful since we shall apply new parameters + * immediately after receiving LL_SUBRATE_IND and central shall apply those + * parameters after receiving ack which it already did, so it's too late + * here to do anything useful. Let's just send LL_REJECT_EXT_IND anyway just + * for debugging purposes and reset to subrate factor of 1 and no latency, + * perhaps we can find some connection event from central and send our PDU. + */ + t1 = connsm->conn_itvl * sp->subrate_factor * (sp->periph_latency + 1) * + BLE_LL_CONN_ITVL_USECS; + t2 = sp->supervision_tmo * BLE_HCI_CONN_SPVN_TMO_UNITS * 1000 / 2; + if ((sp->subrate_factor < 1) || (sp->subrate_factor > 500) || + (sp->cont_num > sp->subrate_factor - 1) || + (sp->subrate_factor * (sp->periph_latency + 1) > 500) || (t1 >= t2)) { + + sp->subrate_factor = 1; + sp->subrate_base_event = connsm->event_cntr; + sp->periph_latency = 0; + sp->cont_num = 0; + sp->supervision_tmo = connsm->supervision_tmo; + + return BLE_ERR_MAX; + } + + ble_ll_conn_subrate_set(connsm, sp); + ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_SUBRATE_REQ); + + return BLE_ERR_MAX; +} +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) static uint8_t ble_ll_ctrl_rx_cis_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, @@ -1865,6 +1991,13 @@ ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_SCA_UPDATE); break; #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + case BLE_LL_CTRL_PROC_SUBRATE_REQ: + /* TODO: send event to host */ + ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_SUBRATE_UPDATE); + break; +#endif + default: break; } @@ -2376,6 +2509,21 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc, void *data) opcode = BLE_LL_CTRL_CIS_REQ; ble_ll_ctrl_cis_create(connsm, ctrdata); break; +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CTRL_PROC_SUBRATE_REQ: + opcode = BLE_LL_CTRL_SUBRATE_REQ; + ble_ll_ctrl_subrate_req_make(connsm, ctrdata, &connsm->subrate_req); + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CTRL_PROC_SUBRATE_UPDATE: + opcode = BLE_LL_CTRL_SUBRATE_IND; + ble_ll_ctrl_subrate_ind_make(connsm, ctrdata, + &connsm->subrate_trans); + break; +#endif #endif default: BLE_LL_ASSERT(0); @@ -2840,6 +2988,14 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) case BLE_LL_CTRL_PERIODIC_SYNC_IND: rsp_opcode = ble_ll_ctrl_rx_periodic_sync_ind(connsm, dptr); break; +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + case BLE_LL_CTRL_SUBRATE_REQ: + rsp_opcode = ble_ll_ctrl_rx_subrate_req(connsm, dptr, rspdata); + break; + case BLE_LL_CTRL_SUBRATE_IND: + rsp_opcode = ble_ll_ctrl_rx_subrate_ind(connsm, dptr, rspdata); + break; #endif default: /* Nothing to do here */ @@ -2924,6 +3080,21 @@ ble_ll_ctrl_reject_ind_send(struct ble_ll_conn_sm *connsm, uint8_t rej_opcode, return rc; } +int +ble_ll_ctrl_tx_start(struct ble_ll_conn_sm *connsm, struct os_mbuf *txpdu) +{ + uint8_t opcode; + + opcode = txpdu->om_data[0]; + switch (opcode) { + case BLE_LL_CTRL_SUBRATE_IND: + connsm->csmflags.cfbit.subrate_trans = 1; + break; + } + + return 0; +} + /** * Called when a Link Layer Control pdu has been transmitted successfully. * This is called when we have a received a PDU during the ISR. @@ -3017,6 +3188,14 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) ble_ll_ctrl_phy_tx_transition_get(txpdu->om_data[2]); break; #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CTRL_SUBRATE_IND: + connsm->csmflags.cfbit.subrate_trans = 0; + connsm->csmflags.cfbit.subrate_ind_txd = 1; + break; +#endif /* BLE_LL_CTRL_SUBRATE_IND */ +#endif /* BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE */ default: break; } From 44f119a73ad3b85b05229636475aa25fa303b010 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 7 Feb 2022 12:47:43 +0100 Subject: [PATCH 0370/1333] nimble/ll: Add HCI for connection subrating --- .../include/controller/ble_ll_conn.h | 3 + .../include/controller/ble_ll_ctrl.h | 4 + .../include/controller/ble_ll_hci.h | 2 +- nimble/controller/src/ble_ll_conn.c | 83 +++++++++++++++- nimble/controller/src/ble_ll_conn_hci.c | 97 +++++++++++++++++++ nimble/controller/src/ble_ll_conn_priv.h | 6 ++ nimble/controller/src/ble_ll_ctrl.c | 3 +- nimble/controller/src/ble_ll_hci.c | 9 ++ nimble/controller/src/ble_ll_hci_ev.c | 32 ++++++ nimble/controller/src/ble_ll_supp_cmd.c | 16 +++ nimble/include/nimble/hci_common.h | 30 ++++++ 11 files changed, 282 insertions(+), 3 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index a50e6e6948..269d881c21 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -134,6 +134,7 @@ union ble_ll_conn_sm_flags { uint32_t pending_initiate_dle:1; uint32_t subrate_trans:1; uint32_t subrate_ind_txd:1; + uint32_t subrate_host_req:1; } cfbit; uint32_t conn_flags; } __attribute__((packed)); @@ -494,6 +495,8 @@ void ble_ll_conn_created_on_aux(struct os_mbuf *rxpdu, #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) +int ble_ll_conn_subrate_req_hci(struct ble_ll_conn_sm *connsm, + struct ble_ll_conn_subrate_req_params *srp); int ble_ll_conn_subrate_req_llcp(struct ble_ll_conn_sm *connsm, struct ble_ll_conn_subrate_req_params *srp); void ble_ll_conn_subrate_set(struct ble_ll_conn_sm *connsm, diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index 17300dc2ae..379960ecea 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -346,6 +346,10 @@ void ble_ll_hci_ev_sca_update(struct ble_ll_conn_sm *connsm, uint8_t status, uint8_t peer_sca); #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) +void ble_ll_hci_ev_subrate_change(struct ble_ll_conn_sm *connsm, uint8_t status); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/controller/include/controller/ble_ll_hci.h b/nimble/controller/include/controller/ble_ll_hci.h index f45aa3ae1b..37d6d205c1 100644 --- a/nimble/controller/include/controller/ble_ll_hci.h +++ b/nimble/controller/include/controller/ble_ll_hci.h @@ -28,7 +28,7 @@ extern "C" { #include "nimble/transport.h" /* For supported commands */ -#define BLE_LL_SUPP_CMD_LEN (45) +#define BLE_LL_SUPP_CMD_LEN (47) extern const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN]; /* The largest event the controller will send. */ diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 4c60c4613a..177b369355 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -957,6 +957,7 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm) connsm->subrate_trans.subrate_factor = 0; ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_SUBRATE_UPDATE); connsm->csmflags.cfbit.subrate_ind_txd = 0; + connsm->csmflags.cfbit.subrate_host_req = 0; } #endif /* BLE_LL_CTRL_SUBRATE_IND */ #endif /* BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE */ @@ -4040,6 +4041,77 @@ ble_ll_conn_periph_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) +int +ble_ll_conn_subrate_req_hci(struct ble_ll_conn_sm *connsm, + struct ble_ll_conn_subrate_req_params *srp) +{ + uint32_t t1, t2; + + if ((srp->subrate_min < 0x0001) || (srp->subrate_min > 0x01f4) || + (srp->subrate_max < 0x0001) || (srp->subrate_max > 0x01f4) || + (srp->max_latency > 0x01f3) || (srp->cont_num > 0x01f3) || + (srp->supervision_tmo < 0x000a) || (srp->supervision_tmo > 0x0c80)) { + return -EINVAL; + } + + if (srp->subrate_max * (srp->max_latency + 1) > 500) { + return -EINVAL; + } + + t1 = connsm->conn_itvl * srp->subrate_max * (srp->max_latency + 1) * + BLE_LL_CONN_ITVL_USECS; + t2 = srp->supervision_tmo * BLE_HCI_CONN_SPVN_TMO_UNITS * 1000 / 2; + if (t1 > t2) { + return -EINVAL; + } + + if (srp->subrate_max < srp->subrate_min) { + return -EINVAL; + } + + if (srp->cont_num >= srp->subrate_max) { + return -EINVAL; + } + +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + if ((connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) && + !ble_ll_conn_rem_feature_check(connsm, + BLE_LL_FEAT_CONN_SUBRATING_HOST)) { + return -ENOTSUP; + } +#endif + + if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_CONN_PARAM_REQ) { + return -EBUSY; + } + + switch (connsm->conn_role) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_LL_CONN_ROLE_CENTRAL: + connsm->subrate_trans.subrate_factor = srp->subrate_max; + connsm->subrate_trans.subrate_base_event = connsm->event_cntr; + connsm->subrate_trans.periph_latency = srp->max_latency; + connsm->subrate_trans.cont_num = srp->cont_num; + connsm->subrate_trans.supervision_tmo = srp->supervision_tmo; + connsm->csmflags.cfbit.subrate_host_req = 1; + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SUBRATE_UPDATE, NULL); + break; +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + case BLE_LL_CONN_ROLE_PERIPHERAL: + connsm->subrate_req = *srp; + connsm->csmflags.cfbit.subrate_host_req = 1; + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SUBRATE_REQ, NULL); + break; +#endif + default: + BLE_LL_ASSERT(0); + } + + + return 0; +} + int ble_ll_conn_subrate_req_llcp(struct ble_ll_conn_sm *connsm, struct ble_ll_conn_subrate_req_params *srp) @@ -4089,9 +4161,16 @@ ble_ll_conn_subrate_set(struct ble_ll_conn_sm *connsm, { int16_t event_cntr_diff; int16_t subrate_events_diff; + uint8_t send_ev; /* Assume parameters were checked by caller */ + send_ev = connsm->csmflags.cfbit.subrate_host_req || + (connsm->subrate_factor != sp->subrate_factor) || + (connsm->periph_latency != sp->periph_latency) || + (connsm->cont_num != sp->cont_num) || + (connsm->supervision_tmo != sp->supervision_tmo); + connsm->subrate_factor = sp->subrate_factor; connsm->subrate_base_event = sp->subrate_base_event; connsm->periph_latency = sp->periph_latency; @@ -4103,7 +4182,9 @@ ble_ll_conn_subrate_set(struct ble_ll_conn_sm *connsm, subrate_events_diff = event_cntr_diff / connsm->subrate_factor; connsm->subrate_base_event += connsm->subrate_factor * subrate_events_diff; - /* TODO send hci event */ + if (send_ev) { + ble_ll_hci_ev_subrate_change(connsm, 0); + } } #endif diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 08ee42057d..4a07ab7698 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "syscfg/syscfg.h" #include "os/os.h" #include "nimble/ble.h" @@ -1692,6 +1693,102 @@ ble_ll_conn_req_peer_sca(const uint8_t *cmdbuf, uint8_t len, } #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) +int +ble_ll_conn_hci_set_default_subrate(const uint8_t *cmdbuf, uint8_t len, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_le_set_default_subrate_cp *cp = (const void *)cmdbuf; + struct ble_ll_conn_global_params *gcp = &g_ble_ll_conn_params; + uint16_t subrate_min; + uint16_t subrate_max; + uint16_t max_latency; + uint16_t cont_num; + uint16_t supervision_tmo; + + subrate_min = le16toh(cp->subrate_min); + subrate_max = le16toh(cp->subrate_max); + max_latency = le16toh(cp->max_latency); + cont_num = le16toh(cp->cont_num); + supervision_tmo = le16toh(cp->supervision_tmo); + + if ((subrate_min < 0x0001) || (subrate_min > 0x01f4) || + (subrate_max < 0x0001) || (subrate_max > 0x01f4) || + (max_latency > 0x01f3) || (cont_num > 0x01f3) || + (supervision_tmo < 0x000a) || (supervision_tmo > 0x0c80)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (subrate_max * (max_latency + 1) > 500) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (subrate_max < subrate_min) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (cont_num >= subrate_max) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + gcp->acc_subrate_min = subrate_min; + gcp->acc_subrate_max = subrate_max; + gcp->acc_max_latency = max_latency; + gcp->acc_cont_num = cont_num; + gcp->acc_supervision_tmo = supervision_tmo; + + return 0; +} + +int +ble_ll_conn_hci_subrate_req(const uint8_t *cmdbuf, uint8_t len, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_le_subrate_req_cp *cp = (const void *)cmdbuf; + struct ble_ll_conn_subrate_req_params srp; + struct ble_ll_conn_sm *connsm; + uint16_t conn_handle; + int rc; + + conn_handle = le16toh(cp->conn_handle); + srp.subrate_min = le16toh(cp->subrate_min); + srp.subrate_max = le16toh(cp->subrate_max); + srp.max_latency = le16toh(cp->max_latency); + srp.cont_num = le16toh(cp->cont_num); + srp.supervision_tmo = le16toh(cp->supervision_tmo); + + connsm = ble_ll_conn_find_by_handle(conn_handle); + if (!connsm) { + return BLE_ERR_UNK_CONN_ID; + } + + rc = ble_ll_conn_subrate_req_hci(connsm, &srp); + if (rc < 0) { + if (rc == -EINVAL) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } else if (rc == -EBUSY) { + return BLE_ERR_CTLR_BUSY; + } else if (rc == -ENOTSUP) { + return BLE_ERR_UNSUPP_REM_FEATURE; + } else { + return BLE_ERR_UNSPECIFIED; + } + } + +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + connsm->acc_subrate_min = srp.subrate_min; + connsm->acc_subrate_min = srp.subrate_max; + connsm->acc_max_latency = srp.max_latency; + connsm->acc_cont_num = srp.cont_num; + connsm->acc_supervision_tmo = srp.supervision_tmo; + } +#endif + + return 0; +} +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) /** * Read authenticated payload timeout (OGF=3, OCF==0x007B) diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index c05e1955bf..7a1e56d874 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -229,6 +229,12 @@ int ble_ll_conn_hci_rd_auth_pyld_tmo(const uint8_t *cmdbuf, uint8_t len, int ble_ll_conn_req_peer_sca(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) +int ble_ll_conn_hci_set_default_subrate(const uint8_t *cmdbuf, uint8_t len, + uint8_t *rspbuf, uint8_t *rsplen); +int ble_ll_conn_hci_subrate_req(const uint8_t *cmdbuf, uint8_t len, + uint8_t *rspbuf, uint8_t *rsplen); +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) void ble_ll_conn_auth_pyld_timer_start(struct ble_ll_conn_sm *connsm); diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index f29d3154f4..5111d6d3c6 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1265,6 +1265,7 @@ ble_ll_ctrl_rx_subrate_ind(struct ble_ll_conn_sm *connsm, uint8_t *req, ble_ll_conn_subrate_set(connsm, sp); ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_SUBRATE_REQ); + connsm->csmflags.cfbit.subrate_host_req = 0; return BLE_ERR_MAX; } @@ -1993,7 +1994,7 @@ ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) case BLE_LL_CTRL_PROC_SUBRATE_REQ: - /* TODO: send event to host */ + ble_ll_hci_ev_subrate_change(connsm, ble_error); ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_SUBRATE_UPDATE); break; #endif diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index bc9160f133..9666b0235f 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -655,6 +655,7 @@ ble_ll_hci_le_cmd_send_cmd_status(uint16_t ocf) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE) case BLE_HCI_OCF_LE_REQ_PEER_SCA: #endif + case BLE_HCI_OCF_LE_SUBRATE_REQ: rc = 1; break; default: @@ -1293,6 +1294,14 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, rc = ble_ll_conn_req_peer_sca(cmdbuf, len, rspbuf, rsplen); break; +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + case BLE_HCI_OCF_LE_SET_DEFAULT_SUBRATE: + rc = ble_ll_conn_hci_set_default_subrate(cmdbuf, len, rspbuf, rsplen); + break; + case BLE_HCI_OCF_LE_SUBRATE_REQ: + rc = ble_ll_conn_hci_subrate_req(cmdbuf, len, rspbuf, rsplen); + break; #endif default: rc = BLE_ERR_UNKNOWN_HCI_CMD; diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index 8543d98925..6da2545c03 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -491,6 +491,38 @@ ble_ll_hci_ev_sca_update(struct ble_ll_conn_sm *connsm, uint8_t status, #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) +void +ble_ll_hci_ev_subrate_change(struct ble_ll_conn_sm *connsm, uint8_t status) +{ + struct ble_hci_ev_le_subev_subrate_change *ev; + struct ble_hci_ev *hci_ev; + + if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_SUBRATE_CHANGE)) { + return; + } + + hci_ev = ble_transport_alloc_evt(0); + if (!hci_ev) { + return; + } + + hci_ev->opcode = BLE_HCI_EVCODE_LE_META; + hci_ev->length = sizeof(*ev); + ev = (void *)hci_ev->data; + + ev->subev_code = BLE_HCI_LE_SUBEV_SUBRATE_CHANGE; + ev->status = status; + ev->conn_handle = htole16(connsm->conn_handle); + ev->subrate_factor = htole16(connsm->subrate_factor); + ev->periph_latency = htole16(connsm->periph_latency); + ev->cont_num = htole16(connsm->cont_num); + ev->supervision_tmo = htole16(connsm->supervision_tmo); + + ble_ll_hci_event_send(hci_ev); +} +#endif + void ble_ll_hci_ev_send_vs_assert(const char *file, uint32_t line) { diff --git a/nimble/controller/src/ble_ll_supp_cmd.c b/nimble/controller/src/ble_ll_supp_cmd.c index 6903c8d201..1c408fbff5 100644 --- a/nimble/controller/src/ble_ll_supp_cmd.c +++ b/nimble/controller/src/ble_ll_supp_cmd.c @@ -582,6 +582,20 @@ BLE_SUPP_CMD_LE_SET_HOST_FEATURE \ ) +/* Octet 46 */ +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) +#define BLE_SUPP_CMD_LE_SET_DEFAULT_SUBRATE (1 << 0) +#define BLE_SUPP_CMD_LE_SUBRATE_REQ (1 << 1) +#else +#define BLE_SUPP_CMD_LE_SET_DEFAULT_SUBRATE (0 << 0) +#define BLE_SUPP_CMD_LE_SUBRATE_REQ (0 << 1) +#endif +#define BLE_LL_SUPP_CMD_OCTET_46 \ +( \ + BLE_SUPP_CMD_LE_SET_DEFAULT_SUBRATE | \ + BLE_SUPP_CMD_LE_SUBRATE_REQ \ +) + /* Defines the array of supported commands */ const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN] = { @@ -630,4 +644,6 @@ const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN] = BLE_LL_SUPP_CMD_OCTET_42, BLE_LL_SUPP_CMD_OCTET_43, BLE_LL_SUPP_CMD_OCTET_44, + 0, + BLE_LL_SUPP_CMD_OCTET_46, }; diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 7d1c3ac902..c52dea2080 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1062,6 +1062,25 @@ struct ble_hci_le_set_host_feat_cp { uint8_t val; } __attribute__((packed)); +#define BLE_HCI_OCF_LE_SET_DEFAULT_SUBRATE (0x007D) +struct ble_hci_le_set_default_subrate_cp { + uint16_t subrate_min; + uint16_t subrate_max; + uint16_t max_latency; + uint16_t cont_num; + uint16_t supervision_tmo; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_SUBRATE_REQ (0x007E) +struct ble_hci_le_subrate_req_cp { + uint16_t conn_handle; + uint16_t subrate_min; + uint16_t subrate_max; + uint16_t max_latency; + uint16_t cont_num; + uint16_t supervision_tmo; +} __attribute__((packed)); + /* --- Vendor specific commands (OGF 0x003F) */ /* Read Random Static Address */ #define BLE_HCI_OCF_VS_RD_STATIC_ADDR (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0001)) @@ -1821,6 +1840,17 @@ struct ble_hci_ev_le_subev_biginfo_adv_report { uint8_t encryption; } __attribute__((packed)); +#define BLE_HCI_LE_SUBEV_SUBRATE_CHANGE (0x23) +struct ble_hci_ev_le_subev_subrate_change { + uint8_t subev_code; + uint8_t status; + uint16_t conn_handle; + uint16_t subrate_factor; + uint16_t periph_latency; + uint16_t cont_num; + uint16_t supervision_tmo; +} __attribute__((packed)); + /* Data buffer overflow event */ #define BLE_HCI_EVENT_ACL_BUF_OVERFLOW (0x01) From b2ac02e87f39167e76f12229b07ab703f0bbbc40 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 7 Apr 2022 14:14:37 +0200 Subject: [PATCH 0371/1333] nimble/ll: Adjust periodic sync HCI commands to 5.3 There are some new parameter values added in 5.3 to control duplicate filtering. Since we do not support ADI in periodic advertising, we simply return a proper error. Note that error is defined only for HCI_LE_Periodic_Advertising_Create_Sync but we add the same behavior for other commands also, as otherwise that would not make any sense. --- nimble/controller/src/ble_ll_conn_hci.c | 17 +++++++++---- nimble/controller/src/ble_ll_sync.c | 32 ++++++++++++++++++++----- nimble/include/nimble/hci_common.h | 1 + 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 4a07ab7698..be41bf62a3 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -2038,9 +2038,13 @@ ble_ll_set_sync_transfer_params(const uint8_t *cmdbuf, uint8_t len, goto done; } - if (cmd->mode > 0x02) { - rc = BLE_ERR_INV_HCI_CMD_PARMS; - goto done; + if ((MYNEWT_VAL(BLE_VERSION) >= 53 ) && (cmd->mode == 0x03)) { + /* We do not support ADI in periodic advertising thus cannot enable + * duplicate filtering. + */ + return BLE_ERR_UNSUPPORTED; + } else if (cmd->mode > 0x02) { + return BLE_ERR_INV_HCI_CMD_PARMS; } skip = le16toh(cmd->skip); @@ -2091,7 +2095,12 @@ ble_ll_set_default_sync_transfer_params(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } - if (cmd->mode > 0x02) { + if ((MYNEWT_VAL(BLE_VERSION) >= 53 ) && (cmd->mode == 0x03)) { + /* We do not support ADI in periodic advertising thus cannot enable + * duplicate filtering. + */ + return BLE_ERR_UNSUPPORTED; + } else if (cmd->mode > 0x02) { return BLE_ERR_INV_HCI_CMD_PARMS; } diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 72da2d970d..0395c72bc5 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -1465,11 +1465,22 @@ ble_ll_sync_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } -#if MYNEWT_VAL(BLE_VERSION) >= 51 - if (cmd->options > BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_DISABLED) { -#else - if (cmd->options > BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_FILTER) { -#endif + if (MYNEWT_VAL(BLE_VERSION) >= 53) { + if (cmd->options & 0xf8) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + if (!(cmd->options & BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_DISABLED) && + (cmd->options & BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_DUPLICATES)) { + /* We do not support ADI in periodic advertising thus cannot enable + * duplicate filtering. + */ + return BLE_ERR_UNSUPPORTED; + } + } else if (MYNEWT_VAL(BLE_VERSION) >= 51) { + if (cmd->options & 0xfc) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + } else if (cmd->options & 0xfe) { return BLE_ERR_INV_HCI_CMD_PARMS; } @@ -1743,7 +1754,16 @@ ble_ll_sync_receive_enable(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } - if (cmd->enable > 0x01) { + if (MYNEWT_VAL(BLE_VERSION) >= 53) { + if (cmd->enable > 0x03) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } else if (cmd->enable == 0x03) { + /* We do not support ADI in periodic advertising thus cannot enable + * duplicate filtering. + */ + return BLE_ERR_UNSUPPORTED; + } + } else if (cmd->enable > 0x01) { return BLE_ERR_INV_HCI_CMD_PARMS; } diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index c52dea2080..58de8a6cd1 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -709,6 +709,7 @@ struct ble_hci_le_ext_create_conn_cp { #define BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_FILTER 0x01 #define BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_DISABLED 0x02 +#define BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_DUPLICATES 0x04 #define BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC (0x0044) struct ble_hci_le_periodic_adv_create_sync_cp { From db755d21304ed6e734d7e292ae450338744b923e Mon Sep 17 00:00:00 2001 From: h2zero Date: Sun, 10 Apr 2022 19:24:43 -0600 Subject: [PATCH 0372/1333] nimble/host: Add missing legacy scan response event type. This adds the missing event type in the extended advertising legacy type decoding. Without this, scan responses would be missed if the PDU was ADV_SCAN_IND. --- nimble/host/src/ble_hs_hci_evt.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 62de50e0b9..b3724a8215 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -501,20 +501,21 @@ ble_hs_hci_evt_le_rd_rem_used_feat_complete(uint8_t subevent, const void *data, static int ble_hs_hci_decode_legacy_type(uint16_t evt_type) { - switch (evt_type) { - case BLE_HCI_LEGACY_ADV_EVTYPE_ADV_IND: - return BLE_HCI_ADV_RPT_EVTYPE_ADV_IND; - case BLE_HCI_LEGACY_ADV_EVTYPE_ADV_DIRECT_IND: - return BLE_HCI_ADV_RPT_EVTYPE_DIR_IND; - case BLE_HCI_LEGACY_ADV_EVTYPE_ADV_SCAN_IND: - return BLE_HCI_ADV_RPT_EVTYPE_SCAN_IND; - case BLE_HCI_LEGACY_ADV_EVTYPE_ADV_NONCON_IND: - return BLE_HCI_ADV_RPT_EVTYPE_NONCONN_IND; - case BLE_HCI_LEGACY_ADV_EVTYPE_SCAN_RSP_ADV_IND: - return BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP; - default: - return -1; - } + switch (evt_type) { + case BLE_HCI_LEGACY_ADV_EVTYPE_ADV_IND: + return BLE_HCI_ADV_RPT_EVTYPE_ADV_IND; + case BLE_HCI_LEGACY_ADV_EVTYPE_ADV_DIRECT_IND: + return BLE_HCI_ADV_RPT_EVTYPE_DIR_IND; + case BLE_HCI_LEGACY_ADV_EVTYPE_ADV_SCAN_IND: + return BLE_HCI_ADV_RPT_EVTYPE_SCAN_IND; + case BLE_HCI_LEGACY_ADV_EVTYPE_ADV_NONCON_IND: + return BLE_HCI_ADV_RPT_EVTYPE_NONCONN_IND; + case BLE_HCI_LEGACY_ADV_EVTYPE_SCAN_RSP_ADV_IND: + case BLE_HCI_LEGACY_ADV_EVTYPE_SCAN_RSP_ADV_SCAN_IND: + return BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP; + default: + return -1; + } } #endif From 14b43a457a2938f8cb9b7a3b6da380eb4486eadc Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 5 Apr 2022 16:15:34 +0200 Subject: [PATCH 0373/1333] nimble/ll: Move global channel map out of ble_ll_conn Global channels map is also used by adv code. This fixes build without central/peripheral roles enabled. --- nimble/controller/include/controller/ble_ll.h | 6 +++++ .../include/controller/ble_ll_conn.h | 8 +++---- nimble/controller/src/ble_ll.c | 4 ++++ nimble/controller/src/ble_ll_adv.c | 11 ++++----- nimble/controller/src/ble_ll_conn.c | 24 +++++++------------ nimble/controller/src/ble_ll_conn_hci.c | 4 ++-- nimble/controller/src/ble_ll_conn_priv.h | 2 -- nimble/controller/src/ble_ll_ctrl.c | 10 ++++---- 8 files changed, 33 insertions(+), 36 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 14fdcc7d70..18468d43b4 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -91,6 +91,8 @@ void ble_ll_assert(const char *file, unsigned line) __attribute((noreturn)); /* Packet queue header definition */ STAILQ_HEAD(ble_ll_pkt_q, os_mbuf_pkthdr); +#define BLE_LL_CHAN_MAP_LEN (5) + /* * Global Link Layer data object. There is only one Link Layer data object * per controller although there may be many instances of the link layer state @@ -104,6 +106,10 @@ struct ble_ll_obj /* Current Link Layer state */ uint8_t ll_state; + /* Global channel map */ + uint8_t chan_map_num_used; + uint8_t chan_map[BLE_LL_CHAN_MAP_LEN]; + #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) /* Number of ACL data packets supported */ uint8_t ll_num_acl_pkts; diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 269d881c21..437d7c2506 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -24,6 +24,7 @@ #include "nimble/ble.h" #include "nimble/hci_common.h" #include "nimble/nimble_npl.h" +#include "controller/ble_ll.h" #include "controller/ble_ll_sched.h" #include "controller/ble_ll_ctrl.h" #include "controller/ble_phy.h" @@ -47,9 +48,6 @@ extern "C" { #define BLE_LL_CONN_STATE_CREATED (1) #define BLE_LL_CONN_STATE_ESTABLISHED (2) -/* Channel map size */ -#define BLE_LL_CONN_CHMAP_LEN (5) - /* Definition for RSSI when the RSSI is unknown */ #define BLE_LL_CONN_UNKNOWN_RSSI (127) @@ -240,8 +238,8 @@ struct ble_ll_conn_sm #endif /* Used to calculate data channel index for connection */ - uint8_t chanmap[BLE_LL_CONN_CHMAP_LEN]; - uint8_t req_chanmap[BLE_LL_CONN_CHMAP_LEN]; + uint8_t chanmap[BLE_LL_CHAN_MAP_LEN]; + uint8_t req_chanmap[BLE_LL_CHAN_MAP_LEN]; uint16_t chanmap_instant; uint16_t channel_id; /* TODO could be union with hop and last chan used */ uint8_t hop_inc; diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index b9d9d7b149..185fb58319 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1640,6 +1640,10 @@ ble_ll_reset(void) g_ble_ll_data.ll_pref_tx_phys = phy_mask; g_ble_ll_data.ll_pref_rx_phys = phy_mask; + /* Enable all channels in channel map */ + g_ble_ll_data.chan_map_num_used = BLE_PHY_NUM_DATA_CHANS; + memset(g_ble_ll_data.chan_map, 0xff, BLE_LL_CHAN_MAP_LEN); + #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Reset connection module */ ble_ll_conn_module_reset(); diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 1aaeeb4d89..129eeba569 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -162,7 +162,7 @@ struct ble_ll_adv_sm uint8_t periodic_sync_active : 1; uint8_t periodic_sync_index : 1; uint8_t periodic_num_used_chans; - uint8_t periodic_chanmap[BLE_LL_CONN_CHMAP_LEN]; + uint8_t periodic_chanmap[BLE_LL_CHAN_MAP_LEN]; uint32_t periodic_adv_itvl_ticks; uint8_t periodic_adv_itvl_rem_usec; uint8_t periodic_adv_event_start_time_remainder; @@ -1372,8 +1372,8 @@ ble_ll_adv_aux_calculate(struct ble_ll_adv_sm *advsm, #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) aux->chan = ble_ll_utils_dci_csa2(advsm->event_cntr++, advsm->channel_id, - g_ble_ll_conn_params.num_used_chans, - g_ble_ll_conn_params.central_chan_map); + g_ble_ll_data.chan_map_num_used, + g_ble_ll_data.chan_map); #else aux->chan = ble_ll_utils_remapped_channel(ble_ll_rand() % BLE_PHY_NUM_DATA_CHANS, g_ble_ll_conn_params.central_chan_map); @@ -2545,9 +2545,8 @@ ble_ll_adv_sm_start_periodic(struct ble_ll_adv_sm *advsm) advsm->periodic_adv_active = 1; /* keep channel map since we cannot change it later on */ - memcpy(advsm->periodic_chanmap, g_ble_ll_conn_params.central_chan_map, - BLE_LL_CONN_CHMAP_LEN); - advsm->periodic_num_used_chans = g_ble_ll_conn_params.num_used_chans; + memcpy(advsm->periodic_chanmap, g_ble_ll_data.chan_map, BLE_LL_CHAN_MAP_LEN); + advsm->periodic_num_used_chans = g_ble_ll_data.chan_map_num_used; advsm->periodic_event_cntr = 0; /* for chaining we start with random counter as we share access addr */ advsm->periodic_chain_event_cntr = ble_ll_rand(); diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 177b369355..dc43fecc66 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1699,9 +1699,8 @@ ble_ll_conn_central_common_init(struct ble_ll_conn_sm *connsm) connsm->hop_inc = (ble_ll_rand() % 12) + 5; /* Set channel map to map requested by host */ - connsm->num_used_chans = g_ble_ll_conn_params.num_used_chans; - memcpy(connsm->chanmap, g_ble_ll_conn_params.central_chan_map, - BLE_LL_CONN_CHMAP_LEN); + connsm->num_used_chans = g_ble_ll_data.chan_map_num_used; + memcpy(connsm->chanmap, g_ble_ll_data.chan_map, BLE_LL_CHAN_MAP_LEN); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) connsm->acc_subrate_min = g_ble_ll_conn_params.acc_subrate_min; @@ -2471,7 +2470,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) on peripheral side. Could ignore it or see if still enqueued. */ connsm->num_used_chans = ble_ll_utils_calc_num_used_chans(connsm->req_chanmap); - memcpy(connsm->chanmap, connsm->req_chanmap, BLE_LL_CONN_CHMAP_LEN); + memcpy(connsm->chanmap, connsm->req_chanmap, BLE_LL_CHAN_MAP_LEN); connsm->csmflags.cfbit.chanmap_update_scheduled = 0; @@ -3007,7 +3006,7 @@ ble_ll_conn_tx_connect_ind_pducb(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_by put_le16(dptr + 10, connsm->conn_itvl); put_le16(dptr + 12, connsm->periph_latency); put_le16(dptr + 14, connsm->supervision_tmo); - memcpy(dptr + 16, &connsm->chanmap, BLE_LL_CONN_CHMAP_LEN); + memcpy(dptr + 16, &connsm->chanmap, BLE_LL_CHAN_MAP_LEN); dptr[21] = connsm->hop_inc | (connsm->central_sca << 5); *hdr_byte = pdu_data->hdr_byte; @@ -3882,17 +3881,15 @@ ble_ll_conn_set_global_chanmap(uint8_t num_used_chans, const uint8_t *chanmap) #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) struct ble_ll_conn_sm *connsm; #endif - struct ble_ll_conn_global_params *conn_params; /* Do nothing if same channel map */ - conn_params = &g_ble_ll_conn_params; - if (!memcmp(conn_params->central_chan_map, chanmap, BLE_LL_CONN_CHMAP_LEN)) { + if (!memcmp(g_ble_ll_data.chan_map, chanmap, BLE_LL_CHAN_MAP_LEN)) { return; } /* Change channel map and cause channel map update procedure to start */ - conn_params->num_used_chans = num_used_chans; - memcpy(conn_params->central_chan_map, chanmap, BLE_LL_CONN_CHMAP_LEN); + g_ble_ll_data.chan_map_num_used = num_used_chans; + memcpy(g_ble_ll_data.chan_map, chanmap, BLE_LL_CHAN_MAP_LEN); #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Perform channel map update */ @@ -3966,7 +3963,7 @@ ble_ll_conn_periph_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr connsm->conn_itvl = get_le16(dptr + 10); connsm->periph_latency = get_le16(dptr + 12); connsm->supervision_tmo = get_le16(dptr + 14); - memcpy(&connsm->chanmap, dptr + 16, BLE_LL_CONN_CHMAP_LEN); + memcpy(&connsm->chanmap, dptr + 16, BLE_LL_CHAN_MAP_LEN); connsm->hop_inc = dptr[21] & 0x1F; connsm->central_sca = dptr[21] >> 5; @@ -4268,11 +4265,6 @@ ble_ll_conn_module_reset(void) conn_params->sugg_tx_octets = BLE_LL_CONN_SUPP_BYTES_MIN; conn_params->sugg_tx_time = BLE_LL_CONN_SUPP_TIME_MIN; - /* Mask in all channels by default */ - conn_params->num_used_chans = BLE_PHY_NUM_DATA_CHANS; - memset(conn_params->central_chan_map, 0xff, BLE_LL_CONN_CHMAP_LEN - 1); - conn_params->central_chan_map[4] = 0x1f; - #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) conn_params->acc_subrate_min = 0x0001; conn_params->acc_subrate_max = 0x0001; diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index be41bf62a3..8f5771a673 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1386,9 +1386,9 @@ ble_ll_conn_hci_rd_chan_map(const uint8_t *cmdbuf, uint8_t len, memset(rsp->chan_map, 0, sizeof(rsp->chan_map)); } else { if (connsm->csmflags.cfbit.chanmap_update_scheduled) { - memcpy(rsp->chan_map, connsm->req_chanmap, BLE_LL_CONN_CHMAP_LEN); + memcpy(rsp->chan_map, connsm->req_chanmap, BLE_LL_CHAN_MAP_LEN); } else { - memcpy(rsp->chan_map, connsm->chanmap, BLE_LL_CONN_CHMAP_LEN); + memcpy(rsp->chan_map, connsm->chanmap, BLE_LL_CHAN_MAP_LEN); } rc = BLE_ERR_SUCCESS; } diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index 7a1e56d874..90c32c0c1e 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -66,8 +66,6 @@ extern "C" { /* Global Link Layer connection parameters */ struct ble_ll_conn_global_params { - uint8_t central_chan_map[BLE_LL_CONN_CHMAP_LEN]; - uint8_t num_used_chans; #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) uint8_t supp_max_tx_octets; uint8_t supp_max_rx_octets; diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 5111d6d3c6..7ece7b1c83 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1868,12 +1868,12 @@ static void ble_ll_ctrl_chanmap_req_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld) { /* Copy channel map that host desires into request */ - memcpy(pyld, g_ble_ll_conn_params.central_chan_map, BLE_LL_CONN_CHMAP_LEN); - memcpy(connsm->req_chanmap, pyld, BLE_LL_CONN_CHMAP_LEN); + memcpy(pyld, g_ble_ll_data.chan_map, BLE_LL_CHAN_MAP_LEN); + memcpy(connsm->req_chanmap, pyld, BLE_LL_CHAN_MAP_LEN); /* Place instant into request */ connsm->chanmap_instant = connsm->event_cntr + connsm->periph_latency + 6 + 1; - put_le16(pyld + BLE_LL_CONN_CHMAP_LEN, connsm->chanmap_instant); + put_le16(pyld + BLE_LL_CHAN_MAP_LEN, connsm->chanmap_instant); /* Set scheduled flag */ connsm->csmflags.cfbit.chanmap_update_scheduled = 1; @@ -2393,13 +2393,13 @@ ble_ll_ctrl_rx_chanmap_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr) #endif /* If instant is in the past, we have to end the connection */ - instant = get_le16(dptr + BLE_LL_CONN_CHMAP_LEN); + instant = get_le16(dptr + BLE_LL_CHAN_MAP_LEN); conn_events = (instant - connsm->event_cntr) & 0xFFFF; if (conn_events >= 32767) { ble_ll_conn_timeout(connsm, BLE_ERR_INSTANT_PASSED); } else { connsm->chanmap_instant = instant; - memcpy(connsm->req_chanmap, dptr, BLE_LL_CONN_CHMAP_LEN); + memcpy(connsm->req_chanmap, dptr, BLE_LL_CHAN_MAP_LEN); connsm->csmflags.cfbit.chanmap_update_scheduled = 1; } From 39dcd34def1447fdd62cbd4b1f01c31fce21acfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 28 Mar 2022 08:33:15 +0200 Subject: [PATCH 0374/1333] host/ble_att_srv: security check for notifications/indications According to Core Specification Version 5.3, Vol 3, Part C 10.3.2.2: " Any notifications received before the security requirements are met shall be ignored. Any indications received before the security requirements are met shall be confirmed and then discarded. When a client reconnects to a server and expects to receive indications or notifications for which security is required, the client shall enable encryption with the server." --- nimble/host/src/ble_att_svr.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 73e258decb..272fc56778 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -2472,6 +2472,7 @@ ble_att_svr_rx_notify(uint16_t conn_handle, struct os_mbuf **rxom) #endif struct ble_att_notify_req *req; + struct ble_gap_sec_state sec_state; uint16_t handle; int rc; @@ -2488,6 +2489,15 @@ ble_att_svr_rx_notify(uint16_t conn_handle, struct os_mbuf **rxom) return BLE_HS_EBADDATA; } + ble_att_svr_get_sec_state(conn_handle, &sec_state); + + /* All indications shall be confirmed, but only these with required + * security established shall be pass to application + */ + if (MYNEWT_VAL(BLE_SM_SC_LVL) >= 2 && !sec_state.encrypted) { + return 0; + } + /* Strip the request base from the front of the mbuf. */ os_mbuf_adj(*rxom, sizeof(*req)); @@ -2537,6 +2547,7 @@ ble_att_svr_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom) #endif struct ble_att_indicate_req *req; + struct ble_gap_sec_state sec_state; struct os_mbuf *txom; uint16_t handle; uint8_t att_err; @@ -2569,6 +2580,15 @@ ble_att_svr_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom) goto done; } + ble_att_svr_get_sec_state(conn_handle, &sec_state); + + /* All indications shall be confirmed, but only these with required + * security established shall be pass to application + */ + if (MYNEWT_VAL(BLE_SM_SC_LVL) >= 2 && !sec_state.encrypted) { + goto done; + } + /* Strip the request base from the front of the mbuf. */ os_mbuf_adj(*rxom, sizeof(*req)); From be09a38ec0cc022838eab08e0ac6f2c966277a5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 17 Dec 2021 07:55:56 +0100 Subject: [PATCH 0375/1333] apps/bttester: add GATT Client service It's meant to be replacement for GATT one (with GATT Server service). This service privides asynchronous responses in form of events. --- apps/bttester/src/bttester.c | 5 + apps/bttester/src/bttester.h | 251 +++++- apps/bttester/src/gap.c | 2 +- apps/bttester/src/gatt_cl.c | 1483 ++++++++++++++++++++++++++++++++++ 4 files changed, 1739 insertions(+), 2 deletions(-) create mode 100644 apps/bttester/src/gatt_cl.c diff --git a/apps/bttester/src/bttester.c b/apps/bttester/src/bttester.c index 5ddc295482..76aebbf1e0 100644 --- a/apps/bttester/src/bttester.c +++ b/apps/bttester/src/bttester.c @@ -83,6 +83,7 @@ static void supported_services(uint8_t *data, uint16_t len) #if MYNEWT_VAL(BLE_MESH) tester_set_bit(buf, BTP_SERVICE_ID_MESH); #endif /* MYNEWT_VAL(BLE_MESH) */ + tester_set_bit(buf, BTP_SERVICE_ID_GATTC); tester_send(BTP_SERVICE_ID_CORE, CORE_READ_SUPPORTED_SERVICES, BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); @@ -232,6 +233,10 @@ static void cmd_handler(struct os_event *ev) cmd->hdr.data, len); break; #endif /* MYNEWT_VAL(BLE_MESH) */ + case BTP_SERVICE_ID_GATTC: + tester_handle_gattc(cmd->hdr.opcode, cmd->hdr.index, + cmd->hdr.data, len); + break; default: tester_rsp(cmd->hdr.service, cmd->hdr.opcode, cmd->hdr.index, BTP_STATUS_FAILED); diff --git a/apps/bttester/src/bttester.h b/apps/bttester/src/bttester.h index 4bf7485779..d37939dc24 100644 --- a/apps/bttester/src/bttester.h +++ b/apps/bttester/src/bttester.h @@ -20,6 +20,7 @@ /* bttester.h - Bluetooth tester headers */ /* + * Copyright (C) 2021 Codecoup * Copyright (c) 2015-2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 @@ -47,6 +48,7 @@ #define BTP_SERVICE_ID_GATT 2 #define BTP_SERVICE_ID_L2CAP 3 #define BTP_SERVICE_ID_MESH 4 +#define BTP_SERVICE_ID_GATTC 6 #define BTP_STATUS_SUCCESS 0x00 #define BTP_STATUS_FAILED 0x01 @@ -493,6 +495,11 @@ struct gatt_included { struct gatt_service service; } __packed; +struct gatt_read_uuid_chr { + uint16_t handle; + uint8_t data[0]; +} __packed; + struct gatt_characteristic { uint16_t characteristic_handle; uint16_t value_handle; @@ -1038,7 +1045,9 @@ uint8_t tester_init_gatt(void); uint8_t tester_unregister_gatt(void); void tester_handle_gatt(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len); -int tester_gatt_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, +void tester_handle_gattc(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len); +int tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, uint8_t indication, struct os_mbuf *om); int tester_gatt_subscribe_ev(uint16_t conn_handle, uint16_t attr_handle, uint8_t reason, uint8_t prev_notify, uint8_t cur_notify, @@ -1060,4 +1069,244 @@ void tester_handle_mesh(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t l void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); int gatt_svr_init(void); +/* GATT Client Service */ +/* commands */ +#define GATTC_READ_SUPPORTED_COMMANDS 0x01 +struct gattc_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define GATTC_EXCHANGE_MTU 0x02 + +#define GATTC_DISC_ALL_PRIM_SVCS 0x03 +struct gattc_disc_all_prim_svcs_cmd { + uint8_t address_type; + uint8_t address[6]; +} __packed; + +#define GATTC_DISC_PRIM_UUID 0x04 +struct gattc_disc_prim_uuid_cmd { + uint8_t address_type; + uint8_t address[6]; + uint8_t uuid_length; + uint8_t uuid[0]; +} __packed; + +#define GATTC_FIND_INCLUDED 0x05 +struct gattc_find_included_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; +} __packed; + +#define GATTC_DISC_ALL_CHRC 0x06 +struct gattc_disc_all_chrc_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; +} __packed; + +#define GATTC_DISC_CHRC_UUID 0x07 +struct gattc_disc_chrc_uuid_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_length; + uint8_t uuid[0]; +} __packed; + +#define GATTC_DISC_ALL_DESC 0x08 +struct gattc_disc_all_desc_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; +} __packed; + +#define GATTC_READ 0x09 +struct gattc_read_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; +} __packed; + +#define GATTC_READ_UUID 0x0a +struct gattc_read_uuid_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_length; + uint8_t uuid[0]; +} __packed; +struct gattc_read_uuid_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint16_t data_length; + uint8_t value_length; + uint8_t data[0]; +} __packed; + +#define GATTC_READ_LONG 0x0b +struct gattc_read_long_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t offset; +} __packed; + +#define GATTC_READ_MULTIPLE 0x0c +struct gattc_read_multiple_cmd { + uint8_t address_type; + uint8_t address[6]; + uint8_t handles_count; + uint16_t handles[0]; +} __packed; + +#define GATTC_WRITE_WITHOUT_RSP 0x0d +struct gattc_write_without_rsp_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define GATTC_SIGNED_WRITE_WITHOUT_RSP 0x0e +struct gattc_signed_write_without_rsp_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define GATTC_WRITE 0x0f +struct gattc_write_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define GATTC_WRITE_LONG 0x10 +struct gattc_write_long_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t offset; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define GATTC_RELIABLE_WRITE 0x11 +struct gattc_reliable_write_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t offset; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define GATTC_CFG_NOTIFY 0x12 +#define GATTC_CFG_INDICATE 0x13 +struct gattc_cfg_notify_cmd { + uint8_t address_type; + uint8_t address[6]; + uint8_t enable; + uint16_t ccc_handle; +} __packed; + +/* events */ +#define GATTC_EV_MTU_EXCHANGED 0x80 +struct gattc_exchange_mtu_ev { + uint8_t address_type; + uint8_t address[6]; + uint16_t mtu; +} __packed; + +#define GATTC_DISC_ALL_PRIM_RP 0x81 +struct gattc_disc_prim_svcs_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint8_t services_count; + uint8_t data[0]; +} __packed; + +#define GATTC_DISC_PRIM_UUID_RP 0x82 + +#define GATTC_FIND_INCLUDED_RP 0x83 +struct gattc_find_included_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint8_t services_count; + struct gatt_included included[0]; +} __packed; + +#define GATTC_DISC_ALL_CHRC_RP 0x84 +#define GATTC_DISC_CHRC_UUID_RP 0x85 +struct gattc_disc_chrc_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint8_t characteristics_count; + struct gatt_characteristic characteristics[0]; +} __packed; + +#define GATTC_DISC_ALL_DESC_RP 0x86 +struct gattc_disc_all_desc_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint8_t descriptors_count; + struct gatt_descriptor descriptors[0]; +} __packed; + +#define GATTC_READ_RP 0x87 +#define GATTC_READ_UUID_RP 0x88 +#define GATTC_READ_LONG_RP 0x89 +#define GATTC_READ_MULTIPLE_RP 0x8a +struct gattc_read_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define GATTC_WRITE_RP 0x8b +struct gattc_write_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; +} __packed; +#define GATTC_WRITE_LONG_RP 0x8c +#define GATTC_RELIABLE_WRITE_RP 0x8d +#define GATTC_RELIABLE_WRITE_RP 0x8d +#define GATTC_CFG_NOTIFY_RP 0x8e +#define GATTC_CFG_INDICATE_RP 0x8f +struct subscribe_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; +} __packed; + +#define GATTC_EV_NOTIFICATION_RXED 0x90 +struct gattc_notification_ev { + uint8_t address_type; + uint8_t address[6]; + uint8_t type; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; +} __packed; + #endif /* __BTTESTER_H__ */ diff --git a/apps/bttester/src/gap.c b/apps/bttester/src/gap.c index ce6cf33dbf..4922f4fb7a 100644 --- a/apps/bttester/src/gap.c +++ b/apps/bttester/src/gap.c @@ -1155,7 +1155,7 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg) print_mbuf(event->notify_rx.om); console_printf("\n"); - tester_gatt_notify_rx_ev(event->notify_rx.conn_handle, + tester_gattc_notify_rx_ev(event->notify_rx.conn_handle, event->notify_rx.attr_handle, event->notify_rx.indication, event->notify_rx.om); diff --git a/apps/bttester/src/gatt_cl.c b/apps/bttester/src/gatt_cl.c new file mode 100644 index 0000000000..c551bb1735 --- /dev/null +++ b/apps/bttester/src/gatt_cl.c @@ -0,0 +1,1483 @@ +/* + * 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. + */ + +#include +#include +#include + +#include "host/ble_gap.h" +#include "host/ble_gatt.h" +#include "console/console.h" +#include "services/gatt/ble_svc_gatt.h" +#include "../../../nimble/host/src/ble_att_priv.h" +#include "../../../nimble/host/src/ble_gatt_priv.h" + +#include "bttester.h" + +#define CONTROLLER_INDEX 0 +#define MAX_BUFFER_SIZE 2048 + +/* Convert UUID from BTP command to bt_uuid */ +static uint8_t btp2bt_uuid(const uint8_t *uuid, uint8_t len, + ble_uuid_any_t *bt_uuid) +{ + uint16_t le16; + + switch (len) { + case 0x02: /* UUID 16 */ + bt_uuid->u.type = BLE_UUID_TYPE_16; + memcpy(&le16, uuid, sizeof(le16)); + BLE_UUID16(bt_uuid)->value = sys_le16_to_cpu(le16); + break; + case 0x10: /* UUID 128*/ + bt_uuid->u.type = BLE_UUID_TYPE_128; + memcpy(BLE_UUID128(bt_uuid)->value, uuid, 16); + break; + default: + return BTP_STATUS_FAILED; + } + return BTP_STATUS_SUCCESS; +} + +/* + * gatt_buf - cache used by a gatt client (to cache data read/discovered) + * and gatt server (to store attribute user_data). + * It is not intended to be used by client and server at the same time. + */ +static struct { + uint16_t len; + uint8_t buf[MAX_BUFFER_SIZE]; + uint16_t cnt; +} gatt_buf; +static struct bt_gatt_subscribe_params { + uint16_t ccc_handle; + uint16_t value; + uint16_t value_handle; +} subscribe_params; + +static void *gatt_buf_add(const void *data, size_t len) +{ + void *ptr = gatt_buf.buf + gatt_buf.len; + + if ((len + gatt_buf.len) > MAX_BUFFER_SIZE) { + return NULL; + } + + if (data) { + memcpy(ptr, data, len); + } else { + (void) memset(ptr, 0, len); + } + + gatt_buf.len += len; + + SYS_LOG_DBG("%d/%d used", gatt_buf.len, MAX_BUFFER_SIZE); + + return ptr; +} + +static void *gatt_buf_reserve(size_t len) +{ + return gatt_buf_add(NULL, len); +} + +static void gatt_buf_clear(void) +{ + (void) memset(&gatt_buf, 0, sizeof(gatt_buf)); +} + +static void discover_destroy(void) +{ + gatt_buf_clear(); +} + +static void read_destroy() +{ + gatt_buf_clear(); +} + +static int tester_mtu_exchanged_ev(uint16_t conn_handle, + const struct ble_gatt_error *error, + uint16_t mtu, void *arg) +{ + struct gattc_exchange_mtu_ev *ev; + struct ble_gap_conn_desc conn; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + + SYS_LOG_DBG(""); + + if (ble_gap_conn_find(conn_handle, &conn)) { + goto fail; + } + + net_buf_simple_init(buf, 0); + ev = net_buf_simple_add(buf, sizeof(*ev)); + + addr = &conn.peer_ota_addr; + + ev->address_type = addr->type; + memcpy(ev->address, addr->val, sizeof(ev->address)); + + ev->mtu = mtu; + + tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_EV_MTU_EXCHANGED, + CONTROLLER_INDEX, buf); +fail: + os_mbuf_free_chain(buf); + return 0; +} + +static void exchange_mtu(uint8_t *data, uint16_t len) +{ + struct ble_gap_conn_desc conn; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + if (ble_gattc_exchange_mtu(conn.conn_handle, tester_mtu_exchanged_ev, NULL)) { + status = BTP_STATUS_FAILED; + goto rsp; + } + +rsp: + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_EXCHANGE_MTU, + CONTROLLER_INDEX, status); +} + +static int disc_prim_svcs_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_svc *gatt_svc, void *arg) +{ + struct gattc_disc_prim_svcs_rp *rp; + struct ble_gap_conn_desc conn; + struct gatt_service *service; + const ble_uuid_any_t *uuid; + const ble_addr_t *addr; + uint8_t uuid_length; + struct os_mbuf *buf = os_msys_get(0, 0); + uint8_t opcode = (uint8_t) (int) arg; + uint8_t err = (uint8_t) error->status; + int rc = 0; + + SYS_LOG_DBG(""); + + if (ble_gap_conn_find(conn_handle, &conn)) { + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + rp->status = err; + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->services_count = 0; + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + if (error->status == BLE_HS_EDONE) { + rp->status = 0; + rp->services_count = gatt_buf.cnt; + os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + uuid = &gatt_svc->uuid; + uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); + + service = gatt_buf_reserve(sizeof(*service) + uuid_length); + if (!service) { + discover_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + service->start_handle = sys_cpu_to_le16(gatt_svc->start_handle); + service->end_handle = sys_cpu_to_le16(gatt_svc->end_handle); + service->uuid_length = uuid_length; + + if (uuid->u.type == BLE_UUID_TYPE_16) { + uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + memcpy(service->uuid, &u16, uuid_length); + } else { + memcpy(service->uuid, BLE_UUID128(uuid)->value, + uuid_length); + } + + gatt_buf.cnt++; + +free: + os_mbuf_free_chain(buf); + return rc; +} + +static void disc_all_prim_svcs(uint8_t *data, uint16_t len) +{ + struct ble_gap_conn_desc conn; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + if (ble_gattc_disc_all_svcs(conn.conn_handle, disc_prim_svcs_cb, + (void *) GATTC_DISC_ALL_PRIM_RP)) { + discover_destroy(); + status = BTP_STATUS_FAILED; + goto rsp; + } + +rsp: + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_PRIM_SVCS, + CONTROLLER_INDEX, status); +} + +static void disc_prim_uuid(uint8_t *data, uint16_t len) +{ + const struct gattc_disc_prim_uuid_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + ble_uuid_any_t uuid; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + if (ble_gattc_disc_svc_by_uuid(conn.conn_handle, + &uuid.u, disc_prim_svcs_cb, + (void *) GATTC_DISC_PRIM_UUID_RP)) { + discover_destroy(); + status = BTP_STATUS_FAILED; + goto rsp; + } + +rsp: + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_PRIM_UUID, CONTROLLER_INDEX, + status); +} + +static int find_included_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_svc *gatt_svc, void *arg) +{ + struct gattc_find_included_rp *rp; + struct gatt_included *included; + const ble_uuid_any_t *uuid; + int service_handle = (int) arg; + uint8_t uuid_length; + uint8_t err = (uint8_t) error->status; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; + + SYS_LOG_DBG(""); + + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + rp->status = err; + + SYS_LOG_DBG(""); + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->services_count = 0; + tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_FIND_INCLUDED_RP, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + if (error->status == BLE_HS_EDONE) { + rp->status = 0; + rp->services_count = gatt_buf.cnt; + os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); + tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_FIND_INCLUDED_RP, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + uuid = &gatt_svc->uuid; + uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); + + included = gatt_buf_reserve(sizeof(*included) + uuid_length); + if (!included) { + discover_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + included->included_handle = sys_cpu_to_le16(service_handle + 1 + + rp->services_count); + included->service.start_handle = sys_cpu_to_le16(gatt_svc->start_handle); + included->service.end_handle = sys_cpu_to_le16(gatt_svc->end_handle); + included->service.uuid_length = uuid_length; + + if (uuid->u.type == BLE_UUID_TYPE_16) { + uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + memcpy(included->service.uuid, &u16, uuid_length); + } else { + memcpy(included->service.uuid, BLE_UUID128(uuid)->value, + uuid_length); + } + + gatt_buf.cnt++; + +free: + os_mbuf_free_chain(buf); + return rc; +} + +static void find_included(uint8_t *data, uint16_t len) +{ + const struct gattc_find_included_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint16_t start_handle, end_handle; + int service_handle_arg; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + start_handle = sys_le16_to_cpu(cmd->start_handle); + end_handle = sys_le16_to_cpu(cmd->end_handle); + service_handle_arg = start_handle; + + if (ble_gattc_find_inc_svcs(conn.conn_handle, start_handle, end_handle, + find_included_cb, + (void *) service_handle_arg)) { + discover_destroy(); + status = BTP_STATUS_FAILED; + goto rsp; + } + +rsp: + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_FIND_INCLUDED, CONTROLLER_INDEX, + status); +} + +static int disc_chrc_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_chr *gatt_chr, void *arg) +{ + struct gattc_disc_chrc_rp *rp; + struct gatt_characteristic *chrc; + const ble_uuid_any_t *uuid; + uint8_t uuid_length; + uint8_t opcode = (uint8_t) (int) arg; + uint8_t err = (uint8_t) error->status; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; + + SYS_LOG_DBG(""); + if (ble_gap_conn_find(conn_handle, &conn)) { + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + rp->status = err; + + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->characteristics_count = 0; + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + if (error->status == BLE_HS_EDONE) { + rp->status = 0; + rp->characteristics_count = gatt_buf.cnt; + os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + uuid = &gatt_chr->uuid; + uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); + + chrc = gatt_buf_reserve(sizeof(*chrc) + uuid_length); + if (!chrc) { + discover_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + chrc->characteristic_handle = sys_cpu_to_le16(gatt_chr->def_handle); + chrc->properties = gatt_chr->properties; + chrc->value_handle = sys_cpu_to_le16(gatt_chr->val_handle); + chrc->uuid_length = uuid_length; + + if (uuid->u.type == BLE_UUID_TYPE_16) { + uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + memcpy(chrc->uuid, &u16, uuid_length); + } else { + memcpy(chrc->uuid, BLE_UUID128(uuid)->value, + uuid_length); + } + + gatt_buf.cnt++; +free: + os_mbuf_free_chain(buf); + return rc; +} + +static void disc_all_chrc(uint8_t *data, uint16_t len) +{ + const struct gattc_disc_all_chrc_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint16_t start_handle, end_handle; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + SYS_LOG_DBG("Conn find rsped"); + status = BTP_STATUS_FAILED; + goto rsp; + } + + start_handle = sys_le16_to_cpu(cmd->start_handle); + end_handle = sys_le16_to_cpu(cmd->end_handle); + + rc = ble_gattc_disc_all_chrs(conn.conn_handle, start_handle, end_handle, + disc_chrc_cb, (void *) GATTC_DISC_ALL_CHRC_RP); + if (rc) { + discover_destroy(); + status = BTP_STATUS_FAILED; + goto rsp; + } + +rsp: + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_CHRC, CONTROLLER_INDEX, + status); +} + +static void disc_chrc_uuid(uint8_t *data, uint16_t len) +{ + const struct gattc_disc_chrc_uuid_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint16_t start_handle, end_handle; + ble_uuid_any_t uuid; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + start_handle = sys_le16_to_cpu(cmd->start_handle); + end_handle = sys_le16_to_cpu(cmd->end_handle); + + rc = ble_gattc_disc_chrs_by_uuid(conn.conn_handle, start_handle, + end_handle, &uuid.u, disc_chrc_cb, + (void *) GATTC_DISC_CHRC_UUID_RP); + if (rc) { + discover_destroy(); + status = BTP_STATUS_FAILED; + goto rsp; + } + +rsp: + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_CHRC_UUID, CONTROLLER_INDEX, + status); +} + +static int disc_all_desc_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + uint16_t chr_val_handle, + const struct ble_gatt_dsc *gatt_dsc, + void *arg) +{ + struct gattc_disc_all_desc_rp *rp; + struct gatt_descriptor *dsc; + const ble_uuid_any_t *uuid; + uint8_t uuid_length; + uint8_t err = (uint8_t) error->status; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; + + SYS_LOG_DBG(""); + + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + rp->status = err; + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->descriptors_count = 0; + tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_DESC_RP, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + if (error->status == BLE_HS_EDONE) { + rp->status = 0; + rp->descriptors_count = gatt_buf.cnt; + os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); + tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_DESC_RP, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + uuid = &gatt_dsc->uuid; + uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); + + dsc = gatt_buf_reserve(sizeof(*dsc) + uuid_length); + if (!dsc) { + discover_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + dsc->descriptor_handle = sys_cpu_to_le16(gatt_dsc->handle); + dsc->uuid_length = uuid_length; + + if (uuid->u.type == BLE_UUID_TYPE_16) { + uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + memcpy(dsc->uuid, &u16, uuid_length); + } else { + memcpy(dsc->uuid, BLE_UUID128(uuid)->value, uuid_length); + } + + gatt_buf.cnt++; + +free: + os_mbuf_free_chain(buf); + return rc; +} + +static void disc_all_desc(uint8_t *data, uint16_t len) +{ + const struct gattc_disc_all_desc_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint16_t start_handle, end_handle; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + start_handle = sys_le16_to_cpu(cmd->start_handle) - 1; + end_handle = sys_le16_to_cpu(cmd->end_handle); + + rc = ble_gattc_disc_all_dscs(conn.conn_handle, start_handle, end_handle, + disc_all_desc_cb, (void *) GATTC_DISC_ALL_DESC); + + SYS_LOG_DBG("rc=%d", rc); + + if (rc) { + discover_destroy(); + status = BTP_STATUS_FAILED; + goto rsp; + } + +rsp: + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_DESC, CONTROLLER_INDEX, + status); +} + +static int read_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) +{ + struct gattc_read_rp *rp; + uint8_t opcode = (uint8_t) (int) arg; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; + + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + SYS_LOG_DBG("status=%d", error->status); + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->status = (uint8_t) BLE_HS_ATT_ERR(error->status); + rp->data_length = 0; + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + read_destroy(); + goto free; + } + + if (!gatt_buf_add(attr->om->om_data, attr->om->om_len)) { + read_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + rp->status = 0; + rp->data_length = attr->om->om_len; + os_mbuf_appendfrom(buf, attr->om, 0, os_mbuf_len(attr->om)); + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + read_destroy(); +free: + os_mbuf_free_chain(buf); + return rc; +} + +static void read(uint8_t *data, uint16_t len) +{ + const struct gattc_read_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + /* Clear buffer */ + read_destroy(); + + if (ble_gattc_read(conn.conn_handle, sys_le16_to_cpu(cmd->handle), + read_cb, (void *) GATTC_READ_RP)) { + read_destroy(); + status = BTP_STATUS_FAILED; + goto rsp; + } + +rsp: + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ, CONTROLLER_INDEX, + status); +} + +static int read_uuid_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) +{ + struct gattc_read_uuid_rp *rp; + struct gatt_read_uuid_chr *chr; + uint8_t opcode = (uint8_t) (int) arg; + uint8_t err = (uint8_t) error->status; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; + static uint16_t attr_len; + + SYS_LOG_DBG("status=%d", error->status); + + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + rp->status = err; + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->data_length = 0; + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + read_destroy(); + goto free; + } + + if (error->status == BLE_HS_EDONE) { + rp->data_length = gatt_buf.len; + rp->value_length = attr_len; + rp->status = 0; + os_mbuf_append(buf, gatt_buf.buf+1, gatt_buf.len-1); + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + read_destroy(); + goto free; + } + + if (error->status == 0) { + attr_len = attr->om->om_len; + } + + if (gatt_buf_add(attr->om->om_data, attr->om->om_len) == NULL) { + read_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + chr = gatt_buf_reserve(sizeof(*chr) + attr->om->om_len); + if (!chr) { + read_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + chr->handle = sys_cpu_to_be16(attr->handle); + memcpy(chr->data, attr->om->om_data, attr->om->om_len); + +free: + os_mbuf_free_chain(buf); + return rc; +} + +static void read_uuid(uint8_t *data, uint16_t len) +{ + const struct gattc_read_uuid_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + ble_uuid_any_t uuid; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + /* Clear buffer */ + read_destroy(); + + if (ble_gattc_read_by_uuid(conn.conn_handle, + sys_le16_to_cpu(cmd->start_handle), + sys_le16_to_cpu(cmd->end_handle), &uuid.u, + read_uuid_cb, (void *) GATTC_READ_UUID_RP)) { + read_destroy(); + status = BTP_STATUS_FAILED; + } + +rsp: + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ_UUID, CONTROLLER_INDEX, + status); +} + +static int read_long_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) +{ + struct gattc_read_rp *rp;; + uint8_t opcode = (uint8_t) (int) arg; + uint8_t err = (uint8_t) error->status; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; + + SYS_LOG_DBG("status=%d", error->status); + + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + rp->status = err; + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->data_length = 0; + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + read_destroy(); + goto free; + } + + if (error->status == BLE_HS_EDONE) { + rp->status = 0; + rp->data_length = gatt_buf.len; + os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + read_destroy(); + goto free; + } + + if (gatt_buf_add(attr->om->om_data, attr->om->om_len) == NULL) { + read_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + rp->data_length += attr->om->om_len; + +free: + os_mbuf_free_chain(buf); + return rc; +} + +static void read_long(uint8_t *data, uint16_t len) +{ + const struct gattc_read_long_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + /* Clear buffer */ + read_destroy(); + + if (ble_gattc_read_long(conn.conn_handle, + sys_le16_to_cpu(cmd->handle), + sys_le16_to_cpu(cmd->offset), + read_long_cb, (void *) GATTC_READ_LONG_RP)) { + read_destroy(); + status = BTP_STATUS_FAILED; + } + +rsp: + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ_LONG, CONTROLLER_INDEX, + status); +} + +static void read_multiple(uint8_t *data, uint16_t len) +{ + const struct gattc_read_multiple_cmd *cmd = (void *) data; + uint16_t handles[cmd->handles_count]; + struct ble_gap_conn_desc conn; + uint8_t status = BTP_STATUS_SUCCESS; + int rc, i; + + SYS_LOG_DBG(""); + + for (i = 0; i < ARRAY_SIZE(handles); i++) { + handles[i] = sys_le16_to_cpu(cmd->handles[i]); + } + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + /* Clear buffer */ + read_destroy(); + + if (ble_gattc_read_mult(conn.conn_handle, handles, + cmd->handles_count, read_cb, (void *) GATTC_READ_MULTIPLE_RP)) { + read_destroy(); + status = BTP_STATUS_FAILED; + } + +rsp: + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ_MULTIPLE, CONTROLLER_INDEX, + status); +} + +static void write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) +{ + const struct gattc_write_without_rsp_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + if (ble_gattc_write_no_rsp_flat(conn.conn_handle, + sys_le16_to_cpu(cmd->handle), cmd->data, + sys_le16_to_cpu(cmd->data_length))) { + status = BTP_STATUS_FAILED; + } + +rsp: + tester_rsp(BTP_SERVICE_ID_GATTC, op, CONTROLLER_INDEX, status); +} + +static int write_cb(uint16_t conn_handle, const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) +{ + struct gattc_write_rp *rp; + uint8_t err = (uint8_t) error->status; + uint8_t opcode = (uint8_t) (int) arg; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; + + SYS_LOG_DBG(""); + + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + rp->status = err; + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); +free: + os_mbuf_free_chain(buf); + return rc; +} + +static void write(uint8_t *data, uint16_t len) +{ + const struct gattc_write_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + if (ble_gattc_write_flat(conn.conn_handle, sys_le16_to_cpu(cmd->handle), + cmd->data, sys_le16_to_cpu(cmd->data_length), + write_cb, (void *) GATTC_WRITE_RP)) { + status = BTP_STATUS_FAILED; + } + +rsp: + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_WRITE, CONTROLLER_INDEX, + status); +} + +static void write_long(uint8_t *data, uint16_t len) +{ + const struct gattc_write_long_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + struct os_mbuf *om = NULL; + uint8_t status = BTP_STATUS_SUCCESS; + int rc = 0; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + goto fail; + } + + om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); + if (!om) { + SYS_LOG_ERR("Insufficient resources"); + status = BTP_STATUS_FAILED; + goto fail; + } + + rc = ble_gattc_write_long(conn.conn_handle, + sys_le16_to_cpu(cmd->handle), + sys_le16_to_cpu(cmd->offset), + om, write_cb, + (void *) GATTC_WRITE_LONG_RP); + if (rc) { + status = BTP_STATUS_FAILED; + } else { + goto rsp; + } + +fail: + SYS_LOG_ERR("Failed to send Write Long request, rc=%d", rc); + os_mbuf_free_chain(om); +rsp: + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_WRITE_LONG, CONTROLLER_INDEX, + status); +} + +static int reliable_write_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attrs, + uint8_t num_attrs, + void *arg) +{ + struct gattc_write_rp *rp; + uint8_t err = (uint8_t) error->status; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; + + SYS_LOG_DBG(""); + + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + rp->status = err; + tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_RELIABLE_WRITE_RP, + CONTROLLER_INDEX, buf); +free: + os_mbuf_free_chain(buf); + return rc; +} + +static void reliable_write(uint8_t *data, uint16_t len) +{ + const struct gattc_reliable_write_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + struct ble_gatt_attr attr; + struct os_mbuf *om = NULL; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto fail; + } + + om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); + /* This is required, because Nimble checks if + * the data is longer than offset + */ + if (os_mbuf_extend(om, sys_le16_to_cpu(cmd->offset) + 1) == NULL) { + status = BTP_STATUS_FAILED; + goto fail; + } + + attr.handle = sys_le16_to_cpu(cmd->handle); + attr.offset = sys_le16_to_cpu(cmd->offset); + attr.om = om; + + if (ble_gattc_write_reliable(conn.conn_handle, &attr, 1, + reliable_write_cb, NULL)) { + status = BTP_STATUS_FAILED; + goto fail; + } else { + goto rsp; + } + +fail: + os_mbuf_free_chain(om); +rsp: + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_WRITE_LONG, CONTROLLER_INDEX, + status); +} + +static int subscribe_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attrs, + void *arg) +{ + struct subscribe_rp *rp; + uint8_t err = (uint8_t) error->status; + uint8_t opcode = (uint8_t) (int) arg; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; + + SYS_LOG_DBG(""); + + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + rp->status = err; + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); +free: + os_mbuf_free_chain(buf); + return rc; +} + +static int enable_subscription(uint16_t conn_handle, uint16_t ccc_handle, + uint16_t value) +{ + uint32_t opcode; + + SYS_LOG_DBG(""); + + opcode = (uint32_t) (value == 0x0001 ? GATTC_CFG_NOTIFY_RP : GATTC_CFG_INDICATE_RP); + + if (ble_gattc_write_flat(conn_handle, ccc_handle, + &value, sizeof(value), subscribe_cb, (void *) opcode)) { + return -EINVAL; + } + + subscribe_params.ccc_handle = value; + + return 0; +} + +static int disable_subscription(uint16_t conn_handle, uint16_t ccc_handle) +{ + uint16_t value = 0x00; + uint32_t opcode; + + SYS_LOG_DBG(""); + + opcode = (uint32_t) (value == 0x0001 ? GATTC_CFG_NOTIFY_RP : GATTC_CFG_INDICATE_RP); + + /* Fail if CCC handle doesn't match */ + if (ccc_handle != subscribe_params.ccc_handle) { + SYS_LOG_ERR("CCC handle doesn't match"); + return -EINVAL; + } + + if (ble_gattc_write_flat(conn_handle, ccc_handle, + &value, sizeof(value), subscribe_cb, (void *) opcode)) { + return -EINVAL; + } + + subscribe_params.ccc_handle = 0; + return 0; +} + +static void config_subscription(uint8_t *data, uint16_t len, uint8_t op) +{ + const struct gattc_cfg_notify_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle); + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + if (cmd->enable) { + uint16_t value; + + if (op == GATTC_CFG_NOTIFY) { + value = 0x0001; + } else { + value = 0x0002; + } + + if (enable_subscription(conn.conn_handle, + ccc_handle, value) != 0) { + status = BTP_STATUS_FAILED; + goto rsp; + } + } else { + if (disable_subscription(conn.conn_handle, ccc_handle) < 0) { + status = BTP_STATUS_FAILED; + } else { + status = BTP_STATUS_SUCCESS; + } + } + +rsp: + SYS_LOG_DBG("Config subscription (op %u) status %u", op, status); + + tester_rsp(BTP_SERVICE_ID_GATTC, op, CONTROLLER_INDEX, status); +} + +int tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, + uint8_t indication, struct os_mbuf *om) +{ + struct gattc_notification_ev *ev; + struct ble_gap_conn_desc conn; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + + SYS_LOG_DBG(""); + + if (!subscribe_params.ccc_handle) { + goto fail; + } + + if (ble_gap_conn_find(conn_handle, &conn)) { + goto fail; + } + + net_buf_simple_init(buf, 0); + ev = net_buf_simple_add(buf, sizeof(*ev)); + + addr = &conn.peer_ota_addr; + + ev->address_type = addr->type; + memcpy(ev->address, addr->val, sizeof(ev->address)); + ev->type = (uint8_t) (indication ? 0x02 : 0x01); + ev->handle = sys_cpu_to_le16(attr_handle); + ev->data_length = sys_cpu_to_le16(os_mbuf_len(om)); + os_mbuf_appendfrom(buf, om, 0, os_mbuf_len(om)); + + tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_EV_NOTIFICATION_RXED, + CONTROLLER_INDEX, buf); + +fail: + os_mbuf_free_chain(buf); + return 0; +} + +static void supported_commands(uint8_t *data, uint16_t len) +{ + uint8_t cmds[3]; + struct gatt_read_supported_commands_rp *rp = (void *) cmds; + + SYS_LOG_DBG(""); + + memset(cmds, 0, sizeof(cmds)); + + tester_set_bit(cmds, GATTC_READ_SUPPORTED_COMMANDS); + tester_set_bit(cmds, GATTC_EXCHANGE_MTU); + tester_set_bit(cmds, GATTC_DISC_ALL_PRIM_SVCS); + tester_set_bit(cmds, GATTC_DISC_PRIM_UUID); + tester_set_bit(cmds, GATTC_FIND_INCLUDED); + tester_set_bit(cmds, GATTC_DISC_ALL_CHRC); + tester_set_bit(cmds, GATTC_DISC_CHRC_UUID); + tester_set_bit(cmds, GATTC_DISC_ALL_DESC); + tester_set_bit(cmds, GATTC_READ); + tester_set_bit(cmds, GATTC_READ_UUID); + tester_set_bit(cmds, GATTC_READ_LONG); + tester_set_bit(cmds, GATTC_READ_MULTIPLE); + tester_set_bit(cmds, GATTC_WRITE_WITHOUT_RSP); +#if 0 + tester_set_bit(cmds, GATTC_SIGNED_WRITE_WITHOUT_RSP); +#endif + tester_set_bit(cmds, GATTC_WRITE); + tester_set_bit(cmds, GATTC_WRITE_LONG); + tester_set_bit(cmds, GATTC_RELIABLE_WRITE); + tester_set_bit(cmds, GATTC_CFG_NOTIFY); + tester_set_bit(cmds, GATTC_CFG_INDICATE); + + tester_send(BTP_SERVICE_ID_GATTC, GATTC_READ_SUPPORTED_COMMANDS, + CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); +} + +void tester_handle_gattc(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len) +{ + switch (opcode) { + case GATTC_READ_SUPPORTED_COMMANDS: + supported_commands(data, len); + return; + case GATTC_EXCHANGE_MTU: + exchange_mtu(data, len); + return; + case GATTC_DISC_ALL_PRIM_SVCS: + disc_all_prim_svcs(data, len); + return; + case GATTC_DISC_PRIM_UUID: + disc_prim_uuid(data, len); + return; + case GATTC_FIND_INCLUDED: + find_included(data, len); + return; + case GATTC_DISC_ALL_CHRC: + disc_all_chrc(data, len); + return; + case GATTC_DISC_CHRC_UUID: + disc_chrc_uuid(data, len); + return; + case GATTC_DISC_ALL_DESC: + disc_all_desc(data, len); + return; + case GATTC_READ: + read(data, len); + return; + case GATTC_READ_UUID: + read_uuid(data, len); + return; + case GATTC_READ_LONG: + read_long(data, len); + return; + case GATTC_READ_MULTIPLE: + read_multiple(data, len); + return; + case GATTC_WRITE_WITHOUT_RSP: + write_without_rsp(data, len, opcode, false); + return; +#if 0 + case GATTC_SIGNED_WRITE_WITHOUT_RSP: + write_without_rsp(data, len, opcode, true); + return; +#endif + case GATTC_WRITE: + write(data, len); + return; + case GATTC_WRITE_LONG: + write_long(data, len); + return; + case GATTC_RELIABLE_WRITE: + reliable_write(data, len); + return; + case GATTC_CFG_NOTIFY: + case GATTC_CFG_INDICATE: + config_subscription(data, len, opcode); + return; + default: + tester_rsp(BTP_SERVICE_ID_GATTC, opcode, index, + BTP_STATUS_UNKNOWN_CMD); + return; + } +} \ No newline at end of file From cf3651fd585edc56ad4711f74686e788f097fc1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 3 Dec 2021 14:18:30 +0100 Subject: [PATCH 0376/1333] host/mesh: fix disconnect We should use connection descriptor from event, as connection no longer exists. --- nimble/host/mesh/src/pb_gatt_srv.c | 14 ++++---------- nimble/host/mesh/src/pb_gatt_srv.h | 2 +- nimble/host/mesh/src/proxy_srv.c | 14 +++++--------- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/nimble/host/mesh/src/pb_gatt_srv.c b/nimble/host/mesh/src/pb_gatt_srv.c index fb629f7185..046c942449 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.c +++ b/nimble/host/mesh/src/pb_gatt_srv.c @@ -159,15 +159,9 @@ void gatt_connected_pb_gatt(uint16_t conn_handle, uint8_t err) BT_DBG("conn %p err 0x%02x", (void *)conn, err); } -void gatt_disconnected_pb_gatt(uint16_t conn_handle, uint8_t reason) +void gatt_disconnected_pb_gatt(struct ble_gap_conn_desc conn, uint8_t reason) { - struct ble_gap_conn_desc info; - - struct ble_hs_conn *conn; - - conn = ble_hs_conn_find(conn_handle); - bt_conn_get_info(conn, &info); - if (info.role != BLE_GAP_ROLE_SLAVE || + if (conn.role != BLE_GAP_ROLE_SLAVE || !service_registered) { return; } @@ -177,9 +171,9 @@ void gatt_disconnected_pb_gatt(uint16_t conn_handle, uint8_t reason) cli = NULL; } - BT_DBG("conn %p reason 0x%02x", (void *)conn, reason); + BT_DBG("conn_handle %d reason 0x%02x", conn.conn_handle, reason); - bt_mesh_pb_gatt_close(conn_handle); + bt_mesh_pb_gatt_close(conn.conn_handle); if (bt_mesh_is_provisioned()) { (void)bt_mesh_pb_gatt_disable(); diff --git a/nimble/host/mesh/src/pb_gatt_srv.h b/nimble/host/mesh/src/pb_gatt_srv.h index a5ebce5283..d143392635 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.h +++ b/nimble/host/mesh/src/pb_gatt_srv.h @@ -14,7 +14,7 @@ int bt_mesh_pb_gatt_enable(void); int bt_mesh_pb_gatt_disable(void); int prov_ccc_write(uint16_t conn_handle, uint8_t type); -void gatt_disconnected_pb_gatt(uint16_t conn_handle, uint8_t err); +void gatt_disconnected_pb_gatt(struct ble_gap_conn_desc conn, uint8_t err); void gatt_connected_pb_gatt(uint16_t conn_handle, uint8_t err); void resolve_svc_handles(void); diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index 72ed3b55f7..f26a079c33 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -825,15 +825,11 @@ static void gatt_connected(uint16_t conn_handle) } } -static void gatt_disconnected(uint16_t conn_handle, uint8_t reason) +static void gatt_disconnected(struct ble_gap_conn_desc conn, uint8_t reason) { - struct ble_gap_conn_desc info; struct bt_mesh_proxy_client *client; - struct ble_hs_conn *conn; - conn = ble_hs_conn_find(conn_handle); - bt_conn_get_info(conn, &info); - if (info.role != BLE_GAP_ROLE_SLAVE) { + if (conn.role != BLE_GAP_ROLE_SLAVE) { return; } @@ -843,7 +839,7 @@ static void gatt_disconnected(uint16_t conn_handle, uint8_t reason) } conn_count--; - client = find_client(conn_handle); + client = find_client(conn.conn_handle); if (client->cli) { bt_mesh_proxy_role_cleanup(client->cli); client->cli = NULL; @@ -938,10 +934,10 @@ int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) (event->type == BLE_GAP_EVENT_ADV_COMPLETE)) { ble_mesh_handle_connect(event, arg); } else if (event->type == BLE_GAP_EVENT_DISCONNECT) { - gatt_disconnected(event->disconnect.conn.conn_handle, + gatt_disconnected(event->disconnect.conn, event->disconnect.reason); #if MYNEWT_VAL(BLE_MESH_PB_GATT) - gatt_disconnected_pb_gatt(event->disconnect.conn.conn_handle, + gatt_disconnected_pb_gatt(event->disconnect.conn, event->disconnect.reason); #endif } else if (event->type == BLE_GAP_EVENT_SUBSCRIBE) { From f2f24ad5a5bd5b5722f282594bc50d8fcbae61d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 16 Nov 2021 14:05:24 +0100 Subject: [PATCH 0377/1333] apps/bttester: make L2CAP listen response parameter consistent with btp Previously, in listen() we used command response parameter straight away. In fact, this parameter is not an error that shall be returned when peer creates L2CAP connection with IUT, but value defined in BTP spec. Now it's translated into CoC error code before passing to ble_l2cap_create_server() as tester_l2cap_event argument. --- apps/bttester/src/l2cap.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/apps/bttester/src/l2cap.c b/apps/bttester/src/l2cap.c index 27cc6a9a6e..7bfa53e7a9 100644 --- a/apps/bttester/src/l2cap.c +++ b/apps/bttester/src/l2cap.c @@ -561,6 +561,22 @@ l2cap_coc_err2hs_err(uint16_t coc_err) } } +static int +l2cap_btp_listen_err2coc_err(uint16_t coc_err) +{ + switch (coc_err) { + case 0x01: + return BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN; + case 0x02: + return BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR; + case 0x03: + return BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ; + case 0x04: + return BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC; + default: + return 0; + } +} static void listen(const uint8_t *data, uint16_t len) { @@ -575,6 +591,7 @@ static void listen(const uint8_t *data, uint16_t len) mtu = TESTER_COC_MTU; } + rsp = l2cap_btp_listen_err2coc_err(rsp); rsp = l2cap_coc_err2hs_err(rsp); /* TODO: Handle cmd->transport flag */ From 09466ab8105905388f5e800b722e4801de90560f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 20 Jul 2021 14:11:53 +0200 Subject: [PATCH 0378/1333] host/l2cap: disconnect if received packet is larger than MPS Peer sending packet larger than MPS is invalid, and should be met with L2CAP channel disconnection. This affects L2CAP/LE/CFC/BV-27-C --- nimble/host/src/ble_l2cap.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/nimble/host/src/ble_l2cap.c b/nimble/host/src/ble_l2cap.c index fb1a617613..810d07b3d7 100644 --- a/nimble/host/src/ble_l2cap.c +++ b/nimble/host/src/ble_l2cap.c @@ -388,6 +388,16 @@ ble_l2cap_rx(struct ble_hs_conn *conn, goto err; } + /* For CIDs from dynamic range we check if SDU size isn't larger than MPS */ + if (chan->dcid >= 0x0040 && chan->dcid <= 0x007F && l2cap_hdr.len > chan->my_coc_mps) { + /* Data exceeds MPS */ + BLE_HS_LOG(ERROR, "error: sdu_len > chan->my_coc_mps (%d>%d)\n", + l2cap_hdr.len, chan->my_coc_mps); + ble_l2cap_disconnect(chan); + rc = BLE_HS_EBADDATA; + goto err; + } + if (chan->rx_buf != NULL) { /* Previous data packet never completed. Discard old packet. */ ble_l2cap_remove_rx(conn, chan); From 33a5574444874880bc4907b521eeb96845a89412 Mon Sep 17 00:00:00 2001 From: Prasad Alatkar Date: Thu, 15 Jul 2021 15:13:01 +0530 Subject: [PATCH 0379/1333] nimble/host: Remove redundant check in connection latency * The `params->latency` is uint16_t and BLE_HCI_CONN_LATENCY_MIN is 0 which is why we can drop it. --- nimble/host/src/ble_gap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 621a88a0fc..7e650fd9a1 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -4659,8 +4659,7 @@ ble_gap_check_conn_params(uint8_t phy, const struct ble_gap_conn_params *params) } /* Check connection latency */ - if ((params->latency < BLE_HCI_CONN_LATENCY_MIN) || - (params->latency > BLE_HCI_CONN_LATENCY_MAX)) { + if (params->latency > BLE_HCI_CONN_LATENCY_MAX) { return BLE_ERR_INV_HCI_CMD_PARMS; } From 77ca03c3102d4a9523367dbc548ef7a9916b6605 Mon Sep 17 00:00:00 2001 From: fredster33 Date: Wed, 13 Apr 2022 03:50:44 -0700 Subject: [PATCH 0380/1333] Align logo, grammar updates (#960) Some grammar fixes in Readme.md --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 96c636634c..07a893aa85 100644 --- a/README.md +++ b/README.md @@ -19,22 +19,24 @@ # --> + Apache Mynewt + ## Overview Apache NimBLE is an open-source Bluetooth 5.1 stack (both Host & Controller) that completely replaces the proprietary SoftDevice on Nordic chipsets. It is part of [Apache Mynewt project](https://github.com/apache/mynewt-core). -Features highlight: - - Support for 251 byte packet size +Feature highlight: + - Support for 251 byte packet size. - Support for all 4 roles concurrently - Broadcaster, Observer, Peripheral and Central - Support for up to 32 simultaneous connections. - Legacy and SC (secure connections) SMP support (pairing and bonding). - Advertising Extensions. - Periodic Advertising. - - Coded (aka Long Range) and 2M PHYs. + - Coded (a.k.a. Long Range) and 2M PHYs. - Bluetooth Mesh. ## Supported hardware From ebaeb57058ece3783b6098d6bd8906e4f0ae2311 Mon Sep 17 00:00:00 2001 From: Prasad Alatkar Date: Wed, 10 Mar 2021 20:02:14 +0530 Subject: [PATCH 0381/1333] nimble/host: Fix error return in `ble_store_util_bonded_peers` - When `max_peer`(input parameter) is less than stored bonds, `ble_store_util_bonded_peers` returns `BLE_HS_ENOMEM` status code unnecessarily. It results in non deletion of oldest bond when `ble_gap_unpair_oldest_peer` is called. --- nimble/host/src/ble_store_util.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/nimble/host/src/ble_store_util.c b/nimble/host/src/ble_store_util.c index 7de482721b..508fa00db2 100644 --- a/nimble/host/src/ble_store_util.c +++ b/nimble/host/src/ble_store_util.c @@ -91,9 +91,6 @@ ble_store_util_bonded_peers(ble_addr_t *out_peer_id_addrs, int *out_num_peers, if (rc != 0) { return rc; } - if (set.status != 0) { - return set.status; - } *out_num_peers = set.num_peers; return 0; From 327d9326e6b8da0f240de4262956d274f6b95b55 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Mon, 11 Oct 2021 10:36:38 +1100 Subject: [PATCH 0382/1333] nimble/sm: Ensure bonded flag is set in sm_result on new pair & bond. The bonded flag was not set on new connection in ble_gap_enc_event() --- nimble/host/src/ble_sm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index c63af4087c..5489551ae1 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -2041,14 +2041,16 @@ ble_sm_key_exch_success(struct ble_sm_proc *proc, struct ble_sm_result *res) /* The procedure is now complete. Update connection bonded state and * terminate procedure. */ + int bonded = !!(proc->flags & BLE_SM_PROC_F_BONDING); ble_sm_update_sec_state(proc->conn_handle, 1, !!(proc->flags & BLE_SM_PROC_F_AUTHENTICATED), - !!(proc->flags & BLE_SM_PROC_F_BONDING), + bonded, proc->key_size); proc->state = BLE_SM_PROC_STATE_NONE; res->app_status = 0; res->enc_cb = 1; + res->bonded = bonded; } static void From d2d29154bf267425087dd38e611d78f66bf7b91f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 13 Apr 2022 10:43:57 +0200 Subject: [PATCH 0383/1333] nimble/ll: Move defunct and deprecated settings to separate file --- nimble/controller/syscfg.defunct.yml | 78 ++++++++++++++++++++++++++++ nimble/controller/syscfg.yml | 62 +--------------------- 2 files changed, 80 insertions(+), 60 deletions(-) create mode 100644 nimble/controller/syscfg.defunct.yml diff --git a/nimble/controller/syscfg.defunct.yml b/nimble/controller/syscfg.defunct.yml new file mode 100644 index 0000000000..da338458a4 --- /dev/null +++ b/nimble/controller/syscfg.defunct.yml @@ -0,0 +1,78 @@ +# 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. +# + +syscfg.defs: +# deprecated settings (to be defunct/removed eventually) + BLE_LL_DIRECT_TEST_MODE: + description: use BLE_LL_DTM instead + value: 0 + deprecated: 1 + BLE_XTAL_SETTLE_TIME: + description: use BLE_LL_RFMGMT_ENABLE_TIME instead + value: 0 + deprecated: 1 + BLE_LL_OUR_SCA: + description: use BLE_LL_SCA instead + value: 60 + deprecated: 1 + BLE_LL_VND_EVENT_ON_ASSERT: + description: use BLE_LL_HCI_VS_EVENT_ON_ASSERT + value: 0 + deprecated: 1 + BLE_PUBLIC_DEV_ADDR: + description: use BLE_LL_PUBLIC_DEV_ADDR + value: "(uint8_t[6]){0x00, 0x00, 0x00, 0x00, 0x00, 0x00}" + deprecated: 1 + BLE_LL_EXT_ADV_AUX_PTR_CNT: + description: use BLE_LL_SCAN_AUX_SEGMENT_CNT + value: 0 + deprecated: 1 + +# defunct settings (to be removed eventually) + BLE_DEVICE: + description: Superseded by BLE_CONTROLLER + value: 1 + defunct: 1 + BLE_LP_CLOCK: + description: Superseded by BLE_CONTROLLER + value: 1 + defunct: 1 + BLE_NUM_COMP_PKT_RATE: + description: Superseded by BLE_LL_NUM_COMP_PKT_ITVL_MS + value: '(2 * OS_TICKS_PER_SEC)' + defunct: 1 + BLE_LL_MASTER_SCA: + description: use BLE_LL_SCA instead + value: 4 + defunct: 1 + BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG: + description: Superseded by BLE_LL_CFG_FEAT_PERIPH_INIT_FEAT_XCHG + value: 0 + defaunt: 1 + BLE_LL_STRICT_CONN_SCHEDULING: + description: Superseded by BLE_LL_CONN_STRICT_SCHED + value: 0 + defunct: 1 + BLE_LL_ADD_STRICT_SCHED_PERIODS: + description: Superseded by BLE_LL_CONN_STRICT_SCHED + value: 0 + defunct: 1 + BLE_LL_USECS_PER_PERIOD: + description: Superseded by BLE_LL_CONN_STRICT_SCHED + value: 0 + defunct: 1 diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 1cd433553e..af41573bb6 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -490,66 +490,6 @@ syscfg.defs: range: 1..257 value: 32 -# deprecated settings (to be defunct/removed eventually) - BLE_LL_DIRECT_TEST_MODE: - description: use BLE_LL_DTM instead - value: 0 - deprecated: 1 - BLE_XTAL_SETTLE_TIME: - description: use BLE_LL_RFMGMT_ENABLE_TIME instead - value: 0 - deprecated: 1 - BLE_LL_OUR_SCA: - description: use BLE_LL_SCA instead - value: 60 - deprecated: 1 - BLE_LL_VND_EVENT_ON_ASSERT: - description: use BLE_LL_HCI_VS_EVENT_ON_ASSERT - value: 0 - deprecated: 1 - BLE_PUBLIC_DEV_ADDR: - description: use BLE_LL_PUBLIC_DEV_ADDR - value: "(uint8_t[6]){0x00, 0x00, 0x00, 0x00, 0x00, 0x00}" - deprecated: 1 - BLE_LL_EXT_ADV_AUX_PTR_CNT: - description: use BLE_LL_SCAN_AUX_SEGMENT_CNT - value: 0 - deprecated: 1 - -# defunct settings (to be removed eventually) - BLE_DEVICE: - description: Superseded by BLE_CONTROLLER - value: 1 - defunct: 1 - BLE_LP_CLOCK: - description: Superseded by BLE_CONTROLLER - value: 1 - defunct: 1 - BLE_NUM_COMP_PKT_RATE: - description: Superseded by BLE_LL_NUM_COMP_PKT_ITVL_MS - value: '(2 * OS_TICKS_PER_SEC)' - defunct: 1 - BLE_LL_MASTER_SCA: - description: use BLE_LL_SCA instead - value: 4 - defunct: 1 - BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG: - description: Superseded by BLE_LL_CFG_FEAT_PERIPH_INIT_FEAT_XCHG - value: 0 - defaunt: 1 - BLE_LL_STRICT_CONN_SCHEDULING: - description: Superseded by BLE_LL_CONN_STRICT_SCHED - value: 0 - defunct: 1 - BLE_LL_ADD_STRICT_SCHED_PERIODS: - description: Superseded by BLE_LL_CONN_STRICT_SCHED - value: 0 - defunct: 1 - BLE_LL_USECS_PER_PERIOD: - description: Superseded by BLE_LL_CONN_STRICT_SCHED - value: 0 - defunct: 1 - syscfg.vals.BLE_LL_CFG_FEAT_LL_EXT_ADV: BLE_LL_CFG_FEAT_LE_CSA2: 1 BLE_HW_WHITELIST_ENABLE: 0 @@ -567,5 +507,7 @@ syscfg.restrictions: - BLE_LL_LNA == 0 || BLE_LL_LNA_GPIO >= 0 $import: + # defunct and deprecated settings + - "@apache-mynewt-nimble/nimble/controller/syscfg.defunct.yml" # "Here be dragons" settings - "@apache-mynewt-nimble/nimble/controller/syscfg.hbd.yml" From da078e51ed1647e691b21f8e6461bd0ad3092745 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 13 Apr 2022 10:45:59 +0200 Subject: [PATCH 0384/1333] nimble/ll: Fix syscfg definition for css --- nimble/controller/syscfg.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index af41573bb6..6ff7bdb32e 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -393,8 +393,11 @@ syscfg.defs: Enables support for vendor-specific HCI commands. value: MYNEWT_VAL(BLE_HCI_VS) BLE_LL_HCI_VS_CONN_STRICT_SCHED: - description: xxx + description: > + Enable HCI commands to control connection strict scheduling. value: 0 + restrictions: + - BLE_LL_HCI_VS if 1 BLE_LL_HCI_VS_EVENT_ON_ASSERT: description: > From 3cc02b2b31bdcd69d1acfce1f375a0160fc79516 Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Mon, 11 Apr 2022 08:22:44 +0200 Subject: [PATCH 0385/1333] apps/btshell: Fix peer_addr_type argument parsing The cmd parser expected a variable named peer_type instead of peer_addr_type. --- apps/btshell/src/cmd.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index 6cb2713518..69a3095a7e 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -103,24 +103,27 @@ parse_dev_addr(const char *prefix, const struct kv_pair *addr_types, if (!prefix) { name[0] = '\0'; } else { - written = snprintf(name, sizeof(name) - 1, "%s", prefix); + written = snprintf(name, sizeof(name), "%s", prefix); if (written >= sizeof(name) || written < 0) { return EINVAL; } } - written = snprintf(name + written, sizeof(name) - written - 1, "%s", "addr"); - if (written >= sizeof(name) || written < 0) { + rc = snprintf(name + written, sizeof(name) - written, "%s", "addr"); + if (rc >= sizeof(name) - written || rc < 0) { return EINVAL; } + written += rc; + rc = parse_arg_addr(name, addr); if (rc == ENOENT) { /* not found */ return rc; } else if (rc == EAGAIN) { /* address found, but no type provided */ - written = snprintf(name + written, sizeof(name) - written - 1, "%s", "_type"); - if (written >= sizeof(name) || written < 0) { + rc = written; + written = snprintf(name + written, sizeof(name) - written, "%s", "_type"); + if (written >= sizeof(name) - rc || written < 0) { return EINVAL; } addr->type = parse_arg_kv(name, addr_types, &rc); @@ -134,8 +137,9 @@ parse_dev_addr(const char *prefix, const struct kv_pair *addr_types, return rc; } else { /* full address found, but let's just make sure there is no type arg */ + rc = written; written = snprintf(name + written, sizeof(name) - written, "%s", "_type"); - if (written >= sizeof(name) || written < 0) { + if (written >= sizeof(name) - rc || written < 0) { return EINVAL; } if (parse_arg_extract(name)) { From 3c561218daacf06c30d0a726978c4105ac2c3a22 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 14 Apr 2022 13:55:39 +0200 Subject: [PATCH 0386/1333] apps/btshell: Add scan filtering based on device name This allows to specify name prefix that is used to filter out devices when scanning. Useful in busy environment. --- apps/btshell/src/btshell.h | 4 ++++ apps/btshell/src/cmd.c | 14 ++++++++++++++ apps/btshell/src/main.c | 22 ++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h index 7c978221c6..f52d65f5cd 100644 --- a/apps/btshell/src/btshell.h +++ b/apps/btshell/src/btshell.h @@ -83,10 +83,14 @@ struct btshell_conn { struct btshell_l2cap_coc_list coc_list; }; +#define NAME_FILTER_LEN_MAX 20 + struct btshell_scan_opts { uint16_t limit; uint8_t ignore_legacy:1; uint8_t periodic_only:1; + uint8_t name_filter_len; + char name_filter[NAME_FILTER_LEN_MAX]; }; extern struct btshell_conn btshell_conns[MYNEWT_VAL(BLE_MAX_CONNECTIONS)]; diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index 69a3095a7e..ddb76c8233 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -1107,11 +1107,14 @@ static const struct shell_cmd_help disconnect_help = { static struct btshell_scan_opts g_scan_opts = { .limit = UINT16_MAX, .ignore_legacy = 0, + .periodic_only = 0, + .name_filter_len = 0, }; static int cmd_set_scan_opts(int argc, char **argv) { + char *name_filter; int rc; rc = parse_arg_all(argc - 1, argv + 1); @@ -1137,6 +1140,16 @@ cmd_set_scan_opts(int argc, char **argv) return rc; } + name_filter = parse_arg_extract("name_filter"); + if (name_filter) { + strncpy(g_scan_opts.name_filter, name_filter, NAME_FILTER_LEN_MAX); + g_scan_opts.name_filter[NAME_FILTER_LEN_MAX - 1] = '\0'; + } else { + g_scan_opts.name_filter[0] = '\0'; + } + + g_scan_opts.name_filter_len = strlen(g_scan_opts.name_filter); + return rc; } @@ -1145,6 +1158,7 @@ static const struct shell_param set_scan_opts_params[] = { {"decode_limit", "usage: =[0-UINT16_MAX], default: UINT16_MAX"}, {"ignore_legacy", "usage: =[0-1], default: 0"}, {"periodic_only", "usage: =[0-1], default: 0"}, + {"name_filter", "usage: =name, default: {none}"}, {NULL, NULL} }; diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index e6f2f565df..cc69e5d157 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -963,9 +963,31 @@ btshell_decode_adv_data(const uint8_t *adv_data, uint8_t adv_data_len, void *arg static void btshell_decode_event_type(struct ble_gap_ext_disc_desc *desc, void *arg) { + const struct ble_hs_adv_field *ad_name = NULL; struct btshell_scan_opts *scan_opts = arg; uint8_t directed = 0; + if (scan_opts && scan_opts->name_filter_len) { + if (ble_hs_adv_find_field(BLE_HS_ADV_TYPE_COMP_NAME, desc->data, + desc->length_data, &ad_name)) { + ble_hs_adv_find_field(BLE_HS_ADV_TYPE_INCOMP_NAME, desc->data, + desc->length_data, &ad_name); + } + + if (!ad_name) { + return; + } + + if (ad_name->length < scan_opts->name_filter_len) { + return; + } + + if (strncasecmp(scan_opts->name_filter, (const char *)ad_name->value, + scan_opts->name_filter_len)) { + return; + } + } + if (desc->props & BLE_HCI_ADV_LEGACY_MASK) { if (scan_opts && scan_opts->ignore_legacy) { return; From 5d9571fa0d374b31fc9facdde5b7bd36d9e99fd4 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 15 Apr 2022 13:19:07 +0200 Subject: [PATCH 0387/1333] nimble/ll: Fix chanmap initialization --- nimble/controller/src/ble_ll.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 185fb58319..23b105fa72 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1642,7 +1642,8 @@ ble_ll_reset(void) /* Enable all channels in channel map */ g_ble_ll_data.chan_map_num_used = BLE_PHY_NUM_DATA_CHANS; - memset(g_ble_ll_data.chan_map, 0xff, BLE_LL_CHAN_MAP_LEN); + memset(g_ble_ll_data.chan_map, 0xff, BLE_LL_CHAN_MAP_LEN - 1); + g_ble_ll_data.chan_map[4] = 0x1f; #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Reset connection module */ From 1fb4475bea9bd8159cece77eeb28be57c9a7c6bb Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 16 Apr 2022 11:46:37 +0200 Subject: [PATCH 0388/1333] nimble/ll: Fix AUX_CONNECT_RSP verification This handles properly the case where AdvA is an identity address in advertising, but an RPA is used in AUX_CONNECT_RSP. --- nimble/controller/src/ble_ll_scan_aux.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index ce2ac07285..e3b94822f2 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -1517,23 +1517,22 @@ ble_ll_scan_aux_check_connect_rsp(uint8_t *rxbuf, targeta_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_RXADD_RAND); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - /* If AdvA was initially resolved, we need to check if current AdvA also - * resolved with the same IRK since it may have changes due to RPA timeout. - * Otherwise it shall be the same as in AUX_CONNECT_REQ. + /* If we have IRK for peer and AdvA is an RPA, we need to check if current + * RPA resolves using that IRK. This is to verify AdvA in case RPS changed + * due to timeout or AdvA in advertising was an identity address but is an + * RPA in AUX_CONNECT_RSP. + * Otherwise, it shall be the same as in AUX_CONNECT_REQ. */ - if (addrd->adva_resolved) { - if (!adva_type) { - return -1; - } - - BLE_LL_ASSERT(addrd->rpa_index >= 0); + if ((addrd->rpa_index >= 0) && ble_ll_is_rpa(adva, adva_type)) { rl = &g_ble_ll_resolv_list[addrd->rpa_index]; if (!ble_ll_resolv_rpa(adva, rl->rl_peer_irk)) { return -1; } + addrd->adva_resolved = 1; addrd->adva = adva; + addrd->adva_type = adva_type; } else if ((adva_type != !!(pdu_data->hdr_byte & BLE_ADV_PDU_HDR_RXADD_MASK)) || (memcmp(adva, pdu_data->adva, 6) != 0)) { From f8f10ab96abb31da4055f57c9b28349183f28deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 17 Nov 2021 12:32:51 +0100 Subject: [PATCH 0389/1333] apps/bttester: add option to connect single ECFC channel BTP specification was extended and we can decide weather or not connect ECFC channel by specifying it in 'option' command argument. This allows to connect single ECFC channel. --- apps/bttester/src/bttester.h | 3 +++ apps/bttester/src/l2cap.c | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/bttester/src/bttester.h b/apps/bttester/src/bttester.h index d37939dc24..767d9fffbf 100644 --- a/apps/bttester/src/bttester.h +++ b/apps/bttester/src/bttester.h @@ -754,6 +754,8 @@ struct l2cap_read_supported_commands_rp { uint8_t data[0]; } __packed; +#define L2CAP_CONNECT_OPT_ECFC 0x01 + #define L2CAP_CONNECT 0x02 struct l2cap_connect_cmd { uint8_t address_type; @@ -761,6 +763,7 @@ struct l2cap_connect_cmd { uint16_t psm; uint16_t mtu; uint8_t num; + uint8_t options; } __packed; struct l2cap_connect_rp { diff --git a/apps/bttester/src/l2cap.c b/apps/bttester/src/l2cap.c index 7bfa53e7a9..41a51d81bb 100644 --- a/apps/bttester/src/l2cap.c +++ b/apps/bttester/src/l2cap.c @@ -397,6 +397,7 @@ static void connect(uint8_t *data, uint16_t len) uint16_t mtu = htole16(cmd->mtu); int rc; int i, j; + bool ecfc = cmd->options & L2CAP_CONNECT_OPT_ECFC; SYS_LOG_DBG("connect: type: %d addr: %s", addr->type, bt_hex(addr->val, 6)); @@ -439,11 +440,11 @@ static void connect(uint8_t *data, uint16_t len) } } - if (cmd->num == 1) { + if (cmd->num == 1 && !ecfc) { rc = ble_l2cap_connect(desc.conn_handle, htole16(cmd->psm), mtu, sdu_rx[0], tester_l2cap_event, NULL); - } else if (cmd->num > 1) { + } else if (ecfc) { rc = ble_l2cap_enhanced_connect(desc.conn_handle, htole16(cmd->psm), mtu, cmd->num, sdu_rx, From 02bb32fd1f659e31075e6dbcf83ec165f715256c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 17 Nov 2021 13:24:56 +0100 Subject: [PATCH 0390/1333] apps/bttester: odd option to hold L2CAP credist and give back on command L2CAP/ECFC/BI-02-C requires IUT to hold credits and give them back when asked to do so. Let's use option defined in BTP to set manual credit give-back procedure when L2CAP connection is created. --- apps/bttester/src/bttester.h | 6 +++++ apps/bttester/src/l2cap.c | 43 +++++++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/apps/bttester/src/bttester.h b/apps/bttester/src/bttester.h index 767d9fffbf..641db8bd89 100644 --- a/apps/bttester/src/bttester.h +++ b/apps/bttester/src/bttester.h @@ -755,6 +755,7 @@ struct l2cap_read_supported_commands_rp { } __packed; #define L2CAP_CONNECT_OPT_ECFC 0x01 +#define L2CAP_CONNECT_OPT_HOLD_CREDIT 0x02 #define L2CAP_CONNECT 0x02 struct l2cap_connect_cmd { @@ -809,6 +810,11 @@ struct l2cap_reconfigure_cmd { uint8_t idxs[]; } __packed; +#define L2CAP_CREDITS 0x08 +struct l2cap_credits_cmd { + uint8_t chan_id; +} __packed; + /* events */ #define L2CAP_EV_CONNECTION_REQ 0x80 struct l2cap_connection_req_ev { diff --git a/apps/bttester/src/l2cap.c b/apps/bttester/src/l2cap.c index 41a51d81bb..7890e7cced 100644 --- a/apps/bttester/src/l2cap.c +++ b/apps/bttester/src/l2cap.c @@ -48,6 +48,7 @@ static os_membuf_t tester_sdu_coc_mem[ struct os_mbuf_pool sdu_os_mbuf_pool; static struct os_mempool sdu_coc_mbuf_mempool; +static bool hold_credit = false; static struct channel { uint8_t chan_id; /* Internal number that identifies L2CAP channel. */ @@ -105,10 +106,13 @@ tester_l2cap_coc_recv(struct ble_l2cap_chan *chan, struct os_mbuf *sdu) (uint32_t) chan, OS_MBUF_PKTLEN(sdu)); os_mbuf_free_chain(sdu); - sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); - assert(sdu != NULL); + if (!hold_credit) { + sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); + assert(sdu != NULL); - ble_l2cap_recv_ready(chan, sdu); + + ble_l2cap_recv_ready(chan, sdu); + } } static void recv_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, @@ -398,6 +402,7 @@ static void connect(uint8_t *data, uint16_t len) int rc; int i, j; bool ecfc = cmd->options & L2CAP_CONNECT_OPT_ECFC; + hold_credit = cmd->options & L2CAP_CONNECT_OPT_HOLD_CREDIT; SYS_LOG_DBG("connect: type: %d addr: %s", addr->type, bt_hex(addr->val, 6)); @@ -611,6 +616,35 @@ static void listen(const uint8_t *data, uint16_t len) BTP_STATUS_FAILED); } +static void credits(uint8_t *data, uint16_t len) +{ + const struct l2cap_credits_cmd *cmd = (void *)data; + struct os_mbuf *sdu; + int rc; + + struct channel *channel = get_channel(cmd->chan_id); + if (channel == NULL) { + goto fail; + } + + sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); + if (sdu == NULL) { + os_mbuf_free_chain(sdu); + goto fail; + } + + rc = ble_l2cap_recv_ready(channel->chan, sdu); + if (rc != 0) { + goto fail; + } + tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_CREDITS, CONTROLLER_INDEX, + BTP_STATUS_SUCCESS); + return; +fail: + tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_CREDITS, CONTROLLER_INDEX, + BTP_STATUS_FAILED); +} + static void reconfigure(const uint8_t *data, uint16_t len) { const struct l2cap_reconfigure_cmd *cmd = (void *) data; @@ -696,6 +730,9 @@ void tester_handle_l2cap(uint8_t opcode, uint8_t index, uint8_t *data, case L2CAP_RECONFIGURE: reconfigure(data, len); return; + case L2CAP_CREDITS: + credits(data, len); + return; default: tester_rsp(BTP_SERVICE_ID_L2CAP, opcode, index, BTP_STATUS_UNKNOWN_CMD); From 7ee72efb48ba4232cfd766da0b6a007c5061f806 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Thu, 7 Apr 2022 15:03:46 +0530 Subject: [PATCH 0391/1333] nimble/host: Add HCI commands / events for LE Power control --- nimble/host/include/host/ble_gap.h | 126 ++++++++++++++ nimble/host/src/ble_gap.c | 155 ++++++++++++++++++ nimble/host/src/ble_gap_priv.h | 5 + nimble/host/src/ble_hs_hci_evt.c | 38 +++++ nimble/include/nimble/hci_common.h | 63 +++++++ nimble/syscfg.yml | 5 + .../examples/linux/include/syscfg/syscfg.h | 4 + .../linux_blemesh/include/syscfg/syscfg.h | 4 + .../examples/nuttx/include/syscfg/syscfg.h | 4 + porting/nimble/include/syscfg/syscfg.h | 4 + porting/npl/riot/include/syscfg/syscfg.h | 4 + 11 files changed, 412 insertions(+) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index 63ae900da5..d27b7f82cb 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -135,6 +135,8 @@ struct hci_conn_update; #define BLE_GAP_EVENT_PERIODIC_SYNC_LOST 22 #define BLE_GAP_EVENT_SCAN_REQ_RCVD 23 #define BLE_GAP_EVENT_PERIODIC_TRANSFER 24 +#define BLE_GAP_EVENT_PATHLOSS_THRESHOLD 25 +#define BLE_GAP_EVENT_TRANSMIT_POWER 26 /*** Reason codes for the subscribe GAP event. */ @@ -973,6 +975,54 @@ struct ble_gap_event { uint8_t adv_clk_accuracy; } periodic_transfer; #endif + +#if MYNEWT_VAL(BLE_POWER_CONTROL) + /** + * Represents a change in either local transmit power or remote transmit + * power. Valid for the following event types: + * o BLE_GAP_EVENT_PATHLOSS_THRESHOLD + */ + + struct { + /** Connection handle */ + uint16_t conn_handle; + + /** Current Path Loss */ + uint8_t current_path_loss; + + /** Entered Zone */ + uint8_t zone_entered; + } pathloss_threshold; + + /** + * Represents crossing of path loss threshold set via LE Set Path Loss + * Reporting Parameter command. Valid for the following event types: + * o BLE_GAP_EVENT_TRANSMIT_POWER + */ + + struct { + /** BLE_ERR_SUCCESS on success or error code on failure */ + uint8_t status; + + /** Connection Handle */ + uint16_t conn_handle; + + /** Reason indicating why event was sent */ + uint8_t reason; + + /** Advertising PHY */ + uint8_t phy; + + /** Transmit power Level */ + uint8_t transmit_power_level; + + /** Transmit Power Level Flag */ + uint8_t transmit_power_level_flag; + + /** Delta indicating change in transmit Power Level */ + uint8_t delta; + } transmit_power; +#endif }; }; @@ -2097,6 +2147,82 @@ int ble_gap_event_listener_register(struct ble_gap_event_listener *listener, */ int ble_gap_event_listener_unregister(struct ble_gap_event_listener *listener); +#if MYNEWT_VAL(BLE_POWER_CONTROL) +/** + * Enable Set Path Loss Reporting. + * + * @param conn_handle Connection handle + * @params enable 1: Enable + * 0: Disable + * + * @return 0 on success; nonzero on failure. + */ + +int ble_gap_set_path_loss_reporting_enable(uint16_t conn_handle, uint8_t enable); + +/** + * Enable Reporting of Transmit Power + * + * @param conn_handle Connection handle + * @params local_enable 1: Enable local transmit power reports + * 0: Disable local transmit power reports + * + * @params remote_enable 1: Enable remote transmit power reports + * 0: Disable remote transmit power reports + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_set_transmit_power_reporting_enable(uint16_t conn_handle, + uint8_t local_enable, + uint8_t remote_enable); + +/** + * LE Enhanced Read Transmit Power Level + * + * @param conn_handle Connection handle + * @params phy Advertising Phy + * + * @params status 0 on success; nonzero on failure. + * @params conn_handle Connection handle + * @params phy Advertising Phy + * + * @params curr_tx_power_level Current trasnmit Power Level + * + * @params mx_tx_power_level Maximum transmit power level + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_enh_read_transmit_power_level(uint16_t conn_handle, uint8_t phy, + uint8_t *out_status, uint8_t *out_phy, + uint8_t *out_curr_tx_power_level, + uint8_t *out_max_tx_power_level); + +/** + * Read Remote Transmit Power Level + * + * @param conn_handle Connection handle + * @params phy Advertising Phy + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_read_remote_transmit_power_level(uint16_t conn_handle, uint8_t phy); + +/** + * Set Path Loss Reproting Param + * + * @param conn_handle Connection handle + * @params high_threshold High Threshold value for path loss + * @params high_hysteresis Hysteresis value for high threshold + * @params low_threshold Low Threshold value for path loss + * @params low_hysteresis Hysteresis value for low threshold + * @params min_time_spent Minimum time controller observes the path loss + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_set_path_loss_reporting_param(uint16_t conn_handle, uint8_t high_threshold, + uint8_t high_hysteresis, uint8_t low_threshold, + uint8_t low_hysteresis, uint16_t min_time_spent); +#endif #ifdef __cplusplus } #endif diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 7e650fd9a1..113a972d64 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -1641,6 +1641,42 @@ ble_gap_rx_periodic_adv_sync_lost(const struct ble_hci_ev_le_subev_periodic_adv_ } #endif +#if MYNEWT_VAL(BLE_POWER_CONTROL) +void +ble_gap_rx_le_pathloss_threshold(const struct ble_hci_ev_le_subev_path_loss_threshold *ev) +{ + struct ble_gap_event event; + + memset(&event, 0, sizeof event); + + event.type = BLE_GAP_EVENT_PATHLOSS_THRESHOLD; + event.pathloss_threshold.conn_handle = le16toh(ev->conn_handle); + event.pathloss_threshold.current_path_loss = ev->current_path_loss; + event.pathloss_threshold.zone_entered = ev->zone_entered; + + ble_gap_event_listener_call(&event); +} + +void +ble_gap_rx_transmit_power_report(const struct ble_hci_ev_le_subev_transmit_power_report *ev) +{ + struct ble_gap_event event; + + memset(&event, 0, sizeof event); + + event.type = BLE_GAP_EVENT_TRANSMIT_POWER; + event.transmit_power.status = ev->status; + event.transmit_power.conn_handle = le16toh(ev->conn_handle); + event.transmit_power.reason = ev->reason; + event.transmit_power.phy = ev->phy; + event.transmit_power.transmit_power_level = ev->transmit_power_level; + event.transmit_power.transmit_power_level_flag = ev->transmit_power_level_flag; + event.transmit_power.delta = ev->delta; + + ble_gap_event_listener_call(&event); +} +#endif + #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) static int periodic_adv_transfer_disable(uint16_t conn_handle) @@ -6213,3 +6249,122 @@ ble_gap_init(void) err: return rc; } + +int +ble_gap_enh_read_transmit_power_level(uint16_t conn_handle, uint8_t phy, uint8_t *out_status, uint8_t *out_phy , + uint8_t *out_curr_tx_power_level, uint8_t *out_max_tx_power_level) + +{ +#if MYNEWT_VAL(BLE_POWER_CONTROL) + struct ble_hci_le_enh_read_transmit_power_level_cp cmd; + struct ble_hci_le_enh_read_transmit_power_level_rp rsp; + uint16_t opcode; + int rc; + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_ENH_READ_TRANSMIT_POWER_LEVEL); + + cmd.conn_handle = htole16(conn_handle); + cmd.phy = phy; + + rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), &rsp, sizeof(rsp)); + + if (rc!=0) { + return rc; + } + + *out_status = rsp.status; + *out_phy = rsp.phy; + *out_curr_tx_power_level = rsp.curr_tx_power_level; + *out_max_tx_power_level = rsp.max_tx_power_level; + + return 0; +#else + return BLE_HS_ENOTSUP; +#endif +} + +int +ble_gap_read_remote_transmit_power_level(uint16_t conn_handle, + uint8_t phy) +{ +#if MYNEWT_VAL(BLE_POWER_CONTROL) + struct ble_hci_le_read_remote_transmit_power_level_cp cmd; + uint16_t opcode; + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_READ_REMOTE_TRANSMIT_POWER_LEVEL); + + cmd.conn_handle = htole16(conn_handle); + cmd.phy = phy; + + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); +#else + return BLE_HS_ENOTSUP; +#endif +} + +int +ble_gap_set_path_loss_reporting_param(uint16_t conn_handle, + uint8_t high_threshold, + uint8_t high_hysteresis, + uint8_t low_threshold, + uint8_t low_hysteresis, + uint16_t min_time_spent) +{ +#if MYNEWT_VAL(BLE_POWER_CONTROL) + struct ble_hci_le_set_path_loss_report_param_cp cmd; + uint16_t opcode; + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PATH_LOSS_REPORT_PARAM); + + cmd.conn_handle = htole16(conn_handle); + cmd.high_threshold = high_threshold; + cmd.high_hysteresis = high_hysteresis; + cmd.low_threshold = low_threshold; + cmd.low_hysteresis = low_hysteresis; + cmd.min_time_spent = min_time_spent; + + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); +#else + return BLE_HS_ENOTSUP; +#endif +} + +int +ble_gap_set_path_loss_reporting_enable(uint16_t conn_handle, + uint8_t enable) +{ +#if MYNEWT_VAL(BLE_POWER_CONTROL) + struct ble_hci_le_set_path_loss_report_enable_cp cmd; + uint16_t opcode; + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PATH_LOSS_REPORT_ENABLE); + + cmd.conn_handle = htole16(conn_handle); + cmd.enable = enable; + + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); +#else + return BLE_HS_ENOTSUP; +#endif +} + +int +ble_gap_set_transmit_power_reporting_enable(uint16_t conn_handle, + uint8_t local_enable, + uint8_t remote_enable) +{ +#if MYNEWT_VAL(BLE_POWER_CONTROL) + struct ble_hci_le_set_transmit_power_report_enable_cp cmd; + uint16_t opcode; + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_TRANS_PWR_REPORT_ENABLE); + + cmd.conn_handle = htole16(conn_handle); + cmd.local_enable = local_enable; + cmd.remote_enable = remote_enable; + + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); +#else + return BLE_HS_ENOTSUP; +#endif +} diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h index 499823bc5a..ca85db3dda 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/nimble/host/src/ble_gap_priv.h @@ -93,6 +93,11 @@ void ble_gap_rx_scan_req_rcvd(const struct ble_hci_ev_le_subev_scan_req_rcvd *ev void ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc); void ble_gap_rx_rd_rem_sup_feat_complete(const struct ble_hci_ev_le_subev_rd_rem_used_feat *ev); +#if MYNEWT_VAL(BLE_POWER_CONTROL) +void ble_gap_rx_transmit_power_report(const struct ble_hci_ev_le_subev_transmit_power_report *ev); +void ble_gap_rx_le_pathloss_threshold(const struct ble_hci_ev_le_subev_path_loss_threshold *ev); +#endif + struct ble_gap_conn_complete { uint8_t status; diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index b3724a8215..be64a3d3af 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -60,6 +60,10 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_rpt; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_lost; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_scan_req_rcvd; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_transfer; +#if MYNEWT_VAL(BLE_POWER_CONTROL) +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_pathloss_threshold; +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_transmit_power_report; +#endif /* Statistics */ struct host_hci_stats @@ -116,6 +120,10 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = { [BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED] = ble_hs_hci_evt_le_adv_set_terminated, [BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD] = ble_hs_hci_evt_le_scan_req_rcvd, [BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_TRANSFER] = ble_hs_hci_evt_le_periodic_adv_sync_transfer, +#if MYNEWT_VAL(BLE_POWER_CONTROL) + [BLE_HCI_LE_SUBEV_PATH_LOSS_THRESHOLD] = ble_hs_hci_evt_le_pathloss_threshold, + [BLE_HCI_LE_SUBEV_TRANSMIT_POWER_REPORT] = ble_hs_hci_evt_le_transmit_power_report, +#endif }; #define BLE_HS_HCI_EVT_LE_DISPATCH_SZ \ @@ -641,6 +649,36 @@ ble_hs_hci_evt_le_periodic_adv_sync_lost(uint8_t subevent, const void *data, return 0; } +#if MYNEWT_VAL(BLE_POWER_CONTROL) +static int +ble_hs_hci_evt_le_pathloss_threshold(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_path_loss_threshold *ev = data; + + if (len != sizeof(*ev)) { + return BLE_HS_EBADDATA; + } + + ble_gap_rx_le_pathloss_threshold(ev); + return 0; +} + +static int +ble_hs_hci_evt_le_transmit_power_report(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_transmit_power_report *ev = data; + + if (len != sizeof(*ev)) { + return BLE_HS_EBADDATA; + } + + ble_gap_rx_transmit_power_report(ev); + return 0; +} +#endif + static int ble_hs_hci_evt_le_periodic_adv_sync_transfer(uint8_t subevent, const void *data, unsigned int len) diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 58de8a6cd1..aa3e3775a6 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1122,6 +1122,49 @@ struct ble_hci_vs_css_set_conn_slot_cp { uint16_t slot_idx; } __attribute__((packed)); +#define BLE_HCI_OCF_LE_ENH_READ_TRANSMIT_POWER_LEVEL (0x0076) +struct ble_hci_le_enh_read_transmit_power_level_cp { + uint16_t conn_handle; + uint8_t phy; +} __attribute__((packed)); +struct ble_hci_le_enh_read_transmit_power_level_rp { + uint8_t status; + uint16_t conn_handle; + uint8_t phy; + uint8_t curr_tx_power_level; + uint8_t max_tx_power_level; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_READ_REMOTE_TRANSMIT_POWER_LEVEL (0x0077) +struct ble_hci_le_read_remote_transmit_power_level_cp { + uint16_t conn_handle; + uint8_t phy; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_SET_PATH_LOSS_REPORT_PARAM (0x0078) +struct ble_hci_le_set_path_loss_report_param_cp { + uint16_t conn_handle; + uint8_t high_threshold; + uint8_t high_hysteresis; + uint8_t low_threshold; + uint8_t low_hysteresis; + uint16_t min_time_spent; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_SET_PATH_LOSS_REPORT_ENABLE (0x0079) +struct ble_hci_le_set_path_loss_report_enable_cp { + uint16_t conn_handle; + uint8_t enable; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_SET_TRANS_PWR_REPORT_ENABLE (0x007A) +struct ble_hci_le_set_transmit_power_report_enable_cp { + uint16_t conn_handle; + uint8_t local_enable; + uint8_t remote_enable; +} __attribute__((packed)); + + /* Command Specific Definitions */ /* --- Set controller to host flow control (OGF 0x03, OCF 0x0031) --- */ #define BLE_HCI_CTLR_TO_HOST_FC_OFF (0) @@ -1823,6 +1866,26 @@ struct ble_hci_ev_le_subev_peer_sca_complete { uint8_t sca; } __attribute__((packed)); +#define BLE_HCI_LE_SUBEV_PATH_LOSS_THRESHOLD (0x20) +struct ble_hci_ev_le_subev_path_loss_threshold { + uint8_t subev_code; + uint16_t conn_handle; + uint8_t current_path_loss; + uint8_t zone_entered; +} __attribute__((packed)); + +#define BLE_HCI_LE_SUBEV_TRANSMIT_POWER_REPORT (0x21) +struct ble_hci_ev_le_subev_transmit_power_report { + uint8_t subev_code; + uint8_t status; + uint16_t conn_handle; + uint8_t reason; + uint8_t phy; + uint8_t transmit_power_level; + uint8_t transmit_power_level_flag; + uint8_t delta; +} __attribute__((packed)); + #define BLE_HCI_LE_SUBEV_BIGINFO_ADV_REPORT (0x22) struct ble_hci_ev_le_subev_biginfo_adv_report { uint8_t subev_code; diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index 2d2d329278..f8c92ea094 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -108,6 +108,11 @@ syscfg.defs: implementations. value: 0 + BLE_POWER_CONTROL: + description: > + This enabled LE Power Control feature + value: 0 + # Allow periodic sync transfer only if 5.1 or higher syscfg.restrictions: - "'BLE_PERIODIC_ADV_SYNC_TRANSFER == 0' || 'BLE_VERSION >= 51'" diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index 903163ad61..14877d1617 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -498,6 +498,10 @@ #define MYNEWT_VAL_BLE_WHITELIST (1) #endif +#ifndef MYNEWT_VAL_BLE_POWER_CONTROL +#define MYNEWT_VAL_BLE_POWER_CONTROL (0) +#endif + /*** @apache-mynewt-nimble/nimble/host */ #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 550ce53985..5fccff8a23 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -499,6 +499,10 @@ #define MYNEWT_VAL_BLE_WHITELIST (1) #endif +#ifndef MYNEWT_VAL_BLE_POWER_CONTROL +#define MYNEWT_VAL_BLE_POWER_CONTROL (0) +#endif + /*** @apache-mynewt-nimble/nimble/host */ #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index 11fa149d65..435b3aebcd 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -498,6 +498,10 @@ #define MYNEWT_VAL_BLE_WHITELIST (1) #endif +#ifndef MYNEWT_VAL_BLE_POWER_CONTROL +#define MYNEWT_VAL_BLE_POWER_CONTROL (0) +#endif + /*** @apache-mynewt-nimble/nimble/host */ #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index 55a7c8b321..ba2a292d79 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -497,6 +497,10 @@ #define MYNEWT_VAL_BLE_WHITELIST (1) #endif +#ifndef MYNEWT_VAL_BLE_POWER_CONTROL +#define MYNEWT_VAL_BLE_POWER_CONTROL (0) +#endif + /*** @apache-mynewt-nimble/nimble/host */ #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index d7493392ff..84bdea5ef7 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -858,6 +858,10 @@ #define MYNEWT_VAL_BLE_WHITELIST (1) #endif +#ifndef MYNEWT_VAL_BLE_POWER_CONTROL +#define MYNEWT_VAL_BLE_POWER_CONTROL (0) +#endif + /*** @apache-mynewt-nimble/nimble/controller */ #ifndef MYNEWT_VAL_BLE_CONTROLLER #define MYNEWT_VAL_BLE_CONTROLLER (1) From 534afc8c481619a54b465da2043c86403ad369b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 19 Apr 2022 12:22:25 +0200 Subject: [PATCH 0392/1333] host/mesh: fix clients array indexing in proxy_srv In proxy_srv clients were indexed using wrong handle values. Now each client has its own handle that is always initialized and is not connected with connection handle. --- nimble/host/mesh/src/proxy_msg.h | 1 + nimble/host/mesh/src/proxy_srv.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/nimble/host/mesh/src/proxy_msg.h b/nimble/host/mesh/src/proxy_msg.h index 349ebcdf4a..dabe7e80ce 100644 --- a/nimble/host/mesh/src/proxy_msg.h +++ b/nimble/host/mesh/src/proxy_msg.h @@ -45,6 +45,7 @@ struct bt_mesh_proxy_role { struct bt_mesh_proxy_client { struct bt_mesh_proxy_role *cli; + uint16_t conn_handle; uint16_t filter[MYNEWT_VAL(BLE_MESH_PROXY_FILTER_SIZE)]; enum __packed { NONE, diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index f26a079c33..65a5af78dd 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -62,7 +62,27 @@ static int conn_count; struct bt_mesh_proxy_client *find_client(uint16_t conn_handle) { - return &clients[conn_handle]; + int i; + + for (i = 0; i < ARRAY_SIZE(clients); i++) { + if (clients[i].conn_handle == conn_handle) { + return &clients[i]; + } + } + return NULL; +} + +static struct bt_mesh_proxy_client *get_client(uint16_t conn_handle) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(clients); i++) { + if (clients[i].conn_handle == 0xffff) { + clients[i].conn_handle = conn_handle; + return &clients[i]; + } + } + return NULL; } /* Next subnet in queue to be advertised */ @@ -811,7 +831,8 @@ static void gatt_connected(uint16_t conn_handle) conn_count++; - client = find_client(conn_handle); + client = get_client(conn_handle); + assert(client); client->filter_type = NONE; (void)memset(client->filter, 0, sizeof(client->filter)); @@ -844,6 +865,8 @@ static void gatt_disconnected(struct ble_gap_conn_desc conn, uint8_t reason) bt_mesh_proxy_role_cleanup(client->cli); client->cli = NULL; } + + client->conn_handle = 0xffff; } void notify_complete(void) @@ -970,6 +993,7 @@ int bt_mesh_proxy_init(void) #if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) k_work_init(&clients[i].send_beacons, proxy_send_beacons); #endif + clients[i].conn_handle = 0xffff; } resolve_svc_handles(); From 854fc2fafc9c488abdd851fb00af1c7a2e59644c Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 1 Sep 2021 16:49:39 +0200 Subject: [PATCH 0393/1333] nimble/host: no random address fix The app didn't build on dialog_da1469x-dk-pro board. Couldn't load random address. --- nimble/host/util/src/addr.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nimble/host/util/src/addr.c b/nimble/host/util/src/addr.c index b3112f1284..830ff02580 100644 --- a/nimble/host/util/src/addr.c +++ b/nimble/host/util/src/addr.c @@ -55,8 +55,13 @@ ble_hs_util_ensure_rand_addr(void) /* Otherwise, try to load a random address. */ rc = ble_hs_util_load_rand_addr(&addr); + if (rc != 0) { - return rc; + /* If it didn't work, generate random address */ + rc = ble_hs_id_gen_rnd(0, &addr); + if (rc != 0) { + return rc; + } } /* Configure nimble to use the random address. */ From 2a7135469ef6ef237dc20341ff978dbd5a4eb17b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 19 Apr 2022 17:07:15 +0200 Subject: [PATCH 0394/1333] Update missing licenses and rat excludes --- .rat-excludes | 4 ++++ porting/targets/porting_default/syscfg.yml | 18 ++++++++++++++++++ targets/nordic_pca10056-blehci-usb/pkg.yml | 18 ++++++++++++++++++ targets/nordic_pca10056-blehci-usb/syscfg.yml | 18 ++++++++++++++++++ targets/nordic_pca10056-blehci-usb/target.yml | 18 ++++++++++++++++++ 5 files changed, 76 insertions(+) diff --git a/.rat-excludes b/.rat-excludes index bed75ef701..a4bcb91b73 100644 --- a/.rat-excludes +++ b/.rat-excludes @@ -16,6 +16,7 @@ pts-sm.txt 94654-20170317-085441153.pts uncrustify.cfg .style_ignored_dirs +.mailmap # tinycrypt - BSD License. tinycrypt @@ -31,3 +32,6 @@ os_mbuf.c # Bluetooth Mesh badge sample - Apache 2.0 License mesh_badge + +#BabbleSim and EDDT - Apache 2.0 License +babblesim diff --git a/porting/targets/porting_default/syscfg.yml b/porting/targets/porting_default/syscfg.yml index 7c6db1ae67..cb6cda18ef 100644 --- a/porting/targets/porting_default/syscfg.yml +++ b/porting/targets/porting_default/syscfg.yml @@ -1,3 +1,21 @@ +# 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. +# + syscfg.vals: BLE_TRANSPORT_LL: socket BLE_SOCK_USE_TCP: 0 diff --git a/targets/nordic_pca10056-blehci-usb/pkg.yml b/targets/nordic_pca10056-blehci-usb/pkg.yml index 772dd75ebe..2c8307d3df 100644 --- a/targets/nordic_pca10056-blehci-usb/pkg.yml +++ b/targets/nordic_pca10056-blehci-usb/pkg.yml @@ -1,3 +1,21 @@ +# 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: "targets/nordic_pca10056-blehci-usb" pkg.type: target pkg.description: diff --git a/targets/nordic_pca10056-blehci-usb/syscfg.yml b/targets/nordic_pca10056-blehci-usb/syscfg.yml index f2579c14f7..0c5701a98b 100644 --- a/targets/nordic_pca10056-blehci-usb/syscfg.yml +++ b/targets/nordic_pca10056-blehci-usb/syscfg.yml @@ -1,3 +1,21 @@ +# 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. +# + syscfg.vals: BLE_TRANSPORT_HS: usb USBD_BTH: 1 diff --git a/targets/nordic_pca10056-blehci-usb/target.yml b/targets/nordic_pca10056-blehci-usb/target.yml index 39f4c8c447..ce455d45c9 100644 --- a/targets/nordic_pca10056-blehci-usb/target.yml +++ b/targets/nordic_pca10056-blehci-usb/target.yml @@ -1,3 +1,21 @@ +# 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. +# + target.app: "@apache-mynewt-nimble/apps/blehci" target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" target.build_profile: debug From 749f13bf9cb85b08b41a562a6fc764d16b8bdec2 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Wed, 20 Apr 2022 13:58:23 +0200 Subject: [PATCH 0395/1333] minor fixes - ble_ll needs to include hal_system.h for hal_debugger_connected() - ble_ll_sync needs stdlib.h for abs() - ble_ll_init() can be static/private --- nimble/controller/include/controller/ble_ll.h | 3 --- nimble/controller/src/ble_ll.c | 3 ++- nimble/controller/src/ble_ll_sync.c | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 18468d43b4..58992e88ad 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -476,9 +476,6 @@ struct ble_ll_acad_channel_map_update_ind { } __attribute__((packed)); /*--- External API ---*/ -/* Initialize the Link Layer */ -void ble_ll_init(void); - /* Reset the Link Layer */ int ble_ll_reset(void); diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 23b105fa72..b6681abfb9 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -47,6 +47,7 @@ #include "ble_ll_conn_priv.h" #include "ble_ll_hci_priv.h" #include "ble_ll_priv.h" +#include "hal/hal_system.h" #if MYNEWT_VAL(BLE_LL_DTM) #include "ble_ll_dtm_priv.h" @@ -1788,7 +1789,7 @@ ble_ll_assert(const char *file, unsigned line) * * @return int */ -void +static void ble_ll_init(void) { int rc; diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 0395c72bc5..65f2fcae60 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "syscfg/syscfg.h" From 65755d5e405b853e69317a2519284a0c2d9b4c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 20 Apr 2022 12:28:28 +0200 Subject: [PATCH 0396/1333] host: l2cap: check connection parameters in ble_l2cap_sig_update_req_rx This should be done before asking application. --- nimble/host/src/ble_l2cap_sig.c | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index 5263852785..05f5829f51 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -373,6 +373,40 @@ ble_l2cap_sig_update_call_cb(struct ble_l2cap_sig_proc *proc, int status) } } +static int +ble_l2cap_sig_check_conn_params(const struct ble_gap_upd_params *params) +{ + /* Check connection interval min */ + if ((params->itvl_min < BLE_HCI_CONN_ITVL_MIN) || + (params->itvl_min > BLE_HCI_CONN_ITVL_MAX)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + /* Check connection interval max */ + if ((params->itvl_max < BLE_HCI_CONN_ITVL_MIN) || + (params->itvl_max > BLE_HCI_CONN_ITVL_MAX) || + (params->itvl_max < params->itvl_min)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* Check connection latency */ + if (params->latency > BLE_HCI_CONN_LATENCY_MAX) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* Check supervision timeout */ + if ((params->supervision_timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN) || + (params->supervision_timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* Check connection event length */ + if (params->min_ce_len > params->max_ce_len) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + return 0; +} + int ble_l2cap_sig_update_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, @@ -414,6 +448,12 @@ ble_l2cap_sig_update_req_rx(uint16_t conn_handle, params.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN; params.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN; + rc = ble_l2cap_sig_check_conn_params(¶ms); + if (rc != 0) { + /* Invalid parameters */ + goto result; + } + /* Ask application if slave's connection parameters are acceptable. */ rc = ble_gap_rx_l2cap_update_req(conn_handle, ¶ms); if (rc == 0) { @@ -421,6 +461,7 @@ ble_l2cap_sig_update_req_rx(uint16_t conn_handle, rc = ble_gap_update_params(conn_handle, ¶ms); } +result: if (rc == 0) { l2cap_result = BLE_L2CAP_SIG_UPDATE_RSP_RESULT_ACCEPT; } else { From c521bf58361c1f6779b172069ce08ce7232319ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 20 Apr 2022 14:03:45 +0200 Subject: [PATCH 0397/1333] apps: bttester: add option to reject CPUP parameters This is required by GAP/CONN/CPUP/BV-05-C --- apps/bttester/src/gap.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/apps/bttester/src/gap.c b/apps/bttester/src/gap.c index 4922f4fb7a..74b956b9f4 100644 --- a/apps/bttester/src/gap.c +++ b/apps/bttester/src/gap.c @@ -41,6 +41,12 @@ #define BLE_AD_DISCOV_MASK (BLE_HS_ADV_F_DISC_LTD | BLE_HS_ADV_F_DISC_GEN) #define ADV_BUF_LEN (sizeof(struct gap_device_found_ev) + 2 * 31) +/* parameter values to reject in CPUP if all match the pattern */ +#define REJECT_INTERVAL_MIN 0x0C80 +#define REJECT_INTERVAL_MAX 0x0C80 +#define REJECT_LATENCY 0x0000 +#define REJECT_SUPERVISION_TIMEOUT 0x0C80 + const uint8_t irk[16] = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, @@ -1220,6 +1226,25 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg) *event->conn_update_req.self_params = *event->conn_update_req.peer_params; break; + case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: + console_printf("connection update request event; " + "conn_handle=%d itvl_min=%d itvl_max=%d " + "latency=%d supervision_timoeut=%d " + "min_ce_len=%d max_ce_len=%d\n", + event->conn_update_req.conn_handle, + event->conn_update_req.peer_params->itvl_min, + event->conn_update_req.peer_params->itvl_max, + event->conn_update_req.peer_params->latency, + event->conn_update_req.peer_params->supervision_timeout, + event->conn_update_req.peer_params->min_ce_len, + event->conn_update_req.peer_params->max_ce_len); + if (event->conn_update_req.peer_params->itvl_min == REJECT_INTERVAL_MIN && + event->conn_update_req.peer_params->itvl_max == REJECT_INTERVAL_MAX && + event->conn_update_req.peer_params->latency == REJECT_LATENCY && + event->conn_update_req.peer_params->supervision_timeout == REJECT_SUPERVISION_TIMEOUT) { + return EINVAL; + } + default: break; } From 4ad6162832e9fda59e2114dc67c31d262b7a374d Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Thu, 21 Apr 2022 13:52:53 +0200 Subject: [PATCH 0398/1333] fix init ordering When building an application (eg btshell), ble_svc_gap_init() is at stage 301 ble_transport_hs_init() happens at the end after 1000 But ble_svc_gap_init calls (through ble_gatts_add_svcs) ble_hs_lock() that uses the ble_hs_mutex. This mutex is only initialized in ble_hs_init() (via ble_transport_hs_init), so this must be called first --- nimble/transport/pkg.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/nimble/transport/pkg.yml b/nimble/transport/pkg.yml index 5fbcbd21f4..03924ced59 100644 --- a/nimble/transport/pkg.yml +++ b/nimble/transport/pkg.yml @@ -52,9 +52,7 @@ pkg.deps.BLE_MONITOR_RTT: pkg.init: ble_transport_init: 250 - ble_transport_hs_init: - - $after:ble_transport_init - - $before:ble_transport_ll_init + ble_transport_hs_init: 251 ble_transport_ll_init: - $after:ble_transport_hs_init From 76c8573ffe7eb741b6dd477b40921911e386b689 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 22 Apr 2022 00:05:47 +0200 Subject: [PATCH 0399/1333] nimble/transport: Remove unused syscfg No longer used in new transport architecture. --- nimble/transport/emspi/syscfg.yml | 10 ---------- nimble/transport/usb/syscfg.yml | 9 --------- 2 files changed, 19 deletions(-) diff --git a/nimble/transport/emspi/syscfg.yml b/nimble/transport/emspi/syscfg.yml index 05e6e14b10..12a853e749 100644 --- a/nimble/transport/emspi/syscfg.yml +++ b/nimble/transport/emspi/syscfg.yml @@ -28,16 +28,6 @@ syscfg.defs: # This is a host-only transport. - BLE_HOST - BLE_HCI_ACL_OUT_COUNT: - description: > - This count is used in creating a pool of elements used by the - code to enqueue various elements. In the case of the controller - only HCI, this number should be equal to the number of mbufs in - the msys pool. For host only, it is really dependent on the - number of ACL buffers that the controller tells the host it - has. - value: 12 - BLE_HCI_EMSPI_SPI_NUM: description: The index of the SPI device to use for HCI. value: 5 diff --git a/nimble/transport/usb/syscfg.yml b/nimble/transport/usb/syscfg.yml index 17ef649be5..2cdd57468a 100644 --- a/nimble/transport/usb/syscfg.yml +++ b/nimble/transport/usb/syscfg.yml @@ -17,12 +17,3 @@ # syscfg.defs: - BLE_HCI_ACL_OUT_COUNT: - description: > - This count is used in creating a pool of elements used by the - code to enqueue various elements. In the case of the controller - only HCI, this number should be equal to the number of mbufs in - the msys pool. For host only, it is really dependent on the - number of ACL buffers that the controller tells the host it - has. - value: 12 From a763af2d2874fa4032aad58599f4429d423c7ecb Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 22 Apr 2022 00:26:46 +0200 Subject: [PATCH 0400/1333] nimble/ll: Add proper verification for per adv enable hci We do not support ADI in periodic advertising so need to return proper error code if requested. Otherwise return an error if RFU bit is set. This fixes HCI/CCO/BI-34-C. --- nimble/controller/src/ble_ll_adv.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 129eeba569..74e8bf56e0 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -3962,6 +3962,18 @@ ble_ll_adv_periodic_enable(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_UNK_ADV_INDENT; } +#if MYNEWT_VAL(BLE_VERSION) >= 53 + if (cmd->enable & 0x02) { + return BLE_ERR_UNSUPPORTED; + } else if (cmd->enable & 0xfc) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } +#else + if (cmd->enable & 0xfe) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } +#endif + if (cmd->enable) { if (advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_DATA_INCOMPLETE) { return BLE_ERR_CMD_DISALLOWED; From 8463e0e832108fad6570ad30a33e8c0041223e8d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 22 Apr 2022 00:36:39 +0200 Subject: [PATCH 0401/1333] nimble/ll: Calculate min auth payload tmo with subrating This fixes HCI/CCO/BI-39-C. --- nimble/controller/src/ble_ll_conn_hci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 8f5771a673..2ffda58a81 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1867,11 +1867,14 @@ ble_ll_conn_hci_wr_auth_pyld_tmo(const uint8_t *cmdbuf, uint8_t len, */ tmo = le16toh(cmd->tmo); min_tmo = (uint32_t)connsm->conn_itvl * BLE_LL_CONN_ITVL_USECS; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + min_tmo *= connsm->subrate_factor; +#endif min_tmo *= (connsm->periph_latency + 1); min_tmo /= 10000; if (tmo < min_tmo) { - rc = BLE_ERR_INV_HCI_CMD_PARMS; + rc = BLE_ERR_CMD_DISALLOWED; } else { connsm->auth_pyld_tmo = tmo; if (ble_npl_callout_is_active(&connsm->auth_pyld_timer)) { From e7fb525b6a651795eb70a24f0536a6517183ae4f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 22 Apr 2022 00:38:24 +0200 Subject: [PATCH 0402/1333] nimble/ll: Remove CIS from host supported features We do not support it so we should not allow to set it. This fixes HCI/CCO/BI-44-C. --- nimble/controller/include/controller/ble_ll.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 58992e88ad..7136852d5f 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -289,8 +289,7 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats; #define BLE_LL_CONN_CLEAR_FEATURE(connsm, feature) (connsm->conn_features &= ~(feature)) /* All the features which can be controlled by the Host */ -#define BLE_LL_HOST_CONTROLLED_FEATURES (BLE_LL_FEAT_CIS_HOST | \ - BLE_LL_FEAT_CONN_SUBRATING_HOST) +#define BLE_LL_HOST_CONTROLLED_FEATURES (BLE_LL_FEAT_CONN_SUBRATING_HOST) /* LL timing */ #define BLE_LL_IFS (150) /* usecs */ From 352d4792cfee96ed15397fa2cb06259156540c5a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 22 Apr 2022 00:43:29 +0200 Subject: [PATCH 0403/1333] nimble/ll: Disallow periodic adv on incompatible ext adv instance We shall not allow enabling periodic advertising on an incompatible extended advertising instance, i.e. scannable, connectable, legacy or anonymous. This fixes HCI/DDI/BI-37-C, HCI/DDI/BI-38-C, HCI/DDI/BI-39-C, HCI/DDI/BI-40-C, HCI/DDI/BI-41-C, HCI/DDI/BI-42-C, HCI/DDI/BI-43-C, HCI/DDI/BI-44-C, HCI/DDI/BI-45-C, HCI/DDI/BI-46-C, HCI/DDI/BI-47-C, HCI/DDI/BI-53-C, HCI/DDI/BI-54-C, HCI/DDI/BI-55-C, HCI/DDI/BI-56-C, HCI/DDI/BI-57-C, HCI/DDI/BI-58-C, HCI/DDI/BI-59-C, HCI/DDI/BI-60-C, HCI/DDI/BI-61-C. (yup, there are so many test cases for testing the same scenario) --- nimble/controller/src/ble_ll_adv.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 74e8bf56e0..7c13743bec 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -3975,6 +3975,13 @@ ble_ll_adv_periodic_enable(const uint8_t *cmdbuf, uint8_t len) #endif if (cmd->enable) { + if (advsm->props & (BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV | + BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE | + BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE | + BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)) { + return BLE_ERR_CMD_DISALLOWED; + } + if (advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_DATA_INCOMPLETE) { return BLE_ERR_CMD_DISALLOWED; } From 21d59b8b40c232d6746778dda6b91cf0c0edba83 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 20 Apr 2022 16:27:06 +0200 Subject: [PATCH 0404/1333] Prepare for NimBLE 1.5.0 release --- NOTICE | 2 +- RELEASE_NOTES.md | 19 +++++++++++-------- repository.yml | 4 ++++ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/NOTICE b/NOTICE index 90952ecc53..0b205146a4 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ Apache Mynewt NimBLE -Copyright 2015-2021 The Apache Software Foundation +Copyright 2015-2022 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 99810a718d..cde2ce272c 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,21 +1,24 @@ # RELEASE NOTES -24 March 2021 - Apache NimBLE v1.4.0 +20 April 2022 - Apache NimBLE v1.5.0 For full release notes, please visit the [Apache Mynewt Wiki](https://cwiki.apache.org/confluence/display/MYNEWT/Release+Notes). -Apache NimBLE is an open-source Bluetooth 5.1 stack (both Host & Controller) that completely +Apache NimBLE is an open-source Bluetooth 5.3 stack (both Host & Controller) that completely replaces the proprietary SoftDevice on Nordic chipsets. New features in this version of NimBLE include: -* Support for PHY on Dialog Configurable MAC (CMAC) -* Support for PHY on Nordic nRF5340 -* Support for Apache NuttX port of NimBLE -* Controller-to-host flow control support -* Support for USB transport -* Various bugfixes +* Fake dual-mode option for controller +* LLCP tracing via HCI events +* Code size optimization for disabled GAP roles +* Support for PA/LNA +* LE Secure Connections Only mode +* Support for Bluetooth Core Specification 5.3 +* Connection subrating +* BabbleSim support +* Various bugfixes and improvements If working on next-generation RTOS and Bluetooth protocol stack sounds exciting to you, get in touch, by sending a mail to the Apache Mynewt diff --git a/repository.yml b/repository.yml index 9f112a825e..4c87b3ee35 100644 --- a/repository.yml +++ b/repository.yml @@ -30,12 +30,14 @@ repo.versions: "1.2.0": "nimble_1_2_0_tag" "1.3.0": "nimble_1_3_0_tag" "1.4.0": "nimble_1_4_0_tag" + "1.5.0": "nimble_1_5_0_tag" "1.0-latest": "1.0.0" "1.1-latest": "1.1.0" "1.2-latest": "1.2.0" "1.3-latest": "1.3.0" "1.4-latest": "1.4.0" + "1.5-latest": "1.5.0" repo.newt_compatibility: 0.0.0: @@ -50,3 +52,5 @@ repo.newt_compatibility: 1.8.0: good 1.4.0: 1.9.0: good + 1.5.0: + 1.10.0: good From 7a111aeebabb8cf5dc57de4c731fd5a2adc5513d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 5 May 2022 19:33:52 +0200 Subject: [PATCH 0405/1333] nimble/phy/nrf53: Fix PA/LNA enable READY/DISABLED events were not published if PA/LNA was enabled so it was not working - it only worked if GPIO debugging is also enabled which published those events. --- nimble/drivers/nrf5340/src/ble_phy.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/nimble/drivers/nrf5340/src/ble_phy.c b/nimble/drivers/nrf5340/src/ble_phy.c index 9734e88783..060e32eef5 100644 --- a/nimble/drivers/nrf5340/src/ble_phy.c +++ b/nimble/drivers/nrf5340/src/ble_phy.c @@ -1298,7 +1298,6 @@ ble_phy_dbg_time_setup(void) /* Publish RADIO->EVENTS_READY */ NRF_RADIO_NS->PUBLISH_READY = DPPI_CH_PUB(RADIO_EVENTS_READY); NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_READY); - #endif #if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 @@ -1435,6 +1434,13 @@ ble_phy_init(void) * TODO: figure out if this affects power consumption */ + /* Publish RADIO->EVENTS_READY */ + NRF_RADIO_NS->PUBLISH_READY = DPPI_CH_PUB(RADIO_EVENTS_READY); + NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_READY); + /* Publish RADIO->EVENTS_DISABLED */ + NRF_RADIO_NS->PUBLISH_DISABLED = DPPI_CH_PUB(RADIO_EVENTS_DISABLED); + NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_DISABLED); + #if PLNA_SINGLE_GPIO plna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO)); NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); From ea26cd4bc0b9dcc0e1dd5cf307ba146da8e7e04f Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 6 May 2022 11:22:58 +0200 Subject: [PATCH 0406/1333] Apache NimBLE 1.5.0 release --- repository.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/repository.yml b/repository.yml index 4c87b3ee35..256bc6b20f 100644 --- a/repository.yml +++ b/repository.yml @@ -22,8 +22,8 @@ repo.versions: "0.0.0": "master" "0-dev": "0.0.0" - "0-latest": "1.4.0" - "1-latest": "1.4.0" + "0-latest": "1.5.0" + "1-latest": "1.5.0" "1.0.0": "nimble_1_0_0_tag" "1.1.0": "nimble_1_1_0_tag" From 5295c093e8d75b095ae8544cc1406d08ceafcf4e Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 29 Apr 2022 10:28:06 +0200 Subject: [PATCH 0407/1333] README: Fix FAQ link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 07a893aa85..40badbbd55 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ want to talk to a human about what you're working on, you can contact us via the Although not a formal channel, you can also find a number of core developers on the #mynewt channel on Freenode IRC or #general channel on [Mynewt Slack](https://mynewt.slack.com/join/shared_invite/enQtNjA1MTg0NzgyNzg3LTcyMmZiOGQzOGMxM2U4ODFmMTIwNjNmYTE5Y2UwYjQwZWIxNTE0MTUzY2JmMTEzOWFjYWZkNGM0YmM4MzAxNWQ) -Also, be sure to checkout the [Frequently Asked Questions](https://mynewt.apache.org/faq/answers) +Also, be sure to checkout the [Frequently Asked Questions](https://mynewt.apache.org/latest/mynewt_faq) for some help troubleshooting first. # Contributing From 3fde0852fc00b7984f3cec139d0dca90ad3d5399 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 25 Apr 2022 11:17:31 +0200 Subject: [PATCH 0408/1333] nimble/phy/nrf: Fix build with GCC 11.1 Looks like GCC 11.1 doesn't like current code. The looks OK though... Error: repos/apache-mynewt-nimble/nimble/drivers/nrf52/src/ble_hw.c: In function 'ble_hw_get_static_addr': repos/apache-mynewt-nimble/nimble/drivers/nrf52/src/ble_hw.c:118:9: error: 'memcpy' offset [0, 3] is out of the bounds [0, 0] [-Werror=array-bounds] 118 | memcpy(addr->val, (void *)&NRF_FICR->DEVICEADDR[0], 4); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ repos/apache-mynewt-nimble/nimble/drivers/nrf52/src/ble_hw.c:119:9: error: 'memcpy' offset [0, 1] is out of the bounds [0, 0] [-Werror=array-bounds] 119 | memcpy(&addr->val[4], (void *)&NRF_FICR->DEVICEADDR[1], 2); --- nimble/drivers/nrf51/src/ble_hw.c | 10 ++++++++-- nimble/drivers/nrf52/src/ble_hw.c | 10 ++++++++-- nimble/drivers/nrf5340/src/ble_hw.c | 10 ++++++++-- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/nimble/drivers/nrf51/src/ble_hw.c b/nimble/drivers/nrf51/src/ble_hw.c index 437efd4f7c..fb6e844b0f 100644 --- a/nimble/drivers/nrf51/src/ble_hw.c +++ b/nimble/drivers/nrf51/src/ble_hw.c @@ -88,11 +88,17 @@ ble_hw_get_public_addr(ble_addr_t *addr) int ble_hw_get_static_addr(ble_addr_t *addr) { + uint32_t addr_high; + uint32_t addr_low; int rc; if ((NRF_FICR->DEVICEADDRTYPE & 1) == 1) { - memcpy(addr->val, (void *)&NRF_FICR->DEVICEADDR[0], 4); - memcpy(&addr->val[4], (void *)&NRF_FICR->DEVICEADDR[1], 2); + addr_low = NRF_FICR->DEVICEADDR[0]; + addr_high = NRF_FICR->DEVICEADDR[1]; + + memcpy(addr->val, &addr_low, 4); + memcpy(&addr->val[4], &addr_high, 2); + addr->val[5] |= 0xc0; addr->type = BLE_ADDR_RANDOM; rc = 0; diff --git a/nimble/drivers/nrf52/src/ble_hw.c b/nimble/drivers/nrf52/src/ble_hw.c index ef4c28b008..0accbbf40e 100644 --- a/nimble/drivers/nrf52/src/ble_hw.c +++ b/nimble/drivers/nrf52/src/ble_hw.c @@ -112,11 +112,17 @@ ble_hw_get_public_addr(ble_addr_t *addr) int ble_hw_get_static_addr(ble_addr_t *addr) { + uint32_t addr_high; + uint32_t addr_low; int rc; if ((NRF_FICR->DEVICEADDRTYPE & 1) == 1) { - memcpy(addr->val, (void *)&NRF_FICR->DEVICEADDR[0], 4); - memcpy(&addr->val[4], (void *)&NRF_FICR->DEVICEADDR[1], 2); + addr_low = NRF_FICR->DEVICEADDR[0]; + addr_high = NRF_FICR->DEVICEADDR[1]; + + memcpy(addr->val, &addr_low, 4); + memcpy(&addr->val[4], &addr_high, 2); + addr->val[5] |= 0xc0; addr->type = BLE_ADDR_RANDOM; rc = 0; diff --git a/nimble/drivers/nrf5340/src/ble_hw.c b/nimble/drivers/nrf5340/src/ble_hw.c index 92bf024979..e578fd05d2 100644 --- a/nimble/drivers/nrf5340/src/ble_hw.c +++ b/nimble/drivers/nrf5340/src/ble_hw.c @@ -83,11 +83,17 @@ ble_hw_get_public_addr(ble_addr_t *addr) int ble_hw_get_static_addr(ble_addr_t *addr) { + uint32_t addr_high; + uint32_t addr_low; int rc; if ((NRF_FICR_NS->DEVICEADDRTYPE & 1) == 1) { - memcpy(addr->val, (void *)&NRF_FICR_NS->DEVICEADDR[0], 4); - memcpy(&addr->val[4], (void *)&NRF_FICR_NS->DEVICEADDR[1], 2); + addr_low = NRF_FICR_NS->DEVICEADDR[0]; + addr_high = NRF_FICR_NS->DEVICEADDR[1]; + + memcpy(addr->val, &addr_low, 4); + memcpy(&addr->val[4], &addr_high, 2); + addr->val[5] |= 0xc0; addr->type = BLE_ADDR_RANDOM; rc = 0; From 04ca1f968400f3e47a734b79c4dcb7117a44d6bb Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Tue, 10 May 2022 10:21:45 +0200 Subject: [PATCH 0409/1333] transport/usb: Enable BTH in TinyUSB stack Setting USBD_BTH to 1 is required to enable code in TinyUSB stack. Due to newt limitation this value could not only be set target or application. Now USBD_BTH is defined by not set and can be set by this package. So user can just specify USB transport and USBD_BTH will be set automatically. --- nimble/transport/usb/syscfg.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/transport/usb/syscfg.yml b/nimble/transport/usb/syscfg.yml index 2cdd57468a..614f6437f6 100644 --- a/nimble/transport/usb/syscfg.yml +++ b/nimble/transport/usb/syscfg.yml @@ -17,3 +17,6 @@ # syscfg.defs: + +syscfg.vals: + USBD_BTH: 1 From 1e63bdb310c72838d84bcce650abbef960741ceb Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Fri, 13 May 2022 09:04:00 +0200 Subject: [PATCH 0410/1333] nimble/ll: only let ble_ll.c add/remove to ll_evq - change all ble_npl_eventq_put(&g_ble_ll_data.ll_evq, ..) -> ble_ll_event_add(..) - change all ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, ..) -> ble_ll_event_remove(..) - rename ble_ll_event_send -> ble_ll_event_add (matches more with remove) --- nimble/controller/include/controller/ble_ll.h | 7 +++- nimble/controller/src/ble_ll.c | 23 +++++++--- nimble/controller/src/ble_ll_adv.c | 42 +++++++++---------- nimble/controller/src/ble_ll_conn.c | 17 ++++---- nimble/controller/src/ble_ll_dtm.c | 12 +++--- nimble/controller/src/ble_ll_hci.c | 2 +- nimble/controller/src/ble_ll_rfmgmt.c | 6 +-- nimble/controller/src/ble_ll_scan.c | 6 +-- nimble/controller/src/ble_ll_scan_aux.c | 2 +- nimble/controller/src/ble_ll_sched.c | 2 +- nimble/controller/src/ble_ll_sync.c | 18 ++++---- 11 files changed, 74 insertions(+), 63 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 7136852d5f..f336c08067 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -559,8 +559,11 @@ void ble_ll_state_set(uint8_t ll_state); /* Get the link layer state */ uint8_t ble_ll_state_get(void); -/* Send an event to LL task */ -void ble_ll_event_send(struct ble_npl_event *ev); +/* Add an event to LL task */ +void ble_ll_event_add(struct ble_npl_event *ev); + +/* Remove an event from LL task */ +void ble_ll_event_remove(struct ble_npl_event *ev); /* Hand received pdu's to LL task */ void ble_ll_rx_pdu_in(struct os_mbuf *rxpdu); diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index b6681abfb9..b4de889edb 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1042,7 +1042,7 @@ ble_ll_rx_pdu_in(struct os_mbuf *rxpdu) pkthdr = OS_MBUF_PKTHDR(rxpdu); STAILQ_INSERT_TAIL(&g_ble_ll_data.ll_rx_pkt_q, pkthdr, omp_next); - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_data.ll_rx_pkt_ev); + ble_ll_event_add(&g_ble_ll_data.ll_rx_pkt_ev); } #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) @@ -1061,7 +1061,7 @@ ble_ll_acl_data_in(struct os_mbuf *txpkt) OS_ENTER_CRITICAL(sr); STAILQ_INSERT_TAIL(&g_ble_ll_data.ll_tx_pkt_q, pkthdr, omp_next); OS_EXIT_CRITICAL(sr); - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_data.ll_tx_pkt_ev); + ble_ll_event_add(&g_ble_ll_data.ll_tx_pkt_ev); } /** @@ -1074,7 +1074,7 @@ ble_ll_acl_data_in(struct os_mbuf *txpkt) void ble_ll_data_buffer_overflow(void) { - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_data.ll_dbuf_overflow_ev); + ble_ll_event_add(&g_ble_ll_data.ll_dbuf_overflow_ev); } #endif @@ -1442,16 +1442,29 @@ ble_ll_state_get(void) /** * ble ll event send * - * Send an event to the Link Layer task + * Add an event to the Link Layer task * * @param ev Event to add to the Link Layer event queue. */ void -ble_ll_event_send(struct ble_npl_event *ev) +ble_ll_event_add(struct ble_npl_event *ev) { ble_npl_eventq_put(&g_ble_ll_data.ll_evq, ev); } +/** + * ble ll event remove + * + * Remove an event from the Link Layer task + * + * @param ev Event to remove from the Link Layer event queue. + */ +void +ble_ll_event_remove(struct ble_npl_event *ev) +{ + ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, ev); +} + /** * Returns the features supported by the link layer * diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 7c13743bec..3327ba58db 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1032,14 +1032,14 @@ ble_ll_adv_tx_done(void *arg) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (ble_ll_adv_active_chanset_is_pri(advsm)) { - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev); + ble_ll_event_add(&advsm->adv_txdone_ev); } else if (ble_ll_adv_active_chanset_is_sec(advsm)) { - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_sec_txdone_ev); + ble_ll_event_add(&advsm->adv_sec_txdone_ev); } else { BLE_LL_ASSERT(0); } #else - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev); + ble_ll_event_add(&advsm->adv_txdone_ev); #endif ble_ll_state_set(BLE_LL_STATE_STANDBY); @@ -1068,7 +1068,7 @@ ble_ll_adv_event_rmvd_from_sched(struct ble_ll_adv_sm *advsm) void ble_ll_adv_periodic_rmvd_from_sched(struct ble_ll_adv_sm *advsm) { - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_periodic_txdone_ev); + ble_ll_event_add(&advsm->adv_periodic_txdone_ev); } #endif @@ -1693,18 +1693,17 @@ ble_ll_adv_halt(void) if (advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING) { ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING); - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, - &advsm->adv_periodic_txdone_ev); + ble_ll_event_add(&advsm->adv_periodic_txdone_ev); ble_ll_state_set(BLE_LL_STATE_STANDBY); g_ble_ll_cur_adv_sm = NULL; return; } #endif - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev); + ble_ll_event_add(&advsm->adv_txdone_ev); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)) { - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_sec_txdone_ev); + ble_ll_event_add(&advsm->adv_sec_txdone_ev); } #endif @@ -1938,9 +1937,9 @@ ble_ll_adv_sm_stop(struct ble_ll_adv_sm *advsm) #endif OS_EXIT_CRITICAL(sr); - ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev); + ble_ll_event_remove(&advsm->adv_txdone_ev); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &advsm->adv_sec_txdone_ev); + ble_ll_event_remove(&advsm->adv_sec_txdone_ev); #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) @@ -2122,7 +2121,7 @@ ble_ll_adv_sync_tx_done(struct ble_ll_adv_sm *advsm) BLE_LL_ASSERT(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING); BLE_LL_ASSERT(!ble_ll_adv_active_chanset_is_sec(advsm)); - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_periodic_txdone_ev); + ble_ll_event_add(&advsm->adv_periodic_txdone_ev); ble_ll_state_set(BLE_LL_STATE_STANDBY); ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING); @@ -2339,8 +2338,7 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm, rc = ble_ll_sched_periodic_adv(sch, first_pdu); if (rc) { STATS_INC(ble_ll_stats, periodic_adv_drop_event); - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, - &advsm->adv_periodic_txdone_ev); + ble_ll_event_add(&advsm->adv_periodic_txdone_ev); return; } @@ -2432,8 +2430,7 @@ ble_ll_adv_periodic_schedule_next(struct ble_ll_adv_sm *advsm) advsm->periodic_adv_itvl_ticks)) { STATS_INC(ble_ll_stats, periodic_chain_drop_event); ble_ll_sched_rmv_elem(&sync->sch); - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, - &advsm->adv_periodic_txdone_ev); + ble_ll_event_add(&advsm->adv_periodic_txdone_ev); } } @@ -2503,7 +2500,7 @@ ble_ll_adv_periodic_done(struct ble_ll_adv_sm *advsm) /* Remove anything else scheduled for periodic */ ble_ll_sched_rmv_elem(&sync->sch); - ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &advsm->adv_periodic_txdone_ev); + ble_ll_event_remove(&advsm->adv_periodic_txdone_ev); /* If we have next SYNC scheduled, try to schedule another one */ if (sync_next->sch.enqueued) { @@ -2612,8 +2609,7 @@ ble_ll_adv_sm_stop_periodic(struct ble_ll_adv_sm *advsm) ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING); - ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, - &advsm->adv_periodic_txdone_ev); + ble_ll_event_remove(&advsm->adv_periodic_txdone_ev); ble_ll_adv_update_periodic_data(advsm); } @@ -4591,12 +4587,12 @@ ble_ll_adv_drop_event(struct ble_ll_adv_sm *advsm) ble_ll_sched_rmv_elem(&advsm->aux[0].sch); ble_ll_sched_rmv_elem(&advsm->aux[1].sch); - ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &advsm->adv_sec_txdone_ev); + ble_ll_event_remove(&advsm->adv_sec_txdone_ev); advsm->aux_active = 0; #endif advsm->adv_chan = ble_ll_adv_final_chan(advsm); - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev); + ble_ll_event_add(&advsm->adv_txdone_ev); } static void @@ -4675,7 +4671,7 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) /* Remove the element from the schedule if it is still there. */ ble_ll_sched_rmv_elem(&advsm->adv_sch); - ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev); + ble_ll_event_remove(&advsm->adv_txdone_ev); /* * Check if we have ended our advertising event. If our last advertising @@ -4815,7 +4811,7 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) rc = ble_ll_sched_adv_resched_pdu(&advsm->adv_sch); if (rc) { STATS_INC(ble_ll_stats, adv_resched_pdu_fail); - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &advsm->adv_txdone_ev); + ble_ll_event_add(&advsm->adv_txdone_ev); } } @@ -4859,7 +4855,7 @@ ble_ll_adv_sec_done(struct ble_ll_adv_sm *advsm) /* Remove anything else scheduled for secondary channel */ ble_ll_sched_rmv_elem(&aux->sch); - ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &advsm->adv_sec_txdone_ev); + ble_ll_event_remove(&advsm->adv_sec_txdone_ev); /* Stop advertising due to transmitting connection response */ if (advsm->flags & BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD) { diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index dc43fecc66..b6660196f5 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -374,7 +374,7 @@ ble_ll_conn_cth_flow_process_cmd(const uint8_t *cmdbuf) cp = (const void *)cmd->data; if (cmd->length != sizeof(cp->handles) + cp->handles * sizeof(cp->h[0])) { - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_conn_cth_flow_error_ev); + ble_ll_event_add(&g_ble_ll_conn_cth_flow_error_ev); return; } @@ -660,7 +660,7 @@ ble_ll_conn_current_sm_over(struct ble_ll_conn_sm *connsm) * need to post to the LL the connection event end event */ if (connsm) { - ble_ll_event_send(&connsm->conn_ev_end); + ble_ll_event_add(&connsm->conn_ev_end); } } @@ -1550,7 +1550,7 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) } if (rc == BLE_LL_SCHED_STATE_DONE) { - ble_ll_event_send(&connsm->conn_ev_end); + ble_ll_event_add(&connsm->conn_ev_end); ble_phy_disable(); ble_ll_state_set(BLE_LL_STATE_STANDBY); g_ble_ll_conn_cur_sm = NULL; @@ -2114,7 +2114,7 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err) } /* Make sure events off queue */ - ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &connsm->conn_ev_end); + ble_ll_event_remove(&connsm->conn_ev_end); /* Connection state machine is now idle */ connsm->conn_state = BLE_LL_CONN_STATE_IDLE; @@ -2781,7 +2781,7 @@ ble_ll_conn_event_end(struct ble_npl_event *ev) } /* Remove any connection end events that might be enqueued */ - ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &connsm->conn_ev_end); + ble_ll_event_remove(&connsm->conn_ev_end); /* * If we have received a packet, we can set the current transmit window @@ -3028,7 +3028,7 @@ ble_ll_conn_event_halt(void) ble_ll_state_set(BLE_LL_STATE_STANDBY); if (g_ble_ll_conn_cur_sm) { g_ble_ll_conn_cur_sm->csmflags.cfbit.pkt_rxd = 0; - ble_ll_event_send(&g_ble_ll_conn_cur_sm->conn_ev_end); + ble_ll_event_add(&g_ble_ll_conn_cur_sm->conn_ev_end); g_ble_ll_conn_cur_sm = NULL; } } @@ -3226,7 +3226,7 @@ ble_ll_conn_rx_isr_start(struct ble_mbuf_hdr *rxhdr, uint32_t aa) if (aa != connsm->access_addr) { STATS_INC(ble_ll_conn_stats, rx_data_pdu_bad_aa); ble_ll_state_set(BLE_LL_STATE_STANDBY); - ble_ll_event_send(&connsm->conn_ev_end); + ble_ll_event_add(&connsm->conn_ev_end); g_ble_ll_conn_cur_sm = NULL; return -1; } @@ -3654,8 +3654,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) #endif ++connsm->completed_pkts; if (connsm->completed_pkts > 2) { - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, - &g_ble_ll_data.ll_comp_pkt_ev); + ble_ll_event_add(&g_ble_ll_data.ll_comp_pkt_ev); } } os_mbuf_free_chain(txpdu); diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index 2c787da88e..db32835cab 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -199,7 +199,7 @@ static int ble_ll_dtm_rx_start(void); static void ble_ll_dtm_ev_rx_restart_cb(struct ble_npl_event *evt) { if (ble_ll_dtm_rx_start() != 0) { - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_dtm_ctx.evt); + ble_ll_event_add(&g_ble_ll_dtm_ctx.evt); STATS_INC(ble_ll_dtm_stats, rx_failed); } } @@ -217,7 +217,7 @@ ble_ll_dtm_tx_done(void *arg) g_ble_ll_dtm_ctx.num_of_packets++; /* Reschedule event in LL context */ - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &ctx->evt); + ble_ll_event_add(&ctx->evt); ble_ll_state_set(BLE_LL_STATE_STANDBY); } @@ -263,7 +263,7 @@ ble_ll_dtm_tx_sched_cb(struct ble_ll_sched_item *sch) resched: /* Reschedule from LL task if late for this PDU */ - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &ctx->evt); + ble_ll_event_add(&ctx->evt); STATS_INC(ble_ll_dtm_stats, tx_failed); @@ -416,7 +416,7 @@ static int ble_ll_dtm_rx_sched_cb(struct ble_ll_sched_item *sch) { if (ble_ll_dtm_rx_start() != 0) { - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_dtm_ctx.evt); + ble_ll_event_add(&g_ble_ll_dtm_ctx.evt); STATS_INC(ble_ll_dtm_stats, rx_failed); return BLE_LL_SCHED_STATE_DONE; } @@ -464,7 +464,7 @@ ble_ll_dtm_ctx_free(struct dtm_ctx * ctx) } ble_ll_sched_rmv_elem(&ctx->sch); - ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &g_ble_ll_dtm_ctx.evt); + ble_ll_event_remove(&g_ble_ll_dtm_ctx.evt); ble_phy_disable(); ble_phy_disable_dtm(); @@ -665,7 +665,7 @@ ble_ll_dtm_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) } if (ble_ll_dtm_rx_start() != 0) { - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_dtm_ctx.evt); + ble_ll_event_add(&g_ble_ll_dtm_ctx.evt); STATS_INC(ble_ll_dtm_stats, rx_failed); } } diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 9666b0235f..6aff00ebbe 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1813,7 +1813,7 @@ ble_ll_hci_cmd_rx(uint8_t *cmdbuf, void *arg) /* Fill out the event and post to Link Layer */ ble_npl_event_set_arg(ev, cmdbuf); - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, ev); + ble_ll_event_add(ev); return 0; } diff --git a/nimble/controller/src/ble_ll_rfmgmt.c b/nimble/controller/src/ble_ll_rfmgmt.c index 1877b61952..a9fd64ecb4 100644 --- a/nimble/controller/src/ble_ll_rfmgmt.c +++ b/nimble/controller/src/ble_ll_rfmgmt.c @@ -236,7 +236,7 @@ ble_ll_rfmgmt_reset(void) rfmgmt->timer_scheduled_at = 0; ble_ll_tmr_stop(&rfmgmt->timer); - ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &rfmgmt->release_ev); + ble_ll_event_remove(&rfmgmt->release_ev); ble_ll_rfmgmt_disable(); @@ -290,10 +290,10 @@ ble_ll_rfmgmt_release(void) OS_ENTER_CRITICAL(sr); - ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &rfmgmt->release_ev); + ble_ll_event_remove(&rfmgmt->release_ev); if (g_ble_ll_rfmgmt_data.state != RFMGMT_STATE_OFF) { - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &rfmgmt->release_ev); + ble_ll_event_add(&rfmgmt->release_ev); } OS_EXIT_CRITICAL(sr); diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 27c0feaa40..d9d351786d 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1674,7 +1674,7 @@ ble_ll_scan_chk_resume(void) OS_ENTER_CRITICAL(sr); if (scansm->restart_timer_needed) { scansm->restart_timer_needed = 0; - ble_ll_event_send(&scansm->scan_sched_ev); + ble_ll_event_add(&scansm->scan_sched_ev); STATS_INC(ble_ll_stats, scan_timer_restarted); OS_EXIT_CRITICAL(sr); return; @@ -1704,13 +1704,13 @@ ble_ll_scan_timer_cb(void *arg) struct ble_ll_scan_sm *scansm; scansm = (struct ble_ll_scan_sm *)arg; - ble_ll_event_send(&scansm->scan_sched_ev); + ble_ll_event_add(&scansm->scan_sched_ev); } void ble_ll_scan_interrupted(struct ble_ll_scan_sm *scansm) { - ble_ll_event_send(&scansm->scan_interrupted_ev); + ble_ll_event_add(&scansm->scan_interrupted_ev); } /** diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index e3b94822f2..2eb915d0e3 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -677,7 +677,7 @@ ble_ll_scan_aux_break(struct ble_ll_scan_aux_data *aux) #endif ble_npl_event_init(&aux->break_ev, ble_ll_scan_aux_break_ev, aux); - ble_ll_event_send(&aux->break_ev); + ble_ll_event_add(&aux->break_ev); } static int diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 40139a807a..149fee90e8 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -144,7 +144,7 @@ ble_ll_sched_preempt(struct ble_ll_sched_item *sch, #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_SCHED_TYPE_CONN: connsm = (struct ble_ll_conn_sm *)entry->cb_arg; - ble_ll_event_send(&connsm->conn_ev_end); + ble_ll_event_add(&connsm->conn_ev_end); break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 65f2fcae60..fec16e8689 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -197,7 +197,7 @@ ble_ll_sync_sm_clear(struct ble_ll_sync_sm *sm) if (sm->flags & (BLE_LL_SYNC_SM_FLAG_ESTABLISHING | BLE_LL_SYNC_SM_FLAG_ESTABLISHED)) { ble_ll_sched_rmv_elem(&sm->sch); - ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &sm->sync_ev_end); + ble_ll_event_remove(&sm->sync_ev_end); } if (sm->next_report) { @@ -481,7 +481,7 @@ ble_ll_sync_event_start_cb(struct ble_ll_sched_item *sch) rc = ble_phy_rx_set_start_time(start, sch->remainder); if (rc && rc != BLE_PHY_ERR_RX_LATE) { STATS_INC(ble_ll_stats, sync_event_failed); - ble_ll_event_send(&sm->sync_ev_end); + ble_ll_event_add(&sm->sync_ev_end); ble_ll_sync_current_sm_over(); rc = BLE_LL_SCHED_STATE_DONE; } else { @@ -534,7 +534,7 @@ ble_ll_sync_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *rxhdr) /* this also handles chains as those have same PDU type */ if (pdu_type != BLE_ADV_PDU_TYPE_AUX_SYNC_IND) { - ble_ll_event_send(&g_ble_ll_sync_sm_current->sync_ev_end); + ble_ll_event_add(&g_ble_ll_sync_sm_current->sync_ev_end); ble_ll_sync_current_sm_over(); STATS_INC(ble_ll_stats, sched_invalid_pdu); return -1; @@ -786,7 +786,7 @@ ble_ll_sync_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) ble_ll_rx_pdu_in(rxpdu); } else { STATS_INC(ble_ll_stats, sync_rx_buf_err); - ble_ll_event_send(&g_ble_ll_sync_sm_current->sync_ev_end); + ble_ll_event_add(&g_ble_ll_sync_sm_current->sync_ev_end); } /* PHY is disabled here */ @@ -809,7 +809,7 @@ ble_ll_sync_wfr_timer_exp(void) STATS_INC(ble_ll_stats, sync_missed_err); ble_ll_sync_current_sm_over(); - ble_ll_event_send(&sm->sync_ev_end); + ble_ll_event_add(&sm->sync_ev_end); } /** @@ -826,7 +826,7 @@ ble_ll_sync_halt(void) ble_ll_sync_current_sm_over(); if (sm) { - ble_ll_event_send(&sm->sync_ev_end); + ble_ll_event_add(&sm->sync_ev_end); } } @@ -1130,7 +1130,7 @@ ble_ll_sync_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) } end_event: - ble_ll_event_send(&sm->sync_ev_end); + ble_ll_event_add(&sm->sync_ev_end); ble_ll_rfmgmt_release(); } @@ -1234,7 +1234,7 @@ ble_ll_sync_event_end(struct ble_npl_event *ev) ble_ll_scan_chk_resume(); /* Remove any end events that might be enqueued */ - ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &sm->sync_ev_end); + ble_ll_event_remove(&sm->sync_ev_end); /* don't schedule next event if sync is not established nor establishing * at this point SM is no longer valid @@ -2227,7 +2227,7 @@ ble_ll_sync_transfer(const uint8_t *cmdbuf, uint8_t len, void ble_ll_sync_rmvd_from_sched(struct ble_ll_sync_sm *sm) { - ble_ll_event_send(&sm->sync_ev_end); + ble_ll_event_add(&sm->sync_ev_end); } bool From d11ceccfdc9afa7dfbf6224293af38938763ada0 Mon Sep 17 00:00:00 2001 From: jrotkiewicz Date: Mon, 16 May 2022 12:15:50 +0200 Subject: [PATCH 0411/1333] ble_ll_hci_vs: find conn function name fix Wrong function call. Function doesn't exist and the build fails. --- nimble/controller/src/ble_ll_hci_vs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index 2b3909206d..f12657cc52 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -220,7 +220,7 @@ ble_ll_hci_vs_css_set_conn_slot(const uint8_t *cmdbuf, uint8_t cmdlen, } conn_handle = le16toh(cmd->conn_handle); - connsm = ble_ll_conn_find_active_conn(conn_handle); + connsm = ble_ll_conn_find_by_handle(conn_handle); if (!connsm) { return BLE_ERR_UNK_CONN_ID; } From c3f2a94f159c677619a083b0dcad36ff40a91752 Mon Sep 17 00:00:00 2001 From: jrotkiewicz Date: Mon, 16 May 2022 17:49:15 +0200 Subject: [PATCH 0412/1333] hci_common.h: added missing offset for VS_CSS cmd --- nimble/include/nimble/hci_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index aa3e3775a6..14225f502f 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1100,7 +1100,7 @@ struct ble_hci_vs_set_tx_pwr_rp { int8_t tx_power; } __attribute__((packed)); -#define BLE_HCI_OCF_VS_CSS (0x0003) +#define BLE_HCI_OCF_VS_CSS (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0003)) struct ble_hci_vs_css_cp { uint8_t opcode; } __attribute__((packed)); From ef33a295928debd42854ce7714fe315102e1c323 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Fri, 13 May 2022 08:19:47 +0200 Subject: [PATCH 0413/1333] port: remove unimplemented function --- porting/npl/freertos/include/nimble/npl_freertos.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/porting/npl/freertos/include/nimble/npl_freertos.h b/porting/npl/freertos/include/nimble/npl_freertos.h index a7b1c4aa79..24441adfa0 100644 --- a/porting/npl/freertos/include/nimble/npl_freertos.h +++ b/porting/npl/freertos/include/nimble/npl_freertos.h @@ -24,8 +24,6 @@ extern "C" { #endif -struct ble_npl_eventq *npl_freertos_eventq_dflt_get(void); - struct ble_npl_event *npl_freertos_eventq_get(struct ble_npl_eventq *evq, ble_npl_time_t tmo); From 09c93dbd06becd94899e4c7f80ab59346fcdeae0 Mon Sep 17 00:00:00 2001 From: Daniel Kampert Date: Fri, 13 May 2022 15:02:55 +0200 Subject: [PATCH 0414/1333] nimble/host: Make BLE_UUIDxx_INIT macros C++ compatible Allows to use `ble_uuid.h` with C++ by changing the BLE_UUIDy_INIT macros. Build environment: ninja 1.9.0 cmake 3.16 xtensa-esp32-elf-gcc.exe (crosstool-NG esp-2021r2-patch3) 8.4.0 (based on GCC 8.4.0) --- nimble/host/include/host/ble_uuid.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/nimble/host/include/host/ble_uuid.h b/nimble/host/include/host/ble_uuid.h index d3576c5950..cc368368c6 100644 --- a/nimble/host/include/host/ble_uuid.h +++ b/nimble/host/include/host/ble_uuid.h @@ -82,19 +82,25 @@ typedef union { #define BLE_UUID16_INIT(uuid16) \ { \ - .u.type = BLE_UUID_TYPE_16, \ + .u = { \ + .type = BLE_UUID_TYPE_16, \ + }, \ .value = (uuid16), \ } #define BLE_UUID32_INIT(uuid32) \ { \ - .u.type = BLE_UUID_TYPE_32, \ + .u = { \ + .type = BLE_UUID_TYPE_32, \ + }, \ .value = (uuid32), \ } -#define BLE_UUID128_INIT(uuid128...) \ +#define BLE_UUID128_INIT(uuid128 ...) \ { \ - .u.type = BLE_UUID_TYPE_128, \ + .u = { \ + .type = BLE_UUID_TYPE_128, \ + }, \ .value = { uuid128 }, \ } From fa0354dd78c5fd63026e7722410450c4f98ad24c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 19 May 2022 09:14:53 +0200 Subject: [PATCH 0415/1333] host/ble_att_srv: fix ble_att_svr_check_perms for SC Only mode If security is not good enough, return BLE_ATT_ERR_INSUFFICIENT_AUTHEN. If security is enabled, but key is to short, return BLE_ATT_ERR_INSUFFICIENT_KEY_SZ --- nimble/host/src/ble_att_svr.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 272fc56778..0a03bcd388 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -289,12 +289,18 @@ ble_att_svr_check_perms(uint16_t conn_handle, int is_read, * require it on level 4 */ if (MYNEWT_VAL(BLE_SM_SC_ONLY)) { - if (sec_state.key_size != 16 || - !sec_state.authenticated || + if (!sec_state.authenticated || !sec_state.encrypted) { - return BLE_ATT_ERR_INSUFFICIENT_KEY_SZ; + *out_att_err = BLE_ATT_ERR_INSUFFICIENT_AUTHEN; + return BLE_HS_ATT_ERR(*out_att_err); + } else if (sec_state.authenticated && + sec_state.encrypted && + sec_state.key_size != 16) { + *out_att_err = BLE_ATT_ERR_INSUFFICIENT_KEY_SZ; + return BLE_HS_ATT_ERR(*out_att_err); } } + if ((enc || authen) && !sec_state.encrypted) { ble_hs_lock(); conn = ble_hs_conn_find(conn_handle); From 86c0a66542ec97f8ccf927abcd6e60ed2f4b4e78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 15 Nov 2021 11:20:15 +0100 Subject: [PATCH 0416/1333] apps/bttester: add lost bond event When we receive GAP event BLE_GAP_EVENT_REPEAT_PAIRING it means that we sent security request, but bond is lost - peer sent pair request in return, which means it doesn't have keys anymore. Bond is also lost when we sent encryption request and peer responded with Ecnryption Change event with error 'PIN or Key Missing'. Inform Upper tester about it. --- apps/bttester/src/bttester.h | 6 ++++++ apps/bttester/src/gap.c | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/apps/bttester/src/bttester.h b/apps/bttester/src/bttester.h index 641db8bd89..7bcd789cd4 100644 --- a/apps/bttester/src/bttester.h +++ b/apps/bttester/src/bttester.h @@ -412,6 +412,12 @@ struct gap_pairing_consent_req_ev { uint8_t address[6]; } __packed; +#define GAP_EV_BOND_LOST 0x8b +struct gap_bond_lost_ev { + uint8_t address_type; + uint8_t address[6]; +} __packed; + /* GATT Service */ /* commands */ #define GATT_READ_SUPPORTED_COMMANDS 0x01 diff --git a/apps/bttester/src/gap.c b/apps/bttester/src/gap.c index 74b956b9f4..e213609336 100644 --- a/apps/bttester/src/gap.c +++ b/apps/bttester/src/gap.c @@ -1025,6 +1025,20 @@ static void le_encryption_changed(struct ble_gap_conn_desc *desc) CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } +static void bond_lost(uint16_t conn_handle) +{ + struct gap_bond_lost_ev ev; + struct ble_gap_conn_desc desc; + int rc; + + rc = ble_gap_conn_find(conn_handle, &desc); + assert(rc == 0); + + memcpy(ev.address, &desc.peer_id_addr, sizeof(ev.address)); + ev.address_type = desc.peer_id_addr.type; + tester_send(BTP_SERVICE_ID_GAP, GAP_EV_BOND_LOST, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); +} + static void print_bytes(const uint8_t *bytes, int len) { int i; @@ -1133,6 +1147,9 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg) assert(rc == 0); print_conn_desc(&desc); le_encryption_changed(&desc); + if (event->enc_change.status == BLE_HS_HCI_ERR(BLE_ERR_PINKEY_MISSING)) { + bond_lost(event->enc_change.conn_handle); + } break; case BLE_GAP_EVENT_PASSKEY_ACTION: console_printf("passkey action event; action=%d", @@ -1201,6 +1218,7 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg) assert(rc == 0); rc = ble_store_util_delete_peer(&desc.peer_id_addr); assert(rc == 0); + bond_lost(event->repeat_pairing.conn_handle); return BLE_GAP_REPEAT_PAIRING_RETRY; case BLE_GAP_EVENT_CONN_UPDATE: console_printf("connection update event; status=%d ", From edb6a287eadc9a8a2a6fb7c60a0e0c4b912a176b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 19 May 2022 10:18:15 +0200 Subject: [PATCH 0417/1333] nimble/host/ble_sm: add restriciton for SC Only This mode requires MITM and SC to be on, and SM_LEGACY must be off. --- nimble/host/syscfg.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index ce2acc48dd..046624022d 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -104,6 +104,9 @@ syscfg.defs: value: 0 restrictions: - 'BLE_SM_SC_LVL == 4 if 1' + - BLE_SM_MITM + - 'BLE_SM_SC if 1' + - '!BLE_SM_LEGACY if 1' BLE_SM_SC_LVL: description: > From 57e29af5d2c0ec40e95911bf9c6543af6f36ff24 Mon Sep 17 00:00:00 2001 From: Jakub Date: Mon, 23 May 2022 13:24:47 +0200 Subject: [PATCH 0418/1333] Init version of python tool for measuring throughput User provides HCI indexes of connected controllers, the tool configures them and starts throughput test. More in README file. --- tools/README.md | 0 tools/hci_throughput/README.md | 100 +++ tools/hci_throughput/check_addr.py | 104 +++ tools/hci_throughput/config.yaml.sample | 55 ++ tools/hci_throughput/hci.py | 605 ++++++++++++++++ tools/hci_throughput/hci_commands.py | 668 ++++++++++++++++++ tools/hci_throughput/hci_device.py | 323 +++++++++ tools/hci_throughput/hci_socket.py | 164 +++++ tools/hci_throughput/init.yaml.sample | 34 + tools/hci_throughput/log/.gitignore | 2 + tools/hci_throughput/main.py | 243 +++++++ tools/hci_throughput/requirements.txt | 3 + .../targets/nordic_pca10040_blehci/pkg.yml | 24 + .../targets/nordic_pca10040_blehci/syscfg.yml | 28 + .../targets/nordic_pca10040_blehci/target.yml | 22 + .../targets/nordic_pca10040_boot/pkg.yml | 6 + .../targets/nordic_pca10040_boot/syscfg.yml | 0 .../targets/nordic_pca10040_boot/target.yml | 3 + .../targets/nordic_pca10056_blehci/pkg.yml | 27 + .../targets/nordic_pca10056_blehci/syscfg.yml | 32 + .../targets/nordic_pca10056_blehci/target.yml | 22 + .../targets/nordic_pca10056_boot/pkg.yml | 6 + .../targets/nordic_pca10056_boot/syscfg.yml | 0 .../targets/nordic_pca10056_boot/target.yml | 3 + .../targets/nordic_pca10059_blehci/pkg.yml | 27 + .../targets/nordic_pca10059_blehci/syscfg.yml | 32 + .../targets/nordic_pca10059_blehci/target.yml | 22 + .../targets/nrf52832_blehci/pkg.yml | 24 + .../targets/nrf52832_blehci/syscfg.yml | 26 + .../targets/nrf52832_blehci/target.yml | 22 + .../targets/nrf52840_blehci/pkg.yml | 27 + .../targets/nrf52840_blehci/syscfg.yml | 32 + .../targets/nrf52840_blehci/target.yml | 22 + tools/hci_throughput/tests/.gitignore | 2 + tools/hci_throughput/throughput.py | 197 ++++++ tools/hci_throughput/transport_factory.py | 38 + tools/hci_throughput/util.py | 70 ++ 37 files changed, 3015 insertions(+) create mode 100644 tools/README.md create mode 100644 tools/hci_throughput/README.md create mode 100644 tools/hci_throughput/check_addr.py create mode 100644 tools/hci_throughput/config.yaml.sample create mode 100644 tools/hci_throughput/hci.py create mode 100644 tools/hci_throughput/hci_commands.py create mode 100644 tools/hci_throughput/hci_device.py create mode 100644 tools/hci_throughput/hci_socket.py create mode 100644 tools/hci_throughput/init.yaml.sample create mode 100644 tools/hci_throughput/log/.gitignore create mode 100644 tools/hci_throughput/main.py create mode 100644 tools/hci_throughput/requirements.txt create mode 100644 tools/hci_throughput/targets/nordic_pca10040_blehci/pkg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10040_blehci/syscfg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10040_blehci/target.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10040_boot/pkg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10040_boot/syscfg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10040_boot/target.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10056_blehci/pkg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10056_blehci/syscfg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10056_blehci/target.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10056_boot/pkg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10056_boot/syscfg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10056_boot/target.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10059_blehci/pkg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10059_blehci/syscfg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10059_blehci/target.yml create mode 100644 tools/hci_throughput/targets/nrf52832_blehci/pkg.yml create mode 100644 tools/hci_throughput/targets/nrf52832_blehci/syscfg.yml create mode 100644 tools/hci_throughput/targets/nrf52832_blehci/target.yml create mode 100644 tools/hci_throughput/targets/nrf52840_blehci/pkg.yml create mode 100644 tools/hci_throughput/targets/nrf52840_blehci/syscfg.yml create mode 100644 tools/hci_throughput/targets/nrf52840_blehci/target.yml create mode 100755 tools/hci_throughput/tests/.gitignore create mode 100644 tools/hci_throughput/throughput.py create mode 100644 tools/hci_throughput/transport_factory.py create mode 100644 tools/hci_throughput/util.py diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/hci_throughput/README.md b/tools/hci_throughput/README.md new file mode 100644 index 0000000000..7a661d6045 --- /dev/null +++ b/tools/hci_throughput/README.md @@ -0,0 +1,100 @@ +# HCI Throughput + +Tool for measuring BLE throughput. + +## Packages versions +Python 3.8.10 \ +Matplotlib 3.5.1 + +## Usage +### Prepare devices +This tool may be used with existing controller or with any board with ```blehci``` app. + + - If you want to use builtin PC controller, provide HCI index of the controller. Turn the Bluetooth ON on your device, run ```hciconfig``` in the terminal and get the HCI index. In the case below HCI index is equal to 0: + +``` +user@user:~$ hciconfig +hci0: Type: Primary Bus: USB + BD Address: 64:BC:58:E2:9C:52 ACL MTU: 1021:4 SCO MTU: 96:6 + UP RUNNING + RX bytes:20003 acl:0 sco:0 events:3176 errors:0 + TX bytes:771246 acl:0 sco:0 commands:3174 errors:0 +``` + + - If you want to use the nimble controller, create the image and load the provided target (can be found under ```/targets``` for NRF52840 and NRF52832). + - NRF52840 may use USB or UART transport. The target is configured for USB by default. + - NRF52832 uses UART as transport. This requires some additional configuration. Get the tty path and run in the terminal: + ``` + sudo btattach -B /dev/ttyACM0 -S 1000000 + ``` + Then proceed with ```hciconfig``` as shown above. + +### Run tests +This tool opens a raw socket which requires running all scripts as ```sudo```. Copy the ```config.yaml.sample``` file, change the name to ```config.yaml``` and fill the parameters. Run ```main.py``` as shown below: +``` +sudo python main.py -i -m rx tx -cf config.yaml +``` +Switch `````` and `````` to corresponding hci indexes present in your computer. ```-m``` and ```-cf``` may be omitted if the defaults are correct. \ +The output provides the plots of measured throughput in ```kb``` or ```kB``` as predefined in ```config.yaml```. In addition to the throughput plots, when the ```flag_plot_packets``` is turned on, the number of packets transmitted/received in time is visualized. + +#### Set ```config.yaml``` file +To run **once** the throughput measurement with given parameters, set the ```flag_testing``` to false. +``` +flag_testing: false +``` + +To run the throughput measurements **more than once** with the same parameters and to generate the plot of average throughputs, set ```config.yaml``` as shown below: +``` +show_tp_plots: false +flag_testing: true +test: + change_param_group: null + change_param_variable: null + start_value: 0 + stop_value: 5 + step: 1 +``` +This configuration provides 5 measurements. The ```show_tp_plots``` flag is optionally set as ```false``` for speed, changing it to ```true``` will trigger rx and tx throughput plots at the end of every iteration. + +To run the throughput measurement with some parameters changing within tests, fill config as below: +``` +flag_testing: true +test: + change_param_group: + - conn + - conn + change_param_variable: + - connection_interval_min + - connection_interval_max + start_value: 0x000A + stop_value: 0x0320 + step: 20 +``` +This will run each test incrementing ```connection_interval_min``` and ```connection_interval_max``` by 20. the final plot will show the influence of the parameters change on the average throughput. + +## Tools +The ```main.py``` script usees all tools mentioned below and it is advised to use it above all. Nevertheless, the sub-tools may be used separately as shown below. + +### HCI device sub-tool +```hci_device.py``` is a tool that manages one hci device. User can provide parameters and run it as receiver or transmitter as shown below: +``` +sudo python hci_device.py -m rx -oa 00:00:00:00:00:00 -oat 0 -di 0 -pa 00:00:00:00:00:00 -pat 0 -pdi 0 -cf config.yaml +``` +Run ```python hci_device.py --help``` for parameters description. \ +If properly configured ```init.yaml``` is present (it is created automatically while running ```main.py```), the script can be run like this: + +``` +sudo python hci_device.py -m tx -if init.yaml +``` + +### Check addr sub-tool +When given hci indexes, ```check_addr.py``` returns devices' address types and addresses. +``` +sudo python check_addr.py -i ... +``` + +### Throughput sub-tool +The timestamps of the received packets are stored in csv files (```tp_receiver.csv``` and ```tp_transmitter.csv``` by default). If the program stopped in the middle of the measurements, you can still plot the values and get the average througput. Provide the filename, sample time and run the tool as shown below: +``` +python throughput.py -f tp_receiver -s 0.1 +``` diff --git a/tools/hci_throughput/check_addr.py b/tools/hci_throughput/check_addr.py new file mode 100644 index 0000000000..a11a416d8f --- /dev/null +++ b/tools/hci_throughput/check_addr.py @@ -0,0 +1,104 @@ +# +# 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. +# + +import argparse +import asyncio +import hci_commands +import sys +import logging +import hci +import traceback +import util +import transport_factory + +def parse_arguments(): + parser = argparse.ArgumentParser( + description='Check HCI device address type and address', + epilog='How to run script: \ + sudo python check_addr.py -i 0 1 2') + parser.add_argument('-i', '--indexes', type=str, nargs='*', + help='specify hci adapters indexes', default=0) + try: + args = parser.parse_args() + except Exception as e: + print(traceback.format_exc()) + return args + +async def main(dev: hci_commands.HCI_Commands): + result = tuple() + task = asyncio.create_task(dev.rx_buffer_q_wait()) + await dev.cmd_reset() + await dev.cmd_read_bd_addr() + + if hci.bdaddr != '00:00:00:00:00:00': + logging.info("Type public: %s, address: %s", hci.PUBLIC_ADDRESS_TYPE, hci.bdaddr) + result = (0, hci.bdaddr) + print("Public address: ", result) + else: + await dev.cmd_vs_read_static_addr() + if hci.static_addr != '00:00:00:00:00:00': + logging.info("Type static random: %s, address: %s", hci.STATIC_RANDOM_ADDRESS_TYPE, hci.static_addr) + result = (1, hci.static_addr) + print("Static random address: ", result) + else: + addr = hci.gen_static_rand_addr() + logging.info("Type static random: %s, generated address: %s", hci.STATIC_RANDOM_ADDRESS_TYPE, addr) + result = (1, addr) + print("Generated static random address: ", result) + task.cancel() + return result + +def check_addr(device_indexes: list, addresses: list) -> list: + util.configure_logging(f"log/check_addr.log", clear_log_file=True) + + logging.info(f"Devices indexes: {device_indexes}") + for index in device_indexes: + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + loop.set_debug(True) + + transport = transport_factory.TransportFactory(device_index=index, + asyncio_loop=loop) + + bt_dev = hci_commands.HCI_Commands(send=transport.send, + rx_buffer_q=transport.rx_buffer_q, + asyncio_loop=loop) + + transport.start() + + addresses.append(loop.run_until_complete(main(bt_dev))) + + transport.stop() + loop.close() + + logging.info(f"Finished: {addresses}") + return addresses + + +if __name__ == '__main__': + try: + args = parse_arguments() + print(args) + addresses = [] + addresses = check_addr(args.indexes, addresses) + print(addresses) + except Exception as e: + print(traceback.format_exc()) + finally: + sys.exit() diff --git a/tools/hci_throughput/config.yaml.sample b/tools/hci_throughput/config.yaml.sample new file mode 100644 index 0000000000..7a8330075c --- /dev/null +++ b/tools/hci_throughput/config.yaml.sample @@ -0,0 +1,55 @@ +# +# 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. +# + +num_of_bytes_to_send: 247 +num_of_packets_to_send: 2000 +show_tp_plots: true +flag_testing: false +test: + change_param_group: + - conn + - conn + change_param_variable: + - connection_interval_min + - connection_interval_max + start_value: 16 + stop_value: 160 + step: 8 +tp: + data_type: kb + sample_time: 0.1 + flag_plot_packets: true +phy: 2M +adv: + advertising_interval_min: 2048 + advertising_interval_max: 2048 + advertising_type: 0 + peer_address: 00:00:00:00:00:00 + advertising_channel_map: 7 + advertising_filter_policy: 0 +conn: + le_scan_interval: 2400 + le_scan_window: 2400 + initiator_filter_policy: 0 + connection_interval_min: 0x0080 + connection_interval_max: 0x0080 + max_latency: 0 + supervision_timeout: 3200 + min_ce_length: 0 + max_ce_length: 0 \ No newline at end of file diff --git a/tools/hci_throughput/hci.py b/tools/hci_throughput/hci.py new file mode 100644 index 0000000000..072e395e8c --- /dev/null +++ b/tools/hci_throughput/hci.py @@ -0,0 +1,605 @@ +# +# 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. +# + +from dataclasses import dataclass +import struct +from binascii import unhexlify +import random + +############ +# DEFINES +############ +AF_BLUETOOTH = 31 +HCI_CHANNEL_USER = 1 +HCI_COMMAND_PACKET = 0x01 +HCI_ACL_DATA_PACKET = 0x02 +HCI_EVENT_PACKET = 0x04 + +HCI_EV_CODE_DISCONN_CMP = 0x05 +HCI_EV_CODE_CMD_CMP = 0x0e +HCI_EV_CODE_CMD_STATUS = 0x0f +HCI_EV_CODE_LE_META_EVENT = 0x3e +HCI_SUBEV_CODE_LE_ENHANCED_CONN_CMP = 0x0a +HCI_SUBEV_CODE_LE_DATA_LEN_CHANGE = 0x07 +HCI_SUBEV_CODE_LE_PHY_UPDATE_CMP = 0x0c +HCI_SUBEV_CODE_LE_CHAN_SEL_ALG = 0x14 +HCI_EV_NUM_COMP_PKTS = 0x13 + +CONN_FAILED_TO_BE_ESTABLISHED = 0x3e +CONN_TIMEOUT = 0x08 + +OGF_HOST_CTL = 0x03 +OCF_SET_EVENT_MASK = 0x0001 +OCF_RESET = 0X0003 + +OGF_INFO_PARAM = 0x04 +OCF_READ_LOCAL_COMMANDS = 0x0002 +OCF_READ_BD_ADDR = 0x0009 + +OGF_LE_CTL = 0x08 +OCF_LE_SET_EVENT_MASK = 0x0001 +OCF_LE_READ_BUFFER_SIZE_V1 = 0x0002 +OCF_LE_READ_BUFFER_SIZE_V2 = 0x0060 +OCF_LE_SET_RANDOM_ADDRESS = 0x0005 +OCF_LE_SET_ADVERTISING_PARAMETERS = 0x0006 +OCF_LE_SET_ADVERTISE_ENABLE = 0x000a +OCF_LE_SET_SCAN_PARAMETERS = 0x000b +OCF_LE_SET_SCAN_ENABLE = 0x000c +OCF_LE_CREATE_CONN = 0x000d +OCF_LE_SET_DATA_LEN = 0x0022 +OCF_LE_READ_SUGGESTED_DFLT_DATA_LEN = 0x0023 +OCF_LE_READ_MAX_DATA_LEN = 0x002f +OCF_LE_READ_PHY = 0x0030 +OCF_LE_SET_DFLT_PHY = 0x0031 +OCF_LE_SET_PHY = 0x0032 + +OGF_VENDOR_SPECIFIC = 0x003f +BLE_HCI_OCF_VS_RD_STATIC_ADDR = 0x0001 + +PUBLIC_ADDRESS_TYPE = 0 +STATIC_RANDOM_ADDRESS_TYPE = 1 + +WAIT_FOR_EVENT_TIMEOUT = 5 +WAIT_FOR_EVENT_CONN_TIMEOUT = 25 + +############ +# GLOBAL VAR +############ +num_of_bytes_to_send = None # based on supported_max_tx_octets +num_of_packets_to_send = None + +events_list = [] +bdaddr = '00:00:00:00:00:00' +static_addr = '00:00:00:00:00:00' +le_read_buffer_size = None +conn_handle = 0 +requested_tx_octets = 1 +requested_tx_time = 1 +suggested_dflt_data_len = None +max_data_len = None +phy = None +ev_num_comp_pkts = None +num_of_completed_packets_cnt = 0 +num_of_completed_packets_time = 0 + +############ +# FUNCTIONS +############ +def get_opcode(ogf: int, ocf: int): + return ((ocf & 0x03ff)|(ogf << 10)) + +def get_ogf_ocf(opcode: int): + ogf = opcode >> 10 + ocf = opcode & 0x03ff + return ogf, ocf + +def cmd_addr_to_ba(addr_str: str): + return unhexlify("".join(addr_str.split(':')))[::-1] + +def ba_addr_to_str(addr_ba: bytearray): + addr_str = addr_ba.hex().upper() + return ':'.join(addr_str[i:i+2] for i in range(len(addr_str), -2, -2))[1:] + +def gen_static_rand_addr(): + while True: + x = [random.randint(0,1) for _ in range(0,48)] + + if 0 in x[:-2] and 1 in x[:-2]: + x[0] = 1 + x[1] = 1 + break + addr_int = int("".join([str(x[i]) for i in range(0,len(x))]), 2) + addr_hex = "{0:0{1}x}".format(addr_int, 12) + addr = ":".join(addr_hex[i:i+2] for i in range(0, len(addr_hex), 2)) + return addr.upper() + +############ +# GLOBAL VAR CLASSES +############ +@dataclass +class Suggested_Dflt_Data_Length(): + status: int + suggested_max_tx_octets: int + suggested_max_tx_time: int + + def __init__(self): + self.set() + + def set(self, status=0, suggested_max_tx_octets=0, suggested_max_tx_time=0): + self.status = status + self.suggested_max_tx_octets = suggested_max_tx_octets + self.suggested_max_tx_time = suggested_max_tx_time + +@dataclass +class Max_Data_Length(): + status: int + supported_max_tx_octets: int + supported_max_tx_time: int + supported_max_rx_octets: int + supported_max_rx_time: int + + def __init__(self): + self.set() + + def set(self, status=0, supported_max_tx_octets=0, supported_max_tx_time=0, + supported_max_rx_octets=0, supported_max_rx_time=0): + self.status = status + self.supported_max_tx_octets = supported_max_tx_octets + self.supported_max_tx_time = supported_max_tx_time + self.supported_max_rx_octets = supported_max_rx_octets + self.supported_max_rx_time = supported_max_rx_time + +@dataclass +class LE_Read_Buffer_Size: + status: int + le_acl_data_packet_length: int + total_num_le_acl_data_packets: int + iso_data_packet_len: int + total_num_iso_data_packets: int + + def __init__(self): + self.set() + + def set(self, status=0, le_acl_data_packet_length=0, + total_num_le_acl_data_packets=0, iso_data_packet_len=0, + total_num_iso_data_packets=0): + self.status = status + self.le_acl_data_packet_length = le_acl_data_packet_length + self.total_num_le_acl_data_packets = total_num_le_acl_data_packets + self.iso_data_packet_len = iso_data_packet_len + self.total_num_iso_data_packets = total_num_iso_data_packets + +@dataclass +class LE_Read_PHY: + status: int + connection_handle: int + tx_phy: int + rx_phy: int + + def __init__(self): + self.set() + + def set(self, status=0, connection_handle=0, tx_phy=0, rx_phy=0): + self.status = status + self.connection_handle = connection_handle + self.tx_phy = tx_phy + self.rx_phy = rx_phy + + +############ +# EVENTS +############ + +@dataclass +class HCI_Ev_Disconn_Complete: + status: int + connection_handle: int + reason: int + + def __init__(self): + self.set() + + def set(self, status=0, connection_handle=0, reason=0): + self.status = status + self.connection_handle = connection_handle + self.reason = reason + +@dataclass +class HCI_Ev_Cmd_Complete: + num_hci_command_packets: int + opcode: int + return_parameters: int + + def __init__(self): + self.set() + + def set(self, num_hci_cmd_packets=0, opcode=0, return_parameters=b''): + self.num_hci_command_packets = num_hci_cmd_packets + self.opcode = opcode + self.return_parameters = return_parameters + +@dataclass +class HCI_Ev_Cmd_Status: + status: int + num_hci_command_packets: int + opcode: int + + def __init__(self): + self.set() + + def set(self, status = 0, num_hci_cmd_packets=0, opcode=0): + self.status = status + self.num_hci_command_packets = num_hci_cmd_packets + self.opcode = opcode + +@dataclass +class HCI_Ev_LE_Meta: + subevent_code: int + + def __init__(self): + self.set() + + def set(self, subevent_code=0): + self.subevent_code = subevent_code + + +@dataclass +class HCI_Ev_LE_Enhanced_Connection_Complete(HCI_Ev_LE_Meta): + status: int + connection_handle: int + role: int + peer_address_type: int + peer_address: str + local_resolvable_private_address: int + peer_resolvable_private_address: int + connection_interval: int + peripheral_latency: int + supervision_timeout: int + central_clock_accuracy: int + + def __init__(self): + self.set() + + def set(self, subevent_code=0, status=0, connection_handle=0, role=0, + peer_address_type=0, peer_address='00:00:00:00:00:00', + local_resolvable_private_address='00:00:00:00:00:00', + peer_resolvable_private_address='00:00:00:00:00:00', + connection_interval=0, peripheral_latency=0, supervision_timeout=0, + central_clock_accuracy=0): + super().set(subevent_code) + self.status = status + self.connection_handle = connection_handle + self.role = role + self.peer_address_type = peer_address_type + self.peer_address = peer_address + self.local_resolvable_private_address = local_resolvable_private_address + self.peer_resolvable_private_address = peer_resolvable_private_address + self.connection_interval = connection_interval + self.peripheral_latency = peripheral_latency + self.supervision_timeout = supervision_timeout + self.central_clock_accuracy = central_clock_accuracy + +@dataclass +class HCI_Ev_LE_Data_Length_Change(HCI_Ev_LE_Meta): + conn_handle: int + max_tx_octets: int + max_tx_time: int + max_rx_octets: int + max_rx_time: int + triggered: int + + def __init__(self): + self.set() + + def set(self, subevent_code=0, conn_handle=0, max_tx_octets=0, + max_tx_time=0, max_rx_octets=0, max_rx_time=0, triggered=0): + super().set(subevent_code) + self.conn_handle = conn_handle + self.max_tx_octets = max_tx_octets + self.max_tx_time = max_tx_time + self.max_rx_octets = max_rx_octets + self.max_rx_time = max_rx_time + self.triggered = triggered + +@dataclass +class HCI_Ev_LE_PHY_Update_Complete(HCI_Ev_LE_Meta): + status: int + connection_handle: int + tx_phy: int + rx_phy: int + + def __init__(self): + self.set() + + def set(self, subevent_code=0, status=0, connection_handle=0, + tx_phy=0, rx_phy=0): + super().set(subevent_code) + self.status = status + self.connection_handle = connection_handle + self.tx_phy = tx_phy + self.rx_phy = rx_phy + +@dataclass +class HCI_Number_Of_Completed_Packets: + num_handles: int + connection_handle: int + num_completed_packets: int + + def __init__(self): + self.set() + + def set(self, num_handles=0, connection_handle=0, num_completed_packets=0): + self.num_handles = num_handles + self.connection_handle = connection_handle + self.num_completed_packets = num_completed_packets + +class HCI_Ev_LE_Chan_Sel_Alg(HCI_Ev_LE_Meta): + connection_handle: int + algorithm: int + + def __init__(self): + self.set() + + def set(self, subevent_code=0, connection_handle=0, algorithm=0): + super().set(subevent_code) + self.connection_handle = connection_handle + self.algorithm = algorithm + +############ +# PARAMETERS +############ +@dataclass +class HCI_Advertising: + advertising_interval_min: int + advertising_interval_max: int + advertising_type: int + own_address_type: int + peer_address_type: int + peer_address: str + advertising_channel_map: int + advertising_filter_policy: int + ba_full_message: bytearray + + def __init__(self): + self.set() + + def set(self, advertising_interval_min=0, advertising_interval_max=0, \ + advertising_type=0, own_address_type=0, peer_address_type=0, \ + peer_address='00:00:00:00:00:00', advertising_channel_map=0, \ + advertising_filter_policy=0): + self.advertising_interval_min = advertising_interval_min + self.advertising_interval_max = advertising_interval_max + self.advertising_type = advertising_type + self.own_address_type = own_address_type + self.peer_address_type = peer_address_type + self.peer_address = peer_address + self.advertising_channel_map = advertising_channel_map + self.advertising_filter_policy = advertising_filter_policy + self.ba_full_message = bytearray(struct.pack(' int: + current_ev_name = type(self.hci_recv_ev_packet.current_event).__name__ + if current_ev_name == type(hci.HCI_Ev_Cmd_Complete()).__name__: + return struct.unpack_from(" hci.max_data_len.supported_max_tx_octets - 4): + logging.critical(f"Number of bytes to send: {hci.num_of_bytes_to_send}\ + not supported. Closing.") + raise SystemExit("Number of bytes to send not supported. Closing.") + + return status() + elif ocf == hci.OCF_LE_READ_PHY: + hci.phy = hci.LE_Read_PHY() + hci.phy.set(*struct.unpack('> 12 + bc_flag = (handle_pb_bc_flags & 0xC000) >> 14 + + hci_recv_acl_data_packet = hci.HCI_Recv_ACL_Data_Packet() + + if pb_flag == 0b10: + l2cap_data = hci.HCI_Recv_L2CAP_Data() + data = buffer[5:] + l2cap_data.set(*struct.unpack(" self.tp.sample_time \ + # or packet_number == 0 \ + # or packet_number == self.tp.total_packets_number-1: + # self.tp.record_throughput(packet_number, timestamp) + # self.last_timestamp = timestamp + + if packet_number >= self.tp.total_packets_number - 1: + self.async_ev_recv_data_finish.set() + + def handle_acl_data(self, buffer: bytes, timestamp: int): + hci_recv_acl_data_packet = self.parse_acl_data(buffer) + logging.debug("%s", hci_recv_acl_data_packet) + recv_data_type = type(hci_recv_acl_data_packet.data).__name__ + if recv_data_type == 'HCI_Recv_L2CAP_Data': + self.match_recv_l2cap_data(buffer, timestamp) + + async def recv_handler(self): + while not self.rx_buffer_q.empty(): + q_buffer_item, q_timestamp = self.rx_buffer_q.get() + packet_type = struct.unpack(' 0 and packets_to_send > 0: + data, last_value = tp.gen_data(hci.num_of_bytes_to_send, last_value) + l2cap_data.set(channel_id=0x0044, data=data) + acl_data.set(connection_handle=hci.conn_handle, pb_flag=0b00, bc_flag=0b00, + data=l2cap_data.ba_full_message) + await bt_dev.acl_data_send(acl_data) + async with bt_dev.async_lock_packets_cnt: + packets_to_send -= 1 + packet_credits -= 1 + else: + logging.info(f"Waiting for num_of_cmp_packets event") + await bt_dev.async_ev_num_cmp_pckts.wait() + bt_dev.async_ev_num_cmp_pckts.clear() + + if hci.num_of_completed_packets_cnt > 0: + async with bt_dev.async_lock_packets_cnt: + sent_packets += hci.num_of_completed_packets_cnt + tx_sent_timestamps.append((hci.num_of_completed_packets_time, + sent_packets)) + logging.info(f"Sent : {sent_packets}") + + packet_credits += hci.num_of_completed_packets_cnt + hci.num_of_completed_packets_cnt = 0 + + + for timestamp in tx_sent_timestamps: + bt_dev.tp.append_to_csv_file(*timestamp) + + await finish(bt_dev, cfg) + + +def parse_cfg_files(args) -> dict: + if args.init_file is None: + ini = { + "own_address": args.own_addr, + "own_address_type": args.own_addr_type, + "dev_index": str(args.dev_idx), + "peer_address": args.peer_addr, + "peer_address_type": args.peer_addr_type, + "peer_dev_index": args.peer_dev_idx + } + else: + with open(args.init_file, "r") as file: + init_file = yaml.safe_load(file) + ini = init_file[args.mode] + global test_dir + test_dir = init_file["test_dir"] + + with open(args.config_file) as f: + cfg = yaml.safe_load(f) + + global show_tp_plots + + hci.num_of_bytes_to_send = cfg["num_of_bytes_to_send"] + hci.num_of_packets_to_send = cfg["num_of_packets_to_send"] + show_tp_plots = cfg["show_tp_plots"] + + return ini, cfg + + +def signal_handler(signum, frame): + logging.critical(f"Received signal: {signal.Signals(signum).name}") + raise ParentCalledException(f"Received signal: {signal.Signals(signum).name}") + + +def main(): + args = parse_arguments() + ini, cfg = parse_cfg_files(args) + log_path = f"log/log_{args.mode}.log" + transport = None + + try: + util.configure_logging(log_path, clear_log_file=True) + + loop = asyncio.get_event_loop() + loop.set_debug(True) + + transport = transport_factory.TransportFactory(device_index=ini['dev_index'], + device_mode=args.mode, + asyncio_loop=loop) + + signal.signal(signal.SIGTERM, signal_handler) + + bt_dev = hci_commands.HCI_Commands(send=transport.send, + rx_buffer_q=transport.rx_buffer_q, + asyncio_loop=loop, + device_mode=args.mode) + + transport.start() + + if args.mode == 'rx': + loop.run_until_complete(async_main_rx(bt_dev, ini, cfg)) + elif args.mode == 'tx': + loop.run_until_complete(async_main_tx(bt_dev, ini, cfg)) + + + except Exception as e: + logging.error(traceback.format_exc()) + except (KeyboardInterrupt or ParentCalledException): + logging.critical("Hard exit triggered.") + logging.error(traceback.format_exc()) + finally: + if transport != None: + transport.stop() + sys.exit() + + +if __name__ == '__main__': + main() diff --git a/tools/hci_throughput/hci_socket.py b/tools/hci_throughput/hci_socket.py new file mode 100644 index 0000000000..f95ea86573 --- /dev/null +++ b/tools/hci_throughput/hci_socket.py @@ -0,0 +1,164 @@ +# +# 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. +# + +import hci +import socket +import ctypes +import struct +import asyncio +import logging +import subprocess +import sys +import time +import multiprocessing + + +SOCKET_RECV_BUFFER_SIZE = 425984 +SOCKET_RECV_TIMEOUT = 3 + + +def btmgmt_dev_reset(index): + logging.info(f"Selecting index {index}") + proc = subprocess.Popen(['btmgmt', '-i', str(index), 'power', 'off'], + shell=False, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + proc.communicate() + + +class BindingError(Exception): + pass + + +class HCI_User_Channel_Socket_Error(BaseException): + pass + + +class HCI_User_Channel_Socket(): + def __init__(self, device_index=0, device_mode=None, + asyncio_loop=None): + logging.debug("Device index: %s, Device address: %s", device_index, device_mode) + self.loop = asyncio_loop + self.libc = ctypes.cdll.LoadLibrary('libc.so.6') + self.rx_buffer_q = multiprocessing.Manager().Queue() + self.counter = 0 + + self.device_index = device_index + self.device_mode = device_mode + self.hci_socket = self.socket_create() + self.socket_bind(self.device_index) + self.socket_clear() + self.listener_proc = None + self.listener_ev = multiprocessing.Manager().Event() + + def socket_create(self): + logging.debug("%s", self.socket_create.__name__) + new_socket = socket.socket(socket.AF_BLUETOOTH, + socket.SOCK_RAW | socket.SOCK_NONBLOCK, + socket.BTPROTO_HCI) + if new_socket == None: + raise HCI_User_Channel_Socket_Error("Socket error. \ + Opening socket failed") + new_socket.setblocking(False) + socket_size = new_socket.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF) + logging.info(f"Default socket recv buffer size: {socket_size}") + new_socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 500000) + socket_size = new_socket.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF) + logging.info(f"Set socket recv buffer size: {socket_size}") + return new_socket + + def socket_bind(self, index): + logging.debug("%s index: %s", self.socket_bind.__name__, index) + # addr: struct sockaddr_hci from /usr/include/bluetooth/hci.h + addr = struct.pack('HHH', hci.AF_BLUETOOTH, index, hci.HCI_CHANNEL_USER) + retry_binding=2 + for i in range(retry_binding): + try: + bind = self.libc.bind(self.hci_socket.fileno(), + ctypes.cast(addr, + ctypes.POINTER(ctypes.c_ubyte)), + len(addr)) + if bind != 0: + raise BindingError + except BindingError: + logging.warning("Binding error. Trying to reset bluetooth.") + btmgmt_dev_reset(self.device_index) + if i < retry_binding - 1: + continue + else: + self.hci_socket.close() + logging.error("Binding error. Check HCI index present.") + sys.exit() + logging.info("Binding done!") + break + + def socket_clear(self): + logging.debug("%s", self.socket_clear.__name__) + try: + logging.info("Clearing the buffer...") + time.sleep(1) + cnt = 0 + while True: + buff = self.hci_socket.recv(SOCKET_RECV_BUFFER_SIZE) + cnt += len(buff) + logging.debug(f"Read from buffer {cnt} bytes") + except BlockingIOError: + logging.info("Buffer empty and ready!") + return + + async def send(self, ba_message): + await self.loop.sock_sendall(self.hci_socket, ba_message) + + def socket_listener(self): + recv_at_once = 0 + while True: + try: + if self.listener_ev.is_set(): + logging.info("listener_ev set") + break + buffer = self.hci_socket.recv(SOCKET_RECV_BUFFER_SIZE) + logging.info(f"Socket recv: {self.counter} th packet with len: {len(buffer)}") + self.rx_buffer_q.put((buffer, time.perf_counter())) + recv_at_once +=1 + self.counter +=1 + + except BlockingIOError: + if recv_at_once > 1: + logging.info(f"Socket recv in one loop: {recv_at_once}") + recv_at_once = 0 + pass + except BrokenPipeError: + logging.info("BrokenPipeError: Closing...") + print("BrokenPipeError. Press Ctrl-C to exit...") + + def close(self): + logging.debug("%s ", self.close.__name__) + return self.hci_socket.close() + + def start(self): + self.listener_proc = multiprocessing.Process(target=self.socket_listener, + daemon=True) + self.listener_proc.start() + logging.info(f"start listener_proc pid: {self.listener_proc.pid}") + + def stop(self): + logging.info(f"stop listener_proc pid: {self.listener_proc.pid}") + self.listener_ev.set() + self.listener_proc.join() + self.close() diff --git a/tools/hci_throughput/init.yaml.sample b/tools/hci_throughput/init.yaml.sample new file mode 100644 index 0000000000..ec17522767 --- /dev/null +++ b/tools/hci_throughput/init.yaml.sample @@ -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. +# + +rx: + dev_index: '1' + own_address_type: 1 + own_address: C0:0D:A5:1A:98:EF + peer_dev_index: '2' + peer_address_type: 1 + peer_address: FE:69:8F:77:2F:49 +tx: + dev_index: '2' + own_address_type: 1 + own_address: FE:69:8F:77:2F:49 + peer_dev_index: '1' + peer_address_type: 1 + peer_address: C0:0D:A5:1A:98:EF +test_dir: /path/to/blehci_throughput/tests/Mon_May_23_12:29:10_2022 diff --git a/tools/hci_throughput/log/.gitignore b/tools/hci_throughput/log/.gitignore new file mode 100644 index 0000000000..c96a04f008 --- /dev/null +++ b/tools/hci_throughput/log/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/tools/hci_throughput/main.py b/tools/hci_throughput/main.py new file mode 100644 index 0000000000..bbaf4d7cd6 --- /dev/null +++ b/tools/hci_throughput/main.py @@ -0,0 +1,243 @@ +# +# 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. +# + +import multiprocessing +import check_addr +import argparse +import yaml +import sys +import subprocess +import traceback +import matplotlib.pyplot as plt +import csv +import util +import os +import math + +PROCESS_TIMEOUT = 500 # seconds, adjust if necessary + +def parse_arguments(): + parser = argparse.ArgumentParser( + description='Measure throughput', + epilog='How to run python scripts: \ + sudo python main.py -i 0 1 -m rx tx -cf config.yaml\ + then hci0 -> rx and hci1 -> tx') + parser.add_argument('-i', '--indexes', type=str, nargs='*', + help='specify adapters indexes', default=[0, 1]) + parser.add_argument('-m', '--modes', type=str, nargs="*", + help='devices modes - receiver, transmitter', + choices=['rx', 'tx'], default=['rx', 'tx']) + parser.add_argument('-cf', '--config_file', type=str, nargs="*", + help='configuration file for devices', + default=["config.yaml"]) + try: + args = parser.parse_args() + except Exception as e: + print(traceback.format_exc()) + + print(f"Indexes: {args.indexes}") + print(f"Modes: {args.modes}") + + return args + + +def get_dev_addr_and_type(hci_indexes: list): + if (len(hci_indexes) != 2): + raise Exception("HCI index error.") + manager = multiprocessing.Manager() + addr_list = manager.list() + check_addrs_proc = multiprocessing.Process(target=check_addr.check_addr, + name="Check addresses", + args=(hci_indexes, addr_list)) + check_addrs_proc.start() + print("check_addrs_proc pid: ", check_addrs_proc.pid) + check_addrs_proc.join() + dev_addr_type_list = [] + for i in range(0, len(addr_list)): + dev_addr_type_list.append((hci_indexes[i],) + addr_list[i]) + return dev_addr_type_list + + +def change_config_var(filename: str, group: str, variable: str, + new_value: int): + with open(filename, "r") as file: + cfg = yaml.safe_load(file) + + if group: + cfg[group][variable] = new_value + else: + cfg[variable] = new_value + + with open(filename, "w") as file: + yaml.safe_dump(cfg, file, indent=1, sort_keys=False, + default_style=None, default_flow_style=False) + + +def get_init_dict(filename: str, args_list: list, modes: list, dir: str): + ini = { + modes[0]:{ + "dev_index": args_list[0][0], + "own_address_type": args_list[0][1], + "own_address": args_list[0][2], + "peer_dev_index": args_list[1][0], + "peer_address_type": args_list[1][1], + "peer_address": args_list[1][2] + }, + modes[1]:{ + "dev_index": args_list[1][0], + "own_address_type": args_list[1][1], + "own_address": args_list[1][2], + "peer_dev_index": args_list[0][0], + "peer_address_type": args_list[0][1], + "peer_address": args_list[0][2] + }, + "test_dir": dir + } + + with open(filename, 'w') as file: + yaml.safe_dump(ini, file, indent=1, sort_keys=False) + + return ini + + +def run_once(modes: list, cfg_file: str, init_file: str): + list_proc = [] + for mode in modes: + proc = subprocess.Popen(["python", "hci_device.py", "-m", + mode, "-if", init_file, "-cf", cfg_file]) + print("start subprocess pid: ", proc.pid) + list_proc.append(proc) + try: + for proc in list_proc: + proc.wait(PROCESS_TIMEOUT) + except subprocess.TimeoutExpired: + for proc in list_proc: + print("TimeoutExpired subprocess pid: ", proc.pid) + proc.terminate() + for proc in list_proc: + proc.wait() + return -1 + + for proc in list_proc: + print("stop subprocess pid: ", proc.pid) + proc.terminate() + proc.wait() + return 0 + + +def testing_variable_influence(cfg: dict, modes: list, cfg_file: str, + init_file: str, init_dict: dict, save_to_file: bool): + tp_test_counter = 1 + changed_params_list = [] + averages = [] + cfg_group = cfg["test"]["change_param_group"] + cfg_variable = cfg["test"]["change_param_variable"] + cfg_start_val = cfg["test"]["start_value"] + cfg_stop_val = cfg["test"]["stop_value"] + cfg_step = cfg["test"]["step"] + data_type = cfg["tp"]["data_type"] + total_iterations = math.ceil((cfg_stop_val - cfg_start_val) / cfg_step) + average_tp_csv_path = init_dict["test_dir"] + "/average_rx_tp.csv" + + with open(average_tp_csv_path, "w") as file: + file.write(f"Average throughput [{data_type}ps]\n") + + for i in range(cfg_start_val, cfg_stop_val, cfg_step): + changed_params_list.append(i) + + if cfg_group and cfg_variable: + print(f"Current param value: {i}") + num_of_params_to_change = len(cfg_variable) + + for j in range(0, num_of_params_to_change): + change_config_var(filename=cfg_file, group=cfg_group[j], + variable=cfg_variable[j], new_value=i) + + print(f"Running test: {tp_test_counter}/{total_iterations}...") + rc = run_once(modes, cfg_file, init_file) + if rc != 0: + print(f"Test {i} failed. Closing...") + return + + tp_test_counter += 1 + + with open(average_tp_csv_path, "r") as file: + csv_reader = csv.reader(file) + next(csv_reader) + for row in csv_reader: + averages.append(float(*row)) + + fig, ax = plt.subplots() + ax.plot(changed_params_list[:len(averages)], averages, '-k') + ax.set_ylabel(f"Average throughput [{data_type}/s]") + ax.set_xlabel("Changed parameter/next iteration") + ax.set_title("Average througput") + + if save_to_file: + name = init_dict["test_dir"] + "/average_tps" + plt.savefig(fname=name, format='png') + + plt.show(block=True) + + +def main(): + args = parse_arguments() + + init_file = "init.yaml" + cfg_file = args.config_file[0] + + with open(cfg_file, "r") as file: + cfg = yaml.safe_load(file) + + addr_list = get_dev_addr_and_type(args.indexes) + if len(addr_list) != len(args.indexes): + raise Exception("No device address received. Check HCI indexes.") + print(f"Received: {addr_list}") + + test_dir_path = util.create_test_directory() + init_dict = get_init_dict(filename=init_file, args_list=addr_list, + modes=args.modes, dir=test_dir_path) + + util.copy_config_files_to_test_directory([init_file, cfg_file], + init_dict["test_dir"]) + + try: + if cfg["flag_testing"]: + testing_variable_influence(cfg, args.modes, *args.config_file, + init_file, init_dict, True) + else: + print(f"Running test...") + rc = run_once(args.modes, cfg_file, init_file) + if rc != 0: + print("Test failed.") + + print("Finished. Closing...") + + except KeyboardInterrupt: + pass + except Exception as e: + print(traceback.format_exc()) + finally: + # Set default ownership for dirs and files + util.set_default_chmod_recurs(os.getcwd() + "/tests") + sys.exit() + + +if __name__ == "__main__": + main() diff --git a/tools/hci_throughput/requirements.txt b/tools/hci_throughput/requirements.txt new file mode 100644 index 0000000000..8b2a114e44 --- /dev/null +++ b/tools/hci_throughput/requirements.txt @@ -0,0 +1,3 @@ +matplotlib==3.1.2 +PyYAML==6.0 +libusb1 \ No newline at end of file diff --git a/tools/hci_throughput/targets/nordic_pca10040_blehci/pkg.yml b/tools/hci_throughput/targets/nordic_pca10040_blehci/pkg.yml new file mode 100644 index 0000000000..9cd3540e7d --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10040_blehci/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: tools/hci_throughput/targets/nordic_pca10040_blehci +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: diff --git a/tools/hci_throughput/targets/nordic_pca10040_blehci/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10040_blehci/syscfg.yml new file mode 100644 index 0000000000..4de2fdd2c2 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10040_blehci/syscfg.yml @@ -0,0 +1,28 @@ +# +# 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. +# + +syscfg.vals: + BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 + MSYS_1_BLOCK_COUNT: 80 + MSYS_1_BLOCK_SIZE: 308 + BLE_TRANSPORT_ACL_COUNT: 80 + BLE_TRANSPORT_ACL_SIZE: 255 + diff --git a/tools/hci_throughput/targets/nordic_pca10040_blehci/target.yml b/tools/hci_throughput/targets/nordic_pca10040_blehci/target.yml new file mode 100644 index 0000000000..f9d6d0fb02 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10040_blehci/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10040" +target.build_profile: optimized diff --git a/tools/hci_throughput/targets/nordic_pca10040_boot/pkg.yml b/tools/hci_throughput/targets/nordic_pca10040_boot/pkg.yml new file mode 100644 index 0000000000..dfcb1b63b7 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10040_boot/pkg.yml @@ -0,0 +1,6 @@ +pkg.name: targets/nordic_pca10040_boot +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/tools/hci_throughput/targets/nordic_pca10040_boot/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10040_boot/syscfg.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/hci_throughput/targets/nordic_pca10040_boot/target.yml b/tools/hci_throughput/targets/nordic_pca10040_boot/target.yml new file mode 100644 index 0000000000..bbf2531475 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10040_boot/target.yml @@ -0,0 +1,3 @@ +target.app: "@mcuboot/boot/mynewt" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10040" +target.build_profile: optimized diff --git a/tools/hci_throughput/targets/nordic_pca10056_blehci/pkg.yml b/tools/hci_throughput/targets/nordic_pca10056_blehci/pkg.yml new file mode 100644 index 0000000000..a60adc72f3 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10056_blehci/pkg.yml @@ -0,0 +1,27 @@ +# +# 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: tools/hci_throughput/targets/nordic_pca10056_blehci +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: + +pkg.deps: + - "@apache-mynewt-core/hw/usb/tinyusb/std_descriptors" diff --git a/tools/hci_throughput/targets/nordic_pca10056_blehci/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10056_blehci/syscfg.yml new file mode 100644 index 0000000000..61f14a788c --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10056_blehci/syscfg.yml @@ -0,0 +1,32 @@ +# +# 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. +# + +syscfg.vals: + BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 + BLE_TRANSPORT_HS: usb + USBD_VID: 0xDCAB + USBD_PID: 0x1234 + USBD_BTH: 1 + USBD_PRODUCT_STRING: '"throughput"' + MSYS_1_BLOCK_COUNT: 80 + MSYS_1_BLOCK_SIZE: 308 + BLE_TRANSPORT_ACL_COUNT: 80 + BLE_TRANSPORT_ACL_SIZE: 255 \ No newline at end of file diff --git a/tools/hci_throughput/targets/nordic_pca10056_blehci/target.yml b/tools/hci_throughput/targets/nordic_pca10056_blehci/target.yml new file mode 100644 index 0000000000..e6317f2d44 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10056_blehci/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: optimized diff --git a/tools/hci_throughput/targets/nordic_pca10056_boot/pkg.yml b/tools/hci_throughput/targets/nordic_pca10056_boot/pkg.yml new file mode 100644 index 0000000000..1b9a6cde18 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10056_boot/pkg.yml @@ -0,0 +1,6 @@ +pkg.name: targets/nordic_pca10056_boot +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/tools/hci_throughput/targets/nordic_pca10056_boot/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10056_boot/syscfg.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/hci_throughput/targets/nordic_pca10056_boot/target.yml b/tools/hci_throughput/targets/nordic_pca10056_boot/target.yml new file mode 100644 index 0000000000..9cde39ac02 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10056_boot/target.yml @@ -0,0 +1,3 @@ +target.app: "@mcuboot/boot/mynewt" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: optimized diff --git a/tools/hci_throughput/targets/nordic_pca10059_blehci/pkg.yml b/tools/hci_throughput/targets/nordic_pca10059_blehci/pkg.yml new file mode 100644 index 0000000000..6b9edc3bb9 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10059_blehci/pkg.yml @@ -0,0 +1,27 @@ +# +# 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: tools/hci_throughput/targets/nordic_pca10059_blehci +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: + +pkg.deps: + - "@apache-mynewt-core/hw/usb/tinyusb/std_descriptors" diff --git a/tools/hci_throughput/targets/nordic_pca10059_blehci/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10059_blehci/syscfg.yml new file mode 100644 index 0000000000..f27e8c0b85 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10059_blehci/syscfg.yml @@ -0,0 +1,32 @@ +# +# 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. +# + +syscfg.vals: + BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 + BLE_TRANSPORT_HS: usb + USBD_VID: 0xDCAB + USBD_PID: 0x1234 + USBD_BTH: 1 + USBD_PRODUCT_STRING: '"throughput_dongle"' + MSYS_1_BLOCK_COUNT: 80 + MSYS_1_BLOCK_SIZE: 308 + BLE_TRANSPORT_ACL_COUNT: 80 + BLE_TRANSPORT_ACL_SIZE: 255 \ No newline at end of file diff --git a/tools/hci_throughput/targets/nordic_pca10059_blehci/target.yml b/tools/hci_throughput/targets/nordic_pca10059_blehci/target.yml new file mode 100644 index 0000000000..b582fddd49 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10059_blehci/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10059" +target.build_profile: optimized diff --git a/tools/hci_throughput/targets/nrf52832_blehci/pkg.yml b/tools/hci_throughput/targets/nrf52832_blehci/pkg.yml new file mode 100644 index 0000000000..72d5574268 --- /dev/null +++ b/tools/hci_throughput/targets/nrf52832_blehci/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: tools/hci_throughput/targets/nrf52832_blehci +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: diff --git a/tools/hci_throughput/targets/nrf52832_blehci/syscfg.yml b/tools/hci_throughput/targets/nrf52832_blehci/syscfg.yml new file mode 100644 index 0000000000..e63f3ed722 --- /dev/null +++ b/tools/hci_throughput/targets/nrf52832_blehci/syscfg.yml @@ -0,0 +1,26 @@ +# +# 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. +# + +syscfg.vals: + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + MSYS_1_BLOCK_COUNT: 80 + MSYS_1_BLOCK_SIZE: 308 + BLE_TRANSPORT_ACL_COUNT: 80 + BLE_TRANSPORT_ACL_SIZE: 255 + diff --git a/tools/hci_throughput/targets/nrf52832_blehci/target.yml b/tools/hci_throughput/targets/nrf52832_blehci/target.yml new file mode 100644 index 0000000000..f9d6d0fb02 --- /dev/null +++ b/tools/hci_throughput/targets/nrf52832_blehci/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10040" +target.build_profile: optimized diff --git a/tools/hci_throughput/targets/nrf52840_blehci/pkg.yml b/tools/hci_throughput/targets/nrf52840_blehci/pkg.yml new file mode 100644 index 0000000000..bc9743eac7 --- /dev/null +++ b/tools/hci_throughput/targets/nrf52840_blehci/pkg.yml @@ -0,0 +1,27 @@ +# +# 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: tools/hci_throughput/targets/nrf52840_blehci +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: + +pkg.deps: + - "@apache-mynewt-core/hw/usb/tinyusb/std_descriptors" diff --git a/tools/hci_throughput/targets/nrf52840_blehci/syscfg.yml b/tools/hci_throughput/targets/nrf52840_blehci/syscfg.yml new file mode 100644 index 0000000000..61f14a788c --- /dev/null +++ b/tools/hci_throughput/targets/nrf52840_blehci/syscfg.yml @@ -0,0 +1,32 @@ +# +# 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. +# + +syscfg.vals: + BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 + BLE_TRANSPORT_HS: usb + USBD_VID: 0xDCAB + USBD_PID: 0x1234 + USBD_BTH: 1 + USBD_PRODUCT_STRING: '"throughput"' + MSYS_1_BLOCK_COUNT: 80 + MSYS_1_BLOCK_SIZE: 308 + BLE_TRANSPORT_ACL_COUNT: 80 + BLE_TRANSPORT_ACL_SIZE: 255 \ No newline at end of file diff --git a/tools/hci_throughput/targets/nrf52840_blehci/target.yml b/tools/hci_throughput/targets/nrf52840_blehci/target.yml new file mode 100644 index 0000000000..e6317f2d44 --- /dev/null +++ b/tools/hci_throughput/targets/nrf52840_blehci/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: optimized diff --git a/tools/hci_throughput/tests/.gitignore b/tools/hci_throughput/tests/.gitignore new file mode 100755 index 0000000000..c96a04f008 --- /dev/null +++ b/tools/hci_throughput/tests/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/tools/hci_throughput/throughput.py b/tools/hci_throughput/throughput.py new file mode 100644 index 0000000000..dcc242d20a --- /dev/null +++ b/tools/hci_throughput/throughput.py @@ -0,0 +1,197 @@ +# +# 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. +# + +import time +import matplotlib.pyplot as plt +import csv +import struct +import argparse +import traceback + +def parse_arguments(): + parser = argparse.ArgumentParser( + description='Plot throughput from the csv file.', + epilog='How to run script: \ + python throughput.py -f tests/Wed_Apr_13_08:36:29_2022/tp_receiver.csv -s 0.1') + + parser.add_argument('-f', '--file', type=str, nargs='*', + help='csv file path', default=["tp_receiver"]) + parser.add_argument('-s', '--samp_t', type=float, nargs='*', + help='specify throughput sample time', default=1.0) + try: + args = parser.parse_args() + except Exception as e: + print(traceback.format_exc()) + return args + +data_types = ['kb', 'kB'] + + +def gen_data(num_of_bytes_in_packet: int, last_number_from_previous_data_packet: int): + counter = last_number_from_previous_data_packet + 1 + rem = num_of_bytes_in_packet % 4 + valid_data_len = int((num_of_bytes_in_packet - rem) / 4) + total_data_len = valid_data_len + rem + data = [0] * total_data_len + for i in range(rem,total_data_len): + data[i] = counter + counter += 1 + last_value = data[len(data)-1] + if rem: + fmt = "<" + str(rem) + "B" + str(valid_data_len) + "I" + else: + fmt = "<" + str(valid_data_len) + "I" + data_ba = struct.pack(fmt, *data) + return data_ba, last_value + + +class Throughput(): + def __init__(self, name="tp_chart", mode="rx", total_packets_number=0, bytes_number_in_packet=0, + throughput_data_type='kb', flag_plot_packets=True, sample_time=1, test_directory=None): + self.name = name + self.mode = mode + self.total_packets_number = total_packets_number + self.bytes_number_in_packet = bytes_number_in_packet + self.predef_packet_key = int((bytes_number_in_packet - (bytes_number_in_packet % 4))/4) + self.total_bits_number = bytes_number_in_packet * 8 + assert throughput_data_type in data_types + self.throughput_data_type = throughput_data_type + self.flag_plot_packets = flag_plot_packets + self.sample_time = sample_time + self.test_directory = test_directory + + if self.test_directory is not None: + self.csv_file_name = self.test_directory + "/" + time.strftime("%Y_%m_%d_%H_%M_%S_") + self.name + ".csv" + else: + self.csv_file_name = time.strftime("%Y_%m_%d_%H_%M_%S_") + self.name + ".csv" + self.clean_csv_file() + + def calc_throughput(self, current_num, last_num, current_time, last_time): + if self.throughput_data_type == 'kb': + return float((((current_num - last_num) * \ + self.total_bits_number) / (current_time-last_time))/1000) + elif self.throughput_data_type == 'kB': + return float((((current_num - last_num) * \ + self.bytes_number_in_packet) / (current_time-last_time))/1000) + + def clean_csv_file(self): + file = open(self.csv_file_name, 'w') + file.write("Time,Packet\n") + + def append_to_csv_file(self, timestamp: float = 0.0, packet_number: int = 0): + with open(self.csv_file_name, "a") as file: + csv_writer = csv.writer(file) + csv_writer.writerow([timestamp, packet_number]) + + def get_average(self, packet_numbers, timestamps): + if self.throughput_data_type == 'kb': + average_tp = ((packet_numbers * self.total_bits_number) \ + / (timestamps[-1] - timestamps[0]))/1000 + elif self.throughput_data_type == 'kB': + average_tp = ((packet_numbers * self.bytes_number_in_packet) \ + / (timestamps[-1] - timestamps[0]))/1000 + return average_tp + + def save_average(self, tp_csv_filename = None): + if self.mode == "rx": + timestamps = [] + packet_numbers = [] + + if tp_csv_filename is None: + tp_csv_filename = self.csv_file_name + else: + tp_csv_filename += ".csv" + + with open(tp_csv_filename, "r") as file: + csv_reader = csv.reader(file) + next(csv_reader) + for row in csv_reader: + timestamps.append(float(row[0])) + packet_numbers.append(float(row[1])) + + average_tp = self.get_average(packet_numbers[-1], timestamps) + print(f"Average rx throughput: {round(average_tp, 3)} {self.throughput_data_type}ps") + + with open(self.test_directory + "/average_rx_tp.csv", "a") as file: + csv_writer = csv.writer(file) + csv_writer.writerow([average_tp]) + + def plot_tp_from_file(self, filename: str = None, sample_time: float = 1, + save_to_file: bool = True): + timestamps = [] + packet_numbers = [] + + if filename is None: + filename = self.csv_file_name + print("Results:", filename) + + with open(filename, "r") as file: + csv_reader = csv.reader(file) + next(csv_reader) + for row in csv_reader: + timestamps.append(float(row[0])) + packet_numbers.append(float(row[1])) + + last_time = 0 + last_number = packet_numbers[0] + throughput = [] + offset = timestamps[0] + + for i in range(0, len(timestamps)): + timestamps[i] -= offset + if timestamps[i] - last_time > sample_time: + throughput.append((timestamps[i], + self.calc_throughput(packet_numbers[i], + last_number, + timestamps[i], + last_time))) + last_time = timestamps[i] + last_number = packet_numbers[i] + + average_tp = self.get_average(packet_numbers[-1], timestamps) + + fig, ax = plt.subplots() + if self.flag_plot_packets: + ax2 = ax.twinx() + + ax.plot(*zip(*throughput), 'k-') + if self.flag_plot_packets: + ax2.plot(timestamps, packet_numbers, 'b-') + + ax.set_title(self.name) + ax.set_ylabel(f"Throughput [{self.throughput_data_type}/s]") + ax.set_xlabel("Time [s]") + ax.text(0.9, 1.02, f"Average: {round(average_tp, 3)}" + f"{self.throughput_data_type}ps", transform=ax.transAxes, + color='k') + if self.flag_plot_packets: + ax2 = ax2.set_ylabel(f"Packets [Max:{len(packet_numbers)}]", + color='b') + + if save_to_file: + path = filename.replace(".csv", ".png") + plt.savefig(path) + + plt.show(block=True) + + +if __name__ == "__main__": + args = parse_arguments() + tp = Throughput(bytes_number_in_packet=247) + tp.plot_tp_from_file(*args.file, args.samp_t[0], save_to_file=False) \ No newline at end of file diff --git a/tools/hci_throughput/transport_factory.py b/tools/hci_throughput/transport_factory.py new file mode 100644 index 0000000000..615bccf52a --- /dev/null +++ b/tools/hci_throughput/transport_factory.py @@ -0,0 +1,38 @@ +# +# 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. +# + +import hci_socket + +class TransportFactory: + def __init__(self, device_index=None, device_mode=None, + asyncio_loop=None) -> None: + if (type(device_index) == int or device_index.isnumeric()): + self.transport = hci_socket.HCI_User_Channel_Socket(int(device_index), + device_mode, asyncio_loop) + else: + raise Exception("No such transport found.") + + self.rx_buffer_q = self.transport.rx_buffer_q + self.send = self.transport.send + + def start(self): + self.transport.start() + + def stop(self): + self.transport.stop() diff --git a/tools/hci_throughput/util.py b/tools/hci_throughput/util.py new file mode 100644 index 0000000000..6aeed607ca --- /dev/null +++ b/tools/hci_throughput/util.py @@ -0,0 +1,70 @@ +# +# 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. +# + +import logging +import shutil +import time +import os + +def create_test_directory(): + test_dir_name = "tests/" + time.strftime("%Y_%m_%d_%H_%M_%S") + path = os.path.join(os.getcwd(), test_dir_name) + os.mkdir(path, mode=0o777) + print("Test directory: ", path) + return path + + +def configure_logging(log_filename, clear_log_file=True): + format_template = ("%(asctime)s %(threadName)s %(name)s %(levelname)s " + "%(filename)-25s %(lineno)-5s " + "%(funcName)-25s : %(message)s") + logging.basicConfig(format=format_template, + filename=log_filename, + filemode='a', + level=logging.DEBUG) + if clear_log_file: + with open(log_filename, "w") as f: + f.write("asctime\t\t\t\t\tthreadName name levelname filename\ + \tlineno\tfuncName\t\t\t\tmessage\n") + + logging.getLogger("asyncio").setLevel(logging.WARNING) + logging.getLogger("matplotlib").setLevel(logging.WARNING) + + +def copy_config_files_to_test_directory(files: list, test_directory: str): + for file in files: + shutil.copy(file, test_directory + "/" + file) + + +def copy_log_files_to_test_directory(dir: str): + log_files = ["log/log_rx.log", "log/log_tx.log", "log/check_addr.log"] + for file in log_files: + shutil.copy(file, dir + "/" + time.strftime("%Y_%m_%d_%H_%M_%S_") + + file.replace("log/", "")) + + +# Running tests as sudo implies root permissions on created directories/files. +# This function sets the default permission mode to dirs/files in given path +# recursively. +def set_default_chmod_recurs(path): + for root, dirs, files in os.walk(path): + for d in dirs: + os.chmod(os.path.join(root, d), 0o0777) + for f in files: + os.chmod(os.path.join(root, f), 0o0777) From 5864300c19f7954d1ad4630f21e3227fcf87de25 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Tue, 17 May 2022 11:35:46 +0200 Subject: [PATCH 0419/1333] nrf5340: avoid have 2 interrupts for each IPC message NOTE: There is a matching patch for mynewt-core that implements the newt function The IPC messages are written in 2 parts: the cmd byte and the rest. It is unneccesary to already interrupt the other core for the first byte, since it will be interrupted by the 2nd write already. --- nimble/transport/nrf5340/src/nrf5340_ble_hci.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index fc9fec7c25..2e9e746f32 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -42,11 +42,11 @@ nrf5340_ble_hci_acl_tx(struct os_mbuf *om) struct os_mbuf *x; int rc; - rc = ipc_nrf5340_send(IPC_TX_CHANNEL, &ind, 1); + rc = ipc_nrf5340_write(IPC_TX_CHANNEL, &ind, 1, false); if (rc == 0) { x = om; while (x) { - rc = ipc_nrf5340_send(IPC_TX_CHANNEL, x->om_data, x->om_len); + rc = ipc_nrf5340_write(IPC_TX_CHANNEL, x->om_data, x->om_len, true); if (rc < 0) { break; } @@ -121,9 +121,9 @@ ble_transport_to_hs_evt_impl(void *buf) int len = 2 + hci_ev[1]; int rc; - rc = ipc_nrf5340_send(IPC_TX_CHANNEL, &ind, 1); + rc = ipc_nrf5340_write(IPC_TX_CHANNEL, &ind, 1, false); if (rc == 0) { - rc = ipc_nrf5340_send(IPC_TX_CHANNEL, hci_ev, len); + rc = ipc_nrf5340_write(IPC_TX_CHANNEL, hci_ev, len, true); } ble_transport_free(buf); @@ -155,9 +155,9 @@ ble_transport_to_ll_cmd_impl(void *buf) int len = 3 + cmd[2]; int rc; - rc = ipc_nrf5340_send(IPC_TX_CHANNEL, &ind, 1); + rc = ipc_nrf5340_write(IPC_TX_CHANNEL, &ind, 1, false); if (rc == 0) { - rc = ipc_nrf5340_send(IPC_TX_CHANNEL, cmd, len); + rc = ipc_nrf5340_write(IPC_TX_CHANNEL, cmd, len, true); } ble_transport_free(buf); From 621a16bc5a889b34ad68311928ecdddea5fff604 Mon Sep 17 00:00:00 2001 From: Jakub Rotkiewicz Date: Fri, 27 May 2022 13:07:09 +0200 Subject: [PATCH 0420/1333] tools/hci_throughput: fix redundant targets --- .../targets/nrf52832_blehci/pkg.yml | 24 -------------- .../targets/nrf52832_blehci/syscfg.yml | 26 --------------- .../targets/nrf52832_blehci/target.yml | 22 ------------- .../targets/nrf52840_blehci/pkg.yml | 27 ---------------- .../targets/nrf52840_blehci/syscfg.yml | 32 ------------------- .../targets/nrf52840_blehci/target.yml | 22 ------------- 6 files changed, 153 deletions(-) delete mode 100644 tools/hci_throughput/targets/nrf52832_blehci/pkg.yml delete mode 100644 tools/hci_throughput/targets/nrf52832_blehci/syscfg.yml delete mode 100644 tools/hci_throughput/targets/nrf52832_blehci/target.yml delete mode 100644 tools/hci_throughput/targets/nrf52840_blehci/pkg.yml delete mode 100644 tools/hci_throughput/targets/nrf52840_blehci/syscfg.yml delete mode 100644 tools/hci_throughput/targets/nrf52840_blehci/target.yml diff --git a/tools/hci_throughput/targets/nrf52832_blehci/pkg.yml b/tools/hci_throughput/targets/nrf52832_blehci/pkg.yml deleted file mode 100644 index 72d5574268..0000000000 --- a/tools/hci_throughput/targets/nrf52832_blehci/pkg.yml +++ /dev/null @@ -1,24 +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. -# - -pkg.name: tools/hci_throughput/targets/nrf52832_blehci -pkg.type: target -pkg.description: -pkg.author: -pkg.homepage: diff --git a/tools/hci_throughput/targets/nrf52832_blehci/syscfg.yml b/tools/hci_throughput/targets/nrf52832_blehci/syscfg.yml deleted file mode 100644 index e63f3ed722..0000000000 --- a/tools/hci_throughput/targets/nrf52832_blehci/syscfg.yml +++ /dev/null @@ -1,26 +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. -# - -syscfg.vals: - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 - MSYS_1_BLOCK_COUNT: 80 - MSYS_1_BLOCK_SIZE: 308 - BLE_TRANSPORT_ACL_COUNT: 80 - BLE_TRANSPORT_ACL_SIZE: 255 - diff --git a/tools/hci_throughput/targets/nrf52832_blehci/target.yml b/tools/hci_throughput/targets/nrf52832_blehci/target.yml deleted file mode 100644 index f9d6d0fb02..0000000000 --- a/tools/hci_throughput/targets/nrf52832_blehci/target.yml +++ /dev/null @@ -1,22 +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. -# - -target.app: "@apache-mynewt-nimble/apps/blehci" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10040" -target.build_profile: optimized diff --git a/tools/hci_throughput/targets/nrf52840_blehci/pkg.yml b/tools/hci_throughput/targets/nrf52840_blehci/pkg.yml deleted file mode 100644 index bc9743eac7..0000000000 --- a/tools/hci_throughput/targets/nrf52840_blehci/pkg.yml +++ /dev/null @@ -1,27 +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. -# - -pkg.name: tools/hci_throughput/targets/nrf52840_blehci -pkg.type: target -pkg.description: -pkg.author: -pkg.homepage: - -pkg.deps: - - "@apache-mynewt-core/hw/usb/tinyusb/std_descriptors" diff --git a/tools/hci_throughput/targets/nrf52840_blehci/syscfg.yml b/tools/hci_throughput/targets/nrf52840_blehci/syscfg.yml deleted file mode 100644 index 61f14a788c..0000000000 --- a/tools/hci_throughput/targets/nrf52840_blehci/syscfg.yml +++ /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. -# - -syscfg.vals: - BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 - BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 - BLE_TRANSPORT_HS: usb - USBD_VID: 0xDCAB - USBD_PID: 0x1234 - USBD_BTH: 1 - USBD_PRODUCT_STRING: '"throughput"' - MSYS_1_BLOCK_COUNT: 80 - MSYS_1_BLOCK_SIZE: 308 - BLE_TRANSPORT_ACL_COUNT: 80 - BLE_TRANSPORT_ACL_SIZE: 255 \ No newline at end of file diff --git a/tools/hci_throughput/targets/nrf52840_blehci/target.yml b/tools/hci_throughput/targets/nrf52840_blehci/target.yml deleted file mode 100644 index e6317f2d44..0000000000 --- a/tools/hci_throughput/targets/nrf52840_blehci/target.yml +++ /dev/null @@ -1,22 +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. -# - -target.app: "@apache-mynewt-nimble/apps/blehci" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: optimized From 56cb10f85db5b27e2f57fff69e32d8cdb7f7992b Mon Sep 17 00:00:00 2001 From: Jakub Date: Fri, 27 May 2022 16:55:16 +0200 Subject: [PATCH 0421/1333] tools/hci_throughput: Added NRF53 targets, README fix --- tools/hci_throughput/README.md | 5 +++ .../nordic_pca10095_app_blehci/pkg.yml | 24 +++++++++++ .../nordic_pca10095_app_blehci/syscfg.yml | 43 +++++++++++++++++++ .../nordic_pca10095_app_blehci/target.yml | 22 ++++++++++ .../targets/nordic_pca10095_app_boot/pkg.yml | 24 +++++++++++ .../nordic_pca10095_app_boot/syscfg.yml | 18 ++++++++ .../nordic_pca10095_app_boot/target.yml | 22 ++++++++++ .../nordic_pca10095_net_blehci/pkg.yml | 24 +++++++++++ .../nordic_pca10095_net_blehci/syscfg.yml | 34 +++++++++++++++ .../nordic_pca10095_net_blehci/target.yml | 22 ++++++++++ .../targets/nordic_pca10095_net_boot/pkg.yml | 24 +++++++++++ .../nordic_pca10095_net_boot/syscfg.yml | 22 ++++++++++ .../nordic_pca10095_net_boot/target.yml | 22 ++++++++++ 13 files changed, 306 insertions(+) create mode 100644 tools/hci_throughput/targets/nordic_pca10095_app_blehci/pkg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10095_app_blehci/syscfg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10095_app_blehci/target.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10095_app_boot/pkg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10095_app_boot/syscfg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10095_app_boot/target.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10095_net_blehci/pkg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10095_net_blehci/syscfg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10095_net_blehci/target.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10095_net_boot/pkg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10095_net_boot/syscfg.yml create mode 100644 tools/hci_throughput/targets/nordic_pca10095_net_boot/target.yml diff --git a/tools/hci_throughput/README.md b/tools/hci_throughput/README.md index 7a661d6045..aa6652f1f9 100644 --- a/tools/hci_throughput/README.md +++ b/tools/hci_throughput/README.md @@ -6,6 +6,11 @@ Tool for measuring BLE throughput. Python 3.8.10 \ Matplotlib 3.5.1 +Install all required packages with: +``` +sudo pip install -r requirements.txt +``` + ## Usage ### Prepare devices This tool may be used with existing controller or with any board with ```blehci``` app. diff --git a/tools/hci_throughput/targets/nordic_pca10095_app_blehci/pkg.yml b/tools/hci_throughput/targets/nordic_pca10095_app_blehci/pkg.yml new file mode 100644 index 0000000000..eab5e9872b --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10095_app_blehci/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: tools/hci_throughput/targets/nordic_pca10095_app_blehci +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: diff --git a/tools/hci_throughput/targets/nordic_pca10095_app_blehci/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10095_app_blehci/syscfg.yml new file mode 100644 index 0000000000..ad3399349e --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10095_app_blehci/syscfg.yml @@ -0,0 +1,43 @@ +# +# 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. +# + +syscfg.vals: + BSP_NRF5340_NET_ENABLE: 1 + NRF5340_EMBED_NET_CORE: 1 + NET_CORE_IMAGE_TARGET_NAME: '@apache-mynewt-nimble/tools/hci_throughput/targets/nordic_pca10095_net_blehci' + + BLE_TRANSPORT_HS: usb + USBD_VID: 0xDCAB + USBD_PID: 0x1234 + USBD_PRODUCT_STRING: '"throughput"' + USBD_BTH: 1 + USBD_BTH_EVENT_EP: 0x81 + USBD_BTH_DATA_IN_EP: 0x82 + USBD_BTH_DATA_OUT_EP: 0x02 + USBD_WINDOWS_COMP_ID: 1 + + BLE_TRANSPORT_ACL_COUNT: 80 + BLE_TRANSPORT_ACL_SIZE: 255 + MSYS_1_BLOCK_COUNT: 80 + MSYS_1_BLOCK_SIZE: 308 + IPC_NRF5340_BUF_SZ: 3072 + + BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 diff --git a/tools/hci_throughput/targets/nordic_pca10095_app_blehci/target.yml b/tools/hci_throughput/targets/nordic_pca10095_app_blehci/target.yml new file mode 100644 index 0000000000..9d5dbb7203 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10095_app_blehci/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10095" +target.build_profile: optimized diff --git a/tools/hci_throughput/targets/nordic_pca10095_app_boot/pkg.yml b/tools/hci_throughput/targets/nordic_pca10095_app_boot/pkg.yml new file mode 100644 index 0000000000..505dcbd5ce --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10095_app_boot/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: tools/hci_throughput/targets/nordic_pca10095_app_boot +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: diff --git a/tools/hci_throughput/targets/nordic_pca10095_app_boot/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10095_app_boot/syscfg.yml new file mode 100644 index 0000000000..30097ef048 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10095_app_boot/syscfg.yml @@ -0,0 +1,18 @@ +# +# 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. +# diff --git a/tools/hci_throughput/targets/nordic_pca10095_app_boot/target.yml b/tools/hci_throughput/targets/nordic_pca10095_app_boot/target.yml new file mode 100644 index 0000000000..0ccd2a988b --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10095_app_boot/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@mcuboot/boot/mynewt" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10095" +target.build_profile: optimized diff --git a/tools/hci_throughput/targets/nordic_pca10095_net_blehci/pkg.yml b/tools/hci_throughput/targets/nordic_pca10095_net_blehci/pkg.yml new file mode 100644 index 0000000000..3983cea9d5 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10095_net_blehci/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: tools/hci_throughput/targets/nordic_pca10095_net_blehci +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: diff --git a/tools/hci_throughput/targets/nordic_pca10095_net_blehci/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10095_net_blehci/syscfg.yml new file mode 100644 index 0000000000..a086199a63 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10095_net_blehci/syscfg.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. +# + +syscfg.vals: + BLE_VERSION: 53 + BLE_TRANSPORT_HS: nrf5340 + BLE_LL_SCA: 50 + OS_CRASH_FILE_LINE: 1 + + BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 + + BLE_TRANSPORT_ACL_COUNT: 80 + BLE_TRANSPORT_ACL_SIZE: 255 + MSYS_1_BLOCK_COUNT: 80 + MSYS_1_BLOCK_SIZE: 308 + IPC_NRF5340_BUF_SZ: 3072 diff --git a/tools/hci_throughput/targets/nordic_pca10095_net_blehci/target.yml b/tools/hci_throughput/targets/nordic_pca10095_net_blehci/target.yml new file mode 100644 index 0000000000..0bf51ba8bc --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10095_net_blehci/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10095_net" +target.build_profile: optimized diff --git a/tools/hci_throughput/targets/nordic_pca10095_net_boot/pkg.yml b/tools/hci_throughput/targets/nordic_pca10095_net_boot/pkg.yml new file mode 100644 index 0000000000..61c48efcb4 --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10095_net_boot/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: tools/hci_throughput/targets/nordic_pca10095_net_boot +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: diff --git a/tools/hci_throughput/targets/nordic_pca10095_net_boot/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10095_net_boot/syscfg.yml new file mode 100644 index 0000000000..10b03c60cc --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10095_net_boot/syscfg.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +syscfg.vals: + BOOTUTIL_OVERWRITE_ONLY: 1 + WATCHDOG_INTERVAL: 0 diff --git a/tools/hci_throughput/targets/nordic_pca10095_net_boot/target.yml b/tools/hci_throughput/targets/nordic_pca10095_net_boot/target.yml new file mode 100644 index 0000000000..a293a4cadd --- /dev/null +++ b/tools/hci_throughput/targets/nordic_pca10095_net_boot/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@mcuboot/boot/mynewt" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10095_net" +target.build_profile: optimized From b752f1bedca422e1d55f102ea8e23a17eb25ec78 Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Thu, 28 Apr 2022 11:59:37 +0200 Subject: [PATCH 0422/1333] transport/monitor: fix unused variable warnings --- nimble/transport/include/nimble/transport/monitor.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/transport/include/nimble/transport/monitor.h b/nimble/transport/include/nimble/transport/monitor.h index 6b56f123b2..623dc54a7b 100644 --- a/nimble/transport/include/nimble/transport/monitor.h +++ b/nimble/transport/include/nimble/transport/monitor.h @@ -35,6 +35,8 @@ int ble_monitor_log(int level, const char *fmt, ...); static inline int ble_monitor_log(int level, const char *fmt, ...) { + (void)level; + (void)fmt; return 0; } From c8a5122ebaf5fd2d478607e7e6ea4c151dc6fa50 Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Thu, 28 Apr 2022 12:01:09 +0200 Subject: [PATCH 0423/1333] drivers/nrf52: fix rfclk functions for RIOT --- nimble/drivers/nrf52/src/ble_phy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/drivers/nrf52/src/ble_phy.c b/nimble/drivers/nrf52/src/ble_phy.c index dc8ba4e7ab..9b44123885 100644 --- a/nimble/drivers/nrf52/src/ble_phy.c +++ b/nimble/drivers/nrf52/src/ble_phy.c @@ -2239,7 +2239,7 @@ void ble_phy_disable_dtm(void) void ble_phy_rfclk_enable(void) { -#if MYNEWT +#if MYNEWT || defined(RIOT_VERSION) nrf52_clock_hfxo_request(); #else nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART); @@ -2249,7 +2249,7 @@ ble_phy_rfclk_enable(void) void ble_phy_rfclk_disable(void) { -#if MYNEWT +#if MYNEWT || defined(RIOT_VERSION) nrf52_clock_hfxo_release(); #else nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); From 5177f6c6655905615da3f9949313075dd28adc17 Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Thu, 28 Apr 2022 12:02:25 +0200 Subject: [PATCH 0424/1333] transport: expose ble_transport_init() in header --- nimble/transport/include/nimble/transport.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/transport/include/nimble/transport.h b/nimble/transport/include/nimble/transport.h index 9e0eb66951..fc3d737564 100644 --- a/nimble/transport/include/nimble/transport.h +++ b/nimble/transport/include/nimble/transport.h @@ -29,6 +29,9 @@ extern "C" { struct os_mbuf; +/* Initialization */ +void ble_transport_init(void); + /* Allocators for supported data types */ void *ble_transport_alloc_cmd(void); void *ble_transport_alloc_evt(int discardable); From 0806f838674ca65e7b8289cacd1166c9c8c23aee Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Thu, 28 Apr 2022 12:03:04 +0200 Subject: [PATCH 0425/1333] npl/hal: import hal_system.h --- porting/nimble/include/hal/hal_system.h | 110 ++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 porting/nimble/include/hal/hal_system.h diff --git a/porting/nimble/include/hal/hal_system.h b/porting/nimble/include/hal/hal_system.h new file mode 100644 index 0000000000..fa0255a68c --- /dev/null +++ b/porting/nimble/include/hal/hal_system.h @@ -0,0 +1,110 @@ +/* + * 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. + */ + + +/** + * @addtogroup HAL + * @{ + * @defgroup HALSystem HAL System + * @{ + */ + +#ifndef H_HAL_SYSTEM_ +#define H_HAL_SYSTEM_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * System reset. + */ +void hal_system_reset(void) __attribute((noreturn)); + +/** + * Called by bootloader to start loaded program. + */ +void hal_system_start(void *img_start) __attribute((noreturn)); + +/** + * Called by split app loader to start the app program. + */ +void hal_system_restart(void *img_start) __attribute((noreturn)); + +/** + * Returns non-zero if there is a HW debugger attached. + */ +int hal_debugger_connected(void); + +/** + * Reboot reason + */ +enum hal_reset_reason { + /** Power on Reset */ + HAL_RESET_POR = 1, + /** Caused by Reset Pin */ + HAL_RESET_PIN = 2, + /** Caused by Watchdog */ + HAL_RESET_WATCHDOG = 3, + /** Soft reset, either system reset or crash */ + HAL_RESET_SOFT = 4, + /** Low supply voltage */ + HAL_RESET_BROWNOUT = 5, + /** Restart due to user request */ + HAL_RESET_REQUESTED = 6, + /** System Off, wakeup on external interrupt*/ + HAL_RESET_SYS_OFF_INT = 7, + /** Restart due to DFU */ + HAL_RESET_DFU = 8, +}; + +/** + * Return the reboot reason + * + * @return A reboot reason + */ +enum hal_reset_reason hal_reset_cause(void); + +/** + * Return the reboot reason as a string + * + * @return String describing previous reset reason + */ +const char *hal_reset_cause_str(void); + +/** + * Starts clocks needed by system + */ +void hal_system_clock_start(void); + +/** + * Reset callback to be called before an reset happens inside hal_system_reset() + */ +void hal_system_reset_cb(void); + +#ifdef __cplusplus +} +#endif + +#endif /* H_HAL_SYSTEM_ */ + +/** + * @} HALSystem + * @} HAL + */ From 510dc550ed488c5f690c8375a2db559ca4dde4b1 Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Thu, 28 Apr 2022 12:03:52 +0200 Subject: [PATCH 0426/1333] porting: fix transport init in nimble_port.c --- porting/nimble/src/nimble_port.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/porting/nimble/src/nimble_port.c b/porting/nimble/src/nimble_port.c index 2a81fd63fc..1bd57f2b04 100644 --- a/porting/nimble/src/nimble_port.c +++ b/porting/nimble/src/nimble_port.c @@ -24,7 +24,7 @@ #include "nimble/nimble_port.h" #if NIMBLE_CFG_CONTROLLER #include "controller/ble_ll.h" -#include "transport/ram/ble_hci_ram.h" +#include "nimble/transport.h" #endif static struct ble_npl_eventq g_eventq_dflt; @@ -46,7 +46,6 @@ nimble_port_init(void) ble_transport_hs_init(); #if NIMBLE_CFG_CONTROLLER - ble_hci_ram_init(); #ifndef RIOT_VERSION hal_timer_init(5, NULL); os_cputime_init(32768); From 49001982f2509c04de2a02150ee011a2c0a8fdac Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Thu, 28 Apr 2022 12:23:48 +0200 Subject: [PATCH 0427/1333] porting/os_mbuf: silence Wcast-align warnings --- porting/nimble/include/os/os_mbuf.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/porting/nimble/include/os/os_mbuf.h b/porting/nimble/include/os/os_mbuf.h index bee47d0bbf..6c05b2a739 100644 --- a/porting/nimble/include/os/os_mbuf.h +++ b/porting/nimble/include/os/os_mbuf.h @@ -132,12 +132,13 @@ struct os_mqueue { ((__om)->om_pkthdr_len >= sizeof (struct os_mbuf_pkthdr)) /** Get a packet header pointer given an mbuf pointer */ -#define OS_MBUF_PKTHDR(__om) ((struct os_mbuf_pkthdr *) \ - (void *)((uint8_t *)&(__om)->om_data + sizeof(struct os_mbuf))) +#define OS_MBUF_PKTHDR(__om) ((struct os_mbuf_pkthdr *)(uintptr_t) \ + (void *)((uint8_t *)&(__om)->om_data \ + + sizeof(struct os_mbuf))) /** Given a mbuf packet header pointer, return a pointer to the mbuf */ #define OS_MBUF_PKTHDR_TO_MBUF(__hdr) \ - (struct os_mbuf *)(void *)((uint8_t *)(__hdr) - sizeof(struct os_mbuf)) + (struct os_mbuf *)(uintptr_t)((uint8_t *)(__hdr) - sizeof(struct os_mbuf)) /** * Gets the length of an entire mbuf chain. The specified mbuf must have a From 719bd3c435b728f07ce7aaffaf6cebbd9c659a46 Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Tue, 10 May 2022 08:22:22 +0200 Subject: [PATCH 0428/1333] drivers/nrf51: add missing include of os_cputime.h --- nimble/drivers/nrf51/src/ble_phy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/drivers/nrf51/src/ble_phy.c b/nimble/drivers/nrf51/src/ble_phy.c index d3bc3c2ecc..a74252b586 100644 --- a/nimble/drivers/nrf51/src/ble_phy.c +++ b/nimble/drivers/nrf51/src/ble_phy.c @@ -22,6 +22,8 @@ #include #include "syscfg/syscfg.h" #include "os/os.h" +/* Keep os_cputime explicitly to enable build on non-Mynewt platforms */ +#include "os/os_cputime.h" #include "ble/xcvr.h" #include "nimble/ble.h" #include "nimble/nimble_opt.h" From 80b6f20f988e3cd0a076031fafc456724d62904b Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Tue, 7 Jun 2022 15:03:28 +0200 Subject: [PATCH 0429/1333] controller: use OS specific PRNG for RIOT builds Currently the controller is using jrand48() to generate pseudo random numbers. For RIOT builds this commit switches to the RIOT build-in PRNG API, as this has two benefits: i) it saves 500bytes of flash and ii) jrand48() internally uses malloc, which has been source to runtime failures in the past. --- nimble/controller/src/ble_ll_rand.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nimble/controller/src/ble_ll_rand.c b/nimble/controller/src/ble_ll_rand.c index 06e5d12bcf..fc7febcf48 100644 --- a/nimble/controller/src/ble_ll_rand.c +++ b/nimble/controller/src/ble_ll_rand.c @@ -33,6 +33,10 @@ #include "trng/trng.h" #endif +#ifdef RIOT_VERSION +#include "random.h" +#endif + #if BABBLESIM extern void tm_tick(void); #endif @@ -134,6 +138,7 @@ ble_ll_rand_data_get(uint8_t *buf, uint8_t len) uint32_t ble_ll_rand(void) { +#ifndef RIOT_VERSION static unsigned short xsubi[3]; static bool init = true; @@ -143,6 +148,9 @@ ble_ll_rand(void) } return (uint32_t) jrand48(xsubi); +#else + return random_uint32(); +#endif } /** From fc66099158978911586b642989e2015d27ac825e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 21 Apr 2022 23:16:11 +0200 Subject: [PATCH 0430/1333] nimble/ll: Add more HCI commands for fake dual-mode This allows NimBLE to be initialized as "dual-mode" controller by BlueZ. Also inquiry "works" a bit better since Inquiry Complete event is simulated after inquiry duration has elapsed. --- nimble/controller/src/ble_ll_hci.c | 78 ++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 6aff00ebbe..ed543404ab 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1580,6 +1580,43 @@ ble_ll_hci_status_params_cmd_proc(const uint8_t *cmdbuf, uint8_t len, } #if MYNEWT_VAL(BLE_LL_HBD_FAKE_DUAL_MODE) +static void +ble_ll_hci_cmd_fake_dual_mode_inquiry_complete(struct ble_npl_event *ev) +{ + struct ble_hci_ev *hci_ev; + + hci_ev = ble_transport_alloc_evt(1); + if (!hci_ev) { + return; + } + + hci_ev->opcode = BLE_HCI_EVCODE_INQUIRY_CMP; + hci_ev->length = 1; + hci_ev->data[0] = 0; + + ble_ll_hci_event_send(hci_ev); +} + +static void +ble_ll_hci_cmd_fake_dual_mode_inquiry(uint32_t length) +{ + static struct ble_npl_callout inquiry_timer; + static bool init; + + if (!init) { + ble_npl_callout_init(&inquiry_timer, &g_ble_ll_data.ll_evq, + ble_ll_hci_cmd_fake_dual_mode_inquiry_complete, + NULL); + } + + if (length) { + ble_npl_callout_reset(&inquiry_timer, + ble_npl_time_ms_to_ticks32(length * 1280)); + } else { + ble_npl_callout_stop(&inquiry_timer); + } +} + static int ble_ll_hci_cmd_fake_dual_mode(uint16_t opcode, uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen) @@ -1588,10 +1625,16 @@ ble_ll_hci_cmd_fake_dual_mode(uint16_t opcode, uint8_t *cmdbuf, uint8_t len, switch (opcode) { case BLE_HCI_OP(BLE_HCI_OGF_LINK_CTRL, 0x01): /* Inquiry */ + ble_ll_hci_cmd_fake_dual_mode_inquiry(cmdbuf[3]); rc = BLE_ERR_MAX + 1; break; case BLE_HCI_OP(BLE_HCI_OGF_LINK_CTRL, 0x02): /* Inquiry Cancel */ + ble_ll_hci_cmd_fake_dual_mode_inquiry(0); + rc = 0; + break; + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x05): /* Set Event Filter */ case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x13): /* Write Local Name */ + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x16): /* Write Connection Accept Timeout */ case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x18): /* Write Page Timeout */ case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x1a): /* Write Scan Enable */ case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x1c): /* Write Page Scan Activity */ @@ -1601,9 +1644,37 @@ ble_ll_hci_cmd_fake_dual_mode(uint16_t opcode, uint8_t *cmdbuf, uint8_t len, case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x33): /* Host Buffer Size */ case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x45): /* Write Inquiry Mode */ case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x52): /* Write Extended Inquiry Response */ + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x56): /* Write Simple Pairing Mode */ case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x6d): /* Write LE Host Support */ rc = 0; break; + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x14): /* Read Local Name */ + memset(rspbuf, 0, 248); + strcpy((char *)rspbuf, "NimBLE"); + *rsplen = 248; + rc = 0; + break; + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x23): /* Read Class Of Device */ + put_le24(rspbuf, 0); + *rsplen = 3; + rc = 0; + break; + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x25): /* Read Voice Settings */ + put_le16(rspbuf, 0); + *rsplen = 2; + rc = 0; + break; + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x38): /* Read Number Of Supported IAC */ + rspbuf[0] = 1; + *rsplen = 1; + rc = 0; + break; + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x39): /* Read Current IAC LAP */ + rspbuf[0] = 1; + put_le24(&rspbuf[1], 0x9e8b33); + *rsplen = 4; + rc = 0; + break; case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 0x58): /* Read Inquiry Response Transmit Power Level */ rspbuf[0] = 0x04; *rsplen = 1; @@ -1614,6 +1685,13 @@ ble_ll_hci_cmd_fake_dual_mode(uint16_t opcode, uint8_t *cmdbuf, uint8_t len, *rsplen = 8; rc = 0; break; + case BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, 0x04): /* Read Local Extended Features */ + rspbuf[0] = 0; + rspbuf[1] = 0; + put_le64(&rspbuf[2], 0x877bffdbfe0ffebf); + *rsplen = 10; + rc = 0; + break; case BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_BUF_SIZE): put_le16(rspbuf, 255); rspbuf[2] = 0; From b8d1180bf6d8a685ce4e592150357a0a21a70532 Mon Sep 17 00:00:00 2001 From: Tian Zeng Date: Wed, 22 Jun 2022 04:03:15 -0400 Subject: [PATCH 0431/1333] Apollo3: Properly accumulate full ACL packet before sending to BLE controller (#1276) There was a bug in the Ambiq Apollo3 ACL data transfer logic in which each data chunk in an mbuf was sent individually to the controller instead of aggregating them together. This caused issues with parts of the bluetooth stack such as BLE SMP. Also deals with cleaning up pointers, making them 1 byte pointers where possible for simplification. --- .../transport/apollo3/src/apollo3_ble_hci.c | 57 ++++++++----------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/nimble/transport/apollo3/src/apollo3_ble_hci.c b/nimble/transport/apollo3/src/apollo3_ble_hci.c index 34b6266ddb..2ed3012e90 100644 --- a/nimble/transport/apollo3/src/apollo3_ble_hci.c +++ b/nimble/transport/apollo3/src/apollo3_ble_hci.c @@ -235,28 +235,9 @@ apollo3_update_wake(void) * The payload is placed into a queue and the controller is turned on. When it is ready * an interrupt will fire to handle sending a message */ -static uint8_t -apollo3_hci_write(uint8_t type, uint16_t len, uint8_t *data) +static int +apollo3_hci_write(hci_drv_write_t *write_buf) { - uint8_t *write_ptr; - hci_drv_write_t write_buf; - - /* comparison compensates for the type byte at index 0. */ - if (len > (MYNEWT_VAL(BLE_TRANSPORT_APOLLO3_MAX_TX_PACKET)-1)) { - return 0; - } - - /* Set all of the fields in the hci write structure. */ - write_buf.len = len + 1; - - write_ptr = (uint8_t *) write_buf.data; - - *write_ptr++ = type; - - for (uint32_t i = 0; i < len; i++) { - write_ptr[i] = data[i]; - } - /* Wake up the BLE controller. */ apollo3_update_wake(); @@ -265,7 +246,10 @@ apollo3_hci_write(uint8_t type, uint16_t len, uint8_t *data) os_time_delay(1); } - am_hal_ble_blocking_hci_write(ble_handle, AM_HAL_BLE_RAW, write_buf.data, write_buf.len); + if (AM_HAL_STATUS_SUCCESS != + am_hal_ble_blocking_hci_write(ble_handle, AM_HAL_BLE_RAW, write_buf->data, write_buf->len)) { + return -1; + } return 0; } @@ -273,17 +257,18 @@ apollo3_hci_write(uint8_t type, uint16_t len, uint8_t *data) static int apollo3_ble_hci_acl_tx(struct os_mbuf *om) { - struct os_mbuf *x; int rc = 0; + hci_drv_write_t write_buf; + uint8_t *ptr = (uint8_t *)write_buf.data; - x = om; - while (x) { - rc = apollo3_hci_write(HCI_H4_ACL, x->om_len, x->om_data); - if (rc < 0) { - break; - } - x = SLIST_NEXT(x, om_next); - } + *ptr = HCI_H4_ACL; + ptr++; + write_buf.len = 1; + + os_mbuf_copydata(om, 0, OS_MBUF_PKTLEN(om), ptr); + write_buf.len += OS_MBUF_PKTLEN(om); + + rc = apollo3_hci_write(&write_buf); os_mbuf_free_chain(om); @@ -327,9 +312,15 @@ ble_transport_to_ll_cmd_impl(void *buf) { int rc; uint8_t *cmd = buf; - int len = HCI_CMD_HDR_LEN + cmd[2]; + hci_drv_write_t write_buf; + uint8_t *ptr = (uint8_t *)write_buf.data; + + *ptr = HCI_H4_CMD; + ptr++; + write_buf.len = HCI_CMD_HDR_LEN + cmd[2] + 1; + memcpy(ptr, cmd, write_buf.len - 1); - rc = apollo3_hci_write(HCI_H4_CMD, len, cmd); + rc = apollo3_hci_write(&write_buf); ble_transport_free(cmd); From b2d682bf51b2bba97f0abc321aecb7be076f3a85 Mon Sep 17 00:00:00 2001 From: Jakub Date: Mon, 13 Jun 2022 14:18:29 +0200 Subject: [PATCH 0432/1333] tools/hci_throughput: fix supported octets info --- tools/hci_throughput/hci.py | 2 ++ tools/hci_throughput/hci_commands.py | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/hci_throughput/hci.py b/tools/hci_throughput/hci.py index 072e395e8c..69b3637454 100644 --- a/tools/hci_throughput/hci.py +++ b/tools/hci_throughput/hci.py @@ -31,6 +31,8 @@ HCI_ACL_DATA_PACKET = 0x02 HCI_EVENT_PACKET = 0x04 +L2CAP_HDR_BYTES = 4 + HCI_EV_CODE_DISCONN_CMP = 0x05 HCI_EV_CODE_CMD_CMP = 0x0e HCI_EV_CODE_CMD_STATUS = 0x0f diff --git a/tools/hci_throughput/hci_commands.py b/tools/hci_throughput/hci_commands.py index 2978ab852b..286f450602 100644 --- a/tools/hci_throughput/hci_commands.py +++ b/tools/hci_throughput/hci_commands.py @@ -422,10 +422,11 @@ def status() -> int: hci.max_data_len.set(*struct.unpack(" hci.max_data_len.supported_max_tx_octets - 4): - logging.critical(f"Number of bytes to send: {hci.num_of_bytes_to_send}\ - not supported. Closing.") - raise SystemExit("Number of bytes to send not supported. Closing.") + if (hci.num_of_bytes_to_send > hci.max_data_len.supported_max_tx_octets - hci.L2CAP_HDR_BYTES): + logging.critical(f"Number of data bytes to send + 4 bytes of L2CAP header: {hci.num_of_bytes_to_send + 4} " + f"exceeds allowed value of: {hci.max_data_len.supported_max_tx_octets}. Closing.") + raise SystemExit(f"Number of data bytes to send + 4 bytes of L2CAP header: {hci.num_of_bytes_to_send + 4} " + f"exceeds allowed value of: {hci.max_data_len.supported_max_tx_octets}. Closing.") return status() elif ocf == hci.OCF_LE_READ_PHY: From 0d49b6691fc240a4f983e1e66fb00fc804a9042b Mon Sep 17 00:00:00 2001 From: Jakub Date: Mon, 13 Jun 2022 15:03:06 +0200 Subject: [PATCH 0433/1333] tools/hci_throughput: added HCI commands Added read local supported commands and local supported features cmds. --- tools/hci_throughput/hci.py | 30 ++++++++++++++++++++++++++++ tools/hci_throughput/hci_commands.py | 14 +++++++++++++ 2 files changed, 44 insertions(+) diff --git a/tools/hci_throughput/hci.py b/tools/hci_throughput/hci.py index 69b3637454..6ed45625f5 100644 --- a/tools/hci_throughput/hci.py +++ b/tools/hci_throughput/hci.py @@ -21,6 +21,7 @@ import struct from binascii import unhexlify import random +import ctypes ############ # DEFINES @@ -57,6 +58,7 @@ OGF_LE_CTL = 0x08 OCF_LE_SET_EVENT_MASK = 0x0001 OCF_LE_READ_BUFFER_SIZE_V1 = 0x0002 +OCF_LE_READ_LOCAL_SUPPORTED_FEATURES = 0x0003 OCF_LE_READ_BUFFER_SIZE_V2 = 0x0060 OCF_LE_SET_RANDOM_ADDRESS = 0x0005 OCF_LE_SET_ADVERTISING_PARAMETERS = 0x0006 @@ -80,6 +82,9 @@ WAIT_FOR_EVENT_TIMEOUT = 5 WAIT_FOR_EVENT_CONN_TIMEOUT = 25 +LE_FEATURE_2M_PHY = ctypes.c_uint64(0x0100).value +LE_FEATURE_CODED_PHY = ctypes.c_uint64(0x0800).value + ############ # GLOBAL VAR ############ @@ -99,6 +104,8 @@ ev_num_comp_pkts = None num_of_completed_packets_cnt = 0 num_of_completed_packets_time = 0 +read_local_commands = None +le_read_local_supported_features = None ############ # FUNCTIONS @@ -203,6 +210,29 @@ def set(self, status=0, connection_handle=0, tx_phy=0, rx_phy=0): self.tx_phy = tx_phy self.rx_phy = rx_phy +@dataclass +class Read_Local_Commands: + status: int + supported_commands: bytes + + def __init__(self): + self.set() + + def set(self, rcv_bytes = bytes(65)): + self.status = int(rcv_bytes[0]) + self.supported_commands = rcv_bytes[1:] + +@dataclass +class LE_Read_Local_Supported_Features: + status: int + le_features: bytes + + def __init__(self): + self.set() + + def set(self, rcv_bytes = bytes(9)): + self.status = int(rcv_bytes[0]) + self.le_features = ctypes.c_uint64.from_buffer_copy(rcv_bytes[1:]).value ############ # EVENTS diff --git a/tools/hci_throughput/hci_commands.py b/tools/hci_throughput/hci_commands.py index 286f450602..a6040ef0f5 100644 --- a/tools/hci_throughput/hci_commands.py +++ b/tools/hci_throughput/hci_commands.py @@ -131,6 +131,14 @@ async def cmd_le_read_buffer_size(self): await self.async_ev_cmd_end.wait() self.async_ev_cmd_end.clear() + async def cmd_le_read_local_supported_features(self): + async with self.async_sem_cmd: + self.hci_send_cmd.set(hci.OGF_LE_CTL, hci.OCF_LE_READ_LOCAL_SUPPORTED_FEATURES) + logging.debug("%s %s", self.cmd_le_read_local_supported_features.__name__, self.hci_send_cmd) + await self.send(self.hci_send_cmd.ba_full_message) + await self.async_ev_cmd_end.wait() + self.async_ev_cmd_end.clear() + async def cmd_le_set_random_addr(self, addr: str): async with self.async_sem_cmd: addr_ba = hci.cmd_addr_to_ba(addr) @@ -382,6 +390,8 @@ def status() -> int: elif ogf == hci.OGF_INFO_PARAM: if ocf == hci.OCF_READ_LOCAL_COMMANDS: + hci.read_local_commands = hci.Read_Local_Commands() + hci.read_local_commands.set(bytes(current_ev.return_parameters)) return status() elif ocf == hci.OCF_READ_BD_ADDR: hci.bdaddr = hci.ba_addr_to_str( @@ -397,6 +407,10 @@ def status() -> int: current_ev.return_parameters)) logging.info(f"LE Buffer size: {hci.le_read_buffer_size}") return hci.le_read_buffer_size.status + elif ocf == hci.OCF_LE_READ_LOCAL_SUPPORTED_FEATURES: + hci.le_read_local_supported_features = hci.LE_Read_Local_Supported_Features() + hci.le_read_local_supported_features.set(current_ev.return_parameters) + return status() elif ocf == hci.OCF_LE_SET_RANDOM_ADDRESS: return status() elif ocf == hci.OCF_LE_SET_ADVERTISING_PARAMETERS: From 10efe05023594ad7cfabf172893a65945434ceaf Mon Sep 17 00:00:00 2001 From: Jakub Date: Mon, 13 Jun 2022 15:09:54 +0200 Subject: [PATCH 0434/1333] tools/hci_throughput: Fixed set phy, error handling --- tools/hci_throughput/hci_device.py | 45 +++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/tools/hci_throughput/hci_device.py b/tools/hci_throughput/hci_device.py index 10ef399825..0a20fed593 100644 --- a/tools/hci_throughput/hci_device.py +++ b/tools/hci_throughput/hci_device.py @@ -82,8 +82,37 @@ def parse_arguments(): logging.error(traceback.format_exc()) sys.exit() +async def set_phy(bt_dev: hci_commands.HCI_Commands, conn_handle, cfg_phy, + supported_features): + def error(info): + print("ERROR: Check log files") + raise Exception(info, ": Unsupported PHY. Closing...") + + PHY_2M = supported_features & hci.LE_FEATURE_2M_PHY + PHY_CODED = supported_features & hci.LE_FEATURE_CODED_PHY + + if (cfg_phy == "1M"): + await bt_dev.cmd_le_set_phy(conn_handle, all_phys=0, tx_phys=1, rx_phys=1, phy_options=0) + logging.info(f"PHY 1M") + + elif (cfg_phy == "2M"): + if (PHY_2M): + await bt_dev.cmd_le_set_phy(conn_handle, all_phys=0, tx_phys=2, rx_phys=2, phy_options=0) + logging.info(f"PHY 2M") + else: + error("2M") + + elif (cfg_phy == "Coded"): + if (PHY_CODED): + await bt_dev.cmd_le_set_phy(conn_handle, all_phys=0, tx_phys=3, rx_phys=3, phy_options=0) + logging.info(f"PHY Coded") + else: + error("Coded") -async def init(bt_dev: hci_commands.HCI_Commands, ini: dict): + else: + error("Possible PHY in config.yaml: 1M, 2M, Coded") + +async def init(bt_dev: hci_commands.HCI_Commands, ini: dict, cfg: dict): """ init: Assumed to be the same for all devices """ asyncio.create_task(bt_dev.rx_buffer_q_wait()) await bt_dev.cmd_reset() @@ -91,7 +120,7 @@ async def init(bt_dev: hci_commands.HCI_Commands, ini: dict): await bt_dev.cmd_le_set_random_addr(ini["own_address"]) await bt_dev.cmd_set_event_mask(mask=0x200080000204e090) await bt_dev.cmd_le_set_event_mask(mask=0x00000007FFFFFFFF) - await bt_dev.cmd_le_set_dflt_phy(all_phys=0, tx_phys=2, rx_phys=2) + await bt_dev.cmd_le_read_local_supported_features() await bt_dev.cmd_le_read_buffer_size() await bt_dev.cmd_le_read_max_data_len() @@ -112,7 +141,7 @@ async def finish(bt_dev: hci_commands.HCI_Commands, cfg: dict): async def async_main_rx(bt_dev: hci_commands.HCI_Commands, ini: dict, cfg: dict): - await init(bt_dev, ini) + await init(bt_dev, ini, cfg) bt_dev.tp = tp.Throughput(name="tp_receiver", mode=bt_dev.device_mode, total_packets_number=hci.num_of_packets_to_send, @@ -154,7 +183,7 @@ async def async_main_rx(bt_dev: hci_commands.HCI_Commands, ini: dict, cfg: dict) await finish(bt_dev, cfg) async def async_main_tx(bt_dev: hci_commands.HCI_Commands, ini: dict, cfg: dict): - await init(bt_dev, ini) + await init(bt_dev, ini, cfg) conn_params = hci.HCI_Connect() conn_params.set( @@ -178,12 +207,8 @@ async def async_main_tx(bt_dev: hci_commands.HCI_Commands, ini: dict, cfg: dict) await bt_dev.cmd_le_set_data_len(hci.conn_handle, tx_octets=0, tx_time=0) await hci_commands.wait_for_event(bt_dev.async_ev_set_data_len, hci.WAIT_FOR_EVENT_TIMEOUT) - if cfg["phy"] == "1M": - await bt_dev.cmd_le_set_phy(hci.conn_handle, all_phys=0, tx_phys=1, rx_phys=1, phy_options=0) - elif cfg["phy"] == "2M": - await bt_dev.cmd_le_set_phy(hci.conn_handle, all_phys=0, tx_phys=2, rx_phys=2, phy_options=0) - else: - raise Exception("PHY parameter not valid.") + await set_phy(bt_dev, hci.conn_handle, cfg['phy'], + hci.le_read_local_supported_features.le_features) await hci_commands.wait_for_event(bt_dev.async_ev_update_phy, hci.WAIT_FOR_EVENT_TIMEOUT) ############ From e9f42c70711f1a8c8656f262444d17edbead8818 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 9 Jun 2022 15:54:39 +0200 Subject: [PATCH 0435/1333] nimble/ll: Workaround for failed conn create on ext adv AUX_CONNECT_RSP is sent from isr, but it's possible that LL will fail to create new connection for various reasons. Moreover, it's possible that LL will "fail" before AUX_CONNECT_RSP is actually sent over the air and will disable phy, so sm will be stuck waiting for tx callback. There's quite a lot of changes required to make this work properly, so for now let's just detect that condition and simply ignore the error, i.e. sm will keep advertising as if there was no AUX_CONNECT_REQ/RSP. --- nimble/controller/src/ble_ll_adv.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 3327ba58db..dad69a0272 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -190,6 +190,7 @@ struct ble_ll_adv_sm #define BLE_LL_ADV_SM_FLAG_PERIODIC_DATA_INCOMPLETE 0x1000 #define BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING 0x2000 #define BLE_LL_ADV_SM_FLAG_PERIODIC_NEW_DATA 0x4000 +#define BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD_ERR 0x8000 #define ADV_DATA_LEN(_advsm) \ ((_advsm->adv_data) ? OS_MBUF_PKTLEN(advsm->adv_data) : 0) @@ -4395,6 +4396,11 @@ ble_ll_adv_conn_req_rxd(uint8_t *rxbuf, struct ble_mbuf_hdr *hdr, if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD)) { ble_ll_adv_sm_stop(advsm); } + } else if (advsm->flags & BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD) { +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD_ERR); + valid = 1; +#endif } } @@ -4859,8 +4865,13 @@ ble_ll_adv_sec_done(struct ble_ll_adv_sm *advsm) /* Stop advertising due to transmitting connection response */ if (advsm->flags & BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD) { - ble_ll_adv_sm_stop(advsm); - return; + if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD_ERR)) { + ble_ll_adv_sm_stop(advsm); + return; + } else { + ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD | + BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD_ERR); + } } /* If we have next AUX scheduled, try to schedule another one */ From c194ba130a8f97df193cbdda792a762d2a94fedb Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 9 Jun 2022 17:42:50 +0200 Subject: [PATCH 0436/1333] nimble/ll: Fix moving anchor point If there was already a control procedure ongoing, pending conn update context was not preserved properly so invalid update was done once procedure was started. Now we keep requested offset in connsm and use it for new procedure. Also this is not only for css so update code accordingly. --- nimble/controller/include/controller/ble_ll_conn.h | 1 + nimble/controller/src/ble_ll_conn.c | 12 ++---------- nimble/controller/src/ble_ll_ctrl.c | 13 +++++++++++++ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 437d7c2506..4215349fa9 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -377,6 +377,7 @@ struct ble_ll_conn_sm /* For connection update procedure */ struct ble_ll_conn_upd_req conn_update_req; + uint16_t conn_update_anchor_offset_req; /* XXX: for now, just store them all */ struct ble_ll_conn_params conn_cp; diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index b6660196f5..393ae8795a 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2185,8 +2185,6 @@ ble_ll_conn_get_anchor(struct ble_ll_conn_sm *connsm, uint16_t conn_event, int ble_ll_conn_move_anchor(struct ble_ll_conn_sm *connsm, uint16_t offset) { - struct ble_ll_conn_params cp = { }; - BLE_LL_ASSERT(connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL); if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ) || @@ -2194,14 +2192,8 @@ ble_ll_conn_move_anchor(struct ble_ll_conn_sm *connsm, uint16_t offset) return -1; } - /* Keep parameters, we just want to move anchor */ - cp.interval_max = connsm->conn_itvl; - cp.interval_min = connsm->conn_itvl; - cp.latency = connsm->periph_latency; - cp.timeout = connsm->supervision_tmo; - cp.offset0 = offset; - - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_CONN_UPDATE, &cp); + connsm->conn_update_anchor_offset_req = offset; + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_CONN_UPDATE, NULL); return 0; } diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 7ece7b1c83..07f303009c 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -394,6 +394,7 @@ static void ble_ll_ctrl_conn_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld, struct ble_ll_conn_params *cp) { + struct ble_ll_conn_params offset_cp = { }; uint16_t instant; uint32_t dt; uint32_t num_old_ce; @@ -416,6 +417,18 @@ ble_ll_ctrl_conn_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld, instant = connsm->event_cntr + connsm->periph_latency + 6 + 1; #endif + /* Check if this is a move anchor request and configure proper connection + * parameters */ + if (connsm->conn_update_anchor_offset_req) { + offset_cp.interval_min = connsm->conn_itvl; + offset_cp.interval_max = connsm->conn_itvl; + offset_cp.latency = connsm->periph_latency; + offset_cp.timeout = connsm->supervision_tmo; + offset_cp.offset0 = connsm->conn_update_anchor_offset_req; + connsm->conn_update_anchor_offset_req = 0; + cp = &offset_cp; + } + /* * XXX: This should change in the future, but for now we will just * start the new instant at the same anchor using win offset 0. From 25c9e2ddac3bc7e933f1890d3d0e20c47ef719f5 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 8 Jun 2022 15:48:59 +0200 Subject: [PATCH 0437/1333] nimble/ll/css: Fix conn event end time calculation Proper end time is obviously slot duration from start time. --- nimble/controller/src/ble_ll_sched.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 149fee90e8..6e1cde5448 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -521,13 +521,13 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, ble_ll_sched_css_set_conn_anchor(connsm); sch->start_time = connsm->anchor_point - g_ble_ll_sched_offset_ticks; + sch->end_time = connsm->anchor_point; sch->remainder = connsm->anchor_point_usecs; OS_EXIT_CRITICAL(sr); - sch->end_time = sch->start_time; rem_us = sch->remainder; - ble_ll_tmr_add(&sch->end_time, &rem_us, ble_ll_sched_css_get_period_slots()); + ble_ll_tmr_add(&sch->end_time, &rem_us, ble_ll_sched_css_get_slot_us()); if (rem_us == 0) { sch->end_time--; } From 3f606a09bfe787d7601da21bbd15ed9cca5ce80d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 9 Jun 2022 16:13:17 +0200 Subject: [PATCH 0438/1333] nimble/ll/css: Fix handling of 1st connection event If there are no connections present, we can schedule 1st connection event as for any other connection, i.e. with non-zero txWindowOffset. We set this new connection as reference only if it's successfully created. For each subsequent connection we do not allow txWindowOffset since it has to be scheduled precisely at slot anchor. Also make sure that requested next slot is reset after connection is created to avoid scheduling another connection on the same slot. --- .../include/controller/ble_ll_sched.h | 1 + nimble/controller/src/ble_ll_conn.c | 5 +++ nimble/controller/src/ble_ll_sched.c | 36 ++++++++++--------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index a65b5d4307..7dac849550 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -179,6 +179,7 @@ int ble_ll_sched_dtm(struct ble_ll_sched_item *sch); #if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) void ble_ll_sched_css_set_params(uint32_t slot_us, uint32_t period_slots); #endif +void ble_ll_sched_css_update_anchor(struct ble_ll_conn_sm *connsm); void ble_ll_sched_css_set_conn_anchor(struct ble_ll_conn_sm *connsm); #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) static inline uint32_t diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 393ae8795a..9199c8674d 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2682,6 +2682,11 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_CONN_ROLE_CENTRAL: +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + ble_ll_sched_css_update_anchor(connsm); + ble_ll_conn_css_set_next_slot(BLE_LL_CONN_CSS_NO_SLOT); +#endif + evbuf = ble_ll_init_get_conn_comp_ev(); ble_ll_conn_comp_event_send(connsm, BLE_ERR_SUCCESS, evbuf, NULL); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 6e1cde5448..14cb954ebb 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -408,7 +408,6 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, { #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) struct ble_ll_sched_css *css = &g_ble_ll_sched_css; - struct ble_ll_conn_sm *connsm_ref; #endif struct ble_ll_sched_item *sch; uint32_t orig_start_time; @@ -504,18 +503,17 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, OS_ENTER_CRITICAL(sr); - connsm_ref = g_ble_ll_conn_css_ref; - if (!connsm_ref) { - g_ble_ll_conn_css_ref = connsm; - - css->period_anchor_slot_idx = connsm->css_slot_idx; - css->period_anchor_idx = 0; - css->period_anchor_ticks = adv_rxend; + if (!g_ble_ll_conn_css_ref) { + css->period_anchor_ticks = earliest_start; css->period_anchor_rem_us = 0; + css->period_anchor_idx = 0; + css->period_anchor_slot_idx = connsm->css_slot_idx; - connsm->css_period_idx = 1; + connsm->css_period_idx = 0; + max_delay = connsm->conn_itvl_ticks; } else { - connsm->css_period_idx = css->period_anchor_idx + 1; + connsm->css_period_idx = css->period_anchor_idx; + max_delay = 0; } ble_ll_sched_css_set_conn_anchor(connsm); @@ -531,11 +529,7 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, if (rem_us == 0) { sch->end_time--; } - - max_delay = 0; - #else - sch->start_time = earliest_start - g_ble_ll_sched_offset_ticks; sch->end_time = earliest_start + ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * @@ -548,13 +542,11 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, sch->remainder = 0; max_delay = connsm->conn_itvl_ticks - min_win_offset; - #endif OS_ENTER_CRITICAL(sr); rc = ble_ll_sched_insert(sch, max_delay, preempt_none); - if (rc == 0) { connsm->tx_win_off = ble_ll_tmr_t2u(sch->start_time - orig_start_time) / BLE_LL_CONN_TX_OFF_USECS; @@ -562,7 +554,6 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, connsm->anchor_point = sch->start_time + g_ble_ll_sched_offset_ticks; connsm->anchor_point_usecs = sch->remainder; connsm->ce_end_time = sch->end_time; - } OS_EXIT_CRITICAL(sr); @@ -1194,6 +1185,17 @@ ble_ll_sched_css_set_params(uint32_t slot_us, uint32_t period_slots) g_ble_ll_sched_css.period_slots = period_slots; } #endif +void +ble_ll_sched_css_update_anchor(struct ble_ll_conn_sm *connsm) +{ + struct ble_ll_sched_css *css = &g_ble_ll_sched_css; + + if (!g_ble_ll_conn_css_ref) { + g_ble_ll_conn_css_ref = connsm; + css->period_anchor_ticks = connsm->anchor_point; + css->period_anchor_rem_us = connsm->anchor_point_usecs; + } +} void ble_ll_sched_css_set_conn_anchor(struct ble_ll_conn_sm *connsm) From 586be82f68610aa51113cdc333f243d54e83ede7 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 9 Jun 2022 17:43:05 +0200 Subject: [PATCH 0439/1333] nimble/ll/css: Simplify slot move --- nimble/controller/src/ble_ll_conn.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 9199c8674d..94f0930eb8 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -463,15 +463,12 @@ ble_ll_conn_css_move(struct ble_ll_conn_sm *connsm, uint16_t slot_idx) (slot_idx != BLE_LL_CONN_CSS_NO_SLOT)); slot_diff = slot_idx - connsm->css_slot_idx; - - if (slot_diff > 0) { - offset = slot_diff * ble_ll_sched_css_get_slot_us() / - BLE_LL_CONN_ITVL_USECS; - } else { - offset = (ble_ll_sched_css_get_period_slots() + slot_diff) * - ble_ll_sched_css_get_slot_us() / BLE_LL_CONN_ITVL_USECS; + if (slot_diff < 0) { + slot_diff += ble_ll_sched_css_get_period_slots(); } + offset = slot_diff * ble_ll_sched_css_get_slot_us() / BLE_LL_CONN_ITVL_USECS; + if (offset >= 0xffff) { return -1; } From 37f3324a464ed2b88efb378994ce844b971fe04a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 9 Jun 2022 17:47:53 +0200 Subject: [PATCH 0440/1333] nimble/ll/css: Disallow conn update if css is enabled Since all central connections are fully managed by css, we shall reject any connection parameters change requested by host. --- nimble/controller/src/ble_ll_conn_hci.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 2ffda58a81..4617d3a75c 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -955,6 +955,15 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_UNK_CONN_ID; } +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + /* Do not allow connection update if css in enabled, we only allow to move + * anchor point (i.e. change slot) via dedicated HCI command. + */ + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + return BLE_ERR_CMD_DISALLOWED; + } +#endif + /* Better not have this procedure ongoing! */ if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ) || IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_UPDATE)) { From 9ad6b101d75c7a78a34edf6cae0048b8b92400c6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 13 Jun 2022 14:58:20 +0200 Subject: [PATCH 0441/1333] nimble/ll/css: Fix updating ref connsm after disconnection We should look for new reference connsm in critical section since ref connsm can be also accessed from isr code. --- nimble/controller/src/ble_ll_conn.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 94f0930eb8..d2ef1bfd83 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2077,6 +2077,7 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err) /* If current connection was reference for CSS, we need to find another * one. It does not matter which one we'll pick. */ + OS_ENTER_CRITICAL(sr); if (connsm == g_ble_ll_conn_css_ref) { SLIST_FOREACH(g_ble_ll_conn_css_ref, &g_ble_ll_conn_active_list, act_sle) { @@ -2085,6 +2086,7 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err) } } } + OS_EXIT_CRITICAL(sr); #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) From d7dc9d9ed7e3036c580e3a1314a86e7988c918b3 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 13 Jun 2022 14:58:35 +0200 Subject: [PATCH 0442/1333] nimble/ll/css: Ignore init slots for css --- nimble/controller/src/ble_ll_conn.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index d2ef1bfd83..67fbf4c5bf 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2532,11 +2532,16 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) } /* - * Calculate ce end time. For a peripgheral, we need to add window widening + * Calculate ce end time. For a peripheral, we need to add window widening * and the transmit window if we still have one. */ - ce_duration = ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * - BLE_LL_SCHED_USECS_PER_SLOT); + if (MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) && + connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + ce_duration = ble_ll_tmr_u2t(BLE_LL_SCHED_USECS_PER_SLOT); + } else { + ce_duration = ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * + BLE_LL_SCHED_USECS_PER_SLOT); + } #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { From 277fd466b81068e78457dacb653f4bb1c12fa371 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 14 Jun 2022 00:51:16 +0200 Subject: [PATCH 0443/1333] nimble/ll/css: Fix moving connection to an earlier slot Moving connection to an earlier slot means we are effectively skipping one period and we have to account for this, otherwise event counter and period index will be out of sync. The reason for this is because when moving to an earlier slot we have to wait for next connection event and then move anchor further by a tx win offset, so effectively we are in next period. --- nimble/controller/src/ble_ll_conn.c | 48 +++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 67fbf4c5bf..802429af49 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2230,7 +2230,9 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) uint16_t trans_next_event_cntr; uint16_t subrate_conn_upd_event_cntr; #endif - +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + uint8_t anchor_calc_for_css = 0; +#endif /* XXX: deal with connection request procedure here as well */ ble_ll_conn_chk_csm_flags(connsm); @@ -2356,11 +2358,12 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { connsm->css_period_idx += event_cntr_diff; - /* If this is non-reference connection, we set anchor from reference - * instead of calculating manually. + /* If this is non-reference connection, we calculate anchor point from + * reference connection instead of using connection interval. This is + * to make sure connections do not drift over time. */ if (g_ble_ll_conn_css_ref != connsm) { - ble_ll_sched_css_set_conn_anchor(connsm); + anchor_calc_for_css = 1; skip_anchor_calc = 1; } } @@ -2410,6 +2413,28 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) } #endif +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + BLE_LL_ASSERT(connsm->css_slot_idx_pending != + BLE_LL_CONN_CSS_NO_SLOT); + + /* If we are moving to an earlier slot, we are effectively skipping + * one period. + */ + if (connsm->css_slot_idx_pending < connsm->css_slot_idx) { + connsm->css_period_idx++; + } + + connsm->css_slot_idx = connsm->css_slot_idx_pending; + connsm->css_slot_idx_pending = BLE_LL_CONN_CSS_NO_SLOT; + + if (anchor_calc_for_css) { + ble_ll_sched_css_set_conn_anchor(connsm); + anchor_calc_for_css = 0; + } + } +#endif + connsm->supervision_tmo = upd->timeout; connsm->periph_latency = upd->latency; connsm->tx_win_size = upd->winsize; @@ -2430,15 +2455,6 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) /* Reset the starting point of the connection supervision timeout */ connsm->last_rxd_pdu_cputime = connsm->anchor_point; -#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { - BLE_LL_ASSERT(connsm->css_slot_idx_pending != - BLE_LL_CONN_CSS_NO_SLOT); - connsm->css_slot_idx = connsm->css_slot_idx_pending; - connsm->css_slot_idx_pending = BLE_LL_CONN_CSS_NO_SLOT; - } -#endif - /* Reset update scheduled flag */ connsm->csmflags.cfbit.conn_update_sched = 0; } @@ -2471,6 +2487,12 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) check to make sure we dont have to restart! */ } +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + if (anchor_calc_for_css) { + ble_ll_sched_css_set_conn_anchor(connsm); + } +#endif + #if (BLE_LL_BT5_PHY_SUPPORTED == 1) if (CONN_F_PHY_UPDATE_SCHED(connsm) && (connsm->event_cntr == connsm->phy_instant)) { From 42ad7e1c787f794510865b53bbe01ea620e44b34 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 14 Jun 2022 12:05:37 +0200 Subject: [PATCH 0444/1333] nimble/ll/css: Allow to change state in runtime This allows to control css state in runtime via HCI command. Default is disabled. --- .../include/controller/ble_ll_sched.h | 8 ++ nimble/controller/src/ble_ll_conn.c | 27 ++++-- nimble/controller/src/ble_ll_conn_hci.c | 3 +- nimble/controller/src/ble_ll_ctrl.c | 3 +- nimble/controller/src/ble_ll_hci_vs.c | 28 +++++- nimble/controller/src/ble_ll_sched.c | 93 +++++++++++-------- nimble/include/nimble/hci_common.h | 9 +- 7 files changed, 122 insertions(+), 49 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index 7dac849550..e50ebc5c70 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -179,9 +179,16 @@ int ble_ll_sched_dtm(struct ble_ll_sched_item *sch); #if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) void ble_ll_sched_css_set_params(uint32_t slot_us, uint32_t period_slots); #endif +void ble_ll_sched_css_set_enabled(uint8_t enabled); void ble_ll_sched_css_update_anchor(struct ble_ll_conn_sm *connsm); void ble_ll_sched_css_set_conn_anchor(struct ble_ll_conn_sm *connsm); #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) +static inline bool +ble_ll_sched_css_is_enabled(void) +{ + return true; +} + static inline uint32_t ble_ll_sched_css_get_slot_us(void) { @@ -201,6 +208,7 @@ ble_ll_sched_css_get_conn_interval_us(void) ble_ll_sched_css_get_slot_us() / 1250; } #else +bool ble_ll_sched_css_is_enabled(void); uint32_t ble_ll_sched_css_get_slot_us(void); uint32_t ble_ll_sched_css_get_period_slots(void); uint32_t ble_ll_sched_css_get_conn_interval_us(void); diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 802429af49..d25fca7a86 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1956,7 +1956,8 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) /* Add to list of active connections */ #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + if (ble_ll_sched_css_is_enabled() && + connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { /* We will insert sorted by css_slot_idx to make finding free slot * easier. */ @@ -2355,7 +2356,8 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) connsm->event_cntr = next_event_cntr; #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + if (ble_ll_sched_css_is_enabled() && + connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { connsm->css_period_idx += event_cntr_diff; /* If this is non-reference connection, we calculate anchor point from @@ -2414,7 +2416,8 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) #endif #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + if (ble_ll_sched_css_is_enabled() && + connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { BLE_LL_ASSERT(connsm->css_slot_idx_pending != BLE_LL_CONN_CSS_NO_SLOT); @@ -2557,13 +2560,21 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) * Calculate ce end time. For a peripheral, we need to add window widening * and the transmit window if we still have one. */ - if (MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) && +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + /* If css is enabled, use slot duration instead of conn_init_slots for + * reservation. + */ + if (ble_ll_sched_css_is_enabled() && connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { - ce_duration = ble_ll_tmr_u2t(BLE_LL_SCHED_USECS_PER_SLOT); + ce_duration = ble_ll_tmr_u2t(ble_ll_sched_css_get_slot_us()); } else { ce_duration = ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * BLE_LL_SCHED_USECS_PER_SLOT); } +#else + ce_duration = ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * + BLE_LL_SCHED_USECS_PER_SLOT); +#endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { @@ -2709,8 +2720,10 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_CONN_ROLE_CENTRAL: #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - ble_ll_sched_css_update_anchor(connsm); - ble_ll_conn_css_set_next_slot(BLE_LL_CONN_CSS_NO_SLOT); + if (ble_ll_sched_css_is_enabled()) { + ble_ll_sched_css_update_anchor(connsm); + ble_ll_conn_css_set_next_slot(BLE_LL_CONN_CSS_NO_SLOT); + } #endif evbuf = ble_ll_init_get_conn_comp_ev(); diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 4617d3a75c..625d8d24e9 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -959,7 +959,8 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) /* Do not allow connection update if css in enabled, we only allow to move * anchor point (i.e. change slot) via dedicated HCI command. */ - if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + if (ble_ll_sched_css_is_enabled() && + connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { return BLE_ERR_CMD_DISALLOWED; } #endif diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 07f303009c..911673beec 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -2246,7 +2246,8 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) /* Reject any attempts to change connection parameters by peripheral */ - if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + if (ble_ll_sched_css_is_enabled() && + connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { rsp_opcode = BLE_LL_CTRL_REJECT_IND_EXT; rspbuf[1] = BLE_LL_CTRL_CONN_PARM_REQ; rspbuf[2] = BLE_ERR_UNSUPPORTED; diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index f12657cc52..7504f10d2f 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -149,7 +149,8 @@ ble_ll_hci_vs_css_configure(const uint8_t *cmdbuf, uint8_t cmdlen, return BLE_ERR_INV_HCI_CMD_PARMS; } - if (!SLIST_EMPTY(&g_ble_ll_conn_active_list)) { + if (ble_ll_sched_css_is_enabled() && + !SLIST_EMPTY(&g_ble_ll_conn_active_list)) { return BLE_ERR_CTLR_BUSY; } @@ -170,6 +171,29 @@ ble_ll_hci_vs_css_configure(const uint8_t *cmdbuf, uint8_t cmdlen, } #endif +static int +ble_ll_hci_vs_css_enable(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_vs_css_enable_cp *cmd = (const void *)cmdbuf; + + if (cmdlen != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (!SLIST_EMPTY(&g_ble_ll_conn_active_list)) { + return BLE_ERR_CTLR_BUSY; + } + + if (cmd->enable & 0xfe) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + ble_ll_sched_css_set_enabled(cmd->enable); + + return BLE_ERR_SUCCESS; +} + static int ble_ll_hci_vs_css_set_next_slot(const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen) @@ -257,6 +281,8 @@ ble_ll_hci_vs_css(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, case BLE_HCI_VS_CSS_OP_CONFIGURE: return ble_ll_hci_vs_css_configure(cmdbuf, cmdlen, rspbuf, rsplen); #endif + case BLE_HCI_VS_CSS_OP_ENABLE: + return ble_ll_hci_vs_css_enable(cmdbuf, cmdlen, rspbuf, rsplen); case BLE_HCI_VS_CSS_OP_SET_NEXT_SLOT: return ble_ll_hci_vs_css_set_next_slot(cmdbuf, cmdlen, rspbuf, rsplen); case BLE_HCI_VS_CSS_OP_SET_CONN_SLOT: diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 14cb954ebb..036a3518d8 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -47,6 +47,7 @@ int32_t g_ble_ll_sched_max_early; #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) struct ble_ll_sched_css { + uint8_t enabled; #if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) uint32_t slot_us; uint32_t period_slots; @@ -408,15 +409,15 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, { #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) struct ble_ll_sched_css *css = &g_ble_ll_sched_css; + uint8_t rem_us; #endif struct ble_ll_sched_item *sch; uint32_t orig_start_time; uint32_t earliest_start; -#if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) uint32_t min_win_offset; -#endif uint32_t max_delay; uint32_t adv_rxend; + bool calc_sch = true; os_sr_t sr; int rc; @@ -499,51 +500,56 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, orig_start_time = earliest_start - g_ble_ll_sched_offset_ticks; #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - uint8_t rem_us; + if (ble_ll_sched_css_is_enabled()) { + OS_ENTER_CRITICAL(sr); - OS_ENTER_CRITICAL(sr); + if (!g_ble_ll_conn_css_ref) { + css->period_anchor_ticks = earliest_start; + css->period_anchor_rem_us = 0; + css->period_anchor_idx = 0; + css->period_anchor_slot_idx = connsm->css_slot_idx; - if (!g_ble_ll_conn_css_ref) { - css->period_anchor_ticks = earliest_start; - css->period_anchor_rem_us = 0; - css->period_anchor_idx = 0; - css->period_anchor_slot_idx = connsm->css_slot_idx; + connsm->css_period_idx = 0; + max_delay = connsm->conn_itvl_ticks; + } else { + connsm->css_period_idx = css->period_anchor_idx; + max_delay = 0; + } - connsm->css_period_idx = 0; - max_delay = connsm->conn_itvl_ticks; - } else { - connsm->css_period_idx = css->period_anchor_idx; - max_delay = 0; - } + ble_ll_sched_css_set_conn_anchor(connsm); - ble_ll_sched_css_set_conn_anchor(connsm); + sch->start_time = connsm->anchor_point - g_ble_ll_sched_offset_ticks; + sch->end_time = connsm->anchor_point; + sch->remainder = connsm->anchor_point_usecs; - sch->start_time = connsm->anchor_point - g_ble_ll_sched_offset_ticks; - sch->end_time = connsm->anchor_point; - sch->remainder = connsm->anchor_point_usecs; + OS_EXIT_CRITICAL(sr); - OS_EXIT_CRITICAL(sr); + rem_us = sch->remainder; + ble_ll_tmr_add(&sch->end_time, &rem_us, ble_ll_sched_css_get_slot_us()); + if (rem_us == 0) { + sch->end_time--; + } - rem_us = sch->remainder; - ble_ll_tmr_add(&sch->end_time, &rem_us, ble_ll_sched_css_get_slot_us()); - if (rem_us == 0) { - sch->end_time--; + calc_sch = false; } -#else - sch->start_time = earliest_start - g_ble_ll_sched_offset_ticks; - sch->end_time = earliest_start + - ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * - BLE_LL_SCHED_USECS_PER_SLOT); - - min_win_offset = ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET) * - BLE_LL_SCHED_USECS_PER_SLOT); - sch->start_time += min_win_offset; - sch->end_time += min_win_offset; - sch->remainder = 0; - - max_delay = connsm->conn_itvl_ticks - min_win_offset; #endif + if (calc_sch) { + sch->start_time = earliest_start - g_ble_ll_sched_offset_ticks; + sch->end_time = earliest_start + + ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) * + BLE_LL_SCHED_USECS_PER_SLOT); + + min_win_offset = ble_ll_tmr_u2t( + MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET) * + BLE_LL_SCHED_USECS_PER_SLOT); + sch->start_time += min_win_offset; + sch->end_time += min_win_offset; + sch->remainder = 0; + + max_delay = connsm->conn_itvl_ticks - min_win_offset; + } + OS_ENTER_CRITICAL(sr); rc = ble_ll_sched_insert(sch, max_delay, preempt_none); @@ -1185,6 +1191,13 @@ ble_ll_sched_css_set_params(uint32_t slot_us, uint32_t period_slots) g_ble_ll_sched_css.period_slots = period_slots; } #endif + +void +ble_ll_sched_css_set_enabled(uint8_t enabled) +{ + g_ble_ll_sched_css.enabled = enabled; +} + void ble_ll_sched_css_update_anchor(struct ble_ll_conn_sm *connsm) { @@ -1224,6 +1237,12 @@ ble_ll_sched_css_set_conn_anchor(struct ble_ll_conn_sm *connsm) } #if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) +inline bool +ble_ll_sched_css_is_enabled(void) +{ + return g_ble_ll_sched_css.enabled; +} + inline uint32_t ble_ll_sched_css_get_slot_us(void) { diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 14225f502f..881fe7450e 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1110,12 +1110,17 @@ struct ble_hci_vs_css_configure_cp { uint32_t slot_us; uint32_t period_slots; } __attribute__((packed)); -#define BLE_HCI_VS_CSS_OP_SET_NEXT_SLOT 0x02 +#define BLE_HCI_VS_CSS_OP_ENABLE 0x02 +struct ble_hci_vs_css_enable_cp { + uint8_t opcode; + uint8_t enable; +} __attribute__((packed)); +#define BLE_HCI_VS_CSS_OP_SET_NEXT_SLOT 0x03 struct ble_hci_vs_css_set_next_slot_cp { uint8_t opcode; uint16_t slot_idx; } __attribute__((packed)); -#define BLE_HCI_VS_CSS_OP_SET_CONN_SLOT 0x03 +#define BLE_HCI_VS_CSS_OP_SET_CONN_SLOT 0x04 struct ble_hci_vs_css_set_conn_slot_cp { uint8_t opcode; uint16_t conn_handle; From b4c43cf880cccccd90ac6865d000892ff671e399 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 15 Jun 2022 15:08:08 +0200 Subject: [PATCH 0445/1333] nimble/ll/css: Disallow slot change if css disabled --- nimble/controller/src/ble_ll_hci_vs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index 7504f10d2f..5aee70f8aa 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -233,6 +233,10 @@ ble_ll_hci_vs_css_set_conn_slot(const uint8_t *cmdbuf, uint8_t cmdlen, return BLE_ERR_INV_HCI_CMD_PARMS; } + if (!ble_ll_sched_css_is_enabled()) { + return BLE_ERR_CMD_DISALLOWED; + } + slot_idx = le16toh(cmd->slot_idx); if ((slot_idx >= ble_ll_sched_css_get_period_slots()) && (slot_idx != BLE_LL_CONN_CSS_NO_SLOT)) { From da153c43b34380f404f8dd83bba0e2dbfeeeb7c4 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 15 Jun 2022 15:09:00 +0200 Subject: [PATCH 0446/1333] nimble/ll/css: Rework slot management --- .../include/controller/ble_ll_conn.h | 1 + nimble/controller/src/ble_ll_conn.c | 134 +++++++++++------- nimble/controller/src/ble_ll_conn_hci.c | 10 ++ nimble/controller/src/ble_ll_conn_priv.h | 5 + nimble/controller/src/ble_ll_hci_vs.c | 2 +- 5 files changed, 100 insertions(+), 52 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 4215349fa9..13e9af00ba 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -389,6 +389,7 @@ struct ble_ll_conn_sm #endif #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + SLIST_ENTRY(ble_ll_conn_sm) css_sle; uint16_t css_slot_idx; uint16_t css_slot_idx_pending; uint8_t css_period_idx; diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index d25fca7a86..9dc897e5f0 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -167,6 +167,11 @@ struct ble_ll_conn_active_list g_ble_ll_conn_active_list; /* List of free connections */ struct ble_ll_conn_free_list g_ble_ll_conn_free_list; +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) +static uint16_t g_ble_ll_conn_css_next_slot = BLE_LL_CONN_CSS_NO_SLOT; +struct ble_ll_conn_css_list g_ble_ll_conn_css_list; +#endif + STATS_SECT_START(ble_ll_conn_stats) STATS_SECT_ENTRY(cant_set_sched) STATS_SECT_ENTRY(conn_ev_late) @@ -394,9 +399,52 @@ ble_ll_conn_cth_flow_process_cmd(const uint8_t *cmdbuf) } #endif - #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) -static uint16_t g_ble_ll_conn_css_next_slot = BLE_LL_CONN_CSS_NO_SLOT; +static void +ble_ll_conn_css_update_list(struct ble_ll_conn_sm *connsm) +{ + bool e_insert_found = false; + bool e_remove_found = false; + struct ble_ll_conn_sm *e_insert = NULL; + struct ble_ll_conn_sm *e_remove = NULL; + struct ble_ll_conn_sm *e_last = NULL; + struct ble_ll_conn_sm *e; + + SLIST_FOREACH(e, &g_ble_ll_conn_css_list, css_sle) { + if (!e_remove_found && (e == connsm)) { + e_remove_found = true; + e_remove = e_last; + } + if (!e_insert_found && (e->css_slot_idx > connsm->css_slot_idx)) { + e_insert_found = true; + e_insert = e_last; + } + + if (e_insert_found && e_remove_found) { + break; + } + + e_last = e; + } + + if (e_remove_found) { + if (e_remove == e_insert) { + return; + } else if (e_remove) { + SLIST_NEXT(e_remove, css_sle) = SLIST_NEXT(connsm, css_sle); + } else { + SLIST_REMOVE_HEAD(&g_ble_ll_conn_css_list, css_sle); + } + } + + if (!e_insert_found && !e && e_last) { + SLIST_INSERT_AFTER(e_last, connsm, css_sle); + } else if (e_insert) { + SLIST_INSERT_AFTER(e_insert, connsm, css_sle); + } else { + SLIST_INSERT_HEAD(&g_ble_ll_conn_css_list, connsm, css_sle); + } +} void ble_ll_conn_css_set_next_slot(uint16_t slot_idx) @@ -417,9 +465,8 @@ ble_ll_conn_css_get_next_slot(void) /* CSS connections are sorted in active conn list so just need to find 1st * free value. */ - SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) { - if ((connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) && - (connsm->css_slot_idx != slot_idx) && + SLIST_FOREACH(connsm, &g_ble_ll_conn_css_list, css_sle) { + if ((connsm->css_slot_idx != slot_idx) && (connsm->css_slot_idx_pending != slot_idx)) { break; } @@ -438,10 +485,13 @@ ble_ll_conn_css_is_slot_busy(uint16_t slot_idx) { struct ble_ll_conn_sm *connsm; - SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) { - if ((connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) && - ((connsm->css_slot_idx == slot_idx) || - (connsm->css_slot_idx_pending == slot_idx))) { + if (g_ble_ll_conn_css_next_slot == slot_idx) { + return 1; + } + + SLIST_FOREACH(connsm, &g_ble_ll_conn_css_list, css_sle) { + if ((connsm->css_slot_idx == slot_idx) || + (connsm->css_slot_idx_pending == slot_idx)) { return 1; } } @@ -1851,10 +1901,6 @@ void ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) { struct ble_ll_conn_global_params *conn_params; -#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - struct ble_ll_conn_sm *connsm_css_prev = NULL; - struct ble_ll_conn_sm *connsm_css; -#endif /* Reset following elements */ connsm->csmflags.conn_flags = 0; @@ -1955,35 +2001,12 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) #endif /* Add to list of active connections */ -#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - if (ble_ll_sched_css_is_enabled() && - connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { - /* We will insert sorted by css_slot_idx to make finding free slot - * easier. - */ - SLIST_FOREACH(connsm_css, &g_ble_ll_conn_active_list, act_sle) { - if ((connsm_css->conn_role == BLE_LL_CONN_ROLE_CENTRAL) && - (connsm_css->css_slot_idx > connsm->css_slot_idx)) { - if (connsm_css_prev) { - SLIST_INSERT_AFTER(connsm_css_prev, connsm, act_sle); - } - break; - } - connsm_css_prev = connsm_css; - } + SLIST_INSERT_HEAD(&g_ble_ll_conn_active_list, connsm, act_sle); - if (!connsm_css_prev) { - /* List was empty or need to insert before 1st connection */ - SLIST_INSERT_HEAD(&g_ble_ll_conn_active_list, connsm, act_sle); - } else if (!connsm_css) { - /* Insert at the end of list */ - SLIST_INSERT_AFTER(connsm_css_prev, connsm, act_sle); - } - } else { - SLIST_INSERT_HEAD(&g_ble_ll_conn_active_list, connsm, act_sle); +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + if (ble_ll_sched_css_is_enabled()) { + ble_ll_conn_css_update_list(connsm); } -#else - SLIST_INSERT_HEAD(&g_ble_ll_conn_active_list, connsm, act_sle); #endif } @@ -2075,19 +2098,18 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err) SLIST_REMOVE(&g_ble_ll_conn_active_list, connsm, ble_ll_conn_sm, act_sle); #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - /* If current connection was reference for CSS, we need to find another - * one. It does not matter which one we'll pick. - */ - OS_ENTER_CRITICAL(sr); - if (connsm == g_ble_ll_conn_css_ref) { - SLIST_FOREACH(g_ble_ll_conn_css_ref, &g_ble_ll_conn_active_list, - act_sle) { - if (g_ble_ll_conn_css_ref->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { - break; - } + if (ble_ll_sched_css_is_enabled() && + (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL)) { + /* If current connection was reference for CSS, we need to find another + * one. It does not matter which one we'll pick. + */ + OS_ENTER_CRITICAL(sr); + SLIST_REMOVE(&g_ble_ll_conn_css_list, connsm, ble_ll_conn_sm, css_sle); + if (connsm == g_ble_ll_conn_css_ref) { + g_ble_ll_conn_css_ref = SLIST_FIRST(&g_ble_ll_conn_css_list); } + OS_EXIT_CRITICAL(sr); } - OS_EXIT_CRITICAL(sr); #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) @@ -2431,6 +2453,8 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) connsm->css_slot_idx = connsm->css_slot_idx_pending; connsm->css_slot_idx_pending = BLE_LL_CONN_CSS_NO_SLOT; + ble_ll_conn_css_update_list(connsm); + if (anchor_calc_for_css) { ble_ll_sched_css_set_conn_anchor(connsm); anchor_calc_for_css = 0; @@ -4323,6 +4347,10 @@ ble_ll_conn_module_reset(void) g_ble_ll_conn_cth_flow.max_buffers = 1; g_ble_ll_conn_cth_flow.num_buffers = 1; #endif + +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + g_ble_ll_conn_css_next_slot = BLE_LL_CONN_CSS_NO_SLOT; +#endif } /* Initialize the connection module */ @@ -4337,6 +4365,10 @@ ble_ll_conn_module_init(void) SLIST_INIT(&g_ble_ll_conn_active_list); STAILQ_INIT(&g_ble_ll_conn_free_list); +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + SLIST_INIT(&g_ble_ll_conn_css_list); +#endif + /* * Take all the connections off the free memory pool and add them to * the free connection list, assigning handles in linear order. Note: diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 625d8d24e9..7a38f0ad7e 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -618,6 +618,11 @@ ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len) if (rc) { SLIST_REMOVE(&g_ble_ll_conn_active_list,connsm,ble_ll_conn_sm,act_sle); STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe); +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + if (ble_ll_sched_css_is_enabled()) { + SLIST_REMOVE(&g_ble_ll_conn_css_list, connsm, ble_ll_conn_sm, css_sle); + } +#endif } return rc; @@ -834,6 +839,11 @@ ble_ll_conn_hci_ext_create(const uint8_t *cmdbuf, uint8_t len) if (rc) { SLIST_REMOVE(&g_ble_ll_conn_active_list,connsm,ble_ll_conn_sm,act_sle); STAILQ_INSERT_TAIL(&g_ble_ll_conn_free_list, connsm, free_stqe); +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + if (ble_ll_sched_css_is_enabled()) { + SLIST_REMOVE(&g_ble_ll_conn_css_list, connsm, ble_ll_conn_sm, css_sle); + } +#endif } return rc; diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index 90c32c0c1e..d0c9111b40 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -104,6 +104,11 @@ STAILQ_HEAD(ble_ll_conn_free_list, ble_ll_conn_sm); extern struct ble_ll_conn_active_list g_ble_ll_conn_active_list; extern struct ble_ll_conn_free_list g_ble_ll_conn_free_list; +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) +SLIST_HEAD(ble_ll_conn_css_list, ble_ll_conn_sm); +extern struct ble_ll_conn_css_list g_ble_ll_conn_css_list; +#endif + struct ble_ll_conn_create_scan { uint8_t filter_policy; uint8_t own_addr_type; diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index 5aee70f8aa..8effae5422 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -150,7 +150,7 @@ ble_ll_hci_vs_css_configure(const uint8_t *cmdbuf, uint8_t cmdlen, } if (ble_ll_sched_css_is_enabled() && - !SLIST_EMPTY(&g_ble_ll_conn_active_list)) { + !SLIST_EMPTY(&g_ble_ll_conn_css_list)) { return BLE_ERR_CTLR_BUSY; } From 105771f3d911cc7b09e9a7760bc92b21c600df5c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 23 Jun 2022 22:16:45 +0200 Subject: [PATCH 0447/1333] nimble/transport: Add missing prototype for ble_monitor_out --- nimble/transport/include/nimble/transport/monitor.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/nimble/transport/include/nimble/transport/monitor.h b/nimble/transport/include/nimble/transport/monitor.h index 623dc54a7b..349f49d73b 100644 --- a/nimble/transport/include/nimble/transport/monitor.h +++ b/nimble/transport/include/nimble/transport/monitor.h @@ -30,9 +30,16 @@ extern "C" { MYNEWT_VAL(BLE_MONITOR_UART)) #if BLE_MONITOR +int ble_monitor_out(int c); int ble_monitor_log(int level, const char *fmt, ...); #else static inline int +ble_monitor_out(int c) +{ + (void)c; + return 0; +} +static inline int ble_monitor_log(int level, const char *fmt, ...) { (void)level; From 41708e93fb4e500cfd4ab84dd9507d3d96c29920 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 22 Jun 2022 19:27:41 +0200 Subject: [PATCH 0448/1333] nimble/ll: Update manufacturer id settings Rename BLE_LL_MFRG_ID to more readable BLE_LL_MANUFACTURER_ID and change default value to id assigned to Apache Foundation (0x0B65). --- nimble/controller/src/ble_ll_ctrl.c | 2 +- nimble/controller/src/ble_ll_hci.c | 2 +- nimble/controller/syscfg.defunct.yml | 4 ++++ nimble/controller/syscfg.yml | 6 +++--- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 911673beec..77f9b93ef2 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1867,7 +1867,7 @@ ble_ll_ctrl_version_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld) /* Fill out response */ pyld[0] = BLE_HCI_VER_BCS; - put_le16(pyld + 1, MYNEWT_VAL(BLE_LL_MFRG_ID)); + put_le16(pyld + 1, MYNEWT_VAL(BLE_LL_MANUFACTURER_ID)); put_le16(pyld + 3, BLE_LL_SUB_VERS_NR); } diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index ed543404ab..054fef90f0 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -211,7 +211,7 @@ ble_ll_hci_rd_local_version(uint8_t *rspbuf, uint8_t *rsplen) rsp->hci_ver = BLE_HCI_VER_BCS; rsp->hci_rev = 0; rsp->lmp_ver = BLE_LMP_VER_BCS; - rsp->manufacturer = htole16(MYNEWT_VAL(BLE_LL_MFRG_ID)); + rsp->manufacturer = htole16(MYNEWT_VAL(BLE_LL_MANUFACTURER_ID)); rsp->lmp_subver = 0; *rsplen = sizeof(*rsp); diff --git a/nimble/controller/syscfg.defunct.yml b/nimble/controller/syscfg.defunct.yml index da338458a4..10206da0be 100644 --- a/nimble/controller/syscfg.defunct.yml +++ b/nimble/controller/syscfg.defunct.yml @@ -42,6 +42,10 @@ syscfg.defs: description: use BLE_LL_SCAN_AUX_SEGMENT_CNT value: 0 deprecated: 1 + BLE_LL_MFRG_ID: + description: use BLE_LL_MANUFACTURER_ID + value: 0x0B65 + deprecated: 1 # defunct settings (to be removed eventually) BLE_DEVICE: diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 6ff7bdb32e..841380f90c 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -75,10 +75,10 @@ syscfg.defs: number of completed packets event to the host. Rate is in milliseconds. value: 2000 - BLE_LL_MFRG_ID: + BLE_LL_MANUFACTURER_ID: description: > - Manufacturer ID. Should be set to unique ID per manufacturer. - value: '0xFFFF' + Manufacturer ID, as assigned by Bluetooth SIG + value: MYNEWT_VAL(BLE_LL_MFRG_ID) # Configuration items for the number of duplicate advertisers and the # number of advertisers from which we have heard a scan response. From bb109d3ba400665a17c4f578f1997f445d4dd4e6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 22 Jun 2022 18:50:54 +0200 Subject: [PATCH 0449/1333] nimble/ll/css: Fix conn create hci with css disabled Need to skip conn interval checks if css is disabled. --- nimble/controller/src/ble_ll_conn_hci.c | 44 ++++++++++++++++--------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 7a38f0ad7e..fb77d668d7 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -514,7 +514,7 @@ ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len) uint16_t conn_itvl_min; uint16_t conn_itvl_max; #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - uint16_t css_slot_idx; + uint16_t css_slot_idx = 0; #endif int rc; @@ -537,9 +537,11 @@ ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len) } #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - css_slot_idx = ble_ll_conn_css_get_next_slot(); - if (css_slot_idx == BLE_LL_CONN_CSS_NO_SLOT) { - return BLE_ERR_MEM_CAPACITY; + if (ble_ll_sched_css_is_enabled()) { + css_slot_idx = ble_ll_conn_css_get_next_slot(); + if (css_slot_idx == BLE_LL_CONN_CSS_NO_SLOT) { + return BLE_ERR_MEM_CAPACITY; + } } #endif @@ -575,10 +577,14 @@ ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len) } #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - cc_params.conn_itvl = ble_ll_sched_css_get_conn_interval_us(); - if ((cc_params.conn_itvl < conn_itvl_min) || - (cc_params.conn_itvl > conn_itvl_max)) { - return BLE_ERR_INV_HCI_CMD_PARMS; + if (ble_ll_sched_css_is_enabled()) { + cc_params.conn_itvl = ble_ll_sched_css_get_conn_interval_us(); + if ((cc_params.conn_itvl < conn_itvl_min) || + (cc_params.conn_itvl > conn_itvl_max)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + } else { + cc_params.conn_itvl = conn_itvl_max; } #else cc_params.conn_itvl = conn_itvl_max; @@ -673,10 +679,14 @@ ble_ll_conn_hci_ext_create_parse_params(const struct conn_params *params, } #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - cc_params->conn_itvl = ble_ll_sched_css_get_conn_interval_us(); - if ((cc_params->conn_itvl < conn_itvl_min) || - (cc_params->conn_itvl > conn_itvl_max)) { - return BLE_ERR_INV_HCI_CMD_PARMS; + if (ble_ll_sched_css_is_enabled()) { + cc_params->conn_itvl = ble_ll_sched_css_get_conn_interval_us(); + if ((cc_params->conn_itvl < conn_itvl_min) || + (cc_params->conn_itvl > conn_itvl_max)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + } else { + cc_params->conn_itvl = conn_itvl_max; } #else cc_params->conn_itvl = conn_itvl_max; @@ -740,7 +750,7 @@ ble_ll_conn_hci_ext_create(const uint8_t *cmdbuf, uint8_t len) struct ble_ll_conn_sm *connsm; const struct init_phy *init_phy; #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - uint16_t css_slot_idx; + uint16_t css_slot_idx = 0; #endif int rc; @@ -765,9 +775,11 @@ ble_ll_conn_hci_ext_create(const uint8_t *cmdbuf, uint8_t len) } #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - css_slot_idx = ble_ll_conn_css_get_next_slot(); - if (css_slot_idx == BLE_LL_CONN_CSS_NO_SLOT) { - return BLE_ERR_MEM_CAPACITY; + if (ble_ll_sched_css_is_enabled()) { + css_slot_idx = ble_ll_conn_css_get_next_slot(); + if (css_slot_idx == BLE_LL_CONN_CSS_NO_SLOT) { + return BLE_ERR_MEM_CAPACITY; + } } #endif From 16f1e4d7b289f3eeee87e877e49dff11f5e81bfc Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 21 Jun 2022 16:32:54 +0200 Subject: [PATCH 0450/1333] nimble/ll: Fix race between conn event and created In rare cases it's possible that 1st connection event is fired before LL processed new connection, thus its state is set to idle. In such case we can just skip the event and LL will reschedule to next event, after the connection is fully created. --- nimble/controller/src/ble_ll_conn.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 9dc897e5f0..0e2dffa048 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1471,12 +1471,12 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) connsm = (struct ble_ll_conn_sm *)sch->cb_arg; g_ble_ll_conn_cur_sm = connsm; BLE_LL_ASSERT(connsm); + + /* In rare cases 1st connection event is fired before LL finished processing + * new connection. In such case just skip this connection event and LL will + * reschedule to next connection event. + */ if (connsm->conn_state == BLE_LL_CONN_STATE_IDLE) { - /* That should not happen. If it does it means connection - * is already closed - */ - STATS_INC(ble_ll_conn_stats, sched_start_in_idle); - BLE_LL_ASSERT(0); ble_ll_conn_current_sm_over(connsm); return BLE_LL_SCHED_STATE_DONE; } @@ -1597,10 +1597,7 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) } if (rc == BLE_LL_SCHED_STATE_DONE) { - ble_ll_event_add(&connsm->conn_ev_end); - ble_phy_disable(); - ble_ll_state_set(BLE_LL_STATE_STANDBY); - g_ble_ll_conn_cur_sm = NULL; + ble_ll_conn_current_sm_over(connsm); } /* Set time that we last serviced the schedule */ From 23ac4ee47b8029c639c65953aa42e9558c7815d4 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 21 Jun 2022 13:50:15 +0200 Subject: [PATCH 0451/1333] nimble/ll: Fix race between aux scan and scan disable It's possible that scheduled aux is being received while scan sm is being disabled. In such case aux should not be processed since it cannot be handled properly anyway. --- nimble/controller/src/ble_ll_scan.c | 8 ++++---- nimble/controller/src/ble_ll_scan_aux.c | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index d9d351786d..27f1e65a71 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -880,10 +880,6 @@ ble_ll_scan_sm_stop(int chk_disable) OS_ENTER_CRITICAL(sr); -#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - scansm->connsm = NULL; -#endif - /* Disable scanning state machine */ scansm->scan_enabled = 0; scansm->restart_timer_needed = 0; @@ -895,6 +891,10 @@ ble_ll_scan_sm_stop(int chk_disable) } #endif +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + scansm->connsm = NULL; +#endif + /* Update backoff if we failed to receive scan response */ if (scansm->scan_rsp_pending) { scansm->scan_rsp_pending = 0; diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 2eb915d0e3..2967083b27 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -1237,7 +1237,10 @@ ble_ll_scan_aux_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) rxinfo = &rxhdr->rxinfo; rxinfo->user_data = aux; - if (!crcok) { + /* It's possible that we received aux while scan was just being disabled in + * LL task. In such case simply ignore aux. + */ + if (!crcok || !ble_ll_scan_enabled()) { rxinfo->flags |= BLE_MBUF_HDR_F_IGNORED; goto done; } From 8c6289aadf65934c57e170322f947f2a66a109ea Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 23 Jun 2022 13:20:21 +0200 Subject: [PATCH 0452/1333] nimble/ll: Fix direct addr type for ext adv reports If direct address was an RPA and controller was not able to resolve it, the direct address type in extended advertising report shall be set to 0xFE. This fixes LL/SCN/DDI/BV-71-C. --- nimble/controller/src/ble_ll_scan.c | 8 ++++++++ nimble/controller/src/ble_ll_scan_aux.c | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 27f1e65a71..6359cf7c81 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -701,6 +701,14 @@ ble_ll_scan_send_adv_report(uint8_t pdu_type, } if (BLE_MBUF_HDR_TARGETA_RESOLVED(hdr)) { inita_type += 2; + } else { +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + if (scansm->ext_scanning) { + if (ble_ll_is_rpa(inita, inita_type)) { + inita_type = 0xfe; + } + } +#endif } #endif diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 2967083b27..999efcbad8 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -270,6 +270,8 @@ ble_ll_hci_ev_alloc_ext_adv_report_for_aux(struct ble_ll_scan_addr_data *addrd, #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) if (addrd->targeta_resolved) { report->dir_addr_type += 2; + } else if (ble_ll_is_rpa(addrd->targeta, addrd->targeta_type)) { + report->dir_addr_type = 0xfe; } #endif } @@ -451,7 +453,12 @@ ble_ll_hci_ev_update_ext_adv_report_from_ext(struct ble_hci_ev *hci_ev, report->dir_addr_type = (ble_ll_scan_get_own_addr_type() & 1) + 2; memcpy(report->dir_addr, ble_ll_scan_aux_get_own_addr(), 6); } else { - report->dir_addr_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_RXADD_MASK); + if (ble_ll_is_rpa(eh_data, pdu_hdr & BLE_ADV_PDU_HDR_RXADD_MASK)) { + report->dir_addr_type = 0xfe; + } else { + report->dir_addr_type = !!(pdu_hdr & + BLE_ADV_PDU_HDR_RXADD_MASK); + } memcpy(report->dir_addr, eh_data, 6); } #else From 3a3044d2ab8e653d6b6eb79369477f3f1059bd47 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 24 Jun 2022 12:51:23 +0200 Subject: [PATCH 0453/1333] nimble/ll: Fix reference to global channel map --- nimble/controller/src/ble_ll_adv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index dad69a0272..8e7df3a397 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1377,7 +1377,7 @@ ble_ll_adv_aux_calculate(struct ble_ll_adv_sm *advsm, g_ble_ll_data.chan_map); #else aux->chan = ble_ll_utils_remapped_channel(ble_ll_rand() % BLE_PHY_NUM_DATA_CHANS, - g_ble_ll_conn_params.central_chan_map); + g_ble_ll_data.chan_map); #endif rem_aux_data_len = AUX_DATA_LEN(advsm) - aux_data_offset; From dc5a32f3b8bbc7420926a1b44161fc5b63a243d0 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 20 Jun 2022 16:16:22 +0200 Subject: [PATCH 0454/1333] nimble/ll: Make LL task stack size configurable This commit makes LL stack size configurable. Depending on compiler and platform default value may not be enough. It was reported that on nRF52840 90 words is not enough even if Ext Adv is disabled. To keep things simple lets just increase default stack size to 120 word for all usecases (with exception of nRF51 where defults to 96 bytes). --- babblesim/hw/bsp/nrf52_bsim/syscfg.yml | 1 + nimble/controller/src/ble_ll.c | 15 ++------------- nimble/controller/syscfg.yml | 5 +++++ nimble/drivers/nrf51/pkg.yml | 3 +++ nimble/drivers/nrf51/syscfg.yml | 21 +++++++++++++++++++++ 5 files changed, 32 insertions(+), 13 deletions(-) create mode 100644 nimble/drivers/nrf51/syscfg.yml diff --git a/babblesim/hw/bsp/nrf52_bsim/syscfg.yml b/babblesim/hw/bsp/nrf52_bsim/syscfg.yml index 5a45e9d08a..c73106f326 100644 --- a/babblesim/hw/bsp/nrf52_bsim/syscfg.yml +++ b/babblesim/hw/bsp/nrf52_bsim/syscfg.yml @@ -72,3 +72,4 @@ syscfg.vals.BLE_CONTROLLER: OS_CPUTIME_FREQ: 32768 OS_CPUTIME_TIMER_NUM: 5 BLE_LL_RFMGMT_ENABLE_TIME: 1500 + BLE_LL_STACK_SIZE: 4000 diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index b4de889edb..cb6a6dc4fd 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -358,21 +358,10 @@ static void ble_ll_event_dbuf_overflow(struct ble_npl_event *ev); #endif #if MYNEWT - -#if BABBLESIM -#define BLE_LL_STACK_SIZE (4000) -#else /* The BLE LL task data structure */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -#define BLE_LL_STACK_SIZE (120) -#else -#define BLE_LL_STACK_SIZE (90) -#endif -#endif - struct os_task g_ble_ll_task; -OS_TASK_STACK_DEFINE(g_ble_ll_stack, BLE_LL_STACK_SIZE); +OS_TASK_STACK_DEFINE(g_ble_ll_stack, MYNEWT_VAL(BLE_LL_STACK_SIZE)); #endif /* MYNEWT */ @@ -1991,7 +1980,7 @@ ble_ll_init(void) /* Initialize the LL task */ os_task_init(&g_ble_ll_task, "ble_ll", ble_ll_task, NULL, MYNEWT_VAL(BLE_LL_PRIO), OS_WAIT_FOREVER, g_ble_ll_stack, - BLE_LL_STACK_SIZE); + MYNEWT_VAL(BLE_LL_STACK_SIZE)); #else /* diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 841380f90c..45fb461fe0 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -493,6 +493,11 @@ syscfg.defs: range: 1..257 value: 32 + BLE_LL_STACK_SIZE: + description: > + This is the stack size for LL task. + value: 120 + syscfg.vals.BLE_LL_CFG_FEAT_LL_EXT_ADV: BLE_LL_CFG_FEAT_LE_CSA2: 1 BLE_HW_WHITELIST_ENABLE: 0 diff --git a/nimble/drivers/nrf51/pkg.yml b/nimble/drivers/nrf51/pkg.yml index 816a563552..9311093b9c 100644 --- a/nimble/drivers/nrf51/pkg.yml +++ b/nimble/drivers/nrf51/pkg.yml @@ -29,3 +29,6 @@ pkg.apis: ble_driver pkg.deps: - nimble - nimble/controller + +# allows to override nimble/controller settings +pkg.subpriority: 1 diff --git a/nimble/drivers/nrf51/syscfg.yml b/nimble/drivers/nrf51/syscfg.yml new file mode 100644 index 0000000000..451742a61a --- /dev/null +++ b/nimble/drivers/nrf51/syscfg.yml @@ -0,0 +1,21 @@ +# 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. +# + + +syscfg.vals.!BLE_LL_CFG_FEAT_LL_EXT_ADV: + BLE_LL_STACK_SIZE: 96 From 55f1818d7d983966d877bcc00d9a1ae3559c1eff Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Fri, 17 Jun 2022 12:12:24 +0200 Subject: [PATCH 0455/1333] ble_conn: fix auth_pyld_timer memleak Every time a connection is made, the ble_npl_callout_init() is done. This causes a timer creation in some NPL cases (eg. FreeRTOS). The alloc behaviour of auth_pyld_timer is now in sync with ctrl_proc_rsp_timer that lives in the same struct. --- nimble/controller/src/ble_ll_conn.c | 4 ---- nimble/controller/src/ble_ll_conn_priv.h | 1 + nimble/controller/src/ble_ll_ctrl.c | 5 +++++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 0e2dffa048..e2eb33e3e3 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1991,10 +1991,6 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) connsm->auth_pyld_tmo = BLE_LL_CONN_DEF_AUTH_PYLD_TMO; CONN_F_LE_PING_SUPP(connsm) = 1; - ble_npl_callout_init(&connsm->auth_pyld_timer, - &g_ble_ll_data.ll_evq, - ble_ll_conn_auth_pyld_timer_cb, - connsm); #endif /* Add to list of active connections */ diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index d0c9111b40..846a6b644b 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -241,6 +241,7 @@ int ble_ll_conn_hci_subrate_req(const uint8_t *cmdbuf, uint8_t len, #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) void ble_ll_conn_auth_pyld_timer_start(struct ble_ll_conn_sm *connsm); +void ble_ll_conn_auth_pyld_timer_cb(struct ble_npl_event *ev); #else #define ble_ll_conn_auth_pyld_timer_start(x) #endif diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 77f9b93ef2..38b3b6d247 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -3224,5 +3224,10 @@ ble_ll_ctrl_init_conn_sm(struct ble_ll_conn_sm *connsm) { ble_npl_callout_init(&connsm->ctrl_proc_rsp_timer, &g_ble_ll_data.ll_evq, ble_ll_ctrl_proc_rsp_timer_cb, connsm); + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) + ble_npl_callout_init(&connsm->auth_pyld_timer, &g_ble_ll_data.ll_evq, + ble_ll_conn_auth_pyld_timer_cb, connsm); +#endif } #endif From acaa9351b1d8f58e25e014d61cc826df74c9991e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 24 Jun 2022 07:25:58 +0200 Subject: [PATCH 0456/1333] nimble/host/sm: rename BLE_SM_SC_LVL to BLE_SM_LVL This rename makes it consistent with Core specification Vol. 3, part C, 10.2.1 LE security mode 1. This level specifies security requirements for both SC and legacy pairing, not only SC. Updated description of this setting. --- nimble/host/src/ble_att_svr.c | 4 ++-- nimble/host/src/ble_sm.c | 6 +++--- nimble/host/syscfg.yml | 5 +++-- porting/examples/linux/include/syscfg/syscfg.h | 4 ++-- porting/examples/linux_blemesh/include/syscfg/syscfg.h | 4 ++-- porting/examples/nuttx/include/syscfg/syscfg.h | 4 ++-- porting/nimble/include/syscfg/syscfg.h | 4 ++-- porting/npl/riot/include/syscfg/syscfg.h | 4 ++-- 8 files changed, 18 insertions(+), 17 deletions(-) diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 0a03bcd388..1f97f82e28 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -2500,7 +2500,7 @@ ble_att_svr_rx_notify(uint16_t conn_handle, struct os_mbuf **rxom) /* All indications shall be confirmed, but only these with required * security established shall be pass to application */ - if (MYNEWT_VAL(BLE_SM_SC_LVL) >= 2 && !sec_state.encrypted) { + if (MYNEWT_VAL(BLE_SM_LVL) >= 2 && !sec_state.encrypted) { return 0; } @@ -2591,7 +2591,7 @@ ble_att_svr_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom) /* All indications shall be confirmed, but only these with required * security established shall be pass to application */ - if (MYNEWT_VAL(BLE_SM_SC_LVL) >= 2 && !sec_state.encrypted) { + if (MYNEWT_VAL(BLE_SM_LVL) >= 2 && !sec_state.encrypted) { goto done; } diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 5489551ae1..fa14a3675a 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -1737,10 +1737,10 @@ ble_sm_verify_auth_requirements(uint8_t cmd) return false; } } - /* Fail if Secure Connections level forces MITM protection and remote does not + /* Fail if security level forces MITM protection and remote does not * support it */ - if (MYNEWT_VAL(BLE_SM_SC_LVL) >= 3 && !(cmd & BLE_SM_PAIR_AUTHREQ_MITM)) { + if (MYNEWT_VAL(BLE_SM_LVL) >= 3 && !(cmd & BLE_SM_PAIR_AUTHREQ_MITM)) { return false; } return true; @@ -1823,7 +1823,7 @@ ble_sm_pair_req_rx(uint16_t conn_handle, struct os_mbuf **om, if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) { res->sm_err = BLE_SM_ERR_CMD_NOT_SUPP; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CMD_NOT_SUPP); - } else if (MYNEWT_VAL(BLE_SM_SC_LVL) == 1) { + } else if (MYNEWT_VAL(BLE_SM_LVL) == 1) { res->sm_err = BLE_SM_ERR_CMD_NOT_SUPP; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CMD_NOT_SUPP); } else if (req->max_enc_key_size < BLE_SM_PAIR_KEY_SZ_MIN) { diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index 046624022d..e9d984dc51 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -108,7 +108,7 @@ syscfg.defs: - 'BLE_SM_SC if 1' - '!BLE_SM_LEGACY if 1' - BLE_SM_SC_LVL: + BLE_SM_LVL: description: > Force global Secure Connections mode 1 level. This level describes requirements for pairing response/request received @@ -117,7 +117,8 @@ syscfg.defs: authentication requirements is granted - 2 - allow to pair despite MITM being on or off - 3 - allow to pair only when MITM protection is on - - 4 - allow to pair only when 128 bit key is used and MITM is on + - 4 - allow to pair only with Secure Connections and + when 128 bit key is used and MITM is on When set to 0 level is no forced and pairing is allowed for all requests/responses with valid values (for example pairing will be rejected with key longer than 128 bits). Successful pairing with diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index 14877d1617..65aa24ebbb 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -823,8 +823,8 @@ #define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_SC_LVL -#define MYNEWT_VAL_BLE_SM_SC_LVL (0) +#ifndef MYNEWT_VAL_BLE_SM_LVL +#define MYNEWT_VAL_BLE_SM_LVL (0) #endif #ifndef MYNEWT_VAL_BLE_SM_SC_ONLY diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 5fccff8a23..9fdaff3dfc 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -826,8 +826,8 @@ #define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_SC_LVL -#define MYNEWT_VAL_BLE_SM_SC_LVL (0) +#ifndef MYNEWT_VAL_BLE_SM_LVL +#define MYNEWT_VAL_BLE_SM_LVL (0) #endif #ifndef MYNEWT_VAL_BLE_SM_SC_ONLY diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index 435b3aebcd..fd9f45613d 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -825,8 +825,8 @@ #define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_SC_LVL -#define MYNEWT_VAL_BLE_SM_SC_LVL (0) +#ifndef MYNEWT_VAL_BLE_SM_LVL +#define MYNEWT_VAL_BLE_SM_LVL (0) #endif #ifndef MYNEWT_VAL_BLE_SM_SC_ONLY diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index ba2a292d79..a3602308f9 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -822,8 +822,8 @@ #define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_SC_LVL -#define MYNEWT_VAL_BLE_SM_SC_LVL (0) +#ifndef MYNEWT_VAL_BLE_SM_LVL +#define MYNEWT_VAL_BLE_SM_LVL (0) #endif #ifndef MYNEWT_VAL_BLE_SM_SC_ONLY diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 84bdea5ef7..2d5f4b2ee9 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1584,8 +1584,8 @@ #define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_SC_LVL -#define MYNEWT_VAL_BLE_SM_SC_LVL (0) +#ifndef MYNEWT_VAL_BLE_SM_LVL +#define MYNEWT_VAL_BLE_SM_LVL (0) #endif #ifndef MYNEWT_VAL_BLE_SM_SC_ONLY From e72da3a70b036bbcdc78461f3963edaf80f5885a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 24 Jun 2022 07:59:02 +0200 Subject: [PATCH 0457/1333] nimble/host/sm: check for SC in ble_sm_pair_req_rx if BLE_SM_SC_ONLY For BLE_SM_SC_ONLY mode it's mandatory to use SC. --- nimble/host/src/ble_sm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index fa14a3675a..7a0864f462 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -1832,10 +1832,12 @@ ble_sm_pair_req_rx(uint16_t conn_handle, struct os_mbuf **om, } else if (req->max_enc_key_size > BLE_SM_PAIR_KEY_SZ_MAX) { res->sm_err = BLE_SM_ERR_INVAL; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_INVAL); - } else if (MYNEWT_VAL(BLE_SM_SC_ONLY) && (req->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX)) { + } else if (MYNEWT_VAL(BLE_SM_SC_ONLY) && (req->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX) && + !(req->authreq & BLE_SM_PAIR_AUTHREQ_SC)) { /* Fail if Secure Connections Only mode is on and remote does not meet - * key size requirements - MITM was checked in last step - */ + * key size requirements - MITM was checked in last step. Fail if SC is not supported + * by peer. + */ res->sm_err = BLE_SM_ERR_ENC_KEY_SZ; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_ENC_KEY_SZ); } else if (!ble_sm_verify_auth_requirements(req->authreq)) { From d4d4f0d5f4b3c42f38778097488d0be880e8914a Mon Sep 17 00:00:00 2001 From: Onkar Date: Fri, 29 Apr 2022 12:02:02 +0530 Subject: [PATCH 0458/1333] Support for read and write suggested datalen cmds --- nimble/host/include/host/ble_gap.h | 54 ++++++++++++++++++++++++---- nimble/host/src/ble_gap.c | 24 +++++++++++-- nimble/host/src/ble_hs_hci_priv.h | 4 +++ nimble/host/src/ble_hs_hci_util.c | 56 ++++++++++++++++++++++++++++++ nimble/include/nimble/hci_common.h | 6 ++++ 5 files changed, 134 insertions(+), 10 deletions(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index d27b7f82cb..83aacacd23 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -1889,17 +1889,57 @@ int ble_gap_update_params(uint16_t conn_handle, * Configure LE Data Length in controller (OGF = 0x08, OCF = 0x0022). * * @param conn_handle Connection handle. - * @param tx_octets The preferred value of payload octets that the Controller - * should use for a new connection (Range - * 0x001B-0x00FB). - * @param tx_time The preferred maximum number of microseconds that the local Controller - * should use to transmit a single link layer packet - * (Range 0x0148-0x4290). + * @param tx_octets The preferred value of payload octets that the + * Controller should use for a new connection + * (Range 0x001B-0x00FB). + * @param tx_time The preferred maximum number of microseconds that + * the local Controller should use to transmit a single + * link layer packet (Range 0x0148-0x4290). * * @return 0 on success, * other error code on failure. */ -int ble_gap_set_data_len(uint16_t conn_handle, uint16_t tx_octets, uint16_t tx_time); +int ble_gap_set_data_len(uint16_t conn_handle, uint16_t tx_octets, + uint16_t tx_time); + +/** + * Read LE Suggested Default Data Length in controller + * (OGF = 0x08, OCF = 0x0024). + * + * @param out_sugg_max_tx_octets The Host's suggested value for the + * Controller's maximum transmitted number of + * payload octets in LL Data PDUs to be used + * for new connections. (Range 0x001B-0x00FB). + * @param out_sugg_max_tx_time The Host's suggested value for the + * Controller's maximum packet transmission + * time for packets containing LL Data PDUs to + * be used for new connections. + * (Range 0x0148-0x4290). + * + * @return 0 on success, + * other error code on failure. + */ +int ble_gap_read_sugg_def_data_len(uint16_t *out_sugg_max_tx_octets, + uint16_t *out_sugg_max_tx_time); + +/** + * Configure LE Suggested Default Data Length in controller + * (OGF = 0x08, OCF = 0x0024). + * + * @param sugg_max_tx_octets The Host's suggested value for the Controller's + * maximum transmitted number of payload octets in + * LL Data PDUs to be used for new connections. + * (Range 0x001B-0x00FB). + * @param sugg_max_tx_time The Host's suggested value for the Controller's + * maximum packet transmission time for packets + * containing LL Data PDUs to be used for new + * connections. (Range 0x0148-0x4290). + * + * @return 0 on success, + * other error code on failure. + */ +int ble_gap_write_sugg_def_data_len(uint16_t sugg_max_tx_octets, + uint16_t sugg_max_tx_time); /** * Initiates the GAP security procedure. diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 113a972d64..ed959957bf 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -5590,14 +5590,32 @@ ble_gap_update_params(uint16_t conn_handle, #endif } -int ble_gap_set_data_len(uint16_t conn_handle, uint16_t tx_octets, uint16_t tx_time) +int +ble_gap_set_data_len(uint16_t conn_handle, uint16_t tx_octets, + uint16_t tx_time) { return ble_hs_hci_util_set_data_len(conn_handle, tx_octets, tx_time); } +int +ble_gap_read_sugg_def_data_len(uint16_t *out_sugg_max_tx_octets, + uint16_t *out_sugg_max_tx_time) +{ + return ble_hs_hci_util_read_sugg_def_data_len(out_sugg_max_tx_octets, + out_sugg_max_tx_time); +} + +int +ble_gap_write_sugg_def_data_len(uint16_t sugg_max_tx_octets, + uint16_t sugg_max_tx_time) +{ + return ble_hs_hci_util_write_sugg_def_data_len(sugg_max_tx_octets, + sugg_max_tx_time); +} + /***************************************************************************** - * $security * - *****************************************************************************/ +* $security * +*****************************************************************************/ int ble_gap_security_initiate(uint16_t conn_handle) { diff --git a/nimble/host/src/ble_hs_hci_priv.h b/nimble/host/src/ble_hs_hci_priv.h index 47f3200817..9ff4c6f06e 100644 --- a/nimble/host/src/ble_hs_hci_priv.h +++ b/nimble/host/src/ble_hs_hci_priv.h @@ -103,6 +103,10 @@ int ble_hs_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi); int ble_hs_hci_util_set_random_addr(const uint8_t *addr); int ble_hs_hci_util_set_data_len(uint16_t conn_handle, uint16_t tx_octets, uint16_t tx_time); +int ble_hs_hci_util_read_sugg_def_data_len(uint16_t *out_sugg_max_tx_octets, + uint16_t *out_sugg_max_tx_time); +int ble_hs_hci_util_write_sugg_def_data_len(uint16_t sugg_max_tx_octets, + uint16_t sugg_max_tx_time); int ble_hs_hci_util_data_hdr_strip(struct os_mbuf *om, struct hci_data_hdr *out_hdr); int ble_hs_hci_evt_process(struct ble_hci_ev *ev); diff --git a/nimble/host/src/ble_hs_hci_util.c b/nimble/host/src/ble_hs_hci_util.c index 996e0fc107..14e55d52ed 100644 --- a/nimble/host/src/ble_hs_hci_util.c +++ b/nimble/host/src/ble_hs_hci_util.c @@ -157,6 +157,62 @@ ble_hs_hci_util_set_data_len(uint16_t conn_handle, uint16_t tx_octets, return 0; } +int +ble_hs_hci_util_read_sugg_def_data_len(uint16_t *out_sugg_max_tx_octets, + uint16_t *out_sugg_max_tx_time) +{ + struct ble_hci_le_rd_sugg_def_data_len_rp rsp; + int rc; + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_RD_SUGG_DEF_DATA_LEN), + NULL, 0, &rsp, sizeof(rsp)); + if (rc != 0) { + return rc; + } + + *out_sugg_max_tx_octets = le16toh(rsp.max_tx_octets); + *out_sugg_max_tx_time = le16toh(rsp.max_tx_time); + + if (*out_sugg_max_tx_octets < BLE_HCI_SUGG_DEF_DATALEN_TX_OCTETS_MIN || + *out_sugg_max_tx_octets > BLE_HCI_SUGG_DEF_DATALEN_TX_OCTETS_MAX) { + BLE_HS_LOG(WARN, + "received suggested maximum tx octets is out of range\n"); + } + + if (*out_sugg_max_tx_time < BLE_HCI_SUGG_DEF_DATALEN_TX_TIME_MIN || + *out_sugg_max_tx_time > BLE_HCI_SUGG_DEF_DATALEN_TX_TIME_MAX) { + BLE_HS_LOG(WARN, + "received suggested maximum tx time is out of range\n"); + } + + return 0; +} + +int +ble_hs_hci_util_write_sugg_def_data_len(uint16_t sugg_max_tx_octets, + uint16_t sugg_max_tx_time) +{ + struct ble_hci_le_wr_sugg_def_data_len_cp cmd; + + if (sugg_max_tx_octets < BLE_HCI_SUGG_DEF_DATALEN_TX_OCTETS_MIN || + sugg_max_tx_octets > BLE_HCI_SUGG_DEF_DATALEN_TX_OCTETS_MAX) { + return BLE_HS_EINVAL; + } + + if (sugg_max_tx_time < BLE_HCI_SUGG_DEF_DATALEN_TX_TIME_MIN || + sugg_max_tx_time > BLE_HCI_SUGG_DEF_DATALEN_TX_TIME_MAX) { + return BLE_HS_EINVAL; + } + + cmd.max_tx_octets = htole16(sugg_max_tx_octets); + cmd.max_tx_time = htole16(sugg_max_tx_time); + + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_WR_SUGG_DEF_DATA_LEN), + &cmd, sizeof(cmd), NULL, 0); +} + int ble_hs_hci_util_data_hdr_strip(struct os_mbuf *om, struct hci_data_hdr *out_hdr) diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 881fe7450e..17fa762722 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1320,6 +1320,12 @@ struct ble_hci_le_set_transmit_power_report_enable_cp { #define BLE_HCI_SET_DATALEN_TX_TIME_MIN (0x0148) #define BLE_HCI_SET_DATALEN_TX_TIME_MAX (0x4290) +/* --- LE read/write suggested default data length (OCF 0x0023 and 0x0024) */ +#define BLE_HCI_SUGG_DEF_DATALEN_TX_OCTETS_MIN (0x001b) +#define BLE_HCI_SUGG_DEF_DATALEN_TX_OCTETS_MAX (0x00fb) +#define BLE_HCI_SUGG_DEF_DATALEN_TX_TIME_MIN (0x0148) +#define BLE_HCI_SUGG_DEF_DATALEN_TX_TIME_MAX (0x4290) + /* --- LE read maximum default PHY (OCF 0x0030) */ #define BLE_HCI_LE_PHY_1M (1) #define BLE_HCI_LE_PHY_2M (2) From f64535def1db5021713506e1b165164a35e38519 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Tue, 14 Jun 2022 09:14:28 +0200 Subject: [PATCH 0459/1333] apps/blehci: Allow log/full implementation in syscfg blehci had log/stub hardwired in application. Now it can be swtiched to log/full in target if needed. --- apps/blehci/pkg.yml | 2 +- apps/blehci/syscfg.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/blehci/pkg.yml b/apps/blehci/pkg.yml index e385d7da5d..0c9e534b24 100644 --- a/apps/blehci/pkg.yml +++ b/apps/blehci/pkg.yml @@ -24,7 +24,7 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/sys/console" - - "@apache-mynewt-core/sys/log/stub" + - "@apache-mynewt-core/sys/log" - "@apache-mynewt-core/sys/stats/full" - "@apache-mynewt-core/kernel/os" - nimble/transport diff --git a/apps/blehci/syscfg.yml b/apps/blehci/syscfg.yml index ec20e68963..5ec89bcb9d 100644 --- a/apps/blehci/syscfg.yml +++ b/apps/blehci/syscfg.yml @@ -21,6 +21,7 @@ syscfg.vals: OS_MAIN_STACK_SIZE: 64 # Stub console CONSOLE_MODE: stub + LOG_IMPLEMENTATION: stub syscfg.vals.'!BLE_TRANSPORT_NETCORE': # Use UART by default if not built on netcore From 9883c2465c4a91103d563cf7c32a796a26a4cc42 Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Sat, 2 Jul 2022 17:57:00 +1000 Subject: [PATCH 0460/1333] docs: Fix a few typos There are small typos in: - apps/blehr/src/main.c - apps/ext_advertiser/src/main.c - nimble/controller/src/ble_ll.c - nimble/host/src/ble_att_svr.c - nimble/host/src/ble_hs_mbuf.c - nimble/host/src/ble_sm.c Fixes: - Should read `response` rather than `respose`. - Should read `measurement` rather than `measurment`. - Should read `largest` rather than `larget`. - Should read `instance` rather than `nstance`. - Should read `application` rather than `applicaiton`. - Should read `always` rather than `alwyas`. --- apps/blehr/src/main.c | 2 +- apps/ext_advertiser/src/main.c | 2 +- nimble/controller/src/ble_ll.c | 2 +- nimble/host/src/ble_att_svr.c | 2 +- nimble/host/src/ble_hs_mbuf.c | 2 +- nimble/host/src/ble_sm.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/blehr/src/main.c b/apps/blehr/src/main.c index e09349fa51..eb26322e0a 100644 --- a/apps/blehr/src/main.c +++ b/apps/blehr/src/main.c @@ -111,7 +111,7 @@ blehr_tx_hrate_stop(void) os_callout_stop(&blehr_tx_timer); } -/* Reset heartrate measurment */ +/* Reset heartrate measurement */ static void blehr_tx_hrate_reset(void) { diff --git a/apps/ext_advertiser/src/main.c b/apps/ext_advertiser/src/main.c index 9cb6c6fe57..ec7649ef43 100644 --- a/apps/ext_advertiser/src/main.c +++ b/apps/ext_advertiser/src/main.c @@ -421,7 +421,7 @@ static void start_periodic(void) ble_addr_t addr; int rc; - /* For periodic we use nstance with non-connectable advertising */ + /* For periodic we use instance with non-connectable advertising */ memset (¶ms, 0, sizeof(params)); /* advertise using random addr */ diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index cb6a6dc4fd..1c92cadab4 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1733,7 +1733,7 @@ ble_ll_pdu_max_tx_octets_get(uint32_t usecs, int phy_mode) * and this can happen if we changed connection form uncoded to coded phy. * However, the lower bound for conn max tx time (all of them) depends on * current phy (uncoded/coded) but it always allows to send at least 27 - * bytes of payload thus we alwyas return at least 27 from here. + * bytes of payload thus we always return at least 27 from here. * * Reference: * Core v5.0, Vol 6, Part B, section 4.5.10 diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 1f97f82e28..26ac14ceb9 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -1303,7 +1303,7 @@ ble_att_svr_build_read_type_rsp(uint16_t conn_handle, *rxom = NULL; os_mbuf_adj(txom, OS_MBUF_PKTLEN(txom)); - /* Allocate space for the respose base, but don't fill in the fields. They + /* Allocate space for the response base, but don't fill in the fields. They * get filled in at the end, when we know the value of the length field. */ diff --git a/nimble/host/src/ble_hs_mbuf.c b/nimble/host/src/ble_hs_mbuf.c index f4d6a790f9..b9a8ff215c 100644 --- a/nimble/host/src/ble_hs_mbuf.c +++ b/nimble/host/src/ble_hs_mbuf.c @@ -92,7 +92,7 @@ ble_hs_mbuf_l2cap_pkt(void) struct os_mbuf * ble_hs_mbuf_att_pkt(void) { - /* Prepare write request and response are the larget ATT commands which + /* Prepare write request and response are the largest ATT commands which * contain attribute data. */ return ble_hs_mbuf_gen_pkt(BLE_HCI_DATA_HDR_SZ + diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 7a0864f462..de1006bce0 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -1222,7 +1222,7 @@ ble_sm_retrieve_ltk(uint16_t ediv, uint64_t rand, uint8_t peer_addr_type, struct ble_store_key_sec key_sec; int rc; - /* Tell applicaiton to look up LTK by peer address and ediv/rand pair. */ + /* Tell application to look up LTK by peer address and ediv/rand pair. */ memset(&key_sec, 0, sizeof key_sec); key_sec.peer_addr.type = peer_addr_type; memcpy(key_sec.peer_addr.val, peer_addr, 6); From 26ccb8af1f3ea6ad81d5d7cbb762747c6e06a24b Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Sat, 2 Jul 2022 18:06:27 +1000 Subject: [PATCH 0461/1333] Update ble_hs_mbuf.c --- nimble/host/src/ble_hs_mbuf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nimble/host/src/ble_hs_mbuf.c b/nimble/host/src/ble_hs_mbuf.c index b9a8ff215c..a80392aa8e 100644 --- a/nimble/host/src/ble_hs_mbuf.c +++ b/nimble/host/src/ble_hs_mbuf.c @@ -95,9 +95,9 @@ ble_hs_mbuf_att_pkt(void) /* Prepare write request and response are the largest ATT commands which * contain attribute data. */ - return ble_hs_mbuf_gen_pkt(BLE_HCI_DATA_HDR_SZ + - BLE_L2CAP_HDR_SZ + - BLE_ATT_PREP_WRITE_CMD_BASE_SZ); + return ble_hs_mbuf_gen_pkt(BLE_HCI_DATA_HDR_SZ + + BLE_L2CAP_HDR_SZ + + BLE_ATT_PREP_WRITE_CMD_BASE_SZ); } struct os_mbuf * From 0df1f7ff0ea3383fe77894a204cf1044b3ed2bfc Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Mon, 4 Jul 2022 14:58:47 +0200 Subject: [PATCH 0462/1333] nimble/host/sm: rename remaining BLE_SM_SC_LVL to BLE_SM_LVL --- nimble/host/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index e9d984dc51..ec55878e07 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -103,7 +103,7 @@ syscfg.defs: requiring mode 1 level 1. value: 0 restrictions: - - 'BLE_SM_SC_LVL == 4 if 1' + - 'BLE_SM_LVL == 4 if 1' - BLE_SM_MITM - 'BLE_SM_SC if 1' - '!BLE_SM_LEGACY if 1' From 5932b3c2dd5275c83c10daa95c3e08ad9528f980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 18 Jul 2022 10:21:35 +0200 Subject: [PATCH 0463/1333] apps/bttester: do not distribute CSRK BLE_SM_OUR_KEY_DIST and BLE_SM_THEIR_KEY_DIST should be set to 3, as we do not support security mode 2 - CSRK shall not be distributed. --- apps/bttester/syscfg.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 330e38d0b8..0d975bd8f7 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -103,8 +103,8 @@ syscfg.vals: BLE_SM_BONDING: 1 BLE_SM_MITM: 0 BLE_SM_SC: 1 - BLE_SM_OUR_KEY_DIST: 7 - BLE_SM_THEIR_KEY_DIST: 7 + BLE_SM_OUR_KEY_DIST: 3 + BLE_SM_THEIR_KEY_DIST: 3 BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION: 1 BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL: 9 BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL: 30 From 9212b4f774c0218b6752825b892684e4f924aad0 Mon Sep 17 00:00:00 2001 From: Jakub Date: Tue, 26 Jul 2022 17:20:40 +0200 Subject: [PATCH 0464/1333] tools/hci_throughput: Custom transport option Added option to pass custom transport module. --- tools/hci_throughput/check_addr.py | 16 ++++++--- tools/hci_throughput/hci_device.py | 9 +++-- tools/hci_throughput/hci_socket.py | 1 - tools/hci_throughput/main.py | 27 ++++++++++---- tools/hci_throughput/transport_factory.py | 44 ++++++++++++++++------- 5 files changed, 69 insertions(+), 28 deletions(-) diff --git a/tools/hci_throughput/check_addr.py b/tools/hci_throughput/check_addr.py index a11a416d8f..7af76a117c 100644 --- a/tools/hci_throughput/check_addr.py +++ b/tools/hci_throughput/check_addr.py @@ -34,8 +34,15 @@ def parse_arguments(): sudo python check_addr.py -i 0 1 2') parser.add_argument('-i', '--indexes', type=str, nargs='*', help='specify hci adapters indexes', default=0) + parser.add_argument('-t', '--transport_directory', type=str, nargs='*', + help='specify hci transport directory path', default="default") try: args = parser.parse_args() + if (type(args.transport_directory) == list): + args.transport_directory = args.transport_directory.pop() + else: + args.transport_directory = args.transport_directory + except Exception as e: print(traceback.format_exc()) return args @@ -64,7 +71,7 @@ async def main(dev: hci_commands.HCI_Commands): task.cancel() return result -def check_addr(device_indexes: list, addresses: list) -> list: +def check_addr(device_indexes: list, addresses: list, transport_directory: str) -> list: util.configure_logging(f"log/check_addr.log", clear_log_file=True) logging.info(f"Devices indexes: {device_indexes}") @@ -73,8 +80,9 @@ def check_addr(device_indexes: list, addresses: list) -> list: asyncio.set_event_loop(loop) loop.set_debug(True) - transport = transport_factory.TransportFactory(device_index=index, - asyncio_loop=loop) + transport = transport_factory.TransportFactory(device_index=str(index), + asyncio_loop=loop, + transport_directory=transport_directory) bt_dev = hci_commands.HCI_Commands(send=transport.send, rx_buffer_q=transport.rx_buffer_q, @@ -96,7 +104,7 @@ def check_addr(device_indexes: list, addresses: list) -> list: args = parse_arguments() print(args) addresses = [] - addresses = check_addr(args.indexes, addresses) + addresses = check_addr(args.indexes, addresses, args.transport_directory) print(addresses) except Exception as e: print(traceback.format_exc()) diff --git a/tools/hci_throughput/hci_device.py b/tools/hci_throughput/hci_device.py index 0a20fed593..4950bf277a 100644 --- a/tools/hci_throughput/hci_device.py +++ b/tools/hci_throughput/hci_device.py @@ -33,6 +33,7 @@ show_tp_plots = False test_dir = None +transport_directory = None class ParentCalledException(KeyboardInterrupt): """ This exception is raised when e.g. parent process sends signal. @@ -273,7 +274,7 @@ def parse_cfg_files(args) -> dict: ini = { "own_address": args.own_addr, "own_address_type": args.own_addr_type, - "dev_index": str(args.dev_idx), + "dev_index": args.dev_idx, "peer_address": args.peer_addr, "peer_address_type": args.peer_addr_type, "peer_dev_index": args.peer_dev_idx @@ -282,8 +283,9 @@ def parse_cfg_files(args) -> dict: with open(args.init_file, "r") as file: init_file = yaml.safe_load(file) ini = init_file[args.mode] - global test_dir + global test_dir, transport_directory test_dir = init_file["test_dir"] + transport_directory = init_file["transport_directory"] with open(args.config_file) as f: cfg = yaml.safe_load(f) @@ -316,7 +318,8 @@ def main(): transport = transport_factory.TransportFactory(device_index=ini['dev_index'], device_mode=args.mode, - asyncio_loop=loop) + asyncio_loop=loop, + transport_directory=transport_directory) signal.signal(signal.SIGTERM, signal_handler) diff --git a/tools/hci_throughput/hci_socket.py b/tools/hci_throughput/hci_socket.py index f95ea86573..41c95eeee6 100644 --- a/tools/hci_throughput/hci_socket.py +++ b/tools/hci_throughput/hci_socket.py @@ -58,7 +58,6 @@ def __init__(self, device_index=0, device_mode=None, self.libc = ctypes.cdll.LoadLibrary('libc.so.6') self.rx_buffer_q = multiprocessing.Manager().Queue() self.counter = 0 - self.device_index = device_index self.device_mode = device_mode self.hci_socket = self.socket_create() diff --git a/tools/hci_throughput/main.py b/tools/hci_throughput/main.py index bbaf4d7cd6..047f300838 100644 --- a/tools/hci_throughput/main.py +++ b/tools/hci_throughput/main.py @@ -43,6 +43,9 @@ def parse_arguments(): parser.add_argument('-m', '--modes', type=str, nargs="*", help='devices modes - receiver, transmitter', choices=['rx', 'tx'], default=['rx', 'tx']) + parser.add_argument('-t', '--transport_directory', type=str, nargs='*', + help='specify hci transport directory path. \ + The default is linux socket', default=["default"]) parser.add_argument('-cf', '--config_file', type=str, nargs="*", help='configuration file for devices', default=["config.yaml"]) @@ -53,18 +56,20 @@ def parse_arguments(): print(f"Indexes: {args.indexes}") print(f"Modes: {args.modes}") + print(f"Transport directory: {args.transport_directory}") return args -def get_dev_addr_and_type(hci_indexes: list): +def get_dev_addr_and_type(hci_indexes: list, transport_directory: str): if (len(hci_indexes) != 2): raise Exception("HCI index error.") manager = multiprocessing.Manager() addr_list = manager.list() check_addrs_proc = multiprocessing.Process(target=check_addr.check_addr, name="Check addresses", - args=(hci_indexes, addr_list)) + args=(hci_indexes, addr_list, + transport_directory)) check_addrs_proc.start() print("check_addrs_proc pid: ", check_addrs_proc.pid) check_addrs_proc.join() @@ -89,7 +94,8 @@ def change_config_var(filename: str, group: str, variable: str, default_style=None, default_flow_style=False) -def get_init_dict(filename: str, args_list: list, modes: list, dir: str): +def get_init_dict(filename: str, args_list: list, modes: list, dir: str, + transport_directory: str): ini = { modes[0]:{ "dev_index": args_list[0][0], @@ -107,7 +113,8 @@ def get_init_dict(filename: str, args_list: list, modes: list, dir: str): "peer_address_type": args_list[0][1], "peer_address": args_list[0][2] }, - "test_dir": dir + "test_dir": dir, + "transport_directory": transport_directory } with open(filename, 'w') as file: @@ -142,7 +149,8 @@ def run_once(modes: list, cfg_file: str, init_file: str): def testing_variable_influence(cfg: dict, modes: list, cfg_file: str, - init_file: str, init_dict: dict, save_to_file: bool): + init_file: str, init_dict: dict, + save_to_file: bool): tp_test_counter = 1 changed_params_list = [] averages = [] @@ -201,18 +209,23 @@ def main(): init_file = "init.yaml" cfg_file = args.config_file[0] + if (type(args.transport_directory) == list): + args.transport_directory = args.transport_directory.pop() + else: + args.transport_directory = args.transport_directory with open(cfg_file, "r") as file: cfg = yaml.safe_load(file) - addr_list = get_dev_addr_and_type(args.indexes) + addr_list = get_dev_addr_and_type(args.indexes, args.transport_directory) if len(addr_list) != len(args.indexes): raise Exception("No device address received. Check HCI indexes.") print(f"Received: {addr_list}") test_dir_path = util.create_test_directory() init_dict = get_init_dict(filename=init_file, args_list=addr_list, - modes=args.modes, dir=test_dir_path) + modes=args.modes, dir=test_dir_path, + transport_directory=args.transport_directory) util.copy_config_files_to_test_directory([init_file, cfg_file], init_dict["test_dir"]) diff --git a/tools/hci_throughput/transport_factory.py b/tools/hci_throughput/transport_factory.py index 615bccf52a..7555c32001 100644 --- a/tools/hci_throughput/transport_factory.py +++ b/tools/hci_throughput/transport_factory.py @@ -18,21 +18,39 @@ # import hci_socket +import logging +import traceback +import sys + class TransportFactory: - def __init__(self, device_index=None, device_mode=None, - asyncio_loop=None) -> None: - if (type(device_index) == int or device_index.isnumeric()): - self.transport = hci_socket.HCI_User_Channel_Socket(int(device_index), - device_mode, asyncio_loop) - else: - raise Exception("No such transport found.") + def __init__(self, device_index: str = None, device_mode=None, + asyncio_loop=None, transport_directory=None) -> None: + if (device_index.isnumeric()): + self.transport = hci_socket.HCI_User_Channel_Socket(int(device_index), + device_mode, + asyncio_loop) + else: + try: + if (transport_directory != "default"): + sys.path.append(transport_directory) + print(sys.path) + import custom_transport + self.transport = custom_transport.Transport(device_index, + device_mode, + asyncio_loop) + else: + raise Exception( + "Device index and transport does not match.") + except Exception as e: + logging.error(traceback.format_exc()) + sys.exit() - self.rx_buffer_q = self.transport.rx_buffer_q - self.send = self.transport.send + self.rx_buffer_q = self.transport.rx_buffer_q + self.send = self.transport.send - def start(self): - self.transport.start() + def start(self): + self.transport.start() - def stop(self): - self.transport.stop() + def stop(self): + self.transport.stop() From c28ca3608259ea0840fdbdfc99ea0b09616bd8e5 Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 27 Jul 2022 10:26:41 +0200 Subject: [PATCH 0465/1333] tools/hci_throughput: fix coding style - PEP8 Fixed coding style to conform with PEP8. autopep8 --in-place --aggressive --aggressive --experimental --- tools/hci_throughput/check_addr.py | 36 ++-- tools/hci_throughput/hci.py | 170 ++++++++++++----- tools/hci_throughput/hci_commands.py | 215 ++++++++++++++-------- tools/hci_throughput/hci_device.py | 82 +++++---- tools/hci_throughput/hci_socket.py | 36 ++-- tools/hci_throughput/main.py | 15 +- tools/hci_throughput/throughput.py | 71 ++++--- tools/hci_throughput/transport_factory.py | 5 +- tools/hci_throughput/util.py | 13 +- 9 files changed, 409 insertions(+), 234 deletions(-) diff --git a/tools/hci_throughput/check_addr.py b/tools/hci_throughput/check_addr.py index 7af76a117c..4569131887 100644 --- a/tools/hci_throughput/check_addr.py +++ b/tools/hci_throughput/check_addr.py @@ -27,6 +27,7 @@ import util import transport_factory + def parse_arguments(): parser = argparse.ArgumentParser( description='Check HCI device address type and address', @@ -34,11 +35,16 @@ def parse_arguments(): sudo python check_addr.py -i 0 1 2') parser.add_argument('-i', '--indexes', type=str, nargs='*', help='specify hci adapters indexes', default=0) - parser.add_argument('-t', '--transport_directory', type=str, nargs='*', - help='specify hci transport directory path', default="default") + parser.add_argument( + '-t', + '--transport_directory', + type=str, + nargs='*', + help='specify hci transport directory path', + default="default") try: args = parser.parse_args() - if (type(args.transport_directory) == list): + if (isinstance(args.transport_directory, list)): args.transport_directory = args.transport_directory.pop() else: args.transport_directory = args.transport_directory @@ -47,6 +53,7 @@ def parse_arguments(): print(traceback.format_exc()) return args + async def main(dev: hci_commands.HCI_Commands): result = tuple() task = asyncio.create_task(dev.rx_buffer_q_wait()) @@ -54,24 +61,31 @@ async def main(dev: hci_commands.HCI_Commands): await dev.cmd_read_bd_addr() if hci.bdaddr != '00:00:00:00:00:00': - logging.info("Type public: %s, address: %s", hci.PUBLIC_ADDRESS_TYPE, hci.bdaddr) + logging.info("Type public: %s, address: %s", + hci.PUBLIC_ADDRESS_TYPE, hci.bdaddr) result = (0, hci.bdaddr) print("Public address: ", result) else: await dev.cmd_vs_read_static_addr() if hci.static_addr != '00:00:00:00:00:00': - logging.info("Type static random: %s, address: %s", hci.STATIC_RANDOM_ADDRESS_TYPE, hci.static_addr) + logging.info("Type static random: %s, address: %s", + hci.STATIC_RANDOM_ADDRESS_TYPE, hci.static_addr) result = (1, hci.static_addr) print("Static random address: ", result) else: addr = hci.gen_static_rand_addr() - logging.info("Type static random: %s, generated address: %s", hci.STATIC_RANDOM_ADDRESS_TYPE, addr) + logging.info("Type static random: %s, generated address: %s", + hci.STATIC_RANDOM_ADDRESS_TYPE, addr) result = (1, addr) print("Generated static random address: ", result) task.cancel() return result -def check_addr(device_indexes: list, addresses: list, transport_directory: str) -> list: + +def check_addr( + device_indexes: list, + addresses: list, + transport_directory: str) -> list: util.configure_logging(f"log/check_addr.log", clear_log_file=True) logging.info(f"Devices indexes: {device_indexes}") @@ -80,9 +94,8 @@ def check_addr(device_indexes: list, addresses: list, transport_directory: str) asyncio.set_event_loop(loop) loop.set_debug(True) - transport = transport_factory.TransportFactory(device_index=str(index), - asyncio_loop=loop, - transport_directory=transport_directory) + transport = transport_factory.TransportFactory(device_index=str( + index), asyncio_loop=loop, transport_directory=transport_directory) bt_dev = hci_commands.HCI_Commands(send=transport.send, rx_buffer_q=transport.rx_buffer_q, @@ -104,7 +117,8 @@ def check_addr(device_indexes: list, addresses: list, transport_directory: str) args = parse_arguments() print(args) addresses = [] - addresses = check_addr(args.indexes, addresses, args.transport_directory) + addresses = check_addr(args.indexes, addresses, + args.transport_directory) print(addresses) except Exception as e: print(traceback.format_exc()) diff --git a/tools/hci_throughput/hci.py b/tools/hci_throughput/hci.py index 6ed45625f5..d0a0b8a1e5 100644 --- a/tools/hci_throughput/hci.py +++ b/tools/hci_throughput/hci.py @@ -88,7 +88,7 @@ ############ # GLOBAL VAR ############ -num_of_bytes_to_send = None # based on supported_max_tx_octets +num_of_bytes_to_send = None # based on supported_max_tx_octets num_of_packets_to_send = None events_list = [] @@ -103,44 +103,53 @@ phy = None ev_num_comp_pkts = None num_of_completed_packets_cnt = 0 -num_of_completed_packets_time = 0 +num_of_completed_packets_time = 0 read_local_commands = None le_read_local_supported_features = None ############ # FUNCTIONS ############ + + def get_opcode(ogf: int, ocf: int): - return ((ocf & 0x03ff)|(ogf << 10)) + return ((ocf & 0x03ff) | (ogf << 10)) + def get_ogf_ocf(opcode: int): ogf = opcode >> 10 ocf = opcode & 0x03ff return ogf, ocf + def cmd_addr_to_ba(addr_str: str): return unhexlify("".join(addr_str.split(':')))[::-1] + def ba_addr_to_str(addr_ba: bytearray): addr_str = addr_ba.hex().upper() - return ':'.join(addr_str[i:i+2] for i in range(len(addr_str), -2, -2))[1:] + return ':'.join(addr_str[i:i + 2] + for i in range(len(addr_str), -2, -2))[1:] + def gen_static_rand_addr(): while True: - x = [random.randint(0,1) for _ in range(0,48)] + x = [random.randint(0, 1) for _ in range(0, 48)] if 0 in x[:-2] and 1 in x[:-2]: x[0] = 1 x[1] = 1 break - addr_int = int("".join([str(x[i]) for i in range(0,len(x))]), 2) + addr_int = int("".join([str(x[i]) for i in range(0, len(x))]), 2) addr_hex = "{0:0{1}x}".format(addr_int, 12) - addr = ":".join(addr_hex[i:i+2] for i in range(0, len(addr_hex), 2)) + addr = ":".join(addr_hex[i:i + 2] for i in range(0, len(addr_hex), 2)) return addr.upper() ############ # GLOBAL VAR CLASSES ############ + + @dataclass class Suggested_Dflt_Data_Length(): status: int @@ -150,11 +159,16 @@ class Suggested_Dflt_Data_Length(): def __init__(self): self.set() - def set(self, status=0, suggested_max_tx_octets=0, suggested_max_tx_time=0): + def set( + self, + status=0, + suggested_max_tx_octets=0, + suggested_max_tx_time=0): self.status = status self.suggested_max_tx_octets = suggested_max_tx_octets self.suggested_max_tx_time = suggested_max_tx_time + @dataclass class Max_Data_Length(): status: int @@ -174,6 +188,7 @@ def set(self, status=0, supported_max_tx_octets=0, supported_max_tx_time=0, self.supported_max_rx_octets = supported_max_rx_octets self.supported_max_rx_time = supported_max_rx_time + @dataclass class LE_Read_Buffer_Size: status: int @@ -194,6 +209,7 @@ def set(self, status=0, le_acl_data_packet_length=0, self.iso_data_packet_len = iso_data_packet_len self.total_num_iso_data_packets = total_num_iso_data_packets + @dataclass class LE_Read_PHY: status: int @@ -210,6 +226,7 @@ def set(self, status=0, connection_handle=0, tx_phy=0, rx_phy=0): self.tx_phy = tx_phy self.rx_phy = rx_phy + @dataclass class Read_Local_Commands: status: int @@ -218,10 +235,11 @@ class Read_Local_Commands: def __init__(self): self.set() - def set(self, rcv_bytes = bytes(65)): + def set(self, rcv_bytes=bytes(65)): self.status = int(rcv_bytes[0]) self.supported_commands = rcv_bytes[1:] + @dataclass class LE_Read_Local_Supported_Features: status: int @@ -230,14 +248,16 @@ class LE_Read_Local_Supported_Features: def __init__(self): self.set() - def set(self, rcv_bytes = bytes(9)): + def set(self, rcv_bytes=bytes(9)): self.status = int(rcv_bytes[0]) - self.le_features = ctypes.c_uint64.from_buffer_copy(rcv_bytes[1:]).value + self.le_features = ctypes.c_uint64.from_buffer_copy( + rcv_bytes[1:]).value ############ # EVENTS ############ + @dataclass class HCI_Ev_Disconn_Complete: status: int @@ -252,6 +272,7 @@ def set(self, status=0, connection_handle=0, reason=0): self.connection_handle = connection_handle self.reason = reason + @dataclass class HCI_Ev_Cmd_Complete: num_hci_command_packets: int @@ -266,6 +287,7 @@ def set(self, num_hci_cmd_packets=0, opcode=0, return_parameters=b''): self.opcode = opcode self.return_parameters = return_parameters + @dataclass class HCI_Ev_Cmd_Status: status: int @@ -275,11 +297,12 @@ class HCI_Ev_Cmd_Status: def __init__(self): self.set() - def set(self, status = 0, num_hci_cmd_packets=0, opcode=0): + def set(self, status=0, num_hci_cmd_packets=0, opcode=0): self.status = status self.num_hci_command_packets = num_hci_cmd_packets self.opcode = opcode + @dataclass class HCI_Ev_LE_Meta: subevent_code: int @@ -327,6 +350,7 @@ def set(self, subevent_code=0, status=0, connection_handle=0, role=0, self.supervision_timeout = supervision_timeout self.central_clock_accuracy = central_clock_accuracy + @dataclass class HCI_Ev_LE_Data_Length_Change(HCI_Ev_LE_Meta): conn_handle: int @@ -341,13 +365,14 @@ def __init__(self): def set(self, subevent_code=0, conn_handle=0, max_tx_octets=0, max_tx_time=0, max_rx_octets=0, max_rx_time=0, triggered=0): - super().set(subevent_code) - self.conn_handle = conn_handle - self.max_tx_octets = max_tx_octets - self.max_tx_time = max_tx_time - self.max_rx_octets = max_rx_octets - self.max_rx_time = max_rx_time - self.triggered = triggered + super().set(subevent_code) + self.conn_handle = conn_handle + self.max_tx_octets = max_tx_octets + self.max_tx_time = max_tx_time + self.max_rx_octets = max_rx_octets + self.max_rx_time = max_rx_time + self.triggered = triggered + @dataclass class HCI_Ev_LE_PHY_Update_Complete(HCI_Ev_LE_Meta): @@ -367,6 +392,7 @@ def set(self, subevent_code=0, status=0, connection_handle=0, self.tx_phy = tx_phy self.rx_phy = rx_phy + @dataclass class HCI_Number_Of_Completed_Packets: num_handles: int @@ -381,6 +407,7 @@ def set(self, num_handles=0, connection_handle=0, num_completed_packets=0): self.connection_handle = connection_handle self.num_completed_packets = num_completed_packets + class HCI_Ev_LE_Chan_Sel_Alg(HCI_Ev_LE_Meta): connection_handle: int algorithm: int @@ -396,6 +423,8 @@ def set(self, subevent_code=0, connection_handle=0, algorithm=0): ############ # PARAMETERS ############ + + @dataclass class HCI_Advertising: advertising_interval_min: int @@ -411,9 +440,9 @@ class HCI_Advertising: def __init__(self): self.set() - def set(self, advertising_interval_min=0, advertising_interval_max=0, \ - advertising_type=0, own_address_type=0, peer_address_type=0, \ - peer_address='00:00:00:00:00:00', advertising_channel_map=0, \ + def set(self, advertising_interval_min=0, advertising_interval_max=0, + advertising_type=0, own_address_type=0, peer_address_type=0, + peer_address='00:00:00:00:00:00', advertising_channel_map=0, advertising_filter_policy=0): self.advertising_interval_min = advertising_interval_min self.advertising_interval_max = advertising_interval_max @@ -423,13 +452,20 @@ def set(self, advertising_interval_min=0, advertising_interval_max=0, \ self.peer_address = peer_address self.advertising_channel_map = advertising_channel_map self.advertising_filter_policy = advertising_filter_policy - self.ba_full_message = bytearray(struct.pack(' int: - current_ev_name = type(self.hci_recv_ev_packet.current_event).__name__ + current_ev_name = type( + self.hci_recv_ev_packet.current_event).__name__ if current_ev_name == type(hci.HCI_Ev_Cmd_Complete()).__name__: - return struct.unpack_from(" int: elif ogf == hci.OGF_INFO_PARAM: if ocf == hci.OCF_READ_LOCAL_COMMANDS: hci.read_local_commands = hci.Read_Local_Commands() - hci.read_local_commands.set(bytes(current_ev.return_parameters)) + hci.read_local_commands.set( + bytes(current_ev.return_parameters)) return status() elif ocf == hci.OCF_READ_BD_ADDR: hci.bdaddr = hci.ba_addr_to_str( - bytes(current_ev.return_parameters[1:7])) + bytes(current_ev.return_parameters[1:7])) return status() elif ogf == hci.OGF_LE_CTL: @@ -409,7 +435,8 @@ def status() -> int: return hci.le_read_buffer_size.status elif ocf == hci.OCF_LE_READ_LOCAL_SUPPORTED_FEATURES: hci.le_read_local_supported_features = hci.LE_Read_Local_Supported_Features() - hci.le_read_local_supported_features.set(current_ev.return_parameters) + hci.le_read_local_supported_features.set( + current_ev.return_parameters) return status() elif ocf == hci.OCF_LE_SET_RANDOM_ADDRESS: return status() @@ -429,18 +456,22 @@ def status() -> int: hci.suggested_dflt_data_len = hci.Suggested_Dflt_Data_Length() hci.suggested_dflt_data_len.set(*struct.unpack(" hci.max_data_len.supported_max_tx_octets - hci.L2CAP_HDR_BYTES): - logging.critical(f"Number of data bytes to send + 4 bytes of L2CAP header: {hci.num_of_bytes_to_send + 4} " - f"exceeds allowed value of: {hci.max_data_len.supported_max_tx_octets}. Closing.") - raise SystemExit(f"Number of data bytes to send + 4 bytes of L2CAP header: {hci.num_of_bytes_to_send + 4} " - f"exceeds allowed value of: {hci.max_data_len.supported_max_tx_octets}. Closing.") + if (hci.num_of_bytes_to_send > + hci.max_data_len.supported_max_tx_octets - hci.L2CAP_HDR_BYTES): + logging.critical( + f"Number of data bytes to send + 4 bytes of L2CAP header: {hci.num_of_bytes_to_send + 4} " + f"exceeds allowed value of: {hci.max_data_len.supported_max_tx_octets}. Closing.") + raise SystemExit( + f"Number of data bytes to send + 4 bytes of L2CAP header: {hci.num_of_bytes_to_send + 4} " + f"exceeds allowed value of: {hci.max_data_len.supported_max_tx_octets}. Closing.") return status() elif ocf == hci.OCF_LE_READ_PHY: @@ -456,9 +487,10 @@ def status() -> int: elif ogf == hci.OGF_VENDOR_SPECIFIC: if ocf == hci.BLE_HCI_OCF_VS_RD_STATIC_ADDR: - if type(current_ev).__name__ == type(hci.HCI_Ev_Cmd_Complete()).__name__: + if type(current_ev).__name__ == type( + hci.HCI_Ev_Cmd_Complete()).__name__: hci.static_addr = hci.ba_addr_to_str( - bytes(current_ev.return_parameters[1:7])) + bytes(current_ev.return_parameters[1:7])) logging.info(f"Received rd static addr: {hci.static_addr}") elif type(current_ev).__name__ == type(hci.HCI_Ev_Cmd_Status()).__name__: logging.info(f"Rd static addr status: {current_ev.status}") @@ -484,39 +516,43 @@ def parse_acl_data(self, buffer: bytes): l2cap_data = buffer[5:] hci_recv_acl_data_packet.set( - packet_type=packet_type, - connection_handle=handle, - pb_flag=pb_flag, - bc_flag=bc_flag, - total_data_len=data_len, - data=l2cap_data) + packet_type=packet_type, + connection_handle=handle, + pb_flag=pb_flag, + bc_flag=bc_flag, + total_data_len=data_len, + data=l2cap_data) return hci_recv_acl_data_packet def parse_subevent(self, subev_code: int): if subev_code == hci.HCI_SUBEV_CODE_LE_ENHANCED_CONN_CMP: self.hci_recv_ev_packet.current_event = \ - self.parse_subev_le_enhcd_conn_cmp(self.hci_recv_ev_packet.recv_data) + self.parse_subev_le_enhcd_conn_cmp( + self.hci_recv_ev_packet.recv_data) hci.events_list.append((hci.HCI_SUBEV_CODE_LE_ENHANCED_CONN_CMP, self.hci_recv_ev_packet.current_event)) return hci.HCI_SUBEV_CODE_LE_ENHANCED_CONN_CMP elif subev_code == hci.HCI_SUBEV_CODE_LE_DATA_LEN_CHANGE: self.hci_recv_ev_packet.current_event = \ - self.parse_subev_le_data_len_change(self.hci_recv_ev_packet.recv_data) + self.parse_subev_le_data_len_change( + self.hci_recv_ev_packet.recv_data) hci.events_list.append((hci.HCI_SUBEV_CODE_LE_DATA_LEN_CHANGE, self.hci_recv_ev_packet.current_event)) return hci.HCI_SUBEV_CODE_LE_DATA_LEN_CHANGE elif subev_code == hci.HCI_SUBEV_CODE_LE_PHY_UPDATE_CMP: self.hci_recv_ev_packet.current_event = \ - self.parse_subev_le_phy_update_cmp(self.hci_recv_ev_packet.recv_data) + self.parse_subev_le_phy_update_cmp( + self.hci_recv_ev_packet.recv_data) hci.events_list.append((hci.HCI_SUBEV_CODE_LE_PHY_UPDATE_CMP, self.hci_recv_ev_packet.current_event)) return hci.HCI_SUBEV_CODE_LE_PHY_UPDATE_CMP elif subev_code == hci.HCI_SUBEV_CODE_LE_CHAN_SEL_ALG: self.hci_recv_ev_packet.current_event = \ - self.parse_subev_le_chan_sel_alg(self.hci_recv_ev_packet.recv_data) + self.parse_subev_le_chan_sel_alg( + self.hci_recv_ev_packet.recv_data) hci.events_list.append((hci.HCI_SUBEV_CODE_LE_CHAN_SEL_ALG, self.hci_recv_ev_packet.current_event)) return hci.HCI_SUBEV_CODE_LE_CHAN_SEL_ALG @@ -526,26 +562,26 @@ def parse_subevent(self, subev_code: int): def parse_event(self, buffer: bytes): self.hci_recv_ev_packet.set(*struct.unpack(' 0 and packets_to_send > 0: - data, last_value = tp.gen_data(hci.num_of_bytes_to_send, last_value) + data, last_value = tp.gen_data( + hci.num_of_bytes_to_send, last_value) l2cap_data.set(channel_id=0x0044, data=data) - acl_data.set(connection_handle=hci.conn_handle, pb_flag=0b00, bc_flag=0b00, - data=l2cap_data.ba_full_message) + acl_data.set(connection_handle=hci.conn_handle, pb_flag=0b00, + bc_flag=0b00, data=l2cap_data.ba_full_message) await bt_dev.acl_data_send(acl_data) async with bt_dev.async_lock_packets_cnt: packets_to_send -= 1 @@ -262,7 +269,6 @@ async def async_main_tx(bt_dev: hci_commands.HCI_Commands, ini: dict, cfg: dict) packet_credits += hci.num_of_completed_packets_cnt hci.num_of_completed_packets_cnt = 0 - for timestamp in tx_sent_timestamps: bt_dev.tp.append_to_csv_file(*timestamp) @@ -301,7 +307,8 @@ def parse_cfg_files(args) -> dict: def signal_handler(signum, frame): logging.critical(f"Received signal: {signal.Signals(signum).name}") - raise ParentCalledException(f"Received signal: {signal.Signals(signum).name}") + raise ParentCalledException( + f"Received signal: {signal.Signals(signum).name}") def main(): @@ -316,10 +323,10 @@ def main(): loop = asyncio.get_event_loop() loop.set_debug(True) - transport = transport_factory.TransportFactory(device_index=ini['dev_index'], - device_mode=args.mode, - asyncio_loop=loop, - transport_directory=transport_directory) + transport = transport_factory.TransportFactory( + device_index=ini['dev_index'], + device_mode=args.mode, asyncio_loop=loop, + transport_directory=transport_directory) signal.signal(signal.SIGTERM, signal_handler) @@ -335,14 +342,13 @@ def main(): elif args.mode == 'tx': loop.run_until_complete(async_main_tx(bt_dev, ini, cfg)) - except Exception as e: logging.error(traceback.format_exc()) except (KeyboardInterrupt or ParentCalledException): logging.critical("Hard exit triggered.") logging.error(traceback.format_exc()) finally: - if transport != None: + if transport is not None: transport.stop() sys.exit() diff --git a/tools/hci_throughput/hci_socket.py b/tools/hci_throughput/hci_socket.py index 41c95eeee6..da908b8f60 100644 --- a/tools/hci_throughput/hci_socket.py +++ b/tools/hci_throughput/hci_socket.py @@ -53,7 +53,10 @@ class HCI_User_Channel_Socket_Error(BaseException): class HCI_User_Channel_Socket(): def __init__(self, device_index=0, device_mode=None, asyncio_loop=None): - logging.debug("Device index: %s, Device address: %s", device_index, device_mode) + logging.debug( + "Device index: %s, Device address: %s", + device_index, + device_mode) self.loop = asyncio_loop self.libc = ctypes.cdll.LoadLibrary('libc.so.6') self.rx_buffer_q = multiprocessing.Manager().Queue() @@ -71,22 +74,28 @@ def socket_create(self): new_socket = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW | socket.SOCK_NONBLOCK, socket.BTPROTO_HCI) - if new_socket == None: + if new_socket is None: raise HCI_User_Channel_Socket_Error("Socket error. \ Opening socket failed") new_socket.setblocking(False) - socket_size = new_socket.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF) + socket_size = new_socket.getsockopt( + socket.SOL_SOCKET, socket.SO_RCVBUF) logging.info(f"Default socket recv buffer size: {socket_size}") new_socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 500000) - socket_size = new_socket.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF) + socket_size = new_socket.getsockopt( + socket.SOL_SOCKET, socket.SO_RCVBUF) logging.info(f"Set socket recv buffer size: {socket_size}") return new_socket def socket_bind(self, index): logging.debug("%s index: %s", self.socket_bind.__name__, index) # addr: struct sockaddr_hci from /usr/include/bluetooth/hci.h - addr = struct.pack('HHH', hci.AF_BLUETOOTH, index, hci.HCI_CHANNEL_USER) - retry_binding=2 + addr = struct.pack( + 'HHH', + hci.AF_BLUETOOTH, + index, + hci.HCI_CHANNEL_USER) + retry_binding = 2 for i in range(retry_binding): try: bind = self.libc.bind(self.hci_socket.fileno(), @@ -118,8 +127,8 @@ def socket_clear(self): cnt += len(buff) logging.debug(f"Read from buffer {cnt} bytes") except BlockingIOError: - logging.info("Buffer empty and ready!") - return + logging.info("Buffer empty and ready!") + return async def send(self, ba_message): await self.loop.sock_sendall(self.hci_socket, ba_message) @@ -132,10 +141,11 @@ def socket_listener(self): logging.info("listener_ev set") break buffer = self.hci_socket.recv(SOCKET_RECV_BUFFER_SIZE) - logging.info(f"Socket recv: {self.counter} th packet with len: {len(buffer)}") + logging.info( + f"Socket recv: {self.counter} th packet with len: {len(buffer)}") self.rx_buffer_q.put((buffer, time.perf_counter())) - recv_at_once +=1 - self.counter +=1 + recv_at_once += 1 + self.counter += 1 except BlockingIOError: if recv_at_once > 1: @@ -151,8 +161,8 @@ def close(self): return self.hci_socket.close() def start(self): - self.listener_proc = multiprocessing.Process(target=self.socket_listener, - daemon=True) + self.listener_proc = multiprocessing.Process( + target=self.socket_listener, daemon=True) self.listener_proc.start() logging.info(f"start listener_proc pid: {self.listener_proc.pid}") diff --git a/tools/hci_throughput/main.py b/tools/hci_throughput/main.py index 047f300838..b00780a03e 100644 --- a/tools/hci_throughput/main.py +++ b/tools/hci_throughput/main.py @@ -30,7 +30,8 @@ import os import math -PROCESS_TIMEOUT = 500 # seconds, adjust if necessary +PROCESS_TIMEOUT = 500 # seconds, adjust if necessary + def parse_arguments(): parser = argparse.ArgumentParser( @@ -97,7 +98,7 @@ def change_config_var(filename: str, group: str, variable: str, def get_init_dict(filename: str, args_list: list, modes: list, dir: str, transport_directory: str): ini = { - modes[0]:{ + modes[0]: { "dev_index": args_list[0][0], "own_address_type": args_list[0][1], "own_address": args_list[0][2], @@ -105,7 +106,7 @@ def get_init_dict(filename: str, args_list: list, modes: list, dir: str, "peer_address_type": args_list[1][1], "peer_address": args_list[1][2] }, - modes[1]:{ + modes[1]: { "dev_index": args_list[1][0], "own_address_type": args_list[1][1], "own_address": args_list[1][2], @@ -209,7 +210,7 @@ def main(): init_file = "init.yaml" cfg_file = args.config_file[0] - if (type(args.transport_directory) == list): + if (isinstance(args.transport_directory, list)): args.transport_directory = args.transport_directory.pop() else: args.transport_directory = args.transport_directory @@ -224,11 +225,11 @@ def main(): test_dir_path = util.create_test_directory() init_dict = get_init_dict(filename=init_file, args_list=addr_list, - modes=args.modes, dir=test_dir_path, - transport_directory=args.transport_directory) + modes=args.modes, dir=test_dir_path, + transport_directory=args.transport_directory) util.copy_config_files_to_test_directory([init_file, cfg_file], - init_dict["test_dir"]) + init_dict["test_dir"]) try: if cfg["flag_testing"]: diff --git a/tools/hci_throughput/throughput.py b/tools/hci_throughput/throughput.py index dcc242d20a..e2b78b72c7 100644 --- a/tools/hci_throughput/throughput.py +++ b/tools/hci_throughput/throughput.py @@ -24,6 +24,9 @@ import argparse import traceback +data_types = ['kb', 'kB'] + + def parse_arguments(): parser = argparse.ArgumentParser( description='Plot throughput from the csv file.', @@ -40,19 +43,18 @@ def parse_arguments(): print(traceback.format_exc()) return args -data_types = ['kb', 'kB'] - -def gen_data(num_of_bytes_in_packet: int, last_number_from_previous_data_packet: int): +def gen_data(num_of_bytes_in_packet: int, + last_number_from_previous_data_packet: int): counter = last_number_from_previous_data_packet + 1 rem = num_of_bytes_in_packet % 4 valid_data_len = int((num_of_bytes_in_packet - rem) / 4) total_data_len = valid_data_len + rem data = [0] * total_data_len - for i in range(rem,total_data_len): + for i in range(rem, total_data_len): data[i] = counter counter += 1 - last_value = data[len(data)-1] + last_value = data[len(data) - 1] if rem: fmt = "<" + str(rem) + "B" + str(valid_data_len) + "I" else: @@ -62,13 +64,22 @@ def gen_data(num_of_bytes_in_packet: int, last_number_from_previous_data_packet: class Throughput(): - def __init__(self, name="tp_chart", mode="rx", total_packets_number=0, bytes_number_in_packet=0, - throughput_data_type='kb', flag_plot_packets=True, sample_time=1, test_directory=None): + def __init__( + self, + name="tp_chart", + mode="rx", + total_packets_number=0, + bytes_number_in_packet=0, + throughput_data_type='kb', + flag_plot_packets=True, + sample_time=1, + test_directory=None): self.name = name self.mode = mode self.total_packets_number = total_packets_number self.bytes_number_in_packet = bytes_number_in_packet - self.predef_packet_key = int((bytes_number_in_packet - (bytes_number_in_packet % 4))/4) + self.predef_packet_key = int( + (bytes_number_in_packet - (bytes_number_in_packet % 4)) / 4) self.total_bits_number = bytes_number_in_packet * 8 assert throughput_data_type in data_types self.throughput_data_type = throughput_data_type @@ -77,38 +88,45 @@ def __init__(self, name="tp_chart", mode="rx", total_packets_number=0, bytes_num self.test_directory = test_directory if self.test_directory is not None: - self.csv_file_name = self.test_directory + "/" + time.strftime("%Y_%m_%d_%H_%M_%S_") + self.name + ".csv" + self.csv_file_name = self.test_directory + "/" + \ + time.strftime("%Y_%m_%d_%H_%M_%S_") + self.name + ".csv" else: - self.csv_file_name = time.strftime("%Y_%m_%d_%H_%M_%S_") + self.name + ".csv" + self.csv_file_name = time.strftime( + "%Y_%m_%d_%H_%M_%S_") + self.name + ".csv" self.clean_csv_file() def calc_throughput(self, current_num, last_num, current_time, last_time): if self.throughput_data_type == 'kb': - return float((((current_num - last_num) * \ - self.total_bits_number) / (current_time-last_time))/1000) + return float( + (((current_num - last_num) * self.total_bits_number) / + (current_time - last_time)) / 1000) elif self.throughput_data_type == 'kB': - return float((((current_num - last_num) * \ - self.bytes_number_in_packet) / (current_time-last_time))/1000) + return float( + (((current_num - last_num) * self.bytes_number_in_packet) / + (current_time - last_time)) / 1000) def clean_csv_file(self): - file = open(self.csv_file_name, 'w') - file.write("Time,Packet\n") + file = open(self.csv_file_name, 'w') + file.write("Time,Packet\n") - def append_to_csv_file(self, timestamp: float = 0.0, packet_number: int = 0): + def append_to_csv_file( + self, + timestamp: float = 0.0, + packet_number: int = 0): with open(self.csv_file_name, "a") as file: csv_writer = csv.writer(file) csv_writer.writerow([timestamp, packet_number]) def get_average(self, packet_numbers, timestamps): if self.throughput_data_type == 'kb': - average_tp = ((packet_numbers * self.total_bits_number) \ - / (timestamps[-1] - timestamps[0]))/1000 + average_tp = ((packet_numbers * self.total_bits_number) + / (timestamps[-1] - timestamps[0])) / 1000 elif self.throughput_data_type == 'kB': - average_tp = ((packet_numbers * self.bytes_number_in_packet) \ - / (timestamps[-1] - timestamps[0]))/1000 + average_tp = ((packet_numbers * self.bytes_number_in_packet) + / (timestamps[-1] - timestamps[0])) / 1000 return average_tp - def save_average(self, tp_csv_filename = None): + def save_average(self, tp_csv_filename=None): if self.mode == "rx": timestamps = [] packet_numbers = [] @@ -126,14 +144,15 @@ def save_average(self, tp_csv_filename = None): packet_numbers.append(float(row[1])) average_tp = self.get_average(packet_numbers[-1], timestamps) - print(f"Average rx throughput: {round(average_tp, 3)} {self.throughput_data_type}ps") + print( + f"Average rx throughput: {round(average_tp, 3)} {self.throughput_data_type}ps") with open(self.test_directory + "/average_rx_tp.csv", "a") as file: csv_writer = csv.writer(file) csv_writer.writerow([average_tp]) def plot_tp_from_file(self, filename: str = None, sample_time: float = 1, - save_to_file: bool = True): + save_to_file: bool = True): timestamps = [] packet_numbers = [] @@ -158,7 +177,7 @@ def plot_tp_from_file(self, filename: str = None, sample_time: float = 1, if timestamps[i] - last_time > sample_time: throughput.append((timestamps[i], self.calc_throughput(packet_numbers[i], - last_number, + last_number, timestamps[i], last_time))) last_time = timestamps[i] @@ -194,4 +213,4 @@ def plot_tp_from_file(self, filename: str = None, sample_time: float = 1, if __name__ == "__main__": args = parse_arguments() tp = Throughput(bytes_number_in_packet=247) - tp.plot_tp_from_file(*args.file, args.samp_t[0], save_to_file=False) \ No newline at end of file + tp.plot_tp_from_file(*args.file, args.samp_t[0], save_to_file=False) diff --git a/tools/hci_throughput/transport_factory.py b/tools/hci_throughput/transport_factory.py index 7555c32001..9b5f07aa90 100644 --- a/tools/hci_throughput/transport_factory.py +++ b/tools/hci_throughput/transport_factory.py @@ -27,9 +27,8 @@ class TransportFactory: def __init__(self, device_index: str = None, device_mode=None, asyncio_loop=None, transport_directory=None) -> None: if (device_index.isnumeric()): - self.transport = hci_socket.HCI_User_Channel_Socket(int(device_index), - device_mode, - asyncio_loop) + self.transport = hci_socket.HCI_User_Channel_Socket( + int(device_index), device_mode, asyncio_loop) else: try: if (transport_directory != "default"): diff --git a/tools/hci_throughput/util.py b/tools/hci_throughput/util.py index 6aeed607ca..472057b1df 100644 --- a/tools/hci_throughput/util.py +++ b/tools/hci_throughput/util.py @@ -22,6 +22,7 @@ import time import os + def create_test_directory(): test_dir_name = "tests/" + time.strftime("%Y_%m_%d_%H_%M_%S") path = os.path.join(os.getcwd(), test_dir_name) @@ -32,8 +33,8 @@ def create_test_directory(): def configure_logging(log_filename, clear_log_file=True): format_template = ("%(asctime)s %(threadName)s %(name)s %(levelname)s " - "%(filename)-25s %(lineno)-5s " - "%(funcName)-25s : %(message)s") + "%(filename)-25s %(lineno)-5s " + "%(funcName)-25s : %(message)s") logging.basicConfig(format=format_template, filename=log_filename, filemode='a', @@ -53,10 +54,10 @@ def copy_config_files_to_test_directory(files: list, test_directory: str): def copy_log_files_to_test_directory(dir: str): - log_files = ["log/log_rx.log", "log/log_tx.log", "log/check_addr.log"] - for file in log_files: - shutil.copy(file, dir + "/" + time.strftime("%Y_%m_%d_%H_%M_%S_") + - file.replace("log/", "")) + log_files = ["log/log_rx.log", "log/log_tx.log", "log/check_addr.log"] + for file in log_files: + shutil.copy(file, dir + "/" + time.strftime("%Y_%m_%d_%H_%M_%S_") + + file.replace("log/", "")) # Running tests as sudo implies root permissions on created directories/files. From bdf755b69584c86e4e5243598490a1176a4ac16e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 27 Jul 2022 11:26:21 +0200 Subject: [PATCH 0466/1333] host/sm: fix check in ble_sm_pair_req_rx If SC_ONLY is enabled fail pairing request if either keysize is to small OR SC is not supported by peer. Previously it was an AND, which means both conditions must be true to fail pairing, which is not correct. --- nimble/host/src/ble_sm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index de1006bce0..0339e3eb41 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -1832,8 +1832,8 @@ ble_sm_pair_req_rx(uint16_t conn_handle, struct os_mbuf **om, } else if (req->max_enc_key_size > BLE_SM_PAIR_KEY_SZ_MAX) { res->sm_err = BLE_SM_ERR_INVAL; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_INVAL); - } else if (MYNEWT_VAL(BLE_SM_SC_ONLY) && (req->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX) && - !(req->authreq & BLE_SM_PAIR_AUTHREQ_SC)) { + } else if (MYNEWT_VAL(BLE_SM_SC_ONLY) && ((req->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX) || + !(req->authreq & BLE_SM_PAIR_AUTHREQ_SC))) { /* Fail if Secure Connections Only mode is on and remote does not meet * key size requirements - MITM was checked in last step. Fail if SC is not supported * by peer. From 6e345d0c883e3258b275f70d0d3474fe1fbcd893 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Tue, 19 Jul 2022 17:09:01 +0200 Subject: [PATCH 0467/1333] apps/btshell: Add default own_addr_type check On default the application has taken "public" as own address type. Now the application checks if public addres is available on the device and if not, on default it uses "random" as own addres type. It prevents advertising, scanning and connecting errors if the user won't change own address type in console, while working with a device, which has no public address available. --- apps/btshell/src/btshell.h | 2 +- apps/btshell/src/cmd.c | 16 ++++++++-------- apps/btshell/src/main.c | 10 ++++++++++ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h index f52d65f5cd..134eb01625 100644 --- a/apps/btshell/src/btshell.h +++ b/apps/btshell/src/btshell.h @@ -184,7 +184,7 @@ int btshell_l2cap_reconfig(uint16_t conn_handle, uint16_t mtu, int btshell_gap_event(struct ble_gap_event *event, void *arg); void btshell_sync_stats(uint16_t handle); - +uint8_t btshell_get_default_own_addr_type(void); /** GATT server. */ #define GATT_SVR_SVC_ALERT_UUID 0x1811 #define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID 0x2A47 diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index ddb76c8233..8b4315865f 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -260,7 +260,7 @@ cmd_advertise_configure(int argc, char **argv) params.own_addr_type = parse_arg_kv_dflt("own_addr_type", cmd_own_addr_types, - BLE_OWN_ADDR_PUBLIC, &rc); + btshell_get_default_own_addr_type(), &rc); if (rc != 0) { console_printf("invalid 'own_addr_type' parameter\n"); return rc; @@ -473,7 +473,7 @@ static const struct shell_param advertise_configure_params[] = { {"directed", "directed advertising, usage: =[0-1], default: 0"}, {"peer_addr_type", "usage: =[public|random|public_id|random_id], default: public"}, {"peer_addr", "usage: =[XX:XX:XX:XX:XX:XX]"}, - {"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public"}, + {"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public if available, otherwise random"}, {"channel_map", "usage: =[0x00-0xff], default: 0"}, {"filter", "usage: =[none|scan|conn|both], default: none"}, {"interval_min", "usage: =[0-UINT32_MAX], default: 0"}, @@ -615,7 +615,7 @@ cmd_advertise(int argc, char **argv) } own_addr_type = parse_arg_kv_dflt("own_addr_type", cmd_own_addr_types, - BLE_OWN_ADDR_PUBLIC, &rc); + btshell_get_default_own_addr_type(), &rc); if (rc != 0) { console_printf("invalid 'own_addr_type' parameter\n"); return rc; @@ -676,7 +676,7 @@ static const struct shell_param advertise_params[] = { {"discov", "discoverable mode, usage: =[non|ltd|gen], default: gen"}, {"peer_addr_type", "usage: =[public|random|public_id|random_id], default: public"}, {"peer_addr", "usage: =[XX:XX:XX:XX:XX:XX]"}, - {"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public"}, + {"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public if available, otherwise random"}, {"channel_map", "usage: =[0x00-0xff], default: 0"}, {"filter", "usage: =[none|scan|conn|both], default: none"}, {"interval_min", "usage: =[0-UINT16_MAX], default: 0"}, @@ -752,7 +752,7 @@ cmd_connect(int argc, char **argv) } own_addr_type = parse_arg_kv_dflt("own_addr_type", cmd_own_addr_types, - BLE_OWN_ADDR_PUBLIC, &rc); + btshell_get_default_own_addr_type(), &rc); if (rc != 0) { console_printf("invalid 'own_addr_type' parameter\n"); return rc; @@ -969,7 +969,7 @@ static const struct shell_param connect_params[] = { {"extended", "usage: =[none|1M|coded|both|all], default: none"}, {"peer_addr_type", "usage: =[public|random|public_id|random_id], default: public"}, {"peer_addr", "usage: =[XX:XX:XX:XX:XX:XX]"}, - {"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public"}, + {"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public if available, otherwise random"}, {"duration", "usage: =[1-INT32_MAX], default: 0"}, {"scan_interval", "usage: =[0-UINT16_MAX], default: 0x0010"}, {"scan_window", "usage: =[0-UINT16_MAX], default: 0x0010"}, @@ -1268,7 +1268,7 @@ cmd_scan(int argc, char **argv) } own_addr_type = parse_arg_kv_dflt("own_addr_type", cmd_own_addr_types, - BLE_OWN_ADDR_PUBLIC, &rc); + btshell_get_default_own_addr_type(), &rc); if (rc != 0) { console_printf("invalid 'own_addr_type' parameter\n"); return rc; @@ -1361,7 +1361,7 @@ static const struct shell_param scan_params[] = { {"window", "usage: =[0-UINT16_MAX], default: 0"}, {"filter", "usage: =[no_wl|use_wl|no_wl_inita|use_wl_inita], default: no_wl"}, {"nodups", "usage: =[0-1], default: 0"}, - {"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public"}, + {"own_addr_type", "usage: =[public|random|rpa_pub|rpa_rnd], default: public if available, otherwise random"}, {"extended_duration", "usage: =[0-UINT16_MAX], default: 0"}, {"extended_period", "usage: =[0-UINT16_MAX], default: 0"}, {"longrange_interval", "usage: =[0-UINT16_MAX], default: 0"}, diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index cc69e5d157..7bea9067f3 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -76,6 +76,8 @@ bssnz_t struct btshell_conn btshell_conns[MYNEWT_VAL(BLE_MAX_CONNECTIONS)]; int btshell_num_conns; +static uint8_t default_own_addr_type; + static os_membuf_t btshell_svc_mem[ OS_MEMPOOL_SIZE(BTSHELL_MAX_SVCS, sizeof(struct btshell_svc)) ]; @@ -2131,6 +2133,8 @@ btshell_on_sync(void) console_printf("Failed to set identity address\n"); } + ble_hs_id_infer_auto(0, &default_own_addr_type); + #if MYNEWT_VAL(BLE_SM_SC) int rc; @@ -2569,6 +2573,12 @@ btshell_init_ext_adv_restart(void) #endif } +uint8_t +btshell_get_default_own_addr_type(void) +{ + return default_own_addr_type; +} + /** * main * From f9eb3c8d27b07d441dc7a77de513ef940ad7da1f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 13 Jul 2022 10:39:35 +0200 Subject: [PATCH 0468/1333] nimble/ll: Fix continuation events handling We should only start counting continuation events if a valid non-empty PDU was rxd/txd in a connection event. Also we should ignore any valid PDUs prior to subrated event. This fixes LL/CON/PER/BV-143-C and LL/CON/CEN/BV-145-C. --- .../include/controller/ble_ll_conn.h | 3 +- nimble/controller/src/ble_ll_conn.c | 41 ++++++++++++++----- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 13e9af00ba..413ae9ecb7 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -310,7 +310,8 @@ struct ble_ll_conn_sm uint16_t subrate_base_event; uint16_t subrate_factor; uint16_t cont_num; - uint16_t last_pdu_event; + uint16_t cont_num_left; + uint8_t has_nonempty_pdu; union { struct ble_ll_conn_subrate_params subrate_trans; diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index e2eb33e3e3..4d1bf85e54 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1436,9 +1436,15 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) } STATS_INC(ble_ll_conn_stats, tx_empty_pdus); } else if ((hdr_byte & BLE_LL_DATA_HDR_LLID_MASK) == BLE_LL_LLID_CTRL) { +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + connsm->has_nonempty_pdu = 1; +#endif STATS_INC(ble_ll_conn_stats, tx_ctrl_pdus); STATS_INCN(ble_ll_conn_stats, tx_ctrl_bytes, cur_txlen); } else { +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + connsm->has_nonempty_pdu = 1; +#endif STATS_INC(ble_ll_conn_stats, tx_l2cap_pdus); STATS_INCN(ble_ll_conn_stats, tx_l2cap_bytes, cur_txlen); } @@ -1918,7 +1924,8 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) connsm->subrate_base_event = 0; connsm->subrate_factor = 1; connsm->cont_num = 0; - connsm->last_pdu_event = 0; + connsm->cont_num_left = 0; + connsm->has_nonempty_pdu = 0; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) @@ -2271,10 +2278,25 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) base_event_cntr = connsm->subrate_base_event; subrate_factor = connsm->subrate_factor; - if ((connsm->cont_num > 0) && - (connsm->event_cntr + 1 == connsm->subrate_base_event + - connsm->subrate_factor) && - (connsm->event_cntr - connsm->last_pdu_event < connsm->cont_num)) { + /* We need to restore remaining continuation events counter if a non-empty + * PDU was txd/rxd in this connection event. Also we need to set counter to + * 0 in case there was no valid PDU at subrated event, since we should not + * use continuation events in such case (i.e. ignore any valid PDUs prior + * to subrated event). + * + * Note that has_nonempty_pdu flag is also cleared here since LL may move to + * next connection event due to scheduling conflict and there will be no + * start callback for new event. + */ + if (connsm->has_nonempty_pdu) { + connsm->cont_num_left = connsm->cont_num; + connsm->has_nonempty_pdu = 0; + } else if (connsm->event_cntr == connsm->subrate_base_event) { + connsm->cont_num_left = 0; + } + + if (connsm->cont_num_left > 0) { + connsm->cont_num_left--; next_is_subrated = 0; } #else @@ -3344,11 +3366,6 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) acl_len = rxbuf[1]; llid = hdr_byte & BLE_LL_DATA_HDR_LLID_MASK; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) - connsm->last_pdu_event = connsm->event_cntr; -#endif - - #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) if (BLE_MBUF_HDR_MIC_FAILURE(hdr)) { STATS_INC(ble_ll_conn_stats, mic_failures); @@ -3428,6 +3445,10 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) goto conn_rx_data_pdu_end; } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + connsm->has_nonempty_pdu = 1; +#endif + if (llid == BLE_LL_LLID_CTRL) { /* Process control frame */ STATS_INC(ble_ll_conn_stats, rx_ctrl_pdus); From 82dd24d8257b2d66fb2f5b447e19c6493fb781a7 Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 3 Aug 2022 17:38:47 +0200 Subject: [PATCH 0469/1333] tools/hci_throughput: testing over encrypted link Added option enable_encryption to run throughput tests over encrypted link. --- tools/hci_throughput/config.yaml.sample | 1 + tools/hci_throughput/hci.py | 37 +++++++++++ tools/hci_throughput/hci_commands.py | 84 +++++++++++++++++++++++++ tools/hci_throughput/hci_device.py | 7 ++- tools/hci_throughput/main.py | 8 ++- 5 files changed, 135 insertions(+), 2 deletions(-) diff --git a/tools/hci_throughput/config.yaml.sample b/tools/hci_throughput/config.yaml.sample index 7a8330075c..68068e3e7e 100644 --- a/tools/hci_throughput/config.yaml.sample +++ b/tools/hci_throughput/config.yaml.sample @@ -43,6 +43,7 @@ adv: peer_address: 00:00:00:00:00:00 advertising_channel_map: 7 advertising_filter_policy: 0 +enable_encryption: true conn: le_scan_interval: 2400 le_scan_window: 2400 diff --git a/tools/hci_throughput/hci.py b/tools/hci_throughput/hci.py index d0a0b8a1e5..e5eb1179c9 100644 --- a/tools/hci_throughput/hci.py +++ b/tools/hci_throughput/hci.py @@ -35,6 +35,7 @@ L2CAP_HDR_BYTES = 4 HCI_EV_CODE_DISCONN_CMP = 0x05 +HCI_EV_CODE_ENCRYPTION_CHANGE = 0x08 HCI_EV_CODE_CMD_CMP = 0x0e HCI_EV_CODE_CMD_STATUS = 0x0f HCI_EV_CODE_LE_META_EVENT = 0x3e @@ -42,6 +43,7 @@ HCI_SUBEV_CODE_LE_DATA_LEN_CHANGE = 0x07 HCI_SUBEV_CODE_LE_PHY_UPDATE_CMP = 0x0c HCI_SUBEV_CODE_LE_CHAN_SEL_ALG = 0x14 +HCI_SUBEV_CODE_LE_LONG_TERM_KEY_REQUEST = 0x05 HCI_EV_NUM_COMP_PKTS = 0x13 CONN_FAILED_TO_BE_ESTABLISHED = 0x3e @@ -66,6 +68,8 @@ OCF_LE_SET_SCAN_PARAMETERS = 0x000b OCF_LE_SET_SCAN_ENABLE = 0x000c OCF_LE_CREATE_CONN = 0x000d +OCF_LE_ENABLE_ENCRYPTION = 0x0019 +OCF_LE_LONG_TERM_KEY_REQUEST_REPLY = 0x001A OCF_LE_SET_DATA_LEN = 0x0022 OCF_LE_READ_SUGGESTED_DFLT_DATA_LEN = 0x0023 OCF_LE_READ_MAX_DATA_LEN = 0x002f @@ -106,6 +110,7 @@ num_of_completed_packets_time = 0 read_local_commands = None le_read_local_supported_features = None +ltk = None ############ # FUNCTIONS @@ -303,6 +308,21 @@ def set(self, status=0, num_hci_cmd_packets=0, opcode=0): self.opcode = opcode +@dataclass +class HCI_Ev_LE_Encryption_Change(): + status: int + connection_handle: int + encryption_enabled: int + + def __init__(self): + self.set() + + def set(self, status=0, connection_handle=0, encryption_enabled=0): + self.status = status + self.connection_handle = connection_handle + self.encryption_enabled = encryption_enabled + + @dataclass class HCI_Ev_LE_Meta: subevent_code: int @@ -374,6 +394,23 @@ def set(self, subevent_code=0, conn_handle=0, max_tx_octets=0, self.triggered = triggered +@dataclass +class HCI_Ev_LE_Long_Term_Key_Request(HCI_Ev_LE_Meta): + conn_handle: int + random_number: int + encrypted_diversifier: int + + def __init__(self): + self.set() + + def set(self, subevent_code=0, conn_handle=0, random_number=0, + encrypted_diversifier=0): + super().set(subevent_code) + self.conn_handle = conn_handle + self.random_number = random_number + self.encrypted_diversifier = encrypted_diversifier + + @dataclass class HCI_Ev_LE_PHY_Update_Complete(HCI_Ev_LE_Meta): status: int diff --git a/tools/hci_throughput/hci_commands.py b/tools/hci_throughput/hci_commands.py index 83e6284f5f..31bed375e1 100644 --- a/tools/hci_throughput/hci_commands.py +++ b/tools/hci_throughput/hci_commands.py @@ -47,6 +47,7 @@ def __init__(self, send=None, rx_buffer_q=None, self.async_sem_cmd = asyncio.Semaphore() self.async_ev_cmd_end = asyncio.Event() self.async_ev_connected = asyncio.Event() + self.async_ev_encryption_change = asyncio.Event() self.async_ev_set_data_len = asyncio.Event() self.async_ev_update_phy = asyncio.Event() self.async_ev_num_cmp_pckts = asyncio.Event() @@ -219,6 +220,41 @@ async def cmd_le_create_connection(self, con_params: hci.HCI_Connect): await self.async_ev_cmd_end.wait() self.async_ev_cmd_end.clear() + async def cmd_le_enable_encryption(self, conn_handle: int, random_number: int, ediv: int, ltk: int): + async with self.async_sem_cmd: + hci.ltk = ltk + random_number_bytes = random_number.to_bytes(8, byteorder='little') + ltk_bytes = ltk.to_bytes(16, byteorder='little') + data_bytes = struct.pack(" dict: with open(args.init_file, "r") as file: init_file = yaml.safe_load(file) ini = init_file[args.mode] - global test_dir, transport_directory + global test_dir, transport_directory, ltk test_dir = init_file["test_dir"] transport_directory = init_file["transport_directory"] + hci.ltk = int(init_file["ltk"], 16) with open(args.config_file) as f: cfg = yaml.safe_load(f) diff --git a/tools/hci_throughput/main.py b/tools/hci_throughput/main.py index b00780a03e..565cce426c 100644 --- a/tools/hci_throughput/main.py +++ b/tools/hci_throughput/main.py @@ -29,6 +29,7 @@ import util import os import math +import random PROCESS_TIMEOUT = 500 # seconds, adjust if necessary @@ -94,6 +95,10 @@ def change_config_var(filename: str, group: str, variable: str, yaml.safe_dump(cfg, file, indent=1, sort_keys=False, default_style=None, default_flow_style=False) +def generate_long_term_key(): + rand_val = random.getrandbits(128) + return rand_val.to_bytes(16, byteorder='little') + def get_init_dict(filename: str, args_list: list, modes: list, dir: str, transport_directory: str): @@ -115,7 +120,8 @@ def get_init_dict(filename: str, args_list: list, modes: list, dir: str, "peer_address": args_list[0][2] }, "test_dir": dir, - "transport_directory": transport_directory + "transport_directory": transport_directory, + "ltk": hex(random.getrandbits(128)) } with open(filename, 'w') as file: From c6444face72d5fc2fa58d0a68793b73bc18e05a3 Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 3 Aug 2022 17:40:02 +0200 Subject: [PATCH 0470/1333] tools/hci_throughput: util path fix --- tools/hci_throughput/util.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/hci_throughput/util.py b/tools/hci_throughput/util.py index 472057b1df..96bfd9086e 100644 --- a/tools/hci_throughput/util.py +++ b/tools/hci_throughput/util.py @@ -21,6 +21,7 @@ import shutil import time import os +from pathlib import Path def create_test_directory(): @@ -50,7 +51,7 @@ def configure_logging(log_filename, clear_log_file=True): def copy_config_files_to_test_directory(files: list, test_directory: str): for file in files: - shutil.copy(file, test_directory + "/" + file) + shutil.copy(file, test_directory + "/" + Path(file).name) def copy_log_files_to_test_directory(dir: str): From a77acc42509f5bc9c57cbbaf8057b0c6c6b749a6 Mon Sep 17 00:00:00 2001 From: larry Date: Fri, 15 Jul 2022 14:23:03 +0800 Subject: [PATCH 0471/1333] porting/npl/nuttx: fix callout_handler implement callout_thread is working for all timeout callout, it need an endless loop to catch all message. --- porting/npl/nuttx/src/os_callout.c | 32 ++++++++++++++++-------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/porting/npl/nuttx/src/os_callout.c b/porting/npl/nuttx/src/os_callout.c index e4580da97a..eb69bb8b66 100644 --- a/porting/npl/nuttx/src/os_callout.c +++ b/porting/npl/nuttx/src/os_callout.c @@ -44,21 +44,23 @@ callout_handler(pthread_addr_t arg) { struct ble_npl_callout *c; - pthread_mutex_lock(&callout_mutex); - while (!pending_callout) { - pthread_cond_wait(&callout_cond, &callout_mutex); - } - - c = pending_callout; - pending_callout = NULL; - pthread_mutex_unlock(&callout_mutex); - - /* Invoke callback */ - - if (c->c_evq) { - ble_npl_eventq_put(c->c_evq, &c->c_ev); - } else { - c->c_ev.ev_cb(&c->c_ev); + while (true) { + pthread_mutex_lock(&callout_mutex); + while (!pending_callout) { + pthread_cond_wait(&callout_cond, &callout_mutex); + } + + c = pending_callout; + pending_callout = NULL; + pthread_mutex_unlock(&callout_mutex); + + /* Invoke callback */ + + if (c->c_evq) { + ble_npl_eventq_put(c->c_evq, &c->c_ev); + } else { + c->c_ev.ev_cb(&c->c_ev); + } } return NULL; From 65716bde509975501782cbe2c74556cd4e5d7eca Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 4 Aug 2022 11:28:14 +0200 Subject: [PATCH 0472/1333] nimble/ll: Fix spurious MIC failure We should only check MIC failures on new PDUs. If we acked encrypted packet, but peer did not receive that ack, the encryption counter will be different on both sides for next packet. This is ok since we should drop retransmission anyway. However, MIC failure is always set by phy and failure is checked in LL before checking for retransmissions, so it does not quite work as expected. --- nimble/controller/src/ble_ll_conn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 4d1bf85e54..ec758bffe6 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3365,9 +3365,10 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) hdr_byte = rxbuf[0]; acl_len = rxbuf[1]; llid = hdr_byte & BLE_LL_DATA_HDR_LLID_MASK; + rxd_sn = hdr_byte & BLE_LL_DATA_HDR_SN_MASK; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (BLE_MBUF_HDR_MIC_FAILURE(hdr)) { + if (BLE_MBUF_HDR_MIC_FAILURE(hdr) && (rxd_sn != connsm->last_rxd_sn)) { STATS_INC(ble_ll_conn_stats, mic_failures); ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC); goto conn_rx_data_pdu_end; @@ -3431,7 +3432,6 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) * Discard the received PDU if the sequence number is the same * as the last received sequence number */ - rxd_sn = hdr_byte & BLE_LL_DATA_HDR_SN_MASK; if (rxd_sn == connsm->last_rxd_sn) { STATS_INC(ble_ll_conn_stats, data_pdu_rx_dup); goto conn_rx_data_pdu_end; From 3bb185daad2296c02d4efd13760b4b884d70d7e4 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 4 Aug 2022 11:47:32 +0200 Subject: [PATCH 0473/1333] nimble/phy/nrf: Wait for CCM to finish decryption In extremely rare cases seems like ENDCRYPT flag is not set before we check for MISTATUS, so just spin a bit in that case and wait for CCM to finish. --- nimble/drivers/nrf52/src/ble_phy.c | 14 ++++---------- nimble/drivers/nrf5340/src/ble_phy.c | 14 ++++---------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/nimble/drivers/nrf52/src/ble_phy.c b/nimble/drivers/nrf52/src/ble_phy.c index 9b44123885..c06536a9ae 100644 --- a/nimble/drivers/nrf52/src/ble_phy.c +++ b/nimble/drivers/nrf52/src/ble_phy.c @@ -1100,6 +1100,10 @@ ble_phy_rx_end_isr(void) ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) if (g_ble_phy_data.phy_encrypted) { + while (NRF_CCM->EVENTS_ENDCRYPT == 0) { + /* Make sure CCM finished */ + }; + /* Only set MIC failure flag if frame is not zero length */ if ((dptr[1] != 0) && (NRF_CCM->MICSTATUS == 0)) { ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE; @@ -1115,16 +1119,6 @@ ble_phy_rx_end_isr(void) STATS_INC(ble_phy_stats, rx_hw_err); ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK; } - - /* - * XXX: This is a total hack work-around for now but I dont - * know what else to do. If ENDCRYPT is not set and we are - * encrypted we need to not trust this frame and drop it. - */ - if (NRF_CCM->EVENTS_ENDCRYPT == 0) { - STATS_INC(ble_phy_stats, rx_hw_err); - ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK; - } } #endif } diff --git a/nimble/drivers/nrf5340/src/ble_phy.c b/nimble/drivers/nrf5340/src/ble_phy.c index 060e32eef5..51b80a561f 100644 --- a/nimble/drivers/nrf5340/src/ble_phy.c +++ b/nimble/drivers/nrf5340/src/ble_phy.c @@ -958,6 +958,10 @@ ble_phy_rx_end_isr(void) ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) if (g_ble_phy_data.phy_encrypted) { + while (NRF_CCM_NS->EVENTS_ENDCRYPT == 0) { + /* Make sure CCM finished */ + }; + /* Only set MIC failure flag if frame is not zero length */ if ((dptr[1] != 0) && (NRF_CCM_NS->MICSTATUS == 0)) { ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE; @@ -973,16 +977,6 @@ ble_phy_rx_end_isr(void) STATS_INC(ble_phy_stats, rx_hw_err); ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK; } - - /* - * XXX: This is a total hack work-around for now but I dont - * know what else to do. If ENDCRYPT is not set and we are - * encrypted we need to not trust this frame and drop it. - */ - if (NRF_CCM_NS->EVENTS_ENDCRYPT == 0) { - STATS_INC(ble_phy_stats, rx_hw_err); - ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK; - } } #endif } From 0f8cfaa4c2c68f10e7369ac7e733627e74e3fc3c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 2 Aug 2022 16:03:02 +0200 Subject: [PATCH 0474/1333] nimble/ll/css: Fix window offset for 1st connection event Depending on timing, connection anchor point calculated for current period and requested slot might have already passed at the time advertising PDU is received and this causes window offset to be calculated incorrectly. In such case we just move connection to next period and recalculate anchor point again. --- nimble/controller/src/ble_ll_sched.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 036a3518d8..5456e8e292 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -516,9 +516,17 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, max_delay = 0; } - ble_ll_sched_css_set_conn_anchor(connsm); + /* It's possible that calculated anchor point in current period has + * already passed, so just move to next period and recalculate. + */ + connsm->css_period_idx--; + do { + connsm->css_period_idx++; + ble_ll_sched_css_set_conn_anchor(connsm); + sch->start_time = + connsm->anchor_point - g_ble_ll_sched_offset_ticks; + } while (LL_TMR_LT(sch->start_time, orig_start_time)); - sch->start_time = connsm->anchor_point - g_ble_ll_sched_offset_ticks; sch->end_time = connsm->anchor_point; sch->remainder = connsm->anchor_point_usecs; From 346a32053ed1f787c7beb8f605ace450996694bd Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 2 Aug 2022 16:07:12 +0200 Subject: [PATCH 0475/1333] nimble/ll: Fix assert on connection event end This was missing in 16f1e4d7, i.e. since we now close connection event in that case, we should also allow to move to next conn event gracefully. --- nimble/controller/src/ble_ll_conn.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index ec758bffe6..564c6cf8c1 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2817,20 +2817,6 @@ ble_ll_conn_event_end(struct ble_npl_event *ev) /* Better be a connection state machine! */ connsm = (struct ble_ll_conn_sm *)ble_npl_event_get_arg(ev); BLE_LL_ASSERT(connsm); - if (connsm->conn_state == BLE_LL_CONN_STATE_IDLE) { - /* That should not happen. If it does it means connection - * is already closed. - * Make sure LL state machine is in idle - */ - STATS_INC(ble_ll_conn_stats, sched_end_in_idle); - BLE_LL_ASSERT(0); - - /* Just in case */ - ble_ll_state_set(BLE_LL_STATE_STANDBY); - - ble_ll_scan_chk_resume(); - return; - } /* Log event end */ ble_ll_trace_u32x2(BLE_LL_TRACE_ID_CONN_EV_END, connsm->conn_handle, From 8447ec2969de52dfd2dcde6b85277265f7b5dc8d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 19 Jul 2022 14:07:40 +0200 Subject: [PATCH 0476/1333] nimble/ll: Fix privacy handling when connecting to a new device Using LL Privacy to initiate a connection to a new device (i.e. use 0x02 or 0x03 as own address type, peer is using an RPA) requires host to add peer RPA and our IRK to resolving list. In this case we should allow to match that RPA as an identity address on resolving list so we can use proper privacy settings. Note that this is a bit of an unspecified behavior, i.e. HCI LE Add Device To Resolving List command parameters indicates that only identity addresses shall be added to resolving list, but this does not seem to be specified anywhere and there is no handling for non-identity address specified. So basically we allow RPA-as-an-identity to be added to resolving list, then if AdvA RPA does not match resolving list we just fall through to see if corresponding entry in resolving list exists and use it as identity address. --- nimble/controller/src/ble_ll_scan.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 6359cf7c81..4893b2b0ca 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1275,17 +1275,17 @@ ble_ll_scan_rx_filter(uint8_t own_addr_type, uint8_t scan_filt_policy, switch (ble_ll_addr_subtype(addrd->adva, addrd->adva_type)) { case BLE_LL_ADDR_SUBTYPE_RPA: - if (addrd->rpa_index < 0) { + if (addrd->rpa_index >= 0) { + addrd->adva_resolved = 1; + + /* Use resolved identity address as advertiser address */ + rl = &g_ble_ll_resolv_list[addrd->rpa_index]; + addrd->adv_addr = rl->rl_identity_addr; + addrd->adv_addr_type = rl->rl_addr_type; break; } - addrd->adva_resolved = 1; - - /* Use resolved identity address as advertiser address */ - rl = &g_ble_ll_resolv_list[addrd->rpa_index]; - addrd->adv_addr = rl->rl_identity_addr; - addrd->adv_addr_type = rl->rl_addr_type; - break; + /* fall-through */ case BLE_LL_ADDR_SUBTYPE_IDENTITY: /* If AdvA is an identity address, we need to check if that device was * added to RL in order to use proper privacy mode. From 9b3feb5ee12e4d50b86c522b2e8b0780ca6bc291 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 5 Aug 2022 14:04:26 +0200 Subject: [PATCH 0477/1333] nimble/ll: Use OTA max rx time for connection event calculations Using effective max rx time for connection event calculations is not optimal since it's possible that time to rx packet with max octets payload is shorter that effective max rx time. Instead, we should calculate time it takes to rx packaet with effectiva max octets payload and use it if less than effective max rx time. --- .../include/controller/ble_ll_conn.h | 1 + nimble/controller/src/ble_ll_conn.c | 28 +++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 413ae9ecb7..3872406f16 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -227,6 +227,7 @@ struct ble_ll_conn_sm uint16_t rem_max_rx_time; uint16_t eff_max_tx_time; uint16_t eff_max_rx_time; + uint16_t ota_max_rx_time; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) uint16_t host_req_max_tx_time; #endif diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 564c6cf8c1..2a8c0c05bb 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1259,13 +1259,13 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) tx_phy_mode = BLE_PHY_MODE_1M; #endif - ticks = (BLE_LL_IFS * 3) + connsm->eff_max_rx_time + + ticks = (BLE_LL_IFS * 3) + connsm->ota_max_rx_time + ble_ll_pdu_tx_time_get(next_txlen, tx_phy_mode) + ble_ll_pdu_tx_time_get(cur_txlen, tx_phy_mode); #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { - ticks += (BLE_LL_IFS + connsm->eff_max_rx_time); + ticks += (BLE_LL_IFS + connsm->ota_max_rx_time); } #endif @@ -1674,7 +1674,7 @@ ble_ll_conn_can_send_next_pdu(struct ble_ll_conn_sm *connsm, uint32_t begtime, /* We will send empty pdu (just a LL header) */ usecs = ble_ll_pdu_tx_time_get(0, tx_phy_mode); } - usecs += (BLE_LL_IFS * 2) + connsm->eff_max_rx_time; + usecs += (BLE_LL_IFS * 2) + connsm->ota_max_rx_time; ticks = (uint32_t)(next_sched_time - begtime); allowed_usecs = ble_ll_tmr_t2u(ticks); @@ -1981,6 +1981,7 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) connsm->rem_max_rx_time = BLE_LL_CONN_SUPP_TIME_MIN; connsm->eff_max_tx_time = BLE_LL_CONN_SUPP_TIME_MIN; connsm->eff_max_rx_time = BLE_LL_CONN_SUPP_TIME_MIN; + connsm->ota_max_rx_time = BLE_LL_CONN_SUPP_TIME_MIN; connsm->rem_max_tx_octets = BLE_LL_CONN_SUPP_BYTES_MIN; connsm->rem_max_rx_octets = BLE_LL_CONN_SUPP_BYTES_MIN; connsm->eff_max_tx_octets = BLE_LL_CONN_SUPP_BYTES_MIN; @@ -2013,9 +2014,12 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) void ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm) { + int ota_max_rx_time_calc = 0; int send_event; uint16_t eff_time; uint16_t eff_bytes; + uint16_t ota_time; + uint8_t phy_mode; /* Assume no event sent */ send_event = 0; @@ -2029,6 +2033,7 @@ ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm) #endif if (eff_time != connsm->eff_max_rx_time) { connsm->eff_max_rx_time = eff_time; + ota_max_rx_time_calc = 1; send_event = 1; } eff_time = min(connsm->rem_max_rx_time, connsm->max_tx_time); @@ -2044,6 +2049,7 @@ ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm) eff_bytes = min(connsm->rem_max_tx_octets, connsm->max_rx_octets); if (eff_bytes != connsm->eff_max_rx_octets) { connsm->eff_max_rx_octets = eff_bytes; + ota_max_rx_time_calc = 1; send_event = 1; } eff_bytes = min(connsm->rem_max_rx_octets, connsm->max_tx_octets); @@ -2052,6 +2058,22 @@ ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm) send_event = 1; } + /* If effective rx octets and/or time value changes, we need to calculate + * actual OTA max rx time, i.e. lesser of effective max rx time and rx time + * of PDU containing max rx octets of payload. This is then used to calculate + * connection events timings. + */ + if (ota_max_rx_time_calc) { +#if BLE_LL_BT5_PHY_SUPPORTED + phy_mode = ble_ll_phy_to_phy_mode(connsm->phy_data.cur_rx_phy, + BLE_HCI_LE_PHY_CODED_S8_PREF); +#else + phy_mode = BLE_PHY_MODE_1M; +#endif + ota_time = ble_ll_pdu_tx_time_get(connsm->eff_max_rx_octets, phy_mode); + connsm->ota_max_rx_time = min(ota_time, connsm->eff_max_rx_time); + } + if (send_event) { ble_ll_hci_ev_datalen_chg(connsm); } From c4a2b2e69526f2e12ae601e0eb468f19689c013f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 11 Aug 2022 10:47:42 +0200 Subject: [PATCH 0478/1333] nimble/phy/nrf: Add PA/LNA turn-on time configuration This allows to define PA/LNA turn-on time which allows it to fully turn on before actual rx/tx. Currently only supported by nRF53 PHY. --- nimble/controller/syscfg.yml | 8 ++++ nimble/drivers/nrf5340/src/ble_phy.c | 65 +++++++++++++++++++--------- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 45fb461fe0..827c345126 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -414,6 +414,10 @@ syscfg.defs: GPIO pin number to control PA. Pin is set to high state when PA should be enabled. value: -1 + BLE_LL_PA_TURN_ON_US: + description: > + Time required for PA to turn on, in microseconds. + value: 1 BLE_LL_LNA: description: Enable LNA support value: 0 @@ -422,6 +426,10 @@ syscfg.defs: GPIO pin number to control LNA. Pin is set to high state when LNA should be enabled. value: -1 + BLE_LL_LNA_TURN_ON_US: + description: > + Time required for LNA to turn on, in microseconds. + value: 1 BLE_LL_SYSINIT_STAGE: description: > diff --git a/nimble/drivers/nrf5340/src/ble_phy.c b/nimble/drivers/nrf5340/src/ble_phy.c index 51b80a561f..49f04a850c 100644 --- a/nimble/drivers/nrf5340/src/ble_phy.c +++ b/nimble/drivers/nrf5340/src/ble_phy.c @@ -42,7 +42,7 @@ /* Channels 0..5 are always used. * Channels 6 and 7 are used for PA/LNA (optionally). - * Channels 6..8 are used for GPIO debugging (optionally). + * Channels 7..9 are used for GPIO debugging (optionally). */ #define DPPI_CH_TIMER0_EVENTS_COMPARE_0 0 @@ -51,14 +51,15 @@ #define DPPI_CH_RADIO_EVENTS_BCMATCH 3 #define DPPI_CH_RADIO_EVENTS_ADDRESS 4 #define DPPI_CH_RTC0_EVENTS_COMPARE_0 5 -#define DPPI_CH_RADIO_EVENTS_READY 6 +#define DPPI_CH_TIMER0_EVENTS_COMPARE_4 6 #define DPPI_CH_RADIO_EVENTS_DISABLED 7 -#define DPPI_CH_RADIO_EVENTS_RXREADY 8 +#define DPPI_CH_RADIO_EVENTS_READY 8 +#define DPPI_CH_RADIO_EVENTS_RXREADY 9 #define DPPI_CH_ENABLE_ALL (DPPIC_CHEN_CH0_Msk | DPPIC_CHEN_CH1_Msk | DPPIC_CHEN_CH2_Msk | \ DPPIC_CHEN_CH3_Msk | DPPIC_CHEN_CH4_Msk | DPPIC_CHEN_CH5_Msk) -#define DPPI_CH_MASK_PLNA (DPPI_CH_MASK(RADIO_EVENTS_READY) | \ +#define DPPI_CH_MASK_PLNA (DPPI_CH_MASK(TIMER0_EVENTS_COMPARE_4) | \ DPPI_CH_MASK(RADIO_EVENTS_DISABLED)) extern uint8_t g_nrf_num_irks; @@ -333,10 +334,14 @@ ble_phy_plna_enable_pa(void) #if MYNEWT_VAL(BLE_LL_PA) ble_ll_plna_pa_enable(); + /* CC[0] is set to radio enable */ + NRF_TIMER0_NS->CC[4] = NRF_TIMER0_NS->CC[0] + BLE_PHY_T_RXENFAST - + MYNEWT_VAL(BLE_LL_PA_TURN_ON_US); + #if PLNA_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); #else - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); #endif #endif } @@ -348,9 +353,9 @@ ble_phy_plna_disable_pa(void) ble_ll_plna_pa_disable(); #if PLNA_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); #else - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); #endif #endif } @@ -361,10 +366,14 @@ ble_phy_plna_enable_lna(void) #if MYNEWT_VAL(BLE_LL_LNA) ble_ll_plna_lna_enable(); + /* CC[0] is set to radio enable */ + NRF_TIMER0_NS->CC[4] = NRF_TIMER0_NS->CC[0] + BLE_PHY_T_RXENFAST - + MYNEWT_VAL(BLE_LL_LNA_TURN_ON_US); + #if PLNA_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); #else - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); #endif #endif } @@ -376,9 +385,9 @@ ble_phy_plna_disable_lna(void) ble_ll_plna_lna_disable(); #if PLNA_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); #else - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); #endif #endif } @@ -548,6 +557,22 @@ ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx) rem_usecs -= 30; } + /* If PA/LNA is used, make sure CC[0] is set to more than turn-on time since + * it's used as a base for turn-on time calculation and thus cannot wrap + * around on subtraction. + */ + if (MYNEWT_VAL(BLE_LL_PA) && tx && + (rem_usecs + BLE_PHY_T_RXENFAST <= MYNEWT_VAL(BLE_LL_PA_TURN_ON_US))) { + cputime--; + rem_usecs += 30; + } + + if (MYNEWT_VAL(BLE_LL_LNA) && !tx && + (rem_usecs + BLE_PHY_T_RXENFAST <= MYNEWT_VAL(BLE_LL_LNA_TURN_ON_US))) { + cputime--; + rem_usecs += 30; + } + /* * Can we set the RTC compare to start TIMER0? We can do it if: * a) Current compare value is not N+1 or N+2 ticks from current @@ -1428,28 +1453,28 @@ ble_phy_init(void) * TODO: figure out if this affects power consumption */ - /* Publish RADIO->EVENTS_READY */ - NRF_RADIO_NS->PUBLISH_READY = DPPI_CH_PUB(RADIO_EVENTS_READY); - NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_READY); + /* Publish TIMER0->EVENTS_COMPARE4 */ + NRF_TIMER0_NS->PUBLISH_COMPARE[4] = DPPI_CH_PUB(TIMER0_EVENTS_COMPARE_4); + NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(TIMER0_EVENTS_COMPARE_4); /* Publish RADIO->EVENTS_DISABLED */ NRF_RADIO_NS->PUBLISH_DISABLED = DPPI_CH_PUB(RADIO_EVENTS_DISABLED); NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_DISABLED); #if PLNA_SINGLE_GPIO plna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO)); - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); NRF_GPIOTE_NS->SUBSCRIBE_CLR[plna_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); NRF_GPIOTE_NS->TASKS_CLR[plna_idx] = 1; #else #if MYNEWT_VAL(BLE_LL_PA) plna_pa_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO)); - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); NRF_GPIOTE_NS->SUBSCRIBE_CLR[plna_pa_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); NRF_GPIOTE_NS->TASKS_CLR[plna_pa_idx] = 1; #endif #if MYNEWT_VAL(BLE_LL_LNA) plna_lna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_LNA_GPIO)); - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); NRF_GPIOTE_NS->SUBSCRIBE_CLR[plna_lna_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); NRF_GPIOTE_NS->TASKS_CLR[plna_lna_idx] = 1; #endif @@ -1903,10 +1928,10 @@ ble_phy_disable_irq_and_ppi(void) NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); #else #if MYNEWT_VAL(BLE_LL_PA) - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); #endif #if MYNEWT_VAL(BLE_LL_LNA) - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); + NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); #endif #endif From 479eaa83edbfb8d86822c0ec9aeab58d6e622e84 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 11 Aug 2022 13:15:21 +0200 Subject: [PATCH 0479/1333] nimble/phy/nrf: Force PA/LNA disable on phy disable This is to make sure PA/LNA control pins are always disabled on phy disable. --- nimble/drivers/nrf5340/src/ble_phy.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/nimble/drivers/nrf5340/src/ble_phy.c b/nimble/drivers/nrf5340/src/ble_phy.c index 49f04a850c..ac90c4f1ae 100644 --- a/nimble/drivers/nrf5340/src/ble_phy.c +++ b/nimble/drivers/nrf5340/src/ble_phy.c @@ -392,6 +392,21 @@ ble_phy_plna_disable_lna(void) #endif } +static void +ble_phy_plna_force_disable(void) +{ +#if PLNA_SINGLE_GPIO + NRF_GPIOTE_NS->TASKS_CLR[plna_idx] = 1; +#else +#if MYNEWT_VAL(BLE_LL_PA) + NRF_GPIOTE_NS->TASKS_CLR[plna_pa_idx] = 1; +#endif +#if MYNEWT_VAL(BLE_LL_LNA) + NRF_GPIOTE_NS->TASKS_CLR[plna_lna_idx] = 1; +#endif +#endif +} + int ble_phy_get_cur_phy(void) { @@ -1973,7 +1988,7 @@ ble_phy_disable(void) ble_phy_stop_usec_timer(); ble_phy_disable_irq_and_ppi(); - + ble_phy_plna_force_disable(); ble_phy_dbg_clear_pins(); } From 437b2f7ad974b4b15c114414fdd1f3942689b245 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 11 Aug 2022 13:19:56 +0200 Subject: [PATCH 0480/1333] nimble/phy/nrf: Add some configuration after boot --- nimble/drivers/nrf5340/src/ble_phy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/drivers/nrf5340/src/ble_phy.c b/nimble/drivers/nrf5340/src/ble_phy.c index ac90c4f1ae..7d0e3e1fa7 100644 --- a/nimble/drivers/nrf5340/src/ble_phy.c +++ b/nimble/drivers/nrf5340/src/ble_phy.c @@ -1386,6 +1386,7 @@ ble_phy_init(void) /* Toggle peripheral power to reset (just in case) */ NRF_RADIO_NS->POWER = 0; NRF_RADIO_NS->POWER = 1; + *(volatile uint32_t *)(NRF_RADIO_NS_BASE + 0x774) = (*(volatile uint32_t* )(NRF_RADIO_NS_BASE + 0x774) & 0xfffffffe) | 0x01000000; /* Errata 16 - RADIO: POWER register is not functional * Workaround: Reset all RADIO registers in firmware. From f722d93661338a464f2941ed79febc3c31114e2d Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Thu, 11 Aug 2022 12:46:46 +0200 Subject: [PATCH 0481/1333] apps/btshell: Add "off" param to "scan" command. Substitute parameter for "cancel". --- apps/btshell/src/cmd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index 8b4315865f..fd75bc02bf 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -1209,7 +1209,7 @@ cmd_scan(int argc, char **argv) return rc; } - if (argc > 1 && strcmp(argv[1], "cancel") == 0) { + if (argc > 1 && (strcmp(argv[1], "cancel") == 0 || strcmp(argv[1], "off") == 0)) { rc = btshell_scan_cancel(); if (rc != 0) { console_printf("scan cancel fail: %d\n", rc); @@ -1353,6 +1353,7 @@ cmd_scan(int argc, char **argv) #if MYNEWT_VAL(SHELL_CMD_HELP) static const struct shell_param scan_params[] = { {"cancel", "cancel scan procedure"}, + {"off", "\"cancel\" param substitute"}, {"extended", "usage: =[none|1M|coded|both], default: none"}, {"duration", "usage: =[1-INT32_MAX], default: INT32_MAX"}, {"limited", "usage: =[0-1], default: 0"}, From 9bd8b5b78c46da2f7d75d7ce05db3a50f9c56c58 Mon Sep 17 00:00:00 2001 From: FanHang Date: Wed, 20 Jul 2022 17:27:23 +0800 Subject: [PATCH 0482/1333] apps/blehr: Fix blehr notify stopped incorrectly Don't stop blehr notity if other handles subscribed Signed-off-by: Hang Fan --- apps/blehr/src/main.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/blehr/src/main.c b/apps/blehr/src/main.c index eb26322e0a..e6dac7ce62 100644 --- a/apps/blehr/src/main.c +++ b/apps/blehr/src/main.c @@ -193,9 +193,6 @@ blehr_gap_event(struct ble_gap_event *event, void *arg) if (event->subscribe.attr_handle == hrs_hrm_handle) { notify_state = event->subscribe.cur_notify; blehr_tx_hrate_reset(); - } else if (event->subscribe.attr_handle != hrs_hrm_handle) { - notify_state = event->subscribe.cur_notify; - blehr_tx_hrate_stop(); } break; From ef4f44a02e74214a0be780884581906c4327bb93 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Fri, 19 Aug 2022 14:24:43 +0200 Subject: [PATCH 0483/1333] nimble/host: Fix host event buffer count Fixes the problem of not putting events such as, for example ble_hs_hci_evt_le_scan_timeout to the queue. --- nimble/host/src/ble_hs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index 13b6fe29e4..aeace63af3 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -30,7 +30,8 @@ #include "nimble/nimble_port.h" #endif -#define BLE_HS_HCI_EVT_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) +#define BLE_HS_HCI_EVT_COUNT (MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) + \ + MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT)) static void ble_hs_event_rx_hci_ev(struct ble_npl_event *ev); #if NIMBLE_BLE_CONNECT From 9331fbc5a435c32512f7f6ad452cf16ae2b720e8 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 19 Aug 2022 13:41:01 +0200 Subject: [PATCH 0484/1333] nimble/ll: Fix own address type check during scan We did not check own address type requested for scan when filtering so we matched random address even if public address was requested and vv. This fixes LL/DDI/SCN/BV-71-C. --- nimble/controller/src/ble_ll_scan.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 4893b2b0ca..010fe150bc 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1333,7 +1333,8 @@ ble_ll_scan_rx_filter(uint8_t own_addr_type, uint8_t scan_filt_policy, } /* Ignore if not directed to us */ - if (!ble_ll_is_our_devaddr(addrd->targeta, addrd->targeta_type)) { + if ((addrd->targeta_type != (own_addr_type & 0x01)) || + !ble_ll_is_our_devaddr(addrd->targeta, addrd->targeta_type)) { return -1; } break; @@ -1347,7 +1348,8 @@ ble_ll_scan_rx_filter(uint8_t own_addr_type, uint8_t scan_filt_policy, #else /* Ignore if not directed to us */ if (addrd->targeta && - !ble_ll_is_our_devaddr(addrd->targeta, addrd->targeta_type)) { + ((addrd->targeta_type != (own_addr_type & 0x01)) || + !ble_ll_is_our_devaddr(addrd->targeta, addrd->targeta_type))) { return -1; } From aa946c08cc789626f0ef104e48ad1d3a7bfef0a9 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 22 Aug 2022 18:58:13 +0200 Subject: [PATCH 0485/1333] nimble/ll: Make sane slot reservation for aux scan We always reserved 5ms slot for aux scan which is way too long for either 1M or 2M scan. As a result we are sometimes not able to scan complete chains if there are many concurrent instances being scanned. Instead, reserve slot for max pdu possible on secondary phy. --- nimble/controller/include/controller/ble_ll_sched.h | 3 ++- nimble/controller/src/ble_ll_scan_aux.c | 7 ++++++- nimble/controller/src/ble_ll_sched.c | 9 +++++---- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index e50ebc5c70..01af613d30 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -165,7 +165,8 @@ int ble_ll_sched_aux_scan(struct ble_mbuf_hdr *ble_hdr, struct ble_ll_aux_data *aux_scan); int ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time, - uint8_t pdu_time_rem, uint32_t offset_us); + uint8_t pdu_time_rem, uint32_t offset_us, + uint32_t max_aux_time_us); #endif /* Stop the scheduler */ diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 999efcbad8..5d77490337 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -746,6 +746,7 @@ ble_ll_scan_aux_sched(struct ble_ll_scan_aux_data *aux, uint32_t pdu_time, uint8_t pdu_time_rem, uint32_t aux_ptr) { uint32_t offset_us; + uint32_t max_aux_time_us; int rc; rc = ble_ll_scan_aux_parse_aux_ptr(aux, aux_ptr, &offset_us); @@ -753,7 +754,11 @@ ble_ll_scan_aux_sched(struct ble_ll_scan_aux_data *aux, uint32_t pdu_time, return -1; } - rc = ble_ll_sched_scan_aux(&aux->sch, pdu_time, pdu_time_rem, offset_us); + max_aux_time_us = ble_ll_pdu_tx_time_get(BLE_LL_MAX_PAYLOAD_LEN, + ble_ll_phy_to_phy_mode(aux->sec_phy, 0)); + + rc = ble_ll_sched_scan_aux(&aux->sch, pdu_time, pdu_time_rem, offset_us, + max_aux_time_us); if (rc < 0) { return -1; } diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 5456e8e292..ccf3fc58dd 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -1099,7 +1099,8 @@ ble_ll_sched_next_time(uint32_t *next_event_time) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) int ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time, - uint8_t pdu_time_rem, uint32_t offset_us) + uint8_t pdu_time_rem, uint32_t offset_us, + uint32_t max_aux_time_us) { uint32_t offset_ticks; os_sr_t sr; @@ -1108,10 +1109,10 @@ ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time, offset_us += pdu_time_rem; offset_ticks = ble_ll_tmr_u2t(offset_us); - sch->start_time = pdu_time + offset_ticks - g_ble_ll_sched_offset_ticks; + sch->start_time = pdu_time + offset_ticks; sch->remainder = offset_us - ble_ll_tmr_t2u(offset_ticks); - /* TODO: make some sane slot reservation */ - sch->end_time = sch->start_time + ble_ll_tmr_u2t(5000); + sch->end_time = sch->start_time + ble_ll_tmr_u2t_up(max_aux_time_us); + sch->start_time -= g_ble_ll_sched_offset_ticks; OS_ENTER_CRITICAL(sr); From cf51b86dceda80349cb0c2de87a05df9bc42c1d0 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 22 Aug 2022 15:31:01 +0200 Subject: [PATCH 0486/1333] nimble/ll: Fix ext adv report status when failed to schedule chain scan If aux chain scan failed to schedule, we simply remove aux ptr flag which results in "complete" event being sent instead of "truncated". We should mark PDU accordingly and send "truncated" if this is last aux chain scanned, but there were more to come. This fixes LL/DDI/SCN/BV-62-C. --- nimble/controller/src/ble_ll_scan_aux.c | 3 +++ nimble/include/nimble/ble.h | 5 +---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 5d77490337..56f1c528eb 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -564,6 +564,8 @@ ble_ll_hci_ev_send_ext_adv_report(struct os_mbuf *rxpdu, } else { report->evt_type |= BLE_HCI_ADV_DATA_STATUS_TRUNCATED; } + } else if (rxinfo->flags & BLE_MBUF_HDR_F_AUX_PTR_FAILED) { + report->evt_type |= BLE_HCI_ADV_DATA_STATUS_TRUNCATED; } switch (report->evt_type & BLE_HCI_ADV_DATA_STATUS_MASK) { @@ -1667,6 +1669,7 @@ ble_ll_scan_aux_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr) aux->aux_ptr); if (rc < 0) { rxinfo->flags &= ~BLE_MBUF_HDR_F_AUX_PTR_WAIT; + rxinfo->flags |= BLE_MBUF_HDR_F_AUX_PTR_FAILED; } } diff --git a/nimble/include/nimble/ble.h b/nimble/include/nimble/ble.h index bbf2275388..0aa96251a1 100644 --- a/nimble/include/nimble/ble.h +++ b/nimble/include/nimble/ble.h @@ -101,7 +101,7 @@ struct ble_mbuf_hdr_rxinfo #define BLE_MBUF_HDR_F_EXT_ADV (0x0800) #define BLE_MBUF_HDR_F_RESOLVED (0x0400) #define BLE_MBUF_HDR_F_AUX_PTR_WAIT (0x0200) -#define BLE_MBUF_HDR_F_AUX_INVALID (0x0100) +#define BLE_MBUF_HDR_F_AUX_PTR_FAILED (0x0100) #define BLE_MBUF_HDR_F_CRC_OK (0x0080) #define BLE_MBUF_HDR_F_DEVMATCH (0x0040) #define BLE_MBUF_HDR_F_MIC_FAILURE (0x0020) @@ -146,9 +146,6 @@ struct ble_mbuf_hdr #define BLE_MBUF_HDR_SCAN_RSP_RXD(hdr) \ (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_SCAN_RSP_RXD)) -#define BLE_MBUF_HDR_AUX_INVALID(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_AUX_INVALID)) - #define BLE_MBUF_HDR_WAIT_AUX(hdr) \ (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_AUX_PTR_WAIT)) From e50cb6d58713cede76a80cf861edaa850383a8f2 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 22 Aug 2022 13:33:03 +0200 Subject: [PATCH 0487/1333] nimble: Fix hci defs order --- nimble/include/nimble/hci_common.h | 85 +++++++++++++++--------------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 17fa762722..40602d7b3e 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1063,6 +1063,48 @@ struct ble_hci_le_set_host_feat_cp { uint8_t val; } __attribute__((packed)); +#define BLE_HCI_OCF_LE_ENH_READ_TRANSMIT_POWER_LEVEL (0x0076) +struct ble_hci_le_enh_read_transmit_power_level_cp { + uint16_t conn_handle; + uint8_t phy; +} __attribute__((packed)); +struct ble_hci_le_enh_read_transmit_power_level_rp { + uint8_t status; + uint16_t conn_handle; + uint8_t phy; + uint8_t curr_tx_power_level; + uint8_t max_tx_power_level; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_READ_REMOTE_TRANSMIT_POWER_LEVEL (0x0077) +struct ble_hci_le_read_remote_transmit_power_level_cp { + uint16_t conn_handle; + uint8_t phy; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_SET_PATH_LOSS_REPORT_PARAM (0x0078) +struct ble_hci_le_set_path_loss_report_param_cp { + uint16_t conn_handle; + uint8_t high_threshold; + uint8_t high_hysteresis; + uint8_t low_threshold; + uint8_t low_hysteresis; + uint16_t min_time_spent; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_SET_PATH_LOSS_REPORT_ENABLE (0x0079) +struct ble_hci_le_set_path_loss_report_enable_cp { + uint16_t conn_handle; + uint8_t enable; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_SET_TRANS_PWR_REPORT_ENABLE (0x007A) +struct ble_hci_le_set_transmit_power_report_enable_cp { + uint16_t conn_handle; + uint8_t local_enable; + uint8_t remote_enable; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_SET_DEFAULT_SUBRATE (0x007D) struct ble_hci_le_set_default_subrate_cp { uint16_t subrate_min; @@ -1127,49 +1169,6 @@ struct ble_hci_vs_css_set_conn_slot_cp { uint16_t slot_idx; } __attribute__((packed)); -#define BLE_HCI_OCF_LE_ENH_READ_TRANSMIT_POWER_LEVEL (0x0076) -struct ble_hci_le_enh_read_transmit_power_level_cp { - uint16_t conn_handle; - uint8_t phy; -} __attribute__((packed)); -struct ble_hci_le_enh_read_transmit_power_level_rp { - uint8_t status; - uint16_t conn_handle; - uint8_t phy; - uint8_t curr_tx_power_level; - uint8_t max_tx_power_level; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_READ_REMOTE_TRANSMIT_POWER_LEVEL (0x0077) -struct ble_hci_le_read_remote_transmit_power_level_cp { - uint16_t conn_handle; - uint8_t phy; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_PATH_LOSS_REPORT_PARAM (0x0078) -struct ble_hci_le_set_path_loss_report_param_cp { - uint16_t conn_handle; - uint8_t high_threshold; - uint8_t high_hysteresis; - uint8_t low_threshold; - uint8_t low_hysteresis; - uint16_t min_time_spent; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_PATH_LOSS_REPORT_ENABLE (0x0079) -struct ble_hci_le_set_path_loss_report_enable_cp { - uint16_t conn_handle; - uint8_t enable; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_TRANS_PWR_REPORT_ENABLE (0x007A) -struct ble_hci_le_set_transmit_power_report_enable_cp { - uint16_t conn_handle; - uint8_t local_enable; - uint8_t remote_enable; -} __attribute__((packed)); - - /* Command Specific Definitions */ /* --- Set controller to host flow control (OGF 0x03, OCF 0x0031) --- */ #define BLE_HCI_CTLR_TO_HOST_FC_OFF (0) From bed2f82b71f0dfdb469d583fa7364a6cb0f989aa Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 22 Aug 2022 20:00:46 +0200 Subject: [PATCH 0488/1333] nimble/ll: Fix periodic data length check Ticks were added to usecs and this does not work as expected. This fixes HCI/DDI/BI-52-C. --- nimble/controller/src/ble_ll_adv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 8e7df3a397..f0e0ae6b7f 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -3748,8 +3748,7 @@ ble_ll_adv_periodic_check_data_itvl(uint16_t payload_len, uint16_t props, pdu_len = ble_ll_adv_sync_get_pdu_len(payload_len, &offset, props); max_usecs += ble_ll_pdu_tx_time_get(pdu_len, phy); - max_usecs += ble_ll_tmr_u2t_up(BLE_LL_MAFS + - MYNEWT_VAL(BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY)); + max_usecs += BLE_LL_MAFS + MYNEWT_VAL(BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY); } itvl_usecs = (uint32_t)itvl * BLE_LL_ADV_PERIODIC_ITVL; From 2aafc341ae85f50433625bded347a45a30b87e34 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 22 Aug 2022 19:31:56 +0200 Subject: [PATCH 0489/1333] nimble/ll: Fix adv macros Use parentheses around macro parameters to avoid issue when expanding macro. Also some macros uses "advsm" instead of "_advsm" parameter. --- nimble/controller/src/ble_ll_adv.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index f0e0ae6b7f..0ffa1afc4d 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -193,19 +193,23 @@ struct ble_ll_adv_sm #define BLE_LL_ADV_SM_FLAG_CONN_RSP_TXD_ERR 0x8000 #define ADV_DATA_LEN(_advsm) \ - ((_advsm->adv_data) ? OS_MBUF_PKTLEN(advsm->adv_data) : 0) + (((_advsm)->adv_data) ? OS_MBUF_PKTLEN((_advsm)->adv_data) : 0) #define SCAN_RSP_DATA_LEN(_advsm) \ - ((_advsm->scan_rsp_data) ? OS_MBUF_PKTLEN(advsm->scan_rsp_data) : 0) -#define AUX_DATA_LEN(_advsm) \ - (*(_advsm->aux_data) ? OS_MBUF_PKTLEN(*advsm->aux_data) : 0) + (((_advsm)->scan_rsp_data) ? OS_MBUF_PKTLEN((_advsm)->scan_rsp_data) : 0) -#define AUX_CURRENT(_advsm) (&(_advsm->aux[_advsm->aux_index])) -#define AUX_NEXT(_advsm) (&(_advsm->aux[_advsm->aux_index ^ 1])) +#define AUX_CURRENT(_advsm) \ + (&((_advsm)->aux[(_advsm)->aux_index])) +#define AUX_NEXT(_advsm) \ + (&((_advsm)->aux[(_advsm)->aux_index ^ 1])) +#define AUX_DATA_LEN(_advsm) \ + (*((_advsm)->aux_data) ? OS_MBUF_PKTLEN(*(_advsm)->aux_data) : 0) -#define SYNC_CURRENT(_advsm) (&(_advsm->periodic_sync[_advsm->periodic_sync_index])) -#define SYNC_NEXT(_advsm) (&(_advsm->periodic_sync[_advsm->periodic_sync_index ^ 1])) +#define SYNC_CURRENT(_advsm) \ + (&((_advsm)->periodic_sync[(_advsm)->periodic_sync_index])) +#define SYNC_NEXT(_advsm) \ + (&((_advsm)->periodic_sync[(_advsm)->periodic_sync_index ^ 1])) #define SYNC_DATA_LEN(_advsm) \ - (_advsm->periodic_adv_data ? OS_MBUF_PKTLEN(advsm->periodic_adv_data) : 0) + ((_advsm)->periodic_adv_data ? OS_MBUF_PKTLEN((_advsm)->periodic_adv_data) : 0) /* The advertising state machine global object */ struct ble_ll_adv_sm g_ble_ll_adv_sm[BLE_ADV_INSTANCES]; From df2ed42d23b5a18cf46f8a8054a330332dca9fdf Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Thu, 18 Aug 2022 15:31:38 +0200 Subject: [PATCH 0490/1333] nimble/transport: Add CDC transport This adds implementation of TinyUSB CDC class that that will transmit HCI protocol over USB/CDC class --- nimble/transport/cdc/pkg.yml | 34 +++ nimble/transport/cdc/src/cdc_hci.c | 432 +++++++++++++++++++++++++++++ nimble/transport/cdc/syscfg.yml | 27 ++ nimble/transport/pkg.yml | 2 + nimble/transport/syscfg.yml | 1 + 5 files changed, 496 insertions(+) create mode 100644 nimble/transport/cdc/pkg.yml create mode 100644 nimble/transport/cdc/src/cdc_hci.c create mode 100644 nimble/transport/cdc/syscfg.yml diff --git a/nimble/transport/cdc/pkg.yml b/nimble/transport/cdc/pkg.yml new file mode 100644 index 0000000000..3620ee1426 --- /dev/null +++ b/nimble/transport/cdc/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: nimble/transport/cdc +pkg.description: HCI H4 transport over CDC +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" + +pkg.deps: + - "@apache-mynewt-core/hw/hal" + - "@apache-mynewt-core/kernel/os" + - nimble + - nimble/transport/common/hci_h4 + - "@apache-mynewt-core/hw/usb/tinyusb" + - "@apache-mynewt-core/hw/usb/tinyusb/cdc" + +pkg.apis: + - ble_transport diff --git a/nimble/transport/cdc/src/cdc_hci.c b/nimble/transport/cdc/src/cdc_hci.c new file mode 100644 index 0000000000..08c8f984a0 --- /dev/null +++ b/nimble/transport/cdc/src/cdc_hci.c @@ -0,0 +1,432 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CDC_HCI_LOG_LEVEL 2 + +/* State machine for assembling packets from HOST (commands and ALCs) */ +static struct hci_h4_sm cdc_hci_h4sm; + +static const struct cdc_callbacks cdc_hci_callback; + +struct usb_in_packet; +struct usb_in_queue { + STAILQ_HEAD(, usb_in_packet) queue; +}; + +static struct os_mempool usb_in_packet_pool; + +#define USB_IN_PACKET_COUNT (MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT) + \ + MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) + \ + MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT) + 1) + +typedef struct cdc_hci_itf { + /* CDC Interface */ + cdc_itf_t cdc_itf; + /* ACL or Evnet packet that is currently transferred over USB */ + struct usb_in_packet *current_in_packet; + int current_in_packet_offset; + /* ACL and Event packets that are waiting to be transmitted */ + struct usb_in_queue usb_in_queue; + uint8_t rx_buffer[USBD_CDC_DATA_EP_SIZE]; +} cdc_hci_itf_t; + +static cdc_hci_itf_t cdc_hci_itf = { + .cdc_itf.callbacks = &cdc_hci_callback, + .usb_in_queue = {STAILQ_HEAD_INITIALIZER(cdc_hci_itf.usb_in_queue.queue)}, +}; + +struct usb_packet_ops { + void (*packet_free)(struct usb_in_packet *packet); + int (*packet_write)(struct usb_in_packet *packet, size_t offset); + int (*packet_size)(struct usb_in_packet *packet); +}; + +struct usb_in_packet { + STAILQ_ENTRY(usb_in_packet) next; + const struct usb_packet_ops *ops; + void *data; +}; + +static uint8_t usb_in_packet_pool_mem[OS_MEMPOOL_BYTES(USB_IN_PACKET_COUNT, sizeof(struct usb_in_packet))]; + +static void +cdc_hci_rx_cb(cdc_itf_t *itf) +{ + int ret; + uint8_t cdc_num = itf->cdc_num; + uint32_t available = tud_cdc_n_available(cdc_num); + uint32_t received = 0; + int consumed = 0; + + while ((available > 0) || (received > consumed)) { + if (consumed == received) { + consumed = 0; + received = tud_cdc_n_read(cdc_num, cdc_hci_itf.rx_buffer, min(available, sizeof(cdc_hci_itf.rx_buffer))); + available = tud_cdc_n_available(cdc_num); + } + ret = hci_h4_sm_rx(&cdc_hci_h4sm, cdc_hci_itf.rx_buffer + consumed, received - consumed); + if (ret < 0) { + tud_cdc_n_read_flush(cdc_num); + break; + } + consumed += ret; + } +} + +static void +usb_in_packet_free(struct usb_in_packet *pkt) +{ + if (pkt) { + pkt->ops->packet_free(pkt); + os_memblock_put(&usb_in_packet_pool, pkt); + } +} + +static int +usb_in_packet_write(struct usb_in_packet *pkt, int offset) +{ + return pkt->ops->packet_write(pkt, offset); +} + +static int +usb_in_packet_size(struct usb_in_packet *pkt) +{ + if (pkt) { + return pkt->ops->packet_size(pkt); + } else { + return 0; + } +} + +static void +cdc_hci_send_next_in_packet(void) +{ + int sr; + struct usb_in_packet *last_packet; + + if (cdc_hci_itf.current_in_packet == NULL || + cdc_hci_itf.current_in_packet_offset == usb_in_packet_size(cdc_hci_itf.current_in_packet)) { + OS_ENTER_CRITICAL(sr); + last_packet = cdc_hci_itf.current_in_packet; + cdc_hci_itf.current_in_packet_offset = 0; + cdc_hci_itf.current_in_packet = STAILQ_FIRST(&cdc_hci_itf.usb_in_queue.queue); + if (cdc_hci_itf.current_in_packet) { + STAILQ_REMOVE_HEAD(&cdc_hci_itf.usb_in_queue.queue, next); + } + OS_EXIT_CRITICAL(sr); + usb_in_packet_free(last_packet); + } + if (cdc_hci_itf.current_in_packet != NULL && + cdc_hci_itf.current_in_packet_offset < usb_in_packet_size(cdc_hci_itf.current_in_packet)) { + cdc_hci_itf.current_in_packet_offset += usb_in_packet_write(cdc_hci_itf.current_in_packet, + cdc_hci_itf.current_in_packet_offset); + } +} + +static void +cdc_hci_tx_complete_cb(cdc_itf_t *itf) +{ + (void)itf; + + cdc_hci_send_next_in_packet(); +} + +static void +cdc_hci_line_state_cb(cdc_itf_t *itf, bool dtr, bool rts) +{ + (void)itf; + (void)rts; + + if (dtr) { + cdc_hci_send_next_in_packet(); + } +} + +static struct usb_in_packet * +cdc_hci_get_usb_in_packet(void) +{ + struct usb_in_packet *packet = (struct usb_in_packet *)os_memblock_get(&usb_in_packet_pool); + if (packet) { + packet->data = NULL; + } + return packet; +} + +static void +cdc_hci_send_next_in_packet_from_usbd_task(void *dummy) +{ + (void)dummy; + cdc_hci_send_next_in_packet(); +} + +static void +cdc_hci_usb_in_enqueue_packet(struct usb_in_packet *pkt) +{ + int sr; + + /* Add to IN queue */ + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&cdc_hci_itf.usb_in_queue.queue, pkt, next); + OS_EXIT_CRITICAL(sr); + + usbd_defer_func(cdc_hci_send_next_in_packet_from_usbd_task, NULL, true); +} + + +/* + * Returns packet size as seen over USB + */ +static int +cdc_hci_event_packet_size(struct usb_in_packet *packet) +{ + struct ble_hci_ev *event = packet->data; + return event->length + 2 /* opcode + length */ + 1 /* H4 header */; +} + +/* + * Free Event packet that BLE stack provided to USB stack. + * Function is called once all data was sent over USB IN endpoint. + */ +static void +cdc_hci_event_packet_free(struct usb_in_packet *packet) +{ + ble_transport_free(packet->data); +} + +/* + * Write Event packed from BLE stack to USB IN endpoint. + * Flush will be called separately. + */ +static int +cdc_hci_event_packet_write(struct usb_in_packet *packet, size_t offset) +{ + uint8_t cdc_num = cdc_hci_itf.cdc_itf.cdc_num; + const uint8_t *buf = ((const uint8_t *)packet->data) - 1; + const struct ble_hci_ev *hci_ev = packet->data; + size_t h4_event_size = hci_ev->length + sizeof(struct ble_hci_ev) + 1; + size_t new_offset = offset; + + /* Write H4 Event type */ + if (new_offset == 0) { + new_offset = tud_cdc_n_write_char(cdc_num, HCI_H4_EVT); + } + /* If first byte was not written rest of the event has to wait as well */ + if (new_offset > 0) { + new_offset += tud_cdc_n_write(cdc_num, buf + new_offset, h4_event_size - new_offset); + tud_cdc_n_write_flush(cdc_num); + } + + return (int)(new_offset - offset); +} + +/* + * USB IN endpoint packet handling functions for Events + */ +static const struct usb_packet_ops event_packet_ops = { + .packet_free = cdc_hci_event_packet_free, + .packet_write = cdc_hci_event_packet_write, + .packet_size = cdc_hci_event_packet_size, +}; + +/* + * Returns packet size as seen over USB + */ +static int +cdc_hci_acl_packet_size(struct usb_in_packet *packet) +{ + struct os_mbuf *om = (struct os_mbuf *)packet->data; + /* Data size of mbuf plus one for H4 header (2) */ + return os_mbuf_len(om) + 1; +} + +/* + * Free ACL data packet that BLE stack provided to USB stack. + * Function is called once all data was sent over USB IN endpoint. + */ +static void +cdc_hci_acl_packet_free(struct usb_in_packet *packet) +{ + struct os_mbuf *om = (struct os_mbuf *)packet->data; + + os_mbuf_free_chain(om); +} + +/* + * Write ACL packed from BLE stack to USB IN endpoint. + * Code traverses mbuf to send all data. + * Flush will be called separately. + */ +static int +cdc_hci_acl_packet_write(struct usb_in_packet *packet, size_t offset) +{ + uint8_t cdc_num = cdc_hci_itf.cdc_itf.cdc_num; + struct os_mbuf *om = (struct os_mbuf *)packet->data; + struct os_mbuf *mb; + size_t new_offset = offset; + uint16_t mbuf_offset; + size_t write_size; + size_t written; + + if (om) { + if (new_offset == 0) { + /* Write H4 ACL type */ + new_offset += tud_cdc_n_write_char(cdc_num, HCI_H4_ACL); + } + + for (;;) { + mb = os_mbuf_off(om, (int)new_offset - 1, &mbuf_offset); + assert(mb); + /* mbuf_offset is == om_len when new_offset reached end of mbuf data */ + if (mb->om_len == mbuf_offset) { + break; + } + /* Chunk in current mbuf */ + write_size = mb->om_len - mbuf_offset; + written = tud_cdc_n_write(cdc_num, mb->om_data + mbuf_offset, write_size); + new_offset += written; + /* USB FIFO did not have enough space for whole mbuf, stop write for now */ + if (written < write_size) { + break; + } + } + tud_cdc_n_write_flush(cdc_num); + } + + return (int)(new_offset - offset); +} + +/* + * USB IN endpoint packet handling functions for ACL data + */ +static const struct usb_packet_ops cdc_hci_acl_packet_ops = { + .packet_free = cdc_hci_acl_packet_free, + .packet_write = cdc_hci_acl_packet_write, + .packet_size = cdc_hci_acl_packet_size, +}; + +static int +cdc_hci_frame_cb(uint8_t pkt_type, void *data) +{ + switch (pkt_type) { + case HCI_H4_CMD: + return ble_transport_to_ll_cmd(data); + case HCI_H4_ACL: + return ble_transport_to_ll_acl(data); + default: + assert(0); + break; + } + + return -1; +} + +/* + * BLE stack callback with Event to be dispatched to USB IN endpoint. + */ +int +ble_transport_to_hs_evt_impl(void *buf) +{ + struct usb_in_packet *pkt; + + assert(buf != NULL); + + pkt = cdc_hci_get_usb_in_packet(); + if (pkt == NULL) { + ble_transport_free(buf); + return BLE_ERR_MEM_CAPACITY; + } + + pkt->data = buf; + pkt->ops = &event_packet_ops; + cdc_hci_usb_in_enqueue_packet(pkt); + + return 0; +} + +/* + * BLE stack callback with ACL data to be dispatched to USB IN endpoint. + */ +int +ble_transport_to_hs_acl_impl(struct os_mbuf *om) +{ + struct usb_in_packet *pkt; + + /* If this packet is zero length, just free it */ + if (OS_MBUF_PKTLEN(om) == 0) { + os_mbuf_free_chain(om); + return 0; + } + + pkt = cdc_hci_get_usb_in_packet(); + if (pkt == NULL) { + assert(0); + return -ENOMEM; + } + + pkt->data = om; + pkt->ops = &cdc_hci_acl_packet_ops; + cdc_hci_usb_in_enqueue_packet(pkt); + + return 0; +} + +void +ble_transport_hs_init(void) +{ + int rc; + + SYSINIT_ASSERT_ACTIVE(); + + rc = os_mempool_init(&usb_in_packet_pool, + USB_IN_PACKET_COUNT, + sizeof(struct usb_in_packet), + usb_in_packet_pool_mem, + "usb_in_packet_pool"); + + SYSINIT_PANIC_ASSERT(rc == 0); + + cdc_itf_add(&cdc_hci_itf.cdc_itf); + + hci_h4_sm_init(&cdc_hci_h4sm, &hci_h4_allocs_from_hs, cdc_hci_frame_cb); +} + +static const struct cdc_callbacks cdc_hci_callback = { + .cdc_rx_cb = cdc_hci_rx_cb, + .cdc_line_coding_cb = NULL, + .cdc_line_state_cb = cdc_hci_line_state_cb, + .cdc_rx_wanted_cb = NULL, + .cdc_send_break_cb = NULL, + .cdc_tx_complete_cb = cdc_hci_tx_complete_cb, +}; + diff --git a/nimble/transport/cdc/syscfg.yml b/nimble/transport/cdc/syscfg.yml new file mode 100644 index 0000000000..0336625093 --- /dev/null +++ b/nimble/transport/cdc/syscfg.yml @@ -0,0 +1,27 @@ +# 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. +# + +syscfg.defs: + USBD_CDC_HCI_DESCRIPTOR_STRING: + description: String for CDC/HCI interface + value: + + USBD_CDC_HCI: + description: Constant value indicating package usage + value: 1 + diff --git a/nimble/transport/pkg.yml b/nimble/transport/pkg.yml index 03924ced59..5070c72883 100644 --- a/nimble/transport/pkg.yml +++ b/nimble/transport/pkg.yml @@ -44,6 +44,8 @@ pkg.deps.'BLE_TRANSPORT_HS == "uart"': - nimble/transport/uart pkg.deps.'BLE_TRANSPORT_HS == "usb"': - nimble/transport/usb +pkg.deps.'BLE_TRANSPORT_HS == "cdc"': + - nimble/transport/cdc pkg.deps.'BLE_TRANSPORT_LL == "apollo3"': - nimble/transport/apollo3 diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml index e69b0ef67c..a4ae6d56fc 100644 --- a/nimble/transport/syscfg.yml +++ b/nimble/transport/syscfg.yml @@ -31,6 +31,7 @@ syscfg.defs: - nrf5340 - uart - usb + - cdc - custom BLE_TRANSPORT_LL: description: > From 338c81014ebb7be717446c18e53ea1d4e68b88e1 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Mon, 22 Aug 2022 11:39:56 +0200 Subject: [PATCH 0491/1333] host/ble_gap.c: Fix failure to run callback on finished scan When both roles - peripheral and central where turned off, removed lines where causing not calling callback function after completing the scan. --- nimble/host/src/ble_gap.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index ed959957bf..289ad5917e 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -917,21 +917,17 @@ ble_gap_disc_report(void *desc) static void ble_gap_disc_complete(void) { -#if NIMBLE_BLE_CONNECT struct ble_gap_master_state state; -#endif struct ble_gap_event event; memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_DISC_COMPLETE; event.disc_complete.reason = 0; -#if NIMBLE_BLE_CONNECT ble_gap_master_extract_state(&state, 1); if (ble_gap_has_client(&state)) { ble_gap_call_event_cb(&event, state.cb, state.cb_arg); } -#endif ble_gap_event_listener_call(&event); } From 0c9bb5d050212711bf924f2262dded535a442c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 22 Sep 2021 14:32:13 +0200 Subject: [PATCH 0492/1333] host: add Pairing Complete GAP event Added event to inform application via GAP event that peer completed pairing with reason code. This is required by SM/CEN/KDU/BI-02-C. --- nimble/host/include/host/ble_gap.h | 19 +++++++++++++++++++ nimble/host/include/host/ble_sm.h | 4 +++- nimble/host/src/ble_gap.c | 14 ++++++++++++++ nimble/host/src/ble_gap_priv.h | 1 + nimble/host/src/ble_sm.c | 9 +++++++++ 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index 83aacacd23..5ff34f5867 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -137,6 +137,7 @@ struct hci_conn_update; #define BLE_GAP_EVENT_PERIODIC_TRANSFER 24 #define BLE_GAP_EVENT_PATHLOSS_THRESHOLD 25 #define BLE_GAP_EVENT_TRANSMIT_POWER 26 +#define BLE_GAP_EVENT_PARING_COMPLETE 27 /*** Reason codes for the subscribe GAP event. */ @@ -1023,6 +1024,24 @@ struct ble_gap_event { uint8_t delta; } transmit_power; #endif + /** + * Represents a received Pairing Complete message + * + * Valid for the following event types: + * o BLE_GAP_EVENT_PARING_COMPLETE + */ + struct { + /** + * Indicates the result of the encryption state change attempt; + * o 0: the encrypted state was successfully updated; + * o BLE host error code: the encryption state change attempt + * failed for the specified reason. + */ + int status; + + /** The handle of the relevant connection. */ + uint16_t conn_handle; + } pairing_complete; }; }; diff --git a/nimble/host/include/host/ble_sm.h b/nimble/host/include/host/ble_sm.h index ceebb85643..ff381cf25b 100644 --- a/nimble/host/include/host/ble_sm.h +++ b/nimble/host/include/host/ble_sm.h @@ -27,6 +27,7 @@ extern "C" { #endif +#define BLE_SM_ERR_SUCCESS 0x00 #define BLE_SM_ERR_PASSKEY 0x01 #define BLE_SM_ERR_OOB 0x02 #define BLE_SM_ERR_AUTHREQ 0x03 @@ -41,7 +42,8 @@ extern "C" { #define BLE_SM_ERR_NUMCMP 0x0c #define BLE_SM_ERR_ALREADY 0x0d #define BLE_SM_ERR_CROSS_TRANS 0x0e -#define BLE_SM_ERR_MAX_PLUS_1 0x0f +#define BLE_SM_ERR_KEY_REJ 0x0f +#define BLE_SM_ERR_MAX_PLUS_1 0x10 #define BLE_SM_PAIR_ALG_JW 0 #define BLE_SM_PAIR_ALG_PASSKEY 1 diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 289ad5917e..0dcf93582d 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -5898,6 +5898,20 @@ ble_gap_repeat_pairing_event(const struct ble_gap_repeat_pairing *rp) #endif } +void +ble_gap_pairing_complete_event(uint16_t conn_handle, int status) +{ +#if NIMBLE_BLE_SM && NIMBLE_BLE_CONNECT + struct ble_gap_event event; + + memset(&event, 0, sizeof event); + event.type = BLE_GAP_EVENT_PARING_COMPLETE; + event.pairing_complete.conn_handle = conn_handle; + event.pairing_complete.status = status; + ble_gap_call_conn_event_cb(&event, conn_handle); +#endif +} + /***************************************************************************** * $rssi * *****************************************************************************/ diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h index ca85db3dda..06c4d16bf2 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/nimble/host/src/ble_gap_priv.h @@ -135,6 +135,7 @@ void ble_gap_subscribe_event(uint16_t conn_handle, uint16_t attr_handle, void ble_gap_mtu_event(uint16_t conn_handle, uint16_t cid, uint16_t mtu); void ble_gap_identity_event(uint16_t conn_handle); int ble_gap_repeat_pairing_event(const struct ble_gap_repeat_pairing *rp); +void ble_gap_pairing_complete_event(uint16_t conn_handle, int status); int ble_gap_master_in_progress(void); void ble_gap_preempt(void); diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 0339e3eb41..71b9f769be 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -933,6 +933,12 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res) ble_hs_unlock(); + if (res->enc_cb && + res->app_status != BLE_HS_ENOTCONN) { + /* Do not send this event on broken connection */ + ble_gap_pairing_complete_event(conn_handle, res->sm_err); + } + if (proc == NULL) { break; } @@ -2053,6 +2059,8 @@ ble_sm_key_exch_success(struct ble_sm_proc *proc, struct ble_sm_result *res) res->app_status = 0; res->enc_cb = 1; res->bonded = bonded; + + res->sm_err = BLE_SM_ERR_SUCCESS; } static void @@ -2423,6 +2431,7 @@ ble_sm_fail_rx(uint16_t conn_handle, struct os_mbuf **om, cmd = (struct ble_sm_pair_fail *)(*om)->om_data; res->app_status = BLE_HS_SM_PEER_ERR(cmd->reason); + res->sm_err = cmd->reason; } } From f7ebfaf95b44013c8ab938edbab2bf98bebc7d8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 22 Sep 2021 14:34:05 +0200 Subject: [PATCH 0493/1333] apps/bttester: handle GAP Pairing Complete event Send event when peer fails pairing procedure with reason code. This is required by SM/CEN/KDU/BI-02-C. --- apps/bttester/src/bttester.h | 7 +++++++ apps/bttester/src/gap.c | 35 ++++++++++++++++++++++++++++++++++- nimble/host/src/ble_sm.c | 1 - 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/apps/bttester/src/bttester.h b/apps/bttester/src/bttester.h index 7bcd789cd4..4aa34b3c25 100644 --- a/apps/bttester/src/bttester.h +++ b/apps/bttester/src/bttester.h @@ -418,6 +418,13 @@ struct gap_bond_lost_ev { uint8_t address[6]; } __packed; +#define GAP_EV_SEC_PAIRING_FAILED 0x8c +struct gap_sec_pairing_failed_ev { + uint8_t address_type; + uint8_t address[6]; + uint8_t reason; +} __packed; + /* GATT Service */ /* commands */ #define GATT_READ_SUPPORTED_COMMANDS 0x01 diff --git a/apps/bttester/src/gap.c b/apps/bttester/src/gap.c index e213609336..24ef4ab352 100644 --- a/apps/bttester/src/gap.c +++ b/apps/bttester/src/gap.c @@ -980,6 +980,31 @@ static void le_identity_resolved(uint16_t conn_handle) CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } +static void le_pairing_failed(uint16_t conn_handle, int reason) +{ + struct ble_gap_conn_desc desc; + struct gap_sec_pairing_failed_ev ev; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find(conn_handle, &desc); + if (rc) { + return; + } + + peer_id_addr = desc.peer_id_addr; + peer_ota_addr = desc.peer_ota_addr; + + ev.address_type = desc.peer_ota_addr.type; + memcpy(ev.address, desc.peer_ota_addr.val, sizeof(ev.address)); + + ev.reason = reason; + + tester_send(BTP_SERVICE_ID_GAP, GAP_EV_SEC_PAIRING_FAILED, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); +} + static void le_conn_param_update(struct ble_gap_conn_desc *desc) { struct gap_conn_param_update_ev ev; @@ -1262,7 +1287,15 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg) event->conn_update_req.peer_params->supervision_timeout == REJECT_SUPERVISION_TIMEOUT) { return EINVAL; } - + case BLE_GAP_EVENT_PARING_COMPLETE: + console_printf("received pairing complete: " + "conn_handle=%d status=%d\n", + event->pairing_complete.conn_handle, + event->pairing_complete.status); + if (event->pairing_complete.status != BLE_SM_ERR_SUCCESS) { + le_pairing_failed(event->pairing_complete.conn_handle, event->pairing_complete.status); + } + break; default: break; } diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 71b9f769be..5188effe94 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -2059,7 +2059,6 @@ ble_sm_key_exch_success(struct ble_sm_proc *proc, struct ble_sm_result *res) res->app_status = 0; res->enc_cb = 1; res->bonded = bonded; - res->sm_err = BLE_SM_ERR_SUCCESS; } From cc29a463fe82b636229dfa98b50c2a16594b5e18 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 24 Aug 2022 14:07:32 +0200 Subject: [PATCH 0494/1333] nimble/ll: Fix host controlled features handling We should not allow to set subrating feature if controller does not support subrating. --- nimble/controller/include/controller/ble_ll.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index f336c08067..a524759a2f 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -289,7 +289,11 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats; #define BLE_LL_CONN_CLEAR_FEATURE(connsm, feature) (connsm->conn_features &= ~(feature)) /* All the features which can be controlled by the Host */ +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) #define BLE_LL_HOST_CONTROLLED_FEATURES (BLE_LL_FEAT_CONN_SUBRATING_HOST) +#else +#define BLE_LL_HOST_CONTROLLED_FEATURES (0) +#endif /* LL timing */ #define BLE_LL_IFS (150) /* usecs */ From 7871321f702e99204a19c05328a16da463e6d342 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 24 Aug 2022 17:21:02 +0200 Subject: [PATCH 0495/1333] nimble/ll: Fix LE Read Supported States with no peripheral Bits 32,33 34 are for connectable advertising during connection state as central and thus should be reported only if both peripheral and central roles are enabled. --- nimble/controller/src/ble_ll.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 1c92cadab4..90fee6bf7b 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -202,17 +202,13 @@ int8_t g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); #define BLE_LL_S_CA_INIT ((uint64_t)1 << 32) #define BLE_LL_S_HDCA_INIT ((uint64_t)1 << 33) #define BLE_LL_S_LDCA_INIT ((uint64_t)1 << 34) -#else -#define BLE_LL_S_CA_INIT ((uint64_t)0 << 32) -#define BLE_LL_S_HDCA_INIT ((uint64_t)0 << 33) -#define BLE_LL_S_LDCA_INIT ((uint64_t)0 << 34) -#endif - -#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define BLE_LL_S_CA_CENTRAL ((uint64_t)1 << 35) #define BLE_LL_S_HDCA_CENTRAL ((uint64_t)1 << 36) #define BLE_LL_S_LDCA_CENTRAL ((uint64_t)1 << 37) #else +#define BLE_LL_S_CA_INIT ((uint64_t)0 << 32) +#define BLE_LL_S_HDCA_INIT ((uint64_t)0 << 33) +#define BLE_LL_S_LDCA_INIT ((uint64_t)0 << 34) #define BLE_LL_S_CA_CENTRAL ((uint64_t)0 << 35) #define BLE_LL_S_HDCA_CENTRAL ((uint64_t)0 << 36) #define BLE_LL_S_LDCA_CENTRAL ((uint64_t)0 << 37) From 3f1e0252d0af6c162d98d73f2a93a3576a91674d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 24 Aug 2022 16:11:54 +0200 Subject: [PATCH 0496/1333] nimble/ll: Fix Read Local Supported Commands Support for LE Periodic Advertising Set Info Transfer command was incorrectlt reported for builds without broadcaster support. --- nimble/controller/src/ble_ll_supp_cmd.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_supp_cmd.c b/nimble/controller/src/ble_ll_supp_cmd.c index 1c408fbff5..a0493a46a7 100644 --- a/nimble/controller/src/ble_ll_supp_cmd.c +++ b/nimble/controller/src/ble_ll_supp_cmd.c @@ -480,16 +480,33 @@ ) /* Octet 40 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_VERSION) >= 51 && \ - MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_VERSION) >= 51 +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) #define BLE_SUPP_CMD_LE_PADV_RECV_ENABLE (1 << 5) #else #define BLE_SUPP_CMD_LE_PADV_RECV_ENABLE (0 << 5) #endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) #define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER (1 << 6) +#else +#define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER (0 << 6) +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) #define BLE_SUPP_CMD_LE_PADV_SET_INFO_TRANSFER (1 << 7) #else +#define BLE_SUPP_CMD_LE_PADV_SET_INFO_TRANSFER (0 << 7) +#endif + +#else +#define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER (0 << 6) +#define BLE_SUPP_CMD_LE_PADV_SET_INFO_TRANSFER (0 << 7) +#endif + +#else +#define BLE_SUPP_CMD_LE_PADV_RECV_ENABLE (0 << 5) #define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER (0 << 6) #define BLE_SUPP_CMD_LE_PADV_SET_INFO_TRANSFER (0 << 7) #endif From 1a27fe6494caa299ab67cd0e9a05fa7ad439c47a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 12 Aug 2022 13:35:14 +0200 Subject: [PATCH 0497/1333] nimble/ll/css: Add vs event to indicate slot change If hci_vs support is enabled for CSS, an event will be sent every time slot chanes for a connection. --- .../include/controller/ble_ll_ctrl.h | 5 +++ nimble/controller/src/ble_ll_conn.c | 5 +++ nimble/controller/src/ble_ll_hci_ev.c | 32 +++++++++++++++++-- nimble/include/nimble/hci_common.h | 11 +++++-- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index 379960ecea..6e7ad13d9f 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -350,6 +350,11 @@ void ble_ll_hci_ev_sca_update(struct ble_ll_conn_sm *connsm, void ble_ll_hci_ev_subrate_change(struct ble_ll_conn_sm *connsm, uint8_t status); #endif +#if MYNEWT_VAL(BLE_LL_HCI_VS_CONN_STRICT_SCHED) +void ble_ll_hci_ev_send_vs_css_slot_changed(uint16_t conn_handle, + uint16_t slot_idx); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 2a8c0c05bb..b625a0e354 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2496,6 +2496,11 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) ble_ll_sched_css_set_conn_anchor(connsm); anchor_calc_for_css = 0; } + +#if MYNEWT_VAL(BLE_LL_HCI_VS_CONN_STRICT_SCHED) + ble_ll_hci_ev_send_vs_css_slot_changed(connsm->conn_handle, + connsm->css_slot_idx); +#endif } #endif diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index 6da2545c03..b0d9fa077f 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -523,10 +523,36 @@ ble_ll_hci_ev_subrate_change(struct ble_ll_conn_sm *connsm, uint8_t status) } #endif +#if MYNEWT_VAL(BLE_LL_HCI_VS_CONN_STRICT_SCHED) +void +ble_ll_hci_ev_send_vs_css_slot_changed(uint16_t conn_handle, uint16_t slot_idx) +{ + struct ble_hci_ev_vs_css_slot_changed *ev; + struct ble_hci_ev_vs *ev_vs; + struct ble_hci_ev *hci_ev; + + hci_ev = ble_transport_alloc_evt(0); + if (!hci_ev) { + return; + + } + + hci_ev->opcode = BLE_HCI_EVCODE_VS; + hci_ev->length = sizeof(*ev_vs) + sizeof(*ev); + ev_vs = (void *)hci_ev->data; + ev_vs->id = BLE_HCI_VS_SUBEV_ID_CSS_SLOT_CHANGED; + ev = (void *)ev_vs->data; + ev->conn_handle = htole16(conn_handle); + ev->slot_idx = htole16(slot_idx); + + ble_ll_hci_event_send(hci_ev); +} +#endif + void ble_ll_hci_ev_send_vs_assert(const char *file, uint32_t line) { - struct ble_hci_ev_vs_debug *ev; + struct ble_hci_ev_vs *ev; struct ble_hci_ev *hci_ev; unsigned int str_len; bool skip = true; @@ -541,12 +567,12 @@ ble_ll_hci_ev_send_vs_assert(const char *file, uint32_t line) hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { - hci_ev->opcode = BLE_HCI_EVCODE_VS_DEBUG; + hci_ev->opcode = BLE_HCI_EVCODE_VS; hci_ev->length = sizeof(*ev); ev = (void *) hci_ev->data; /* Debug id for future use */ - ev->id = 0x00; + ev->id = BLE_HCI_VS_SUBEV_ID_ASSERT; /* snprintf would be nicer but this is heavy on flash * len = snprintf((char *) ev->data, max_len, "%s:%u", file, line); diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 40602d7b3e..b690eeb24c 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1554,12 +1554,19 @@ struct ble_hci_ev_auth_pyld_tmo { #define BLE_HCI_EVCODE_SAM_STATUS_CHG (0x58) -#define BLE_HCI_EVCODE_VS_DEBUG (0xFF) -struct ble_hci_ev_vs_debug { +#define BLE_HCI_EVCODE_VS (0xff) +struct ble_hci_ev_vs { uint8_t id; uint8_t data[0]; } __attribute__((packed)); +#define BLE_HCI_VS_SUBEV_ID_ASSERT (0x01) +#define BLE_HCI_VS_SUBEV_ID_CSS_SLOT_CHANGED (0x02) +struct ble_hci_ev_vs_css_slot_changed { + uint16_t conn_handle; + uint16_t slot_idx; +}; + /* LE sub-event codes */ #define BLE_HCI_LE_SUBEV_CONN_COMPLETE (0x01) struct ble_hci_ev_le_subev_conn_complete { From 6d88641ab25a28447290d4509315f393b4741a00 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 19 Aug 2022 14:48:34 +0200 Subject: [PATCH 0498/1333] nimble/ll/css: Add HCI vs command to read current slot for connection --- nimble/controller/src/ble_ll_hci_vs.c | 33 +++++++++++++++++++++++++++ nimble/include/nimble/hci_common.h | 10 ++++++++ 2 files changed, 43 insertions(+) diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index 8effae5422..7aa2e8d19c 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -268,6 +268,37 @@ ble_ll_hci_vs_css_set_conn_slot(const uint8_t *cmdbuf, uint8_t cmdlen, return BLE_ERR_SUCCESS; } +static int +ble_ll_hci_vs_css_read_conn_slot(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_vs_css_read_conn_slot_cp *cmd = (const void *)cmdbuf; + struct ble_hci_vs_css_read_conn_slot_rp *rsp = (void *)rspbuf; + struct ble_ll_conn_sm *connsm; + uint16_t conn_handle; + + if (cmdlen != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (!ble_ll_sched_css_is_enabled()) { + return BLE_ERR_CMD_DISALLOWED; + } + + conn_handle = le16toh(cmd->conn_handle); + connsm = ble_ll_conn_find_by_handle(conn_handle); + if (!connsm) { + return BLE_ERR_UNK_CONN_ID; + } + + *rsplen = sizeof(*rsp); + rsp->opcode = cmd->opcode; + rsp->conn_handle = cmd->conn_handle; + rsp->slot_idx = htole16(connsm->css_slot_idx); + + return BLE_ERR_SUCCESS; +} + static int ble_ll_hci_vs_css(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen) @@ -291,6 +322,8 @@ ble_ll_hci_vs_css(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, return ble_ll_hci_vs_css_set_next_slot(cmdbuf, cmdlen, rspbuf, rsplen); case BLE_HCI_VS_CSS_OP_SET_CONN_SLOT: return ble_ll_hci_vs_css_set_conn_slot(cmdbuf, cmdlen, rspbuf, rsplen); + case BLE_HCI_VS_CSS_OP_READ_CONN_SLOT: + return ble_ll_hci_vs_css_read_conn_slot(cmdbuf, cmdlen, rspbuf, rsplen); } return BLE_ERR_INV_HCI_CMD_PARMS; diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index b690eeb24c..a46158435f 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1168,6 +1168,16 @@ struct ble_hci_vs_css_set_conn_slot_cp { uint16_t conn_handle; uint16_t slot_idx; } __attribute__((packed)); +#define BLE_HCI_VS_CSS_OP_READ_CONN_SLOT 0x05 +struct ble_hci_vs_css_read_conn_slot_cp { + uint8_t opcode; + uint16_t conn_handle; +} __attribute__((packed)); +struct ble_hci_vs_css_read_conn_slot_rp { + uint8_t opcode; + uint16_t conn_handle; + uint16_t slot_idx; +} __attribute__((packed)); /* Command Specific Definitions */ /* --- Set controller to host flow control (OGF 0x03, OCF 0x0031) --- */ From 5098c2889e894521d2008c2a036c687335e4fd79 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 23 Aug 2022 16:23:54 +0200 Subject: [PATCH 0499/1333] nimble/ll/css: Add separate vs hci commands for css. --- nimble/controller/src/ble_ll_hci_vs.c | 71 ++++++++++----------------- nimble/include/nimble/hci_common.h | 20 ++------ 2 files changed, 31 insertions(+), 60 deletions(-) diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index 7aa2e8d19c..d003465008 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -138,7 +138,7 @@ ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, #if MYNEWT_VAL(BLE_LL_HCI_VS_CONN_STRICT_SCHED) #if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) static int -ble_ll_hci_vs_css_configure(const uint8_t *cmdbuf, uint8_t cmdlen, +ble_ll_hci_vs_css_configure(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen) { const struct ble_hci_vs_css_configure_cp *cmd = (const void *)cmdbuf; @@ -149,9 +149,8 @@ ble_ll_hci_vs_css_configure(const uint8_t *cmdbuf, uint8_t cmdlen, return BLE_ERR_INV_HCI_CMD_PARMS; } - if (ble_ll_sched_css_is_enabled() && - !SLIST_EMPTY(&g_ble_ll_conn_css_list)) { - return BLE_ERR_CTLR_BUSY; + if (ble_ll_sched_css_is_enabled()) { + return BLE_ERR_CMD_DISALLOWED; } slot_us = le32toh(cmd->slot_us); @@ -172,7 +171,7 @@ ble_ll_hci_vs_css_configure(const uint8_t *cmdbuf, uint8_t cmdlen, #endif static int -ble_ll_hci_vs_css_enable(const uint8_t *cmdbuf, uint8_t cmdlen, +ble_ll_hci_vs_css_enable(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen) { const struct ble_hci_vs_css_enable_cp *cmd = (const void *)cmdbuf; @@ -182,7 +181,7 @@ ble_ll_hci_vs_css_enable(const uint8_t *cmdbuf, uint8_t cmdlen, } if (!SLIST_EMPTY(&g_ble_ll_conn_active_list)) { - return BLE_ERR_CTLR_BUSY; + return BLE_ERR_CMD_DISALLOWED; } if (cmd->enable & 0xfe) { @@ -195,8 +194,9 @@ ble_ll_hci_vs_css_enable(const uint8_t *cmdbuf, uint8_t cmdlen, } static int -ble_ll_hci_vs_css_set_next_slot(const uint8_t *cmdbuf, uint8_t cmdlen, - uint8_t *rspbuf, uint8_t *rsplen) +ble_ll_hci_vs_css_set_next_slot(uint16_t ocf, const uint8_t *cmdbuf, + uint8_t cmdlen, uint8_t *rspbuf, + uint8_t *rsplen) { const struct ble_hci_vs_css_set_next_slot_cp *cmd = (const void *)cmdbuf; uint16_t slot_idx; @@ -221,8 +221,9 @@ ble_ll_hci_vs_css_set_next_slot(const uint8_t *cmdbuf, uint8_t cmdlen, } static int -ble_ll_hci_vs_css_set_conn_slot(const uint8_t *cmdbuf, uint8_t cmdlen, - uint8_t *rspbuf, uint8_t *rsplen) +ble_ll_hci_vs_css_set_conn_slot(uint16_t ocf, const uint8_t *cmdbuf, + uint8_t cmdlen, uint8_t *rspbuf, + uint8_t *rsplen) { const struct ble_hci_vs_css_set_conn_slot_cp *cmd = (const void *)cmdbuf; struct ble_ll_conn_sm *connsm; @@ -269,8 +270,9 @@ ble_ll_hci_vs_css_set_conn_slot(const uint8_t *cmdbuf, uint8_t cmdlen, } static int -ble_ll_hci_vs_css_read_conn_slot(const uint8_t *cmdbuf, uint8_t cmdlen, - uint8_t *rspbuf, uint8_t *rsplen) +ble_ll_hci_vs_css_read_conn_slot(uint16_t ocf, const uint8_t *cmdbuf, + uint8_t cmdlen, uint8_t *rspbuf, + uint8_t *rsplen) { const struct ble_hci_vs_css_read_conn_slot_cp *cmd = (const void *)cmdbuf; struct ble_hci_vs_css_read_conn_slot_rp *rsp = (void *)rspbuf; @@ -292,42 +294,11 @@ ble_ll_hci_vs_css_read_conn_slot(const uint8_t *cmdbuf, uint8_t cmdlen, } *rsplen = sizeof(*rsp); - rsp->opcode = cmd->opcode; rsp->conn_handle = cmd->conn_handle; rsp->slot_idx = htole16(connsm->css_slot_idx); return BLE_ERR_SUCCESS; } - -static int -ble_ll_hci_vs_css(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, - uint8_t *rspbuf, uint8_t *rsplen) -{ - const struct ble_hci_vs_css_cp *cmd = (const void *)cmdbuf; - - if (cmdlen < sizeof(*cmd)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - *rsplen = 0; - - switch (cmd->opcode) { -#if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) - case BLE_HCI_VS_CSS_OP_CONFIGURE: - return ble_ll_hci_vs_css_configure(cmdbuf, cmdlen, rspbuf, rsplen); -#endif - case BLE_HCI_VS_CSS_OP_ENABLE: - return ble_ll_hci_vs_css_enable(cmdbuf, cmdlen, rspbuf, rsplen); - case BLE_HCI_VS_CSS_OP_SET_NEXT_SLOT: - return ble_ll_hci_vs_css_set_next_slot(cmdbuf, cmdlen, rspbuf, rsplen); - case BLE_HCI_VS_CSS_OP_SET_CONN_SLOT: - return ble_ll_hci_vs_css_set_conn_slot(cmdbuf, cmdlen, rspbuf, rsplen); - case BLE_HCI_VS_CSS_OP_READ_CONN_SLOT: - return ble_ll_hci_vs_css_read_conn_slot(cmdbuf, cmdlen, rspbuf, rsplen); - } - - return BLE_ERR_INV_HCI_CMD_PARMS; -} #endif static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { @@ -336,8 +307,18 @@ static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_TX_PWR, ble_ll_hci_vs_set_tx_power), #if MYNEWT_VAL(BLE_LL_HCI_VS_CONN_STRICT_SCHED) - BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_CSS, - ble_ll_hci_vs_css), +#if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) + BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_CSS_CONFIGURE, + ble_ll_hci_vs_css_configure), +#endif + BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_CSS_ENABLE, + ble_ll_hci_vs_css_enable), + BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_CSS_SET_NEXT_SLOT, + ble_ll_hci_vs_css_set_next_slot), + BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_CSS_SET_CONN_SLOT, + ble_ll_hci_vs_css_set_conn_slot), + BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_CSS_READ_CONN_SLOT, + ble_ll_hci_vs_css_read_conn_slot), #endif }; diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index a46158435f..b83c35aa12 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1142,39 +1142,29 @@ struct ble_hci_vs_set_tx_pwr_rp { int8_t tx_power; } __attribute__((packed)); -#define BLE_HCI_OCF_VS_CSS (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0003)) -struct ble_hci_vs_css_cp { - uint8_t opcode; -} __attribute__((packed)); -#define BLE_HCI_VS_CSS_OP_CONFIGURE 0x01 +#define BLE_HCI_OCF_VS_CSS_CONFIGURE (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0003)) struct ble_hci_vs_css_configure_cp { - uint8_t opcode; uint32_t slot_us; uint32_t period_slots; } __attribute__((packed)); -#define BLE_HCI_VS_CSS_OP_ENABLE 0x02 +#define BLE_HCI_OCF_VS_CSS_ENABLE (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0004)) struct ble_hci_vs_css_enable_cp { - uint8_t opcode; uint8_t enable; } __attribute__((packed)); -#define BLE_HCI_VS_CSS_OP_SET_NEXT_SLOT 0x03 +#define BLE_HCI_OCF_VS_CSS_SET_NEXT_SLOT (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0005)) struct ble_hci_vs_css_set_next_slot_cp { - uint8_t opcode; uint16_t slot_idx; } __attribute__((packed)); -#define BLE_HCI_VS_CSS_OP_SET_CONN_SLOT 0x04 +#define BLE_HCI_OCF_VS_CSS_SET_CONN_SLOT (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0006)) struct ble_hci_vs_css_set_conn_slot_cp { - uint8_t opcode; uint16_t conn_handle; uint16_t slot_idx; } __attribute__((packed)); -#define BLE_HCI_VS_CSS_OP_READ_CONN_SLOT 0x05 +#define BLE_HCI_OCF_VS_CSS_READ_CONN_SLOT (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0007)) struct ble_hci_vs_css_read_conn_slot_cp { - uint8_t opcode; uint16_t conn_handle; } __attribute__((packed)); struct ble_hci_vs_css_read_conn_slot_rp { - uint8_t opcode; uint16_t conn_handle; uint16_t slot_idx; } __attribute__((packed)); From a7d5ac1148b07fc0458da71c3ebe7cd9e8264507 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 30 Aug 2022 10:41:13 +0200 Subject: [PATCH 0500/1333] babblesim: Fix build with latest BabbleSim irq_sources.h was removed, not needed. --- babblesim/core/src/cmsis.c | 1 - babblesim/core/src/irq_handler.c | 1 - 2 files changed, 2 deletions(-) diff --git a/babblesim/core/src/cmsis.c b/babblesim/core/src/cmsis.c index 9beb329091..1ac6b2414c 100644 --- a/babblesim/core/src/cmsis.c +++ b/babblesim/core/src/cmsis.c @@ -9,7 +9,6 @@ #include #include "irq_ctrl.h" -#include "irq_sources.h" #include #include "cmsis.h" #include "os/sim.h" diff --git a/babblesim/core/src/irq_handler.c b/babblesim/core/src/irq_handler.c index f72aaf2411..d29797500d 100644 --- a/babblesim/core/src/irq_handler.c +++ b/babblesim/core/src/irq_handler.c @@ -8,7 +8,6 @@ #include #include "irq_ctrl.h" -#include "irq_sources.h" #include "os/sim.h" static int currently_running_irq = -1; From 5a7f7df964dde786546bf194dcb0035ff778c6e6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 30 Aug 2022 10:41:51 +0200 Subject: [PATCH 0501/1333] babblesim: Add syscfg def indicating BabbleSim bsp Useful for syscfg variants --- babblesim/hw/bsp/nrf52_bsim/syscfg.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/babblesim/hw/bsp/nrf52_bsim/syscfg.yml b/babblesim/hw/bsp/nrf52_bsim/syscfg.yml index c73106f326..e5733dd521 100644 --- a/babblesim/hw/bsp/nrf52_bsim/syscfg.yml +++ b/babblesim/hw/bsp/nrf52_bsim/syscfg.yml @@ -17,6 +17,7 @@ # syscfg.defs: + BABBLESIM: 1 BSP_NRF52: description: 'Set to indicate that BSP has NRF52' value: 1 From 87825c238e8cf48d1b43379b298cd6344ce83b46 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 23 Aug 2022 00:07:27 +0200 Subject: [PATCH 0502/1333] nimble/ll: Check advertising data length This adds check for advertising/scan response data length when adding data to advertising instance or changing instance parameters. This fixes HCI/DDI/BI-62-C. --- nimble/controller/src/ble_ll_adv.c | 312 ++++++++++++++++++++--------- 1 file changed, 215 insertions(+), 97 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 0ffa1afc4d..7e672fd12b 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1357,117 +1357,173 @@ ble_ll_adv_aux_scannable_pdu_payload_len(struct ble_ll_adv_sm *advsm) return len; } -static void -ble_ll_adv_aux_calculate(struct ble_ll_adv_sm *advsm, - struct ble_ll_adv_aux *aux, uint16_t aux_data_offset) +static uint16_t +ble_ll_adv_aux_calculate_payload(struct ble_ll_adv_sm *advsm, uint16_t props, + struct os_mbuf *data, uint32_t data_offset, + uint8_t *data_len_o, uint8_t *ext_hdr_flags_o) { - uint16_t rem_aux_data_len; - uint8_t hdr_len; + uint16_t rem_data_len; + uint8_t data_len; + uint8_t ext_hdr_flags; + uint8_t ext_hdr_len; bool chainable; + bool first_pdu; - BLE_LL_ASSERT(!aux->sch.enqueued); - BLE_LL_ASSERT((AUX_DATA_LEN(advsm) > aux_data_offset) || - (AUX_DATA_LEN(advsm) == 0 && aux_data_offset == 0)); - - aux->aux_data_offset = aux_data_offset; - aux->aux_data_len = 0; - aux->payload_len = 0; - aux->ext_hdr = 0; + /* Note: advsm shall only be used to check if periodic advertising is + * enabled, other parameters in advsm may have different values than + * those we want to check (e.g. when reconfiguring instance). + */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) - aux->chan = ble_ll_utils_dci_csa2(advsm->event_cntr++, - advsm->channel_id, - g_ble_ll_data.chan_map_num_used, - g_ble_ll_data.chan_map); -#else - aux->chan = ble_ll_utils_remapped_channel(ble_ll_rand() % BLE_PHY_NUM_DATA_CHANS, - g_ble_ll_data.chan_map); -#endif + rem_data_len = (data ? OS_MBUF_PKTLEN(data) : 0) - data_offset; + BLE_LL_ASSERT((int16_t)rem_data_len >= 0); - rem_aux_data_len = AUX_DATA_LEN(advsm) - aux_data_offset; - chainable = !(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE); + first_pdu = (data_offset == 0); + chainable = !(props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE); - hdr_len = BLE_LL_EXT_ADV_HDR_LEN; + ext_hdr_flags = 0; + ext_hdr_len = BLE_LL_EXT_ADV_HDR_LEN; - if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE)) { - /* ADI */ - aux->ext_hdr |= (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT); - hdr_len += BLE_LL_EXT_ADV_DATA_INFO_SIZE; + /* ADI for anything but scannable */ + if (!(props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE)) { + ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT); + ext_hdr_len += BLE_LL_EXT_ADV_DATA_INFO_SIZE; } - /* AdvA for 1st PDU in chain (i.e. AUX_ADV_IND or AUX_SCAN_RSP) */ - if (aux_data_offset == 0 && - !(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV)) { - aux->ext_hdr |= (1 << BLE_LL_EXT_ADV_ADVA_BIT); - hdr_len += BLE_LL_EXT_ADV_ADVA_SIZE; + /* AdvA in 1st PDU, except for anonymous */ + if (first_pdu && + !(props & BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV)) { + ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_ADVA_BIT); + ext_hdr_len += BLE_LL_EXT_ADV_ADVA_SIZE; } - /* Note: this function does not calculate AUX_ADV_IND when advertising is - * scannable. Instead it is calculated in ble_ll_adv_aux_schedule_first(). + /* TargetA in 1st PDU, if directed * - * However this function calculates length of AUX_SCAN_RSP and according - * to BT 5.0 Vol 6 Part B, 2.3.2.3, TargetA shall not be include there. - * - * This is why TargetA is added to all directed advertising here unless it - * is scannable one. - * - * Note. TargetA shall not be also in AUX_CHAIN_IND + * Note that for scannable this calculates AUX_SCAN_RSP which shall not + * include TargetA (see: Core 5.3, Vol 6, Part B, 2.3.2.3). For scannable + * TargetA is included in AUX_ADV_IND which is in that case calculated in + * ble_ll_adv_aux_schedule_first(). */ - if (aux_data_offset == 0 && - (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) && - !(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE)) { - aux->ext_hdr |= (1 << BLE_LL_EXT_ADV_TARGETA_BIT); - hdr_len += BLE_LL_EXT_ADV_TARGETA_SIZE; + if (first_pdu && + (props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) && + !(props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE)) { + ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_TARGETA_BIT); + ext_hdr_len += BLE_LL_EXT_ADV_TARGETA_SIZE; } - /* TxPower if configured. - * Note: TxPower should not be be present in AUX_CHAIN_IND - */ - if (aux_data_offset == 0 && - (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR)) { - aux->ext_hdr |= (1 << BLE_LL_EXT_ADV_TX_POWER_BIT); - hdr_len += BLE_LL_EXT_ADV_TX_POWER_SIZE; + /* TxPower in 1st PDU, if configured */ + if (first_pdu && + (props & BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR)) { + ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_TX_POWER_BIT); + ext_hdr_len += BLE_LL_EXT_ADV_TX_POWER_SIZE; } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) - /* SyncInfo for 1st PDU in chain (i.e. AUX_ADV_IND only) if periodic - * advertising is enabled - */ - if (aux_data_offset == 0 && advsm->periodic_adv_active) { - aux->ext_hdr |= (1 << BLE_LL_EXT_ADV_SYNC_INFO_BIT); - hdr_len += BLE_LL_EXT_ADV_SYNC_INFO_SIZE; + /* SyncInfo in 1st PDU, if periodic advertising is enabled */ + if (first_pdu && advsm->periodic_adv_active) { + ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_SYNC_INFO_BIT); + ext_hdr_len += BLE_LL_EXT_ADV_SYNC_INFO_SIZE; } #endif - /* if we have any fields in ext header we need to add flags, note that Aux - * PTR is handled later and it will account for flags if needed + /* Flags, if any field is present in header + * + * Note that this does not account for AuxPtr which is added later if + * remaining data does not fit in single PDU. */ - if (aux->ext_hdr) { - hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE; + if (ext_hdr_flags) { + ext_hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE; } - /* AdvData always */ - aux->aux_data_len = min(BLE_LL_MAX_PAYLOAD_LEN - hdr_len, rem_aux_data_len); + /* AdvData */ + data_len = min(BLE_LL_MAX_PAYLOAD_LEN - ext_hdr_len, rem_data_len); /* AuxPtr if there are more AdvData remaining that we can fit here */ - if (chainable && (rem_aux_data_len > aux->aux_data_len)) { - /* adjust for flags that needs to be added if AuxPtr is only field - * in Extended Header - */ - if (!aux->ext_hdr) { - hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE; - aux->aux_data_len -= BLE_LL_EXT_ADV_FLAGS_SIZE; - } + if (chainable && (rem_data_len > data_len)) { + /* Add flags if not already added */ + if (!ext_hdr_flags) { + ext_hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE; + data_len -= BLE_LL_EXT_ADV_FLAGS_SIZE; + } - aux->ext_hdr |= (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT); - hdr_len += BLE_LL_EXT_ADV_AUX_PTR_SIZE; - aux->aux_data_len -= BLE_LL_EXT_ADV_AUX_PTR_SIZE; + ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT); + ext_hdr_len += BLE_LL_EXT_ADV_AUX_PTR_SIZE; - /* PDU payload should be full if chained */ - BLE_LL_ASSERT(hdr_len + aux->aux_data_len == BLE_LL_MAX_PAYLOAD_LEN); + data_len -= BLE_LL_EXT_ADV_AUX_PTR_SIZE; + + /* PDU payload should be full if adding AuxPtr */ + BLE_LL_ASSERT(ext_hdr_len + data_len == BLE_LL_MAX_PAYLOAD_LEN); } - aux->payload_len = hdr_len + aux->aux_data_len; + *data_len_o = data_len; + *ext_hdr_flags_o = ext_hdr_flags; + + return ext_hdr_len + data_len; +} + +static void +ble_ll_adv_aux_calculate(struct ble_ll_adv_sm *advsm, + struct ble_ll_adv_aux *aux, uint16_t data_offset) +{ + BLE_LL_ASSERT(!aux->sch.enqueued); + BLE_LL_ASSERT((AUX_DATA_LEN(advsm) > data_offset) || + (AUX_DATA_LEN(advsm) == 0 && data_offset == 0)); + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) + aux->chan = ble_ll_utils_dci_csa2(advsm->event_cntr++, + advsm->channel_id, + g_ble_ll_data.chan_map_num_used, + g_ble_ll_data.chan_map); +#else + aux->chan = ble_ll_utils_remapped_channel(ble_ll_rand() % BLE_PHY_NUM_DATA_CHANS, + g_ble_ll_data.chan_map); +#endif + + aux->aux_data_offset = data_offset; + aux->payload_len = ble_ll_adv_aux_calculate_payload(advsm, advsm->props, + *advsm->aux_data, + data_offset, + &aux->aux_data_len, + &aux->ext_hdr); +} + +static bool +ble_ll_adv_aux_check_data_itvl(struct ble_ll_adv_sm *advsm, uint16_t props, + uint8_t pri_phy, uint8_t sec_phy, + struct os_mbuf *data, uint32_t interval_us) +{ + uint32_t max_usecs; + uint16_t data_offset; + uint16_t pdu_len; + uint8_t data_len; + uint8_t ext_hdr_flags; + + /* FIXME: + * We should include PDUs on primary channel when calculating advertising + * event duration, but the actual time varies a bit in our case due to + * scheduling. For now let's assume we always schedule all PDUs 300us apart + * and we use shortest possible payload (ADI+AuxPtr, no AdvA). + * + * Note that calculations below do not take channel map and max skip into + * account, but we do not support max skip anyway for now. + */ + + max_usecs = 3 * (ble_ll_pdu_tx_time_get(7, pri_phy) + 300) + + BLE_LL_MAFS + MYNEWT_VAL(BLE_LL_SCHED_AUX_MAFS_DELAY); + + data_offset = 0; + + do { + pdu_len = ble_ll_adv_aux_calculate_payload(advsm, props, data, data_offset, + &data_len, &ext_hdr_flags); + + max_usecs += ble_ll_pdu_tx_time_get(pdu_len, sec_phy); + max_usecs += BLE_LL_MAFS + MYNEWT_VAL(BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY); + + data_offset += data_len; + + } while (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)); + + return max_usecs < interval_us; } static void @@ -1485,8 +1541,8 @@ ble_ll_adv_aux_schedule_next(struct ble_ll_adv_sm *advsm) struct ble_ll_adv_aux *aux; struct ble_ll_adv_aux *aux_next; struct ble_ll_sched_item *sch; - uint16_t rem_aux_data_len; - uint16_t next_aux_data_offset; + uint16_t rem_data_len; + uint16_t next_data_offset; uint32_t max_usecs; BLE_LL_ASSERT(advsm->aux_active); @@ -1512,14 +1568,14 @@ ble_ll_adv_aux_schedule_next(struct ble_ll_adv_sm *advsm) return; } - next_aux_data_offset = aux->aux_data_offset + aux->aux_data_len; + next_data_offset = aux->aux_data_offset + aux->aux_data_len; - BLE_LL_ASSERT(AUX_DATA_LEN(advsm) >= next_aux_data_offset); + BLE_LL_ASSERT(AUX_DATA_LEN(advsm) >= next_data_offset); - rem_aux_data_len = AUX_DATA_LEN(advsm) - next_aux_data_offset; - BLE_LL_ASSERT(rem_aux_data_len > 0); + rem_data_len = AUX_DATA_LEN(advsm) - next_data_offset; + BLE_LL_ASSERT(rem_data_len > 0); - ble_ll_adv_aux_calculate(advsm, aux_next, next_aux_data_offset); + ble_ll_adv_aux_calculate(advsm, aux_next, next_data_offset); max_usecs = ble_ll_pdu_tx_time_get(aux_next->payload_len, advsm->sec_phy); aux_next->start_time = aux->sch.end_time + @@ -1738,6 +1794,7 @@ ble_ll_adv_set_adv_params(const uint8_t *cmdbuf, uint8_t len) uint8_t adv_filter_policy; uint16_t adv_itvl_min; uint16_t adv_itvl_max; + uint32_t adv_itvl_usecs; uint16_t props; if (len != sizeof(*cmd)) { @@ -1833,6 +1890,14 @@ ble_ll_adv_set_adv_params(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } + /* Determine the advertising interval we will use */ + if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) { + /* Set it to max. allowed for high duty cycle advertising */ + adv_itvl_usecs = BLE_LL_ADV_PDU_ITVL_HD_MS_MAX; + } else { + adv_itvl_usecs = adv_itvl_max * BLE_LL_ADV_ITVL; + } + /* Fill out rest of advertising state machine */ advsm->own_addr_type = cmd->own_addr_type; advsm->peer_addr_type = cmd->peer_addr_type; @@ -1840,6 +1905,7 @@ ble_ll_adv_set_adv_params(const uint8_t *cmdbuf, uint8_t len) advsm->adv_chanmask = cmd->chan_map; advsm->adv_itvl_min = adv_itvl_min; advsm->adv_itvl_max = adv_itvl_max; + advsm->adv_itvl_usecs = adv_itvl_usecs; advsm->props = props; return 0; @@ -2712,15 +2778,6 @@ ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm) (access_addr & 0x0000ffff); #endif - /* Determine the advertising interval we will use */ - if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) { - /* Set it to max. allowed for high duty cycle advertising */ - advsm->adv_itvl_usecs = BLE_LL_ADV_PDU_ITVL_HD_MS_MAX; - } else { - advsm->adv_itvl_usecs = (uint32_t)advsm->adv_itvl_max; - advsm->adv_itvl_usecs *= BLE_LL_ADV_ITVL; - } - /* Set first advertising channel */ adv_chan = ble_ll_adv_first_chan(advsm); advsm->adv_chan = adv_chan; @@ -2991,6 +3048,19 @@ ble_ll_adv_set_scan_rsp_data(const uint8_t *data, uint8_t datalen, if (!advsm->new_scan_rsp_data) { return BLE_ERR_MEM_CAPACITY; } + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) && + !ble_ll_adv_aux_check_data_itvl(advsm, advsm->props, advsm->pri_phy, + advsm->sec_phy, + advsm->new_scan_rsp_data, + advsm->adv_itvl_usecs)) { + os_mbuf_free_chain(advsm->new_scan_rsp_data); + advsm->new_scan_rsp_data = NULL; + return BLE_ERR_PACKET_TOO_LONG; + } +#endif + ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_NEW_SCAN_RSP_DATA); } else { ble_ll_adv_update_data_mbuf(&advsm->scan_rsp_data, new_data, @@ -3000,6 +3070,16 @@ ble_ll_adv_set_scan_rsp_data(const uint8_t *data, uint8_t datalen, } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) && + !ble_ll_adv_aux_check_data_itvl(advsm, advsm->props, advsm->pri_phy, + advsm->sec_phy, + advsm->scan_rsp_data, + advsm->adv_itvl_usecs)) { + os_mbuf_free_chain(advsm->scan_rsp_data); + advsm->scan_rsp_data = NULL; + return BLE_ERR_PACKET_TOO_LONG; + } + /* DID shall be updated when host provides new scan response data */ ble_ll_adv_update_did(advsm); #endif @@ -3133,6 +3213,18 @@ ble_ll_adv_set_adv_data(const uint8_t *data, uint8_t datalen, uint8_t instance, if (!advsm->new_adv_data) { return BLE_ERR_MEM_CAPACITY; } + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) && + !ble_ll_adv_aux_check_data_itvl(advsm, advsm->props, advsm->pri_phy, + advsm->sec_phy, advsm->new_adv_data, + advsm->adv_itvl_usecs)) { + os_mbuf_free_chain(advsm->new_adv_data); + advsm->new_adv_data = NULL; + return BLE_ERR_PACKET_TOO_LONG; + } +#endif + ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_NEW_ADV_DATA); } else { ble_ll_adv_update_data_mbuf(&advsm->adv_data, new_data, @@ -3142,6 +3234,15 @@ ble_ll_adv_set_adv_data(const uint8_t *data, uint8_t datalen, uint8_t instance, } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + if (!(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) && + !ble_ll_adv_aux_check_data_itvl(advsm, advsm->props, advsm->pri_phy, + advsm->sec_phy, advsm->adv_data, + advsm->adv_itvl_usecs)) { + os_mbuf_free_chain(advsm->adv_data); + advsm->adv_data = NULL; + return BLE_ERR_PACKET_TOO_LONG; + } + /* DID shall be updated when host provides new advertising data */ ble_ll_adv_update_did(advsm); #endif @@ -3230,6 +3331,7 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, struct ble_ll_adv_sm *advsm; uint32_t adv_itvl_min; uint32_t adv_itvl_max; + uint32_t adv_itvl_usecs; uint16_t props; int rc; @@ -3411,6 +3513,21 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, goto done; } + /* Determine the advertising interval we will use */ + if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) { + /* Set it to max. allowed for high duty cycle advertising */ + adv_itvl_usecs = BLE_LL_ADV_PDU_ITVL_HD_MS_MAX; + } else { + adv_itvl_usecs = adv_itvl_max * BLE_LL_ADV_ITVL; + } + + if (!ble_ll_adv_aux_check_data_itvl(advsm, props, cmd->pri_phy, cmd->sec_phy, + advsm->adv_data, adv_itvl_usecs) || + !ble_ll_adv_aux_check_data_itvl(advsm, props, cmd->pri_phy, cmd->sec_phy, + advsm->scan_rsp_data, adv_itvl_usecs)) { + return BLE_ERR_PACKET_TOO_LONG; + } + rc = BLE_ERR_SUCCESS; if (cmd->tx_power == 127) { @@ -3428,6 +3545,7 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, advsm->adv_chanmask = cmd->pri_chan_map; advsm->adv_itvl_min = adv_itvl_min; advsm->adv_itvl_max = adv_itvl_max; + advsm->adv_itvl_usecs = adv_itvl_usecs; advsm->pri_phy = cmd->pri_phy; advsm->sec_phy = cmd->sec_phy; /* Update SID only */ From 933445d6c9b87b21a204a4c65daea71239209e88 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 23 Aug 2022 00:50:30 +0200 Subject: [PATCH 0503/1333] nimble/ll: Remove min/max interval from advsm We don't use it anywhere, just need calculated interval. --- nimble/controller/src/ble_ll_adv.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 7e672fd12b..c2057f7063 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -106,8 +106,6 @@ struct ble_ll_adv_sm int8_t adv_txpwr; uint16_t flags; uint16_t props; - uint16_t adv_itvl_min; - uint16_t adv_itvl_max; uint32_t adv_itvl_usecs; uint32_t adv_event_start_time; uint32_t adv_pdu_start_time; @@ -1903,8 +1901,6 @@ ble_ll_adv_set_adv_params(const uint8_t *cmdbuf, uint8_t len) advsm->peer_addr_type = cmd->peer_addr_type; advsm->adv_filter_policy = adv_filter_policy; advsm->adv_chanmask = cmd->chan_map; - advsm->adv_itvl_min = adv_itvl_min; - advsm->adv_itvl_max = adv_itvl_max; advsm->adv_itvl_usecs = adv_itvl_usecs; advsm->props = props; @@ -3543,8 +3539,6 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, advsm->own_addr_type = cmd->own_addr_type; advsm->adv_filter_policy = cmd->filter_policy; advsm->adv_chanmask = cmd->pri_chan_map; - advsm->adv_itvl_min = adv_itvl_min; - advsm->adv_itvl_max = adv_itvl_max; advsm->adv_itvl_usecs = adv_itvl_usecs; advsm->pri_phy = cmd->pri_phy; advsm->sec_phy = cmd->sec_phy; @@ -5217,8 +5211,6 @@ ble_ll_adv_sm_init(struct ble_ll_adv_sm *advsm) { memset(advsm, 0, sizeof(struct ble_ll_adv_sm)); - advsm->adv_itvl_min = BLE_HCI_ADV_ITVL_DEF; - advsm->adv_itvl_max = BLE_HCI_ADV_ITVL_DEF; advsm->adv_chanmask = BLE_HCI_ADV_CHANMASK_DEF; /* Initialize advertising tx done event */ From e9e2ccfa8a22184ce54a3150229e3d12b3e954fc Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 23 Aug 2022 11:50:37 +0200 Subject: [PATCH 0504/1333] nimble/ll: Use syscfg val to reserve slot for aux scan Turns out we have syscfg val for aux scan payload, but we forgot to use it. --- nimble/controller/src/ble_ll_scan_aux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 56f1c528eb..ed69055b1c 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -756,7 +756,7 @@ ble_ll_scan_aux_sched(struct ble_ll_scan_aux_data *aux, uint32_t pdu_time, return -1; } - max_aux_time_us = ble_ll_pdu_tx_time_get(BLE_LL_MAX_PAYLOAD_LEN, + max_aux_time_us = ble_ll_pdu_tx_time_get(MYNEWT_VAL(BLE_LL_SCHED_SCAN_AUX_PDU_LEN), ble_ll_phy_to_phy_mode(aux->sec_phy, 0)); rc = ble_ll_sched_scan_aux(&aux->sch, pdu_time, pdu_time_rem, offset_us, From c9cbc3cb15828e0d03ac6e3df5693f39efc8b715 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 23 Aug 2022 15:40:08 +0200 Subject: [PATCH 0505/1333] nimble/ll: Adjust names in adv structs Skip aux and sync prefixes since it's quite obvious as those members are in aux and sync structs. --- nimble/controller/src/ble_ll_adv.c | 139 ++++++++++++++--------------- 1 file changed, 69 insertions(+), 70 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index c2057f7063..85500d5769 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -58,10 +58,10 @@ struct ble_ll_adv_aux { struct ble_ll_sched_item sch; uint32_t start_time; - uint16_t aux_data_offset; + uint16_t data_offset; uint8_t chan; - uint8_t ext_hdr; - uint8_t aux_data_len; + uint8_t ext_hdr_flags; + uint8_t data_len; uint8_t payload_len; }; @@ -69,10 +69,10 @@ struct ble_ll_adv_aux { struct ble_ll_adv_sync { struct ble_ll_sched_item sch; uint32_t start_time; - uint16_t sync_data_offset; + uint16_t data_offset; uint8_t chan; - uint8_t ext_hdr; - uint8_t sync_data_len; + uint8_t ext_hdr_flags; + uint8_t data_len; uint8_t payload_len; }; @@ -732,17 +732,17 @@ ble_ll_adv_aux_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) adv_mode |= BLE_LL_EXT_ADV_MODE_CONN; } - ext_hdr_len = aux->payload_len - BLE_LL_EXT_ADV_HDR_LEN - aux->aux_data_len; + ext_hdr_len = aux->payload_len - BLE_LL_EXT_ADV_HDR_LEN - aux->data_len; dptr[0] = (adv_mode << 6) | ext_hdr_len; dptr += 1; /* only put flags if needed */ - if (aux->ext_hdr) { - dptr[0] = aux->ext_hdr; + if (aux->ext_hdr_flags) { + dptr[0] = aux->ext_hdr_flags; dptr += 1; } - if (aux->ext_hdr & (1 << BLE_LL_EXT_ADV_ADVA_BIT)) { + if (aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_ADVA_BIT)) { /* Set TxAdd to random if needed. */ if (advsm->flags & BLE_LL_ADV_SM_FLAG_TX_ADD) { @@ -753,7 +753,7 @@ ble_ll_adv_aux_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) dptr += BLE_LL_EXT_ADV_ADVA_SIZE; } - if (aux->ext_hdr & (1 << BLE_LL_EXT_ADV_TARGETA_BIT)) { + if (aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_TARGETA_BIT)) { memcpy(dptr, advsm->initiator_addr, BLE_LL_EXT_ADV_TARGETA_SIZE); dptr += BLE_LL_EXT_ADV_TARGETA_SIZE; @@ -763,13 +763,13 @@ ble_ll_adv_aux_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) } } - if (aux->ext_hdr & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) { + if (aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) { dptr[0] = advsm->adi & 0x00ff; dptr[1] = advsm->adi >> 8; dptr += BLE_LL_EXT_ADV_DATA_INFO_SIZE; } - if (aux->ext_hdr & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { + if (aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { if (!AUX_NEXT(advsm)->sch.enqueued) { /* * Trim data here in case we do not have next aux scheduled. This @@ -791,20 +791,20 @@ ble_ll_adv_aux_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) - if (aux->ext_hdr & (1 << BLE_LL_EXT_ADV_SYNC_INFO_BIT)) { + if (aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_SYNC_INFO_BIT)) { ble_ll_adv_put_syncinfo(advsm, NULL, NULL, dptr); dptr += BLE_LL_EXT_ADV_SYNC_INFO_SIZE; } #endif - if (aux->ext_hdr & (1 << BLE_LL_EXT_ADV_TX_POWER_BIT)) { + if (aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_TX_POWER_BIT)) { dptr[0] = advsm->adv_txpwr + ble_ll_get_tx_pwr_compensation(); dptr += BLE_LL_EXT_ADV_TX_POWER_SIZE; } - if (aux->aux_data_len) { - os_mbuf_copydata(*advsm->aux_data, aux->aux_data_offset, - aux->aux_data_len, dptr); + if (aux->data_len) { + os_mbuf_copydata(*advsm->aux_data, aux->data_offset, + aux->data_len, dptr); } *hdr_byte = pdu_type; @@ -1476,12 +1476,12 @@ ble_ll_adv_aux_calculate(struct ble_ll_adv_sm *advsm, g_ble_ll_data.chan_map); #endif - aux->aux_data_offset = data_offset; + aux->data_offset = data_offset; aux->payload_len = ble_ll_adv_aux_calculate_payload(advsm, advsm->props, *advsm->aux_data, data_offset, - &aux->aux_data_len, - &aux->ext_hdr); + &aux->data_len, + &aux->ext_hdr_flags); } static bool @@ -1562,11 +1562,11 @@ ble_ll_adv_aux_schedule_next(struct ble_ll_adv_sm *advsm) * Do not schedule next aux if current aux does not have AuxPtr in extended * header as this means we do not need subsequent ADV_CHAIN_IND to be sent. */ - if (!(aux->ext_hdr & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT))) { + if (!(aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT))) { return; } - next_data_offset = aux->aux_data_offset + aux->aux_data_len; + next_data_offset = aux->data_offset + aux->data_len; BLE_LL_ASSERT(AUX_DATA_LEN(advsm) >= next_data_offset); @@ -2131,17 +2131,17 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) /* non-connectable and non-scannable */ adv_mode = 0; - ext_hdr_len = sync->payload_len - BLE_LL_EXT_ADV_HDR_LEN - sync->sync_data_len; + ext_hdr_len = sync->payload_len - BLE_LL_EXT_ADV_HDR_LEN - sync->data_len; dptr[0] = (adv_mode << 6) | ext_hdr_len; dptr += 1; /* only put flags if needed */ - if (sync->ext_hdr) { - dptr[0] = sync->ext_hdr; + if (sync->ext_hdr_flags) { + dptr[0] = sync->ext_hdr_flags; dptr += 1; } - if (sync->ext_hdr & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { + if (sync->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { if (!SYNC_NEXT(advsm)->sch.enqueued) { /* * Trim data here in case we do not have next sync scheduled. This @@ -2160,14 +2160,14 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) dptr += BLE_LL_EXT_ADV_AUX_PTR_SIZE; } - if (sync->ext_hdr & (1 << BLE_LL_EXT_ADV_TX_POWER_BIT)) { + if (sync->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_TX_POWER_BIT)) { dptr[0] = advsm->adv_txpwr + ble_ll_get_tx_pwr_compensation(); dptr += BLE_LL_EXT_ADV_TX_POWER_SIZE; } - if (sync->sync_data_len) { - os_mbuf_copydata(advsm->periodic_adv_data, sync->sync_data_offset, - sync->sync_data_len, dptr); + if (sync->data_len) { + os_mbuf_copydata(advsm->periodic_adv_data, sync->data_offset, + sync->data_len, dptr); } *hdr_byte = pdu_type; @@ -2291,34 +2291,33 @@ ble_ll_adv_sync_tx_start_cb(struct ble_ll_sched_item *sch) static void ble_ll_adv_sync_calculate(struct ble_ll_adv_sm *advsm, - struct ble_ll_adv_sync *sync, - uint16_t sync_data_offset, + struct ble_ll_adv_sync *sync, uint16_t data_offset, uint8_t chan) { - uint16_t rem_sync_data_len; - uint8_t hdr_len; + uint16_t rem_data_len; + uint8_t ext_hdr_len; BLE_LL_ASSERT(!sync->sch.enqueued); - BLE_LL_ASSERT((SYNC_DATA_LEN(advsm) > sync_data_offset) || - (SYNC_DATA_LEN(advsm) == 0 && sync_data_offset == 0)); + BLE_LL_ASSERT((SYNC_DATA_LEN(advsm) > data_offset) || + (SYNC_DATA_LEN(advsm) == 0 && data_offset == 0)); - sync->sync_data_offset = sync_data_offset; - sync->sync_data_len = 0; + sync->data_offset = data_offset; + sync->data_len = 0; sync->payload_len = 0; - sync->ext_hdr = 0; + sync->ext_hdr_flags = 0; sync->chan = chan; - rem_sync_data_len = SYNC_DATA_LEN(advsm) - sync_data_offset; + rem_data_len = SYNC_DATA_LEN(advsm) - data_offset; - hdr_len = BLE_LL_EXT_ADV_HDR_LEN; + ext_hdr_len = BLE_LL_EXT_ADV_HDR_LEN; /* TxPower if configured * Note: TxPower shall not be present in chain PDU for SYNC */ - if (sync_data_offset == 0 && + if (data_offset == 0 && (advsm->periodic_adv_props & BLE_HCI_LE_SET_PERIODIC_ADV_PROP_INC_TX_PWR)) { - sync->ext_hdr |= (1 << BLE_LL_EXT_ADV_TX_POWER_BIT); - hdr_len += BLE_LL_EXT_ADV_TX_POWER_SIZE; + sync->ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_TX_POWER_BIT); + ext_hdr_len += BLE_LL_EXT_ADV_TX_POWER_SIZE; } /* if we have any fields in ext header we need to add flags, note that Aux @@ -2328,32 +2327,32 @@ ble_ll_adv_sync_calculate(struct ble_ll_adv_sm *advsm, * how Aux calculate works and this also make it easier to add more fields * into flags if needed in future */ - if (sync->ext_hdr) { - hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE; + if (sync->ext_hdr_flags) { + ext_hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE; } /* AdvData always */ - sync->sync_data_len = min(BLE_LL_MAX_PAYLOAD_LEN - hdr_len, rem_sync_data_len); + sync->data_len = min(BLE_LL_MAX_PAYLOAD_LEN - ext_hdr_len, rem_data_len); /* AuxPtr if there are more AdvData remaining that we can fit here */ - if ((rem_sync_data_len > sync->sync_data_len)) { - /* adjust for flags that needs to be added if AuxPtr is only field - * in Extended Header - */ - if (!sync->ext_hdr) { - hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE; - sync->sync_data_len -= BLE_LL_EXT_ADV_FLAGS_SIZE; - } + if ((rem_data_len > sync->data_len)) { + /* adjust for flags that needs to be added if AuxPtr is only field + * in Extended Header + */ + if (!sync->ext_hdr_flags) { + ext_hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE; + sync->data_len -= BLE_LL_EXT_ADV_FLAGS_SIZE; + } - sync->ext_hdr |= (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT); - hdr_len += BLE_LL_EXT_ADV_AUX_PTR_SIZE; - sync->sync_data_len -= BLE_LL_EXT_ADV_AUX_PTR_SIZE; + sync->ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT); + ext_hdr_len += BLE_LL_EXT_ADV_AUX_PTR_SIZE; + sync->data_len -= BLE_LL_EXT_ADV_AUX_PTR_SIZE; - /* PDU payload should be full if chained */ - BLE_LL_ASSERT(hdr_len + sync->sync_data_len == BLE_LL_MAX_PAYLOAD_LEN); + /* PDU payload should be full if chained */ + BLE_LL_ASSERT(ext_hdr_len + sync->data_len == BLE_LL_MAX_PAYLOAD_LEN); } - sync->payload_len = hdr_len + sync->sync_data_len; + sync->payload_len = ext_hdr_len + sync->data_len; } static void @@ -2433,8 +2432,8 @@ ble_ll_adv_periodic_schedule_next(struct ble_ll_adv_sm *advsm) struct ble_ll_adv_sync *sync; struct ble_ll_adv_sync *sync_next; struct ble_ll_sched_item *sch; - uint16_t rem_sync_data_len; - uint16_t next_sync_data_offset; + uint16_t rem_data_len; + uint16_t next_data_offset; uint32_t max_usecs; uint8_t chan; @@ -2457,16 +2456,16 @@ ble_ll_adv_periodic_schedule_next(struct ble_ll_adv_sm *advsm) * Do not schedule next sync if current sync does not have AuxPtr in extended * header as this means we do not need subsequent ADV_CHAIN_IND to be sent. */ - if (!(sync->ext_hdr & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT))) { + if (!(sync->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT))) { return; } - next_sync_data_offset = sync->sync_data_offset + sync->sync_data_len; + next_data_offset = sync->data_offset + sync->data_len; - BLE_LL_ASSERT(SYNC_DATA_LEN(advsm) >= next_sync_data_offset); + BLE_LL_ASSERT(SYNC_DATA_LEN(advsm) >= next_data_offset); - rem_sync_data_len = SYNC_DATA_LEN(advsm) - next_sync_data_offset; - BLE_LL_ASSERT(rem_sync_data_len > 0); + rem_data_len = SYNC_DATA_LEN(advsm) - next_data_offset; + BLE_LL_ASSERT(rem_data_len > 0); /* we use separate counter for chaining */ chan = ble_ll_utils_dci_csa2(advsm->periodic_chain_event_cntr++, @@ -2474,7 +2473,7 @@ ble_ll_adv_periodic_schedule_next(struct ble_ll_adv_sm *advsm) advsm->periodic_num_used_chans, advsm->periodic_chanmap); - ble_ll_adv_sync_calculate(advsm, sync_next, next_sync_data_offset, chan); + ble_ll_adv_sync_calculate(advsm, sync_next, next_data_offset, chan); max_usecs = ble_ll_pdu_tx_time_get(sync_next->payload_len, advsm->sec_phy); sync_next->start_time = sync->sch.end_time + From cc29e37c9cee5a0ae74bd21ddcb34e6ed6ddce58 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 30 Aug 2022 11:25:36 +0200 Subject: [PATCH 0506/1333] nimble/phy/nrf: Fix setting -3dBm power on nRF5340 There was a typo which would result in -4 dBm being set instead. --- nimble/drivers/nrf5340/src/ble_phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/drivers/nrf5340/src/ble_phy.c b/nimble/drivers/nrf5340/src/ble_phy.c index 7d0e3e1fa7..6999aee634 100644 --- a/nimble/drivers/nrf5340/src/ble_phy.c +++ b/nimble/drivers/nrf5340/src/ble_phy.c @@ -1817,7 +1817,7 @@ ble_phy_txpower_round(int dbm) } if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg3dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm; + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg3dBm; } if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm) { From ca3e5982707f98c2c6f190f6a6aa7fed1915e230 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 31 Aug 2022 09:24:16 +0200 Subject: [PATCH 0507/1333] nimble/ll: Fix not setting TX power in HCI VS command PHY was not configured to use new TX power immediatelly. This resulted in new TX power being used only after advertising event ended. --- nimble/controller/src/ble_ll_hci_vs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index d003465008..c56fc660bf 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -128,6 +128,8 @@ ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, g_ble_ll_tx_power = ble_phy_txpower_round(cmd->tx_power); } + ble_phy_txpwr_set(g_ble_ll_tx_power); + rsp->tx_power = g_ble_ll_tx_power; *rsplen = sizeof(*rsp); From 3de15c9615a9587ee1346d9a6cb57ad65a08ea22 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Wed, 31 Aug 2022 15:25:26 +0200 Subject: [PATCH 0508/1333] apps/peripheral: Fix not saving conn_handle after connection Even though conn_handle is defined and later used in connection params update request event callback, it was never initialized with a proper value. --- apps/peripheral/src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/peripheral/src/main.c b/apps/peripheral/src/main.c index f22579a732..28e8afb141 100755 --- a/apps/peripheral/src/main.c +++ b/apps/peripheral/src/main.c @@ -50,6 +50,7 @@ adv_event(struct ble_gap_event *event, void *arg) MODLOG_DFLT(INFO, "connection %s; status=%d\n", event->connect.status == 0 ? "established" : "failed", event->connect.status); + conn_handle = event->connect.conn_handle; break; case BLE_GAP_EVENT_CONN_UPDATE_REQ: /* connected device requests update of connection parameters, From 5ea8badc4698b05b42011032e9ef4afc088e96f0 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 4 Aug 2022 15:09:55 +0200 Subject: [PATCH 0509/1333] nimble/ll: Add vs command to change all data length parameters --- nimble/controller/include/controller/ble_ll.h | 4 -- .../include/controller/ble_ll_conn.h | 1 + .../include/controller/ble_ll_hci.h | 3 + nimble/controller/src/ble_ll.c | 30 -------- nimble/controller/src/ble_ll_conn.c | 53 ++++++++++++++ nimble/controller/src/ble_ll_conn_hci.c | 39 +++-------- nimble/controller/src/ble_ll_conn_priv.h | 6 ++ nimble/controller/src/ble_ll_ctrl.c | 7 +- nimble/controller/src/ble_ll_hci.c | 69 ++++++++++--------- nimble/controller/src/ble_ll_hci_vs.c | 52 ++++++++++++++ nimble/include/nimble/hci_common.h | 12 ++++ 11 files changed, 178 insertions(+), 98 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index a524759a2f..8535d44047 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -596,10 +596,6 @@ int ble_ll_set_host_feat(const uint8_t *cmdbuf, uint8_t len); /* Read set of states supported by the Link Layer */ uint64_t ble_ll_read_supp_states(void); -/* Check if octets and time are valid. Returns 0 if not valid */ -int ble_ll_chk_txrx_octets(uint16_t octets); -int ble_ll_chk_txrx_time(uint16_t time); - /* Random numbers */ int ble_ll_rand_init(void); void ble_ll_rand_sample(uint8_t rnum); diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 3872406f16..c849794281 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -230,6 +230,7 @@ struct ble_ll_conn_sm uint16_t ota_max_rx_time; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) uint16_t host_req_max_tx_time; + uint16_t host_req_max_rx_time; #endif #if (BLE_LL_BT5_PHY_SUPPORTED == 1) diff --git a/nimble/controller/include/controller/ble_ll_hci.h b/nimble/controller/include/controller/ble_ll_hci.h index 37d6d205c1..b73f852751 100644 --- a/nimble/controller/include/controller/ble_ll_hci.h +++ b/nimble/controller/include/controller/ble_ll_hci.h @@ -83,6 +83,9 @@ bool ble_ll_hci_adv_mode_ext(void); /* Get TX power compensation rounded to integer dB */ int8_t ble_ll_get_tx_pwr_compensation(void); +/* Check if max octets/time are within allowed range */ +int ble_ll_hci_check_dle(uint16_t max_octets, uint16_t max_time); + #if MYNEWT_VAL(BLE_LL_HCI_VS) void ble_ll_hci_vs_register(struct ble_ll_hci_vs_cmd *cmds, uint32_t num_cmds); #endif diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 90fee6bf7b..356bf4afd0 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -503,36 +503,6 @@ ble_ll_rxpdu_alloc(uint16_t len) return NULL; } -int -ble_ll_chk_txrx_octets(uint16_t octets) -{ - int rc; - - if ((octets < BLE_LL_CONN_SUPP_BYTES_MIN) || - (octets > BLE_LL_CONN_SUPP_BYTES_MAX)) { - rc = 0; - } else { - rc = 1; - } - - return rc; -} - -int -ble_ll_chk_txrx_time(uint16_t time) -{ - int rc; - - if ((time < BLE_LL_CONN_SUPP_TIME_MIN) || - (time > BLE_LL_CONN_SUPP_TIME_MAX)) { - rc = 0; - } else { - rc = 1; - } - - return rc; -} - /** * Checks to see if the address is a resolvable private address. * diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index b625a0e354..9bfa1f8e5f 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1798,6 +1798,58 @@ ble_ll_conn_central_init(struct ble_ll_conn_sm *connsm, } #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) +int +ble_ll_conn_set_data_len(struct ble_ll_conn_sm *connsm, + uint16_t tx_octets, uint16_t tx_time, + uint16_t rx_octets, uint16_t rx_time) +{ + int init_dle = 0; + + /* Note: octets/time shall be checked by caller! */ + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) + /* Keep original values requested by host since we may want to recalculate + * after PHY changes between coded and uncoded. + */ + connsm->host_req_max_tx_time = tx_time; + connsm->host_req_max_rx_time = rx_time; + + /* If peer does not support coded, we cannot use value larger than 2120us */ + if (!ble_ll_conn_rem_feature_check(connsm, BLE_LL_FEAT_LE_CODED_PHY)) { + tx_time = min(tx_time, BLE_LL_CONN_SUPP_TIME_MAX_UNCODED); + rx_time = min(rx_time, BLE_LL_CONN_SUPP_TIME_MAX_UNCODED); + } +#endif + + if (connsm->max_tx_time != tx_time) { + connsm->max_tx_time = tx_time; + init_dle = 1; + } + + if (connsm->max_tx_octets != tx_octets) { + connsm->max_tx_octets = tx_octets; + init_dle = 1; + } + + if (rx_time && (connsm->max_rx_time != rx_time)) { + connsm->max_rx_time = rx_time; + init_dle = 1; + } + + if (rx_octets && (connsm->max_rx_octets != rx_octets)) { + connsm->max_rx_octets = rx_octets; + init_dle = 1; + } + + if (init_dle) { + ble_ll_ctrl_initiate_dle(connsm); + } + + return 0; +} +#endif + #if (BLE_LL_BT5_PHY_SUPPORTED == 1) static void @@ -1988,6 +2040,7 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) connsm->eff_max_rx_octets = BLE_LL_CONN_SUPP_BYTES_MIN; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) connsm->host_req_max_tx_time = 0; + connsm->host_req_max_rx_time = 0; #endif /* Reset encryption data */ diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index fb77d668d7..d0de63ba9e 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1475,8 +1475,8 @@ ble_ll_conn_hci_set_data_len(const uint8_t *cmdbuf, uint8_t len, struct ble_hci_le_set_data_len_rp *rsp = (void *) rspbuf; int rc; uint16_t handle; - uint16_t txoctets; - uint16_t txtime; + uint16_t tx_octets; + uint16_t tx_time; struct ble_ll_conn_sm *connsm; if (len != sizeof(*cmd)) { @@ -1491,42 +1491,19 @@ ble_ll_conn_hci_set_data_len(const uint8_t *cmdbuf, uint8_t len, goto done; } - txoctets = le16toh(cmd->tx_octets); - txtime = le16toh(cmd->tx_time); + tx_octets = le16toh(cmd->tx_octets); + tx_time = le16toh(cmd->tx_time); - /* Make sure it is valid */ - if (!ble_ll_chk_txrx_octets(txoctets) || - !ble_ll_chk_txrx_time(txtime)) { - rc = BLE_ERR_INV_HCI_CMD_PARMS; - goto done; - } - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - /* - * Keep original value requested by host since we may want to recalculate - * MaxTxTime after PHY changes between coded and uncoded. - */ - connsm->host_req_max_tx_time = txtime; - - /* If peer does not support coded, we cannot use value larger than 2120us */ - if (!ble_ll_conn_rem_feature_check(connsm, BLE_LL_FEAT_LE_CODED_PHY)) { - txtime = min(txtime, BLE_LL_CONN_SUPP_TIME_MAX_UNCODED); + if (!ble_ll_hci_check_dle(tx_octets, tx_time)) { + return BLE_ERR_INV_HCI_CMD_PARMS; } -#endif - - rc = BLE_ERR_SUCCESS; - if (connsm->max_tx_time != txtime || - connsm->max_tx_octets != txoctets) { - connsm->max_tx_time = txtime; - connsm->max_tx_octets = txoctets; - - ble_ll_ctrl_initiate_dle(connsm); - } + rc = ble_ll_conn_set_data_len(connsm, tx_octets, tx_time, 0, 0); done: rsp->conn_handle = htole16(handle); *rsplen = sizeof(*rsp); + return rc; } #endif diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index 846a6b644b..bb58e4b7a6 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -252,6 +252,12 @@ bool ble_ll_conn_cth_flow_enable(bool enabled); void ble_ll_conn_cth_flow_process_cmd(const uint8_t *cmdbuf); #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) +int ble_ll_conn_set_data_len(struct ble_ll_conn_sm *connsm, + uint16_t tx_octets, uint16_t tx_time, + uint16_t rx_octets, uint16_t rx_time); +#endif + void ble_ll_conn_itvl_to_ticks(uint32_t itvl, uint32_t *itvl_ticks, uint8_t *itvl_usecs); diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 38b3b6d247..948eefae32 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -2124,7 +2124,12 @@ ble_ll_ctrl_update_features(struct ble_ll_conn_sm *connsm, uint8_t *feat) } else { connsm->max_tx_time = g_ble_ll_conn_params.conn_init_max_tx_time_coded; } - connsm->max_rx_time = BLE_LL_CONN_SUPP_TIME_MAX_CODED; + if (connsm->host_req_max_rx_time) { + connsm->max_rx_time = max(connsm->max_rx_time, + connsm->host_req_max_rx_time); + } else { + connsm->max_rx_time = BLE_LL_CONN_SUPP_TIME_MAX_CODED; + } } #endif diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 054fef90f0..f0151b497d 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -435,6 +435,15 @@ ble_ll_hci_le_set_def_phy(const uint8_t *cmdbuf, uint8_t len) #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) +int +ble_ll_hci_check_dle(uint16_t max_octets, uint16_t max_time) +{ + return (max_octets >= BLE_LL_CONN_SUPP_BYTES_MIN) && + (max_octets <= BLE_LL_CONN_SUPP_BYTES_MAX) && + (max_time >= BLE_LL_CONN_SUPP_TIME_MIN) && + (max_time <= BLE_LL_CONN_SUPP_TIME_MAX); +} + /** * HCI write suggested default data length command. * @@ -453,51 +462,47 @@ ble_ll_hci_le_set_def_phy(const uint8_t *cmdbuf, uint8_t len) static int ble_ll_hci_le_wr_sugg_data_len(const uint8_t *cmdbuf, uint8_t len) { - const struct ble_hci_le_wr_sugg_def_data_len_cp *cmd = (const void*) cmdbuf; - uint16_t tx_oct; + const struct ble_hci_le_wr_sugg_def_data_len_cp *cmd = (const void *)cmdbuf; + uint16_t tx_octets; uint16_t tx_time; - int rc; if (len != sizeof(*cmd)) { return BLE_ERR_INV_HCI_CMD_PARMS; } /* Get suggested octets and time */ - tx_oct = le16toh(cmd->max_tx_octets); + tx_octets = le16toh(cmd->max_tx_octets); tx_time = le16toh(cmd->max_tx_time); - /* If valid, write into suggested and change connection initial times */ - if (ble_ll_chk_txrx_octets(tx_oct) && ble_ll_chk_txrx_time(tx_time)) { - g_ble_ll_conn_params.sugg_tx_octets = (uint8_t)tx_oct; - g_ble_ll_conn_params.sugg_tx_time = tx_time; + if (!ble_ll_hci_check_dle(tx_octets, tx_time)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } - /* - * We can disregard host suggestion, but we are a nice controller so - * let's use host suggestion, unless they exceed max supported values - * in which case we just use our max. - */ - g_ble_ll_conn_params.conn_init_max_tx_octets = - min(tx_oct, g_ble_ll_conn_params.supp_max_tx_octets); - g_ble_ll_conn_params.conn_init_max_tx_time = - min(tx_time, g_ble_ll_conn_params.supp_max_tx_time); + g_ble_ll_conn_params.sugg_tx_octets = tx_octets; + g_ble_ll_conn_params.sugg_tx_time = tx_time; - /* - * Use the same for coded and uncoded defaults. These are used when PHY - * parameters are initialized and we want to use values overridden by - * host. Make sure we do not exceed max supported time on uncoded. - */ - g_ble_ll_conn_params.conn_init_max_tx_time_uncoded = - min(BLE_LL_CONN_SUPP_TIME_MAX_UNCODED, - g_ble_ll_conn_params.conn_init_max_tx_time); - g_ble_ll_conn_params.conn_init_max_tx_time_coded = - g_ble_ll_conn_params.conn_init_max_tx_time; + /* + * We can disregard host suggestion, but we are a nice controller so + * let's use host suggestion, unless they exceed max supported values + * in which case we just use our max. + */ + g_ble_ll_conn_params.conn_init_max_tx_octets = + min(tx_octets, g_ble_ll_conn_params.supp_max_tx_octets); + g_ble_ll_conn_params.conn_init_max_tx_time = + min(tx_time, g_ble_ll_conn_params.supp_max_tx_time); - rc = BLE_ERR_SUCCESS; - } else { - rc = BLE_ERR_INV_HCI_CMD_PARMS; - } + /* + * Use the same for coded and uncoded defaults. These are used when PHY + * parameters are initialized and we want to use values overridden by + * host. Make sure we do not exceed max supported time on uncoded. + */ + g_ble_ll_conn_params.conn_init_max_tx_time_uncoded = + min(BLE_LL_CONN_SUPP_TIME_MAX_UNCODED, + g_ble_ll_conn_params.conn_init_max_tx_time); + g_ble_ll_conn_params.conn_init_max_tx_time_coded = + g_ble_ll_conn_params.conn_init_max_tx_time; - return rc; + return 0; } /** diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index c56fc660bf..9b9cf268d8 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -303,6 +303,54 @@ ble_ll_hci_vs_css_read_conn_slot(uint16_t ocf, const uint8_t *cmdbuf, } #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) +static int +ble_ll_hci_vs_set_data_len(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_vs_set_data_len_cp *cmd = (const void *) cmdbuf; + struct ble_hci_vs_set_data_len_rp *rsp = (void *) rspbuf; + struct ble_ll_conn_sm *connsm; + uint16_t conn_handle; + uint16_t tx_octets; + uint16_t tx_time; + uint16_t rx_octets; + uint16_t rx_time; + int rc; + + if (cmdlen != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + conn_handle = le16toh(cmd->conn_handle); + connsm = ble_ll_conn_find_by_handle(conn_handle); + if (!connsm) { + return BLE_ERR_UNK_CONN_ID; + } + + tx_octets = le16toh(cmd->tx_octets); + tx_time = le16toh(cmd->tx_time); + rx_octets = le16toh(cmd->rx_octets); + rx_time = le16toh(cmd->rx_time); + + if (!ble_ll_hci_check_dle(tx_octets, tx_time) || + !ble_ll_hci_check_dle(rx_octets, rx_time)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + rc = ble_ll_conn_set_data_len(connsm, tx_octets, tx_time, rx_octets, + rx_time); + if (rc) { + return rc; + } + + rsp->conn_handle = htole16(conn_handle); + *rsplen = sizeof(*rsp); + + return 0; +} +#endif + static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_RD_STATIC_ADDR, ble_ll_hci_vs_rd_static_addr), @@ -322,6 +370,10 @@ static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_CSS_READ_CONN_SLOT, ble_ll_hci_vs_css_read_conn_slot), #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) + BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_DATA_LEN, + ble_ll_hci_vs_set_data_len), +#endif }; static struct ble_ll_hci_vs_cmd * diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index b83c35aa12..cfcbd822ad 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1168,6 +1168,18 @@ struct ble_hci_vs_css_read_conn_slot_rp { uint16_t conn_handle; uint16_t slot_idx; } __attribute__((packed)); +#define BLE_HCI_OCF_VS_SET_DATA_LEN (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0004)) +struct ble_hci_vs_set_data_len_cp { + uint16_t conn_handle; + uint16_t tx_octets; + uint16_t tx_time; + uint16_t rx_octets; + uint16_t rx_time; +} __attribute__((packed)); +struct ble_hci_vs_set_data_len_rp { + uint16_t conn_handle; +} __attribute__((packed)); + /* Command Specific Definitions */ /* --- Set controller to host flow control (OGF 0x03, OCF 0x0031) --- */ From c1a2c9949805148520afb852d86afe588061d64e Mon Sep 17 00:00:00 2001 From: Jakub Rotkiewicz Date: Wed, 27 Jul 2022 09:23:42 +0200 Subject: [PATCH 0510/1333] nimble/host/ble_l2cap_coc: SDUs for faster data rx Added list of SDUs for faster data rx. This allows to process more data while receiving another. --- nimble/host/src/ble_l2cap_coc.c | 93 ++++++++++++++++++---------- nimble/host/src/ble_l2cap_coc_priv.h | 8 ++- nimble/host/syscfg.yml | 8 ++- 3 files changed, 74 insertions(+), 35 deletions(-) diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c index f74cea2800..973ff75f46 100644 --- a/nimble/host/src/ble_l2cap_coc.c +++ b/nimble/host/src/ble_l2cap_coc.c @@ -175,6 +175,7 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) { int rc; struct os_mbuf **om; + struct os_mbuf *rx_sdu; struct ble_l2cap_coc_endpoint *rx; uint16_t om_total; @@ -186,10 +187,13 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) rx = &chan->coc_rx; BLE_HS_DBG_ASSERT(rx != NULL); + rx_sdu = rx->sdus[chan->coc_rx.current_sdu_idx]; + BLE_HS_DBG_ASSERT(rx_sdu != NULL); + om_total = OS_MBUF_PKTLEN(*om); /* First LE frame */ - if (OS_MBUF_PKTLEN(rx->sdu) == 0) { + if (OS_MBUF_PKTLEN(rx_sdu) == 0) { uint16_t sdu_len; rc = ble_hs_mbuf_pullup_base(om, BLE_L2CAP_SDU_SIZE); @@ -199,12 +203,15 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) sdu_len = get_le16((*om)->om_data); + BLE_HS_LOG(INFO, "First LE frame received %d, SDU len: %d\n", + om_total, sdu_len + 2); + /* We should receive payload of size sdu_len + 2 bytes of sdu_len field */ if (om_total > sdu_len + 2) { BLE_HS_LOG(ERROR, "Payload larger than expected (%d>%d)\n", om_total, sdu_len + 2); /* Disconnect peer with invalid behaviour */ - rx->sdu = NULL; + rx_sdu = NULL; rx->data_offset = 0; ble_l2cap_disconnect(chan); return BLE_HS_EBADDATA; @@ -218,12 +225,13 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) return BLE_HS_EBADDATA; } - BLE_HS_LOG(DEBUG, "sdu_len=%d, received LE frame=%d, credits=%d\n", - sdu_len, om_total, rx->credits); + BLE_HS_LOG(DEBUG, + "sdu_len=%d, received LE frame=%d, credits=%d, current_sdu_idx=%d\n", + sdu_len, om_total, rx->credits, chan->coc_rx.current_sdu_idx); os_mbuf_adj(*om , BLE_L2CAP_SDU_SIZE); - rc = os_mbuf_appendfrom(rx->sdu, *om, 0, om_total - BLE_L2CAP_SDU_SIZE); + rc = os_mbuf_appendfrom(rx_sdu, *om, 0, om_total - BLE_L2CAP_SDU_SIZE); if (rc != 0) { /* FIXME: User shall give us big enough buffer. * need to handle it better @@ -238,16 +246,16 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) } else { BLE_HS_LOG(DEBUG, "Continuation...received %d\n", (*om)->om_len); - if (OS_MBUF_PKTLEN(rx->sdu) + (*om)->om_len > rx->data_offset) { + if (OS_MBUF_PKTLEN(rx_sdu) + (*om)->om_len > rx->data_offset) { /* Disconnect peer with invalid behaviour */ BLE_HS_LOG(ERROR, "Payload larger than expected (%d>%d)\n", - OS_MBUF_PKTLEN(rx->sdu) + (*om)->om_len, rx->data_offset); - rx->sdu = NULL; + OS_MBUF_PKTLEN(rx_sdu) + (*om)->om_len, rx->data_offset); + rx_sdu = NULL; rx->data_offset = 0; ble_l2cap_disconnect(chan); return BLE_HS_EBADDATA; } - rc = os_mbuf_appendfrom(rx->sdu, *om, 0, om_total); + rc = os_mbuf_appendfrom(rx_sdu, *om, 0, om_total); if (rc != 0) { /* FIXME: need to handle it better */ BLE_HS_LOG(DEBUG, "Could not append data rc=%d\n", rc); @@ -257,17 +265,19 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) rx->credits--; - if (OS_MBUF_PKTLEN(rx->sdu) == rx->data_offset) { - struct os_mbuf *sdu_rx = rx->sdu; + if (OS_MBUF_PKTLEN(rx_sdu) == rx->data_offset) { + struct os_mbuf *sdu_rx = rx_sdu; BLE_HS_LOG(DEBUG, "Received sdu_len=%d, credits left=%d\n", - OS_MBUF_PKTLEN(rx->sdu), rx->credits); + OS_MBUF_PKTLEN(rx_sdu), rx->credits); /* Lets get back control to os_mbuf to application. * Since it this callback application might want to set new sdu * we need to prepare space for this. Therefore we need sdu_rx */ - rx->sdu = NULL; + rx_sdu = NULL; + chan->coc_rx.current_sdu_idx = + (chan->coc_rx.current_sdu_idx + 1) % BLE_L2CAP_SDU_BUFF_CNT; rx->data_offset = 0; ble_l2cap_event_coc_received_data(chan, sdu_rx); @@ -288,8 +298,9 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) ble_l2cap_sig_le_credits(chan->conn_handle, chan->scid, rx->credits); } - BLE_HS_LOG(DEBUG, "Received partial sdu_len=%d, credits left=%d\n", - OS_MBUF_PKTLEN(rx->sdu), rx->credits); + BLE_HS_LOG(DEBUG, + "Received partial sdu_len=%d, credits left=%d, current_sdu_idx=%d\n", + OS_MBUF_PKTLEN(rx_sdu), rx->credits, chan->coc_rx.current_sdu_idx); return 0; } @@ -324,7 +335,12 @@ ble_l2cap_coc_chan_alloc(struct ble_hs_conn *conn, uint16_t psm, uint16_t mtu, chan->my_coc_mps = MYNEWT_VAL(BLE_L2CAP_COC_MPS); chan->rx_fn = ble_l2cap_coc_rx_fn; chan->coc_rx.mtu = mtu; - chan->coc_rx.sdu = sdu_rx; + chan->coc_rx.sdus[0] = sdu_rx; + for (int i = 1; i < BLE_L2CAP_SDU_BUFF_CNT; i++) { + chan->coc_rx.sdus[i] = NULL; + } + chan->coc_rx.current_sdu_idx = 0; + chan->coc_rx.next_sdu_alloc_idx = chan->coc_rx.sdus[0] == NULL ? 0 : 1; /* Number of credits should allow to send full SDU with on given * L2CAP MTU @@ -391,8 +407,10 @@ ble_l2cap_coc_cleanup_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan chan->scid - BLE_L2CAP_COC_CID_START); } - os_mbuf_free_chain(chan->coc_rx.sdu); - os_mbuf_free_chain(chan->coc_tx.sdu); + for (int i = 0; i < BLE_L2CAP_SDU_BUFF_CNT; i++) { + os_mbuf_free_chain(chan->coc_rx.sdus[i]); + } + os_mbuf_free_chain(chan->coc_tx.sdus[0]); } static void @@ -427,7 +445,7 @@ ble_l2cap_coc_continue_tx(struct ble_l2cap_chan *chan) /* If there is no data to send, just return success */ tx = &chan->coc_tx; - if (!tx->sdu) { + if (!tx->sdus[0]) { ble_hs_unlock(); return 0; } @@ -438,7 +456,7 @@ ble_l2cap_coc_continue_tx(struct ble_l2cap_chan *chan) BLE_HS_LOG(DEBUG, "Available credits %d\n", tx->credits); /* lets calculate data we are going to send */ - left_to_send = OS_MBUF_PKTLEN(tx->sdu) - tx->data_offset; + left_to_send = OS_MBUF_PKTLEN(tx->sdus[0]) - tx->data_offset; if (tx->data_offset == 0) { sdu_size_offset = BLE_L2CAP_SDU_SIZE; @@ -458,9 +476,10 @@ ble_l2cap_coc_continue_tx(struct ble_l2cap_chan *chan) if (tx->data_offset == 0) { /* First packet needs SDU len first. Left to send */ - uint16_t l = htole16(OS_MBUF_PKTLEN(tx->sdu)); + uint16_t l = htole16(OS_MBUF_PKTLEN(tx->sdus[0])); - BLE_HS_LOG(DEBUG, "Sending SDU len=%d\n", OS_MBUF_PKTLEN(tx->sdu)); + BLE_HS_LOG(DEBUG, "Sending SDU len=%d\n", + OS_MBUF_PKTLEN(tx->sdus[0])); rc = os_mbuf_append(txom, &l, sizeof(uint16_t)); if (rc) { rc = BLE_HS_ENOMEM; @@ -473,7 +492,7 @@ ble_l2cap_coc_continue_tx(struct ble_l2cap_chan *chan) * that for first packet we need to decrease data size by 2 bytes for sdu * size */ - rc = os_mbuf_appendfrom(txom, tx->sdu, tx->data_offset, + rc = os_mbuf_appendfrom(txom, tx->sdus[0], tx->data_offset, len - sdu_size_offset); if (rc) { rc = BLE_HS_ENOMEM; @@ -494,18 +513,19 @@ ble_l2cap_coc_continue_tx(struct ble_l2cap_chan *chan) } BLE_HS_LOG(DEBUG, "Sent %d bytes, credits=%d, to send %d bytes \n", - len, tx->credits, OS_MBUF_PKTLEN(tx->sdu)- tx->data_offset); + len, tx->credits, + OS_MBUF_PKTLEN(tx->sdus[0]) - tx->data_offset); - if (tx->data_offset == OS_MBUF_PKTLEN(tx->sdu)) { + if (tx->data_offset == OS_MBUF_PKTLEN(tx->sdus[0])) { BLE_HS_LOG(DEBUG, "Complete package sent\n"); - os_mbuf_free_chain(tx->sdu); - tx->sdu = NULL; + os_mbuf_free_chain(tx->sdus[0]); + tx->sdus[0] = NULL; tx->data_offset = 0; break; } } - if (tx->sdu) { + if (tx->sdus[0]) { /* Not complete SDU sent, wait for credits */ tx->flags |= BLE_L2CAP_COC_FLAG_STALLED; ble_hs_unlock(); @@ -523,8 +543,8 @@ ble_l2cap_coc_continue_tx(struct ble_l2cap_chan *chan) return 0; failed: - os_mbuf_free_chain(tx->sdu); - tx->sdu = NULL; + os_mbuf_free_chain(tx->sdus[0]); + tx->sdus[0] = NULL; os_mbuf_free_chain(txom); if (tx->flags & BLE_L2CAP_COC_FLAG_STALLED) { @@ -582,7 +602,14 @@ ble_l2cap_coc_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx) return BLE_HS_EINVAL; } - chan->coc_rx.sdu = sdu_rx; + if (chan->coc_rx.sdus[0] != NULL && + chan->coc_rx.next_sdu_alloc_idx == chan->coc_rx.current_sdu_idx) { + return BLE_HS_EBUSY; + } + + chan->coc_rx.sdus[chan->coc_rx.next_sdu_alloc_idx] = sdu_rx; + chan->coc_rx.next_sdu_alloc_idx = + (chan->coc_rx.next_sdu_alloc_idx + 1) % BLE_L2CAP_SDU_BUFF_CNT; ble_hs_lock(); conn = ble_hs_conn_find_assert(chan->conn_handle); @@ -625,11 +652,11 @@ ble_l2cap_coc_send(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_tx) } ble_hs_lock(); - if (tx->sdu) { + if (tx->sdus[0]) { ble_hs_unlock(); return BLE_HS_EBUSY; } - tx->sdu = sdu_tx; + tx->sdus[0] = sdu_tx; /* leave the host locked on purpose when ble_l2cap_coc_continue_tx() */ diff --git a/nimble/host/src/ble_l2cap_coc_priv.h b/nimble/host/src/ble_l2cap_coc_priv.h index 5ebdaa050c..37a95b31ec 100644 --- a/nimble/host/src/ble_l2cap_coc_priv.h +++ b/nimble/host/src/ble_l2cap_coc_priv.h @@ -37,8 +37,14 @@ struct ble_l2cap_chan; #define BLE_L2CAP_COC_FLAG_STALLED 0x01 +#define BLE_L2CAP_SDU_BUFF_CNT (MYNEWT_VAL(BLE_L2CAP_COC_SDU_BUFF_COUNT)) + struct ble_l2cap_coc_endpoint { - struct os_mbuf *sdu; + struct os_mbuf *sdus[BLE_L2CAP_SDU_BUFF_CNT]; + /* Index for currently used sdu from sdus */ + uint16_t current_sdu_idx; + /* Index indicating free sdus slot to allocate next sdu */ + uint16_t next_sdu_alloc_idx; uint16_t mtu; uint16_t credits; uint16_t data_offset; diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index ec55878e07..cf35be243c 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -79,7 +79,13 @@ syscfg.defs: the required HCI and L2CAP headers fit into the smallest available MSYS blocks. value: 'MYNEWT_VAL_MSYS_1_BLOCK_SIZE-8' - + BLE_L2CAP_COC_SDU_BUFF_COUNT: + description: > + Defines maximum number of SDU buffers in L2CAP COC endpoints. + Provides more currently available credits to receive more data packets. + value: 1 + restrictions: + - 'BLE_L2CAP_COC_SDU_BUFF_COUNT > 0' BLE_L2CAP_ENHANCED_COC: description: > Enables LE Enhanced CoC mode. From 46df736023e2fa76c425418073d80ff1d76d54ae Mon Sep 17 00:00:00 2001 From: Jakub Rotkiewicz Date: Wed, 27 Jul 2022 09:28:06 +0200 Subject: [PATCH 0511/1333] nimble/host/ble_l2cap_coc: coding style fixes --- nimble/host/src/ble_l2cap_coc.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c index 973ff75f46..875dbeba07 100644 --- a/nimble/host/src/ble_l2cap_coc.c +++ b/nimble/host/src/ble_l2cap_coc.c @@ -35,7 +35,7 @@ static struct ble_l2cap_coc_srv_list ble_l2cap_coc_srvs; static os_membuf_t ble_l2cap_coc_srv_mem[ OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM), - sizeof (struct ble_l2cap_coc_srv)) + sizeof(struct ble_l2cap_coc_srv)) ]; static struct os_mempool ble_l2cap_coc_srv_pool; @@ -67,9 +67,9 @@ ble_l2cap_coc_srv_alloc(void) int ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu, - ble_l2cap_event_fn *cb, void *cb_arg) + ble_l2cap_event_fn *cb, void *cb_arg) { - struct ble_l2cap_coc_srv * srv; + struct ble_l2cap_coc_srv *srv; srv = ble_l2cap_coc_srv_alloc(); if (!srv) { @@ -113,7 +113,7 @@ ble_l2cap_get_first_available_bit(uint32_t *cid_mask) * a) If bit == 0 means all the bits are used * b) this function returns 1 + index */ - bit = __builtin_ffs(~(unsigned int)(cid_mask[i])); + bit = __builtin_ffs(~(unsigned int) (cid_mask[i])); if (bit != 0) { break; } @@ -148,8 +148,8 @@ ble_l2cap_coc_srv_find(uint16_t psm) srv = NULL; STAILQ_FOREACH(cur, &ble_l2cap_coc_srvs, next) { if (cur->psm == psm) { - srv = cur; - break; + srv = cur; + break; } } @@ -229,7 +229,7 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) "sdu_len=%d, received LE frame=%d, credits=%d, current_sdu_idx=%d\n", sdu_len, om_total, rx->credits, chan->coc_rx.current_sdu_idx); - os_mbuf_adj(*om , BLE_L2CAP_SDU_SIZE); + os_mbuf_adj(*om, BLE_L2CAP_SDU_SIZE); rc = os_mbuf_appendfrom(rx_sdu, *om, 0, om_total - BLE_L2CAP_SDU_SIZE); if (rc != 0) { @@ -306,7 +306,8 @@ ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) } void -ble_l2cap_coc_set_new_mtu_mps(struct ble_l2cap_chan *chan, uint16_t mtu, uint16_t mps) +ble_l2cap_coc_set_new_mtu_mps(struct ble_l2cap_chan *chan, uint16_t mtu, + uint16_t mps) { chan->my_coc_mps = mps; chan->coc_rx.mtu = mtu; @@ -378,7 +379,7 @@ ble_l2cap_coc_create_srv_chan(struct ble_hs_conn *conn, uint16_t psm, static void ble_l2cap_event_coc_disconnected(struct ble_l2cap_chan *chan) { - struct ble_l2cap_event event = { }; + struct ble_l2cap_event event = {}; /* FIXME */ if (!chan->cb) { @@ -397,7 +398,7 @@ ble_l2cap_coc_cleanup_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan { /* PSM 0 is used for fixed channels. */ if (chan->psm == 0) { - return; + return; } ble_l2cap_event_coc_disconnected(chan); @@ -416,7 +417,7 @@ ble_l2cap_coc_cleanup_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan static void ble_l2cap_event_coc_unstalled(struct ble_l2cap_chan *chan, int status) { - struct ble_l2cap_event event = { }; + struct ble_l2cap_event event = {}; if (!chan->cb) { return; @@ -669,10 +670,10 @@ ble_l2cap_coc_init(void) STAILQ_INIT(&ble_l2cap_coc_srvs); return os_mempool_init(&ble_l2cap_coc_srv_pool, - MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM), - sizeof (struct ble_l2cap_coc_srv), - ble_l2cap_coc_srv_mem, - "ble_l2cap_coc_srv_pool"); + MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM), + sizeof(struct ble_l2cap_coc_srv), + ble_l2cap_coc_srv_mem, + "ble_l2cap_coc_srv_pool"); } #endif From f85bbda005b7507111d728a33950bdc8e445ceb9 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 6 Sep 2022 14:04:39 +0200 Subject: [PATCH 0512/1333] nimble/ll: Fix BLE_HCI_OCF_VS_SET_DATA_LEN OCF This was duplicating BLE_HCI_OCF_VS_CSS_ENABLE and caused assert on register. --- nimble/include/nimble/hci_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index cfcbd822ad..a3c3dc3f08 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1168,7 +1168,7 @@ struct ble_hci_vs_css_read_conn_slot_rp { uint16_t conn_handle; uint16_t slot_idx; } __attribute__((packed)); -#define BLE_HCI_OCF_VS_SET_DATA_LEN (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0004)) +#define BLE_HCI_OCF_VS_SET_DATA_LEN (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0008)) struct ble_hci_vs_set_data_len_cp { uint16_t conn_handle; uint16_t tx_octets; From 77cf73807448208370c8fb7733162c57ace7a576 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 28 Feb 2022 23:58:43 +0100 Subject: [PATCH 0513/1333] nimble/phy/nrf52: Add tx-tx transition This adds TX-TX transition, initially supported only on nRF52 PHY. --- .../controller/include/controller/ble_phy.h | 1 + nimble/drivers/nrf52/src/ble_phy.c | 31 +++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index 44e8809b28..3980d344ee 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -65,6 +65,7 @@ struct os_mbuf; #define BLE_PHY_TRANSITION_NONE (0) #define BLE_PHY_TRANSITION_RX_TX (1) #define BLE_PHY_TRANSITION_TX_RX (2) +#define BLE_PHY_TRANSITION_TX_TX (3) /* PHY error codes */ #define BLE_PHY_ERR_RADIO_STATE (1) diff --git a/nimble/drivers/nrf52/src/ble_phy.c b/nimble/drivers/nrf52/src/ble_phy.c index c06536a9ae..c4086a2351 100644 --- a/nimble/drivers/nrf52/src/ble_phy.c +++ b/nimble/drivers/nrf52/src/ble_phy.c @@ -977,6 +977,7 @@ ble_phy_tx_end_isr(void) uint8_t was_encrypted; uint8_t transition; uint32_t rx_time; + uint32_t tx_time; /* Store PHY on which we've just transmitted smth */ tx_phy_mode = g_ble_phy_data.phy_cur_phy_mode; @@ -1001,14 +1002,9 @@ ble_phy_tx_end_isr(void) } #endif - /* Call transmit end callback */ - if (g_ble_phy_data.txend_cb) { - g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg); - } - transition = g_ble_phy_data.phy_transition; - if (transition == BLE_PHY_TRANSITION_TX_RX) { + if (transition == BLE_PHY_TRANSITION_TX_RX) { #if (BLE_LL_BT5_PHY_SUPPORTED == 1) ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); #endif @@ -1032,6 +1028,25 @@ ble_phy_tx_end_isr(void) nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); ble_phy_plna_enable_lna(); + } else if (transition == BLE_PHY_TRANSITION_TX_TX) { + /* Schedule TX exactly T_IFS after TX end captured in CC[2] */ + tx_time = NRF_TIMER0->CC[2] + BLE_LL_IFS; + /* Adjust for delay between EVENT_END and actual TX end time */ + tx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; + /* Adjust for radio ramp-up */ + tx_time -= BLE_PHY_T_TXENFAST; + /* Adjust for delay between EVENT_READY and actual TX start time */ + tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; + + nrf_timer_cc_set(NRF_TIMER0, 0, tx_time); + NRF_TIMER0->EVENTS_COMPARE[0] = 0; + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); + + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); + if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) { + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk); + g_ble_phy_data.phy_transition_late = 1; + } } else { /* * XXX: not sure we need to stop the timer here all the time. Or that @@ -1043,6 +1058,10 @@ ble_phy_tx_end_isr(void) PPI_CHEN_CH20_Msk | PPI_CHEN_CH31_Msk); assert(transition == BLE_PHY_TRANSITION_NONE); } + + if (g_ble_phy_data.txend_cb) { + g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg); + } } static inline uint8_t From 886597f223e2ede21f3f66677a7734a227d930fc Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 6 Sep 2022 11:36:22 +0200 Subject: [PATCH 0514/1333] babblesim: Fix EDTT transport nad target --- babblesim/edtt/hci_transport/src/ble_hci_edtt.c | 10 ++++++++-- babblesim/targets/edtthci/syscfg.yml | 2 +- 2 files changed, 9 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 aa70f056a4..5f84fa7b49 100644 --- a/babblesim/edtt/hci_transport/src/ble_hci_edtt.c +++ b/babblesim/edtt/hci_transport/src/ble_hci_edtt.c @@ -142,7 +142,7 @@ ble_hci_edtt_cmdevt_tx(uint8_t *hci_ev, uint8_t edtt_type) * A BLE_ERR_[...] error code on failure. */ int -ble_transport_to_hs_evt(void *buf) +ble_transport_to_hs_evt_impl(void *buf) { return ble_hci_edtt_cmdevt_tx(buf, BLE_HCI_EDTT_EVT); } @@ -156,11 +156,17 @@ ble_transport_to_hs_evt(void *buf) * A BLE_ERR_[...] error code on failure. */ int -ble_transport_to_hs_acl(struct os_mbuf *om) +ble_transport_to_hs_acl_impl(struct os_mbuf *om) { return ble_hci_edtt_acl_tx(om); } +void +ble_transport_hs_init(void) +{ + +} + /** * @brief Clean out excess bytes from the input buffer */ diff --git a/babblesim/targets/edtthci/syscfg.yml b/babblesim/targets/edtthci/syscfg.yml index 972659e39f..0476ccf36b 100644 --- a/babblesim/targets/edtthci/syscfg.yml +++ b/babblesim/targets/edtthci/syscfg.yml @@ -26,6 +26,7 @@ syscfg.vals: EDTT_HCI_LOG_FILE: ("hci_logs") EDTT_HCI_LOGS: 1 + BLE_LL_HCI_VS_EVENT_ON_ASSERT: 0 BLE_LL_CFG_FEAT_LE_ENCRYPTION: 1 BLE_LL_CFG_FEAT_CONN_PARAM_REQ: 1 BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG: 1 @@ -47,7 +48,6 @@ syscfg.vals: BLE_ROLE_OBSERVER: 1 BLE_VERSION: 52 - BLE_CONTROLLER: 1 BLE_LL_ROLE_CENTRAL: 1 BLE_LL_ROLE_PERIPHERAL: 1 BLE_LL_ROLE_BROADCASTER: 1 From e74371c06f4408124822901c82d493dbaa98cd10 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 7 Sep 2022 21:08:24 +0200 Subject: [PATCH 0515/1333] nimble/ll: Disable vnd assert on BabbleSim BabbleSim does not understand __BKPT(0) and we can simply assert instead. --- nimble/controller/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 827c345126..acd0ef0d0a 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -513,7 +513,7 @@ syscfg.vals.BLE_LL_CFG_FEAT_LL_EXT_ADV: # Enable vendor event on assert in standalone build to make failed assertions in # controller code visible when connected to external host -syscfg.vals.!BLE_HOST: +syscfg.vals.'!BLE_HOST && !BABBLESIM': BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 syscfg.restrictions: From 0b983a52d5361927e23f48bc6608387510597740 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 7 Sep 2022 21:09:11 +0200 Subject: [PATCH 0516/1333] babblesim: Fix blehci target --- babblesim/targets/blehci/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/babblesim/targets/blehci/syscfg.yml b/babblesim/targets/blehci/syscfg.yml index aec4c4a4ab..14a909e913 100644 --- a/babblesim/targets/blehci/syscfg.yml +++ b/babblesim/targets/blehci/syscfg.yml @@ -18,4 +18,4 @@ syscfg.vals: BLE_LL_PUBLIC_DEV_ADDR: 0xbabb1e000001 - BLE_HCI_TRANSPORT: uart + BLE_HCI_TRANSPORT_HS: uart From 12bd3d1e8bafb16797ffe585398fa2082d131d2a Mon Sep 17 00:00:00 2001 From: Jakub Date: Mon, 29 Aug 2022 17:35:38 +0200 Subject: [PATCH 0517/1333] tools/hci_throughput: updated README.md file, help descriptions --- tools/hci_throughput/README.md | 23 ++++++++++++++--------- tools/hci_throughput/check_addr.py | 14 ++++++-------- tools/hci_throughput/config.yaml.sample | 2 +- tools/hci_throughput/hci_device.py | 8 ++++---- tools/hci_throughput/init.yaml.sample | 2 ++ tools/hci_throughput/main.py | 11 ++++++----- 6 files changed, 33 insertions(+), 27 deletions(-) diff --git a/tools/hci_throughput/README.md b/tools/hci_throughput/README.md index aa6652f1f9..1e153928a9 100644 --- a/tools/hci_throughput/README.md +++ b/tools/hci_throughput/README.md @@ -13,9 +13,9 @@ sudo pip install -r requirements.txt ## Usage ### Prepare devices -This tool may be used with existing controller or with any board with ```blehci``` app. +This tool may be used with the existing controller or with any board with ```blehci``` app. - - If you want to use builtin PC controller, provide HCI index of the controller. Turn the Bluetooth ON on your device, run ```hciconfig``` in the terminal and get the HCI index. In the case below HCI index is equal to 0: + - If you want to use the builtin PC controller, provide HCI index of the controller. Turn the Bluetooth ON on your device, run ```hciconfig``` in the terminal and get the HCI index. In the case below HCI index is equal to 0: ``` user@user:~$ hciconfig @@ -27,21 +27,26 @@ hci0: Type: Primary Bus: USB ``` - If you want to use the nimble controller, create the image and load the provided target (can be found under ```/targets``` for NRF52840 and NRF52832). - - NRF52840 may use USB or UART transport. The target is configured for USB by default. - - NRF52832 uses UART as transport. This requires some additional configuration. Get the tty path and run in the terminal: + - NRF52840 may use USB or UART as HCI transport. The target is configured for USB by default. + - NRF52832 uses UART as HCI transport. This requires some additional configuration. Get the tty path and run in the terminal: ``` sudo btattach -B /dev/ttyACM0 -S 1000000 ``` Then proceed with ```hciconfig``` as shown above. ### Run tests -This tool opens a raw socket which requires running all scripts as ```sudo```. Copy the ```config.yaml.sample``` file, change the name to ```config.yaml``` and fill the parameters. Run ```main.py``` as shown below: + + +This tool opens a raw socket which requires running all scripts as ```sudo```. Copy the ```config.yaml.sample``` file, change the name to ```config.yaml``` and fill the parameters. +Optionally pass the path to the custom transport directory if used. Run ```main.py``` as shown below: ``` -sudo python main.py -i -m rx tx -cf config.yaml +sudo python main.py -i -m rx tx -t -cf config.yaml ``` -Switch `````` and `````` to corresponding hci indexes present in your computer. ```-m``` and ```-cf``` may be omitted if the defaults are correct. \ +Switch `````` and `````` to corresponding hci indexes present in your computer. ```-m```, ```-t``` and ```-cf``` may be omitted if the defaults are correct. \ The output provides the plots of measured throughput in ```kb``` or ```kB``` as predefined in ```config.yaml```. In addition to the throughput plots, when the ```flag_plot_packets``` is turned on, the number of packets transmitted/received in time is visualized. +**_When encountering issues with running tests, try to investigate the files in the log folder._** + #### Set ```config.yaml``` file To run **once** the throughput measurement with given parameters, set the ```flag_testing``` to false. ``` @@ -93,9 +98,9 @@ sudo python hci_device.py -m tx -if init.yaml ``` ### Check addr sub-tool -When given hci indexes, ```check_addr.py``` returns devices' address types and addresses. +When given hci indexes, ```check_addr.py``` returns devices' address types and addresses. Optionally pass the path to the custom transport directory if used. ``` -sudo python check_addr.py -i ... +sudo python check_addr.py -i ... -t ``` ### Throughput sub-tool diff --git a/tools/hci_throughput/check_addr.py b/tools/hci_throughput/check_addr.py index 4569131887..ce2a944651 100644 --- a/tools/hci_throughput/check_addr.py +++ b/tools/hci_throughput/check_addr.py @@ -32,16 +32,14 @@ def parse_arguments(): parser = argparse.ArgumentParser( description='Check HCI device address type and address', epilog='How to run script: \ - sudo python check_addr.py -i 0 1 2') + sudo python check_addr.py -i 0 1 2 \ + -t path/to/custom_transport_dir') parser.add_argument('-i', '--indexes', type=str, nargs='*', help='specify hci adapters indexes', default=0) - parser.add_argument( - '-t', - '--transport_directory', - type=str, - nargs='*', - help='specify hci transport directory path', - default="default") + parser.add_argument('-t', '--transport_directory', type=str, nargs='*', + help='specify hci transport directory path. \ + Use for transport other than the default linux socket.', + default=["default"]) try: args = parser.parse_args() if (isinstance(args.transport_directory, list)): diff --git a/tools/hci_throughput/config.yaml.sample b/tools/hci_throughput/config.yaml.sample index 68068e3e7e..6d5dcbcf8a 100644 --- a/tools/hci_throughput/config.yaml.sample +++ b/tools/hci_throughput/config.yaml.sample @@ -43,7 +43,7 @@ adv: peer_address: 00:00:00:00:00:00 advertising_channel_map: 7 advertising_filter_policy: 0 -enable_encryption: true +enable_encryption: false conn: le_scan_interval: 2400 le_scan_window: 2400 diff --git a/tools/hci_throughput/hci_device.py b/tools/hci_throughput/hci_device.py index b054b70502..b634d54930 100644 --- a/tools/hci_throughput/hci_device.py +++ b/tools/hci_throughput/hci_device.py @@ -44,13 +44,13 @@ class ParentCalledException(KeyboardInterrupt): def parse_arguments(): parser = argparse.ArgumentParser( - description='HCI device with User Channel Socket', - epilog='Start a device according to predefined mode (receiver/transmitter). \ + description='HCI device with User Channel Socket. \ + Start a device according to predefined mode (receiver/transmitter). \ The initialization of the device is based on received parameters \ or predefined init.yaml and config.yaml files.\ The tx device will try to connect to rx device and send data. \ - After completion the throughput plots will pop up. \ - How to run the python scripts, first specifying all params: \ + After completion the throughput plots will pop up. ', + epilog='How to run the python script: \ sudo python hci_device.py -m rx -oa 00:00:00:00:00:00 -oat 0 -di 0 \ -pa 00:00:00:00:00:00 -pat 0 -pdi 0 -cf config.yaml\ or, if present, specifying init.yaml file \ diff --git a/tools/hci_throughput/init.yaml.sample b/tools/hci_throughput/init.yaml.sample index ec17522767..f097d9cf2c 100644 --- a/tools/hci_throughput/init.yaml.sample +++ b/tools/hci_throughput/init.yaml.sample @@ -32,3 +32,5 @@ tx: peer_address_type: 1 peer_address: C0:0D:A5:1A:98:EF test_dir: /path/to/blehci_throughput/tests/Mon_May_23_12:29:10_2022 +transport_directory: default or /path/to/custom_transport.py +ltk: '0xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' \ No newline at end of file diff --git a/tools/hci_throughput/main.py b/tools/hci_throughput/main.py index 565cce426c..1f9d6e1518 100644 --- a/tools/hci_throughput/main.py +++ b/tools/hci_throughput/main.py @@ -36,10 +36,10 @@ def parse_arguments(): parser = argparse.ArgumentParser( - description='Measure throughput', - epilog='How to run python scripts: \ - sudo python main.py -i 0 1 -m rx tx -cf config.yaml\ - then hci0 -> rx and hci1 -> tx') + description='App for measuring BLE throughput over ACL.', + epilog='How to run python script for hci0 -> rx and hci1 -> tx: \ + sudo python main.py -i 0 1 -m rx tx \ + -t path/to/custom_transport_directory -cf config.yaml') parser.add_argument('-i', '--indexes', type=str, nargs='*', help='specify adapters indexes', default=[0, 1]) parser.add_argument('-m', '--modes', type=str, nargs="*", @@ -47,7 +47,8 @@ def parse_arguments(): choices=['rx', 'tx'], default=['rx', 'tx']) parser.add_argument('-t', '--transport_directory', type=str, nargs='*', help='specify hci transport directory path. \ - The default is linux socket', default=["default"]) + Use for transport other than the default linux socket.', + default=["default"]) parser.add_argument('-cf', '--config_file', type=str, nargs="*", help='configuration file for devices', default=["config.yaml"]) From fbe82de8f7abf7d8b701a01592598ccbd3fb3c9b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 5 Sep 2022 09:30:24 +0200 Subject: [PATCH 0518/1333] nimble/ll: Set default ACL buffer size to 251 This controls only data part of packet and thus should not include ACL header size. Set default to 251 to avoid unnecessary packets fragmentation. --- nimble/transport/syscfg.yml | 2 +- tools/hci_throughput/targets/nordic_pca10040_blehci/syscfg.yml | 1 - tools/hci_throughput/targets/nordic_pca10056_blehci/syscfg.yml | 1 - tools/hci_throughput/targets/nordic_pca10059_blehci/syscfg.yml | 1 - .../targets/nordic_pca10095_app_blehci/syscfg.yml | 1 - .../targets/nordic_pca10095_net_blehci/syscfg.yml | 1 - 6 files changed, 1 insertion(+), 6 deletions(-) diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml index a4ae6d56fc..becd81d617 100644 --- a/nimble/transport/syscfg.yml +++ b/nimble/transport/syscfg.yml @@ -57,7 +57,7 @@ syscfg.defs: value: 10 BLE_TRANSPORT_ACL_SIZE: description: Size of each buffer in ACL pool. - value: 255 + value: 251 BLE_TRANSPORT_EVT_COUNT: description: > Number of event buffers available in transport. diff --git a/tools/hci_throughput/targets/nordic_pca10040_blehci/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10040_blehci/syscfg.yml index 4de2fdd2c2..1c2bbee274 100644 --- a/tools/hci_throughput/targets/nordic_pca10040_blehci/syscfg.yml +++ b/tools/hci_throughput/targets/nordic_pca10040_blehci/syscfg.yml @@ -24,5 +24,4 @@ syscfg.vals: MSYS_1_BLOCK_COUNT: 80 MSYS_1_BLOCK_SIZE: 308 BLE_TRANSPORT_ACL_COUNT: 80 - BLE_TRANSPORT_ACL_SIZE: 255 diff --git a/tools/hci_throughput/targets/nordic_pca10056_blehci/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10056_blehci/syscfg.yml index 61f14a788c..1c65d055bb 100644 --- a/tools/hci_throughput/targets/nordic_pca10056_blehci/syscfg.yml +++ b/tools/hci_throughput/targets/nordic_pca10056_blehci/syscfg.yml @@ -29,4 +29,3 @@ syscfg.vals: MSYS_1_BLOCK_COUNT: 80 MSYS_1_BLOCK_SIZE: 308 BLE_TRANSPORT_ACL_COUNT: 80 - BLE_TRANSPORT_ACL_SIZE: 255 \ No newline at end of file diff --git a/tools/hci_throughput/targets/nordic_pca10059_blehci/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10059_blehci/syscfg.yml index f27e8c0b85..6fc26b9db1 100644 --- a/tools/hci_throughput/targets/nordic_pca10059_blehci/syscfg.yml +++ b/tools/hci_throughput/targets/nordic_pca10059_blehci/syscfg.yml @@ -29,4 +29,3 @@ syscfg.vals: MSYS_1_BLOCK_COUNT: 80 MSYS_1_BLOCK_SIZE: 308 BLE_TRANSPORT_ACL_COUNT: 80 - BLE_TRANSPORT_ACL_SIZE: 255 \ No newline at end of file diff --git a/tools/hci_throughput/targets/nordic_pca10095_app_blehci/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10095_app_blehci/syscfg.yml index ad3399349e..c7ff62bba0 100644 --- a/tools/hci_throughput/targets/nordic_pca10095_app_blehci/syscfg.yml +++ b/tools/hci_throughput/targets/nordic_pca10095_app_blehci/syscfg.yml @@ -33,7 +33,6 @@ syscfg.vals: USBD_WINDOWS_COMP_ID: 1 BLE_TRANSPORT_ACL_COUNT: 80 - BLE_TRANSPORT_ACL_SIZE: 255 MSYS_1_BLOCK_COUNT: 80 MSYS_1_BLOCK_SIZE: 308 IPC_NRF5340_BUF_SZ: 3072 diff --git a/tools/hci_throughput/targets/nordic_pca10095_net_blehci/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10095_net_blehci/syscfg.yml index a086199a63..7f0b5b60f8 100644 --- a/tools/hci_throughput/targets/nordic_pca10095_net_blehci/syscfg.yml +++ b/tools/hci_throughput/targets/nordic_pca10095_net_blehci/syscfg.yml @@ -28,7 +28,6 @@ syscfg.vals: BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 BLE_TRANSPORT_ACL_COUNT: 80 - BLE_TRANSPORT_ACL_SIZE: 255 MSYS_1_BLOCK_COUNT: 80 MSYS_1_BLOCK_SIZE: 308 IPC_NRF5340_BUF_SZ: 3072 From 60b51b0b80ae4335e0391d4b2d1161c031658523 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 5 Sep 2022 09:36:41 +0200 Subject: [PATCH 0519/1333] nimble/ports: Refresh syscfg --- .../examples/linux/include/logcfg/logcfg.h | 2 +- .../examples/linux/include/syscfg/syscfg.h | 117 ++++++++------- .../linux/include/sysflash/sysflash.h | 25 +++- .../linux_blemesh/include/logcfg/logcfg.h | 2 +- .../linux_blemesh/include/syscfg/syscfg.h | 119 ++++++++------- .../linux_blemesh/include/sysflash/sysflash.h | 25 +++- .../examples/nuttx/include/logcfg/logcfg.h | 2 +- .../examples/nuttx/include/syscfg/syscfg.h | 117 ++++++++------- .../nuttx/include/sysflash/sysflash.h | 25 +++- porting/nimble/include/logcfg/logcfg.h | 2 +- porting/nimble/include/syscfg/syscfg.h | 117 ++++++++------- porting/nimble/include/sysflash/sysflash.h | 25 +++- porting/npl/riot/include/logcfg/logcfg.h | 2 +- porting/npl/riot/include/syscfg/syscfg.h | 136 +++++++++++------- porting/npl/riot/include/sysflash/sysflash.h | 25 +++- 15 files changed, 461 insertions(+), 280 deletions(-) diff --git a/porting/examples/linux/include/logcfg/logcfg.h b/porting/examples/linux/include/logcfg/logcfg.h index fab4d812fc..89af353092 100644 --- a/porting/examples/linux/include/logcfg/logcfg.h +++ b/porting/examples/linux/include/logcfg/logcfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.10.0-dev + * This file was generated by Apache newt version: 1.11.0-dev */ #ifndef H_MYNEWT_LOGCFG_ diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index 65aa24ebbb..3ba53c20e5 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.10.0-dev + * This file was generated by Apache newt version: 1.11.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -20,7 +20,7 @@ #endif #ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME -#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME ("trng") +#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME "trng" #endif #ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG @@ -315,7 +315,7 @@ #endif #ifndef MYNEWT_VAL_CONSOLE_UART_DEV -#define MYNEWT_VAL_CONSOLE_UART_DEV ("uart0") +#define MYNEWT_VAL_CONSOLE_UART_DEV "uart0" #endif #ifndef MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL @@ -474,6 +474,10 @@ #define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER (0) #endif +#ifndef MYNEWT_VAL_BLE_POWER_CONTROL +#define MYNEWT_VAL_BLE_POWER_CONTROL (0) +#endif + #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif @@ -498,10 +502,6 @@ #define MYNEWT_VAL_BLE_WHITELIST (1) #endif -#ifndef MYNEWT_VAL_BLE_POWER_CONTROL -#define MYNEWT_VAL_BLE_POWER_CONTROL (0) -#endif - /*** @apache-mynewt-nimble/nimble/host */ #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) @@ -743,42 +743,6 @@ #define MYNEWT_VAL_BLE_MESH (0) #endif -#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE -#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT -#define MYNEWT_VAL_BLE_MONITOR_RTT (0) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME ("btmonitor") -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART -#define MYNEWT_VAL_BLE_MONITOR_UART (0) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE -#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE -#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV -#define MYNEWT_VAL_BLE_MONITOR_UART_DEV ("uart0") -#endif - #ifndef MYNEWT_VAL_BLE_RPA_TIMEOUT #define MYNEWT_VAL_BLE_RPA_TIMEOUT (300) #endif @@ -799,6 +763,10 @@ #define MYNEWT_VAL_BLE_SM_LEGACY (1) #endif +#ifndef MYNEWT_VAL_BLE_SM_LVL +#define MYNEWT_VAL_BLE_SM_LVL (0) +#endif + #ifndef MYNEWT_VAL_BLE_SM_MAX_PROCS #define MYNEWT_VAL_BLE_SM_MAX_PROCS (1) #endif @@ -823,10 +791,6 @@ #define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_LVL -#define MYNEWT_VAL_BLE_SM_LVL (0) -#endif - #ifndef MYNEWT_VAL_BLE_SM_SC_ONLY #define MYNEWT_VAL_BLE_SM_SC_ONLY (0) #endif @@ -902,7 +866,7 @@ #endif #ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT -#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT ("Apache Mynewt NimBLE") +#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT "Apache Mynewt NimBLE" #endif #ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_READ_PERM @@ -954,7 +918,7 @@ #endif #ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME -#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME ("nimble") +#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME "nimble" #endif #ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH @@ -1025,6 +989,42 @@ #undef MYNEWT_VAL_BLE_HCI_TRANSPORT +#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT +#define MYNEWT_VAL_BLE_MONITOR_RTT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME "btmonitor" +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART +#define MYNEWT_VAL_BLE_MONITOR_UART (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE +#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV +#define MYNEWT_VAL_BLE_MONITOR_UART_DEV "uart0" +#endif + #ifndef MYNEWT_VAL_BLE_TRANSPORT #define MYNEWT_VAL_BLE_TRANSPORT (1) #endif @@ -1044,7 +1044,7 @@ #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE -#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (255) +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (251) #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT @@ -1060,6 +1060,9 @@ #define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (257) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__cdc +#define MYNEWT_VAL_BLE_TRANSPORT_HS__cdc (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__custom #define MYNEWT_VAL_BLE_TRANSPORT_HS__custom (0) #endif @@ -1083,12 +1086,18 @@ #endif /* Overridden by @apache-mynewt-nimble/porting/targets/linux (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 +#define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__custom #define MYNEWT_VAL_BLE_TRANSPORT_LL__custom (0) #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac #define MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac (0) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__emspi +#define MYNEWT_VAL_BLE_TRANSPORT_LL__emspi (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__native #define MYNEWT_VAL_BLE_TRANSPORT_LL__native (0) #endif @@ -1141,7 +1150,7 @@ /*** newt */ #ifndef MYNEWT_VAL_APP_NAME -#define MYNEWT_VAL_APP_NAME ("dummy_app") +#define MYNEWT_VAL_APP_NAME "dummy_app" #endif #ifndef MYNEWT_VAL_APP_dummy_app @@ -1149,7 +1158,7 @@ #endif #ifndef MYNEWT_VAL_ARCH_NAME -#define MYNEWT_VAL_ARCH_NAME ("sim") +#define MYNEWT_VAL_ARCH_NAME "sim" #endif #ifndef MYNEWT_VAL_ARCH_sim @@ -1157,7 +1166,7 @@ #endif #ifndef MYNEWT_VAL_BSP_NAME -#define MYNEWT_VAL_BSP_NAME ("native") +#define MYNEWT_VAL_BSP_NAME "native" #endif #ifndef MYNEWT_VAL_BSP_native @@ -1173,7 +1182,7 @@ #endif #ifndef MYNEWT_VAL_TARGET_NAME -#define MYNEWT_VAL_TARGET_NAME ("linux") +#define MYNEWT_VAL_TARGET_NAME "linux" #endif #ifndef MYNEWT_VAL_TARGET_linux diff --git a/porting/examples/linux/include/sysflash/sysflash.h b/porting/examples/linux/include/sysflash/sysflash.h index 28391ca66a..8d358ac99a 100644 --- a/porting/examples/linux/include/sysflash/sysflash.h +++ b/porting/examples/linux/include/sysflash/sysflash.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.10.0-dev + * This file was generated by Apache newt version: 1.11.0-dev */ #ifndef H_MYNEWT_SYSFLASH_ @@ -15,10 +15,33 @@ extern const struct flash_area sysflash_map_dflt[6]; #define FLASH_AREA_BOOTLOADER 0 +#define FLASH_AREA_BOOTLOADER_DEVICE 0 +#define FLASH_AREA_BOOTLOADER_OFFSET 0x00000000 +#define FLASH_AREA_BOOTLOADER_SIZE 16384 + #define FLASH_AREA_IMAGE_0 1 +#define FLASH_AREA_IMAGE_0_DEVICE 0 +#define FLASH_AREA_IMAGE_0_OFFSET 0x00020000 +#define FLASH_AREA_IMAGE_0_SIZE 393216 + #define FLASH_AREA_IMAGE_1 2 +#define FLASH_AREA_IMAGE_1_DEVICE 0 +#define FLASH_AREA_IMAGE_1_OFFSET 0x00080000 +#define FLASH_AREA_IMAGE_1_SIZE 393216 + #define FLASH_AREA_IMAGE_SCRATCH 3 +#define FLASH_AREA_IMAGE_SCRATCH_DEVICE 0 +#define FLASH_AREA_IMAGE_SCRATCH_OFFSET 0x000e0000 +#define FLASH_AREA_IMAGE_SCRATCH_SIZE 131072 + #define FLASH_AREA_REBOOT_LOG 16 +#define FLASH_AREA_REBOOT_LOG_DEVICE 0 +#define FLASH_AREA_REBOOT_LOG_OFFSET 0x00004000 +#define FLASH_AREA_REBOOT_LOG_SIZE 16384 + #define FLASH_AREA_NFFS 17 +#define FLASH_AREA_NFFS_DEVICE 0 +#define FLASH_AREA_NFFS_OFFSET 0x00008000 +#define FLASH_AREA_NFFS_SIZE 32768 #endif diff --git a/porting/examples/linux_blemesh/include/logcfg/logcfg.h b/porting/examples/linux_blemesh/include/logcfg/logcfg.h index c3b5cdf400..520c658c6b 100644 --- a/porting/examples/linux_blemesh/include/logcfg/logcfg.h +++ b/porting/examples/linux_blemesh/include/logcfg/logcfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.10.0-dev + * This file was generated by Apache newt version: 1.11.0-dev */ #ifndef H_MYNEWT_LOGCFG_ diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 9fdaff3dfc..019cafac7d 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.10.0-dev + * This file was generated by Apache newt version: 1.11.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -20,7 +20,7 @@ #endif #ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME -#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME ("trng") +#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME "trng" #endif #ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG @@ -316,7 +316,7 @@ #endif #ifndef MYNEWT_VAL_CONSOLE_UART_DEV -#define MYNEWT_VAL_CONSOLE_UART_DEV ("uart0") +#define MYNEWT_VAL_CONSOLE_UART_DEV "uart0" #endif #ifndef MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL @@ -475,6 +475,10 @@ #define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER (0) #endif +#ifndef MYNEWT_VAL_BLE_POWER_CONTROL +#define MYNEWT_VAL_BLE_POWER_CONTROL (0) +#endif + #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif @@ -499,10 +503,6 @@ #define MYNEWT_VAL_BLE_WHITELIST (1) #endif -#ifndef MYNEWT_VAL_BLE_POWER_CONTROL -#define MYNEWT_VAL_BLE_POWER_CONTROL (0) -#endif - /*** @apache-mynewt-nimble/nimble/host */ #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) @@ -745,42 +745,6 @@ #define MYNEWT_VAL_BLE_MESH (1) #endif -#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE -#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT -#define MYNEWT_VAL_BLE_MONITOR_RTT (0) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME ("btmonitor") -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART -#define MYNEWT_VAL_BLE_MONITOR_UART (0) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE -#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE -#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV -#define MYNEWT_VAL_BLE_MONITOR_UART_DEV ("uart0") -#endif - #ifndef MYNEWT_VAL_BLE_RPA_TIMEOUT #define MYNEWT_VAL_BLE_RPA_TIMEOUT (300) #endif @@ -801,6 +765,10 @@ #define MYNEWT_VAL_BLE_SM_LEGACY (1) #endif +#ifndef MYNEWT_VAL_BLE_SM_LVL +#define MYNEWT_VAL_BLE_SM_LVL (0) +#endif + #ifndef MYNEWT_VAL_BLE_SM_MAX_PROCS #define MYNEWT_VAL_BLE_SM_MAX_PROCS (1) #endif @@ -826,10 +794,6 @@ #define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_LVL -#define MYNEWT_VAL_BLE_SM_LVL (0) -#endif - #ifndef MYNEWT_VAL_BLE_SM_SC_ONLY #define MYNEWT_VAL_BLE_SM_SC_ONLY (0) #endif @@ -959,7 +923,7 @@ #endif #ifndef MYNEWT_VAL_BLE_MESH_DEVICE_NAME -#define MYNEWT_VAL_BLE_MESH_DEVICE_NAME ("nimble-mesh-node") +#define MYNEWT_VAL_BLE_MESH_DEVICE_NAME "nimble-mesh-node" #endif #ifndef MYNEWT_VAL_BLE_MESH_DEV_UUID @@ -1477,7 +1441,7 @@ #endif #ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT -#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT ("Apache Mynewt NimBLE") +#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT "Apache Mynewt NimBLE" #endif #ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_READ_PERM @@ -1529,7 +1493,7 @@ #endif #ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME -#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME ("nimble") +#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME "nimble" #endif #ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH @@ -1600,6 +1564,42 @@ #undef MYNEWT_VAL_BLE_HCI_TRANSPORT +#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT +#define MYNEWT_VAL_BLE_MONITOR_RTT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME "btmonitor" +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART +#define MYNEWT_VAL_BLE_MONITOR_UART (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE +#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV +#define MYNEWT_VAL_BLE_MONITOR_UART_DEV "uart0" +#endif + #ifndef MYNEWT_VAL_BLE_TRANSPORT #define MYNEWT_VAL_BLE_TRANSPORT (1) #endif @@ -1619,7 +1619,7 @@ #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE -#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (255) +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (251) #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT @@ -1635,6 +1635,9 @@ #define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (257) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__cdc +#define MYNEWT_VAL_BLE_TRANSPORT_HS__cdc (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__custom #define MYNEWT_VAL_BLE_TRANSPORT_HS__custom (0) #endif @@ -1658,12 +1661,18 @@ #endif /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 +#define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__custom #define MYNEWT_VAL_BLE_TRANSPORT_LL__custom (0) #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac #define MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac (0) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__emspi +#define MYNEWT_VAL_BLE_TRANSPORT_LL__emspi (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__native #define MYNEWT_VAL_BLE_TRANSPORT_LL__native (0) #endif @@ -1716,7 +1725,7 @@ /*** newt */ #ifndef MYNEWT_VAL_APP_NAME -#define MYNEWT_VAL_APP_NAME ("dummy_app") +#define MYNEWT_VAL_APP_NAME "dummy_app" #endif #ifndef MYNEWT_VAL_APP_dummy_app @@ -1724,7 +1733,7 @@ #endif #ifndef MYNEWT_VAL_ARCH_NAME -#define MYNEWT_VAL_ARCH_NAME ("sim") +#define MYNEWT_VAL_ARCH_NAME "sim" #endif #ifndef MYNEWT_VAL_ARCH_sim @@ -1732,7 +1741,7 @@ #endif #ifndef MYNEWT_VAL_BSP_NAME -#define MYNEWT_VAL_BSP_NAME ("native") +#define MYNEWT_VAL_BSP_NAME "native" #endif #ifndef MYNEWT_VAL_BSP_native @@ -1748,7 +1757,7 @@ #endif #ifndef MYNEWT_VAL_TARGET_NAME -#define MYNEWT_VAL_TARGET_NAME ("linux_blemesh") +#define MYNEWT_VAL_TARGET_NAME "linux_blemesh" #endif #ifndef MYNEWT_VAL_TARGET_linux_blemesh diff --git a/porting/examples/linux_blemesh/include/sysflash/sysflash.h b/porting/examples/linux_blemesh/include/sysflash/sysflash.h index 28391ca66a..8d358ac99a 100644 --- a/porting/examples/linux_blemesh/include/sysflash/sysflash.h +++ b/porting/examples/linux_blemesh/include/sysflash/sysflash.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.10.0-dev + * This file was generated by Apache newt version: 1.11.0-dev */ #ifndef H_MYNEWT_SYSFLASH_ @@ -15,10 +15,33 @@ extern const struct flash_area sysflash_map_dflt[6]; #define FLASH_AREA_BOOTLOADER 0 +#define FLASH_AREA_BOOTLOADER_DEVICE 0 +#define FLASH_AREA_BOOTLOADER_OFFSET 0x00000000 +#define FLASH_AREA_BOOTLOADER_SIZE 16384 + #define FLASH_AREA_IMAGE_0 1 +#define FLASH_AREA_IMAGE_0_DEVICE 0 +#define FLASH_AREA_IMAGE_0_OFFSET 0x00020000 +#define FLASH_AREA_IMAGE_0_SIZE 393216 + #define FLASH_AREA_IMAGE_1 2 +#define FLASH_AREA_IMAGE_1_DEVICE 0 +#define FLASH_AREA_IMAGE_1_OFFSET 0x00080000 +#define FLASH_AREA_IMAGE_1_SIZE 393216 + #define FLASH_AREA_IMAGE_SCRATCH 3 +#define FLASH_AREA_IMAGE_SCRATCH_DEVICE 0 +#define FLASH_AREA_IMAGE_SCRATCH_OFFSET 0x000e0000 +#define FLASH_AREA_IMAGE_SCRATCH_SIZE 131072 + #define FLASH_AREA_REBOOT_LOG 16 +#define FLASH_AREA_REBOOT_LOG_DEVICE 0 +#define FLASH_AREA_REBOOT_LOG_OFFSET 0x00004000 +#define FLASH_AREA_REBOOT_LOG_SIZE 16384 + #define FLASH_AREA_NFFS 17 +#define FLASH_AREA_NFFS_DEVICE 0 +#define FLASH_AREA_NFFS_OFFSET 0x00008000 +#define FLASH_AREA_NFFS_SIZE 32768 #endif diff --git a/porting/examples/nuttx/include/logcfg/logcfg.h b/porting/examples/nuttx/include/logcfg/logcfg.h index fab4d812fc..89af353092 100644 --- a/porting/examples/nuttx/include/logcfg/logcfg.h +++ b/porting/examples/nuttx/include/logcfg/logcfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.10.0-dev + * This file was generated by Apache newt version: 1.11.0-dev */ #ifndef H_MYNEWT_LOGCFG_ diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index fd9f45613d..040a1b3d60 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.10.0-dev + * This file was generated by Apache newt version: 1.11.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -20,7 +20,7 @@ #endif #ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME -#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME ("trng") +#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME "trng" #endif #ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG @@ -315,7 +315,7 @@ #endif #ifndef MYNEWT_VAL_CONSOLE_UART_DEV -#define MYNEWT_VAL_CONSOLE_UART_DEV ("uart0") +#define MYNEWT_VAL_CONSOLE_UART_DEV "uart0" #endif #ifndef MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL @@ -474,6 +474,10 @@ #define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER (0) #endif +#ifndef MYNEWT_VAL_BLE_POWER_CONTROL +#define MYNEWT_VAL_BLE_POWER_CONTROL (0) +#endif + #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif @@ -498,10 +502,6 @@ #define MYNEWT_VAL_BLE_WHITELIST (1) #endif -#ifndef MYNEWT_VAL_BLE_POWER_CONTROL -#define MYNEWT_VAL_BLE_POWER_CONTROL (0) -#endif - /*** @apache-mynewt-nimble/nimble/host */ #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) @@ -743,42 +743,6 @@ #define MYNEWT_VAL_BLE_MESH (0) #endif -#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE -#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT -#define MYNEWT_VAL_BLE_MONITOR_RTT (0) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME ("btmonitor") -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART -#define MYNEWT_VAL_BLE_MONITOR_UART (0) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE -#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE -#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV -#define MYNEWT_VAL_BLE_MONITOR_UART_DEV ("uart0") -#endif - #ifndef MYNEWT_VAL_BLE_RPA_TIMEOUT #define MYNEWT_VAL_BLE_RPA_TIMEOUT (300) #endif @@ -800,6 +764,10 @@ #define MYNEWT_VAL_BLE_SM_LEGACY (1) #endif +#ifndef MYNEWT_VAL_BLE_SM_LVL +#define MYNEWT_VAL_BLE_SM_LVL (0) +#endif + #ifndef MYNEWT_VAL_BLE_SM_MAX_PROCS #define MYNEWT_VAL_BLE_SM_MAX_PROCS (1) #endif @@ -825,10 +793,6 @@ #define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_LVL -#define MYNEWT_VAL_BLE_SM_LVL (0) -#endif - #ifndef MYNEWT_VAL_BLE_SM_SC_ONLY #define MYNEWT_VAL_BLE_SM_SC_ONLY (0) #endif @@ -904,7 +868,7 @@ #endif #ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT -#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT ("Apache Mynewt NimBLE") +#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT "Apache Mynewt NimBLE" #endif #ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_READ_PERM @@ -956,7 +920,7 @@ #endif #ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME -#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME ("nimble") +#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME "nimble" #endif #ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH @@ -1027,6 +991,42 @@ #undef MYNEWT_VAL_BLE_HCI_TRANSPORT +#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT +#define MYNEWT_VAL_BLE_MONITOR_RTT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME "btmonitor" +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART +#define MYNEWT_VAL_BLE_MONITOR_UART (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE +#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV +#define MYNEWT_VAL_BLE_MONITOR_UART_DEV "uart0" +#endif + #ifndef MYNEWT_VAL_BLE_TRANSPORT #define MYNEWT_VAL_BLE_TRANSPORT (1) #endif @@ -1046,7 +1046,7 @@ #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE -#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (255) +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (251) #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT @@ -1062,6 +1062,9 @@ #define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (257) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__cdc +#define MYNEWT_VAL_BLE_TRANSPORT_HS__cdc (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__custom #define MYNEWT_VAL_BLE_TRANSPORT_HS__custom (0) #endif @@ -1085,12 +1088,18 @@ #endif /* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 +#define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__custom #define MYNEWT_VAL_BLE_TRANSPORT_LL__custom (0) #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac #define MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac (0) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__emspi +#define MYNEWT_VAL_BLE_TRANSPORT_LL__emspi (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__native #define MYNEWT_VAL_BLE_TRANSPORT_LL__native (0) #endif @@ -1143,7 +1152,7 @@ /*** newt */ #ifndef MYNEWT_VAL_APP_NAME -#define MYNEWT_VAL_APP_NAME ("dummy_app") +#define MYNEWT_VAL_APP_NAME "dummy_app" #endif #ifndef MYNEWT_VAL_APP_dummy_app @@ -1151,7 +1160,7 @@ #endif #ifndef MYNEWT_VAL_ARCH_NAME -#define MYNEWT_VAL_ARCH_NAME ("sim") +#define MYNEWT_VAL_ARCH_NAME "sim" #endif #ifndef MYNEWT_VAL_ARCH_sim @@ -1159,7 +1168,7 @@ #endif #ifndef MYNEWT_VAL_BSP_NAME -#define MYNEWT_VAL_BSP_NAME ("native") +#define MYNEWT_VAL_BSP_NAME "native" #endif #ifndef MYNEWT_VAL_BSP_native @@ -1175,7 +1184,7 @@ #endif #ifndef MYNEWT_VAL_TARGET_NAME -#define MYNEWT_VAL_TARGET_NAME ("nuttx") +#define MYNEWT_VAL_TARGET_NAME "nuttx" #endif #ifndef MYNEWT_VAL_TARGET_nuttx diff --git a/porting/examples/nuttx/include/sysflash/sysflash.h b/porting/examples/nuttx/include/sysflash/sysflash.h index 28391ca66a..8d358ac99a 100644 --- a/porting/examples/nuttx/include/sysflash/sysflash.h +++ b/porting/examples/nuttx/include/sysflash/sysflash.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.10.0-dev + * This file was generated by Apache newt version: 1.11.0-dev */ #ifndef H_MYNEWT_SYSFLASH_ @@ -15,10 +15,33 @@ extern const struct flash_area sysflash_map_dflt[6]; #define FLASH_AREA_BOOTLOADER 0 +#define FLASH_AREA_BOOTLOADER_DEVICE 0 +#define FLASH_AREA_BOOTLOADER_OFFSET 0x00000000 +#define FLASH_AREA_BOOTLOADER_SIZE 16384 + #define FLASH_AREA_IMAGE_0 1 +#define FLASH_AREA_IMAGE_0_DEVICE 0 +#define FLASH_AREA_IMAGE_0_OFFSET 0x00020000 +#define FLASH_AREA_IMAGE_0_SIZE 393216 + #define FLASH_AREA_IMAGE_1 2 +#define FLASH_AREA_IMAGE_1_DEVICE 0 +#define FLASH_AREA_IMAGE_1_OFFSET 0x00080000 +#define FLASH_AREA_IMAGE_1_SIZE 393216 + #define FLASH_AREA_IMAGE_SCRATCH 3 +#define FLASH_AREA_IMAGE_SCRATCH_DEVICE 0 +#define FLASH_AREA_IMAGE_SCRATCH_OFFSET 0x000e0000 +#define FLASH_AREA_IMAGE_SCRATCH_SIZE 131072 + #define FLASH_AREA_REBOOT_LOG 16 +#define FLASH_AREA_REBOOT_LOG_DEVICE 0 +#define FLASH_AREA_REBOOT_LOG_OFFSET 0x00004000 +#define FLASH_AREA_REBOOT_LOG_SIZE 16384 + #define FLASH_AREA_NFFS 17 +#define FLASH_AREA_NFFS_DEVICE 0 +#define FLASH_AREA_NFFS_OFFSET 0x00008000 +#define FLASH_AREA_NFFS_SIZE 32768 #endif diff --git a/porting/nimble/include/logcfg/logcfg.h b/porting/nimble/include/logcfg/logcfg.h index fab4d812fc..89af353092 100644 --- a/porting/nimble/include/logcfg/logcfg.h +++ b/porting/nimble/include/logcfg/logcfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.10.0-dev + * This file was generated by Apache newt version: 1.11.0-dev */ #ifndef H_MYNEWT_LOGCFG_ diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index a3602308f9..7eb0856daf 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.10.0-dev + * This file was generated by Apache newt version: 1.11.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -20,7 +20,7 @@ #endif #ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME -#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME ("trng") +#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME "trng" #endif #ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG @@ -315,7 +315,7 @@ #endif #ifndef MYNEWT_VAL_CONSOLE_UART_DEV -#define MYNEWT_VAL_CONSOLE_UART_DEV ("uart0") +#define MYNEWT_VAL_CONSOLE_UART_DEV "uart0" #endif #ifndef MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL @@ -473,6 +473,10 @@ #define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER (0) #endif +#ifndef MYNEWT_VAL_BLE_POWER_CONTROL +#define MYNEWT_VAL_BLE_POWER_CONTROL (0) +#endif + #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif @@ -497,10 +501,6 @@ #define MYNEWT_VAL_BLE_WHITELIST (1) #endif -#ifndef MYNEWT_VAL_BLE_POWER_CONTROL -#define MYNEWT_VAL_BLE_POWER_CONTROL (0) -#endif - /*** @apache-mynewt-nimble/nimble/host */ #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) @@ -742,42 +742,6 @@ #define MYNEWT_VAL_BLE_MESH (0) #endif -#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE -#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT -#define MYNEWT_VAL_BLE_MONITOR_RTT (0) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME ("btmonitor") -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART -#define MYNEWT_VAL_BLE_MONITOR_UART (0) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE -#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE -#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV -#define MYNEWT_VAL_BLE_MONITOR_UART_DEV ("uart0") -#endif - #ifndef MYNEWT_VAL_BLE_RPA_TIMEOUT #define MYNEWT_VAL_BLE_RPA_TIMEOUT (300) #endif @@ -798,6 +762,10 @@ #define MYNEWT_VAL_BLE_SM_LEGACY (1) #endif +#ifndef MYNEWT_VAL_BLE_SM_LVL +#define MYNEWT_VAL_BLE_SM_LVL (0) +#endif + #ifndef MYNEWT_VAL_BLE_SM_MAX_PROCS #define MYNEWT_VAL_BLE_SM_MAX_PROCS (1) #endif @@ -822,10 +790,6 @@ #define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_LVL -#define MYNEWT_VAL_BLE_SM_LVL (0) -#endif - #ifndef MYNEWT_VAL_BLE_SM_SC_ONLY #define MYNEWT_VAL_BLE_SM_SC_ONLY (0) #endif @@ -901,7 +865,7 @@ #endif #ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT -#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT ("Apache Mynewt NimBLE") +#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT "Apache Mynewt NimBLE" #endif #ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_READ_PERM @@ -953,7 +917,7 @@ #endif #ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME -#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME ("nimble") +#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME "nimble" #endif #ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH @@ -1024,6 +988,42 @@ #undef MYNEWT_VAL_BLE_HCI_TRANSPORT +#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT +#define MYNEWT_VAL_BLE_MONITOR_RTT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME "btmonitor" +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART +#define MYNEWT_VAL_BLE_MONITOR_UART (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE +#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV +#define MYNEWT_VAL_BLE_MONITOR_UART_DEV "uart0" +#endif + #ifndef MYNEWT_VAL_BLE_TRANSPORT #define MYNEWT_VAL_BLE_TRANSPORT (1) #endif @@ -1043,7 +1043,7 @@ #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE -#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (255) +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (251) #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT @@ -1059,6 +1059,9 @@ #define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (257) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__cdc +#define MYNEWT_VAL_BLE_TRANSPORT_HS__cdc (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__custom #define MYNEWT_VAL_BLE_TRANSPORT_HS__custom (0) #endif @@ -1082,12 +1085,18 @@ #endif /* Overridden by @apache-mynewt-nimble/porting/targets/porting_default (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 +#define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__custom #define MYNEWT_VAL_BLE_TRANSPORT_LL__custom (0) #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac #define MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac (0) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__emspi +#define MYNEWT_VAL_BLE_TRANSPORT_LL__emspi (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__native #define MYNEWT_VAL_BLE_TRANSPORT_LL__native (0) #endif @@ -1138,7 +1147,7 @@ /*** newt */ #ifndef MYNEWT_VAL_APP_NAME -#define MYNEWT_VAL_APP_NAME ("dummy_app") +#define MYNEWT_VAL_APP_NAME "dummy_app" #endif #ifndef MYNEWT_VAL_APP_dummy_app @@ -1146,7 +1155,7 @@ #endif #ifndef MYNEWT_VAL_ARCH_NAME -#define MYNEWT_VAL_ARCH_NAME ("sim") +#define MYNEWT_VAL_ARCH_NAME "sim" #endif #ifndef MYNEWT_VAL_ARCH_sim @@ -1154,7 +1163,7 @@ #endif #ifndef MYNEWT_VAL_BSP_NAME -#define MYNEWT_VAL_BSP_NAME ("native") +#define MYNEWT_VAL_BSP_NAME "native" #endif #ifndef MYNEWT_VAL_BSP_native @@ -1170,7 +1179,7 @@ #endif #ifndef MYNEWT_VAL_TARGET_NAME -#define MYNEWT_VAL_TARGET_NAME ("porting_default") +#define MYNEWT_VAL_TARGET_NAME "porting_default" #endif #ifndef MYNEWT_VAL_TARGET_porting_default diff --git a/porting/nimble/include/sysflash/sysflash.h b/porting/nimble/include/sysflash/sysflash.h index 28391ca66a..8d358ac99a 100644 --- a/porting/nimble/include/sysflash/sysflash.h +++ b/porting/nimble/include/sysflash/sysflash.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.10.0-dev + * This file was generated by Apache newt version: 1.11.0-dev */ #ifndef H_MYNEWT_SYSFLASH_ @@ -15,10 +15,33 @@ extern const struct flash_area sysflash_map_dflt[6]; #define FLASH_AREA_BOOTLOADER 0 +#define FLASH_AREA_BOOTLOADER_DEVICE 0 +#define FLASH_AREA_BOOTLOADER_OFFSET 0x00000000 +#define FLASH_AREA_BOOTLOADER_SIZE 16384 + #define FLASH_AREA_IMAGE_0 1 +#define FLASH_AREA_IMAGE_0_DEVICE 0 +#define FLASH_AREA_IMAGE_0_OFFSET 0x00020000 +#define FLASH_AREA_IMAGE_0_SIZE 393216 + #define FLASH_AREA_IMAGE_1 2 +#define FLASH_AREA_IMAGE_1_DEVICE 0 +#define FLASH_AREA_IMAGE_1_OFFSET 0x00080000 +#define FLASH_AREA_IMAGE_1_SIZE 393216 + #define FLASH_AREA_IMAGE_SCRATCH 3 +#define FLASH_AREA_IMAGE_SCRATCH_DEVICE 0 +#define FLASH_AREA_IMAGE_SCRATCH_OFFSET 0x000e0000 +#define FLASH_AREA_IMAGE_SCRATCH_SIZE 131072 + #define FLASH_AREA_REBOOT_LOG 16 +#define FLASH_AREA_REBOOT_LOG_DEVICE 0 +#define FLASH_AREA_REBOOT_LOG_OFFSET 0x00004000 +#define FLASH_AREA_REBOOT_LOG_SIZE 16384 + #define FLASH_AREA_NFFS 17 +#define FLASH_AREA_NFFS_DEVICE 0 +#define FLASH_AREA_NFFS_OFFSET 0x00008000 +#define FLASH_AREA_NFFS_SIZE 32768 #endif diff --git a/porting/npl/riot/include/logcfg/logcfg.h b/porting/npl/riot/include/logcfg/logcfg.h index fab4d812fc..89af353092 100644 --- a/porting/npl/riot/include/logcfg/logcfg.h +++ b/porting/npl/riot/include/logcfg/logcfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.10.0-dev + * This file was generated by Apache newt version: 1.11.0-dev */ #ifndef H_MYNEWT_LOGCFG_ diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 2d5f4b2ee9..c4055db29d 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.10.0-dev + * This file was generated by Apache newt version: 1.11.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -676,7 +676,7 @@ #endif #ifndef MYNEWT_VAL_CONSOLE_UART_DEV -#define MYNEWT_VAL_CONSOLE_UART_DEV ("uart0") +#define MYNEWT_VAL_CONSOLE_UART_DEV "uart0" #endif #ifndef MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL @@ -834,6 +834,10 @@ #define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER (0) #endif +#ifndef MYNEWT_VAL_BLE_POWER_CONTROL +#define MYNEWT_VAL_BLE_POWER_CONTROL (0) +#endif + #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif @@ -858,10 +862,6 @@ #define MYNEWT_VAL_BLE_WHITELIST (1) #endif -#ifndef MYNEWT_VAL_BLE_POWER_CONTROL -#define MYNEWT_VAL_BLE_POWER_CONTROL (0) -#endif - /*** @apache-mynewt-nimble/nimble/controller */ #ifndef MYNEWT_VAL_BLE_CONTROLLER #define MYNEWT_VAL_BLE_CONTROLLER (1) @@ -915,6 +915,10 @@ #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_PING (MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION) #endif +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE (0) +#endif + /* Value copied from BLE_EXT_ADV */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV (0) @@ -1075,6 +1079,15 @@ #define MYNEWT_VAL_BLE_LL_LNA_GPIO (-1) #endif +#ifndef MYNEWT_VAL_BLE_LL_LNA_TURN_ON_US +#define MYNEWT_VAL_BLE_LL_LNA_TURN_ON_US (1) +#endif + +/* Value copied from BLE_LL_MFRG_ID */ +#ifndef MYNEWT_VAL_BLE_LL_MANUFACTURER_ID +#define MYNEWT_VAL_BLE_LL_MANUFACTURER_ID (0x0B65) +#endif + #ifndef MYNEWT_VAL_BLE_LL_MASTER_SCA #define MYNEWT_VAL_BLE_LL_MASTER_SCA (4) #endif @@ -1084,7 +1097,7 @@ #endif #ifndef MYNEWT_VAL_BLE_LL_MFRG_ID -#define MYNEWT_VAL_BLE_LL_MFRG_ID (0xFFFF) +#define MYNEWT_VAL_BLE_LL_MFRG_ID (0x0B65) #endif #ifndef MYNEWT_VAL_BLE_LL_NUM_COMP_PKT_ITVL_MS @@ -1111,6 +1124,10 @@ #define MYNEWT_VAL_BLE_LL_PA_GPIO (-1) #endif +#ifndef MYNEWT_VAL_BLE_LL_PA_TURN_ON_US +#define MYNEWT_VAL_BLE_LL_PA_TURN_ON_US (1) +#endif + #ifndef MYNEWT_VAL_BLE_LL_PRIO #define MYNEWT_VAL_BLE_LL_PRIO (0) #endif @@ -1178,6 +1195,10 @@ #define MYNEWT_VAL_BLE_LL_SCHED_SCAN_SYNC_PDU_LEN (32) #endif +#ifndef MYNEWT_VAL_BLE_LL_STACK_SIZE +#define MYNEWT_VAL_BLE_LL_STACK_SIZE (120) +#endif + #ifndef MYNEWT_VAL_BLE_LL_STRICT_CONN_SCHEDULING #define MYNEWT_VAL_BLE_LL_STRICT_CONN_SCHEDULING (0) #endif @@ -1502,42 +1523,6 @@ #define MYNEWT_VAL_BLE_MESH (0) #endif -#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE -#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT -#define MYNEWT_VAL_BLE_MONITOR_RTT (0) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME ("btmonitor") -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE -#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART -#define MYNEWT_VAL_BLE_MONITOR_UART (0) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE -#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE -#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64) -#endif - -#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV -#define MYNEWT_VAL_BLE_MONITOR_UART_DEV ("uart0") -#endif - #ifndef MYNEWT_VAL_BLE_RPA_TIMEOUT #define MYNEWT_VAL_BLE_RPA_TIMEOUT (300) #endif @@ -1559,6 +1544,10 @@ #define MYNEWT_VAL_BLE_SM_LEGACY (0) #endif +#ifndef MYNEWT_VAL_BLE_SM_LVL +#define MYNEWT_VAL_BLE_SM_LVL (0) +#endif + #ifndef MYNEWT_VAL_BLE_SM_MAX_PROCS #define MYNEWT_VAL_BLE_SM_MAX_PROCS (1) #endif @@ -1584,10 +1573,6 @@ #define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) #endif -#ifndef MYNEWT_VAL_BLE_SM_LVL -#define MYNEWT_VAL_BLE_SM_LVL (0) -#endif - #ifndef MYNEWT_VAL_BLE_SM_SC_ONLY #define MYNEWT_VAL_BLE_SM_SC_ONLY (0) #endif @@ -1618,7 +1603,7 @@ #endif #ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME -#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME ("nimble") +#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME "nimble" #endif #ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH @@ -1669,6 +1654,42 @@ #undef MYNEWT_VAL_BLE_HCI_TRANSPORT +#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT +#define MYNEWT_VAL_BLE_MONITOR_RTT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME "btmonitor" +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART +#define MYNEWT_VAL_BLE_MONITOR_UART (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE +#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV +#define MYNEWT_VAL_BLE_MONITOR_UART_DEV "uart0" +#endif + #ifndef MYNEWT_VAL_BLE_TRANSPORT #define MYNEWT_VAL_BLE_TRANSPORT (1) #endif @@ -1689,7 +1710,7 @@ #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE -#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (255) +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (251) #endif /* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/transport) */ @@ -1706,6 +1727,9 @@ #define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (257) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__cdc +#define MYNEWT_VAL_BLE_TRANSPORT_HS__cdc (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__custom #define MYNEWT_VAL_BLE_TRANSPORT_HS__custom (0) #endif @@ -1728,12 +1752,18 @@ #define MYNEWT_VAL_BLE_TRANSPORT_HS (1) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 +#define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__custom #define MYNEWT_VAL_BLE_TRANSPORT_LL__custom (0) #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac #define MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac (0) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__emspi +#define MYNEWT_VAL_BLE_TRANSPORT_LL__emspi (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__native #define MYNEWT_VAL_BLE_TRANSPORT_LL__native (1) #endif @@ -1749,7 +1779,7 @@ /*** newt */ #ifndef MYNEWT_VAL_APP_NAME -#define MYNEWT_VAL_APP_NAME ("dummy_app") +#define MYNEWT_VAL_APP_NAME "dummy_app" #endif #ifndef MYNEWT_VAL_APP_dummy_app @@ -1757,7 +1787,7 @@ #endif #ifndef MYNEWT_VAL_ARCH_NAME -#define MYNEWT_VAL_ARCH_NAME ("cortex_m4") +#define MYNEWT_VAL_ARCH_NAME "cortex_m4" #endif #ifndef MYNEWT_VAL_ARCH_cortex_m4 @@ -1765,7 +1795,7 @@ #endif #ifndef MYNEWT_VAL_BSP_NAME -#define MYNEWT_VAL_BSP_NAME ("nordic_pca10056") +#define MYNEWT_VAL_BSP_NAME "nordic_pca10056" #endif #ifndef MYNEWT_VAL_BSP_nordic_pca10056 @@ -1781,7 +1811,7 @@ #endif #ifndef MYNEWT_VAL_TARGET_NAME -#define MYNEWT_VAL_TARGET_NAME ("riot") +#define MYNEWT_VAL_TARGET_NAME "riot" #endif #ifndef MYNEWT_VAL_TARGET_riot diff --git a/porting/npl/riot/include/sysflash/sysflash.h b/porting/npl/riot/include/sysflash/sysflash.h index 28391ca66a..05324aaabc 100644 --- a/porting/npl/riot/include/sysflash/sysflash.h +++ b/porting/npl/riot/include/sysflash/sysflash.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.10.0-dev + * This file was generated by Apache newt version: 1.11.0-dev */ #ifndef H_MYNEWT_SYSFLASH_ @@ -15,10 +15,33 @@ extern const struct flash_area sysflash_map_dflt[6]; #define FLASH_AREA_BOOTLOADER 0 +#define FLASH_AREA_BOOTLOADER_DEVICE 0 +#define FLASH_AREA_BOOTLOADER_OFFSET 0x00000000 +#define FLASH_AREA_BOOTLOADER_SIZE 32768 + #define FLASH_AREA_IMAGE_0 1 +#define FLASH_AREA_IMAGE_0_DEVICE 0 +#define FLASH_AREA_IMAGE_0_OFFSET 0x0000c000 +#define FLASH_AREA_IMAGE_0_SIZE 483328 + #define FLASH_AREA_IMAGE_1 2 +#define FLASH_AREA_IMAGE_1_DEVICE 0 +#define FLASH_AREA_IMAGE_1_OFFSET 0x00082000 +#define FLASH_AREA_IMAGE_1_SIZE 483328 + #define FLASH_AREA_IMAGE_SCRATCH 3 +#define FLASH_AREA_IMAGE_SCRATCH_DEVICE 0 +#define FLASH_AREA_IMAGE_SCRATCH_OFFSET 0x000f8000 +#define FLASH_AREA_IMAGE_SCRATCH_SIZE 16384 + #define FLASH_AREA_REBOOT_LOG 16 +#define FLASH_AREA_REBOOT_LOG_DEVICE 0 +#define FLASH_AREA_REBOOT_LOG_OFFSET 0x00008000 +#define FLASH_AREA_REBOOT_LOG_SIZE 16384 + #define FLASH_AREA_NFFS 17 +#define FLASH_AREA_NFFS_DEVICE 0 +#define FLASH_AREA_NFFS_OFFSET 0x000fc000 +#define FLASH_AREA_NFFS_SIZE 16384 #endif From c562999bc339f5ff73da9cb59471d7c9212943a6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 6 Sep 2022 14:00:16 +0200 Subject: [PATCH 0520/1333] nimble/phy: Add support for variable T_ifs This enables APIs to support variable T_ifs in PHY. By default 150us is used but this value can be changed before each transition. After transition value is reset to default so LL does not need to care about setting T_ifs everywhere. This may be useful for scheduling of related events with tight timings. Disabled by default since it allows for compile-time optimizations. --- .../controller/include/controller/ble_phy.h | 5 +++ nimble/drivers/nrf52/src/ble_phy.c | 39 +++++++++++++++++-- nimble/drivers/nrf52/syscfg.yml | 9 +++++ 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index 3980d344ee..69b259970d 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -87,6 +87,11 @@ int ble_phy_init(void); /* Set the PHY channel */ int ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit); +#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) +/* Set T_ifs time for next transition */ +void ble_phy_tifs_set(uint16_t tifs); +#endif + /* Set transmit start time */ int ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs); diff --git a/nimble/drivers/nrf52/src/ble_phy.c b/nimble/drivers/nrf52/src/ble_phy.c index c4086a2351..eb55c22883 100644 --- a/nimble/drivers/nrf52/src/ble_phy.c +++ b/nimble/drivers/nrf52/src/ble_phy.c @@ -140,6 +140,9 @@ struct ble_phy_obj void *txend_arg; ble_phy_tx_end_func txend_cb; uint32_t phy_start_cputime; +#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) + uint16_t tifs; +#endif }; struct ble_phy_obj g_ble_phy_data; @@ -642,6 +645,26 @@ nrf_wait_disabled(void) } } +#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) +static uint16_t +ble_phy_tifs_get(void) +{ + return g_ble_phy_data.tifs; +} + +void +ble_phy_tifs_set(uint16_t tifs) +{ + g_ble_phy_data.tifs = tifs; +} +#else +static uint16_t +ble_phy_tifs_get(void) +{ + return BLE_LL_IFS; +} +#endif + /** * * @@ -796,7 +819,7 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) if (txrx == BLE_PHY_WFR_ENABLE_TXRX) { /* RX shall start exactly T_IFS after TX end captured in CC[2] */ - end_time = NRF_TIMER0->CC[2] + BLE_LL_IFS; + end_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); /* Adjust for delay between EVENT_END and actual TX end time */ end_time += g_ble_phy_t_txenddelay[tx_phy_mode]; /* Wait a bit longer due to allowed active clock accuracy */ @@ -1015,7 +1038,7 @@ ble_phy_tx_end_isr(void) ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_TXRX, tx_phy_mode, 0); /* Schedule RX exactly T_IFS after TX end captured in CC[2] */ - rx_time = NRF_TIMER0->CC[2] + BLE_LL_IFS; + rx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); /* Adjust for delay between EVENT_END and actual TX end time */ rx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; /* Adjust for radio ramp-up */ @@ -1030,7 +1053,7 @@ ble_phy_tx_end_isr(void) ble_phy_plna_enable_lna(); } else if (transition == BLE_PHY_TRANSITION_TX_TX) { /* Schedule TX exactly T_IFS after TX end captured in CC[2] */ - tx_time = NRF_TIMER0->CC[2] + BLE_LL_IFS; + tx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); /* Adjust for delay between EVENT_END and actual TX end time */ tx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; /* Adjust for radio ramp-up */ @@ -1161,7 +1184,7 @@ ble_phy_rx_end_isr(void) */ /* Schedule TX exactly T_IFS after RX end captured in CC[2] */ - tx_time = NRF_TIMER0->CC[2] + BLE_LL_IFS; + tx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); /* Adjust for delay between actual RX end time and EVENT_END */ tx_time -= g_ble_phy_t_rxenddelay[ble_hdr->rxinfo.phy_mode]; /* Adjust for radio ramp-up */ @@ -1379,6 +1402,10 @@ ble_phy_isr(void) NRF_RADIO->EVENTS_DISABLED = 0; nrf_radio_int_disable(NRF_RADIO, RADIO_INTENCLR_DISABLED_Msk); +#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) + g_ble_phy_data.tifs = BLE_LL_IFS; +#endif + switch (g_ble_phy_data.phy_state) { case BLE_PHY_STATE_RX: #if MYNEWT_VAL(BLE_LL_LNA) @@ -1524,6 +1551,10 @@ ble_phy_init(void) /* Set phy channel to an invalid channel so first set channel works */ g_ble_phy_data.phy_chan = BLE_PHY_NUM_CHANS; +#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) + g_ble_phy_data.tifs = BLE_LL_IFS; +#endif + /* Toggle peripheral power to reset (just in case) */ nrf_radio_power_set(NRF_RADIO, false); nrf_radio_power_set(NRF_RADIO, true); diff --git a/nimble/drivers/nrf52/syscfg.yml b/nimble/drivers/nrf52/syscfg.yml index 3bd49708ca..c3ef5ae1d1 100644 --- a/nimble/drivers/nrf52/syscfg.yml +++ b/nimble/drivers/nrf52/syscfg.yml @@ -17,6 +17,15 @@ # syscfg.defs: + BLE_PHY_VARIABLE_TIFS: + description: > + Enables API to set custom T_ifs (inter-frame spacing) for each + transition. T_ifs is reset to default value after each transition. + When disabled, 150us is always used which enables some build-time + optimizations by compiler. + experimental: 1 + value: 0 + BLE_PHY_SYSVIEW: description: > Enable SystemView tracing module for radio driver. From 1101fecc85a3b87928a7fcf8a5eff11d6716f84b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 9 Sep 2022 12:08:45 +0200 Subject: [PATCH 0521/1333] nimble/ll: Fix txend callback We should call txend before transition as otherwise called code may mess up transition. --- nimble/drivers/nrf52/src/ble_phy.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nimble/drivers/nrf52/src/ble_phy.c b/nimble/drivers/nrf52/src/ble_phy.c index eb55c22883..bfc111b6c9 100644 --- a/nimble/drivers/nrf52/src/ble_phy.c +++ b/nimble/drivers/nrf52/src/ble_phy.c @@ -1025,6 +1025,10 @@ ble_phy_tx_end_isr(void) } #endif + if (g_ble_phy_data.txend_cb) { + g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg); + } + transition = g_ble_phy_data.phy_transition; if (transition == BLE_PHY_TRANSITION_TX_RX) { @@ -1081,10 +1085,6 @@ ble_phy_tx_end_isr(void) PPI_CHEN_CH20_Msk | PPI_CHEN_CH31_Msk); assert(transition == BLE_PHY_TRANSITION_NONE); } - - if (g_ble_phy_data.txend_cb) { - g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg); - } } static inline uint8_t From 2a50a58da6b547622b02fad0ea5cabe3bfa97f9c Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 31 Aug 2022 14:59:19 +0200 Subject: [PATCH 0522/1333] nimble/ll: Rename PLNA to FEM This is in preparation to extend generic API with additions like multiple antenna support which is offered by some FEMs. --- .../{ble_ll_plna.h => ble_ll_fem.h} | 22 +- nimble/controller/pkg.yml | 8 +- nimble/controller/src/ble_ll.c | 10 +- nimble/controller/syscfg.defunct.yml | 24 +++ nimble/controller/syscfg.yml | 30 +-- nimble/drivers/{plna => fem}/sky66112/pkg.yml | 6 +- .../{plna => fem}/sky66112/src/sky66112.c | 14 +- .../drivers/{plna => fem}/sky66112/syscfg.yml | 4 +- nimble/drivers/nrf52/src/ble_phy.c | 88 ++++---- nimble/drivers/nrf5340/src/ble_phy.c | 188 +++++++++--------- 10 files changed, 209 insertions(+), 185 deletions(-) rename nimble/controller/include/controller/{ble_ll_plna.h => ble_ll_fem.h} (73%) rename nimble/drivers/{plna => fem}/sky66112/pkg.yml (92%) rename nimble/drivers/{plna => fem}/sky66112/src/sky66112.c (91%) rename nimble/drivers/{plna => fem}/sky66112/syscfg.yml (97%) diff --git a/nimble/controller/include/controller/ble_ll_plna.h b/nimble/controller/include/controller/ble_ll_fem.h similarity index 73% rename from nimble/controller/include/controller/ble_ll_plna.h rename to nimble/controller/include/controller/ble_ll_fem.h index c4fb65ea98..3d645173db 100644 --- a/nimble/controller/include/controller/ble_ll_plna.h +++ b/nimble/controller/include/controller/ble_ll_fem.h @@ -17,8 +17,8 @@ * under the License. */ -#ifndef H_BLE_LL_PLNA_ -#define H_BLE_LL_PLNA_ +#ifndef H_BLE_LL_FEM_ +#define H_BLE_LL_FEM_ #ifdef __cplusplus extern "C" { @@ -26,20 +26,20 @@ extern "C" { #include "syscfg/syscfg.h" -#if MYNEWT_VAL(BLE_LL_PA) -void ble_ll_plna_pa_init(void); -void ble_ll_plna_pa_enable(void); -void ble_ll_plna_pa_disable(void); +#if MYNEWT_VAL(BLE_LL_FEM_PA) +void ble_ll_fem_pa_init(void); +void ble_ll_fem_pa_enable(void); +void ble_ll_fem_pa_disable(void); #endif -#if MYNEWT_VAL(BLE_LL_LNA) -void ble_ll_plna_lna_init(void); -void ble_ll_plna_lna_enable(void); -void ble_ll_plna_lna_disable(void); +#if MYNEWT_VAL(BLE_LL_FEM_LNA) +void ble_ll_fem_lna_init(void); +void ble_ll_fem_lna_enable(void); +void ble_ll_fem_lna_disable(void); #endif #ifdef __cplusplus } #endif -#endif /* H_BLE_LL_PLNA_ */ +#endif /* H_BLE_LL_FEM_ */ diff --git a/nimble/controller/pkg.yml b/nimble/controller/pkg.yml index 702f3d8932..9115e45289 100644 --- a/nimble/controller/pkg.yml +++ b/nimble/controller/pkg.yml @@ -29,10 +29,10 @@ pkg.req_apis: - ble_driver - ble_transport - stats -pkg.req_apis.BLE_LL_PA: - - ble_ll_pa -pkg.req_apis.BLE_LL_LNA: - - ble_ll_lna +pkg.req_apis.BLE_LL_FEM_PA: + - ble_ll_fem_pa +pkg.req_apis.BLE_LL_FEM_LNA: + - ble_ll_fem_lna pkg.deps: - "@apache-mynewt-core/kernel/os" diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 356bf4afd0..d394bc4f76 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -43,7 +43,7 @@ #include "controller/ble_ll_rfmgmt.h" #include "controller/ble_ll_trace.h" #include "controller/ble_ll_sync.h" -#include "controller/ble_ll_plna.h" +#include "controller/ble_ll_fem.h" #include "ble_ll_conn_priv.h" #include "ble_ll_hci_priv.h" #include "ble_ll_priv.h" @@ -1640,11 +1640,11 @@ ble_ll_reset(void) #endif -#if MYNEWT_VAL(BLE_LL_PA) - ble_ll_plna_pa_init(); +#if MYNEWT_VAL(BLE_LL_FEM_PA) + ble_ll_fem_pa_init(); #endif -#if MYNEWT_VAL(BLE_LL_LNA) - ble_ll_plna_lna_init(); +#if MYNEWT_VAL(BLE_LL_FEM_LNA) + ble_ll_fem_lna_init(); #endif /* Re-initialize the PHY */ diff --git a/nimble/controller/syscfg.defunct.yml b/nimble/controller/syscfg.defunct.yml index 10206da0be..6190c6bc11 100644 --- a/nimble/controller/syscfg.defunct.yml +++ b/nimble/controller/syscfg.defunct.yml @@ -46,6 +46,30 @@ syscfg.defs: description: use BLE_LL_MANUFACTURER_ID value: 0x0B65 deprecated: 1 + BLE_LL_PA: + description: use BLE_LL_FEM_PA + value: 0 + deprecated: 1 + BLE_LL_PA_GPIO: + description: use BLE_LL_FEM_PA_GPIO + value: -1 + deprecated: 1 + BLE_LL_PA_TURN_ON_US: + description: use BLE_LL_FEM_PA_TURN_ON_US + value: 1 + deprecated: 1 + BLE_LL_LNA: + description: use BLE_LL_FEM_LNA + value: 0 + deprecated: 1 + BLE_LL_LNA_GPIO: + description: use BLE_LL_FEM_LNA_GPIO + value: -1 + deprecated: 1 + BLE_LL_LNA_TURN_ON_US: + description: use BLE_LL_FEM_LNA_TURN_ON_US + value: 1 + deprecated: 1 # defunct settings (to be removed eventually) BLE_DEVICE: diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index acd0ef0d0a..11e582c524 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -406,30 +406,30 @@ syscfg.defs: line number where assertion occured. value: MYNEWT_VAL(BLE_LL_VND_EVENT_ON_ASSERT) - BLE_LL_PA: - description: Enable PA support - value: 0 - BLE_LL_PA_GPIO: + BLE_LL_FEM_PA: + description: Enable FEM PA support + value: MYNEWT_VAL(BLE_LL_PA) + BLE_LL_FEM_PA_GPIO: description: > GPIO pin number to control PA. Pin is set to high state when PA should be enabled. - value: -1 - BLE_LL_PA_TURN_ON_US: + value: MYNEWT_VAL(BLE_LL_PA_GPIO) + BLE_LL_FEM_PA_TURN_ON_US: description: > Time required for PA to turn on, in microseconds. - value: 1 - BLE_LL_LNA: + value: MYNEWT_VAL(BLE_LL_PA_TURN_ON_US) + BLE_LL_FEM_LNA: description: Enable LNA support - value: 0 - BLE_LL_LNA_GPIO: + value: MYNEWT_VAL(BLE_LL_LNA) + BLE_LL_FEM_LNA_GPIO: description: > GPIO pin number to control LNA. Pin is set to high state when LNA should be enabled. - value: -1 - BLE_LL_LNA_TURN_ON_US: + value: MYNEWT_VAL(BLE_LL_LNA_GPIO) + BLE_LL_FEM_LNA_TURN_ON_US: description: > Time required for LNA to turn on, in microseconds. - value: 1 + value: MYNEWT_VAL(BLE_LL_LNA_TURN_ON_US) BLE_LL_SYSINIT_STAGE: description: > @@ -519,8 +519,8 @@ syscfg.vals.'!BLE_HOST && !BABBLESIM': syscfg.restrictions: - BLE_TRANSPORT_LL == "native" - BLE_LL_PUBLIC_DEV_ADDR <= 0xffffffffffff - - BLE_LL_PA == 0 || BLE_LL_PA_GPIO >= 0 - - BLE_LL_LNA == 0 || BLE_LL_LNA_GPIO >= 0 + - BLE_LL_FEM_PA == 0 || BLE_LL_FEM_PA_GPIO >= 0 + - BLE_LL_FEM_LNA == 0 || BLE_LL_FEM_LNA_GPIO >= 0 $import: # defunct and deprecated settings diff --git a/nimble/drivers/plna/sky66112/pkg.yml b/nimble/drivers/fem/sky66112/pkg.yml similarity index 92% rename from nimble/drivers/plna/sky66112/pkg.yml rename to nimble/drivers/fem/sky66112/pkg.yml index c3cb0fd322..5dd738a070 100644 --- a/nimble/drivers/plna/sky66112/pkg.yml +++ b/nimble/drivers/fem/sky66112/pkg.yml @@ -17,13 +17,13 @@ # under the License. # -pkg.name: nimble/drivers/plna/sky66112 +pkg.name: nimble/drivers/fem/sky66112 pkg.description: Driver for SKY66112 front-end module pkg.author: "Apache Mynewt " pkg.homepage: "https://mynewt.apache.org/" pkg.apis: - - ble_ll_pa - - ble_ll_lna + - ble_ll_fem_pa + - ble_ll_fem_lna pkg.deps: - nimble/controller diff --git a/nimble/drivers/plna/sky66112/src/sky66112.c b/nimble/drivers/fem/sky66112/src/sky66112.c similarity index 91% rename from nimble/drivers/plna/sky66112/src/sky66112.c rename to nimble/drivers/fem/sky66112/src/sky66112.c index 4a849fbb58..7a957b0b46 100644 --- a/nimble/drivers/plna/sky66112/src/sky66112.c +++ b/nimble/drivers/fem/sky66112/src/sky66112.c @@ -21,7 +21,7 @@ #include #include "syscfg/syscfg.h" #include "hal/hal_gpio.h" -#include "controller/ble_ll_plna.h" +#include "controller/ble_ll_fem.h" #define NO_BYPASS \ ((MYNEWT_VAL(SKY66112_TX_BYPASS) == 0) && \ @@ -38,13 +38,13 @@ sky66112_bypass(uint8_t enabled) } void -ble_ll_plna_pa_init(void) +ble_ll_fem_pa_init(void) { /* Nothing to do here */ } void -ble_ll_plna_pa_enable(void) +ble_ll_fem_pa_enable(void) { if (!MYNEWT_VAL(SKY66112_TX_BYPASS)) { sky66112_bypass(0); @@ -52,7 +52,7 @@ ble_ll_plna_pa_enable(void) } void -ble_ll_plna_pa_disable(void) +ble_ll_fem_pa_disable(void) { if (!MYNEWT_VAL(SKY66112_TX_BYPASS)) { sky66112_bypass(1); @@ -60,13 +60,13 @@ ble_ll_plna_pa_disable(void) } void -ble_ll_plna_lna_init(void) +ble_ll_fem_lna_init(void) { /* Nothing to do here */ } void -ble_ll_plna_lna_enable(void) +ble_ll_fem_lna_enable(void) { if (!MYNEWT_VAL(SKY66112_RX_BYPASS)) { sky66112_bypass(0); @@ -74,7 +74,7 @@ ble_ll_plna_lna_enable(void) } void -ble_ll_plna_lna_disable(void) +ble_ll_fem_lna_disable(void) { if (!MYNEWT_VAL(SKY66112_RX_BYPASS)) { sky66112_bypass(1); diff --git a/nimble/drivers/plna/sky66112/syscfg.yml b/nimble/drivers/fem/sky66112/syscfg.yml similarity index 97% rename from nimble/drivers/plna/sky66112/syscfg.yml rename to nimble/drivers/fem/sky66112/syscfg.yml index 50434553a0..c7aaa0a8bf 100644 --- a/nimble/drivers/plna/sky66112/syscfg.yml +++ b/nimble/drivers/fem/sky66112/syscfg.yml @@ -57,10 +57,10 @@ syscfg.defs: Only valid if CPS signal is controller by driver. value: 0 -syscfg.vals.!BLE_LL_PA: +syscfg.vals.!BLE_LL_FEM_PA: # Enable TX bypass by default if PA is disabled SKY66112_TX_BYPASS: 1 -syscfg.vals.!BLE_LL_LNA: +syscfg.vals.!BLE_LL_FEM_LNA: # Enable RX bypass by default if LNA is disabled SKY66112_RX_BYPASS: 1 diff --git a/nimble/drivers/nrf52/src/ble_phy.c b/nimble/drivers/nrf52/src/ble_phy.c index bfc111b6c9..a94cb2a75a 100644 --- a/nimble/drivers/nrf52/src/ble_phy.c +++ b/nimble/drivers/nrf52/src/ble_phy.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,6 @@ #include "controller/ble_phy.h" #include "controller/ble_phy_trace.h" #include "controller/ble_ll.h" -#include "controller/ble_ll_plna.h" #include "nrfx.h" #if MYNEWT #include "mcu/nrf52_clock.h" @@ -321,20 +321,20 @@ struct nrf_ccm_data g_nrf_ccm_data; static int g_ble_phy_gpiote_idx; -#if MYNEWT_VAL(BLE_LL_PA) || MYNEWT_VAL(BLE_LL_LNA) +#if MYNEWT_VAL(BLE_LL_FEM_PA) || MYNEWT_VAL(BLE_LL_FEM_LNA) -#define PLNA_SINGLE_GPIO \ - (!MYNEWT_VAL(BLE_LL_PA) || !MYNEWT_VAL(BLE_LL_LNA) || \ - (MYNEWT_VAL(BLE_LL_PA_GPIO) == MYNEWT_VAL(BLE_LL_LNA_GPIO))) +#define FEM_SINGLE_GPIO \ + (!MYNEWT_VAL(BLE_LL_FEM_PA) || !MYNEWT_VAL(BLE_LL_FEM_LNA) || \ + (MYNEWT_VAL(BLE_LL_FEM_PA_GPIO) == MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO))) -#if PLNA_SINGLE_GPIO -static uint8_t plna_idx; +#if FEM_SINGLE_GPIO +static uint8_t fem_idx; #else -#if MYNEWT_VAL(BLE_LL_PA) -static uint8_t plna_pa_idx; +#if MYNEWT_VAL(BLE_LL_FEM_PA) +static uint8_t fem_pa_idx; #endif -#if MYNEWT_VAL(BLE_LL_LNA) -static uint8_t plna_lna_idx; +#if MYNEWT_VAL(BLE_LL_FEM_LNA) +static uint8_t fem_lna_idx; #endif #endif @@ -466,14 +466,14 @@ ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode) #endif static void -ble_phy_plna_enable_pa(void) +ble_phy_fem_enable_pa(void) { -#if MYNEWT_VAL(BLE_LL_PA) - ble_ll_plna_pa_enable(); +#if MYNEWT_VAL(BLE_LL_FEM_PA) + ble_ll_fem_pa_enable(); -#if !PLNA_SINGLE_GPIO - NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[plna_pa_idx]); - NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[plna_pa_idx]); +#if !FEM_SINGLE_GPIO + NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[fem_pa_idx]); + NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[fem_pa_idx]); #endif NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; @@ -481,14 +481,14 @@ ble_phy_plna_enable_pa(void) } static void -ble_phy_plna_enable_lna(void) +ble_phy_fem_enable_lna(void) { -#if MYNEWT_VAL(BLE_LL_LNA) - ble_ll_plna_lna_enable(); +#if MYNEWT_VAL(BLE_LL_FEM_LNA) + ble_ll_fem_lna_enable(); -#if !PLNA_SINGLE_GPIO - NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[plna_lna_idx]); - NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[plna_lna_idx]); +#if !FEM_SINGLE_GPIO + NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[fem_lna_idx]); + NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[fem_lna_idx]); #endif NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; @@ -1054,7 +1054,7 @@ ble_phy_tx_end_isr(void) NRF_TIMER0->EVENTS_COMPARE[0] = 0; nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); - ble_phy_plna_enable_lna(); + ble_phy_fem_enable_lna(); } else if (transition == BLE_PHY_TRANSITION_TX_TX) { /* Schedule TX exactly T_IFS after TX end captured in CC[2] */ tx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); @@ -1196,7 +1196,7 @@ ble_phy_rx_end_isr(void) NRF_TIMER0->EVENTS_COMPARE[0] = 0; nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); - ble_phy_plna_enable_pa(); + ble_phy_fem_enable_pa(); /* * XXX: Hack warning! @@ -1408,9 +1408,9 @@ ble_phy_isr(void) switch (g_ble_phy_data.phy_state) { case BLE_PHY_STATE_RX: -#if MYNEWT_VAL(BLE_LL_LNA) +#if MYNEWT_VAL(BLE_LL_FEM_LNA) NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; - ble_ll_plna_lna_disable(); + ble_ll_fem_lna_disable(); #endif if (g_ble_phy_data.phy_rx_started) { ble_phy_rx_end_isr(); @@ -1419,9 +1419,9 @@ ble_phy_isr(void) } break; case BLE_PHY_STATE_TX: -#if MYNEWT_VAL(BLE_LL_PA) +#if MYNEWT_VAL(BLE_LL_FEM_PA) NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; - ble_ll_plna_pa_disable(); + ble_ll_fem_pa_disable(); #endif ble_phy_tx_end_isr(); break; @@ -1441,8 +1441,8 @@ ble_phy_isr(void) #if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \ MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \ MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 || \ - MYNEWT_VAL(BLE_LL_PA) || \ - MYNEWT_VAL(BLE_LL_LNA) + MYNEWT_VAL(BLE_LL_FEM_PA) || \ + MYNEWT_VAL(BLE_LL_FEM_LNA) static int ble_phy_gpiote_configure(int pin) { @@ -1630,19 +1630,19 @@ ble_phy_init(void) (uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[3]), (uint32_t)&(NRF_RADIO->TASKS_DISABLE)); -#if MYNEWT_VAL(BLE_LL_PA) || MYNEWT_VAL(BLE_LL_LNA) -#if PLNA_SINGLE_GPIO - plna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO)); - NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[plna_idx]); - NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[plna_idx]); +#if MYNEWT_VAL(BLE_LL_FEM_PA) || MYNEWT_VAL(BLE_LL_FEM_LNA) +#if FEM_SINGLE_GPIO + fem_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); + NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[fem_idx]); + NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[fem_idx]); #else -#if MYNEWT_VAL(BLE_LL_PA) - plna_pa_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO)); - NRF_GPIOTE->TASKS_CLR[plna_pa_idx] = 1; +#if MYNEWT_VAL(BLE_LL_FEM_PA) + fem_pa_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); + NRF_GPIOTE->TASKS_CLR[fem_pa_idx] = 1; #endif -#if MYNEWT_VAL(BLE_LL_LNA) - plna_lna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_LNA_GPIO)); - NRF_GPIOTE->TASKS_CLR[plna_lna_idx] = 1; +#if MYNEWT_VAL(BLE_LL_FEM_LNA) + fem_lna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)); + NRF_GPIOTE->TASKS_CLR[fem_lna_idx] = 1; #endif #endif @@ -1814,7 +1814,7 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); rc = 0; - ble_phy_plna_enable_pa(); + ble_phy_fem_enable_pa(); } return rc; @@ -1861,7 +1861,7 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) /* Enable PPI to automatically start RXEN */ nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); - ble_phy_plna_enable_lna(); + ble_phy_fem_enable_lna(); /* Start rx */ rc = ble_phy_rx(); diff --git a/nimble/drivers/nrf5340/src/ble_phy.c b/nimble/drivers/nrf5340/src/ble_phy.c index 6999aee634..76c0289e02 100644 --- a/nimble/drivers/nrf5340/src/ble_phy.c +++ b/nimble/drivers/nrf5340/src/ble_phy.c @@ -27,7 +27,7 @@ #include #include #include -#include "controller/ble_ll_plna.h" +#include "controller/ble_ll_fem.h" #include #include @@ -59,8 +59,8 @@ #define DPPI_CH_ENABLE_ALL (DPPIC_CHEN_CH0_Msk | DPPIC_CHEN_CH1_Msk | DPPIC_CHEN_CH2_Msk | \ DPPIC_CHEN_CH3_Msk | DPPIC_CHEN_CH4_Msk | DPPIC_CHEN_CH5_Msk) -#define DPPI_CH_MASK_PLNA (DPPI_CH_MASK(TIMER0_EVENTS_COMPARE_4) | \ - DPPI_CH_MASK(RADIO_EVENTS_DISABLED)) +#define DPPI_CH_MASK_FEM (DPPI_CH_MASK(TIMER0_EVENTS_COMPARE_4) | \ + DPPI_CH_MASK(RADIO_EVENTS_DISABLED)) extern uint8_t g_nrf_num_irks; extern uint32_t g_nrf_irk_list[]; @@ -244,20 +244,20 @@ static struct nrf_ccm_data nrf_ccm_data; static int g_ble_phy_gpiote_idx; -#if MYNEWT_VAL(BLE_LL_PA) || MYNEWT_VAL(BLE_LL_LNA) +#if MYNEWT_VAL(BLE_LL_FEM_PA) || MYNEWT_VAL(BLE_LL_FEM_LNA) -#define PLNA_SINGLE_GPIO \ - (!MYNEWT_VAL(BLE_LL_PA) || !MYNEWT_VAL(BLE_LL_LNA) || \ - (MYNEWT_VAL(BLE_LL_PA_GPIO) == MYNEWT_VAL(BLE_LL_LNA_GPIO))) +#define FEM_SINGLE_GPIO \ + (!MYNEWT_VAL(BLE_LL_FEM_PA) || !MYNEWT_VAL(BLE_LL_FEM_LNA) || \ + (MYNEWT_VAL(BLE_LL_FEM_PA_GPIO) == MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO))) -#if PLNA_SINGLE_GPIO -static uint8_t plna_idx; +#if FEM_SINGLE_GPIO +static uint8_t fem_idx; #else -#if MYNEWT_VAL(BLE_LL_PA) -static uint8_t plna_pa_idx; +#if MYNEWT_VAL(BLE_LL_FEM_PA) +static uint8_t fem_pa_idx; #endif -#if MYNEWT_VAL(BLE_LL_LNA) -static uint8_t plna_lna_idx; +#if MYNEWT_VAL(BLE_LL_FEM_LNA) +static uint8_t fem_lna_idx; #endif #endif @@ -329,80 +329,80 @@ ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode) } static void -ble_phy_plna_enable_pa(void) +ble_phy_fem_enable_pa(void) { -#if MYNEWT_VAL(BLE_LL_PA) - ble_ll_plna_pa_enable(); +#if MYNEWT_VAL(BLE_LL_FEM_PA) + ble_ll_fem_pa_enable(); /* CC[0] is set to radio enable */ NRF_TIMER0_NS->CC[4] = NRF_TIMER0_NS->CC[0] + BLE_PHY_T_RXENFAST - - MYNEWT_VAL(BLE_LL_PA_TURN_ON_US); + MYNEWT_VAL(BLE_LL_FEM_PA_TURN_ON_US); -#if PLNA_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); +#if FEM_SINGLE_GPIO + NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); #else - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); + NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_pa_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); #endif #endif } static void -ble_phy_plna_disable_pa(void) +ble_phy_fem_disable_pa(void) { -#if MYNEWT_VAL(BLE_LL_PA) - ble_ll_plna_pa_disable(); +#if MYNEWT_VAL(BLE_LL_FEM_PA) + ble_ll_fem_pa_disable(); -#if PLNA_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); +#if FEM_SINGLE_GPIO + NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); #else - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); + NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_pa_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); #endif #endif } static void -ble_phy_plna_enable_lna(void) +ble_phy_fem_enable_lna(void) { -#if MYNEWT_VAL(BLE_LL_LNA) - ble_ll_plna_lna_enable(); +#if MYNEWT_VAL(BLE_LL_FEM_LNA) + ble_ll_fem_lna_enable(); /* CC[0] is set to radio enable */ NRF_TIMER0_NS->CC[4] = NRF_TIMER0_NS->CC[0] + BLE_PHY_T_RXENFAST - - MYNEWT_VAL(BLE_LL_LNA_TURN_ON_US); + MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US); -#if PLNA_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); +#if FEM_SINGLE_GPIO + NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); #else - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); + NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_lna_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); #endif #endif } static void -ble_phy_plna_disable_lna(void) +ble_phy_fem_disable_lna(void) { -#if MYNEWT_VAL(BLE_LL_LNA) - ble_ll_plna_lna_disable(); +#if MYNEWT_VAL(BLE_LL_FEM_LNA) + ble_ll_fem_lna_disable(); -#if PLNA_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); +#if FEM_SINGLE_GPIO + NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); #else - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); + NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_lna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); #endif #endif } static void -ble_phy_plna_force_disable(void) +ble_phy_fem_force_disable(void) { -#if PLNA_SINGLE_GPIO - NRF_GPIOTE_NS->TASKS_CLR[plna_idx] = 1; +#if FEM_SINGLE_GPIO + NRF_GPIOTE_NS->TASKS_CLR[fem_idx] = 1; #else -#if MYNEWT_VAL(BLE_LL_PA) - NRF_GPIOTE_NS->TASKS_CLR[plna_pa_idx] = 1; +#if MYNEWT_VAL(BLE_LL_FEM_PA) + NRF_GPIOTE_NS->TASKS_CLR[fem_pa_idx] = 1; #endif -#if MYNEWT_VAL(BLE_LL_LNA) - NRF_GPIOTE_NS->TASKS_CLR[plna_lna_idx] = 1; +#if MYNEWT_VAL(BLE_LL_FEM_LNA) + NRF_GPIOTE_NS->TASKS_CLR[fem_lna_idx] = 1; #endif #endif } @@ -576,14 +576,14 @@ ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx) * it's used as a base for turn-on time calculation and thus cannot wrap * around on subtraction. */ - if (MYNEWT_VAL(BLE_LL_PA) && tx && - (rem_usecs + BLE_PHY_T_RXENFAST <= MYNEWT_VAL(BLE_LL_PA_TURN_ON_US))) { + if (MYNEWT_VAL(BLE_LL_FEM_PA) && tx && + (rem_usecs + BLE_PHY_T_RXENFAST <= MYNEWT_VAL(BLE_LL_FEM_PA_TURN_ON_US))) { cputime--; rem_usecs += 30; } - if (MYNEWT_VAL(BLE_LL_LNA) && !tx && - (rem_usecs + BLE_PHY_T_RXENFAST <= MYNEWT_VAL(BLE_LL_LNA_TURN_ON_US))) { + if (MYNEWT_VAL(BLE_LL_FEM_LNA) && !tx && + (rem_usecs + BLE_PHY_T_RXENFAST <= MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US))) { cputime--; rem_usecs += 30; } @@ -930,7 +930,7 @@ ble_phy_tx_end_isr(void) /* Start radio on timer */ NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - ble_phy_plna_enable_lna(); + ble_phy_fem_enable_lna(); } else { NRF_TIMER0_NS->TASKS_STOP = 1; NRF_TIMER0_NS->TASKS_SHUTDOWN = 1; @@ -1054,7 +1054,7 @@ ble_phy_rx_end_isr(void) /* Enable automatic TX */ NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - ble_phy_plna_enable_pa(); + ble_phy_fem_enable_pa(); /* * XXX: Hack warning! @@ -1257,20 +1257,20 @@ ble_phy_isr(void) NRF_RADIO_NS->INTENCLR = RADIO_INTENCLR_DISABLED_Msk; switch (g_ble_phy_data.phy_state) { - case BLE_PHY_STATE_RX: - ble_phy_plna_disable_lna(); - if (g_ble_phy_data.phy_rx_started) { - ble_phy_rx_end_isr(); - } else { - ble_ll_wfr_timer_exp(NULL); - } - break; - case BLE_PHY_STATE_TX: - ble_phy_plna_disable_pa(); - ble_phy_tx_end_isr(); - break; - default: - BLE_LL_ASSERT(0); + case BLE_PHY_STATE_RX: + ble_phy_fem_disable_lna(); + if (g_ble_phy_data.phy_rx_started) { + ble_phy_rx_end_isr(); + } else { + ble_ll_wfr_timer_exp(NULL); + } + break; + case BLE_PHY_STATE_TX: + ble_phy_fem_disable_pa(); + ble_phy_tx_end_isr(); + break; + default: + BLE_LL_ASSERT(0); } } @@ -1284,8 +1284,8 @@ ble_phy_isr(void) #if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \ MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \ MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 || \ - MYNEWT_VAL(BLE_LL_PA) || \ - MYNEWT_VAL(BLE_LL_LNA) + MYNEWT_VAL(BLE_LL_FEM_PA) || \ + MYNEWT_VAL(BLE_LL_FEM_LNA) static int ble_phy_gpiote_configure(int pin) { @@ -1463,7 +1463,7 @@ ble_phy_init(void) NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[1] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[2] = DPPI_CH_SUB(RADIO_EVENTS_END); -#if MYNEWT_VAL(BLE_LL_PA) || MYNEWT_VAL(BLE_LL_LNA) +#if MYNEWT_VAL(BLE_LL_FEM_PA) || MYNEWT_VAL(BLE_LL_FEM_LNA) /* We keep both channels enabled and CLR task subscribed all the time. It's * enough to just (un)subscribe SET task when needed. * TODO: figure out if this affects power consumption @@ -1476,27 +1476,27 @@ ble_phy_init(void) NRF_RADIO_NS->PUBLISH_DISABLED = DPPI_CH_PUB(RADIO_EVENTS_DISABLED); NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_DISABLED); -#if PLNA_SINGLE_GPIO - plna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO)); - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[plna_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); - NRF_GPIOTE_NS->TASKS_CLR[plna_idx] = 1; +#if FEM_SINGLE_GPIO + fem_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); + NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); + NRF_GPIOTE_NS->SUBSCRIBE_CLR[fem_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); + NRF_GPIOTE_NS->TASKS_CLR[fem_idx] = 1; #else -#if MYNEWT_VAL(BLE_LL_PA) - plna_pa_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_PA_GPIO)); - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[plna_pa_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); - NRF_GPIOTE_NS->TASKS_CLR[plna_pa_idx] = 1; +#if MYNEWT_VAL(BLE_LL_FEM_PA) + fem_pa_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); + NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_pa_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); + NRF_GPIOTE_NS->SUBSCRIBE_CLR[fem_pa_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); + NRF_GPIOTE_NS->TASKS_CLR[fem_pa_idx] = 1; #endif -#if MYNEWT_VAL(BLE_LL_LNA) - plna_lna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_LNA_GPIO)); - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[plna_lna_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); - NRF_GPIOTE_NS->TASKS_CLR[plna_lna_idx] = 1; +#if MYNEWT_VAL(BLE_LL_FEM_LNA) + fem_lna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)); + NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_lna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); + NRF_GPIOTE_NS->SUBSCRIBE_CLR[fem_lna_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); + NRF_GPIOTE_NS->TASKS_CLR[fem_lna_idx] = 1; #endif #endif - NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK_PLNA; + NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK_FEM; #endif /* Set isr in vector table and enable interrupt */ @@ -1630,7 +1630,7 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); rc = 0; - ble_phy_plna_enable_pa(); + ble_phy_fem_enable_pa(); } return rc; } @@ -1663,7 +1663,7 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) /* Enable PPI to automatically start RXEN */ NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - ble_phy_plna_enable_lna(); + ble_phy_fem_enable_lna(); /* Start rx */ rc = ble_phy_rx(); @@ -1940,14 +1940,14 @@ ble_phy_disable_irq_and_ppi(void) NRF_AAR_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RADIO_EVENTS_BCMATCH); NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); -#if PLNA_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); +#if FEM_SINGLE_GPIO + NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); #else -#if MYNEWT_VAL(BLE_LL_PA) - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_pa_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); +#if MYNEWT_VAL(BLE_LL_FEM_PA) + NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_pa_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); #endif -#if MYNEWT_VAL(BLE_LL_LNA) - NRF_GPIOTE_NS->SUBSCRIBE_SET[plna_lna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); +#if MYNEWT_VAL(BLE_LL_FEM_LNA) + NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_lna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); #endif #endif @@ -1989,7 +1989,7 @@ ble_phy_disable(void) ble_phy_stop_usec_timer(); ble_phy_disable_irq_and_ppi(); - ble_phy_plna_force_disable(); + ble_phy_fem_force_disable(); ble_phy_dbg_clear_pins(); } From fb1ae2ec75ffec664d234f4683a3f23f329d8e52 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 31 Aug 2022 15:28:11 +0200 Subject: [PATCH 0523/1333] nimble/fem: Add support for runtime configuration of SKY66112 This allows to configure FEM operation mode at runtime. --- .../fem/sky66112/include/sky66112/sky66112.h | 38 +++++++ nimble/drivers/fem/sky66112/src/sky66112.c | 106 +++++++++++++----- nimble/drivers/fem/sky66112/syscfg.yml | 7 ++ 3 files changed, 121 insertions(+), 30 deletions(-) create mode 100644 nimble/drivers/fem/sky66112/include/sky66112/sky66112.h diff --git a/nimble/drivers/fem/sky66112/include/sky66112/sky66112.h b/nimble/drivers/fem/sky66112/include/sky66112/sky66112.h new file mode 100644 index 0000000000..2403e7c06f --- /dev/null +++ b/nimble/drivers/fem/sky66112/include/sky66112/sky66112.h @@ -0,0 +1,38 @@ +/* + * 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 _SKY66112_H +#define _SKY66112_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void sky66112_tx_hp_mode(uint8_t enabled); +void sky66112_antenna_port(uint8_t port); +void sky66112_rx_bypass(uint8_t enabled); +void sky66112_tx_bypass(uint8_t enabled); +#ifdef __cplusplus +} +#endif + +#endif /* _SKY66112_H */ diff --git a/nimble/drivers/fem/sky66112/src/sky66112.c b/nimble/drivers/fem/sky66112/src/sky66112.c index 7a957b0b46..9b74c45c77 100644 --- a/nimble/drivers/fem/sky66112/src/sky66112.c +++ b/nimble/drivers/fem/sky66112/src/sky66112.c @@ -18,22 +18,25 @@ */ #include -#include +#include #include "syscfg/syscfg.h" #include "hal/hal_gpio.h" #include "controller/ble_ll_fem.h" -#define NO_BYPASS \ - ((MYNEWT_VAL(SKY66112_TX_BYPASS) == 0) && \ - (MYNEWT_VAL(SKY66112_RX_BYPASS) == 0)) +static struct { + uint8_t rx_bypass : 1; + uint8_t tx_bypass : 1; +} sky66112_config = { + .rx_bypass = MYNEWT_VAL(SKY66112_RX_BYPASS), + .tx_bypass = MYNEWT_VAL(SKY66112_TX_BYPASS), +}; static void sky66112_bypass(uint8_t enabled) { - if (NO_BYPASS) { - return; - } - + /* this is called only if bypass is enabled which means CPS PIN is + * correctly set and there is no need to check it here. + */ hal_gpio_write(MYNEWT_VAL(SKY66112_PIN_CPS), enabled); } @@ -46,16 +49,16 @@ ble_ll_fem_pa_init(void) void ble_ll_fem_pa_enable(void) { - if (!MYNEWT_VAL(SKY66112_TX_BYPASS)) { - sky66112_bypass(0); + if (sky66112_config.tx_bypass) { + sky66112_bypass(1); } } void ble_ll_fem_pa_disable(void) { - if (!MYNEWT_VAL(SKY66112_TX_BYPASS)) { - sky66112_bypass(1); + if (sky66112_config.tx_bypass) { + sky66112_bypass(0); } } @@ -68,50 +71,93 @@ ble_ll_fem_lna_init(void) void ble_ll_fem_lna_enable(void) { - if (!MYNEWT_VAL(SKY66112_RX_BYPASS)) { - sky66112_bypass(0); + if (sky66112_config.rx_bypass) { + sky66112_bypass(1); } } void ble_ll_fem_lna_disable(void) { - if (!MYNEWT_VAL(SKY66112_RX_BYPASS)) { - sky66112_bypass(1); + if (sky66112_config.rx_bypass) { + sky66112_bypass(0); } } void -sky66112_init(void) +sky66112_tx_hp_mode(uint8_t enabled) { - int pin; + int pin = MYNEWT_VAL(SKY66112_PIN_CHL); - /* Use CRX and CTX to enable sleep mode */ - pin = MYNEWT_VAL(SKY66112_PIN_CSD); if (pin >= 0) { - hal_gpio_init_out(pin, 1); + hal_gpio_write(pin, enabled); } +} - pin = MYNEWT_VAL(SKY66112_PIN_CPS); - if (NO_BYPASS) { - /* Disable bypass */ - if (pin >= 0) { +void +sky66112_antenna_port(uint8_t port) +{ + int pin = MYNEWT_VAL(SKY66112_PIN_SEL); + + if (pin >= 0) { + switch (port) { + case 1: hal_gpio_init_out(pin, 0); + break; + case 2: + hal_gpio_init_out(pin, 1); + break; + default: + assert(0); } - } else { - /* Enable bypass, we'll disable it when needed */ - assert(pin >= 0); + } +} + +void +sky66112_rx_bypass(uint8_t enabled) +{ + int pin = MYNEWT_VAL(SKY66112_PIN_CPS); + + if (pin >= 0) { + sky66112_config.rx_bypass = enabled; + sky66112_bypass(enabled); + } +} + +void +sky66112_tx_bypass(uint8_t enabled) +{ + int pin = MYNEWT_VAL(SKY66112_PIN_CPS); + + if (pin >= 0) { + sky66112_config.tx_bypass = enabled; + sky66112_bypass(enabled); + } +} + +void +sky66112_init(void) +{ + int pin; + + /* Use CRX and CTX to enable sleep mode */ + pin = MYNEWT_VAL(SKY66112_PIN_CSD); + if (pin >= 0) { hal_gpio_init_out(pin, 1); } + /* Set default tx power mode */ pin = MYNEWT_VAL(SKY66112_PIN_CHL); if (pin >= 0) { hal_gpio_init_out(pin, MYNEWT_VAL(SKY66112_TX_HP_MODE)); } - /* Select ANT1 */ - pin = MYNEWT_VAL(SKY66112_PIN_SEL); + /* Disable bypass, we'll enable it when needed */ + pin = MYNEWT_VAL(SKY66112_PIN_CPS); if (pin >= 0) { hal_gpio_init_out(pin, 0); } + + sky66112_tx_hp_mode(MYNEWT_VAL(SKY66112_TX_HP_MODE)); + sky66112_antenna_port(MYNEWT_VAL(SKY66112_ANTENNA_PORT)); } diff --git a/nimble/drivers/fem/sky66112/syscfg.yml b/nimble/drivers/fem/sky66112/syscfg.yml index c7aaa0a8bf..1da8397888 100644 --- a/nimble/drivers/fem/sky66112/syscfg.yml +++ b/nimble/drivers/fem/sky66112/syscfg.yml @@ -56,6 +56,13 @@ syscfg.defs: Enables bypass for RX which effectively disables operation as PA. Only valid if CPS signal is controller by driver. value: 0 + SKY66112_ANTENNA_PORT: + description: > + Selects which antenna port should be enabled: + 1 for ANT1 port enabled + 2 for ANT2 port enabled + range: 1, 2 + value: 1 syscfg.vals.!BLE_LL_FEM_PA: # Enable TX bypass by default if PA is disabled From 2c3c3bf82c6288dcbacc948a6f877d69a3651f89 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 8 Sep 2022 09:20:34 +0200 Subject: [PATCH 0524/1333] nimble/ll: Add generic interface for controlling FEM antenna This allows to select active antenna if supported by FEM. 0 means default antenna, while any other value is FEM specific. --- .../include/controller/ble_ll_fem.h | 5 ++++ nimble/controller/pkg.yml | 2 ++ nimble/controller/src/ble_ll_hci_vs.c | 27 +++++++++++++++++ nimble/controller/syscfg.yml | 4 +++ .../fem/sky66112/include/sky66112/sky66112.h | 1 - nimble/drivers/fem/sky66112/pkg.yml | 1 + nimble/drivers/fem/sky66112/src/sky66112.c | 29 ++++++++++++++----- nimble/include/nimble/hci_common.h | 5 ++++ 8 files changed, 66 insertions(+), 8 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_fem.h b/nimble/controller/include/controller/ble_ll_fem.h index 3d645173db..d8c6dbec07 100644 --- a/nimble/controller/include/controller/ble_ll_fem.h +++ b/nimble/controller/include/controller/ble_ll_fem.h @@ -38,6 +38,11 @@ void ble_ll_fem_lna_enable(void); void ble_ll_fem_lna_disable(void); #endif +#if MYNEWT_VAL(BLE_LL_FEM_ANTENNA) +/* 0 sets default antenna, any other value is FEM specific */ +int ble_ll_fem_antenna(uint8_t antenna); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/controller/pkg.yml b/nimble/controller/pkg.yml index 9115e45289..4462823cf2 100644 --- a/nimble/controller/pkg.yml +++ b/nimble/controller/pkg.yml @@ -33,6 +33,8 @@ pkg.req_apis.BLE_LL_FEM_PA: - ble_ll_fem_pa pkg.req_apis.BLE_LL_FEM_LNA: - ble_ll_fem_lna +pkg.req_apis.BLE_LL_FEM_ANTENNA: + - ble_ll_fem_antenna pkg.deps: - "@apache-mynewt-core/kernel/os" diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index 9b9cf268d8..c6c1e256b4 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -25,6 +25,7 @@ #include "controller/ble_ll_adv.h" #include "controller/ble_ll_scan.h" #include "controller/ble_hw.h" +#include "controller/ble_ll_fem.h" #include "ble_ll_conn_priv.h" #include "ble_ll_priv.h" @@ -351,6 +352,29 @@ ble_ll_hci_vs_set_data_len(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, } #endif +#if MYNEWT_VAL(BLE_LL_FEM_ANTENNA) +static int +ble_ll_hci_vs_set_antenna(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_vs_set_antenna_cp *cmd = (const void *) cmdbuf; + + if (cmdlen != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (ble_ll_hci_vs_is_controller_busy()) { + return BLE_ERR_CMD_DISALLOWED; + } + + if (ble_ll_fem_antenna(cmd->antenna)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + return BLE_ERR_SUCCESS; +} +#endif + static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_RD_STATIC_ADDR, ble_ll_hci_vs_rd_static_addr), @@ -374,6 +398,9 @@ static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_DATA_LEN, ble_ll_hci_vs_set_data_len), #endif +#if MYNEWT_VAL(BLE_LL_FEM_ANTENNA) + BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_ANTENNA, ble_ll_hci_vs_set_antenna), +#endif }; static struct ble_ll_hci_vs_cmd * diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 11e582c524..364e9f58e0 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -430,6 +430,10 @@ syscfg.defs: description: > Time required for LNA to turn on, in microseconds. value: MYNEWT_VAL(BLE_LL_LNA_TURN_ON_US) + BLE_LL_FEM_ANTENNA: + description: > + Enable support for runtime antenna selection in FEM. + value: 0 BLE_LL_SYSINIT_STAGE: description: > diff --git a/nimble/drivers/fem/sky66112/include/sky66112/sky66112.h b/nimble/drivers/fem/sky66112/include/sky66112/sky66112.h index 2403e7c06f..6bdf59f74a 100644 --- a/nimble/drivers/fem/sky66112/include/sky66112/sky66112.h +++ b/nimble/drivers/fem/sky66112/include/sky66112/sky66112.h @@ -28,7 +28,6 @@ extern "C" { #endif void sky66112_tx_hp_mode(uint8_t enabled); -void sky66112_antenna_port(uint8_t port); void sky66112_rx_bypass(uint8_t enabled); void sky66112_tx_bypass(uint8_t enabled); #ifdef __cplusplus diff --git a/nimble/drivers/fem/sky66112/pkg.yml b/nimble/drivers/fem/sky66112/pkg.yml index 5dd738a070..532fe212a9 100644 --- a/nimble/drivers/fem/sky66112/pkg.yml +++ b/nimble/drivers/fem/sky66112/pkg.yml @@ -24,6 +24,7 @@ pkg.homepage: "https://mynewt.apache.org/" pkg.apis: - ble_ll_fem_pa - ble_ll_fem_lna + - ble_ll_fem_antenna pkg.deps: - nimble/controller diff --git a/nimble/drivers/fem/sky66112/src/sky66112.c b/nimble/drivers/fem/sky66112/src/sky66112.c index 9b74c45c77..9e9ceab691 100644 --- a/nimble/drivers/fem/sky66112/src/sky66112.c +++ b/nimble/drivers/fem/sky66112/src/sky66112.c @@ -94,23 +94,26 @@ sky66112_tx_hp_mode(uint8_t enabled) } } -void -sky66112_antenna_port(uint8_t port) +int +ble_ll_fem_antenna(uint8_t port) { int pin = MYNEWT_VAL(SKY66112_PIN_SEL); if (pin >= 0) { switch (port) { + case 0: case 1: - hal_gpio_init_out(pin, 0); + hal_gpio_write(pin, 0); break; case 2: - hal_gpio_init_out(pin, 1); + hal_gpio_write(pin, 1); break; default: - assert(0); + return -1; } } + + return 0; } void @@ -158,6 +161,18 @@ sky66112_init(void) hal_gpio_init_out(pin, 0); } - sky66112_tx_hp_mode(MYNEWT_VAL(SKY66112_TX_HP_MODE)); - sky66112_antenna_port(MYNEWT_VAL(SKY66112_ANTENNA_PORT)); + /* configure default antenna */ + pin = MYNEWT_VAL(SKY66112_PIN_SEL); + if (pin >= 0) { + switch (MYNEWT_VAL(SKY66112_ANTENNA_PORT)) { + case 1: + hal_gpio_init_out(pin, 0); + break; + case 2: + hal_gpio_init_out(pin, 1); + break; + default: + assert(0); + } + } } diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index a3c3dc3f08..7c5ebe9a00 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1179,6 +1179,11 @@ struct ble_hci_vs_set_data_len_cp { struct ble_hci_vs_set_data_len_rp { uint16_t conn_handle; } __attribute__((packed)); +#define BLE_HCI_OCF_VS_SET_ANTENNA (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0009)) +struct ble_hci_vs_set_antenna_cp { + uint8_t antenna; +} __attribute__((packed)); + /* Command Specific Definitions */ From fbeb4b7506efcb4d819d0ed2648845a01bd78e99 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 12 Sep 2022 16:36:18 +0200 Subject: [PATCH 0525/1333] nimble/ll: Fix calculations for aux scheduling We need to take scheduling offset into account when calculating advertising event duration. --- nimble/controller/src/ble_ll_adv.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 85500d5769..c2ab127bfd 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1674,28 +1674,18 @@ ble_ll_adv_aux_set_start_time(struct ble_ll_adv_sm *advsm) chans = bits[advsm->adv_chanmask]; - /* - * We want to schedule auxiliary packet as soon as possible after the end - * of advertising event, but no sooner than T_MAFS. The interval between - * advertising packets is 250 usecs (8.19 ticks) on LE Coded and a bit less - * on 1M, but it can vary a bit due to scheduling which we can't really - * control. Since we round ticks up for both interval and T_MAFS, we still - * have some margin here. The worst thing that can happen is that we skip - * last advertising packet which is not a bit problem so leave it as-is, no - * need to make code more complicated. - */ - - /* - * XXX: this could be improved if phy has TX-TX transition with controlled - * or predefined interval, but since it makes advertising code even - * more complicated let's skip it for now... - */ - adv_pdu_dur = (int32_t)(sched->end_time - sched->start_time) - g_ble_ll_sched_offset_ticks; - /* 9 is 8.19 ticks rounded up - see comment above */ - adv_event_dur = (adv_pdu_dur * chans) + (9 * (chans - 1)); + /* The interval between advertising PDUs may vary due to scheduling, but in + * general we reserve 3 ticks for end-to-schedule time and add scheduler + * offset. That should be more that enough to make sure there's at least + * T_mafs delay between last advertising PDU and auxiliary PDU. + * + * TODO we can make this much more efficient with TX-TX transition + */ + adv_event_dur = (adv_pdu_dur * chans) + + ((3 + g_ble_ll_sched_offset_ticks) * (chans - 1)); advsm->aux[0].start_time = advsm->adv_event_start_time + adv_event_dur + ble_ll_tmr_u2t_up(BLE_LL_MAFS + From 084eb382c5c11a57f7e704bf127abe675142bb52 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 12 Sep 2022 12:16:47 +0200 Subject: [PATCH 0526/1333] nimble/ll: Fix scheduling adv PDUs We schedule consecutive PDUs in advertising event at "now" timestamp, but to make sure we do not miss the slow we should account for an extra tick that can happen during processing. --- nimble/controller/src/ble_ll_adv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index c2ab127bfd..edca7527b3 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -4842,12 +4842,12 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) ++advsm->adv_chan; } - /* - * We will transmit right away. Set next pdu start time to now - * plus a xcvr start delay just so we dont count late adv starts + /* We want to send next PDU right away so start time is set to "now" + * plus scheduling offset. Add an extra tick since LL timer may tick + * when we calculate other things in the meantime. */ advsm->adv_pdu_start_time = ble_ll_tmr_get() + - g_ble_ll_sched_offset_ticks; + g_ble_ll_sched_offset_ticks + 1; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) /* If we're past aux (unlikely, but can happen), just drop an event */ From a7b016ebac9189a907412dc6eff8a805b33fde2f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 6 Sep 2022 15:45:10 +0200 Subject: [PATCH 0527/1333] nimble/phy: Introduce common phy for nRF52 and nRF53 This is starting point for common phy for nRF52 and nRF53 which will make maintaining both much easier. For now this is just c&p of nrf52 phy to make changes easier to follow. Note that nrf5x phy will not support nRF51 since, apart from other differences, it does not support hardware tifs which is required for nRF51. --- nimble/drivers/nrf5x/include/ble/xcvr.h | 52 + nimble/drivers/nrf5x/pkg.yml | 31 + nimble/drivers/nrf5x/src/ble_hw.c | 517 +++++ nimble/drivers/nrf5x/src/ble_phy.c | 2301 ++++++++++++++++++++++ nimble/drivers/nrf5x/src/ble_phy_trace.c | 44 + nimble/drivers/nrf5x/syscfg.yml | 72 + 6 files changed, 3017 insertions(+) create mode 100644 nimble/drivers/nrf5x/include/ble/xcvr.h create mode 100644 nimble/drivers/nrf5x/pkg.yml create mode 100644 nimble/drivers/nrf5x/src/ble_hw.c create mode 100644 nimble/drivers/nrf5x/src/ble_phy.c create mode 100644 nimble/drivers/nrf5x/src/ble_phy_trace.c create mode 100644 nimble/drivers/nrf5x/syscfg.yml diff --git a/nimble/drivers/nrf5x/include/ble/xcvr.h b/nimble/drivers/nrf5x/include/ble/xcvr.h new file mode 100644 index 0000000000..757bb80faa --- /dev/null +++ b/nimble/drivers/nrf5x/include/ble/xcvr.h @@ -0,0 +1,52 @@ +/* + * 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_BLE_XCVR_ +#define H_BLE_XCVR_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define XCVR_RX_RADIO_RAMPUP_USECS (40) +#define XCVR_TX_RADIO_RAMPUP_USECS (40) + +/* + * NOTE: we have to account for the RTC output compare issue. We want it to be + * 5 ticks. + */ +#define XCVR_PROC_DELAY_USECS (153) +#define XCVR_RX_START_DELAY_USECS (XCVR_RX_RADIO_RAMPUP_USECS) +#define XCVR_TX_START_DELAY_USECS (XCVR_TX_RADIO_RAMPUP_USECS) +#define XCVR_TX_SCHED_DELAY_USECS \ + (XCVR_TX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS) +#define XCVR_RX_SCHED_DELAY_USECS \ + (XCVR_RX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS) + +/* + * Define HW whitelist size. This is the total possible whitelist size; + * not necessarily the size that will be used (may be smaller) + */ +#define BLE_HW_WHITE_LIST_SIZE (8) + +#ifdef __cplusplus +} +#endif + +#endif /* H_BLE_XCVR_ */ diff --git a/nimble/drivers/nrf5x/pkg.yml b/nimble/drivers/nrf5x/pkg.yml new file mode 100644 index 0000000000..e0b314ea4d --- /dev/null +++ b/nimble/drivers/nrf5x/pkg.yml @@ -0,0 +1,31 @@ +# +# 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: nimble/drivers/nrf5x +pkg.description: PHY for nRF52 and nRF53 series +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" +pkg.keywords: + - ble + - bluetooth + +pkg.apis: ble_driver +pkg.deps: + - nimble + - nimble/controller diff --git a/nimble/drivers/nrf5x/src/ble_hw.c b/nimble/drivers/nrf5x/src/ble_hw.c new file mode 100644 index 0000000000..0accbbf40e --- /dev/null +++ b/nimble/drivers/nrf5x/src/ble_hw.c @@ -0,0 +1,517 @@ +/* + * 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. + */ + +#include +#include +#include +#include "syscfg/syscfg.h" +#include "os/os.h" +#include "ble/xcvr.h" +#include "nimble/ble.h" +#include "nimble/nimble_opt.h" +#include "nrfx.h" +#include "controller/ble_hw.h" +#if MYNEWT +#include "mcu/cmsis_nvic.h" +#else +#include "core_cm4.h" +#include +#endif +#include "os/os_trace_api.h" +#include +#include "hal/nrf_ecb.h" + +/* Total number of resolving list elements */ +#define BLE_HW_RESOLV_LIST_SIZE (16) + +/* We use this to keep track of which entries are set to valid addresses */ +static uint8_t g_ble_hw_whitelist_mask; + +/* Random number generator isr callback */ +ble_rng_isr_cb_t g_ble_rng_isr_cb; + +#if BABBLESIM +extern void tm_tick(void); +#endif + +/* If LL privacy is enabled, allocate memory for AAR */ +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + +/* The NRF51 supports up to 16 IRK entries */ +#if (MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE) < 16) +#define NRF_IRK_LIST_ENTRIES (MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE)) +#else +#define NRF_IRK_LIST_ENTRIES (16) +#endif + +/* NOTE: each entry is 16 bytes long. */ +uint32_t g_nrf_irk_list[NRF_IRK_LIST_ENTRIES * 4]; + +/* Current number of IRK entries */ +uint8_t g_nrf_num_irks; + +#endif + +/* Returns public device address or -1 if not present */ +int +ble_hw_get_public_addr(ble_addr_t *addr) +{ + uint32_t addr_high; + uint32_t addr_low; + +#if MYNEWT_VAL(BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR) + /* + * The BMD-345 modules are preprogrammed from the factory with a unique public + * The Bluetooth device address stored in the CUSTOMER[0] and CUSTOMER[1] + * registers of the User Information Configuration Registers (UICR). + * The Bluetooth device address consists of the IEEE Organizationally Unique + * Identifier (OUI) combined with the hexadecimal digits that are printed on + * a 2D barcode and in human-readable text on the module label.The Bluetooth + * device address is stored in little endian format. The most significant + * bytes of the CUSTOMER[1] register are 0xFF to complete the 32-bit register. + */ + + /* Copy into device address. We can do this because we know platform */ + addr_low = NRF_UICR->CUSTOMER[0]; + addr_high = NRF_UICR->CUSTOMER[1]; +#else + /* Does FICR have a public address */ + if ((NRF_FICR->DEVICEADDRTYPE & 1) != 0) { + return -1; + } + + /* Copy into device address. We can do this because we know platform */ + addr_low = NRF_FICR->DEVICEADDR[0]; + addr_high = NRF_FICR->DEVICEADDR[1]; +#endif + + memcpy(addr->val, &addr_low, 4); + memcpy(&addr->val[4], &addr_high, 2); + addr->type = BLE_ADDR_PUBLIC; + + return 0; +} + +/* Returns random static address or -1 if not present */ +int +ble_hw_get_static_addr(ble_addr_t *addr) +{ + uint32_t addr_high; + uint32_t addr_low; + int rc; + + if ((NRF_FICR->DEVICEADDRTYPE & 1) == 1) { + addr_low = NRF_FICR->DEVICEADDR[0]; + addr_high = NRF_FICR->DEVICEADDR[1]; + + memcpy(addr->val, &addr_low, 4); + memcpy(&addr->val[4], &addr_high, 2); + + addr->val[5] |= 0xc0; + addr->type = BLE_ADDR_RANDOM; + rc = 0; + } else { + rc = -1; + } + + return rc; +} + +/** + * Clear the whitelist + * + * @return int + */ +void +ble_hw_whitelist_clear(void) +{ + NRF_RADIO->DACNF = 0; + g_ble_hw_whitelist_mask = 0; +} + +/** + * Add a device to the hw whitelist + * + * @param addr + * @param addr_type + * + * @return int 0: success, BLE error code otherwise + */ +int +ble_hw_whitelist_add(const uint8_t *addr, uint8_t addr_type) +{ + int i; + uint32_t mask; + + /* Find first ununsed device address match element */ + mask = 0x01; + for (i = 0; i < BLE_HW_WHITE_LIST_SIZE; ++i) { + if ((mask & g_ble_hw_whitelist_mask) == 0) { + NRF_RADIO->DAB[i] = get_le32(addr); + NRF_RADIO->DAP[i] = get_le16(addr + 4); + if (addr_type == BLE_ADDR_RANDOM) { + NRF_RADIO->DACNF |= (mask << 8); + } + g_ble_hw_whitelist_mask |= mask; + return BLE_ERR_SUCCESS; + } + mask <<= 1; + } + + return BLE_ERR_MEM_CAPACITY; +} + +/** + * Remove a device from the hw whitelist + * + * @param addr + * @param addr_type + * + */ +void +ble_hw_whitelist_rmv(const uint8_t *addr, uint8_t addr_type) +{ + int i; + uint8_t cfg_addr; + uint16_t dap; + uint16_t txadd; + uint32_t dab; + uint32_t mask; + + /* Find first ununsed device address match element */ + dab = get_le32(addr); + dap = get_le16(addr + 4); + txadd = NRF_RADIO->DACNF >> 8; + mask = 0x01; + for (i = 0; i < BLE_HW_WHITE_LIST_SIZE; ++i) { + if (mask & g_ble_hw_whitelist_mask) { + if ((dab == NRF_RADIO->DAB[i]) && (dap == NRF_RADIO->DAP[i])) { + cfg_addr = txadd & mask; + if (addr_type == BLE_ADDR_RANDOM) { + if (cfg_addr != 0) { + break; + } + } else { + if (cfg_addr == 0) { + break; + } + } + } + } + mask <<= 1; + } + + if (i < BLE_HW_WHITE_LIST_SIZE) { + g_ble_hw_whitelist_mask &= ~mask; + NRF_RADIO->DACNF &= ~mask; + } +} + +/** + * Returns the size of the whitelist in HW + * + * @return int Number of devices allowed in whitelist + */ +uint8_t +ble_hw_whitelist_size(void) +{ + return BLE_HW_WHITE_LIST_SIZE; +} + +/** + * Enable the whitelisted devices + */ +void +ble_hw_whitelist_enable(void) +{ + /* Enable the configured device addresses */ + NRF_RADIO->DACNF |= g_ble_hw_whitelist_mask; +} + +/** + * Disables the whitelisted devices + */ +void +ble_hw_whitelist_disable(void) +{ + /* Disable all whitelist devices */ + NRF_RADIO->DACNF &= 0x0000ff00; +} + +/** + * Boolean function which returns true ('1') if there is a match on the + * whitelist. + * + * @return int + */ +int +ble_hw_whitelist_match(void) +{ + return (int)NRF_RADIO->EVENTS_DEVMATCH; +} + +/* Encrypt data */ +int +ble_hw_encrypt_block(struct ble_encryption_block *ecb) +{ + int rc; + uint32_t end; + uint32_t err; + + /* Stop ECB */ + nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STOPECB); + /* XXX: does task stop clear these counters? Anyway to do this quicker? */ + NRF_ECB->EVENTS_ENDECB = 0; + NRF_ECB->EVENTS_ERRORECB = 0; + NRF_ECB->ECBDATAPTR = (uint32_t)ecb; + + /* Start ECB */ + nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STARTECB); + + /* Wait till error or done */ + rc = 0; + while (1) { + end = NRF_ECB->EVENTS_ENDECB; + err = NRF_ECB->EVENTS_ERRORECB; + if (end || err) { + if (err) { + rc = -1; + } + break; + } +#if BABBLESIM + tm_tick(); +#endif + } + + return rc; +} + +/** + * Random number generator ISR. + */ +static void +ble_rng_isr(void) +{ + uint8_t rnum; + + os_trace_isr_enter(); + + /* No callback? Clear and disable interrupts */ + if (g_ble_rng_isr_cb == NULL) { + nrf_rng_int_disable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK); + NRF_RNG->EVENTS_VALRDY = 0; + (void)NRF_RNG->SHORTS; + os_trace_isr_exit(); + return; + } + + /* If there is a value ready grab it */ + if (NRF_RNG->EVENTS_VALRDY) { + NRF_RNG->EVENTS_VALRDY = 0; + rnum = (uint8_t)NRF_RNG->VALUE; + (*g_ble_rng_isr_cb)(rnum); + } + + os_trace_isr_exit(); +} + +/** + * Initialize the random number generator + * + * @param cb + * @param bias + * + * @return int + */ +int +ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias) +{ + /* Set bias */ + if (bias) { + NRF_RNG->CONFIG = 1; + } else { + NRF_RNG->CONFIG = 0; + } + + /* If we were passed a function pointer we need to enable the interrupt */ + if (cb != NULL) { +#ifndef RIOT_VERSION + NVIC_SetPriority(RNG_IRQn, (1 << __NVIC_PRIO_BITS) - 1); +#endif +#if MYNEWT + NVIC_SetVector(RNG_IRQn, (uint32_t)ble_rng_isr); +#else + ble_npl_hw_set_isr(RNG_IRQn, ble_rng_isr); +#endif + NVIC_EnableIRQ(RNG_IRQn); + g_ble_rng_isr_cb = cb; + } + + return 0; +} + +/** + * Start the random number generator + * + * @return int + */ +int +ble_hw_rng_start(void) +{ + os_sr_t sr; + + /* No need for interrupt if there is no callback */ + OS_ENTER_CRITICAL(sr); + NRF_RNG->EVENTS_VALRDY = 0; + + if (g_ble_rng_isr_cb) { + nrf_rng_int_enable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK); + } + nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_START); + OS_EXIT_CRITICAL(sr); + + return 0; +} + +/** + * Stop the random generator + * + * @return int + */ +int +ble_hw_rng_stop(void) +{ + os_sr_t sr; + + /* No need for interrupt if there is no callback */ + OS_ENTER_CRITICAL(sr); + nrf_rng_int_disable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK); + nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_STOP); + NRF_RNG->EVENTS_VALRDY = 0; + OS_EXIT_CRITICAL(sr); + + return 0; +} + +/** + * Read the random number generator. + * + * @return uint8_t + */ +uint8_t +ble_hw_rng_read(void) +{ + uint8_t rnum; + + /* Wait for a sample */ + while (NRF_RNG->EVENTS_VALRDY == 0) { + } + + NRF_RNG->EVENTS_VALRDY = 0; + rnum = (uint8_t)NRF_RNG->VALUE; + + return rnum; +} + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) +/** + * Clear the resolving list + * + * @return int + */ +void +ble_hw_resolv_list_clear(void) +{ + g_nrf_num_irks = 0; +} + +/** + * Add a device to the hw resolving list + * + * @param irk Pointer to IRK to add + * + * @return int 0: success, BLE error code otherwise + */ +int +ble_hw_resolv_list_add(uint8_t *irk) +{ + uint32_t *nrf_entry; + + /* Find first ununsed device address match element */ + if (g_nrf_num_irks == NRF_IRK_LIST_ENTRIES) { + return BLE_ERR_MEM_CAPACITY; + } + + /* Copy into irk list */ + nrf_entry = &g_nrf_irk_list[4 * g_nrf_num_irks]; + memcpy(nrf_entry, irk, 16); + + /* Add to total */ + ++g_nrf_num_irks; + return BLE_ERR_SUCCESS; +} + +/** + * Remove a device from the hw resolving list + * + * @param index Index of IRK to remove + */ +void +ble_hw_resolv_list_rmv(int index) +{ + uint32_t *irk_entry; + + if (index < g_nrf_num_irks) { + --g_nrf_num_irks; + irk_entry = &g_nrf_irk_list[index]; + if (g_nrf_num_irks > index) { + memmove(irk_entry, irk_entry + 4, 16 * (g_nrf_num_irks - index)); + } + } +} + +/** + * Returns the size of the resolving list. NOTE: this returns the maximum + * allowable entries in the HW. Configuration options may limit this. + * + * @return int Number of devices allowed in resolving list + */ +uint8_t +ble_hw_resolv_list_size(void) +{ + return BLE_HW_RESOLV_LIST_SIZE; +} + +/** + * Called to determine if the address received was resolved. + * + * @return int Negative values indicate unresolved address; positive values + * indicate index in resolving list of resolved address. + */ +int +ble_hw_resolv_list_match(void) +{ + if (NRF_AAR->ENABLE && NRF_AAR->EVENTS_END && NRF_AAR->EVENTS_RESOLVED) { + return (int)NRF_AAR->STATUS; + } + + return -1; +} +#endif diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c new file mode 100644 index 0000000000..a94cb2a75a --- /dev/null +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -0,0 +1,2301 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "syscfg/syscfg.h" +#include "os/os.h" +/* Keep os_cputime explicitly to enable build on non-Mynewt platforms */ +#include "os/os_cputime.h" +#include "ble/xcvr.h" +#include "nimble/ble.h" +#include "nimble/nimble_opt.h" +#include "nimble/nimble_npl.h" +#include "controller/ble_phy.h" +#include "controller/ble_phy_trace.h" +#include "controller/ble_ll.h" +#include "nrfx.h" +#if MYNEWT +#include "mcu/nrf52_clock.h" +#include "mcu/cmsis_nvic.h" +#include "hal/hal_gpio.h" +#else +#include "core_cm4.h" +#endif + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) +#if !MYNEWT_VAL_CHOICE(MCU_TARGET, nRF52840) && !MYNEWT_VAL_CHOICE(MCU_TARGET, nRF52811) +#error LE Coded PHY can only be enabled on nRF52811 or nRF52840 +#endif +#endif + +#if BABBLESIM +extern void tm_tick(void); +#endif + +/* + * NOTE: This code uses a couple of PPI channels so care should be taken when + * using PPI somewhere else. + * + * Pre-programmed channels: CH20, CH21, CH23, CH25, CH31 + * Regular channels: CH4, CH5 and optionally CH6, CH7, CH17, CH18, CH19 + * - CH4 = cancel wfr timer on address match + * - CH5 = disable radio on wfr timer expiry + * - CH6 = PA/LNA control (enable) + * - CH7 = PA/LNA control (disable) + * - CH17 = (optional) gpio debug for radio ramp-up + * - CH18 = (optional) gpio debug for wfr timer RX enabled + * - CH19 = (optional) gpio debug for wfr timer radio disabled + * + */ + +/* XXX: 4) Make sure RF is higher priority interrupt than schedule */ + +/* + * XXX: Maximum possible transmit time is 1 msec for a 60ppm crystal + * and 16ms for a 30ppm crystal! We need to limit PDU size based on + * crystal accuracy. Look at this in the spec. + */ + +/* XXX: private header file? */ +extern uint8_t g_nrf_num_irks; +extern uint32_t g_nrf_irk_list[]; + +/* To disable all radio interrupts */ +#define NRF_RADIO_IRQ_MASK_ALL (0x34FF) + +/* + * We configure the nrf with a 1 byte S0 field, 8 bit length field, and + * zero bit S1 field. The preamble is 8 bits long. + */ +#define NRF_LFLEN_BITS (8) +#define NRF_S0LEN (1) +#define NRF_S1LEN_BITS (0) +#define NRF_CILEN_BITS (2) +#define NRF_TERMLEN_BITS (3) + +/* Maximum length of frames */ +#define NRF_MAXLEN (255) +#define NRF_BALEN (3) /* For base address of 3 bytes */ + +/* NRF_RADIO->PCNF0 configuration values */ +#define NRF_PCNF0 (NRF_LFLEN_BITS << RADIO_PCNF0_LFLEN_Pos) | \ + (RADIO_PCNF0_S1INCL_Msk) | \ + (NRF_S0LEN << RADIO_PCNF0_S0LEN_Pos) | \ + (NRF_S1LEN_BITS << RADIO_PCNF0_S1LEN_Pos) +#define NRF_PCNF0_1M (NRF_PCNF0) | \ + (RADIO_PCNF0_PLEN_8bit << RADIO_PCNF0_PLEN_Pos) +#define NRF_PCNF0_2M (NRF_PCNF0) | \ + (RADIO_PCNF0_PLEN_16bit << RADIO_PCNF0_PLEN_Pos) +#define NRF_PCNF0_CODED (NRF_PCNF0) | \ + (RADIO_PCNF0_PLEN_LongRange << RADIO_PCNF0_PLEN_Pos) | \ + (NRF_CILEN_BITS << RADIO_PCNF0_CILEN_Pos) | \ + (NRF_TERMLEN_BITS << RADIO_PCNF0_TERMLEN_Pos) + +/* BLE PHY data structure */ +struct ble_phy_obj +{ + uint8_t phy_stats_initialized; + int8_t phy_txpwr_dbm; + uint8_t phy_chan; + uint8_t phy_state; + uint8_t phy_transition; + uint8_t phy_transition_late; + uint8_t phy_rx_started; + uint8_t phy_encrypted; + uint8_t phy_privacy; + uint8_t phy_tx_pyld_len; + uint8_t phy_cur_phy_mode; + uint8_t phy_tx_phy_mode; + uint8_t phy_rx_phy_mode; + uint8_t phy_bcc_offset; + int8_t rx_pwr_compensation; + uint32_t phy_aar_scratch; + uint32_t phy_access_address; + struct ble_mbuf_hdr rxhdr; + void *txend_arg; + ble_phy_tx_end_func txend_cb; + uint32_t phy_start_cputime; +#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) + uint16_t tifs; +#endif +}; +struct ble_phy_obj g_ble_phy_data; + +/* XXX: if 27 byte packets desired we can make this smaller */ +/* Global transmit/receive buffer */ +static uint32_t g_ble_phy_tx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4]; +static uint32_t g_ble_phy_rx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4]; + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) +/* Make sure word-aligned for faster copies */ +static uint32_t g_ble_phy_enc_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4]; +#endif + +/* RF center frequency for each channel index (offset from 2400 MHz) */ +static const uint8_t g_ble_phy_chan_freq[BLE_PHY_NUM_CHANS] = { + 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, /* 0-9 */ + 24, 28, 30, 32, 34, 36, 38, 40, 42, 44, /* 10-19 */ + 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, /* 20-29 */ + 66, 68, 70, 72, 74, 76, 78, 2, 26, 80, /* 30-39 */ +}; + +#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +/* packet start offsets (in usecs) */ +static const uint16_t g_ble_phy_mode_pkt_start_off[BLE_PHY_NUM_MODE] = { + [BLE_PHY_MODE_1M] = 40, + [BLE_PHY_MODE_2M] = 24, + [BLE_PHY_MODE_CODED_125KBPS] = 376, + [BLE_PHY_MODE_CODED_500KBPS] = 376 +}; +#endif + +/* Various radio timings */ +/* Radio ramp-up times in usecs (fast mode) */ +#define BLE_PHY_T_TXENFAST (XCVR_TX_RADIO_RAMPUP_USECS) +#define BLE_PHY_T_RXENFAST (XCVR_RX_RADIO_RAMPUP_USECS) + +#if BABBLESIM +/* delay between EVENTS_READY and start of tx */ +static const uint8_t g_ble_phy_t_txdelay[BLE_PHY_NUM_MODE] = { + [BLE_PHY_MODE_1M] = 1, + [BLE_PHY_MODE_2M] = 1, +}; +/* delay between EVENTS_END and end of txd packet */ +static const uint8_t g_ble_phy_t_txenddelay[BLE_PHY_NUM_MODE] = { + [BLE_PHY_MODE_1M] = 1, + [BLE_PHY_MODE_2M] = 1, +}; +/* delay between rxd access address (w/ TERM1 for coded) and EVENTS_ADDRESS */ +static const uint8_t g_ble_phy_t_rxaddrdelay[BLE_PHY_NUM_MODE] = { + [BLE_PHY_MODE_1M] = 9, + [BLE_PHY_MODE_2M] = 5, +}; +/* delay between end of rxd packet and EVENTS_END */ +static const uint8_t g_ble_phy_t_rxenddelay[BLE_PHY_NUM_MODE] = { + [BLE_PHY_MODE_1M] = 9, + [BLE_PHY_MODE_2M] = 5, +}; +#else +/* delay between EVENTS_READY and start of tx */ +static const uint8_t g_ble_phy_t_txdelay[BLE_PHY_NUM_MODE] = { + [BLE_PHY_MODE_1M] = 4, + [BLE_PHY_MODE_2M] = 3, + [BLE_PHY_MODE_CODED_125KBPS] = 5, + [BLE_PHY_MODE_CODED_500KBPS] = 5 +}; +/* delay between EVENTS_END and end of txd packet */ +static const uint8_t g_ble_phy_t_txenddelay[BLE_PHY_NUM_MODE] = { + [BLE_PHY_MODE_1M] = 4, + [BLE_PHY_MODE_2M] = 3, + [BLE_PHY_MODE_CODED_125KBPS] = 9, + [BLE_PHY_MODE_CODED_500KBPS] = 3 +}; +/* delay between rxd access address (w/ TERM1 for coded) and EVENTS_ADDRESS */ +static const uint8_t g_ble_phy_t_rxaddrdelay[BLE_PHY_NUM_MODE] = { + [BLE_PHY_MODE_1M] = 6, + [BLE_PHY_MODE_2M] = 2, + [BLE_PHY_MODE_CODED_125KBPS] = 17, + [BLE_PHY_MODE_CODED_500KBPS] = 17 +}; +/* delay between end of rxd packet and EVENTS_END */ +static const uint8_t g_ble_phy_t_rxenddelay[BLE_PHY_NUM_MODE] = { + [BLE_PHY_MODE_1M] = 6, + [BLE_PHY_MODE_2M] = 2, + [BLE_PHY_MODE_CODED_125KBPS] = 27, + [BLE_PHY_MODE_CODED_500KBPS] = 22 +}; +#endif + +/* Statistics */ +STATS_SECT_START(ble_phy_stats) + STATS_SECT_ENTRY(phy_isrs) + STATS_SECT_ENTRY(tx_good) + STATS_SECT_ENTRY(tx_fail) + STATS_SECT_ENTRY(tx_late) + STATS_SECT_ENTRY(tx_bytes) + STATS_SECT_ENTRY(rx_starts) + STATS_SECT_ENTRY(rx_aborts) + STATS_SECT_ENTRY(rx_valid) + STATS_SECT_ENTRY(rx_crc_err) + STATS_SECT_ENTRY(rx_late) + STATS_SECT_ENTRY(radio_state_errs) + STATS_SECT_ENTRY(rx_hw_err) + STATS_SECT_ENTRY(tx_hw_err) +STATS_SECT_END +STATS_SECT_DECL(ble_phy_stats) ble_phy_stats; + +STATS_NAME_START(ble_phy_stats) + STATS_NAME(ble_phy_stats, phy_isrs) + STATS_NAME(ble_phy_stats, tx_good) + STATS_NAME(ble_phy_stats, tx_fail) + STATS_NAME(ble_phy_stats, tx_late) + STATS_NAME(ble_phy_stats, tx_bytes) + STATS_NAME(ble_phy_stats, rx_starts) + STATS_NAME(ble_phy_stats, rx_aborts) + STATS_NAME(ble_phy_stats, rx_valid) + STATS_NAME(ble_phy_stats, rx_crc_err) + STATS_NAME(ble_phy_stats, rx_late) + STATS_NAME(ble_phy_stats, radio_state_errs) + STATS_NAME(ble_phy_stats, rx_hw_err) + STATS_NAME(ble_phy_stats, tx_hw_err) +STATS_NAME_END(ble_phy_stats) + +/* + * NOTE: + * Tested the following to see what would happen: + * -> NVIC has radio irq enabled (interrupt # 1, mask 0x2). + * -> Set up nrf to receive. Clear ADDRESS event register. + * -> Enable ADDRESS interrupt on nrf5 by writing to INTENSET. + * -> Enable RX. + * -> Disable interrupts globally using OS_ENTER_CRITICAL(). + * -> Wait until a packet is received and the ADDRESS event occurs. + * -> Call ble_phy_disable(). + * + * At this point I wanted to see the state of the cortex NVIC. The IRQ + * pending bit was TRUE for the radio interrupt (as expected) as we never + * serviced the radio interrupt (interrupts were disabled). + * + * What was unexpected was this: without clearing the pending IRQ in the NVIC, + * when radio interrupts were re-enabled (address event bit in INTENSET set to + * 1) and the radio ADDRESS event register read 1 (it was never cleared after + * the first address event), the radio did not enter the ISR! I would have + * expected that if the following were true, an interrupt would occur: + * -> NVIC ISER bit set to TRUE + * -> NVIC ISPR bit reads TRUE, meaning interrupt is pending. + * -> Radio peripheral interrupts are enabled for some event (or events). + * -> Corresponding event register(s) in radio peripheral read 1. + * + * Not sure what the end result of all this is. We will clear the pending + * bit in the NVIC just to be sure when we disable the PHY. + */ + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) + +/* + * Per nordic, the number of bytes needed for scratch is 16 + MAX_PKT_SIZE. + * However, when I used a smaller size it still overwrote the scratchpad. Until + * I figure this out I am just going to allocate 67 words so we have enough + * space for 267 bytes of scratch. I used 268 bytes since not sure if this + * needs to be aligned and burning a byte is no big deal. + */ +//#define NRF_ENC_SCRATCH_WORDS (((MYNEWT_VAL(BLE_LL_MAX_PKT_SIZE) + 16) + 3) / 4) +#define NRF_ENC_SCRATCH_WORDS (67) + +uint32_t g_nrf_encrypt_scratchpad[NRF_ENC_SCRATCH_WORDS]; + +struct nrf_ccm_data +{ + uint8_t key[16]; + uint64_t pkt_counter; + uint8_t dir_bit; + uint8_t iv[8]; +} __attribute__((packed)); + +struct nrf_ccm_data g_nrf_ccm_data; +#endif + +static int g_ble_phy_gpiote_idx; + +#if MYNEWT_VAL(BLE_LL_FEM_PA) || MYNEWT_VAL(BLE_LL_FEM_LNA) + +#define FEM_SINGLE_GPIO \ + (!MYNEWT_VAL(BLE_LL_FEM_PA) || !MYNEWT_VAL(BLE_LL_FEM_LNA) || \ + (MYNEWT_VAL(BLE_LL_FEM_PA_GPIO) == MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO))) + +#if FEM_SINGLE_GPIO +static uint8_t fem_idx; +#else +#if MYNEWT_VAL(BLE_LL_FEM_PA) +static uint8_t fem_pa_idx; +#endif +#if MYNEWT_VAL(BLE_LL_FEM_LNA) +static uint8_t fem_lna_idx; +#endif +#endif + +#endif + +#ifndef BABBLESIM +static void +ble_phy_apply_errata_102_106_107(void) +{ + /* [102] RADIO: PAYLOAD/END events delayed or not triggered after ADDRESS + * [106] RADIO: Higher CRC error rates for some access addresses + * [107] RADIO: Immediate address match for access addresses containing MSBs 0x00 + */ + *(volatile uint32_t *)0x40001774 = ((*(volatile uint32_t *)0x40001774) & + 0xfffffffe) | 0x01000000; +} +#endif + +#if (BLE_LL_BT5_PHY_SUPPORTED == 1) + +/* Packet start offset (in usecs). This is the preamble plus access address. + * For LE Coded PHY this also includes CI and TERM1. */ +uint32_t +ble_phy_mode_pdu_start_off(int phy_mode) +{ + return g_ble_phy_mode_pkt_start_off[phy_mode]; +} + +#if NRF52840_XXAA +static inline bool +ble_phy_mode_is_coded(uint8_t phy_mode) +{ + return (phy_mode == BLE_PHY_MODE_CODED_125KBPS) || + (phy_mode == BLE_PHY_MODE_CODED_500KBPS); +} + +static void +ble_phy_apply_nrf52840_errata(uint8_t new_phy_mode) +{ + bool new_coded = ble_phy_mode_is_coded(new_phy_mode); + bool cur_coded = ble_phy_mode_is_coded(g_ble_phy_data.phy_cur_phy_mode); + + /* + * Workarounds should be applied only when switching to/from LE Coded PHY + * so no need to apply them every time. + * + * nRF52840 Engineering A Errata v1.2 + * [164] RADIO: Low sensitivity in long range mode + * + * nRF52840 Rev 1 Errata + * [191] RADIO: High packet error rate in BLE Long Range mode + */ + if (new_coded == cur_coded) { + return; + } + + if (new_coded) { +#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_164) + /* [164] */ + *(volatile uint32_t *)0x4000173C |= 0x80000000; + *(volatile uint32_t *)0x4000173C = + ((*(volatile uint32_t *)0x4000173C & 0xFFFFFF00) | 0x5C); +#endif +#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_191) + /* [191] */ + *(volatile uint32_t *) 0x40001740 = + ((*((volatile uint32_t *) 0x40001740)) & 0x7FFF00FF) | + 0x80000000 | (((uint32_t)(196)) << 8); +#endif + } else { +#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_164) + /* [164] */ + *(volatile uint32_t *)0x4000173C &= ~0x80000000; +#endif +#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_191) + /* [191] */ + *(volatile uint32_t *) 0x40001740 = + ((*((volatile uint32_t *) 0x40001740)) & 0x7FFFFFFF); +#endif + } +} +#endif + +static void +ble_phy_mode_apply(uint8_t phy_mode) +{ + if (phy_mode == g_ble_phy_data.phy_cur_phy_mode) { + return; + } + +#if NRF52840_XXAA + ble_phy_apply_nrf52840_errata(phy_mode); +#endif + + switch (phy_mode) { + case BLE_PHY_MODE_1M: + NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit; + NRF_RADIO->PCNF0 = NRF_PCNF0_1M; + break; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) + case BLE_PHY_MODE_2M: + NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_2Mbit; + NRF_RADIO->PCNF0 = NRF_PCNF0_2M; + break; +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) + case BLE_PHY_MODE_CODED_125KBPS: + NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_LR125Kbit; + NRF_RADIO->PCNF0 = NRF_PCNF0_CODED; + break; + case BLE_PHY_MODE_CODED_500KBPS: + NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_LR500Kbit; + NRF_RADIO->PCNF0 = NRF_PCNF0_CODED; + break; +#endif + default: + assert(0); + } + + g_ble_phy_data.phy_cur_phy_mode = phy_mode; +} + +void +ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode) +{ + g_ble_phy_data.phy_tx_phy_mode = tx_phy_mode; + g_ble_phy_data.phy_rx_phy_mode = rx_phy_mode; +} +#endif + +static void +ble_phy_fem_enable_pa(void) +{ +#if MYNEWT_VAL(BLE_LL_FEM_PA) + ble_ll_fem_pa_enable(); + +#if !FEM_SINGLE_GPIO + NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[fem_pa_idx]); + NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[fem_pa_idx]); +#endif + + NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; +#endif +} + +static void +ble_phy_fem_enable_lna(void) +{ +#if MYNEWT_VAL(BLE_LL_FEM_LNA) + ble_ll_fem_lna_enable(); + +#if !FEM_SINGLE_GPIO + NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[fem_lna_idx]); + NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[fem_lna_idx]); +#endif + + NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; +#endif +} + +int +ble_phy_get_cur_phy(void) +{ +#if (BLE_LL_BT5_PHY_SUPPORTED == 1) + switch (g_ble_phy_data.phy_cur_phy_mode) { + case BLE_PHY_MODE_1M: + return BLE_PHY_1M; + case BLE_PHY_MODE_2M: + return BLE_PHY_2M; + case BLE_PHY_MODE_CODED_125KBPS: + case BLE_PHY_MODE_CODED_500KBPS: + return BLE_PHY_CODED; + default: + assert(0); + return -1; + } +#else + return BLE_PHY_1M; +#endif +} + +/** + * Copies the data from the phy receive buffer into a mbuf chain. + * + * @param dptr Pointer to receive buffer + * @param rxpdu Pointer to already allocated mbuf chain + * + * NOTE: the packet header already has the total mbuf length in it. The + * lengths of the individual mbufs are not set prior to calling. + * + */ +void +ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu) +{ + uint32_t rem_len; + uint32_t copy_len; + uint32_t block_len; + uint32_t block_rem_len; + void *dst; + void *src; + struct os_mbuf * om; + + /* Better be aligned */ + assert(((uint32_t)dptr & 3) == 0); + + block_len = rxpdu->om_omp->omp_databuf_len; + rem_len = OS_MBUF_PKTHDR(rxpdu)->omp_len; + src = dptr; + + /* + * Setup for copying from first mbuf which is shorter due to packet header + * and extra leading space + */ + copy_len = block_len - rxpdu->om_pkthdr_len - 4; + om = rxpdu; + dst = om->om_data; + + while (true) { + /* + * Always copy blocks of length aligned to word size, only last mbuf + * will have remaining non-word size bytes appended. + */ + block_rem_len = copy_len; + copy_len = min(copy_len, rem_len); + copy_len &= ~3; + + dst = om->om_data; + om->om_len = copy_len; + rem_len -= copy_len; + block_rem_len -= copy_len; + +#if BABBLESIM + memcpy(dst, src, copy_len); + dst += copy_len; + src += copy_len; +#else + __asm__ volatile (".syntax unified \n" + " mov r4, %[len] \n" + " b 2f \n" + "1: ldr r3, [%[src], %[len]] \n" + " str r3, [%[dst], %[len]] \n" + "2: subs %[len], #4 \n" + " bpl 1b \n" + " adds %[src], %[src], r4 \n" + " adds %[dst], %[dst], r4 \n" + : [dst] "+r" (dst), [src] "+r" (src), + [len] "+r" (copy_len) + : + : "r3", "r4", "memory" + ); +#endif + + if ((rem_len < 4) && (block_rem_len >= rem_len)) { + break; + } + + /* Move to next mbuf */ + om = SLIST_NEXT(om, om_next); + copy_len = block_len; + } + + /* Copy remaining bytes, if any, to last mbuf */ + om->om_len += rem_len; + +#if BABBLESIM + memcpy(dst, src, rem_len); +#else + __asm__ volatile (".syntax unified \n" + " b 2f \n" + "1: ldrb r3, [%[src], %[len]] \n" + " strb r3, [%[dst], %[len]] \n" + "2: subs %[len], #1 \n" + " bpl 1b \n" + : [len] "+r" (rem_len) + : [dst] "r" (dst), [src] "r" (src) + : "r3", "memory" + ); +#endif + + /* Copy header */ + memcpy(BLE_MBUF_HDR_PTR(rxpdu), &g_ble_phy_data.rxhdr, + sizeof(struct ble_mbuf_hdr)); +} + +/** + * Called when we want to wait if the radio is in either the rx or tx + * disable states. We want to wait until that state is over before doing + * anything to the radio + */ +static void +nrf_wait_disabled(void) +{ + uint32_t state; + + state = NRF_RADIO->STATE; + if (state != RADIO_STATE_STATE_Disabled) { + if ((state == RADIO_STATE_STATE_RxDisable) || + (state == RADIO_STATE_STATE_TxDisable)) { + /* This will end within a short time (6 usecs). Just poll */ + while (NRF_RADIO->STATE == state) { + /* If this fails, something is really wrong. Should last + * no more than 6 usecs */ +#if BABBLESIM + tm_tick(); +#endif + } + } + } +} + +#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) +static uint16_t +ble_phy_tifs_get(void) +{ + return g_ble_phy_data.tifs; +} + +void +ble_phy_tifs_set(uint16_t tifs) +{ + g_ble_phy_data.tifs = tifs; +} +#else +static uint16_t +ble_phy_tifs_get(void) +{ + return BLE_LL_IFS; +} +#endif + +/** + * + * + */ +static int +ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx) +{ + uint32_t next_cc; + uint32_t cur_cc; + uint32_t cntr; + uint32_t delta; + + /* + * We need to adjust start time to include radio ramp-up and TX pipeline + * delay (the latter only if applicable, so only for TX). + * + * Radio ramp-up time is 40 usecs and TX delay is 3 or 5 usecs depending on + * phy, thus we'll offset RTC by 2 full ticks (61 usecs) and then compensate + * using TIMER0 with 1 usec precision. + */ + + cputime -= 2; + rem_usecs += 61; + if (tx) { + rem_usecs -= BLE_PHY_T_TXENFAST; + rem_usecs -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; + } else { + rem_usecs -= BLE_PHY_T_RXENFAST; + } + + /* + * rem_usecs will be no more than 2 ticks, but if it is more than single + * tick then we should better count one more low-power tick rather than + * 30 high-power usecs. Also make sure we don't set TIMER0 CC to 0 as the + * compare won't occur. + */ + + if (rem_usecs > 30) { + cputime++; + rem_usecs -= 30; + } + + /* + * Can we set the RTC compare to start TIMER0? We can do it if: + * a) Current compare value is not N+1 or N+2 ticks from current + * counter. + * b) The value we want to set is not at least N+2 from current + * counter. + * + * NOTE: since the counter can tick 1 while we do these calculations we + * need to account for it. + */ + next_cc = cputime & 0xffffff; + cur_cc = NRF_RTC0->CC[0]; + cntr = NRF_RTC0->COUNTER; + + delta = (cur_cc - cntr) & 0xffffff; + if ((delta <= 3) && (delta != 0)) { + return -1; + } + delta = (next_cc - cntr) & 0xffffff; + if ((delta & 0x800000) || (delta < 3)) { + return -1; + } + + /* Clear and set TIMER0 to fire off at proper time */ + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CLEAR); + nrf_timer_cc_set(NRF_TIMER0, 0, rem_usecs); + NRF_TIMER0->EVENTS_COMPARE[0] = 0; + + /* Set RTC compare to start TIMER0 */ + NRF_RTC0->EVENTS_COMPARE[0] = 0; + nrf_rtc_cc_set(NRF_RTC0, 0, next_cc); + nrf_rtc_event_enable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); + + /* Enable PPI */ + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH31_Msk); + + /* Store the cputime at which we set the RTC */ + g_ble_phy_data.phy_start_cputime = cputime; + + return 0; +} + +static int +ble_phy_set_start_now(void) +{ + os_sr_t sr; + uint32_t now; + + OS_ENTER_CRITICAL(sr); + + /* + * Set TIMER0 to fire immediately. We can't set CC to 0 as compare will not + * occur in such case. + */ + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CLEAR); + nrf_timer_cc_set(NRF_TIMER0, 0, 1); + NRF_TIMER0->EVENTS_COMPARE[0] = 0; + + /* + * Set RTC compare to start TIMER0. We need to set it to at least N+2 ticks + * from current value to guarantee triggering compare event, but let's set + * it to N+3 to account for possible extra tick on RTC0 during these + * operations. + */ + now = os_cputime_get32(); + NRF_RTC0->EVENTS_COMPARE[0] = 0; + nrf_rtc_cc_set(NRF_RTC0, 0, now + 3); + nrf_rtc_event_enable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); + + /* Enable PPI */ + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH31_Msk); + /* + * Store the cputime at which we set the RTC + * + * XXX Compare event may be triggered on previous CC value (if it was set to + * less than N+2) so in rare cases actual start time may be 2 ticks earlier + * than what we expect. Since this is only used on RX, it may cause AUX scan + * to be scheduled 1 or 2 ticks too late so we'll miss it - it's acceptable + * for now. + */ + g_ble_phy_data.phy_start_cputime = now + 3; + + OS_EXIT_CRITICAL(sr); + + return 0; +} + +/** + * Function is used to set PPI so that we can time out waiting for a reception + * to occur. This happens for two reasons: we have sent a packet and we are + * waiting for a response (txrx should be set to ENABLE_TXRX) or we are + * starting a connection event and we are a slave and we are waiting for the + * master to send us a packet (txrx should be set to ENABLE_RX). + * + * NOTE: when waiting for a txrx turn-around, wfr_usecs is not used as there + * is no additional time to wait; we know when we should receive the address of + * the received frame. + * + * @param txrx Flag denoting if this wfr is a txrx turn-around or not. + * @param tx_phy_mode phy mode for last TX (only valid for TX->RX) + * @param wfr_usecs Amount of usecs to wait. + */ +void +ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) +{ + uint32_t end_time; + uint8_t phy; + + phy = g_ble_phy_data.phy_cur_phy_mode; + + if (txrx == BLE_PHY_WFR_ENABLE_TXRX) { + /* RX shall start exactly T_IFS after TX end captured in CC[2] */ + end_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); + /* Adjust for delay between EVENT_END and actual TX end time */ + end_time += g_ble_phy_t_txenddelay[tx_phy_mode]; + /* Wait a bit longer due to allowed active clock accuracy */ + end_time += 2; + /* + * It's possible that we'll capture PDU start time at the end of timer + * cycle and since wfr expires at the beginning of calculated timer + * cycle it can be almost 1 usec too early. Let's compensate for this + * by waiting 1 usec more. + */ + end_time += 1; + } else { + /* + * RX shall start no later than wfr_usecs after RX enabled. + * CC[0] is the time of RXEN so adjust for radio ram-up. + * Do not add jitter since this is already covered by LL. + */ + end_time = NRF_TIMER0->CC[0] + BLE_PHY_T_RXENFAST + wfr_usecs; + } + + /* + * Note: on LE Coded EVENT_ADDRESS is fired after TERM1 is received, so + * we are actually calculating relative to start of packet payload + * which is fine. + */ + + /* Adjust for receiving access address since this triggers EVENT_ADDRESS */ + end_time += ble_phy_mode_pdu_start_off(phy); + /* Adjust for delay between actual access address RX and EVENT_ADDRESS */ + end_time += g_ble_phy_t_rxaddrdelay[phy]; + + /* wfr_secs is the time from rxen until timeout */ + nrf_timer_cc_set(NRF_TIMER0, 3, end_time); + NRF_TIMER0->EVENTS_COMPARE[3] = 0; + + /* Enable wait for response PPI */ + nrf_ppi_channels_enable(NRF_PPI, (PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk)); + + /* + * It may happen that if CPU is halted for a brief moment (e.g. during flash + * erase or write), TIMER0 already counted past CC[3] and thus wfr will not + * fire as expected. In case this happened, let's just disable PPIs for wfr + * and trigger wfr manually (i.e. disable radio). + * + * Note that the same applies to RX start time set in CC[0] but since it + * should fire earlier than wfr, fixing wfr is enough. + * + * CC[1] is only used as a reference on RX start, we do not need it here so + * it can be used to read TIMER0 counter. + */ + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE1); + if (NRF_TIMER0->CC[1] > NRF_TIMER0->CC[3]) { + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk); + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + } +} + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) +static uint32_t +ble_phy_get_ccm_datarate(void) +{ +#if BLE_LL_BT5_PHY_SUPPORTED + switch (g_ble_phy_data.phy_cur_phy_mode) { + case BLE_PHY_MODE_1M: + return CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos; + case BLE_PHY_MODE_2M: + return CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) + case BLE_PHY_MODE_CODED_125KBPS: + return CCM_MODE_DATARATE_125Kbps << CCM_MODE_DATARATE_Pos; + case BLE_PHY_MODE_CODED_500KBPS: + return CCM_MODE_DATARATE_500Kbps << CCM_MODE_DATARATE_Pos; +#endif + } + + assert(0); + return 0; +#else + return CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos; +#endif +} +#endif + +/** + * Setup transceiver for receive. + */ +static void +ble_phy_rx_xcvr_setup(void) +{ + uint8_t *dptr; + + dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; + dptr += 3; + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) + if (g_ble_phy_data.phy_encrypted) { + NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0]; + NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0]; + NRF_CCM->OUTPTR = (uint32_t)dptr; + NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0]; + NRF_CCM->MODE = CCM_MODE_LENGTH_Msk | CCM_MODE_MODE_Decryption | + ble_phy_get_ccm_datarate(); + NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data; + NRF_CCM->SHORTS = 0; + NRF_CCM->EVENTS_ERROR = 0; + NRF_CCM->EVENTS_ENDCRYPT = 0; + nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH25_Msk); + } else { + NRF_RADIO->PACKETPTR = (uint32_t)dptr; + } +#else + NRF_RADIO->PACKETPTR = (uint32_t)dptr; +#endif + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + if (g_ble_phy_data.phy_privacy) { + NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Enabled; + NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; + NRF_AAR->SCRATCHPTR = (uint32_t)&g_ble_phy_data.phy_aar_scratch; + NRF_AAR->EVENTS_END = 0; + NRF_AAR->EVENTS_RESOLVED = 0; + NRF_AAR->EVENTS_NOTRESOLVED = 0; + } else { + if (g_ble_phy_data.phy_encrypted == 0) { + NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Disabled; + } + } +#endif + + /* Turn off trigger TXEN on output compare match and AAR on bcmatch */ + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk | PPI_CHEN_CH23_Msk); + + /* Reset the rx started flag. Used for the wait for response */ + g_ble_phy_data.phy_rx_started = 0; + g_ble_phy_data.phy_state = BLE_PHY_STATE_RX; + +#if BLE_LL_BT5_PHY_SUPPORTED + /* + * On Coded PHY there are CI and TERM1 fields before PDU starts so we need + * to take this into account when setting up BCC. + */ + if (g_ble_phy_data.phy_cur_phy_mode == BLE_PHY_MODE_CODED_125KBPS || + g_ble_phy_data.phy_cur_phy_mode == BLE_PHY_MODE_CODED_500KBPS) { + g_ble_phy_data.phy_bcc_offset = 5; + } else { + g_ble_phy_data.phy_bcc_offset = 0; + } +#else + g_ble_phy_data.phy_bcc_offset = 0; +#endif + + /* I want to know when 1st byte received (after address) */ + nrf_radio_bcc_set(NRF_RADIO, 8 + g_ble_phy_data.phy_bcc_offset); /* in bits */ + NRF_RADIO->EVENTS_ADDRESS = 0; + NRF_RADIO->EVENTS_DEVMATCH = 0; + NRF_RADIO->EVENTS_BCMATCH = 0; + NRF_RADIO->EVENTS_RSSIEND = 0; + NRF_RADIO->EVENTS_CRCOK = 0; + NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk | + RADIO_SHORTS_READY_START_Msk | + RADIO_SHORTS_ADDRESS_BCSTART_Msk | + RADIO_SHORTS_ADDRESS_RSSISTART_Msk | + RADIO_SHORTS_DISABLED_RSSISTOP_Msk; + + nrf_radio_int_enable(NRF_RADIO, RADIO_INTENSET_ADDRESS_Msk | + RADIO_INTENSET_DISABLED_Msk); +} + +/** + * Called from interrupt context when the transmit ends + * + */ +static void +ble_phy_tx_end_isr(void) +{ + uint8_t tx_phy_mode; + uint8_t was_encrypted; + uint8_t transition; + uint32_t rx_time; + uint32_t tx_time; + + /* Store PHY on which we've just transmitted smth */ + tx_phy_mode = g_ble_phy_data.phy_cur_phy_mode; + + /* If this transmission was encrypted we need to remember it */ + was_encrypted = g_ble_phy_data.phy_encrypted; + (void)was_encrypted; + + /* Better be in TX state! */ + assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX); + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) + /* + * XXX: not sure what to do. We had a HW error during transmission. + * For now I just count a stat but continue on like all is good. + */ + if (was_encrypted) { + if (NRF_CCM->EVENTS_ERROR) { + STATS_INC(ble_phy_stats, tx_hw_err); + NRF_CCM->EVENTS_ERROR = 0; + } + } +#endif + + if (g_ble_phy_data.txend_cb) { + g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg); + } + + transition = g_ble_phy_data.phy_transition; + + if (transition == BLE_PHY_TRANSITION_TX_RX) { +#if (BLE_LL_BT5_PHY_SUPPORTED == 1) + ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); +#endif + + /* Packet pointer needs to be reset. */ + ble_phy_rx_xcvr_setup(); + + ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_TXRX, tx_phy_mode, 0); + + /* Schedule RX exactly T_IFS after TX end captured in CC[2] */ + rx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); + /* Adjust for delay between EVENT_END and actual TX end time */ + rx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; + /* Adjust for radio ramp-up */ + rx_time -= BLE_PHY_T_RXENFAST; + /* Start listening a bit earlier due to allowed active clock accuracy */ + rx_time -= 2; + + nrf_timer_cc_set(NRF_TIMER0, 0, rx_time); + NRF_TIMER0->EVENTS_COMPARE[0] = 0; + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); + + ble_phy_fem_enable_lna(); + } else if (transition == BLE_PHY_TRANSITION_TX_TX) { + /* Schedule TX exactly T_IFS after TX end captured in CC[2] */ + tx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); + /* Adjust for delay between EVENT_END and actual TX end time */ + tx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; + /* Adjust for radio ramp-up */ + tx_time -= BLE_PHY_T_TXENFAST; + /* Adjust for delay between EVENT_READY and actual TX start time */ + tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; + + nrf_timer_cc_set(NRF_TIMER0, 0, tx_time); + NRF_TIMER0->EVENTS_COMPARE[0] = 0; + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); + + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); + if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) { + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk); + g_ble_phy_data.phy_transition_late = 1; + } + } else { + /* + * XXX: not sure we need to stop the timer here all the time. Or that + * it should be stopped here. + */ + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP); + NRF_TIMER0->TASKS_SHUTDOWN = 1; + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | + PPI_CHEN_CH20_Msk | PPI_CHEN_CH31_Msk); + assert(transition == BLE_PHY_TRANSITION_NONE); + } +} + +static inline uint8_t +ble_phy_get_cur_rx_phy_mode(void) +{ + uint8_t phy; + + phy = g_ble_phy_data.phy_cur_phy_mode; + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) + /* + * For Coded PHY mode can be set to either codings since actual coding is + * set in packet header. However, here we need actual coding of received + * packet as this determines pipeline delays so need to figure this out + * using CI field. + */ + if ((phy == BLE_PHY_MODE_CODED_125KBPS) || + (phy == BLE_PHY_MODE_CODED_500KBPS)) { + phy = NRF_RADIO->PDUSTAT & RADIO_PDUSTAT_CISTAT_Msk ? + BLE_PHY_MODE_CODED_500KBPS : + BLE_PHY_MODE_CODED_125KBPS; + } +#endif + + return phy; +} + +static void +ble_phy_rx_end_isr(void) +{ + int rc; + uint8_t *dptr; + uint8_t crcok; + uint32_t tx_time; + struct ble_mbuf_hdr *ble_hdr; + + /* Disable automatic RXEN */ + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH21_Msk); + + /* Set RSSI and CRC status flag in header */ + ble_hdr = &g_ble_phy_data.rxhdr; + assert(NRF_RADIO->EVENTS_RSSIEND != 0); + ble_hdr->rxinfo.rssi = (-1 * NRF_RADIO->RSSISAMPLE) + + g_ble_phy_data.rx_pwr_compensation; + + dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; + dptr += 3; + + /* Count PHY crc errors and valid packets */ + crcok = NRF_RADIO->EVENTS_CRCOK; + if (!crcok) { + STATS_INC(ble_phy_stats, rx_crc_err); + } else { + STATS_INC(ble_phy_stats, rx_valid); + ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) + if (g_ble_phy_data.phy_encrypted) { + while (NRF_CCM->EVENTS_ENDCRYPT == 0) { + /* Make sure CCM finished */ + }; + + /* Only set MIC failure flag if frame is not zero length */ + if ((dptr[1] != 0) && (NRF_CCM->MICSTATUS == 0)) { + ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE; + } + + /* + * XXX: not sure how to deal with this. This should not + * be a MIC failure but we should not hand it up. I guess + * this is just some form of rx error and that is how we + * handle it? For now, just set CRC error flags + */ + if (NRF_CCM->EVENTS_ERROR) { + STATS_INC(ble_phy_stats, rx_hw_err); + ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK; + } + } +#endif + } + +#if (BLE_LL_BT5_PHY_SUPPORTED == 1) + ble_phy_mode_apply(g_ble_phy_data.phy_tx_phy_mode); +#endif + + /* + * Let's schedule TX now and we will just cancel it after processing RXed + * packet if we don't need TX. + * + * We need this to initiate connection in case AUX_CONNECT_REQ was sent on + * LE Coded S8. In this case the time we process RXed packet is roughly the + * same as the limit when we need to have TX scheduled (i.e. TIMER0 and PPI + * armed) so we may simply miss the slot and set the timer in the past. + * + * When TX is scheduled in advance, we may event process packet a bit longer + * during radio ramp-up - this gives us extra 40 usecs which is more than + * enough. + */ + + /* Schedule TX exactly T_IFS after RX end captured in CC[2] */ + tx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); + /* Adjust for delay between actual RX end time and EVENT_END */ + tx_time -= g_ble_phy_t_rxenddelay[ble_hdr->rxinfo.phy_mode]; + /* Adjust for radio ramp-up */ + tx_time -= BLE_PHY_T_TXENFAST; + /* Adjust for delay between EVENT_READY and actual TX start time */ + tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; + + nrf_timer_cc_set(NRF_TIMER0, 0, tx_time); + NRF_TIMER0->EVENTS_COMPARE[0] = 0; + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); + + ble_phy_fem_enable_pa(); + + /* + * XXX: Hack warning! + * + * It may happen (during flash erase) that CPU is stopped for a moment and + * TIMER0 already counted past CC[0]. In such case we will be stuck waiting + * for TX to start since EVENTS_COMPARE[0] will not happen any time soon. + * For now let's set a flag denoting that we are late in RX-TX transition so + * ble_phy_tx() will fail - this allows everything to cleanup nicely without + * the need for extra handling in many places. + * + * Note: CC[3] is used only for wfr which we do not need here. + */ + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); + if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) { + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk); + g_ble_phy_data.phy_transition_late = 1; + } + + /* + * XXX: This is a horrible ugly hack to deal with the RAM S1 byte + * that is not sent over the air but is present here. Simply move the + * data pointer to deal with it. Fix this later. + */ + dptr[2] = dptr[1]; + dptr[1] = dptr[0]; + rc = ble_ll_rx_end(dptr + 1, ble_hdr); + if (rc < 0) { + ble_phy_disable(); + } +} + +static bool +ble_phy_rx_start_isr(void) +{ + int rc; + uint32_t state; + uint32_t usecs; + uint32_t pdu_usecs; + uint32_t ticks; + struct ble_mbuf_hdr *ble_hdr; + uint8_t *dptr; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + int adva_offset; +#endif + + dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; + + /* Clear events and clear interrupt */ + NRF_RADIO->EVENTS_ADDRESS = 0; + nrf_radio_int_disable(NRF_RADIO, RADIO_INTENCLR_ADDRESS_Msk); + + /* Clear wfr timer channels */ + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk); + + /* Initialize the ble mbuf header */ + ble_hdr = &g_ble_phy_data.rxhdr; + ble_hdr->rxinfo.flags = ble_ll_state_get(); + ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan; + ble_hdr->rxinfo.handle = 0; + ble_hdr->rxinfo.phy = ble_phy_get_cur_phy(); + ble_hdr->rxinfo.phy_mode = ble_phy_get_cur_rx_phy_mode(); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + ble_hdr->rxinfo.user_data = NULL; +#endif + + /* + * Calculate accurate packets start time (with remainder) + * + * We may start receiving packet somewhere during preamble in which case + * it is possible that actual transmission started before TIMER0 was + * running - need to take this into account. + */ + ble_hdr->beg_cputime = g_ble_phy_data.phy_start_cputime; + + usecs = NRF_TIMER0->CC[1]; + pdu_usecs = ble_phy_mode_pdu_start_off(ble_hdr->rxinfo.phy_mode) + + g_ble_phy_t_rxaddrdelay[ble_hdr->rxinfo.phy_mode]; + if (usecs < pdu_usecs) { + g_ble_phy_data.phy_start_cputime--; + usecs += 30; + } + usecs -= pdu_usecs; + + ticks = os_cputime_usecs_to_ticks(usecs); + usecs -= os_cputime_ticks_to_usecs(ticks); + if (usecs == 31) { + usecs = 0; + ++ticks; + } + + ble_hdr->beg_cputime += ticks; + ble_hdr->rem_usecs = usecs; + + /* XXX: I wonder if we always have the 1st byte. If we need to wait for + * rx chain delay, it could be 18 usecs from address interrupt. The + nrf52 may be able to get here early. */ + /* Wait to get 1st byte of frame */ + while (1) { + state = NRF_RADIO->STATE; + if (NRF_RADIO->EVENTS_BCMATCH != 0) { + break; + } + + /* + * If state is disabled, we should have the BCMATCH. If not, + * something is wrong! + */ + if (state == RADIO_STATE_STATE_Disabled) { + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); + NRF_RADIO->SHORTS = 0; + return false; + } + +#if BABBLESIM + tm_tick(); +#endif + } + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + /* + * If privacy is enabled and received PDU has TxAdd bit set (i.e. random + * address) we try to resolve address using AAR. + */ + if (g_ble_phy_data.phy_privacy && (dptr[3] & 0x40)) { + /* + * AdvA is located at 4th octet in RX buffer (after S0, length an S1 + * fields). In case of extended advertising PDU we need to add 2 more + * octets for extended header. + */ + adva_offset = (dptr[3] & 0x0f) == 0x07 ? 2 : 0; + NRF_AAR->ADDRPTR = (uint32_t)(dptr + 3 + adva_offset); + + /* Trigger AAR after last bit of AdvA is received */ + NRF_RADIO->EVENTS_BCMATCH = 0; + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH23_Msk); + nrf_radio_bcc_set(NRF_RADIO, (BLE_LL_PDU_HDR_LEN + adva_offset + + BLE_DEV_ADDR_LEN) * 8 + g_ble_phy_data.phy_bcc_offset); + } +#endif + + /* Call Link Layer receive start function */ + rc = ble_ll_rx_start(dptr + 3, + g_ble_phy_data.phy_chan, + &g_ble_phy_data.rxhdr); + if (rc >= 0) { + /* Set rx started flag and enable rx end ISR */ + g_ble_phy_data.phy_rx_started = 1; + } else { + /* Disable PHY */ + ble_phy_disable(); + STATS_INC(ble_phy_stats, rx_aborts); + } + + /* Count rx starts */ + STATS_INC(ble_phy_stats, rx_starts); + + return true; +} + +static void +ble_phy_isr(void) +{ + uint32_t irq_en; + + os_trace_isr_enter(); + + /* Read irq register to determine which interrupts are enabled */ + irq_en = NRF_RADIO->INTENSET; + + /* + * NOTE: order of checking is important! Possible, if things get delayed, + * we have both an ADDRESS and DISABLED interrupt in rx state. If we get + * an address, we disable the DISABLED interrupt. + */ + + /* We get this if we have started to receive a frame */ + if ((irq_en & RADIO_INTENCLR_ADDRESS_Msk) && NRF_RADIO->EVENTS_ADDRESS) { + /* + * wfr timer is calculated to expire at the exact time we should start + * receiving a packet (with 1 usec precision) so it is possible it will + * fire at the same time as EVENT_ADDRESS. If this happens, radio will + * be disabled while we are waiting for EVENT_BCCMATCH after 1st byte + * of payload is received and ble_phy_rx_start_isr() will fail. In this + * case we should not clear DISABLED irq mask so it will be handled as + * regular radio disabled event below. In other case radio was disabled + * on purpose and there's nothing more to handle so we can clear mask. + */ + if (ble_phy_rx_start_isr()) { + irq_en &= ~RADIO_INTENCLR_DISABLED_Msk; + } + } + + /* Handle disabled event. This is enabled for both TX and RX. On RX, we + * need to check phy_rx_started flag to make sure we actually were receiving + * a PDU, otherwise this is due to wfr. + */ + if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) { + BLE_LL_ASSERT(NRF_RADIO->EVENTS_END || + ((g_ble_phy_data.phy_state == BLE_PHY_STATE_RX) && + !g_ble_phy_data.phy_rx_started)); + NRF_RADIO->EVENTS_END = 0; + NRF_RADIO->EVENTS_DISABLED = 0; + nrf_radio_int_disable(NRF_RADIO, RADIO_INTENCLR_DISABLED_Msk); + +#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) + g_ble_phy_data.tifs = BLE_LL_IFS; +#endif + + switch (g_ble_phy_data.phy_state) { + case BLE_PHY_STATE_RX: +#if MYNEWT_VAL(BLE_LL_FEM_LNA) + NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; + ble_ll_fem_lna_disable(); +#endif + if (g_ble_phy_data.phy_rx_started) { + ble_phy_rx_end_isr(); + } else { + ble_ll_wfr_timer_exp(NULL); + } + break; + case BLE_PHY_STATE_TX: +#if MYNEWT_VAL(BLE_LL_FEM_PA) + NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; + ble_ll_fem_pa_disable(); +#endif + ble_phy_tx_end_isr(); + break; + default: + BLE_LL_ASSERT(0); + } + } + + g_ble_phy_data.phy_transition_late = 0; + + /* Count # of interrupts */ + STATS_INC(ble_phy_stats, phy_isrs); + + os_trace_isr_exit(); +} + +#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \ + MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \ + MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 || \ + MYNEWT_VAL(BLE_LL_FEM_PA) || \ + MYNEWT_VAL(BLE_LL_FEM_LNA) +static int +ble_phy_gpiote_configure(int pin) +{ + NRF_GPIO_Type *port; + + g_ble_phy_gpiote_idx--; + +#if NRF52840_XXAA + port = pin > 31 ? NRF_P1 : NRF_P0; + pin &= 0x1f; +#else + port = NRF_P0; +#endif + + /* Configure GPIO directly to avoid dependency to hal_gpio (for porting) */ + port->DIRSET = (1 << pin); + port->OUTCLR = (1 << pin); + + NRF_GPIOTE->CONFIG[g_ble_phy_gpiote_idx] = + (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | + ((pin & 0x1F) << GPIOTE_CONFIG_PSEL_Pos) | +#if NRF52840_XXAA + ((port == NRF_P1) << GPIOTE_CONFIG_PORT_Pos); +#else + 0; +#endif + + BLE_LL_ASSERT(g_ble_phy_gpiote_idx >= 0); + + return g_ble_phy_gpiote_idx; +} +#endif + +static void +ble_phy_dbg_time_setup(void) +{ + int idx __attribute__((unused)); + + /* + * We setup GPIOTE starting from last configuration index to minimize risk + * of conflict with GPIO setup via hal. It's not great solution, but since + * this is just debugging code we can live with this. + */ + +#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 + idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); + + nrf_ppi_channel_endpoint_setup(NRF_PPI, 17, (uint32_t)&(NRF_RADIO->EVENTS_READY), + (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH17_Msk); + + /* CH[20] and PPI CH[21] are on to trigger TASKS_TXEN or TASKS_RXEN */ + nrf_ppi_fork_endpoint_setup(NRF_PPI, 20, (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); + nrf_ppi_fork_endpoint_setup(NRF_PPI, 21, (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); +#endif + +#if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 + idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); + + /* CH[26] and CH[27] are always on for EVENT_ADDRESS and EVENT_END */ + nrf_ppi_fork_endpoint_setup(NRF_PPI, 26, (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); + nrf_ppi_fork_endpoint_setup(NRF_PPI, 27, (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); +#endif + +#if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 + idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); + +#if NRF52840_XXAA + nrf_ppi_channel_endpoint_setup(NRF_PPI, 18, (uint32_t)&(NRF_RADIO->EVENTS_RXREADY), + (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); +#else + nrf_ppi_channel_endpoint_setup(NRF_PPI, 18, (uint32_t)&(NRF_RADIO->EVENTS_READY), + (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); +#endif + nrf_ppi_channel_endpoint_setup(NRF_PPI, 19, (uint32_t)&(NRF_RADIO->EVENTS_DISABLED), + (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH18_Msk | PPI_CHEN_CH19_Msk); + + /* CH[4] and CH[5] are always on for wfr */ + nrf_ppi_fork_endpoint_setup(NRF_PPI, 4, (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); + nrf_ppi_fork_endpoint_setup(NRF_PPI, 5, (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); +#endif +} + +/** + * ble phy init + * + * Initialize the PHY. + * + * @return int 0: success; PHY error code otherwise + */ +int +ble_phy_init(void) +{ + int rc; + + g_ble_phy_gpiote_idx = 8; + + /* Default phy to use is 1M */ + g_ble_phy_data.phy_cur_phy_mode = BLE_PHY_MODE_1M; + g_ble_phy_data.phy_tx_phy_mode = BLE_PHY_MODE_1M; + g_ble_phy_data.phy_rx_phy_mode = BLE_PHY_MODE_1M; + + g_ble_phy_data.rx_pwr_compensation = 0; + + /* Set phy channel to an invalid channel so first set channel works */ + g_ble_phy_data.phy_chan = BLE_PHY_NUM_CHANS; + +#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) + g_ble_phy_data.tifs = BLE_LL_IFS; +#endif + + /* Toggle peripheral power to reset (just in case) */ + nrf_radio_power_set(NRF_RADIO, false); + nrf_radio_power_set(NRF_RADIO, true); + + /* Disable all interrupts */ + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); + + /* Set configuration registers */ + NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit; + NRF_RADIO->PCNF0 = NRF_PCNF0; + + /* XXX: should maxlen be 251 for encryption? */ + NRF_RADIO->PCNF1 = NRF_MAXLEN | + (RADIO_PCNF1_ENDIAN_Little << RADIO_PCNF1_ENDIAN_Pos) | + (NRF_BALEN << RADIO_PCNF1_BALEN_Pos) | + RADIO_PCNF1_WHITEEN_Msk; + + /* Enable radio fast ramp-up */ + NRF_RADIO->MODECNF0 |= (RADIO_MODECNF0_RU_Fast << RADIO_MODECNF0_RU_Pos) & + RADIO_MODECNF0_RU_Msk; + + /* Set logical address 1 for TX and RX */ + NRF_RADIO->TXADDRESS = 0; + NRF_RADIO->RXADDRESSES = (1 << 0); + + /* Configure the CRC registers */ + NRF_RADIO->CRCCNF = (RADIO_CRCCNF_SKIPADDR_Skip << RADIO_CRCCNF_SKIPADDR_Pos) | RADIO_CRCCNF_LEN_Three; + + /* Configure BLE poly */ + NRF_RADIO->CRCPOLY = 0x0000065B; + + /* Configure IFS */ + NRF_RADIO->TIFS = BLE_LL_IFS; + + /* Captures tx/rx start in timer0 cc 1 and tx/rx end in timer0 cc 2 */ + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH26_Msk | PPI_CHEN_CH27_Msk); + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) + nrf_ccm_int_disable(NRF_CCM, 0xffffffff); + NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; + NRF_CCM->EVENTS_ERROR = 0; + memset(g_nrf_encrypt_scratchpad, 0, sizeof(g_nrf_encrypt_scratchpad)); +#endif + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + g_ble_phy_data.phy_aar_scratch = 0; + NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; + nrf_aar_int_disable(NRF_AAR, 0xffffffff); + NRF_AAR->EVENTS_END = 0; + NRF_AAR->EVENTS_RESOLVED = 0; + NRF_AAR->EVENTS_NOTRESOLVED = 0; + NRF_AAR->NIRK = 0; +#endif + + /* TIMER0 setup for PHY when using RTC */ + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP); + NRF_TIMER0->TASKS_SHUTDOWN = 1; + NRF_TIMER0->BITMODE = 3; /* 32-bit timer */ + NRF_TIMER0->MODE = 0; /* Timer mode */ + NRF_TIMER0->PRESCALER = 4; /* gives us 1 MHz */ + + /* + * PPI setup. + * Channel 4: Captures TIMER0 in CC[3] when EVENTS_ADDRESS occurs. Used + * to cancel the wait for response timer. + * Channel 5: TIMER0 CC[3] to TASKS_DISABLE on radio. This is the wait + * for response timer. + */ + nrf_ppi_channel_endpoint_setup(NRF_PPI, NRF_PPI_CHANNEL4, + (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS), + (uint32_t)&(NRF_TIMER0->TASKS_CAPTURE[3])); + nrf_ppi_channel_endpoint_setup(NRF_PPI, NRF_PPI_CHANNEL5, + (uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[3]), + (uint32_t)&(NRF_RADIO->TASKS_DISABLE)); + +#if MYNEWT_VAL(BLE_LL_FEM_PA) || MYNEWT_VAL(BLE_LL_FEM_LNA) +#if FEM_SINGLE_GPIO + fem_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); + NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[fem_idx]); + NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[fem_idx]); +#else +#if MYNEWT_VAL(BLE_LL_FEM_PA) + fem_pa_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); + NRF_GPIOTE->TASKS_CLR[fem_pa_idx] = 1; +#endif +#if MYNEWT_VAL(BLE_LL_FEM_LNA) + fem_lna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)); + NRF_GPIOTE->TASKS_CLR[fem_lna_idx] = 1; +#endif +#endif + + NRF_PPI->CH[6].EEP = (uint32_t)&(NRF_RADIO->EVENTS_READY); + NRF_PPI->CH[7].EEP = (uint32_t)&(NRF_RADIO->EVENTS_DISABLED); + NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; +#endif + + /* Set isr in vector table and enable interrupt */ +#ifndef RIOT_VERSION + NVIC_SetPriority(RADIO_IRQn, 0); +#endif +#if MYNEWT + NVIC_SetVector(RADIO_IRQn, (uint32_t)ble_phy_isr); +#else + ble_npl_hw_set_isr(RADIO_IRQn, ble_phy_isr); +#endif + NVIC_EnableIRQ(RADIO_IRQn); + + /* Register phy statistics */ + if (!g_ble_phy_data.phy_stats_initialized) { + rc = stats_init_and_reg(STATS_HDR(ble_phy_stats), + STATS_SIZE_INIT_PARMS(ble_phy_stats, + STATS_SIZE_32), + STATS_NAME_INIT_PARMS(ble_phy_stats), + "ble_phy"); + assert(rc == 0); + + g_ble_phy_data.phy_stats_initialized = 1; + } + + ble_phy_dbg_time_setup(); + + return 0; +} + +/** + * Puts the phy into receive mode. + * + * @return int 0: success; BLE Phy error code otherwise + */ +int +ble_phy_rx(void) +{ + /* + * Check radio state. + * + * In case radio is now disabling we'll wait for it to finish, but if for + * any reason it's just in idle state we proceed with RX as usual since + * nRF52 radio can ramp-up from idle state as well. + * + * Note that TX and RX states values are the same except for 3rd bit so we + * can make a shortcut here when checking for idle state. + */ + nrf_wait_disabled(); + if ((NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) && + ((NRF_RADIO->STATE & 0x07) != RADIO_STATE_STATE_RxIdle)) { + ble_phy_disable(); + STATS_INC(ble_phy_stats, radio_state_errs); + return BLE_PHY_ERR_RADIO_STATE; + } + + /* Make sure all interrupts are disabled */ + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); + + /* Clear events prior to enabling receive */ + NRF_RADIO->EVENTS_END = 0; + NRF_RADIO->EVENTS_DISABLED = 0; + + /* Setup for rx */ + ble_phy_rx_xcvr_setup(); + + /* PPI to start radio automatically shall be set here */ + assert(NRF_PPI->CHEN & PPI_CHEN_CH21_Msk); + + return 0; +} + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) +/** + * Called to enable encryption at the PHY. Note that this state will persist + * in the PHY; in other words, if you call this function you have to call + * disable so that future PHY transmits/receives will not be encrypted. + * + * @param pkt_counter + * @param iv + * @param key + * @param is_master + */ +void +ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key, + uint8_t is_master) +{ + memcpy(g_nrf_ccm_data.key, key, 16); + g_nrf_ccm_data.pkt_counter = pkt_counter; + memcpy(g_nrf_ccm_data.iv, iv, 8); + g_nrf_ccm_data.dir_bit = is_master; + g_ble_phy_data.phy_encrypted = 1; + /* Enable the module (AAR cannot be on while CCM on) */ + NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Disabled; + NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled; +} + +void +ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir) +{ + g_nrf_ccm_data.pkt_counter = pkt_counter; + g_nrf_ccm_data.dir_bit = dir; +} + +void +ble_phy_encrypt_disable(void) +{ + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH25_Msk); + nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_STOP); + NRF_CCM->EVENTS_ERROR = 0; + NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled; + + g_ble_phy_data.phy_encrypted = 0; +} +#endif + +void +ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb, void *arg) +{ + /* Set transmit end callback and arg */ + g_ble_phy_data.txend_cb = txend_cb; + g_ble_phy_data.txend_arg = arg; +} + +/** + * Called to set the start time of a transmission. + * + * This function is called to set the start time when we are not going from + * rx to tx automatically. + * + * NOTE: care must be taken when calling this function. The channel should + * already be set. + * + * @param cputime This is the tick at which the 1st bit of the preamble + * should be transmitted + * @param rem_usecs This is used only when the underlying timing uses a 32.768 + * kHz crystal. It is the # of usecs from the cputime tick + * at which the first bit of the preamble should be + * transmitted. + * @return int + */ +int +ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) +{ + int rc; + + ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_TX, cputime, rem_usecs); + +#if (BLE_LL_BT5_PHY_SUPPORTED == 1) + ble_phy_mode_apply(g_ble_phy_data.phy_tx_phy_mode); +#endif + + /* XXX: This should not be necessary, but paranoia is good! */ + /* Clear timer0 compare to RXEN since we are transmitting */ + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH21_Msk); + + if (ble_phy_set_start_time(cputime, rem_usecs, true) != 0) { + STATS_INC(ble_phy_stats, tx_late); + ble_phy_disable(); + rc = BLE_PHY_ERR_TX_LATE; + } else { + /* Enable PPI to automatically start TXEN */ + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); + rc = 0; + + ble_phy_fem_enable_pa(); + } + + return rc; +} + +/** + * Called to set the start time of a reception + * + * This function acts a bit differently than transmit. If we are late getting + * here we will still attempt to receive. + * + * NOTE: care must be taken when calling this function. The channel should + * already be set. + * + * @param cputime + * + * @return int + */ +int +ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) +{ + bool late = false; + int rc = 0; + + ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_RX, cputime, rem_usecs); + +#if (BLE_LL_BT5_PHY_SUPPORTED == 1) + ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); +#endif + + /* XXX: This should not be necessary, but paranoia is good! */ + /* Clear timer0 compare to TXEN since we are transmitting */ + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk); + + if (ble_phy_set_start_time(cputime, rem_usecs, false) != 0) { + STATS_INC(ble_phy_stats, rx_late); + + /* We're late so let's just try to start RX as soon as possible */ + ble_phy_set_start_now(); + + late = true; + } + + /* Enable PPI to automatically start RXEN */ + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); + + ble_phy_fem_enable_lna(); + + /* Start rx */ + rc = ble_phy_rx(); + + /* + * If we enabled receiver but were late, let's return proper error code so + * caller can handle this. + */ + if (!rc && late) { + rc = BLE_PHY_ERR_RX_LATE; + } + + return rc; +} + +int +ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) +{ + int rc; + uint8_t *dptr; + uint8_t *pktptr; + uint8_t payload_len; + uint8_t hdr_byte; + uint32_t state; + uint32_t shortcuts; + + if (g_ble_phy_data.phy_transition_late) { + ble_phy_disable(); + STATS_INC(ble_phy_stats, tx_late); + return BLE_PHY_ERR_TX_LATE; + } + + /* + * This check is to make sure that the radio is not in a state where + * it is moving to disabled state. If so, let it get there. + */ + nrf_wait_disabled(); + + /* + * XXX: Although we may not have to do this here, I clear all the PPI + * that should not be used when transmitting. Some of them are only enabled + * if encryption and/or privacy is on, but I dont care. Better to be + * paranoid, and if you are going to clear one, might as well clear them + * all. + */ + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | + PPI_CHEN_CH23_Msk | PPI_CHEN_CH25_Msk); + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) + if (g_ble_phy_data.phy_encrypted) { + dptr = (uint8_t *)&g_ble_phy_enc_buf[0]; + pktptr = (uint8_t *)&g_ble_phy_tx_buf[0]; + NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; + NRF_CCM->INPTR = (uint32_t)dptr; + NRF_CCM->OUTPTR = (uint32_t)pktptr; + NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0]; + NRF_CCM->EVENTS_ERROR = 0; + NRF_CCM->MODE = CCM_MODE_LENGTH_Msk | ble_phy_get_ccm_datarate(); + NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data; + } else { +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; +#endif + dptr = (uint8_t *)&g_ble_phy_tx_buf[0]; + pktptr = dptr; + } +#else + dptr = (uint8_t *)&g_ble_phy_tx_buf[0]; + pktptr = dptr; +#endif + + /* Set PDU payload */ + payload_len = pducb(&dptr[3], pducb_arg, &hdr_byte); + + /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */ + dptr[0] = hdr_byte; + dptr[1] = payload_len; + dptr[2] = 0; + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) + /* Start key-stream generation and encryption (via short) */ + if (g_ble_phy_data.phy_encrypted) { + nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); + } +#endif + + NRF_RADIO->PACKETPTR = (uint32_t)pktptr; + + /* Clear the ready, end and disabled events */ + NRF_RADIO->EVENTS_READY = 0; + NRF_RADIO->EVENTS_END = 0; + NRF_RADIO->EVENTS_DISABLED = 0; + + /* Enable shortcuts for transmit start/end. */ + shortcuts = RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_READY_START_Msk; + NRF_RADIO->SHORTS = shortcuts; + nrf_radio_int_enable(NRF_RADIO, RADIO_INTENSET_DISABLED_Msk); + + /* Set the PHY transition */ + g_ble_phy_data.phy_transition = end_trans; + + /* Set transmitted payload length */ + g_ble_phy_data.phy_tx_pyld_len = payload_len; + + /* If we already started transmitting, abort it! */ + state = NRF_RADIO->STATE; + if (state != RADIO_STATE_STATE_Tx) { + /* Set phy state to transmitting and count packet statistics */ + g_ble_phy_data.phy_state = BLE_PHY_STATE_TX; + STATS_INC(ble_phy_stats, tx_good); + STATS_INCN(ble_phy_stats, tx_bytes, payload_len + BLE_LL_PDU_HDR_LEN); + rc = BLE_ERR_SUCCESS; + } else { + ble_phy_disable(); + STATS_INC(ble_phy_stats, tx_late); + rc = BLE_PHY_ERR_RADIO_STATE; + } + + return rc; +} + +/** + * ble phy txpwr set + * + * Set the transmit output power (in dBm). + * + * NOTE: If the output power specified is within the BLE limits but outside + * the chip limits, we "rail" the power level so we dont exceed the min/max + * chip values. + * + * @param dbm Power output in dBm. + * + * @return int 0: success; anything else is an error + */ +int +ble_phy_txpwr_set(int dbm) +{ + /* "Rail" power level if outside supported range */ + dbm = ble_phy_txpower_round(dbm); + + NRF_RADIO->TXPOWER = dbm; + g_ble_phy_data.phy_txpwr_dbm = dbm; + + return 0; +} + +/** + * ble phy txpwr round + * + * Get the rounded transmit output power (in dBm). + * + * @param dbm Power output in dBm. + * + * @return int Rounded power in dBm + */ +int ble_phy_txpower_round(int dbm) +{ + /* TODO this should be per nRF52XXX */ + + /* "Rail" power level if outside supported range */ + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos4dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Pos4dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_0dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_0dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm; + } + + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm; +} + +/** + * ble phy set access addr + * + * Set access address. + * + * @param access_addr Access address + * + * @return int 0: success; PHY error code otherwise + */ +static int +ble_phy_set_access_addr(uint32_t access_addr) +{ + NRF_RADIO->BASE0 = (access_addr << 8); + NRF_RADIO->PREFIX0 = (NRF_RADIO->PREFIX0 & 0xFFFFFF00) | (access_addr >> 24); + + g_ble_phy_data.phy_access_address = access_addr; + +#ifndef BABBLESIM + ble_phy_apply_errata_102_106_107(); +#endif + return 0; +} + +/** + * ble phy txpwr get + * + * Get the transmit power. + * + * @return int The current PHY transmit power, in dBm + */ +int +ble_phy_txpwr_get(void) +{ + return g_ble_phy_data.phy_txpwr_dbm; +} + +void +ble_phy_set_rx_pwr_compensation(int8_t compensation) +{ + g_ble_phy_data.rx_pwr_compensation = compensation; +} + +/** + * ble phy setchan + * + * Sets the logical frequency of the transceiver. The input parameter is the + * BLE channel index (0 to 39, inclusive). The NRF frequency register works like + * this: logical frequency = 2400 + FREQ (MHz). + * + * Thus, to get a logical frequency of 2402 MHz, you would program the + * FREQUENCY register to 2. + * + * @param chan This is the Data Channel Index or Advertising Channel index + * + * @return int 0: success; PHY error code otherwise + */ +int +ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit) +{ + assert(chan < BLE_PHY_NUM_CHANS); + + /* Check for valid channel range */ + if (chan >= BLE_PHY_NUM_CHANS) { + return BLE_PHY_ERR_INV_PARAM; + } + + /* Set current access address */ + ble_phy_set_access_addr(access_addr); + + /* Configure crcinit */ + NRF_RADIO->CRCINIT = crcinit; + + /* Set the frequency and the data whitening initial value */ + g_ble_phy_data.phy_chan = chan; + NRF_RADIO->FREQUENCY = g_ble_phy_chan_freq[chan]; + NRF_RADIO->DATAWHITEIV = chan; + + return 0; +} + +/** + * Stop the timer used to count microseconds when using RTC for cputime + */ +static void +ble_phy_stop_usec_timer(void) +{ + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP); + NRF_TIMER0->TASKS_SHUTDOWN = 1; + nrf_rtc_event_disable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); +} + +/** + * ble phy disable irq and ppi + * + * This routine is to be called when reception was stopped due to either a + * wait for response timeout or a packet being received and the phy is to be + * restarted in receive mode. Generally, the disable routine is called to stop + * the phy. + */ +static void +ble_phy_disable_irq_and_ppi(void) +{ + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); + NRF_RADIO->SHORTS = 0; + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | + PPI_CHEN_CH20_Msk | PPI_CHEN_CH21_Msk | PPI_CHEN_CH23_Msk | + PPI_CHEN_CH25_Msk | PPI_CHEN_CH31_Msk); + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk); + NVIC_ClearPendingIRQ(RADIO_IRQn); + g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE; +} + +void +ble_phy_restart_rx(void) +{ + ble_phy_stop_usec_timer(); + ble_phy_disable_irq_and_ppi(); + + ble_phy_set_start_now(); + /* Enable PPI to automatically start RXEN */ + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); + + ble_phy_rx(); +} + +/** + * ble phy disable + * + * Disables the PHY. This should be called when an event is over. It stops + * the usec timer (if used), disables interrupts, disables the RADIO, disables + * PPI and sets state to idle. + */ +void +ble_phy_disable(void) +{ + ble_phy_trace_void(BLE_PHY_TRACE_ID_DISABLE); + + ble_phy_stop_usec_timer(); + ble_phy_disable_irq_and_ppi(); +} + +/* Gets the current access address */ +uint32_t ble_phy_access_addr_get(void) +{ + return g_ble_phy_data.phy_access_address; +} + +/** + * Return the phy state + * + * @return int The current PHY state. + */ +int +ble_phy_state_get(void) +{ + return g_ble_phy_data.phy_state; +} + +/** + * Called to see if a reception has started + * + * @return int + */ +int +ble_phy_rx_started(void) +{ + return g_ble_phy_data.phy_rx_started; +} + +/** + * Return the transceiver state + * + * @return int transceiver state. + */ +uint8_t +ble_phy_xcvr_state_get(void) +{ + uint32_t state; + state = NRF_RADIO->STATE; + return (uint8_t)state; +} + +/** + * Called to return the maximum data pdu payload length supported by the + * phy. For this chip, if encryption is enabled, the maximum payload is 27 + * bytes. + * + * @return uint8_t Maximum data channel PDU payload size supported + */ +uint8_t +ble_phy_max_data_pdu_pyld(void) +{ + return BLE_LL_DATA_PDU_MAX_PYLD; +} + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) +void +ble_phy_resolv_list_enable(void) +{ + NRF_AAR->NIRK = (uint32_t)g_nrf_num_irks; + g_ble_phy_data.phy_privacy = 1; +} + +void +ble_phy_resolv_list_disable(void) +{ + g_ble_phy_data.phy_privacy = 0; +} +#endif + +#if MYNEWT_VAL(BLE_LL_DTM) +void ble_phy_enable_dtm(void) +{ + /* When DTM is enabled we need to disable whitening as per + * Bluetooth v5.0 Vol 6. Part F. 4.1.1 + */ + NRF_RADIO->PCNF1 &= ~RADIO_PCNF1_WHITEEN_Msk; +} + +void ble_phy_disable_dtm(void) +{ + /* Enable whitening */ + NRF_RADIO->PCNF1 |= RADIO_PCNF1_WHITEEN_Msk; +} +#endif + +void +ble_phy_rfclk_enable(void) +{ +#if MYNEWT || defined(RIOT_VERSION) + nrf52_clock_hfxo_request(); +#else + nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART); +#endif +} + +void +ble_phy_rfclk_disable(void) +{ +#if MYNEWT || defined(RIOT_VERSION) + nrf52_clock_hfxo_release(); +#else + nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); +#endif +} diff --git a/nimble/drivers/nrf5x/src/ble_phy_trace.c b/nimble/drivers/nrf5x/src/ble_phy_trace.c new file mode 100644 index 0000000000..93b2eb3263 --- /dev/null +++ b/nimble/drivers/nrf5x/src/ble_phy_trace.c @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#include +#include "syscfg/syscfg.h" +#include "os/os_trace_api.h" + +#if MYNEWT_VAL(BLE_PHY_SYSVIEW) + +static os_trace_module_t g_ble_phy_trace_mod; +uint32_t ble_phy_trace_off; + +static void +ble_phy_trace_module_send_desc(void) +{ + os_trace_module_desc(&g_ble_phy_trace_mod, "0 phy_set_tx cputime=%u usecs=%u"); + os_trace_module_desc(&g_ble_phy_trace_mod, "1 phy_set_rx cputime=%u usecs=%u"); + os_trace_module_desc(&g_ble_phy_trace_mod, "2 phy_disable"); +} + +void +ble_phy_trace_init(void) +{ + ble_phy_trace_off = + os_trace_module_register(&g_ble_phy_trace_mod, "ble_phy", 3, + ble_phy_trace_module_send_desc); +} +#endif diff --git a/nimble/drivers/nrf5x/syscfg.yml b/nimble/drivers/nrf5x/syscfg.yml new file mode 100644 index 0000000000..3bd49708ca --- /dev/null +++ b/nimble/drivers/nrf5x/syscfg.yml @@ -0,0 +1,72 @@ +# 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. +# + +syscfg.defs: + BLE_PHY_SYSVIEW: + description: > + Enable SystemView tracing module for radio driver. + value: 0 + + BLE_PHY_DBG_TIME_TXRXEN_READY_PIN: + description: > + When set to proper GPIO pin number, this pin will be set + to high state when radio is enabled using PPI channels + 20 or 21 and back to low state on radio EVENTS_READY. + This can be used to measure radio ram-up time. + value: -1 + + BLE_PHY_DBG_TIME_ADDRESS_END_PIN: + description: > + When set to proper GPIO pin number, this pin will be set + to high state on radio EVENTS_ADDRESS and back to low state + on radio EVENTS_END. + This can be used to measure radio pipeline delays. + value: -1 + + BLE_PHY_DBG_TIME_WFR_PIN: + description: > + When set to proper GPIO pin number, this pin will be set + to high state on radio EVENTS_RXREADY and back to low + state when wfr timer expires. + This can be used to check if wfr is calculated properly. + value: -1 + + BLE_PHY_NRF52840_ERRATA_164: + description: > + Enable workaround for anomaly 164 found in nRF52840. + "[164] RADIO: Low selectivity in long range mode" + This shall be only enabled for: + - nRF52840 Engineering A + value: 0 + + BLE_PHY_NRF52840_ERRATA_191: + description: > + Enable workaround for anomaly 191 found in nRF52840. + "[191] RADIO: High packet error rate in BLE Long Range mode" + This shall be only enabled for: + - nRF52840 Engineering B + - nRF52840 Engineering C + - nRF52840 Rev 1 (final silicon) + value: 1 + + BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR: + description: > + Ublox BMD-345 modules come with public address preprogrammed + in UICR register. If enabled public address will be read from + custom UICR instead of FICR register. + value: 0 From 4d3b302fa603fee6cb842341a6e1945ee6e09c19 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 6 Sep 2022 23:01:44 +0200 Subject: [PATCH 0528/1333] nimble/phy/nrf5x: Move out nRF52 code This moves most of code specific to nRF52 series to separate file and creates private phy APIs to call that code. The moved code is anything related to PPI: FEM, GPIO debug and PPI itself. --- nimble/drivers/nrf5x/src/ble_phy.c | 267 +++++------------------ nimble/drivers/nrf5x/src/nrf52/phy.c | 165 ++++++++++++++ nimble/drivers/nrf5x/src/nrf52/phy_ppi.h | 113 ++++++++++ nimble/drivers/nrf5x/src/phy_priv.h | 79 +++++++ 4 files changed, 407 insertions(+), 217 deletions(-) create mode 100644 nimble/drivers/nrf5x/src/nrf52/phy.c create mode 100644 nimble/drivers/nrf5x/src/nrf52/phy_ppi.h create mode 100644 nimble/drivers/nrf5x/src/phy_priv.h diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index a94cb2a75a..9388194833 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "syscfg/syscfg.h" #include "os/os.h" @@ -46,6 +45,7 @@ #else #include "core_cm4.h" #endif +#include "phy_priv.h" #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) #if !MYNEWT_VAL_CHOICE(MCU_TARGET, nRF52840) && !MYNEWT_VAL_CHOICE(MCU_TARGET, nRF52811) @@ -319,27 +319,6 @@ struct nrf_ccm_data struct nrf_ccm_data g_nrf_ccm_data; #endif -static int g_ble_phy_gpiote_idx; - -#if MYNEWT_VAL(BLE_LL_FEM_PA) || MYNEWT_VAL(BLE_LL_FEM_LNA) - -#define FEM_SINGLE_GPIO \ - (!MYNEWT_VAL(BLE_LL_FEM_PA) || !MYNEWT_VAL(BLE_LL_FEM_LNA) || \ - (MYNEWT_VAL(BLE_LL_FEM_PA_GPIO) == MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO))) - -#if FEM_SINGLE_GPIO -static uint8_t fem_idx; -#else -#if MYNEWT_VAL(BLE_LL_FEM_PA) -static uint8_t fem_pa_idx; -#endif -#if MYNEWT_VAL(BLE_LL_FEM_LNA) -static uint8_t fem_lna_idx; -#endif -#endif - -#endif - #ifndef BABBLESIM static void ble_phy_apply_errata_102_106_107(void) @@ -465,36 +444,6 @@ ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode) } #endif -static void -ble_phy_fem_enable_pa(void) -{ -#if MYNEWT_VAL(BLE_LL_FEM_PA) - ble_ll_fem_pa_enable(); - -#if !FEM_SINGLE_GPIO - NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[fem_pa_idx]); - NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[fem_pa_idx]); -#endif - - NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; -#endif -} - -static void -ble_phy_fem_enable_lna(void) -{ -#if MYNEWT_VAL(BLE_LL_FEM_LNA) - ble_ll_fem_lna_enable(); - -#if !FEM_SINGLE_GPIO - NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[fem_lna_idx]); - NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[fem_lna_idx]); -#endif - - NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; -#endif -} - int ble_phy_get_cur_phy(void) { @@ -741,7 +690,7 @@ ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx) nrf_rtc_event_enable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); /* Enable PPI */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH31_Msk); + phy_ppi_rtc0_compare0_to_timer0_start_enable(); /* Store the cputime at which we set the RTC */ g_ble_phy_data.phy_start_cputime = cputime; @@ -777,7 +726,8 @@ ble_phy_set_start_now(void) nrf_rtc_event_enable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); /* Enable PPI */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH31_Msk); + phy_ppi_rtc0_compare0_to_timer0_start_enable(); + /* * Store the cputime at which we set the RTC * @@ -856,7 +806,7 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) NRF_TIMER0->EVENTS_COMPARE[3] = 0; /* Enable wait for response PPI */ - nrf_ppi_channels_enable(NRF_PPI, (PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk)); + phy_ppi_wfr_enable(); /* * It may happen that if CPU is halted for a brief moment (e.g. during flash @@ -872,7 +822,7 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) */ nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE1); if (NRF_TIMER0->CC[1] > NRF_TIMER0->CC[3]) { - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk); + phy_ppi_wfr_disable(); nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); } } @@ -927,7 +877,7 @@ ble_phy_rx_xcvr_setup(void) NRF_CCM->EVENTS_ERROR = 0; NRF_CCM->EVENTS_ENDCRYPT = 0; nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH25_Msk); + phy_ppi_radio_address_to_ccm_crypt_enable(); } else { NRF_RADIO->PACKETPTR = (uint32_t)dptr; } @@ -951,7 +901,8 @@ ble_phy_rx_xcvr_setup(void) #endif /* Turn off trigger TXEN on output compare match and AAR on bcmatch */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk | PPI_CHEN_CH23_Msk); + phy_ppi_timer0_compare0_to_radio_txen_disable(); + phy_ppi_radio_bcmatch_to_aar_start_disable(); /* Reset the rx started flag. Used for the wait for response */ g_ble_phy_data.phy_rx_started = 0; @@ -1052,9 +1003,11 @@ ble_phy_tx_end_isr(void) nrf_timer_cc_set(NRF_TIMER0, 0, rx_time); NRF_TIMER0->EVENTS_COMPARE[0] = 0; - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); + phy_ppi_timer0_compare0_to_radio_rxen_enable(); - ble_phy_fem_enable_lna(); +#if PHY_USE_FEM_LNA + phy_fem_enable_lna(); +#endif } else if (transition == BLE_PHY_TRANSITION_TX_TX) { /* Schedule TX exactly T_IFS after TX end captured in CC[2] */ tx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); @@ -1067,11 +1020,11 @@ ble_phy_tx_end_isr(void) nrf_timer_cc_set(NRF_TIMER0, 0, tx_time); NRF_TIMER0->EVENTS_COMPARE[0] = 0; - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); + phy_ppi_timer0_compare0_to_radio_txen_enable(); nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) { - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk); + phy_ppi_timer0_compare0_to_radio_txen_disable(); g_ble_phy_data.phy_transition_late = 1; } } else { @@ -1081,8 +1034,9 @@ ble_phy_tx_end_isr(void) */ nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP); NRF_TIMER0->TASKS_SHUTDOWN = 1; - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | - PPI_CHEN_CH20_Msk | PPI_CHEN_CH31_Msk); + phy_ppi_wfr_disable(); + phy_ppi_timer0_compare0_to_radio_txen_disable(); + phy_ppi_rtc0_compare0_to_timer0_start_disable(); assert(transition == BLE_PHY_TRANSITION_NONE); } } @@ -1122,7 +1076,7 @@ ble_phy_rx_end_isr(void) struct ble_mbuf_hdr *ble_hdr; /* Disable automatic RXEN */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH21_Msk); + phy_ppi_timer0_compare0_to_radio_rxen_disable(); /* Set RSSI and CRC status flag in header */ ble_hdr = &g_ble_phy_data.rxhdr; @@ -1194,9 +1148,11 @@ ble_phy_rx_end_isr(void) nrf_timer_cc_set(NRF_TIMER0, 0, tx_time); NRF_TIMER0->EVENTS_COMPARE[0] = 0; - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); + phy_ppi_timer0_compare0_to_radio_txen_enable(); - ble_phy_fem_enable_pa(); +#if PHY_USE_FEM_PA + phy_fem_enable_pa(); +#endif /* * XXX: Hack warning! @@ -1212,7 +1168,7 @@ ble_phy_rx_end_isr(void) */ nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) { - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk); + phy_ppi_timer0_compare0_to_radio_txen_disable(); g_ble_phy_data.phy_transition_late = 1; } @@ -1250,7 +1206,7 @@ ble_phy_rx_start_isr(void) nrf_radio_int_disable(NRF_RADIO, RADIO_INTENCLR_ADDRESS_Msk); /* Clear wfr timer channels */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk); + phy_ppi_wfr_disable(); /* Initialize the ble mbuf header */ ble_hdr = &g_ble_phy_data.rxhdr; @@ -1332,7 +1288,7 @@ ble_phy_rx_start_isr(void) /* Trigger AAR after last bit of AdvA is received */ NRF_RADIO->EVENTS_BCMATCH = 0; - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH23_Msk); + phy_ppi_radio_bcmatch_to_aar_start_enable(); nrf_radio_bcc_set(NRF_RADIO, (BLE_LL_PDU_HDR_LEN + adva_offset + BLE_DEV_ADDR_LEN) * 8 + g_ble_phy_data.phy_bcc_offset); } @@ -1409,7 +1365,7 @@ ble_phy_isr(void) switch (g_ble_phy_data.phy_state) { case BLE_PHY_STATE_RX: #if MYNEWT_VAL(BLE_LL_FEM_LNA) - NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; + phy_ppi_fem_disable(); ble_ll_fem_lna_disable(); #endif if (g_ble_phy_data.phy_rx_started) { @@ -1420,7 +1376,7 @@ ble_phy_isr(void) break; case BLE_PHY_STATE_TX: #if MYNEWT_VAL(BLE_LL_FEM_PA) - NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; + phy_ppi_fem_disable(); ble_ll_fem_pa_disable(); #endif ble_phy_tx_end_isr(); @@ -1438,95 +1394,6 @@ ble_phy_isr(void) os_trace_isr_exit(); } -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 || \ - MYNEWT_VAL(BLE_LL_FEM_PA) || \ - MYNEWT_VAL(BLE_LL_FEM_LNA) -static int -ble_phy_gpiote_configure(int pin) -{ - NRF_GPIO_Type *port; - - g_ble_phy_gpiote_idx--; - -#if NRF52840_XXAA - port = pin > 31 ? NRF_P1 : NRF_P0; - pin &= 0x1f; -#else - port = NRF_P0; -#endif - - /* Configure GPIO directly to avoid dependency to hal_gpio (for porting) */ - port->DIRSET = (1 << pin); - port->OUTCLR = (1 << pin); - - NRF_GPIOTE->CONFIG[g_ble_phy_gpiote_idx] = - (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | - ((pin & 0x1F) << GPIOTE_CONFIG_PSEL_Pos) | -#if NRF52840_XXAA - ((port == NRF_P1) << GPIOTE_CONFIG_PORT_Pos); -#else - 0; -#endif - - BLE_LL_ASSERT(g_ble_phy_gpiote_idx >= 0); - - return g_ble_phy_gpiote_idx; -} -#endif - -static void -ble_phy_dbg_time_setup(void) -{ - int idx __attribute__((unused)); - - /* - * We setup GPIOTE starting from last configuration index to minimize risk - * of conflict with GPIO setup via hal. It's not great solution, but since - * this is just debugging code we can live with this. - */ - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 - idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); - - nrf_ppi_channel_endpoint_setup(NRF_PPI, 17, (uint32_t)&(NRF_RADIO->EVENTS_READY), - (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH17_Msk); - - /* CH[20] and PPI CH[21] are on to trigger TASKS_TXEN or TASKS_RXEN */ - nrf_ppi_fork_endpoint_setup(NRF_PPI, 20, (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); - nrf_ppi_fork_endpoint_setup(NRF_PPI, 21, (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); -#endif - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 - idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); - - /* CH[26] and CH[27] are always on for EVENT_ADDRESS and EVENT_END */ - nrf_ppi_fork_endpoint_setup(NRF_PPI, 26, (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); - nrf_ppi_fork_endpoint_setup(NRF_PPI, 27, (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); -#endif - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 - idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); - -#if NRF52840_XXAA - nrf_ppi_channel_endpoint_setup(NRF_PPI, 18, (uint32_t)&(NRF_RADIO->EVENTS_RXREADY), - (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); -#else - nrf_ppi_channel_endpoint_setup(NRF_PPI, 18, (uint32_t)&(NRF_RADIO->EVENTS_READY), - (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); -#endif - nrf_ppi_channel_endpoint_setup(NRF_PPI, 19, (uint32_t)&(NRF_RADIO->EVENTS_DISABLED), - (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH18_Msk | PPI_CHEN_CH19_Msk); - - /* CH[4] and CH[5] are always on for wfr */ - nrf_ppi_fork_endpoint_setup(NRF_PPI, 4, (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); - nrf_ppi_fork_endpoint_setup(NRF_PPI, 5, (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); -#endif -} - /** * ble phy init * @@ -1539,8 +1406,6 @@ ble_phy_init(void) { int rc; - g_ble_phy_gpiote_idx = 8; - /* Default phy to use is 1M */ g_ble_phy_data.phy_cur_phy_mode = BLE_PHY_MODE_1M; g_ble_phy_data.phy_tx_phy_mode = BLE_PHY_MODE_1M; @@ -1589,9 +1454,6 @@ ble_phy_init(void) /* Configure IFS */ NRF_RADIO->TIFS = BLE_LL_IFS; - /* Captures tx/rx start in timer0 cc 1 and tx/rx end in timer0 cc 2 */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH26_Msk | PPI_CHEN_CH27_Msk); - #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) nrf_ccm_int_disable(NRF_CCM, 0xffffffff); NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; @@ -1616,39 +1478,13 @@ ble_phy_init(void) NRF_TIMER0->MODE = 0; /* Timer mode */ NRF_TIMER0->PRESCALER = 4; /* gives us 1 MHz */ - /* - * PPI setup. - * Channel 4: Captures TIMER0 in CC[3] when EVENTS_ADDRESS occurs. Used - * to cancel the wait for response timer. - * Channel 5: TIMER0 CC[3] to TASKS_DISABLE on radio. This is the wait - * for response timer. - */ - nrf_ppi_channel_endpoint_setup(NRF_PPI, NRF_PPI_CHANNEL4, - (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS), - (uint32_t)&(NRF_TIMER0->TASKS_CAPTURE[3])); - nrf_ppi_channel_endpoint_setup(NRF_PPI, NRF_PPI_CHANNEL5, - (uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[3]), - (uint32_t)&(NRF_RADIO->TASKS_DISABLE)); - -#if MYNEWT_VAL(BLE_LL_FEM_PA) || MYNEWT_VAL(BLE_LL_FEM_LNA) -#if FEM_SINGLE_GPIO - fem_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); - NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[fem_idx]); - NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[fem_idx]); -#else -#if MYNEWT_VAL(BLE_LL_FEM_PA) - fem_pa_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); - NRF_GPIOTE->TASKS_CLR[fem_pa_idx] = 1; -#endif -#if MYNEWT_VAL(BLE_LL_FEM_LNA) - fem_lna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)); - NRF_GPIOTE->TASKS_CLR[fem_lna_idx] = 1; -#endif -#endif + phy_ppi_init(); - NRF_PPI->CH[6].EEP = (uint32_t)&(NRF_RADIO->EVENTS_READY); - NRF_PPI->CH[7].EEP = (uint32_t)&(NRF_RADIO->EVENTS_DISABLED); - NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; +#if PHY_USE_DEBUG + phy_debug_init(); +#endif +#if PHY_USE_FEM + phy_fem_init(); #endif /* Set isr in vector table and enable interrupt */ @@ -1674,8 +1510,6 @@ ble_phy_init(void) g_ble_phy_data.phy_stats_initialized = 1; } - ble_phy_dbg_time_setup(); - return 0; } @@ -1715,9 +1549,6 @@ ble_phy_rx(void) /* Setup for rx */ ble_phy_rx_xcvr_setup(); - /* PPI to start radio automatically shall be set here */ - assert(NRF_PPI->CHEN & PPI_CHEN_CH21_Msk); - return 0; } @@ -1756,7 +1587,7 @@ ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir) void ble_phy_encrypt_disable(void) { - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH25_Msk); + phy_ppi_radio_address_to_ccm_crypt_disable(); nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_STOP); NRF_CCM->EVENTS_ERROR = 0; NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled; @@ -1803,7 +1634,7 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) /* XXX: This should not be necessary, but paranoia is good! */ /* Clear timer0 compare to RXEN since we are transmitting */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH21_Msk); + phy_ppi_timer0_compare0_to_radio_rxen_disable(); if (ble_phy_set_start_time(cputime, rem_usecs, true) != 0) { STATS_INC(ble_phy_stats, tx_late); @@ -1811,10 +1642,12 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) rc = BLE_PHY_ERR_TX_LATE; } else { /* Enable PPI to automatically start TXEN */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); + phy_ppi_timer0_compare0_to_radio_txen_enable(); rc = 0; - ble_phy_fem_enable_pa(); +#if PHY_USE_FEM_PA + phy_fem_enable_pa(); +#endif } return rc; @@ -1847,7 +1680,7 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) /* XXX: This should not be necessary, but paranoia is good! */ /* Clear timer0 compare to TXEN since we are transmitting */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk); + phy_ppi_timer0_compare0_to_radio_txen_disable(); if (ble_phy_set_start_time(cputime, rem_usecs, false) != 0) { STATS_INC(ble_phy_stats, rx_late); @@ -1859,9 +1692,11 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) } /* Enable PPI to automatically start RXEN */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); + phy_ppi_timer0_compare0_to_radio_rxen_enable(); - ble_phy_fem_enable_lna(); +#if PHY_USE_FEM_LNA + phy_fem_enable_lna(); +#endif /* Start rx */ rc = ble_phy_rx(); @@ -1907,8 +1742,9 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) * paranoid, and if you are going to clear one, might as well clear them * all. */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | - PPI_CHEN_CH23_Msk | PPI_CHEN_CH25_Msk); + phy_ppi_wfr_disable(); + phy_ppi_radio_bcmatch_to_aar_start_disable(); + phy_ppi_radio_address_to_ccm_crypt_disable(); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) if (g_ble_phy_data.phy_encrypted) { @@ -2158,10 +1994,7 @@ ble_phy_disable_irq_and_ppi(void) nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); NRF_RADIO->SHORTS = 0; nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | - PPI_CHEN_CH20_Msk | PPI_CHEN_CH21_Msk | PPI_CHEN_CH23_Msk | - PPI_CHEN_CH25_Msk | PPI_CHEN_CH31_Msk); - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk); + phy_ppi_disable(); NVIC_ClearPendingIRQ(RADIO_IRQn); g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE; } @@ -2174,7 +2007,7 @@ ble_phy_restart_rx(void) ble_phy_set_start_now(); /* Enable PPI to automatically start RXEN */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); + phy_ppi_timer0_compare0_to_radio_rxen_enable(); ble_phy_rx(); } diff --git a/nimble/drivers/nrf5x/src/nrf52/phy.c b/nimble/drivers/nrf5x/src/nrf52/phy.c new file mode 100644 index 0000000000..4f825b8f2a --- /dev/null +++ b/nimble/drivers/nrf5x/src/nrf52/phy.c @@ -0,0 +1,165 @@ +/* + * 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. + */ + +#include +#include +#include +#include "../phy_priv.h" + +#if PHY_USE_DEBUG +void +phy_debug_init(void) +{ +#if PHY_USE_DEBUG_1 + phy_gpiote_configure(PHY_GPIOTE_DEBUG_1, + MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); + + nrf_ppi_channel_endpoint_setup(NRF_PPI, 17, + (uint32_t)&(NRF_RADIO->EVENTS_READY), + (uint32_t)&(NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_DEBUG_1])); + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH17_Msk); + + /* CH[20] and PPI CH[21] are on to trigger TASKS_TXEN or TASKS_RXEN */ + nrf_ppi_fork_endpoint_setup(NRF_PPI, 20, + (uint32_t)&(NRF_GPIOTE->TASKS_SET[PHY_GPIOTE_DEBUG_1])); + nrf_ppi_fork_endpoint_setup(NRF_PPI, 21, + (uint32_t)&(NRF_GPIOTE->TASKS_SET[PHY_GPIOTE_DEBUG_1])); +#endif + +#if PHY_USE_DEBUG_2 + phy_gpiote_configure(PHY_GPIOTE_DEBUG_2, + MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); + + /* CH[26] and CH[27] are always on for EVENT_ADDRESS and EVENT_END */ + nrf_ppi_fork_endpoint_setup(NRF_PPI, 26, + (uint32_t)&(NRF_GPIOTE->TASKS_SET[PHY_GPIOTE_DEBUG_2])); + nrf_ppi_fork_endpoint_setup(NRF_PPI, 27, + (uint32_t)&(NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_DEBUG_2])); +#endif + +#if PHY_USE_DEBUG_3 + phy_gpiote_configure(PHY_GPIOTE_DEBUG_3, MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); + +#if NRF52840_XXAA + nrf_ppi_channel_endpoint_setup(NRF_PPI, 18, + (uint32_t)&(NRF_RADIO->EVENTS_RXREADY), + (uint32_t)&(NRF_GPIOTE->TASKS_SET[PHY_GPIOTE_DEBUG_3])); +#else + nrf_ppi_channel_endpoint_setup(NRF_PPI, 18, + (uint32_t)&(NRF_RADIO->EVENTS_READY), + (uint32_t)&(NRF_GPIOTE->TASKS_SET[GIDX_DEBUG_3])); +#endif + nrf_ppi_channel_endpoint_setup(NRF_PPI, 19, + (uint32_t)&(NRF_RADIO->EVENTS_DISABLED), + (uint32_t)&(NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_DEBUG_3])); + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH18_Msk | PPI_CHEN_CH19_Msk); + + /* CH[4] and CH[5] are always on for wfr */ + nrf_ppi_fork_endpoint_setup(NRF_PPI, 4, + (uint32_t)&(NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_DEBUG_3])); + nrf_ppi_fork_endpoint_setup(NRF_PPI, 5, + (uint32_t)&(NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_DEBUG_3])); +#endif +} +#endif /* PHY_USE_DEBUG */ + +#if PHY_USE_FEM +void +phy_fem_init(void) +{ +#if PHY_USE_FEM_SINGLE_GPIO +#if PHY_USE_FEM_PA + phy_gpiote_configure(PHY_GPIOTE_FEM, MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); +#else + phy_gpiote_configure(PHY_GPIOTE_FEM, MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)); +#endif + NRF_PPI->CH[6].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[PHY_GPIOTE_FEM]); + NRF_PPI->CH[7].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM]); +#else +#if PHY_USE_FEM_PA + phy_gpiote_configure(PHY_GPIOTE_FEM_PA, MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); + NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM_PA] = 1; +#endif +#if PHY_USE_FEM_LNA + phy_gpiote_configure(PHY_GPIOTE_FEM_LNA, MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)); + NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM_LNA] = 1; +#endif +#endif /* PHY_USE_FEM_SINGLE_GPIO */ + + NRF_PPI->CH[6].EEP = (uint32_t)&(NRF_RADIO->EVENTS_READY); + NRF_PPI->CH[7].EEP = (uint32_t)&(NRF_RADIO->EVENTS_DISABLED); + + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk); +} + +#if PHY_USE_FEM_PA +void +phy_fem_enable_pa(void) +{ + ble_ll_fem_pa_enable(); + +#if !PHY_USE_FEM_SINGLE_GPIO + /* Switch FEM channels to control PA */ + NRF_PPI->CH[6].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[PHY_GPIOTE_FEM_PA]); + NRF_PPI->CH[7].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM_PA]); +#endif + + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk); +} +#endif + +#if PHY_USE_FEM_LNA +void +phy_fem_enable_lna(void) +{ + ble_ll_fem_lna_enable(); + +#if !PHY_USE_FEM_SINGLE_GPIO + /* Switch FEM channels to control LNA */ + NRF_PPI->CH[6].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[PHY_GPIOTE_FEM_LNA]); + NRF_PPI->CH[7].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM_LNA]); +#endif + + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk); +} +#endif +#endif /* PHY_USE_FEM */ + +void +phy_ppi_init(void) +{ + /* radio_address_to_timer0_capture1 */ + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH26_Msk); + /* radio_end_to_timer0_capture2 */ + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH27_Msk); + + /* + * PPI setup. + * Channel 4: Captures TIMER0 in CC[3] when EVENTS_ADDRESS occurs. Used + * to cancel the wait for response timer. + * Channel 5: TIMER0 CC[3] to TASKS_DISABLE on radio. This is the wait + * for response timer. + */ + nrf_ppi_channel_endpoint_setup(NRF_PPI, NRF_PPI_CHANNEL4, + (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS), + (uint32_t)&(NRF_TIMER0->TASKS_CAPTURE[3])); + nrf_ppi_channel_endpoint_setup(NRF_PPI, NRF_PPI_CHANNEL5, + (uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[3]), + (uint32_t)&(NRF_RADIO->TASKS_DISABLE)); +} diff --git a/nimble/drivers/nrf5x/src/nrf52/phy_ppi.h b/nimble/drivers/nrf5x/src/nrf52/phy_ppi.h new file mode 100644 index 0000000000..a77b718339 --- /dev/null +++ b/nimble/drivers/nrf5x/src/nrf52/phy_ppi.h @@ -0,0 +1,113 @@ +/* + * 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_PHY_PPI_ +#define H_PHY_PPI_ + +#include + +static inline void +phy_ppi_rtc0_compare0_to_timer0_start_enable(void) +{ + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH31_Msk); +} + +static inline void +phy_ppi_rtc0_compare0_to_timer0_start_disable(void) +{ + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH31_Msk); +} + +static inline void +phy_ppi_timer0_compare0_to_radio_txen_enable(void) +{ + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); +} + +static inline void +phy_ppi_timer0_compare0_to_radio_txen_disable(void) +{ + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk); +} + +static inline void +phy_ppi_timer0_compare0_to_radio_rxen_enable(void) +{ + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); +} + +static inline void +phy_ppi_timer0_compare0_to_radio_rxen_disable(void) +{ + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH21_Msk); +} + +static inline void +phy_ppi_radio_bcmatch_to_aar_start_enable(void) +{ + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH23_Msk); +} + +static inline void +phy_ppi_radio_bcmatch_to_aar_start_disable(void) +{ + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH23_Msk); +} + +static inline void +phy_ppi_radio_address_to_ccm_crypt_enable(void) +{ + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH25_Msk); +} + +static inline void +phy_ppi_radio_address_to_ccm_crypt_disable(void) +{ + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH25_Msk); +} + +static inline void +phy_ppi_wfr_enable(void) +{ + nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk); +} + +static inline void +phy_ppi_wfr_disable(void) +{ + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk); +} + +static inline void +phy_ppi_fem_disable(void) +{ + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk); +} + +static inline void +phy_ppi_disable(void) +{ + nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | + PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk | + PPI_CHEN_CH20_Msk | PPI_CHEN_CH21_Msk | + PPI_CHEN_CH23_Msk | PPI_CHEN_CH25_Msk | + PPI_CHEN_CH31_Msk); +} + +#endif /* H_PHY_PPI_ */ diff --git a/nimble/drivers/nrf5x/src/phy_priv.h b/nimble/drivers/nrf5x/src/phy_priv.h new file mode 100644 index 0000000000..881221ad1d --- /dev/null +++ b/nimble/drivers/nrf5x/src/phy_priv.h @@ -0,0 +1,79 @@ +/* + * 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_PHY_PRIV_ +#define H_PHY_PRIV_ + +#include +#include + +#define PHY_USE_DEBUG_1 (MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0) +#define PHY_USE_DEBUG_2 (MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0) +#define PHY_USE_DEBUG_3 (MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0) +#define PHY_USE_DEBUG (PHY_USE_DEBUG_1 || PHY_USE_DEBUG_2 || PHY_USE_DEBUG_3) + +#define PHY_USE_FEM_PA (MYNEWT_VAL(BLE_LL_FEM_PA) != 0) +#define PHY_USE_FEM_LNA (MYNEWT_VAL(BLE_LL_FEM_LNA) != 0) +#define PHY_USE_FEM (PHY_USE_FEM_PA || PHY_USE_FEM_LNA) +#define PHY_USE_FEM_SINGLE_GPIO \ + (PHY_USE_FEM && (!PHY_USE_FEM_PA || !PHY_USE_FEM_LNA || \ + (MYNEWT_VAL(BLE_LL_FEM_PA_GPIO) == \ + MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)))) + +/* GPIOTE indexes, start assigning from last one */ +#define PHY_GPIOTE_DEBUG_1 (8 - PHY_USE_DEBUG_1) +#define PHY_GPIOTE_DEBUG_2 (PHY_GPIOTE_DEBUG_1 - PHY_USE_DEBUG_2) +#define PHY_GPIOTE_DEBUG_3 (PHY_GPIOTE_DEBUG_2 - PHY_USE_DEBUG_3) +#if PHY_USE_FEM_SINGLE_GPIO +#define PHY_GPIOTE_FEM (PHY_GPIOTE_DEBUG_3 - PHY_USE_FEM) +#else +#define PHY_GPIOTE_FEM_PA (PHY_GPIOTE_DEBUG_3 - PHY_USE_FEM_PA) +#define PHY_GPIOTE_FEM_LNA (PHY_GPIOTE_FEM_PA - PHY_USE_FEM_LNA) +#endif + +static inline void +phy_gpiote_configure(int idx, int pin) +{ + nrf_gpio_cfg_output(pin); + nrf_gpiote_task_configure(NRF_GPIOTE, idx, pin, NRF_GPIOTE_POLARITY_NONE, + NRF_GPIOTE_INITIAL_VALUE_LOW); + nrf_gpiote_task_enable(NRF_GPIOTE, idx); +} + +#if PHY_USE_DEBUG +void phy_debug_init(void); +#endif + +#if PHY_USE_FEM +void phy_fem_init(void); +#if PHY_USE_FEM_PA +void phy_fem_enable_pa(void); +#endif +#if PHY_USE_FEM_LNA +void phy_fem_enable_lna(void); +#endif +#endif + +void phy_ppi_init(void); + +#ifdef NRF52_SERIES +#include "nrf52/phy_ppi.h" +#endif + +#endif /* H_PHY_PRIV_ */ From e4b98645145927e84de5442850e6e90aa79deffd Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 8 Sep 2022 10:12:28 +0200 Subject: [PATCH 0529/1333] nimble/phy/nrf5x: Rework nRF52 erratas --- nimble/drivers/nrf5x/src/ble_phy.c | 84 ++++++++++++------------------ nimble/drivers/nrf5x/syscfg.yml | 18 ------- 2 files changed, 32 insertions(+), 70 deletions(-) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 9388194833..d5113434d1 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -45,6 +45,7 @@ #else #include "core_cm4.h" #endif +#include #include "phy_priv.h" #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) @@ -319,19 +320,6 @@ struct nrf_ccm_data struct nrf_ccm_data g_nrf_ccm_data; #endif -#ifndef BABBLESIM -static void -ble_phy_apply_errata_102_106_107(void) -{ - /* [102] RADIO: PAYLOAD/END events delayed or not triggered after ADDRESS - * [106] RADIO: Higher CRC error rates for some access addresses - * [107] RADIO: Immediate address match for access addresses containing MSBs 0x00 - */ - *(volatile uint32_t *)0x40001774 = ((*(volatile uint32_t *)0x40001774) & - 0xfffffffe) | 0x01000000; -} -#endif - #if (BLE_LL_BT5_PHY_SUPPORTED == 1) /* Packet start offset (in usecs). This is the preamble plus access address. @@ -342,8 +330,8 @@ ble_phy_mode_pdu_start_off(int phy_mode) return g_ble_phy_mode_pkt_start_off[phy_mode]; } -#if NRF52840_XXAA -static inline bool +#if NRF52_ERRATA_191_ENABLE_WORKAROUND +static bool ble_phy_mode_is_coded(uint8_t phy_mode) { return (phy_mode == BLE_PHY_MODE_CODED_125KBPS) || @@ -351,48 +339,26 @@ ble_phy_mode_is_coded(uint8_t phy_mode) } static void -ble_phy_apply_nrf52840_errata(uint8_t new_phy_mode) +phy_nrf52_errata_191(uint8_t new_phy_mode) { - bool new_coded = ble_phy_mode_is_coded(new_phy_mode); - bool cur_coded = ble_phy_mode_is_coded(g_ble_phy_data.phy_cur_phy_mode); + bool from_coded = ble_phy_mode_is_coded(g_ble_phy_data.phy_cur_phy_mode); + bool to_coded = ble_phy_mode_is_coded(new_phy_mode); - /* - * Workarounds should be applied only when switching to/from LE Coded PHY - * so no need to apply them every time. - * - * nRF52840 Engineering A Errata v1.2 - * [164] RADIO: Low sensitivity in long range mode - * - * nRF52840 Rev 1 Errata - * [191] RADIO: High packet error rate in BLE Long Range mode + /* [191] RADIO: High packet error rate in BLE Long Range mode + * Should be applied only if switching to/from LE Coded, no need to apply + * on each mode change. */ - if (new_coded == cur_coded) { + if (from_coded == to_coded) { return; } - if (new_coded) { -#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_164) - /* [164] */ - *(volatile uint32_t *)0x4000173C |= 0x80000000; - *(volatile uint32_t *)0x4000173C = - ((*(volatile uint32_t *)0x4000173C & 0xFFFFFF00) | 0x5C); -#endif -#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_191) - /* [191] */ - *(volatile uint32_t *) 0x40001740 = - ((*((volatile uint32_t *) 0x40001740)) & 0x7FFF00FF) | - 0x80000000 | (((uint32_t)(196)) << 8); -#endif + if (to_coded) { + *(volatile uint32_t *)0x40001740 = + ((*((volatile uint32_t *)0x40001740)) & 0x7fff00ff) | + 0x80000000 | (((uint32_t)(196)) << 8); } else { -#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_164) - /* [164] */ - *(volatile uint32_t *)0x4000173C &= ~0x80000000; -#endif -#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_191) - /* [191] */ *(volatile uint32_t *) 0x40001740 = - ((*((volatile uint32_t *) 0x40001740)) & 0x7FFFFFFF); -#endif + ((*((volatile uint32_t *) 0x40001740)) & 0x7fffffff); } } #endif @@ -404,8 +370,10 @@ ble_phy_mode_apply(uint8_t phy_mode) return; } -#if NRF52840_XXAA - ble_phy_apply_nrf52840_errata(phy_mode); +#if NRF52_ERRATA_191_ENABLE_WORKAROUND + if (nrf52_errata_191()) { + phy_nrf52_errata_191(phy_mode); + } #endif switch (phy_mode) { @@ -1906,9 +1874,21 @@ ble_phy_set_access_addr(uint32_t access_addr) g_ble_phy_data.phy_access_address = access_addr; +#if NRF52_ERRATA_102_ENABLE_WORKAROUND || \ + NRF52_ERRATA_106_ENABLE_WORKAROUND || \ + NRF52_ERRATA_107_ENABLE_WORKAROUND #ifndef BABBLESIM - ble_phy_apply_errata_102_106_107(); + if (nrf52_errata_102() || nrf52_errata_106() || nrf52_errata_107()) { + /* [102] RADIO: PAYLOAD/END events delayed or not triggered after ADDRESS + * [106] RADIO: Higher CRC error rates for some access addresses + * [107] RADIO: Immediate address match for access addresses containing MSBs 0x00 + */ + *(volatile uint32_t *)0x40001774 = + ((*(volatile uint32_t *)0x40001774) & 0xfffffffe) | 0x01000000; + } #endif +#endif + return 0; } diff --git a/nimble/drivers/nrf5x/syscfg.yml b/nimble/drivers/nrf5x/syscfg.yml index 3bd49708ca..f24517ef07 100644 --- a/nimble/drivers/nrf5x/syscfg.yml +++ b/nimble/drivers/nrf5x/syscfg.yml @@ -46,24 +46,6 @@ syscfg.defs: This can be used to check if wfr is calculated properly. value: -1 - BLE_PHY_NRF52840_ERRATA_164: - description: > - Enable workaround for anomaly 164 found in nRF52840. - "[164] RADIO: Low selectivity in long range mode" - This shall be only enabled for: - - nRF52840 Engineering A - value: 0 - - BLE_PHY_NRF52840_ERRATA_191: - description: > - Enable workaround for anomaly 191 found in nRF52840. - "[191] RADIO: High packet error rate in BLE Long Range mode" - This shall be only enabled for: - - nRF52840 Engineering B - - nRF52840 Engineering C - - nRF52840 Rev 1 (final silicon) - value: 1 - BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR: description: > Ublox BMD-345 modules come with public address preprogrammed From 9dd64d2903a670c79493f035013d69d948400178 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 8 Sep 2022 10:34:37 +0200 Subject: [PATCH 0530/1333] nimble/phy/nrf5x: Move out TX power rounding --- nimble/drivers/nrf5x/src/ble_phy.c | 40 ++++------------------------ nimble/drivers/nrf5x/src/nrf52/phy.c | 34 +++++++++++++++++++++++ nimble/drivers/nrf5x/src/phy_priv.h | 2 ++ 3 files changed, 41 insertions(+), 35 deletions(-) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index d5113434d1..b4d64d88df 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -1803,8 +1803,8 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) int ble_phy_txpwr_set(int dbm) { - /* "Rail" power level if outside supported range */ - dbm = ble_phy_txpower_round(dbm); + /* Get actual TX power supported by radio */ + dbm = phy_txpower_round(dbm); NRF_RADIO->TXPOWER = dbm; g_ble_phy_data.phy_txpwr_dbm = dbm; @@ -1821,40 +1821,10 @@ ble_phy_txpwr_set(int dbm) * * @return int Rounded power in dBm */ -int ble_phy_txpower_round(int dbm) +int +ble_phy_txpower_round(int dbm) { - /* TODO this should be per nRF52XXX */ - - /* "Rail" power level if outside supported range */ - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos4dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Pos4dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_0dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_0dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm; - } - - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm; + return phy_txpower_round(dbm); } /** diff --git a/nimble/drivers/nrf5x/src/nrf52/phy.c b/nimble/drivers/nrf5x/src/nrf52/phy.c index 4f825b8f2a..763e3eef2f 100644 --- a/nimble/drivers/nrf5x/src/nrf52/phy.c +++ b/nimble/drivers/nrf5x/src/nrf52/phy.c @@ -163,3 +163,37 @@ phy_ppi_init(void) (uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[3]), (uint32_t)&(NRF_RADIO->TASKS_DISABLE)); } + +int8_t +phy_txpower_round(int8_t dbm) +{ + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos4dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Pos4dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_0dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_0dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm; + } + + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm; +} diff --git a/nimble/drivers/nrf5x/src/phy_priv.h b/nimble/drivers/nrf5x/src/phy_priv.h index 881221ad1d..b2308e61f2 100644 --- a/nimble/drivers/nrf5x/src/phy_priv.h +++ b/nimble/drivers/nrf5x/src/phy_priv.h @@ -76,4 +76,6 @@ void phy_ppi_init(void); #include "nrf52/phy_ppi.h" #endif +int8_t phy_txpower_round(int8_t dbm); + #endif /* H_PHY_PRIV_ */ From 0024679216db08366dd0358e6eedfa3022d7627e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 10 Sep 2022 01:24:07 +0200 Subject: [PATCH 0531/1333] nimble/phy/nrf5x: Force FEM disable on ble_phy_disable --- nimble/drivers/nrf5x/src/ble_phy.c | 4 ++++ nimble/drivers/nrf5x/src/nrf52/phy.c | 15 +++++++++++++++ nimble/drivers/nrf5x/src/phy_priv.h | 1 + 3 files changed, 20 insertions(+) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index b4d64d88df..36f209c5b7 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -1976,6 +1976,10 @@ ble_phy_disable(void) ble_phy_stop_usec_timer(); ble_phy_disable_irq_and_ppi(); + +#if PHY_USE_FEM + phy_fem_disable(); +#endif } /* Gets the current access address */ diff --git a/nimble/drivers/nrf5x/src/nrf52/phy.c b/nimble/drivers/nrf5x/src/nrf52/phy.c index 763e3eef2f..d4492464a4 100644 --- a/nimble/drivers/nrf5x/src/nrf52/phy.c +++ b/nimble/drivers/nrf5x/src/nrf52/phy.c @@ -139,6 +139,21 @@ phy_fem_enable_lna(void) nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk); } #endif + +void +phy_fem_disable(void) +{ +#if PHY_USE_FEM_SINGLE_GPIO + NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM] = 1; +#else +#if PHY_USE_FEM_PA + NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM_PA] = 1; +#endif +#if PHY_USE_FEM_LNA + NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM_LNA] = 1; +#endif +#endif +} #endif /* PHY_USE_FEM */ void diff --git a/nimble/drivers/nrf5x/src/phy_priv.h b/nimble/drivers/nrf5x/src/phy_priv.h index b2308e61f2..1a026a6d11 100644 --- a/nimble/drivers/nrf5x/src/phy_priv.h +++ b/nimble/drivers/nrf5x/src/phy_priv.h @@ -68,6 +68,7 @@ void phy_fem_enable_pa(void); #if PHY_USE_FEM_LNA void phy_fem_enable_lna(void); #endif +void phy_fem_disable(void); #endif void phy_ppi_init(void); From 9ea411fbe637ca4b0e40d32a9741e6ac8cb57a3f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 8 Sep 2022 12:13:15 +0200 Subject: [PATCH 0532/1333] nimble/phy/nrf5x: Add nRF53 support This adds code for nRF5340 net core. --- nimble/drivers/nrf5x/pkg.yml | 5 + nimble/drivers/nrf5x/src/ble_phy.c | 48 ++++- nimble/drivers/nrf5x/src/nrf53/phy.c | 235 +++++++++++++++++++++++ nimble/drivers/nrf5x/src/nrf53/phy_ppi.h | 159 +++++++++++++++ nimble/drivers/nrf5x/src/phy_priv.h | 8 + 5 files changed, 452 insertions(+), 3 deletions(-) create mode 100644 nimble/drivers/nrf5x/src/nrf53/phy.c create mode 100644 nimble/drivers/nrf5x/src/nrf53/phy_ppi.h diff --git a/nimble/drivers/nrf5x/pkg.yml b/nimble/drivers/nrf5x/pkg.yml index e0b314ea4d..b99e669248 100644 --- a/nimble/drivers/nrf5x/pkg.yml +++ b/nimble/drivers/nrf5x/pkg.yml @@ -29,3 +29,8 @@ pkg.apis: ble_driver pkg.deps: - nimble - nimble/controller + +pkg.ign_dirs.'MCU_TARGET=="nRF5340_NET"': + - nrf52 +pkg.ign_dirs.'MCU_TARGET!="nRF5340_NET"': + - nrf53 diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 36f209c5b7..0d9b363f0f 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -39,7 +39,12 @@ #include "controller/ble_ll.h" #include "nrfx.h" #if MYNEWT -#include "mcu/nrf52_clock.h" +#ifdef NRF52_SERIES +#include +#endif +#ifdef NRF53_SERIES +#include +#endif #include "mcu/cmsis_nvic.h" #include "hal/hal_gpio.h" #else @@ -49,8 +54,10 @@ #include "phy_priv.h" #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) -#if !MYNEWT_VAL_CHOICE(MCU_TARGET, nRF52840) && !MYNEWT_VAL_CHOICE(MCU_TARGET, nRF52811) -#error LE Coded PHY can only be enabled on nRF52811 or nRF52840 +#if !MYNEWT_VAL_CHOICE(MCU_TARGET, nRF52840) && \ + !MYNEWT_VAL_CHOICE(MCU_TARGET, nRF52811) && \ + !MYNEWT_VAL_CHOICE(MCU_TARGET, nRF5340_NET) +#error LE Coded PHY can only be enabled on nRF52811, nRF52840 or nRF5340 #endif #endif @@ -379,21 +386,33 @@ ble_phy_mode_apply(uint8_t phy_mode) switch (phy_mode) { case BLE_PHY_MODE_1M: NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit; +#ifdef NRF53_SERIES + *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0080); +#endif NRF_RADIO->PCNF0 = NRF_PCNF0_1M; break; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) case BLE_PHY_MODE_2M: NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_2Mbit; +#ifdef NRF53_SERIES + *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0084); +#endif NRF_RADIO->PCNF0 = NRF_PCNF0_2M; break; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) case BLE_PHY_MODE_CODED_125KBPS: NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_LR125Kbit; +#ifdef NRF53_SERIES + *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0080); +#endif NRF_RADIO->PCNF0 = NRF_PCNF0_CODED; break; case BLE_PHY_MODE_CODED_500KBPS: NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_LR500Kbit; +#ifdef NRF53_SERIES + *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0080); +#endif NRF_RADIO->PCNF0 = NRF_PCNF0_CODED; break; #endif @@ -1392,6 +1411,19 @@ ble_phy_init(void) nrf_radio_power_set(NRF_RADIO, false); nrf_radio_power_set(NRF_RADIO, true); +#ifdef NRF53_SERIES + *(volatile uint32_t *)(NRF_RADIO_NS_BASE + 0x774) = + (*(volatile uint32_t* )(NRF_RADIO_NS_BASE + 0x774) & 0xfffffffe) | 0x01000000; +#if NRF53_ERRATA_16_ENABLE_WORKAROUND + if (nrf53_errata_16()) { + /* [16] RADIO: POWER register is not functional */ + NRF_RADIO_NS->SUBSCRIBE_TXEN = 0; + NRF_RADIO_NS->SUBSCRIBE_RXEN = 0; + NRF_RADIO_NS->SUBSCRIBE_DISABLE = 0; + } +#endif +#endif + /* Disable all interrupts */ nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); @@ -2071,7 +2103,12 @@ void ble_phy_rfclk_enable(void) { #if MYNEWT || defined(RIOT_VERSION) +#ifdef NRF52_SERIES nrf52_clock_hfxo_request(); +#endif +#ifdef NRF53_SERIES + nrf5340_net_clock_hfxo_request(); +#endif #else nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART); #endif @@ -2081,7 +2118,12 @@ void ble_phy_rfclk_disable(void) { #if MYNEWT || defined(RIOT_VERSION) +#ifdef NRF52_SERIES nrf52_clock_hfxo_release(); +#endif +#ifdef NRF53_SERIES + nrf5340_net_clock_hfxo_release(); +#endif #else nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); #endif diff --git a/nimble/drivers/nrf5x/src/nrf53/phy.c b/nimble/drivers/nrf5x/src/nrf53/phy.c new file mode 100644 index 0000000000..78b45578c5 --- /dev/null +++ b/nimble/drivers/nrf5x/src/nrf53/phy.c @@ -0,0 +1,235 @@ +/* + * 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. + */ + +#include +#include +#include +#include "../phy_priv.h" + +#if PHY_USE_DEBUG +void +phy_debug_init(void) +{ +#if PHY_USE_DEBUG_1 + phy_gpiote_configure(PHY_GPIOTE_DEBUG_1, + MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); + + NRF_RADIO->PUBLISH_READY = DPPI_CH_PUB(RADIO_EVENTS_READY); + NRF_DPPIC->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_READY); + + NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_DEBUG_1] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); + NRF_GPIOTE->SUBSCRIBE_CLR[PHY_GPIOTE_DEBUG_1] = DPPI_CH_SUB(RADIO_EVENTS_READY); +#endif + +#if PHY_USE_DEBUG_2 + phy_gpiote_configure(PHY_GPIOTE_DEBUG_2, + MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); + + NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_DEBUG_2] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); + NRF_GPIOTE->SUBSCRIBE_CLR[PHY_GPIOTE_DEBUG_2] = DPPI_CH_SUB(RADIO_EVENTS_END); +#endif + +#if PHY_USE_DEBUG_3 + phy_gpiote_configure(PHY_GPIOTE_DEBUG_3, MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); + + NRF_RADIO->PUBLISH_RXREADY = DPPI_CH_PUB(RADIO_EVENTS_READY); + NRF_RADIO->PUBLISH_DISABLED = DPPI_CH_PUB(RADIO_EVENTS_DISABLED); + NRF_DPPIC->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_RXREADY) | + DPPI_CH_MASK(RADIO_EVENTS_DISABLED); + + NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_DEBUG_3] = DPPI_CH_SUB(RADIO_EVENTS_RXREADY); + + /* TODO figure out how (if?) to subscribe task to multiple DPPI channels + * Currently only last one is working. Also using multiple GPIOTE for same + * PIN doesn't work... + */ + NRF_GPIOTE->SUBSCRIBE_CLR[PHY_GPIOTE_DEBUG_3] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); + NRF_GPIOTE->SUBSCRIBE_CLR[PHY_GPIOTE_DEBUG_3] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); + NRF_GPIOTE->SUBSCRIBE_CLR[PHY_GPIOTE_DEBUG_3] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_3); + +#endif +} +#endif /* PHY_USE_DEBUG */ + +#if PHY_USE_FEM +void +phy_fem_init() +{ + /* We can keep clear tasks subscribed and published channels always enabled, + * it's enough to just (un)subscribe set tasks when needed. + * TODO: check if this affects power consumption + */ + + NRF_TIMER0->PUBLISH_COMPARE[2] = DPPI_CH_PUB(TIMER0_EVENTS_COMPARE_2); + NRF_RADIO->PUBLISH_DISABLED = DPPI_CH_PUB(RADIO_EVENTS_DISABLED); + +#if PHY_USE_FEM_SINGLE_GPIO +#if PHY_USE_FEM_PA + phy_gpiote_configure(PHY_GPIOTE_FEM, MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); +#else + phy_gpiote_configure(PHY_GPIOTE_FEM, MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)); +#endif + NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_FEM] = + DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_2); + NRF_GPIOTE->SUBSCRIBE_CLR[PHY_GPIOTE_FEM] = + DPPI_CH_SUB(RADIO_EVENTS_DISABLED); + NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM] = 1; +#else +#if PHY_USE_FEM_PA + phy_gpiote_configure(PHY_GPIOTE_FEM_PA, MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); + NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_FEM_PA] = + DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_2); + NRF_GPIOTE->SUBSCRIBE_CLR[PHY_GPIOTE_FEM_PA] = + DPPI_CH_SUB(RADIO_EVENTS_DISABLED); + NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM_PA] = 1; +#endif +#if PHY_USE_FEM_LNA + phy_gpiote_configure(PHY_GPIOTE_FEM_LNA, MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)); + NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_FEM_LNA] = + DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_2); + NRF_GPIOTE->SUBSCRIBE_CLR[PHY_GPIOTE_FEM_LNA] = + DPPI_CH_SUB(RADIO_EVENTS_DISABLED); + NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM_LNA] = 1; +#endif +#endif /* PHY_USE_FEM_SINGLE_GPIO */ + + NRF_DPPIC->CHENSET = DPPI_CH_MASK_FEM; +} + +void +phy_fem_enable_pa(void) +{ + ble_ll_fem_pa_enable(); + +#if PHY_USE_FEM_SINGLE_GPIO + NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_FEM] = + DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_2); +#else + NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_FEM_PA] = + DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_2); +#endif +} + +void +phy_fem_enable_lna(void) +{ + ble_ll_fem_lna_enable(); + +#if PHY_USE_FEM_SINGLE_GPIO + NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_FEM] = + DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_2); +#else + NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_FEM_LNA] = + DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_2); +#endif +} + +void +phy_fem_disable(void) +{ +#if PHY_USE_FEM_SINGLE_GPIO + NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM] = 1; +#else +#if PHY_USE_FEM_PA + NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM_PA] = 1; +#endif +#if PHY_USE_FEM_LNA + NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM_LNA] = 1; +#endif +#endif +} +#endif /* PHY_USE_FEM */ + +void +phy_ppi_init(void) +{ + /* Publish events */ + NRF_TIMER0->PUBLISH_COMPARE[0] = DPPI_CH_PUB(TIMER0_EVENTS_COMPARE_0); + NRF_TIMER0->PUBLISH_COMPARE[3] = DPPI_CH_PUB(TIMER0_EVENTS_COMPARE_3); + NRF_RADIO->PUBLISH_END = DPPI_CH_PUB(RADIO_EVENTS_END); + NRF_RADIO->PUBLISH_BCMATCH = DPPI_CH_PUB(RADIO_EVENTS_BCMATCH); + NRF_RADIO->PUBLISH_ADDRESS = DPPI_CH_PUB(RADIO_EVENTS_ADDRESS); + NRF_RTC0->PUBLISH_COMPARE[0] = DPPI_CH_PUB(RTC0_EVENTS_COMPARE_0); + + /* Enable channels we publish on */ + NRF_DPPIC->CHENSET = DPPI_CH_ENABLE_ALL; + + /* radio_address_to_timer0_capture1 */ + NRF_TIMER0->SUBSCRIBE_CAPTURE[1] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); + /* radio_end_to_timer0_capture2 */ + NRF_TIMER0->SUBSCRIBE_CAPTURE[2] = DPPI_CH_SUB(RADIO_EVENTS_END); +} + +int8_t +phy_txpower_round(int8_t dbm) +{ + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_0dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_0dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg1dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg1dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg2dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg2dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg3dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg3dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg5dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg5dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg6dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg6dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg7dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg7dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg16dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg16dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm; + } + + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm) { + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm; + } + + return (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm; +} diff --git a/nimble/drivers/nrf5x/src/nrf53/phy_ppi.h b/nimble/drivers/nrf5x/src/nrf53/phy_ppi.h new file mode 100644 index 0000000000..6412f32753 --- /dev/null +++ b/nimble/drivers/nrf5x/src/nrf53/phy_ppi.h @@ -0,0 +1,159 @@ +/* + * 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_PHY_PPI_ +#define H_PHY_PPI_ + +#define DPPI_CH_PUB(_ch) (((DPPI_CH_ ## _ch) & 0xff) | (1 << 31)) +#define DPPI_CH_SUB(_ch) (((DPPI_CH_ ## _ch) & 0xff) | (1 << 31)) +#define DPPI_CH_UNSUB(_ch) (((DPPI_CH_ ## _ch) & 0xff) | (0 << 31)) +#define DPPI_CH_MASK(_ch) (1 << (DPPI_CH_ ## _ch)) + +/* Channels 0..5 are always used. + * Channels 6 and 7 are used for PA/LNA (optionally). + * Channels 7..9 are used for GPIO debugging (optionally). + */ + +#define DPPI_CH_TIMER0_EVENTS_COMPARE_0 0 +#define DPPI_CH_TIMER0_EVENTS_COMPARE_3 1 +#define DPPI_CH_RADIO_EVENTS_END 2 +#define DPPI_CH_RADIO_EVENTS_BCMATCH 3 +#define DPPI_CH_RADIO_EVENTS_ADDRESS 4 +#define DPPI_CH_RTC0_EVENTS_COMPARE_0 5 +#define DPPI_CH_TIMER0_EVENTS_COMPARE_2 6 +#define DPPI_CH_RADIO_EVENTS_DISABLED 7 +#define DPPI_CH_RADIO_EVENTS_READY 8 +#define DPPI_CH_RADIO_EVENTS_RXREADY 9 + +#define DPPI_CH_ENABLE_ALL (DPPIC_CHEN_CH0_Msk | DPPIC_CHEN_CH1_Msk | \ + DPPIC_CHEN_CH2_Msk | DPPIC_CHEN_CH3_Msk | \ + DPPIC_CHEN_CH4_Msk | DPPIC_CHEN_CH5_Msk) + +#define DPPI_CH_MASK_FEM (DPPI_CH_MASK(TIMER0_EVENTS_COMPARE_2) | \ + DPPI_CH_MASK(RADIO_EVENTS_DISABLED)) + +static inline void +phy_ppi_rtc0_compare0_to_timer0_start_enable(void) +{ + NRF_TIMER0->SUBSCRIBE_START = DPPI_CH_SUB(RTC0_EVENTS_COMPARE_0); +} + +static inline void +phy_ppi_rtc0_compare0_to_timer0_start_disable(void) +{ + NRF_TIMER0->SUBSCRIBE_START = DPPI_CH_UNSUB(RTC0_EVENTS_COMPARE_0); + NRF_TIMER0->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); + NRF_RADIO->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); +} + +static inline void +phy_ppi_timer0_compare0_to_radio_txen_enable(void) +{ + NRF_RADIO->SUBSCRIBE_TXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); +} + +static inline void +phy_ppi_timer0_compare0_to_radio_txen_disable(void) +{ + NRF_RADIO->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); +} + +static inline void +phy_ppi_timer0_compare0_to_radio_rxen_enable(void) +{ + NRF_RADIO->SUBSCRIBE_RXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); +} + +static inline void +phy_ppi_timer0_compare0_to_radio_rxen_disable(void) +{ + NRF_RADIO->SUBSCRIBE_RXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); +} + +static inline void +phy_ppi_radio_address_to_ccm_crypt_enable(void) +{ + NRF_CCM->SUBSCRIBE_CRYPT = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); +} + +static inline void +phy_ppi_radio_address_to_ccm_crypt_disable(void) +{ + NRF_CCM->SUBSCRIBE_CRYPT = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); +} + +static inline void +phy_ppi_radio_bcmatch_to_aar_start_enable(void) +{ + NRF_AAR->SUBSCRIBE_START = DPPI_CH_SUB(RADIO_EVENTS_BCMATCH); +} + +static inline void +phy_ppi_radio_bcmatch_to_aar_start_disable(void) +{ + NRF_AAR->SUBSCRIBE_START = DPPI_CH_UNSUB(RADIO_EVENTS_BCMATCH); +} + +static inline void +phy_ppi_wfr_enable(void) +{ + NRF_TIMER0->SUBSCRIBE_CAPTURE[3] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); + NRF_RADIO->SUBSCRIBE_DISABLE = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_3); +} + +static inline void +phy_ppi_wfr_disable(void) +{ + NRF_TIMER0->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); + NRF_RADIO->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); +} + +static inline void +phy_ppi_fem_disable(void) +{ +#if PHY_USE_FEM_SINGLE_GPIO + NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_FEM] = + DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); +#else +#if PHY_USE_FEM_PA + NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_FEM_PA] = + DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_2); +#endif +#if PHY_USE_FEM_LNA + NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_FEM_LNA] = + DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_2); +#endif +#endif +} + +static inline void +phy_ppi_disable(void) +{ + NRF_TIMER0->SUBSCRIBE_START = DPPI_CH_UNSUB(RTC0_EVENTS_COMPARE_0); + NRF_TIMER0->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); + NRF_RADIO->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); + NRF_RADIO->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); + NRF_RADIO->SUBSCRIBE_RXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); + NRF_AAR->SUBSCRIBE_START = DPPI_CH_UNSUB(RADIO_EVENTS_BCMATCH); + NRF_CCM->SUBSCRIBE_CRYPT = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); + + phy_ppi_fem_disable(); +} + +#endif /* H_PHY_PPI_ */ \ No newline at end of file diff --git a/nimble/drivers/nrf5x/src/phy_priv.h b/nimble/drivers/nrf5x/src/phy_priv.h index 1a026a6d11..8cf140ee3d 100644 --- a/nimble/drivers/nrf5x/src/phy_priv.h +++ b/nimble/drivers/nrf5x/src/phy_priv.h @@ -20,6 +20,7 @@ #ifndef H_PHY_PRIV_ #define H_PHY_PRIV_ +#include #include #include @@ -79,4 +80,11 @@ void phy_ppi_init(void); int8_t phy_txpower_round(int8_t dbm); +#ifdef NRF52_SERIES +#include "nrf52/phy_ppi.h" +#endif +#ifdef NRF53_SERIES +#include "nrf53/phy_ppi.h" +#endif + #endif /* H_PHY_PRIV_ */ From f396441898a9fb80c81d9397fce09b83a93751e4 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 10 Sep 2022 15:14:18 +0200 Subject: [PATCH 0533/1333] nimble/phy/nrf5x: Add support for FEM turn on time This adds proper support for FEM turn on time. Max supported turn on time is 90us due to some optimizations in code, but that should be enough - we can change it later if needed. --- nimble/drivers/nrf5x/src/ble_phy.c | 196 +++++++++++++++++++-------- nimble/drivers/nrf5x/src/nrf52/phy.c | 2 +- nimble/drivers/nrf5x/syscfg.yml | 6 + 3 files changed, 147 insertions(+), 57 deletions(-) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 0d9b363f0f..52119d1ed3 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -606,41 +606,65 @@ ble_phy_tifs_get(void) * */ static int -ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx) +ble_phy_set_start_time(uint32_t cputime, uint8_t rem_us, bool tx) { uint32_t next_cc; uint32_t cur_cc; uint32_t cntr; uint32_t delta; + int radio_rem_us; +#if PHY_USE_FEM + int fem_rem_us = 0; +#endif + int rem_us_corr; + int min_rem_us; - /* - * We need to adjust start time to include radio ramp-up and TX pipeline - * delay (the latter only if applicable, so only for TX). - * - * Radio ramp-up time is 40 usecs and TX delay is 3 or 5 usecs depending on - * phy, thus we'll offset RTC by 2 full ticks (61 usecs) and then compensate - * using TIMER0 with 1 usec precision. + /* Calculate rem_us for radio and FEM enable. The result may be a negative + * value, but we'll adjust later. */ - - cputime -= 2; - rem_usecs += 61; if (tx) { - rem_usecs -= BLE_PHY_T_TXENFAST; - rem_usecs -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; + radio_rem_us = rem_us - BLE_PHY_T_TXENFAST - + g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; +#if PHY_USE_FEM_PA + fem_rem_us = rem_us - MYNEWT_VAL(BLE_LL_FEM_PA_TURN_ON_US); +#endif } else { - rem_usecs -= BLE_PHY_T_RXENFAST; + radio_rem_us = rem_us - BLE_PHY_T_TXENFAST; +#if PHY_USE_FEM_LNA + fem_rem_us = rem_us - MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US); +#endif } - /* - * rem_usecs will be no more than 2 ticks, but if it is more than single - * tick then we should better count one more low-power tick rather than - * 30 high-power usecs. Also make sure we don't set TIMER0 CC to 0 as the - * compare won't occur. +#if PHY_USE_FEM + min_rem_us = min(radio_rem_us, fem_rem_us); +#else + min_rem_us = radio_rem_us; +#endif + + /* We need to adjust rem_us values, so they are >=1 for TIMER0 compare + * event to be triggered. + * + * If FEM is not enabled, calculated rem_us is -45<=rem_us<=-15 since we + * only had to adjust earlier for ramp-up and txdelay, i.e. 40+5=45us in + * worst case, so we adjust by 1 or 2 tick(s) only. + * + * If FEM is enabled, turn on time may be a bit longer, so we also allow to + * adjust by 3 ticks so up to 90us which should be enough. If needed, we + * can extend this by another tick but having FEM with turn on time >90us + * means transition may become tricky. */ - if (rem_usecs > 30) { - cputime++; - rem_usecs -= 30; + if ((PHY_USE_FEM) && (min_rem_us <= -61)) { + cputime -= 3; + rem_us_corr = 91; + } else if (min_rem_us <= -30) { + /* rem_us is -60..-30 */ + cputime -= 2; + rem_us_corr = 61; + } else { + /* rem_us is -29..0 */ + cputime -= 1; + rem_us_corr = 30; } /* @@ -668,8 +692,14 @@ ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx) /* Clear and set TIMER0 to fire off at proper time */ nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CLEAR); - nrf_timer_cc_set(NRF_TIMER0, 0, rem_usecs); + nrf_timer_cc_set(NRF_TIMER0, 0, radio_rem_us + rem_us_corr); NRF_TIMER0->EVENTS_COMPARE[0] = 0; +#if PHY_USE_FEM + if (fem_rem_us) { + nrf_timer_cc_set(NRF_TIMER0, 2, fem_rem_us + rem_us_corr); + NRF_TIMER0->EVENTS_COMPARE[2] = 0; + } +#endif /* Set RTC compare to start TIMER0 */ NRF_RTC0->EVENTS_COMPARE[0] = 0; @@ -677,6 +707,19 @@ ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx) nrf_rtc_event_enable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); /* Enable PPI */ +#if PHY_USE_FEM + if (fem_rem_us) { + if (tx) { +#if PHY_USE_FEM_PA + phy_fem_enable_pa(); +#endif + } else { +#if PHY_USE_FEM_LNA + phy_fem_enable_lna(); +#endif + } + } +#endif phy_ppi_rtc0_compare0_to_timer0_start_enable(); /* Store the cputime at which we set the RTC */ @@ -690,16 +733,41 @@ ble_phy_set_start_now(void) { os_sr_t sr; uint32_t now; + uint32_t radio_rem_us; +#if PHY_USE_FEM_LNA + uint32_t fem_rem_us; +#endif OS_ENTER_CRITICAL(sr); - /* - * Set TIMER0 to fire immediately. We can't set CC to 0 as compare will not - * occur in such case. + /* We need to set TIMER0 compare registers to at least 1 as otherwise + * compare event won't be triggered. Event (FEM/radio) that have to be + * triggered first is set to 1, other event is set to 1+diff. + * + * Note that this is only used for rx, so only need to handle LNA. */ + +#if PHY_USE_FEM_LNA + if (MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US) > BLE_PHY_T_RXENFAST) { + radio_rem_us = 1 + MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US) - + BLE_PHY_T_RXENFAST; + fem_rem_us = 1; + } else { + radio_rem_us = 1; + fem_rem_us = 1 + BLE_PHY_T_RXENFAST - + MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US); + } +#else + radio_rem_us = 1; +#endif + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CLEAR); - nrf_timer_cc_set(NRF_TIMER0, 0, 1); + nrf_timer_cc_set(NRF_TIMER0, 0, radio_rem_us); NRF_TIMER0->EVENTS_COMPARE[0] = 0; +#if PHY_USE_FEM_LNA + nrf_timer_cc_set(NRF_TIMER0, 2, fem_rem_us); + NRF_TIMER0->EVENTS_COMPARE[2] = 0; +#endif /* * Set RTC compare to start TIMER0. We need to set it to at least N+2 ticks @@ -939,6 +1007,10 @@ ble_phy_tx_end_isr(void) uint8_t transition; uint32_t rx_time; uint32_t tx_time; +#if PHY_USE_FEM_LNA + uint32_t fem_time; +#endif + uint32_t radio_time; /* Store PHY on which we've just transmitted smth */ tx_phy_mode = g_ble_phy_data.phy_cur_phy_mode; @@ -983,25 +1055,33 @@ ble_phy_tx_end_isr(void) rx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); /* Adjust for delay between EVENT_END and actual TX end time */ rx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; - /* Adjust for radio ramp-up */ - rx_time -= BLE_PHY_T_RXENFAST; /* Start listening a bit earlier due to allowed active clock accuracy */ rx_time -= 2; - nrf_timer_cc_set(NRF_TIMER0, 0, rx_time); - NRF_TIMER0->EVENTS_COMPARE[0] = 0; - phy_ppi_timer0_compare0_to_radio_rxen_enable(); - #if PHY_USE_FEM_LNA + fem_time = rx_time - MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US); + nrf_timer_cc_set(NRF_TIMER0, 2, fem_time); + NRF_TIMER0->EVENTS_COMPARE[2] = 0; phy_fem_enable_lna(); #endif + + radio_time = rx_time - BLE_PHY_T_RXENFAST; + nrf_timer_cc_set(NRF_TIMER0, 0, radio_time); + NRF_TIMER0->EVENTS_COMPARE[0] = 0; + phy_ppi_timer0_compare0_to_radio_rxen_enable(); + + /* In case TIMER0 did already count past CC[0] and/or CC[2], radio + * and/or LNA may not be enabled. In any case we won't be stuck since + * wfr will cancel rx if needed. + * + * FIXME failing to enable LNA may result in unexpected RSSI drop in + * case we still rxd something, so perhaps we could check it here + */ } else if (transition == BLE_PHY_TRANSITION_TX_TX) { /* Schedule TX exactly T_IFS after TX end captured in CC[2] */ tx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); /* Adjust for delay between EVENT_END and actual TX end time */ tx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; - /* Adjust for radio ramp-up */ - tx_time -= BLE_PHY_T_TXENFAST; /* Adjust for delay between EVENT_READY and actual TX start time */ tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; @@ -1009,6 +1089,8 @@ ble_phy_tx_end_isr(void) NRF_TIMER0->EVENTS_COMPARE[0] = 0; phy_ppi_timer0_compare0_to_radio_txen_enable(); + /* TODO handle PA */ + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) { phy_ppi_timer0_compare0_to_radio_txen_disable(); @@ -1060,7 +1142,12 @@ ble_phy_rx_end_isr(void) uint8_t *dptr; uint8_t crcok; uint32_t tx_time; +#if PHY_USE_FEM_PA + uint32_t fem_time; +#endif + uint32_t radio_time; struct ble_mbuf_hdr *ble_hdr; + bool is_late; /* Disable automatic RXEN */ phy_ppi_timer0_compare0_to_radio_rxen_disable(); @@ -1128,33 +1215,38 @@ ble_phy_rx_end_isr(void) tx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); /* Adjust for delay between actual RX end time and EVENT_END */ tx_time -= g_ble_phy_t_rxenddelay[ble_hdr->rxinfo.phy_mode]; - /* Adjust for radio ramp-up */ - tx_time -= BLE_PHY_T_TXENFAST; + +#if PHY_USE_FEM_PA + fem_time = tx_time - MYNEWT_VAL(BLE_LL_FEM_PA_TURN_ON_US); +#endif + /* Adjust for delay between EVENT_READY and actual TX start time */ tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; - nrf_timer_cc_set(NRF_TIMER0, 0, tx_time); + radio_time = tx_time - BLE_PHY_T_TXENFAST; + nrf_timer_cc_set(NRF_TIMER0, 0, radio_time); NRF_TIMER0->EVENTS_COMPARE[0] = 0; phy_ppi_timer0_compare0_to_radio_txen_enable(); #if PHY_USE_FEM_PA + nrf_timer_cc_set(NRF_TIMER0, 2, fem_time); + NRF_TIMER0->EVENTS_COMPARE[2] = 0; phy_fem_enable_pa(); #endif - /* - * XXX: Hack warning! - * - * It may happen (during flash erase) that CPU is stopped for a moment and - * TIMER0 already counted past CC[0]. In such case we will be stuck waiting - * for TX to start since EVENTS_COMPARE[0] will not happen any time soon. - * For now let's set a flag denoting that we are late in RX-TX transition so - * ble_phy_tx() will fail - this allows everything to cleanup nicely without - * the need for extra handling in many places. + /* Need to check if TIMER0 did not already count past CC[0] and/or CC[2], so + * we're not stuck waiting for events in case radio and/or PA was not + * started. If event was triggered we're fine regardless of timer value. * * Note: CC[3] is used only for wfr which we do not need here. */ nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); - if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) { + is_late = (NRF_TIMER0->CC[3] > radio_time) && !NRF_TIMER0->EVENTS_COMPARE[0]; +#if PHY_USE_FEM_PA + is_late = is_late || + ((NRF_TIMER0->CC[3] > fem_time) && !NRF_TIMER0->EVENTS_COMPARE[2]); +#endif + if (is_late) { phy_ppi_timer0_compare0_to_radio_txen_disable(); g_ble_phy_data.phy_transition_late = 1; } @@ -1644,10 +1736,6 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) /* Enable PPI to automatically start TXEN */ phy_ppi_timer0_compare0_to_radio_txen_enable(); rc = 0; - -#if PHY_USE_FEM_PA - phy_fem_enable_pa(); -#endif } return rc; @@ -1694,10 +1782,6 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) /* Enable PPI to automatically start RXEN */ phy_ppi_timer0_compare0_to_radio_rxen_enable(); -#if PHY_USE_FEM_LNA - phy_fem_enable_lna(); -#endif - /* Start rx */ rc = ble_phy_rx(); diff --git a/nimble/drivers/nrf5x/src/nrf52/phy.c b/nimble/drivers/nrf5x/src/nrf52/phy.c index d4492464a4..188d157111 100644 --- a/nimble/drivers/nrf5x/src/nrf52/phy.c +++ b/nimble/drivers/nrf5x/src/nrf52/phy.c @@ -102,7 +102,7 @@ phy_fem_init(void) #endif #endif /* PHY_USE_FEM_SINGLE_GPIO */ - NRF_PPI->CH[6].EEP = (uint32_t)&(NRF_RADIO->EVENTS_READY); + NRF_PPI->CH[6].EEP = (uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[2]); NRF_PPI->CH[7].EEP = (uint32_t)&(NRF_RADIO->EVENTS_DISABLED); nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk); diff --git a/nimble/drivers/nrf5x/syscfg.yml b/nimble/drivers/nrf5x/syscfg.yml index f24517ef07..1d4027f7d0 100644 --- a/nimble/drivers/nrf5x/syscfg.yml +++ b/nimble/drivers/nrf5x/syscfg.yml @@ -52,3 +52,9 @@ syscfg.defs: in UICR register. If enabled public address will be read from custom UICR instead of FICR register. value: 0 + +syscfg.restrictions: + # code supports turn on times up to 90us due to some optimizations, but it + # should be enough for most (all?) cases + - "!BLE_LL_FEM_PA || BLE_LL_FEM_PA_TURN_ON_US <= 90" + - "!BLE_LL_FEM_LNA || BLE_LL_FEM_LNA_TURN_ON_US <= 90" From eaa56fa7e7a90522109e097d34be06a4b65013ee Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 12 Sep 2022 16:37:11 +0200 Subject: [PATCH 0534/1333] nimble/phy/nrf5x: Adjust scheduling offset for FEM turn on Radio enable takes 2 ticks, so if FEM turn on time is more than that we need to account for extra tick in scheduling offset. --- nimble/drivers/nrf5x/include/ble/xcvr.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/nimble/drivers/nrf5x/include/ble/xcvr.h b/nimble/drivers/nrf5x/include/ble/xcvr.h index 757bb80faa..829514b422 100644 --- a/nimble/drivers/nrf5x/include/ble/xcvr.h +++ b/nimble/drivers/nrf5x/include/ble/xcvr.h @@ -24,14 +24,23 @@ extern "C" { #endif +#include + #define XCVR_RX_RADIO_RAMPUP_USECS (40) #define XCVR_TX_RADIO_RAMPUP_USECS (40) -/* - * NOTE: we have to account for the RTC output compare issue. We want it to be - * 5 ticks. +/* We need to account for the RTC compare issue, we want it to be 5 ticks. + * In case FEM turn on time is more than radio enable (i.e. 2 ticks) we want + * to add 1 more tick to compensate for additional delay. + * + * TODO this file should be refactored... */ +#if (MYNEWT_VAL(BLE_LL_FEM_PA) && (MYNEWT_VAL(BLE_LL_FEM_PA_TURN_ON_US) > 60)) || \ + (MYNEWT_VAL(BLE_LL_FEM_LNA) && (MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US) > 60)) +#define XCVR_PROC_DELAY_USECS (183) +#else #define XCVR_PROC_DELAY_USECS (153) +#endif #define XCVR_RX_START_DELAY_USECS (XCVR_RX_RADIO_RAMPUP_USECS) #define XCVR_TX_START_DELAY_USECS (XCVR_TX_RADIO_RAMPUP_USECS) #define XCVR_TX_SCHED_DELAY_USECS \ From 3b02d6ba2f9c2fd32b070ff533b1cd3a10d69501 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 8 Sep 2022 15:13:43 +0200 Subject: [PATCH 0535/1333] nimble/ll: Remove nrf52 and nrf5340 phys --- nimble/drivers/nrf52/include/ble/xcvr.h | 52 - nimble/drivers/nrf52/pkg.yml | 13 +- nimble/drivers/nrf52/src/ble_hw.c | 517 ----- nimble/drivers/nrf52/src/ble_phy.c | 2301 -------------------- nimble/drivers/nrf52/src/ble_phy_trace.c | 44 - nimble/drivers/nrf52/syscfg.yml | 81 - nimble/drivers/nrf5340/include/ble/xcvr.h | 50 - nimble/drivers/nrf5340/pkg.yml | 13 +- nimble/drivers/nrf5340/src/ble_hw.c | 477 ---- nimble/drivers/nrf5340/src/ble_phy.c | 2079 ------------------ nimble/drivers/nrf5340/src/ble_phy_trace.c | 45 - nimble/drivers/nrf5340/syscfg.yml | 62 - 12 files changed, 4 insertions(+), 5730 deletions(-) delete mode 100644 nimble/drivers/nrf52/include/ble/xcvr.h delete mode 100644 nimble/drivers/nrf52/src/ble_hw.c delete mode 100644 nimble/drivers/nrf52/src/ble_phy.c delete mode 100644 nimble/drivers/nrf52/src/ble_phy_trace.c delete mode 100644 nimble/drivers/nrf52/syscfg.yml delete mode 100644 nimble/drivers/nrf5340/include/ble/xcvr.h delete mode 100644 nimble/drivers/nrf5340/src/ble_hw.c delete mode 100644 nimble/drivers/nrf5340/src/ble_phy.c delete mode 100644 nimble/drivers/nrf5340/src/ble_phy_trace.c delete mode 100644 nimble/drivers/nrf5340/syscfg.yml diff --git a/nimble/drivers/nrf52/include/ble/xcvr.h b/nimble/drivers/nrf52/include/ble/xcvr.h deleted file mode 100644 index 757bb80faa..0000000000 --- a/nimble/drivers/nrf52/include/ble/xcvr.h +++ /dev/null @@ -1,52 +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_BLE_XCVR_ -#define H_BLE_XCVR_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define XCVR_RX_RADIO_RAMPUP_USECS (40) -#define XCVR_TX_RADIO_RAMPUP_USECS (40) - -/* - * NOTE: we have to account for the RTC output compare issue. We want it to be - * 5 ticks. - */ -#define XCVR_PROC_DELAY_USECS (153) -#define XCVR_RX_START_DELAY_USECS (XCVR_RX_RADIO_RAMPUP_USECS) -#define XCVR_TX_START_DELAY_USECS (XCVR_TX_RADIO_RAMPUP_USECS) -#define XCVR_TX_SCHED_DELAY_USECS \ - (XCVR_TX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS) -#define XCVR_RX_SCHED_DELAY_USECS \ - (XCVR_RX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS) - -/* - * Define HW whitelist size. This is the total possible whitelist size; - * not necessarily the size that will be used (may be smaller) - */ -#define BLE_HW_WHITE_LIST_SIZE (8) - -#ifdef __cplusplus -} -#endif - -#endif /* H_BLE_XCVR_ */ diff --git a/nimble/drivers/nrf52/pkg.yml b/nimble/drivers/nrf52/pkg.yml index a1ff457e6f..c97452613a 100644 --- a/nimble/drivers/nrf52/pkg.yml +++ b/nimble/drivers/nrf52/pkg.yml @@ -18,14 +18,5 @@ # pkg.name: nimble/drivers/nrf52 -pkg.description: BLE driver for nRF52 systems. -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth - -pkg.apis: ble_driver -pkg.deps: - - nimble - - nimble/controller +pkg.type: transient +pkg.link: "@apache-mynewt-nimble/nimble/drivers/nrf5x" diff --git a/nimble/drivers/nrf52/src/ble_hw.c b/nimble/drivers/nrf52/src/ble_hw.c deleted file mode 100644 index 0accbbf40e..0000000000 --- a/nimble/drivers/nrf52/src/ble_hw.c +++ /dev/null @@ -1,517 +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. - */ - -#include -#include -#include -#include "syscfg/syscfg.h" -#include "os/os.h" -#include "ble/xcvr.h" -#include "nimble/ble.h" -#include "nimble/nimble_opt.h" -#include "nrfx.h" -#include "controller/ble_hw.h" -#if MYNEWT -#include "mcu/cmsis_nvic.h" -#else -#include "core_cm4.h" -#include -#endif -#include "os/os_trace_api.h" -#include -#include "hal/nrf_ecb.h" - -/* Total number of resolving list elements */ -#define BLE_HW_RESOLV_LIST_SIZE (16) - -/* We use this to keep track of which entries are set to valid addresses */ -static uint8_t g_ble_hw_whitelist_mask; - -/* Random number generator isr callback */ -ble_rng_isr_cb_t g_ble_rng_isr_cb; - -#if BABBLESIM -extern void tm_tick(void); -#endif - -/* If LL privacy is enabled, allocate memory for AAR */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - -/* The NRF51 supports up to 16 IRK entries */ -#if (MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE) < 16) -#define NRF_IRK_LIST_ENTRIES (MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE)) -#else -#define NRF_IRK_LIST_ENTRIES (16) -#endif - -/* NOTE: each entry is 16 bytes long. */ -uint32_t g_nrf_irk_list[NRF_IRK_LIST_ENTRIES * 4]; - -/* Current number of IRK entries */ -uint8_t g_nrf_num_irks; - -#endif - -/* Returns public device address or -1 if not present */ -int -ble_hw_get_public_addr(ble_addr_t *addr) -{ - uint32_t addr_high; - uint32_t addr_low; - -#if MYNEWT_VAL(BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR) - /* - * The BMD-345 modules are preprogrammed from the factory with a unique public - * The Bluetooth device address stored in the CUSTOMER[0] and CUSTOMER[1] - * registers of the User Information Configuration Registers (UICR). - * The Bluetooth device address consists of the IEEE Organizationally Unique - * Identifier (OUI) combined with the hexadecimal digits that are printed on - * a 2D barcode and in human-readable text on the module label.The Bluetooth - * device address is stored in little endian format. The most significant - * bytes of the CUSTOMER[1] register are 0xFF to complete the 32-bit register. - */ - - /* Copy into device address. We can do this because we know platform */ - addr_low = NRF_UICR->CUSTOMER[0]; - addr_high = NRF_UICR->CUSTOMER[1]; -#else - /* Does FICR have a public address */ - if ((NRF_FICR->DEVICEADDRTYPE & 1) != 0) { - return -1; - } - - /* Copy into device address. We can do this because we know platform */ - addr_low = NRF_FICR->DEVICEADDR[0]; - addr_high = NRF_FICR->DEVICEADDR[1]; -#endif - - memcpy(addr->val, &addr_low, 4); - memcpy(&addr->val[4], &addr_high, 2); - addr->type = BLE_ADDR_PUBLIC; - - return 0; -} - -/* Returns random static address or -1 if not present */ -int -ble_hw_get_static_addr(ble_addr_t *addr) -{ - uint32_t addr_high; - uint32_t addr_low; - int rc; - - if ((NRF_FICR->DEVICEADDRTYPE & 1) == 1) { - addr_low = NRF_FICR->DEVICEADDR[0]; - addr_high = NRF_FICR->DEVICEADDR[1]; - - memcpy(addr->val, &addr_low, 4); - memcpy(&addr->val[4], &addr_high, 2); - - addr->val[5] |= 0xc0; - addr->type = BLE_ADDR_RANDOM; - rc = 0; - } else { - rc = -1; - } - - return rc; -} - -/** - * Clear the whitelist - * - * @return int - */ -void -ble_hw_whitelist_clear(void) -{ - NRF_RADIO->DACNF = 0; - g_ble_hw_whitelist_mask = 0; -} - -/** - * Add a device to the hw whitelist - * - * @param addr - * @param addr_type - * - * @return int 0: success, BLE error code otherwise - */ -int -ble_hw_whitelist_add(const uint8_t *addr, uint8_t addr_type) -{ - int i; - uint32_t mask; - - /* Find first ununsed device address match element */ - mask = 0x01; - for (i = 0; i < BLE_HW_WHITE_LIST_SIZE; ++i) { - if ((mask & g_ble_hw_whitelist_mask) == 0) { - NRF_RADIO->DAB[i] = get_le32(addr); - NRF_RADIO->DAP[i] = get_le16(addr + 4); - if (addr_type == BLE_ADDR_RANDOM) { - NRF_RADIO->DACNF |= (mask << 8); - } - g_ble_hw_whitelist_mask |= mask; - return BLE_ERR_SUCCESS; - } - mask <<= 1; - } - - return BLE_ERR_MEM_CAPACITY; -} - -/** - * Remove a device from the hw whitelist - * - * @param addr - * @param addr_type - * - */ -void -ble_hw_whitelist_rmv(const uint8_t *addr, uint8_t addr_type) -{ - int i; - uint8_t cfg_addr; - uint16_t dap; - uint16_t txadd; - uint32_t dab; - uint32_t mask; - - /* Find first ununsed device address match element */ - dab = get_le32(addr); - dap = get_le16(addr + 4); - txadd = NRF_RADIO->DACNF >> 8; - mask = 0x01; - for (i = 0; i < BLE_HW_WHITE_LIST_SIZE; ++i) { - if (mask & g_ble_hw_whitelist_mask) { - if ((dab == NRF_RADIO->DAB[i]) && (dap == NRF_RADIO->DAP[i])) { - cfg_addr = txadd & mask; - if (addr_type == BLE_ADDR_RANDOM) { - if (cfg_addr != 0) { - break; - } - } else { - if (cfg_addr == 0) { - break; - } - } - } - } - mask <<= 1; - } - - if (i < BLE_HW_WHITE_LIST_SIZE) { - g_ble_hw_whitelist_mask &= ~mask; - NRF_RADIO->DACNF &= ~mask; - } -} - -/** - * Returns the size of the whitelist in HW - * - * @return int Number of devices allowed in whitelist - */ -uint8_t -ble_hw_whitelist_size(void) -{ - return BLE_HW_WHITE_LIST_SIZE; -} - -/** - * Enable the whitelisted devices - */ -void -ble_hw_whitelist_enable(void) -{ - /* Enable the configured device addresses */ - NRF_RADIO->DACNF |= g_ble_hw_whitelist_mask; -} - -/** - * Disables the whitelisted devices - */ -void -ble_hw_whitelist_disable(void) -{ - /* Disable all whitelist devices */ - NRF_RADIO->DACNF &= 0x0000ff00; -} - -/** - * Boolean function which returns true ('1') if there is a match on the - * whitelist. - * - * @return int - */ -int -ble_hw_whitelist_match(void) -{ - return (int)NRF_RADIO->EVENTS_DEVMATCH; -} - -/* Encrypt data */ -int -ble_hw_encrypt_block(struct ble_encryption_block *ecb) -{ - int rc; - uint32_t end; - uint32_t err; - - /* Stop ECB */ - nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STOPECB); - /* XXX: does task stop clear these counters? Anyway to do this quicker? */ - NRF_ECB->EVENTS_ENDECB = 0; - NRF_ECB->EVENTS_ERRORECB = 0; - NRF_ECB->ECBDATAPTR = (uint32_t)ecb; - - /* Start ECB */ - nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STARTECB); - - /* Wait till error or done */ - rc = 0; - while (1) { - end = NRF_ECB->EVENTS_ENDECB; - err = NRF_ECB->EVENTS_ERRORECB; - if (end || err) { - if (err) { - rc = -1; - } - break; - } -#if BABBLESIM - tm_tick(); -#endif - } - - return rc; -} - -/** - * Random number generator ISR. - */ -static void -ble_rng_isr(void) -{ - uint8_t rnum; - - os_trace_isr_enter(); - - /* No callback? Clear and disable interrupts */ - if (g_ble_rng_isr_cb == NULL) { - nrf_rng_int_disable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK); - NRF_RNG->EVENTS_VALRDY = 0; - (void)NRF_RNG->SHORTS; - os_trace_isr_exit(); - return; - } - - /* If there is a value ready grab it */ - if (NRF_RNG->EVENTS_VALRDY) { - NRF_RNG->EVENTS_VALRDY = 0; - rnum = (uint8_t)NRF_RNG->VALUE; - (*g_ble_rng_isr_cb)(rnum); - } - - os_trace_isr_exit(); -} - -/** - * Initialize the random number generator - * - * @param cb - * @param bias - * - * @return int - */ -int -ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias) -{ - /* Set bias */ - if (bias) { - NRF_RNG->CONFIG = 1; - } else { - NRF_RNG->CONFIG = 0; - } - - /* If we were passed a function pointer we need to enable the interrupt */ - if (cb != NULL) { -#ifndef RIOT_VERSION - NVIC_SetPriority(RNG_IRQn, (1 << __NVIC_PRIO_BITS) - 1); -#endif -#if MYNEWT - NVIC_SetVector(RNG_IRQn, (uint32_t)ble_rng_isr); -#else - ble_npl_hw_set_isr(RNG_IRQn, ble_rng_isr); -#endif - NVIC_EnableIRQ(RNG_IRQn); - g_ble_rng_isr_cb = cb; - } - - return 0; -} - -/** - * Start the random number generator - * - * @return int - */ -int -ble_hw_rng_start(void) -{ - os_sr_t sr; - - /* No need for interrupt if there is no callback */ - OS_ENTER_CRITICAL(sr); - NRF_RNG->EVENTS_VALRDY = 0; - - if (g_ble_rng_isr_cb) { - nrf_rng_int_enable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK); - } - nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_START); - OS_EXIT_CRITICAL(sr); - - return 0; -} - -/** - * Stop the random generator - * - * @return int - */ -int -ble_hw_rng_stop(void) -{ - os_sr_t sr; - - /* No need for interrupt if there is no callback */ - OS_ENTER_CRITICAL(sr); - nrf_rng_int_disable(NRF_RNG, NRF_RNG_INT_VALRDY_MASK); - nrf_rng_task_trigger(NRF_RNG, NRF_RNG_TASK_STOP); - NRF_RNG->EVENTS_VALRDY = 0; - OS_EXIT_CRITICAL(sr); - - return 0; -} - -/** - * Read the random number generator. - * - * @return uint8_t - */ -uint8_t -ble_hw_rng_read(void) -{ - uint8_t rnum; - - /* Wait for a sample */ - while (NRF_RNG->EVENTS_VALRDY == 0) { - } - - NRF_RNG->EVENTS_VALRDY = 0; - rnum = (uint8_t)NRF_RNG->VALUE; - - return rnum; -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) -/** - * Clear the resolving list - * - * @return int - */ -void -ble_hw_resolv_list_clear(void) -{ - g_nrf_num_irks = 0; -} - -/** - * Add a device to the hw resolving list - * - * @param irk Pointer to IRK to add - * - * @return int 0: success, BLE error code otherwise - */ -int -ble_hw_resolv_list_add(uint8_t *irk) -{ - uint32_t *nrf_entry; - - /* Find first ununsed device address match element */ - if (g_nrf_num_irks == NRF_IRK_LIST_ENTRIES) { - return BLE_ERR_MEM_CAPACITY; - } - - /* Copy into irk list */ - nrf_entry = &g_nrf_irk_list[4 * g_nrf_num_irks]; - memcpy(nrf_entry, irk, 16); - - /* Add to total */ - ++g_nrf_num_irks; - return BLE_ERR_SUCCESS; -} - -/** - * Remove a device from the hw resolving list - * - * @param index Index of IRK to remove - */ -void -ble_hw_resolv_list_rmv(int index) -{ - uint32_t *irk_entry; - - if (index < g_nrf_num_irks) { - --g_nrf_num_irks; - irk_entry = &g_nrf_irk_list[index]; - if (g_nrf_num_irks > index) { - memmove(irk_entry, irk_entry + 4, 16 * (g_nrf_num_irks - index)); - } - } -} - -/** - * Returns the size of the resolving list. NOTE: this returns the maximum - * allowable entries in the HW. Configuration options may limit this. - * - * @return int Number of devices allowed in resolving list - */ -uint8_t -ble_hw_resolv_list_size(void) -{ - return BLE_HW_RESOLV_LIST_SIZE; -} - -/** - * Called to determine if the address received was resolved. - * - * @return int Negative values indicate unresolved address; positive values - * indicate index in resolving list of resolved address. - */ -int -ble_hw_resolv_list_match(void) -{ - if (NRF_AAR->ENABLE && NRF_AAR->EVENTS_END && NRF_AAR->EVENTS_RESOLVED) { - return (int)NRF_AAR->STATUS; - } - - return -1; -} -#endif diff --git a/nimble/drivers/nrf52/src/ble_phy.c b/nimble/drivers/nrf52/src/ble_phy.c deleted file mode 100644 index a94cb2a75a..0000000000 --- a/nimble/drivers/nrf52/src/ble_phy.c +++ /dev/null @@ -1,2301 +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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "syscfg/syscfg.h" -#include "os/os.h" -/* Keep os_cputime explicitly to enable build on non-Mynewt platforms */ -#include "os/os_cputime.h" -#include "ble/xcvr.h" -#include "nimble/ble.h" -#include "nimble/nimble_opt.h" -#include "nimble/nimble_npl.h" -#include "controller/ble_phy.h" -#include "controller/ble_phy_trace.h" -#include "controller/ble_ll.h" -#include "nrfx.h" -#if MYNEWT -#include "mcu/nrf52_clock.h" -#include "mcu/cmsis_nvic.h" -#include "hal/hal_gpio.h" -#else -#include "core_cm4.h" -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) -#if !MYNEWT_VAL_CHOICE(MCU_TARGET, nRF52840) && !MYNEWT_VAL_CHOICE(MCU_TARGET, nRF52811) -#error LE Coded PHY can only be enabled on nRF52811 or nRF52840 -#endif -#endif - -#if BABBLESIM -extern void tm_tick(void); -#endif - -/* - * NOTE: This code uses a couple of PPI channels so care should be taken when - * using PPI somewhere else. - * - * Pre-programmed channels: CH20, CH21, CH23, CH25, CH31 - * Regular channels: CH4, CH5 and optionally CH6, CH7, CH17, CH18, CH19 - * - CH4 = cancel wfr timer on address match - * - CH5 = disable radio on wfr timer expiry - * - CH6 = PA/LNA control (enable) - * - CH7 = PA/LNA control (disable) - * - CH17 = (optional) gpio debug for radio ramp-up - * - CH18 = (optional) gpio debug for wfr timer RX enabled - * - CH19 = (optional) gpio debug for wfr timer radio disabled - * - */ - -/* XXX: 4) Make sure RF is higher priority interrupt than schedule */ - -/* - * XXX: Maximum possible transmit time is 1 msec for a 60ppm crystal - * and 16ms for a 30ppm crystal! We need to limit PDU size based on - * crystal accuracy. Look at this in the spec. - */ - -/* XXX: private header file? */ -extern uint8_t g_nrf_num_irks; -extern uint32_t g_nrf_irk_list[]; - -/* To disable all radio interrupts */ -#define NRF_RADIO_IRQ_MASK_ALL (0x34FF) - -/* - * We configure the nrf with a 1 byte S0 field, 8 bit length field, and - * zero bit S1 field. The preamble is 8 bits long. - */ -#define NRF_LFLEN_BITS (8) -#define NRF_S0LEN (1) -#define NRF_S1LEN_BITS (0) -#define NRF_CILEN_BITS (2) -#define NRF_TERMLEN_BITS (3) - -/* Maximum length of frames */ -#define NRF_MAXLEN (255) -#define NRF_BALEN (3) /* For base address of 3 bytes */ - -/* NRF_RADIO->PCNF0 configuration values */ -#define NRF_PCNF0 (NRF_LFLEN_BITS << RADIO_PCNF0_LFLEN_Pos) | \ - (RADIO_PCNF0_S1INCL_Msk) | \ - (NRF_S0LEN << RADIO_PCNF0_S0LEN_Pos) | \ - (NRF_S1LEN_BITS << RADIO_PCNF0_S1LEN_Pos) -#define NRF_PCNF0_1M (NRF_PCNF0) | \ - (RADIO_PCNF0_PLEN_8bit << RADIO_PCNF0_PLEN_Pos) -#define NRF_PCNF0_2M (NRF_PCNF0) | \ - (RADIO_PCNF0_PLEN_16bit << RADIO_PCNF0_PLEN_Pos) -#define NRF_PCNF0_CODED (NRF_PCNF0) | \ - (RADIO_PCNF0_PLEN_LongRange << RADIO_PCNF0_PLEN_Pos) | \ - (NRF_CILEN_BITS << RADIO_PCNF0_CILEN_Pos) | \ - (NRF_TERMLEN_BITS << RADIO_PCNF0_TERMLEN_Pos) - -/* BLE PHY data structure */ -struct ble_phy_obj -{ - uint8_t phy_stats_initialized; - int8_t phy_txpwr_dbm; - uint8_t phy_chan; - uint8_t phy_state; - uint8_t phy_transition; - uint8_t phy_transition_late; - uint8_t phy_rx_started; - uint8_t phy_encrypted; - uint8_t phy_privacy; - uint8_t phy_tx_pyld_len; - uint8_t phy_cur_phy_mode; - uint8_t phy_tx_phy_mode; - uint8_t phy_rx_phy_mode; - uint8_t phy_bcc_offset; - int8_t rx_pwr_compensation; - uint32_t phy_aar_scratch; - uint32_t phy_access_address; - struct ble_mbuf_hdr rxhdr; - void *txend_arg; - ble_phy_tx_end_func txend_cb; - uint32_t phy_start_cputime; -#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) - uint16_t tifs; -#endif -}; -struct ble_phy_obj g_ble_phy_data; - -/* XXX: if 27 byte packets desired we can make this smaller */ -/* Global transmit/receive buffer */ -static uint32_t g_ble_phy_tx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4]; -static uint32_t g_ble_phy_rx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4]; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -/* Make sure word-aligned for faster copies */ -static uint32_t g_ble_phy_enc_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4]; -#endif - -/* RF center frequency for each channel index (offset from 2400 MHz) */ -static const uint8_t g_ble_phy_chan_freq[BLE_PHY_NUM_CHANS] = { - 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, /* 0-9 */ - 24, 28, 30, 32, 34, 36, 38, 40, 42, 44, /* 10-19 */ - 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, /* 20-29 */ - 66, 68, 70, 72, 74, 76, 78, 2, 26, 80, /* 30-39 */ -}; - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) -/* packet start offsets (in usecs) */ -static const uint16_t g_ble_phy_mode_pkt_start_off[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 40, - [BLE_PHY_MODE_2M] = 24, - [BLE_PHY_MODE_CODED_125KBPS] = 376, - [BLE_PHY_MODE_CODED_500KBPS] = 376 -}; -#endif - -/* Various radio timings */ -/* Radio ramp-up times in usecs (fast mode) */ -#define BLE_PHY_T_TXENFAST (XCVR_TX_RADIO_RAMPUP_USECS) -#define BLE_PHY_T_RXENFAST (XCVR_RX_RADIO_RAMPUP_USECS) - -#if BABBLESIM -/* delay between EVENTS_READY and start of tx */ -static const uint8_t g_ble_phy_t_txdelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 1, - [BLE_PHY_MODE_2M] = 1, -}; -/* delay between EVENTS_END and end of txd packet */ -static const uint8_t g_ble_phy_t_txenddelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 1, - [BLE_PHY_MODE_2M] = 1, -}; -/* delay between rxd access address (w/ TERM1 for coded) and EVENTS_ADDRESS */ -static const uint8_t g_ble_phy_t_rxaddrdelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 9, - [BLE_PHY_MODE_2M] = 5, -}; -/* delay between end of rxd packet and EVENTS_END */ -static const uint8_t g_ble_phy_t_rxenddelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 9, - [BLE_PHY_MODE_2M] = 5, -}; -#else -/* delay between EVENTS_READY and start of tx */ -static const uint8_t g_ble_phy_t_txdelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 4, - [BLE_PHY_MODE_2M] = 3, - [BLE_PHY_MODE_CODED_125KBPS] = 5, - [BLE_PHY_MODE_CODED_500KBPS] = 5 -}; -/* delay between EVENTS_END and end of txd packet */ -static const uint8_t g_ble_phy_t_txenddelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 4, - [BLE_PHY_MODE_2M] = 3, - [BLE_PHY_MODE_CODED_125KBPS] = 9, - [BLE_PHY_MODE_CODED_500KBPS] = 3 -}; -/* delay between rxd access address (w/ TERM1 for coded) and EVENTS_ADDRESS */ -static const uint8_t g_ble_phy_t_rxaddrdelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 6, - [BLE_PHY_MODE_2M] = 2, - [BLE_PHY_MODE_CODED_125KBPS] = 17, - [BLE_PHY_MODE_CODED_500KBPS] = 17 -}; -/* delay between end of rxd packet and EVENTS_END */ -static const uint8_t g_ble_phy_t_rxenddelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 6, - [BLE_PHY_MODE_2M] = 2, - [BLE_PHY_MODE_CODED_125KBPS] = 27, - [BLE_PHY_MODE_CODED_500KBPS] = 22 -}; -#endif - -/* Statistics */ -STATS_SECT_START(ble_phy_stats) - STATS_SECT_ENTRY(phy_isrs) - STATS_SECT_ENTRY(tx_good) - STATS_SECT_ENTRY(tx_fail) - STATS_SECT_ENTRY(tx_late) - STATS_SECT_ENTRY(tx_bytes) - STATS_SECT_ENTRY(rx_starts) - STATS_SECT_ENTRY(rx_aborts) - STATS_SECT_ENTRY(rx_valid) - STATS_SECT_ENTRY(rx_crc_err) - STATS_SECT_ENTRY(rx_late) - STATS_SECT_ENTRY(radio_state_errs) - STATS_SECT_ENTRY(rx_hw_err) - STATS_SECT_ENTRY(tx_hw_err) -STATS_SECT_END -STATS_SECT_DECL(ble_phy_stats) ble_phy_stats; - -STATS_NAME_START(ble_phy_stats) - STATS_NAME(ble_phy_stats, phy_isrs) - STATS_NAME(ble_phy_stats, tx_good) - STATS_NAME(ble_phy_stats, tx_fail) - STATS_NAME(ble_phy_stats, tx_late) - STATS_NAME(ble_phy_stats, tx_bytes) - STATS_NAME(ble_phy_stats, rx_starts) - STATS_NAME(ble_phy_stats, rx_aborts) - STATS_NAME(ble_phy_stats, rx_valid) - STATS_NAME(ble_phy_stats, rx_crc_err) - STATS_NAME(ble_phy_stats, rx_late) - STATS_NAME(ble_phy_stats, radio_state_errs) - STATS_NAME(ble_phy_stats, rx_hw_err) - STATS_NAME(ble_phy_stats, tx_hw_err) -STATS_NAME_END(ble_phy_stats) - -/* - * NOTE: - * Tested the following to see what would happen: - * -> NVIC has radio irq enabled (interrupt # 1, mask 0x2). - * -> Set up nrf to receive. Clear ADDRESS event register. - * -> Enable ADDRESS interrupt on nrf5 by writing to INTENSET. - * -> Enable RX. - * -> Disable interrupts globally using OS_ENTER_CRITICAL(). - * -> Wait until a packet is received and the ADDRESS event occurs. - * -> Call ble_phy_disable(). - * - * At this point I wanted to see the state of the cortex NVIC. The IRQ - * pending bit was TRUE for the radio interrupt (as expected) as we never - * serviced the radio interrupt (interrupts were disabled). - * - * What was unexpected was this: without clearing the pending IRQ in the NVIC, - * when radio interrupts were re-enabled (address event bit in INTENSET set to - * 1) and the radio ADDRESS event register read 1 (it was never cleared after - * the first address event), the radio did not enter the ISR! I would have - * expected that if the following were true, an interrupt would occur: - * -> NVIC ISER bit set to TRUE - * -> NVIC ISPR bit reads TRUE, meaning interrupt is pending. - * -> Radio peripheral interrupts are enabled for some event (or events). - * -> Corresponding event register(s) in radio peripheral read 1. - * - * Not sure what the end result of all this is. We will clear the pending - * bit in the NVIC just to be sure when we disable the PHY. - */ - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - -/* - * Per nordic, the number of bytes needed for scratch is 16 + MAX_PKT_SIZE. - * However, when I used a smaller size it still overwrote the scratchpad. Until - * I figure this out I am just going to allocate 67 words so we have enough - * space for 267 bytes of scratch. I used 268 bytes since not sure if this - * needs to be aligned and burning a byte is no big deal. - */ -//#define NRF_ENC_SCRATCH_WORDS (((MYNEWT_VAL(BLE_LL_MAX_PKT_SIZE) + 16) + 3) / 4) -#define NRF_ENC_SCRATCH_WORDS (67) - -uint32_t g_nrf_encrypt_scratchpad[NRF_ENC_SCRATCH_WORDS]; - -struct nrf_ccm_data -{ - uint8_t key[16]; - uint64_t pkt_counter; - uint8_t dir_bit; - uint8_t iv[8]; -} __attribute__((packed)); - -struct nrf_ccm_data g_nrf_ccm_data; -#endif - -static int g_ble_phy_gpiote_idx; - -#if MYNEWT_VAL(BLE_LL_FEM_PA) || MYNEWT_VAL(BLE_LL_FEM_LNA) - -#define FEM_SINGLE_GPIO \ - (!MYNEWT_VAL(BLE_LL_FEM_PA) || !MYNEWT_VAL(BLE_LL_FEM_LNA) || \ - (MYNEWT_VAL(BLE_LL_FEM_PA_GPIO) == MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO))) - -#if FEM_SINGLE_GPIO -static uint8_t fem_idx; -#else -#if MYNEWT_VAL(BLE_LL_FEM_PA) -static uint8_t fem_pa_idx; -#endif -#if MYNEWT_VAL(BLE_LL_FEM_LNA) -static uint8_t fem_lna_idx; -#endif -#endif - -#endif - -#ifndef BABBLESIM -static void -ble_phy_apply_errata_102_106_107(void) -{ - /* [102] RADIO: PAYLOAD/END events delayed or not triggered after ADDRESS - * [106] RADIO: Higher CRC error rates for some access addresses - * [107] RADIO: Immediate address match for access addresses containing MSBs 0x00 - */ - *(volatile uint32_t *)0x40001774 = ((*(volatile uint32_t *)0x40001774) & - 0xfffffffe) | 0x01000000; -} -#endif - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - -/* Packet start offset (in usecs). This is the preamble plus access address. - * For LE Coded PHY this also includes CI and TERM1. */ -uint32_t -ble_phy_mode_pdu_start_off(int phy_mode) -{ - return g_ble_phy_mode_pkt_start_off[phy_mode]; -} - -#if NRF52840_XXAA -static inline bool -ble_phy_mode_is_coded(uint8_t phy_mode) -{ - return (phy_mode == BLE_PHY_MODE_CODED_125KBPS) || - (phy_mode == BLE_PHY_MODE_CODED_500KBPS); -} - -static void -ble_phy_apply_nrf52840_errata(uint8_t new_phy_mode) -{ - bool new_coded = ble_phy_mode_is_coded(new_phy_mode); - bool cur_coded = ble_phy_mode_is_coded(g_ble_phy_data.phy_cur_phy_mode); - - /* - * Workarounds should be applied only when switching to/from LE Coded PHY - * so no need to apply them every time. - * - * nRF52840 Engineering A Errata v1.2 - * [164] RADIO: Low sensitivity in long range mode - * - * nRF52840 Rev 1 Errata - * [191] RADIO: High packet error rate in BLE Long Range mode - */ - if (new_coded == cur_coded) { - return; - } - - if (new_coded) { -#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_164) - /* [164] */ - *(volatile uint32_t *)0x4000173C |= 0x80000000; - *(volatile uint32_t *)0x4000173C = - ((*(volatile uint32_t *)0x4000173C & 0xFFFFFF00) | 0x5C); -#endif -#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_191) - /* [191] */ - *(volatile uint32_t *) 0x40001740 = - ((*((volatile uint32_t *) 0x40001740)) & 0x7FFF00FF) | - 0x80000000 | (((uint32_t)(196)) << 8); -#endif - } else { -#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_164) - /* [164] */ - *(volatile uint32_t *)0x4000173C &= ~0x80000000; -#endif -#if MYNEWT_VAL(BLE_PHY_NRF52840_ERRATA_191) - /* [191] */ - *(volatile uint32_t *) 0x40001740 = - ((*((volatile uint32_t *) 0x40001740)) & 0x7FFFFFFF); -#endif - } -} -#endif - -static void -ble_phy_mode_apply(uint8_t phy_mode) -{ - if (phy_mode == g_ble_phy_data.phy_cur_phy_mode) { - return; - } - -#if NRF52840_XXAA - ble_phy_apply_nrf52840_errata(phy_mode); -#endif - - switch (phy_mode) { - case BLE_PHY_MODE_1M: - NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit; - NRF_RADIO->PCNF0 = NRF_PCNF0_1M; - break; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) - case BLE_PHY_MODE_2M: - NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_2Mbit; - NRF_RADIO->PCNF0 = NRF_PCNF0_2M; - break; -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - case BLE_PHY_MODE_CODED_125KBPS: - NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_LR125Kbit; - NRF_RADIO->PCNF0 = NRF_PCNF0_CODED; - break; - case BLE_PHY_MODE_CODED_500KBPS: - NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_LR500Kbit; - NRF_RADIO->PCNF0 = NRF_PCNF0_CODED; - break; -#endif - default: - assert(0); - } - - g_ble_phy_data.phy_cur_phy_mode = phy_mode; -} - -void -ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode) -{ - g_ble_phy_data.phy_tx_phy_mode = tx_phy_mode; - g_ble_phy_data.phy_rx_phy_mode = rx_phy_mode; -} -#endif - -static void -ble_phy_fem_enable_pa(void) -{ -#if MYNEWT_VAL(BLE_LL_FEM_PA) - ble_ll_fem_pa_enable(); - -#if !FEM_SINGLE_GPIO - NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[fem_pa_idx]); - NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[fem_pa_idx]); -#endif - - NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; -#endif -} - -static void -ble_phy_fem_enable_lna(void) -{ -#if MYNEWT_VAL(BLE_LL_FEM_LNA) - ble_ll_fem_lna_enable(); - -#if !FEM_SINGLE_GPIO - NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[fem_lna_idx]); - NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[fem_lna_idx]); -#endif - - NRF_PPI->CHENSET = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; -#endif -} - -int -ble_phy_get_cur_phy(void) -{ -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - switch (g_ble_phy_data.phy_cur_phy_mode) { - case BLE_PHY_MODE_1M: - return BLE_PHY_1M; - case BLE_PHY_MODE_2M: - return BLE_PHY_2M; - case BLE_PHY_MODE_CODED_125KBPS: - case BLE_PHY_MODE_CODED_500KBPS: - return BLE_PHY_CODED; - default: - assert(0); - return -1; - } -#else - return BLE_PHY_1M; -#endif -} - -/** - * Copies the data from the phy receive buffer into a mbuf chain. - * - * @param dptr Pointer to receive buffer - * @param rxpdu Pointer to already allocated mbuf chain - * - * NOTE: the packet header already has the total mbuf length in it. The - * lengths of the individual mbufs are not set prior to calling. - * - */ -void -ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu) -{ - uint32_t rem_len; - uint32_t copy_len; - uint32_t block_len; - uint32_t block_rem_len; - void *dst; - void *src; - struct os_mbuf * om; - - /* Better be aligned */ - assert(((uint32_t)dptr & 3) == 0); - - block_len = rxpdu->om_omp->omp_databuf_len; - rem_len = OS_MBUF_PKTHDR(rxpdu)->omp_len; - src = dptr; - - /* - * Setup for copying from first mbuf which is shorter due to packet header - * and extra leading space - */ - copy_len = block_len - rxpdu->om_pkthdr_len - 4; - om = rxpdu; - dst = om->om_data; - - while (true) { - /* - * Always copy blocks of length aligned to word size, only last mbuf - * will have remaining non-word size bytes appended. - */ - block_rem_len = copy_len; - copy_len = min(copy_len, rem_len); - copy_len &= ~3; - - dst = om->om_data; - om->om_len = copy_len; - rem_len -= copy_len; - block_rem_len -= copy_len; - -#if BABBLESIM - memcpy(dst, src, copy_len); - dst += copy_len; - src += copy_len; -#else - __asm__ volatile (".syntax unified \n" - " mov r4, %[len] \n" - " b 2f \n" - "1: ldr r3, [%[src], %[len]] \n" - " str r3, [%[dst], %[len]] \n" - "2: subs %[len], #4 \n" - " bpl 1b \n" - " adds %[src], %[src], r4 \n" - " adds %[dst], %[dst], r4 \n" - : [dst] "+r" (dst), [src] "+r" (src), - [len] "+r" (copy_len) - : - : "r3", "r4", "memory" - ); -#endif - - if ((rem_len < 4) && (block_rem_len >= rem_len)) { - break; - } - - /* Move to next mbuf */ - om = SLIST_NEXT(om, om_next); - copy_len = block_len; - } - - /* Copy remaining bytes, if any, to last mbuf */ - om->om_len += rem_len; - -#if BABBLESIM - memcpy(dst, src, rem_len); -#else - __asm__ volatile (".syntax unified \n" - " b 2f \n" - "1: ldrb r3, [%[src], %[len]] \n" - " strb r3, [%[dst], %[len]] \n" - "2: subs %[len], #1 \n" - " bpl 1b \n" - : [len] "+r" (rem_len) - : [dst] "r" (dst), [src] "r" (src) - : "r3", "memory" - ); -#endif - - /* Copy header */ - memcpy(BLE_MBUF_HDR_PTR(rxpdu), &g_ble_phy_data.rxhdr, - sizeof(struct ble_mbuf_hdr)); -} - -/** - * Called when we want to wait if the radio is in either the rx or tx - * disable states. We want to wait until that state is over before doing - * anything to the radio - */ -static void -nrf_wait_disabled(void) -{ - uint32_t state; - - state = NRF_RADIO->STATE; - if (state != RADIO_STATE_STATE_Disabled) { - if ((state == RADIO_STATE_STATE_RxDisable) || - (state == RADIO_STATE_STATE_TxDisable)) { - /* This will end within a short time (6 usecs). Just poll */ - while (NRF_RADIO->STATE == state) { - /* If this fails, something is really wrong. Should last - * no more than 6 usecs */ -#if BABBLESIM - tm_tick(); -#endif - } - } - } -} - -#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) -static uint16_t -ble_phy_tifs_get(void) -{ - return g_ble_phy_data.tifs; -} - -void -ble_phy_tifs_set(uint16_t tifs) -{ - g_ble_phy_data.tifs = tifs; -} -#else -static uint16_t -ble_phy_tifs_get(void) -{ - return BLE_LL_IFS; -} -#endif - -/** - * - * - */ -static int -ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx) -{ - uint32_t next_cc; - uint32_t cur_cc; - uint32_t cntr; - uint32_t delta; - - /* - * We need to adjust start time to include radio ramp-up and TX pipeline - * delay (the latter only if applicable, so only for TX). - * - * Radio ramp-up time is 40 usecs and TX delay is 3 or 5 usecs depending on - * phy, thus we'll offset RTC by 2 full ticks (61 usecs) and then compensate - * using TIMER0 with 1 usec precision. - */ - - cputime -= 2; - rem_usecs += 61; - if (tx) { - rem_usecs -= BLE_PHY_T_TXENFAST; - rem_usecs -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; - } else { - rem_usecs -= BLE_PHY_T_RXENFAST; - } - - /* - * rem_usecs will be no more than 2 ticks, but if it is more than single - * tick then we should better count one more low-power tick rather than - * 30 high-power usecs. Also make sure we don't set TIMER0 CC to 0 as the - * compare won't occur. - */ - - if (rem_usecs > 30) { - cputime++; - rem_usecs -= 30; - } - - /* - * Can we set the RTC compare to start TIMER0? We can do it if: - * a) Current compare value is not N+1 or N+2 ticks from current - * counter. - * b) The value we want to set is not at least N+2 from current - * counter. - * - * NOTE: since the counter can tick 1 while we do these calculations we - * need to account for it. - */ - next_cc = cputime & 0xffffff; - cur_cc = NRF_RTC0->CC[0]; - cntr = NRF_RTC0->COUNTER; - - delta = (cur_cc - cntr) & 0xffffff; - if ((delta <= 3) && (delta != 0)) { - return -1; - } - delta = (next_cc - cntr) & 0xffffff; - if ((delta & 0x800000) || (delta < 3)) { - return -1; - } - - /* Clear and set TIMER0 to fire off at proper time */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CLEAR); - nrf_timer_cc_set(NRF_TIMER0, 0, rem_usecs); - NRF_TIMER0->EVENTS_COMPARE[0] = 0; - - /* Set RTC compare to start TIMER0 */ - NRF_RTC0->EVENTS_COMPARE[0] = 0; - nrf_rtc_cc_set(NRF_RTC0, 0, next_cc); - nrf_rtc_event_enable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); - - /* Enable PPI */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH31_Msk); - - /* Store the cputime at which we set the RTC */ - g_ble_phy_data.phy_start_cputime = cputime; - - return 0; -} - -static int -ble_phy_set_start_now(void) -{ - os_sr_t sr; - uint32_t now; - - OS_ENTER_CRITICAL(sr); - - /* - * Set TIMER0 to fire immediately. We can't set CC to 0 as compare will not - * occur in such case. - */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CLEAR); - nrf_timer_cc_set(NRF_TIMER0, 0, 1); - NRF_TIMER0->EVENTS_COMPARE[0] = 0; - - /* - * Set RTC compare to start TIMER0. We need to set it to at least N+2 ticks - * from current value to guarantee triggering compare event, but let's set - * it to N+3 to account for possible extra tick on RTC0 during these - * operations. - */ - now = os_cputime_get32(); - NRF_RTC0->EVENTS_COMPARE[0] = 0; - nrf_rtc_cc_set(NRF_RTC0, 0, now + 3); - nrf_rtc_event_enable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); - - /* Enable PPI */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH31_Msk); - /* - * Store the cputime at which we set the RTC - * - * XXX Compare event may be triggered on previous CC value (if it was set to - * less than N+2) so in rare cases actual start time may be 2 ticks earlier - * than what we expect. Since this is only used on RX, it may cause AUX scan - * to be scheduled 1 or 2 ticks too late so we'll miss it - it's acceptable - * for now. - */ - g_ble_phy_data.phy_start_cputime = now + 3; - - OS_EXIT_CRITICAL(sr); - - return 0; -} - -/** - * Function is used to set PPI so that we can time out waiting for a reception - * to occur. This happens for two reasons: we have sent a packet and we are - * waiting for a response (txrx should be set to ENABLE_TXRX) or we are - * starting a connection event and we are a slave and we are waiting for the - * master to send us a packet (txrx should be set to ENABLE_RX). - * - * NOTE: when waiting for a txrx turn-around, wfr_usecs is not used as there - * is no additional time to wait; we know when we should receive the address of - * the received frame. - * - * @param txrx Flag denoting if this wfr is a txrx turn-around or not. - * @param tx_phy_mode phy mode for last TX (only valid for TX->RX) - * @param wfr_usecs Amount of usecs to wait. - */ -void -ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) -{ - uint32_t end_time; - uint8_t phy; - - phy = g_ble_phy_data.phy_cur_phy_mode; - - if (txrx == BLE_PHY_WFR_ENABLE_TXRX) { - /* RX shall start exactly T_IFS after TX end captured in CC[2] */ - end_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); - /* Adjust for delay between EVENT_END and actual TX end time */ - end_time += g_ble_phy_t_txenddelay[tx_phy_mode]; - /* Wait a bit longer due to allowed active clock accuracy */ - end_time += 2; - /* - * It's possible that we'll capture PDU start time at the end of timer - * cycle and since wfr expires at the beginning of calculated timer - * cycle it can be almost 1 usec too early. Let's compensate for this - * by waiting 1 usec more. - */ - end_time += 1; - } else { - /* - * RX shall start no later than wfr_usecs after RX enabled. - * CC[0] is the time of RXEN so adjust for radio ram-up. - * Do not add jitter since this is already covered by LL. - */ - end_time = NRF_TIMER0->CC[0] + BLE_PHY_T_RXENFAST + wfr_usecs; - } - - /* - * Note: on LE Coded EVENT_ADDRESS is fired after TERM1 is received, so - * we are actually calculating relative to start of packet payload - * which is fine. - */ - - /* Adjust for receiving access address since this triggers EVENT_ADDRESS */ - end_time += ble_phy_mode_pdu_start_off(phy); - /* Adjust for delay between actual access address RX and EVENT_ADDRESS */ - end_time += g_ble_phy_t_rxaddrdelay[phy]; - - /* wfr_secs is the time from rxen until timeout */ - nrf_timer_cc_set(NRF_TIMER0, 3, end_time); - NRF_TIMER0->EVENTS_COMPARE[3] = 0; - - /* Enable wait for response PPI */ - nrf_ppi_channels_enable(NRF_PPI, (PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk)); - - /* - * It may happen that if CPU is halted for a brief moment (e.g. during flash - * erase or write), TIMER0 already counted past CC[3] and thus wfr will not - * fire as expected. In case this happened, let's just disable PPIs for wfr - * and trigger wfr manually (i.e. disable radio). - * - * Note that the same applies to RX start time set in CC[0] but since it - * should fire earlier than wfr, fixing wfr is enough. - * - * CC[1] is only used as a reference on RX start, we do not need it here so - * it can be used to read TIMER0 counter. - */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE1); - if (NRF_TIMER0->CC[1] > NRF_TIMER0->CC[3]) { - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk); - nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); - } -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -static uint32_t -ble_phy_get_ccm_datarate(void) -{ -#if BLE_LL_BT5_PHY_SUPPORTED - switch (g_ble_phy_data.phy_cur_phy_mode) { - case BLE_PHY_MODE_1M: - return CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos; - case BLE_PHY_MODE_2M: - return CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - case BLE_PHY_MODE_CODED_125KBPS: - return CCM_MODE_DATARATE_125Kbps << CCM_MODE_DATARATE_Pos; - case BLE_PHY_MODE_CODED_500KBPS: - return CCM_MODE_DATARATE_500Kbps << CCM_MODE_DATARATE_Pos; -#endif - } - - assert(0); - return 0; -#else - return CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos; -#endif -} -#endif - -/** - * Setup transceiver for receive. - */ -static void -ble_phy_rx_xcvr_setup(void) -{ - uint8_t *dptr; - - dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; - dptr += 3; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (g_ble_phy_data.phy_encrypted) { - NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0]; - NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0]; - NRF_CCM->OUTPTR = (uint32_t)dptr; - NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0]; - NRF_CCM->MODE = CCM_MODE_LENGTH_Msk | CCM_MODE_MODE_Decryption | - ble_phy_get_ccm_datarate(); - NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data; - NRF_CCM->SHORTS = 0; - NRF_CCM->EVENTS_ERROR = 0; - NRF_CCM->EVENTS_ENDCRYPT = 0; - nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH25_Msk); - } else { - NRF_RADIO->PACKETPTR = (uint32_t)dptr; - } -#else - NRF_RADIO->PACKETPTR = (uint32_t)dptr; -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - if (g_ble_phy_data.phy_privacy) { - NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Enabled; - NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; - NRF_AAR->SCRATCHPTR = (uint32_t)&g_ble_phy_data.phy_aar_scratch; - NRF_AAR->EVENTS_END = 0; - NRF_AAR->EVENTS_RESOLVED = 0; - NRF_AAR->EVENTS_NOTRESOLVED = 0; - } else { - if (g_ble_phy_data.phy_encrypted == 0) { - NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Disabled; - } - } -#endif - - /* Turn off trigger TXEN on output compare match and AAR on bcmatch */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk | PPI_CHEN_CH23_Msk); - - /* Reset the rx started flag. Used for the wait for response */ - g_ble_phy_data.phy_rx_started = 0; - g_ble_phy_data.phy_state = BLE_PHY_STATE_RX; - -#if BLE_LL_BT5_PHY_SUPPORTED - /* - * On Coded PHY there are CI and TERM1 fields before PDU starts so we need - * to take this into account when setting up BCC. - */ - if (g_ble_phy_data.phy_cur_phy_mode == BLE_PHY_MODE_CODED_125KBPS || - g_ble_phy_data.phy_cur_phy_mode == BLE_PHY_MODE_CODED_500KBPS) { - g_ble_phy_data.phy_bcc_offset = 5; - } else { - g_ble_phy_data.phy_bcc_offset = 0; - } -#else - g_ble_phy_data.phy_bcc_offset = 0; -#endif - - /* I want to know when 1st byte received (after address) */ - nrf_radio_bcc_set(NRF_RADIO, 8 + g_ble_phy_data.phy_bcc_offset); /* in bits */ - NRF_RADIO->EVENTS_ADDRESS = 0; - NRF_RADIO->EVENTS_DEVMATCH = 0; - NRF_RADIO->EVENTS_BCMATCH = 0; - NRF_RADIO->EVENTS_RSSIEND = 0; - NRF_RADIO->EVENTS_CRCOK = 0; - NRF_RADIO->SHORTS = RADIO_SHORTS_END_DISABLE_Msk | - RADIO_SHORTS_READY_START_Msk | - RADIO_SHORTS_ADDRESS_BCSTART_Msk | - RADIO_SHORTS_ADDRESS_RSSISTART_Msk | - RADIO_SHORTS_DISABLED_RSSISTOP_Msk; - - nrf_radio_int_enable(NRF_RADIO, RADIO_INTENSET_ADDRESS_Msk | - RADIO_INTENSET_DISABLED_Msk); -} - -/** - * Called from interrupt context when the transmit ends - * - */ -static void -ble_phy_tx_end_isr(void) -{ - uint8_t tx_phy_mode; - uint8_t was_encrypted; - uint8_t transition; - uint32_t rx_time; - uint32_t tx_time; - - /* Store PHY on which we've just transmitted smth */ - tx_phy_mode = g_ble_phy_data.phy_cur_phy_mode; - - /* If this transmission was encrypted we need to remember it */ - was_encrypted = g_ble_phy_data.phy_encrypted; - (void)was_encrypted; - - /* Better be in TX state! */ - assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX); - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - /* - * XXX: not sure what to do. We had a HW error during transmission. - * For now I just count a stat but continue on like all is good. - */ - if (was_encrypted) { - if (NRF_CCM->EVENTS_ERROR) { - STATS_INC(ble_phy_stats, tx_hw_err); - NRF_CCM->EVENTS_ERROR = 0; - } - } -#endif - - if (g_ble_phy_data.txend_cb) { - g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg); - } - - transition = g_ble_phy_data.phy_transition; - - if (transition == BLE_PHY_TRANSITION_TX_RX) { -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); -#endif - - /* Packet pointer needs to be reset. */ - ble_phy_rx_xcvr_setup(); - - ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_TXRX, tx_phy_mode, 0); - - /* Schedule RX exactly T_IFS after TX end captured in CC[2] */ - rx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); - /* Adjust for delay between EVENT_END and actual TX end time */ - rx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; - /* Adjust for radio ramp-up */ - rx_time -= BLE_PHY_T_RXENFAST; - /* Start listening a bit earlier due to allowed active clock accuracy */ - rx_time -= 2; - - nrf_timer_cc_set(NRF_TIMER0, 0, rx_time); - NRF_TIMER0->EVENTS_COMPARE[0] = 0; - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); - - ble_phy_fem_enable_lna(); - } else if (transition == BLE_PHY_TRANSITION_TX_TX) { - /* Schedule TX exactly T_IFS after TX end captured in CC[2] */ - tx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); - /* Adjust for delay between EVENT_END and actual TX end time */ - tx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; - /* Adjust for radio ramp-up */ - tx_time -= BLE_PHY_T_TXENFAST; - /* Adjust for delay between EVENT_READY and actual TX start time */ - tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; - - nrf_timer_cc_set(NRF_TIMER0, 0, tx_time); - NRF_TIMER0->EVENTS_COMPARE[0] = 0; - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); - - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); - if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) { - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk); - g_ble_phy_data.phy_transition_late = 1; - } - } else { - /* - * XXX: not sure we need to stop the timer here all the time. Or that - * it should be stopped here. - */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP); - NRF_TIMER0->TASKS_SHUTDOWN = 1; - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | - PPI_CHEN_CH20_Msk | PPI_CHEN_CH31_Msk); - assert(transition == BLE_PHY_TRANSITION_NONE); - } -} - -static inline uint8_t -ble_phy_get_cur_rx_phy_mode(void) -{ - uint8_t phy; - - phy = g_ble_phy_data.phy_cur_phy_mode; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - /* - * For Coded PHY mode can be set to either codings since actual coding is - * set in packet header. However, here we need actual coding of received - * packet as this determines pipeline delays so need to figure this out - * using CI field. - */ - if ((phy == BLE_PHY_MODE_CODED_125KBPS) || - (phy == BLE_PHY_MODE_CODED_500KBPS)) { - phy = NRF_RADIO->PDUSTAT & RADIO_PDUSTAT_CISTAT_Msk ? - BLE_PHY_MODE_CODED_500KBPS : - BLE_PHY_MODE_CODED_125KBPS; - } -#endif - - return phy; -} - -static void -ble_phy_rx_end_isr(void) -{ - int rc; - uint8_t *dptr; - uint8_t crcok; - uint32_t tx_time; - struct ble_mbuf_hdr *ble_hdr; - - /* Disable automatic RXEN */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH21_Msk); - - /* Set RSSI and CRC status flag in header */ - ble_hdr = &g_ble_phy_data.rxhdr; - assert(NRF_RADIO->EVENTS_RSSIEND != 0); - ble_hdr->rxinfo.rssi = (-1 * NRF_RADIO->RSSISAMPLE) + - g_ble_phy_data.rx_pwr_compensation; - - dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; - dptr += 3; - - /* Count PHY crc errors and valid packets */ - crcok = NRF_RADIO->EVENTS_CRCOK; - if (!crcok) { - STATS_INC(ble_phy_stats, rx_crc_err); - } else { - STATS_INC(ble_phy_stats, rx_valid); - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (g_ble_phy_data.phy_encrypted) { - while (NRF_CCM->EVENTS_ENDCRYPT == 0) { - /* Make sure CCM finished */ - }; - - /* Only set MIC failure flag if frame is not zero length */ - if ((dptr[1] != 0) && (NRF_CCM->MICSTATUS == 0)) { - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE; - } - - /* - * XXX: not sure how to deal with this. This should not - * be a MIC failure but we should not hand it up. I guess - * this is just some form of rx error and that is how we - * handle it? For now, just set CRC error flags - */ - if (NRF_CCM->EVENTS_ERROR) { - STATS_INC(ble_phy_stats, rx_hw_err); - ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK; - } - } -#endif - } - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_tx_phy_mode); -#endif - - /* - * Let's schedule TX now and we will just cancel it after processing RXed - * packet if we don't need TX. - * - * We need this to initiate connection in case AUX_CONNECT_REQ was sent on - * LE Coded S8. In this case the time we process RXed packet is roughly the - * same as the limit when we need to have TX scheduled (i.e. TIMER0 and PPI - * armed) so we may simply miss the slot and set the timer in the past. - * - * When TX is scheduled in advance, we may event process packet a bit longer - * during radio ramp-up - this gives us extra 40 usecs which is more than - * enough. - */ - - /* Schedule TX exactly T_IFS after RX end captured in CC[2] */ - tx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); - /* Adjust for delay between actual RX end time and EVENT_END */ - tx_time -= g_ble_phy_t_rxenddelay[ble_hdr->rxinfo.phy_mode]; - /* Adjust for radio ramp-up */ - tx_time -= BLE_PHY_T_TXENFAST; - /* Adjust for delay between EVENT_READY and actual TX start time */ - tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; - - nrf_timer_cc_set(NRF_TIMER0, 0, tx_time); - NRF_TIMER0->EVENTS_COMPARE[0] = 0; - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); - - ble_phy_fem_enable_pa(); - - /* - * XXX: Hack warning! - * - * It may happen (during flash erase) that CPU is stopped for a moment and - * TIMER0 already counted past CC[0]. In such case we will be stuck waiting - * for TX to start since EVENTS_COMPARE[0] will not happen any time soon. - * For now let's set a flag denoting that we are late in RX-TX transition so - * ble_phy_tx() will fail - this allows everything to cleanup nicely without - * the need for extra handling in many places. - * - * Note: CC[3] is used only for wfr which we do not need here. - */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); - if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) { - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk); - g_ble_phy_data.phy_transition_late = 1; - } - - /* - * XXX: This is a horrible ugly hack to deal with the RAM S1 byte - * that is not sent over the air but is present here. Simply move the - * data pointer to deal with it. Fix this later. - */ - dptr[2] = dptr[1]; - dptr[1] = dptr[0]; - rc = ble_ll_rx_end(dptr + 1, ble_hdr); - if (rc < 0) { - ble_phy_disable(); - } -} - -static bool -ble_phy_rx_start_isr(void) -{ - int rc; - uint32_t state; - uint32_t usecs; - uint32_t pdu_usecs; - uint32_t ticks; - struct ble_mbuf_hdr *ble_hdr; - uint8_t *dptr; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - int adva_offset; -#endif - - dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; - - /* Clear events and clear interrupt */ - NRF_RADIO->EVENTS_ADDRESS = 0; - nrf_radio_int_disable(NRF_RADIO, RADIO_INTENCLR_ADDRESS_Msk); - - /* Clear wfr timer channels */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk); - - /* Initialize the ble mbuf header */ - ble_hdr = &g_ble_phy_data.rxhdr; - ble_hdr->rxinfo.flags = ble_ll_state_get(); - ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan; - ble_hdr->rxinfo.handle = 0; - ble_hdr->rxinfo.phy = ble_phy_get_cur_phy(); - ble_hdr->rxinfo.phy_mode = ble_phy_get_cur_rx_phy_mode(); -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - ble_hdr->rxinfo.user_data = NULL; -#endif - - /* - * Calculate accurate packets start time (with remainder) - * - * We may start receiving packet somewhere during preamble in which case - * it is possible that actual transmission started before TIMER0 was - * running - need to take this into account. - */ - ble_hdr->beg_cputime = g_ble_phy_data.phy_start_cputime; - - usecs = NRF_TIMER0->CC[1]; - pdu_usecs = ble_phy_mode_pdu_start_off(ble_hdr->rxinfo.phy_mode) + - g_ble_phy_t_rxaddrdelay[ble_hdr->rxinfo.phy_mode]; - if (usecs < pdu_usecs) { - g_ble_phy_data.phy_start_cputime--; - usecs += 30; - } - usecs -= pdu_usecs; - - ticks = os_cputime_usecs_to_ticks(usecs); - usecs -= os_cputime_ticks_to_usecs(ticks); - if (usecs == 31) { - usecs = 0; - ++ticks; - } - - ble_hdr->beg_cputime += ticks; - ble_hdr->rem_usecs = usecs; - - /* XXX: I wonder if we always have the 1st byte. If we need to wait for - * rx chain delay, it could be 18 usecs from address interrupt. The - nrf52 may be able to get here early. */ - /* Wait to get 1st byte of frame */ - while (1) { - state = NRF_RADIO->STATE; - if (NRF_RADIO->EVENTS_BCMATCH != 0) { - break; - } - - /* - * If state is disabled, we should have the BCMATCH. If not, - * something is wrong! - */ - if (state == RADIO_STATE_STATE_Disabled) { - nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); - NRF_RADIO->SHORTS = 0; - return false; - } - -#if BABBLESIM - tm_tick(); -#endif - } - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - /* - * If privacy is enabled and received PDU has TxAdd bit set (i.e. random - * address) we try to resolve address using AAR. - */ - if (g_ble_phy_data.phy_privacy && (dptr[3] & 0x40)) { - /* - * AdvA is located at 4th octet in RX buffer (after S0, length an S1 - * fields). In case of extended advertising PDU we need to add 2 more - * octets for extended header. - */ - adva_offset = (dptr[3] & 0x0f) == 0x07 ? 2 : 0; - NRF_AAR->ADDRPTR = (uint32_t)(dptr + 3 + adva_offset); - - /* Trigger AAR after last bit of AdvA is received */ - NRF_RADIO->EVENTS_BCMATCH = 0; - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH23_Msk); - nrf_radio_bcc_set(NRF_RADIO, (BLE_LL_PDU_HDR_LEN + adva_offset + - BLE_DEV_ADDR_LEN) * 8 + g_ble_phy_data.phy_bcc_offset); - } -#endif - - /* Call Link Layer receive start function */ - rc = ble_ll_rx_start(dptr + 3, - g_ble_phy_data.phy_chan, - &g_ble_phy_data.rxhdr); - if (rc >= 0) { - /* Set rx started flag and enable rx end ISR */ - g_ble_phy_data.phy_rx_started = 1; - } else { - /* Disable PHY */ - ble_phy_disable(); - STATS_INC(ble_phy_stats, rx_aborts); - } - - /* Count rx starts */ - STATS_INC(ble_phy_stats, rx_starts); - - return true; -} - -static void -ble_phy_isr(void) -{ - uint32_t irq_en; - - os_trace_isr_enter(); - - /* Read irq register to determine which interrupts are enabled */ - irq_en = NRF_RADIO->INTENSET; - - /* - * NOTE: order of checking is important! Possible, if things get delayed, - * we have both an ADDRESS and DISABLED interrupt in rx state. If we get - * an address, we disable the DISABLED interrupt. - */ - - /* We get this if we have started to receive a frame */ - if ((irq_en & RADIO_INTENCLR_ADDRESS_Msk) && NRF_RADIO->EVENTS_ADDRESS) { - /* - * wfr timer is calculated to expire at the exact time we should start - * receiving a packet (with 1 usec precision) so it is possible it will - * fire at the same time as EVENT_ADDRESS. If this happens, radio will - * be disabled while we are waiting for EVENT_BCCMATCH after 1st byte - * of payload is received and ble_phy_rx_start_isr() will fail. In this - * case we should not clear DISABLED irq mask so it will be handled as - * regular radio disabled event below. In other case radio was disabled - * on purpose and there's nothing more to handle so we can clear mask. - */ - if (ble_phy_rx_start_isr()) { - irq_en &= ~RADIO_INTENCLR_DISABLED_Msk; - } - } - - /* Handle disabled event. This is enabled for both TX and RX. On RX, we - * need to check phy_rx_started flag to make sure we actually were receiving - * a PDU, otherwise this is due to wfr. - */ - if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && NRF_RADIO->EVENTS_DISABLED) { - BLE_LL_ASSERT(NRF_RADIO->EVENTS_END || - ((g_ble_phy_data.phy_state == BLE_PHY_STATE_RX) && - !g_ble_phy_data.phy_rx_started)); - NRF_RADIO->EVENTS_END = 0; - NRF_RADIO->EVENTS_DISABLED = 0; - nrf_radio_int_disable(NRF_RADIO, RADIO_INTENCLR_DISABLED_Msk); - -#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) - g_ble_phy_data.tifs = BLE_LL_IFS; -#endif - - switch (g_ble_phy_data.phy_state) { - case BLE_PHY_STATE_RX: -#if MYNEWT_VAL(BLE_LL_FEM_LNA) - NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; - ble_ll_fem_lna_disable(); -#endif - if (g_ble_phy_data.phy_rx_started) { - ble_phy_rx_end_isr(); - } else { - ble_ll_wfr_timer_exp(NULL); - } - break; - case BLE_PHY_STATE_TX: -#if MYNEWT_VAL(BLE_LL_FEM_PA) - NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; - ble_ll_fem_pa_disable(); -#endif - ble_phy_tx_end_isr(); - break; - default: - BLE_LL_ASSERT(0); - } - } - - g_ble_phy_data.phy_transition_late = 0; - - /* Count # of interrupts */ - STATS_INC(ble_phy_stats, phy_isrs); - - os_trace_isr_exit(); -} - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 || \ - MYNEWT_VAL(BLE_LL_FEM_PA) || \ - MYNEWT_VAL(BLE_LL_FEM_LNA) -static int -ble_phy_gpiote_configure(int pin) -{ - NRF_GPIO_Type *port; - - g_ble_phy_gpiote_idx--; - -#if NRF52840_XXAA - port = pin > 31 ? NRF_P1 : NRF_P0; - pin &= 0x1f; -#else - port = NRF_P0; -#endif - - /* Configure GPIO directly to avoid dependency to hal_gpio (for porting) */ - port->DIRSET = (1 << pin); - port->OUTCLR = (1 << pin); - - NRF_GPIOTE->CONFIG[g_ble_phy_gpiote_idx] = - (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | - ((pin & 0x1F) << GPIOTE_CONFIG_PSEL_Pos) | -#if NRF52840_XXAA - ((port == NRF_P1) << GPIOTE_CONFIG_PORT_Pos); -#else - 0; -#endif - - BLE_LL_ASSERT(g_ble_phy_gpiote_idx >= 0); - - return g_ble_phy_gpiote_idx; -} -#endif - -static void -ble_phy_dbg_time_setup(void) -{ - int idx __attribute__((unused)); - - /* - * We setup GPIOTE starting from last configuration index to minimize risk - * of conflict with GPIO setup via hal. It's not great solution, but since - * this is just debugging code we can live with this. - */ - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 - idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); - - nrf_ppi_channel_endpoint_setup(NRF_PPI, 17, (uint32_t)&(NRF_RADIO->EVENTS_READY), - (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH17_Msk); - - /* CH[20] and PPI CH[21] are on to trigger TASKS_TXEN or TASKS_RXEN */ - nrf_ppi_fork_endpoint_setup(NRF_PPI, 20, (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); - nrf_ppi_fork_endpoint_setup(NRF_PPI, 21, (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); -#endif - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 - idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); - - /* CH[26] and CH[27] are always on for EVENT_ADDRESS and EVENT_END */ - nrf_ppi_fork_endpoint_setup(NRF_PPI, 26, (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); - nrf_ppi_fork_endpoint_setup(NRF_PPI, 27, (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); -#endif - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 - idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); - -#if NRF52840_XXAA - nrf_ppi_channel_endpoint_setup(NRF_PPI, 18, (uint32_t)&(NRF_RADIO->EVENTS_RXREADY), - (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); -#else - nrf_ppi_channel_endpoint_setup(NRF_PPI, 18, (uint32_t)&(NRF_RADIO->EVENTS_READY), - (uint32_t)&(NRF_GPIOTE->TASKS_SET[idx])); -#endif - nrf_ppi_channel_endpoint_setup(NRF_PPI, 19, (uint32_t)&(NRF_RADIO->EVENTS_DISABLED), - (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH18_Msk | PPI_CHEN_CH19_Msk); - - /* CH[4] and CH[5] are always on for wfr */ - nrf_ppi_fork_endpoint_setup(NRF_PPI, 4, (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); - nrf_ppi_fork_endpoint_setup(NRF_PPI, 5, (uint32_t)&(NRF_GPIOTE->TASKS_CLR[idx])); -#endif -} - -/** - * ble phy init - * - * Initialize the PHY. - * - * @return int 0: success; PHY error code otherwise - */ -int -ble_phy_init(void) -{ - int rc; - - g_ble_phy_gpiote_idx = 8; - - /* Default phy to use is 1M */ - g_ble_phy_data.phy_cur_phy_mode = BLE_PHY_MODE_1M; - g_ble_phy_data.phy_tx_phy_mode = BLE_PHY_MODE_1M; - g_ble_phy_data.phy_rx_phy_mode = BLE_PHY_MODE_1M; - - g_ble_phy_data.rx_pwr_compensation = 0; - - /* Set phy channel to an invalid channel so first set channel works */ - g_ble_phy_data.phy_chan = BLE_PHY_NUM_CHANS; - -#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) - g_ble_phy_data.tifs = BLE_LL_IFS; -#endif - - /* Toggle peripheral power to reset (just in case) */ - nrf_radio_power_set(NRF_RADIO, false); - nrf_radio_power_set(NRF_RADIO, true); - - /* Disable all interrupts */ - nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); - - /* Set configuration registers */ - NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit; - NRF_RADIO->PCNF0 = NRF_PCNF0; - - /* XXX: should maxlen be 251 for encryption? */ - NRF_RADIO->PCNF1 = NRF_MAXLEN | - (RADIO_PCNF1_ENDIAN_Little << RADIO_PCNF1_ENDIAN_Pos) | - (NRF_BALEN << RADIO_PCNF1_BALEN_Pos) | - RADIO_PCNF1_WHITEEN_Msk; - - /* Enable radio fast ramp-up */ - NRF_RADIO->MODECNF0 |= (RADIO_MODECNF0_RU_Fast << RADIO_MODECNF0_RU_Pos) & - RADIO_MODECNF0_RU_Msk; - - /* Set logical address 1 for TX and RX */ - NRF_RADIO->TXADDRESS = 0; - NRF_RADIO->RXADDRESSES = (1 << 0); - - /* Configure the CRC registers */ - NRF_RADIO->CRCCNF = (RADIO_CRCCNF_SKIPADDR_Skip << RADIO_CRCCNF_SKIPADDR_Pos) | RADIO_CRCCNF_LEN_Three; - - /* Configure BLE poly */ - NRF_RADIO->CRCPOLY = 0x0000065B; - - /* Configure IFS */ - NRF_RADIO->TIFS = BLE_LL_IFS; - - /* Captures tx/rx start in timer0 cc 1 and tx/rx end in timer0 cc 2 */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH26_Msk | PPI_CHEN_CH27_Msk); - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - nrf_ccm_int_disable(NRF_CCM, 0xffffffff); - NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; - NRF_CCM->EVENTS_ERROR = 0; - memset(g_nrf_encrypt_scratchpad, 0, sizeof(g_nrf_encrypt_scratchpad)); -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - g_ble_phy_data.phy_aar_scratch = 0; - NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; - nrf_aar_int_disable(NRF_AAR, 0xffffffff); - NRF_AAR->EVENTS_END = 0; - NRF_AAR->EVENTS_RESOLVED = 0; - NRF_AAR->EVENTS_NOTRESOLVED = 0; - NRF_AAR->NIRK = 0; -#endif - - /* TIMER0 setup for PHY when using RTC */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP); - NRF_TIMER0->TASKS_SHUTDOWN = 1; - NRF_TIMER0->BITMODE = 3; /* 32-bit timer */ - NRF_TIMER0->MODE = 0; /* Timer mode */ - NRF_TIMER0->PRESCALER = 4; /* gives us 1 MHz */ - - /* - * PPI setup. - * Channel 4: Captures TIMER0 in CC[3] when EVENTS_ADDRESS occurs. Used - * to cancel the wait for response timer. - * Channel 5: TIMER0 CC[3] to TASKS_DISABLE on radio. This is the wait - * for response timer. - */ - nrf_ppi_channel_endpoint_setup(NRF_PPI, NRF_PPI_CHANNEL4, - (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS), - (uint32_t)&(NRF_TIMER0->TASKS_CAPTURE[3])); - nrf_ppi_channel_endpoint_setup(NRF_PPI, NRF_PPI_CHANNEL5, - (uint32_t)&(NRF_TIMER0->EVENTS_COMPARE[3]), - (uint32_t)&(NRF_RADIO->TASKS_DISABLE)); - -#if MYNEWT_VAL(BLE_LL_FEM_PA) || MYNEWT_VAL(BLE_LL_FEM_LNA) -#if FEM_SINGLE_GPIO - fem_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); - NRF_PPI->CH[6].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_SET[fem_idx]); - NRF_PPI->CH[7].TEP = (uint32_t) &(NRF_GPIOTE->TASKS_CLR[fem_idx]); -#else -#if MYNEWT_VAL(BLE_LL_FEM_PA) - fem_pa_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); - NRF_GPIOTE->TASKS_CLR[fem_pa_idx] = 1; -#endif -#if MYNEWT_VAL(BLE_LL_FEM_LNA) - fem_lna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)); - NRF_GPIOTE->TASKS_CLR[fem_lna_idx] = 1; -#endif -#endif - - NRF_PPI->CH[6].EEP = (uint32_t)&(NRF_RADIO->EVENTS_READY); - NRF_PPI->CH[7].EEP = (uint32_t)&(NRF_RADIO->EVENTS_DISABLED); - NRF_PPI->CHENCLR = PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk; -#endif - - /* Set isr in vector table and enable interrupt */ -#ifndef RIOT_VERSION - NVIC_SetPriority(RADIO_IRQn, 0); -#endif -#if MYNEWT - NVIC_SetVector(RADIO_IRQn, (uint32_t)ble_phy_isr); -#else - ble_npl_hw_set_isr(RADIO_IRQn, ble_phy_isr); -#endif - NVIC_EnableIRQ(RADIO_IRQn); - - /* Register phy statistics */ - if (!g_ble_phy_data.phy_stats_initialized) { - rc = stats_init_and_reg(STATS_HDR(ble_phy_stats), - STATS_SIZE_INIT_PARMS(ble_phy_stats, - STATS_SIZE_32), - STATS_NAME_INIT_PARMS(ble_phy_stats), - "ble_phy"); - assert(rc == 0); - - g_ble_phy_data.phy_stats_initialized = 1; - } - - ble_phy_dbg_time_setup(); - - return 0; -} - -/** - * Puts the phy into receive mode. - * - * @return int 0: success; BLE Phy error code otherwise - */ -int -ble_phy_rx(void) -{ - /* - * Check radio state. - * - * In case radio is now disabling we'll wait for it to finish, but if for - * any reason it's just in idle state we proceed with RX as usual since - * nRF52 radio can ramp-up from idle state as well. - * - * Note that TX and RX states values are the same except for 3rd bit so we - * can make a shortcut here when checking for idle state. - */ - nrf_wait_disabled(); - if ((NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) && - ((NRF_RADIO->STATE & 0x07) != RADIO_STATE_STATE_RxIdle)) { - ble_phy_disable(); - STATS_INC(ble_phy_stats, radio_state_errs); - return BLE_PHY_ERR_RADIO_STATE; - } - - /* Make sure all interrupts are disabled */ - nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); - - /* Clear events prior to enabling receive */ - NRF_RADIO->EVENTS_END = 0; - NRF_RADIO->EVENTS_DISABLED = 0; - - /* Setup for rx */ - ble_phy_rx_xcvr_setup(); - - /* PPI to start radio automatically shall be set here */ - assert(NRF_PPI->CHEN & PPI_CHEN_CH21_Msk); - - return 0; -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -/** - * Called to enable encryption at the PHY. Note that this state will persist - * in the PHY; in other words, if you call this function you have to call - * disable so that future PHY transmits/receives will not be encrypted. - * - * @param pkt_counter - * @param iv - * @param key - * @param is_master - */ -void -ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key, - uint8_t is_master) -{ - memcpy(g_nrf_ccm_data.key, key, 16); - g_nrf_ccm_data.pkt_counter = pkt_counter; - memcpy(g_nrf_ccm_data.iv, iv, 8); - g_nrf_ccm_data.dir_bit = is_master; - g_ble_phy_data.phy_encrypted = 1; - /* Enable the module (AAR cannot be on while CCM on) */ - NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Disabled; - NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled; -} - -void -ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir) -{ - g_nrf_ccm_data.pkt_counter = pkt_counter; - g_nrf_ccm_data.dir_bit = dir; -} - -void -ble_phy_encrypt_disable(void) -{ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH25_Msk); - nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_STOP); - NRF_CCM->EVENTS_ERROR = 0; - NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled; - - g_ble_phy_data.phy_encrypted = 0; -} -#endif - -void -ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb, void *arg) -{ - /* Set transmit end callback and arg */ - g_ble_phy_data.txend_cb = txend_cb; - g_ble_phy_data.txend_arg = arg; -} - -/** - * Called to set the start time of a transmission. - * - * This function is called to set the start time when we are not going from - * rx to tx automatically. - * - * NOTE: care must be taken when calling this function. The channel should - * already be set. - * - * @param cputime This is the tick at which the 1st bit of the preamble - * should be transmitted - * @param rem_usecs This is used only when the underlying timing uses a 32.768 - * kHz crystal. It is the # of usecs from the cputime tick - * at which the first bit of the preamble should be - * transmitted. - * @return int - */ -int -ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) -{ - int rc; - - ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_TX, cputime, rem_usecs); - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_tx_phy_mode); -#endif - - /* XXX: This should not be necessary, but paranoia is good! */ - /* Clear timer0 compare to RXEN since we are transmitting */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH21_Msk); - - if (ble_phy_set_start_time(cputime, rem_usecs, true) != 0) { - STATS_INC(ble_phy_stats, tx_late); - ble_phy_disable(); - rc = BLE_PHY_ERR_TX_LATE; - } else { - /* Enable PPI to automatically start TXEN */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH20_Msk); - rc = 0; - - ble_phy_fem_enable_pa(); - } - - return rc; -} - -/** - * Called to set the start time of a reception - * - * This function acts a bit differently than transmit. If we are late getting - * here we will still attempt to receive. - * - * NOTE: care must be taken when calling this function. The channel should - * already be set. - * - * @param cputime - * - * @return int - */ -int -ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) -{ - bool late = false; - int rc = 0; - - ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_RX, cputime, rem_usecs); - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); -#endif - - /* XXX: This should not be necessary, but paranoia is good! */ - /* Clear timer0 compare to TXEN since we are transmitting */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH20_Msk); - - if (ble_phy_set_start_time(cputime, rem_usecs, false) != 0) { - STATS_INC(ble_phy_stats, rx_late); - - /* We're late so let's just try to start RX as soon as possible */ - ble_phy_set_start_now(); - - late = true; - } - - /* Enable PPI to automatically start RXEN */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); - - ble_phy_fem_enable_lna(); - - /* Start rx */ - rc = ble_phy_rx(); - - /* - * If we enabled receiver but were late, let's return proper error code so - * caller can handle this. - */ - if (!rc && late) { - rc = BLE_PHY_ERR_RX_LATE; - } - - return rc; -} - -int -ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) -{ - int rc; - uint8_t *dptr; - uint8_t *pktptr; - uint8_t payload_len; - uint8_t hdr_byte; - uint32_t state; - uint32_t shortcuts; - - if (g_ble_phy_data.phy_transition_late) { - ble_phy_disable(); - STATS_INC(ble_phy_stats, tx_late); - return BLE_PHY_ERR_TX_LATE; - } - - /* - * This check is to make sure that the radio is not in a state where - * it is moving to disabled state. If so, let it get there. - */ - nrf_wait_disabled(); - - /* - * XXX: Although we may not have to do this here, I clear all the PPI - * that should not be used when transmitting. Some of them are only enabled - * if encryption and/or privacy is on, but I dont care. Better to be - * paranoid, and if you are going to clear one, might as well clear them - * all. - */ - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | - PPI_CHEN_CH23_Msk | PPI_CHEN_CH25_Msk); - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (g_ble_phy_data.phy_encrypted) { - dptr = (uint8_t *)&g_ble_phy_enc_buf[0]; - pktptr = (uint8_t *)&g_ble_phy_tx_buf[0]; - NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; - NRF_CCM->INPTR = (uint32_t)dptr; - NRF_CCM->OUTPTR = (uint32_t)pktptr; - NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0]; - NRF_CCM->EVENTS_ERROR = 0; - NRF_CCM->MODE = CCM_MODE_LENGTH_Msk | ble_phy_get_ccm_datarate(); - NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data; - } else { -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; -#endif - dptr = (uint8_t *)&g_ble_phy_tx_buf[0]; - pktptr = dptr; - } -#else - dptr = (uint8_t *)&g_ble_phy_tx_buf[0]; - pktptr = dptr; -#endif - - /* Set PDU payload */ - payload_len = pducb(&dptr[3], pducb_arg, &hdr_byte); - - /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */ - dptr[0] = hdr_byte; - dptr[1] = payload_len; - dptr[2] = 0; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - /* Start key-stream generation and encryption (via short) */ - if (g_ble_phy_data.phy_encrypted) { - nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); - } -#endif - - NRF_RADIO->PACKETPTR = (uint32_t)pktptr; - - /* Clear the ready, end and disabled events */ - NRF_RADIO->EVENTS_READY = 0; - NRF_RADIO->EVENTS_END = 0; - NRF_RADIO->EVENTS_DISABLED = 0; - - /* Enable shortcuts for transmit start/end. */ - shortcuts = RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_READY_START_Msk; - NRF_RADIO->SHORTS = shortcuts; - nrf_radio_int_enable(NRF_RADIO, RADIO_INTENSET_DISABLED_Msk); - - /* Set the PHY transition */ - g_ble_phy_data.phy_transition = end_trans; - - /* Set transmitted payload length */ - g_ble_phy_data.phy_tx_pyld_len = payload_len; - - /* If we already started transmitting, abort it! */ - state = NRF_RADIO->STATE; - if (state != RADIO_STATE_STATE_Tx) { - /* Set phy state to transmitting and count packet statistics */ - g_ble_phy_data.phy_state = BLE_PHY_STATE_TX; - STATS_INC(ble_phy_stats, tx_good); - STATS_INCN(ble_phy_stats, tx_bytes, payload_len + BLE_LL_PDU_HDR_LEN); - rc = BLE_ERR_SUCCESS; - } else { - ble_phy_disable(); - STATS_INC(ble_phy_stats, tx_late); - rc = BLE_PHY_ERR_RADIO_STATE; - } - - return rc; -} - -/** - * ble phy txpwr set - * - * Set the transmit output power (in dBm). - * - * NOTE: If the output power specified is within the BLE limits but outside - * the chip limits, we "rail" the power level so we dont exceed the min/max - * chip values. - * - * @param dbm Power output in dBm. - * - * @return int 0: success; anything else is an error - */ -int -ble_phy_txpwr_set(int dbm) -{ - /* "Rail" power level if outside supported range */ - dbm = ble_phy_txpower_round(dbm); - - NRF_RADIO->TXPOWER = dbm; - g_ble_phy_data.phy_txpwr_dbm = dbm; - - return 0; -} - -/** - * ble phy txpwr round - * - * Get the rounded transmit output power (in dBm). - * - * @param dbm Power output in dBm. - * - * @return int Rounded power in dBm - */ -int ble_phy_txpower_round(int dbm) -{ - /* TODO this should be per nRF52XXX */ - - /* "Rail" power level if outside supported range */ - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos4dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Pos4dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_0dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_0dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm; - } - - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm; -} - -/** - * ble phy set access addr - * - * Set access address. - * - * @param access_addr Access address - * - * @return int 0: success; PHY error code otherwise - */ -static int -ble_phy_set_access_addr(uint32_t access_addr) -{ - NRF_RADIO->BASE0 = (access_addr << 8); - NRF_RADIO->PREFIX0 = (NRF_RADIO->PREFIX0 & 0xFFFFFF00) | (access_addr >> 24); - - g_ble_phy_data.phy_access_address = access_addr; - -#ifndef BABBLESIM - ble_phy_apply_errata_102_106_107(); -#endif - return 0; -} - -/** - * ble phy txpwr get - * - * Get the transmit power. - * - * @return int The current PHY transmit power, in dBm - */ -int -ble_phy_txpwr_get(void) -{ - return g_ble_phy_data.phy_txpwr_dbm; -} - -void -ble_phy_set_rx_pwr_compensation(int8_t compensation) -{ - g_ble_phy_data.rx_pwr_compensation = compensation; -} - -/** - * ble phy setchan - * - * Sets the logical frequency of the transceiver. The input parameter is the - * BLE channel index (0 to 39, inclusive). The NRF frequency register works like - * this: logical frequency = 2400 + FREQ (MHz). - * - * Thus, to get a logical frequency of 2402 MHz, you would program the - * FREQUENCY register to 2. - * - * @param chan This is the Data Channel Index or Advertising Channel index - * - * @return int 0: success; PHY error code otherwise - */ -int -ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit) -{ - assert(chan < BLE_PHY_NUM_CHANS); - - /* Check for valid channel range */ - if (chan >= BLE_PHY_NUM_CHANS) { - return BLE_PHY_ERR_INV_PARAM; - } - - /* Set current access address */ - ble_phy_set_access_addr(access_addr); - - /* Configure crcinit */ - NRF_RADIO->CRCINIT = crcinit; - - /* Set the frequency and the data whitening initial value */ - g_ble_phy_data.phy_chan = chan; - NRF_RADIO->FREQUENCY = g_ble_phy_chan_freq[chan]; - NRF_RADIO->DATAWHITEIV = chan; - - return 0; -} - -/** - * Stop the timer used to count microseconds when using RTC for cputime - */ -static void -ble_phy_stop_usec_timer(void) -{ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_STOP); - NRF_TIMER0->TASKS_SHUTDOWN = 1; - nrf_rtc_event_disable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); -} - -/** - * ble phy disable irq and ppi - * - * This routine is to be called when reception was stopped due to either a - * wait for response timeout or a packet being received and the phy is to be - * restarted in receive mode. Generally, the disable routine is called to stop - * the phy. - */ -static void -ble_phy_disable_irq_and_ppi(void) -{ - nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_IRQ_MASK_ALL); - NRF_RADIO->SHORTS = 0; - nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk | - PPI_CHEN_CH20_Msk | PPI_CHEN_CH21_Msk | PPI_CHEN_CH23_Msk | - PPI_CHEN_CH25_Msk | PPI_CHEN_CH31_Msk); - nrf_ppi_channels_disable(NRF_PPI, PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk); - NVIC_ClearPendingIRQ(RADIO_IRQn); - g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE; -} - -void -ble_phy_restart_rx(void) -{ - ble_phy_stop_usec_timer(); - ble_phy_disable_irq_and_ppi(); - - ble_phy_set_start_now(); - /* Enable PPI to automatically start RXEN */ - nrf_ppi_channels_enable(NRF_PPI, PPI_CHEN_CH21_Msk); - - ble_phy_rx(); -} - -/** - * ble phy disable - * - * Disables the PHY. This should be called when an event is over. It stops - * the usec timer (if used), disables interrupts, disables the RADIO, disables - * PPI and sets state to idle. - */ -void -ble_phy_disable(void) -{ - ble_phy_trace_void(BLE_PHY_TRACE_ID_DISABLE); - - ble_phy_stop_usec_timer(); - ble_phy_disable_irq_and_ppi(); -} - -/* Gets the current access address */ -uint32_t ble_phy_access_addr_get(void) -{ - return g_ble_phy_data.phy_access_address; -} - -/** - * Return the phy state - * - * @return int The current PHY state. - */ -int -ble_phy_state_get(void) -{ - return g_ble_phy_data.phy_state; -} - -/** - * Called to see if a reception has started - * - * @return int - */ -int -ble_phy_rx_started(void) -{ - return g_ble_phy_data.phy_rx_started; -} - -/** - * Return the transceiver state - * - * @return int transceiver state. - */ -uint8_t -ble_phy_xcvr_state_get(void) -{ - uint32_t state; - state = NRF_RADIO->STATE; - return (uint8_t)state; -} - -/** - * Called to return the maximum data pdu payload length supported by the - * phy. For this chip, if encryption is enabled, the maximum payload is 27 - * bytes. - * - * @return uint8_t Maximum data channel PDU payload size supported - */ -uint8_t -ble_phy_max_data_pdu_pyld(void) -{ - return BLE_LL_DATA_PDU_MAX_PYLD; -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) -void -ble_phy_resolv_list_enable(void) -{ - NRF_AAR->NIRK = (uint32_t)g_nrf_num_irks; - g_ble_phy_data.phy_privacy = 1; -} - -void -ble_phy_resolv_list_disable(void) -{ - g_ble_phy_data.phy_privacy = 0; -} -#endif - -#if MYNEWT_VAL(BLE_LL_DTM) -void ble_phy_enable_dtm(void) -{ - /* When DTM is enabled we need to disable whitening as per - * Bluetooth v5.0 Vol 6. Part F. 4.1.1 - */ - NRF_RADIO->PCNF1 &= ~RADIO_PCNF1_WHITEEN_Msk; -} - -void ble_phy_disable_dtm(void) -{ - /* Enable whitening */ - NRF_RADIO->PCNF1 |= RADIO_PCNF1_WHITEEN_Msk; -} -#endif - -void -ble_phy_rfclk_enable(void) -{ -#if MYNEWT || defined(RIOT_VERSION) - nrf52_clock_hfxo_request(); -#else - nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART); -#endif -} - -void -ble_phy_rfclk_disable(void) -{ -#if MYNEWT || defined(RIOT_VERSION) - nrf52_clock_hfxo_release(); -#else - nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); -#endif -} diff --git a/nimble/drivers/nrf52/src/ble_phy_trace.c b/nimble/drivers/nrf52/src/ble_phy_trace.c deleted file mode 100644 index 93b2eb3263..0000000000 --- a/nimble/drivers/nrf52/src/ble_phy_trace.c +++ /dev/null @@ -1,44 +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. - */ - -#include -#include "syscfg/syscfg.h" -#include "os/os_trace_api.h" - -#if MYNEWT_VAL(BLE_PHY_SYSVIEW) - -static os_trace_module_t g_ble_phy_trace_mod; -uint32_t ble_phy_trace_off; - -static void -ble_phy_trace_module_send_desc(void) -{ - os_trace_module_desc(&g_ble_phy_trace_mod, "0 phy_set_tx cputime=%u usecs=%u"); - os_trace_module_desc(&g_ble_phy_trace_mod, "1 phy_set_rx cputime=%u usecs=%u"); - os_trace_module_desc(&g_ble_phy_trace_mod, "2 phy_disable"); -} - -void -ble_phy_trace_init(void) -{ - ble_phy_trace_off = - os_trace_module_register(&g_ble_phy_trace_mod, "ble_phy", 3, - ble_phy_trace_module_send_desc); -} -#endif diff --git a/nimble/drivers/nrf52/syscfg.yml b/nimble/drivers/nrf52/syscfg.yml deleted file mode 100644 index c3ef5ae1d1..0000000000 --- a/nimble/drivers/nrf52/syscfg.yml +++ /dev/null @@ -1,81 +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. -# - -syscfg.defs: - BLE_PHY_VARIABLE_TIFS: - description: > - Enables API to set custom T_ifs (inter-frame spacing) for each - transition. T_ifs is reset to default value after each transition. - When disabled, 150us is always used which enables some build-time - optimizations by compiler. - experimental: 1 - value: 0 - - BLE_PHY_SYSVIEW: - description: > - Enable SystemView tracing module for radio driver. - value: 0 - - BLE_PHY_DBG_TIME_TXRXEN_READY_PIN: - description: > - When set to proper GPIO pin number, this pin will be set - to high state when radio is enabled using PPI channels - 20 or 21 and back to low state on radio EVENTS_READY. - This can be used to measure radio ram-up time. - value: -1 - - BLE_PHY_DBG_TIME_ADDRESS_END_PIN: - description: > - When set to proper GPIO pin number, this pin will be set - to high state on radio EVENTS_ADDRESS and back to low state - on radio EVENTS_END. - This can be used to measure radio pipeline delays. - value: -1 - - BLE_PHY_DBG_TIME_WFR_PIN: - description: > - When set to proper GPIO pin number, this pin will be set - to high state on radio EVENTS_RXREADY and back to low - state when wfr timer expires. - This can be used to check if wfr is calculated properly. - value: -1 - - BLE_PHY_NRF52840_ERRATA_164: - description: > - Enable workaround for anomaly 164 found in nRF52840. - "[164] RADIO: Low selectivity in long range mode" - This shall be only enabled for: - - nRF52840 Engineering A - value: 0 - - BLE_PHY_NRF52840_ERRATA_191: - description: > - Enable workaround for anomaly 191 found in nRF52840. - "[191] RADIO: High packet error rate in BLE Long Range mode" - This shall be only enabled for: - - nRF52840 Engineering B - - nRF52840 Engineering C - - nRF52840 Rev 1 (final silicon) - value: 1 - - BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR: - description: > - Ublox BMD-345 modules come with public address preprogrammed - in UICR register. If enabled public address will be read from - custom UICR instead of FICR register. - value: 0 diff --git a/nimble/drivers/nrf5340/include/ble/xcvr.h b/nimble/drivers/nrf5340/include/ble/xcvr.h deleted file mode 100644 index df6ef700d3..0000000000 --- a/nimble/drivers/nrf5340/include/ble/xcvr.h +++ /dev/null @@ -1,50 +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_BLE_XCVR_ -#define H_BLE_XCVR_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define XCVR_RX_RADIO_RAMPUP_USECS (40) -#define XCVR_TX_RADIO_RAMPUP_USECS (40) - -/* - * NOTE: we have to account for the RTC output compare issue. We want it to be - * 5 ticks. - */ -#define XCVR_PROC_DELAY_USECS (153) -#define XCVR_RX_START_DELAY_USECS (XCVR_RX_RADIO_RAMPUP_USECS) -#define XCVR_TX_START_DELAY_USECS (XCVR_TX_RADIO_RAMPUP_USECS) -#define XCVR_TX_SCHED_DELAY_USECS (XCVR_TX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS) -#define XCVR_RX_SCHED_DELAY_USECS (XCVR_RX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS) - -/* - * Define HW whitelist size. This is the total possible whitelist size; - * not necessarily the size that will be used (may be smaller) - */ -#define BLE_HW_WHITE_LIST_SIZE (8) - -#ifdef __cplusplus -} -#endif - -#endif /* H_BLE_XCVR_ */ diff --git a/nimble/drivers/nrf5340/pkg.yml b/nimble/drivers/nrf5340/pkg.yml index 3ff442120b..794697e9b0 100644 --- a/nimble/drivers/nrf5340/pkg.yml +++ b/nimble/drivers/nrf5340/pkg.yml @@ -18,14 +18,5 @@ # pkg.name: nimble/drivers/nrf5340 -pkg.description: BLE driver for nRF5340 systems. -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth - -pkg.apis: ble_driver -pkg.deps: - - nimble - - nimble/controller +pkg.type: transient +pkg.link: "@apache-mynewt-nimble/nimble/drivers/nrf5x" diff --git a/nimble/drivers/nrf5340/src/ble_hw.c b/nimble/drivers/nrf5340/src/ble_hw.c deleted file mode 100644 index e578fd05d2..0000000000 --- a/nimble/drivers/nrf5340/src/ble_hw.c +++ /dev/null @@ -1,477 +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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* Total number of resolving list elements */ -#define BLE_HW_RESOLV_LIST_SIZE (16) - -/* We use this to keep track of which entries are set to valid addresses */ -static uint8_t g_ble_hw_whitelist_mask; - -/* Random number generator isr callback */ -static ble_rng_isr_cb_t ble_rng_isr_cb; - -/* If LL privacy is enabled, allocate memory for AAR */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - -/* The NRF5340 supports up to 16 IRK entries */ -#if (MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE) < 16) -#define NRF_IRK_LIST_ENTRIES (MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE)) -#else -#define NRF_IRK_LIST_ENTRIES (16) -#endif - -/* NOTE: each entry is 16 bytes long. */ -uint32_t g_nrf_irk_list[NRF_IRK_LIST_ENTRIES * 4]; - -/* Current number of IRK entries */ -uint8_t g_nrf_num_irks; - -#endif - -/* Returns public device address or -1 if not present */ -int -ble_hw_get_public_addr(ble_addr_t *addr) -{ - uint32_t addr_high; - uint32_t addr_low; - - /* Does FICR have a public address */ - if ((NRF_FICR_NS->DEVICEADDRTYPE & 1) != 0) { - return -1; - } - - /* Copy into device address. We can do this because we know platform */ - addr_low = NRF_FICR_NS->DEVICEADDR[0]; - addr_high = NRF_FICR_NS->DEVICEADDR[1]; - memcpy(addr->val, &addr_low, 4); - memcpy(&addr->val[4], &addr_high, 2); - addr->type = BLE_ADDR_PUBLIC; - - return 0; -} - -/* Returns random static address or -1 if not present */ -int -ble_hw_get_static_addr(ble_addr_t *addr) -{ - uint32_t addr_high; - uint32_t addr_low; - int rc; - - if ((NRF_FICR_NS->DEVICEADDRTYPE & 1) == 1) { - addr_low = NRF_FICR_NS->DEVICEADDR[0]; - addr_high = NRF_FICR_NS->DEVICEADDR[1]; - - memcpy(addr->val, &addr_low, 4); - memcpy(&addr->val[4], &addr_high, 2); - - addr->val[5] |= 0xc0; - addr->type = BLE_ADDR_RANDOM; - rc = 0; - } else { - rc = -1; - } - - return rc; -} - -/** - * Clear the whitelist - * - * @return int - */ -void -ble_hw_whitelist_clear(void) -{ - NRF_RADIO_NS->DACNF = 0; - g_ble_hw_whitelist_mask = 0; -} - -/** - * Add a device to the hw whitelist - * - * @param addr - * @param addr_type - * - * @return int 0: success, BLE error code otherwise - */ -int -ble_hw_whitelist_add(const uint8_t *addr, uint8_t addr_type) -{ - int i; - uint32_t mask; - - /* Find first ununsed device address match element */ - mask = 0x01; - for (i = 0; i < BLE_HW_WHITE_LIST_SIZE; ++i) { - if ((mask & g_ble_hw_whitelist_mask) == 0) { - NRF_RADIO_NS->DAB[i] = get_le32(addr); - NRF_RADIO_NS->DAP[i] = get_le16(addr + 4); - if (addr_type == BLE_ADDR_RANDOM) { - NRF_RADIO_NS->DACNF |= (mask << 8); - } - g_ble_hw_whitelist_mask |= mask; - return BLE_ERR_SUCCESS; - } - mask <<= 1; - } - - return BLE_ERR_MEM_CAPACITY; -} - -/** - * Remove a device from the hw whitelist - * - * @param addr - * @param addr_type - * - */ -void -ble_hw_whitelist_rmv(const uint8_t *addr, uint8_t addr_type) -{ - int i; - uint16_t dap; - uint16_t txadd; - uint32_t dab; - uint32_t mask; - - /* Find first ununsed device address match element */ - dab = get_le32(addr); - dap = get_le16(addr + 4); - txadd = NRF_RADIO_NS->DACNF >> 8; - mask = 0x01; - for (i = 0; i < BLE_HW_WHITE_LIST_SIZE; ++i) { - if (mask & g_ble_hw_whitelist_mask) { - if ((dab == NRF_RADIO_NS->DAB[i]) && (dap == NRF_RADIO_NS->DAP[i])) { - if (addr_type == !!(txadd & mask)) { - break; - } - } - } - mask <<= 1; - } - - if (i < BLE_HW_WHITE_LIST_SIZE) { - g_ble_hw_whitelist_mask &= ~mask; - NRF_RADIO_NS->DACNF &= ~mask; - } -} - -/** - * Returns the size of the whitelist in HW - * - * @return int Number of devices allowed in whitelist - */ -uint8_t -ble_hw_whitelist_size(void) -{ - return BLE_HW_WHITE_LIST_SIZE; -} - -/** - * Enable the whitelisted devices - */ -void -ble_hw_whitelist_enable(void) -{ - /* Enable the configured device addresses */ - NRF_RADIO_NS->DACNF |= g_ble_hw_whitelist_mask; -} - -/** - * Disables the whitelisted devices - */ -void -ble_hw_whitelist_disable(void) -{ - /* Disable all whitelist devices */ - NRF_RADIO_NS->DACNF &= 0x0000ff00; -} - -/** - * Boolean function which returns true ('1') if there is a match on the - * whitelist. - * - * @return int - */ -int -ble_hw_whitelist_match(void) -{ - return NRF_RADIO_NS->EVENTS_DEVMATCH; -} - -/* Encrypt data */ -int -ble_hw_encrypt_block(struct ble_encryption_block *ecb) -{ - int rc; - uint32_t end; - uint32_t err; - - /* Stop ECB */ - NRF_ECB_NS->TASKS_STOPECB = 1; - /* XXX: does task stop clear these counters? Anyway to do this quicker? */ - NRF_ECB_NS->EVENTS_ENDECB = 0; - NRF_ECB_NS->EVENTS_ERRORECB = 0; - NRF_ECB_NS->ECBDATAPTR = (uint32_t)ecb; - - /* Start ECB */ - NRF_ECB_NS->TASKS_STARTECB = 1; - - /* Wait till error or done */ - rc = 0; - while (1) { - end = NRF_ECB_NS->EVENTS_ENDECB; - err = NRF_ECB_NS->EVENTS_ERRORECB; - if (end || err) { - if (err) { - rc = -1; - } - break; - } - } - - return rc; -} - -/** - * Random number generator ISR. - */ -static void -ble_rng_isr(void) -{ - uint8_t rnum; - - os_trace_isr_enter(); - - /* No callback? Clear and disable interrupts */ - if (ble_rng_isr_cb == NULL) { - NRF_RNG_NS->INTENCLR = 1; - NRF_RNG_NS->EVENTS_VALRDY = 0; - (void)NRF_RNG_NS->SHORTS; - os_trace_isr_exit(); - return; - } - - /* If there is a value ready grab it */ - if (NRF_RNG_NS->EVENTS_VALRDY) { - NRF_RNG_NS->EVENTS_VALRDY = 0; - rnum = (uint8_t)NRF_RNG_NS->VALUE; - (*ble_rng_isr_cb)(rnum); - } - - os_trace_isr_exit(); -} - -/** - * Initialize the random number generator - * - * @param cb - * @param bias - * - * @return int - */ -int -ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias) -{ - /* Set bias */ - if (bias) { - NRF_RNG_NS->CONFIG = 1; - } else { - NRF_RNG_NS->CONFIG = 0; - } - - /* If we were passed a function pointer we need to enable the interrupt */ - if (cb != NULL) { -#ifndef RIOT_VERSION - NVIC_SetPriority(RNG_IRQn, (1 << __NVIC_PRIO_BITS) - 1); -#endif -#if MYNEWT - NVIC_SetVector(RNG_IRQn, (uint32_t)ble_rng_isr); -#else - ble_npl_hw_set_isr(RNG_IRQn, ble_rng_isr); -#endif - NVIC_EnableIRQ(RNG_IRQn); - ble_rng_isr_cb = cb; - } - - return 0; -} - -/** - * Start the random number generator - * - * @return int - */ -int -ble_hw_rng_start(void) -{ - os_sr_t sr; - - /* No need for interrupt if there is no callback */ - OS_ENTER_CRITICAL(sr); - NRF_RNG_NS->EVENTS_VALRDY = 0; - if (ble_rng_isr_cb) { - NRF_RNG_NS->INTENSET = 1; - } - NRF_RNG_NS->TASKS_START = 1; - OS_EXIT_CRITICAL(sr); - - return 0; -} - -/** - * Stop the random generator - * - * @return int - */ -int -ble_hw_rng_stop(void) -{ - os_sr_t sr; - - /* No need for interrupt if there is no callback */ - OS_ENTER_CRITICAL(sr); - NRF_RNG_NS->INTENCLR = 1; - NRF_RNG_NS->TASKS_STOP = 1; - NRF_RNG_NS->EVENTS_VALRDY = 0; - OS_EXIT_CRITICAL(sr); - - return 0; -} - -/** - * Read the random number generator. - * - * @return uint8_t - */ -uint8_t -ble_hw_rng_read(void) -{ - uint8_t rnum; - - /* Wait for a sample */ - while (NRF_RNG_NS->EVENTS_VALRDY == 0) { - } - - NRF_RNG_NS->EVENTS_VALRDY = 0; - rnum = (uint8_t)NRF_RNG_NS->VALUE; - - return rnum; -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) -/** - * Clear the resolving list - * - * @return int - */ -void -ble_hw_resolv_list_clear(void) -{ - g_nrf_num_irks = 0; -} - -/** - * Add a device to the hw resolving list - * - * @param irk Pointer to IRK to add - * - * @return int 0: success, BLE error code otherwise - */ -int -ble_hw_resolv_list_add(uint8_t *irk) -{ - uint32_t *nrf_entry; - - /* Find first ununsed device address match element */ - if (g_nrf_num_irks == NRF_IRK_LIST_ENTRIES) { - return BLE_ERR_MEM_CAPACITY; - } - - /* Copy into irk list */ - nrf_entry = &g_nrf_irk_list[4 * g_nrf_num_irks]; - memcpy(nrf_entry, irk, 16); - - /* Add to total */ - ++g_nrf_num_irks; - return BLE_ERR_SUCCESS; -} - -/** - * Remove a device from the hw resolving list - * - * @param index Index of IRK to remove - */ -void -ble_hw_resolv_list_rmv(int index) -{ - uint32_t *irk_entry; - - if (index < g_nrf_num_irks) { - --g_nrf_num_irks; - irk_entry = &g_nrf_irk_list[index]; - if (g_nrf_num_irks > index) { - memmove(irk_entry, irk_entry + 4, 16 * (g_nrf_num_irks - index)); - } - } -} - -/** - * Returns the size of the resolving list. NOTE: this returns the maximum - * allowable entries in the HW. Configuration options may limit this. - * - * @return int Number of devices allowed in resolving list - */ -uint8_t -ble_hw_resolv_list_size(void) -{ - return BLE_HW_RESOLV_LIST_SIZE; -} - -/** - * Called to determine if the address received was resolved. - * - * @return int Negative values indicate unresolved address; positive values - * indicate index in resolving list of resolved address. - */ -int -ble_hw_resolv_list_match(void) -{ - if (NRF_AAR_NS->ENABLE && NRF_AAR_NS->EVENTS_END && - NRF_AAR_NS->EVENTS_RESOLVED) { - return (int)NRF_AAR_NS->STATUS; - } - - return -1; -} -#endif diff --git a/nimble/drivers/nrf5340/src/ble_phy.c b/nimble/drivers/nrf5340/src/ble_phy.c deleted file mode 100644 index 76c0289e02..0000000000 --- a/nimble/drivers/nrf5340/src/ble_phy.c +++ /dev/null @@ -1,2079 +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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "controller/ble_ll_fem.h" - -#include -#include -#include -#include -#include - -#define DPPI_CH_PUB(_ch) (((DPPI_CH_ ## _ch) & 0xff) | (1 << 31)) -#define DPPI_CH_SUB(_ch) (((DPPI_CH_ ## _ch) & 0xff) | (1 << 31)) -#define DPPI_CH_UNSUB(_ch) (((DPPI_CH_ ## _ch) & 0xff) | (0 << 31)) -#define DPPI_CH_MASK(_ch) (1 << (DPPI_CH_ ## _ch)) - -/* Channels 0..5 are always used. - * Channels 6 and 7 are used for PA/LNA (optionally). - * Channels 7..9 are used for GPIO debugging (optionally). - */ - -#define DPPI_CH_TIMER0_EVENTS_COMPARE_0 0 -#define DPPI_CH_TIMER0_EVENTS_COMPARE_3 1 -#define DPPI_CH_RADIO_EVENTS_END 2 -#define DPPI_CH_RADIO_EVENTS_BCMATCH 3 -#define DPPI_CH_RADIO_EVENTS_ADDRESS 4 -#define DPPI_CH_RTC0_EVENTS_COMPARE_0 5 -#define DPPI_CH_TIMER0_EVENTS_COMPARE_4 6 -#define DPPI_CH_RADIO_EVENTS_DISABLED 7 -#define DPPI_CH_RADIO_EVENTS_READY 8 -#define DPPI_CH_RADIO_EVENTS_RXREADY 9 - -#define DPPI_CH_ENABLE_ALL (DPPIC_CHEN_CH0_Msk | DPPIC_CHEN_CH1_Msk | DPPIC_CHEN_CH2_Msk | \ - DPPIC_CHEN_CH3_Msk | DPPIC_CHEN_CH4_Msk | DPPIC_CHEN_CH5_Msk) - -#define DPPI_CH_MASK_FEM (DPPI_CH_MASK(TIMER0_EVENTS_COMPARE_4) | \ - DPPI_CH_MASK(RADIO_EVENTS_DISABLED)) - -extern uint8_t g_nrf_num_irks; -extern uint32_t g_nrf_irk_list[]; - -/* To disable all radio interrupts */ -#define NRF_RADIO_IRQ_MASK_ALL (0x34FF) - -/* - * We configure the nrf with a 1 byte S0 field, 8 bit length field, and - * zero bit S1 field. The preamble is 8 bits long. - */ -#define NRF_LFLEN_BITS (8) -#define NRF_S0LEN (1) -#define NRF_S1LEN_BITS (0) -#define NRF_CILEN_BITS (2) -#define NRF_TERMLEN_BITS (3) - -/* Maximum length of frames */ -#define NRF_MAXLEN (255) -#define NRF_BALEN (3) /* For base address of 3 bytes */ - -/* NRF_RADIO_NS->PCNF0 configuration values */ -#define NRF_PCNF0 (NRF_LFLEN_BITS << RADIO_PCNF0_LFLEN_Pos) | \ - (RADIO_PCNF0_S1INCL_Msk) | \ - (NRF_S0LEN << RADIO_PCNF0_S0LEN_Pos) | \ - (NRF_S1LEN_BITS << RADIO_PCNF0_S1LEN_Pos) -#define NRF_PCNF0_1M (NRF_PCNF0) | \ - (RADIO_PCNF0_PLEN_8bit << RADIO_PCNF0_PLEN_Pos) -#define NRF_PCNF0_2M (NRF_PCNF0) | \ - (RADIO_PCNF0_PLEN_16bit << RADIO_PCNF0_PLEN_Pos) -#define NRF_PCNF0_CODED (NRF_PCNF0) | \ - (RADIO_PCNF0_PLEN_LongRange << RADIO_PCNF0_PLEN_Pos) | \ - (NRF_CILEN_BITS << RADIO_PCNF0_CILEN_Pos) | \ - (NRF_TERMLEN_BITS << RADIO_PCNF0_TERMLEN_Pos) - -/* BLE PHY data structure */ -struct ble_phy_obj { - uint8_t phy_stats_initialized; - int8_t phy_txpwr_dbm; - uint8_t phy_chan; - uint8_t phy_state; - uint8_t phy_transition; - uint8_t phy_transition_late; - uint8_t phy_rx_started; - uint8_t phy_encrypted; - uint8_t phy_privacy; - uint8_t phy_tx_pyld_len; - uint8_t phy_cur_phy_mode; - uint8_t phy_tx_phy_mode; - uint8_t phy_rx_phy_mode; - uint8_t phy_bcc_offset; - int8_t rx_pwr_compensation; - uint32_t phy_aar_scratch; - uint32_t phy_access_address; - struct ble_mbuf_hdr rxhdr; - void *txend_arg; - ble_phy_tx_end_func txend_cb; - uint32_t phy_start_cputime; -}; -struct ble_phy_obj g_ble_phy_data; - -/* XXX: if 27 byte packets desired we can make this smaller */ -/* Global transmit/receive buffer */ -static uint32_t g_ble_phy_tx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4]; -static uint32_t g_ble_phy_rx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4]; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -/* Make sure word-aligned for faster copies */ -static uint32_t g_ble_phy_enc_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4]; -#endif - -/* RF center frequency for each channel index (offset from 2400 MHz) */ -static const uint8_t g_ble_phy_chan_freq[BLE_PHY_NUM_CHANS] = { - 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, /* 0-9 */ - 24, 28, 30, 32, 34, 36, 38, 40, 42, 44, /* 10-19 */ - 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, /* 20-29 */ - 66, 68, 70, 72, 74, 76, 78, 2, 26, 80, /* 30-39 */ -}; - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) -/* packet start offsets (in usecs) */ -static const uint16_t g_ble_phy_mode_pkt_start_off[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 40, - [BLE_PHY_MODE_2M] = 24, - [BLE_PHY_MODE_CODED_125KBPS] = 376, - [BLE_PHY_MODE_CODED_500KBPS] = 376 -}; -#endif - -/* Various radio timings */ -/* Radio ramp-up times in usecs (fast mode) */ -#define BLE_PHY_T_TXENFAST (XCVR_TX_RADIO_RAMPUP_USECS) -#define BLE_PHY_T_RXENFAST (XCVR_RX_RADIO_RAMPUP_USECS) - -/* delay between EVENTS_READY and start of tx */ -static const uint8_t g_ble_phy_t_txdelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 4, - [BLE_PHY_MODE_2M] = 3, - [BLE_PHY_MODE_CODED_125KBPS] = 5, - [BLE_PHY_MODE_CODED_500KBPS] = 5 -}; -/* delay between EVENTS_END and end of txd packet */ -static const uint8_t g_ble_phy_t_txenddelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 4, - [BLE_PHY_MODE_2M] = 3, - [BLE_PHY_MODE_CODED_125KBPS] = 9, - [BLE_PHY_MODE_CODED_500KBPS] = 3 -}; -/* delay between rxd access address (w/ TERM1 for coded) and EVENTS_ADDRESS */ -static const uint8_t g_ble_phy_t_rxaddrdelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 6, - [BLE_PHY_MODE_2M] = 2, - [BLE_PHY_MODE_CODED_125KBPS] = 17, - [BLE_PHY_MODE_CODED_500KBPS] = 17 -}; -/* delay between end of rxd packet and EVENTS_END */ -static const uint8_t g_ble_phy_t_rxenddelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 6, - [BLE_PHY_MODE_2M] = 2, - [BLE_PHY_MODE_CODED_125KBPS] = 27, - [BLE_PHY_MODE_CODED_500KBPS] = 22 -}; - -/* Statistics */ -STATS_SECT_START(ble_phy_stats) -STATS_SECT_ENTRY(phy_isrs) -STATS_SECT_ENTRY(tx_good) -STATS_SECT_ENTRY(tx_fail) -STATS_SECT_ENTRY(tx_late) -STATS_SECT_ENTRY(tx_bytes) -STATS_SECT_ENTRY(rx_starts) -STATS_SECT_ENTRY(rx_aborts) -STATS_SECT_ENTRY(rx_valid) -STATS_SECT_ENTRY(rx_crc_err) -STATS_SECT_ENTRY(rx_late) -STATS_SECT_ENTRY(radio_state_errs) -STATS_SECT_ENTRY(rx_hw_err) -STATS_SECT_ENTRY(tx_hw_err) -STATS_SECT_END -STATS_SECT_DECL(ble_phy_stats) ble_phy_stats; - -STATS_NAME_START(ble_phy_stats) -STATS_NAME(ble_phy_stats, phy_isrs) -STATS_NAME(ble_phy_stats, tx_good) -STATS_NAME(ble_phy_stats, tx_fail) -STATS_NAME(ble_phy_stats, tx_late) -STATS_NAME(ble_phy_stats, tx_bytes) -STATS_NAME(ble_phy_stats, rx_starts) -STATS_NAME(ble_phy_stats, rx_aborts) -STATS_NAME(ble_phy_stats, rx_valid) -STATS_NAME(ble_phy_stats, rx_crc_err) -STATS_NAME(ble_phy_stats, rx_late) -STATS_NAME(ble_phy_stats, radio_state_errs) -STATS_NAME(ble_phy_stats, rx_hw_err) -STATS_NAME(ble_phy_stats, tx_hw_err) -STATS_NAME_END(ble_phy_stats) - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -/* - * Per nordic, the number of bytes needed for scratch is 16 + MAX_PKT_SIZE. - * However, when I used a smaller size it still overwrote the scratchpad. Until - * I figure this out I am just going to allocate 67 words so we have enough - * space for 267 bytes of scratch. I used 268 bytes since not sure if this - * needs to be aligned and burning a byte is no big deal. - * - *#define NRF_ENC_SCRATCH_WORDS (((MYNEWT_VAL(BLE_LL_MAX_PKT_SIZE) + 16) + 3) / 4) - */ -#define NRF_ENC_SCRATCH_WORDS (67) - -static uint32_t nrf_encrypt_scratchpad[NRF_ENC_SCRATCH_WORDS]; - -struct nrf_ccm_data { - uint8_t key[16]; - uint64_t pkt_counter; - uint8_t dir_bit; - uint8_t iv[8]; -} __attribute__((packed)); - -static struct nrf_ccm_data nrf_ccm_data; -#endif - -static int g_ble_phy_gpiote_idx; - -#if MYNEWT_VAL(BLE_LL_FEM_PA) || MYNEWT_VAL(BLE_LL_FEM_LNA) - -#define FEM_SINGLE_GPIO \ - (!MYNEWT_VAL(BLE_LL_FEM_PA) || !MYNEWT_VAL(BLE_LL_FEM_LNA) || \ - (MYNEWT_VAL(BLE_LL_FEM_PA_GPIO) == MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO))) - -#if FEM_SINGLE_GPIO -static uint8_t fem_idx; -#else -#if MYNEWT_VAL(BLE_LL_FEM_PA) -static uint8_t fem_pa_idx; -#endif -#if MYNEWT_VAL(BLE_LL_FEM_LNA) -static uint8_t fem_lna_idx; -#endif -#endif - -#endif - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 -static uint8_t phy_dbg_txrxen_ready_idx; -#endif -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 -static uint8_t phy_dbg_address_end_idx; -#endif -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 -static uint8_t phy_dbg_wfr_idx; -#endif - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - -uint32_t -ble_phy_mode_pdu_start_off(int phy_mode) -{ - return g_ble_phy_mode_pkt_start_off[phy_mode]; -} - -static void -ble_phy_mode_apply(uint8_t phy_mode) -{ - if (phy_mode == g_ble_phy_data.phy_cur_phy_mode) { - return; - } - - switch (phy_mode) { - case BLE_PHY_MODE_1M: - NRF_RADIO_NS->MODE = RADIO_MODE_MODE_Ble_1Mbit; - *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0080); - NRF_RADIO_NS->PCNF0 = NRF_PCNF0_1M; - break; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) - case BLE_PHY_MODE_2M: - NRF_RADIO_NS->MODE = RADIO_MODE_MODE_Ble_2Mbit; - *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0084); - NRF_RADIO_NS->PCNF0 = NRF_PCNF0_2M; - break; -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - case BLE_PHY_MODE_CODED_125KBPS: - NRF_RADIO_NS->MODE = RADIO_MODE_MODE_Ble_LR125Kbit; - *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0080); - NRF_RADIO_NS->PCNF0 = NRF_PCNF0_CODED; - break; - case BLE_PHY_MODE_CODED_500KBPS: - NRF_RADIO_NS->MODE = RADIO_MODE_MODE_Ble_LR500Kbit; - *((volatile uint32_t *)0x41008588) = *((volatile uint32_t *)0x01FF0080); - NRF_RADIO_NS->PCNF0 = NRF_PCNF0_CODED; - break; -#endif - default: - assert(0); - } - - g_ble_phy_data.phy_cur_phy_mode = phy_mode; -} -#endif - -void -ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode) -{ - g_ble_phy_data.phy_tx_phy_mode = tx_phy_mode; - g_ble_phy_data.phy_rx_phy_mode = rx_phy_mode; -} - -static void -ble_phy_fem_enable_pa(void) -{ -#if MYNEWT_VAL(BLE_LL_FEM_PA) - ble_ll_fem_pa_enable(); - - /* CC[0] is set to radio enable */ - NRF_TIMER0_NS->CC[4] = NRF_TIMER0_NS->CC[0] + BLE_PHY_T_RXENFAST - - MYNEWT_VAL(BLE_LL_FEM_PA_TURN_ON_US); - -#if FEM_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); -#else - NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_pa_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); -#endif -#endif -} - -static void -ble_phy_fem_disable_pa(void) -{ -#if MYNEWT_VAL(BLE_LL_FEM_PA) - ble_ll_fem_pa_disable(); - -#if FEM_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); -#else - NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_pa_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); -#endif -#endif -} - -static void -ble_phy_fem_enable_lna(void) -{ -#if MYNEWT_VAL(BLE_LL_FEM_LNA) - ble_ll_fem_lna_enable(); - - /* CC[0] is set to radio enable */ - NRF_TIMER0_NS->CC[4] = NRF_TIMER0_NS->CC[0] + BLE_PHY_T_RXENFAST - - MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US); - -#if FEM_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); -#else - NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_lna_idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_4); -#endif -#endif -} - -static void -ble_phy_fem_disable_lna(void) -{ -#if MYNEWT_VAL(BLE_LL_FEM_LNA) - ble_ll_fem_lna_disable(); - -#if FEM_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); -#else - NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_lna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); -#endif -#endif -} - -static void -ble_phy_fem_force_disable(void) -{ -#if FEM_SINGLE_GPIO - NRF_GPIOTE_NS->TASKS_CLR[fem_idx] = 1; -#else -#if MYNEWT_VAL(BLE_LL_FEM_PA) - NRF_GPIOTE_NS->TASKS_CLR[fem_pa_idx] = 1; -#endif -#if MYNEWT_VAL(BLE_LL_FEM_LNA) - NRF_GPIOTE_NS->TASKS_CLR[fem_lna_idx] = 1; -#endif -#endif -} - -int -ble_phy_get_cur_phy(void) -{ -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - switch (g_ble_phy_data.phy_cur_phy_mode) { - case BLE_PHY_MODE_1M: - return BLE_PHY_1M; - case BLE_PHY_MODE_2M: - return BLE_PHY_2M; - case BLE_PHY_MODE_CODED_125KBPS: - case BLE_PHY_MODE_CODED_500KBPS: - return BLE_PHY_CODED; - default: - assert(0); - return -1; - } -#else - return BLE_PHY_1M; -#endif -} - -void -ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu) -{ - uint32_t rem_len; - uint32_t copy_len; - uint32_t block_len; - uint32_t block_rem_len; - void *dst; - void *src; - struct os_mbuf * om; - - /* Better be aligned */ - assert(((uint32_t)dptr & 3) == 0); - - block_len = rxpdu->om_omp->omp_databuf_len; - rem_len = OS_MBUF_PKTHDR(rxpdu)->omp_len; - src = dptr; - - /* - * Setup for copying from first mbuf which is shorter due to packet header - * and extra leading space - */ - copy_len = block_len - rxpdu->om_pkthdr_len - 4; - om = rxpdu; - dst = om->om_data; - - while (true) { - /* - * Always copy blocks of length aligned to word size, only last mbuf - * will have remaining non-word size bytes appended. - */ - block_rem_len = copy_len; - copy_len = min(copy_len, rem_len); - copy_len &= ~3; - - dst = om->om_data; - om->om_len = copy_len; - rem_len -= copy_len; - block_rem_len -= copy_len; - - __asm__ volatile (".syntax unified \n" - " mov r4, %[len] \n" - " b 2f \n" - "1: ldr r3, [%[src], %[len]] \n" - " str r3, [%[dst], %[len]] \n" - "2: subs %[len], #4 \n" - " bpl 1b \n" - " adds %[src], %[src], r4 \n" - " adds %[dst], %[dst], r4 \n" - : [dst] "+r" (dst), [src] "+r" (src), - [len] "+r" (copy_len) - : - : "r3", "r4", "memory" - ); - - if ((rem_len < 4) && (block_rem_len >= rem_len)) { - break; - } - - /* Move to next mbuf */ - om = SLIST_NEXT(om, om_next); - copy_len = block_len; - } - - /* Copy remaining bytes, if any, to last mbuf */ - om->om_len += rem_len; - __asm__ volatile (".syntax unified \n" - " b 2f \n" - "1: ldrb r3, [%[src], %[len]] \n" - " strb r3, [%[dst], %[len]] \n" - "2: subs %[len], #1 \n" - " bpl 1b \n" - : [len] "+r" (rem_len) - : [dst] "r" (dst), [src] "r" (src) - : "r3", "memory" - ); - - /* Copy header */ - memcpy(BLE_MBUF_HDR_PTR(rxpdu), &g_ble_phy_data.rxhdr, - sizeof(struct ble_mbuf_hdr)); -} - -/** - * Called when we want to wait if the radio is in either the rx or tx - * disable states. We want to wait until that state is over before doing - * anything to the radio - */ -static void -nrf_wait_disabled(void) -{ - uint32_t state; - - state = NRF_RADIO_NS->STATE; - if (state != RADIO_STATE_STATE_Disabled) { - if ((state == RADIO_STATE_STATE_RxDisable) || - (state == RADIO_STATE_STATE_TxDisable)) { - /* This will end within a short time (6 usecs). Just poll */ - while (NRF_RADIO_NS->STATE == state) { - /* If this fails, something is really wrong. Should last - * no more than 6 usecs - */ - } - } - } -} - -static int -ble_phy_set_start_time(uint32_t cputime, uint8_t rem_usecs, bool tx) -{ - uint32_t next_cc; - uint32_t cur_cc; - uint32_t cntr; - uint32_t delta; - - /* - * We need to adjust start time to include radio ramp-up and TX pipeline - * delay (the latter only if applicable, so only for TX). - * - * Radio ramp-up time is 40 usecs and TX delay is 3 or 5 usecs depending on - * phy, thus we'll offset RTC by 2 full ticks (61 usecs) and then compensate - * using TIMER0 with 1 usec precision. - */ - - cputime -= 2; - rem_usecs += 61; - if (tx) { - rem_usecs -= BLE_PHY_T_TXENFAST; - rem_usecs -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; - } else { - rem_usecs -= BLE_PHY_T_RXENFAST; - } - - /* - * rem_usecs will be no more than 2 ticks, but if it is more than single - * tick then we should better count one more low-power tick rather than - * 30 high-power usecs. Also make sure we don't set TIMER0 CC to 0 as the - * compare won't occur. - */ - - if (rem_usecs > 30) { - cputime++; - rem_usecs -= 30; - } - - /* If PA/LNA is used, make sure CC[0] is set to more than turn-on time since - * it's used as a base for turn-on time calculation and thus cannot wrap - * around on subtraction. - */ - if (MYNEWT_VAL(BLE_LL_FEM_PA) && tx && - (rem_usecs + BLE_PHY_T_RXENFAST <= MYNEWT_VAL(BLE_LL_FEM_PA_TURN_ON_US))) { - cputime--; - rem_usecs += 30; - } - - if (MYNEWT_VAL(BLE_LL_FEM_LNA) && !tx && - (rem_usecs + BLE_PHY_T_RXENFAST <= MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US))) { - cputime--; - rem_usecs += 30; - } - - /* - * Can we set the RTC compare to start TIMER0? We can do it if: - * a) Current compare value is not N+1 or N+2 ticks from current - * counter. - * b) The value we want to set is not at least N+2 from current - * counter. - * - * NOTE: since the counter can tick 1 while we do these calculations we - * need to account for it. - */ - next_cc = cputime & 0xffffff; - cur_cc = NRF_RTC0_NS->CC[0]; - cntr = NRF_RTC0_NS->COUNTER; - - delta = (cur_cc - cntr) & 0xffffff; - if ((delta <= 3) && (delta != 0)) { - return -1; - } - delta = (next_cc - cntr) & 0xffffff; - if ((delta & 0x800000) || (delta < 3)) { - return -1; - } - - /* Clear and set TIMER0 to fire off at proper time */ - NRF_TIMER0_NS->TASKS_CLEAR = 1; - NRF_TIMER0_NS->CC[0] = rem_usecs; - NRF_TIMER0_NS->EVENTS_COMPARE[0] = 0; - - /* Set RTC compare to start TIMER0 */ - NRF_RTC0_NS->EVENTS_COMPARE[0] = 0; - NRF_RTC0_NS->CC[0] = next_cc; - NRF_RTC0_NS->EVTENSET = RTC_EVTENSET_COMPARE0_Msk; - - /* Enable PPI */ - NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_CH_SUB(RTC0_EVENTS_COMPARE_0); - - /* Store the cputime at which we set the RTC */ - g_ble_phy_data.phy_start_cputime = cputime; - - return 0; -} - -static int -ble_phy_set_start_now(void) -{ - os_sr_t sr; - uint32_t now; - - OS_ENTER_CRITICAL(sr); - - /* - * Set TIMER0 to fire immediately. We can't set CC to 0 as compare will not - * occur in such case. - */ - NRF_TIMER0_NS->TASKS_CLEAR = 1; - NRF_TIMER0_NS->CC[0] = 1; - NRF_TIMER0_NS->EVENTS_COMPARE[0] = 0; - - /* - * Set RTC compare to start TIMER0. We need to set it to at least N+2 ticks - * from current value to guarantee triggering compare event, but let's set - * it to N+3 to account for possible extra tick on RTC0 during these - * operations. - */ - now = os_cputime_get32(); - NRF_RTC0_NS->EVENTS_COMPARE[0] = 0; - NRF_RTC0_NS->CC[0] = now + 3; - NRF_RTC0_NS->EVTENSET = RTC_EVTENSET_COMPARE0_Msk; - - /* Enable PPI */ - NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_CH_SUB(RTC0_EVENTS_COMPARE_0); - - /* - * Store the cputime at which we set the RTC - * - * XXX Compare event may be triggered on previous CC value (if it was set to - * less than N+2) so in rare cases actual start time may be 2 ticks earlier - * than what we expect. Since this is only used on RX, it may cause AUX scan - * to be scheduled 1 or 2 ticks too late so we'll miss it - it's acceptable - * for now. - */ - g_ble_phy_data.phy_start_cputime = now + 3; - - OS_EXIT_CRITICAL(sr); - - return 0; -} - -void -ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) -{ - uint32_t end_time; - uint8_t phy; - - phy = g_ble_phy_data.phy_cur_phy_mode; - - if (txrx == BLE_PHY_WFR_ENABLE_TXRX) { - /* RX shall start exactly T_IFS after TX end captured in CC[2] */ - end_time = NRF_TIMER0_NS->CC[2] + BLE_LL_IFS; - /* Adjust for delay between EVENT_END and actual TX end time */ - end_time += g_ble_phy_t_txenddelay[tx_phy_mode]; - /* Wait a bit longer due to allowed active clock accuracy */ - end_time += 2; - /* - * It's possible that we'll capture PDU start time at the end of timer - * cycle and since wfr expires at the beginning of calculated timer - * cycle it can be almost 1 usec too early. Let's compensate for this - * by waiting 1 usec more. - */ - end_time += 1; - } else { - /* - * RX shall start no later than wfr_usecs after RX enabled. - * CC[0] is the time of RXEN so adjust for radio ram-up. - * Do not add jitter since this is already covered by LL. - */ - end_time = NRF_TIMER0_NS->CC[0] + BLE_PHY_T_RXENFAST + wfr_usecs; - } - - /* - * Note: on LE Coded EVENT_ADDRESS is fired after TERM1 is received, so - * we are actually calculating relative to start of packet payload - * which is fine. - */ - - /* Adjust for receiving access address since this triggers EVENT_ADDRESS */ - end_time += ble_phy_mode_pdu_start_off(phy); - /* Adjust for delay between actual access address RX and EVENT_ADDRESS */ - end_time += g_ble_phy_t_rxaddrdelay[phy]; - - /* wfr_secs is the time from rxen until timeout */ - NRF_TIMER0_NS->CC[3] = end_time; - NRF_TIMER0_NS->EVENTS_COMPARE[3] = 0; - - /* Subscribe for wait for response events */ - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_3); - - /* - * It may happen that if CPU is halted for a brief moment (e.g. during flash - * erase or write), TIMER0 already counted past CC[3] and thus wfr will not - * fire as expected. In case this happened, let's just disable PPIs for wfr - * and trigger wfr manually (i.e. disable radio). - * - * Note that the same applies to RX start time set in CC[0] but since it - * should fire earlier than wfr, fixing wfr is enough. - * - * CC[1] is only used as a reference on RX start, we do not need it here so - * it can be used to read TIMER0 counter. - */ - NRF_TIMER0_NS->TASKS_CAPTURE[1] = 1; - if (NRF_TIMER0_NS->CC[1] > NRF_TIMER0_NS->CC[3]) { - /* Unsubscribe from wfr events */ - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); - - NRF_RADIO_NS->TASKS_DISABLE = 1; - } -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -static uint32_t -ble_phy_get_ccm_datarate(void) -{ -#if BLE_LL_BT5_PHY_SUPPORTED - switch (g_ble_phy_data.phy_cur_phy_mode) { - case BLE_PHY_MODE_1M: - return CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos; - case BLE_PHY_MODE_2M: - return CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - case BLE_PHY_MODE_CODED_125KBPS: - return CCM_MODE_DATARATE_125Kbps << CCM_MODE_DATARATE_Pos; - case BLE_PHY_MODE_CODED_500KBPS: - return CCM_MODE_DATARATE_500Kbps << CCM_MODE_DATARATE_Pos; -#endif - } - - assert(0); - return 0; -#else - return CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos; -#endif -} -#endif - -/** - * Setup transceiver for receive. - */ -static void -ble_phy_rx_xcvr_setup(void) -{ - uint8_t *dptr; - - dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; - dptr += 3; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (g_ble_phy_data.phy_encrypted) { - NRF_RADIO_NS->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0]; - NRF_CCM_NS->INPTR = (uint32_t)&g_ble_phy_enc_buf[0]; - NRF_CCM_NS->OUTPTR = (uint32_t)dptr; - NRF_CCM_NS->SCRATCHPTR = (uint32_t)&nrf_encrypt_scratchpad[0]; - NRF_CCM_NS->MODE = CCM_MODE_LENGTH_Msk | CCM_MODE_MODE_Decryption | - ble_phy_get_ccm_datarate(); - NRF_CCM_NS->CNFPTR = (uint32_t)&nrf_ccm_data; - NRF_CCM_NS->SHORTS = 0; - NRF_CCM_NS->EVENTS_ERROR = 0; - NRF_CCM_NS->EVENTS_ENDCRYPT = 0; - NRF_CCM_NS->TASKS_KSGEN = 1; - - /* Subscribe to radio address event */ - NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); - } else { - NRF_RADIO_NS->PACKETPTR = (uint32_t)dptr; - } -#else - NRF_RADIO_NS->PACKETPTR = (uint32_t)dptr; -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - if (g_ble_phy_data.phy_privacy) { - NRF_AAR_NS->ENABLE = AAR_ENABLE_ENABLE_Enabled; - NRF_AAR_NS->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; - NRF_AAR_NS->SCRATCHPTR = (uint32_t)&g_ble_phy_data.phy_aar_scratch; - NRF_AAR_NS->EVENTS_END = 0; - NRF_AAR_NS->EVENTS_RESOLVED = 0; - NRF_AAR_NS->EVENTS_NOTRESOLVED = 0; - } else { - if (g_ble_phy_data.phy_encrypted == 0) { - NRF_AAR_NS->ENABLE = AAR_ENABLE_ENABLE_Disabled; - } - } -#endif - - /* Turn off trigger TXEN on output compare match and AAR on bcmatch */ - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - NRF_AAR_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RADIO_EVENTS_BCMATCH); - - /* Reset the rx started flag. Used for the wait for response */ - g_ble_phy_data.phy_rx_started = 0; - g_ble_phy_data.phy_state = BLE_PHY_STATE_RX; - -#if BLE_LL_BT5_PHY_SUPPORTED - /* - * On Coded PHY there are CI and TERM1 fields before PDU starts so we need - * to take this into account when setting up BCC. - */ - if (g_ble_phy_data.phy_cur_phy_mode == BLE_PHY_MODE_CODED_125KBPS || - g_ble_phy_data.phy_cur_phy_mode == BLE_PHY_MODE_CODED_500KBPS) { - g_ble_phy_data.phy_bcc_offset = 5; - } else { - g_ble_phy_data.phy_bcc_offset = 0; - } -#else - g_ble_phy_data.phy_bcc_offset = 0; -#endif - - /* I want to know when 1st byte received (after address) */ - NRF_RADIO_NS->BCC = 8 + g_ble_phy_data.phy_bcc_offset; /* in bits */ - NRF_RADIO_NS->EVENTS_ADDRESS = 0; - NRF_RADIO_NS->EVENTS_DEVMATCH = 0; - NRF_RADIO_NS->EVENTS_BCMATCH = 0; - NRF_RADIO_NS->EVENTS_RSSIEND = 0; - NRF_RADIO_NS->EVENTS_CRCOK = 0; - NRF_RADIO_NS->SHORTS = RADIO_SHORTS_END_DISABLE_Msk | - RADIO_SHORTS_READY_START_Msk | - RADIO_SHORTS_ADDRESS_BCSTART_Msk | - RADIO_SHORTS_ADDRESS_RSSISTART_Msk | - RADIO_SHORTS_DISABLED_RSSISTOP_Msk; - - NRF_RADIO_NS->INTENSET = RADIO_INTENSET_ADDRESS_Msk | - RADIO_INTENSET_DISABLED_Msk; -} - -/** - * Called from interrupt context when the transmit ends - * - */ -static void -ble_phy_tx_end_isr(void) -{ - uint8_t tx_phy_mode; - uint8_t was_encrypted; - uint8_t transition; - uint32_t rx_time; - - /* Store PHY on which we've just transmitted smth */ - tx_phy_mode = g_ble_phy_data.phy_cur_phy_mode; - - /* If this transmission was encrypted we need to remember it */ - was_encrypted = g_ble_phy_data.phy_encrypted; - (void)was_encrypted; - - /* Better be in TX state! */ - assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX); - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - /* - * XXX: not sure what to do. We had a HW error during transmission. - * For now I just count a stat but continue on like all is good. - */ - if (was_encrypted) { - if (NRF_CCM_NS->EVENTS_ERROR) { - STATS_INC(ble_phy_stats, tx_hw_err); - NRF_CCM_NS->EVENTS_ERROR = 0; - } - } -#endif - - /* Call transmit end callback */ - if (g_ble_phy_data.txend_cb) { - g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg); - } - - transition = g_ble_phy_data.phy_transition; - if (transition == BLE_PHY_TRANSITION_TX_RX) { - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); -#endif - - /* Packet pointer needs to be reset. */ - ble_phy_rx_xcvr_setup(); - - ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_TXRX, tx_phy_mode, 0); - - /* Schedule RX exactly T_IFS after TX end captured in CC[2] */ - rx_time = NRF_TIMER0_NS->CC[2] + BLE_LL_IFS; - /* Adjust for delay between EVENT_END and actual TX end time */ - rx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; - /* Adjust for radio ramp-up */ - rx_time -= BLE_PHY_T_RXENFAST; - /* Start listening a bit earlier due to allowed active clock accuracy */ - rx_time -= 2; - - NRF_TIMER0_NS->CC[0] = rx_time; - NRF_TIMER0_NS->EVENTS_COMPARE[0] = 0; - - /* Start radio on timer */ - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - - ble_phy_fem_enable_lna(); - } else { - NRF_TIMER0_NS->TASKS_STOP = 1; - NRF_TIMER0_NS->TASKS_SHUTDOWN = 1; - - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RTC0_EVENTS_COMPARE_0); - - assert(transition == BLE_PHY_TRANSITION_NONE); - } -} - -static inline uint8_t -ble_phy_get_cur_rx_phy_mode(void) -{ - uint8_t phy; - - phy = g_ble_phy_data.phy_cur_phy_mode; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) - /* - * For Coded PHY mode can be set to either codings since actual coding is - * set in packet header. However, here we need actual coding of received - * packet as this determines pipeline delays so need to figure this out - * using CI field. - */ - if ((phy == BLE_PHY_MODE_CODED_125KBPS) || - (phy == BLE_PHY_MODE_CODED_500KBPS)) { - phy = NRF_RADIO_NS->PDUSTAT & RADIO_PDUSTAT_CISTAT_Msk ? - BLE_PHY_MODE_CODED_500KBPS : BLE_PHY_MODE_CODED_125KBPS; - } -#endif - - return phy; -} - -static void -ble_phy_rx_end_isr(void) -{ - int rc; - uint8_t *dptr; - uint8_t crcok; - uint32_t tx_time; - struct ble_mbuf_hdr *ble_hdr; - - /* Disable automatic RXEN */ - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - - /* Set RSSI and CRC status flag in header */ - ble_hdr = &g_ble_phy_data.rxhdr; - assert(NRF_RADIO_NS->EVENTS_RSSIEND != 0); - ble_hdr->rxinfo.rssi = (-1 * NRF_RADIO_NS->RSSISAMPLE) + - g_ble_phy_data.rx_pwr_compensation; - - dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; - dptr += 3; - - /* Count PHY crc errors and valid packets */ - crcok = NRF_RADIO_NS->EVENTS_CRCOK; - if (!crcok) { - STATS_INC(ble_phy_stats, rx_crc_err); - } else { - STATS_INC(ble_phy_stats, rx_valid); - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (g_ble_phy_data.phy_encrypted) { - while (NRF_CCM_NS->EVENTS_ENDCRYPT == 0) { - /* Make sure CCM finished */ - }; - - /* Only set MIC failure flag if frame is not zero length */ - if ((dptr[1] != 0) && (NRF_CCM_NS->MICSTATUS == 0)) { - ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_MIC_FAILURE; - } - - /* - * XXX: not sure how to deal with this. This should not - * be a MIC failure but we should not hand it up. I guess - * this is just some form of rx error and that is how we - * handle it? For now, just set CRC error flags - */ - if (NRF_CCM_NS->EVENTS_ERROR) { - STATS_INC(ble_phy_stats, rx_hw_err); - ble_hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_CRC_OK; - } - } -#endif - } - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_tx_phy_mode); -#endif - - /* - * Let's schedule TX now and we will just cancel it after processing RXed - * packet if we don't need TX. - * - * We need this to initiate connection in case AUX_CONNECT_REQ was sent on - * LE Coded S8. In this case the time we process RXed packet is roughly the - * same as the limit when we need to have TX scheduled (i.e. TIMER0 and PPI - * armed) so we may simply miss the slot and set the timer in the past. - * - * When TX is scheduled in advance, we may event process packet a bit longer - * during radio ramp-up - this gives us extra 40 usecs which is more than - * enough. - */ - - /* Schedule TX exactly T_IFS after RX end captured in CC[2] */ - tx_time = NRF_TIMER0_NS->CC[2] + BLE_LL_IFS; - /* Adjust for delay between actual RX end time and EVENT_END */ - tx_time -= g_ble_phy_t_rxenddelay[ble_hdr->rxinfo.phy_mode]; - /* Adjust for radio ramp-up */ - tx_time -= BLE_PHY_T_TXENFAST; - /* Adjust for delay between EVENT_READY and actual TX start time */ - tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; - - NRF_TIMER0_NS->CC[0] = tx_time; - NRF_TIMER0_NS->EVENTS_COMPARE[0] = 0; - - /* Enable automatic TX */ - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - - ble_phy_fem_enable_pa(); - - /* - * XXX: Hack warning! - * - * It may happen (during flash erase) that CPU is stopped for a moment and - * TIMER0 already counted past CC[0]. In such case we will be stuck waiting - * for TX to start since EVENTS_COMPARE[0] will not happen any time soon. - * For now let's set a flag denoting that we are late in RX-TX transition so - * ble_phy_tx() will fail - this allows everything to cleanup nicely without - * the need for extra handling in many places. - * - * Note: CC[3] is used only for wfr which we do not need here. - */ - NRF_TIMER0_NS->TASKS_CAPTURE[3] = 1; - if (NRF_TIMER0_NS->CC[3] > NRF_TIMER0_NS->CC[0]) { - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - - g_ble_phy_data.phy_transition_late = 1; - } - - /* - * XXX: This is a horrible ugly hack to deal with the RAM S1 byte - * that is not sent over the air but is present here. Simply move the - * data pointer to deal with it. Fix this later. - */ - dptr[2] = dptr[1]; - dptr[1] = dptr[0]; - rc = ble_ll_rx_end(dptr + 1, ble_hdr); - if (rc < 0) { - ble_phy_disable(); - } -} - -static bool -ble_phy_rx_start_isr(void) -{ - int rc; - uint32_t state; - uint32_t usecs; - uint32_t pdu_usecs; - uint32_t ticks; - struct ble_mbuf_hdr *ble_hdr; - uint8_t *dptr; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - int adva_offset; -#endif - - dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; - - /* Clear events and clear interrupt */ - NRF_RADIO_NS->EVENTS_ADDRESS = 0; - NRF_RADIO_NS->INTENCLR = RADIO_INTENCLR_ADDRESS_Msk; - - /* Clear wfr timer channels and DISABLED interrupt */ - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); - - /* Initialize the ble mbuf header */ - ble_hdr = &g_ble_phy_data.rxhdr; - ble_hdr->rxinfo.flags = ble_ll_state_get(); - ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan; - ble_hdr->rxinfo.handle = 0; - ble_hdr->rxinfo.phy = ble_phy_get_cur_phy(); - ble_hdr->rxinfo.phy_mode = ble_phy_get_cur_rx_phy_mode(); -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - ble_hdr->rxinfo.user_data = NULL; -#endif - - /* - * Calculate accurate packets start time (with remainder) - * - * We may start receiving packet somewhere during preamble in which case - * it is possible that actual transmission started before TIMER0 was - * running - need to take this into account. - */ - ble_hdr->beg_cputime = g_ble_phy_data.phy_start_cputime; - - usecs = NRF_TIMER0_NS->CC[1]; - pdu_usecs = ble_phy_mode_pdu_start_off(ble_hdr->rxinfo.phy_mode) + - g_ble_phy_t_rxaddrdelay[ble_hdr->rxinfo.phy_mode]; - if (usecs < pdu_usecs) { - g_ble_phy_data.phy_start_cputime--; - usecs += 30; - } - usecs -= pdu_usecs; - - ticks = os_cputime_usecs_to_ticks(usecs); - usecs -= os_cputime_ticks_to_usecs(ticks); - if (usecs == 31) { - usecs = 0; - ++ticks; - } - - ble_hdr->beg_cputime += ticks; - ble_hdr->rem_usecs = usecs; - - /* Wait to get 1st byte of frame */ - while (1) { - state = NRF_RADIO_NS->STATE; - if (NRF_RADIO_NS->EVENTS_BCMATCH != 0) { - break; - } - - /* - * If state is disabled, we should have the BCMATCH. If not, - * something is wrong! - */ - if (state == RADIO_STATE_STATE_Disabled) { - NRF_RADIO_NS->INTENCLR = NRF_RADIO_IRQ_MASK_ALL; - NRF_RADIO_NS->SHORTS = 0; - return false; - } - } - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - /* - * If privacy is enabled and received PDU has TxAdd bit set (i.e. random - * address) we try to resolve address using AAR. - */ - if (g_ble_phy_data.phy_privacy && (dptr[3] & 0x40)) { - /* - * AdvA is located at 4th octet in RX buffer (after S0, length an S1 - * fields). In case of extended advertising PDU we need to add 2 more - * octets for extended header. - */ - adva_offset = (dptr[3] & 0x0f) == 0x07 ? 2 : 0; - NRF_AAR_NS->ADDRPTR = (uint32_t)(dptr + 3 + adva_offset); - - /* Trigger AAR after last bit of AdvA is received */ - NRF_RADIO_NS->EVENTS_BCMATCH = 0; - NRF_AAR_NS->SUBSCRIBE_START = DPPI_CH_SUB(RADIO_EVENTS_BCMATCH); - NRF_RADIO_NS->BCC = (BLE_LL_PDU_HDR_LEN + adva_offset + BLE_DEV_ADDR_LEN) * 8 + - g_ble_phy_data.phy_bcc_offset; - } -#endif - - /* Call Link Layer receive start function */ - rc = ble_ll_rx_start(dptr + 3, - g_ble_phy_data.phy_chan, - &g_ble_phy_data.rxhdr); - if (rc >= 0) { - /* Set rx started flag and enable rx end ISR */ - g_ble_phy_data.phy_rx_started = 1; - } else { - /* Disable PHY */ - ble_phy_disable(); - STATS_INC(ble_phy_stats, rx_aborts); - } - - /* Count rx starts */ - STATS_INC(ble_phy_stats, rx_starts); - - return true; -} - -static void -ble_phy_isr(void) -{ - uint32_t irq_en; - - os_trace_isr_enter(); - - /* Read irq register to determine which interrupts are enabled */ - irq_en = NRF_RADIO_NS->INTENCLR; - - /* - * NOTE: order of checking is important! Possible, if things get delayed, - * we have both an ADDRESS and DISABLED interrupt in rx state. If we get - * an address, we disable the DISABLED interrupt. - */ - - /* We get this if we have started to receive a frame */ - if ((irq_en & RADIO_INTENCLR_ADDRESS_Msk) && NRF_RADIO_NS->EVENTS_ADDRESS) { - /* - * wfr timer is calculated to expire at the exact time we should start - * receiving a packet (with 1 usec precision) so it is possible it will - * fire at the same time as EVENT_ADDRESS. If this happens, radio will - * be disabled while we are waiting for EVENT_BCCMATCH after 1st byte - * of payload is received and ble_phy_rx_start_isr() will fail. In this - * case we should not clear DISABLED irq mask so it will be handled as - * regular radio disabled event below. In other case radio was disabled - * on purpose and there's nothing more to handle so we can clear mask. - */ - if (ble_phy_rx_start_isr()) { - irq_en &= ~RADIO_INTENCLR_DISABLED_Msk; - } - } - - /* Handle disabled event. This is enabled for both TX and RX. On RX, we - * need to check phy_rx_started flag to make sure we actually were receiving - * a PDU, otherwise this is due to wfr. - */ - if ((irq_en & RADIO_INTENCLR_DISABLED_Msk) && - NRF_RADIO_NS->EVENTS_DISABLED) { - BLE_LL_ASSERT(NRF_RADIO_NS->EVENTS_END || - ((g_ble_phy_data.phy_state == BLE_PHY_STATE_RX) && - !g_ble_phy_data.phy_rx_started)); - NRF_RADIO_NS->EVENTS_END = 0; - NRF_RADIO_NS->EVENTS_DISABLED = 0; - NRF_RADIO_NS->INTENCLR = RADIO_INTENCLR_DISABLED_Msk; - - switch (g_ble_phy_data.phy_state) { - case BLE_PHY_STATE_RX: - ble_phy_fem_disable_lna(); - if (g_ble_phy_data.phy_rx_started) { - ble_phy_rx_end_isr(); - } else { - ble_ll_wfr_timer_exp(NULL); - } - break; - case BLE_PHY_STATE_TX: - ble_phy_fem_disable_pa(); - ble_phy_tx_end_isr(); - break; - default: - BLE_LL_ASSERT(0); - } - } - - g_ble_phy_data.phy_transition_late = 0; - /* Count # of interrupts */ - STATS_INC(ble_phy_stats, phy_isrs); - - os_trace_isr_exit(); -} - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 || \ - MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 || \ - MYNEWT_VAL(BLE_LL_FEM_PA) || \ - MYNEWT_VAL(BLE_LL_FEM_LNA) -static int -ble_phy_gpiote_configure(int pin) -{ - NRF_GPIO_Type *port; - - g_ble_phy_gpiote_idx--; - - port = pin > 31 ? NRF_P1_NS : NRF_P0_NS; - pin &= 0x1f; - - /* Configure GPIO directly to avoid dependency to hal_gpio (for porting) */ - port->DIRSET = (1 << pin); - port->OUTCLR = (1 << pin); - - NRF_GPIOTE_NS->CONFIG[g_ble_phy_gpiote_idx] = - (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | - ((pin & 0x1F) << GPIOTE_CONFIG_PSEL_Pos) | - ((port == NRF_P1_NS) << GPIOTE_CONFIG_PORT_Pos); - - BLE_LL_ASSERT(g_ble_phy_gpiote_idx >= 0); - - return g_ble_phy_gpiote_idx; -} -#endif - -static void -ble_phy_dbg_time_setup(void) -{ - int idx __attribute__((unused)) = 8; - - /* - * We setup GPIOTE starting from last configuration index to minimize risk - * of conflict with GPIO setup via hal. It's not great solution, but since - * this is just debugging code we can live with this. - */ - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 - idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN)); - phy_dbg_txrxen_ready_idx = idx; - - NRF_GPIOTE_NS->SUBSCRIBE_SET[idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[idx] = DPPI_CH_SUB(RADIO_EVENTS_READY); - - /* Publish RADIO->EVENTS_READY */ - NRF_RADIO_NS->PUBLISH_READY = DPPI_CH_PUB(RADIO_EVENTS_READY); - NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_READY); -#endif - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 - idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN)); - phy_dbg_address_end_idx = idx; - - NRF_GPIOTE_NS->SUBSCRIBE_SET[idx] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[idx] = DPPI_CH_SUB(RADIO_EVENTS_END); -#endif - -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 - idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN)); - phy_dbg_wfr_idx = idx; - - NRF_GPIOTE_NS->SUBSCRIBE_SET[idx] = DPPI_CH_SUB(RADIO_EVENTS_RXREADY); - - /* TODO figure out how (if?) to subscribe task to multiple DPPI channels - * Currently only last one is working. Also using multiple GPIOTE for same - * PIN doesn't work... - */ - NRF_GPIOTE_NS->SUBSCRIBE_CLR[idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[idx] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[idx] = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_3); - - /* Publish RADIO->EVENTS_RXREADY */ - NRF_RADIO_NS->PUBLISH_RXREADY = DPPI_CH_PUB(RADIO_EVENTS_READY); - NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_RXREADY); - - /* Publish RADIO->EVENTS_DISABLED */ - NRF_RADIO_NS->PUBLISH_DISABLED = DPPI_CH_PUB(RADIO_EVENTS_DISABLED); - NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_DISABLED); -#endif -} - -int -ble_phy_init(void) -{ - int rc; - - g_ble_phy_gpiote_idx = 8; - - /* Default phy to use is 1M */ - g_ble_phy_data.phy_cur_phy_mode = BLE_PHY_MODE_1M; - g_ble_phy_data.phy_tx_phy_mode = BLE_PHY_MODE_1M; - g_ble_phy_data.phy_rx_phy_mode = BLE_PHY_MODE_1M; - - g_ble_phy_data.rx_pwr_compensation = 0; - - /* Set phy channel to an invalid channel so first set channel works */ - g_ble_phy_data.phy_chan = BLE_PHY_NUM_CHANS; - - /* Toggle peripheral power to reset (just in case) */ - NRF_RADIO_NS->POWER = 0; - NRF_RADIO_NS->POWER = 1; - *(volatile uint32_t *)(NRF_RADIO_NS_BASE + 0x774) = (*(volatile uint32_t* )(NRF_RADIO_NS_BASE + 0x774) & 0xfffffffe) | 0x01000000; - - /* Errata 16 - RADIO: POWER register is not functional - * Workaround: Reset all RADIO registers in firmware. - */ - NRF_RADIO_NS->SUBSCRIBE_TXEN = 0; - NRF_RADIO_NS->SUBSCRIBE_RXEN = 0; - NRF_RADIO_NS->SUBSCRIBE_DISABLE = 0; - - /* Disable all interrupts */ - NRF_RADIO_NS->INTENCLR = NRF_RADIO_IRQ_MASK_ALL; - - /* Set configuration registers */ - NRF_RADIO_NS->MODE = RADIO_MODE_MODE_Ble_1Mbit; - NRF_RADIO_NS->PCNF0 = NRF_PCNF0; - - /* XXX: should maxlen be 251 for encryption? */ - NRF_RADIO_NS->PCNF1 = NRF_MAXLEN | - (RADIO_PCNF1_ENDIAN_Little << RADIO_PCNF1_ENDIAN_Pos) | - (NRF_BALEN << RADIO_PCNF1_BALEN_Pos) | - RADIO_PCNF1_WHITEEN_Msk; - - /* Enable radio fast ramp-up */ - NRF_RADIO_NS->MODECNF0 |= (RADIO_MODECNF0_RU_Fast << RADIO_MODECNF0_RU_Pos) & RADIO_MODECNF0_RU_Msk; - - /* Set logical address 1 for TX and RX */ - NRF_RADIO_NS->TXADDRESS = 0; - NRF_RADIO_NS->RXADDRESSES = (1 << 0); - - /* Configure the CRC registers */ - NRF_RADIO_NS->CRCCNF = (RADIO_CRCCNF_SKIPADDR_Skip << RADIO_CRCCNF_SKIPADDR_Pos) | RADIO_CRCCNF_LEN_Three; - - /* Configure BLE poly */ - NRF_RADIO_NS->CRCPOLY = 0x0000065B; - - /* Configure IFS */ - NRF_RADIO_NS->TIFS = BLE_LL_IFS; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - NRF_CCM_NS->INTENCLR = 0xffffffff; - NRF_CCM_NS->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; - NRF_CCM_NS->EVENTS_ERROR = 0; - memset(nrf_encrypt_scratchpad, 0, sizeof(nrf_encrypt_scratchpad)); -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - g_ble_phy_data.phy_aar_scratch = 0; - NRF_AAR_NS->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; - NRF_AAR_NS->INTENCLR = 0xffffffff; - NRF_AAR_NS->EVENTS_END = 0; - NRF_AAR_NS->EVENTS_RESOLVED = 0; - NRF_AAR_NS->EVENTS_NOTRESOLVED = 0; - NRF_AAR_NS->NIRK = 0; -#endif - - /* TIMER0 setup for PHY when using RTC */ - NRF_TIMER0_NS->TASKS_STOP = 1; - NRF_TIMER0_NS->TASKS_SHUTDOWN = 1; - NRF_TIMER0_NS->BITMODE = 3; /* 32-bit timer */ - NRF_TIMER0_NS->MODE = 0; /* Timer mode */ - NRF_TIMER0_NS->PRESCALER = 4; /* gives us 1 MHz */ - - /* Publish events */ - NRF_TIMER0_NS->PUBLISH_COMPARE[0] = DPPI_CH_PUB(TIMER0_EVENTS_COMPARE_0); - NRF_TIMER0_NS->PUBLISH_COMPARE[3] = DPPI_CH_PUB(TIMER0_EVENTS_COMPARE_3); - NRF_RADIO_NS->PUBLISH_END = DPPI_CH_PUB(RADIO_EVENTS_END); - NRF_RADIO_NS->PUBLISH_BCMATCH = DPPI_CH_PUB(RADIO_EVENTS_BCMATCH); - NRF_RADIO_NS->PUBLISH_ADDRESS = DPPI_CH_PUB(RADIO_EVENTS_ADDRESS); - NRF_RTC0_NS->PUBLISH_COMPARE[0] = DPPI_CH_PUB(RTC0_EVENTS_COMPARE_0); - - /* Enable channels we publish on */ - NRF_DPPIC_NS->CHENSET = DPPI_CH_ENABLE_ALL; - - /* Captures tx/rx start in timer0 cc 1 and tx/rx end in timer0 cc 2 */ - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[1] = DPPI_CH_SUB(RADIO_EVENTS_ADDRESS); - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[2] = DPPI_CH_SUB(RADIO_EVENTS_END); - -#if MYNEWT_VAL(BLE_LL_FEM_PA) || MYNEWT_VAL(BLE_LL_FEM_LNA) - /* We keep both channels enabled and CLR task subscribed all the time. It's - * enough to just (un)subscribe SET task when needed. - * TODO: figure out if this affects power consumption - */ - - /* Publish TIMER0->EVENTS_COMPARE4 */ - NRF_TIMER0_NS->PUBLISH_COMPARE[4] = DPPI_CH_PUB(TIMER0_EVENTS_COMPARE_4); - NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(TIMER0_EVENTS_COMPARE_4); - /* Publish RADIO->EVENTS_DISABLED */ - NRF_RADIO_NS->PUBLISH_DISABLED = DPPI_CH_PUB(RADIO_EVENTS_DISABLED); - NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK(RADIO_EVENTS_DISABLED); - -#if FEM_SINGLE_GPIO - fem_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); - NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[fem_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); - NRF_GPIOTE_NS->TASKS_CLR[fem_idx] = 1; -#else -#if MYNEWT_VAL(BLE_LL_FEM_PA) - fem_pa_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); - NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_pa_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[fem_pa_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); - NRF_GPIOTE_NS->TASKS_CLR[fem_pa_idx] = 1; -#endif -#if MYNEWT_VAL(BLE_LL_FEM_LNA) - fem_lna_idx = ble_phy_gpiote_configure(MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)); - NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_lna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); - NRF_GPIOTE_NS->SUBSCRIBE_CLR[fem_lna_idx] = DPPI_CH_SUB(RADIO_EVENTS_DISABLED); - NRF_GPIOTE_NS->TASKS_CLR[fem_lna_idx] = 1; -#endif -#endif - - NRF_DPPIC_NS->CHENSET = DPPI_CH_MASK_FEM; -#endif - - /* Set isr in vector table and enable interrupt */ -#ifndef RIOT_VERSION - NVIC_SetPriority(RADIO_IRQn, 0); -#endif -#if MYNEWT - NVIC_SetVector(RADIO_IRQn, (uint32_t)ble_phy_isr); -#else - ble_npl_hw_set_isr(RADIO_IRQn, ble_phy_isr); -#endif - NVIC_EnableIRQ(RADIO_IRQn); - - /* Register phy statistics */ - if (!g_ble_phy_data.phy_stats_initialized) { - rc = stats_init_and_reg(STATS_HDR(ble_phy_stats), - STATS_SIZE_INIT_PARMS(ble_phy_stats, - STATS_SIZE_32), - STATS_NAME_INIT_PARMS(ble_phy_stats), - "ble_phy"); - assert(rc == 0); - - g_ble_phy_data.phy_stats_initialized = 1; - } - - ble_phy_dbg_time_setup(); - - return 0; -} - -int -ble_phy_rx(void) -{ - /* - * Check radio state. - * - * In case radio is now disabling we'll wait for it to finish, but if for - * any reason it's just in idle state we proceed with RX as usual since - * nRF52 radio can ramp-up from idle state as well. - * - * Note that TX and RX states values are the same except for 3rd bit so we - * can make a shortcut here when checking for idle state. - */ - nrf_wait_disabled(); - if ((NRF_RADIO_NS->STATE != RADIO_STATE_STATE_Disabled) && - ((NRF_RADIO_NS->STATE & 0x07) != RADIO_STATE_STATE_RxIdle)) { - ble_phy_disable(); - STATS_INC(ble_phy_stats, radio_state_errs); - return BLE_PHY_ERR_RADIO_STATE; - } - - /* Make sure all interrupts are disabled */ - NRF_RADIO_NS->INTENCLR = NRF_RADIO_IRQ_MASK_ALL; - - /* Clear events prior to enabling receive */ - NRF_RADIO_NS->EVENTS_END = 0; - NRF_RADIO_NS->EVENTS_DISABLED = 0; - - /* Setup for rx */ - ble_phy_rx_xcvr_setup(); - - /* task to start RX should be subscribed here */ - assert(NRF_RADIO_NS->SUBSCRIBE_RXEN & DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0)); - - return 0; -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -void -ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key, - uint8_t is_central) -{ - memcpy(nrf_ccm_data.key, key, 16); - nrf_ccm_data.pkt_counter = pkt_counter; - memcpy(nrf_ccm_data.iv, iv, 8); - nrf_ccm_data.dir_bit = is_central; - g_ble_phy_data.phy_encrypted = 1; - /* Enable the module (AAR cannot be on while CCM on) */ - NRF_AAR_NS->ENABLE = AAR_ENABLE_ENABLE_Disabled; - NRF_CCM_NS->ENABLE = CCM_ENABLE_ENABLE_Enabled; -} - -void -ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir) -{ - nrf_ccm_data.pkt_counter = pkt_counter; - nrf_ccm_data.dir_bit = dir; -} - -void -ble_phy_encrypt_disable(void) -{ - NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - NRF_CCM_NS->TASKS_STOP = 1; - NRF_CCM_NS->EVENTS_ERROR = 0; - NRF_CCM_NS->ENABLE = CCM_ENABLE_ENABLE_Disabled; - - g_ble_phy_data.phy_encrypted = 0; -} -#endif - -void -ble_phy_set_txend_cb(ble_phy_tx_end_func txend_cb, void *arg) -{ - /* Set transmit end callback and arg */ - g_ble_phy_data.txend_cb = txend_cb; - g_ble_phy_data.txend_arg = arg; -} - -int -ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) -{ - int rc; - - ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_TX, cputime, rem_usecs); - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_tx_phy_mode); -#endif - - /* XXX: This should not be necessary, but paranoia is good! */ - /* Clear timer0 compare to RXEN since we are transmitting */ - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - - if (ble_phy_set_start_time(cputime, rem_usecs, true) != 0) { - STATS_INC(ble_phy_stats, tx_late); - ble_phy_disable(); - rc = BLE_PHY_ERR_TX_LATE; - } else { - /* Enable PPI to automatically start TXEN */ - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - rc = 0; - - ble_phy_fem_enable_pa(); - } - return rc; -} - -int -ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) -{ - bool late = false; - int rc = 0; - - ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_RX, cputime, rem_usecs); - -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) - ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); -#endif - - /* XXX: This should not be necessary, but paranoia is good! */ - /* Clear timer0 compare to TXEN since we are transmitting */ - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - - if (ble_phy_set_start_time(cputime, rem_usecs, false) != 0) { - STATS_INC(ble_phy_stats, rx_late); - - /* We're late so let's just try to start RX as soon as possible */ - ble_phy_set_start_now(); - - late = true; - } - - /* Enable PPI to automatically start RXEN */ - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - - ble_phy_fem_enable_lna(); - - /* Start rx */ - rc = ble_phy_rx(); - - /* - * If we enabled receiver but were late, let's return proper error code so - * caller can handle this. - */ - if (!rc && late) { - rc = BLE_PHY_ERR_RX_LATE; - } - - return rc; -} - -int -ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) -{ - int rc; - uint8_t *dptr; - uint8_t *pktptr; - uint8_t payload_len; - uint8_t hdr_byte; - uint32_t state; - uint32_t shortcuts; - - if (g_ble_phy_data.phy_transition_late) { - ble_phy_disable(); - STATS_INC(ble_phy_stats, tx_late); - return BLE_PHY_ERR_TX_LATE; - } - - /* - * This check is to make sure that the radio is not in a state where - * it is moving to disabled state. If so, let it get there. - */ - nrf_wait_disabled(); - - /* - * XXX: Although we may not have to do this here, I clear all the PPI - * that should not be used when transmitting. Some of them are only enabled - * if encryption and/or privacy is on, but I dont care. Better to be - * paranoid, and if you are going to clear one, might as well clear them - * all. - */ - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); - NRF_AAR_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RADIO_EVENTS_BCMATCH); - NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (g_ble_phy_data.phy_encrypted) { - dptr = (uint8_t *)&g_ble_phy_enc_buf[0]; - pktptr = (uint8_t *)&g_ble_phy_tx_buf[0]; - NRF_CCM_NS->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; - NRF_CCM_NS->INPTR = (uint32_t)dptr; - NRF_CCM_NS->OUTPTR = (uint32_t)pktptr; - NRF_CCM_NS->SCRATCHPTR = (uint32_t)&nrf_encrypt_scratchpad[0]; - NRF_CCM_NS->EVENTS_ERROR = 0; - NRF_CCM_NS->MODE = CCM_MODE_LENGTH_Msk | ble_phy_get_ccm_datarate(); - NRF_CCM_NS->CNFPTR = (uint32_t)&nrf_ccm_data; - } else { -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - NRF_AAR_NS->IRKPTR = (uint32_t)&g_nrf_irk_list[0]; -#endif - dptr = (uint8_t *)&g_ble_phy_tx_buf[0]; - pktptr = dptr; - } -#else - dptr = (uint8_t *)&g_ble_phy_tx_buf[0]; - pktptr = dptr; -#endif - - /* Set PDU payload */ - payload_len = pducb(&dptr[3], pducb_arg, &hdr_byte); - - /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */ - dptr[0] = hdr_byte; - dptr[1] = payload_len; - dptr[2] = 0; - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - /* Start key-stream generation and encryption (via short) */ - if (g_ble_phy_data.phy_encrypted) { - NRF_CCM_NS->TASKS_KSGEN = 1; - } -#endif - - NRF_RADIO_NS->PACKETPTR = (uint32_t)pktptr; - - /* Clear the ready, end and disabled events */ - NRF_RADIO_NS->EVENTS_READY = 0; - NRF_RADIO_NS->EVENTS_END = 0; - NRF_RADIO_NS->EVENTS_DISABLED = 0; - - /* Enable shortcuts for transmit start/end. */ - shortcuts = RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_READY_START_Msk; - NRF_RADIO_NS->SHORTS = shortcuts; - NRF_RADIO_NS->INTENSET = RADIO_INTENSET_DISABLED_Msk; - - /* Set the PHY transition */ - g_ble_phy_data.phy_transition = end_trans; - - /* Set transmitted payload length */ - g_ble_phy_data.phy_tx_pyld_len = payload_len; - - /* If we already started transmitting, abort it! */ - state = NRF_RADIO_NS->STATE; - if (state != RADIO_STATE_STATE_Tx) { - /* Set phy state to transmitting and count packet statistics */ - g_ble_phy_data.phy_state = BLE_PHY_STATE_TX; - STATS_INC(ble_phy_stats, tx_good); - STATS_INCN(ble_phy_stats, tx_bytes, payload_len + BLE_LL_PDU_HDR_LEN); - rc = BLE_ERR_SUCCESS; - } else { - ble_phy_disable(); - STATS_INC(ble_phy_stats, tx_late); - rc = BLE_PHY_ERR_RADIO_STATE; - } - - return rc; -} - -int -ble_phy_txpwr_set(int dbm) -{ - /* "Rail" power level if outside supported range */ - dbm = ble_phy_txpower_round(dbm); - - NRF_RADIO_NS->TXPOWER = dbm; - g_ble_phy_data.phy_txpwr_dbm = dbm; - - return 0; -} - -int -ble_phy_txpower_round(int dbm) -{ - /* "Rail" power level if outside supported range */ - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_0dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_0dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg1dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg1dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg2dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg2dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg3dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg3dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg4dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg5dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg5dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg6dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg6dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg7dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg7dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg16dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg16dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm; - } - - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm; - } - - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm; -} - -static int -ble_phy_set_access_addr(uint32_t access_addr) -{ - NRF_RADIO_NS->BASE0 = (access_addr << 8); - NRF_RADIO_NS->PREFIX0 = (NRF_RADIO_NS->PREFIX0 & 0xFFFFFF00) | (access_addr >> 24); - - g_ble_phy_data.phy_access_address = access_addr; - - return 0; -} - -int -ble_phy_txpwr_get(void) -{ - return g_ble_phy_data.phy_txpwr_dbm; -} - -void -ble_phy_set_rx_pwr_compensation(int8_t compensation) -{ - g_ble_phy_data.rx_pwr_compensation = compensation; -} - -int -ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit) -{ - assert(chan < BLE_PHY_NUM_CHANS); - - /* Check for valid channel range */ - if (chan >= BLE_PHY_NUM_CHANS) { - return BLE_PHY_ERR_INV_PARAM; - } - - /* Set current access address */ - ble_phy_set_access_addr(access_addr); - - /* Configure crcinit */ - NRF_RADIO_NS->CRCINIT = crcinit; - - /* Set the frequency and the data whitening initial value */ - g_ble_phy_data.phy_chan = chan; - NRF_RADIO_NS->FREQUENCY = g_ble_phy_chan_freq[chan]; - NRF_RADIO_NS->DATAWHITEIV = chan; - - return 0; -} - -/** - * Stop the timer used to count microseconds when using RTC for cputime - */ -static void -ble_phy_stop_usec_timer(void) -{ - NRF_TIMER0_NS->TASKS_STOP = 1; - NRF_TIMER0_NS->TASKS_SHUTDOWN = 1; - NRF_RTC0_NS->EVTENCLR = RTC_EVTENSET_COMPARE0_Msk; -} - -/** - * ble phy disable irq and ppi - * - * This routine is to be called when reception was stopped due to either a - * wait for response timeout or a packet being received and the phy is to be - * restarted in receive mode. Generally, the disable routine is called to stop - * the phy. - */ -static void -ble_phy_disable_irq_and_ppi(void) -{ - NRF_RADIO_NS->INTENCLR = NRF_RADIO_IRQ_MASK_ALL; - NRF_RADIO_NS->SHORTS = 0; - NRF_RADIO_NS->TASKS_DISABLE = 1; - - NRF_TIMER0_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RTC0_EVENTS_COMPARE_0); - NRF_TIMER0_NS->SUBSCRIBE_CAPTURE[3] = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - NRF_RADIO_NS->SUBSCRIBE_DISABLE = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_3); - NRF_RADIO_NS->SUBSCRIBE_TXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_0); - NRF_AAR_NS->SUBSCRIBE_START = DPPI_CH_UNSUB(RADIO_EVENTS_BCMATCH); - NRF_CCM_NS->SUBSCRIBE_CRYPT = DPPI_CH_UNSUB(RADIO_EVENTS_ADDRESS); - -#if FEM_SINGLE_GPIO - NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_idx] = DPPI_CH_UNSUB(RADIO_EVENTS_READY); -#else -#if MYNEWT_VAL(BLE_LL_FEM_PA) - NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_pa_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); -#endif -#if MYNEWT_VAL(BLE_LL_FEM_LNA) - NRF_GPIOTE_NS->SUBSCRIBE_SET[fem_lna_idx] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_4); -#endif -#endif - - NVIC_ClearPendingIRQ(RADIO_IRQn); - g_ble_phy_data.phy_state = BLE_PHY_STATE_IDLE; -} - -void -ble_phy_restart_rx(void) -{ - ble_phy_stop_usec_timer(); - ble_phy_disable_irq_and_ppi(); - - ble_phy_set_start_now(); - /* Enable PPI to automatically start RXEN */ - NRF_RADIO_NS->SUBSCRIBE_RXEN = DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_0); - - ble_phy_rx(); -} - -static void -ble_phy_dbg_clear_pins(void) -{ -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0 - NRF_GPIOTE_NS->TASKS_CLR[phy_dbg_txrxen_ready_idx] = 1; -#endif -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0 - NRF_GPIOTE_NS->TASKS_CLR[phy_dbg_address_end_idx] = 1; -#endif -#if MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0 - NRF_GPIOTE_NS->TASKS_CLR[phy_dbg_wfr_idx] = 1; -#endif -} - -void -ble_phy_disable(void) -{ - ble_phy_trace_void(BLE_PHY_TRACE_ID_DISABLE); - - ble_phy_stop_usec_timer(); - ble_phy_disable_irq_and_ppi(); - ble_phy_fem_force_disable(); - ble_phy_dbg_clear_pins(); -} - -uint32_t -ble_phy_access_addr_get(void) -{ - return g_ble_phy_data.phy_access_address; -} - -int -ble_phy_state_get(void) -{ - return g_ble_phy_data.phy_state; -} - -int -ble_phy_rx_started(void) -{ - return g_ble_phy_data.phy_rx_started; -} - -uint8_t -ble_phy_xcvr_state_get(void) -{ - uint32_t state; - state = NRF_RADIO_NS->STATE; - return (uint8_t)state; -} - -uint8_t -ble_phy_max_data_pdu_pyld(void) -{ - return BLE_LL_DATA_PDU_MAX_PYLD; -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) -void -ble_phy_resolv_list_enable(void) -{ - NRF_AAR_NS->NIRK = (uint32_t)g_nrf_num_irks; - g_ble_phy_data.phy_privacy = 1; -} - -void -ble_phy_resolv_list_disable(void) -{ - g_ble_phy_data.phy_privacy = 0; -} -#endif - -#if MYNEWT_VAL(BLE_LL_DTM) -void -ble_phy_enable_dtm(void) -{ - /* When DTM is enabled we need to disable whitening as per - * Bluetooth v5.0 Vol 6. Part F. 4.1.1 - */ - NRF_RADIO_NS->PCNF1 &= ~RADIO_PCNF1_WHITEEN_Msk; -} - -void -ble_phy_disable_dtm(void) -{ - /* Enable whitening */ - NRF_RADIO_NS->PCNF1 |= RADIO_PCNF1_WHITEEN_Msk; -} -#endif - -void -ble_phy_rfclk_enable(void) -{ -#if MYNEWT - nrf5340_net_clock_hfxo_request(); -#else - NRF_CLOCK_NS->TASKS_HFCLKSTART = 1; -#endif -} - -void -ble_phy_rfclk_disable(void) -{ -#if MYNEWT - nrf5340_net_clock_hfxo_release(); -#else - NRF_CLOCK_NS->TASKS_HFCLKSTOP = 1; -#endif -} diff --git a/nimble/drivers/nrf5340/src/ble_phy_trace.c b/nimble/drivers/nrf5340/src/ble_phy_trace.c deleted file mode 100644 index dad7867907..0000000000 --- a/nimble/drivers/nrf5340/src/ble_phy_trace.c +++ /dev/null @@ -1,45 +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. - */ - -#include -#include -#include -#include "controller/ble_phy_trace.h" - -#if MYNEWT_VAL(BLE_PHY_SYSVIEW) - -static os_trace_module_t g_ble_phy_trace_mod; -uint32_t ble_phy_trace_off; - -static void -ble_phy_trace_module_send_desc(void) -{ - os_trace_module_desc(&g_ble_phy_trace_mod, "0 phy_set_tx cputime=%u usecs=%u"); - os_trace_module_desc(&g_ble_phy_trace_mod, "1 phy_set_rx cputime=%u usecs=%u"); - os_trace_module_desc(&g_ble_phy_trace_mod, "2 phy_disable"); -} - -void -ble_phy_trace_init(void) -{ - ble_phy_trace_off = - os_trace_module_register(&g_ble_phy_trace_mod, "ble_phy", 3, - ble_phy_trace_module_send_desc); -} -#endif diff --git a/nimble/drivers/nrf5340/syscfg.yml b/nimble/drivers/nrf5340/syscfg.yml deleted file mode 100644 index ed82f6d604..0000000000 --- a/nimble/drivers/nrf5340/syscfg.yml +++ /dev/null @@ -1,62 +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. -# - -syscfg.defs: - BLE_PHY_SYSVIEW: - description: > - Enable SystemView tracing module for radio driver. - value: 0 - - BLE_PHY_DBG_TIME_TXRXEN_READY_PIN: - description: > - When set to proper GPIO pin number, this pin will be set - to high state when radio is enabled (TASKS_TXEN or TASKS_RXEN) - and back to low state on radio EVENTS_READY. - This can be used to measure radio ram-up time. - - Note: - GPIO control for selected pin needs to be assigned to Network - Core, configure IPC_NRF5340_NET_GPIO in ipc_nrf5340 driver on - Application Core. - value: -1 - - BLE_PHY_DBG_TIME_ADDRESS_END_PIN: - description: > - When set to proper GPIO pin number, this pin will be set - to high state on radio EVENTS_ADDRESS and back to low state - on radio EVENTS_END. - This can be used to measure radio pipeline delays. - - Note: - GPIO control for selected pin needs to be assigned to Network - Core, configure IPC_NRF5340_NET_GPIO in ipc_nrf5340 driver on - Application Core. - value: -1 - - BLE_PHY_DBG_TIME_WFR_PIN: - description: > - When set to proper GPIO pin number, this pin will be set - to high state on radio EVENTS_RXREADY and back to low - state when wfr timer expires. - This can be used to check if wfr is calculated properly. - - Note: - GPIO control for selected pin needs to be assigned to Network - Core, configure IPC_NRF5340_NET_GPIO in ipc_nrf5340 driver on - Application Core. - value: -1 From ce36b50ae5efd3ceebf64c62a8ee5330802e3617 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 17 Sep 2022 23:19:01 +0200 Subject: [PATCH 0536/1333] babblesim: Update dependency to phy --- babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml b/babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml index 99e59a26c1..5e4279b32c 100644 --- a/babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/pkg.yml @@ -29,4 +29,4 @@ pkg.deps: - "babblesim/core" pkg.deps.BLE_CONTROLLER: - - "@apache-mynewt-nimble/nimble/drivers/nrf52" + - "@apache-mynewt-nimble/nimble/drivers/nrf5x" From 35583ac325d03136fce0801ef342d3a509502013 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 17 Sep 2022 23:19:30 +0200 Subject: [PATCH 0537/1333] babblesim: Print script errors to stderr --- babblesim/sdk/scripts/link_babblesim.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/babblesim/sdk/scripts/link_babblesim.sh b/babblesim/sdk/scripts/link_babblesim.sh index 9254a18a72..1c069eb34a 100755 --- a/babblesim/sdk/scripts/link_babblesim.sh +++ b/babblesim/sdk/scripts/link_babblesim.sh @@ -22,7 +22,7 @@ if [ -z ${BSIM_COMPONENTS_PATH+x} ]; then echo "This board requires the BabbleSim simulator. Please set" \ "the environment variable BSIM_COMPONENTS_PATH to point to its components" \ "folder. More information can be found in" \ - "https://babblesim.github.io/folder_structure_and_env.html" + "https://babblesim.github.io/folder_structure_and_env.html" 1>&2 exit 1 fi @@ -30,7 +30,7 @@ if [ -z ${BSIM_OUT_PATH+x} ]; then echo "This board requires the BabbleSim simulator. Please set" \ "the environment variable BSIM_OUT_PATH to point to the folder where the" \ "simulator is compiled to. More information can be found in" \ - "https://babblesim.github.io/folder_structure_and_env.html" + "https://babblesim.github.io/folder_structure_and_env.html" 1>&2 exit 1 fi From 8519ba4dc359a885903b8b820a86d5beae7c35a8 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 19 Sep 2022 12:44:41 +0200 Subject: [PATCH 0538/1333] nimble/phy: Make private functions static Some functions are never used by LL and can be considered private so let's make them static. --- nimble/controller/include/controller/ble_phy.h | 8 -------- nimble/drivers/dialog_cmac/src/ble_phy.c | 5 +++-- nimble/drivers/nrf51/src/ble_phy.c | 6 ++++++ nimble/drivers/nrf5x/src/ble_phy.c | 16 +++++++++++----- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index 69b259970d..5a989e2fb9 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -107,9 +107,6 @@ typedef uint8_t (*ble_phy_tx_pducb_t)(uint8_t *dptr, void *pducb_arg, /* Place the PHY into transmit mode */ int ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans); -/* Place the PHY into receive mode */ -int ble_phy_rx(void); - /* Copies the received PHY buffer into the allocated pdu */ void ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu); @@ -211,14 +208,9 @@ void ble_phy_resolv_list_disable(void); #define BLE_PHY_IDX_CODED (2) #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) || MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)) -uint32_t ble_phy_mode_pdu_start_off(int phy); void ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode); -#else -#define ble_phy_mode_pdu_start_off(phy) (40) - #endif -int ble_phy_get_cur_phy(void); static inline int ble_ll_phy_to_phy_mode(int phy, int phy_options) { int phy_mode; diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index 1e6a3c9999..077675a3ef 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -310,6 +310,7 @@ static bool ble_phy_rx_start_isr(void); static void ble_phy_rx_setup_fields(void); static void ble_phy_rx_setup_xcvr(void); static void ble_phy_mode_apply(uint8_t phy_mode); +static int ble_phy_get_cur_phy(void); void FIELD_IRQHandler(void) @@ -1012,7 +1013,7 @@ ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode) g_ble_phy_data.frame_offset_rxtx = g_ble_phy_frame_offset_rxtx[rxtx]; } -int +static int ble_phy_get_cur_phy(void) { #if (BLE_LL_BT5_PHY_SUPPORTED == 1) @@ -1327,7 +1328,7 @@ ble_phy_rx_setup_xcvr(void) g_ble_phy_data.phy_rx_started = 0; } -int +static int ble_phy_rx(void) { MCU_DIAG_SER('R'); diff --git a/nimble/drivers/nrf51/src/ble_phy.c b/nimble/drivers/nrf51/src/ble_phy.c index a74252b586..c0d827d7c6 100644 --- a/nimble/drivers/nrf51/src/ble_phy.c +++ b/nimble/drivers/nrf51/src/ble_phy.c @@ -47,6 +47,12 @@ #error LE Coded PHY cannot be enabled on nRF51 #endif +static uint32_t +ble_phy_mode_pdu_start_off(int phy_mode) +{ + return 40; +} + /* XXX: 4) Make sure RF is higher priority interrupt than schedule */ /* diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 52119d1ed3..5108c45697 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -152,7 +152,7 @@ struct ble_phy_obj uint16_t tifs; #endif }; -struct ble_phy_obj g_ble_phy_data; +static struct ble_phy_obj g_ble_phy_data; /* XXX: if 27 byte packets desired we can make this smaller */ /* Global transmit/receive buffer */ @@ -314,7 +314,7 @@ STATS_NAME_END(ble_phy_stats) //#define NRF_ENC_SCRATCH_WORDS (((MYNEWT_VAL(BLE_LL_MAX_PKT_SIZE) + 16) + 3) / 4) #define NRF_ENC_SCRATCH_WORDS (67) -uint32_t g_nrf_encrypt_scratchpad[NRF_ENC_SCRATCH_WORDS]; +static uint32_t g_nrf_encrypt_scratchpad[NRF_ENC_SCRATCH_WORDS]; struct nrf_ccm_data { @@ -331,7 +331,7 @@ struct nrf_ccm_data g_nrf_ccm_data; /* Packet start offset (in usecs). This is the preamble plus access address. * For LE Coded PHY this also includes CI and TERM1. */ -uint32_t +static uint32_t ble_phy_mode_pdu_start_off(int phy_mode) { return g_ble_phy_mode_pkt_start_off[phy_mode]; @@ -429,9 +429,15 @@ ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode) g_ble_phy_data.phy_tx_phy_mode = tx_phy_mode; g_ble_phy_data.phy_rx_phy_mode = rx_phy_mode; } +#else +static uint32_t +ble_phy_mode_pdu_start_off(int phy_mode) +{ + return 40; +} #endif -int +static int ble_phy_get_cur_phy(void) { #if (BLE_LL_BT5_PHY_SUPPORTED == 1) @@ -1610,7 +1616,7 @@ ble_phy_init(void) * * @return int 0: success; BLE Phy error code otherwise */ -int +static int ble_phy_rx(void) { /* From 0d7ae1bc1819e740adcbaf04c65895cdf97fb209 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 21 Sep 2022 14:01:04 +0200 Subject: [PATCH 0539/1333] nimble/phy/nrf5x: Enable LNA on "start now" rx LNA was not enabled properly if RX was started "now". --- nimble/drivers/nrf5x/src/ble_phy.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 5108c45697..dc9961567b 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -786,6 +786,10 @@ ble_phy_set_start_now(void) nrf_rtc_cc_set(NRF_RTC0, 0, now + 3); nrf_rtc_event_enable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); +#if PHY_USE_FEM_LNA + phy_fem_enable_lna(); +#endif + /* Enable PPI */ phy_ppi_rtc0_compare0_to_timer0_start_enable(); From d4f945d973eb8849a6c4f94a2a9b8ddef69c126c Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 22 Sep 2022 11:00:24 +0200 Subject: [PATCH 0540/1333] README: Add some notes about external projects using NimBLE Point to known external projects that use NimBLE. --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 40badbbd55..d5ddbec81e 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,15 @@ Implements a simple BLE peripheral that supports the Nordic UART / Serial Port Emulation service (https://developer.nordicsemi.com/nRF5_SDK/nRF51_SDK_v8.x.x/doc/8.0.0/s110/html/a00072.html). +## External projects using NimBLE + +Several other projects provide support for using NimBLE either by [NPL port](https://github.com/apache/mynewt-nimble/tree/master/porting) or forking: + + * [The Espressif ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/nimble/index.html) contains a NimBLE port for ESP-32 devices. + * [The RIOT](https://doc.riot-os.org/group__pkg__nimble.html) operating system contains a package for using NimBLE. + + If you publish a NimBLE port, please let us know to include it here! + # Getting Help If you are having trouble using or contributing to Apache Mynewt NimBLE, or just From 10beb51ea4ea93544187fb7676a7ca64ac4be240 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Wed, 21 Sep 2022 13:04:47 +0200 Subject: [PATCH 0541/1333] refactor: ble_gap_conn_broken can be private, make static --- nimble/host/src/ble_gap.c | 2 +- nimble/host/src/ble_gap_priv.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 0dcf93582d..d8a944a842 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -1113,7 +1113,7 @@ ble_gap_update_failed(uint16_t conn_handle, int status) } #endif -void +static void ble_gap_conn_broken(uint16_t conn_handle, int reason) { #if NIMBLE_BLE_CONNECT diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h index 06c4d16bf2..d6051b7305 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/nimble/host/src/ble_gap_priv.h @@ -143,7 +143,6 @@ void ble_gap_preempt_done(void); int ble_gap_terminate_with_conn(struct ble_hs_conn *conn, uint8_t hci_reason); void ble_gap_reset_state(int reason); -void ble_gap_conn_broken(uint16_t conn_handle, int reason); int32_t ble_gap_timer(void); int ble_gap_init(void); From 00d10c2d99872f12e015b2e07a44492c370d6f42 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Wed, 21 Sep 2022 13:07:18 +0200 Subject: [PATCH 0542/1333] refactor: move ble_hs_misc_null_addr to only usage, make static --- nimble/host/src/ble_hs_id.c | 2 ++ nimble/host/src/ble_hs_misc.c | 2 -- nimble/host/src/ble_hs_priv.h | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/nimble/host/src/ble_hs_id.c b/nimble/host/src/ble_hs_id.c index e8b6c8b630..bd50e20171 100644 --- a/nimble/host/src/ble_hs_id.c +++ b/nimble/host/src/ble_hs_id.c @@ -23,6 +23,8 @@ static uint8_t ble_hs_id_pub[6]; static uint8_t ble_hs_id_rnd[6]; +static const uint8_t ble_hs_misc_null_addr[6]; + void ble_hs_id_set_pub(const uint8_t *pub_addr) diff --git a/nimble/host/src/ble_hs_misc.c b/nimble/host/src/ble_hs_misc.c index dfb46b7414..c016ce75eb 100644 --- a/nimble/host/src/ble_hs_misc.c +++ b/nimble/host/src/ble_hs_misc.c @@ -22,8 +22,6 @@ #include "os/os.h" #include "ble_hs_priv.h" -const uint8_t ble_hs_misc_null_addr[6]; - int ble_hs_misc_conn_chan_find(uint16_t conn_handle, uint16_t cid, struct ble_hs_conn **out_conn, diff --git a/nimble/host/src/ble_hs_priv.h b/nimble/host/src/ble_hs_priv.h index 044b30cc91..d8949cbc98 100644 --- a/nimble/host/src/ble_hs_priv.h +++ b/nimble/host/src/ble_hs_priv.h @@ -94,8 +94,6 @@ extern struct os_mbuf_pool ble_hs_mbuf_pool; extern uint8_t ble_hs_sync_state; extern uint8_t ble_hs_enabled_state; -extern const uint8_t ble_hs_misc_null_addr[6]; - extern uint16_t ble_hs_max_attrs; extern uint16_t ble_hs_max_services; extern uint16_t ble_hs_max_client_configs; From 0cdfaa8622ada0b22ea28c38b9c64a5b8f2008a6 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Wed, 21 Sep 2022 14:47:05 +0200 Subject: [PATCH 0543/1333] fix: make include cm4 dependant on SERIES, not MYNEWT only --- nimble/drivers/nrf5x/src/ble_hw.c | 2 ++ nimble/drivers/nrf5x/src/ble_phy.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/nimble/drivers/nrf5x/src/ble_hw.c b/nimble/drivers/nrf5x/src/ble_hw.c index 0accbbf40e..9a46fa6c85 100644 --- a/nimble/drivers/nrf5x/src/ble_hw.c +++ b/nimble/drivers/nrf5x/src/ble_hw.c @@ -30,7 +30,9 @@ #if MYNEWT #include "mcu/cmsis_nvic.h" #else +#ifdef NRF52_SERIES #include "core_cm4.h" +#endif #include #endif #include "os/os_trace_api.h" diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index dc9961567b..84f60cefab 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -48,8 +48,11 @@ #include "mcu/cmsis_nvic.h" #include "hal/hal_gpio.h" #else +#include +#ifdef NRF52_SERIES #include "core_cm4.h" #endif +#endif #include #include "phy_priv.h" From d3dc966fc7e962338745c8677f383b497dd745c1 Mon Sep 17 00:00:00 2001 From: Jakub Rotkiewicz Date: Mon, 26 Sep 2022 10:10:59 +0200 Subject: [PATCH 0544/1333] nimble/host: fix l2cap coc rx endpoint buffs alloc Dissallow current vs next sdu index check when only one buffer is used. --- nimble/host/src/ble_l2cap_coc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c index 875dbeba07..c9d7b61bee 100644 --- a/nimble/host/src/ble_l2cap_coc.c +++ b/nimble/host/src/ble_l2cap_coc.c @@ -604,7 +604,8 @@ ble_l2cap_coc_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx) } if (chan->coc_rx.sdus[0] != NULL && - chan->coc_rx.next_sdu_alloc_idx == chan->coc_rx.current_sdu_idx) { + chan->coc_rx.next_sdu_alloc_idx == chan->coc_rx.current_sdu_idx && + BLE_L2CAP_SDU_BUFF_CNT != 1) { return BLE_HS_EBUSY; } From 154bdd46acadee8bb1fc6f28535fdf8a9fa61004 Mon Sep 17 00:00:00 2001 From: Jakub Rotkiewicz Date: Mon, 26 Sep 2022 10:12:55 +0200 Subject: [PATCH 0545/1333] btshell and blestress: update l2cap coc rx buffers Updated apps to support setting the RX SDU buffers number. --- apps/blestress/src/stress.c | 10 ++++++---- apps/blestress/syscfg.yml | 3 +++ apps/btshell/src/main.c | 16 +++++++++++----- apps/btshell/syscfg.yml | 3 +++ 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/apps/blestress/src/stress.c b/apps/blestress/src/stress.c index 1bdbafa9ec..1a9cb0c0d9 100644 --- a/apps/blestress/src/stress.c +++ b/apps/blestress/src/stress.c @@ -167,11 +167,13 @@ stress_l2cap_coc_accept(uint16_t peer_mtu, struct ble_l2cap_chan *chan) console_printf("LE CoC accepting, chan: 0x%08lx, peer_mtu %d\n", (uint32_t) chan, peer_mtu); - sdu_rx = os_msys_get_pkthdr(STRESS_COC_MTU, 0); - assert(sdu_rx != NULL); + for (int i = 0; i < MYNEWT_VAL(BLE_L2CAP_COC_SDU_BUFF_COUNT); i++) { + sdu_rx = os_msys_get_pkthdr(STRESS_COC_MTU, 0); + assert(sdu_rx != NULL); - rc = ble_l2cap_recv_ready(chan, sdu_rx); - assert(rc == 0); + rc = ble_l2cap_recv_ready(chan, sdu_rx); + assert(rc == 0); + } } void diff --git a/apps/blestress/syscfg.yml b/apps/blestress/syscfg.yml index 3acf280bb1..ce50050c7c 100644 --- a/apps/blestress/syscfg.yml +++ b/apps/blestress/syscfg.yml @@ -67,6 +67,9 @@ syscfg.vals: # BLE_L2CAP_COC_MAX_NUM: 2 + # L2CAP COC SDU buffers in RX endpoint + BLE_L2CAP_COC_SDU_BUFF_COUNT: 1 + # Enable 2M PHY BLE_LL_CFG_FEAT_LE_2M_PHY: 1 diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index 7bea9067f3..2df3719117 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -2224,19 +2224,25 @@ btshell_l2cap_coc_recv(struct ble_l2cap_chan *chan, struct os_mbuf *sdu) static int btshell_l2cap_coc_accept(uint16_t conn_handle, uint16_t peer_mtu, - struct ble_l2cap_chan *chan) + struct ble_l2cap_chan *chan) { struct os_mbuf *sdu_rx; + int rc; console_printf("LE CoC accepting, chan: 0x%08lx, peer_mtu %d\n", (uint32_t) chan, peer_mtu); - sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); - if (!sdu_rx) { - return BLE_HS_ENOMEM; + for (int i = 0; i < MYNEWT_VAL(BLE_L2CAP_COC_SDU_BUFF_COUNT); i++) { + sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); + if (!sdu_rx) { + return BLE_HS_ENOMEM; + } + + rc = ble_l2cap_recv_ready(chan, sdu_rx); + assert(rc == 0); } - return ble_l2cap_recv_ready(chan, sdu_rx); + return rc; } static void diff --git a/apps/btshell/syscfg.yml b/apps/btshell/syscfg.yml index 1535b336d9..b9dfa875d5 100644 --- a/apps/btshell/syscfg.yml +++ b/apps/btshell/syscfg.yml @@ -41,5 +41,8 @@ syscfg.vals: # Whether to save data to sys/config, or just keep it in RAM. BLE_STORE_CONFIG_PERSIST: 0 + # L2CAP COC SDU buffers in RX endpoint + BLE_L2CAP_COC_SDU_BUFF_COUNT: 1 + syscfg.vals.BLE_MESH: MSYS_1_BLOCK_COUNT: 16 From d21a386e96508928a78a533fedfe6d2497800461 Mon Sep 17 00:00:00 2001 From: Hang Fan Date: Tue, 27 Sep 2022 12:37:21 +0800 Subject: [PATCH 0546/1333] porting/examples: Fix build error Add default macro of MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT to avoid build error. --- porting/examples/linux/include/syscfg/syscfg.h | 4 ++++ porting/examples/linux_blemesh/include/syscfg/syscfg.h | 4 ++++ porting/examples/nuttx/include/syscfg/syscfg.h | 4 ++++ porting/nimble/include/syscfg/syscfg.h | 4 ++++ porting/npl/riot/include/syscfg/syscfg.h | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index 3ba53c20e5..cfffe63884 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -723,6 +723,10 @@ #define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) #endif +#ifndef MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT +#define MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT (1) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS #define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1) #endif diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 019cafac7d..a7cc7de5df 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -724,6 +724,10 @@ #define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) #endif +#ifndef MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT +#define MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT (1) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS #define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1) #endif diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index 040a1b3d60..b257c9f915 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -723,6 +723,10 @@ #define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) #endif +#ifndef MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT +#define MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT (1) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS #define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1) #endif diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index 7eb0856daf..6f8710be7b 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -722,6 +722,10 @@ #define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) #endif +#ifndef MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT +#define MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT (1) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS #define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1) #endif diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index c4055db29d..280fac615e 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1503,6 +1503,10 @@ #define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) #endif +#ifndef MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT +#define MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT (1) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS #define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1) #endif From 14292897975d2874d489e01cb9ae24fc8ed35c8b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 26 Sep 2022 14:10:19 +0200 Subject: [PATCH 0547/1333] nimble/ll: Fix skipping chain pdus Since chain pdus are scheduled from LL while previous aux/chain pdu is already in scheduler, it's possible that previous pdu will be already processed before LL can schedule chain. In such case previous pdu will be sent with AuxPtr offset=0 and we should simply drop subseqent pdus. --- nimble/controller/src/ble_ll_adv.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index edca7527b3..c26e852116 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -63,6 +63,7 @@ struct ble_ll_adv_aux { uint8_t ext_hdr_flags; uint8_t data_len; uint8_t payload_len; + uint8_t auxptr_zero; }; /* Scheduling data for sync PDUs */ @@ -74,6 +75,7 @@ struct ble_ll_adv_sync { uint8_t ext_hdr_flags; uint8_t data_len; uint8_t payload_len; + uint8_t auxptr_zero; }; /* @@ -784,6 +786,8 @@ ble_ll_adv_aux_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) offset = ble_ll_tmr_t2u(AUX_NEXT(advsm)->start_time - aux->start_time); } + aux->auxptr_zero = offset == 0; + ble_ll_adv_put_aux_ptr(AUX_NEXT(advsm)->chan, advsm->sec_phy, offset, dptr); @@ -1586,13 +1590,12 @@ ble_ll_adv_aux_schedule_next(struct ble_ll_adv_sm *advsm) sch->end_time = aux_next->start_time + ble_ll_tmr_u2t_up(max_usecs); ble_ll_sched_adv_new(&aux_next->sch, ble_ll_adv_aux_scheduled, aux_next); - /* - * In case duration is set for advertising set we need to check if newly - * scheduled aux will fit inside duration. If not, remove it from scheduler - * so advertising will stop after current aux. + /* Remove aux if previous one was already sent with zero offset or new one + * is scheduled past advertising duration (if set). */ - if (advsm->duration && - LL_TMR_GT(aux_next->sch.end_time, advsm->adv_end_time)) { + if (aux->auxptr_zero || + (advsm->duration && LL_TMR_GT(aux_next->sch.end_time, + advsm->adv_end_time))) { ble_ll_sched_rmv_elem(&aux_next->sch); } } @@ -1615,6 +1618,7 @@ ble_ll_adv_aux_schedule_first(struct ble_ll_adv_sm *advsm) advsm->aux_dropped = 0; aux = AUX_CURRENT(advsm); + aux->auxptr_zero = 0; ble_ll_adv_aux_calculate(advsm, aux, 0); /* Set end time to maximum time this schedule item may take */ @@ -2144,6 +2148,8 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) sync->start_time); } + sync->auxptr_zero = offset == 0; + ble_ll_adv_put_aux_ptr(SYNC_NEXT(advsm)->chan, advsm->sec_phy, offset, dptr); @@ -2363,6 +2369,7 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm, advsm->periodic_sync_index = 0; sync = SYNC_CURRENT(advsm); + sync->auxptr_zero = 0; /* For first SYNC packet in chain we use separate CSA#2 state to maintain * freq hopping as advertised in SyncInfo @@ -2481,12 +2488,14 @@ ble_ll_adv_periodic_schedule_next(struct ble_ll_adv_sm *advsm) ble_ll_sched_adv_new(&sync_next->sch, ble_ll_adv_sync_next_scheduled, sync_next); - /* if we are pass advertising interval, drop chain */ - if (LL_TMR_GT(sch->end_time, advsm->periodic_adv_event_start_time + - advsm->periodic_adv_itvl_ticks)) { + /* Remove aux if previous one was already sent with zero offset or new one + * is scheduled past advertising interval. + */ + if (sync->auxptr_zero || + (LL_TMR_GT(sch->end_time, advsm->periodic_adv_event_start_time + + advsm->periodic_adv_itvl_ticks))) { STATS_INC(ble_ll_stats, periodic_chain_drop_event); ble_ll_sched_rmv_elem(&sync->sch); - ble_ll_event_add(&advsm->adv_periodic_txdone_ev); } } From 465ffa69b8e402989b9c1a08090b269261abbd74 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 22 Sep 2022 17:21:58 +0200 Subject: [PATCH 0548/1333] nimble/ll: Fix initiator on aux with RPA and no peer IRK This is follow up on 8447ec2969. We allow peer RPA to be used in the same way as identity address if we do not have peer IRK, so we also need to update checks for AUX_CONNECT_RSP. --- nimble/controller/src/ble_ll_scan_aux.c | 41 +++++++++++++------------ 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index ed69055b1c..23f4986eb1 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -1502,6 +1502,7 @@ ble_ll_scan_aux_check_connect_rsp(uint8_t *rxbuf, #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) struct ble_ll_resolv_entry *rl = NULL; #endif + uint8_t match_adva = 1; pdu_hdr = rxbuf[0]; pdu_len = rxbuf[1]; @@ -1534,34 +1535,34 @@ ble_ll_scan_aux_check_connect_rsp(uint8_t *rxbuf, targeta_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_RXADD_RAND); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - /* If we have IRK for peer and AdvA is an RPA, we need to check if current - * RPA resolves using that IRK. This is to verify AdvA in case RPS changed - * due to timeout or AdvA in advertising was an identity address but is an - * RPA in AUX_CONNECT_RSP. - * Otherwise, it shall be the same as in AUX_CONNECT_REQ. + /* If AdvA is an RPA and we have peer IRK, we need to check if it resolves + * using that RPA because peer can change RPA between advertising PDU and + * AUX_CONNECT_RSP. In other case, we expect AdvA to be the same as in + * advertising PDU. */ if ((addrd->rpa_index >= 0) && ble_ll_is_rpa(adva, adva_type)) { rl = &g_ble_ll_resolv_list[addrd->rpa_index]; - if (!ble_ll_resolv_rpa(adva, rl->rl_peer_irk)) { - return -1; - } + if (rl->rl_has_peer) { + if (!ble_ll_resolv_rpa(adva, rl->rl_peer_irk)) { + return -1; + } - addrd->adva_resolved = 1; - addrd->adva = adva; - addrd->adva_type = adva_type; - } else if ((adva_type != - !!(pdu_data->hdr_byte & BLE_ADV_PDU_HDR_RXADD_MASK)) || - (memcmp(adva, pdu_data->adva, 6) != 0)) { - return -1; - } -#else - if ((adva_type != !!(pdu_data->hdr_byte & BLE_ADV_PDU_HDR_RXADD_MASK)) || - (memcmp(adva, pdu_data->adva, 6) != 0)) { - return -1; + addrd->adva_resolved = 1; + addrd->adva = adva; + addrd->adva_type = adva_type; + + match_adva = 0; + } } #endif /* BLE_LL_CFG_FEAT_LL_PRIVACY */ + if (match_adva && + ((adva_type != !!(pdu_data->hdr_byte & BLE_ADV_PDU_HDR_RXADD_MASK)) || + (memcmp(adva, pdu_data->adva, 6) != 0))) { + return -1; + } + if ((targeta_type != !!(pdu_data->hdr_byte & BLE_ADV_PDU_HDR_TXADD_MASK)) || (memcmp(targeta, pdu_data->inita, 6) != 0)) { return -1; From d7ae17e2ebff7d0f6ec09f34af81f9700f06a64b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 22 Sep 2022 20:24:09 +0200 Subject: [PATCH 0549/1333] nimble/ll: Fix failed CRC on AUX_CONNECT_RSP If CRC does not match on AUX_CONNECT_RSP, we should cancel already scheduled connection as otherwise there will be spurious connection timeout as scheduler will run uninitialized connection. --- nimble/controller/src/ble_ll_scan_aux.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 23f4986eb1..01e516fde7 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -1583,6 +1583,9 @@ ble_ll_scan_aux_rx_pkt_in_for_initiator(struct os_mbuf *rxpdu, aux = rxinfo->user_data; if (rxinfo->flags & BLE_MBUF_HDR_F_IGNORED) { + if (aux->flags & BLE_LL_SCAN_AUX_F_W4_CONNECT_RSP) { + ble_ll_conn_send_connect_req_cancel(); + } ble_ll_scan_aux_free(aux); ble_ll_scan_chk_resume(); return; From b36ce21bc1929883962a501416278228b08730b4 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Mon, 26 Sep 2022 14:48:14 +0200 Subject: [PATCH 0550/1333] host: Add defines for Key Distribution settings Add key distribution masks defines. This can be used to initialize sm_our_key_dist and sm_their_key_dist fields in ble_hs_cfg struct. --- nimble/host/include/host/ble_hs.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/nimble/host/include/host/ble_hs.h b/nimble/host/include/host/ble_hs.h index 6c2acfd4d5..e1dff5e006 100644 --- a/nimble/host/include/host/ble_hs.h +++ b/nimble/host/include/host/ble_hs.h @@ -165,6 +165,25 @@ extern "C" { /** KeyboardDisplay Only IO capability */ #define BLE_HS_IO_KEYBOARD_DISPLAY 0x04 +/** + * @} + */ + +/** + * @brief LE key distribution + * @defgroup bt_host_key_dist LE key distribution + * + * @{ + */ + +/** Distibute LTK */ +#define BLE_HS_KEY_DIST_ENC_KEY 0x01 + +/** Distribute IRK */ +#define BLE_HS_KEY_DIST_ID_KEY 0x02 + +/** CSRK distibution and LinkKey are not supported */ + /** * @} */ From ef03c7c1c6a6efdd252b6931bf7c75a99b23c23f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 28 Sep 2022 23:49:54 +0200 Subject: [PATCH 0551/1333] nimble/ll: Always send assert vs event if enabled We should always send assert vs event if enabled, regardless if we'll break due to attached debugger or not. This is useful when using monitor over RTT since using RTT means debugger is attached even though we may not actually have sw debugger running. --- nimble/controller/src/ble_ll.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index d394bc4f76..d9f3955eee 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1742,10 +1742,10 @@ ble_ll_is_addr_empty(const uint8_t *addr) void ble_ll_assert(const char *file, unsigned line) { + ble_ll_hci_ev_send_vs_assert(file, line); + if (hal_debugger_connected()) { __BKPT(0); - } else { - ble_ll_hci_ev_send_vs_assert(file, line); \ } while (1); From 9257bfecf20f413ad3c3da540b22d319105cd846 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 29 Sep 2022 00:53:02 +0200 Subject: [PATCH 0552/1333] nimble/ll: Fix backoff handling for aux scan We should update backoff after receiving scan response PDU instead of waiting for complete chain to be received. This also fixes problem where we try to update backoff in an invalid state, i.e. backoff_count is non-zero. It happens if we start to scan response chain with backoff_count=0 and before complete chain is scanned we scan another pdu which fails. This updates backoff_count to non-zero value so when we finish scanning chain and try to update backoff, the backoff_count value is non-zero which is considered an invalid state. [Core 5.3, Vol 6, Part B, 4.4.3.2] --- nimble/controller/src/ble_ll_scan.c | 6 ++--- nimble/controller/src/ble_ll_scan_aux.c | 31 +++++++++++-------------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 010fe150bc..75441bb562 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1535,10 +1535,8 @@ ble_ll_scan_send_scan_req(uint8_t pdu_type, uint8_t *rxbuf, BLE_LL_ASSERT(scansm->scan_rsp_pending == 0); /* We want to send a request. See if backoff allows us */ - if (scansm->backoff_count > 0) { - if (--scansm->backoff_count != 0) { - return false; - } + if (ble_ll_scan_backoff_kick() != 0) { + return false; } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 01e516fde7..57d79f923d 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -198,21 +198,6 @@ ble_ll_scan_aux_free(struct ble_ll_scan_aux_data *aux) os_memblock_put(&aux_data_pool, aux); } -static void -ble_ll_scan_aux_update_scan_backoff(struct ble_ll_scan_aux_data *aux) -{ - if (!(aux->flags & BLE_LL_SCAN_AUX_F_W4_SCAN_RSP) && - !(aux->flags & BLE_LL_SCAN_AUX_F_SCANNED)) { - return; - } - - if ((aux->hci_state & BLE_LL_SCAN_AUX_H_DONE) && - !(aux->hci_state & BLE_LL_SCAN_AUX_H_TRUNCATED)) { - ble_ll_scan_backoff_update(1); - } else { - ble_ll_scan_backoff_update(0); - } -} static inline bool ble_ll_scan_aux_need_truncation(struct ble_ll_scan_aux_data *aux) @@ -670,7 +655,10 @@ ble_ll_scan_aux_break_ev(struct ble_npl_event *ev) ble_ll_hci_ev_send_ext_adv_truncated_report(aux); } - ble_ll_scan_aux_update_scan_backoff(aux); + /* Update backoff if we were waiting for scan response */ + if (aux->flags & BLE_LL_SCAN_AUX_F_W4_SCAN_RSP) { + ble_ll_scan_backoff_update(0); + } ble_ll_scan_aux_free(aux); ble_ll_scan_chk_resume(); @@ -1658,7 +1646,15 @@ ble_ll_scan_aux_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr) aux->hci_state |= BLE_LL_SCAN_AUX_H_DONE; } - ble_ll_scan_aux_update_scan_backoff(aux); + /* Update backoff if we were waiting for scan response */ + if (aux->flags & BLE_LL_SCAN_AUX_F_W4_SCAN_RSP) { + ble_ll_scan_backoff_update(0); + } + } else if (rxinfo->flags & BLE_MBUF_HDR_F_SCAN_RSP_RXD) { + /* We assume scan success when AUX_SCAN_RSP is received, no need to + * wait for complete chain (Core 5.3, Vol 6, Part B, 4.4.3.1). + */ + ble_ll_scan_backoff_update(1); } if (aux->hci_state & BLE_LL_SCAN_AUX_H_DONE) { @@ -1736,7 +1732,6 @@ ble_ll_scan_aux_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr) if ((aux->hci_state & BLE_LL_SCAN_AUX_H_DONE) && (!(rxinfo->flags & BLE_MBUF_HDR_F_AUX_PTR_WAIT) || (ble_ll_sched_rmv_elem(&aux->sch) == 0))) { - ble_ll_scan_aux_update_scan_backoff(aux); ble_ll_scan_aux_free(aux); } From 0c3e1b728c43250bfc73f1ebde68a28c79047597 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 29 Sep 2022 01:01:26 +0200 Subject: [PATCH 0553/1333] nimble/ll: Fix active scan on aux We should not allow to free aux_data from pkt_in if there was AUX_SCAN_REQ sent for that pdu as this will result in use-after-free of aux_data when AUX_SCAN_RSP is received. This can happen if we send AUX_SCAN_REQ from isr and then in pkt_in figure out this is a duplicate so we don't want to scan this chain anymore. We should just wait for AUX_SCAN_RSP and stop there. --- nimble/controller/src/ble_ll_scan_aux.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 57d79f923d..60b4b5c10b 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -1724,12 +1724,14 @@ ble_ll_scan_aux_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr) aux->hci_state |= BLE_LL_SCAN_AUX_H_DONE; } - /* - * If we are done processing this chain and aux scan was not scheduled or - * we removed it from scheduler, we can remove aux_data now. Otherwise we - * will remove on next pkt_in. + /* If we are done processing this chain we can remove aux_data now if: + * - we did not send AUX_SCAN_REQ for this PDU + * - there was no aux scan scheduled from this PDU + * - there was aux scan scheduled from this PDU but we removed it + * In other cases, we'll remove aux_data on next pkt_in. */ if ((aux->hci_state & BLE_LL_SCAN_AUX_H_DONE) && + !(rxinfo->flags & BLE_MBUF_HDR_F_SCAN_REQ_TXD) && (!(rxinfo->flags & BLE_MBUF_HDR_F_AUX_PTR_WAIT) || (ble_ll_sched_rmv_elem(&aux->sch) == 0))) { ble_ll_scan_aux_free(aux); From ef7c30dcbe0af4d3cc8802281341088bb7dd2c0a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 29 Sep 2022 10:16:51 +0200 Subject: [PATCH 0554/1333] nimble/ll: Fix aux_data leak We should mark hci stream if ext adv report event is either disabled or cannot be allocated, otherwise we will never free aux_data. --- nimble/controller/src/ble_ll_scan_aux.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 60b4b5c10b..63e2feb27a 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -587,6 +587,7 @@ ble_ll_hci_ev_send_ext_adv_report_for_aux(struct os_mbuf *rxpdu, int rc; if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) { + aux->hci_state = BLE_LL_SCAN_AUX_H_DONE; return -1; } @@ -601,6 +602,7 @@ ble_ll_hci_ev_send_ext_adv_report_for_aux(struct os_mbuf *rxpdu, } else { hci_ev = ble_ll_hci_ev_alloc_ext_adv_report_for_aux(addrd, aux); if (!hci_ev) { + aux->hci_state = BLE_LL_SCAN_AUX_H_DONE; return -1; } } From 4c5c48e70be93c987c30467cdcddf67923b496f9 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 27 Sep 2022 21:39:00 +0200 Subject: [PATCH 0555/1333] nimble/ll: Fix MIC failure during encryption start This fixes unexpected MIC failure when retransmission happens during encryption start procedure as follows: - peripheral sends LL_START_ENC_REQ unencrypted, central acks - central sends LL_START_ENC_RSP encrypted, peripheral acks - central retransmits LL_START_ENC_RSP for whatever reason The problem is that peripheral increments rx packet counter after 1st LL_START_ENC_RSP is received, so retransmission is decrypted with different rx packet counter and thus is not valid. We properly ignore MIC failure for retransmission, but then code checks if received PDU is valid in currect state, i.e. encryption start procedure. Since it was not properly decrypted, the PDU type is likely garbage and thus considered as not allowed so we terminate connection with MIC failure. The "ultimate" fix for such issues is to simply ignore any retransmitted PDU with MIC failure since basically contents of such PDUs are garbage and not really useful for any checks. --- nimble/controller/src/ble_ll_conn.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 9bfa1f8e5f..12b6706963 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3434,9 +3434,15 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) rxd_sn = hdr_byte & BLE_LL_DATA_HDR_SN_MASK; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (BLE_MBUF_HDR_MIC_FAILURE(hdr) && (rxd_sn != connsm->last_rxd_sn)) { - STATS_INC(ble_ll_conn_stats, mic_failures); - ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC); + if (BLE_MBUF_HDR_MIC_FAILURE(hdr)) { + /* MIC failure is expected on retransmissions since packet counter does + * not match, so we simply ignore retransmitted PDU with MIC failure as + * they do not have proper decrypted contents. + */ + if (rxd_sn != connsm->last_rxd_sn) { + STATS_INC(ble_ll_conn_stats, mic_failures); + ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC); + } goto conn_rx_data_pdu_end; } #endif From e2f3e92d03c1844dc1cfa56cb8392d1a72208c99 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 29 Sep 2022 21:29:09 +0200 Subject: [PATCH 0556/1333] Update mailmap --- .mailmap | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.mailmap b/.mailmap index c1458fc5b5..61be657c2a 100644 --- a/.mailmap +++ b/.mailmap @@ -1,8 +1,20 @@ +Brian Giori Christopher Collins +Christopher Collins +Jakub Rotkiewicz +Jakub Rotkiewicz +Magdalena Kasenberg +Magdalena Kasenberg <–magdalena.kasenberg@codecoup.pl> Marko Kiiskila +Michał Narajowski +Sterling Hughes +Sterling Hughes +Szymon Czapracki +Szymon Janc Vipul Rahane Vipul Rahane Vipul Rahane +Will San Filippo Will San Filippo Will San Filippo From e178ff0d9f9c970e1b8df3358f393f9d564f2b9c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 11 Aug 2022 10:47:11 +0200 Subject: [PATCH 0557/1333] nimble/transport: Add generic IPC transport with flow control This adds generic IPC transport that should be used as a base for any transport with LL on separate core. It's similar to HCI H4, but has a bit different header to simplify processing and supports internal flow control to make sure LL does not send data that other core does not have free buffers for. IPC transport requires memory shared between cores to keep track of number of available buffers on application core. Application core will initialize counters to total number of available buffers. Then on each alloc LL will atomically test and decrease relevan counter and will allocate buffer only if that counter was non-zero. The counter will be increased by application core if relevant buffer was freed. --- nimble/controller/src/ble_ll_conn.c | 20 +- .../include/nimble/transport/hci_ipc.h | 98 ++++++++ .../syscfg.yml => common/hci_ipc/pkg.yml} | 10 +- nimble/transport/common/hci_ipc/src/hci_ipc.c | 219 ++++++++++++++++++ nimble/transport/include/nimble/transport.h | 3 + .../include/nimble/transport/transport_ipc.h | 46 ++++ .../transport/include/nimble/transport_impl.h | 6 - nimble/transport/nrf5340/pkg.yml | 2 +- .../transport/nrf5340/src/nrf5340_ble_hci.c | 116 ++++++---- nimble/transport/src/transport.c | 80 ++++++- 10 files changed, 527 insertions(+), 73 deletions(-) create mode 100644 nimble/transport/common/hci_ipc/include/nimble/transport/hci_ipc.h rename nimble/transport/{nrf5340/syscfg.yml => common/hci_ipc/pkg.yml} (79%) create mode 100644 nimble/transport/common/hci_ipc/src/hci_ipc.c create mode 100644 nimble/transport/include/nimble/transport/transport_ipc.h diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 12b6706963..d7a202da89 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -43,6 +43,9 @@ #include "controller/ble_ll_utils.h" #include "ble_ll_conn_priv.h" #include "ble_ll_ctrl_priv.h" +#if MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_common_hci_ipc +#include +#endif #if (BLETEST_THROUGHPUT_TEST == 1) extern void bletest_completed_pkt(uint16_t handle); @@ -3548,9 +3551,9 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) /* Free buffer */ conn_rx_data_pdu_end: -#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) +#if MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_common_hci_ipc if (hdr->rxinfo.flags & BLE_MBUF_HDR_F_CONN_CREDIT_INT) { - ble_transport_int_flow_ctl_put(); + hci_ipc_put(HCI_IPC_TYPE_ACL); } #endif @@ -3614,12 +3617,12 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) alloc_rxpdu = false; } -#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) - /* Do not alloc PDU if there are no free buffers in transport. We'll nak - * this PDU in LL. +#if MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_common_hci_ipc + /* If IPC transport is used, make sure there is buffer available on app side + * for this PDU. We'll just nak in LL if there are no free buffers. */ if (alloc_rxpdu && BLE_LL_LLID_IS_DATA(hdr_byte) && (rx_pyld_len > 0)) { - if (ble_transport_int_flow_ctl_get()) { + if (hci_ipc_get(HCI_IPC_TYPE_ACL)) { rxhdr->rxinfo.flags |= BLE_MBUF_HDR_F_CONN_CREDIT_INT; } else { alloc_rxpdu = false; @@ -3639,8 +3642,9 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) if (ble_ll_conn_cth_flow_alloc_credit(connsm)) { rxhdr->rxinfo.flags |= BLE_MBUF_HDR_F_CONN_CREDIT; } else { -#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) - ble_transport_int_flow_ctl_put(); +#if MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_common_hci_ipc + /* Need to return app buffer to pool since we won't use it */ + hci_ipc_put(HCI_IPC_TYPE_ACL); #endif alloc_rxpdu = false; } diff --git a/nimble/transport/common/hci_ipc/include/nimble/transport/hci_ipc.h b/nimble/transport/common/hci_ipc/include/nimble/transport/hci_ipc.h new file mode 100644 index 0000000000..2f84f68f14 --- /dev/null +++ b/nimble/transport/common/hci_ipc/include/nimble/transport/hci_ipc.h @@ -0,0 +1,98 @@ +/* + * 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 _HCI_IPC_H_ +#define _HCI_IPC_H_ + +#include + +#define HCI_IPC_TYPE_CMD 0x01 +#define HCI_IPC_TYPE_ACL 0x02 +#define HCI_IPC_TYPE_EVT 0x04 +#define HCI_IPC_TYPE_EVT_DISCARDABLE 0x05 +#define HCI_IPC_TYPE_EVT_IN_CMD 0x06 + +struct __attribute__((packed)) hci_ipc_hdr { + uint8_t type; + uint16_t length; +}; + +struct hci_ipc_sm { + struct hci_ipc_hdr hdr; + uint8_t hdr_len; + uint16_t rem_len; + uint16_t buf_len; + + union { + uint8_t *buf; + struct os_mbuf *om; + }; +}; + +struct hci_ipc_shm { + uint16_t n2a_num_acl; + uint16_t n2a_num_evt; + uint16_t n2a_num_evt_disc; +}; + +void hci_ipc_init(volatile struct hci_ipc_shm *shm, struct hci_ipc_sm *sm); +int hci_ipc_rx(struct hci_ipc_sm *sm, const uint8_t *buf, uint16_t len); + +extern void hci_ipc_atomic_put(volatile uint16_t *num); +extern uint16_t hci_ipc_atomic_get(volatile uint16_t *num); + +/* Just to optimize static inlines below, do not use directly! */ +extern volatile struct hci_ipc_shm *g_ipc_shm; + +static inline int +hci_ipc_get(uint8_t type) +{ + volatile struct hci_ipc_shm *shm = g_ipc_shm; + + switch (type) { + case HCI_IPC_TYPE_ACL: + return hci_ipc_atomic_get(&shm->n2a_num_acl); + case HCI_IPC_TYPE_EVT: + return hci_ipc_atomic_get(&shm->n2a_num_evt); + case HCI_IPC_TYPE_EVT_DISCARDABLE: + return hci_ipc_atomic_get(&shm->n2a_num_evt_disc); + } + + return 0; +} + +static inline void +hci_ipc_put(uint8_t type) +{ + volatile struct hci_ipc_shm *shm = g_ipc_shm; + + switch (type) { + case HCI_IPC_TYPE_ACL: + hci_ipc_atomic_put(&shm->n2a_num_acl); + break; + case HCI_IPC_TYPE_EVT: + hci_ipc_atomic_put(&shm->n2a_num_evt); + break; + case HCI_IPC_TYPE_EVT_DISCARDABLE: + hci_ipc_atomic_put(&shm->n2a_num_evt_disc); + break; + } +} + +#endif /* _HCI_IPC_H_ */ diff --git a/nimble/transport/nrf5340/syscfg.yml b/nimble/transport/common/hci_ipc/pkg.yml similarity index 79% rename from nimble/transport/nrf5340/syscfg.yml rename to nimble/transport/common/hci_ipc/pkg.yml index e8334f2a0a..b66a332090 100644 --- a/nimble/transport/nrf5340/syscfg.yml +++ b/nimble/transport/common/hci_ipc/pkg.yml @@ -1,3 +1,4 @@ +# # 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 @@ -16,5 +17,10 @@ # under the License. # -syscfg.defs: - BLE_TRANSPORT_INT_FLOW_CTL: 1 +pkg.name: nimble/transport/common/hci_ipc +pkg.description: Custom HCI IPC protocol +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" + +pkg.deps: + - nimble diff --git a/nimble/transport/common/hci_ipc/src/hci_ipc.c b/nimble/transport/common/hci_ipc/src/hci_ipc.c new file mode 100644 index 0000000000..fafbacc3d7 --- /dev/null +++ b/nimble/transport/common/hci_ipc/src/hci_ipc.c @@ -0,0 +1,219 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +volatile struct hci_ipc_shm *g_ipc_shm; + +static void +hci_ipc_alloc(struct hci_ipc_sm *sm) +{ + assert(sm->hdr.type); + assert(sm->buf == NULL); + + switch (sm->hdr.type) { +#if MYNEWT_VAL(BLE_CONTROLLER) + case HCI_IPC_TYPE_CMD: + sm->buf = ble_transport_alloc_cmd(); + break; +#endif + case HCI_IPC_TYPE_ACL: +#if MYNEWT_VAL(BLE_CONTROLLER) + sm->om = ble_transport_alloc_acl_from_hs(); +#else + sm->om = ble_transport_alloc_acl_from_ll(); +#endif + break; +#if !MYNEWT_VAL(BLE_CONTROLLER) + case HCI_IPC_TYPE_EVT: + sm->buf = ble_transport_alloc_evt(0); + break; + case HCI_IPC_TYPE_EVT_DISCARDABLE: + sm->buf = ble_transport_alloc_evt(1); + break; + case HCI_IPC_TYPE_EVT_IN_CMD: + sm->buf = ble_transport_alloc_cmd(); + break; +#endif + default: + assert(0); + break; + } + + assert(sm->buf); + + sm->rem_len = sm->hdr.length; + sm->buf_len = 0; +} + +static bool +hci_ipc_has_hdr(struct hci_ipc_sm *sm) +{ + return sm->hdr_len == sizeof(sm->hdr); +} + +static void +hci_ipc_frame(struct hci_ipc_sm *sm) +{ + assert(sm->hdr.type); + assert(sm->buf); + assert(sm->rem_len == 0); + + switch (sm->hdr.type) { +#if MYNEWT_VAL(BLE_CONTROLLER) + case HCI_IPC_TYPE_CMD: + ble_transport_to_ll_cmd(sm->buf); + break; +#endif + case HCI_IPC_TYPE_ACL: +#if MYNEWT_VAL(BLE_CONTROLLER) + ble_transport_to_ll_acl(sm->om); +#else + ble_transport_to_hs_acl(sm->om); +#endif + break; +#if !MYNEWT_VAL(BLE_CONTROLLER) + case HCI_IPC_TYPE_EVT: + case HCI_IPC_TYPE_EVT_DISCARDABLE: + case HCI_IPC_TYPE_EVT_IN_CMD: + ble_transport_to_hs_evt(sm->buf); + break; +#endif + default: + assert(0); + break; + } + + sm->hdr.type = 0; + sm->hdr.length = 0; + sm->hdr_len = 0; + sm->buf_len = 0; + sm->rem_len = 0; + sm->buf = NULL; +} + +static uint16_t +hci_ipc_copy_to_hdr(struct hci_ipc_sm *sm, const uint8_t *buf, uint16_t len) +{ + uint16_t rem_hdr_len; + uint8_t *p; + + if (hci_ipc_has_hdr(sm)) { + return 0; + } + + rem_hdr_len = sizeof(sm->hdr) - sm->hdr_len; + len = min(len, rem_hdr_len); + + p = (void *)&sm->hdr; + memcpy(p + sm->hdr_len, buf, len); + + sm->hdr_len += len; + + if (hci_ipc_has_hdr(sm)) { + hci_ipc_alloc(sm); + } + + return len; +} + +static uint16_t +hci_ipc_copy_to_buf(struct hci_ipc_sm *sm, const uint8_t *buf, uint16_t len) +{ + int rc; + + assert(sm->hdr.type); + assert(sm->buf); + + len = min(len, sm->rem_len); + + switch (sm->hdr.type) { +#if MYNEWT_VAL(BLE_CONTROLLER) + case HCI_IPC_TYPE_CMD: +#else + case HCI_IPC_TYPE_EVT: + case HCI_IPC_TYPE_EVT_DISCARDABLE: + case HCI_IPC_TYPE_EVT_IN_CMD: +#endif + memcpy(sm->buf + sm->buf_len, buf, len); + break; + case HCI_IPC_TYPE_ACL: + rc = os_mbuf_append(sm->om, buf, len); + assert(rc == 0); + break; + default: + assert(0); + break; + } + + sm->rem_len -= len; + sm->buf_len += len; + + if (sm->rem_len == 0) { + hci_ipc_frame(sm); + } + + return len; +} + +int +hci_ipc_rx(struct hci_ipc_sm *sm, const uint8_t *buf, uint16_t len) +{ + uint16_t rem_len = len; + uint16_t copy_len; + + while (rem_len) { + if (hci_ipc_has_hdr(sm)) { + copy_len = hci_ipc_copy_to_buf(sm, buf, rem_len); + } else { + copy_len = hci_ipc_copy_to_hdr(sm, buf, rem_len); + } + + rem_len -= copy_len; + buf += copy_len; + } + + return len; +} + +void +hci_ipc_init(volatile struct hci_ipc_shm *shm, struct hci_ipc_sm *sm) +{ + assert(g_ipc_shm == NULL); + + g_ipc_shm = shm; + memset(sm, 0, sizeof(*sm)); + +#if MYNEWT_VAL(BLE_CONTROLLER) + while (shm->n2a_num_evt_disc == 0) { + /* Wait until app side initializes credits */ + } +#else + shm->n2a_num_acl = MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT); + shm->n2a_num_evt = MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT); + shm->n2a_num_evt_disc = MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT); +#endif +} diff --git a/nimble/transport/include/nimble/transport.h b/nimble/transport/include/nimble/transport.h index fc3d737564..d18ff56056 100644 --- a/nimble/transport/include/nimble/transport.h +++ b/nimble/transport/include/nimble/transport.h @@ -26,6 +26,9 @@ extern "C" { #include #include +#if MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_common_hci_ipc +#include +#endif struct os_mbuf; diff --git a/nimble/transport/include/nimble/transport/transport_ipc.h b/nimble/transport/include/nimble/transport/transport_ipc.h new file mode 100644 index 0000000000..1817514934 --- /dev/null +++ b/nimble/transport/include/nimble/transport/transport_ipc.h @@ -0,0 +1,46 @@ +/* + * 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_NIMBLE_TRANSPORT_IPC_ +#define H_NIMBLE_TRANSPORT_IPC_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* NOTE: These APIs shall only be used by IPC transports */ + +#define BLE_TRANSPORT_IPC \ + MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_common_hci_ipc +#define BLE_TRANSPORT_IPC_ON_HS \ + (BLE_TRANSPORT_IPC && !MYNEWT_VAL(BLE_CONTROLLER)) +#define BLE_TRANSPORT_IPC_ON_LL \ + (BLE_TRANSPORT_IPC && MYNEWT_VAL(BLE_CONTROLLER)) + +/* Free cmd/evt buffer sent over IPC */ +void ble_transport_ipc_free(void *buf); + +/* Get IPC type for cmd/evt buffer */ +uint8_t ble_transport_ipc_buf_evt_type_get(void *buf); + +#ifdef __cplusplus +} +#endif + +#endif /* H_NIMBLE_TRANSPORT_IPC_ */ diff --git a/nimble/transport/include/nimble/transport_impl.h b/nimble/transport/include/nimble/transport_impl.h index 61d8cd68a3..d99a8d957d 100644 --- a/nimble/transport/include/nimble/transport_impl.h +++ b/nimble/transport/include/nimble/transport_impl.h @@ -34,12 +34,6 @@ extern int ble_transport_to_ll_acl_impl(struct os_mbuf *om); extern int ble_transport_to_hs_evt_impl(void *buf); extern int ble_transport_to_hs_acl_impl(struct os_mbuf *om); -#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) -/* To be implemented if transport supports internal flow control between cores */ -extern int ble_transport_int_flow_ctl_get(void); -extern void ble_transport_int_flow_ctl_put(void); -#endif - #ifdef __cplusplus } #endif diff --git a/nimble/transport/nrf5340/pkg.yml b/nimble/transport/nrf5340/pkg.yml index 73dfcf9e50..be44d0f8d1 100644 --- a/nimble/transport/nrf5340/pkg.yml +++ b/nimble/transport/nrf5340/pkg.yml @@ -28,7 +28,7 @@ pkg.keywords: pkg.deps: - nimble - - nimble/transport/common/hci_h4 + - nimble/transport/common/hci_ipc - "@apache-mynewt-core/kernel/os" - "@apache-mynewt-core/hw/drivers/ipc_nrf5340" diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index 2e9e746f32..e5ea5a51b3 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #if MYNEWT_VAL(BLE_CONTROLLER) #define IPC_TX_CHANNEL 0 @@ -33,16 +33,19 @@ #define IPC_RX_CHANNEL 0 #endif -static struct hci_h4_sm hci_nrf5340_h4sm; +static struct hci_ipc_sm g_hci_ipc_sm; static int nrf5340_ble_hci_acl_tx(struct os_mbuf *om) { - uint8_t ind = HCI_H4_ACL; + struct hci_ipc_hdr hdr; struct os_mbuf *x; int rc; - rc = ipc_nrf5340_write(IPC_TX_CHANNEL, &ind, 1, false); + hdr.type = HCI_IPC_TYPE_ACL; + hdr.length = 4 + get_le16(&om->om_data[2]); + + rc = ipc_nrf5340_write(IPC_TX_CHANNEL, &hdr, sizeof(hdr), false); if (rc == 0) { x = om; while (x) { @@ -59,37 +62,6 @@ nrf5340_ble_hci_acl_tx(struct os_mbuf *om) return (rc < 0) ? BLE_ERR_MEM_CAPACITY : 0; } -static int -nrf5340_ble_hci_frame_cb(uint8_t pkt_type, void *data) -{ - int rc; - - switch (pkt_type) { -#if MYNEWT_VAL(BLE_CONTROLLER) - case HCI_H4_CMD: - rc = ble_transport_to_ll_cmd(data); - break; -#endif - case HCI_H4_ACL: -#if MYNEWT_VAL(BLE_CONTROLLER) - rc = ble_transport_to_ll_acl(data); -#else - rc = ble_transport_to_hs_acl(data); -#endif - break; -#if !MYNEWT_VAL(BLE_CONTROLLER) - case HCI_H4_EVT: - rc = ble_transport_to_hs_evt(data); - break; -#endif - default: - assert(0); - break; - } - - return rc; -} - static void nrf5340_ble_hci_trans_rx(int channel, void *user_data) { @@ -98,7 +70,7 @@ nrf5340_ble_hci_trans_rx(int channel, void *user_data) len = ipc_nrf5340_available_buf(channel, (void **)&buf); while (len > 0) { - len = hci_h4_sm_rx(&hci_nrf5340_h4sm, buf, len); + len = hci_ipc_rx(&g_hci_ipc_sm, buf, len); ipc_nrf5340_consume(channel, len); len = ipc_nrf5340_available_buf(channel, (void **)&buf); } @@ -116,17 +88,19 @@ nrf5340_ble_hci_init(void) int ble_transport_to_hs_evt_impl(void *buf) { - uint8_t ind = HCI_H4_EVT; - uint8_t* hci_ev = buf; - int len = 2 + hci_ev[1]; + struct hci_ipc_hdr hdr; + uint8_t *hci_ev = buf; int rc; - rc = ipc_nrf5340_write(IPC_TX_CHANNEL, &ind, 1, false); + hdr.type = ble_transport_ipc_buf_evt_type_get(buf); + hdr.length = 2 + hci_ev[1]; + + rc = ipc_nrf5340_write(IPC_TX_CHANNEL, &hdr, sizeof(hdr), false); if (rc == 0) { - rc = ipc_nrf5340_write(IPC_TX_CHANNEL, hci_ev, len, true); + rc = ipc_nrf5340_write(IPC_TX_CHANNEL, hci_ev, hdr.length, true); } - ble_transport_free(buf); + ble_transport_ipc_free(buf); return (rc < 0) ? BLE_ERR_MEM_CAPACITY : 0; } @@ -140,8 +114,9 @@ ble_transport_to_hs_acl_impl(struct os_mbuf *om) void ble_transport_hs_init(void) { - hci_h4_sm_init(&hci_nrf5340_h4sm, &hci_h4_allocs_from_hs, - nrf5340_ble_hci_frame_cb); + volatile struct hci_ipc_shm *shm = ipc_nrf5340_hci_shm_get(); + + hci_ipc_init(shm, &g_hci_ipc_sm); nrf5340_ble_hci_init(); } #endif /* BLE_CONTROLLER */ @@ -150,17 +125,19 @@ ble_transport_hs_init(void) int ble_transport_to_ll_cmd_impl(void *buf) { - uint8_t ind = HCI_H4_CMD; + struct hci_ipc_hdr hdr; uint8_t *cmd = buf; - int len = 3 + cmd[2]; int rc; - rc = ipc_nrf5340_write(IPC_TX_CHANNEL, &ind, 1, false); + hdr.type = HCI_IPC_TYPE_CMD; + hdr.length = 3 + cmd[2]; + + rc = ipc_nrf5340_write(IPC_TX_CHANNEL, &hdr, sizeof(hdr), false); if (rc == 0) { - rc = ipc_nrf5340_write(IPC_TX_CHANNEL, cmd, len, true); + rc = ipc_nrf5340_write(IPC_TX_CHANNEL, cmd, hdr.length, true); } - ble_transport_free(buf); + ble_transport_ipc_free(buf); return (rc < 0) ? BLE_ERR_MEM_CAPACITY : 0; } @@ -174,8 +151,45 @@ ble_transport_to_ll_acl_impl(struct os_mbuf *om) void ble_transport_ll_init(void) { - hci_h4_sm_init(&hci_nrf5340_h4sm, &hci_h4_allocs_from_ll, - nrf5340_ble_hci_frame_cb); + volatile struct hci_ipc_shm *shm = ipc_nrf5340_hci_shm_get(); + + hci_ipc_init(shm, &g_hci_ipc_sm); nrf5340_ble_hci_init(); } #endif /* !BLE_CONTROLLER */ + +uint16_t +hci_ipc_atomic_get(volatile uint16_t *num) +{ + int ret; + + __asm__ volatile (".syntax unified \n" + "1: ldrexh r1, [%[addr]] \n" + " mov %[ret], r1 \n" + " cmp r1, #0 \n" + " itte ne \n" + " subne r2, r1, #1 \n" + " strexhne r1, r2, [%[addr]] \n" + " clrexeq \n" + " cmp r1, #0 \n" + " bne 1b \n" + : [ret] "=&r" (ret) + : [addr] "r" (num) + : "r1", "r2", "memory"); + + return ret; +} + +void +hci_ipc_atomic_put(volatile uint16_t *num) +{ + __asm__ volatile (".syntax unified \n" + "1: ldrexh r1, [%[addr]] \n" + " add r1, r1, #1 \n" + " strexh r2, r1, [%[addr]] \n" + " cmp r2, #0 \n" + " bne 1b \n" + : + : [addr] "r" (num) + : "r1", "r2", "memory"); +} diff --git a/nimble/transport/src/transport.c b/nimble/transport/src/transport.c index 0a641a807b..9de703e713 100644 --- a/nimble/transport/src/transport.c +++ b/nimble/transport/src/transport.c @@ -25,6 +25,9 @@ #include #include #include +#if BLE_TRANSPORT_IPC +#include +#endif #define OMP_FLAG_FROM_HS (0x01) #define OMP_FLAG_FROM_LL (0x02) @@ -79,17 +82,48 @@ ble_transport_alloc_cmd(void) return os_memblock_get(&pool_cmd); } +static void * +try_alloc_evt(struct os_mempool *mp) +{ +#if BLE_TRANSPORT_IPC_ON_LL + uint8_t type; +#endif + void *buf; + +#if BLE_TRANSPORT_IPC_ON_LL + if (mp == &pool_evt) { + type = HCI_IPC_TYPE_EVT; + } else { + type = HCI_IPC_TYPE_EVT_DISCARDABLE; + } + + if (!hci_ipc_get(type)) { + return NULL; + } +#endif + + buf = os_memblock_get(mp); + +#if BLE_TRANSPORT_IPC_ON_LL + if (!buf) { + hci_ipc_put(type); + } +#endif + + return buf; +} + void * ble_transport_alloc_evt(int discardable) { void *buf; if (discardable) { - buf = os_memblock_get(&pool_evt_lo); + buf = try_alloc_evt(&pool_evt_lo); } else { - buf = os_memblock_get(&pool_evt); + buf = try_alloc_evt(&pool_evt); if (!buf) { - buf = os_memblock_get(&pool_evt_lo); + buf = try_alloc_evt(&pool_evt_lo); } } @@ -135,6 +169,26 @@ ble_transport_alloc_acl_from_ll(void) void ble_transport_free(void *buf) +{ + if (os_memblock_from(&pool_cmd, buf)) { + os_memblock_put(&pool_cmd, buf); + } else if (os_memblock_from(&pool_evt, buf)) { + os_memblock_put(&pool_evt, buf); +#if BLE_TRANSPORT_IPC + hci_ipc_put(HCI_IPC_TYPE_EVT); +#endif + } else if (os_memblock_from(&pool_evt_lo, buf)) { + os_memblock_put(&pool_evt_lo, buf); +#if BLE_TRANSPORT_IPC + hci_ipc_put(HCI_IPC_TYPE_EVT_DISCARDABLE); +#endif + } else { + assert(0); + } +} + +void +ble_transport_ipc_free(void *buf) { if (os_memblock_from(&pool_cmd, buf)) { os_memblock_put(&pool_cmd, buf); @@ -172,9 +226,9 @@ ble_transport_acl_put(struct os_mempool_ext *mpe, void *data, void *arg) err = os_memblock_put_from_cb(&mpe->mpe_mp, data); } -#if MYNEWT_VAL(BLE_TRANSPORT_INT_FLOW_CTL) +#if BLE_TRANSPORT_IPC_ON_HS if (from_ll && !err) { - ble_transport_int_flow_ctl_put(); + hci_ipc_put(HCI_IPC_TYPE_ACL); } #endif @@ -218,3 +272,19 @@ ble_transport_register_put_acl_from_ll_cb(os_mempool_put_fn (*cb)) return 0; } + +#if BLE_TRANSPORT_IPC +uint8_t +ble_transport_ipc_buf_evt_type_get(void *buf) +{ + if (os_memblock_from(&pool_cmd, buf)) { + return HCI_IPC_TYPE_EVT_IN_CMD; + } else if (os_memblock_from(&pool_evt, buf)) { + return HCI_IPC_TYPE_EVT; + } else if (os_memblock_from(&pool_evt_lo, buf)) { + return HCI_IPC_TYPE_EVT_DISCARDABLE; + } else { + assert(0); + } +} +#endif From 27ed71508e5456dffb12923f3a8732d16a6940f2 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 26 Sep 2022 14:09:04 +0200 Subject: [PATCH 0558/1333] nimble/ll: Move RX power compensation from PHY to LL This will make is easier to handle FEM RX power compensation in generic way. --- nimble/controller/include/controller/ble_phy.h | 3 --- nimble/controller/src/ble_ll.c | 6 ++++++ nimble/controller/src/ble_ll_conn.c | 3 ++- nimble/controller/src/ble_ll_hci.c | 3 ++- nimble/controller/src/ble_ll_priv.h | 2 ++ nimble/controller/src/ble_ll_scan.c | 8 +++++--- nimble/controller/src/ble_ll_scan_aux.c | 5 +++-- nimble/drivers/dialog_cmac/src/ble_phy.c | 5 ----- nimble/drivers/nrf51/src/ble_phy.c | 12 +----------- nimble/drivers/nrf5x/src/ble_phy.c | 12 +----------- 10 files changed, 22 insertions(+), 37 deletions(-) diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index 5a989e2fb9..495a068c37 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -119,9 +119,6 @@ int ble_phy_txpower_round(int dbm); /* Get the transmit power */ int ble_phy_txpwr_get(void); -/* Set RX path power compensation value rounded to integer dB */ -void ble_phy_set_rx_pwr_compensation(int8_t compensation); - /* Disable the PHY */ void ble_phy_disable(void); diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index d9f3955eee..bb44a278ed 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -66,6 +66,8 @@ */ int8_t g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); +int8_t g_ble_ll_tx_power_compensation; +int8_t g_ble_ll_rx_power_compensation; /* Supported states */ #if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) @@ -1589,6 +1591,10 @@ ble_ll_reset(void) ble_ll_sync_reset(); #endif + /* reset power compensation */ + g_ble_ll_tx_power_compensation = 0; + g_ble_ll_rx_power_compensation = 0; + /* FLush all packets from Link layer queues */ ble_ll_flush_pkt_queue(&g_ble_ll_data.ll_tx_pkt_q); ble_ll_flush_pkt_queue(&g_ble_ll_data.ll_rx_pkt_q); diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index d7a202da89..eeed8b668e 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -43,6 +43,7 @@ #include "controller/ble_ll_utils.h" #include "ble_ll_conn_priv.h" #include "ble_ll_ctrl_priv.h" +#include "ble_ll_priv.h" #if MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_common_hci_ipc #include #endif @@ -3489,7 +3490,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) #endif /* Update RSSI */ - connsm->conn_rssi = hdr->rxinfo.rssi; + connsm->conn_rssi = hdr->rxinfo.rssi + g_ble_ll_rx_power_compensation; /* * If we are a peripheral, we can only start to use peripheral latency diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index f0151b497d..39085d4cf0 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -826,7 +826,8 @@ ble_ll_write_rf_path_compensation(const uint8_t *cmdbuf, uint8_t len) tx_path_pwr_compensation = tx; rx_path_pwr_compensation = rx; - ble_phy_set_rx_pwr_compensation(rx_path_pwr_compensation / 10); + g_ble_ll_tx_power_compensation = tx / 10; + g_ble_ll_rx_power_compensation = rx / 10; return BLE_ERR_SUCCESS; } diff --git a/nimble/controller/src/ble_ll_priv.h b/nimble/controller/src/ble_ll_priv.h index ca8e082958..c373de202e 100644 --- a/nimble/controller/src/ble_ll_priv.h +++ b/nimble/controller/src/ble_ll_priv.h @@ -25,6 +25,8 @@ extern "C" { #endif extern int8_t g_ble_ll_tx_power; +extern int8_t g_ble_ll_tx_power_compensation; +extern int8_t g_ble_ll_rx_power_compensation; #ifdef MYNEWT diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 75441bb562..d935405083 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -41,6 +41,7 @@ #include "controller/ble_ll_trace.h" #include "controller/ble_ll_sync.h" #include "ble_ll_conn_priv.h" +#include "ble_ll_priv.h" #if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) @@ -716,7 +717,7 @@ ble_ll_scan_send_adv_report(uint8_t pdu_type, if (scansm->ext_scanning) { rc = ble_ll_hci_send_legacy_ext_adv_report(evtype, adva, adva_type, - hdr->rxinfo.rssi, + hdr->rxinfo.rssi + g_ble_ll_rx_power_compensation, adv_data_len, om, inita, inita_type); goto done; @@ -725,11 +726,12 @@ goto done; if (subev == BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT) { rc = ble_ll_hci_send_dir_adv_report(adva, adva_type, inita, inita_type, - hdr->rxinfo.rssi); + hdr->rxinfo.rssi + g_ble_ll_rx_power_compensation); goto done; } - rc = ble_ll_hci_send_adv_report(evtype, adva, adva_type, hdr->rxinfo.rssi, + rc = ble_ll_hci_send_adv_report(evtype, adva, adva_type, + hdr->rxinfo.rssi + g_ble_ll_rx_power_compensation, adv_data_len, om); done: if (!rc && scansm->scan_filt_dups) { diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 63e2feb27a..0800f4af3b 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -38,6 +38,7 @@ #include "controller/ble_ll_whitelist.h" #include "controller/ble_ll_resolv.h" #include "controller/ble_ll_sync.h" +#include "ble_ll_priv.h" #define BLE_LL_SCAN_AUX_F_AUX_ADV 0x0001 #define BLE_LL_SCAN_AUX_F_AUX_CHAIN 0x0002 @@ -408,7 +409,7 @@ ble_ll_hci_ev_update_ext_adv_report_from_ext(struct ble_hci_ev *hci_ev, report->pri_phy = rxinfo->phy; report->sec_phy = 0; report->sid = 0xff; - report->rssi = rxhdr->rxinfo.rssi; + report->rssi = rxhdr->rxinfo.rssi + g_ble_ll_rx_power_compensation; report->periodic_itvl = 0; report->data_len = 0; @@ -529,7 +530,7 @@ ble_ll_hci_ev_send_ext_adv_report(struct os_mbuf *rxpdu, hci_subev = (void *)(*hci_ev)->data; report = hci_subev->reports; - report->rssi = rxinfo->rssi; + report->rssi = rxinfo->rssi + g_ble_ll_rx_power_compensation; report->data_len = min(max_data_len, data_len - offset); os_mbuf_copydata(rxpdu, offset, report->data_len, report->data); diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index 077675a3ef..33c41d2c81 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -1673,11 +1673,6 @@ ble_phy_txpower_round(int dbm) return 0; } -void -ble_phy_set_rx_pwr_compensation(int8_t compensation) -{ -} - int ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crc_init) { diff --git a/nimble/drivers/nrf51/src/ble_phy.c b/nimble/drivers/nrf51/src/ble_phy.c index c0d827d7c6..94302ad32b 100644 --- a/nimble/drivers/nrf51/src/ble_phy.c +++ b/nimble/drivers/nrf51/src/ble_phy.c @@ -102,7 +102,6 @@ struct ble_phy_obj uint8_t phy_privacy; uint8_t phy_tx_pyld_len; uint8_t *rxdptr; - int8_t rx_pwr_compensation; uint32_t phy_aar_scratch; uint32_t phy_access_address; struct ble_mbuf_hdr rxhdr; @@ -626,8 +625,7 @@ ble_phy_rx_end_isr(void) /* Set RSSI and CRC status flag in header */ ble_hdr = &g_ble_phy_data.rxhdr; assert(NRF_RADIO->EVENTS_RSSIEND != 0); - ble_hdr->rxinfo.rssi = (-1 * NRF_RADIO->RSSISAMPLE) + - g_ble_phy_data.rx_pwr_compensation; + ble_hdr->rxinfo.rssi = (-1 * NRF_RADIO->RSSISAMPLE); dptr = g_ble_phy_data.rxdptr; @@ -855,8 +853,6 @@ ble_phy_init(void) /* Set phy channel to an invalid channel so first set channel works */ g_ble_phy_data.phy_chan = BLE_PHY_NUM_CHANS; - g_ble_phy_data.rx_pwr_compensation = 0; - /* Toggle peripheral power to reset (just in case) */ NRF_RADIO->POWER = 0; NRF_RADIO->POWER = 1; @@ -1318,12 +1314,6 @@ ble_phy_txpwr_get(void) return g_ble_phy_data.phy_txpwr_dbm; } -void -ble_phy_set_rx_pwr_compensation(int8_t compensation) -{ - g_ble_phy_data.rx_pwr_compensation = compensation; -} - /** * ble phy setchan * diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 84f60cefab..90d3a3463b 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -144,7 +144,6 @@ struct ble_phy_obj uint8_t phy_tx_phy_mode; uint8_t phy_rx_phy_mode; uint8_t phy_bcc_offset; - int8_t rx_pwr_compensation; uint32_t phy_aar_scratch; uint32_t phy_access_address; struct ble_mbuf_hdr rxhdr; @@ -1168,8 +1167,7 @@ ble_phy_rx_end_isr(void) /* Set RSSI and CRC status flag in header */ ble_hdr = &g_ble_phy_data.rxhdr; assert(NRF_RADIO->EVENTS_RSSIEND != 0); - ble_hdr->rxinfo.rssi = (-1 * NRF_RADIO->RSSISAMPLE) + - g_ble_phy_data.rx_pwr_compensation; + ble_hdr->rxinfo.rssi = (-1 * NRF_RADIO->RSSISAMPLE); dptr = (uint8_t *)&g_ble_phy_rx_buf[0]; dptr += 3; @@ -1503,8 +1501,6 @@ ble_phy_init(void) g_ble_phy_data.phy_tx_phy_mode = BLE_PHY_MODE_1M; g_ble_phy_data.phy_rx_phy_mode = BLE_PHY_MODE_1M; - g_ble_phy_data.rx_pwr_compensation = 0; - /* Set phy channel to an invalid channel so first set channel works */ g_ble_phy_data.phy_chan = BLE_PHY_NUM_CHANS; @@ -2004,12 +2000,6 @@ ble_phy_txpwr_get(void) return g_ble_phy_data.phy_txpwr_dbm; } -void -ble_phy_set_rx_pwr_compensation(int8_t compensation) -{ - g_ble_phy_data.rx_pwr_compensation = compensation; -} - /** * ble phy setchan * From 98feaf20adae91745d6e2d5db67a0716c79ba932 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 26 Sep 2022 14:16:10 +0200 Subject: [PATCH 0559/1333] nimble/ll: Fix not resetting TX power on HCI reset Reset TX power to default on HCI reset. There is no standard way of setting (or reading) TX power so make sure things are at default when reseting controller. --- nimble/controller/src/ble_ll.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index bb44a278ed..2ce70765e9 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1349,7 +1349,8 @@ ble_ll_task(void *arg) /* Init ble phy */ ble_phy_init(); - /* Set output power to 1mW (0 dBm) */ + /* Set output power to default */ + g_ble_ll_tx_power = ble_phy_txpower_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); ble_phy_txpwr_set(g_ble_ll_tx_power); /* Tell the host that we are ready to receive packets */ @@ -1595,6 +1596,10 @@ ble_ll_reset(void) g_ble_ll_tx_power_compensation = 0; g_ble_ll_rx_power_compensation = 0; + /* Set output power to default */ + g_ble_ll_tx_power = ble_phy_txpower_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); + ble_phy_txpwr_set(g_ble_ll_tx_power); + /* FLush all packets from Link layer queues */ ble_ll_flush_pkt_queue(&g_ble_ll_data.ll_tx_pkt_q); ble_ll_flush_pkt_queue(&g_ble_ll_data.ll_rx_pkt_q); From 8f0ecadecc991ab7a441e7fe2f13916ff643f1d8 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 26 Sep 2022 14:55:09 +0200 Subject: [PATCH 0560/1333] nimble/ll: Unify PHY tx power API names Consistently use tx_power for transmit power related PHY API. --- nimble/controller/include/controller/ble_phy.h | 6 +++--- nimble/controller/src/ble_ll.c | 8 ++++---- nimble/controller/src/ble_ll_adv.c | 14 +++++++------- nimble/controller/src/ble_ll_dtm.c | 2 +- nimble/controller/src/ble_ll_hci.c | 4 ++-- nimble/controller/src/ble_ll_hci_vs.c | 4 ++-- nimble/drivers/dialog_cmac/src/ble_phy.c | 4 ++-- nimble/drivers/native/src/ble_phy.c | 7 ++++--- nimble/drivers/nrf51/src/ble_phy.c | 7 ++++--- nimble/drivers/nrf5x/src/ble_phy.c | 6 +++--- 10 files changed, 32 insertions(+), 30 deletions(-) diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index 495a068c37..35ef87edb2 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -111,13 +111,13 @@ int ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans); void ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu); /* Set the transmit power */ -int ble_phy_txpwr_set(int dbm); +int ble_phy_tx_power_set(int dbm); /* Get highest allowed power from range */ -int ble_phy_txpower_round(int dbm); +int ble_phy_tx_power_round(int dbm); /* Get the transmit power */ -int ble_phy_txpwr_get(void); +int ble_phy_tx_power_get(void); /* Disable the PHY */ void ble_phy_disable(void); diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 2ce70765e9..bcd0374085 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1350,8 +1350,8 @@ ble_ll_task(void *arg) ble_phy_init(); /* Set output power to default */ - g_ble_ll_tx_power = ble_phy_txpower_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); - ble_phy_txpwr_set(g_ble_ll_tx_power); + g_ble_ll_tx_power = ble_phy_tx_power_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); + ble_phy_tx_power_set(g_ble_ll_tx_power); /* Tell the host that we are ready to receive packets */ ble_ll_hci_send_noop(); @@ -1597,8 +1597,8 @@ ble_ll_reset(void) g_ble_ll_rx_power_compensation = 0; /* Set output power to default */ - g_ble_ll_tx_power = ble_phy_txpower_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); - ble_phy_txpwr_set(g_ble_ll_tx_power); + g_ble_ll_tx_power = ble_phy_tx_power_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); + ble_phy_tx_power_set(g_ble_ll_tx_power); /* FLush all packets from Link layer queues */ ble_ll_flush_pkt_queue(&g_ble_ll_data.ll_tx_pkt_q); diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index c26e852116..949335c1dd 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1030,7 +1030,7 @@ ble_ll_adv_tx_done(void *arg) struct ble_ll_adv_sm *advsm; /* reset power to max after advertising */ - ble_phy_txpwr_set(g_ble_ll_tx_power); + ble_phy_tx_power_set(g_ble_ll_tx_power); advsm = (struct ble_ll_adv_sm *)arg; @@ -1111,7 +1111,7 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch) } /* Set the power */ - ble_phy_txpwr_set(advsm->adv_txpwr); + ble_phy_tx_power_set(advsm->adv_txpwr); /* Set channel */ rc = ble_phy_setchan(advsm->adv_chan, BLE_ACCESS_ADDR_ADV, BLE_LL_CRCINIT_ADV); @@ -1255,7 +1255,7 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch) ble_ll_adv_active_chanset_set_sec(advsm); /* Set the power */ - ble_phy_txpwr_set(advsm->adv_txpwr); + ble_phy_tx_power_set(advsm->adv_txpwr); /* Set channel */ aux = AUX_CURRENT(advsm); @@ -1740,7 +1740,7 @@ ble_ll_adv_halt(void) ble_ll_trace_u32(BLE_LL_TRACE_ID_ADV_HALT, advsm->adv_instance); - ble_phy_txpwr_set(g_ble_ll_tx_power); + ble_phy_tx_power_set(g_ble_ll_tx_power); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) if (advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING) { @@ -2176,7 +2176,7 @@ static void ble_ll_adv_sync_tx_done(struct ble_ll_adv_sm *advsm) { /* reset power to default after advertising */ - ble_phy_txpwr_set(g_ble_ll_tx_power); + ble_phy_tx_power_set(g_ble_ll_tx_power); /* for sync we trace a no pri nor sec set */ ble_ll_trace_u32x2(BLE_LL_TRACE_ID_ADV_TXDONE, advsm->adv_instance, 0); @@ -2232,7 +2232,7 @@ ble_ll_adv_sync_tx_start_cb(struct ble_ll_sched_item *sch) ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING); /* Set the power */ - ble_phy_txpwr_set(advsm->adv_txpwr); + ble_phy_tx_power_set(advsm->adv_txpwr); /* Set channel */ sync = SYNC_CURRENT(advsm); @@ -3528,7 +3528,7 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, /* no preference */ advsm->adv_txpwr = g_ble_ll_tx_power; } else { - advsm->adv_txpwr = ble_phy_txpower_round(cmd->tx_power); + advsm->adv_txpwr = ble_phy_tx_power_round(cmd->tx_power); } /* we can always store as those are validated and used only when needed */ diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index db32835cab..1b41bc2dff 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -243,7 +243,7 @@ ble_ll_dtm_tx_sched_cb(struct ble_ll_sched_item *sch) ble_phy_mode_set(ctx->phy_mode, ctx->phy_mode); #endif ble_phy_set_txend_cb(ble_ll_dtm_tx_done, ctx); - ble_phy_txpwr_set(0); + ble_phy_tx_power_set(0); sch->start_time += g_ble_ll_sched_offset_ticks; diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 39085d4cf0..6089ed94cd 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -786,8 +786,8 @@ ble_ll_read_tx_power(uint8_t *rspbuf, uint8_t *rsplen) { struct ble_hci_le_rd_transmit_power_rp *rsp = (void *) rspbuf; - rsp->min_tx_power = ble_phy_txpower_round(-127); - rsp->max_tx_power = ble_phy_txpower_round(126); + rsp->min_tx_power = ble_phy_tx_power_round(-127); + rsp->max_tx_power = ble_phy_tx_power_round(126); *rsplen = sizeof(*rsp); return BLE_ERR_SUCCESS; diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index c6c1e256b4..8cbf3dcab7 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -126,10 +126,10 @@ ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, /* restore reset default */ g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); } else { - g_ble_ll_tx_power = ble_phy_txpower_round(cmd->tx_power); + g_ble_ll_tx_power = ble_phy_tx_power_round(cmd->tx_power); } - ble_phy_txpwr_set(g_ble_ll_tx_power); + ble_phy_tx_power_set(g_ble_ll_tx_power); rsp->tx_power = g_ble_ll_tx_power; *rsplen = sizeof(*rsp); diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index 33c41d2c81..b7e4818c2c 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -1652,7 +1652,7 @@ ble_phy_encrypt_disable(void) #endif int -ble_phy_txpwr_set(int dbm) +ble_phy_tx_power_set(int dbm) { #if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE) if (g_cmac_shared_data.debug.tx_power_override != INT8_MAX) { @@ -1668,7 +1668,7 @@ ble_phy_txpwr_set(int dbm) } int -ble_phy_txpower_round(int dbm) +ble_phy_tx_power_round(int dbm) { return 0; } diff --git a/nimble/drivers/native/src/ble_phy.c b/nimble/drivers/native/src/ble_phy.c index f9ab0fcb80..410b9ce602 100644 --- a/nimble/drivers/native/src/ble_phy.c +++ b/nimble/drivers/native/src/ble_phy.c @@ -464,7 +464,7 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) * @return int 0: success; anything else is an error */ int -ble_phy_txpwr_set(int dbm) +ble_phy_tx_power_set(int dbm) { /* Check valid range */ assert(dbm <= BLE_PHY_MAX_PWR_DBM); @@ -492,7 +492,8 @@ ble_phy_txpwr_set(int dbm) * * @return int Rounded power in dBm */ -int ble_phy_txpower_round(int dbm) +int +ble_phy_tx_power_round(int dbm) { /* "Rail" power level if outside supported range */ if (dbm > BLE_XCVR_TX_PWR_MAX_DBM) { @@ -514,7 +515,7 @@ int ble_phy_txpower_round(int dbm) * @return int The current PHY transmit power, in dBm */ int -ble_phy_txpwr_get(void) +ble_phy_tx_power_get(void) { return g_ble_phy_data.phy_txpwr_dbm; } diff --git a/nimble/drivers/nrf51/src/ble_phy.c b/nimble/drivers/nrf51/src/ble_phy.c index 94302ad32b..cfcfb7ec36 100644 --- a/nimble/drivers/nrf51/src/ble_phy.c +++ b/nimble/drivers/nrf51/src/ble_phy.c @@ -1258,7 +1258,7 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) * @return int 0: success; anything else is an error */ int -ble_phy_txpwr_set(int dbm) +ble_phy_tx_power_set(int dbm) { /* Check valid range */ assert(dbm <= BLE_PHY_MAX_PWR_DBM); @@ -1287,7 +1287,8 @@ ble_phy_txpwr_set(int dbm) * * @return int Rounded power in dBm */ -int ble_phy_txpower_round(int dbm) +int +ble_phy_tx_power_round(int dbm) { /* "Rail" power level if outside supported range */ if (dbm > NRF_TX_PWR_MAX_DBM) { @@ -1309,7 +1310,7 @@ int ble_phy_txpower_round(int dbm) * @return int The current PHY transmit power, in dBm */ int -ble_phy_txpwr_get(void) +ble_phy_tx_power_get(void) { return g_ble_phy_data.phy_txpwr_dbm; } diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 90d3a3463b..24f2ed686d 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -1926,7 +1926,7 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) * @return int 0: success; anything else is an error */ int -ble_phy_txpwr_set(int dbm) +ble_phy_tx_power_set(int dbm) { /* Get actual TX power supported by radio */ dbm = phy_txpower_round(dbm); @@ -1947,7 +1947,7 @@ ble_phy_txpwr_set(int dbm) * @return int Rounded power in dBm */ int -ble_phy_txpower_round(int dbm) +ble_phy_tx_power_round(int dbm) { return phy_txpower_round(dbm); } @@ -1995,7 +1995,7 @@ ble_phy_set_access_addr(uint32_t access_addr) * @return int The current PHY transmit power, in dBm */ int -ble_phy_txpwr_get(void) +ble_phy_tx_power_get(void) { return g_ble_phy_data.phy_txpwr_dbm; } From 70117943f4afeba0245a84a38d7a42f194280e4f Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 28 Sep 2022 14:38:40 +0200 Subject: [PATCH 0561/1333] nimble/ll: Fix not rounding TX power when restoring defaults HCI VS command didn't round default TX power value. --- nimble/controller/src/ble_ll_hci_vs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index 8cbf3dcab7..93ec2e8504 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -124,7 +124,7 @@ ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, if (cmd->tx_power == 127) { /* restore reset default */ - g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); + g_ble_ll_tx_power = ble_phy_tx_power_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); } else { g_ble_ll_tx_power = ble_phy_tx_power_round(cmd->tx_power); } From 934193cb85d62b288de3bd28972f283740b08fe3 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 28 Sep 2022 14:40:08 +0200 Subject: [PATCH 0562/1333] nimble/ll: Use global symbol for accessing TX power compensation Global symbol is in dBm units (as opose to HCI, which is in 0.1 dBm) and doesn't require division by 10 on each access. This also improves performance on CPUs with no HW division support. --- nimble/controller/include/controller/ble_ll_hci.h | 3 --- nimble/controller/src/ble_ll_adv.c | 6 +++--- nimble/controller/src/ble_ll_hci.c | 6 ------ 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_hci.h b/nimble/controller/include/controller/ble_ll_hci.h index b73f852751..cb0ec033e9 100644 --- a/nimble/controller/include/controller/ble_ll_hci.h +++ b/nimble/controller/include/controller/ble_ll_hci.h @@ -80,9 +80,6 @@ int ble_ll_hci_chk_phy_masks(uint8_t all_phys, uint8_t tx_phys, uint8_t rx_phys, /* Returns true if Extended Advertising HCI commands are in use */ bool ble_ll_hci_adv_mode_ext(void); -/* Get TX power compensation rounded to integer dB */ -int8_t ble_ll_get_tx_pwr_compensation(void); - /* Check if max octets/time are within allowed range */ int ble_ll_hci_check_dle(uint16_t max_octets, uint16_t max_time); diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 949335c1dd..8733e5d878 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -802,7 +802,7 @@ ble_ll_adv_aux_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) #endif if (aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_TX_POWER_BIT)) { - dptr[0] = advsm->adv_txpwr + ble_ll_get_tx_pwr_compensation(); + dptr[0] = advsm->adv_txpwr + g_ble_ll_tx_power_compensation; dptr += BLE_LL_EXT_ADV_TX_POWER_SIZE; } @@ -879,7 +879,7 @@ ble_ll_adv_aux_scannable_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_b if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR) { *ext_hdr_len += BLE_LL_EXT_ADV_TX_POWER_SIZE; *ext_hdr |= (1 << BLE_LL_EXT_ADV_TX_POWER_BIT); - dptr[0] = advsm->adv_txpwr + ble_ll_get_tx_pwr_compensation(); + dptr[0] = advsm->adv_txpwr + g_ble_ll_tx_power_compensation; dptr += BLE_LL_EXT_ADV_TX_POWER_SIZE; } @@ -2157,7 +2157,7 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) } if (sync->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_TX_POWER_BIT)) { - dptr[0] = advsm->adv_txpwr + ble_ll_get_tx_pwr_compensation(); + dptr[0] = advsm->adv_txpwr + g_ble_ll_tx_power_compensation; dptr += BLE_LL_EXT_ADV_TX_POWER_SIZE; } diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 6089ed94cd..fa3bf66b45 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -832,12 +832,6 @@ ble_ll_write_rf_path_compensation(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_SUCCESS; } -int8_t -ble_ll_get_tx_pwr_compensation(void) -{ - return tx_path_pwr_compensation / 10; -} - /** * Process a LE command sent from the host to the controller. The HCI command * has a 3 byte command header followed by data. The header is: From 24c7b00317d4e80e0a02245bb0a9160d6ecfb4e7 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 28 Sep 2022 22:25:31 +0200 Subject: [PATCH 0563/1333] nimble/ll: Add support for tunable FEM gain and fix compensation This allows to implement dynamic FEM PA and LNA gains and fixes some issues with power compensation from host. g_ble_ll_tx_power and advsm->tx_power now hold rounded host compensated values. If FEM is used expected PHY tx power is altered by FEM PA gain (static or dynamic) before being set. LL operates on PHY (or FEM) power levels and compensate those when reporting to host via HCI. As per spec (clarified in errata): Radiative Tx power level = Tx power level at RF transceiver output + RF_TX_Path_Compensation_Value Rx power level at RF transceiver input = Rx power level at antenna + RF_RX_Path_Compensation_Value --- .../include/controller/ble_ll_fem.h | 13 ++++++ nimble/controller/src/ble_ll.c | 45 ++++++++++++++++--- nimble/controller/src/ble_ll_adv.c | 28 ++++++------ nimble/controller/src/ble_ll_conn.c | 2 +- nimble/controller/src/ble_ll_dtm.c | 3 +- nimble/controller/src/ble_ll_hci.c | 4 +- nimble/controller/src/ble_ll_hci_vs.c | 8 ++-- nimble/controller/src/ble_ll_priv.h | 19 ++++++++ nimble/controller/src/ble_ll_scan.c | 6 +-- nimble/controller/src/ble_ll_scan_aux.c | 4 +- nimble/controller/syscfg.yml | 18 ++++++++ 11 files changed, 118 insertions(+), 32 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_fem.h b/nimble/controller/include/controller/ble_ll_fem.h index d8c6dbec07..48cf94c583 100644 --- a/nimble/controller/include/controller/ble_ll_fem.h +++ b/nimble/controller/include/controller/ble_ll_fem.h @@ -30,12 +30,25 @@ extern "C" { void ble_ll_fem_pa_init(void); void ble_ll_fem_pa_enable(void); void ble_ll_fem_pa_disable(void); +#if MYNEWT_VAL(BLE_LL_FEM_PA_GAIN_TUNABLE) +/* Configures FEM to selected TX power and returns expected PHY TX power */ +int ble_ll_fem_pa_tx_power_set(int tx_power); + +/* returns rounded FEM TX power */ +int ble_ll_fem_pa_tx_power_round(int tx_power); +#endif #endif #if MYNEWT_VAL(BLE_LL_FEM_LNA) void ble_ll_fem_lna_init(void); void ble_ll_fem_lna_enable(void); void ble_ll_fem_lna_disable(void); + +#if MYNEWT_VAL(BLE_LL_FEM_LNA_GAIN_TUNABLE) +/* Return current value of FEM LNA RX gain (in dBm) */ +int ble_ll_fem_lna_rx_gain(void); +#endif + #endif #if MYNEWT_VAL(BLE_LL_FEM_ANTENNA) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index bcd0374085..64c4f6e72b 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -65,7 +65,8 @@ * right thing to do. */ -int8_t g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM); +/* This is TX power on PHY (or FEM PA if enabled) */ +int8_t g_ble_ll_tx_power; int8_t g_ble_ll_tx_power_compensation; int8_t g_ble_ll_rx_power_compensation; @@ -1350,8 +1351,8 @@ ble_ll_task(void *arg) ble_phy_init(); /* Set output power to default */ - g_ble_ll_tx_power = ble_phy_tx_power_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); - ble_phy_tx_power_set(g_ble_ll_tx_power); + g_ble_ll_tx_power = ble_ll_tx_power_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); + ble_ll_tx_power_set(g_ble_ll_tx_power); /* Tell the host that we are ready to receive packets */ ble_ll_hci_send_noop(); @@ -1597,8 +1598,8 @@ ble_ll_reset(void) g_ble_ll_rx_power_compensation = 0; /* Set output power to default */ - g_ble_ll_tx_power = ble_phy_tx_power_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); - ble_phy_tx_power_set(g_ble_ll_tx_power); + g_ble_ll_tx_power = ble_ll_tx_power_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); + ble_ll_tx_power_set(g_ble_ll_tx_power); /* FLush all packets from Link layer queues */ ble_ll_flush_pkt_queue(&g_ble_ll_data.ll_tx_pkt_q); @@ -1987,3 +1988,37 @@ ble_transport_ll_init(void) { ble_ll_init(); } + +int +ble_ll_tx_power_round(int tx_power) +{ +#if MYNEWT_VAL(BLE_LL_FEM_PA) +#if MYNEWT_VAL(BLE_LL_FEM_PA_GAIN_TUNABLE) + tx_power = ble_ll_fem_pa_tx_power_round(tx_power); +#else + tx_power = ble_phy_tx_power_round(tx_power); + tx_power += MYNEWT_VAL(BLE_LL_FEM_PA_GAIN); +#endif +#else + tx_power = ble_phy_tx_power_round(tx_power); +#endif + + return tx_power; +} + +void +ble_ll_tx_power_set(int tx_power) +{ +#if MYNEWT_VAL(BLE_LL_FEM_PA) +#if MYNEWT_VAL(BLE_LL_FEM_PA_GAIN_TUNABLE) + /* TODO should rounding be in assert only? or just skip it and assume + * power is already rounded? + */ + tx_power = ble_ll_fem_pa_tx_power_round(tx_power); + tx_power = ble_ll_fem_pa_tx_power_set(tx_power); +#else + tx_power -= MYNEWT_VAL(BLE_LL_FEM_PA_GAIN); +#endif +#endif + ble_phy_tx_power_set(tx_power); +} diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 8733e5d878..8d6b6e85cc 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -105,7 +105,7 @@ struct ble_ll_adv_sm uint8_t adv_chan; uint8_t adv_pdu_len; int8_t adv_rpa_index; - int8_t adv_txpwr; + int8_t tx_power; uint16_t flags; uint16_t props; uint32_t adv_itvl_usecs; @@ -802,7 +802,7 @@ ble_ll_adv_aux_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) #endif if (aux->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_TX_POWER_BIT)) { - dptr[0] = advsm->adv_txpwr + g_ble_ll_tx_power_compensation; + dptr[0] = advsm->tx_power + g_ble_ll_tx_power_compensation; dptr += BLE_LL_EXT_ADV_TX_POWER_SIZE; } @@ -879,7 +879,7 @@ ble_ll_adv_aux_scannable_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_b if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR) { *ext_hdr_len += BLE_LL_EXT_ADV_TX_POWER_SIZE; *ext_hdr |= (1 << BLE_LL_EXT_ADV_TX_POWER_BIT); - dptr[0] = advsm->adv_txpwr + g_ble_ll_tx_power_compensation; + dptr[0] = advsm->tx_power + g_ble_ll_tx_power_compensation; dptr += BLE_LL_EXT_ADV_TX_POWER_SIZE; } @@ -1029,8 +1029,8 @@ ble_ll_adv_tx_done(void *arg) { struct ble_ll_adv_sm *advsm; - /* reset power to max after advertising */ - ble_phy_tx_power_set(g_ble_ll_tx_power); + /* reset power to default after advertising */ + ble_ll_tx_power_set(g_ble_ll_tx_power); advsm = (struct ble_ll_adv_sm *)arg; @@ -1111,7 +1111,7 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch) } /* Set the power */ - ble_phy_tx_power_set(advsm->adv_txpwr); + ble_ll_tx_power_set(advsm->tx_power); /* Set channel */ rc = ble_phy_setchan(advsm->adv_chan, BLE_ACCESS_ADDR_ADV, BLE_LL_CRCINIT_ADV); @@ -1255,7 +1255,7 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch) ble_ll_adv_active_chanset_set_sec(advsm); /* Set the power */ - ble_phy_tx_power_set(advsm->adv_txpwr); + ble_ll_tx_power_set(advsm->tx_power); /* Set channel */ aux = AUX_CURRENT(advsm); @@ -1740,7 +1740,7 @@ ble_ll_adv_halt(void) ble_ll_trace_u32(BLE_LL_TRACE_ID_ADV_HALT, advsm->adv_instance); - ble_phy_tx_power_set(g_ble_ll_tx_power); + ble_ll_tx_power_set(g_ble_ll_tx_power); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) if (advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING) { @@ -1858,7 +1858,7 @@ ble_ll_adv_set_adv_params(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } - advsm->adv_txpwr = g_ble_ll_tx_power; + advsm->tx_power = ble_ll_tx_power_round(g_ble_ll_tx_power - g_ble_ll_tx_power_compensation); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) if (cmd->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { @@ -2157,7 +2157,7 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) } if (sync->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_TX_POWER_BIT)) { - dptr[0] = advsm->adv_txpwr + g_ble_ll_tx_power_compensation; + dptr[0] = advsm->tx_power + g_ble_ll_tx_power_compensation; dptr += BLE_LL_EXT_ADV_TX_POWER_SIZE; } @@ -2232,7 +2232,7 @@ ble_ll_adv_sync_tx_start_cb(struct ble_ll_sched_item *sch) ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING); /* Set the power */ - ble_phy_tx_power_set(advsm->adv_txpwr); + ble_phy_tx_power_set(advsm->tx_power); /* Set channel */ sync = SYNC_CURRENT(advsm); @@ -3526,9 +3526,9 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, if (cmd->tx_power == 127) { /* no preference */ - advsm->adv_txpwr = g_ble_ll_tx_power; + advsm->tx_power = ble_ll_tx_power_round(g_ble_ll_tx_power - g_ble_ll_tx_power_compensation); } else { - advsm->adv_txpwr = ble_phy_tx_power_round(cmd->tx_power); + advsm->tx_power = ble_ll_tx_power_round(cmd->tx_power - g_ble_ll_tx_power_compensation); } /* we can always store as those are validated and used only when needed */ @@ -3564,7 +3564,7 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, done: /* Update TX power */ - rsp->tx_power = rc ? 0 : advsm->adv_txpwr; + rsp->tx_power = rc ? 0 : (advsm->tx_power + g_ble_ll_tx_power_compensation); *rsplen = sizeof(*rsp); return rc; diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index eeed8b668e..2d344e2275 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3490,7 +3490,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) #endif /* Update RSSI */ - connsm->conn_rssi = hdr->rxinfo.rssi + g_ble_ll_rx_power_compensation; + connsm->conn_rssi = hdr->rxinfo.rssi - ble_ll_rx_gain(); /* * If we are a peripheral, we can only start to use peripheral latency diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index 1b41bc2dff..2a32ccca2a 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -31,6 +31,7 @@ #include "controller/ble_ll_rfmgmt.h" #include "controller/ble_ll_tmr.h" #include "ble_ll_dtm_priv.h" +#include "ble_ll_priv.h" STATS_SECT_START(ble_ll_dtm_stats) STATS_SECT_ENTRY(rx_count) @@ -243,7 +244,7 @@ ble_ll_dtm_tx_sched_cb(struct ble_ll_sched_item *sch) ble_phy_mode_set(ctx->phy_mode, ctx->phy_mode); #endif ble_phy_set_txend_cb(ble_ll_dtm_tx_done, ctx); - ble_phy_tx_power_set(0); + ble_ll_tx_power_set(g_ble_ll_tx_power); sch->start_time += g_ble_ll_sched_offset_ticks; diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index fa3bf66b45..79d90e5006 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -786,8 +786,8 @@ ble_ll_read_tx_power(uint8_t *rspbuf, uint8_t *rsplen) { struct ble_hci_le_rd_transmit_power_rp *rsp = (void *) rspbuf; - rsp->min_tx_power = ble_phy_tx_power_round(-127); - rsp->max_tx_power = ble_phy_tx_power_round(126); + rsp->min_tx_power = ble_ll_tx_power_round(-127); + rsp->max_tx_power = ble_ll_tx_power_round(126); *rsplen = sizeof(*rsp); return BLE_ERR_SUCCESS; diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index 93ec2e8504..d248d21332 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -124,14 +124,14 @@ ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, if (cmd->tx_power == 127) { /* restore reset default */ - g_ble_ll_tx_power = ble_phy_tx_power_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); + g_ble_ll_tx_power = ble_ll_tx_power_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM) - g_ble_ll_tx_power_compensation); } else { - g_ble_ll_tx_power = ble_phy_tx_power_round(cmd->tx_power); + g_ble_ll_tx_power = ble_ll_tx_power_round(cmd->tx_power - g_ble_ll_tx_power_compensation); } - ble_phy_tx_power_set(g_ble_ll_tx_power); + ble_ll_tx_power_set(g_ble_ll_tx_power); - rsp->tx_power = g_ble_ll_tx_power; + rsp->tx_power = g_ble_ll_tx_power + g_ble_ll_tx_power_compensation; *rsplen = sizeof(*rsp); return BLE_ERR_SUCCESS; diff --git a/nimble/controller/src/ble_ll_priv.h b/nimble/controller/src/ble_ll_priv.h index c373de202e..ccaf9faa8e 100644 --- a/nimble/controller/src/ble_ll_priv.h +++ b/nimble/controller/src/ble_ll_priv.h @@ -28,6 +28,25 @@ extern int8_t g_ble_ll_tx_power; extern int8_t g_ble_ll_tx_power_compensation; extern int8_t g_ble_ll_rx_power_compensation; +int ble_ll_tx_power_round(int tx_power); +void ble_ll_tx_power_set(int tx_power); + +static inline int +ble_ll_rx_gain(void) +{ + int gain = g_ble_ll_rx_power_compensation; + +#if MYNEWT_VAL(BLE_LL_FEM_LNA) +#if MYNEWT_VAL(BLE_LL_FEM_LNA_GAIN_TUNABLE) + gain += ble_ll_fem_lna_rx_gain(); +#else + gain += MYNEWT_VAL(BLE_LL_FEM_LNA_GAIN); +#endif +#endif + + return gain; +} + #ifdef MYNEWT #include "syscfg/syscfg.h" diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index d935405083..a5b3833bb9 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -717,7 +717,7 @@ ble_ll_scan_send_adv_report(uint8_t pdu_type, if (scansm->ext_scanning) { rc = ble_ll_hci_send_legacy_ext_adv_report(evtype, adva, adva_type, - hdr->rxinfo.rssi + g_ble_ll_rx_power_compensation, + hdr->rxinfo.rssi - ble_ll_rx_gain(), adv_data_len, om, inita, inita_type); goto done; @@ -726,12 +726,12 @@ goto done; if (subev == BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT) { rc = ble_ll_hci_send_dir_adv_report(adva, adva_type, inita, inita_type, - hdr->rxinfo.rssi + g_ble_ll_rx_power_compensation); + hdr->rxinfo.rssi - ble_ll_rx_gain()); goto done; } rc = ble_ll_hci_send_adv_report(evtype, adva, adva_type, - hdr->rxinfo.rssi + g_ble_ll_rx_power_compensation, + hdr->rxinfo.rssi - ble_ll_rx_gain(), adv_data_len, om); done: if (!rc && scansm->scan_filt_dups) { diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 0800f4af3b..f7c92d5302 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -409,7 +409,7 @@ ble_ll_hci_ev_update_ext_adv_report_from_ext(struct ble_hci_ev *hci_ev, report->pri_phy = rxinfo->phy; report->sec_phy = 0; report->sid = 0xff; - report->rssi = rxhdr->rxinfo.rssi + g_ble_ll_rx_power_compensation; + report->rssi = rxhdr->rxinfo.rssi - ble_ll_rx_gain(); report->periodic_itvl = 0; report->data_len = 0; @@ -530,7 +530,7 @@ ble_ll_hci_ev_send_ext_adv_report(struct os_mbuf *rxpdu, hci_subev = (void *)(*hci_ev)->data; report = hci_subev->reports; - report->rssi = rxinfo->rssi + g_ble_ll_rx_power_compensation; + report->rssi = rxinfo->rssi - ble_ll_rx_gain(); report->data_len = min(max_data_len, data_len - offset); os_mbuf_copydata(rxpdu, offset, report->data_len, report->data); diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 364e9f58e0..ba750daa61 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -409,6 +409,15 @@ syscfg.defs: BLE_LL_FEM_PA: description: Enable FEM PA support value: MYNEWT_VAL(BLE_LL_PA) + BLE_LL_FEM_PA_GAIN: + description: PA fixed TX gain (in dBm). + value: 0 + BLE_LL_FEM_PA_GAIN_TUNABLE: + description: > + PA TX gain is tunable and not constant. If enabled + ble_ll_fem_pa_tx_power_set() and ble_ll_fem_pa_tx_power_round() + shall be implemented (see ble_ll_fem.h for details). + value: 0 BLE_LL_FEM_PA_GPIO: description: > GPIO pin number to control PA. Pin is set to high state when PA @@ -421,6 +430,15 @@ syscfg.defs: BLE_LL_FEM_LNA: description: Enable LNA support value: MYNEWT_VAL(BLE_LL_LNA) + BLE_LL_FEM_LNA_GAIN: + description: LNA fixed RX gain (in dBm). + value: 0 + BLE_LL_FEM_LNA_GAIN_TUNABLE: + description: > + LNA RX gain is tunable and not constant. If enabled + ble_ll_fem_lna_rx_gain() shall be implemented (see ble_ll_fem.h for + details). + value: 0 BLE_LL_FEM_LNA_GPIO: description: > GPIO pin number to control LNA. Pin is set to high state when LNA From b78a7bd54bc567b819348fbe10166b8b29d4df93 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 3 Oct 2022 08:48:05 +0200 Subject: [PATCH 0564/1333] nimble/ll: Rename BLE_LL_FEM to BLE_FEM FEM is not really related to LL so make it similar to PHY drivers. --- .../controller/{ble_ll_fem.h => ble_fem.h} | 36 +++++++++---------- nimble/controller/pkg.yml | 12 +++---- nimble/controller/src/ble_ll.c | 28 +++++++-------- nimble/controller/src/ble_ll_hci_vs.c | 8 ++--- nimble/controller/src/ble_ll_priv.h | 8 ++--- nimble/controller/syscfg.defunct.yml | 12 +++---- nimble/controller/syscfg.yml | 32 ++++++++--------- nimble/drivers/fem/sky66112/pkg.yml | 6 ++-- nimble/drivers/fem/sky66112/src/sky66112.c | 16 ++++----- nimble/drivers/fem/sky66112/syscfg.yml | 4 +-- nimble/drivers/nrf5x/include/ble/xcvr.h | 4 +-- nimble/drivers/nrf5x/src/ble_phy.c | 24 ++++++------- nimble/drivers/nrf5x/src/nrf52/phy.c | 14 ++++---- nimble/drivers/nrf5x/src/nrf53/phy.c | 14 ++++---- nimble/drivers/nrf5x/src/phy_priv.h | 8 ++--- nimble/drivers/nrf5x/syscfg.yml | 4 +-- 16 files changed, 115 insertions(+), 115 deletions(-) rename nimble/controller/include/controller/{ble_ll_fem.h => ble_fem.h} (65%) diff --git a/nimble/controller/include/controller/ble_ll_fem.h b/nimble/controller/include/controller/ble_fem.h similarity index 65% rename from nimble/controller/include/controller/ble_ll_fem.h rename to nimble/controller/include/controller/ble_fem.h index 48cf94c583..bd0b93e13a 100644 --- a/nimble/controller/include/controller/ble_ll_fem.h +++ b/nimble/controller/include/controller/ble_fem.h @@ -17,8 +17,8 @@ * under the License. */ -#ifndef H_BLE_LL_FEM_ -#define H_BLE_LL_FEM_ +#ifndef H_BLE_FEM_ +#define H_BLE_FEM_ #ifdef __cplusplus extern "C" { @@ -26,38 +26,38 @@ extern "C" { #include "syscfg/syscfg.h" -#if MYNEWT_VAL(BLE_LL_FEM_PA) -void ble_ll_fem_pa_init(void); -void ble_ll_fem_pa_enable(void); -void ble_ll_fem_pa_disable(void); -#if MYNEWT_VAL(BLE_LL_FEM_PA_GAIN_TUNABLE) +#if MYNEWT_VAL(BLE_FEM_PA) +void ble_fem_pa_init(void); +void ble_fem_pa_enable(void); +void ble_fem_pa_disable(void); +#if MYNEWT_VAL(BLE_FEM_PA_GAIN_TUNABLE) /* Configures FEM to selected TX power and returns expected PHY TX power */ -int ble_ll_fem_pa_tx_power_set(int tx_power); +int ble_fem_pa_tx_power_set(int tx_power); /* returns rounded FEM TX power */ -int ble_ll_fem_pa_tx_power_round(int tx_power); +int ble_fem_pa_tx_power_round(int tx_power); #endif #endif -#if MYNEWT_VAL(BLE_LL_FEM_LNA) -void ble_ll_fem_lna_init(void); -void ble_ll_fem_lna_enable(void); -void ble_ll_fem_lna_disable(void); +#if MYNEWT_VAL(BLE_FEM_LNA) +void ble_fem_lna_init(void); +void ble_fem_lna_enable(void); +void ble_fem_lna_disable(void); -#if MYNEWT_VAL(BLE_LL_FEM_LNA_GAIN_TUNABLE) +#if MYNEWT_VAL(BLE_FEM_LNA_GAIN_TUNABLE) /* Return current value of FEM LNA RX gain (in dBm) */ -int ble_ll_fem_lna_rx_gain(void); +int ble_fem_lna_rx_gain(void); #endif #endif -#if MYNEWT_VAL(BLE_LL_FEM_ANTENNA) +#if MYNEWT_VAL(BLE_FEM_ANTENNA) /* 0 sets default antenna, any other value is FEM specific */ -int ble_ll_fem_antenna(uint8_t antenna); +int ble_fem_antenna(uint8_t antenna); #endif #ifdef __cplusplus } #endif -#endif /* H_BLE_LL_FEM_ */ +#endif /* H_BLE_FEM_ */ diff --git a/nimble/controller/pkg.yml b/nimble/controller/pkg.yml index 4462823cf2..678fea17bb 100644 --- a/nimble/controller/pkg.yml +++ b/nimble/controller/pkg.yml @@ -29,12 +29,12 @@ pkg.req_apis: - ble_driver - ble_transport - stats -pkg.req_apis.BLE_LL_FEM_PA: - - ble_ll_fem_pa -pkg.req_apis.BLE_LL_FEM_LNA: - - ble_ll_fem_lna -pkg.req_apis.BLE_LL_FEM_ANTENNA: - - ble_ll_fem_antenna +pkg.req_apis.BLE_FEM_PA: + - ble_fem_pa +pkg.req_apis.BLE_FEM_LNA: + - ble_fem_lna +pkg.req_apis.BLE_FEM_ANTENNA: + - ble_fem_antenna pkg.deps: - "@apache-mynewt-core/kernel/os" diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 64c4f6e72b..ec66fc5374 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -43,7 +43,7 @@ #include "controller/ble_ll_rfmgmt.h" #include "controller/ble_ll_trace.h" #include "controller/ble_ll_sync.h" -#include "controller/ble_ll_fem.h" +#include "controller/ble_fem.h" #include "ble_ll_conn_priv.h" #include "ble_ll_hci_priv.h" #include "ble_ll_priv.h" @@ -1652,11 +1652,11 @@ ble_ll_reset(void) #endif -#if MYNEWT_VAL(BLE_LL_FEM_PA) - ble_ll_fem_pa_init(); +#if MYNEWT_VAL(BLE_FEM_PA) + ble_fem_pa_init(); #endif -#if MYNEWT_VAL(BLE_LL_FEM_LNA) - ble_ll_fem_lna_init(); +#if MYNEWT_VAL(BLE_FEM_LNA) + ble_fem_lna_init(); #endif /* Re-initialize the PHY */ @@ -1992,12 +1992,12 @@ ble_transport_ll_init(void) int ble_ll_tx_power_round(int tx_power) { -#if MYNEWT_VAL(BLE_LL_FEM_PA) -#if MYNEWT_VAL(BLE_LL_FEM_PA_GAIN_TUNABLE) - tx_power = ble_ll_fem_pa_tx_power_round(tx_power); +#if MYNEWT_VAL(BLE_FEM_PA) +#if MYNEWT_VAL(BLE_FEM_PA_GAIN_TUNABLE) + tx_power = ble_fem_pa_tx_power_round(tx_power); #else tx_power = ble_phy_tx_power_round(tx_power); - tx_power += MYNEWT_VAL(BLE_LL_FEM_PA_GAIN); + tx_power += MYNEWT_VAL(BLE_FEM_PA_GAIN); #endif #else tx_power = ble_phy_tx_power_round(tx_power); @@ -2009,15 +2009,15 @@ ble_ll_tx_power_round(int tx_power) void ble_ll_tx_power_set(int tx_power) { -#if MYNEWT_VAL(BLE_LL_FEM_PA) -#if MYNEWT_VAL(BLE_LL_FEM_PA_GAIN_TUNABLE) +#if MYNEWT_VAL(BLE_FEM_PA) +#if MYNEWT_VAL(BLE_FEM_PA_GAIN_TUNABLE) /* TODO should rounding be in assert only? or just skip it and assume * power is already rounded? */ - tx_power = ble_ll_fem_pa_tx_power_round(tx_power); - tx_power = ble_ll_fem_pa_tx_power_set(tx_power); + tx_power = ble_fem_pa_tx_power_round(tx_power); + tx_power = ble_fem_pa_tx_power_set(tx_power); #else - tx_power -= MYNEWT_VAL(BLE_LL_FEM_PA_GAIN); + tx_power -= MYNEWT_VAL(BLE_FEM_PA_GAIN); #endif #endif ble_phy_tx_power_set(tx_power); diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index d248d21332..e9c4e2d17b 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -25,7 +25,7 @@ #include "controller/ble_ll_adv.h" #include "controller/ble_ll_scan.h" #include "controller/ble_hw.h" -#include "controller/ble_ll_fem.h" +#include "controller/ble_fem.h" #include "ble_ll_conn_priv.h" #include "ble_ll_priv.h" @@ -352,7 +352,7 @@ ble_ll_hci_vs_set_data_len(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, } #endif -#if MYNEWT_VAL(BLE_LL_FEM_ANTENNA) +#if MYNEWT_VAL(BLE_FEM_ANTENNA) static int ble_ll_hci_vs_set_antenna(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen) @@ -367,7 +367,7 @@ ble_ll_hci_vs_set_antenna(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, return BLE_ERR_CMD_DISALLOWED; } - if (ble_ll_fem_antenna(cmd->antenna)) { + if (ble_fem_antenna(cmd->antenna)) { return BLE_ERR_INV_HCI_CMD_PARMS; } @@ -398,7 +398,7 @@ static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_DATA_LEN, ble_ll_hci_vs_set_data_len), #endif -#if MYNEWT_VAL(BLE_LL_FEM_ANTENNA) +#if MYNEWT_VAL(BLE_FEM_ANTENNA) BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_ANTENNA, ble_ll_hci_vs_set_antenna), #endif }; diff --git a/nimble/controller/src/ble_ll_priv.h b/nimble/controller/src/ble_ll_priv.h index ccaf9faa8e..1ee30882c5 100644 --- a/nimble/controller/src/ble_ll_priv.h +++ b/nimble/controller/src/ble_ll_priv.h @@ -36,11 +36,11 @@ ble_ll_rx_gain(void) { int gain = g_ble_ll_rx_power_compensation; -#if MYNEWT_VAL(BLE_LL_FEM_LNA) -#if MYNEWT_VAL(BLE_LL_FEM_LNA_GAIN_TUNABLE) - gain += ble_ll_fem_lna_rx_gain(); +#if MYNEWT_VAL(BLE_FEM_LNA) +#if MYNEWT_VAL(BLE_FEM_LNA_GAIN_TUNABLE) + gain += ble_fem_lna_rx_gain(); #else - gain += MYNEWT_VAL(BLE_LL_FEM_LNA_GAIN); + gain += MYNEWT_VAL(BLE_FEM_LNA_GAIN); #endif #endif diff --git a/nimble/controller/syscfg.defunct.yml b/nimble/controller/syscfg.defunct.yml index 6190c6bc11..239861287f 100644 --- a/nimble/controller/syscfg.defunct.yml +++ b/nimble/controller/syscfg.defunct.yml @@ -47,27 +47,27 @@ syscfg.defs: value: 0x0B65 deprecated: 1 BLE_LL_PA: - description: use BLE_LL_FEM_PA + description: use BLE_FEM_PA value: 0 deprecated: 1 BLE_LL_PA_GPIO: - description: use BLE_LL_FEM_PA_GPIO + description: use BLE_FEM_PA_GPIO value: -1 deprecated: 1 BLE_LL_PA_TURN_ON_US: - description: use BLE_LL_FEM_PA_TURN_ON_US + description: use BLE_FEM_PA_TURN_ON_US value: 1 deprecated: 1 BLE_LL_LNA: - description: use BLE_LL_FEM_LNA + description: use BLE_FEM_LNA value: 0 deprecated: 1 BLE_LL_LNA_GPIO: - description: use BLE_LL_FEM_LNA_GPIO + description: use BLE_FEM_LNA_GPIO value: -1 deprecated: 1 BLE_LL_LNA_TURN_ON_US: - description: use BLE_LL_FEM_LNA_TURN_ON_US + description: use BLE_FEM_LNA_TURN_ON_US value: 1 deprecated: 1 diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index ba750daa61..13295a309c 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -406,49 +406,49 @@ syscfg.defs: line number where assertion occured. value: MYNEWT_VAL(BLE_LL_VND_EVENT_ON_ASSERT) - BLE_LL_FEM_PA: + BLE_FEM_PA: description: Enable FEM PA support value: MYNEWT_VAL(BLE_LL_PA) - BLE_LL_FEM_PA_GAIN: + BLE_FEM_PA_GAIN: description: PA fixed TX gain (in dBm). value: 0 - BLE_LL_FEM_PA_GAIN_TUNABLE: + BLE_FEM_PA_GAIN_TUNABLE: description: > PA TX gain is tunable and not constant. If enabled - ble_ll_fem_pa_tx_power_set() and ble_ll_fem_pa_tx_power_round() - shall be implemented (see ble_ll_fem.h for details). + ble_fem_pa_tx_power_set() and ble_fem_pa_tx_power_round() + shall be implemented (see ble_fem.h for details). value: 0 - BLE_LL_FEM_PA_GPIO: + BLE_FEM_PA_GPIO: description: > GPIO pin number to control PA. Pin is set to high state when PA should be enabled. value: MYNEWT_VAL(BLE_LL_PA_GPIO) - BLE_LL_FEM_PA_TURN_ON_US: + BLE_FEM_PA_TURN_ON_US: description: > Time required for PA to turn on, in microseconds. value: MYNEWT_VAL(BLE_LL_PA_TURN_ON_US) - BLE_LL_FEM_LNA: + BLE_FEM_LNA: description: Enable LNA support value: MYNEWT_VAL(BLE_LL_LNA) - BLE_LL_FEM_LNA_GAIN: + BLE_FEM_LNA_GAIN: description: LNA fixed RX gain (in dBm). value: 0 - BLE_LL_FEM_LNA_GAIN_TUNABLE: + BLE_FEM_LNA_GAIN_TUNABLE: description: > LNA RX gain is tunable and not constant. If enabled - ble_ll_fem_lna_rx_gain() shall be implemented (see ble_ll_fem.h for + ble_fem_lna_rx_gain() shall be implemented (see ble_fem.h for details). value: 0 - BLE_LL_FEM_LNA_GPIO: + BLE_FEM_LNA_GPIO: description: > GPIO pin number to control LNA. Pin is set to high state when LNA should be enabled. value: MYNEWT_VAL(BLE_LL_LNA_GPIO) - BLE_LL_FEM_LNA_TURN_ON_US: + BLE_FEM_LNA_TURN_ON_US: description: > Time required for LNA to turn on, in microseconds. value: MYNEWT_VAL(BLE_LL_LNA_TURN_ON_US) - BLE_LL_FEM_ANTENNA: + BLE_FEM_ANTENNA: description: > Enable support for runtime antenna selection in FEM. value: 0 @@ -541,8 +541,8 @@ syscfg.vals.'!BLE_HOST && !BABBLESIM': syscfg.restrictions: - BLE_TRANSPORT_LL == "native" - BLE_LL_PUBLIC_DEV_ADDR <= 0xffffffffffff - - BLE_LL_FEM_PA == 0 || BLE_LL_FEM_PA_GPIO >= 0 - - BLE_LL_FEM_LNA == 0 || BLE_LL_FEM_LNA_GPIO >= 0 + - BLE_FEM_PA == 0 || BLE_FEM_PA_GPIO >= 0 + - BLE_FEM_LNA == 0 || BLE_FEM_LNA_GPIO >= 0 $import: # defunct and deprecated settings diff --git a/nimble/drivers/fem/sky66112/pkg.yml b/nimble/drivers/fem/sky66112/pkg.yml index 532fe212a9..822cfaa857 100644 --- a/nimble/drivers/fem/sky66112/pkg.yml +++ b/nimble/drivers/fem/sky66112/pkg.yml @@ -22,9 +22,9 @@ pkg.description: Driver for SKY66112 front-end module pkg.author: "Apache Mynewt " pkg.homepage: "https://mynewt.apache.org/" pkg.apis: - - ble_ll_fem_pa - - ble_ll_fem_lna - - ble_ll_fem_antenna + - ble_fem_pa + - ble_fem_lna + - ble_fem_antenna pkg.deps: - nimble/controller diff --git a/nimble/drivers/fem/sky66112/src/sky66112.c b/nimble/drivers/fem/sky66112/src/sky66112.c index 9e9ceab691..873afa1060 100644 --- a/nimble/drivers/fem/sky66112/src/sky66112.c +++ b/nimble/drivers/fem/sky66112/src/sky66112.c @@ -21,7 +21,7 @@ #include #include "syscfg/syscfg.h" #include "hal/hal_gpio.h" -#include "controller/ble_ll_fem.h" +#include "controller/ble_fem.h" static struct { uint8_t rx_bypass : 1; @@ -41,13 +41,13 @@ sky66112_bypass(uint8_t enabled) } void -ble_ll_fem_pa_init(void) +ble_fem_pa_init(void) { /* Nothing to do here */ } void -ble_ll_fem_pa_enable(void) +ble_fem_pa_enable(void) { if (sky66112_config.tx_bypass) { sky66112_bypass(1); @@ -55,7 +55,7 @@ ble_ll_fem_pa_enable(void) } void -ble_ll_fem_pa_disable(void) +ble_fem_pa_disable(void) { if (sky66112_config.tx_bypass) { sky66112_bypass(0); @@ -63,13 +63,13 @@ ble_ll_fem_pa_disable(void) } void -ble_ll_fem_lna_init(void) +ble_fem_lna_init(void) { /* Nothing to do here */ } void -ble_ll_fem_lna_enable(void) +ble_fem_lna_enable(void) { if (sky66112_config.rx_bypass) { sky66112_bypass(1); @@ -77,7 +77,7 @@ ble_ll_fem_lna_enable(void) } void -ble_ll_fem_lna_disable(void) +ble_fem_lna_disable(void) { if (sky66112_config.rx_bypass) { sky66112_bypass(0); @@ -95,7 +95,7 @@ sky66112_tx_hp_mode(uint8_t enabled) } int -ble_ll_fem_antenna(uint8_t port) +ble_fem_antenna(uint8_t port) { int pin = MYNEWT_VAL(SKY66112_PIN_SEL); diff --git a/nimble/drivers/fem/sky66112/syscfg.yml b/nimble/drivers/fem/sky66112/syscfg.yml index 1da8397888..d946831f05 100644 --- a/nimble/drivers/fem/sky66112/syscfg.yml +++ b/nimble/drivers/fem/sky66112/syscfg.yml @@ -64,10 +64,10 @@ syscfg.defs: range: 1, 2 value: 1 -syscfg.vals.!BLE_LL_FEM_PA: +syscfg.vals.!BLE_FEM_PA: # Enable TX bypass by default if PA is disabled SKY66112_TX_BYPASS: 1 -syscfg.vals.!BLE_LL_FEM_LNA: +syscfg.vals.!BLE_FEM_LNA: # Enable RX bypass by default if LNA is disabled SKY66112_RX_BYPASS: 1 diff --git a/nimble/drivers/nrf5x/include/ble/xcvr.h b/nimble/drivers/nrf5x/include/ble/xcvr.h index 829514b422..bb2da56845 100644 --- a/nimble/drivers/nrf5x/include/ble/xcvr.h +++ b/nimble/drivers/nrf5x/include/ble/xcvr.h @@ -35,8 +35,8 @@ extern "C" { * * TODO this file should be refactored... */ -#if (MYNEWT_VAL(BLE_LL_FEM_PA) && (MYNEWT_VAL(BLE_LL_FEM_PA_TURN_ON_US) > 60)) || \ - (MYNEWT_VAL(BLE_LL_FEM_LNA) && (MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US) > 60)) +#if (MYNEWT_VAL(BLE_FEM_PA) && (MYNEWT_VAL(BLE_FEM_PA_TURN_ON_US) > 60)) || \ + (MYNEWT_VAL(BLE_FEM_LNA) && (MYNEWT_VAL(BLE_FEM_LNA_TURN_ON_US) > 60)) #define XCVR_PROC_DELAY_USECS (183) #else #define XCVR_PROC_DELAY_USECS (153) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 24f2ed686d..3b9fa1e9f5 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include @@ -634,12 +634,12 @@ ble_phy_set_start_time(uint32_t cputime, uint8_t rem_us, bool tx) radio_rem_us = rem_us - BLE_PHY_T_TXENFAST - g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; #if PHY_USE_FEM_PA - fem_rem_us = rem_us - MYNEWT_VAL(BLE_LL_FEM_PA_TURN_ON_US); + fem_rem_us = rem_us - MYNEWT_VAL(BLE_FEM_PA_TURN_ON_US); #endif } else { radio_rem_us = rem_us - BLE_PHY_T_TXENFAST; #if PHY_USE_FEM_LNA - fem_rem_us = rem_us - MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US); + fem_rem_us = rem_us - MYNEWT_VAL(BLE_FEM_LNA_TURN_ON_US); #endif } @@ -756,14 +756,14 @@ ble_phy_set_start_now(void) */ #if PHY_USE_FEM_LNA - if (MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US) > BLE_PHY_T_RXENFAST) { - radio_rem_us = 1 + MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US) - + if (MYNEWT_VAL(BLE_FEM_LNA_TURN_ON_US) > BLE_PHY_T_RXENFAST) { + radio_rem_us = 1 + MYNEWT_VAL(BLE_FEM_LNA_TURN_ON_US) - BLE_PHY_T_RXENFAST; fem_rem_us = 1; } else { radio_rem_us = 1; fem_rem_us = 1 + BLE_PHY_T_RXENFAST - - MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US); + MYNEWT_VAL(BLE_FEM_LNA_TURN_ON_US); } #else radio_rem_us = 1; @@ -1071,7 +1071,7 @@ ble_phy_tx_end_isr(void) rx_time -= 2; #if PHY_USE_FEM_LNA - fem_time = rx_time - MYNEWT_VAL(BLE_LL_FEM_LNA_TURN_ON_US); + fem_time = rx_time - MYNEWT_VAL(BLE_FEM_LNA_TURN_ON_US); nrf_timer_cc_set(NRF_TIMER0, 2, fem_time); NRF_TIMER0->EVENTS_COMPARE[2] = 0; phy_fem_enable_lna(); @@ -1228,7 +1228,7 @@ ble_phy_rx_end_isr(void) tx_time -= g_ble_phy_t_rxenddelay[ble_hdr->rxinfo.phy_mode]; #if PHY_USE_FEM_PA - fem_time = tx_time - MYNEWT_VAL(BLE_LL_FEM_PA_TURN_ON_US); + fem_time = tx_time - MYNEWT_VAL(BLE_FEM_PA_TURN_ON_US); #endif /* Adjust for delay between EVENT_READY and actual TX start time */ @@ -1454,9 +1454,9 @@ ble_phy_isr(void) switch (g_ble_phy_data.phy_state) { case BLE_PHY_STATE_RX: -#if MYNEWT_VAL(BLE_LL_FEM_LNA) +#if MYNEWT_VAL(BLE_FEM_LNA) phy_ppi_fem_disable(); - ble_ll_fem_lna_disable(); + ble_fem_lna_disable(); #endif if (g_ble_phy_data.phy_rx_started) { ble_phy_rx_end_isr(); @@ -1465,9 +1465,9 @@ ble_phy_isr(void) } break; case BLE_PHY_STATE_TX: -#if MYNEWT_VAL(BLE_LL_FEM_PA) +#if MYNEWT_VAL(BLE_FEM_PA) phy_ppi_fem_disable(); - ble_ll_fem_pa_disable(); + ble_fem_pa_disable(); #endif ble_phy_tx_end_isr(); break; diff --git a/nimble/drivers/nrf5x/src/nrf52/phy.c b/nimble/drivers/nrf5x/src/nrf52/phy.c index 188d157111..6a6eeb882c 100644 --- a/nimble/drivers/nrf5x/src/nrf52/phy.c +++ b/nimble/drivers/nrf5x/src/nrf52/phy.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include "../phy_priv.h" #if PHY_USE_DEBUG @@ -85,19 +85,19 @@ phy_fem_init(void) { #if PHY_USE_FEM_SINGLE_GPIO #if PHY_USE_FEM_PA - phy_gpiote_configure(PHY_GPIOTE_FEM, MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); + phy_gpiote_configure(PHY_GPIOTE_FEM, MYNEWT_VAL(BLE_FEM_PA_GPIO)); #else - phy_gpiote_configure(PHY_GPIOTE_FEM, MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)); + phy_gpiote_configure(PHY_GPIOTE_FEM, MYNEWT_VAL(BLE_FEM_LNA_GPIO)); #endif NRF_PPI->CH[6].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_SET[PHY_GPIOTE_FEM]); NRF_PPI->CH[7].TEP = (uint32_t)&(NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM]); #else #if PHY_USE_FEM_PA - phy_gpiote_configure(PHY_GPIOTE_FEM_PA, MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); + phy_gpiote_configure(PHY_GPIOTE_FEM_PA, MYNEWT_VAL(BLE_FEM_PA_GPIO)); NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM_PA] = 1; #endif #if PHY_USE_FEM_LNA - phy_gpiote_configure(PHY_GPIOTE_FEM_LNA, MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)); + phy_gpiote_configure(PHY_GPIOTE_FEM_LNA, MYNEWT_VAL(BLE_FEM_LNA_GPIO)); NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM_LNA] = 1; #endif #endif /* PHY_USE_FEM_SINGLE_GPIO */ @@ -112,7 +112,7 @@ phy_fem_init(void) void phy_fem_enable_pa(void) { - ble_ll_fem_pa_enable(); + ble_fem_pa_enable(); #if !PHY_USE_FEM_SINGLE_GPIO /* Switch FEM channels to control PA */ @@ -128,7 +128,7 @@ phy_fem_enable_pa(void) void phy_fem_enable_lna(void) { - ble_ll_fem_lna_enable(); + ble_fem_lna_enable(); #if !PHY_USE_FEM_SINGLE_GPIO /* Switch FEM channels to control LNA */ diff --git a/nimble/drivers/nrf5x/src/nrf53/phy.c b/nimble/drivers/nrf5x/src/nrf53/phy.c index 78b45578c5..0d9ab1a76e 100644 --- a/nimble/drivers/nrf5x/src/nrf53/phy.c +++ b/nimble/drivers/nrf5x/src/nrf53/phy.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include "../phy_priv.h" #if PHY_USE_DEBUG @@ -81,9 +81,9 @@ phy_fem_init() #if PHY_USE_FEM_SINGLE_GPIO #if PHY_USE_FEM_PA - phy_gpiote_configure(PHY_GPIOTE_FEM, MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); + phy_gpiote_configure(PHY_GPIOTE_FEM, MYNEWT_VAL(BLE_FEM_PA_GPIO)); #else - phy_gpiote_configure(PHY_GPIOTE_FEM, MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)); + phy_gpiote_configure(PHY_GPIOTE_FEM, MYNEWT_VAL(BLE_FEM_LNA_GPIO)); #endif NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_FEM] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_2); @@ -92,7 +92,7 @@ phy_fem_init() NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM] = 1; #else #if PHY_USE_FEM_PA - phy_gpiote_configure(PHY_GPIOTE_FEM_PA, MYNEWT_VAL(BLE_LL_FEM_PA_GPIO)); + phy_gpiote_configure(PHY_GPIOTE_FEM_PA, MYNEWT_VAL(BLE_FEM_PA_GPIO)); NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_FEM_PA] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_2); NRF_GPIOTE->SUBSCRIBE_CLR[PHY_GPIOTE_FEM_PA] = @@ -100,7 +100,7 @@ phy_fem_init() NRF_GPIOTE->TASKS_CLR[PHY_GPIOTE_FEM_PA] = 1; #endif #if PHY_USE_FEM_LNA - phy_gpiote_configure(PHY_GPIOTE_FEM_LNA, MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)); + phy_gpiote_configure(PHY_GPIOTE_FEM_LNA, MYNEWT_VAL(BLE_FEM_LNA_GPIO)); NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_FEM_LNA] = DPPI_CH_UNSUB(TIMER0_EVENTS_COMPARE_2); NRF_GPIOTE->SUBSCRIBE_CLR[PHY_GPIOTE_FEM_LNA] = @@ -115,7 +115,7 @@ phy_fem_init() void phy_fem_enable_pa(void) { - ble_ll_fem_pa_enable(); + ble_fem_pa_enable(); #if PHY_USE_FEM_SINGLE_GPIO NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_FEM] = @@ -129,7 +129,7 @@ phy_fem_enable_pa(void) void phy_fem_enable_lna(void) { - ble_ll_fem_lna_enable(); + ble_fem_lna_enable(); #if PHY_USE_FEM_SINGLE_GPIO NRF_GPIOTE->SUBSCRIBE_SET[PHY_GPIOTE_FEM] = diff --git a/nimble/drivers/nrf5x/src/phy_priv.h b/nimble/drivers/nrf5x/src/phy_priv.h index 8cf140ee3d..664d625c97 100644 --- a/nimble/drivers/nrf5x/src/phy_priv.h +++ b/nimble/drivers/nrf5x/src/phy_priv.h @@ -29,13 +29,13 @@ #define PHY_USE_DEBUG_3 (MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0) #define PHY_USE_DEBUG (PHY_USE_DEBUG_1 || PHY_USE_DEBUG_2 || PHY_USE_DEBUG_3) -#define PHY_USE_FEM_PA (MYNEWT_VAL(BLE_LL_FEM_PA) != 0) -#define PHY_USE_FEM_LNA (MYNEWT_VAL(BLE_LL_FEM_LNA) != 0) +#define PHY_USE_FEM_PA (MYNEWT_VAL(BLE_FEM_PA) != 0) +#define PHY_USE_FEM_LNA (MYNEWT_VAL(BLE_FEM_LNA) != 0) #define PHY_USE_FEM (PHY_USE_FEM_PA || PHY_USE_FEM_LNA) #define PHY_USE_FEM_SINGLE_GPIO \ (PHY_USE_FEM && (!PHY_USE_FEM_PA || !PHY_USE_FEM_LNA || \ - (MYNEWT_VAL(BLE_LL_FEM_PA_GPIO) == \ - MYNEWT_VAL(BLE_LL_FEM_LNA_GPIO)))) + (MYNEWT_VAL(BLE_FEM_PA_GPIO) == \ + MYNEWT_VAL(BLE_FEM_LNA_GPIO)))) /* GPIOTE indexes, start assigning from last one */ #define PHY_GPIOTE_DEBUG_1 (8 - PHY_USE_DEBUG_1) diff --git a/nimble/drivers/nrf5x/syscfg.yml b/nimble/drivers/nrf5x/syscfg.yml index 1d4027f7d0..af4c62d3ec 100644 --- a/nimble/drivers/nrf5x/syscfg.yml +++ b/nimble/drivers/nrf5x/syscfg.yml @@ -56,5 +56,5 @@ syscfg.defs: syscfg.restrictions: # code supports turn on times up to 90us due to some optimizations, but it # should be enough for most (all?) cases - - "!BLE_LL_FEM_PA || BLE_LL_FEM_PA_TURN_ON_US <= 90" - - "!BLE_LL_FEM_LNA || BLE_LL_FEM_LNA_TURN_ON_US <= 90" + - "!BLE_FEM_PA || BLE_FEM_PA_TURN_ON_US <= 90" + - "!BLE_FEM_LNA || BLE_FEM_LNA_TURN_ON_US <= 90" From b21575c894402009387ef0a80d9d013c5c81bc93 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 3 Oct 2022 08:51:05 +0200 Subject: [PATCH 0565/1333] nimble/ports: Refresh syscfg --- .../examples/linux/include/syscfg/syscfg.h | 53 ++++++++- .../linux_blemesh/include/syscfg/syscfg.h | 54 ++++++++- .../examples/nuttx/include/syscfg/syscfg.h | 53 ++++++++- porting/nimble/include/syscfg/syscfg.h | 53 ++++++++- porting/npl/riot/include/syscfg/syscfg.h | 106 +++++++++++++++--- 5 files changed, 290 insertions(+), 29 deletions(-) diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index cfffe63884..c98da2aba3 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -719,14 +719,14 @@ #define MYNEWT_VAL_BLE_L2CAP_COC_MPS (MYNEWT_VAL_MSYS_1_BLOCK_SIZE-8) #endif -#ifndef MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC -#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) -#endif - #ifndef MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT #define MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT (1) #endif +#ifndef MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC +#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS #define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1) #endif @@ -1193,4 +1193,49 @@ #define MYNEWT_VAL_TARGET_linux (1) #endif +/*** Included packages */ +#define MYNEWT_PKG_apache_mynewt_core__compiler_sim 1 +#define MYNEWT_PKG_apache_mynewt_core__crypto_tinycrypt 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_bsp_native 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_flash_enc_flash 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_flash_enc_flash_ef_tinycrypt 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_trng 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_trng_trng_sw 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart_uart_hal 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_hal 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_mcu_native 1 +#define MYNEWT_PKG_apache_mynewt_core__kernel_os 1 +#define MYNEWT_PKG_apache_mynewt_core__kernel_sim 1 +#define MYNEWT_PKG_apache_mynewt_core__net_ip_mn_socket 1 +#define MYNEWT_PKG_apache_mynewt_core__net_ip_native_sockets 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_console_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_defs 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_flash_map 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_common 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_modlog 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_stats_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sys 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sysdown 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sysinit 1 +#define MYNEWT_PKG_apache_mynewt_core__util_mem 1 +#define MYNEWT_PKG_apache_mynewt_core__util_rwlock 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ans 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_bas 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_dis 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gap 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gatt 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ias 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ipss 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_lls 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_tps 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_transport 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_socket 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_npl_mynewt 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_linux 1 + #endif diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index a7cc7de5df..851337c7d1 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -720,14 +720,14 @@ #define MYNEWT_VAL_BLE_L2CAP_COC_MPS (MYNEWT_VAL_MSYS_1_BLOCK_SIZE-8) #endif -#ifndef MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC -#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) -#endif - #ifndef MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT #define MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT (1) #endif +#ifndef MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC +#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS #define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1) #endif @@ -1768,4 +1768,50 @@ #define MYNEWT_VAL_TARGET_linux_blemesh (1) #endif +/*** Included packages */ +#define MYNEWT_PKG_apache_mynewt_core__compiler_sim 1 +#define MYNEWT_PKG_apache_mynewt_core__crypto_tinycrypt 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_bsp_native 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_flash_enc_flash 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_flash_enc_flash_ef_tinycrypt 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_trng 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_trng_trng_sw 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart_uart_hal 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_hal 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_mcu_native 1 +#define MYNEWT_PKG_apache_mynewt_core__kernel_os 1 +#define MYNEWT_PKG_apache_mynewt_core__kernel_sim 1 +#define MYNEWT_PKG_apache_mynewt_core__net_ip_mn_socket 1 +#define MYNEWT_PKG_apache_mynewt_core__net_ip_native_sockets 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_console_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_defs 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_flash_map 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_common 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_modlog 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_stats_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sys 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sysdown 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sysinit 1 +#define MYNEWT_PKG_apache_mynewt_core__util_mem 1 +#define MYNEWT_PKG_apache_mynewt_core__util_rwlock 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_mesh 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ans 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_bas 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_dis 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gap 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gatt 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ias 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ipss 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_lls 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_tps 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_transport 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_socket 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_npl_mynewt 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_linux_blemesh 1 + #endif diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index b257c9f915..e0f0734926 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -719,14 +719,14 @@ #define MYNEWT_VAL_BLE_L2CAP_COC_MPS (MYNEWT_VAL_MSYS_1_BLOCK_SIZE-8) #endif -#ifndef MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC -#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) -#endif - #ifndef MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT #define MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT (1) #endif +#ifndef MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC +#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS #define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1) #endif @@ -1195,4 +1195,49 @@ #define MYNEWT_VAL_TARGET_nuttx (1) #endif +/*** Included packages */ +#define MYNEWT_PKG_apache_mynewt_core__compiler_sim 1 +#define MYNEWT_PKG_apache_mynewt_core__crypto_tinycrypt 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_bsp_native 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_flash_enc_flash 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_flash_enc_flash_ef_tinycrypt 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_trng 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_trng_trng_sw 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart_uart_hal 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_hal 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_mcu_native 1 +#define MYNEWT_PKG_apache_mynewt_core__kernel_os 1 +#define MYNEWT_PKG_apache_mynewt_core__kernel_sim 1 +#define MYNEWT_PKG_apache_mynewt_core__net_ip_mn_socket 1 +#define MYNEWT_PKG_apache_mynewt_core__net_ip_native_sockets 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_console_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_defs 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_flash_map 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_common 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_modlog 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_stats_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sys 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sysdown 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sysinit 1 +#define MYNEWT_PKG_apache_mynewt_core__util_mem 1 +#define MYNEWT_PKG_apache_mynewt_core__util_rwlock 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ans 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_bas 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_dis 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gap 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gatt 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ias 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ipss 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_lls 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_tps 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_transport 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_socket 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_npl_mynewt 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_nuttx 1 + #endif diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index 6f8710be7b..0184055e73 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -718,14 +718,14 @@ #define MYNEWT_VAL_BLE_L2CAP_COC_MPS (MYNEWT_VAL_MSYS_1_BLOCK_SIZE-8) #endif -#ifndef MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC -#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) -#endif - #ifndef MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT #define MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT (1) #endif +#ifndef MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC +#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS #define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1) #endif @@ -1190,4 +1190,49 @@ #define MYNEWT_VAL_TARGET_porting_default (1) #endif +/*** Included packages */ +#define MYNEWT_PKG_apache_mynewt_core__compiler_sim 1 +#define MYNEWT_PKG_apache_mynewt_core__crypto_tinycrypt 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_bsp_native 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_flash_enc_flash 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_flash_enc_flash_ef_tinycrypt 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_trng 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_trng_trng_sw 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart_uart_hal 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_hal 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_mcu_native 1 +#define MYNEWT_PKG_apache_mynewt_core__kernel_os 1 +#define MYNEWT_PKG_apache_mynewt_core__kernel_sim 1 +#define MYNEWT_PKG_apache_mynewt_core__net_ip_mn_socket 1 +#define MYNEWT_PKG_apache_mynewt_core__net_ip_native_sockets 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_console_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_defs 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_flash_map 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_common 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_modlog 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_stats_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sys 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sysdown 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sysinit 1 +#define MYNEWT_PKG_apache_mynewt_core__util_mem 1 +#define MYNEWT_PKG_apache_mynewt_core__util_rwlock 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ans 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_bas 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_dis 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gap 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gatt 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ias 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ipss 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_lls 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_tps 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_transport 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_socket 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_npl_mynewt 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_porting_default 1 + #endif diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 280fac615e..1945d28a57 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -670,6 +670,10 @@ #define MYNEWT_VAL_BASELIBC_PRESENT (1) #endif +#ifndef MYNEWT_VAL_BASELIBC_THREAD_SAFE_HEAP_ALLOCATION +#define MYNEWT_VAL_BASELIBC_THREAD_SAFE_HEAP_ALLOCATION (0) +#endif + /*** @apache-mynewt-core/sys/console/stub */ #ifndef MYNEWT_VAL_CONSOLE_UART_BAUD #define MYNEWT_VAL_CONSOLE_UART_BAUD (115200) @@ -871,6 +875,56 @@ #define MYNEWT_VAL_BLE_DEVICE (1) #endif +#ifndef MYNEWT_VAL_BLE_FEM_ANTENNA +#define MYNEWT_VAL_BLE_FEM_ANTENNA (0) +#endif + +/* Value copied from BLE_LL_LNA */ +#ifndef MYNEWT_VAL_BLE_FEM_LNA +#define MYNEWT_VAL_BLE_FEM_LNA (0) +#endif + +#ifndef MYNEWT_VAL_BLE_FEM_LNA_GAIN +#define MYNEWT_VAL_BLE_FEM_LNA_GAIN (0) +#endif + +#ifndef MYNEWT_VAL_BLE_FEM_LNA_GAIN_TUNABLE +#define MYNEWT_VAL_BLE_FEM_LNA_GAIN_TUNABLE (0) +#endif + +/* Value copied from BLE_LL_LNA_GPIO */ +#ifndef MYNEWT_VAL_BLE_FEM_LNA_GPIO +#define MYNEWT_VAL_BLE_FEM_LNA_GPIO (-1) +#endif + +/* Value copied from BLE_LL_LNA_TURN_ON_US */ +#ifndef MYNEWT_VAL_BLE_FEM_LNA_TURN_ON_US +#define MYNEWT_VAL_BLE_FEM_LNA_TURN_ON_US (1) +#endif + +/* Value copied from BLE_LL_PA */ +#ifndef MYNEWT_VAL_BLE_FEM_PA +#define MYNEWT_VAL_BLE_FEM_PA (0) +#endif + +#ifndef MYNEWT_VAL_BLE_FEM_PA_GAIN +#define MYNEWT_VAL_BLE_FEM_PA_GAIN (0) +#endif + +#ifndef MYNEWT_VAL_BLE_FEM_PA_GAIN_TUNABLE +#define MYNEWT_VAL_BLE_FEM_PA_GAIN_TUNABLE (0) +#endif + +/* Value copied from BLE_LL_PA_GPIO */ +#ifndef MYNEWT_VAL_BLE_FEM_PA_GPIO +#define MYNEWT_VAL_BLE_FEM_PA_GPIO (-1) +#endif + +/* Value copied from BLE_LL_PA_TURN_ON_US */ +#ifndef MYNEWT_VAL_BLE_FEM_PA_TURN_ON_US +#define MYNEWT_VAL_BLE_FEM_PA_TURN_ON_US (1) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ #ifndef MYNEWT_VAL_BLE_HW_WHITELIST_ENABLE #define MYNEWT_VAL_BLE_HW_WHITELIST_ENABLE (0) @@ -1253,7 +1307,7 @@ #define MYNEWT_VAL_BLE_XTAL_SETTLE_TIME (0) #endif -/*** @apache-mynewt-nimble/nimble/drivers/nrf52 */ +/*** @apache-mynewt-nimble/nimble/drivers/nrf5x */ #ifndef MYNEWT_VAL_BLE_PHY_DBG_TIME_ADDRESS_END_PIN #define MYNEWT_VAL_BLE_PHY_DBG_TIME_ADDRESS_END_PIN (-1) #endif @@ -1266,14 +1320,6 @@ #define MYNEWT_VAL_BLE_PHY_DBG_TIME_WFR_PIN (-1) #endif -#ifndef MYNEWT_VAL_BLE_PHY_NRF52840_ERRATA_164 -#define MYNEWT_VAL_BLE_PHY_NRF52840_ERRATA_164 (0) -#endif - -#ifndef MYNEWT_VAL_BLE_PHY_NRF52840_ERRATA_191 -#define MYNEWT_VAL_BLE_PHY_NRF52840_ERRATA_191 (1) -#endif - #ifndef MYNEWT_VAL_BLE_PHY_SYSVIEW #define MYNEWT_VAL_BLE_PHY_SYSVIEW (0) #endif @@ -1499,14 +1545,14 @@ #define MYNEWT_VAL_BLE_L2CAP_COC_MPS (MYNEWT_VAL_MSYS_1_BLOCK_SIZE-8) #endif -#ifndef MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC -#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) -#endif - #ifndef MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT #define MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT (1) #endif +#ifndef MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC +#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS #define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1) #endif @@ -1822,4 +1868,38 @@ #define MYNEWT_VAL_TARGET_riot (1) #endif +/*** Included packages */ +#define MYNEWT_PKG_apache_mynewt_core__compiler_arm_none_eabi_m4 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_bsp_nordic_pca10056 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_cmsis_core 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart_uart_hal 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_hal 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_mcu_nordic 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_mcu_nordic_nrf52xxx 1 +#define MYNEWT_PKG_apache_mynewt_core__kernel_os 1 +#define MYNEWT_PKG_apache_mynewt_core__libc_baselibc 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_console_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_defs 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_flash_map 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_common 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_modlog 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_stats_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sys 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sysdown 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sysinit 1 +#define MYNEWT_PKG_apache_mynewt_core__util_mem 1 +#define MYNEWT_PKG_apache_mynewt_core__util_rwlock 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_controller 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_drivers_nrf5x 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gap 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gatt 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_transport 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_npl_mynewt 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_riot 1 + #endif From 7f83b89d4243cb3be6d454c588c32693f967869f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 3 Oct 2022 18:27:44 +0200 Subject: [PATCH 0566/1333] nimble/phy: Add syscfg for variable tifs This was removed accidentally when migrating to nrf5x phy. --- nimble/drivers/nrf5x/syscfg.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/nimble/drivers/nrf5x/syscfg.yml b/nimble/drivers/nrf5x/syscfg.yml index af4c62d3ec..3c8339c0ab 100644 --- a/nimble/drivers/nrf5x/syscfg.yml +++ b/nimble/drivers/nrf5x/syscfg.yml @@ -17,6 +17,15 @@ # syscfg.defs: + BLE_PHY_VARIABLE_TIFS: + description: > + Enables API to set custom T_ifs (inter-frame spacing) for each + transition. T_ifs is reset to default value after each transition. + When disabled, 150us is always used which enables some build-time + optimizations by compiler. + experimental: 1 + value: 0 + BLE_PHY_SYSVIEW: description: > Enable SystemView tracing module for radio driver. From 535d4a8124c104066bb0f69b12cc7910c89a2e6e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 30 Aug 2022 20:51:30 +0200 Subject: [PATCH 0567/1333] nimble/ll: Add support for non-LL items in scheduler This adds support for non-LL items in scheduler or so-called external items. Custom items shall use BLE_LL_SCHED_EXTERNAL type and set LL state to BLE_LL_STATE_EXTERNAL when executing. When in that state, LL will call appropriate callbacks as for any other built-in state which shall be implemented by application. If different types of custom items are used, they can be differentiated by sched_ext_type field which can have an arbitrary value set by application. Note that this feature is marked as experimental as API is subject to change. --- nimble/controller/include/controller/ble_ll.h | 3 + .../include/controller/ble_ll_ext.h | 58 +++++++++++++++++++ .../include/controller/ble_ll_sched.h | 14 +++++ nimble/controller/src/ble_ll.c | 25 ++++++++ nimble/controller/src/ble_ll_scan.c | 5 ++ nimble/controller/src/ble_ll_sched.c | 20 +++++-- nimble/controller/syscfg.yml | 6 ++ 7 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 nimble/controller/include/controller/ble_ll_ext.h diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 8535d44047..25a8f296a9 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -237,6 +237,9 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats; #if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) && MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) #define BLE_LL_STATE_SCAN_AUX (7) #endif +#if MYNEWT_VAL(BLE_LL_EXT) +#define BLE_LL_STATE_EXTERNAL (8) +#endif /* LL Features */ #define BLE_LL_FEAT_LE_ENCRYPTION (0x0000000001) diff --git a/nimble/controller/include/controller/ble_ll_ext.h b/nimble/controller/include/controller/ble_ll_ext.h new file mode 100644 index 0000000000..fc46ad4da8 --- /dev/null +++ b/nimble/controller/include/controller/ble_ll_ext.h @@ -0,0 +1,58 @@ +/* + * 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_BLE_LL_EXT_ +#define H_BLE_LL_EXT_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if MYNEWT_VAL(BLE_LL_EXT) + +/* Quickstart guide: + * - create scheduling item with sched_type set to BLE_LL_SCHED_EXTERNAL + * - use sched_ext_type to differentiate between different types of custom items + * - insert into scheduler using ble_ll_sched_insert() + * - set LL state to BLE_LL_STATE_EXTERNAL when item is being executed + * - set LL state back to BLE_LL_STATE_IDLE when item is done + */ + +struct ble_ll_sched_item; + +/* Called when LL is in "external" state and PHY starts to receive a PDU */ +int ble_ll_ext_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *rxhdr); +/* Called when LL is in "external" state and PHY finished to receive a PDU */ +int ble_ll_ext_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr); +/* Called when PDU received in "external" state reaches LL */ +void ble_ll_ext_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr); +/* Called when LL is in "external" state and was preempted */ +void ble_ll_ext_halt(void); +/* Called when LL is in "external" state and PHY failed to receive a PDU */ +void ble_ll_ext_wfr_timer_exp(void); +/* Called when an "external" scheduling item was removed from scheduler queue */ +void ble_ll_ext_sched_removed(struct ble_ll_sched_item *sch); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* H_BLE_LL_EXT_ */ diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index 01af613d30..12fe3dfeac 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -70,6 +70,9 @@ extern uint8_t g_ble_ll_sched_offset_ticks; #define BLE_LL_SCHED_TYPE_PERIODIC (6) #define BLE_LL_SCHED_TYPE_SYNC (7) #define BLE_LL_SCHED_TYPE_SCAN_AUX (8) +#if MYNEWT_VAL(BLE_LL_EXT) +#define BLE_LL_SCHED_TYPE_EXTERNAL (255) +#endif /* Return values for schedule callback. */ #define BLE_LL_SCHED_STATE_RUNNING (0) @@ -80,6 +83,10 @@ struct ble_ll_sched_item; typedef int (*sched_cb_func)(struct ble_ll_sched_item *sch); typedef void (*sched_remove_cb_func)(struct ble_ll_sched_item *sch); +typedef int (* ble_ll_sched_preempt_cb_t)(struct ble_ll_sched_item *sch, + struct ble_ll_sched_item *item); + + /* * Schedule item * sched_type: This is the type of the schedule item. @@ -91,6 +98,9 @@ typedef void (*sched_remove_cb_func)(struct ble_ll_sched_item *sch); struct ble_ll_sched_item { uint8_t sched_type; +#if MYNEWT_VAL(BLE_LL_EXT) + uint8_t sched_ext_type; +#endif uint8_t enqueued; uint8_t remainder; uint32_t start_time; @@ -103,6 +113,10 @@ struct ble_ll_sched_item /* Initialize the scheduler */ int ble_ll_sched_init(void); +int ble_ll_sched_insert(struct ble_ll_sched_item *sch, uint32_t max_delay, + ble_ll_sched_preempt_cb_t preempt_cb); +void ble_ll_sched_restart(void); + /* Remove item(s) from schedule */ int ble_ll_sched_rmv_elem(struct ble_ll_sched_item *sch); diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index ec66fc5374..011b0e5f6a 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -44,6 +44,9 @@ #include "controller/ble_ll_trace.h" #include "controller/ble_ll_sync.h" #include "controller/ble_fem.h" +#if MYNEWT_VAL(BLE_LL_EXT_SCHED) +#include "controller/ble_ll_ext.h" +#endif #include "ble_ll_conn_priv.h" #include "ble_ll_hci_priv.h" #include "ble_ll_priv.h" @@ -800,6 +803,11 @@ ble_ll_wfr_timer_exp(void *arg) case BLE_LL_STATE_DTM: ble_ll_dtm_wfr_timer_exp(); break; +#endif +#if MYNEWT_VAL(BLE_LL_EXT_SCHED) + case BLE_LL_STATE_EXTERNAL: + ble_ll_ext_wfr_timer_exp(); + break; #endif default: break; @@ -975,6 +983,11 @@ ble_ll_rx_pkt_in(void) case BLE_LL_STATE_DTM: ble_ll_dtm_rx_pkt_in(m, ble_hdr); break; +#endif +#if MYNEWT_VAL(BLE_LL_EXT_SCHED) + case BLE_LL_STATE_EXTERNAL: + ble_ll_ext_rx_pkt_in(m, ble_hdr); + break; #endif default: /* Any other state should never occur */ @@ -1121,6 +1134,11 @@ ble_ll_rx_start(uint8_t *rxbuf, uint8_t chan, struct ble_mbuf_hdr *rxhdr) case BLE_LL_STATE_DTM: rc = ble_ll_dtm_rx_isr_start(rxhdr, ble_phy_access_addr_get()); break; +#endif +#if MYNEWT_VAL(BLE_LL_EXT_SCHED) + case BLE_LL_STATE_EXTERNAL: + rc = ble_ll_ext_rx_isr_start(pdu_type, rxhdr); + break; #endif default: /* Should not be in this state! */ @@ -1165,6 +1183,13 @@ ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) ble_ll_trace_u32x3(BLE_LL_TRACE_ID_RX_END, pdu_type, len, rxhdr->rxinfo.flags); +#if MYNEWT_VAL(BLE_LL_EXT_SCHED) + if (BLE_MBUF_HDR_RX_STATE(rxhdr) == BLE_LL_STATE_EXTERNAL) { + rc = ble_ll_ext_rx_isr_end(rxbuf, rxhdr); + return rc; + } +#endif + #if MYNEWT_VAL(BLE_LL_DTM) if (BLE_MBUF_HDR_RX_STATE(rxhdr) == BLE_LL_STATE_DTM) { rc = ble_ll_dtm_rx_isr_end(rxbuf, rxhdr); diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index a5b3833bb9..a0afbdcc28 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1119,6 +1119,11 @@ ble_ll_scan_event_proc(struct ble_npl_event *ev) case BLE_LL_STATE_SCAN_AUX: start_scan = false; break; +#endif +#if MYNEWT_VAL(BLE_LL_EXT_SCHED) + case BLE_LL_STATE_EXTERNAL: + start_scan = false; + break; #endif case BLE_LL_STATE_SCANNING: /* Must disable PHY since we will move to a new channel */ diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index ccf3fc58dd..6cfedb2af9 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -31,6 +31,9 @@ #include "controller/ble_ll_trace.h" #include "controller/ble_ll_tmr.h" #include "controller/ble_ll_sync.h" +#if MYNEWT_VAL(BLE_LL_EXT) +#include "controller/ble_ll_ext.h" +#endif #include "ble_ll_priv.h" #include "ble_ll_conn_priv.h" @@ -66,9 +69,6 @@ static struct ble_ll_sched_css g_ble_ll_sched_css = { }; #endif -typedef int (* ble_ll_sched_preempt_cb_t)(struct ble_ll_sched_item *sch, - struct ble_ll_sched_item *item); - /* XXX: TODO: * 1) Add some accounting to the schedule code to see how late we are * (min/max?) @@ -169,6 +169,11 @@ ble_ll_sched_preempt(struct ble_ll_sched_item *sch, break; #endif #endif +#endif +#if MYNEWT_VAL(BLE_LL_EXT) + case BLE_LL_SCHED_TYPE_EXTERNAL: + ble_ll_ext_sched_removed(entry); + break; #endif default: BLE_LL_ASSERT(0); @@ -191,7 +196,7 @@ ble_ll_sched_q_head_changed(void) ble_ll_tmr_stop(&g_ble_ll_sched_timer); } -static inline void +void ble_ll_sched_restart(void) { struct ble_ll_sched_item *first; @@ -211,7 +216,7 @@ ble_ll_sched_restart(void) } } -static int +int ble_ll_sched_insert(struct ble_ll_sched_item *sch, uint32_t max_delay, ble_ll_sched_preempt_cb_t preempt_cb) { @@ -1006,6 +1011,11 @@ ble_ll_sched_execute_item(struct ble_ll_sched_item *sch) STATS_INC(ble_ll_stats, sched_state_conn_errs); ble_ll_conn_event_halt(); break; +#endif +#if MYNEWT_VAL(BLE_LL_EXT) + case BLE_LL_STATE_EXTERNAL: + ble_ll_ext_halt(); + break; #endif default: BLE_LL_ASSERT(0); diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 13295a309c..686821ae1e 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -484,6 +484,12 @@ syscfg.defs: while rfmgmt is active. value: -1 + BLE_LL_EXT: + description: > + Enables API to support external (i.e. non-native to LL) state for + NimBLE LL and scheduler. See ble_ll_ext.h. + experimental: 1 + value: 0 # Below settings allow to change scheduler timings. These should be left at # default values unless you know what you are doing! BLE_LL_SCHED_AUX_MAFS_DELAY: From e716ae5ef7b458472ace5823dc1eee4891570d44 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 3 Oct 2022 19:30:09 +0200 Subject: [PATCH 0568/1333] nimble/phy/nrf5x: Fix tx-tx transition We need to store current transition before calling txend callback. This is important in case of tx-tx transition since txend callback will call ble_phy_tx which overwrites current transition. --- nimble/drivers/nrf5x/src/ble_phy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 3b9fa1e9f5..799760df7a 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -1047,12 +1047,12 @@ ble_phy_tx_end_isr(void) } #endif + transition = g_ble_phy_data.phy_transition; + if (g_ble_phy_data.txend_cb) { g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg); } - transition = g_ble_phy_data.phy_transition; - if (transition == BLE_PHY_TRANSITION_TX_RX) { #if (BLE_LL_BT5_PHY_SUPPORTED == 1) ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); From 7b5bbb6ec0a513648433f6d38258d90729c5ef0f Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 4 Oct 2022 10:42:24 +0200 Subject: [PATCH 0569/1333] nimble/ll: Fix not setting proper TX power in periodic advertising All PHY power settings should go via ble_ll_tx_power_set() to make sure FEM and/or host compensation is taken int account. --- nimble/controller/src/ble_ll_adv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 8d6b6e85cc..6ba4617759 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -2176,7 +2176,7 @@ static void ble_ll_adv_sync_tx_done(struct ble_ll_adv_sm *advsm) { /* reset power to default after advertising */ - ble_phy_tx_power_set(g_ble_ll_tx_power); + ble_ll_tx_power_set(g_ble_ll_tx_power); /* for sync we trace a no pri nor sec set */ ble_ll_trace_u32x2(BLE_LL_TRACE_ID_ADV_TXDONE, advsm->adv_instance, 0); @@ -2232,7 +2232,7 @@ ble_ll_adv_sync_tx_start_cb(struct ble_ll_sched_item *sch) ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING); /* Set the power */ - ble_phy_tx_power_set(advsm->tx_power); + ble_ll_tx_power_set(advsm->tx_power); /* Set channel */ sync = SYNC_CURRENT(advsm); From 266e81d2d32fa1e58bd7d7b9fc51156be50e0301 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 4 Oct 2022 14:36:38 +0200 Subject: [PATCH 0570/1333] nimble/ll: Add option to define maximum allowed TX power This allows to limit (clip) maximum allowed TX power to meet requirements for selected LE PHY power class. --- nimble/controller/src/ble_ll.c | 6 ++++-- nimble/controller/src/ble_ll_adv.c | 3 ++- nimble/controller/src/ble_ll_hci_vs.c | 8 ++++++-- nimble/controller/syscfg.yml | 8 ++++++++ 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 011b0e5f6a..d8d2e6bc27 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1376,7 +1376,8 @@ ble_ll_task(void *arg) ble_phy_init(); /* Set output power to default */ - g_ble_ll_tx_power = ble_ll_tx_power_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); + g_ble_ll_tx_power = ble_ll_tx_power_round(min(MYNEWT_VAL(BLE_LL_TX_PWR_DBM), + MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM))); ble_ll_tx_power_set(g_ble_ll_tx_power); /* Tell the host that we are ready to receive packets */ @@ -1623,7 +1624,8 @@ ble_ll_reset(void) g_ble_ll_rx_power_compensation = 0; /* Set output power to default */ - g_ble_ll_tx_power = ble_ll_tx_power_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM)); + g_ble_ll_tx_power = ble_ll_tx_power_round(min(MYNEWT_VAL(BLE_LL_TX_PWR_DBM), + MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM))); ble_ll_tx_power_set(g_ble_ll_tx_power); /* FLush all packets from Link layer queues */ diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 6ba4617759..49228246b5 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -3528,7 +3528,8 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, /* no preference */ advsm->tx_power = ble_ll_tx_power_round(g_ble_ll_tx_power - g_ble_ll_tx_power_compensation); } else { - advsm->tx_power = ble_ll_tx_power_round(cmd->tx_power - g_ble_ll_tx_power_compensation); + advsm->tx_power = ble_ll_tx_power_round(min(cmd->tx_power, MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM)) - + g_ble_ll_tx_power_compensation); } /* we can always store as those are validated and used only when needed */ diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index e9c4e2d17b..9f7fb18517 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -124,9 +124,13 @@ ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, if (cmd->tx_power == 127) { /* restore reset default */ - g_ble_ll_tx_power = ble_ll_tx_power_round(MYNEWT_VAL(BLE_LL_TX_PWR_DBM) - g_ble_ll_tx_power_compensation); + g_ble_ll_tx_power = ble_ll_tx_power_round(min(MYNEWT_VAL(BLE_LL_TX_PWR_DBM), + MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM)) - + g_ble_ll_tx_power_compensation); } else { - g_ble_ll_tx_power = ble_ll_tx_power_round(cmd->tx_power - g_ble_ll_tx_power_compensation); + g_ble_ll_tx_power = ble_ll_tx_power_round(min(cmd->tx_power, + MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM)) - + g_ble_ll_tx_power_compensation); } ble_ll_tx_power_set(g_ble_ll_tx_power); diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 686821ae1e..38f6379537 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -69,6 +69,14 @@ syscfg.defs: may be rounded up or down depending on used radio. value: '0' + BLE_LL_TX_PWR_MAX_DBM: + description: > + Maximum allowed transmit power level (in dBm). This limits maximum + power to specified value (including FEM and/or host compensation). + Useful for ensuring selected power class of device. Defaults to + maximum allowed by specification (Power Class 1). + value: '20' + BLE_LL_NUM_COMP_PKT_ITVL_MS: description: > Determines the interval at which the controller will send the From 0414740226c0eaa2f812ce920dff609666a88c53 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 4 Oct 2022 10:16:46 +0200 Subject: [PATCH 0571/1333] nimble/phy/nrf5x: Fix tx-tx transition timing Need to adjust start time by ramp up time. --- nimble/drivers/nrf5x/src/ble_phy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 799760df7a..df610c9303 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -1097,7 +1097,8 @@ ble_phy_tx_end_isr(void) /* Adjust for delay between EVENT_READY and actual TX start time */ tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; - nrf_timer_cc_set(NRF_TIMER0, 0, tx_time); + radio_time = tx_time - BLE_PHY_T_TXENFAST; + nrf_timer_cc_set(NRF_TIMER0, 0, radio_time); NRF_TIMER0->EVENTS_COMPARE[0] = 0; phy_ppi_timer0_compare0_to_radio_txen_enable(); From 7b97e1d5c64cf50912db3b6716f5073b874ebb0e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 4 Oct 2022 09:47:41 +0200 Subject: [PATCH 0572/1333] nimble/phy/nrf5x: Fix variable tifs We need to first read current tifs, the reset it to default value, otherwise handlers will always use default tifs value. --- nimble/drivers/nrf5x/src/ble_phy.c | 46 +++++++++++++++++------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index df610c9303..9e6316d2a8 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -590,23 +590,11 @@ nrf_wait_disabled(void) } #if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) -static uint16_t -ble_phy_tifs_get(void) -{ - return g_ble_phy_data.tifs; -} - void ble_phy_tifs_set(uint16_t tifs) { g_ble_phy_data.tifs = tifs; } -#else -static uint16_t -ble_phy_tifs_get(void) -{ - return BLE_LL_IFS; -} #endif /** @@ -831,12 +819,19 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) { uint32_t end_time; uint8_t phy; + uint16_t tifs; phy = g_ble_phy_data.phy_cur_phy_mode; +#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) + tifs = g_ble_phy_data.tifs; +#else + tifs = BLE_LL_IFS; +#endif + if (txrx == BLE_PHY_WFR_ENABLE_TXRX) { /* RX shall start exactly T_IFS after TX end captured in CC[2] */ - end_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); + end_time = NRF_TIMER0->CC[2] + tifs; /* Adjust for delay between EVENT_END and actual TX end time */ end_time += g_ble_phy_t_txenddelay[tx_phy_mode]; /* Wait a bit longer due to allowed active clock accuracy */ @@ -1023,6 +1018,7 @@ ble_phy_tx_end_isr(void) uint32_t fem_time; #endif uint32_t radio_time; + uint16_t tifs; /* Store PHY on which we've just transmitted smth */ tx_phy_mode = g_ble_phy_data.phy_cur_phy_mode; @@ -1047,6 +1043,12 @@ ble_phy_tx_end_isr(void) } #endif +#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) + tifs = g_ble_phy_data.tifs; + g_ble_phy_data.tifs = BLE_LL_IFS; +#else + tifs = BLE_LL_IFS; +#endif transition = g_ble_phy_data.phy_transition; if (g_ble_phy_data.txend_cb) { @@ -1064,7 +1066,7 @@ ble_phy_tx_end_isr(void) ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_TXRX, tx_phy_mode, 0); /* Schedule RX exactly T_IFS after TX end captured in CC[2] */ - rx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); + rx_time = NRF_TIMER0->CC[2] + tifs; /* Adjust for delay between EVENT_END and actual TX end time */ rx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; /* Start listening a bit earlier due to allowed active clock accuracy */ @@ -1091,7 +1093,7 @@ ble_phy_tx_end_isr(void) */ } else if (transition == BLE_PHY_TRANSITION_TX_TX) { /* Schedule TX exactly T_IFS after TX end captured in CC[2] */ - tx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); + tx_time = NRF_TIMER0->CC[2] + tifs; /* Adjust for delay between EVENT_END and actual TX end time */ tx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; /* Adjust for delay between EVENT_READY and actual TX start time */ @@ -1159,6 +1161,7 @@ ble_phy_rx_end_isr(void) uint32_t fem_time; #endif uint32_t radio_time; + uint16_t tifs; struct ble_mbuf_hdr *ble_hdr; bool is_late; @@ -1223,8 +1226,15 @@ ble_phy_rx_end_isr(void) * enough. */ +#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) + tifs = g_ble_phy_data.tifs; + g_ble_phy_data.tifs = BLE_LL_IFS; +#else + tifs = BLE_LL_IFS; +#endif + /* Schedule TX exactly T_IFS after RX end captured in CC[2] */ - tx_time = NRF_TIMER0->CC[2] + ble_phy_tifs_get(); + tx_time = NRF_TIMER0->CC[2] + tifs; /* Adjust for delay between actual RX end time and EVENT_END */ tx_time -= g_ble_phy_t_rxenddelay[ble_hdr->rxinfo.phy_mode]; @@ -1449,10 +1459,6 @@ ble_phy_isr(void) NRF_RADIO->EVENTS_DISABLED = 0; nrf_radio_int_disable(NRF_RADIO, RADIO_INTENCLR_DISABLED_Msk); -#if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) - g_ble_phy_data.tifs = BLE_LL_IFS; -#endif - switch (g_ble_phy_data.phy_state) { case BLE_PHY_STATE_RX: #if MYNEWT_VAL(BLE_FEM_LNA) From 25f84900bb9adce4ecbae533b7a07a0e24f0566b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 5 Oct 2022 09:12:40 +0200 Subject: [PATCH 0573/1333] nimble/transport: Enable extra buffer on app when using IPC If IPC transport is used on app core and we do not have host, we should enable an extra buffer for command to make sure controller-to-host flow control can be handled. This does not need to be handled on controller side since it needs to have that feature enabled anyway. --- nimble/transport/src/transport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/transport/src/transport.c b/nimble/transport/src/transport.c index 9de703e713..4e811495f6 100644 --- a/nimble/transport/src/transport.c +++ b/nimble/transport/src/transport.c @@ -34,7 +34,8 @@ #define OMP_FLAG_FROM_MASK (0x03) #if MYNEWT_VAL(BLE_HS_FLOW_CTRL) || \ - MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) + MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) || \ + (!MYNEWT_VAL(BLE_HOST) && BLE_TRANSPORT_IPC_ON_HS) #define POOL_CMD_COUNT (2) #else #define POOL_CMD_COUNT (1) From 18203ccafc31b9d7580c2eddf48029dabe489c0e Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Tue, 27 Sep 2022 18:15:39 +0530 Subject: [PATCH 0574/1333] nimble/host: Add HCI Commands/ events for connection subrating --- nimble/host/include/host/ble_gap.h | 68 +++++++++++++++++++ nimble/host/src/ble_gap.c | 60 ++++++++++++++++ nimble/host/src/ble_gap_priv.h | 4 +- nimble/host/src/ble_hs_hci_evt.c | 26 ++++++- nimble/host/src/ble_hs_startup.c | 10 +++ nimble/syscfg.yml | 5 ++ .../examples/linux/include/syscfg/syscfg.h | 4 ++ .../linux_blemesh/include/syscfg/syscfg.h | 4 ++ .../examples/nuttx/include/syscfg/syscfg.h | 4 ++ porting/nimble/include/syscfg/syscfg.h | 4 ++ porting/npl/riot/include/syscfg/syscfg.h | 4 ++ 11 files changed, 190 insertions(+), 3 deletions(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index 5ff34f5867..37ac797463 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -138,6 +138,7 @@ struct hci_conn_update; #define BLE_GAP_EVENT_PATHLOSS_THRESHOLD 25 #define BLE_GAP_EVENT_TRANSMIT_POWER 26 #define BLE_GAP_EVENT_PARING_COMPLETE 27 +#define BLE_GAP_EVENT_SUBRATE_CHANGE 28 /*** Reason codes for the subscribe GAP event. */ @@ -1042,6 +1043,34 @@ struct ble_gap_event { /** The handle of the relevant connection. */ uint16_t conn_handle; } pairing_complete; + +#if MYNEWT_VAL(BLE_CONN_SUBRATING) + /** + * Represents a subrate change event that indicates connection subrate update procedure + * has completed and some parameters have changed Valid for + * the following event types: + * o BLE_GAP_EVENT_SUBRATE_CHANGE + */ + struct { + /** BLE_ERR_SUCCESS on success or error code on failure */ + uint8_t status; + + /** Connection Handle */ + uint16_t conn_handle; + + /** Subrate Factor */ + uint16_t subrate_factor; + + /** Peripheral Latency */ + uint16_t periph_latency; + + /** Continuation Number */ + uint16_t cont_num; + + /** Supervision Timeout */ + uint16_t supervision_tmo; + } subrate_change; +#endif }; }; @@ -2167,6 +2196,45 @@ int ble_gap_set_prefered_default_le_phy(uint8_t tx_phys_mask, int ble_gap_set_prefered_le_phy(uint16_t conn_handle, uint8_t tx_phys_mask, uint8_t rx_phys_mask, uint16_t phy_opts); +#if MYNEWT_VAL(BLE_CONN_SUBRATING) +/** + * Set default subrate + * + * @param subrate_min Min subrate factor allowed in request by a peripheral + * @param subrate_max Max subrate factor allowed in request by a peripheral + * @param max_latency Max peripheral latency allowed in units of + * subrated conn interval. + * + * @param cont_num Min number of underlying conn event to remain active + * after a packet containing PDU with non-zero length field + * is sent or received in request by a peripheral. + * + * @param supervision_timeout Max supervision timeout allowed in request by a peripheral + */ +int ble_gap_set_default_subrate(uint16_t subrate_min, uint16_t subrate_max, uint16_t max_latency, + uint16_t cont_num, uint16_t supervision_timeout); + +/** + * Subrate Request + * + * @param conn_handle Connection Handle of the ACL. + * @param subrate_min Min subrate factor to be applied + * @param subrate_max Max subrate factor to be applied + * @param max_latency Max peripheral latency allowed in units of + * subrated conn interval. + * + * @param cont_num Min number of underlying conn event to remain active + * after a packet containing PDU with non-zero length field + * is sent or received in request by a peripheral. + * + * @param supervision_timeout Max supervision timeout allowed for this connection + */ + +int +ble_gap_subrate_req(uint16_t conn_handle, uint16_t subrate_min, uint16_t subrate_max, + uint16_t max_latency, uint16_t cont_num, + uint16_t supervision_timeout); +#endif /** * Event listener structure * diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index d8a944a842..952b59b0a9 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -1777,6 +1777,26 @@ ble_gap_rx_periodic_adv_sync_transfer(const struct ble_hci_ev_le_subev_periodic_ } #endif +#if MYNEWT_VAL(BLE_CONN_SUBRATING) +void +ble_gap_rx_subrate_change(const struct ble_hci_ev_le_subev_subrate_change *ev) +{ + struct ble_gap_event event; + + memset(&event, 0x0, sizeof event); + + event.type = BLE_GAP_EVENT_SUBRATE_CHANGE; + event.subrate_change.status = ev->status; + event.subrate_change.conn_handle = le16toh(ev->conn_handle); + event.subrate_change.subrate_factor = le16toh(ev->subrate_factor); + event.subrate_change.periph_latency = le16toh(ev->periph_latency); + event.subrate_change.cont_num = le16toh(ev->cont_num); + event.subrate_change.supervision_tmo = le16toh(ev->supervision_tmo); + + ble_gap_event_listener_call(&event); +} +#endif + #if NIMBLE_BLE_CONNECT static int ble_gap_rd_rem_sup_feat_tx(uint16_t handle) @@ -4663,6 +4683,46 @@ ble_gap_conn_create_tx(uint8_t own_addr_type, const ble_addr_t *peer_addr, } #endif +#if MYNEWT_VAL(BLE_CONN_SUBRATING) +int +ble_gap_set_default_subrate(uint16_t subrate_min, uint16_t subrate_max, uint16_t max_latency, + uint16_t cont_num, uint16_t supervision_tmo) +{ + struct ble_hci_le_set_default_subrate_cp cmd; + uint16_t opcode; + + cmd.subrate_min = htole16(subrate_min); + cmd.subrate_max = htole16(subrate_max); + cmd.max_latency = htole16(max_latency); + cmd.cont_num = htole16(cont_num); + cmd.supervision_tmo = htole16(supervision_tmo); + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_DEFAULT_SUBRATE); + + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); +} + +int +ble_gap_subrate_req(uint16_t conn_handle, uint16_t subrate_min, uint16_t subrate_max, + uint16_t max_latency, uint16_t cont_num, + uint16_t supervision_tmo) +{ + struct ble_hci_le_subrate_req_cp cmd; + uint16_t opcode; + + cmd.conn_handle = htole16(conn_handle); + cmd.subrate_min = htole16(subrate_min); + cmd.subrate_max = htole16(subrate_max); + cmd.max_latency = htole16(max_latency); + cmd.cont_num = htole16(cont_num); + cmd.supervision_tmo = htole16(supervision_tmo); + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SUBRATE_REQ); + + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); +} +#endif + #if MYNEWT_VAL(BLE_EXT_ADV) #if MYNEWT_VAL(BLE_ROLE_CENTRAL) static int diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h index d6051b7305..0e4947f154 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/nimble/host/src/ble_gap_priv.h @@ -92,7 +92,9 @@ void ble_gap_rx_scan_req_rcvd(const struct ble_hci_ev_le_subev_scan_req_rcvd *ev #endif void ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc); void ble_gap_rx_rd_rem_sup_feat_complete(const struct ble_hci_ev_le_subev_rd_rem_used_feat *ev); - +#if MYNEWT_VAL(BLE_CONN_SUBRATING) +void ble_gap_rx_subrate_change(const struct ble_hci_ev_le_subev_subrate_change *ev); +#endif #if MYNEWT_VAL(BLE_POWER_CONTROL) void ble_gap_rx_transmit_power_report(const struct ble_hci_ev_le_subev_transmit_power_report *ev); void ble_gap_rx_le_pathloss_threshold(const struct ble_hci_ev_le_subev_path_loss_threshold *ev); diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index be64a3d3af..f7113f6318 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -64,10 +64,12 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_transfer; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_pathloss_threshold; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_transmit_power_report; #endif +#if MYNEWT_VAL(BLE_CONN_SUBRATING) +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_subrate_change; +#endif /* Statistics */ -struct host_hci_stats -{ +struct host_hci_stats { uint32_t events_rxd; uint32_t good_acks_rxd; uint32_t bad_acks_rxd; @@ -124,6 +126,9 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = { [BLE_HCI_LE_SUBEV_PATH_LOSS_THRESHOLD] = ble_hs_hci_evt_le_pathloss_threshold, [BLE_HCI_LE_SUBEV_TRANSMIT_POWER_REPORT] = ble_hs_hci_evt_le_transmit_power_report, #endif +#if MYNEWT_VAL(BLE_CONN_SUBRATING) + [BLE_HCI_LE_SUBEV_SUBRATE_CHANGE] = ble_hs_hci_evt_le_subrate_change, +#endif }; #define BLE_HS_HCI_EVT_LE_DISPATCH_SZ \ @@ -750,6 +755,23 @@ ble_hs_hci_evt_le_scan_req_rcvd(uint8_t subevent, const void *data, return 0; } +#if MYNEWT_VAL(BLE_CONN_SUBRATING) +static int +ble_hs_hci_evt_le_subrate_change(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_subrate_change *ev = data; + + if (len != sizeof(*ev)) { + return BLE_HS_ECONTROLLER; + } + + ble_gap_rx_subrate_change(ev); + + return 0; +} +#endif + #if NIMBLE_BLE_CONNECT static int ble_hs_hci_evt_le_conn_upd_complete(uint8_t subevent, const void *data, diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c index 96e4e655cc..03f3d2e4a4 100644 --- a/nimble/host/src/ble_hs_startup.c +++ b/nimble/host/src/ble_hs_startup.c @@ -240,6 +240,16 @@ ble_hs_startup_le_set_evmask_tx(void) } #endif +#if MYNEWT_VAL(BLE_CONN_SUBRATING) + if (version >= BLE_HCI_VER_BCS_5_3) { + /** + * Enable the following LE events: + * 0x0000000400000000 LE Subrate change event + */ + mask |= 0x0000000400000000; + } +#endif + cmd.event_mask = htole64(mask); rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index f8c92ea094..a50bc89e6d 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -113,6 +113,11 @@ syscfg.defs: This enabled LE Power Control feature value: 0 + BLE_CONN_SUBRATING: + description: > + This enables LE Connection Subrating feature + value: 0 + # Allow periodic sync transfer only if 5.1 or higher syscfg.restrictions: - "'BLE_PERIODIC_ADV_SYNC_TRANSFER == 0' || 'BLE_VERSION >= 51'" diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index c98da2aba3..a74ff46b53 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -478,6 +478,10 @@ #define MYNEWT_VAL_BLE_POWER_CONTROL (0) #endif +#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING +#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) +#endif + #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 851337c7d1..a5ee902984 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -479,6 +479,10 @@ #define MYNEWT_VAL_BLE_POWER_CONTROL (0) #endif +#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING +#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) +#endif + #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index e0f0734926..741695d869 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -478,6 +478,10 @@ #define MYNEWT_VAL_BLE_POWER_CONTROL (0) #endif +#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING +#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) +#endif + #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index 0184055e73..dcd5acc0d4 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -477,6 +477,10 @@ #define MYNEWT_VAL_BLE_POWER_CONTROL (0) #endif +#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING +#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) +#endif + #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 1945d28a57..b732e00f35 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -842,6 +842,10 @@ #define MYNEWT_VAL_BLE_POWER_CONTROL (0) #endif +#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING +#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) +#endif + #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif From 801484e4610b6c49f366f527dde60b1f650f50f3 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 6 Oct 2022 14:08:05 +0200 Subject: [PATCH 0575/1333] nimble/fem: Reset SKY66112 to defaults on HCI reset Make sure we set all configuration to defaults when HCI reset is issued. --- nimble/drivers/fem/sky66112/src/sky66112.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/nimble/drivers/fem/sky66112/src/sky66112.c b/nimble/drivers/fem/sky66112/src/sky66112.c index 873afa1060..c9760171ef 100644 --- a/nimble/drivers/fem/sky66112/src/sky66112.c +++ b/nimble/drivers/fem/sky66112/src/sky66112.c @@ -43,7 +43,11 @@ sky66112_bypass(uint8_t enabled) void ble_fem_pa_init(void) { - /* Nothing to do here */ + sky66112_tx_hp_mode(MYNEWT_VAL(SKY66112_TX_HP_MODE)); + sky66112_tx_bypass(0); +#if MYNEWT_VAL(BLE_FEM_ANTENNA) + ble_fem_antenna(MYNEWT_VAL(SKY66112_ANTENNA_PORT)); +#endif } void @@ -65,7 +69,10 @@ ble_fem_pa_disable(void) void ble_fem_lna_init(void) { - /* Nothing to do here */ + sky66112_rx_bypass(0); +#if MYNEWT_VAL(BLE_FEM_ANTENNA) + ble_fem_antenna(MYNEWT_VAL(SKY66112_ANTENNA_PORT)); +#endif } void From 374e0bc85c1c59c5e4ec29ffedfd1f8288c792d8 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Thu, 6 Oct 2022 10:58:57 +0200 Subject: [PATCH 0576/1333] Fix missing includes and missing return (compiler gives error) --- nimble/transport/include/nimble/transport/transport_ipc.h | 3 +++ nimble/transport/nrf5340/src/nrf5340_ble_hci.c | 1 + nimble/transport/src/transport.c | 1 + 3 files changed, 5 insertions(+) diff --git a/nimble/transport/include/nimble/transport/transport_ipc.h b/nimble/transport/include/nimble/transport/transport_ipc.h index 1817514934..8059c3aeb8 100644 --- a/nimble/transport/include/nimble/transport/transport_ipc.h +++ b/nimble/transport/include/nimble/transport/transport_ipc.h @@ -20,10 +20,13 @@ #ifndef H_NIMBLE_TRANSPORT_IPC_ #define H_NIMBLE_TRANSPORT_IPC_ +#include + #ifdef __cplusplus extern "C" { #endif + /* NOTE: These APIs shall only be used by IPC transports */ #define BLE_TRANSPORT_IPC \ diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index e5ea5a51b3..9ee3617893 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include diff --git a/nimble/transport/src/transport.c b/nimble/transport/src/transport.c index 4e811495f6..a1ee34099f 100644 --- a/nimble/transport/src/transport.c +++ b/nimble/transport/src/transport.c @@ -287,5 +287,6 @@ ble_transport_ipc_buf_evt_type_get(void *buf) } else { assert(0); } + return 0; } #endif From bcd55dde825e61e0957876de82a2ec131fea55a2 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 7 Oct 2022 11:02:52 +0200 Subject: [PATCH 0577/1333] nimble/ll: Fix not re-initializing CSS on HCI reset Reset CSS configuration to defaults on HCI reset. Otherwise we could end up with enabled CSS after HCI reset. --- nimble/controller/src/ble_ll_sched.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 6cfedb2af9..3b2b885cde 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -1198,6 +1198,14 @@ ble_ll_sched_init(void) g_ble_ll_sched_q_head_changed = 0; +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + memset(&g_ble_ll_sched_css, 0, sizeof (g_ble_ll_sched_css)); +#if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED) + g_ble_ll_sched_css.slot_us = MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_SLOT_US); + g_ble_ll_sched_css.period_slots = MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_PERIOD_SLOTS); +#endif +#endif + return 0; } From b353ddc1a44e1d4817e369d4a8b59a98aa3b0e7e Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 10 Oct 2022 16:18:29 +0200 Subject: [PATCH 0578/1333] nimble/ll: Fix enabling extended scan with no configuration Core Specification 5.3, Vol 4, Part E, 7.8.65: "If Enable is set to 0x01 and the Host has not issued the HCI_LE_Set_Extended_Scan_Parameters command, the Controller shall either use vendor-specified parameters or return the error code Command Disallowed (0x0C)" To keep things simple we just reject in such case. This was affecting HCI/DDI/BV-06-C qualification test case. --- nimble/controller/src/ble_ll_scan.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index a0afbdcc28..587ae6b2d6 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -2314,6 +2314,27 @@ ble_ll_scan_set_enable(uint8_t enable, uint8_t filter_dups, uint16_t period, scansm = &g_ble_ll_scan_sm; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + if (ext) { + /* + * If Enable is set to 0x01 and the Host has not issued the + * HCI_LE_Set_Extended_Scan_Parameters command, the Controller shall + * either use vendor-specified parameters or return the error code + * Command Disallowed (0x0C) + * + * To keep things simple for devices without public address we + * reject in such case. + */ + for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) { + if (g_ble_ll_scan_params.scan_phys[i].configured) { + break; + } + } + + if (i == BLE_LL_SCAN_PHY_NUMBER) { + return BLE_ERR_CMD_DISALLOWED; + } + } + /* we can do that here since value will never change until reset */ scansm->ext_scanning = ext; From c6e6614cf114526113f02321cf38c156417d675d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sun, 9 Oct 2022 21:44:30 +0200 Subject: [PATCH 0579/1333] nimble/ll: Add init and reset for external code This adds init and reset calls for external code so it can be initialized and reset properly in sync with LL. --- nimble/controller/include/controller/ble_ll_ext.h | 4 ++++ nimble/controller/src/ble_ll.c | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/nimble/controller/include/controller/ble_ll_ext.h b/nimble/controller/include/controller/ble_ll_ext.h index fc46ad4da8..5b3bb3767f 100644 --- a/nimble/controller/include/controller/ble_ll_ext.h +++ b/nimble/controller/include/controller/ble_ll_ext.h @@ -36,6 +36,10 @@ extern "C" { struct ble_ll_sched_item; +/* Called when LL package is initialized (before ll_task is started) */ +void ble_ll_ext_init(void); +/* Called when LL is reset (i.e. HCI_Reset) */ +void ble_ll_ext_reset(void); /* Called when LL is in "external" state and PHY starts to receive a PDU */ int ble_ll_ext_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *rxhdr); /* Called when LL is in "external" state and PHY finished to receive a PDU */ diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index d8d2e6bc27..b3719c1283 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -56,6 +56,10 @@ #include "ble_ll_dtm_priv.h" #endif +#if MYNEWT_VAL(BLE_LL_EXT) +#include +#endif + /* XXX: * * 1) use the sanity task! @@ -1605,6 +1609,10 @@ ble_ll_reset(void) ble_ll_rfmgmt_reset(); OS_EXIT_CRITICAL(sr); +#if MYNEWT_VAL(BLE_LL_EXT) + ble_ll_ext_reset(); +#endif + #if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) /* Stop any advertising */ ble_ll_adv_reset(); @@ -1981,6 +1989,10 @@ ble_ll_init(void) ble_ll_hci_vs_init(); #endif +#if MYNEWT_VAL(BLE_LL_EXT) + ble_ll_ext_init(); +#endif + #if MYNEWT /* Initialize the LL task */ os_task_init(&g_ble_ll_task, "ble_ll", ble_ll_task, NULL, From f6567c02bc07751782771278cc5d9eb5b6b4f666 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 10 Oct 2022 11:21:18 +0200 Subject: [PATCH 0580/1333] nimble/ll: Fix ifdefs for BLE_LL_EXT --- nimble/controller/src/ble_ll.c | 10 +++++----- nimble/controller/src/ble_ll_scan.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index b3719c1283..9384a46c7b 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -44,7 +44,7 @@ #include "controller/ble_ll_trace.h" #include "controller/ble_ll_sync.h" #include "controller/ble_fem.h" -#if MYNEWT_VAL(BLE_LL_EXT_SCHED) +#if MYNEWT_VAL(BLE_LL_EXT) #include "controller/ble_ll_ext.h" #endif #include "ble_ll_conn_priv.h" @@ -808,7 +808,7 @@ ble_ll_wfr_timer_exp(void *arg) ble_ll_dtm_wfr_timer_exp(); break; #endif -#if MYNEWT_VAL(BLE_LL_EXT_SCHED) +#if MYNEWT_VAL(BLE_LL_EXT) case BLE_LL_STATE_EXTERNAL: ble_ll_ext_wfr_timer_exp(); break; @@ -988,7 +988,7 @@ ble_ll_rx_pkt_in(void) ble_ll_dtm_rx_pkt_in(m, ble_hdr); break; #endif -#if MYNEWT_VAL(BLE_LL_EXT_SCHED) +#if MYNEWT_VAL(BLE_LL_EXT) case BLE_LL_STATE_EXTERNAL: ble_ll_ext_rx_pkt_in(m, ble_hdr); break; @@ -1139,7 +1139,7 @@ ble_ll_rx_start(uint8_t *rxbuf, uint8_t chan, struct ble_mbuf_hdr *rxhdr) rc = ble_ll_dtm_rx_isr_start(rxhdr, ble_phy_access_addr_get()); break; #endif -#if MYNEWT_VAL(BLE_LL_EXT_SCHED) +#if MYNEWT_VAL(BLE_LL_EXT) case BLE_LL_STATE_EXTERNAL: rc = ble_ll_ext_rx_isr_start(pdu_type, rxhdr); break; @@ -1187,7 +1187,7 @@ ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) ble_ll_trace_u32x3(BLE_LL_TRACE_ID_RX_END, pdu_type, len, rxhdr->rxinfo.flags); -#if MYNEWT_VAL(BLE_LL_EXT_SCHED) +#if MYNEWT_VAL(BLE_LL_EXT) if (BLE_MBUF_HDR_RX_STATE(rxhdr) == BLE_LL_STATE_EXTERNAL) { rc = ble_ll_ext_rx_isr_end(rxbuf, rxhdr); return rc; diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 587ae6b2d6..7c16dd35b3 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1120,7 +1120,7 @@ ble_ll_scan_event_proc(struct ble_npl_event *ev) start_scan = false; break; #endif -#if MYNEWT_VAL(BLE_LL_EXT_SCHED) +#if MYNEWT_VAL(BLE_LL_EXT) case BLE_LL_STATE_EXTERNAL: start_scan = false; break; From e7006a8e780fa8aed8ba5a2cfe3bd824ea87e8fd Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 11 Oct 2022 14:22:52 +0200 Subject: [PATCH 0581/1333] nimble/ll: Add API to read random data from controller This may be useful to get some random if MCU does not support trng, e.g. as on nRF5340 app core. --- apps/bttester/src/gap.c | 2 +- nimble/host/include/host/ble_hs_hci.h | 15 +++++++++++++++ nimble/host/mesh/src/glue.c | 2 +- nimble/host/src/ble_hs_hci_priv.h | 1 - nimble/host/src/ble_hs_hci_util.c | 2 +- nimble/host/src/ble_hs_id.c | 2 +- nimble/host/src/ble_sm.c | 10 +++++----- nimble/host/src/ble_sm_alg.c | 2 +- nimble/host/src/ble_sm_sc.c | 2 +- 9 files changed, 26 insertions(+), 12 deletions(-) diff --git a/apps/bttester/src/gap.c b/apps/bttester/src/gap.c index 24ef4ab352..aee9591cca 100644 --- a/apps/bttester/src/gap.c +++ b/apps/bttester/src/gap.c @@ -837,7 +837,7 @@ static void auth_passkey_display(uint16_t conn_handle, unsigned int passkey) return; } - rc = ble_hs_hci_util_rand(&pk.passkey, sizeof(pk.passkey)); + rc = ble_hs_hci_rand(&pk.passkey, sizeof(pk.passkey)); assert(rc == 0); /* Max value is 999999 */ pk.passkey %= 1000000; diff --git a/nimble/host/include/host/ble_hs_hci.h b/nimble/host/include/host/ble_hs_hci.h index e10b8e62a5..739eea9265 100644 --- a/nimble/host/include/host/ble_hs_hci.h +++ b/nimble/host/include/host/ble_hs_hci.h @@ -87,6 +87,21 @@ int ble_hs_hci_read_chan_map(uint16_t conn_handle, uint8_t *out_chan_map); */ int ble_hs_hci_set_chan_class(const uint8_t *chan_map); +/** + * Reads random data into buffer from controller. + * This allows to use BLE controller as a source of true random data. + * + * @param dst Destination buffer. + * @param len Destination buffer length. + * + * @return 0 on success; + * A BLE host HCI return code if the controller + * rejected the request; + * A BLE host core return code on unexpected + * error. + */ +int ble_hs_hci_rand(void *dst, int len); + #ifdef __cplusplus } #endif diff --git a/nimble/host/mesh/src/glue.c b/nimble/host/mesh/src/glue.c index c00af9477e..f6f57f0598 100644 --- a/nimble/host/mesh/src/glue.c +++ b/nimble/host/mesh/src/glue.c @@ -588,7 +588,7 @@ int bt_rand(void *buf, size_t len) { int rc; - rc = ble_hs_hci_util_rand(buf, len); + rc = ble_hs_hci_rand(buf, len); if (rc != 0) { return -1; } diff --git a/nimble/host/src/ble_hs_hci_priv.h b/nimble/host/src/ble_hs_hci_priv.h index 9ff4c6f06e..356f3a538d 100644 --- a/nimble/host/src/ble_hs_hci_priv.h +++ b/nimble/host/src/ble_hs_hci_priv.h @@ -98,7 +98,6 @@ void ble_hs_hci_set_phony_ack_cb(ble_hs_hci_phony_ack_fn *cb); #endif int ble_hs_hci_util_read_adv_tx_pwr(int8_t *out_pwr); -int ble_hs_hci_util_rand(void *dst, int len); int ble_hs_hci_util_read_rssi(uint16_t conn_handle, int8_t *out_rssi); int ble_hs_hci_util_set_random_addr(const uint8_t *addr); int ble_hs_hci_util_set_data_len(uint16_t conn_handle, uint16_t tx_octets, diff --git a/nimble/host/src/ble_hs_hci_util.c b/nimble/host/src/ble_hs_hci_util.c index 14e55d52ed..11d0a77e74 100644 --- a/nimble/host/src/ble_hs_hci_util.c +++ b/nimble/host/src/ble_hs_hci_util.c @@ -58,7 +58,7 @@ ble_hs_hci_util_read_adv_tx_pwr(int8_t *out_tx_pwr) } int -ble_hs_hci_util_rand(void *dst, int len) +ble_hs_hci_rand(void *dst, int len) { struct ble_hci_le_rand_rp rsp; uint8_t *u8ptr; diff --git a/nimble/host/src/ble_hs_id.c b/nimble/host/src/ble_hs_id.c index bd50e20171..2dd21aa785 100644 --- a/nimble/host/src/ble_hs_id.c +++ b/nimble/host/src/ble_hs_id.c @@ -41,7 +41,7 @@ ble_hs_id_gen_rnd(int nrpa, ble_addr_t *out_addr) out_addr->type = BLE_ADDR_RANDOM; - rc = ble_hs_hci_util_rand(out_addr->val, 6); + rc = ble_hs_hci_rand(out_addr->val, 6); if (rc != 0) { return rc; } diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 5188effe94..6d781bd548 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -261,7 +261,7 @@ ble_sm_gen_pair_rand(uint8_t *pair_rand) } #endif - rc = ble_hs_hci_util_rand(pair_rand, 16); + rc = ble_hs_hci_rand(pair_rand, 16); if (rc != 0) { return rc; } @@ -282,7 +282,7 @@ ble_sm_gen_ediv(struct ble_sm_master_id *master_id) } #endif - rc = ble_hs_hci_util_rand(&master_id->ediv, sizeof master_id->ediv); + rc = ble_hs_hci_rand(&master_id->ediv, sizeof master_id->ediv); if (rc != 0) { return rc; } @@ -303,7 +303,7 @@ ble_sm_gen_master_id_rand(struct ble_sm_master_id *master_id) } #endif - rc = ble_hs_hci_util_rand(&master_id->rand_val, sizeof master_id->rand_val); + rc = ble_hs_hci_rand(&master_id->rand_val, sizeof master_id->rand_val); if (rc != 0) { return rc; } @@ -325,7 +325,7 @@ ble_sm_gen_ltk(struct ble_sm_proc *proc, uint8_t *ltk) } #endif - rc = ble_hs_hci_util_rand(ltk, proc->key_size); + rc = ble_hs_hci_rand(ltk, proc->key_size); if (rc != 0) { return rc; } @@ -350,7 +350,7 @@ ble_sm_gen_csrk(struct ble_sm_proc *proc, uint8_t *csrk) } #endif - rc = ble_hs_hci_util_rand(csrk, 16); + rc = ble_hs_hci_rand(csrk, 16); if (rc != 0) { return rc; } diff --git a/nimble/host/src/ble_sm_alg.c b/nimble/host/src/ble_sm_alg.c index 8b3326deb4..282a2b13f6 100644 --- a/nimble/host/src/ble_sm_alg.c +++ b/nimble/host/src/ble_sm_alg.c @@ -517,7 +517,7 @@ ble_sm_alg_rand(uint8_t *dst, unsigned int size) size -= num; } #else - if (ble_hs_hci_util_rand(dst, size)) { + if (ble_hs_hci_rand(dst, size)) { return 0; } #endif diff --git a/nimble/host/src/ble_sm_sc.c b/nimble/host/src/ble_sm_sc.c index 162a4a2ba1..0cd2b2ee86 100644 --- a/nimble/host/src/ble_sm_sc.c +++ b/nimble/host/src/ble_sm_sc.c @@ -893,7 +893,7 @@ ble_sm_sc_oob_generate_data(struct ble_sm_sc_oob_data *oob_data) return rc; } - rc = ble_hs_hci_util_rand(oob_data->r, 16); + rc = ble_hs_hci_rand(oob_data->r, 16); if (rc) { return rc; } From c3b05eb4d855a05bbf4b2abbef9d8a375cb4650e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 5 Oct 2022 11:42:07 +0200 Subject: [PATCH 0582/1333] nimble/host: Add APIs to handle vs HCI commands and events This adds API to send a vs hci command and an event to handle vs hci events. --- nimble/host/include/host/ble_gap.h | 14 ++++++++++++++ nimble/host/include/host/ble_hs_hci.h | 18 ++++++++++++++++++ nimble/host/src/ble_gap.c | 15 +++++++++++++++ nimble/host/src/ble_gap_priv.h | 1 + nimble/host/src/ble_hs_hci.c | 14 ++++++++++++++ nimble/host/src/ble_hs_hci_evt.c | 22 ++++++++++++++++++++++ 6 files changed, 84 insertions(+) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index 37ac797463..b132189a07 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -139,6 +139,7 @@ struct hci_conn_update; #define BLE_GAP_EVENT_TRANSMIT_POWER 26 #define BLE_GAP_EVENT_PARING_COMPLETE 27 #define BLE_GAP_EVENT_SUBRATE_CHANGE 28 +#define BLE_GAP_EVENT_VS_HCI 29 /*** Reason codes for the subscribe GAP event. */ @@ -1071,6 +1072,19 @@ struct ble_gap_event { uint16_t supervision_tmo; } subrate_change; #endif + +#if MYNEWT_VAL(BLE_HCI_VS) + /** + * Represents a received vendor-specific HCI event + * + * Valid for the following event types: + * o BLE_GAP_EVENT_VS_HCI + */ + struct { + const void *ev; + uint8_t length; + } vs_hci; +#endif }; }; diff --git a/nimble/host/include/host/ble_hs_hci.h b/nimble/host/include/host/ble_hs_hci.h index 739eea9265..237712080a 100644 --- a/nimble/host/include/host/ble_hs_hci.h +++ b/nimble/host/include/host/ble_hs_hci.h @@ -102,6 +102,24 @@ int ble_hs_hci_set_chan_class(const uint8_t *chan_map); */ int ble_hs_hci_rand(void *dst, int len); +#if MYNEWT_VAL(BLE_HCI_VS) +/** + * Send an arbitrary HCI command to the controller. + * + * The command has to be a vendor-specific command, i.e. OGF=0x3f is always + * assumed. + * + * @param ocf OCF for vendor-specific HCI command + * @param cmdbuf command buffer + * @param cmdlen length of command buffer + * @param rspbuf response buffer + * @param rsplen length of response buffer + * @return 0 on success, error code on failure + */ +int ble_hs_hci_send_vs_cmd(uint16_t ocf, const void *cmdbuf, uint8_t cmdlen, + void *rspbuf, uint8_t rsplen); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 952b59b0a9..f726899506 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -6083,6 +6083,21 @@ ble_gap_mtu_event(uint16_t conn_handle, uint16_t cid, uint16_t mtu) #endif } +#if MYNEWT_VAL(BLE_HCI_VS) +void +ble_gap_vs_hci_event(const void *buf, uint8_t len) +{ + struct ble_gap_event event; + + memset(&event, 0, sizeof event); + event.type = BLE_GAP_EVENT_VS_HCI; + event.vs_hci.ev = buf; + event.vs_hci.length = len; + + ble_gap_event_listener_call(&event); +} +#endif + /***************************************************************************** * $preempt * *****************************************************************************/ diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h index 0e4947f154..5b627d1057 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/nimble/host/src/ble_gap_priv.h @@ -138,6 +138,7 @@ void ble_gap_mtu_event(uint16_t conn_handle, uint16_t cid, uint16_t mtu); void ble_gap_identity_event(uint16_t conn_handle); int ble_gap_repeat_pairing_event(const struct ble_gap_repeat_pairing *rp); void ble_gap_pairing_complete_event(uint16_t conn_handle, int status); +void ble_gap_vs_hci_event(const void *buf, uint8_t len); int ble_gap_master_in_progress(void); void ble_gap_preempt(void); diff --git a/nimble/host/src/ble_hs_hci.c b/nimble/host/src/ble_hs_hci.c index 0624e387d1..af61b5454b 100644 --- a/nimble/host/src/ble_hs_hci.c +++ b/nimble/host/src/ble_hs_hci.c @@ -349,6 +349,20 @@ ble_hs_hci_cmd_tx(uint16_t opcode, const void *cmd, uint8_t cmd_len, return rc; } +#if MYNEWT_VAL(BLE_HCI_VS) +int +ble_hs_hci_send_vs_cmd(uint16_t ocf, const void *cmdbuf, uint8_t cmdlen, + void *rspbuf, uint8_t rsplen) +{ + int rc; + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_VENDOR, ocf), + cmdbuf, cmdlen, rspbuf, rsplen); + + return rc; +} +#endif + static void ble_hs_hci_rx_ack(uint8_t *ack_ev) { diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index f7113f6318..9437e755cb 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -38,6 +38,9 @@ static ble_hs_hci_evt_fn ble_hs_hci_evt_encrypt_change; static ble_hs_hci_evt_fn ble_hs_hci_evt_enc_key_refresh; #endif static ble_hs_hci_evt_fn ble_hs_hci_evt_le_meta; +#if MYNEWT_VAL(BLE_HCI_VS) +static ble_hs_hci_evt_fn ble_hs_hci_evt_vs; +#endif typedef int ble_hs_hci_evt_le_fn(uint8_t subevent, const void *data, unsigned int len); @@ -93,6 +96,9 @@ static const struct ble_hs_hci_evt_dispatch_entry ble_hs_hci_evt_dispatch[] = { { BLE_HCI_EVCODE_ENC_KEY_REFRESH, ble_hs_hci_evt_enc_key_refresh }, #endif { BLE_HCI_EVCODE_HW_ERROR, ble_hs_hci_evt_hw_error }, +#if MYNEWT_VAL(BLE_HCI_VS) + { BLE_HCI_EVCODE_VS, ble_hs_hci_evt_vs }, +#endif }; #define BLE_HS_HCI_EVT_DISPATCH_SZ \ @@ -274,6 +280,22 @@ ble_hs_hci_evt_num_completed_pkts(uint8_t event_code, const void *data, return 0; } +#if MYNEWT_VAL(BLE_HCI_VS) +static int +ble_hs_hci_evt_vs(uint8_t event_code, const void *data, unsigned int len) +{ + const struct ble_hci_ev_vs *ev = data; + + if (len < sizeof(*ev)) { + return BLE_HS_ECONTROLLER; + } + + ble_gap_vs_hci_event(data, len); + + return 0; +} +#endif + static int ble_hs_hci_evt_le_meta(uint8_t event_code, const void *data, unsigned int len) { From dd19017bec40c2fabd825236dc15dde974f639a0 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 14 Oct 2022 16:39:55 +0200 Subject: [PATCH 0583/1333] nimble/ll: Fix syscfg restrictions syscfg conditions should use single quotes --- nimble/transport/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml index becd81d617..e8d83bd15f 100644 --- a/nimble/transport/syscfg.yml +++ b/nimble/transport/syscfg.yml @@ -93,5 +93,5 @@ $import: - "@apache-mynewt-nimble/nimble/transport/syscfg.monitor.yml" - "@apache-mynewt-nimble/nimble/transport/syscfg.defunct.yml" -syscfg.vals."BLE_EXT_ADV || BLE_LL_CFG_FEAT_LL_EXT_ADV": +syscfg.vals.'BLE_EXT_ADV || BLE_LL_CFG_FEAT_LL_EXT_ADV': BLE_TRANSPORT_EVT_SIZE: 257 From a36a73083ca50b30c68cb5dabe3f4688e4de9cd7 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 10 Oct 2022 23:48:42 +0200 Subject: [PATCH 0584/1333] nimble/host: Add host callback to provide security keys Application can use new callback to generate keys for new pairing prior to keys distribution. This allows keys to be derived from some other source (e.g. as in Vol 3, Part H, appendix B) instead of just being randomized. This also provides sane way of setting IRK from application that will be applied when host starts. --- nimble/host/include/host/ble_hs.h | 3 + nimble/host/include/host/ble_store.h | 36 +++++++++++ nimble/host/src/ble_hs_startup.c | 16 ++++- nimble/host/src/ble_sm.c | 92 ++++++++++++++++++++-------- 4 files changed, 122 insertions(+), 25 deletions(-) diff --git a/nimble/host/include/host/ble_hs.h b/nimble/host/include/host/ble_hs.h index e1dff5e006..1f4f19041f 100644 --- a/nimble/host/include/host/ble_hs.h +++ b/nimble/host/include/host/ble_hs.h @@ -276,6 +276,9 @@ struct ble_hs_cfg { */ ble_hs_sync_fn *sync_cb; + /** Callback to handle generation of security keys */ + ble_store_gen_key_fn *store_gen_key_cb; + /* XXX: These need to go away. Instead, the nimble host package should * require the host-store API (not yet implemented).. */ diff --git a/nimble/host/include/host/ble_store.h b/nimble/host/include/host/ble_store.h index 30a5666cfe..7c03ed860e 100644 --- a/nimble/host/include/host/ble_store.h +++ b/nimble/host/include/host/ble_store.h @@ -178,6 +178,42 @@ struct ble_store_status_event { }; }; +/* Generate LTK, EDIT and Rand */ +#define BLE_STORE_GEN_KEY_LTK 0x01 +/* Generate IRK */ +#define BLE_STORE_GEN_KEY_IRK 0x02 +/* Generate CSRK */ +#define BLE_STORE_GEN_KEY_CSRK 0x03 + +struct ble_store_gen_key { + union { + uint8_t ltk_periph[16]; + uint8_t irk[16]; + uint8_t csrk[16]; + }; + uint16_t ediv; + uint64_t rand; +}; + +/** + * Generates key required by security module. + * This can be used to use custom routines to generate keys instead of simply + * randomizing them. + * + * \p conn_handle is set to \p BLE_HS_CONN_HANDLE_NONE if key is not requested + * for a specific connection (e.g. an IRK). + * + * @param key Key that shall be generated. + * @param gen_key Storage for generated key. + * @param conn_handle Connection handle for which keys are generated. + * + * @return 0 if keys were generated successfully + * Other nonzero on error. + */ +typedef int ble_store_gen_key_fn(uint8_t key, + struct ble_store_gen_key *gen_key, + uint16_t conn_handle); + /** * Searches the store for an object matching the specified criteria. If a * match is found, it is read from the store and the dst parameter is populated diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c index 03f3d2e4a4..0843671b75 100644 --- a/nimble/host/src/ble_hs_startup.c +++ b/nimble/host/src/ble_hs_startup.c @@ -318,6 +318,7 @@ ble_hs_startup_reset_tx(void) int ble_hs_startup_go(void) { + struct ble_store_gen_key gen_key; int rc; rc = ble_hs_startup_reset_tx(); @@ -372,7 +373,20 @@ ble_hs_startup_go(void) return rc; } - ble_hs_pvcy_set_our_irk(NULL); + if (ble_hs_cfg.store_gen_key_cb) { + memset(&gen_key, 0, sizeof(gen_key)); + rc = ble_hs_cfg.store_gen_key_cb(BLE_STORE_GEN_KEY_IRK, &gen_key, + BLE_HS_CONN_HANDLE_NONE); + if (rc == 0) { + ble_hs_pvcy_set_our_irk(gen_key.irk); + } + } else { + rc = -1; + } + + if (rc != 0) { + ble_hs_pvcy_set_our_irk(NULL); + } /* If flow control is enabled, configure the controller to use it. */ ble_hs_flow_startup(); diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 6d781bd548..9106d26ce1 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -2078,6 +2078,8 @@ ble_sm_key_exch_exec(struct ble_sm_proc *proc, struct ble_sm_result *res, uint8_t our_key_dist; struct os_mbuf *txom; const uint8_t *irk; + struct ble_store_gen_key gen_key; + int ltk_gen = 0; int rc; ble_sm_key_dist(proc, &init_key_dist, &resp_key_dist); @@ -2095,15 +2097,37 @@ ble_sm_key_exch_exec(struct ble_sm_proc *proc, struct ble_sm_result *res, goto err; } - rc = ble_sm_gen_ltk(proc, enc_info->ltk); - if (rc != 0) { - os_mbuf_free_chain(txom); - goto err; + proc->our_keys.key_size = proc->key_size; + + if (ble_hs_cfg.store_gen_key_cb) { + memset(&gen_key, 0, sizeof(gen_key)); + rc = ble_hs_cfg.store_gen_key_cb(BLE_STORE_GEN_KEY_LTK, &gen_key, + proc->conn_handle); + if (rc == 0) { + /* Trim LRK to keysize */ + memset(gen_key.ltk_periph + proc->key_size, 0, + 16 - proc->key_size); + + proc->our_keys.ediv = gen_key.ediv; + proc->our_keys.rand_val = gen_key.rand; + memcpy(proc->our_keys.ltk, gen_key.ltk_periph, 16); + + ltk_gen = 1; + } } - /* store LTK before sending since ble_sm_tx consumes tx mbuf */ - memcpy(proc->our_keys.ltk, enc_info->ltk, 16); - proc->our_keys.key_size = proc->key_size; + if (!ltk_gen) { + rc = ble_sm_gen_ltk(proc, enc_info->ltk); + if (rc != 0) { + os_mbuf_free_chain(txom); + goto err; + } + + /* store LTK before sending since ble_sm_tx consumes tx mbuf */ + memcpy(proc->our_keys.ltk, enc_info->ltk, 16); + } else { + memcpy(enc_info->ltk, proc->our_keys.ltk, 16); + } proc->our_keys.ltk_valid = 1; rc = ble_sm_tx(proc->conn_handle, txom); @@ -2119,20 +2143,25 @@ ble_sm_key_exch_exec(struct ble_sm_proc *proc, struct ble_sm_result *res, goto err; } - rc = ble_sm_gen_ediv(master_id); - if (rc != 0) { - os_mbuf_free_chain(txom); - goto err; - } - rc = ble_sm_gen_master_id_rand(master_id); - if (rc != 0) { - os_mbuf_free_chain(txom); - goto err; - } + if (!ltk_gen) { + rc = ble_sm_gen_ediv(master_id); + if (rc != 0) { + os_mbuf_free_chain(txom); + goto err; + } + rc = ble_sm_gen_master_id_rand(master_id); + if (rc != 0) { + os_mbuf_free_chain(txom); + goto err; + } + proc->our_keys.rand_val = master_id->rand_val; + proc->our_keys.ediv = master_id->ediv; + } else { + master_id->ediv = proc->our_keys.ediv; + master_id->rand_val = proc->our_keys.rand_val; + } proc->our_keys.ediv_rand_valid = 1; - proc->our_keys.rand_val = master_id->rand_val; - proc->our_keys.ediv = master_id->ediv; rc = ble_sm_tx(proc->conn_handle, txom); if (rc != 0) { @@ -2197,14 +2226,29 @@ ble_sm_key_exch_exec(struct ble_sm_proc *proc, struct ble_sm_result *res, goto err; } - rc = ble_sm_gen_csrk(proc, sign_info->sig_key); - if (rc != 0) { - os_mbuf_free_chain(txom); - goto err; + if (ble_hs_cfg.store_gen_key_cb) { + memset(&gen_key, 0, sizeof(gen_key)); + rc = ble_hs_cfg.store_gen_key_cb(BLE_STORE_GEN_KEY_CSRK, &gen_key, + proc->conn_handle); + if (rc == 0) { + memcpy(proc->our_keys.csrk, gen_key.csrk, 16); + } + } else { + rc = -1; } + if (rc != 0) { + rc = ble_sm_gen_csrk(proc, sign_info->sig_key); + if (rc != 0) { + os_mbuf_free_chain(txom); + goto err; + } + + memcpy(proc->our_keys.csrk, sign_info->sig_key, 16); + } else { + memcpy(sign_info->sig_key, proc->our_keys.csrk, 16); + } proc->our_keys.csrk_valid = 1; - memcpy(proc->our_keys.csrk, sign_info->sig_key, 16); rc = ble_sm_tx(proc->conn_handle, txom); if (rc != 0) { From 7022ad22708b80016c9834edc5bd51564705c208 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 24 Oct 2022 11:39:00 +0200 Subject: [PATCH 0585/1333] nimble/ll/css: Always enable css if vs hci is disabled Without vs hci there's nothing else to enable css... --- nimble/controller/src/ble_ll_sched.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 3b2b885cde..32900b8ea1 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -1204,6 +1204,9 @@ ble_ll_sched_init(void) g_ble_ll_sched_css.slot_us = MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_SLOT_US); g_ble_ll_sched_css.period_slots = MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_PERIOD_SLOTS); #endif +#if !MYNEWT_VAL(BLE_LL_HCI_VS_CONN_STRICT_SCHED) + g_ble_ll_sched_css.enabled = 1; +#endif #endif return 0; From 36406e05dc73b0386c4d5119e267c4c645df4cb7 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 24 Oct 2022 14:20:41 +0200 Subject: [PATCH 0586/1333] nimble/ll/css: Fix scheduling 1st conn event If we try to schedule new connection after reference connection slot, but before slot for that connection (in the same period), anchor point will be set too far in the future and thus window offset will be more than connection interval which is invalid. This is because reference period idx is advanced after connection event for reference connection has ended, i.e. stored period idx value is N+1 for each subsequent in N-th period. To schedule connections properly we should first try to schedule in N-th period, i.e. stored value -1. --- nimble/controller/src/ble_ll_sched.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 32900b8ea1..cf64e82f3a 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -517,12 +517,22 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, connsm->css_period_idx = 0; max_delay = connsm->conn_itvl_ticks; } else { - connsm->css_period_idx = css->period_anchor_idx; + /* Reference connection may be already at next period if it has + * slot index lower than our, so we first try schedule one period + * earlier since our slot index in that period may not yet have + * passed. This avoids scheduling 1st connection event too far in + * the future, i.e. more than conn interval. + */ + if (connsm->css_slot_idx > css->period_anchor_slot_idx) { + connsm->css_period_idx = css->period_anchor_idx - 1; + } else { + connsm->css_period_idx = css->period_anchor_idx; + } max_delay = 0; } - /* It's possible that calculated anchor point in current period has - * already passed, so just move to next period and recalculate. + /* Calculate anchor point and move to next period if scheduled too + * early. */ connsm->css_period_idx--; do { From 98a683e1b4f3d8c8847ad5790c2e16b11899c5ee Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 26 Oct 2022 13:07:03 +0200 Subject: [PATCH 0587/1333] nimble/host: Add support for enabling controller DTM This allows to controll DTM from application. --- nimble/host/include/host/ble_dtm.h | 49 +++++++++++++++++++++ nimble/host/src/ble_dtm.c | 71 ++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 nimble/host/include/host/ble_dtm.h create mode 100644 nimble/host/src/ble_dtm.c diff --git a/nimble/host/include/host/ble_dtm.h b/nimble/host/include/host/ble_dtm.h new file mode 100644 index 0000000000..e340a3069a --- /dev/null +++ b/nimble/host/include/host/ble_dtm.h @@ -0,0 +1,49 @@ +/* + * 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_BLE_DTM_ +#define H_BLE_DTM_ + +#include +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_dtm_rx_params { + uint8_t channel; + uint8_t phy; + uint8_t modulation_index; +}; + +int ble_dtm_rx_start(const struct ble_dtm_rx_params *params); + +struct ble_dtm_tx_params { + uint8_t channel; + uint8_t test_data_len; + uint8_t payload; + uint8_t phy; +}; +int ble_dtm_tx_start(const struct ble_dtm_tx_params *params); + +int ble_dtm_stop(uint16_t *num_packets); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/nimble/host/src/ble_dtm.c b/nimble/host/src/ble_dtm.c new file mode 100644 index 0000000000..d88bee2702 --- /dev/null +++ b/nimble/host/src/ble_dtm.c @@ -0,0 +1,71 @@ +/* + * 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. + */ + +#include +#include +#include +#include "ble_hs_hci_priv.h" + +int +ble_dtm_rx_start(const struct ble_dtm_rx_params *params) +{ + struct ble_hci_le_rx_test_v2_cp cmd; + + cmd.rx_chan = params->channel; + cmd.phy = params->phy; + cmd.index = params->modulation_index; + + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_RX_TEST_V2), + &cmd, sizeof(cmd), NULL, 0); +} + +int +ble_dtm_tx_start(const struct ble_dtm_tx_params *params) +{ + struct ble_hci_le_tx_test_v2_cp cmd; + + cmd.tx_chan = params->channel; + cmd.test_data_len = params->test_data_len; + cmd.payload = params->payload; + cmd.phy = params->phy; + + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_TX_TEST_V2), + &cmd, sizeof(cmd), NULL, 0); +} + +int +ble_dtm_stop(uint16_t *num_packets) +{ + struct ble_hci_le_test_end_rp rsp; + int rc; + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_TEST_END), + NULL, 0, &rsp, sizeof(rsp)); + + if (rc) { + *num_packets = 0; + } else { + *num_packets = le16toh(rsp.num_packets); + } + + return rc; +} From 183dbf49b3d5db059f5efc60ffde229bb3d5f147 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 28 Oct 2022 09:51:48 +0200 Subject: [PATCH 0588/1333] nimble/ll: Add helper for checking if controller is busy ble_ll_is_busy() returns 1 if there is anything related to radio activity happening in LL (scanning, advertising, connections etc). --- nimble/controller/src/ble_ll.c | 46 +++++++++++++++++++++++++++++ nimble/controller/src/ble_ll_priv.h | 5 ++++ 2 files changed, 51 insertions(+) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 9384a46c7b..aa91d2133c 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -2061,3 +2061,49 @@ ble_ll_tx_power_set(int tx_power) #endif ble_phy_tx_power_set(tx_power); } + +int +ble_ll_is_busy(void) +{ +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + struct ble_ll_conn_sm *cur; + int i = 0; +#endif + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) + if (ble_ll_sync_enabled()) { + return 1; + } +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) + if (ble_ll_adv_enabled()) { + return 1; + } +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) + if (ble_ll_scan_enabled()) { + return 1; + } +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + if (g_ble_ll_conn_create_sm.connsm) { + return 1; + } +#endif + +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + STAILQ_FOREACH(cur, &g_ble_ll_conn_free_list, free_stqe) { + i++; + } + + /* check if all connection objects are free */ + if (i < MYNEWT_VAL(BLE_MAX_CONNECTIONS)) { + return 1; + } +#endif + + return 0; +} diff --git a/nimble/controller/src/ble_ll_priv.h b/nimble/controller/src/ble_ll_priv.h index 1ee30882c5..0a41509b34 100644 --- a/nimble/controller/src/ble_ll_priv.h +++ b/nimble/controller/src/ble_ll_priv.h @@ -47,6 +47,11 @@ ble_ll_rx_gain(void) return gain; } +/* if there is any radio related activity enabled + * (scanning, advertising, connection etc) + */ +int ble_ll_is_busy(void); + #ifdef MYNEWT #include "syscfg/syscfg.h" From 50a993f1b8ebe224da905d24644435f7c7a842c1 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 28 Oct 2022 09:53:12 +0200 Subject: [PATCH 0589/1333] nimble/ll: Use common helper for checking if allowed to set TX power No need for local helper. --- nimble/controller/src/ble_ll_hci_vs.c | 54 +-------------------------- 1 file changed, 2 insertions(+), 52 deletions(-) diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index 9f7fb18517..3f373c4264 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -57,56 +57,6 @@ ble_ll_hci_vs_rd_static_addr(uint16_t ocf, return BLE_ERR_SUCCESS; } -/* disallow changing TX power if there is any radio activity - * note: we could allow to change it if there is no TX activity (eg only - * passive scan or sync) but lets just keep this simple for now - */ -static int -ble_ll_hci_vs_is_controller_busy(void) -{ -#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - struct ble_ll_conn_sm *cur; - int i = 0; -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) - if (ble_ll_sync_enabled()) { - return 1; - } -#endif - -#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) - if (ble_ll_adv_enabled()) { - return 1; - } -#endif - -#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) - if (ble_ll_scan_enabled()) { - return 1; - } -#endif - -#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - if (g_ble_ll_conn_create_sm.connsm) { - return 1; - } -#endif - -#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - STAILQ_FOREACH(cur, &g_ble_ll_conn_free_list, free_stqe) { - i++; - } - - /* check if all connection objects are free */ - if (i < MYNEWT_VAL(BLE_MAX_CONNECTIONS)) { - return 1; - } -#endif - - return 0; -} - static int ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen) @@ -118,7 +68,7 @@ ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, return BLE_ERR_INV_HCI_CMD_PARMS; } - if (ble_ll_hci_vs_is_controller_busy()) { + if (ble_ll_is_busy()) { return BLE_ERR_CMD_DISALLOWED; } @@ -367,7 +317,7 @@ ble_ll_hci_vs_set_antenna(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, return BLE_ERR_INV_HCI_CMD_PARMS; } - if (ble_ll_hci_vs_is_controller_busy()) { + if (ble_ll_is_busy()) { return BLE_ERR_CMD_DISALLOWED; } From 5a9b202a0d0ead9bc03adcd83addbe9bf72c2f81 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 28 Oct 2022 09:53:54 +0200 Subject: [PATCH 0590/1333] nimble/ll: Don't allow to enable DTM if controller is busy DTM disables whitening and should not be mixed with any normal BLE traffic. --- nimble/controller/src/ble_ll_dtm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index 2a32ccca2a..352a380ae9 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -483,7 +483,7 @@ ble_ll_dtm_tx_test(uint8_t tx_chan, uint8_t len, uint8_t packet_payload, { uint8_t phy_mode; - if (g_ble_ll_dtm_ctx.active) { + if (g_ble_ll_dtm_ctx.active || ble_ll_is_busy()) { return BLE_ERR_CTLR_BUSY; } @@ -585,7 +585,7 @@ ble_ll_dtm_rx_test(uint8_t rx_chan, uint8_t hci_phy) { uint8_t phy_mode; - if (g_ble_ll_dtm_ctx.active) { + if (g_ble_ll_dtm_ctx.active || ble_ll_is_busy()) { return BLE_ERR_CTLR_BUSY; } From ae414aa597a0da5591cbb37b7c48f2f82f755cc9 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 28 Oct 2022 10:13:40 +0200 Subject: [PATCH 0591/1333] nimble/ll: Disallow HCI commands if DTM test is enabled If DTM is enabled we should not allow for other activities. To keep things simple just disallow all commands except LE Test End and Reset. --- nimble/controller/src/ble_ll_dtm.c | 6 ++++++ nimble/controller/src/ble_ll_dtm_priv.h | 1 + nimble/controller/src/ble_ll_hci.c | 18 +++++++++++++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index 352a380ae9..705d5b2582 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -705,6 +705,12 @@ ble_ll_dtm_reset(void) ble_ll_dtm_ctx_free(&g_ble_ll_dtm_ctx); } +int +ble_ll_dtm_enabled(void) +{ + return g_ble_ll_dtm_ctx.active; +} + void ble_ll_dtm_init(void) { diff --git a/nimble/controller/src/ble_ll_dtm_priv.h b/nimble/controller/src/ble_ll_dtm_priv.h index e04af07beb..1e0e2c6fd0 100644 --- a/nimble/controller/src/ble_ll_dtm_priv.h +++ b/nimble/controller/src/ble_ll_dtm_priv.h @@ -37,4 +37,5 @@ int ble_ll_dtm_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr); void ble_ll_dtm_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr); void ble_ll_dtm_wfr_timer_exp(void); void ble_ll_dtm_reset(void); +int ble_ll_dtm_enabled(void); #endif diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 79d90e5006..dc95f0de4a 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1756,6 +1756,22 @@ ble_ll_hci_cmd_proc(struct ble_npl_event *ev) /* Assume response length is zero */ rsplen = 0; +#if MYNEWT_VAL(BLE_LL_DTM) + /* if DTM test is enabled disallow any command other than LE Test End or + * HCI Reset + */ + if (ble_ll_dtm_enabled()) { + switch (opcode) { + case BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_TEST_END): + case BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, BLE_HCI_OCF_CB_RESET): + break; + default: + rc = BLE_ERR_CMD_DISALLOWED; + goto send_cc_cs; + } + } +#endif + #if MYNEWT_VAL(BLE_LL_HBD_FAKE_DUAL_MODE) rc = ble_ll_hci_cmd_fake_dual_mode(opcode, cmd->data, cmd->length, rspbuf, &rsplen); @@ -1798,7 +1814,7 @@ ble_ll_hci_cmd_proc(struct ble_npl_event *ev) rc += (BLE_ERR_MAX + 1); } -#if MYNEWT_VAL(BLE_LL_HBD_FAKE_DUAL_MODE) +#if MYNEWT_VAL(BLE_LL_HBD_FAKE_DUAL_MODE) || MYNEWT_VAL(BLE_LL_DTM) send_cc_cs: #endif /* If no response is generated, we free the buffers */ From bc66d1a315bc47dbac0ac54293d8db2edd0b2f40 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 28 Oct 2022 09:51:48 +0200 Subject: [PATCH 0592/1333] nimble/ll: Extend controller busy helper with flags This allows to optionally exclude specific checks (currently connections only). --- nimble/controller/src/ble_ll.c | 16 +++++++++------- nimble/controller/src/ble_ll_dtm.c | 4 ++-- nimble/controller/src/ble_ll_hci_vs.c | 4 ++-- nimble/controller/src/ble_ll_priv.h | 4 +++- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index aa91d2133c..d193b09d1c 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -2063,7 +2063,7 @@ ble_ll_tx_power_set(int tx_power) } int -ble_ll_is_busy(void) +ble_ll_is_busy(unsigned int flags) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) struct ble_ll_conn_sm *cur; @@ -2095,13 +2095,15 @@ ble_ll_is_busy(void) #endif #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - STAILQ_FOREACH(cur, &g_ble_ll_conn_free_list, free_stqe) { - i++; - } + if (!(flags & BLE_LL_BUSY_EXCLUDE_CONNECTIONS)) { + STAILQ_FOREACH(cur, &g_ble_ll_conn_free_list, free_stqe) { + i++; + } - /* check if all connection objects are free */ - if (i < MYNEWT_VAL(BLE_MAX_CONNECTIONS)) { - return 1; + /* check if all connection objects are free */ + if (i < MYNEWT_VAL(BLE_MAX_CONNECTIONS)) { + return 1; + } } #endif diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index 705d5b2582..9bf49e04ff 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -483,7 +483,7 @@ ble_ll_dtm_tx_test(uint8_t tx_chan, uint8_t len, uint8_t packet_payload, { uint8_t phy_mode; - if (g_ble_ll_dtm_ctx.active || ble_ll_is_busy()) { + if (g_ble_ll_dtm_ctx.active || ble_ll_is_busy(0)) { return BLE_ERR_CTLR_BUSY; } @@ -585,7 +585,7 @@ ble_ll_dtm_rx_test(uint8_t rx_chan, uint8_t hci_phy) { uint8_t phy_mode; - if (g_ble_ll_dtm_ctx.active || ble_ll_is_busy()) { + if (g_ble_ll_dtm_ctx.active || ble_ll_is_busy(0)) { return BLE_ERR_CTLR_BUSY; } diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index 3f373c4264..c07d9f788d 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -68,7 +68,7 @@ ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, return BLE_ERR_INV_HCI_CMD_PARMS; } - if (ble_ll_is_busy()) { + if (ble_ll_is_busy(0)) { return BLE_ERR_CMD_DISALLOWED; } @@ -317,7 +317,7 @@ ble_ll_hci_vs_set_antenna(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, return BLE_ERR_INV_HCI_CMD_PARMS; } - if (ble_ll_is_busy()) { + if (ble_ll_is_busy(0)) { return BLE_ERR_CMD_DISALLOWED; } diff --git a/nimble/controller/src/ble_ll_priv.h b/nimble/controller/src/ble_ll_priv.h index 0a41509b34..f0498fea8a 100644 --- a/nimble/controller/src/ble_ll_priv.h +++ b/nimble/controller/src/ble_ll_priv.h @@ -50,7 +50,9 @@ ble_ll_rx_gain(void) /* if there is any radio related activity enabled * (scanning, advertising, connection etc) */ -int ble_ll_is_busy(void); +#define BLE_LL_BUSY_EXCLUDE_CONNECTIONS 0x01 + +int ble_ll_is_busy(unsigned int flags); #ifdef MYNEWT From b7c1dd7a62dab4de17984f382e8ee101c5361c7d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 28 Oct 2022 11:51:22 +0200 Subject: [PATCH 0593/1333] nimble/ll: Use common helper for checking if allowed to set RL No need for local helper. --- nimble/controller/src/ble_ll_resolv.c | 38 ++++----------------------- 1 file changed, 5 insertions(+), 33 deletions(-) diff --git a/nimble/controller/src/ble_ll_resolv.c b/nimble/controller/src/ble_ll_resolv.c index a972fe3de8..8ec9a97d1b 100644 --- a/nimble/controller/src/ble_ll_resolv.c +++ b/nimble/controller/src/ble_ll_resolv.c @@ -31,6 +31,7 @@ #include "controller/ble_ll_sync.h" #include "controller/ble_hw.h" #include "ble_ll_conn_priv.h" +#include "ble_ll_priv.h" #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) struct ble_ll_resolv_data @@ -47,35 +48,6 @@ struct ble_ll_resolv_data g_ble_ll_resolv_data; __attribute__((aligned(4))) struct ble_ll_resolv_entry g_ble_ll_resolv_list[MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE)]; -static int -ble_ll_is_controller_busy(void) -{ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) - if (ble_ll_sync_enabled()) { - return 1; - } -#endif - -#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) - if (ble_ll_adv_enabled()) { - return 1; - } -#endif - -#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) - if (ble_ll_scan_enabled()) { - return 1; - } -#endif - -#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - if (g_ble_ll_conn_create_sm.connsm) { - return 1; - } -#endif - - return 0; -} /** * Called to determine if a change is allowed to the resolving list at this * time. We are not allowed to modify the resolving list if address translation @@ -90,7 +62,7 @@ ble_ll_resolv_list_chg_allowed(void) int rc; if (g_ble_ll_resolv_data.addr_res_enabled && - ble_ll_is_controller_busy()) { + ble_ll_is_busy(BLE_LL_BUSY_EXCLUDE_CONNECTIONS)) { rc = 0; } else { rc = 1; @@ -456,8 +428,8 @@ ble_ll_resolv_enable_cmd(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } - if (ble_ll_is_controller_busy()) { - return BLE_ERR_CMD_DISALLOWED; + if (ble_ll_is_busy(BLE_LL_BUSY_EXCLUDE_CONNECTIONS)) { + return BLE_ERR_CMD_DISALLOWED; } @@ -561,7 +533,7 @@ ble_ll_resolve_set_priv_mode(const uint8_t *cmdbuf, uint8_t len) const struct ble_hci_le_set_privacy_mode_cp *cmd = (const void *) cmdbuf; struct ble_ll_resolv_entry *rl; - if (ble_ll_is_controller_busy()) { + if (ble_ll_is_busy(BLE_LL_BUSY_EXCLUDE_CONNECTIONS)) { return BLE_ERR_CMD_DISALLOWED; } From 639da1a0f3a330bf765c2fd0662cb54fac69c1a6 Mon Sep 17 00:00:00 2001 From: timoxd7 Date: Mon, 7 Nov 2022 14:51:55 +0100 Subject: [PATCH 0594/1333] Removed 'using namespace std;' from header file --- porting/npl/linux/src/wqueue.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/porting/npl/linux/src/wqueue.h b/porting/npl/linux/src/wqueue.h index 1de779e7d3..d9a7b6cc42 100644 --- a/porting/npl/linux/src/wqueue.h +++ b/porting/npl/linux/src/wqueue.h @@ -25,8 +25,6 @@ #include #include -using namespace std; - template class wqueue { list m_queue; From 32f2ab3ab6dca320ff4b74ab93da2700b7f71d78 Mon Sep 17 00:00:00 2001 From: timoxd7 Date: Mon, 7 Nov 2022 14:53:12 +0100 Subject: [PATCH 0595/1333] Moved min/max macros from global scope in header file to translation unit exlusice c files --- nimble/host/src/ble_att.c | 9 +++++++++ nimble/host/src/ble_gap.c | 8 ++++++++ nimble/host/src/ble_gattc.c | 9 +++++++++ nimble/host/src/ble_hs_hci_util.c | 8 ++++++++ nimble/host/src/ble_sm.c | 9 +++++++++ porting/nimble/include/os/os.h | 8 -------- porting/nimble/src/os_mbuf.c | 8 ++++++++ 7 files changed, 51 insertions(+), 8 deletions(-) diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index 5f119ac1cc..81e08aa049 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -23,6 +23,15 @@ #include "host/ble_att.h" #if NIMBLE_BLE_CONNECT + +#ifndef min +#define min(a, b) ((a)<(b)?(a):(b)) +#endif + +#ifndef max +#define max(a, b) ((a)>(b)?(a):(b)) +#endif + static uint16_t ble_att_preferred_mtu_val; /** Dispatch table for incoming ATT requests. Sorted by op code. */ diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index f726899506..89fc39408e 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -27,6 +27,14 @@ #include "ble_hs_priv.h" #include "ble_gap_priv.h" +#ifndef min +#define min(a, b) ((a)<(b)?(a):(b)) +#endif + +#ifndef max +#define max(a, b) ((a)>(b)?(a):(b)) +#endif + #if MYNEWT #include "bsp/bsp.h" #else diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index e4bd0a42ee..d2b198fa65 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -62,6 +62,15 @@ #include "ble_hs_priv.h" #if NIMBLE_BLE_CONNECT + +#ifndef min +#define min(a, b) ((a)<(b)?(a):(b)) +#endif + +#ifndef max +#define max(a, b) ((a)>(b)?(a):(b)) +#endif + /***************************************************************************** * $definitions / declarations * *****************************************************************************/ diff --git a/nimble/host/src/ble_hs_hci_util.c b/nimble/host/src/ble_hs_hci_util.c index 11d0a77e74..cb55469c24 100644 --- a/nimble/host/src/ble_hs_hci_util.c +++ b/nimble/host/src/ble_hs_hci_util.c @@ -22,6 +22,14 @@ #include "host/ble_hs_hci.h" #include "ble_hs_priv.h" +#ifndef min +#define min(a, b) ((a)<(b)?(a):(b)) +#endif + +#ifndef max +#define max(a, b) ((a)>(b)?(a):(b)) +#endif + uint16_t ble_hs_hci_util_handle_pb_bc_join(uint16_t handle, uint8_t pb, uint8_t bc) { diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 9106d26ce1..9a66de304e 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -49,6 +49,15 @@ #include "ble_hs_priv.h" #if NIMBLE_BLE_CONNECT + +#ifndef min +#define min(a, b) ((a)<(b)?(a):(b)) +#endif + +#ifndef max +#define max(a, b) ((a)>(b)?(a):(b)) +#endif + #if NIMBLE_BLE_SM /** Procedure timeout; 30 seconds. */ diff --git a/porting/nimble/include/os/os.h b/porting/nimble/include/os/os.h index f7a7ef9c58..da7427f6e0 100644 --- a/porting/nimble/include/os/os.h +++ b/porting/nimble/include/os/os.h @@ -26,14 +26,6 @@ extern "C" { #endif -#ifndef min -#define min(a, b) ((a)<(b)?(a):(b)) -#endif - -#ifndef max -#define max(a, b) ((a)>(b)?(a):(b)) -#endif - #include "syscfg/syscfg.h" #include "nimble/nimble_npl.h" diff --git a/porting/nimble/src/os_mbuf.c b/porting/nimble/src/os_mbuf.c index cebdb29f78..804badc82b 100644 --- a/porting/nimble/src/os_mbuf.c +++ b/porting/nimble/src/os_mbuf.c @@ -41,6 +41,14 @@ #include #include +#ifndef min +#define min(a, b) ((a)<(b)?(a):(b)) +#endif + +#ifndef max +#define max(a, b) ((a)>(b)?(a):(b)) +#endif + /** * @addtogroup OSKernel * @{ From cea78d32c29b72950f4778817ccea2b3705271ec Mon Sep 17 00:00:00 2001 From: timoxd7 Date: Tue, 15 Nov 2022 21:11:04 +0100 Subject: [PATCH 0596/1333] Fixed min/max formatting --- nimble/host/src/ble_att.c | 4 ++-- nimble/host/src/ble_gap.c | 4 ++-- nimble/host/src/ble_gattc.c | 4 ++-- nimble/host/src/ble_hs_hci_util.c | 4 ++-- nimble/host/src/ble_sm.c | 4 ++-- porting/nimble/src/os_mbuf.c | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index 81e08aa049..d2b460ce39 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -25,11 +25,11 @@ #if NIMBLE_BLE_CONNECT #ifndef min -#define min(a, b) ((a)<(b)?(a):(b)) +#define min(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef max -#define max(a, b) ((a)>(b)?(a):(b)) +#define max(a, b) ((a) > (b) ? (a) : (b)) #endif static uint16_t ble_att_preferred_mtu_val; diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 89fc39408e..ba1ec7fb09 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -28,11 +28,11 @@ #include "ble_gap_priv.h" #ifndef min -#define min(a, b) ((a)<(b)?(a):(b)) +#define min(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef max -#define max(a, b) ((a)>(b)?(a):(b)) +#define max(a, b) ((a) > (b) ? (a) : (b)) #endif #if MYNEWT diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index d2b198fa65..4763f14ef2 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -64,11 +64,11 @@ #if NIMBLE_BLE_CONNECT #ifndef min -#define min(a, b) ((a)<(b)?(a):(b)) +#define min(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef max -#define max(a, b) ((a)>(b)?(a):(b)) +#define max(a, b) ((a) > (b) ? (a) : (b)) #endif /***************************************************************************** diff --git a/nimble/host/src/ble_hs_hci_util.c b/nimble/host/src/ble_hs_hci_util.c index cb55469c24..f9897acaa3 100644 --- a/nimble/host/src/ble_hs_hci_util.c +++ b/nimble/host/src/ble_hs_hci_util.c @@ -23,11 +23,11 @@ #include "ble_hs_priv.h" #ifndef min -#define min(a, b) ((a)<(b)?(a):(b)) +#define min(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef max -#define max(a, b) ((a)>(b)?(a):(b)) +#define max(a, b) ((a) > (b) ? (a) : (b)) #endif uint16_t diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 9a66de304e..4658e1d2b2 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -51,11 +51,11 @@ #if NIMBLE_BLE_CONNECT #ifndef min -#define min(a, b) ((a)<(b)?(a):(b)) +#define min(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef max -#define max(a, b) ((a)>(b)?(a):(b)) +#define max(a, b) ((a) > (b) ? (a) : (b)) #endif #if NIMBLE_BLE_SM diff --git a/porting/nimble/src/os_mbuf.c b/porting/nimble/src/os_mbuf.c index 804badc82b..f659070328 100644 --- a/porting/nimble/src/os_mbuf.c +++ b/porting/nimble/src/os_mbuf.c @@ -42,11 +42,11 @@ #include #ifndef min -#define min(a, b) ((a)<(b)?(a):(b)) +#define min(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef max -#define max(a, b) ((a)>(b)?(a):(b)) +#define max(a, b) ((a) > (b) ? (a) : (b)) #endif /** From 68a41845f638d1d285c5117184fb87ac0d09f9a5 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 21 Nov 2022 15:30:20 +0100 Subject: [PATCH 0597/1333] nimble/ll: Require 257 bytes HCI events when enabling fake dual-mode Some BR/EDR commands eg. Read Local Name command have fixed (max allowed HCI event size) return values. If event size is smaller it results in assert. --- nimble/controller/syscfg.hbd.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/controller/syscfg.hbd.yml b/nimble/controller/syscfg.hbd.yml index d5a05e1444..ee5a86e942 100644 --- a/nimble/controller/syscfg.hbd.yml +++ b/nimble/controller/syscfg.hbd.yml @@ -23,3 +23,5 @@ syscfg.defs: device. It can be initialized and used by Windows 10 to some extent. value: 0 + restrictions: + - '(BLE_TRANSPORT_EVT_SIZE == 257) if 1' From 94d4ce064805944cddf18debc16c8e8dc160dabf Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 23 Nov 2022 16:24:04 +0530 Subject: [PATCH 0598/1333] nimble/host: Enabled LE Power control event mask if feature is enabled --- nimble/host/src/ble_hs_startup.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c index 0843671b75..7509fd5e49 100644 --- a/nimble/host/src/ble_hs_startup.c +++ b/nimble/host/src/ble_hs_startup.c @@ -250,6 +250,17 @@ ble_hs_startup_le_set_evmask_tx(void) } #endif +#if MYNEWT_VAL(BLE_POWER_CONTROL) + if (version >= BLE_HCI_VER_BCS_5_2) { + /** + * Enable the following LE events: + * 0x0000000080000000 LE Path Loss Threshold event + * 0x0000000100000000 LE Transmit Power Reporting event + */ + mask |= 0x0000000180000000; + } +#endif + cmd.event_mask = htole64(mask); rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, From 2d433e1b5eafbba76129dee384b489894d6fc6f4 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 24 Nov 2022 13:51:02 +0100 Subject: [PATCH 0599/1333] nimble/ll: Fix adding peripheral connections to CSS list Only central role connections should be added to that list. --- nimble/controller/src/ble_ll_conn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 2d344e2275..5ca0997fd1 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2062,7 +2062,8 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) SLIST_INSERT_HEAD(&g_ble_ll_conn_active_list, connsm, act_sle); #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - if (ble_ll_sched_css_is_enabled()) { + if (ble_ll_sched_css_is_enabled() && + (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL)) { ble_ll_conn_css_update_list(connsm); } #endif From d16b023a56b1691b9cc61448b7d0f60606e0bfe9 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 25 Nov 2022 14:46:21 +0100 Subject: [PATCH 0600/1333] nimble/ll/css: Fix updating css list If connsm is already on css list and has slot index changed, the list may not be sorted properly so in some case item was not re-inseterd properly. To make things simpler, let's just remove item from the list and then find proper place for it bo be inserted, since doing both in single pass is too convoluted. --- nimble/controller/src/ble_ll_conn.c | 56 +++++++++++++++-------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 5ca0997fd1..8e327f4112 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -407,46 +407,48 @@ ble_ll_conn_cth_flow_process_cmd(const uint8_t *cmdbuf) static void ble_ll_conn_css_update_list(struct ble_ll_conn_sm *connsm) { - bool e_insert_found = false; - bool e_remove_found = false; - struct ble_ll_conn_sm *e_insert = NULL; - struct ble_ll_conn_sm *e_remove = NULL; - struct ble_ll_conn_sm *e_last = NULL; struct ble_ll_conn_sm *e; + struct ble_ll_conn_sm *e_last; + struct ble_ll_conn_sm *e_insert_after = NULL; + bool found_to_insert = false; - SLIST_FOREACH(e, &g_ble_ll_conn_css_list, css_sle) { - if (!e_remove_found && (e == connsm)) { - e_remove_found = true; - e_remove = e_last; - } - if (!e_insert_found && (e->css_slot_idx > connsm->css_slot_idx)) { - e_insert_found = true; - e_insert = e_last; + if (SLIST_FIRST(&g_ble_ll_conn_css_list) == connsm) { + SLIST_REMOVE_HEAD(&g_ble_ll_conn_css_list, css_sle); + } else { + e_last = NULL; + SLIST_FOREACH(e, &g_ble_ll_conn_css_list, css_sle) { + if (e == connsm) { + SLIST_NEXT(e_last, css_sle) = SLIST_NEXT(e, css_sle); + break; + } + e_last = e; } + } - if (e_insert_found && e_remove_found) { + if (SLIST_EMPTY(&g_ble_ll_conn_css_list)) { + SLIST_INSERT_HEAD(&g_ble_ll_conn_css_list, connsm, css_sle); + return; + } + + e_last = NULL; + SLIST_FOREACH(e, &g_ble_ll_conn_css_list, css_sle) { + if (e->css_slot_idx > connsm->css_slot_idx) { + found_to_insert = true; + e_insert_after = e_last; break; } e_last = e; } - if (e_remove_found) { - if (e_remove == e_insert) { - return; - } else if (e_remove) { - SLIST_NEXT(e_remove, css_sle) = SLIST_NEXT(connsm, css_sle); + if (found_to_insert) { + if (e_insert_after) { + SLIST_INSERT_AFTER(e_last, connsm, css_sle); } else { - SLIST_REMOVE_HEAD(&g_ble_ll_conn_css_list, css_sle); + SLIST_INSERT_HEAD(&g_ble_ll_conn_css_list, connsm, css_sle); } - } - - if (!e_insert_found && !e && e_last) { - SLIST_INSERT_AFTER(e_last, connsm, css_sle); - } else if (e_insert) { - SLIST_INSERT_AFTER(e_insert, connsm, css_sle); } else { - SLIST_INSERT_HEAD(&g_ble_ll_conn_css_list, connsm, css_sle); + SLIST_INSERT_AFTER(e_last, connsm, css_sle); } } From 623244488010cc98b09bfb765c4913bba812c45a Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 30 Nov 2022 16:17:28 +0100 Subject: [PATCH 0601/1333] nimble/phy/nrf5x: Implement NRF5340 errata 158 Trim values shall be loaded after if toggling power. --- nimble/drivers/nrf5x/src/ble_phy.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 9e6316d2a8..c941cde7a6 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -1520,6 +1520,12 @@ ble_phy_init(void) nrf_radio_power_set(NRF_RADIO, true); #ifdef NRF53_SERIES + /* Errata 158: load trim values after toggling power */ + for (uint32_t index = 0; index < 32ul && + NRF_FICR_NS->TRIMCNF[index].ADDR != (uint32_t *)0xFFFFFFFFul; index++) { + *((volatile uint32_t *)NRF_FICR_NS->TRIMCNF[index].ADDR) = NRF_FICR_NS->TRIMCNF[index].DATA; + } + *(volatile uint32_t *)(NRF_RADIO_NS_BASE + 0x774) = (*(volatile uint32_t* )(NRF_RADIO_NS_BASE + 0x774) & 0xfffffffe) | 0x01000000; #if NRF53_ERRATA_16_ENABLE_WORKAROUND From 37290c6e091d18e72b104a2b1b6660d9644dee5d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 30 Nov 2022 16:22:43 +0100 Subject: [PATCH 0602/1333] nimble/ll: Simplify DTM RX test DTM test uses fixed frequency and PHY mode so there is no need to re-configure those after every packet reception. It is enough to just restart scanning. --- nimble/controller/src/ble_ll_dtm.c | 42 +++--------------------------- 1 file changed, 4 insertions(+), 38 deletions(-) diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index 9bf49e04ff..b1e4f6f0a6 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -195,16 +195,6 @@ ble_ll_dtm_ev_tx_resched_cb(struct ble_npl_event *evt) { BLE_LL_ASSERT(rc == 0); } -static int ble_ll_dtm_rx_start(void); - -static void -ble_ll_dtm_ev_rx_restart_cb(struct ble_npl_event *evt) { - if (ble_ll_dtm_rx_start() != 0) { - ble_ll_event_add(&g_ble_ll_dtm_ctx.evt); - STATS_INC(ble_ll_dtm_stats, rx_failed); - } -} - static void ble_ll_dtm_tx_done(void *arg) { @@ -402,7 +392,7 @@ ble_ll_dtm_rx_start(void) #endif OS_ENTER_CRITICAL(sr); - rc = ble_phy_rx_set_start_time(ble_ll_tmr_get(), 0); + rc = ble_phy_rx_set_start_time(ble_ll_rfmgmt_enable_now(), 0); OS_EXIT_CRITICAL(sr); if (rc && rc != BLE_PHY_ERR_RX_LATE) { return rc; @@ -413,22 +403,9 @@ ble_ll_dtm_rx_start(void) return 0; } -static int -ble_ll_dtm_rx_sched_cb(struct ble_ll_sched_item *sch) -{ - if (ble_ll_dtm_rx_start() != 0) { - ble_ll_event_add(&g_ble_ll_dtm_ctx.evt); - STATS_INC(ble_ll_dtm_stats, rx_failed); - return BLE_LL_SCHED_STATE_DONE; - } - - return BLE_LL_SCHED_STATE_RUNNING; -} - static int ble_ll_dtm_rx_create_ctx(uint8_t rf_channel, uint8_t phy_mode) { - struct ble_ll_sched_item *sch = &g_ble_ll_dtm_ctx.sch; int rc; g_ble_ll_dtm_ctx.phy_mode = phy_mode; @@ -436,16 +413,8 @@ ble_ll_dtm_rx_create_ctx(uint8_t rf_channel, uint8_t phy_mode) STATS_CLEAR(ble_ll_dtm_stats, rx_count); - ble_npl_event_init(&g_ble_ll_dtm_ctx.evt, ble_ll_dtm_ev_rx_restart_cb, - NULL); - - sch->sched_cb = ble_ll_dtm_rx_sched_cb; - sch->cb_arg = &g_ble_ll_dtm_ctx; - sch->sched_type = BLE_LL_SCHED_TYPE_DTM; - sch->start_time = ble_ll_rfmgmt_enable_now(); - - rc = ble_ll_sched_dtm(sch); - BLE_LL_ASSERT(rc == 0); + rc = ble_ll_dtm_rx_start(); + assert(rc == 0); ble_phy_enable_dtm(); @@ -665,10 +634,7 @@ ble_ll_dtm_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) STATS_INC(ble_ll_dtm_stats, rx_count); } - if (ble_ll_dtm_rx_start() != 0) { - ble_ll_event_add(&g_ble_ll_dtm_ctx.evt); - STATS_INC(ble_ll_dtm_stats, rx_failed); - } + ble_phy_restart_rx(); } int From eddc008fa54741b047408a7d316529cf272950e1 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 9 Dec 2022 13:29:29 +0100 Subject: [PATCH 0603/1333] porting/examples: Fix build error on linux Since 'using namespace std' was removed from public header it is needed to explicitly use it when using std::list --- porting/npl/linux/src/wqueue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porting/npl/linux/src/wqueue.h b/porting/npl/linux/src/wqueue.h index d9a7b6cc42..61540562e1 100644 --- a/porting/npl/linux/src/wqueue.h +++ b/porting/npl/linux/src/wqueue.h @@ -27,7 +27,7 @@ template class wqueue { - list m_queue; + std::list m_queue; pthread_mutex_t m_mutex; pthread_mutexattr_t m_mutex_attr; pthread_cond_t m_condv; From 2587fbfd8b12d07bdc66ad8a3d1ed857ca07bb9e Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 9 Dec 2022 17:04:49 +0100 Subject: [PATCH 0604/1333] nimble/mesh: Fix build on linux Use MIN/MAX macros instead of min/max. --- nimble/host/mesh/src/adv_legacy.c | 2 +- nimble/host/mesh/src/cfg_cli.c | 2 +- nimble/host/mesh/src/cfg_srv.c | 2 +- nimble/host/mesh/src/glue.c | 2 +- nimble/host/mesh/src/lpn.c | 8 ++++---- nimble/host/mesh/src/proxy_srv.c | 4 ++-- nimble/host/mesh/src/transport.c | 2 +- porting/examples/linux_blemesh/ble.c | 4 ++-- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index e495dd614c..b642e1aaec 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -61,7 +61,7 @@ static inline void adv_send(struct os_mbuf *buf) struct bt_data ad; int err; - adv_int = max(adv_int_min, + adv_int = MAX(adv_int_min, BT_MESH_TRANSMIT_INT(BT_MESH_ADV(buf)->xmit)); #if MYNEWT_VAL(BLE_CONTROLLER) duration = ((BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1) * diff --git a/nimble/host/mesh/src/cfg_cli.c b/nimble/host/mesh/src/cfg_cli.c index 773bafa709..2a68b40a12 100644 --- a/nimble/host/mesh/src/cfg_cli.c +++ b/nimble/host/mesh/src/cfg_cli.c @@ -52,7 +52,7 @@ static int comp_data_status(struct bt_mesh_model *model, if (param->page) { *(param->page) = net_buf_simple_pull_u8(buf); } - to_copy = min(net_buf_simple_tailroom(param->comp), buf->om_len); + to_copy = MIN(net_buf_simple_tailroom(param->comp), buf->om_len); net_buf_simple_add_mem(param->comp, buf->om_data, to_copy); bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); diff --git a/nimble/host/mesh/src/cfg_srv.c b/nimble/host/mesh/src/cfg_srv.c index 2af24370e3..cdbd0400ca 100644 --- a/nimble/host/mesh/src/cfg_srv.c +++ b/nimble/host/mesh/src/cfg_srv.c @@ -2042,7 +2042,7 @@ static int mod_app_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf) { - struct os_mbuf *msg = NET_BUF_SIMPLE(max(BT_MESH_MODEL_BUF_LEN(OP_VND_MOD_APP_LIST, + struct os_mbuf *msg = NET_BUF_SIMPLE(MAX(BT_MESH_MODEL_BUF_LEN(OP_VND_MOD_APP_LIST, 9 + KEY_LIST_LEN), BT_MESH_MODEL_BUF_LEN(OP_SIG_MOD_APP_LIST, 9 + KEY_LIST_LEN))); diff --git a/nimble/host/mesh/src/glue.c b/nimble/host/mesh/src/glue.c index f6f57f0598..bcacf833c6 100644 --- a/nimble/host/mesh/src/glue.c +++ b/nimble/host/mesh/src/glue.c @@ -53,7 +53,7 @@ bt_hex(const void *buf, size_t len) str = hexbufs[curbuf++]; curbuf %= ARRAY_SIZE(hexbufs); - len = min(len, (sizeof(hexbufs[0]) - 1) / 2); + len = MIN(len, (sizeof(hexbufs[0]) - 1) / 2); for (i = 0; i < len; i++) { str[i * 2] = hex[b[i] >> 4]; diff --git a/nimble/host/mesh/src/lpn.c b/nimble/host/mesh/src/lpn.c index 1d2f229e6b..6e164c1352 100644 --- a/nimble/host/mesh/src/lpn.c +++ b/nimble/host/mesh/src/lpn.c @@ -32,7 +32,7 @@ #endif #define LPN_RECV_DELAY MYNEWT_VAL(BLE_MESH_LPN_RECV_DELAY) -#define SCAN_LATENCY min(MYNEWT_VAL(BLE_MESH_LPN_SCAN_LATENCY), \ +#define SCAN_LATENCY MIN(MYNEWT_VAL(BLE_MESH_LPN_SCAN_LATENCY), \ LPN_RECV_DELAY) #define FRIEND_REQ_RETRY_TIMEOUT K_SECONDS(MYNEWT_VAL(BLE_MESH_LPN_RETRY_TIMEOUT)) @@ -152,12 +152,12 @@ static int32_t poll_timeout(struct bt_mesh_lpn *lpn) { /* If we're waiting for segment acks keep polling at high freq */ if (bt_mesh_tx_in_progress()) { - return min(POLL_TIMEOUT_MAX(lpn), K_SECONDS(1)); + return MIN(POLL_TIMEOUT_MAX(lpn), K_SECONDS(1)); } if (lpn->poll_timeout < POLL_TIMEOUT_MAX(lpn)) { lpn->poll_timeout *= 2; - lpn->poll_timeout = min(lpn->poll_timeout, + lpn->poll_timeout = MIN(lpn->poll_timeout, POLL_TIMEOUT_MAX(lpn)); } @@ -1000,7 +1000,7 @@ int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx, } /* Set initial poll timeout */ - lpn->poll_timeout = min(POLL_TIMEOUT_MAX(lpn), + lpn->poll_timeout = MIN(POLL_TIMEOUT_MAX(lpn), POLL_TIMEOUT_INIT); } diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index 65a5af78dd..91c87e50fc 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -581,8 +581,8 @@ static int gatt_proxy_advertise(struct bt_mesh_subnet *sub) * 6 slices, but make sure that a slice is at least one * second long (to avoid excessive rotation). */ - max_timeout = NODE_ID_TIMEOUT / max(subnet_count, 6); - max_timeout = max(max_timeout, K_SECONDS(1)); + max_timeout = NODE_ID_TIMEOUT / MAX(subnet_count, 6); + max_timeout = MAX(max_timeout, K_SECONDS(1)); if (remaining > max_timeout || remaining < 0) { remaining = max_timeout; diff --git a/nimble/host/mesh/src/transport.c b/nimble/host/mesh/src/transport.c index d563c9fa05..b3c9d52395 100644 --- a/nimble/host/mesh/src/transport.c +++ b/nimble/host/mesh/src/transport.c @@ -1008,7 +1008,7 @@ static inline int32_t ack_timeout(struct seg_rx *rx) /* Make sure we don't send more frequently than the duration for * each packet (default is 300ms). */ - return max(to, K_MSEC(400)); + return MAX(to, K_MSEC(400)); } int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, uint8_t ctl_op, void *data, diff --git a/porting/examples/linux_blemesh/ble.c b/porting/examples/linux_blemesh/ble.c index 7a64eac9ea..277481d21c 100644 --- a/porting/examples/linux_blemesh/ble.c +++ b/porting/examples/linux_blemesh/ble.c @@ -54,7 +54,7 @@ fault_get_cur(struct bt_mesh_model *model, *test_id = recent_test_id; *company_id = CID_VENDOR; - *fault_count = min(*fault_count, sizeof(reg_faults)); + *fault_count = MIN(*fault_count, sizeof(reg_faults)); memcpy(faults, reg_faults, *fault_count); return 0; @@ -78,7 +78,7 @@ fault_get_reg(struct bt_mesh_model *model, if (has_reg_fault) { uint8_t reg_faults[FAULT_ARR_SIZE] = { [0 ... FAULT_ARR_SIZE-1] = 0xff }; - *fault_count = min(*fault_count, sizeof(reg_faults)); + *fault_count = MIN(*fault_count, sizeof(reg_faults)); memcpy(faults, reg_faults, *fault_count); } else { *fault_count = 0; From 58a71bad16b6cbc8514bdbe77699c3492484b6be Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 9 Dec 2022 17:06:15 +0100 Subject: [PATCH 0605/1333] portling/linux: Fix build on latest Fedora This leads to implicit include of unistd.h which provides link symbol that collide with mesh internal symbols. If needed c files may include it directly. --- porting/npl/linux/include/nimble/os_types.h | 1 - 1 file changed, 1 deletion(-) diff --git a/porting/npl/linux/include/nimble/os_types.h b/porting/npl/linux/include/nimble/os_types.h index a5d8bf5486..aa24745f5f 100644 --- a/porting/npl/linux/include/nimble/os_types.h +++ b/porting/npl/linux/include/nimble/os_types.h @@ -21,7 +21,6 @@ #define _NPL_OS_TYPES_H #include -#include #include #include #include From 2de047cbbcf0d8d0f204274e75b432e60015c879 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 8 Dec 2022 14:35:33 +0100 Subject: [PATCH 0606/1333] nimble/fem: Add runtime default antenna selection to SKY66112 This allows to configure default antenna at runtime. --- .../fem/sky66112/include/sky66112/sky66112.h | 5 +++++ nimble/drivers/fem/sky66112/src/sky66112.c | 22 ++++++++++++++++--- nimble/drivers/fem/sky66112/syscfg.yml | 13 ++++++----- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/nimble/drivers/fem/sky66112/include/sky66112/sky66112.h b/nimble/drivers/fem/sky66112/include/sky66112/sky66112.h index 6bdf59f74a..4b995b616a 100644 --- a/nimble/drivers/fem/sky66112/include/sky66112/sky66112.h +++ b/nimble/drivers/fem/sky66112/include/sky66112/sky66112.h @@ -30,6 +30,11 @@ extern "C" { void sky66112_tx_hp_mode(uint8_t enabled); void sky66112_rx_bypass(uint8_t enabled); void sky66112_tx_bypass(uint8_t enabled); + +#if MYNEWT_VAL_CHOICE(SKY66112_ANTENNA_PORT, runtime) +uint8_t sky66112_default_antenna_get(void); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/drivers/fem/sky66112/src/sky66112.c b/nimble/drivers/fem/sky66112/src/sky66112.c index c9760171ef..615055c75b 100644 --- a/nimble/drivers/fem/sky66112/src/sky66112.c +++ b/nimble/drivers/fem/sky66112/src/sky66112.c @@ -31,6 +31,18 @@ static struct { .tx_bypass = MYNEWT_VAL(SKY66112_TX_BYPASS), }; +#if !MYNEWT_VAL_CHOICE(SKY66112_ANTENNA_PORT, runtime) +static uint8_t +sky66112_default_antenna_get(void) +{ + if (MYNEWT_VAL_CHOICE(SKY66112_ANTENNA_PORT, ANT2)) { + return 2; + } else { + return 1; + } +} +#endif + static void sky66112_bypass(uint8_t enabled) { @@ -46,7 +58,7 @@ ble_fem_pa_init(void) sky66112_tx_hp_mode(MYNEWT_VAL(SKY66112_TX_HP_MODE)); sky66112_tx_bypass(0); #if MYNEWT_VAL(BLE_FEM_ANTENNA) - ble_fem_antenna(MYNEWT_VAL(SKY66112_ANTENNA_PORT)); + ble_fem_antenna(0); #endif } @@ -71,7 +83,7 @@ ble_fem_lna_init(void) { sky66112_rx_bypass(0); #if MYNEWT_VAL(BLE_FEM_ANTENNA) - ble_fem_antenna(MYNEWT_VAL(SKY66112_ANTENNA_PORT)); + ble_fem_antenna(0); #endif } @@ -105,10 +117,14 @@ int ble_fem_antenna(uint8_t port) { int pin = MYNEWT_VAL(SKY66112_PIN_SEL); + uint8_t ant; if (pin >= 0) { switch (port) { case 0: + ant = sky66112_default_antenna_get(); + assert(ant == 1 || ant == 2); + return ble_fem_antenna(ant); case 1: hal_gpio_write(pin, 0); break; @@ -171,7 +187,7 @@ sky66112_init(void) /* configure default antenna */ pin = MYNEWT_VAL(SKY66112_PIN_SEL); if (pin >= 0) { - switch (MYNEWT_VAL(SKY66112_ANTENNA_PORT)) { + switch (sky66112_default_antenna_get()) { case 1: hal_gpio_init_out(pin, 0); break; diff --git a/nimble/drivers/fem/sky66112/syscfg.yml b/nimble/drivers/fem/sky66112/syscfg.yml index d946831f05..120fd4e519 100644 --- a/nimble/drivers/fem/sky66112/syscfg.yml +++ b/nimble/drivers/fem/sky66112/syscfg.yml @@ -58,11 +58,14 @@ syscfg.defs: value: 0 SKY66112_ANTENNA_PORT: description: > - Selects which antenna port should be enabled: - 1 for ANT1 port enabled - 2 for ANT2 port enabled - range: 1, 2 - value: 1 + Selects which antenna port should be enabled. If 'runtime' is + selected sky66112_default_antenna_get() (see sky66112/sky66112.h) + shall be implemeneted by application. + choices: + - ANT1 + - ANT2 + - runtime + value: ANT1 syscfg.vals.!BLE_FEM_PA: # Enable TX bypass by default if PA is disabled From 9f99d55e64d492057425b455810b465dca8efd5b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 25 Nov 2022 13:56:23 +0100 Subject: [PATCH 0607/1333] nimble/drivers/fem: Add support for nRF21540 This adds support for nRF21540 FEM. FEM is controlled via GPIOs, there's no support for SPI. --- .../fem/nrf21540/include/nrf21540/nrf21540.h | 36 +++++ nimble/drivers/fem/nrf21540/pkg.yml | 30 ++++ nimble/drivers/fem/nrf21540/src/nrf21540.c | 143 ++++++++++++++++++ nimble/drivers/fem/nrf21540/syscfg.yml | 45 ++++++ 4 files changed, 254 insertions(+) create mode 100644 nimble/drivers/fem/nrf21540/include/nrf21540/nrf21540.h create mode 100644 nimble/drivers/fem/nrf21540/pkg.yml create mode 100644 nimble/drivers/fem/nrf21540/src/nrf21540.c create mode 100644 nimble/drivers/fem/nrf21540/syscfg.yml diff --git a/nimble/drivers/fem/nrf21540/include/nrf21540/nrf21540.h b/nimble/drivers/fem/nrf21540/include/nrf21540/nrf21540.h new file mode 100644 index 0000000000..54efc854ad --- /dev/null +++ b/nimble/drivers/fem/nrf21540/include/nrf21540/nrf21540.h @@ -0,0 +1,36 @@ +/* + * 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 _NRF21540_H +#define _NRF21540_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int nrf21540_mode_set(uint8_t mode); + +#ifdef __cplusplus +} +#endif + +#endif /* _NRF21540_H */ diff --git a/nimble/drivers/fem/nrf21540/pkg.yml b/nimble/drivers/fem/nrf21540/pkg.yml new file mode 100644 index 0000000000..c6dd5f55ea --- /dev/null +++ b/nimble/drivers/fem/nrf21540/pkg.yml @@ -0,0 +1,30 @@ +# +# 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: nimble/drivers/fem/nrf21540 +pkg.description: Driver for nRF21540 front-end module +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" +pkg.apis: + - ble_fem_pa + - ble_fem_lna + - ble_fem_antenna + +pkg.init: + nrf21540_init: 999 diff --git a/nimble/drivers/fem/nrf21540/src/nrf21540.c b/nimble/drivers/fem/nrf21540/src/nrf21540.c new file mode 100644 index 0000000000..b70a66e769 --- /dev/null +++ b/nimble/drivers/fem/nrf21540/src/nrf21540.c @@ -0,0 +1,143 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include + +static void +nrf21540_pdn_set(int state) +{ + int pin; + + pin = MYNEWT_VAL(NRF21540_PIN_PDN); + hal_gpio_write(pin, state); +} + +int +nrf21540_mode_set(uint8_t mode) +{ +#ifdef MYNEWT_VAL_NRF21540_PIN_MODE + int pin; + + pin = MYNEWT_VAL(NRF21540_PIN_MODE); + hal_gpio_init_out(pin, mode); + + return 0; +#else + return -1; +#endif +} + +void +ble_fem_pa_init(void) +{ + nrf21540_pdn_set(0); +} + +void +ble_fem_pa_enable(void) +{ + nrf21540_pdn_set(1); +} + +void +ble_fem_pa_disable(void) +{ + nrf21540_pdn_set(0); +} + +void +ble_fem_lna_init(void) +{ +} + +void +ble_fem_lna_enable(void) +{ + nrf21540_pdn_set(1); +} + +void +ble_fem_lna_disable(void) +{ + nrf21540_pdn_set(0); +} + +int +ble_fem_antenna(uint8_t port) +{ +#ifdef MYNEWT_VAL_NRF21540_PIN_ANT_SEL + int pin; + + pin = MYNEWT_VAL(NRF21540_PIN_ANT_SEL); + switch (port) { + case 0: + case 1: + hal_gpio_write(pin, 0); + break; + case 2: + hal_gpio_write(pin, 1); + break; + default: + return -1; + } + + return 0; +#else + return -1; +#endif +} + +void +nrf21540_init(void) +{ + int pin; + + pin = MYNEWT_VAL(NRF21540_PIN_PDN); + assert(pin >= 0); + hal_gpio_init_out(pin, 0); + +#ifdef MYNEWT_VAL_NRF21540_PIN_ANT_SEL + pin = MYNEWT_VAL(NRF21540_PIN_ANT_SEL); + assert(pin >= 0); + switch (MYNEWT_VAL(NRF21540_ANTENNA_PORT)) { + case 1: + hal_gpio_init_out(pin, 0); + break; + case 2: + hal_gpio_init_out(pin, 1); + break; + default: + assert(0); + } +#endif + +#ifdef MYNEWT_VAL_NRF21540_PIN_MODE + pin = MYNEWT_VAL(NRF21540_PIN_MODE); + assert(pin >= 0); + if (MYNEWT_VAL_CHOICE(NRF21540_TX_GAIN_PRESET, POUTB)) { + hal_gpio_init_out(pin, 1); + } else { + hal_gpio_init_out(pin, 0); + } +#endif +} diff --git a/nimble/drivers/fem/nrf21540/syscfg.yml b/nimble/drivers/fem/nrf21540/syscfg.yml new file mode 100644 index 0000000000..13e5f17a9e --- /dev/null +++ b/nimble/drivers/fem/nrf21540/syscfg.yml @@ -0,0 +1,45 @@ +# 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. +# + +syscfg.defs: + NRF21540_PIN_PDN: + description: > + GPIO pin number to control PDN signal. + value: + restrictions: $notnull + NRF21540_PIN_ANT_SEL: + description: > + GPIO pin number to control ANT_SEL signal. + value: + NRF21540_PIN_MODE: + description: > + GPIO pin number to control MODE signal. + value: + NRF21540_ANTENNA_PORT: + description: > + Selects antenna port, valid only if ANT_SEL pin is configured. + range: 1, 2 + value: 1 + NRF21540_TX_GAIN_PRESET: + description: > + Selects TX gain preset, valid only if MODE pin is configured. + choices: + - none + - POUTA + - POUTB + value: none From 4e7dcde6f339be027caec6aabea90a0d3d9a0cac Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 28 Nov 2022 14:56:13 +0100 Subject: [PATCH 0608/1333] nimble/phy: Fix nrf5x build with PA or LNA disabled on nRF53 --- nimble/drivers/nrf5x/src/nrf53/phy.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/drivers/nrf5x/src/nrf53/phy.c b/nimble/drivers/nrf5x/src/nrf53/phy.c index 0d9ab1a76e..8310406526 100644 --- a/nimble/drivers/nrf5x/src/nrf53/phy.c +++ b/nimble/drivers/nrf5x/src/nrf53/phy.c @@ -112,6 +112,7 @@ phy_fem_init() NRF_DPPIC->CHENSET = DPPI_CH_MASK_FEM; } +#if PHY_USE_FEM_PA void phy_fem_enable_pa(void) { @@ -125,7 +126,9 @@ phy_fem_enable_pa(void) DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_2); #endif } +#endif +#if PHY_USE_FEM_LNA void phy_fem_enable_lna(void) { @@ -139,6 +142,7 @@ phy_fem_enable_lna(void) DPPI_CH_SUB(TIMER0_EVENTS_COMPARE_2); #endif } +#endif void phy_fem_disable(void) From 62b0fff5812e770f3addaf09a79b90bcf5dd80f7 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Tue, 13 Dec 2022 11:30:46 +0530 Subject: [PATCH 0609/1333] nimble/host: Add helper macros to set interval min / max for perdiodic adv --- nimble/host/include/host/ble_gap.h | 7 ++++--- nimble/host/src/ble_gap.c | 7 +++---- nimble/include/nimble/hci_common.h | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index b132189a07..47a1d5647d 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -44,6 +44,7 @@ struct hci_conn_update; #define BLE_GAP_SCAN_WIN_MS(t) ((t) * 1000 / BLE_HCI_SCAN_ITVL) #define BLE_GAP_CONN_ITVL_MS(t) ((t) * 1000 / BLE_HCI_CONN_ITVL) #define BLE_GAP_SUPERVISION_TIMEOUT_MS(t) ((t) / 10) +#define BLE_GAP_PERIODIC_ITVL_MS(t) ((t) * 1000 / BLE_HCI_PERIODIC_ADV_ITVL) /** 30 ms. */ #define BLE_GAP_ADV_FAST_INTERVAL1_MIN BLE_GAP_ADV_ITVL_MS(30) @@ -1458,14 +1459,14 @@ int ble_gap_ext_adv_active(uint8_t instance); /** @brief Periodic advertising parameters */ struct ble_gap_periodic_adv_params { /** If include TX power in advertising PDU */ - unsigned int include_tx_power:1; + unsigned int include_tx_power : 1; - /** Minimum advertising interval in 0.625ms units, if 0 stack use sane + /** Minimum advertising interval in 1.25ms units, if 0 stack use sane * defaults */ uint16_t itvl_min; - /** Maximum advertising interval in 0.625ms units, if 0 stack use sane + /** Maximum advertising interval in 1.25ms units, if 0 stack use sane * defaults */ uint16_t itvl_max; diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index ba1ec7fb09..b6d54bc30c 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -3418,12 +3418,11 @@ ble_gap_periodic_adv_params_tx(uint8_t instance, /* Fill optional fields if application did not specify them. */ if (params->itvl_min == 0 && params->itvl_max == 0) { - /* TODO defines for those */ - cmd.min_itvl = htole16(30 / 1.25); //30 ms - cmd.max_itvl = htole16(60 / 1.25); //150 ms + cmd.min_itvl = BLE_GAP_PERIODIC_ITVL_MS(30); + cmd.max_itvl = BLE_GAP_PERIODIC_ITVL_MS(60); } else { - cmd.min_itvl = htole16( params->itvl_min); + cmd.min_itvl = htole16(params->itvl_min); cmd.max_itvl = htole16(params->itvl_max); } diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 7c5ebe9a00..eadb0b0e6f 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1265,6 +1265,8 @@ struct ble_hci_vs_set_antenna_cp { #define BLE_HCI_ADV_ITVL_DEF (0x800) /* 1.28 seconds */ #define BLE_HCI_ADV_CHANMASK_DEF (0x7) /* all channels */ +#define BLE_HCI_PERIODIC_ADV_ITVL (1250) /* usecs */ + /* Set scan parameters */ #define BLE_HCI_SCAN_TYPE_PASSIVE (0) #define BLE_HCI_SCAN_TYPE_ACTIVE (1) From df80b4c954dcfb01259fa076b2de0f84de9d8528 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 23 Dec 2022 11:35:07 +0100 Subject: [PATCH 0610/1333] nimble/phy/nrf5x: Fix PA for tx-tx transition --- nimble/drivers/nrf5x/src/ble_phy.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index c941cde7a6..0663eba76a 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -1014,7 +1014,7 @@ ble_phy_tx_end_isr(void) uint8_t transition; uint32_t rx_time; uint32_t tx_time; -#if PHY_USE_FEM_LNA +#if PHY_USE_FEM uint32_t fem_time; #endif uint32_t radio_time; @@ -1096,6 +1096,11 @@ ble_phy_tx_end_isr(void) tx_time = NRF_TIMER0->CC[2] + tifs; /* Adjust for delay between EVENT_END and actual TX end time */ tx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; + +#if PHY_USE_FEM_PA + fem_time = tx_time - MYNEWT_VAL(BLE_FEM_PA_TURN_ON_US); +#endif + /* Adjust for delay between EVENT_READY and actual TX start time */ tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; @@ -1104,7 +1109,11 @@ ble_phy_tx_end_isr(void) NRF_TIMER0->EVENTS_COMPARE[0] = 0; phy_ppi_timer0_compare0_to_radio_txen_enable(); - /* TODO handle PA */ +#if PHY_USE_FEM_PA + nrf_timer_cc_set(NRF_TIMER0, 2, fem_time); + NRF_TIMER0->EVENTS_COMPARE[2] = 0; + phy_fem_enable_pa(); +#endif nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) { From b90c5ecafb9a06bb683393e37b259efef1f35045 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 21 Dec 2022 10:43:18 +0100 Subject: [PATCH 0611/1333] nimble/ll: Allow to tune time needed for scheduling next conn event This works by allowing to shorten connection event end time by specified number of us. This value should be tuned only after measuring performance as depends on various factors like build optimisation, cache, clock speed etc. --- nimble/controller/src/ble_ll_conn.c | 2 ++ nimble/controller/syscfg.yml | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 8e327f4112..408e9b8abc 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -939,6 +939,8 @@ ble_ll_conn_get_next_sched_time(struct ble_ll_conn_sm *connsm) rem_us = connsm->anchor_point_usecs; ble_ll_tmr_add_u(&ce_end, &rem_us, connsm->conn_itvl_usecs); + ce_end -= ble_ll_tmr_u2t_up(MYNEWT_VAL(BLE_LL_CONN_EVENT_END_MARGIN)); + if (ble_ll_sched_next_time(&next_sched_time)) { if (LL_TMR_LT(next_sched_time, ce_end)) { ce_end = next_sched_time; diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 38f6379537..3c1dc18bf9 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -537,6 +537,15 @@ syscfg.defs: range: 1..257 value: 32 + BLE_LL_CONN_EVENT_END_MARGIN: + description: > + Extra time needed for scheduling next connection event. Setting this + value results in ending connection event sooner (in microseconds) + which gives more time to schedule next event. This value should be + tuned only after measuring performance as depends on various factors + like build optimisation, cache, clock speed etc. + value: 0 + BLE_LL_STACK_SIZE: description: > This is the stack size for LL task. From 7fde2c7ad135a133c17aeb0cd99d557f8c0cc0f3 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 28 Dec 2022 16:13:29 +0100 Subject: [PATCH 0612/1333] nimble/ll: Fix not being able to get back to default DLE values If new DLE parameters were matching default values DLE update procedure was not started. --- .../controller/include/controller/ble_ll_ctrl.h | 2 +- nimble/controller/src/ble_ll_conn.c | 4 ++-- nimble/controller/src/ble_ll_ctrl.c | 17 ++++++++++------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index 6e7ad13d9f..445ccc4f45 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -333,7 +333,7 @@ void ble_ll_hci_ev_send_adv_set_terminated(uint8_t status, uint8_t adv_handle, int ble_ll_hci_ev_phy_update(struct ble_ll_conn_sm *connsm, uint8_t status); void ble_ll_calc_session_key(struct ble_ll_conn_sm *connsm); void ble_ll_ctrl_phy_update_proc_complete(struct ble_ll_conn_sm *connsm); -void ble_ll_ctrl_initiate_dle(struct ble_ll_conn_sm *connsm); +void ble_ll_ctrl_initiate_dle(struct ble_ll_conn_sm *connsm, bool initial); void ble_ll_hci_ev_send_vs_assert(const char *file, uint32_t line); void ble_ll_hci_ev_send_vs_llcp_trace(uint8_t type, uint16_t handle, uint16_t count, void *pdu, size_t length); diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 408e9b8abc..9b926010c1 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1851,7 +1851,7 @@ ble_ll_conn_set_data_len(struct ble_ll_conn_sm *connsm, } if (init_dle) { - ble_ll_ctrl_initiate_dle(connsm); + ble_ll_ctrl_initiate_dle(connsm, false); } return 0; @@ -2664,7 +2664,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) !ble_ll_conn_rem_feature_check(connsm, BLE_LL_FEAT_LE_CODED_PHY)) { ble_ll_conn_rem_feature_add(connsm, BLE_LL_FEAT_LE_CODED_PHY); connsm->max_rx_time = BLE_LL_CONN_SUPP_TIME_MAX_CODED; - ble_ll_ctrl_initiate_dle(connsm); + ble_ll_ctrl_initiate_dle(connsm, false); } #endif } diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 948eefae32..fe3c05fe2c 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -2081,7 +2081,7 @@ ble_ll_ctrl_rx_conn_update(struct ble_ll_conn_sm *connsm, uint8_t *dptr) } void -ble_ll_ctrl_initiate_dle(struct ble_ll_conn_sm *connsm) +ble_ll_ctrl_initiate_dle(struct ble_ll_conn_sm *connsm, bool initial) { if (!(connsm->conn_features & BLE_LL_FEAT_DATA_LEN_EXT)) { return; @@ -2090,12 +2090,15 @@ ble_ll_ctrl_initiate_dle(struct ble_ll_conn_sm *connsm) /* * Section 4.5.10 Vol 6 PART B. If the max tx/rx time or octets * exceeds the minimum, data length procedure needs to occur + * "at the earliest practical opportunity". */ - if ((connsm->max_tx_octets <= BLE_LL_CONN_SUPP_BYTES_MIN) && - (connsm->max_rx_octets <= BLE_LL_CONN_SUPP_BYTES_MIN) && - (connsm->max_tx_time <= BLE_LL_CONN_SUPP_TIME_MIN) && - (connsm->max_rx_time <= BLE_LL_CONN_SUPP_TIME_MIN)) { - return; + if (initial) { + if ((connsm->max_tx_octets <= BLE_LL_CONN_SUPP_BYTES_MIN) && + (connsm->max_rx_octets <= BLE_LL_CONN_SUPP_BYTES_MIN) && + (connsm->max_tx_time <= BLE_LL_CONN_SUPP_TIME_MIN) && + (connsm->max_rx_time <= BLE_LL_CONN_SUPP_TIME_MIN)) { + return; + } } ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_DATA_LEN_UPD, NULL); @@ -3048,7 +3051,7 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) if (connsm->csmflags.cfbit.pending_initiate_dle) { connsm->csmflags.cfbit.pending_initiate_dle = 0; - ble_ll_ctrl_initiate_dle(connsm); + ble_ll_ctrl_initiate_dle(connsm, true); } return rc; From e7dead61af783631c828824e4e80636828cb6520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Fri, 13 Jan 2023 11:28:46 +0100 Subject: [PATCH 0613/1333] ll: Fix compiler error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixing false possitive compiler error /home/rymek/projects/bletiny_proj/repos/apache-mynewt-nimble/nimble/controller/src/ble_ll_scan.c:456:12: error: array subscript is outside array bounds of 'struct ble_ll_scan_advertisers[0]' [␛]8;;https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Warray-bounds␇-Werror=array-bounds␛]8;;␇] 456 | memcpy(&adv->adv_addr, addr, BLE_DEV_ADDR_LEN); --- nimble/controller/src/ble_ll_scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 7c16dd35b3..b7516e7805 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -442,7 +442,7 @@ ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t txadd, /* XXX: for now, if we dont have room, just leave */ num_advs = g_ble_ll_scan_num_rsp_advs; - if (num_advs == MYNEWT_VAL(BLE_LL_NUM_SCAN_RSP_ADVS)) { + if (num_advs >= MYNEWT_VAL(BLE_LL_NUM_SCAN_RSP_ADVS)) { return; } From baa6b2f0ded5ac737f3778841ae90794e54bd5f2 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 19 Jan 2023 22:16:17 +0100 Subject: [PATCH 0614/1333] Initial Github Action integration This adds: - building all test targets on Linux - runing 'newt test all' - building dummy and Linux ports --- .github/project.yml | 50 +++++++++++++++++ .../targets}/dialog_cmac/pkg.yml | 0 .../targets}/dialog_cmac/syscfg.yml | 0 .../targets}/dialog_cmac/target.yml | 0 .github/targets/native_btshell/pkg.yml | 24 +++++++++ .github/targets/native_btshell/syscfg.yml | 25 +++++++++ .github/targets/native_btshell/target.yml | 23 ++++++++ .../targets/nordic_pca10028_blehci/pkg.yml | 26 +++++++++ .../targets/nordic_pca10028_blehci/syscfg.yml | 25 +++++++++ .../targets/nordic_pca10028_blehci/target.yml | 23 ++++++++ .github/targets/nordic_pca10028_boot/README | 3 ++ .github/targets/nordic_pca10028_boot/pkg.yml | 25 +++++++++ .../targets/nordic_pca10028_boot/syscfg.yml | 25 +++++++++ .../targets/nordic_pca10028_boot/target.yml | 23 ++++++++ .../nordic_pca10028_bt5_blehci/pkg.yml | 25 +++++++++ .../nordic_pca10028_bt5_blehci/syscfg.yml | 21 ++++++++ .../nordic_pca10028_bt5_blehci/target.yml | 23 ++++++++ .../nordic_pca10056-blehci-usb/pkg.yml | 0 .../nordic_pca10056-blehci-usb/syscfg.yml | 0 .../nordic_pca10056-blehci-usb/target.yml | 0 .../nordic_pca10056_advertiser/pkg.yml | 24 +++++++++ .../nordic_pca10056_advertiser/target.yml | 21 ++++++++ .../targets/nordic_pca10056_blecent/pkg.yml | 25 +++++++++ .../nordic_pca10056_blecent/target.yml | 21 ++++++++ .../targets/nordic_pca10056_blecsc/pkg.yml | 25 +++++++++ .../targets/nordic_pca10056_blecsc/target.yml | 21 ++++++++ .../targets/nordic_pca10056_blehci/pkg.yml | 25 +++++++++ .../targets/nordic_pca10056_blehci/target.yml | 21 ++++++++ .../pkg.yml | 25 +++++++++ .../syscfg.yml | 38 +++++++++++++ .../target.yml | 21 ++++++++ .../nordic_pca10056_blehci_no_privacy/pkg.yml | 25 +++++++++ .../syscfg.yml | 22 ++++++++ .../target.yml | 21 ++++++++ .github/targets/nordic_pca10056_blehr/pkg.yml | 25 +++++++++ .../targets/nordic_pca10056_blehr/target.yml | 21 ++++++++ .../targets/nordic_pca10056_blemesh/pkg.yml | 25 +++++++++ .../nordic_pca10056_blemesh/target.yml | 21 ++++++++ .../nordic_pca10056_blemesh_cdb/pkg.yml | 25 +++++++++ .../nordic_pca10056_blemesh_cdb/syscfg.yml | 21 ++++++++ .../nordic_pca10056_blemesh_cdb/target.yml | 21 ++++++++ .../nordic_pca10056_blemesh_ext_adv/pkg.yml | 25 +++++++++ .../syscfg.yml | 22 ++++++++ .../target.yml | 21 ++++++++ .../nordic_pca10056_blemesh_light/pkg.yml | 25 +++++++++ .../nordic_pca10056_blemesh_light/target.yml | 21 ++++++++ .../pkg.yml | 24 +++++++++ .../target.yml | 22 ++++++++ .../pkg.yml | 25 +++++++++ .../target.yml | 22 ++++++++ .../nordic_pca10056_blemesh_shell/pkg.yml | 25 +++++++++ .../nordic_pca10056_blemesh_shell/target.yml | 21 ++++++++ .../nordic_pca10056_blemesh_storage/pkg.yml | 25 +++++++++ .../syscfg.yml | 22 ++++++++ .../target.yml | 21 ++++++++ .../targets/nordic_pca10056_bleprph/pkg.yml | 25 +++++++++ .../nordic_pca10056_bleprph/target.yml | 21 ++++++++ .../nordic_pca10056_bleprph_oic/pkg.yml | 25 +++++++++ .../nordic_pca10056_bleprph_oic/target.yml | 21 ++++++++ .../targets/nordic_pca10056_blesplit/pkg.yml | 25 +++++++++ .../nordic_pca10056_blesplit/target.yml | 21 ++++++++ .../targets/nordic_pca10056_bleuart/pkg.yml | 25 +++++++++ .../nordic_pca10056_bleuart/target.yml | 21 ++++++++ .../targets/nordic_pca10056_btshell/pkg.yml | 25 +++++++++ .../nordic_pca10056_btshell/target.yml | 23 ++++++++ .../nordic_pca10056_btshell_2M/pkg.yml | 24 +++++++++ .../nordic_pca10056_btshell_2M/syscfg.yml | 21 ++++++++ .../nordic_pca10056_btshell_2M/target.yml | 22 ++++++++ .../nordic_pca10056_btshell_2M_coded/pkg.yml | 24 +++++++++ .../syscfg.yml | 22 ++++++++ .../target.yml | 22 ++++++++ .../nordic_pca10056_btshell_all/pkg.yml | 25 +++++++++ .../nordic_pca10056_btshell_all/syscfg.h | 24 +++++++++ .../nordic_pca10056_btshell_all/target.yml | 23 ++++++++ .../nordic_pca10056_btshell_all_v52/pkg.yml | 25 +++++++++ .../nordic_pca10056_btshell_all_v52/syscfg.h | 25 +++++++++ .../target.yml | 23 ++++++++ .../nordic_pca10056_btshell_coded/pkg.yml | 24 +++++++++ .../nordic_pca10056_btshell_coded/syscfg.yml | 21 ++++++++ .../nordic_pca10056_btshell_coded/target.yml | 22 ++++++++ .../nordic_pca10056_btshell_ext_adv/pkg.yml | 24 +++++++++ .../syscfg.yml | 21 ++++++++ .../target.yml | 22 ++++++++ .../pkg.yml | 24 +++++++++ .../syscfg.yml | 22 ++++++++ .../target.yml | 22 ++++++++ .../nordic_pca10056_btshell_sm_legacy/pkg.yml | 24 +++++++++ .../syscfg.yml | 22 ++++++++ .../target.yml | 22 ++++++++ .../nordic_pca10056_btshell_sm_none/pkg.yml | 24 +++++++++ .../syscfg.yml | 22 ++++++++ .../target.yml | 22 ++++++++ .../nordic_pca10056_btshell_sm_sc/pkg.yml | 24 +++++++++ .../nordic_pca10056_btshell_sm_sc/syscfg.yml | 22 ++++++++ .../nordic_pca10056_btshell_sm_sc/target.yml | 22 ++++++++ .../pkg.yml | 24 +++++++++ .../syscfg.yml | 22 ++++++++ .../target.yml | 22 ++++++++ .../pkg.yml | 25 +++++++++ .../syscfg.yml | 21 ++++++++ .../target.yml | 23 ++++++++ .../targets/nordic_pca10056_bttester/pkg.yml | 25 +++++++++ .../nordic_pca10056_bttester/target.yml | 23 ++++++++ .../nordic_pca10056_ext_advertiser/pkg.yml | 25 +++++++++ .../nordic_pca10056_ext_advertiser/target.yml | 23 ++++++++ .../targets/nordic_pca10056_scanner/pkg.yml | 24 +++++++++ .../nordic_pca10056_scanner/target.yml | 21 ++++++++ .../targets/nordic_pca10095_blehci/pkg.yml | 26 +++++++++ .../targets/nordic_pca10095_blehci/syscfg.yml | 38 +++++++++++++ .../targets/nordic_pca10095_blehci/target.yml | 23 ++++++++ .../targets/nordic_pca10095_btshell/pkg.yml | 25 +++++++++ .../nordic_pca10095_btshell/syscfg.yml | 21 ++++++++ .../nordic_pca10095_btshell/target.yml | 23 ++++++++ .../nordic_pca10095_net-blehci/pkg.yml | 0 .../nordic_pca10095_net-blehci/syscfg.yml | 0 .../nordic_pca10095_net-blehci/target.yml | 0 .github/workflows/build_ports.yml | 37 +++++++++++++ .github/workflows/build_targets.yml | 53 +++++++++++++++++++ .github/workflows/newt_test_all.yml | 49 +++++++++++++++++ 119 files changed, 2647 insertions(+) create mode 100644 .github/project.yml rename {targets => .github/targets}/dialog_cmac/pkg.yml (100%) rename {targets => .github/targets}/dialog_cmac/syscfg.yml (100%) rename {targets => .github/targets}/dialog_cmac/target.yml (100%) create mode 100644 .github/targets/native_btshell/pkg.yml create mode 100644 .github/targets/native_btshell/syscfg.yml create mode 100644 .github/targets/native_btshell/target.yml create mode 100644 .github/targets/nordic_pca10028_blehci/pkg.yml create mode 100644 .github/targets/nordic_pca10028_blehci/syscfg.yml create mode 100644 .github/targets/nordic_pca10028_blehci/target.yml create mode 100644 .github/targets/nordic_pca10028_boot/README create mode 100644 .github/targets/nordic_pca10028_boot/pkg.yml create mode 100644 .github/targets/nordic_pca10028_boot/syscfg.yml create mode 100644 .github/targets/nordic_pca10028_boot/target.yml create mode 100644 .github/targets/nordic_pca10028_bt5_blehci/pkg.yml create mode 100644 .github/targets/nordic_pca10028_bt5_blehci/syscfg.yml create mode 100644 .github/targets/nordic_pca10028_bt5_blehci/target.yml rename {targets => .github/targets}/nordic_pca10056-blehci-usb/pkg.yml (100%) rename {targets => .github/targets}/nordic_pca10056-blehci-usb/syscfg.yml (100%) rename {targets => .github/targets}/nordic_pca10056-blehci-usb/target.yml (100%) create mode 100644 .github/targets/nordic_pca10056_advertiser/pkg.yml create mode 100644 .github/targets/nordic_pca10056_advertiser/target.yml create mode 100644 .github/targets/nordic_pca10056_blecent/pkg.yml create mode 100644 .github/targets/nordic_pca10056_blecent/target.yml create mode 100644 .github/targets/nordic_pca10056_blecsc/pkg.yml create mode 100644 .github/targets/nordic_pca10056_blecsc/target.yml create mode 100644 .github/targets/nordic_pca10056_blehci/pkg.yml create mode 100644 .github/targets/nordic_pca10056_blehci/target.yml create mode 100644 .github/targets/nordic_pca10056_blehci_all_enabled/pkg.yml create mode 100644 .github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml create mode 100644 .github/targets/nordic_pca10056_blehci_all_enabled/target.yml create mode 100644 .github/targets/nordic_pca10056_blehci_no_privacy/pkg.yml create mode 100644 .github/targets/nordic_pca10056_blehci_no_privacy/syscfg.yml create mode 100644 .github/targets/nordic_pca10056_blehci_no_privacy/target.yml create mode 100644 .github/targets/nordic_pca10056_blehr/pkg.yml create mode 100644 .github/targets/nordic_pca10056_blehr/target.yml create mode 100644 .github/targets/nordic_pca10056_blemesh/pkg.yml create mode 100644 .github/targets/nordic_pca10056_blemesh/target.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_cdb/pkg.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_cdb/syscfg.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_cdb/target.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_ext_adv/pkg.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_ext_adv/syscfg.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_ext_adv/target.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_light/pkg.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_light/target.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_models_example_1/pkg.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_models_example_1/target.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_models_example_2/pkg.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_models_example_2/target.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_shell/pkg.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_shell/target.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_storage/pkg.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_storage/syscfg.yml create mode 100644 .github/targets/nordic_pca10056_blemesh_storage/target.yml create mode 100644 .github/targets/nordic_pca10056_bleprph/pkg.yml create mode 100644 .github/targets/nordic_pca10056_bleprph/target.yml create mode 100644 .github/targets/nordic_pca10056_bleprph_oic/pkg.yml create mode 100644 .github/targets/nordic_pca10056_bleprph_oic/target.yml create mode 100644 .github/targets/nordic_pca10056_blesplit/pkg.yml create mode 100644 .github/targets/nordic_pca10056_blesplit/target.yml create mode 100644 .github/targets/nordic_pca10056_bleuart/pkg.yml create mode 100644 .github/targets/nordic_pca10056_bleuart/target.yml create mode 100644 .github/targets/nordic_pca10056_btshell/pkg.yml create mode 100644 .github/targets/nordic_pca10056_btshell/target.yml create mode 100644 .github/targets/nordic_pca10056_btshell_2M/pkg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_2M/syscfg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_2M/target.yml create mode 100644 .github/targets/nordic_pca10056_btshell_2M_coded/pkg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_2M_coded/syscfg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_2M_coded/target.yml create mode 100644 .github/targets/nordic_pca10056_btshell_all/pkg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_all/syscfg.h create mode 100644 .github/targets/nordic_pca10056_btshell_all/target.yml create mode 100644 .github/targets/nordic_pca10056_btshell_all_v52/pkg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_all_v52/syscfg.h create mode 100644 .github/targets/nordic_pca10056_btshell_all_v52/target.yml create mode 100644 .github/targets/nordic_pca10056_btshell_coded/pkg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_coded/syscfg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_coded/target.yml create mode 100644 .github/targets/nordic_pca10056_btshell_ext_adv/pkg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_ext_adv/syscfg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_ext_adv/target.yml create mode 100644 .github/targets/nordic_pca10056_btshell_periodic_adv/pkg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_periodic_adv/syscfg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_periodic_adv/target.yml create mode 100644 .github/targets/nordic_pca10056_btshell_sm_legacy/pkg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_sm_legacy/syscfg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_sm_legacy/target.yml create mode 100644 .github/targets/nordic_pca10056_btshell_sm_none/pkg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_sm_none/syscfg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_sm_none/target.yml create mode 100644 .github/targets/nordic_pca10056_btshell_sm_sc/pkg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_sm_sc/syscfg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_sm_sc/target.yml create mode 100644 .github/targets/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_sm_sc_legacy/syscfg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_sm_sc_legacy/target.yml create mode 100644 .github/targets/nordic_pca10056_btshell_xtal_settle_0/pkg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_xtal_settle_0/syscfg.yml create mode 100644 .github/targets/nordic_pca10056_btshell_xtal_settle_0/target.yml create mode 100644 .github/targets/nordic_pca10056_bttester/pkg.yml create mode 100644 .github/targets/nordic_pca10056_bttester/target.yml create mode 100644 .github/targets/nordic_pca10056_ext_advertiser/pkg.yml create mode 100644 .github/targets/nordic_pca10056_ext_advertiser/target.yml create mode 100644 .github/targets/nordic_pca10056_scanner/pkg.yml create mode 100644 .github/targets/nordic_pca10056_scanner/target.yml create mode 100644 .github/targets/nordic_pca10095_blehci/pkg.yml create mode 100644 .github/targets/nordic_pca10095_blehci/syscfg.yml create mode 100644 .github/targets/nordic_pca10095_blehci/target.yml create mode 100644 .github/targets/nordic_pca10095_btshell/pkg.yml create mode 100644 .github/targets/nordic_pca10095_btshell/syscfg.yml create mode 100644 .github/targets/nordic_pca10095_btshell/target.yml rename {targets => .github/targets}/nordic_pca10095_net-blehci/pkg.yml (100%) rename {targets => .github/targets}/nordic_pca10095_net-blehci/syscfg.yml (100%) rename {targets => .github/targets}/nordic_pca10095_net-blehci/target.yml (100%) create mode 100644 .github/workflows/build_ports.yml create mode 100644 .github/workflows/build_targets.yml create mode 100644 .github/workflows/newt_test_all.yml diff --git a/.github/project.yml b/.github/project.yml new file mode 100644 index 0000000000..10eb2dfce2 --- /dev/null +++ b/.github/project.yml @@ -0,0 +1,50 @@ +# +# 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. +# + +project.name: "apache-mynewt-nimble" + +project.repositories: + - apache-mynewt-core + - mcuboot + - apache-mynewt-mcumgr + +repository.apache-mynewt-core: + type: github + vers: 0.0.0 + user: apache + repo: mynewt-core + +repository.mcuboot: + type: github + vers: 0.0.0 + user: mcu-tools + repo: mcuboot + branch: main + +repository.apache-mynewt-mcumgr: + type: github + vers: 0.0.0 + user: apache + repo: mynewt-mcumgr + +repository.tinyusb: + type: github + vers: 0.0.0 + user: hathach + repo: tinyusb diff --git a/targets/dialog_cmac/pkg.yml b/.github/targets/dialog_cmac/pkg.yml similarity index 100% rename from targets/dialog_cmac/pkg.yml rename to .github/targets/dialog_cmac/pkg.yml diff --git a/targets/dialog_cmac/syscfg.yml b/.github/targets/dialog_cmac/syscfg.yml similarity index 100% rename from targets/dialog_cmac/syscfg.yml rename to .github/targets/dialog_cmac/syscfg.yml diff --git a/targets/dialog_cmac/target.yml b/.github/targets/dialog_cmac/target.yml similarity index 100% rename from targets/dialog_cmac/target.yml rename to .github/targets/dialog_cmac/target.yml diff --git a/.github/targets/native_btshell/pkg.yml b/.github/targets/native_btshell/pkg.yml new file mode 100644 index 0000000000..a252525536 --- /dev/null +++ b/.github/targets/native_btshell/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: targets/native_btshell +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/native_btshell/syscfg.yml b/.github/targets/native_btshell/syscfg.yml new file mode 100644 index 0000000000..e3d568e15c --- /dev/null +++ b/.github/targets/native_btshell/syscfg.yml @@ -0,0 +1,25 @@ +# +# 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. +# + +syscfg.vals: + BLE_TRANSPORT_LL: socket + BLE_SOCK_USE_LINUX_BLUE: 1 + BLE_SOCK_LINUX_DEV: 0 + BLE_SOCK_USE_TCP: 0 + diff --git a/.github/targets/native_btshell/target.yml b/.github/targets/native_btshell/target.yml new file mode 100644 index 0000000000..a95cc6072f --- /dev/null +++ b/.github/targets/native_btshell/target.yml @@ -0,0 +1,23 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/native" +target.build_profile: debug + diff --git a/.github/targets/nordic_pca10028_blehci/pkg.yml b/.github/targets/nordic_pca10028_blehci/pkg.yml new file mode 100644 index 0000000000..a1365ea75e --- /dev/null +++ b/.github/targets/nordic_pca10028_blehci/pkg.yml @@ -0,0 +1,26 @@ +# +# 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. +# + +### Package: targets/blehci-nordic_pca10028 +pkg.name: "targets/nordic_pca10028_blehci" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10028_blehci/syscfg.yml b/.github/targets/nordic_pca10028_blehci/syscfg.yml new file mode 100644 index 0000000000..90a965d2af --- /dev/null +++ b/.github/targets/nordic_pca10028_blehci/syscfg.yml @@ -0,0 +1,25 @@ +# +# 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. +# + +syscfg.vals: + BLE_MAX_CONNECTIONS: 4 + + BLE_TRANSPORT_UART_BAUDRATE: 115200 + BLE_TRANSPORT_UART_FLOW_CONTROL: off + BLE_TRANSPORT_ACL_SIZE: 128 diff --git a/.github/targets/nordic_pca10028_blehci/target.yml b/.github/targets/nordic_pca10028_blehci/target.yml new file mode 100644 index 0000000000..fe0f6a6db5 --- /dev/null +++ b/.github/targets/nordic_pca10028_blehci/target.yml @@ -0,0 +1,23 @@ +# +# 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. +# + +### Target: targets/blehci-nordic_pca10028 +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10028" +target.build_profile: "optimized" diff --git a/.github/targets/nordic_pca10028_boot/README b/.github/targets/nordic_pca10028_boot/README new file mode 100644 index 0000000000..d2d1760bbc --- /dev/null +++ b/.github/targets/nordic_pca10028_boot/README @@ -0,0 +1,3 @@ +*** targets/nordic_pca10028_boot +Note: security is disabled in this boot loader target. With security, +the boot loader is just barely too large to fit on the nRF51. diff --git a/.github/targets/nordic_pca10028_boot/pkg.yml b/.github/targets/nordic_pca10028_boot/pkg.yml new file mode 100644 index 0000000000..ab6ff0c919 --- /dev/null +++ b/.github/targets/nordic_pca10028_boot/pkg.yml @@ -0,0 +1,25 @@ +# +# 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. +# + +### Package: targets/nordic_pca10028_boot +pkg.name: "targets/nordic_pca10028_boot" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10028_boot/syscfg.yml b/.github/targets/nordic_pca10028_boot/syscfg.yml new file mode 100644 index 0000000000..7719a48ac2 --- /dev/null +++ b/.github/targets/nordic_pca10028_boot/syscfg.yml @@ -0,0 +1,25 @@ +# +# 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. +# + +syscfg.vals: + BOOTUTIL_SIGN_RSA: 0 + BOOTUTIL_SIGN_ECC: 0 + UART_0: 0 + TIMER_0: 0 + OS_CPUTIME_TIMER_NUM: -1 diff --git a/.github/targets/nordic_pca10028_boot/target.yml b/.github/targets/nordic_pca10028_boot/target.yml new file mode 100644 index 0000000000..0bc319fe0e --- /dev/null +++ b/.github/targets/nordic_pca10028_boot/target.yml @@ -0,0 +1,23 @@ +# +# 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. +# + +### Target: targets/nordic_pca10028_boot +target.app: "@mcuboot/boot/mynewt" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10028" +target.build_profile: "optimized" diff --git a/.github/targets/nordic_pca10028_bt5_blehci/pkg.yml b/.github/targets/nordic_pca10028_bt5_blehci/pkg.yml new file mode 100644 index 0000000000..e7bd2e0761 --- /dev/null +++ b/.github/targets/nordic_pca10028_bt5_blehci/pkg.yml @@ -0,0 +1,25 @@ +# +# 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. +# + +### Package: targets/nordic_pca10028_bt5_blehci +pkg.name: "targets/nordic_pca10028_bt5_blehci" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10028_bt5_blehci/syscfg.yml b/.github/targets/nordic_pca10028_bt5_blehci/syscfg.yml new file mode 100644 index 0000000000..a5526dfeb8 --- /dev/null +++ b/.github/targets/nordic_pca10028_bt5_blehci/syscfg.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +syscfg.vals: + BLE_EXT_ADV: 1 diff --git a/.github/targets/nordic_pca10028_bt5_blehci/target.yml b/.github/targets/nordic_pca10028_bt5_blehci/target.yml new file mode 100644 index 0000000000..48a385b621 --- /dev/null +++ b/.github/targets/nordic_pca10028_bt5_blehci/target.yml @@ -0,0 +1,23 @@ +# +# 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. +# + +### Target: targets/nordic_pca10028_bt5_blehci +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10028" +target.build_profile: "optimized" diff --git a/targets/nordic_pca10056-blehci-usb/pkg.yml b/.github/targets/nordic_pca10056-blehci-usb/pkg.yml similarity index 100% rename from targets/nordic_pca10056-blehci-usb/pkg.yml rename to .github/targets/nordic_pca10056-blehci-usb/pkg.yml diff --git a/targets/nordic_pca10056-blehci-usb/syscfg.yml b/.github/targets/nordic_pca10056-blehci-usb/syscfg.yml similarity index 100% rename from targets/nordic_pca10056-blehci-usb/syscfg.yml rename to .github/targets/nordic_pca10056-blehci-usb/syscfg.yml diff --git a/targets/nordic_pca10056-blehci-usb/target.yml b/.github/targets/nordic_pca10056-blehci-usb/target.yml similarity index 100% rename from targets/nordic_pca10056-blehci-usb/target.yml rename to .github/targets/nordic_pca10056-blehci-usb/target.yml diff --git a/.github/targets/nordic_pca10056_advertiser/pkg.yml b/.github/targets/nordic_pca10056_advertiser/pkg.yml new file mode 100644 index 0000000000..84d0c05b34 --- /dev/null +++ b/.github/targets/nordic_pca10056_advertiser/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: "targets/nordic_pca10056_advertiser" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_advertiser/target.yml b/.github/targets/nordic_pca10056_advertiser/target.yml new file mode 100644 index 0000000000..863751aac8 --- /dev/null +++ b/.github/targets/nordic_pca10056_advertiser/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/advertiser" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_blecent/pkg.yml b/.github/targets/nordic_pca10056_blecent/pkg.yml new file mode 100644 index 0000000000..d47c0544da --- /dev/null +++ b/.github/targets/nordic_pca10056_blecent/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_blecent" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_blecent/target.yml b/.github/targets/nordic_pca10056_blecent/target.yml new file mode 100644 index 0000000000..a2da5bf678 --- /dev/null +++ b/.github/targets/nordic_pca10056_blecent/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blecent" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_blecsc/pkg.yml b/.github/targets/nordic_pca10056_blecsc/pkg.yml new file mode 100644 index 0000000000..f26c7df69a --- /dev/null +++ b/.github/targets/nordic_pca10056_blecsc/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_blecsc" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_blecsc/target.yml b/.github/targets/nordic_pca10056_blecsc/target.yml new file mode 100644 index 0000000000..b665aaf399 --- /dev/null +++ b/.github/targets/nordic_pca10056_blecsc/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blecsc" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_blehci/pkg.yml b/.github/targets/nordic_pca10056_blehci/pkg.yml new file mode 100644 index 0000000000..b66dab9879 --- /dev/null +++ b/.github/targets/nordic_pca10056_blehci/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_blehci" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_blehci/target.yml b/.github/targets/nordic_pca10056_blehci/target.yml new file mode 100644 index 0000000000..103dd2996c --- /dev/null +++ b/.github/targets/nordic_pca10056_blehci/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_blehci_all_enabled/pkg.yml b/.github/targets/nordic_pca10056_blehci_all_enabled/pkg.yml new file mode 100644 index 0000000000..c44ac2824a --- /dev/null +++ b/.github/targets/nordic_pca10056_blehci_all_enabled/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_blehci_all_enabled" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml b/.github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml new file mode 100644 index 0000000000..eace456a5c --- /dev/null +++ b/.github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml @@ -0,0 +1,38 @@ +# +# 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. +# + +syscfg.vals: + BLE_EXT_ADV: 1 + BLE_EXT_ADV_MAX_SIZE: 1650 + BLE_TRANSPORT_UART_BAUDRATE: 1000000 + BLE_TRANSPORT_UART_FLOW_CONTROL: rtscts + BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 + BLE_LL_CFG_FEAT_LL_PRIVACY: 1 + BLE_LL_CONN_INIT_MAX_TX_BYTES: 251 + BLE_LL_DTM: 1 + BLE_MAX_CONNECTIONS: 5 + BLE_MAX_PERIODIC_SYNCS: 5 + BLE_MULTI_ADV_INSTANCES: 6 + BLE_PERIODIC_ADV: 1 + BLE_PHY_DBG_TIME_ADDRESS_END_PIN: 14 + BLE_PHY_DBG_TIME_TXRXEN_READY_PIN: 12 + BLE_PHY_DBG_TIME_WFR_PIN: 16 + BLE_XTAL_SETTLE_TIME: 1500 diff --git a/.github/targets/nordic_pca10056_blehci_all_enabled/target.yml b/.github/targets/nordic_pca10056_blehci_all_enabled/target.yml new file mode 100644 index 0000000000..103dd2996c --- /dev/null +++ b/.github/targets/nordic_pca10056_blehci_all_enabled/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_blehci_no_privacy/pkg.yml b/.github/targets/nordic_pca10056_blehci_no_privacy/pkg.yml new file mode 100644 index 0000000000..539a36409e --- /dev/null +++ b/.github/targets/nordic_pca10056_blehci_no_privacy/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_blehci_no_privacy" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_blehci_no_privacy/syscfg.yml b/.github/targets/nordic_pca10056_blehci_no_privacy/syscfg.yml new file mode 100644 index 0000000000..8d1f9afff8 --- /dev/null +++ b/.github/targets/nordic_pca10056_blehci_no_privacy/syscfg.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +syscfg.vals: + BLE_LL_CFG_FEAT_LL_PRIVACY: 0 + diff --git a/.github/targets/nordic_pca10056_blehci_no_privacy/target.yml b/.github/targets/nordic_pca10056_blehci_no_privacy/target.yml new file mode 100644 index 0000000000..103dd2996c --- /dev/null +++ b/.github/targets/nordic_pca10056_blehci_no_privacy/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_blehr/pkg.yml b/.github/targets/nordic_pca10056_blehr/pkg.yml new file mode 100644 index 0000000000..fd7e6fa90d --- /dev/null +++ b/.github/targets/nordic_pca10056_blehr/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_blehr" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_blehr/target.yml b/.github/targets/nordic_pca10056_blehr/target.yml new file mode 100644 index 0000000000..104b2ea5ae --- /dev/null +++ b/.github/targets/nordic_pca10056_blehr/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blehr" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_blemesh/pkg.yml b/.github/targets/nordic_pca10056_blemesh/pkg.yml new file mode 100644 index 0000000000..b1785b01b5 --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_blemesh" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_blemesh/target.yml b/.github/targets/nordic_pca10056_blemesh/target.yml new file mode 100644 index 0000000000..0146506c39 --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blemesh" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_blemesh_cdb/pkg.yml b/.github/targets/nordic_pca10056_blemesh_cdb/pkg.yml new file mode 100644 index 0000000000..2a85a98817 --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_cdb/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_blemesh_cdb" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_blemesh_cdb/syscfg.yml b/.github/targets/nordic_pca10056_blemesh_cdb/syscfg.yml new file mode 100644 index 0000000000..b17ebb3a18 --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_cdb/syscfg.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +syscfg.vals: + BLE_MESH_CDB: 1 diff --git a/.github/targets/nordic_pca10056_blemesh_cdb/target.yml b/.github/targets/nordic_pca10056_blemesh_cdb/target.yml new file mode 100644 index 0000000000..0146506c39 --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_cdb/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blemesh" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_blemesh_ext_adv/pkg.yml b/.github/targets/nordic_pca10056_blemesh_ext_adv/pkg.yml new file mode 100644 index 0000000000..3fec50f689 --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_ext_adv/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_blemesh_ext_adv" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_blemesh_ext_adv/syscfg.yml b/.github/targets/nordic_pca10056_blemesh_ext_adv/syscfg.yml new file mode 100644 index 0000000000..1bb5ba41ce --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_ext_adv/syscfg.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +syscfg.vals: + BLE_MULTI_ADV_INSTANCES: 1 + BLE_EXT_ADV: 1 diff --git a/.github/targets/nordic_pca10056_blemesh_ext_adv/target.yml b/.github/targets/nordic_pca10056_blemesh_ext_adv/target.yml new file mode 100644 index 0000000000..0146506c39 --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_ext_adv/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blemesh" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_blemesh_light/pkg.yml b/.github/targets/nordic_pca10056_blemesh_light/pkg.yml new file mode 100644 index 0000000000..991cccfd73 --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_light/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_blemesh_light" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_blemesh_light/target.yml b/.github/targets/nordic_pca10056_blemesh_light/target.yml new file mode 100644 index 0000000000..400ed4b6a9 --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_light/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blemesh_light" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_blemesh_models_example_1/pkg.yml b/.github/targets/nordic_pca10056_blemesh_models_example_1/pkg.yml new file mode 100644 index 0000000000..38c54781ae --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_models_example_1/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: "targets/nordic_pca10056_blemesh_models_example_1" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_blemesh_models_example_1/target.yml b/.github/targets/nordic_pca10056_blemesh_models_example_1/target.yml new file mode 100644 index 0000000000..963ea6f087 --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_models_example_1/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blemesh_models_example_1" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_blemesh_models_example_2/pkg.yml b/.github/targets/nordic_pca10056_blemesh_models_example_2/pkg.yml new file mode 100644 index 0000000000..b17b652583 --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_models_example_2/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_blemesh_models_example_2" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_blemesh_models_example_2/target.yml b/.github/targets/nordic_pca10056_blemesh_models_example_2/target.yml new file mode 100644 index 0000000000..9461ceff7e --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_models_example_2/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blemesh_models_example_2" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_blemesh_shell/pkg.yml b/.github/targets/nordic_pca10056_blemesh_shell/pkg.yml new file mode 100644 index 0000000000..4636feb41a --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_shell/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_blemesh_shell" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_blemesh_shell/target.yml b/.github/targets/nordic_pca10056_blemesh_shell/target.yml new file mode 100644 index 0000000000..1236f8cc8e --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_shell/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blemesh_shell" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_blemesh_storage/pkg.yml b/.github/targets/nordic_pca10056_blemesh_storage/pkg.yml new file mode 100644 index 0000000000..ff17acfcc0 --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_storage/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_blemesh_storage" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_blemesh_storage/syscfg.yml b/.github/targets/nordic_pca10056_blemesh_storage/syscfg.yml new file mode 100644 index 0000000000..e64a2655bb --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_storage/syscfg.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +syscfg.vals: + BLE_MESH_SETTINGS: 1 + CONFIG_NFFS: 1 diff --git a/.github/targets/nordic_pca10056_blemesh_storage/target.yml b/.github/targets/nordic_pca10056_blemesh_storage/target.yml new file mode 100644 index 0000000000..0146506c39 --- /dev/null +++ b/.github/targets/nordic_pca10056_blemesh_storage/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blemesh" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_bleprph/pkg.yml b/.github/targets/nordic_pca10056_bleprph/pkg.yml new file mode 100644 index 0000000000..d1e7b95eea --- /dev/null +++ b/.github/targets/nordic_pca10056_bleprph/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_bleprph" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_bleprph/target.yml b/.github/targets/nordic_pca10056_bleprph/target.yml new file mode 100644 index 0000000000..ef3bfacb08 --- /dev/null +++ b/.github/targets/nordic_pca10056_bleprph/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/bleprph" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_bleprph_oic/pkg.yml b/.github/targets/nordic_pca10056_bleprph_oic/pkg.yml new file mode 100644 index 0000000000..aef9c2eb2e --- /dev/null +++ b/.github/targets/nordic_pca10056_bleprph_oic/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_bleprph_oic" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_bleprph_oic/target.yml b/.github/targets/nordic_pca10056_bleprph_oic/target.yml new file mode 100644 index 0000000000..b9e3747fa2 --- /dev/null +++ b/.github/targets/nordic_pca10056_bleprph_oic/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-core/apps/bleprph_oic" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_blesplit/pkg.yml b/.github/targets/nordic_pca10056_blesplit/pkg.yml new file mode 100644 index 0000000000..8781b07ae0 --- /dev/null +++ b/.github/targets/nordic_pca10056_blesplit/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_blesplit" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_blesplit/target.yml b/.github/targets/nordic_pca10056_blesplit/target.yml new file mode 100644 index 0000000000..402d56434d --- /dev/null +++ b/.github/targets/nordic_pca10056_blesplit/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-core/apps/blesplit" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_bleuart/pkg.yml b/.github/targets/nordic_pca10056_bleuart/pkg.yml new file mode 100644 index 0000000000..f3f3ce922d --- /dev/null +++ b/.github/targets/nordic_pca10056_bleuart/pkg.yml @@ -0,0 +1,25 @@ +# +# 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: "targets/nordic_pca10056_bleuart" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10056_bleuart/target.yml b/.github/targets/nordic_pca10056_bleuart/target.yml new file mode 100644 index 0000000000..89b118bdd0 --- /dev/null +++ b/.github/targets/nordic_pca10056_bleuart/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-core/apps/bleuart" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10056_btshell/pkg.yml b/.github/targets/nordic_pca10056_btshell/pkg.yml new file mode 100644 index 0000000000..9049e01390 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell/pkg.yml @@ -0,0 +1,25 @@ +# +# 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. +# + +### Package: targets/nordic_pca10056_btshell +pkg.name: "targets/nordic_pca10056_btshell" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_btshell/target.yml b/.github/targets/nordic_pca10056_btshell/target.yml new file mode 100644 index 0000000000..be48db4ac3 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell/target.yml @@ -0,0 +1,23 @@ +# +# 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. +# + +### Target: targets/nordic_pca10056_btshell +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_btshell_2M/pkg.yml b/.github/targets/nordic_pca10056_btshell_2M/pkg.yml new file mode 100644 index 0000000000..fc2db1d019 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_2M/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: "targets/nordic_pca10056_btshell_2M" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_btshell_2M/syscfg.yml b/.github/targets/nordic_pca10056_btshell_2M/syscfg.yml new file mode 100644 index 0000000000..95d75dedd9 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_2M/syscfg.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +syscfg.vals: + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 diff --git a/.github/targets/nordic_pca10056_btshell_2M/target.yml b/.github/targets/nordic_pca10056_btshell_2M/target.yml new file mode 100644 index 0000000000..396524b428 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_2M/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_btshell_2M_coded/pkg.yml b/.github/targets/nordic_pca10056_btshell_2M_coded/pkg.yml new file mode 100644 index 0000000000..0ddee925fb --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_2M_coded/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: "targets/nordic_pca10056_btshell_2M_coded" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_btshell_2M_coded/syscfg.yml b/.github/targets/nordic_pca10056_btshell_2M_coded/syscfg.yml new file mode 100644 index 0000000000..83359127e5 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_2M_coded/syscfg.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +syscfg.vals: + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 diff --git a/.github/targets/nordic_pca10056_btshell_2M_coded/target.yml b/.github/targets/nordic_pca10056_btshell_2M_coded/target.yml new file mode 100644 index 0000000000..396524b428 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_2M_coded/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_btshell_all/pkg.yml b/.github/targets/nordic_pca10056_btshell_all/pkg.yml new file mode 100644 index 0000000000..2a18f7030d --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_all/pkg.yml @@ -0,0 +1,25 @@ +# +# 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. +# + +### Package: targets/nordic_pca10056_btshell_all +pkg.name: "targets/nordic_pca10056_btshell_all" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_btshell_all/syscfg.h b/.github/targets/nordic_pca10056_btshell_all/syscfg.h new file mode 100644 index 0000000000..1fd335a1e8 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_all/syscfg.h @@ -0,0 +1,24 @@ +BLE_EDDYSTONE: 1 +BLE_EXT_ADV: 1 +BLE_EXT_ADV_MAX_SIZE: 1650 +BLE_HS_DEBUG: 1 +BLE_L2CAP_COC_MAX_NUM: 5 + +BLE_MAX_CONNECTIONS: 5 +BLE_MONITOR_RTT: 1 +BLE_MULTI_ADV_INSTANCES: 5 +BLE_PERIODIC_ADV: 1 +BLE_MAX_PERIODIC_SYNCS: 5 +BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 +BLE_SM_BONDING: 1 +BLE_SM_LEGACY: 1 +BLE_SM_SC: 1 +BLE_STORE_MAX_BONDS: 5 +BLE_VERSION: 51 + +BLE_LL_CFG_FEAT_LE_2M_PHY: 1 +BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 +BLE_LL_CFG_FEAT_LL_PRIVACY: 1 +BLE_LL_CONN_INIT_MAX_TX_BYTES: 251 +BLE_LL_DTM: 1 +BLE_LL_DTM_EXTENSIONS: 1 diff --git a/.github/targets/nordic_pca10056_btshell_all/target.yml b/.github/targets/nordic_pca10056_btshell_all/target.yml new file mode 100644 index 0000000000..8ad43d72b4 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_all/target.yml @@ -0,0 +1,23 @@ +# +# 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. +# + +### Target: targets/nordic_pca10056_btshell_all +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_btshell_all_v52/pkg.yml b/.github/targets/nordic_pca10056_btshell_all_v52/pkg.yml new file mode 100644 index 0000000000..14d5fc6942 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_all_v52/pkg.yml @@ -0,0 +1,25 @@ +# +# 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. +# + +### Package: targets/nordic_pca10056_btshell_all_v52 +pkg.name: "targets/nordic_pca10056_btshell_all_v52" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_btshell_all_v52/syscfg.h b/.github/targets/nordic_pca10056_btshell_all_v52/syscfg.h new file mode 100644 index 0000000000..fc43e89844 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_all_v52/syscfg.h @@ -0,0 +1,25 @@ +BLE_EDDYSTONE: 1 +BLE_EXT_ADV: 1 +BLE_EXT_ADV_MAX_SIZE: 1650 +BLE_HS_DEBUG: 1 +BLE_L2CAP_COC_MAX_NUM: 5 +BLE_L2CAP_ENHANCED_COC: 1 + +BLE_MAX_CONNECTIONS: 5 +BLE_MONITOR_RTT: 1 +BLE_MULTI_ADV_INSTANCES: 5 +BLE_PERIODIC_ADV: 1 +BLE_MAX_PERIODIC_SYNCS: 5 +BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 +BLE_SM_BONDING: 1 +BLE_SM_LEGACY: 1 +BLE_SM_SC: 1 +BLE_STORE_MAX_BONDS: 5 +BLE_VERSION: 52 + +BLE_LL_CFG_FEAT_LE_2M_PHY: 1 +BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 +BLE_LL_CFG_FEAT_LL_PRIVACY: 1 +BLE_LL_CONN_INIT_MAX_TX_BYTES: 251 +BLE_LL_DTM: 1 +BLE_LL_DTM_EXTENSIONS: 1 diff --git a/.github/targets/nordic_pca10056_btshell_all_v52/target.yml b/.github/targets/nordic_pca10056_btshell_all_v52/target.yml new file mode 100644 index 0000000000..85a2ae90db --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_all_v52/target.yml @@ -0,0 +1,23 @@ +# +# 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. +# + +### Target: targets/nordic_pca10056_btshell_all_v52 +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_btshell_coded/pkg.yml b/.github/targets/nordic_pca10056_btshell_coded/pkg.yml new file mode 100644 index 0000000000..c3ec70a308 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_coded/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: "targets/nordic_pca10056_btshell_coded" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_btshell_coded/syscfg.yml b/.github/targets/nordic_pca10056_btshell_coded/syscfg.yml new file mode 100644 index 0000000000..849aad7d0e --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_coded/syscfg.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +syscfg.vals: + BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 diff --git a/.github/targets/nordic_pca10056_btshell_coded/target.yml b/.github/targets/nordic_pca10056_btshell_coded/target.yml new file mode 100644 index 0000000000..396524b428 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_coded/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_btshell_ext_adv/pkg.yml b/.github/targets/nordic_pca10056_btshell_ext_adv/pkg.yml new file mode 100644 index 0000000000..c8cce29975 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_ext_adv/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: "targets/nordic_pca10056_btshell_ext_adv" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_btshell_ext_adv/syscfg.yml b/.github/targets/nordic_pca10056_btshell_ext_adv/syscfg.yml new file mode 100644 index 0000000000..a5526dfeb8 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_ext_adv/syscfg.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +syscfg.vals: + BLE_EXT_ADV: 1 diff --git a/.github/targets/nordic_pca10056_btshell_ext_adv/target.yml b/.github/targets/nordic_pca10056_btshell_ext_adv/target.yml new file mode 100644 index 0000000000..396524b428 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_ext_adv/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_btshell_periodic_adv/pkg.yml b/.github/targets/nordic_pca10056_btshell_periodic_adv/pkg.yml new file mode 100644 index 0000000000..b4f519e241 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_periodic_adv/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: "targets/nordic_pca10056_btshell_periodic_adv" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_btshell_periodic_adv/syscfg.yml b/.github/targets/nordic_pca10056_btshell_periodic_adv/syscfg.yml new file mode 100644 index 0000000000..2f01ccabb3 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_periodic_adv/syscfg.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +syscfg.vals: + BLE_EXT_ADV: 1 + BLE_PERIODIC_ADV: 1 diff --git a/.github/targets/nordic_pca10056_btshell_periodic_adv/target.yml b/.github/targets/nordic_pca10056_btshell_periodic_adv/target.yml new file mode 100644 index 0000000000..396524b428 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_periodic_adv/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_btshell_sm_legacy/pkg.yml b/.github/targets/nordic_pca10056_btshell_sm_legacy/pkg.yml new file mode 100644 index 0000000000..4c3d331ebe --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_sm_legacy/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: "targets/nordic_pca10056_btshell_sm_legacy" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_btshell_sm_legacy/syscfg.yml b/.github/targets/nordic_pca10056_btshell_sm_legacy/syscfg.yml new file mode 100644 index 0000000000..a7789d626f --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_sm_legacy/syscfg.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +syscfg.vals: + BLE_SM_LEGACY: 1 + BLE_SM_SC: 0 diff --git a/.github/targets/nordic_pca10056_btshell_sm_legacy/target.yml b/.github/targets/nordic_pca10056_btshell_sm_legacy/target.yml new file mode 100644 index 0000000000..396524b428 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_sm_legacy/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_btshell_sm_none/pkg.yml b/.github/targets/nordic_pca10056_btshell_sm_none/pkg.yml new file mode 100644 index 0000000000..a8ccee1f45 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_sm_none/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: "targets/nordic_pca10056_btshell_sm_none" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_btshell_sm_none/syscfg.yml b/.github/targets/nordic_pca10056_btshell_sm_none/syscfg.yml new file mode 100644 index 0000000000..9ee2ab8f6d --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_sm_none/syscfg.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +syscfg.vals: + BLE_SM_LEGACY: 0 + BLE_SM_SC: 0 diff --git a/.github/targets/nordic_pca10056_btshell_sm_none/target.yml b/.github/targets/nordic_pca10056_btshell_sm_none/target.yml new file mode 100644 index 0000000000..396524b428 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_sm_none/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_btshell_sm_sc/pkg.yml b/.github/targets/nordic_pca10056_btshell_sm_sc/pkg.yml new file mode 100644 index 0000000000..611096aa36 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_sm_sc/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: "targets/nordic_pca10056_btshell_sm_sc" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_btshell_sm_sc/syscfg.yml b/.github/targets/nordic_pca10056_btshell_sm_sc/syscfg.yml new file mode 100644 index 0000000000..d6b579ceb4 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_sm_sc/syscfg.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +syscfg.vals: + BLE_SM_LEGACY: 0 + BLE_SM_SC: 1 diff --git a/.github/targets/nordic_pca10056_btshell_sm_sc/target.yml b/.github/targets/nordic_pca10056_btshell_sm_sc/target.yml new file mode 100644 index 0000000000..396524b428 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_sm_sc/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml b/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml new file mode 100644 index 0000000000..3983ec0cae --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: "targets/nordic_pca10056_btshell_sm_sc_legacy" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/syscfg.yml b/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/syscfg.yml new file mode 100644 index 0000000000..d62f1f0f1c --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/syscfg.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +syscfg.vals: + BLE_SM_LEGACY: 1 + BLE_SM_SC: 1 diff --git a/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/target.yml b/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/target.yml new file mode 100644 index 0000000000..396524b428 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_btshell_xtal_settle_0/pkg.yml b/.github/targets/nordic_pca10056_btshell_xtal_settle_0/pkg.yml new file mode 100644 index 0000000000..19a580e193 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_xtal_settle_0/pkg.yml @@ -0,0 +1,25 @@ +# +# 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. +# + +### Package: targets/nordic_pca10056_btshell_xtal_settle_0 +pkg.name: "targets/nordic_pca10056_btshell_xtal_settle_0" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_btshell_xtal_settle_0/syscfg.yml b/.github/targets/nordic_pca10056_btshell_xtal_settle_0/syscfg.yml new file mode 100644 index 0000000000..324a679fa4 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_xtal_settle_0/syscfg.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +syscfg.vals: + BLE_XTAL_SETTLE_TIME: 0 diff --git a/.github/targets/nordic_pca10056_btshell_xtal_settle_0/target.yml b/.github/targets/nordic_pca10056_btshell_xtal_settle_0/target.yml new file mode 100644 index 0000000000..988da49e16 --- /dev/null +++ b/.github/targets/nordic_pca10056_btshell_xtal_settle_0/target.yml @@ -0,0 +1,23 @@ +# +# 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. +# + +### Target: targets/nordic_pca10056_btshell_xtal_settle_0 +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_bttester/pkg.yml b/.github/targets/nordic_pca10056_bttester/pkg.yml new file mode 100644 index 0000000000..d50d245c38 --- /dev/null +++ b/.github/targets/nordic_pca10056_bttester/pkg.yml @@ -0,0 +1,25 @@ +# +# 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. +# + +### Package: targets/nordic_pca10056_bttester +pkg.name: "targets/nordic_pca10056_bttester" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_bttester/target.yml b/.github/targets/nordic_pca10056_bttester/target.yml new file mode 100644 index 0000000000..36f8f128a7 --- /dev/null +++ b/.github/targets/nordic_pca10056_bttester/target.yml @@ -0,0 +1,23 @@ +# +# 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. +# + +### Target: targets/nordic_pca10056_bttester +target.app: "@apache-mynewt-nimble/apps/bttester" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_ext_advertiser/pkg.yml b/.github/targets/nordic_pca10056_ext_advertiser/pkg.yml new file mode 100644 index 0000000000..7dee435744 --- /dev/null +++ b/.github/targets/nordic_pca10056_ext_advertiser/pkg.yml @@ -0,0 +1,25 @@ +# +# 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. +# + +### Package: targets/nordic_pca10056_btshell +pkg.name: "targets/nordic_pca10056_ext_advertiser" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_ext_advertiser/target.yml b/.github/targets/nordic_pca10056_ext_advertiser/target.yml new file mode 100644 index 0000000000..6761de7ab9 --- /dev/null +++ b/.github/targets/nordic_pca10056_ext_advertiser/target.yml @@ -0,0 +1,23 @@ +# +# 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. +# + +### Target: targets/nordic_pca10056_btshell +target.app: "@apache-mynewt-nimble/apps/ext_advertiser" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10056_scanner/pkg.yml b/.github/targets/nordic_pca10056_scanner/pkg.yml new file mode 100644 index 0000000000..dfc3c8b015 --- /dev/null +++ b/.github/targets/nordic_pca10056_scanner/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: "targets/nordic_pca10056_scanner" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_scanner/target.yml b/.github/targets/nordic_pca10056_scanner/target.yml new file mode 100644 index 0000000000..904549cb75 --- /dev/null +++ b/.github/targets/nordic_pca10056_scanner/target.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/scanner" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets/nordic_pca10095_blehci/pkg.yml b/.github/targets/nordic_pca10095_blehci/pkg.yml new file mode 100644 index 0000000000..04841c9472 --- /dev/null +++ b/.github/targets/nordic_pca10095_blehci/pkg.yml @@ -0,0 +1,26 @@ +# +# 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. +# + +### Package: targets/blehci-nordic_pca10095 +pkg.name: "targets/nordic_pca10095_blehci" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + diff --git a/.github/targets/nordic_pca10095_blehci/syscfg.yml b/.github/targets/nordic_pca10095_blehci/syscfg.yml new file mode 100644 index 0000000000..3ffe99c7db --- /dev/null +++ b/.github/targets/nordic_pca10095_blehci/syscfg.yml @@ -0,0 +1,38 @@ +# +# 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. +# + +syscfg.vals: + BLE_MAX_CONNECTIONS: 4 + + BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 + BLE_LL_CFG_FEAT_LL_PRIVACY: 1 + BLE_LL_CONN_INIT_MAX_TX_BYTES: 251 + BLE_LL_CONN_INIT_SLOTS: 4 + BLE_LL_DTM: 1 + BLE_LL_DTM_EXTENSIONS: 1 + BLE_LL_VND_EVENT_ON_ASSERT: 1 + BLE_MAX_CONNECTIONS: 5 + BLE_MAX_PERIODIC_SYNCS: 5 + BLE_MULTI_ADV_INSTANCES: 5 + BLE_EXT_ADV: 1 + BLE_PERIODIC_ADV: 1 + BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 + BLE_VERSION: 51 diff --git a/.github/targets/nordic_pca10095_blehci/target.yml b/.github/targets/nordic_pca10095_blehci/target.yml new file mode 100644 index 0000000000..854cd3dab6 --- /dev/null +++ b/.github/targets/nordic_pca10095_blehci/target.yml @@ -0,0 +1,23 @@ +# +# 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. +# + +### Target: targets/blehci-nordic_pca10095 +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10095_net" +target.build_profile: "debug" diff --git a/.github/targets/nordic_pca10095_btshell/pkg.yml b/.github/targets/nordic_pca10095_btshell/pkg.yml new file mode 100644 index 0000000000..cfcc43dfff --- /dev/null +++ b/.github/targets/nordic_pca10095_btshell/pkg.yml @@ -0,0 +1,25 @@ +# +# 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. +# + +### Package: targets/nordic_pca10056_btshell +pkg.name: "targets/nordic_pca10095_btshell" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10095_btshell/syscfg.yml b/.github/targets/nordic_pca10095_btshell/syscfg.yml new file mode 100644 index 0000000000..c37554dcd4 --- /dev/null +++ b/.github/targets/nordic_pca10095_btshell/syscfg.yml @@ -0,0 +1,21 @@ +# +# 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. +# + +syscfg.vals: + BSP_NRF5340_NET_ENABLE: 1 diff --git a/.github/targets/nordic_pca10095_btshell/target.yml b/.github/targets/nordic_pca10095_btshell/target.yml new file mode 100644 index 0000000000..ffbee16b4b --- /dev/null +++ b/.github/targets/nordic_pca10095_btshell/target.yml @@ -0,0 +1,23 @@ +# +# 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. +# + +### Target: targets/nordic_pca10095_btshell +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10095" +target.build_profile: "debug" diff --git a/targets/nordic_pca10095_net-blehci/pkg.yml b/.github/targets/nordic_pca10095_net-blehci/pkg.yml similarity index 100% rename from targets/nordic_pca10095_net-blehci/pkg.yml rename to .github/targets/nordic_pca10095_net-blehci/pkg.yml diff --git a/targets/nordic_pca10095_net-blehci/syscfg.yml b/.github/targets/nordic_pca10095_net-blehci/syscfg.yml similarity index 100% rename from targets/nordic_pca10095_net-blehci/syscfg.yml rename to .github/targets/nordic_pca10095_net-blehci/syscfg.yml diff --git a/targets/nordic_pca10095_net-blehci/target.yml b/.github/targets/nordic_pca10095_net-blehci/target.yml similarity index 100% rename from targets/nordic_pca10095_net-blehci/target.yml rename to .github/targets/nordic_pca10095_net-blehci/target.yml diff --git a/.github/workflows/build_ports.yml b/.github/workflows/build_ports.yml new file mode 100644 index 0000000000..f125399c12 --- /dev/null +++ b/.github/workflows/build_ports.yml @@ -0,0 +1,37 @@ +# +# 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. +# + +name: newt test all + +on: [push, pull_request] + +jobs: + ports: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install -y make ccache gcc-multilib g++-multilib + - name: Build ports + run: | + make -C porting/examples/dummy/ clean all + make -C porting/examples/linux/ clean all + make -C porting/examples/linux_blemesh/ clean all diff --git a/.github/workflows/build_targets.yml b/.github/workflows/build_targets.yml new file mode 100644 index 0000000000..6d4a1e7352 --- /dev/null +++ b/.github/workflows/build_targets.yml @@ -0,0 +1,53 @@ +# +# 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. +# + +name: build all targets + +on: [push, pull_request] + +jobs: + targets: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: '1.16' + - uses: carlosperate/arm-none-eabi-gcc-action@48db4484a55750df7a0ccca63347fcdea6534d78 + with: + release: '12.2.Rel1' + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install -y gcc-multilib + - name: Install newt + run: | + go version + go get mynewt.apache.org/newt/newt@latest + - name: Setup project + run: | + cp .github/project.yml project.yml + mkdir repos + git clone --depth=1 https://github.com/apache/mynewt-core repos/apache-mynewt-core + git clone --depth=1 https://github.com/mcu-tools/mcuboot.git repos/mcuboot + git clone --depth=1 https://github.com/apache/mynewt-mcumgr repos/apache-mynewt-mcumgr + git clone --depth=1 https://github.com/hathach/tinyusb.git repos/tinyusb + ln -s .github/targets ci_targets + - name: Build targets + run: ls ci_targets | xargs -n1 sh -c 'echo "Testing $0"; newt build -q $0' diff --git a/.github/workflows/newt_test_all.yml b/.github/workflows/newt_test_all.yml new file mode 100644 index 0000000000..20ed795771 --- /dev/null +++ b/.github/workflows/newt_test_all.yml @@ -0,0 +1,49 @@ +# +# 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. +# + +name: newt test all + +on: [push, pull_request] + +jobs: + newt_test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: '1.16' + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install -y gcc-multilib + - name: Install newt + run: | + go version + go get mynewt.apache.org/newt/newt@latest + - name: Setup project + run: | + cp .github/project.yml project.yml + mkdir repos + git clone --depth=1 https://github.com/apache/mynewt-core repos/apache-mynewt-core + git clone --depth=1 https://github.com/mcu-tools/mcuboot.git repos/mcuboot + git clone --depth=1 https://github.com/apache/mynewt-mcumgr repos/apache-mynewt-mcumgr + git clone --depth=1 https://github.com/hathach/tinyusb.git repos/tinyusb + - name: newt test all + run: newt test all From 591dc5f7e5b8dbc9691143158b50bf57edf85da0 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 23 Jan 2023 21:17:07 +0100 Subject: [PATCH 0615/1333] ci: Add support for Mac and Windows runners Test builds on non-linux runners. --- .../native_btshell/pkg.yml | 0 .../native_btshell/syscfg.yml | 0 .../native_btshell/target.yml | 0 .github/workflows/build_targets.yml | 20 ++++++++++++++++--- 4 files changed, 17 insertions(+), 3 deletions(-) rename .github/{targets => targets_native}/native_btshell/pkg.yml (100%) rename .github/{targets => targets_native}/native_btshell/syscfg.yml (100%) rename .github/{targets => targets_native}/native_btshell/target.yml (100%) diff --git a/.github/targets/native_btshell/pkg.yml b/.github/targets_native/native_btshell/pkg.yml similarity index 100% rename from .github/targets/native_btshell/pkg.yml rename to .github/targets_native/native_btshell/pkg.yml diff --git a/.github/targets/native_btshell/syscfg.yml b/.github/targets_native/native_btshell/syscfg.yml similarity index 100% rename from .github/targets/native_btshell/syscfg.yml rename to .github/targets_native/native_btshell/syscfg.yml diff --git a/.github/targets/native_btshell/target.yml b/.github/targets_native/native_btshell/target.yml similarity index 100% rename from .github/targets/native_btshell/target.yml rename to .github/targets_native/native_btshell/target.yml diff --git a/.github/workflows/build_targets.yml b/.github/workflows/build_targets.yml index 6d4a1e7352..0040748a09 100644 --- a/.github/workflows/build_targets.yml +++ b/.github/workflows/build_targets.yml @@ -23,7 +23,11 @@ on: [push, pull_request] jobs: targets: - runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 @@ -33,6 +37,7 @@ jobs: with: release: '12.2.Rel1' - name: Install Dependencies + if: matrix.os == 'ubuntu-latest' run: | sudo apt-get update sudo apt-get install -y gcc-multilib @@ -48,6 +53,15 @@ jobs: git clone --depth=1 https://github.com/mcu-tools/mcuboot.git repos/mcuboot git clone --depth=1 https://github.com/apache/mynewt-mcumgr repos/apache-mynewt-mcumgr git clone --depth=1 https://github.com/hathach/tinyusb.git repos/tinyusb - ln -s .github/targets ci_targets - name: Build targets - run: ls ci_targets | xargs -n1 sh -c 'echo "Testing $0"; newt build -q $0' + shell: bash + run: | + cp -r .github/targets ci_targets + ls ci_targets | xargs -n1 sh -c 'echo "Testing $0"; newt build -q $0' + rm -rf ci_targets + - name: Build native targets + if: matrix.os == 'ubuntu-latest' + run: | + cp -r .github/targets_native ci_targets + ls ci_targets | xargs -n1 sh -c 'echo "Testing $0"; newt build -q $0' + rm -rf ci_targets From e5a74c09df3997cca4c1d9c515782e8ff37c8bf9 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 25 Jan 2023 21:33:01 +0100 Subject: [PATCH 0616/1333] ci: Improve jobs naming Make jobs name more user friendly. --- .github/workflows/build_ports.yml | 3 ++- .github/workflows/build_targets.yml | 3 ++- .github/workflows/newt_test_all.yml | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_ports.yml b/.github/workflows/build_ports.yml index f125399c12..0d30d453ff 100644 --- a/.github/workflows/build_ports.yml +++ b/.github/workflows/build_ports.yml @@ -17,12 +17,13 @@ # under the License. # -name: newt test all +name: Build check on: [push, pull_request] jobs: ports: + name: Build ports runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/build_targets.yml b/.github/workflows/build_targets.yml index 0040748a09..16ea8aac63 100644 --- a/.github/workflows/build_targets.yml +++ b/.github/workflows/build_targets.yml @@ -17,12 +17,13 @@ # under the License. # -name: build all targets +name: Build check on: [push, pull_request] jobs: targets: + name: Build all test targets strategy: fail-fast: false matrix: diff --git a/.github/workflows/newt_test_all.yml b/.github/workflows/newt_test_all.yml index 20ed795771..26048d9fd1 100644 --- a/.github/workflows/newt_test_all.yml +++ b/.github/workflows/newt_test_all.yml @@ -17,12 +17,13 @@ # under the License. # -name: newt test all +name: Unit tests on: [push, pull_request] jobs: newt_test: + name: Run newt test all runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 From 8831a5cc1638c416ec5de45582966f2c77e9987d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 25 Jan 2023 17:24:24 +0100 Subject: [PATCH 0617/1333] ci: Add style check Test style in PR changes only --- .github/check_style.py | 133 ++++++++++++++++++++++++++++++ .github/workflows/check_style.yml | 38 +++++++++ uncrustify.cfg | 2 +- 3 files changed, 172 insertions(+), 1 deletion(-) create mode 100755 .github/check_style.py create mode 100644 .github/workflows/check_style.yml diff --git a/.github/check_style.py b/.github/check_style.py new file mode 100755 index 0000000000..047c0f2271 --- /dev/null +++ b/.github/check_style.py @@ -0,0 +1,133 @@ +#!/usr/bin/python + +# +# 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. +# + +import os.path +import re +import subprocess +import tempfile +import sys + +coding_style_url = "https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md" + +def get_lines_range(m: re.Match) -> range: + first = int(m.group(1)) + + if m.group(2) is not None: + last = first + int(m.group(2)) + else: + last = first + 1 + + return range(first, last) + + +def run_cmd(cmd: str) -> list[str]: + out = subprocess.check_output(cmd, text=True, shell=True) + return out.splitlines() + + +def check_file(fname: str, commit: str, upstream: str) -> list[str]: + ret = [] + + diff_lines = set() + for s in run_cmd(f"git diff -U0 {upstream} {commit} -- {fname}"): + m = re.match(r"^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@", s) + if not m: + continue + diff_lines.update(get_lines_range(m)) + + with tempfile.NamedTemporaryFile(suffix=os.path.basename(fname)) as tmpf: + lines = subprocess.check_output(f"git show {commit}:{fname}", + shell=True) + tmpf.write(lines) + + in_chunk = False + + for s in run_cmd(f"uncrustify -q -c uncrustify.cfg -f {tmpf.name} | " + f"diff -u0 -p {tmpf.name} - || true"): + m = re.match(r"^@@ -(\d+)(?:,(\d+))? \+\d+(?:,\d+)? @@", s) + if not m: + if in_chunk: + ret.append(s) + continue + + in_chunk = len(diff_lines & set(get_lines_range(m))) != 0 + + if in_chunk: + ret.append(s) + + return ret + + +def is_ignored(fname: str, ign_dirs: list[str]) -> bool: + if not re.search(r"\.(c|cpp|h|hpp)$", fname): + return True + + for d in ign_dirs: + if fname.startswith(d): + return True + + return False + + +def main() -> bool: + if len(sys.argv) > 1: + commit = sys.argv[1] + else: + commit = "HEAD" + if len(sys.argv) > 2: + upstream = sys.argv[2] + else: + upstream = "origin/master" + + mb = run_cmd(f"git merge-base {upstream} {commit}") + upstream = mb[0] + + has_error = False + + cfg_fname = os.path.join(os.path.dirname(__file__), "../.style_ignored_dirs") + with open(cfg_fname, "r") as x: + ign_dirs = [s.strip() for s in x.readlines() if + s.strip() and not s.startswith("#")] + + files = run_cmd(f"git diff --diff-filter=AM --name-only {upstream} {commit}") + for cfg_fname in files: + if is_ignored(cfg_fname, ign_dirs): + print(f"\033[90m- {cfg_fname}\033[0m") + continue + + diff = check_file(cfg_fname, commit, upstream) + if len(diff) > 0: + print(f"\033[31m! See {coding_style_url} for details.\033[0m") + print() + print(f"\033[31m! {cfg_fname}\033[0m") + print() + print("\n".join(diff)) + print() + has_error = True + else: + print(f"+ {cfg_fname}") + + return not has_error + + +if __name__ == "__main__": + if not main(): + sys.exit(1) diff --git a/.github/workflows/check_style.yml b/.github/workflows/check_style.yml new file mode 100644 index 0000000000..ce713bb4e0 --- /dev/null +++ b/.github/workflows/check_style.yml @@ -0,0 +1,38 @@ +# +# 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. +# + +name: Compliance check + +on: [pull_request] + +jobs: + style_check: + name: Coding style + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install -y uncrustify + - name: check style + run: | + .github/check_style.py diff --git a/uncrustify.cfg b/uncrustify.cfg index 481a62ab05..2bdd2ac531 100644 --- a/uncrustify.cfg +++ b/uncrustify.cfg @@ -678,7 +678,7 @@ sp_try_brace = ignore # ignore/add/remove/force sp_getset_brace = ignore # ignore/add/remove/force # Add or remove space between a variable and '{' for C++ uniform initialization. Default=Add -sp_word_brace = add # ignore/add/remove/force +sp_word_brace_init_lst = add # ignore/add/remove/force # Add or remove space between a variable and '{' for a namespace. Default=Add sp_word_brace_ns = add # ignore/add/remove/force From 439047b37ebfb48e0f825f445e597aff2544eae9 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 27 Jan 2023 16:18:33 +0100 Subject: [PATCH 0618/1333] ci: Remove Travis integration ASF moves away from travis to Github Actions. --- .travis.yml | 156 ---------------------------------------------------- 1 file changed, 156 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index d3dd9742b8..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,156 +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. - -language: go - -dist: bionic - -_addons: &addon_conf - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc-multilib - - gcc-7-multilib - - g++-multilib - -go: - - "1.16" - -git: - depth: false - -matrix: - allow_failures: - - env: - - TEST=BUILD_PORTS - - VM_AMOUNT=1 - - TARGET_SET=1 - include: - # Style checking - - os: linux - language: python - python: - - "3.5" - addons: - apt: - packages: - - "python3-pip" - env: - - TEST=STYLE - - DEBUG=1 - - # newt build - - os: linux - addons: *addon_conf - env: - - TEST=BUILD_TARGETS - - VM_AMOUNT=4 - - TARGET_SET=1 - - os: linux - addons: *addon_conf - env: - - TEST=BUILD_TARGETS - - VM_AMOUNT=4 - - TARGET_SET=2 - - os: linux - addons: *addon_conf - env: - - TEST=BUILD_TARGETS - - VM_AMOUNT=4 - - TARGET_SET=3 - - os: linux - addons: *addon_conf - env: - - TEST=BUILD_TARGETS - - VM_AMOUNT=4 - - TARGET_SET=4 - - # newt test all (Linux) - - os: linux - addons: *addon_conf - env: - - TEST=TEST_ALL - - VM_AMOUNT=2 - - TARGET_SET=1 - - os: linux - addons: *addon_conf - env: - - TEST=TEST_ALL - - VM_AMOUNT=2 - - TARGET_SET=2 - - # ports - - os: linux - addons: *addon_conf - env: - - TEST=BUILD_PORTS - - VM_AMOUNT=1 - - TARGET_SET=1 - - - os: windows - env: - - TEST=BUILD_TARGETS_WINDOWS - - VM_AMOUNT=1 - - TARGET_SET=1 - -before_install: - - printenv - - export GOPATH=$HOME/gopath - - go version - -install: - - git clone https://github.com/JuulLabs-OSS/mynewt-travis-ci $HOME/ci - - chmod +x $HOME/ci/*.sh - - | - if [ "${TEST}" == "STYLE" ]; then - pip3 install requests - else - $HOME/ci/${TRAVIS_OS_NAME}_travis_install.sh - fi - -before_script: - - | - if [ "${TEST}" == "STYLE" ]; then - $HOME/ci/install_uncrustify.sh - else - newt version - gcc --version - if [ "${TEST}" != "TEST_ALL" ]; then arm-none-eabi-gcc --version; fi - cp -R $HOME/ci/mynewt-nimble-project.yml project.yml - mkdir -p targets - cp -R $HOME/ci/mynewt-nimble-targets targets - $HOME/ci/prepare_test.sh $VM_AMOUNT - mkdir -p repos && pushd repos/ - git clone --depth=1 https://github.com/apache/mynewt-core apache-mynewt-core - git clone --depth=1 https://github.com/JuulLabs-OSS/mcuboot mcuboot - git clone --depth=1 https://github.com/apache/mynewt-mcumgr apache-mynewt-mcumgr - popd - fi - -script: - - | - if [ "${TEST}" == "STYLE" ]; then - python3 $HOME/ci/check_style.py - else - $HOME/ci/run_test.sh - fi - -cache: - directories: - - $HOME/TOOLCHAIN - - $HOME/Library/Caches/Homebrew From e72a20a1132fccd6e5d9097ff90f3617a5354133 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 27 Jan 2023 12:42:19 +0100 Subject: [PATCH 0619/1333] nimble: Cleanup ISO HCI commands/events defs This updates names to conform with Core 5.3 and also makes naming consistent for all commands/events. Also removes #ifdefs since we do not need them for HCI defs. --- nimble/controller/src/ble_ll.c | 6 +- nimble/controller/src/ble_ll_hci.c | 2 +- nimble/include/nimble/hci_common.h | 240 ++++++++++++++++------------- 3 files changed, 137 insertions(+), 111 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index d193b09d1c..9b9fc4e0ac 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1484,7 +1484,7 @@ ble_ll_read_supp_features(void) int ble_ll_set_host_feat(const uint8_t *cmdbuf, uint8_t len) { - const struct ble_hci_le_set_host_feat_cp *cmd = (const void *) cmdbuf; + const struct ble_hci_le_set_host_feature_cp *cmd = (const void *) cmdbuf; uint64_t mask; if (len != sizeof(*cmd)) { @@ -1497,7 +1497,7 @@ ble_ll_set_host_feat(const uint8_t *cmdbuf, uint8_t len) } #endif - if ((cmd->bit_num > 0x3F) || (cmd->val > 1)) { + if ((cmd->bit_num > 0x3F) || (cmd->bit_val > 1)) { return BLE_ERR_INV_HCI_CMD_PARMS; } @@ -1506,7 +1506,7 @@ ble_ll_set_host_feat(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_UNSUPPORTED; } - if (cmd->val == 0) { + if (cmd->bit_val == 0) { g_ble_ll_data.ll_supp_features &= ~(mask); } else { g_ble_ll_data.ll_supp_features |= mask; diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index dc95f0de4a..f36563b1c1 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1285,7 +1285,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, break; #endif #if MYNEWT_VAL(BLE_VERSION) >= 52 - case BLE_HCI_OCF_LE_SET_HOST_FEAT: + case BLE_HCI_OCF_LE_SET_HOST_FEATURE: rc = ble_ll_set_host_feat(cmdbuf, len); break; #endif diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index eadb0b0e6f..6c9d40617a 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -835,112 +835,105 @@ struct ble_hci_le_set_default_periodic_sync_transfer_params_cp { #define BLE_HCI_OCF_LE_GENERATE_DHKEY_V2 (0x005E) #define BLE_HCI_OCF_LE_MODIFY_SCA (0x005F) -#if MYNEWT_VAL(BLE_ISO) #define BLE_HCI_OCF_LE_READ_ISO_TX_SYNC (0x0061) struct ble_hci_le_read_iso_tx_sync_cp { uint16_t conn_handle; } __attribute__((packed)); - struct ble_hci_le_read_iso_tx_sync_rp { uint16_t conn_handle; uint16_t packet_seq_num; - uint32_t timestamp; - uint8_t timeoffset[3]; + uint32_t tx_timestamp; + uint8_t time_offset[3]; } __attribute__((packed)); -#define BLE_HCI_LE_SET_CIG_CIS_MAX_NUM (0x1F) -#define BLE_HCI_OCF_LE_SET_CIG_PARAM (0x0062) +#define BLE_HCI_OCF_LE_SET_CIG_PARAMS (0x0062) struct ble_hci_le_cis_params { uint8_t cis_id; - uint16_t max_sdu_mtos; - uint16_t max_sdu_stom; - uint8_t phy_mtos; - uint8_t phy_stom; - uint8_t rnt_mtos; - uint8_t rnt_stom; + uint16_t max_sdu_c_to_p; + uint16_t max_sdu_p_to_c; + uint8_t phy_c_to_p; + uint8_t phy_p_to_c; + uint8_t rnt_c_to_p; + uint8_t rnt_p_to_c; } __attribute__((packed)); - struct ble_hci_le_set_cig_params_cp { uint8_t cig_id; - uint8_t sdu_interval_mtos[3]; - uint8_t sdu_interval_stom[3]; - uint8_t sca; + uint8_t sdu_interval_c_to_p[3]; + uint8_t sdu_interval_p_to_c[3]; + uint8_t worst_sca; uint8_t packing; uint8_t framing; - uint16_t max_latency_mtos; - uint16_t max_latency_stom; - uint8_t cis_cnt; - struct ble_hci_le_cis_params cis_params[0]; + uint16_t max_latency_c_to_p; + uint16_t max_latency_p_to_c; + uint8_t cis_count; + struct ble_hci_le_cis_params cis[0]; } __attribute__((packed)); - struct ble_hci_le_set_cig_params_rp { uint8_t cig_id; - uint8_t cis_cnt; - uint16_t cis_handle[0]; + uint8_t cis_count; + uint16_t conn_handle[0]; } __attribute__((packed)); -#if MYNEWT_VAL(BLE_ISO_TEST) -#define BLE_HCI_OCF_LE_SET_CIG_PARAM_TEST (0x0063) +#define BLE_HCI_OCF_LE_SET_CIG_PARAMS_TEST (0x0063) struct ble_hci_le_cis_params_test { uint8_t cis_id; uint8_t nse; - uint16_t max_sdu_mtos; - uint16_t max_sdu_stom; - uint16_t max_pdu_mtos; - uint16_t max_pdu_stom; - uint8_t phy_mtos; - uint8_t phy_stom; - uint8_t bn_mtos; - uint8_t bn_stom; + uint16_t max_sdu_c_to_p; + uint16_t max_sdu_p_to_c; + uint16_t max_pdu_c_to_p; + uint16_t max_pdu_p_to_c; + uint8_t phy_c_to_p; + uint8_t phy_p_to_c; + uint8_t bn_c_to_p; + uint8_t bn_p_to_c; } __attribute__((packed)); - struct ble_hci_le_set_cig_params_test_cp { uint8_t cig_id; - uint8_t sdu_interval_mtos[3]; - uint8_t sdu_interval_stom[3]; - uint8_t ft_mtos; - uint8_t ft_stom; + uint8_t sdu_interval_c_to_p[3]; + uint8_t sdu_interval_p_to_c[3]; + uint8_t ft_c_to_p; + uint8_t ft_p_to_c; uint16_t iso_interval; - uint8_t sca; + uint8_t worst_sca; uint8_t packing; uint8_t framing; - uint8_t cis_cnt; - struct ble_hci_le_cis_params_test cis_params[0]; + uint8_t cis_count; + struct ble_hci_le_cis_params_test cis[0]; +} __attribute__((packed)); +struct ble_hci_le_set_cig_params_test_rp { + uint8_t cig_id; + uint8_t cis_count; + uint16_t conn_handle[0]; } __attribute__((packed)); -#endif -#define BLE_HCI_LE_CREATE_CIS_MAX_CIS_NUM (0x1F) #define BLE_HCI_OCF_LE_CREATE_CIS (0x0064) struct ble_hci_le_create_cis_params { uint16_t cis_handle; uint16_t conn_handle; } __attribute__((packed)); - struct ble_hci_le_create_cis_cp { - uint8_t cis_cnt; - struct ble_hci_le_create_cis_params params[0]; + uint8_t cis_count; + struct ble_hci_le_create_cis_params cis[0]; } __attribute__((packed)); #define BLE_HCI_OCF_LE_REMOVE_CIG (0x0065) struct ble_hci_le_remove_cig_cp { uint8_t cig_id; } __attribute__((packed)); - struct ble_hci_le_remove_cig_rp { uint8_t cig_id; } __attribute__((packed)); #define BLE_HCI_OCF_LE_ACCEPT_CIS_REQ (0x0066) struct ble_hci_le_accept_cis_request_cp { - uint16_t cis_handle; + uint16_t conn_handle; } __attribute__((packed)); #define BLE_HCI_OCF_LE_REJECT_CIS_REQ (0x0067) struct ble_hci_le_reject_cis_request_cp { - uint16_t cis_handle; + uint16_t conn_handle; uint8_t reason; } __attribute__((packed)); - struct ble_hci_le_reject_cis_request_rp { uint16_t conn_handle; } __attribute__((packed)); @@ -949,11 +942,11 @@ struct ble_hci_le_reject_cis_request_rp { struct ble_hci_le_create_big_cp { uint8_t big_handle; uint8_t adv_handle; - uint8_t bis_cnt; + uint8_t num_bis; uint8_t sdu_interval[3]; uint16_t max_sdu; uint16_t max_transport_latency; - uint8_t rnt; + uint8_t rtn; uint8_t phy; uint8_t packing; uint8_t framing; @@ -961,12 +954,11 @@ struct ble_hci_le_create_big_cp { uint8_t broadcast_code[16]; } __attribute__((packed)); -#if MYNEWT_VAL(BLE_ISO_TEST) #define BLE_HCI_OCF_LE_CREATE_BIG_TEST (0x0069) struct ble_hci_le_create_big_test_cp { uint8_t big_handle; uint8_t adv_handle; - uint8_t bis_cnt; + uint8_t num_bis; uint8_t sdu_interval[3]; uint16_t iso_interval; uint8_t nse; @@ -981,7 +973,6 @@ struct ble_hci_le_create_big_test_cp { uint8_t encryption; uint8_t broadcast_code[16]; } __attribute__((packed)); -#endif #define BLE_HCI_OCF_LE_TERMINATE_BIG (0x006a) struct ble_hci_le_terminate_big_cp { @@ -989,78 +980,113 @@ struct ble_hci_le_terminate_big_cp { uint8_t reason; } __attribute__((packed)); -#define BLE_HCI_LE_BIG_CREATE_SYNC_LEN_MIN (25) #define BLE_HCI_OCF_LE_BIG_CREATE_SYNC (0x006b) struct ble_hci_le_big_create_sync_cp { uint8_t big_handle; uint16_t sync_handle; - uint8_t big_cnt; uint8_t encryption; uint8_t broadcast_code[16]; uint8_t mse; - uint16_t timeout; + uint16_t sync_timeout; + uint8_t num_bis; uint8_t bis[0]; } __attribute__((packed)); #define BLE_HCI_OCF_LE_BIG_TERMINATE_SYNC (0x006c) -struct ble_hci_le_terminate_big_sync_cp { +struct ble_hci_le_big_terminate_sync_cp { + uint8_t big_handle; +} __attribute__((packed)); +struct ble_hci_le_big_terminate_sync_rp { uint8_t big_handle; } __attribute__((packed)); -#endif #define BLE_HCI_OCF_LE_REQ_PEER_SCA (0x006d) struct ble_hci_le_request_peer_sca_cp { uint16_t conn_handle; } __attribute__((packed)); -#if MYNEWT_VAL(BLE_ISO) #define BLE_HCI_OCF_LE_SETUP_ISO_DATA_PATH (0x006e) -struct ble_hci_le_iso_setup_data_path_cp { - uint16_t iso_handle; - uint8_t direction; - uint8_t id; +struct ble_hci_le_setup_iso_data_path_cp { + uint16_t conn_handle; + uint8_t data_path_dir; + uint8_t data_path_id; uint8_t codec_id[5]; uint8_t controller_delay[3]; - uint8_t codec_conf_len; - uint8_t codec_conf[0]; + uint8_t codec_config_len; + uint8_t codec_config[0]; +} __attribute__((packed)); +struct ble_hci_le_setup_iso_data_path_rp { + uint16_t conn_handle; } __attribute__((packed)); -#define BLE_HCI_LE_REMOVE_INPUT_DATA_PATH_BIT (0x01) -#define BLE_HCI_LE_REMOVE_OUTPUT_DATA_PATH_BIT (0x02) #define BLE_HCI_OCF_LE_REMOVE_ISO_DATA_PATH (0x006f) -struct ble_hci_le_iso_remove_data_path_cp { - uint16_t iso_handle; - uint8_t direction; +struct ble_hci_le_remove_iso_data_path_cp { + uint16_t conn_handle; + uint8_t data_path_dir; +} __attribute__((packed)); +struct ble_hci_le_remove_iso_data_path_rp { + uint16_t conn_handle; } __attribute__((packed)); -#if MYNEWT_VAL(BLE_ISO_TEST) #define BLE_HCI_OCF_LE_ISO_TRANSMIT_TEST (0x0070) struct ble_hci_le_iso_transmit_test_cp { - uint16_t iso_handle; + uint16_t conn_handle; uint8_t payload_type; } __attribute__((packed)); +struct ble_hci_le_iso_transmit_test_rp { + uint16_t conn_handle; +} __attribute__((packed)); #define BLE_HCI_OCF_LE_ISO_RECEIVE_TEST (0x0071) struct ble_hci_le_iso_receive_test_cp { - uint16_t iso_handle; + uint16_t conn_handle; + uint8_t payload_type; +} __attribute__((packed)); +struct ble_hci_le_iso_receive_test_rp { + uint16_t conn_handle; } __attribute__((packed)); #define BLE_HCI_OCF_LE_ISO_READ_TEST_COUNTERS (0x0072) struct ble_hci_le_iso_read_test_counters_cp { - uint16_t iso_handle; + uint16_t conn_handle; +} __attribute__((packed)); +struct ble_hci_le_iso_read_test_counters_rp { + uint16_t conn_handle; + uint32_t received_sdu_count; + uint32_t missed_sdu_count; + uint32_t failed_sdu_count; } __attribute__((packed)); #define BLE_HCI_OCF_LE_ISO_TEST_END (0x0073) struct ble_hci_le_iso_test_end_cp { - uint16_t iso_handle; + uint16_t conn_handle; +} __attribute__((packed)); +struct ble_hci_le_iso_test_end_rp { + uint16_t conn_handle; + uint32_t received_sdu_count; + uint32_t missed_sdu_count; + uint32_t failed_sdu_count; } __attribute__((packed)); -#endif -#endif -#define BLE_HCI_OCF_LE_SET_HOST_FEAT (0x0074) -struct ble_hci_le_set_host_feat_cp { +#define BLE_HCI_OCF_LE_SET_HOST_FEATURE (0x0074) +struct ble_hci_le_set_host_feature_cp { uint8_t bit_num; - uint8_t val; + uint8_t bit_val; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_READ_ISO_LINK_QUALITY (0x0075) +struct ble_hci_le_read_iso_link_quality_cp { + uint16_t conn_handle; +} __attribute__((packed)); +struct ble_hci_le_read_iso_link_quality_rp { + uint16_t conn_handle; + uint32_t tx_unacked_pkts; + uint32_t tx_flushed_pkts; + uint32_t tx_last_subevent_pkts; + uint32_t retransmitted_pkts; + uint32_t crc_error_pkts; + uint32_t rx_unreceived_pkts; + uint32_t duplicate_pkts; } __attribute__((packed)); #define BLE_HCI_OCF_LE_ENH_READ_TRANSMIT_POWER_LEVEL (0x0076) @@ -1816,43 +1842,43 @@ struct ble_hci_ev_le_subev_periodic_adv_sync_transfer { uint8_t aca; } __attribute__((packed)); -#define BLE_HCI_LE_SUBEV_CIS_ESTAB (0x19) +#define BLE_HCI_LE_SUBEV_CIS_ESTABLISHED (0x19) struct ble_hci_ev_le_subev_cis_established { uint8_t subev_code; uint8_t status; - uint16_t cis_handle; + uint16_t conn_handle; uint8_t cig_sync_delay[3]; uint8_t cis_sync_delay[3]; - uint8_t trans_latency_mtos[3]; - uint8_t trans_latency_stom[3]; - uint8_t phy_mtos; - uint8_t phy_stom; + uint8_t transport_latency_c_to_p[3]; + uint8_t transport_latency_p_to_c[3]; + uint8_t phy_c_to_p; + uint8_t phy_p_to_c; uint8_t nse; - uint8_t bn_mtos; - uint8_t bn_stom; - uint8_t ft_mtos; - uint8_t ft_stom; - uint16_t max_pdu_mtos; - uint16_t max_pdu_stom; + uint8_t bn_c_to_p; + uint8_t bn_p_to_c; + uint8_t ft_c_to_p; + uint8_t ft_p_to_c; + uint16_t max_pdu_c_to_p; + uint16_t max_pdu_p_to_c; uint16_t iso_interval; } __attribute__((packed)); #define BLE_HCI_LE_SUBEV_CIS_REQUEST (0x1A) struct ble_hci_ev_le_subev_cis_request { uint8_t subev_code; - uint16_t conn_handle; - uint16_t cis_handle; + uint16_t acl_conn_handle; + uint16_t cis_conn_handle; uint8_t cig_id; uint8_t cis_id; } __attribute__((packed)); -#define BLE_HCI_LE_SUBEV_BIG_COMP (0x1B) -struct ble_hci_ev_le_subev_big_complete { +#define BLE_HCI_LE_SUBEV_CREATE_BIG_COMPLETE (0x1B) +struct ble_hci_ev_le_subev_create_big_complete { uint8_t subev_code; uint8_t status; uint8_t big_handle; uint8_t big_sync_delay[3]; - uint8_t transport_latency[3]; + uint8_t transport_latency_big[3]; uint8_t phy; uint8_t nse; uint8_t bn; @@ -1860,31 +1886,31 @@ struct ble_hci_ev_le_subev_big_complete { uint8_t irc; uint16_t max_pdu; uint16_t iso_interval; - uint8_t bis_cnt; - uint16_t bis[0]; + uint8_t num_bis; + uint16_t conn_handle[0]; } __attribute__((packed)); -#define BLE_HCI_LE_SUBEV_BIG_TERMINATE_COMP (0x1C) -struct ble_hci_ev_le_subev_big_terminate_complete { +#define BLE_HCI_LE_SUBEV_TERMINATE_BIG_COMPLETE (0x1C) +struct ble_hci_ev_le_subev_terminate_big_complete { uint8_t subev_code; uint8_t big_handle; uint8_t reason; } __attribute__((packed)); -#define BLE_HCI_LE_SUBEV_BIG_SYNC_ESTAB (0x1D) +#define BLE_HCI_LE_SUBEV_BIG_SYNC_ESTABLISHED (0x1D) struct ble_hci_ev_le_subev_big_sync_established { uint8_t subev_code; uint8_t status; uint8_t big_handle; - uint8_t transport_latency[3]; + uint8_t transport_latency_big[3]; uint8_t nse; uint8_t bn; uint8_t pto; uint8_t irc; uint16_t max_pdu; uint16_t iso_interval; - uint8_t bis_cnt; - uint16_t bis_handles[0]; + uint8_t num_bis; + uint16_t conn_handle[0]; } __attribute__((packed)); #define BLE_HCI_LE_SUBEV_BIG_SYNC_LOST (0x1E) From 6e9b61b1c8f6a715ae7fc4676eeecf2ac1fd45e4 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 26 Feb 2022 21:35:48 +0100 Subject: [PATCH 0620/1333] nimble/ll: Add few useful macros --- nimble/controller/include/controller/ble_ll_utils.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimble/controller/include/controller/ble_ll_utils.h b/nimble/controller/include/controller/ble_ll_utils.h index 16b91a0cb8..added99043 100644 --- a/nimble/controller/include/controller/ble_ll_utils.h +++ b/nimble/controller/include/controller/ble_ll_utils.h @@ -23,6 +23,11 @@ #define INT16_LT(_a, _b) ((int16_t)((_a) - (_b)) < 0) #define INT16_LTE(_a, _b) ((int16_t)((_a) - (_b)) <= 0) +#define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) +#define MAX(_a, _b) ((_a) < (_b) ? (_a) : (_b)) +#define CLAMP(_n, _min, _max) (MAX(_min, MIN(_n, _max))) +#define IN_RANGE(_n, _min, _max) (((_n) >= (_min)) && ((_n) <= (_max))) + uint32_t ble_ll_utils_calc_access_addr(void); uint8_t ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap); uint8_t ble_ll_utils_dci_csa2(uint16_t counter, uint16_t chan_id, From a7861f3c24c67a16d24cd169454ae9904bac743c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 26 Feb 2022 21:36:21 +0100 Subject: [PATCH 0621/1333] nimble/ll: Add helper to calculate Seed AA --- .../include/controller/ble_ll_utils.h | 1 + nimble/controller/src/ble_ll_utils.c | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/nimble/controller/include/controller/ble_ll_utils.h b/nimble/controller/include/controller/ble_ll_utils.h index added99043..5739e04689 100644 --- a/nimble/controller/include/controller/ble_ll_utils.h +++ b/nimble/controller/include/controller/ble_ll_utils.h @@ -29,6 +29,7 @@ #define IN_RANGE(_n, _min, _max) (((_n) >= (_min)) && ((_n) <= (_max))) uint32_t ble_ll_utils_calc_access_addr(void); +uint32_t ble_ll_utils_calc_seed_aa(void); uint8_t ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap); uint8_t ble_ll_utils_dci_csa2(uint16_t counter, uint16_t chan_id, uint8_t num_used_chans, const uint8_t *chan_map); diff --git a/nimble/controller/src/ble_ll_utils.c b/nimble/controller/src/ble_ll_utils.c index a2507ad288..1c65a7cf00 100644 --- a/nimble/controller/src/ble_ll_utils.c +++ b/nimble/controller/src/ble_ll_utils.c @@ -144,6 +144,45 @@ ble_ll_utils_calc_access_addr(void) return aa; } +uint32_t +ble_ll_utils_calc_seed_aa(void) +{ + uint32_t seed_aa; + + while (1) { + seed_aa = ble_ll_rand(); + + /* saa(19) == saa(15) */ + if (!!(seed_aa & (1 << 19)) != !!(seed_aa & (1 << 15))) { + continue; + } + + /* saa(22) = saa(16) */ + if (!!(seed_aa & (1 << 22)) != !!(seed_aa & (1 << 16))) { + continue; + } + + /* saa(22) != saa(15) */ + if (!!(seed_aa & (1 << 22)) == !!(seed_aa & (1 << 15))) { + continue; + } + + /* saa(25) == 0 */ + if (seed_aa & (1 << 25)) { + continue; + } + + /* saa(23) == 1 */ + if (!(seed_aa & (1 << 23))) { + continue; + } + + break; + } + + return seed_aa; +} + uint8_t ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap) { From 5652310e74ff6e03e086ace9673924cfbc0d3852 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 27 Jan 2023 12:58:25 +0100 Subject: [PATCH 0622/1333] nimble/ll: Add helper to calculate BIG AA --- .../include/controller/ble_ll_utils.h | 1 + nimble/controller/src/ble_ll_utils.c | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/nimble/controller/include/controller/ble_ll_utils.h b/nimble/controller/include/controller/ble_ll_utils.h index 5739e04689..3e28fcb4c6 100644 --- a/nimble/controller/include/controller/ble_ll_utils.h +++ b/nimble/controller/include/controller/ble_ll_utils.h @@ -30,6 +30,7 @@ uint32_t ble_ll_utils_calc_access_addr(void); uint32_t ble_ll_utils_calc_seed_aa(void); +uint32_t ble_ll_utils_calc_big_aa(uint32_t seed_aa, uint32_t n); uint8_t ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap); uint8_t ble_ll_utils_dci_csa2(uint16_t counter, uint16_t chan_id, uint8_t num_used_chans, const uint8_t *chan_map); diff --git a/nimble/controller/src/ble_ll_utils.c b/nimble/controller/src/ble_ll_utils.c index 1c65a7cf00..4f1c679ba6 100644 --- a/nimble/controller/src/ble_ll_utils.c +++ b/nimble/controller/src/ble_ll_utils.c @@ -183,6 +183,32 @@ ble_ll_utils_calc_seed_aa(void) return seed_aa; } +uint32_t +ble_ll_utils_calc_big_aa(uint32_t seed_aa, uint32_t n) +{ + uint32_t d; + uint32_t dw; + + /* Core 5.3, Vol 6, Part B, 2.1.2 */ + /* TODO simplify? */ + d = ((35 * n) + 42) % 128; + dw = (!!(d & (1 << 0)) << 31) | + (!!(d & (1 << 0)) << 30) | + (!!(d & (1 << 0)) << 29) | + (!!(d & (1 << 0)) << 28) | + (!!(d & (1 << 0)) << 27) | + (!!(d & (1 << 0)) << 26) | + (!!(d & (1 << 1)) << 25) | + (!!(d & (1 << 6)) << 24) | + (!!(d & (1 << 1)) << 23) | + (!!(d & (1 << 5)) << 21) | + (!!(d & (1 << 4)) << 20) | + (!!(d & (1 << 3)) << 18) | + (!!(d & (1 << 2)) << 17); + + return seed_aa ^ dw; +} + uint8_t ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap) { From 5b87eb0b62ea1cdf05d6af6a8d96bcc25c2e4b83 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 27 Jan 2023 00:48:06 +0100 Subject: [PATCH 0623/1333] nimble/ll: Add helper to validate AA --- .../include/controller/ble_ll_utils.h | 1 + nimble/controller/src/ble_ll_utils.c | 162 +++++++++--------- 2 files changed, 84 insertions(+), 79 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_utils.h b/nimble/controller/include/controller/ble_ll_utils.h index 3e28fcb4c6..4d7e7e702d 100644 --- a/nimble/controller/include/controller/ble_ll_utils.h +++ b/nimble/controller/include/controller/ble_ll_utils.h @@ -28,6 +28,7 @@ #define CLAMP(_n, _min, _max) (MAX(_min, MIN(_n, _max))) #define IN_RANGE(_n, _min, _max) (((_n) >= (_min)) && ((_n) <= (_max))) +int ble_ll_utils_verify_aa(uint32_t aa); uint32_t ble_ll_utils_calc_access_addr(void); uint32_t ble_ll_utils_calc_seed_aa(void); uint32_t ble_ll_utils_calc_big_aa(uint32_t seed_aa, uint32_t n); diff --git a/nimble/controller/src/ble_ll_utils.c b/nimble/controller/src/ble_ll_utils.c index 4f1c679ba6..1259f94d73 100644 --- a/nimble/controller/src/ble_ll_utils.c +++ b/nimble/controller/src/ble_ll_utils.c @@ -32,10 +32,9 @@ static const uint16_t g_ble_sca_ppm_tbl[8] = { 500, 250, 150, 100, 75, 50, 30, 20 }; -uint32_t -ble_ll_utils_calc_access_addr(void) +int +ble_ll_utils_verify_aa(uint32_t aa) { - uint32_t aa; uint16_t aa_low; uint16_t aa_high; uint32_t temp; @@ -47,100 +46,105 @@ ble_ll_utils_calc_access_addr(void) uint8_t ones; int tmp; - /* Calculate a random access address */ - aa = 0; - while (1) { - /* Get two, 16-bit random numbers */ - aa_low = ble_ll_rand() & 0xFFFF; - aa_high = ble_ll_rand() & 0xFFFF; + aa_low = aa & 0xffff; + aa_high = aa >> 16; - /* All four bytes cannot be equal */ - if (aa_low == aa_high) { - continue; - } + /* All four bytes cannot be equal */ + if (aa_low == aa_high) { + return 0; + } - /* Upper 6 bits must have 2 transitions */ - tmp = (int16_t)aa_high >> 10; - if (__builtin_popcount(tmp ^ (tmp >> 1)) < 2) { - continue; - } + /* Upper 6 bits must have 2 transitions */ + tmp = (int16_t)aa_high >> 10; + if (__builtin_popcount(tmp ^ (tmp >> 1)) < 2) { + return 0; + } - /* Cannot be access address or be 1 bit different */ - aa = aa_high; - aa = (aa << 16) | aa_low; - bits_diff = 0; - temp = aa ^ BLE_ACCESS_ADDR_ADV; - for (mask = 0x00000001; mask != 0; mask <<= 1) { - if (mask & temp) { - ++bits_diff; - if (bits_diff > 1) { - break; - } + /* Cannot be access address or be 1 bit different */ + aa = aa_high; + aa = (aa << 16) | aa_low; + bits_diff = 0; + temp = aa ^ BLE_ACCESS_ADDR_ADV; + for (mask = 0x00000001; mask != 0; mask <<= 1) { + if (mask & temp) { + ++bits_diff; + if (bits_diff > 1) { + break; } } - if (bits_diff <= 1) { - continue; - } + } + if (bits_diff <= 1) { + return 0; + } - /* Cannot have more than 24 transitions */ - transitions = 0; - consecutive = 1; - ones = 0; - mask = 0x00000001; - while (mask < 0x80000000) { - prev_bit = aa & mask; - mask <<= 1; - if (mask & aa) { - if (prev_bit == 0) { - ++transitions; - consecutive = 1; - } else { - ++consecutive; - } + /* Cannot have more than 24 transitions */ + transitions = 0; + consecutive = 1; + ones = 0; + mask = 0x00000001; + while (mask < 0x80000000) { + prev_bit = aa & mask; + mask <<= 1; + if (mask & aa) { + if (prev_bit == 0) { + ++transitions; + consecutive = 1; } else { - if (prev_bit == 0) { - ++consecutive; - } else { - ++transitions; - consecutive = 1; - } - } - - if (prev_bit) { - ones++; + ++consecutive; } - - /* 8 lsb should have at least three 1 */ - if (mask == 0x00000100 && ones < 3) { - break; + } else { + if (prev_bit == 0) { + ++consecutive; + } else { + ++transitions; + consecutive = 1; } + } - /* 16 lsb should have no more than 11 transitions */ - if (mask == 0x00010000 && transitions > 11) { - break; - } + if (prev_bit) { + ones++; + } - /* This is invalid! */ - if (consecutive > 6) { - /* Make sure we always detect invalid sequence below */ - mask = 0; - break; - } + /* 8 lsb should have at least three 1 */ + if (mask == 0x00000100 && ones < 3) { + break; } - /* Invalid sequence found */ - if (mask != 0x80000000) { - continue; + /* 16 lsb should have no more than 11 transitions */ + if (mask == 0x00010000 && transitions > 11) { + break; } - /* Cannot be more than 24 transitions */ - if (transitions > 24) { - continue; + /* This is invalid! */ + if (consecutive > 6) { + /* Make sure we always detect invalid sequence below */ + mask = 0; + break; } + } - /* We have a valid access address */ - break; + /* Invalid sequence found */ + if (mask != 0x80000000) { + return 0; } + + /* Cannot be more than 24 transitions */ + if (transitions > 24) { + return 0; + } + + return 1; +} + +uint32_t +ble_ll_utils_calc_access_addr(void) +{ + uint32_t aa; + + do { + aa = ble_ll_rand(); + } while (!ble_ll_utils_verify_aa(aa)); + return aa; } From 32814579e6c7c98da1de0b356280f1bcf5dc3809 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 27 Jan 2023 00:50:58 +0100 Subject: [PATCH 0624/1333] nimble/ll: Rename helper to calculate AA This is for consistency wither other helpers which use shorter name. --- nimble/controller/include/controller/ble_ll_utils.h | 2 +- nimble/controller/src/ble_ll_adv.c | 4 ++-- nimble/controller/src/ble_ll_conn.c | 2 +- nimble/controller/src/ble_ll_utils.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_utils.h b/nimble/controller/include/controller/ble_ll_utils.h index 4d7e7e702d..fe1bca9f67 100644 --- a/nimble/controller/include/controller/ble_ll_utils.h +++ b/nimble/controller/include/controller/ble_ll_utils.h @@ -29,7 +29,7 @@ #define IN_RANGE(_n, _min, _max) (((_n) >= (_min)) && ((_n) <= (_max))) int ble_ll_utils_verify_aa(uint32_t aa); -uint32_t ble_ll_utils_calc_access_addr(void); +uint32_t ble_ll_utils_calc_aa(void); uint32_t ble_ll_utils_calc_seed_aa(void); uint32_t ble_ll_utils_calc_big_aa(uint32_t seed_aa, uint32_t n); uint8_t ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap); diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 49228246b5..125b62475b 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -2612,7 +2612,7 @@ ble_ll_adv_sm_start_periodic(struct ble_ll_adv_sm *advsm) advsm->periodic_event_cntr = 0; /* for chaining we start with random counter as we share access addr */ advsm->periodic_chain_event_cntr = ble_ll_rand(); - advsm->periodic_access_addr = ble_ll_utils_calc_access_addr(); + advsm->periodic_access_addr = ble_ll_utils_calc_aa(); advsm->periodic_channel_id = ((advsm->periodic_access_addr & 0xffff0000) >> 16) ^ (advsm->periodic_access_addr & 0x0000ffff); advsm->periodic_crcinit = ble_ll_rand() & 0xffffff; @@ -2767,7 +2767,7 @@ ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) advsm->event_cntr = 0; - access_addr = ble_ll_utils_calc_access_addr(); + access_addr = ble_ll_utils_calc_aa(); advsm->channel_id = ((access_addr & 0xffff0000) >> 16) ^ (access_addr & 0x0000ffff); #endif diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 9b926010c1..4f12f14312 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1769,7 +1769,7 @@ ble_ll_conn_central_common_init(struct ble_ll_conn_sm *connsm) #endif /* Calculate random access address and crc initialization value */ - connsm->access_addr = ble_ll_utils_calc_access_addr(); + connsm->access_addr = ble_ll_utils_calc_aa(); connsm->crcinit = ble_ll_rand() & 0xffffff; /* Set initial schedule callback */ diff --git a/nimble/controller/src/ble_ll_utils.c b/nimble/controller/src/ble_ll_utils.c index 1259f94d73..1921ee72a3 100644 --- a/nimble/controller/src/ble_ll_utils.c +++ b/nimble/controller/src/ble_ll_utils.c @@ -137,7 +137,7 @@ ble_ll_utils_verify_aa(uint32_t aa) } uint32_t -ble_ll_utils_calc_access_addr(void) +ble_ll_utils_calc_aa(void) { uint32_t aa; From c7381e887766caaaa9f7fac81fe80d3af21d2099 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 19 Jan 2023 20:48:23 +0100 Subject: [PATCH 0625/1333] nimble/ll: Add ble_ll_pdu This is small step to declutter ble_ll and cleanup defs for PDU-related defs and helpers. --- .../include/controller/ble_ll_pdu.h | 42 ++++++++++++++ nimble/controller/src/ble_ll_pdu.c | 58 +++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 nimble/controller/include/controller/ble_ll_pdu.h create mode 100644 nimble/controller/src/ble_ll_pdu.c diff --git a/nimble/controller/include/controller/ble_ll_pdu.h b/nimble/controller/include/controller/ble_ll_pdu.h new file mode 100644 index 0000000000..60eef83368 --- /dev/null +++ b/nimble/controller/include/controller/ble_ll_pdu.h @@ -0,0 +1,42 @@ +/* + * 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_BLE_LL_PDU_ +#define H_BLE_LL_PDU_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_LL_PDU_PREAMBLE_1M_LEN (1) +#define BLE_LL_PDU_PREAMBLE_2M_LEN (2) +#define BLE_LL_PDU_AA_LEN (4) +#define BLE_LL_PDU_HEADER_LEN (2) +#define BLE_LL_PDU_CRC_LEN (3) + +uint32_t ble_ll_pdu_syncword_us(uint8_t phy_mode); +uint32_t ble_ll_pdu_us(uint8_t payload_len, uint8_t phy_mode); + +#ifdef __cplusplus +} +#endif + +#endif /* H_BLE_LL_PDU_ */ diff --git a/nimble/controller/src/ble_ll_pdu.c b/nimble/controller/src/ble_ll_pdu.c new file mode 100644 index 0000000000..bcbb5ff06b --- /dev/null +++ b/nimble/controller/src/ble_ll_pdu.c @@ -0,0 +1,58 @@ +/* + * 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. + */ + +#include +#include + +static const uint16_t syncword_len[] = { + [BLE_PHY_MODE_1M] = (BLE_LL_PDU_PREAMBLE_1M_LEN + BLE_LL_PDU_AA_LEN) * 8, + [BLE_PHY_MODE_2M] = (BLE_LL_PDU_PREAMBLE_2M_LEN + BLE_LL_PDU_AA_LEN) * 4, + [BLE_PHY_MODE_CODED_125KBPS] = 80 + 256 + 16 + 24, + [BLE_PHY_MODE_CODED_500KBPS] = 80 + 256 + 16 + 24, +}; + +static const uint16_t payload0_len[] = { + [BLE_PHY_MODE_1M] = (BLE_LL_PDU_PREAMBLE_1M_LEN + BLE_LL_PDU_AA_LEN + + BLE_LL_PDU_HEADER_LEN + BLE_LL_PDU_CRC_LEN) * 8, + [BLE_PHY_MODE_2M] = (BLE_LL_PDU_PREAMBLE_2M_LEN + BLE_LL_PDU_AA_LEN + + BLE_LL_PDU_HEADER_LEN + BLE_LL_PDU_CRC_LEN) * 4, + [BLE_PHY_MODE_CODED_125KBPS] = 80 + 256 + 16 + 24 + + 8 * (BLE_LL_PDU_HEADER_LEN * 8 + 24 + 3), + [BLE_PHY_MODE_CODED_500KBPS] = 80 + 256 + 16 + 24 + + 2 * (BLE_LL_PDU_HEADER_LEN * 8 + 24 + 3), +}; + +static const uint8_t us_per_octet[] = { + [BLE_PHY_MODE_1M] = 8, + [BLE_PHY_MODE_2M] = 4, + [BLE_PHY_MODE_CODED_125KBPS] = 64, + [BLE_PHY_MODE_CODED_500KBPS] = 16, +}; + +uint32_t +ble_ll_pdu_syncword_us(uint8_t phy_mode) +{ + return syncword_len[phy_mode]; +} + +uint32_t +ble_ll_pdu_us(uint8_t payload_len, uint8_t phy_mode) +{ + return payload0_len[phy_mode] + (payload_len * us_per_octet[phy_mode]); +} From d9fbaccd3e525c625089608d24fda0e45e6bb821 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 27 Jan 2023 01:08:43 +0100 Subject: [PATCH 0626/1333] nimble/ll: Remove ble_ll_pdu_tx_time_get Use ble_ll_pdu_us instead. --- nimble/controller/include/controller/ble_ll.h | 4 -- nimble/controller/src/ble_ll.c | 53 +------------------ nimble/controller/src/ble_ll_adv.c | 35 ++++++------ nimble/controller/src/ble_ll_conn.c | 21 ++++---- nimble/controller/src/ble_ll_dtm.c | 3 +- nimble/controller/src/ble_ll_scan_aux.c | 3 +- nimble/controller/src/ble_ll_sched.c | 5 +- 7 files changed, 37 insertions(+), 87 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 25a8f296a9..9fe3fb8f01 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -495,10 +495,6 @@ int ble_ll_is_valid_random_addr(const uint8_t *addr); int ble_ll_is_valid_own_addr_type(uint8_t own_addr_type, const uint8_t *random_addr); -/* Calculate the amount of time in microseconds a PDU with payload length of - * 'payload_len' will take to transmit on a PHY 'phy_mode'. */ -uint32_t ble_ll_pdu_tx_time_get(uint16_t payload_len, int phy_mode); - /* Calculate maximum octets of PDU payload which can be transmitted during * 'usecs' on a PHY 'phy_mode'. */ uint16_t ble_ll_pdu_max_tx_octets_get(uint32_t usecs, int phy_mode); diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 9b9fc4e0ac..913f68cfea 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -33,6 +33,7 @@ #include "controller/ble_phy.h" #include "controller/ble_phy_trace.h" #include "controller/ble_ll.h" +#include "controller/ble_ll_pdu.h" #include "controller/ble_ll_adv.h" #include "controller/ble_ll_sched.h" #include "controller/ble_ll_scan.h" @@ -377,25 +378,6 @@ uint8_t g_dev_addr[BLE_DEV_ADDR_LEN]; /** Our random address */ uint8_t g_random_addr[BLE_DEV_ADDR_LEN]; -static const uint16_t g_ble_ll_pdu_header_tx_time[BLE_PHY_NUM_MODE] = -{ - [BLE_PHY_MODE_1M] = - (BLE_LL_PREAMBLE_LEN + BLE_LL_ACC_ADDR_LEN + BLE_LL_CRC_LEN + - BLE_LL_PDU_HDR_LEN) << 3, - [BLE_PHY_MODE_2M] = - (BLE_LL_PREAMBLE_LEN * 2 + BLE_LL_ACC_ADDR_LEN + BLE_LL_CRC_LEN + - BLE_LL_PDU_HDR_LEN) << 2, - /* For Coded PHY we have exact TX times provided by specification: - * - Preamble, Access Address, CI, TERM1 (always coded as S=8) - * - PDU, CRC, TERM2 (coded as S=2 or S=8) - * (Vol 6, Part B, 2.2). - */ - [BLE_PHY_MODE_CODED_125KBPS] = - (80 + 256 + 16 + 24 + 8 * (BLE_LL_PDU_HDR_LEN * 8 + 24 + 3)), - [BLE_PHY_MODE_CODED_500KBPS] = - (80 + 256 + 16 + 24 + 2 * (BLE_LL_PDU_HDR_LEN * 8 + 24 + 3)), -}; - /** * Counts the number of advertising PDU's received, by type. For advertising * PDU's that contain a destination address, we still count these packets even @@ -1700,37 +1682,6 @@ ble_ll_reset(void) return rc; } -uint32_t -ble_ll_pdu_tx_time_get(uint16_t payload_len, int phy_mode) -{ - uint32_t usecs; - -#if (BLE_LL_BT5_PHY_SUPPORTED) - if (phy_mode == BLE_PHY_MODE_1M) { - /* 8 usecs per byte */ - usecs = payload_len << 3; - } else if (phy_mode == BLE_PHY_MODE_2M) { - /* 4 usecs per byte */ - usecs = payload_len << 2; - } else if (phy_mode == BLE_PHY_MODE_CODED_125KBPS) { - /* S=8 => 8 * 8 = 64 usecs per byte */ - usecs = payload_len << 6; - } else if (phy_mode == BLE_PHY_MODE_CODED_500KBPS) { - /* S=2 => 2 * 8 = 16 usecs per byte */ - usecs = payload_len << 4; - } else { - BLE_LL_ASSERT(0); - } - - usecs += g_ble_ll_pdu_header_tx_time[phy_mode]; -#else - usecs = (((payload_len) + BLE_LL_PDU_HDR_LEN + BLE_LL_ACC_ADDR_LEN - + BLE_LL_PREAMBLE_LEN + BLE_LL_CRC_LEN) << 3); -#endif - - return usecs; -} - uint16_t ble_ll_pdu_max_tx_octets_get(uint32_t usecs, int phy_mode) { @@ -1739,7 +1690,7 @@ ble_ll_pdu_max_tx_octets_get(uint32_t usecs, int phy_mode) BLE_LL_ASSERT(phy_mode < BLE_PHY_NUM_MODE); - header_tx_time = g_ble_ll_pdu_header_tx_time[phy_mode]; + header_tx_time = ble_ll_pdu_us(0, phy_mode); /* * Current conn max tx time can be too short to even send a packet header diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 125b62475b..6f35c7e535 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -29,6 +29,7 @@ #include "controller/ble_phy.h" #include "controller/ble_hw.h" #include "controller/ble_ll.h" +#include "controller/ble_ll_pdu.h" #include "controller/ble_ll_hci.h" #include "controller/ble_ll_adv.h" #include "controller/ble_ll_sched.h" @@ -781,7 +782,7 @@ ble_ll_adv_aux_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) offset = 0; } else if (advsm->rx_ble_hdr) { offset = ble_ll_tmr_t2u(AUX_NEXT(advsm)->start_time - advsm->rx_ble_hdr->beg_cputime); - offset -= (advsm->rx_ble_hdr->rem_usecs + ble_ll_pdu_tx_time_get(12, advsm->sec_phy) + BLE_LL_IFS); + offset -= (advsm->rx_ble_hdr->rem_usecs + ble_ll_pdu_us(12, advsm->sec_phy) + BLE_LL_IFS); } else { offset = ble_ll_tmr_t2u(AUX_NEXT(advsm)->start_time - aux->start_time); } @@ -1206,7 +1207,7 @@ ble_ll_adv_set_sched(struct ble_ll_adv_sm *advsm) /* Set end time to maximum time this schedule item may take */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) { - max_usecs = ble_ll_pdu_tx_time_get(advsm->adv_pdu_len, BLE_PHY_MODE_1M); + max_usecs = ble_ll_pdu_us(advsm->adv_pdu_len, BLE_PHY_MODE_1M); if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) { max_usecs += BLE_LL_SCHED_DIRECT_ADV_MAX_USECS; @@ -1218,10 +1219,10 @@ ble_ll_adv_set_sched(struct ble_ll_adv_sm *advsm) * In ADV_EXT_IND we always set only ADI and AUX so the payload length * is always 7 bytes. */ - max_usecs = ble_ll_pdu_tx_time_get(7, advsm->pri_phy); + max_usecs = ble_ll_pdu_us(7, advsm->pri_phy); } #else - max_usecs = ble_ll_pdu_tx_time_get(advsm->adv_pdu_len, BLE_PHY_MODE_1M); + max_usecs = ble_ll_pdu_us(advsm->adv_pdu_len, BLE_PHY_MODE_1M); if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED) { max_usecs += BLE_LL_SCHED_DIRECT_ADV_MAX_USECS; @@ -1509,7 +1510,7 @@ ble_ll_adv_aux_check_data_itvl(struct ble_ll_adv_sm *advsm, uint16_t props, * account, but we do not support max skip anyway for now. */ - max_usecs = 3 * (ble_ll_pdu_tx_time_get(7, pri_phy) + 300) + + max_usecs = 3 * (ble_ll_pdu_us(7, pri_phy) + 300) + BLE_LL_MAFS + MYNEWT_VAL(BLE_LL_SCHED_AUX_MAFS_DELAY); data_offset = 0; @@ -1518,7 +1519,7 @@ ble_ll_adv_aux_check_data_itvl(struct ble_ll_adv_sm *advsm, uint16_t props, pdu_len = ble_ll_adv_aux_calculate_payload(advsm, props, data, data_offset, &data_len, &ext_hdr_flags); - max_usecs += ble_ll_pdu_tx_time_get(pdu_len, sec_phy); + max_usecs += ble_ll_pdu_us(pdu_len, sec_phy); max_usecs += BLE_LL_MAFS + MYNEWT_VAL(BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY); data_offset += data_len; @@ -1578,7 +1579,7 @@ ble_ll_adv_aux_schedule_next(struct ble_ll_adv_sm *advsm) BLE_LL_ASSERT(rem_data_len > 0); ble_ll_adv_aux_calculate(advsm, aux_next, next_data_offset); - max_usecs = ble_ll_pdu_tx_time_get(aux_next->payload_len, advsm->sec_phy); + max_usecs = ble_ll_pdu_us(aux_next->payload_len, advsm->sec_phy); aux_next->start_time = aux->sch.end_time + ble_ll_tmr_u2t_up(BLE_LL_MAFS + @@ -1623,13 +1624,13 @@ ble_ll_adv_aux_schedule_first(struct ble_ll_adv_sm *advsm) /* Set end time to maximum time this schedule item may take */ if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) { - max_usecs = ble_ll_pdu_tx_time_get(aux->payload_len, advsm->sec_phy) + + max_usecs = ble_ll_pdu_us(aux->payload_len, advsm->sec_phy) + BLE_LL_IFS + /* AUX_CONN_REQ */ - ble_ll_pdu_tx_time_get(34 + 14, advsm->sec_phy) + + ble_ll_pdu_us(34 + 14, advsm->sec_phy) + BLE_LL_IFS + /* AUX_CONN_RSP */ - ble_ll_pdu_tx_time_get(14, advsm->sec_phy); + ble_ll_pdu_us(14, advsm->sec_phy); } else if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE) { /* For scannable advertising we need to calculate how much time we * need for AUX_ADV_IND along with AUX_SCAN_REQ, AUX_SCAN_RSP and @@ -1641,16 +1642,16 @@ ble_ll_adv_aux_schedule_first(struct ble_ll_adv_sm *advsm) * 2. length of AUX_ADV_IND is calculated by special function: * ble_ll_adv_aux_scannable_pdu_payload_len() */ - max_usecs = ble_ll_pdu_tx_time_get(ble_ll_adv_aux_scannable_pdu_payload_len(advsm), + max_usecs = ble_ll_pdu_us(ble_ll_adv_aux_scannable_pdu_payload_len(advsm), advsm->sec_phy) + BLE_LL_IFS + /* AUX_SCAN_REQ */ - ble_ll_pdu_tx_time_get(12, advsm->sec_phy) + + ble_ll_pdu_us(12, advsm->sec_phy) + BLE_LL_IFS + /* AUX_SCAN_RSP */ - ble_ll_pdu_tx_time_get(aux->payload_len, advsm->sec_phy); + ble_ll_pdu_us(aux->payload_len, advsm->sec_phy); } else { - max_usecs = ble_ll_pdu_tx_time_get(aux->payload_len, advsm->sec_phy); + max_usecs = ble_ll_pdu_us(aux->payload_len, advsm->sec_phy); } sch = &aux->sch; @@ -2385,7 +2386,7 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm, ble_ll_adv_sync_calculate(advsm, sync, 0, chan); /* sync is always non-connectable and non-scannable*/ - max_usecs = ble_ll_pdu_tx_time_get(sync->payload_len, advsm->sec_phy); + max_usecs = ble_ll_pdu_us(sync->payload_len, advsm->sec_phy); sch = &sync->sch; @@ -2471,7 +2472,7 @@ ble_ll_adv_periodic_schedule_next(struct ble_ll_adv_sm *advsm) advsm->periodic_chanmap); ble_ll_adv_sync_calculate(advsm, sync_next, next_data_offset, chan); - max_usecs = ble_ll_pdu_tx_time_get(sync_next->payload_len, advsm->sec_phy); + max_usecs = ble_ll_pdu_us(sync_next->payload_len, advsm->sec_phy); sync_next->start_time = sync->sch.end_time + ble_ll_tmr_u2t_up(BLE_LL_MAFS + @@ -3862,7 +3863,7 @@ ble_ll_adv_periodic_check_data_itvl(uint16_t payload_len, uint16_t props, while (offset < payload_len) { pdu_len = ble_ll_adv_sync_get_pdu_len(payload_len, &offset, props); - max_usecs += ble_ll_pdu_tx_time_get(pdu_len, phy); + max_usecs += ble_ll_pdu_us(pdu_len, phy); max_usecs += BLE_LL_MAFS + MYNEWT_VAL(BLE_LL_SCHED_AUX_CHAIN_MAFS_DELAY); } diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 4f12f14312..379a59a750 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -28,6 +28,7 @@ #include "nimble/hci_common.h" #include "nimble/transport.h" #include "controller/ble_ll.h" +#include "controller/ble_ll_pdu.h" #include "controller/ble_ll_conn.h" #include "controller/ble_ll_hci.h" #include "controller/ble_ll_scan.h" @@ -1268,8 +1269,8 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) #endif ticks = (BLE_LL_IFS * 3) + connsm->ota_max_rx_time + - ble_ll_pdu_tx_time_get(next_txlen, tx_phy_mode) + - ble_ll_pdu_tx_time_get(cur_txlen, tx_phy_mode); + ble_ll_pdu_us(next_txlen, tx_phy_mode) + + ble_ll_pdu_us(cur_txlen, tx_phy_mode); #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { @@ -1677,10 +1678,10 @@ ble_ll_conn_can_send_next_pdu(struct ble_ll_conn_sm *connsm, uint32_t begtime, if (rem_bytes > connsm->eff_max_tx_octets) { rem_bytes = connsm->eff_max_tx_octets; } - usecs = ble_ll_pdu_tx_time_get(rem_bytes, tx_phy_mode); + usecs = ble_ll_pdu_us(rem_bytes, tx_phy_mode); } else { /* We will send empty pdu (just a LL header) */ - usecs = ble_ll_pdu_tx_time_get(0, tx_phy_mode); + usecs = ble_ll_pdu_us(0, tx_phy_mode); } usecs += (BLE_LL_IFS * 2) + connsm->ota_max_rx_time; @@ -2132,7 +2133,7 @@ ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm) #else phy_mode = BLE_PHY_MODE_1M; #endif - ota_time = ble_ll_pdu_tx_time_get(connsm->eff_max_rx_octets, phy_mode); + ota_time = ble_ll_pdu_us(connsm->eff_max_rx_octets, phy_mode); connsm->ota_max_rx_time = min(ota_time, connsm->eff_max_rx_time); } @@ -2787,7 +2788,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) usecs = rxhdr->rem_usecs + 1250 + (connsm->tx_win_off * BLE_LL_CONN_TX_WIN_USECS) + - ble_ll_pdu_tx_time_get(BLE_CONNECT_REQ_LEN, + ble_ll_pdu_us(BLE_CONNECT_REQ_LEN, rxhdr->rxinfo.phy_mode); if (rxhdr->rxinfo.channel < BLE_PHY_NUM_DATA_CHANS) { @@ -3689,7 +3690,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) rx_phy_mode = BLE_PHY_MODE_1M; #endif add_usecs = rxhdr->rem_usecs + - ble_ll_pdu_tx_time_get(rx_pyld_len, rx_phy_mode); + ble_ll_pdu_us(rx_pyld_len, rx_phy_mode); /* * Check the packet CRC. A connection event can continue even if the @@ -4341,11 +4342,9 @@ ble_ll_conn_subrate_set(struct ble_ll_conn_sm *connsm, #endif #define MAX_TIME_UNCODED(_maxbytes) \ - ble_ll_pdu_tx_time_get(_maxbytes + BLE_LL_DATA_MIC_LEN, \ - BLE_PHY_MODE_1M); + ble_ll_pdu_us(_maxbytes + BLE_LL_DATA_MIC_LEN, BLE_PHY_MODE_1M); #define MAX_TIME_CODED(_maxbytes) \ - ble_ll_pdu_tx_time_get(_maxbytes + BLE_LL_DATA_MIC_LEN, \ - BLE_PHY_MODE_CODED_125KBPS); + ble_ll_pdu_us(_maxbytes + BLE_LL_DATA_MIC_LEN, BLE_PHY_MODE_CODED_125KBPS); /** * Called to reset the connection module. When this function is called the diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index b1e4f6f0a6..07e25fe2f8 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -26,6 +26,7 @@ #include "os/os.h" #include "stats/stats.h" #include "controller/ble_ll.h" +#include "controller/ble_ll_pdu.h" #include "controller/ble_phy.h" #include "controller/ble_ll_sched.h" #include "controller/ble_ll_rfmgmt.h" @@ -269,7 +270,7 @@ ble_ll_dtm_calculate_itvl(struct dtm_ctx *ctx, uint8_t len, uint32_t itvl_usec; /* Calculate interval as per spec Bluetooth 5.0 Vol 6. Part F, 4.1.6 */ - l = ble_ll_pdu_tx_time_get(len + BLE_LL_PDU_HDR_LEN, phy_mode); + l = ble_ll_pdu_us(len, phy_mode); itvl_usec = ((l + 249 + 624) / 625) * 625; #if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index f7c92d5302..45f9ce462c 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -31,6 +31,7 @@ #include "controller/ble_phy.h" #include "controller/ble_hw.h" #include "controller/ble_ll.h" +#include "controller/ble_ll_pdu.h" #include "controller/ble_ll_sched.h" #include "controller/ble_ll_scan.h" #include "controller/ble_ll_scan_aux.h" @@ -747,7 +748,7 @@ ble_ll_scan_aux_sched(struct ble_ll_scan_aux_data *aux, uint32_t pdu_time, return -1; } - max_aux_time_us = ble_ll_pdu_tx_time_get(MYNEWT_VAL(BLE_LL_SCHED_SCAN_AUX_PDU_LEN), + max_aux_time_us = ble_ll_pdu_us(MYNEWT_VAL(BLE_LL_SCHED_SCAN_AUX_PDU_LEN), ble_ll_phy_to_phy_mode(aux->sec_phy, 0)); rc = ble_ll_sched_scan_aux(&aux->sch, pdu_time, pdu_time_rem, offset_us, diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index cf64e82f3a..513257db59 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -23,6 +23,7 @@ #include "ble/xcvr.h" #include "controller/ble_phy.h" #include "controller/ble_ll.h" +#include "controller/ble_ll_pdu.h" #include "controller/ble_ll_sched.h" #include "controller/ble_ll_adv.h" #include "controller/ble_ll_scan.h" @@ -680,7 +681,7 @@ ble_ll_sched_sync_reschedule(struct ble_ll_sched_item *sch, ble_ll_tmr_sub(&start_time, &start_time_rem_usecs, window_widening); - dur = ble_ll_pdu_tx_time_get(MYNEWT_VAL(BLE_LL_SCHED_SCAN_SYNC_PDU_LEN), + dur = ble_ll_pdu_us(MYNEWT_VAL(BLE_LL_SCHED_SCAN_SYNC_PDU_LEN), phy_mode); end_time = start_time + ble_ll_tmr_u2t(dur); @@ -729,7 +730,7 @@ ble_ll_sched_sync(struct ble_ll_sched_item *sch, ble_ll_tmr_add(&start_time, &start_time_rem_usecs, offset); - dur = ble_ll_pdu_tx_time_get(MYNEWT_VAL(BLE_LL_SCHED_SCAN_SYNC_PDU_LEN), + dur = ble_ll_pdu_us(MYNEWT_VAL(BLE_LL_SCHED_SCAN_SYNC_PDU_LEN), phy_mode); end_time = start_time + ble_ll_tmr_u2t(dur); From 6c124515b502b0956c0225fb6c7a1ab48d49111a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 26 Jan 2023 23:42:33 +0100 Subject: [PATCH 0627/1333] nimble/ll: Add some crypto functions This adds h6, h7 and h8 crypto functions that are used to derive GSK from broadcast code. For now we use TinyCrypt, later we may use hw accelerators as an option. --- .../include/controller/ble_ll_crypto.h | 50 +++++++++++++++ nimble/controller/pkg.yml | 1 + nimble/controller/src/ble_ll_crypto.c | 62 +++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 nimble/controller/include/controller/ble_ll_crypto.h create mode 100644 nimble/controller/src/ble_ll_crypto.c diff --git a/nimble/controller/include/controller/ble_ll_crypto.h b/nimble/controller/include/controller/ble_ll_crypto.h new file mode 100644 index 0000000000..4514b0b107 --- /dev/null +++ b/nimble/controller/include/controller/ble_ll_crypto.h @@ -0,0 +1,50 @@ +/* + * 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_BLE_LL_CRYPTO_ +#define H_BLE_LL_CRYPTO_ + +#ifdef __cplusplus +extern "C" { +#endif + +int +ble_ll_crypto_cmac(const uint8_t *key, const uint8_t *in, int len, + uint8_t *out); + +static inline int +ble_ll_crypto_h6(const uint8_t *w, const uint8_t *key_id, uint8_t *out) +{ + return ble_ll_crypto_cmac(w, key_id, 4, out); +} + +static inline int +ble_ll_crypto_h7(const uint8_t *salt, const uint8_t *w, uint8_t *out) +{ + return ble_ll_crypto_cmac(salt, w, 16, out); +} + +int ble_ll_crypto_h8(const uint8_t *k, const uint8_t *s, const uint8_t *key_id, + uint8_t *out); + +#ifdef __cplusplus +} +#endif + +#endif /* H_BLE_LL_CRYPTO_ */ diff --git a/nimble/controller/pkg.yml b/nimble/controller/pkg.yml index 678fea17bb..5e43ba39db 100644 --- a/nimble/controller/pkg.yml +++ b/nimble/controller/pkg.yml @@ -38,5 +38,6 @@ pkg.req_apis.BLE_FEM_ANTENNA: pkg.deps: - "@apache-mynewt-core/kernel/os" + - "@apache-mynewt-core/crypto/tinycrypt" - nimble - nimble/transport diff --git a/nimble/controller/src/ble_ll_crypto.c b/nimble/controller/src/ble_ll_crypto.c new file mode 100644 index 0000000000..be3e1be3b6 --- /dev/null +++ b/nimble/controller/src/ble_ll_crypto.c @@ -0,0 +1,62 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include + +int +ble_ll_crypto_cmac(const uint8_t *key, const uint8_t *in, int len, + uint8_t *out) +{ + struct tc_aes_key_sched_struct sched; + struct tc_cmac_struct state; + + if (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) { + return -1; + } + + if (tc_cmac_update(&state, in, len) == TC_CRYPTO_FAIL) { + return -1; + } + + if (tc_cmac_final(out, &state) == TC_CRYPTO_FAIL) { + return -1; + } + + return 0; +} + +int +ble_ll_crypto_h8(const uint8_t *k, const uint8_t *s, const uint8_t *key_id, + uint8_t *out) +{ + uint8_t ik[16]; + int rc; + + rc = ble_ll_crypto_cmac(s, k, 16, ik); + if (rc) { + return rc; + } + + return ble_ll_crypto_cmac(ik, key_id, 4, out); +} From fcf166804ab07d89c2f74ac4ba90b08878149f63 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 27 Jan 2023 19:41:01 +0100 Subject: [PATCH 0628/1333] ci: Make check style output more readable --- .github/check_style.py | 45 +++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/.github/check_style.py b/.github/check_style.py index 047c0f2271..7b2fa5b8fa 100755 --- a/.github/check_style.py +++ b/.github/check_style.py @@ -25,7 +25,7 @@ import tempfile import sys -coding_style_url = "https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md" +INFO_URL = "https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md" def get_lines_range(m: re.Match) -> range: first = int(m.group(1)) @@ -100,32 +100,41 @@ def main() -> bool: mb = run_cmd(f"git merge-base {upstream} {commit}") upstream = mb[0] - has_error = False - cfg_fname = os.path.join(os.path.dirname(__file__), "../.style_ignored_dirs") with open(cfg_fname, "r") as x: ign_dirs = [s.strip() for s in x.readlines() if s.strip() and not s.startswith("#")] + results_ok = [] + results_fail = [] + results_ign = [] + files = run_cmd(f"git diff --diff-filter=AM --name-only {upstream} {commit}") - for cfg_fname in files: - if is_ignored(cfg_fname, ign_dirs): - print(f"\033[90m- {cfg_fname}\033[0m") + for fname in files: + if is_ignored(fname, ign_dirs): + results_ign.append(fname) continue - diff = check_file(cfg_fname, commit, upstream) - if len(diff) > 0: - print(f"\033[31m! See {coding_style_url} for details.\033[0m") - print() - print(f"\033[31m! {cfg_fname}\033[0m") - print() - print("\n".join(diff)) - print() - has_error = True + diff = check_file(fname, commit, upstream) + if len(diff) == 0: + results_ok.append(fname) else: - print(f"+ {cfg_fname}") - - return not has_error + results_fail.append((fname, diff)) + + for fname in results_ign: + print(f"\033[90m[ NA ] {fname}\033[0m") + for fname in results_ok: + print(f"\033[32m[ OK ] {fname}\033[0m") + for fname, diff in results_fail: + print(f"\033[31m[FAIL] {fname}\033[0m") + print("\n".join(diff)) + print() + + if len(results_fail) > 0: + print(f"\033[31mYour code has style problems, see {INFO_URL} for " + f"details.\033[0m") + + return len(results_fail) == 0 if __name__ == "__main__": From 8be739d0c313d4bc1d5996f77ef680d17ab86661 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 27 Jan 2023 13:32:58 +0100 Subject: [PATCH 0629/1333] nimble/phy: Rework phy encryption API This splits encryption API into smaller functions. We start encryption with a common key, they have to set IV (which can be different for each subevent) and also counter/dir_bit. --- .../controller/include/controller/ble_phy.h | 11 ++--- nimble/controller/src/ble_ll_conn.c | 46 +++++++++---------- nimble/drivers/dialog_cmac/src/ble_phy.c | 28 ++++++----- nimble/drivers/native/src/ble_phy.c | 20 +++----- nimble/drivers/nrf51/src/ble_phy.c | 28 ++++------- nimble/drivers/nrf5x/src/ble_phy.c | 29 ++++-------- 6 files changed, 70 insertions(+), 92 deletions(-) diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index 35ef87edb2..9b3a57b9f7 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -160,15 +160,14 @@ uint8_t ble_phy_max_data_pdu_pyld(void); uint32_t ble_phy_access_addr_get(void); /* Enable encryption */ -void ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key, - uint8_t is_central); - +void ble_phy_encrypt_enable(const uint8_t *key); +/* Set encryption IV */ +void ble_phy_encrypt_iv_set(const uint8_t *iv); +/* Set encryption packet counter and direction bit */ +void ble_phy_encrypt_counter_set(uint64_t counter, uint8_t dir_bit); /* Disable encryption */ void ble_phy_encrypt_disable(void); -/* Set the packet counters and dir used by LE encyption */ -void ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir); - /* Enable phy resolving list */ void ble_phy_resolv_list_enable(void); diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 379a59a750..5b88d3ef1e 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -859,10 +859,10 @@ ble_ll_conn_start_rx_encrypt(void *arg) connsm = (struct ble_ll_conn_sm *)arg; CONN_F_ENCRYPTED(connsm) = 1; - ble_phy_encrypt_enable(connsm->enc_data.rx_pkt_cntr, - connsm->enc_data.iv, - connsm->enc_data.enc_block.cipher_text, - !CONN_IS_CENTRAL(connsm)); + ble_phy_encrypt_enable(connsm->enc_data.enc_block.cipher_text); + ble_phy_encrypt_iv_set(connsm->enc_data.iv); + ble_phy_encrypt_counter_set(connsm->enc_data.rx_pkt_cntr, + !CONN_IS_CENTRAL(connsm)); } #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) @@ -905,8 +905,8 @@ ble_ll_conn_continue_rx_encrypt(void *arg) struct ble_ll_conn_sm *connsm; connsm = (struct ble_ll_conn_sm *)arg; - ble_phy_encrypt_set_pkt_cntr(connsm->enc_data.rx_pkt_cntr, - !CONN_IS_CENTRAL(connsm)); + ble_phy_encrypt_counter_set(connsm->enc_data.rx_pkt_cntr, + !CONN_IS_CENTRAL(connsm)); } #endif @@ -1362,10 +1362,10 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) */ CONN_F_ENCRYPTED(connsm) = 1; connsm->enc_data.tx_encrypted = 1; - ble_phy_encrypt_enable(connsm->enc_data.tx_pkt_cntr, - connsm->enc_data.iv, - connsm->enc_data.enc_block.cipher_text, - CONN_IS_CENTRAL(connsm)); + ble_phy_encrypt_enable(connsm->enc_data.enc_block.cipher_text); + ble_phy_encrypt_iv_set(connsm->enc_data.iv); + ble_phy_encrypt_counter_set(connsm->enc_data.tx_pkt_cntr, + CONN_IS_CENTRAL(connsm)); } else if (is_ctrl && (opcode == BLE_LL_CTRL_START_ENC_REQ)) { /* * Only the peripheral sends this and it gets sent unencrypted but @@ -1398,10 +1398,10 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) case BLE_LL_CONN_ROLE_PERIPHERAL: CONN_F_ENCRYPTED(connsm) = 1; connsm->enc_data.tx_encrypted = 1; - ble_phy_encrypt_enable(connsm->enc_data.tx_pkt_cntr, - connsm->enc_data.iv, - connsm->enc_data.enc_block.cipher_text, - CONN_IS_CENTRAL(connsm)); + ble_phy_encrypt_enable(connsm->enc_data.enc_block.cipher_text); + ble_phy_encrypt_iv_set(connsm->enc_data.iv); + ble_phy_encrypt_counter_set(connsm->enc_data.tx_pkt_cntr, + CONN_IS_CENTRAL(connsm)); if (txend_func == NULL) { txend_func = ble_ll_conn_start_rx_unencrypt; } else { @@ -1417,8 +1417,8 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) /* If encrypted set packet counter */ if (CONN_F_ENCRYPTED(connsm)) { connsm->enc_data.tx_encrypted = 1; - ble_phy_encrypt_set_pkt_cntr(connsm->enc_data.tx_pkt_cntr, - CONN_IS_CENTRAL(connsm)); + ble_phy_encrypt_counter_set(connsm->enc_data.tx_pkt_cntr, + CONN_IS_CENTRAL(connsm)); if (txend_func == NULL) { txend_func = ble_ll_conn_continue_rx_encrypt; } @@ -1526,10 +1526,9 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) if (!rc) { #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) if (CONN_F_ENCRYPTED(connsm)) { - ble_phy_encrypt_enable(connsm->enc_data.tx_pkt_cntr, - connsm->enc_data.iv, - connsm->enc_data.enc_block.cipher_text, - 1); + ble_phy_encrypt_enable(connsm->enc_data.enc_block.cipher_text); + ble_phy_encrypt_iv_set(connsm->enc_data.iv); + ble_phy_encrypt_counter_set(connsm->enc_data.tx_pkt_cntr, 1); } else { ble_phy_encrypt_disable(); } @@ -1551,10 +1550,9 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) case BLE_LL_CONN_ROLE_PERIPHERAL: #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) if (CONN_F_ENCRYPTED(connsm)) { - ble_phy_encrypt_enable(connsm->enc_data.rx_pkt_cntr, - connsm->enc_data.iv, - connsm->enc_data.enc_block.cipher_text, - 1); + ble_phy_encrypt_enable(connsm->enc_data.enc_block.cipher_text); + ble_phy_encrypt_iv_set(connsm->enc_data.iv); + ble_phy_encrypt_counter_set(connsm->enc_data.rx_pkt_cntr, 1); } else { ble_phy_encrypt_disable(); } diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index b7e4818c2c..a1ba306129 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -1598,19 +1598,12 @@ ble_phy_rx_enc_start(uint8_t len) } void -ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key, - uint8_t is_master) +ble_phy_encrypt_enable(const uint8_t *key) { struct ble_phy_encrypt_obj *enc; enc = &g_ble_phy_encrypt_data; memcpy(enc->key, key, 16); - memcpy(&enc->b0[6], iv, 8); - put_le32(&enc->b0[1], pkt_counter); - enc->b0[5] = is_master ? 0x80 : 0; - memcpy(&enc->ai[6], iv, 8); - put_le32(&enc->ai[1], pkt_counter); - enc->ai[5] = enc->b0[5]; g_ble_phy_data.phy_encrypted = 1; @@ -1631,14 +1624,25 @@ ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key, } void -ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir) +ble_phy_encrypt_iv_set(const uint8_t *iv) +{ + struct ble_phy_encrypt_obj *enc; + + enc = &g_ble_phy_encrypt_data; + memcpy(&enc->b0[6], iv, 8); + memcpy(&enc->ai[6], iv, 8); +} + + +void +ble_phy_encrypt_counter_set(uint64_t counter, uint8_t dir_bit) { struct ble_phy_encrypt_obj *enc; enc = &g_ble_phy_encrypt_data; - put_le32(&enc->b0[1], pkt_counter); - enc->b0[5] = dir ? 0x80 : 0; - put_le32(&enc->ai[1], pkt_counter); + put_le32(&enc->b0[1], counter); + enc->b0[5] = dir_bit ? 0x80 : 0; + put_le32(&enc->ai[1], counter); enc->ai[5] = enc->b0[5]; CMAC->CM_CRYPTO_CTRL_REG = CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_SW_REQ_PBUF_CLR_Msk; diff --git a/nimble/drivers/native/src/ble_phy.c b/nimble/drivers/native/src/ble_phy.c index 410b9ce602..7635621c6b 100644 --- a/nimble/drivers/native/src/ble_phy.c +++ b/nimble/drivers/native/src/ble_phy.c @@ -342,24 +342,18 @@ ble_phy_restart_rx(void) } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -/** - * Called to enable encryption at the PHY. Note that this state will persist - * in the PHY; in other words, if you call this function you have to call - * disable so that future PHY transmits/receives will not be encrypted. - * - * @param pkt_counter - * @param iv - * @param key - * @param is_master - */ void -ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key, - uint8_t is_master) +ble_phy_encrypt_enable(const uint8_t *key) +{ +} + +void +ble_phy_encrypt_iv_set(const uint8_t *iv) { } void -ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir) +ble_phy_encrypt_counter_set(uint64_t counter, uint8_t dir_bit) { } diff --git a/nimble/drivers/nrf51/src/ble_phy.c b/nimble/drivers/nrf51/src/ble_phy.c index cfcfb7ec36..f35c778121 100644 --- a/nimble/drivers/nrf51/src/ble_phy.c +++ b/nimble/drivers/nrf51/src/ble_phy.c @@ -983,24 +983,10 @@ ble_phy_rx(void) } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -/** - * Called to enable encryption at the PHY. Note that this state will persist - * in the PHY; in other words, if you call this function you have to call - * disable so that future PHY transmits/receives will not be encrypted. - * - * @param pkt_counter - * @param iv - * @param key - * @param is_master - */ void -ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key, - uint8_t is_master) +ble_phy_encrypt_enable(const uint8_t *key) { memcpy(g_nrf_ccm_data.key, key, 16); - g_nrf_ccm_data.pkt_counter = pkt_counter; - memcpy(g_nrf_ccm_data.iv, iv, 8); - g_nrf_ccm_data.dir_bit = is_master; g_ble_phy_data.phy_encrypted = 1; /* Encryption uses LFLEN=5, S1LEN = 3. */ @@ -1014,10 +1000,16 @@ ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key, } void -ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir) +ble_phy_encrypt_iv_set(const uint8_t *iv) +{ + memcpy(g_nrf_ccm_data.iv, iv, 8); +} + +void +ble_phy_encrypt_counter_set(uint64_t counter, uint8_t dir_bit) { - g_nrf_ccm_data.pkt_counter = pkt_counter; - g_nrf_ccm_data.dir_bit = dir; + g_nrf_ccm_data.pkt_counter = counter; + g_nrf_ccm_data.dir_bit = dir_bit; } void diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 0663eba76a..d4fe0a512e 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -1676,35 +1676,26 @@ ble_phy_rx(void) } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -/** - * Called to enable encryption at the PHY. Note that this state will persist - * in the PHY; in other words, if you call this function you have to call - * disable so that future PHY transmits/receives will not be encrypted. - * - * @param pkt_counter - * @param iv - * @param key - * @param is_master - */ void -ble_phy_encrypt_enable(uint64_t pkt_counter, uint8_t *iv, uint8_t *key, - uint8_t is_master) +ble_phy_encrypt_enable(const uint8_t *key) { memcpy(g_nrf_ccm_data.key, key, 16); - g_nrf_ccm_data.pkt_counter = pkt_counter; - memcpy(g_nrf_ccm_data.iv, iv, 8); - g_nrf_ccm_data.dir_bit = is_master; g_ble_phy_data.phy_encrypted = 1; - /* Enable the module (AAR cannot be on while CCM on) */ NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Disabled; NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled; } void -ble_phy_encrypt_set_pkt_cntr(uint64_t pkt_counter, int dir) +ble_phy_encrypt_iv_set(const uint8_t *iv) +{ + memcpy(g_nrf_ccm_data.iv, iv, 8); +} + +void +ble_phy_encrypt_counter_set(uint64_t counter, uint8_t dir_bit) { - g_nrf_ccm_data.pkt_counter = pkt_counter; - g_nrf_ccm_data.dir_bit = dir; + g_nrf_ccm_data.pkt_counter = counter; + g_nrf_ccm_data.dir_bit = dir_bit; } void From 20198fae319842e445cfb24cc5038ccb877be41e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 21 Jan 2023 00:49:50 +0100 Subject: [PATCH 0630/1333] nimble/phy: Add API to set ifs for tx-tx transition TX-TX transition is kind of special since we'll use it e.g. for ISO to achieve proper spacing between subevents thus we want to be able to control time between start of PDUs. --- .../controller/include/controller/ble_phy.h | 4 +++ nimble/drivers/nrf5x/src/ble_phy.c | 28 +++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index 9b3a57b9f7..902ac0342c 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -92,6 +92,10 @@ int ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit); void ble_phy_tifs_set(uint16_t tifs); #endif +/* Set T_ifs for tx-tx transitions. Anchor is 0 for start of previous PDU, + * non-zero for end of PDU */ +void ble_phy_tifs_txtx_set(uint16_t usecs, uint8_t anchor); + /* Set transmit start time */ int ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs); diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index d4fe0a512e..3cdae5c511 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -68,6 +68,8 @@ extern void tm_tick(void); #endif +#include + /* * NOTE: This code uses a couple of PPI channels so care should be taken when * using PPI somewhere else. @@ -153,6 +155,9 @@ struct ble_phy_obj #if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) uint16_t tifs; #endif + + uint16_t txtx_time_us; + uint8_t txtx_time_anchor; }; static struct ble_phy_obj g_ble_phy_data; @@ -1092,8 +1097,20 @@ ble_phy_tx_end_isr(void) * case we still rxd something, so perhaps we could check it here */ } else if (transition == BLE_PHY_TRANSITION_TX_TX) { - /* Schedule TX exactly T_IFS after TX end captured in CC[2] */ - tx_time = NRF_TIMER0->CC[2] + tifs; + if (g_ble_phy_data.txtx_time_anchor) { + /* Schedule next TX relative to current TX end. TX end timestamp is + * captured in CC[2]. + */ + tx_time = NRF_TIMER0->CC[2] + g_ble_phy_data.txtx_time_us; + } else { + /* Schedule next TX relative to current TX start. AA timestamp is + * captured in CC[1], we need to adjust for sync word to get TX + * start. + */ + tx_time = NRF_TIMER0->CC[1] - ble_ll_pdu_syncword_us(tx_phy_mode) + + g_ble_phy_data.txtx_time_us; + } + /* Adjust for delay between EVENT_END and actual TX end time */ tx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; @@ -2228,3 +2245,10 @@ ble_phy_rfclk_disable(void) nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP); #endif } + +void +ble_phy_tifs_txtx_set(uint16_t usecs, uint8_t anchor) +{ + g_ble_phy_data.txtx_time_us = usecs; + g_ble_phy_data.txtx_time_anchor = anchor; +} From bc1662c95f7d83dfe2925b327a3bba94d58928d0 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 27 Jan 2023 11:33:07 +0100 Subject: [PATCH 0631/1333] nimble/phy/nrf53: Clean state on phy disable --- nimble/drivers/nrf5x/src/ble_phy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 3cdae5c511..1e5fc5c3f5 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -2126,6 +2126,8 @@ ble_phy_disable(void) ble_phy_stop_usec_timer(); ble_phy_disable_irq_and_ppi(); + g_ble_phy_data.phy_transition_late = 0; + #if PHY_USE_FEM phy_fem_disable(); #endif From f740c39b66697a187f0ad2e1431301e23228cb1e Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 30 Jan 2023 09:40:42 +0100 Subject: [PATCH 0632/1333] targets: Restore example targets Those were accidentally moved to CI targets but are expected to be used by users. --- .../targets/nordic_pca10028_blehci/pkg.yml | 4 +-- .github/targets/nordic_pca10028_boot/pkg.yml | 4 +-- .../nordic_pca10028_bt5_blehci/pkg.yml | 4 +-- .../nordic_pca10056-blehci-usb/pkg.yml | 2 +- .../nordic_pca10056_advertiser/pkg.yml | 2 +- .../targets/nordic_pca10056_blecent/pkg.yml | 2 +- .../targets/nordic_pca10056_blecsc/pkg.yml | 2 +- .../targets/nordic_pca10056_blehci/pkg.yml | 2 +- .../pkg.yml | 2 +- .../nordic_pca10056_blehci_no_privacy/pkg.yml | 2 +- .github/targets/nordic_pca10056_blehr/pkg.yml | 2 +- .../targets/nordic_pca10056_blemesh/pkg.yml | 2 +- .../nordic_pca10056_blemesh_cdb/pkg.yml | 2 +- .../nordic_pca10056_blemesh_ext_adv/pkg.yml | 2 +- .../nordic_pca10056_blemesh_light/pkg.yml | 2 +- .../pkg.yml | 2 +- .../pkg.yml | 2 +- .../nordic_pca10056_blemesh_shell/pkg.yml | 2 +- .../nordic_pca10056_blemesh_storage/pkg.yml | 2 +- .../targets/nordic_pca10056_bleprph/pkg.yml | 2 +- .../nordic_pca10056_bleprph_oic/pkg.yml | 2 +- .../targets/nordic_pca10056_blesplit/pkg.yml | 2 +- .../targets/nordic_pca10056_bleuart/pkg.yml | 2 +- .../targets/nordic_pca10056_btshell/pkg.yml | 4 +-- .../nordic_pca10056_btshell_2M/pkg.yml | 2 +- .../nordic_pca10056_btshell_2M_coded/pkg.yml | 2 +- .../nordic_pca10056_btshell_all/pkg.yml | 4 +-- .../nordic_pca10056_btshell_all_v52/pkg.yml | 4 +-- .../nordic_pca10056_btshell_coded/pkg.yml | 2 +- .../nordic_pca10056_btshell_ext_adv/pkg.yml | 2 +- .../pkg.yml | 2 +- .../nordic_pca10056_btshell_sm_legacy/pkg.yml | 2 +- .../nordic_pca10056_btshell_sm_none/pkg.yml | 2 +- .../nordic_pca10056_btshell_sm_sc/pkg.yml | 2 +- .../pkg.yml | 2 +- .../pkg.yml | 4 +-- .../targets/nordic_pca10056_bttester/pkg.yml | 4 +-- .../nordic_pca10056_ext_advertiser/pkg.yml | 4 +-- .../targets/nordic_pca10056_scanner/pkg.yml | 2 +- .../targets/nordic_pca10095_blehci/pkg.yml | 4 +-- .../targets/nordic_pca10095_btshell/pkg.yml | 4 +-- .github/targets_native/native_btshell/pkg.yml | 2 +- .github/workflows/build_targets.yml | 12 ++++----- .../targets => targets}/dialog_cmac/pkg.yml | 0 .../dialog_cmac/syscfg.yml | 0 .../dialog_cmac/target.yml | 0 targets/nordic_pca10056-blehci-usb/pkg.yml | 27 +++++++++++++++++++ targets/nordic_pca10056-blehci-usb/syscfg.yml | 24 +++++++++++++++++ targets/nordic_pca10056-blehci-usb/target.yml | 21 +++++++++++++++ .../nordic_pca10095_net-blehci/pkg.yml | 0 .../nordic_pca10095_net-blehci/syscfg.yml | 0 .../nordic_pca10095_net-blehci/target.yml | 0 52 files changed, 131 insertions(+), 59 deletions(-) rename {.github/targets => targets}/dialog_cmac/pkg.yml (100%) rename {.github/targets => targets}/dialog_cmac/syscfg.yml (100%) rename {.github/targets => targets}/dialog_cmac/target.yml (100%) create mode 100644 targets/nordic_pca10056-blehci-usb/pkg.yml create mode 100644 targets/nordic_pca10056-blehci-usb/syscfg.yml create mode 100644 targets/nordic_pca10056-blehci-usb/target.yml rename {.github/targets => targets}/nordic_pca10095_net-blehci/pkg.yml (100%) rename {.github/targets => targets}/nordic_pca10095_net-blehci/syscfg.yml (100%) rename {.github/targets => targets}/nordic_pca10095_net-blehci/target.yml (100%) diff --git a/.github/targets/nordic_pca10028_blehci/pkg.yml b/.github/targets/nordic_pca10028_blehci/pkg.yml index a1365ea75e..b3504c3d90 100644 --- a/.github/targets/nordic_pca10028_blehci/pkg.yml +++ b/.github/targets/nordic_pca10028_blehci/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: targets/blehci-nordic_pca10028 -pkg.name: "targets/nordic_pca10028_blehci" +### Package: "targets_ci/blehci-nordic_pca10028 +pkg.name: "targets_ci/nordic_pca10028_blehci" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10028_boot/pkg.yml b/.github/targets/nordic_pca10028_boot/pkg.yml index ab6ff0c919..6cf0c922e3 100644 --- a/.github/targets/nordic_pca10028_boot/pkg.yml +++ b/.github/targets/nordic_pca10028_boot/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: targets/nordic_pca10028_boot -pkg.name: "targets/nordic_pca10028_boot" +### Package: "targets_ci/nordic_pca10028_boot +pkg.name: "targets_ci/nordic_pca10028_boot" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10028_bt5_blehci/pkg.yml b/.github/targets/nordic_pca10028_bt5_blehci/pkg.yml index e7bd2e0761..80774bfd45 100644 --- a/.github/targets/nordic_pca10028_bt5_blehci/pkg.yml +++ b/.github/targets/nordic_pca10028_bt5_blehci/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: targets/nordic_pca10028_bt5_blehci -pkg.name: "targets/nordic_pca10028_bt5_blehci" +### Package: "targets_ci/nordic_pca10028_bt5_blehci +pkg.name: "targets_ci/nordic_pca10028_bt5_blehci" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056-blehci-usb/pkg.yml b/.github/targets/nordic_pca10056-blehci-usb/pkg.yml index 2c8307d3df..4f92d9b96a 100644 --- a/.github/targets/nordic_pca10056-blehci-usb/pkg.yml +++ b/.github/targets/nordic_pca10056-blehci-usb/pkg.yml @@ -16,7 +16,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056-blehci-usb" +pkg.name: "targets_ci/nordic_pca10056-blehci-usb" pkg.type: target pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_advertiser/pkg.yml b/.github/targets/nordic_pca10056_advertiser/pkg.yml index 84d0c05b34..6de3362b52 100644 --- a/.github/targets/nordic_pca10056_advertiser/pkg.yml +++ b/.github/targets/nordic_pca10056_advertiser/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_advertiser" +pkg.name: "targets_ci/nordic_pca10056_advertiser" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_blecent/pkg.yml b/.github/targets/nordic_pca10056_blecent/pkg.yml index d47c0544da..64dbe8b51a 100644 --- a/.github/targets/nordic_pca10056_blecent/pkg.yml +++ b/.github/targets/nordic_pca10056_blecent/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_blecent" +pkg.name: "targets_ci/nordic_pca10056_blecent" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_blecsc/pkg.yml b/.github/targets/nordic_pca10056_blecsc/pkg.yml index f26c7df69a..65a125ca35 100644 --- a/.github/targets/nordic_pca10056_blecsc/pkg.yml +++ b/.github/targets/nordic_pca10056_blecsc/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_blecsc" +pkg.name: "targets_ci/nordic_pca10056_blecsc" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_blehci/pkg.yml b/.github/targets/nordic_pca10056_blehci/pkg.yml index b66dab9879..204f4a5f36 100644 --- a/.github/targets/nordic_pca10056_blehci/pkg.yml +++ b/.github/targets/nordic_pca10056_blehci/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_blehci" +pkg.name: "targets_ci/nordic_pca10056_blehci" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_blehci_all_enabled/pkg.yml b/.github/targets/nordic_pca10056_blehci_all_enabled/pkg.yml index c44ac2824a..6ede68c23a 100644 --- a/.github/targets/nordic_pca10056_blehci_all_enabled/pkg.yml +++ b/.github/targets/nordic_pca10056_blehci_all_enabled/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_blehci_all_enabled" +pkg.name: "targets_ci/nordic_pca10056_blehci_all_enabled" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_blehci_no_privacy/pkg.yml b/.github/targets/nordic_pca10056_blehci_no_privacy/pkg.yml index 539a36409e..ed7e725dd1 100644 --- a/.github/targets/nordic_pca10056_blehci_no_privacy/pkg.yml +++ b/.github/targets/nordic_pca10056_blehci_no_privacy/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_blehci_no_privacy" +pkg.name: "targets_ci/nordic_pca10056_blehci_no_privacy" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_blehr/pkg.yml b/.github/targets/nordic_pca10056_blehr/pkg.yml index fd7e6fa90d..aa37aa0e1c 100644 --- a/.github/targets/nordic_pca10056_blehr/pkg.yml +++ b/.github/targets/nordic_pca10056_blehr/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_blehr" +pkg.name: "targets_ci/nordic_pca10056_blehr" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_blemesh/pkg.yml b/.github/targets/nordic_pca10056_blemesh/pkg.yml index b1785b01b5..04f35835ae 100644 --- a/.github/targets/nordic_pca10056_blemesh/pkg.yml +++ b/.github/targets/nordic_pca10056_blemesh/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_blemesh" +pkg.name: "targets_ci/nordic_pca10056_blemesh" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_blemesh_cdb/pkg.yml b/.github/targets/nordic_pca10056_blemesh_cdb/pkg.yml index 2a85a98817..1c059a402e 100644 --- a/.github/targets/nordic_pca10056_blemesh_cdb/pkg.yml +++ b/.github/targets/nordic_pca10056_blemesh_cdb/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_blemesh_cdb" +pkg.name: "targets_ci/nordic_pca10056_blemesh_cdb" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_blemesh_ext_adv/pkg.yml b/.github/targets/nordic_pca10056_blemesh_ext_adv/pkg.yml index 3fec50f689..1f8c88d3b8 100644 --- a/.github/targets/nordic_pca10056_blemesh_ext_adv/pkg.yml +++ b/.github/targets/nordic_pca10056_blemesh_ext_adv/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_blemesh_ext_adv" +pkg.name: "targets_ci/nordic_pca10056_blemesh_ext_adv" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_blemesh_light/pkg.yml b/.github/targets/nordic_pca10056_blemesh_light/pkg.yml index 991cccfd73..cfb98f674a 100644 --- a/.github/targets/nordic_pca10056_blemesh_light/pkg.yml +++ b/.github/targets/nordic_pca10056_blemesh_light/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_blemesh_light" +pkg.name: "targets_ci/nordic_pca10056_blemesh_light" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_blemesh_models_example_1/pkg.yml b/.github/targets/nordic_pca10056_blemesh_models_example_1/pkg.yml index 38c54781ae..68b8325b87 100644 --- a/.github/targets/nordic_pca10056_blemesh_models_example_1/pkg.yml +++ b/.github/targets/nordic_pca10056_blemesh_models_example_1/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_blemesh_models_example_1" +pkg.name: "targets_ci/nordic_pca10056_blemesh_models_example_1" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_blemesh_models_example_2/pkg.yml b/.github/targets/nordic_pca10056_blemesh_models_example_2/pkg.yml index b17b652583..2944216a51 100644 --- a/.github/targets/nordic_pca10056_blemesh_models_example_2/pkg.yml +++ b/.github/targets/nordic_pca10056_blemesh_models_example_2/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_blemesh_models_example_2" +pkg.name: "targets_ci/nordic_pca10056_blemesh_models_example_2" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_blemesh_shell/pkg.yml b/.github/targets/nordic_pca10056_blemesh_shell/pkg.yml index 4636feb41a..e0bb36a941 100644 --- a/.github/targets/nordic_pca10056_blemesh_shell/pkg.yml +++ b/.github/targets/nordic_pca10056_blemesh_shell/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_blemesh_shell" +pkg.name: "targets_ci/nordic_pca10056_blemesh_shell" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_blemesh_storage/pkg.yml b/.github/targets/nordic_pca10056_blemesh_storage/pkg.yml index ff17acfcc0..7a04e49ac5 100644 --- a/.github/targets/nordic_pca10056_blemesh_storage/pkg.yml +++ b/.github/targets/nordic_pca10056_blemesh_storage/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_blemesh_storage" +pkg.name: "targets_ci/nordic_pca10056_blemesh_storage" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_bleprph/pkg.yml b/.github/targets/nordic_pca10056_bleprph/pkg.yml index d1e7b95eea..4beaa1fca0 100644 --- a/.github/targets/nordic_pca10056_bleprph/pkg.yml +++ b/.github/targets/nordic_pca10056_bleprph/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_bleprph" +pkg.name: "targets_ci/nordic_pca10056_bleprph" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_bleprph_oic/pkg.yml b/.github/targets/nordic_pca10056_bleprph_oic/pkg.yml index aef9c2eb2e..2c2f231e58 100644 --- a/.github/targets/nordic_pca10056_bleprph_oic/pkg.yml +++ b/.github/targets/nordic_pca10056_bleprph_oic/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_bleprph_oic" +pkg.name: "targets_ci/nordic_pca10056_bleprph_oic" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_blesplit/pkg.yml b/.github/targets/nordic_pca10056_blesplit/pkg.yml index 8781b07ae0..d62ab79c46 100644 --- a/.github/targets/nordic_pca10056_blesplit/pkg.yml +++ b/.github/targets/nordic_pca10056_blesplit/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_blesplit" +pkg.name: "targets_ci/nordic_pca10056_blesplit" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_bleuart/pkg.yml b/.github/targets/nordic_pca10056_bleuart/pkg.yml index f3f3ce922d..0ae1073dec 100644 --- a/.github/targets/nordic_pca10056_bleuart/pkg.yml +++ b/.github/targets/nordic_pca10056_bleuart/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_bleuart" +pkg.name: "targets_ci/nordic_pca10056_bleuart" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_btshell/pkg.yml b/.github/targets/nordic_pca10056_btshell/pkg.yml index 9049e01390..287ca4e3c3 100644 --- a/.github/targets/nordic_pca10056_btshell/pkg.yml +++ b/.github/targets/nordic_pca10056_btshell/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: targets/nordic_pca10056_btshell -pkg.name: "targets/nordic_pca10056_btshell" +### Package: "targets_ci/nordic_pca10056_btshell +pkg.name: "targets_ci/nordic_pca10056_btshell" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_btshell_2M/pkg.yml b/.github/targets/nordic_pca10056_btshell_2M/pkg.yml index fc2db1d019..e555575641 100644 --- a/.github/targets/nordic_pca10056_btshell_2M/pkg.yml +++ b/.github/targets/nordic_pca10056_btshell_2M/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_btshell_2M" +pkg.name: "targets_ci/nordic_pca10056_btshell_2M" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_btshell_2M_coded/pkg.yml b/.github/targets/nordic_pca10056_btshell_2M_coded/pkg.yml index 0ddee925fb..a0b8ad888a 100644 --- a/.github/targets/nordic_pca10056_btshell_2M_coded/pkg.yml +++ b/.github/targets/nordic_pca10056_btshell_2M_coded/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_btshell_2M_coded" +pkg.name: "targets_ci/nordic_pca10056_btshell_2M_coded" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_btshell_all/pkg.yml b/.github/targets/nordic_pca10056_btshell_all/pkg.yml index 2a18f7030d..5ac5cc77d9 100644 --- a/.github/targets/nordic_pca10056_btshell_all/pkg.yml +++ b/.github/targets/nordic_pca10056_btshell_all/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: targets/nordic_pca10056_btshell_all -pkg.name: "targets/nordic_pca10056_btshell_all" +### Package: "targets_ci/nordic_pca10056_btshell_all +pkg.name: "targets_ci/nordic_pca10056_btshell_all" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_btshell_all_v52/pkg.yml b/.github/targets/nordic_pca10056_btshell_all_v52/pkg.yml index 14d5fc6942..e218c511c1 100644 --- a/.github/targets/nordic_pca10056_btshell_all_v52/pkg.yml +++ b/.github/targets/nordic_pca10056_btshell_all_v52/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: targets/nordic_pca10056_btshell_all_v52 -pkg.name: "targets/nordic_pca10056_btshell_all_v52" +### Package: "targets_ci/nordic_pca10056_btshell_all_v52 +pkg.name: "targets_ci/nordic_pca10056_btshell_all_v52" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_btshell_coded/pkg.yml b/.github/targets/nordic_pca10056_btshell_coded/pkg.yml index c3ec70a308..87a1eb64cf 100644 --- a/.github/targets/nordic_pca10056_btshell_coded/pkg.yml +++ b/.github/targets/nordic_pca10056_btshell_coded/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_btshell_coded" +pkg.name: "targets_ci/nordic_pca10056_btshell_coded" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_btshell_ext_adv/pkg.yml b/.github/targets/nordic_pca10056_btshell_ext_adv/pkg.yml index c8cce29975..b39ebae190 100644 --- a/.github/targets/nordic_pca10056_btshell_ext_adv/pkg.yml +++ b/.github/targets/nordic_pca10056_btshell_ext_adv/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_btshell_ext_adv" +pkg.name: "targets_ci/nordic_pca10056_btshell_ext_adv" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_btshell_periodic_adv/pkg.yml b/.github/targets/nordic_pca10056_btshell_periodic_adv/pkg.yml index b4f519e241..3a3a7d1eb3 100644 --- a/.github/targets/nordic_pca10056_btshell_periodic_adv/pkg.yml +++ b/.github/targets/nordic_pca10056_btshell_periodic_adv/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_btshell_periodic_adv" +pkg.name: "targets_ci/nordic_pca10056_btshell_periodic_adv" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_btshell_sm_legacy/pkg.yml b/.github/targets/nordic_pca10056_btshell_sm_legacy/pkg.yml index 4c3d331ebe..79dbec4447 100644 --- a/.github/targets/nordic_pca10056_btshell_sm_legacy/pkg.yml +++ b/.github/targets/nordic_pca10056_btshell_sm_legacy/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_btshell_sm_legacy" +pkg.name: "targets_ci/nordic_pca10056_btshell_sm_legacy" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_btshell_sm_none/pkg.yml b/.github/targets/nordic_pca10056_btshell_sm_none/pkg.yml index a8ccee1f45..1061c2fa83 100644 --- a/.github/targets/nordic_pca10056_btshell_sm_none/pkg.yml +++ b/.github/targets/nordic_pca10056_btshell_sm_none/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_btshell_sm_none" +pkg.name: "targets_ci/nordic_pca10056_btshell_sm_none" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_btshell_sm_sc/pkg.yml b/.github/targets/nordic_pca10056_btshell_sm_sc/pkg.yml index 611096aa36..0de1653943 100644 --- a/.github/targets/nordic_pca10056_btshell_sm_sc/pkg.yml +++ b/.github/targets/nordic_pca10056_btshell_sm_sc/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_btshell_sm_sc" +pkg.name: "targets_ci/nordic_pca10056_btshell_sm_sc" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml b/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml index 3983ec0cae..e75836015e 100644 --- a/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml +++ b/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_btshell_sm_sc_legacy" +pkg.name: "targets_ci/nordic_pca10056_btshell_sm_sc_legacy" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_btshell_xtal_settle_0/pkg.yml b/.github/targets/nordic_pca10056_btshell_xtal_settle_0/pkg.yml index 19a580e193..2dde3239c3 100644 --- a/.github/targets/nordic_pca10056_btshell_xtal_settle_0/pkg.yml +++ b/.github/targets/nordic_pca10056_btshell_xtal_settle_0/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: targets/nordic_pca10056_btshell_xtal_settle_0 -pkg.name: "targets/nordic_pca10056_btshell_xtal_settle_0" +### Package: "targets_ci/nordic_pca10056_btshell_xtal_settle_0 +pkg.name: "targets_ci/nordic_pca10056_btshell_xtal_settle_0" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_bttester/pkg.yml b/.github/targets/nordic_pca10056_bttester/pkg.yml index d50d245c38..5f72b58da8 100644 --- a/.github/targets/nordic_pca10056_bttester/pkg.yml +++ b/.github/targets/nordic_pca10056_bttester/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: targets/nordic_pca10056_bttester -pkg.name: "targets/nordic_pca10056_bttester" +### Package: "targets_ci/nordic_pca10056_bttester +pkg.name: "targets_ci/nordic_pca10056_bttester" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_ext_advertiser/pkg.yml b/.github/targets/nordic_pca10056_ext_advertiser/pkg.yml index 7dee435744..7a196568ee 100644 --- a/.github/targets/nordic_pca10056_ext_advertiser/pkg.yml +++ b/.github/targets/nordic_pca10056_ext_advertiser/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: targets/nordic_pca10056_btshell -pkg.name: "targets/nordic_pca10056_ext_advertiser" +### Package: "targets_ci/nordic_pca10056_btshell +pkg.name: "targets_ci/nordic_pca10056_ext_advertiser" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_scanner/pkg.yml b/.github/targets/nordic_pca10056_scanner/pkg.yml index dfc3c8b015..04b210a878 100644 --- a/.github/targets/nordic_pca10056_scanner/pkg.yml +++ b/.github/targets/nordic_pca10056_scanner/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets/nordic_pca10056_scanner" +pkg.name: "targets_ci/nordic_pca10056_scanner" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10095_blehci/pkg.yml b/.github/targets/nordic_pca10095_blehci/pkg.yml index 04841c9472..2cb827ecb4 100644 --- a/.github/targets/nordic_pca10095_blehci/pkg.yml +++ b/.github/targets/nordic_pca10095_blehci/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: targets/blehci-nordic_pca10095 -pkg.name: "targets/nordic_pca10095_blehci" +### Package: "targets_ci/blehci-nordic_pca10095 +pkg.name: "targets_ci/nordic_pca10095_blehci" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10095_btshell/pkg.yml b/.github/targets/nordic_pca10095_btshell/pkg.yml index cfcc43dfff..889405d345 100644 --- a/.github/targets/nordic_pca10095_btshell/pkg.yml +++ b/.github/targets/nordic_pca10095_btshell/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: targets/nordic_pca10056_btshell -pkg.name: "targets/nordic_pca10095_btshell" +### Package: "targets_ci/nordic_pca10056_btshell +pkg.name: "targets_ci/nordic_pca10095_btshell" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_native/native_btshell/pkg.yml b/.github/targets_native/native_btshell/pkg.yml index a252525536..870ccae9ca 100644 --- a/.github/targets_native/native_btshell/pkg.yml +++ b/.github/targets_native/native_btshell/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: targets/native_btshell +pkg.name: targets_ci/native_btshell pkg.type: target pkg.description: pkg.author: diff --git a/.github/workflows/build_targets.yml b/.github/workflows/build_targets.yml index 16ea8aac63..c14f8da18e 100644 --- a/.github/workflows/build_targets.yml +++ b/.github/workflows/build_targets.yml @@ -57,12 +57,12 @@ jobs: - name: Build targets shell: bash run: | - cp -r .github/targets ci_targets - ls ci_targets | xargs -n1 sh -c 'echo "Testing $0"; newt build -q $0' - rm -rf ci_targets + cp -r .github/targets targets_ci + ls targets_ci | xargs -n1 sh -c 'echo "Testing $0"; newt build -q targets_ci/$0' + rm -rf targets_ci - name: Build native targets if: matrix.os == 'ubuntu-latest' run: | - cp -r .github/targets_native ci_targets - ls ci_targets | xargs -n1 sh -c 'echo "Testing $0"; newt build -q $0' - rm -rf ci_targets + cp -r .github/targets_native targets_ci + ls targets_ci | xargs -n1 sh -c 'echo "Testing $0"; newt build -q targets_ci/$0' + rm -rf targets_ci diff --git a/.github/targets/dialog_cmac/pkg.yml b/targets/dialog_cmac/pkg.yml similarity index 100% rename from .github/targets/dialog_cmac/pkg.yml rename to targets/dialog_cmac/pkg.yml diff --git a/.github/targets/dialog_cmac/syscfg.yml b/targets/dialog_cmac/syscfg.yml similarity index 100% rename from .github/targets/dialog_cmac/syscfg.yml rename to targets/dialog_cmac/syscfg.yml diff --git a/.github/targets/dialog_cmac/target.yml b/targets/dialog_cmac/target.yml similarity index 100% rename from .github/targets/dialog_cmac/target.yml rename to targets/dialog_cmac/target.yml diff --git a/targets/nordic_pca10056-blehci-usb/pkg.yml b/targets/nordic_pca10056-blehci-usb/pkg.yml new file mode 100644 index 0000000000..2c8307d3df --- /dev/null +++ b/targets/nordic_pca10056-blehci-usb/pkg.yml @@ -0,0 +1,27 @@ +# 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: "targets/nordic_pca10056-blehci-usb" +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: + +pkg.deps: + - "@apache-mynewt-core/hw/usb/tinyusb" + - "@apache-mynewt-core/hw/usb/tinyusb/std_descriptors" diff --git a/targets/nordic_pca10056-blehci-usb/syscfg.yml b/targets/nordic_pca10056-blehci-usb/syscfg.yml new file mode 100644 index 0000000000..0c5701a98b --- /dev/null +++ b/targets/nordic_pca10056-blehci-usb/syscfg.yml @@ -0,0 +1,24 @@ +# 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. +# + +syscfg.vals: + BLE_TRANSPORT_HS: usb + USBD_BTH: 1 + + USBD_PID: 0xC01A + USBD_VID: 0xC0CA diff --git a/targets/nordic_pca10056-blehci-usb/target.yml b/targets/nordic_pca10056-blehci-usb/target.yml new file mode 100644 index 0000000000..ce455d45c9 --- /dev/null +++ b/targets/nordic_pca10056-blehci-usb/target.yml @@ -0,0 +1,21 @@ +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: debug diff --git a/.github/targets/nordic_pca10095_net-blehci/pkg.yml b/targets/nordic_pca10095_net-blehci/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10095_net-blehci/pkg.yml rename to targets/nordic_pca10095_net-blehci/pkg.yml diff --git a/.github/targets/nordic_pca10095_net-blehci/syscfg.yml b/targets/nordic_pca10095_net-blehci/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10095_net-blehci/syscfg.yml rename to targets/nordic_pca10095_net-blehci/syscfg.yml diff --git a/.github/targets/nordic_pca10095_net-blehci/target.yml b/targets/nordic_pca10095_net-blehci/target.yml similarity index 100% rename from .github/targets/nordic_pca10095_net-blehci/target.yml rename to targets/nordic_pca10095_net-blehci/target.yml From 0bc085e16562a5ed9668831c086c093623a5e95a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 27 Jan 2023 20:23:19 +0100 Subject: [PATCH 0633/1333] nimble/ll/test: Add unit test for BIG/BIS aa --- nimble/controller/test/src/ble_ll_aa_test.c | 103 ++++++++++++++++++++ nimble/controller/test/src/ble_ll_test.c | 3 + 2 files changed, 106 insertions(+) create mode 100644 nimble/controller/test/src/ble_ll_aa_test.c diff --git a/nimble/controller/test/src/ble_ll_aa_test.c b/nimble/controller/test/src/ble_ll_aa_test.c new file mode 100644 index 0000000000..4d64d87a00 --- /dev/null +++ b/nimble/controller/test/src/ble_ll_aa_test.c @@ -0,0 +1,103 @@ +/* + * 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. + */ + +#include +#include +#include + +TEST_CASE_SELF(ble_ll_aa_test_1) +{ + uint32_t seed_aa; + uint32_t aa; + + seed_aa = 0x78e52493; + + /* BIG Control */ + aa = ble_ll_utils_calc_big_aa(seed_aa, 0); + TEST_ASSERT(aa == 0x7a412493); + + /* BISes */ + aa = ble_ll_utils_calc_big_aa(seed_aa, 1); + TEST_ASSERT(aa == 0x85e32493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 2); + TEST_ASSERT(aa == 0x79d52493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 3); + TEST_ASSERT(aa == 0x86752493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 4); + TEST_ASSERT(aa == 0x7a572493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 5); + TEST_ASSERT(aa == 0x85f12493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 6); + TEST_ASSERT(aa == 0x79d32493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 7); + TEST_ASSERT(aa == 0x86732493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 8); + TEST_ASSERT(aa == 0x7b652493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 9); + TEST_ASSERT(aa == 0x85c72493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 10); + TEST_ASSERT(aa == 0x78e12493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 11); + TEST_ASSERT(aa == 0x86412493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 12); + TEST_ASSERT(aa == 0x7b632493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 13); + TEST_ASSERT(aa == 0x85d52493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 14); + TEST_ASSERT(aa == 0x78f72493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 15); + TEST_ASSERT(aa == 0x86572493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 16); + TEST_ASSERT(aa == 0x7b712493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 17); + TEST_ASSERT(aa == 0x85d32493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 18); + TEST_ASSERT(aa == 0x78c52493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 19); + TEST_ASSERT(aa == 0x87652493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 20); + TEST_ASSERT(aa == 0x7b472493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 21); + TEST_ASSERT(aa == 0x84e12493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 22); + TEST_ASSERT(aa == 0x78c32493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 23); + TEST_ASSERT(aa == 0x87632493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 24); + TEST_ASSERT(aa == 0x7b552493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 25); + TEST_ASSERT(aa == 0x84f72493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 26); + TEST_ASSERT(aa == 0x78d12493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 27); + TEST_ASSERT(aa == 0x87712493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 28); + TEST_ASSERT(aa == 0x7b532493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 29); + TEST_ASSERT(aa == 0x84c52493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 30); + TEST_ASSERT(aa == 0x79e72493); + aa = ble_ll_utils_calc_big_aa(seed_aa, 31); + TEST_ASSERT(aa == 0x87472493); +} + +TEST_SUITE(ble_ll_aa_test_suite) +{ + ble_ll_aa_test_1(); +} diff --git a/nimble/controller/test/src/ble_ll_test.c b/nimble/controller/test/src/ble_ll_test.c index ee089afe7f..efb9bf002f 100644 --- a/nimble/controller/test/src/ble_ll_test.c +++ b/nimble/controller/test/src/ble_ll_test.c @@ -26,9 +26,12 @@ #if MYNEWT_VAL(SELFTEST) +TEST_SUITE_DECL(ble_ll_aa_test_suite); + int main(int argc, char **argv) { + ble_ll_aa_test_suite(); ble_ll_csa2_test_suite(); return tu_any_failed; } From 84f50834807d61b382070420cdc732af63f053ee Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 27 Jan 2023 20:39:23 +0100 Subject: [PATCH 0634/1333] nimble/ll/test: Add crypto unit tests --- .../controller/test/src/ble_ll_crypto_test.c | 147 ++++++++++++++++++ nimble/controller/test/src/ble_ll_test.c | 2 + 2 files changed, 149 insertions(+) create mode 100644 nimble/controller/test/src/ble_ll_crypto_test.c diff --git a/nimble/controller/test/src/ble_ll_crypto_test.c b/nimble/controller/test/src/ble_ll_crypto_test.c new file mode 100644 index 0000000000..a2e727a070 --- /dev/null +++ b/nimble/controller/test/src/ble_ll_crypto_test.c @@ -0,0 +1,147 @@ +/* + * 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. + */ + +#include +#include +#include + +TEST_CASE_SELF(ble_ll_crypto_test_h6) { + const uint8_t w[] = { + 0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05, + 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b + }; + const uint8_t key_id[] = { 0x6c, 0x65, 0x62, 0x72 }; + const uint8_t ok[] = { + 0x2d, 0x9a, 0xe1, 0x02, 0xe7, 0x6d, 0xc9, 0x1c, + 0xe8, 0xd3, 0xa9, 0xe2, 0x80, 0xb1, 0x63, 0x99 + }; + uint8_t out[16]; + int rc; + + rc = ble_ll_crypto_h6(w, key_id, out); + TEST_ASSERT(rc == 0); + + rc = memcmp(out, ok, 16); + TEST_ASSERT(rc == 0); +} + +TEST_CASE_SELF(ble_ll_crypto_test_h7) { + const uint8_t salt[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0x6D, 0x70, 0x31 + }; + const uint8_t w[] = { + 0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05, + 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b + }; + const uint8_t ok[] = { + 0xfb, 0x17, 0x35, 0x97, 0xc6, 0xa3, 0xc0, 0xec, + 0xd2, 0x99, 0x8c, 0x2a, 0x75, 0xa5, 0x70, 0x11 + }; + uint8_t out[16]; + int rc; + + rc = ble_ll_crypto_h7(salt, w, out); + TEST_ASSERT(rc == 0); + + rc = memcmp(out, ok, 16); + TEST_ASSERT(rc == 0); +} + +TEST_CASE_SELF(ble_ll_crypto_test_h8) { + const uint8_t k[] = { + 0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05, + 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b + }; + const uint8_t s[] = { + 0x15, 0x36, 0xd1, 0x8d, 0xe3, 0xd2, 0x0d, 0xf9, + 0x9b, 0x70, 0x44, 0xc1, 0x2f, 0x9e, 0xd5, 0xba + }; + const uint8_t key_id[] = { 0xcc, 0x03, 0x01, 0x48 }; + const uint8_t ok[] = { + 0xe5, 0xe5, 0xbe, 0xba, 0xae, 0x72, 0x28, 0xe7, + 0x22, 0xa3, 0x89, 0x04, 0xed, 0x35, 0x0f, 0x6d + }; + uint8_t out[16]; + int rc; + + rc = ble_ll_crypto_h8(k, s, key_id, out); + TEST_ASSERT(rc == 0); + + rc = memcmp(out, ok, 16); + TEST_ASSERT(rc == 0); +} + +TEST_CASE_SELF(ble_ll_crypto_test_gskd) { + const uint8_t broadcast_code[] = { + 0x00, 0x00, 0x00, 0x00, 0x65, 0x73, 0x75, 0x6f, + 0x48, 0x20, 0x65, 0x6e, 0x72, 0xb8, 0xc3, 0x42 + }; + const uint8_t gskd[] = { + 0x55, 0x18, 0x8b, 0x3d, 0x32, 0xf6, 0xbb, 0x9a, + 0x90, 0x0a, 0xfc, 0xfb, 0xee, 0xd4, 0xe7, 0x2a + }; + const uint8_t big1[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x42, 0x49, 0x47, 0x31 + }; + const uint8_t big2[] = { 0x42, 0x49, 0x47, 0x32 }; + const uint8_t big3[] = { 0x42, 0x49, 0x47, 0x33 }; + const uint8_t ok_igltk[] = { + 0x4c, 0x0d, 0xd7, 0x4c, 0x2b, 0x19, 0xaa, 0x95, + 0xd8, 0x98, 0x23, 0x85, 0x5f, 0x10, 0x01, 0xb8 + }; + const uint8_t ok_gltk[] = { + 0xc4, 0xcd, 0x4b, 0x83, 0x49, 0xb5, 0xa1, 0x8a, + 0x02, 0xde, 0x66, 0x20, 0x90, 0x17, 0xae, 0xd3 + }; + const uint8_t ok_gsk[] = { + 0xbe, 0x2a, 0x16, 0xfc, 0x7a, 0xc4, 0x64, 0xe7, + 0x52, 0x30, 0x1b, 0xcc, 0xc8, 0x18, 0x81, 0x2c + }; + uint8_t igltk[16]; + uint8_t gltk[16]; + uint8_t gsk[16]; + int rc; + + rc = ble_ll_crypto_h7(big1, broadcast_code, igltk); + TEST_ASSERT(rc == 0); + + rc = memcmp(igltk, ok_igltk, 16); + TEST_ASSERT(rc == 0); + + rc = ble_ll_crypto_h6(igltk, big2, gltk); + TEST_ASSERT(rc == 0); + + rc = memcmp(gltk, ok_gltk, 16); + TEST_ASSERT(rc == 0); + + rc = ble_ll_crypto_h8(gltk, gskd, big3, gsk); + TEST_ASSERT(rc == 0); + + rc = memcmp(gsk, ok_gsk, 16); + TEST_ASSERT(rc == 0); +} + +TEST_SUITE(ble_ll_crypto_test_suite) { + ble_ll_crypto_test_h6(); + ble_ll_crypto_test_h7(); + ble_ll_crypto_test_h8(); + ble_ll_crypto_test_gskd(); +} diff --git a/nimble/controller/test/src/ble_ll_test.c b/nimble/controller/test/src/ble_ll_test.c index efb9bf002f..e496e15fa7 100644 --- a/nimble/controller/test/src/ble_ll_test.c +++ b/nimble/controller/test/src/ble_ll_test.c @@ -27,11 +27,13 @@ #if MYNEWT_VAL(SELFTEST) TEST_SUITE_DECL(ble_ll_aa_test_suite); +TEST_SUITE_DECL(ble_ll_crypto_test_suite); int main(int argc, char **argv) { ble_ll_aa_test_suite(); + ble_ll_crypto_test_suite(); ble_ll_csa2_test_suite(); return tu_any_failed; } From 2f984a3c3ec388a5e511179ff2c0e40db1a63368 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 27 Jan 2023 20:25:11 +0100 Subject: [PATCH 0635/1333] nimble/ll/test: Cleanup tests --- .../include/controller/ble_ll_test.h | 35 ------------------- nimble/controller/test/src/ble_ll_csa2_test.c | 11 +++--- nimble/controller/test/src/ble_ll_csa2_test.h | 27 -------------- nimble/controller/test/src/ble_ll_test.c | 10 +++--- 4 files changed, 8 insertions(+), 75 deletions(-) delete mode 100644 nimble/controller/include/controller/ble_ll_test.h delete mode 100644 nimble/controller/test/src/ble_ll_csa2_test.h diff --git a/nimble/controller/include/controller/ble_ll_test.h b/nimble/controller/include/controller/ble_ll_test.h deleted file mode 100644 index 32984c6b3e..0000000000 --- a/nimble/controller/include/controller/ble_ll_test.h +++ /dev/null @@ -1,35 +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_LL_TEST_ -#define H_LL_TEST_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ble_ll_csa2_test_all(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/nimble/controller/test/src/ble_ll_csa2_test.c b/nimble/controller/test/src/ble_ll_csa2_test.c index 566500e36a..ae8f8897d1 100644 --- a/nimble/controller/test/src/ble_ll_csa2_test.c +++ b/nimble/controller/test/src/ble_ll_csa2_test.c @@ -17,13 +17,10 @@ * under the License. */ -#include -#include -#include "testutil/testutil.h" -#include "controller/ble_ll_test.h" -#include "controller/ble_ll_conn.h" -#include "controller/ble_ll_utils.h" -#include "ble_ll_csa2_test.h" +#include +#include +#include +#include TEST_CASE_SELF(ble_ll_csa2_test_1) { diff --git a/nimble/controller/test/src/ble_ll_csa2_test.h b/nimble/controller/test/src/ble_ll_csa2_test.h deleted file mode 100644 index 5bcc142bb3..0000000000 --- a/nimble/controller/test/src/ble_ll_csa2_test.h +++ /dev/null @@ -1,27 +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_BLE_LL_CSA2_TEST_ -#define H_BLE_LL_CSA2_TEST_ - -#include "testutil/testutil.h" - -TEST_SUITE_DECL(ble_ll_csa2_test_suite); - -#endif diff --git a/nimble/controller/test/src/ble_ll_test.c b/nimble/controller/test/src/ble_ll_test.c index e496e15fa7..2b36cb1f3c 100644 --- a/nimble/controller/test/src/ble_ll_test.c +++ b/nimble/controller/test/src/ble_ll_test.c @@ -17,17 +17,14 @@ * under the License. */ -#include "sysinit/sysinit.h" -#include "syscfg/syscfg.h" -#include "controller/ble_ll_test.h" -#include "os/os.h" -#include "testutil/testutil.h" -#include "ble_ll_csa2_test.h" +#include +#include #if MYNEWT_VAL(SELFTEST) TEST_SUITE_DECL(ble_ll_aa_test_suite); TEST_SUITE_DECL(ble_ll_crypto_test_suite); +TEST_SUITE_DECL(ble_ll_csa2_test_suite); int main(int argc, char **argv) @@ -35,6 +32,7 @@ main(int argc, char **argv) ble_ll_aa_test_suite(); ble_ll_crypto_test_suite(); ble_ll_csa2_test_suite(); + return tu_any_failed; } From 864018bf5aea3c1bd7ad161cfdbebd151f539a23 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 31 Jan 2023 13:36:59 +0100 Subject: [PATCH 0636/1333] ci: Unify tests with mynewt-core repository Use check scripts from core repository. --- .github/check_style.py | 142 ------------------ .../{check_style.yml => compliance_check.yml} | 22 ++- 2 files changed, 21 insertions(+), 143 deletions(-) delete mode 100755 .github/check_style.py rename .github/workflows/{check_style.yml => compliance_check.yml} (57%) diff --git a/.github/check_style.py b/.github/check_style.py deleted file mode 100755 index 7b2fa5b8fa..0000000000 --- a/.github/check_style.py +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/python - -# -# 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. -# - -import os.path -import re -import subprocess -import tempfile -import sys - -INFO_URL = "https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md" - -def get_lines_range(m: re.Match) -> range: - first = int(m.group(1)) - - if m.group(2) is not None: - last = first + int(m.group(2)) - else: - last = first + 1 - - return range(first, last) - - -def run_cmd(cmd: str) -> list[str]: - out = subprocess.check_output(cmd, text=True, shell=True) - return out.splitlines() - - -def check_file(fname: str, commit: str, upstream: str) -> list[str]: - ret = [] - - diff_lines = set() - for s in run_cmd(f"git diff -U0 {upstream} {commit} -- {fname}"): - m = re.match(r"^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@", s) - if not m: - continue - diff_lines.update(get_lines_range(m)) - - with tempfile.NamedTemporaryFile(suffix=os.path.basename(fname)) as tmpf: - lines = subprocess.check_output(f"git show {commit}:{fname}", - shell=True) - tmpf.write(lines) - - in_chunk = False - - for s in run_cmd(f"uncrustify -q -c uncrustify.cfg -f {tmpf.name} | " - f"diff -u0 -p {tmpf.name} - || true"): - m = re.match(r"^@@ -(\d+)(?:,(\d+))? \+\d+(?:,\d+)? @@", s) - if not m: - if in_chunk: - ret.append(s) - continue - - in_chunk = len(diff_lines & set(get_lines_range(m))) != 0 - - if in_chunk: - ret.append(s) - - return ret - - -def is_ignored(fname: str, ign_dirs: list[str]) -> bool: - if not re.search(r"\.(c|cpp|h|hpp)$", fname): - return True - - for d in ign_dirs: - if fname.startswith(d): - return True - - return False - - -def main() -> bool: - if len(sys.argv) > 1: - commit = sys.argv[1] - else: - commit = "HEAD" - if len(sys.argv) > 2: - upstream = sys.argv[2] - else: - upstream = "origin/master" - - mb = run_cmd(f"git merge-base {upstream} {commit}") - upstream = mb[0] - - cfg_fname = os.path.join(os.path.dirname(__file__), "../.style_ignored_dirs") - with open(cfg_fname, "r") as x: - ign_dirs = [s.strip() for s in x.readlines() if - s.strip() and not s.startswith("#")] - - results_ok = [] - results_fail = [] - results_ign = [] - - files = run_cmd(f"git diff --diff-filter=AM --name-only {upstream} {commit}") - for fname in files: - if is_ignored(fname, ign_dirs): - results_ign.append(fname) - continue - - diff = check_file(fname, commit, upstream) - if len(diff) == 0: - results_ok.append(fname) - else: - results_fail.append((fname, diff)) - - for fname in results_ign: - print(f"\033[90m[ NA ] {fname}\033[0m") - for fname in results_ok: - print(f"\033[32m[ OK ] {fname}\033[0m") - for fname, diff in results_fail: - print(f"\033[31m[FAIL] {fname}\033[0m") - print("\n".join(diff)) - print() - - if len(results_fail) > 0: - print(f"\033[31mYour code has style problems, see {INFO_URL} for " - f"details.\033[0m") - - return len(results_fail) == 0 - - -if __name__ == "__main__": - if not main(): - sys.exit(1) diff --git a/.github/workflows/check_style.yml b/.github/workflows/compliance_check.yml similarity index 57% rename from .github/workflows/check_style.yml rename to .github/workflows/compliance_check.yml index ce713bb4e0..edacc93f6d 100644 --- a/.github/workflows/check_style.yml +++ b/.github/workflows/compliance_check.yml @@ -33,6 +33,26 @@ jobs: run: | sudo apt-get update sudo apt-get install -y uncrustify + mkdir repos + git clone --depth=1 https://github.com/apache/mynewt-core repos/apache-mynewt-core - name: check style run: | - .github/check_style.py + ./repos/apache-mynewt-core/.github/check_style.py + + style_license: + name: Licensing + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Install Dependencies + run: | + mkdir repos + git clone --depth=1 https://github.com/apache/mynewt-core repos/apache-mynewt-core + wget https://dlcdn.apache.org//creadur/apache-rat-0.15/apache-rat-0.15-bin.tar.gz + tar zxf apache-rat-0.15-bin.tar.gz apache-rat-0.15/apache-rat-0.15.jar + mv apache-rat-0.15/apache-rat-0.15.jar apache-rat.jar + - name: check licensing + run: | + ./repos/apache-mynewt-core/.github/check_license.py From 95a875335ad8f98ada8c572bc2720fa74bdc647b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 31 Jan 2023 13:40:30 +0100 Subject: [PATCH 0637/1333] README: Add GH Actions badges Makes it easier to catch broken CI on master branch. --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index d5ddbec81e..952a35caac 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,20 @@ ## Overview + + + + + + + + + + + + +

+ Apache NimBLE is an open-source Bluetooth 5.1 stack (both Host & Controller) that completely replaces the proprietary SoftDevice on Nordic chipsets. It is part of [Apache Mynewt project](https://github.com/apache/mynewt-core). From 33942430e3f412ee8644b9a7d6b14b6a1ea3945b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 2 Feb 2023 18:06:42 +0100 Subject: [PATCH 0638/1333] nimble/ports: Refresh syscfg --- .../examples/linux/include/syscfg/syscfg.h | 11 +++-- .../linux_blemesh/include/syscfg/syscfg.h | 11 +++-- .../examples/nuttx/include/syscfg/syscfg.h | 11 +++-- porting/nimble/include/syscfg/syscfg.h | 11 +++-- porting/npl/riot/include/syscfg/syscfg.h | 43 ++++++++++++++++--- 5 files changed, 56 insertions(+), 31 deletions(-) diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index a74ff46b53..f60846de7f 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -430,6 +430,10 @@ #endif /*** @apache-mynewt-nimble/nimble */ +#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING +#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) +#endif + #ifndef MYNEWT_VAL_BLE_EXT_ADV #define MYNEWT_VAL_BLE_EXT_ADV (0) #endif @@ -478,10 +482,6 @@ #define MYNEWT_VAL_BLE_POWER_CONTROL (0) #endif -#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING -#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) -#endif - #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif @@ -1063,9 +1063,8 @@ #define MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT (16) #endif -/* Overridden by @apache-mynewt-nimble/nimble/transport (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE -#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (257) +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (70) #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__cdc diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index a5ee902984..3af3ecc095 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -431,6 +431,10 @@ #endif /*** @apache-mynewt-nimble/nimble */ +#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING +#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) +#endif + #ifndef MYNEWT_VAL_BLE_EXT_ADV #define MYNEWT_VAL_BLE_EXT_ADV (0) #endif @@ -479,10 +483,6 @@ #define MYNEWT_VAL_BLE_POWER_CONTROL (0) #endif -#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING -#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) -#endif - #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif @@ -1638,9 +1638,8 @@ #define MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT (16) #endif -/* Overridden by @apache-mynewt-nimble/nimble/transport (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE -#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (257) +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (70) #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__cdc diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index 741695d869..6035f7966e 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -430,6 +430,10 @@ #endif /*** @apache-mynewt-nimble/nimble */ +#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING +#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) +#endif + #ifndef MYNEWT_VAL_BLE_EXT_ADV #define MYNEWT_VAL_BLE_EXT_ADV (0) #endif @@ -478,10 +482,6 @@ #define MYNEWT_VAL_BLE_POWER_CONTROL (0) #endif -#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING -#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) -#endif - #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif @@ -1065,9 +1065,8 @@ #define MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT (16) #endif -/* Overridden by @apache-mynewt-nimble/nimble/transport (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE -#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (257) +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (70) #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__cdc diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index dcd5acc0d4..612afbd8eb 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -429,6 +429,10 @@ #endif /*** @apache-mynewt-nimble/nimble */ +#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING +#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) +#endif + #ifndef MYNEWT_VAL_BLE_EXT_ADV #define MYNEWT_VAL_BLE_EXT_ADV (0) #endif @@ -477,10 +481,6 @@ #define MYNEWT_VAL_BLE_POWER_CONTROL (0) #endif -#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING -#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) -#endif - #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif @@ -1062,9 +1062,8 @@ #define MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT (16) #endif -/* Overridden by @apache-mynewt-nimble/nimble/transport (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE -#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (257) +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (70) #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__cdc diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index b732e00f35..71c0798fb5 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -19,6 +19,19 @@ #define MYNEWT_VAL_HARDFLOAT (0) #endif +/*** @apache-mynewt-core/crypto/tinycrypt */ +#ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE +#define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) +#endif + +#ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME +#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME "trng" +#endif + +#ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG +#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG (0) +#endif + /*** @apache-mynewt-core/hw/bsp/nordic_pca10056 */ #ifndef MYNEWT_VAL_BSP_NRF52840 #define MYNEWT_VAL_BSP_NRF52840 (1) @@ -145,7 +158,7 @@ #endif #ifndef MYNEWT_VAL_MCU_ICACHE_ENABLED -#define MYNEWT_VAL_MCU_ICACHE_ENABLED (0) +#define MYNEWT_VAL_MCU_ICACHE_ENABLED (1) #endif /* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ @@ -792,6 +805,10 @@ #endif /*** @apache-mynewt-nimble/nimble */ +#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING +#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) +#endif + #ifndef MYNEWT_VAL_BLE_EXT_ADV #define MYNEWT_VAL_BLE_EXT_ADV (0) #endif @@ -842,10 +859,6 @@ #define MYNEWT_VAL_BLE_POWER_CONTROL (0) #endif -#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING -#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) -#endif - #ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) #endif @@ -1029,6 +1042,10 @@ #define MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_CONN_EVENT_END_MARGIN +#define MYNEWT_VAL_BLE_LL_CONN_EVENT_END_MARGIN (0) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ #ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_MAX_TX_BYTES #define MYNEWT_VAL_BLE_LL_CONN_INIT_MAX_TX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE) @@ -1103,6 +1120,10 @@ #define MYNEWT_VAL_BLE_LL_DTM_EXTENSIONS (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_EXT +#define MYNEWT_VAL_BLE_LL_EXT (0) +#endif + #ifndef MYNEWT_VAL_BLE_LL_EXT_ADV_AUX_PTR_CNT #define MYNEWT_VAL_BLE_LL_EXT_ADV_AUX_PTR_CNT (0) #endif @@ -1283,6 +1304,10 @@ #define MYNEWT_VAL_BLE_LL_TX_PWR_DBM (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_TX_PWR_MAX_DBM +#define MYNEWT_VAL_BLE_LL_TX_PWR_MAX_DBM (20) +#endif + #ifndef MYNEWT_VAL_BLE_LL_USECS_PER_PERIOD #define MYNEWT_VAL_BLE_LL_USECS_PER_PERIOD (0) #endif @@ -1332,6 +1357,10 @@ #define MYNEWT_VAL_BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR (0) #endif +#ifndef MYNEWT_VAL_BLE_PHY_VARIABLE_TIFS +#define MYNEWT_VAL_BLE_PHY_VARIABLE_TIFS (0) +#endif + /*** @apache-mynewt-nimble/nimble/host */ #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) @@ -1776,9 +1805,8 @@ #define MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT (16) #endif -/* Overridden by @apache-mynewt-nimble/nimble/transport (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE -#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (257) +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (70) #endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__cdc @@ -1874,6 +1902,7 @@ /*** Included packages */ #define MYNEWT_PKG_apache_mynewt_core__compiler_arm_none_eabi_m4 1 +#define MYNEWT_PKG_apache_mynewt_core__crypto_tinycrypt 1 #define MYNEWT_PKG_apache_mynewt_core__hw_bsp_nordic_pca10056 1 #define MYNEWT_PKG_apache_mynewt_core__hw_cmsis_core 1 #define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart 1 From dad00798bfceca4ab82ddc2a14b4ce0470b0c97c Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 2 Feb 2023 18:00:44 +0100 Subject: [PATCH 0639/1333] nimble/ll: Use MIN/MAX macros from ble_ll_utils.h Use macros provided by utils instead of relying on system providing min and max macros. --- nimble/controller/src/ble_ll.c | 7 +++--- nimble/controller/src/ble_ll_adv.c | 8 +++---- nimble/controller/src/ble_ll_conn.c | 32 ++++++++++++------------- nimble/controller/src/ble_ll_ctrl.c | 5 ++-- nimble/controller/src/ble_ll_hci.c | 7 +++--- nimble/controller/src/ble_ll_hci_vs.c | 5 ++-- nimble/controller/src/ble_ll_scan_aux.c | 3 ++- nimble/controller/src/ble_ll_sync.c | 2 +- nimble/controller/src/ble_ll_utils.c | 4 ++-- 9 files changed, 39 insertions(+), 34 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 913f68cfea..8b2395723a 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -29,6 +29,7 @@ #include "nimble/nimble_opt.h" #include "nimble/hci_common.h" #include "nimble/transport.h" +#include "controller/ble_ll_utils.h" #include "controller/ble_hw.h" #include "controller/ble_phy.h" #include "controller/ble_phy_trace.h" @@ -1362,7 +1363,7 @@ ble_ll_task(void *arg) ble_phy_init(); /* Set output power to default */ - g_ble_ll_tx_power = ble_ll_tx_power_round(min(MYNEWT_VAL(BLE_LL_TX_PWR_DBM), + g_ble_ll_tx_power = ble_ll_tx_power_round(MIN(MYNEWT_VAL(BLE_LL_TX_PWR_DBM), MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM))); ble_ll_tx_power_set(g_ble_ll_tx_power); @@ -1614,7 +1615,7 @@ ble_ll_reset(void) g_ble_ll_rx_power_compensation = 0; /* Set output power to default */ - g_ble_ll_tx_power = ble_ll_tx_power_round(min(MYNEWT_VAL(BLE_LL_TX_PWR_DBM), + g_ble_ll_tx_power = ble_ll_tx_power_round(MIN(MYNEWT_VAL(BLE_LL_TX_PWR_DBM), MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM))); ble_ll_tx_power_set(g_ble_ll_tx_power); @@ -1727,7 +1728,7 @@ ble_ll_pdu_max_tx_octets_get(uint32_t usecs, int phy_mode) } /* see comment at the beginning */ - return max(27, octets); + return MAX(27, octets); } static inline bool diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 6f35c7e535..dfa41bc782 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1438,7 +1438,7 @@ ble_ll_adv_aux_calculate_payload(struct ble_ll_adv_sm *advsm, uint16_t props, } /* AdvData */ - data_len = min(BLE_LL_MAX_PAYLOAD_LEN - ext_hdr_len, rem_data_len); + data_len = MIN(BLE_LL_MAX_PAYLOAD_LEN - ext_hdr_len, rem_data_len); /* AuxPtr if there are more AdvData remaining that we can fit here */ if (chainable && (rem_data_len > data_len)) { @@ -2329,7 +2329,7 @@ ble_ll_adv_sync_calculate(struct ble_ll_adv_sm *advsm, } /* AdvData always */ - sync->data_len = min(BLE_LL_MAX_PAYLOAD_LEN - ext_hdr_len, rem_data_len); + sync->data_len = MIN(BLE_LL_MAX_PAYLOAD_LEN - ext_hdr_len, rem_data_len); /* AuxPtr if there are more AdvData remaining that we can fit here */ if ((rem_data_len > sync->data_len)) { @@ -3529,7 +3529,7 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, /* no preference */ advsm->tx_power = ble_ll_tx_power_round(g_ble_ll_tx_power - g_ble_ll_tx_power_compensation); } else { - advsm->tx_power = ble_ll_tx_power_round(min(cmd->tx_power, MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM)) - + advsm->tx_power = ble_ll_tx_power_round(MIN(cmd->tx_power, MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM)) - g_ble_ll_tx_power_compensation); } @@ -3827,7 +3827,7 @@ ble_ll_adv_sync_get_pdu_len(uint16_t data_len, uint16_t *data_offset, } /* AdvData always */ - data_len = min(BLE_LL_MAX_PAYLOAD_LEN - hdr_len, rem_data_len); + data_len = MIN(BLE_LL_MAX_PAYLOAD_LEN - hdr_len, rem_data_len); /* AuxPtr if there are more AdvData remaining that we can fit here */ if (rem_data_len > data_len) { diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 5b88d3ef1e..8f75ecd2de 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1824,8 +1824,8 @@ ble_ll_conn_set_data_len(struct ble_ll_conn_sm *connsm, /* If peer does not support coded, we cannot use value larger than 2120us */ if (!ble_ll_conn_rem_feature_check(connsm, BLE_LL_FEAT_LE_CODED_PHY)) { - tx_time = min(tx_time, BLE_LL_CONN_SUPP_TIME_MAX_UNCODED); - rx_time = min(rx_time, BLE_LL_CONN_SUPP_TIME_MAX_UNCODED); + tx_time = MIN(tx_time, BLE_LL_CONN_SUPP_TIME_MAX_UNCODED); + rx_time = MIN(rx_time, BLE_LL_CONN_SUPP_TIME_MAX_UNCODED); } #endif @@ -2086,10 +2086,10 @@ ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm) send_event = 0; /* See if effective times have changed */ - eff_time = min(connsm->rem_max_tx_time, connsm->max_rx_time); + eff_time = MIN(connsm->rem_max_tx_time, connsm->max_rx_time); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) if (connsm->phy_data.cur_rx_phy == BLE_PHY_CODED) { - eff_time = max(eff_time, BLE_LL_CONN_SUPP_TIME_MIN_CODED); + eff_time = MAX(eff_time, BLE_LL_CONN_SUPP_TIME_MIN_CODED); } #endif if (eff_time != connsm->eff_max_rx_time) { @@ -2097,23 +2097,23 @@ ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm) ota_max_rx_time_calc = 1; send_event = 1; } - eff_time = min(connsm->rem_max_rx_time, connsm->max_tx_time); + eff_time = MIN(connsm->rem_max_rx_time, connsm->max_tx_time); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) if (connsm->phy_data.cur_tx_phy == BLE_PHY_CODED) { - eff_time = max(eff_time, BLE_LL_CONN_SUPP_TIME_MIN_CODED); + eff_time = MAX(eff_time, BLE_LL_CONN_SUPP_TIME_MIN_CODED); } #endif if (eff_time != connsm->eff_max_tx_time) { connsm->eff_max_tx_time = eff_time; send_event = 1; } - eff_bytes = min(connsm->rem_max_tx_octets, connsm->max_rx_octets); + eff_bytes = MIN(connsm->rem_max_tx_octets, connsm->max_rx_octets); if (eff_bytes != connsm->eff_max_rx_octets) { connsm->eff_max_rx_octets = eff_bytes; ota_max_rx_time_calc = 1; send_event = 1; } - eff_bytes = min(connsm->rem_max_rx_octets, connsm->max_tx_octets); + eff_bytes = MIN(connsm->rem_max_rx_octets, connsm->max_tx_octets); if (eff_bytes != connsm->eff_max_tx_octets) { connsm->eff_max_tx_octets = eff_bytes; send_event = 1; @@ -2132,7 +2132,7 @@ ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm) phy_mode = BLE_PHY_MODE_1M; #endif ota_time = ble_ll_pdu_us(connsm->eff_max_rx_octets, phy_mode); - connsm->ota_max_rx_time = min(ota_time, connsm->eff_max_rx_time); + connsm->ota_max_rx_time = MIN(ota_time, connsm->eff_max_rx_time); } if (send_event) { @@ -4290,15 +4290,15 @@ ble_ll_conn_subrate_req_llcp(struct ble_ll_conn_sm *connsm, return -EINVAL; } - connsm->subrate_trans.subrate_factor = min(connsm->acc_subrate_max, + connsm->subrate_trans.subrate_factor = MIN(connsm->acc_subrate_max, srp->subrate_max); connsm->subrate_trans.subrate_base_event = connsm->event_cntr; - connsm->subrate_trans.periph_latency = min(connsm->acc_max_latency, + connsm->subrate_trans.periph_latency = MIN(connsm->acc_max_latency, srp->max_latency); - connsm->subrate_trans.cont_num = min(max(connsm->acc_cont_num, + connsm->subrate_trans.cont_num = MIN(MAX(connsm->acc_cont_num, srp->cont_num), connsm->subrate_trans.subrate_factor - 1); - connsm->subrate_trans.supervision_tmo = min(connsm->supervision_tmo, + connsm->subrate_trans.supervision_tmo = MIN(connsm->supervision_tmo, srp->supervision_tmo); ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SUBRATE_UPDATE, NULL); @@ -4392,7 +4392,7 @@ ble_ll_conn_module_reset(void) /* Configure the global LL parameters */ conn_params = &g_ble_ll_conn_params; - maxbytes = min(MYNEWT_VAL(BLE_LL_SUPP_MAX_RX_BYTES), max_phy_pyld); + maxbytes = MIN(MYNEWT_VAL(BLE_LL_SUPP_MAX_RX_BYTES), max_phy_pyld); conn_params->supp_max_rx_octets = maxbytes; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) conn_params->supp_max_rx_time = MAX_TIME_CODED(maxbytes); @@ -4400,7 +4400,7 @@ ble_ll_conn_module_reset(void) conn_params->supp_max_rx_time = MAX_TIME_UNCODED(maxbytes); #endif - maxbytes = min(MYNEWT_VAL(BLE_LL_SUPP_MAX_TX_BYTES), max_phy_pyld); + maxbytes = MIN(MYNEWT_VAL(BLE_LL_SUPP_MAX_TX_BYTES), max_phy_pyld); conn_params->supp_max_tx_octets = maxbytes; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) conn_params->supp_max_tx_time = MAX_TIME_CODED(maxbytes); @@ -4408,7 +4408,7 @@ ble_ll_conn_module_reset(void) conn_params->supp_max_tx_time = MAX_TIME_UNCODED(maxbytes); #endif - maxbytes = min(MYNEWT_VAL(BLE_LL_CONN_INIT_MAX_TX_BYTES), max_phy_pyld); + maxbytes = MIN(MYNEWT_VAL(BLE_LL_CONN_INIT_MAX_TX_BYTES), max_phy_pyld); conn_params->conn_init_max_tx_octets = maxbytes; conn_params->conn_init_max_tx_time = MAX_TIME_UNCODED(maxbytes); conn_params->conn_init_max_tx_time_uncoded = MAX_TIME_UNCODED(maxbytes); diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index fe3c05fe2c..3a10052314 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -24,6 +24,7 @@ #include "nimble/ble.h" #include "nimble/nimble_opt.h" #include "nimble/hci_common.h" +#include "controller/ble_ll_utils.h" #include "controller/ble_ll.h" #include "controller/ble_ll_hci.h" #include "controller/ble_ll_ctrl.h" @@ -2122,13 +2123,13 @@ ble_ll_ctrl_update_features(struct ble_ll_conn_sm *connsm, uint8_t *feat) */ if (ble_ll_conn_rem_feature_check(connsm, BLE_LL_FEAT_LE_CODED_PHY)) { if (connsm->host_req_max_tx_time) { - connsm->max_tx_time = max(connsm->max_tx_time, + connsm->max_tx_time = MAX(connsm->max_tx_time, connsm->host_req_max_tx_time); } else { connsm->max_tx_time = g_ble_ll_conn_params.conn_init_max_tx_time_coded; } if (connsm->host_req_max_rx_time) { - connsm->max_rx_time = max(connsm->max_rx_time, + connsm->max_rx_time = MAX(connsm->max_rx_time, connsm->host_req_max_rx_time); } else { connsm->max_rx_time = BLE_LL_CONN_SUPP_TIME_MAX_CODED; diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index f36563b1c1..fab304932e 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -24,6 +24,7 @@ #include "nimble/ble.h" #include "nimble/nimble_opt.h" #include "nimble/hci_common.h" +#include "controller/ble_ll_utils.h" #include "controller/ble_hw.h" #include "controller/ble_ll_adv.h" #include "controller/ble_ll_scan.h" @@ -487,9 +488,9 @@ ble_ll_hci_le_wr_sugg_data_len(const uint8_t *cmdbuf, uint8_t len) * in which case we just use our max. */ g_ble_ll_conn_params.conn_init_max_tx_octets = - min(tx_octets, g_ble_ll_conn_params.supp_max_tx_octets); + MIN(tx_octets, g_ble_ll_conn_params.supp_max_tx_octets); g_ble_ll_conn_params.conn_init_max_tx_time = - min(tx_time, g_ble_ll_conn_params.supp_max_tx_time); + MIN(tx_time, g_ble_ll_conn_params.supp_max_tx_time); /* * Use the same for coded and uncoded defaults. These are used when PHY @@ -497,7 +498,7 @@ ble_ll_hci_le_wr_sugg_data_len(const uint8_t *cmdbuf, uint8_t len) * host. Make sure we do not exceed max supported time on uncoded. */ g_ble_ll_conn_params.conn_init_max_tx_time_uncoded = - min(BLE_LL_CONN_SUPP_TIME_MAX_UNCODED, + MIN(BLE_LL_CONN_SUPP_TIME_MAX_UNCODED, g_ble_ll_conn_params.conn_init_max_tx_time); g_ble_ll_conn_params.conn_init_max_tx_time_coded = g_ble_ll_conn_params.conn_init_max_tx_time; diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index c07d9f788d..b5affc2f1e 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -19,6 +19,7 @@ #include #include "syscfg/syscfg.h" +#include "controller/ble_ll_utils.h" #include "controller/ble_ll.h" #include "controller/ble_ll_hci.h" #include "controller/ble_ll_sync.h" @@ -74,11 +75,11 @@ ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, if (cmd->tx_power == 127) { /* restore reset default */ - g_ble_ll_tx_power = ble_ll_tx_power_round(min(MYNEWT_VAL(BLE_LL_TX_PWR_DBM), + g_ble_ll_tx_power = ble_ll_tx_power_round(MIN(MYNEWT_VAL(BLE_LL_TX_PWR_DBM), MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM)) - g_ble_ll_tx_power_compensation); } else { - g_ble_ll_tx_power = ble_ll_tx_power_round(min(cmd->tx_power, + g_ble_ll_tx_power = ble_ll_tx_power_round(MIN(cmd->tx_power, MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM)) - g_ble_ll_tx_power_compensation); } diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 45f9ce462c..45c55ba078 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -28,6 +28,7 @@ #include "os/os.h" #include "nimble/ble.h" #include "nimble/hci_common.h" +#include "controller/ble_ll_utils.h" #include "controller/ble_phy.h" #include "controller/ble_hw.h" #include "controller/ble_ll.h" @@ -533,7 +534,7 @@ ble_ll_hci_ev_send_ext_adv_report(struct os_mbuf *rxpdu, report->rssi = rxinfo->rssi - ble_ll_rx_gain(); - report->data_len = min(max_data_len, data_len - offset); + report->data_len = MIN(max_data_len, data_len - offset); os_mbuf_copydata(rxpdu, offset, report->data_len, report->data); (*hci_ev)->length += report->data_len; diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index fec16e8689..f298ac1aed 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -705,7 +705,7 @@ ble_ll_sync_send_per_adv_rpt(struct ble_ll_sync_sm *sm, struct os_mbuf *rxpdu, ev->rssi = rssi; ev->cte_type = 0xff; - ev->data_len = min(max_data_len, datalen - offset); + ev->data_len = MIN(max_data_len, datalen - offset); /* adjust event length */ hci_ev->length += ev->data_len; diff --git a/nimble/controller/src/ble_ll_utils.c b/nimble/controller/src/ble_ll_utils.c index 1921ee72a3..3603742d97 100644 --- a/nimble/controller/src/ble_ll_utils.c +++ b/nimble/controller/src/ble_ll_utils.c @@ -458,8 +458,8 @@ ble_ll_utils_dci_iso_subevent(uint16_t chan_id, uint16_t *prn_sub_lu, /* Core 5.3, Vol 6, Part B, 4.5.8.3.6 (enjoy!) */ /* TODO optimize this somehow */ - d = max(1, max(min(3, num_used_chans - 5), - min(11, (num_used_chans - 10) / 2))); + d = MAX(1, MAX(MIN(3, num_used_chans - 5), + MIN(11, (num_used_chans - 10) / 2))); *remap_idx = (*remap_idx + d + prn_sub_se * (num_used_chans - 2 * d + 1) / 65536) % num_used_chans; From 511ad6a9e678532a35e9a4cc7af8742251fca685 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 2 Feb 2023 18:15:05 +0100 Subject: [PATCH 0640/1333] nimble/ll: Fix MAX macro There was a copy'n'paste type in MAX macro. --- nimble/controller/include/controller/ble_ll_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/include/controller/ble_ll_utils.h b/nimble/controller/include/controller/ble_ll_utils.h index fe1bca9f67..629a894bba 100644 --- a/nimble/controller/include/controller/ble_ll_utils.h +++ b/nimble/controller/include/controller/ble_ll_utils.h @@ -24,7 +24,7 @@ #define INT16_LTE(_a, _b) ((int16_t)((_a) - (_b)) <= 0) #define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) -#define MAX(_a, _b) ((_a) < (_b) ? (_a) : (_b)) +#define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b)) #define CLAMP(_n, _min, _max) (MAX(_min, MIN(_n, _max))) #define IN_RANGE(_n, _min, _max) (((_n) >= (_min)) && ((_n) <= (_max))) From 5f7ca7062877edd75983b8ef6eccc22e5826d0b0 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 30 Jan 2023 17:26:31 +0100 Subject: [PATCH 0641/1333] nimble/phy: Add setting for header mask for encryption ISO PDUs require different bits to be masked out in PDU header than standard data PDUs (Core 5.3, Vol 6, Part E, 2.2) when generating keystream for encryption/decrytpion so we need to be able to set such mask. For now this only works on nRF5340 as it has dedicated support for that. Header mask is always reset to default (data PDU) to avoid changing lots of old code. --- nimble/controller/include/controller/ble_ll_pdu.h | 5 +++++ nimble/controller/include/controller/ble_phy.h | 2 ++ nimble/drivers/nrf5x/src/ble_phy.c | 11 +++++++++++ 3 files changed, 18 insertions(+) diff --git a/nimble/controller/include/controller/ble_ll_pdu.h b/nimble/controller/include/controller/ble_ll_pdu.h index 60eef83368..b18db94482 100644 --- a/nimble/controller/include/controller/ble_ll_pdu.h +++ b/nimble/controller/include/controller/ble_ll_pdu.h @@ -26,6 +26,11 @@ extern "C" { #endif +/* Header mask for keystream generation */ +#define BLE_LL_PDU_HEADERMASK_DATA (0xe3) +#define BLE_LL_PDU_HEADERMASK_BIS (0xc3) +#define BLE_LL_PDU_HEADERMASK_CIS (0xa3) + #define BLE_LL_PDU_PREAMBLE_1M_LEN (1) #define BLE_LL_PDU_PREAMBLE_2M_LEN (2) #define BLE_LL_PDU_AA_LEN (4) diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index 902ac0342c..bba8bccbf8 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -165,6 +165,8 @@ uint32_t ble_phy_access_addr_get(void); /* Enable encryption */ void ble_phy_encrypt_enable(const uint8_t *key); +/* Set mask for PDU header (see Core 5.3, Vol 6, Part E, 2.2) */ +void ble_phy_encrypt_header_mask_set(uint8_t mask); /* Set encryption IV */ void ble_phy_encrypt_iv_set(const uint8_t *iv); /* Set encryption packet counter and direction bit */ diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 1e5fc5c3f5..3e0953294c 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -1700,6 +1700,17 @@ ble_phy_encrypt_enable(const uint8_t *key) g_ble_phy_data.phy_encrypted = 1; NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Disabled; NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled; +#ifdef NRF5340_XXAA + NRF_CCM->HEADERMASK = BLE_LL_PDU_HEADERMASK_DATA; +#endif +} + +void +ble_phy_encrypt_header_mask_set(uint8_t mask) +{ +#ifdef NRF5340_XXAA + NRF_CCM->HEADERMASK = mask; +#endif } void From f5c918d1b598052af2d61bf4a837d1033e11a200 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 31 Jan 2023 00:30:43 +0100 Subject: [PATCH 0642/1333] nimble/phy/nrf5x: Add workaround to allow encrypted ISO on nRF52840 nRF52840 does not allow to change mask for PDU header for keystream generation, but we can workaround this by masking bits out manually and then restoring original header byte after keystream is generated. This only works for TX (e.g. ISO Broadcaster) but it may still be useful. --- nimble/drivers/nrf5x/src/ble_phy.c | 43 +++++++++++++++++++++++++++++ nimble/drivers/nrf5x/src/phy_priv.h | 5 ++++ nimble/drivers/nrf5x/syscfg.yml | 9 ++++++ 3 files changed, 57 insertions(+) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 3e0953294c..c1e2df7259 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -140,6 +140,10 @@ struct ble_phy_obj uint8_t phy_transition_late; uint8_t phy_rx_started; uint8_t phy_encrypted; +#if PHY_USE_HEADERMASK_WORKAROUND + uint8_t phy_headermask; + uint8_t phy_headerbyte; +#endif uint8_t phy_privacy; uint8_t phy_tx_pyld_len; uint8_t phy_cur_phy_mode; @@ -1517,6 +1521,20 @@ ble_phy_isr(void) os_trace_isr_exit(); } +#if PHY_USE_HEADERMASK_WORKAROUND +static void +ble_phy_ccm_isr(void) +{ + volatile uint8_t *tx_buf = (uint8_t *)g_ble_phy_tx_buf; + + if (NRF_CCM->EVENTS_ENDKSGEN) { + while (tx_buf[0] == 0xff); + tx_buf[0] = g_ble_phy_data.phy_headerbyte; + NRF_CCM->INTENCLR = CCM_INTENCLR_ENDKSGEN_Msk; + } +} +#endif + /** * ble phy init * @@ -1599,6 +1617,12 @@ ble_phy_init(void) NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; NRF_CCM->EVENTS_ERROR = 0; memset(g_nrf_encrypt_scratchpad, 0, sizeof(g_nrf_encrypt_scratchpad)); + +#if PHY_USE_HEADERMASK_WORKAROUND + NVIC_SetVector(CCM_AAR_IRQn, (uint32_t)ble_phy_ccm_isr); + NVIC_EnableIRQ(CCM_AAR_IRQn); + NRF_CCM->INTENCLR = CCM_INTENCLR_ENDKSGEN_Msk;; +#endif #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) @@ -1703,6 +1727,9 @@ ble_phy_encrypt_enable(const uint8_t *key) #ifdef NRF5340_XXAA NRF_CCM->HEADERMASK = BLE_LL_PDU_HEADERMASK_DATA; #endif +#if PHY_USE_HEADERMASK_WORKAROUND + g_ble_phy_data.phy_headermask = BLE_LL_PDU_HEADERMASK_DATA; +#endif } void @@ -1711,6 +1738,9 @@ ble_phy_encrypt_header_mask_set(uint8_t mask) #ifdef NRF5340_XXAA NRF_CCM->HEADERMASK = mask; #endif +#if PHY_USE_HEADERMASK_WORKAROUND + g_ble_phy_data.phy_headermask = mask; +#endif } void @@ -1914,6 +1944,15 @@ ble_phy_tx(ble_phy_tx_pducb_t pducb, void *pducb_arg, uint8_t end_trans) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) /* Start key-stream generation and encryption (via short) */ if (g_ble_phy_data.phy_encrypted) { +#if PHY_USE_HEADERMASK_WORKAROUND + if (g_ble_phy_data.phy_headermask != BLE_LL_PDU_HEADERMASK_DATA) { + g_ble_phy_data.phy_headerbyte = dptr[0]; + dptr[0] &= g_ble_phy_data.phy_headermask; + g_ble_phy_tx_buf[0] = 0xffffffff; + NRF_CCM->EVENTS_ENDKSGEN = 0; + NRF_CCM->INTENSET = CCM_INTENSET_ENDKSGEN_Msk; + } +#endif nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); } #endif @@ -2134,6 +2173,10 @@ ble_phy_disable(void) { ble_phy_trace_void(BLE_PHY_TRACE_ID_DISABLE); +#if PHY_USE_HEADERMASK_WORKAROUND + NRF_CCM->INTENCLR = CCM_INTENCLR_ENDKSGEN_Msk; +#endif + ble_phy_stop_usec_timer(); ble_phy_disable_irq_and_ppi(); diff --git a/nimble/drivers/nrf5x/src/phy_priv.h b/nimble/drivers/nrf5x/src/phy_priv.h index 664d625c97..c732352032 100644 --- a/nimble/drivers/nrf5x/src/phy_priv.h +++ b/nimble/drivers/nrf5x/src/phy_priv.h @@ -24,6 +24,11 @@ #include #include + +#if defined(NRF52840_XXAA) && MYNEWT_VAL(BLE_PHY_NRF52_HEADERMASK_WORKAROUND) +#define PHY_USE_HEADERMASK_WORKAROUND 1 +#endif + #define PHY_USE_DEBUG_1 (MYNEWT_VAL(BLE_PHY_DBG_TIME_TXRXEN_READY_PIN) >= 0) #define PHY_USE_DEBUG_2 (MYNEWT_VAL(BLE_PHY_DBG_TIME_ADDRESS_END_PIN) >= 0) #define PHY_USE_DEBUG_3 (MYNEWT_VAL(BLE_PHY_DBG_TIME_WFR_PIN) >= 0) diff --git a/nimble/drivers/nrf5x/syscfg.yml b/nimble/drivers/nrf5x/syscfg.yml index 3c8339c0ab..e483e844be 100644 --- a/nimble/drivers/nrf5x/syscfg.yml +++ b/nimble/drivers/nrf5x/syscfg.yml @@ -55,6 +55,15 @@ syscfg.defs: This can be used to check if wfr is calculated properly. value: -1 + BLE_PHY_NRF52_HEADERMASK_WORKAROUND: + description: > + This enables workaround for lack of HEADERMASK register on some + nRF52 family MCUs (notably nRF52840) which is required for enabling + encryption for ISO PDUs. + Note: this requires exclusive access to CCM_AAR interrupt and only + works for TX (i.e. ISO Broadcaster). + value: 0 + BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR: description: > Ublox BMD-345 modules come with public address preprogrammed From c995fe4fc40cfdb0967c98bff53f7d0bcc36030e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 31 Jan 2023 11:23:20 +0100 Subject: [PATCH 0643/1333] nimble/ll: Optimize num used channels calculation popcount calculates number of bits set without loop. --- nimble/controller/src/ble_ll_utils.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/nimble/controller/src/ble_ll_utils.c b/nimble/controller/src/ble_ll_utils.c index 3603742d97..5d023b115d 100644 --- a/nimble/controller/src/ble_ll_utils.c +++ b/nimble/controller/src/ble_ll_utils.c @@ -253,21 +253,8 @@ ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap) uint8_t ble_ll_utils_calc_num_used_chans(const uint8_t *chan_map) { - uint32_t u32 = 0; - uint32_t num_used_chans = 0; - unsigned idx; - - for (idx = 0; idx < 37; idx++) { - if ((idx % 8) == 0) { - u32 = chan_map[idx / 8]; - } - if (u32 & 1) { - num_used_chans++; - } - u32 >>= 1; - } - - return num_used_chans; + return __builtin_popcountll(((uint64_t)(chan_map[4] & 0x1f) << 32) | + get_le32(chan_map)); } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) From 4cd3b3b8d614482090e87d40795f0eab06ed81f2 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 31 Jan 2023 12:18:04 +0100 Subject: [PATCH 0644/1333] nimble/ll: Use consistent chan_map naming --- nimble/controller/include/controller/ble_ll.h | 2 +- .../include/controller/ble_ll_conn.h | 4 +- .../include/controller/ble_ll_utils.h | 11 ++- nimble/controller/src/ble_ll.c | 2 +- nimble/controller/src/ble_ll_adv.c | 4 +- nimble/controller/src/ble_ll_conn.c | 28 +++--- nimble/controller/src/ble_ll_conn_hci.c | 4 +- nimble/controller/src/ble_ll_sync.c | 77 ++++++++-------- nimble/controller/src/ble_ll_utils.c | 18 ++-- nimble/controller/test/src/ble_ll_csa2_test.c | 90 +++++++++---------- 10 files changed, 121 insertions(+), 119 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 9fe3fb8f01..35b562a9b4 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -107,8 +107,8 @@ struct ble_ll_obj uint8_t ll_state; /* Global channel map */ - uint8_t chan_map_num_used; uint8_t chan_map[BLE_LL_CHAN_MAP_LEN]; + uint8_t chan_map_used; #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) /* Number of ACL data packets supported */ diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index c849794281..a44e802e3e 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -240,14 +240,14 @@ struct ble_ll_conn_sm #endif /* Used to calculate data channel index for connection */ - uint8_t chanmap[BLE_LL_CHAN_MAP_LEN]; + uint8_t chan_map[BLE_LL_CHAN_MAP_LEN]; uint8_t req_chanmap[BLE_LL_CHAN_MAP_LEN]; uint16_t chanmap_instant; uint16_t channel_id; /* TODO could be union with hop and last chan used */ uint8_t hop_inc; uint8_t data_chan_index; uint8_t last_unmapped_chan; - uint8_t num_used_chans; + uint8_t chan_map_used; /* Ack/Flow Control */ uint8_t tx_seqnum; /* note: can be 1 bit */ diff --git a/nimble/controller/include/controller/ble_ll_utils.h b/nimble/controller/include/controller/ble_ll_utils.h index 629a894bba..291872bfb8 100644 --- a/nimble/controller/include/controller/ble_ll_utils.h +++ b/nimble/controller/include/controller/ble_ll_utils.h @@ -32,16 +32,19 @@ int ble_ll_utils_verify_aa(uint32_t aa); uint32_t ble_ll_utils_calc_aa(void); uint32_t ble_ll_utils_calc_seed_aa(void); uint32_t ble_ll_utils_calc_big_aa(uint32_t seed_aa, uint32_t n); -uint8_t ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap); + +uint8_t ble_ll_utils_chan_map_remap(const uint8_t *chan_map, uint8_t remap_index); +uint8_t ble_ll_utils_chan_map_used_get(const uint8_t *chan_map); + uint8_t ble_ll_utils_dci_csa2(uint16_t counter, uint16_t chan_id, uint8_t num_used_chans, const uint8_t *chan_map); uint16_t ble_ll_utils_dci_iso_event(uint16_t counter, uint16_t chan_id, - uint16_t *prn_sub_lu, uint8_t num_used_chans, + uint16_t *prn_sub_lu, uint8_t chan_map_used, const uint8_t *chan_map, uint16_t *remap_idx); uint16_t ble_ll_utils_dci_iso_subevent(uint16_t chan_id, uint16_t *prn_sub_lu, - uint8_t num_used_chans, const uint8_t *chan_map, + uint8_t chan_map_used, const uint8_t *chan_map, uint16_t *remap_idx); -uint8_t ble_ll_utils_calc_num_used_chans(const uint8_t *chan_map); + uint32_t ble_ll_utils_calc_window_widening(uint32_t anchor_point, uint32_t last_anchor_point, uint8_t central_sca); diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 8b2395723a..4da7a1f850 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1640,7 +1640,7 @@ ble_ll_reset(void) g_ble_ll_data.ll_pref_rx_phys = phy_mask; /* Enable all channels in channel map */ - g_ble_ll_data.chan_map_num_used = BLE_PHY_NUM_DATA_CHANS; + g_ble_ll_data.chan_map_used = BLE_PHY_NUM_DATA_CHANS; memset(g_ble_ll_data.chan_map, 0xff, BLE_LL_CHAN_MAP_LEN - 1); g_ble_ll_data.chan_map[4] = 0x1f; diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index dfa41bc782..1173c193c0 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1474,7 +1474,7 @@ ble_ll_adv_aux_calculate(struct ble_ll_adv_sm *advsm, #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) aux->chan = ble_ll_utils_dci_csa2(advsm->event_cntr++, advsm->channel_id, - g_ble_ll_data.chan_map_num_used, + g_ble_ll_data.chan_map_used, g_ble_ll_data.chan_map); #else aux->chan = ble_ll_utils_remapped_channel(ble_ll_rand() % BLE_PHY_NUM_DATA_CHANS, @@ -2609,7 +2609,7 @@ ble_ll_adv_sm_start_periodic(struct ble_ll_adv_sm *advsm) /* keep channel map since we cannot change it later on */ memcpy(advsm->periodic_chanmap, g_ble_ll_data.chan_map, BLE_LL_CHAN_MAP_LEN); - advsm->periodic_num_used_chans = g_ble_ll_data.chan_map_num_used; + advsm->periodic_num_used_chans = g_ble_ll_data.chan_map_used; advsm->periodic_event_cntr = 0; /* for chaining we start with random counter as we share access addr */ advsm->periodic_chain_event_cntr = ble_ll_rand(); diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 8f75ecd2de..8992c386f9 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -776,14 +776,14 @@ ble_ll_conn_calc_dci_csa1(struct ble_ll_conn_sm *conn) /* Is this a valid channel? */ bitpos = 1 << (curchan & 0x07); - if (conn->chanmap[curchan >> 3] & bitpos) { + if (conn->chan_map[curchan >> 3] & bitpos) { return curchan; } /* Calculate remap index */ - remap_index = curchan % conn->num_used_chans; + remap_index = curchan % conn->chan_map_used; - return ble_ll_utils_remapped_channel(remap_index, conn->chanmap); + return ble_ll_utils_chan_map_remap(conn->chan_map, remap_index); } /** @@ -803,7 +803,7 @@ ble_ll_conn_calc_dci(struct ble_ll_conn_sm *conn, uint16_t latency) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) if (CONN_F_CSA2_SUPP(conn)) { return ble_ll_utils_dci_csa2(conn->event_cntr, conn->channel_id, - conn->num_used_chans, conn->chanmap); + conn->chan_map_used, conn->chan_map); } #endif @@ -1756,8 +1756,8 @@ ble_ll_conn_central_common_init(struct ble_ll_conn_sm *connsm) connsm->hop_inc = (ble_ll_rand() % 12) + 5; /* Set channel map to map requested by host */ - connsm->num_used_chans = g_ble_ll_data.chan_map_num_used; - memcpy(connsm->chanmap, g_ble_ll_data.chan_map, BLE_LL_CHAN_MAP_LEN); + connsm->chan_map_used = g_ble_ll_data.chan_map_used; + memcpy(connsm->chan_map, g_ble_ll_data.chan_map, BLE_LL_CHAN_MAP_LEN); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) connsm->acc_subrate_min = g_ble_ll_conn_params.acc_subrate_min; @@ -2605,9 +2605,9 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) * the queue of the central. This means that we never successfully * transmitted update request. Would end up killing connection on peripheral side. Could ignore it or see if still enqueued. */ - connsm->num_used_chans = - ble_ll_utils_calc_num_used_chans(connsm->req_chanmap); - memcpy(connsm->chanmap, connsm->req_chanmap, BLE_LL_CHAN_MAP_LEN); + connsm->chan_map_used = + ble_ll_utils_chan_map_used_get(connsm->req_chanmap); + memcpy(connsm->chan_map, connsm->req_chanmap, BLE_LL_CHAN_MAP_LEN); connsm->csmflags.cfbit.chanmap_update_scheduled = 0; @@ -3155,7 +3155,7 @@ ble_ll_conn_tx_connect_ind_pducb(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_by put_le16(dptr + 10, connsm->conn_itvl); put_le16(dptr + 12, connsm->periph_latency); put_le16(dptr + 14, connsm->supervision_tmo); - memcpy(dptr + 16, &connsm->chanmap, BLE_LL_CHAN_MAP_LEN); + memcpy(dptr + 16, &connsm->chan_map, BLE_LL_CHAN_MAP_LEN); dptr[21] = connsm->hop_inc | (connsm->central_sca << 5); *hdr_byte = pdu_data->hdr_byte; @@ -4042,7 +4042,7 @@ ble_ll_conn_set_global_chanmap(uint8_t num_used_chans, const uint8_t *chanmap) } /* Change channel map and cause channel map update procedure to start */ - g_ble_ll_data.chan_map_num_used = num_used_chans; + g_ble_ll_data.chan_map_used = num_used_chans; memcpy(g_ble_ll_data.chan_map, chanmap, BLE_LL_CHAN_MAP_LEN); #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) @@ -4117,7 +4117,7 @@ ble_ll_conn_periph_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr connsm->conn_itvl = get_le16(dptr + 10); connsm->periph_latency = get_le16(dptr + 12); connsm->supervision_tmo = get_le16(dptr + 14); - memcpy(&connsm->chanmap, dptr + 16, BLE_LL_CHAN_MAP_LEN); + memcpy(&connsm->chan_map, dptr + 16, BLE_LL_CHAN_MAP_LEN); connsm->hop_inc = dptr[21] & 0x1F; connsm->central_sca = dptr[21] >> 5; @@ -4155,8 +4155,8 @@ ble_ll_conn_periph_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr connsm->peer_addr_type = pat; /* Calculate number of used channels; make sure it meets min requirement */ - connsm->num_used_chans = ble_ll_utils_calc_num_used_chans(connsm->chanmap); - if (connsm->num_used_chans < 2) { + connsm->chan_map_used = ble_ll_utils_chan_map_used_get(connsm->chan_map); + if (connsm->chan_map_used < 2) { goto err_periph_start; } diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index d0de63ba9e..dbda28bb4b 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1420,7 +1420,7 @@ ble_ll_conn_hci_rd_chan_map(const uint8_t *cmdbuf, uint8_t len, if (connsm->csmflags.cfbit.chanmap_update_scheduled) { memcpy(rsp->chan_map, connsm->req_chanmap, BLE_LL_CHAN_MAP_LEN); } else { - memcpy(rsp->chan_map, connsm->chanmap, BLE_LL_CHAN_MAP_LEN); + memcpy(rsp->chan_map, connsm->chan_map, BLE_LL_CHAN_MAP_LEN); } rc = BLE_ERR_SUCCESS; } @@ -1454,7 +1454,7 @@ ble_ll_conn_hci_set_chan_class(const uint8_t *cmdbuf, uint8_t len) * channel but the Link Layer needs minimum two channels to operate. So * I will not allow this command if there are less than 2 channels masked. */ - num_used_chans = ble_ll_utils_calc_num_used_chans(cmd->chan_map); + num_used_chans = ble_ll_utils_chan_map_used_get(cmd->chan_map); if ((num_used_chans < 2) || ((cmd->chan_map[4] & 0xe0) != 0)) { return BLE_ERR_INV_HCI_CMD_PARMS; } diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index f298ac1aed..971f879909 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -64,7 +64,6 @@ #define BLE_LL_SYNC_SM_FLAG_NEW_CHANMAP 0x0200 #define BLE_LL_SYNC_SM_FLAG_CHAIN 0x0400 -#define BLE_LL_SYNC_CHMAP_LEN 5 #define BLE_LL_SYNC_ITVL_USECS 1250 struct ble_ll_sync_sm { @@ -75,11 +74,11 @@ struct ble_ll_sync_sm { uint8_t adv_addr_type; uint8_t sca; - uint8_t chanmap[BLE_LL_SYNC_CHMAP_LEN]; - uint8_t num_used_chans; + uint8_t chan_map[BLE_LL_CHAN_MAP_LEN]; + uint8_t chan_map_used; - uint8_t chanmap_new[BLE_LL_SYNC_CHMAP_LEN]; - uint16_t chanmap_new_instant; + uint8_t chan_map_new[BLE_LL_CHAN_MAP_LEN]; + uint16_t chan_map_new_instant; uint8_t chan_index; uint8_t chan_chain; @@ -997,18 +996,18 @@ ble_ll_sync_check_acad(struct ble_ll_sync_sm *sm, /* Channels Mask (37 bits) * TODO should we check this? */ - sm->chanmap_new[0] = chmu->map[0]; - sm->chanmap_new[1] = chmu->map[1]; - sm->chanmap_new[2] = chmu->map[2]; - sm->chanmap_new[3] = chmu->map[3]; - sm->chanmap_new[4] = chmu->map[4] & 0x1f; + sm->chan_map_new[0] = chmu->map[0]; + sm->chan_map_new[1] = chmu->map[1]; + sm->chan_map_new[2] = chmu->map[2]; + sm->chan_map_new[3] = chmu->map[3]; + sm->chan_map_new[4] = chmu->map[4] & 0x1f; /* drop if channel map is invalid */ - if (ble_ll_utils_calc_num_used_chans(sm->chanmap_new) == 0) { + if (ble_ll_utils_chan_map_used_get(sm->chan_map_new) == 0) { return false; } - sm->chanmap_new_instant = le16toh(chmu->instant); + sm->chan_map_new_instant = le16toh(chmu->instant); sm->flags |= BLE_LL_SYNC_SM_FLAG_NEW_CHANMAP; break; default: @@ -1165,21 +1164,21 @@ ble_ll_sync_next_event(struct ble_ll_sync_sm *sm, uint32_t cur_ww_adjust) /* update channel map if needed */ if (sm->flags & BLE_LL_SYNC_SM_FLAG_NEW_CHANMAP) { - if (((int16_t)(sm->event_cntr - sm->chanmap_new_instant)) >= 0) { + if (((int16_t)(sm->event_cntr - sm->chan_map_new_instant)) >= 0) { /* map was verified on reception */ - sm->chanmap[0] = sm->chanmap_new[0]; - sm->chanmap[1] = sm->chanmap_new[1]; - sm->chanmap[2] = sm->chanmap_new[2]; - sm->chanmap[3] = sm->chanmap_new[3]; - sm->chanmap[4] = sm->chanmap_new[4]; - sm->num_used_chans = ble_ll_utils_calc_num_used_chans(sm->chanmap); + sm->chan_map[0] = sm->chan_map_new[0]; + sm->chan_map[1] = sm->chan_map_new[1]; + sm->chan_map[2] = sm->chan_map_new[2]; + sm->chan_map[3] = sm->chan_map_new[3]; + sm->chan_map[4] = sm->chan_map_new[4]; + sm->chan_map_used = ble_ll_utils_chan_map_used_get(sm->chan_map); sm->flags &= ~BLE_LL_SYNC_SM_FLAG_NEW_CHANMAP; } } /* Calculate channel index of next event */ sm->chan_index = ble_ll_utils_dci_csa2(sm->event_cntr, sm->channel_id, - sm->num_used_chans, sm->chanmap); + sm->chan_map_used, sm->chan_map); cur_ww = ble_ll_utils_calc_window_widening(sm->anchor_point, sm->last_anchor_point, @@ -1373,12 +1372,12 @@ ble_ll_sync_info_event(struct ble_ll_scan_addr_data *addrd, sm->itvl_ticks = ble_ll_tmr_u2t_r(usecs, &sm->itvl_usecs); /* Channels Mask (37 bits) */ - sm->chanmap[0] = syncinfo[4]; - sm->chanmap[1] = syncinfo[5]; - sm->chanmap[2] = syncinfo[6]; - sm->chanmap[3] = syncinfo[7]; - sm->chanmap[4] = syncinfo[8] & 0x1f; - sm->num_used_chans = ble_ll_utils_calc_num_used_chans(sm->chanmap); + sm->chan_map[0] = syncinfo[4]; + sm->chan_map[1] = syncinfo[5]; + sm->chan_map[2] = syncinfo[6]; + sm->chan_map[3] = syncinfo[7]; + sm->chan_map[4] = syncinfo[8] & 0x1f; + sm->chan_map_used = ble_ll_utils_chan_map_used_get(sm->chan_map); /* SCA (3 bits) */ sm->sca = syncinfo[8] >> 5; @@ -1410,7 +1409,7 @@ ble_ll_sync_info_event(struct ble_ll_scan_addr_data *addrd, /* Calculate channel index of first event */ sm->chan_index = ble_ll_utils_dci_csa2(sm->event_cntr, sm->channel_id, - sm->num_used_chans, sm->chanmap); + sm->chan_map_used, sm->chan_map); if (ble_ll_sched_sync(&sm->sch, rxhdr->beg_cputime, rxhdr->rem_usecs, offset, sm->phy_mode)) { @@ -1945,12 +1944,12 @@ ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, sm->itvl_ticks = ble_ll_tmr_u2t_r(itvl_usecs, &sm->itvl_usecs); /* Channels Mask (37 bits) */ - sm->chanmap[0] = syncinfo[4]; - sm->chanmap[1] = syncinfo[5]; - sm->chanmap[2] = syncinfo[6]; - sm->chanmap[3] = syncinfo[7]; - sm->chanmap[4] = syncinfo[8] & 0x1f; - sm->num_used_chans = ble_ll_utils_calc_num_used_chans(sm->chanmap); + sm->chan_map[0] = syncinfo[4]; + sm->chan_map[1] = syncinfo[5]; + sm->chan_map[2] = syncinfo[6]; + sm->chan_map[3] = syncinfo[7]; + sm->chan_map[4] = syncinfo[8] & 0x1f; + sm->chan_map_used = ble_ll_utils_chan_map_used_get(sm->chan_map); /* SCA (3 bits) */ sm->sca = syncinfo[8] >> 5; @@ -1978,7 +1977,7 @@ ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, /* Calculate channel index of first event */ sm->chan_index = ble_ll_utils_dci_csa2(sm->event_cntr, sm->channel_id, - sm->num_used_chans, sm->chanmap); + sm->chan_map_used, sm->chan_map); /* get anchor for specified conn event */ conn_event_count = get_le16(sync_ind + 20); @@ -2075,11 +2074,11 @@ ble_ll_sync_put_syncinfo(struct ble_ll_sync_sm *syncsm, put_le16(&dptr[2], syncsm->itvl); /* Channels Mask (37 bits) */ - dptr[4] = syncsm->chanmap[0]; - dptr[5] = syncsm->chanmap[1]; - dptr[6] = syncsm->chanmap[2]; - dptr[7] = syncsm->chanmap[3]; - dptr[8] = syncsm->chanmap[4] & 0x1f; + dptr[4] = syncsm->chan_map[0]; + dptr[5] = syncsm->chan_map[1]; + dptr[6] = syncsm->chan_map[2]; + dptr[7] = syncsm->chan_map[3]; + dptr[8] = syncsm->chan_map[4] & 0x1f; /* SCA (3 bits) */ dptr[8] |= syncsm->sca << 5; diff --git a/nimble/controller/src/ble_ll_utils.c b/nimble/controller/src/ble_ll_utils.c index 5d023b115d..9fa32f8fc7 100644 --- a/nimble/controller/src/ble_ll_utils.c +++ b/nimble/controller/src/ble_ll_utils.c @@ -214,7 +214,7 @@ ble_ll_utils_calc_big_aa(uint32_t seed_aa, uint32_t n) } uint8_t -ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap) +ble_ll_utils_chan_map_remap(const uint8_t *chan_map, uint8_t remap_index) { uint8_t cntr; uint8_t mask; @@ -229,7 +229,7 @@ ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap) chan = 0; cntr = 0; for (i = 0; i < BLE_LL_CHMAP_LEN; i++) { - usable_chans = chanmap[i]; + usable_chans = chan_map[i]; if (usable_chans != 0) { mask = 0x01; for (j = 0; j < 8; j++) { @@ -251,7 +251,7 @@ ble_ll_utils_remapped_channel(uint8_t remap_index, const uint8_t *chanmap) } uint8_t -ble_ll_utils_calc_num_used_chans(const uint8_t *chan_map) +ble_ll_utils_chan_map_used_get(const uint8_t *chan_map) { return __builtin_popcountll(((uint64_t)(chan_map[4] & 0x1f) << 32) | get_le32(chan_map)); @@ -412,7 +412,7 @@ ble_ll_utils_dci_csa2(uint16_t counter, uint16_t chan_id, uint16_t ble_ll_utils_dci_iso_event(uint16_t counter, uint16_t chan_id, - uint16_t *prn_sub_lu, uint8_t num_used_chans, + uint16_t *prn_sub_lu, uint8_t chan_map_used, const uint8_t *chan_map, uint16_t *remap_idx) { uint16_t prn_s; @@ -424,7 +424,7 @@ ble_ll_utils_dci_iso_event(uint16_t counter, uint16_t chan_id, *prn_sub_lu = prn_s; - chan_idx = ble_ll_utils_csa2_calc_chan_idx(prn_e, num_used_chans, chan_map, + chan_idx = ble_ll_utils_csa2_calc_chan_idx(prn_e, chan_map_used, chan_map, remap_idx); return chan_idx; @@ -432,7 +432,7 @@ ble_ll_utils_dci_iso_event(uint16_t counter, uint16_t chan_id, uint16_t ble_ll_utils_dci_iso_subevent(uint16_t chan_id, uint16_t *prn_sub_lu, - uint8_t num_used_chans, const uint8_t *chan_map, + uint8_t chan_map_used, const uint8_t *chan_map, uint16_t *remap_idx) { uint16_t prn_sub_se; @@ -445,10 +445,10 @@ ble_ll_utils_dci_iso_subevent(uint16_t chan_id, uint16_t *prn_sub_lu, /* Core 5.3, Vol 6, Part B, 4.5.8.3.6 (enjoy!) */ /* TODO optimize this somehow */ - d = MAX(1, MAX(MIN(3, num_used_chans - 5), - MIN(11, (num_used_chans - 10) / 2))); + d = MAX(1, MAX(MIN(3, chan_map_used - 5), + MIN(11, (chan_map_used - 10) / 2))); *remap_idx = (*remap_idx + d + prn_sub_se * - (num_used_chans - 2 * d + 1) / 65536) % num_used_chans; + (chan_map_used - 2 * d + 1) / 65536) % chan_map_used; chan_idx = ble_ll_utils_csa2_remap2chan(*remap_idx, chan_map); diff --git a/nimble/controller/test/src/ble_ll_csa2_test.c b/nimble/controller/test/src/ble_ll_csa2_test.c index ae8f8897d1..d7d43dcfb6 100644 --- a/nimble/controller/test/src/ble_ll_csa2_test.c +++ b/nimble/controller/test/src/ble_ll_csa2_test.c @@ -44,12 +44,12 @@ TEST_CASE_SELF(ble_ll_csa2_test_1) conn.channel_id = ((0x8e89bed6 & 0xffff0000) >> 16) ^ (0x8e89bed6 & 0x0000ffff); - conn.num_used_chans = 37; - conn.chanmap[0] = 0xff; - conn.chanmap[1] = 0xff; - conn.chanmap[2] = 0xff; - conn.chanmap[3] = 0xff; - conn.chanmap[4] = 0x1f; + conn.chan_map_used = 37; + conn.chan_map[0] = 0xff; + conn.chan_map[1] = 0xff; + conn.chan_map[2] = 0xff; + conn.chan_map[3] = 0xff; + conn.chan_map[4] = 0x1f; conn.event_cntr = 1; rc = ble_ll_conn_calc_dci(&conn, 0); @@ -86,12 +86,12 @@ TEST_CASE_SELF(ble_ll_csa2_test_2) conn.channel_id = ((0x8e89bed6 & 0xffff0000) >> 16) ^ (0x8e89bed6 & 0x0000ffff); - conn.num_used_chans = 9; - conn.chanmap[0] = 0x00; - conn.chanmap[1] = 0x06; - conn.chanmap[2] = 0xe0; - conn.chanmap[3] = 0x00; - conn.chanmap[4] = 0x1e; + conn.chan_map_used = 9; + conn.chan_map[0] = 0x00; + conn.chan_map[1] = 0x06; + conn.chan_map[2] = 0xe0; + conn.chan_map[3] = 0x00; + conn.chan_map[4] = 0x1e; conn.event_cntr = 6; rc = ble_ll_conn_calc_dci(&conn, 0); @@ -109,7 +109,7 @@ TEST_CASE_SELF(ble_ll_csa2_test_2) TEST_CASE_SELF(ble_ll_csa2_test_3) { uint8_t chan_map[5]; - uint8_t num_used_chans; + uint8_t chan_map_used; uint16_t chan_id; uint16_t prn_sub_lu; uint16_t chan_idx; @@ -121,86 +121,86 @@ TEST_CASE_SELF(ble_ll_csa2_test_3) chan_map[2] = 0xff; chan_map[3] = 0xff; chan_map[4] = 0x1f; - num_used_chans = ble_ll_utils_calc_num_used_chans(chan_map); - TEST_ASSERT(num_used_chans == 37); + chan_map_used = ble_ll_utils_chan_map_used_get(chan_map); + TEST_ASSERT(chan_map_used == 37); chan_id = 0x305f; - chan_idx = ble_ll_utils_dci_iso_event(0, chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_event(0, chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 56857); TEST_ASSERT(chan_idx == 25); TEST_ASSERT(remap_idx == 25); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 11710); TEST_ASSERT(chan_idx == 1); TEST_ASSERT(remap_idx == 1); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 16649); TEST_ASSERT(chan_idx == 16); TEST_ASSERT(remap_idx == 16); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 38198); TEST_ASSERT(chan_idx == 36); TEST_ASSERT(remap_idx == 36); - chan_idx = ble_ll_utils_dci_iso_event(1, chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_event(1, chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 1685); TEST_ASSERT(chan_idx == 20); TEST_ASSERT(remap_idx == 20); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 20925); TEST_ASSERT(chan_idx == 36); TEST_ASSERT(remap_idx == 36); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 11081); TEST_ASSERT(chan_idx == 12); TEST_ASSERT(remap_idx == 12); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 48920); TEST_ASSERT(chan_idx == 34); TEST_ASSERT(remap_idx == 34); - chan_idx = ble_ll_utils_dci_iso_event(2, chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_event(2, chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 38301); TEST_ASSERT(chan_idx == 6); TEST_ASSERT(remap_idx == 6); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 6541); TEST_ASSERT(chan_idx == 18); TEST_ASSERT(remap_idx == 18); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 14597); TEST_ASSERT(chan_idx == 32); TEST_ASSERT(remap_idx == 32); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 62982); TEST_ASSERT(chan_idx == 21); TEST_ASSERT(remap_idx == 21); - chan_idx = ble_ll_utils_dci_iso_event(3, chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_event(3, chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 27475); TEST_ASSERT(chan_idx == 21); TEST_ASSERT(remap_idx == 21); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 40400); TEST_ASSERT(chan_idx == 4); TEST_ASSERT(remap_idx == 4); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 30015); TEST_ASSERT(chan_idx == 22); TEST_ASSERT(remap_idx == 22); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 49818); TEST_ASSERT(chan_idx == 8); TEST_ASSERT(remap_idx == 8); @@ -211,66 +211,66 @@ TEST_CASE_SELF(ble_ll_csa2_test_3) chan_map[2] = 0xe0; chan_map[3] = 0x00; chan_map[4] = 0x1e; - num_used_chans = ble_ll_utils_calc_num_used_chans(chan_map); - TEST_ASSERT(num_used_chans == 9); + chan_map_used = ble_ll_utils_chan_map_used_get(chan_map); + TEST_ASSERT(chan_map_used == 9); chan_id = 0x305f; - chan_idx = ble_ll_utils_dci_iso_event(6, chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_event(6, chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 10975); TEST_ASSERT(chan_idx == 23); TEST_ASSERT(remap_idx == 4); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 14383); TEST_ASSERT(chan_idx == 35); TEST_ASSERT(remap_idx == 7); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 28946); TEST_ASSERT(chan_idx == 21); TEST_ASSERT(remap_idx == 2); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 61038); TEST_ASSERT(chan_idx == 36); TEST_ASSERT(remap_idx == 8); - chan_idx = ble_ll_utils_dci_iso_event(7, chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_event(7, chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 5490); TEST_ASSERT(chan_idx == 9); TEST_ASSERT(remap_idx == 0); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 4108); TEST_ASSERT(chan_idx == 22); TEST_ASSERT(remap_idx == 3); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 45462); TEST_ASSERT(chan_idx == 36); TEST_ASSERT(remap_idx == 8); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 64381); TEST_ASSERT(chan_idx == 33); TEST_ASSERT(remap_idx == 5); - chan_idx = ble_ll_utils_dci_iso_event(8, chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_event(8, chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 46970); TEST_ASSERT(chan_idx == 34); TEST_ASSERT(remap_idx == 6); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 7196); TEST_ASSERT(chan_idx == 9); TEST_ASSERT(remap_idx == 0); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 33054); TEST_ASSERT(chan_idx == 33); TEST_ASSERT(remap_idx == 5); - chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, num_used_chans, chan_map, &remap_idx); + chan_idx = ble_ll_utils_dci_iso_subevent(chan_id, &prn_sub_lu, chan_map_used, chan_map, &remap_idx); TEST_ASSERT((prn_sub_lu ^ chan_id) == 42590); TEST_ASSERT(chan_idx == 10); TEST_ASSERT(remap_idx == 1); From 94d9faf080c91f5e92c5f2677867a16ef94bc089 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 31 Jan 2023 12:38:58 +0100 Subject: [PATCH 0645/1333] nimble/ll: Fix global chan_map handling Global channel map should be handled by common code so need to move it out of ble_ll_conn. --- .../include/controller/ble_ll_conn.h | 3 ++ nimble/controller/src/ble_ll_conn.c | 20 ++--------- nimble/controller/src/ble_ll_conn_hci.c | 32 ------------------ nimble/controller/src/ble_ll_conn_priv.h | 1 - nimble/controller/src/ble_ll_hci.c | 33 ++++++++++++++++++- 5 files changed, 37 insertions(+), 52 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index a44e802e3e..016e5abd23 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -459,6 +459,9 @@ struct ble_ll_conn_sm *ble_ll_conn_find_by_handle(uint16_t handle); struct ble_ll_conn_sm *ble_ll_conn_find_by_peer_addr(const uint8_t* addr, uint8_t addr_type); +/* Perform channel map update on all connections (applies to central role) */ +void ble_ll_conn_chan_map_update(void); + /* required for unit testing */ uint8_t ble_ll_conn_calc_dci(struct ble_ll_conn_sm *conn, uint16_t latency); diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 8992c386f9..0c6530b51a 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -4023,29 +4023,13 @@ ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t length) } } #endif -/** - * Called to set the global channel mask that we use for all connections. - * - * @param num_used_chans - * @param chanmap - */ + void -ble_ll_conn_set_global_chanmap(uint8_t num_used_chans, const uint8_t *chanmap) +ble_ll_conn_chan_map_update(void) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) struct ble_ll_conn_sm *connsm; -#endif - /* Do nothing if same channel map */ - if (!memcmp(g_ble_ll_data.chan_map, chanmap, BLE_LL_CHAN_MAP_LEN)) { - return; - } - - /* Change channel map and cause channel map update procedure to start */ - g_ble_ll_data.chan_map_used = num_used_chans; - memcpy(g_ble_ll_data.chan_map, chanmap, BLE_LL_CHAN_MAP_LEN); - -#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) /* Perform channel map update */ SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) { if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index dbda28bb4b..5010dddb42 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1432,38 +1432,6 @@ ble_ll_conn_hci_rd_chan_map(const uint8_t *cmdbuf, uint8_t len, } #endif -/** - * Called when the host issues the LE command "set host channel classification" - * - * @param cmdbuf - * - * @return int - */ -int -ble_ll_conn_hci_set_chan_class(const uint8_t *cmdbuf, uint8_t len) -{ - const struct ble_hci_le_set_host_chan_class_cp *cmd = (const void *) cmdbuf; - uint8_t num_used_chans; - - if (len != sizeof(*cmd)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* - * The HCI command states that the host is allowed to mask in just one - * channel but the Link Layer needs minimum two channels to operate. So - * I will not allow this command if there are less than 2 channels masked. - */ - num_used_chans = ble_ll_utils_chan_map_used_get(cmd->chan_map); - if ((num_used_chans < 2) || ((cmd->chan_map[4] & 0xe0) != 0)) { - return BLE_ERR_INV_HCI_CMD_PARMS; - } - - /* Set the host channel mask */ - ble_ll_conn_set_global_chanmap(num_used_chans, cmd->chan_map); - return BLE_ERR_SUCCESS; -} - #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index bb58e4b7a6..023881d0f1 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -182,7 +182,6 @@ int ble_ll_conn_periph_start(uint8_t *rxbuf, uint8_t pat, /* Link Layer interface */ void ble_ll_conn_module_init(void); -void ble_ll_conn_set_global_chanmap(uint8_t num_used_chans, const uint8_t *chanmap); void ble_ll_conn_module_reset(void); void ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t len); int ble_ll_conn_rx_isr_start(struct ble_mbuf_hdr *rxhdr, uint32_t aa); diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index fab304932e..695e65334a 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -33,6 +33,7 @@ #include "controller/ble_ll_whitelist.h" #include "controller/ble_ll_resolv.h" #include "controller/ble_ll_sync.h" +#include #include "controller/ble_ll_iso.h" #include "ble_ll_priv.h" #include "ble_ll_conn_priv.h" @@ -833,6 +834,36 @@ ble_ll_write_rf_path_compensation(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_SUCCESS; } +static int +ble_ll_hci_le_set_host_chan_class(const uint8_t *cmdbuf, uint8_t len) +{ + const struct ble_hci_le_set_host_chan_class_cp *cmd = (const void *)cmdbuf; + uint8_t chan_map_used; + + if (len != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* HCI command allows only single channel to be enabled, but LL needs at + * least 2 channels to work so let's reject in such case. + */ + chan_map_used = ble_ll_utils_chan_map_used_get(cmd->chan_map); + if ((chan_map_used < 2) || (cmd->chan_map[4] & 0xe0)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (!memcmp(g_ble_ll_data.chan_map, cmd->chan_map, BLE_LL_CHAN_MAP_LEN)) { + return BLE_ERR_SUCCESS; + } + + memcpy(g_ble_ll_data.chan_map, cmd->chan_map, BLE_LL_CHAN_MAP_LEN); + g_ble_ll_data.chan_map_used = chan_map_used; + + ble_ll_conn_chan_map_update(); + + return BLE_ERR_SUCCESS; +} + /** * Process a LE command sent from the host to the controller. The HCI command * has a 3 byte command header followed by data. The header is: @@ -957,7 +988,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, break; #endif case BLE_HCI_OCF_LE_SET_HOST_CHAN_CLASS: - rc = ble_ll_conn_hci_set_chan_class(cmdbuf, len); + rc = ble_ll_hci_le_set_host_chan_class(cmdbuf, len); break; #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_HCI_OCF_LE_RD_CHAN_MAP: From 354e7c83329ef4a1b5818de2f44e3a4f86c60437 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 2 Feb 2023 22:45:12 +0100 Subject: [PATCH 0646/1333] ci: Build RIOT port Building against RIOT master branch and thus this is allowed to fail. --- .github/workflows/build_ports.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_ports.yml b/.github/workflows/build_ports.yml index 0d30d453ff..727016d913 100644 --- a/.github/workflows/build_ports.yml +++ b/.github/workflows/build_ports.yml @@ -27,12 +27,24 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + - uses: carlosperate/arm-none-eabi-gcc-action@48db4484a55750df7a0ccca63347fcdea6534d78 + with: + release: '12.2.Rel1' - name: Install Dependencies run: | sudo apt-get update sudo apt-get install -y make ccache gcc-multilib g++-multilib - - name: Build ports + - name: Build example ports run: | make -C porting/examples/dummy/ clean all make -C porting/examples/linux/ clean all make -C porting/examples/linux_blemesh/ clean all + - name: Build RIOT port + if: success() || failure() + continue-on-error: true + run: | + git clone --depth=1 https://github.com/RIOT-OS/RIOT + rm RIOT/pkg/nimble/patches/ -rf + sed -i 's|PKG_URL.*|PKG_URL = '$(pwd)'|' RIOT/pkg/nimble/Makefile + sed -i 's|PKG_VERSION.*|PKG_VERSION = '${{ github.sha }}'|' RIOT/pkg/nimble/Makefile + make -C RIOT/examples/nimble_gatt From 26a70e2ac330a836f7b1a9c08e98c9d80e5c86a2 Mon Sep 17 00:00:00 2001 From: Roshan Date: Fri, 3 Feb 2023 22:34:55 +0530 Subject: [PATCH 0647/1333] NimBLE/host: Remove duplicate parameter description --- nimble/host/src/ble_l2cap.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/nimble/host/src/ble_l2cap.c b/nimble/host/src/ble_l2cap.c index 810d07b3d7..50fe18c651 100644 --- a/nimble/host/src/ble_l2cap.c +++ b/nimble/host/src/ble_l2cap.c @@ -331,10 +331,6 @@ ble_l2cap_get_mtu(struct ble_l2cap_chan *chan) * pointer to the appropriate handler gets * written here. The caller should pass the * receive buffer to this callback. - * @param out_rx_buf If a full L2CAP packet has been received, this - * will point to the entire L2CAP packet. To - * process the packet, pass this buffer to the - * receive handler (out_rx_cb). * @param out_reject_cid Indicates whether an L2CAP Command Reject * command should be sent. If this equals -1, * no reject should get sent. Otherwise, the From f32f28c9e331b9f6b277116afbf7a3a9e9ce984a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 3 Feb 2023 16:10:04 +0100 Subject: [PATCH 0648/1333] Fix uncrustify configuration This changes required aligmnent of closing parenthesis of function call if placed in new line. Before: int x = func(aaa, bbb, ccc, ); After: int x = func(aaa, bbb, ccc, ); The syntax above is not really used, but it also affects macros so may be useful in some cases. --- uncrustify.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uncrustify.cfg b/uncrustify.cfg index 2bdd2ac531..1735f339ad 100644 --- a/uncrustify.cfg +++ b/uncrustify.cfg @@ -225,7 +225,7 @@ indent_paren_nl = false # false/true # 0: Indent to body level # 1: Align under the open paren # 2: Indent to the brace level -indent_paren_close = 0 # number +indent_paren_close = 2 # number # Controls the indent of a comma when inside a paren.If TRUE, aligns under the open paren indent_comma_paren = false # false/true From e657c828a1b99f3e484159fe9e56f421b42ed016 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 3 Feb 2023 16:10:28 +0100 Subject: [PATCH 0649/1333] nimble/ll: Refactor ble_ll_supp_cmd This refactors ble_ll_supp_cmd file to be easier to read and maintain. --- .../include/controller/ble_ll_hci.h | 6 +- nimble/controller/src/ble_ll_hci.c | 3 +- nimble/controller/src/ble_ll_hci_supp_cmd.c | 328 +++++++++ nimble/controller/src/ble_ll_supp_cmd.c | 666 ------------------ 4 files changed, 331 insertions(+), 672 deletions(-) create mode 100644 nimble/controller/src/ble_ll_hci_supp_cmd.c delete mode 100644 nimble/controller/src/ble_ll_supp_cmd.c diff --git a/nimble/controller/include/controller/ble_ll_hci.h b/nimble/controller/include/controller/ble_ll_hci.h index cb0ec033e9..7421e77a05 100644 --- a/nimble/controller/include/controller/ble_ll_hci.h +++ b/nimble/controller/include/controller/ble_ll_hci.h @@ -27,10 +27,6 @@ extern "C" { #include "nimble/hci_common.h" #include "nimble/transport.h" -/* For supported commands */ -#define BLE_LL_SUPP_CMD_LEN (47) -extern const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN]; - /* The largest event the controller will send. */ #define BLE_LL_MAX_EVT_LEN MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE) @@ -83,6 +79,8 @@ bool ble_ll_hci_adv_mode_ext(void); /* Check if max octets/time are within allowed range */ int ble_ll_hci_check_dle(uint16_t max_octets, uint16_t max_time); +void ble_ll_hci_supp_cmd_get(uint8_t *buf); + #if MYNEWT_VAL(BLE_LL_HCI_VS) void ble_ll_hci_vs_register(struct ble_ll_hci_vs_cmd *cmds, uint32_t num_cmds); #endif diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 695e65334a..a7c0718774 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -257,8 +257,7 @@ ble_ll_hci_rd_local_supp_cmd(uint8_t *rspbuf, uint8_t *rsplen) { struct ble_hci_ip_rd_loc_supp_cmd_rp *rsp = (void *) rspbuf; - memset(rsp->commands, 0, sizeof(rsp->commands)); - memcpy(rsp->commands, g_ble_ll_supp_cmds, sizeof(g_ble_ll_supp_cmds)); + ble_ll_hci_supp_cmd_get(rsp->commands); *rsplen = sizeof(*rsp); return BLE_ERR_SUCCESS; diff --git a/nimble/controller/src/ble_ll_hci_supp_cmd.c b/nimble/controller/src/ble_ll_hci_supp_cmd.c new file mode 100644 index 0000000000..8315a1bfda --- /dev/null +++ b/nimble/controller/src/ble_ll_hci_supp_cmd.c @@ -0,0 +1,328 @@ +/* + * 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. + */ + +#include +#include +#include +#include + +/* Magic macros */ +#define BIT(n) (1 << (n)) | +#define OCTET(x) (0 | x 0) + +static const uint8_t octet_0 = OCTET( +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + BIT(5) /* HCI Disconnect */ +#endif +); + +static const uint8_t octet_2 = OCTET( +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + BIT(7) /* HCI Read Remote Version Information */ +#endif +); + +static const uint8_t octet_5 = OCTET( + BIT(6) /* HCI Set Event Mask */ + BIT(7) /* HCI Reset */ +); + +static const uint8_t octet_10 = OCTET( +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) + BIT(5) /* HCI Set Controller To Host Flow Control */ + BIT(6) /* HCI Host Buffer Size */ + BIT(7) /* HCI Host Number Of Completed Packets */ +#endif +); + +static const uint8_t octet_14 = OCTET( + BIT(3) /* HCI Read Local Version Information */ + BIT(5) /* HCI Read Local Supported Features */ +); + +static const uint8_t octet_15 = OCTET( + BIT(1) /* HCI Read BD ADDR */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + BIT(5) /* HCI Read RSSI */ +#endif +); + +static const uint8_t octet_25 = OCTET( + BIT(0) /* HCI LE Set Event Mask */ + BIT(1) /* HCI LE Read Buffer Size [v1] */ + BIT(2) /* HCI LE Read Local Supported Features */ + BIT(4) /* HCI LE Set Random Address */ +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) + BIT(5) /* HCI LE Set Advertising Parameters */ + BIT(6) /* HCI LE Read Advertising Physical Channel Tx Power */ + BIT(7) /* HCI LE Set Advertising Data */ +#endif +); + +static const uint8_t octet_26 = OCTET( +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) + BIT(0) /* HCI LE Set Scan Response Data */ + BIT(1) /* HCI LE Set Advertising Enable */ +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) + BIT(2) /* HCI LE Set Scan Parameters */ + BIT(3) /* HCI LE Set Scan Enable */ +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + BIT(4) /* HCI LE Create Connection */ + BIT(5) /* HCI LE Create Connection Cancel */ +#endif + BIT(6) /* HCI LE Read Filter Accept List Size */ + BIT(7) /* HCI LE Clear Filter Accept List */ +); + +static const uint8_t octet_27 = OCTET( + BIT(0) /* HCI LE Add Device To Filter Accept List */ + BIT(1) /* HCI LE Remove Device From Filter Accept List */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + BIT(2) /* HCI LE Connection Update */ +#endif + BIT(3) /* HCI LE Set Host Channel Classification */ +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + BIT(4) /* HCI LE Read Channel Map */ + BIT(5) /* HCI LE Read Remote Features */ +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) + BIT(6) /* HCI LE Encrypt */ +#endif + BIT(7) /* HCI LE Rand */ +); + +static const uint8_t octet_28 = OCTET( +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + BIT(0) /* HCI LE Enable Encryption */ +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) + BIT(1) /* HCI LE Long Term Key Request Reply */ + BIT(2) /* HCI LE Long Term Key Request Negative Reply */ +#endif +#endif + BIT(3) /* HCI LE Read Supported States */ +#if MYNEWT_VAL(BLE_LL_DTM) + BIT(4) /* HCI LE Receiver Test [v1] */ + BIT(5) /* HCI LE Transmitter Test [v1] */ + BIT(6) /* HCI LE Test End */ +#endif +); + +static const uint8_t octet_33 = OCTET( +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + BIT(4) /* HCI LE Remote Connection Parameter Request Reply */ + BIT(5) /* HCI LE Remote Connection Parameter Request Negative Reply */ +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) + BIT(6) /* HCI LE Set Data Length */ + BIT(7) /* HCI LE Read Suggested Default Data Length */ +#endif +); + +static const uint8_t octet_34 = OCTET( +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) + BIT(0) /* HCI LE Write Suggested Data Length */ +#endif +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + BIT(3) /* HCI LE Add Device To Resolving List */ + BIT(4) /* HCI LE Remove Device From Resolving List */ + BIT(5) /* HCI LE Clear Resolving List */ + BIT(6) /* HCI LE Read Resolving List Size */ + BIT(7) /* HCI LE Read Peer Resolvable Address */ +#endif +); + +static const uint8_t octet_35 = OCTET( +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + BIT(0) /* HCI LE Read Local Resolvable Address */ + BIT(1) /* HCI LE Set Address Resolution Enable */ + BIT(2) /* HCI LE Set Resolvable Private Address Timeout */ +#endif + BIT(3) /* HCI LE Read Maximum Data Length */ +#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + BIT(4) /* HCI LE Read PHY */ + BIT(5) /* HCI LE Set Default PHY */ + BIT(6) /* HCI LE Set PHY */ +#endif +#endif +#if MYNEWT_VAL(BLE_LL_DTM) + BIT(7) /* HCI LE Receiver Test [v2] */ +#endif +); + +static const uint8_t octet_36 = OCTET( +#if MYNEWT_VAL(BLE_LL_DTM) + BIT(0) /* HCI LE Transmitter Test [v2] */ +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) + BIT(1) /* HCI LE Set Advertising Set Random Address */ + BIT(2) /* HCI LE Set Extended Advertising Parameters */ + BIT(3) /* HCI LE Set Extended Advertising Data */ + BIT(4) /* HCI LE Set Extended Scan Response Data */ + BIT(5) /* HCI LE Set Extended Advertising Enable */ + BIT(6) /* HCI LE Read Maximum Advertising Data Length */ + BIT(7) /* HCI LE Read Number of Supported Advertising Sets */ +#endif +); + +static const uint8_t octet_37 = OCTET( +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) + BIT(0) /* HCI LE Remove Advertising Set */ + BIT(1) /* HCI LE Clear Advertising Sets */ +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) + BIT(2) /* HCI LE Set Periodic Advertising Parameters */ + BIT(3) /* HCI LE Set Periodic Advertising Data */ + BIT(4) /* HCI LE Set Periodic Advertising Enable */ +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) + BIT(5) /* HCI LE Set Extended Scan Parameters */ + BIT(6) /* HCI LE Set Extended Scan Enable */ +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + BIT(7) /* HCI LE Extended Create Connection */ +#endif +#endif +); + +static const uint8_t octet_38 = OCTET( +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) + BIT(0) /* HCI LE Periodic Advertising Create Sync */ + BIT(1) /* HCI LE Periodic Advertising Create Sync Cancel */ + BIT(2) /* HCI LE Periodic Advertising Terminate Sync */ + BIT(3) /* HCI LE Add Device To Periodic Advertiser List */ + BIT(4) /* HCI LE Remove Device From Periodic Advertiser List */ + BIT(5) /* HCI LE Clear Periodic Advertiser List */ + BIT(6) /* HCI LE Read Periodic Advertiser List Size */ +#endif + BIT(7) /* HCI LE Read Transmit Power */ +); + +static const uint8_t octet_39 = OCTET( + BIT(0) /* HCI LE Read RF Path Compensation */ + BIT(1) /* HCI LE Write RF Path Compensation */ +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + BIT(2) /* HCI LE Set Privacy Mode */ +#endif +); + +static const uint8_t octet_40 = OCTET( +#if MYNEWT_VAL(BLE_VERSION) >= 51 && MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) + BIT(5) /* HCI LE Set Periodic Advertising Receive Enable */ +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) +#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) + BIT(6) /* HCI LE Periodic Advertising Sync Transfer */ +#endif +#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) + BIT(7) /* HCI LE Periodic Advertising Set Info Transfer */ +#endif +#endif +#endif +); + +static const uint8_t octet_41 = OCTET( +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) + BIT(0) /* HCI LE Set Periodic Advertising Sync Transfer Parameters */ + BIT(1) /* HCI LE Set Default Periodic Advertising Sync Transfer Parameters */ +#endif +); + +static const uint8_t octet_43 = OCTET( +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE) + BIT(2) /* HCI LE Request Peer SCA */ +#endif +); + +static const uint8_t octet_44 = OCTET( +#if MYNEWT_VAL(BLE_VERSION) >= 52 + BIT(1) /* HCI LE Set Host Feature */ +#endif +); + +static const uint8_t octet_46 = OCTET( +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + BIT(0) /* HCI LE Set Default Subrate */ + BIT(1) /* HCI LE Subrate Request */ +#endif +); + +static const uint8_t g_ble_ll_hci_supp_cmds[64] = { + octet_0, + 0, + octet_2, + 0, + 0, + octet_5, + 0, + 0, + 0, + 0, + octet_10, + 0, + 0, + 0, + octet_14, + octet_15, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + octet_25, + octet_26, + octet_27, + octet_28, + 0, + 0, + 0, + 0, + octet_33, + octet_34, + octet_35, + octet_36, + octet_37, + octet_38, + octet_39, + octet_40, + octet_41, + 0, + octet_43, + octet_44, + 0, + octet_46, +}; + +void +ble_ll_hci_supp_cmd_get(uint8_t *buf) +{ + memcpy(buf, g_ble_ll_hci_supp_cmds, sizeof(g_ble_ll_hci_supp_cmds)); +} diff --git a/nimble/controller/src/ble_ll_supp_cmd.c b/nimble/controller/src/ble_ll_supp_cmd.c deleted file mode 100644 index a0493a46a7..0000000000 --- a/nimble/controller/src/ble_ll_supp_cmd.c +++ /dev/null @@ -1,666 +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. - */ - -#include -#include - -#include "nimble/ble.h" -#include "nimble/nimble_opt.h" -#include "nimble/hci_common.h" -#include "controller/ble_ll.h" -#include "controller/ble_ll_hci.h" - -/* Octet 0 */ -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_DISCONNECT (1 << 5) -#else -#define BLE_SUPP_CMD_DISCONNECT (0 << 5) -#endif -#define BLE_LL_SUPP_CMD_OCTET_0 (BLE_SUPP_CMD_DISCONNECT) - -/* Octet 2*/ -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_READ_REM_VER_INFO (1 << 7) -#else -#define BLE_SUPP_CMD_READ_REM_VER_INFO (0 << 7) -#endif -#define BLE_LL_SUPP_CMD_OCTET_2 (BLE_SUPP_CMD_READ_REM_VER_INFO) - -/* Octet 5 */ -#define BLE_SUPP_CMD_SET_EVENT_MASK (1 << 6) -#define BLE_SUPP_CMD_RESET (1 << 7) -#define BLE_LL_SUPP_CMD_OCTET_5 \ -( \ - BLE_SUPP_CMD_SET_EVENT_MASK | \ - BLE_SUPP_CMD_RESET \ -) - -/* Octet 10 */ -#define BLE_SUPP_CMD_RD_TX_PWR (0 << 2) -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) -#define BLE_SUPP_CMD_SET_CTRL_TO_HOST_FLOW (1 << 5) -#define BLE_SUPP_CMD_HOST_BUFFER_SIZE (1 << 6) -#define BLE_SUPP_CMD_HOST_NUM_COMP_PACKETS (1 << 7) -#else -#define BLE_SUPP_CMD_SET_CTRL_TO_HOST_FLOW (0 << 5) -#define BLE_SUPP_CMD_HOST_BUFFER_SIZE (0 << 6) -#define BLE_SUPP_CMD_HOST_NUM_COMP_PACKETS (0 << 7) -#endif -#define BLE_LL_SUPP_CMD_OCTET_10 \ -( \ - BLE_SUPP_CMD_RD_TX_PWR | \ - BLE_SUPP_CMD_SET_CTRL_TO_HOST_FLOW | \ - BLE_SUPP_CMD_HOST_BUFFER_SIZE | \ - BLE_SUPP_CMD_HOST_NUM_COMP_PACKETS \ -) - -/* Octet 14 */ -#define BLE_SUPP_CMD_RD_LOC_VER (1 << 3) -#define BLE_SUPP_CMD_RD_LOC_SUPP_FEAT (1 << 5) -#define BLE_LL_SUPP_CMD_OCTET_14 \ -( \ - BLE_SUPP_CMD_RD_LOC_VER | \ - BLE_SUPP_CMD_RD_LOC_SUPP_FEAT \ -) - -/* Octet 15 */ -#define BLE_SUPP_CMD_RD_BD_ADDR (1 << 1) - -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_RD_RSSI (1 << 5) -#else -#define BLE_SUPP_CMD_RD_RSSI (0 << 5) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_15 \ -( \ - BLE_SUPP_CMD_RD_BD_ADDR | \ - BLE_SUPP_CMD_RD_RSSI \ -) - -/* Octet 25 */ -#define BLE_SUPP_CMD_LE_SET_EV_MASK (1 << 0) -#define BLE_SUPP_CMD_LE_RD_BUF_SIZE (1 << 1) -#define BLE_SUPP_CMD_LE_RD_LOC_FEAT (1 << 2) -#define BLE_SUPP_CMD_LE_SET_RAND_ADDR (1 << 4) -#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) -#define BLE_SUPP_CMD_LE_SET_ADV_PARAMS (1 << 5) -#define BLE_SUPP_CMD_LE_SET_ADV_TX_PWR (1 << 6) -#define BLE_SUPP_CMD_LE_SET_ADV_DATA (1 << 7) -#else -#define BLE_SUPP_CMD_LE_SET_ADV_PARAMS (0 << 5) -#define BLE_SUPP_CMD_LE_SET_ADV_TX_PWR (0 << 6) -#define BLE_SUPP_CMD_LE_SET_ADV_DATA (0 << 7) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_25 \ -( \ - BLE_SUPP_CMD_LE_SET_EV_MASK | \ - BLE_SUPP_CMD_LE_RD_BUF_SIZE | \ - BLE_SUPP_CMD_LE_RD_LOC_FEAT | \ - BLE_SUPP_CMD_LE_SET_RAND_ADDR | \ - BLE_SUPP_CMD_LE_SET_ADV_PARAMS | \ - BLE_SUPP_CMD_LE_SET_ADV_TX_PWR | \ - BLE_SUPP_CMD_LE_SET_ADV_DATA \ -) - -/* Octet 26 */ -#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) -#define BLE_SUPP_CMD_LE_SET_SCAN_RSP_DATA (1 << 0) -#define BLE_SUPP_CMD_LE_SET_ADV_ENABLE (1 << 1) -#else -#define BLE_SUPP_CMD_LE_SET_SCAN_RSP_DATA (0 << 0) -#define BLE_SUPP_CMD_LE_SET_ADV_ENABLE (0 << 1) -#endif -#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) -#define BLE_SUPP_CMD_LE_SET_SCAN_PARAMS (1 << 2) -#define BLE_SUPP_CMD_LE_SET_SCAN_ENABLE (1 << 3) -#else -#define BLE_SUPP_CMD_LE_SET_SCAN_PARAMS (0 << 2) -#define BLE_SUPP_CMD_LE_SET_SCAN_ENABLE (0 << 3) -#endif -#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_LE_CREATE_CONN (1 << 4) -#define BLE_SUPP_CMD_LE_CREATE_CONN_CANCEL (1 << 5) -#else -#define BLE_SUPP_CMD_LE_CREATE_CONN (0 << 4) -#define BLE_SUPP_CMD_LE_CREATE_CONN_CANCEL (0 << 5) - -#endif -#define BLE_SUPP_CMD_LE_RD_WHITELIST_SIZE (1 << 6) -#define BLE_SUPP_CMD_LE_CLR_WHITELIST (1 << 7) - -#define BLE_LL_SUPP_CMD_OCTET_26 \ -( \ - BLE_SUPP_CMD_LE_SET_SCAN_RSP_DATA | \ - BLE_SUPP_CMD_LE_SET_ADV_ENABLE | \ - BLE_SUPP_CMD_LE_SET_SCAN_PARAMS | \ - BLE_SUPP_CMD_LE_SET_SCAN_ENABLE | \ - BLE_SUPP_CMD_LE_CREATE_CONN | \ - BLE_SUPP_CMD_LE_CREATE_CONN_CANCEL | \ - BLE_SUPP_CMD_LE_RD_WHITELIST_SIZE | \ - BLE_SUPP_CMD_LE_CLR_WHITELIST \ -) - -/* Octet 27 */ -#define BLE_SUPP_CMD_LE_ADD_DEV_WHITELIST (1 << 0) -#define BLE_SUPP_CMD_LE_RMV_DEV_WHITELIST (1 << 1) -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_LE_CONN_UPDATE (1 << 2) -#else -#define BLE_SUPP_CMD_LE_CONN_UPDATE (0 << 2) -#endif -#define BLE_SUPP_CMD_LE_SET_HOST_CHAN_CLASS (1 << 3) -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_LE_RD_CHAN_MAP (1 << 4) -#define BLE_SUPP_CMD_LE_RD_REM_USED_FEAT (1 << 5) -#else -#define BLE_SUPP_CMD_LE_RD_CHAN_MAP (0 << 4) -#define BLE_SUPP_CMD_LE_RD_REM_USED_FEAT (0 << 5) -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -#define BLE_SUPP_CMD_LE_ENCRYPT (1 << 6) -#else -#define BLE_SUPP_CMD_LE_ENCRYPT (0 << 6) -#endif -#define BLE_SUPP_CMD_LE_RAND (1 << 7) - -#define BLE_LL_SUPP_CMD_OCTET_27 \ -( \ - BLE_SUPP_CMD_LE_ENCRYPT | \ - BLE_SUPP_CMD_LE_RAND | \ - BLE_SUPP_CMD_LE_ADD_DEV_WHITELIST | \ - BLE_SUPP_CMD_LE_RMV_DEV_WHITELIST | \ - BLE_SUPP_CMD_LE_CONN_UPDATE | \ - BLE_SUPP_CMD_LE_SET_HOST_CHAN_CLASS | \ - BLE_SUPP_CMD_LE_RD_CHAN_MAP | \ - BLE_SUPP_CMD_LE_RD_REM_USED_FEAT \ -) - -/* Octet 28 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) -#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_LE_START_ENCRYPT (1 << 0) -#else -#define BLE_SUPP_CMD_LE_START_ENCRYPT (0 << 0) -#endif -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) -#define BLE_SUPP_CMD_LE_LTK_REQ_REPLY (1 << 1) -#define BLE_SUPP_CMD_LE_LTK_REQ_NEG_REPLY (1 << 2) -#else -#define BLE_SUPP_CMD_LE_LTK_REQ_REPLY (0 << 1) -#define BLE_SUPP_CMD_LE_LTK_REQ_NEG_REPLY (0 << 2) -#endif -#else -#define BLE_SUPP_CMD_LE_START_ENCRYPT (0 << 0) -#define BLE_SUPP_CMD_LE_LTK_REQ_REPLY (0 << 1) -#define BLE_SUPP_CMD_LE_LTK_REQ_NEG_REPLY (0 << 2) -#endif -#define BLE_SUPP_CMD_LE_READ_SUPP_STATES (1 << 3) - -#if MYNEWT_VAL(BLE_LL_DTM) -#define BLE_SUPP_CMD_LE_RX_TEST (1 << 4) -#define BLE_SUPP_CMD_LE_TX_TEST (1 << 5) -#define BLE_SUPP_CMD_LE_TEST_END (1 << 6) - -#else -#define BLE_SUPP_CMD_LE_RX_TEST (0 << 4) -#define BLE_SUPP_CMD_LE_TX_TEST (0 << 5) -#define BLE_SUPP_CMD_LE_TEST_END (0 << 6) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_28 \ -( \ - BLE_SUPP_CMD_LE_START_ENCRYPT | \ - BLE_SUPP_CMD_LE_LTK_REQ_REPLY | \ - BLE_SUPP_CMD_LE_LTK_REQ_NEG_REPLY | \ - BLE_SUPP_CMD_LE_READ_SUPP_STATES | \ - BLE_SUPP_CMD_LE_RX_TEST | \ - BLE_SUPP_CMD_LE_TX_TEST | \ - BLE_SUPP_CMD_LE_TEST_END \ -) - -/* Octet 33 */ -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_LE_REM_CONN_PRR (1 << 4) -#define BLE_SUPP_CMD_LE_REM_CONN_PRNR (1 << 5) -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) -#define BLE_SUPP_CMD_LE_SET_DATALEN (1 << 6) -#define BLE_SUPP_CMD_LE_RD_SUGG_DATALEN (1 << 7) -#else -#define BLE_SUPP_CMD_LE_SET_DATALEN (0 << 6) -#define BLE_SUPP_CMD_LE_RD_SUGG_DATALEN (0 << 7) -#endif -#else -#define BLE_SUPP_CMD_LE_REM_CONN_PRR (0 << 4) -#define BLE_SUPP_CMD_LE_REM_CONN_PRNR (0 << 5) -#define BLE_SUPP_CMD_LE_SET_DATALEN (0 << 6) -#define BLE_SUPP_CMD_LE_RD_SUGG_DATALEN (0 << 7) -#endif - - -#define BLE_LL_SUPP_CMD_OCTET_33 \ -( \ - BLE_SUPP_CMD_LE_REM_CONN_PRR | \ - BLE_SUPP_CMD_LE_REM_CONN_PRNR | \ - BLE_SUPP_CMD_LE_SET_DATALEN | \ - BLE_SUPP_CMD_LE_RD_SUGG_DATALEN \ -) - -/* Octet 34 */ -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) -#define BLE_SUPP_CMD_LE_WR_SUGG_DATALEN (1 << 0) -#else -#define BLE_SUPP_CMD_LE_WR_SUGG_DATALEN (0 << 0) -#endif -#else -#define BLE_SUPP_CMD_LE_WR_SUGG_DATALEN (0 << 0) -#endif -#define BLE_SUPP_CMD_LE_READ_LOCAL_P256_PK (0 << 1) -#define BLE_SUPP_CMD_LE_GENERATE_DH_KEY (0 << 2) -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) -#define BLE_SUPP_CMD_LE_ADD_RESOLV_LIST (1 << 3) -#define BLE_SUPP_CMD_LE_REMOVE_RESOLV_LIST (1 << 4) -#define BLE_SUPP_CMD_LE_CLEAR_RESOLV_LIST (1 << 5) -#define BLE_SUPP_CMD_LE_RD_RESOLV_SIZE (1 << 6) -#define BLE_SUPP_CMD_LE_RD_PEER_RESV_ADDR (1 << 7) -#else -#define BLE_SUPP_CMD_LE_ADD_RESOLV_LIST (0 << 3) -#define BLE_SUPP_CMD_LE_REMOVE_RESOLV_LIST (0 << 4) -#define BLE_SUPP_CMD_LE_CLEAR_RESOLV_LIST (0 << 5) -#define BLE_SUPP_CMD_LE_RD_RESOLV_SIZE (0 << 6) -#define BLE_SUPP_CMD_LE_RD_PEER_RESV_ADDR (0 << 7) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_34 \ -( \ - BLE_SUPP_CMD_LE_WR_SUGG_DATALEN | \ - BLE_SUPP_CMD_LE_READ_LOCAL_P256_PK | \ - BLE_SUPP_CMD_LE_GENERATE_DH_KEY | \ - BLE_SUPP_CMD_LE_ADD_RESOLV_LIST | \ - BLE_SUPP_CMD_LE_REMOVE_RESOLV_LIST | \ - BLE_SUPP_CMD_LE_CLEAR_RESOLV_LIST | \ - BLE_SUPP_CMD_LE_RD_RESOLV_SIZE | \ - BLE_SUPP_CMD_LE_RD_PEER_RESV_ADDR \ -) - -/* Octet 35 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) -#define BLE_SUPP_CMD_LE_RD_LOCAL_RESV_ADDR (1 << 0) -#define BLE_SUPP_CMD_LE_SET_ADDR_RES_EN (1 << 1) -#define BLE_SUPP_CMD_LE_SET_RESV_ADDR_TMO (1 << 2) -#else -#define BLE_SUPP_CMD_LE_RD_LOCAL_RESV_ADDR (0 << 0) -#define BLE_SUPP_CMD_LE_SET_ADDR_RES_EN (0 << 1) -#define BLE_SUPP_CMD_LE_SET_RESV_ADDR_TMO (0 << 2) -#endif -#define BLE_SUPP_CMD_LE_RD_MAX_DATALEN (1 << 3) -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_LE_READ_PHY (1 << 4) -#define BLE_SUPP_CMD_LE_SET_DEFAULT_PHY (1 << 5) -#define BLE_SUPP_CMD_LE_SET_PHY (1 << 6) -#else -#define BLE_SUPP_CMD_LE_READ_PHY (0 << 4) -#define BLE_SUPP_CMD_LE_SET_DEFAULT_PHY (0 << 5) -#define BLE_SUPP_CMD_LE_SET_PHY (0 << 6) -#endif -#else -#define BLE_SUPP_CMD_LE_READ_PHY (0 << 4) -#define BLE_SUPP_CMD_LE_SET_DEFAULT_PHY (0 << 5) -#define BLE_SUPP_CMD_LE_SET_PHY (0 << 6) -#endif - -#if MYNEWT_VAL(BLE_LL_DTM) -#define BLE_SUPP_CMD_LE_ENHANCED_RX_TEST (1 << 7) -#else -#define BLE_SUPP_CMD_LE_ENHANCED_RX_TEST (0 << 7) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_35 \ -( \ - BLE_SUPP_CMD_LE_RD_LOCAL_RESV_ADDR | \ - BLE_SUPP_CMD_LE_SET_ADDR_RES_EN | \ - BLE_SUPP_CMD_LE_SET_RESV_ADDR_TMO | \ - BLE_SUPP_CMD_LE_RD_MAX_DATALEN | \ - BLE_SUPP_CMD_LE_READ_PHY | \ - BLE_SUPP_CMD_LE_SET_DEFAULT_PHY | \ - BLE_SUPP_CMD_LE_SET_PHY | \ - BLE_SUPP_CMD_LE_ENHANCED_RX_TEST \ -) - -/* Octet 36 */ -#if MYNEWT_VAL(BLE_LL_DTM) -#define BLE_SUPP_CMD_LE_ENHANCED_TX_TEST (1 << 0) -#else -#define BLE_SUPP_CMD_LE_ENHANCED_TX_TEST (0 << 0) -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) -#define BLE_SUPP_CMD_LE_SET_ADVS_RAND_ADDR (1 << 1) -#define BLE_SUPP_CMD_LE_SET_EXT_ADV_PARAM (1 << 2) -#define BLE_SUPP_CMD_LE_SET_EXT_ADV_DATA (1 << 3) -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_RSP (1 << 4) -#define BLE_SUPP_CMD_LE_SET_EXT_ADV_ENABLE (1 << 5) -#define BLE_SUPP_CMD_LE_RD_MAX_ADV_DATA_LEN (1 << 6) -#define BLE_SUPP_CMD_LE_RD_NUM_SUPP_ADVS (1 << 7) -#else -#define BLE_SUPP_CMD_LE_SET_ADVS_RAND_ADDR (0 << 1) -#define BLE_SUPP_CMD_LE_SET_EXT_ADV_PARAM (0 << 2) -#define BLE_SUPP_CMD_LE_SET_EXT_ADV_DATA (0 << 3) -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_RSP (0 << 4) -#define BLE_SUPP_CMD_LE_SET_EXT_ADV_ENABLE (0 << 5) -#define BLE_SUPP_CMD_LE_RD_MAX_ADV_DATA_LEN (0 << 6) -#define BLE_SUPP_CMD_LE_RD_NUM_SUPP_ADVS (0 << 7) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_36 \ -( \ - BLE_SUPP_CMD_LE_ENHANCED_TX_TEST | \ - BLE_SUPP_CMD_LE_SET_ADVS_RAND_ADDR | \ - BLE_SUPP_CMD_LE_SET_EXT_ADV_PARAM | \ - BLE_SUPP_CMD_LE_SET_EXT_ADV_DATA | \ - BLE_SUPP_CMD_LE_SET_EXT_SCAN_RSP | \ - BLE_SUPP_CMD_LE_SET_EXT_ADV_ENABLE | \ - BLE_SUPP_CMD_LE_RD_MAX_ADV_DATA_LEN | \ - BLE_SUPP_CMD_LE_RD_NUM_SUPP_ADVS \ -) - -/* Octet 37 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) -#define BLE_SUPP_CMD_LE_REMOVE_ADVS (1 << 0) -#define BLE_SUPP_CMD_LE_CLEAR_ADVS (1 << 1) -#else -#define BLE_SUPP_CMD_LE_REMOVE_ADVS (0 << 0) -#define BLE_SUPP_CMD_LE_CLEAR_ADVS (0 << 1) -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) -#define BLE_SUPP_CMD_LE_SET_PADV_PARAM (1 << 2) -#define BLE_SUPP_CMD_LE_SET_PADV_DATA (1 << 3) -#define BLE_SUPP_CMD_LE_SET_PADV_ENABLE (1 << 4) -#else -#define BLE_SUPP_CMD_LE_SET_PADV_PARAM (0 << 2) -#define BLE_SUPP_CMD_LE_SET_PADV_DATA (0 << 3) -#define BLE_SUPP_CMD_LE_SET_PADV_ENABLE (0 << 4) -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_PARAM (1 << 5) -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_ENABLE (1 << 6) -#else -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_PARAM (0 << 5) -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_ENABLE (0 << 6) -#endif -#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) -#define BLE_SUPP_CMD_LE_EXT_CREATE_CONN (1 << 7) -#else -#define BLE_SUPP_CMD_LE_EXT_CREATE_CONN (0 << 7) -#endif -#else -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_PARAM (0 << 5) -#define BLE_SUPP_CMD_LE_SET_EXT_SCAN_ENABLE (0 << 6) -#define BLE_SUPP_CMD_LE_EXT_CREATE_CONN (0 << 7) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_37 \ -( \ - BLE_SUPP_CMD_LE_REMOVE_ADVS | \ - BLE_SUPP_CMD_LE_CLEAR_ADVS | \ - BLE_SUPP_CMD_LE_SET_PADV_PARAM | \ - BLE_SUPP_CMD_LE_SET_PADV_DATA | \ - BLE_SUPP_CMD_LE_SET_PADV_ENABLE | \ - BLE_SUPP_CMD_LE_SET_EXT_SCAN_PARAM | \ - BLE_SUPP_CMD_LE_SET_EXT_SCAN_ENABLE | \ - BLE_SUPP_CMD_LE_EXT_CREATE_CONN \ -) - -/* Octet 38 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) -#define BLE_SUPP_CMD_LE_PADV_CREATE_SYNC (1 << 0) -#define BLE_SUPP_CMD_LE_PADV_CREATE_SYNC_C (1 << 1) -#define BLE_SUPP_CMD_LE_PADV_TERMINATE_SYNC (1 << 2) -#define BLE_SUPP_CMD_LE_ADD_PADV_LIST (1 << 3) -#define BLE_SUPP_CMD_LE_REMOVE_PADV_LIST (1 << 4) -#define BLE_SUPP_CMD_LE_CLEAR_PADV_LIST (1 << 5) -#define BLE_SUPP_CMD_LE_RD_PADV_LIST_SIZE (1 << 6) -#else -#define BLE_SUPP_CMD_LE_PADV_CREATE_SYNC (0 << 0) -#define BLE_SUPP_CMD_LE_PADV_CREATE_SYNC_C (0 << 1) -#define BLE_SUPP_CMD_LE_PADV_TERMINATE_SYNC (0 << 2) -#define BLE_SUPP_CMD_LE_ADD_PADV_LIST (0 << 3) -#define BLE_SUPP_CMD_LE_REMOVE_PADV_LIST (0 << 4) -#define BLE_SUPP_CMD_LE_CLEAR_PADV_LIST (0 << 5) -#define BLE_SUPP_CMD_LE_RD_PADV_LIST_SIZE (0 << 6) -#endif -#define BLE_SUPP_CMD_LE_RD_TX_POWER (1 << 7) - -#define BLE_LL_SUPP_CMD_OCTET_38 \ -( \ - BLE_SUPP_CMD_LE_PADV_CREATE_SYNC | \ - BLE_SUPP_CMD_LE_PADV_CREATE_SYNC_C | \ - BLE_SUPP_CMD_LE_PADV_TERMINATE_SYNC | \ - BLE_SUPP_CMD_LE_ADD_PADV_LIST | \ - BLE_SUPP_CMD_LE_REMOVE_PADV_LIST | \ - BLE_SUPP_CMD_LE_CLEAR_PADV_LIST | \ - BLE_SUPP_CMD_LE_RD_PADV_LIST_SIZE | \ - BLE_SUPP_CMD_LE_RD_TX_POWER \ -) - -/* Octet 39 */ -#define BLE_SUPP_CMD_LE_RD_RF_PATH_COMP (1 << 0) -#define BLE_SUPP_CMD_LE_WR_RF_PATH_COMP (1 << 1) -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) -#define BLE_SUPP_CMD_LE_SET_PRIVACY_MODE (1 << 2) -#else -#define BLE_SUPP_CMD_LE_SET_PRIVACY_MODE (0 << 2) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_39 \ -( \ - BLE_SUPP_CMD_LE_RD_RF_PATH_COMP | \ - BLE_SUPP_CMD_LE_WR_RF_PATH_COMP | \ - BLE_SUPP_CMD_LE_SET_PRIVACY_MODE \ -) - -/* Octet 40 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_VERSION) >= 51 -#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) -#define BLE_SUPP_CMD_LE_PADV_RECV_ENABLE (1 << 5) -#else -#define BLE_SUPP_CMD_LE_PADV_RECV_ENABLE (0 << 5) -#endif - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) -#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) -#define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER (1 << 6) -#else -#define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER (0 << 6) -#endif - -#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) -#define BLE_SUPP_CMD_LE_PADV_SET_INFO_TRANSFER (1 << 7) -#else -#define BLE_SUPP_CMD_LE_PADV_SET_INFO_TRANSFER (0 << 7) -#endif - -#else -#define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER (0 << 6) -#define BLE_SUPP_CMD_LE_PADV_SET_INFO_TRANSFER (0 << 7) -#endif - -#else -#define BLE_SUPP_CMD_LE_PADV_RECV_ENABLE (0 << 5) -#define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER (0 << 6) -#define BLE_SUPP_CMD_LE_PADV_SET_INFO_TRANSFER (0 << 7) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_40 \ -( \ - BLE_SUPP_CMD_LE_PADV_RECV_ENABLE | \ - BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER | \ - BLE_SUPP_CMD_LE_PADV_SET_INFO_TRANSFER \ -) - -/* Octet 41 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) -#define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER_PARAMS (1 << 0) -#define BLE_SUPP_CMD_LE_PADV_DEFAULT_SYNC_TRANSFER_PARAMS (1 << 1) -#else -#define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER_PARAMS (0 << 0) -#define BLE_SUPP_CMD_LE_PADV_DEFAULT_SYNC_TRANSFER_PARAMS (0 << 1) -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) -#define BLE_SUPP_CMD_LE_READ_BUF_SIZE_V2 (1 << 5) -#define BLE_SUPP_CMD_LE_READ_ISO_TX_SYNC (1 << 6) -#define BLE_SUPP_CMD_LE_SET_CIG_PARAM (1 << 7) -#else -#define BLE_SUPP_CMD_LE_READ_BUF_SIZE_V2 (0 << 5) -#define BLE_SUPP_CMD_LE_READ_ISO_TX_SYNC (0 << 6) -#define BLE_SUPP_CMD_LE_SET_CIG_PARAM (0 << 7) -#endif - -#define BLE_LL_SUPP_CMD_OCTET_41 \ -( \ - BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER_PARAMS | \ - BLE_SUPP_CMD_LE_PADV_DEFAULT_SYNC_TRANSFER_PARAMS | \ - BLE_SUPP_CMD_LE_READ_BUF_SIZE_V2 | \ - BLE_SUPP_CMD_LE_READ_ISO_TX_SYNC | \ - BLE_SUPP_CMD_LE_SET_CIG_PARAM \ -) - -/* Octet 42 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) -#define BLE_SUPP_CMD_LE_SET_CIG_PARAM_TEST (1 << 0) -#define BLE_SUPP_CMD_LE_CREATE_CIS (1 << 1) -#define BLE_SUPP_CMD_LE_REMOVE_CIG (1 << 2) -#define BLE_SUPP_CMD_LE_ACCEPT_CIS_REQ (1 << 3) -#define BLE_SUPP_CMD_LE_REJECT_CIS_REQ (1 << 4) -#define BLE_SUPP_CMD_LE_CREATE_BIG (1 << 5) -#define BLE_SUPP_CMD_LE_CREATE_BIG_TEST (1 << 6) -#define BLE_SUPP_CMD_LE_TERMINATE_BIG (1 << 7) -#else -#define BLE_SUPP_CMD_LE_SET_CIG_PARAM_TEST (0 << 0) -#define BLE_SUPP_CMD_LE_CREATE_CIS (0 << 1) -#define BLE_SUPP_CMD_LE_REMOVE_CIG (0 << 2) -#define BLE_SUPP_CMD_LE_ACCEPT_CIS_REQ (0 << 3) -#define BLE_SUPP_CMD_LE_REJECT_CIS_REQ (0 << 4) -#define BLE_SUPP_CMD_LE_CREATE_BIG (0 << 5) -#define BLE_SUPP_CMD_LE_CREATE_BIG_TEST (0 << 6) -#define BLE_SUPP_CMD_LE_TERMINATE_BIG (0 << 7) -#endif -#define BLE_LL_SUPP_CMD_OCTET_42 \ -( \ - BLE_SUPP_CMD_LE_SET_CIG_PARAM_TEST | \ - BLE_SUPP_CMD_LE_CREATE_CIS | \ - BLE_SUPP_CMD_LE_REMOVE_CIG | \ - BLE_SUPP_CMD_LE_ACCEPT_CIS_REQ | \ - BLE_SUPP_CMD_LE_REJECT_CIS_REQ | \ - BLE_SUPP_CMD_LE_CREATE_BIG | \ - BLE_SUPP_CMD_LE_CREATE_BIG_TEST | \ - BLE_SUPP_CMD_LE_TERMINATE_BIG \ -) - -/* Octet 43 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE) -#define BLE_SUPP_CMD_LE_REQUEST_PEER_SCA (1 << 2) -#else -#define BLE_SUPP_CMD_LE_REQUEST_PEER_SCA (0 << 0) -#endif -#define BLE_LL_SUPP_CMD_OCTET_43 \ -( \ - BLE_SUPP_CMD_LE_REQUEST_PEER_SCA \ -) - -/* Octet 44 */ -#if MYNEWT_VAL(BLE_VERSION) >= 52 -#define BLE_SUPP_CMD_LE_SET_HOST_FEATURE (1 << 1) -#else -#define BLE_SUPP_CMD_LE_SET_HOST_FEATURE (0 << 1) -#endif -#define BLE_LL_SUPP_CMD_OCTET_44 \ -( \ - BLE_SUPP_CMD_LE_SET_HOST_FEATURE \ -) - -/* Octet 46 */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) -#define BLE_SUPP_CMD_LE_SET_DEFAULT_SUBRATE (1 << 0) -#define BLE_SUPP_CMD_LE_SUBRATE_REQ (1 << 1) -#else -#define BLE_SUPP_CMD_LE_SET_DEFAULT_SUBRATE (0 << 0) -#define BLE_SUPP_CMD_LE_SUBRATE_REQ (0 << 1) -#endif -#define BLE_LL_SUPP_CMD_OCTET_46 \ -( \ - BLE_SUPP_CMD_LE_SET_DEFAULT_SUBRATE | \ - BLE_SUPP_CMD_LE_SUBRATE_REQ \ -) - -/* Defines the array of supported commands */ -const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN] = -{ - BLE_LL_SUPP_CMD_OCTET_0, /* Octet 0 */ - 0, - BLE_LL_SUPP_CMD_OCTET_2, /* Octet 2 */ - 0, - 0, - BLE_LL_SUPP_CMD_OCTET_5, - 0, - 0, - 0, /* Octet 8 */ - 0, - BLE_LL_SUPP_CMD_OCTET_10, - 0, - 0, - 0, - BLE_LL_SUPP_CMD_OCTET_14, - BLE_LL_SUPP_CMD_OCTET_15, - 0, /* Octet 16 */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, /* Octet 24 */ - BLE_LL_SUPP_CMD_OCTET_25, - BLE_LL_SUPP_CMD_OCTET_26, - BLE_LL_SUPP_CMD_OCTET_27, - BLE_LL_SUPP_CMD_OCTET_28, - 0, - 0, - 0, - 0, /* Octet 32 */ - BLE_LL_SUPP_CMD_OCTET_33, - BLE_LL_SUPP_CMD_OCTET_34, - BLE_LL_SUPP_CMD_OCTET_35, - BLE_LL_SUPP_CMD_OCTET_36, - BLE_LL_SUPP_CMD_OCTET_37, - BLE_LL_SUPP_CMD_OCTET_38, - BLE_LL_SUPP_CMD_OCTET_39, - BLE_LL_SUPP_CMD_OCTET_40, /* Octet 40 */ - BLE_LL_SUPP_CMD_OCTET_41, - BLE_LL_SUPP_CMD_OCTET_42, - BLE_LL_SUPP_CMD_OCTET_43, - BLE_LL_SUPP_CMD_OCTET_44, - 0, - BLE_LL_SUPP_CMD_OCTET_46, -}; From ed083b36cb85c7437b905ee905ea4aed6a1653ad Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Mon, 6 Feb 2023 05:03:29 +0800 Subject: [PATCH 0650/1333] porting/nuttx: Fix error: implicit declaration of function 'usleep' Report here: https://github.com/apache/nuttx/actions/runs/4098214664/jobs/7067171681 Signed-off-by: Xiang Xiao --- porting/examples/nuttx/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/porting/examples/nuttx/main.c b/porting/examples/nuttx/main.c index 82582573ad..7492e120e9 100644 --- a/porting/examples/nuttx/main.c +++ b/porting/examples/nuttx/main.c @@ -22,9 +22,9 @@ #include #include #include - - #include +#include + #include "nimble/nimble_npl.h" #include "nimble/nimble_port.h" From 4ff3784817bf2e162614dc49718ceca926e26bdb Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 3 Feb 2023 22:12:49 +0100 Subject: [PATCH 0651/1333] nimble/transport: Remove ACL pool if not used This removes extra memory used by ACL pool structures if pool is not used, i.e. count=0. This happens e.g. on combined build since both hs and ll sides use msys instead of transport pool. This can also be set by user if neither central nor peripheral role is enabled and ACL pool is not needed. --- nimble/transport/src/transport.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/nimble/transport/src/transport.c b/nimble/transport/src/transport.c index a1ee34099f..7e5601d150 100644 --- a/nimble/transport/src/transport.c +++ b/nimble/transport/src/transport.c @@ -71,9 +71,11 @@ static struct os_mempool pool_evt; static uint8_t pool_evt_lo_buf[ OS_MEMPOOL_BYTES(POOL_EVT_LO_COUNT, POOL_EVT_SIZE) ]; static struct os_mempool pool_evt_lo; +#if POOL_ACL_COUNT > 0 static uint8_t pool_acl_buf[ OS_MEMPOOL_BYTES(POOL_ACL_COUNT, POOL_ACL_SIZE) ]; static struct os_mempool_ext pool_acl; static struct os_mbuf_pool mpool_acl; +#endif static os_mempool_put_fn *transport_put_acl_from_ll_cb; @@ -134,6 +136,7 @@ ble_transport_alloc_evt(int discardable) struct os_mbuf * ble_transport_alloc_acl_from_hs(void) { +#if POOL_ACL_COUNT > 0 struct os_mbuf *om; struct os_mbuf_pkthdr *pkthdr; uint16_t usrhdr_len; @@ -151,11 +154,15 @@ ble_transport_alloc_acl_from_hs(void) } return om; +#else + return NULL; +#endif } struct os_mbuf * ble_transport_alloc_acl_from_ll(void) { +#if POOL_ACL_COUNT > 0 struct os_mbuf *om; struct os_mbuf_pkthdr *pkthdr; @@ -166,6 +173,9 @@ ble_transport_alloc_acl_from_ll(void) } return om; +#else + return NULL; +#endif } void @@ -202,6 +212,7 @@ ble_transport_ipc_free(void *buf) } } +#if POOL_ACL_COUNT > 0 static os_error_t ble_transport_acl_put(struct os_mempool_ext *mpe, void *data, void *arg) { @@ -235,6 +246,7 @@ ble_transport_acl_put(struct os_mempool_ext *mpe, void *data, void *arg) return err; } +#endif void ble_transport_init(void) @@ -255,6 +267,7 @@ ble_transport_init(void) pool_evt_lo_buf, "transport_pool_evt_lo"); SYSINIT_PANIC_ASSERT(rc == 0); +#if POOL_ACL_COUNT > 0 rc = os_mempool_ext_init(&pool_acl, POOL_ACL_COUNT, POOL_ACL_SIZE, pool_acl_buf, "transport_pool_acl"); SYSINIT_PANIC_ASSERT(rc == 0); @@ -264,6 +277,7 @@ ble_transport_init(void) SYSINIT_PANIC_ASSERT(rc == 0); pool_acl.mpe_put_cb = ble_transport_acl_put; +#endif } int From 8a01f72db5a7728feed04c112523ecaf6ea238a6 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Tue, 24 Jan 2023 15:08:42 +0100 Subject: [PATCH 0652/1333] apps: Allow stub/full implementation of packages in syscfg Packages console, log and stats allow to choose stub or full implementation. All apps had either stub or full implementation hardwired in pkg.yml file. Now it can be easily overriden in target. This also changes defunct setting of CONSOLE_MODE to CONSOLE_IMPLEMENTATION in all apps. --- apps/advertiser/pkg.yml | 6 +++--- apps/advertiser/syscfg.yml | 4 ++++ apps/blecent/pkg.yml | 6 +++--- apps/blecent/syscfg.yml | 4 ++++ apps/blecsc/pkg.yml | 6 +++--- apps/blecsc/syscfg.yml | 4 ++++ apps/blehci/pkg.yml | 2 +- apps/blehci/syscfg.yml | 3 ++- apps/blehr/pkg.yml | 6 +++--- apps/blehr/syscfg.yml | 4 ++++ apps/blemesh/pkg.yml | 6 +++--- apps/blemesh/syscfg.yml | 4 ++++ apps/blemesh_light/pkg.yml | 6 +++--- apps/blemesh_light/syscfg.yml | 4 ++++ apps/blemesh_models_example_1/pkg.yml | 6 +++--- apps/blemesh_models_example_1/syscfg.yml | 4 ++++ apps/blemesh_models_example_2/pkg.yml | 6 +++--- apps/blemesh_models_example_2/syscfg.yml | 4 ++++ apps/blemesh_shell/pkg.yml | 6 +++--- apps/blemesh_shell/syscfg.yml | 4 ++++ apps/bleprph/pkg.yml | 6 +++--- apps/bleprph/syscfg.yml | 4 ++++ apps/blestress/pkg.yml | 6 +++--- apps/blestress/syscfg.yml | 4 ++++ apps/btshell/pkg.yml | 6 +++--- apps/btshell/syscfg.yml | 4 ++++ apps/bttester/pkg.yml | 6 +++--- apps/bttester/syscfg.yml | 4 ++++ apps/central/pkg.yml | 6 +++--- apps/central/syscfg.yml | 4 ++++ apps/ext_advertiser/pkg.yml | 6 +++--- apps/ext_advertiser/syscfg.yml | 4 ++++ apps/mesh_badge/pkg.yml | 6 +++--- apps/mesh_badge/syscfg.yml | 4 ++++ apps/peripheral/pkg.yml | 6 +++--- apps/peripheral/syscfg.yml | 4 ++++ apps/scanner/pkg.yml | 6 +++--- apps/scanner/syscfg.yml | 4 ++++ 38 files changed, 129 insertions(+), 56 deletions(-) diff --git a/apps/advertiser/pkg.yml b/apps/advertiser/pkg.yml index ad6f133d59..2693cdad34 100644 --- a/apps/advertiser/pkg.yml +++ b/apps/advertiser/pkg.yml @@ -24,9 +24,9 @@ pkg.author: "Krzysztof Kopyściński " pkg.deps: - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/log/modlog" - "@apache-mynewt-nimble/nimble/host" - "@apache-mynewt-nimble/nimble/host/util" diff --git a/apps/advertiser/syscfg.yml b/apps/advertiser/syscfg.yml index 963839fc35..63b136bebe 100644 --- a/apps/advertiser/syscfg.yml +++ b/apps/advertiser/syscfg.yml @@ -17,6 +17,10 @@ syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + BLE_ROLE_BROADCASTER: 1 BLE_ROLE_CENTRAL: 0 BLE_ROLE_OBSERVER: 0 diff --git a/apps/blecent/pkg.yml b/apps/blecent/pkg.yml index 86e3f01690..7b06e62792 100644 --- a/apps/blecent/pkg.yml +++ b/apps/blecent/pkg.yml @@ -24,10 +24,10 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" - "@apache-mynewt-core/sys/log/modlog" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/stats" - nimble/host - nimble/host/util - nimble/host/services/gap diff --git a/apps/blecent/syscfg.yml b/apps/blecent/syscfg.yml index e186383968..30c0febb66 100644 --- a/apps/blecent/syscfg.yml +++ b/apps/blecent/syscfg.yml @@ -17,6 +17,10 @@ # syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + # DEBUG logging is a bit noisy; use INFO. LOG_LEVEL: 1 diff --git a/apps/blecsc/pkg.yml b/apps/blecsc/pkg.yml index d3768fc7f9..3f862f3805 100644 --- a/apps/blecsc/pkg.yml +++ b/apps/blecsc/pkg.yml @@ -26,10 +26,10 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" - "@apache-mynewt-core/sys/log/modlog" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/sysinit" - "@apache-mynewt-core/sys/id" - nimble/host diff --git a/apps/blecsc/syscfg.yml b/apps/blecsc/syscfg.yml index abf899691d..8234ae8ad8 100644 --- a/apps/blecsc/syscfg.yml +++ b/apps/blecsc/syscfg.yml @@ -17,6 +17,10 @@ syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + # Disable central and observer roles. BLE_ROLE_BROADCASTER: 1 BLE_ROLE_CENTRAL: 0 diff --git a/apps/blehci/pkg.yml b/apps/blehci/pkg.yml index 0c9e534b24..915ae5b604 100644 --- a/apps/blehci/pkg.yml +++ b/apps/blehci/pkg.yml @@ -25,7 +25,7 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/sys/console" - "@apache-mynewt-core/sys/log" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/kernel/os" - nimble/transport diff --git a/apps/blehci/syscfg.yml b/apps/blehci/syscfg.yml index 5ec89bcb9d..3a8f53f75a 100644 --- a/apps/blehci/syscfg.yml +++ b/apps/blehci/syscfg.yml @@ -20,8 +20,9 @@ syscfg.vals: # Default task settings OS_MAIN_STACK_SIZE: 64 # Stub console - CONSOLE_MODE: stub + CONSOLE_IMPLEMENTATION: stub LOG_IMPLEMENTATION: stub + STATS_IMPLEMENTATION: full syscfg.vals.'!BLE_TRANSPORT_NETCORE': # Use UART by default if not built on netcore diff --git a/apps/blehr/pkg.yml b/apps/blehr/pkg.yml index ace633b16e..43c84ce3e8 100644 --- a/apps/blehr/pkg.yml +++ b/apps/blehr/pkg.yml @@ -26,10 +26,10 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" - "@apache-mynewt-core/sys/log/modlog" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/sysinit" - "@apache-mynewt-core/sys/id" - nimble/host diff --git a/apps/blehr/syscfg.yml b/apps/blehr/syscfg.yml index 98cf255428..a34080ed90 100644 --- a/apps/blehr/syscfg.yml +++ b/apps/blehr/syscfg.yml @@ -17,6 +17,10 @@ syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + # Disable central and observer roles. BLE_ROLE_BROADCASTER: 1 BLE_ROLE_CENTRAL: 0 diff --git a/apps/blemesh/pkg.yml b/apps/blemesh/pkg.yml index 19fb478230..fb4c494146 100644 --- a/apps/blemesh/pkg.yml +++ b/apps/blemesh/pkg.yml @@ -24,10 +24,10 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" - "@apache-mynewt-core/sys/log/modlog" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/shell" - nimble/host - nimble/host/services/gap diff --git a/apps/blemesh/syscfg.yml b/apps/blemesh/syscfg.yml index 4424b14de0..e6e961bf49 100644 --- a/apps/blemesh/syscfg.yml +++ b/apps/blemesh/syscfg.yml @@ -17,6 +17,10 @@ # syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + # Enable the shell task. SHELL_TASK: 1 diff --git a/apps/blemesh_light/pkg.yml b/apps/blemesh_light/pkg.yml index bb37ffb5ff..f261a6f4ef 100644 --- a/apps/blemesh_light/pkg.yml +++ b/apps/blemesh_light/pkg.yml @@ -24,10 +24,10 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" - "@apache-mynewt-core/sys/log/modlog" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/shell" - nimble/host - nimble/host/services/gap diff --git a/apps/blemesh_light/syscfg.yml b/apps/blemesh_light/syscfg.yml index 826d9d5f34..0443549f8c 100644 --- a/apps/blemesh_light/syscfg.yml +++ b/apps/blemesh_light/syscfg.yml @@ -21,6 +21,10 @@ syscfg.defs: value: 0 syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + # Enable the shell task. SHELL_TASK: 1 diff --git a/apps/blemesh_models_example_1/pkg.yml b/apps/blemesh_models_example_1/pkg.yml index 44e2d79cbc..3cf9cd81d0 100644 --- a/apps/blemesh_models_example_1/pkg.yml +++ b/apps/blemesh_models_example_1/pkg.yml @@ -24,9 +24,9 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" + - "@apache-mynewt-core/sys/stats" - nimble/host - nimble/host/services/gap - nimble/host/services/gatt diff --git a/apps/blemesh_models_example_1/syscfg.yml b/apps/blemesh_models_example_1/syscfg.yml index 969753fe05..26e178b0dc 100644 --- a/apps/blemesh_models_example_1/syscfg.yml +++ b/apps/blemesh_models_example_1/syscfg.yml @@ -17,6 +17,10 @@ # syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + # Set log level to info (disable debug logging). LOG_LEVEL: 1 diff --git a/apps/blemesh_models_example_2/pkg.yml b/apps/blemesh_models_example_2/pkg.yml index 194b5546c4..f4ceacbc7a 100644 --- a/apps/blemesh_models_example_2/pkg.yml +++ b/apps/blemesh_models_example_2/pkg.yml @@ -24,9 +24,9 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/encoding/base64" - "@apache-mynewt-core/sys/config" - nimble/host diff --git a/apps/blemesh_models_example_2/syscfg.yml b/apps/blemesh_models_example_2/syscfg.yml index b56e9d2d00..4ba0e1b7e2 100644 --- a/apps/blemesh_models_example_2/syscfg.yml +++ b/apps/blemesh_models_example_2/syscfg.yml @@ -17,6 +17,10 @@ # syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + # Set log level to info (disable debug logging). LOG_LEVEL: 1 diff --git a/apps/blemesh_shell/pkg.yml b/apps/blemesh_shell/pkg.yml index a7e457ed10..df3a45d444 100644 --- a/apps/blemesh_shell/pkg.yml +++ b/apps/blemesh_shell/pkg.yml @@ -24,10 +24,10 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" - "@apache-mynewt-core/sys/log/modlog" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/shell" - nimble/host - nimble/host/services/gap diff --git a/apps/blemesh_shell/syscfg.yml b/apps/blemesh_shell/syscfg.yml index 0756e46fe5..a450ae4bea 100644 --- a/apps/blemesh_shell/syscfg.yml +++ b/apps/blemesh_shell/syscfg.yml @@ -17,6 +17,10 @@ # syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + # Enable the shell task. SHELL_TASK: 1 diff --git a/apps/bleprph/pkg.yml b/apps/bleprph/pkg.yml index 0bb0d9d0bb..6a7a354cfd 100644 --- a/apps/bleprph/pkg.yml +++ b/apps/bleprph/pkg.yml @@ -29,10 +29,10 @@ pkg.deps: - "@apache-mynewt-core/mgmt/imgmgr" - "@apache-mynewt-core/mgmt/smp" - "@apache-mynewt-core/mgmt/smp/transport/ble" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" - "@apache-mynewt-core/sys/log/modlog" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/sysinit" - "@apache-mynewt-core/sys/id" - nimble/host diff --git a/apps/bleprph/syscfg.yml b/apps/bleprph/syscfg.yml index e00eb3b8e9..0800f213ba 100644 --- a/apps/bleprph/syscfg.yml +++ b/apps/bleprph/syscfg.yml @@ -38,6 +38,10 @@ syscfg.defs: value: "(int[]){ LED_1, LED_2, LED_3 }" syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + # Disable central and observer roles. BLE_ROLE_BROADCASTER: 1 BLE_ROLE_CENTRAL: 0 diff --git a/apps/blestress/pkg.yml b/apps/blestress/pkg.yml index 21013eb58a..e56cdd64a2 100644 --- a/apps/blestress/pkg.yml +++ b/apps/blestress/pkg.yml @@ -26,9 +26,9 @@ pkg.deps: - "@mcuboot/boot/bootutil" - "@apache-mynewt-core/sys/log/modlog" - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/id" - "@apache-mynewt-nimble/nimble/host" - "@apache-mynewt-nimble/nimble/host/util" diff --git a/apps/blestress/syscfg.yml b/apps/blestress/syscfg.yml index ce50050c7c..5e16ed1f41 100644 --- a/apps/blestress/syscfg.yml +++ b/apps/blestress/syscfg.yml @@ -35,6 +35,10 @@ syscfg.defs: # Settings this app overrides. syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + # Change these settings: # Set 0 to print all debug logs, but keep in mind that plenty of diff --git a/apps/btshell/pkg.yml b/apps/btshell/pkg.yml index abbee73c7e..b50b371c38 100644 --- a/apps/btshell/pkg.yml +++ b/apps/btshell/pkg.yml @@ -24,10 +24,10 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/log/full" + - "@apache-mynewt-core/sys/log" - "@apache-mynewt-core/sys/log/modlog" - - "@apache-mynewt-core/sys/stats/full" - - "@apache-mynewt-core/sys/console/full" + - "@apache-mynewt-core/sys/stats" + - "@apache-mynewt-core/sys/console" - "@apache-mynewt-core/sys/shell" - nimble/host - nimble/host/services/gap diff --git a/apps/btshell/syscfg.yml b/apps/btshell/syscfg.yml index b9dfa875d5..091a2df0c1 100644 --- a/apps/btshell/syscfg.yml +++ b/apps/btshell/syscfg.yml @@ -22,6 +22,10 @@ syscfg.defs: value: 1 syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + # Enable the shell task. SHELL_TASK: 1 diff --git a/apps/bttester/pkg.yml b/apps/bttester/pkg.yml index 219e529810..e763185fe5 100644 --- a/apps/bttester/pkg.yml +++ b/apps/bttester/pkg.yml @@ -26,10 +26,10 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" - "@apache-mynewt-core/sys/log/modlog" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/shell" - "@apache-mynewt-nimble/nimble/host" - "@apache-mynewt-nimble/nimble/host/util" diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 0d975bd8f7..5038e8121b 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -80,6 +80,10 @@ syscfg.defs: value: 5 syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + OS_MAIN_STACK_SIZE: 512 SHELL_TASK: 0 SHELL_NEWTMGR: 0 diff --git a/apps/central/pkg.yml b/apps/central/pkg.yml index 5f5b27a971..90913711e6 100644 --- a/apps/central/pkg.yml +++ b/apps/central/pkg.yml @@ -24,9 +24,9 @@ pkg.author: "Krzysztof Kopyściński " pkg.deps: - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/log/modlog" - "@apache-mynewt-nimble/nimble/host" - "@apache-mynewt-nimble/nimble/host/util/" diff --git a/apps/central/syscfg.yml b/apps/central/syscfg.yml index c23ba04206..3761c496ed 100644 --- a/apps/central/syscfg.yml +++ b/apps/central/syscfg.yml @@ -17,6 +17,10 @@ syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + BLE_ROLE_BROADCASTER: 0 BLE_ROLE_CENTRAL: 1 BLE_ROLE_OBSERVER: 1 diff --git a/apps/ext_advertiser/pkg.yml b/apps/ext_advertiser/pkg.yml index 32df4efc10..baf1ea0b05 100644 --- a/apps/ext_advertiser/pkg.yml +++ b/apps/ext_advertiser/pkg.yml @@ -31,8 +31,8 @@ pkg.deps: - nimble/host/services/gatt - nimble/host/store/config - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/sysinit" - "@apache-mynewt-core/sys/id" diff --git a/apps/ext_advertiser/syscfg.yml b/apps/ext_advertiser/syscfg.yml index f157ab82b0..410433fdf8 100644 --- a/apps/ext_advertiser/syscfg.yml +++ b/apps/ext_advertiser/syscfg.yml @@ -17,6 +17,10 @@ syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + # Disable not used GAP roles (we only do non-connectable # advertising here) BLE_ROLE_BROADCASTER: 1 diff --git a/apps/mesh_badge/pkg.yml b/apps/mesh_badge/pkg.yml index d1276a51cf..238104d71c 100644 --- a/apps/mesh_badge/pkg.yml +++ b/apps/mesh_badge/pkg.yml @@ -26,10 +26,10 @@ pkg.deps: - "@apache-mynewt-core/hw/drivers/display/cfb" - "@apache-mynewt-core/hw/drivers/display/ssd1673" - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" - "@apache-mynewt-core/sys/log/modlog" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/shell" - nimble/host - nimble/host/services/gap diff --git a/apps/mesh_badge/syscfg.yml b/apps/mesh_badge/syscfg.yml index 2b8f457d55..81f1d75ff7 100644 --- a/apps/mesh_badge/syscfg.yml +++ b/apps/mesh_badge/syscfg.yml @@ -19,6 +19,10 @@ # Package: apps/mesh_badge syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + # Enable the shell task. SHELL_TASK: 1 diff --git a/apps/peripheral/pkg.yml b/apps/peripheral/pkg.yml index d5c862c810..82ff496a71 100644 --- a/apps/peripheral/pkg.yml +++ b/apps/peripheral/pkg.yml @@ -25,9 +25,9 @@ pkg.author: "Krzysztof Kopyściński krzysztof.kopyscinski@codecoup.pl" pkg.deps: - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/log/modlog" - "@apache-mynewt-nimble/nimble/host" - "@apache-mynewt-nimble/nimble/host/util/" diff --git a/apps/peripheral/syscfg.yml b/apps/peripheral/syscfg.yml index 0b9542316d..891ce0f59b 100644 --- a/apps/peripheral/syscfg.yml +++ b/apps/peripheral/syscfg.yml @@ -17,6 +17,10 @@ syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + BLE_ROLE_BROADCASTER: 1 BLE_ROLE_CENTRAL: 0 BLE_ROLE_OBSERVER: 0 diff --git a/apps/scanner/pkg.yml b/apps/scanner/pkg.yml index 442ab9db64..5e17add142 100644 --- a/apps/scanner/pkg.yml +++ b/apps/scanner/pkg.yml @@ -25,9 +25,9 @@ pkg.author: "Krzysztof Kopyściński " pkg.deps: - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console/full" - - "@apache-mynewt-core/sys/log/full" - - "@apache-mynewt-core/sys/stats/full" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" + - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/log/modlog" - "@apache-mynewt-nimble/nimble/host" - "@apache-mynewt-nimble/nimble/host/util/" diff --git a/apps/scanner/syscfg.yml b/apps/scanner/syscfg.yml index 568a2c6b7d..75d9dff251 100644 --- a/apps/scanner/syscfg.yml +++ b/apps/scanner/syscfg.yml @@ -17,6 +17,10 @@ syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + BLE_ROLE_BROADCASTER: 0 BLE_ROLE_CENTRAL: 0 BLE_ROLE_OBSERVER: 1 From cfb0ffb1c89ee8c6b4daefa3c38fd93d5e5fbbfb Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 3 Feb 2023 21:52:56 +0100 Subject: [PATCH 0653/1333] ci: Add check to verify if ports configurations need update This will help keeping ports in good shape. --- .github/project_ports.yml | 56 +++++++++++++++++++++ .github/workflows/ports_syscfg_check.yml | 63 ++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 .github/project_ports.yml create mode 100644 .github/workflows/ports_syscfg_check.yml diff --git a/.github/project_ports.yml b/.github/project_ports.yml new file mode 100644 index 0000000000..0a9b2cf01b --- /dev/null +++ b/.github/project_ports.yml @@ -0,0 +1,56 @@ +# +# 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. +# + +project.name: "apache-mynewt-nimble" + +project.repositories: + - apache-mynewt-core + - mcuboot + - apache-mynewt-mcumgr + +repository.apache-mynewt-core: + type: github + vers: 0.0.0 + user: apache + repo: mynewt-core + +repository.apache-mynewt-nimble: + type: github + vers: 0.0.0 + user: apache + repo: mynewt-nimble + +repository.mcuboot: + type: github + vers: 0.0.0 + user: mcu-tools + repo: mcuboot + branch: main + +repository.apache-mynewt-mcumgr: + type: github + vers: 0.0.0 + user: apache + repo: mynewt-mcumgr + +repository.tinyusb: + type: github + vers: 0.0.0 + user: hathach + repo: tinyusb diff --git a/.github/workflows/ports_syscfg_check.yml b/.github/workflows/ports_syscfg_check.yml new file mode 100644 index 0000000000..a8d0254080 --- /dev/null +++ b/.github/workflows/ports_syscfg_check.yml @@ -0,0 +1,63 @@ +# +# 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. +# + +name: Check ports syscfg update + +on: [pull_request] + +jobs: + targets: + name: Check ports syscfg update + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: '1.16' + - uses: carlosperate/arm-none-eabi-gcc-action@48db4484a55750df7a0ccca63347fcdea6534d78 + with: + release: '12.2.Rel1' + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install -y gcc-multilib + - name: Install newt + run: | + go version + go get mynewt.apache.org/newt/newt@latest + - name: Setup project + run: | + mkdir /tmp/proj + mkdir /tmp/proj/repos + cp .github/project_ports.yml /tmp/proj/project.yml + git clone --depth=1 https://github.com/apache/mynewt-core /tmp/proj/repos/apache-mynewt-core + git clone --depth=1 https://github.com/mcu-tools/mcuboot.git /tmp/proj/repos/mcuboot + git clone --depth=1 https://github.com/apache/mynewt-mcumgr /tmp/proj/repos/apache-mynewt-mcumgr + git clone --depth=1 https://github.com/hathach/tinyusb.git /tmp/proj/repos/tinyusb + cp -r `pwd` /tmp/proj/repos/apache-mynewt-nimble + - name: Check ports syscfg + run: | + cd /tmp/proj + ./repos/apache-mynewt-nimble/porting/update_generated_files.sh + cd repos/apache-mynewt-nimble + git diff --quiet || (\ + echo -e "\033[0;31mChanges in system configration files detected."; + echo -e "\033[0;31mRun ./repos/apache-mynewt-nimble/porting/update_generated_files.sh" \ + "to update NimBLE ports configurations."; + exit 1) From 674eeafa0bcf53573d0ab852834ec824bbc19008 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 6 Feb 2023 17:21:28 +0100 Subject: [PATCH 0654/1333] nimble/ports: Refresh syscfg --- porting/npl/riot/include/syscfg/syscfg.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 71c0798fb5..dbde6c9904 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1349,6 +1349,10 @@ #define MYNEWT_VAL_BLE_PHY_DBG_TIME_WFR_PIN (-1) #endif +#ifndef MYNEWT_VAL_BLE_PHY_NRF52_HEADERMASK_WORKAROUND +#define MYNEWT_VAL_BLE_PHY_NRF52_HEADERMASK_WORKAROUND (0) +#endif + #ifndef MYNEWT_VAL_BLE_PHY_SYSVIEW #define MYNEWT_VAL_BLE_PHY_SYSVIEW (0) #endif From 65e774e1040edba8dc95662424ab5832253b1a70 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Mon, 6 Feb 2023 16:33:06 +0800 Subject: [PATCH 0655/1333] nimble/transport: Fix compilation warning in socket transpor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ble_hci_socket.c:359:5: warning: implicit declaration of function ‘ble_hci_trans_buf_free’ change ble_hci_trans_buf_free to ble_transport_free Signed-off-by: Xiang Xiao --- nimble/transport/socket/src/ble_hci_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/transport/socket/src/ble_hci_socket.c b/nimble/transport/socket/src/ble_hci_socket.c index 5dd1d17df7..059bf4a922 100644 --- a/nimble/transport/socket/src/ble_hci_socket.c +++ b/nimble/transport/socket/src/ble_hci_socket.c @@ -356,7 +356,7 @@ ble_hci_sock_cmdevt_tx(uint8_t *hci_ev, uint8_t h4_type) (struct sockaddr *)&addr, sizeof(struct sockaddr_hci)); free(buf); - ble_hci_trans_buf_free(hci_ev); + ble_transport_free(hci_ev); if (i != len + 1) { if (i < 0) { dprintf(1, "sendto() failed : %d\n", errno); From 69c0d323a9e85d19d523c67c7addaa9bee778dac Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Mon, 6 Feb 2023 16:51:03 +0800 Subject: [PATCH 0656/1333] porting: Fix SYSINIT_PANIC_ASSERT_MSG refinition warning porting/npl/nuttx/include/nimble/nimble_npl_os.h:40: warning: "SYSINIT_PANIC_ASSERT_MSG" redefined 40 | #define SYSINIT_PANIC_ASSERT_MSG(rc, msg) do \ | nimble/host/services/tps/src/ble_svc_tps.c:22: porting/nimble/include/sysinit/sysinit.h:32: note: this is the location of the previous definition 32 | #define SYSINIT_PANIC_ASSERT_MSG(rc, msg) assert(rc) | Signed-off-by: Xiang Xiao --- porting/npl/linux/include/nimble/nimble_npl_os.h | 7 ------- porting/npl/nuttx/include/nimble/nimble_npl_os.h | 7 ------- 2 files changed, 14 deletions(-) diff --git a/porting/npl/linux/include/nimble/nimble_npl_os.h b/porting/npl/linux/include/nimble/nimble_npl_os.h index 585d378525..17e61b22af 100644 --- a/porting/npl/linux/include/nimble/nimble_npl_os.h +++ b/porting/npl/linux/include/nimble/nimble_npl_os.h @@ -37,13 +37,6 @@ extern "C" { #define SYSINIT_PANIC_MSG(msg) __assert_fail(msg, __FILE__, __LINE__, __func__) -#define SYSINIT_PANIC_ASSERT_MSG(rc, msg) do \ -{ \ - if (!(rc)) { \ - SYSINIT_PANIC_MSG(msg); \ - } \ -} while (0) - #ifdef __cplusplus } #endif diff --git a/porting/npl/nuttx/include/nimble/nimble_npl_os.h b/porting/npl/nuttx/include/nimble/nimble_npl_os.h index 0f765f5a3d..a2fcbc42ef 100644 --- a/porting/npl/nuttx/include/nimble/nimble_npl_os.h +++ b/porting/npl/nuttx/include/nimble/nimble_npl_os.h @@ -37,13 +37,6 @@ extern "C" { #define SYSINIT_PANIC_MSG(msg) { fprintf(stderr, "%s\n", msg); abort(); } -#define SYSINIT_PANIC_ASSERT_MSG(rc, msg) do \ -{ \ - if (!(rc)) { \ - SYSINIT_PANIC_MSG(msg); \ - } \ -} while (0) - #ifdef __cplusplus } #endif From efb9058a4246f8eb273b707f439a2a9af81ab081 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 2 Feb 2023 08:59:24 +0100 Subject: [PATCH 0657/1333] nimble/ll: Add option to control initial DLE update New option allows to select if controller should initiate DLE update automatically for connection. By default it is enabled to not change existing controller behavior. --- nimble/controller/include/controller/ble_ll_conn.h | 2 ++ nimble/controller/src/ble_ll_ctrl.c | 5 +++++ nimble/controller/syscfg.yml | 12 ++++++++---- porting/npl/riot/include/syscfg/syscfg.h | 4 ++++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 016e5abd23..1e704ad36c 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -129,7 +129,9 @@ union ble_ll_conn_sm_flags { uint32_t aux_conn_req: 1; uint32_t rxd_features:1; uint32_t pending_hci_rd_features:1; +#if MYNEWT_VAL(BLE_LL_CONN_INIT_AUTO_DLE) uint32_t pending_initiate_dle:1; +#endif uint32_t subrate_trans:1; uint32_t subrate_ind_txd:1; uint32_t subrate_host_req:1; diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 3a10052314..7d828aeb07 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -2137,7 +2137,10 @@ ble_ll_ctrl_update_features(struct ble_ll_conn_sm *connsm, uint8_t *feat) } #endif +#if MYNEWT_VAL(BLE_LL_CONN_INIT_AUTO_DLE) connsm->csmflags.cfbit.pending_initiate_dle = 1; +#endif + connsm->csmflags.cfbit.rxd_features = 1; } } @@ -3050,10 +3053,12 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) #endif } +#if MYNEWT_VAL(BLE_LL_CONN_INIT_AUTO_DLE) if (connsm->csmflags.cfbit.pending_initiate_dle) { connsm->csmflags.cfbit.pending_initiate_dle = 0; ble_ll_ctrl_initiate_dle(connsm, true); } +#endif return rc; } diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 3c1dc18bf9..34039bb034 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -140,11 +140,15 @@ syscfg.defs: BLE_LL_CONN_INIT_MAX_TX_BYTES: description: > Used to set the initial maximum transmit PDU size in a - connection. If this is set to a value greater than 27, - the controller will automatically attempt to do the - data length update procedure. The host can always tell - the controller to update this value. + connection. The host can always tell the controller to update this + value. value: '27' + BLE_LL_CONN_INIT_AUTO_DLE: + description: > + If BLE_LL_CONN_INIT_MAX_TX_BYTES is set to value greater than 27 + controller will automatically attempt to do the data length update + procedure. + value: 1 # The number of slots that will be allocated to each connection BLE_LL_CONN_INIT_SLOTS: diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index dbde6c9904..75752c0279 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1046,6 +1046,10 @@ #define MYNEWT_VAL_BLE_LL_CONN_EVENT_END_MARGIN (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_AUTO_DLE +#define MYNEWT_VAL_BLE_LL_CONN_INIT_AUTO_DLE (1) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ #ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_MAX_TX_BYTES #define MYNEWT_VAL_BLE_LL_CONN_INIT_MAX_TX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE) From e0e9629afedfb17b4589a76edc26bf639f36ec49 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sun, 12 Feb 2023 16:58:42 +0800 Subject: [PATCH 0658/1333] porting/nuttx; Fix error: unrecognized command-line option '-m32' -m32 is supported by x64 toolchain, not arm-none-eabi-gcc Signed-off-by: Xiang Xiao --- porting/examples/nuttx/Make.defs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/porting/examples/nuttx/Make.defs b/porting/examples/nuttx/Make.defs index f35d428e82..94a2a3e1d9 100644 --- a/porting/examples/nuttx/Make.defs +++ b/porting/examples/nuttx/Make.defs @@ -48,8 +48,7 @@ INC = \ INCLUDES := $(addprefix -I, $(INC)) -CFLAGS += \ - $(NIMBLE_CFLAGS) \ +CFLAGS += \ $(INCLUDES) \ $(TINYCRYPT_CFLAGS) \ -DNIMBLE_CFG_CONTROLLER=0 -DOS_CFG_ALIGN_4=4 -DOS_CFG_ALIGNMENT=4 \ From 17a8e61fdec48d579df3bc5af59a9cff5edee674 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 8 Feb 2023 16:12:54 +0100 Subject: [PATCH 0659/1333] porting: Remove unused SYSINIT_PANIC_MSG Those are no longer used. --- porting/npl/linux/include/nimble/nimble_npl_os.h | 2 -- porting/npl/nuttx/include/nimble/nimble_npl_os.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/porting/npl/linux/include/nimble/nimble_npl_os.h b/porting/npl/linux/include/nimble/nimble_npl_os.h index 17e61b22af..d171fc048c 100644 --- a/porting/npl/linux/include/nimble/nimble_npl_os.h +++ b/porting/npl/linux/include/nimble/nimble_npl_os.h @@ -35,8 +35,6 @@ extern "C" { #define BLE_NPL_TIME_FOREVER INT32_MAX -#define SYSINIT_PANIC_MSG(msg) __assert_fail(msg, __FILE__, __LINE__, __func__) - #ifdef __cplusplus } #endif diff --git a/porting/npl/nuttx/include/nimble/nimble_npl_os.h b/porting/npl/nuttx/include/nimble/nimble_npl_os.h index a2fcbc42ef..8a41d411db 100644 --- a/porting/npl/nuttx/include/nimble/nimble_npl_os.h +++ b/porting/npl/nuttx/include/nimble/nimble_npl_os.h @@ -35,8 +35,6 @@ extern "C" { #define BLE_NPL_TIME_FOREVER INT32_MAX -#define SYSINIT_PANIC_MSG(msg) { fprintf(stderr, "%s\n", msg); abort(); } - #ifdef __cplusplus } #endif From 9bed38f91a6a658527a49058ac89a8783461fcae Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 22 Feb 2023 11:55:22 +0100 Subject: [PATCH 0660/1333] nimble/ll: Fix missing critical section exit in PAST It was possible to exit ble_ll_sync_transfer() without exiting critical section. --- nimble/controller/src/ble_ll_sync.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 971f879909..c83f4e319a 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -2185,32 +2185,30 @@ ble_ll_sync_transfer(const uint8_t *cmdbuf, uint8_t len, if (!(sm->flags & BLE_LL_SYNC_SM_FLAG_ESTABLISHED)) { rc = BLE_ERR_UNK_ADV_INDENT; - OS_EXIT_CRITICAL(sr); - goto done; + goto exit_crit; } handle = le16toh(cmd->conn_handle); if (handle > 0xeff) { rc = BLE_ERR_INV_HCI_CMD_PARMS; - OS_EXIT_CRITICAL(sr); - goto done; + goto exit_crit; } connsm = ble_ll_conn_find_by_handle(handle); if (!connsm) { rc = BLE_ERR_UNK_CONN_ID; - OS_EXIT_CRITICAL(sr); - goto done; + goto exit_crit; } /* Allow initiate LL procedure only if remote supports it. */ if (!ble_ll_conn_rem_feature_check(connsm, BLE_LL_FEAT_SYNC_TRANS_RECV)) { rc = BLE_ERR_UNSUPP_REM_FEATURE; - goto done; + goto exit_crit; } rc = ble_ll_sync_send_sync_ind(sm, connsm, cmd->service_data); +exit_crit: OS_EXIT_CRITICAL(sr); done: rsp->conn_handle = cmd->conn_handle; From 0a08f6f449bbd95e549d8b883866422ba4cc94c8 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 24 Feb 2023 23:45:16 +0100 Subject: [PATCH 0661/1333] babblesim: Fix os_arch_in_isr --- babblesim/core/src/irq_handler.c | 6 ++++++ babblesim/hw/bsp/nrf52_bsim/include/os/os_arch.h | 7 ++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/babblesim/core/src/irq_handler.c b/babblesim/core/src/irq_handler.c index d29797500d..05eb881a6d 100644 --- a/babblesim/core/src/irq_handler.c +++ b/babblesim/core/src/irq_handler.c @@ -22,6 +22,12 @@ extern void (* const systemVectors[256])(void); * handler and therefore its priority handling */ +int +os_arch_in_isr(void) +{ + return currently_running_irq >= 0; +} + void posix_interrupt_raised(void) { uint64_t irq_lock; diff --git a/babblesim/hw/bsp/nrf52_bsim/include/os/os_arch.h b/babblesim/hw/bsp/nrf52_bsim/include/os/os_arch.h index 32bc97bcb2..574f1e8133 100644 --- a/babblesim/hw/bsp/nrf52_bsim/include/os/os_arch.h +++ b/babblesim/hw/bsp/nrf52_bsim/include/os/os_arch.h @@ -48,11 +48,8 @@ void os_arch_frame_init(struct stack_frame *sf); #define OS_IDLE_STACK_SIZE (4000) #endif -static inline int -os_arch_in_isr(void) -{ - return hw_irq_ctrl_get_irq_status(); -} +/* Implemented in irq_handler */ +int os_arch_in_isr(void); /* Include common arch definitions and APIs */ #include "os/arch/common.h" From 2de66c2797ef1848930f6ee5d5cded15a8a483d9 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 24 Feb 2023 23:45:42 +0100 Subject: [PATCH 0662/1333] babblesim: Fix invalid switch from isr to task BabbleSim triggers interrupts when exiting from critical section (i.e. interrupts are unlocked) and then we check for pending context switch. This can lead to invalid switch from isr to task context before isr has actually finished: - interrupts are unlocked - interrupt is triggered - isr calls os_* which uses critical section and triggers context switch (e.g. os_eventq_put) - when exiting critical section in isr, we check for pending context switch and immediately switch to task context before isr is completed To fix this we should only perform context switch if exiting from critical section in task context. --- babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch.c b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch.c index 8277ae7cae..b545688cc4 100644 --- a/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch.c +++ b/babblesim/hw/bsp/nrf52_bsim/src/arch/bsim_arch/os_arch.c @@ -148,7 +148,7 @@ os_arch_restore_sr(os_sr_t osr) { hw_irq_ctrl_change_lock(osr); - if (!osr && bsim_pend_sv) { + if (!osr && bsim_pend_sv && !os_arch_in_isr()) { do_ctx_sw(); } } From 154754b577f7fe42b24f699de89c3efa9fb64e36 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 24 Feb 2023 23:57:40 +0100 Subject: [PATCH 0663/1333] nimble/phy/nrf5x: Fix setting RTC CC[0] value CC[0] has only 24 bits valid so we should mask target value. Not really sure if this does matter on actual hardware (should not?), but BabbleSim does not handle it correctly. --- nimble/drivers/nrf5x/src/ble_phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index c1e2df7259..bf989e88e0 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -782,7 +782,7 @@ ble_phy_set_start_now(void) */ now = os_cputime_get32(); NRF_RTC0->EVENTS_COMPARE[0] = 0; - nrf_rtc_cc_set(NRF_RTC0, 0, now + 3); + nrf_rtc_cc_set(NRF_RTC0, 0, (now + 3) & 0xffffff); nrf_rtc_event_enable(NRF_RTC0, RTC_EVTENSET_COMPARE0_Msk); #if PHY_USE_FEM_LNA From d7eb050cfe32c25b76441a15886b3e02a2d2c779 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 25 Feb 2023 00:01:02 +0100 Subject: [PATCH 0664/1333] nimble/ll: Suppress compiler warning ble_error is not used in some configurations so just suppress compiler warning (instead of #ifdef so we don't need to worry about it anymore). --- nimble/controller/src/ble_ll_ctrl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 7d828aeb07..b7c9c01e8a 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1954,6 +1954,9 @@ ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, ble_error = dptr[1]; } + /* Suppress unused-but-set if not used by following code (due to syscfg) */ + (void)ble_error; + /* XXX: should I check to make sure the rejected opcode is sane if we receive ind ext? */ switch (connsm->cur_ctrl_proc) { From ca22da24b46424f117fec1b1e26e40871f57732f Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 1 Mar 2023 12:11:55 +0530 Subject: [PATCH 0665/1333] Nimble/host: Add check status before executing stack command Added change of checking stack status in APIs exposed to user to avoid incorrect behaviour of executing commands without stack initialized. --- nimble/host/src/ble_gap.c | 186 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 180 insertions(+), 6 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index b6d54bc30c..85b4c44188 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -490,6 +490,10 @@ ble_gap_conn_find_by_addr(const ble_addr_t *addr, #if NIMBLE_BLE_CONNECT struct ble_hs_conn *conn; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); conn = ble_hs_conn_find_by_addr(addr); @@ -543,6 +547,10 @@ int ble_gap_set_priv_mode(const ble_addr_t *peer_addr, uint8_t priv_mode) { #if NIMBLE_BLE_CONNECT + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + return ble_hs_pvcy_set_mode(peer_addr, priv_mode); #else return BLE_HS_ENOTSUP; @@ -558,6 +566,10 @@ ble_gap_read_le_phy(uint16_t conn_handle, uint8_t *tx_phy, uint8_t *rx_phy) struct ble_hs_conn *conn; int rc; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); conn = ble_hs_conn_find(conn_handle); ble_hs_unlock(); @@ -606,6 +618,10 @@ ble_gap_set_prefered_default_le_phy(uint8_t tx_phys_mask, uint8_t rx_phys_mask) return BLE_ERR_INV_HCI_CMD_PARMS; } + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + memset(&cmd, 0, sizeof(cmd)); if (tx_phys_mask == 0) { @@ -636,6 +652,10 @@ ble_gap_set_prefered_le_phy(uint16_t conn_handle, uint8_t tx_phys_mask, struct ble_hci_le_set_phy_cp cmd; struct ble_hs_conn *conn; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); conn = ble_hs_conn_find(conn_handle); ble_hs_unlock(); @@ -2239,6 +2259,10 @@ ble_gap_wl_set(const ble_addr_t *addrs, uint8_t white_list_count) STATS_INC(ble_gap_stats, wl_set); + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); for (i = 0; i < white_list_count; i++) { @@ -2343,6 +2367,10 @@ ble_gap_adv_stop(void) #if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) int rc; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); rc = ble_gap_adv_stop_no_lock(); ble_hs_unlock(); @@ -2540,6 +2568,10 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, STATS_INC(ble_gap_stats, adv_start); + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); rc = ble_gap_adv_validate(own_addr_type, direct_addr, adv_params); @@ -2556,11 +2588,6 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, } } - if (!ble_hs_is_enabled()) { - rc = BLE_HS_EDISABLED; - goto done; - } - if (ble_gap_is_preempted()) { rc = BLE_HS_EPREEMPTED; goto done; @@ -2625,6 +2652,10 @@ ble_gap_adv_set_data(const uint8_t *data, int data_len) STATS_INC(ble_gap_stats, adv_set_data); + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + /* Check for valid parameters */ if (((data == NULL) && (data_len != 0)) || (data_len > BLE_HCI_MAX_ADV_DATA_LEN)) { @@ -2649,6 +2680,9 @@ ble_gap_adv_rsp_set_data(const uint8_t *data, int data_len) struct ble_hci_le_set_scan_rsp_data_cp cmd; uint16_t opcode; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } /* Check for valid parameters */ if (((data == NULL) && (data_len != 0)) || @@ -2675,6 +2709,10 @@ ble_gap_adv_set_fields(const struct ble_hs_adv_fields *adv_fields) uint8_t buf_sz; int rc; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + rc = ble_hs_adv_set_fields(adv_fields, buf, &buf_sz, sizeof buf); if (rc != 0) { return rc; @@ -2883,6 +2921,10 @@ ble_gap_ext_adv_configure(uint8_t instance, return BLE_HS_EINVAL; } + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + rc = ble_gap_ext_adv_params_validate(params); if (rc) { return rc; @@ -2947,6 +2989,10 @@ ble_gap_ext_adv_set_addr(uint8_t instance, const ble_addr_t *addr) return BLE_HS_EINVAL; } + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); rc = ble_gap_ext_adv_set_addr_no_lock(instance, addr->val); ble_hs_unlock(); @@ -2967,6 +3013,10 @@ ble_gap_ext_adv_start(uint8_t instance, int duration, int max_events) return BLE_HS_EINVAL; } + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); if (!ble_gap_slave[instance].configured) { ble_hs_unlock(); @@ -3244,6 +3294,11 @@ ble_gap_ext_adv_set_data(uint8_t instance, struct os_mbuf *data) goto done; } + if (!ble_hs_is_enabled()) { + rc = BLE_HS_EDISABLED; + goto done; + } + ble_hs_lock(); rc = ble_gap_ext_adv_set_data_validate(instance, data); if (rc != 0) { @@ -3311,6 +3366,11 @@ ble_gap_ext_adv_rsp_set_data(uint8_t instance, struct os_mbuf *data) goto done; } + if (!ble_hs_is_enabled()) { + rc = BLE_HS_EDISABLED; + goto done; + } + ble_hs_lock(); rc = ble_gap_ext_adv_rsp_set_validate(instance, data); if (rc != 0) { @@ -3339,6 +3399,10 @@ ble_gap_ext_adv_remove(uint8_t instance) return BLE_HS_EINVAL; } + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); if (!ble_gap_slave[instance].configured) { ble_hs_unlock(); @@ -3372,6 +3436,10 @@ ble_gap_ext_adv_clear(void) uint8_t instance; uint16_t opcode; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); for (instance = 0; instance < BLE_ADV_INSTANCES; instance++) { @@ -3464,6 +3532,10 @@ ble_gap_periodic_adv_configure(uint8_t instance, return BLE_HS_EINVAL; } + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + rc = ble_gap_periodic_adv_params_validate(params); if (rc) { return rc; @@ -3510,6 +3582,10 @@ ble_gap_periodic_adv_start(uint8_t instance) return BLE_HS_EINVAL; } + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); /* Periodic advertising cannot start unless it is configured before */ @@ -3657,6 +3733,11 @@ ble_gap_periodic_adv_set_data(uint8_t instance, struct os_mbuf *data) goto done; } + if (!ble_hs_is_enabled()) { + rc = BLE_HS_EDISABLED; + goto done; + } + ble_hs_lock(); rc = ble_gap_periodic_adv_set_data_validate(instance, data); @@ -3705,6 +3786,10 @@ ble_gap_periodic_adv_stop(uint8_t instance) return BLE_HS_EINVAL; } + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); rc = ble_gap_periodic_adv_stop_no_lock(instance); ble_hs_unlock(); @@ -3761,6 +3846,10 @@ ble_gap_periodic_adv_sync_create(const ble_addr_t *addr, uint8_t adv_sid, return BLE_HS_EINVAL; } + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); /* No sync can be created if another sync is still pending */ @@ -3849,6 +3938,10 @@ ble_gap_periodic_adv_sync_terminate(uint16_t sync_handle) uint16_t opcode; int rc; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); if (ble_gap_sync.op == BLE_GAP_OP_SYNC) { @@ -3895,6 +3988,10 @@ ble_gap_periodic_adv_sync_reporting(uint16_t sync_handle, bool enable) uint16_t opcode; int rc; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); if (ble_gap_sync.op == BLE_GAP_OP_SYNC) { @@ -3931,6 +4028,10 @@ ble_gap_periodic_adv_sync_transfer(uint16_t sync_handle, uint16_t conn_handle, uint16_t opcode; int rc; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); conn = ble_hs_conn_find(conn_handle); @@ -3975,6 +4076,10 @@ ble_gap_periodic_adv_sync_set_info(uint8_t instance, uint16_t conn_handle, return BLE_HS_EINVAL; } + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); if (ble_gap_slave[instance].periodic_op != BLE_GAP_OP_S_PERIODIC_ADV) { /* periodic adv not enabled */ @@ -4037,6 +4142,10 @@ ble_gap_periodic_adv_sync_receive(uint16_t conn_handle, struct ble_hs_conn *conn; int rc; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); conn = ble_hs_conn_find(conn_handle); @@ -4097,6 +4206,10 @@ ble_gap_add_dev_to_periodic_adv_list(const ble_addr_t *peer_addr, return BLE_ERR_INV_HCI_CMD_PARMS; } + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + cmd.peer_addr_type = peer_addr->type; memcpy(cmd.peer_addr, peer_addr->val, BLE_DEV_ADDR_LEN); cmd.sid = adv_sid; @@ -4117,6 +4230,10 @@ ble_gap_rem_dev_from_periodic_adv_list(const ble_addr_t *peer_addr, uint8_t adv_ return BLE_ERR_INV_HCI_CMD_PARMS; } + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + cmd.peer_addr_type = peer_addr->type; memcpy(cmd.peer_addr, peer_addr->val, BLE_DEV_ADDR_LEN); cmd.sid = adv_sid; @@ -4324,6 +4441,10 @@ ble_gap_disc_cancel(void) #if NIMBLE_BLE_SCAN int rc; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); rc = ble_gap_disc_cancel_no_lock(); ble_hs_unlock(); @@ -4417,6 +4538,10 @@ ble_gap_ext_disc(uint8_t own_addr_type, uint16_t duration, uint16_t period, STATS_INC(ble_gap_stats, discover); + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); rc = ble_gap_disc_ext_validate(own_addr_type); @@ -4543,6 +4668,10 @@ ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms, #if MYNEWT_VAL(BLE_EXT_ADV) struct ble_gap_ext_disc_params p = {0}; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + p.itvl = disc_params->itvl; p.passive = disc_params->passive; p.window = disc_params->window; @@ -4564,6 +4693,10 @@ ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms, STATS_INC(ble_gap_stats, discover); + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); /* Make a copy of the parameter strcuture and fill unspecified values with @@ -4966,7 +5099,8 @@ ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, } if (!ble_hs_is_enabled()) { - return BLE_HS_EDISABLED; + rc = BLE_HS_EDISABLED; + goto done; } if (ble_gap_is_preempted()) { @@ -5242,6 +5376,10 @@ ble_gap_terminate(uint16_t conn_handle, uint8_t hci_reason) STATS_INC(ble_gap_stats, terminate); + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); conn = ble_hs_conn_find(conn_handle); @@ -5321,6 +5459,10 @@ ble_gap_conn_cancel(void) #if MYNEWT_VAL(BLE_ROLE_CENTRAL) int rc; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); rc = ble_gap_conn_cancel_no_lock(); ble_hs_unlock(); @@ -5579,6 +5721,10 @@ ble_gap_update_params(uint16_t conn_handle, return BLE_HS_EINVAL; } + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + STATS_INC(ble_gap_stats, update); memset(&l2cap_params, 0, sizeof l2cap_params); entry = NULL; @@ -5692,6 +5838,10 @@ ble_gap_security_initiate(uint16_t conn_handle) STATS_INC(ble_gap_stats, security_initiate); + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + ble_hs_lock(); conn = ble_hs_conn_find(conn_handle); if (conn != NULL) { @@ -5753,6 +5903,10 @@ ble_gap_pair_initiate(uint16_t conn_handle) { int rc; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + rc = ble_sm_pair_initiate(conn_handle); return rc; @@ -5770,6 +5924,10 @@ ble_gap_encryption_initiate(uint16_t conn_handle, ble_hs_conn_flags_t conn_flags; int rc; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + rc = ble_hs_atomic_conn_flags(conn_handle, &conn_flags); if (rc != 0) { return rc; @@ -5793,6 +5951,10 @@ ble_gap_unpair(const ble_addr_t *peer_addr) #if NIMBLE_BLE_SM struct ble_hs_conn *conn; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + if (ble_addr_cmp(peer_addr, BLE_ADDR_ANY) == 0) { return BLE_HS_EINVAL; } @@ -5823,6 +5985,10 @@ ble_gap_unpair_oldest_peer(void) int num_peers; int rc; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + rc = ble_store_util_bonded_peers( &oldest_peer_id_addr, &num_peers, 1); if (rc != 0) { @@ -5852,6 +6018,10 @@ ble_gap_unpair_oldest_except(const ble_addr_t *peer_addr) int num_peers; int rc, i; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + rc = ble_store_util_bonded_peers( &peer_id_addrs[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS)); if (rc != 0) { @@ -5988,6 +6158,10 @@ ble_gap_conn_rssi(uint16_t conn_handle, int8_t *out_rssi) { int rc; + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + rc = ble_hs_hci_util_read_rssi(conn_handle, out_rssi); return rc; } From b61889fa433af0cb42f38b8d078aac77dfb537eb Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 25 Feb 2023 10:40:59 +0800 Subject: [PATCH 0666/1333] nimble/doc: Fix typo in HCI transport document Trivial copy-paste mistake fix. Signed-off-by: Axel Lin --- nimble/doc/transport.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/doc/transport.md b/nimble/doc/transport.md index cd14993ae8..35065197c9 100644 --- a/nimble/doc/transport.md +++ b/nimble/doc/transport.md @@ -36,8 +36,8 @@ another core). +----------+ +----------+ || || +----+ +----+ -| | <--- ble_transport_to_ll_acl ---- | | -| | <--- ble_transport_to_ll_evt ---- | | +| | <--- ble_transport_to_hs_acl ---- | | +| | <--- ble_transport_to_hs_evt ---- | | | HS | | LL | | | ---- ble_transport_to_ll_cmd ---> | | | | ---- ble_transport_to_ll_acl ---> | | From dddcc9de03bbe22d746e09ded58bc7ac3991f915 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Sat, 25 Feb 2023 22:56:02 +0100 Subject: [PATCH 0667/1333] ci: Add debug output for ports syscfg updates It seems that occasionally this fails on GHA but doesn't fail locally. This will help to debug this. --- .github/workflows/ports_syscfg_check.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ports_syscfg_check.yml b/.github/workflows/ports_syscfg_check.yml index a8d0254080..4dbea4e35c 100644 --- a/.github/workflows/ports_syscfg_check.yml +++ b/.github/workflows/ports_syscfg_check.yml @@ -51,11 +51,17 @@ jobs: git clone --depth=1 https://github.com/apache/mynewt-mcumgr /tmp/proj/repos/apache-mynewt-mcumgr git clone --depth=1 https://github.com/hathach/tinyusb.git /tmp/proj/repos/tinyusb cp -r `pwd` /tmp/proj/repos/apache-mynewt-nimble - - name: Check ports syscfg + - name: Build ports tests targets run: | cd /tmp/proj ./repos/apache-mynewt-nimble/porting/update_generated_files.sh cd repos/apache-mynewt-nimble + - name: Check ports syscfg (debug) + if: runner.debug == '1' + run: | + git diff + - name: Check ports syscfg + run: | git diff --quiet || (\ echo -e "\033[0;31mChanges in system configration files detected."; echo -e "\033[0;31mRun ./repos/apache-mynewt-nimble/porting/update_generated_files.sh" \ From 92e63dda2b1cd5bc6d73e052231e2b0bf421c798 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 28 Feb 2023 15:12:55 +0100 Subject: [PATCH 0668/1333] nimble/host: Add peer id addr to identity resolved event This way app does not need to query for new ID address. --- nimble/host/include/host/ble_gap.h | 2 ++ nimble/host/src/ble_gap.c | 3 ++- nimble/host/src/ble_gap_priv.h | 2 +- nimble/host/src/ble_sm.c | 3 ++- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index 47a1d5647d..8324272d98 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -808,6 +808,8 @@ struct ble_gap_event { struct { /** The handle of the relevant connection. */ uint16_t conn_handle; + /** Peer identity address */ + ble_addr_t peer_id_addr; } identity_resolved; /** diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 85b4c44188..6a82f4eb1a 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -6104,7 +6104,7 @@ ble_gap_enc_event(uint16_t conn_handle, int status, } void -ble_gap_identity_event(uint16_t conn_handle) +ble_gap_identity_event(uint16_t conn_handle, const ble_addr_t *peer_id_addr) { #if NIMBLE_BLE_SM && NIMBLE_BLE_CONNECT struct ble_gap_event event; @@ -6114,6 +6114,7 @@ ble_gap_identity_event(uint16_t conn_handle) memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_IDENTITY_RESOLVED; event.identity_resolved.conn_handle = conn_handle; + event.identity_resolved.peer_id_addr = *peer_id_addr; ble_gap_call_conn_event_cb(&event, conn_handle); #endif } diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h index 5b627d1057..1c3f92b740 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/nimble/host/src/ble_gap_priv.h @@ -135,7 +135,7 @@ void ble_gap_subscribe_event(uint16_t conn_handle, uint16_t attr_handle, uint8_t prev_notify, uint8_t cur_notify, uint8_t prev_indicate, uint8_t cur_indicate); void ble_gap_mtu_event(uint16_t conn_handle, uint16_t cid, uint16_t mtu); -void ble_gap_identity_event(uint16_t conn_handle); +void ble_gap_identity_event(uint16_t conn_handle, const ble_addr_t *peer_id_addr); int ble_gap_repeat_pairing_event(const struct ble_gap_repeat_pairing *rp); void ble_gap_pairing_complete_event(uint16_t conn_handle, int status); void ble_gap_vs_hci_event(const void *buf, uint8_t len); diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 4658e1d2b2..3066fda0a6 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -573,7 +573,8 @@ ble_sm_persist_keys(struct ble_sm_proc *proc) ble_hs_unlock(); if (identity_ev) { - ble_gap_identity_event(proc->conn_handle); + /* Use peer_addr since it does have proper addr type (i.e. 0/1, not 2/3) */ + ble_gap_identity_event(proc->conn_handle, &peer_addr); } authenticated = proc->flags & BLE_SM_PROC_F_AUTHENTICATED; From bc7828341226d860429c63994065f8f1b8b8d7b0 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Wed, 1 Mar 2023 19:26:49 +0100 Subject: [PATCH 0669/1333] ble_hci_socket.c: fix warning 'len' may be used uninitialized in this function [-Wmaybe-uninitialized] --- nimble/transport/socket/src/ble_hci_socket.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/transport/socket/src/ble_hci_socket.c b/nimble/transport/socket/src/ble_hci_socket.c index 059bf4a922..d77baef66d 100644 --- a/nimble/transport/socket/src/ble_hci_socket.c +++ b/nimble/transport/socket/src/ble_hci_socket.c @@ -334,6 +334,7 @@ ble_hci_sock_cmdevt_tx(uint8_t *hci_ev, uint8_t h4_type) memcpy(&addr, &addr, sizeof(struct sockaddr_hci)); + len = 0; if (h4_type == BLE_HCI_UART_H4_CMD) { len = sizeof(struct ble_hci_cmd) + hci_ev[2]; STATS_INC(hci_sock_stats, ocmd); From d01f529e84fc58a45e57ffd49e91559c26d59752 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Tue, 28 Feb 2023 14:06:56 +0100 Subject: [PATCH 0670/1333] nimble/host: Add connection handle related GAP APIs This adds two new GAP APIs: void ble_gap_conn_foreach_handle(ble_gap_conn_foreach_handle_fn *cb, void *arg) API can be used to call function declared by the user for every connection that is currently established. As arguments, it takes a pointer to the function, that will be called and a void pointer, which is used to pass the optional argument of any type to the called function. Function from passed pointer should return an int value and take two arguments - uint16_t for conn_handle and void* for the optional argument (see ble_gap_conn_foreach_handle_fn typedef). int ble_gap_conn_func_handle_by_addr(const ble_addr_t *addr, uint16_t *out_conn_handle) The API will look for the connection with address specified in the first argument and if it succeds, it will write the connection handle to the variable pointed by out_conn_handle. Returns 0 on success or BLE_HS_ENOTCONN if connection with specified address was not found. --- nimble/host/include/host/ble_gap.h | 1 + nimble/host/src/ble_gap.c | 51 ++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index 8324272d98..a5dadfbdf2 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -1092,6 +1092,7 @@ struct ble_gap_event { }; typedef int ble_gap_event_fn(struct ble_gap_event *event, void *arg); +typedef int ble_gap_conn_foreach_handle_fn(uint16_t conn_handle, void *arg); #define BLE_GAP_CONN_MODE_NON 0 #define BLE_GAP_CONN_MODE_DIR 1 diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 6a82f4eb1a..f486b72097 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -513,6 +513,57 @@ ble_gap_conn_find_by_addr(const ble_addr_t *addr, #endif } +int +ble_gap_conn_find_handle_by_addr(const ble_addr_t *addr, uint16_t *out_conn_handle) +{ +#if NIMBLE_BLE_CONNECT + struct ble_hs_conn *conn; + + ble_hs_lock(); + + conn = ble_hs_conn_find_by_addr(addr); + if (conn != NULL) { + *out_conn_handle = conn->bhc_handle; + } else { + *out_conn_handle = BLE_HS_CONN_HANDLE_NONE; + } + + ble_hs_unlock(); + + if (conn == NULL) { + return BLE_HS_ENOTCONN; + } + + return 0; +#else + return BLE_HS_ENOTSUP; +#endif +} + +struct foreach_handle_cb_arg { + ble_gap_conn_foreach_handle_fn *cb; + void *arg; +}; + +static int +ble_gap_conn_foreach_handle_callback(struct ble_hs_conn *conn, void *arg) +{ + struct foreach_handle_cb_arg *cb_arg = (struct foreach_handle_cb_arg *)arg; + + return cb_arg->cb(conn->bhc_handle, cb_arg->arg); +} + +void +ble_gap_conn_foreach_handle(ble_gap_conn_foreach_handle_fn *cb, void *arg) +{ + struct foreach_handle_cb_arg cb_arg = { + .cb = cb, + .arg = arg, + }; + + ble_hs_conn_foreach(ble_gap_conn_foreach_handle_callback, &cb_arg); +} + #if NIMBLE_BLE_CONNECT static int ble_gap_extract_conn_cb(uint16_t conn_handle, From 377c6107ed8c016304949d6d338ff3d8ff90ce48 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 7 Mar 2023 21:50:57 +0100 Subject: [PATCH 0671/1333] ci: Use latest go for building newt This should make it easier for upgrading dependencies in newt. --- .github/workflows/build_targets.yml | 4 ++-- .github/workflows/newt_test_all.yml | 4 ++-- .github/workflows/ports_syscfg_check.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_targets.yml b/.github/workflows/build_targets.yml index c14f8da18e..ec7c1ac70a 100644 --- a/.github/workflows/build_targets.yml +++ b/.github/workflows/build_targets.yml @@ -33,7 +33,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '1.16' + go-version: 'stable' - uses: carlosperate/arm-none-eabi-gcc-action@48db4484a55750df7a0ccca63347fcdea6534d78 with: release: '12.2.Rel1' @@ -45,7 +45,7 @@ jobs: - name: Install newt run: | go version - go get mynewt.apache.org/newt/newt@latest + go install mynewt.apache.org/newt/newt@latest - name: Setup project run: | cp .github/project.yml project.yml diff --git a/.github/workflows/newt_test_all.yml b/.github/workflows/newt_test_all.yml index 26048d9fd1..988ba09fd9 100644 --- a/.github/workflows/newt_test_all.yml +++ b/.github/workflows/newt_test_all.yml @@ -29,7 +29,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '1.16' + go-version: 'stable' - name: Install Dependencies run: | sudo apt-get update @@ -37,7 +37,7 @@ jobs: - name: Install newt run: | go version - go get mynewt.apache.org/newt/newt@latest + go install mynewt.apache.org/newt/newt@latest - name: Setup project run: | cp .github/project.yml project.yml diff --git a/.github/workflows/ports_syscfg_check.yml b/.github/workflows/ports_syscfg_check.yml index 4dbea4e35c..07f1300544 100644 --- a/.github/workflows/ports_syscfg_check.yml +++ b/.github/workflows/ports_syscfg_check.yml @@ -29,7 +29,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '1.16' + go-version: 'stable' - uses: carlosperate/arm-none-eabi-gcc-action@48db4484a55750df7a0ccca63347fcdea6534d78 with: release: '12.2.Rel1' @@ -40,7 +40,7 @@ jobs: - name: Install newt run: | go version - go get mynewt.apache.org/newt/newt@latest + go install mynewt.apache.org/newt/newt@latest - name: Setup project run: | mkdir /tmp/proj From 1a5d0bf1c3437361b3e698d9edb0cd102cb672e5 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 13 Mar 2023 15:58:06 +0100 Subject: [PATCH 0672/1333] nimble/phy/nrf5x: Fix tx-tx timing When scheduling relative to TX start time we should also adjust for delay between radio event and actual TX time. --- nimble/drivers/nrf5x/src/ble_phy.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index bf989e88e0..d0f7418515 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -1113,6 +1113,10 @@ ble_phy_tx_end_isr(void) */ tx_time = NRF_TIMER0->CC[1] - ble_ll_pdu_syncword_us(tx_phy_mode) + g_ble_phy_data.txtx_time_us; + /* Adjust for delay between EVENT_ADDRESS and actual address TX time */ + /* FIXME assume this is the same as EVENT_END to end, but we should + * measure this to be sure */ + tx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; } /* Adjust for delay between EVENT_END and actual TX end time */ From 88758a810731c978e08d985d603b2aad82283663 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Wed, 8 Mar 2023 09:08:58 +0100 Subject: [PATCH 0673/1333] porting/nuttx/example: perform initialization if not done by NSH For example, when Nimble NuttX example is the entry point for users applications. --- porting/examples/nuttx/main.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/porting/examples/nuttx/main.c b/porting/examples/nuttx/main.c index 7492e120e9..9eeddec838 100644 --- a/porting/examples/nuttx/main.c +++ b/porting/examples/nuttx/main.c @@ -24,6 +24,9 @@ #include #include #include +#include + +#include "netutils/netinit.h" #include "nimble/nimble_npl.h" #include "nimble/nimble_port.h" @@ -71,6 +74,18 @@ int main(int argc, char *argv[]) ble_hci_sock_set_device(atoi(argv[1])); } +#ifndef CONFIG_NSH_ARCHINIT + /* Perform architecture-specific initialization */ + + boardctl(BOARDIOC_INIT, 0); +#endif + +#ifndef CONFIG_NSH_NETINIT + /* Bring up the network */ + + netinit_bringup(); +#endif + printf("port init\n"); nimble_port_init(); From 64758379a6d9fe9eb7e0e6725823cd63c06a1223 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Tue, 14 Mar 2023 17:02:07 +0530 Subject: [PATCH 0674/1333] This will help not execute extra code when DEBUG level is not set. --- nimble/host/src/ble_att_clt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_att_clt.c b/nimble/host/src/ble_att_clt.c index a36cf3aa0a..b500f416c1 100644 --- a/nimble/host/src/ble_att_clt.c +++ b/nimble/host/src/ble_att_clt.c @@ -707,6 +707,8 @@ ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t handle, struct ble_att_write_cmd *cmd; struct os_mbuf *txom2; + +#if MYNEWT_VAL(BLE_HS_DEBUG) uint8_t b; int rc; int i; @@ -720,7 +722,7 @@ ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t handle, assert(rc == 0); BLE_HS_LOG(DEBUG, "0x%02x", b); } - +#endif cmd = ble_att_cmd_get(BLE_ATT_OP_WRITE_CMD, sizeof(*cmd), &txom2); if (cmd == NULL) { From 7cc8c08d67d52b373eeeec6b33b113192cf2e996 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Fri, 17 Mar 2023 10:21:46 +0100 Subject: [PATCH 0675/1333] nimble/host: Update existing bond while re-pairing While re-pairing ble_store_config_find_sec function was checking peer address, ediv and random number. Even if peer address was the same, the bond could be recognized as not the one we was looking for, because ediv and random number could be different. This was causting issues when the BLE_STORE_MAX_BONDS syscfg val was used. Re-pairing to the same device was treated as pairing to the new device and if current number of bonds was the same as BLE_STORE_MAX_BONDS, the re-pairing was failing. --- apps/btshell/src/cmd.c | 13 ------- nimble/host/include/host/ble_store.h | 8 ----- nimble/host/src/ble_sm.c | 6 ++-- nimble/host/src/ble_store.c | 28 +++++++-------- .../host/store/config/src/ble_store_config.c | 36 +++++-------------- nimble/host/store/ram/src/ble_store_ram.c | 36 +++++-------------- nimble/host/test/src/ble_sm_test_util.c | 6 ---- 7 files changed, 31 insertions(+), 102 deletions(-) diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index fd75bc02bf..4148b8e8a1 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -2258,17 +2258,6 @@ cmd_keystore_parse_keydata(int argc, char **argv, union ble_store_key *out, return rc; } - out->sec.ediv = parse_arg_uint16("ediv", &rc); - if (rc != 0) { - console_printf("invalid 'ediv' parameter\n"); - return rc; - } - - out->sec.rand_num = parse_arg_uint64("rand", &rc); - if (rc != 0) { - console_printf("invalid 'rand' parameter\n"); - return rc; - } return 0; default: @@ -2317,8 +2306,6 @@ cmd_keystore_parse_valuedata(int argc, char **argv, return rc; } out->sec.peer_addr = key->sec.peer_addr; - out->sec.ediv = key->sec.ediv; - out->sec.rand_num = key->sec.rand_num; break; } diff --git a/nimble/host/include/host/ble_store.h b/nimble/host/include/host/ble_store.h index 7c03ed860e..24b208a09d 100644 --- a/nimble/host/include/host/ble_store.h +++ b/nimble/host/include/host/ble_store.h @@ -50,14 +50,6 @@ struct ble_store_key_sec { */ ble_addr_t peer_addr; - /** Key by ediv; ediv_rand_present=0 means don't key off ediv. */ - uint16_t ediv; - - /** Key by rand_num; ediv_rand_present=0 means don't key off rand_num. */ - uint64_t rand_num; - - unsigned ediv_rand_present:1; - /** Number of results to skip; 0 means retrieve the first match. */ uint8_t idx; }; diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 3066fda0a6..643712d491 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -1242,11 +1242,11 @@ ble_sm_retrieve_ltk(uint16_t ediv, uint64_t rand, uint8_t peer_addr_type, memset(&key_sec, 0, sizeof key_sec); key_sec.peer_addr.type = peer_addr_type; memcpy(key_sec.peer_addr.val, peer_addr, 6); - key_sec.ediv = ediv; - key_sec.rand_num = rand; - key_sec.ediv_rand_present = 1; rc = ble_store_read_our_sec(&key_sec, value_sec); + if (value_sec->ediv != ediv || value_sec->rand_num != rand) { + return BLE_HS_ENOENT; + } return rc; } diff --git a/nimble/host/src/ble_store.c b/nimble/host/src/ble_store.c index 22e6089471..1adab34673 100644 --- a/nimble/host/src/ble_store.c +++ b/nimble/host/src/ble_store.c @@ -299,10 +299,6 @@ ble_store_key_from_value_sec(struct ble_store_key_sec *out_key, const struct ble_store_value_sec *value) { out_key->peer_addr = value->peer_addr; - - out_key->ediv = value->ediv; - out_key->rand_num = value->rand_num; - out_key->ediv_rand_present = 1; out_key->idx = 0; } @@ -341,18 +337,18 @@ ble_store_iterate(int obj_type, /* a magic value to retrieve anything */ memset(&key, 0, sizeof(key)); switch(obj_type) { - case BLE_STORE_OBJ_TYPE_PEER_SEC: - case BLE_STORE_OBJ_TYPE_OUR_SEC: - key.sec.peer_addr = *BLE_ADDR_ANY; - pidx = &key.sec.idx; - break; - case BLE_STORE_OBJ_TYPE_CCCD: - key.cccd.peer_addr = *BLE_ADDR_ANY; - pidx = &key.cccd.idx; - break; - default: - BLE_HS_DBG_ASSERT(0); - return BLE_HS_EINVAL; + case BLE_STORE_OBJ_TYPE_PEER_SEC: + case BLE_STORE_OBJ_TYPE_OUR_SEC: + key.sec.peer_addr = *BLE_ADDR_ANY; + pidx = &key.sec.idx; + break; + case BLE_STORE_OBJ_TYPE_CCCD: + key.cccd.peer_addr = *BLE_ADDR_ANY; + pidx = &key.cccd.idx; + break; + default: + BLE_HS_DBG_ASSERT(0); + return BLE_HS_EINVAL; } while (1) { diff --git a/nimble/host/store/config/src/ble_store_config.c b/nimble/host/store/config/src/ble_store_config.c index cc1d59afd5..0220ba760e 100644 --- a/nimble/host/store/config/src/ble_store_config.c +++ b/nimble/host/store/config/src/ble_store_config.c @@ -75,10 +75,6 @@ ble_store_config_print_key_sec(const struct ble_store_key_sec *key_sec) ble_hs_log_flat_buf(key_sec->peer_addr.val, 6); BLE_HS_LOG(DEBUG, " "); } - if (key_sec->ediv_rand_present) { - BLE_HS_LOG(DEBUG, "ediv=0x%02x rand=0x%llx ", - key_sec->ediv, key_sec->rand_num); - } } static int @@ -87,36 +83,20 @@ ble_store_config_find_sec(const struct ble_store_key_sec *key_sec, int num_value_secs) { const struct ble_store_value_sec *cur; - int skipped; int i; - skipped = 0; - - for (i = 0; i < num_value_secs; i++) { - cur = value_secs + i; - - if (ble_addr_cmp(&key_sec->peer_addr, BLE_ADDR_ANY)) { - if (ble_addr_cmp(&cur->peer_addr, &key_sec->peer_addr)) { - continue; - } + if (!ble_addr_cmp(&key_sec->peer_addr, BLE_ADDR_ANY)) { + if (key_sec->idx < num_value_secs) { + return key_sec->idx; } + } else if (key_sec->idx == 0) { + for (i = 0; i < num_value_secs; i++) { + cur = &value_secs[i]; - if (key_sec->ediv_rand_present) { - if (cur->ediv != key_sec->ediv) { - continue; + if (!ble_addr_cmp(&cur->peer_addr, &key_sec->peer_addr)) { + return i; } - - if (cur->rand_num != key_sec->rand_num) { - continue; - } - } - - if (key_sec->idx > skipped) { - skipped++; - continue; } - - return i; } return -1; diff --git a/nimble/host/store/ram/src/ble_store_ram.c b/nimble/host/store/ram/src/ble_store_ram.c index b912ea476a..450be717d2 100644 --- a/nimble/host/store/ram/src/ble_store_ram.c +++ b/nimble/host/store/ram/src/ble_store_ram.c @@ -84,10 +84,6 @@ ble_store_ram_print_key_sec(const struct ble_store_key_sec *key_sec) ble_hs_log_flat_buf(key_sec->peer_addr.val, 6); BLE_HS_LOG(DEBUG, " "); } - if (key_sec->ediv_rand_present) { - BLE_HS_LOG(DEBUG, "ediv=0x%02x rand=0x%llx ", - key_sec->ediv, key_sec->rand_num); - } } static int @@ -96,36 +92,20 @@ ble_store_ram_find_sec(const struct ble_store_key_sec *key_sec, int num_value_secs) { const struct ble_store_value_sec *cur; - int skipped; int i; - skipped = 0; - - for (i = 0; i < num_value_secs; i++) { - cur = value_secs + i; - - if (ble_addr_cmp(&key_sec->peer_addr, BLE_ADDR_ANY)) { - if (ble_addr_cmp(&cur->peer_addr, &key_sec->peer_addr)) { - continue; - } + if (!ble_addr_cmp(&key_sec->peer_addr, BLE_ADDR_ANY)) { + if (key_sec->idx < num_value_secs) { + return key_sec->idx; } + } else if (key_sec->idx == 0) { + for (i = 0; i < num_value_secs; i++) { + cur = &value_secs[i]; - if (key_sec->ediv_rand_present) { - if (cur->ediv != key_sec->ediv) { - continue; + if (!ble_addr_cmp(&cur->peer_addr, &key_sec->peer_addr)) { + return i; } - - if (cur->rand_num != key_sec->rand_num) { - continue; - } - } - - if (key_sec->idx > skipped) { - skipped++; - continue; } - - return i; } return -1; diff --git a/nimble/host/test/src/ble_sm_test_util.c b/nimble/host/test/src/ble_sm_test_util.c index bad473f178..e3becdf866 100644 --- a/nimble/host/test/src/ble_sm_test_util.c +++ b/nimble/host/test/src/ble_sm_test_util.c @@ -1671,9 +1671,6 @@ ble_sm_test_util_peer_bonding_good(int send_enc_req, TEST_ASSERT(ble_sm_test_store_obj_type == BLE_STORE_OBJ_TYPE_OUR_SEC); TEST_ASSERT(ble_sm_test_store_key.sec.peer_addr.type == ble_hs_misc_peer_addr_type_to_id(peer_addr_type)); - TEST_ASSERT(ble_sm_test_store_key.sec.ediv_rand_present); - TEST_ASSERT(ble_sm_test_store_key.sec.ediv == ediv); - TEST_ASSERT(ble_sm_test_store_key.sec.rand_num == rand_num); TEST_ASSERT(!conn->bhc_sec_state.encrypted); TEST_ASSERT(ble_sm_num_procs() == 1); @@ -1738,9 +1735,6 @@ ble_sm_test_util_peer_bonding_bad(uint16_t ediv, uint64_t rand_num) /* Ensure the LTK request event got sent to the application. */ TEST_ASSERT(ble_sm_test_store_obj_type == BLE_STORE_OBJ_TYPE_OUR_SEC); - TEST_ASSERT(ble_sm_test_store_key.sec.ediv_rand_present); - TEST_ASSERT(ble_sm_test_store_key.sec.ediv == ediv); - TEST_ASSERT(ble_sm_test_store_key.sec.rand_num == rand_num); TEST_ASSERT(!conn->bhc_sec_state.encrypted); From e75ee046145e5dcedb8f9de8e250b24ffe503f1c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 23 Aug 2022 21:27:40 +0200 Subject: [PATCH 0676/1333] nimble/ll: Remove some unused defs --- nimble/controller/include/controller/ble_ll_scan.h | 5 ----- nimble/controller/include/controller/ble_ll_sched.h | 6 ------ nimble/controller/src/ble_ll_scan.c | 5 ----- 3 files changed, 16 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index 34bcd60b17..07e4c9208a 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -235,11 +235,6 @@ void ble_ll_scan_wfr_timer_exp(void); /* Called when scan could be interrupted */ void ble_ll_scan_interrupted(struct ble_ll_scan_sm *scansm); -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -/* Called to parse extended advertising*/ -void ble_ll_scan_end_adv_evt(struct ble_ll_aux_data *aux_data); -#endif - /* Called to halt currently running scan */ void ble_ll_scan_halt(void); diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index 12fe3dfeac..f9334c6158 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -172,12 +172,6 @@ int ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm * connsm); int ble_ll_sched_next_time(uint32_t *next_event_time); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -struct ble_ll_scan_sm; -struct ble_ll_aux_data; -int ble_ll_sched_aux_scan(struct ble_mbuf_hdr *ble_hdr, - struct ble_ll_scan_sm *scansm, - struct ble_ll_aux_data *aux_scan); - int ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time, uint8_t pdu_time_rem, uint32_t offset_us, uint32_t max_aux_time_us); diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index b7516e7805..748cf3ac5d 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -362,11 +362,6 @@ ble_ll_scan_get_ext_adv_report(struct ext_adv_report *copy_from) return hci_ev; } - -void -ble_ll_scan_end_adv_evt(struct ble_ll_aux_data *aux_data) -{ -} #endif void From 465de20085122cbc5e2579b386ce52e494ee6693 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 22 Aug 2022 21:01:04 +0200 Subject: [PATCH 0677/1333] nimble/ll: Fix aux scan timing We should include clock drift due to sleep clock accuracy and jitter when calculating aux scan start time (Core 5.3, Vol 6, Part B, 4.2.2). Slot duration calculation should also include the above and possible drift due to offset accuracy. --- .../include/controller/ble_ll_scan_aux.h | 4 +- .../include/controller/ble_ll_sched.h | 4 +- nimble/controller/src/ble_ll_scan_aux.c | 103 +++++++++--------- nimble/controller/src/ble_ll_sched.c | 13 +-- 4 files changed, 57 insertions(+), 67 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_scan_aux.h b/nimble/controller/include/controller/ble_ll_scan_aux.h index c7d63b8449..b1d6c9caf5 100644 --- a/nimble/controller/include/controller/ble_ll_scan_aux.h +++ b/nimble/controller/include/controller/ble_ll_scan_aux.h @@ -29,8 +29,8 @@ extern "C" { struct ble_ll_scan_aux_data; void ble_ll_scan_aux_init(void); -int ble_ll_scan_aux_sched(struct ble_ll_scan_aux_data *aux, uint32_t pdu_time, - uint8_t pdu_time_rem, uint32_t aux_ptr); +int ble_ll_scan_aux_sched(struct ble_ll_scan_aux_data *aux, uint32_t pdu_ticks, + uint8_t pdu_rem_us, uint32_t aux_ptr); int ble_ll_scan_aux_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *rxhdr); int ble_ll_scan_aux_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok); void ble_ll_scan_aux_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *rxhdr); diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index f9334c6158..5e04ce09f7 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -172,9 +172,7 @@ int ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm * connsm); int ble_ll_sched_next_time(uint32_t *next_event_time); #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -int ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time, - uint8_t pdu_time_rem, uint32_t offset_us, - uint32_t max_aux_time_us); +int ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch); #endif /* Stop the scheduler */ diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 45c55ba078..6160fef234 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -68,7 +68,7 @@ struct ble_ll_scan_aux_data { uint8_t pri_phy; uint8_t sec_phy; uint8_t chan; - uint8_t offset_unit : 1; + uint16_t wfr_us; uint32_t aux_ptr; struct ble_ll_sched_item sch; struct ble_npl_event break_ev; @@ -111,7 +111,6 @@ static int ble_ll_scan_aux_sched_cb(struct ble_ll_sched_item *sch) { struct ble_ll_scan_aux_data *aux = sch->cb_arg; - uint32_t wfr_us; #if BLE_LL_BT5_PHY_SUPPORTED uint8_t phy_mode; #endif @@ -158,8 +157,7 @@ ble_ll_scan_aux_sched_cb(struct ble_ll_sched_item *sch) ble_ll_whitelist_disable(); } - wfr_us = aux->offset_unit ? 300 : 30; - ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_RX, 0, wfr_us); + ble_phy_wfr_enable(BLE_PHY_WFR_ENABLE_RX, 0, aux->wfr_us); aux_data_current = aux; @@ -683,82 +681,87 @@ ble_ll_scan_aux_break(struct ble_ll_scan_aux_data *aux) } static int -ble_ll_scan_aux_parse_aux_ptr(struct ble_ll_scan_aux_data *aux, - uint32_t aux_ptr, uint32_t *offset_us) +ble_ll_scan_aux_phy_to_phy(uint8_t aux_phy, uint8_t *phy) { - uint8_t offset_unit; - uint32_t offset; - uint8_t chan; - uint8_t phy; - - phy = (aux_ptr >> 21) & 0x07; - switch (phy) { + switch (aux_phy) { case 0: - phy = BLE_PHY_1M; + *phy = BLE_PHY_1M; break; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) case 1: - phy = BLE_PHY_2M; + *phy = BLE_PHY_2M; break; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) case 2: - phy = BLE_PHY_CODED; + *phy = BLE_PHY_CODED; break; #endif default: return -1; } + return 0; +} + +int +ble_ll_scan_aux_sched(struct ble_ll_scan_aux_data *aux, uint32_t pdu_ticks, + uint8_t pdu_rem_us, uint32_t aux_ptr) +{ + struct ble_ll_sched_item *sch; + uint32_t aux_offset; + uint8_t offset_unit; + uint8_t aux_phy; + uint8_t chan; + uint8_t ca; + uint8_t phy; + uint32_t offset_us; + uint16_t pdu_rx_us; + uint16_t aux_ww_us; + uint16_t aux_tx_win_us; + + /* Parse AuxPtr */ chan = aux_ptr & 0x3f; + ca = aux_ptr & 0x40; + offset_unit = aux_ptr & 0x80; + aux_offset = (aux_ptr >> 8) & 0x1fff; + aux_phy = (aux_ptr >> 21) & 0x07; + if (chan >= BLE_PHY_NUM_DATA_CHANS) { return -1; } - offset = 30 * ((aux_ptr >> 8) & 0x1fff); - if ((aux_ptr >> 7) & 0x01) { - offset *= 10; - offset_unit = 1; - } else { - offset_unit = 0; - } - - if (offset < BLE_LL_MAFS) { + if (ble_ll_scan_aux_phy_to_phy(aux_phy, &phy) < 0) { return -1; } + /* Actual offset */ + offset_us = aux_offset * (offset_unit ? 300 : 30); + /* Time to scan aux PDU */ + pdu_rx_us = ble_ll_pdu_us(MYNEWT_VAL(BLE_LL_SCHED_SCAN_AUX_PDU_LEN), + ble_ll_phy_to_phy_mode(phy, 0)); + /* Transmit window */ + aux_tx_win_us = offset_unit ? 300 : 30; + /* Window widening to include drift due to sleep clock accuracy and jitter */ + aux_ww_us = offset_us * (ca ? 50 : 500) / 1000000 + BLE_LL_JITTER_USECS; + aux->sec_phy = phy; aux->chan = chan; - aux->offset_unit = offset_unit; + aux->wfr_us = aux_ww_us + aux_tx_win_us; - *offset_us = offset; + sch = &aux->sch; - return 0; -} + sch->start_time = pdu_ticks; + sch->remainder = pdu_rem_us; + ble_ll_tmr_add(&sch->start_time, &sch->remainder, offset_us - aux_ww_us); -int -ble_ll_scan_aux_sched(struct ble_ll_scan_aux_data *aux, uint32_t pdu_time, - uint8_t pdu_time_rem, uint32_t aux_ptr) -{ - uint32_t offset_us; - uint32_t max_aux_time_us; - int rc; + sch->end_time = sch->start_time + + ble_ll_tmr_u2t_up(sch->remainder + 2 * aux_ww_us + + aux_tx_win_us + pdu_rx_us); - rc = ble_ll_scan_aux_parse_aux_ptr(aux, aux_ptr, &offset_us); - if (rc < 0) { - return -1; - } - - max_aux_time_us = ble_ll_pdu_us(MYNEWT_VAL(BLE_LL_SCHED_SCAN_AUX_PDU_LEN), - ble_ll_phy_to_phy_mode(aux->sec_phy, 0)); - - rc = ble_ll_sched_scan_aux(&aux->sch, pdu_time, pdu_time_rem, offset_us, - max_aux_time_us); - if (rc < 0) { - return -1; - } + sch->start_time -= g_ble_ll_sched_offset_ticks; - return 0; + return ble_ll_sched_scan_aux(&aux->sch); } int diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 513257db59..e7524193cb 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -1119,22 +1119,11 @@ ble_ll_sched_next_time(uint32_t *next_event_time) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) int -ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch, uint32_t pdu_time, - uint8_t pdu_time_rem, uint32_t offset_us, - uint32_t max_aux_time_us) +ble_ll_sched_scan_aux(struct ble_ll_sched_item *sch) { - uint32_t offset_ticks; os_sr_t sr; int rc; - offset_us += pdu_time_rem; - offset_ticks = ble_ll_tmr_u2t(offset_us); - - sch->start_time = pdu_time + offset_ticks; - sch->remainder = offset_us - ble_ll_tmr_t2u(offset_ticks); - sch->end_time = sch->start_time + ble_ll_tmr_u2t_up(max_aux_time_us); - sch->start_time -= g_ble_ll_sched_offset_ticks; - OS_ENTER_CRITICAL(sr); rc = ble_ll_sched_insert(sch, 0, preempt_none); From d8dfb1699171f91b82c1238b0d7f793fe98fa347 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 6 Apr 2023 12:15:43 +0200 Subject: [PATCH 0678/1333] nimble/ll: Fix HCI_Host_Buffer_Size Any non-zero value for num ACL packets and packet length is valid. The quoted text from spec referrerd to command and event packets, not ACL packets. --- nimble/controller/src/ble_ll_hci.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index a7c0718774..37ba94c617 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1464,17 +1464,9 @@ ble_ll_hci_cb_host_buf_size(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } - /* - * Core 5.2 Vol 4 Part E section 7.3.39 states that "Both the Host and the - * Controller shall support command and event packets, where the data portion - * (excluding header) contained in the packets is 255 octets in size.". - * This means we can basically accept any allowed value since LL does not - * reassemble incoming data thus will not send more than 255 octets in single - * data packet. - */ acl_num = le16toh(cmd->acl_num); acl_data_len = le16toh(cmd->acl_data_len); - if (acl_data_len < 255) { + if ((acl_num < 1) || (acl_data_len < 1)) { return BLE_ERR_INV_HCI_CMD_PARMS; } From 333c575bbfa2278deda04cd0081666940a76b525 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Thu, 6 Apr 2023 14:04:25 +0200 Subject: [PATCH 0679/1333] build: fix various compile warnings mostly comparison signed vs unsigned and possible un-initialized usage --- nimble/controller/src/ble_ll_adv.c | 4 ++-- nimble/controller/src/ble_ll_conn.c | 4 ++-- nimble/controller/src/ble_ll_conn_hci.c | 4 ++-- nimble/controller/src/ble_ll_ctrl.c | 10 +++++----- nimble/controller/src/ble_ll_hci_ev.c | 2 +- nimble/controller/src/ble_ll_sched.c | 2 +- nimble/controller/src/ble_ll_sync.c | 12 ++++++------ nimble/host/services/ans/src/ble_svc_ans.c | 1 + nimble/host/src/ble_att.c | 2 +- nimble/host/src/ble_hs_hci.c | 4 ++-- nimble/host/src/ble_hs_hci_evt.c | 2 +- nimble/host/src/ble_hs_hci_util.c | 2 +- nimble/host/src/ble_l2cap_coc.c | 2 +- nimble/host/src/ble_store.c | 2 +- porting/nimble/src/hal_timer.c | 2 +- 15 files changed, 28 insertions(+), 27 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 1173c193c0..ab5e6e2dbe 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -222,7 +222,7 @@ static struct ble_ll_adv_sm * ble_ll_adv_sm_find_configured(uint8_t instance) { struct ble_ll_adv_sm *advsm; - int i; + unsigned int i; /* in legacy mode we only allow instance 0 */ if (!ble_ll_hci_adv_mode_ext()) { @@ -3295,7 +3295,7 @@ static struct ble_ll_adv_sm * ble_ll_adv_sm_get(uint8_t instance) { struct ble_ll_adv_sm *advsm; - int i; + unsigned int i; advsm = ble_ll_adv_sm_find_configured(instance); if (advsm) { diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 0c6530b51a..d1e87204ac 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1473,7 +1473,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) static int ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) { - int rc; + int rc = 0; #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) uint32_t usecs; #endif @@ -3594,7 +3594,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) uint8_t hdr_nesn; uint8_t conn_sn; uint8_t conn_nesn; - uint8_t reply; + uint8_t reply = 0; uint16_t rem_bytes; uint8_t opcode = 0; uint8_t rx_pyld_len; diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 5010dddb42..a14c2f329c 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -140,7 +140,7 @@ ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, struct ble_hci_ev_le_subev_enh_conn_complete *enh_ev; struct ble_hci_ev_le_subev_conn_complete *ev; struct ble_hci_ev *hci_ev = (void *) evbuf; - uint8_t *rpa; + uint8_t *rpa = NULL; BLE_LL_ASSERT(evbuf); @@ -801,7 +801,7 @@ ble_ll_conn_hci_ext_create(const uint8_t *cmdbuf, uint8_t len) cc_params_fb = NULL; - for (int i = 0; i < ARRAY_SIZE(init_phys); i++) { + for (unsigned int i = 0; i < ARRAY_SIZE(init_phys); i++) { init_phy = &init_phys[i]; if ((cc_scan.init_phy_mask & init_phy->mask) == 0) { diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index b7c9c01e8a..03b9177f6c 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1720,7 +1720,7 @@ ble_ll_ctrl_rx_pause_enc_req(struct ble_ll_conn_sm *connsm) static uint8_t ble_ll_ctrl_rx_pause_enc_rsp(struct ble_ll_conn_sm *connsm) { - int rc; + int rc = 0; switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) @@ -1761,7 +1761,7 @@ ble_ll_ctrl_rx_pause_enc_rsp(struct ble_ll_conn_sm *connsm) static uint8_t ble_ll_ctrl_rx_start_enc_rsp(struct ble_ll_conn_sm *connsm) { - int rc; + int rc = 0; /* Not in proper state. Discard */ if (connsm->enc_data.enc_state != CONN_ENC_S_START_ENC_RSP_WAIT) { @@ -1907,7 +1907,7 @@ uint8_t ble_ll_ctrl_conn_param_reply(struct ble_ll_conn_sm *connsm, uint8_t *rsp, struct ble_ll_conn_params *req) { - uint8_t rsp_opcode; + uint8_t rsp_opcode = 0; switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) @@ -2451,7 +2451,7 @@ static struct os_mbuf * ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc, void *data) { uint8_t len; - uint8_t opcode; + uint8_t opcode = 0; uint8_t *dptr; uint8_t *ctrdata; struct os_mbuf *om; @@ -2756,7 +2756,6 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) uint64_t feature; uint8_t len; uint8_t opcode; - uint8_t rsp_opcode; uint8_t *dptr; uint8_t *rspbuf; uint8_t *rspdata; @@ -2764,6 +2763,7 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) int restart_encryption; #endif int rc = 0; + uint8_t rsp_opcode = 0; /* XXX: where do we validate length received and packet header length? * do this in LL task when received. Someplace!!! What I mean diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index b0d9fa077f..bde965d478 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -585,7 +585,7 @@ ble_ll_hci_ev_send_vs_assert(const char *file, uint32_t line) * hci_ev->length += len; */ str_len = strlen(file); - if (str_len > max_len) { + if (str_len > (unsigned int)max_len) { str_len = max_len; } diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index e7524193cb..b31d7818e6 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -419,7 +419,7 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, #endif struct ble_ll_sched_item *sch; uint32_t orig_start_time; - uint32_t earliest_start; + uint32_t earliest_start = 0; uint32_t min_win_offset; uint32_t max_delay; uint32_t adv_rxend; diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index c83f4e319a..31791dce37 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -143,7 +143,7 @@ static int ble_ll_sync_event_start_cb(struct ble_ll_sched_item *sch); static int ble_ll_sync_on_list(const uint8_t *addr, uint8_t addr_type, uint8_t sid) { - int i; + unsigned int i; for (i = 0; i < ARRAY_SIZE(g_ble_ll_sync_adv_list); i++) { if ((g_ble_ll_sync_adv_list[i].adv_sid == sid) && @@ -159,7 +159,7 @@ ble_ll_sync_on_list(const uint8_t *addr, uint8_t addr_type, uint8_t sid) static int ble_ll_sync_list_get_free(void) { - int i; + unsigned int i; for (i = 0; i < ARRAY_SIZE(g_ble_ll_sync_adv_list); i++) { if (g_ble_ll_sync_adv_list[i].adv_sid == 0xff) { @@ -172,7 +172,7 @@ ble_ll_sync_list_get_free(void) static bool ble_ll_sync_list_empty(void) { - int i; + unsigned int i; for (i = 0; i < ARRAY_SIZE(g_ble_ll_sync_adv_list); i++) { if (g_ble_ll_sync_adv_list[i].adv_sid != 0xff) { @@ -1716,7 +1716,7 @@ ble_ll_sync_list_remove(const uint8_t *cmdbuf, uint8_t len) int ble_ll_sync_list_clear(void) { - int i; + unsigned int i; if (g_ble_ll_sync_create_comp_ev) { return BLE_ERR_CMD_DISALLOWED; @@ -2241,7 +2241,7 @@ ble_ll_sync_enabled(void) void ble_ll_sync_reset(void) { - int i; + unsigned int i; for (i = 0; i < BLE_LL_SYNC_CNT; i++) { ble_ll_sync_sm_clear(&g_ble_ll_sync_sm[i]); @@ -2267,7 +2267,7 @@ ble_ll_sync_reset(void) void ble_ll_sync_init(void) { - int i; + unsigned int i; for (i = 0; i < ARRAY_SIZE(g_ble_ll_sync_adv_list); i++) { g_ble_ll_sync_adv_list[i].adv_sid = 0xff; diff --git a/nimble/host/services/ans/src/ble_svc_ans.c b/nimble/host/services/ans/src/ble_svc_ans.c index df1e0764ad..edaf7f3c12 100644 --- a/nimble/host/services/ans/src/ble_svc_ans.c +++ b/nimble/host/services/ans/src/ble_svc_ans.c @@ -457,6 +457,7 @@ ble_svc_ans_init(void) rc = ble_gatts_add_svcs(ble_svc_ans_defs); SYSINIT_PANIC_ASSERT(rc == 0); + (void)rc; ble_svc_ans_new_alert_cat = MYNEWT_VAL(BLE_SVC_ANS_NEW_ALERT_CAT); ble_svc_ans_unr_alert_cat = MYNEWT_VAL(BLE_SVC_ANS_UNR_ALERT_CAT); diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index d2b460ce39..436a55077d 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -137,7 +137,7 @@ static const struct ble_att_rx_dispatch_entry * ble_att_rx_dispatch_entry_find(uint8_t op) { const struct ble_att_rx_dispatch_entry *entry; - int i; + unsigned int i; for (i = 0; i < BLE_ATT_RX_DISPATCH_SZ; i++) { entry = ble_att_rx_dispatch + i; diff --git a/nimble/host/src/ble_hs_hci.c b/nimble/host/src/ble_hs_hci.c index af61b5454b..a3a7d2529e 100644 --- a/nimble/host/src/ble_hs_hci.c +++ b/nimble/host/src/ble_hs_hci.c @@ -143,8 +143,8 @@ ble_hs_hci_rx_cmd_complete(const void *data, int len, const struct ble_hci_ev_command_complete_nop *nop = data; uint16_t opcode; - if (len < sizeof(*ev)) { - if (len < sizeof(*nop)) { + if (len < (int)sizeof(*ev)) { + if (len < (int)sizeof(*nop)) { return BLE_HS_ECONTROLLER; } diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 9437e755cb..1699c645be 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -144,7 +144,7 @@ static const struct ble_hs_hci_evt_dispatch_entry * ble_hs_hci_evt_dispatch_find(uint8_t event_code) { const struct ble_hs_hci_evt_dispatch_entry *entry; - int i; + unsigned int i; for (i = 0; i < BLE_HS_HCI_EVT_DISPATCH_SZ; i++) { entry = ble_hs_hci_evt_dispatch + i; diff --git a/nimble/host/src/ble_hs_hci_util.c b/nimble/host/src/ble_hs_hci_util.c index f9897acaa3..7803252696 100644 --- a/nimble/host/src/ble_hs_hci_util.c +++ b/nimble/host/src/ble_hs_hci_util.c @@ -81,7 +81,7 @@ ble_hs_hci_rand(void *dst, int len) return rc; } - chunk_sz = min(len, sizeof(rsp)); + chunk_sz = min(len, (int)sizeof(rsp)); memcpy(u8ptr, &rsp.random_number, chunk_sz); len -= chunk_sz; diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c index c9d7b61bee..ae5624ce98 100644 --- a/nimble/host/src/ble_l2cap_coc.c +++ b/nimble/host/src/ble_l2cap_coc.c @@ -103,7 +103,7 @@ ble_l2cap_clear_used_cid(uint32_t *cid_mask, int bit) static inline int ble_l2cap_get_first_available_bit(uint32_t *cid_mask) { - int i; + unsigned int i; int bit = 0; for (i = 0; i < BLE_HS_CONN_L2CAP_COC_CID_MASK_LEN; i++) { diff --git a/nimble/host/src/ble_store.c b/nimble/host/src/ble_store.c index 1adab34673..79b2f7b95e 100644 --- a/nimble/host/src/ble_store.c +++ b/nimble/host/src/ble_store.c @@ -394,7 +394,7 @@ ble_store_clear(void) union ble_store_key key; int obj_type; int rc; - int i; + unsigned int i; /* A zeroed key will always retrieve the first value. */ memset(&key, 0, sizeof key); diff --git a/porting/nimble/src/hal_timer.c b/porting/nimble/src/hal_timer.c index aa78bf9a28..e649a9070c 100644 --- a/porting/nimble/src/hal_timer.c +++ b/porting/nimble/src/hal_timer.c @@ -184,7 +184,7 @@ nrf_timer_set_ocmp(struct nrf52_hal_timer *bsptimer, uint32_t expiry) } else { rtctimer->INTENCLR = RTC_INTENCLR_TICK_Msk; - if (delta_t < (1UL << 24)) { + if (delta_t < (1L << 24)) { rtctimer->CC[NRF_RTC_TIMER_CC_INT] = expiry & 0x00ffffff; } else { /* CC too far ahead. Just make sure we set compare far ahead */ From 357f7210ee0640c5c74d351dd51de9d4068a2664 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 4 Apr 2023 14:47:03 +0200 Subject: [PATCH 0680/1333] nimble/ll: Account for host provided Max_CE_length If host provides maximum CE length (when initiating connection or updating its parameters) LL will take it into account when checking if more packages can be send in current event. --- nimble/controller/include/controller/ble_ll_conn.h | 3 +-- nimble/controller/src/ble_ll_conn.c | 14 ++++++++++++-- nimble/controller/src/ble_ll_conn_hci.c | 12 +++++++----- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 1e704ad36c..7ba3c44f8c 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -291,8 +291,7 @@ struct ble_ll_conn_sm /* Connection timing */ uint16_t conn_itvl; uint16_t supervision_tmo; - uint16_t min_ce_len; - uint16_t max_ce_len; + uint32_t max_ce_len_ticks; uint16_t tx_win_off; uint32_t anchor_point; uint8_t anchor_point_usecs; /* XXX: can this be uint8_t ?*/ diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index d1e87204ac..b70a237673 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -942,6 +942,12 @@ ble_ll_conn_get_next_sched_time(struct ble_ll_conn_sm *connsm) ce_end -= ble_ll_tmr_u2t_up(MYNEWT_VAL(BLE_LL_CONN_EVENT_END_MARGIN)); + if (connsm->max_ce_len_ticks) { + if (LL_TMR_LT(connsm->anchor_point + connsm->max_ce_len_ticks, ce_end)) { + ce_end = connsm->anchor_point + connsm->max_ce_len_ticks; + } + } + if (ble_ll_sched_next_time(&next_sched_time)) { if (LL_TMR_LT(next_sched_time, ce_end)) { ce_end = next_sched_time; @@ -1800,8 +1806,7 @@ ble_ll_conn_central_init(struct ble_ll_conn_sm *connsm, connsm->conn_itvl_usecs = cc_params->conn_itvl_usecs; connsm->periph_latency = cc_params->conn_latency; connsm->supervision_tmo = cc_params->supervision_timeout; - connsm->min_ce_len = cc_params->min_ce_len; - connsm->max_ce_len = cc_params->max_ce_len; + connsm->max_ce_len_ticks = ble_ll_tmr_u2t_up(cc_params->max_ce_len * BLE_LL_CONN_CE_USECS); } #endif @@ -2576,6 +2581,11 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) ble_ll_conn_itvl_to_ticks(connsm->conn_itvl, &connsm->conn_itvl_ticks, &connsm->conn_itvl_usecs); + if (connsm->conn_param_req.handle != 0) { + connsm->max_ce_len_ticks = ble_ll_tmr_u2t_up(connsm->conn_param_req.max_ce_len * BLE_LL_CONN_CE_USECS); + connsm->conn_param_req.handle = 0; + } + if (upd->winoffset != 0) { usecs = upd->winoffset * BLE_LL_CONN_ITVL_USECS; ble_ll_tmr_add(&connsm->anchor_point, &connsm->anchor_point_usecs, diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index a14c2f329c..5aea53b87c 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -480,12 +480,14 @@ ble_ll_conn_hci_create_check_params(struct ble_ll_conn_create_params *cc_params) return BLE_ERR_INV_HCI_CMD_PARMS; } - /* Adjust min/max ce length to be less than interval */ - if (cc_params->min_ce_len > cc_params->conn_itvl) { - cc_params->min_ce_len = cc_params->conn_itvl; + /* Adjust min/max ce length to be less than interval + * Note that interval is in 1.25ms and CE is in 625us + */ + if (cc_params->min_ce_len > cc_params->conn_itvl * 2) { + cc_params->min_ce_len = cc_params->conn_itvl * 2; } - if (cc_params->max_ce_len > cc_params->conn_itvl) { - cc_params->max_ce_len = cc_params->conn_itvl; + if (cc_params->max_ce_len > cc_params->conn_itvl * 2) { + cc_params->max_ce_len = cc_params->conn_itvl * 2; } /* Precalculate conn interval */ From edaffa71f37081a8a4517303022fe73aaebde14e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 3 Jan 2023 16:22:47 +0100 Subject: [PATCH 0681/1333] nimble/transport: Move cmac_driver to core repo cmac_driver is moved as ipc_cmac driver to core repository. This is to have drivers stored in one place, as with ipc_nrf5340. --- nimble/drivers/dialog_cmac/src/ble_hw.c | 2 +- nimble/drivers/dialog_cmac/src/ble_phy.c | 8 +- nimble/drivers/dialog_cmac/src/ble_rf.c | 36 +- .../dialog_cmac/cmac_driver/diag/pkg.yml | 28 -- .../cmac_driver/diag/src/cmac_diag.c | 66 --- .../include/cmac_driver/cmac_diag.h | 34 -- .../include/cmac_driver/cmac_host.h | 35 -- .../include/cmac_driver/cmac_shared.h | 194 --------- .../transport/dialog_cmac/cmac_driver/pkg.yml | 39 -- .../cmac_driver/scripts/build_libcmac.sh | 45 --- .../cmac_driver/scripts/create_cmac_bin.sh | 31 -- .../dialog_cmac/cmac_driver/src/cmac_host.c | 375 ------------------ .../dialog_cmac/cmac_driver/src/cmac_mbox.c | 174 -------- .../dialog_cmac/cmac_driver/src/cmac_rand.c | 145 ------- .../dialog_cmac/cmac_driver/src/cmac_shared.c | 96 ----- .../dialog_cmac/cmac_driver/syscfg.yml | 104 ----- nimble/transport/dialog_cmac/pkg.yml | 6 +- nimble/transport/dialog_cmac/src/hci_cmac.c | 15 +- 18 files changed, 33 insertions(+), 1400 deletions(-) delete mode 100644 nimble/transport/dialog_cmac/cmac_driver/diag/pkg.yml delete mode 100644 nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c delete mode 100644 nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_diag.h delete mode 100644 nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_host.h delete mode 100644 nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h delete mode 100644 nimble/transport/dialog_cmac/cmac_driver/pkg.yml delete mode 100755 nimble/transport/dialog_cmac/cmac_driver/scripts/build_libcmac.sh delete mode 100755 nimble/transport/dialog_cmac/cmac_driver/scripts/create_cmac_bin.sh delete mode 100644 nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c delete mode 100644 nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c delete mode 100644 nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c delete mode 100644 nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c delete mode 100644 nimble/transport/dialog_cmac/cmac_driver/syscfg.yml diff --git a/nimble/drivers/dialog_cmac/src/ble_hw.c b/nimble/drivers/dialog_cmac/src/ble_hw.c index a2724b687d..195dcd35dd 100644 --- a/nimble/drivers/dialog_cmac/src/ble_hw.c +++ b/nimble/drivers/dialog_cmac/src/ble_hw.c @@ -23,7 +23,7 @@ #include "nimble/ble.h" #include "controller/ble_hw.h" #include "CMAC.h" -#include "cmac_driver/cmac_shared.h" +#include #include "tinycrypt/aes.h" static struct tc_aes_key_sched_struct g_ctx; diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index a1ba306129..997ce2ab04 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -27,7 +27,7 @@ #include "nimble/ble.h" #include "mcu/mcu.h" #include "mcu/cmac_timer.h" -#include "cmac_driver/cmac_shared.h" +#include #include "controller/ble_phy.h" #include "controller/ble_ll.h" #include "stats/stats.h" @@ -524,7 +524,7 @@ ble_phy_rx_start_isr(void) /* Read the latched RSSI value */ ble_hdr->rxinfo.rssi = ble_rf_get_rssi(); #if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE) - g_cmac_shared_data.debug.last_rx_rssi = ble_hdr->rxinfo.rssi; + g_cmac_shm_debugdata.last_rx_rssi = ble_hdr->rxinfo.rssi; #endif /* Count rx starts */ @@ -1659,8 +1659,8 @@ int ble_phy_tx_power_set(int dbm) { #if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE) - if (g_cmac_shared_data.debug.tx_power_override != INT8_MAX) { - ble_rf_set_tx_power(g_cmac_shared_data.debug.tx_power_override); + if (g_cmac_shm_debugdata.tx_power_ovr_enable) { + ble_rf_set_tx_power(g_cmac_shm_debugdata.tx_power_ovr); } else { ble_rf_set_tx_power(dbm); } diff --git a/nimble/drivers/dialog_cmac/src/ble_rf.c b/nimble/drivers/dialog_cmac/src/ble_rf.c index 806f4ea82d..61f3663eca 100644 --- a/nimble/drivers/dialog_cmac/src/ble_rf.c +++ b/nimble/drivers/dialog_cmac/src/ble_rf.c @@ -23,7 +23,7 @@ #include "mcu/mcu.h" #include "mcu/cmac_timer.h" #include "controller/ble_phy.h" -#include "cmac_driver/cmac_shared.h" +#include #include "ble_rf_priv.h" #define RF_CALIBRATION_0 (0x01) @@ -206,8 +206,7 @@ ble_rf_rfcu_apply_recommended_settings(void) static void ble_rf_rfcu_apply_settings(void) { - ble_rf_apply_trim(g_cmac_shared_data.trim.rfcu, - g_cmac_shared_data.trim.rfcu_len); + ble_rf_apply_trim(g_cmac_shm_trim.rfcu, g_cmac_shm_trim.rfcu_len); ble_rf_rfcu_apply_recommended_settings(); } @@ -242,8 +241,7 @@ ble_rf_synth_apply_recommended_settings(void) static void ble_rf_synth_apply_settings(void) { - ble_rf_apply_trim(g_cmac_shared_data.trim.synth, - g_cmac_shared_data.trim.synth_len); + ble_rf_apply_trim(g_cmac_shm_trim.synth, g_cmac_shm_trim.synth_len); ble_rf_synth_apply_recommended_settings(); } @@ -495,8 +493,8 @@ ble_rf_calibrate_int(uint8_t mask) __enable_irq(); #if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE) - g_cmac_shared_data.debug.cal_res_1 = g_ble_phy_rf_data.cal_res_1; - g_cmac_shared_data.debug.cal_res_2 = g_ble_phy_rf_data.cal_res_2; + g_cmac_shm_debugdata.cal_res_1 = g_ble_phy_rf_data.cal_res_1; + g_cmac_shm_debugdata.cal_res_2 = g_ble_phy_rf_data.cal_res_2; #endif } @@ -545,19 +543,19 @@ ble_rf_init(void) return; } - val = ble_rf_find_trim_reg(g_cmac_shared_data.trim.rfcu_mode1, - g_cmac_shared_data.trim.rfcu_mode1_len, + val = ble_rf_find_trim_reg(g_cmac_shm_trim.rfcu_mode1, + g_cmac_shm_trim.rfcu_mode1_len, 0x4002004c); g_ble_phy_rf_data.trim_val1_tx_1 = val; - val = ble_rf_find_trim_reg(g_cmac_shared_data.trim.rfcu_mode2, - g_cmac_shared_data.trim.rfcu_mode2_len, + val = ble_rf_find_trim_reg(g_cmac_shm_trim.rfcu_mode2, + g_cmac_shm_trim.rfcu_mode2_len, 0x4002004c); g_ble_phy_rf_data.trim_val1_tx_2 = val; if (!g_ble_phy_rf_data.trim_val1_tx_1 || !g_ble_phy_rf_data.trim_val1_tx_2) { - val = ble_rf_find_trim_reg(g_cmac_shared_data.trim.rfcu, - g_cmac_shared_data.trim.rfcu_len, + val = ble_rf_find_trim_reg(g_cmac_shm_trim.rfcu, + g_cmac_shm_trim.rfcu_len, 0x4002004c); if (!val) { val = 0x0300; @@ -566,8 +564,8 @@ ble_rf_init(void) g_ble_phy_rf_data.trim_val1_tx_2 = val; } - val = ble_rf_find_trim_reg(g_cmac_shared_data.trim.synth, - g_cmac_shared_data.trim.synth_len, + val = ble_rf_find_trim_reg(g_cmac_shm_trim.synth, + g_cmac_shm_trim.synth_len, 0x40022038); if (!val) { val = 0x0198ff03; @@ -577,10 +575,10 @@ ble_rf_init(void) set_reg32_bits((uint32_t)&g_ble_phy_rf_data.trim_val2_tx, 0x0001ff00, 0x87); #if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE) - g_cmac_shared_data.debug.trim_val1_tx_1 = g_ble_phy_rf_data.trim_val1_tx_1; - g_cmac_shared_data.debug.trim_val1_tx_2 = g_ble_phy_rf_data.trim_val1_tx_2; - g_cmac_shared_data.debug.trim_val2_tx = g_ble_phy_rf_data.trim_val2_tx; - g_cmac_shared_data.debug.trim_val2_rx = g_ble_phy_rf_data.trim_val2_rx; + g_cmac_shm_debugdata.trim_val1_tx_1 = g_ble_phy_rf_data.trim_val1_tx_1; + g_cmac_shm_debugdata.trim_val1_tx_2 = g_ble_phy_rf_data.trim_val1_tx_2; + g_cmac_shm_debugdata.trim_val2_tx = g_ble_phy_rf_data.trim_val2_tx; + g_cmac_shm_debugdata.trim_val2_rx = g_ble_phy_rf_data.trim_val2_rx; #endif ble_rf_rfcu_enable(); diff --git a/nimble/transport/dialog_cmac/cmac_driver/diag/pkg.yml b/nimble/transport/dialog_cmac/cmac_driver/diag/pkg.yml deleted file mode 100644 index 9b9ee83eb6..0000000000 --- a/nimble/transport/dialog_cmac/cmac_driver/diag/pkg.yml +++ /dev/null @@ -1,28 +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. -# - -pkg.name: nimble/transport/dialog_cmac/cmac_driver/diag -pkg.description: Default diag configuration for CMAC -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - dialog - - da1469x - - cmac -pkg.apis: dialog_cmac_diag diff --git a/nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c b/nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c deleted file mode 100644 index 83299038d4..0000000000 --- a/nimble/transport/dialog_cmac/cmac_driver/diag/src/cmac_diag.c +++ /dev/null @@ -1,66 +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. - */ - -#include "syscfg/syscfg.h" -#include "mcu/mcu.h" - -#if MYNEWT_VAL(BLE_CONTROLLER) -void -cmac_diag_setup_cmac(void) -{ - MCU_DIAG_MAP( 0, 4, DSER); - MCU_DIAG_MAP( 1, 6, CMAC_ON_ERROR); - MCU_DIAG_MAP( 2, 2, PHY_TX_EN); - MCU_DIAG_MAP( 3, 2, PHY_RX_EN); - MCU_DIAG_MAP( 4, 2, PHY_TXRX_DATA_COMB); - MCU_DIAG_MAP( 5, 2, PHY_TXRX_DATA_EN_COMB); - MCU_DIAG_MAP( 6, 5, EV1US_FRAME_START); - MCU_DIAG_MAP( 7, 5, EV_BS_START); - MCU_DIAG_MAP( 8, 5, EV1C_BS_STOP); - MCU_DIAG_MAP( 9, 5, EV1US_PHY_TO_IDLE); - MCU_DIAG_MAP(10, 9, CALLBACK_IRQ); - MCU_DIAG_MAP(11, 9, FIELD_IRQ); - MCU_DIAG_MAP(12, 9, FRAME_IRQ); - MCU_DIAG_MAP(13, 3, SLP_TIMER_ACTIVE); - MCU_DIAG_MAP(14, 4, SLEEPING); - MCU_DIAG_MAP(15, 8, LL_TIMER1_00); -} -#else -void -cmac_diag_setup_host(void) -{ - /* Setup pins for diagnostic signals */ - mcu_gpio_set_pin_function(42, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAG0); /* DIAG_0 @ P1.10 */ - mcu_gpio_set_pin_function(43, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAG1); /* DIAG_1 @ P1.11 */ - mcu_gpio_set_pin_function(44, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAG2); /* DIAG_2 @ P1.12 */ - mcu_gpio_set_pin_function(24, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_3 @ P0.24 */ - mcu_gpio_set_pin_function(21, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_4 @ P0.21 */ - mcu_gpio_set_pin_function(20, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_5 @ P0.20 */ - mcu_gpio_set_pin_function(19, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_6 @ P0.19 */ - mcu_gpio_set_pin_function(18, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_7 @ P0.18 */ - mcu_gpio_set_pin_function(31, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_8 @ P0.31 */ - mcu_gpio_set_pin_function(30, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_9 @ P0.30 */ - mcu_gpio_set_pin_function(29, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_10 @ P0.29 */ - mcu_gpio_set_pin_function(28, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_11 @ P0.28 */ - mcu_gpio_set_pin_function(27, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_12 @ P0.27 */ - mcu_gpio_set_pin_function(26, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_13 @ P0.26 */ - mcu_gpio_set_pin_function(38, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_14 @ P1.06 */ - mcu_gpio_set_pin_function(41, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_15 @ P1.09 */ -} -#endif diff --git a/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_diag.h b/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_diag.h deleted file mode 100644 index dc6ee903d1..0000000000 --- a/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_diag.h +++ /dev/null @@ -1,34 +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 __MCU_CMAC_DIAG_H_ -#define __MCU_CMAC_DIAG_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -void cmac_diag_setup_host(void); -void cmac_diag_setup_cmac(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __MCU_CMAC_DIAG_H_ */ diff --git a/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_host.h b/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_host.h deleted file mode 100644 index 50d8675524..0000000000 --- a/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_host.h +++ /dev/null @@ -1,35 +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 __DA1469X_CMAC_V2_H_ -#define __DA1469X_CMAC_V2_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -void cmac_host_init(void); -void cmac_host_signal2cmac(void); -void cmac_host_rf_calibrate(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __DA1469X_CMAC_V2_H_ */ diff --git a/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h b/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h deleted file mode 100644 index 887af25872..0000000000 --- a/nimble/transport/dialog_cmac/cmac_driver/include/cmac_driver/cmac_shared.h +++ /dev/null @@ -1,194 +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 __MCU_CMAC_SHARED_H_ -#define __MCU_CMAC_SHARED_H_ - -#include -#include "syscfg/syscfg.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define CMAC_SHARED_MAGIC_CMAC (0x4C6C) /* "lL" */ -#define CMAC_SHARED_MAGIC_SYS (0x5368) /* "hS" */ - -#define CMAC_SHARED_F_SYS_LPCLK_AVAILABLE (0x0001) - -/* - * Simple circular buffer for storing random numbers generated by M33 - * Empty: cmr_in = cmr_out = 0; - * Full: cmr_in + 1 = cmr_out - * - * cmr_in: used by the M33 to add random numbers to the circular buffer. - * cmr_out: used by CMAC to retrieve random numbers - * - * NOTE: cmr_in and cmr_out are indices. - */ -#define CMAC_RAND_BUF_ELEMS (16) - -struct cmac_rand { - int cmr_active; - int cmr_in; - int cmr_out; - uint32_t cmr_buf[CMAC_RAND_BUF_ELEMS]; -}; - -struct cmac_mbox { - uint16_t rd_off; - uint16_t wr_off; -}; - -struct cmac_dcdc { - uint8_t enabled; - uint32_t v18; - uint32_t v18p; - uint32_t vdd; - uint32_t v14; - uint32_t ctrl1; -}; - -struct cmac_trim { - uint8_t rfcu_len; - uint8_t rfcu_mode1_len; - uint8_t rfcu_mode2_len; - uint8_t synth_len; - uint32_t rfcu[ MYNEWT_VAL(CMAC_TRIM_SIZE_RFCU) ]; - uint32_t rfcu_mode1[2]; - uint32_t rfcu_mode2[2]; - uint32_t synth[ MYNEWT_VAL(CMAC_TRIM_SIZE_SYNTH) ]; -}; - -#if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE) -struct cmac_debug { - int8_t last_rx_rssi; - int8_t tx_power_override; - - uint32_t cal_res_1; - uint32_t cal_res_2; - uint32_t trim_val1_tx_1; - uint32_t trim_val1_tx_2; - uint32_t trim_val2_tx; - uint32_t trim_val2_rx; -}; -#endif - -#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE) -struct cmac_coredump { - uint32_t lr; - uint32_t pc; - uint32_t assert; - const char *assert_file; - uint32_t assert_line; - - uint32_t CM_STAT_REG; - uint32_t CM_LL_TIMER1_36_10_REG; - uint32_t CM_LL_TIMER1_9_0_REG; - uint32_t CM_ERROR_REG; - uint32_t CM_EXC_STAT_REG; -}; -#endif - -#define CMAC_PENDING_OP_LP_CLK 0x0001 -#define CMAC_PENDING_OP_RF_CAL 0x0002 - -struct cmac_shared_data { - uint16_t magic_cmac; - uint16_t magic_sys; - uint16_t pending_ops; - uint16_t lp_clock_freq; /* LP clock frequency */ - uint32_t xtal32m_settle_us;/* XTAL32M settling time */ - struct cmac_mbox mbox_s2c; /* SYS2CMAC mailbox */ - struct cmac_mbox mbox_c2s; /* CMAC2SYS mailbox */ - struct cmac_dcdc dcdc; /* DCDC settings */ - struct cmac_trim trim; /* Trim data */ - struct cmac_rand rand; /* Random numbers */ -#if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE) - struct cmac_debug debug; /* Extra debug data */ -#endif -#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE) - struct cmac_coredump coredump; -#endif - - uint8_t mbox_s2c_buf[ MYNEWT_VAL(CMAC_MBOX_SIZE_S2C) ]; - uint8_t mbox_c2s_buf[ MYNEWT_VAL(CMAC_MBOX_SIZE_C2S) ]; -}; - -#if MYNEWT_VAL(BLE_CONTROLLER) -extern volatile struct cmac_shared_data g_cmac_shared_data; -#else -extern volatile struct cmac_shared_data *g_cmac_shared_data; -#endif - -/* cmac_mbox */ -typedef int (cmac_mbox_read_cb)(const void *data, uint16_t len); -typedef void (cmac_mbox_write_notif_cb)(void); -void cmac_mbox_set_read_cb(cmac_mbox_read_cb *cb); -void cmac_mbox_set_write_notif_cb(cmac_mbox_write_notif_cb *cb); -int cmac_mbox_has_data(void); -int cmac_mbox_read(void); -int cmac_mbox_write(const void *data, uint16_t len); - -/* cmac_rand */ -typedef void (*cmac_rand_isr_cb_t)(uint8_t rnum); -void cmac_rand_start(void); -void cmac_rand_stop(void); -void cmac_rand_read(void); -void cmac_rand_write(void); -void cmac_rand_chk_fill(void); -int cmac_rand_get_next(void); -int cmac_rand_is_active(void); -int cmac_rand_is_full(void); -void cmac_rand_fill(uint32_t *buf, int num_words); -void cmac_rand_set_isr_cb(cmac_rand_isr_cb_t cb); - -void cmac_shared_init(void); -void cmac_shared_sync(void); - -#if MYNEWT_VAL(BLE_CONTROLLER) -#define CMAC_SHARED_LOCK_VAL 0xc0000000 -#else -#define CMAC_SHARED_LOCK_VAL 0x40000000 -#endif - -static inline void -cmac_shared_lock(void) -{ - volatile uint32_t *bsr_set = (void *)0x50050074; - volatile uint32_t *bsr_stat = (void *)0x5005007c; - - while ((*bsr_stat & 0xc0000000) != CMAC_SHARED_LOCK_VAL) { - *bsr_set = CMAC_SHARED_LOCK_VAL; - } -} - -static inline void -cmac_shared_unlock(void) -{ - volatile uint32_t *bsr_reset = (void *)0x50050078; - - *bsr_reset = CMAC_SHARED_LOCK_VAL; -} - -#ifdef __cplusplus -} -#endif - -#endif /* __MCU_CMAC_SHARED_H_ */ diff --git a/nimble/transport/dialog_cmac/cmac_driver/pkg.yml b/nimble/transport/dialog_cmac/cmac_driver/pkg.yml deleted file mode 100644 index 1fa003abb2..0000000000 --- a/nimble/transport/dialog_cmac/cmac_driver/pkg.yml +++ /dev/null @@ -1,39 +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. -# - -pkg.name: nimble/transport/dialog_cmac/cmac_driver -pkg.description: Driver for Dialog CMAC IPC -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - dialog - - da1469x - - cmac - -pkg.req_apis.CMAC_DEBUG_DIAG_ENABLE: - - dialog_cmac_diag - -pkg.ign_files.BLE_CONTROLLER: - - cmac_host.c - -pkg.post_link_cmds.BLE_CONTROLLER: - scripts/create_cmac_bin.sh: 100 - -pkg.pre_link_cmds.!BLE_CONTROLLER: - scripts/build_libcmac.sh: 100 diff --git a/nimble/transport/dialog_cmac/cmac_driver/scripts/build_libcmac.sh b/nimble/transport/dialog_cmac/cmac_driver/scripts/build_libcmac.sh deleted file mode 100755 index bbc822aa5f..0000000000 --- a/nimble/transport/dialog_cmac/cmac_driver/scripts/build_libcmac.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -# 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. - -NEWT=${MYNEWT_NEWT_PATH} -OBJCOPY=${MYNEWT_OBJCOPY_PATH} -AR=${MYNEWT_AR_PATH} -LIBCMAC_A=${MYNEWT_USER_SRC_DIR}/libcmac.a - -export WORK_DIR=${MYNEWT_USER_WORK_DIR} -export BASENAME_ROM=cmac.rom -export BASENAME_RAM=cmac.ram - -if [ ${MYNEWT_VAL_CMAC_IMAGE_SINGLE} -eq 0 ]; then - # Create empty binary for ROM image (1 byte required for objcopy) - truncate -s 1 ${WORK_DIR}/${BASENAME_ROM}.bin - # Create fixed size RAM image - truncate -s ${MYNEWT_VAL_CMAC_IMAGE_RAM_SIZE} ${WORK_DIR}/${BASENAME_RAM}.bin -else - ${NEWT} build ${MYNEWT_VAL_CMAC_IMAGE_TARGET_NAME} -fi - -cd ${WORK_DIR} - -# Convert both binaries to objects and create archive to link -${OBJCOPY} -I binary -O elf32-littlearm -B armv8-m.main \ - --rename-section .data=.libcmac.rom ${BASENAME_ROM}.bin ${BASENAME_ROM}.o -${OBJCOPY} -I binary -O elf32-littlearm -B armv8-m.main \ - --rename-section .data=.libcmac.ram ${BASENAME_RAM}.bin ${BASENAME_RAM}.o -${AR} -rcs ${LIBCMAC_A} ${BASENAME_ROM}.o ${BASENAME_RAM}.o diff --git a/nimble/transport/dialog_cmac/cmac_driver/scripts/create_cmac_bin.sh b/nimble/transport/dialog_cmac/cmac_driver/scripts/create_cmac_bin.sh deleted file mode 100755 index 954d086048..0000000000 --- a/nimble/transport/dialog_cmac/cmac_driver/scripts/create_cmac_bin.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -# 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. - -OBJCOPY=${MYNEWT_OBJCOPY_PATH} -ELF=${MYNEWT_APP_BIN_DIR}/blehci.elf - -cd ${WORK_DIR} - -# Strip .ram section from ROM image -${OBJCOPY} -R .ram -O binary ${ELF} ${BASENAME_ROM}.bin -# RAM image is the same as binary created by newt -cp ${ELF}.bin ${BASENAME_RAM}.bin - -# Create a copy of ROM image to flash to partition, if required -cp ${BASENAME_ROM}.bin ${ELF}.rom.bin diff --git a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c deleted file mode 100644 index cdb00060ae..0000000000 --- a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_host.c +++ /dev/null @@ -1,375 +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. - */ - -#include -#include -#include -#include -#include "syscfg/syscfg.h" -#include "sysflash/sysflash.h" -#include "os/os.h" -#include "mcu/mcu.h" -#include "mcu/cmsis_nvic.h" -#include "mcu/da1469x_hal.h" -#include "mcu/da1469x_lpclk.h" -#include "mcu/da1469x_clock.h" -#include "mcu/da1469x_trimv.h" -#include "mcu/da1469x_pdc.h" -#include "cmac_driver/cmac_host.h" -#include "cmac_driver/cmac_shared.h" -#include "cmac_driver/cmac_diag.h" -#include "trng/trng.h" -#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE) -#include "console/console.h" -#endif - -/* CMAC data */ -extern char _binary_cmac_rom_bin_start[]; -extern char _binary_cmac_rom_bin_end; -extern char _binary_cmac_ram_bin_start[]; -extern char _binary_cmac_ram_bin_end; - -struct cmac_image_info { - uint32_t magic; - uint32_t size_rom; - uint32_t size_ram; - uint32_t offset_data; - uint32_t offset_shared; -}; - -/* PDC entry for waking up CMAC */ -static int8_t g_cmac_host_pdc_sys2cmac; -/* PDC entry for waking up M33 */ -static int8_t g_cmac_host_pdc_cmac2sys; - -static void cmac_host_rand_fill(struct os_event *ev); -static struct os_event g_cmac_host_rand_ev = { - .ev_cb = cmac_host_rand_fill -}; - -static void cmac_host_rand_chk_fill(void); - -#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, uart) -static void cmac_host_error_w4flush(struct os_event *ev); -static struct os_event g_cmac_host_error_ev = { - .ev_cb = cmac_host_error_w4flush -}; -#endif - -static void -cmac2sys_isr(void) -{ -#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE) - volatile struct cmac_coredump *cd = &g_cmac_shared_data->coredump; - const char *assert_file; -#endif - - os_trace_isr_enter(); - - /* Clear CMAC2SYS interrupt */ - *(volatile uint32_t *)0x40002000 = 2; - - cmac_mbox_read(); - - if (*(volatile uint32_t *)0x40002000 & 0x1c00) { -#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE) - console_blocking_mode(); - console_printf("CMAC error (0x%08lx)\n", *(volatile uint32_t *)0x40002000); - console_printf(" lr:0x%08lx pc:0x%08lx\n", cd->lr, cd->pc); - if (cd->assert) { - console_printf(" assert:0x%08lx\n", cd->assert); - if (cd->assert_file) { - /* Need to translate pointer from M0 code segment to M33 data */ - assert_file = cd->assert_file + MCU_MEM_SYSRAM_START_ADDRESS + - MEMCTRL->CMI_CODE_BASE_REG; - console_printf(" %s:%d\n", - assert_file, (unsigned)cd->assert_line); - } - } - console_printf(" 0x%08lx CM_ERROR_REG\n", cd->CM_ERROR_REG); - console_printf(" 0x%08lx CM_EXC_STAT_REG\n", cd->CM_EXC_STAT_REG); - console_printf(" 0x%08lx CM_LL_TIMER1_36_10_REG\n", cd->CM_LL_TIMER1_36_10_REG); - console_printf(" 0x%08lx CM_LL_TIMER1_9_0_REG\n", cd->CM_LL_TIMER1_9_0_REG); - - /* Spin if debugger is connected to CMAC to avoid resetting it */ - if (cd->CM_STAT_REG & 0x20) { - for (;;); - } -#endif - -#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, uart) - NVIC_DisableIRQ(CMAC2SYS_IRQn); - /* Wait until UART is flushed and then assert */ - cmac_host_error_w4flush(NULL); - return; -#endif - - /* XXX CMAC is in error state, need to recover */ - assert(0); - return; - } - - cmac_host_rand_chk_fill(); - - os_trace_isr_exit(); -} - -static void -cmac_host_rand_fill(struct os_event *ev) -{ - size_t num_bytes; - struct trng_dev *trng; - uint32_t *rnum; - uint32_t rnums[CMAC_RAND_BUF_ELEMS]; - - /* Check if full */ - if (!cmac_rand_is_active() || cmac_rand_is_full()) { - return; - } - - assert(ev->ev_arg != NULL); - - /* Fill buffer with random numbers even though we may not use all of them */ - trng = ev->ev_arg; - rnum = &rnums[0]; - num_bytes = trng_read(trng, rnum, CMAC_RAND_BUF_ELEMS * sizeof(uint32_t)); - - cmac_rand_fill(rnum, num_bytes / 4); - cmac_host_signal2cmac(); -} - -static void -cmac_host_rand_chk_fill(void) -{ - if (cmac_rand_is_active() && !cmac_rand_is_full()) { - os_eventq_put(os_eventq_dflt_get(), &g_cmac_host_rand_ev); - } -} - -#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, uart) -#if MYNEWT_VAL(BLE_TRANSPORT_UART_PORT) < 0 || MYNEWT_VAL(BLE_TRANSPORT_UART_PORT) > 2 -#error Invalid BLE_HCI_UART_PORT -#endif -static void -cmac_host_error_w4flush(struct os_event *ev) -{ - static UART_Type * const regs[] = { - (void *)UART, - (void *)UART2, - (void *)UART3 - }; - - if (!ev) { - /* Move to task context, we do not want to spin in interrupt */ - os_eventq_put(os_eventq_dflt_get(), &g_cmac_host_error_ev); - return; - } - - do { - cmac_mbox_read(); - while ((regs[MYNEWT_VAL(BLE_TRANSPORT_UART_PORT)]->UART_LSR_REG & - UART_UART_LSR_REG_UART_TEMT_Msk) == 0) { - /* Wait until both FIFO and shift registers are empty */ - } - } while (cmac_mbox_has_data()); - - /* Reset CMAC */ - CRG_TOP->CLK_RADIO_REG |= CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Msk; - - assert(0); -} -#endif - -void -cmac_host_signal2cmac(void) -{ - da1469x_pdc_set(g_cmac_host_pdc_sys2cmac); -} - -static void -cmac_host_lpclk_cb(uint32_t freq) -{ - /* No need to wakeup CMAC if LP clock frequency did not change */ - if (g_cmac_shared_data->lp_clock_freq == freq) { - return; - } - - cmac_shared_lock(); - g_cmac_shared_data->lp_clock_freq = freq; - g_cmac_shared_data->pending_ops |= CMAC_PENDING_OP_LP_CLK; - cmac_shared_unlock(); - - cmac_host_signal2cmac(); -} - -#if MYNEWT_VAL(CMAC_DEBUG_HOST_PRINT_ENABLE) -static void -cmac_host_print_trim(const char *name, const uint32_t *tv, unsigned len) -{ - console_printf("[CMAC] Trim values for '%s'\n", name); - - while (len) { - console_printf(" 0x%08x = 0x%08x\n", (unsigned)tv[0], (unsigned)tv[1]); - len -= 2; - tv += 2; - } -} -#endif - -void -cmac_host_rf_calibrate(void) -{ - cmac_shared_lock(); - g_cmac_shared_data->pending_ops |= CMAC_PENDING_OP_RF_CAL; - cmac_shared_unlock(); - - cmac_host_signal2cmac(); -} - -void -cmac_host_init(void) -{ - struct trng_dev *trng; - struct cmac_image_info ii; - uint32_t cmac_rom_size; - uint32_t cmac_ram_size; -#if !MYNEWT_VAL(CMAC_IMAGE_SINGLE) - const struct flash_area *fa; - int rc; -#endif - struct cmac_trim *trim; - - /* Get trng os device */ - trng = (struct trng_dev *) os_dev_open("trng", OS_TIMEOUT_NEVER, NULL); - assert(trng); - g_cmac_host_rand_ev.ev_arg = trng; - -#if MYNEWT_VAL(CMAC_DEBUG_DIAG_ENABLE) - cmac_diag_setup_host(); -#endif - -#if MYNEWT_VAL(CMAC_DEBUG_SWD_ENABLE) - /* Enable CMAC debugger */ - CRG_TOP->SYS_CTRL_REG |= 0x40; /* CRG_TOP_SYS_CTRL_REG_CMAC_DEBUGGER_ENABLE_Msk */ -#endif - - /* - * Add PDC entry to wake up CMAC from M33 - * - * XXX if MCU_DEBUG_GPIO_DEEP_SLEEP is enabled on CMAC, this should also - * enable PD_COM so CMAC can access GPIOs after wake up - */ - g_cmac_host_pdc_sys2cmac = da1469x_pdc_add(MCU_PDC_TRIGGER_MAC_TIMER, - MCU_PDC_MASTER_CMAC, - MCU_PDC_EN_XTAL); - da1469x_pdc_set(g_cmac_host_pdc_sys2cmac); - da1469x_pdc_ack(g_cmac_host_pdc_sys2cmac); - - /* Add PDC entry to wake up M33 from CMAC, if does not exist yet */ - g_cmac_host_pdc_cmac2sys = da1469x_pdc_find(MCU_PDC_TRIGGER_COMBO, - MCU_PDC_MASTER_M33, 0); - if (g_cmac_host_pdc_cmac2sys < 0) { - g_cmac_host_pdc_cmac2sys = da1469x_pdc_add(MCU_PDC_TRIGGER_COMBO, - MCU_PDC_MASTER_M33, - MCU_PDC_EN_XTAL); - da1469x_pdc_set(g_cmac_host_pdc_cmac2sys); - da1469x_pdc_ack(g_cmac_host_pdc_cmac2sys); - } - - /* Setup CMAC2SYS interrupt */ - NVIC_SetVector(CMAC2SYS_IRQn, (uint32_t)cmac2sys_isr); - NVIC_SetPriority(CMAC2SYS_IRQn, MYNEWT_VAL(CMAC_CMAC2SYS_IRQ_PRIORITY)); - NVIC_DisableIRQ(CMAC2SYS_IRQn); - - /* Enable Radio LDO */ - CRG_TOP->POWER_CTRL_REG |= CRG_TOP_POWER_CTRL_REG_LDO_RADIO_ENABLE_Msk; - - /* Enable CMAC, but keep it in reset */ - CRG_TOP->CLK_RADIO_REG = (1 << CRG_TOP_CLK_RADIO_REG_RFCU_ENABLE_Pos) | - (1 << CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Pos) | - (0 << CRG_TOP_CLK_RADIO_REG_CMAC_CLK_SEL_Pos) | - (1 << CRG_TOP_CLK_RADIO_REG_CMAC_CLK_ENABLE_Pos) | - (0 << CRG_TOP_CLK_RADIO_REG_CMAC_DIV_Pos); - - /* Calculate size of ROM and RAM area */ - cmac_rom_size = &_binary_cmac_rom_bin_end - &_binary_cmac_rom_bin_start[0]; - cmac_ram_size = &_binary_cmac_ram_bin_end - &_binary_cmac_ram_bin_start[0]; - - /* Load image header and check if image can be loaded */ -#if MYNEWT_VAL(CMAC_IMAGE_SINGLE) - memcpy(&ii, &_binary_cmac_rom_bin_start[128], sizeof(ii)); -#else - rc = flash_area_open(FLASH_AREA_IMAGE_1, &fa); - assert(rc == 0); - rc = flash_area_read(fa, 128, &ii, sizeof(ii)); - assert(rc == 0); -#endif - - assert(ii.magic == 0xC3ACC3AC); - assert(ii.size_rom == cmac_rom_size); - assert(ii.size_ram <= cmac_ram_size); - - /* Copy CMAC image to RAM */ -#if MYNEWT_VAL(CMAC_IMAGE_SINGLE) - memset(&_binary_cmac_ram_bin_start, 0xaa, cmac_ram_size); - memcpy(&_binary_cmac_ram_bin_start, &_binary_cmac_rom_bin_start, ii.size_rom); -#else - memset(&_binary_cmac_ram_bin_start, 0xaa, cmac_ram_size); - rc = flash_area_read(fa, 0, &_binary_cmac_ram_bin_start, ii.size_rom); - assert(rc == 0); -#endif - - /* Setup CMAC memory addresses */ - MEMCTRL->CMI_CODE_BASE_REG = (uint32_t)&_binary_cmac_ram_bin_start; - MEMCTRL->CMI_DATA_BASE_REG = MEMCTRL->CMI_CODE_BASE_REG + ii.offset_data; - MEMCTRL->CMI_SHARED_BASE_REG = MEMCTRL->CMI_CODE_BASE_REG + ii.offset_shared; - MEMCTRL->CMI_END_REG = MEMCTRL->CMI_CODE_BASE_REG + ii.size_ram - 1; - - /* Initialize shared memory */ - cmac_shared_init(); - - trim = (struct cmac_trim *)&g_cmac_shared_data->trim; - trim->rfcu_len = da1469x_trimv_group_read(6, trim->rfcu, ARRAY_SIZE(trim->rfcu)); - trim->rfcu_mode1_len = da1469x_trimv_group_read(8, trim->rfcu_mode1, ARRAY_SIZE(trim->rfcu_mode1)); - trim->rfcu_mode2_len = da1469x_trimv_group_read(10, trim->rfcu_mode2, ARRAY_SIZE(trim->rfcu_mode2)); - trim->synth_len = da1469x_trimv_group_read(7, trim->synth, ARRAY_SIZE(trim->synth)); - -#if MYNEWT_VAL(CMAC_DEBUG_HOST_PRINT_ENABLE) - cmac_host_print_trim("rfcu", trim->rfcu, trim->rfcu_len); - cmac_host_print_trim("rfcu_mode1", trim->rfcu_mode1, trim->rfcu_mode1_len); - cmac_host_print_trim("rfcu_mode2", trim->rfcu_mode2, trim->rfcu_mode2_len); - cmac_host_print_trim("synth", trim->synth, trim->synth_len); -#endif - - /* Release CMAC from reset and sync */ - CRG_TOP->CLK_RADIO_REG &= ~CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Msk; - cmac_shared_sync(); - - da1469x_lpclk_register_cmac_cb(cmac_host_lpclk_cb); - -#if MYNEWT_VAL(CMAC_DEBUG_HOST_PRINT_ENABLE) && MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE) - /* Trim values are calculated on RF init, so are valid after synced with CMAC */ - console_printf("[CMAC] Calculated trim_val1: 1=0x%08x 2=0x%08x\n", - (unsigned)g_cmac_shared_data->debug.trim_val1_tx_1, - (unsigned)g_cmac_shared_data->debug.trim_val1_tx_2); - console_printf("[CMAC] Calculated trim_val2: tx=0x%08x rx=0x%08x\n", - (unsigned)g_cmac_shared_data->debug.trim_val2_tx, - (unsigned)g_cmac_shared_data->debug.trim_val2_rx); -#endif -} diff --git a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c deleted file mode 100644 index d2ee9ac9b2..0000000000 --- a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_mbox.c +++ /dev/null @@ -1,174 +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. - */ - -#include -#include -#include -#include -#include -#include "syscfg/syscfg.h" -#include "mcu/mcu.h" -#include "os/os_arch.h" -#include "os/os.h" - -#ifndef min -#define min(_a, _b) ((_a) < (_b) ? (_a) : (_b)) -#endif - -static cmac_mbox_read_cb *g_cmac_mbox_read_cb; -static cmac_mbox_write_notif_cb *g_cmac_mbox_write_notif_cb; - -void -cmac_mbox_set_read_cb(cmac_mbox_read_cb *cb) -{ - g_cmac_mbox_read_cb = cb; -} - -void -cmac_mbox_set_write_notif_cb(cmac_mbox_write_notif_cb *cb) -{ - g_cmac_mbox_write_notif_cb = cb; -} - -int -cmac_mbox_has_data(void) -{ -#if MYNEWT_VAL(BLE_CONTROLLER) - volatile struct cmac_mbox *mbox = &g_cmac_shared_data.mbox_s2c; -#else - volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_c2s; -#endif - - return mbox->rd_off != mbox->wr_off; -} - -int -cmac_mbox_read(void) -{ -#if MYNEWT_VAL(BLE_CONTROLLER) - volatile struct cmac_mbox *mbox = &g_cmac_shared_data.mbox_s2c; - uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data.mbox_s2c_buf; - const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_S2C); -#else - volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_c2s; - uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data->mbox_c2s_buf; - const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_C2S); -#endif - uint16_t rd_off; - uint16_t wr_off; - uint16_t chunk; - int len = 0; - - if (!g_cmac_mbox_read_cb) { - return 0; - } - - do { - rd_off = mbox->rd_off; - wr_off = mbox->wr_off; - - if (rd_off <= wr_off) { - chunk = wr_off - rd_off; - } else { - chunk = mbox_size - rd_off; - } - - while (chunk) { - len = g_cmac_mbox_read_cb(&mbox_buf[rd_off], chunk); - if (len < 0) { - break; - } - - rd_off += len; - chunk -= len; - } - - mbox->rd_off = rd_off == mbox_size ? 0 : rd_off; - } while ((mbox->rd_off != mbox->wr_off) && (len >= 0)); - - return 0; -} - -int -cmac_mbox_write(const void *data, uint16_t len) -{ -#if MYNEWT_VAL(BLE_CONTROLLER) - volatile struct cmac_mbox *mbox = &g_cmac_shared_data.mbox_c2s; - uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data.mbox_c2s_buf; - const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_C2S); -#else - volatile struct cmac_mbox *mbox = &g_cmac_shared_data->mbox_s2c; - uint8_t *mbox_buf = (uint8_t *)&g_cmac_shared_data->mbox_s2c_buf; - const uint16_t mbox_size = MYNEWT_VAL(CMAC_MBOX_SIZE_S2C); -#endif - uint16_t rd_off; - uint16_t wr_off; - uint16_t max_wr; - uint16_t chunk; - - while (len) { - rd_off = mbox->rd_off; - wr_off = mbox->wr_off; - - /* - * Calculate maximum length to write, i.e. up to end of buffer or stop - * before rd_off to be able to detect full queue. - */ - if (rd_off > wr_off) { - /* - * |0|1|2|3|4|5|6|7| - * | | | |W| | |R| | - * `---^ - */ - max_wr = rd_off - wr_off - 1; - } else if (rd_off == 0) { - /* - * |0|1|2|3|4|5|6|7| - * |R| | |W| | | | | - * `-------^ - */ - max_wr = mbox_size - wr_off - 1; - } else { - /* - * |0|1|2|3|4|5|6|7| - * | |R| |W| | | | | - * `---------^ - */ - max_wr = mbox_size - wr_off; - } - - chunk = min(len, max_wr); - - if (chunk == 0) { - continue; - } - - memcpy(&mbox_buf[wr_off], data, chunk); - - wr_off += chunk; - mbox->wr_off = wr_off == mbox_size ? 0 : wr_off; - - g_cmac_mbox_write_notif_cb(); - - len -= chunk; - data = (uint8_t *)data + chunk; - } - - return 0; -} diff --git a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c deleted file mode 100644 index dbb93e9254..0000000000 --- a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_rand.c +++ /dev/null @@ -1,145 +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. - */ - -#include -#include -#include -#include -#include "syscfg/syscfg.h" -#include "mcu/mcu.h" -#include "os/os_arch.h" -#include "os/os.h" - -#if !MYNEWT_VAL(BLE_CONTROLLER) -int -cmac_rand_is_active(void) -{ - return g_cmac_shared_data->rand.cmr_active; -} - -int -cmac_rand_is_full(void) -{ - int next; - bool rc; - - next = cmac_rand_get_next(); - if (next == g_cmac_shared_data->rand.cmr_out) { - rc = 1; - } else { - rc = 0; - } - return rc; -} - -int -cmac_rand_get_next(void) -{ - int next; - - /* If active and not full, put event on queue to get random numbers */ - next = g_cmac_shared_data->rand.cmr_in + 1; - if (next == CMAC_RAND_BUF_ELEMS) { - next = 0; - } - return next; -} - -void -cmac_rand_fill(uint32_t *buf, int num_words) -{ - int next; - - /* XXX: if words is 0, is it possible we could get into a state - where we are waiting for random numbers but M33 does not know it - has to fill any? */ - - /* NOTE: we already know the buffer is not full first time through */ - next = g_cmac_shared_data->rand.cmr_in; - while (num_words) { - g_cmac_shared_data->rand.cmr_buf[next] = buf[0]; - next = cmac_rand_get_next(); - g_cmac_shared_data->rand.cmr_in = next; - next = cmac_rand_get_next(); - if (next == g_cmac_shared_data->rand.cmr_out) { - break; - } - --num_words; - ++buf; - } -} -#endif - -#if MYNEWT_VAL(BLE_CONTROLLER) -static cmac_rand_isr_cb_t g_cmac_rand_isr_cb; - -void -cmac_rand_set_isr_cb(cmac_rand_isr_cb_t cb) -{ - g_cmac_rand_isr_cb = cb; -} - -void -cmac_rand_start(void) -{ - g_cmac_shared_data.rand.cmr_active = 1; -} - -void -cmac_rand_stop(void) -{ - g_cmac_shared_data.rand.cmr_active = 0; -} - -/** - * cmac rnum read - * - * Called during the system to cmac isr to take random numbers - * from shared memory into the BLE stack. - */ -void -cmac_rand_read(void) -{ - uint8_t bytes_left; - uint32_t rnum; - - /* Just leave if no callback. */ - if (g_cmac_rand_isr_cb == NULL) { - return; - } - - bytes_left = 0; - while (g_cmac_shared_data.rand.cmr_active) { - if (bytes_left) { - --bytes_left; - rnum >>= 8; - } else if (g_cmac_shared_data.rand.cmr_out != g_cmac_shared_data.rand.cmr_in) { - bytes_left = 3; - rnum = g_cmac_shared_data.rand.cmr_buf[g_cmac_shared_data.rand.cmr_out]; - ++g_cmac_shared_data.rand.cmr_out; - if (g_cmac_shared_data.rand.cmr_out == CMAC_RAND_BUF_ELEMS) { - g_cmac_shared_data.rand.cmr_out = 0; - } - } else { - break; - } - (*g_cmac_rand_isr_cb)((uint8_t)rnum); - } -} -#endif diff --git a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c b/nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c deleted file mode 100644 index cd7984afa8..0000000000 --- a/nimble/transport/dialog_cmac/cmac_driver/src/cmac_shared.c +++ /dev/null @@ -1,96 +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. - */ - -#include "syscfg/syscfg.h" -#if MYNEWT_VAL(BLE_CONTROLLER) && !MYNEWT_VAL(MCU_DEBUG_DSER_CMAC_SHARED) -#define MCU_DIAG_SER_DISABLE -#endif - -#include -#include -#include -#include "mcu/mcu.h" -#include -#include "os/os_arch.h" -#include "os/os.h" - -#ifndef min -#define min(_a, _b) ((_a) < (_b) ? (_a) : (_b)) -#endif - -#if MYNEWT_VAL(BLE_CONTROLLER) -volatile struct cmac_shared_data g_cmac_shared_data __attribute__((section(".shdata"))); -#else -volatile struct cmac_shared_data *g_cmac_shared_data; -#include "mcu/da1469x_clock.h" -#define MCU_DIAG_SER(_x) -#endif - -void -cmac_shared_init(void) -{ -#if !MYNEWT_VAL(BLE_CONTROLLER) - g_cmac_shared_data = (void *)(MCU_MEM_SYSRAM_START_ADDRESS + - MEMCTRL->CMI_SHARED_BASE_REG); - - memset((void *)g_cmac_shared_data, 0, sizeof(*g_cmac_shared_data)); - - g_cmac_shared_data->xtal32m_settle_us = MYNEWT_VAL(MCU_CLOCK_XTAL32M_SETTLE_TIME_US); - - g_cmac_shared_data->dcdc.enabled = DCDC->DCDC_CTRL1_REG & DCDC_DCDC_CTRL1_REG_DCDC_ENABLE_Msk; - if (g_cmac_shared_data->dcdc.enabled) { - g_cmac_shared_data->dcdc.v18 = DCDC->DCDC_V18_REG; - g_cmac_shared_data->dcdc.v18p = DCDC->DCDC_V18P_REG; - g_cmac_shared_data->dcdc.vdd = DCDC->DCDC_VDD_REG; - g_cmac_shared_data->dcdc.v14 = DCDC->DCDC_V14_REG; - g_cmac_shared_data->dcdc.ctrl1 = DCDC->DCDC_CTRL1_REG; - } - -#if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE) - g_cmac_shared_data->debug.tx_power_override = INT8_MAX; -#endif -#endif -} - - -void -cmac_shared_sync(void) -{ - /* - * We need to guarantee proper order of initialization here, i.e. SYS has - * to wait until CMAC finished initialization as otherwise host may start - * sending HCI packets which will timeout as there is no one to read them. - */ -#if MYNEWT_VAL(BLE_CONTROLLER) - assert(g_cmac_shared_data.magic_cmac == 0); - - g_cmac_shared_data.magic_cmac = CMAC_SHARED_MAGIC_CMAC; - while (g_cmac_shared_data.magic_sys != CMAC_SHARED_MAGIC_SYS); - - NVIC_SetPriority(SYS2CMAC_IRQn, 3); - NVIC_EnableIRQ(SYS2CMAC_IRQn); -#else - assert(g_cmac_shared_data->magic_sys == 0); - - while (g_cmac_shared_data->magic_cmac != CMAC_SHARED_MAGIC_CMAC); - g_cmac_shared_data->magic_sys = CMAC_SHARED_MAGIC_SYS; - - NVIC_EnableIRQ(CMAC2SYS_IRQn); -#endif -} diff --git a/nimble/transport/dialog_cmac/cmac_driver/syscfg.yml b/nimble/transport/dialog_cmac/cmac_driver/syscfg.yml deleted file mode 100644 index 6ff3b4408b..0000000000 --- a/nimble/transport/dialog_cmac/cmac_driver/syscfg.yml +++ /dev/null @@ -1,104 +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. -# - -syscfg.defs: - CMAC_MBOX_SIZE_S2C: - description: > - Size of mailbox for SYS to CMAC data. The size - value should be power of 2 to allow for better - code optimization. - value: 128 - CMAC_MBOX_SIZE_C2S: - description: > - Size of mailbox for CMAC to SYS data. The size - value should be power of 2 to allow for better - code optimization. - value: 128 - - CMAC_TRIM_SIZE_RFCU: - description: > - Size of trim values for RFCU. This is maximum - number of trim values that can be read from - OTP and applied, all excessive values will be - discarded. - value: 10 - CMAC_TRIM_SIZE_SYNTH: - description: > - Size of trim values for RFCU. This is maximum - number of trim values that can be read from - OTP and applied, all excessive values will be - discarded. - value: 10 - - CMAC_DEBUG_SWD_ENABLE: - description: > - Enable CMAC SWD interface. - value: 0 - CMAC_DEBUG_DIAG_ENABLE: - description: > - Enable CMAC diagnostic lines. - value: 0 - CMAC_DEBUG_DATA_ENABLE: - description: > - Enable extra debugging data in shared segment. - value: 0 - CMAC_DEBUG_COREDUMP_ENABLE: - description: > - Enable dumping CMAC registers to shared segment - on fault. - value: 1 - CMAC_DEBUG_HOST_PRINT_ENABLE: - description: > - Enable some debug printouts to console from host side. - This will dump some settings during startup, useful to - check what is loaded to CMAC via shared data. - value: 0 - - CMAC_IMAGE_SINGLE: - description: > - When enable, CMAC binary is linked with application image - creating a single image build. See CMAC_IMAGE_TARGET_NAME. - When disabled, CMAC binary is built and flashed separately - to flash partition. See CMAC_IMAGE_PARTITION. - value: 1 - CMAC_IMAGE_TARGET_NAME: - description: > - Target name to build for CMAC binary for single image build. - value: "@apache-mynewt-nimble/targets/dialog_cmac" - CMAC_IMAGE_PARTITION: - description: > - Flash partition to load CMAC binary from if single image build - is disabled. - value: FLASH_AREA_IMAGE_1 - CMAC_IMAGE_RAM_SIZE: - description: > - Size of RAM area in bytes reserved for CMAC if single image - build is disabled. Unit suffix (K, M) is allowed. - Note: for single image build this setting is not applicable - since proper RAM area size is automatically calculated from - CMAC binary. - value: 128K - - CMAC_CMAC2SYS_IRQ_PRIORITY: - description: > - The priority of the CMAC2SYS IRQ. Default is 0, or highest - priority. - value: 0 - -syscfg.restrictions.!BLE_CONTROLLER: - - TRNG diff --git a/nimble/transport/dialog_cmac/pkg.yml b/nimble/transport/dialog_cmac/pkg.yml index 2c02d7e7ca..40de98fe99 100644 --- a/nimble/transport/dialog_cmac/pkg.yml +++ b/nimble/transport/dialog_cmac/pkg.yml @@ -18,16 +18,16 @@ # pkg.name: nimble/transport/dialog_cmac -pkg.description: HCI H4 transport for Dialog CMAC +pkg.description: IPC transport for Dialog CMAC pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" +pkg.homepage: "https://mynewt.apache.org/" pkg.keywords: - ble - bluetooth pkg.deps: - nimble/transport/common/hci_h4 - - nimble/transport/dialog_cmac/cmac_driver + - "@apache-mynewt-core/hw/drivers/ipc_cmac" pkg.apis: - ble_transport diff --git a/nimble/transport/dialog_cmac/src/hci_cmac.c b/nimble/transport/dialog_cmac/src/hci_cmac.c index e0702a03b0..164be6680c 100644 --- a/nimble/transport/dialog_cmac/src/hci_cmac.c +++ b/nimble/transport/dialog_cmac/src/hci_cmac.c @@ -24,9 +24,10 @@ /* to enable dser diag */ #include #endif /* BLE_CONTROLLER */ -#include +#include +#include #if !MYNEWT_VAL(BLE_CONTROLLER) -#include +#include #endif /* !BLE_CONTROLLER */ #include #include @@ -99,8 +100,8 @@ ble_transport_ll_init(void) hci_h4_sm_init(&hci_cmac_h4sm, &hci_h4_allocs_from_ll, hci_cmac_hs_frame_cb); /* We can now handle data from CMAC, initialize it */ - cmac_mbox_set_read_cb(hci_cmac_hs_mbox_read_cb); - cmac_mbox_set_write_notif_cb(hci_cmac_hs_mbox_write_notif_cb); + cmac_mbox_cb_set(hci_cmac_hs_mbox_read_cb, + hci_cmac_hs_mbox_write_notif_cb); cmac_host_init(); } #endif /* !BLE_CONTROLLER */ @@ -155,11 +156,11 @@ ble_transport_hs_init(void) hci_h4_sm_init(&hci_cmac_h4sm, &hci_h4_allocs_from_hs, hci_cmac_ll_frame_cb); /* Setup callbacks for mailboxes */ - cmac_mbox_set_read_cb(hci_cmac_ll_mbox_read_cb); - cmac_mbox_set_write_notif_cb(hci_cmac_ll_mbox_write_notif_cb); + cmac_mbox_cb_set(hci_cmac_ll_mbox_read_cb, + hci_cmac_ll_mbox_write_notif_cb); /* Synchronize with SYS */ - cmac_shared_sync(); + cmac_shm_ll_ready(); } #endif From d44e2fc71960f6fc15d3cc962c597808c03653cd Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 17 Apr 2023 15:49:42 +0200 Subject: [PATCH 0682/1333] targets: Enable "all" features on sample CMAC target --- targets/dialog_cmac/syscfg.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/targets/dialog_cmac/syscfg.yml b/targets/dialog_cmac/syscfg.yml index 71a109a286..f73d4e01ba 100644 --- a/targets/dialog_cmac/syscfg.yml +++ b/targets/dialog_cmac/syscfg.yml @@ -21,10 +21,18 @@ syscfg.vals: MCU_DEEP_SLEEP: 1 MCU_SLP_TIMER: 1 MCU_SLP_TIMER_32K_ONLY: 1 + MCU_DEBUG_HCI_EVENT_ON_FAULT: 1 + MCU_DEBUG_HCI_EVENT_ON_ASSERT: 1 + MSYS_1_BLOCK_SIZE: 308 BLE_TRANSPORT_HS: dialog_cmac + BLE_TRANSPORT_ACL_COUNT: 16 + BLE_TRANSPORT_ACL_SIZE: 255 + BLE_TRANSPORT_EVT_COUNT: 4 + BLE_TRANSPORT_EVT_DISCARDABLE_COUNT: 16 # LL recommended settings (decreasing timing values is not recommended) + BLE_LL_STACK_SIZE: 200 BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL: 1 BLE_LL_CONN_INIT_MIN_WIN_OFFSET: 2 BLE_LL_RFMGMT_ENABLE_TIME: 20 @@ -33,3 +41,22 @@ syscfg.vals: # NOTE: set public address in target settings # BLE_LL_PUBLIC_DEV_ADDR: 0xffffffffffff + + # LL features + BLE_VERSION: 53 + BLE_EXT_ADV: 1 + BLE_EXT_ADV_MAX_SIZE: 1650 + BLE_PERIODIC_ADV: 1 + BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 + BLE_MULTI_ADV_INSTANCES: 4 + BLE_MAX_PERIODIC_SYNCS: 4 + BLE_MAX_CONNECTIONS: 4 + BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_LL_CFG_FEAT_LE_CODED_PHY: 0 + BLE_LL_CFG_FEAT_LL_PRIVACY: 1 + BLE_LL_CFG_FEAT_LL_SCA_UPDATE: 1 + BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE: 1 + BLE_LL_CONN_INIT_SLOTS: 1 + BLE_LL_SCAN_AUX_SEGMENT_CNT: 16 + BLE_LL_NUM_SCAN_DUP_ADVS: 64 From 2fb2440f4922e734697242c7fd0aa5f1de690478 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Fri, 5 May 2023 12:04:11 +0530 Subject: [PATCH 0683/1333] nimble/host: Fix compilation issues observed by enabling -O2 optimization --- nimble/host/src/ble_gattc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index 4763f14ef2..63d967b490 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -1956,7 +1956,7 @@ static int ble_gattc_find_inc_svcs_rx_adata(struct ble_gattc_proc *proc, struct ble_att_read_type_adata *adata) { - struct ble_gatt_svc service; + struct ble_gatt_svc service = {0}; int call_cb; int cbrc; int rc; From 2e737706bad691306e3f28ad85c58d2c46856fe4 Mon Sep 17 00:00:00 2001 From: Yoan Picchi Date: Wed, 3 May 2023 09:52:36 +0100 Subject: [PATCH 0684/1333] doc: Add a new external NimBLE port to README NimBLE have been ported to work on the Open IOT SDK, which support freeRTOS, RTX and ThreadX --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 952a35caac..fe75773da0 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ Several other projects provide support for using NimBLE either by [NPL port](htt * [The Espressif ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/nimble/index.html) contains a NimBLE port for ESP-32 devices. * [The RIOT](https://doc.riot-os.org/group__pkg__nimble.html) operating system contains a package for using NimBLE. + * [The Open IOT SDK](https://gitlab.arm.com/iot/open-iot-sdk/sdk) contains a NimBLE [port](https://gitlab.arm.com/iot/open-iot-sdk/sdk/-/tree/main/components/bluetooth) based on [CMSIS RTOSv2](https://www.keil.com/pack/doc/CMSIS/RTOS2/html/index.html), which is an RTOS interface implemented by either Amazon Freertos, CMSIS RTX or Azure ThreadX. If you publish a NimBLE port, please let us know to include it here! From c514f5b574e425e34448f7843f7cd81dce49343a Mon Sep 17 00:00:00 2001 From: ikaracha Date: Thu, 4 May 2023 13:10:51 +0300 Subject: [PATCH 0685/1333] nimble/phy/cmac: Apply preferred RF setting per silicon variant (TSMC and GF). --- nimble/drivers/dialog_cmac/src/ble_rf.c | 35 ++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/nimble/drivers/dialog_cmac/src/ble_rf.c b/nimble/drivers/dialog_cmac/src/ble_rf.c index 61f3663eca..32ae0634e2 100644 --- a/nimble/drivers/dialog_cmac/src/ble_rf.c +++ b/nimble/drivers/dialog_cmac/src/ble_rf.c @@ -30,6 +30,14 @@ #define RF_CALIBRATION_1 (0x02) #define RF_CALIBRATION_2 (0x04) +enum chip_variant { + CHIP_VARIANT_TSMC, + CHIP_VARIANT_GF, + CHIP_VARIANT_UNKNOWN +}; + +static int g_chip_variant; + static const int8_t g_ble_rf_power_lvls[] = { -18, -12, -8, -6, -3, -2, -1, 0, 1, 2, 3, 4, 4, 5, 6 }; @@ -114,6 +122,21 @@ set_reg16_mask(uint32_t addr, uint16_t mask, uint16_t val) *reg = (*reg & (~mask)) | (val & mask); } +static inline int +read_chip_variant(void) +{ + uint32_t chip_id1 = get_reg32_bits(0x50040200, 0xFF); + + switch (chip_id1) { + case '2': + return CHIP_VARIANT_TSMC; + case '3': + return CHIP_VARIANT_GF; + default: + return CHIP_VARIANT_UNKNOWN; + } +} + static void delay_us(uint32_t delay_us) { @@ -233,6 +256,9 @@ ble_rf_synth_is_enabled(void) static void ble_rf_synth_apply_recommended_settings(void) { + if (g_chip_variant == CHIP_VARIANT_GF) { + set_reg32_mask(0x40022034, 0x00000018, 0x0215807B); + } set_reg32_mask(0x40022048, 0x0000000c, 0x000000d5); set_reg32_mask(0x40022050, 0x00000300, 0x00000300); set_reg16_mask(0x40022024, 0x0001, 0x0001); @@ -335,7 +361,11 @@ ble_rf_calibration_1(void) set_reg32(0x40020000, 0x0f168820); set_reg32_bits(0x40022000, 0x00000001, 0); set_reg32_bits(0x4002101c, 0x00001e00, 0); - set_reg32_bits(0x4002001c, 0x0000003f, 47); + if (g_chip_variant == CHIP_VARIANT_TSMC) { + set_reg32_bits(0x4002001c, 0x0000003f, 47); + } else { + set_reg32_bits(0x4002001c, 0x0000003f, 44); + } set_reg8(0x40020006, 1); set_reg32(0x40020020, 16); set_reg32_bits(0x4002003c, 0x00000800, 1); @@ -537,6 +567,9 @@ ble_rf_init(void) static bool done = false; uint32_t val; + g_chip_variant = read_chip_variant(); + assert(g_chip_variant != CHIP_VARIANT_UNKNOWN); + ble_rf_disable(); if (done) { From d1c2cf5250524c478e61a43a56316bccd7e3bde9 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Thu, 27 Apr 2023 10:08:56 +0200 Subject: [PATCH 0686/1333] apps/blestress: Fix nrfx include path This fixes include path after nrfx was switched to used github repository --- apps/blestress/src/rx_stress.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/blestress/src/rx_stress.h b/apps/blestress/src/rx_stress.h index 62f84117a4..b2f897197a 100644 --- a/apps/blestress/src/rx_stress.h +++ b/apps/blestress/src/rx_stress.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include /* BLE */ #include "nimble/ble.h" From abd16e61863f2e4cba60ba7b847cbcd242582fa0 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 8 May 2023 16:04:27 +0200 Subject: [PATCH 0687/1333] ci: Download external nrfx repository In long term we should think on better mechanism for syncing core and nimble requirements in CI. --- .github/workflows/build_targets.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_targets.yml b/.github/workflows/build_targets.yml index ec7c1ac70a..235a8c2840 100644 --- a/.github/workflows/build_targets.yml +++ b/.github/workflows/build_targets.yml @@ -54,6 +54,7 @@ jobs: git clone --depth=1 https://github.com/mcu-tools/mcuboot.git repos/mcuboot git clone --depth=1 https://github.com/apache/mynewt-mcumgr repos/apache-mynewt-mcumgr git clone --depth=1 https://github.com/hathach/tinyusb.git repos/tinyusb + git clone --depth=1 https://github.com/NordicSemiconductor/nrfx --branch v2.8.0 repos/nordic-nrfx - name: Build targets shell: bash run: | From 631380aab0e02f8690bd2b3f87c6cc83e439d509 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 20 Apr 2023 16:46:05 +0200 Subject: [PATCH 0688/1333] nimble/ll: Allow to locally update connection min/max CE length Updating Min/Max CE Length can be done without triggering LL procedure. We can do that if current connection parameters fits parameters parameters provided in HCI command. Note that this is also valid for Connections Strict Scheduling. --- .../include/controller/ble_ll_hci.h | 5 +- .../include/controller/ble_ll_sync.h | 2 +- nimble/controller/src/ble_ll_conn_hci.c | 55 ++++++++++++++++++- nimble/controller/src/ble_ll_conn_priv.h | 2 +- nimble/controller/src/ble_ll_hci.c | 29 +++++++--- nimble/controller/src/ble_ll_sync.c | 6 +- 6 files changed, 82 insertions(+), 17 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_hci.h b/nimble/controller/include/controller/ble_ll_hci.h index 7421e77a05..ff66805040 100644 --- a/nimble/controller/include/controller/ble_ll_hci.h +++ b/nimble/controller/include/controller/ble_ll_hci.h @@ -38,7 +38,7 @@ extern "C" { */ #define BLE_LL_CFG_NUM_HCI_CMD_PKTS (1) -typedef void (*ble_ll_hci_post_cmd_complete_cb)(void); +typedef void (*ble_ll_hci_post_cmd_complete_cb)(void *user_data); #if MYNEWT_VAL(BLE_LL_HCI_VS) typedef int (* ble_ll_hci_vs_cb_t)(uint16_t ocf, @@ -81,6 +81,9 @@ int ble_ll_hci_check_dle(uint16_t max_octets, uint16_t max_time); void ble_ll_hci_supp_cmd_get(uint8_t *buf); +/* Used to set post HCI command hook */ +void ble_ll_hci_post_cmd_cb_set(ble_ll_hci_post_cmd_complete_cb cb, void *user_data); + #if MYNEWT_VAL(BLE_LL_HCI_VS) void ble_ll_hci_vs_register(struct ble_ll_hci_vs_cmd *cmds, uint32_t num_cmds); #endif diff --git a/nimble/controller/include/controller/ble_ll_sync.h b/nimble/controller/include/controller/ble_ll_sync.h index 8002d2a317..b4f9e944d2 100644 --- a/nimble/controller/include/controller/ble_ll_sync.h +++ b/nimble/controller/include/controller/ble_ll_sync.h @@ -34,7 +34,7 @@ struct ble_ll_scan_addr_data; struct ble_ll_sync_sm; int ble_ll_sync_create(const uint8_t *cmdbuf, uint8_t len); -int ble_ll_sync_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb); +int ble_ll_sync_cancel(void); int ble_ll_sync_terminate(const uint8_t *cmdbuf, uint8_t len); int ble_ll_sync_list_add(const uint8_t *cmdbuf, uint8_t len); int ble_ll_sync_list_remove(const uint8_t *cmdbuf, uint8_t len); diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 5aea53b87c..175a64266e 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -946,6 +946,34 @@ ble_ll_conn_hci_read_rem_features(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_SUCCESS; } +static bool +ble_ll_conn_params_in_range(struct ble_ll_conn_sm *connsm, + const struct ble_hci_le_conn_update_cp *cmd) +{ + if (!IN_RANGE(connsm->conn_itvl, le16toh(cmd->conn_itvl_min), + le16toh(cmd->conn_itvl_max))) { + return false; + } + + if (connsm->periph_latency != le16toh(cmd->conn_latency)) { + return false; + } + + if (connsm->supervision_tmo != le16toh(cmd->supervision_timeout)) { + return false; + } + + return true; +} + +static void +ble_ll_conn_hci_update_complete_event(void *user_data) +{ + struct ble_ll_conn_sm *connsm = user_data; + + ble_ll_hci_ev_conn_update(connsm, BLE_ERR_SUCCESS); +} + /** * Called to process a connection update command. * @@ -962,6 +990,7 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) uint16_t handle; struct ble_ll_conn_sm *connsm; struct hci_conn_update *hcu; + uint16_t max_ce_len; /* * XXX: must deal with peripheral not supporting this feature and using @@ -979,6 +1008,26 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_UNK_CONN_ID; } + /* if current connection parameters fit updated values we don't have to + * trigger LL procedure and just update local values (Min/Max CE Length) + * + * Note that this is also allowed for CSS as nothing changes WRT connections + * scheduling. + */ + if (ble_ll_conn_params_in_range(connsm, cmd)) { + max_ce_len = le16toh(cmd->max_ce_len); + + if (le16toh(cmd->min_ce_len) > max_ce_len) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + connsm->max_ce_len_ticks = ble_ll_tmr_u2t_up(max_ce_len * BLE_LL_CONN_CE_USECS); + + ble_ll_hci_post_cmd_cb_set(ble_ll_conn_hci_update_complete_event, connsm); + + return BLE_ERR_SUCCESS; + } + #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) /* Do not allow connection update if css in enabled, we only allow to move * anchor point (i.e. change slot) via dedicated HCI command. @@ -1198,7 +1247,7 @@ ble_ll_conn_hci_param_nrr(const uint8_t *cmdbuf, uint8_t len, * safe to use g_ble_ll_conn_comp_ev */ static void -ble_ll_conn_hci_cancel_conn_complete_event(void) +ble_ll_conn_hci_cancel_conn_complete_event(void *user_data) { BLE_LL_ASSERT(g_ble_ll_conn_comp_ev); @@ -1216,7 +1265,7 @@ ble_ll_conn_hci_cancel_conn_complete_event(void) * @return int */ int -ble_ll_conn_create_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb) +ble_ll_conn_create_cancel(void) { int rc; struct ble_ll_conn_sm *connsm; @@ -1236,7 +1285,7 @@ ble_ll_conn_create_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb) ble_ll_scan_sm_stop(1); ble_ll_conn_end(connsm, BLE_ERR_UNK_CONN_ID); - *post_cmd_cb = ble_ll_conn_hci_cancel_conn_complete_event; + ble_ll_hci_post_cmd_cb_set(ble_ll_conn_hci_cancel_conn_complete_event, NULL); rc = BLE_ERR_SUCCESS; } else { diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index 023881d0f1..a3e1cc4bbc 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -204,7 +204,7 @@ int ble_ll_conn_hci_param_rr(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); int ble_ll_conn_hci_param_nrr(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); -int ble_ll_conn_create_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb); +int ble_ll_conn_create_cancel(void); void ble_ll_conn_num_comp_pkts_event_send(struct ble_ll_conn_sm *connsm); void ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status, uint8_t *evbuf, struct ble_ll_adv_sm *advsm); diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 37ba94c617..0f92654b00 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -56,6 +56,9 @@ static uint64_t g_ble_ll_hci_event_mask2; static int16_t rx_path_pwr_compensation; static int16_t tx_path_pwr_compensation; +static ble_ll_hci_post_cmd_complete_cb hci_cmd_post_cb = NULL; +static void *hci_cmd_post_cb_user_data = NULL; + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) static enum { ADV_MODE_ANY, @@ -879,8 +882,7 @@ ble_ll_hci_le_set_host_chan_class(const uint8_t *cmdbuf, uint8_t len) */ static int ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, - uint8_t *rspbuf, uint8_t *rsplen, - ble_ll_hci_post_cmd_complete_cb *cb) + uint8_t *rspbuf, uint8_t *rsplen) { int rc; @@ -960,7 +962,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, break; case BLE_HCI_OCF_LE_CREATE_CONN_CANCEL: if (len == 0) { - rc = ble_ll_conn_create_cancel(cb); + rc = ble_ll_conn_create_cancel(); } break; #endif @@ -1187,7 +1189,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, break; case BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC_CANCEL: if (len == 0) { - rc = ble_ll_sync_cancel(cb); + rc = ble_ll_sync_cancel(); } break; case BLE_HCI_OCF_LE_PERIODIC_ADV_TERM_SYNC: @@ -1736,6 +1738,15 @@ ble_ll_hci_cmd_fake_dual_mode(uint16_t opcode, uint8_t *cmdbuf, uint8_t len, } #endif + +void +ble_ll_hci_post_cmd_cb_set(ble_ll_hci_post_cmd_complete_cb cb, void *user_data) +{ + BLE_LL_ASSERT(hci_cmd_post_cb == NULL); + hci_cmd_post_cb = cb; + hci_cmd_post_cb_user_data = user_data; +} + /** * Called to process an HCI command from the host. * @@ -1750,7 +1761,6 @@ ble_ll_hci_cmd_proc(struct ble_npl_event *ev) struct ble_hci_cmd *cmd; uint16_t opcode; uint16_t ocf; - ble_ll_hci_post_cmd_complete_cb post_cb = NULL; struct ble_hci_ev *hci_ev; struct ble_hci_ev_command_status *cmd_status; struct ble_hci_ev_command_complete *cmd_complete; @@ -1817,7 +1827,7 @@ ble_ll_hci_cmd_proc(struct ble_npl_event *ev) rc = ble_ll_hci_status_params_cmd_proc(cmd->data, cmd->length, ocf, rspbuf, &rsplen); break; case BLE_HCI_OGF_LE: - rc = ble_ll_hci_le_cmd_proc(cmd->data, cmd->length, ocf, rspbuf, &rsplen, &post_cb); + rc = ble_ll_hci_le_cmd_proc(cmd->data, cmd->length, ocf, rspbuf, &rsplen); break; #if MYNEWT_VAL(BLE_LL_HCI_VS) case BLE_HCI_OGF_VENDOR: @@ -1875,8 +1885,11 @@ ble_ll_hci_cmd_proc(struct ble_npl_event *ev) ble_ll_hci_event_send(hci_ev); /* Call post callback if set by command handler */ - if (post_cb) { - post_cb(); + if (hci_cmd_post_cb) { + hci_cmd_post_cb(hci_cmd_post_cb_user_data); + + hci_cmd_post_cb = NULL; + hci_cmd_post_cb_user_data = NULL; } BLE_LL_DEBUG_GPIO(HCI_CMD, 0); diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 31791dce37..7016dfed05 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -1559,13 +1559,13 @@ ble_ll_sync_create(const uint8_t *cmdbuf, uint8_t len) } static void -ble_ll_sync_cancel_complete_event(void) +ble_ll_sync_cancel_complete_event(void *user_data) { ble_ll_sync_est_event_failed(BLE_ERR_OPERATION_CANCELLED); } int -ble_ll_sync_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb) +ble_ll_sync_cancel(void) { struct ble_ll_sync_sm *sm; os_sr_t sr; @@ -1596,7 +1596,7 @@ ble_ll_sync_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb) OS_EXIT_CRITICAL(sr); /* g_ble_ll_sync_create_comp_ev will be cleared by this callback */ - *post_cmd_cb = ble_ll_sync_cancel_complete_event; + ble_ll_hci_post_cmd_cb_set(ble_ll_sync_cancel_complete_event, NULL); return BLE_ERR_SUCCESS; } From 1240af08b93f10fb20f5d3d81b46a0eebf4b6b15 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Wed, 10 May 2023 14:43:36 +0200 Subject: [PATCH 0689/1333] porting/FreeRTOS: fix IRQ priority FreeRTOS assumes a max irq priority for IRQs that are allowed to do system calls. This is set to 5 by default, so we use the highest allowed for the Radio. --- nimble/drivers/nrf5x/src/ble_phy.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index d0f7418515..bbf4f0a573 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -1657,8 +1657,12 @@ ble_phy_init(void) /* Set isr in vector table and enable interrupt */ #ifndef RIOT_VERSION +#ifdef FREERTOS + NVIC_SetPriority(RADIO_IRQn, 5); +#else NVIC_SetPriority(RADIO_IRQn, 0); #endif +#endif #if MYNEWT NVIC_SetVector(RADIO_IRQn, (uint32_t)ble_phy_isr); #else From 46fdbeeb0dd7ce04c1a95f77b38242a803fa25c0 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Mon, 8 May 2023 13:42:04 +0200 Subject: [PATCH 0690/1333] nimble/ll: Fix ports build The assert only works on MyNewt --- nimble/controller/src/ble_ll_sync.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 7016dfed05..f06f87c173 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -211,8 +211,7 @@ ble_ll_sync_sm_clear(struct ble_ll_sync_sm *sm) } ble_ll_rfmgmt_release(); - - BLE_LL_ASSERT(sm->sync_ev_end.ev.ev_queued == 0); + BLE_LL_ASSERT(ble_npl_event_is_queued(&sm->sync_ev_end) == 0); BLE_LL_ASSERT(sm->sch.enqueued == 0); memset(sm, 0, sizeof(*sm)); From bd8c96621f8007b06a4770a143ddc88e73734d2a Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 17 May 2023 13:39:22 +0200 Subject: [PATCH 0691/1333] nimble/ll: Rework how TX power is configured TX power is now always configured after channel (and PHY) is set before transmission is started. There is no "default" TX power and all users are expected to set it explicitly before transmission. This means that at the end of advertising TX power is not set back to global value. Main rationale for this change is to properly handle FEM that may have amplification factor depends on signal frequency (channel used). --- nimble/controller/src/ble_ll.c | 14 +++++++++++-- nimble/controller/src/ble_ll_adv.c | 26 +++++++++---------------- nimble/controller/src/ble_ll_conn.c | 3 +++ nimble/controller/src/ble_ll_hci_vs.c | 2 -- nimble/controller/src/ble_ll_scan.c | 7 +++++++ nimble/controller/src/ble_ll_scan_aux.c | 8 ++++++++ 6 files changed, 39 insertions(+), 21 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 4da7a1f850..ed1795bee5 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -76,6 +76,7 @@ /* This is TX power on PHY (or FEM PA if enabled) */ int8_t g_ble_ll_tx_power; +static int8_t g_ble_ll_tx_power_phy_current; int8_t g_ble_ll_tx_power_compensation; int8_t g_ble_ll_rx_power_compensation; @@ -1365,7 +1366,7 @@ ble_ll_task(void *arg) /* Set output power to default */ g_ble_ll_tx_power = ble_ll_tx_power_round(MIN(MYNEWT_VAL(BLE_LL_TX_PWR_DBM), MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM))); - ble_ll_tx_power_set(g_ble_ll_tx_power); + g_ble_ll_tx_power_phy_current = INT8_MAX; /* Tell the host that we are ready to receive packets */ ble_ll_hci_send_noop(); @@ -1617,7 +1618,7 @@ ble_ll_reset(void) /* Set output power to default */ g_ble_ll_tx_power = ble_ll_tx_power_round(MIN(MYNEWT_VAL(BLE_LL_TX_PWR_DBM), MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM))); - ble_ll_tx_power_set(g_ble_ll_tx_power); + g_ble_ll_tx_power_phy_current = INT8_MAX; /* FLush all packets from Link layer queues */ ble_ll_flush_pkt_queue(&g_ble_ll_data.ll_tx_pkt_q); @@ -2011,6 +2012,15 @@ ble_ll_tx_power_set(int tx_power) tx_power -= MYNEWT_VAL(BLE_FEM_PA_GAIN); #endif #endif + + /* If current TX power configuration matches requested one we don't need + * to update PHY tx power. + */ + if (g_ble_ll_tx_power_phy_current == tx_power) { + return; + } + + g_ble_ll_tx_power_phy_current = tx_power; ble_phy_tx_power_set(tx_power); } diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index ab5e6e2dbe..c7f16e1104 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1030,9 +1030,6 @@ ble_ll_adv_tx_done(void *arg) { struct ble_ll_adv_sm *advsm; - /* reset power to default after advertising */ - ble_ll_tx_power_set(g_ble_ll_tx_power); - advsm = (struct ble_ll_adv_sm *)arg; ble_ll_trace_u32x2(BLE_LL_TRACE_ID_ADV_TXDONE, advsm->adv_instance, @@ -1111,9 +1108,6 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch) goto adv_tx_done; } - /* Set the power */ - ble_ll_tx_power_set(advsm->tx_power); - /* Set channel */ rc = ble_phy_setchan(advsm->adv_chan, BLE_ACCESS_ADDR_ADV, BLE_LL_CRCINIT_ADV); BLE_LL_ASSERT(rc == 0); @@ -1131,6 +1125,9 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch) #endif #endif + /* Set the power */ + ble_ll_tx_power_set(advsm->tx_power); + /* Set transmit start time. */ txstart = sch->start_time + g_ble_ll_sched_offset_ticks; rc = ble_phy_tx_set_start_time(txstart, sch->remainder); @@ -1255,9 +1252,6 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch) ble_ll_adv_active_chanset_set_sec(advsm); - /* Set the power */ - ble_ll_tx_power_set(advsm->tx_power); - /* Set channel */ aux = AUX_CURRENT(advsm); rc = ble_phy_setchan(aux->chan, BLE_ACCESS_ADDR_ADV, @@ -1269,6 +1263,9 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch) ble_phy_mode_set(advsm->sec_phy, advsm->sec_phy); #endif + /* Set the power */ + ble_ll_tx_power_set(advsm->tx_power); + /* Set transmit start time. */ txstart = sch->start_time + g_ble_ll_sched_offset_ticks; rc = ble_phy_tx_set_start_time(txstart, sch->remainder); @@ -1741,8 +1738,6 @@ ble_ll_adv_halt(void) ble_ll_trace_u32(BLE_LL_TRACE_ID_ADV_HALT, advsm->adv_instance); - ble_ll_tx_power_set(g_ble_ll_tx_power); - #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) if (advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING) { ble_ll_adv_flags_clear(advsm, @@ -2176,9 +2171,6 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) static void ble_ll_adv_sync_tx_done(struct ble_ll_adv_sm *advsm) { - /* reset power to default after advertising */ - ble_ll_tx_power_set(g_ble_ll_tx_power); - /* for sync we trace a no pri nor sec set */ ble_ll_trace_u32x2(BLE_LL_TRACE_ID_ADV_TXDONE, advsm->adv_instance, 0); @@ -2232,9 +2224,6 @@ ble_ll_adv_sync_tx_start_cb(struct ble_ll_sched_item *sch) ble_ll_adv_active_chanset_clear(advsm); ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING); - /* Set the power */ - ble_ll_tx_power_set(advsm->tx_power); - /* Set channel */ sync = SYNC_CURRENT(advsm); rc = ble_phy_setchan(sync->chan, advsm->periodic_access_addr, @@ -2247,6 +2236,9 @@ ble_ll_adv_sync_tx_start_cb(struct ble_ll_sched_item *sch) ble_phy_mode_set(advsm->sec_phy, advsm->sec_phy); #endif + /* Set the power */ + ble_ll_tx_power_set(advsm->tx_power); + /* Set transmit start time. */ txstart = sch->start_time + g_ble_ll_sched_offset_ticks; rc = ble_phy_tx_set_start_time(txstart, sch->remainder); diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index b70a237673..78146f4f4c 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1523,6 +1523,9 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) ble_phy_mode_set(connsm->phy_data.tx_phy_mode, connsm->phy_data.rx_phy_mode); #endif + /* Set the power */ + ble_ll_tx_power_set(g_ble_ll_tx_power); + switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_CONN_ROLE_CENTRAL: diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index b5affc2f1e..7fd9a6ea6b 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -84,8 +84,6 @@ ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, g_ble_ll_tx_power_compensation); } - ble_ll_tx_power_set(g_ble_ll_tx_power); - rsp->tx_power = g_ble_ll_tx_power + g_ble_ll_tx_power_compensation; *rsplen = sizeof(*rsp); diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 748cf3ac5d..3c5073238f 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -785,6 +785,13 @@ ble_ll_scan_start(struct ble_ll_scan_sm *scansm) ble_phy_mode_set(phy_mode, phy_mode); #endif + /* if scan is not passive we need to set tx power as we may end up sending + * package + */ + if (scansm->scanp->scan_type != BLE_SCAN_TYPE_PASSIVE) { + ble_ll_tx_power_set(g_ble_ll_tx_power); + } + rc = ble_phy_rx_set_start_time(ble_ll_tmr_get() + g_ble_ll_sched_offset_ticks, 0); if (!rc || rc == BLE_PHY_ERR_RX_LATE) { diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 6160fef234..3d5f27753a 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -142,6 +142,14 @@ ble_ll_scan_aux_sched_cb(struct ble_ll_sched_item *sch) ble_phy_mode_set(phy_mode, phy_mode); #endif + /* if scan is not passive we need to set tx power as we may end up sending + * package + */ + /* TODO do this only on first AUX? */ + if (aux->scan_type != BLE_SCAN_TYPE_PASSIVE) { + ble_ll_tx_power_set(g_ble_ll_tx_power); + } + rc = ble_phy_rx_set_start_time(sch->start_time + g_ble_ll_sched_offset_ticks, sch->remainder); if (rc != 0 && rc != BLE_PHY_ERR_RX_LATE) { From 550d5a77cac8913d2b97b9238c87d85456a0623d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 17 May 2023 13:48:11 +0200 Subject: [PATCH 0692/1333] nimble/ll: Add function for getting current PHY channel This is useful for dynamic FEM drivers. --- nimble/controller/include/controller/ble_phy.h | 1 + nimble/drivers/dialog_cmac/src/ble_phy.c | 6 ++++++ nimble/drivers/native/src/ble_phy.c | 6 ++++++ nimble/drivers/nrf51/src/ble_phy.c | 6 ++++++ nimble/drivers/nrf5x/src/ble_phy.c | 6 ++++++ 5 files changed, 25 insertions(+) diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index bba8bccbf8..ab96cb9c70 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -86,6 +86,7 @@ int ble_phy_init(void); /* Set the PHY channel */ int ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit); +uint8_t ble_phy_chan_get(void); #if MYNEWT_VAL(BLE_PHY_VARIABLE_TIFS) /* Set T_ifs time for next transition */ diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index 997ce2ab04..938455bbbd 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -1697,6 +1697,12 @@ ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crc_init) return 0; } +uint8_t +ble_phy_chan_get(void) +{ + return g_ble_phy_data.channel; +} + void ble_phy_restart_rx(void) { diff --git a/nimble/drivers/native/src/ble_phy.c b/nimble/drivers/native/src/ble_phy.c index 7635621c6b..e27f36e991 100644 --- a/nimble/drivers/native/src/ble_phy.c +++ b/nimble/drivers/native/src/ble_phy.c @@ -551,6 +551,12 @@ ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit) return 0; } +uint8_t +ble_phy_chan_get(void) +{ + return g_ble_phy_data.phy_chan; +} + /** * Disable the PHY. This will do the following: * -> Turn off all phy interrupts. diff --git a/nimble/drivers/nrf51/src/ble_phy.c b/nimble/drivers/nrf51/src/ble_phy.c index f35c778121..c3a523dce1 100644 --- a/nimble/drivers/nrf51/src/ble_phy.c +++ b/nimble/drivers/nrf51/src/ble_phy.c @@ -1365,6 +1365,12 @@ ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit) return 0; } +uint8_t +ble_phy_chan_get(void) +{ + return g_ble_phy_data.phy_chan; +} + /** * Stop the timer used to count microseconds when using RTC for cputime */ diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index bbf4f0a573..223afbff9c 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -2126,6 +2126,12 @@ ble_phy_setchan(uint8_t chan, uint32_t access_addr, uint32_t crcinit) return 0; } +uint8_t +ble_phy_chan_get(void) +{ + return g_ble_phy_data.phy_chan; +} + /** * Stop the timer used to count microseconds when using RTC for cputime */ From a38655bb4a84deebc5e798d40d7dec48a19fa58f Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Mon, 22 May 2023 10:24:41 +0530 Subject: [PATCH 0693/1333] nimble/host: Removed the extra status field in the enh read transmit power level --- nimble/host/src/ble_gap.c | 2 +- nimble/include/nimble/hci_common.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index f486b72097..add9ea529f 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -6608,7 +6608,7 @@ ble_gap_enh_read_transmit_power_level(uint16_t conn_handle, uint8_t phy, uint8_t return rc; } - *out_status = rsp.status; + *out_status = rc; *out_phy = rsp.phy; *out_curr_tx_power_level = rsp.curr_tx_power_level; *out_max_tx_power_level = rsp.max_tx_power_level; diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 6c9d40617a..13c4a7146c 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1095,7 +1095,6 @@ struct ble_hci_le_enh_read_transmit_power_level_cp { uint8_t phy; } __attribute__((packed)); struct ble_hci_le_enh_read_transmit_power_level_rp { - uint8_t status; uint16_t conn_handle; uint8_t phy; uint8_t curr_tx_power_level; From a60ee37b8ffa9f6c0a3e635480680069a0f351a9 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 23 May 2023 15:04:50 +0200 Subject: [PATCH 0694/1333] nimble/ll: Fix encryption start procedure We need to update rx packet counter and direction bit after sending LL_START_ENC_RSP in central role as otherwise we will fail to decrypt LL_START_ENC_RSP from peripheral and will drop connection due to MIC failure. This only happens if peripheral replies with LL_START_ENC_RSP in the next slot after we send LL_START_ENC_RSP. If peripheral replies with an empty PDU instead, we will update direction bit on continuation and decryption on rx will be successful. --- nimble/controller/src/ble_ll_conn.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 78146f4f4c..a4e6724132 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1372,6 +1372,9 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) ble_phy_encrypt_iv_set(connsm->enc_data.iv); ble_phy_encrypt_counter_set(connsm->enc_data.tx_pkt_cntr, CONN_IS_CENTRAL(connsm)); + if (txend_func == NULL) { + txend_func = ble_ll_conn_continue_rx_encrypt; + } } else if (is_ctrl && (opcode == BLE_LL_CTRL_START_ENC_REQ)) { /* * Only the peripheral sends this and it gets sent unencrypted but From 06bc61ee35103c9bccf4e1515f47887de691fc63 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Thu, 25 May 2023 15:39:20 +0200 Subject: [PATCH 0695/1333] nimble/ll: Add HCI events for BIGInfo reports --- nimble/controller/include/controller/ble_ll.h | 1 + nimble/controller/src/ble_ll_sync.c | 92 ++++++++++++++++++- nimble/controller/syscfg.yml | 6 ++ 3 files changed, 97 insertions(+), 2 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 35b562a9b4..c4e70e6ef3 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -475,6 +475,7 @@ struct ble_dev_addr /* ACAD data types */ #define BLE_LL_ACAD_CHANNEL_MAP_UPDATE_IND 0x28 +#define BLE_LL_ACAD_BIGINFO 0x2C struct ble_ll_acad_channel_map_update_ind { uint8_t map[5]; diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index f06f87c173..f10a59938d 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -66,6 +66,9 @@ #define BLE_LL_SYNC_ITVL_USECS 1250 +#define BLE_LL_SYNC_BIGINFO_LEN 33 +#define BLE_LL_SYNC_BIGINFO_LEN_ENC 57 + struct ble_ll_sync_sm { uint16_t flags; @@ -661,6 +664,70 @@ ble_ll_sync_send_truncated_per_adv_rpt(struct ble_ll_sync_sm *sm, uint8_t *evbuf ble_ll_hci_event_send(hci_ev); } +#if MYNEWT_VAL(BLE_LL_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) +static void +ble_ll_sync_parse_biginfo_to_ev(struct ble_hci_ev_le_subev_biginfo_adv_report *ev, + const uint8_t *biginfo, uint8_t biginfo_len) +{ + uint32_t fields_buf; + + fields_buf = get_le32(&biginfo[0]); + ev->iso_interval = (fields_buf >> 15) & 0x0FFF; + ev->bis_cnt = (fields_buf >> 27) & 0x1F; + + fields_buf = get_le32(&biginfo[4]); + ev->nse = fields_buf & 0x1F; + ev->bn = (fields_buf >> 5) & 0x07; + ev->pto = (fields_buf >> 28) & 0x0F; + + fields_buf = get_le32(&biginfo[8]); + ev->irc = (fields_buf >> 20) & 0x0F; + ev->max_pdu = (fields_buf >> 24) & 0xFF; + + fields_buf = get_le32(&biginfo[17]); + ev->sdu_interval[0] = fields_buf & 0xFF; + ev->sdu_interval[1] = (fields_buf >> 8) & 0xFF; + ev->sdu_interval[2] = (fields_buf >> 16) & 0x0F; + ev->max_sdu = (fields_buf >> 20) & 0x0FFF; + + ev->phy = (biginfo[27] >> 5) & 0x07; + + ev->framing = (biginfo[32] >> 7) & 0x01; + + if (biginfo_len == BLE_LL_SYNC_BIGINFO_LEN_ENC) { + ev->encryption = 1; + } else { + ev->encryption = 0; + } +} + +static void +ble_ll_sync_send_biginfo_adv_rpt(struct ble_ll_sync_sm *sm, const uint8_t *biginfo, uint8_t biginfo_len) +{ + struct ble_hci_ev_le_subev_biginfo_adv_report *ev; + struct ble_hci_ev *hci_ev; + + if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_BIGINFO_ADV_REPORT)) { + return; + } + + hci_ev = ble_transport_alloc_evt(1); + if (!hci_ev) { + return; + } + + hci_ev->opcode = BLE_HCI_EVCODE_LE_META; + hci_ev->length = sizeof(*ev); + ev = (void *) hci_ev->data; + + ev->subev_code = BLE_HCI_LE_SUBEV_BIGINFO_ADV_REPORT; + ev->sync_handle = htole16(ble_ll_sync_get_handle(sm)); + ble_ll_sync_parse_biginfo_to_ev(ev, biginfo, biginfo_len); + + ble_ll_hci_event_send(hci_ev); +} +#endif + static void ble_ll_sync_send_per_adv_rpt(struct ble_ll_sync_sm *sm, struct os_mbuf *rxpdu, int8_t rssi, int8_t tx_power, int datalen, @@ -963,7 +1030,8 @@ ble_ll_sync_check_failed(struct ble_ll_sync_sm *sm) static bool ble_ll_sync_check_acad(struct ble_ll_sync_sm *sm, - const uint8_t *acad, uint8_t acad_len) + const uint8_t *acad, uint8_t acad_len, + const uint8_t **biginfo, uint8_t *biginfo_len) { const struct ble_ll_acad_channel_map_update_ind *chmu; unsigned int ad_len; @@ -1009,6 +1077,18 @@ ble_ll_sync_check_acad(struct ble_ll_sync_sm *sm, sm->chan_map_new_instant = le16toh(chmu->instant); sm->flags |= BLE_LL_SYNC_SM_FLAG_NEW_CHANMAP; break; + +#if MYNEWT_VAL(BLE_LL_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) + case BLE_LL_ACAD_BIGINFO: + if ((ad_len - 1 == BLE_LL_SYNC_BIGINFO_LEN) || (ad_len - 1 == BLE_LL_SYNC_BIGINFO_LEN_ENC)) { + *biginfo = &acad[2]; + *biginfo_len = ad_len - 1; + } else { + return false; + } + break; +#endif + default: break; } @@ -1034,6 +1114,8 @@ ble_ll_sync_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) uint8_t *aux = NULL; uint8_t *acad = NULL; uint8_t acad_len; + const uint8_t *biginfo = NULL; + uint8_t biginfo_len = 0; int datalen; bool reports_enabled; @@ -1099,7 +1181,7 @@ ble_ll_sync_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) } /* check ACAD, needs to be done before rxpdu is adjusted for ADV data */ - if (acad && !ble_ll_sync_check_acad(sm, acad, acad_len)) { + if (acad && !ble_ll_sync_check_acad(sm, acad, acad_len, &biginfo, &biginfo_len)) { /* we got bad packet (bad ACAD data), end event */ goto end_event; } @@ -1117,6 +1199,12 @@ ble_ll_sync_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) /* send reports from this PDU */ ble_ll_sync_send_per_adv_rpt(sm, rxpdu, hdr->rxinfo.rssi, tx_power, datalen, aux, aux_scheduled); + +#if MYNEWT_VAL(BLE_LL_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) + if (biginfo) { + ble_ll_sync_send_biginfo_adv_rpt(sm, biginfo, biginfo_len); + } +#endif } /* if chain was scheduled we don't end event yet */ diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 34039bb034..bff7b966ec 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -363,6 +363,12 @@ syscfg.defs: restrictions: - 'BLE_LL_CFG_FEAT_LL_ISO if 1' + BLE_LL_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: + description: > + This option is used to enable/disable support for + handling BIGInfo data + value: 0 + BLE_LL_SCAN_AUX_SEGMENT_CNT: description: > Number of auxiliary advertising segments that can be scanned From 8d6cc495057dd5aa1b5e3d3029ec82bac0289123 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Thu, 25 May 2023 15:42:45 +0200 Subject: [PATCH 0696/1333] nimble/host: Add BIGInfo report event This allows to receive BIGInfo reports in periodic advertisement sync callback function --- nimble/controller/syscfg.yml | 2 +- nimble/host/include/host/ble_gap.h | 49 ++++++++++++++++++++++++++++++ nimble/host/src/ble_gap.c | 41 +++++++++++++++++++++++++ nimble/host/src/ble_gap_priv.h | 3 ++ nimble/host/src/ble_hs_hci_evt.c | 23 ++++++++++++++ nimble/host/src/ble_hs_startup.c | 10 ++++++ nimble/syscfg.yml | 8 ++++- 7 files changed, 134 insertions(+), 2 deletions(-) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index bff7b966ec..55c20cf1f3 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -367,7 +367,7 @@ syscfg.defs: description: > This option is used to enable/disable support for handling BIGInfo data - value: 0 + value: MYNEWT_VAL(BLE_BIGINFO_REPORTS) BLE_LL_SCAN_AUX_SEGMENT_CNT: description: > diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index a5dadfbdf2..09139994c2 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -141,6 +141,7 @@ struct hci_conn_update; #define BLE_GAP_EVENT_PARING_COMPLETE 27 #define BLE_GAP_EVENT_SUBRATE_CHANGE 28 #define BLE_GAP_EVENT_VS_HCI 29 +#define BLE_GAP_EVENT_BIGINFO_REPORT 30 /*** Reason codes for the subscribe GAP event. */ @@ -982,6 +983,54 @@ struct ble_gap_event { } periodic_transfer; #endif +#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) + /** + * Represents a periodic advertising sync transfer received. Valid for + * the following event types: + * o BLE_GAP_EVENT_BIGINFO_REPORT + */ + struct { + /** Synchronization handle */ + uint16_t sync_handle; + + /** Number of present BISes */ + uint8_t bis_cnt; + + /** Number of SubEvents */ + uint8_t nse; + + /** ISO Interval */ + uint16_t iso_interval; + + /** Burst Number */ + uint8_t bn; + + /** Pre-Transmission Offset */ + uint8_t pto; + + /** Immediate Repetition Count */ + uint8_t irc; + + /** Maximum PDU size */ + uint16_t max_pdu; + + /** Maximum SDU size */ + uint16_t max_sdu; + + /** Service Data Unit Interval */ + uint32_t sdu_interval; + + /** BIG PHY */ + uint8_t phy; + + /** Framing of BIS Data PDUs */ + uint8_t framing : 1; + + /** Encryption */ + uint8_t encryption : 1; + } biginfo_report; +#endif + #if MYNEWT_VAL(BLE_POWER_CONTROL) /** * Represents a change in either local transmit power or remote transmit diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index add9ea529f..92023a4912 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -1849,6 +1849,47 @@ ble_gap_rx_periodic_adv_sync_transfer(const struct ble_hci_ev_le_subev_periodic_ ble_hs_unlock(); + cb(&event, cb_arg); +} +#endif + +#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) +void +ble_gap_rx_biginfo_adv_rpt(const struct ble_hci_ev_le_subev_biginfo_adv_report *ev) +{ + struct ble_hs_periodic_sync *psync; + struct ble_gap_event event; + ble_gap_event_fn *cb; + void *cb_arg; + + cb = NULL; + cb_arg = NULL; + + ble_hs_lock(); + psync = ble_hs_periodic_sync_find_by_handle(le16toh(ev->sync_handle)); + if (psync) { + cb = psync->cb; + cb_arg = psync->cb_arg; + } + ble_hs_unlock(); + + memset(&event, 0, sizeof event); + + event.type = BLE_GAP_EVENT_BIGINFO_REPORT; + event.biginfo_report.sync_handle = ev->sync_handle; + event.biginfo_report.bis_cnt = ev->bis_cnt; + event.biginfo_report.nse = ev->nse; + event.biginfo_report.iso_interval = ev->iso_interval; + event.biginfo_report.bn = ev->bn; + event.biginfo_report.pto = ev->pto; + event.biginfo_report.irc = ev->irc; + event.biginfo_report.max_pdu = ev->max_pdu; + event.biginfo_report.sdu_interval = get_le24(&ev->sdu_interval[0]); + event.biginfo_report.max_sdu = ev->max_sdu; + event.biginfo_report.phy = ev->phy; + event.biginfo_report.framing = ev->framing; + event.biginfo_report.encryption = ev->encryption; + ble_gap_event_listener_call(&event); if (cb) { cb(&event, cb_arg); diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h index 1c3f92b740..d7fb760941 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/nimble/host/src/ble_gap_priv.h @@ -88,6 +88,9 @@ void ble_gap_rx_periodic_adv_rpt(const struct ble_hci_ev_le_subev_periodic_adv_r void ble_gap_rx_periodic_adv_sync_lost(const struct ble_hci_ev_le_subev_periodic_adv_sync_lost *ev); void ble_gap_rx_periodic_adv_sync_transfer(const struct ble_hci_ev_le_subev_periodic_adv_sync_transfer *ev); #endif +#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) +void ble_gap_rx_biginfo_adv_rpt(const struct ble_hci_ev_le_subev_biginfo_adv_report *ev); +#endif void ble_gap_rx_scan_req_rcvd(const struct ble_hci_ev_le_subev_scan_req_rcvd *ev); #endif void ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc); diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 1699c645be..b91e771c0e 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -63,6 +63,9 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_rpt; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_lost; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_scan_req_rcvd; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_transfer; +#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_biginfo_adv_report; +#endif #if MYNEWT_VAL(BLE_POWER_CONTROL) static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_pathloss_threshold; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_transmit_power_report; @@ -128,6 +131,9 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = { [BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED] = ble_hs_hci_evt_le_adv_set_terminated, [BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD] = ble_hs_hci_evt_le_scan_req_rcvd, [BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_TRANSFER] = ble_hs_hci_evt_le_periodic_adv_sync_transfer, +#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) + [BLE_HCI_LE_SUBEV_BIGINFO_ADV_REPORT] = ble_hs_hci_evt_le_biginfo_adv_report, +#endif #if MYNEWT_VAL(BLE_POWER_CONTROL) [BLE_HCI_LE_SUBEV_PATH_LOSS_THRESHOLD] = ble_hs_hci_evt_le_pathloss_threshold, [BLE_HCI_LE_SUBEV_TRANSMIT_POWER_REPORT] = ble_hs_hci_evt_le_transmit_power_report, @@ -723,6 +729,23 @@ ble_hs_hci_evt_le_periodic_adv_sync_transfer(uint8_t subevent, const void *data, return 0; } +#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) +static int +ble_hs_hci_evt_le_biginfo_adv_report(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_biginfo_adv_report *ev = data; + + if (len != sizeof(*ev)) { + return BLE_HS_EBADDATA; + } + + ble_gap_rx_biginfo_adv_rpt(ev); + + return 0; +} +#endif + static int ble_hs_hci_evt_le_scan_timeout(uint8_t subevent, const void *data, unsigned int len) diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c index 7509fd5e49..15e50bf06e 100644 --- a/nimble/host/src/ble_hs_startup.c +++ b/nimble/host/src/ble_hs_startup.c @@ -261,6 +261,16 @@ ble_hs_startup_le_set_evmask_tx(void) } #endif +#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) + if (version >= BLE_HCI_VER_BCS_5_2) { + /** + * Enable the following LE events: + * 0x0000000200000000 LE BIGInfo Advertising Report event + */ + mask |= 0x0000000200000000; + } +#endif + cmd.event_mask = htole64(mask); rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index a50bc89e6d..17caf410cb 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -68,7 +68,13 @@ syscfg.defs: restrictions: - 'BLE_PERIODIC_ADV if 1' - '(BLE_ROLE_CENTRAL || BLE_ROLE_PERIPHERAL) if 1' - + BLE_BIGINFO_REPORTS: + description: > + This enables BIGInfo reports. + value: 0 + restrictions: + - 'BLE_PERIODIC_ADV if 1' + - '(BLE_VERSION >= 52) if 1' BLE_EXT_ADV_MAX_SIZE: description: > This allows to configure maximum size of advertising data and From fbf85bf37d083c4da49dc0c56b536e9733813b63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 31 May 2023 09:11:11 +0200 Subject: [PATCH 0697/1333] nimble: Allow to configure BLE version 5.4 Adds configuration for Core Specification 5.4 --- nimble/include/nimble/hci_common.h | 5 +++++ nimble/syscfg.yml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 13c4a7146c..db364db8d7 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -2019,6 +2019,7 @@ struct ble_hci_ev_le_subev_subrate_change { #define BLE_HCI_VER_BCS_5_1 (10) #define BLE_HCI_VER_BCS_5_2 (11) #define BLE_HCI_VER_BCS_5_3 (12) +#define BLE_HCI_VER_BCS_5_4 (13) #define BLE_LMP_VER_BCS_1_0b (0) #define BLE_LMP_VER_BCS_1_1 (1) @@ -2033,6 +2034,7 @@ struct ble_hci_ev_le_subev_subrate_change { #define BLE_LMP_VER_BCS_5_1 (10) #define BLE_LMP_VER_BCS_5_2 (11) #define BLE_LMP_VER_BCS_5_3 (12) +#define BLE_LMP_VER_BCS_5_4 (13) /* selected HCI and LMP version */ #if MYNEWT_VAL(BLE_VERSION) == 50 @@ -2047,6 +2049,9 @@ struct ble_hci_ev_le_subev_subrate_change { #elif MYNEWT_VAL(BLE_VERSION) == 53 #define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_5_3 #define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_5_3 +#elif MYNEWT_VAL(BLE_VERSION) == 54 +#define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_5_4 +#define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_5_4 #endif #define BLE_HCI_DATA_HDR_SZ 4 diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index 17caf410cb..81424931a8 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -86,7 +86,7 @@ syscfg.defs: This allows to configure supported Bluetooth Core version. Some features may not be available if version is too low. Version is integer for easy comparison. - range: 50, 51, 52, 53 + range: 50, 51, 52, 53, 54 value: 50 BLE_ISO: description: > From 9ae4f9d2787fd7ceff894a80f95c5623a71a329c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 31 May 2023 09:18:51 +0200 Subject: [PATCH 0698/1333] apps/bttester: configure for Core Specification v5.3 Bump bttester version up so BLE 5.3 features can be used. --- apps/bttester/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 5038e8121b..5db9af2ea8 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -100,7 +100,7 @@ syscfg.vals: BLE_L2CAP_COC_MAX_NUM: 2 BLE_L2CAP_SIG_MAX_PROCS: 2 BLE_L2CAP_ENHANCED_COC: 1 - BLE_VERSION: 52 + BLE_VERSION: 53 # Some testcases require MPS < MTU BLE_L2CAP_COC_MPS: 100 BLE_RPA_TIMEOUT: 30 From a366af0d4b1851b74d1e20b79eac54940d96661c Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Mon, 5 Jun 2023 10:23:53 +0200 Subject: [PATCH 0699/1333] nimble: Add experimental tag for BIGInfo syscfgs This adds "experimental" tag for BIGInfo sycfgs and changes the name of host's syscfg to describe it better. --- nimble/controller/syscfg.yml | 3 ++- nimble/host/include/host/ble_gap.h | 2 +- nimble/host/src/ble_gap.c | 2 +- nimble/host/src/ble_gap_priv.h | 2 +- nimble/host/src/ble_hs_hci_evt.c | 6 +++--- nimble/host/src/ble_hs_startup.c | 2 +- nimble/syscfg.yml | 3 ++- 7 files changed, 11 insertions(+), 9 deletions(-) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 55c20cf1f3..a7e6af030a 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -367,7 +367,8 @@ syscfg.defs: description: > This option is used to enable/disable support for handling BIGInfo data - value: MYNEWT_VAL(BLE_BIGINFO_REPORTS) + value: MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) + experimental: 1 BLE_LL_SCAN_AUX_SEGMENT_CNT: description: > diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index 09139994c2..bf40236e7a 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -983,7 +983,7 @@ struct ble_gap_event { } periodic_transfer; #endif -#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) /** * Represents a periodic advertising sync transfer received. Valid for * the following event types: diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 92023a4912..119e3521db 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -1853,7 +1853,7 @@ ble_gap_rx_periodic_adv_sync_transfer(const struct ble_hci_ev_le_subev_periodic_ } #endif -#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) void ble_gap_rx_biginfo_adv_rpt(const struct ble_hci_ev_le_subev_biginfo_adv_report *ev) { diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h index d7fb760941..0be949da60 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/nimble/host/src/ble_gap_priv.h @@ -88,7 +88,7 @@ void ble_gap_rx_periodic_adv_rpt(const struct ble_hci_ev_le_subev_periodic_adv_r void ble_gap_rx_periodic_adv_sync_lost(const struct ble_hci_ev_le_subev_periodic_adv_sync_lost *ev); void ble_gap_rx_periodic_adv_sync_transfer(const struct ble_hci_ev_le_subev_periodic_adv_sync_transfer *ev); #endif -#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) void ble_gap_rx_biginfo_adv_rpt(const struct ble_hci_ev_le_subev_biginfo_adv_report *ev); #endif void ble_gap_rx_scan_req_rcvd(const struct ble_hci_ev_le_subev_scan_req_rcvd *ev); diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index b91e771c0e..e7af2243b8 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -63,7 +63,7 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_rpt; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_lost; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_scan_req_rcvd; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_transfer; -#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_biginfo_adv_report; #endif #if MYNEWT_VAL(BLE_POWER_CONTROL) @@ -131,7 +131,7 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = { [BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED] = ble_hs_hci_evt_le_adv_set_terminated, [BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD] = ble_hs_hci_evt_le_scan_req_rcvd, [BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_TRANSFER] = ble_hs_hci_evt_le_periodic_adv_sync_transfer, -#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) [BLE_HCI_LE_SUBEV_BIGINFO_ADV_REPORT] = ble_hs_hci_evt_le_biginfo_adv_report, #endif #if MYNEWT_VAL(BLE_POWER_CONTROL) @@ -729,7 +729,7 @@ ble_hs_hci_evt_le_periodic_adv_sync_transfer(uint8_t subevent, const void *data, return 0; } -#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) static int ble_hs_hci_evt_le_biginfo_adv_report(uint8_t subevent, const void *data, unsigned int len) diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c index 15e50bf06e..75e98ebc43 100644 --- a/nimble/host/src/ble_hs_startup.c +++ b/nimble/host/src/ble_hs_startup.c @@ -261,7 +261,7 @@ ble_hs_startup_le_set_evmask_tx(void) } #endif -#if MYNEWT_VAL(BLE_BIGINFO_REPORTS) +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) if (version >= BLE_HCI_VER_BCS_5_2) { /** * Enable the following LE events: diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index 81424931a8..ce43a00b1d 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -68,13 +68,14 @@ syscfg.defs: restrictions: - 'BLE_PERIODIC_ADV if 1' - '(BLE_ROLE_CENTRAL || BLE_ROLE_PERIPHERAL) if 1' - BLE_BIGINFO_REPORTS: + BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: description: > This enables BIGInfo reports. value: 0 restrictions: - 'BLE_PERIODIC_ADV if 1' - '(BLE_VERSION >= 52) if 1' + experimental: 1 BLE_EXT_ADV_MAX_SIZE: description: > This allows to configure maximum size of advertising data and From 7f17076cc2f908f3b6df1653b58a9b7c253aedb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 5 Jun 2023 13:30:38 +0200 Subject: [PATCH 0700/1333] apps: bttester: make bttester code compliant with Mynewt code style bttester was initially ported from Zephyr. This app is independent now and should follow Mynewt Coding Standards. --- apps/bttester/src/atomic.h | 298 +-- apps/bttester/src/bttester.c | 525 ++--- apps/bttester/src/bttester.h | 1359 ++++++------ apps/bttester/src/bttester_pipe.h | 12 +- apps/bttester/src/gap.c | 2696 ++++++++++++------------ apps/bttester/src/gatt.c | 3188 +++++++++++++++-------------- apps/bttester/src/gatt_cl.c | 2466 +++++++++++----------- apps/bttester/src/glue.c | 88 +- apps/bttester/src/glue.h | 23 +- apps/bttester/src/l2cap.c | 1132 +++++----- apps/bttester/src/main.c | 45 +- apps/bttester/src/mesh.c | 1299 ++++++------ apps/bttester/src/uart_pipe.c | 68 +- 13 files changed, 6771 insertions(+), 6428 deletions(-) diff --git a/apps/bttester/src/atomic.h b/apps/bttester/src/atomic.h index 66283e9ac3..4376ad5bb7 100644 --- a/apps/bttester/src/atomic.h +++ b/apps/bttester/src/atomic.h @@ -55,12 +55,13 @@ typedef atomic_t atomic_val_t; * @param new_value New value to store. * @return 1 if @a new_value is written, 0 otherwise. */ -static inline int atomic_cas(atomic_t *target, atomic_val_t old_value, - atomic_val_t new_value) +static inline int +atomic_cas(atomic_t *target, atomic_val_t old_value, + atomic_val_t new_value) { return __atomic_compare_exchange_n(target, &old_value, new_value, - 0, __ATOMIC_SEQ_CST, - __ATOMIC_SEQ_CST); + 0, __ATOMIC_SEQ_CST, + __ATOMIC_SEQ_CST); } /** @@ -74,7 +75,8 @@ static inline int atomic_cas(atomic_t *target, atomic_val_t old_value, * * @return Previous value of @a target. */ -static inline atomic_val_t atomic_add(atomic_t *target, atomic_val_t value) +static inline atomic_val_t +atomic_add(atomic_t *target, atomic_val_t value) { return __atomic_fetch_add(target, value, __ATOMIC_SEQ_CST); } @@ -91,7 +93,8 @@ static inline atomic_val_t atomic_add(atomic_t *target, atomic_val_t value) * @return Previous value of @a target. */ -static inline atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value) +static inline atomic_val_t +atomic_sub(atomic_t *target, atomic_val_t value) { return __atomic_fetch_sub(target, value, __ATOMIC_SEQ_CST); } @@ -107,7 +110,8 @@ static inline atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value) * @return Previous value of @a target. */ -static inline atomic_val_t atomic_inc(atomic_t *target) +static inline atomic_val_t +atomic_inc(atomic_t *target) { return atomic_add(target, 1); } @@ -123,7 +127,8 @@ static inline atomic_val_t atomic_inc(atomic_t *target) * @return Previous value of @a target. */ -static inline atomic_val_t atomic_dec(atomic_t *target) +static inline atomic_val_t +atomic_dec(atomic_t *target) { return atomic_sub(target, 1); } @@ -139,7 +144,8 @@ static inline atomic_val_t atomic_dec(atomic_t *target) * @return Value of @a target. */ -static inline atomic_val_t atomic_get(const atomic_t *target) +static inline atomic_val_t +atomic_get(const atomic_t *target) { return __atomic_load_n(target, __ATOMIC_SEQ_CST); } @@ -157,7 +163,8 @@ static inline atomic_val_t atomic_get(const atomic_t *target) * @return Previous value of @a target. */ -static inline atomic_val_t atomic_set(atomic_t *target, atomic_val_t value) +static inline atomic_val_t +atomic_set(atomic_t *target, atomic_val_t value) { /* This builtin, as described by Intel, is not a traditional * test-and-set operation, but rather an atomic exchange operation. It @@ -178,7 +185,8 @@ static inline atomic_val_t atomic_set(atomic_t *target, atomic_val_t value) * @return Previous value of @a target. */ -static inline atomic_val_t atomic_clear(atomic_t *target) +static inline atomic_val_t +atomic_clear(atomic_t *target) { return atomic_set(target, 0); } @@ -196,7 +204,8 @@ static inline atomic_val_t atomic_clear(atomic_t *target) * @return Previous value of @a target. */ -static inline atomic_val_t atomic_or(atomic_t *target, atomic_val_t value) +static inline atomic_val_t +atomic_or(atomic_t *target, atomic_val_t value) { return __atomic_fetch_or(target, value, __ATOMIC_SEQ_CST); } @@ -214,7 +223,8 @@ static inline atomic_val_t atomic_or(atomic_t *target, atomic_val_t value) * @return Previous value of @a target. */ -static inline atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value) +static inline atomic_val_t +atomic_xor(atomic_t *target, atomic_val_t value) { return __atomic_fetch_xor(target, value, __ATOMIC_SEQ_CST); } @@ -232,7 +242,8 @@ static inline atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value) * @return Previous value of @a target. */ -static inline atomic_val_t atomic_and(atomic_t *target, atomic_val_t value) +static inline atomic_val_t +atomic_and(atomic_t *target, atomic_val_t value) { return __atomic_fetch_and(target, value, __ATOMIC_SEQ_CST); } @@ -250,149 +261,150 @@ static inline atomic_val_t atomic_and(atomic_t *target, atomic_val_t value) * @return Previous value of @a target. */ -static inline atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value) +static inline atomic_val_t +atomic_nand(atomic_t *target, atomic_val_t value) { return __atomic_fetch_nand(target, value, __ATOMIC_SEQ_CST); } - /** - * @brief Initialize an atomic variable. - * - * This macro can be used to initialize an atomic variable. For example, - * @code atomic_t my_var = ATOMIC_INIT(75); @endcode - * - * @param i Value to assign to atomic variable. - */ +/** + * @brief Initialize an atomic variable. + * + * This macro can be used to initialize an atomic variable. For example, + * @code atomic_t my_var = ATOMIC_INIT(75); @endcode + * + * @param i Value to assign to atomic variable. + */ #define ATOMIC_INIT(i) (i) - /** - * @cond INTERNAL_HIDDEN - */ +/** + * @cond INTERNAL_HIDDEN + */ #define ATOMIC_BITS (sizeof(atomic_val_t) * 8) #define ATOMIC_MASK(bit) (1 << ((bit) & (ATOMIC_BITS - 1))) #define ATOMIC_ELEM(addr, bit) ((addr) + ((bit) / ATOMIC_BITS)) - /** - * INTERNAL_HIDDEN @endcond - */ +/** + * INTERNAL_HIDDEN @endcond + */ - /** - * @brief Define an array of atomic variables. - * - * This macro defines an array of atomic variables containing at least - * @a num_bits bits. - * - * @note - * If used from file scope, the bits of the array are initialized to zero; - * if used from within a function, the bits are left uninitialized. - * - * @param name Name of array of atomic variables. - * @param num_bits Number of bits needed. - */ +/** + * @brief Define an array of atomic variables. + * + * This macro defines an array of atomic variables containing at least + * @a num_bits bits. + * + * @note + * If used from file scope, the bits of the array are initialized to zero; + * if used from within a function, the bits are left uninitialized. + * + * @param name Name of array of atomic variables. + * @param num_bits Number of bits needed. + */ #define ATOMIC_DEFINE(name, num_bits) \ - atomic_t name[1 + ((num_bits) - 1) / ATOMIC_BITS] - - /** - * @brief Atomically test a bit. - * - * This routine tests whether bit number @a bit of @a target is set or not. - * The target may be a single atomic variable or an array of them. - * - * @param target Address of atomic variable or array. - * @param bit Bit number (starting from 0). - * - * @return 1 if the bit was set, 0 if it wasn't. - */ - static inline int - atomic_test_bit(const atomic_t *target, int bit) - { - atomic_val_t val = atomic_get(ATOMIC_ELEM(target, bit)); - - return (1 & (val >> (bit & (ATOMIC_BITS - 1)))); - } - - /** - * @brief Atomically test and clear a bit. - * - * Atomically clear bit number @a bit of @a target and return its old value. - * The target may be a single atomic variable or an array of them. - * - * @param target Address of atomic variable or array. - * @param bit Bit number (starting from 0). - * - * @return 1 if the bit was set, 0 if it wasn't. - */ - static inline int - atomic_test_and_clear_bit(atomic_t *target, int bit) - { - atomic_val_t mask = ATOMIC_MASK(bit); - atomic_val_t old; - - old = atomic_and(ATOMIC_ELEM(target, bit), ~mask); - - return (old & mask) != 0; - } - - /** - * @brief Atomically set a bit. - * - * Atomically set bit number @a bit of @a target and return its old value. - * The target may be a single atomic variable or an array of them. - * - * @param target Address of atomic variable or array. - * @param bit Bit number (starting from 0). - * - * @return 1 if the bit was set, 0 if it wasn't. - */ - static inline int - atomic_test_and_set_bit(atomic_t *target, int bit) - { - atomic_val_t mask = ATOMIC_MASK(bit); - atomic_val_t old; - - old = atomic_or(ATOMIC_ELEM(target, bit), mask); - - return (old & mask) != 0; - } - - /** - * @brief Atomically clear a bit. - * - * Atomically clear bit number @a bit of @a target. - * The target may be a single atomic variable or an array of them. - * - * @param target Address of atomic variable or array. - * @param bit Bit number (starting from 0). - * - * @return N/A - */ - static inline void - atomic_clear_bit(atomic_t *target, int bit) - { - atomic_val_t mask = ATOMIC_MASK(bit); - - atomic_and(ATOMIC_ELEM(target, bit), ~mask); - } - - /** - * @brief Atomically set a bit. - * - * Atomically set bit number @a bit of @a target. - * The target may be a single atomic variable or an array of them. - * - * @param target Address of atomic variable or array. - * @param bit Bit number (starting from 0). - * - * @return N/A - */ - static inline void - atomic_set_bit(atomic_t *target, int bit) - { - atomic_val_t mask = ATOMIC_MASK(bit); + atomic_t name[1 + ((num_bits) - 1) / ATOMIC_BITS] + +/** + * @brief Atomically test a bit. + * + * This routine tests whether bit number @a bit of @a target is set or not. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return 1 if the bit was set, 0 if it wasn't. + */ +static inline int +atomic_test_bit(const atomic_t *target, int bit) +{ + atomic_val_t val = atomic_get(ATOMIC_ELEM(target, bit)); + + return (1 & (val >> (bit & (ATOMIC_BITS - 1)))); +} + +/** + * @brief Atomically test and clear a bit. + * + * Atomically clear bit number @a bit of @a target and return its old value. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return 1 if the bit was set, 0 if it wasn't. + */ +static inline int +atomic_test_and_clear_bit(atomic_t *target, int bit) +{ + atomic_val_t mask = ATOMIC_MASK(bit); + atomic_val_t old; + + old = atomic_and(ATOMIC_ELEM(target, bit), ~mask); + + return (old & mask) != 0; +} + +/** + * @brief Atomically set a bit. + * + * Atomically set bit number @a bit of @a target and return its old value. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return 1 if the bit was set, 0 if it wasn't. + */ +static inline int +atomic_test_and_set_bit(atomic_t *target, int bit) +{ + atomic_val_t mask = ATOMIC_MASK(bit); + atomic_val_t old; + + old = atomic_or(ATOMIC_ELEM(target, bit), mask); + + return (old & mask) != 0; +} - atomic_or(ATOMIC_ELEM(target, bit), mask); - } +/** + * @brief Atomically clear a bit. + * + * Atomically clear bit number @a bit of @a target. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return N/A + */ +static inline void +atomic_clear_bit(atomic_t *target, int bit) +{ + atomic_val_t mask = ATOMIC_MASK(bit); + + atomic_and(ATOMIC_ELEM(target, bit), ~mask); +} + +/** + * @brief Atomically set a bit. + * + * Atomically set bit number @a bit of @a target. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return N/A + */ +static inline void +atomic_set_bit(atomic_t *target, int bit) +{ + atomic_val_t mask = ATOMIC_MASK(bit); + + atomic_or(ATOMIC_ELEM(target, bit), mask); +} /** * @} diff --git a/apps/bttester/src/bttester.c b/apps/bttester/src/bttester.c index 76aebbf1e0..62219f565a 100644 --- a/apps/bttester/src/bttester.c +++ b/apps/bttester/src/bttester.c @@ -42,338 +42,351 @@ static struct os_eventq *cmds_queue; static struct os_event bttester_ev[CMD_QUEUED]; struct btp_buf { - struct os_event *ev; - union { - uint8_t data[BTP_MTU]; - struct btp_hdr hdr; - }; + struct os_event *ev; + union { + uint8_t data[BTP_MTU]; + struct btp_hdr hdr; + }; }; static struct btp_buf cmd_buf[CMD_QUEUED]; -static void supported_commands(uint8_t *data, uint16_t len) +static void +supported_commands(uint8_t *data, uint16_t len) { - uint8_t buf[1]; - struct core_read_supported_commands_rp *rp = (void *) buf; + uint8_t buf[1]; + struct core_read_supported_commands_rp *rp = (void *) buf; - memset(buf, 0, sizeof(buf)); + memset(buf, 0, sizeof(buf)); - tester_set_bit(buf, CORE_READ_SUPPORTED_COMMANDS); - tester_set_bit(buf, CORE_READ_SUPPORTED_SERVICES); - tester_set_bit(buf, CORE_REGISTER_SERVICE); - tester_set_bit(buf, CORE_UNREGISTER_SERVICE); + tester_set_bit(buf, CORE_READ_SUPPORTED_COMMANDS); + tester_set_bit(buf, CORE_READ_SUPPORTED_SERVICES); + tester_set_bit(buf, CORE_REGISTER_SERVICE); + tester_set_bit(buf, CORE_UNREGISTER_SERVICE); - tester_send(BTP_SERVICE_ID_CORE, CORE_READ_SUPPORTED_COMMANDS, - BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); + tester_send(BTP_SERVICE_ID_CORE, CORE_READ_SUPPORTED_COMMANDS, + BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); } -static void supported_services(uint8_t *data, uint16_t len) +static void +supported_services(uint8_t *data, uint16_t len) { - uint8_t buf[1]; - struct core_read_supported_services_rp *rp = (void *) buf; + uint8_t buf[1]; + struct core_read_supported_services_rp *rp = (void *) buf; - memset(buf, 0, sizeof(buf)); + memset(buf, 0, sizeof(buf)); - tester_set_bit(buf, BTP_SERVICE_ID_CORE); - tester_set_bit(buf, BTP_SERVICE_ID_GAP); - tester_set_bit(buf, BTP_SERVICE_ID_GATT); + tester_set_bit(buf, BTP_SERVICE_ID_CORE); + tester_set_bit(buf, BTP_SERVICE_ID_GAP); + tester_set_bit(buf, BTP_SERVICE_ID_GATT); #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) - tester_set_bit(buf, BTP_SERVICE_ID_L2CAP); + tester_set_bit(buf, BTP_SERVICE_ID_L2CAP); #endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */ #if MYNEWT_VAL(BLE_MESH) - tester_set_bit(buf, BTP_SERVICE_ID_MESH); + tester_set_bit(buf, BTP_SERVICE_ID_MESH); #endif /* MYNEWT_VAL(BLE_MESH) */ - tester_set_bit(buf, BTP_SERVICE_ID_GATTC); + tester_set_bit(buf, BTP_SERVICE_ID_GATTC); - tester_send(BTP_SERVICE_ID_CORE, CORE_READ_SUPPORTED_SERVICES, - BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); + tester_send(BTP_SERVICE_ID_CORE, CORE_READ_SUPPORTED_SERVICES, + BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); } -static void register_service(uint8_t *data, uint16_t len) +static void +register_service(uint8_t *data, uint16_t len) { - struct core_register_service_cmd *cmd = (void *) data; - uint8_t status; - - switch (cmd->id) { - case BTP_SERVICE_ID_GAP: - status = tester_init_gap(); - /* Rsp with success status will be handled by bt enable cb */ - if (status == BTP_STATUS_FAILED) { - goto rsp; - } - return; - case BTP_SERVICE_ID_GATT: - status = tester_init_gatt(); - break; + struct core_register_service_cmd *cmd = (void *) data; + uint8_t status; + + switch (cmd->id) { + case BTP_SERVICE_ID_GAP: + status = tester_init_gap(); + /* Rsp with success status will be handled by bt enable cb */ + if (status == BTP_STATUS_FAILED) { + goto rsp; + } + return; + case BTP_SERVICE_ID_GATT: + status = tester_init_gatt(); + break; #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) - case BTP_SERVICE_ID_L2CAP: - status = tester_init_l2cap(); - break; + case BTP_SERVICE_ID_L2CAP: + status = tester_init_l2cap(); + break; #endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */ #if MYNEWT_VAL(BLE_MESH) - case BTP_SERVICE_ID_MESH: - status = tester_init_mesh(); - break; + case BTP_SERVICE_ID_MESH: + status = tester_init_mesh(); + break; #endif /* MYNEWT_VAL(BLE_MESH) */ - default: - status = BTP_STATUS_FAILED; - break; - } + default: + status = BTP_STATUS_FAILED; + break; + } rsp: - tester_rsp(BTP_SERVICE_ID_CORE, CORE_REGISTER_SERVICE, BTP_INDEX_NONE, - status); + tester_rsp(BTP_SERVICE_ID_CORE, CORE_REGISTER_SERVICE, BTP_INDEX_NONE, + status); } -static void unregister_service(uint8_t *data, uint16_t len) +static void +unregister_service(uint8_t *data, uint16_t len) { - struct core_unregister_service_cmd *cmd = (void *) data; - uint8_t status; - - switch (cmd->id) { - case BTP_SERVICE_ID_GAP: - status = tester_unregister_gap(); - break; - case BTP_SERVICE_ID_GATT: - status = tester_unregister_gatt(); - break; + struct core_unregister_service_cmd *cmd = (void *) data; + uint8_t status; + + switch (cmd->id) { + case BTP_SERVICE_ID_GAP: + status = tester_unregister_gap(); + break; + case BTP_SERVICE_ID_GATT: + status = tester_unregister_gatt(); + break; #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) - case BTP_SERVICE_ID_L2CAP: - status = tester_unregister_l2cap(); - break; + case BTP_SERVICE_ID_L2CAP: + status = tester_unregister_l2cap(); + break; #endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */ #if MYNEWT_VAL(BLE_MESH) - case BTP_SERVICE_ID_MESH: - status = tester_unregister_mesh(); - break; + case BTP_SERVICE_ID_MESH: + status = tester_unregister_mesh(); + break; #endif /* MYNEWT_VAL(BLE_MESH) */ - default: - status = BTP_STATUS_FAILED; - break; - } + default: + status = BTP_STATUS_FAILED; + break; + } - tester_rsp(BTP_SERVICE_ID_CORE, CORE_UNREGISTER_SERVICE, BTP_INDEX_NONE, - status); + tester_rsp(BTP_SERVICE_ID_CORE, CORE_UNREGISTER_SERVICE, BTP_INDEX_NONE, + status); } -static void handle_core(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len) +static void +handle_core(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len) { - if (index != BTP_INDEX_NONE) { - tester_rsp(BTP_SERVICE_ID_CORE, opcode, index, - BTP_STATUS_FAILED); - return; - } - - switch (opcode) { - case CORE_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - return; - case CORE_READ_SUPPORTED_SERVICES: - supported_services(data, len); - return; - case CORE_REGISTER_SERVICE: - register_service(data, len); - return; - case CORE_UNREGISTER_SERVICE: - unregister_service(data, len); - return; - default: - tester_rsp(BTP_SERVICE_ID_CORE, opcode, BTP_INDEX_NONE, - BTP_STATUS_UNKNOWN_CMD); - return; - } + if (index != BTP_INDEX_NONE) { + tester_rsp(BTP_SERVICE_ID_CORE, opcode, index, + BTP_STATUS_FAILED); + return; + } + + switch (opcode) { + case CORE_READ_SUPPORTED_COMMANDS: + supported_commands(data, len); + return; + case CORE_READ_SUPPORTED_SERVICES: + supported_services(data, len); + return; + case CORE_REGISTER_SERVICE: + register_service(data, len); + return; + case CORE_UNREGISTER_SERVICE: + unregister_service(data, len); + return; + default: + tester_rsp(BTP_SERVICE_ID_CORE, opcode, BTP_INDEX_NONE, + BTP_STATUS_UNKNOWN_CMD); + return; + } } -static void cmd_handler(struct os_event *ev) +static void +cmd_handler(struct os_event *ev) { - uint16_t len; - struct btp_buf *cmd; - - if (!ev || !ev->ev_arg) { - return; - } - - cmd = ev->ev_arg; - - len = sys_le16_to_cpu(cmd->hdr.len); - if (MYNEWT_VAL(BTTESTER_BTP_LOG)) { - console_printf("[DBG] received %d bytes: %s\n", - sizeof(cmd->hdr) + len, - bt_hex(cmd->data, - sizeof(cmd->hdr) + len)); - } - - /* TODO - * verify if service is registered before calling handler - */ - - switch (cmd->hdr.service) { - case BTP_SERVICE_ID_CORE: - handle_core(cmd->hdr.opcode, cmd->hdr.index, - cmd->hdr.data, len); - break; - case BTP_SERVICE_ID_GAP: - tester_handle_gap(cmd->hdr.opcode, cmd->hdr.index, - cmd->hdr.data, len); - break; - case BTP_SERVICE_ID_GATT: - tester_handle_gatt(cmd->hdr.opcode, cmd->hdr.index, - cmd->hdr.data, len); - break; + uint16_t len; + struct btp_buf *cmd; + + if (!ev || !ev->ev_arg) { + return; + } + + cmd = ev->ev_arg; + + len = sys_le16_to_cpu(cmd->hdr.len); + if (MYNEWT_VAL(BTTESTER_BTP_LOG)) { + console_printf("[DBG] received %d bytes: %s\n", + sizeof(cmd->hdr) + len, + bt_hex(cmd->data, + sizeof(cmd->hdr) + len)); + } + + /* TODO + * verify if service is registered before calling handler + */ + + switch (cmd->hdr.service) { + case BTP_SERVICE_ID_CORE: + handle_core(cmd->hdr.opcode, cmd->hdr.index, + cmd->hdr.data, len); + break; + case BTP_SERVICE_ID_GAP: + tester_handle_gap(cmd->hdr.opcode, cmd->hdr.index, + cmd->hdr.data, len); + break; + case BTP_SERVICE_ID_GATT: + tester_handle_gatt(cmd->hdr.opcode, cmd->hdr.index, + cmd->hdr.data, len); + break; #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) - case BTP_SERVICE_ID_L2CAP: - tester_handle_l2cap(cmd->hdr.opcode, cmd->hdr.index, - cmd->hdr.data, len); - break; + case BTP_SERVICE_ID_L2CAP: + tester_handle_l2cap(cmd->hdr.opcode, cmd->hdr.index, + cmd->hdr.data, len); + break; #endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */ #if MYNEWT_VAL(BLE_MESH) - case BTP_SERVICE_ID_MESH: - tester_handle_mesh(cmd->hdr.opcode, cmd->hdr.index, - cmd->hdr.data, len); - break; + case BTP_SERVICE_ID_MESH: + tester_handle_mesh(cmd->hdr.opcode, cmd->hdr.index, + cmd->hdr.data, len); + break; #endif /* MYNEWT_VAL(BLE_MESH) */ - case BTP_SERVICE_ID_GATTC: - tester_handle_gattc(cmd->hdr.opcode, cmd->hdr.index, - cmd->hdr.data, len); - break; - default: - tester_rsp(cmd->hdr.service, cmd->hdr.opcode, - cmd->hdr.index, BTP_STATUS_FAILED); - break; - } - - os_eventq_put(&avail_queue, ev); + case BTP_SERVICE_ID_GATTC: + tester_handle_gattc(cmd->hdr.opcode, cmd->hdr.index, + cmd->hdr.data, len); + break; + default: + tester_rsp(cmd->hdr.service, cmd->hdr.opcode, + cmd->hdr.index, BTP_STATUS_FAILED); + break; + } + + os_eventq_put(&avail_queue, ev); } -static uint8_t *recv_cb(uint8_t *buf, size_t *off) +static uint8_t * +recv_cb(uint8_t *buf, size_t *off) { - struct btp_hdr *cmd = (void *) buf; - struct os_event *new_ev; - struct btp_buf *new_buf, *old_buf; - uint16_t len; - - if (*off < sizeof(*cmd)) { - return buf; - } - - len = sys_le16_to_cpu(cmd->len); - if (len > BTP_MTU - sizeof(*cmd)) { - *off = 0; - return buf; - } - - if (*off < sizeof(*cmd) + len) { - return buf; - } - - new_ev = os_eventq_get_no_wait(&avail_queue); - if (!new_ev) { - SYS_LOG_ERR("BT tester: RX overflow"); - *off = 0; - return buf; - } - - old_buf = CONTAINER_OF(buf, struct btp_buf, data); - os_eventq_put(cmds_queue, old_buf->ev); - - new_buf = new_ev->ev_arg; - *off = 0; - return new_buf->data; + struct btp_hdr *cmd = (void *) buf; + struct os_event *new_ev; + struct btp_buf *new_buf, *old_buf; + uint16_t len; + + if (*off < sizeof(*cmd)) { + return buf; + } + + len = sys_le16_to_cpu(cmd->len); + if (len > BTP_MTU - sizeof(*cmd)) { + *off = 0; + return buf; + } + + if (*off < sizeof(*cmd) + len) { + return buf; + } + + new_ev = os_eventq_get_no_wait(&avail_queue); + if (!new_ev) { + SYS_LOG_ERR("BT tester: RX overflow"); + *off = 0; + return buf; + } + + old_buf = CONTAINER_OF(buf, struct btp_buf, data); + os_eventq_put(cmds_queue, old_buf->ev); + + new_buf = new_ev->ev_arg; + *off = 0; + return new_buf->data; } -static void avail_queue_init(void) +static void +avail_queue_init(void) { - int i; + int i; - os_eventq_init(&avail_queue); + os_eventq_init(&avail_queue); - for (i = 0; i < CMD_QUEUED; i++) { - cmd_buf[i].ev = &bttester_ev[i]; - bttester_ev[i].ev_cb = cmd_handler; - bttester_ev[i].ev_arg = &cmd_buf[i]; + for (i = 0; i < CMD_QUEUED; i++) { + cmd_buf[i].ev = &bttester_ev[i]; + bttester_ev[i].ev_cb = cmd_handler; + bttester_ev[i].ev_arg = &cmd_buf[i]; - os_eventq_put(&avail_queue, &bttester_ev[i]); - } + os_eventq_put(&avail_queue, &bttester_ev[i]); + } } -void bttester_evq_set(struct os_eventq *evq) +void +bttester_evq_set(struct os_eventq *evq) { - cmds_queue = evq; + cmds_queue = evq; } -void tester_init(void) +void +tester_init(void) { - struct os_event *ev; - struct btp_buf *buf; + struct os_event *ev; + struct btp_buf *buf; - avail_queue_init(); - bttester_evq_set(os_eventq_dflt_get()); + avail_queue_init(); + bttester_evq_set(os_eventq_dflt_get()); - ev = os_eventq_get(&avail_queue); - buf = ev->ev_arg; + ev = os_eventq_get(&avail_queue); + buf = ev->ev_arg; - if (bttester_pipe_init()) { - SYS_LOG_ERR("Failed to initialize pipe"); - return; - } + if (bttester_pipe_init()) { + SYS_LOG_ERR("Failed to initialize pipe"); + return; + } - bttester_pipe_register(buf->data, BTP_MTU, recv_cb); + bttester_pipe_register(buf->data, BTP_MTU, recv_cb); - tester_send(BTP_SERVICE_ID_CORE, CORE_EV_IUT_READY, BTP_INDEX_NONE, - NULL, 0); + tester_send(BTP_SERVICE_ID_CORE, CORE_EV_IUT_READY, BTP_INDEX_NONE, + NULL, 0); } -void tester_send(uint8_t service, uint8_t opcode, uint8_t index, uint8_t *data, - size_t len) +void +tester_send(uint8_t service, uint8_t opcode, uint8_t index, uint8_t *data, + size_t len) { - struct btp_hdr msg; - - msg.service = service; - msg.opcode = opcode; - msg.index = index; - msg.len = len; - - bttester_pipe_send((uint8_t *)&msg, sizeof(msg)); - if (data && len) { - bttester_pipe_send(data, len); - } - - if (MYNEWT_VAL(BTTESTER_BTP_LOG)) { - console_printf("[DBG] send %d bytes hdr: %s\n", sizeof(msg), - bt_hex((char *) &msg, sizeof(msg))); - if (data && len) { - console_printf("[DBG] send %d bytes data: %s\n", len, - bt_hex((char *) data, len)); - } - } + struct btp_hdr msg; + + msg.service = service; + msg.opcode = opcode; + msg.index = index; + msg.len = len; + + bttester_pipe_send((uint8_t *) &msg, sizeof(msg)); + if (data && len) { + bttester_pipe_send(data, len); + } + + if (MYNEWT_VAL(BTTESTER_BTP_LOG)) { + console_printf("[DBG] send %d bytes hdr: %s\n", sizeof(msg), + bt_hex((char *) &msg, sizeof(msg))); + if (data && len) { + console_printf("[DBG] send %d bytes data: %s\n", len, + bt_hex((char *) data, len)); + } + } } -void tester_send_buf(uint8_t service, uint8_t opcode, uint8_t index, - struct os_mbuf *data) +void +tester_send_buf(uint8_t service, uint8_t opcode, uint8_t index, + struct os_mbuf *data) { - struct btp_hdr msg; + struct btp_hdr msg; - msg.service = service; - msg.opcode = opcode; - msg.index = index; - msg.len = os_mbuf_len(data); + msg.service = service; + msg.opcode = opcode; + msg.index = index; + msg.len = os_mbuf_len(data); - bttester_pipe_send((uint8_t *)&msg, sizeof(msg)); - if (data && msg.len) { - bttester_pipe_send_buf(data); - } + bttester_pipe_send((uint8_t *) &msg, sizeof(msg)); + if (data && msg.len) { + bttester_pipe_send_buf(data); + } } -void tester_rsp(uint8_t service, uint8_t opcode, uint8_t index, uint8_t status) +void +tester_rsp(uint8_t service, uint8_t opcode, uint8_t index, uint8_t status) { - struct btp_status s; + struct btp_status s; - if (status == BTP_STATUS_SUCCESS) { - tester_send(service, opcode, index, NULL, 0); - return; - } + if (status == BTP_STATUS_SUCCESS) { + tester_send(service, opcode, index, NULL, 0); + return; + } - s.code = status; - tester_send(service, BTP_STATUS, index, (uint8_t *) &s, sizeof(s)); + s.code = status; + tester_send(service, BTP_STATUS, index, (uint8_t *) &s, sizeof(s)); } diff --git a/apps/bttester/src/bttester.h b/apps/bttester/src/bttester.h index 4aa34b3c25..87bb275b89 100644 --- a/apps/bttester/src/bttester.h +++ b/apps/bttester/src/bttester.h @@ -41,29 +41,29 @@ #define BTP_MTU MYNEWT_VAL(BTTESTER_BTP_DATA_SIZE_MAX) #define BTP_DATA_MAX_SIZE (BTP_MTU - sizeof(struct btp_hdr)) -#define BTP_INDEX_NONE 0xff +#define BTP_INDEX_NONE 0xff -#define BTP_SERVICE_ID_CORE 0 -#define BTP_SERVICE_ID_GAP 1 -#define BTP_SERVICE_ID_GATT 2 -#define BTP_SERVICE_ID_L2CAP 3 -#define BTP_SERVICE_ID_MESH 4 -#define BTP_SERVICE_ID_GATTC 6 +#define BTP_SERVICE_ID_CORE 0 +#define BTP_SERVICE_ID_GAP 1 +#define BTP_SERVICE_ID_GATT 2 +#define BTP_SERVICE_ID_L2CAP 3 +#define BTP_SERVICE_ID_MESH 4 +#define BTP_SERVICE_ID_GATTC 6 -#define BTP_STATUS_SUCCESS 0x00 -#define BTP_STATUS_FAILED 0x01 -#define BTP_STATUS_UNKNOWN_CMD 0x02 -#define BTP_STATUS_NOT_READY 0x03 +#define BTP_STATUS_SUCCESS 0x00 +#define BTP_STATUS_FAILED 0x01 +#define BTP_STATUS_UNKNOWN_CMD 0x02 +#define BTP_STATUS_NOT_READY 0x03 #define SYS_LOG_DBG(fmt, ...) \ - if (MYNEWT_VAL(BTTESTER_DEBUG)) { \ - console_printf("[DBG] %s: " fmt "\n", \ - __func__, ## __VA_ARGS__); \ - } + if (MYNEWT_VAL(BTTESTER_DEBUG)) { \ + console_printf("[DBG] %s: " fmt "\n", \ + __func__, ## __VA_ARGS__); \ + } #define SYS_LOG_INF(fmt, ...) console_printf("[INF] %s: " fmt "\n", \ - __func__, ## __VA_ARGS__); + __func__, ## __VA_ARGS__); #define SYS_LOG_ERR(fmt, ...) console_printf("[WRN] %s: " fmt "\n", \ - __func__, ## __VA_ARGS__); + __func__, ## __VA_ARGS__); #define SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG #define SYS_LOG_DOMAIN "bttester" @@ -73,217 +73,217 @@ #define sys_cpu_to_le16 htole16 struct btp_hdr { - uint8_t service; - uint8_t opcode; - uint8_t index; - uint16_t len; - uint8_t data[0]; + uint8_t service; + uint8_t opcode; + uint8_t index; + uint16_t len; + uint8_t data[0]; } __packed; -#define BTP_STATUS 0x00 +#define BTP_STATUS 0x00 struct btp_status { - uint8_t code; + uint8_t code; } __packed; /* Core Service */ -#define CORE_READ_SUPPORTED_COMMANDS 0x01 +#define CORE_READ_SUPPORTED_COMMANDS 0x01 struct core_read_supported_commands_rp { - uint8_t data[0]; + uint8_t data[0]; } __packed; -#define CORE_READ_SUPPORTED_SERVICES 0x02 +#define CORE_READ_SUPPORTED_SERVICES 0x02 struct core_read_supported_services_rp { - uint8_t data[0]; + uint8_t data[0]; } __packed; -#define CORE_REGISTER_SERVICE 0x03 +#define CORE_REGISTER_SERVICE 0x03 struct core_register_service_cmd { - uint8_t id; + uint8_t id; } __packed; -#define CORE_UNREGISTER_SERVICE 0x04 +#define CORE_UNREGISTER_SERVICE 0x04 struct core_unregister_service_cmd { - uint8_t id; + uint8_t id; } __packed; /* events */ -#define CORE_EV_IUT_READY 0x80 +#define CORE_EV_IUT_READY 0x80 /* GAP Service */ /* commands */ -#define GAP_READ_SUPPORTED_COMMANDS 0x01 +#define GAP_READ_SUPPORTED_COMMANDS 0x01 struct gap_read_supported_commands_rp { - uint8_t data[0]; + uint8_t data[0]; } __packed; -#define GAP_READ_CONTROLLER_INDEX_LIST 0x02 +#define GAP_READ_CONTROLLER_INDEX_LIST 0x02 struct gap_read_controller_index_list_rp { - uint8_t num; - uint8_t index[0]; -} __packed; - -#define GAP_SETTINGS_POWERED 0 -#define GAP_SETTINGS_CONNECTABLE 1 -#define GAP_SETTINGS_FAST_CONNECTABLE 2 -#define GAP_SETTINGS_DISCOVERABLE 3 -#define GAP_SETTINGS_BONDABLE 4 -#define GAP_SETTINGS_LINK_SEC_3 5 -#define GAP_SETTINGS_SSP 6 -#define GAP_SETTINGS_BREDR 7 -#define GAP_SETTINGS_HS 8 -#define GAP_SETTINGS_LE 9 -#define GAP_SETTINGS_ADVERTISING 10 -#define GAP_SETTINGS_SC 11 -#define GAP_SETTINGS_DEBUG_KEYS 12 -#define GAP_SETTINGS_PRIVACY 13 -#define GAP_SETTINGS_CONTROLLER_CONFIG 14 -#define GAP_SETTINGS_STATIC_ADDRESS 15 - -#define GAP_READ_CONTROLLER_INFO 0x03 + uint8_t num; + uint8_t index[0]; +} __packed; + +#define GAP_SETTINGS_POWERED 0 +#define GAP_SETTINGS_CONNECTABLE 1 +#define GAP_SETTINGS_FAST_CONNECTABLE 2 +#define GAP_SETTINGS_DISCOVERABLE 3 +#define GAP_SETTINGS_BONDABLE 4 +#define GAP_SETTINGS_LINK_SEC_3 5 +#define GAP_SETTINGS_SSP 6 +#define GAP_SETTINGS_BREDR 7 +#define GAP_SETTINGS_HS 8 +#define GAP_SETTINGS_LE 9 +#define GAP_SETTINGS_ADVERTISING 10 +#define GAP_SETTINGS_SC 11 +#define GAP_SETTINGS_DEBUG_KEYS 12 +#define GAP_SETTINGS_PRIVACY 13 +#define GAP_SETTINGS_CONTROLLER_CONFIG 14 +#define GAP_SETTINGS_STATIC_ADDRESS 15 + +#define GAP_READ_CONTROLLER_INFO 0x03 struct gap_read_controller_info_rp { - uint8_t address[6]; - uint32_t supported_settings; - uint32_t current_settings; - uint8_t cod[3]; - uint8_t name[249]; - uint8_t short_name[11]; + uint8_t address[6]; + uint32_t supported_settings; + uint32_t current_settings; + uint8_t cod[3]; + uint8_t name[249]; + uint8_t short_name[11]; } __packed; -#define GAP_RESET 0x04 +#define GAP_RESET 0x04 struct gap_reset_rp { - uint32_t current_settings; + uint32_t current_settings; } __packed; -#define GAP_SET_POWERED 0x05 +#define GAP_SET_POWERED 0x05 struct gap_set_powered_cmd { - uint8_t powered; + uint8_t powered; } __packed; struct gap_set_powered_rp { - uint32_t current_settings; + uint32_t current_settings; } __packed; -#define GAP_SET_CONNECTABLE 0x06 +#define GAP_SET_CONNECTABLE 0x06 struct gap_set_connectable_cmd { - uint8_t connectable; + uint8_t connectable; } __packed; struct gap_set_connectable_rp { - uint32_t current_settings; + uint32_t current_settings; } __packed; -#define GAP_SET_FAST_CONNECTABLE 0x07 +#define GAP_SET_FAST_CONNECTABLE 0x07 struct gap_set_fast_connectable_cmd { - uint8_t fast_connectable; + uint8_t fast_connectable; } __packed; struct gap_set_fast_connectable_rp { - uint32_t current_settings; + uint32_t current_settings; } __packed; -#define GAP_NON_DISCOVERABLE 0x00 -#define GAP_GENERAL_DISCOVERABLE 0x01 -#define GAP_LIMITED_DISCOVERABLE 0x02 +#define GAP_NON_DISCOVERABLE 0x00 +#define GAP_GENERAL_DISCOVERABLE 0x01 +#define GAP_LIMITED_DISCOVERABLE 0x02 -#define GAP_SET_DISCOVERABLE 0x08 +#define GAP_SET_DISCOVERABLE 0x08 struct gap_set_discoverable_cmd { - uint8_t discoverable; + uint8_t discoverable; } __packed; struct gap_set_discoverable_rp { - uint32_t current_settings; + uint32_t current_settings; } __packed; -#define GAP_SET_BONDABLE 0x09 +#define GAP_SET_BONDABLE 0x09 struct gap_set_bondable_cmd { - uint8_t bondable; + uint8_t bondable; } __packed; struct gap_set_bondable_rp { - uint32_t current_settings; + uint32_t current_settings; } __packed; -#define GAP_START_ADVERTISING 0x0a +#define GAP_START_ADVERTISING 0x0a struct gap_start_advertising_cmd { - uint8_t adv_data_len; - uint8_t scan_rsp_len; - uint8_t adv_data[0]; - uint8_t scan_rsp[0]; + uint8_t adv_data_len; + uint8_t scan_rsp_len; + uint8_t adv_data[0]; + uint8_t scan_rsp[0]; } __packed; struct gap_start_advertising_rp { - uint32_t current_settings; + uint32_t current_settings; } __packed; -#define GAP_STOP_ADVERTISING 0x0b +#define GAP_STOP_ADVERTISING 0x0b struct gap_stop_advertising_rp { - uint32_t current_settings; + uint32_t current_settings; } __packed; -#define GAP_DISCOVERY_FLAG_LE 0x01 -#define GAP_DISCOVERY_FLAG_BREDR 0x02 -#define GAP_DISCOVERY_FLAG_LIMITED 0x04 -#define GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN 0x08 -#define GAP_DISCOVERY_FLAG_LE_OBSERVE 0x10 +#define GAP_DISCOVERY_FLAG_LE 0x01 +#define GAP_DISCOVERY_FLAG_BREDR 0x02 +#define GAP_DISCOVERY_FLAG_LIMITED 0x04 +#define GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN 0x08 +#define GAP_DISCOVERY_FLAG_LE_OBSERVE 0x10 -#define GAP_START_DISCOVERY 0x0c +#define GAP_START_DISCOVERY 0x0c struct gap_start_discovery_cmd { - uint8_t flags; + uint8_t flags; } __packed; -#define GAP_STOP_DISCOVERY 0x0d +#define GAP_STOP_DISCOVERY 0x0d -#define GAP_CONNECT 0x0e +#define GAP_CONNECT 0x0e struct gap_connect_cmd { - uint8_t address_type; - uint8_t address[6]; + uint8_t address_type; + uint8_t address[6]; } __packed; -#define GAP_DISCONNECT 0x0f +#define GAP_DISCONNECT 0x0f struct gap_disconnect_cmd { - uint8_t address_type; - uint8_t address[6]; + uint8_t address_type; + uint8_t address[6]; } __packed; -#define GAP_IO_CAP_DISPLAY_ONLY 0 -#define GAP_IO_CAP_DISPLAY_YESNO 1 -#define GAP_IO_CAP_KEYBOARD_ONLY 2 -#define GAP_IO_CAP_NO_INPUT_OUTPUT 3 -#define GAP_IO_CAP_KEYBOARD_DISPLAY 4 +#define GAP_IO_CAP_DISPLAY_ONLY 0 +#define GAP_IO_CAP_DISPLAY_YESNO 1 +#define GAP_IO_CAP_KEYBOARD_ONLY 2 +#define GAP_IO_CAP_NO_INPUT_OUTPUT 3 +#define GAP_IO_CAP_KEYBOARD_DISPLAY 4 -#define GAP_SET_IO_CAP 0x10 +#define GAP_SET_IO_CAP 0x10 struct gap_set_io_cap_cmd { - uint8_t io_cap; + uint8_t io_cap; } __packed; -#define GAP_PAIR 0x11 +#define GAP_PAIR 0x11 struct gap_pair_cmd { - uint8_t address_type; - uint8_t address[6]; + uint8_t address_type; + uint8_t address[6]; } __packed; -#define GAP_UNPAIR 0x12 +#define GAP_UNPAIR 0x12 struct gap_unpair_cmd { - uint8_t address_type; - uint8_t address[6]; + uint8_t address_type; + uint8_t address[6]; } __packed; -#define GAP_PASSKEY_ENTRY 0x13 +#define GAP_PASSKEY_ENTRY 0x13 struct gap_passkey_entry_cmd { - uint8_t address_type; - uint8_t address[6]; - uint32_t passkey; + uint8_t address_type; + uint8_t address[6]; + uint32_t passkey; } __packed; -#define GAP_PASSKEY_CONFIRM 0x14 +#define GAP_PASSKEY_CONFIRM 0x14 struct gap_passkey_confirm_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t match; + uint8_t address_type; + uint8_t address[6]; + uint8_t match; } __packed; -#define GAP_START_DIRECT_ADV 0x15 +#define GAP_START_DIRECT_ADV 0x15 struct gap_start_direct_adv_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t high_duty; + uint8_t address_type; + uint8_t address[6]; + uint8_t high_duty; } __packed; -#define GAP_CONN_PARAM_UPDATE 0x16 +#define GAP_CONN_PARAM_UPDATE 0x16 struct gap_conn_param_update_cmd { uint8_t address_type; uint8_t address[6]; @@ -293,104 +293,104 @@ struct gap_conn_param_update_cmd { uint16_t supervision_timeout; } __packed; -#define GAP_PAIRING_CONSENT_RSP 0x17 +#define GAP_PAIRING_CONSENT_RSP 0x17 struct gap_pairing_consent_rsp_cmd { uint8_t address_type; uint8_t address[6]; uint8_t consent; } __packed; -#define GAP_OOB_LEGACY_SET_DATA 0x18 +#define GAP_OOB_LEGACY_SET_DATA 0x18 struct gap_oob_legacy_set_data_cmd { uint8_t oob_data[16]; } __packed; -#define GAP_OOB_SC_GET_LOCAL_DATA 0x19 +#define GAP_OOB_SC_GET_LOCAL_DATA 0x19 struct gap_oob_sc_get_local_data_rp { uint8_t r[16]; uint8_t c[16]; } __packed; -#define GAP_OOB_SC_SET_REMOTE_DATA 0x1a +#define GAP_OOB_SC_SET_REMOTE_DATA 0x1a struct gap_oob_sc_set_remote_data_cmd { uint8_t r[16]; uint8_t c[16]; } __packed; -#define GAP_SET_MITM 0x1b +#define GAP_SET_MITM 0x1b struct gap_set_mitm_cmd { uint8_t mitm; } __packed; -#define GAP_SET_FILTER_ACCEPT_LIST 0x1c +#define GAP_SET_FILTER_ACCEPT_LIST 0x1c struct gap_set_filter_accept_list_cmd { uint8_t list_len; ble_addr_t addrs[]; } __packed; /* events */ -#define GAP_EV_NEW_SETTINGS 0x80 +#define GAP_EV_NEW_SETTINGS 0x80 struct gap_new_settings_ev { - uint32_t current_settings; + uint32_t current_settings; } __packed; -#define GAP_DEVICE_FOUND_FLAG_RSSI 0x01 -#define GAP_DEVICE_FOUND_FLAG_AD 0x02 -#define GAP_DEVICE_FOUND_FLAG_SD 0x04 +#define GAP_DEVICE_FOUND_FLAG_RSSI 0x01 +#define GAP_DEVICE_FOUND_FLAG_AD 0x02 +#define GAP_DEVICE_FOUND_FLAG_SD 0x04 -#define GAP_EV_DEVICE_FOUND 0x81 +#define GAP_EV_DEVICE_FOUND 0x81 struct gap_device_found_ev { - uint8_t address_type; - uint8_t address[6]; - int8_t rssi; - uint8_t flags; - uint16_t eir_data_len; - uint8_t eir_data[0]; + uint8_t address_type; + uint8_t address[6]; + int8_t rssi; + uint8_t flags; + uint16_t eir_data_len; + uint8_t eir_data[0]; } __packed; -#define GAP_EV_DEVICE_CONNECTED 0x82 +#define GAP_EV_DEVICE_CONNECTED 0x82 struct gap_device_connected_ev { - uint8_t address_type; - uint8_t address[6]; - uint16_t conn_itvl; - uint16_t conn_latency; - uint16_t supervision_timeout; + uint8_t address_type; + uint8_t address[6]; + uint16_t conn_itvl; + uint16_t conn_latency; + uint16_t supervision_timeout; } __packed; -#define GAP_EV_DEVICE_DISCONNECTED 0x83 +#define GAP_EV_DEVICE_DISCONNECTED 0x83 struct gap_device_disconnected_ev { - uint8_t address_type; - uint8_t address[6]; + uint8_t address_type; + uint8_t address[6]; } __packed; -#define GAP_EV_PASSKEY_DISPLAY 0x84 +#define GAP_EV_PASSKEY_DISPLAY 0x84 struct gap_passkey_display_ev { - uint8_t address_type; - uint8_t address[6]; - uint32_t passkey; + uint8_t address_type; + uint8_t address[6]; + uint32_t passkey; } __packed; -#define GAP_EV_PASSKEY_ENTRY_REQ 0x85 +#define GAP_EV_PASSKEY_ENTRY_REQ 0x85 struct gap_passkey_entry_req_ev { - uint8_t address_type; - uint8_t address[6]; + uint8_t address_type; + uint8_t address[6]; } __packed; -#define GAP_EV_PASSKEY_CONFIRM_REQ 0x86 +#define GAP_EV_PASSKEY_CONFIRM_REQ 0x86 struct gap_passkey_confirm_req_ev { - uint8_t address_type; - uint8_t address[6]; - uint32_t passkey; + uint8_t address_type; + uint8_t address[6]; + uint32_t passkey; } __packed; -#define GAP_EV_IDENTITY_RESOLVED 0x87 +#define GAP_EV_IDENTITY_RESOLVED 0x87 struct gap_identity_resolved_ev { - uint8_t address_type; - uint8_t address[6]; - uint8_t identity_address_type; - uint8_t identity_address[6]; + uint8_t address_type; + uint8_t address[6]; + uint8_t identity_address_type; + uint8_t identity_address[6]; } __packed; -#define GAP_EV_CONN_PARAM_UPDATE 0x88 +#define GAP_EV_CONN_PARAM_UPDATE 0x88 struct gap_conn_param_update_ev { uint8_t address_type; uint8_t address[6]; @@ -399,26 +399,26 @@ struct gap_conn_param_update_ev { uint16_t supervision_timeout; } __packed; -#define GAP_EV_SEC_LEVEL_CHANGED 0x89 +#define GAP_EV_SEC_LEVEL_CHANGED 0x89 struct gap_sec_level_changed_ev { uint8_t address_type; uint8_t address[6]; uint8_t level; } __packed; -#define GAP_EV_PAIRING_CONSENT_REQ 0x8a +#define GAP_EV_PAIRING_CONSENT_REQ 0x8a struct gap_pairing_consent_req_ev { uint8_t address_type; uint8_t address[6]; } __packed; -#define GAP_EV_BOND_LOST 0x8b +#define GAP_EV_BOND_LOST 0x8b struct gap_bond_lost_ev { uint8_t address_type; uint8_t address[6]; } __packed; -#define GAP_EV_SEC_PAIRING_FAILED 0x8c +#define GAP_EV_SEC_PAIRING_FAILED 0x8c struct gap_sec_pairing_failed_ev { uint8_t address_type; uint8_t address[6]; @@ -427,109 +427,109 @@ struct gap_sec_pairing_failed_ev { /* GATT Service */ /* commands */ -#define GATT_READ_SUPPORTED_COMMANDS 0x01 +#define GATT_READ_SUPPORTED_COMMANDS 0x01 struct gatt_read_supported_commands_rp { - uint8_t data[0]; + uint8_t data[0]; } __packed; -#define GATT_SERVICE_PRIMARY 0x00 -#define GATT_SERVICE_SECONDARY 0x01 +#define GATT_SERVICE_PRIMARY 0x00 +#define GATT_SERVICE_SECONDARY 0x01 -#define GATT_ADD_SERVICE 0x02 +#define GATT_ADD_SERVICE 0x02 struct gatt_add_service_cmd { - uint8_t type; - uint8_t uuid_length; - uint8_t uuid[0]; + uint8_t type; + uint8_t uuid_length; + uint8_t uuid[0]; } __packed; struct gatt_add_service_rp { - uint16_t svc_id; + uint16_t svc_id; } __packed; -#define GATT_ADD_CHARACTERISTIC 0x03 +#define GATT_ADD_CHARACTERISTIC 0x03 struct gatt_add_characteristic_cmd { - uint16_t svc_id; - uint8_t properties; - uint8_t permissions; - uint8_t uuid_length; - uint8_t uuid[0]; + uint16_t svc_id; + uint8_t properties; + uint8_t permissions; + uint8_t uuid_length; + uint8_t uuid[0]; } __packed; struct gatt_add_characteristic_rp { - uint16_t char_id; + uint16_t char_id; } __packed; -#define GATT_ADD_DESCRIPTOR 0x04 +#define GATT_ADD_DESCRIPTOR 0x04 struct gatt_add_descriptor_cmd { - uint16_t char_id; - uint8_t permissions; - uint8_t uuid_length; - uint8_t uuid[0]; + uint16_t char_id; + uint8_t permissions; + uint8_t uuid_length; + uint8_t uuid[0]; } __packed; struct gatt_add_descriptor_rp { - uint16_t desc_id; + uint16_t desc_id; } __packed; -#define GATT_ADD_INCLUDED_SERVICE 0x05 +#define GATT_ADD_INCLUDED_SERVICE 0x05 struct gatt_add_included_service_cmd { - uint16_t svc_id; + uint16_t svc_id; } __packed; struct gatt_add_included_service_rp { - uint16_t included_service_id; + uint16_t included_service_id; } __packed; -#define GATT_SET_VALUE 0x06 - struct gatt_set_value_cmd { - uint16_t attr_id; - uint16_t len; - uint8_t value[0]; +#define GATT_SET_VALUE 0x06 +struct gatt_set_value_cmd { + uint16_t attr_id; + uint16_t len; + uint8_t value[0]; } __packed; -#define GATT_START_SERVER 0x07 +#define GATT_START_SERVER 0x07 struct gatt_start_server_rp { - uint16_t db_attr_off; - uint8_t db_attr_cnt; + uint16_t db_attr_off; + uint8_t db_attr_cnt; } __packed; -#define GATT_SET_ENC_KEY_SIZE 0x09 +#define GATT_SET_ENC_KEY_SIZE 0x09 struct gatt_set_enc_key_size_cmd { - uint16_t attr_id; - uint8_t key_size; + uint16_t attr_id; + uint8_t key_size; } __packed; /* Gatt Client */ struct gatt_service { - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_length; - uint8_t uuid[0]; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_length; + uint8_t uuid[0]; } __packed; struct gatt_included { - uint16_t included_handle; - struct gatt_service service; + uint16_t included_handle; + struct gatt_service service; } __packed; struct gatt_read_uuid_chr { - uint16_t handle; - uint8_t data[0]; + uint16_t handle; + uint8_t data[0]; } __packed; struct gatt_characteristic { - uint16_t characteristic_handle; - uint16_t value_handle; - uint8_t properties; - uint8_t uuid_length; - uint8_t uuid[0]; + uint16_t characteristic_handle; + uint16_t value_handle; + uint8_t properties; + uint8_t uuid_length; + uint8_t uuid[0]; } __packed; struct gatt_descriptor { - uint16_t descriptor_handle; - uint8_t uuid_length; - uint8_t uuid[0]; + uint16_t descriptor_handle; + uint8_t uuid_length; + uint8_t uuid[0]; } __packed; -#define GATT_EXCHANGE_MTU 0x0a +#define GATT_EXCHANGE_MTU 0x0a -#define GATT_DISC_ALL_PRIM_SVCS 0x0b +#define GATT_DISC_ALL_PRIM_SVCS 0x0b struct gatt_disc_all_prim_svcs_cmd { uint8_t address_type; uint8_t address[6]; @@ -539,140 +539,140 @@ struct gatt_disc_all_prim_svcs_rp { struct gatt_service services[0]; } __packed; -#define GATT_DISC_PRIM_UUID 0x0c +#define GATT_DISC_PRIM_UUID 0x0c struct gatt_disc_prim_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t uuid_length; - uint8_t uuid[0]; + uint8_t address_type; + uint8_t address[6]; + uint8_t uuid_length; + uint8_t uuid[0]; } __packed; struct gatt_disc_prim_uuid_rp { - uint8_t services_count; - struct gatt_service services[0]; + uint8_t services_count; + struct gatt_service services[0]; } __packed; -#define GATT_FIND_INCLUDED 0x0d +#define GATT_FIND_INCLUDED 0x0d struct gatt_find_included_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; } __packed; struct gatt_find_included_rp { - uint8_t services_count; - struct gatt_included included[0]; + uint8_t services_count; + struct gatt_included included[0]; } __packed; -#define GATT_DISC_ALL_CHRC 0x0e +#define GATT_DISC_ALL_CHRC 0x0e struct gatt_disc_all_chrc_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; } __packed; struct gatt_disc_chrc_rp { - uint8_t characteristics_count; - struct gatt_characteristic characteristics[0]; + uint8_t characteristics_count; + struct gatt_characteristic characteristics[0]; } __packed; -#define GATT_DISC_CHRC_UUID 0x0f +#define GATT_DISC_CHRC_UUID 0x0f struct gatt_disc_chrc_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_length; - uint8_t uuid[0]; + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_length; + uint8_t uuid[0]; } __packed; -#define GATT_DISC_ALL_DESC 0x10 +#define GATT_DISC_ALL_DESC 0x10 struct gatt_disc_all_desc_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; } __packed; struct gatt_disc_all_desc_rp { - uint8_t descriptors_count; - struct gatt_descriptor descriptors[0]; + uint8_t descriptors_count; + struct gatt_descriptor descriptors[0]; } __packed; -#define GATT_READ 0x11 +#define GATT_READ 0x11 struct gatt_read_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; } __packed; struct gatt_read_rp { - uint8_t att_response; - uint16_t data_length; - uint8_t data[0]; + uint8_t att_response; + uint16_t data_length; + uint8_t data[0]; } __packed; -#define GATT_READ_UUID 0x12 +#define GATT_READ_UUID 0x12 struct gatt_read_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_length; - uint8_t uuid[0]; + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_length; + uint8_t uuid[0]; } __packed; -#define GATT_READ_LONG 0x13 +#define GATT_READ_LONG 0x13 struct gatt_read_long_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t offset; } __packed; -#define GATT_READ_MULTIPLE 0x14 +#define GATT_READ_MULTIPLE 0x14 struct gatt_read_multiple_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t handles_count; - uint16_t handles[0]; + uint8_t address_type; + uint8_t address[6]; + uint8_t handles_count; + uint16_t handles[0]; } __packed; -#define GATT_WRITE_WITHOUT_RSP 0x15 +#define GATT_WRITE_WITHOUT_RSP 0x15 struct gatt_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; } __packed; -#define GATT_SIGNED_WRITE_WITHOUT_RSP 0x16 +#define GATT_SIGNED_WRITE_WITHOUT_RSP 0x16 struct gatt_signed_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; } __packed; -#define GATT_WRITE 0x17 +#define GATT_WRITE 0x17 struct gatt_write_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; } __packed; -#define GATT_WRITE_LONG 0x18 +#define GATT_WRITE_LONG 0x18 struct gatt_write_long_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; - uint16_t data_length; - uint8_t data[0]; + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t offset; + uint16_t data_length; + uint8_t data[0]; } __packed; -#define GATT_RELIABLE_WRITE 0x19 +#define GATT_RELIABLE_WRITE 0x19 struct gatt_reliable_write_cmd { uint8_t address_type; uint8_t address[6]; @@ -682,46 +682,46 @@ struct gatt_reliable_write_cmd { uint8_t data[0]; } __packed; -#define GATT_CFG_NOTIFY 0x1a -#define GATT_CFG_INDICATE 0x1b +#define GATT_CFG_NOTIFY 0x1a +#define GATT_CFG_INDICATE 0x1b struct gatt_cfg_notify_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t enable; - uint16_t ccc_handle; + uint8_t address_type; + uint8_t address[6]; + uint8_t enable; + uint16_t ccc_handle; } __packed; -#define GATT_GET_ATTRIBUTES 0x1c +#define GATT_GET_ATTRIBUTES 0x1c struct gatt_get_attributes_cmd { - uint16_t start_handle; - uint16_t end_handle; - uint8_t type_length; - uint8_t type[0]; + uint16_t start_handle; + uint16_t end_handle; + uint8_t type_length; + uint8_t type[0]; } __packed; struct gatt_get_attributes_rp { - uint8_t attrs_count; - uint8_t attrs[0]; + uint8_t attrs_count; + uint8_t attrs[0]; } __packed; struct gatt_attr { - uint16_t handle; - uint8_t permission; - uint8_t type_length; - uint8_t type[0]; + uint16_t handle; + uint8_t permission; + uint8_t type_length; + uint8_t type[0]; } __packed; -#define GATT_GET_ATTRIBUTE_VALUE 0x1d +#define GATT_GET_ATTRIBUTE_VALUE 0x1d struct gatt_get_attribute_value_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; } __packed; struct gatt_get_attribute_value_rp { - uint8_t att_response; - uint16_t value_length; - uint8_t value[0]; + uint8_t att_response; + uint16_t value_length; + uint8_t value[0]; } __packed; -#define GATT_CHANGE_DATABASE 0x1e +#define GATT_CHANGE_DATABASE 0x1e struct gatt_change_database { uint16_t start_handle; uint16_t end_handle; @@ -729,92 +729,94 @@ struct gatt_change_database { } __packed; /* GATT events */ -#define GATT_EV_NOTIFICATION 0x80 +#define GATT_EV_NOTIFICATION 0x80 struct gatt_notification_ev { - uint8_t address_type; - uint8_t address[6]; - uint8_t type; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; + uint8_t address_type; + uint8_t address[6]; + uint8_t type; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; } __packed; -#define GATT_EV_ATTR_VALUE_CHANGED 0x81 +#define GATT_EV_ATTR_VALUE_CHANGED 0x81 struct gatt_attr_value_changed_ev { - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; } __packed; -static inline void tester_set_bit(uint8_t *addr, unsigned int bit) +static inline void +tester_set_bit(uint8_t *addr, unsigned int bit) { - uint8_t *p = addr + (bit / 8); + uint8_t *p = addr + (bit / 8); - *p |= BIT(bit % 8); + *p |= BIT(bit % 8); } -static inline uint8_t tester_test_bit(const uint8_t *addr, unsigned int bit) +static inline uint8_t +tester_test_bit(const uint8_t *addr, unsigned int bit) { - const uint8_t *p = addr + (bit / 8); + const uint8_t *p = addr + (bit / 8); - return *p & BIT(bit % 8); + return *p & BIT(bit % 8); } /* L2CAP Service */ /* commands */ -#define L2CAP_READ_SUPPORTED_COMMANDS 0x01 +#define L2CAP_READ_SUPPORTED_COMMANDS 0x01 struct l2cap_read_supported_commands_rp { - uint8_t data[0]; + uint8_t data[0]; } __packed; -#define L2CAP_CONNECT_OPT_ECFC 0x01 -#define L2CAP_CONNECT_OPT_HOLD_CREDIT 0x02 +#define L2CAP_CONNECT_OPT_ECFC 0x01 +#define L2CAP_CONNECT_OPT_HOLD_CREDIT 0x02 -#define L2CAP_CONNECT 0x02 +#define L2CAP_CONNECT 0x02 struct l2cap_connect_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t psm; - uint16_t mtu; - uint8_t num; - uint8_t options; + uint8_t address_type; + uint8_t address[6]; + uint16_t psm; + uint16_t mtu; + uint8_t num; + uint8_t options; } __packed; struct l2cap_connect_rp { - uint8_t num; - uint8_t chan_ids[0]; + uint8_t num; + uint8_t chan_ids[0]; } __packed; -#define L2CAP_DISCONNECT 0x03 +#define L2CAP_DISCONNECT 0x03 struct l2cap_disconnect_cmd { - uint8_t chan_id; + uint8_t chan_id; } __packed; -#define L2CAP_SEND_DATA 0x04 +#define L2CAP_SEND_DATA 0x04 struct l2cap_send_data_cmd { - uint8_t chan_id; - uint16_t data_len; - uint8_t data[]; + uint8_t chan_id; + uint16_t data_len; + uint8_t data[]; } __packed; -#define L2CAP_TRANSPORT_BREDR 0x00 -#define L2CAP_TRANSPORT_LE 0x01 +#define L2CAP_TRANSPORT_BREDR 0x00 +#define L2CAP_TRANSPORT_LE 0x01 -#define L2CAP_LISTEN 0x05 +#define L2CAP_LISTEN 0x05 struct l2cap_listen_cmd { - uint16_t psm; - uint8_t transport; - uint16_t mtu; - uint16_t response; + uint16_t psm; + uint8_t transport; + uint16_t mtu; + uint16_t response; } __packed; -#define L2CAP_ACCEPT_CONNECTION 0x06 +#define L2CAP_ACCEPT_CONNECTION 0x06 struct l2cap_accept_connection_cmd { - uint8_t chan_id; - uint16_t result; + uint8_t chan_id; + uint16_t result; } __packed; -#define L2CAP_RECONFIGURE 0x07 +#define L2CAP_RECONFIGURE 0x07 struct l2cap_reconfigure_cmd { uint8_t address_type; uint8_t address[6]; @@ -823,215 +825,215 @@ struct l2cap_reconfigure_cmd { uint8_t idxs[]; } __packed; -#define L2CAP_CREDITS 0x08 +#define L2CAP_CREDITS 0x08 struct l2cap_credits_cmd { uint8_t chan_id; } __packed; /* events */ -#define L2CAP_EV_CONNECTION_REQ 0x80 +#define L2CAP_EV_CONNECTION_REQ 0x80 struct l2cap_connection_req_ev { - uint8_t chan_id; - uint16_t psm; - uint8_t address_type; - uint8_t address[6]; + uint8_t chan_id; + uint16_t psm; + uint8_t address_type; + uint8_t address[6]; } __packed; -#define L2CAP_EV_CONNECTED 0x81 +#define L2CAP_EV_CONNECTED 0x81 struct l2cap_connected_ev { - uint8_t chan_id; - uint16_t psm; - uint16_t peer_mtu; - uint16_t peer_mps; - uint16_t our_mtu; - uint16_t our_mps; - uint8_t address_type; - uint8_t address[6]; + uint8_t chan_id; + uint16_t psm; + uint16_t peer_mtu; + uint16_t peer_mps; + uint16_t our_mtu; + uint16_t our_mps; + uint8_t address_type; + uint8_t address[6]; } __packed; -#define L2CAP_EV_DISCONNECTED 0x82 +#define L2CAP_EV_DISCONNECTED 0x82 struct l2cap_disconnected_ev { - uint16_t result; - uint8_t chan_id; - uint16_t psm; - uint8_t address_type; - uint8_t address[6]; + uint16_t result; + uint8_t chan_id; + uint16_t psm; + uint8_t address_type; + uint8_t address[6]; } __packed; -#define L2CAP_EV_DATA_RECEIVED 0x83 +#define L2CAP_EV_DATA_RECEIVED 0x83 struct l2cap_data_received_ev { - uint8_t chan_id; - uint16_t data_length; - uint8_t data[0]; + uint8_t chan_id; + uint16_t data_length; + uint8_t data[0]; } __packed; -#define L2CAP_EV_RECONFIGURED 0x84 +#define L2CAP_EV_RECONFIGURED 0x84 struct l2cap_reconfigured_ev { - uint8_t chan_id; - uint16_t peer_mtu; - uint16_t peer_mps; - uint16_t our_mtu; - uint16_t our_mps; + uint8_t chan_id; + uint16_t peer_mtu; + uint16_t peer_mps; + uint16_t our_mtu; + uint16_t our_mps; } __packed; /* MESH Service */ /* commands */ -#define MESH_READ_SUPPORTED_COMMANDS 0x01 +#define MESH_READ_SUPPORTED_COMMANDS 0x01 struct mesh_read_supported_commands_rp { - uint8_t data[0]; + uint8_t data[0]; } __packed; -#define MESH_OUT_BLINK BIT(0) -#define MESH_OUT_BEEP BIT(1) -#define MESH_OUT_VIBRATE BIT(2) -#define MESH_OUT_DISPLAY_NUMBER BIT(3) -#define MESH_OUT_DISPLAY_STRING BIT(4) +#define MESH_OUT_BLINK BIT(0) +#define MESH_OUT_BEEP BIT(1) +#define MESH_OUT_VIBRATE BIT(2) +#define MESH_OUT_DISPLAY_NUMBER BIT(3) +#define MESH_OUT_DISPLAY_STRING BIT(4) -#define MESH_IN_PUSH BIT(0) -#define MESH_IN_TWIST BIT(1) -#define MESH_IN_ENTER_NUMBER BIT(2) -#define MESH_IN_ENTER_STRING BIT(3) +#define MESH_IN_PUSH BIT(0) +#define MESH_IN_TWIST BIT(1) +#define MESH_IN_ENTER_NUMBER BIT(2) +#define MESH_IN_ENTER_STRING BIT(3) -#define MESH_CONFIG_PROVISIONING 0x02 +#define MESH_CONFIG_PROVISIONING 0x02 struct mesh_config_provisioning_cmd { - uint8_t uuid[16]; - uint8_t static_auth[16]; - uint8_t out_size; - uint16_t out_actions; - uint8_t in_size; - uint16_t in_actions; + uint8_t uuid[16]; + uint8_t static_auth[16]; + uint8_t out_size; + uint16_t out_actions; + uint8_t in_size; + uint16_t in_actions; } __packed; -#define MESH_PROVISION_NODE 0x03 +#define MESH_PROVISION_NODE 0x03 struct mesh_provision_node_cmd { - uint8_t net_key[16]; - uint16_t net_key_idx; - uint8_t flags; - uint32_t iv_index; - uint32_t seq_num; - uint16_t addr; - uint8_t dev_key[16]; -} __packed; - -#define MESH_INIT 0x04 -#define MESH_RESET 0x05 -#define MESH_INPUT_NUMBER 0x06 + uint8_t net_key[16]; + uint16_t net_key_idx; + uint8_t flags; + uint32_t iv_index; + uint32_t seq_num; + uint16_t addr; + uint8_t dev_key[16]; +} __packed; + +#define MESH_INIT 0x04 +#define MESH_RESET 0x05 +#define MESH_INPUT_NUMBER 0x06 struct mesh_input_number_cmd { - uint32_t number; + uint32_t number; } __packed; -#define MESH_INPUT_STRING 0x07 +#define MESH_INPUT_STRING 0x07 struct mesh_input_string_cmd { - uint8_t string_len; - uint8_t string[0]; + uint8_t string_len; + uint8_t string[0]; } __packed; -#define MESH_IVU_TEST_MODE 0x08 +#define MESH_IVU_TEST_MODE 0x08 struct mesh_ivu_test_mode_cmd { - uint8_t enable; + uint8_t enable; } __packed; -#define MESH_IVU_TOGGLE_STATE 0x09 +#define MESH_IVU_TOGGLE_STATE 0x09 -#define MESH_NET_SEND 0x0a +#define MESH_NET_SEND 0x0a struct mesh_net_send_cmd { - uint8_t ttl; - uint16_t src; - uint16_t dst; - uint8_t payload_len; - uint8_t payload[0]; + uint8_t ttl; + uint16_t src; + uint16_t dst; + uint8_t payload_len; + uint8_t payload[0]; } __packed; -#define MESH_HEALTH_GENERATE_FAULTS 0x0b +#define MESH_HEALTH_GENERATE_FAULTS 0x0b struct mesh_health_generate_faults_rp { - uint8_t test_id; - uint8_t cur_faults_count; - uint8_t reg_faults_count; - uint8_t current_faults[0]; - uint8_t registered_faults[0]; + uint8_t test_id; + uint8_t cur_faults_count; + uint8_t reg_faults_count; + uint8_t current_faults[0]; + uint8_t registered_faults[0]; } __packed; -#define MESH_HEALTH_CLEAR_FAULTS 0x0c +#define MESH_HEALTH_CLEAR_FAULTS 0x0c -#define MESH_LPN 0x0d +#define MESH_LPN 0x0d struct mesh_lpn_set_cmd { - uint8_t enable; + uint8_t enable; } __packed; -#define MESH_LPN_POLL 0x0e +#define MESH_LPN_POLL 0x0e -#define MESH_MODEL_SEND 0x0f +#define MESH_MODEL_SEND 0x0f struct mesh_model_send_cmd { - uint16_t src; - uint16_t dst; - uint8_t payload_len; - uint8_t payload[0]; + uint16_t src; + uint16_t dst; + uint8_t payload_len; + uint8_t payload[0]; } __packed; -#define MESH_LPN_SUBSCRIBE 0x10 +#define MESH_LPN_SUBSCRIBE 0x10 struct mesh_lpn_subscribe_cmd { - uint16_t address; + uint16_t address; } __packed; -#define MESH_LPN_UNSUBSCRIBE 0x11 +#define MESH_LPN_UNSUBSCRIBE 0x11 struct mesh_lpn_unsubscribe_cmd { - uint16_t address; + uint16_t address; } __packed; -#define MESH_RPL_CLEAR 0x12 -#define MESH_PROXY_IDENTITY 0x13 +#define MESH_RPL_CLEAR 0x12 +#define MESH_PROXY_IDENTITY 0x13 /* events */ -#define MESH_EV_OUT_NUMBER_ACTION 0x80 +#define MESH_EV_OUT_NUMBER_ACTION 0x80 struct mesh_out_number_action_ev { - uint16_t action; - uint32_t number; + uint16_t action; + uint32_t number; } __packed; -#define MESH_EV_OUT_STRING_ACTION 0x81 +#define MESH_EV_OUT_STRING_ACTION 0x81 struct mesh_out_string_action_ev { - uint8_t string_len; - uint8_t string[0]; + uint8_t string_len; + uint8_t string[0]; } __packed; -#define MESH_EV_IN_ACTION 0x82 +#define MESH_EV_IN_ACTION 0x82 struct mesh_in_action_ev { - uint16_t action; - uint8_t size; + uint16_t action; + uint8_t size; } __packed; -#define MESH_EV_PROVISIONED 0x83 +#define MESH_EV_PROVISIONED 0x83 -#define MESH_PROV_BEARER_PB_ADV 0x00 -#define MESH_PROV_BEARER_PB_GATT 0x01 -#define MESH_EV_PROV_LINK_OPEN 0x84 +#define MESH_PROV_BEARER_PB_ADV 0x00 +#define MESH_PROV_BEARER_PB_GATT 0x01 +#define MESH_EV_PROV_LINK_OPEN 0x84 struct mesh_prov_link_open_ev { - uint8_t bearer; + uint8_t bearer; } __packed; -#define MESH_EV_PROV_LINK_CLOSED 0x85 +#define MESH_EV_PROV_LINK_CLOSED 0x85 struct mesh_prov_link_closed_ev { - uint8_t bearer; + uint8_t bearer; } __packed; -#define MESH_EV_NET_RECV 0x86 +#define MESH_EV_NET_RECV 0x86 struct mesh_net_recv_ev { - uint8_t ttl; - uint8_t ctl; - uint16_t src; - uint16_t dst; - uint8_t payload_len; - uint8_t payload[0]; + uint8_t ttl; + uint8_t ctl; + uint16_t src; + uint16_t dst; + uint8_t payload_len; + uint8_t payload[0]; } __packed; -#define MESH_EV_INVALID_BEARER 0x87 +#define MESH_EV_INVALID_BEARER 0x87 struct mesh_invalid_bearer_ev { - uint8_t opcode; + uint8_t opcode; } __packed; -#define MESH_EV_INCOMP_TIMER_EXP 0x88 +#define MESH_EV_INCOMP_TIMER_EXP 0x88 -#define MESH_EV_LPN_ESTABLISHED 0x8b +#define MESH_EV_LPN_ESTABLISHED 0x8b struct mesh_lpn_established_ev { uint16_t net_idx; uint16_t friend_addr; @@ -1039,257 +1041,282 @@ struct mesh_lpn_established_ev { uint8_t recv_win; } __packed; -#define MESH_EV_LPN_TERMINATED 0x8c +#define MESH_EV_LPN_TERMINATED 0x8c struct mesh_lpn_terminated_ev { uint16_t net_idx; uint16_t friend_addr; } __packed; -#define MESH_EV_LPN_POLLED 0x8d +#define MESH_EV_LPN_POLLED 0x8d struct mesh_lpn_polled_ev { uint16_t net_idx; uint16_t friend_addr; uint8_t retry; } __packed; -void tester_init(void); -void tester_rsp(uint8_t service, uint8_t opcode, uint8_t index, uint8_t status); -void tester_send(uint8_t service, uint8_t opcode, uint8_t index, uint8_t *data, - size_t len); -void tester_send_buf(uint8_t service, uint8_t opcode, uint8_t index, - struct os_mbuf *buf); - -uint8_t tester_init_gap(void); -uint8_t tester_unregister_gap(void); -void tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len); -uint8_t tester_init_gatt(void); -uint8_t tester_unregister_gatt(void); -void tester_handle_gatt(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len); -void tester_handle_gattc(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len); -int tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, - uint8_t indication, struct os_mbuf *om); -int tester_gatt_subscribe_ev(uint16_t conn_handle, uint16_t attr_handle, uint8_t reason, - uint8_t prev_notify, uint8_t cur_notify, - uint8_t prev_indicate, uint8_t cur_indicate); +void +tester_init(void); +void +tester_rsp(uint8_t service, uint8_t opcode, uint8_t index, uint8_t status); +void +tester_send(uint8_t service, uint8_t opcode, uint8_t index, uint8_t *data, + size_t len); +void +tester_send_buf(uint8_t service, uint8_t opcode, uint8_t index, + struct os_mbuf *buf); + +uint8_t +tester_init_gap(void); +uint8_t +tester_unregister_gap(void); +void +tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len); +uint8_t +tester_init_gatt(void); +uint8_t +tester_unregister_gatt(void); +void +tester_handle_gatt(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len); +void +tester_handle_gattc(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len); +int +tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, + uint8_t indication, struct os_mbuf *om); +int +tester_gatt_subscribe_ev(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t reason, + uint8_t prev_notify, + uint8_t cur_notify, + uint8_t prev_indicate, + uint8_t cur_indicate); #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) -uint8_t tester_init_l2cap(void); -uint8_t tester_unregister_l2cap(void); -void tester_handle_l2cap(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len); +uint8_t +tester_init_l2cap(void); +uint8_t +tester_unregister_l2cap(void); +void +tester_handle_l2cap(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len); #endif #if MYNEWT_VAL(BLE_MESH) -uint8_t tester_init_mesh(void); -uint8_t tester_unregister_mesh(void); -void tester_handle_mesh(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len); +uint8_t +tester_init_mesh(void); +uint8_t +tester_unregister_mesh(void); +void +tester_handle_mesh(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len); #endif /* MYNEWT_VAL(BLE_MESH) */ -void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); -int gatt_svr_init(void); +void +gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); +int +gatt_svr_init(void); /* GATT Client Service */ /* commands */ #define GATTC_READ_SUPPORTED_COMMANDS 0x01 struct gattc_read_supported_commands_rp { - uint8_t data[0]; + uint8_t data[0]; } __packed; #define GATTC_EXCHANGE_MTU 0x02 #define GATTC_DISC_ALL_PRIM_SVCS 0x03 struct gattc_disc_all_prim_svcs_cmd { - uint8_t address_type; - uint8_t address[6]; + uint8_t address_type; + uint8_t address[6]; } __packed; #define GATTC_DISC_PRIM_UUID 0x04 struct gattc_disc_prim_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t uuid_length; - uint8_t uuid[0]; + uint8_t address_type; + uint8_t address[6]; + uint8_t uuid_length; + uint8_t uuid[0]; } __packed; #define GATTC_FIND_INCLUDED 0x05 struct gattc_find_included_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; } __packed; #define GATTC_DISC_ALL_CHRC 0x06 struct gattc_disc_all_chrc_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; } __packed; #define GATTC_DISC_CHRC_UUID 0x07 struct gattc_disc_chrc_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_length; - uint8_t uuid[0]; + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_length; + uint8_t uuid[0]; } __packed; #define GATTC_DISC_ALL_DESC 0x08 struct gattc_disc_all_desc_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; } __packed; #define GATTC_READ 0x09 struct gattc_read_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; } __packed; #define GATTC_READ_UUID 0x0a struct gattc_read_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_length; - uint8_t uuid[0]; + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_length; + uint8_t uuid[0]; } __packed; struct gattc_read_uuid_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint16_t data_length; - uint8_t value_length; - uint8_t data[0]; + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint16_t data_length; + uint8_t value_length; + uint8_t data[0]; } __packed; #define GATTC_READ_LONG 0x0b struct gattc_read_long_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t offset; } __packed; #define GATTC_READ_MULTIPLE 0x0c struct gattc_read_multiple_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t handles_count; - uint16_t handles[0]; + uint8_t address_type; + uint8_t address[6]; + uint8_t handles_count; + uint16_t handles[0]; } __packed; #define GATTC_WRITE_WITHOUT_RSP 0x0d struct gattc_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; } __packed; #define GATTC_SIGNED_WRITE_WITHOUT_RSP 0x0e struct gattc_signed_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; } __packed; #define GATTC_WRITE 0x0f struct gattc_write_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; } __packed; #define GATTC_WRITE_LONG 0x10 struct gattc_write_long_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; - uint16_t data_length; - uint8_t data[0]; + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t offset; + uint16_t data_length; + uint8_t data[0]; } __packed; #define GATTC_RELIABLE_WRITE 0x11 struct gattc_reliable_write_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; - uint16_t data_length; - uint8_t data[0]; + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t offset; + uint16_t data_length; + uint8_t data[0]; } __packed; #define GATTC_CFG_NOTIFY 0x12 #define GATTC_CFG_INDICATE 0x13 struct gattc_cfg_notify_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t enable; - uint16_t ccc_handle; + uint8_t address_type; + uint8_t address[6]; + uint8_t enable; + uint16_t ccc_handle; } __packed; /* events */ #define GATTC_EV_MTU_EXCHANGED 0x80 struct gattc_exchange_mtu_ev { - uint8_t address_type; - uint8_t address[6]; - uint16_t mtu; + uint8_t address_type; + uint8_t address[6]; + uint16_t mtu; } __packed; #define GATTC_DISC_ALL_PRIM_RP 0x81 struct gattc_disc_prim_svcs_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint8_t services_count; - uint8_t data[0]; + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint8_t services_count; + uint8_t data[0]; } __packed; #define GATTC_DISC_PRIM_UUID_RP 0x82 #define GATTC_FIND_INCLUDED_RP 0x83 struct gattc_find_included_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint8_t services_count; - struct gatt_included included[0]; + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint8_t services_count; + struct gatt_included included[0]; } __packed; #define GATTC_DISC_ALL_CHRC_RP 0x84 #define GATTC_DISC_CHRC_UUID_RP 0x85 struct gattc_disc_chrc_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint8_t characteristics_count; - struct gatt_characteristic characteristics[0]; + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint8_t characteristics_count; + struct gatt_characteristic characteristics[0]; } __packed; #define GATTC_DISC_ALL_DESC_RP 0x86 struct gattc_disc_all_desc_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint8_t descriptors_count; - struct gatt_descriptor descriptors[0]; + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint8_t descriptors_count; + struct gatt_descriptor descriptors[0]; } __packed; #define GATTC_READ_RP 0x87 @@ -1297,18 +1324,18 @@ struct gattc_disc_all_desc_rp { #define GATTC_READ_LONG_RP 0x89 #define GATTC_READ_MULTIPLE_RP 0x8a struct gattc_read_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint16_t data_length; - uint8_t data[0]; + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint16_t data_length; + uint8_t data[0]; } __packed; #define GATTC_WRITE_RP 0x8b struct gattc_write_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; + uint8_t address_type; + uint8_t address[6]; + uint8_t status; } __packed; #define GATTC_WRITE_LONG_RP 0x8c #define GATTC_RELIABLE_WRITE_RP 0x8d @@ -1316,19 +1343,19 @@ struct gattc_write_rp { #define GATTC_CFG_NOTIFY_RP 0x8e #define GATTC_CFG_INDICATE_RP 0x8f struct subscribe_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; + uint8_t address_type; + uint8_t address[6]; + uint8_t status; } __packed; #define GATTC_EV_NOTIFICATION_RXED 0x90 struct gattc_notification_ev { - uint8_t address_type; - uint8_t address[6]; - uint8_t type; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; + uint8_t address_type; + uint8_t address[6]; + uint8_t type; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; } __packed; #endif /* __BTTESTER_H__ */ diff --git a/apps/bttester/src/bttester_pipe.h b/apps/bttester/src/bttester_pipe.h index 64b63cd6a1..5f27a41c2c 100644 --- a/apps/bttester/src/bttester_pipe.h +++ b/apps/bttester/src/bttester_pipe.h @@ -28,10 +28,14 @@ extern "C" { #endif typedef uint8_t *(*bttester_pipe_recv_cb)(uint8_t *buf, size_t *off); -void bttester_pipe_register(uint8_t *buf, size_t len, bttester_pipe_recv_cb cb); -int bttester_pipe_send(const uint8_t *data, int len); -int bttester_pipe_send_buf(struct os_mbuf *buf); -int bttester_pipe_init(void); +void +bttester_pipe_register(uint8_t *buf, size_t len, bttester_pipe_recv_cb cb); +int +bttester_pipe_send(const uint8_t *data, int len); +int +bttester_pipe_send_buf(struct os_mbuf *buf); +int +bttester_pipe_init(void); #ifdef __cplusplus } diff --git a/apps/bttester/src/gap.c b/apps/bttester/src/gap.c index aee9591cca..655a82ec3d 100644 --- a/apps/bttester/src/gap.c +++ b/apps/bttester/src/gap.c @@ -48,8 +48,8 @@ #define REJECT_SUPERVISION_TIMEOUT 0x0C80 const uint8_t irk[16] = { - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, }; static uint8_t oob[16]; @@ -75,174 +75,179 @@ static struct os_callout bttester_nrpa_rotate_timer; #endif static const struct ble_gap_conn_params dflt_conn_params = { - .scan_itvl = 0x0010, - .scan_window = 0x0010, - .itvl_min = BLE_GAP_INITIAL_CONN_ITVL_MIN, - .itvl_max = BLE_GAP_INITIAL_CONN_ITVL_MAX, - .latency = 0, - .supervision_timeout = 0x0100, - .min_ce_len = 0x0010, - .max_ce_len = 0x0300, + .scan_itvl = 0x0010, + .scan_window = 0x0010, + .itvl_min = BLE_GAP_INITIAL_CONN_ITVL_MIN, + .itvl_max = BLE_GAP_INITIAL_CONN_ITVL_MAX, + .latency = 0, + .supervision_timeout = 0x0100, + .min_ce_len = 0x0010, + .max_ce_len = 0x0300, }; -static void conn_param_update(struct os_event *ev); +static void +conn_param_update(struct os_event *ev); - -static int gap_conn_find_by_addr(const ble_addr_t *dev_addr, - struct ble_gap_conn_desc *out_desc) +static int +gap_conn_find_by_addr(const ble_addr_t *dev_addr, + struct ble_gap_conn_desc *out_desc) { - ble_addr_t addr = *dev_addr; - - if (memcmp(BLE_ADDR_ANY, &peer_id_addr, 6) == 0) { - return ble_gap_conn_find_by_addr(&addr, out_desc); - } - - if (BLE_ADDR_IS_RPA(&addr)) { - if(ble_addr_cmp(&peer_ota_addr, &addr) != 0) { - return -1; - } - - return ble_gap_conn_find_by_addr(&addr, out_desc); - } else { - if(ble_addr_cmp(&peer_id_addr, &addr) != 0) { - return -1; - } - - if (BLE_ADDR_IS_RPA(&peer_ota_addr)) { - /* Change addr type to ID addr */ - addr.type |= 2; - } - - return ble_gap_conn_find_by_addr(&addr, out_desc); - } + ble_addr_t addr = *dev_addr; + + if (memcmp(BLE_ADDR_ANY, &peer_id_addr, 6) == 0) { + return ble_gap_conn_find_by_addr(&addr, out_desc); + } + + if (BLE_ADDR_IS_RPA(&addr)) { + if (ble_addr_cmp(&peer_ota_addr, &addr) != 0) { + return -1; + } + + return ble_gap_conn_find_by_addr(&addr, out_desc); + } else { + if (ble_addr_cmp(&peer_id_addr, &addr) != 0) { + return -1; + } + + if (BLE_ADDR_IS_RPA(&peer_ota_addr)) { + /* Change addr type to ID addr */ + addr.type |= 2; + } + + return ble_gap_conn_find_by_addr(&addr, out_desc); + } } -static int gap_event_cb(struct ble_gap_event *event, void *arg); +static int +gap_event_cb(struct ble_gap_event *event, void *arg); -static void supported_commands(uint8_t *data, uint16_t len) +static void +supported_commands(uint8_t *data, uint16_t len) { - uint8_t cmds[3]; - struct gap_read_supported_commands_rp *rp = (void *) &cmds; - - SYS_LOG_DBG(""); - - memset(cmds, 0, sizeof(cmds)); - - tester_set_bit(cmds, GAP_READ_SUPPORTED_COMMANDS); - tester_set_bit(cmds, GAP_READ_CONTROLLER_INDEX_LIST); - tester_set_bit(cmds, GAP_READ_CONTROLLER_INFO); - tester_set_bit(cmds, GAP_SET_CONNECTABLE); - tester_set_bit(cmds, GAP_SET_DISCOVERABLE); - tester_set_bit(cmds, GAP_SET_BONDABLE); - tester_set_bit(cmds, GAP_START_ADVERTISING); - tester_set_bit(cmds, GAP_STOP_ADVERTISING); - tester_set_bit(cmds, GAP_START_DISCOVERY); - tester_set_bit(cmds, GAP_STOP_DISCOVERY); - tester_set_bit(cmds, GAP_CONNECT); - tester_set_bit(cmds, GAP_DISCONNECT); - tester_set_bit(cmds, GAP_SET_IO_CAP); - tester_set_bit(cmds, GAP_PAIR); - tester_set_bit(cmds, GAP_UNPAIR); - tester_set_bit(cmds, GAP_PASSKEY_ENTRY); - tester_set_bit(cmds, GAP_PASSKEY_CONFIRM); - tester_set_bit(cmds, GAP_START_DIRECT_ADV); - tester_set_bit(cmds, GAP_CONN_PARAM_UPDATE); - tester_set_bit(cmds, GAP_OOB_LEGACY_SET_DATA); - tester_set_bit(cmds, GAP_OOB_SC_GET_LOCAL_DATA); - tester_set_bit(cmds, GAP_OOB_SC_SET_REMOTE_DATA); - tester_set_bit(cmds, GAP_SET_MITM); - - tester_send(BTP_SERVICE_ID_GAP, GAP_READ_SUPPORTED_COMMANDS, - CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); + uint8_t cmds[3]; + struct gap_read_supported_commands_rp *rp = (void *) &cmds; + + SYS_LOG_DBG(""); + + memset(cmds, 0, sizeof(cmds)); + + tester_set_bit(cmds, GAP_READ_SUPPORTED_COMMANDS); + tester_set_bit(cmds, GAP_READ_CONTROLLER_INDEX_LIST); + tester_set_bit(cmds, GAP_READ_CONTROLLER_INFO); + tester_set_bit(cmds, GAP_SET_CONNECTABLE); + tester_set_bit(cmds, GAP_SET_DISCOVERABLE); + tester_set_bit(cmds, GAP_SET_BONDABLE); + tester_set_bit(cmds, GAP_START_ADVERTISING); + tester_set_bit(cmds, GAP_STOP_ADVERTISING); + tester_set_bit(cmds, GAP_START_DISCOVERY); + tester_set_bit(cmds, GAP_STOP_DISCOVERY); + tester_set_bit(cmds, GAP_CONNECT); + tester_set_bit(cmds, GAP_DISCONNECT); + tester_set_bit(cmds, GAP_SET_IO_CAP); + tester_set_bit(cmds, GAP_PAIR); + tester_set_bit(cmds, GAP_UNPAIR); + tester_set_bit(cmds, GAP_PASSKEY_ENTRY); + tester_set_bit(cmds, GAP_PASSKEY_CONFIRM); + tester_set_bit(cmds, GAP_START_DIRECT_ADV); + tester_set_bit(cmds, GAP_CONN_PARAM_UPDATE); + tester_set_bit(cmds, GAP_OOB_LEGACY_SET_DATA); + tester_set_bit(cmds, GAP_OOB_SC_GET_LOCAL_DATA); + tester_set_bit(cmds, GAP_OOB_SC_SET_REMOTE_DATA); + tester_set_bit(cmds, GAP_SET_MITM); + + tester_send(BTP_SERVICE_ID_GAP, GAP_READ_SUPPORTED_COMMANDS, + CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); } -static void controller_index_list(uint8_t *data, uint16_t len) +static void +controller_index_list(uint8_t *data, uint16_t len) { - struct gap_read_controller_index_list_rp *rp; - uint8_t buf[sizeof(*rp) + 1]; + struct gap_read_controller_index_list_rp *rp; + uint8_t buf[sizeof(*rp) + 1]; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rp = (void *) buf; + rp = (void *) buf; - rp->num = 1; - rp->index[0] = CONTROLLER_INDEX; + rp->num = 1; + rp->index[0] = CONTROLLER_INDEX; - tester_send(BTP_SERVICE_ID_GAP, GAP_READ_CONTROLLER_INDEX_LIST, - BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); + tester_send(BTP_SERVICE_ID_GAP, GAP_READ_CONTROLLER_INDEX_LIST, + BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); } -static void controller_info(uint8_t *data, uint16_t len) +static void +controller_info(uint8_t *data, uint16_t len) { - struct gap_read_controller_info_rp rp; - uint32_t supported_settings = 0; - ble_addr_t addr; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_hs_pvcy_set_our_irk(irk); - assert(rc == 0); - - memset(&rp, 0, sizeof(rp)); - - /* Make sure we have proper identity address set (public preferred) */ - rc = ble_hs_util_ensure_addr(1); - assert(rc == 0); - rc = ble_hs_id_copy_addr(BLE_ADDR_RANDOM, addr.val, NULL); - assert(rc == 0); - - if (MYNEWT_VAL(BTTESTER_PRIVACY_MODE)) { - if (MYNEWT_VAL(BTTESTER_USE_NRPA)) { - own_addr_type = BLE_OWN_ADDR_RANDOM; - rc = ble_hs_id_gen_rnd(1, &addr); - assert(rc == 0); - rc = ble_hs_id_set_rnd(addr.val); - assert(rc == 0); - } else { - own_addr_type = BLE_OWN_ADDR_RPA_RANDOM_DEFAULT; - } - current_settings |= BIT(GAP_SETTINGS_PRIVACY); - supported_settings |= BIT(GAP_SETTINGS_PRIVACY); - memcpy(rp.address, addr.val, sizeof(rp.address)); - } else { - rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, rp.address, NULL); - if (rc) { - own_addr_type = BLE_OWN_ADDR_RANDOM; - memcpy(rp.address, addr.val, sizeof(rp.address)); - supported_settings |= BIT(GAP_SETTINGS_STATIC_ADDRESS); - current_settings |= BIT(GAP_SETTINGS_STATIC_ADDRESS); - } else { - own_addr_type = BLE_OWN_ADDR_PUBLIC; - } - } - - supported_settings |= BIT(GAP_SETTINGS_POWERED); - supported_settings |= BIT(GAP_SETTINGS_CONNECTABLE); - supported_settings |= BIT(GAP_SETTINGS_BONDABLE); - supported_settings |= BIT(GAP_SETTINGS_LE); - supported_settings |= BIT(GAP_SETTINGS_ADVERTISING); - supported_settings |= BIT(GAP_SETTINGS_SC); - - if (ble_hs_cfg.sm_bonding) { - current_settings |= BIT(GAP_SETTINGS_BONDABLE); - } - if (ble_hs_cfg.sm_sc) { - current_settings |= BIT(GAP_SETTINGS_SC); - } - - rp.supported_settings = sys_cpu_to_le32(supported_settings); - rp.current_settings = sys_cpu_to_le32(current_settings); - - memcpy(rp.name, CONTROLLER_NAME, sizeof(CONTROLLER_NAME)); - - tester_send(BTP_SERVICE_ID_GAP, GAP_READ_CONTROLLER_INFO, - CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); + struct gap_read_controller_info_rp rp; + uint32_t supported_settings = 0; + ble_addr_t addr; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_hs_pvcy_set_our_irk(irk); + assert(rc == 0); + + memset(&rp, 0, sizeof(rp)); + + /* Make sure we have proper identity address set (public preferred) */ + rc = ble_hs_util_ensure_addr(1); + assert(rc == 0); + rc = ble_hs_id_copy_addr(BLE_ADDR_RANDOM, addr.val, NULL); + assert(rc == 0); + + if (MYNEWT_VAL(BTTESTER_PRIVACY_MODE)) { + if (MYNEWT_VAL(BTTESTER_USE_NRPA)) { + own_addr_type = BLE_OWN_ADDR_RANDOM; + rc = ble_hs_id_gen_rnd(1, &addr); + assert(rc == 0); + rc = ble_hs_id_set_rnd(addr.val); + assert(rc == 0); + } else { + own_addr_type = BLE_OWN_ADDR_RPA_RANDOM_DEFAULT; + } + current_settings |= BIT(GAP_SETTINGS_PRIVACY); + supported_settings |= BIT(GAP_SETTINGS_PRIVACY); + memcpy(rp.address, addr.val, sizeof(rp.address)); + } else { + rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, rp.address, NULL); + if (rc) { + own_addr_type = BLE_OWN_ADDR_RANDOM; + memcpy(rp.address, addr.val, sizeof(rp.address)); + supported_settings |= BIT(GAP_SETTINGS_STATIC_ADDRESS); + current_settings |= BIT(GAP_SETTINGS_STATIC_ADDRESS); + } else { + own_addr_type = BLE_OWN_ADDR_PUBLIC; + } + } + + supported_settings |= BIT(GAP_SETTINGS_POWERED); + supported_settings |= BIT(GAP_SETTINGS_CONNECTABLE); + supported_settings |= BIT(GAP_SETTINGS_BONDABLE); + supported_settings |= BIT(GAP_SETTINGS_LE); + supported_settings |= BIT(GAP_SETTINGS_ADVERTISING); + supported_settings |= BIT(GAP_SETTINGS_SC); + + if (ble_hs_cfg.sm_bonding) { + current_settings |= BIT(GAP_SETTINGS_BONDABLE); + } + if (ble_hs_cfg.sm_sc) { + current_settings |= BIT(GAP_SETTINGS_SC); + } + + rp.supported_settings = sys_cpu_to_le32(supported_settings); + rp.current_settings = sys_cpu_to_le32(current_settings); + + memcpy(rp.name, CONTROLLER_NAME, sizeof(CONTROLLER_NAME)); + + tester_send(BTP_SERVICE_ID_GAP, GAP_READ_CONTROLLER_INFO, + CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); } static struct ble_gap_adv_params adv_params = { - .conn_mode = BLE_GAP_CONN_MODE_NON, - .disc_mode = BLE_GAP_DISC_MODE_NON, + .conn_mode = BLE_GAP_CONN_MODE_NON, + .disc_mode = BLE_GAP_DISC_MODE_NON, }; #if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) @@ -277,406 +282,417 @@ static void rotate_nrpa_cb(struct os_event *ev) } #endif -static void set_connectable(uint8_t *data, uint16_t len) +static void +set_connectable(uint8_t *data, uint16_t len) { - const struct gap_set_connectable_cmd *cmd = (void *) data; - struct gap_set_connectable_rp rp; + const struct gap_set_connectable_cmd *cmd = (void *) data; + struct gap_set_connectable_rp rp; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - if (cmd->connectable) { - current_settings |= BIT(GAP_SETTINGS_CONNECTABLE); - adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; - } else { - current_settings &= ~BIT(GAP_SETTINGS_CONNECTABLE); - adv_params.conn_mode = BLE_GAP_CONN_MODE_NON; - } + if (cmd->connectable) { + current_settings |= BIT(GAP_SETTINGS_CONNECTABLE); + adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; + } else { + current_settings &= ~BIT(GAP_SETTINGS_CONNECTABLE); + adv_params.conn_mode = BLE_GAP_CONN_MODE_NON; + } - rp.current_settings = sys_cpu_to_le32(current_settings); + rp.current_settings = sys_cpu_to_le32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, GAP_SET_CONNECTABLE, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); + tester_send(BTP_SERVICE_ID_GAP, GAP_SET_CONNECTABLE, CONTROLLER_INDEX, + (uint8_t *) &rp, sizeof(rp)); } static uint8_t ad_flags = BLE_HS_ADV_F_BREDR_UNSUP; -static void set_discoverable(uint8_t *data, uint16_t len) +static void +set_discoverable(uint8_t *data, uint16_t len) { - const struct gap_set_discoverable_cmd *cmd = (void *) data; - struct gap_set_discoverable_rp rp; - - SYS_LOG_DBG(""); - - switch (cmd->discoverable) { - case GAP_NON_DISCOVERABLE: - ad_flags &= ~(BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_DISC_LTD); - adv_params.disc_mode = BLE_GAP_DISC_MODE_NON; - current_settings &= ~BIT(GAP_SETTINGS_DISCOVERABLE); - break; - case GAP_GENERAL_DISCOVERABLE: - ad_flags &= ~BLE_HS_ADV_F_DISC_LTD; - ad_flags |= BLE_HS_ADV_F_DISC_GEN; - adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; - current_settings |= BIT(GAP_SETTINGS_DISCOVERABLE); - break; - case GAP_LIMITED_DISCOVERABLE: - ad_flags &= ~BLE_HS_ADV_F_DISC_GEN; - ad_flags |= BLE_HS_ADV_F_DISC_LTD; - adv_params.disc_mode = BLE_GAP_DISC_MODE_LTD; - current_settings |= BIT(GAP_SETTINGS_DISCOVERABLE); - break; - default: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_DISCOVERABLE, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - return; - } - - rp.current_settings = sys_cpu_to_le32(current_settings); - - tester_send(BTP_SERVICE_ID_GAP, GAP_SET_DISCOVERABLE, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); + const struct gap_set_discoverable_cmd *cmd = (void *) data; + struct gap_set_discoverable_rp rp; + + SYS_LOG_DBG(""); + + switch (cmd->discoverable) { + case GAP_NON_DISCOVERABLE: + ad_flags &= ~(BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_DISC_LTD); + adv_params.disc_mode = BLE_GAP_DISC_MODE_NON; + current_settings &= ~BIT(GAP_SETTINGS_DISCOVERABLE); + break; + case GAP_GENERAL_DISCOVERABLE: + ad_flags &= ~BLE_HS_ADV_F_DISC_LTD; + ad_flags |= BLE_HS_ADV_F_DISC_GEN; + adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + current_settings |= BIT(GAP_SETTINGS_DISCOVERABLE); + break; + case GAP_LIMITED_DISCOVERABLE: + ad_flags &= ~BLE_HS_ADV_F_DISC_GEN; + ad_flags |= BLE_HS_ADV_F_DISC_LTD; + adv_params.disc_mode = BLE_GAP_DISC_MODE_LTD; + current_settings |= BIT(GAP_SETTINGS_DISCOVERABLE); + break; + default: + tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_DISCOVERABLE, + CONTROLLER_INDEX, BTP_STATUS_FAILED); + return; + } + + rp.current_settings = sys_cpu_to_le32(current_settings); + + tester_send(BTP_SERVICE_ID_GAP, GAP_SET_DISCOVERABLE, CONTROLLER_INDEX, + (uint8_t *) &rp, sizeof(rp)); } -static void set_bondable(const uint8_t *data, uint16_t len) +static void +set_bondable(const uint8_t *data, uint16_t len) { - const struct gap_set_bondable_cmd *cmd = (void *) data; - struct gap_set_bondable_rp rp; + const struct gap_set_bondable_cmd *cmd = (void *) data; + struct gap_set_bondable_rp rp; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - ble_hs_cfg.sm_bonding = cmd->bondable; - if (ble_hs_cfg.sm_bonding) { - current_settings |= BIT(GAP_SETTINGS_BONDABLE); - } else { - current_settings &= ~BIT(GAP_SETTINGS_BONDABLE); - } + ble_hs_cfg.sm_bonding = cmd->bondable; + if (ble_hs_cfg.sm_bonding) { + current_settings |= BIT(GAP_SETTINGS_BONDABLE); + } else { + current_settings &= ~BIT(GAP_SETTINGS_BONDABLE); + } - rp.current_settings = sys_cpu_to_le32(current_settings); + rp.current_settings = sys_cpu_to_le32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, GAP_SET_BONDABLE, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); + tester_send(BTP_SERVICE_ID_GAP, GAP_SET_BONDABLE, CONTROLLER_INDEX, + (uint8_t *) &rp, sizeof(rp)); } static struct bt_data ad[10] = { - BT_DATA(BLE_HS_ADV_TYPE_FLAGS, &ad_flags, sizeof(ad_flags)), + BT_DATA(BLE_HS_ADV_TYPE_FLAGS, &ad_flags, sizeof(ad_flags)), }; static struct bt_data sd[10]; -static int set_ad(const struct bt_data *ad, size_t ad_len, - uint8_t *buf, uint8_t *buf_len) +static int +set_ad(const struct bt_data *ad, size_t ad_len, + uint8_t *buf, uint8_t *buf_len) { - int i; + int i; - for (i = 0; i < ad_len; i++) { - buf[(*buf_len)++] = ad[i].data_len + 1; - buf[(*buf_len)++] = ad[i].type; + for (i = 0; i < ad_len; i++) { + buf[(*buf_len)++] = ad[i].data_len + 1; + buf[(*buf_len)++] = ad[i].type; - memcpy(&buf[*buf_len], ad[i].data, - ad[i].data_len); - *buf_len += ad[i].data_len; - } + memcpy(&buf[*buf_len], ad[i].data, + ad[i].data_len); + *buf_len += ad[i].data_len; + } - return 0; + return 0; } -static void start_advertising(const uint8_t *data, uint16_t len) +static void +start_advertising(const uint8_t *data, uint16_t len) { - const struct gap_start_advertising_cmd *cmd = (void *) data; - struct gap_start_advertising_rp rp; - int32_t duration_ms = BLE_HS_FOREVER; - uint8_t buf[BLE_HS_ADV_MAX_SZ]; - uint8_t buf_len = 0; - uint8_t adv_len, sd_len; - int err; - - int i; - - SYS_LOG_DBG(""); - - for (i = 0, adv_len = 1; i < cmd->adv_data_len; adv_len++) { - if (adv_len >= ARRAY_SIZE(ad)) { - SYS_LOG_ERR("ad[] Out of memory"); - goto fail; - } - - ad[adv_len].type = cmd->adv_data[i++]; - ad[adv_len].data_len = cmd->adv_data[i++]; - ad[adv_len].data = &cmd->adv_data[i]; - i += ad[adv_len].data_len; - } - - for (i = 0, sd_len = 0; i < cmd->scan_rsp_len; sd_len++) { - if (sd_len >= ARRAY_SIZE(sd)) { - SYS_LOG_ERR("sd[] Out of memory"); - goto fail; - } - - sd[sd_len].type = cmd->scan_rsp[i++]; - sd[sd_len].data_len = cmd->scan_rsp[i++]; - sd[sd_len].data = &cmd->scan_rsp[i]; - i += sd[sd_len].data_len; - } - - err = set_ad(ad, adv_len, buf, &buf_len); - if (err) { - goto fail; - } - - err = ble_gap_adv_set_data(buf, buf_len); - if (err != 0) { - goto fail; - } - - if (sd_len) { - buf_len = 0; - - err = set_ad(sd, sd_len, buf, &buf_len); - if (err) { - SYS_LOG_ERR("Advertising failed: err %d", err); - goto fail; - } - - err = ble_gap_adv_rsp_set_data(buf, buf_len); - if (err != 0) { - SYS_LOG_ERR("Advertising failed: err %d", err); - goto fail; - } - } - - if (adv_params.disc_mode == BLE_GAP_DISC_MODE_LTD) { - duration_ms = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); - } + const struct gap_start_advertising_cmd *cmd = (void *) data; + struct gap_start_advertising_rp rp; + int32_t duration_ms = BLE_HS_FOREVER; + uint8_t buf[BLE_HS_ADV_MAX_SZ]; + uint8_t buf_len = 0; + uint8_t adv_len, sd_len; + int err; + + int i; + + SYS_LOG_DBG(""); + + for (i = 0, adv_len = 1; i < cmd->adv_data_len; adv_len++) { + if (adv_len >= ARRAY_SIZE(ad)) { + SYS_LOG_ERR("ad[] Out of memory"); + goto fail; + } + + ad[adv_len].type = cmd->adv_data[i++]; + ad[adv_len].data_len = cmd->adv_data[i++]; + ad[adv_len].data = &cmd->adv_data[i]; + i += ad[adv_len].data_len; + } + + for (i = 0, sd_len = 0; i < cmd->scan_rsp_len; sd_len++) { + if (sd_len >= ARRAY_SIZE(sd)) { + SYS_LOG_ERR("sd[] Out of memory"); + goto fail; + } + + sd[sd_len].type = cmd->scan_rsp[i++]; + sd[sd_len].data_len = cmd->scan_rsp[i++]; + sd[sd_len].data = &cmd->scan_rsp[i]; + i += sd[sd_len].data_len; + } + + err = set_ad(ad, adv_len, buf, &buf_len); + if (err) { + goto fail; + } + + err = ble_gap_adv_set_data(buf, buf_len); + if (err != 0) { + goto fail; + } + + if (sd_len) { + buf_len = 0; + + err = set_ad(sd, sd_len, buf, &buf_len); + if (err) { + SYS_LOG_ERR("Advertising failed: err %d", err); + goto fail; + } + + err = ble_gap_adv_rsp_set_data(buf, buf_len); + if (err != 0) { + SYS_LOG_ERR("Advertising failed: err %d", err); + goto fail; + } + } + + if (adv_params.disc_mode == BLE_GAP_DISC_MODE_LTD) { + duration_ms = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); + } #if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) - if (MYNEWT_VAL(BTTESTER_NRPA_TIMEOUT) < duration_ms / 1000) { - advertising_start = os_get_uptime_usec(); - os_callout_reset(&bttester_nrpa_rotate_timer, + if (MYNEWT_VAL(BTTESTER_NRPA_TIMEOUT) < duration_ms / 1000) { + advertising_start = os_get_uptime_usec(); + os_callout_reset(&bttester_nrpa_rotate_timer, OS_TICKS_PER_SEC * MYNEWT_VAL(BTTESTER_NRPA_TIMEOUT)); - } + } #endif - err = ble_gap_adv_start(own_addr_type, NULL, duration_ms, - &adv_params, gap_event_cb, NULL); - if (err) { - SYS_LOG_ERR("Advertising failed: err %d", err); - goto fail; - } - - current_settings |= BIT(GAP_SETTINGS_ADVERTISING); - rp.current_settings = sys_cpu_to_le32(current_settings); - - tester_send(BTP_SERVICE_ID_GAP, GAP_START_ADVERTISING, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); - return; + err = ble_gap_adv_start(own_addr_type, NULL, duration_ms, + &adv_params, gap_event_cb, NULL); + if (err) { + SYS_LOG_ERR("Advertising failed: err %d", err); + goto fail; + } + + current_settings |= BIT(GAP_SETTINGS_ADVERTISING); + rp.current_settings = sys_cpu_to_le32(current_settings); + + tester_send(BTP_SERVICE_ID_GAP, GAP_START_ADVERTISING, CONTROLLER_INDEX, + (uint8_t *) &rp, sizeof(rp)); + return; fail: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_ADVERTISING, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_ADVERTISING, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static void stop_advertising(const uint8_t *data, uint16_t len) +static void +stop_advertising(const uint8_t *data, uint16_t len) { - struct gap_stop_advertising_rp rp; + struct gap_stop_advertising_rp rp; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - if (ble_gap_adv_stop() != 0) { - tester_rsp(BTP_SERVICE_ID_GAP, GAP_STOP_ADVERTISING, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - return; - } + if (ble_gap_adv_stop() != 0) { + tester_rsp(BTP_SERVICE_ID_GAP, GAP_STOP_ADVERTISING, + CONTROLLER_INDEX, BTP_STATUS_FAILED); + return; + } - current_settings &= ~BIT(GAP_SETTINGS_ADVERTISING); - rp.current_settings = sys_cpu_to_le32(current_settings); + current_settings &= ~BIT(GAP_SETTINGS_ADVERTISING); + rp.current_settings = sys_cpu_to_le32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, GAP_STOP_ADVERTISING, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); + tester_send(BTP_SERVICE_ID_GAP, GAP_STOP_ADVERTISING, CONTROLLER_INDEX, + (uint8_t *) &rp, sizeof(rp)); } -static uint8_t get_ad_flags(const uint8_t *data, uint8_t data_len) +static uint8_t +get_ad_flags(const uint8_t *data, uint8_t data_len) { - uint8_t len, i; - - /* Parse advertisement to get flags */ - for (i = 0; i < data_len; i += len - 1) { - len = data[i++]; - if (!len) { - break; - } - - /* Check if field length is correct */ - if (len > (data_len - i) || (data_len - i) < 1) { - break; - } - - switch (data[i++]) { - case BLE_HS_ADV_TYPE_FLAGS: - return data[i]; - default: - break; - } - } - - return 0; + uint8_t len, i; + + /* Parse advertisement to get flags */ + for (i = 0; i < data_len; i += len - 1) { + len = data[i++]; + if (!len) { + break; + } + + /* Check if field length is correct */ + if (len > (data_len - i) || (data_len - i) < 1) { + break; + } + + switch (data[i++]) { + case BLE_HS_ADV_TYPE_FLAGS: + return data[i]; + default: + break; + } + } + + return 0; } static uint8_t discovery_flags; static struct os_mbuf *adv_buf; -static void store_adv(const ble_addr_t *addr, int8_t rssi, - const uint8_t *data, uint8_t len) +static void +store_adv(const ble_addr_t *addr, int8_t rssi, + const uint8_t *data, uint8_t len) { - struct gap_device_found_ev *ev; + struct gap_device_found_ev *ev; - /* cleanup */ - net_buf_simple_init(adv_buf, 0); + /* cleanup */ + net_buf_simple_init(adv_buf, 0); - ev = net_buf_simple_add(adv_buf, sizeof(*ev)); + ev = net_buf_simple_add(adv_buf, sizeof(*ev)); - memcpy(ev->address, addr->val, sizeof(ev->address)); - ev->address_type = addr->type; - ev->rssi = rssi; - ev->flags = GAP_DEVICE_FOUND_FLAG_AD | GAP_DEVICE_FOUND_FLAG_RSSI; - ev->eir_data_len = len; - memcpy(net_buf_simple_add(adv_buf, len), data, len); + memcpy(ev->address, addr->val, sizeof(ev->address)); + ev->address_type = addr->type; + ev->rssi = rssi; + ev->flags = GAP_DEVICE_FOUND_FLAG_AD | GAP_DEVICE_FOUND_FLAG_RSSI; + ev->eir_data_len = len; + memcpy(net_buf_simple_add(adv_buf, len), data, len); } -static void device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, - const uint8_t *data, uint8_t len) +static void +device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, + const uint8_t *data, uint8_t len) { - struct gap_device_found_ev *ev; - ble_addr_t a; - - /* if General/Limited Discovery - parse Advertising data to get flags */ - if (!(discovery_flags & GAP_DISCOVERY_FLAG_LE_OBSERVE) && - (evtype != BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP)) { - uint8_t flags = get_ad_flags(data, len); - - /* ignore non-discoverable devices */ - if (!(flags & BLE_AD_DISCOV_MASK)) { - SYS_LOG_DBG("Non discoverable, skipping"); - return; - } - - /* if Limited Discovery - ignore general discoverable devices */ - if ((discovery_flags & GAP_DISCOVERY_FLAG_LIMITED) && - !(flags & BLE_HS_ADV_F_DISC_LTD)) { - SYS_LOG_DBG("General discoverable, skipping"); - return; - } - } - - /* attach Scan Response data */ - if (evtype == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) { - /* skip if there is no pending advertisement */ - if (!adv_buf->om_len) { - SYS_LOG_INF("No pending advertisement, skipping"); - return; - } - - ev = (void *) adv_buf->om_data; - a.type = ev->address_type; - memcpy(a.val, ev->address, sizeof(a.val)); - - /* - * in general, the Scan Response comes right after the - * Advertisement, but if not if send stored event and ignore - * this one - */ - if (ble_addr_cmp(addr, &a)) { - SYS_LOG_INF("Address does not match, skipping"); - goto done; - } - - ev->eir_data_len += len; - ev->flags |= GAP_DEVICE_FOUND_FLAG_SD; - - memcpy(net_buf_simple_add(adv_buf, len), data, len); - - goto done; - } - - /* - * if there is another pending advertisement, send it and store the - * current one - */ - if (adv_buf->om_len) { - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_FOUND, - CONTROLLER_INDEX, adv_buf->om_data, - adv_buf->om_len); - } - - store_adv(addr, rssi, data, len); - - /* if Active Scan and scannable event - wait for Scan Response */ - if ((discovery_flags & GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN) && - (evtype == BLE_HCI_ADV_RPT_EVTYPE_ADV_IND || - evtype == BLE_HCI_ADV_RPT_EVTYPE_SCAN_IND)) { - SYS_LOG_DBG("Waiting for scan response"); - return; - } + struct gap_device_found_ev *ev; + ble_addr_t a; + + /* if General/Limited Discovery - parse Advertising data to get flags */ + if (!(discovery_flags & GAP_DISCOVERY_FLAG_LE_OBSERVE) && + (evtype != BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP)) { + uint8_t flags = get_ad_flags(data, len); + + /* ignore non-discoverable devices */ + if (!(flags & BLE_AD_DISCOV_MASK)) { + SYS_LOG_DBG("Non discoverable, skipping"); + return; + } + + /* if Limited Discovery - ignore general discoverable devices */ + if ((discovery_flags & GAP_DISCOVERY_FLAG_LIMITED) && + !(flags & BLE_HS_ADV_F_DISC_LTD)) { + SYS_LOG_DBG("General discoverable, skipping"); + return; + } + } + + /* attach Scan Response data */ + if (evtype == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) { + /* skip if there is no pending advertisement */ + if (!adv_buf->om_len) { + SYS_LOG_INF("No pending advertisement, skipping"); + return; + } + + ev = (void *) adv_buf->om_data; + a.type = ev->address_type; + memcpy(a.val, ev->address, sizeof(a.val)); + + /* + * in general, the Scan Response comes right after the + * Advertisement, but if not if send stored event and ignore + * this one + */ + if (ble_addr_cmp(addr, &a)) { + SYS_LOG_INF("Address does not match, skipping"); + goto done; + } + + ev->eir_data_len += len; + ev->flags |= GAP_DEVICE_FOUND_FLAG_SD; + + memcpy(net_buf_simple_add(adv_buf, len), data, len); + + goto done; + } + + /* + * if there is another pending advertisement, send it and store the + * current one + */ + if (adv_buf->om_len) { + tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_FOUND, + CONTROLLER_INDEX, adv_buf->om_data, + adv_buf->om_len); + } + + store_adv(addr, rssi, data, len); + + /* if Active Scan and scannable event - wait for Scan Response */ + if ((discovery_flags & GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN) && + (evtype == BLE_HCI_ADV_RPT_EVTYPE_ADV_IND || + evtype == BLE_HCI_ADV_RPT_EVTYPE_SCAN_IND)) { + SYS_LOG_DBG("Waiting for scan response"); + return; + } done: - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_FOUND, - CONTROLLER_INDEX, adv_buf->om_data, adv_buf->om_len); + tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_FOUND, + CONTROLLER_INDEX, adv_buf->om_data, adv_buf->om_len); } -static int discovery_cb(struct ble_gap_event *event, void *arg) +static int +discovery_cb(struct ble_gap_event *event, void *arg) { - if (event->type == BLE_GAP_EVENT_DISC) { - device_found(&event->disc.addr, event->disc.rssi, - event->disc.event_type, event->disc.data, - event->disc.length_data); - } + if (event->type == BLE_GAP_EVENT_DISC) { + device_found(&event->disc.addr, event->disc.rssi, + event->disc.event_type, event->disc.data, + event->disc.length_data); + } - return 0; + return 0; } -static void start_discovery(const uint8_t *data, uint16_t len) +static void +start_discovery(const uint8_t *data, uint16_t len) { - const struct gap_start_discovery_cmd *cmd = (void *) data; - struct ble_gap_disc_params params = {0}; - uint8_t status; + const struct gap_start_discovery_cmd *cmd = (void *) data; + struct ble_gap_disc_params params = {0}; + uint8_t status; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - /* only LE scan is supported */ - if (cmd->flags & GAP_DISCOVERY_FLAG_BREDR) { - status = BTP_STATUS_FAILED; - goto reply; - } + /* only LE scan is supported */ + if (cmd->flags & GAP_DISCOVERY_FLAG_BREDR) { + status = BTP_STATUS_FAILED; + goto reply; + } - params.passive = (cmd->flags & GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN) == 0; - params.limited = (cmd->flags & GAP_DISCOVERY_FLAG_LIMITED) > 0; - params.filter_duplicates = 1; + params.passive = (cmd->flags & GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN) == 0; + params.limited = (cmd->flags & GAP_DISCOVERY_FLAG_LIMITED) > 0; + params.filter_duplicates = 1; - if (ble_gap_disc(own_addr_type, BLE_HS_FOREVER, - ¶ms, discovery_cb, NULL) != 0) { - status = BTP_STATUS_FAILED; - goto reply; - } + if (ble_gap_disc(own_addr_type, BLE_HS_FOREVER, + ¶ms, discovery_cb, NULL) != 0) { + status = BTP_STATUS_FAILED; + goto reply; + } - net_buf_simple_init(adv_buf, 0); - discovery_flags = cmd->flags; + net_buf_simple_init(adv_buf, 0); + discovery_flags = cmd->flags; - status = BTP_STATUS_SUCCESS; + status = BTP_STATUS_SUCCESS; reply: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_DISCOVERY, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_DISCOVERY, CONTROLLER_INDEX, + status); } -static void stop_discovery(const uint8_t *data, uint16_t len) +static void +stop_discovery(const uint8_t *data, uint16_t len) { - uint8_t status = BTP_STATUS_SUCCESS; + uint8_t status = BTP_STATUS_SUCCESS; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - if (ble_gap_disc_cancel() != 0) { - status = BTP_STATUS_FAILED; - } + if (ble_gap_disc_cancel() != 0) { + status = BTP_STATUS_FAILED; + } - tester_rsp(BTP_SERVICE_ID_GAP, GAP_STOP_DISCOVERY, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GAP, GAP_STOP_DISCOVERY, CONTROLLER_INDEX, + status); } - /* Bluetooth Core Spec v5.1 | Section 10.7.1 * If a privacy-enabled Peripheral, that has a stored bond, * receives a resolvable private address, the Host may resolve @@ -685,302 +701,316 @@ static void stop_discovery(const uint8_t *data, uint16_t len) * If the resolution procedure fails, then the Host shall disconnect * with the error code "Authentication failure" [...] */ -static void periph_privacy(struct ble_gap_conn_desc desc) +static void +periph_privacy(struct ble_gap_conn_desc desc) { #if !MYNEWT_VAL(BTTESTER_PRIVACY_MODE) - return; + return; #endif - int count; + int count; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count); - if (count > 0 && BLE_ADDR_IS_RPA(&desc.peer_id_addr)) { - SYS_LOG_DBG("Authentication failure, disconnecting"); - ble_gap_terminate(desc.conn_handle, BLE_ERR_AUTH_FAIL); - } + ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count); + if (count > 0 && BLE_ADDR_IS_RPA(&desc.peer_id_addr)) { + SYS_LOG_DBG("Authentication failure, disconnecting"); + ble_gap_terminate(desc.conn_handle, BLE_ERR_AUTH_FAIL); + } } -static void device_connected_ev_send(struct os_event *ev) +static void +device_connected_ev_send(struct os_event *ev) { - struct ble_gap_conn_desc desc; - int rc; + struct ble_gap_conn_desc desc; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = gap_conn_find_by_addr((ble_addr_t *)&connected_ev, &desc); - if (rc) { - tester_rsp(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - return; - } + rc = gap_conn_find_by_addr((ble_addr_t *) &connected_ev, &desc); + if (rc) { + tester_rsp(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED, + CONTROLLER_INDEX, BTP_STATUS_FAILED); + return; + } - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED, - CONTROLLER_INDEX, (uint8_t *) &connected_ev, - sizeof(connected_ev)); + tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED, + CONTROLLER_INDEX, (uint8_t *) &connected_ev, + sizeof(connected_ev)); - periph_privacy(desc); + periph_privacy(desc); } -static void le_connected(uint16_t conn_handle, int status) +static void +le_connected(uint16_t conn_handle, int status) { - struct ble_gap_conn_desc desc; - ble_addr_t *addr; - int rc; + struct ble_gap_conn_desc desc; + ble_addr_t *addr; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - if (status != 0) { - return; - } + if (status != 0) { + return; + } - rc = ble_gap_conn_find(conn_handle, &desc); - if (rc) { - return; - } + rc = ble_gap_conn_find(conn_handle, &desc); + if (rc) { + return; + } - peer_id_addr = desc.peer_id_addr; - peer_ota_addr = desc.peer_ota_addr; + peer_id_addr = desc.peer_id_addr; + peer_ota_addr = desc.peer_ota_addr; - addr = &desc.peer_id_addr; + addr = &desc.peer_id_addr; - memcpy(connected_ev.address, addr->val, sizeof(connected_ev.address)); - connected_ev.address_type = addr->type; - connected_ev.conn_itvl = desc.conn_itvl; - connected_ev.conn_latency = desc.conn_latency; - connected_ev.supervision_timeout = desc.supervision_timeout; + memcpy(connected_ev.address, addr->val, sizeof(connected_ev.address)); + connected_ev.address_type = addr->type; + connected_ev.conn_itvl = desc.conn_itvl; + connected_ev.conn_latency = desc.conn_latency; + connected_ev.supervision_timeout = desc.supervision_timeout; #if MYNEWT_VAL(BTTESTER_CONN_RETRY) - os_callout_reset(&connected_ev_co, - os_time_ms_to_ticks32( - CONNECTED_EV_DELAY_MS(desc.conn_itvl))); + os_callout_reset(&connected_ev_co, + os_time_ms_to_ticks32( + CONNECTED_EV_DELAY_MS(desc.conn_itvl))); #else - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED, - CONTROLLER_INDEX, (uint8_t *) &connected_ev, - sizeof(connected_ev)); + tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED, + CONTROLLER_INDEX, (uint8_t *) &connected_ev, + sizeof(connected_ev)); #endif } -static void le_disconnected(struct ble_gap_conn_desc *conn, int reason) +static void +le_disconnected(struct ble_gap_conn_desc *conn, int reason) { - struct gap_device_disconnected_ev ev; - ble_addr_t *addr = &conn->peer_ota_addr; + struct gap_device_disconnected_ev ev; + ble_addr_t *addr = &conn->peer_ota_addr; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); #if MYNEWT_VAL(BTTESTER_CONN_RETRY) - int rc; - - if ((reason == BLE_HS_HCI_ERR(BLE_ERR_CONN_ESTABLISHMENT)) && - os_callout_queued(&connected_ev_co)) { - if (connection_attempts < MYNEWT_VAL(BTTESTER_CONN_RETRY)) { - os_callout_stop(&connected_ev_co); - - /* try connecting again */ - rc = ble_gap_connect(own_addr_type, addr, 0, - &dflt_conn_params, gap_event_cb, - NULL); - - if (rc == 0) { - connection_attempts++; - return; - } - } - } else if (os_callout_queued(&connected_ev_co)) { - os_callout_stop(&connected_ev_co); - return; - } + int rc; + + if ((reason == BLE_HS_HCI_ERR(BLE_ERR_CONN_ESTABLISHMENT)) && + os_callout_queued(&connected_ev_co)) { + if (connection_attempts < MYNEWT_VAL(BTTESTER_CONN_RETRY)) { + os_callout_stop(&connected_ev_co); + + /* try connecting again */ + rc = ble_gap_connect(own_addr_type, addr, 0, + &dflt_conn_params, gap_event_cb, + NULL); + + if (rc == 0) { + connection_attempts++; + return; + } + } + } else if (os_callout_queued(&connected_ev_co)) { + os_callout_stop(&connected_ev_co); + return; + } #endif - connection_attempts = 0; - memset(&connected_ev, 0, sizeof(connected_ev)); + connection_attempts = 0; + memset(&connected_ev, 0, sizeof(connected_ev)); - memcpy(ev.address, addr->val, sizeof(ev.address)); - ev.address_type = addr->type; + memcpy(ev.address, addr->val, sizeof(ev.address)); + ev.address_type = addr->type; - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_DISCONNECTED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_DISCONNECTED, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } -static void auth_passkey_oob(uint16_t conn_handle) +static void +auth_passkey_oob(uint16_t conn_handle) { - struct ble_gap_conn_desc desc; - struct ble_sm_io pk; - int rc; + struct ble_gap_conn_desc desc; + struct ble_sm_io pk; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find(conn_handle, &desc); - if (rc) { - return; - } + rc = ble_gap_conn_find(conn_handle, &desc); + if (rc) { + return; + } - memcpy(pk.oob, oob, sizeof(oob)); - pk.action = BLE_SM_IOACT_OOB; + memcpy(pk.oob, oob, sizeof(oob)); + pk.action = BLE_SM_IOACT_OOB; - rc = ble_sm_inject_io(conn_handle, &pk); - assert(rc == 0); + rc = ble_sm_inject_io(conn_handle, &pk); + assert(rc == 0); } -static void auth_passkey_display(uint16_t conn_handle, unsigned int passkey) +static void +auth_passkey_display(uint16_t conn_handle, unsigned int passkey) { - struct ble_gap_conn_desc desc; - struct gap_passkey_display_ev ev; - ble_addr_t *addr; - struct ble_sm_io pk; - int rc; + struct ble_gap_conn_desc desc; + struct gap_passkey_display_ev ev; + ble_addr_t *addr; + struct ble_sm_io pk; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find(conn_handle, &desc); - if (rc) { - return; - } + rc = ble_gap_conn_find(conn_handle, &desc); + if (rc) { + return; + } - rc = ble_hs_hci_rand(&pk.passkey, sizeof(pk.passkey)); - assert(rc == 0); - /* Max value is 999999 */ - pk.passkey %= 1000000; - pk.action = BLE_SM_IOACT_DISP; + rc = ble_hs_hci_rand(&pk.passkey, sizeof(pk.passkey)); + assert(rc == 0); + /* Max value is 999999 */ + pk.passkey %= 1000000; + pk.action = BLE_SM_IOACT_DISP; - rc = ble_sm_inject_io(conn_handle, &pk); - assert(rc == 0); + rc = ble_sm_inject_io(conn_handle, &pk); + assert(rc == 0); - addr = &desc.peer_ota_addr; + addr = &desc.peer_ota_addr; - memcpy(ev.address, addr->val, sizeof(ev.address)); - ev.address_type = addr->type; - ev.passkey = sys_cpu_to_le32(pk.passkey); + memcpy(ev.address, addr->val, sizeof(ev.address)); + ev.address_type = addr->type; + ev.passkey = sys_cpu_to_le32(pk.passkey); - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_DISPLAY, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_DISPLAY, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } -static void auth_passkey_entry(uint16_t conn_handle) +static void +auth_passkey_entry(uint16_t conn_handle) { - struct ble_gap_conn_desc desc; - struct gap_passkey_entry_req_ev ev; - ble_addr_t *addr; - int rc; + struct ble_gap_conn_desc desc; + struct gap_passkey_entry_req_ev ev; + ble_addr_t *addr; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find(conn_handle, &desc); - if (rc) { - return; - } + rc = ble_gap_conn_find(conn_handle, &desc); + if (rc) { + return; + } - addr = &desc.peer_ota_addr; + addr = &desc.peer_ota_addr; - memcpy(ev.address, addr->val, sizeof(ev.address)); - ev.address_type = addr->type; + memcpy(ev.address, addr->val, sizeof(ev.address)); + ev.address_type = addr->type; - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_ENTRY_REQ, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_ENTRY_REQ, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } -static void auth_passkey_numcmp(uint16_t conn_handle, unsigned int passkey) +static void +auth_passkey_numcmp(uint16_t conn_handle, unsigned int passkey) { - struct ble_gap_conn_desc desc; - struct gap_passkey_confirm_req_ev ev; - ble_addr_t *addr; - int rc; + struct ble_gap_conn_desc desc; + struct gap_passkey_confirm_req_ev ev; + ble_addr_t *addr; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find(conn_handle, &desc); - if (rc) { - return; - } + rc = ble_gap_conn_find(conn_handle, &desc); + if (rc) { + return; + } - addr = &desc.peer_ota_addr; + addr = &desc.peer_ota_addr; - memcpy(ev.address, addr->val, sizeof(ev.address)); - ev.address_type = addr->type; - ev.passkey = sys_cpu_to_le32(passkey); + memcpy(ev.address, addr->val, sizeof(ev.address)); + ev.address_type = addr->type; + ev.passkey = sys_cpu_to_le32(passkey); - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_CONFIRM_REQ, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_CONFIRM_REQ, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } -static void auth_passkey_oob_sc(uint16_t conn_handle) +static void +auth_passkey_oob_sc(uint16_t conn_handle) { - int rc; - struct ble_sm_io pk; + int rc; + struct ble_sm_io pk; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - memset(&pk, 0, sizeof(pk)); + memset(&pk, 0, sizeof(pk)); - pk.oob_sc_data.local = &oob_data_local; + pk.oob_sc_data.local = &oob_data_local; - if (ble_hs_cfg.sm_oob_data_flag) { - pk.oob_sc_data.remote = &oob_data_remote; - } + if (ble_hs_cfg.sm_oob_data_flag) { + pk.oob_sc_data.remote = &oob_data_remote; + } - pk.action = BLE_SM_IOACT_OOB_SC; - rc = ble_sm_inject_io(conn_handle, &pk); - if (rc != 0) { - console_printf("error providing oob; rc=%d\n", rc); - } + pk.action = BLE_SM_IOACT_OOB_SC; + rc = ble_sm_inject_io(conn_handle, &pk); + if (rc != 0) { + console_printf("error providing oob; rc=%d\n", rc); + } } -static void le_passkey_action(uint16_t conn_handle, - struct ble_gap_passkey_params *params) +static void +le_passkey_action(uint16_t conn_handle, + struct ble_gap_passkey_params *params) { - SYS_LOG_DBG(""); - - switch (params->action) { - case BLE_SM_IOACT_NONE: - break; - case BLE_SM_IOACT_OOB: - auth_passkey_oob(conn_handle); - break; - case BLE_SM_IOACT_INPUT: - auth_passkey_entry(conn_handle); - break; - case BLE_SM_IOACT_DISP: - auth_passkey_display(conn_handle, params->numcmp); - break; - case BLE_SM_IOACT_NUMCMP: - auth_passkey_numcmp(conn_handle, params->numcmp); - break; - case BLE_SM_IOACT_OOB_SC: - auth_passkey_oob_sc(conn_handle); - break; - default: - assert(0); - } + SYS_LOG_DBG(""); + + switch (params->action) { + case BLE_SM_IOACT_NONE: + break; + case BLE_SM_IOACT_OOB: + auth_passkey_oob(conn_handle); + break; + case BLE_SM_IOACT_INPUT: + auth_passkey_entry(conn_handle); + break; + case BLE_SM_IOACT_DISP: + auth_passkey_display(conn_handle, + params->numcmp); + break; + case BLE_SM_IOACT_NUMCMP: + auth_passkey_numcmp(conn_handle, + params->numcmp); + break; + case BLE_SM_IOACT_OOB_SC: + auth_passkey_oob_sc(conn_handle); + break; + default: + assert(0); + } } -static void le_identity_resolved(uint16_t conn_handle) +static void +le_identity_resolved(uint16_t conn_handle) { - struct ble_gap_conn_desc desc; - struct gap_identity_resolved_ev ev; - int rc; + struct ble_gap_conn_desc desc; + struct gap_identity_resolved_ev ev; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find(conn_handle, &desc); - if (rc) { - return; - } + rc = ble_gap_conn_find(conn_handle, &desc); + if (rc) { + return; + } - peer_id_addr = desc.peer_id_addr; - peer_ota_addr = desc.peer_ota_addr; + peer_id_addr = desc.peer_id_addr; + peer_ota_addr = desc.peer_ota_addr; - ev.address_type = desc.peer_ota_addr.type; - memcpy(ev.address, desc.peer_ota_addr.val, sizeof(ev.address)); + ev.address_type = desc.peer_ota_addr.type; + memcpy(ev.address, desc.peer_ota_addr.val, sizeof(ev.address)); - ev.identity_address_type = desc.peer_id_addr.type; - memcpy(ev.identity_address, desc.peer_id_addr.val, - sizeof(ev.identity_address)); + ev.identity_address_type = desc.peer_id_addr.type; + memcpy(ev.identity_address, desc.peer_id_addr.val, + sizeof(ev.identity_address)); - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_IDENTITY_RESOLVED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_GAP, GAP_EV_IDENTITY_RESOLVED, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } -static void le_pairing_failed(uint16_t conn_handle, int reason) +static void +le_pairing_failed(uint16_t conn_handle, int reason) { struct ble_gap_conn_desc desc; struct gap_sec_pairing_failed_ev ev; @@ -1005,52 +1035,55 @@ static void le_pairing_failed(uint16_t conn_handle, int reason) CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } -static void le_conn_param_update(struct ble_gap_conn_desc *desc) +static void +le_conn_param_update(struct ble_gap_conn_desc *desc) { - struct gap_conn_param_update_ev ev; + struct gap_conn_param_update_ev ev; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - ev.address_type = desc->peer_ota_addr.type; - memcpy(ev.address, desc->peer_ota_addr.val, sizeof(ev.address)); + ev.address_type = desc->peer_ota_addr.type; + memcpy(ev.address, desc->peer_ota_addr.val, sizeof(ev.address)); - ev.conn_itvl = desc->conn_itvl; - ev.conn_latency = desc->conn_latency; - ev.supervision_timeout = desc->supervision_timeout; + ev.conn_itvl = desc->conn_itvl; + ev.conn_latency = desc->conn_latency; + ev.supervision_timeout = desc->supervision_timeout; - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_CONN_PARAM_UPDATE, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_GAP, GAP_EV_CONN_PARAM_UPDATE, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } -static void le_encryption_changed(struct ble_gap_conn_desc *desc) +static void +le_encryption_changed(struct ble_gap_conn_desc *desc) { - struct gap_sec_level_changed_ev ev; - - SYS_LOG_DBG(""); - - encrypted = (bool) desc->sec_state.encrypted; - - ev.address_type = desc->peer_ota_addr.type; - memcpy(ev.address, desc->peer_ota_addr.val, sizeof(ev.address)); - ev.level = 0; - - if (desc->sec_state.encrypted) { - if (desc->sec_state.authenticated) { - if (desc->sec_state.key_size == 16) { - ev.level = 3; - } else { - ev.level = 2; - } - } else { - ev.level = 1; - } - } - - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_SEC_LEVEL_CHANGED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + struct gap_sec_level_changed_ev ev; + + SYS_LOG_DBG(""); + + encrypted = (bool) desc->sec_state.encrypted; + + ev.address_type = desc->peer_ota_addr.type; + memcpy(ev.address, desc->peer_ota_addr.val, sizeof(ev.address)); + ev.level = 0; + + if (desc->sec_state.encrypted) { + if (desc->sec_state.authenticated) { + if (desc->sec_state.key_size == 16) { + ev.level = 3; + } else { + ev.level = 2; + } + } else { + ev.level = 1; + } + } + + tester_send(BTP_SERVICE_ID_GAP, GAP_EV_SEC_LEVEL_CHANGED, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } -static void bond_lost(uint16_t conn_handle) +static void +bond_lost(uint16_t conn_handle) { struct gap_bond_lost_ev ev; struct ble_gap_conn_desc desc; @@ -1061,766 +1094,807 @@ static void bond_lost(uint16_t conn_handle) memcpy(ev.address, &desc.peer_id_addr, sizeof(ev.address)); ev.address_type = desc.peer_id_addr.type; - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_BOND_LOST, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_GAP, + GAP_EV_BOND_LOST, + CONTROLLER_INDEX, + (uint8_t *) &ev, + sizeof(ev)); } -static void print_bytes(const uint8_t *bytes, int len) +static void +print_bytes(const uint8_t *bytes, int len) { - int i; + int i; - for (i = 0; i < len; i++) { - console_printf("%s0x%02x", i != 0 ? ":" : "", bytes[i]); - } + for (i = 0; i < len; i++) { + console_printf("%s0x%02x", i != 0 ? ":" : "", bytes[i]); + } } -static void print_mbuf(const struct os_mbuf *om) +static void +print_mbuf(const struct os_mbuf *om) { - int colon; - - colon = 0; - while (om != NULL) { - if (colon) { - console_printf(":"); - } else { - colon = 1; - } - print_bytes(om->om_data, om->om_len); - om = SLIST_NEXT(om, om_next); - } + int colon; + + colon = 0; + while (om != NULL) { + if (colon) { + console_printf(":"); + } else { + colon = 1; + } + print_bytes(om->om_data, om->om_len); + om = SLIST_NEXT(om, om_next); + } } -static void print_addr(const void *addr) +static void +print_addr(const void *addr) { - const uint8_t *u8p; + const uint8_t *u8p; - u8p = addr; - console_printf("%02x:%02x:%02x:%02x:%02x:%02x", - u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); + u8p = addr; + console_printf("%02x:%02x:%02x:%02x:%02x:%02x", + u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); } -static void print_conn_desc(const struct ble_gap_conn_desc *desc) +static void +print_conn_desc(const struct ble_gap_conn_desc *desc) { - console_printf("handle=%d our_ota_addr_type=%d our_ota_addr=", - desc->conn_handle, desc->our_ota_addr.type); - print_addr(desc->our_ota_addr.val); - console_printf(" our_id_addr_type=%d our_id_addr=", - desc->our_id_addr.type); - print_addr(desc->our_id_addr.val); - console_printf(" peer_ota_addr_type=%d peer_ota_addr=", - desc->peer_ota_addr.type); - print_addr(desc->peer_ota_addr.val); - console_printf(" peer_id_addr_type=%d peer_id_addr=", - desc->peer_id_addr.type); - print_addr(desc->peer_id_addr.val); - console_printf(" conn_itvl=%d conn_latency=%d supervision_timeout=%d " - "key_sz=%d encrypted=%d authenticated=%d bonded=%d\n", - desc->conn_itvl, desc->conn_latency, - desc->supervision_timeout, - desc->sec_state.key_size, - desc->sec_state.encrypted, - desc->sec_state.authenticated, - desc->sec_state.bonded); + console_printf("handle=%d our_ota_addr_type=%d our_ota_addr=", + desc->conn_handle, desc->our_ota_addr.type); + print_addr(desc->our_ota_addr.val); + console_printf(" our_id_addr_type=%d our_id_addr=", + desc->our_id_addr.type); + print_addr(desc->our_id_addr.val); + console_printf(" peer_ota_addr_type=%d peer_ota_addr=", + desc->peer_ota_addr.type); + print_addr(desc->peer_ota_addr.val); + console_printf(" peer_id_addr_type=%d peer_id_addr=", + desc->peer_id_addr.type); + print_addr(desc->peer_id_addr.val); + console_printf(" conn_itvl=%d conn_latency=%d supervision_timeout=%d " + "key_sz=%d encrypted=%d authenticated=%d bonded=%d\n", + desc->conn_itvl, desc->conn_latency, + desc->supervision_timeout, + desc->sec_state.key_size, + desc->sec_state.encrypted, + desc->sec_state.authenticated, + desc->sec_state.bonded); } -static void adv_complete(void) +static void +adv_complete(void) { - struct gap_new_settings_ev ev; + struct gap_new_settings_ev ev; - current_settings &= ~BIT(GAP_SETTINGS_ADVERTISING); - ev.current_settings = sys_cpu_to_le32(current_settings); + current_settings &= ~BIT(GAP_SETTINGS_ADVERTISING); + ev.current_settings = sys_cpu_to_le32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_NEW_SETTINGS, CONTROLLER_INDEX, - (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_GAP, GAP_EV_NEW_SETTINGS, CONTROLLER_INDEX, + (uint8_t *) &ev, sizeof(ev)); } -static int gap_event_cb(struct ble_gap_event *event, void *arg) +static int +gap_event_cb(struct ble_gap_event *event, void *arg) { - struct ble_gap_conn_desc desc; - int rc; - - switch (event->type) { - case BLE_GAP_EVENT_ADV_COMPLETE: - console_printf("advertising complete; reason=%d\n", - event->adv_complete.reason); - break; - case BLE_GAP_EVENT_CONNECT: - console_printf("connection %s; status=%d ", - event->connect.status == 0 ? "established" : "failed", - event->connect.status); - if (event->connect.status == 0) { - rc = ble_gap_conn_find(event->connect.conn_handle, &desc); - assert(rc == 0); - print_conn_desc(&desc); - } - - if (desc.role == BLE_GAP_ROLE_SLAVE) { - adv_complete(); - } - - le_connected(event->connect.conn_handle, - event->connect.status); - break; - case BLE_GAP_EVENT_DISCONNECT: - console_printf("disconnect; reason=%d ", event->disconnect.reason); - print_conn_desc(&event->disconnect.conn); - le_disconnected(&event->disconnect.conn, - event->disconnect.reason); - break; - case BLE_GAP_EVENT_ENC_CHANGE: - console_printf("encryption change event; status=%d ", event->enc_change.status); - rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc); - assert(rc == 0); - print_conn_desc(&desc); - le_encryption_changed(&desc); - if (event->enc_change.status == BLE_HS_HCI_ERR(BLE_ERR_PINKEY_MISSING)) { - bond_lost(event->enc_change.conn_handle); - } - break; - case BLE_GAP_EVENT_PASSKEY_ACTION: - console_printf("passkey action event; action=%d", - event->passkey.params.action); - if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) { - console_printf(" numcmp=%lu", - (unsigned long)event->passkey.params.numcmp); - } - console_printf("\n"); - le_passkey_action(event->passkey.conn_handle, - &event->passkey.params); - break; - case BLE_GAP_EVENT_IDENTITY_RESOLVED: - console_printf("identity resolved "); - rc = ble_gap_conn_find(event->identity_resolved.conn_handle, &desc); - assert(rc == 0); - print_conn_desc(&desc); - le_identity_resolved(event->identity_resolved.conn_handle); - break; - case BLE_GAP_EVENT_NOTIFY_RX: - console_printf("notification rx event; attr_handle=%d indication=%d " - "len=%d data=", - event->notify_rx.attr_handle, - event->notify_rx.indication, - OS_MBUF_PKTLEN(event->notify_rx.om)); - - print_mbuf(event->notify_rx.om); - console_printf("\n"); - tester_gattc_notify_rx_ev(event->notify_rx.conn_handle, - event->notify_rx.attr_handle, - event->notify_rx.indication, - event->notify_rx.om); - break; - case BLE_GAP_EVENT_SUBSCRIBE: - console_printf("subscribe event; conn_handle=%d attr_handle=%d " - "reason=%d prevn=%d curn=%d previ=%d curi=%d\n", - event->subscribe.conn_handle, - event->subscribe.attr_handle, - event->subscribe.reason, - event->subscribe.prev_notify, - event->subscribe.cur_notify, - event->subscribe.prev_indicate, - event->subscribe.cur_indicate); - tester_gatt_subscribe_ev(event->subscribe.conn_handle, - event->subscribe.attr_handle, - event->subscribe.reason, - event->subscribe.prev_notify, - event->subscribe.cur_notify, - event->subscribe.prev_indicate, - event->subscribe.cur_indicate); - break; - case BLE_GAP_EVENT_REPEAT_PAIRING: - console_printf("repeat pairing event; conn_handle=%d " - "cur_key_sz=%d cur_auth=%d cur_sc=%d " - "new_key_sz=%d new_auth=%d new_sc=%d " - "new_bonding=%d\n", - event->repeat_pairing.conn_handle, - event->repeat_pairing.cur_key_size, - event->repeat_pairing.cur_authenticated, - event->repeat_pairing.cur_sc, - event->repeat_pairing.new_key_size, - event->repeat_pairing.new_authenticated, - event->repeat_pairing.new_sc, - event->repeat_pairing.new_bonding); - rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc); - assert(rc == 0); - rc = ble_store_util_delete_peer(&desc.peer_id_addr); - assert(rc == 0); - bond_lost(event->repeat_pairing.conn_handle); - return BLE_GAP_REPEAT_PAIRING_RETRY; - case BLE_GAP_EVENT_CONN_UPDATE: - console_printf("connection update event; status=%d ", - event->conn_update.status); - rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc); - assert(rc == 0); - print_conn_desc(&desc); - le_conn_param_update(&desc); - break; - case BLE_GAP_EVENT_CONN_UPDATE_REQ: - console_printf("connection update request event; " - "conn_handle=%d itvl_min=%d itvl_max=%d " - "latency=%d supervision_timoeut=%d " - "min_ce_len=%d max_ce_len=%d\n", - event->conn_update_req.conn_handle, - event->conn_update_req.peer_params->itvl_min, - event->conn_update_req.peer_params->itvl_max, - event->conn_update_req.peer_params->latency, - event->conn_update_req.peer_params->supervision_timeout, - event->conn_update_req.peer_params->min_ce_len, - event->conn_update_req.peer_params->max_ce_len); - - *event->conn_update_req.self_params = - *event->conn_update_req.peer_params; - break; - case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: - console_printf("connection update request event; " - "conn_handle=%d itvl_min=%d itvl_max=%d " - "latency=%d supervision_timoeut=%d " - "min_ce_len=%d max_ce_len=%d\n", - event->conn_update_req.conn_handle, - event->conn_update_req.peer_params->itvl_min, - event->conn_update_req.peer_params->itvl_max, - event->conn_update_req.peer_params->latency, - event->conn_update_req.peer_params->supervision_timeout, - event->conn_update_req.peer_params->min_ce_len, - event->conn_update_req.peer_params->max_ce_len); - if (event->conn_update_req.peer_params->itvl_min == REJECT_INTERVAL_MIN && - event->conn_update_req.peer_params->itvl_max == REJECT_INTERVAL_MAX && - event->conn_update_req.peer_params->latency == REJECT_LATENCY && - event->conn_update_req.peer_params->supervision_timeout == REJECT_SUPERVISION_TIMEOUT) { - return EINVAL; - } + struct ble_gap_conn_desc desc; + int rc; + + switch (event->type) { + case BLE_GAP_EVENT_ADV_COMPLETE: + console_printf("advertising complete; reason=%d\n", + event->adv_complete.reason); + break; + case BLE_GAP_EVENT_CONNECT: + console_printf("connection %s; status=%d ", + event->connect.status == 0 ? "established" + : "failed", + event->connect.status); + if (event->connect.status == 0) { + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + print_conn_desc(&desc); + } + + if (desc.role == BLE_GAP_ROLE_SLAVE) { + adv_complete(); + } + + le_connected(event->connect.conn_handle, + event->connect.status); + break; + case BLE_GAP_EVENT_DISCONNECT: + console_printf("disconnect; reason=%d ", + event->disconnect.reason); + print_conn_desc(&event->disconnect.conn); + le_disconnected(&event->disconnect.conn, + event->disconnect.reason); + break; + case BLE_GAP_EVENT_ENC_CHANGE: + console_printf("encryption change event; status=%d ", + event->enc_change.status); + rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc); + assert(rc == 0); + print_conn_desc(&desc); + le_encryption_changed(&desc); + if (event->enc_change.status + == BLE_HS_HCI_ERR(BLE_ERR_PINKEY_MISSING)) { + bond_lost(event->enc_change.conn_handle); + } + break; + case BLE_GAP_EVENT_PASSKEY_ACTION: + console_printf("passkey action event; action=%d", + event->passkey.params.action); + if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) { + console_printf(" numcmp=%lu", + (unsigned long) event->passkey.params.numcmp); + } + console_printf("\n"); + le_passkey_action(event->passkey.conn_handle, + &event->passkey.params); + break; + case BLE_GAP_EVENT_IDENTITY_RESOLVED: + console_printf("identity resolved "); + rc = ble_gap_conn_find(event->identity_resolved.conn_handle, &desc); + assert(rc == 0); + print_conn_desc(&desc); + le_identity_resolved(event->identity_resolved.conn_handle); + break; + case BLE_GAP_EVENT_NOTIFY_RX: + console_printf( + "notification rx event; attr_handle=%d indication=%d " + "len=%d data=", + event->notify_rx.attr_handle, + event->notify_rx.indication, + OS_MBUF_PKTLEN(event->notify_rx.om)); + + print_mbuf(event->notify_rx.om); + console_printf("\n"); + tester_gattc_notify_rx_ev(event->notify_rx.conn_handle, + event->notify_rx.attr_handle, + event->notify_rx.indication, + event->notify_rx.om); + break; + case BLE_GAP_EVENT_SUBSCRIBE: + console_printf("subscribe event; conn_handle=%d attr_handle=%d " + "reason=%d prevn=%d curn=%d previ=%d curi=%d\n", + event->subscribe.conn_handle, + event->subscribe.attr_handle, + event->subscribe.reason, + event->subscribe.prev_notify, + event->subscribe.cur_notify, + event->subscribe.prev_indicate, + event->subscribe.cur_indicate); + tester_gatt_subscribe_ev(event->subscribe.conn_handle, + event->subscribe.attr_handle, + event->subscribe.reason, + event->subscribe.prev_notify, + event->subscribe.cur_notify, + event->subscribe.prev_indicate, + event->subscribe.cur_indicate); + break; + case BLE_GAP_EVENT_REPEAT_PAIRING: + console_printf("repeat pairing event; conn_handle=%d " + "cur_key_sz=%d cur_auth=%d cur_sc=%d " + "new_key_sz=%d new_auth=%d new_sc=%d " + "new_bonding=%d\n", + event->repeat_pairing.conn_handle, + event->repeat_pairing.cur_key_size, + event->repeat_pairing.cur_authenticated, + event->repeat_pairing.cur_sc, + event->repeat_pairing.new_key_size, + event->repeat_pairing.new_authenticated, + event->repeat_pairing.new_sc, + event->repeat_pairing.new_bonding); + rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc); + assert(rc == 0); + rc = ble_store_util_delete_peer(&desc.peer_id_addr); + assert(rc == 0); + bond_lost(event->repeat_pairing.conn_handle); + return BLE_GAP_REPEAT_PAIRING_RETRY; + case BLE_GAP_EVENT_CONN_UPDATE: + console_printf("connection update event; status=%d ", + event->conn_update.status); + rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc); + assert(rc == 0); + print_conn_desc(&desc); + le_conn_param_update(&desc); + break; + case BLE_GAP_EVENT_CONN_UPDATE_REQ: + console_printf("connection update request event; " + "conn_handle=%d itvl_min=%d itvl_max=%d " + "latency=%d supervision_timoeut=%d " + "min_ce_len=%d max_ce_len=%d\n", + event->conn_update_req.conn_handle, + event->conn_update_req.peer_params->itvl_min, + event->conn_update_req.peer_params->itvl_max, + event->conn_update_req.peer_params->latency, + event->conn_update_req.peer_params->supervision_timeout, + event->conn_update_req.peer_params->min_ce_len, + event->conn_update_req.peer_params->max_ce_len); + + *event->conn_update_req.self_params = *event->conn_update_req.peer_params; + break; + case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: + console_printf("connection update request event; " + "conn_handle=%d itvl_min=%d itvl_max=%d " + "latency=%d supervision_timoeut=%d " + "min_ce_len=%d max_ce_len=%d\n", + event->conn_update_req.conn_handle, + event->conn_update_req.peer_params->itvl_min, + event->conn_update_req.peer_params->itvl_max, + event->conn_update_req.peer_params->latency, + event->conn_update_req.peer_params->supervision_timeout, + event->conn_update_req.peer_params->min_ce_len, + event->conn_update_req.peer_params->max_ce_len); + if (event->conn_update_req.peer_params->itvl_min + == REJECT_INTERVAL_MIN && + event->conn_update_req.peer_params->itvl_max + == REJECT_INTERVAL_MAX && + event->conn_update_req.peer_params->latency == REJECT_LATENCY + && + event->conn_update_req.peer_params->supervision_timeout + == REJECT_SUPERVISION_TIMEOUT) { + return EINVAL; + } case BLE_GAP_EVENT_PARING_COMPLETE: console_printf("received pairing complete: " "conn_handle=%d status=%d\n", event->pairing_complete.conn_handle, event->pairing_complete.status); if (event->pairing_complete.status != BLE_SM_ERR_SUCCESS) { - le_pairing_failed(event->pairing_complete.conn_handle, event->pairing_complete.status); + le_pairing_failed(event->pairing_complete.conn_handle, + event->pairing_complete.status); } break; - default: - break; - } + default: + break; + } - return 0; + return 0; } -static void connect(const uint8_t *data, uint16_t len) +static void +connect(const uint8_t *data, uint16_t len) { - uint8_t status = BTP_STATUS_SUCCESS; - ble_addr_t *addr = (ble_addr_t *) data; + uint8_t status = BTP_STATUS_SUCCESS; + ble_addr_t *addr = (ble_addr_t *) data; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - if (ble_addr_cmp(BLE_ADDR_ANY, addr) == 0) { - addr = NULL; - } + if (ble_addr_cmp(BLE_ADDR_ANY, addr) == 0) { + addr = NULL; + } - if (ble_gap_connect(own_addr_type, addr, 0, - &dflt_conn_params, gap_event_cb, NULL)) { - status = BTP_STATUS_FAILED; - } + if (ble_gap_connect(own_addr_type, addr, 0, + &dflt_conn_params, gap_event_cb, NULL)) { + status = BTP_STATUS_FAILED; + } - tester_rsp(BTP_SERVICE_ID_GAP, GAP_CONNECT, CONTROLLER_INDEX, status); + tester_rsp(BTP_SERVICE_ID_GAP, GAP_CONNECT, CONTROLLER_INDEX, status); } -static void disconnect(const uint8_t *data, uint16_t len) +static void +disconnect(const uint8_t *data, uint16_t len) { - struct ble_gap_conn_desc desc; - uint8_t status; - int rc; + struct ble_gap_conn_desc desc; + uint8_t status; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = gap_conn_find_by_addr((ble_addr_t *)data, &desc); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } + rc = gap_conn_find_by_addr((ble_addr_t *) data, &desc); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } - if (ble_gap_terminate(desc.conn_handle, BLE_ERR_REM_USER_CONN_TERM)) { - status = BTP_STATUS_FAILED; - } else { - status = BTP_STATUS_SUCCESS; - } + if (ble_gap_terminate(desc.conn_handle, BLE_ERR_REM_USER_CONN_TERM)) { + status = BTP_STATUS_FAILED; + } else { + status = BTP_STATUS_SUCCESS; + } rsp: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_DISCONNECT, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GAP, GAP_DISCONNECT, CONTROLLER_INDEX, + status); } -static void set_io_cap(const uint8_t *data, uint16_t len) +static void +set_io_cap(const uint8_t *data, uint16_t len) { - const struct gap_set_io_cap_cmd *cmd = (void *) data; - uint8_t status; - - SYS_LOG_DBG(""); - - switch (cmd->io_cap) { - case GAP_IO_CAP_DISPLAY_ONLY: - ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_DISP_ONLY; - ble_hs_cfg.sm_mitm = 1; - break; - case GAP_IO_CAP_KEYBOARD_DISPLAY: - ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_KEYBOARD_DISP; - ble_hs_cfg.sm_mitm = 1; - break; - case GAP_IO_CAP_NO_INPUT_OUTPUT: - ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_NO_IO; - ble_hs_cfg.sm_mitm = 0; - break; - case GAP_IO_CAP_KEYBOARD_ONLY: - ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_KEYBOARD_ONLY; - ble_hs_cfg.sm_mitm = 1; - break; - case GAP_IO_CAP_DISPLAY_YESNO: - ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_DISP_YES_NO; - ble_hs_cfg.sm_mitm = 1; - break; - default: - status = BTP_STATUS_FAILED; - goto rsp; - } - - status = BTP_STATUS_SUCCESS; + const struct gap_set_io_cap_cmd *cmd = (void *) data; + uint8_t status; + + SYS_LOG_DBG(""); + + switch (cmd->io_cap) { + case GAP_IO_CAP_DISPLAY_ONLY: + ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_DISP_ONLY; + ble_hs_cfg.sm_mitm = 1; + break; + case GAP_IO_CAP_KEYBOARD_DISPLAY: + ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_KEYBOARD_DISP; + ble_hs_cfg.sm_mitm = 1; + break; + case GAP_IO_CAP_NO_INPUT_OUTPUT: + ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_NO_IO; + ble_hs_cfg.sm_mitm = 0; + break; + case GAP_IO_CAP_KEYBOARD_ONLY: + ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_KEYBOARD_ONLY; + ble_hs_cfg.sm_mitm = 1; + break; + case GAP_IO_CAP_DISPLAY_YESNO: + ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_DISP_YES_NO; + ble_hs_cfg.sm_mitm = 1; + break; + default: + status = BTP_STATUS_FAILED; + goto rsp; + } + + status = BTP_STATUS_SUCCESS; rsp: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_IO_CAP, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_IO_CAP, CONTROLLER_INDEX, + status); } -static void pair(const uint8_t *data, uint16_t len) +static void +pair(const uint8_t *data, uint16_t len) { - struct ble_gap_conn_desc desc; - uint8_t status; - int rc; + struct ble_gap_conn_desc desc; + uint8_t status; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = gap_conn_find_by_addr((ble_addr_t *)data, &desc); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } + rc = gap_conn_find_by_addr((ble_addr_t *) data, &desc); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } - if (ble_gap_security_initiate(desc.conn_handle)) { - status = BTP_STATUS_FAILED; - goto rsp; - } + if (ble_gap_security_initiate(desc.conn_handle)) { + status = BTP_STATUS_FAILED; + goto rsp; + } - status = BTP_STATUS_SUCCESS; + status = BTP_STATUS_SUCCESS; rsp: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_PAIR, CONTROLLER_INDEX, status); + tester_rsp(BTP_SERVICE_ID_GAP, GAP_PAIR, CONTROLLER_INDEX, status); } -static void unpair(const uint8_t *data, uint16_t len) +static void +unpair(const uint8_t *data, uint16_t len) { - uint8_t status; - int err; + uint8_t status; + int err; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - err = ble_gap_unpair((ble_addr_t *) data); - status = (uint8_t) (err != 0 ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); - tester_rsp(BTP_SERVICE_ID_GAP, GAP_UNPAIR, CONTROLLER_INDEX, status); + err = ble_gap_unpair((ble_addr_t *) data); + status = (uint8_t) (err != 0 ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_GAP, GAP_UNPAIR, CONTROLLER_INDEX, status); } -static void passkey_entry(const uint8_t *data, uint16_t len) +static void +passkey_entry(const uint8_t *data, uint16_t len) { - const struct gap_passkey_entry_cmd *cmd = (void *) data; - struct ble_gap_conn_desc desc; - struct ble_sm_io pk; - uint8_t status; - int rc; + const struct gap_passkey_entry_cmd *cmd = (void *) data; + struct ble_gap_conn_desc desc; + struct ble_sm_io pk; + uint8_t status; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = gap_conn_find_by_addr((ble_addr_t *)data, &desc); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } + rc = gap_conn_find_by_addr((ble_addr_t *) data, &desc); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } - pk.action = BLE_SM_IOACT_INPUT; - pk.passkey = sys_le32_to_cpu(cmd->passkey); + pk.action = BLE_SM_IOACT_INPUT; + pk.passkey = sys_le32_to_cpu(cmd->passkey); - rc = ble_sm_inject_io(desc.conn_handle, &pk); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } + rc = ble_sm_inject_io(desc.conn_handle, &pk); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } - status = BTP_STATUS_SUCCESS; + status = BTP_STATUS_SUCCESS; rsp: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_PASSKEY_ENTRY, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GAP, GAP_PASSKEY_ENTRY, CONTROLLER_INDEX, + status); } -static void passkey_confirm(const uint8_t *data, uint16_t len) +static void +passkey_confirm(const uint8_t *data, uint16_t len) { - const struct gap_passkey_confirm_cmd *cmd = (void *) data; - struct ble_gap_conn_desc desc; - struct ble_sm_io pk; - uint8_t status; - int rc; + const struct gap_passkey_confirm_cmd *cmd = (void *) data; + struct ble_gap_conn_desc desc; + struct ble_sm_io pk; + uint8_t status; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = gap_conn_find_by_addr((ble_addr_t *)data, &desc); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } + rc = gap_conn_find_by_addr((ble_addr_t *) data, &desc); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } - pk.action = BLE_SM_IOACT_NUMCMP; - pk.numcmp_accept = cmd->match; + pk.action = BLE_SM_IOACT_NUMCMP; + pk.numcmp_accept = cmd->match; - rc = ble_sm_inject_io(desc.conn_handle, &pk); - if (rc) { - console_printf("sm inject io failed"); - status = BTP_STATUS_FAILED; - goto rsp; - } + rc = ble_sm_inject_io(desc.conn_handle, &pk); + if (rc) { + console_printf("sm inject io failed"); + status = BTP_STATUS_FAILED; + goto rsp; + } - status = BTP_STATUS_SUCCESS; + status = BTP_STATUS_SUCCESS; rsp: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_PASSKEY_CONFIRM, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GAP, GAP_PASSKEY_CONFIRM, CONTROLLER_INDEX, + status); } -static void start_direct_adv(const uint8_t *data, uint16_t len) +static void +start_direct_adv(const uint8_t *data, uint16_t len) { - const struct gap_start_direct_adv_cmd *cmd = (void *) data; - struct gap_start_advertising_rp rp; - static struct ble_gap_adv_params adv_params = { - .conn_mode = BLE_GAP_CONN_MODE_DIR, - }; - int err; - - SYS_LOG_DBG(""); - - adv_params.high_duty_cycle = cmd->high_duty; - - err = ble_gap_adv_start(own_addr_type, (ble_addr_t *)data, - BLE_HS_FOREVER, &adv_params, - gap_event_cb, NULL); - if (err) { - SYS_LOG_ERR("Advertising failed: err %d", err); - goto fail; - } - - current_settings |= BIT(GAP_SETTINGS_ADVERTISING); - rp.current_settings = sys_cpu_to_le32(current_settings); - - tester_send(BTP_SERVICE_ID_GAP, GAP_START_DIRECT_ADV, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); - return; + const struct gap_start_direct_adv_cmd *cmd = (void *) data; + struct gap_start_advertising_rp rp; + static struct ble_gap_adv_params adv_params = { + .conn_mode = BLE_GAP_CONN_MODE_DIR, + }; + int err; + + SYS_LOG_DBG(""); + + adv_params.high_duty_cycle = cmd->high_duty; + + err = ble_gap_adv_start(own_addr_type, (ble_addr_t *) data, + BLE_HS_FOREVER, &adv_params, + gap_event_cb, NULL); + if (err) { + SYS_LOG_ERR("Advertising failed: err %d", err); + goto fail; + } + + current_settings |= BIT(GAP_SETTINGS_ADVERTISING); + rp.current_settings = sys_cpu_to_le32(current_settings); + + tester_send(BTP_SERVICE_ID_GAP, GAP_START_DIRECT_ADV, CONTROLLER_INDEX, + (uint8_t *) &rp, sizeof(rp)); + return; fail: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_DIRECT_ADV, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_DIRECT_ADV, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static void conn_param_update_cb(uint16_t conn_handle, int status, void *arg) +static void +conn_param_update_cb(uint16_t conn_handle, int status, void *arg) { - console_printf("conn param update complete; conn_handle=%d status=%d\n", - conn_handle, status); + console_printf("conn param update complete; conn_handle=%d status=%d\n", + conn_handle, status); } -static int conn_param_update_slave(uint16_t conn_handle, - const struct gap_conn_param_update_cmd *cmd) +static int +conn_param_update_slave(uint16_t conn_handle, + const struct gap_conn_param_update_cmd *cmd) { - int rc; - struct ble_l2cap_sig_update_params params; + int rc; + struct ble_l2cap_sig_update_params params; - params.itvl_min = cmd->conn_itvl_min; - params.itvl_max = cmd->conn_itvl_max; - params.slave_latency = cmd->conn_latency; - params.timeout_multiplier = cmd->supervision_timeout; + params.itvl_min = cmd->conn_itvl_min; + params.itvl_max = cmd->conn_itvl_max; + params.slave_latency = cmd->conn_latency; + params.timeout_multiplier = cmd->supervision_timeout; - rc = ble_l2cap_sig_update(conn_handle, ¶ms, - conn_param_update_cb, NULL); - if (rc) { - SYS_LOG_ERR("Failed to send update params: rc=%d", rc); - } + rc = ble_l2cap_sig_update(conn_handle, ¶ms, + conn_param_update_cb, NULL); + if (rc) { + SYS_LOG_ERR("Failed to send update params: rc=%d", rc); + } - return 0; + return 0; } -static int conn_param_update_master(uint16_t conn_handle, - const struct gap_conn_param_update_cmd *cmd) +static int +conn_param_update_master(uint16_t conn_handle, + const struct gap_conn_param_update_cmd *cmd) { - int rc; - struct ble_gap_upd_params params; - - params.itvl_min = cmd->conn_itvl_min; - params.itvl_max = cmd->conn_itvl_max; - params.latency = cmd->conn_latency; - params.supervision_timeout = cmd->supervision_timeout; - params.min_ce_len = 0; - params.max_ce_len = 0; - rc = ble_gap_update_params(conn_handle, ¶ms); - if (rc) { - SYS_LOG_ERR("Failed to send update params: rc=%d", rc); - } - - return rc; + int rc; + struct ble_gap_upd_params params; + + params.itvl_min = cmd->conn_itvl_min; + params.itvl_max = cmd->conn_itvl_max; + params.latency = cmd->conn_latency; + params.supervision_timeout = cmd->supervision_timeout; + params.min_ce_len = 0; + params.max_ce_len = 0; + rc = ble_gap_update_params(conn_handle, ¶ms); + if (rc) { + SYS_LOG_ERR("Failed to send update params: rc=%d", rc); + } + + return rc; } -static void conn_param_update(struct os_event *ev) +static void +conn_param_update(struct os_event *ev) { - struct ble_gap_conn_desc desc; - int rc; + struct ble_gap_conn_desc desc; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = gap_conn_find_by_addr((ble_addr_t *)&update_params, &desc); - if (rc) { - goto rsp; - } + rc = gap_conn_find_by_addr((ble_addr_t *) &update_params, &desc); + if (rc) { + goto rsp; + } - if ((desc.conn_itvl >= update_params.conn_itvl_min) && - (desc.conn_itvl <= update_params.conn_itvl_max) && - (desc.conn_latency == update_params.conn_latency) && - (desc.supervision_timeout == update_params.supervision_timeout)) { - goto rsp; - } + if ((desc.conn_itvl >= update_params.conn_itvl_min) && + (desc.conn_itvl <= update_params.conn_itvl_max) && + (desc.conn_latency == update_params.conn_latency) && + (desc.supervision_timeout == update_params.supervision_timeout)) { + goto rsp; + } - if (desc.role == BLE_GAP_ROLE_MASTER) { - rc = conn_param_update_master(desc.conn_handle, &update_params); - } else { - rc = conn_param_update_slave(desc.conn_handle, &update_params); - } + if (desc.role == BLE_GAP_ROLE_MASTER) { + rc = conn_param_update_master(desc.conn_handle, &update_params); + } else { + rc = conn_param_update_slave(desc.conn_handle, &update_params); + } - if (rc == 0) { - return; - } + if (rc == 0) { + return; + } rsp: - SYS_LOG_ERR("Conn param update fail; rc=%d", rc); + SYS_LOG_ERR("Conn param update fail; rc=%d", rc); } -static void conn_param_update_async(const uint8_t *data, uint16_t len) +static void +conn_param_update_async(const uint8_t *data, uint16_t len) { - const struct gap_conn_param_update_cmd *cmd = (void *) data; - update_params = *cmd; + const struct gap_conn_param_update_cmd *cmd = (void *) data; + update_params = *cmd; - os_callout_reset(&update_params_co, 0); + os_callout_reset(&update_params_co, 0); - tester_rsp(BTP_SERVICE_ID_GAP, GAP_CONN_PARAM_UPDATE, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_GAP, GAP_CONN_PARAM_UPDATE, CONTROLLER_INDEX, + BTP_STATUS_SUCCESS); } -static void oob_legacy_set_data(const uint8_t *data, uint16_t len) +static void +oob_legacy_set_data(const uint8_t *data, uint16_t len) { - const struct gap_oob_legacy_set_data_cmd *cmd = (void *) data; + const struct gap_oob_legacy_set_data_cmd *cmd = (void *) data; - ble_hs_cfg.sm_oob_data_flag = 1; - memcpy(oob, cmd->oob_data, sizeof(oob)); + ble_hs_cfg.sm_oob_data_flag = 1; + memcpy(oob, cmd->oob_data, sizeof(oob)); - tester_rsp(BTP_SERVICE_ID_GAP, GAP_OOB_LEGACY_SET_DATA, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_GAP, GAP_OOB_LEGACY_SET_DATA, + CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } -static void oob_sc_get_local_data(const uint8_t *data, uint16_t len) +static void +oob_sc_get_local_data(const uint8_t *data, uint16_t len) { - struct gap_oob_sc_get_local_data_rp rp; + struct gap_oob_sc_get_local_data_rp rp; - memcpy(rp.r, oob_data_local.r, 16); - memcpy(rp.c, oob_data_local.c, 16); + memcpy(rp.r, oob_data_local.r, 16); + memcpy(rp.c, oob_data_local.c, 16); - tester_send(BTP_SERVICE_ID_GAP, GAP_OOB_SC_GET_LOCAL_DATA, - CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); + tester_send(BTP_SERVICE_ID_GAP, GAP_OOB_SC_GET_LOCAL_DATA, + CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); } -static void oob_sc_set_remote_data(const uint8_t *data, uint16_t len) +static void +oob_sc_set_remote_data(const uint8_t *data, uint16_t len) { - const struct gap_oob_sc_set_remote_data_cmd *cmd = (void *) data; + const struct gap_oob_sc_set_remote_data_cmd *cmd = (void *) data; - ble_hs_cfg.sm_oob_data_flag = 1; - memcpy(oob_data_remote.r, cmd->r, 16); - memcpy(oob_data_remote.c, cmd->c, 16); + ble_hs_cfg.sm_oob_data_flag = 1; + memcpy(oob_data_remote.r, cmd->r, 16); + memcpy(oob_data_remote.c, cmd->c, 16); - tester_rsp(BTP_SERVICE_ID_GAP, GAP_OOB_SC_SET_REMOTE_DATA, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_GAP, GAP_OOB_SC_SET_REMOTE_DATA, + CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } -static void set_mitm(const uint8_t *data, uint16_t len) +static void +set_mitm(const uint8_t *data, uint16_t len) { - const struct gap_set_mitm_cmd *cmd = (void *) data; + const struct gap_set_mitm_cmd *cmd = (void *) data; - ble_hs_cfg.sm_mitm = cmd->mitm; + ble_hs_cfg.sm_mitm = cmd->mitm; - tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_MITM, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_MITM, + CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } -static void set_filter_accept_list(const uint8_t *data, uint16_t len) +static void +set_filter_accept_list(const uint8_t *data, uint16_t len) { - uint8_t status = BTP_STATUS_SUCCESS; - struct gap_set_filter_accept_list_cmd *tmp = - (struct gap_set_filter_accept_list_cmd *) data; - - SYS_LOG_DBG(""); - - /* - * Check if the nb of bytes received matches the len of addrs list. - * Then set the filter accept list. - */ - if (((len - sizeof(tmp->list_len))/sizeof(ble_addr_t) != - tmp->list_len) || ble_gap_wl_set(tmp->addrs, tmp->list_len)) { - status = BTP_STATUS_FAILED; - } - - tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_FILTER_ACCEPT_LIST, - CONTROLLER_INDEX, status); + uint8_t status = BTP_STATUS_SUCCESS; + struct gap_set_filter_accept_list_cmd *tmp = + (struct gap_set_filter_accept_list_cmd *) data; + + SYS_LOG_DBG(""); + + /* + * Check if the nb of bytes received matches the len of addrs list. + * Then set the filter accept list. + */ + if (((len - sizeof(tmp->list_len)) / sizeof(ble_addr_t) != + tmp->list_len) || ble_gap_wl_set(tmp->addrs, tmp->list_len)) { + status = BTP_STATUS_FAILED; + } + + tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_FILTER_ACCEPT_LIST, + CONTROLLER_INDEX, status); } -void tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len) +void +tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len) { - switch (opcode) { - case GAP_READ_SUPPORTED_COMMANDS: - case GAP_READ_CONTROLLER_INDEX_LIST: - if (index != BTP_INDEX_NONE){ - tester_rsp(BTP_SERVICE_ID_GAP, opcode, index, - BTP_STATUS_FAILED); - return; - } - break; - default: - if (index != CONTROLLER_INDEX){ - tester_rsp(BTP_SERVICE_ID_GAP, opcode, index, - BTP_STATUS_FAILED); - return; - } - break; - } - - switch (opcode) { - case GAP_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - return; - case GAP_READ_CONTROLLER_INDEX_LIST: - controller_index_list(data, len); - return; - case GAP_READ_CONTROLLER_INFO: - controller_info(data, len); - return; - case GAP_SET_CONNECTABLE: - set_connectable(data, len); - return; - case GAP_SET_DISCOVERABLE: - set_discoverable(data, len); - return; - case GAP_SET_BONDABLE: - set_bondable(data, len); - return; - case GAP_START_ADVERTISING: - start_advertising(data, len); - return; - case GAP_STOP_ADVERTISING: - stop_advertising(data, len); - return; - case GAP_START_DISCOVERY: - start_discovery(data, len); - return; - case GAP_STOP_DISCOVERY: - stop_discovery(data, len); - return; - case GAP_CONNECT: - connect(data, len); - return; - case GAP_DISCONNECT: - disconnect(data, len); - return; - case GAP_SET_IO_CAP: - set_io_cap(data, len); - return; - case GAP_PAIR: - pair(data, len); - return; - case GAP_UNPAIR: - unpair(data, len); - return; - case GAP_PASSKEY_ENTRY: - passkey_entry(data, len); - return; - case GAP_PASSKEY_CONFIRM: - passkey_confirm(data, len); - return; - case GAP_START_DIRECT_ADV: - start_direct_adv(data, len); - return; - case GAP_CONN_PARAM_UPDATE: - conn_param_update_async(data, len); - return; - case GAP_OOB_LEGACY_SET_DATA: - oob_legacy_set_data(data, len); - return; - case GAP_OOB_SC_GET_LOCAL_DATA: - oob_sc_get_local_data(data, len); - return; - case GAP_OOB_SC_SET_REMOTE_DATA: - oob_sc_set_remote_data(data, len); - return; - case GAP_SET_MITM: - set_mitm(data, len); - return; - case GAP_SET_FILTER_ACCEPT_LIST: - set_filter_accept_list(data, len); - return; - default: - tester_rsp(BTP_SERVICE_ID_GAP, opcode, index, - BTP_STATUS_UNKNOWN_CMD); - return; - } + switch (opcode) { + case GAP_READ_SUPPORTED_COMMANDS: + case GAP_READ_CONTROLLER_INDEX_LIST: + if (index != BTP_INDEX_NONE) { + tester_rsp(BTP_SERVICE_ID_GAP, opcode, index, + BTP_STATUS_FAILED); + return; + } + break; + default: + if (index != CONTROLLER_INDEX) { + tester_rsp(BTP_SERVICE_ID_GAP, opcode, index, + BTP_STATUS_FAILED); + return; + } + break; + } + + switch (opcode) { + case GAP_READ_SUPPORTED_COMMANDS: + supported_commands(data, len); + return; + case GAP_READ_CONTROLLER_INDEX_LIST: + controller_index_list(data, len); + return; + case GAP_READ_CONTROLLER_INFO: + controller_info(data, len); + return; + case GAP_SET_CONNECTABLE: + set_connectable(data, len); + return; + case GAP_SET_DISCOVERABLE: + set_discoverable(data, len); + return; + case GAP_SET_BONDABLE: + set_bondable(data, len); + return; + case GAP_START_ADVERTISING: + start_advertising(data, len); + return; + case GAP_STOP_ADVERTISING: + stop_advertising(data, len); + return; + case GAP_START_DISCOVERY: + start_discovery(data, len); + return; + case GAP_STOP_DISCOVERY: + stop_discovery(data, len); + return; + case GAP_CONNECT: + connect(data, len); + return; + case GAP_DISCONNECT: + disconnect(data, len); + return; + case GAP_SET_IO_CAP: + set_io_cap(data, len); + return; + case GAP_PAIR: + pair(data, len); + return; + case GAP_UNPAIR: + unpair(data, len); + return; + case GAP_PASSKEY_ENTRY: + passkey_entry(data, len); + return; + case GAP_PASSKEY_CONFIRM: + passkey_confirm(data, len); + return; + case GAP_START_DIRECT_ADV: + start_direct_adv(data, len); + return; + case GAP_CONN_PARAM_UPDATE: + conn_param_update_async(data, len); + return; + case GAP_OOB_LEGACY_SET_DATA: + oob_legacy_set_data(data, len); + return; + case GAP_OOB_SC_GET_LOCAL_DATA: + oob_sc_get_local_data(data, len); + return; + case GAP_OOB_SC_SET_REMOTE_DATA: + oob_sc_set_remote_data(data, len); + return; + case GAP_SET_MITM: + set_mitm(data, len); + return; + case GAP_SET_FILTER_ACCEPT_LIST: + set_filter_accept_list(data, len); + return; + default: + tester_rsp(BTP_SERVICE_ID_GAP, opcode, index, + BTP_STATUS_UNKNOWN_CMD); + return; + } } -static void tester_init_gap_cb(int err) +static void +tester_init_gap_cb(int err) { - if (err) { - tester_rsp(BTP_SERVICE_ID_CORE, CORE_REGISTER_SERVICE, - BTP_INDEX_NONE, BTP_STATUS_FAILED); - return; - } + if (err) { + tester_rsp(BTP_SERVICE_ID_CORE, CORE_REGISTER_SERVICE, + BTP_INDEX_NONE, BTP_STATUS_FAILED); + return; + } - current_settings = 0; - current_settings |= BIT(GAP_SETTINGS_POWERED); - current_settings |= BIT(GAP_SETTINGS_LE); + current_settings = 0; + current_settings |= BIT(GAP_SETTINGS_POWERED); + current_settings |= BIT(GAP_SETTINGS_LE); - os_callout_init(&update_params_co, os_eventq_dflt_get(), - conn_param_update, NULL); + os_callout_init(&update_params_co, os_eventq_dflt_get(), + conn_param_update, NULL); - os_callout_init(&connected_ev_co, os_eventq_dflt_get(), - device_connected_ev_send, NULL); + os_callout_init(&connected_ev_co, os_eventq_dflt_get(), + device_connected_ev_send, NULL); - tester_rsp(BTP_SERVICE_ID_CORE, CORE_REGISTER_SERVICE, BTP_INDEX_NONE, - BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_CORE, CORE_REGISTER_SERVICE, BTP_INDEX_NONE, + BTP_STATUS_SUCCESS); } -uint8_t tester_init_gap(void) +uint8_t +tester_init_gap(void) { #if MYNEWT_VAL(BLE_SM_SC) - int rc; + int rc; - rc = ble_sm_sc_oob_generate_data(&oob_data_local); - if (rc) { - console_printf("Error: generating oob data; reason=%d\n", rc); - return BTP_STATUS_FAILED; - } + rc = ble_sm_sc_oob_generate_data(&oob_data_local); + if (rc) { + console_printf("Error: generating oob data; reason=%d\n", rc); + return BTP_STATUS_FAILED; + } #endif #if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) - os_callout_init(&bttester_nrpa_rotate_timer, os_eventq_dflt_get(), + os_callout_init(&bttester_nrpa_rotate_timer, os_eventq_dflt_get(), rotate_nrpa_cb, NULL); #endif - adv_buf = NET_BUF_SIMPLE(ADV_BUF_LEN); + adv_buf = NET_BUF_SIMPLE(ADV_BUF_LEN); - tester_init_gap_cb(BTP_STATUS_SUCCESS); - return BTP_STATUS_SUCCESS; + tester_init_gap_cb(BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } -uint8_t tester_unregister_gap(void) +uint8_t +tester_unregister_gap(void) { - return BTP_STATUS_SUCCESS; + return BTP_STATUS_SUCCESS; } diff --git a/apps/bttester/src/gatt.c b/apps/bttester/src/gatt.c index 130d9f1ee8..02ea3ec727 100644 --- a/apps/bttester/src/gatt.c +++ b/apps/bttester/src/gatt.c @@ -44,15 +44,15 @@ /* 0000xxxx-8c26-476f-89a7-a108033a69c7 */ #define PTS_UUID_DECLARE(uuid16) \ ((const ble_uuid_t *) (&(ble_uuid128_t) BLE_UUID128_INIT( \ - 0xc7, 0x69, 0x3a, 0x03, 0x08, 0xa1, 0xa7, 0x89, \ - 0x6f, 0x47, 0x26, 0x8c, uuid16, uuid16 >> 8, 0x00, 0x00 \ + 0xc7, 0x69, 0x3a, 0x03, 0x08, 0xa1, 0xa7, 0x89, \ + 0x6f, 0x47, 0x26, 0x8c, uuid16, uuid16 >> 8, 0x00, 0x00 \ ))) /* 0000xxxx-8c26-476f-89a7-a108033a69c6 */ #define PTS_UUID_DECLARE_ALT(uuid16) \ ((const ble_uuid_t *) (&(ble_uuid128_t) BLE_UUID128_INIT( \ - 0xc6, 0x69, 0x3a, 0x03, 0x08, 0xa1, 0xa7, 0x89, \ - 0x6f, 0x47, 0x26, 0x8c, uuid16, uuid16 >> 8, 0x00, 0x00 \ + 0xc6, 0x69, 0x3a, 0x03, 0x08, 0xa1, 0xa7, 0x89, \ + 0x6f, 0x47, 0x26, 0x8c, uuid16, uuid16 >> 8, 0x00, 0x00 \ ))) #define PTS_SVC 0x0001 @@ -84,528 +84,530 @@ uint16_t notify_handle; uint8_t notify_value = 90; struct find_attr_data { - ble_uuid_any_t *uuid; - int attr_type; - void *ptr; - uint16_t handle; + ble_uuid_any_t *uuid; + int attr_type; + void *ptr; + uint16_t handle; }; static int gatt_svr_read_write_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg); + struct ble_gatt_access_ctxt *ctxt, + void *arg); static int gatt_svr_read_write_auth_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg); + struct ble_gatt_access_ctxt *ctxt, + void *arg); static int gatt_svr_read_write_enc_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg); + struct ble_gatt_access_ctxt *ctxt, + void *arg); static int gatt_svr_dsc_read_write_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg); + struct ble_gatt_access_ctxt *ctxt, + void *arg); static int gatt_svr_write_no_rsp_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg); + struct ble_gatt_access_ctxt *ctxt, + void *arg); static int gatt_svr_rel_write_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg); + struct ble_gatt_access_ctxt *ctxt, + void *arg); static int gatt_svr_read_write_long_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg); + struct ble_gatt_access_ctxt *ctxt, + void *arg); static int gatt_svr_dsc_read_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg); + struct ble_gatt_access_ctxt *ctxt, + void *arg); static int gatt_svr_dsc_read_write_long_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg); + struct ble_gatt_access_ctxt *ctxt, + void *arg); static const struct ble_gatt_svc_def gatt_svr_inc_svcs[] = { - { - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = PTS_UUID_DECLARE(PTS_INC_SVC), - .characteristics = (struct ble_gatt_chr_def[]) {{ - .uuid = PTS_UUID_DECLARE(PTS_CHR_READ_WRITE_ALT), - .access_cb = gatt_svr_read_write_test, - .flags = BLE_GATT_CHR_F_WRITE | - BLE_GATT_CHR_F_READ, - }, { - 0, - } }, - }, - - { - 0, /* No more services. */ - }, + { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = PTS_UUID_DECLARE(PTS_INC_SVC), + .characteristics = (struct ble_gatt_chr_def[]) {{ + .uuid = PTS_UUID_DECLARE(PTS_CHR_READ_WRITE_ALT), + .access_cb = gatt_svr_read_write_test, + .flags = BLE_GATT_CHR_F_WRITE | + BLE_GATT_CHR_F_READ, + }, { + 0, + }}, + + }, + + { + 0, /* No more services. */ + }, }; static const struct ble_gatt_svc_def *inc_svcs[] = { - &gatt_svr_inc_svcs[0], - NULL, + &gatt_svr_inc_svcs[0], + NULL, }; static const struct ble_gatt_svc_def gatt_svr_svcs[] = { - { - /*** Service: PTS test. */ - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = PTS_UUID_DECLARE(PTS_SVC), - .includes = inc_svcs, - .characteristics = (struct ble_gatt_chr_def[]) { { - .uuid = PTS_UUID_DECLARE(PTS_CHR_READ_WRITE), - .access_cb = gatt_svr_read_write_test, - .flags = BLE_GATT_CHR_F_READ | - BLE_GATT_CHR_F_WRITE, - .descriptors = (struct ble_gatt_dsc_def[]) { { - .uuid = PTS_UUID_DECLARE(PTS_DSC_READ_WRITE), - .access_cb = gatt_svr_dsc_read_write_test, - .att_flags = BLE_ATT_F_READ | - BLE_ATT_F_WRITE, - }, { - .uuid = PTS_UUID_DECLARE(PTS_LONG_DSC_READ_WRITE), - .access_cb = gatt_svr_dsc_read_write_long_test, - .att_flags = BLE_ATT_F_READ | - BLE_ATT_F_WRITE, - }, { - .uuid = PTS_UUID_DECLARE(PTS_DSC_READ), - .access_cb = gatt_svr_dsc_read_test, - .att_flags = BLE_ATT_F_READ, - }, { - 0, /* No more descriptors in this characteristic */ - } } - }, { - .uuid = PTS_UUID_DECLARE(PTS_CHR_WRITE_NO_RSP), - .access_cb = gatt_svr_write_no_rsp_test, - .flags = BLE_GATT_CHR_F_READ | - BLE_GATT_CHR_F_WRITE | - BLE_GATT_CHR_F_WRITE_NO_RSP, - }, { - .uuid = PTS_UUID_DECLARE(PTS_CHR_READ_WRITE_AUTHEN), - .access_cb = gatt_svr_read_write_auth_test, - .flags = BLE_GATT_CHR_F_READ_AUTHEN | - BLE_GATT_CHR_F_READ | - BLE_GATT_CHR_F_WRITE_AUTHEN | - BLE_GATT_CHR_F_WRITE | - BLE_GATT_CHR_F_WRITE_AUTHEN, - }, { - .uuid = PTS_UUID_DECLARE(PTS_CHR_RELIABLE_WRITE), - .access_cb = gatt_svr_rel_write_test, - .flags = BLE_GATT_CHR_F_WRITE | - BLE_GATT_CHR_F_RELIABLE_WRITE, - }, { - .uuid = PTS_UUID_DECLARE(PTS_CHR_READ_WRITE_ENC), - .access_cb = gatt_svr_read_write_enc_test, - .flags = BLE_GATT_CHR_F_READ_ENC | - BLE_GATT_CHR_F_READ | - BLE_GATT_CHR_F_WRITE | - BLE_GATT_CHR_F_WRITE_ENC, - .min_key_size = 16, - }, { - .uuid = PTS_UUID_DECLARE(PTS_LONG_CHR_READ_WRITE), - .access_cb = gatt_svr_read_write_long_test, - .flags = BLE_GATT_CHR_F_WRITE | - BLE_GATT_CHR_F_READ, - }, { - .uuid = PTS_UUID_DECLARE(PTS_LONG_CHR_READ_WRITE_ALT), - .access_cb = gatt_svr_read_write_long_test, - .flags = BLE_GATT_CHR_F_WRITE | - BLE_GATT_CHR_F_READ, - }, { - .uuid = PTS_UUID_DECLARE(PTS_CHR_NOTIFY), - .access_cb = gatt_svr_read_write_test, - .val_handle = ¬ify_handle, - .flags = BLE_GATT_CHR_F_NOTIFY | - BLE_GATT_CHR_F_INDICATE, - }, { - 0, /* No more characteristics in this service. */ - } }, - }, - - { - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = PTS_UUID_DECLARE_ALT(PTS_SVC), - .characteristics = (struct ble_gatt_chr_def[]) { { - .uuid = PTS_UUID_DECLARE_ALT(PTS_CHR_READ_WRITE), - .access_cb = gatt_svr_read_write_test, - .flags = BLE_GATT_CHR_F_WRITE | - BLE_GATT_CHR_F_READ, - }, { - 0, /* No more characteristics in this service */ - } }, - }, - - { - 0, /* No more services. */ - }, + { + /*** Service: PTS test. */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = PTS_UUID_DECLARE(PTS_SVC), + .includes = inc_svcs, + .characteristics = (struct ble_gatt_chr_def[]) { + { + .uuid = PTS_UUID_DECLARE(PTS_CHR_READ_WRITE), + .access_cb = gatt_svr_read_write_test, + .flags = BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_WRITE, + .descriptors = (struct ble_gatt_dsc_def[]) {{ + .uuid = PTS_UUID_DECLARE(PTS_DSC_READ_WRITE), + .access_cb = gatt_svr_dsc_read_write_test, + .att_flags = BLE_ATT_F_READ | + BLE_ATT_F_WRITE, + }, { + .uuid = PTS_UUID_DECLARE(PTS_LONG_DSC_READ_WRITE), + .access_cb = gatt_svr_dsc_read_write_long_test, + .att_flags = BLE_ATT_F_READ | + BLE_ATT_F_WRITE, + }, { + .uuid = PTS_UUID_DECLARE(PTS_DSC_READ), + .access_cb = gatt_svr_dsc_read_test, + .att_flags = BLE_ATT_F_READ, + }, { + 0, /* No more descriptors in this characteristic */ + }} + }, { + .uuid = PTS_UUID_DECLARE(PTS_CHR_WRITE_NO_RSP), + .access_cb = gatt_svr_write_no_rsp_test, + .flags = BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_WRITE | + BLE_GATT_CHR_F_WRITE_NO_RSP, + }, { + .uuid = PTS_UUID_DECLARE(PTS_CHR_READ_WRITE_AUTHEN), + .access_cb = gatt_svr_read_write_auth_test, + .flags = BLE_GATT_CHR_F_READ_AUTHEN | + BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_WRITE_AUTHEN | + BLE_GATT_CHR_F_WRITE | + BLE_GATT_CHR_F_WRITE_AUTHEN, + }, { + .uuid = PTS_UUID_DECLARE(PTS_CHR_RELIABLE_WRITE), + .access_cb = gatt_svr_rel_write_test, + .flags = BLE_GATT_CHR_F_WRITE | + BLE_GATT_CHR_F_RELIABLE_WRITE, + }, { + .uuid = PTS_UUID_DECLARE(PTS_CHR_READ_WRITE_ENC), + .access_cb = gatt_svr_read_write_enc_test, + .flags = BLE_GATT_CHR_F_READ_ENC | + BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_WRITE | + BLE_GATT_CHR_F_WRITE_ENC, + .min_key_size = 16, + }, { + .uuid = PTS_UUID_DECLARE(PTS_LONG_CHR_READ_WRITE), + .access_cb = gatt_svr_read_write_long_test, + .flags = BLE_GATT_CHR_F_WRITE | + BLE_GATT_CHR_F_READ, + }, { + .uuid = PTS_UUID_DECLARE(PTS_LONG_CHR_READ_WRITE_ALT), + .access_cb = gatt_svr_read_write_long_test, + .flags = BLE_GATT_CHR_F_WRITE | + BLE_GATT_CHR_F_READ, + }, { + .uuid = PTS_UUID_DECLARE(PTS_CHR_NOTIFY), + .access_cb = gatt_svr_read_write_test, + .val_handle = ¬ify_handle, + .flags = BLE_GATT_CHR_F_NOTIFY | + BLE_GATT_CHR_F_INDICATE, + }, { + 0, /* No more characteristics in this service. */ + } + }, + }, { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = PTS_UUID_DECLARE_ALT(PTS_SVC), + .characteristics = (struct ble_gatt_chr_def[]) {{ + .uuid = PTS_UUID_DECLARE_ALT(PTS_CHR_READ_WRITE), + .access_cb = gatt_svr_read_write_test, + .flags = BLE_GATT_CHR_F_WRITE | + BLE_GATT_CHR_F_READ, + }, { + 0, /* No more characteristics in this service */ + }}, + }, { + 0, /* No more services. */ + }, }; -static void attr_value_changed_ev(uint16_t handle, struct os_mbuf *data) +static void +attr_value_changed_ev(uint16_t handle, struct os_mbuf *data) { - struct gatt_attr_value_changed_ev *ev; - struct os_mbuf *buf = os_msys_get(0, 0); + struct gatt_attr_value_changed_ev *ev; + struct os_mbuf *buf = os_msys_get(0, 0); - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - net_buf_simple_init(buf, 0); - ev = net_buf_simple_add(buf, sizeof(*ev)); + net_buf_simple_init(buf, 0); + ev = net_buf_simple_add(buf, sizeof(*ev)); - ev->handle = sys_cpu_to_le16(handle); - ev->data_length = sys_cpu_to_le16(os_mbuf_len(data)); - os_mbuf_appendfrom(buf, data, 0, os_mbuf_len(data)); + ev->handle = sys_cpu_to_le16(handle); + ev->data_length = sys_cpu_to_le16(os_mbuf_len(data)); + os_mbuf_appendfrom(buf, data, 0, os_mbuf_len(data)); - tester_send_buf(BTP_SERVICE_ID_GATT, GATT_EV_ATTR_VALUE_CHANGED, - CONTROLLER_INDEX, buf); + tester_send_buf(BTP_SERVICE_ID_GATT, GATT_EV_ATTR_VALUE_CHANGED, + CONTROLLER_INDEX, buf); } static int gatt_svr_chr_write(uint16_t conn_handle, uint16_t attr_handle, - struct os_mbuf *om, uint16_t min_len, uint16_t max_len, - void *dst, uint16_t *len) + struct os_mbuf *om, uint16_t min_len, uint16_t max_len, + void *dst, uint16_t *len) { - uint16_t om_len; - int rc; + uint16_t om_len; + int rc; - om_len = OS_MBUF_PKTLEN(om); - if (om_len < min_len || om_len > max_len) { - return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; - } + om_len = OS_MBUF_PKTLEN(om); + if (om_len < min_len || om_len > max_len) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } - rc = ble_hs_mbuf_to_flat(om, dst, max_len, len); - if (rc != 0) { - return BLE_ATT_ERR_UNLIKELY; - } + rc = ble_hs_mbuf_to_flat(om, dst, max_len, len); + if (rc != 0) { + return BLE_ATT_ERR_UNLIKELY; + } - attr_value_changed_ev(attr_handle, om); + attr_value_changed_ev(attr_handle, om); - return 0; + return 0; } static uint16_t extract_uuid16_from_pts_uuid128(const ble_uuid_t *uuid) { - const uint8_t *u8ptr; - uint16_t uuid16; + const uint8_t *u8ptr; + uint16_t uuid16; - u8ptr = BLE_UUID128(uuid)->value; - uuid16 = u8ptr[12]; - uuid16 |= (uint16_t)u8ptr[13] << 8; - return uuid16; + u8ptr = BLE_UUID128(uuid)->value; + uuid16 = u8ptr[12]; + uuid16 |= (uint16_t) u8ptr[13] << 8; + return uuid16; } static int gatt_svr_read_write_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg) + struct ble_gatt_access_ctxt *ctxt, + void *arg) { - uint16_t uuid16; - int rc; - - uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); - assert(uuid16 != 0); - - switch (uuid16) { - case PTS_CHR_READ_WRITE: - case PTS_CHR_READ_WRITE_ALT: - if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_short_val, - &gatt_svr_pts_static_short_val, NULL); - return rc; - } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { - rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_short_val, - sizeof gatt_svr_pts_static_short_val); - return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; - } - default: - assert(0); - return BLE_ATT_ERR_UNLIKELY; - } + uint16_t uuid16; + int rc; + + uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); + assert(uuid16 != 0); + + switch (uuid16) { + case PTS_CHR_READ_WRITE: + case PTS_CHR_READ_WRITE_ALT: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(conn_handle, attr_handle, + ctxt->om, 0, + sizeof gatt_svr_pts_static_short_val, + &gatt_svr_pts_static_short_val, NULL); + return rc; + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_short_val, + sizeof gatt_svr_pts_static_short_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } } static int gatt_svr_read_write_long_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg) + struct ble_gatt_access_ctxt *ctxt, + void *arg) { - uint16_t uuid16; - int rc; - - uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); - assert(uuid16 != 0); - - switch (uuid16) { - case PTS_LONG_CHR_READ_WRITE: - case PTS_LONG_CHR_READ_WRITE_ALT: - if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_long_val, - &gatt_svr_pts_static_long_val, NULL); - return rc; - } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { - rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_long_val, - sizeof gatt_svr_pts_static_long_val); - return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; - } - default: - assert(0); - return BLE_ATT_ERR_UNLIKELY; - } + uint16_t uuid16; + int rc; + + uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); + assert(uuid16 != 0); + + switch (uuid16) { + case PTS_LONG_CHR_READ_WRITE: + case PTS_LONG_CHR_READ_WRITE_ALT: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(conn_handle, attr_handle, + ctxt->om, 0, + sizeof gatt_svr_pts_static_long_val, + &gatt_svr_pts_static_long_val, NULL); + return rc; + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_long_val, + sizeof gatt_svr_pts_static_long_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } } static int gatt_svr_read_write_auth_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg) + struct ble_gatt_access_ctxt *ctxt, + void *arg) { - uint16_t uuid16; - int rc; - - uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); - assert(uuid16 != 0); - - switch (uuid16) { - case PTS_CHR_READ_WRITE_AUTHEN: - if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_val, - &gatt_svr_pts_static_val, NULL); - return rc; - } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { - rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_val, - sizeof gatt_svr_pts_static_val); - return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; - } - default: - assert(0); - return BLE_ATT_ERR_UNLIKELY; - } + uint16_t uuid16; + int rc; + + uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); + assert(uuid16 != 0); + + switch (uuid16) { + case PTS_CHR_READ_WRITE_AUTHEN: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(conn_handle, attr_handle, + ctxt->om, 0, + sizeof gatt_svr_pts_static_val, + &gatt_svr_pts_static_val, NULL); + return rc; + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_val, + sizeof gatt_svr_pts_static_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } } static int gatt_svr_read_write_enc_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg) + struct ble_gatt_access_ctxt *ctxt, + void *arg) { - uint16_t uuid16; - int rc; - - uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); - assert(uuid16 != 0); - - switch (uuid16) { - case PTS_CHR_READ_WRITE_ENC: - if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { - rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_val, - sizeof gatt_svr_pts_static_val); - return rc; - } else if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_val, - &gatt_svr_pts_static_val, NULL); - return rc; - } - default: - assert(0); - return BLE_ATT_ERR_UNLIKELY; - } + uint16_t uuid16; + int rc; + + uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); + assert(uuid16 != 0); + + switch (uuid16) { + case PTS_CHR_READ_WRITE_ENC: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_val, + sizeof gatt_svr_pts_static_val); + return rc; + } else if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(conn_handle, attr_handle, + ctxt->om, 0, + sizeof gatt_svr_pts_static_val, + &gatt_svr_pts_static_val, NULL); + return rc; + } + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } } static int gatt_svr_dsc_read_write_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg) + struct ble_gatt_access_ctxt *ctxt, + void *arg) { - uint16_t uuid16; - int rc; - - uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); - assert(uuid16 != 0); - - switch (uuid16) { - case PTS_DSC_READ_WRITE: - if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_DSC) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_short_val, - &gatt_svr_pts_static_short_val, NULL); - return rc; - } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC) { - rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_short_val, - sizeof gatt_svr_pts_static_short_val); - return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; - } - default: - assert(0); - return BLE_ATT_ERR_UNLIKELY; - } + uint16_t uuid16; + int rc; + + uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); + assert(uuid16 != 0); + + switch (uuid16) { + case PTS_DSC_READ_WRITE: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_DSC) { + rc = gatt_svr_chr_write(conn_handle, attr_handle, + ctxt->om, 0, + sizeof gatt_svr_pts_static_short_val, + &gatt_svr_pts_static_short_val, NULL); + return rc; + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC) { + rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_short_val, + sizeof gatt_svr_pts_static_short_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } } static int gatt_svr_dsc_read_write_long_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg) + struct ble_gatt_access_ctxt *ctxt, + void *arg) { - uint16_t uuid16; - int rc; - - uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); - assert(uuid16 != 0); - - switch (uuid16) { - case PTS_LONG_DSC_READ_WRITE: - if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_DSC) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_long_val, - &gatt_svr_pts_static_long_val, NULL); - return rc; - } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC) { - rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_long_val, - sizeof gatt_svr_pts_static_long_val); - return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; - } - default: - assert(0); - return BLE_ATT_ERR_UNLIKELY; - } + uint16_t uuid16; + int rc; + + uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); + assert(uuid16 != 0); + + switch (uuid16) { + case PTS_LONG_DSC_READ_WRITE: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_DSC) { + rc = gatt_svr_chr_write(conn_handle, attr_handle, + ctxt->om, 0, + sizeof gatt_svr_pts_static_long_val, + &gatt_svr_pts_static_long_val, NULL); + return rc; + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC) { + rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_long_val, + sizeof gatt_svr_pts_static_long_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } } static int gatt_svr_dsc_read_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg) + struct ble_gatt_access_ctxt *ctxt, + void *arg) { - uint16_t uuid16; - int rc; - - uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); - assert(uuid16 != 0); - - switch (uuid16) { - case PTS_DSC_READ: - if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC) { - rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_long_val, - sizeof gatt_svr_pts_static_long_val); - return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; - } - default: - assert(0); - return BLE_ATT_ERR_UNLIKELY; - } + uint16_t uuid16; + int rc; + + uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); + assert(uuid16 != 0); + + switch (uuid16) { + case PTS_DSC_READ: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC) { + rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_long_val, + sizeof gatt_svr_pts_static_long_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } } static int gatt_svr_write_no_rsp_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg) + struct ble_gatt_access_ctxt *ctxt, + void *arg) { - uint16_t uuid16; - int rc; - - uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); - assert(uuid16 != 0); - - switch (uuid16) { - case PTS_CHR_WRITE_NO_RSP: - if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_short_val, - &gatt_svr_pts_static_short_val, NULL); - return rc; - } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { - rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_short_val, - sizeof gatt_svr_pts_static_short_val); - return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; - } - default: - assert(0); - return BLE_ATT_ERR_UNLIKELY; - } + uint16_t uuid16; + int rc; + + uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); + assert(uuid16 != 0); + + switch (uuid16) { + case PTS_CHR_WRITE_NO_RSP: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(conn_handle, attr_handle, + ctxt->om, 0, + sizeof gatt_svr_pts_static_short_val, + &gatt_svr_pts_static_short_val, NULL); + return rc; + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_short_val, + sizeof gatt_svr_pts_static_short_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } } static int gatt_svr_rel_write_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg) + struct ble_gatt_access_ctxt *ctxt, + void *arg) { - uint16_t uuid16; - int rc; - - uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); - assert(uuid16 != 0); - - switch (uuid16) { - case PTS_CHR_RELIABLE_WRITE: - if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_val, - &gatt_svr_pts_static_val, NULL); - return rc; - } - - default: - assert(0); - return BLE_ATT_ERR_UNLIKELY; - } + uint16_t uuid16; + int rc; + + uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); + assert(uuid16 != 0); + + switch (uuid16) { + case PTS_CHR_RELIABLE_WRITE: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(conn_handle, attr_handle, + ctxt->om, 0, + sizeof gatt_svr_pts_static_val, + &gatt_svr_pts_static_val, NULL); + return rc; + } + + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } } -static void start_server(uint8_t *data, uint16_t len) +static void +start_server(uint8_t *data, uint16_t len) { - struct gatt_start_server_rp rp; + struct gatt_start_server_rp rp; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - ble_gatts_show_local(); + ble_gatts_show_local(); - ble_svc_gatt_changed(0x0001, 0xffff); + ble_svc_gatt_changed(0x0001, 0xffff); - rp.db_attr_off = 0; - rp.db_attr_cnt = 0; + rp.db_attr_off = 0; + rp.db_attr_cnt = 0; - tester_send(BTP_SERVICE_ID_GATT, GATT_START_SERVER, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); + tester_send(BTP_SERVICE_ID_GATT, GATT_START_SERVER, CONTROLLER_INDEX, + (uint8_t *) &rp, sizeof(rp)); } /* Convert UUID from BTP command to bt_uuid */ -static uint8_t btp2bt_uuid(const uint8_t *uuid, uint8_t len, - ble_uuid_any_t *bt_uuid) +static uint8_t +btp2bt_uuid(const uint8_t *uuid, uint8_t len, + ble_uuid_any_t *bt_uuid) { - uint16_t le16; - - switch (len) { - case 0x02: /* UUID 16 */ - bt_uuid->u.type = BLE_UUID_TYPE_16; - memcpy(&le16, uuid, sizeof(le16)); - BLE_UUID16(bt_uuid)->value = sys_le16_to_cpu(le16); - break; - case 0x10: /* UUID 128*/ - bt_uuid->u.type = BLE_UUID_TYPE_128; - memcpy(BLE_UUID128(bt_uuid)->value, uuid, 16); - break; - default: - return BTP_STATUS_FAILED; - } - return BTP_STATUS_SUCCESS; + uint16_t le16; + + switch (len) { + case 0x02: /* UUID 16 */ + bt_uuid->u.type = BLE_UUID_TYPE_16; + memcpy(&le16, uuid, sizeof(le16)); + BLE_UUID16(bt_uuid)->value = sys_le16_to_cpu(le16); + break; + case 0x10: /* UUID 128*/ + bt_uuid->u.type = BLE_UUID_TYPE_128; + memcpy(BLE_UUID128(bt_uuid)->value, uuid, 16); + break; + default: + return BTP_STATUS_FAILED; + } + return BTP_STATUS_SUCCESS; } /* @@ -614,995 +616,1026 @@ static uint8_t btp2bt_uuid(const uint8_t *uuid, uint8_t len, * It is not intended to be used by client and server at the same time. */ static struct { - uint16_t len; - uint8_t buf[MAX_BUFFER_SIZE]; + uint16_t len; + uint8_t buf[MAX_BUFFER_SIZE]; } gatt_buf; -static void *gatt_buf_add(const void *data, size_t len) +static void * +gatt_buf_add(const void *data, size_t len) { - void *ptr = gatt_buf.buf + gatt_buf.len; + void *ptr = gatt_buf.buf + gatt_buf.len; - if ((len + gatt_buf.len) > MAX_BUFFER_SIZE) { - return NULL; - } + if ((len + gatt_buf.len) > MAX_BUFFER_SIZE) { + return NULL; + } - if (data) { - memcpy(ptr, data, len); - } else { - (void)memset(ptr, 0, len); - } + if (data) { + memcpy(ptr, data, len); + } else { + (void) memset(ptr, 0, len); + } - gatt_buf.len += len; + gatt_buf.len += len; - SYS_LOG_DBG("%d/%d used", gatt_buf.len, MAX_BUFFER_SIZE); + SYS_LOG_DBG("%d/%d used", gatt_buf.len, MAX_BUFFER_SIZE); - return ptr; + return ptr; } -static void *gatt_buf_reserve(size_t len) +static void * +gatt_buf_reserve(size_t len) { - return gatt_buf_add(NULL, len); + return gatt_buf_add(NULL, len); } -static void gatt_buf_clear(void) +static void +gatt_buf_clear(void) { - (void)memset(&gatt_buf, 0, sizeof(gatt_buf)); + (void) memset(&gatt_buf, 0, sizeof(gatt_buf)); } -static void discover_destroy(void) +static void +discover_destroy(void) { - gatt_buf_clear(); + gatt_buf_clear(); } -static void read_destroy() +static void +read_destroy() { - gatt_buf_clear(); + gatt_buf_clear(); } -static int read_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) +static int +read_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) { - struct gatt_read_rp *rp = (void *) gatt_buf.buf; - uint8_t btp_opcode = (uint8_t) (int) arg; - - SYS_LOG_DBG("status=%d", error->status); - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->att_response = (uint8_t) BLE_HS_ATT_ERR(error->status); - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); - read_destroy(); - return 0; - } - - if (!gatt_buf_add(attr->om->om_data, attr->om->om_len)) { - tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - read_destroy(); - return 0; - } - - rp->data_length += attr->om->om_len; - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); - read_destroy(); - - return 0; + struct gatt_read_rp *rp = (void *) gatt_buf.buf; + uint8_t btp_opcode = (uint8_t) (int) arg; + + SYS_LOG_DBG("status=%d", error->status); + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->att_response = (uint8_t) BLE_HS_ATT_ERR(error->status); + tester_send(BTP_SERVICE_ID_GATT, btp_opcode, + CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + read_destroy(); + return 0; + } + + if (!gatt_buf_add(attr->om->om_data, attr->om->om_len)) { + tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, + CONTROLLER_INDEX, BTP_STATUS_FAILED); + read_destroy(); + return 0; + } + + rp->data_length += attr->om->om_len; + tester_send(BTP_SERVICE_ID_GATT, btp_opcode, + CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + read_destroy(); + + return 0; } -static void read(uint8_t *data, uint16_t len) +static void +read(uint8_t *data, uint16_t len) { - const struct gatt_read_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - int rc; + const struct gatt_read_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - goto fail; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + goto fail; + } - /* Clear buffer */ - read_destroy(); + /* Clear buffer */ + read_destroy(); - if (!gatt_buf_reserve(sizeof(struct gatt_read_rp))) { - goto fail; - } + if (!gatt_buf_reserve(sizeof(struct gatt_read_rp))) { + goto fail; + } - if (ble_gattc_read(conn.conn_handle, sys_le16_to_cpu(cmd->handle), - read_cb, (void *)GATT_READ)) { - read_destroy(); - goto fail; - } + if (ble_gattc_read(conn.conn_handle, sys_le16_to_cpu(cmd->handle), + read_cb, (void *) GATT_READ)) { + read_destroy(); + goto fail; + } - return; + return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_READ, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_READ, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static int read_long_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) +static int +read_long_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) { - struct gatt_read_rp *rp = (void *) gatt_buf.buf; - uint8_t btp_opcode = (uint8_t) (int) arg; - - SYS_LOG_DBG("status=%d", error->status); - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->att_response = (uint8_t) BLE_HS_ATT_ERR(error->status); - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); - read_destroy(); - return 0; - } - - if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); - read_destroy(); - return 0; - } - - if (gatt_buf_add(attr->om->om_data, attr->om->om_len) == NULL) { - tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - read_destroy(); - return BLE_HS_ENOMEM; - } - - rp->data_length += attr->om->om_len; - - return 0; + struct gatt_read_rp *rp = (void *) gatt_buf.buf; + uint8_t btp_opcode = (uint8_t) (int) arg; + + SYS_LOG_DBG("status=%d", error->status); + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->att_response = (uint8_t) BLE_HS_ATT_ERR(error->status); + tester_send(BTP_SERVICE_ID_GATT, btp_opcode, + CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + read_destroy(); + return 0; + } + + if (error->status == BLE_HS_EDONE) { + tester_send(BTP_SERVICE_ID_GATT, btp_opcode, + CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + read_destroy(); + return 0; + } + + if (gatt_buf_add(attr->om->om_data, attr->om->om_len) == NULL) { + tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, + CONTROLLER_INDEX, BTP_STATUS_FAILED); + read_destroy(); + return BLE_HS_ENOMEM; + } + + rp->data_length += attr->om->om_len; + + return 0; } -static void read_long(uint8_t *data, uint16_t len) +static void +read_long(uint8_t *data, uint16_t len) { - const struct gatt_read_long_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - int rc; + const struct gatt_read_long_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - goto fail; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + goto fail; + } - /* Clear buffer */ - read_destroy(); + /* Clear buffer */ + read_destroy(); - if (!gatt_buf_reserve(sizeof(struct gatt_read_rp))) { - goto fail; - } + if (!gatt_buf_reserve(sizeof(struct gatt_read_rp))) { + goto fail; + } - if (ble_gattc_read_long(conn.conn_handle, - sys_le16_to_cpu(cmd->handle), - sys_le16_to_cpu(cmd->offset), - read_long_cb, (void *)GATT_READ_LONG)) { - read_destroy(); - goto fail; - } + if (ble_gattc_read_long(conn.conn_handle, + sys_le16_to_cpu(cmd->handle), + sys_le16_to_cpu(cmd->offset), + read_long_cb, (void *) GATT_READ_LONG)) { + read_destroy(); + goto fail; + } - return; + return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_READ_LONG, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_READ_LONG, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static void read_multiple(uint8_t *data, uint16_t len) +static void +read_multiple(uint8_t *data, uint16_t len) { - const struct gatt_read_multiple_cmd *cmd = (void *) data; - uint16_t handles[cmd->handles_count]; - struct ble_gap_conn_desc conn; - int rc, i; + const struct gatt_read_multiple_cmd *cmd = (void *) data; + uint16_t handles[cmd->handles_count]; + struct ble_gap_conn_desc conn; + int rc, i; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - for (i = 0; i < ARRAY_SIZE(handles); i++) { - handles[i] = sys_le16_to_cpu(cmd->handles[i]); - } + for (i = 0; i < ARRAY_SIZE(handles); i++) { + handles[i] = sys_le16_to_cpu(cmd->handles[i]); + } - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - goto fail; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + goto fail; + } - /* Clear buffer */ - read_destroy(); + /* Clear buffer */ + read_destroy(); - if (!gatt_buf_reserve(sizeof(struct gatt_read_rp))) { - goto fail; - } + if (!gatt_buf_reserve(sizeof(struct gatt_read_rp))) { + goto fail; + } - if (ble_gattc_read_mult(conn.conn_handle, handles, - cmd->handles_count, read_cb, - (void *)GATT_READ_MULTIPLE)) { - read_destroy(); - goto fail; - } + if (ble_gattc_read_mult(conn.conn_handle, handles, + cmd->handles_count, read_cb, + (void *) GATT_READ_MULTIPLE)) { + read_destroy(); + goto fail; + } - return; + return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_READ_MULTIPLE, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_READ_MULTIPLE, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static void write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) +static void +write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) { - const struct gatt_write_without_rsp_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; + const struct gatt_write_without_rsp_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } - if (ble_gattc_write_no_rsp_flat(conn.conn_handle, - sys_le16_to_cpu(cmd->handle), cmd->data, - sys_le16_to_cpu(cmd->data_length))) { - status = BTP_STATUS_FAILED; - } + if (ble_gattc_write_no_rsp_flat(conn.conn_handle, + sys_le16_to_cpu(cmd->handle), cmd->data, + sys_le16_to_cpu(cmd->data_length))) { + status = BTP_STATUS_FAILED; + } rsp: - tester_rsp(BTP_SERVICE_ID_GATT, op, CONTROLLER_INDEX, status); + tester_rsp(BTP_SERVICE_ID_GATT, op, CONTROLLER_INDEX, status); } -static int write_rsp(uint16_t conn_handle, const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) +static int +write_rsp(uint16_t conn_handle, const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) { - uint8_t err = (uint8_t) error->status; - uint8_t btp_opcode = (uint8_t) (int) arg; + uint8_t err = (uint8_t) error->status; + uint8_t btp_opcode = (uint8_t) (int) arg; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, &err, sizeof(err)); - return 0; + tester_send(BTP_SERVICE_ID_GATT, btp_opcode, + CONTROLLER_INDEX, &err, sizeof(err)); + return 0; } -static void write(uint8_t *data, uint16_t len) +static void +write(uint8_t *data, uint16_t len) { - const struct gatt_write_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - int rc; + const struct gatt_write_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - goto fail; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + goto fail; + } - if (ble_gattc_write_flat(conn.conn_handle, sys_le16_to_cpu(cmd->handle), - cmd->data, sys_le16_to_cpu(cmd->data_length), - write_rsp, (void *) GATT_WRITE)) { - goto fail; - } + if (ble_gattc_write_flat(conn.conn_handle, sys_le16_to_cpu(cmd->handle), + cmd->data, sys_le16_to_cpu(cmd->data_length), + write_rsp, (void *) GATT_WRITE)) { + goto fail; + } - return; + return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_WRITE, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_WRITE, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static void write_long(uint8_t *data, uint16_t len) +static void +write_long(uint8_t *data, uint16_t len) { - const struct gatt_write_long_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - struct os_mbuf *om = NULL; - int rc = 0; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - goto fail; - } - - om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); - if (!om) { - SYS_LOG_ERR("Insufficient resources"); - goto fail; - } - - rc = ble_gattc_write_long(conn.conn_handle, - sys_le16_to_cpu(cmd->handle), - sys_le16_to_cpu(cmd->offset), - om, write_rsp, - (void *) GATT_WRITE_LONG); - if (!rc) { - return; - } + const struct gatt_write_long_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + struct os_mbuf *om = NULL; + int rc = 0; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + goto fail; + } + + om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); + if (!om) { + SYS_LOG_ERR("Insufficient resources"); + goto fail; + } + + rc = ble_gattc_write_long(conn.conn_handle, + sys_le16_to_cpu(cmd->handle), + sys_le16_to_cpu(cmd->offset), + om, write_rsp, + (void *) GATT_WRITE_LONG); + if (!rc) { + return; + } fail: - SYS_LOG_ERR("Failed to send Write Long request, rc=%d", rc); - os_mbuf_free_chain(om); - tester_rsp(BTP_SERVICE_ID_GATT, GATT_WRITE_LONG, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + SYS_LOG_ERR("Failed to send Write Long request, rc=%d", rc); + os_mbuf_free_chain(om); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_WRITE_LONG, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static int reliable_write_rsp(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attrs, - uint8_t num_attrs, - void *arg) +static int +reliable_write_rsp(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attrs, + uint8_t num_attrs, + void *arg) { - uint8_t err = (uint8_t) error->status; + uint8_t err = (uint8_t) error->status; - SYS_LOG_DBG("Reliable write status %d", err); + SYS_LOG_DBG("Reliable write status %d", err); - tester_send(BTP_SERVICE_ID_GATT, GATT_RELIABLE_WRITE, - CONTROLLER_INDEX, &err, sizeof(err)); - return 0; + tester_send(BTP_SERVICE_ID_GATT, GATT_RELIABLE_WRITE, + CONTROLLER_INDEX, &err, sizeof(err)); + return 0; } -static void reliable_write(uint8_t *data, uint16_t len) +static void +reliable_write(uint8_t *data, uint16_t len) { - const struct gatt_reliable_write_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - struct ble_gatt_attr attr; - struct os_mbuf *om = NULL; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - goto fail; - } - - om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); - /* This is required, because Nimble checks if - * the data is longer than offset - */ - if (os_mbuf_extend(om, sys_le16_to_cpu(cmd->offset) + 1) == NULL) { - goto fail; - } - - attr.handle = sys_le16_to_cpu(cmd->handle); - attr.offset = sys_le16_to_cpu(cmd->offset); - attr.om = om; - - if (ble_gattc_write_reliable(conn.conn_handle, &attr, 1, - reliable_write_rsp, NULL)) { - goto fail; - } - - return; + const struct gatt_reliable_write_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + struct ble_gatt_attr attr; + struct os_mbuf *om = NULL; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + goto fail; + } + + om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); + /* This is required, because Nimble checks if + * the data is longer than offset + */ + if (os_mbuf_extend(om, sys_le16_to_cpu(cmd->offset) + 1) == NULL) { + goto fail; + } + + attr.handle = sys_le16_to_cpu(cmd->handle); + attr.offset = sys_le16_to_cpu(cmd->offset); + attr.om = om; + + if (ble_gattc_write_reliable(conn.conn_handle, &attr, 1, + reliable_write_rsp, NULL)) { + goto fail; + } + + return; fail: - os_mbuf_free_chain(om); + os_mbuf_free_chain(om); - tester_rsp(BTP_SERVICE_ID_GATT, GATT_WRITE_LONG, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_WRITE_LONG, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } static struct bt_gatt_subscribe_params { - uint16_t ccc_handle; - uint16_t value; - uint16_t value_handle; + uint16_t ccc_handle; + uint16_t value; + uint16_t value_handle; } subscribe_params; -static void read_uuid(uint8_t *data, uint16_t len) +static void +read_uuid(uint8_t *data, uint16_t len) { - const struct gatt_read_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - ble_uuid_any_t uuid; - int rc; + const struct gatt_read_uuid_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + ble_uuid_any_t uuid; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - goto fail; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + goto fail; + } - if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { - goto fail; - } + if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { + goto fail; + } - /* Clear buffer */ - read_destroy(); + /* Clear buffer */ + read_destroy(); - if (!gatt_buf_reserve(sizeof(struct gatt_read_rp))) { - goto fail; - } + if (!gatt_buf_reserve(sizeof(struct gatt_read_rp))) { + goto fail; + } - if (ble_gattc_read_by_uuid(conn.conn_handle, - sys_le16_to_cpu(cmd->start_handle), - sys_le16_to_cpu(cmd->end_handle), &uuid.u, - read_long_cb, (void *)GATT_READ_UUID)) { - read_destroy(); - goto fail; - } + if (ble_gattc_read_by_uuid(conn.conn_handle, + sys_le16_to_cpu(cmd->start_handle), + sys_le16_to_cpu(cmd->end_handle), &uuid.u, + read_long_cb, (void *) GATT_READ_UUID)) { + read_destroy(); + goto fail; + } - return; + return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_READ, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_READ, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static int disc_prim_uuid_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - const struct ble_gatt_svc *gatt_svc, void *arg) +static int +disc_prim_uuid_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_svc *gatt_svc, void *arg) { - struct gatt_disc_prim_uuid_rp *rp = (void *) gatt_buf.buf; - struct gatt_service *service; - const ble_uuid_any_t *uuid; - uint8_t uuid_length; - uint8_t opcode = (uint8_t) (int) arg; - - SYS_LOG_DBG(""); - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - tester_rsp(BTP_SERVICE_ID_GATT, opcode, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - discover_destroy(); - return 0; - } - - if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, opcode, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); - discover_destroy(); - return 0; - } - - uuid = &gatt_svc->uuid; - uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); - - service = gatt_buf_reserve(sizeof(*service) + uuid_length); - if (!service) { - tester_rsp(BTP_SERVICE_ID_GATT, opcode, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - discover_destroy(); - return BLE_HS_ENOMEM; - } - - service->start_handle = sys_cpu_to_le16(gatt_svc->start_handle); - service->end_handle = sys_cpu_to_le16(gatt_svc->end_handle); - service->uuid_length = uuid_length; - - if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); - memcpy(service->uuid, &u16, uuid_length); - } else { - memcpy(service->uuid, BLE_UUID128(uuid)->value, - uuid_length); - } - - rp->services_count++; - - return 0; + struct gatt_disc_prim_uuid_rp *rp = (void *) gatt_buf.buf; + struct gatt_service *service; + const ble_uuid_any_t *uuid; + uint8_t uuid_length; + uint8_t opcode = (uint8_t) (int) arg; + + SYS_LOG_DBG(""); + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + tester_rsp(BTP_SERVICE_ID_GATT, opcode, + CONTROLLER_INDEX, BTP_STATUS_FAILED); + discover_destroy(); + return 0; + } + + if (error->status == BLE_HS_EDONE) { + tester_send(BTP_SERVICE_ID_GATT, opcode, + CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + discover_destroy(); + return 0; + } + + uuid = &gatt_svc->uuid; + uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); + + service = gatt_buf_reserve(sizeof(*service) + uuid_length); + if (!service) { + tester_rsp(BTP_SERVICE_ID_GATT, opcode, + CONTROLLER_INDEX, BTP_STATUS_FAILED); + discover_destroy(); + return BLE_HS_ENOMEM; + } + + service->start_handle = sys_cpu_to_le16(gatt_svc->start_handle); + service->end_handle = sys_cpu_to_le16(gatt_svc->end_handle); + service->uuid_length = uuid_length; + + if (uuid->u.type == BLE_UUID_TYPE_16) { + uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + memcpy(service->uuid, &u16, uuid_length); + } else { + memcpy(service->uuid, BLE_UUID128(uuid)->value, + uuid_length); + } + + rp->services_count++; + + return 0; } -static int disc_all_desc_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - uint16_t chr_val_handle, - const struct ble_gatt_dsc *gatt_dsc, - void *arg) +static int +disc_all_desc_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + uint16_t chr_val_handle, + const struct ble_gatt_dsc *gatt_dsc, + void *arg) { - struct gatt_disc_all_desc_rp *rp = (void *) gatt_buf.buf; - struct gatt_descriptor *dsc; - const ble_uuid_any_t *uuid; - uint8_t uuid_length; - - SYS_LOG_DBG(""); - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_DESC, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - discover_destroy(); - return 0; - } - - if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_DESC, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); - discover_destroy(); - return 0; - } - - uuid = &gatt_dsc->uuid; - uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); - - dsc = gatt_buf_reserve(sizeof(*dsc) + uuid_length); - if (!dsc) { - tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_DESC, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - discover_destroy(); - return BLE_HS_ENOMEM; - } - - dsc->descriptor_handle = sys_cpu_to_le16(gatt_dsc->handle); - dsc->uuid_length = uuid_length; - - if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); - memcpy(dsc->uuid, &u16, uuid_length); - } else { - memcpy(dsc->uuid, BLE_UUID128(uuid)->value, uuid_length); - } - - rp->descriptors_count++; - - return 0; + struct gatt_disc_all_desc_rp *rp = (void *) gatt_buf.buf; + struct gatt_descriptor *dsc; + const ble_uuid_any_t *uuid; + uint8_t uuid_length; + + SYS_LOG_DBG(""); + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_DESC, + CONTROLLER_INDEX, BTP_STATUS_FAILED); + discover_destroy(); + return 0; + } + + if (error->status == BLE_HS_EDONE) { + tester_send(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_DESC, + CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + discover_destroy(); + return 0; + } + + uuid = &gatt_dsc->uuid; + uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); + + dsc = gatt_buf_reserve(sizeof(*dsc) + uuid_length); + if (!dsc) { + tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_DESC, + CONTROLLER_INDEX, BTP_STATUS_FAILED); + discover_destroy(); + return BLE_HS_ENOMEM; + } + + dsc->descriptor_handle = sys_cpu_to_le16(gatt_dsc->handle); + dsc->uuid_length = uuid_length; + + if (uuid->u.type == BLE_UUID_TYPE_16) { + uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + memcpy(dsc->uuid, &u16, uuid_length); + } else { + memcpy(dsc->uuid, BLE_UUID128(uuid)->value, uuid_length); + } + + rp->descriptors_count++; + + return 0; } -static void disc_all_prim_svcs(uint8_t *data, uint16_t len) +static void +disc_all_prim_svcs(uint8_t *data, uint16_t len) { - struct ble_gap_conn_desc conn; - int rc; + struct ble_gap_conn_desc conn; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - goto fail; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + goto fail; + } - if (!gatt_buf_reserve(sizeof(struct gatt_disc_all_prim_svcs_rp))) { - goto fail; - } + if (!gatt_buf_reserve(sizeof(struct gatt_disc_all_prim_svcs_rp))) { + goto fail; + } - if (ble_gattc_disc_all_svcs(conn.conn_handle, disc_prim_uuid_cb, - (void *) GATT_DISC_ALL_PRIM_SVCS)) { - discover_destroy(); - goto fail; - } + if (ble_gattc_disc_all_svcs(conn.conn_handle, disc_prim_uuid_cb, + (void *) GATT_DISC_ALL_PRIM_SVCS)) { + discover_destroy(); + goto fail; + } - return; + return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_PRIM_SVCS, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_PRIM_SVCS, + CONTROLLER_INDEX, BTP_STATUS_FAILED); } -static void disc_all_desc(uint8_t *data, uint16_t len) +static void +disc_all_desc(uint8_t *data, uint16_t len) { - const struct gatt_disc_all_desc_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint16_t start_handle, end_handle; - int rc; + const struct gatt_disc_all_desc_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint16_t start_handle, end_handle; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - goto fail; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + goto fail; + } - if (!gatt_buf_reserve(sizeof(struct gatt_disc_all_desc_rp))) { - goto fail; - } + if (!gatt_buf_reserve(sizeof(struct gatt_disc_all_desc_rp))) { + goto fail; + } - start_handle = sys_le16_to_cpu(cmd->start_handle) - 1; - end_handle = sys_le16_to_cpu(cmd->end_handle); + start_handle = sys_le16_to_cpu(cmd->start_handle) - 1; + end_handle = sys_le16_to_cpu(cmd->end_handle); - rc = ble_gattc_disc_all_dscs(conn.conn_handle, start_handle, end_handle, - disc_all_desc_cb, NULL); + rc = ble_gattc_disc_all_dscs(conn.conn_handle, start_handle, end_handle, + disc_all_desc_cb, NULL); - SYS_LOG_DBG("rc=%d", rc); + SYS_LOG_DBG("rc=%d", rc); - if (rc) { - discover_destroy(); - goto fail; - } + if (rc) { + discover_destroy(); + goto fail; + } - return; + return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_DESC, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_DESC, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static int find_included_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - const struct ble_gatt_svc *gatt_svc, void *arg) +static int +find_included_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_svc *gatt_svc, void *arg) { - struct gatt_find_included_rp *rp = (void *) gatt_buf.buf; - struct gatt_included *included; - const ble_uuid_any_t *uuid; - int service_handle = (int) arg; - uint8_t uuid_length; - - SYS_LOG_DBG(""); - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - tester_rsp(BTP_SERVICE_ID_GATT, GATT_FIND_INCLUDED, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - discover_destroy(); - return 0; - } - - if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, GATT_FIND_INCLUDED, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); - discover_destroy(); - return 0; - } - - uuid = &gatt_svc->uuid; - uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); - - - included = gatt_buf_reserve(sizeof(*included) + uuid_length); - if (!included) { - tester_rsp(BTP_SERVICE_ID_GATT, GATT_FIND_INCLUDED, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - discover_destroy(); - return BLE_HS_ENOMEM; - } - - /* FIXME */ - included->included_handle = sys_cpu_to_le16(service_handle + 1 + - rp->services_count); - included->service.start_handle = sys_cpu_to_le16(gatt_svc->start_handle); - included->service.end_handle = sys_cpu_to_le16(gatt_svc->end_handle); - included->service.uuid_length = uuid_length; - - if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); - memcpy(included->service.uuid, &u16, uuid_length); - } else { - memcpy(included->service.uuid, BLE_UUID128(uuid)->value, - uuid_length); - } - - rp->services_count++; - - return 0; + struct gatt_find_included_rp *rp = (void *) gatt_buf.buf; + struct gatt_included *included; + const ble_uuid_any_t *uuid; + int service_handle = (int) arg; + uint8_t uuid_length; + + SYS_LOG_DBG(""); + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + tester_rsp(BTP_SERVICE_ID_GATT, GATT_FIND_INCLUDED, + CONTROLLER_INDEX, BTP_STATUS_FAILED); + discover_destroy(); + return 0; + } + + if (error->status == BLE_HS_EDONE) { + tester_send(BTP_SERVICE_ID_GATT, GATT_FIND_INCLUDED, + CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + discover_destroy(); + return 0; + } + + uuid = &gatt_svc->uuid; + uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); + + included = gatt_buf_reserve(sizeof(*included) + uuid_length); + if (!included) { + tester_rsp(BTP_SERVICE_ID_GATT, GATT_FIND_INCLUDED, + CONTROLLER_INDEX, BTP_STATUS_FAILED); + discover_destroy(); + return BLE_HS_ENOMEM; + } + + /* FIXME */ + included->included_handle = sys_cpu_to_le16(service_handle + 1 + + rp->services_count); + included->service.start_handle = sys_cpu_to_le16(gatt_svc->start_handle); + included->service.end_handle = sys_cpu_to_le16(gatt_svc->end_handle); + included->service.uuid_length = uuid_length; + + if (uuid->u.type == BLE_UUID_TYPE_16) { + uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + memcpy(included->service.uuid, &u16, uuid_length); + } else { + memcpy(included->service.uuid, BLE_UUID128(uuid)->value, + uuid_length); + } + + rp->services_count++; + + return 0; } -static int disc_chrc_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - const struct ble_gatt_chr *gatt_chr, void *arg) +static int +disc_chrc_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_chr *gatt_chr, void *arg) { - struct gatt_disc_chrc_rp *rp = (void *) gatt_buf.buf; - struct gatt_characteristic *chrc; - const ble_uuid_any_t *uuid; - uint8_t btp_opcode = (uint8_t) (int) arg; - uint8_t uuid_length; - - SYS_LOG_DBG(""); - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - discover_destroy(); - return 0; - } - - if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); - discover_destroy(); - return 0; - } - - uuid = &gatt_chr->uuid; - uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); - - chrc = gatt_buf_reserve(sizeof(*chrc) + uuid_length); - if (!chrc) { - tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - discover_destroy(); - return BLE_HS_ENOMEM; - } - - chrc->characteristic_handle = sys_cpu_to_le16(gatt_chr->def_handle); - chrc->properties = gatt_chr->properties; - chrc->value_handle = sys_cpu_to_le16(gatt_chr->val_handle); - chrc->uuid_length = uuid_length; - - if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); - memcpy(chrc->uuid, &u16, uuid_length); - } else { - memcpy(chrc->uuid, BLE_UUID128(uuid)->value, - uuid_length); - } - - rp->characteristics_count++; - - return 0; + struct gatt_disc_chrc_rp *rp = (void *) gatt_buf.buf; + struct gatt_characteristic *chrc; + const ble_uuid_any_t *uuid; + uint8_t btp_opcode = (uint8_t) (int) arg; + uint8_t uuid_length; + + SYS_LOG_DBG(""); + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, + CONTROLLER_INDEX, BTP_STATUS_FAILED); + discover_destroy(); + return 0; + } + + if (error->status == BLE_HS_EDONE) { + tester_send(BTP_SERVICE_ID_GATT, btp_opcode, + CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + discover_destroy(); + return 0; + } + + uuid = &gatt_chr->uuid; + uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); + + chrc = gatt_buf_reserve(sizeof(*chrc) + uuid_length); + if (!chrc) { + tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, + CONTROLLER_INDEX, BTP_STATUS_FAILED); + discover_destroy(); + return BLE_HS_ENOMEM; + } + + chrc->characteristic_handle = sys_cpu_to_le16(gatt_chr->def_handle); + chrc->properties = gatt_chr->properties; + chrc->value_handle = sys_cpu_to_le16(gatt_chr->val_handle); + chrc->uuid_length = uuid_length; + + if (uuid->u.type == BLE_UUID_TYPE_16) { + uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + memcpy(chrc->uuid, &u16, uuid_length); + } else { + memcpy(chrc->uuid, BLE_UUID128(uuid)->value, + uuid_length); + } + + rp->characteristics_count++; + + return 0; } -static void disc_chrc_uuid(uint8_t *data, uint16_t len) +static void +disc_chrc_uuid(uint8_t *data, uint16_t len) { - const struct gatt_disc_chrc_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint16_t start_handle, end_handle; - ble_uuid_any_t uuid; - int rc; + const struct gatt_disc_chrc_uuid_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint16_t start_handle, end_handle; + ble_uuid_any_t uuid; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - goto fail; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + goto fail; + } - if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { - goto fail; - } + if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { + goto fail; + } - if (!gatt_buf_reserve(sizeof(struct gatt_disc_chrc_rp))) { - goto fail; - } + if (!gatt_buf_reserve(sizeof(struct gatt_disc_chrc_rp))) { + goto fail; + } - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); + start_handle = sys_le16_to_cpu(cmd->start_handle); + end_handle = sys_le16_to_cpu(cmd->end_handle); - if (ble_gattc_disc_chrs_by_uuid(conn.conn_handle, start_handle, - end_handle, &uuid.u, disc_chrc_cb, - (void *)GATT_DISC_CHRC_UUID)) { - discover_destroy(); - goto fail; - } + if (ble_gattc_disc_chrs_by_uuid(conn.conn_handle, start_handle, + end_handle, &uuid.u, disc_chrc_cb, + (void *) GATT_DISC_CHRC_UUID)) { + discover_destroy(); + goto fail; + } - return; + return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_CHRC_UUID, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_CHRC_UUID, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static void disc_prim_uuid(uint8_t *data, uint16_t len) +static void +disc_prim_uuid(uint8_t *data, uint16_t len) { - const struct gatt_disc_prim_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - ble_uuid_any_t uuid; - int rc; + const struct gatt_disc_prim_uuid_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + ble_uuid_any_t uuid; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - goto fail; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + goto fail; + } - if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { - goto fail; - } + if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { + goto fail; + } - if (!gatt_buf_reserve(sizeof(struct gatt_disc_prim_uuid_rp))) { - goto fail; - } + if (!gatt_buf_reserve(sizeof(struct gatt_disc_prim_uuid_rp))) { + goto fail; + } - if (ble_gattc_disc_svc_by_uuid(conn.conn_handle, - &uuid.u, disc_prim_uuid_cb, - (void *) GATT_DISC_PRIM_UUID)) { - discover_destroy(); - goto fail; - } + if (ble_gattc_disc_svc_by_uuid(conn.conn_handle, + &uuid.u, disc_prim_uuid_cb, + (void *) GATT_DISC_PRIM_UUID)) { + discover_destroy(); + goto fail; + } - return; + return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_PRIM_UUID, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_PRIM_UUID, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static void disc_all_chrc(uint8_t *data, uint16_t len) +static void +disc_all_chrc(uint8_t *data, uint16_t len) { - const struct gatt_disc_all_chrc_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint16_t start_handle, end_handle; - int rc; + const struct gatt_disc_all_chrc_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint16_t start_handle, end_handle; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - SYS_LOG_DBG("Conn find failed"); - goto fail; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + SYS_LOG_DBG("Conn find failed"); + goto fail; + } - if (!gatt_buf_reserve(sizeof(struct gatt_disc_chrc_rp))) { - SYS_LOG_DBG("Buf reserve failed"); - goto fail; - } + if (!gatt_buf_reserve(sizeof(struct gatt_disc_chrc_rp))) { + SYS_LOG_DBG("Buf reserve failed"); + goto fail; + } - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); + start_handle = sys_le16_to_cpu(cmd->start_handle); + end_handle = sys_le16_to_cpu(cmd->end_handle); - rc = ble_gattc_disc_all_chrs(conn.conn_handle, start_handle, end_handle, - disc_chrc_cb, (void *)GATT_DISC_ALL_CHRC); - if (rc) { - discover_destroy(); - goto fail; - } + rc = ble_gattc_disc_all_chrs(conn.conn_handle, start_handle, end_handle, + disc_chrc_cb, (void *) GATT_DISC_ALL_CHRC); + if (rc) { + discover_destroy(); + goto fail; + } - return; + return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_CHRC, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_CHRC, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static void find_included(uint8_t *data, uint16_t len) +static void +find_included(uint8_t *data, uint16_t len) { - const struct gatt_find_included_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint16_t start_handle, end_handle; - int service_handle_arg; - int rc; + const struct gatt_find_included_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint16_t start_handle, end_handle; + int service_handle_arg; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - goto fail; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + goto fail; + } - if (!gatt_buf_reserve(sizeof(struct gatt_find_included_rp))) { - goto fail; - } + if (!gatt_buf_reserve(sizeof(struct gatt_find_included_rp))) { + goto fail; + } - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); - service_handle_arg = start_handle; + start_handle = sys_le16_to_cpu(cmd->start_handle); + end_handle = sys_le16_to_cpu(cmd->end_handle); + service_handle_arg = start_handle; - if (ble_gattc_find_inc_svcs(conn.conn_handle, start_handle, end_handle, - find_included_cb, - (void *)service_handle_arg)) { - discover_destroy(); - goto fail; - } + if (ble_gattc_find_inc_svcs(conn.conn_handle, start_handle, end_handle, + find_included_cb, + (void *) service_handle_arg)) { + discover_destroy(); + goto fail; + } - return; + return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_FIND_INCLUDED, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_FIND_INCLUDED, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static int exchange_func(uint16_t conn_handle, - const struct ble_gatt_error *error, - uint16_t mtu, void *arg) +static int +exchange_func(uint16_t conn_handle, + const struct ble_gatt_error *error, + uint16_t mtu, void *arg) { - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - if (error->status) { - tester_rsp(BTP_SERVICE_ID_GATT, GATT_EXCHANGE_MTU, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + if (error->status) { + tester_rsp(BTP_SERVICE_ID_GATT, GATT_EXCHANGE_MTU, + CONTROLLER_INDEX, BTP_STATUS_FAILED); - return 0; -} + return 0; + } - tester_rsp(BTP_SERVICE_ID_GATT, GATT_EXCHANGE_MTU, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_EXCHANGE_MTU, CONTROLLER_INDEX, + BTP_STATUS_SUCCESS); - return 0; + return 0; } -static void exchange_mtu(uint8_t *data, uint16_t len) +static void +exchange_mtu(uint8_t *data, uint16_t len) { - struct ble_gap_conn_desc conn; - int rc; + struct ble_gap_conn_desc conn; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - goto fail; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + goto fail; + } - if (ble_gattc_exchange_mtu(conn.conn_handle, exchange_func, NULL)) { - goto fail; - } + if (ble_gattc_exchange_mtu(conn.conn_handle, exchange_func, NULL)) { + goto fail; + } - return; + return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_EXCHANGE_MTU, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_EXCHANGE_MTU, + CONTROLLER_INDEX, BTP_STATUS_FAILED); } -static int enable_subscription(uint16_t conn_handle, uint16_t ccc_handle, - uint16_t value) +static int +enable_subscription(uint16_t conn_handle, uint16_t ccc_handle, + uint16_t value) { - uint8_t op; + uint8_t op; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - op = (uint8_t) (value == 0x0001 ? GATT_CFG_NOTIFY : GATT_CFG_INDICATE); + op = (uint8_t) (value == 0x0001 ? GATT_CFG_NOTIFY : GATT_CFG_INDICATE); - if (ble_gattc_write_flat(conn_handle, ccc_handle, - &value, sizeof(value), NULL, NULL)) { - return -EINVAL; - } + if (ble_gattc_write_flat(conn_handle, ccc_handle, + &value, sizeof(value), NULL, NULL)) { + return -EINVAL; + } - subscribe_params.ccc_handle = value; + subscribe_params.ccc_handle = value; - tester_rsp(BTP_SERVICE_ID_GATT, op, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); - return 0; + tester_rsp(BTP_SERVICE_ID_GATT, op, CONTROLLER_INDEX, + BTP_STATUS_SUCCESS); + return 0; } -static int disable_subscription(uint16_t conn_handle, uint16_t ccc_handle) +static int +disable_subscription(uint16_t conn_handle, uint16_t ccc_handle) { - uint16_t value = 0x00; + uint16_t value = 0x00; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - /* Fail if CCC handle doesn't match */ - if (ccc_handle != subscribe_params.ccc_handle) { - SYS_LOG_ERR("CCC handle doesn't match"); - return -EINVAL; - } + /* Fail if CCC handle doesn't match */ + if (ccc_handle != subscribe_params.ccc_handle) { + SYS_LOG_ERR("CCC handle doesn't match"); + return -EINVAL; + } - if (ble_gattc_write_no_rsp_flat(conn_handle, ccc_handle, - &value, sizeof(value))) { - return -EINVAL; - } + if (ble_gattc_write_no_rsp_flat(conn_handle, ccc_handle, + &value, sizeof(value))) { + return -EINVAL; + } - subscribe_params.ccc_handle = 0; - return 0; + subscribe_params.ccc_handle = 0; + return 0; } -static void config_subscription(uint8_t *data, uint16_t len, uint8_t op) +static void +config_subscription(uint8_t *data, uint16_t len, uint8_t op) { - const struct gatt_cfg_notify_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle); - uint8_t status; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); - if (rc) { - tester_rsp(BTP_SERVICE_ID_GATT, op, CONTROLLER_INDEX, - BTP_STATUS_FAILED); - return; - } - - if (cmd->enable) { - uint16_t value; - - if (op == GATT_CFG_NOTIFY) { - value = 0x0001; - } else { - value = 0x0002; - } - - /* on success response will be sent from callback */ - if (enable_subscription(conn.conn_handle, - ccc_handle, value) == 0) { - return; - } - - status = BTP_STATUS_FAILED; - } else { - if (disable_subscription(conn.conn_handle, ccc_handle) < 0) { - status = BTP_STATUS_FAILED; - } else { - status = BTP_STATUS_SUCCESS; - } - } - - SYS_LOG_DBG("Config subscription (op %u) status %u", op, status); - - tester_rsp(BTP_SERVICE_ID_GATT, op, CONTROLLER_INDEX, status); + const struct gatt_cfg_notify_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle); + uint8_t status; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + tester_rsp(BTP_SERVICE_ID_GATT, op, CONTROLLER_INDEX, + BTP_STATUS_FAILED); + return; + } + + if (cmd->enable) { + uint16_t value; + + if (op == GATT_CFG_NOTIFY) { + value = 0x0001; + } else { + value = 0x0002; + } + + /* on success response will be sent from callback */ + if (enable_subscription(conn.conn_handle, + ccc_handle, value) == 0) { + return; + } + + status = BTP_STATUS_FAILED; + } else { + if (disable_subscription(conn.conn_handle, ccc_handle) < 0) { + status = BTP_STATUS_FAILED; + } else { + status = BTP_STATUS_SUCCESS; + } + } + + SYS_LOG_DBG("Config subscription (op %u) status %u", op, status); + + tester_rsp(BTP_SERVICE_ID_GATT, op, CONTROLLER_INDEX, status); } #define BTP_PERM_F_READ 0x01 @@ -1615,484 +1648,513 @@ static void config_subscription(uint8_t *data, uint16_t len, uint8_t op) #define BTP_PERM_F_WRITE_AUTHOR 0x80 static int flags_hs2btp_map[] = { - BTP_PERM_F_READ, - BTP_PERM_F_WRITE, - BTP_PERM_F_READ_ENC, - BTP_PERM_F_READ_AUTHEN, - BTP_PERM_F_READ_AUTHOR, - BTP_PERM_F_WRITE_ENC, - BTP_PERM_F_WRITE_AUTHEN, - BTP_PERM_F_WRITE_AUTHOR, + BTP_PERM_F_READ, + BTP_PERM_F_WRITE, + BTP_PERM_F_READ_ENC, + BTP_PERM_F_READ_AUTHEN, + BTP_PERM_F_READ_AUTHOR, + BTP_PERM_F_WRITE_ENC, + BTP_PERM_F_WRITE_AUTHEN, + BTP_PERM_F_WRITE_AUTHOR, }; -static uint8_t flags_hs2btp(uint8_t flags) +static uint8_t +flags_hs2btp(uint8_t flags) { - int i; - uint8_t ret = 0; + int i; + uint8_t ret = 0; - for (i = 0; i < 8; ++i) { - if (flags & BIT(i)) { - ret |= flags_hs2btp_map[i]; - } - } + for (i = 0; i < 8; ++i) { + if (flags & BIT(i)) { + ret |= flags_hs2btp_map[i]; + } + } - return ret; + return ret; } -static void get_attrs(uint8_t *data, uint16_t len) +static void +get_attrs(uint8_t *data, uint16_t len) { - const struct gatt_get_attributes_cmd *cmd = (void *) data; - struct gatt_get_attributes_rp *rp; - struct gatt_attr *gatt_attr; - struct os_mbuf *buf = os_msys_get(0, 0); - uint16_t start_handle, end_handle; - struct ble_att_svr_entry *entry = NULL; - ble_uuid_any_t uuid; - ble_uuid_t *uuid_ptr = NULL; - uint8_t count = 0; - char str[BLE_UUID_STR_LEN]; - - SYS_LOG_DBG(""); - - memset(str, 0, sizeof(str)); - memset(&uuid, 0, sizeof(uuid)); - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); - - if (cmd->type_length) { - if (btp2bt_uuid(cmd->type, cmd->type_length, &uuid)) { - goto fail; - } - - ble_uuid_to_str(&uuid.u, str); - SYS_LOG_DBG("start 0x%04x end 0x%04x, uuid %s", start_handle, - end_handle, str); - - uuid_ptr = &uuid.u; - } else { - SYS_LOG_DBG("start 0x%04x end 0x%04x", start_handle, end_handle); - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - entry = ble_att_svr_find_by_uuid(entry, uuid_ptr, end_handle); - while (entry) { - - if (entry->ha_handle_id < start_handle) { - entry = ble_att_svr_find_by_uuid(entry, - uuid_ptr, end_handle); - continue; - } - - gatt_attr = net_buf_simple_add(buf, sizeof(*gatt_attr)); - gatt_attr->handle = sys_cpu_to_le16(entry->ha_handle_id); - gatt_attr->permission = flags_hs2btp(entry->ha_flags); - - if (entry->ha_uuid->type == BLE_UUID_TYPE_16) { - gatt_attr->type_length = 2; - net_buf_simple_add_le16(buf, - BLE_UUID16(entry->ha_uuid)->value); - } else { - gatt_attr->type_length = 16; - net_buf_simple_add_mem(buf, - BLE_UUID128(entry->ha_uuid)->value, - gatt_attr->type_length); - } - - count++; - - entry = ble_att_svr_find_by_uuid(entry, uuid_ptr, end_handle); - } - - rp->attrs_count = count; - - tester_send_buf(BTP_SERVICE_ID_GATT, GATT_GET_ATTRIBUTES, - CONTROLLER_INDEX, buf); - - goto free; + const struct gatt_get_attributes_cmd *cmd = (void *) data; + struct gatt_get_attributes_rp *rp; + struct gatt_attr *gatt_attr; + struct os_mbuf *buf = os_msys_get(0, 0); + uint16_t start_handle, end_handle; + struct ble_att_svr_entry *entry = NULL; + ble_uuid_any_t uuid; + ble_uuid_t *uuid_ptr = NULL; + uint8_t count = 0; + char str[BLE_UUID_STR_LEN]; + + SYS_LOG_DBG(""); + + memset(str, 0, sizeof(str)); + memset(&uuid, 0, sizeof(uuid)); + start_handle = sys_le16_to_cpu(cmd->start_handle); + end_handle = sys_le16_to_cpu(cmd->end_handle); + + if (cmd->type_length) { + if (btp2bt_uuid(cmd->type, cmd->type_length, &uuid)) { + goto fail; + } + + ble_uuid_to_str(&uuid.u, str); + SYS_LOG_DBG("start 0x%04x end 0x%04x, uuid %s", start_handle, + end_handle, str); + + uuid_ptr = &uuid.u; + } else { + SYS_LOG_DBG("start 0x%04x end 0x%04x", start_handle, end_handle); + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + entry = ble_att_svr_find_by_uuid(entry, uuid_ptr, end_handle); + while (entry) { + + if (entry->ha_handle_id < start_handle) { + entry = ble_att_svr_find_by_uuid(entry, + uuid_ptr, end_handle); + continue; + } + + gatt_attr = net_buf_simple_add(buf, sizeof(*gatt_attr)); + gatt_attr->handle = sys_cpu_to_le16(entry->ha_handle_id); + gatt_attr->permission = flags_hs2btp(entry->ha_flags); + + if (entry->ha_uuid->type == BLE_UUID_TYPE_16) { + gatt_attr->type_length = 2; + net_buf_simple_add_le16(buf, + BLE_UUID16(entry->ha_uuid)->value); + } else { + gatt_attr->type_length = 16; + net_buf_simple_add_mem(buf, + BLE_UUID128(entry->ha_uuid)->value, + gatt_attr->type_length); + } + + count++; + + entry = ble_att_svr_find_by_uuid(entry, uuid_ptr, end_handle); + } + + rp->attrs_count = count; + + tester_send_buf(BTP_SERVICE_ID_GATT, GATT_GET_ATTRIBUTES, + CONTROLLER_INDEX, buf); + + goto free; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_GET_ATTRIBUTES, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_GET_ATTRIBUTES, CONTROLLER_INDEX, + BTP_STATUS_FAILED); free: - os_mbuf_free_chain(buf); + os_mbuf_free_chain(buf); } -static void get_attr_val(uint8_t *data, uint16_t len) +static void +get_attr_val(uint8_t *data, uint16_t len) { - const struct gatt_get_attribute_value_cmd *cmd = (void *) data; - struct gatt_get_attribute_value_rp *rp; - struct ble_gap_conn_desc conn; - struct os_mbuf *buf = os_msys_get(0, 0); - uint16_t handle = sys_cpu_to_le16(cmd->handle); - uint8_t out_att_err; - int conn_status; + const struct gatt_get_attribute_value_cmd *cmd = (void *) data; + struct gatt_get_attribute_value_rp *rp; + struct ble_gap_conn_desc conn; + struct os_mbuf *buf = os_msys_get(0, 0); + uint16_t handle = sys_cpu_to_le16(cmd->handle); + uint8_t out_att_err; + int conn_status; - conn_status = ble_gap_conn_find_by_addr((ble_addr_t *)data, &conn); + conn_status = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (conn_status) { - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + if (conn_status) { + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); - ble_att_svr_read_handle(BLE_HS_CONN_HANDLE_NONE, - handle, 0, buf, - &out_att_err); + ble_att_svr_read_handle(BLE_HS_CONN_HANDLE_NONE, + handle, 0, buf, + &out_att_err); - rp->att_response = out_att_err; - rp->value_length = os_mbuf_len(buf) - sizeof(*rp); + rp->att_response = out_att_err; + rp->value_length = os_mbuf_len(buf) - sizeof(*rp); - tester_send_buf(BTP_SERVICE_ID_GATT, GATT_GET_ATTRIBUTE_VALUE, - CONTROLLER_INDEX, buf); + tester_send_buf(BTP_SERVICE_ID_GATT, GATT_GET_ATTRIBUTE_VALUE, + CONTROLLER_INDEX, buf); - goto free; - } else { - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + goto free; + } else { + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); - ble_att_svr_read_handle(conn.conn_handle, - handle, 0, buf, - &out_att_err); + ble_att_svr_read_handle(conn.conn_handle, + handle, 0, buf, + &out_att_err); - rp->att_response = out_att_err; - rp->value_length = os_mbuf_len(buf) - sizeof(*rp); + rp->att_response = out_att_err; + rp->value_length = os_mbuf_len(buf) - sizeof(*rp); - tester_send_buf(BTP_SERVICE_ID_GATT, GATT_GET_ATTRIBUTE_VALUE, - CONTROLLER_INDEX, buf); + tester_send_buf(BTP_SERVICE_ID_GATT, GATT_GET_ATTRIBUTE_VALUE, + CONTROLLER_INDEX, buf); - goto free; - } + goto free; + } free: - os_mbuf_free_chain(buf); + os_mbuf_free_chain(buf); } -static void change_database(uint8_t *data, uint16_t len) +static void +change_database(uint8_t *data, uint16_t len) { - const struct gatt_change_database *cmd = (void *) data; + const struct gatt_change_database *cmd = (void *) data; - SYS_LOG_DBG("") + SYS_LOG_DBG("") - ble_gatts_show_local(); + ble_gatts_show_local(); - ble_svc_gatt_changed(cmd->start_handle, cmd->end_handle); + ble_svc_gatt_changed(cmd->start_handle, cmd->end_handle); - tester_rsp(BTP_SERVICE_ID_GATT, GATT_CHANGE_DATABASE, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_GATT, GATT_CHANGE_DATABASE, CONTROLLER_INDEX, + BTP_STATUS_SUCCESS); - return; + return; } -static void supported_commands(uint8_t *data, uint16_t len) +static void +supported_commands(uint8_t *data, uint16_t len) { - uint8_t cmds[4]; - struct gatt_read_supported_commands_rp *rp = (void *) cmds; - - SYS_LOG_DBG(""); - - memset(cmds, 0, sizeof(cmds)); - - tester_set_bit(cmds, GATT_READ_SUPPORTED_COMMANDS); - tester_set_bit(cmds, GATT_START_SERVER); - tester_set_bit(cmds, GATT_EXCHANGE_MTU); - tester_set_bit(cmds, GATT_DISC_ALL_PRIM_SVCS); - tester_set_bit(cmds, GATT_DISC_PRIM_UUID); - tester_set_bit(cmds, GATT_FIND_INCLUDED); - tester_set_bit(cmds, GATT_DISC_ALL_CHRC); - tester_set_bit(cmds, GATT_DISC_CHRC_UUID); - tester_set_bit(cmds, GATT_DISC_ALL_DESC); - tester_set_bit(cmds, GATT_READ); - tester_set_bit(cmds, GATT_READ_LONG); - tester_set_bit(cmds, GATT_READ_MULTIPLE); - tester_set_bit(cmds, GATT_WRITE_WITHOUT_RSP); + uint8_t cmds[4]; + struct gatt_read_supported_commands_rp *rp = (void *) cmds; + + SYS_LOG_DBG(""); + + memset(cmds, 0, sizeof(cmds)); + + tester_set_bit(cmds, GATT_READ_SUPPORTED_COMMANDS); + tester_set_bit(cmds, GATT_START_SERVER); + tester_set_bit(cmds, GATT_EXCHANGE_MTU); + tester_set_bit(cmds, GATT_DISC_ALL_PRIM_SVCS); + tester_set_bit(cmds, GATT_DISC_PRIM_UUID); + tester_set_bit(cmds, GATT_FIND_INCLUDED); + tester_set_bit(cmds, GATT_DISC_ALL_CHRC); + tester_set_bit(cmds, GATT_DISC_CHRC_UUID); + tester_set_bit(cmds, GATT_DISC_ALL_DESC); + tester_set_bit(cmds, GATT_READ); + tester_set_bit(cmds, GATT_READ_LONG); + tester_set_bit(cmds, GATT_READ_MULTIPLE); + tester_set_bit(cmds, GATT_WRITE_WITHOUT_RSP); #if 0 - tester_set_bit(cmds, GATT_SIGNED_WRITE_WITHOUT_RSP); + tester_set_bit(cmds, GATT_SIGNED_WRITE_WITHOUT_RSP); #endif - tester_set_bit(cmds, GATT_WRITE); - tester_set_bit(cmds, GATT_WRITE_LONG); - tester_set_bit(cmds, GATT_CFG_NOTIFY); - tester_set_bit(cmds, GATT_CFG_INDICATE); - tester_set_bit(cmds, GATT_GET_ATTRIBUTES); - tester_set_bit(cmds, GATT_GET_ATTRIBUTE_VALUE); - tester_set_bit(cmds, GATT_CHANGE_DATABASE); - - tester_send(BTP_SERVICE_ID_GATT, GATT_READ_SUPPORTED_COMMANDS, - CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); + tester_set_bit(cmds, GATT_WRITE); + tester_set_bit(cmds, GATT_WRITE_LONG); + tester_set_bit(cmds, GATT_CFG_NOTIFY); + tester_set_bit(cmds, GATT_CFG_INDICATE); + tester_set_bit(cmds, GATT_GET_ATTRIBUTES); + tester_set_bit(cmds, GATT_GET_ATTRIBUTE_VALUE); + tester_set_bit(cmds, GATT_CHANGE_DATABASE); + + tester_send(BTP_SERVICE_ID_GATT, GATT_READ_SUPPORTED_COMMANDS, + CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); } enum attr_type { - BLE_GATT_ATTR_SVC = 0, - BLE_GATT_ATTR_CHR, - BLE_GATT_ATTR_DSC, + BLE_GATT_ATTR_SVC = 0, + BLE_GATT_ATTR_CHR, + BLE_GATT_ATTR_DSC, }; -void tester_handle_gatt(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len) +void +tester_handle_gatt(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len) { - switch (opcode) { - case GATT_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - return; - case GATT_START_SERVER: - start_server(data, len); - return; - case GATT_EXCHANGE_MTU: - exchange_mtu(data, len); - return; - case GATT_DISC_ALL_PRIM_SVCS: - disc_all_prim_svcs(data, len); - return; - case GATT_DISC_PRIM_UUID: - disc_prim_uuid(data, len); - return; - case GATT_FIND_INCLUDED: - find_included(data, len); - return; - case GATT_DISC_ALL_CHRC: - disc_all_chrc(data, len); - return; - case GATT_DISC_CHRC_UUID: - disc_chrc_uuid(data, len); - return; - case GATT_DISC_ALL_DESC: - disc_all_desc(data, len); - return; - case GATT_CHANGE_DATABASE: - change_database(data, len); - return; - case GATT_READ: - read(data, len); - return; - case GATT_READ_UUID: - read_uuid(data, len); - return; - case GATT_READ_LONG: - read_long(data, len); - return; - case GATT_READ_MULTIPLE: - read_multiple(data, len); - return; - case GATT_WRITE_WITHOUT_RSP: - write_without_rsp(data, len, opcode, false); - return; + switch (opcode) { + case GATT_READ_SUPPORTED_COMMANDS: + supported_commands(data, len); + return; + case GATT_START_SERVER: + start_server(data, len); + return; + case GATT_EXCHANGE_MTU: + exchange_mtu(data, len); + return; + case GATT_DISC_ALL_PRIM_SVCS: + disc_all_prim_svcs(data, len); + return; + case GATT_DISC_PRIM_UUID: + disc_prim_uuid(data, len); + return; + case GATT_FIND_INCLUDED: + find_included(data, len); + return; + case GATT_DISC_ALL_CHRC: + disc_all_chrc(data, len); + return; + case GATT_DISC_CHRC_UUID: + disc_chrc_uuid(data, len); + return; + case GATT_DISC_ALL_DESC: + disc_all_desc(data, len); + return; + case GATT_CHANGE_DATABASE: + change_database(data, len); + return; + case GATT_READ: + read(data, len); + return; + case GATT_READ_UUID: + read_uuid(data, len); + return; + case GATT_READ_LONG: + read_long(data, len); + return; + case GATT_READ_MULTIPLE: + read_multiple(data, len); + return; + case GATT_WRITE_WITHOUT_RSP: + write_without_rsp(data, + len, + opcode, + false); + return; #if 0 - case GATT_SIGNED_WRITE_WITHOUT_RSP: - write_without_rsp(data, len, opcode, true); - return; + case GATT_SIGNED_WRITE_WITHOUT_RSP: + write_without_rsp(data, len, opcode, true); + return; #endif - case GATT_WRITE: - write(data, len); - return; - case GATT_WRITE_LONG: - write_long(data, len); - return; - case GATT_RELIABLE_WRITE: - reliable_write(data, len); - return; - case GATT_CFG_NOTIFY: - case GATT_CFG_INDICATE: - config_subscription(data, len, opcode); - return; - case GATT_GET_ATTRIBUTES: - get_attrs(data, len); - return; - case GATT_GET_ATTRIBUTE_VALUE: - get_attr_val(data, len); - return; - default: - tester_rsp(BTP_SERVICE_ID_GATT, opcode, index, - BTP_STATUS_UNKNOWN_CMD); - return; - } + case GATT_WRITE: + write(data, len); + return; + case GATT_WRITE_LONG: + write_long(data, len); + return; + case GATT_RELIABLE_WRITE: + reliable_write(data, len); + return; + case GATT_CFG_NOTIFY: + case GATT_CFG_INDICATE: + config_subscription(data, len, opcode); + return; + case GATT_GET_ATTRIBUTES: + get_attrs(data, len); + return; + case GATT_GET_ATTRIBUTE_VALUE: + get_attr_val(data, len); + return; + default: + tester_rsp(BTP_SERVICE_ID_GATT, opcode, index, + BTP_STATUS_UNKNOWN_CMD); + return; + } } -int tester_gatt_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, - uint8_t indication, struct os_mbuf *om) +int +tester_gatt_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, + uint8_t indication, struct os_mbuf *om) { - struct gatt_notification_ev *ev; - struct ble_gap_conn_desc conn; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; + struct gatt_notification_ev *ev; + struct ble_gap_conn_desc conn; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - if (!subscribe_params.ccc_handle) { - goto fail; - } + if (!subscribe_params.ccc_handle) { + goto fail; + } - if (ble_gap_conn_find(conn_handle, &conn)) { - goto fail; - } + if (ble_gap_conn_find(conn_handle, &conn)) { + goto fail; + } - net_buf_simple_init(buf, 0); - ev = net_buf_simple_add(buf, sizeof(*ev)); + net_buf_simple_init(buf, 0); + ev = net_buf_simple_add(buf, sizeof(*ev)); - addr = &conn.peer_ota_addr; + addr = &conn.peer_ota_addr; - ev->address_type = addr->type; - memcpy(ev->address, addr->val, sizeof(ev->address)); - ev->type = (uint8_t) (indication ? 0x02 : 0x01); - ev->handle = sys_cpu_to_le16(attr_handle); - ev->data_length = sys_cpu_to_le16(os_mbuf_len(om)); - os_mbuf_appendfrom(buf, om, 0, os_mbuf_len(om)); + ev->address_type = addr->type; + memcpy(ev->address, addr->val, sizeof(ev->address)); + ev->type = (uint8_t) (indication ? 0x02 : 0x01); + ev->handle = sys_cpu_to_le16(attr_handle); + ev->data_length = sys_cpu_to_le16(os_mbuf_len(om)); + os_mbuf_appendfrom(buf, om, 0, os_mbuf_len(om)); - tester_send_buf(BTP_SERVICE_ID_GATT, GATT_EV_NOTIFICATION, - CONTROLLER_INDEX, buf); + tester_send_buf(BTP_SERVICE_ID_GATT, GATT_EV_NOTIFICATION, + CONTROLLER_INDEX, buf); fail: - os_mbuf_free_chain(buf); - return 0; + os_mbuf_free_chain(buf); + return 0; } -void notify_test_stop(void) +void +notify_test_stop(void) { - os_callout_stop(¬ify_tx_timer); + os_callout_stop(¬ify_tx_timer); } -void notify_test_reset(void) +void +notify_test_reset(void) { - int rc; + int rc; - rc = os_callout_reset(¬ify_tx_timer, OS_TICKS_PER_SEC); - assert(rc == 0); + rc = os_callout_reset(¬ify_tx_timer, OS_TICKS_PER_SEC); + assert(rc == 0); } -void notify_test(struct os_event *ev) +void +notify_test(struct os_event *ev) { - static uint8_t ntf[1]; - struct os_mbuf *om; - int rc; - - if (!notify_state && !indicate_state) { - notify_test_stop(); - notify_value = 90; - return; - } - - ntf[0] = notify_value; - - notify_value++; - if (notify_value == 160) { - notify_value = 90; - } - - om = ble_hs_mbuf_from_flat(ntf, sizeof(ntf)); - - if (notify_state) { - rc = ble_gatts_notify_custom(myconn_handle, notify_handle, om); - assert(rc == 0); - } - - if (indicate_state) { - rc = ble_gatts_indicate_custom(myconn_handle, notify_handle, om); - assert(rc == 0); - } + static uint8_t ntf[1]; + struct os_mbuf *om; + int rc; + + if (!notify_state && !indicate_state) { + notify_test_stop(); + notify_value = 90; + return; + } + + ntf[0] = notify_value; + + notify_value++; + if (notify_value == 160) { + notify_value = 90; + } + + om = ble_hs_mbuf_from_flat(ntf, sizeof(ntf)); + + if (notify_state) { + rc = ble_gatts_notify_custom(myconn_handle, notify_handle, om); + assert(rc == 0); + } + + if (indicate_state) { + rc = ble_gatts_indicate_custom(myconn_handle, notify_handle, om); + assert(rc == 0); + } } -int tester_gatt_subscribe_ev(uint16_t conn_handle, uint16_t attr_handle, uint8_t reason, - uint8_t prev_notify, uint8_t cur_notify, - uint8_t prev_indicate, uint8_t cur_indicate) +int +tester_gatt_subscribe_ev(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t reason, + uint8_t prev_notify, + uint8_t cur_notify, + uint8_t prev_indicate, + uint8_t cur_indicate) { - SYS_LOG_DBG(""); - myconn_handle = conn_handle; - - if (cur_notify == 0 && cur_indicate == 0) { - SYS_LOG_INF("Unsubscribed"); - memset(&subscribe_params, 0, sizeof(subscribe_params)); - return 0; - } - - if (cur_notify) { - SYS_LOG_INF("Subscribed to notifications"); - if (attr_handle == notify_handle) { - notify_state = cur_notify; - } - } - - if (cur_indicate) { - SYS_LOG_INF("Subscribed to indications"); - if (attr_handle == notify_handle) { - indicate_state = cur_indicate; - } - } - - - if (notify_state || indicate_state) { - notify_test_reset(); - } else { - notify_test_stop(); - } - - return 0; + SYS_LOG_DBG(""); + myconn_handle = conn_handle; + + if (cur_notify == 0 && cur_indicate == 0) { + SYS_LOG_INF("Unsubscribed"); + memset(&subscribe_params, 0, sizeof(subscribe_params)); + return 0; + } + + if (cur_notify) { + SYS_LOG_INF("Subscribed to notifications"); + if (attr_handle == notify_handle) { + notify_state = cur_notify; + } + } + + if (cur_indicate) { + SYS_LOG_INF("Subscribed to indications"); + if (attr_handle == notify_handle) { + indicate_state = cur_indicate; + } + } + + if (notify_state || indicate_state) { + notify_test_reset(); + } else { + notify_test_stop(); + } + + return 0; } void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) { - char buf[BLE_UUID_STR_LEN]; - - switch (ctxt->op) { - case BLE_GATT_REGISTER_OP_SVC: - MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n", - ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), - ctxt->svc.handle); - break; - - case BLE_GATT_REGISTER_OP_CHR: - MODLOG_DFLT(DEBUG, "registering characteristic %s with " - "def_handle=%d val_handle=%d\n", - ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf), - ctxt->chr.def_handle, - ctxt->chr.val_handle); - break; - - case BLE_GATT_REGISTER_OP_DSC: - MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n", - ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf), - ctxt->dsc.handle); - break; - - default: - assert(0); - break; - } + char buf[BLE_UUID_STR_LEN]; + + switch (ctxt->op) { + case BLE_GATT_REGISTER_OP_SVC: + MODLOG_DFLT(DEBUG, + "registered service %s with handle=%d\n", + ble_uuid_to_str( + ctxt->svc.svc_def->uuid, + buf), + ctxt->svc.handle); + break; + + case BLE_GATT_REGISTER_OP_CHR: + MODLOG_DFLT(DEBUG, + "registering characteristic %s with " + "def_handle=%d val_handle=%d\n", + ble_uuid_to_str( + ctxt->chr.chr_def->uuid, + buf), + ctxt->chr.def_handle, + ctxt->chr.val_handle); + break; + + case BLE_GATT_REGISTER_OP_DSC: + MODLOG_DFLT(DEBUG, + "registering descriptor %s with handle=%d\n", + ble_uuid_to_str( + ctxt->dsc.dsc_def->uuid, + buf), + ctxt->dsc.handle); + break; + + default: + assert(0); + break; + } } -int gatt_svr_init(void) +int +gatt_svr_init(void) { - int rc; + int rc; - rc = ble_gatts_count_cfg(gatt_svr_inc_svcs); - if (rc != 0) { - return rc; - } + rc = ble_gatts_count_cfg(gatt_svr_inc_svcs); + if (rc != 0) { + return rc; + } - rc = ble_gatts_add_svcs(gatt_svr_inc_svcs); - if (rc != 0) { - return rc; - } + rc = ble_gatts_add_svcs(gatt_svr_inc_svcs); + if (rc != 0) { + return rc; + } - rc = ble_gatts_count_cfg(gatt_svr_svcs); - if (rc != 0) { - return rc; - } + rc = ble_gatts_count_cfg(gatt_svr_svcs); + if (rc != 0) { + return rc; + } - rc = ble_gatts_add_svcs(gatt_svr_svcs); - if (rc != 0) { - return rc; - } + rc = ble_gatts_add_svcs(gatt_svr_svcs); + if (rc != 0) { + return rc; + } - return 0; + return 0; } -uint8_t tester_init_gatt(void) +uint8_t +tester_init_gatt(void) { - os_callout_init(¬ify_tx_timer, os_eventq_dflt_get(), - notify_test, NULL); + os_callout_init(¬ify_tx_timer, os_eventq_dflt_get(), + notify_test, NULL); - return BTP_STATUS_SUCCESS; + return BTP_STATUS_SUCCESS; } -uint8_t tester_unregister_gatt(void) +uint8_t +tester_unregister_gatt(void) { - return BTP_STATUS_SUCCESS; + return BTP_STATUS_SUCCESS; } diff --git a/apps/bttester/src/gatt_cl.c b/apps/bttester/src/gatt_cl.c index c551bb1735..3ca5ecfc04 100644 --- a/apps/bttester/src/gatt_cl.c +++ b/apps/bttester/src/gatt_cl.c @@ -34,25 +34,26 @@ #define MAX_BUFFER_SIZE 2048 /* Convert UUID from BTP command to bt_uuid */ -static uint8_t btp2bt_uuid(const uint8_t *uuid, uint8_t len, - ble_uuid_any_t *bt_uuid) +static uint8_t +btp2bt_uuid(const uint8_t *uuid, uint8_t len, + ble_uuid_any_t *bt_uuid) { - uint16_t le16; - - switch (len) { - case 0x02: /* UUID 16 */ - bt_uuid->u.type = BLE_UUID_TYPE_16; - memcpy(&le16, uuid, sizeof(le16)); - BLE_UUID16(bt_uuid)->value = sys_le16_to_cpu(le16); - break; - case 0x10: /* UUID 128*/ - bt_uuid->u.type = BLE_UUID_TYPE_128; - memcpy(BLE_UUID128(bt_uuid)->value, uuid, 16); - break; - default: - return BTP_STATUS_FAILED; - } - return BTP_STATUS_SUCCESS; + uint16_t le16; + + switch (len) { + case 0x02: /* UUID 16 */ + bt_uuid->u.type = BLE_UUID_TYPE_16; + memcpy(&le16, uuid, sizeof(le16)); + BLE_UUID16(bt_uuid)->value = sys_le16_to_cpu(le16); + break; + case 0x10: /* UUID 128*/ + bt_uuid->u.type = BLE_UUID_TYPE_128; + memcpy(BLE_UUID128(bt_uuid)->value, uuid, 16); + break; + default: + return BTP_STATUS_FAILED; + } + return BTP_STATUS_SUCCESS; } /* @@ -61,1423 +62,1484 @@ static uint8_t btp2bt_uuid(const uint8_t *uuid, uint8_t len, * It is not intended to be used by client and server at the same time. */ static struct { - uint16_t len; - uint8_t buf[MAX_BUFFER_SIZE]; - uint16_t cnt; + uint16_t len; + uint8_t buf[MAX_BUFFER_SIZE]; + uint16_t cnt; } gatt_buf; static struct bt_gatt_subscribe_params { - uint16_t ccc_handle; - uint16_t value; - uint16_t value_handle; + uint16_t ccc_handle; + uint16_t value; + uint16_t value_handle; } subscribe_params; -static void *gatt_buf_add(const void *data, size_t len) +static void * +gatt_buf_add(const void *data, size_t len) { - void *ptr = gatt_buf.buf + gatt_buf.len; + void *ptr = gatt_buf.buf + gatt_buf.len; - if ((len + gatt_buf.len) > MAX_BUFFER_SIZE) { - return NULL; - } + if ((len + gatt_buf.len) > MAX_BUFFER_SIZE) { + return NULL; + } - if (data) { - memcpy(ptr, data, len); - } else { - (void) memset(ptr, 0, len); - } + if (data) { + memcpy(ptr, data, len); + } else { + (void) memset(ptr, 0, len); + } - gatt_buf.len += len; + gatt_buf.len += len; - SYS_LOG_DBG("%d/%d used", gatt_buf.len, MAX_BUFFER_SIZE); + SYS_LOG_DBG("%d/%d used", gatt_buf.len, MAX_BUFFER_SIZE); - return ptr; + return ptr; } -static void *gatt_buf_reserve(size_t len) +static void * +gatt_buf_reserve(size_t len) { - return gatt_buf_add(NULL, len); + return gatt_buf_add(NULL, len); } -static void gatt_buf_clear(void) +static void +gatt_buf_clear(void) { - (void) memset(&gatt_buf, 0, sizeof(gatt_buf)); + (void) memset(&gatt_buf, 0, sizeof(gatt_buf)); } -static void discover_destroy(void) +static void +discover_destroy(void) { - gatt_buf_clear(); + gatt_buf_clear(); } -static void read_destroy() +static void +read_destroy() { - gatt_buf_clear(); + gatt_buf_clear(); } -static int tester_mtu_exchanged_ev(uint16_t conn_handle, - const struct ble_gatt_error *error, - uint16_t mtu, void *arg) +static int +tester_mtu_exchanged_ev(uint16_t conn_handle, + const struct ble_gatt_error *error, + uint16_t mtu, void *arg) { - struct gattc_exchange_mtu_ev *ev; - struct ble_gap_conn_desc conn; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; + struct gattc_exchange_mtu_ev *ev; + struct ble_gap_conn_desc conn; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - if (ble_gap_conn_find(conn_handle, &conn)) { - goto fail; - } + if (ble_gap_conn_find(conn_handle, &conn)) { + goto fail; + } - net_buf_simple_init(buf, 0); - ev = net_buf_simple_add(buf, sizeof(*ev)); + net_buf_simple_init(buf, 0); + ev = net_buf_simple_add(buf, sizeof(*ev)); - addr = &conn.peer_ota_addr; + addr = &conn.peer_ota_addr; - ev->address_type = addr->type; - memcpy(ev->address, addr->val, sizeof(ev->address)); + ev->address_type = addr->type; + memcpy(ev->address, addr->val, sizeof(ev->address)); - ev->mtu = mtu; + ev->mtu = mtu; - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_EV_MTU_EXCHANGED, - CONTROLLER_INDEX, buf); + tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_EV_MTU_EXCHANGED, + CONTROLLER_INDEX, buf); fail: - os_mbuf_free_chain(buf); - return 0; + os_mbuf_free_chain(buf); + return 0; } -static void exchange_mtu(uint8_t *data, uint16_t len) +static void +exchange_mtu(uint8_t *data, uint16_t len) { - struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; + struct ble_gap_conn_desc conn; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } - if (ble_gattc_exchange_mtu(conn.conn_handle, tester_mtu_exchanged_ev, NULL)) { - status = BTP_STATUS_FAILED; - goto rsp; - } + if (ble_gattc_exchange_mtu(conn.conn_handle, + tester_mtu_exchanged_ev, + NULL)) { + status = BTP_STATUS_FAILED; + goto rsp; + } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_EXCHANGE_MTU, - CONTROLLER_INDEX, status); + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_EXCHANGE_MTU, + CONTROLLER_INDEX, status); } -static int disc_prim_svcs_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - const struct ble_gatt_svc *gatt_svc, void *arg) +static int +disc_prim_svcs_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_svc *gatt_svc, void *arg) { - struct gattc_disc_prim_svcs_rp *rp; - struct ble_gap_conn_desc conn; - struct gatt_service *service; - const ble_uuid_any_t *uuid; - const ble_addr_t *addr; - uint8_t uuid_length; - struct os_mbuf *buf = os_msys_get(0, 0); - uint8_t opcode = (uint8_t) (int) arg; - uint8_t err = (uint8_t) error->status; - int rc = 0; - - SYS_LOG_DBG(""); - - if (ble_gap_conn_find(conn_handle, &conn)) { - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - rp->status = err; - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->services_count = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - if (error->status == BLE_HS_EDONE) { - rp->status = 0; - rp->services_count = gatt_buf.cnt; - os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - uuid = &gatt_svc->uuid; - uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); - - service = gatt_buf_reserve(sizeof(*service) + uuid_length); - if (!service) { - discover_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - service->start_handle = sys_cpu_to_le16(gatt_svc->start_handle); - service->end_handle = sys_cpu_to_le16(gatt_svc->end_handle); - service->uuid_length = uuid_length; - - if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); - memcpy(service->uuid, &u16, uuid_length); - } else { - memcpy(service->uuid, BLE_UUID128(uuid)->value, - uuid_length); - } - - gatt_buf.cnt++; + struct gattc_disc_prim_svcs_rp *rp; + struct ble_gap_conn_desc conn; + struct gatt_service *service; + const ble_uuid_any_t *uuid; + const ble_addr_t *addr; + uint8_t uuid_length; + struct os_mbuf *buf = os_msys_get(0, 0); + uint8_t opcode = (uint8_t) (int) arg; + uint8_t err = (uint8_t) error->status; + int rc = 0; + + SYS_LOG_DBG(""); + + if (ble_gap_conn_find(conn_handle, &conn)) { + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + rp->status = err; + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->services_count = 0; + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + if (error->status == BLE_HS_EDONE) { + rp->status = 0; + rp->services_count = gatt_buf.cnt; + os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + uuid = &gatt_svc->uuid; + uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); + + service = gatt_buf_reserve(sizeof(*service) + uuid_length); + if (!service) { + discover_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + service->start_handle = sys_cpu_to_le16(gatt_svc->start_handle); + service->end_handle = sys_cpu_to_le16(gatt_svc->end_handle); + service->uuid_length = uuid_length; + + if (uuid->u.type == BLE_UUID_TYPE_16) { + uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + memcpy(service->uuid, &u16, uuid_length); + } else { + memcpy(service->uuid, BLE_UUID128(uuid)->value, + uuid_length); + } + + gatt_buf.cnt++; free: - os_mbuf_free_chain(buf); - return rc; + os_mbuf_free_chain(buf); + return rc; } -static void disc_all_prim_svcs(uint8_t *data, uint16_t len) +static void +disc_all_prim_svcs(uint8_t *data, uint16_t len) { - struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; + struct ble_gap_conn_desc conn; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } - if (ble_gattc_disc_all_svcs(conn.conn_handle, disc_prim_svcs_cb, - (void *) GATTC_DISC_ALL_PRIM_RP)) { - discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; - } + if (ble_gattc_disc_all_svcs(conn.conn_handle, disc_prim_svcs_cb, + (void *) GATTC_DISC_ALL_PRIM_RP)) { + discover_destroy(); + status = BTP_STATUS_FAILED; + goto rsp; + } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_PRIM_SVCS, - CONTROLLER_INDEX, status); + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_PRIM_SVCS, + CONTROLLER_INDEX, status); } -static void disc_prim_uuid(uint8_t *data, uint16_t len) +static void +disc_prim_uuid(uint8_t *data, uint16_t len) { - const struct gattc_disc_prim_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - ble_uuid_any_t uuid; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (ble_gattc_disc_svc_by_uuid(conn.conn_handle, - &uuid.u, disc_prim_svcs_cb, - (void *) GATTC_DISC_PRIM_UUID_RP)) { - discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; - } + const struct gattc_disc_prim_uuid_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + ble_uuid_any_t uuid; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + if (ble_gattc_disc_svc_by_uuid(conn.conn_handle, + &uuid.u, disc_prim_svcs_cb, + (void *) GATTC_DISC_PRIM_UUID_RP)) { + discover_destroy(); + status = BTP_STATUS_FAILED; + goto rsp; + } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_PRIM_UUID, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_PRIM_UUID, CONTROLLER_INDEX, + status); } -static int find_included_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - const struct ble_gatt_svc *gatt_svc, void *arg) +static int +find_included_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_svc *gatt_svc, void *arg) { - struct gattc_find_included_rp *rp; - struct gatt_included *included; - const ble_uuid_any_t *uuid; - int service_handle = (int) arg; - uint8_t uuid_length; - uint8_t err = (uint8_t) error->status; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; - - SYS_LOG_DBG(""); - - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - rp->status = err; - - SYS_LOG_DBG(""); - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->services_count = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_FIND_INCLUDED_RP, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - if (error->status == BLE_HS_EDONE) { - rp->status = 0; - rp->services_count = gatt_buf.cnt; - os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_FIND_INCLUDED_RP, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - uuid = &gatt_svc->uuid; - uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); - - included = gatt_buf_reserve(sizeof(*included) + uuid_length); - if (!included) { - discover_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - included->included_handle = sys_cpu_to_le16(service_handle + 1 + - rp->services_count); - included->service.start_handle = sys_cpu_to_le16(gatt_svc->start_handle); - included->service.end_handle = sys_cpu_to_le16(gatt_svc->end_handle); - included->service.uuid_length = uuid_length; - - if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); - memcpy(included->service.uuid, &u16, uuid_length); - } else { - memcpy(included->service.uuid, BLE_UUID128(uuid)->value, - uuid_length); - } - - gatt_buf.cnt++; + struct gattc_find_included_rp *rp; + struct gatt_included *included; + const ble_uuid_any_t *uuid; + int service_handle = (int) arg; + uint8_t uuid_length; + uint8_t err = (uint8_t) error->status; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; + + SYS_LOG_DBG(""); + + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + rp->status = err; + + SYS_LOG_DBG(""); + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->services_count = 0; + tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_FIND_INCLUDED_RP, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + if (error->status == BLE_HS_EDONE) { + rp->status = 0; + rp->services_count = gatt_buf.cnt; + os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); + tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_FIND_INCLUDED_RP, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + uuid = &gatt_svc->uuid; + uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); + + included = gatt_buf_reserve(sizeof(*included) + uuid_length); + if (!included) { + discover_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + included->included_handle = sys_cpu_to_le16(service_handle + 1 + + rp->services_count); + included->service.start_handle = sys_cpu_to_le16(gatt_svc->start_handle); + included->service.end_handle = sys_cpu_to_le16(gatt_svc->end_handle); + included->service.uuid_length = uuid_length; + + if (uuid->u.type == BLE_UUID_TYPE_16) { + uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + memcpy(included->service.uuid, &u16, uuid_length); + } else { + memcpy(included->service.uuid, BLE_UUID128(uuid)->value, + uuid_length); + } + + gatt_buf.cnt++; free: - os_mbuf_free_chain(buf); - return rc; + os_mbuf_free_chain(buf); + return rc; } -static void find_included(uint8_t *data, uint16_t len) +static void +find_included(uint8_t *data, uint16_t len) { - const struct gattc_find_included_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint16_t start_handle, end_handle; - int service_handle_arg; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); - service_handle_arg = start_handle; - - if (ble_gattc_find_inc_svcs(conn.conn_handle, start_handle, end_handle, - find_included_cb, - (void *) service_handle_arg)) { - discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; - } + const struct gattc_find_included_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint16_t start_handle, end_handle; + int service_handle_arg; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + start_handle = sys_le16_to_cpu(cmd->start_handle); + end_handle = sys_le16_to_cpu(cmd->end_handle); + service_handle_arg = start_handle; + + if (ble_gattc_find_inc_svcs(conn.conn_handle, start_handle, end_handle, + find_included_cb, + (void *) service_handle_arg)) { + discover_destroy(); + status = BTP_STATUS_FAILED; + goto rsp; + } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_FIND_INCLUDED, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_FIND_INCLUDED, CONTROLLER_INDEX, + status); } -static int disc_chrc_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - const struct ble_gatt_chr *gatt_chr, void *arg) +static int +disc_chrc_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_chr *gatt_chr, void *arg) { - struct gattc_disc_chrc_rp *rp; - struct gatt_characteristic *chrc; - const ble_uuid_any_t *uuid; - uint8_t uuid_length; - uint8_t opcode = (uint8_t) (int) arg; - uint8_t err = (uint8_t) error->status; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; - - SYS_LOG_DBG(""); - if (ble_gap_conn_find(conn_handle, &conn)) { - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - rp->status = err; - - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->characteristics_count = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - if (error->status == BLE_HS_EDONE) { - rp->status = 0; - rp->characteristics_count = gatt_buf.cnt; - os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - uuid = &gatt_chr->uuid; - uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); - - chrc = gatt_buf_reserve(sizeof(*chrc) + uuid_length); - if (!chrc) { - discover_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - chrc->characteristic_handle = sys_cpu_to_le16(gatt_chr->def_handle); - chrc->properties = gatt_chr->properties; - chrc->value_handle = sys_cpu_to_le16(gatt_chr->val_handle); - chrc->uuid_length = uuid_length; - - if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); - memcpy(chrc->uuid, &u16, uuid_length); - } else { - memcpy(chrc->uuid, BLE_UUID128(uuid)->value, - uuid_length); - } - - gatt_buf.cnt++; + struct gattc_disc_chrc_rp *rp; + struct gatt_characteristic *chrc; + const ble_uuid_any_t *uuid; + uint8_t uuid_length; + uint8_t opcode = (uint8_t) (int) arg; + uint8_t err = (uint8_t) error->status; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; + + SYS_LOG_DBG(""); + if (ble_gap_conn_find(conn_handle, &conn)) { + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + rp->status = err; + + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->characteristics_count = 0; + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + if (error->status == BLE_HS_EDONE) { + rp->status = 0; + rp->characteristics_count = gatt_buf.cnt; + os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + uuid = &gatt_chr->uuid; + uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); + + chrc = gatt_buf_reserve(sizeof(*chrc) + uuid_length); + if (!chrc) { + discover_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + chrc->characteristic_handle = sys_cpu_to_le16(gatt_chr->def_handle); + chrc->properties = gatt_chr->properties; + chrc->value_handle = sys_cpu_to_le16(gatt_chr->val_handle); + chrc->uuid_length = uuid_length; + + if (uuid->u.type == BLE_UUID_TYPE_16) { + uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + memcpy(chrc->uuid, &u16, uuid_length); + } else { + memcpy(chrc->uuid, BLE_UUID128(uuid)->value, + uuid_length); + } + + gatt_buf.cnt++; free: - os_mbuf_free_chain(buf); - return rc; + os_mbuf_free_chain(buf); + return rc; } -static void disc_all_chrc(uint8_t *data, uint16_t len) +static void +disc_all_chrc(uint8_t *data, uint16_t len) { - const struct gattc_disc_all_chrc_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint16_t start_handle, end_handle; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - SYS_LOG_DBG("Conn find rsped"); - status = BTP_STATUS_FAILED; - goto rsp; - } - - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); - - rc = ble_gattc_disc_all_chrs(conn.conn_handle, start_handle, end_handle, - disc_chrc_cb, (void *) GATTC_DISC_ALL_CHRC_RP); - if (rc) { - discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; - } + const struct gattc_disc_all_chrc_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint16_t start_handle, end_handle; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + SYS_LOG_DBG("Conn find rsped"); + status = BTP_STATUS_FAILED; + goto rsp; + } + + start_handle = sys_le16_to_cpu(cmd->start_handle); + end_handle = sys_le16_to_cpu(cmd->end_handle); + + rc = ble_gattc_disc_all_chrs(conn.conn_handle, + start_handle, + end_handle, + disc_chrc_cb, + (void *) GATTC_DISC_ALL_CHRC_RP); + if (rc) { + discover_destroy(); + status = BTP_STATUS_FAILED; + goto rsp; + } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_CHRC, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_CHRC, CONTROLLER_INDEX, + status); } -static void disc_chrc_uuid(uint8_t *data, uint16_t len) +static void +disc_chrc_uuid(uint8_t *data, uint16_t len) { - const struct gattc_disc_chrc_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint16_t start_handle, end_handle; - ble_uuid_any_t uuid; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); - - rc = ble_gattc_disc_chrs_by_uuid(conn.conn_handle, start_handle, - end_handle, &uuid.u, disc_chrc_cb, - (void *) GATTC_DISC_CHRC_UUID_RP); - if (rc) { - discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; - } + const struct gattc_disc_chrc_uuid_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint16_t start_handle, end_handle; + ble_uuid_any_t uuid; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + start_handle = sys_le16_to_cpu(cmd->start_handle); + end_handle = sys_le16_to_cpu(cmd->end_handle); + + rc = ble_gattc_disc_chrs_by_uuid(conn.conn_handle, start_handle, + end_handle, &uuid.u, disc_chrc_cb, + (void *) GATTC_DISC_CHRC_UUID_RP); + if (rc) { + discover_destroy(); + status = BTP_STATUS_FAILED; + goto rsp; + } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_CHRC_UUID, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_CHRC_UUID, CONTROLLER_INDEX, + status); } -static int disc_all_desc_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - uint16_t chr_val_handle, - const struct ble_gatt_dsc *gatt_dsc, - void *arg) +static int +disc_all_desc_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + uint16_t chr_val_handle, + const struct ble_gatt_dsc *gatt_dsc, + void *arg) { - struct gattc_disc_all_desc_rp *rp; - struct gatt_descriptor *dsc; - const ble_uuid_any_t *uuid; - uint8_t uuid_length; - uint8_t err = (uint8_t) error->status; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; - - SYS_LOG_DBG(""); - - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - rp->status = err; - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->descriptors_count = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_DESC_RP, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - if (error->status == BLE_HS_EDONE) { - rp->status = 0; - rp->descriptors_count = gatt_buf.cnt; - os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_DESC_RP, - CONTROLLER_INDEX, buf); - discover_destroy(); - goto free; - } - - uuid = &gatt_dsc->uuid; - uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); - - dsc = gatt_buf_reserve(sizeof(*dsc) + uuid_length); - if (!dsc) { - discover_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - dsc->descriptor_handle = sys_cpu_to_le16(gatt_dsc->handle); - dsc->uuid_length = uuid_length; - - if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); - memcpy(dsc->uuid, &u16, uuid_length); - } else { - memcpy(dsc->uuid, BLE_UUID128(uuid)->value, uuid_length); - } - - gatt_buf.cnt++; + struct gattc_disc_all_desc_rp *rp; + struct gatt_descriptor *dsc; + const ble_uuid_any_t *uuid; + uint8_t uuid_length; + uint8_t err = (uint8_t) error->status; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; + + SYS_LOG_DBG(""); + + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + rp->status = err; + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->descriptors_count = 0; + tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_DESC_RP, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + if (error->status == BLE_HS_EDONE) { + rp->status = 0; + rp->descriptors_count = gatt_buf.cnt; + os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); + tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_DESC_RP, + CONTROLLER_INDEX, buf); + discover_destroy(); + goto free; + } + + uuid = &gatt_dsc->uuid; + uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16); + + dsc = gatt_buf_reserve(sizeof(*dsc) + uuid_length); + if (!dsc) { + discover_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + dsc->descriptor_handle = sys_cpu_to_le16(gatt_dsc->handle); + dsc->uuid_length = uuid_length; + + if (uuid->u.type == BLE_UUID_TYPE_16) { + uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + memcpy(dsc->uuid, &u16, uuid_length); + } else { + memcpy(dsc->uuid, BLE_UUID128(uuid)->value, uuid_length); + } + + gatt_buf.cnt++; free: - os_mbuf_free_chain(buf); - return rc; + os_mbuf_free_chain(buf); + return rc; } -static void disc_all_desc(uint8_t *data, uint16_t len) +static void +disc_all_desc(uint8_t *data, uint16_t len) { - const struct gattc_disc_all_desc_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint16_t start_handle, end_handle; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; + const struct gattc_disc_all_desc_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint16_t start_handle, end_handle; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } - start_handle = sys_le16_to_cpu(cmd->start_handle) - 1; - end_handle = sys_le16_to_cpu(cmd->end_handle); + start_handle = sys_le16_to_cpu(cmd->start_handle) - 1; + end_handle = sys_le16_to_cpu(cmd->end_handle); - rc = ble_gattc_disc_all_dscs(conn.conn_handle, start_handle, end_handle, - disc_all_desc_cb, (void *) GATTC_DISC_ALL_DESC); + rc = ble_gattc_disc_all_dscs(conn.conn_handle, + start_handle, + end_handle, + disc_all_desc_cb, + (void *) GATTC_DISC_ALL_DESC); - SYS_LOG_DBG("rc=%d", rc); + SYS_LOG_DBG("rc=%d", rc); - if (rc) { - discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; - } + if (rc) { + discover_destroy(); + status = BTP_STATUS_FAILED; + goto rsp; + } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_DESC, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_DESC, CONTROLLER_INDEX, + status); } -static int read_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) +static int +read_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) { - struct gattc_read_rp *rp; - uint8_t opcode = (uint8_t) (int) arg; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; - - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - SYS_LOG_DBG("status=%d", error->status); - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->status = (uint8_t) BLE_HS_ATT_ERR(error->status); - rp->data_length = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - read_destroy(); - goto free; - } - - if (!gatt_buf_add(attr->om->om_data, attr->om->om_len)) { - read_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - rp->status = 0; - rp->data_length = attr->om->om_len; - os_mbuf_appendfrom(buf, attr->om, 0, os_mbuf_len(attr->om)); - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - read_destroy(); + struct gattc_read_rp *rp; + uint8_t opcode = (uint8_t) (int) arg; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; + + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + SYS_LOG_DBG("status=%d", error->status); + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->status = (uint8_t) BLE_HS_ATT_ERR(error->status); + rp->data_length = 0; + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + read_destroy(); + goto free; + } + + if (!gatt_buf_add(attr->om->om_data, attr->om->om_len)) { + read_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + rp->status = 0; + rp->data_length = attr->om->om_len; + os_mbuf_appendfrom(buf, attr->om, 0, os_mbuf_len(attr->om)); + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + read_destroy(); free: - os_mbuf_free_chain(buf); - return rc; + os_mbuf_free_chain(buf); + return rc; } -static void read(uint8_t *data, uint16_t len) +static void +read(uint8_t *data, uint16_t len) { - const struct gattc_read_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; + const struct gattc_read_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } - /* Clear buffer */ - read_destroy(); + /* Clear buffer */ + read_destroy(); - if (ble_gattc_read(conn.conn_handle, sys_le16_to_cpu(cmd->handle), - read_cb, (void *) GATTC_READ_RP)) { - read_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; - } + if (ble_gattc_read(conn.conn_handle, sys_le16_to_cpu(cmd->handle), + read_cb, (void *) GATTC_READ_RP)) { + read_destroy(); + status = BTP_STATUS_FAILED; + goto rsp; + } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ, CONTROLLER_INDEX, + status); } -static int read_uuid_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) +static int +read_uuid_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) { - struct gattc_read_uuid_rp *rp; - struct gatt_read_uuid_chr *chr; - uint8_t opcode = (uint8_t) (int) arg; - uint8_t err = (uint8_t) error->status; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; - static uint16_t attr_len; - - SYS_LOG_DBG("status=%d", error->status); - - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - rp->status = err; - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->data_length = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - read_destroy(); - goto free; - } - - if (error->status == BLE_HS_EDONE) { - rp->data_length = gatt_buf.len; - rp->value_length = attr_len; - rp->status = 0; - os_mbuf_append(buf, gatt_buf.buf+1, gatt_buf.len-1); - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + struct gattc_read_uuid_rp *rp; + struct gatt_read_uuid_chr *chr; + uint8_t opcode = (uint8_t) (int) arg; + uint8_t err = (uint8_t) error->status; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; + static uint16_t attr_len; + + SYS_LOG_DBG("status=%d", error->status); + + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + rp->status = err; + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->data_length = 0; + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + read_destroy(); + goto free; + } + + if (error->status == BLE_HS_EDONE) { + rp->data_length = gatt_buf.len; + rp->value_length = attr_len; + rp->status = 0; + os_mbuf_append(buf, gatt_buf.buf + 1, gatt_buf.len - 1); + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, CONTROLLER_INDEX, buf); - read_destroy(); - goto free; - } - - if (error->status == 0) { - attr_len = attr->om->om_len; - } - - if (gatt_buf_add(attr->om->om_data, attr->om->om_len) == NULL) { - read_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - chr = gatt_buf_reserve(sizeof(*chr) + attr->om->om_len); - if (!chr) { - read_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - chr->handle = sys_cpu_to_be16(attr->handle); - memcpy(chr->data, attr->om->om_data, attr->om->om_len); + read_destroy(); + goto free; + } + + if (error->status == 0) { + attr_len = attr->om->om_len; + } + + if (gatt_buf_add(attr->om->om_data, attr->om->om_len) == NULL) { + read_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + chr = gatt_buf_reserve(sizeof(*chr) + attr->om->om_len); + if (!chr) { + read_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + chr->handle = sys_cpu_to_be16(attr->handle); + memcpy(chr->data, attr->om->om_data, attr->om->om_len); free: - os_mbuf_free_chain(buf); - return rc; + os_mbuf_free_chain(buf); + return rc; } -static void read_uuid(uint8_t *data, uint16_t len) +static void +read_uuid(uint8_t *data, uint16_t len) { - const struct gattc_read_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - ble_uuid_any_t uuid; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - /* Clear buffer */ - read_destroy(); - - if (ble_gattc_read_by_uuid(conn.conn_handle, - sys_le16_to_cpu(cmd->start_handle), - sys_le16_to_cpu(cmd->end_handle), &uuid.u, - read_uuid_cb, (void *) GATTC_READ_UUID_RP)) { - read_destroy(); - status = BTP_STATUS_FAILED; - } + const struct gattc_read_uuid_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + ble_uuid_any_t uuid; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + /* Clear buffer */ + read_destroy(); + + if (ble_gattc_read_by_uuid(conn.conn_handle, + sys_le16_to_cpu(cmd->start_handle), + sys_le16_to_cpu(cmd->end_handle), &uuid.u, + read_uuid_cb, (void *) GATTC_READ_UUID_RP)) { + read_destroy(); + status = BTP_STATUS_FAILED; + } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ_UUID, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ_UUID, CONTROLLER_INDEX, + status); } -static int read_long_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) +static int +read_long_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) { - struct gattc_read_rp *rp;; - uint8_t opcode = (uint8_t) (int) arg; - uint8_t err = (uint8_t) error->status; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; - - SYS_LOG_DBG("status=%d", error->status); - - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } - - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); - - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); - - rp->status = err; - - if (error->status != 0 && error->status != BLE_HS_EDONE) { - rp->data_length = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - read_destroy(); - goto free; - } - - if (error->status == BLE_HS_EDONE) { - rp->status = 0; - rp->data_length = gatt_buf.len; - os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); - read_destroy(); - goto free; - } - - if (gatt_buf_add(attr->om->om_data, attr->om->om_len) == NULL) { - read_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - - rp->data_length += attr->om->om_len; + struct gattc_read_rp *rp;; + uint8_t opcode = (uint8_t) (int) arg; + uint8_t err = (uint8_t) error->status; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; + + SYS_LOG_DBG("status=%d", error->status); + + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } + + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); + + addr = &conn.peer_ota_addr; + + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); + + rp->status = err; + + if (error->status != 0 && error->status != BLE_HS_EDONE) { + rp->data_length = 0; + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + read_destroy(); + goto free; + } + + if (error->status == BLE_HS_EDONE) { + rp->status = 0; + rp->data_length = gatt_buf.len; + os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); + read_destroy(); + goto free; + } + + if (gatt_buf_add(attr->om->om_data, attr->om->om_len) == NULL) { + read_destroy(); + rc = BLE_HS_ENOMEM; + goto free; + } + + rp->data_length += attr->om->om_len; free: - os_mbuf_free_chain(buf); - return rc; + os_mbuf_free_chain(buf); + return rc; } -static void read_long(uint8_t *data, uint16_t len) +static void +read_long(uint8_t *data, uint16_t len) { - const struct gattc_read_long_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - /* Clear buffer */ - read_destroy(); - - if (ble_gattc_read_long(conn.conn_handle, - sys_le16_to_cpu(cmd->handle), - sys_le16_to_cpu(cmd->offset), - read_long_cb, (void *) GATTC_READ_LONG_RP)) { - read_destroy(); - status = BTP_STATUS_FAILED; - } + const struct gattc_read_long_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + /* Clear buffer */ + read_destroy(); + + if (ble_gattc_read_long(conn.conn_handle, + sys_le16_to_cpu(cmd->handle), + sys_le16_to_cpu(cmd->offset), + read_long_cb, (void *) GATTC_READ_LONG_RP)) { + read_destroy(); + status = BTP_STATUS_FAILED; + } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ_LONG, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ_LONG, CONTROLLER_INDEX, + status); } -static void read_multiple(uint8_t *data, uint16_t len) +static void +read_multiple(uint8_t *data, uint16_t len) { - const struct gattc_read_multiple_cmd *cmd = (void *) data; - uint16_t handles[cmd->handles_count]; - struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; - int rc, i; - - SYS_LOG_DBG(""); - - for (i = 0; i < ARRAY_SIZE(handles); i++) { - handles[i] = sys_le16_to_cpu(cmd->handles[i]); - } - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - /* Clear buffer */ - read_destroy(); - - if (ble_gattc_read_mult(conn.conn_handle, handles, - cmd->handles_count, read_cb, (void *) GATTC_READ_MULTIPLE_RP)) { - read_destroy(); - status = BTP_STATUS_FAILED; - } + const struct gattc_read_multiple_cmd *cmd = (void *) data; + uint16_t handles[cmd->handles_count]; + struct ble_gap_conn_desc conn; + uint8_t status = BTP_STATUS_SUCCESS; + int rc, i; + + SYS_LOG_DBG(""); + + for (i = 0; i < ARRAY_SIZE(handles); i++) { + handles[i] = sys_le16_to_cpu(cmd->handles[i]); + } + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + /* Clear buffer */ + read_destroy(); + + if (ble_gattc_read_mult(conn.conn_handle, + handles, + cmd->handles_count, + read_cb, + (void *) GATTC_READ_MULTIPLE_RP)) { + read_destroy(); + status = BTP_STATUS_FAILED; + } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ_MULTIPLE, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ_MULTIPLE, CONTROLLER_INDEX, + status); } -static void write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) +static void +write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) { - const struct gattc_write_without_rsp_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; + const struct gattc_write_without_rsp_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } - if (ble_gattc_write_no_rsp_flat(conn.conn_handle, - sys_le16_to_cpu(cmd->handle), cmd->data, - sys_le16_to_cpu(cmd->data_length))) { - status = BTP_STATUS_FAILED; - } + if (ble_gattc_write_no_rsp_flat(conn.conn_handle, + sys_le16_to_cpu(cmd->handle), cmd->data, + sys_le16_to_cpu(cmd->data_length))) { + status = BTP_STATUS_FAILED; + } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, op, CONTROLLER_INDEX, status); + tester_rsp(BTP_SERVICE_ID_GATTC, op, CONTROLLER_INDEX, status); } -static int write_cb(uint16_t conn_handle, const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) +static int +write_cb(uint16_t conn_handle, const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) { - struct gattc_write_rp *rp; - uint8_t err = (uint8_t) error->status; - uint8_t opcode = (uint8_t) (int) arg; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; + struct gattc_write_rp *rp; + uint8_t err = (uint8_t) error->status; + uint8_t opcode = (uint8_t) (int) arg; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); - addr = &conn.peer_ota_addr; + addr = &conn.peer_ota_addr; - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); - rp->status = err; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); + rp->status = err; + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); free: - os_mbuf_free_chain(buf); - return rc; + os_mbuf_free_chain(buf); + return rc; } -static void write(uint8_t *data, uint16_t len) +static void +write(uint8_t *data, uint16_t len) { - const struct gattc_write_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; + const struct gattc_write_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } - if (ble_gattc_write_flat(conn.conn_handle, sys_le16_to_cpu(cmd->handle), - cmd->data, sys_le16_to_cpu(cmd->data_length), - write_cb, (void *) GATTC_WRITE_RP)) { - status = BTP_STATUS_FAILED; - } + if (ble_gattc_write_flat(conn.conn_handle, sys_le16_to_cpu(cmd->handle), + cmd->data, sys_le16_to_cpu(cmd->data_length), + write_cb, (void *) GATTC_WRITE_RP)) { + status = BTP_STATUS_FAILED; + } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_WRITE, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_WRITE, CONTROLLER_INDEX, + status); } -static void write_long(uint8_t *data, uint16_t len) +static void +write_long(uint8_t *data, uint16_t len) { - const struct gattc_write_long_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - struct os_mbuf *om = NULL; - uint8_t status = BTP_STATUS_SUCCESS; - int rc = 0; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - goto fail; - } - - om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); - if (!om) { - SYS_LOG_ERR("Insufficient resources"); - status = BTP_STATUS_FAILED; - goto fail; - } - - rc = ble_gattc_write_long(conn.conn_handle, - sys_le16_to_cpu(cmd->handle), - sys_le16_to_cpu(cmd->offset), - om, write_cb, - (void *) GATTC_WRITE_LONG_RP); - if (rc) { - status = BTP_STATUS_FAILED; - } else { - goto rsp; - } + const struct gattc_write_long_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + struct os_mbuf *om = NULL; + uint8_t status = BTP_STATUS_SUCCESS; + int rc = 0; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + goto fail; + } + + om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); + if (!om) { + SYS_LOG_ERR("Insufficient resources"); + status = BTP_STATUS_FAILED; + goto fail; + } + + rc = ble_gattc_write_long(conn.conn_handle, + sys_le16_to_cpu(cmd->handle), + sys_le16_to_cpu(cmd->offset), + om, write_cb, + (void *) GATTC_WRITE_LONG_RP); + if (rc) { + status = BTP_STATUS_FAILED; + } else { + goto rsp; + } fail: - SYS_LOG_ERR("Failed to send Write Long request, rc=%d", rc); - os_mbuf_free_chain(om); + SYS_LOG_ERR("Failed to send Write Long request, rc=%d", rc); + os_mbuf_free_chain(om); rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_WRITE_LONG, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_WRITE_LONG, CONTROLLER_INDEX, + status); } -static int reliable_write_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attrs, - uint8_t num_attrs, - void *arg) +static int +reliable_write_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attrs, + uint8_t num_attrs, + void *arg) { - struct gattc_write_rp *rp; - uint8_t err = (uint8_t) error->status; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; + struct gattc_write_rp *rp; + uint8_t err = (uint8_t) error->status; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); - addr = &conn.peer_ota_addr; + addr = &conn.peer_ota_addr; - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); - rp->status = err; - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_RELIABLE_WRITE_RP, - CONTROLLER_INDEX, buf); + rp->status = err; + tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_RELIABLE_WRITE_RP, + CONTROLLER_INDEX, buf); free: - os_mbuf_free_chain(buf); - return rc; + os_mbuf_free_chain(buf); + return rc; } -static void reliable_write(uint8_t *data, uint16_t len) +static void +reliable_write(uint8_t *data, uint16_t len) { - const struct gattc_reliable_write_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - struct ble_gatt_attr attr; - struct os_mbuf *om = NULL; - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto fail; - } - - om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); - /* This is required, because Nimble checks if - * the data is longer than offset - */ - if (os_mbuf_extend(om, sys_le16_to_cpu(cmd->offset) + 1) == NULL) { - status = BTP_STATUS_FAILED; - goto fail; - } - - attr.handle = sys_le16_to_cpu(cmd->handle); - attr.offset = sys_le16_to_cpu(cmd->offset); - attr.om = om; - - if (ble_gattc_write_reliable(conn.conn_handle, &attr, 1, - reliable_write_cb, NULL)) { - status = BTP_STATUS_FAILED; - goto fail; - } else { - goto rsp; - } + const struct gattc_reliable_write_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + struct ble_gatt_attr attr; + struct os_mbuf *om = NULL; + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto fail; + } + + om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); + /* This is required, because Nimble checks if + * the data is longer than offset + */ + if (os_mbuf_extend(om, sys_le16_to_cpu(cmd->offset) + 1) == NULL) { + status = BTP_STATUS_FAILED; + goto fail; + } + + attr.handle = sys_le16_to_cpu(cmd->handle); + attr.offset = sys_le16_to_cpu(cmd->offset); + attr.om = om; + + if (ble_gattc_write_reliable(conn.conn_handle, &attr, 1, + reliable_write_cb, NULL)) { + status = BTP_STATUS_FAILED; + goto fail; + } else { + goto rsp; + } fail: - os_mbuf_free_chain(om); + os_mbuf_free_chain(om); rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_WRITE_LONG, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_WRITE_LONG, CONTROLLER_INDEX, + status); } -static int subscribe_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attrs, - void *arg) +static int +subscribe_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attrs, + void *arg) { - struct subscribe_rp *rp; - uint8_t err = (uint8_t) error->status; - uint8_t opcode = (uint8_t) (int) arg; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; - struct ble_gap_conn_desc conn; - int rc = 0; + struct subscribe_rp *rp; + uint8_t err = (uint8_t) error->status; + uint8_t opcode = (uint8_t) (int) arg; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; + struct ble_gap_conn_desc conn; + int rc = 0; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - if (ble_gap_conn_find(conn_handle, &conn)) { - rc = BLE_HS_EINVAL; - goto free; - } + if (ble_gap_conn_find(conn_handle, &conn)) { + rc = BLE_HS_EINVAL; + goto free; + } - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + net_buf_simple_init(buf, 0); + rp = net_buf_simple_add(buf, sizeof(*rp)); - addr = &conn.peer_ota_addr; + addr = &conn.peer_ota_addr; - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); + rp->address_type = addr->type; + memcpy(rp->address, addr->val, sizeof(rp->address)); - rp->status = err; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); + rp->status = err; + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, + CONTROLLER_INDEX, buf); free: - os_mbuf_free_chain(buf); - return rc; + os_mbuf_free_chain(buf); + return rc; } -static int enable_subscription(uint16_t conn_handle, uint16_t ccc_handle, - uint16_t value) +static int +enable_subscription(uint16_t conn_handle, uint16_t ccc_handle, + uint16_t value) { - uint32_t opcode; + uint32_t opcode; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - opcode = (uint32_t) (value == 0x0001 ? GATTC_CFG_NOTIFY_RP : GATTC_CFG_INDICATE_RP); + opcode = (uint32_t) (value == 0x0001 ? GATTC_CFG_NOTIFY_RP + : GATTC_CFG_INDICATE_RP); - if (ble_gattc_write_flat(conn_handle, ccc_handle, - &value, sizeof(value), subscribe_cb, (void *) opcode)) { - return -EINVAL; - } + if (ble_gattc_write_flat(conn_handle, + ccc_handle, + &value, + sizeof(value), + subscribe_cb, + (void *) opcode)) { + return -EINVAL; + } - subscribe_params.ccc_handle = value; + subscribe_params.ccc_handle = value; - return 0; + return 0; } -static int disable_subscription(uint16_t conn_handle, uint16_t ccc_handle) +static int +disable_subscription(uint16_t conn_handle, uint16_t ccc_handle) { - uint16_t value = 0x00; - uint32_t opcode; - - SYS_LOG_DBG(""); - - opcode = (uint32_t) (value == 0x0001 ? GATTC_CFG_NOTIFY_RP : GATTC_CFG_INDICATE_RP); - - /* Fail if CCC handle doesn't match */ - if (ccc_handle != subscribe_params.ccc_handle) { - SYS_LOG_ERR("CCC handle doesn't match"); - return -EINVAL; - } - - if (ble_gattc_write_flat(conn_handle, ccc_handle, - &value, sizeof(value), subscribe_cb, (void *) opcode)) { - return -EINVAL; - } - - subscribe_params.ccc_handle = 0; - return 0; + uint16_t value = 0x00; + uint32_t opcode; + + SYS_LOG_DBG(""); + + opcode = (uint32_t) (value == 0x0001 ? GATTC_CFG_NOTIFY_RP + : GATTC_CFG_INDICATE_RP); + + /* Fail if CCC handle doesn't match */ + if (ccc_handle != subscribe_params.ccc_handle) { + SYS_LOG_ERR("CCC handle doesn't match"); + return -EINVAL; + } + + if (ble_gattc_write_flat(conn_handle, + ccc_handle, + &value, + sizeof(value), + subscribe_cb, + (void *) opcode)) { + return -EINVAL; + } + + subscribe_params.ccc_handle = 0; + return 0; } -static void config_subscription(uint8_t *data, uint16_t len, uint8_t op) +static void +config_subscription(uint8_t *data, uint16_t len, uint8_t op) { - const struct gattc_cfg_notify_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; - uint16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle); - uint8_t status = BTP_STATUS_SUCCESS; - int rc; - - SYS_LOG_DBG(""); - - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); - if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; - } - - if (cmd->enable) { - uint16_t value; - - if (op == GATTC_CFG_NOTIFY) { - value = 0x0001; - } else { - value = 0x0002; - } - - if (enable_subscription(conn.conn_handle, - ccc_handle, value) != 0) { - status = BTP_STATUS_FAILED; - goto rsp; - } - } else { - if (disable_subscription(conn.conn_handle, ccc_handle) < 0) { - status = BTP_STATUS_FAILED; - } else { - status = BTP_STATUS_SUCCESS; - } - } + const struct gattc_cfg_notify_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; + uint16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle); + uint8_t status = BTP_STATUS_SUCCESS; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (rc) { + status = BTP_STATUS_FAILED; + goto rsp; + } + + if (cmd->enable) { + uint16_t value; + + if (op == GATTC_CFG_NOTIFY) { + value = 0x0001; + } else { + value = 0x0002; + } + + if (enable_subscription(conn.conn_handle, + ccc_handle, value) != 0) { + status = BTP_STATUS_FAILED; + goto rsp; + } + } else { + if (disable_subscription(conn.conn_handle, ccc_handle) < 0) { + status = BTP_STATUS_FAILED; + } else { + status = BTP_STATUS_SUCCESS; + } + } rsp: - SYS_LOG_DBG("Config subscription (op %u) status %u", op, status); + SYS_LOG_DBG("Config subscription (op %u) status %u", op, status); - tester_rsp(BTP_SERVICE_ID_GATTC, op, CONTROLLER_INDEX, status); + tester_rsp(BTP_SERVICE_ID_GATTC, op, CONTROLLER_INDEX, status); } -int tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, - uint8_t indication, struct os_mbuf *om) +int +tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, + uint8_t indication, struct os_mbuf *om) { - struct gattc_notification_ev *ev; - struct ble_gap_conn_desc conn; - struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; + struct gattc_notification_ev *ev; + struct ble_gap_conn_desc conn; + struct os_mbuf *buf = os_msys_get(0, 0); + const ble_addr_t *addr; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - if (!subscribe_params.ccc_handle) { - goto fail; - } + if (!subscribe_params.ccc_handle) { + goto fail; + } - if (ble_gap_conn_find(conn_handle, &conn)) { - goto fail; - } + if (ble_gap_conn_find(conn_handle, &conn)) { + goto fail; + } - net_buf_simple_init(buf, 0); - ev = net_buf_simple_add(buf, sizeof(*ev)); + net_buf_simple_init(buf, 0); + ev = net_buf_simple_add(buf, sizeof(*ev)); - addr = &conn.peer_ota_addr; + addr = &conn.peer_ota_addr; - ev->address_type = addr->type; - memcpy(ev->address, addr->val, sizeof(ev->address)); - ev->type = (uint8_t) (indication ? 0x02 : 0x01); - ev->handle = sys_cpu_to_le16(attr_handle); - ev->data_length = sys_cpu_to_le16(os_mbuf_len(om)); - os_mbuf_appendfrom(buf, om, 0, os_mbuf_len(om)); + ev->address_type = addr->type; + memcpy(ev->address, addr->val, sizeof(ev->address)); + ev->type = (uint8_t) (indication ? 0x02 : 0x01); + ev->handle = sys_cpu_to_le16(attr_handle); + ev->data_length = sys_cpu_to_le16(os_mbuf_len(om)); + os_mbuf_appendfrom(buf, om, 0, os_mbuf_len(om)); - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_EV_NOTIFICATION_RXED, - CONTROLLER_INDEX, buf); + tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_EV_NOTIFICATION_RXED, + CONTROLLER_INDEX, buf); fail: - os_mbuf_free_chain(buf); - return 0; + os_mbuf_free_chain(buf); + return 0; } -static void supported_commands(uint8_t *data, uint16_t len) +static void +supported_commands(uint8_t *data, uint16_t len) { - uint8_t cmds[3]; - struct gatt_read_supported_commands_rp *rp = (void *) cmds; - - SYS_LOG_DBG(""); - - memset(cmds, 0, sizeof(cmds)); - - tester_set_bit(cmds, GATTC_READ_SUPPORTED_COMMANDS); - tester_set_bit(cmds, GATTC_EXCHANGE_MTU); - tester_set_bit(cmds, GATTC_DISC_ALL_PRIM_SVCS); - tester_set_bit(cmds, GATTC_DISC_PRIM_UUID); - tester_set_bit(cmds, GATTC_FIND_INCLUDED); - tester_set_bit(cmds, GATTC_DISC_ALL_CHRC); - tester_set_bit(cmds, GATTC_DISC_CHRC_UUID); - tester_set_bit(cmds, GATTC_DISC_ALL_DESC); - tester_set_bit(cmds, GATTC_READ); - tester_set_bit(cmds, GATTC_READ_UUID); - tester_set_bit(cmds, GATTC_READ_LONG); - tester_set_bit(cmds, GATTC_READ_MULTIPLE); - tester_set_bit(cmds, GATTC_WRITE_WITHOUT_RSP); + uint8_t cmds[3]; + struct gatt_read_supported_commands_rp *rp = (void *) cmds; + + SYS_LOG_DBG(""); + + memset(cmds, 0, sizeof(cmds)); + + tester_set_bit(cmds, GATTC_READ_SUPPORTED_COMMANDS); + tester_set_bit(cmds, GATTC_EXCHANGE_MTU); + tester_set_bit(cmds, GATTC_DISC_ALL_PRIM_SVCS); + tester_set_bit(cmds, GATTC_DISC_PRIM_UUID); + tester_set_bit(cmds, GATTC_FIND_INCLUDED); + tester_set_bit(cmds, GATTC_DISC_ALL_CHRC); + tester_set_bit(cmds, GATTC_DISC_CHRC_UUID); + tester_set_bit(cmds, GATTC_DISC_ALL_DESC); + tester_set_bit(cmds, GATTC_READ); + tester_set_bit(cmds, GATTC_READ_UUID); + tester_set_bit(cmds, GATTC_READ_LONG); + tester_set_bit(cmds, GATTC_READ_MULTIPLE); + tester_set_bit(cmds, GATTC_WRITE_WITHOUT_RSP); #if 0 - tester_set_bit(cmds, GATTC_SIGNED_WRITE_WITHOUT_RSP); + tester_set_bit(cmds, GATTC_SIGNED_WRITE_WITHOUT_RSP); #endif - tester_set_bit(cmds, GATTC_WRITE); - tester_set_bit(cmds, GATTC_WRITE_LONG); - tester_set_bit(cmds, GATTC_RELIABLE_WRITE); - tester_set_bit(cmds, GATTC_CFG_NOTIFY); - tester_set_bit(cmds, GATTC_CFG_INDICATE); - - tester_send(BTP_SERVICE_ID_GATTC, GATTC_READ_SUPPORTED_COMMANDS, - CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); + tester_set_bit(cmds, GATTC_WRITE); + tester_set_bit(cmds, GATTC_WRITE_LONG); + tester_set_bit(cmds, GATTC_RELIABLE_WRITE); + tester_set_bit(cmds, GATTC_CFG_NOTIFY); + tester_set_bit(cmds, GATTC_CFG_INDICATE); + + tester_send(BTP_SERVICE_ID_GATTC, GATTC_READ_SUPPORTED_COMMANDS, + CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); } -void tester_handle_gattc(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len) +void +tester_handle_gattc(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len) { - switch (opcode) { - case GATTC_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - return; - case GATTC_EXCHANGE_MTU: - exchange_mtu(data, len); - return; - case GATTC_DISC_ALL_PRIM_SVCS: - disc_all_prim_svcs(data, len); - return; - case GATTC_DISC_PRIM_UUID: - disc_prim_uuid(data, len); - return; - case GATTC_FIND_INCLUDED: - find_included(data, len); - return; - case GATTC_DISC_ALL_CHRC: - disc_all_chrc(data, len); - return; - case GATTC_DISC_CHRC_UUID: - disc_chrc_uuid(data, len); - return; - case GATTC_DISC_ALL_DESC: - disc_all_desc(data, len); - return; - case GATTC_READ: - read(data, len); - return; - case GATTC_READ_UUID: - read_uuid(data, len); - return; - case GATTC_READ_LONG: - read_long(data, len); - return; - case GATTC_READ_MULTIPLE: - read_multiple(data, len); - return; - case GATTC_WRITE_WITHOUT_RSP: - write_without_rsp(data, len, opcode, false); - return; + switch (opcode) { + case GATTC_READ_SUPPORTED_COMMANDS: + supported_commands(data, len); + return; + case GATTC_EXCHANGE_MTU: + exchange_mtu(data, len); + return; + case GATTC_DISC_ALL_PRIM_SVCS: + disc_all_prim_svcs(data, len); + return; + case GATTC_DISC_PRIM_UUID: + disc_prim_uuid(data, len); + return; + case GATTC_FIND_INCLUDED: + find_included(data, len); + return; + case GATTC_DISC_ALL_CHRC: + disc_all_chrc(data, len); + return; + case GATTC_DISC_CHRC_UUID: + disc_chrc_uuid(data, len); + return; + case GATTC_DISC_ALL_DESC: + disc_all_desc(data, len); + return; + case GATTC_READ: + read(data, len); + return; + case GATTC_READ_UUID: + read_uuid(data, len); + return; + case GATTC_READ_LONG: + read_long(data, len); + return; + case GATTC_READ_MULTIPLE: + read_multiple(data, len); + return; + case GATTC_WRITE_WITHOUT_RSP: + write_without_rsp(data, + len, + opcode, + false); + return; #if 0 - case GATTC_SIGNED_WRITE_WITHOUT_RSP: - write_without_rsp(data, len, opcode, true); - return; + case GATTC_SIGNED_WRITE_WITHOUT_RSP: + write_without_rsp(data, len, opcode, true); + return; #endif - case GATTC_WRITE: - write(data, len); - return; - case GATTC_WRITE_LONG: - write_long(data, len); - return; - case GATTC_RELIABLE_WRITE: - reliable_write(data, len); - return; - case GATTC_CFG_NOTIFY: - case GATTC_CFG_INDICATE: - config_subscription(data, len, opcode); - return; - default: - tester_rsp(BTP_SERVICE_ID_GATTC, opcode, index, - BTP_STATUS_UNKNOWN_CMD); - return; - } + case GATTC_WRITE: + write(data, len); + return; + case GATTC_WRITE_LONG: + write_long(data, len); + return; + case GATTC_RELIABLE_WRITE: + reliable_write(data, len); + return; + case GATTC_CFG_NOTIFY: + case GATTC_CFG_INDICATE: + config_subscription(data, len, opcode); + return; + default: + tester_rsp(BTP_SERVICE_ID_GATTC, opcode, index, + BTP_STATUS_UNKNOWN_CMD); + return; + } } \ No newline at end of file diff --git a/apps/bttester/src/glue.c b/apps/bttester/src/glue.c index 3e606062a3..f4c838184b 100644 --- a/apps/bttester/src/glue.c +++ b/apps/bttester/src/glue.c @@ -31,99 +31,99 @@ const char *bt_hex(const void *buf, size_t len) { - static const char hex[] = "0123456789abcdef"; - static char hexbufs[4][137]; - static uint8_t curbuf; - const uint8_t *b = buf; - char *str; - int i; + static const char hex[] = "0123456789abcdef"; + static char hexbufs[4][137]; + static uint8_t curbuf; + const uint8_t *b = buf; + char *str; + int i; - str = hexbufs[curbuf++]; - curbuf %= ARRAY_SIZE(hexbufs); + str = hexbufs[curbuf++]; + curbuf %= ARRAY_SIZE(hexbufs); - len = min(len, (sizeof(hexbufs[0]) - 1) / 2); + len = min(len, (sizeof(hexbufs[0]) - 1) / 2); - for (i = 0; i < len; i++) { - str[i * 2] = hex[b[i] >> 4]; - str[i * 2 + 1] = hex[b[i] & 0xf]; - } + for (i = 0; i < len; i++) { + str[i * 2] = hex[b[i] >> 4]; + str[i * 2 + 1] = hex[b[i] & 0xf]; + } - str[i * 2] = '\0'; + str[i * 2] = '\0'; - return str; + return str; } struct os_mbuf * NET_BUF_SIMPLE(uint16_t size) { - struct os_mbuf *buf; + struct os_mbuf *buf; - buf = os_msys_get(size, 0); - assert(buf); + buf = os_msys_get(size, 0); + assert(buf); - return buf; + return buf; } /* This is by purpose */ void net_buf_simple_init(struct os_mbuf *buf, - size_t reserve_head) + size_t reserve_head) { - /* This is called in Zephyr after init. - * Note in Mynewt case we don't care abour reserved head*/ - buf->om_data = &buf->om_databuf[buf->om_pkthdr_len] + reserve_head; - buf->om_len = 0; + /* This is called in Zephyr after init. + * Note in Mynewt case we don't care abour reserved head*/ + buf->om_data = &buf->om_databuf[buf->om_pkthdr_len] + reserve_head; + buf->om_len = 0; } void net_buf_simple_add_le16(struct os_mbuf *om, uint16_t val) { - val = htole16(val); - os_mbuf_append(om, &val, sizeof(val)); - ASSERT_NOT_CHAIN(om); + val = htole16(val); + os_mbuf_append(om, &val, sizeof(val)); + ASSERT_NOT_CHAIN(om); } void net_buf_simple_add_be16(struct os_mbuf *om, uint16_t val) { - val = htobe16(val); - os_mbuf_append(om, &val, sizeof(val)); - ASSERT_NOT_CHAIN(om); + val = htobe16(val); + os_mbuf_append(om, &val, sizeof(val)); + ASSERT_NOT_CHAIN(om); } void net_buf_simple_add_be32(struct os_mbuf *om, uint32_t val) { - val = htobe32(val); - os_mbuf_append(om, &val, sizeof(val)); - ASSERT_NOT_CHAIN(om); + val = htobe32(val); + os_mbuf_append(om, &val, sizeof(val)); + ASSERT_NOT_CHAIN(om); } void net_buf_simple_add_u8(struct os_mbuf *om, uint8_t val) { - os_mbuf_append(om, &val, 1); - ASSERT_NOT_CHAIN(om); + os_mbuf_append(om, &val, 1); + ASSERT_NOT_CHAIN(om); } void* net_buf_simple_add(struct os_mbuf *om, uint8_t len) { - void * tmp; + void * tmp; - tmp = os_mbuf_extend(om, len); - ASSERT_NOT_CHAIN(om); + tmp = os_mbuf_extend(om, len); + ASSERT_NOT_CHAIN(om); - return tmp; + return tmp; } uint8_t * net_buf_simple_push(struct os_mbuf *om, uint8_t len) { - uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len]; + uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len]; - assert(headroom >= len); - om->om_data -= len; - om->om_len += len; + assert(headroom >= len); + om->om_data -= len; + om->om_len += len; - return om->om_data; + return om->om_data; } #endif diff --git a/apps/bttester/src/glue.h b/apps/bttester/src/glue.h index 6508560151..0372d757fe 100644 --- a/apps/bttester/src/glue.h +++ b/apps/bttester/src/glue.h @@ -49,15 +49,22 @@ struct bt_data { .data = (const uint8_t *)(_data), \ } -struct os_mbuf * NET_BUF_SIMPLE(uint16_t size); -void net_buf_simple_init(struct os_mbuf *buf, size_t reserve_head); -void net_buf_simple_add_le16(struct os_mbuf *om, uint16_t val); -void net_buf_simple_add_u8(struct os_mbuf *om, uint8_t val); -void *net_buf_simple_add(struct os_mbuf *om, uint8_t len); -uint8_t *net_buf_simple_push(struct os_mbuf *om, uint8_t len); +struct os_mbuf * +NET_BUF_SIMPLE(uint16_t size); +void +net_buf_simple_init(struct os_mbuf *buf, size_t reserve_head); +void +net_buf_simple_add_le16(struct os_mbuf *om, uint16_t val); +void +net_buf_simple_add_u8(struct os_mbuf *om, uint8_t val); +void * +net_buf_simple_add(struct os_mbuf *om, uint8_t len); +uint8_t * +net_buf_simple_push(struct os_mbuf *om, uint8_t len); -#define net_buf_simple_add_mem(a,b,c) os_mbuf_append(a,b,c) +#define net_buf_simple_add_mem(a, b, c) os_mbuf_append(a,b,c) -const char *bt_hex(const void *buf, size_t len); +const char * +bt_hex(const void *buf, size_t len); #endif /* __GLUE_H__ */ diff --git a/apps/bttester/src/l2cap.c b/apps/bttester/src/l2cap.c index 7890e7cced..32baab1d91 100644 --- a/apps/bttester/src/l2cap.c +++ b/apps/bttester/src/l2cap.c @@ -43,7 +43,7 @@ #define TESTER_COC_BUF_COUNT (3 * MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)) static os_membuf_t tester_sdu_coc_mem[ - OS_MEMPOOL_SIZE(TESTER_COC_BUF_COUNT, TESTER_COC_MTU) + OS_MEMPOOL_SIZE(TESTER_COC_BUF_COUNT, TESTER_COC_MTU) ]; struct os_mbuf_pool sdu_os_mbuf_pool; @@ -51,574 +51,595 @@ static struct os_mempool sdu_coc_mbuf_mempool; static bool hold_credit = false; static struct channel { - uint8_t chan_id; /* Internal number that identifies L2CAP channel. */ - uint8_t state; - struct ble_l2cap_chan *chan; + uint8_t chan_id; /* Internal number that identifies L2CAP channel. */ + uint8_t state; + struct ble_l2cap_chan *chan; } channels[CHANNELS]; -static uint8_t recv_cb_buf[TESTER_COC_MTU + sizeof(struct l2cap_data_received_ev)]; +static uint8_t + recv_cb_buf[TESTER_COC_MTU + sizeof(struct l2cap_data_received_ev)]; -static struct channel *get_free_channel(void) +static struct channel * +get_free_channel(void) { - uint8_t i; - struct channel *chan; + uint8_t i; + struct channel *chan; - for (i = 0; i < CHANNELS; i++) { - if (channels[i].state) { - continue; - } + for (i = 0; i < CHANNELS; i++) { + if (channels[i].state) { + continue; + } - chan = &channels[i]; - chan->chan_id = i; + chan = &channels[i]; + chan->chan_id = i; - return chan; - } + return chan; + } - return NULL; + return NULL; } -struct channel *find_channel(struct ble_l2cap_chan *chan) +struct channel * +find_channel(struct ble_l2cap_chan *chan) { - int i; + int i; - for (i = 0; i < CHANNELS; ++i) { - if (channels[i].chan == chan) { - return &channels[i]; - } - } + for (i = 0; i < CHANNELS; ++i) { + if (channels[i].chan == chan) { + return &channels[i]; + } + } - return NULL; + return NULL; } -struct channel *get_channel(uint8_t chan_id) +struct channel * +get_channel(uint8_t chan_id) { - if (chan_id >= CHANNELS) { - return NULL; - } + if (chan_id >= CHANNELS) { + return NULL; + } - return &channels[chan_id]; + return &channels[chan_id]; } static void tester_l2cap_coc_recv(struct ble_l2cap_chan *chan, struct os_mbuf *sdu) { - SYS_LOG_DBG("LE CoC SDU received, chan: 0x%08lx, data len %d", - (uint32_t) chan, OS_MBUF_PKTLEN(sdu)); - - os_mbuf_free_chain(sdu); - if (!hold_credit) { - sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); - assert(sdu != NULL); + SYS_LOG_DBG("LE CoC SDU received, chan: 0x%08lx, data len %d", + (uint32_t) chan, OS_MBUF_PKTLEN(sdu)); + os_mbuf_free_chain(sdu); + if (!hold_credit) { + sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); + assert(sdu != NULL); - ble_l2cap_recv_ready(chan, sdu); - } + ble_l2cap_recv_ready(chan, sdu); + } } -static void recv_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, - struct os_mbuf *buf, void *arg) +static void +recv_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, + struct os_mbuf *buf, void *arg) { - struct l2cap_data_received_ev *ev = (void *) recv_cb_buf; - struct channel *channel = find_channel(chan); - assert(channel != NULL); + struct l2cap_data_received_ev *ev = (void *) recv_cb_buf; + struct channel *channel = find_channel(chan); + assert(channel != NULL); - ev->chan_id = channel->chan_id; - ev->data_length = OS_MBUF_PKTLEN(buf); + ev->chan_id = channel->chan_id; + ev->data_length = OS_MBUF_PKTLEN(buf); - if (ev->data_length > TESTER_COC_MTU) { - SYS_LOG_ERR("Too large sdu received, truncating data"); - ev->data_length = TESTER_COC_MTU; - } - os_mbuf_copydata(buf, 0, ev->data_length, ev->data); + if (ev->data_length > TESTER_COC_MTU) { + SYS_LOG_ERR("Too large sdu received, truncating data"); + ev->data_length = TESTER_COC_MTU; + } + os_mbuf_copydata(buf, 0, ev->data_length, ev->data); - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DATA_RECEIVED, - CONTROLLER_INDEX, recv_cb_buf, sizeof(*ev) + ev->data_length); + tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DATA_RECEIVED, + CONTROLLER_INDEX, recv_cb_buf, sizeof(*ev) + ev->data_length); - tester_l2cap_coc_recv(chan, buf); + tester_l2cap_coc_recv(chan, buf); } -static void unstalled_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, - int status, void *arg) +static void +unstalled_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, + int status, void *arg) { - if (status) { - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - } else { - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); - } + if (status) { + tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, + CONTROLLER_INDEX, BTP_STATUS_FAILED); + } else { + tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, + CONTROLLER_INDEX, BTP_STATUS_SUCCESS); + } } -static void reconfigured_ev(uint16_t conn_handle, struct ble_l2cap_chan *chan, - struct ble_l2cap_chan_info *chan_info, - int status) +static void +reconfigured_ev(uint16_t conn_handle, struct ble_l2cap_chan *chan, + struct ble_l2cap_chan_info *chan_info, + int status) { - struct l2cap_reconfigured_ev ev; - struct channel *channel; + struct l2cap_reconfigured_ev ev; + struct channel *channel; - if (status != 0) { - return; - } + if (status != 0) { + return; + } - channel = find_channel(chan); - assert(channel != NULL); + channel = find_channel(chan); + assert(channel != NULL); - ev.chan_id = channel->chan_id; - ev.peer_mtu = chan_info->peer_coc_mtu; - ev.peer_mps = chan_info->peer_l2cap_mtu; - ev.our_mtu = chan_info->our_coc_mtu; - ev.our_mps = chan_info->our_l2cap_mtu; + ev.chan_id = channel->chan_id; + ev.peer_mtu = chan_info->peer_coc_mtu; + ev.peer_mps = chan_info->peer_l2cap_mtu; + ev.our_mtu = chan_info->our_coc_mtu; + ev.our_mps = chan_info->our_l2cap_mtu; - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_RECONFIGURED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_RECONFIGURED, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } -static void connected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, - struct ble_l2cap_chan_info *chan_info, void *arg) +static void +connected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, + struct ble_l2cap_chan_info *chan_info, void *arg) { - struct l2cap_connected_ev ev; - struct ble_gap_conn_desc desc; - struct channel *channel = find_channel(chan); - - if (channel == NULL) { - channel = get_free_channel(); - } - - ev.chan_id = channel->chan_id; - ev.psm = chan_info->psm; - ev.peer_mtu = chan_info->peer_coc_mtu; - ev.peer_mps = chan_info->peer_l2cap_mtu; - ev.our_mtu = chan_info->our_coc_mtu; - ev.our_mps = chan_info->our_l2cap_mtu; - channel->state = 1; - channel->chan = chan; - - if (!ble_gap_conn_find(conn_handle, &desc)) { - ev.address_type = desc.peer_ota_addr.type; - memcpy(ev.address, desc.peer_ota_addr.val, - sizeof(ev.address)); - } - - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_CONNECTED, CONTROLLER_INDEX, - (uint8_t *) &ev, sizeof(ev)); + struct l2cap_connected_ev ev; + struct ble_gap_conn_desc desc; + struct channel *channel = find_channel(chan); + + if (channel == NULL) { + channel = get_free_channel(); + } + + ev.chan_id = channel->chan_id; + ev.psm = chan_info->psm; + ev.peer_mtu = chan_info->peer_coc_mtu; + ev.peer_mps = chan_info->peer_l2cap_mtu; + ev.our_mtu = chan_info->our_coc_mtu; + ev.our_mps = chan_info->our_l2cap_mtu; + channel->state = 1; + channel->chan = chan; + + if (!ble_gap_conn_find(conn_handle, &desc)) { + ev.address_type = desc.peer_ota_addr.type; + memcpy(ev.address, desc.peer_ota_addr.val, + sizeof(ev.address)); + } + + tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_CONNECTED, CONTROLLER_INDEX, + (uint8_t *) &ev, sizeof(ev)); } -static void disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, - struct ble_l2cap_chan_info *chan_info, void *arg) +static void +disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, + struct ble_l2cap_chan_info *chan_info, void *arg) { - struct l2cap_disconnected_ev ev; - struct ble_gap_conn_desc desc; - struct channel *channel; + struct l2cap_disconnected_ev ev; + struct ble_gap_conn_desc desc; + struct channel *channel; - memset(&ev, 0, sizeof(struct l2cap_disconnected_ev)); + memset(&ev, 0, sizeof(struct l2cap_disconnected_ev)); - channel = find_channel(chan); - assert(channel != NULL); + channel = find_channel(chan); + assert(channel != NULL); - channel->state = 0; - channel->chan = chan; - ev.chan_id = channel->chan_id; - ev.psm = chan_info->psm; + channel->state = 0; + channel->chan = chan; + ev.chan_id = channel->chan_id; + ev.psm = chan_info->psm; - if (!ble_gap_conn_find(conn_handle, &desc)) { - ev.address_type = desc.peer_ota_addr.type; - memcpy(ev.address, desc.peer_ota_addr.val, - sizeof(ev.address)); - } + if (!ble_gap_conn_find(conn_handle, &desc)) { + ev.address_type = desc.peer_ota_addr.type; + memcpy(ev.address, desc.peer_ota_addr.val, + sizeof(ev.address)); + } - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DISCONNECTED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DISCONNECTED, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } -static int accept_cb(uint16_t conn_handle, uint16_t peer_mtu, - struct ble_l2cap_chan *chan) +static int +accept_cb(uint16_t conn_handle, uint16_t peer_mtu, + struct ble_l2cap_chan *chan) { - struct os_mbuf *sdu_rx; + struct os_mbuf *sdu_rx; - SYS_LOG_DBG("LE CoC accepting, chan: 0x%08lx, peer_mtu %d", - (uint32_t) chan, peer_mtu); + SYS_LOG_DBG("LE CoC accepting, chan: 0x%08lx, peer_mtu %d", + (uint32_t) chan, peer_mtu); - sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); - if (!sdu_rx) { - return BLE_HS_ENOMEM; - } + sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); + if (!sdu_rx) { + return BLE_HS_ENOMEM; + } - ble_l2cap_recv_ready(chan, sdu_rx); + ble_l2cap_recv_ready(chan, sdu_rx); - return 0; + return 0; } static int tester_l2cap_event(struct ble_l2cap_event *event, void *arg) { - struct ble_l2cap_chan_info chan_info; - int accept_response; - struct ble_gap_conn_desc conn; - - switch (event->type) { - case BLE_L2CAP_EVENT_COC_CONNECTED: - if (ble_l2cap_get_chan_info(event->connect.chan, &chan_info)) { - assert(0); - } - - if (event->connect.status) { - console_printf("LE COC error: %d\n", event->connect.status); - return 0; - } - - console_printf("LE COC connected, conn: %d, chan: 0x%08lx, " - "psm: 0x%02x, scid: 0x%04x, dcid: 0x%04x, " - "our_mps: %d, our_mtu: %d, peer_mps: %d, " - "peer_mtu: %d\n", event->connect.conn_handle, - (uint32_t) event->connect.chan, chan_info.psm, - chan_info.scid, chan_info.dcid, - chan_info.our_l2cap_mtu, chan_info.our_coc_mtu, - chan_info.peer_l2cap_mtu, chan_info.peer_coc_mtu); - - connected_cb(event->connect.conn_handle, - event->connect.chan, &chan_info, arg); - - return 0; - case BLE_L2CAP_EVENT_COC_DISCONNECTED: - if (ble_l2cap_get_chan_info(event->disconnect.chan, - &chan_info)) { - assert(0); - } - console_printf("LE CoC disconnected, chan: 0x%08lx\n", - (uint32_t) event->disconnect.chan); - - disconnected_cb(event->disconnect.conn_handle, - event->disconnect.chan, &chan_info, arg); - return 0; - case BLE_L2CAP_EVENT_COC_ACCEPT: - ble_l2cap_get_chan_info(event->accept.chan, &chan_info); - if (chan_info.psm == 0x00F2) { - /* TSPX_psm_authentication_required */ - ble_gap_conn_find(event->accept.conn_handle, &conn); - if (!conn.sec_state.authenticated) { - return BLE_HS_EAUTHEN; - } - } else if (chan_info.psm == 0x00F3) { - /* TSPX_psm_authorization_required */ - ble_gap_conn_find(event->accept.conn_handle, &conn); - if (!conn.sec_state.encrypted) { - return BLE_HS_EAUTHOR; - } - return BLE_HS_EAUTHOR; - } else if (chan_info.psm == 0x00F4) { - /* TSPX_psm_encryption_key_size_required */ - ble_gap_conn_find(event->accept.conn_handle, &conn); - if (conn.sec_state.key_size < 16) { - return BLE_HS_EENCRYPT_KEY_SZ; - } - } - - accept_response = POINTER_TO_INT(arg); - if (accept_response) { - return accept_response; - } - - console_printf("LE CoC accept, chan: 0x%08lx, handle: %u, sdu_size: %u\n", - (uint32_t) event->accept.chan, - event->accept.conn_handle, - event->accept.peer_sdu_size); - - return accept_cb(event->accept.conn_handle, - event->accept.peer_sdu_size, - event->accept.chan); - - case BLE_L2CAP_EVENT_COC_DATA_RECEIVED: - console_printf("LE CoC data received, chan: 0x%08lx, handle: %u, sdu_len: %u\n", - (uint32_t) event->receive.chan, - event->receive.conn_handle, - OS_MBUF_PKTLEN(event->receive.sdu_rx)); - - recv_cb(event->receive.conn_handle, event->receive.chan, - event->receive.sdu_rx, arg); - return 0; - case BLE_L2CAP_EVENT_COC_TX_UNSTALLED: - console_printf("LE CoC tx unstalled, chan: 0x%08lx, handle: %u, status: %d\n", - (uint32_t) event->tx_unstalled.chan, - event->tx_unstalled.conn_handle, - event->tx_unstalled.status); - - unstalled_cb(event->tx_unstalled.conn_handle, - event->tx_unstalled.chan, - event->tx_unstalled.status, arg); - return 0; - case BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED: - if (ble_l2cap_get_chan_info(event->reconfigured.chan, - &chan_info)) { - assert(0); - } - console_printf("LE CoC reconfigure completed status 0x%02x, " - "chan: 0x%08lx\n", event->reconfigured.status, - (uint32_t) event->reconfigured.chan); - - if (event->reconfigured.status == 0) { - console_printf("\t our_mps: %d our_mtu %d\n", - chan_info.our_l2cap_mtu, chan_info.our_coc_mtu); - } - - reconfigured_ev(event->reconfigured.conn_handle, - event->reconfigured.chan, - &chan_info, - event->reconfigured.status); - return 0; - case BLE_L2CAP_EVENT_COC_PEER_RECONFIGURED: - if (ble_l2cap_get_chan_info(event->reconfigured.chan, - &chan_info)) { - assert(0); - } - console_printf("LE CoC peer reconfigured status 0x%02x, " - "chan: 0x%08lx\n", event->reconfigured.status, - (uint32_t) event->reconfigured.chan); - - if (event->reconfigured.status == 0) { - console_printf("\t peer_mps: %d peer_mtu %d\n", - chan_info.peer_l2cap_mtu, chan_info.peer_coc_mtu); - } - - reconfigured_ev(event->reconfigured.conn_handle, - event->reconfigured.chan, - &chan_info, - event->reconfigured.status); - return 0; - default: - return 0; - } + struct ble_l2cap_chan_info chan_info; + int accept_response; + struct ble_gap_conn_desc conn; + + switch (event->type) { + case BLE_L2CAP_EVENT_COC_CONNECTED: + if (ble_l2cap_get_chan_info(event->connect.chan, &chan_info)) { + assert(0); + } + + if (event->connect.status) { + console_printf("LE COC error: %d\n", event->connect.status); + return 0; + } + + console_printf("LE COC connected, conn: %d, chan: 0x%08lx, " + "psm: 0x%02x, scid: 0x%04x, dcid: 0x%04x, " + "our_mps: %d, our_mtu: %d, peer_mps: %d, " + "peer_mtu: %d\n", event->connect.conn_handle, + (uint32_t) event->connect.chan, chan_info.psm, + chan_info.scid, chan_info.dcid, + chan_info.our_l2cap_mtu, chan_info.our_coc_mtu, + chan_info.peer_l2cap_mtu, chan_info.peer_coc_mtu); + + connected_cb(event->connect.conn_handle, + event->connect.chan, &chan_info, arg); + + return 0; + case BLE_L2CAP_EVENT_COC_DISCONNECTED: + if (ble_l2cap_get_chan_info(event->disconnect.chan, + &chan_info)) { + assert(0); + } + console_printf("LE CoC disconnected, chan: 0x%08lx\n", + (uint32_t) event->disconnect.chan); + + disconnected_cb(event->disconnect.conn_handle, + event->disconnect.chan, &chan_info, arg); + return 0; + case BLE_L2CAP_EVENT_COC_ACCEPT: + ble_l2cap_get_chan_info(event->accept.chan, + &chan_info); + if (chan_info.psm == 0x00F2) { + /* TSPX_psm_authentication_required */ + ble_gap_conn_find(event->accept.conn_handle, &conn); + if (!conn.sec_state.authenticated) { + return BLE_HS_EAUTHEN; + } + } else if (chan_info.psm == 0x00F3) { + /* TSPX_psm_authorization_required */ + ble_gap_conn_find(event->accept.conn_handle, &conn); + if (!conn.sec_state.encrypted) { + return BLE_HS_EAUTHOR; + } + return BLE_HS_EAUTHOR; + } else if (chan_info.psm == 0x00F4) { + /* TSPX_psm_encryption_key_size_required */ + ble_gap_conn_find(event->accept.conn_handle, &conn); + if (conn.sec_state.key_size < 16) { + return BLE_HS_EENCRYPT_KEY_SZ; + } + } + + accept_response = POINTER_TO_INT(arg); + if (accept_response) { + return accept_response; + } + + console_printf( + "LE CoC accept, chan: 0x%08lx, handle: %u, sdu_size: %u\n", + (uint32_t) event->accept.chan, + event->accept.conn_handle, + event->accept.peer_sdu_size); + + return accept_cb(event->accept.conn_handle, + event->accept.peer_sdu_size, + event->accept.chan); + + case BLE_L2CAP_EVENT_COC_DATA_RECEIVED: + console_printf( + "LE CoC data received, chan: 0x%08lx, handle: %u, sdu_len: %u\n", + (uint32_t) event->receive.chan, + event->receive.conn_handle, + OS_MBUF_PKTLEN(event->receive.sdu_rx)); + + recv_cb(event->receive.conn_handle, event->receive.chan, + event->receive.sdu_rx, arg); + return 0; + case BLE_L2CAP_EVENT_COC_TX_UNSTALLED: + console_printf( + "LE CoC tx unstalled, chan: 0x%08lx, handle: %u, status: %d\n", + (uint32_t) event->tx_unstalled.chan, + event->tx_unstalled.conn_handle, + event->tx_unstalled.status); + + unstalled_cb(event->tx_unstalled.conn_handle, + event->tx_unstalled.chan, + event->tx_unstalled.status, arg); + return 0; + case BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED: + if (ble_l2cap_get_chan_info(event->reconfigured.chan, + &chan_info)) { + assert(0); + } + console_printf("LE CoC reconfigure completed status 0x%02x, " + "chan: 0x%08lx\n", event->reconfigured.status, + (uint32_t) event->reconfigured.chan); + + if (event->reconfigured.status == 0) { + console_printf("\t our_mps: %d our_mtu %d\n", + chan_info.our_l2cap_mtu, chan_info.our_coc_mtu); + } + + reconfigured_ev(event->reconfigured.conn_handle, + event->reconfigured.chan, + &chan_info, + event->reconfigured.status); + return 0; + case BLE_L2CAP_EVENT_COC_PEER_RECONFIGURED: + if (ble_l2cap_get_chan_info(event->reconfigured.chan, + &chan_info)) { + assert(0); + } + console_printf("LE CoC peer reconfigured status 0x%02x, " + "chan: 0x%08lx\n", event->reconfigured.status, + (uint32_t) event->reconfigured.chan); + + if (event->reconfigured.status == 0) { + console_printf("\t peer_mps: %d peer_mtu %d\n", + chan_info.peer_l2cap_mtu, + chan_info.peer_coc_mtu); + } + + reconfigured_ev(event->reconfigured.conn_handle, + event->reconfigured.chan, + &chan_info, + event->reconfigured.status); + return 0; + default: + return 0; + } } -static void connect(uint8_t *data, uint16_t len) +static void +connect(uint8_t *data, uint16_t len) { - const struct l2cap_connect_cmd *cmd = (void *) data; - uint8_t rp_buf[sizeof(struct l2cap_connect_rp) + cmd->num]; - struct l2cap_connect_rp *rp = (void *) rp_buf; - struct ble_gap_conn_desc desc; - struct channel *chan; - struct os_mbuf *sdu_rx[cmd->num]; - ble_addr_t *addr = (void *) data; - uint16_t mtu = htole16(cmd->mtu); - int rc; - int i, j; - bool ecfc = cmd->options & L2CAP_CONNECT_OPT_ECFC; - hold_credit = cmd->options & L2CAP_CONNECT_OPT_HOLD_CREDIT; - - SYS_LOG_DBG("connect: type: %d addr: %s", addr->type, bt_hex(addr->val, 6)); - - if (mtu == 0 || mtu > TESTER_COC_MTU) { - mtu = TESTER_COC_MTU; - } - - rc = ble_gap_conn_find_by_addr(addr, &desc); - if (rc) { - SYS_LOG_ERR("GAP conn find failed"); - goto fail; - } - - rp->num = cmd->num; - - for (i = 0; i < cmd->num; i++) { - chan = get_free_channel(); - if (!chan) { - SYS_LOG_ERR("No free channels"); - goto fail; - } - /* temporarily mark channel as used to select next one */ + const struct l2cap_connect_cmd *cmd = (void *) data; + uint8_t rp_buf[sizeof(struct l2cap_connect_rp) + cmd->num]; + struct l2cap_connect_rp *rp = (void *) rp_buf; + struct ble_gap_conn_desc desc; + struct channel *chan; + struct os_mbuf *sdu_rx[cmd->num]; + ble_addr_t *addr = (void *) data; + uint16_t mtu = htole16(cmd->mtu); + int rc; + int i, j; + bool ecfc = cmd->options & L2CAP_CONNECT_OPT_ECFC; + hold_credit = cmd->options & L2CAP_CONNECT_OPT_HOLD_CREDIT; + + SYS_LOG_DBG("connect: type: %d addr: %s", + addr->type, + bt_hex(addr->val, 6)); + + if (mtu == 0 || mtu > TESTER_COC_MTU) { + mtu = TESTER_COC_MTU; + } + + rc = ble_gap_conn_find_by_addr(addr, &desc); + if (rc) { + SYS_LOG_ERR("GAP conn find failed"); + goto fail; + } + + rp->num = cmd->num; + + for (i = 0; i < cmd->num; i++) { + chan = get_free_channel(); + if (!chan) { + SYS_LOG_ERR("No free channels"); + goto fail; + } + /* temporarily mark channel as used to select next one */ chan->state = 1; - rp->chan_ids[i] = chan->chan_id; - - sdu_rx[i] = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); - if (sdu_rx[i] == NULL) { - SYS_LOG_ERR("Failed to alloc buf"); - goto fail; - } - } - - /* mark selected channels as unused again */ - for (i = 0; i < cmd->num; i++) { - for (j = 0; j < CHANNELS; j++) { - if (rp->chan_ids[i] == channels[j].chan_id) { - channels[j].state = 0; - } - } - } - - if (cmd->num == 1 && !ecfc) { - rc = ble_l2cap_connect(desc.conn_handle, htole16(cmd->psm), - mtu, sdu_rx[0], - tester_l2cap_event, NULL); - } else if (ecfc) { - rc = ble_l2cap_enhanced_connect(desc.conn_handle, - htole16(cmd->psm), mtu, - cmd->num, sdu_rx, - tester_l2cap_event, NULL); - } else { - SYS_LOG_ERR("Invalid 'num' parameter value"); - goto fail; - } - - if (rc) { - SYS_LOG_ERR("L2CAP connect failed\n"); - goto fail; - } - - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_CONNECT, CONTROLLER_INDEX, - (uint8_t *) rp, sizeof(rp_buf)); - - return; + rp->chan_ids[i] = chan->chan_id; + + sdu_rx[i] = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); + if (sdu_rx[i] == NULL) { + SYS_LOG_ERR("Failed to alloc buf"); + goto fail; + } + } + + /* mark selected channels as unused again */ + for (i = 0; i < cmd->num; i++) { + for (j = 0; j < CHANNELS; j++) { + if (rp->chan_ids[i] == channels[j].chan_id) { + channels[j].state = 0; + } + } + } + + if (cmd->num == 1 && !ecfc) { + rc = ble_l2cap_connect(desc.conn_handle, htole16(cmd->psm), + mtu, sdu_rx[0], + tester_l2cap_event, NULL); + } else if (ecfc) { + rc = ble_l2cap_enhanced_connect(desc.conn_handle, + htole16(cmd->psm), mtu, + cmd->num, sdu_rx, + tester_l2cap_event, NULL); + } else { + SYS_LOG_ERR("Invalid 'num' parameter value"); + goto fail; + } + + if (rc) { + SYS_LOG_ERR("L2CAP connect failed\n"); + goto fail; + } + + tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_CONNECT, CONTROLLER_INDEX, + (uint8_t *) rp, sizeof(rp_buf)); + + return; fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_CONNECT, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_CONNECT, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static void disconnect(const uint8_t *data, uint16_t len) +static void +disconnect(const uint8_t *data, uint16_t len) { - const struct l2cap_disconnect_cmd *cmd = (void *) data; - struct channel *chan; - uint8_t status; - int err; + const struct l2cap_disconnect_cmd *cmd = (void *) data; + struct channel *chan; + uint8_t status; + int err; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - chan = get_channel(cmd->chan_id); - assert(chan != NULL); + chan = get_channel(cmd->chan_id); + assert(chan != NULL); - err = ble_l2cap_disconnect(chan->chan); - if (err) { - status = BTP_STATUS_FAILED; - goto rsp; - } + err = ble_l2cap_disconnect(chan->chan); + if (err) { + status = BTP_STATUS_FAILED; + goto rsp; + } - status = BTP_STATUS_SUCCESS; + status = BTP_STATUS_SUCCESS; rsp: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_DISCONNECT, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_DISCONNECT, CONTROLLER_INDEX, + status); } -static void send_data(const uint8_t *data, uint16_t len) +static void +send_data(const uint8_t *data, uint16_t len) { - const struct l2cap_send_data_cmd *cmd = (void *) data; - struct os_mbuf *sdu_tx = NULL; - int rc; - uint16_t data_len = sys_le16_to_cpu(cmd->data_len); - struct channel *chan = get_channel(cmd->chan_id); - - SYS_LOG_DBG("cmd->chan_id=%d", cmd->chan_id); - - if (!chan) { - SYS_LOG_ERR("Invalid channel\n"); - goto fail; - } - - /* FIXME: For now, fail if data length exceeds buffer length */ - if (data_len > TESTER_COC_MTU) { - SYS_LOG_ERR("Data length exceeds buffer length"); - goto fail; - } - - sdu_tx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); - if (sdu_tx == NULL) { - SYS_LOG_ERR("No memory in the test sdu pool\n"); - goto fail; - } - - os_mbuf_append(sdu_tx, cmd->data, data_len); - - /* ble_l2cap_send takes ownership of the sdu */ - rc = ble_l2cap_send(chan->chan, sdu_tx); - if (rc == 0 || rc == BLE_HS_ESTALLED) { - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); - return; - } - - SYS_LOG_ERR("Unable to send data: %d", rc); - os_mbuf_free_chain(sdu_tx); + const struct l2cap_send_data_cmd *cmd = (void *) data; + struct os_mbuf *sdu_tx = NULL; + int rc; + uint16_t data_len = sys_le16_to_cpu(cmd->data_len); + struct channel *chan = get_channel(cmd->chan_id); + + SYS_LOG_DBG("cmd->chan_id=%d", cmd->chan_id); + + if (!chan) { + SYS_LOG_ERR("Invalid channel\n"); + goto fail; + } + + /* FIXME: For now, fail if data length exceeds buffer length */ + if (data_len > TESTER_COC_MTU) { + SYS_LOG_ERR("Data length exceeds buffer length"); + goto fail; + } + + sdu_tx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); + if (sdu_tx == NULL) { + SYS_LOG_ERR("No memory in the test sdu pool\n"); + goto fail; + } + + os_mbuf_append(sdu_tx, cmd->data, data_len); + + /* ble_l2cap_send takes ownership of the sdu */ + rc = ble_l2cap_send(chan->chan, sdu_tx); + if (rc == 0 || rc == BLE_HS_ESTALLED) { + tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, CONTROLLER_INDEX, + BTP_STATUS_SUCCESS); + return; + } + + SYS_LOG_ERR("Unable to send data: %d", rc); + os_mbuf_free_chain(sdu_tx); fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } static int l2cap_coc_err2hs_err(uint16_t coc_err) { - switch (coc_err) { - case BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM: - return BLE_HS_ENOTSUP; - case BLE_L2CAP_COC_ERR_NO_RESOURCES: - return BLE_HS_ENOMEM; - case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN: - return BLE_HS_EAUTHEN; - case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR: - return BLE_HS_EAUTHOR; - case BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC: - return BLE_HS_EENCRYPT; - case BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ: - return BLE_HS_EENCRYPT_KEY_SZ; - case BLE_L2CAP_COC_ERR_UNACCEPTABLE_PARAMETERS: - return BLE_HS_EINVAL; - default: - return 0; - } + switch (coc_err) { + case BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM: + return BLE_HS_ENOTSUP; + case BLE_L2CAP_COC_ERR_NO_RESOURCES: + return BLE_HS_ENOMEM; + case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN: + return BLE_HS_EAUTHEN; + case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR: + return BLE_HS_EAUTHOR; + case BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC: + return BLE_HS_EENCRYPT; + case BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ: + return BLE_HS_EENCRYPT_KEY_SZ; + case BLE_L2CAP_COC_ERR_UNACCEPTABLE_PARAMETERS: + return BLE_HS_EINVAL; + default: + return 0; + } } static int l2cap_btp_listen_err2coc_err(uint16_t coc_err) { switch (coc_err) { - case 0x01: - return BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN; - case 0x02: - return BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR; - case 0x03: - return BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ; - case 0x04: - return BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC; - default: - return 0; + case 0x01: + return BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN; + case 0x02: + return BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR; + case 0x03: + return BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ; + case 0x04: + return BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC; + default: + return 0; } } -static void listen(const uint8_t *data, uint16_t len) +static void +listen(const uint8_t *data, uint16_t len) { - const struct l2cap_listen_cmd *cmd = (void *) data; - uint16_t mtu = htole16(cmd->mtu); - uint16_t rsp = htole16(cmd->response); - int rc; + const struct l2cap_listen_cmd *cmd = (void *) data; + uint16_t mtu = htole16(cmd->mtu); + uint16_t rsp = htole16(cmd->response); + int rc; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - if (mtu == 0 || mtu > TESTER_COC_MTU) { - mtu = TESTER_COC_MTU; - } + if (mtu == 0 || mtu > TESTER_COC_MTU) { + mtu = TESTER_COC_MTU; + } - rsp = l2cap_btp_listen_err2coc_err(rsp); - rsp = l2cap_coc_err2hs_err(rsp); + rsp = l2cap_btp_listen_err2coc_err(rsp); + rsp = l2cap_coc_err2hs_err(rsp); - /* TODO: Handle cmd->transport flag */ - rc = ble_l2cap_create_server(cmd->psm, mtu, tester_l2cap_event, - INT_TO_POINTER(rsp)); - if (rc) { - goto fail; - } + /* TODO: Handle cmd->transport flag */ + rc = ble_l2cap_create_server(cmd->psm, mtu, tester_l2cap_event, + INT_TO_POINTER(rsp)); + if (rc) { + goto fail; + } - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_LISTEN, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); - return; + tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_LISTEN, CONTROLLER_INDEX, + BTP_STATUS_SUCCESS); + return; fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_LISTEN, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_LISTEN, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static void credits(uint8_t *data, uint16_t len) +static void +credits(uint8_t *data, uint16_t len) { - const struct l2cap_credits_cmd *cmd = (void *)data; + const struct l2cap_credits_cmd *cmd = (void *) data; struct os_mbuf *sdu; int rc; @@ -645,121 +666,126 @@ static void credits(uint8_t *data, uint16_t len) BTP_STATUS_FAILED); } -static void reconfigure(const uint8_t *data, uint16_t len) +static void +reconfigure(const uint8_t *data, uint16_t len) { - const struct l2cap_reconfigure_cmd *cmd = (void *) data; - uint16_t mtu = htole16(cmd->mtu); - struct ble_gap_conn_desc desc; - ble_addr_t *addr = (void *) data; - struct ble_l2cap_chan *chans[cmd->num]; - struct channel *channel; - int rc; - int i; - - SYS_LOG_DBG(""); - - if (mtu == 0 || mtu > TESTER_COC_MTU) { - mtu = TESTER_COC_MTU; - } - - rc = ble_gap_conn_find_by_addr(addr, &desc); - if (rc) { - SYS_LOG_ERR("GAP conn find failed"); - goto fail; - } - - for (i = 0; i < cmd->num; ++i) { - channel = get_channel(cmd->idxs[i]); - if (channel == NULL) { - goto fail; - } - chans[i] = channel->chan; - } - - rc = ble_l2cap_reconfig(chans, cmd->num, mtu); - if (rc) { - goto fail; - } - - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_RECONFIGURE, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); - return; + const struct l2cap_reconfigure_cmd *cmd = (void *) data; + uint16_t mtu = htole16(cmd->mtu); + struct ble_gap_conn_desc desc; + ble_addr_t *addr = (void *) data; + struct ble_l2cap_chan *chans[cmd->num]; + struct channel *channel; + int rc; + int i; + + SYS_LOG_DBG(""); + + if (mtu == 0 || mtu > TESTER_COC_MTU) { + mtu = TESTER_COC_MTU; + } + + rc = ble_gap_conn_find_by_addr(addr, &desc); + if (rc) { + SYS_LOG_ERR("GAP conn find failed"); + goto fail; + } + + for (i = 0; i < cmd->num; ++i) { + channel = get_channel(cmd->idxs[i]); + if (channel == NULL) { + goto fail; + } + chans[i] = channel->chan; + } + + rc = ble_l2cap_reconfig(chans, cmd->num, mtu); + if (rc) { + goto fail; + } + + tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_RECONFIGURE, CONTROLLER_INDEX, + BTP_STATUS_SUCCESS); + return; fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_RECONFIGURE, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_RECONFIGURE, CONTROLLER_INDEX, + BTP_STATUS_FAILED); } -static void supported_commands(uint8_t *data, uint16_t len) +static void +supported_commands(uint8_t *data, uint16_t len) { - uint8_t cmds[1]; - struct l2cap_read_supported_commands_rp *rp = (void *) cmds; + uint8_t cmds[1]; + struct l2cap_read_supported_commands_rp *rp = (void *) cmds; - memset(cmds, 0, sizeof(cmds)); + memset(cmds, 0, sizeof(cmds)); - tester_set_bit(cmds, L2CAP_READ_SUPPORTED_COMMANDS); - tester_set_bit(cmds, L2CAP_CONNECT); - tester_set_bit(cmds, L2CAP_DISCONNECT); - tester_set_bit(cmds, L2CAP_LISTEN); - tester_set_bit(cmds, L2CAP_SEND_DATA); - tester_set_bit(cmds, L2CAP_RECONFIGURE); + tester_set_bit(cmds, L2CAP_READ_SUPPORTED_COMMANDS); + tester_set_bit(cmds, L2CAP_CONNECT); + tester_set_bit(cmds, L2CAP_DISCONNECT); + tester_set_bit(cmds, L2CAP_LISTEN); + tester_set_bit(cmds, L2CAP_SEND_DATA); + tester_set_bit(cmds, L2CAP_RECONFIGURE); - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_READ_SUPPORTED_COMMANDS, - CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); + tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_READ_SUPPORTED_COMMANDS, + CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); } -void tester_handle_l2cap(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len) +void +tester_handle_l2cap(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len) { - switch (opcode) { - case L2CAP_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - return; - case L2CAP_CONNECT: - connect(data, len); - return; - case L2CAP_DISCONNECT: - disconnect(data, len); - return; - case L2CAP_SEND_DATA: - send_data(data, len); - return; - case L2CAP_LISTEN: - listen(data, len); - return; - case L2CAP_RECONFIGURE: - reconfigure(data, len); - return; - case L2CAP_CREDITS: - credits(data, len); - return; - default: - tester_rsp(BTP_SERVICE_ID_L2CAP, opcode, index, - BTP_STATUS_UNKNOWN_CMD); - return; - } + switch (opcode) { + case L2CAP_READ_SUPPORTED_COMMANDS: + supported_commands(data, len); + return; + case L2CAP_CONNECT: + connect(data, len); + return; + case L2CAP_DISCONNECT: + disconnect(data, len); + return; + case L2CAP_SEND_DATA: + send_data(data, len); + return; + case L2CAP_LISTEN: + listen(data, len); + return; + case L2CAP_RECONFIGURE: + reconfigure(data, len); + return; + case L2CAP_CREDITS: + credits(data, len); + return; + default: + tester_rsp(BTP_SERVICE_ID_L2CAP, opcode, index, + BTP_STATUS_UNKNOWN_CMD); + return; + } } -uint8_t tester_init_l2cap(void) +uint8_t +tester_init_l2cap(void) { - int rc; + int rc; - /* For testing we want to support all the available channels */ - rc = os_mempool_init(&sdu_coc_mbuf_mempool, TESTER_COC_BUF_COUNT, - TESTER_COC_MTU, tester_sdu_coc_mem, - "tester_coc_sdu_pool"); - assert(rc == 0); + /* For testing we want to support all the available channels */ + rc = os_mempool_init(&sdu_coc_mbuf_mempool, TESTER_COC_BUF_COUNT, + TESTER_COC_MTU, tester_sdu_coc_mem, + "tester_coc_sdu_pool"); + assert(rc == 0); - rc = os_mbuf_pool_init(&sdu_os_mbuf_pool, &sdu_coc_mbuf_mempool, - TESTER_COC_MTU, TESTER_COC_BUF_COUNT); - assert(rc == 0); + rc = os_mbuf_pool_init(&sdu_os_mbuf_pool, &sdu_coc_mbuf_mempool, + TESTER_COC_MTU, TESTER_COC_BUF_COUNT); + assert(rc == 0); - return BTP_STATUS_SUCCESS; + return BTP_STATUS_SUCCESS; } -uint8_t tester_unregister_l2cap(void) +uint8_t +tester_unregister_l2cap(void) { - return BTP_STATUS_SUCCESS; + return BTP_STATUS_SUCCESS; } #endif diff --git a/apps/bttester/src/main.c b/apps/bttester/src/main.c index ea130805c9..8cc48661ae 100644 --- a/apps/bttester/src/main.c +++ b/apps/bttester/src/main.c @@ -33,40 +33,43 @@ #include "bttester.h" -static void on_reset(int reason) +static void +on_reset(int reason) { - MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason); + MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason); } -static void on_sync(void) +static void +on_sync(void) { - MODLOG_DFLT(INFO, "Bluetooth initialized\n"); + MODLOG_DFLT(INFO, "Bluetooth initialized\n"); - tester_init(); + tester_init(); } -int main(int argc, char **argv) +int +main(int argc, char **argv) { - int rc; + int rc; #ifdef ARCH_sim - mcu_sim_parse_args(argc, argv); + mcu_sim_parse_args(argc, argv); #endif - /* Initialize OS */ - sysinit(); + /* Initialize OS */ + sysinit(); - /* Initialize the NimBLE host configuration. */ - ble_hs_cfg.reset_cb = on_reset; - ble_hs_cfg.sync_cb = on_sync; - ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb, - ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + /* Initialize the NimBLE host configuration. */ + ble_hs_cfg.reset_cb = on_reset; + ble_hs_cfg.sync_cb = on_sync; + ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb, + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; - rc = gatt_svr_init(); - assert(rc == 0); + rc = gatt_svr_init(); + assert(rc == 0); - while (1) { - os_eventq_run(os_eventq_dflt_get()); - } - return 0; + while (1) { + os_eventq_run(os_eventq_dflt_get()); + } + return 0; } diff --git a/apps/bttester/src/mesh.c b/apps/bttester/src/mesh.c index 46bf7699c3..26093f755d 100644 --- a/apps/bttester/src/mesh.c +++ b/apps/bttester/src/mesh.c @@ -70,132 +70,138 @@ static uint8_t static_auth[16]; #define MODEL_BOUNDS_MAX 2 static struct model_data { - struct bt_mesh_model *model; - uint16_t addr; - uint16_t appkey_idx; + struct bt_mesh_model *model; + uint16_t addr; + uint16_t appkey_idx; } model_bound[MODEL_BOUNDS_MAX]; static struct { - uint16_t local; - uint16_t dst; - uint16_t net_idx; + uint16_t local; + uint16_t dst; + uint16_t net_idx; } net = { - .local = BT_MESH_ADDR_UNASSIGNED, - .dst = BT_MESH_ADDR_UNASSIGNED, + .local = BT_MESH_ADDR_UNASSIGNED, + .dst = BT_MESH_ADDR_UNASSIGNED, }; -static void supported_commands(uint8_t *data, uint16_t len) -{ - struct os_mbuf *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE); - - net_buf_simple_init(buf, 0); - - /* 1st octet */ - memset(net_buf_simple_add(buf, 1), 0, 1); - tester_set_bit(buf->om_data, MESH_READ_SUPPORTED_COMMANDS); - tester_set_bit(buf->om_data, MESH_CONFIG_PROVISIONING); - tester_set_bit(buf->om_data, MESH_PROVISION_NODE); - tester_set_bit(buf->om_data, MESH_INIT); - tester_set_bit(buf->om_data, MESH_RESET); - tester_set_bit(buf->om_data, MESH_INPUT_NUMBER); - tester_set_bit(buf->om_data, MESH_INPUT_STRING); - /* 2nd octet */ - tester_set_bit(buf->om_data, MESH_IVU_TEST_MODE); - tester_set_bit(buf->om_data, MESH_IVU_TOGGLE_STATE); - tester_set_bit(buf->om_data, MESH_NET_SEND); - tester_set_bit(buf->om_data, MESH_HEALTH_GENERATE_FAULTS); - tester_set_bit(buf->om_data, MESH_HEALTH_CLEAR_FAULTS); - tester_set_bit(buf->om_data, MESH_LPN); - tester_set_bit(buf->om_data, MESH_LPN_POLL); - tester_set_bit(buf->om_data, MESH_MODEL_SEND); - /* 3rd octet */ - memset(net_buf_simple_add(buf, 1), 0, 1); +static void +supported_commands(uint8_t *data, uint16_t len) +{ + struct os_mbuf *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE); + + net_buf_simple_init(buf, 0); + + /* 1st octet */ + memset(net_buf_simple_add(buf, 1), 0, 1); + tester_set_bit(buf->om_data, MESH_READ_SUPPORTED_COMMANDS); + tester_set_bit(buf->om_data, MESH_CONFIG_PROVISIONING); + tester_set_bit(buf->om_data, MESH_PROVISION_NODE); + tester_set_bit(buf->om_data, MESH_INIT); + tester_set_bit(buf->om_data, MESH_RESET); + tester_set_bit(buf->om_data, MESH_INPUT_NUMBER); + tester_set_bit(buf->om_data, MESH_INPUT_STRING); + /* 2nd octet */ + tester_set_bit(buf->om_data, MESH_IVU_TEST_MODE); + tester_set_bit(buf->om_data, MESH_IVU_TOGGLE_STATE); + tester_set_bit(buf->om_data, MESH_NET_SEND); + tester_set_bit(buf->om_data, MESH_HEALTH_GENERATE_FAULTS); + tester_set_bit(buf->om_data, MESH_HEALTH_CLEAR_FAULTS); + tester_set_bit(buf->om_data, MESH_LPN); + tester_set_bit(buf->om_data, MESH_LPN_POLL); + tester_set_bit(buf->om_data, MESH_MODEL_SEND); + /* 3rd octet */ + memset(net_buf_simple_add(buf, 1), 0, 1); #if MYNEWT_VAL(BLE_MESH_TESTING) - tester_set_bit(buf->om_data, MESH_LPN_SUBSCRIBE); - tester_set_bit(buf->om_data, MESH_LPN_UNSUBSCRIBE); - tester_set_bit(buf->om_data, MESH_RPL_CLEAR); + tester_set_bit(buf->om_data, MESH_LPN_SUBSCRIBE); + tester_set_bit(buf->om_data, MESH_LPN_UNSUBSCRIBE); + tester_set_bit(buf->om_data, MESH_RPL_CLEAR); #endif /* CONFIG_BT_TESTING */ - tester_set_bit(buf->om_data, MESH_PROXY_IDENTITY); + tester_set_bit(buf->om_data, MESH_PROXY_IDENTITY); - tester_send_buf(BTP_SERVICE_ID_MESH, MESH_READ_SUPPORTED_COMMANDS, - CONTROLLER_INDEX, buf); + tester_send_buf(BTP_SERVICE_ID_MESH, MESH_READ_SUPPORTED_COMMANDS, + CONTROLLER_INDEX, buf); } -static void get_faults(uint8_t *faults, uint8_t faults_size, uint8_t *dst, uint8_t *count) +static void +get_faults(uint8_t *faults, uint8_t faults_size, uint8_t *dst, uint8_t *count) { - uint8_t i, limit = *count; - - for (i = 0, *count = 0; i < faults_size && *count < limit; i++) { - if (faults[i]) { - *dst++ = faults[i]; - (*count)++; - } - } + uint8_t i, limit = *count; + + for (i = 0, *count = 0; i < faults_size && *count < limit; i++) { + if (faults[i]) { + *dst++ = faults[i]; + (*count)++; + } + } } -static int fault_get_cur(struct bt_mesh_model *model, uint8_t *test_id, - uint16_t *company_id, uint8_t *faults, uint8_t *fault_count) +static int +fault_get_cur(struct bt_mesh_model *model, uint8_t *test_id, + uint16_t *company_id, uint8_t *faults, uint8_t *fault_count) { - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - *test_id = HEALTH_TEST_ID; - *company_id = CID_LOCAL; + *test_id = HEALTH_TEST_ID; + *company_id = CID_LOCAL; - get_faults(cur_faults, sizeof(cur_faults), faults, fault_count); + get_faults(cur_faults, sizeof(cur_faults), faults, fault_count); - return 0; + return 0; } -static int fault_get_reg(struct bt_mesh_model *model, uint16_t company_id, - uint8_t *test_id, uint8_t *faults, uint8_t *fault_count) +static int +fault_get_reg(struct bt_mesh_model *model, uint16_t company_id, + uint8_t *test_id, uint8_t *faults, uint8_t *fault_count) { - SYS_LOG_DBG("company_id 0x%04x", company_id); + SYS_LOG_DBG("company_id 0x%04x", company_id); - if (company_id != CID_LOCAL) { - return -EINVAL; - } + if (company_id != CID_LOCAL) { + return -EINVAL; + } - *test_id = HEALTH_TEST_ID; + *test_id = HEALTH_TEST_ID; - get_faults(reg_faults, sizeof(reg_faults), faults, fault_count); + get_faults(reg_faults, sizeof(reg_faults), faults, fault_count); - return 0; + return 0; } -static int fault_clear(struct bt_mesh_model *model, uint16_t company_id) +static int +fault_clear(struct bt_mesh_model *model, uint16_t company_id) { - SYS_LOG_DBG("company_id 0x%04x", company_id); + SYS_LOG_DBG("company_id 0x%04x", company_id); - if (company_id != CID_LOCAL) { - return -EINVAL; - } + if (company_id != CID_LOCAL) { + return -EINVAL; + } - memset(reg_faults, 0, sizeof(reg_faults)); + memset(reg_faults, 0, sizeof(reg_faults)); - return 0; + return 0; } -static int fault_test(struct bt_mesh_model *model, uint8_t test_id, - uint16_t company_id) +static int +fault_test(struct bt_mesh_model *model, uint8_t test_id, + uint16_t company_id) { - SYS_LOG_DBG("test_id 0x%02x company_id 0x%04x", test_id, company_id); + SYS_LOG_DBG("test_id 0x%02x company_id 0x%04x", test_id, company_id); - if (company_id != CID_LOCAL || test_id != HEALTH_TEST_ID) { - return -EINVAL; - } + if (company_id != CID_LOCAL || test_id != HEALTH_TEST_ID) { + return -EINVAL; + } - return 0; + return 0; } static const struct bt_mesh_health_srv_cb health_srv_cb = { - .fault_get_cur = fault_get_cur, - .fault_get_reg = fault_get_reg, - .fault_clear = fault_clear, - .fault_test = fault_test, + .fault_get_cur = fault_get_cur, + .fault_get_reg = fault_get_reg, + .fault_clear = fault_clear, + .fault_test = fault_test, }; static struct bt_mesh_health_srv health_srv = { - .cb = &health_srv_cb, + .cb = &health_srv_cb, }; static struct bt_mesh_model_pub health_pub; @@ -203,791 +209,836 @@ static struct bt_mesh_model_pub health_pub; static void health_pub_init(void) { - health_pub.msg = BT_MESH_HEALTH_FAULT_MSG(CUR_FAULTS_MAX); + health_pub.msg = BT_MESH_HEALTH_FAULT_MSG(CUR_FAULTS_MAX); } static struct bt_mesh_cfg_cli cfg_cli = { }; -void show_faults(uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count) +void +show_faults(uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count) { - size_t i; + size_t i; - if (!fault_count) { - SYS_LOG_DBG("Health Test ID 0x%02x Company ID 0x%04x: " - "no faults", test_id, cid); - return; - } + if (!fault_count) { + SYS_LOG_DBG("Health Test ID 0x%02x Company ID 0x%04x: " + "no faults", test_id, cid); + return; + } - SYS_LOG_DBG("Health Test ID 0x%02x Company ID 0x%04x Fault Count %zu: ", - test_id, cid, fault_count); + SYS_LOG_DBG("Health Test ID 0x%02x Company ID 0x%04x Fault Count %zu: ", + test_id, cid, fault_count); - for (i = 0; i < fault_count; i++) { - SYS_LOG_DBG("0x%02x", faults[i]); - } + for (i = 0; i < fault_count; i++) { + SYS_LOG_DBG("0x%02x", faults[i]); + } } -static void health_current_status(struct bt_mesh_health_cli *cli, uint16_t addr, - uint8_t test_id, uint16_t cid, uint8_t *faults, - size_t fault_count) +static void +health_current_status(struct bt_mesh_health_cli *cli, uint16_t addr, + uint8_t test_id, uint16_t cid, uint8_t *faults, + size_t fault_count) { - SYS_LOG_DBG("Health Current Status from 0x%04x", addr); - show_faults(test_id, cid, faults, fault_count); + SYS_LOG_DBG("Health Current Status from 0x%04x", addr); + show_faults(test_id, cid, faults, fault_count); } static struct bt_mesh_health_cli health_cli = { - .current_status = health_current_status, + .current_status = health_current_status, }; static struct bt_mesh_model root_models[] = { - BT_MESH_MODEL_CFG_SRV, - BT_MESH_MODEL_CFG_CLI(&cfg_cli), - BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), - BT_MESH_MODEL_HEALTH_CLI(&health_cli), + BT_MESH_MODEL_CFG_SRV, + BT_MESH_MODEL_CFG_CLI(&cfg_cli), + BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), + BT_MESH_MODEL_HEALTH_CLI(&health_cli), }; static struct bt_mesh_model vnd_models[] = { - BT_MESH_MODEL_VND(CID_LOCAL, VND_MODEL_ID_1, BT_MESH_MODEL_NO_OPS, NULL, - NULL), + BT_MESH_MODEL_VND(CID_LOCAL, VND_MODEL_ID_1, BT_MESH_MODEL_NO_OPS, NULL, + NULL), }; static struct bt_mesh_elem elements[] = { - BT_MESH_ELEM(0, root_models, vnd_models), + BT_MESH_ELEM(0, root_models, vnd_models), }; -static void link_open(bt_mesh_prov_bearer_t bearer) +static void +link_open(bt_mesh_prov_bearer_t bearer) { - struct mesh_prov_link_open_ev ev; + struct mesh_prov_link_open_ev ev; - SYS_LOG_DBG("bearer 0x%02x", bearer); + SYS_LOG_DBG("bearer 0x%02x", bearer); - switch (bearer) { - case BT_MESH_PROV_ADV: - ev.bearer = MESH_PROV_BEARER_PB_ADV; - break; - case BT_MESH_PROV_GATT: - ev.bearer = MESH_PROV_BEARER_PB_GATT; - break; - default: - SYS_LOG_ERR("Invalid bearer"); + switch (bearer) { + case BT_MESH_PROV_ADV: + ev.bearer = MESH_PROV_BEARER_PB_ADV; + break; + case BT_MESH_PROV_GATT: + ev.bearer = MESH_PROV_BEARER_PB_GATT; + break; + default: + SYS_LOG_ERR("Invalid bearer"); - return; - } + return; + } - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROV_LINK_OPEN, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROV_LINK_OPEN, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } -static void link_close(bt_mesh_prov_bearer_t bearer) +static void +link_close(bt_mesh_prov_bearer_t bearer) { - struct mesh_prov_link_closed_ev ev; + struct mesh_prov_link_closed_ev ev; - SYS_LOG_DBG("bearer 0x%02x", bearer); + SYS_LOG_DBG("bearer 0x%02x", bearer); - switch (bearer) { - case BT_MESH_PROV_ADV: - ev.bearer = MESH_PROV_BEARER_PB_ADV; - break; - case BT_MESH_PROV_GATT: - ev.bearer = MESH_PROV_BEARER_PB_GATT; - break; - default: - SYS_LOG_ERR("Invalid bearer"); + switch (bearer) { + case BT_MESH_PROV_ADV: + ev.bearer = MESH_PROV_BEARER_PB_ADV; + break; + case BT_MESH_PROV_GATT: + ev.bearer = MESH_PROV_BEARER_PB_GATT; + break; + default: + SYS_LOG_ERR("Invalid bearer"); - return; - } + return; + } - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROV_LINK_CLOSED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROV_LINK_CLOSED, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } -static int output_number(bt_mesh_output_action_t action, uint32_t number) +static int +output_number(bt_mesh_output_action_t action, uint32_t number) { - struct mesh_out_number_action_ev ev; + struct mesh_out_number_action_ev ev; - SYS_LOG_DBG("action 0x%04x number 0x%08lx", action, number); + SYS_LOG_DBG("action 0x%04x number 0x%08lx", action, number); - ev.action = sys_cpu_to_le16(action); - ev.number = sys_cpu_to_le32(number); + ev.action = sys_cpu_to_le16(action); + ev.number = sys_cpu_to_le32(number); - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_OUT_NUMBER_ACTION, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_MESH, MESH_EV_OUT_NUMBER_ACTION, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); - return 0; + return 0; } -static int output_string(const char *str) +static int +output_string(const char *str) { - struct mesh_out_string_action_ev *ev; - struct os_mbuf *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE); + struct mesh_out_string_action_ev *ev; + struct os_mbuf *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE); - SYS_LOG_DBG("str %s", str); + SYS_LOG_DBG("str %s", str); - net_buf_simple_init(buf, 0); + net_buf_simple_init(buf, 0); - ev = net_buf_simple_add(buf, sizeof(*ev)); - ev->string_len = strlen(str); + ev = net_buf_simple_add(buf, sizeof(*ev)); + ev->string_len = strlen(str); - net_buf_simple_add_mem(buf, str, ev->string_len); + net_buf_simple_add_mem(buf, str, ev->string_len); - tester_send_buf(BTP_SERVICE_ID_MESH, MESH_EV_OUT_STRING_ACTION, - CONTROLLER_INDEX, buf); + tester_send_buf(BTP_SERVICE_ID_MESH, MESH_EV_OUT_STRING_ACTION, + CONTROLLER_INDEX, buf); - os_mbuf_free_chain(buf); - return 0; + os_mbuf_free_chain(buf); + return 0; } -static int input(bt_mesh_input_action_t action, uint8_t size) +static int +input(bt_mesh_input_action_t action, uint8_t size) { - struct mesh_in_action_ev ev; + struct mesh_in_action_ev ev; - SYS_LOG_DBG("action 0x%04x number 0x%02x", action, size); + SYS_LOG_DBG("action 0x%04x number 0x%02x", action, size); - input_size = size; + input_size = size; - ev.action = sys_cpu_to_le16(action); - ev.size = size; + ev.action = sys_cpu_to_le16(action); + ev.size = size; - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_IN_ACTION, CONTROLLER_INDEX, - (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_MESH, MESH_EV_IN_ACTION, CONTROLLER_INDEX, + (uint8_t *) &ev, sizeof(ev)); - return 0; + return 0; } static uint8_t vnd_app_key[16]; static uint16_t vnd_app_key_idx = 0x000f; -static void prov_complete(uint16_t net_idx, uint16_t addr) +static void +prov_complete(uint16_t net_idx, uint16_t addr) { - SYS_LOG_DBG("net_idx 0x%04x addr 0x%04x", net_idx, addr); + SYS_LOG_DBG("net_idx 0x%04x addr 0x%04x", net_idx, addr); - net.net_idx = net_idx, - net.local = addr; - net.dst = addr; + net.net_idx = net_idx, + net.local = addr; + net.dst = addr; - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROVISIONED, CONTROLLER_INDEX, - NULL, 0); + tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROVISIONED, CONTROLLER_INDEX, + NULL, 0); } -static void prov_reset(void) +static void +prov_reset(void) { - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); + bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); } static const struct bt_mesh_comp comp = { - .cid = CID_LOCAL, - .elem = elements, - .elem_count = ARRAY_SIZE(elements), + .cid = CID_LOCAL, + .elem = elements, + .elem_count = ARRAY_SIZE(elements), }; static struct bt_mesh_prov prov = { - .uuid = dev_uuid, - .static_val = static_auth, - .static_val_len = sizeof(static_auth), - .output_number = output_number, - .output_string = output_string, - .input = input, - .link_open = link_open, - .link_close = link_close, - .complete = prov_complete, - .reset = prov_reset, + .uuid = dev_uuid, + .static_val = static_auth, + .static_val_len = sizeof(static_auth), + .output_number = output_number, + .output_string = output_string, + .input = input, + .link_open = link_open, + .link_close = link_close, + .complete = prov_complete, + .reset = prov_reset, }; -static void config_prov(uint8_t *data, uint16_t len) +static void +config_prov(uint8_t *data, uint16_t len) { - const struct mesh_config_provisioning_cmd *cmd = (void *) data; + const struct mesh_config_provisioning_cmd *cmd = (void *) data; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - memcpy(dev_uuid, cmd->uuid, sizeof(dev_uuid)); - memcpy(static_auth, cmd->static_auth, sizeof(static_auth)); + memcpy(dev_uuid, cmd->uuid, sizeof(dev_uuid)); + memcpy(static_auth, cmd->static_auth, sizeof(static_auth)); - prov.output_size = cmd->out_size; - prov.output_actions = sys_le16_to_cpu(cmd->out_actions); - prov.input_size = cmd->in_size; - prov.input_actions = sys_le16_to_cpu(cmd->in_actions); + prov.output_size = cmd->out_size; + prov.output_actions = sys_le16_to_cpu(cmd->out_actions); + prov.input_size = cmd->in_size; + prov.input_actions = sys_le16_to_cpu(cmd->in_actions); - tester_rsp(BTP_SERVICE_ID_MESH, MESH_CONFIG_PROVISIONING, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_MESH, MESH_CONFIG_PROVISIONING, + CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } -static void provision_node(uint8_t *data, uint16_t len) +static void +provision_node(uint8_t *data, uint16_t len) { - const struct mesh_provision_node_cmd *cmd = (void *) data; + const struct mesh_provision_node_cmd *cmd = (void *) data; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - memcpy(dev_key, cmd->dev_key, sizeof(dev_key)); - memcpy(net_key, cmd->net_key, sizeof(net_key)); + memcpy(dev_key, cmd->dev_key, sizeof(dev_key)); + memcpy(net_key, cmd->net_key, sizeof(net_key)); - addr = sys_le16_to_cpu(cmd->addr); - flags = cmd->flags; - iv_index = sys_le32_to_cpu(cmd->iv_index); - net_key_idx = sys_le16_to_cpu(cmd->net_key_idx); + addr = sys_le16_to_cpu(cmd->addr); + flags = cmd->flags; + iv_index = sys_le32_to_cpu(cmd->iv_index); + net_key_idx = sys_le16_to_cpu(cmd->net_key_idx); - tester_rsp(BTP_SERVICE_ID_MESH, MESH_PROVISION_NODE, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_MESH, MESH_PROVISION_NODE, + CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } -static void init(uint8_t *data, uint16_t len) +static void +init(uint8_t *data, uint16_t len) { - uint8_t status = BTP_STATUS_SUCCESS; - int err; - - SYS_LOG_DBG(""); - - err = bt_mesh_init(own_addr_type, &prov, &comp); - if (err) { - status = BTP_STATUS_FAILED; - - goto rsp; - } - - if (addr) { - err = bt_mesh_provision(net_key, net_key_idx, flags, iv_index, - addr, dev_key); - if (err) { - status = BTP_STATUS_FAILED; - } - } else { - err = bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); - if (err) { - status = BTP_STATUS_FAILED; - } - } + uint8_t status = BTP_STATUS_SUCCESS; + int err; + + SYS_LOG_DBG(""); + + err = bt_mesh_init(own_addr_type, &prov, &comp); + if (err) { + status = BTP_STATUS_FAILED; + + goto rsp; + } + + if (addr) { + err = bt_mesh_provision(net_key, net_key_idx, flags, iv_index, + addr, dev_key); + if (err) { + status = BTP_STATUS_FAILED; + } + } else { + err = bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); + if (err) { + status = BTP_STATUS_FAILED; + } + } rsp: - tester_rsp(BTP_SERVICE_ID_MESH, MESH_INIT, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_MESH, MESH_INIT, CONTROLLER_INDEX, + status); } -static void reset(uint8_t *data, uint16_t len) +static void +reset(uint8_t *data, uint16_t len) { - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - bt_mesh_reset(); + bt_mesh_reset(); - tester_rsp(BTP_SERVICE_ID_MESH, MESH_RESET, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_MESH, MESH_RESET, CONTROLLER_INDEX, + BTP_STATUS_SUCCESS); } -static void input_number(uint8_t *data, uint16_t len) +static void +input_number(uint8_t *data, uint16_t len) { - const struct mesh_input_number_cmd *cmd = (void *) data; - uint8_t status = BTP_STATUS_SUCCESS; - uint32_t number; - int err; + const struct mesh_input_number_cmd *cmd = (void *) data; + uint8_t status = BTP_STATUS_SUCCESS; + uint32_t number; + int err; - number = sys_le32_to_cpu(cmd->number); + number = sys_le32_to_cpu(cmd->number); - SYS_LOG_DBG("number 0x%04lx", number); + SYS_LOG_DBG("number 0x%04lx", number); - err = bt_mesh_input_number(number); - if (err) { - status = BTP_STATUS_FAILED; - } + err = bt_mesh_input_number(number); + if (err) { + status = BTP_STATUS_FAILED; + } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_INPUT_NUMBER, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_MESH, MESH_INPUT_NUMBER, CONTROLLER_INDEX, + status); } -static void input_string(uint8_t *data, uint16_t len) +static void +input_string(uint8_t *data, uint16_t len) { - const struct mesh_input_string_cmd *cmd = (void *) data; - uint8_t status = BTP_STATUS_SUCCESS; - uint8_t str_auth[16]; - int err; - - SYS_LOG_DBG(""); - - if (cmd->string_len > sizeof(str_auth)) { - SYS_LOG_ERR("Too long input (%u chars required)", input_size); - status = BTP_STATUS_FAILED; - goto rsp; - } else if (cmd->string_len < input_size) { - SYS_LOG_ERR("Too short input (%u chars required)", input_size); - status = BTP_STATUS_FAILED; - goto rsp; - } - - strncpy((char *)str_auth, (char *)cmd->string, cmd->string_len); - - err = bt_mesh_input_string((char *)str_auth); - if (err) { - status = BTP_STATUS_FAILED; - } + const struct mesh_input_string_cmd *cmd = (void *) data; + uint8_t status = BTP_STATUS_SUCCESS; + uint8_t str_auth[16]; + int err; + + SYS_LOG_DBG(""); + + if (cmd->string_len > sizeof(str_auth)) { + SYS_LOG_ERR("Too long input (%u chars required)", input_size); + status = BTP_STATUS_FAILED; + goto rsp; + } else if (cmd->string_len < input_size) { + SYS_LOG_ERR("Too short input (%u chars required)", input_size); + status = BTP_STATUS_FAILED; + goto rsp; + } + + strncpy((char *) str_auth, (char *) cmd->string, cmd->string_len); + + err = bt_mesh_input_string((char *) str_auth); + if (err) { + status = BTP_STATUS_FAILED; + } rsp: - tester_rsp(BTP_SERVICE_ID_MESH, MESH_INPUT_STRING, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_MESH, MESH_INPUT_STRING, CONTROLLER_INDEX, + status); } -static void ivu_test_mode(uint8_t *data, uint16_t len) +static void +ivu_test_mode(uint8_t *data, uint16_t len) { - const struct mesh_ivu_test_mode_cmd *cmd = (void *) data; + const struct mesh_ivu_test_mode_cmd *cmd = (void *) data; - SYS_LOG_DBG("enable 0x%02x", cmd->enable); + SYS_LOG_DBG("enable 0x%02x", cmd->enable); - bt_mesh_iv_update_test(cmd->enable ? true : false); + bt_mesh_iv_update_test(cmd->enable ? true : false); - tester_rsp(BTP_SERVICE_ID_MESH, MESH_IVU_TEST_MODE, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_MESH, MESH_IVU_TEST_MODE, CONTROLLER_INDEX, + BTP_STATUS_SUCCESS); } -static void ivu_toggle_state(uint8_t *data, uint16_t len) +static void +ivu_toggle_state(uint8_t *data, uint16_t len) { - bool result; + bool result; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - result = bt_mesh_iv_update(); - if (!result) { - SYS_LOG_ERR("Failed to toggle the IV Update state"); - } + result = bt_mesh_iv_update(); + if (!result) { + SYS_LOG_ERR("Failed to toggle the IV Update state"); + } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_IVU_TOGGLE_STATE, CONTROLLER_INDEX, - result ? BTP_STATUS_SUCCESS : BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_MESH, MESH_IVU_TOGGLE_STATE, CONTROLLER_INDEX, + result ? BTP_STATUS_SUCCESS : BTP_STATUS_FAILED); } -static void lpn(uint8_t *data, uint16_t len) +static void +lpn(uint8_t *data, uint16_t len) { - struct mesh_lpn_set_cmd *cmd = (void *) data; - bool enable; - int err; + struct mesh_lpn_set_cmd *cmd = (void *) data; + bool enable; + int err; - SYS_LOG_DBG("enable 0x%02x", cmd->enable); + SYS_LOG_DBG("enable 0x%02x", cmd->enable); - enable = cmd->enable ? true : false; - err = bt_mesh_lpn_set(enable); - if (err) { - SYS_LOG_ERR("Failed to toggle LPN (err %d)", err); - } + enable = cmd->enable ? true : false; + err = bt_mesh_lpn_set(enable); + if (err) { + SYS_LOG_ERR("Failed to toggle LPN (err %d)", err); + } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN, CONTROLLER_INDEX, + err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } -static void lpn_poll(uint8_t *data, uint16_t len) +static void +lpn_poll(uint8_t *data, uint16_t len) { - int err; + int err; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - err = bt_mesh_lpn_poll(); - if (err) { - SYS_LOG_ERR("Failed to send poll msg (err %d)", err); - } + err = bt_mesh_lpn_poll(); + if (err) { + SYS_LOG_ERR("Failed to send poll msg (err %d)", err); + } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN_POLL, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN_POLL, CONTROLLER_INDEX, + err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } -static void net_send(uint8_t *data, uint16_t len) +static void +net_send(uint8_t *data, uint16_t len) { - struct mesh_net_send_cmd *cmd = (void *) data; - struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); - struct bt_mesh_msg_ctx ctx = { - .net_idx = net.net_idx, - .app_idx = vnd_app_key_idx, - .addr = sys_le16_to_cpu(cmd->dst), - .send_ttl = cmd->ttl, - }; - int err; - - SYS_LOG_DBG("ttl 0x%02x dst 0x%04x payload_len %d", ctx.send_ttl, - ctx.addr, cmd->payload_len); - - if (!bt_mesh_app_key_exists(vnd_app_key_idx)) { - (void)bt_mesh_app_key_add(vnd_app_key_idx, net.net_idx, - vnd_app_key); - vnd_models[0].keys[0] = vnd_app_key_idx; - } - - net_buf_simple_add_mem(msg, cmd->payload, cmd->payload_len); - - err = bt_mesh_model_send(&vnd_models[0], &ctx, msg, NULL, NULL); - if (err) { - SYS_LOG_ERR("Failed to send (err %d)", err); - } - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_NET_SEND, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); - - os_mbuf_free_chain(msg); + struct mesh_net_send_cmd *cmd = (void *) data; + struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net.net_idx, + .app_idx = vnd_app_key_idx, + .addr = sys_le16_to_cpu(cmd->dst), + .send_ttl = cmd->ttl, + }; + int err; + + SYS_LOG_DBG("ttl 0x%02x dst 0x%04x payload_len %d", ctx.send_ttl, + ctx.addr, cmd->payload_len); + + if (!bt_mesh_app_key_exists(vnd_app_key_idx)) { + (void) bt_mesh_app_key_add(vnd_app_key_idx, net.net_idx, + vnd_app_key); + vnd_models[0].keys[0] = vnd_app_key_idx; + } + + net_buf_simple_add_mem(msg, cmd->payload, cmd->payload_len); + + err = bt_mesh_model_send(&vnd_models[0], &ctx, msg, NULL, NULL); + if (err) { + SYS_LOG_ERR("Failed to send (err %d)", err); + } + + tester_rsp(BTP_SERVICE_ID_MESH, MESH_NET_SEND, CONTROLLER_INDEX, + err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); + + os_mbuf_free_chain(msg); } -static void health_generate_faults(uint8_t *data, uint16_t len) +static void +health_generate_faults(uint8_t *data, uint16_t len) { - struct mesh_health_generate_faults_rp *rp; - struct os_mbuf *buf = NET_BUF_SIMPLE(sizeof(*rp) + sizeof(cur_faults) + - sizeof(reg_faults)); - uint8_t some_faults[] = { 0x01, 0x02, 0x03, 0xff, 0x06 }; - uint8_t cur_faults_count, reg_faults_count; + struct mesh_health_generate_faults_rp *rp; + struct os_mbuf *buf = NET_BUF_SIMPLE(sizeof(*rp) + sizeof(cur_faults) + + sizeof(reg_faults)); + uint8_t some_faults[] = {0x01, 0x02, 0x03, 0xff, 0x06}; + uint8_t cur_faults_count, reg_faults_count; - rp = net_buf_simple_add(buf, sizeof(*rp)); + rp = net_buf_simple_add(buf, sizeof(*rp)); - cur_faults_count = min(sizeof(cur_faults), sizeof(some_faults)); - memcpy(cur_faults, some_faults, cur_faults_count); - net_buf_simple_add_mem(buf, cur_faults, cur_faults_count); - rp->cur_faults_count = cur_faults_count; + cur_faults_count = min(sizeof(cur_faults), sizeof(some_faults)); + memcpy(cur_faults, some_faults, cur_faults_count); + net_buf_simple_add_mem(buf, cur_faults, cur_faults_count); + rp->cur_faults_count = cur_faults_count; - reg_faults_count = min(sizeof(reg_faults), sizeof(some_faults)); - memcpy(reg_faults, some_faults, reg_faults_count); - net_buf_simple_add_mem(buf, reg_faults, reg_faults_count); - rp->reg_faults_count = reg_faults_count; + reg_faults_count = min(sizeof(reg_faults), sizeof(some_faults)); + memcpy(reg_faults, some_faults, reg_faults_count); + net_buf_simple_add_mem(buf, reg_faults, reg_faults_count); + rp->reg_faults_count = reg_faults_count; - bt_mesh_fault_update(&elements[0]); + bt_mesh_fault_update(&elements[0]); - tester_send_buf(BTP_SERVICE_ID_MESH, MESH_HEALTH_GENERATE_FAULTS, - CONTROLLER_INDEX, buf); + tester_send_buf(BTP_SERVICE_ID_MESH, MESH_HEALTH_GENERATE_FAULTS, + CONTROLLER_INDEX, buf); } -static void health_clear_faults(uint8_t *data, uint16_t len) +static void +health_clear_faults(uint8_t *data, uint16_t len) { - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - memset(cur_faults, 0, sizeof(cur_faults)); - memset(reg_faults, 0, sizeof(reg_faults)); + memset(cur_faults, 0, sizeof(cur_faults)); + memset(reg_faults, 0, sizeof(reg_faults)); - bt_mesh_fault_update(&elements[0]); + bt_mesh_fault_update(&elements[0]); - tester_rsp(BTP_SERVICE_ID_MESH, MESH_HEALTH_CLEAR_FAULTS, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_MESH, MESH_HEALTH_CLEAR_FAULTS, + CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } -static void model_send(uint8_t *data, uint16_t len) +static void +model_send(uint8_t *data, uint16_t len) { - struct mesh_model_send_cmd *cmd = (void *) data; - struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); - struct bt_mesh_msg_ctx ctx = { - .net_idx = net.net_idx, - .app_idx = BT_MESH_KEY_DEV, - .addr = sys_le16_to_cpu(cmd->dst), - .send_ttl = BT_MESH_TTL_DEFAULT, - }; - struct bt_mesh_model *model = NULL; - int err, i; - uint16_t src = sys_le16_to_cpu(cmd->src); - - /* Lookup source address */ - for (i = 0; i < ARRAY_SIZE(model_bound); i++) { - if (bt_mesh_model_elem(model_bound[i].model)->addr == src) { - model = model_bound[i].model; - ctx.app_idx = model_bound[i].appkey_idx; + struct mesh_model_send_cmd *cmd = (void *) data; + struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net.net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = sys_le16_to_cpu(cmd->dst), + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct bt_mesh_model *model = NULL; + int err, i; + uint16_t src = sys_le16_to_cpu(cmd->src); + + /* Lookup source address */ + for (i = 0; i < ARRAY_SIZE(model_bound); i++) { + if (bt_mesh_model_elem(model_bound[i].model)->addr == src) { + model = model_bound[i].model; + ctx.app_idx = model_bound[i].appkey_idx; + + break; + } + } + + if (!model) { + SYS_LOG_ERR("Model not found"); + err = -EINVAL; + + goto fail; + } + + SYS_LOG_DBG("src 0x%04x dst 0x%04x model %p payload_len %d", src, + ctx.addr, model, cmd->payload_len); + + net_buf_simple_add_mem(msg, cmd->payload, cmd->payload_len); + + err = bt_mesh_model_send(model, &ctx, msg, NULL, NULL); + if (err) { + SYS_LOG_ERR("Failed to send (err %d)", err); + } - break; - } - } - - if (!model) { - SYS_LOG_ERR("Model not found"); - err = -EINVAL; +fail: + tester_rsp(BTP_SERVICE_ID_MESH, MESH_MODEL_SEND, CONTROLLER_INDEX, + err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); - goto fail; - } + os_mbuf_free_chain(msg); +} - SYS_LOG_DBG("src 0x%04x dst 0x%04x model %p payload_len %d", src, - ctx.addr, model, cmd->payload_len); +#if MYNEWT_VAL(BLE_MESH_TESTING) - net_buf_simple_add_mem(msg, cmd->payload, cmd->payload_len); +static void +lpn_subscribe(uint8_t *data, uint16_t len) +{ + struct mesh_lpn_subscribe_cmd *cmd = (void *) data; + uint16_t address = sys_le16_to_cpu(cmd->address); + int err; - err = bt_mesh_model_send(model, &ctx, msg, NULL, NULL); - if (err) { - SYS_LOG_ERR("Failed to send (err %d)", err); - } + SYS_LOG_DBG("address 0x%04x", address); -fail: - tester_rsp(BTP_SERVICE_ID_MESH, MESH_MODEL_SEND, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); + err = bt_test_mesh_lpn_group_add(address); + if (err) { + SYS_LOG_ERR("Failed to subscribe (err %d)", err); + } - os_mbuf_free_chain(msg); + tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN_SUBSCRIBE, CONTROLLER_INDEX, + err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } -#if MYNEWT_VAL(BLE_MESH_TESTING) -static void lpn_subscribe(uint8_t *data, uint16_t len) +static void +lpn_unsubscribe(uint8_t *data, uint16_t len) { - struct mesh_lpn_subscribe_cmd *cmd = (void *) data; - uint16_t address = sys_le16_to_cpu(cmd->address); - int err; + struct mesh_lpn_unsubscribe_cmd *cmd = (void *) data; + uint16_t address = sys_le16_to_cpu(cmd->address); + int err; - SYS_LOG_DBG("address 0x%04x", address); + SYS_LOG_DBG("address 0x%04x", address); - err = bt_test_mesh_lpn_group_add(address); - if (err) { - SYS_LOG_ERR("Failed to subscribe (err %d)", err); - } + err = bt_test_mesh_lpn_group_remove(&address, 1); + if (err) { + SYS_LOG_ERR("Failed to unsubscribe (err %d)", err); + } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN_SUBSCRIBE, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN_UNSUBSCRIBE, CONTROLLER_INDEX, + err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } -static void lpn_unsubscribe(uint8_t *data, uint16_t len) +static void +rpl_clear(uint8_t *data, uint16_t len) { - struct mesh_lpn_unsubscribe_cmd *cmd = (void *) data; - uint16_t address = sys_le16_to_cpu(cmd->address); - int err; + int err; - SYS_LOG_DBG("address 0x%04x", address); + SYS_LOG_DBG(""); - err = bt_test_mesh_lpn_group_remove(&address, 1); - if (err) { - SYS_LOG_ERR("Failed to unsubscribe (err %d)", err); - } + err = bt_test_mesh_rpl_clear(); + if (err) { + SYS_LOG_ERR("Failed to clear RPL (err %d)", err); + } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN_UNSUBSCRIBE, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_MESH, MESH_RPL_CLEAR, CONTROLLER_INDEX, + err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } -static void rpl_clear(uint8_t *data, uint16_t len) +#endif /* MYNEWT_VAL(BLE_MESH_TESTING) */ + +static void +proxy_identity_enable(uint8_t *data, uint16_t len) { - int err; + int err; - SYS_LOG_DBG(""); + SYS_LOG_DBG(""); - err = bt_test_mesh_rpl_clear(); - if (err) { - SYS_LOG_ERR("Failed to clear RPL (err %d)", err); - } + err = bt_mesh_proxy_identity_enable(); + if (err) { + SYS_LOG_ERR("Failed to enable proxy identity (err %d)", err); + } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_RPL_CLEAR, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_MESH, MESH_PROXY_IDENTITY, CONTROLLER_INDEX, + err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } -#endif /* MYNEWT_VAL(BLE_MESH_TESTING) */ -static void proxy_identity_enable(uint8_t *data, uint16_t len) -{ - int err; - - SYS_LOG_DBG(""); - - err = bt_mesh_proxy_identity_enable(); - if (err) { - SYS_LOG_ERR("Failed to enable proxy identity (err %d)", err); - } - - tester_rsp(BTP_SERVICE_ID_MESH, MESH_PROXY_IDENTITY, CONTROLLER_INDEX, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); -} - -void tester_handle_mesh(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len) -{ - switch (opcode) { - case MESH_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - break; - case MESH_CONFIG_PROVISIONING: - config_prov(data, len); - break; - case MESH_PROVISION_NODE: - provision_node(data, len); - break; - case MESH_INIT: - init(data, len); - break; - case MESH_RESET: - reset(data, len); - break; - case MESH_INPUT_NUMBER: - input_number(data, len); - break; - case MESH_INPUT_STRING: - input_string(data, len); - break; - case MESH_IVU_TEST_MODE: - ivu_test_mode(data, len); - break; - case MESH_IVU_TOGGLE_STATE: - ivu_toggle_state(data, len); - break; - case MESH_LPN: - lpn(data, len); - break; - case MESH_LPN_POLL: - lpn_poll(data, len); - break; - case MESH_NET_SEND: - net_send(data, len); - break; - case MESH_HEALTH_GENERATE_FAULTS: - health_generate_faults(data, len); - break; - case MESH_HEALTH_CLEAR_FAULTS: - health_clear_faults(data, len); - break; - case MESH_MODEL_SEND: - model_send(data, len); - break; +void +tester_handle_mesh(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len) +{ + switch (opcode) { + case MESH_READ_SUPPORTED_COMMANDS: + supported_commands(data, len); + break; + case MESH_CONFIG_PROVISIONING: + config_prov(data, len); + break; + case MESH_PROVISION_NODE: + provision_node(data, len); + break; + case MESH_INIT: + init(data, len); + break; + case MESH_RESET: + reset(data, len); + break; + case MESH_INPUT_NUMBER: + input_number(data, len); + break; + case MESH_INPUT_STRING: + input_string(data, len); + break; + case MESH_IVU_TEST_MODE: + ivu_test_mode(data, len); + break; + case MESH_IVU_TOGGLE_STATE: + ivu_toggle_state(data, len); + break; + case MESH_LPN: + lpn(data, len); + break; + case MESH_LPN_POLL: + lpn_poll(data, len); + break; + case MESH_NET_SEND: + net_send(data, len); + break; + case MESH_HEALTH_GENERATE_FAULTS: + health_generate_faults(data, len); + break; + case MESH_HEALTH_CLEAR_FAULTS: + health_clear_faults(data, len); + break; + case MESH_MODEL_SEND: + model_send(data, len); + break; #if MYNEWT_VAL(BLE_MESH_TESTING) - case MESH_LPN_SUBSCRIBE: - lpn_subscribe(data, len); - break; - case MESH_LPN_UNSUBSCRIBE: - lpn_unsubscribe(data, len); - break; - case MESH_RPL_CLEAR: - rpl_clear(data, len); - break; + case MESH_LPN_SUBSCRIBE: + lpn_subscribe(data, len); + break; + case MESH_LPN_UNSUBSCRIBE: + lpn_unsubscribe(data, len); + break; + case MESH_RPL_CLEAR: + rpl_clear(data, len); + break; #endif /* MYNEWT_VAL(BLE_MESH_TESTING) */ - case MESH_PROXY_IDENTITY: - proxy_identity_enable(data, len); - break; - default: - tester_rsp(BTP_SERVICE_ID_MESH, opcode, index, - BTP_STATUS_UNKNOWN_CMD); - break; - } + case MESH_PROXY_IDENTITY: + proxy_identity_enable(data, len); + break; + default: + tester_rsp(BTP_SERVICE_ID_MESH, opcode, index, + BTP_STATUS_UNKNOWN_CMD); + break; + } } -void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const void *payload, - size_t payload_len) +void +net_recv_ev(uint8_t ttl, + uint8_t ctl, + uint16_t src, + uint16_t dst, + const void *payload, + size_t payload_len) { - struct os_mbuf *buf = NET_BUF_SIMPLE(UINT8_MAX); - struct mesh_net_recv_ev *ev; + struct os_mbuf *buf = NET_BUF_SIMPLE(UINT8_MAX); + struct mesh_net_recv_ev *ev; - SYS_LOG_DBG("ttl 0x%02x ctl 0x%02x src 0x%04x dst 0x%04x " - "payload_len %d", ttl, ctl, src, dst, payload_len); + SYS_LOG_DBG("ttl 0x%02x ctl 0x%02x src 0x%04x dst 0x%04x " + "payload_len %d", ttl, ctl, src, dst, payload_len); - if (payload_len > net_buf_simple_tailroom(buf)) { - SYS_LOG_ERR("Payload size exceeds buffer size"); + if (payload_len > net_buf_simple_tailroom(buf)) { + SYS_LOG_ERR("Payload size exceeds buffer size"); - goto done; - } + goto done; + } - ev = net_buf_simple_add(buf, sizeof(*ev)); - ev->ttl = ttl; - ev->ctl = ctl; - ev->src = sys_cpu_to_le16(src); - ev->dst = sys_cpu_to_le16(dst); - ev->payload_len = payload_len; - net_buf_simple_add_mem(buf, payload, payload_len); + ev = net_buf_simple_add(buf, sizeof(*ev)); + ev->ttl = ttl; + ev->ctl = ctl; + ev->src = sys_cpu_to_le16(src); + ev->dst = sys_cpu_to_le16(dst); + ev->payload_len = payload_len; + net_buf_simple_add_mem(buf, payload, payload_len); - tester_send_buf(BTP_SERVICE_ID_MESH, MESH_EV_NET_RECV, CONTROLLER_INDEX, - buf); + tester_send_buf(BTP_SERVICE_ID_MESH, MESH_EV_NET_RECV, CONTROLLER_INDEX, + buf); done: - os_mbuf_free_chain(buf); + os_mbuf_free_chain(buf); } -static void model_bound_cb(uint16_t addr, struct bt_mesh_model *model, - uint16_t key_idx) +static void +model_bound_cb(uint16_t addr, struct bt_mesh_model *model, + uint16_t key_idx) { - int i; + int i; - SYS_LOG_DBG("remote addr 0x%04x key_idx 0x%04x model %p", - addr, key_idx, model); + SYS_LOG_DBG("remote addr 0x%04x key_idx 0x%04x model %p", + addr, key_idx, model); - for (i = 0; i < ARRAY_SIZE(model_bound); i++) { - if (!model_bound[i].model) { - model_bound[i].model = model; - model_bound[i].addr = addr; - model_bound[i].appkey_idx = key_idx; + for (i = 0; i < ARRAY_SIZE(model_bound); i++) { + if (!model_bound[i].model) { + model_bound[i].model = model; + model_bound[i].addr = addr; + model_bound[i].appkey_idx = key_idx; - return; - } - } + return; + } + } - SYS_LOG_ERR("model_bound is full"); + SYS_LOG_ERR("model_bound is full"); } -static void model_unbound_cb(uint16_t addr, struct bt_mesh_model *model, - uint16_t key_idx) +static void +model_unbound_cb(uint16_t addr, struct bt_mesh_model *model, + uint16_t key_idx) { - int i; + int i; - SYS_LOG_DBG("remote addr 0x%04x key_idx 0x%04x model %p", - addr, key_idx, model); + SYS_LOG_DBG("remote addr 0x%04x key_idx 0x%04x model %p", + addr, key_idx, model); - for (i = 0; i < ARRAY_SIZE(model_bound); i++) { - if (model_bound[i].model == model) { - model_bound[i].model = NULL; - model_bound[i].addr = 0x0000; - model_bound[i].appkey_idx = BT_MESH_KEY_UNUSED; + for (i = 0; i < ARRAY_SIZE(model_bound); i++) { + if (model_bound[i].model == model) { + model_bound[i].model = NULL; + model_bound[i].addr = 0x0000; + model_bound[i].appkey_idx = BT_MESH_KEY_UNUSED; - return; - } - } + return; + } + } - SYS_LOG_INF("model not found"); + SYS_LOG_INF("model not found"); } -static void invalid_bearer_cb(uint8_t opcode) +static void +invalid_bearer_cb(uint8_t opcode) { - struct mesh_invalid_bearer_ev ev = { - .opcode = opcode, - }; + struct mesh_invalid_bearer_ev ev = { + .opcode = opcode, + }; - SYS_LOG_DBG("opcode 0x%02x", opcode); + SYS_LOG_DBG("opcode 0x%02x", opcode); - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_INVALID_BEARER, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_MESH, MESH_EV_INVALID_BEARER, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } -static void incomp_timer_exp_cb(void) +static void +incomp_timer_exp_cb(void) { - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_INCOMP_TIMER_EXP, - CONTROLLER_INDEX, NULL, 0); + tester_send(BTP_SERVICE_ID_MESH, MESH_EV_INCOMP_TIMER_EXP, + CONTROLLER_INDEX, NULL, 0); } static struct bt_test_cb bt_test_cb = { - .mesh_net_recv = net_recv_ev, - .mesh_model_bound = model_bound_cb, - .mesh_model_unbound = model_unbound_cb, - .mesh_prov_invalid_bearer = invalid_bearer_cb, - .mesh_trans_incomp_timer_exp = incomp_timer_exp_cb, + .mesh_net_recv = net_recv_ev, + .mesh_model_bound = model_bound_cb, + .mesh_model_unbound = model_unbound_cb, + .mesh_prov_invalid_bearer = invalid_bearer_cb, + .mesh_trans_incomp_timer_exp = incomp_timer_exp_cb, }; -static void lpn_established(uint16_t friend_addr) +static void +lpn_established(uint16_t friend_addr) { - struct bt_mesh_lpn *lpn = &bt_mesh.lpn; - struct mesh_lpn_established_ev ev = { lpn->sub->net_idx, friend_addr, lpn->queue_size, - lpn->recv_win }; + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + struct mesh_lpn_established_ev + ev = {lpn->sub->net_idx, friend_addr, lpn->queue_size, + lpn->recv_win}; - SYS_LOG_DBG("Friendship (as LPN) established with " - "Friend 0x%04x Queue Size %d Receive Window %d", - friend_addr, lpn->queue_size, lpn->recv_win); + SYS_LOG_DBG("Friendship (as LPN) established with " + "Friend 0x%04x Queue Size %d Receive Window %d", + friend_addr, lpn->queue_size, lpn->recv_win); - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_LPN_ESTABLISHED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_MESH, MESH_EV_LPN_ESTABLISHED, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } -static void lpn_terminated(uint16_t friend_addr) +static void +lpn_terminated(uint16_t friend_addr) { - struct bt_mesh_lpn *lpn = &bt_mesh.lpn; - struct mesh_lpn_terminated_ev ev = { lpn->sub->net_idx, friend_addr }; + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + struct mesh_lpn_terminated_ev ev = {lpn->sub->net_idx, friend_addr}; - SYS_LOG_DBG("Friendship (as LPN) lost with Friend " - "0x%04x", friend_addr); + SYS_LOG_DBG("Friendship (as LPN) lost with Friend " + "0x%04x", friend_addr); - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_LPN_TERMINATED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + tester_send(BTP_SERVICE_ID_MESH, MESH_EV_LPN_TERMINATED, + CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } -void lpn_cb(uint16_t friend_addr, bool established) +void +lpn_cb(uint16_t friend_addr, bool established) { - if (established) { - lpn_established(friend_addr); - } else { - lpn_terminated(friend_addr); - } + if (established) { + lpn_established(friend_addr); + } else { + lpn_terminated(friend_addr); + } } -uint8_t tester_init_mesh(void) +uint8_t +tester_init_mesh(void) { - health_pub_init(); + health_pub_init(); - if (IS_ENABLED(CONFIG_BT_TESTING)) { - bt_mesh_lpn_set_cb(lpn_cb); - bt_test_cb_register(&bt_test_cb); - } + if (IS_ENABLED(CONFIG_BT_TESTING)) { + bt_mesh_lpn_set_cb(lpn_cb); + bt_test_cb_register(&bt_test_cb); + } - return BTP_STATUS_SUCCESS; + return BTP_STATUS_SUCCESS; } -uint8_t tester_unregister_mesh(void) +uint8_t +tester_unregister_mesh(void) { - return BTP_STATUS_SUCCESS; + return BTP_STATUS_SUCCESS; } #endif /* MYNEWT_VAL(BLE_MESH) */ diff --git a/apps/bttester/src/uart_pipe.c b/apps/bttester/src/uart_pipe.c index 1118d9af57..223a78975f 100644 --- a/apps/bttester/src/uart_pipe.c +++ b/apps/bttester/src/uart_pipe.c @@ -41,7 +41,7 @@ struct uart_pipe_ring { static struct uart_dev *uart_dev; static struct uart_pipe_ring cr_tx; static uint8_t cr_tx_buf[MYNEWT_VAL(BTTESTER_BTP_DATA_SIZE_MAX)]; -typedef void (*console_write_char)(struct uart_dev*, uint8_t); +typedef void (*console_write_char)(struct uart_dev *, uint8_t); static console_write_char write_char_cb; static struct uart_pipe_ring cr_rx; @@ -217,39 +217,39 @@ bttester_pipe_send(const uint8_t *data, int len) int bttester_pipe_send_buf(struct os_mbuf *buf) { - int i, len; - struct os_mbuf *om; - - /* Assure that there is a write cb installed; this enables to debug - * code that is faulting before the console was initialized. - */ - if (!write_char_cb) { - return -1; - } - - for (om = buf; om; om = SLIST_NEXT(om, om_next)) { - len = om->om_len; - for (i = 0; i < len; ++i) { - write_char_cb(uart_dev, om->om_data[i]); - } - } - - uart_start_tx(uart_dev); - - return 0; + int i, len; + struct os_mbuf *om; + + /* Assure that there is a write cb installed; this enables to debug + * code that is faulting before the console was initialized. + */ + if (!write_char_cb) { + return -1; + } + + for (om = buf; om; om = SLIST_NEXT(om, om_next)) { + len = om->om_len; + for (i = 0; i < len; ++i) { + write_char_cb(uart_dev, om->om_data[i]); + } + } + + uart_start_tx(uart_dev); + + return 0; } int bttester_pipe_init(void) { struct uart_conf uc = { - .uc_speed = MYNEWT_VAL(CONSOLE_UART_BAUD), - .uc_databits = 8, - .uc_stopbits = 1, - .uc_parity = UART_PARITY_NONE, - .uc_flow_ctl = MYNEWT_VAL(CONSOLE_UART_FLOW_CONTROL), - .uc_tx_char = uart_console_tx_char, - .uc_rx_char = uart_console_rx_char, + .uc_speed = MYNEWT_VAL(CONSOLE_UART_BAUD), + .uc_databits = 8, + .uc_stopbits = 1, + .uc_parity = UART_PARITY_NONE, + .uc_flow_ctl = MYNEWT_VAL(CONSOLE_UART_FLOW_CONTROL), + .uc_tx_char = uart_console_tx_char, + .uc_rx_char = uart_console_rx_char, }; cr_tx.size = sizeof(cr_tx_buf); @@ -262,8 +262,9 @@ bttester_pipe_init(void) rx_ev.ev_cb = uart_console_rx_char_event; if (!uart_dev) { - uart_dev = (struct uart_dev *)os_dev_open(MYNEWT_VAL(CONSOLE_UART_DEV), - OS_TIMEOUT_NEVER, &uc); + uart_dev = + (struct uart_dev *) os_dev_open(MYNEWT_VAL(CONSOLE_UART_DEV), + OS_TIMEOUT_NEVER, &uc); if (!uart_dev) { return -1; } @@ -274,8 +275,9 @@ bttester_pipe_init(void) void bttester_pipe_register(uint8_t *buf, size_t len, bttester_pipe_recv_cb cb) { - recv_buf = buf; - recv_buf_len = len; - app_cb = cb; + recv_buf = buf; + recv_buf_len = len; + app_cb = cb; } + #endif /* MYNEWT_VAL(BTTESTER_PIPE_UART) */ From 4c0096fa80424f1b1d46931011166a6e59e2700a Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Tue, 6 Jun 2023 14:19:27 +0530 Subject: [PATCH 0701/1333] apps/blecent: Fix incorrect return value handling in blecent_should_connect. --- apps/blecent/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/blecent/src/main.c b/apps/blecent/src/main.c index 7f1c5f151c..f794937e22 100644 --- a/apps/blecent/src/main.c +++ b/apps/blecent/src/main.c @@ -272,7 +272,7 @@ blecent_should_connect(const struct ble_gap_disc_desc *disc) rc = ble_hs_adv_parse_fields(&fields, disc->data, disc->length_data); if (rc != 0) { - return rc; + return 0; } /* The device has to advertise support for the Alert Notification From ed6952ad2edd9fbb8159a43949414253a3845501 Mon Sep 17 00:00:00 2001 From: Jakub Date: Tue, 6 Jun 2023 10:02:45 +0200 Subject: [PATCH 0702/1333] nimble/transport: Remove initialization of hci socket from sysinit This caused double call to hci socket init function and triggered assertion while trying to run apps on native. --- nimble/transport/socket/pkg.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/nimble/transport/socket/pkg.yml b/nimble/transport/socket/pkg.yml index fb4144d3ae..b64075baeb 100644 --- a/nimble/transport/socket/pkg.yml +++ b/nimble/transport/socket/pkg.yml @@ -33,6 +33,3 @@ pkg.deps: pkg.apis: - ble_transport - -pkg.init: - ble_hci_sock_init: 'MYNEWT_VAL(BLE_SOCK_CLI_SYSINIT_STAGE)' From 8074802c1142fa75fa4e5570c985358eb074fa3b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 5 Jun 2023 23:41:10 +0200 Subject: [PATCH 0703/1333] nimble/ll: Fix hci supported cmds BLE_LL_BT5_PHY_SUPPORTED is defined in ble_ll.h so if that file is not included, we calculate incorrect hci supported cmds bitmask. --- nimble/controller/src/ble_ll_hci_supp_cmd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/controller/src/ble_ll_hci_supp_cmd.c b/nimble/controller/src/ble_ll_hci_supp_cmd.c index 8315a1bfda..dc0df71497 100644 --- a/nimble/controller/src/ble_ll_hci_supp_cmd.c +++ b/nimble/controller/src/ble_ll_hci_supp_cmd.c @@ -20,6 +20,7 @@ #include #include #include +#include #include /* Magic macros */ From b2ebf7630d27dfcd01927e8abbc126ff80de62b6 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Thu, 8 Jun 2023 13:17:43 +0530 Subject: [PATCH 0704/1333] nimble/host: Fix data type of power level and delta to handle negative values --- nimble/host/include/host/ble_gap.h | 8 ++++---- nimble/include/nimble/hci_common.h | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index bf40236e7a..c6d9dc817f 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -1068,14 +1068,14 @@ struct ble_gap_event { /** Advertising PHY */ uint8_t phy; - /** Transmit power Level */ - uint8_t transmit_power_level; + /** Transmit power Level */ + int8_t transmit_power_level; /** Transmit Power Level Flag */ uint8_t transmit_power_level_flag; - /** Delta indicating change in transmit Power Level */ - uint8_t delta; + /** Delta indicating change in transmit Power Level */ + int8_t delta; } transmit_power; #endif /** diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index db364db8d7..ca0c219ee2 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1937,14 +1937,14 @@ struct ble_hci_ev_le_subev_path_loss_threshold { #define BLE_HCI_LE_SUBEV_TRANSMIT_POWER_REPORT (0x21) struct ble_hci_ev_le_subev_transmit_power_report { - uint8_t subev_code; - uint8_t status; + uint8_t subev_code; + uint8_t status; uint16_t conn_handle; - uint8_t reason; - uint8_t phy; - uint8_t transmit_power_level; - uint8_t transmit_power_level_flag; - uint8_t delta; + uint8_t reason; + uint8_t phy; + int8_t transmit_power_level; + uint8_t transmit_power_level_flag; + int8_t delta; } __attribute__((packed)); #define BLE_HCI_LE_SUBEV_BIGINFO_ADV_REPORT (0x22) From 2a566fa86fa859d1dc749d0d7d3e71bde8ee44c5 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 31 Jan 2023 14:51:41 +0100 Subject: [PATCH 0705/1333] nimble/ll: Cleanup transport handlers ble_ll_hci seems like a good place for rx functions to be declared. Also they do not need extra arg parameter as it's never used. And add ISO handler as well. --- .../include/controller/ble_ll_hci.h | 4 +++ nimble/controller/src/ble_ll.c | 10 +++++-- nimble/controller/src/ble_ll_conn_priv.h | 3 -- nimble/controller/src/ble_ll_hci.c | 28 +++++++++---------- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_hci.h b/nimble/controller/include/controller/ble_ll_hci.h index ff66805040..6fef1f7b16 100644 --- a/nimble/controller/include/controller/ble_ll_hci.h +++ b/nimble/controller/include/controller/ble_ll_hci.h @@ -57,6 +57,10 @@ struct ble_ll_hci_vs_cmd { /* Initialize LL HCI */ void ble_ll_hci_init(void); +int ble_ll_hci_cmd_rx(uint8_t *cmdbuf); +int ble_ll_hci_acl_rx(struct os_mbuf *om); +int ble_ll_hci_iso_rx(struct os_mbuf *om); + /* Used to determine if the LE event is enabled/disabled */ bool ble_ll_hci_is_le_event_enabled(unsigned int subev); diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index ed1795bee5..a1bbe63bb3 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1966,13 +1966,19 @@ ble_ll_init(void) int ble_transport_to_ll_cmd_impl(void *buf) { - return ble_ll_hci_cmd_rx(buf, NULL); + return ble_ll_hci_cmd_rx(buf); } int ble_transport_to_ll_acl_impl(struct os_mbuf *om) { - return ble_ll_hci_acl_rx(om, NULL); + return ble_ll_hci_acl_rx(om); +} + +int +ble_transport_to_ll_iso_impl(struct os_mbuf *om) +{ + return ble_ll_hci_iso_rx(om); } void diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index a3e1cc4bbc..954a27663a 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -260,9 +260,6 @@ int ble_ll_conn_set_data_len(struct ble_ll_conn_sm *connsm, void ble_ll_conn_itvl_to_ticks(uint32_t itvl, uint32_t *itvl_ticks, uint8_t *itvl_usecs); -int ble_ll_hci_cmd_rx(uint8_t *cmd, void *arg); -int ble_ll_hci_acl_rx(struct os_mbuf *om, void *arg); - int ble_ll_conn_hci_le_rd_phy(const uint8_t *cmdbuf, uint8_t len, uint8_t *rsp, uint8_t *rsplen); int ble_ll_conn_hci_le_set_phy(const uint8_t *cmdbuf, uint8_t len); diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 0f92654b00..6e3f0afa45 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1895,19 +1895,8 @@ ble_ll_hci_cmd_proc(struct ble_npl_event *ev) BLE_LL_DEBUG_GPIO(HCI_CMD, 0); } -/** - * Sends an HCI command to the controller. On success, the supplied buffer is - * relinquished to the controller task. On failure, the caller must free the - * buffer. - * - * @param cmd A flat buffer containing the HCI command to - * send. - * - * @return 0 on success; - * BLE_ERR_MEM_CAPACITY on HCI buffer exhaustion. - */ int -ble_ll_hci_cmd_rx(uint8_t *cmdbuf, void *arg) +ble_ll_hci_cmd_rx(uint8_t *cmdbuf) { struct ble_npl_event *ev; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) @@ -1948,9 +1937,8 @@ ble_ll_hci_cmd_rx(uint8_t *cmdbuf, void *arg) return 0; } -/* Send ACL data from host to contoller */ int -ble_ll_hci_acl_rx(struct os_mbuf *om, void *arg) +ble_ll_hci_acl_rx(struct os_mbuf *om) { #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) ble_ll_acl_data_in(om); @@ -1961,6 +1949,18 @@ ble_ll_hci_acl_rx(struct os_mbuf *om, void *arg) return 0; } +int +ble_ll_hci_iso_rx(struct os_mbuf *om) +{ +#if MYNEWT_VAL(BLE_LL_ISO) + /* FIXME send to isoal... */ + os_mbuf_free_chain(om); +#else + os_mbuf_free_chain(om); +#endif + return 0; +} + /** * Initalize the LL HCI. * From d56bd9dee7caab1d2ffe9d198a1a63fbc0f757d1 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 31 Jan 2023 14:31:03 +0100 Subject: [PATCH 0706/1333] nimble/ll: Add macros to handle conn handles Connection handles for ACL, CIS and BIS are assigned from the same pool so we'll just split that poll into separate ranges - we'll use msbyte as an indicator for type of conn_handle, this gives us 256 handles of each type which should be more than enough. --- nimble/controller/include/controller/ble_ll.h | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index c4e70e6ef3..5043429bb2 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -335,6 +335,27 @@ struct ble_dev_addr #define BLE_LL_MAX_PDU_LEN ((BLE_LL_PDU_HDR_LEN) + (BLE_LL_MAX_PAYLOAD_LEN)) #define BLE_LL_CRCINIT_ADV (0x555555) +#define BLE_LL_CONN_HANDLE(t, h) ((((t) << 8) & BLE_LL_CONN_HANDLE_TYPE_MASK) | \ + ((h) & BLE_LL_CONN_HANDLE_IDX_MASK)) +#define BLE_LL_CONN_HANDLE_TYPE_MASK (0x0700) +#define BLE_LL_CONN_HANDLE_IDX_MASK (0x00ff) +#define BLE_LL_CONN_HANDLE_TYPE(conn_h) (((conn_h) & BLE_LL_CONN_HANDLE_TYPE_MASK) >> 8) +#define BLE_LL_CONN_HANDLE_IDX(conn_h) ((conn_h) & BLE_LL_CONN_HANDLE_IDX_MASK) + +#define BLE_LL_CONN_HANDLE_TYPE_ACL (0x00) +#define BLE_LL_CONN_HANDLE_TYPE_CIS (0x01) +#define BLE_LL_CONN_HANDLE_TYPE_BIS (0x02) +#define BLE_LL_CONN_HANDLE_TYPE_BIS_SYNC (0x03) + +#define BLE_LL_CONN_HANDLE_IS_ACL(ch) \ + (BLE_LL_CONN_HANDLE_TYPE(ch) == BLE_LL_CONN_HANDLE_TYPE_ACL) +#define BLE_LL_CONN_HANDLE_IS_CIS(ch) \ + (BLE_LL_CONN_HANDLE_TYPE(ch) == BLE_LL_CONN_HANDLE_TYPE_CIS) +#define BLE_LL_CONN_HANDLE_IS_BIS(ch) \ + (BLE_LL_CONN_HANDLE_TYPE(ch) == BLE_LL_CONN_HANDLE_TYPE_BIS) +#define BLE_LL_CONN_HANDLE_IS_BIS_SYNC(ch) \ + (BLE_LL_CONN_HANDLE_TYPE(ch) == BLE_LL_CONN_HANDLE_TYPE_BIS_SYNC) + /* Access address for advertising channels */ #define BLE_ACCESS_ADDR_ADV (0x8E89BED6) From 6d02d3406aff5f604ed5dff8f1c2e321bc3e1db8 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sat, 26 Feb 2022 21:37:39 +0100 Subject: [PATCH 0707/1333] nimble/ll: Initial support for ISO Broadcasting state This adds initial support for ISO Broadcasting state: - all valid combinations of BIG/BIS parameters should be supported, - encryption is supported, - BIG control procedures are supported, - no LE Create BIG command (only LE Create BIG Test). HCI and ISOAL support coming soon. --- nimble/controller/include/controller/ble_ll.h | 4 + .../include/controller/ble_ll_iso_big.h | 47 + .../include/controller/ble_ll_sched.h | 5 + nimble/controller/src/ble_ll.c | 14 +- nimble/controller/src/ble_ll_hci.c | 37 +- nimble/controller/src/ble_ll_iso_big.c | 1092 +++++++++++++++++ nimble/controller/src/ble_ll_sched.c | 36 + nimble/controller/syscfg.yml | 17 + 8 files changed, 1241 insertions(+), 11 deletions(-) create mode 100644 nimble/controller/include/controller/ble_ll_iso_big.h create mode 100644 nimble/controller/src/ble_ll_iso_big.c diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 5043429bb2..fcfdff200e 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -240,6 +240,9 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats; #if MYNEWT_VAL(BLE_LL_EXT) #define BLE_LL_STATE_EXTERNAL (8) #endif +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) +#define BLE_LL_STATE_BIG (9) +#endif /* LL Features */ #define BLE_LL_FEAT_LE_ENCRYPTION (0x0000000001) @@ -301,6 +304,7 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats; /* LL timing */ #define BLE_LL_IFS (150) /* usecs */ #define BLE_LL_MAFS (300) /* usecs */ +#define BLE_LL_MSS (150) /* usecs */ /* * BLE LL device address. Note that element 0 of the array is the LSB and diff --git a/nimble/controller/include/controller/ble_ll_iso_big.h b/nimble/controller/include/controller/ble_ll_iso_big.h new file mode 100644 index 0000000000..1756fd2641 --- /dev/null +++ b/nimble/controller/include/controller/ble_ll_iso_big.h @@ -0,0 +1,47 @@ +/* + * 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_BLE_LL_ISO_BIG_ +#define H_BLE_LL_ISO_BIG_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + +void ble_ll_iso_big_chan_map_update(void); + +void ble_ll_iso_big_halt(void); + +int ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len); +int ble_ll_iso_big_hci_create_test(const uint8_t *cmdbuf, uint8_t len); +int ble_ll_iso_big_hci_terminate(const uint8_t *cmdbuf, uint8_t len); +void ble_ll_iso_big_hci_evt_complete(void); + +void ble_ll_iso_big_init(void); +void ble_ll_iso_big_reset(void); + +#endif /* BLE_LL_ISO_BROADCASTER */ + +#ifdef __cplusplus +} +#endif + +#endif /* H_BLE_LL_ISO_BIG_ */ diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index 5e04ce09f7..961a20aa4d 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -70,6 +70,7 @@ extern uint8_t g_ble_ll_sched_offset_ticks; #define BLE_LL_SCHED_TYPE_PERIODIC (6) #define BLE_LL_SCHED_TYPE_SYNC (7) #define BLE_LL_SCHED_TYPE_SCAN_AUX (8) +#define BLE_LL_SCHED_TYPE_BIG (9) #if MYNEWT_VAL(BLE_LL_EXT) #define BLE_LL_SCHED_TYPE_EXTERNAL (255) #endif @@ -222,6 +223,10 @@ uint32_t ble_ll_sched_css_get_conn_interval_us(void); #endif #endif +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) +int ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first); +#endif /* BLE_LL_ISO_BROADCASTER */ + #ifdef __cplusplus } #endif diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index a1bbe63bb3..de30b89222 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -46,6 +46,7 @@ #include "controller/ble_ll_trace.h" #include "controller/ble_ll_sync.h" #include "controller/ble_fem.h" +#include "controller/ble_ll_iso_big.h" #if MYNEWT_VAL(BLE_LL_EXT) #include "controller/ble_ll_ext.h" #endif @@ -1678,6 +1679,10 @@ ble_ll_reset(void) ble_fem_lna_init(); #endif +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + ble_ll_iso_big_reset(); +#endif + /* Re-initialize the PHY */ rc = ble_phy_init(); @@ -1913,8 +1918,11 @@ ble_ll_init(void) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) features |= BLE_LL_FEAT_CIS_CENTRAL; features |= BLE_LL_FEAT_CIS_PERIPH; + features |= BLE_LL_FEAT_CIS_HOST; +#endif + +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) features |= BLE_LL_FEAT_ISO_BROADCASTER; - features |= BLE_LL_FEAT_ISO_HOST_SUPPORT; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) @@ -1942,6 +1950,10 @@ ble_ll_init(void) ble_ll_hci_vs_init(); #endif +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + ble_ll_iso_big_init(); +#endif + #if MYNEWT_VAL(BLE_LL_EXT) ble_ll_ext_init(); #endif diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 6e3f0afa45..b693f5ca48 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -35,6 +35,7 @@ #include "controller/ble_ll_sync.h" #include #include "controller/ble_ll_iso.h" +#include "controller/ble_ll_iso_big.h" #include "ble_ll_priv.h" #include "ble_ll_conn_priv.h" #include "ble_ll_hci_priv.h" @@ -338,7 +339,7 @@ ble_ll_hci_le_read_bufsize(uint8_t *rspbuf, uint8_t *rsplen) return BLE_ERR_SUCCESS; } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) +#if MYNEWT_VAL(BLE_LL_ISO) /** * HCI read buffer size v2 command. Returns the ACL and ISO data packet length and * num data packets. @@ -355,8 +356,9 @@ ble_ll_hci_le_read_bufsize_v2(uint8_t *rspbuf, uint8_t *rsplen) rp->data_len = htole16(g_ble_ll_data.ll_acl_pkt_size); rp->data_packets = g_ble_ll_data.ll_num_acl_pkts; - rp->iso_data_len = 0; - rp->iso_data_packets = 0; + /* XXX for testing only */ + rp->iso_data_len = 512; + rp->iso_data_packets = 10; *rsplen = sizeof(*rp); return BLE_ERR_SUCCESS; @@ -661,6 +663,11 @@ ble_ll_hci_le_cmd_send_cmd_status(uint16_t ocf) case BLE_HCI_OCF_LE_GEN_DHKEY: case BLE_HCI_OCF_LE_SET_PHY: case BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC: +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + case BLE_HCI_OCF_LE_CREATE_BIG: + case BLE_HCI_OCF_LE_CREATE_BIG_TEST: + case BLE_HCI_OCF_LE_TERMINATE_BIG: +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE) case BLE_HCI_OCF_LE_REQ_PEER_SCA: #endif @@ -862,6 +869,9 @@ ble_ll_hci_le_set_host_chan_class(const uint8_t *cmdbuf, uint8_t len) g_ble_ll_data.chan_map_used = chan_map_used; ble_ll_conn_chan_map_update(); +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + ble_ll_iso_big_chan_map_update(); +#endif return BLE_ERR_SUCCESS; } @@ -1254,6 +1264,17 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, rc = ble_ll_set_default_sync_transfer_params(cmdbuf, len); break; #endif +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + case BLE_HCI_OCF_LE_CREATE_BIG: + rc = ble_ll_iso_big_hci_create(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_CREATE_BIG_TEST: + rc = ble_ll_iso_big_hci_create_test(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_TERMINATE_BIG: + rc = ble_ll_iso_big_hci_terminate(cmdbuf, len); + break; +#endif /* BLE_LL_ISO_BROADCASTER */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) case BLE_HCI_OCF_LE_READ_ISO_TX_SYNC: rc = ble_ll_iso_read_tx_sync(cmdbuf, len); @@ -1273,12 +1294,6 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, case BLE_HCI_OCF_LE_REJECT_CIS_REQ: rc = ble_ll_iso_reject_cis_req(cmdbuf, len); break; - case BLE_HCI_OCF_LE_CREATE_BIG: - rc = ble_ll_iso_create_big(cmdbuf, len); - break; - case BLE_HCI_OCF_LE_TERMINATE_BIG: - rc = ble_ll_iso_terminate_big(cmdbuf, len); - break; case BLE_HCI_OCF_LE_BIG_CREATE_SYNC: rc = ble_ll_iso_big_create_sync(cmdbuf, len); break; @@ -1291,12 +1306,14 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, case BLE_HCI_OCF_LE_REMOVE_ISO_DATA_PATH: rc = ble_ll_iso_remove_iso_data_path(cmdbuf, len); break; +#endif +#if MYNEWT_VAL(BLE_LL_ISO) case BLE_HCI_OCF_LE_RD_BUF_SIZE_V2: if (len == 0) { rc = ble_ll_hci_le_read_bufsize_v2(rspbuf, rsplen); } break; -#endif +#endif /* BLE_LL_ISO */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO_TEST) case BLE_HCI_OCF_LE_SET_CIG_PARAM_TEST: rc = ble_ll_iso_set_cig_param_test(cmdbuf, len, rspbuf, rsplen); diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c new file mode 100644 index 0000000000..20e5ff07bc --- /dev/null +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -0,0 +1,1092 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ble_ll_priv.h" + +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + +/* XXX make those configurable */ +#define BIG_POOL_SIZE (10) +#define BIS_POOL_SIZE (10) + +#define BIG_HANDLE_INVALID (0xff) + +#define BIG_CONTROL_ACTIVE_CHAN_MAP 1 +#define BIG_CONTROL_ACTIVE_TERM 2 + +struct ble_ll_iso_big; + +struct ble_ll_iso_bis { + struct ble_ll_iso_big *big; + uint8_t num; + uint16_t conn_handle; + + uint32_t aa; + uint32_t crc_init; + uint16_t chan_id; + uint8_t iv[8]; + + struct { + uint16_t prn_sub_lu; + uint16_t remap_idx; + + uint8_t subevent_num; + uint8_t n; + uint8_t g; + } tx; + + STAILQ_ENTRY(ble_ll_iso_bis) bis_q_next; +}; + +STAILQ_HEAD(ble_ll_iso_bis_q, ble_ll_iso_bis); + +struct big_params { + uint8_t nse; /* 1-31 */ + uint8_t bn; /* 1-7, mandatory 1 */ + uint8_t irc; /* 1-15 */ + uint8_t pto; /* 0-15, mandatory 0 */ + uint32_t sdu_interval; + uint16_t iso_interval; + uint16_t max_transport_latency; + uint16_t max_sdu; + uint8_t max_pdu; + uint8_t phy; + uint8_t interleaved : 1; + uint8_t framed : 1; + uint8_t encrypted : 1; + uint8_t broadcast_code[16]; +}; + +struct ble_ll_iso_big { + uint8_t handle; + uint8_t num_bis; + uint16_t iso_interval; + uint16_t bis_spacing; + uint16_t sub_interval; + uint8_t phy; + uint8_t max_pdu; + uint16_t max_sdu; + uint16_t mpt; + uint8_t bn; /* 1-7, mandatory 1 */ + uint8_t pto; /* 0-15, mandatory 0 */ + uint8_t irc; /* 1-15 */ + uint8_t nse; /* 1-31 */ + uint8_t interleaved : 1; + uint8_t framed : 1; + uint8_t encrypted : 1; + uint8_t giv[8]; + uint8_t gskd[16]; + uint8_t gsk[16]; + uint8_t iv[8]; + uint8_t gc; + + uint32_t sdu_interval; + + uint32_t ctrl_aa; + uint16_t crc_init; + uint8_t chan_map[BLE_LL_CHAN_MAP_LEN]; + uint8_t chan_map_used; + + uint64_t big_counter; + uint64_t bis_counter; + + uint32_t sync_delay; + uint32_t event_start; + uint8_t event_start_us; + struct ble_ll_sched_item sch; + struct ble_npl_event event_done; + + struct { + uint16_t subevents_rem; + struct ble_ll_iso_bis *bis; + } tx; + + struct ble_ll_iso_bis_q bis_q; + + uint8_t cstf : 1; + uint8_t cssn : 4; + uint8_t control_active : 3; + uint16_t control_instant; + + uint8_t chan_map_new_pending : 1; + uint8_t chan_map_new[BLE_LL_CHAN_MAP_LEN]; + + uint8_t term_pending : 1; + uint8_t term_reason : 7; +}; + +static struct ble_ll_iso_big big_pool[BIG_POOL_SIZE]; +static struct ble_ll_iso_bis bis_pool[BIS_POOL_SIZE]; +static uint8_t big_pool_free = BIG_POOL_SIZE; +static uint8_t bis_pool_free = BIS_POOL_SIZE; + +static struct ble_ll_iso_big *big_pending; +static struct ble_ll_iso_big *big_active; + +static void +ble_ll_iso_big_free(struct ble_ll_iso_big *big) +{ + struct ble_ll_iso_bis *bis; + + if (big->handle == BIG_HANDLE_INVALID) { + return; + } + + big->handle = BIG_HANDLE_INVALID; + ble_ll_sched_rmv_elem(&big->sch); + ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &big->event_done); + + STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) { + bis->big = NULL; + bis_pool_free++; + } + + big_pool_free++; +} + +static void +ble_ll_iso_big_terminate_complete(struct ble_ll_iso_big *big) +{ + struct ble_hci_ev *hci_ev; + struct ble_hci_ev_le_subev_terminate_big_complete *evt; + uint8_t big_handle; + uint8_t reason; + + big_handle = big->handle; + reason = big->term_reason; + + ble_ll_iso_big_free(big); + + hci_ev = ble_transport_alloc_evt(0); + if (!hci_ev) { + BLE_LL_ASSERT(0); + return; + } + hci_ev->opcode = BLE_HCI_EVCODE_LE_META; + hci_ev->length = sizeof(*evt); + + evt = (void *)hci_ev->data; + memset(evt, 0, hci_ev->length); + evt->subev_code = BLE_HCI_LE_SUBEV_TERMINATE_BIG_COMPLETE; + evt->big_handle = big_handle; + evt->reason = reason; + + ble_transport_to_hs_evt(hci_ev); +} + +static void +ble_ll_iso_big_chan_map_update_complete(struct ble_ll_iso_big *big) +{ + memcpy(big->chan_map, big->chan_map_new, BLE_LL_CHAN_MAP_LEN); + big->chan_map_used = ble_ll_utils_chan_map_used_get(big->chan_map); +} + +static void +ble_ll_iso_big_update_event_start(struct ble_ll_iso_big *big) +{ + os_sr_t sr; + + OS_ENTER_CRITICAL(sr); + big->event_start = big->sch.start_time + g_ble_ll_sched_offset_ticks; + big->event_start_us = big->sch.remainder; + OS_EXIT_CRITICAL(sr); +} + +static void +ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) +{ + int rc; + + ble_ll_rfmgmt_release(); + + if (big->big_counter == 0) { + BLE_LL_ASSERT(big == big_pending); + ble_ll_iso_big_hci_evt_complete(); + } + + + big->sch.start_time = big->event_start; + big->sch.remainder = big->event_start_us; + + do { + big->big_counter++; + big->bis_counter += big->bn; + + if (big->control_active && + (big->control_instant == (uint16_t)big->big_counter)) { + switch (big->control_active) { + case BIG_CONTROL_ACTIVE_TERM: + ble_ll_iso_big_terminate_complete(big); + return; + case BIG_CONTROL_ACTIVE_CHAN_MAP: + ble_ll_iso_big_chan_map_update_complete(big); + break; + default: + BLE_LL_ASSERT(0); + break; + } + + big->control_active = 0; + big->cstf = 0; + } + + if (!big->control_active) { + if (big->term_pending) { + big->term_pending = 0; + big->control_active = BIG_CONTROL_ACTIVE_TERM; + } else if (big->chan_map_new_pending) { + memcpy(big->chan_map_new, g_ble_ll_data.chan_map, + BLE_LL_CHAN_MAP_LEN); + big->chan_map_new_pending = 0; + big->control_active = BIG_CONTROL_ACTIVE_CHAN_MAP; + } + + if (big->control_active) { + big->control_instant = big->big_counter + 6; + big->cstf = 1; + big->cssn += 1; + } + } + + /* XXX precalculate some data here? */ + + ble_ll_tmr_add(&big->sch.start_time, &big->sch.remainder, + big->iso_interval * 1250); + big->sch.end_time = big->sch.start_time + + ble_ll_tmr_u2t_up(big->sync_delay) + 1; + big->sch.start_time -= g_ble_ll_sched_offset_ticks; + + if (big->control_active) { + /* XXX fixme */ + big->sch.end_time += 10; + } + + /* XXX this should always succeed since we preempt anything for now */ + rc = ble_ll_sched_iso_big(&big->sch, 0); + assert(rc == 0); + } while (rc < 0); + + ble_ll_iso_big_update_event_start(big); +} + +static void +ble_ll_iso_big_event_done_ev(struct ble_npl_event *ev) +{ + struct ble_ll_iso_big *big; + + big = ble_npl_event_get_arg(ev); + + ble_ll_iso_big_event_done(big); +} + +static void +ble_ll_iso_big_event_done_to_ll(struct ble_ll_iso_big *big) +{ + big_active = NULL; + ble_ll_state_set(BLE_LL_STATE_STANDBY); + ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &big->event_done); +} + +static uint8_t +ble_ll_iso_big_control_pdu_cb(uint8_t *dptr, void *arg, uint8_t *hdr_byte) +{ + struct ble_ll_iso_big *big; + uint8_t len; + + big = arg; + + /* CSTF shall be set to 0 in Control PDU */ + *hdr_byte = 3 | (big->cssn << 2); + + BLE_LL_ASSERT(big->cstf); + BLE_LL_ASSERT(big->control_active); + + if (big->encrypted) { + ble_phy_encrypt_header_mask_set(BLE_LL_PDU_HEADERMASK_BIS); + ble_phy_encrypt_iv_set(big->iv); + ble_phy_encrypt_counter_set(big->bis_counter, 1); + } + + switch (big->control_active) { + case BIG_CONTROL_ACTIVE_CHAN_MAP: + dptr[0] = 0x00; /* BIG_CHANNEL_MAP_IND */ + memcpy(&dptr[1], big->chan_map_new, BLE_LL_CHAN_MAP_LEN); + put_le16(&dptr[6], big->control_instant); + len = 8; + break; + case BIG_CONTROL_ACTIVE_TERM: + dptr[0] = 0x01; /* BIG_TERMINATE_IND */ + dptr[1] = big->term_reason; + put_le16(&dptr[2], big->control_instant); + len = 4; + break; + default: + BLE_LL_ASSERT(0); + len = 0; + break; + } + + return len; +} + +static void +ble_ll_iso_big_control_txend_cb(void *arg) +{ + struct ble_ll_iso_big *big; + + big = arg; + + ble_ll_iso_big_event_done_to_ll(big); +} + +static int +ble_ll_iso_big_control_tx(struct ble_ll_iso_big *big) +{ + uint16_t chan_idx; + uint16_t chan_id; + uint16_t foo, bar; + int rc; + + chan_id = big->ctrl_aa ^ (big->ctrl_aa >> 16); + + chan_idx = ble_ll_utils_dci_iso_event(big->big_counter, chan_id, + &foo, + big->chan_map_used, + big->chan_map, + &bar); + + ble_phy_set_txend_cb(ble_ll_iso_big_control_txend_cb, big); + ble_phy_setchan(chan_idx, big->ctrl_aa, big->crc_init << 8); + + rc = ble_phy_tx(ble_ll_iso_big_control_pdu_cb, big, BLE_PHY_TRANSITION_NONE); + + return rc; +} + +static uint8_t +ble_ll_iso_big_subevent_pdu_cb(uint8_t *dptr, void *arg, uint8_t *hdr_byte) +{ + struct ble_ll_iso_big *big; + struct ble_ll_iso_bis *bis; + int idx; + uint8_t llid; + uint8_t pdu_len; + + big = arg; + bis = big->tx.bis; + + /* Core 5.3, Vol 6, Part B, 4.4.6.6 */ + if (bis->tx.g < big->irc) { + idx = bis->tx.n; + } else { + idx = big->bn * big->pto * (bis->tx.g - big->irc + 1) + bis->tx.n; + } + + if (big->encrypted) { + ble_phy_encrypt_header_mask_set(BLE_LL_PDU_HEADERMASK_BIS); + ble_phy_encrypt_iv_set(bis->iv); + ble_phy_encrypt_counter_set(big->bis_counter + idx, 1); + } + + llid = 0; + pdu_len = big->max_pdu; + /* XXX dummy data for testing */ + memset(dptr, bis->num | (bis->num << 4), pdu_len); + put_be32(dptr, big->big_counter); + put_be32(&dptr[4], big->bis_counter + idx); + dptr[8] = bis->tx.subevent_num; + dptr[9] = bis->tx.g; + dptr[10] = bis->tx.n; + if (bis->tx.g == 0) { + dptr[11] = 'B'; + } else if (bis->tx.g < big->irc) { + dptr[11] = 'R'; + } else { + dptr[11] = 'P'; + } + dptr[12] = 0xff; + + *hdr_byte = llid | (big->cssn << 2) | (big->cstf << 5); + + return pdu_len; +} + +static int +ble_ll_iso_big_subevent_tx(struct ble_ll_iso_big *big) +{ + struct ble_ll_iso_bis *bis; + uint16_t chan_idx; + int to_tx; + int rc; + + bis = big->tx.bis; + + if (bis->tx.subevent_num == 1) { + chan_idx = ble_ll_utils_dci_iso_event(big->big_counter, bis->chan_id, + &bis->tx.prn_sub_lu, + big->chan_map_used, + big->chan_map, + &bis->tx.remap_idx); + } else { + chan_idx = ble_ll_utils_dci_iso_subevent(bis->chan_id, + &bis->tx.prn_sub_lu, + big->chan_map_used, + big->chan_map, + &bis->tx.remap_idx); + } + + ble_phy_setchan(chan_idx, bis->aa, bis->crc_init); + + to_tx = (big->tx.subevents_rem > 1) || big->cstf; + + rc = ble_phy_tx(ble_ll_iso_big_subevent_pdu_cb, big, + to_tx ? BLE_PHY_TRANSITION_TX_TX + : BLE_PHY_TRANSITION_NONE); + return rc; +} + +static void +ble_ll_iso_big_subevent_txend_cb(void *arg) +{ + struct ble_ll_iso_big *big; + struct ble_ll_iso_bis *bis; + int rc; + + big = arg; + bis = big->tx.bis; + + bis->tx.n++; + if (bis->tx.n == big->bn) { + bis->tx.n = 0; + bis->tx.g++; + } + + /* Switch to next BIS if interleaved or all subevents for current BIS were + * transmitted. + */ + if (big->interleaved || (bis->tx.subevent_num == big->nse)) { + bis = STAILQ_NEXT(bis, bis_q_next); + if (!bis) { + bis = STAILQ_FIRST(&big->bis_q); + } + big->tx.bis = bis; + } + + bis->tx.subevent_num++; + big->tx.subevents_rem--; + + if (big->tx.subevents_rem > 0) { + rc = ble_ll_iso_big_subevent_tx(big); + if (rc) { + ble_phy_disable(); + ble_ll_iso_big_event_done_to_ll(big); + } + return; + } + + if (big->cstf) { + rc = ble_ll_iso_big_control_tx(big); + if (rc) { + ble_phy_disable(); + ble_ll_iso_big_event_done_to_ll(big); + } + return; + } + + ble_ll_iso_big_event_done_to_ll(big); +} + +static int +ble_ll_iso_big_event_sched_cb(struct ble_ll_sched_item *sch) +{ + struct ble_ll_iso_big *big; + struct ble_ll_iso_bis *bis; +#if (BLE_LL_BT5_PHY_SUPPORTED == 1) + uint8_t phy_mode; +#endif + int rc; + + big = sch->cb_arg; + + ble_ll_state_set(BLE_LL_STATE_BIG); + big_active = big; + + ble_ll_whitelist_disable(); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) + ble_phy_resolv_list_disable(); +#endif +#if (BLE_LL_BT5_PHY_SUPPORTED == 1) + phy_mode = ble_ll_phy_to_phy_mode(big->phy, 0); + ble_phy_mode_set(phy_mode, phy_mode); +#endif + + BLE_LL_ASSERT(!big->framed); + + /* XXX calculate this in advance at the end of previous event? */ + big->tx.subevents_rem = big->num_bis * big->nse; + STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) { + bis->tx.subevent_num = 0; + bis->tx.n = 0; + bis->tx.g = 0; + } + + /* Select 1st BIS for transmission */ + big->tx.bis = STAILQ_FIRST(&big->bis_q); + big->tx.bis->tx.subevent_num = 1; + + if (big->interleaved) { + ble_phy_tifs_txtx_set(big->bis_spacing, 0); + } else { + ble_phy_tifs_txtx_set(big->sub_interval, 0); + } + + rc = ble_phy_tx_set_start_time(sch->start_time + g_ble_ll_sched_offset_ticks, + sch->remainder); + if (rc) { + ble_phy_disable(); + ble_ll_iso_big_event_done_to_ll(big); + return BLE_LL_SCHED_STATE_DONE; + } + + ble_phy_set_txend_cb(ble_ll_iso_big_subevent_txend_cb, big); + + if (big->encrypted) { + ble_phy_encrypt_enable(big->gsk); + } else { + ble_phy_encrypt_disable(); + } + + rc = ble_ll_iso_big_subevent_tx(big); + if (rc) { + ble_phy_disable(); + ble_ll_iso_big_event_done_to_ll(big); + return BLE_LL_SCHED_STATE_DONE; + } + + return BLE_LL_SCHED_STATE_RUNNING; +} + +static void +ble_ll_iso_big_calculate_gsk(struct ble_ll_iso_big *big, + const uint8_t *broadcast_code) +{ + static const uint8_t big1[16] = {0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x42, 0x49, 0x47, 0x31}; + static const uint8_t big2[4] = {0x42, 0x49, 0x47, 0x32}; + static const uint8_t big3[4] = {0x42, 0x49, 0x47, 0x33}; + uint8_t code[16]; + uint8_t igltk[16]; + uint8_t gltk[16]; + + /* broadcast code is lsb-first in hci, we need msb-first */ + swap_buf(code, broadcast_code, 16); + + ble_ll_rand_data_get(big->gskd, sizeof(big->gskd)); + + ble_ll_crypto_h7(big1, code, igltk); + ble_ll_crypto_h6(igltk, big2, gltk); + ble_ll_crypto_h8(gltk, big->gskd, big3, big->gsk); + + /* need gskd for biginfo, i.e. lsb-first */ + swap_in_place(big->gskd, 16); +} + +static void +ble_ll_iso_big_calculate_iv(struct ble_ll_iso_big *big) +{ + struct ble_ll_iso_bis *bis; + uint8_t *aa; + + ble_ll_rand_data_get(big->giv, sizeof(big->giv)); + STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) { + memcpy(&bis->iv[4], &big->giv[4], 4); + aa = (uint8_t *)&bis->aa; + bis->iv[0] = big->giv[0] ^ aa[0]; + bis->iv[1] = big->giv[1] ^ aa[1]; + bis->iv[2] = big->giv[2] ^ aa[2]; + bis->iv[3] = big->giv[3] ^ aa[3]; + } + + memcpy(&big->iv[4], &big->giv[4], 4); + aa = (uint8_t *)&big->ctrl_aa; + big->iv[0] = big->giv[0] ^ aa[0]; + big->iv[1] = big->giv[1] ^ aa[1]; + big->iv[2] = big->giv[2] ^ aa[2]; + big->iv[3] = big->giv[3] ^ aa[3]; +} + +static int +ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, + struct big_params *bp) +{ + struct ble_ll_iso_big *big = NULL; + struct ble_ll_iso_bis *bis; + uint32_t seed_aa; + uint8_t pte; + uint8_t gc; + uint8_t idx; + int rc; + + if ((big_pool_free == 0) || (bis_pool_free < num_bis)) { + return -ENOMEM; + } + + /* Find free BIG */ + for (idx = 0; idx < BIG_POOL_SIZE; idx++) { + if (!big && big_pool[idx].handle == BIG_HANDLE_INVALID) { + big = &big_pool[idx]; + } + if (big_pool[idx].handle == big_handle) { + return -EALREADY; + } + } + + BLE_LL_ASSERT(big); + + /* TODO find valid advertising instance */ + + big->handle = big_handle; + + big->crc_init = ble_ll_rand(); + memcpy(big->chan_map, g_ble_ll_data.chan_map, BLE_LL_CHAN_MAP_LEN); + big->chan_map_used = g_ble_ll_data.chan_map_used; + + big->big_counter = 0; + big->bis_counter = 0; + + big->cstf = 0; + big->cssn = 0; + big->control_active = 0; + big->control_instant = 0; + big->chan_map_new_pending = 0; + big->term_pending = 0; + big->term_reason = 0; + + /* Calculate number of additional events for pre-transmissions */ + /* Core 5.3, Vol 6, Part B, 4.4.6.6 */ + gc = bp->nse / bp->bn; + (void)pte; + if (bp->irc == gc) { + pte = 0; + } else { + pte = bp->pto * (gc - bp->irc); + } + + /* Allocate BISes */ + STAILQ_INIT(&big->bis_q); + big->num_bis = 0; + for (idx = 0; (big->num_bis < num_bis) && (idx < BIS_POOL_SIZE); idx++) { + bis = &bis_pool[idx]; + if (bis->big) { + continue; + } + + big->num_bis++; + STAILQ_INSERT_TAIL(&big->bis_q, bis, bis_q_next); + + bis->big = big; + bis->num = big->num_bis; + bis->crc_init = (big->crc_init << 8) | (big->num_bis); + + BLE_LL_ASSERT(!big->framed); + } + + big_pool_free--; + bis_pool_free -= num_bis; + + /* Calculate AA for each BIS and BIG Control. We have to repeat this process + * until all AAs are valid. + */ + do { + rc = 0; + + seed_aa = ble_ll_utils_calc_seed_aa(); + big->ctrl_aa = ble_ll_utils_calc_big_aa(seed_aa, 0); + + if (!ble_ll_utils_verify_aa(big->ctrl_aa)) { + continue; + } + + rc = 1; + + STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) { + bis->aa = ble_ll_utils_calc_big_aa(seed_aa, bis->num); + if (!ble_ll_utils_verify_aa(bis->aa)) { + rc = 0; + break; + } + bis->chan_id = bis->aa ^ (bis->aa >> 16); + } + } while (rc == 0); + + big->bn = bp->bn; + big->pto = bp->pto; + big->irc = bp->irc; + big->nse = bp->nse; + big->interleaved = bp->interleaved; + big->framed = bp->framed; + big->encrypted = bp->encrypted; + big->sdu_interval = bp->sdu_interval; + big->iso_interval = bp->iso_interval; + big->phy = bp->phy; + big->max_pdu = bp->max_pdu; + big->max_sdu = bp->max_sdu; + /* Core 5.3, Vol 6, Part B, 4.4.6.3 */ + big->mpt = ble_ll_pdu_us(big->max_pdu + (big->encrypted ? 4 : 0), + ble_ll_phy_to_phy_mode(big->phy, + BLE_HCI_LE_PHY_CODED_S8_PREF)); + + /* Core 5.3, Vol 6, Part B, 4.4.6.4 */ + if (big->interleaved) { + big->bis_spacing = big->mpt + BLE_LL_MSS; + big->sub_interval = big->num_bis * big->bis_spacing; + } else { + big->sub_interval = big->mpt + BLE_LL_MSS; + big->bis_spacing = big->nse * big->sub_interval; + } + /* Core 5.3, Vol 6, Part B, 4.4.6.5 */ + big->sync_delay = (big->num_bis - 1) * big->bis_spacing + + (big->nse - 1) * big->sub_interval + big->mpt; + + /* Reset PTO if pre-transmissions won't be used */ + big->gc = gc; + if (big->irc == gc) { + big->pto = 0; + } + + if (big->encrypted) { + ble_ll_iso_big_calculate_gsk(big, bp->broadcast_code); + ble_ll_iso_big_calculate_iv(big); + } + + /* For now we will schedule complete event as single item. This allows for + * shortest possible subevent space (150us) but can create sequence of long + * events that will block scheduler from other activities. To mitigate this + * we use preempt_none strategy so scheudling is opportunistic and depending + * on other activities this may create gaps in stream. + * Eventually we should allow for some more robust scheduling, e.g. per-BIS + * for sequential arrangement or per-subevent for interleaved, or event + * per-BIS-subevent but this requires larger subevent space since 150us is + * not enough for some phys to run scheduler item. + */ + + /* Schedule 1st event a bit in future */ + /* FIXME schedule 6ms in the future to avoid conflict with periodic + * advertising when both are started at the same time; we should + * select this value in some smart way later... + */ + big->sch.start_time = ble_ll_tmr_get() + ble_ll_tmr_u2t(6000); + big->sch.remainder = 0; + big->sch.end_time = big->sch.start_time + + ble_ll_tmr_u2t_up(big->sync_delay) + 1; + big->sch.start_time -= g_ble_ll_sched_offset_ticks; + + rc = ble_ll_sched_iso_big(&big->sch, 1); + if (rc < 0) { + ble_ll_iso_big_free(big); + return -EFAULT; + } + + ble_ll_iso_big_update_event_start(big); + + big_pending = big; + + return 0; +} + +static int +ble_ll_iso_big_terminate(uint8_t big_handle, uint8_t reason) +{ + struct ble_ll_iso_big *big = NULL; + unsigned idx; + + for (idx = 0; idx < BIG_POOL_SIZE; idx++) { + if (big_pool[idx].handle == big_handle) { + big = &big_pool[idx]; + break; + } + } + + if (!big) { + return -ENOENT; + } + + big->term_reason = reason; + big->term_pending = 1; + + return 0; +} + +void +ble_ll_iso_big_chan_map_update(void) +{ + struct ble_ll_iso_big *big; + int idx; + + for (idx = 0; idx < BIG_POOL_SIZE; idx++) { + big = &big_pool[idx]; + + if (big->handle == BIG_HANDLE_INVALID) { + continue; + } + + big->chan_map_new_pending = 1; + } +} + +void +ble_ll_iso_big_halt(void) +{ + if (big_active) { + ble_ll_iso_big_event_done_to_ll(big_active); + } +} + +void +ble_ll_iso_big_hci_evt_complete(void) +{ + struct ble_ll_iso_big *big; + struct ble_ll_iso_bis *bis; + struct ble_hci_ev_le_subev_create_big_complete *evt; + struct ble_hci_ev *hci_ev; + uint8_t idx; + + big = big_pending; + big_pending = NULL; + + if (!big) { + return; + } + + hci_ev = ble_transport_alloc_evt(0); + if (!hci_ev) { + BLE_LL_ASSERT(0); + /* XXX should we retry later? */ + return; + } + hci_ev->opcode = BLE_HCI_EVCODE_LE_META; + hci_ev->length = sizeof(*evt) + big->num_bis * sizeof(evt->conn_handle[0]); + + evt = (void *)hci_ev->data; + memset(evt, 0, hci_ev->length); + evt->subev_code = BLE_HCI_LE_SUBEV_CREATE_BIG_COMPLETE; + evt->status = 0x00; + + evt->big_handle = big->handle; + put_le24(evt->big_sync_delay, big->sync_delay); + /* Core 5.3, Vol 6, Part G, 3.2.2 */ + put_le24(evt->transport_latency_big, + big->sync_delay + + (big->pto * (big->nse / big->bn - big->irc) + 1) * big->iso_interval * 1250 - + big->sdu_interval); + evt->phy = big->phy; + evt->nse = big->nse; + evt->bn = big->bn; + evt->pto = big->pto; + evt->irc = big->irc; + evt->max_pdu = htole16(big->max_pdu); + evt->iso_interval = htole16(big->iso_interval); + evt->num_bis = big->num_bis; + + idx = 0; + STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) { + evt->conn_handle[idx] = htole16(bis->conn_handle); + idx++; + } + + ble_ll_hci_event_send(hci_ev); +} + +int +ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len) +{ + /* TODO implement :) */ + + return BLE_ERR_UNSPECIFIED; +} + +int +ble_ll_iso_big_hci_create_test(const uint8_t *cmdbuf, uint8_t len) +{ + const struct ble_hci_le_create_big_test_cp *cmd = (void *)cmdbuf; + struct big_params bp; + uint32_t iso_interval_us; + int rc; + + if (len != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (!IN_RANGE(cmd->big_handle, 0x00, 0xef) || + !IN_RANGE(cmd->adv_handle, 0x00, 0xef) || + !IN_RANGE(cmd->num_bis, 0x01, 0x1f) || + !IN_RANGE(get_le24(cmd->sdu_interval), 0x0000ff, 0x0fffff) || + !IN_RANGE(le16toh(cmd->iso_interval), 0x0004, 0x0c80) || + !IN_RANGE(cmd->nse, 0x01, 0x1f) || + !IN_RANGE(le16toh(cmd->max_sdu), 0x0001, 0x0fff) || + !IN_RANGE(le16toh(cmd->max_pdu), 0x0001, 0x00fb) || + /* phy */ + (cmd->packing > 1) || (cmd->framing > 1) || + !IN_RANGE(cmd->bn, 0x01, 0x07) || + !IN_RANGE(cmd->irc, 0x01, 0x0f) || + !IN_RANGE(cmd->pto, 0x00, 0x0f) || + (cmd->encryption) > 1) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + bp.nse = cmd->nse; + bp.bn = cmd->bn; + bp.irc = cmd->irc; + bp.pto = cmd->pto; + bp.sdu_interval = get_le24(cmd->sdu_interval); + bp.iso_interval = le16toh(cmd->iso_interval); + bp.max_sdu = le16toh(cmd->max_sdu); + bp.max_pdu = le16toh(cmd->max_pdu); + /* TODO verify phy */ + if (cmd->phy & BLE_HCI_LE_PHY_2M_PREF_MASK) { + bp.phy = BLE_PHY_2M; + } else if (cmd->phy & BLE_HCI_LE_PHY_1M_PREF_MASK) { + bp.phy = BLE_PHY_1M; + } else { + bp.phy = BLE_PHY_CODED; + } + bp.interleaved = cmd->packing; + bp.framed = cmd->framing; + bp.encrypted = cmd->encryption; + memcpy(bp.broadcast_code, cmd->broadcast_code, 16); + + if (bp.nse % bp.bn) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + iso_interval_us = bp.iso_interval * 1250; + + if (!bp.framed) { + /* sdu_interval shall be an integer multiple of iso_interval */ + if (iso_interval_us % bp.sdu_interval) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* bn shall be an integer multiple of (iso_interval / sdu_interval) */ + if (bp.bn % (iso_interval_us / bp.sdu_interval)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + } + + rc = ble_ll_iso_big_create(cmd->big_handle, cmd->adv_handle, cmd->num_bis, + &bp); + switch (rc) { + case 0: + break; + case -EINVAL: + return BLE_ERR_INV_HCI_CMD_PARMS; + case -ENOMEM: + return BLE_ERR_CONN_REJ_RESOURCES; + case -ENOENT: + return BLE_ERR_UNK_ADV_INDENT; + default: + return BLE_ERR_UNSPECIFIED; + } + + return 0; +} + +int +ble_ll_iso_big_hci_terminate(const uint8_t *cmdbuf, uint8_t len) +{ + const struct ble_hci_le_terminate_big_cp *cmd = (void *)cmdbuf; + int err; + + err = ble_ll_iso_big_terminate(cmd->big_handle, cmd->reason); + switch (err) { + case 0: + break; + case -ENOENT: + return BLE_ERR_UNK_ADV_INDENT; + default: + return BLE_ERR_UNSPECIFIED; + } + + return 0; +} + +void +ble_ll_iso_big_init(void) +{ + struct ble_ll_iso_big *big; + struct ble_ll_iso_bis *bis; + uint8_t idx; + + memset(big_pool, 0, sizeof(big_pool)); + memset(bis_pool, 0, sizeof(bis_pool)); + + for (idx = 0; idx < BIG_POOL_SIZE; idx++) { + big = &big_pool[idx]; + + big->handle = BIG_HANDLE_INVALID; + + big->sch.sched_type = BLE_LL_SCHED_TYPE_BIG; + big->sch.sched_cb = ble_ll_iso_big_event_sched_cb; + big->sch.cb_arg = big; + + ble_npl_event_init(&big->event_done, ble_ll_iso_big_event_done_ev, big); + } + + for (idx = 0; idx < BIS_POOL_SIZE; idx++) { + bis = &bis_pool[idx]; + bis->conn_handle = BLE_LL_CONN_HANDLE(BLE_LL_CONN_HANDLE_TYPE_BIS, idx); + } + + big_pool_free = ARRAY_SIZE(big_pool); + bis_pool_free = ARRAY_SIZE(bis_pool); +} + +void +ble_ll_iso_big_reset(void) +{ + struct ble_ll_iso_big *big; + int idx; + + for (idx = 0; idx < BIG_POOL_SIZE; idx++) { + big = &big_pool[idx]; + ble_ll_iso_big_free(big); + } + + ble_ll_iso_big_init(); +} + +#endif /* BLE_LL_ISO_BROADCASTER */ diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index b31d7818e6..c4cbe14258 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -32,6 +32,7 @@ #include "controller/ble_ll_trace.h" #include "controller/ble_ll_tmr.h" #include "controller/ble_ll_sync.h" +#include "controller/ble_ll_iso_big.h" #if MYNEWT_VAL(BLE_LL_EXT) #include "controller/ble_ll_ext.h" #endif @@ -171,6 +172,12 @@ ble_ll_sched_preempt(struct ble_ll_sched_item *sch, #endif #endif #endif +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + case BLE_LL_SCHED_TYPE_BIG: + /* FIXME sometimes it may be useful to preempt... */ + BLE_LL_ASSERT(0); + break; +#endif #if MYNEWT_VAL(BLE_LL_EXT) case BLE_LL_SCHED_TYPE_EXTERNAL: ble_ll_ext_sched_removed(entry); @@ -883,6 +890,30 @@ ble_ll_sched_adv_resched_pdu(struct ble_ll_sched_item *sch) return rc; } +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) +int +ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first) +{ + os_sr_t sr; + int rc; + + OS_ENTER_CRITICAL(sr); + + if (first) { + rc = ble_ll_sched_insert(sch, BLE_LL_SCHED_MAX_DELAY_ANY, preempt_none); + } else { + /* XXX provide better strategy for preemption */ + rc = ble_ll_sched_insert(sch, 0, preempt_any); + } + + OS_EXIT_CRITICAL(sr); + + ble_ll_sched_restart(); + + return rc; +} +#endif /* BLE_LL_ISO_BROADCASTER */ + /** * Remove a schedule element * @@ -1023,6 +1054,11 @@ ble_ll_sched_execute_item(struct ble_ll_sched_item *sch) ble_ll_conn_event_halt(); break; #endif +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + case BLE_LL_STATE_BIG: + ble_ll_iso_big_halt(); + break; +#endif #if MYNEWT_VAL(BLE_LL_EXT) case BLE_LL_STATE_EXTERNAL: ble_ll_ext_halt(); diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index a7e6af030a..f02b04dfe4 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -472,6 +472,23 @@ syscfg.defs: Enable support for runtime antenna selection in FEM. value: 0 + BLE_LL_ISO: + description: > + Enable support for isochronous data. + This enables common code (e.g. ISOAL) for all types of isochronous + data, particular ISO features have to be enabled separately. + restrictions: + - (BLE_VERSION >= 52) if 1 + value: 0 + state: experimental + BLE_LL_ISO_BROADCASTER: + description: > + Enable support for Isochronous Broadcasting state. + restrictions: + - BLE_LL_ISO if 1 + value: 0 + state: experimental + BLE_LL_SYSINIT_STAGE: description: > Sysinit stage for the NimBLE controller. From 6349d771d5547c567e6c6e653c67b685166bf1e3 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 31 Jan 2023 14:27:20 +0100 Subject: [PATCH 0708/1333] nimble/ll: Add BIGInfo to periodic adv train This enables BIGInfo in periodic advertising which allows receiver to synchronize with BIG. --- .../include/controller/ble_ll_adv.h | 14 ++ .../include/controller/ble_ll_iso_big.h | 6 + nimble/controller/src/ble_ll_adv.c | 98 +++++++++++++ nimble/controller/src/ble_ll_iso_big.c | 130 +++++++++++++++++- 4 files changed, 247 insertions(+), 1 deletion(-) diff --git a/nimble/controller/include/controller/ble_ll_adv.h b/nimble/controller/include/controller/ble_ll_adv.h index 4afaadd002..ba17ed5e07 100644 --- a/nimble/controller/include/controller/ble_ll_adv.h +++ b/nimble/controller/include/controller/ble_ll_adv.h @@ -199,6 +199,20 @@ int ble_ll_adv_periodic_enable(const uint8_t *cmdbuf, uint8_t len); int ble_ll_adv_periodic_set_info_transfer(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); +/* Get advertising instance with periodic advertising configured */ +struct ble_ll_adv_sm *ble_ll_adv_sync_get(uint8_t handle); + +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) +struct ble_ll_iso_big; + +/* Add BIG to periodic advertising instance */ +int ble_ll_adv_sync_big_add(struct ble_ll_adv_sm *advsm, + struct ble_ll_iso_big *big); +/* Remove BIG from periodic advertising instance */ +int ble_ll_adv_sync_big_remove(struct ble_ll_adv_sm *advsm, + struct ble_ll_iso_big *big); +#endif /* BLE_LL_ISO_BROADCASTER */ + /* Called to notify adv code about RPA rotation */ void ble_ll_adv_rpa_timeout(void); diff --git a/nimble/controller/include/controller/ble_ll_iso_big.h b/nimble/controller/include/controller/ble_ll_iso_big.h index 1756fd2641..c9052126cb 100644 --- a/nimble/controller/include/controller/ble_ll_iso_big.h +++ b/nimble/controller/include/controller/ble_ll_iso_big.h @@ -26,6 +26,12 @@ extern "C" { #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) +struct ble_ll_iso_big; + +int ble_ll_iso_big_biginfo_copy(struct ble_ll_iso_big *big, uint8_t *dptr, + uint32_t base_ticks, uint8_t base_rem_us); +int ble_ll_iso_big_biginfo_len(struct ble_ll_iso_big *big); + void ble_ll_iso_big_chan_map_update(void); void ble_ll_iso_big_halt(void); diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index c7f16e1104..7056c8de93 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -16,6 +16,8 @@ * specific language governing permissions and limitations * under the License. */ + +#include #include #include #include @@ -40,6 +42,7 @@ #include "controller/ble_ll_trace.h" #include "controller/ble_ll_utils.h" #include "controller/ble_ll_rfmgmt.h" +#include "controller/ble_ll_iso_big.h" #include "ble_ll_conn_priv.h" #include "ble_ll_priv.h" @@ -77,6 +80,9 @@ struct ble_ll_adv_sync { uint8_t data_len; uint8_t payload_len; uint8_t auxptr_zero; +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + struct ble_ll_iso_big *big; +#endif }; /* @@ -174,6 +180,11 @@ struct ble_ll_adv_sm uint16_t periodic_event_cntr_last_sent; #endif #endif + +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + struct ble_ll_iso_big *big; +#endif /* BLE_LL_ISO_BROADCASTER */ + #endif }; @@ -2107,6 +2118,9 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) uint8_t adv_mode; uint8_t pdu_type; uint8_t ext_hdr_len; +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + uint8_t biginfo_len; +#endif uint32_t offset; advsm = pducb_arg; @@ -2126,10 +2140,17 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) dptr += 1; /* only put flags if needed */ +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + if (sync->ext_hdr_flags || sync->big) { + dptr[0] = sync->ext_hdr_flags; + dptr += 1; + } +#else if (sync->ext_hdr_flags) { dptr[0] = sync->ext_hdr_flags; dptr += 1; } +#endif if (sync->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { if (!SYNC_NEXT(advsm)->sch.enqueued) { @@ -2157,6 +2178,18 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) dptr += BLE_LL_EXT_ADV_TX_POWER_SIZE; } +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + if (advsm->big) { + biginfo_len = ble_ll_iso_big_biginfo_copy(advsm->big, dptr, + sync->sch.start_time + + g_ble_ll_sched_offset_ticks, + sync->sch.remainder); + BLE_LL_ASSERT(biginfo_len > 0); + + dptr += biginfo_len; + } +#endif + if (sync->data_len) { os_mbuf_copydata(advsm->periodic_adv_data, sync->data_offset, sync->data_len, dptr); @@ -2316,9 +2349,25 @@ ble_ll_adv_sync_calculate(struct ble_ll_adv_sm *advsm, * how Aux calculate works and this also make it easier to add more fields * into flags if needed in future */ +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + sync->big = advsm->big; + /* If BIG is present flags will always be also present even if none is set + * to indicate ACAD is present. + */ + if (sync->ext_hdr_flags || sync->big) { + ext_hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE; + } +#else if (sync->ext_hdr_flags) { ext_hdr_len += BLE_LL_EXT_ADV_FLAGS_SIZE; } +#endif + +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + if (advsm->big) { + ext_hdr_len += ble_ll_iso_big_biginfo_len(advsm->big); + } +#endif /* AdvData always */ sync->data_len = MIN(BLE_LL_MAX_PAYLOAD_LEN - ext_hdr_len, rem_data_len); @@ -5242,6 +5291,55 @@ ble_ll_adv_sm_init(struct ble_ll_adv_sm *advsm) advsm->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY; } +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) +struct ble_ll_adv_sm * +ble_ll_adv_sync_get(uint8_t handle) +{ + struct ble_ll_adv_sm *advsm; + + advsm = ble_ll_adv_sm_find_configured(handle); + if (!advsm) { + return NULL; + } + + if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_CONFIGURED)) { + return NULL; + } + + return advsm; +} + +int +ble_ll_adv_sync_big_add(struct ble_ll_adv_sm *advsm, + struct ble_ll_iso_big *big) +{ + if (!(advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_CONFIGURED)) { + return -EINVAL; + } + + if (advsm->big && (advsm->big != big)) { + return -EBUSY; + } + + advsm->big = big; + + return 0; +} + +int +ble_ll_adv_sync_big_remove(struct ble_ll_adv_sm *advsm, + struct ble_ll_iso_big *big) +{ + if (advsm->big != big) { + return -EINVAL; + } + + advsm->big = NULL; + + return 0; +} +#endif /* BLE_LL_ISO_BROADCASTER */ + /** * Initialize the advertising functionality of a BLE device. This should * be called once on initialization diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 20e5ff07bc..594ff4a1dd 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -90,6 +91,8 @@ struct big_params { }; struct ble_ll_iso_big { + struct ble_ll_adv_sm *advsm; + uint8_t handle; uint8_t num_bis; uint16_t iso_interval; @@ -119,6 +122,8 @@ struct ble_ll_iso_big { uint8_t chan_map[BLE_LL_CHAN_MAP_LEN]; uint8_t chan_map_used; + uint8_t biginfo[33]; + uint64_t big_counter; uint64_t bis_counter; @@ -155,6 +160,113 @@ static uint8_t bis_pool_free = BIS_POOL_SIZE; static struct ble_ll_iso_big *big_pending; static struct ble_ll_iso_big *big_active; +static void +ble_ll_iso_big_biginfo_calc(struct ble_ll_iso_big *big, uint32_t seed_aa) +{ + uint8_t *buf; + + buf = big->biginfo; + + /* big_offset, big_offset_units, iso_interval, num_bis */ + put_le32(buf, (big->num_bis << 27) | (big->iso_interval << 15)); + buf += 4; + + /* nse, bn */ + *(uint8_t *)buf = (big->bn << 5) | (big->nse); + buf += 1; + + /* sub_interval, pto */ + put_le24(buf,(big->pto << 20) | (big->sub_interval)); + buf += 3; + + /* bis_spacing, irc */ + put_le24(buf, (big->irc << 20) | (big->bis_spacing)); + buf += 3; + + /* max_pdu, rfu */ + put_le16(buf, big->max_pdu); + buf += 2; + + /* seed_access_address */ + put_le32(buf, seed_aa); + buf += 4; + + /* sdu_interval, max_sdu */ + put_le32(buf, (big->max_sdu << 20) | (big->sdu_interval)); + buf += 4; + + /* base_crc_init */ + put_le16(buf, big->crc_init); + buf += 2; + + /* chm, phy */ + memcpy(buf, big->chan_map, 5); + buf[4] |= (big->phy - 1) << 5; + buf += 5; + + /* bis_payload_cnt, framing */ + memset(buf, 0x00, 5); +} + +int +ble_ll_iso_big_biginfo_copy(struct ble_ll_iso_big *big, uint8_t *dptr, + uint32_t base_ticks, uint8_t base_rem_us) +{ + uint8_t *dptr_start; + uint64_t counter; + uint32_t offset_us; + uint32_t offset; + uint32_t d_ticks; + uint8_t d_rem_us; + + dptr_start = dptr; + counter = big->bis_counter; + + d_ticks = big->event_start - base_ticks; + d_rem_us = big->event_start_us; + ble_ll_tmr_sub(&d_ticks, &d_rem_us, base_rem_us); + + offset_us = ble_ll_tmr_t2u(d_ticks) + d_rem_us; + if (offset_us <= 600) { + counter += big->bn; + offset_us += big->iso_interval * 1250; + } + if (offset_us >= 491460) { + offset = 0x4000 | (offset_us / 300); + } else { + offset = offset_us / 30; + } + + *dptr++ = ble_ll_iso_big_biginfo_len(big) - 1; + *dptr++ = 0x2c; + + memcpy(dptr, big->biginfo, 33); + put_le32(dptr, get_le32(dptr) | (offset & 0x7fff)); + dptr += 28; + + *dptr++ = counter & 0xff; + *dptr++ = (counter >> 8) & 0xff; + *dptr++ = (counter >> 16) & 0xff; + *dptr++ = (counter >> 24) & 0xff; + *dptr++ = (counter >> 32) & 0xff; + + if (big->encrypted) { + memcpy(dptr, big->giv, 8); + dptr += 8; + memcpy(dptr, big->gskd, 16); + dptr += 16; + } + + return dptr - dptr_start; +} + +int +ble_ll_iso_big_biginfo_len(struct ble_ll_iso_big *big) +{ + return 2 + sizeof(big->biginfo) + + (big->encrypted ? sizeof(big->giv) + sizeof(big->gskd) : 0); +} + static void ble_ll_iso_big_free(struct ble_ll_iso_big *big) { @@ -655,6 +767,7 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, { struct ble_ll_iso_big *big = NULL; struct ble_ll_iso_bis *bis; + struct ble_ll_adv_sm *advsm; uint32_t seed_aa; uint8_t pte; uint8_t gc; @@ -677,8 +790,16 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, BLE_LL_ASSERT(big); - /* TODO find valid advertising instance */ + advsm = ble_ll_adv_sync_get(adv_handle); + if (!advsm) { + return -ENOENT; + } + + if (ble_ll_adv_sync_big_add(advsm, big) < 0) { + return -ENOENT; + } + big->advsm = advsm; big->handle = big_handle; big->crc_init = ble_ll_rand(); @@ -793,6 +914,8 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, ble_ll_iso_big_calculate_iv(big); } + ble_ll_iso_big_biginfo_calc(big, seed_aa); + /* For now we will schedule complete event as single item. This allows for * shortest possible subevent space (150us) but can create sequence of long * events that will block scheduler from other activities. To mitigate this @@ -845,6 +968,11 @@ ble_ll_iso_big_terminate(uint8_t big_handle, uint8_t reason) return -ENOENT; } + /* Not sure if this is correct, but let's remove BIGInfo now since there's + * no point for peer to syncing to a BIG that will be disconnected soon. + */ + ble_ll_adv_sync_big_remove(big->advsm, big); + big->term_reason = reason; big->term_pending = 1; From ca043593a9e85b7ccb281abee51df2148c22672d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 18 Mar 2022 21:06:55 +0100 Subject: [PATCH 0709/1333] nimble/transport: Add ISO support This adds support for HCI ISO Data packets to UART H4, nRF5340 IPC and native transport. The default ISO buffers count is set to 0 as it will disable ISO support by default. --- .../hci_h4/include/nimble/transport/hci_h4.h | 2 + nimble/transport/common/hci_h4/src/hci_h4.c | 14 ++++ .../include/nimble/transport/hci_ipc.h | 1 + nimble/transport/common/hci_ipc/src/hci_ipc.c | 15 ++++ nimble/transport/include/nimble/transport.h | 4 ++ .../include/nimble/transport/monitor.h | 12 ++++ .../transport/include/nimble/transport_impl.h | 2 + .../transport/nrf5340/src/nrf5340_ble_hci.c | 35 ++++++++++ nimble/transport/src/monitor.c | 16 +++++ nimble/transport/src/monitor_priv.h | 2 + nimble/transport/src/transport.c | 69 +++++++++++++++++++ nimble/transport/syscfg.yml | 21 ++++++ nimble/transport/uart/src/hci_uart.c | 30 ++++++++ 13 files changed, 223 insertions(+) diff --git a/nimble/transport/common/hci_h4/include/nimble/transport/hci_h4.h b/nimble/transport/common/hci_h4/include/nimble/transport/hci_h4.h index 139160a545..6ad083a05f 100644 --- a/nimble/transport/common/hci_h4/include/nimble/transport/hci_h4.h +++ b/nimble/transport/common/hci_h4/include/nimble/transport/hci_h4.h @@ -31,11 +31,13 @@ typedef void *(hci_h4_alloc_cmd)(void); typedef void *(hci_h4_alloc_evt)(int); typedef struct os_mbuf *(hci_h4_alloc_acl)(void); +typedef struct os_mbuf *(hci_h4_alloc_iso)(void); struct hci_h4_allocators { hci_h4_alloc_cmd *cmd; hci_h4_alloc_acl *acl; hci_h4_alloc_evt *evt; + hci_h4_alloc_iso *iso; }; extern const struct hci_h4_allocators hci_h4_allocs_from_ll; diff --git a/nimble/transport/common/hci_h4/src/hci_h4.c b/nimble/transport/common/hci_h4/src/hci_h4.c index cb09134296..ea30f4293b 100644 --- a/nimble/transport/common/hci_h4/src/hci_h4.c +++ b/nimble/transport/common/hci_h4/src/hci_h4.c @@ -39,6 +39,7 @@ const struct hci_h4_allocators hci_h4_allocs_from_ll = { const struct hci_h4_allocators hci_h4_allocs_from_hs = { .cmd = ble_transport_alloc_cmd, .acl = ble_transport_alloc_acl_from_hs, + .iso = ble_transport_alloc_iso_from_hs, }; struct hci_h4_input_buffer { @@ -58,6 +59,7 @@ hci_h4_frame_start(struct hci_h4_sm *rxs, uint8_t pkt_type) rxs->min_len = 3; break; case HCI_H4_ACL: + case HCI_H4_ISO: rxs->min_len = 4; break; case HCI_H4_EVT: @@ -159,6 +161,16 @@ hci_h4_sm_w4_header(struct hci_h4_sm *h4sm, struct hci_h4_input_buffer *ib) h4sm->exp_len = h4sm->hdr[1] + 2; break; + case HCI_H4_ISO: + assert(h4sm->allocs && h4sm->allocs->iso); + h4sm->om = h4sm->allocs->iso(); + if (!h4sm->om) { + return -1; + } + + os_mbuf_append(h4sm->om, h4sm->hdr, h4sm->len); + h4sm->exp_len = (get_le16(&h4sm->hdr[2]) & 0x7fff) + 4; + break; default: assert(0); break; @@ -185,6 +197,7 @@ hci_h4_sm_w4_payload(struct hci_h4_sm *h4sm, } break; case HCI_H4_ACL: + case HCI_H4_ISO: assert(h4sm->om); mbuf_len = OS_MBUF_PKTLEN(h4sm->om); @@ -230,6 +243,7 @@ hci_h4_sm_completed(struct hci_h4_sm *h4sm) } break; case HCI_H4_ACL: + case HCI_H4_ISO: if (h4sm->om) { assert(h4sm->frame_cb); rc = h4sm->frame_cb(h4sm->pkt_type, h4sm->om); diff --git a/nimble/transport/common/hci_ipc/include/nimble/transport/hci_ipc.h b/nimble/transport/common/hci_ipc/include/nimble/transport/hci_ipc.h index 2f84f68f14..551fb93d4c 100644 --- a/nimble/transport/common/hci_ipc/include/nimble/transport/hci_ipc.h +++ b/nimble/transport/common/hci_ipc/include/nimble/transport/hci_ipc.h @@ -27,6 +27,7 @@ #define HCI_IPC_TYPE_EVT 0x04 #define HCI_IPC_TYPE_EVT_DISCARDABLE 0x05 #define HCI_IPC_TYPE_EVT_IN_CMD 0x06 +#define HCI_IPC_TYPE_ISO 0x07 struct __attribute__((packed)) hci_ipc_hdr { uint8_t type; diff --git a/nimble/transport/common/hci_ipc/src/hci_ipc.c b/nimble/transport/common/hci_ipc/src/hci_ipc.c index fafbacc3d7..613c9ce153 100644 --- a/nimble/transport/common/hci_ipc/src/hci_ipc.c +++ b/nimble/transport/common/hci_ipc/src/hci_ipc.c @@ -58,6 +58,13 @@ hci_ipc_alloc(struct hci_ipc_sm *sm) sm->buf = ble_transport_alloc_cmd(); break; #endif + case HCI_IPC_TYPE_ISO: +#if MYNEWT_VAL(BLE_CONTROLLER) + sm->om = ble_transport_alloc_iso_from_hs(); +#else + sm->om = ble_transport_alloc_iso_from_ll(); +#endif + break; default: assert(0); break; @@ -102,6 +109,13 @@ hci_ipc_frame(struct hci_ipc_sm *sm) ble_transport_to_hs_evt(sm->buf); break; #endif + case HCI_IPC_TYPE_ISO: +#if MYNEWT_VAL(BLE_CONTROLLER) + ble_transport_to_ll_iso(sm->om); +#else + ble_transport_to_hs_iso(sm->om); +#endif + break; default: assert(0); break; @@ -161,6 +175,7 @@ hci_ipc_copy_to_buf(struct hci_ipc_sm *sm, const uint8_t *buf, uint16_t len) memcpy(sm->buf + sm->buf_len, buf, len); break; case HCI_IPC_TYPE_ACL: + case HCI_IPC_TYPE_ISO: rc = os_mbuf_append(sm->om, buf, len); assert(rc == 0); break; diff --git a/nimble/transport/include/nimble/transport.h b/nimble/transport/include/nimble/transport.h index d18ff56056..fcb3297cf7 100644 --- a/nimble/transport/include/nimble/transport.h +++ b/nimble/transport/include/nimble/transport.h @@ -39,7 +39,9 @@ void ble_transport_init(void); void *ble_transport_alloc_cmd(void); void *ble_transport_alloc_evt(int discardable); struct os_mbuf *ble_transport_alloc_acl_from_hs(void); +struct os_mbuf *ble_transport_alloc_iso_from_hs(void); struct os_mbuf *ble_transport_alloc_acl_from_ll(void); +struct os_mbuf *ble_transport_alloc_iso_from_ll(void); /* Generic deallocator for cmd/evt buffers */ void ble_transport_free(void *buf); @@ -50,8 +52,10 @@ int ble_transport_register_put_acl_from_ll_cb(os_mempool_put_fn *cb); /* Send data to hs/ll side */ int ble_transport_to_ll_cmd(void *buf); int ble_transport_to_ll_acl(struct os_mbuf *om); +int ble_transport_to_ll_iso(struct os_mbuf *om); int ble_transport_to_hs_evt(void *buf); int ble_transport_to_hs_acl(struct os_mbuf *om); +int ble_transport_to_hs_iso(struct os_mbuf *om); #ifdef __cplusplus } diff --git a/nimble/transport/include/nimble/transport/monitor.h b/nimble/transport/include/nimble/transport/monitor.h index 349f49d73b..dc12c69c4a 100644 --- a/nimble/transport/include/nimble/transport/monitor.h +++ b/nimble/transport/include/nimble/transport/monitor.h @@ -59,6 +59,12 @@ ble_transport_to_ll_acl(struct os_mbuf *om) return ble_transport_to_ll_acl_impl(om); } +static inline int +ble_transport_to_ll_iso(struct os_mbuf *om) +{ + return ble_transport_to_ll_iso_impl(om); +} + static inline int ble_transport_to_hs_evt(void *buf) { @@ -70,6 +76,12 @@ ble_transport_to_hs_acl(struct os_mbuf *om) { return ble_transport_to_hs_acl_impl(om); } + +static inline int +ble_transport_to_hs_iso(struct os_mbuf *om) +{ + return ble_transport_to_hs_iso_impl(om); +} #endif /* BLE_MONITOR */ #ifdef __cplusplus diff --git a/nimble/transport/include/nimble/transport_impl.h b/nimble/transport/include/nimble/transport_impl.h index d99a8d957d..8d95c8920e 100644 --- a/nimble/transport/include/nimble/transport_impl.h +++ b/nimble/transport/include/nimble/transport_impl.h @@ -31,8 +31,10 @@ extern void ble_transport_hs_init(void); /* APIs to be implemented by HS/LL side of transports */ extern int ble_transport_to_ll_cmd_impl(void *buf); extern int ble_transport_to_ll_acl_impl(struct os_mbuf *om); +extern int ble_transport_to_ll_iso_impl(struct os_mbuf *om); extern int ble_transport_to_hs_evt_impl(void *buf); extern int ble_transport_to_hs_acl_impl(struct os_mbuf *om); +extern int ble_transport_to_hs_iso_impl(struct os_mbuf *om); #ifdef __cplusplus } diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index 9ee3617893..7f3c5efe27 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -63,6 +63,35 @@ nrf5340_ble_hci_acl_tx(struct os_mbuf *om) return (rc < 0) ? BLE_ERR_MEM_CAPACITY : 0; } +#if !MYNEWT_VAL(BLE_CONTROLLER) +static int +nrf5340_ble_hci_iso_tx(struct os_mbuf *om) +{ + struct hci_ipc_hdr hdr; + struct os_mbuf *x; + int rc; + + hdr.type = HCI_IPC_TYPE_ISO; + hdr.length = 4 + get_le16(&om->om_data[2]); + + rc = ipc_nrf5340_write(IPC_TX_CHANNEL, &hdr, sizeof(hdr), false); + if (rc == 0) { + x = om; + while (x) { + rc = ipc_nrf5340_write(IPC_TX_CHANNEL, x->om_data, x->om_len, true); + if (rc < 0) { + break; + } + x = SLIST_NEXT(x, om_next); + } + } + + os_mbuf_free_chain(om); + + return (rc < 0) ? BLE_ERR_MEM_CAPACITY : 0; +} +#endif + static void nrf5340_ble_hci_trans_rx(int channel, void *user_data) { @@ -149,6 +178,12 @@ ble_transport_to_ll_acl_impl(struct os_mbuf *om) return nrf5340_ble_hci_acl_tx(om); } +int +ble_transport_to_ll_iso_impl(struct os_mbuf *om) +{ + return nrf5340_ble_hci_iso_tx(om); +} + void ble_transport_ll_init(void) { diff --git a/nimble/transport/src/monitor.c b/nimble/transport/src/monitor.c index 88309149bc..b21dd93058 100644 --- a/nimble/transport/src/monitor.c +++ b/nimble/transport/src/monitor.c @@ -509,6 +509,14 @@ ble_transport_to_ll_acl(struct os_mbuf *om) return ble_transport_to_ll_acl_impl(om); } +int +ble_transport_to_ll_iso(struct os_mbuf *om) +{ + ble_monitor_send_om(BLE_MONITOR_OPCODE_ISO_TX_PKT, om); + + return ble_transport_to_ll_iso_impl(om); +} + int ble_transport_to_hs_acl(struct os_mbuf *om) { @@ -528,4 +536,12 @@ ble_transport_to_hs_evt(void *buf) return ble_transport_to_hs_evt_impl(buf); } +int +ble_transport_to_hs_iso(struct os_mbuf *om) +{ + ble_monitor_send_om(BLE_MONITOR_OPCODE_ISO_RX_PKT, om); + + return ble_transport_to_hs_iso_impl(om); +} + #endif /* MYNEWT_VAL(BLE_MONITOR_RTT) || MYNEWT_VAL(BLE_MONITOR_UART) */ diff --git a/nimble/transport/src/monitor_priv.h b/nimble/transport/src/monitor_priv.h index 0fb96509d9..938da8f5ba 100644 --- a/nimble/transport/src/monitor_priv.h +++ b/nimble/transport/src/monitor_priv.h @@ -38,6 +38,8 @@ extern "C" { #define BLE_MONITOR_OPCODE_VENDOR_DIAG 11 #define BLE_MONITOR_OPCODE_SYSTEM_NOTE 12 #define BLE_MONITOR_OPCODE_USER_LOGGING 13 +#define BLE_MONITOR_OPCODE_ISO_TX_PKT 18 +#define BLE_MONITOR_OPCODE_ISO_RX_PKT 19 #define BLE_MONITOR_EXTHDR_COMMAND_DROPS 1 #define BLE_MONITOR_EXTHDR_EVENT_DROPS 2 diff --git a/nimble/transport/src/transport.c b/nimble/transport/src/transport.c index 7e5601d150..c9b37a7e94 100644 --- a/nimble/transport/src/transport.c +++ b/nimble/transport/src/transport.c @@ -49,18 +49,26 @@ #if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_LL, native) && \ MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, native) #define POOL_ACL_COUNT (0) +#define POOL_ISO_COUNT (0) #elif !MYNEWT_VAL_CHOICE(BLE_TRANSPORT_LL, native) && \ !MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, native) #define POOL_ACL_COUNT ((MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_HS_COUNT)) + \ (MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT))) +#define POOL_ISO_COUNT ((MYNEWT_VAL(BLE_TRANSPORT_ISO_FROM_HS_COUNT)) + \ + (MYNEWT_VAL(BLE_TRANSPORT_ISO_FROM_LL_COUNT))) #elif MYNEWT_VAL_CHOICE(BLE_TRANSPORT_LL, native) #define POOL_ACL_COUNT (MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_HS_COUNT)) +#define POOL_ISO_COUNT (MYNEWT_VAL(BLE_TRANSPORT_ISO_FROM_HS_COUNT)) #else #define POOL_ACL_COUNT (MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT)) +#define POOL_ISO_COUNT (MYNEWT_VAL(BLE_TRANSPORT_ISO_FROM_LL_COUNT)) #endif #define POOL_ACL_SIZE (OS_ALIGN( MYNEWT_VAL(BLE_TRANSPORT_ACL_SIZE) + \ BLE_MBUF_MEMBLOCK_OVERHEAD + \ BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT)) +#define POOL_ISO_SIZE (OS_ALIGN(MYNEWT_VAL(BLE_TRANSPORT_ISO_SIZE) + \ + BLE_MBUF_MEMBLOCK_OVERHEAD + \ + BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT)) static uint8_t pool_cmd_buf[ OS_MEMPOOL_BYTES(POOL_CMD_COUNT, POOL_CMD_SIZE) ]; static struct os_mempool pool_cmd; @@ -77,6 +85,12 @@ static struct os_mempool_ext pool_acl; static struct os_mbuf_pool mpool_acl; #endif +#if POOL_ISO_COUNT > 0 +static uint8_t pool_iso_buf[ OS_MEMPOOL_BYTES(POOL_ISO_COUNT, POOL_ISO_SIZE) ]; +static struct os_mempool_ext pool_iso; +static struct os_mbuf_pool mpool_iso; +#endif + static os_mempool_put_fn *transport_put_acl_from_ll_cb; void * @@ -159,6 +173,32 @@ ble_transport_alloc_acl_from_hs(void) #endif } +struct os_mbuf * +ble_transport_alloc_iso_from_hs(void) +{ +#if POOL_ISO_COUNT > 0 + struct os_mbuf *om; + struct os_mbuf_pkthdr *pkthdr; + uint16_t usrhdr_len; + +#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_LL, native) + usrhdr_len = sizeof(struct ble_mbuf_hdr); +#else + usrhdr_len = 0; +#endif + + om = os_mbuf_get_pkthdr(&mpool_iso, usrhdr_len); + if (om) { + pkthdr = OS_MBUF_PKTHDR(om); + pkthdr->omp_flags = OMP_FLAG_FROM_HS; + } + + return om; +#else + return NULL; +#endif +} + struct os_mbuf * ble_transport_alloc_acl_from_ll(void) { @@ -178,6 +218,25 @@ ble_transport_alloc_acl_from_ll(void) #endif } +struct os_mbuf * +ble_transport_alloc_iso_from_ll(void) +{ +#if POOL_ISO_COUNT > 0 + struct os_mbuf *om; + struct os_mbuf_pkthdr *pkthdr; + + om = os_mbuf_get_pkthdr(&mpool_iso, 0); + if (om) { + pkthdr = OS_MBUF_PKTHDR(om); + pkthdr->omp_flags = OMP_FLAG_FROM_LL; + } + + return om; +#else + return NULL; +#endif +} + void ble_transport_free(void *buf) { @@ -278,6 +337,16 @@ ble_transport_init(void) pool_acl.mpe_put_cb = ble_transport_acl_put; #endif + +#if POOL_ISO_COUNT > 0 + rc = os_mempool_ext_init(&pool_iso, POOL_ISO_COUNT, POOL_ISO_SIZE, + pool_iso_buf, "transport_pool_iso"); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = os_mbuf_pool_init(&mpool_iso, &pool_iso.mpe_mp, + POOL_ISO_SIZE, POOL_ISO_COUNT); + SYSINIT_PANIC_ASSERT(rc == 0); +#endif } int diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml index e8d83bd15f..7f02f6cc8f 100644 --- a/nimble/transport/syscfg.yml +++ b/nimble/transport/syscfg.yml @@ -58,6 +58,16 @@ syscfg.defs: BLE_TRANSPORT_ACL_SIZE: description: Size of each buffer in ACL pool. value: 251 + BLE_TRANSPORT_ISO_COUNT: + description: > + Number of ISO buffers available in transport. This determines + number of buffers used by host/controller for flow control. + Buffers pool is allocated for each non-native transport side + selected, unless overriden by BLE_TRANSPORT_ISO_FROM_[HS|LL]_COUNT. + value: 10 + BLE_TRANSPORT_ISO_SIZE: + description: Size of each buffer in ISO pool. + value: 300 BLE_TRANSPORT_EVT_COUNT: description: > Number of event buffers available in transport. @@ -88,6 +98,17 @@ syscfg.defs: of ACL buffers available for controller. value: MYNEWT_VAL(BLE_TRANSPORT_ACL_COUNT) + BLE_TRANSPORT_ISO_FROM_HS_COUNT: + description: > + Overrides BLE_TRANSPORT_ISO_COUNT on host side, i.e. number + of ISO buffers available for host. + value: MYNEWT_VAL(BLE_TRANSPORT_ISO_COUNT) + BLE_TRANSPORT_ISO_FROM_LL_COUNT: + description: > + Overrides BLE_TRANSPORT_ISO_COUNT on controller side, i.e. number + of ISO buffers available for controller. + value: MYNEWT_VAL(BLE_TRANSPORT_ISO_COUNT) + # import monitor and defunct settings from separate file to reduce clutter in main file $import: - "@apache-mynewt-nimble/nimble/transport/syscfg.monitor.yml" diff --git a/nimble/transport/uart/src/hci_uart.c b/nimble/transport/uart/src/hci_uart.c index 42206f58b0..af1f45ae92 100644 --- a/nimble/transport/uart/src/hci_uart.c +++ b/nimble/transport/uart/src/hci_uart.c @@ -61,6 +61,8 @@ hci_uart_frame_cb(uint8_t pkt_type, void *data) return ble_transport_to_ll_cmd(data); case HCI_H4_ACL: return ble_transport_to_ll_acl(data); + case HCI_H4_ISO: + return ble_transport_to_ll_iso(data); default: assert(0); break; @@ -227,6 +229,34 @@ ble_transport_to_hs_acl_impl(struct os_mbuf *om) return 0; } +int +ble_transport_to_hs_iso_impl(struct os_mbuf *om) +{ + struct hci_uart_tx *txe; + os_sr_t sr; + + txe = os_memblock_get(&pool_tx_q); + if (!txe) { + assert(0); + return -ENOMEM; + } + + txe->type = HCI_H4_ISO; + txe->sent_type = 0; + txe->len = OS_MBUF_PKTLEN(om); + txe->idx = 0; + txe->buf = NULL; + txe->om = om; + + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&tx_q, txe, tx_q_next); + OS_EXIT_CRITICAL(sr); + + hal_uart_start_tx(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT)); + + return 0; +} + void ble_transport_hs_init(void) { From c1cfe3decc3e1348cb4c61aecd9b61d07290f11b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 31 Jan 2023 14:37:01 +0100 Subject: [PATCH 0710/1333] nimble/ll: Initial ISOAL implementation This adds some ISOAL code that for now works with unframed PDUs only. It's enough to pass qualification test cases that do not require framed PDUs and even stream some actual content if host supports LC3 codec. --- nimble/controller/include/controller/ble_ll.h | 5 + .../include/controller/ble_ll_iso_big.h | 7 + .../include/controller/ble_ll_isoal.h | 84 ++++ nimble/controller/src/ble_ll.c | 12 + nimble/controller/src/ble_ll_hci.c | 20 +- nimble/controller/src/ble_ll_iso_big.c | 104 ++++- nimble/controller/src/ble_ll_isoal.c | 403 ++++++++++++++++++ nimble/include/nimble/ble.h | 5 + nimble/include/nimble/hci_common.h | 31 ++ 9 files changed, 661 insertions(+), 10 deletions(-) create mode 100644 nimble/controller/include/controller/ble_ll_isoal.h create mode 100644 nimble/controller/src/ble_ll_isoal.c diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index fcfdff200e..408f03b690 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -118,6 +118,11 @@ struct ble_ll_obj uint16_t ll_acl_pkt_size; #endif +#if MYNEWT_VAL(BLE_LL_ISO) + uint8_t ll_num_iso_pkts; + uint16_t ll_iso_pkt_size; +#endif + /* Preferred PHY's */ uint8_t ll_pref_tx_phys; uint8_t ll_pref_rx_phys; diff --git a/nimble/controller/include/controller/ble_ll_iso_big.h b/nimble/controller/include/controller/ble_ll_iso_big.h index c9052126cb..30cf1b46af 100644 --- a/nimble/controller/include/controller/ble_ll_iso_big.h +++ b/nimble/controller/include/controller/ble_ll_iso_big.h @@ -27,11 +27,18 @@ extern "C" { #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) struct ble_ll_iso_big; +struct ble_ll_iso_bis; int ble_ll_iso_big_biginfo_copy(struct ble_ll_iso_big *big, uint8_t *dptr, uint32_t base_ticks, uint8_t base_rem_us); int ble_ll_iso_big_biginfo_len(struct ble_ll_iso_big *big); +struct ble_ll_iso_bis *ble_ll_iso_big_find_bis_by_handle(uint16_t conn_handle); +struct ble_ll_isoal_mux *ble_ll_iso_big_find_mux_by_handle(uint16_t conn_handle); +int ble_ll_iso_big_last_tx_timestamp_get(struct ble_ll_iso_bis *bis, + uint16_t *packet_seq_num, + uint32_t *timestamp); + void ble_ll_iso_big_chan_map_update(void); void ble_ll_iso_big_halt(void); diff --git a/nimble/controller/include/controller/ble_ll_isoal.h b/nimble/controller/include/controller/ble_ll_isoal.h new file mode 100644 index 0000000000..5104ea979e --- /dev/null +++ b/nimble/controller/include/controller/ble_ll_isoal.h @@ -0,0 +1,84 @@ +/* + * 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_BLE_LL_ISOAL_ +#define H_BLE_LL_ISOAL_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if MYNEWT_VAL(BLE_LL_ISO) + +struct ble_ll_isoal_mux { + /* Max PDU length */ + uint8_t max_pdu; + /* Number of expected SDUs per ISO interval */ + uint8_t sdu_per_interval; + /* Number of expected PDUs per SDU */ + uint8_t pdu_per_sdu; + /* Number of SDUs required to fill complete BIG/CIG event (i.e. with pt) */ + uint8_t sdu_per_event; + /* Number of SDUs available for current event */ + uint8_t sdu_in_event; + + STAILQ_HEAD(, os_mbuf_pkthdr) sdu_q; + + struct os_mbuf *frag; + + uint32_t sdu_counter; + + uint32_t event_tx_timestamp; + uint32_t last_tx_timestamp; + uint16_t last_tx_packet_seq_num; +}; + +void +ble_ll_isoal_mux_init(struct ble_ll_isoal_mux *mux, uint8_t max_pdu, + uint32_t iso_interval_us, uint32_t sdu_interval_us, + uint8_t bn, uint8_t pte); +void ble_ll_isoal_mux_free(struct ble_ll_isoal_mux *mux); + +int ble_ll_isoal_mux_event_start(struct ble_ll_isoal_mux *mux, + uint32_t timestamp); +int ble_ll_isoal_mux_event_done(struct ble_ll_isoal_mux *mux); + +int +ble_ll_isoal_mux_unframed_get(struct ble_ll_isoal_mux *mux, uint8_t idx, + uint8_t *llid, void *dptr); + +/* HCI command handlers */ +int ble_ll_isoal_hci_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen); +int ble_ll_isoal_hci_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen); +int ble_ll_isoal_hci_read_tx_sync(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen); + +void ble_ll_isoal_init(void); +void ble_ll_isoal_reset(void); +int ble_ll_isoal_data_in(struct os_mbuf *om); + +#endif /* BLE_LL_ISO */ + +#ifdef __cplusplus +} +#endif + +#endif /* H_BLE_LL_ISOAL_ */ diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index de30b89222..4ccab7b50a 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -46,6 +46,7 @@ #include "controller/ble_ll_trace.h" #include "controller/ble_ll_sync.h" #include "controller/ble_fem.h" +#include "controller/ble_ll_isoal.h" #include "controller/ble_ll_iso_big.h" #if MYNEWT_VAL(BLE_LL_EXT) #include "controller/ble_ll_ext.h" @@ -1679,6 +1680,9 @@ ble_ll_reset(void) ble_fem_lna_init(); #endif +#if MYNEWT_VAL(BLE_LL_ISO) + ble_ll_isoal_reset(); +#endif #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) ble_ll_iso_big_reset(); #endif @@ -1811,6 +1815,11 @@ ble_ll_init(void) lldata->ll_acl_pkt_size = MYNEWT_VAL(BLE_TRANSPORT_ACL_SIZE); #endif +#if MYNEWT_VAL(BLE_LL_ISO) + lldata->ll_num_iso_pkts = MYNEWT_VAL(BLE_TRANSPORT_ISO_FROM_HS_COUNT); + lldata->ll_iso_pkt_size = MYNEWT_VAL(BLE_TRANSPORT_ISO_SIZE); +#endif + /* Initialize eventq */ ble_npl_eventq_init(&lldata->ll_evq); @@ -1950,6 +1959,9 @@ ble_ll_init(void) ble_ll_hci_vs_init(); #endif +#if MYNEWT_VAL(BLE_LL_ISO) + ble_ll_isoal_init(); +#endif #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) ble_ll_iso_big_init(); #endif diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index b693f5ca48..c2b3af71ab 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -34,6 +34,7 @@ #include "controller/ble_ll_resolv.h" #include "controller/ble_ll_sync.h" #include +#include "controller/ble_ll_isoal.h" #include "controller/ble_ll_iso.h" #include "controller/ble_ll_iso_big.h" #include "ble_ll_priv.h" @@ -356,9 +357,8 @@ ble_ll_hci_le_read_bufsize_v2(uint8_t *rspbuf, uint8_t *rsplen) rp->data_len = htole16(g_ble_ll_data.ll_acl_pkt_size); rp->data_packets = g_ble_ll_data.ll_num_acl_pkts; - /* XXX for testing only */ - rp->iso_data_len = 512; - rp->iso_data_packets = 10; + rp->iso_data_len = htole16(g_ble_ll_data.ll_iso_pkt_size); + rp->iso_data_packets = g_ble_ll_data.ll_num_iso_pkts; *rsplen = sizeof(*rp); return BLE_ERR_SUCCESS; @@ -1300,14 +1300,17 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, case BLE_HCI_OCF_LE_BIG_TERMINATE_SYNC: rc = ble_ll_iso_big_terminate_sync(cmdbuf,len); break; +#endif +#if MYNEWT_VAL(BLE_LL_ISO) case BLE_HCI_OCF_LE_SETUP_ISO_DATA_PATH: - rc = ble_ll_iso_setup_iso_data_path(cmdbuf, len); + rc = ble_ll_isoal_hci_setup_iso_data_path(cmdbuf, len, rspbuf, rsplen); break; case BLE_HCI_OCF_LE_REMOVE_ISO_DATA_PATH: - rc = ble_ll_iso_remove_iso_data_path(cmdbuf, len); + rc = ble_ll_isoal_hci_remove_iso_data_path(cmdbuf, len, rspbuf, rsplen); + break; + case BLE_HCI_OCF_LE_READ_ISO_TX_SYNC: + rc = ble_ll_isoal_hci_read_tx_sync(cmdbuf, len, rspbuf, rsplen); break; -#endif -#if MYNEWT_VAL(BLE_LL_ISO) case BLE_HCI_OCF_LE_RD_BUF_SIZE_V2: if (len == 0) { rc = ble_ll_hci_le_read_bufsize_v2(rspbuf, rsplen); @@ -1970,8 +1973,7 @@ int ble_ll_hci_iso_rx(struct os_mbuf *om) { #if MYNEWT_VAL(BLE_LL_ISO) - /* FIXME send to isoal... */ - os_mbuf_free_chain(om); + ble_ll_isoal_data_in(om); #else os_mbuf_free_chain(om); #endif diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 594ff4a1dd..096d3a98a0 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,9 @@ struct ble_ll_iso_bis { uint8_t g; } tx; + struct ble_ll_isoal_mux mux; + uint16_t num_completed_pkt; + STAILQ_ENTRY(ble_ll_iso_bis) bis_q_next; }; @@ -160,6 +164,58 @@ static uint8_t bis_pool_free = BIS_POOL_SIZE; static struct ble_ll_iso_big *big_pending; static struct ble_ll_iso_big *big_active; +struct ble_ll_iso_bis * +ble_ll_iso_big_find_bis_by_handle(uint16_t conn_handle) +{ + struct ble_ll_iso_bis *bis; + uint8_t bis_idx; + + if (!BLE_LL_CONN_HANDLE_IS_BIS(conn_handle)) { + return NULL; + } + + bis_idx = BLE_LL_CONN_HANDLE_IDX(conn_handle); + + if (bis_idx >= BIS_POOL_SIZE) { + return NULL; + } + + bis = &bis_pool[bis_idx]; + if (!bis->big) { + return NULL; + } + + return bis; +} + +struct ble_ll_isoal_mux * +ble_ll_iso_big_find_mux_by_handle(uint16_t conn_handle) +{ + struct ble_ll_iso_bis *bis; + + bis = ble_ll_iso_big_find_bis_by_handle(conn_handle); + if (bis) { + return &bis->mux; + } + + return NULL; +} + +int +ble_ll_iso_big_last_tx_timestamp_get(struct ble_ll_iso_bis *bis, + uint16_t *packet_seq_num, uint32_t *timestamp) +{ + struct ble_ll_iso_big *big; + + big = bis->big; + + *packet_seq_num = big->bis_counter; + *timestamp = (uint64_t)big->event_start * 1000000 / 32768 + + big->event_start_us; + + return 0; +} + static void ble_ll_iso_big_biginfo_calc(struct ble_ll_iso_big *big, uint32_t seed_aa) { @@ -281,6 +337,7 @@ ble_ll_iso_big_free(struct ble_ll_iso_big *big) ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &big->event_done); STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) { + ble_ll_isoal_mux_free(&bis->mux); bis->big = NULL; bis_pool_free++; } @@ -339,6 +396,10 @@ ble_ll_iso_big_update_event_start(struct ble_ll_iso_big *big) static void ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) { + struct ble_ll_iso_bis *bis; + struct ble_hci_ev *hci_ev; + struct ble_hci_ev_num_comp_pkts *hci_ev_ncp; + int num_completed_pkt; int rc; ble_ll_rfmgmt_release(); @@ -348,6 +409,37 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) ble_ll_iso_big_hci_evt_complete(); } + hci_ev = ble_transport_alloc_evt(1); + if (hci_ev) { + hci_ev->opcode = BLE_HCI_EVCODE_NUM_COMP_PKTS; + hci_ev->length = sizeof(*hci_ev_ncp); + hci_ev_ncp = (void *)hci_ev->data; + hci_ev_ncp->count = 0; + } + + STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) { + num_completed_pkt = ble_ll_isoal_mux_event_done(&bis->mux); + if (hci_ev && num_completed_pkt) { + hci_ev_ncp->completed[hci_ev_ncp->count].handle = + htole16(bis->conn_handle); + hci_ev_ncp->completed[hci_ev_ncp->count].packets = + htole16(num_completed_pkt + bis->num_completed_pkt); + bis->num_completed_pkt = 0; + hci_ev_ncp->count++; + } else { + bis->num_completed_pkt += num_completed_pkt; + } + } + + if (hci_ev) { + if (hci_ev_ncp->count) { + hci_ev->length = sizeof(*hci_ev_ncp) + + hci_ev_ncp->count * sizeof(hci_ev_ncp->completed[0]); + ble_transport_to_hs_evt(hci_ev); + } else { + ble_transport_free(hci_ev); + } + } big->sch.start_time = big->event_start; big->sch.remainder = big->event_start_us; @@ -532,6 +624,9 @@ ble_ll_iso_big_subevent_pdu_cb(uint8_t *dptr, void *arg, uint8_t *hdr_byte) ble_phy_encrypt_counter_set(big->bis_counter + idx, 1); } +#if 1 + pdu_len = ble_ll_isoal_mux_unframed_get(&bis->mux, idx, &llid, dptr); +#else llid = 0; pdu_len = big->max_pdu; /* XXX dummy data for testing */ @@ -549,6 +644,7 @@ ble_ll_iso_big_subevent_pdu_cb(uint8_t *dptr, void *arg, uint8_t *hdr_byte) dptr[11] = 'P'; } dptr[12] = 0xff; +#endif *hdr_byte = llid | (big->cssn << 2) | (big->cstf << 5); @@ -669,6 +765,10 @@ ble_ll_iso_big_event_sched_cb(struct ble_ll_sched_item *sch) /* XXX calculate this in advance at the end of previous event? */ big->tx.subevents_rem = big->num_bis * big->nse; STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) { + ble_ll_isoal_mux_event_start(&bis->mux, (uint64_t)big->event_start * + 1000000 / 32768 + + big->event_start_us); + bis->tx.subevent_num = 0; bis->tx.n = 0; bis->tx.g = 0; @@ -820,7 +920,6 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, /* Calculate number of additional events for pre-transmissions */ /* Core 5.3, Vol 6, Part B, 4.4.6.6 */ gc = bp->nse / bp->bn; - (void)pte; if (bp->irc == gc) { pte = 0; } else { @@ -844,6 +943,9 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, bis->crc_init = (big->crc_init << 8) | (big->num_bis); BLE_LL_ASSERT(!big->framed); + + ble_ll_isoal_mux_init(&bis->mux, bp->max_pdu, bp->iso_interval * 1250, + bp->sdu_interval, bp->bn, pte); } big_pool_free--; diff --git a/nimble/controller/src/ble_ll_isoal.c b/nimble/controller/src/ble_ll_isoal.c new file mode 100644 index 0000000000..b028844316 --- /dev/null +++ b/nimble/controller/src/ble_ll_isoal.c @@ -0,0 +1,403 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#if MYNEWT_VAL(BLE_LL_ISO) + +STAILQ_HEAD(ble_ll_iso_tx_q, os_mbuf_pkthdr); + +static struct ble_npl_event ll_isoal_tx_pkt_in; +static struct ble_ll_iso_tx_q ll_isoal_tx_q; + +void +ble_ll_isoal_mux_init(struct ble_ll_isoal_mux *mux, uint8_t max_pdu, + uint32_t iso_interval_us, uint32_t sdu_interval_us, + uint8_t bn, uint8_t pte) +{ + memset(mux, 0, sizeof(*mux)); + + mux->max_pdu = max_pdu; + /* Core 5.3, Vol 6, Part G, 2.1 */ + mux->sdu_per_interval = iso_interval_us / sdu_interval_us; + mux->pdu_per_sdu = bn / mux->sdu_per_interval; + + mux->sdu_per_event = (1 + pte) * mux->sdu_per_interval; + + STAILQ_INIT(&mux->sdu_q); +} + +void +ble_ll_isoal_mux_free(struct ble_ll_isoal_mux *mux) +{ + struct os_mbuf_pkthdr *pkthdr; + struct os_mbuf *om; + struct os_mbuf *om_next; + + pkthdr = STAILQ_FIRST(&mux->sdu_q); + while (pkthdr) { + om = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); + + while (om) { + om_next = SLIST_NEXT(om, om_next); + os_mbuf_free(om); + om = om_next; + } + + STAILQ_REMOVE_HEAD(&mux->sdu_q, omp_next); + pkthdr = STAILQ_FIRST(&mux->sdu_q); + } + + STAILQ_INIT(&mux->sdu_q); +} + +static void +ble_ll_isoal_mux_tx_pkt_in(struct ble_ll_isoal_mux *mux, struct os_mbuf *om, + uint8_t pb, uint32_t timestamp) +{ + struct os_mbuf_pkthdr *pkthdr; + struct ble_mbuf_hdr *blehdr; + os_sr_t sr; + + BLE_LL_ASSERT(mux); + + switch (pb) { + case BLE_HCI_ISO_PB_FIRST: + BLE_LL_ASSERT(!mux->frag); + mux->frag = om; + om = NULL; + break; + case BLE_HCI_ISO_PB_CONTINUATION: + BLE_LL_ASSERT(mux->frag); + os_mbuf_concat(mux->frag, om); + om = NULL; + break; + case BLE_HCI_ISO_PB_COMPLETE: + BLE_LL_ASSERT(!mux->frag); + break; + case BLE_HCI_ISO_PB_LAST: + BLE_LL_ASSERT(mux->frag); + os_mbuf_concat(mux->frag, om); + om = mux->frag; + mux->frag = NULL; + break; + default: + BLE_LL_ASSERT(0); + break; + } + + if (!om) { + return; + } + + blehdr = BLE_MBUF_HDR_PTR(om); + blehdr->txiso.packet_seq_num = ++mux->sdu_counter; + + OS_ENTER_CRITICAL(sr); + pkthdr = OS_MBUF_PKTHDR(om); + STAILQ_INSERT_TAIL(&mux->sdu_q, pkthdr, omp_next); + OS_EXIT_CRITICAL(sr); +} + +int +ble_ll_isoal_mux_event_start(struct ble_ll_isoal_mux *mux, uint32_t timestamp) +{ + struct os_mbuf_pkthdr *pkthdr; + uint8_t num_sdu; + + num_sdu = mux->sdu_per_event; + + pkthdr = STAILQ_FIRST(&mux->sdu_q); + while (pkthdr && num_sdu--) { + pkthdr = STAILQ_NEXT(pkthdr, omp_next); + } + + mux->sdu_in_event = mux->sdu_per_event - num_sdu; + mux->event_tx_timestamp = timestamp; + + return mux->sdu_in_event; +} + +int +ble_ll_isoal_mux_event_done(struct ble_ll_isoal_mux *mux) +{ + struct os_mbuf_pkthdr *pkthdr; + struct ble_mbuf_hdr *blehdr; + struct os_mbuf *om; + struct os_mbuf *om_next; + uint8_t num_sdu; + int pkt_freed = 0; + + num_sdu = min(mux->sdu_in_event, mux->sdu_per_interval); + + pkthdr = STAILQ_FIRST(&mux->sdu_q); + if (pkthdr) { + om = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); + blehdr = BLE_MBUF_HDR_PTR(om); + mux->last_tx_timestamp = mux->event_tx_timestamp; + mux->last_tx_packet_seq_num = blehdr->txiso.packet_seq_num; + } + + while (pkthdr && num_sdu--) { + om = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); + + while (om) { + om_next = SLIST_NEXT(om, om_next); + os_mbuf_free(om); + pkt_freed++; + om = om_next; + } + + STAILQ_REMOVE_HEAD(&mux->sdu_q, omp_next); + pkthdr = STAILQ_FIRST(&mux->sdu_q); + } + + mux->sdu_in_event = 0; + + return pkt_freed; +} + +int +ble_ll_isoal_mux_unframed_get(struct ble_ll_isoal_mux *mux, uint8_t idx, + uint8_t *llid, void *dptr) +{ + struct os_mbuf_pkthdr *pkthdr; + struct os_mbuf *om; + uint8_t sdu_idx; + uint8_t pdu_idx; + uint16_t sdu_offset; + uint16_t rem_len; + uint8_t pdu_len; + + sdu_idx = idx / mux->pdu_per_sdu; + pdu_idx = idx - sdu_idx * mux->pdu_per_sdu; + + if (sdu_idx >= mux->sdu_in_event) { + *llid = 1; + return 0; + } + + pkthdr = STAILQ_FIRST(&mux->sdu_q); + while (pkthdr && sdu_idx--) { + pkthdr = STAILQ_NEXT(pkthdr, omp_next); + } + + if (!pkthdr) { + *llid = 1; + return 0; + } + + om = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); + sdu_offset = pdu_idx * mux->max_pdu; + rem_len = OS_MBUF_PKTLEN(om) - sdu_offset; + + if ((int32_t)rem_len <= 0) { + *llid = 1; + pdu_len = 0; + } else { + *llid = (pdu_idx < mux->pdu_per_sdu - 1); + pdu_len = min(mux->max_pdu, rem_len); + } + + os_mbuf_copydata(om, sdu_offset, pdu_len, dptr); + + return pdu_len; +} + +static void +ble_ll_isoal_tx_pkt_in(struct ble_npl_event *ev) +{ + struct os_mbuf *om; + struct os_mbuf_pkthdr *pkthdr; + struct ble_hci_iso *hci_iso; + struct ble_hci_iso_data *hci_iso_data; + struct ble_ll_isoal_mux *mux; + uint16_t data_hdr_len; + uint16_t handle; + uint16_t conn_handle; + uint16_t length; + uint16_t pb_flag; + uint16_t ts_flag; + uint32_t timestamp = 0; + os_sr_t sr; + + while (STAILQ_FIRST(&ll_isoal_tx_q)) { + pkthdr = STAILQ_FIRST(&ll_isoal_tx_q); + om = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); + + OS_ENTER_CRITICAL(sr); + STAILQ_REMOVE_HEAD(&ll_isoal_tx_q, omp_next); + OS_EXIT_CRITICAL(sr); + + hci_iso = (void *)om->om_data; + + handle = le16toh(hci_iso->handle); + conn_handle = BLE_HCI_ISO_CONN_HANDLE(handle); + pb_flag = BLE_HCI_ISO_PB_FLAG(handle); + ts_flag = BLE_HCI_ISO_TS_FLAG(handle); + length = BLE_HCI_ISO_LENGTH(le16toh(hci_iso->length)); + + data_hdr_len = 0; + if ((pb_flag == BLE_HCI_ISO_PB_FIRST) || + (pb_flag == BLE_HCI_ISO_PB_COMPLETE)) { + if (ts_flag) { + timestamp = get_le32(om->om_data + sizeof(*hci_iso)); + data_hdr_len += sizeof(uint32_t); + } + + hci_iso_data = (void *)(om->om_data + sizeof(*hci_iso) + data_hdr_len); + data_hdr_len += sizeof(*hci_iso_data); + } + os_mbuf_adj(om, sizeof(*hci_iso) + data_hdr_len); + + if (OS_MBUF_PKTLEN(om) != length - data_hdr_len) { + os_mbuf_free_chain(om); + continue; + } + + switch (BLE_LL_CONN_HANDLE_TYPE(conn_handle)) { + case BLE_LL_CONN_HANDLE_TYPE_BIS: + mux = ble_ll_iso_big_find_mux_by_handle(conn_handle); + ble_ll_isoal_mux_tx_pkt_in(mux, om, pb_flag, timestamp); + break; + default: + os_mbuf_free_chain(om); + break; + } + } +} + +int +ble_ll_isoal_hci_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_le_setup_iso_data_path_cp *cmd = (const void *)cmdbuf; + struct ble_hci_le_setup_iso_data_path_rp *rsp = (void *)rspbuf; + struct ble_ll_iso_bis *bis; + uint16_t conn_handle; + + conn_handle = le16toh(cmd->conn_handle); + switch (BLE_LL_CONN_HANDLE_TYPE(conn_handle)) { + case BLE_LL_CONN_HANDLE_TYPE_BIS: + bis = ble_ll_iso_big_find_bis_by_handle(conn_handle); + if (bis) { + break; + } + default: + return BLE_ERR_UNK_CONN_ID; + } + + /* Only input for now since we only support BIS */ + if (cmd->data_path_dir) { + return BLE_ERR_CMD_DISALLOWED; + } + + /* We do not (yet) support any vendor-specific data path */ + if (cmd->data_path_id) { + return BLE_ERR_CMD_DISALLOWED; + } + + rsp->conn_handle = cmd->conn_handle; + *rsplen = sizeof(*rsp); + + return 0; +} + +int +ble_ll_isoal_hci_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_le_remove_iso_data_path_cp *cmd = (const void *)cmdbuf; + struct ble_hci_le_remove_iso_data_path_rp *rsp = (void *)rspbuf; + + /* XXX accepts anything for now */ + rsp->conn_handle = cmd->conn_handle; + *rsplen = sizeof(*rsp); + + return 0; +} + +int +ble_ll_isoal_hci_read_tx_sync(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_le_read_iso_tx_sync_cp *cmd = (const void *)cmdbuf; + struct ble_hci_le_read_iso_tx_sync_rp *rsp = (void *)rspbuf; + struct ble_ll_isoal_mux *mux; + uint16_t handle; + + handle = le16toh(cmd->conn_handle); + switch (BLE_LL_CONN_HANDLE_TYPE(handle)) { + case BLE_LL_CONN_HANDLE_TYPE_BIS: + mux = ble_ll_iso_big_find_mux_by_handle(handle); + if (!mux) { + return BLE_ERR_UNK_CONN_ID; + } + break; + default: + return BLE_ERR_UNK_CONN_ID; + } + + rsp->conn_handle = cmd->conn_handle; + rsp->packet_seq_num = htole16(mux->last_tx_packet_seq_num); + rsp->tx_timestamp = htole32(mux->last_tx_timestamp); + put_le24(rsp->time_offset, 0); + + *rsplen = sizeof(*rsp); + + return 0; +} + +void +ble_ll_isoal_init(void) +{ + STAILQ_INIT(&ll_isoal_tx_q); + ble_npl_event_init(&ll_isoal_tx_pkt_in, ble_ll_isoal_tx_pkt_in, NULL); +} + +void +ble_ll_isoal_reset(void) +{ + STAILQ_INIT(&ll_isoal_tx_q); + ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &ll_isoal_tx_pkt_in); +} + +int +ble_ll_isoal_data_in(struct os_mbuf *om) +{ + struct os_mbuf_pkthdr *hdr; + os_sr_t sr; + + hdr = OS_MBUF_PKTHDR(om); + + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&ll_isoal_tx_q, hdr, omp_next); + OS_EXIT_CRITICAL(sr); + + ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &ll_isoal_tx_pkt_in); + + return 0; +} + +#endif /* BLE_LL_ISO */ diff --git a/nimble/include/nimble/ble.h b/nimble/include/nimble/ble.h index 0aa96251a1..6979e945bf 100644 --- a/nimble/include/nimble/ble.h +++ b/nimble/include/nimble/ble.h @@ -118,11 +118,16 @@ struct ble_mbuf_hdr_txinfo uint16_t pyld_len; }; +struct ble_mbuf_hdr_txiso { + uint16_t packet_seq_num; +}; + struct ble_mbuf_hdr { union { struct ble_mbuf_hdr_rxinfo rxinfo; struct ble_mbuf_hdr_txinfo txinfo; + struct ble_mbuf_hdr_txiso txiso; }; uint32_t beg_cputime; uint32_t rem_usecs; diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index ca0c219ee2..93429a2f52 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -2070,6 +2070,37 @@ struct hci_data_hdr #define BLE_HCI_PB_FIRST_FLUSH 2 #define BLE_HCI_PB_FULL 3 +#define BLE_HCI_ISO_CONN_HANDLE_MASK (0x07ff) +#define BLE_HCI_ISO_PB_FLAG_MASK (0x3000) +#define BLE_HCI_ISO_TS_FLAG_MASK (0x4000) +#define BLE_HCI_ISO_LENGTH_MASK (0x7fff) + +#define BLE_HCI_ISO_HANDLE(ch, pb, ts) ((ch) | ((pb) << 12) | ((ts) << 14)) + +#define BLE_HCI_ISO_CONN_HANDLE(h) ((h) & BLE_HCI_ISO_CONN_HANDLE_MASK) +#define BLE_HCI_ISO_PB_FLAG(h) (((h) & BLE_HCI_ISO_PB_FLAG_MASK) >> 12) +#define BLE_HCI_ISO_TS_FLAG(h) ((h) & BLE_HCI_ISO_TS_FLAG_MASK) +#define BLE_HCI_ISO_LENGTH(l) ((l) & BLE_HCI_ISO_LENGTH_MASK) + +#define BLE_HCI_ISO_PB_FIRST (0) +#define BLE_HCI_ISO_PB_CONTINUATION (1) +#define BLE_HCI_ISO_PB_COMPLETE (2) +#define BLE_HCI_ISO_PB_LAST (3) + +struct ble_hci_iso { + uint16_t handle; + uint16_t length; + uint8_t data[0]; +}; + +#define BLE_HCI_ISO_HDR_SDU_LENGTH_MASK (0x07ff) + +struct ble_hci_iso_data { + uint16_t packet_seq_num; + uint16_t sdu_len; + uint8_t data[0]; +}; + #ifdef __cplusplus } #endif From dacbdbe58fb7825911eb1c09f94e9ab426969d8e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 31 Jan 2023 15:02:30 +0100 Subject: [PATCH 0711/1333] nimble/ll: Add LE BIG Create command handling This adds initial support for LE BIG Create command that shold be used by host to create BIG (LE BIG Create Test should not be used for that purpose). It will not make any calculations to set BIG parameters, just set NSE, BN and IRC to 1 which is fine but not too smart - we'll change that later. --- nimble/controller/src/ble_ll_iso_big.c | 58 +++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 096d3a98a0..31bcd21f0f 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -1164,9 +1164,63 @@ ble_ll_iso_big_hci_evt_complete(void) int ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len) { - /* TODO implement :) */ + const struct ble_hci_le_create_big_cp *cmd = (void *)cmdbuf; + struct big_params bp; + int rc; + + if (len != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } - return BLE_ERR_UNSPECIFIED; + if (!IN_RANGE(cmd->big_handle, 0x00, 0xef) || + !IN_RANGE(cmd->adv_handle, 0x00, 0xef) || + !IN_RANGE(cmd->num_bis, 0x01, 0x1f) || + !IN_RANGE(get_le24(cmd->sdu_interval), 0x0000ff, 0x0fffff) || + !IN_RANGE(le16toh(cmd->max_sdu), 0x0001, 0x0fff) || + !IN_RANGE(le16toh(cmd->max_transport_latency), 0x0005, 0x0fa0) || + !IN_RANGE(cmd->rtn, 0x00, 0x1e) || + (cmd->packing > 1) || (cmd->framing > 1) || (cmd->encryption) > 1) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + bp.sdu_interval = get_le24(cmd->sdu_interval); + bp.max_transport_latency = le16toh(cmd->max_transport_latency); + bp.max_sdu = le16toh(cmd->max_sdu); + if (cmd->phy & BLE_HCI_LE_PHY_2M_PREF_MASK) { + bp.phy = BLE_PHY_2M; + } else if (cmd->phy & BLE_HCI_LE_PHY_1M_PREF_MASK) { + bp.phy = BLE_PHY_1M; + } else { + bp.phy = BLE_PHY_CODED; + } + bp.interleaved = cmd->packing; + bp.framed = cmd->framing; + bp.encrypted = cmd->encryption; + memcpy(bp.broadcast_code, cmd->broadcast_code, 16); + + bp.nse = 1; + bp.bn = 1; + bp.irc = 1; + bp.pto = 0; + bp.iso_interval = bp.sdu_interval / 1250; + bp.max_pdu = bp.max_sdu; + + rc = ble_ll_iso_big_create(cmd->big_handle, cmd->adv_handle, cmd->num_bis, + &bp); + switch (rc) { + case 0: + break; + case -EINVAL: + return BLE_ERR_INV_HCI_CMD_PARMS; + case -ENOMEM: + return BLE_ERR_CONN_REJ_RESOURCES; + case -ENOENT: + return BLE_ERR_UNK_ADV_INDENT; + default: + return BLE_ERR_UNSPECIFIED; + } + + return 0; } int From 4dfc8eee377f275215f61cc7017242c6e081f105 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 30 Jan 2023 17:32:09 +0100 Subject: [PATCH 0712/1333] nimble/ll: Update supported commands bitmask --- nimble/controller/src/ble_ll_hci_supp_cmd.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_hci_supp_cmd.c b/nimble/controller/src/ble_ll_hci_supp_cmd.c index dc0df71497..f10c89890d 100644 --- a/nimble/controller/src/ble_ll_hci_supp_cmd.c +++ b/nimble/controller/src/ble_ll_hci_supp_cmd.c @@ -251,6 +251,18 @@ static const uint8_t octet_41 = OCTET( BIT(0) /* HCI LE Set Periodic Advertising Sync Transfer Parameters */ BIT(1) /* HCI LE Set Default Periodic Advertising Sync Transfer Parameters */ #endif +#if MYNEWT_VAL(BLE_LL_ISO) + BIT(5) /* HCI LE Read Buffer Size [v2] */ + BIT(6) /* HCI LE Read ISO TX Sync */ +#endif +); + +static const uint8_t octet_42 = OCTET( +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + BIT(5) /* HCI LE Create BIG */ + BIT(6) /* HCI LE Create BIG Test */ + BIT(7) /* HCI LE Terminate BIG */ +#endif ); static const uint8_t octet_43 = OCTET( @@ -315,7 +327,7 @@ static const uint8_t g_ble_ll_hci_supp_cmds[64] = { octet_39, octet_40, octet_41, - 0, + octet_42, octet_43, octet_44, 0, From b24051536a6e5feab45434cf7650800a7677ca31 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 31 May 2023 18:10:37 +0200 Subject: [PATCH 0713/1333] nimble/host: Add dummy implementation for ISO rx This just frees the buffer since host does not handle them (yet). --- nimble/host/src/ble_hs.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index aeace63af3..aa97c6bf05 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -799,6 +799,14 @@ ble_transport_to_hs_acl_impl(struct os_mbuf *om) return ble_hs_rx_data(om, NULL); } +int +ble_transport_to_hs_iso_impl(struct os_mbuf *om) +{ + os_mbuf_free_chain(om); + + return 0; +} + void ble_transport_hs_init(void) { From 16d255a36522ceed9ac9f64051c7547ec9b99be3 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 5 Jun 2023 13:07:59 +0200 Subject: [PATCH 0714/1333] nimble/ll: Add debug printf vs hci event This adds helper to send vs hci event with payload formatted in printf-like manner. This shall not be used in any publicly available code, it's only intended for local debugging purposes. --- .../include/controller/ble_ll_ctrl.h | 1 + nimble/controller/src/ble_ll_hci_ev.c | 31 ++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index 445ccc4f45..89502a45a3 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -335,6 +335,7 @@ void ble_ll_calc_session_key(struct ble_ll_conn_sm *connsm); void ble_ll_ctrl_phy_update_proc_complete(struct ble_ll_conn_sm *connsm); void ble_ll_ctrl_initiate_dle(struct ble_ll_conn_sm *connsm, bool initial); void ble_ll_hci_ev_send_vs_assert(const char *file, uint32_t line); +void ble_ll_hci_ev_send_vs_printf(uint8_t id, const char *fmt, ...); void ble_ll_hci_ev_send_vs_llcp_trace(uint8_t type, uint16_t handle, uint16_t count, void *pdu, size_t length); diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index bde965d478..6588fabedb 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -16,8 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -#include + #include +#include +#include +#include #include #include "syscfg/syscfg.h" #include "nimble/ble.h" @@ -609,6 +612,32 @@ ble_ll_hci_ev_send_vs_assert(const char *file, uint32_t line) } } +void +ble_ll_hci_ev_send_vs_printf(uint8_t id, const char *fmt, ...) +{ + struct ble_hci_ev_vs *ev; + struct ble_hci_ev *hci_ev; + va_list ap; + + hci_ev = ble_transport_alloc_evt(1); + if (!hci_ev) { + return; + } + + hci_ev->opcode = BLE_HCI_EVCODE_VS; + hci_ev->length = sizeof(*ev); + + ev = (void *) hci_ev->data; + ev->id = id; + + va_start(ap, fmt); + hci_ev->length += vsnprintf((void *)ev->data, + BLE_HCI_MAX_DATA_LEN - sizeof(*ev), fmt, ap); + va_end(ap); + + ble_ll_hci_event_send(hci_ev); +} + #if MYNEWT_VAL(BLE_LL_HCI_LLCP_TRACE) void ble_ll_hci_ev_send_vs_llcp_trace(uint8_t type, uint16_t handle, uint16_t count, From a974bbc0a78f69c75275a2730194b8ff93d601d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 7 Jun 2023 08:19:19 +0200 Subject: [PATCH 0715/1333] apps: bttester: fix attribute reporting in read by UUID There is no need to call `gatt_buf_add` when `gatt_buf` if filled using pointer `chr` from `gatt_buf_reserve`. This caused sending malformed data to BTP reposnse event. --- apps/bttester/src/gatt_cl.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/apps/bttester/src/gatt_cl.c b/apps/bttester/src/gatt_cl.c index 3ca5ecfc04..af08764292 100644 --- a/apps/bttester/src/gatt_cl.c +++ b/apps/bttester/src/gatt_cl.c @@ -844,7 +844,8 @@ read_uuid_cb(uint16_t conn_handle, rp->data_length = gatt_buf.len; rp->value_length = attr_len; rp->status = 0; - os_mbuf_append(buf, gatt_buf.buf + 1, gatt_buf.len - 1); + os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); + tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, CONTROLLER_INDEX, buf); read_destroy(); @@ -855,12 +856,6 @@ read_uuid_cb(uint16_t conn_handle, attr_len = attr->om->om_len; } - if (gatt_buf_add(attr->om->om_data, attr->om->om_len) == NULL) { - read_destroy(); - rc = BLE_HS_ENOMEM; - goto free; - } - chr = gatt_buf_reserve(sizeof(*chr) + attr->om->om_len); if (!chr) { read_destroy(); From 160e4332ce76ec2d1bdab33e101c093882d49c25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 9 Jun 2023 13:53:16 +0200 Subject: [PATCH 0716/1333] apps/bttester: fix retrieving app included services Local Included Service(s) values are retrieved using `ble_att_svr_read_handle`, which will lead to calling `entry->ha_cb` for Included Service. This will be `ble_gatts_inc_access`, which will not add UUID if it's not of 16 bit type. Use 16 bit UUID for included service. `out_att_err` is now set to 0 by default - it may be not overwritten if no error occured. This will lead to undefined behavior and incorrect data in BTP response. --- apps/bttester/src/gatt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/bttester/src/gatt.c b/apps/bttester/src/gatt.c index 02ea3ec727..dd7dadb4a5 100644 --- a/apps/bttester/src/gatt.c +++ b/apps/bttester/src/gatt.c @@ -138,7 +138,7 @@ gatt_svr_dsc_read_write_long_test(uint16_t conn_handle, uint16_t attr_handle, static const struct ble_gatt_svc_def gatt_svr_inc_svcs[] = { { .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = PTS_UUID_DECLARE(PTS_INC_SVC), + .uuid = BLE_UUID16_DECLARE(PTS_INC_SVC), .characteristics = (struct ble_gatt_chr_def[]) {{ .uuid = PTS_UUID_DECLARE(PTS_CHR_READ_WRITE_ALT), .access_cb = gatt_svr_read_write_test, @@ -1761,7 +1761,7 @@ get_attr_val(uint8_t *data, uint16_t len) struct ble_gap_conn_desc conn; struct os_mbuf *buf = os_msys_get(0, 0); uint16_t handle = sys_cpu_to_le16(cmd->handle); - uint8_t out_att_err; + uint8_t out_att_err = 0; int conn_status; conn_status = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); From 634e41b16655e31dd89fbb0b49e2732160332801 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 13 Jun 2023 11:49:14 +0200 Subject: [PATCH 0717/1333] nimble/ll: Fix clearing connsm flags We have over 32 flags so using union with uint32_t does not work anymore. Let's just use memset instead. --- nimble/controller/src/ble_ll_conn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index a4e6724132..a1ace9fbd2 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1976,7 +1976,7 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) struct ble_ll_conn_global_params *conn_params; /* Reset following elements */ - connsm->csmflags.conn_flags = 0; + memset(&connsm->csmflags, 0, sizeof(connsm->csmflags)); connsm->event_cntr = 0; connsm->conn_state = BLE_LL_CONN_STATE_IDLE; connsm->disconnect_reason = 0; From f561b746673dfc171c4534145849c259efa746a5 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 13 Jun 2023 12:13:48 +0200 Subject: [PATCH 0718/1333] nimble/ll: Fix connection update instant calculation The instant for connection update was calculated at the time PDU was enqueued in connsm. This caused new conn params to be always applied at instant regardless if PDU was event dequeued for tx, e.g. in case there were lots of data PDUs to be send before control PDU. Currently we calculate instant when PDU is dequeued to make sure this is the next PDU to be sent and thus instant is valid. --- .../include/controller/ble_ll_conn.h | 1 + nimble/controller/src/ble_ll_ctrl.c | 65 ++++++++++++------- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 7ba3c44f8c..fa1b926742 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -109,6 +109,7 @@ union ble_ll_conn_sm_flags { uint32_t awaiting_host_reply:1; uint32_t terminate_started:1; uint32_t conn_update_sched:1; + uint32_t conn_update_use_cp:1; uint32_t host_expects_upd_event:1; uint32_t version_ind_sent:1; uint32_t rxd_version_ind:1; diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 03b9177f6c..af227cb529 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -383,18 +383,28 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr, return rsp_opcode; } -/** - * Called to make a connection update request LL control PDU - * - * Context: Link Layer - * - * @param connsm - * @param rsp - */ static void -ble_ll_ctrl_conn_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld, - struct ble_ll_conn_params *cp) +ble_ll_ctrl_conn_update_init_proc(struct ble_ll_conn_sm *connsm, + struct ble_ll_conn_params *cp) +{ + /* This only stores conn params, if any. The caller will enqueue LL Control + * PDU and we will calculate its contents when dequeued so we know that + * instant is in the future. + */ + + connsm->csmflags.cfbit.conn_update_sched = 0; + connsm->csmflags.cfbit.conn_update_use_cp = (cp != NULL); + + if (cp) { + connsm->conn_cp = *cp; + } +} + +static void +ble_ll_ctrl_conn_update_make_ind_pdu(struct ble_ll_conn_sm *connsm, + uint8_t *ctrdata) { + struct ble_ll_conn_params *cp = NULL; struct ble_ll_conn_params offset_cp = { }; uint16_t instant; uint32_t dt; @@ -404,6 +414,10 @@ ble_ll_ctrl_conn_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld, struct hci_conn_update *hcu; struct ble_ll_conn_upd_req *req; + if (connsm->csmflags.cfbit.conn_update_use_cp) { + cp = &connsm->conn_cp; + } + /* * Set instant. We set the instant to the current event counter plus * the amount of peripheral latency as the peripheral may not be listening @@ -475,15 +489,12 @@ ble_ll_ctrl_conn_upd_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld, req->instant = instant; /* XXX: make sure this works for the connection parameter request proc. */ - pyld[0] = req->winsize; - put_le16(pyld + 1, req->winoffset); - put_le16(pyld + 3, req->interval); - put_le16(pyld + 5, req->latency); - put_le16(pyld + 7, req->timeout); - put_le16(pyld + 9, instant); - - /* Set flag in state machine to denote we have scheduled an update */ - connsm->csmflags.cfbit.conn_update_sched = 1; + ctrdata[0] = req->winsize; + put_le16(ctrdata + 1, req->winoffset); + put_le16(ctrdata + 3, req->interval); + put_le16(ctrdata + 5, req->latency); + put_le16(ctrdata + 7, req->timeout); + put_le16(ctrdata + 9, instant); } /** @@ -519,7 +530,7 @@ ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t * BLE_LL_CONN_CLEAR_FEATURE(connsm, BLE_LL_FEAT_CONN_PARM_REQ); #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { - ble_ll_ctrl_conn_upd_make(connsm, rspdata, NULL); + ble_ll_ctrl_conn_update_init_proc(connsm, NULL); connsm->reject_reason = BLE_ERR_SUCCESS; return BLE_LL_CTRL_CONN_UPDATE_IND; } @@ -1912,8 +1923,7 @@ ble_ll_ctrl_conn_param_reply(struct ble_ll_conn_sm *connsm, uint8_t *rsp, switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_CONN_ROLE_CENTRAL: - /* Create a connection update pdu */ - ble_ll_ctrl_conn_upd_make(connsm, rsp + 1, req); + ble_ll_ctrl_conn_update_init_proc(connsm, req); rsp_opcode = BLE_LL_CTRL_CONN_UPDATE_IND; break; #endif @@ -1967,7 +1977,7 @@ ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, case BLE_LL_CONN_ROLE_CENTRAL: /* As a central we should send connection update indication in this point */ rsp_opcode = BLE_LL_CTRL_CONN_UPDATE_IND; - ble_ll_ctrl_conn_upd_make(connsm, rspdata, NULL); + ble_ll_ctrl_conn_update_init_proc(connsm, NULL); connsm->reject_reason = BLE_ERR_SUCCESS; break; #endif @@ -2467,7 +2477,7 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc, void *data) switch (ctrl_proc) { case BLE_LL_CTRL_PROC_CONN_UPDATE: opcode = BLE_LL_CTRL_CONN_UPDATE_IND; - ble_ll_ctrl_conn_upd_make(connsm, ctrdata, data); + ble_ll_ctrl_conn_update_init_proc(connsm, data); break; case BLE_LL_CTRL_PROC_CHAN_MAP_UPD: opcode = BLE_LL_CTRL_CHANNEL_MAP_REQ; @@ -3116,9 +3126,16 @@ int ble_ll_ctrl_tx_start(struct ble_ll_conn_sm *connsm, struct os_mbuf *txpdu) { uint8_t opcode; + uint8_t *ctrdata; opcode = txpdu->om_data[0]; + ctrdata = &txpdu->om_data[1]; + switch (opcode) { + case BLE_LL_CTRL_CONN_UPDATE_IND: + ble_ll_ctrl_conn_update_make_ind_pdu(connsm, ctrdata); + connsm->csmflags.cfbit.conn_update_sched = 1; + break; case BLE_LL_CTRL_SUBRATE_IND: connsm->csmflags.cfbit.subrate_trans = 1; break; From 9d7c5c5006b1ea2c568db53f211ebb937b482e15 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 6 Jun 2023 00:43:05 +0200 Subject: [PATCH 0719/1333] nimble/ll: Simplify sync sched handling Make sync sched handling more like other items, i.e. scheduler item is set via internal API and scheduling funcs just do the necessary scheduling. --- .../include/controller/ble_ll_sched.h | 9 +-- nimble/controller/src/ble_ll_sched.c | 58 ++----------------- nimble/controller/src/ble_ll_sync.c | 46 ++++++++++++--- 3 files changed, 44 insertions(+), 69 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index 961a20aa4d..cceb96ce11 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -142,13 +142,8 @@ int ble_ll_sched_adv_new(struct ble_ll_sched_item *sch, /* Schedule periodic advertising event */ int ble_ll_sched_periodic_adv(struct ble_ll_sched_item *sch, bool first_event); -int ble_ll_sched_sync_reschedule(struct ble_ll_sched_item *sch, - uint32_t anchor_point, - uint8_t anchor_point_usecs, - uint32_t window_widening, int8_t phy_mode); -int ble_ll_sched_sync(struct ble_ll_sched_item *sch, - uint32_t beg_cputime, uint32_t rem_usecs, uint32_t offset, - int8_t phy_mode); +int ble_ll_sched_sync_reschedule(struct ble_ll_sched_item *sch, uint32_t ww_us); +int ble_ll_sched_sync(struct ble_ll_sched_item *sch); /* Reschedule an advertising event */ int ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch, diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index c4cbe14258..8e8cee18fe 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -671,38 +671,13 @@ ble_ll_sched_sync_overlaps_current(struct ble_ll_sched_item *sch) } int -ble_ll_sched_sync_reschedule(struct ble_ll_sched_item *sch, - uint32_t anchor_point, uint8_t anchor_point_usecs, - uint32_t window_widening, - int8_t phy_mode) +ble_ll_sched_sync_reschedule(struct ble_ll_sched_item *sch, uint32_t ww_us) { - uint8_t start_time_rem_usecs; - uint32_t start_time; - uint32_t end_time; - uint32_t dur; - int rc = 0; os_sr_t sr; + int rc = 0; - start_time = anchor_point; - start_time_rem_usecs = anchor_point_usecs; - - ble_ll_tmr_sub(&start_time, &start_time_rem_usecs, window_widening); - - dur = ble_ll_pdu_us(MYNEWT_VAL(BLE_LL_SCHED_SCAN_SYNC_PDU_LEN), - phy_mode); - end_time = start_time + ble_ll_tmr_u2t(dur); - - start_time -= g_ble_ll_sched_offset_ticks; - - /* Set schedule start and end times */ - sch->start_time = start_time; - sch->remainder = start_time_rem_usecs; - sch->end_time = end_time; - - /* Better be past current time or we just leave */ - if (LL_TMR_LEQ(sch->start_time, ble_ll_tmr_get())) { - return -1; - } + /* Adjust start time to include window widening */ + ble_ll_tmr_sub(&sch->start_time, &sch->remainder, ww_us); OS_ENTER_CRITICAL(sr); @@ -721,32 +696,11 @@ ble_ll_sched_sync_reschedule(struct ble_ll_sched_item *sch, } int -ble_ll_sched_sync(struct ble_ll_sched_item *sch, - uint32_t beg_cputime, uint32_t rem_usecs, - uint32_t offset, int8_t phy_mode) +ble_ll_sched_sync(struct ble_ll_sched_item *sch) { - uint8_t start_time_rem_usecs; - uint32_t start_time; - uint32_t end_time; - uint32_t dur; os_sr_t sr; int rc = 0; - start_time = beg_cputime; - start_time_rem_usecs = rem_usecs; - - ble_ll_tmr_add(&start_time, &start_time_rem_usecs, offset); - - dur = ble_ll_pdu_us(MYNEWT_VAL(BLE_LL_SCHED_SCAN_SYNC_PDU_LEN), - phy_mode); - end_time = start_time + ble_ll_tmr_u2t(dur); - - start_time -= g_ble_ll_sched_offset_ticks; - - sch->start_time = start_time; - sch->remainder = start_time_rem_usecs; - sch->end_time = end_time; - OS_ENTER_CRITICAL(sr); rc = ble_ll_sched_insert(sch, 0, preempt_none); @@ -755,8 +709,6 @@ ble_ll_sched_sync(struct ble_ll_sched_item *sch, ble_ll_sched_restart(); - STATS_INC(ble_ll_stats, sync_scheduled); - return rc; } #endif diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index f10a59938d..8aef8e2c82 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -25,6 +25,7 @@ #include "syscfg/syscfg.h" #include "controller/ble_ll.h" +#include "controller/ble_ll_pdu.h" #include "controller/ble_ll_hci.h" #include "controller/ble_ll_sync.h" #include "controller/ble_ll_utils.h" @@ -946,6 +947,26 @@ ble_ll_sync_parse_aux_ptr(const uint8_t *buf, uint8_t *chan, uint32_t *offset, *phy = (aux_ptr_field >> 21) & 0x07; } +static void +ble_ll_sync_sched_set(struct ble_ll_sched_item *sch, uint32_t start_ticks, + uint8_t start_rem_us, uint32_t offset, uint8_t phy_mode) +{ + uint32_t duration_us; + uint32_t duration; + + if (offset > 0) { + ble_ll_tmr_add(&start_ticks, &start_rem_us, offset); + } + + duration_us = ble_ll_pdu_us(MYNEWT_VAL(BLE_LL_SCHED_SCAN_SYNC_PDU_LEN), + phy_mode); + duration = ble_ll_tmr_u2t(duration_us); + + sch->start_time = start_ticks - g_ble_ll_sched_offset_ticks; + sch->remainder = start_rem_us; + sch->end_time = start_ticks + duration; +} + static int ble_ll_sync_schedule_chain(struct ble_ll_sync_sm *sm, struct ble_mbuf_hdr *hdr, const uint8_t *aux) @@ -980,8 +1001,10 @@ ble_ll_sync_schedule_chain(struct ble_ll_sync_sm *sm, struct ble_mbuf_hdr *hdr, sm->flags |= BLE_LL_SYNC_SM_FLAG_CHAIN; - return ble_ll_sched_sync(&sm->sch, hdr->beg_cputime, hdr->rem_usecs, - offset, sm->phy_mode); + ble_ll_sync_sched_set(&sm->sch, hdr->beg_cputime, hdr->rem_usecs, offset, + sm->phy_mode); + + return ble_ll_sched_sync(&sm->sch); } static void @@ -1358,9 +1381,10 @@ ble_ll_sync_event_end(struct ble_npl_event *ev) ble_ll_sync_sm_clear(sm); return; } - } while (ble_ll_sched_sync_reschedule(&sm->sch, sm->anchor_point, - sm->anchor_point_usecs, - sm->window_widening, sm->phy_mode)); + + ble_ll_sync_sched_set(&sm->sch, sm->anchor_point, + sm->anchor_point_usecs, 0, sm->phy_mode); + } while (ble_ll_sched_sync_reschedule(&sm->sch, sm->window_widening)); } void @@ -1498,8 +1522,10 @@ ble_ll_sync_info_event(struct ble_ll_scan_addr_data *addrd, sm->chan_index = ble_ll_utils_dci_csa2(sm->event_cntr, sm->channel_id, sm->chan_map_used, sm->chan_map); - if (ble_ll_sched_sync(&sm->sch, rxhdr->beg_cputime, rxhdr->rem_usecs, - offset, sm->phy_mode)) { + ble_ll_sync_sched_set(&sm->sch, rxhdr->beg_cputime, rxhdr->rem_usecs, + offset, sm->phy_mode); + + if (ble_ll_sched_sync(&sm->sch)) { return; } @@ -2093,8 +2119,10 @@ ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, } } - if (ble_ll_sched_sync(&sm->sch, sm->anchor_point, sm->anchor_point_usecs, - offset, sm->phy_mode)) { + ble_ll_sync_sched_set(&sm->sch, sm->anchor_point, sm->anchor_point_usecs, + offset, sm->phy_mode); + + if (ble_ll_sched_sync(&sm->sch)) { /* release SM if this failed */ ble_ll_sync_transfer_received(sm, BLE_ERR_CONN_ESTABLISHMENT); memset(sm, 0, sizeof(*sm)); From dce1a41a7dc9ad6b0cc6ac8dab40b6f8ee2a2c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 16 Jun 2023 14:22:01 +0200 Subject: [PATCH 0720/1333] apps/bttester: do not fail pairing if it's already active Sometimes it's simpler to call pair() even when procedure is already active. Do not fail command in this case, as it doesn't influence already ongoing procedure. --- apps/bttester/src/gap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/bttester/src/gap.c b/apps/bttester/src/gap.c index 655a82ec3d..c28853a0e3 100644 --- a/apps/bttester/src/gap.c +++ b/apps/bttester/src/gap.c @@ -1457,7 +1457,8 @@ pair(const uint8_t *data, uint16_t len) goto rsp; } - if (ble_gap_security_initiate(desc.conn_handle)) { + rc = ble_gap_security_initiate(desc.conn_handle); + if (rc != 0 && rc != BLE_HS_EALREADY) { status = BTP_STATUS_FAILED; goto rsp; } From 20a82a5de39f9cbf7492fef6dc4300be21c31c50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 15 Jun 2023 14:31:25 +0200 Subject: [PATCH 0721/1333] host/sm: split error check for SC Only requirements in Pair Response Different status shall be returned when key size is to small and when SC is not supported. This is affecting GAP/SEC/SEM/BV-23-C --- nimble/host/src/ble_sm.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 643712d491..dbea8b706e 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -1848,14 +1848,18 @@ ble_sm_pair_req_rx(uint16_t conn_handle, struct os_mbuf **om, } else if (req->max_enc_key_size > BLE_SM_PAIR_KEY_SZ_MAX) { res->sm_err = BLE_SM_ERR_INVAL; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_INVAL); - } else if (MYNEWT_VAL(BLE_SM_SC_ONLY) && ((req->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX) || - !(req->authreq & BLE_SM_PAIR_AUTHREQ_SC))) { - /* Fail if Secure Connections Only mode is on and remote does not meet - * key size requirements - MITM was checked in last step. Fail if SC is not supported - * by peer. + } else if (MYNEWT_VAL(BLE_SM_SC_ONLY)) { + /* Fail if Secure Connections Only mode is on and remote does not + * meet key size requirements - MITM was checked in last step. + * Fail if SC is not supported by peer or key size is too small */ - res->sm_err = BLE_SM_ERR_ENC_KEY_SZ; - res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_ENC_KEY_SZ); + if (!(req->authreq & BLE_SM_PAIR_AUTHREQ_SC)) { + res->sm_err = BLE_SM_ERR_AUTHREQ; + res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_AUTHREQ); + } else if (req->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX) { + res->sm_err = BLE_SM_ERR_ENC_KEY_SZ; + res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_ENC_KEY_SZ); + } } else if (!ble_sm_verify_auth_requirements(req->authreq)) { res->sm_err = BLE_SM_ERR_AUTHREQ; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_AUTHREQ); From 841fa4c7e65b06e7e977bf64e711c31cbe535c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 12 Jun 2023 12:06:04 +0200 Subject: [PATCH 0722/1333] apps: bttester: reject L2CAP connections basing on PSM only PSM on which Lower Tester requests connection fully defines what are requirements for request to be accepted. That means that `response` parameter should not be used to return errors from `tester_l2cap_event`, and is not needed. --- apps/bttester/src/l2cap.c | 59 +++++---------------------------------- 1 file changed, 7 insertions(+), 52 deletions(-) diff --git a/apps/bttester/src/l2cap.c b/apps/bttester/src/l2cap.c index 32baab1d91..768dd0ed0a 100644 --- a/apps/bttester/src/l2cap.c +++ b/apps/bttester/src/l2cap.c @@ -261,7 +261,6 @@ static int tester_l2cap_event(struct ble_l2cap_event *event, void *arg) { struct ble_l2cap_chan_info chan_info; - int accept_response; struct ble_gap_conn_desc conn; switch (event->type) { @@ -321,11 +320,12 @@ tester_l2cap_event(struct ble_l2cap_event *event, void *arg) if (conn.sec_state.key_size < 16) { return BLE_HS_EENCRYPT_KEY_SZ; } - } - - accept_response = POINTER_TO_INT(arg); - if (accept_response) { - return accept_response; + } else if (chan_info.psm == 0x00F5) { + /* TSPX_psm_encryption_required */ + ble_gap_conn_find(event->accept.conn_handle, &conn); + if (conn.sec_state.key_size == 0) { + return BLE_HS_EENCRYPT; + } } console_printf( @@ -563,52 +563,11 @@ send_data(const uint8_t *data, uint16_t len) BTP_STATUS_FAILED); } -static int -l2cap_coc_err2hs_err(uint16_t coc_err) -{ - switch (coc_err) { - case BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM: - return BLE_HS_ENOTSUP; - case BLE_L2CAP_COC_ERR_NO_RESOURCES: - return BLE_HS_ENOMEM; - case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN: - return BLE_HS_EAUTHEN; - case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR: - return BLE_HS_EAUTHOR; - case BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC: - return BLE_HS_EENCRYPT; - case BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ: - return BLE_HS_EENCRYPT_KEY_SZ; - case BLE_L2CAP_COC_ERR_UNACCEPTABLE_PARAMETERS: - return BLE_HS_EINVAL; - default: - return 0; - } -} - -static int -l2cap_btp_listen_err2coc_err(uint16_t coc_err) -{ - switch (coc_err) { - case 0x01: - return BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN; - case 0x02: - return BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR; - case 0x03: - return BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ; - case 0x04: - return BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC; - default: - return 0; - } -} - static void listen(const uint8_t *data, uint16_t len) { const struct l2cap_listen_cmd *cmd = (void *) data; uint16_t mtu = htole16(cmd->mtu); - uint16_t rsp = htole16(cmd->response); int rc; SYS_LOG_DBG(""); @@ -617,12 +576,8 @@ listen(const uint8_t *data, uint16_t len) mtu = TESTER_COC_MTU; } - rsp = l2cap_btp_listen_err2coc_err(rsp); - rsp = l2cap_coc_err2hs_err(rsp); - /* TODO: Handle cmd->transport flag */ - rc = ble_l2cap_create_server(cmd->psm, mtu, tester_l2cap_event, - INT_TO_POINTER(rsp)); + rc = ble_l2cap_create_server(cmd->psm, mtu, tester_l2cap_event, NULL); if (rc) { goto fail; } From 89db9ca298a0ec238109c881933598e4445d2f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 13 Jun 2023 08:30:30 +0200 Subject: [PATCH 0723/1333] host/sm: do not send Pairing Failed after receiving Pairing Failed When device receives Pairing Failed message, according to Core v5.4, Vol 3, Part H, 3.5.5: This is used when there has been a failure during pairing and reports that the pairing procedure has been stopped and no further communication for the current pairing procedure is to occur. Sending our own Pairing Failed is further communication. This affects SM/CEN/PKE/BI-02-C --- nimble/host/src/ble_sm.c | 22 ++++++++++++---------- nimble/host/src/ble_sm_priv.h | 3 ++- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index dbea8b706e..831cf0fcb2 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -904,7 +904,8 @@ ble_sm_chk_repeat_pairing(uint16_t conn_handle, } void -ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res) +ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res, + bool tx_fail) { struct ble_sm_proc *prev; struct ble_sm_proc *proc; @@ -937,7 +938,7 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res) } } - if (res->sm_err != 0) { + if (res->sm_err != 0 && tx_fail) { ble_sm_pair_fail_tx(conn_handle, res->sm_err); } @@ -1208,7 +1209,7 @@ ble_sm_enc_event_rx(uint16_t conn_handle, uint8_t evt_status, int encrypted) ble_hs_unlock(); res.bonded = bonded; - ble_sm_process_result(conn_handle, &res); + ble_sm_process_result(conn_handle, &res, true); } void @@ -1429,7 +1430,7 @@ ble_sm_ltk_req_rx(const struct ble_hci_ev_le_subev_lt_key_req *ev) } } - ble_sm_process_result(conn_handle, &res); + ble_sm_process_result(conn_handle, &res, true); return 0; } @@ -2576,7 +2577,7 @@ ble_sm_pair_initiate(uint16_t conn_handle) } if (proc != NULL) { - ble_sm_process_result(conn_handle, &res); + ble_sm_process_result(conn_handle, &res, true); } return res.app_status; @@ -2615,7 +2616,7 @@ ble_sm_slave_initiate(uint16_t conn_handle) ble_hs_unlock(); if (proc != NULL) { - ble_sm_process_result(conn_handle, &res); + ble_sm_process_result(conn_handle, &res, true); } return res.app_status; @@ -2669,7 +2670,7 @@ ble_sm_enc_initiate(uint16_t conn_handle, uint8_t key_size, ble_hs_unlock(); - ble_sm_process_result(conn_handle, &res); + ble_sm_process_result(conn_handle, &res, true); return res.app_status; } @@ -2707,7 +2708,8 @@ ble_sm_rx(struct ble_l2cap_chan *chan) memset(&res, 0, sizeof res); rx_cb(conn_handle, om, &res); - ble_sm_process_result(conn_handle, &res); + ble_sm_process_result(conn_handle, &res, op == BLE_SM_OP_PAIR_FAIL ? + false : true); rc = res.app_status; } else { rc = BLE_HS_ENOTSUP; @@ -2821,7 +2823,7 @@ ble_sm_inject_io(uint16_t conn_handle, struct ble_sm_io *pkey) return rc; } - ble_sm_process_result(conn_handle, &res); + ble_sm_process_result(conn_handle, &res, true); return res.app_status; } @@ -2834,7 +2836,7 @@ ble_sm_connection_broken(uint16_t conn_handle) res.app_status = BLE_HS_ENOTCONN; res.enc_cb = 1; - ble_sm_process_result(conn_handle, &res); + ble_sm_process_result(conn_handle, &res, true); } int diff --git a/nimble/host/src/ble_sm_priv.h b/nimble/host/src/ble_sm_priv.h index 27e75aa1d9..5e761c1e1a 100644 --- a/nimble/host/src/ble_sm_priv.h +++ b/nimble/host/src/ble_sm_priv.h @@ -381,7 +381,8 @@ uint8_t *ble_sm_our_pair_rand(struct ble_sm_proc *proc); uint8_t *ble_sm_peer_pair_rand(struct ble_sm_proc *proc); int ble_sm_ioact_state(uint8_t action); int ble_sm_proc_can_advance(struct ble_sm_proc *proc); -void ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res); +void ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res, + bool tx_fail); void ble_sm_confirm_advance(struct ble_sm_proc *proc); void ble_sm_ia_ra(struct ble_sm_proc *proc, uint8_t *out_iat, uint8_t *out_ia, From fe2e4fc6b6d2148a3cf7bd4068a4549b959253f3 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 13 Jun 2023 15:40:10 +0200 Subject: [PATCH 0724/1333] nimble/ll: Simplify connsm flags Since we no longer use union with uint32_t to clear flags, there's no point in having union so let's just convert it to regular struct. --- .../include/controller/ble_ll_conn.h | 109 +++++++++--------- nimble/controller/src/ble_ll_conn.c | 100 ++++++++-------- nimble/controller/src/ble_ll_conn_hci.c | 26 ++--- nimble/controller/src/ble_ll_ctrl.c | 66 ++++++----- nimble/controller/src/ble_ll_hci_ev.c | 2 +- 5 files changed, 152 insertions(+), 151 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index fa1b926742..234c164c4d 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -98,47 +98,46 @@ struct ble_ll_conn_enc_data #endif /* Connection state machine flags. */ -union ble_ll_conn_sm_flags { - struct { - uint32_t pkt_rxd:1; - uint32_t terminate_ind_txd:1; - uint32_t terminate_ind_rxd:1; - uint32_t terminate_ind_rxd_acked:1; - uint32_t allow_periph_latency:1; - uint32_t periph_set_last_anchor:1; - uint32_t awaiting_host_reply:1; - uint32_t terminate_started:1; - uint32_t conn_update_sched:1; - uint32_t conn_update_use_cp:1; - uint32_t host_expects_upd_event:1; - uint32_t version_ind_sent:1; - uint32_t rxd_version_ind:1; - uint32_t chanmap_update_scheduled:1; - uint32_t conn_empty_pdu_txd:1; - uint32_t last_txd_md:1; - uint32_t conn_req_txd:1; - uint32_t send_ltk_req:1; - uint32_t encrypted:1; - uint32_t encrypt_chg_sent:1; - uint32_t le_ping_supp:1; - uint32_t csa2_supp:1; - uint32_t host_phy_update: 1; - uint32_t phy_update_sched: 1; - uint32_t ctrlr_phy_update: 1; - uint32_t phy_update_event: 1; - uint32_t peer_phy_update: 1; /* XXX:combine with ctrlr udpate bit? */ - uint32_t aux_conn_req: 1; - uint32_t rxd_features:1; - uint32_t pending_hci_rd_features:1; +struct ble_ll_conn_sm_flags { + uint32_t pkt_rxd : 1; + uint32_t terminate_ind_txd : 1; + uint32_t terminate_ind_rxd : 1; + uint32_t terminate_ind_rxd_acked : 1; + uint32_t allow_periph_latency : 1; + uint32_t periph_set_last_anchor : 1; + uint32_t awaiting_host_reply : 1; + uint32_t terminate_started : 1; + uint32_t conn_update_sched : 1; + uint32_t conn_update_use_cp : 1; + uint32_t host_expects_upd_event : 1; + uint32_t version_ind_sent : 1; + uint32_t rxd_version_ind : 1; + uint32_t chanmap_update_scheduled : 1; + uint32_t conn_empty_pdu_txd : 1; + uint32_t last_txd_md : 1; + uint32_t conn_req_txd : 1; + uint32_t send_ltk_req : 1; + uint32_t encrypted : 1; + uint32_t encrypt_chg_sent : 1; + uint32_t le_ping_supp : 1; + uint32_t csa2_supp : 1; + uint32_t host_phy_update: 1; + uint32_t phy_update_sched: 1; + uint32_t ctrlr_phy_update: 1; + uint32_t phy_update_event: 1; + uint32_t peer_phy_update: 1; /* XXX:combine with ctrlr udpate bit? */ + uint32_t aux_conn_req: 1; + uint32_t rxd_features : 1; + uint32_t pending_hci_rd_features : 1; #if MYNEWT_VAL(BLE_LL_CONN_INIT_AUTO_DLE) - uint32_t pending_initiate_dle:1; + uint32_t pending_initiate_dle : 1; #endif - uint32_t subrate_trans:1; - uint32_t subrate_ind_txd:1; - uint32_t subrate_host_req:1; - } cfbit; - uint32_t conn_flags; -} __attribute__((packed)); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + uint8_t subrate_trans : 1; + uint8_t subrate_ind_txd : 1; + uint8_t subrate_host_req : 1; +#endif +}; /** * Structure used for PHY data inside a connection. @@ -207,7 +206,7 @@ struct ble_ll_conn_subrate_req_params { struct ble_ll_conn_sm { /* Connection state machine flags */ - union ble_ll_conn_sm_flags csmflags; + struct ble_ll_conn_sm_flags flags; /* Current connection handle, state and role */ uint16_t conn_handle; @@ -402,21 +401,21 @@ struct ble_ll_conn_sm }; /* Flags */ -#define CONN_F_UPDATE_SCHED(csm) ((csm)->csmflags.cfbit.conn_update_sched) -#define CONN_F_EMPTY_PDU_TXD(csm) ((csm)->csmflags.cfbit.conn_empty_pdu_txd) -#define CONN_F_LAST_TXD_MD(csm) ((csm)->csmflags.cfbit.last_txd_md) -#define CONN_F_CONN_REQ_TXD(csm) ((csm)->csmflags.cfbit.conn_req_txd) -#define CONN_F_ENCRYPTED(csm) ((csm)->csmflags.cfbit.encrypted) -#define CONN_F_ENC_CHANGE_SENT(csm) ((csm)->csmflags.cfbit.encrypt_chg_sent) -#define CONN_F_LE_PING_SUPP(csm) ((csm)->csmflags.cfbit.le_ping_supp) -#define CONN_F_TERMINATE_STARTED(csm) ((csm)->csmflags.cfbit.terminate_started) -#define CONN_F_CSA2_SUPP(csm) ((csm)->csmflags.cfbit.csa2_supp) -#define CONN_F_HOST_PHY_UPDATE(csm) ((csm)->csmflags.cfbit.host_phy_update) -#define CONN_F_PHY_UPDATE_SCHED(csm) ((csm)->csmflags.cfbit.phy_update_sched) -#define CONN_F_CTRLR_PHY_UPDATE(csm) ((csm)->csmflags.cfbit.ctrlr_phy_update) -#define CONN_F_PHY_UPDATE_EVENT(csm) ((csm)->csmflags.cfbit.phy_update_event) -#define CONN_F_PEER_PHY_UPDATE(csm) ((csm)->csmflags.cfbit.peer_phy_update) -#define CONN_F_AUX_CONN_REQ(csm) ((csm)->csmflags.cfbit.aux_conn_req) +#define CONN_F_UPDATE_SCHED(csm) ((csm)->csmflags.conn_update_sched) +#define CONN_F_EMPTY_PDU_TXD(csm) ((csm)->flags.conn_empty_pdu_txd) +#define CONN_F_LAST_TXD_MD(csm) ((csm)->flags.last_txd_md) +#define CONN_F_CONN_REQ_TXD(csm) ((csm)->csmflags.conn_req_txd) +#define CONN_F_ENCRYPTED(csm) ((csm)->flags.encrypted) +#define CONN_F_ENC_CHANGE_SENT(csm) ((csm)->flags.encrypt_chg_sent) +#define CONN_F_LE_PING_SUPP(csm) ((csm)->flags.le_ping_supp) +#define CONN_F_TERMINATE_STARTED(csm) ((csm)->flags.terminate_started) +#define CONN_F_CSA2_SUPP(csm) ((csm)->flags.csa2_supp) +#define CONN_F_HOST_PHY_UPDATE(csm) ((csm)->flags.host_phy_update) +#define CONN_F_PHY_UPDATE_SCHED(csm) ((csm)->flags.phy_update_sched) +#define CONN_F_CTRLR_PHY_UPDATE(csm) ((csm)->flags.ctrlr_phy_update) +#define CONN_F_PHY_UPDATE_EVENT(csm) ((csm)->flags.phy_update_event) +#define CONN_F_PEER_PHY_UPDATE(csm) ((csm)->flags.peer_phy_update) +#define CONN_F_AUX_CONN_REQ(csm) ((csm)->csmflags.aux_conn_req) /* Role */ #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index a1ace9fbd2..d39fbe59d9 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -969,7 +969,7 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm) uint8_t update_status; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (connsm->csmflags.cfbit.send_ltk_req) { + if (connsm->flags.send_ltk_req) { /* * Send Long term key request event to host. If masked, we need to * send a REJECT_IND. @@ -978,7 +978,7 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm) ble_ll_ctrl_reject_ind_send(connsm, BLE_LL_CTRL_ENC_REQ, BLE_ERR_PINKEY_MISSING); } - connsm->csmflags.cfbit.send_ltk_req = 0; + connsm->flags.send_ltk_req = 0; } #endif @@ -988,7 +988,7 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm) * has passed the instant. * 2) We successfully sent the reject reason. */ - if (connsm->csmflags.cfbit.host_expects_upd_event) { + if (connsm->flags.host_expects_upd_event) { update_status = BLE_ERR_SUCCESS; if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_UPDATE)) { ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CONN_UPDATE); @@ -999,7 +999,7 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm) } } ble_ll_hci_ev_conn_update(connsm, update_status); - connsm->csmflags.cfbit.host_expects_upd_event = 0; + connsm->flags.host_expects_upd_event = 0; } /* Check if we need to send PHY update complete event */ @@ -1014,12 +1014,12 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - if (connsm->csmflags.cfbit.subrate_ind_txd) { + if (connsm->flags.subrate_ind_txd) { ble_ll_conn_subrate_set(connsm, &connsm->subrate_trans); connsm->subrate_trans.subrate_factor = 0; ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_SUBRATE_UPDATE); - connsm->csmflags.cfbit.subrate_ind_txd = 0; - connsm->csmflags.cfbit.subrate_host_req = 0; + connsm->flags.subrate_ind_txd = 0; + connsm->flags.subrate_host_req = 0; } #endif /* BLE_LL_CTRL_SUBRATE_IND */ #endif /* BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE */ @@ -1109,7 +1109,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) md = 0; hdr_byte = BLE_LL_LLID_DATA_FRAG; - if (connsm->csmflags.cfbit.terminate_ind_rxd) { + if (connsm->flags.terminate_ind_rxd) { /* We just received terminate indication. * Just send empty packet as an ACK */ @@ -1337,7 +1337,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) * We could do this. Now, we just keep going and hope that we dont * overrun next scheduled item. */ - if ((connsm->csmflags.cfbit.terminate_ind_rxd) || + if ((connsm->flags.terminate_ind_rxd) || (CONN_IS_PERIPHERAL(connsm) && (md == 0) && (connsm->cons_rxd_bad_crc == 0) && ((connsm->last_rxd_hdr_byte & BLE_LL_DATA_HDR_MD_MASK) == 0) && @@ -1449,8 +1449,8 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) /* Increment packets transmitted */ if (CONN_F_EMPTY_PDU_TXD(connsm)) { - if (connsm->csmflags.cfbit.terminate_ind_rxd) { - connsm->csmflags.cfbit.terminate_ind_rxd_acked = 1; + if (connsm->flags.terminate_ind_rxd) { + connsm->flags.terminate_ind_rxd_acked = 1; } STATS_INC(ble_ll_conn_stats, tx_empty_pdus); } else if ((hdr_byte & BLE_LL_DATA_HDR_LLID_MASK) == BLE_LL_LLID_CTRL) { @@ -1582,7 +1582,7 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) * Set flag that tells peripheral to set last anchor point if a packet * has been received. */ - connsm->csmflags.cfbit.periph_set_last_anchor = 1; + connsm->flags.periph_set_last_anchor = 1; /* * Set the wait for response time. The anchor point is when we @@ -1976,7 +1976,7 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) struct ble_ll_conn_global_params *conn_params; /* Reset following elements */ - memset(&connsm->csmflags, 0, sizeof(connsm->csmflags)); + memset(&connsm->flags, 0, sizeof(connsm->flags)); connsm->event_cntr = 0; connsm->conn_state = BLE_LL_CONN_STATE_IDLE; connsm->disconnect_reason = 0; @@ -2239,19 +2239,19 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err) * If we have features and there's pending HCI command, send an event before * disconnection event so it does make sense to host. */ - if (connsm->csmflags.cfbit.pending_hci_rd_features && - connsm->csmflags.cfbit.rxd_features) { + if (connsm->flags.pending_hci_rd_features && + connsm->flags.rxd_features) { ble_ll_hci_ev_rd_rem_used_feat(connsm, BLE_ERR_SUCCESS); - connsm->csmflags.cfbit.pending_hci_rd_features = 0; + connsm->flags.pending_hci_rd_features = 0; } /* * If there is still pending read features request HCI command, send an * event to complete it. */ - if (connsm->csmflags.cfbit.pending_hci_rd_features) { + if (connsm->flags.pending_hci_rd_features) { ble_ll_hci_ev_rd_rem_used_feat(connsm, ble_err); - connsm->csmflags.cfbit.pending_hci_rd_features = 0; + connsm->flags.pending_hci_rd_features = 0; } /* @@ -2263,7 +2263,7 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err) * received and we should not send an event. */ if (ble_err && (ble_err != BLE_ERR_UNK_CONN_ID || - connsm->csmflags.cfbit.terminate_ind_rxd)) { + connsm->flags.terminate_ind_rxd)) { ble_ll_disconn_comp_event_send(connsm, ble_err); } @@ -2413,11 +2413,11 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) /* Set event counter to the next connection event that we will tx/rx in */ use_periph_latency = next_is_subrated && - connsm->csmflags.cfbit.allow_periph_latency && - !connsm->csmflags.cfbit.conn_update_sched && - !connsm->csmflags.cfbit.phy_update_sched && - !connsm->csmflags.cfbit.chanmap_update_scheduled && - connsm->csmflags.cfbit.pkt_rxd; + connsm->flags.allow_periph_latency && + !connsm->flags.conn_update_sched && + !connsm->flags.phy_update_sched && + !connsm->flags.chanmap_update_scheduled && + connsm->flags.pkt_rxd; if (next_is_subrated) { next_event_cntr = base_event_cntr + subrate_factor; @@ -2429,7 +2429,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) /* If we are in subrate transition mode, we should also listen on * subrated connection events based on new parameters. */ - if (connsm->csmflags.cfbit.subrate_trans) { + if (connsm->flags.subrate_trans) { BLE_LL_ASSERT(CONN_IS_CENTRAL(connsm)); cstp = &connsm->subrate_trans; @@ -2455,7 +2455,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) * and one connection event before instant regardless of subrating. */ if (CONN_IS_PERIPHERAL(connsm) && - connsm->csmflags.cfbit.conn_update_sched && + connsm->flags.conn_update_sched && (connsm->subrate_factor > 1)) { subrate_conn_upd_event_cntr = connsm->conn_update_req.instant - 1; if (connsm->event_cntr == subrate_conn_upd_event_cntr) { @@ -2524,7 +2524,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) * connection by the the transmit window offset. We also copy in the * update parameters as they now should take effect. */ - if (connsm->csmflags.cfbit.conn_update_sched && + if (connsm->flags.conn_update_sched && (connsm->event_cntr == connsm->conn_update_req.instant)) { /* Set flag so we send connection update event */ @@ -2535,7 +2535,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) (connsm->conn_itvl != upd->interval) || (connsm->periph_latency != upd->latency) || (connsm->supervision_tmo != upd->timeout)) { - connsm->csmflags.cfbit.host_expects_upd_event = 1; + connsm->flags.host_expects_upd_event = 1; } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) @@ -2602,7 +2602,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) connsm->last_rxd_pdu_cputime = connsm->anchor_point; /* Reset update scheduled flag */ - connsm->csmflags.cfbit.conn_update_sched = 0; + connsm->flags.conn_update_sched = 0; } /* @@ -2614,7 +2614,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) * new channel map once the event counter equals or has passed channel * map update instant. */ - if (connsm->csmflags.cfbit.chanmap_update_scheduled && + if (connsm->flags.chanmap_update_scheduled && ((int16_t)(connsm->chanmap_instant - connsm->event_cntr) <= 0)) { /* XXX: there is a chance that the control packet is still on @@ -2625,7 +2625,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) ble_ll_utils_chan_map_used_get(connsm->req_chanmap); memcpy(connsm->chan_map, connsm->req_chanmap, BLE_LL_CHAN_MAP_LEN); - connsm->csmflags.cfbit.chanmap_update_scheduled = 0; + connsm->flags.chanmap_update_scheduled = 0; ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CHAN_MAP_UPD); @@ -2773,7 +2773,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) connsm->conn_state = BLE_LL_CONN_STATE_CREATED; /* Clear packet received flag */ - connsm->csmflags.cfbit.pkt_rxd = 0; + connsm->flags.pkt_rxd = 0; /* Consider time created the last scheduled time */ connsm->last_scheduled = ble_ll_tmr_get(); @@ -2929,10 +2929,10 @@ ble_ll_conn_event_end(struct ble_npl_event *ev) ble_ll_scan_chk_resume(); /* If we have transmitted the terminate IND successfully, we are done */ - if ((connsm->csmflags.cfbit.terminate_ind_txd) || - (connsm->csmflags.cfbit.terminate_ind_rxd && - connsm->csmflags.cfbit.terminate_ind_rxd_acked)) { - if (connsm->csmflags.cfbit.terminate_ind_txd) { + if ((connsm->flags.terminate_ind_txd) || + (connsm->flags.terminate_ind_rxd && + connsm->flags.terminate_ind_rxd_acked)) { + if (connsm->flags.terminate_ind_txd) { ble_err = BLE_ERR_CONN_TERM_LOCAL; } else { /* Make sure the disconnect reason is valid! */ @@ -2952,7 +2952,7 @@ ble_ll_conn_event_end(struct ble_npl_event *ev) * If we have received a packet, we can set the current transmit window * usecs to 0 since we dont need to listen in the transmit window. */ - if (connsm->csmflags.cfbit.pkt_rxd) { + if (connsm->flags.pkt_rxd) { connsm->periph_cur_tx_win_usecs = 0; } @@ -2979,7 +2979,7 @@ ble_ll_conn_event_end(struct ble_npl_event *ev) /* Reset "per connection event" variables */ connsm->cons_rxd_bad_crc = 0; - connsm->csmflags.cfbit.pkt_rxd = 0; + connsm->flags.pkt_rxd = 0; /* See if we need to start any control procedures */ ble_ll_ctrl_chk_proc_start(connsm); @@ -3030,10 +3030,10 @@ ble_ll_conn_event_end(struct ble_npl_event *ev) ble_ll_conn_num_comp_pkts_event_send(connsm); /* If we have features and there's pending HCI command, send an event */ - if (connsm->csmflags.cfbit.pending_hci_rd_features && - connsm->csmflags.cfbit.rxd_features) { + if (connsm->flags.pending_hci_rd_features && + connsm->flags.rxd_features) { ble_ll_hci_ev_rd_rem_used_feat(connsm, BLE_ERR_SUCCESS); - connsm->csmflags.cfbit.pending_hci_rd_features = 0; + connsm->flags.pending_hci_rd_features = 0; } } @@ -3192,7 +3192,7 @@ ble_ll_conn_event_halt(void) { ble_ll_state_set(BLE_LL_STATE_STANDBY); if (g_ble_ll_conn_cur_sm) { - g_ble_ll_conn_cur_sm->csmflags.cfbit.pkt_rxd = 0; + g_ble_ll_conn_cur_sm->flags.pkt_rxd = 0; ble_ll_event_add(&g_ble_ll_conn_cur_sm->conn_ev_end); g_ble_ll_conn_cur_sm = NULL; } @@ -3400,14 +3400,14 @@ ble_ll_conn_rx_isr_start(struct ble_mbuf_hdr *rxhdr, uint32_t aa) rxhdr->rxinfo.handle = connsm->conn_handle; /* Set flag denoting we have received a packet in connection event */ - connsm->csmflags.cfbit.pkt_rxd = 1; + connsm->flags.pkt_rxd = 1; /* Connection is established */ connsm->conn_state = BLE_LL_CONN_STATE_ESTABLISHED; /* Set anchor point (and last) if 1st rxd frame in connection event */ - if (connsm->csmflags.cfbit.periph_set_last_anchor) { - connsm->csmflags.cfbit.periph_set_last_anchor = 0; + if (connsm->flags.periph_set_last_anchor) { + connsm->flags.periph_set_last_anchor = 0; connsm->last_anchor_point = rxhdr->beg_cputime; connsm->anchor_point = connsm->last_anchor_point; connsm->anchor_point_usecs = rxhdr->rem_usecs; @@ -3519,7 +3519,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { if (hdr_byte & BLE_LL_DATA_HDR_NESN_MASK) { - connsm->csmflags.cfbit.allow_periph_latency = 1; + connsm->flags.allow_periph_latency = 1; } } #endif @@ -3857,7 +3857,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) if (BLE_LL_LLID_IS_CTRL(hdr_byte) && (opcode == BLE_LL_CTRL_TERMINATE_IND) && (rx_pyld_len == (1 + BLE_LL_CTRL_TERMINATE_IND_LEN))) { - connsm->csmflags.cfbit.terminate_ind_rxd = 1; + connsm->flags.terminate_ind_rxd = 1; connsm->rxd_disconnect_reason = rxbuf[3]; } @@ -4244,14 +4244,14 @@ ble_ll_conn_subrate_req_hci(struct ble_ll_conn_sm *connsm, connsm->subrate_trans.periph_latency = srp->max_latency; connsm->subrate_trans.cont_num = srp->cont_num; connsm->subrate_trans.supervision_tmo = srp->supervision_tmo; - connsm->csmflags.cfbit.subrate_host_req = 1; + connsm->flags.subrate_host_req = 1; ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SUBRATE_UPDATE, NULL); break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_CONN_ROLE_PERIPHERAL: connsm->subrate_req = *srp; - connsm->csmflags.cfbit.subrate_host_req = 1; + connsm->flags.subrate_host_req = 1; ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SUBRATE_REQ, NULL); break; #endif @@ -4316,7 +4316,7 @@ ble_ll_conn_subrate_set(struct ble_ll_conn_sm *connsm, /* Assume parameters were checked by caller */ - send_ev = connsm->csmflags.cfbit.subrate_host_req || + send_ev = connsm->flags.subrate_host_req || (connsm->subrate_factor != sp->subrate_factor) || (connsm->periph_latency != sp->periph_latency) || (connsm->cont_num != sp->cont_num) || diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 175a64266e..3cedc12ff6 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -921,7 +921,7 @@ ble_ll_conn_hci_read_rem_features(const uint8_t *cmdbuf, uint8_t len) } /* If already pending exit with error */ - if (connsm->csmflags.cfbit.pending_hci_rd_features) { + if (connsm->flags.pending_hci_rd_features) { return BLE_ERR_CMD_DISALLOWED; } @@ -929,8 +929,8 @@ ble_ll_conn_hci_read_rem_features(const uint8_t *cmdbuf, uint8_t len) * Start control procedure if we did not receive peer's features and did not * start procedure already. */ - if (!connsm->csmflags.cfbit.rxd_features && - !IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG)) { + if (!connsm->flags.rxd_features && + !IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG)) { #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if ((connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) && !(ble_ll_read_supp_features() & BLE_LL_FEAT_PERIPH_INIT)) { @@ -941,7 +941,7 @@ ble_ll_conn_hci_read_rem_features(const uint8_t *cmdbuf, uint8_t len) ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG, NULL); } - connsm->csmflags.cfbit.pending_hci_rd_features = 1; + connsm->flags.pending_hci_rd_features = 1; return BLE_ERR_SUCCESS; } @@ -1062,11 +1062,11 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) * peripheral has initiated the procedure, we need to send a reject to the * peripheral. */ - if (connsm->csmflags.cfbit.awaiting_host_reply) { + if (connsm->flags.awaiting_host_reply) { switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_CONN_ROLE_CENTRAL: - connsm->csmflags.cfbit.awaiting_host_reply = 0; + connsm->flags.awaiting_host_reply = 0; /* XXX: If this fails no reject ind will be sent! */ ble_ll_ctrl_reject_ind_send(connsm, connsm->host_reply_opcode, @@ -1089,7 +1089,7 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) * update procedure we should deny the peripheral request for now. */ #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - if (connsm->csmflags.cfbit.chanmap_update_scheduled) { + if (connsm->flags.chanmap_update_scheduled) { if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { return BLE_ERR_DIFF_TRANS_COLL; } @@ -1159,7 +1159,7 @@ ble_ll_conn_hci_param_rr(const uint8_t *cmdbuf, uint8_t len, rc = ble_ll_conn_process_conn_params(cmd, connsm); /* The connection should be awaiting a reply. If not, just discard */ - if (connsm->csmflags.cfbit.awaiting_host_reply) { + if (connsm->flags.awaiting_host_reply) { /* Get a control packet buffer */ if (rc == BLE_ERR_SUCCESS) { om = os_msys_get_pkthdr(BLE_LL_CTRL_MAX_PDU_LEN, @@ -1177,7 +1177,7 @@ ble_ll_conn_hci_param_rr(const uint8_t *cmdbuf, uint8_t len, ble_ll_ctrl_reject_ind_send(connsm, connsm->host_reply_opcode, BLE_ERR_CONN_PARMS); } - connsm->csmflags.cfbit.awaiting_host_reply = 0; + connsm->flags.awaiting_host_reply = 0; /* XXX: if we cant get a buffer, what do we do? We need to remember * reason if it was a negative reply. We also would need to have @@ -1224,11 +1224,11 @@ ble_ll_conn_hci_param_nrr(const uint8_t *cmdbuf, uint8_t len, rc = BLE_ERR_SUCCESS; /* The connection should be awaiting a reply. If not, just discard */ - if (connsm->csmflags.cfbit.awaiting_host_reply) { + if (connsm->flags.awaiting_host_reply) { /* XXX: check return code and deal */ ble_ll_ctrl_reject_ind_send(connsm, connsm->host_reply_opcode, cmd->reason); - connsm->csmflags.cfbit.awaiting_host_reply = 0; + connsm->flags.awaiting_host_reply = 0; /* XXX: if we cant get a buffer, what do we do? We need to remember * reason if it was a negative reply. We also would need to have @@ -1393,7 +1393,7 @@ ble_ll_conn_hci_rd_rem_ver_cmd(const uint8_t *cmdbuf, uint8_t len) * NOTE: we cant just send the event here. That would cause the event to * be queued before the command status. */ - if (!connsm->csmflags.cfbit.version_ind_sent) { + if (!connsm->flags.version_ind_sent) { ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_VERSION_XCHG, NULL); } else { connsm->pending_ctrl_procs |= (1 << BLE_LL_CTRL_PROC_VERSION_XCHG); @@ -1468,7 +1468,7 @@ ble_ll_conn_hci_rd_chan_map(const uint8_t *cmdbuf, uint8_t len, rc = BLE_ERR_UNK_CONN_ID; memset(rsp->chan_map, 0, sizeof(rsp->chan_map)); } else { - if (connsm->csmflags.cfbit.chanmap_update_scheduled) { + if (connsm->flags.chanmap_update_scheduled) { memcpy(rsp->chan_map, connsm->req_chanmap, BLE_LL_CHAN_MAP_LEN); } else { memcpy(rsp->chan_map, connsm->chan_map, BLE_LL_CHAN_MAP_LEN); diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index af227cb529..726a44de9b 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -367,7 +367,7 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr, */ ble_ll_hci_ev_rem_conn_parm_req(connsm, req); connsm->host_reply_opcode = opcode; - connsm->csmflags.cfbit.awaiting_host_reply = 1; + connsm->flags.awaiting_host_reply = 1; rsp_opcode = 255; } else { /* Create reply to connection request */ @@ -392,8 +392,8 @@ ble_ll_ctrl_conn_update_init_proc(struct ble_ll_conn_sm *connsm, * instant is in the future. */ - connsm->csmflags.cfbit.conn_update_sched = 0; - connsm->csmflags.cfbit.conn_update_use_cp = (cp != NULL); + connsm->flags.conn_update_sched = 0; + connsm->flags.conn_update_use_cp = (cp != NULL); if (cp) { connsm->conn_cp = *cp; @@ -414,7 +414,7 @@ ble_ll_ctrl_conn_update_make_ind_pdu(struct ble_ll_conn_sm *connsm, struct hci_conn_update *hcu; struct ble_ll_conn_upd_req *req; - if (connsm->csmflags.cfbit.conn_update_use_cp) { + if (connsm->flags.conn_update_use_cp) { cp = &connsm->conn_cp; } @@ -570,11 +570,11 @@ ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t * if (ctrl_proc == BLE_LL_CTRL_PROC_CONN_PARAM_REQ) { ble_ll_hci_ev_conn_update(connsm, BLE_ERR_UNSUPP_REM_FEATURE); } else if (ctrl_proc == BLE_LL_CTRL_PROC_FEATURE_XCHG) { - if (connsm->csmflags.cfbit.pending_hci_rd_features) { + if (connsm->flags.pending_hci_rd_features) { ble_ll_hci_ev_rd_rem_used_feat(connsm, BLE_ERR_UNSUPP_REM_FEATURE); } - connsm->csmflags.cfbit.pending_hci_rd_features = 0; + connsm->flags.pending_hci_rd_features = 0; } } @@ -1290,7 +1290,7 @@ ble_ll_ctrl_rx_subrate_ind(struct ble_ll_conn_sm *connsm, uint8_t *req, ble_ll_conn_subrate_set(connsm, sp); ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_SUBRATE_REQ); - connsm->csmflags.cfbit.subrate_host_req = 0; + connsm->flags.subrate_host_req = 0; return BLE_ERR_MAX; } @@ -1875,7 +1875,7 @@ static void ble_ll_ctrl_version_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld) { /* Set flag to denote we have sent/received this */ - connsm->csmflags.cfbit.version_ind_sent = 1; + connsm->flags.version_ind_sent = 1; /* Fill out response */ pyld[0] = BLE_HCI_VER_BCS; @@ -1901,7 +1901,7 @@ ble_ll_ctrl_chanmap_req_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld) put_le16(pyld + BLE_LL_CHAN_MAP_LEN, connsm->chanmap_instant); /* Set scheduled flag */ - connsm->csmflags.cfbit.chanmap_update_scheduled = 1; + connsm->flags.chanmap_update_scheduled = 1; } /** @@ -2073,7 +2073,7 @@ ble_ll_ctrl_rx_conn_update(struct ble_ll_conn_sm *connsm, uint8_t *dptr) if (conn_events >= 32767) { ble_ll_conn_timeout(connsm, BLE_ERR_INSTANT_PASSED); } else { - connsm->csmflags.cfbit.conn_update_sched = 1; + connsm->flags.conn_update_sched = 1; /* * Errata says that receiving a connection update when the event @@ -2125,7 +2125,7 @@ ble_ll_ctrl_update_features(struct ble_ll_conn_sm *connsm, uint8_t *feat) memcpy(connsm->remote_features, feat + 1, 7); /* If we received peer's features for the 1st time, we should try DLE */ - if (!connsm->csmflags.cfbit.rxd_features) { + if (!connsm->flags.rxd_features) { #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) /* * If connection was established on uncoded PHY, by default we use @@ -2151,10 +2151,10 @@ ble_ll_ctrl_update_features(struct ble_ll_conn_sm *connsm, uint8_t *feat) #endif #if MYNEWT_VAL(BLE_LL_CONN_INIT_AUTO_DLE) - connsm->csmflags.cfbit.pending_initiate_dle = 1; + connsm->flags.pending_initiate_dle = 1; #endif - connsm->csmflags.cfbit.rxd_features = 1; + connsm->flags.rxd_features = 1; } } @@ -2234,9 +2234,9 @@ ble_ll_ctrl_rx_feature_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr) } /* Send event to host if pending features read */ - if (connsm->csmflags.cfbit.pending_hci_rd_features) { + if (connsm->flags.pending_hci_rd_features) { ble_ll_hci_ev_rd_rem_used_feat(connsm, BLE_ERR_SUCCESS); - connsm->csmflags.cfbit.pending_hci_rd_features = 0; + connsm->flags.pending_hci_rd_features = 0; } } @@ -2265,7 +2265,7 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * well. This is not expected to happen anyway. A return of BLE_ERR_MAX * means that we will simply discard the connection parameter request */ - if (connsm->csmflags.cfbit.awaiting_host_reply) { + if (connsm->flags.awaiting_host_reply) { return BLE_ERR_MAX; } @@ -2326,7 +2326,7 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, */ #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if ((connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) && - (connsm->csmflags.cfbit.chanmap_update_scheduled)) { + (connsm->flags.chanmap_update_scheduled)) { rsp_opcode = BLE_LL_CTRL_REJECT_IND_EXT; rspbuf[1] = BLE_LL_CTRL_CONN_PARM_REQ; rspbuf[2] = BLE_ERR_DIFF_TRANS_COLL; @@ -2359,8 +2359,8 @@ ble_ll_ctrl_rx_conn_param_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * state just clear the awaiting reply. The peripheral will hopefully stop its * procedure when we reply. */ - if (connsm->csmflags.cfbit.awaiting_host_reply) { - connsm->csmflags.cfbit.awaiting_host_reply = 0; + if (connsm->flags.awaiting_host_reply) { + connsm->flags.awaiting_host_reply = 0; } /* If we receive a response and no procedure is pending, just leave */ @@ -2395,10 +2395,10 @@ ble_ll_ctrl_rx_version_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, connsm->vers_nr = dptr[0]; connsm->comp_id = get_le16(dptr + 1); connsm->sub_vers_nr = get_le16(dptr + 3); - connsm->csmflags.cfbit.rxd_version_ind = 1; + connsm->flags.rxd_version_ind = 1; rsp_opcode = BLE_ERR_MAX; - if (!connsm->csmflags.cfbit.version_ind_sent) { + if (!connsm->flags.version_ind_sent) { rsp_opcode = BLE_LL_CTRL_VERSION_IND; ble_ll_ctrl_version_ind_make(connsm, rspbuf); } @@ -2439,7 +2439,7 @@ ble_ll_ctrl_rx_chanmap_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr) } else { connsm->chanmap_instant = instant; memcpy(connsm->req_chanmap, dptr, BLE_LL_CHAN_MAP_LEN); - connsm->csmflags.cfbit.chanmap_update_scheduled = 1; + connsm->flags.chanmap_update_scheduled = 1; } return BLE_ERR_MAX; @@ -2734,7 +2734,7 @@ ble_ll_ctrl_chk_proc_start(struct ble_ll_conn_sm *connsm) * received the information dont start it. */ if ((i == BLE_LL_CTRL_PROC_VERSION_XCHG) && - (connsm->csmflags.cfbit.rxd_version_ind)) { + (connsm->flags.rxd_version_ind)) { ble_ll_hci_ev_rd_rem_ver(connsm, BLE_ERR_SUCCESS); CLR_PENDING_CTRL_PROC(connsm, i); } else { @@ -3067,8 +3067,8 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) } #if MYNEWT_VAL(BLE_LL_CONN_INIT_AUTO_DLE) - if (connsm->csmflags.cfbit.pending_initiate_dle) { - connsm->csmflags.cfbit.pending_initiate_dle = 0; + if (connsm->flags.pending_initiate_dle) { + connsm->flags.pending_initiate_dle = 0; ble_ll_ctrl_initiate_dle(connsm, true); } #endif @@ -3134,11 +3134,13 @@ ble_ll_ctrl_tx_start(struct ble_ll_conn_sm *connsm, struct os_mbuf *txpdu) switch (opcode) { case BLE_LL_CTRL_CONN_UPDATE_IND: ble_ll_ctrl_conn_update_make_ind_pdu(connsm, ctrdata); - connsm->csmflags.cfbit.conn_update_sched = 1; + connsm->flags.conn_update_sched = 1; break; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) case BLE_LL_CTRL_SUBRATE_IND: - connsm->csmflags.cfbit.subrate_trans = 1; + connsm->flags.subrate_trans = 1; break; +#endif } return 0; @@ -3170,7 +3172,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) opcode = txpdu->om_data[0]; switch (opcode) { case BLE_LL_CTRL_TERMINATE_IND: - connsm->csmflags.cfbit.terminate_ind_txd = 1; + connsm->flags.terminate_ind_txd = 1; rc = -1; break; case BLE_LL_CTRL_REJECT_IND_EXT: @@ -3182,7 +3184,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) if (txpdu->om_data[1] == BLE_LL_CTRL_CONN_PARM_REQ && txpdu->om_data[2] != BLE_ERR_LMP_COLLISION) { connsm->reject_reason = txpdu->om_data[2]; - connsm->csmflags.cfbit.host_expects_upd_event = 1; + connsm->flags.host_expects_upd_event = 1; } } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) @@ -3204,7 +3206,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) break; case BLE_LL_CTRL_ENC_RSP: connsm->enc_data.enc_state = CONN_ENC_S_LTK_REQ_WAIT; - connsm->csmflags.cfbit.send_ltk_req = 1; + connsm->flags.send_ltk_req = 1; break; #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_CTRL_START_ENC_RSP: @@ -3240,8 +3242,8 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_CTRL_SUBRATE_IND: - connsm->csmflags.cfbit.subrate_trans = 0; - connsm->csmflags.cfbit.subrate_ind_txd = 1; + connsm->flags.subrate_trans = 0; + connsm->flags.subrate_ind_txd = 1; break; #endif /* BLE_LL_CTRL_SUBRATE_IND */ #endif /* BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE */ diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index 6588fabedb..fb3d3dd7d5 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -331,7 +331,7 @@ ble_ll_hci_ev_le_csa(struct ble_ll_conn_sm *connsm) ev->subev_code = BLE_HCI_LE_SUBEV_CHAN_SEL_ALG; ev->conn_handle = htole16(connsm->conn_handle); - ev->csa = connsm->csmflags.cfbit.csa2_supp ? 0x01 : 0x00; + ev->csa = connsm->flags.csa2_supp ? 0x01 : 0x00; ble_ll_hci_event_send(hci_ev); } From f11970b01878e75e04d829ed9efeb7e10855225a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 13 Jun 2023 16:10:38 +0200 Subject: [PATCH 0725/1333] nimble/ll: Remove CONN_F macros This removes CONN_F macros to access connsm flags. Those are currently not used consistently and were not updated for new features so can be considered legacy now. Since flags union is now removed there's also no real benefit of accessing flags using macros vs bitfield directly. --- .../include/controller/ble_ll_conn.h | 17 ---- nimble/controller/src/ble_ll_conn.c | 80 +++++++++---------- nimble/controller/src/ble_ll_conn_hci.c | 16 ++-- nimble/controller/src/ble_ll_ctrl.c | 48 +++++------ nimble/controller/src/ble_ll_hci_ev.c | 4 +- nimble/controller/test/src/ble_ll_csa2_test.c | 6 +- 6 files changed, 76 insertions(+), 95 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 234c164c4d..16478029c7 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -400,23 +400,6 @@ struct ble_ll_conn_sm #endif }; -/* Flags */ -#define CONN_F_UPDATE_SCHED(csm) ((csm)->csmflags.conn_update_sched) -#define CONN_F_EMPTY_PDU_TXD(csm) ((csm)->flags.conn_empty_pdu_txd) -#define CONN_F_LAST_TXD_MD(csm) ((csm)->flags.last_txd_md) -#define CONN_F_CONN_REQ_TXD(csm) ((csm)->csmflags.conn_req_txd) -#define CONN_F_ENCRYPTED(csm) ((csm)->flags.encrypted) -#define CONN_F_ENC_CHANGE_SENT(csm) ((csm)->flags.encrypt_chg_sent) -#define CONN_F_LE_PING_SUPP(csm) ((csm)->flags.le_ping_supp) -#define CONN_F_TERMINATE_STARTED(csm) ((csm)->flags.terminate_started) -#define CONN_F_CSA2_SUPP(csm) ((csm)->flags.csa2_supp) -#define CONN_F_HOST_PHY_UPDATE(csm) ((csm)->flags.host_phy_update) -#define CONN_F_PHY_UPDATE_SCHED(csm) ((csm)->flags.phy_update_sched) -#define CONN_F_CTRLR_PHY_UPDATE(csm) ((csm)->flags.ctrlr_phy_update) -#define CONN_F_PHY_UPDATE_EVENT(csm) ((csm)->flags.phy_update_event) -#define CONN_F_PEER_PHY_UPDATE(csm) ((csm)->flags.peer_phy_update) -#define CONN_F_AUX_CONN_REQ(csm) ((csm)->csmflags.aux_conn_req) - /* Role */ #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) #define CONN_IS_CENTRAL(csm) (csm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index d39fbe59d9..7bc5cd65c3 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -801,7 +801,7 @@ ble_ll_conn_calc_dci(struct ble_ll_conn_sm *conn, uint16_t latency) uint8_t index; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) - if (CONN_F_CSA2_SUPP(conn)) { + if (conn->flags.csa2_supp) { return ble_ll_utils_dci_csa2(conn->event_cntr, conn->channel_id, conn->chan_map_used, conn->chan_map); } @@ -858,7 +858,7 @@ ble_ll_conn_start_rx_encrypt(void *arg) struct ble_ll_conn_sm *connsm; connsm = (struct ble_ll_conn_sm *)arg; - CONN_F_ENCRYPTED(connsm) = 1; + connsm->flags.encrypted = 1; ble_phy_encrypt_enable(connsm->enc_data.enc_block.cipher_text); ble_phy_encrypt_iv_set(connsm->enc_data.iv); ble_phy_encrypt_counter_set(connsm->enc_data.rx_pkt_cntr, @@ -872,7 +872,7 @@ ble_ll_conn_start_rx_unencrypt(void *arg) struct ble_ll_conn_sm *connsm; connsm = (struct ble_ll_conn_sm *)arg; - CONN_F_ENCRYPTED(connsm) = 0; + connsm->flags.encrypted = 0; ble_phy_encrypt_disable(); } #endif @@ -883,7 +883,7 @@ ble_ll_conn_txend_encrypt(void *arg) struct ble_ll_conn_sm *connsm; connsm = (struct ble_ll_conn_sm *)arg; - CONN_F_ENCRYPTED(connsm) = 1; + connsm->flags.encrypted = 1; ble_ll_conn_current_sm_over(connsm); } @@ -894,7 +894,7 @@ ble_ll_conn_rxend_unencrypt(void *arg) struct ble_ll_conn_sm *connsm; connsm = (struct ble_ll_conn_sm *)arg; - CONN_F_ENCRYPTED(connsm) = 0; + connsm->flags.encrypted = 0; ble_ll_conn_current_sm_over(connsm); } #endif @@ -1004,10 +1004,10 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm) /* Check if we need to send PHY update complete event */ #if (BLE_LL_BT5_PHY_SUPPORTED == 1) - if (CONN_F_PHY_UPDATE_EVENT(connsm)) { + if (connsm->flags.phy_update_event) { if (!ble_ll_hci_ev_phy_update(connsm, BLE_ERR_SUCCESS)) { /* Sent event. Clear flag */ - CONN_F_PHY_UPDATE_EVENT(connsm) = 0; + connsm->flags.phy_update_event = 0; } } #endif @@ -1061,7 +1061,7 @@ ble_ll_conn_adjust_pyld_len(struct ble_ll_conn_sm *connsm, uint16_t pyld_len) ret = pyld_len; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (CONN_F_ENCRYPTED(connsm)) { + if (connsm->flags.encrypted) { max_pyld_len -= BLE_LL_DATA_MIC_LEN; } #endif @@ -1113,7 +1113,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) /* We just received terminate indication. * Just send empty packet as an ACK */ - CONN_F_EMPTY_PDU_TXD(connsm) = 1; + connsm->flags.conn_empty_pdu_txd = 1; goto conn_tx_pdu; } @@ -1122,8 +1122,8 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) * the transmit queue. */ pkthdr = STAILQ_FIRST(&connsm->conn_txq); - if (!connsm->cur_tx_pdu && !CONN_F_EMPTY_PDU_TXD(connsm) && !pkthdr) { - CONN_F_EMPTY_PDU_TXD(connsm) = 1; + if (!connsm->cur_tx_pdu && !connsm->flags.conn_empty_pdu_txd && !pkthdr) { + connsm->flags.conn_empty_pdu_txd = 1; goto conn_tx_pdu; } @@ -1132,7 +1132,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) * the connection transmit queue */ cur_offset = 0; - if (!connsm->cur_tx_pdu && !CONN_F_EMPTY_PDU_TXD(connsm)) { + if (!connsm->cur_tx_pdu && !connsm->flags.conn_empty_pdu_txd) { /* Convert packet header to mbuf */ m = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); nextpkthdr = STAILQ_NEXT(pkthdr, omp_next); @@ -1150,7 +1150,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) ((connsm->enc_data.enc_state > CONN_ENC_S_ENC_RSP_TO_BE_SENT) && CONN_IS_PERIPHERAL(connsm))) { if (!ble_ll_ctrl_enc_allowed_pdu_tx(pkthdr)) { - CONN_F_EMPTY_PDU_TXD(connsm) = 1; + connsm->flags.conn_empty_pdu_txd = 1; goto conn_tx_pdu; } @@ -1292,7 +1292,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) /* If we send an empty PDU we need to initialize the header */ conn_tx_pdu: - if (CONN_F_EMPTY_PDU_TXD(connsm)) { + if (connsm->flags.conn_empty_pdu_txd) { /* * This looks strange, but we dont use the data pointer in the mbuf * when we have an empty pdu. @@ -1366,7 +1366,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) * Both central and peripheral send the START_ENC_RSP encrypted and receive * encrypted */ - CONN_F_ENCRYPTED(connsm) = 1; + connsm->flags.encrypted = 1; connsm->enc_data.tx_encrypted = 1; ble_phy_encrypt_enable(connsm->enc_data.enc_block.cipher_text); ble_phy_encrypt_iv_set(connsm->enc_data.iv); @@ -1380,7 +1380,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) * Only the peripheral sends this and it gets sent unencrypted but * we receive encrypted */ - CONN_F_ENCRYPTED(connsm) = 0; + connsm->flags.encrypted = 0; connsm->enc_data.enc_state = CONN_ENC_S_START_ENC_RSP_WAIT; connsm->enc_data.tx_encrypted = 0; ble_phy_encrypt_disable(); @@ -1397,7 +1397,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_CONN_ROLE_CENTRAL: - CONN_F_ENCRYPTED(connsm) = 0; + connsm->flags.encrypted = 0; connsm->enc_data.enc_state = CONN_ENC_S_PAUSED; connsm->enc_data.tx_encrypted = 0; ble_phy_encrypt_disable(); @@ -1405,7 +1405,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_CONN_ROLE_PERIPHERAL: - CONN_F_ENCRYPTED(connsm) = 1; + connsm->flags.encrypted = 1; connsm->enc_data.tx_encrypted = 1; ble_phy_encrypt_enable(connsm->enc_data.enc_block.cipher_text); ble_phy_encrypt_iv_set(connsm->enc_data.iv); @@ -1424,7 +1424,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) } } else { /* If encrypted set packet counter */ - if (CONN_F_ENCRYPTED(connsm)) { + if (connsm->flags.encrypted) { connsm->enc_data.tx_encrypted = 1; ble_phy_encrypt_counter_set(connsm->enc_data.tx_pkt_cntr, CONN_IS_CENTRAL(connsm)); @@ -1445,10 +1445,10 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) ble_hdr->txinfo.offset); /* Set last transmitted MD bit */ - CONN_F_LAST_TXD_MD(connsm) = md; + connsm->flags.last_txd_md = md; /* Increment packets transmitted */ - if (CONN_F_EMPTY_PDU_TXD(connsm)) { + if (connsm->flags.conn_empty_pdu_txd) { if (connsm->flags.terminate_ind_rxd) { connsm->flags.terminate_ind_rxd_acked = 1; } @@ -1537,7 +1537,7 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) rc = ble_phy_tx_set_start_time(start, sch->remainder); if (!rc) { #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (CONN_F_ENCRYPTED(connsm)) { + if (connsm->flags.encrypted) { ble_phy_encrypt_enable(connsm->enc_data.enc_block.cipher_text); ble_phy_encrypt_iv_set(connsm->enc_data.iv); ble_phy_encrypt_counter_set(connsm->enc_data.tx_pkt_cntr, 1); @@ -1561,7 +1561,7 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_CONN_ROLE_PERIPHERAL: #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (CONN_F_ENCRYPTED(connsm)) { + if (connsm->flags.encrypted) { ble_phy_encrypt_enable(connsm->enc_data.enc_block.cipher_text); ble_phy_encrypt_iv_set(connsm->enc_data.iv); ble_phy_encrypt_counter_set(connsm->enc_data.rx_pkt_cntr, 1); @@ -1945,7 +1945,7 @@ ble_ll_conn_set_csa(struct ble_ll_conn_sm *connsm, bool chsel) { #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) if (chsel) { - CONN_F_CSA2_SUPP(connsm) = 1; + connsm->flags.csa2_supp = 1; connsm->channel_id = ((connsm->access_addr & 0xffff0000) >> 16) ^ (connsm->access_addr & 0x0000ffff); @@ -2069,7 +2069,7 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) connsm->auth_pyld_tmo = BLE_LL_CONN_DEF_AUTH_PYLD_TMO; - CONN_F_LE_PING_SUPP(connsm) = 1; + connsm->flags.le_ping_supp = 1; #endif /* Add to list of active connections */ @@ -2355,11 +2355,11 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) ble_ll_conn_chk_csm_flags(connsm); /* If unable to start terminate procedure, start it now */ - if (connsm->disconnect_reason && !CONN_F_TERMINATE_STARTED(connsm)) { + if (connsm->disconnect_reason && !connsm->flags.terminate_started) { ble_ll_ctrl_terminate_start(connsm); } - if (CONN_F_TERMINATE_STARTED(connsm) && CONN_IS_PERIPHERAL(connsm)) { + if (connsm->flags.terminate_started && CONN_IS_PERIPHERAL(connsm)) { /* Some of the devices waits whole connection interval to ACK our * TERMINATE_IND sent as a Slave. Since we are here it means we are still waiting for ACK. * Make sure we catch it in next connection event. @@ -2640,7 +2640,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) #endif #if (BLE_LL_BT5_PHY_SUPPORTED == 1) - if (CONN_F_PHY_UPDATE_SCHED(connsm) && + if (connsm->flags.phy_update_sched && (connsm->event_cntr == connsm->phy_instant)) { /* Set cur phy to new phy */ @@ -2659,8 +2659,8 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) } /* Clear flags and set flag to send event at next instant */ - CONN_F_PHY_UPDATE_SCHED(connsm) = 0; - CONN_F_PHY_UPDATE_EVENT(connsm) = 1; + connsm->flags.phy_update_sched = 0; + connsm->flags.phy_update_event = 1; ble_ll_ctrl_phy_update_proc_complete(connsm); @@ -2693,7 +2693,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) * passed the termination timeout. If so, no need to continue with * connection as we will time out anyway. */ - if (CONN_F_TERMINATE_STARTED(connsm)) { + if (connsm->flags.terminate_started) { if ((int32_t)(connsm->terminate_timeout - connsm->anchor_point) <= 0) { return -1; } @@ -2856,7 +2856,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) * the other side can support it? */ if (!ble_ll_conn_phy_update_if_needed(connsm)) { - CONN_F_CTRLR_PHY_UPDATE(connsm) = 1; + connsm->flags.ctrlr_phy_update = 1; } #endif switch (connsm->conn_role) { @@ -3504,7 +3504,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) * connection */ if ((connsm->enc_data.enc_state == CONN_ENC_S_ENCRYPTED) && - CONN_F_LE_PING_SUPP(connsm) && (acl_len != 0)) { + connsm->flags.le_ping_supp && (acl_len != 0)) { ble_ll_conn_auth_pyld_timer_start(connsm); } #endif @@ -3723,7 +3723,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_CONN_ROLE_CENTRAL: - reply = CONN_F_LAST_TXD_MD(connsm); + reply = connsm->flags.last_txd_md; break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) @@ -3760,7 +3760,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) if (rxpdu && ((hdr_sn && conn_nesn) || (!hdr_sn && !conn_nesn))) { connsm->next_exp_seqnum ^= 1; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (CONN_F_ENCRYPTED(connsm) && !ble_ll_conn_is_empty_pdu(rxbuf)) { + if (connsm->flags.encrypted && !ble_ll_conn_is_empty_pdu(rxbuf)) { ++connsm->enc_data.rx_pkt_cntr; } #endif @@ -3773,7 +3773,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) * Check NESN bit from header. If same as tx seq num, the transmission * is acknowledged. Otherwise we need to resend this PDU. */ - if (CONN_F_EMPTY_PDU_TXD(connsm) || connsm->cur_tx_pdu) { + if (connsm->flags.conn_empty_pdu_txd || connsm->cur_tx_pdu) { hdr_nesn = hdr_byte & BLE_LL_DATA_HDR_NESN_MASK; conn_sn = connsm->tx_seqnum; if ((hdr_nesn && conn_sn) || (!hdr_nesn && !conn_sn)) { @@ -3785,8 +3785,8 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) STATS_INC(ble_ll_conn_stats, data_pdu_txg); /* If we transmitted the empty pdu, clear flag */ - if (CONN_F_EMPTY_PDU_TXD(connsm)) { - CONN_F_EMPTY_PDU_TXD(connsm) = 0; + if (connsm->flags.conn_empty_pdu_txd) { + connsm->flags.conn_empty_pdu_txd = 0; goto chk_rx_terminate_ind; } @@ -3864,7 +3864,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_CONN_ROLE_CENTRAL: - reply = CONN_F_LAST_TXD_MD(connsm) || (hdr_byte & BLE_LL_DATA_HDR_MD_MASK); + reply = connsm->flags.last_txd_md || (hdr_byte & BLE_LL_DATA_HDR_MD_MASK); break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) @@ -3881,7 +3881,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) /* If reply flag set, send data pdu and continue connection event */ rc = -1; - if (rx_pyld_len && CONN_F_ENCRYPTED(connsm)) { + if (rx_pyld_len && connsm->flags.encrypted) { rx_pyld_len += BLE_LL_DATA_MIC_LEN; } if (reply && ble_ll_conn_can_send_next_pdu(connsm, begtime, add_usecs)) { diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 3cedc12ff6..b2b55f64e8 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1334,7 +1334,7 @@ ble_ll_conn_hci_disconnect_cmd(const struct ble_hci_lc_disconnect_cp *cmd) rc = BLE_ERR_CMD_DISALLOWED; } else { /* This control procedure better not be pending! */ - BLE_LL_ASSERT(CONN_F_TERMINATE_STARTED(connsm) == 0); + BLE_LL_ASSERT(connsm->flags.terminate_started == 0); /* Record the disconnect reason */ connsm->disconnect_reason = cmd->reason; @@ -1990,7 +1990,7 @@ ble_ll_conn_hci_le_set_phy(const uint8_t *cmdbuf, uint8_t len) * If host has requested a PHY update and we are not finished do * not allow another one */ - if (CONN_F_HOST_PHY_UPDATE(connsm)) { + if (connsm->flags.host_phy_update) { return BLE_ERR_CMD_DISALLOWED; } @@ -2019,9 +2019,9 @@ ble_ll_conn_hci_le_set_phy(const uint8_t *cmdbuf, uint8_t len) */ if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_PHY_UPDATE)) { if (connsm->cur_ctrl_proc != BLE_LL_CTRL_PROC_PHY_UPDATE) { - CONN_F_CTRLR_PHY_UPDATE(connsm) = 0; + connsm->flags.ctrlr_phy_update = 0; } - CONN_F_HOST_PHY_UPDATE(connsm) = 1; + connsm->flags.host_phy_update = 1; } else { /* * We could be doing a peer-initiated PHY update procedure. If this @@ -2029,20 +2029,20 @@ ble_ll_conn_hci_le_set_phy(const uint8_t *cmdbuf, uint8_t len) * we are not done with a peer-initiated procedure we just set the * pending bit but do not start the control procedure. */ - if (CONN_F_PEER_PHY_UPDATE(connsm)) { + if (connsm->flags.peer_phy_update) { connsm->pending_ctrl_procs |= (1 << BLE_LL_CTRL_PROC_PHY_UPDATE); - CONN_F_HOST_PHY_UPDATE(connsm) = 1; + connsm->flags.host_phy_update = 1; } else { /* Check if we should start phy update procedure */ if (!ble_ll_conn_phy_update_if_needed(connsm)) { - CONN_F_HOST_PHY_UPDATE(connsm) = 1; + connsm->flags.host_phy_update = 1; } else { /* * Set flag to send a PHY update complete event. We set flag * even if we do not do an update procedure since we have to * inform the host even if we decide not to change anything. */ - CONN_F_PHY_UPDATE_EVENT(connsm) = 1; + connsm->flags.phy_update_event = 1; } } } diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 726a44de9b..0533f6dbda 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -198,13 +198,13 @@ ble_ll_ctrl_phy_update_cancel(struct ble_ll_conn_sm *connsm, uint8_t ble_err) CLR_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_PHY_UPDATE); /* Check if the host wants an event */ - if (CONN_F_HOST_PHY_UPDATE(connsm)) { + if (connsm->flags.host_phy_update) { ble_ll_hci_ev_phy_update(connsm, ble_err); - CONN_F_HOST_PHY_UPDATE(connsm) = 0; + connsm->flags.host_phy_update = 0; } /* Clear any bits for phy updates that might be in progress */ - CONN_F_CTRLR_PHY_UPDATE(connsm) = 0; + connsm->flags.ctrlr_phy_update = 0; } #endif @@ -687,24 +687,24 @@ ble_ll_ctrl_phy_update_proc_complete(struct ble_ll_conn_sm *connsm) connsm->phy_tx_transition = 0; - if (CONN_F_PEER_PHY_UPDATE(connsm)) { - CONN_F_PEER_PHY_UPDATE(connsm) = 0; - } else if (CONN_F_CTRLR_PHY_UPDATE(connsm)) { - CONN_F_CTRLR_PHY_UPDATE(connsm) = 0; + if (connsm->flags.peer_phy_update) { + connsm->flags.peer_phy_update = 0; + } else if (connsm->flags.ctrlr_phy_update) { + connsm->flags.ctrlr_phy_update = 0; } else { /* Must be a host-initiated update */ - CONN_F_HOST_PHY_UPDATE(connsm) = 0; + connsm->flags.host_phy_update = 0; chk_host_phy = 0; - if (CONN_F_PHY_UPDATE_EVENT(connsm) == 0) { + if (connsm->flags.phy_update_event == 0) { ble_ll_hci_ev_phy_update(connsm, BLE_ERR_SUCCESS); } } /* Must check if we need to start host procedure */ if (chk_host_phy) { - if (CONN_F_HOST_PHY_UPDATE(connsm)) { + if (connsm->flags.host_phy_update) { if (ble_ll_conn_phy_update_if_needed(connsm)) { - CONN_F_HOST_PHY_UPDATE(connsm) = 0; + connsm->flags.host_phy_update = 0; } else { chk_proc_stop = 0; } @@ -829,14 +829,14 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * one running. */ if ((m_to_s == 0) && (s_to_m == 0)) { - if (CONN_F_PEER_PHY_UPDATE(connsm)) { - CONN_F_PEER_PHY_UPDATE(connsm) = 0; - } else if (CONN_F_CTRLR_PHY_UPDATE(connsm)) { - CONN_F_CTRLR_PHY_UPDATE(connsm) = 0; + if (connsm->flags.peer_phy_update) { + connsm->flags.peer_phy_update = 0; + } else if (connsm->flags.ctrlr_phy_update) { + connsm->flags.ctrlr_phy_update = 0; ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_PHY_UPDATE); } else { ble_ll_hci_ev_phy_update(connsm, BLE_ERR_SUCCESS); - CONN_F_HOST_PHY_UPDATE(connsm) = 0; + connsm->flags.host_phy_update = 0; ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_PHY_UPDATE); } instant = 0; @@ -844,7 +844,7 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, /* Determine instant we will use. 6 more is minimum */ instant = connsm->event_cntr + connsm->periph_latency + 6 + 1; connsm->phy_instant = instant; - CONN_F_PHY_UPDATE_SCHED(connsm) = 1; + connsm->flags.phy_update_sched = 1; /* Set new phys to use when instant occurs */ connsm->phy_data.new_tx_phy = m_to_s; @@ -921,7 +921,7 @@ ble_ll_ctrl_rx_phy_req(struct ble_ll_conn_sm *connsm, uint8_t *req, * NOTE: do not change order of these two lines as the call to * make the LL_PHY_UPDATE_IND pdu might clear the flag. */ - CONN_F_PEER_PHY_UPDATE(connsm) = 1; + connsm->flags.peer_phy_update = 1; ble_ll_ctrl_phy_update_ind_make(connsm, req, rsp, 1); rsp_opcode = BLE_LL_CTRL_PHY_UPDATE_IND; } @@ -940,14 +940,14 @@ ble_ll_ctrl_rx_phy_req(struct ble_ll_conn_sm *connsm, uint8_t *req, ble_ll_ctrl_phy_update_cancel(connsm, err); /* XXX: ? Should not be any phy update events */ - CONN_F_PHY_UPDATE_EVENT(connsm) = 0; + connsm->flags.phy_update_event = 0; } /* XXX: TODO: if we started another procedure with an instant * why are we doing this? Need to look into this.*/ /* Respond to central's phy update procedure */ - CONN_F_PEER_PHY_UPDATE(connsm) = 1; + connsm->flags.peer_phy_update = 1; ble_ll_ctrl_phy_req_rsp_make(connsm, rsp); rsp_opcode = BLE_LL_CTRL_PHY_RSP; @@ -1093,7 +1093,7 @@ ble_ll_ctrl_rx_phy_update_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr) connsm->phy_data.new_tx_phy = new_tx_phy; connsm->phy_data.new_rx_phy = new_rx_phy; connsm->phy_instant = instant; - CONN_F_PHY_UPDATE_SCHED(connsm) = 1; + connsm->flags.phy_update_sched = 1; } return BLE_ERR_MAX; } @@ -2643,7 +2643,7 @@ ble_ll_ctrl_terminate_start(struct ble_ll_conn_sm *connsm) ctrl_proc = BLE_LL_CTRL_PROC_TERMINATE; om = ble_ll_ctrl_proc_init(connsm, ctrl_proc, NULL); if (om) { - CONN_F_TERMINATE_STARTED(connsm) = 1; + connsm->flags.terminate_started = 1; /* Set terminate "timeout" */ usecs = connsm->supervision_tmo * BLE_HCI_CONN_SPVN_TMO_UNITS * 1000; @@ -2709,7 +2709,7 @@ ble_ll_ctrl_chk_proc_start(struct ble_ll_conn_sm *connsm) * terminate if needed */ if (connsm->disconnect_reason) { - if (!CONN_F_TERMINATE_STARTED(connsm)) { + if (!connsm->flags.terminate_started) { /* * If the terminate procedure has not started it means we were not * able to start it right away (no control pdu was available). @@ -3212,7 +3212,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) case BLE_LL_CTRL_START_ENC_RSP: if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { connsm->enc_data.enc_state = CONN_ENC_S_ENCRYPTED; - if (CONN_F_LE_PING_SUPP(connsm)) { + if (connsm->flags.le_ping_supp) { ble_ll_conn_auth_pyld_timer_start(connsm); } } diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index fb3d3dd7d5..3fb5e7ae22 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -135,7 +135,7 @@ ble_ll_hci_ev_encrypt_chg(struct ble_ll_conn_sm *connsm, uint8_t status) struct ble_hci_ev_enrypt_chg *ev_enc_chf; struct ble_hci_ev *hci_ev; - if (CONN_F_ENC_CHANGE_SENT(connsm) == 0) { + if (connsm->flags.encrypt_chg_sent == 0) { if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_ENCRYPT_CHG)) { hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { @@ -151,7 +151,7 @@ ble_ll_hci_ev_encrypt_chg(struct ble_ll_conn_sm *connsm, uint8_t status) } } - CONN_F_ENC_CHANGE_SENT(connsm) = 1; + connsm->flags.encrypt_chg_sent = 1; return; } diff --git a/nimble/controller/test/src/ble_ll_csa2_test.c b/nimble/controller/test/src/ble_ll_csa2_test.c index d7d43dcfb6..91081227e3 100644 --- a/nimble/controller/test/src/ble_ll_csa2_test.c +++ b/nimble/controller/test/src/ble_ll_csa2_test.c @@ -34,8 +34,7 @@ TEST_CASE_SELF(ble_ll_csa2_test_1) */ memset(&conn, 0, sizeof(conn)); - - CONN_F_CSA2_SUPP(&conn) = 1; + conn.flags.csa2_supp = 1; /* * based on sample data from CoreSpec 5.0 Vol 6 Part C 3.1 @@ -76,8 +75,7 @@ TEST_CASE_SELF(ble_ll_csa2_test_2) */ memset(&conn, 0, sizeof(conn)); - - CONN_F_CSA2_SUPP(&conn) = 1; + conn.flags.csa2_supp = 1; /* * based on sample data from CoreSpec 5.0 Vol 6 Part C 3.2 From db390799477df7d2ade022a03cd0204009b90254 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 13 Jun 2023 23:38:19 +0200 Subject: [PATCH 0726/1333] nimble/ll: Cleanup connsm flag names --- .../include/controller/ble_ll_conn.h | 44 +++++------ nimble/controller/src/ble_ll_conn.c | 70 ++++++++--------- nimble/controller/src/ble_ll_conn_hci.c | 38 +++++----- nimble/controller/src/ble_ll_ctrl.c | 76 +++++++++---------- nimble/controller/src/ble_ll_hci_ev.c | 6 +- nimble/controller/test/src/ble_ll_csa2_test.c | 4 +- 6 files changed, 118 insertions(+), 120 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 16478029c7..cb7ad60ae6 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -100,35 +100,33 @@ struct ble_ll_conn_enc_data /* Connection state machine flags. */ struct ble_ll_conn_sm_flags { uint32_t pkt_rxd : 1; + uint32_t last_txd_md : 1; + uint32_t empty_pdu_txd : 1; + uint32_t periph_use_latency : 1; + uint32_t periph_set_last_anchor : 1; + uint32_t csa2 : 1; + uint32_t encrypted : 1; + uint32_t encrypt_ltk_req : 1; + uint32_t encrypt_event_sent : 1; + uint32_t version_ind_txd : 1; + uint32_t version_ind_rxd : 1; + uint32_t features_rxd : 1; + uint32_t features_host_req : 1; + uint32_t terminate_started : 1; uint32_t terminate_ind_txd : 1; uint32_t terminate_ind_rxd : 1; uint32_t terminate_ind_rxd_acked : 1; - uint32_t allow_periph_latency : 1; - uint32_t periph_set_last_anchor : 1; - uint32_t awaiting_host_reply : 1; - uint32_t terminate_started : 1; uint32_t conn_update_sched : 1; uint32_t conn_update_use_cp : 1; - uint32_t host_expects_upd_event : 1; - uint32_t version_ind_sent : 1; - uint32_t rxd_version_ind : 1; - uint32_t chanmap_update_scheduled : 1; - uint32_t conn_empty_pdu_txd : 1; - uint32_t last_txd_md : 1; - uint32_t conn_req_txd : 1; - uint32_t send_ltk_req : 1; - uint32_t encrypted : 1; - uint32_t encrypt_chg_sent : 1; + uint32_t conn_update_host_w4reply : 1; + uint32_t conn_update_host_w4event : 1; + uint32_t chanmap_update_sched : 1; + uint32_t phy_update_sched : 1; + uint32_t phy_update_self_initiated : 1; + uint32_t phy_update_peer_initiated : 1; + uint32_t phy_update_host_initiated : 1; + uint32_t phy_update_host_w4event : 1; uint32_t le_ping_supp : 1; - uint32_t csa2_supp : 1; - uint32_t host_phy_update: 1; - uint32_t phy_update_sched: 1; - uint32_t ctrlr_phy_update: 1; - uint32_t phy_update_event: 1; - uint32_t peer_phy_update: 1; /* XXX:combine with ctrlr udpate bit? */ - uint32_t aux_conn_req: 1; - uint32_t rxd_features : 1; - uint32_t pending_hci_rd_features : 1; #if MYNEWT_VAL(BLE_LL_CONN_INIT_AUTO_DLE) uint32_t pending_initiate_dle : 1; #endif diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 7bc5cd65c3..3565e10424 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -801,7 +801,7 @@ ble_ll_conn_calc_dci(struct ble_ll_conn_sm *conn, uint16_t latency) uint8_t index; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) - if (conn->flags.csa2_supp) { + if (conn->flags.csa2) { return ble_ll_utils_dci_csa2(conn->event_cntr, conn->channel_id, conn->chan_map_used, conn->chan_map); } @@ -969,7 +969,7 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm) uint8_t update_status; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (connsm->flags.send_ltk_req) { + if (connsm->flags.encrypt_ltk_req) { /* * Send Long term key request event to host. If masked, we need to * send a REJECT_IND. @@ -978,7 +978,7 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm) ble_ll_ctrl_reject_ind_send(connsm, BLE_LL_CTRL_ENC_REQ, BLE_ERR_PINKEY_MISSING); } - connsm->flags.send_ltk_req = 0; + connsm->flags.encrypt_ltk_req = 0; } #endif @@ -988,7 +988,7 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm) * has passed the instant. * 2) We successfully sent the reject reason. */ - if (connsm->flags.host_expects_upd_event) { + if (connsm->flags.conn_update_host_w4event) { update_status = BLE_ERR_SUCCESS; if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_UPDATE)) { ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CONN_UPDATE); @@ -999,15 +999,15 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm) } } ble_ll_hci_ev_conn_update(connsm, update_status); - connsm->flags.host_expects_upd_event = 0; + connsm->flags.conn_update_host_w4event = 0; } /* Check if we need to send PHY update complete event */ #if (BLE_LL_BT5_PHY_SUPPORTED == 1) - if (connsm->flags.phy_update_event) { + if (connsm->flags.phy_update_host_w4event) { if (!ble_ll_hci_ev_phy_update(connsm, BLE_ERR_SUCCESS)) { /* Sent event. Clear flag */ - connsm->flags.phy_update_event = 0; + connsm->flags.phy_update_host_w4event = 0; } } #endif @@ -1113,7 +1113,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) /* We just received terminate indication. * Just send empty packet as an ACK */ - connsm->flags.conn_empty_pdu_txd = 1; + connsm->flags.empty_pdu_txd = 1; goto conn_tx_pdu; } @@ -1122,8 +1122,8 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) * the transmit queue. */ pkthdr = STAILQ_FIRST(&connsm->conn_txq); - if (!connsm->cur_tx_pdu && !connsm->flags.conn_empty_pdu_txd && !pkthdr) { - connsm->flags.conn_empty_pdu_txd = 1; + if (!connsm->cur_tx_pdu && !connsm->flags.empty_pdu_txd && !pkthdr) { + connsm->flags.empty_pdu_txd = 1; goto conn_tx_pdu; } @@ -1132,7 +1132,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) * the connection transmit queue */ cur_offset = 0; - if (!connsm->cur_tx_pdu && !connsm->flags.conn_empty_pdu_txd) { + if (!connsm->cur_tx_pdu && !connsm->flags.empty_pdu_txd) { /* Convert packet header to mbuf */ m = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); nextpkthdr = STAILQ_NEXT(pkthdr, omp_next); @@ -1150,7 +1150,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) ((connsm->enc_data.enc_state > CONN_ENC_S_ENC_RSP_TO_BE_SENT) && CONN_IS_PERIPHERAL(connsm))) { if (!ble_ll_ctrl_enc_allowed_pdu_tx(pkthdr)) { - connsm->flags.conn_empty_pdu_txd = 1; + connsm->flags.empty_pdu_txd = 1; goto conn_tx_pdu; } @@ -1292,7 +1292,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) /* If we send an empty PDU we need to initialize the header */ conn_tx_pdu: - if (connsm->flags.conn_empty_pdu_txd) { + if (connsm->flags.empty_pdu_txd) { /* * This looks strange, but we dont use the data pointer in the mbuf * when we have an empty pdu. @@ -1448,7 +1448,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) connsm->flags.last_txd_md = md; /* Increment packets transmitted */ - if (connsm->flags.conn_empty_pdu_txd) { + if (connsm->flags.empty_pdu_txd) { if (connsm->flags.terminate_ind_rxd) { connsm->flags.terminate_ind_rxd_acked = 1; } @@ -1945,7 +1945,7 @@ ble_ll_conn_set_csa(struct ble_ll_conn_sm *connsm, bool chsel) { #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) if (chsel) { - connsm->flags.csa2_supp = 1; + connsm->flags.csa2 = 1; connsm->channel_id = ((connsm->access_addr & 0xffff0000) >> 16) ^ (connsm->access_addr & 0x0000ffff); @@ -2239,19 +2239,19 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err) * If we have features and there's pending HCI command, send an event before * disconnection event so it does make sense to host. */ - if (connsm->flags.pending_hci_rd_features && - connsm->flags.rxd_features) { + if (connsm->flags.features_host_req && + connsm->flags.features_rxd) { ble_ll_hci_ev_rd_rem_used_feat(connsm, BLE_ERR_SUCCESS); - connsm->flags.pending_hci_rd_features = 0; + connsm->flags.features_host_req = 0; } /* * If there is still pending read features request HCI command, send an * event to complete it. */ - if (connsm->flags.pending_hci_rd_features) { + if (connsm->flags.features_host_req) { ble_ll_hci_ev_rd_rem_used_feat(connsm, ble_err); - connsm->flags.pending_hci_rd_features = 0; + connsm->flags.features_host_req = 0; } /* @@ -2263,7 +2263,7 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err) * received and we should not send an event. */ if (ble_err && (ble_err != BLE_ERR_UNK_CONN_ID || - connsm->flags.terminate_ind_rxd)) { + connsm->flags.terminate_ind_rxd)) { ble_ll_disconn_comp_event_send(connsm, ble_err); } @@ -2413,10 +2413,10 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) /* Set event counter to the next connection event that we will tx/rx in */ use_periph_latency = next_is_subrated && - connsm->flags.allow_periph_latency && + connsm->flags.periph_use_latency && !connsm->flags.conn_update_sched && !connsm->flags.phy_update_sched && - !connsm->flags.chanmap_update_scheduled && + !connsm->flags.chanmap_update_sched && connsm->flags.pkt_rxd; if (next_is_subrated) { @@ -2535,7 +2535,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) (connsm->conn_itvl != upd->interval) || (connsm->periph_latency != upd->latency) || (connsm->supervision_tmo != upd->timeout)) { - connsm->flags.host_expects_upd_event = 1; + connsm->flags.conn_update_host_w4event = 1; } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) @@ -2614,7 +2614,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) * new channel map once the event counter equals or has passed channel * map update instant. */ - if (connsm->flags.chanmap_update_scheduled && + if (connsm->flags.chanmap_update_sched && ((int16_t)(connsm->chanmap_instant - connsm->event_cntr) <= 0)) { /* XXX: there is a chance that the control packet is still on @@ -2625,7 +2625,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) ble_ll_utils_chan_map_used_get(connsm->req_chanmap); memcpy(connsm->chan_map, connsm->req_chanmap, BLE_LL_CHAN_MAP_LEN); - connsm->flags.chanmap_update_scheduled = 0; + connsm->flags.chanmap_update_sched = 0; ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_CHAN_MAP_UPD); @@ -2660,7 +2660,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) /* Clear flags and set flag to send event at next instant */ connsm->flags.phy_update_sched = 0; - connsm->flags.phy_update_event = 1; + connsm->flags.phy_update_host_w4event = 1; ble_ll_ctrl_phy_update_proc_complete(connsm); @@ -2856,7 +2856,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) * the other side can support it? */ if (!ble_ll_conn_phy_update_if_needed(connsm)) { - connsm->flags.ctrlr_phy_update = 1; + connsm->flags.phy_update_self_initiated = 1; } #endif switch (connsm->conn_role) { @@ -3030,10 +3030,10 @@ ble_ll_conn_event_end(struct ble_npl_event *ev) ble_ll_conn_num_comp_pkts_event_send(connsm); /* If we have features and there's pending HCI command, send an event */ - if (connsm->flags.pending_hci_rd_features && - connsm->flags.rxd_features) { + if (connsm->flags.features_host_req && + connsm->flags.features_rxd) { ble_ll_hci_ev_rd_rem_used_feat(connsm, BLE_ERR_SUCCESS); - connsm->flags.pending_hci_rd_features = 0; + connsm->flags.features_host_req = 0; } } @@ -3519,7 +3519,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { if (hdr_byte & BLE_LL_DATA_HDR_NESN_MASK) { - connsm->flags.allow_periph_latency = 1; + connsm->flags.periph_use_latency = 1; } } #endif @@ -3773,7 +3773,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) * Check NESN bit from header. If same as tx seq num, the transmission * is acknowledged. Otherwise we need to resend this PDU. */ - if (connsm->flags.conn_empty_pdu_txd || connsm->cur_tx_pdu) { + if (connsm->flags.empty_pdu_txd || connsm->cur_tx_pdu) { hdr_nesn = hdr_byte & BLE_LL_DATA_HDR_NESN_MASK; conn_sn = connsm->tx_seqnum; if ((hdr_nesn && conn_sn) || (!hdr_nesn && !conn_sn)) { @@ -3785,8 +3785,8 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) STATS_INC(ble_ll_conn_stats, data_pdu_txg); /* If we transmitted the empty pdu, clear flag */ - if (connsm->flags.conn_empty_pdu_txd) { - connsm->flags.conn_empty_pdu_txd = 0; + if (connsm->flags.empty_pdu_txd) { + connsm->flags.empty_pdu_txd = 0; goto chk_rx_terminate_ind; } diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index b2b55f64e8..7f5ab699bf 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -921,7 +921,7 @@ ble_ll_conn_hci_read_rem_features(const uint8_t *cmdbuf, uint8_t len) } /* If already pending exit with error */ - if (connsm->flags.pending_hci_rd_features) { + if (connsm->flags.features_host_req) { return BLE_ERR_CMD_DISALLOWED; } @@ -929,7 +929,7 @@ ble_ll_conn_hci_read_rem_features(const uint8_t *cmdbuf, uint8_t len) * Start control procedure if we did not receive peer's features and did not * start procedure already. */ - if (!connsm->flags.rxd_features && + if (!connsm->flags.features_rxd && !IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG)) { #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) if ((connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) && @@ -941,7 +941,7 @@ ble_ll_conn_hci_read_rem_features(const uint8_t *cmdbuf, uint8_t len) ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG, NULL); } - connsm->flags.pending_hci_rd_features = 1; + connsm->flags.features_host_req = 1; return BLE_ERR_SUCCESS; } @@ -1062,11 +1062,11 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) * peripheral has initiated the procedure, we need to send a reject to the * peripheral. */ - if (connsm->flags.awaiting_host_reply) { + if (connsm->flags.conn_update_host_w4reply) { switch (connsm->conn_role) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_LL_CONN_ROLE_CENTRAL: - connsm->flags.awaiting_host_reply = 0; + connsm->flags.conn_update_host_w4reply = 0; /* XXX: If this fails no reject ind will be sent! */ ble_ll_ctrl_reject_ind_send(connsm, connsm->host_reply_opcode, @@ -1089,7 +1089,7 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) * update procedure we should deny the peripheral request for now. */ #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - if (connsm->flags.chanmap_update_scheduled) { + if (connsm->flags.chanmap_update_sched) { if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { return BLE_ERR_DIFF_TRANS_COLL; } @@ -1159,7 +1159,7 @@ ble_ll_conn_hci_param_rr(const uint8_t *cmdbuf, uint8_t len, rc = ble_ll_conn_process_conn_params(cmd, connsm); /* The connection should be awaiting a reply. If not, just discard */ - if (connsm->flags.awaiting_host_reply) { + if (connsm->flags.conn_update_host_w4reply) { /* Get a control packet buffer */ if (rc == BLE_ERR_SUCCESS) { om = os_msys_get_pkthdr(BLE_LL_CTRL_MAX_PDU_LEN, @@ -1177,7 +1177,7 @@ ble_ll_conn_hci_param_rr(const uint8_t *cmdbuf, uint8_t len, ble_ll_ctrl_reject_ind_send(connsm, connsm->host_reply_opcode, BLE_ERR_CONN_PARMS); } - connsm->flags.awaiting_host_reply = 0; + connsm->flags.conn_update_host_w4reply = 0; /* XXX: if we cant get a buffer, what do we do? We need to remember * reason if it was a negative reply. We also would need to have @@ -1224,11 +1224,11 @@ ble_ll_conn_hci_param_nrr(const uint8_t *cmdbuf, uint8_t len, rc = BLE_ERR_SUCCESS; /* The connection should be awaiting a reply. If not, just discard */ - if (connsm->flags.awaiting_host_reply) { + if (connsm->flags.conn_update_host_w4reply) { /* XXX: check return code and deal */ ble_ll_ctrl_reject_ind_send(connsm, connsm->host_reply_opcode, cmd->reason); - connsm->flags.awaiting_host_reply = 0; + connsm->flags.conn_update_host_w4reply = 0; /* XXX: if we cant get a buffer, what do we do? We need to remember * reason if it was a negative reply. We also would need to have @@ -1393,7 +1393,7 @@ ble_ll_conn_hci_rd_rem_ver_cmd(const uint8_t *cmdbuf, uint8_t len) * NOTE: we cant just send the event here. That would cause the event to * be queued before the command status. */ - if (!connsm->flags.version_ind_sent) { + if (!connsm->flags.version_ind_txd) { ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_VERSION_XCHG, NULL); } else { connsm->pending_ctrl_procs |= (1 << BLE_LL_CTRL_PROC_VERSION_XCHG); @@ -1468,7 +1468,7 @@ ble_ll_conn_hci_rd_chan_map(const uint8_t *cmdbuf, uint8_t len, rc = BLE_ERR_UNK_CONN_ID; memset(rsp->chan_map, 0, sizeof(rsp->chan_map)); } else { - if (connsm->flags.chanmap_update_scheduled) { + if (connsm->flags.chanmap_update_sched) { memcpy(rsp->chan_map, connsm->req_chanmap, BLE_LL_CHAN_MAP_LEN); } else { memcpy(rsp->chan_map, connsm->chan_map, BLE_LL_CHAN_MAP_LEN); @@ -1990,7 +1990,7 @@ ble_ll_conn_hci_le_set_phy(const uint8_t *cmdbuf, uint8_t len) * If host has requested a PHY update and we are not finished do * not allow another one */ - if (connsm->flags.host_phy_update) { + if (connsm->flags.phy_update_host_initiated) { return BLE_ERR_CMD_DISALLOWED; } @@ -2019,9 +2019,9 @@ ble_ll_conn_hci_le_set_phy(const uint8_t *cmdbuf, uint8_t len) */ if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_PHY_UPDATE)) { if (connsm->cur_ctrl_proc != BLE_LL_CTRL_PROC_PHY_UPDATE) { - connsm->flags.ctrlr_phy_update = 0; + connsm->flags.phy_update_self_initiated = 0; } - connsm->flags.host_phy_update = 1; + connsm->flags.phy_update_host_initiated = 1; } else { /* * We could be doing a peer-initiated PHY update procedure. If this @@ -2029,20 +2029,20 @@ ble_ll_conn_hci_le_set_phy(const uint8_t *cmdbuf, uint8_t len) * we are not done with a peer-initiated procedure we just set the * pending bit but do not start the control procedure. */ - if (connsm->flags.peer_phy_update) { + if (connsm->flags.phy_update_peer_initiated) { connsm->pending_ctrl_procs |= (1 << BLE_LL_CTRL_PROC_PHY_UPDATE); - connsm->flags.host_phy_update = 1; + connsm->flags.phy_update_host_initiated = 1; } else { /* Check if we should start phy update procedure */ if (!ble_ll_conn_phy_update_if_needed(connsm)) { - connsm->flags.host_phy_update = 1; + connsm->flags.phy_update_host_initiated = 1; } else { /* * Set flag to send a PHY update complete event. We set flag * even if we do not do an update procedure since we have to * inform the host even if we decide not to change anything. */ - connsm->flags.phy_update_event = 1; + connsm->flags.phy_update_host_w4event = 1; } } } diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 0533f6dbda..ed03fd10f9 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -198,13 +198,13 @@ ble_ll_ctrl_phy_update_cancel(struct ble_ll_conn_sm *connsm, uint8_t ble_err) CLR_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_PHY_UPDATE); /* Check if the host wants an event */ - if (connsm->flags.host_phy_update) { + if (connsm->flags.phy_update_host_initiated) { ble_ll_hci_ev_phy_update(connsm, ble_err); - connsm->flags.host_phy_update = 0; + connsm->flags.phy_update_host_initiated = 0; } /* Clear any bits for phy updates that might be in progress */ - connsm->flags.ctrlr_phy_update = 0; + connsm->flags.phy_update_self_initiated = 0; } #endif @@ -367,7 +367,7 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr, */ ble_ll_hci_ev_rem_conn_parm_req(connsm, req); connsm->host_reply_opcode = opcode; - connsm->flags.awaiting_host_reply = 1; + connsm->flags.conn_update_host_w4reply = 1; rsp_opcode = 255; } else { /* Create reply to connection request */ @@ -570,11 +570,11 @@ ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t * if (ctrl_proc == BLE_LL_CTRL_PROC_CONN_PARAM_REQ) { ble_ll_hci_ev_conn_update(connsm, BLE_ERR_UNSUPP_REM_FEATURE); } else if (ctrl_proc == BLE_LL_CTRL_PROC_FEATURE_XCHG) { - if (connsm->flags.pending_hci_rd_features) { + if (connsm->flags.features_host_req) { ble_ll_hci_ev_rd_rem_used_feat(connsm, BLE_ERR_UNSUPP_REM_FEATURE); } - connsm->flags.pending_hci_rd_features = 0; + connsm->flags.features_host_req = 0; } } @@ -687,24 +687,24 @@ ble_ll_ctrl_phy_update_proc_complete(struct ble_ll_conn_sm *connsm) connsm->phy_tx_transition = 0; - if (connsm->flags.peer_phy_update) { - connsm->flags.peer_phy_update = 0; - } else if (connsm->flags.ctrlr_phy_update) { - connsm->flags.ctrlr_phy_update = 0; + if (connsm->flags.phy_update_peer_initiated) { + connsm->flags.phy_update_peer_initiated = 0; + } else if (connsm->flags.phy_update_self_initiated) { + connsm->flags.phy_update_self_initiated = 0; } else { /* Must be a host-initiated update */ - connsm->flags.host_phy_update = 0; + connsm->flags.phy_update_host_initiated = 0; chk_host_phy = 0; - if (connsm->flags.phy_update_event == 0) { + if (connsm->flags.phy_update_host_w4event == 0) { ble_ll_hci_ev_phy_update(connsm, BLE_ERR_SUCCESS); } } /* Must check if we need to start host procedure */ if (chk_host_phy) { - if (connsm->flags.host_phy_update) { + if (connsm->flags.phy_update_host_initiated) { if (ble_ll_conn_phy_update_if_needed(connsm)) { - connsm->flags.host_phy_update = 0; + connsm->flags.phy_update_host_initiated = 0; } else { chk_proc_stop = 0; } @@ -829,14 +829,14 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * one running. */ if ((m_to_s == 0) && (s_to_m == 0)) { - if (connsm->flags.peer_phy_update) { - connsm->flags.peer_phy_update = 0; - } else if (connsm->flags.ctrlr_phy_update) { - connsm->flags.ctrlr_phy_update = 0; + if (connsm->flags.phy_update_peer_initiated) { + connsm->flags.phy_update_peer_initiated = 0; + } else if (connsm->flags.phy_update_self_initiated) { + connsm->flags.phy_update_self_initiated = 0; ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_PHY_UPDATE); } else { ble_ll_hci_ev_phy_update(connsm, BLE_ERR_SUCCESS); - connsm->flags.host_phy_update = 0; + connsm->flags.phy_update_host_initiated = 0; ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_PHY_UPDATE); } instant = 0; @@ -921,7 +921,7 @@ ble_ll_ctrl_rx_phy_req(struct ble_ll_conn_sm *connsm, uint8_t *req, * NOTE: do not change order of these two lines as the call to * make the LL_PHY_UPDATE_IND pdu might clear the flag. */ - connsm->flags.peer_phy_update = 1; + connsm->flags.phy_update_peer_initiated = 1; ble_ll_ctrl_phy_update_ind_make(connsm, req, rsp, 1); rsp_opcode = BLE_LL_CTRL_PHY_UPDATE_IND; } @@ -940,14 +940,14 @@ ble_ll_ctrl_rx_phy_req(struct ble_ll_conn_sm *connsm, uint8_t *req, ble_ll_ctrl_phy_update_cancel(connsm, err); /* XXX: ? Should not be any phy update events */ - connsm->flags.phy_update_event = 0; + connsm->flags.phy_update_host_w4event = 0; } /* XXX: TODO: if we started another procedure with an instant * why are we doing this? Need to look into this.*/ /* Respond to central's phy update procedure */ - connsm->flags.peer_phy_update = 1; + connsm->flags.phy_update_peer_initiated = 1; ble_ll_ctrl_phy_req_rsp_make(connsm, rsp); rsp_opcode = BLE_LL_CTRL_PHY_RSP; @@ -1875,7 +1875,7 @@ static void ble_ll_ctrl_version_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld) { /* Set flag to denote we have sent/received this */ - connsm->flags.version_ind_sent = 1; + connsm->flags.version_ind_txd = 1; /* Fill out response */ pyld[0] = BLE_HCI_VER_BCS; @@ -1901,7 +1901,7 @@ ble_ll_ctrl_chanmap_req_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld) put_le16(pyld + BLE_LL_CHAN_MAP_LEN, connsm->chanmap_instant); /* Set scheduled flag */ - connsm->flags.chanmap_update_scheduled = 1; + connsm->flags.chanmap_update_sched = 1; } /** @@ -2125,7 +2125,7 @@ ble_ll_ctrl_update_features(struct ble_ll_conn_sm *connsm, uint8_t *feat) memcpy(connsm->remote_features, feat + 1, 7); /* If we received peer's features for the 1st time, we should try DLE */ - if (!connsm->flags.rxd_features) { + if (!connsm->flags.features_rxd) { #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) /* * If connection was established on uncoded PHY, by default we use @@ -2154,7 +2154,7 @@ ble_ll_ctrl_update_features(struct ble_ll_conn_sm *connsm, uint8_t *feat) connsm->flags.pending_initiate_dle = 1; #endif - connsm->flags.rxd_features = 1; + connsm->flags.features_rxd = 1; } } @@ -2234,9 +2234,9 @@ ble_ll_ctrl_rx_feature_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr) } /* Send event to host if pending features read */ - if (connsm->flags.pending_hci_rd_features) { + if (connsm->flags.features_host_req) { ble_ll_hci_ev_rd_rem_used_feat(connsm, BLE_ERR_SUCCESS); - connsm->flags.pending_hci_rd_features = 0; + connsm->flags.features_host_req = 0; } } @@ -2265,7 +2265,7 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * well. This is not expected to happen anyway. A return of BLE_ERR_MAX * means that we will simply discard the connection parameter request */ - if (connsm->flags.awaiting_host_reply) { + if (connsm->flags.conn_update_host_w4reply) { return BLE_ERR_MAX; } @@ -2326,7 +2326,7 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, */ #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) if ((connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) && - (connsm->flags.chanmap_update_scheduled)) { + (connsm->flags.chanmap_update_sched)) { rsp_opcode = BLE_LL_CTRL_REJECT_IND_EXT; rspbuf[1] = BLE_LL_CTRL_CONN_PARM_REQ; rspbuf[2] = BLE_ERR_DIFF_TRANS_COLL; @@ -2359,8 +2359,8 @@ ble_ll_ctrl_rx_conn_param_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, * state just clear the awaiting reply. The peripheral will hopefully stop its * procedure when we reply. */ - if (connsm->flags.awaiting_host_reply) { - connsm->flags.awaiting_host_reply = 0; + if (connsm->flags.conn_update_host_w4reply) { + connsm->flags.conn_update_host_w4reply = 0; } /* If we receive a response and no procedure is pending, just leave */ @@ -2395,10 +2395,10 @@ ble_ll_ctrl_rx_version_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, connsm->vers_nr = dptr[0]; connsm->comp_id = get_le16(dptr + 1); connsm->sub_vers_nr = get_le16(dptr + 3); - connsm->flags.rxd_version_ind = 1; + connsm->flags.version_ind_rxd = 1; rsp_opcode = BLE_ERR_MAX; - if (!connsm->flags.version_ind_sent) { + if (!connsm->flags.version_ind_txd) { rsp_opcode = BLE_LL_CTRL_VERSION_IND; ble_ll_ctrl_version_ind_make(connsm, rspbuf); } @@ -2439,7 +2439,7 @@ ble_ll_ctrl_rx_chanmap_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr) } else { connsm->chanmap_instant = instant; memcpy(connsm->req_chanmap, dptr, BLE_LL_CHAN_MAP_LEN); - connsm->flags.chanmap_update_scheduled = 1; + connsm->flags.chanmap_update_sched = 1; } return BLE_ERR_MAX; @@ -2734,7 +2734,7 @@ ble_ll_ctrl_chk_proc_start(struct ble_ll_conn_sm *connsm) * received the information dont start it. */ if ((i == BLE_LL_CTRL_PROC_VERSION_XCHG) && - (connsm->flags.rxd_version_ind)) { + (connsm->flags.version_ind_rxd)) { ble_ll_hci_ev_rd_rem_ver(connsm, BLE_ERR_SUCCESS); CLR_PENDING_CTRL_PROC(connsm, i); } else { @@ -3184,7 +3184,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) if (txpdu->om_data[1] == BLE_LL_CTRL_CONN_PARM_REQ && txpdu->om_data[2] != BLE_ERR_LMP_COLLISION) { connsm->reject_reason = txpdu->om_data[2]; - connsm->flags.host_expects_upd_event = 1; + connsm->flags.conn_update_host_w4event = 1; } } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) @@ -3206,7 +3206,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) break; case BLE_LL_CTRL_ENC_RSP: connsm->enc_data.enc_state = CONN_ENC_S_LTK_REQ_WAIT; - connsm->flags.send_ltk_req = 1; + connsm->flags.encrypt_ltk_req = 1; break; #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_CTRL_START_ENC_RSP: diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index 3fb5e7ae22..fb4424a596 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -135,7 +135,7 @@ ble_ll_hci_ev_encrypt_chg(struct ble_ll_conn_sm *connsm, uint8_t status) struct ble_hci_ev_enrypt_chg *ev_enc_chf; struct ble_hci_ev *hci_ev; - if (connsm->flags.encrypt_chg_sent == 0) { + if (connsm->flags.encrypt_event_sent == 0) { if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_ENCRYPT_CHG)) { hci_ev = ble_transport_alloc_evt(0); if (hci_ev) { @@ -151,7 +151,7 @@ ble_ll_hci_ev_encrypt_chg(struct ble_ll_conn_sm *connsm, uint8_t status) } } - connsm->flags.encrypt_chg_sent = 1; + connsm->flags.encrypt_event_sent = 1; return; } @@ -331,7 +331,7 @@ ble_ll_hci_ev_le_csa(struct ble_ll_conn_sm *connsm) ev->subev_code = BLE_HCI_LE_SUBEV_CHAN_SEL_ALG; ev->conn_handle = htole16(connsm->conn_handle); - ev->csa = connsm->flags.csa2_supp ? 0x01 : 0x00; + ev->csa = connsm->flags.csa2 ? 0x01 : 0x00; ble_ll_hci_event_send(hci_ev); } diff --git a/nimble/controller/test/src/ble_ll_csa2_test.c b/nimble/controller/test/src/ble_ll_csa2_test.c index 91081227e3..7939367e5e 100644 --- a/nimble/controller/test/src/ble_ll_csa2_test.c +++ b/nimble/controller/test/src/ble_ll_csa2_test.c @@ -34,7 +34,7 @@ TEST_CASE_SELF(ble_ll_csa2_test_1) */ memset(&conn, 0, sizeof(conn)); - conn.flags.csa2_supp = 1; + conn.flags.csa2 = 1; /* * based on sample data from CoreSpec 5.0 Vol 6 Part C 3.1 @@ -75,7 +75,7 @@ TEST_CASE_SELF(ble_ll_csa2_test_2) */ memset(&conn, 0, sizeof(conn)); - conn.flags.csa2_supp = 1; + conn.flags.csa2 = 1; /* * based on sample data from CoreSpec 5.0 Vol 6 Part C 3.2 From 42f1790a6ccdb401fa8bfb90f79cf83a7443db44 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 9 Jun 2023 17:28:47 +0200 Subject: [PATCH 0727/1333] nimble/drivers/fem: Add support for SKY66403-11 This adds driver for SKY66403-11. It is very similar to SKY66112-11 but PINs configuration has different meaning in transmit mode. --- .../fem/sky66403/include/sky66403/sky66403.h | 42 ++++ nimble/drivers/fem/sky66403/pkg.yml | 32 +++ nimble/drivers/fem/sky66403/src/sky66403.c | 201 ++++++++++++++++++ nimble/drivers/fem/sky66403/syscfg.yml | 76 +++++++ 4 files changed, 351 insertions(+) create mode 100644 nimble/drivers/fem/sky66403/include/sky66403/sky66403.h create mode 100644 nimble/drivers/fem/sky66403/pkg.yml create mode 100644 nimble/drivers/fem/sky66403/src/sky66403.c create mode 100644 nimble/drivers/fem/sky66403/syscfg.yml diff --git a/nimble/drivers/fem/sky66403/include/sky66403/sky66403.h b/nimble/drivers/fem/sky66403/include/sky66403/sky66403.h new file mode 100644 index 0000000000..a9dc99babd --- /dev/null +++ b/nimble/drivers/fem/sky66403/include/sky66403/sky66403.h @@ -0,0 +1,42 @@ +/* + * 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 _SKY66403_H +#define _SKY66403_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void sky66403_tx_linear_mode(uint8_t enabled); +void sky66403_rx_bypass(uint8_t enabled); +void sky66403_tx_bypass(uint8_t enabled); + +#if MYNEWT_VAL_CHOICE(SKY66403_ANTENNA_PORT, runtime) +uint8_t sky66403_default_antenna_get(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SKY66403_H */ diff --git a/nimble/drivers/fem/sky66403/pkg.yml b/nimble/drivers/fem/sky66403/pkg.yml new file mode 100644 index 0000000000..d119cf12cd --- /dev/null +++ b/nimble/drivers/fem/sky66403/pkg.yml @@ -0,0 +1,32 @@ +# +# 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: nimble/drivers/fem/sky66403 +pkg.description: Driver for SKY66403 front-end module +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" +pkg.apis: + - ble_fem_pa + - ble_fem_lna + - ble_fem_antenna +pkg.deps: + - nimble/controller + +pkg.init: + sky66403_init: 999 diff --git a/nimble/drivers/fem/sky66403/src/sky66403.c b/nimble/drivers/fem/sky66403/src/sky66403.c new file mode 100644 index 0000000000..1aa87d149d --- /dev/null +++ b/nimble/drivers/fem/sky66403/src/sky66403.c @@ -0,0 +1,201 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include + +static struct { + uint8_t rx_bypass : 1; + uint8_t tx_bypass : 1; +} sky66403_config = { + .rx_bypass = MYNEWT_VAL(SKY66403_RX_BYPASS), + .tx_bypass = MYNEWT_VAL(SKY66403_TX_BYPASS), +}; + +#if !MYNEWT_VAL_CHOICE(SKY66403_ANTENNA_PORT, runtime) +static uint8_t +sky66403_default_antenna_get(void) +{ + if (MYNEWT_VAL_CHOICE(SKY66403_ANTENNA_PORT, ANT2)) { + return 2; + } else { + return 1; + } +} +#endif + +static void +sky66403_bypass(uint8_t enabled) +{ + /* this is called only if bypass is enabled which means CPS PIN is + * correctly set and there is no need to check it here. + */ + hal_gpio_write(MYNEWT_VAL(SKY66403_PIN_CPS), enabled); +} + +void +ble_fem_pa_init(void) +{ + sky66403_tx_linear_mode(MYNEWT_VAL(SKY66403_TX_LINEAR_MODE)); + sky66403_tx_bypass(0); +#if MYNEWT_VAL(BLE_FEM_ANTENNA) + ble_fem_antenna(0); +#endif +} + +void +ble_fem_pa_enable(void) +{ + if (sky66403_config.tx_bypass) { + sky66403_bypass(1); + } +} + +void +ble_fem_pa_disable(void) +{ + if (sky66403_config.tx_bypass) { + sky66403_bypass(0); + } +} + +void +ble_fem_lna_init(void) +{ + sky66403_rx_bypass(0); +#if MYNEWT_VAL(BLE_FEM_ANTENNA) + ble_fem_antenna(0); +#endif +} + +void +ble_fem_lna_enable(void) +{ + if (sky66403_config.rx_bypass) { + sky66403_bypass(1); + } +} + +void +ble_fem_lna_disable(void) +{ + if (sky66403_config.rx_bypass) { + sky66403_bypass(0); + } +} + +void +sky66403_tx_linear_mode(uint8_t enabled) +{ + int pin = MYNEWT_VAL(SKY66403_PIN_CHL); + + if (pin >= 0) { + hal_gpio_write(pin, enabled); + } +} + +int +ble_fem_antenna(uint8_t port) +{ + int pin = MYNEWT_VAL(SKY66403_PIN_SEL); + uint8_t ant; + + if (pin >= 0) { + switch (port) { + case 0: + ant = sky66403_default_antenna_get(); + assert(ant == 1 || ant == 2); + return ble_fem_antenna(ant); + case 1: + hal_gpio_write(pin, 0); + break; + case 2: + hal_gpio_write(pin, 1); + break; + default: + return -1; + } + } + + return 0; +} + +void +sky66403_rx_bypass(uint8_t enabled) +{ + int pin = MYNEWT_VAL(SKY66403_PIN_CPS); + + if (pin >= 0) { + sky66403_config.rx_bypass = enabled; + sky66403_bypass(enabled); + } +} + +void +sky66403_tx_bypass(uint8_t enabled) +{ + int pin = MYNEWT_VAL(SKY66403_PIN_CPS); + + if (pin >= 0) { + sky66403_config.tx_bypass = enabled; + sky66403_bypass(enabled); + } +} + +void +sky66403_init(void) +{ + int pin; + + /* Use CRX and CTX to enable sleep mode */ + pin = MYNEWT_VAL(SKY66403_PIN_CSD); + if (pin >= 0) { + hal_gpio_init_out(pin, 1); + } + + /* Set default tx power mode */ + pin = MYNEWT_VAL(SKY66403_PIN_CHL); + if (pin >= 0) { + hal_gpio_init_out(pin, MYNEWT_VAL(SKY66403_TX_LINEAR_MODE)); + } + + /* Disable bypass, we'll enable it when needed */ + pin = MYNEWT_VAL(SKY66403_PIN_CPS); + if (pin >= 0) { + hal_gpio_init_out(pin, 0); + } + + /* configure default antenna */ + pin = MYNEWT_VAL(SKY66403_PIN_SEL); + if (pin >= 0) { + switch (sky66403_default_antenna_get()) { + case 1: + hal_gpio_init_out(pin, 0); + break; + case 2: + hal_gpio_init_out(pin, 1); + break; + default: + assert(0); + } + } +} diff --git a/nimble/drivers/fem/sky66403/syscfg.yml b/nimble/drivers/fem/sky66403/syscfg.yml new file mode 100644 index 0000000000..def2da51f3 --- /dev/null +++ b/nimble/drivers/fem/sky66403/syscfg.yml @@ -0,0 +1,76 @@ +# 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. +# + +syscfg.defs: + SKY66403_PIN_CSD: + description: > + GPIO pin number to control CSD signal. + When set to '-1', pin state will not be changed and it should be + driven externally. + value: -1 + SKY66403_PIN_CPS: + description: > + GPIO pin number to control CPS signal. + When set to '-1', pin state will not be changed and it should be + driven externally. + value: -1 + SKY66403_PIN_CHL: + description: > + GPIO pin number to control CHL signal. + When set to '-1', pin state will not be changed and it should be + driven externally. + value: -1 + SKY66403_PIN_SEL: + description: > + GPIO pin number to control SEL signal. + When set to '-1', pin state will not be changed and it should be + driven externally. + value: -1 + SKY66403_TX_LINEAR_MODE: + description: > + Enables linear mode for TX. + Only valid if CHL signal is controller by driver. + value: 0 + SKY66403_TX_BYPASS: + description: > + Enables bypass for TX which effectively disables operation as PA. + Only valid if CPS signal is controller by driver. + value: 0 + SKY66403_RX_BYPASS: + description: > + Enables bypass for RX which effectively disables operation as PA. + Only valid if CPS signal is controller by driver. + value: 0 + SKY66403_ANTENNA_PORT: + description: > + Selects which antenna port should be enabled. If 'runtime' is + selected SKY66403_default_antenna_get() (see SKY66403/SKY66403.h) + shall be implemeneted by application. + choices: + - ANT1 + - ANT2 + - runtime + value: ANT1 + +syscfg.vals.!BLE_FEM_PA: + # Enable TX bypass by default if PA is disabled + SKY66403_TX_BYPASS: 1 + +syscfg.vals.!BLE_FEM_LNA: + # Enable RX bypass by default if LNA is disabled + SKY66403_RX_BYPASS: 1 From b590fab9405115e5ff730f5fc17dd02f92e84531 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 20 Jun 2023 13:50:40 +0200 Subject: [PATCH 0728/1333] nimble/phy/cmac: Move chip variant detection to core Chip variant detection does not work properly in ble_rf_init since it may be called when PD_SYS is disabled. We better do this in core on CMAC startup as PD_SYS is always enabled at that time. --- nimble/drivers/dialog_cmac/src/ble_rf.c | 30 +++---------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/nimble/drivers/dialog_cmac/src/ble_rf.c b/nimble/drivers/dialog_cmac/src/ble_rf.c index 32ae0634e2..f9756ec645 100644 --- a/nimble/drivers/dialog_cmac/src/ble_rf.c +++ b/nimble/drivers/dialog_cmac/src/ble_rf.c @@ -30,14 +30,6 @@ #define RF_CALIBRATION_1 (0x02) #define RF_CALIBRATION_2 (0x04) -enum chip_variant { - CHIP_VARIANT_TSMC, - CHIP_VARIANT_GF, - CHIP_VARIANT_UNKNOWN -}; - -static int g_chip_variant; - static const int8_t g_ble_rf_power_lvls[] = { -18, -12, -8, -6, -3, -2, -1, 0, 1, 2, 3, 4, 4, 5, 6 }; @@ -122,21 +114,6 @@ set_reg16_mask(uint32_t addr, uint16_t mask, uint16_t val) *reg = (*reg & (~mask)) | (val & mask); } -static inline int -read_chip_variant(void) -{ - uint32_t chip_id1 = get_reg32_bits(0x50040200, 0xFF); - - switch (chip_id1) { - case '2': - return CHIP_VARIANT_TSMC; - case '3': - return CHIP_VARIANT_GF; - default: - return CHIP_VARIANT_UNKNOWN; - } -} - static void delay_us(uint32_t delay_us) { @@ -256,7 +233,7 @@ ble_rf_synth_is_enabled(void) static void ble_rf_synth_apply_recommended_settings(void) { - if (g_chip_variant == CHIP_VARIANT_GF) { + if (mcu_chip_variant_get() == MCU_CHIP_VARIANT_GF) { set_reg32_mask(0x40022034, 0x00000018, 0x0215807B); } set_reg32_mask(0x40022048, 0x0000000c, 0x000000d5); @@ -361,7 +338,7 @@ ble_rf_calibration_1(void) set_reg32(0x40020000, 0x0f168820); set_reg32_bits(0x40022000, 0x00000001, 0); set_reg32_bits(0x4002101c, 0x00001e00, 0); - if (g_chip_variant == CHIP_VARIANT_TSMC) { + if (mcu_chip_variant_get() == MCU_CHIP_VARIANT_TSMC) { set_reg32_bits(0x4002001c, 0x0000003f, 47); } else { set_reg32_bits(0x4002001c, 0x0000003f, 44); @@ -567,8 +544,7 @@ ble_rf_init(void) static bool done = false; uint32_t val; - g_chip_variant = read_chip_variant(); - assert(g_chip_variant != CHIP_VARIANT_UNKNOWN); + assert(mcu_chip_variant_get()); ble_rf_disable(); From 80ef459c48dd2e938789013da1222438ffa2bf92 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 14 Oct 2022 18:48:51 +0200 Subject: [PATCH 0729/1333] nimble/transport: Add UART transport for external controller This is the same as standard "uart" transport except it's for LL side which means it can be used for NimBLE host to talk to external controller. Enable it by "BLE_TRANSPORT_LL: uart_ll". --- nimble/transport/pkg.yml | 2 + nimble/transport/syscfg.yml | 1 + nimble/transport/uart_ll/pkg.yml | 32 ++++ nimble/transport/uart_ll/src/hci_uart.c | 245 ++++++++++++++++++++++++ nimble/transport/uart_ll/syscfg.yml | 39 ++++ 5 files changed, 319 insertions(+) create mode 100644 nimble/transport/uart_ll/pkg.yml create mode 100644 nimble/transport/uart_ll/src/hci_uart.c create mode 100644 nimble/transport/uart_ll/syscfg.yml diff --git a/nimble/transport/pkg.yml b/nimble/transport/pkg.yml index 5070c72883..30237f75bd 100644 --- a/nimble/transport/pkg.yml +++ b/nimble/transport/pkg.yml @@ -48,6 +48,8 @@ pkg.deps.'BLE_TRANSPORT_HS == "cdc"': - nimble/transport/cdc pkg.deps.'BLE_TRANSPORT_LL == "apollo3"': - nimble/transport/apollo3 +pkg.deps.'BLE_TRANSPORT_LL == "uart_ll"': + - nimble/transport/uart_ll pkg.deps.BLE_MONITOR_RTT: - "@apache-mynewt-core/hw/drivers/rtt" diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml index 7f02f6cc8f..febe09d401 100644 --- a/nimble/transport/syscfg.yml +++ b/nimble/transport/syscfg.yml @@ -46,6 +46,7 @@ syscfg.defs: - nrf5340 - socket - apollo3 + - uart_ll - custom BLE_TRANSPORT_ACL_COUNT: diff --git a/nimble/transport/uart_ll/pkg.yml b/nimble/transport/uart_ll/pkg.yml new file mode 100644 index 0000000000..efc97d5456 --- /dev/null +++ b/nimble/transport/uart_ll/pkg.yml @@ -0,0 +1,32 @@ +# +# 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: nimble/transport/uart_ll +pkg.description: HCI H4 transport over UART to external controller +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" + +pkg.deps: + - "@apache-mynewt-core/hw/hal" + - "@apache-mynewt-core/kernel/os" + - nimble + - nimble/transport/common/hci_h4 + +pkg.apis: + - ble_transport diff --git a/nimble/transport/uart_ll/src/hci_uart.c b/nimble/transport/uart_ll/src/hci_uart.c new file mode 100644 index 0000000000..95eae3f4b3 --- /dev/null +++ b/nimble/transport/uart_ll/src/hci_uart.c @@ -0,0 +1,245 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include "os/os_mbuf.h" +#include "os/os_mempool.h" +#include "hal/hal_uart.h" +#include "nimble/transport.h" +#include "nimble/transport/hci_h4.h" + +#define TX_Q_SIZE (MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_HS_COUNT) + 1) + +struct hci_uart_tx { + uint8_t type; + uint8_t sent_type; + uint16_t len; + uint16_t idx; + + struct os_mbuf *om; + uint8_t *buf; + + STAILQ_ENTRY(hci_uart_tx) tx_q_next; +}; + +static STAILQ_HEAD(, hci_uart_tx) tx_q; + +static struct os_mempool pool_tx_q; +static uint8_t pool_tx_q_buf[ OS_MEMPOOL_BYTES(TX_Q_SIZE, + sizeof(struct hci_uart_tx)) ]; + +struct hci_h4_sm hci_uart_h4sm; + +static int +hci_uart_frame_cb(uint8_t pkt_type, void *data) +{ + switch (pkt_type) { + case HCI_H4_EVT: + return ble_transport_to_hs_evt(data); + case HCI_H4_ACL: + return ble_transport_to_hs_acl(data); + default: + assert(0); + break; + } + + return -1; +} + +static int +hci_uart_rx_char(void *arg, uint8_t data) +{ + hci_h4_sm_rx(&hci_uart_h4sm, &data, 1); + + return 0; +} + +static int +hci_uart_tx_char(void *arg) +{ + struct hci_uart_tx *tx; + uint8_t ch; + os_sr_t sr; + + OS_ENTER_CRITICAL(sr); + tx = STAILQ_FIRST(&tx_q); + OS_EXIT_CRITICAL(sr); + if (!tx) { + return -1; + } + + if (!tx->sent_type) { + tx->sent_type = 1; + return tx->type; + } + + switch (tx->type) { + case HCI_H4_CMD: + ch = tx->buf[tx->idx]; + tx->idx++; + if (tx->idx == tx->len) { + ble_transport_free(tx->buf); + OS_ENTER_CRITICAL(sr); + STAILQ_REMOVE_HEAD(&tx_q, tx_q_next); + OS_EXIT_CRITICAL(sr); + os_memblock_put(&pool_tx_q, tx); + } + break; + case HCI_H4_ACL: + os_mbuf_copydata(tx->om, 0, 1, &ch); + os_mbuf_adj(tx->om, 1); + tx->len--; + if (tx->len == 0) { + os_mbuf_free_chain(tx->om); + OS_ENTER_CRITICAL(sr); + STAILQ_REMOVE_HEAD(&tx_q, tx_q_next); + OS_EXIT_CRITICAL(sr); + os_memblock_put(&pool_tx_q, tx); + } + break; + default: + assert(0); + OS_ENTER_CRITICAL(sr); + STAILQ_REMOVE_HEAD(&tx_q, tx_q_next); + OS_EXIT_CRITICAL(sr); + os_memblock_put(&pool_tx_q, tx); + } + + return ch; +} + +static int +hci_uart_configure(void) +{ + enum hal_uart_parity parity; + enum hal_uart_flow_ctl flowctl; + int rc; + + rc = hal_uart_init_cbs(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT), + hci_uart_tx_char, NULL, + hci_uart_rx_char, NULL); + if (rc != 0) { + return -1; + } + + if (MYNEWT_VAL_CHOICE(BLE_TRANSPORT_UART_PARITY, odd)) { + parity = HAL_UART_PARITY_ODD; + } else if (MYNEWT_VAL_CHOICE(BLE_TRANSPORT_UART_PARITY, even)) { + parity = HAL_UART_PARITY_EVEN; + } else { + parity = HAL_UART_PARITY_NONE; + } + + if (MYNEWT_VAL_CHOICE(BLE_TRANSPORT_UART_FLOW_CONTROL, rtscts)) { + flowctl = HAL_UART_FLOW_CTL_RTS_CTS; + } else { + flowctl = HAL_UART_FLOW_CTL_NONE; + } + + rc = hal_uart_config(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT), + MYNEWT_VAL(BLE_TRANSPORT_UART_BAUDRATE), + MYNEWT_VAL(BLE_TRANSPORT_UART_DATA_BITS), + MYNEWT_VAL(BLE_TRANSPORT_UART_STOP_BITS), + parity, flowctl); + if (rc != 0) { + return -1; + } + + return 0; +} + +int +ble_transport_to_ll_cmd_impl(void *buf) +{ + struct hci_uart_tx *txe; + os_sr_t sr; + + txe = os_memblock_get(&pool_tx_q); + if (!txe) { + assert(0); + return -ENOMEM; + } + + txe->type = HCI_H4_CMD; + txe->sent_type = 0; + txe->len = 3 + ((uint8_t *)buf)[2]; + txe->buf = buf; + txe->idx = 0; + txe->om = NULL; + + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&tx_q, txe, tx_q_next); + OS_EXIT_CRITICAL(sr); + + hal_uart_start_tx(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT)); + + return 0; +} + +int +ble_transport_to_ll_acl_impl(struct os_mbuf *om) +{ + struct hci_uart_tx *txe; + os_sr_t sr; + + txe = os_memblock_get(&pool_tx_q); + if (!txe) { + assert(0); + return -ENOMEM; + } + + txe->type = HCI_H4_ACL; + txe->sent_type = 0; + txe->len = OS_MBUF_PKTLEN(om); + txe->idx = 0; + txe->buf = NULL; + txe->om = om; + + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&tx_q, txe, tx_q_next); + OS_EXIT_CRITICAL(sr); + + hal_uart_start_tx(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT)); + + return 0; +} + +void +ble_transport_ll_init(void) +{ + int rc; + + SYSINIT_ASSERT_ACTIVE(); + + rc = hci_uart_configure(); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = os_mempool_init(&pool_tx_q, TX_Q_SIZE, sizeof(struct hci_uart_tx), + pool_tx_q_buf, "hci_uart_tx_q"); + SYSINIT_PANIC_ASSERT(rc == 0); + + hci_h4_sm_init(&hci_uart_h4sm, &hci_h4_allocs_from_ll, hci_uart_frame_cb); + + STAILQ_INIT(&tx_q); +} diff --git a/nimble/transport/uart_ll/syscfg.yml b/nimble/transport/uart_ll/syscfg.yml new file mode 100644 index 0000000000..ccf38b61a5 --- /dev/null +++ b/nimble/transport/uart_ll/syscfg.yml @@ -0,0 +1,39 @@ +# 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. +# + +syscfg.defs: + BLE_TRANSPORT_UART_LL_PORT: + description: UART index to use for HCI interface + value: 0 + BLE_TRANSPORT_UART_LL_BAUDRATE: + description: Baudrate on UART + value: 1000000 + BLE_TRANSPORT_UART_LL_DATA_BITS: + description: Number of data bits on UART + value: 8 + BLE_TRANSPORT_UART_LL_STOP_BITS: + description: Number of stop bits on UART + value: 1 + BLE_TRANSPORT_UART_LL_PARITY: + description: Parity on UART + value: none + choices: none,even,odd + BLE_TRANSPORT_UART_LL_FLOW_CONTROL: + description: Flow control on UART + choices: off,rtscts + value: rtscts From eead9c1fe4deafad14108a9ba1858c81a4b3d384 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 22 Jun 2023 16:14:09 +0200 Subject: [PATCH 0730/1333] nimble/phy/nrf5340: Add support for high voltage on RADIO This allows to set few more power levels on PHY (up to +3dBm). --- nimble/drivers/nrf5x/src/ble_phy.c | 2 +- nimble/drivers/nrf5x/src/nrf52/phy.c | 6 +++ nimble/drivers/nrf5x/src/nrf53/phy.c | 77 +++++++++++++++++++++++++++- nimble/drivers/nrf5x/src/phy_priv.h | 1 + nimble/drivers/nrf5x/syscfg.yml | 8 +++ 5 files changed, 91 insertions(+), 3 deletions(-) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 223afbff9c..84d2ff5e2f 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -2019,7 +2019,7 @@ ble_phy_tx_power_set(int dbm) /* Get actual TX power supported by radio */ dbm = phy_txpower_round(dbm); - NRF_RADIO->TXPOWER = dbm; + phy_txpower_set(dbm); g_ble_phy_data.phy_txpwr_dbm = dbm; return 0; diff --git a/nimble/drivers/nrf5x/src/nrf52/phy.c b/nimble/drivers/nrf5x/src/nrf52/phy.c index 6a6eeb882c..30a19966b7 100644 --- a/nimble/drivers/nrf5x/src/nrf52/phy.c +++ b/nimble/drivers/nrf5x/src/nrf52/phy.c @@ -179,6 +179,12 @@ phy_ppi_init(void) (uint32_t)&(NRF_RADIO->TASKS_DISABLE)); } +void +phy_txpower_set(int8_t dbm) +{ + NRF_RADIO->TXPOWER = dbm; +} + int8_t phy_txpower_round(int8_t dbm) { diff --git a/nimble/drivers/nrf5x/src/nrf53/phy.c b/nimble/drivers/nrf5x/src/nrf53/phy.c index 8310406526..ceda769b0f 100644 --- a/nimble/drivers/nrf5x/src/nrf53/phy.c +++ b/nimble/drivers/nrf5x/src/nrf53/phy.c @@ -22,6 +22,14 @@ #include #include "../phy_priv.h" +/* + * When the radio is operated on high voltage (see VREQCTRL - Voltage request + * control on page 62 for how to control voltage), the output power is increased + * by 3 dB. I.e. if the TXPOWER value is set to 0 dBm and high voltage is + * requested using VREQCTRL, the output power will be +3 + * */ +#define NRF_TXPOWER_VREQH 3 + #if PHY_USE_DEBUG void phy_debug_init(void) @@ -180,9 +188,50 @@ phy_ppi_init(void) NRF_TIMER0->SUBSCRIBE_CAPTURE[2] = DPPI_CH_SUB(RADIO_EVENTS_END); } +void +phy_txpower_set(int8_t dbm) +{ +#if MYNEWT_VAL(BLE_PHY_NRF5340_VDDH) + switch (dbm) { + case ((int8_t)RADIO_TXPOWER_TXPOWER_0dBm) + NRF_TXPOWER_VREQH: + case ((int8_t)RADIO_TXPOWER_TXPOWER_Neg1dBm) + NRF_TXPOWER_VREQH: + case ((int8_t)RADIO_TXPOWER_TXPOWER_Neg2dBm) + NRF_TXPOWER_VREQH: + case ((int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm) + NRF_TXPOWER_VREQH: + case ((int8_t)RADIO_TXPOWER_TXPOWER_Neg16dBm) + NRF_TXPOWER_VREQH: + case ((int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm) + NRF_TXPOWER_VREQH: + case ((int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm) + NRF_TXPOWER_VREQH: + NRF_VREQCTRL->VREGRADIO.VREQH = 1; + dbm -= NRF_TXPOWER_VREQH; + break; + default: + NRF_VREQCTRL->VREGRADIO.VREQH = 0; + break; + } +#endif + + NRF_RADIO->TXPOWER = dbm; +} + int8_t phy_txpower_round(int8_t dbm) { +#if MYNEWT_VAL(BLE_PHY_NRF5340_VDDH) + /* +3 dBm */ + if (dbm >= ((int8_t)RADIO_TXPOWER_TXPOWER_0dBm) + NRF_TXPOWER_VREQH) { + return ((int8_t)RADIO_TXPOWER_TXPOWER_0dBm) + NRF_TXPOWER_VREQH; + } + + /* +2 dBm */ + if (dbm >= ((int8_t)RADIO_TXPOWER_TXPOWER_Neg1dBm) + NRF_TXPOWER_VREQH) { + return ((int8_t)RADIO_TXPOWER_TXPOWER_Neg1dBm) + NRF_TXPOWER_VREQH; + } + + /* +1 dBm */ + if (dbm >= ((int8_t)RADIO_TXPOWER_TXPOWER_Neg2dBm) + NRF_TXPOWER_VREQH) { + return ((int8_t)RADIO_TXPOWER_TXPOWER_Neg2dBm) + NRF_TXPOWER_VREQH; + } +#endif + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_0dBm) { return (int8_t)RADIO_TXPOWER_TXPOWER_0dBm; } @@ -219,21 +268,45 @@ phy_txpower_round(int8_t dbm) return (int8_t)RADIO_TXPOWER_TXPOWER_Neg8dBm; } +#if MYNEWT_VAL(BLE_PHY_NRF5340_VDDH) + /* -9 dBm */ + if (dbm >= ((int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm) + NRF_TXPOWER_VREQH) { + return ((int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm) + NRF_TXPOWER_VREQH; + } +#endif + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm) { return (int8_t)RADIO_TXPOWER_TXPOWER_Neg12dBm; } +#if MYNEWT_VAL(BLE_PHY_NRF5340_VDDH) + /* -13 dBm */ + if (dbm >= ((int8_t)RADIO_TXPOWER_TXPOWER_Neg16dBm) + NRF_TXPOWER_VREQH) { + return ((int8_t)RADIO_TXPOWER_TXPOWER_Neg16dBm) + NRF_TXPOWER_VREQH; + } +#endif + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg16dBm) { return (int8_t)RADIO_TXPOWER_TXPOWER_Neg16dBm; } +#if MYNEWT_VAL(BLE_PHY_NRF5340_VDDH) + /* -17 dBm */ + if (dbm >= ((int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm) + NRF_TXPOWER_VREQH) { + return ((int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm) + NRF_TXPOWER_VREQH; + } +#endif + if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm) { return (int8_t)RADIO_TXPOWER_TXPOWER_Neg20dBm; } - if (dbm >= (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm) { - return (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm; +#if MYNEWT_VAL(BLE_PHY_NRF5340_VDDH) + /* -37 dBm */ + if (dbm >= ((int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm) + NRF_TXPOWER_VREQH) { + return ((int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm) + NRF_TXPOWER_VREQH; } +#endif return (int8_t)RADIO_TXPOWER_TXPOWER_Neg40dBm; } diff --git a/nimble/drivers/nrf5x/src/phy_priv.h b/nimble/drivers/nrf5x/src/phy_priv.h index c732352032..db0664da2b 100644 --- a/nimble/drivers/nrf5x/src/phy_priv.h +++ b/nimble/drivers/nrf5x/src/phy_priv.h @@ -83,6 +83,7 @@ void phy_ppi_init(void); #include "nrf52/phy_ppi.h" #endif +void phy_txpower_set(int8_t dbm); int8_t phy_txpower_round(int8_t dbm); #ifdef NRF52_SERIES diff --git a/nimble/drivers/nrf5x/syscfg.yml b/nimble/drivers/nrf5x/syscfg.yml index e483e844be..07c9042f67 100644 --- a/nimble/drivers/nrf5x/syscfg.yml +++ b/nimble/drivers/nrf5x/syscfg.yml @@ -64,6 +64,14 @@ syscfg.defs: works for TX (i.e. ISO Broadcaster). value: 0 + BLE_PHY_NRF5340_VDDH: + description: > + This indicates if VDDH pin of nRF5340 is connected to external + power source. If connected PHY driver will make use of high voltage + operation mode for additional TX power levels (+3, +2, +1, -9, -13, + -17, -37). + value: 0 + BLE_PHY_UBLOX_BMD345_PUBLIC_ADDR: description: > Ublox BMD-345 modules come with public address preprogrammed From 326fb77c0fe278011879872ea74c89fdec75e66e Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Wed, 28 Jun 2023 11:40:12 +0200 Subject: [PATCH 0731/1333] nimble/phy/nrf5x: Update NRF5340 errata 158 Errata specifies only NRF_RADIO registers that should be copied from FICR, code copied all registers from TRIMCNF. Now only NRF_RADIO registers are copied as part of Errata 158 implementation. Signed-off-by: Jerzy Kasenberg --- nimble/drivers/nrf5x/src/ble_phy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 84d2ff5e2f..3ba359c8f3 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -1571,7 +1571,9 @@ ble_phy_init(void) /* Errata 158: load trim values after toggling power */ for (uint32_t index = 0; index < 32ul && NRF_FICR_NS->TRIMCNF[index].ADDR != (uint32_t *)0xFFFFFFFFul; index++) { - *((volatile uint32_t *)NRF_FICR_NS->TRIMCNF[index].ADDR) = NRF_FICR_NS->TRIMCNF[index].DATA; + if (((uint32_t)NRF_FICR_NS->TRIMCNF[index].ADDR & 0xFFFFF000ul) == (volatile uint32_t)NRF_RADIO_NS) { + *((volatile uint32_t *)NRF_FICR_NS->TRIMCNF[index].ADDR) = NRF_FICR_NS->TRIMCNF[index].DATA; + } } *(volatile uint32_t *)(NRF_RADIO_NS_BASE + 0x774) = From 5923735634d770ecb4811c315d83ef120b3589b4 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Wed, 28 Jun 2023 10:29:43 +0200 Subject: [PATCH 0732/1333] host/l2cap: fix typo in the macro's name Changed from 'BLE_L2CAP_ERR_RECONFIG_UNACCAPTED_PARAM' to 'BLE_L2CAP_ERR_RECONFIG_UNACCEPTED_PARAM'. --- nimble/host/include/host/ble_l2cap.h | 2 +- nimble/host/src/ble_l2cap_sig.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nimble/host/include/host/ble_l2cap.h b/nimble/host/include/host/ble_l2cap.h index aef9682cc4..6edfa85d78 100644 --- a/nimble/host/include/host/ble_l2cap.h +++ b/nimble/host/include/host/ble_l2cap.h @@ -80,7 +80,7 @@ struct ble_hs_conn; #define BLE_L2CAP_ERR_RECONFIG_REDUCTION_MTU_NOT_ALLOWED 0x0001 #define BLE_L2CAP_ERR_RECONFIG_REDUCTION_MPS_NOT_ALLOWED 0x0002 #define BLE_L2CAP_ERR_RECONFIG_INVALID_DCID 0x0003 -#define BLE_L2CAP_ERR_RECONFIG_UNACCAPTED_PARAM 0x0004 +#define BLE_L2CAP_ERR_RECONFIG_UNACCEPTED_PARAM 0x0004 #define BLE_L2CAP_EVENT_COC_CONNECTED 0 #define BLE_L2CAP_EVENT_COC_DISCONNECTED 1 diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index 05f5829f51..42459179bb 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -795,14 +795,14 @@ ble_l2cap_sig_credit_base_reconfig_req_rx(uint16_t conn_handle, } if (hdr->length <= sizeof(*req)) { - rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_UNACCAPTED_PARAM); + rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_UNACCEPTED_PARAM); goto failed; } req = (struct ble_l2cap_sig_credit_base_reconfig_req *)(*om)->om_data; if ((req->mps < BLE_L2CAP_ECOC_MIN_MTU) || (req->mtu < BLE_L2CAP_ECOC_MIN_MTU)) { - rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_UNACCAPTED_PARAM); + rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_UNACCEPTED_PARAM); goto failed; } @@ -811,7 +811,7 @@ ble_l2cap_sig_credit_base_reconfig_req_rx(uint16_t conn_handle, cid_cnt = (hdr->length - sizeof(*req)) / sizeof(uint16_t); if (cid_cnt > BLE_L2CAP_MAX_COC_CONN_REQ) { - rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_UNACCAPTED_PARAM); + rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_UNACCEPTED_PARAM); goto failed; } From 66c866465f574dee2abbe1a9738148f2d840d154 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Fri, 30 Jun 2023 16:23:06 +0200 Subject: [PATCH 0733/1333] host/dtm: add doxygen comments for the header file Add missing doxygen comments. --- nimble/host/include/host/ble_dtm.h | 77 ++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/nimble/host/include/host/ble_dtm.h b/nimble/host/include/host/ble_dtm.h index e340a3069a..cd01a23b70 100644 --- a/nimble/host/include/host/ble_dtm.h +++ b/nimble/host/include/host/ble_dtm.h @@ -25,25 +25,102 @@ extern "C" { #endif +/** + * @file ble_dtm.h + * + * @brief DTM (Direct Test Mode) + * + * This header file provides the interface and data structures for working with + * the Direct Test Mode (DTM) functionality in a BLE (Bluetooth Low Energy) host. + * DTM allows for testing and validation of the BLE radio performance by enabling + * custom transmission and reception of data packets. + * + * @defgroup bt_host_dtm Bluetooth Host Direct Test Mode + * @ingroup bt_host + * @{ + */ + +/** + * @struct ble_dtm_rx_params + * @brief Parameters for DTM RX test. + * + * This structure represents the parameters for a Direct Test Mode (DTM) receiver test. + */ struct ble_dtm_rx_params { + /** The channel to use for the RX test. */ uint8_t channel; + + /** The PHY to use for the RX test. */ uint8_t phy; + + /** The modulation index to use for the RX test. */ uint8_t modulation_index; }; +/** + * @brief Start a Direct Test Mode (DTM) receiver test. + * + * This function starts a DTM RX test with the provided parameters. + * + * @param params The parameters for the DTM RX test. + * + * @return 0 on success; + * A non-zero value on failure. + */ int ble_dtm_rx_start(const struct ble_dtm_rx_params *params); +/** + * @struct ble_dtm_tx_params + * @brief Parameters for DTM TX test. + * + * This structure represents the parameters for a Direct Test Mode (DTM) transmitter test. + */ struct ble_dtm_tx_params { + /** The channel to use for the TX test. */ uint8_t channel; + + /** The length of the data for the TX test. */ uint8_t test_data_len; + + /** The payload to use for the TX test. */ uint8_t payload; + + /** The PHY to use for the TX test. */ uint8_t phy; }; + +/** + * @brief Start a Direct Test Mode (DTM) transmitter test. + * + * This function starts a DTM TX test with the provided parameters. + * + * @param params The parameters for the DTM TX test. + * + * @return 0 on success; + * A non-zero value on failure. + */ int ble_dtm_tx_start(const struct ble_dtm_tx_params *params); +/** + * @brief Stops a Direct Test Mode (DTM) test and retrieves the number of transmitted packets. + * + * This function sends a command to the Bluetooth controller to stop the currently running DTM test. + * It retrieves the number of packets transmitted during the test and stores it in the provided `num_packets` variable. + * + * @param num_packets Pointer to a `uint16_t` variable to store the number of transmitted packets. + * If an error occurs, the value will be set to 0. + * + * @return 0 on success; + * A non-zero value on failure. + */ int ble_dtm_stop(uint16_t *num_packets); #ifdef __cplusplus } #endif + +/** + * @} + */ + #endif From a0f74cd1812423006e6700c05bbe5b07c9ff8881 Mon Sep 17 00:00:00 2001 From: Petro Karashchenko Date: Fri, 7 Jul 2023 19:46:14 +0300 Subject: [PATCH 0734/1333] porting/examples/nuttx: align parameters passed to ble_npl_task_init() Signed-off-by: Petro Karashchenko --- porting/examples/nuttx/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/porting/examples/nuttx/main.c b/porting/examples/nuttx/main.c index 9eeddec838..7e289be77d 100644 --- a/porting/examples/nuttx/main.c +++ b/porting/examples/nuttx/main.c @@ -111,8 +111,8 @@ int main(int argc, char *argv[]) printf("hci_sock task init\n"); ret = ble_npl_task_init(&s_task_hci, "hci_sock", ble_hci_sock_task, - NULL, TASK_DEFAULT_PRIORITY, BLE_NPL_TIME_FOREVER, - TASK_DEFAULT_STACK, TASK_DEFAULT_STACK_SIZE); + NULL, TASK_DEFAULT_PRIORITY, BLE_NPL_TIME_FOREVER, + TASK_DEFAULT_STACK, TASK_DEFAULT_STACK_SIZE); if (ret != 0) { @@ -122,8 +122,8 @@ int main(int argc, char *argv[]) /* Create task which handles default event queue for host stack. */ printf("ble_host task init\n"); ret = ble_npl_task_init(&s_task_host, "ble_host", ble_host_task, - NULL, TASK_DEFAULT_PRIORITY, BLE_NPL_TIME_FOREVER, - TASK_DEFAULT_STACK, TASK_DEFAULT_STACK_SIZE); + NULL, TASK_DEFAULT_PRIORITY, BLE_NPL_TIME_FOREVER, + TASK_DEFAULT_STACK, TASK_DEFAULT_STACK_SIZE); if (ret != 0) From 62cfff48402e503a8163948044f5ef8d9504a874 Mon Sep 17 00:00:00 2001 From: Petro Karashchenko Date: Fri, 7 Jul 2023 19:47:28 +0300 Subject: [PATCH 0735/1333] porting/npl/nuttx: add support for thread names Use pthread_setname_np() to set names for created tasks Signed-off-by: Petro Karashchenko --- porting/npl/nuttx/src/os_callout.c | 1 + porting/npl/nuttx/src/os_task.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/porting/npl/nuttx/src/os_callout.c b/porting/npl/nuttx/src/os_callout.c index eb69bb8b66..3b4ee5fb0e 100644 --- a/porting/npl/nuttx/src/os_callout.c +++ b/porting/npl/nuttx/src/os_callout.c @@ -91,6 +91,7 @@ ble_npl_callout_init(struct ble_npl_callout *c, pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, CONFIG_NIMBLE_CALLOUT_THREAD_STACKSIZE); pthread_create(&callout_thread, &attr, callout_handler, NULL); + pthread_setname_np(callout_thread, "ble_npl_callout"); thread_started = true; } diff --git a/porting/npl/nuttx/src/os_task.c b/porting/npl/nuttx/src/os_task.c index 40f8c8c7ba..075928a784 100644 --- a/porting/npl/nuttx/src/os_task.c +++ b/porting/npl/nuttx/src/os_task.c @@ -77,6 +77,10 @@ ble_npl_task_init(struct ble_npl_task *t, const char *name, ble_npl_task_func_t { err = OS_ENOMEM; } + else + { + pthread_setname_np(t->handle, t->name); + } return err; } From 4953755ee54c41a37f708e73202b9bc64451eb40 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Fri, 23 Jun 2023 17:18:28 +0200 Subject: [PATCH 0736/1333] host/att: add doxygen comments for the header file --- nimble/host/include/host/ble_att.h | 149 +++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/nimble/host/include/host/ble_att.h b/nimble/host/include/host/ble_att.h index 391a992aeb..cb98eab478 100644 --- a/nimble/host/include/host/ble_att.h +++ b/nimble/host/include/host/ble_att.h @@ -32,75 +32,224 @@ extern "C" { #endif +/** Chained memory buffer. */ struct os_mbuf; +/** + * @defgroup ble_att_uuids Attribute Protocol (ATT) UUIDs + * @{ + */ +/** UUID for a primary service. */ #define BLE_ATT_UUID_PRIMARY_SERVICE 0x2800 + +/** UUID for a secondary service. */ #define BLE_ATT_UUID_SECONDARY_SERVICE 0x2801 + +/** UUID for an include definition. */ #define BLE_ATT_UUID_INCLUDE 0x2802 + +/** UUID for a characteristic. */ #define BLE_ATT_UUID_CHARACTERISTIC 0x2803 +/** @} */ + +/** + * @defgroup ble_att_err_codes Attribute Protocol (ATT) Error Codes + * @{ + */ + +/** The attribute handle given was not valid on this server */ #define BLE_ATT_ERR_INVALID_HANDLE 0x01 + +/** The attribute cannot be read. */ #define BLE_ATT_ERR_READ_NOT_PERMITTED 0x02 + +/** The attribute cannot be written. */ #define BLE_ATT_ERR_WRITE_NOT_PERMITTED 0x03 + +/** The attribute PDU was invalid. */ #define BLE_ATT_ERR_INVALID_PDU 0x04 + +/** The attribute requires authentication before it can be read or written. */ #define BLE_ATT_ERR_INSUFFICIENT_AUTHEN 0x05 + +/** ATT Server does not support the request received from the client. */ #define BLE_ATT_ERR_REQ_NOT_SUPPORTED 0x06 + +/** Offset specified was past the end of the attribute. */ #define BLE_ATT_ERR_INVALID_OFFSET 0x07 + +/** The attribute requires authorization before it can be read or written. */ #define BLE_ATT_ERR_INSUFFICIENT_AUTHOR 0x08 + +/** Too many prepare writes have been queued. */ #define BLE_ATT_ERR_PREPARE_QUEUE_FULL 0x09 + +/** No attribute found within the given attribute handle range. */ #define BLE_ATT_ERR_ATTR_NOT_FOUND 0x0a + +/** The attribute cannot be read using the ATT_READ_BLOB_REQ PDU. */ #define BLE_ATT_ERR_ATTR_NOT_LONG 0x0b + +/** The Encryption Key Size used for encrypting this link is too short. */ #define BLE_ATT_ERR_INSUFFICIENT_KEY_SZ 0x0c + +/** The attribute value length is invalid for the operation. */ #define BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN 0x0d + +/** The attribute request that was requested has encountered an error that was unlikely, + * and therefore could not be completed as requested. */ #define BLE_ATT_ERR_UNLIKELY 0x0e + +/** The attribute requires encryption before it can be read or written */ #define BLE_ATT_ERR_INSUFFICIENT_ENC 0x0f + +/** The attribute type is not a supported grouping attribute as defined by a higher layer specification. */ #define BLE_ATT_ERR_UNSUPPORTED_GROUP 0x10 + +/**Insufficient Resources to complete the request. */ #define BLE_ATT_ERR_INSUFFICIENT_RES 0x11 +/** @} */ + +/** + * @defgroup ble_att_op_codes Attribute Protocol (ATT) Operation Codes + * @{ + */ + +/** Error Response. */ #define BLE_ATT_OP_ERROR_RSP 0x01 + +/** MTU Request. */ #define BLE_ATT_OP_MTU_REQ 0x02 + +/** MTU Response. */ #define BLE_ATT_OP_MTU_RSP 0x03 + +/** Find Information Request. */ #define BLE_ATT_OP_FIND_INFO_REQ 0x04 + +/** Find Information Response. */ #define BLE_ATT_OP_FIND_INFO_RSP 0x05 + +/** Find By Type Value Request. */ #define BLE_ATT_OP_FIND_TYPE_VALUE_REQ 0x06 + +/** Find By Type Value Response. */ #define BLE_ATT_OP_FIND_TYPE_VALUE_RSP 0x07 + +/** Read By Type Request. */ #define BLE_ATT_OP_READ_TYPE_REQ 0x08 + +/** Read By Type Response. */ #define BLE_ATT_OP_READ_TYPE_RSP 0x09 + +/** Read Request. */ #define BLE_ATT_OP_READ_REQ 0x0a + +/** Read Response. */ #define BLE_ATT_OP_READ_RSP 0x0b + +/** Read Blob Request. */ #define BLE_ATT_OP_READ_BLOB_REQ 0x0c + +/** Read Blob Response. */ #define BLE_ATT_OP_READ_BLOB_RSP 0x0d + +/** Read Multiple Request. */ #define BLE_ATT_OP_READ_MULT_REQ 0x0e + +/** Read Multiple Response. */ #define BLE_ATT_OP_READ_MULT_RSP 0x0f + +/** Read By Group Type Request. */ #define BLE_ATT_OP_READ_GROUP_TYPE_REQ 0x10 + +/** Read By Group Type Response. */ #define BLE_ATT_OP_READ_GROUP_TYPE_RSP 0x11 + +/** Write Request. */ #define BLE_ATT_OP_WRITE_REQ 0x12 + +/** Write Response. */ #define BLE_ATT_OP_WRITE_RSP 0x13 + +/** Prepare Write Request. */ #define BLE_ATT_OP_PREP_WRITE_REQ 0x16 + +/** Prepare Write Response. */ #define BLE_ATT_OP_PREP_WRITE_RSP 0x17 + +/** Execute Write Request. */ #define BLE_ATT_OP_EXEC_WRITE_REQ 0x18 + +/** Execute Write Response. */ #define BLE_ATT_OP_EXEC_WRITE_RSP 0x19 + +/** Notify Request. */ #define BLE_ATT_OP_NOTIFY_REQ 0x1b + +/** Indicate Request. */ #define BLE_ATT_OP_INDICATE_REQ 0x1d + +/** Indicate Response. */ #define BLE_ATT_OP_INDICATE_RSP 0x1e + +/** Write Command. */ #define BLE_ATT_OP_WRITE_CMD 0x52 +/** @} */ + +/** Maximum length of an Attribute Protocol (ATT) attribute. */ #define BLE_ATT_ATTR_MAX_LEN 512 +/** + * @defgroup ble_att_flags Attribute Protocol (ATT) Flags + * @{ + */ + +/** Read permission flag. */ #define BLE_ATT_F_READ 0x01 + +/** Write permission flag. */ #define BLE_ATT_F_WRITE 0x02 + +/** Read encrypted permission flag. */ #define BLE_ATT_F_READ_ENC 0x04 + +/** Read authenticated permission flag. */ #define BLE_ATT_F_READ_AUTHEN 0x08 + +/** Read authorized permission flag. */ #define BLE_ATT_F_READ_AUTHOR 0x10 + +/** Write encrypted permission flag. */ #define BLE_ATT_F_WRITE_ENC 0x20 + +/** Write authenticated permission flag. */ #define BLE_ATT_F_WRITE_AUTHEN 0x40 + +/** Write authorized permission flag. */ #define BLE_ATT_F_WRITE_AUTHOR 0x80 +/** Read and write permission flag. */ #define HA_FLAG_PERM_RW (BLE_ATT_F_READ | BLE_ATT_F_WRITE) +/** @} */ + +/** + * @defgroup ble_att_access_op_codes Attribute Protocol (ATT) Access Operation Codes + * @{ + */ + +/** Access operation: Read. */ #define BLE_ATT_ACCESS_OP_READ 1 + +/** Access operation: Write. */ #define BLE_ATT_ACCESS_OP_WRITE 2 +/** @} */ + /** Default ATT MTU. Also the minimum. */ #define BLE_ATT_MTU_DFLT 23 From 3bd6e5b15b00c6d32badab20526a8cbb24997667 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 10 Jul 2023 15:21:22 +0200 Subject: [PATCH 0737/1333] apps: Add DTM shell application This application provides shell interface for Bluetooth DTM. It also provides few extra commands useful for testing (TX power configuration, antenna selection, unmodulated carrier). --- apps/dtm/pkg.yml | 33 +++ apps/dtm/src/main.c | 425 ++++++++++++++++++++++++++++++++++ apps/dtm/src/parse.c | 529 +++++++++++++++++++++++++++++++++++++++++++ apps/dtm/src/parse.h | 58 +++++ apps/dtm/syscfg.yml | 28 +++ 5 files changed, 1073 insertions(+) create mode 100644 apps/dtm/pkg.yml create mode 100644 apps/dtm/src/main.c create mode 100644 apps/dtm/src/parse.c create mode 100644 apps/dtm/src/parse.h create mode 100644 apps/dtm/syscfg.yml diff --git a/apps/dtm/pkg.yml b/apps/dtm/pkg.yml new file mode 100644 index 0000000000..2204befc41 --- /dev/null +++ b/apps/dtm/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: apps/dtm +pkg.type: app +pkg.description: "Bluetooth DTM shell application" +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - "@apache-mynewt-core/sys/log" + - "@apache-mynewt-core/sys/stats" + - "@apache-mynewt-core/sys/shell" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/kernel/os" + - "@apache-mynewt-nimble/nimble/host" + - "@apache-mynewt-mcumgr/cmd/img_mgmt" + - "@mcuboot/boot/bootutil" diff --git a/apps/dtm/src/main.c b/apps/dtm/src/main.c new file mode 100644 index 0000000000..e5e0689c80 --- /dev/null +++ b/apps/dtm/src/main.c @@ -0,0 +1,425 @@ +/* + * 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. + */ + +#include "os/mynewt.h" +#include +#include +#include +#include "nimble/ble.h" +#include "nimble/nimble_opt.h" +#include "host/ble_hs.h" +#include "host/ble_dtm.h" +#include +#include + +static const struct kv_pair phy_opts[] = { + { "1M", 0x01 }, + { "2M", 0x02 }, + { "coded", 0x03 }, + { NULL } +}; + +static const struct kv_pair modulation_index_opts[] = { + { "standard", 0x00 }, + { "stable", 0x01 }, + { NULL } +}; + +static int +cmd_rx_test(int argc, char **argv) +{ + struct ble_dtm_rx_params params; + int rc; + + rc = parse_arg_all(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + params.channel = parse_arg_uint8("channel", &rc); + if ((rc != 0) || (params.channel > 39)) { + console_printf("invalid channel\n"); + return rc; + } + + params.phy = parse_arg_kv_dflt("phy", phy_opts, 0x01, &rc); + if (rc != 0) { + console_printf("invalid 'phy' parameter\n"); + return rc; + } + + params.modulation_index = parse_arg_kv_dflt("modulation_index", + modulation_index_opts, 0x00, &rc); + if (rc != 0) { + console_printf("invalid 'modulation_index' parameter\n"); + return rc; + } + + rc = ble_dtm_rx_start(¶ms); + if (rc) { + console_printf("failed to start RX test\n"); + return rc; + } + + console_printf("RX test started\n"); + return 0; +} + +static int +cmd_tx_test(int argc, char **argv) +{ + struct ble_dtm_tx_params params; + int rc; + + rc = parse_arg_all(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + params.channel = parse_arg_uint8("channel", &rc); + if ((rc != 0) || (params.channel > 39)) { + console_printf("invalid channel\n"); + return rc; + } + + params.phy = parse_arg_kv_dflt("phy", phy_opts, 0x01, &rc); + if (rc != 0) { + console_printf("invalid 'phy' parameter\n"); + return rc; + } + + params.payload = parse_arg_uint8("payload", &rc); + if ((rc != 0) || ((params.payload > 7))) { + console_printf("invalid 'payload' parameter\n"); + return rc; + } + + params.test_data_len = parse_arg_uint8_dflt("data_length", 0, &rc); + if (rc != 0) { + console_printf("invalid 'data_length' parameter\n"); + return rc; + } + + rc = ble_dtm_tx_start(¶ms); + if (rc) { + console_printf("failed to start TX test\n"); + return rc; + } + + console_printf("TX test started\n"); + return 0; +} + +static int +cmd_stop_test(int argc, char **argv) +{ + uint16_t num_packets; + int rc; + + rc = parse_arg_all(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + rc = ble_dtm_stop(&num_packets); + if (rc) { + console_printf("failed to stop test\n"); + return rc; + } + + console_printf("Test stopped (%u packets)\n", num_packets); + return 0; +} + +static int +cmd_tx_power(int argc, char **argv) +{ + struct ble_hci_vs_set_tx_pwr_cp cmd; + struct ble_hci_vs_set_tx_pwr_rp rsp; + int rc; + + rc = parse_arg_all(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + cmd.tx_power = parse_arg_long_bounds_dflt("power", + -127, 127, 127, &rc); + if (rc != 0) { + console_printf("invalid 'power' parameter\n"); + return rc; + } + + rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_SET_TX_PWR, &cmd, sizeof(cmd), + &rsp, sizeof(rsp)); + if (rc) { + console_printf("failed to set TX power\n"); + return rc; + } + + console_printf("TX power set to %d dBm\n", rsp.tx_power); + return 0; +} + +static int +cmd_set_antenna(int argc, char **argv) +{ + struct ble_hci_vs_set_antenna_cp cmd; + int rc; + + rc = parse_arg_all(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + cmd.antenna = parse_arg_uint8_dflt("antenna", 0, &rc); + if (rc != 0 || ((cmd.antenna > 2))) { + console_printf("invalid 'antenna' parameter\n"); + return rc; + } + + rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_SET_ANTENNA, &cmd, sizeof(cmd), + NULL, 0); + if (rc) { + console_printf("failed to set antenna\n"); + return rc; + } + + console_printf("Antenna set to %u\n", cmd.antenna); + return 0; +} + +#define BLE_HCI_OCF_VS_TEST_CARRIER (0x0020) + +static bool tx_carrier_running = false; + +static int +cmd_tx_carrier(int argc, char **argv) +{ + uint8_t cmd[2]; + int rc; + + rc = parse_arg_all(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + if (tx_carrier_running) { + console_printf("TX carrier already started\n"); + return 0; + } + + cmd[0] = 1; + cmd[1] = parse_arg_uint8("channel", &rc); + if ((rc != 0) || (cmd[1] > 39)) { + console_printf("invalid channel\n"); + return rc; + } + + rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_TEST_CARRIER, &cmd, sizeof(cmd), + NULL, 0); + if (rc) { + console_printf("failed to start TX carrier\n"); + return rc; + } + + console_printf("TX carrier started\n"); + tx_carrier_running = true; + return 0; +} + +static int +cmd_stop_carrier(int argc, char **argv) +{ + uint8_t cmd[2]; + int rc; + + rc = parse_arg_all(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + if (!tx_carrier_running) { + console_printf("TX carrier not started\n"); + return 0; + } + cmd[0] = 0; + cmd[1] = 0; + + rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_TEST_CARRIER, &cmd, sizeof(cmd), + NULL, 0); + if (rc) { + console_printf("failed to stop TX carrier\n"); + return rc; + } + + console_printf("TX carrier stopped\n"); + tx_carrier_running = false; + return 0; +} + +static const struct shell_param cmd_rx_test_params[] = { + {"channel", "RX channel, usage: =[0-39]"}, + {"phy", "usage: =[1M|2M], default: 1M"}, + {"modulation_index", "usage: =[standard|stable], default=standard"}, + {NULL} +}; + +static const struct shell_cmd_help cmd_rx_test_help = { + .summary = "start DTM RX test", + .usage = NULL, + .params = cmd_rx_test_params, +}; + +static const struct shell_param cmd_tx_test_params[] = { + {"channel", "RX channel, usage: =[0-39]"}, + {"phy", "usage: =[1M|2M], default: 1M"}, + {"data_length", "usage: =[0-255], default: 0"}, + {"payload", "usage: =[0-7]"}, + {NULL} +}; + +static const struct shell_cmd_help cmd_tx_test_help = { + .summary = "start DTM TX test", + .usage = NULL, + .params = cmd_tx_test_params, +}; + +static const struct shell_cmd_help cmd_stop_test_help = { + .summary = "stop DTM test", + .usage = NULL, + .params = NULL, +}; + +static const struct shell_param cmd_tx_power_params[] = { + {"power", "usage: =[-127-127], default: 127"}, + {NULL} +}; + +static const struct shell_cmd_help cmd_tx_power_help = { + .summary = "set TX power", + .usage = NULL, + .params = cmd_tx_power_params, +}; + +static const struct shell_param cmd_set_antenna_params[] = { + {"antenna", "usage: =[0,1,2], default: 0"}, + {NULL} +}; + +static const struct shell_cmd_help cmd_set_antenna_help = { + .summary = "set active antenna ", + .usage = NULL, + .params = cmd_set_antenna_params, +}; + +static const struct shell_param cmd_tx_carrier_params[] = { + {"channel", "TX channel, usage: =[0-39]"}, + {NULL} +}; + +static const struct shell_cmd_help cmd_tx_carrier_help = { + .summary = "TX unmodulated carrier", + .usage = NULL, + .params = cmd_tx_carrier_params, +}; + +static const struct shell_cmd_help cmd_stop_carrier_help = { + .summary = "stop TX unmodulated carrier", + .usage = NULL, + .params = NULL, +}; + +static const struct shell_cmd dtm_commands[] = { + { + .sc_cmd = "rx-test", + .sc_cmd_func = cmd_rx_test, + .help = &cmd_rx_test_help, + }, + { + .sc_cmd = "tx-test", + .sc_cmd_func = cmd_tx_test, + .help = &cmd_tx_test_help, + }, + { + .sc_cmd = "stop-test", + .sc_cmd_func = cmd_stop_test, + .help = &cmd_stop_test_help, + }, + { + .sc_cmd = "tx-power", + .sc_cmd_func = cmd_tx_power, + .help = &cmd_tx_power_help, + }, + { + .sc_cmd = "set-antenna", + .sc_cmd_func = cmd_set_antenna, + .help = &cmd_set_antenna_help, + }, + { + .sc_cmd = "tx-carrier", + .sc_cmd_func = cmd_tx_carrier, + .help = &cmd_tx_carrier_help, + }, + { + .sc_cmd = "stop-carrier", + .sc_cmd_func = cmd_stop_carrier, + .help = &cmd_stop_carrier_help, + }, + { } +}; + +static void +on_sync(void) +{ + console_printf("Host and controller synced\n"); +} + +static void +on_reset(int reason) +{ + console_printf("Error: Resetting state; reason=%d\n", reason); +} + +int +main(void) +{ + struct image_version the_version; + char prompt[50]; + + sysinit(); + + img_mgmt_read_info(0, &the_version, NULL, NULL); + + snprintf(prompt, sizeof(prompt), "dtm_%u.%u.%u", + the_version.iv_major, the_version.iv_minor, the_version.iv_revision); + + /* Initialize the NimBLE host configuration. */ + ble_hs_cfg.reset_cb = on_reset; + ble_hs_cfg.sync_cb = on_sync; + + shell_register(prompt, dtm_commands); + shell_register_default_module(prompt); + + while (1) { + os_eventq_run(os_eventq_dflt_get()); + } + + return 0; +} diff --git a/apps/dtm/src/parse.c b/apps/dtm/src/parse.c new file mode 100644 index 0000000000..ed79d74042 --- /dev/null +++ b/apps/dtm/src/parse.c @@ -0,0 +1,529 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "console/console.h" + +#define CMD_MAX_ARGS 16 + +static char *cmd_args[CMD_MAX_ARGS][2]; +static int cmd_num_args; + +int +parse_arg_find_idx(const char *key) +{ + int i; + + for (i = 0; i < cmd_num_args; i++) { + if (strcmp(cmd_args[i][0], key) == 0) { + return i; + } + } + + return -1; +} + +char * +parse_arg_peek(const char *key) +{ + int i; + + for (i = 0; i < cmd_num_args; i++) { + if (strcmp(cmd_args[i][0], key) == 0) { + return cmd_args[i][1]; + } + } + + return NULL; +} + +char * +parse_arg_extract(const char *key) +{ + int i; + + for (i = 0; i < cmd_num_args; i++) { + if (strcmp(cmd_args[i][0], key) == 0) { + /* Erase parameter. */ + cmd_args[i][0][0] = '\0'; + + return cmd_args[i][1]; + } + } + + return NULL; +} + +/** + * Determines which number base to use when parsing the specified numeric + * string. This just avoids base '0' so that numbers don't get interpreted as + * octal. + */ +static int +parse_arg_long_base(char *sval) +{ + if (sval[0] == '0' && sval[1] == 'x') { + return 0; + } else { + return 10; + } +} + +long +parse_long_bounds(char *sval, long min, long max, int *out_status) +{ + char *endptr; + long lval; + + lval = strtol(sval, &endptr, parse_arg_long_base(sval)); + if (sval[0] != '\0' && *endptr == '\0' && + lval >= min && lval <= max) { + + *out_status = 0; + return lval; + } + + *out_status = EINVAL; + return 0; +} + +long +parse_arg_long_bounds_peek(char *name, long min, long max, int *out_status) +{ + char *sval; + + sval = parse_arg_peek(name); + if (sval == NULL) { + *out_status = ENOENT; + return 0; + } + return parse_long_bounds(sval, min, max, out_status); +} + +long +parse_arg_long_bounds(char *name, long min, long max, int *out_status) +{ + char *sval; + + sval = parse_arg_extract(name); + if (sval == NULL) { + *out_status = ENOENT; + return 0; + } + return parse_long_bounds(sval, min, max, out_status); +} + +long +parse_arg_long_bounds_dflt(char *name, long min, long max, + long dflt, int *out_status) +{ + long val; + int rc; + + val = parse_arg_long_bounds(name, min, max, &rc); + if (rc == ENOENT) { + rc = 0; + val = dflt; + } + + *out_status = rc; + + return val; +} + +uint64_t +parse_arg_uint64_bounds(char *name, uint64_t min, uint64_t max, int *out_status) +{ + char *endptr; + char *sval; + uint64_t lval; + + sval = parse_arg_extract(name); + if (sval == NULL) { + *out_status = ENOENT; + return 0; + } + + lval = strtoull(sval, &endptr, parse_arg_long_base(sval)); + if (sval[0] != '\0' && *endptr == '\0' && + lval >= min && lval <= max) { + + *out_status = 0; + return lval; + } + + *out_status = EINVAL; + return 0; +} + +long +parse_arg_long(char *name, int *out_status) +{ + return parse_arg_long_bounds(name, LONG_MIN, LONG_MAX, out_status); +} + +uint8_t +parse_arg_bool(char *name, int *out_status) +{ + return parse_arg_long_bounds(name, 0, 1, out_status); +} + +uint8_t +parse_arg_bool_dflt(char *name, uint8_t dflt, int *out_status) +{ + return parse_arg_long_bounds_dflt(name, 0, 1, dflt, out_status); +} + +uint8_t +parse_arg_uint8(char *name, int *out_status) +{ + return parse_arg_long_bounds(name, 0, UINT8_MAX, out_status); +} + +uint16_t +parse_arg_uint16(char *name, int *out_status) +{ + return parse_arg_long_bounds(name, 0, UINT16_MAX, out_status); +} + +uint16_t +parse_arg_uint16_peek(char *name, int *out_status) +{ + return parse_arg_long_bounds_peek(name, 0, UINT16_MAX, out_status); +} + +uint32_t +parse_arg_uint32(char *name, int *out_status) +{ + return parse_arg_uint64_bounds(name, 0, UINT32_MAX, out_status); +} + +uint64_t +parse_arg_uint64(char *name, int *out_status) +{ + return parse_arg_uint64_bounds(name, 0, UINT64_MAX, out_status); +} + +uint8_t +parse_arg_uint8_dflt(char *name, uint8_t dflt, int *out_status) +{ + uint8_t val; + int rc; + + val = parse_arg_uint8(name, &rc); + if (rc == ENOENT) { + val = dflt; + rc = 0; + } + + *out_status = rc; + return val; +} + +uint16_t +parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status) +{ + uint16_t val; + int rc; + + val = parse_arg_uint16(name, &rc); + if (rc == ENOENT) { + val = dflt; + rc = 0; + } + + *out_status = rc; + return val; +} + +uint32_t +parse_arg_uint32_dflt(char *name, uint32_t dflt, int *out_status) +{ + uint32_t val; + int rc; + + val = parse_arg_uint32(name, &rc); + if (rc == ENOENT) { + val = dflt; + rc = 0; + } + + *out_status = rc; + return val; +} + +static uint32_t +parse_time_unit_mult(const char *str) +{ + if (!strcasecmp(str, "us")) { + return 1; + } else if (!strcasecmp(str, "ms")) { + return 1000; + } else if (!strcasecmp(str, "s")) { + return 1000000; + } + + return 0; +} + +static uint32_t +parse_time_us(const char *str, int *out_status) +{ + uint32_t val = 0; + uint32_t val_div = 1; + uint32_t val_mult = 1; + uint32_t val_us; + + while (isdigit((unsigned char)*str)) { + val *= 10; + val += *str - '0'; + str++; + } + + if (*str == '.') { + str++; + while (isdigit((unsigned char)*str)) { + val *= 10; + val += *str - '0'; + val_div *= 10; + str++; + } + } + + val_mult = parse_time_unit_mult(str); + if (val_mult == 0) { + *out_status = EINVAL; + return 0; + } + + if (val_mult > val_div) { + val_us = val * (val_mult / val_div); + } else { + val_us = val * (val_div / val_mult); + } + + *out_status = 0; + + return val_us; +} + +uint32_t +parse_arg_time_dflt(char *name, int step_us, uint32_t dflt, int *out_status) +{ + const char *arg; + uint32_t val; + int rc; + + arg = parse_arg_peek(name); + if (!arg) { + *out_status = 0; + return dflt; + } + + val = parse_time_us(arg, &rc); + if (rc) { + val = parse_arg_uint32(name, &rc); + if (rc == ENOENT) { + *out_status = 0; + return dflt; + } + } else { + val /= step_us; + parse_arg_extract(name); + } + + *out_status = rc; + return val; +} + +const struct kv_pair * +parse_kv_find(const struct kv_pair *kvs, char *name) +{ + const struct kv_pair *kv; + int i; + + for (i = 0; kvs[i].key != NULL; i++) { + kv = kvs + i; + if (strcmp(name, kv->key) == 0) { + return kv; + } + } + + return NULL; +} + +int +parse_arg_kv(char *name, const struct kv_pair *kvs, int *out_status) +{ + const struct kv_pair *kv; + char *sval; + + sval = parse_arg_extract(name); + if (sval == NULL) { + *out_status = ENOENT; + return -1; + } + + kv = parse_kv_find(kvs, sval); + if (kv == NULL) { + *out_status = EINVAL; + return -1; + } + + *out_status = 0; + return kv->val; +} + +int +parse_arg_kv_dflt(char *name, const struct kv_pair *kvs, int def_val, + int *out_status) +{ + int val; + int rc; + + val = parse_arg_kv(name, kvs, &rc); + if (rc == ENOENT) { + rc = 0; + val = def_val; + } + + *out_status = rc; + + return val; +} + + +static int +parse_arg_byte_stream_delim(char *sval, char *delims, int max_len, + uint8_t *dst, int *out_len) +{ + unsigned long ul; + char *endptr; + char *token; + int i; + char *tok_ptr; + + i = 0; + for (token = strtok_r(sval, delims, &tok_ptr); + token != NULL; + token = strtok_r(NULL, delims, &tok_ptr)) { + + if (i >= max_len) { + return EINVAL; + } + + ul = strtoul(token, &endptr, 16); + if (sval[0] == '\0' || *endptr != '\0' || ul > UINT8_MAX) { + return -1; + } + + dst[i] = ul; + i++; + } + + *out_len = i; + + return 0; +} + +int +parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len) +{ + char *sval; + + sval = parse_arg_extract(name); + if (sval == NULL) { + return ENOENT; + } + + return parse_arg_byte_stream_delim(sval, ":-", max_len, dst, out_len); +} + +int +parse_arg_uint8_list_with_separator(char *name, char *separator, int max_len, + uint8_t *dst, int *out_len) +{ + char *sval; + + sval = parse_arg_extract(name); + if (sval == NULL) { + return ENOENT; + } + + return parse_arg_byte_stream_delim(sval, separator, max_len, dst, out_len); +} + +int +parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len) +{ + int actual_len; + int rc; + + rc = parse_arg_byte_stream(name, len, dst, &actual_len); + if (rc != 0) { + return rc; + } + + if (actual_len != len) { + return EINVAL; + } + + return 0; +} + +int +parse_arg_all(int argc, char **argv) +{ + char *key; + char *val; + int i; + char *tok_ptr; + + cmd_num_args = 0; + + for (i = 0; i < argc; i++) { + key = strtok_r(argv[i], "=", &tok_ptr); + val = strtok_r(NULL, "=", &tok_ptr); + + if (key != NULL && val != NULL) { + if (strlen(key) == 0) { + console_printf("Error: invalid argument: %s\n", argv[i]); + return -1; + } + + if (cmd_num_args >= CMD_MAX_ARGS) { + console_printf("Error: too many arguments"); + return -1; + } + + cmd_args[cmd_num_args][0] = key; + cmd_args[cmd_num_args][1] = val; + cmd_num_args++; + } + } + + return 0; +} diff --git a/apps/dtm/src/parse.h b/apps/dtm/src/parse.h new file mode 100644 index 0000000000..a0255d368f --- /dev/null +++ b/apps/dtm/src/parse.h @@ -0,0 +1,58 @@ +/* + * 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 PARSE_H +#define PARSE_H + +#include + +struct kv_pair { + char *key; + int val; +}; + +uint32_t parse_arg_time_dflt(char *name, int step, uint32_t dflt, int *out_status); +const struct kv_pair *parse_kv_find(const struct kv_pair *kvs, char *name); +int parse_arg_find_idx(const char *key); +char *parse_arg_extract(const char *key); +long parse_arg_long_bounds(char *name, long min, long max, int *out_status); +long parse_arg_long_bounds_dflt(char *name, long min, long max, + long dflt, int *out_status); +uint64_t parse_arg_uint64_bounds(char *name, uint64_t min, + uint64_t max, int *out_status); +long parse_arg_long(char *name, int *staus); +uint8_t parse_arg_bool(char *name, int *status); +uint8_t parse_arg_bool_dflt(char *name, uint8_t dflt, int *out_status); +uint8_t parse_arg_uint8(char *name, int *status); +uint8_t parse_arg_uint8_dflt(char *name, uint8_t dflt, int *out_status); +uint16_t parse_arg_uint16(char *name, int *status); +uint16_t parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status); +uint32_t parse_arg_uint32(char *name, int *out_status); +uint32_t parse_arg_uint32_dflt(char *name, uint32_t dflt, int *out_status); +uint64_t parse_arg_uint64(char *name, int *out_status); +int parse_arg_kv(char *name, const struct kv_pair *kvs, int *out_status); +int parse_arg_kv_dflt(char *name, const struct kv_pair *kvs, int def_val, + int *out_status); +int parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len); +int parse_arg_uint8_list_with_separator(char *name, char *separator, int max_len, + uint8_t *dst, int *out_len); +int parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len); +int parse_arg_all(int argc, char **argv); + +#endif diff --git a/apps/dtm/syscfg.yml b/apps/dtm/syscfg.yml new file mode 100644 index 0000000000..b88c387a11 --- /dev/null +++ b/apps/dtm/syscfg.yml @@ -0,0 +1,28 @@ +# 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. + +syscfg.vals: + # Enable the shell task. + SHELL_TASK: 1 + SHELL_CMD_HELP: 1 + CONSOLE_HISTORY: ram + CONSOLE_HISTORY_RAM_HISTORY_SIZE: 50 + + BLE_LL_DTM: 1 + BLE_LL_DTM_EXTENSIONS: 1 + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 From 98d972d220a0a49f40dca8074418397d5323d1ec Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 10 Jul 2023 17:07:52 +0200 Subject: [PATCH 0738/1333] ci: Add DTM application target Adds target for building DTM application. --- .github/targets/nordic_pca10056_dtm/pkg.yml | 25 +++++++++++++++++++ .../targets/nordic_pca10056_dtm/target.yml | 23 +++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 .github/targets/nordic_pca10056_dtm/pkg.yml create mode 100644 .github/targets/nordic_pca10056_dtm/target.yml diff --git a/.github/targets/nordic_pca10056_dtm/pkg.yml b/.github/targets/nordic_pca10056_dtm/pkg.yml new file mode 100644 index 0000000000..9cbab32434 --- /dev/null +++ b/.github/targets/nordic_pca10056_dtm/pkg.yml @@ -0,0 +1,25 @@ +# +# 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. +# + +### Package: "targets_ci/nordic_pca10056_dtm +pkg.name: "targets_ci/nordic_pca10056_dtm" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: diff --git a/.github/targets/nordic_pca10056_dtm/target.yml b/.github/targets/nordic_pca10056_dtm/target.yml new file mode 100644 index 0000000000..8c6b21a736 --- /dev/null +++ b/.github/targets/nordic_pca10056_dtm/target.yml @@ -0,0 +1,23 @@ +# +# 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. +# + +### Target: targets/nordic_pca10056_dtm +target.app: "@apache-mynewt-nimble/apps/dtm" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "debug" From 37697bbc7409c74e8973c44db9d01cd086900ee2 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Mon, 17 Jul 2023 16:51:30 +0200 Subject: [PATCH 0739/1333] host/uuid: add doxygen comments for the header file Adds missing macros and structures documentation. --- nimble/host/include/host/ble_uuid.h | 85 +++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/nimble/host/include/host/ble_uuid.h b/nimble/host/include/host/ble_uuid.h index cc368368c6..a63104b4c1 100644 --- a/nimble/host/include/host/ble_uuid.h +++ b/nimble/host/include/host/ble_uuid.h @@ -56,30 +56,55 @@ typedef struct { /** 16-bit UUID */ typedef struct { + /** Generic UUID structure */ ble_uuid_t u; + + /** 16-bit UUID value */ uint16_t value; } ble_uuid16_t; /** 32-bit UUID */ typedef struct { + /** Generic UUID structure */ ble_uuid_t u; + + /** 32-bit UUID value */ uint32_t value; } ble_uuid32_t; /** 128-bit UUID */ typedef struct { + /** Generic UUID structure */ ble_uuid_t u; + + /** 128-bit UUID value */ uint8_t value[16]; } ble_uuid128_t; /** Universal UUID type, to be used for any-UUID static allocation */ typedef union { + /** Generic UUID structure */ ble_uuid_t u; + + /** 16-bit UUID structure */ ble_uuid16_t u16; + + /** 32-bit UUID structure */ ble_uuid32_t u32; + + /** 128-bit UUID structure */ ble_uuid128_t u128; } ble_uuid_any_t; +/** + * @brief Macro for initializing a 16-bit UUID. + * + * This macro initializes a 16-bit UUID with the provided value. + * + * @param uuid16 The value of the 16-bit UUID. + * + * @return The initialized 16-bit UUID structure. + */ #define BLE_UUID16_INIT(uuid16) \ { \ .u = { \ @@ -88,6 +113,15 @@ typedef union { .value = (uuid16), \ } +/** + * @brief Macro for initializing a 32-bit UUID. + * + * This macro initializes a 32-bit UUID with the provided value. + * + * @param uuid32 The value of the 32-bit UUID. + * + * @return The initialized 32-bit UUID structure. + */ #define BLE_UUID32_INIT(uuid32) \ { \ .u = { \ @@ -96,6 +130,15 @@ typedef union { .value = (uuid32), \ } +/** + * @brief Macro for initializing a 128-bit UUID. + * + * This macro initializes a 128-bit UUID with the provided value. + * + * @param uuid128 The value of the 128-bit UUID. + * + * @return The initialized 128-bit UUID structure. + */ #define BLE_UUID128_INIT(uuid128 ...) \ { \ .u = { \ @@ -104,21 +147,63 @@ typedef union { .value = { uuid128 }, \ } +/** + * @brief Macro for declaring a pointer to a 16-bit UUID structure initialized with a specific 16-bit UUID value. + * + * @param uuid16 The 16-bit UUID value to initialize the structure with. + * + * @return Pointer to a `ble_uuid_t` structure. + */ #define BLE_UUID16_DECLARE(uuid16) \ ((ble_uuid_t *) (&(ble_uuid16_t) BLE_UUID16_INIT(uuid16))) +/** + * @brief Macro for declaring a pointer to a 32-bit UUID structure initialized with a specific 32-bit UUID value. + * + * @param uuid32 The 32-bit UUID value to initialize the structure with. + * + * @return Pointer to a `ble_uuid_t` structure. + */ #define BLE_UUID32_DECLARE(uuid32) \ ((ble_uuid_t *) (&(ble_uuid32_t) BLE_UUID32_INIT(uuid32))) +/** + * @brief Macro for declaring a pointer to a 128-bit UUID structure initialized with specific 128-bit UUID values. + * + * @param uuid128 The 128-bit UUID value to initialize the structure with. + * + * @return Pointer to a `ble_uuid_t` structure. + */ #define BLE_UUID128_DECLARE(uuid128...) \ ((ble_uuid_t *) (&(ble_uuid128_t) BLE_UUID128_INIT(uuid128))) +/** + * @brief Macro for casting a pointer to a `ble_uuid_t` structure to a pointer to 16-bit UUID structure. + * + * @param u Pointer to a `ble_uuid_t` structure. + * + * @return Pointer to a `ble_uuid16_t` structure. + */ #define BLE_UUID16(u) \ ((ble_uuid16_t *) (u)) +/** + * @brief Macro for casting a pointer to a `ble_uuid_t` structure to a pointer to 32-bit UUID structure. + * + * @param u Pointer to a `ble_uuid_t` structure. + * + * @return Pointer to a `ble_uuid32_t` structure. + */ #define BLE_UUID32(u) \ ((ble_uuid32_t *) (u)) +/** + * @brief Macro for casting a pointer to a `ble_uuid_t` structure to a pointer to 128-bit UUID structure. + * + * @param u Pointer to a `ble_uuid_t` structure. + * + * @return Pointer to a `ble_uuid128_t` structure. + */ #define BLE_UUID128(u) \ ((ble_uuid128_t *) (u)) From 28649933ad4f885754313f59dcf75a4a26febd2a Mon Sep 17 00:00:00 2001 From: Mingjie Shen Date: Tue, 18 Jul 2023 21:55:35 -0400 Subject: [PATCH 0740/1333] porting/examples: Fix implicit function declaration --- porting/examples/linux/main.c | 1 + porting/examples/linux_blemesh/main.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/porting/examples/linux/main.c b/porting/examples/linux/main.c index a2e255d083..25323b9a0f 100644 --- a/porting/examples/linux/main.c +++ b/porting/examples/linux/main.c @@ -39,6 +39,7 @@ void nimble_host_task(void *param); void ble_hci_sock_ack_handler(void *param); void ble_hci_sock_init(void); void ble_hci_sock_set_device(int dev); +void ble_store_ram_init(void); #define TASK_DEFAULT_PRIORITY 1 #define TASK_DEFAULT_STACK NULL diff --git a/porting/examples/linux_blemesh/main.c b/porting/examples/linux_blemesh/main.c index f5c5e4f04f..5a9befdc10 100644 --- a/porting/examples/linux_blemesh/main.c +++ b/porting/examples/linux_blemesh/main.c @@ -38,6 +38,8 @@ static struct ble_npl_task s_task_mesh_adv; void nimble_host_task(void *param); void ble_hci_sock_ack_handler(void *param); void ble_hci_sock_init(void); +void ble_hci_sock_set_device(int dev); +void ble_store_ram_init(void); #define TASK_DEFAULT_PRIORITY 1 #define TASK_DEFAULT_STACK NULL From cc556e97f4dc1da30ee7274f2b08e4e2a47535cf Mon Sep 17 00:00:00 2001 From: Mingjie Shen Date: Tue, 18 Jul 2023 21:40:14 -0400 Subject: [PATCH 0741/1333] porting: Add missing return statement --- porting/npl/dummy/src/npl_os_dummy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/porting/npl/dummy/src/npl_os_dummy.c b/porting/npl/dummy/src/npl_os_dummy.c index a522531fa3..059e1a689a 100644 --- a/porting/npl/dummy/src/npl_os_dummy.c +++ b/porting/npl/dummy/src/npl_os_dummy.c @@ -41,6 +41,7 @@ ble_npl_eventq_init(struct ble_npl_eventq *evq) struct ble_npl_event * ble_npl_eventq_get(struct ble_npl_eventq *evq, ble_npl_time_t tmo) { + return NULL; } void From b521e22267a6bec76c509a636043163cdc0756c5 Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Mon, 17 Jul 2023 18:51:49 +0400 Subject: [PATCH 0742/1333] nimble/host: fix gcc 13 warnings --- nimble/host/src/ble_att_svr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 26ac14ceb9..8612d36963 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -1725,6 +1725,9 @@ ble_att_svr_build_read_group_type_rsp(uint16_t conn_handle, /* Silence warnings. */ end_group_handle = 0; + start_group_handle = 0; + + entry = NULL; *att_err = 0; *err_handle = start_handle; @@ -1745,7 +1748,6 @@ ble_att_svr_build_read_group_type_rsp(uint16_t conn_handle, goto done; } - start_group_handle = 0; rsp->bagp_length = 0; STAILQ_FOREACH(entry, &ble_att_svr_list, ha_next) { if (entry->ha_handle_id < start_handle) { From dd2083a549340e8469354aae4fc6bd3a2acdc972 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Mon, 26 Jun 2023 12:56:20 +0200 Subject: [PATCH 0743/1333] host/hs_stop: add doxygen comments for the header file Add missing structure members documentation. --- nimble/host/include/host/ble_hs_stop.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/nimble/host/include/host/ble_hs_stop.h b/nimble/host/include/host/ble_hs_stop.h index e4feb62bff..8b3ebd3fb4 100644 --- a/nimble/host/include/host/ble_hs_stop.h +++ b/nimble/host/include/host/ble_hs_stop.h @@ -20,6 +20,13 @@ #ifndef H_BLE_HS_STOP_ #define H_BLE_HS_STOP_ +/** + * @brief Bluetooth Host Stop API + * @defgroup bt_hs_stop Bluetooth Host Stop + * @ingroup bt_host + * @{ + */ + /** @typedef ble_hs_stop_fn * @brief Callback function; reports the result of a host stop procedure. * @@ -38,8 +45,13 @@ typedef void ble_hs_stop_fn(int status, void *arg); * This should be used as an opaque structure and not modified manually. */ struct ble_hs_stop_listener { + /** The callback function to be called when the stop procedure completes. */ ble_hs_stop_fn *fn; + + /** An optional argument to be passed to the callback function. */ void *arg; + + /** Singly-linked list entry. */ SLIST_ENTRY(ble_hs_stop_listener) link; }; @@ -67,4 +79,8 @@ struct ble_hs_stop_listener { int ble_hs_stop(struct ble_hs_stop_listener *listener, ble_hs_stop_fn *fn, void *arg); +/** +* @} +*/ + #endif From ea64b64356fc461ff8e47fc914acd5392679b8f1 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Thu, 6 Jul 2023 18:27:56 +0200 Subject: [PATCH 0744/1333] host/hs_log: add doxygen comments for the header file Add missing macros and functions documentation. --- nimble/host/include/host/ble_hs_log.h | 55 +++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/nimble/host/include/host/ble_hs_log.h b/nimble/host/include/host/ble_hs_log.h index 7b90eaf9f0..a89b1e6629 100644 --- a/nimble/host/include/host/ble_hs_log.h +++ b/nimble/host/include/host/ble_hs_log.h @@ -20,6 +20,19 @@ #ifndef H_BLE_HS_LOG_ #define H_BLE_HS_LOG_ +/** + * @file ble_hs_log.h + * + * @brief Bluetooth Host Log + * + * This header file defines macros and functions used for logging messages + * within the BLE Host Stack. + * + * @defgroup bt_host_log Bluetooth Host Log + * @ingroup bt_host + * @{ + */ + #include "modlog/modlog.h" #include "log/log.h" @@ -34,20 +47,62 @@ extern "C" { struct os_mbuf; +/** + * @brief Macro for logging messages at a specified log level. + * + * The BLE_HS_LOG macro allows logging messages with different severity levels, + * such as DEBUG, INFO, WARN, ERROR or CRITICAL. + * + * @param lvl The log level of the message. + * @param ... The format string and additional arguments for the log message. + */ #define BLE_HS_LOG(lvl, ...) \ BLE_HS_LOG_ ## lvl(__VA_ARGS__) +/** + * @brief Macro for logging a Bluetooth address at a specified log level. + * + * The BLE_HS_LOG_ADDR macro allows logging Bluetooth addresses in the format + * "XX:XX:XX:XX:XX:XX" at different severity levels, such as DEBUG, INFO, WARN, ERROR or CRITICAL. + * + * @param lvl The log level of the message. + * @param addr The Bluetooth address to be logged. + */ #define BLE_HS_LOG_ADDR(lvl, addr) \ BLE_HS_LOG_ ## lvl("%02x:%02x:%02x:%02x:%02x:%02x", \ (addr)[5], (addr)[4], (addr)[3], \ (addr)[2], (addr)[1], (addr)[0]) +/** + * @brief Logs the content of an `os_mbuf` structure. + * + * This function iterates over each byte in the provided `os_mbuf` and logs its + * value in hexadecimal format using the `BLE_HS_LOG` macro with the log level + * set to DEBUG. + * + * @param om The `os_mbuf` to log. + */ void ble_hs_log_mbuf(const struct os_mbuf *om); + +/** + * @brief Logs the content of a flat buffer. + * + * This function iterates over each byte in the provided buffer and logs its + * value in hexadecimal format using the `BLE_HS_LOG` macro with the log level + * set to DEBUG. + * + * @param data Pointer to the buffer to log. + * @param len Length of the buffer. + */ void ble_hs_log_flat_buf(const void *data, int len); #ifdef __cplusplus } #endif +/** + * @} + */ + #endif From 18738b27432688f722eeb4afd2a0d51d5c377644 Mon Sep 17 00:00:00 2001 From: "Deomid \"rojer\" Ryabkov" Date: Wed, 19 Jul 2023 21:45:58 +0100 Subject: [PATCH 0745/1333] if MYNEWT -> ifdef MYNEWT Currently there's a mix of `#if MYNEWT` and `#ifdef MYNEWT` used in the codebase to check if the environment is Mynewt or not. This is incompatible with `-Wundef`, so switch common parts of the code to uniformly use `#ifdef`. --- nimble/controller/src/ble_ll.c | 4 ++-- nimble/host/mesh/src/adv_legacy.c | 4 ++-- nimble/host/src/ble_gap.c | 2 +- nimble/host/src/ble_hs.c | 2 +- nimble/host/src/ble_hs_shutdown.c | 2 +- nimble/transport/socket/src/ble_hci_socket.c | 4 ++-- porting/nimble/include/log/log.h | 2 +- porting/nimble/src/hal_timer.c | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 4ccab7b50a..84475c32b2 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -368,7 +368,7 @@ static void ble_ll_event_tx_pkt(struct ble_npl_event *ev); static void ble_ll_event_dbuf_overflow(struct ble_npl_event *ev); #endif -#if MYNEWT +#ifdef MYNEWT /* The BLE LL task data structure */ struct os_task g_ble_ll_task; @@ -1970,7 +1970,7 @@ ble_ll_init(void) ble_ll_ext_init(); #endif -#if MYNEWT +#ifdef MYNEWT /* Initialize the LL task */ os_task_init(&g_ble_ll_task, "ble_ll", ble_ll_task, NULL, MYNEWT_VAL(BLE_LL_PRIO), OS_WAIT_FOREVER, g_ble_ll_stack, diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index b642e1aaec..26865058e9 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -40,7 +40,7 @@ static int adv_initialized = false; /* TinyCrypt PRNG consumes a lot of stack space, so we need to have * an increased call stack whenever it's used. */ -#if MYNEWT +#ifdef MYNEWT OS_TASK_STACK_DEFINE(g_blemesh_stack, MYNEWT_VAL(BLE_MESH_ADV_STACK_SIZE)); struct os_task adv_task; #endif @@ -214,7 +214,7 @@ void bt_mesh_adv_init(void) ble_npl_eventq_init(&bt_mesh_adv_queue); -#if MYNEWT +#ifdef MYNEWT os_task_init(&adv_task, "mesh_adv", mesh_adv_thread, NULL, MYNEWT_VAL(BLE_MESH_ADV_TASK_PRIO), OS_WAIT_FOREVER, g_blemesh_stack, MYNEWT_VAL(BLE_MESH_ADV_STACK_SIZE)); diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 119e3521db..488613c03c 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -35,7 +35,7 @@ #define max(a, b) ((a) > (b) ? (a) : (b)) #endif -#if MYNEWT +#ifdef MYNEWT #include "bsp/bsp.h" #else #define bssnz_t diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index aa97c6bf05..e130c1ca14 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -120,7 +120,7 @@ ble_hs_evq_set(struct ble_npl_eventq *evq) int ble_hs_locked_by_cur_task(void) { -#if MYNEWT +#ifdef MYNEWT struct os_task *owner; if (!ble_npl_os_started()) { diff --git a/nimble/host/src/ble_hs_shutdown.c b/nimble/host/src/ble_hs_shutdown.c index f29d4a6692..bdd7f727df 100644 --- a/nimble/host/src/ble_hs_shutdown.c +++ b/nimble/host/src/ble_hs_shutdown.c @@ -17,7 +17,7 @@ * under the License. */ -#if MYNEWT +#ifdef MYNEWT #include "os/mynewt.h" #include "ble_hs_priv.h" diff --git a/nimble/transport/socket/src/ble_hci_socket.c b/nimble/transport/socket/src/ble_hci_socket.c index d77baef66d..75a813dba3 100644 --- a/nimble/transport/socket/src/ble_hci_socket.c +++ b/nimble/transport/socket/src/ble_hci_socket.c @@ -146,7 +146,7 @@ STATS_NAME_END(hci_sock_stats) #define BLE_HCI_UART_H4_SKIP_CMD 0x81 #define BLE_HCI_UART_H4_SKIP_ACL 0x82 -#if MYNEWT +#ifdef MYNEWT #define BLE_SOCK_STACK_SIZE \ OS_STACK_ALIGN(MYNEWT_VAL(BLE_SOCK_STACK_SIZE)) @@ -778,7 +778,7 @@ ble_hci_sock_init_task(void) ble_npl_callout_init(&ble_hci_sock_state.timer, &ble_hci_sock_state.evq, ble_hci_sock_rx_ev, NULL); -#if MYNEWT +#ifdef MYNEWT { os_stack_t *pstack; diff --git a/porting/nimble/include/log/log.h b/porting/nimble/include/log/log.h index b50c5b1709..be9237c524 100644 --- a/porting/nimble/include/log/log.h +++ b/porting/nimble/include/log/log.h @@ -30,7 +30,7 @@ log_dummy(void *log, ...) (void)log; } -#if MYNEWT +#ifdef MYNEWT #define LOG_DEBUG(_log, _mod, ...) log_dummy(_log, ## __VA_ARGS__) #define LOG_INFO(_log, _mod, ...) log_dummy(_log, ## __VA_ARGS__) #define LOG_WARN(_log, _mod, ...) log_dummy(_log, ## __VA_ARGS__) diff --git a/porting/nimble/src/hal_timer.c b/porting/nimble/src/hal_timer.c index e649a9070c..21ba8ca77a 100644 --- a/porting/nimble/src/hal_timer.c +++ b/porting/nimble/src/hal_timer.c @@ -541,7 +541,7 @@ hal_timer_init(int timer_num, void *cfg) #ifndef RIOT_VERSION NVIC_SetPriority(irq_num, (1 << __NVIC_PRIO_BITS) - 1); #endif -#if MYNEWT +#ifdef MYNEWT NVIC_SetVector(irq_num, (uint32_t)irq_isr); #else ble_npl_hw_set_isr(irq_num, irq_isr); From 188256f1ef27737b5d6ca13d754f22a1062b2744 Mon Sep 17 00:00:00 2001 From: "Deomid \"rojer\" Ryabkov" Date: Wed, 19 Jul 2023 21:39:23 +0100 Subject: [PATCH 0746/1333] porting/npl/linux: Replace pthread_yield() with sched_yield() Per `pthread_yield(3)`: ``` This call is nonstandard, but present on several other systems. Use the standardized sched_yield(2) instead. ``` --- porting/npl/linux/src/os_task.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/porting/npl/linux/src/os_task.c b/porting/npl/linux/src/os_task.c index fe6c2df11c..b03deb0661 100644 --- a/porting/npl/linux/src/os_task.c +++ b/porting/npl/linux/src/os_task.c @@ -17,6 +17,8 @@ * under the License. */ +#include + #include "os/os.h" #include "nimble/nimble_npl.h" @@ -106,7 +108,7 @@ bool ble_npl_os_started(void) void ble_npl_task_yield(void) { - pthread_yield(); + sched_yield(); } #ifdef __cplusplus From 9bf905ffd589290d782d909a93ba8cd2d4334256 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 20 Jul 2023 15:57:59 +0200 Subject: [PATCH 0747/1333] porting/npl: Fix linux tests makefile clean target clean target was failing if there was incomplete build. --- porting/npl/linux/test/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porting/npl/linux/test/Makefile b/porting/npl/linux/test/Makefile index c0be3d5f80..ac8c24925c 100644 --- a/porting/npl/linux/test/Makefile +++ b/porting/npl/linux/test/Makefile @@ -99,7 +99,7 @@ show_objs: ### ===== Clean ===== clean: @echo "Cleaning artifacts." - rm *~ .depend $(OBJS) *.o *.exe + rm -f .depend $(OBJS) *.o *.exe ### ===== Dependencies ===== ### Rebuild if headers change From fd20c10596d03faf960fe815139b30ef5accc2fd Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 20 Jul 2023 16:38:26 +0200 Subject: [PATCH 0748/1333] porting/npl: Fix linux tests build For now build with -m32 flag. --- porting/npl/linux/test/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/porting/npl/linux/test/Makefile b/porting/npl/linux/test/Makefile index ac8c24925c..cab378d320 100644 --- a/porting/npl/linux/test/Makefile +++ b/porting/npl/linux/test/Makefile @@ -43,11 +43,12 @@ CFLAGS = \ $(INCLUDES) $(DEFINES) \ -g \ -D_GNU_SOURCE \ + -m32 \ $(NULL) LIBS = -lrt -lpthread -lstdc++ -LDFLAGS = +LDFLAGS = -m32 ### ===== Sources ===== From e6e583e52307ef03a6a2e037397c14b9a81fc0c3 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 20 Jul 2023 15:58:37 +0200 Subject: [PATCH 0749/1333] ci: Add linux power NPL test to CI Make sure Linux NPL tests pass. --- .github/workflows/build_ports.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_ports.yml b/.github/workflows/build_ports.yml index 727016d913..70a3349593 100644 --- a/.github/workflows/build_ports.yml +++ b/.github/workflows/build_ports.yml @@ -39,6 +39,7 @@ jobs: make -C porting/examples/dummy/ clean all make -C porting/examples/linux/ clean all make -C porting/examples/linux_blemesh/ clean all + make -C porting/npl/linux/test/ clean all test - name: Build RIOT port if: success() || failure() continue-on-error: true From 064f05091941a5aafd7f5aa9834533c79e988705 Mon Sep 17 00:00:00 2001 From: "Deomid \"rojer\" Ryabkov" Date: Wed, 19 Jul 2023 21:42:24 +0100 Subject: [PATCH 0750/1333] porting/npl/linux: PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP is a GNU extension Need to provide `__USE_GNU` hint to pthread.h --- porting/npl/linux/src/os_atomic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/porting/npl/linux/src/os_atomic.c b/porting/npl/linux/src/os_atomic.c index 3aaec08ada..51260149ce 100644 --- a/porting/npl/linux/src/os_atomic.c +++ b/porting/npl/linux/src/os_atomic.c @@ -18,6 +18,7 @@ */ #include +#define __USE_GNU #include #include "nimble/nimble_npl.h" From ef0fb14f99682da466ede8ddc1e711d7b76ef065 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Fri, 14 Jul 2023 12:01:56 +0200 Subject: [PATCH 0751/1333] native: Change pointer type casting to uintptr_t This is necessary to build native target on 64-bit architecture --- nimble/drivers/native/src/ble_phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/drivers/native/src/ble_phy.c b/nimble/drivers/native/src/ble_phy.c index e27f36e991..4609c2864b 100644 --- a/nimble/drivers/native/src/ble_phy.c +++ b/nimble/drivers/native/src/ble_phy.c @@ -165,7 +165,7 @@ ble_phy_rxpdu_copy(uint8_t *dptr, struct os_mbuf *rxpdu) struct os_mbuf_pkthdr *pkthdr; /* Better be aligned */ - assert(((uint32_t)dptr & 3) == 0); + assert(((uintptr_t)dptr & 3) == 0); pkthdr = OS_MBUF_PKTHDR(rxpdu); rem_bytes = pkthdr->omp_len; From dc60f90a379b92262b2e58fc2e48ae65cd4f45d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 25 Jul 2023 08:39:41 +0200 Subject: [PATCH 0752/1333] host/ble_l2cap_coc: coc_rx.sdus index should not exceed BLE_L2CAP_SDU_BUFF_CNT Multiple calls to `ble_l2cap_coc_recv_ready` with `BLE_L2CAP_SDU_BUFF_CNT == 1` will lead to assigning coc_rx.sdus outside array range - so this will (most likely) overwrite rest of stucture. This will lead to either undefined behavior or crash when structure members are accessed. --- nimble/host/src/ble_l2cap_coc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c index ae5624ce98..25727ee19c 100644 --- a/nimble/host/src/ble_l2cap_coc.c +++ b/nimble/host/src/ble_l2cap_coc.c @@ -341,7 +341,12 @@ ble_l2cap_coc_chan_alloc(struct ble_hs_conn *conn, uint16_t psm, uint16_t mtu, chan->coc_rx.sdus[i] = NULL; } chan->coc_rx.current_sdu_idx = 0; - chan->coc_rx.next_sdu_alloc_idx = chan->coc_rx.sdus[0] == NULL ? 0 : 1; + + if (BLE_L2CAP_SDU_BUFF_CNT == 1) { + chan->coc_rx.next_sdu_alloc_idx = 0; + } else { + chan->coc_rx.next_sdu_alloc_idx = chan->coc_rx.sdus[0] == NULL ? 0 : 1; + } /* Number of credits should allow to send full SDU with on given * L2CAP MTU From 32e39750d659cdd1c83f631ceb62b0762f20bcf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 6 Jul 2023 08:34:02 +0200 Subject: [PATCH 0753/1333] apps/bttester: split bttester.h and add btp_ prefixes Splits `bttester.h` into seperate files, one for each BTP service. Adds BTP_ prefix for defines and btp_ prefix for structs. --- apps/bttester/src/btp/btp.h | 88 ++ apps/bttester/src/btp/btp_core.h | 51 + apps/bttester/src/btp/btp_gap.h | 343 +++++ apps/bttester/src/btp/btp_gatt.h | 347 +++++ apps/bttester/src/btp/btp_gattc.h | 266 ++++ apps/bttester/src/btp/btp_l2cap.h | 141 ++ apps/bttester/src/btp/btp_mesh.h | 205 +++ apps/bttester/src/btp/bttester.h | 124 ++ apps/bttester/src/btp_core.c | 167 ++ apps/bttester/src/{gap.c => btp_gap.c} | 408 ++--- apps/bttester/src/{gatt.c => btp_gatt.c} | 318 ++-- .../bttester/src/{gatt_cl.c => btp_gatt_cl.c} | 272 ++-- apps/bttester/src/{l2cap.c => btp_l2cap.c} | 120 +- apps/bttester/src/{mesh.c => btp_mesh.c} | 206 +-- apps/bttester/src/bttester.c | 145 +- apps/bttester/src/bttester.h | 1361 ----------------- apps/bttester/src/bttester_pipe.h | 2 +- apps/bttester/src/main.c | 2 +- 18 files changed, 2399 insertions(+), 2167 deletions(-) create mode 100644 apps/bttester/src/btp/btp.h create mode 100644 apps/bttester/src/btp/btp_core.h create mode 100644 apps/bttester/src/btp/btp_gap.h create mode 100644 apps/bttester/src/btp/btp_gatt.h create mode 100644 apps/bttester/src/btp/btp_gattc.h create mode 100644 apps/bttester/src/btp/btp_l2cap.h create mode 100644 apps/bttester/src/btp/btp_mesh.h create mode 100644 apps/bttester/src/btp/bttester.h create mode 100644 apps/bttester/src/btp_core.c rename apps/bttester/src/{gap.c => btp_gap.c} (79%) rename apps/bttester/src/{gatt.c => btp_gatt.c} (85%) rename apps/bttester/src/{gatt_cl.c => btp_gatt_cl.c} (82%) rename apps/bttester/src/{l2cap.c => btp_l2cap.c} (84%) rename apps/bttester/src/{mesh.c => btp_mesh.c} (78%) delete mode 100644 apps/bttester/src/bttester.h diff --git a/apps/bttester/src/btp/btp.h b/apps/bttester/src/btp/btp.h new file mode 100644 index 0000000000..3cf172f9b5 --- /dev/null +++ b/apps/bttester/src/btp/btp.h @@ -0,0 +1,88 @@ +/* + * 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. + */ + +/* btp.h - Bluetooth tester btp headers */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * Copyright (C) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bttester.h" +#include "btp_core.h" +#include "btp_gap.h" +#include "btp_gatt.h" +#include "btp_gattc.h" +#include "btp_l2cap.h" +#include "btp_mesh.h" + +#if MYNEWT_VAL(BLE_MESH) +#include "mesh/glue.h" +#else +#include "../glue.h" +#endif + +#define BTP_MTU MYNEWT_VAL(BTTESTER_BTP_DATA_SIZE_MAX) +#define BTP_DATA_MAX_SIZE (BTP_MTU - sizeof(struct btp_hdr)) + +#define BTP_INDEX_NONE 0xff + +#define BTP_SERVICE_ID_CORE 0 +#define BTP_SERVICE_ID_GAP 1 +#define BTP_SERVICE_ID_GATT 2 +#define BTP_SERVICE_ID_L2CAP 3 +#define BTP_SERVICE_ID_MESH 4 +#define BTP_SERVICE_ID_GATTC 6 + +#define BTP_STATUS_SUCCESS 0x00 +#define BTP_STATUS_FAILED 0x01 +#define BTP_STATUS_UNKNOWN_CMD 0x02 +#define BTP_STATUS_NOT_READY 0x03 + +#define SYS_LOG_DBG(fmt, ...) \ + if (MYNEWT_VAL(BTTESTER_DEBUG)) { \ + console_printf("[DBG] %s: " fmt "\n", \ + __func__, ## __VA_ARGS__); \ + } +#define SYS_LOG_INF(fmt, ...) console_printf("[INF] %s: " fmt "\n", \ + __func__, ## __VA_ARGS__); +#define SYS_LOG_ERR(fmt, ...) console_printf("[WRN] %s: " fmt "\n", \ + __func__, ## __VA_ARGS__); + +#define SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG +#define SYS_LOG_DOMAIN "bttester" + +#define sys_cpu_to_le32 htole32 +#define sys_le32_to_cpu le32toh +#define sys_cpu_to_le16 htole16 + +struct btp_hdr { + uint8_t service; + uint8_t opcode; + uint8_t index; + uint16_t len; + uint8_t data[0]; +} __packed; + +#define BTP_STATUS 0x00 +struct btp_status { + uint8_t code; +} __packed; diff --git a/apps/bttester/src/btp/btp_core.h b/apps/bttester/src/btp/btp_core.h new file mode 100644 index 0000000000..cbf309ce88 --- /dev/null +++ b/apps/bttester/src/btp/btp_core.h @@ -0,0 +1,51 @@ +/* + * 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. + */ + +/* btp_core.h - Bluetooth tester Core service headers */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * Copyright (C) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Core Service */ +#define BTP_CORE_READ_SUPPORTED_COMMANDS 0x01 +struct btp_core_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define BTP_CORE_READ_SUPPORTED_SERVICES 0x02 +struct btp_core_read_supported_services_rp { + uint8_t data[0]; +} __packed; + +#define BTP_CORE_REGISTER_SERVICE 0x03 +struct btp_core_register_service_cmd { + uint8_t id; +} __packed; + +#define BTP_CORE_UNREGISTER_SERVICE 0x04 +struct btp_core_unregister_service_cmd { + uint8_t id; +} __packed; + +/* events */ +#define BTP_CORE_EV_IUT_READY 0x80 \ No newline at end of file diff --git a/apps/bttester/src/btp/btp_gap.h b/apps/bttester/src/btp/btp_gap.h new file mode 100644 index 0000000000..4a24df678d --- /dev/null +++ b/apps/bttester/src/btp/btp_gap.h @@ -0,0 +1,343 @@ +/* + * 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. + */ + +/* btp_gap.h - Bluetooth tester GAP service headers */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * Copyright (C) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* GAP Service */ +/* commands */ +#define BTP_GAP_READ_SUPPORTED_COMMANDS 0x01 +struct btp_gap_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define BTP_GAP_READ_CONTROLLER_INDEX_LIST 0x02 +struct btp_gap_read_controller_index_list_rp { + uint8_t num; + uint8_t index[0]; +} __packed; + +#define BTP_GAP_SETTINGS_POWERED 0 +#define BTP_GAP_SETTINGS_CONNECTABLE 1 +#define BTP_GAP_SETTINGS_FAST_CONNECTABLE 2 +#define BTP_GAP_SETTINGS_DISCOVERABLE 3 +#define BTP_GAP_SETTINGS_BONDABLE 4 +#define BTP_GAP_SETTINGS_LINK_SEC_3 5 +#define BTP_GAP_SETTINGS_SSP 6 +#define BTP_GAP_SETTINGS_BREDR 7 +#define BTP_GAP_SETTINGS_HS 8 +#define BTP_GAP_SETTINGS_LE 9 +#define BTP_GAP_SETTINGS_ADVERTISING 10 +#define BTP_GAP_SETTINGS_SC 11 +#define BTP_GAP_SETTINGS_DEBUG_KEYS 12 +#define BTP_GAP_SETTINGS_PRIVACY 13 +#define BTP_GAP_SETTINGS_CONTROLLER_CONFIG 14 +#define BTP_GAP_SETTINGS_STATIC_ADDRESS 15 + +#define BTP_GAP_READ_CONTROLLER_INFO 0x03 +struct btp_gap_read_controller_info_rp { + uint8_t address[6]; + uint32_t supported_settings; + uint32_t current_settings; + uint8_t cod[3]; + uint8_t name[249]; + uint8_t short_name[11]; +} __packed; + +#define BTP_GAP_RESET 0x04 +struct btp_gap_reset_rp { + uint32_t current_settings; +} __packed; + +#define BTP_GAP_SET_POWERED 0x05 +struct btp_gap_set_powered_cmd { + uint8_t powered; +} __packed; +struct btp_gap_set_powered_rp { + uint32_t current_settings; +} __packed; + +#define BTP_GAP_SET_CONNECTABLE 0x06 +struct btp_gap_set_connectable_cmd { + uint8_t connectable; +} __packed; +struct btp_gap_set_connectable_rp { + uint32_t current_settings; +} __packed; + +#define BTP_GAP_SET_FAST_CONNECTABLE 0x07 +struct btp_gap_set_fast_connectable_cmd { + uint8_t fast_connectable; +} __packed; +struct btp_gap_set_fast_connectable_rp { + uint32_t current_settings; +} __packed; + +#define BTP_GAP_NON_DISCOVERABLE 0x00 +#define BTP_GAP_GENERAL_DISCOVERABLE 0x01 +#define BTP_GAP_LIMITED_DISCOVERABLE 0x02 + +#define BTP_GAP_SET_DISCOVERABLE 0x08 +struct btp_gap_set_discoverable_cmd { + uint8_t discoverable; +} __packed; +struct btp_gap_set_discoverable_rp { + uint32_t current_settings; +} __packed; + +#define BTP_GAP_SET_BONDABLE 0x09 +struct btp_gap_set_bondable_cmd { + uint8_t bondable; +} __packed; +struct btp_gap_set_bondable_rp { + uint32_t current_settings; +} __packed; + +#define BTP_GAP_START_ADVERTISING 0x0a +struct btp_gap_start_advertising_cmd { + uint8_t adv_data_len; + uint8_t scan_rsp_len; + uint8_t adv_data[0]; + uint8_t scan_rsp[0]; +} __packed; +struct btp_gap_start_advertising_rp { + uint32_t current_settings; +} __packed; + +#define BTP_GAP_STOP_ADVERTISING 0x0b +struct btp_gap_stop_advertising_rp { + uint32_t current_settings; +} __packed; + +#define BTP_GAP_DISCOVERY_FLAG_LE 0x01 +#define BTP_GAP_DISCOVERY_FLAG_BREDR 0x02 +#define BTP_GAP_DISCOVERY_FLAG_LIMITED 0x04 +#define BTP_GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN 0x08 +#define BTP_GAP_DISCOVERY_FLAG_LE_OBSERVE 0x10 + +#define BTP_GAP_START_DISCOVERY 0x0c +struct btp_gap_start_discovery_cmd { + uint8_t flags; +} __packed; + +#define BTP_GAP_STOP_DISCOVERY 0x0d + +#define BTP_GAP_CONNECT 0x0e +struct btp_gap_connect_cmd { + uint8_t address_type; + uint8_t address[6]; +} __packed; + +#define BTP_GAP_DISCONNECT 0x0f +struct btp_gap_disconnect_cmd { + uint8_t address_type; + uint8_t address[6]; +} __packed; + +#define BTP_GAP_IO_CAP_DISPLAY_ONLY 0 +#define BTP_GAP_IO_CAP_DISPLAY_YESNO 1 +#define BTP_GAP_IO_CAP_KEYBOARD_ONLY 2 +#define BTP_GAP_IO_CAP_NO_INPUT_OUTPUT 3 +#define BTP_GAP_IO_CAP_KEYBOARD_DISPLAY 4 + +#define BTP_GAP_SET_IO_CAP 0x10 +struct btp_gap_set_io_cap_cmd { + uint8_t io_cap; +} __packed; + +#define BTP_GAP_PAIR 0x11 +struct btp_gap_pair_cmd { + uint8_t address_type; + uint8_t address[6]; +} __packed; + +#define BTP_GAP_UNPAIR 0x12 +struct btp_gap_unpair_cmd { + uint8_t address_type; + uint8_t address[6]; +} __packed; + +#define BTP_GAP_PASSKEY_ENTRY 0x13 +struct btp_gap_passkey_entry_cmd { + uint8_t address_type; + uint8_t address[6]; + uint32_t passkey; +} __packed; + +#define BTP_GAP_PASSKEY_CONFIRM 0x14 +struct btp_gap_passkey_confirm_cmd { + uint8_t address_type; + uint8_t address[6]; + uint8_t match; +} __packed; + +#define BTP_GAP_START_DIRECT_ADV 0x15 +struct btp_gap_start_direct_adv_cmd { + uint8_t address_type; + uint8_t address[6]; + uint8_t high_duty; +} __packed; + +#define BTP_GAP_CONN_PARAM_UPDATE 0x16 +struct btp_gap_conn_param_update_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t conn_itvl_min; + uint16_t conn_itvl_max; + uint16_t conn_latency; + uint16_t supervision_timeout; +} __packed; + +#define BTP_GAP_PAIRING_CONSENT_RSP 0x17 +struct btp_gap_pairing_consent_rsp_cmd { + uint8_t address_type; + uint8_t address[6]; + uint8_t consent; +} __packed; + +#define BTP_GAP_OOB_LEGACY_SET_DATA 0x18 +struct btp_gap_oob_legacy_set_data_cmd { + uint8_t oob_data[16]; +} __packed; + +#define BTP_GAP_OOB_SC_GET_LOCAL_DATA 0x19 +struct btp_gap_oob_sc_get_local_data_rp { + uint8_t r[16]; + uint8_t c[16]; +} __packed; + +#define BTP_GAP_OOB_SC_SET_REMOTE_DATA 0x1a +struct btp_gap_oob_sc_set_remote_data_cmd { + uint8_t r[16]; + uint8_t c[16]; +} __packed; + +#define BTP_GAP_SET_MITM 0x1b +struct btp_gap_set_mitm_cmd { + uint8_t mitm; +} __packed; + +#define BTP_GAP_SET_FILTER_ACCEPT_LIST 0x1c +struct btp_gap_set_filter_accept_list_cmd { + uint8_t list_len; + ble_addr_t addrs[]; +} __packed; +/* events */ +#define BTP_GAP_EV_NEW_SETTINGS 0x80 +struct btp_gap_new_settings_ev { + uint32_t current_settings; +} __packed; + +#define BTP_GAP_DEVICE_FOUND_FLAG_RSSI 0x01 +#define BTP_GAP_DEVICE_FOUND_FLAG_AD 0x02 +#define BTP_GAP_DEVICE_FOUND_FLAG_SD 0x04 + +#define BTP_GAP_EV_DEVICE_FOUND 0x81 +struct btp_gap_device_found_ev { + uint8_t address_type; + uint8_t address[6]; + int8_t rssi; + uint8_t flags; + uint16_t eir_data_len; + uint8_t eir_data[0]; +} __packed; + +#define BTP_GAP_EV_DEVICE_CONNECTED 0x82 +struct btp_gap_device_connected_ev { + uint8_t address_type; + uint8_t address[6]; + uint16_t conn_itvl; + uint16_t conn_latency; + uint16_t supervision_timeout; +} __packed; + +#define BTP_GAP_EV_DEVICE_DISCONNECTED 0x83 +struct btp_gap_device_disconnected_ev { + uint8_t address_type; + uint8_t address[6]; +} __packed; + +#define BTP_GAP_EV_PASSKEY_DISPLAY 0x84 +struct btp_gap_passkey_display_ev { + uint8_t address_type; + uint8_t address[6]; + uint32_t passkey; +} __packed; + +#define BTP_GAP_EV_PASSKEY_ENTRY_REQ 0x85 +struct btp_gap_passkey_entry_req_ev { + uint8_t address_type; + uint8_t address[6]; +} __packed; + +#define BTP_GAP_EV_PASSKEY_CONFIRM_REQ 0x86 +struct btp_gap_passkey_confirm_req_ev { + uint8_t address_type; + uint8_t address[6]; + uint32_t passkey; +} __packed; + +#define BTP_GAP_EV_IDENTITY_RESOLVED 0x87 +struct btp_gap_identity_resolved_ev { + uint8_t address_type; + uint8_t address[6]; + uint8_t identity_address_type; + uint8_t identity_address[6]; +} __packed; + +#define BTP_GAP_EV_CONN_PARAM_UPDATE 0x88 +struct btp_gap_conn_param_update_ev { + uint8_t address_type; + uint8_t address[6]; + uint16_t conn_itvl; + uint16_t conn_latency; + uint16_t supervision_timeout; +} __packed; + +#define BTP_GAP_EV_SEC_LEVEL_CHANGED 0x89 +struct btp_gap_sec_level_changed_ev { + uint8_t address_type; + uint8_t address[6]; + uint8_t level; +} __packed; + +#define BTP_GAP_EV_PAIRING_CONSENT_REQ 0x8a +struct btp_gap_pairing_consent_req_ev { + uint8_t address_type; + uint8_t address[6]; +} __packed; + +#define BTP_GAP_EV_BOND_LOST 0x8b +struct btp_gap_bond_lost_ev { + uint8_t address_type; + uint8_t address[6]; +} __packed; + +#define BTP_GAP_EV_SEC_PAIRING_FAILED 0x8c +struct btp_gap_sec_pairing_failed_ev { + uint8_t address_type; + uint8_t address[6]; + uint8_t reason; +} __packed; diff --git a/apps/bttester/src/btp/btp_gatt.h b/apps/bttester/src/btp/btp_gatt.h new file mode 100644 index 0000000000..6e23366460 --- /dev/null +++ b/apps/bttester/src/btp/btp_gatt.h @@ -0,0 +1,347 @@ +/* + * 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. + */ + +/* btp_gatt.h - Bluetooth tester GATT service headers */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * Copyright (C) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* GATT Service */ +/* commands */ +#define BTP_GATT_READ_SUPPORTED_COMMANDS 0x01 +struct btp_gatt_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define BTP_GATT_SERVICE_PRIMARY 0x00 +#define BTP_GATT_SERVICE_SECONDARY 0x01 + +#define BTP_GATT_ADD_SERVICE 0x02 +struct btp_gatt_add_service_cmd { + uint8_t type; + uint8_t uuid_length; + uint8_t uuid[0]; +} __packed; +struct btp_gatt_add_service_rp { + uint16_t svc_id; +} __packed; + +#define BTP_GATT_ADD_CHARACTERISTIC 0x03 +struct btp_gatt_add_characteristic_cmd { + uint16_t svc_id; + uint8_t properties; + uint8_t permissions; + uint8_t uuid_length; + uint8_t uuid[0]; +} __packed; +struct btp_gatt_add_characteristic_rp { + uint16_t char_id; +} __packed; + +#define BTP_GATT_ADD_DESCRIPTOR 0x04 +struct btp_gatt_add_descriptor_cmd { + uint16_t char_id; + uint8_t permissions; + uint8_t uuid_length; + uint8_t uuid[0]; +} __packed; +struct btp_gatt_add_descriptor_rp { + uint16_t desc_id; +} __packed; + +#define BTP_GATT_ADD_INCLUDED_SERVICE 0x05 +struct btp_gatt_add_included_service_cmd { + uint16_t svc_id; +} __packed; +struct btp_gatt_add_included_service_rp { + uint16_t included_service_id; +} __packed; + +#define BTP_GATT_SET_VALUE 0x06 +struct btp_gatt_set_value_cmd { + uint16_t attr_id; + uint16_t len; + uint8_t value[0]; +} __packed; + +#define BTP_GATT_START_SERVER 0x07 +struct btp_gatt_start_server_rp { + uint16_t db_attr_off; + uint8_t db_attr_cnt; +} __packed; + +#define BTP_GATT_SET_ENC_KEY_SIZE 0x09 +struct btp_gatt_set_enc_key_size_cmd { + uint16_t attr_id; + uint8_t key_size; +} __packed; + +struct btp_gatt_service { + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_length; + uint8_t uuid[0]; +} __packed; + +struct btp_gatt_included { + uint16_t included_handle; + struct btp_gatt_service service; +} __packed; + +struct btp_gatt_read_uuid_chr { + uint16_t handle; + uint8_t data[0]; +} __packed; + +struct btp_gatt_characteristic { + uint16_t characteristic_handle; + uint16_t value_handle; + uint8_t properties; + uint8_t uuid_length; + uint8_t uuid[0]; +} __packed; + +struct btp_gatt_descriptor { + uint16_t descriptor_handle; + uint8_t uuid_length; + uint8_t uuid[0]; +} __packed; + +#define BTP_GATT_EXCHANGE_MTU 0x0a + +#define BTP_GATT_DISC_ALL_PRIM_SVCS 0x0b +struct btp_gatt_disc_all_prim_svcs_cmd { + uint8_t address_type; + uint8_t address[6]; +} __packed; +struct btp_gatt_disc_all_prim_svcs_rp { + uint8_t services_count; + struct btp_gatt_service services[0]; +} __packed; + +#define BTP_GATT_DISC_PRIM_UUID 0x0c +struct btp_gatt_disc_prim_uuid_cmd { + uint8_t address_type; + uint8_t address[6]; + uint8_t uuid_length; + uint8_t uuid[0]; +} __packed; +struct btp_gatt_disc_prim_uuid_rp { + uint8_t services_count; + struct btp_gatt_service services[0]; +} __packed; + +#define BTP_GATT_FIND_INCLUDED 0x0d +struct btp_gatt_find_included_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; +} __packed; +struct btp_gatt_find_included_rp { + uint8_t services_count; + struct btp_gatt_included included[0]; +} __packed; + +#define BTP_GATT_DISC_ALL_CHRC 0x0e +struct btp_gatt_disc_all_chrc_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; +} __packed; +struct btp_gatt_disc_chrc_rp { + uint8_t characteristics_count; + struct btp_gatt_characteristic characteristics[0]; +} __packed; + +#define BTP_GATT_DISC_CHRC_UUID 0x0f +struct btp_gatt_disc_chrc_uuid_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_length; + uint8_t uuid[0]; +} __packed; + +#define BTP_GATT_DISC_ALL_DESC 0x10 +struct btp_gatt_disc_all_desc_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; +} __packed; +struct btp_gatt_disc_all_desc_rp { + uint8_t descriptors_count; + struct btp_gatt_descriptor descriptors[0]; +} __packed; + +#define BTP_GATT_READ 0x11 +struct btp_gatt_read_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; +} __packed; +struct btp_gatt_read_rp { + uint8_t att_response; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define BTP_GATT_READ_UUID 0x12 +struct btp_gatt_read_uuid_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_length; + uint8_t uuid[0]; +} __packed; + +#define BTP_GATT_READ_LONG 0x13 +struct btp_gatt_read_long_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t offset; +} __packed; + +#define BTP_GATT_READ_MULTIPLE 0x14 +struct btp_gatt_read_multiple_cmd { + uint8_t address_type; + uint8_t address[6]; + uint8_t handles_count; + uint16_t handles[0]; +} __packed; + +#define BTP_GATT_WRITE_WITHOUT_RSP 0x15 +struct btp_gatt_write_without_rsp_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define BTP_GATT_SIGNED_WRITE_WITHOUT_RSP 0x16 +struct btp_gatt_signed_write_without_rsp_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define BTP_GATT_WRITE 0x17 +struct btp_gatt_write_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define BTP_GATT_WRITE_LONG 0x18 +struct btp_gatt_write_long_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t offset; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define BTP_GATT_RELIABLE_WRITE 0x19 +struct btp_gatt_reliable_write_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t offset; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define BTP_GATT_CFG_NOTIFY 0x1a +#define BTP_GATT_CFG_INDICATE 0x1b +struct btp_gatt_cfg_notify_cmd { + uint8_t address_type; + uint8_t address[6]; + uint8_t enable; + uint16_t ccc_handle; +} __packed; + +#define BTP_GATT_GET_ATTRIBUTES 0x1c +struct btp_gatt_get_attributes_cmd { + uint16_t start_handle; + uint16_t end_handle; + uint8_t type_length; + uint8_t type[0]; +} __packed; +struct btp_gatt_get_attributes_rp { + uint8_t attrs_count; + uint8_t attrs[0]; +} __packed; +struct btp_gatt_attr { + uint16_t handle; + uint8_t permission; + uint8_t type_length; + uint8_t type[0]; +} __packed; + +#define BTP_GATT_GET_ATTRIBUTE_VALUE 0x1d +struct btp_gatt_get_attribute_value_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; +} __packed; +struct btp_gatt_get_attribute_value_rp { + uint8_t att_response; + uint16_t value_length; + uint8_t value[0]; +} __packed; + +#define BTP_GATT_CHANGE_DATABASE 0x1e +struct btp_gatt_change_database { + uint16_t start_handle; + uint16_t end_handle; + uint8_t visibility; +} __packed; + +/* GATT events */ +#define BTP_GATT_EV_NOTIFICATION 0x80 +struct btp_gatt_notification_ev { + uint8_t address_type; + uint8_t address[6]; + uint8_t type; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define BTP_GATT_EV_ATTR_VALUE_CHANGED 0x81 +struct btp_gatt_attr_value_changed_ev { + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; +} __packed; diff --git a/apps/bttester/src/btp/btp_gattc.h b/apps/bttester/src/btp/btp_gattc.h new file mode 100644 index 0000000000..0b946a52b1 --- /dev/null +++ b/apps/bttester/src/btp/btp_gattc.h @@ -0,0 +1,266 @@ +/* + * 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. + */ + +/* btp_gattc.h - Bluetooth tester GATT Client service headers */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * Copyright (C) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* GATT Client Service */ +/* commands */ +#define BTP_GATTC_READ_SUPPORTED_COMMANDS 0x01 +struct btp_gattc_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define BTP_GATTC_EXCHANGE_MTU 0x02 + +#define BTP_GATTC_DISC_ALL_PRIM_SVCS 0x03 +struct btp_gattc_disc_all_prim_svcs_cmd { + uint8_t address_type; + uint8_t address[6]; +} __packed; + +#define BTP_GATTC_DISC_PRIM_UUID 0x04 +struct btp_gattc_disc_prim_uuid_cmd { + uint8_t address_type; + uint8_t address[6]; + uint8_t uuid_length; + uint8_t uuid[0]; +} __packed; + +#define BTP_GATTC_FIND_INCLUDED 0x05 +struct btp_gattc_find_included_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; +} __packed; + +#define BTP_GATTC_DISC_ALL_CHRC 0x06 +struct btp_gattc_disc_all_chrc_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; +} __packed; + +#define BTP_GATTC_DISC_CHRC_UUID 0x07 +struct btp_gattc_disc_chrc_uuid_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_length; + uint8_t uuid[0]; +} __packed; + +#define BTP_GATTC_DISC_ALL_DESC 0x08 +struct btp_gattc_disc_all_desc_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; +} __packed; + +#define BTP_GATTC_READ 0x09 +struct btp_gattc_read_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; +} __packed; + +#define BTP_GATTC_READ_UUID 0x0a +struct btp_gattc_read_uuid_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_length; + uint8_t uuid[0]; +} __packed; +struct btp_gattc_read_uuid_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint16_t data_length; + uint8_t value_length; + uint8_t data[0]; +} __packed; + +#define BTP_GATTC_READ_LONG 0x0b +struct btp_gattc_read_long_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t offset; +} __packed; + +#define BTP_GATTC_READ_MULTIPLE 0x0c +struct btp_gattc_read_multiple_cmd { + uint8_t address_type; + uint8_t address[6]; + uint8_t handles_count; + uint16_t handles[0]; +} __packed; + +#define BTP_GATTC_WRITE_WITHOUT_RSP 0x0d +struct btp_gattc_write_without_rsp_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define BTP_GATTC_SIGNED_WRITE_WITHOUT_RSP 0x0e +struct btp_gattc_signed_write_without_rsp_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define BTP_GATTC_WRITE 0x0f +struct btp_gattc_write_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define BTP_GATTC_WRITE_LONG 0x10 +struct btp_gattc_write_long_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t offset; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define BTP_GATTC_RELIABLE_WRITE 0x11 +struct btp_gattc_reliable_write_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t handle; + uint16_t offset; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define BTP_GATTC_CFG_NOTIFY 0x12 +#define BTP_GATTC_CFG_INDICATE 0x13 +struct btp_gattc_cfg_notify_cmd { + uint8_t address_type; + uint8_t address[6]; + uint8_t enable; + uint16_t ccc_handle; +} __packed; + +/* events */ +#define BTP_GATTC_EV_MTU_EXCHANGED 0x80 +struct btp_gattc_exchange_mtu_ev { + uint8_t address_type; + uint8_t address[6]; + uint16_t mtu; +} __packed; + +#define BTP_GATTC_DISC_ALL_PRIM_RP 0x81 +struct btp_gattc_disc_prim_svcs_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint8_t services_count; + uint8_t data[0]; +} __packed; + +#define BTP_GATTC_DISC_PRIM_UUID_RP 0x82 + +#define BTP_GATTC_FIND_INCLUDED_RP 0x83 +struct btp_gattc_find_included_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint8_t services_count; + struct btp_gatt_included included[0]; +} __packed; + +#define BTP_GATTC_DISC_ALL_CHRC_RP 0x84 +#define BTP_GATTC_DISC_CHRC_UUID_RP 0x85 +struct btp_gattc_disc_chrc_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint8_t characteristics_count; + struct btp_gatt_characteristic characteristics[0]; +} __packed; + +#define BTP_GATTC_DISC_ALL_DESC_RP 0x86 +struct btp_gattc_disc_all_desc_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint8_t descriptors_count; + struct btp_gatt_descriptor descriptors[0]; +} __packed; + +#define BTP_GATTC_READ_RP 0x87 +#define BTP_GATTC_READ_UUID_RP 0x88 +#define BTP_GATTC_READ_LONG_RP 0x89 +#define BTP_GATTC_READ_MULTIPLE_RP 0x8a +struct btp_gattc_read_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define BTP_GATTC_WRITE_RP 0x8b +struct btp_gattc_write_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; +} __packed; +#define BTP_GATTC_WRITE_LONG_RP 0x8c +#define BTP_GATTC_RELIABLE_WRITE_RP 0x8d +#define BTP_GATTC_CFG_NOTIFY_RP 0x8e +#define BTP_GATTC_CFG_INDICATE_RP 0x8f +struct btp_subscribe_rp { + uint8_t address_type; + uint8_t address[6]; + uint8_t status; +} __packed; + +#define BTP_GATTC_EV_NOTIFICATION_RXED 0x90 +struct btp_gattc_notification_ev { + uint8_t address_type; + uint8_t address[6]; + uint8_t type; + uint16_t handle; + uint16_t data_length; + uint8_t data[0]; +} __packed; diff --git a/apps/bttester/src/btp/btp_l2cap.h b/apps/bttester/src/btp/btp_l2cap.h new file mode 100644 index 0000000000..5916345531 --- /dev/null +++ b/apps/bttester/src/btp/btp_l2cap.h @@ -0,0 +1,141 @@ +/* + * 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. + */ + +/* btp_l2cap.h - Bluetooth tester L2CAP service headers */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * Copyright (C) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* L2CAP Service */ +/* commands */ +#define BTP_L2CAP_READ_SUPPORTED_COMMANDS 0x01 +struct btp_l2cap_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define BTP_L2CAP_CONNECT_OPT_ECFC 0x01 +#define BTP_L2CAP_CONNECT_OPT_HOLD_CREDIT 0x02 + +#define BTP_L2CAP_CONNECT 0x02 +struct btp_l2cap_connect_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t psm; + uint16_t mtu; + uint8_t num; + uint8_t options; +} __packed; + +struct btp_l2cap_connect_rp { + uint8_t num; + uint8_t chan_ids[0]; +} __packed; + +#define BTP_L2CAP_DISCONNECT 0x03 +struct btp_l2cap_disconnect_cmd { + uint8_t chan_id; +} __packed; + +#define BTP_L2CAP_SEND_DATA 0x04 +struct btp_l2cap_send_data_cmd { + uint8_t chan_id; + uint16_t data_len; + uint8_t data[]; +} __packed; + +#define BTP_L2CAP_TRANSPORT_BREDR 0x00 +#define BTP_L2CAP_TRANSPORT_LE 0x01 + +#define BTP_L2CAP_LISTEN 0x05 +struct btp_l2cap_listen_cmd { + uint16_t psm; + uint8_t transport; + uint16_t mtu; + uint16_t response; +} __packed; + +#define BTP_L2CAP_ACCEPT_CONNECTION 0x06 +struct l2cap_accept_connection_cmd { + uint8_t chan_id; + uint16_t result; +} __packed; + +#define BTP_L2CAP_RECONFIGURE 0x07 +struct btp_l2cap_reconfigure_cmd { + uint8_t address_type; + uint8_t address[6]; + uint16_t mtu; + uint8_t num; + uint8_t idxs[]; +} __packed; + +#define BTP_L2CAP_CREDITS 0x08 +struct btp_l2cap_credits_cmd { + uint8_t chan_id; +} __packed; + +/* events */ +#define BTP_L2CAP_EV_CONNECTION_REQ 0x80 +struct btp_l2cap_connection_req_ev { + uint8_t chan_id; + uint16_t psm; + uint8_t address_type; + uint8_t address[6]; +} __packed; + +#define BTP_L2CAP_EV_CONNECTED 0x81 +struct btp_l2cap_connected_ev { + uint8_t chan_id; + uint16_t psm; + uint16_t peer_mtu; + uint16_t peer_mps; + uint16_t our_mtu; + uint16_t our_mps; + uint8_t address_type; + uint8_t address[6]; +} __packed; + +#define BTP_L2CAP_EV_DISCONNECTED 0x82 +struct btp_l2cap_disconnected_ev { + uint16_t result; + uint8_t chan_id; + uint16_t psm; + uint8_t address_type; + uint8_t address[6]; +} __packed; + +#define BTP_L2CAP_EV_DATA_RECEIVED 0x83 +struct btp_l2cap_data_received_ev { + uint8_t chan_id; + uint16_t data_length; + uint8_t data[0]; +} __packed; + +#define BTP_L2CAP_EV_RECONFIGURED 0x84 +struct btp_l2cap_reconfigured_ev { + uint8_t chan_id; + uint16_t peer_mtu; + uint16_t peer_mps; + uint16_t our_mtu; + uint16_t our_mps; +} __packed; diff --git a/apps/bttester/src/btp/btp_mesh.h b/apps/bttester/src/btp/btp_mesh.h new file mode 100644 index 0000000000..0a356e40ff --- /dev/null +++ b/apps/bttester/src/btp/btp_mesh.h @@ -0,0 +1,205 @@ +/* + * 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. + */ + +/* btp_mesh.h - Bluetooth tester MESH service headers */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * Copyright (C) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* MESH Service */ +/* commands */ +#define BTP_MESH_READ_SUPPORTED_COMMANDS 0x01 +struct btp_mesh_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define BTP_MESH_OUT_BLINK BIT(0) +#define BTP_MESH_OUT_BEEP BIT(1) +#define BTP_MESH_OUT_VIBRATE BIT(2) +#define BTP_MESH_OUT_DISPLAY_NUMBER BIT(3) +#define BTP_MESH_OUT_DISPLAY_STRING BIT(4) + +#define BTP_MESH_IN_PUSH BIT(0) +#define BTP_MESH_IN_TWIST BIT(1) +#define BTP_MESH_IN_ENTER_NUMBER BIT(2) +#define BTP_MESH_IN_ENTER_STRING BIT(3) + +#define BTP_MESH_CONFIG_PROVISIONING 0x02 +struct btp_mesh_config_provisioning_cmd { + uint8_t uuid[16]; + uint8_t static_auth[16]; + uint8_t out_size; + uint16_t out_actions; + uint8_t in_size; + uint16_t in_actions; +} __packed; + +#define BTP_MESH_PROVISION_NODE 0x03 +struct btp_mesh_provision_node_cmd { + uint8_t net_key[16]; + uint16_t net_key_idx; + uint8_t flags; + uint32_t iv_index; + uint32_t seq_num; + uint16_t addr; + uint8_t dev_key[16]; +} __packed; + +#define BTP_MESH_INIT 0x04 +#define BTP_MESH_RESET 0x05 +#define BTP_MESH_INPUT_NUMBER 0x06 +struct btp_mesh_input_number_cmd { + uint32_t number; +} __packed; + +#define BTP_MESH_INPUT_STRING 0x07 +struct btp_mesh_input_string_cmd { + uint8_t string_len; + uint8_t string[0]; +} __packed; + +#define BTP_MESH_IVU_TEST_MODE 0x08 +struct btp_mesh_ivu_test_mode_cmd { + uint8_t enable; +} __packed; + +#define BTP_MESH_IVU_TOGGLE_STATE 0x09 + +#define BTP_MESH_NET_SEND 0x0a +struct btp_mesh_net_send_cmd { + uint8_t ttl; + uint16_t src; + uint16_t dst; + uint8_t payload_len; + uint8_t payload[0]; +} __packed; + +#define BTP_MESH_HEALTH_GENERATE_FAULTS 0x0b +struct btp_mesh_health_generate_faults_rp { + uint8_t test_id; + uint8_t cur_faults_count; + uint8_t reg_faults_count; + uint8_t current_faults[0]; + uint8_t registered_faults[0]; +} __packed; + +#define BTP_MESH_HEALTH_CLEAR_FAULTS 0x0c + +#define BTP_MESH_LPN 0x0d +struct btp_mesh_lpn_set_cmd { + uint8_t enable; +} __packed; + +#define BTP_MESH_LPN_POLL 0x0e + +#define BTP_MESH_MODEL_SEND 0x0f +struct btp_mesh_model_send_cmd { + uint16_t src; + uint16_t dst; + uint8_t payload_len; + uint8_t payload[0]; +} __packed; + +#define BTP_MESH_LPN_SUBSCRIBE 0x10 +struct btp_mesh_lpn_subscribe_cmd { + uint16_t address; +} __packed; + +#define BTP_MESH_LPN_UNSUBSCRIBE 0x11 +struct btp_mesh_lpn_unsubscribe_cmd { + uint16_t address; +} __packed; + +#define BTP_MESH_RPL_CLEAR 0x12 +#define BTP_MESH_PROXY_IDENTITY 0x13 + +/* events */ +#define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80 +struct btp_mesh_out_number_action_ev { + uint16_t action; + uint32_t number; +} __packed; + +#define BTP_MESH_EV_OUT_STRING_ACTION 0x81 +struct btp_mesh_out_string_action_ev { + uint8_t string_len; + uint8_t string[0]; +} __packed; + +#define BTP_MESH_EV_IN_ACTION 0x82 +struct btp_mesh_in_action_ev { + uint16_t action; + uint8_t size; +} __packed; + +#define BTP_MESH_EV_PROVISIONED 0x83 + +#define BTP_MESH_PROV_BEARER_PB_ADV 0x00 +#define BTP_MESH_PROV_BEARER_PB_GATT 0x01 +#define BTP_MESH_EV_PROV_LINK_OPEN 0x84 +struct btp_mesh_prov_link_open_ev { + uint8_t bearer; +} __packed; + +#define BTP_MESH_EV_PROV_LINK_CLOSED 0x85 +struct btp_mesh_prov_link_closed_ev { + uint8_t bearer; +} __packed; + +#define BTP_MESH_EV_NET_RECV 0x86 +struct btp_mesh_net_recv_ev { + uint8_t ttl; + uint8_t ctl; + uint16_t src; + uint16_t dst; + uint8_t payload_len; + uint8_t payload[0]; +} __packed; + +#define BTP_MESH_EV_INVALID_BEARER 0x87 +struct btp_mesh_invalid_bearer_ev { + uint8_t opcode; +} __packed; + +#define BTP_MESH_EV_INCOMP_TIMER_EXP 0x88 + +#define BTP_MESH_EV_LPN_ESTABLISHED 0x8b +struct btp_mesh_lpn_established_ev { + uint16_t net_idx; + uint16_t friend_addr; + uint8_t queue_size; + uint8_t recv_win; +} __packed; + +#define BTP_MESH_EV_LPN_TERMINATED 0x8c +struct btp_mesh_lpn_terminated_ev { + uint16_t net_idx; + uint16_t friend_addr; +} __packed; + +#define BTP_MESH_EV_LPN_POLLED 0x8d +struct btp_mesh_lpn_polled_ev { + uint16_t net_idx; + uint16_t friend_addr; + uint8_t retry; +} __packed; diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h new file mode 100644 index 0000000000..06ea5833e1 --- /dev/null +++ b/apps/bttester/src/btp/bttester.h @@ -0,0 +1,124 @@ +/* + * 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. + */ + +/* bttester.h - Bluetooth tester headers */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * Copyright (C) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __BTTESTER_H__ +#define __BTTESTER_H__ + +#include "syscfg/syscfg.h" +#include "host/ble_gatt.h" +#if MYNEWT_VAL(BLE_MESH) +#include "mesh/glue.h" +#else +#include "glue.h" +#endif + +static inline void +tester_set_bit(uint8_t *addr, unsigned int bit) +{ + uint8_t *p = addr + (bit / 8); + + *p |= BIT(bit % 8); +} + +static inline uint8_t +tester_test_bit(const uint8_t *addr, unsigned int bit) +{ + const uint8_t *p = addr + (bit / 8); + + return *p & BIT(bit % 8); +} + + +void +tester_init(void); +void +tester_rsp(uint8_t service, uint8_t opcode, uint8_t index, uint8_t status); +void +tester_send(uint8_t service, uint8_t opcode, uint8_t index, uint8_t *data, + size_t len); +void +tester_send_buf(uint8_t service, uint8_t opcode, uint8_t index, + struct os_mbuf *buf); + +uint8_t +tester_init_gap(void); +uint8_t +tester_unregister_gap(void); +void +tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len); +void +tester_handle_core(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len); +uint8_t +tester_init_gatt(void); +uint8_t +tester_unregister_gatt(void); +void +tester_handle_gatt(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len); +void +tester_handle_gattc(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len); +int +tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, + uint8_t indication, struct os_mbuf *om); +int +tester_gatt_subscribe_ev(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t reason, + uint8_t prev_notify, + uint8_t cur_notify, + uint8_t prev_indicate, + uint8_t cur_indicate); + +#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) +uint8_t +tester_init_l2cap(void); +uint8_t +tester_unregister_l2cap(void); +void +tester_handle_l2cap(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len); +#endif + +#if MYNEWT_VAL(BLE_MESH) +uint8_t +tester_init_mesh(void); +uint8_t +tester_unregister_mesh(void); +void +tester_handle_mesh(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len); +#endif /* MYNEWT_VAL(BLE_MESH) */ + +void +gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); + +int +gatt_svr_init(void); +#endif /* __BTTESTER_H__ */ \ No newline at end of file diff --git a/apps/bttester/src/btp_core.c b/apps/bttester/src/btp_core.c new file mode 100644 index 0000000000..afcac7c52b --- /dev/null +++ b/apps/bttester/src/btp_core.c @@ -0,0 +1,167 @@ +/* + * 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. + */ + +/* btp_core.c - Bluetooth BTP Core service */ + +/* + * Copyright (C) 2023 Codecoup + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "btp/btp.h" + +static void +supported_commands(uint8_t *data, uint16_t len) +{ + uint8_t buf[1]; + struct core_read_supported_commands_rp *rp = (void *) buf; + + memset(buf, 0, sizeof(buf)); + + tester_set_bit(buf, BTP_CORE_READ_SUPPORTED_COMMANDS); + tester_set_bit(buf, BTP_CORE_READ_SUPPORTED_SERVICES); + tester_set_bit(buf, BTP_CORE_REGISTER_SERVICE); + tester_set_bit(buf, BTP_CORE_UNREGISTER_SERVICE); + + tester_send(BTP_SERVICE_ID_CORE, BTP_CORE_READ_SUPPORTED_COMMANDS, + BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); +} + +static void +supported_services(uint8_t *data, uint16_t len) +{ + uint8_t buf[1]; + struct core_read_supported_services_rp *rp = (void *) buf; + + memset(buf, 0, sizeof(buf)); + + tester_set_bit(buf, BTP_SERVICE_ID_CORE); + tester_set_bit(buf, BTP_SERVICE_ID_GAP); + tester_set_bit(buf, BTP_SERVICE_ID_GATT); +#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) + tester_set_bit(buf, BTP_SERVICE_ID_L2CAP); +#endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */ +#if MYNEWT_VAL(BLE_MESH) + tester_set_bit(buf, BTP_SERVICE_ID_MESH); +#endif /* MYNEWT_VAL(BLE_MESH) */ + tester_set_bit(buf, BTP_SERVICE_ID_GATTC); + + tester_send(BTP_SERVICE_ID_CORE, BTP_CORE_READ_SUPPORTED_SERVICES, + BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); +} + +static void +register_service(uint8_t *data, uint16_t len) +{ + struct core_register_service_cmd *cmd = (void *) data; + uint8_t status; + + switch (cmd->id) { + case BTP_SERVICE_ID_GAP: + status = tester_init_gap(); + /* Rsp with success status will be handled by bt enable cb */ + if (status == BTP_STATUS_FAILED) { + goto rsp; + } + return; + case BTP_SERVICE_ID_GATT: + status = tester_init_gatt(); + break; +#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) + case BTP_SERVICE_ID_L2CAP: + status = tester_init_l2cap(); + break; +#endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */ +#if MYNEWT_VAL(BLE_MESH) + case BTP_SERVICE_ID_MESH: + status = tester_init_mesh(); + break; +#endif /* MYNEWT_VAL(BLE_MESH) */ + default: + status = BTP_STATUS_FAILED; + break; + } + +rsp: + tester_rsp(BTP_SERVICE_ID_CORE, BTP_CORE_REGISTER_SERVICE, BTP_INDEX_NONE, + status); +} + +static void +unregister_service(uint8_t *data, uint16_t len) +{ + struct core_unregister_service_cmd *cmd = (void *) data; + uint8_t status; + + switch (cmd->id) { + case BTP_SERVICE_ID_GAP: + status = tester_unregister_gap(); + break; + case BTP_SERVICE_ID_GATT: + status = tester_unregister_gatt(); + break; +#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) + case BTP_SERVICE_ID_L2CAP: + status = tester_unregister_l2cap(); + break; +#endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */ +#if MYNEWT_VAL(BLE_MESH) + case BTP_SERVICE_ID_MESH: + status = tester_unregister_mesh(); + break; +#endif /* MYNEWT_VAL(BLE_MESH) */ + default: + status = BTP_STATUS_FAILED; + break; + } + + tester_rsp(BTP_SERVICE_ID_CORE, BTP_CORE_UNREGISTER_SERVICE, BTP_INDEX_NONE, + status); +} + +void +tester_handle_core(uint8_t opcode, uint8_t index, uint8_t *data, + uint16_t len) +{ + if (index != BTP_INDEX_NONE) { + tester_rsp(BTP_SERVICE_ID_CORE, opcode, index, + BTP_STATUS_FAILED); + return; + } + + switch (opcode) { + case BTP_CORE_READ_SUPPORTED_COMMANDS: + supported_commands(data, len); + return; + case BTP_CORE_READ_SUPPORTED_SERVICES: + supported_services(data, len); + return; + case BTP_CORE_REGISTER_SERVICE: + register_service(data, len); + return; + case BTP_CORE_UNREGISTER_SERVICE: + unregister_service(data, len); + return; + default: + tester_rsp(BTP_SERVICE_ID_CORE, opcode, BTP_INDEX_NONE, + BTP_STATUS_UNKNOWN_CMD); + return; + } +} diff --git a/apps/bttester/src/gap.c b/apps/bttester/src/btp_gap.c similarity index 79% rename from apps/bttester/src/gap.c rename to apps/bttester/src/btp_gap.c index c28853a0e3..24f7f82dcc 100644 --- a/apps/bttester/src/gap.c +++ b/apps/bttester/src/btp_gap.c @@ -33,13 +33,13 @@ #include "../../../nimble/host/src/ble_hs_hci_priv.h" #include "../../../nimble/host/src/ble_sm_priv.h" -#include "bttester.h" +#include "btp/btp.h" #define CONTROLLER_INDEX 0 #define CONTROLLER_NAME "btp_tester" #define BLE_AD_DISCOV_MASK (BLE_HS_ADV_F_DISC_LTD | BLE_HS_ADV_F_DISC_GEN) -#define ADV_BUF_LEN (sizeof(struct gap_device_found_ev) + 2 * 31) +#define ADV_BUF_LEN (sizeof(struct btp_gap_device_found_ev) + 2 * 31) /* parameter values to reject in CPUP if all match the pattern */ #define REJECT_INTERVAL_MIN 0x0C80 @@ -62,11 +62,11 @@ static ble_addr_t peer_id_addr; static ble_addr_t peer_ota_addr; static bool encrypted = false; -static struct os_callout update_params_co; -static struct gap_conn_param_update_cmd update_params; +static struct os_callout update_params_co; +static struct btp_gap_conn_param_update_cmd update_params; -static struct os_callout connected_ev_co; -static struct gap_device_connected_ev connected_ev; +static struct os_callout connected_ev_co; +static struct btp_gap_device_connected_ev connected_ev; #define CONNECTED_EV_DELAY_MS(itvl) 8 * BLE_HCI_CONN_ITVL * itvl / 1000 static int connection_attempts; #if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) @@ -124,46 +124,46 @@ gap_event_cb(struct ble_gap_event *event, void *arg); static void supported_commands(uint8_t *data, uint16_t len) { - uint8_t cmds[3]; - struct gap_read_supported_commands_rp *rp = (void *) &cmds; + uint8_t cmds[3]; + struct btp_gap_read_supported_commands_rp *rp = (void *) &cmds; SYS_LOG_DBG(""); memset(cmds, 0, sizeof(cmds)); - tester_set_bit(cmds, GAP_READ_SUPPORTED_COMMANDS); - tester_set_bit(cmds, GAP_READ_CONTROLLER_INDEX_LIST); - tester_set_bit(cmds, GAP_READ_CONTROLLER_INFO); - tester_set_bit(cmds, GAP_SET_CONNECTABLE); - tester_set_bit(cmds, GAP_SET_DISCOVERABLE); - tester_set_bit(cmds, GAP_SET_BONDABLE); - tester_set_bit(cmds, GAP_START_ADVERTISING); - tester_set_bit(cmds, GAP_STOP_ADVERTISING); - tester_set_bit(cmds, GAP_START_DISCOVERY); - tester_set_bit(cmds, GAP_STOP_DISCOVERY); - tester_set_bit(cmds, GAP_CONNECT); - tester_set_bit(cmds, GAP_DISCONNECT); - tester_set_bit(cmds, GAP_SET_IO_CAP); - tester_set_bit(cmds, GAP_PAIR); - tester_set_bit(cmds, GAP_UNPAIR); - tester_set_bit(cmds, GAP_PASSKEY_ENTRY); - tester_set_bit(cmds, GAP_PASSKEY_CONFIRM); - tester_set_bit(cmds, GAP_START_DIRECT_ADV); - tester_set_bit(cmds, GAP_CONN_PARAM_UPDATE); - tester_set_bit(cmds, GAP_OOB_LEGACY_SET_DATA); - tester_set_bit(cmds, GAP_OOB_SC_GET_LOCAL_DATA); - tester_set_bit(cmds, GAP_OOB_SC_SET_REMOTE_DATA); - tester_set_bit(cmds, GAP_SET_MITM); - - tester_send(BTP_SERVICE_ID_GAP, GAP_READ_SUPPORTED_COMMANDS, + tester_set_bit(cmds, BTP_GAP_READ_SUPPORTED_COMMANDS); + tester_set_bit(cmds, BTP_GAP_READ_CONTROLLER_INDEX_LIST); + tester_set_bit(cmds, BTP_GAP_READ_CONTROLLER_INFO); + tester_set_bit(cmds, BTP_GAP_SET_CONNECTABLE); + tester_set_bit(cmds, BTP_GAP_SET_DISCOVERABLE); + tester_set_bit(cmds, BTP_GAP_SET_BONDABLE); + tester_set_bit(cmds, BTP_GAP_START_ADVERTISING); + tester_set_bit(cmds, BTP_GAP_STOP_ADVERTISING); + tester_set_bit(cmds, BTP_GAP_START_DISCOVERY); + tester_set_bit(cmds, BTP_GAP_STOP_DISCOVERY); + tester_set_bit(cmds, BTP_GAP_CONNECT); + tester_set_bit(cmds, BTP_GAP_DISCONNECT); + tester_set_bit(cmds, BTP_GAP_SET_IO_CAP); + tester_set_bit(cmds, BTP_GAP_PAIR); + tester_set_bit(cmds, BTP_GAP_UNPAIR); + tester_set_bit(cmds, BTP_GAP_PASSKEY_ENTRY); + tester_set_bit(cmds, BTP_GAP_PASSKEY_CONFIRM); + tester_set_bit(cmds, BTP_GAP_START_DIRECT_ADV); + tester_set_bit(cmds, BTP_GAP_CONN_PARAM_UPDATE); + tester_set_bit(cmds, BTP_GAP_OOB_LEGACY_SET_DATA); + tester_set_bit(cmds, BTP_GAP_OOB_SC_GET_LOCAL_DATA); + tester_set_bit(cmds, BTP_GAP_OOB_SC_SET_REMOTE_DATA); + tester_set_bit(cmds, BTP_GAP_SET_MITM); + + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_READ_SUPPORTED_COMMANDS, CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); } static void controller_index_list(uint8_t *data, uint16_t len) { - struct gap_read_controller_index_list_rp *rp; - uint8_t buf[sizeof(*rp) + 1]; + struct btp_gap_read_controller_index_list_rp *rp; + uint8_t buf[sizeof(*rp) + 1]; SYS_LOG_DBG(""); @@ -172,15 +172,15 @@ controller_index_list(uint8_t *data, uint16_t len) rp->num = 1; rp->index[0] = CONTROLLER_INDEX; - tester_send(BTP_SERVICE_ID_GAP, GAP_READ_CONTROLLER_INDEX_LIST, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_READ_CONTROLLER_INDEX_LIST, BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); } static void controller_info(uint8_t *data, uint16_t len) { - struct gap_read_controller_info_rp rp; - uint32_t supported_settings = 0; + struct btp_gap_read_controller_info_rp rp; + uint32_t supported_settings = 0; ble_addr_t addr; int rc; @@ -207,33 +207,33 @@ controller_info(uint8_t *data, uint16_t len) } else { own_addr_type = BLE_OWN_ADDR_RPA_RANDOM_DEFAULT; } - current_settings |= BIT(GAP_SETTINGS_PRIVACY); - supported_settings |= BIT(GAP_SETTINGS_PRIVACY); + current_settings |= BIT(BTP_GAP_SETTINGS_PRIVACY); + supported_settings |= BIT(BTP_GAP_SETTINGS_PRIVACY); memcpy(rp.address, addr.val, sizeof(rp.address)); } else { rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, rp.address, NULL); if (rc) { own_addr_type = BLE_OWN_ADDR_RANDOM; memcpy(rp.address, addr.val, sizeof(rp.address)); - supported_settings |= BIT(GAP_SETTINGS_STATIC_ADDRESS); - current_settings |= BIT(GAP_SETTINGS_STATIC_ADDRESS); + supported_settings |= BIT(BTP_GAP_SETTINGS_STATIC_ADDRESS); + current_settings |= BIT(BTP_GAP_SETTINGS_STATIC_ADDRESS); } else { own_addr_type = BLE_OWN_ADDR_PUBLIC; } } - supported_settings |= BIT(GAP_SETTINGS_POWERED); - supported_settings |= BIT(GAP_SETTINGS_CONNECTABLE); - supported_settings |= BIT(GAP_SETTINGS_BONDABLE); - supported_settings |= BIT(GAP_SETTINGS_LE); - supported_settings |= BIT(GAP_SETTINGS_ADVERTISING); - supported_settings |= BIT(GAP_SETTINGS_SC); + supported_settings |= BIT(BTP_GAP_SETTINGS_POWERED); + supported_settings |= BIT(BTP_GAP_SETTINGS_CONNECTABLE); + supported_settings |= BIT(BTP_GAP_SETTINGS_BONDABLE); + supported_settings |= BIT(BTP_GAP_SETTINGS_LE); + supported_settings |= BIT(BTP_GAP_SETTINGS_ADVERTISING); + supported_settings |= BIT(BTP_GAP_SETTINGS_SC); if (ble_hs_cfg.sm_bonding) { - current_settings |= BIT(GAP_SETTINGS_BONDABLE); + current_settings |= BIT(BTP_GAP_SETTINGS_BONDABLE); } if (ble_hs_cfg.sm_sc) { - current_settings |= BIT(GAP_SETTINGS_SC); + current_settings |= BIT(BTP_GAP_SETTINGS_SC); } rp.supported_settings = sys_cpu_to_le32(supported_settings); @@ -241,7 +241,7 @@ controller_info(uint8_t *data, uint16_t len) memcpy(rp.name, CONTROLLER_NAME, sizeof(CONTROLLER_NAME)); - tester_send(BTP_SERVICE_ID_GAP, GAP_READ_CONTROLLER_INFO, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_READ_CONTROLLER_INFO, CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); } @@ -285,22 +285,22 @@ static void rotate_nrpa_cb(struct os_event *ev) static void set_connectable(uint8_t *data, uint16_t len) { - const struct gap_set_connectable_cmd *cmd = (void *) data; - struct gap_set_connectable_rp rp; + const struct btp_gap_set_connectable_cmd *cmd = (void *) data; + struct btp_gap_set_connectable_rp rp; SYS_LOG_DBG(""); if (cmd->connectable) { - current_settings |= BIT(GAP_SETTINGS_CONNECTABLE); + current_settings |= BIT(BTP_GAP_SETTINGS_CONNECTABLE); adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; } else { - current_settings &= ~BIT(GAP_SETTINGS_CONNECTABLE); + current_settings &= ~BIT(BTP_GAP_SETTINGS_CONNECTABLE); adv_params.conn_mode = BLE_GAP_CONN_MODE_NON; } rp.current_settings = sys_cpu_to_le32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, GAP_SET_CONNECTABLE, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_SET_CONNECTABLE, CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); } @@ -309,59 +309,59 @@ static uint8_t ad_flags = BLE_HS_ADV_F_BREDR_UNSUP; static void set_discoverable(uint8_t *data, uint16_t len) { - const struct gap_set_discoverable_cmd *cmd = (void *) data; - struct gap_set_discoverable_rp rp; + const struct btp_gap_set_discoverable_cmd *cmd = (void *) data; + struct btp_gap_set_discoverable_rp rp; SYS_LOG_DBG(""); switch (cmd->discoverable) { - case GAP_NON_DISCOVERABLE: + case BTP_GAP_NON_DISCOVERABLE: ad_flags &= ~(BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_DISC_LTD); adv_params.disc_mode = BLE_GAP_DISC_MODE_NON; - current_settings &= ~BIT(GAP_SETTINGS_DISCOVERABLE); + current_settings &= ~BIT(BTP_GAP_SETTINGS_DISCOVERABLE); break; - case GAP_GENERAL_DISCOVERABLE: + case BTP_GAP_GENERAL_DISCOVERABLE: ad_flags &= ~BLE_HS_ADV_F_DISC_LTD; ad_flags |= BLE_HS_ADV_F_DISC_GEN; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; - current_settings |= BIT(GAP_SETTINGS_DISCOVERABLE); + current_settings |= BIT(BTP_GAP_SETTINGS_DISCOVERABLE); break; - case GAP_LIMITED_DISCOVERABLE: + case BTP_GAP_LIMITED_DISCOVERABLE: ad_flags &= ~BLE_HS_ADV_F_DISC_GEN; ad_flags |= BLE_HS_ADV_F_DISC_LTD; adv_params.disc_mode = BLE_GAP_DISC_MODE_LTD; - current_settings |= BIT(GAP_SETTINGS_DISCOVERABLE); + current_settings |= BIT(BTP_GAP_SETTINGS_DISCOVERABLE); break; default: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_DISCOVERABLE, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_SET_DISCOVERABLE, CONTROLLER_INDEX, BTP_STATUS_FAILED); return; } rp.current_settings = sys_cpu_to_le32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, GAP_SET_DISCOVERABLE, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_SET_DISCOVERABLE, CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); } static void set_bondable(const uint8_t *data, uint16_t len) { - const struct gap_set_bondable_cmd *cmd = (void *) data; - struct gap_set_bondable_rp rp; + const struct btp_gap_set_bondable_cmd *cmd = (void *) data; + struct btp_gap_set_bondable_rp rp; SYS_LOG_DBG(""); ble_hs_cfg.sm_bonding = cmd->bondable; if (ble_hs_cfg.sm_bonding) { - current_settings |= BIT(GAP_SETTINGS_BONDABLE); + current_settings |= BIT(BTP_GAP_SETTINGS_BONDABLE); } else { - current_settings &= ~BIT(GAP_SETTINGS_BONDABLE); + current_settings &= ~BIT(BTP_GAP_SETTINGS_BONDABLE); } rp.current_settings = sys_cpu_to_le32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, GAP_SET_BONDABLE, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_SET_BONDABLE, CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); } @@ -391,9 +391,9 @@ set_ad(const struct bt_data *ad, size_t ad_len, static void start_advertising(const uint8_t *data, uint16_t len) { - const struct gap_start_advertising_cmd *cmd = (void *) data; - struct gap_start_advertising_rp rp; - int32_t duration_ms = BLE_HS_FOREVER; + const struct btp_gap_start_advertising_cmd *cmd = (void *) data; + struct btp_gap_start_advertising_rp rp; + int32_t duration_ms = BLE_HS_FOREVER; uint8_t buf[BLE_HS_ADV_MAX_SZ]; uint8_t buf_len = 0; uint8_t adv_len, sd_len; @@ -471,34 +471,34 @@ start_advertising(const uint8_t *data, uint16_t len) goto fail; } - current_settings |= BIT(GAP_SETTINGS_ADVERTISING); + current_settings |= BIT(BTP_GAP_SETTINGS_ADVERTISING); rp.current_settings = sys_cpu_to_le32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, GAP_START_ADVERTISING, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_START_ADVERTISING, CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); return; fail: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_ADVERTISING, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_START_ADVERTISING, CONTROLLER_INDEX, BTP_STATUS_FAILED); } static void stop_advertising(const uint8_t *data, uint16_t len) { - struct gap_stop_advertising_rp rp; + struct btp_gap_stop_advertising_rp rp; SYS_LOG_DBG(""); if (ble_gap_adv_stop() != 0) { - tester_rsp(BTP_SERVICE_ID_GAP, GAP_STOP_ADVERTISING, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_STOP_ADVERTISING, CONTROLLER_INDEX, BTP_STATUS_FAILED); return; } - current_settings &= ~BIT(GAP_SETTINGS_ADVERTISING); + current_settings &= ~BIT(BTP_GAP_SETTINGS_ADVERTISING); rp.current_settings = sys_cpu_to_le32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, GAP_STOP_ADVERTISING, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_STOP_ADVERTISING, CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); } @@ -537,7 +537,7 @@ static void store_adv(const ble_addr_t *addr, int8_t rssi, const uint8_t *data, uint8_t len) { - struct gap_device_found_ev *ev; + struct btp_gap_device_found_ev *ev; /* cleanup */ net_buf_simple_init(adv_buf, 0); @@ -547,7 +547,7 @@ store_adv(const ble_addr_t *addr, int8_t rssi, memcpy(ev->address, addr->val, sizeof(ev->address)); ev->address_type = addr->type; ev->rssi = rssi; - ev->flags = GAP_DEVICE_FOUND_FLAG_AD | GAP_DEVICE_FOUND_FLAG_RSSI; + ev->flags = BTP_GAP_DEVICE_FOUND_FLAG_AD | BTP_GAP_DEVICE_FOUND_FLAG_RSSI; ev->eir_data_len = len; memcpy(net_buf_simple_add(adv_buf, len), data, len); } @@ -556,11 +556,11 @@ static void device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, const uint8_t *data, uint8_t len) { - struct gap_device_found_ev *ev; - ble_addr_t a; + struct btp_gap_device_found_ev *ev; + ble_addr_t a; /* if General/Limited Discovery - parse Advertising data to get flags */ - if (!(discovery_flags & GAP_DISCOVERY_FLAG_LE_OBSERVE) && + if (!(discovery_flags & BTP_GAP_DISCOVERY_FLAG_LE_OBSERVE) && (evtype != BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP)) { uint8_t flags = get_ad_flags(data, len); @@ -571,7 +571,7 @@ device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, } /* if Limited Discovery - ignore general discoverable devices */ - if ((discovery_flags & GAP_DISCOVERY_FLAG_LIMITED) && + if ((discovery_flags & BTP_GAP_DISCOVERY_FLAG_LIMITED) && !(flags & BLE_HS_ADV_F_DISC_LTD)) { SYS_LOG_DBG("General discoverable, skipping"); return; @@ -601,7 +601,7 @@ device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, } ev->eir_data_len += len; - ev->flags |= GAP_DEVICE_FOUND_FLAG_SD; + ev->flags |= BTP_GAP_DEVICE_FOUND_FLAG_SD; memcpy(net_buf_simple_add(adv_buf, len), data, len); @@ -613,7 +613,7 @@ device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, * current one */ if (adv_buf->om_len) { - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_FOUND, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_FOUND, CONTROLLER_INDEX, adv_buf->om_data, adv_buf->om_len); } @@ -621,14 +621,14 @@ device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, store_adv(addr, rssi, data, len); /* if Active Scan and scannable event - wait for Scan Response */ - if ((discovery_flags & GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN) && + if ((discovery_flags & BTP_GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN) && (evtype == BLE_HCI_ADV_RPT_EVTYPE_ADV_IND || evtype == BLE_HCI_ADV_RPT_EVTYPE_SCAN_IND)) { SYS_LOG_DBG("Waiting for scan response"); return; } done: - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_FOUND, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_FOUND, CONTROLLER_INDEX, adv_buf->om_data, adv_buf->om_len); } @@ -647,20 +647,20 @@ discovery_cb(struct ble_gap_event *event, void *arg) static void start_discovery(const uint8_t *data, uint16_t len) { - const struct gap_start_discovery_cmd *cmd = (void *) data; - struct ble_gap_disc_params params = {0}; + const struct btp_gap_start_discovery_cmd *cmd = (void *) data; + struct ble_gap_disc_params params = {0}; uint8_t status; SYS_LOG_DBG(""); /* only LE scan is supported */ - if (cmd->flags & GAP_DISCOVERY_FLAG_BREDR) { + if (cmd->flags & BTP_GAP_DISCOVERY_FLAG_BREDR) { status = BTP_STATUS_FAILED; goto reply; } - params.passive = (cmd->flags & GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN) == 0; - params.limited = (cmd->flags & GAP_DISCOVERY_FLAG_LIMITED) > 0; + params.passive = (cmd->flags & BTP_GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN) == 0; + params.limited = (cmd->flags & BTP_GAP_DISCOVERY_FLAG_LIMITED) > 0; params.filter_duplicates = 1; if (ble_gap_disc(own_addr_type, BLE_HS_FOREVER, @@ -674,7 +674,7 @@ start_discovery(const uint8_t *data, uint16_t len) status = BTP_STATUS_SUCCESS; reply: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_DISCOVERY, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_START_DISCOVERY, CONTROLLER_INDEX, status); } @@ -689,7 +689,7 @@ stop_discovery(const uint8_t *data, uint16_t len) status = BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_GAP, GAP_STOP_DISCOVERY, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_STOP_DISCOVERY, CONTROLLER_INDEX, status); } @@ -728,12 +728,12 @@ device_connected_ev_send(struct os_event *ev) rc = gap_conn_find_by_addr((ble_addr_t *) &connected_ev, &desc); if (rc) { - tester_rsp(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_CONNECTED, CONTROLLER_INDEX, BTP_STATUS_FAILED); return; } - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_CONNECTED, CONTROLLER_INDEX, (uint8_t *) &connected_ev, sizeof(connected_ev)); @@ -774,7 +774,7 @@ le_connected(uint16_t conn_handle, int status) os_time_ms_to_ticks32( CONNECTED_EV_DELAY_MS(desc.conn_itvl))); #else - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_CONNECTED, CONTROLLER_INDEX, (uint8_t *) &connected_ev, sizeof(connected_ev)); #endif @@ -783,8 +783,8 @@ le_connected(uint16_t conn_handle, int status) static void le_disconnected(struct ble_gap_conn_desc *conn, int reason) { - struct gap_device_disconnected_ev ev; - ble_addr_t *addr = &conn->peer_ota_addr; + struct btp_gap_device_disconnected_ev ev; + ble_addr_t *addr = &conn->peer_ota_addr; SYS_LOG_DBG(""); @@ -818,7 +818,7 @@ le_disconnected(struct ble_gap_conn_desc *conn, int reason) memcpy(ev.address, addr->val, sizeof(ev.address)); ev.address_type = addr->type; - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_DISCONNECTED, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_DISCONNECTED, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } @@ -846,9 +846,9 @@ auth_passkey_oob(uint16_t conn_handle) static void auth_passkey_display(uint16_t conn_handle, unsigned int passkey) { - struct ble_gap_conn_desc desc; - struct gap_passkey_display_ev ev; - ble_addr_t *addr; + struct ble_gap_conn_desc desc; + struct btp_gap_passkey_display_ev ev; + ble_addr_t *addr; struct ble_sm_io pk; int rc; @@ -874,16 +874,16 @@ auth_passkey_display(uint16_t conn_handle, unsigned int passkey) ev.address_type = addr->type; ev.passkey = sys_cpu_to_le32(pk.passkey); - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_DISPLAY, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_DISPLAY, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } static void auth_passkey_entry(uint16_t conn_handle) { - struct ble_gap_conn_desc desc; - struct gap_passkey_entry_req_ev ev; - ble_addr_t *addr; + struct ble_gap_conn_desc desc; + struct btp_gap_passkey_entry_req_ev ev; + ble_addr_t *addr; int rc; SYS_LOG_DBG(""); @@ -898,16 +898,16 @@ auth_passkey_entry(uint16_t conn_handle) memcpy(ev.address, addr->val, sizeof(ev.address)); ev.address_type = addr->type; - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_ENTRY_REQ, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_ENTRY_REQ, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } static void auth_passkey_numcmp(uint16_t conn_handle, unsigned int passkey) { - struct ble_gap_conn_desc desc; - struct gap_passkey_confirm_req_ev ev; - ble_addr_t *addr; + struct ble_gap_conn_desc desc; + struct btp_gap_passkey_confirm_req_ev ev; + ble_addr_t *addr; int rc; SYS_LOG_DBG(""); @@ -923,7 +923,7 @@ auth_passkey_numcmp(uint16_t conn_handle, unsigned int passkey) ev.address_type = addr->type; ev.passkey = sys_cpu_to_le32(passkey); - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_CONFIRM_REQ, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_CONFIRM_REQ, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } @@ -984,9 +984,9 @@ le_passkey_action(uint16_t conn_handle, static void le_identity_resolved(uint16_t conn_handle) { - struct ble_gap_conn_desc desc; - struct gap_identity_resolved_ev ev; - int rc; + struct ble_gap_conn_desc desc; + struct btp_gap_identity_resolved_ev ev; + int rc; SYS_LOG_DBG(""); @@ -1005,16 +1005,16 @@ le_identity_resolved(uint16_t conn_handle) memcpy(ev.identity_address, desc.peer_id_addr.val, sizeof(ev.identity_address)); - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_IDENTITY_RESOLVED, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_IDENTITY_RESOLVED, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } static void le_pairing_failed(uint16_t conn_handle, int reason) { - struct ble_gap_conn_desc desc; - struct gap_sec_pairing_failed_ev ev; - int rc; + struct ble_gap_conn_desc desc; + struct btp_gap_sec_pairing_failed_ev ev; + int rc; SYS_LOG_DBG(""); @@ -1031,14 +1031,14 @@ le_pairing_failed(uint16_t conn_handle, int reason) ev.reason = reason; - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_SEC_PAIRING_FAILED, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_SEC_PAIRING_FAILED, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } static void le_conn_param_update(struct ble_gap_conn_desc *desc) { - struct gap_conn_param_update_ev ev; + struct btp_gap_conn_param_update_ev ev; SYS_LOG_DBG(""); @@ -1049,14 +1049,14 @@ le_conn_param_update(struct ble_gap_conn_desc *desc) ev.conn_latency = desc->conn_latency; ev.supervision_timeout = desc->supervision_timeout; - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_CONN_PARAM_UPDATE, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_CONN_PARAM_UPDATE, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } static void le_encryption_changed(struct ble_gap_conn_desc *desc) { - struct gap_sec_level_changed_ev ev; + struct btp_gap_sec_level_changed_ev ev; SYS_LOG_DBG(""); @@ -1078,15 +1078,15 @@ le_encryption_changed(struct ble_gap_conn_desc *desc) } } - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_SEC_LEVEL_CHANGED, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_SEC_LEVEL_CHANGED, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } static void bond_lost(uint16_t conn_handle) { - struct gap_bond_lost_ev ev; - struct ble_gap_conn_desc desc; + struct btp_gap_bond_lost_ev ev; + struct ble_gap_conn_desc desc; int rc; rc = ble_gap_conn_find(conn_handle, &desc); @@ -1095,7 +1095,7 @@ bond_lost(uint16_t conn_handle) memcpy(ev.address, &desc.peer_id_addr, sizeof(ev.address)); ev.address_type = desc.peer_id_addr.type; tester_send(BTP_SERVICE_ID_GAP, - GAP_EV_BOND_LOST, + BTP_GAP_EV_BOND_LOST, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); @@ -1166,12 +1166,12 @@ print_conn_desc(const struct ble_gap_conn_desc *desc) static void adv_complete(void) { - struct gap_new_settings_ev ev; + struct btp_gap_new_settings_ev ev; - current_settings &= ~BIT(GAP_SETTINGS_ADVERTISING); + current_settings &= ~BIT(BTP_GAP_SETTINGS_ADVERTISING); ev.current_settings = sys_cpu_to_le32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, GAP_EV_NEW_SETTINGS, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_NEW_SETTINGS, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } @@ -1372,7 +1372,7 @@ connect(const uint8_t *data, uint16_t len) status = BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_GAP, GAP_CONNECT, CONTROLLER_INDEX, status); + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_CONNECT, CONTROLLER_INDEX, status); } static void @@ -1397,36 +1397,36 @@ disconnect(const uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_DISCONNECT, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_DISCONNECT, CONTROLLER_INDEX, status); } static void set_io_cap(const uint8_t *data, uint16_t len) { - const struct gap_set_io_cap_cmd *cmd = (void *) data; - uint8_t status; + const struct btp_gap_set_io_cap_cmd *cmd = (void *) data; + uint8_t status; SYS_LOG_DBG(""); switch (cmd->io_cap) { - case GAP_IO_CAP_DISPLAY_ONLY: + case BTP_GAP_IO_CAP_DISPLAY_ONLY: ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_DISP_ONLY; ble_hs_cfg.sm_mitm = 1; break; - case GAP_IO_CAP_KEYBOARD_DISPLAY: + case BTP_GAP_IO_CAP_KEYBOARD_DISPLAY: ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_KEYBOARD_DISP; ble_hs_cfg.sm_mitm = 1; break; - case GAP_IO_CAP_NO_INPUT_OUTPUT: + case BTP_GAP_IO_CAP_NO_INPUT_OUTPUT: ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_NO_IO; ble_hs_cfg.sm_mitm = 0; break; - case GAP_IO_CAP_KEYBOARD_ONLY: + case BTP_GAP_IO_CAP_KEYBOARD_ONLY: ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_KEYBOARD_ONLY; ble_hs_cfg.sm_mitm = 1; break; - case GAP_IO_CAP_DISPLAY_YESNO: + case BTP_GAP_IO_CAP_DISPLAY_YESNO: ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_DISP_YES_NO; ble_hs_cfg.sm_mitm = 1; break; @@ -1438,7 +1438,7 @@ set_io_cap(const uint8_t *data, uint16_t len) status = BTP_STATUS_SUCCESS; rsp: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_IO_CAP, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_SET_IO_CAP, CONTROLLER_INDEX, status); } @@ -1466,7 +1466,7 @@ pair(const uint8_t *data, uint16_t len) status = BTP_STATUS_SUCCESS; rsp: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_PAIR, CONTROLLER_INDEX, status); + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_PAIR, CONTROLLER_INDEX, status); } static void @@ -1479,14 +1479,14 @@ unpair(const uint8_t *data, uint16_t len) err = ble_gap_unpair((ble_addr_t *) data); status = (uint8_t) (err != 0 ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); - tester_rsp(BTP_SERVICE_ID_GAP, GAP_UNPAIR, CONTROLLER_INDEX, status); + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_UNPAIR, CONTROLLER_INDEX, status); } static void passkey_entry(const uint8_t *data, uint16_t len) { - const struct gap_passkey_entry_cmd *cmd = (void *) data; - struct ble_gap_conn_desc desc; + const struct btp_gap_passkey_entry_cmd *cmd = (void *) data; + struct ble_gap_conn_desc desc; struct ble_sm_io pk; uint8_t status; int rc; @@ -1511,15 +1511,15 @@ passkey_entry(const uint8_t *data, uint16_t len) status = BTP_STATUS_SUCCESS; rsp: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_PASSKEY_ENTRY, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_PASSKEY_ENTRY, CONTROLLER_INDEX, status); } static void passkey_confirm(const uint8_t *data, uint16_t len) { - const struct gap_passkey_confirm_cmd *cmd = (void *) data; - struct ble_gap_conn_desc desc; + const struct btp_gap_passkey_confirm_cmd *cmd = (void *) data; + struct ble_gap_conn_desc desc; struct ble_sm_io pk; uint8_t status; int rc; @@ -1545,16 +1545,16 @@ passkey_confirm(const uint8_t *data, uint16_t len) status = BTP_STATUS_SUCCESS; rsp: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_PASSKEY_CONFIRM, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_PASSKEY_CONFIRM, CONTROLLER_INDEX, status); } static void start_direct_adv(const uint8_t *data, uint16_t len) { - const struct gap_start_direct_adv_cmd *cmd = (void *) data; - struct gap_start_advertising_rp rp; - static struct ble_gap_adv_params adv_params = { + const struct btp_gap_start_direct_adv_cmd *cmd = (void *) data; + struct btp_gap_start_advertising_rp rp; + static struct ble_gap_adv_params adv_params = { .conn_mode = BLE_GAP_CONN_MODE_DIR, }; int err; @@ -1571,14 +1571,14 @@ start_direct_adv(const uint8_t *data, uint16_t len) goto fail; } - current_settings |= BIT(GAP_SETTINGS_ADVERTISING); + current_settings |= BIT(BTP_GAP_SETTINGS_ADVERTISING); rp.current_settings = sys_cpu_to_le32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, GAP_START_DIRECT_ADV, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_START_DIRECT_ADV, CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); return; fail: - tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_DIRECT_ADV, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_START_DIRECT_ADV, CONTROLLER_INDEX, BTP_STATUS_FAILED); } @@ -1591,7 +1591,7 @@ conn_param_update_cb(uint16_t conn_handle, int status, void *arg) static int conn_param_update_slave(uint16_t conn_handle, - const struct gap_conn_param_update_cmd *cmd) + const struct btp_gap_conn_param_update_cmd *cmd) { int rc; struct ble_l2cap_sig_update_params params; @@ -1612,7 +1612,7 @@ conn_param_update_slave(uint16_t conn_handle, static int conn_param_update_master(uint16_t conn_handle, - const struct gap_conn_param_update_cmd *cmd) + const struct btp_gap_conn_param_update_cmd *cmd) { int rc; struct ble_gap_upd_params params; @@ -1668,69 +1668,69 @@ conn_param_update(struct os_event *ev) static void conn_param_update_async(const uint8_t *data, uint16_t len) { - const struct gap_conn_param_update_cmd *cmd = (void *) data; + const struct btp_gap_conn_param_update_cmd *cmd = (void *) data; update_params = *cmd; os_callout_reset(&update_params_co, 0); - tester_rsp(BTP_SERVICE_ID_GAP, GAP_CONN_PARAM_UPDATE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_CONN_PARAM_UPDATE, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } static void oob_legacy_set_data(const uint8_t *data, uint16_t len) { - const struct gap_oob_legacy_set_data_cmd *cmd = (void *) data; + const struct btp_gap_oob_legacy_set_data_cmd *cmd = (void *) data; ble_hs_cfg.sm_oob_data_flag = 1; memcpy(oob, cmd->oob_data, sizeof(oob)); - tester_rsp(BTP_SERVICE_ID_GAP, GAP_OOB_LEGACY_SET_DATA, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_OOB_LEGACY_SET_DATA, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } static void oob_sc_get_local_data(const uint8_t *data, uint16_t len) { - struct gap_oob_sc_get_local_data_rp rp; + struct btp_gap_oob_sc_get_local_data_rp rp; memcpy(rp.r, oob_data_local.r, 16); memcpy(rp.c, oob_data_local.c, 16); - tester_send(BTP_SERVICE_ID_GAP, GAP_OOB_SC_GET_LOCAL_DATA, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_OOB_SC_GET_LOCAL_DATA, CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); } static void oob_sc_set_remote_data(const uint8_t *data, uint16_t len) { - const struct gap_oob_sc_set_remote_data_cmd *cmd = (void *) data; + const struct btp_gap_oob_sc_set_remote_data_cmd *cmd = (void *) data; ble_hs_cfg.sm_oob_data_flag = 1; memcpy(oob_data_remote.r, cmd->r, 16); memcpy(oob_data_remote.c, cmd->c, 16); - tester_rsp(BTP_SERVICE_ID_GAP, GAP_OOB_SC_SET_REMOTE_DATA, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_OOB_SC_SET_REMOTE_DATA, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } static void set_mitm(const uint8_t *data, uint16_t len) { - const struct gap_set_mitm_cmd *cmd = (void *) data; + const struct btp_gap_set_mitm_cmd *cmd = (void *) data; ble_hs_cfg.sm_mitm = cmd->mitm; - tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_MITM, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_SET_MITM, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } static void set_filter_accept_list(const uint8_t *data, uint16_t len) { - uint8_t status = BTP_STATUS_SUCCESS; - struct gap_set_filter_accept_list_cmd *tmp = - (struct gap_set_filter_accept_list_cmd *) data; + uint8_t status = BTP_STATUS_SUCCESS; + struct btp_gap_set_filter_accept_list_cmd *tmp = + (struct btp_gap_set_filter_accept_list_cmd *) data; SYS_LOG_DBG(""); @@ -1743,7 +1743,7 @@ set_filter_accept_list(const uint8_t *data, uint16_t len) status = BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_GAP, GAP_SET_FILTER_ACCEPT_LIST, + tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_SET_FILTER_ACCEPT_LIST, CONTROLLER_INDEX, status); } @@ -1752,8 +1752,8 @@ tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len) { switch (opcode) { - case GAP_READ_SUPPORTED_COMMANDS: - case GAP_READ_CONTROLLER_INDEX_LIST: + case BTP_GAP_READ_SUPPORTED_COMMANDS: + case BTP_GAP_READ_CONTROLLER_INDEX_LIST: if (index != BTP_INDEX_NONE) { tester_rsp(BTP_SERVICE_ID_GAP, opcode, index, BTP_STATUS_FAILED); @@ -1770,76 +1770,76 @@ tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data, } switch (opcode) { - case GAP_READ_SUPPORTED_COMMANDS: + case BTP_GAP_READ_SUPPORTED_COMMANDS: supported_commands(data, len); return; - case GAP_READ_CONTROLLER_INDEX_LIST: + case BTP_GAP_READ_CONTROLLER_INDEX_LIST: controller_index_list(data, len); return; - case GAP_READ_CONTROLLER_INFO: + case BTP_GAP_READ_CONTROLLER_INFO: controller_info(data, len); return; - case GAP_SET_CONNECTABLE: + case BTP_GAP_SET_CONNECTABLE: set_connectable(data, len); return; - case GAP_SET_DISCOVERABLE: + case BTP_GAP_SET_DISCOVERABLE: set_discoverable(data, len); return; - case GAP_SET_BONDABLE: + case BTP_GAP_SET_BONDABLE: set_bondable(data, len); return; - case GAP_START_ADVERTISING: + case BTP_GAP_START_ADVERTISING: start_advertising(data, len); return; - case GAP_STOP_ADVERTISING: + case BTP_GAP_STOP_ADVERTISING: stop_advertising(data, len); return; - case GAP_START_DISCOVERY: + case BTP_GAP_START_DISCOVERY: start_discovery(data, len); return; - case GAP_STOP_DISCOVERY: + case BTP_GAP_STOP_DISCOVERY: stop_discovery(data, len); return; - case GAP_CONNECT: + case BTP_GAP_CONNECT: connect(data, len); return; - case GAP_DISCONNECT: + case BTP_GAP_DISCONNECT: disconnect(data, len); return; - case GAP_SET_IO_CAP: + case BTP_GAP_SET_IO_CAP: set_io_cap(data, len); return; - case GAP_PAIR: + case BTP_GAP_PAIR: pair(data, len); return; - case GAP_UNPAIR: + case BTP_GAP_UNPAIR: unpair(data, len); return; - case GAP_PASSKEY_ENTRY: + case BTP_GAP_PASSKEY_ENTRY: passkey_entry(data, len); return; - case GAP_PASSKEY_CONFIRM: + case BTP_GAP_PASSKEY_CONFIRM: passkey_confirm(data, len); return; - case GAP_START_DIRECT_ADV: + case BTP_GAP_START_DIRECT_ADV: start_direct_adv(data, len); return; - case GAP_CONN_PARAM_UPDATE: + case BTP_GAP_CONN_PARAM_UPDATE: conn_param_update_async(data, len); return; - case GAP_OOB_LEGACY_SET_DATA: + case BTP_GAP_OOB_LEGACY_SET_DATA: oob_legacy_set_data(data, len); return; - case GAP_OOB_SC_GET_LOCAL_DATA: + case BTP_GAP_OOB_SC_GET_LOCAL_DATA: oob_sc_get_local_data(data, len); return; - case GAP_OOB_SC_SET_REMOTE_DATA: + case BTP_GAP_OOB_SC_SET_REMOTE_DATA: oob_sc_set_remote_data(data, len); return; - case GAP_SET_MITM: + case BTP_GAP_SET_MITM: set_mitm(data, len); return; - case GAP_SET_FILTER_ACCEPT_LIST: + case BTP_GAP_SET_FILTER_ACCEPT_LIST: set_filter_accept_list(data, len); return; default: @@ -1853,14 +1853,14 @@ static void tester_init_gap_cb(int err) { if (err) { - tester_rsp(BTP_SERVICE_ID_CORE, CORE_REGISTER_SERVICE, + tester_rsp(BTP_SERVICE_ID_CORE, BTP_CORE_REGISTER_SERVICE, BTP_INDEX_NONE, BTP_STATUS_FAILED); return; } current_settings = 0; - current_settings |= BIT(GAP_SETTINGS_POWERED); - current_settings |= BIT(GAP_SETTINGS_LE); + current_settings |= BIT(BTP_GAP_SETTINGS_POWERED); + current_settings |= BIT(BTP_GAP_SETTINGS_LE); os_callout_init(&update_params_co, os_eventq_dflt_get(), conn_param_update, NULL); @@ -1868,7 +1868,7 @@ tester_init_gap_cb(int err) os_callout_init(&connected_ev_co, os_eventq_dflt_get(), device_connected_ev_send, NULL); - tester_rsp(BTP_SERVICE_ID_CORE, CORE_REGISTER_SERVICE, BTP_INDEX_NONE, + tester_rsp(BTP_SERVICE_ID_CORE, BTP_CORE_REGISTER_SERVICE, BTP_INDEX_NONE, BTP_STATUS_SUCCESS); } diff --git a/apps/bttester/src/gatt.c b/apps/bttester/src/btp_gatt.c similarity index 85% rename from apps/bttester/src/gatt.c rename to apps/bttester/src/btp_gatt.c index dd7dadb4a5..d3b826f53b 100644 --- a/apps/bttester/src/gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -36,7 +36,7 @@ #include "../../../nimble/host/src/ble_att_priv.h" #include "../../../nimble/host/src/ble_gatt_priv.h" -#include "bttester.h" +#include "btp/btp.h" #define CONTROLLER_INDEX 0 #define MAX_BUFFER_SIZE 2048 @@ -255,8 +255,8 @@ static const struct ble_gatt_svc_def gatt_svr_svcs[] = { static void attr_value_changed_ev(uint16_t handle, struct os_mbuf *data) { - struct gatt_attr_value_changed_ev *ev; - struct os_mbuf *buf = os_msys_get(0, 0); + struct btp_gatt_attr_value_changed_ev *ev; + struct os_mbuf *buf = os_msys_get(0, 0); SYS_LOG_DBG(""); @@ -267,7 +267,7 @@ attr_value_changed_ev(uint16_t handle, struct os_mbuf *data) ev->data_length = sys_cpu_to_le16(os_mbuf_len(data)); os_mbuf_appendfrom(buf, data, 0, os_mbuf_len(data)); - tester_send_buf(BTP_SERVICE_ID_GATT, GATT_EV_ATTR_VALUE_CHANGED, + tester_send_buf(BTP_SERVICE_ID_GATT, BTP_GATT_EV_ATTR_VALUE_CHANGED, CONTROLLER_INDEX, buf); } @@ -572,7 +572,7 @@ gatt_svr_rel_write_test(uint16_t conn_handle, uint16_t attr_handle, static void start_server(uint8_t *data, uint16_t len) { - struct gatt_start_server_rp rp; + struct btp_gatt_start_server_rp rp; SYS_LOG_DBG(""); @@ -583,7 +583,7 @@ start_server(uint8_t *data, uint16_t len) rp.db_attr_off = 0; rp.db_attr_cnt = 0; - tester_send(BTP_SERVICE_ID_GATT, GATT_START_SERVER, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_START_SERVER, CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); } @@ -672,8 +672,8 @@ read_cb(uint16_t conn_handle, struct ble_gatt_attr *attr, void *arg) { - struct gatt_read_rp *rp = (void *) gatt_buf.buf; - uint8_t btp_opcode = (uint8_t) (int) arg; + struct btp_gatt_read_rp *rp = (void *) gatt_buf.buf; + uint8_t btp_opcode = (uint8_t) (int) arg; SYS_LOG_DBG("status=%d", error->status); @@ -703,8 +703,8 @@ read_cb(uint16_t conn_handle, static void read(uint8_t *data, uint16_t len) { - const struct gatt_read_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gatt_read_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; int rc; SYS_LOG_DBG(""); @@ -717,12 +717,12 @@ read(uint8_t *data, uint16_t len) /* Clear buffer */ read_destroy(); - if (!gatt_buf_reserve(sizeof(struct gatt_read_rp))) { + if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) { goto fail; } if (ble_gattc_read(conn.conn_handle, sys_le16_to_cpu(cmd->handle), - read_cb, (void *) GATT_READ)) { + read_cb, (void *) BTP_GATT_READ)) { read_destroy(); goto fail; } @@ -730,7 +730,7 @@ read(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_READ, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ, CONTROLLER_INDEX, BTP_STATUS_FAILED); } @@ -740,8 +740,8 @@ read_long_cb(uint16_t conn_handle, struct ble_gatt_attr *attr, void *arg) { - struct gatt_read_rp *rp = (void *) gatt_buf.buf; - uint8_t btp_opcode = (uint8_t) (int) arg; + struct btp_gatt_read_rp *rp = (void *) gatt_buf.buf; + uint8_t btp_opcode = (uint8_t) (int) arg; SYS_LOG_DBG("status=%d", error->status); @@ -775,8 +775,8 @@ read_long_cb(uint16_t conn_handle, static void read_long(uint8_t *data, uint16_t len) { - const struct gatt_read_long_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gatt_read_long_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; int rc; SYS_LOG_DBG(""); @@ -789,14 +789,14 @@ read_long(uint8_t *data, uint16_t len) /* Clear buffer */ read_destroy(); - if (!gatt_buf_reserve(sizeof(struct gatt_read_rp))) { + if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) { goto fail; } if (ble_gattc_read_long(conn.conn_handle, sys_le16_to_cpu(cmd->handle), sys_le16_to_cpu(cmd->offset), - read_long_cb, (void *) GATT_READ_LONG)) { + read_long_cb, (void *) BTP_GATT_READ_LONG)) { read_destroy(); goto fail; } @@ -804,15 +804,15 @@ read_long(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_READ_LONG, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ_LONG, CONTROLLER_INDEX, BTP_STATUS_FAILED); } static void read_multiple(uint8_t *data, uint16_t len) { - const struct gatt_read_multiple_cmd *cmd = (void *) data; - uint16_t handles[cmd->handles_count]; + const struct btp_gatt_read_multiple_cmd *cmd = (void *) data; + uint16_t handles[cmd->handles_count]; struct ble_gap_conn_desc conn; int rc, i; @@ -830,13 +830,13 @@ read_multiple(uint8_t *data, uint16_t len) /* Clear buffer */ read_destroy(); - if (!gatt_buf_reserve(sizeof(struct gatt_read_rp))) { + if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) { goto fail; } if (ble_gattc_read_mult(conn.conn_handle, handles, cmd->handles_count, read_cb, - (void *) GATT_READ_MULTIPLE)) { + (void *) BTP_GATT_READ_MULTIPLE)) { read_destroy(); goto fail; } @@ -844,15 +844,15 @@ read_multiple(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_READ_MULTIPLE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ_MULTIPLE, CONTROLLER_INDEX, BTP_STATUS_FAILED); } static void write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) { - const struct gatt_write_without_rsp_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gatt_write_without_rsp_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -892,8 +892,8 @@ write_rsp(uint16_t conn_handle, const struct ble_gatt_error *error, static void write(uint8_t *data, uint16_t len) { - const struct gatt_write_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gatt_write_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; int rc; SYS_LOG_DBG(""); @@ -905,22 +905,22 @@ write(uint8_t *data, uint16_t len) if (ble_gattc_write_flat(conn.conn_handle, sys_le16_to_cpu(cmd->handle), cmd->data, sys_le16_to_cpu(cmd->data_length), - write_rsp, (void *) GATT_WRITE)) { + write_rsp, (void *) BTP_GATT_WRITE)) { goto fail; } return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_WRITE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE, CONTROLLER_INDEX, BTP_STATUS_FAILED); } static void write_long(uint8_t *data, uint16_t len) { - const struct gatt_write_long_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gatt_write_long_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; struct os_mbuf *om = NULL; int rc = 0; @@ -941,7 +941,7 @@ write_long(uint8_t *data, uint16_t len) sys_le16_to_cpu(cmd->handle), sys_le16_to_cpu(cmd->offset), om, write_rsp, - (void *) GATT_WRITE_LONG); + (void *) BTP_GATT_WRITE_LONG); if (!rc) { return; } @@ -949,7 +949,7 @@ write_long(uint8_t *data, uint16_t len) fail: SYS_LOG_ERR("Failed to send Write Long request, rc=%d", rc); os_mbuf_free_chain(om); - tester_rsp(BTP_SERVICE_ID_GATT, GATT_WRITE_LONG, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE_LONG, CONTROLLER_INDEX, BTP_STATUS_FAILED); } @@ -964,7 +964,7 @@ reliable_write_rsp(uint16_t conn_handle, SYS_LOG_DBG("Reliable write status %d", err); - tester_send(BTP_SERVICE_ID_GATT, GATT_RELIABLE_WRITE, + tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_RELIABLE_WRITE, CONTROLLER_INDEX, &err, sizeof(err)); return 0; } @@ -972,8 +972,8 @@ reliable_write_rsp(uint16_t conn_handle, static void reliable_write(uint8_t *data, uint16_t len) { - const struct gatt_reliable_write_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gatt_reliable_write_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; struct ble_gatt_attr attr; struct os_mbuf *om = NULL; int rc; @@ -1007,7 +1007,7 @@ reliable_write(uint8_t *data, uint16_t len) fail: os_mbuf_free_chain(om); - tester_rsp(BTP_SERVICE_ID_GATT, GATT_WRITE_LONG, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE_LONG, CONTROLLER_INDEX, BTP_STATUS_FAILED); } @@ -1020,8 +1020,8 @@ static struct bt_gatt_subscribe_params { static void read_uuid(uint8_t *data, uint16_t len) { - const struct gatt_read_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gatt_read_uuid_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; ble_uuid_any_t uuid; int rc; @@ -1039,14 +1039,14 @@ read_uuid(uint8_t *data, uint16_t len) /* Clear buffer */ read_destroy(); - if (!gatt_buf_reserve(sizeof(struct gatt_read_rp))) { + if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) { goto fail; } if (ble_gattc_read_by_uuid(conn.conn_handle, sys_le16_to_cpu(cmd->start_handle), sys_le16_to_cpu(cmd->end_handle), &uuid.u, - read_long_cb, (void *) GATT_READ_UUID)) { + read_long_cb, (void *) BTP_GATT_READ_UUID)) { read_destroy(); goto fail; } @@ -1054,7 +1054,7 @@ read_uuid(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_READ, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ, CONTROLLER_INDEX, BTP_STATUS_FAILED); } @@ -1063,9 +1063,9 @@ disc_prim_uuid_cb(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_svc *gatt_svc, void *arg) { - struct gatt_disc_prim_uuid_rp *rp = (void *) gatt_buf.buf; - struct gatt_service *service; - const ble_uuid_any_t *uuid; + struct btp_gatt_disc_prim_uuid_rp *rp = (void *) gatt_buf.buf; + struct btp_gatt_service *service; + const ble_uuid_any_t *uuid; uint8_t uuid_length; uint8_t opcode = (uint8_t) (int) arg; @@ -1120,22 +1120,22 @@ disc_all_desc_cb(uint16_t conn_handle, const struct ble_gatt_dsc *gatt_dsc, void *arg) { - struct gatt_disc_all_desc_rp *rp = (void *) gatt_buf.buf; - struct gatt_descriptor *dsc; - const ble_uuid_any_t *uuid; + struct btp_gatt_disc_all_desc_rp *rp = (void *) gatt_buf.buf; + struct btp_gatt_descriptor *dsc; + const ble_uuid_any_t *uuid; uint8_t uuid_length; SYS_LOG_DBG(""); if (error->status != 0 && error->status != BLE_HS_EDONE) { - tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_DESC, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC, CONTROLLER_INDEX, BTP_STATUS_FAILED); discover_destroy(); return 0; } if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_DESC, + tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC, CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); discover_destroy(); return 0; @@ -1146,7 +1146,7 @@ disc_all_desc_cb(uint16_t conn_handle, dsc = gatt_buf_reserve(sizeof(*dsc) + uuid_length); if (!dsc) { - tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_DESC, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC, CONTROLLER_INDEX, BTP_STATUS_FAILED); discover_destroy(); return BLE_HS_ENOMEM; @@ -1180,12 +1180,12 @@ disc_all_prim_svcs(uint8_t *data, uint16_t len) goto fail; } - if (!gatt_buf_reserve(sizeof(struct gatt_disc_all_prim_svcs_rp))) { + if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_all_prim_svcs_rp))) { goto fail; } if (ble_gattc_disc_all_svcs(conn.conn_handle, disc_prim_uuid_cb, - (void *) GATT_DISC_ALL_PRIM_SVCS)) { + (void *) BTP_GATT_DISC_ALL_PRIM_SVCS)) { discover_destroy(); goto fail; } @@ -1193,15 +1193,15 @@ disc_all_prim_svcs(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_PRIM_SVCS, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_PRIM_SVCS, CONTROLLER_INDEX, BTP_STATUS_FAILED); } static void disc_all_desc(uint8_t *data, uint16_t len) { - const struct gatt_disc_all_desc_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gatt_disc_all_desc_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; int rc; @@ -1212,7 +1212,7 @@ disc_all_desc(uint8_t *data, uint16_t len) goto fail; } - if (!gatt_buf_reserve(sizeof(struct gatt_disc_all_desc_rp))) { + if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_all_desc_rp))) { goto fail; } @@ -1232,7 +1232,7 @@ disc_all_desc(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_DESC, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC, CONTROLLER_INDEX, BTP_STATUS_FAILED); } @@ -1241,23 +1241,23 @@ find_included_cb(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_svc *gatt_svc, void *arg) { - struct gatt_find_included_rp *rp = (void *) gatt_buf.buf; - struct gatt_included *included; - const ble_uuid_any_t *uuid; + struct btp_gatt_find_included_rp *rp = (void *) gatt_buf.buf; + struct btp_gatt_included *included; + const ble_uuid_any_t *uuid; int service_handle = (int) arg; uint8_t uuid_length; SYS_LOG_DBG(""); if (error->status != 0 && error->status != BLE_HS_EDONE) { - tester_rsp(BTP_SERVICE_ID_GATT, GATT_FIND_INCLUDED, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, CONTROLLER_INDEX, BTP_STATUS_FAILED); discover_destroy(); return 0; } if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, GATT_FIND_INCLUDED, + tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); discover_destroy(); return 0; @@ -1268,7 +1268,7 @@ find_included_cb(uint16_t conn_handle, included = gatt_buf_reserve(sizeof(*included) + uuid_length); if (!included) { - tester_rsp(BTP_SERVICE_ID_GATT, GATT_FIND_INCLUDED, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, CONTROLLER_INDEX, BTP_STATUS_FAILED); discover_destroy(); return BLE_HS_ENOMEM; @@ -1299,9 +1299,9 @@ disc_chrc_cb(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_chr *gatt_chr, void *arg) { - struct gatt_disc_chrc_rp *rp = (void *) gatt_buf.buf; - struct gatt_characteristic *chrc; - const ble_uuid_any_t *uuid; + struct btp_gatt_disc_chrc_rp *rp = (void *) gatt_buf.buf; + struct btp_gatt_characteristic *chrc; + const ble_uuid_any_t *uuid; uint8_t btp_opcode = (uint8_t) (int) arg; uint8_t uuid_length; @@ -1353,8 +1353,8 @@ disc_chrc_cb(uint16_t conn_handle, static void disc_chrc_uuid(uint8_t *data, uint16_t len) { - const struct gatt_disc_chrc_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gatt_disc_chrc_uuid_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; ble_uuid_any_t uuid; int rc; @@ -1370,7 +1370,7 @@ disc_chrc_uuid(uint8_t *data, uint16_t len) goto fail; } - if (!gatt_buf_reserve(sizeof(struct gatt_disc_chrc_rp))) { + if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_chrc_rp))) { goto fail; } @@ -1379,7 +1379,7 @@ disc_chrc_uuid(uint8_t *data, uint16_t len) if (ble_gattc_disc_chrs_by_uuid(conn.conn_handle, start_handle, end_handle, &uuid.u, disc_chrc_cb, - (void *) GATT_DISC_CHRC_UUID)) { + (void *) BTP_GATT_DISC_CHRC_UUID)) { discover_destroy(); goto fail; } @@ -1387,15 +1387,15 @@ disc_chrc_uuid(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_CHRC_UUID, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_CHRC_UUID, CONTROLLER_INDEX, BTP_STATUS_FAILED); } static void disc_prim_uuid(uint8_t *data, uint16_t len) { - const struct gatt_disc_prim_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gatt_disc_prim_uuid_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; ble_uuid_any_t uuid; int rc; @@ -1410,13 +1410,13 @@ disc_prim_uuid(uint8_t *data, uint16_t len) goto fail; } - if (!gatt_buf_reserve(sizeof(struct gatt_disc_prim_uuid_rp))) { + if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_prim_uuid_rp))) { goto fail; } if (ble_gattc_disc_svc_by_uuid(conn.conn_handle, &uuid.u, disc_prim_uuid_cb, - (void *) GATT_DISC_PRIM_UUID)) { + (void *) BTP_GATT_DISC_PRIM_UUID)) { discover_destroy(); goto fail; } @@ -1424,15 +1424,15 @@ disc_prim_uuid(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_PRIM_UUID, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_PRIM_UUID, CONTROLLER_INDEX, BTP_STATUS_FAILED); } static void disc_all_chrc(uint8_t *data, uint16_t len) { - const struct gatt_disc_all_chrc_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gatt_disc_all_chrc_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; int rc; @@ -1444,7 +1444,7 @@ disc_all_chrc(uint8_t *data, uint16_t len) goto fail; } - if (!gatt_buf_reserve(sizeof(struct gatt_disc_chrc_rp))) { + if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_chrc_rp))) { SYS_LOG_DBG("Buf reserve failed"); goto fail; } @@ -1453,7 +1453,7 @@ disc_all_chrc(uint8_t *data, uint16_t len) end_handle = sys_le16_to_cpu(cmd->end_handle); rc = ble_gattc_disc_all_chrs(conn.conn_handle, start_handle, end_handle, - disc_chrc_cb, (void *) GATT_DISC_ALL_CHRC); + disc_chrc_cb, (void *) BTP_GATT_DISC_ALL_CHRC); if (rc) { discover_destroy(); goto fail; @@ -1462,15 +1462,15 @@ disc_all_chrc(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_DISC_ALL_CHRC, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_CHRC, CONTROLLER_INDEX, BTP_STATUS_FAILED); } static void find_included(uint8_t *data, uint16_t len) { - const struct gatt_find_included_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gatt_find_included_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; int service_handle_arg; int rc; @@ -1482,7 +1482,7 @@ find_included(uint8_t *data, uint16_t len) goto fail; } - if (!gatt_buf_reserve(sizeof(struct gatt_find_included_rp))) { + if (!gatt_buf_reserve(sizeof(struct btp_gatt_find_included_rp))) { goto fail; } @@ -1500,7 +1500,7 @@ find_included(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_FIND_INCLUDED, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, CONTROLLER_INDEX, BTP_STATUS_FAILED); } @@ -1512,13 +1512,13 @@ exchange_func(uint16_t conn_handle, SYS_LOG_DBG(""); if (error->status) { - tester_rsp(BTP_SERVICE_ID_GATT, GATT_EXCHANGE_MTU, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_EXCHANGE_MTU, CONTROLLER_INDEX, BTP_STATUS_FAILED); return 0; } - tester_rsp(BTP_SERVICE_ID_GATT, GATT_EXCHANGE_MTU, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_EXCHANGE_MTU, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); return 0; @@ -1543,7 +1543,7 @@ exchange_mtu(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_EXCHANGE_MTU, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_EXCHANGE_MTU, CONTROLLER_INDEX, BTP_STATUS_FAILED); } @@ -1555,7 +1555,7 @@ enable_subscription(uint16_t conn_handle, uint16_t ccc_handle, SYS_LOG_DBG(""); - op = (uint8_t) (value == 0x0001 ? GATT_CFG_NOTIFY : GATT_CFG_INDICATE); + op = (uint8_t) (value == 0x0001 ? BTP_GATT_CFG_NOTIFY : BTP_GATT_CFG_INDICATE); if (ble_gattc_write_flat(conn_handle, ccc_handle, &value, sizeof(value), NULL, NULL)) { @@ -1594,8 +1594,8 @@ disable_subscription(uint16_t conn_handle, uint16_t ccc_handle) static void config_subscription(uint8_t *data, uint16_t len, uint8_t op) { - const struct gatt_cfg_notify_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gatt_cfg_notify_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; uint16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle); uint8_t status; int rc; @@ -1612,7 +1612,7 @@ config_subscription(uint8_t *data, uint16_t len, uint8_t op) if (cmd->enable) { uint16_t value; - if (op == GATT_CFG_NOTIFY) { + if (op == BTP_GATT_CFG_NOTIFY) { value = 0x0001; } else { value = 0x0002; @@ -1676,10 +1676,10 @@ flags_hs2btp(uint8_t flags) static void get_attrs(uint8_t *data, uint16_t len) { - const struct gatt_get_attributes_cmd *cmd = (void *) data; - struct gatt_get_attributes_rp *rp; - struct gatt_attr *gatt_attr; - struct os_mbuf *buf = os_msys_get(0, 0); + const struct btp_gatt_get_attributes_cmd *cmd = (void *) data; + struct btp_gatt_get_attributes_rp *rp; + struct btp_gatt_attr *gatt_attr; + struct os_mbuf *buf = os_msys_get(0, 0); uint16_t start_handle, end_handle; struct ble_att_svr_entry *entry = NULL; ble_uuid_any_t uuid; @@ -1742,12 +1742,12 @@ get_attrs(uint8_t *data, uint16_t len) rp->attrs_count = count; - tester_send_buf(BTP_SERVICE_ID_GATT, GATT_GET_ATTRIBUTES, + tester_send_buf(BTP_SERVICE_ID_GATT, BTP_GATT_GET_ATTRIBUTES, CONTROLLER_INDEX, buf); goto free; fail: - tester_rsp(BTP_SERVICE_ID_GATT, GATT_GET_ATTRIBUTES, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_GET_ATTRIBUTES, CONTROLLER_INDEX, BTP_STATUS_FAILED); free: os_mbuf_free_chain(buf); @@ -1756,9 +1756,9 @@ get_attrs(uint8_t *data, uint16_t len) static void get_attr_val(uint8_t *data, uint16_t len) { - const struct gatt_get_attribute_value_cmd *cmd = (void *) data; - struct gatt_get_attribute_value_rp *rp; - struct ble_gap_conn_desc conn; + const struct btp_gatt_get_attribute_value_cmd *cmd = (void *) data; + struct btp_gatt_get_attribute_value_rp *rp; + struct ble_gap_conn_desc conn; struct os_mbuf *buf = os_msys_get(0, 0); uint16_t handle = sys_cpu_to_le16(cmd->handle); uint8_t out_att_err = 0; @@ -1777,7 +1777,7 @@ get_attr_val(uint8_t *data, uint16_t len) rp->att_response = out_att_err; rp->value_length = os_mbuf_len(buf) - sizeof(*rp); - tester_send_buf(BTP_SERVICE_ID_GATT, GATT_GET_ATTRIBUTE_VALUE, + tester_send_buf(BTP_SERVICE_ID_GATT, BTP_GATT_GET_ATTRIBUTE_VALUE, CONTROLLER_INDEX, buf); goto free; @@ -1792,7 +1792,7 @@ get_attr_val(uint8_t *data, uint16_t len) rp->att_response = out_att_err; rp->value_length = os_mbuf_len(buf) - sizeof(*rp); - tester_send_buf(BTP_SERVICE_ID_GATT, GATT_GET_ATTRIBUTE_VALUE, + tester_send_buf(BTP_SERVICE_ID_GATT, BTP_GATT_GET_ATTRIBUTE_VALUE, CONTROLLER_INDEX, buf); goto free; @@ -1805,7 +1805,7 @@ get_attr_val(uint8_t *data, uint16_t len) static void change_database(uint8_t *data, uint16_t len) { - const struct gatt_change_database *cmd = (void *) data; + const struct btp_gatt_change_database *cmd = (void *) data; SYS_LOG_DBG("") @@ -1813,7 +1813,7 @@ change_database(uint8_t *data, uint16_t len) ble_svc_gatt_changed(cmd->start_handle, cmd->end_handle); - tester_rsp(BTP_SERVICE_ID_GATT, GATT_CHANGE_DATABASE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_CHANGE_DATABASE, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); return; @@ -1822,38 +1822,38 @@ change_database(uint8_t *data, uint16_t len) static void supported_commands(uint8_t *data, uint16_t len) { - uint8_t cmds[4]; - struct gatt_read_supported_commands_rp *rp = (void *) cmds; + uint8_t cmds[4]; + struct btp_gatt_read_supported_commands_rp *rp = (void *) cmds; SYS_LOG_DBG(""); memset(cmds, 0, sizeof(cmds)); - tester_set_bit(cmds, GATT_READ_SUPPORTED_COMMANDS); - tester_set_bit(cmds, GATT_START_SERVER); - tester_set_bit(cmds, GATT_EXCHANGE_MTU); - tester_set_bit(cmds, GATT_DISC_ALL_PRIM_SVCS); - tester_set_bit(cmds, GATT_DISC_PRIM_UUID); - tester_set_bit(cmds, GATT_FIND_INCLUDED); - tester_set_bit(cmds, GATT_DISC_ALL_CHRC); - tester_set_bit(cmds, GATT_DISC_CHRC_UUID); - tester_set_bit(cmds, GATT_DISC_ALL_DESC); - tester_set_bit(cmds, GATT_READ); - tester_set_bit(cmds, GATT_READ_LONG); - tester_set_bit(cmds, GATT_READ_MULTIPLE); - tester_set_bit(cmds, GATT_WRITE_WITHOUT_RSP); + tester_set_bit(cmds, BTP_GATT_READ_SUPPORTED_COMMANDS); + tester_set_bit(cmds, BTP_GATT_START_SERVER); + tester_set_bit(cmds, BTP_GATT_EXCHANGE_MTU); + tester_set_bit(cmds, BTP_GATT_DISC_ALL_PRIM_SVCS); + tester_set_bit(cmds, BTP_GATT_DISC_PRIM_UUID); + tester_set_bit(cmds, BTP_GATT_FIND_INCLUDED); + tester_set_bit(cmds, BTP_GATT_DISC_ALL_CHRC); + tester_set_bit(cmds, BTP_GATT_DISC_CHRC_UUID); + tester_set_bit(cmds, BTP_GATT_DISC_ALL_DESC); + tester_set_bit(cmds, BTP_GATT_READ); + tester_set_bit(cmds, BTP_GATT_READ_LONG); + tester_set_bit(cmds, BTP_GATT_READ_MULTIPLE); + tester_set_bit(cmds, BTP_GATT_WRITE_WITHOUT_RSP); #if 0 - tester_set_bit(cmds, GATT_SIGNED_WRITE_WITHOUT_RSP); + tester_set_bit(cmds, BTP_GATT_SIGNED_WRITE_WITHOUT_RSP); #endif - tester_set_bit(cmds, GATT_WRITE); - tester_set_bit(cmds, GATT_WRITE_LONG); - tester_set_bit(cmds, GATT_CFG_NOTIFY); - tester_set_bit(cmds, GATT_CFG_INDICATE); - tester_set_bit(cmds, GATT_GET_ATTRIBUTES); - tester_set_bit(cmds, GATT_GET_ATTRIBUTE_VALUE); - tester_set_bit(cmds, GATT_CHANGE_DATABASE); - - tester_send(BTP_SERVICE_ID_GATT, GATT_READ_SUPPORTED_COMMANDS, + tester_set_bit(cmds, BTP_GATT_WRITE); + tester_set_bit(cmds, BTP_GATT_WRITE_LONG); + tester_set_bit(cmds, BTP_GATT_CFG_NOTIFY); + tester_set_bit(cmds, BTP_GATT_CFG_INDICATE); + tester_set_bit(cmds, BTP_GATT_GET_ATTRIBUTES); + tester_set_bit(cmds, BTP_GATT_GET_ATTRIBUTE_VALUE); + tester_set_bit(cmds, BTP_GATT_CHANGE_DATABASE); + + tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_READ_SUPPORTED_COMMANDS, CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); } @@ -1868,76 +1868,76 @@ tester_handle_gatt(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len) { switch (opcode) { - case GATT_READ_SUPPORTED_COMMANDS: + case BTP_GATT_READ_SUPPORTED_COMMANDS: supported_commands(data, len); return; - case GATT_START_SERVER: + case BTP_GATT_START_SERVER: start_server(data, len); return; - case GATT_EXCHANGE_MTU: + case BTP_GATT_EXCHANGE_MTU: exchange_mtu(data, len); return; - case GATT_DISC_ALL_PRIM_SVCS: + case BTP_GATT_DISC_ALL_PRIM_SVCS: disc_all_prim_svcs(data, len); return; - case GATT_DISC_PRIM_UUID: + case BTP_GATT_DISC_PRIM_UUID: disc_prim_uuid(data, len); return; - case GATT_FIND_INCLUDED: + case BTP_GATT_FIND_INCLUDED: find_included(data, len); return; - case GATT_DISC_ALL_CHRC: + case BTP_GATT_DISC_ALL_CHRC: disc_all_chrc(data, len); return; - case GATT_DISC_CHRC_UUID: + case BTP_GATT_DISC_CHRC_UUID: disc_chrc_uuid(data, len); return; - case GATT_DISC_ALL_DESC: + case BTP_GATT_DISC_ALL_DESC: disc_all_desc(data, len); return; - case GATT_CHANGE_DATABASE: + case BTP_GATT_CHANGE_DATABASE: change_database(data, len); return; - case GATT_READ: + case BTP_GATT_READ: read(data, len); return; - case GATT_READ_UUID: + case BTP_GATT_READ_UUID: read_uuid(data, len); return; - case GATT_READ_LONG: + case BTP_GATT_READ_LONG: read_long(data, len); return; - case GATT_READ_MULTIPLE: + case BTP_GATT_READ_MULTIPLE: read_multiple(data, len); return; - case GATT_WRITE_WITHOUT_RSP: + case BTP_GATT_WRITE_WITHOUT_RSP: write_without_rsp(data, len, opcode, false); return; #if 0 - case GATT_SIGNED_WRITE_WITHOUT_RSP: + case BTP_GATT_SIGNED_WRITE_WITHOUT_RSP: write_without_rsp(data, len, opcode, true); return; #endif - case GATT_WRITE: + case BTP_GATT_WRITE: write(data, len); return; - case GATT_WRITE_LONG: + case BTP_GATT_WRITE_LONG: write_long(data, len); return; - case GATT_RELIABLE_WRITE: + case BTP_GATT_RELIABLE_WRITE: reliable_write(data, len); return; - case GATT_CFG_NOTIFY: - case GATT_CFG_INDICATE: + case BTP_GATT_CFG_NOTIFY: + case BTP_GATT_CFG_INDICATE: config_subscription(data, len, opcode); return; - case GATT_GET_ATTRIBUTES: + case BTP_GATT_GET_ATTRIBUTES: get_attrs(data, len); return; - case GATT_GET_ATTRIBUTE_VALUE: + case BTP_GATT_GET_ATTRIBUTE_VALUE: get_attr_val(data, len); return; default: @@ -1951,8 +1951,8 @@ int tester_gatt_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, uint8_t indication, struct os_mbuf *om) { - struct gatt_notification_ev *ev; - struct ble_gap_conn_desc conn; + struct btp_gatt_notification_ev *ev; + struct ble_gap_conn_desc conn; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; @@ -1978,7 +1978,7 @@ tester_gatt_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, ev->data_length = sys_cpu_to_le16(os_mbuf_len(om)); os_mbuf_appendfrom(buf, om, 0, os_mbuf_len(om)); - tester_send_buf(BTP_SERVICE_ID_GATT, GATT_EV_NOTIFICATION, + tester_send_buf(BTP_SERVICE_ID_GATT, BTP_GATT_EV_NOTIFICATION, CONTROLLER_INDEX, buf); fail: diff --git a/apps/bttester/src/gatt_cl.c b/apps/bttester/src/btp_gatt_cl.c similarity index 82% rename from apps/bttester/src/gatt_cl.c rename to apps/bttester/src/btp_gatt_cl.c index af08764292..af33f17ee4 100644 --- a/apps/bttester/src/gatt_cl.c +++ b/apps/bttester/src/btp_gatt_cl.c @@ -28,7 +28,7 @@ #include "../../../nimble/host/src/ble_att_priv.h" #include "../../../nimble/host/src/ble_gatt_priv.h" -#include "bttester.h" +#include "btp/btp.h" #define CONTROLLER_INDEX 0 #define MAX_BUFFER_SIZE 2048 @@ -123,8 +123,8 @@ tester_mtu_exchanged_ev(uint16_t conn_handle, const struct ble_gatt_error *error, uint16_t mtu, void *arg) { - struct gattc_exchange_mtu_ev *ev; - struct ble_gap_conn_desc conn; + struct btp_gattc_exchange_mtu_ev *ev; + struct ble_gap_conn_desc conn; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; @@ -144,7 +144,7 @@ tester_mtu_exchanged_ev(uint16_t conn_handle, ev->mtu = mtu; - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_EV_MTU_EXCHANGED, + tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_EV_MTU_EXCHANGED, CONTROLLER_INDEX, buf); fail: os_mbuf_free_chain(buf); @@ -174,7 +174,7 @@ exchange_mtu(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_EXCHANGE_MTU, + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_EXCHANGE_MTU, CONTROLLER_INDEX, status); } @@ -183,10 +183,10 @@ disc_prim_svcs_cb(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_svc *gatt_svc, void *arg) { - struct gattc_disc_prim_svcs_rp *rp; - struct ble_gap_conn_desc conn; - struct gatt_service *service; - const ble_uuid_any_t *uuid; + struct btp_gattc_disc_prim_svcs_rp *rp; + struct ble_gap_conn_desc conn; + struct btp_gatt_service *service; + const ble_uuid_any_t *uuid; const ble_addr_t *addr; uint8_t uuid_length; struct os_mbuf *buf = os_msys_get(0, 0); @@ -272,22 +272,22 @@ disc_all_prim_svcs(uint8_t *data, uint16_t len) } if (ble_gattc_disc_all_svcs(conn.conn_handle, disc_prim_svcs_cb, - (void *) GATTC_DISC_ALL_PRIM_RP)) { + (void *) BTP_GATTC_DISC_ALL_PRIM_RP)) { discover_destroy(); status = BTP_STATUS_FAILED; goto rsp; } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_PRIM_SVCS, + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_PRIM_SVCS, CONTROLLER_INDEX, status); } static void disc_prim_uuid(uint8_t *data, uint16_t len) { - const struct gattc_disc_prim_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gattc_disc_prim_uuid_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; ble_uuid_any_t uuid; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -307,14 +307,14 @@ disc_prim_uuid(uint8_t *data, uint16_t len) if (ble_gattc_disc_svc_by_uuid(conn.conn_handle, &uuid.u, disc_prim_svcs_cb, - (void *) GATTC_DISC_PRIM_UUID_RP)) { + (void *) BTP_GATTC_DISC_PRIM_UUID_RP)) { discover_destroy(); status = BTP_STATUS_FAILED; goto rsp; } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_PRIM_UUID, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_PRIM_UUID, CONTROLLER_INDEX, status); } @@ -323,9 +323,9 @@ find_included_cb(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_svc *gatt_svc, void *arg) { - struct gattc_find_included_rp *rp; - struct gatt_included *included; - const ble_uuid_any_t *uuid; + struct btp_gattc_find_included_rp *rp; + struct btp_gatt_included *included; + const ble_uuid_any_t *uuid; int service_handle = (int) arg; uint8_t uuid_length; uint8_t err = (uint8_t) error->status; @@ -354,7 +354,7 @@ find_included_cb(uint16_t conn_handle, SYS_LOG_DBG(""); if (error->status != 0 && error->status != BLE_HS_EDONE) { rp->services_count = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_FIND_INCLUDED_RP, + tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_FIND_INCLUDED_RP, CONTROLLER_INDEX, buf); discover_destroy(); goto free; @@ -364,7 +364,7 @@ find_included_cb(uint16_t conn_handle, rp->status = 0; rp->services_count = gatt_buf.cnt; os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_FIND_INCLUDED_RP, + tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_FIND_INCLUDED_RP, CONTROLLER_INDEX, buf); discover_destroy(); goto free; @@ -404,8 +404,8 @@ find_included_cb(uint16_t conn_handle, static void find_included(uint8_t *data, uint16_t len) { - const struct gattc_find_included_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gattc_find_included_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; int service_handle_arg; uint8_t status = BTP_STATUS_SUCCESS; @@ -432,7 +432,7 @@ find_included(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_FIND_INCLUDED, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_FIND_INCLUDED, CONTROLLER_INDEX, status); } @@ -441,9 +441,9 @@ disc_chrc_cb(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_chr *gatt_chr, void *arg) { - struct gattc_disc_chrc_rp *rp; - struct gatt_characteristic *chrc; - const ble_uuid_any_t *uuid; + struct btp_gattc_disc_chrc_rp *rp; + struct btp_gatt_characteristic *chrc; + const ble_uuid_any_t *uuid; uint8_t uuid_length; uint8_t opcode = (uint8_t) (int) arg; uint8_t err = (uint8_t) error->status; @@ -522,8 +522,8 @@ disc_chrc_cb(uint16_t conn_handle, static void disc_all_chrc(uint8_t *data, uint16_t len) { - const struct gattc_disc_all_chrc_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gattc_disc_all_chrc_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -544,7 +544,7 @@ disc_all_chrc(uint8_t *data, uint16_t len) start_handle, end_handle, disc_chrc_cb, - (void *) GATTC_DISC_ALL_CHRC_RP); + (void *) BTP_GATTC_DISC_ALL_CHRC_RP); if (rc) { discover_destroy(); status = BTP_STATUS_FAILED; @@ -552,15 +552,15 @@ disc_all_chrc(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_CHRC, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_CHRC, CONTROLLER_INDEX, status); } static void disc_chrc_uuid(uint8_t *data, uint16_t len) { - const struct gattc_disc_chrc_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gattc_disc_chrc_uuid_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; ble_uuid_any_t uuid; uint8_t status = BTP_STATUS_SUCCESS; @@ -584,7 +584,7 @@ disc_chrc_uuid(uint8_t *data, uint16_t len) rc = ble_gattc_disc_chrs_by_uuid(conn.conn_handle, start_handle, end_handle, &uuid.u, disc_chrc_cb, - (void *) GATTC_DISC_CHRC_UUID_RP); + (void *) BTP_GATTC_DISC_CHRC_UUID_RP); if (rc) { discover_destroy(); status = BTP_STATUS_FAILED; @@ -592,7 +592,7 @@ disc_chrc_uuid(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_CHRC_UUID, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_CHRC_UUID, CONTROLLER_INDEX, status); } @@ -603,9 +603,9 @@ disc_all_desc_cb(uint16_t conn_handle, const struct ble_gatt_dsc *gatt_dsc, void *arg) { - struct gattc_disc_all_desc_rp *rp; - struct gatt_descriptor *dsc; - const ble_uuid_any_t *uuid; + struct btp_gattc_disc_all_desc_rp *rp; + struct btp_gatt_descriptor *dsc; + const ble_uuid_any_t *uuid; uint8_t uuid_length; uint8_t err = (uint8_t) error->status; struct os_mbuf *buf = os_msys_get(0, 0); @@ -632,7 +632,7 @@ disc_all_desc_cb(uint16_t conn_handle, if (error->status != 0 && error->status != BLE_HS_EDONE) { rp->descriptors_count = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_DESC_RP, + tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_DESC_RP, CONTROLLER_INDEX, buf); discover_destroy(); goto free; @@ -642,7 +642,7 @@ disc_all_desc_cb(uint16_t conn_handle, rp->status = 0; rp->descriptors_count = gatt_buf.cnt; os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_DESC_RP, + tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_DESC_RP, CONTROLLER_INDEX, buf); discover_destroy(); goto free; @@ -678,8 +678,8 @@ disc_all_desc_cb(uint16_t conn_handle, static void disc_all_desc(uint8_t *data, uint16_t len) { - const struct gattc_disc_all_desc_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gattc_disc_all_desc_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -699,7 +699,7 @@ disc_all_desc(uint8_t *data, uint16_t len) start_handle, end_handle, disc_all_desc_cb, - (void *) GATTC_DISC_ALL_DESC); + (void *) BTP_GATTC_DISC_ALL_DESC); SYS_LOG_DBG("rc=%d", rc); @@ -710,7 +710,7 @@ disc_all_desc(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_DISC_ALL_DESC, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_DESC, CONTROLLER_INDEX, status); } @@ -720,8 +720,8 @@ read_cb(uint16_t conn_handle, struct ble_gatt_attr *attr, void *arg) { - struct gattc_read_rp *rp; - uint8_t opcode = (uint8_t) (int) arg; + struct btp_gattc_read_rp *rp; + uint8_t opcode = (uint8_t) (int) arg; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; struct ble_gap_conn_desc conn; @@ -771,8 +771,8 @@ read_cb(uint16_t conn_handle, static void read(uint8_t *data, uint16_t len) { - const struct gattc_read_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gattc_read_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -788,14 +788,14 @@ read(uint8_t *data, uint16_t len) read_destroy(); if (ble_gattc_read(conn.conn_handle, sys_le16_to_cpu(cmd->handle), - read_cb, (void *) GATTC_READ_RP)) { + read_cb, (void *) BTP_GATTC_READ_RP)) { read_destroy(); status = BTP_STATUS_FAILED; goto rsp; } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ, CONTROLLER_INDEX, status); } @@ -805,9 +805,9 @@ read_uuid_cb(uint16_t conn_handle, struct ble_gatt_attr *attr, void *arg) { - struct gattc_read_uuid_rp *rp; - struct gatt_read_uuid_chr *chr; - uint8_t opcode = (uint8_t) (int) arg; + struct btp_gattc_read_uuid_rp *rp; + struct btp_gatt_read_uuid_chr *chr; + uint8_t opcode = (uint8_t) (int) arg; uint8_t err = (uint8_t) error->status; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; @@ -874,8 +874,8 @@ read_uuid_cb(uint16_t conn_handle, static void read_uuid(uint8_t *data, uint16_t len) { - const struct gattc_read_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gattc_read_uuid_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; ble_uuid_any_t uuid; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -899,13 +899,13 @@ read_uuid(uint8_t *data, uint16_t len) if (ble_gattc_read_by_uuid(conn.conn_handle, sys_le16_to_cpu(cmd->start_handle), sys_le16_to_cpu(cmd->end_handle), &uuid.u, - read_uuid_cb, (void *) GATTC_READ_UUID_RP)) { + read_uuid_cb, (void *) BTP_GATTC_READ_UUID_RP)) { read_destroy(); status = BTP_STATUS_FAILED; } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ_UUID, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_UUID, CONTROLLER_INDEX, status); } @@ -915,7 +915,7 @@ read_long_cb(uint16_t conn_handle, struct ble_gatt_attr *attr, void *arg) { - struct gattc_read_rp *rp;; + struct btp_gattc_read_rp *rp;; uint8_t opcode = (uint8_t) (int) arg; uint8_t err = (uint8_t) error->status; struct os_mbuf *buf = os_msys_get(0, 0); @@ -974,8 +974,8 @@ read_long_cb(uint16_t conn_handle, static void read_long(uint8_t *data, uint16_t len) { - const struct gattc_read_long_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gattc_read_long_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -993,21 +993,21 @@ read_long(uint8_t *data, uint16_t len) if (ble_gattc_read_long(conn.conn_handle, sys_le16_to_cpu(cmd->handle), sys_le16_to_cpu(cmd->offset), - read_long_cb, (void *) GATTC_READ_LONG_RP)) { + read_long_cb, (void *) BTP_GATTC_READ_LONG_RP)) { read_destroy(); status = BTP_STATUS_FAILED; } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ_LONG, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_LONG, CONTROLLER_INDEX, status); } static void read_multiple(uint8_t *data, uint16_t len) { - const struct gattc_read_multiple_cmd *cmd = (void *) data; - uint16_t handles[cmd->handles_count]; + const struct btp_gattc_read_multiple_cmd *cmd = (void *) data; + uint16_t handles[cmd->handles_count]; struct ble_gap_conn_desc conn; uint8_t status = BTP_STATUS_SUCCESS; int rc, i; @@ -1031,21 +1031,21 @@ read_multiple(uint8_t *data, uint16_t len) handles, cmd->handles_count, read_cb, - (void *) GATTC_READ_MULTIPLE_RP)) { + (void *) BTP_GATTC_READ_MULTIPLE_RP)) { read_destroy(); status = BTP_STATUS_FAILED; } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_READ_MULTIPLE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_MULTIPLE, CONTROLLER_INDEX, status); } static void write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) { - const struct gattc_write_without_rsp_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gattc_write_without_rsp_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -1072,8 +1072,8 @@ write_cb(uint16_t conn_handle, const struct ble_gatt_error *error, struct ble_gatt_attr *attr, void *arg) { - struct gattc_write_rp *rp; - uint8_t err = (uint8_t) error->status; + struct btp_gattc_write_rp *rp; + uint8_t err = (uint8_t) error->status; uint8_t opcode = (uint8_t) (int) arg; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; @@ -1106,8 +1106,8 @@ write_cb(uint16_t conn_handle, const struct ble_gatt_error *error, static void write(uint8_t *data, uint16_t len) { - const struct gattc_write_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gattc_write_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -1121,20 +1121,20 @@ write(uint8_t *data, uint16_t len) if (ble_gattc_write_flat(conn.conn_handle, sys_le16_to_cpu(cmd->handle), cmd->data, sys_le16_to_cpu(cmd->data_length), - write_cb, (void *) GATTC_WRITE_RP)) { + write_cb, (void *) BTP_GATTC_WRITE_RP)) { status = BTP_STATUS_FAILED; } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_WRITE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_WRITE, CONTROLLER_INDEX, status); } static void write_long(uint8_t *data, uint16_t len) { - const struct gattc_write_long_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gattc_write_long_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; struct os_mbuf *om = NULL; uint8_t status = BTP_STATUS_SUCCESS; int rc = 0; @@ -1157,7 +1157,7 @@ write_long(uint8_t *data, uint16_t len) sys_le16_to_cpu(cmd->handle), sys_le16_to_cpu(cmd->offset), om, write_cb, - (void *) GATTC_WRITE_LONG_RP); + (void *) BTP_GATTC_WRITE_LONG_RP); if (rc) { status = BTP_STATUS_FAILED; } else { @@ -1168,7 +1168,7 @@ write_long(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to send Write Long request, rc=%d", rc); os_mbuf_free_chain(om); rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_WRITE_LONG, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_WRITE_LONG, CONTROLLER_INDEX, status); } @@ -1179,8 +1179,8 @@ reliable_write_cb(uint16_t conn_handle, uint8_t num_attrs, void *arg) { - struct gattc_write_rp *rp; - uint8_t err = (uint8_t) error->status; + struct btp_gattc_write_rp *rp; + uint8_t err = (uint8_t) error->status; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; struct ble_gap_conn_desc conn; @@ -1202,7 +1202,7 @@ reliable_write_cb(uint16_t conn_handle, memcpy(rp->address, addr->val, sizeof(rp->address)); rp->status = err; - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_RELIABLE_WRITE_RP, + tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_RELIABLE_WRITE_RP, CONTROLLER_INDEX, buf); free: os_mbuf_free_chain(buf); @@ -1212,8 +1212,8 @@ reliable_write_cb(uint16_t conn_handle, static void reliable_write(uint8_t *data, uint16_t len) { - const struct gattc_reliable_write_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gattc_reliable_write_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; struct ble_gatt_attr attr; struct os_mbuf *om = NULL; uint8_t status = BTP_STATUS_SUCCESS; @@ -1251,7 +1251,7 @@ reliable_write(uint8_t *data, uint16_t len) fail: os_mbuf_free_chain(om); rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, GATTC_WRITE_LONG, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_WRITE_LONG, CONTROLLER_INDEX, status); } @@ -1261,8 +1261,8 @@ subscribe_cb(uint16_t conn_handle, struct ble_gatt_attr *attrs, void *arg) { - struct subscribe_rp *rp; - uint8_t err = (uint8_t) error->status; + struct btp_subscribe_rp *rp; + uint8_t err = (uint8_t) error->status; uint8_t opcode = (uint8_t) (int) arg; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; @@ -1300,8 +1300,8 @@ enable_subscription(uint16_t conn_handle, uint16_t ccc_handle, SYS_LOG_DBG(""); - opcode = (uint32_t) (value == 0x0001 ? GATTC_CFG_NOTIFY_RP - : GATTC_CFG_INDICATE_RP); + opcode = (uint32_t) (value == 0x0001 ? BTP_GATTC_CFG_NOTIFY_RP + : BTP_GATTC_CFG_INDICATE_RP); if (ble_gattc_write_flat(conn_handle, ccc_handle, @@ -1325,8 +1325,8 @@ disable_subscription(uint16_t conn_handle, uint16_t ccc_handle) SYS_LOG_DBG(""); - opcode = (uint32_t) (value == 0x0001 ? GATTC_CFG_NOTIFY_RP - : GATTC_CFG_INDICATE_RP); + opcode = (uint32_t) (value == 0x0001 ? BTP_GATTC_CFG_NOTIFY_RP + : BTP_GATTC_CFG_INDICATE_RP); /* Fail if CCC handle doesn't match */ if (ccc_handle != subscribe_params.ccc_handle) { @@ -1350,8 +1350,8 @@ disable_subscription(uint16_t conn_handle, uint16_t ccc_handle) static void config_subscription(uint8_t *data, uint16_t len, uint8_t op) { - const struct gattc_cfg_notify_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gattc_cfg_notify_cmd *cmd = (void *) data; + struct ble_gap_conn_desc conn; uint16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle); uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -1367,7 +1367,7 @@ config_subscription(uint8_t *data, uint16_t len, uint8_t op) if (cmd->enable) { uint16_t value; - if (op == GATTC_CFG_NOTIFY) { + if (op == BTP_GATTC_CFG_NOTIFY) { value = 0x0001; } else { value = 0x0002; @@ -1396,8 +1396,8 @@ int tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, uint8_t indication, struct os_mbuf *om) { - struct gattc_notification_ev *ev; - struct ble_gap_conn_desc conn; + struct btp_gattc_notification_ev *ev; + struct ble_gap_conn_desc conn; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; @@ -1423,7 +1423,7 @@ tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, ev->data_length = sys_cpu_to_le16(os_mbuf_len(om)); os_mbuf_appendfrom(buf, om, 0, os_mbuf_len(om)); - tester_send_buf(BTP_SERVICE_ID_GATTC, GATTC_EV_NOTIFICATION_RXED, + tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_EV_NOTIFICATION_RXED, CONTROLLER_INDEX, buf); fail: @@ -1434,36 +1434,36 @@ tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, static void supported_commands(uint8_t *data, uint16_t len) { - uint8_t cmds[3]; - struct gatt_read_supported_commands_rp *rp = (void *) cmds; + uint8_t cmds[3]; + struct btp_gatt_read_supported_commands_rp *rp = (void *) cmds; SYS_LOG_DBG(""); memset(cmds, 0, sizeof(cmds)); - tester_set_bit(cmds, GATTC_READ_SUPPORTED_COMMANDS); - tester_set_bit(cmds, GATTC_EXCHANGE_MTU); - tester_set_bit(cmds, GATTC_DISC_ALL_PRIM_SVCS); - tester_set_bit(cmds, GATTC_DISC_PRIM_UUID); - tester_set_bit(cmds, GATTC_FIND_INCLUDED); - tester_set_bit(cmds, GATTC_DISC_ALL_CHRC); - tester_set_bit(cmds, GATTC_DISC_CHRC_UUID); - tester_set_bit(cmds, GATTC_DISC_ALL_DESC); - tester_set_bit(cmds, GATTC_READ); - tester_set_bit(cmds, GATTC_READ_UUID); - tester_set_bit(cmds, GATTC_READ_LONG); - tester_set_bit(cmds, GATTC_READ_MULTIPLE); - tester_set_bit(cmds, GATTC_WRITE_WITHOUT_RSP); + tester_set_bit(cmds, BTP_GATTC_READ_SUPPORTED_COMMANDS); + tester_set_bit(cmds, BTP_GATTC_EXCHANGE_MTU); + tester_set_bit(cmds, BTP_GATTC_DISC_ALL_PRIM_SVCS); + tester_set_bit(cmds, BTP_GATTC_DISC_PRIM_UUID); + tester_set_bit(cmds, BTP_GATTC_FIND_INCLUDED); + tester_set_bit(cmds, BTP_GATTC_DISC_ALL_CHRC); + tester_set_bit(cmds, BTP_GATTC_DISC_CHRC_UUID); + tester_set_bit(cmds, BTP_GATTC_DISC_ALL_DESC); + tester_set_bit(cmds, BTP_GATTC_READ); + tester_set_bit(cmds, BTP_GATTC_READ_UUID); + tester_set_bit(cmds, BTP_GATTC_READ_LONG); + tester_set_bit(cmds, BTP_GATTC_READ_MULTIPLE); + tester_set_bit(cmds, BTP_GATTC_WRITE_WITHOUT_RSP); #if 0 - tester_set_bit(cmds, GATTC_SIGNED_WRITE_WITHOUT_RSP); + tester_set_bit(cmds, BTP_GATTC_SIGNED_WRITE_WITHOUT_RSP); #endif - tester_set_bit(cmds, GATTC_WRITE); - tester_set_bit(cmds, GATTC_WRITE_LONG); - tester_set_bit(cmds, GATTC_RELIABLE_WRITE); - tester_set_bit(cmds, GATTC_CFG_NOTIFY); - tester_set_bit(cmds, GATTC_CFG_INDICATE); + tester_set_bit(cmds, BTP_GATTC_WRITE); + tester_set_bit(cmds, BTP_GATTC_WRITE_LONG); + tester_set_bit(cmds, BTP_GATTC_RELIABLE_WRITE); + tester_set_bit(cmds, BTP_GATTC_CFG_NOTIFY); + tester_set_bit(cmds, BTP_GATTC_CFG_INDICATE); - tester_send(BTP_SERVICE_ID_GATTC, GATTC_READ_SUPPORTED_COMMANDS, + tester_send(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_SUPPORTED_COMMANDS, CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); } @@ -1472,64 +1472,64 @@ tester_handle_gattc(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len) { switch (opcode) { - case GATTC_READ_SUPPORTED_COMMANDS: + case BTP_GATTC_READ_SUPPORTED_COMMANDS: supported_commands(data, len); return; - case GATTC_EXCHANGE_MTU: + case BTP_GATTC_EXCHANGE_MTU: exchange_mtu(data, len); return; - case GATTC_DISC_ALL_PRIM_SVCS: + case BTP_GATTC_DISC_ALL_PRIM_SVCS: disc_all_prim_svcs(data, len); return; - case GATTC_DISC_PRIM_UUID: + case BTP_GATTC_DISC_PRIM_UUID: disc_prim_uuid(data, len); return; - case GATTC_FIND_INCLUDED: + case BTP_GATTC_FIND_INCLUDED: find_included(data, len); return; - case GATTC_DISC_ALL_CHRC: + case BTP_GATTC_DISC_ALL_CHRC: disc_all_chrc(data, len); return; - case GATTC_DISC_CHRC_UUID: + case BTP_GATTC_DISC_CHRC_UUID: disc_chrc_uuid(data, len); return; - case GATTC_DISC_ALL_DESC: + case BTP_GATTC_DISC_ALL_DESC: disc_all_desc(data, len); return; - case GATTC_READ: + case BTP_GATTC_READ: read(data, len); return; - case GATTC_READ_UUID: + case BTP_GATTC_READ_UUID: read_uuid(data, len); return; - case GATTC_READ_LONG: + case BTP_GATTC_READ_LONG: read_long(data, len); return; - case GATTC_READ_MULTIPLE: + case BTP_GATTC_READ_MULTIPLE: read_multiple(data, len); return; - case GATTC_WRITE_WITHOUT_RSP: + case BTP_GATTC_WRITE_WITHOUT_RSP: write_without_rsp(data, len, opcode, false); return; #if 0 - case GATTC_SIGNED_WRITE_WITHOUT_RSP: + case BTP_GATTC_SIGNED_WRITE_WITHOUT_RSP: write_without_rsp(data, len, opcode, true); return; #endif - case GATTC_WRITE: + case BTP_GATTC_WRITE: write(data, len); return; - case GATTC_WRITE_LONG: + case BTP_GATTC_WRITE_LONG: write_long(data, len); return; - case GATTC_RELIABLE_WRITE: + case BTP_GATTC_RELIABLE_WRITE: reliable_write(data, len); return; - case GATTC_CFG_NOTIFY: - case GATTC_CFG_INDICATE: + case BTP_GATTC_CFG_NOTIFY: + case BTP_GATTC_CFG_INDICATE: config_subscription(data, len, opcode); return; default: diff --git a/apps/bttester/src/l2cap.c b/apps/bttester/src/btp_l2cap.c similarity index 84% rename from apps/bttester/src/l2cap.c rename to apps/bttester/src/btp_l2cap.c index 768dd0ed0a..93435943a4 100644 --- a/apps/bttester/src/l2cap.c +++ b/apps/bttester/src/btp_l2cap.c @@ -35,7 +35,7 @@ #include "../../../nimble/host/src/ble_l2cap_priv.h" -#include "bttester.h" +#include "btp/btp.h" #define CONTROLLER_INDEX 0 #define CHANNELS MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) @@ -57,7 +57,7 @@ static struct channel { } channels[CHANNELS]; static uint8_t - recv_cb_buf[TESTER_COC_MTU + sizeof(struct l2cap_data_received_ev)]; + recv_cb_buf[TESTER_COC_MTU + sizeof(struct btp_l2cap_data_received_ev)]; static struct channel * get_free_channel(void) @@ -122,8 +122,8 @@ static void recv_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, struct os_mbuf *buf, void *arg) { - struct l2cap_data_received_ev *ev = (void *) recv_cb_buf; - struct channel *channel = find_channel(chan); + struct btp_l2cap_data_received_ev *ev = (void *) recv_cb_buf; + struct channel *channel = find_channel(chan); assert(channel != NULL); ev->chan_id = channel->chan_id; @@ -135,7 +135,7 @@ recv_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, } os_mbuf_copydata(buf, 0, ev->data_length, ev->data); - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DATA_RECEIVED, + tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_DATA_RECEIVED, CONTROLLER_INDEX, recv_cb_buf, sizeof(*ev) + ev->data_length); tester_l2cap_coc_recv(chan, buf); @@ -146,10 +146,10 @@ unstalled_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, int status, void *arg) { if (status) { - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, CONTROLLER_INDEX, BTP_STATUS_FAILED); } else { - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } } @@ -159,8 +159,8 @@ reconfigured_ev(uint16_t conn_handle, struct ble_l2cap_chan *chan, struct ble_l2cap_chan_info *chan_info, int status) { - struct l2cap_reconfigured_ev ev; - struct channel *channel; + struct btp_l2cap_reconfigured_ev ev; + struct channel *channel; if (status != 0) { return; @@ -175,7 +175,7 @@ reconfigured_ev(uint16_t conn_handle, struct ble_l2cap_chan *chan, ev.our_mtu = chan_info->our_coc_mtu; ev.our_mps = chan_info->our_l2cap_mtu; - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_RECONFIGURED, + tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_RECONFIGURED, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } @@ -183,8 +183,8 @@ static void connected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, struct ble_l2cap_chan_info *chan_info, void *arg) { - struct l2cap_connected_ev ev; - struct ble_gap_conn_desc desc; + struct btp_l2cap_connected_ev ev; + struct ble_gap_conn_desc desc; struct channel *channel = find_channel(chan); if (channel == NULL) { @@ -206,7 +206,7 @@ connected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, sizeof(ev.address)); } - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_CONNECTED, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_CONNECTED, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } @@ -214,11 +214,11 @@ static void disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, struct ble_l2cap_chan_info *chan_info, void *arg) { - struct l2cap_disconnected_ev ev; - struct ble_gap_conn_desc desc; + struct btp_l2cap_disconnected_ev ev; + struct ble_gap_conn_desc desc; struct channel *channel; - memset(&ev, 0, sizeof(struct l2cap_disconnected_ev)); + memset(&ev, 0, sizeof(struct btp_l2cap_disconnected_ev)); channel = find_channel(chan); assert(channel != NULL); @@ -234,7 +234,7 @@ disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, sizeof(ev.address)); } - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DISCONNECTED, + tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_DISCONNECTED, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } @@ -406,18 +406,18 @@ tester_l2cap_event(struct ble_l2cap_event *event, void *arg) static void connect(uint8_t *data, uint16_t len) { - const struct l2cap_connect_cmd *cmd = (void *) data; - uint8_t rp_buf[sizeof(struct l2cap_connect_rp) + cmd->num]; - struct l2cap_connect_rp *rp = (void *) rp_buf; - struct ble_gap_conn_desc desc; + const struct btp_l2cap_connect_cmd *cmd = (void *) data; + uint8_t rp_buf[sizeof(struct btp_l2cap_connect_rp) + cmd->num]; + struct btp_l2cap_connect_rp *rp = (void *) rp_buf; + struct ble_gap_conn_desc desc; struct channel *chan; struct os_mbuf *sdu_rx[cmd->num]; ble_addr_t *addr = (void *) data; uint16_t mtu = htole16(cmd->mtu); int rc; int i, j; - bool ecfc = cmd->options & L2CAP_CONNECT_OPT_ECFC; - hold_credit = cmd->options & L2CAP_CONNECT_OPT_HOLD_CREDIT; + bool ecfc = cmd->options & BTP_L2CAP_CONNECT_OPT_ECFC; + hold_credit = cmd->options & BTP_L2CAP_CONNECT_OPT_HOLD_CREDIT; SYS_LOG_DBG("connect: type: %d addr: %s", addr->type, @@ -481,21 +481,21 @@ connect(uint8_t *data, uint16_t len) goto fail; } - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_CONNECT, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CONNECT, CONTROLLER_INDEX, (uint8_t *) rp, sizeof(rp_buf)); return; fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_CONNECT, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CONNECT, CONTROLLER_INDEX, BTP_STATUS_FAILED); } static void disconnect(const uint8_t *data, uint16_t len) { - const struct l2cap_disconnect_cmd *cmd = (void *) data; - struct channel *chan; + const struct btp_l2cap_disconnect_cmd *cmd = (void *) data; + struct channel *chan; uint8_t status; int err; @@ -513,15 +513,15 @@ disconnect(const uint8_t *data, uint16_t len) status = BTP_STATUS_SUCCESS; rsp: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_DISCONNECT, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_DISCONNECT, CONTROLLER_INDEX, status); } static void send_data(const uint8_t *data, uint16_t len) { - const struct l2cap_send_data_cmd *cmd = (void *) data; - struct os_mbuf *sdu_tx = NULL; + const struct btp_l2cap_send_data_cmd *cmd = (void *) data; + struct os_mbuf *sdu_tx = NULL; int rc; uint16_t data_len = sys_le16_to_cpu(cmd->data_len); struct channel *chan = get_channel(cmd->chan_id); @@ -550,7 +550,7 @@ send_data(const uint8_t *data, uint16_t len) /* ble_l2cap_send takes ownership of the sdu */ rc = ble_l2cap_send(chan->chan, sdu_tx); if (rc == 0 || rc == BLE_HS_ESTALLED) { - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); return; } @@ -559,15 +559,15 @@ send_data(const uint8_t *data, uint16_t len) os_mbuf_free_chain(sdu_tx); fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, CONTROLLER_INDEX, BTP_STATUS_FAILED); } static void listen(const uint8_t *data, uint16_t len) { - const struct l2cap_listen_cmd *cmd = (void *) data; - uint16_t mtu = htole16(cmd->mtu); + const struct btp_l2cap_listen_cmd *cmd = (void *) data; + uint16_t mtu = htole16(cmd->mtu); int rc; SYS_LOG_DBG(""); @@ -582,20 +582,20 @@ listen(const uint8_t *data, uint16_t len) goto fail; } - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_LISTEN, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_LISTEN, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); return; fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_LISTEN, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_LISTEN, CONTROLLER_INDEX, BTP_STATUS_FAILED); } static void credits(uint8_t *data, uint16_t len) { - const struct l2cap_credits_cmd *cmd = (void *) data; - struct os_mbuf *sdu; + const struct btp_l2cap_credits_cmd *cmd = (void *) data; + struct os_mbuf *sdu; int rc; struct channel *channel = get_channel(cmd->chan_id); @@ -613,19 +613,19 @@ credits(uint8_t *data, uint16_t len) if (rc != 0) { goto fail; } - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_CREDITS, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CREDITS, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); return; fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_CREDITS, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CREDITS, CONTROLLER_INDEX, BTP_STATUS_FAILED); } static void reconfigure(const uint8_t *data, uint16_t len) { - const struct l2cap_reconfigure_cmd *cmd = (void *) data; - uint16_t mtu = htole16(cmd->mtu); + const struct btp_l2cap_reconfigure_cmd *cmd = (void *) data; + uint16_t mtu = htole16(cmd->mtu); struct ble_gap_conn_desc desc; ble_addr_t *addr = (void *) data; struct ble_l2cap_chan *chans[cmd->num]; @@ -658,31 +658,31 @@ reconfigure(const uint8_t *data, uint16_t len) goto fail; } - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_RECONFIGURE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_RECONFIGURE, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); return; fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_RECONFIGURE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_RECONFIGURE, CONTROLLER_INDEX, BTP_STATUS_FAILED); } static void supported_commands(uint8_t *data, uint16_t len) { - uint8_t cmds[1]; - struct l2cap_read_supported_commands_rp *rp = (void *) cmds; + uint8_t cmds[1]; + struct btp_l2cap_read_supported_commands_rp *rp = (void *) cmds; memset(cmds, 0, sizeof(cmds)); - tester_set_bit(cmds, L2CAP_READ_SUPPORTED_COMMANDS); - tester_set_bit(cmds, L2CAP_CONNECT); - tester_set_bit(cmds, L2CAP_DISCONNECT); - tester_set_bit(cmds, L2CAP_LISTEN); - tester_set_bit(cmds, L2CAP_SEND_DATA); - tester_set_bit(cmds, L2CAP_RECONFIGURE); + tester_set_bit(cmds, BTP_L2CAP_READ_SUPPORTED_COMMANDS); + tester_set_bit(cmds, BTP_L2CAP_CONNECT); + tester_set_bit(cmds, BTP_L2CAP_DISCONNECT); + tester_set_bit(cmds, BTP_L2CAP_LISTEN); + tester_set_bit(cmds, BTP_L2CAP_SEND_DATA); + tester_set_bit(cmds, BTP_L2CAP_RECONFIGURE); - tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_READ_SUPPORTED_COMMANDS, + tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_READ_SUPPORTED_COMMANDS, CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); } @@ -691,25 +691,25 @@ tester_handle_l2cap(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len) { switch (opcode) { - case L2CAP_READ_SUPPORTED_COMMANDS: + case BTP_L2CAP_READ_SUPPORTED_COMMANDS: supported_commands(data, len); return; - case L2CAP_CONNECT: + case BTP_L2CAP_CONNECT: connect(data, len); return; - case L2CAP_DISCONNECT: + case BTP_L2CAP_DISCONNECT: disconnect(data, len); return; - case L2CAP_SEND_DATA: + case BTP_L2CAP_SEND_DATA: send_data(data, len); return; - case L2CAP_LISTEN: + case BTP_L2CAP_LISTEN: listen(data, len); return; - case L2CAP_RECONFIGURE: + case BTP_L2CAP_RECONFIGURE: reconfigure(data, len); return; - case L2CAP_CREDITS: + case BTP_L2CAP_CREDITS: credits(data, len); return; default: diff --git a/apps/bttester/src/mesh.c b/apps/bttester/src/btp_mesh.c similarity index 78% rename from apps/bttester/src/mesh.c rename to apps/bttester/src/btp_mesh.c index 26093f755d..cc36515a4e 100644 --- a/apps/bttester/src/mesh.c +++ b/apps/bttester/src/btp_mesh.c @@ -36,7 +36,7 @@ #include "mesh/testing.h" #include "console/console.h" -#include "bttester.h" +#include "btp/btp.h" extern uint8_t own_addr_type; @@ -93,32 +93,32 @@ supported_commands(uint8_t *data, uint16_t len) /* 1st octet */ memset(net_buf_simple_add(buf, 1), 0, 1); - tester_set_bit(buf->om_data, MESH_READ_SUPPORTED_COMMANDS); - tester_set_bit(buf->om_data, MESH_CONFIG_PROVISIONING); - tester_set_bit(buf->om_data, MESH_PROVISION_NODE); - tester_set_bit(buf->om_data, MESH_INIT); - tester_set_bit(buf->om_data, MESH_RESET); - tester_set_bit(buf->om_data, MESH_INPUT_NUMBER); - tester_set_bit(buf->om_data, MESH_INPUT_STRING); + tester_set_bit(buf->om_data, BTP_MESH_READ_SUPPORTED_COMMANDS); + tester_set_bit(buf->om_data, BTP_MESH_CONFIG_PROVISIONING); + tester_set_bit(buf->om_data, BTP_MESH_PROVISION_NODE); + tester_set_bit(buf->om_data, BTP_MESH_INIT); + tester_set_bit(buf->om_data, BTP_MESH_RESET); + tester_set_bit(buf->om_data, BTP_MESH_INPUT_NUMBER); + tester_set_bit(buf->om_data, BTP_MESH_INPUT_STRING); /* 2nd octet */ - tester_set_bit(buf->om_data, MESH_IVU_TEST_MODE); - tester_set_bit(buf->om_data, MESH_IVU_TOGGLE_STATE); - tester_set_bit(buf->om_data, MESH_NET_SEND); - tester_set_bit(buf->om_data, MESH_HEALTH_GENERATE_FAULTS); - tester_set_bit(buf->om_data, MESH_HEALTH_CLEAR_FAULTS); - tester_set_bit(buf->om_data, MESH_LPN); - tester_set_bit(buf->om_data, MESH_LPN_POLL); - tester_set_bit(buf->om_data, MESH_MODEL_SEND); + tester_set_bit(buf->om_data, BTP_MESH_IVU_TEST_MODE); + tester_set_bit(buf->om_data, BTP_MESH_IVU_TOGGLE_STATE); + tester_set_bit(buf->om_data, BTP_MESH_NET_SEND); + tester_set_bit(buf->om_data, BTP_MESH_HEALTH_GENERATE_FAULTS); + tester_set_bit(buf->om_data, BTP_MESH_HEALTH_CLEAR_FAULTS); + tester_set_bit(buf->om_data, BTP_MESH_LPN); + tester_set_bit(buf->om_data, BTP_MESH_LPN_POLL); + tester_set_bit(buf->om_data, BTP_MESH_MODEL_SEND); /* 3rd octet */ memset(net_buf_simple_add(buf, 1), 0, 1); #if MYNEWT_VAL(BLE_MESH_TESTING) - tester_set_bit(buf->om_data, MESH_LPN_SUBSCRIBE); - tester_set_bit(buf->om_data, MESH_LPN_UNSUBSCRIBE); - tester_set_bit(buf->om_data, MESH_RPL_CLEAR); + tester_set_bit(buf->om_data, BTP_MESH_LPN_SUBSCRIBE); + tester_set_bit(buf->om_data, BTP_MESH_LPN_UNSUBSCRIBE); + tester_set_bit(buf->om_data, BTP_MESH_RPL_CLEAR); #endif /* CONFIG_BT_TESTING */ - tester_set_bit(buf->om_data, MESH_PROXY_IDENTITY); + tester_set_bit(buf->om_data, BTP_MESH_PROXY_IDENTITY); - tester_send_buf(BTP_SERVICE_ID_MESH, MESH_READ_SUPPORTED_COMMANDS, + tester_send_buf(BTP_SERVICE_ID_MESH, BTP_MESH_READ_SUPPORTED_COMMANDS, CONTROLLER_INDEX, buf); } @@ -266,16 +266,16 @@ static struct bt_mesh_elem elements[] = { static void link_open(bt_mesh_prov_bearer_t bearer) { - struct mesh_prov_link_open_ev ev; + struct btp_mesh_prov_link_open_ev ev; SYS_LOG_DBG("bearer 0x%02x", bearer); switch (bearer) { case BT_MESH_PROV_ADV: - ev.bearer = MESH_PROV_BEARER_PB_ADV; + ev.bearer = BTP_MESH_PROV_BEARER_PB_ADV; break; case BT_MESH_PROV_GATT: - ev.bearer = MESH_PROV_BEARER_PB_GATT; + ev.bearer = BTP_MESH_PROV_BEARER_PB_GATT; break; default: SYS_LOG_ERR("Invalid bearer"); @@ -283,23 +283,23 @@ link_open(bt_mesh_prov_bearer_t bearer) return; } - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROV_LINK_OPEN, + tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROV_LINK_OPEN, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } static void link_close(bt_mesh_prov_bearer_t bearer) { - struct mesh_prov_link_closed_ev ev; + struct btp_mesh_prov_link_closed_ev ev; SYS_LOG_DBG("bearer 0x%02x", bearer); switch (bearer) { case BT_MESH_PROV_ADV: - ev.bearer = MESH_PROV_BEARER_PB_ADV; + ev.bearer = BTP_MESH_PROV_BEARER_PB_ADV; break; case BT_MESH_PROV_GATT: - ev.bearer = MESH_PROV_BEARER_PB_GATT; + ev.bearer = BTP_MESH_PROV_BEARER_PB_GATT; break; default: SYS_LOG_ERR("Invalid bearer"); @@ -307,21 +307,21 @@ link_close(bt_mesh_prov_bearer_t bearer) return; } - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROV_LINK_CLOSED, + tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROV_LINK_CLOSED, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } static int output_number(bt_mesh_output_action_t action, uint32_t number) { - struct mesh_out_number_action_ev ev; + struct btp_mesh_out_number_action_ev ev; SYS_LOG_DBG("action 0x%04x number 0x%08lx", action, number); ev.action = sys_cpu_to_le16(action); ev.number = sys_cpu_to_le32(number); - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_OUT_NUMBER_ACTION, + tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_OUT_NUMBER_ACTION, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); return 0; @@ -330,8 +330,8 @@ output_number(bt_mesh_output_action_t action, uint32_t number) static int output_string(const char *str) { - struct mesh_out_string_action_ev *ev; - struct os_mbuf *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE); + struct btp_mesh_out_string_action_ev *ev; + struct os_mbuf *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE); SYS_LOG_DBG("str %s", str); @@ -342,7 +342,7 @@ output_string(const char *str) net_buf_simple_add_mem(buf, str, ev->string_len); - tester_send_buf(BTP_SERVICE_ID_MESH, MESH_EV_OUT_STRING_ACTION, + tester_send_buf(BTP_SERVICE_ID_MESH, BTP_MESH_EV_OUT_STRING_ACTION, CONTROLLER_INDEX, buf); os_mbuf_free_chain(buf); @@ -352,7 +352,7 @@ output_string(const char *str) static int input(bt_mesh_input_action_t action, uint8_t size) { - struct mesh_in_action_ev ev; + struct btp_mesh_in_action_ev ev; SYS_LOG_DBG("action 0x%04x number 0x%02x", action, size); @@ -361,7 +361,7 @@ input(bt_mesh_input_action_t action, uint8_t size) ev.action = sys_cpu_to_le16(action); ev.size = size; - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_IN_ACTION, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_IN_ACTION, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); return 0; @@ -379,7 +379,7 @@ prov_complete(uint16_t net_idx, uint16_t addr) net.local = addr; net.dst = addr; - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROVISIONED, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROVISIONED, CONTROLLER_INDEX, NULL, 0); } @@ -413,7 +413,7 @@ static struct bt_mesh_prov prov = { static void config_prov(uint8_t *data, uint16_t len) { - const struct mesh_config_provisioning_cmd *cmd = (void *) data; + const struct btp_mesh_config_provisioning_cmd *cmd = (void *) data; SYS_LOG_DBG(""); @@ -425,14 +425,14 @@ config_prov(uint8_t *data, uint16_t len) prov.input_size = cmd->in_size; prov.input_actions = sys_le16_to_cpu(cmd->in_actions); - tester_rsp(BTP_SERVICE_ID_MESH, MESH_CONFIG_PROVISIONING, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_CONFIG_PROVISIONING, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } static void provision_node(uint8_t *data, uint16_t len) { - const struct mesh_provision_node_cmd *cmd = (void *) data; + const struct btp_mesh_provision_node_cmd *cmd = (void *) data; SYS_LOG_DBG(""); @@ -444,7 +444,7 @@ provision_node(uint8_t *data, uint16_t len) iv_index = sys_le32_to_cpu(cmd->iv_index); net_key_idx = sys_le16_to_cpu(cmd->net_key_idx); - tester_rsp(BTP_SERVICE_ID_MESH, MESH_PROVISION_NODE, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_PROVISION_NODE, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } @@ -477,7 +477,7 @@ init(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_MESH, MESH_INIT, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_INIT, CONTROLLER_INDEX, status); } @@ -488,15 +488,15 @@ reset(uint8_t *data, uint16_t len) bt_mesh_reset(); - tester_rsp(BTP_SERVICE_ID_MESH, MESH_RESET, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_RESET, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } static void input_number(uint8_t *data, uint16_t len) { - const struct mesh_input_number_cmd *cmd = (void *) data; - uint8_t status = BTP_STATUS_SUCCESS; + const struct btp_mesh_input_number_cmd *cmd = (void *) data; + uint8_t status = BTP_STATUS_SUCCESS; uint32_t number; int err; @@ -509,15 +509,15 @@ input_number(uint8_t *data, uint16_t len) status = BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_INPUT_NUMBER, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_INPUT_NUMBER, CONTROLLER_INDEX, status); } static void input_string(uint8_t *data, uint16_t len) { - const struct mesh_input_string_cmd *cmd = (void *) data; - uint8_t status = BTP_STATUS_SUCCESS; + const struct btp_mesh_input_string_cmd *cmd = (void *) data; + uint8_t status = BTP_STATUS_SUCCESS; uint8_t str_auth[16]; int err; @@ -541,20 +541,20 @@ input_string(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_MESH, MESH_INPUT_STRING, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_INPUT_STRING, CONTROLLER_INDEX, status); } static void ivu_test_mode(uint8_t *data, uint16_t len) { - const struct mesh_ivu_test_mode_cmd *cmd = (void *) data; + const struct btp_mesh_ivu_test_mode_cmd *cmd = (void *) data; SYS_LOG_DBG("enable 0x%02x", cmd->enable); bt_mesh_iv_update_test(cmd->enable ? true : false); - tester_rsp(BTP_SERVICE_ID_MESH, MESH_IVU_TEST_MODE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_IVU_TEST_MODE, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } @@ -570,14 +570,14 @@ ivu_toggle_state(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to toggle the IV Update state"); } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_IVU_TOGGLE_STATE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_IVU_TOGGLE_STATE, CONTROLLER_INDEX, result ? BTP_STATUS_SUCCESS : BTP_STATUS_FAILED); } static void lpn(uint8_t *data, uint16_t len) { - struct mesh_lpn_set_cmd *cmd = (void *) data; + struct btp_mesh_lpn_set_cmd *cmd = (void *) data; bool enable; int err; @@ -589,7 +589,7 @@ lpn(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to toggle LPN (err %d)", err); } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN, CONTROLLER_INDEX, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } @@ -605,15 +605,15 @@ lpn_poll(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to send poll msg (err %d)", err); } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN_POLL, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN_POLL, CONTROLLER_INDEX, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } static void net_send(uint8_t *data, uint16_t len) { - struct mesh_net_send_cmd *cmd = (void *) data; - struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); + struct btp_mesh_net_send_cmd *cmd = (void *) data; + struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); struct bt_mesh_msg_ctx ctx = { .net_idx = net.net_idx, .app_idx = vnd_app_key_idx, @@ -638,7 +638,7 @@ net_send(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to send (err %d)", err); } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_NET_SEND, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_NET_SEND, CONTROLLER_INDEX, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); os_mbuf_free_chain(msg); @@ -647,8 +647,8 @@ net_send(uint8_t *data, uint16_t len) static void health_generate_faults(uint8_t *data, uint16_t len) { - struct mesh_health_generate_faults_rp *rp; - struct os_mbuf *buf = NET_BUF_SIMPLE(sizeof(*rp) + sizeof(cur_faults) + + struct btp_mesh_health_generate_faults_rp *rp; + struct os_mbuf *buf = NET_BUF_SIMPLE(sizeof(*rp) + sizeof(cur_faults) + sizeof(reg_faults)); uint8_t some_faults[] = {0x01, 0x02, 0x03, 0xff, 0x06}; uint8_t cur_faults_count, reg_faults_count; @@ -667,7 +667,7 @@ health_generate_faults(uint8_t *data, uint16_t len) bt_mesh_fault_update(&elements[0]); - tester_send_buf(BTP_SERVICE_ID_MESH, MESH_HEALTH_GENERATE_FAULTS, + tester_send_buf(BTP_SERVICE_ID_MESH, BTP_MESH_HEALTH_GENERATE_FAULTS, CONTROLLER_INDEX, buf); } @@ -681,15 +681,15 @@ health_clear_faults(uint8_t *data, uint16_t len) bt_mesh_fault_update(&elements[0]); - tester_rsp(BTP_SERVICE_ID_MESH, MESH_HEALTH_CLEAR_FAULTS, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_HEALTH_CLEAR_FAULTS, CONTROLLER_INDEX, BTP_STATUS_SUCCESS); } static void model_send(uint8_t *data, uint16_t len) { - struct mesh_model_send_cmd *cmd = (void *) data; - struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); + struct btp_mesh_model_send_cmd *cmd = (void *) data; + struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); struct bt_mesh_msg_ctx ctx = { .net_idx = net.net_idx, .app_idx = BT_MESH_KEY_DEV, @@ -728,7 +728,7 @@ model_send(uint8_t *data, uint16_t len) } fail: - tester_rsp(BTP_SERVICE_ID_MESH, MESH_MODEL_SEND, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_MODEL_SEND, CONTROLLER_INDEX, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); os_mbuf_free_chain(msg); @@ -739,8 +739,8 @@ model_send(uint8_t *data, uint16_t len) static void lpn_subscribe(uint8_t *data, uint16_t len) { - struct mesh_lpn_subscribe_cmd *cmd = (void *) data; - uint16_t address = sys_le16_to_cpu(cmd->address); + struct btp_mesh_lpn_subscribe_cmd *cmd = (void *) data; + uint16_t address = sys_le16_to_cpu(cmd->address); int err; SYS_LOG_DBG("address 0x%04x", address); @@ -750,15 +750,15 @@ lpn_subscribe(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to subscribe (err %d)", err); } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN_SUBSCRIBE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN_SUBSCRIBE, CONTROLLER_INDEX, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } static void lpn_unsubscribe(uint8_t *data, uint16_t len) { - struct mesh_lpn_unsubscribe_cmd *cmd = (void *) data; - uint16_t address = sys_le16_to_cpu(cmd->address); + struct btp_mesh_lpn_unsubscribe_cmd *cmd = (void *) data; + uint16_t address = sys_le16_to_cpu(cmd->address); int err; SYS_LOG_DBG("address 0x%04x", address); @@ -768,7 +768,7 @@ lpn_unsubscribe(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to unsubscribe (err %d)", err); } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_LPN_UNSUBSCRIBE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN_UNSUBSCRIBE, CONTROLLER_INDEX, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } @@ -784,7 +784,7 @@ rpl_clear(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to clear RPL (err %d)", err); } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_RPL_CLEAR, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_RPL_CLEAR, CONTROLLER_INDEX, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } @@ -802,7 +802,7 @@ proxy_identity_enable(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to enable proxy identity (err %d)", err); } - tester_rsp(BTP_SERVICE_ID_MESH, MESH_PROXY_IDENTITY, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_PROXY_IDENTITY, CONTROLLER_INDEX, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } @@ -810,63 +810,63 @@ void tester_handle_mesh(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len) { switch (opcode) { - case MESH_READ_SUPPORTED_COMMANDS: + case BTP_MESH_READ_SUPPORTED_COMMANDS: supported_commands(data, len); break; - case MESH_CONFIG_PROVISIONING: + case BTP_MESH_CONFIG_PROVISIONING: config_prov(data, len); break; - case MESH_PROVISION_NODE: + case BTP_MESH_PROVISION_NODE: provision_node(data, len); break; - case MESH_INIT: + case BTP_MESH_INIT: init(data, len); break; - case MESH_RESET: + case BTP_MESH_RESET: reset(data, len); break; - case MESH_INPUT_NUMBER: + case BTP_MESH_INPUT_NUMBER: input_number(data, len); break; - case MESH_INPUT_STRING: + case BTP_MESH_INPUT_STRING: input_string(data, len); break; - case MESH_IVU_TEST_MODE: + case BTP_MESH_IVU_TEST_MODE: ivu_test_mode(data, len); break; - case MESH_IVU_TOGGLE_STATE: + case BTP_MESH_IVU_TOGGLE_STATE: ivu_toggle_state(data, len); break; - case MESH_LPN: + case BTP_MESH_LPN: lpn(data, len); break; - case MESH_LPN_POLL: + case BTP_MESH_LPN_POLL: lpn_poll(data, len); break; - case MESH_NET_SEND: + case BTP_MESH_NET_SEND: net_send(data, len); break; - case MESH_HEALTH_GENERATE_FAULTS: + case BTP_MESH_HEALTH_GENERATE_FAULTS: health_generate_faults(data, len); break; - case MESH_HEALTH_CLEAR_FAULTS: + case BTP_MESH_HEALTH_CLEAR_FAULTS: health_clear_faults(data, len); break; - case MESH_MODEL_SEND: + case BTP_MESH_MODEL_SEND: model_send(data, len); break; #if MYNEWT_VAL(BLE_MESH_TESTING) - case MESH_LPN_SUBSCRIBE: + case BTP_MESH_LPN_SUBSCRIBE: lpn_subscribe(data, len); break; - case MESH_LPN_UNSUBSCRIBE: + case BTP_MESH_LPN_UNSUBSCRIBE: lpn_unsubscribe(data, len); break; - case MESH_RPL_CLEAR: + case BTP_MESH_RPL_CLEAR: rpl_clear(data, len); break; #endif /* MYNEWT_VAL(BLE_MESH_TESTING) */ - case MESH_PROXY_IDENTITY: + case BTP_MESH_PROXY_IDENTITY: proxy_identity_enable(data, len); break; default: @@ -884,8 +884,8 @@ net_recv_ev(uint8_t ttl, const void *payload, size_t payload_len) { - struct os_mbuf *buf = NET_BUF_SIMPLE(UINT8_MAX); - struct mesh_net_recv_ev *ev; + struct os_mbuf *buf = NET_BUF_SIMPLE(UINT8_MAX); + struct btp_mesh_net_recv_ev *ev; SYS_LOG_DBG("ttl 0x%02x ctl 0x%02x src 0x%04x dst 0x%04x " "payload_len %d", ttl, ctl, src, dst, payload_len); @@ -904,7 +904,7 @@ net_recv_ev(uint8_t ttl, ev->payload_len = payload_len; net_buf_simple_add_mem(buf, payload, payload_len); - tester_send_buf(BTP_SERVICE_ID_MESH, MESH_EV_NET_RECV, CONTROLLER_INDEX, + tester_send_buf(BTP_SERVICE_ID_MESH, BTP_MESH_EV_NET_RECV, CONTROLLER_INDEX, buf); done: os_mbuf_free_chain(buf); @@ -957,20 +957,20 @@ model_unbound_cb(uint16_t addr, struct bt_mesh_model *model, static void invalid_bearer_cb(uint8_t opcode) { - struct mesh_invalid_bearer_ev ev = { + struct btp_mesh_invalid_bearer_ev ev = { .opcode = opcode, }; SYS_LOG_DBG("opcode 0x%02x", opcode); - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_INVALID_BEARER, + tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_INVALID_BEARER, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } static void incomp_timer_exp_cb(void) { - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_INCOMP_TIMER_EXP, + tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_INCOMP_TIMER_EXP, CONTROLLER_INDEX, NULL, 0); } @@ -987,7 +987,7 @@ lpn_established(uint16_t friend_addr) { struct bt_mesh_lpn *lpn = &bt_mesh.lpn; - struct mesh_lpn_established_ev + struct btp_mesh_lpn_established_ev ev = {lpn->sub->net_idx, friend_addr, lpn->queue_size, lpn->recv_win}; @@ -995,20 +995,20 @@ lpn_established(uint16_t friend_addr) "Friend 0x%04x Queue Size %d Receive Window %d", friend_addr, lpn->queue_size, lpn->recv_win); - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_LPN_ESTABLISHED, + tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_LPN_ESTABLISHED, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } static void lpn_terminated(uint16_t friend_addr) { - struct bt_mesh_lpn *lpn = &bt_mesh.lpn; - struct mesh_lpn_terminated_ev ev = {lpn->sub->net_idx, friend_addr}; + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + struct btp_mesh_lpn_terminated_ev ev = {lpn->sub->net_idx, friend_addr}; SYS_LOG_DBG("Friendship (as LPN) lost with Friend " "0x%04x", friend_addr); - tester_send(BTP_SERVICE_ID_MESH, MESH_EV_LPN_TERMINATED, + tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_LPN_TERMINATED, CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } diff --git a/apps/bttester/src/bttester.c b/apps/bttester/src/bttester.c index 62219f565a..1bb22e7cfc 100644 --- a/apps/bttester/src/bttester.c +++ b/apps/bttester/src/bttester.c @@ -33,7 +33,7 @@ #include "console/console.h" #include "bttester_pipe.h" -#include "bttester.h" +#include "btp/btp.h" #define CMD_QUEUED 2 @@ -51,145 +51,6 @@ struct btp_buf { static struct btp_buf cmd_buf[CMD_QUEUED]; -static void -supported_commands(uint8_t *data, uint16_t len) -{ - uint8_t buf[1]; - struct core_read_supported_commands_rp *rp = (void *) buf; - - memset(buf, 0, sizeof(buf)); - - tester_set_bit(buf, CORE_READ_SUPPORTED_COMMANDS); - tester_set_bit(buf, CORE_READ_SUPPORTED_SERVICES); - tester_set_bit(buf, CORE_REGISTER_SERVICE); - tester_set_bit(buf, CORE_UNREGISTER_SERVICE); - - tester_send(BTP_SERVICE_ID_CORE, CORE_READ_SUPPORTED_COMMANDS, - BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); -} - -static void -supported_services(uint8_t *data, uint16_t len) -{ - uint8_t buf[1]; - struct core_read_supported_services_rp *rp = (void *) buf; - - memset(buf, 0, sizeof(buf)); - - tester_set_bit(buf, BTP_SERVICE_ID_CORE); - tester_set_bit(buf, BTP_SERVICE_ID_GAP); - tester_set_bit(buf, BTP_SERVICE_ID_GATT); -#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) - tester_set_bit(buf, BTP_SERVICE_ID_L2CAP); -#endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */ -#if MYNEWT_VAL(BLE_MESH) - tester_set_bit(buf, BTP_SERVICE_ID_MESH); -#endif /* MYNEWT_VAL(BLE_MESH) */ - tester_set_bit(buf, BTP_SERVICE_ID_GATTC); - - tester_send(BTP_SERVICE_ID_CORE, CORE_READ_SUPPORTED_SERVICES, - BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); -} - -static void -register_service(uint8_t *data, uint16_t len) -{ - struct core_register_service_cmd *cmd = (void *) data; - uint8_t status; - - switch (cmd->id) { - case BTP_SERVICE_ID_GAP: - status = tester_init_gap(); - /* Rsp with success status will be handled by bt enable cb */ - if (status == BTP_STATUS_FAILED) { - goto rsp; - } - return; - case BTP_SERVICE_ID_GATT: - status = tester_init_gatt(); - break; -#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) - case BTP_SERVICE_ID_L2CAP: - status = tester_init_l2cap(); - break; -#endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */ -#if MYNEWT_VAL(BLE_MESH) - case BTP_SERVICE_ID_MESH: - status = tester_init_mesh(); - break; -#endif /* MYNEWT_VAL(BLE_MESH) */ - default: - status = BTP_STATUS_FAILED; - break; - } - -rsp: - tester_rsp(BTP_SERVICE_ID_CORE, CORE_REGISTER_SERVICE, BTP_INDEX_NONE, - status); -} - -static void -unregister_service(uint8_t *data, uint16_t len) -{ - struct core_unregister_service_cmd *cmd = (void *) data; - uint8_t status; - - switch (cmd->id) { - case BTP_SERVICE_ID_GAP: - status = tester_unregister_gap(); - break; - case BTP_SERVICE_ID_GATT: - status = tester_unregister_gatt(); - break; -#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) - case BTP_SERVICE_ID_L2CAP: - status = tester_unregister_l2cap(); - break; -#endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */ -#if MYNEWT_VAL(BLE_MESH) - case BTP_SERVICE_ID_MESH: - status = tester_unregister_mesh(); - break; -#endif /* MYNEWT_VAL(BLE_MESH) */ - default: - status = BTP_STATUS_FAILED; - break; - } - - tester_rsp(BTP_SERVICE_ID_CORE, CORE_UNREGISTER_SERVICE, BTP_INDEX_NONE, - status); -} - -static void -handle_core(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len) -{ - if (index != BTP_INDEX_NONE) { - tester_rsp(BTP_SERVICE_ID_CORE, opcode, index, - BTP_STATUS_FAILED); - return; - } - - switch (opcode) { - case CORE_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - return; - case CORE_READ_SUPPORTED_SERVICES: - supported_services(data, len); - return; - case CORE_REGISTER_SERVICE: - register_service(data, len); - return; - case CORE_UNREGISTER_SERVICE: - unregister_service(data, len); - return; - default: - tester_rsp(BTP_SERVICE_ID_CORE, opcode, BTP_INDEX_NONE, - BTP_STATUS_UNKNOWN_CMD); - return; - } -} - static void cmd_handler(struct os_event *ev) { @@ -216,7 +77,7 @@ cmd_handler(struct os_event *ev) switch (cmd->hdr.service) { case BTP_SERVICE_ID_CORE: - handle_core(cmd->hdr.opcode, cmd->hdr.index, + tester_handle_core(cmd->hdr.opcode, cmd->hdr.index, cmd->hdr.data, len); break; case BTP_SERVICE_ID_GAP: @@ -330,7 +191,7 @@ tester_init(void) bttester_pipe_register(buf->data, BTP_MTU, recv_cb); - tester_send(BTP_SERVICE_ID_CORE, CORE_EV_IUT_READY, BTP_INDEX_NONE, + tester_send(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, BTP_INDEX_NONE, NULL, 0); } diff --git a/apps/bttester/src/bttester.h b/apps/bttester/src/bttester.h deleted file mode 100644 index 87bb275b89..0000000000 --- a/apps/bttester/src/bttester.h +++ /dev/null @@ -1,1361 +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. - */ - -/* bttester.h - Bluetooth tester headers */ - -/* - * Copyright (C) 2021 Codecoup - * Copyright (c) 2015-2016 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __BTTESTER_H__ -#define __BTTESTER_H__ - -#include "syscfg/syscfg.h" -#include "host/ble_gatt.h" - -#if MYNEWT_VAL(BLE_MESH) -#include "mesh/glue.h" -#else -#include "glue.h" -#endif - -#define BTP_MTU MYNEWT_VAL(BTTESTER_BTP_DATA_SIZE_MAX) -#define BTP_DATA_MAX_SIZE (BTP_MTU - sizeof(struct btp_hdr)) - -#define BTP_INDEX_NONE 0xff - -#define BTP_SERVICE_ID_CORE 0 -#define BTP_SERVICE_ID_GAP 1 -#define BTP_SERVICE_ID_GATT 2 -#define BTP_SERVICE_ID_L2CAP 3 -#define BTP_SERVICE_ID_MESH 4 -#define BTP_SERVICE_ID_GATTC 6 - -#define BTP_STATUS_SUCCESS 0x00 -#define BTP_STATUS_FAILED 0x01 -#define BTP_STATUS_UNKNOWN_CMD 0x02 -#define BTP_STATUS_NOT_READY 0x03 - -#define SYS_LOG_DBG(fmt, ...) \ - if (MYNEWT_VAL(BTTESTER_DEBUG)) { \ - console_printf("[DBG] %s: " fmt "\n", \ - __func__, ## __VA_ARGS__); \ - } -#define SYS_LOG_INF(fmt, ...) console_printf("[INF] %s: " fmt "\n", \ - __func__, ## __VA_ARGS__); -#define SYS_LOG_ERR(fmt, ...) console_printf("[WRN] %s: " fmt "\n", \ - __func__, ## __VA_ARGS__); - -#define SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG -#define SYS_LOG_DOMAIN "bttester" - -#define sys_cpu_to_le32 htole32 -#define sys_le32_to_cpu le32toh -#define sys_cpu_to_le16 htole16 - -struct btp_hdr { - uint8_t service; - uint8_t opcode; - uint8_t index; - uint16_t len; - uint8_t data[0]; -} __packed; - -#define BTP_STATUS 0x00 -struct btp_status { - uint8_t code; -} __packed; - -/* Core Service */ -#define CORE_READ_SUPPORTED_COMMANDS 0x01 -struct core_read_supported_commands_rp { - uint8_t data[0]; -} __packed; - -#define CORE_READ_SUPPORTED_SERVICES 0x02 -struct core_read_supported_services_rp { - uint8_t data[0]; -} __packed; - -#define CORE_REGISTER_SERVICE 0x03 -struct core_register_service_cmd { - uint8_t id; -} __packed; - -#define CORE_UNREGISTER_SERVICE 0x04 -struct core_unregister_service_cmd { - uint8_t id; -} __packed; - -/* events */ -#define CORE_EV_IUT_READY 0x80 - -/* GAP Service */ -/* commands */ -#define GAP_READ_SUPPORTED_COMMANDS 0x01 -struct gap_read_supported_commands_rp { - uint8_t data[0]; -} __packed; - -#define GAP_READ_CONTROLLER_INDEX_LIST 0x02 -struct gap_read_controller_index_list_rp { - uint8_t num; - uint8_t index[0]; -} __packed; - -#define GAP_SETTINGS_POWERED 0 -#define GAP_SETTINGS_CONNECTABLE 1 -#define GAP_SETTINGS_FAST_CONNECTABLE 2 -#define GAP_SETTINGS_DISCOVERABLE 3 -#define GAP_SETTINGS_BONDABLE 4 -#define GAP_SETTINGS_LINK_SEC_3 5 -#define GAP_SETTINGS_SSP 6 -#define GAP_SETTINGS_BREDR 7 -#define GAP_SETTINGS_HS 8 -#define GAP_SETTINGS_LE 9 -#define GAP_SETTINGS_ADVERTISING 10 -#define GAP_SETTINGS_SC 11 -#define GAP_SETTINGS_DEBUG_KEYS 12 -#define GAP_SETTINGS_PRIVACY 13 -#define GAP_SETTINGS_CONTROLLER_CONFIG 14 -#define GAP_SETTINGS_STATIC_ADDRESS 15 - -#define GAP_READ_CONTROLLER_INFO 0x03 -struct gap_read_controller_info_rp { - uint8_t address[6]; - uint32_t supported_settings; - uint32_t current_settings; - uint8_t cod[3]; - uint8_t name[249]; - uint8_t short_name[11]; -} __packed; - -#define GAP_RESET 0x04 -struct gap_reset_rp { - uint32_t current_settings; -} __packed; - -#define GAP_SET_POWERED 0x05 -struct gap_set_powered_cmd { - uint8_t powered; -} __packed; -struct gap_set_powered_rp { - uint32_t current_settings; -} __packed; - -#define GAP_SET_CONNECTABLE 0x06 -struct gap_set_connectable_cmd { - uint8_t connectable; -} __packed; -struct gap_set_connectable_rp { - uint32_t current_settings; -} __packed; - -#define GAP_SET_FAST_CONNECTABLE 0x07 -struct gap_set_fast_connectable_cmd { - uint8_t fast_connectable; -} __packed; -struct gap_set_fast_connectable_rp { - uint32_t current_settings; -} __packed; - -#define GAP_NON_DISCOVERABLE 0x00 -#define GAP_GENERAL_DISCOVERABLE 0x01 -#define GAP_LIMITED_DISCOVERABLE 0x02 - -#define GAP_SET_DISCOVERABLE 0x08 -struct gap_set_discoverable_cmd { - uint8_t discoverable; -} __packed; -struct gap_set_discoverable_rp { - uint32_t current_settings; -} __packed; - -#define GAP_SET_BONDABLE 0x09 -struct gap_set_bondable_cmd { - uint8_t bondable; -} __packed; -struct gap_set_bondable_rp { - uint32_t current_settings; -} __packed; - -#define GAP_START_ADVERTISING 0x0a -struct gap_start_advertising_cmd { - uint8_t adv_data_len; - uint8_t scan_rsp_len; - uint8_t adv_data[0]; - uint8_t scan_rsp[0]; -} __packed; -struct gap_start_advertising_rp { - uint32_t current_settings; -} __packed; - -#define GAP_STOP_ADVERTISING 0x0b -struct gap_stop_advertising_rp { - uint32_t current_settings; -} __packed; - -#define GAP_DISCOVERY_FLAG_LE 0x01 -#define GAP_DISCOVERY_FLAG_BREDR 0x02 -#define GAP_DISCOVERY_FLAG_LIMITED 0x04 -#define GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN 0x08 -#define GAP_DISCOVERY_FLAG_LE_OBSERVE 0x10 - -#define GAP_START_DISCOVERY 0x0c -struct gap_start_discovery_cmd { - uint8_t flags; -} __packed; - -#define GAP_STOP_DISCOVERY 0x0d - -#define GAP_CONNECT 0x0e -struct gap_connect_cmd { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GAP_DISCONNECT 0x0f -struct gap_disconnect_cmd { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GAP_IO_CAP_DISPLAY_ONLY 0 -#define GAP_IO_CAP_DISPLAY_YESNO 1 -#define GAP_IO_CAP_KEYBOARD_ONLY 2 -#define GAP_IO_CAP_NO_INPUT_OUTPUT 3 -#define GAP_IO_CAP_KEYBOARD_DISPLAY 4 - -#define GAP_SET_IO_CAP 0x10 -struct gap_set_io_cap_cmd { - uint8_t io_cap; -} __packed; - -#define GAP_PAIR 0x11 -struct gap_pair_cmd { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GAP_UNPAIR 0x12 -struct gap_unpair_cmd { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GAP_PASSKEY_ENTRY 0x13 -struct gap_passkey_entry_cmd { - uint8_t address_type; - uint8_t address[6]; - uint32_t passkey; -} __packed; - -#define GAP_PASSKEY_CONFIRM 0x14 -struct gap_passkey_confirm_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t match; -} __packed; - -#define GAP_START_DIRECT_ADV 0x15 -struct gap_start_direct_adv_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t high_duty; -} __packed; - -#define GAP_CONN_PARAM_UPDATE 0x16 -struct gap_conn_param_update_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t conn_itvl_min; - uint16_t conn_itvl_max; - uint16_t conn_latency; - uint16_t supervision_timeout; -} __packed; - -#define GAP_PAIRING_CONSENT_RSP 0x17 -struct gap_pairing_consent_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t consent; -} __packed; - -#define GAP_OOB_LEGACY_SET_DATA 0x18 -struct gap_oob_legacy_set_data_cmd { - uint8_t oob_data[16]; -} __packed; - -#define GAP_OOB_SC_GET_LOCAL_DATA 0x19 -struct gap_oob_sc_get_local_data_rp { - uint8_t r[16]; - uint8_t c[16]; -} __packed; - -#define GAP_OOB_SC_SET_REMOTE_DATA 0x1a -struct gap_oob_sc_set_remote_data_cmd { - uint8_t r[16]; - uint8_t c[16]; -} __packed; - -#define GAP_SET_MITM 0x1b -struct gap_set_mitm_cmd { - uint8_t mitm; -} __packed; - -#define GAP_SET_FILTER_ACCEPT_LIST 0x1c -struct gap_set_filter_accept_list_cmd { - uint8_t list_len; - ble_addr_t addrs[]; -} __packed; -/* events */ -#define GAP_EV_NEW_SETTINGS 0x80 -struct gap_new_settings_ev { - uint32_t current_settings; -} __packed; - -#define GAP_DEVICE_FOUND_FLAG_RSSI 0x01 -#define GAP_DEVICE_FOUND_FLAG_AD 0x02 -#define GAP_DEVICE_FOUND_FLAG_SD 0x04 - -#define GAP_EV_DEVICE_FOUND 0x81 -struct gap_device_found_ev { - uint8_t address_type; - uint8_t address[6]; - int8_t rssi; - uint8_t flags; - uint16_t eir_data_len; - uint8_t eir_data[0]; -} __packed; - -#define GAP_EV_DEVICE_CONNECTED 0x82 -struct gap_device_connected_ev { - uint8_t address_type; - uint8_t address[6]; - uint16_t conn_itvl; - uint16_t conn_latency; - uint16_t supervision_timeout; -} __packed; - -#define GAP_EV_DEVICE_DISCONNECTED 0x83 -struct gap_device_disconnected_ev { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GAP_EV_PASSKEY_DISPLAY 0x84 -struct gap_passkey_display_ev { - uint8_t address_type; - uint8_t address[6]; - uint32_t passkey; -} __packed; - -#define GAP_EV_PASSKEY_ENTRY_REQ 0x85 -struct gap_passkey_entry_req_ev { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GAP_EV_PASSKEY_CONFIRM_REQ 0x86 -struct gap_passkey_confirm_req_ev { - uint8_t address_type; - uint8_t address[6]; - uint32_t passkey; -} __packed; - -#define GAP_EV_IDENTITY_RESOLVED 0x87 -struct gap_identity_resolved_ev { - uint8_t address_type; - uint8_t address[6]; - uint8_t identity_address_type; - uint8_t identity_address[6]; -} __packed; - -#define GAP_EV_CONN_PARAM_UPDATE 0x88 -struct gap_conn_param_update_ev { - uint8_t address_type; - uint8_t address[6]; - uint16_t conn_itvl; - uint16_t conn_latency; - uint16_t supervision_timeout; -} __packed; - -#define GAP_EV_SEC_LEVEL_CHANGED 0x89 -struct gap_sec_level_changed_ev { - uint8_t address_type; - uint8_t address[6]; - uint8_t level; -} __packed; - -#define GAP_EV_PAIRING_CONSENT_REQ 0x8a -struct gap_pairing_consent_req_ev { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GAP_EV_BOND_LOST 0x8b -struct gap_bond_lost_ev { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GAP_EV_SEC_PAIRING_FAILED 0x8c -struct gap_sec_pairing_failed_ev { - uint8_t address_type; - uint8_t address[6]; - uint8_t reason; -} __packed; - -/* GATT Service */ -/* commands */ -#define GATT_READ_SUPPORTED_COMMANDS 0x01 -struct gatt_read_supported_commands_rp { - uint8_t data[0]; -} __packed; - -#define GATT_SERVICE_PRIMARY 0x00 -#define GATT_SERVICE_SECONDARY 0x01 - -#define GATT_ADD_SERVICE 0x02 -struct gatt_add_service_cmd { - uint8_t type; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; -struct gatt_add_service_rp { - uint16_t svc_id; -} __packed; - -#define GATT_ADD_CHARACTERISTIC 0x03 -struct gatt_add_characteristic_cmd { - uint16_t svc_id; - uint8_t properties; - uint8_t permissions; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; -struct gatt_add_characteristic_rp { - uint16_t char_id; -} __packed; - -#define GATT_ADD_DESCRIPTOR 0x04 -struct gatt_add_descriptor_cmd { - uint16_t char_id; - uint8_t permissions; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; -struct gatt_add_descriptor_rp { - uint16_t desc_id; -} __packed; - -#define GATT_ADD_INCLUDED_SERVICE 0x05 -struct gatt_add_included_service_cmd { - uint16_t svc_id; -} __packed; -struct gatt_add_included_service_rp { - uint16_t included_service_id; -} __packed; - -#define GATT_SET_VALUE 0x06 -struct gatt_set_value_cmd { - uint16_t attr_id; - uint16_t len; - uint8_t value[0]; -} __packed; - -#define GATT_START_SERVER 0x07 -struct gatt_start_server_rp { - uint16_t db_attr_off; - uint8_t db_attr_cnt; -} __packed; - -#define GATT_SET_ENC_KEY_SIZE 0x09 -struct gatt_set_enc_key_size_cmd { - uint16_t attr_id; - uint8_t key_size; -} __packed; - -/* Gatt Client */ -struct gatt_service { - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; - -struct gatt_included { - uint16_t included_handle; - struct gatt_service service; -} __packed; - -struct gatt_read_uuid_chr { - uint16_t handle; - uint8_t data[0]; -} __packed; - -struct gatt_characteristic { - uint16_t characteristic_handle; - uint16_t value_handle; - uint8_t properties; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; - -struct gatt_descriptor { - uint16_t descriptor_handle; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; - -#define GATT_EXCHANGE_MTU 0x0a - -#define GATT_DISC_ALL_PRIM_SVCS 0x0b -struct gatt_disc_all_prim_svcs_cmd { - uint8_t address_type; - uint8_t address[6]; -} __packed; -struct gatt_disc_all_prim_svcs_rp { - uint8_t services_count; - struct gatt_service services[0]; -} __packed; - -#define GATT_DISC_PRIM_UUID 0x0c -struct gatt_disc_prim_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; -struct gatt_disc_prim_uuid_rp { - uint8_t services_count; - struct gatt_service services[0]; -} __packed; - -#define GATT_FIND_INCLUDED 0x0d -struct gatt_find_included_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; -} __packed; -struct gatt_find_included_rp { - uint8_t services_count; - struct gatt_included included[0]; -} __packed; - -#define GATT_DISC_ALL_CHRC 0x0e -struct gatt_disc_all_chrc_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; -} __packed; -struct gatt_disc_chrc_rp { - uint8_t characteristics_count; - struct gatt_characteristic characteristics[0]; -} __packed; - -#define GATT_DISC_CHRC_UUID 0x0f -struct gatt_disc_chrc_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; - -#define GATT_DISC_ALL_DESC 0x10 -struct gatt_disc_all_desc_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; -} __packed; -struct gatt_disc_all_desc_rp { - uint8_t descriptors_count; - struct gatt_descriptor descriptors[0]; -} __packed; - -#define GATT_READ 0x11 -struct gatt_read_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; -} __packed; -struct gatt_read_rp { - uint8_t att_response; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATT_READ_UUID 0x12 -struct gatt_read_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; - -#define GATT_READ_LONG 0x13 -struct gatt_read_long_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; -} __packed; - -#define GATT_READ_MULTIPLE 0x14 -struct gatt_read_multiple_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t handles_count; - uint16_t handles[0]; -} __packed; - -#define GATT_WRITE_WITHOUT_RSP 0x15 -struct gatt_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATT_SIGNED_WRITE_WITHOUT_RSP 0x16 -struct gatt_signed_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATT_WRITE 0x17 -struct gatt_write_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATT_WRITE_LONG 0x18 -struct gatt_write_long_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATT_RELIABLE_WRITE 0x19 -struct gatt_reliable_write_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATT_CFG_NOTIFY 0x1a -#define GATT_CFG_INDICATE 0x1b -struct gatt_cfg_notify_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t enable; - uint16_t ccc_handle; -} __packed; - -#define GATT_GET_ATTRIBUTES 0x1c -struct gatt_get_attributes_cmd { - uint16_t start_handle; - uint16_t end_handle; - uint8_t type_length; - uint8_t type[0]; -} __packed; -struct gatt_get_attributes_rp { - uint8_t attrs_count; - uint8_t attrs[0]; -} __packed; -struct gatt_attr { - uint16_t handle; - uint8_t permission; - uint8_t type_length; - uint8_t type[0]; -} __packed; - -#define GATT_GET_ATTRIBUTE_VALUE 0x1d -struct gatt_get_attribute_value_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; -} __packed; -struct gatt_get_attribute_value_rp { - uint8_t att_response; - uint16_t value_length; - uint8_t value[0]; -} __packed; - -#define GATT_CHANGE_DATABASE 0x1e -struct gatt_change_database { - uint16_t start_handle; - uint16_t end_handle; - uint8_t visibility; -} __packed; - -/* GATT events */ -#define GATT_EV_NOTIFICATION 0x80 -struct gatt_notification_ev { - uint8_t address_type; - uint8_t address[6]; - uint8_t type; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATT_EV_ATTR_VALUE_CHANGED 0x81 -struct gatt_attr_value_changed_ev { - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -static inline void -tester_set_bit(uint8_t *addr, unsigned int bit) -{ - uint8_t *p = addr + (bit / 8); - - *p |= BIT(bit % 8); -} - -static inline uint8_t -tester_test_bit(const uint8_t *addr, unsigned int bit) -{ - const uint8_t *p = addr + (bit / 8); - - return *p & BIT(bit % 8); -} - -/* L2CAP Service */ -/* commands */ -#define L2CAP_READ_SUPPORTED_COMMANDS 0x01 -struct l2cap_read_supported_commands_rp { - uint8_t data[0]; -} __packed; - -#define L2CAP_CONNECT_OPT_ECFC 0x01 -#define L2CAP_CONNECT_OPT_HOLD_CREDIT 0x02 - -#define L2CAP_CONNECT 0x02 -struct l2cap_connect_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t psm; - uint16_t mtu; - uint8_t num; - uint8_t options; -} __packed; - -struct l2cap_connect_rp { - uint8_t num; - uint8_t chan_ids[0]; -} __packed; - -#define L2CAP_DISCONNECT 0x03 -struct l2cap_disconnect_cmd { - uint8_t chan_id; -} __packed; - -#define L2CAP_SEND_DATA 0x04 -struct l2cap_send_data_cmd { - uint8_t chan_id; - uint16_t data_len; - uint8_t data[]; -} __packed; - -#define L2CAP_TRANSPORT_BREDR 0x00 -#define L2CAP_TRANSPORT_LE 0x01 - -#define L2CAP_LISTEN 0x05 -struct l2cap_listen_cmd { - uint16_t psm; - uint8_t transport; - uint16_t mtu; - uint16_t response; -} __packed; - -#define L2CAP_ACCEPT_CONNECTION 0x06 -struct l2cap_accept_connection_cmd { - uint8_t chan_id; - uint16_t result; -} __packed; - -#define L2CAP_RECONFIGURE 0x07 -struct l2cap_reconfigure_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t mtu; - uint8_t num; - uint8_t idxs[]; -} __packed; - -#define L2CAP_CREDITS 0x08 -struct l2cap_credits_cmd { - uint8_t chan_id; -} __packed; - -/* events */ -#define L2CAP_EV_CONNECTION_REQ 0x80 -struct l2cap_connection_req_ev { - uint8_t chan_id; - uint16_t psm; - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define L2CAP_EV_CONNECTED 0x81 -struct l2cap_connected_ev { - uint8_t chan_id; - uint16_t psm; - uint16_t peer_mtu; - uint16_t peer_mps; - uint16_t our_mtu; - uint16_t our_mps; - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define L2CAP_EV_DISCONNECTED 0x82 -struct l2cap_disconnected_ev { - uint16_t result; - uint8_t chan_id; - uint16_t psm; - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define L2CAP_EV_DATA_RECEIVED 0x83 -struct l2cap_data_received_ev { - uint8_t chan_id; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define L2CAP_EV_RECONFIGURED 0x84 -struct l2cap_reconfigured_ev { - uint8_t chan_id; - uint16_t peer_mtu; - uint16_t peer_mps; - uint16_t our_mtu; - uint16_t our_mps; -} __packed; - -/* MESH Service */ -/* commands */ -#define MESH_READ_SUPPORTED_COMMANDS 0x01 -struct mesh_read_supported_commands_rp { - uint8_t data[0]; -} __packed; - -#define MESH_OUT_BLINK BIT(0) -#define MESH_OUT_BEEP BIT(1) -#define MESH_OUT_VIBRATE BIT(2) -#define MESH_OUT_DISPLAY_NUMBER BIT(3) -#define MESH_OUT_DISPLAY_STRING BIT(4) - -#define MESH_IN_PUSH BIT(0) -#define MESH_IN_TWIST BIT(1) -#define MESH_IN_ENTER_NUMBER BIT(2) -#define MESH_IN_ENTER_STRING BIT(3) - -#define MESH_CONFIG_PROVISIONING 0x02 -struct mesh_config_provisioning_cmd { - uint8_t uuid[16]; - uint8_t static_auth[16]; - uint8_t out_size; - uint16_t out_actions; - uint8_t in_size; - uint16_t in_actions; -} __packed; - -#define MESH_PROVISION_NODE 0x03 -struct mesh_provision_node_cmd { - uint8_t net_key[16]; - uint16_t net_key_idx; - uint8_t flags; - uint32_t iv_index; - uint32_t seq_num; - uint16_t addr; - uint8_t dev_key[16]; -} __packed; - -#define MESH_INIT 0x04 -#define MESH_RESET 0x05 -#define MESH_INPUT_NUMBER 0x06 -struct mesh_input_number_cmd { - uint32_t number; -} __packed; - -#define MESH_INPUT_STRING 0x07 -struct mesh_input_string_cmd { - uint8_t string_len; - uint8_t string[0]; -} __packed; - -#define MESH_IVU_TEST_MODE 0x08 -struct mesh_ivu_test_mode_cmd { - uint8_t enable; -} __packed; - -#define MESH_IVU_TOGGLE_STATE 0x09 - -#define MESH_NET_SEND 0x0a -struct mesh_net_send_cmd { - uint8_t ttl; - uint16_t src; - uint16_t dst; - uint8_t payload_len; - uint8_t payload[0]; -} __packed; - -#define MESH_HEALTH_GENERATE_FAULTS 0x0b -struct mesh_health_generate_faults_rp { - uint8_t test_id; - uint8_t cur_faults_count; - uint8_t reg_faults_count; - uint8_t current_faults[0]; - uint8_t registered_faults[0]; -} __packed; - -#define MESH_HEALTH_CLEAR_FAULTS 0x0c - -#define MESH_LPN 0x0d -struct mesh_lpn_set_cmd { - uint8_t enable; -} __packed; - -#define MESH_LPN_POLL 0x0e - -#define MESH_MODEL_SEND 0x0f -struct mesh_model_send_cmd { - uint16_t src; - uint16_t dst; - uint8_t payload_len; - uint8_t payload[0]; -} __packed; - -#define MESH_LPN_SUBSCRIBE 0x10 -struct mesh_lpn_subscribe_cmd { - uint16_t address; -} __packed; - -#define MESH_LPN_UNSUBSCRIBE 0x11 -struct mesh_lpn_unsubscribe_cmd { - uint16_t address; -} __packed; - -#define MESH_RPL_CLEAR 0x12 -#define MESH_PROXY_IDENTITY 0x13 - -/* events */ -#define MESH_EV_OUT_NUMBER_ACTION 0x80 -struct mesh_out_number_action_ev { - uint16_t action; - uint32_t number; -} __packed; - -#define MESH_EV_OUT_STRING_ACTION 0x81 -struct mesh_out_string_action_ev { - uint8_t string_len; - uint8_t string[0]; -} __packed; - -#define MESH_EV_IN_ACTION 0x82 -struct mesh_in_action_ev { - uint16_t action; - uint8_t size; -} __packed; - -#define MESH_EV_PROVISIONED 0x83 - -#define MESH_PROV_BEARER_PB_ADV 0x00 -#define MESH_PROV_BEARER_PB_GATT 0x01 -#define MESH_EV_PROV_LINK_OPEN 0x84 -struct mesh_prov_link_open_ev { - uint8_t bearer; -} __packed; - -#define MESH_EV_PROV_LINK_CLOSED 0x85 -struct mesh_prov_link_closed_ev { - uint8_t bearer; -} __packed; - -#define MESH_EV_NET_RECV 0x86 -struct mesh_net_recv_ev { - uint8_t ttl; - uint8_t ctl; - uint16_t src; - uint16_t dst; - uint8_t payload_len; - uint8_t payload[0]; -} __packed; - -#define MESH_EV_INVALID_BEARER 0x87 -struct mesh_invalid_bearer_ev { - uint8_t opcode; -} __packed; - -#define MESH_EV_INCOMP_TIMER_EXP 0x88 - -#define MESH_EV_LPN_ESTABLISHED 0x8b -struct mesh_lpn_established_ev { - uint16_t net_idx; - uint16_t friend_addr; - uint8_t queue_size; - uint8_t recv_win; -} __packed; - -#define MESH_EV_LPN_TERMINATED 0x8c -struct mesh_lpn_terminated_ev { - uint16_t net_idx; - uint16_t friend_addr; -} __packed; - -#define MESH_EV_LPN_POLLED 0x8d -struct mesh_lpn_polled_ev { - uint16_t net_idx; - uint16_t friend_addr; - uint8_t retry; -} __packed; - -void -tester_init(void); -void -tester_rsp(uint8_t service, uint8_t opcode, uint8_t index, uint8_t status); -void -tester_send(uint8_t service, uint8_t opcode, uint8_t index, uint8_t *data, - size_t len); -void -tester_send_buf(uint8_t service, uint8_t opcode, uint8_t index, - struct os_mbuf *buf); - -uint8_t -tester_init_gap(void); -uint8_t -tester_unregister_gap(void); -void -tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len); -uint8_t -tester_init_gatt(void); -uint8_t -tester_unregister_gatt(void); -void -tester_handle_gatt(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len); -void -tester_handle_gattc(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len); -int -tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, - uint8_t indication, struct os_mbuf *om); -int -tester_gatt_subscribe_ev(uint16_t conn_handle, - uint16_t attr_handle, - uint8_t reason, - uint8_t prev_notify, - uint8_t cur_notify, - uint8_t prev_indicate, - uint8_t cur_indicate); - -#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) -uint8_t -tester_init_l2cap(void); -uint8_t -tester_unregister_l2cap(void); -void -tester_handle_l2cap(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len); -#endif - -#if MYNEWT_VAL(BLE_MESH) -uint8_t -tester_init_mesh(void); -uint8_t -tester_unregister_mesh(void); -void -tester_handle_mesh(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len); -#endif /* MYNEWT_VAL(BLE_MESH) */ - -void -gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); -int -gatt_svr_init(void); - -/* GATT Client Service */ -/* commands */ -#define GATTC_READ_SUPPORTED_COMMANDS 0x01 -struct gattc_read_supported_commands_rp { - uint8_t data[0]; -} __packed; - -#define GATTC_EXCHANGE_MTU 0x02 - -#define GATTC_DISC_ALL_PRIM_SVCS 0x03 -struct gattc_disc_all_prim_svcs_cmd { - uint8_t address_type; - uint8_t address[6]; -} __packed; - -#define GATTC_DISC_PRIM_UUID 0x04 -struct gattc_disc_prim_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; - -#define GATTC_FIND_INCLUDED 0x05 -struct gattc_find_included_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; -} __packed; - -#define GATTC_DISC_ALL_CHRC 0x06 -struct gattc_disc_all_chrc_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; -} __packed; - -#define GATTC_DISC_CHRC_UUID 0x07 -struct gattc_disc_chrc_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; - -#define GATTC_DISC_ALL_DESC 0x08 -struct gattc_disc_all_desc_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; -} __packed; - -#define GATTC_READ 0x09 -struct gattc_read_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; -} __packed; - -#define GATTC_READ_UUID 0x0a -struct gattc_read_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_length; - uint8_t uuid[0]; -} __packed; -struct gattc_read_uuid_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint16_t data_length; - uint8_t value_length; - uint8_t data[0]; -} __packed; - -#define GATTC_READ_LONG 0x0b -struct gattc_read_long_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; -} __packed; - -#define GATTC_READ_MULTIPLE 0x0c -struct gattc_read_multiple_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t handles_count; - uint16_t handles[0]; -} __packed; - -#define GATTC_WRITE_WITHOUT_RSP 0x0d -struct gattc_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATTC_SIGNED_WRITE_WITHOUT_RSP 0x0e -struct gattc_signed_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATTC_WRITE 0x0f -struct gattc_write_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATTC_WRITE_LONG 0x10 -struct gattc_write_long_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATTC_RELIABLE_WRITE 0x11 -struct gattc_reliable_write_cmd { - uint8_t address_type; - uint8_t address[6]; - uint16_t handle; - uint16_t offset; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATTC_CFG_NOTIFY 0x12 -#define GATTC_CFG_INDICATE 0x13 -struct gattc_cfg_notify_cmd { - uint8_t address_type; - uint8_t address[6]; - uint8_t enable; - uint16_t ccc_handle; -} __packed; - -/* events */ -#define GATTC_EV_MTU_EXCHANGED 0x80 -struct gattc_exchange_mtu_ev { - uint8_t address_type; - uint8_t address[6]; - uint16_t mtu; -} __packed; - -#define GATTC_DISC_ALL_PRIM_RP 0x81 -struct gattc_disc_prim_svcs_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint8_t services_count; - uint8_t data[0]; -} __packed; - -#define GATTC_DISC_PRIM_UUID_RP 0x82 - -#define GATTC_FIND_INCLUDED_RP 0x83 -struct gattc_find_included_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint8_t services_count; - struct gatt_included included[0]; -} __packed; - -#define GATTC_DISC_ALL_CHRC_RP 0x84 -#define GATTC_DISC_CHRC_UUID_RP 0x85 -struct gattc_disc_chrc_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint8_t characteristics_count; - struct gatt_characteristic characteristics[0]; -} __packed; - -#define GATTC_DISC_ALL_DESC_RP 0x86 -struct gattc_disc_all_desc_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint8_t descriptors_count; - struct gatt_descriptor descriptors[0]; -} __packed; - -#define GATTC_READ_RP 0x87 -#define GATTC_READ_UUID_RP 0x88 -#define GATTC_READ_LONG_RP 0x89 -#define GATTC_READ_MULTIPLE_RP 0x8a -struct gattc_read_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#define GATTC_WRITE_RP 0x8b -struct gattc_write_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; -} __packed; -#define GATTC_WRITE_LONG_RP 0x8c -#define GATTC_RELIABLE_WRITE_RP 0x8d -#define GATTC_RELIABLE_WRITE_RP 0x8d -#define GATTC_CFG_NOTIFY_RP 0x8e -#define GATTC_CFG_INDICATE_RP 0x8f -struct subscribe_rp { - uint8_t address_type; - uint8_t address[6]; - uint8_t status; -} __packed; - -#define GATTC_EV_NOTIFICATION_RXED 0x90 -struct gattc_notification_ev { - uint8_t address_type; - uint8_t address[6]; - uint8_t type; - uint16_t handle; - uint16_t data_length; - uint8_t data[0]; -} __packed; - -#endif /* __BTTESTER_H__ */ diff --git a/apps/bttester/src/bttester_pipe.h b/apps/bttester/src/bttester_pipe.h index 5f27a41c2c..ac56c575ac 100644 --- a/apps/bttester/src/bttester_pipe.h +++ b/apps/bttester/src/bttester_pipe.h @@ -21,7 +21,7 @@ #define __BTTESTER_PIPE_H__ #include -#include "bttester.h" +#include "btp/bttester.h" #ifdef __cplusplus extern "C" { diff --git a/apps/bttester/src/main.c b/apps/bttester/src/main.c index 8cc48661ae..99dff7e3de 100644 --- a/apps/bttester/src/main.c +++ b/apps/bttester/src/main.c @@ -31,7 +31,7 @@ #include "host/ble_uuid.h" #include "host/ble_hs.h" -#include "bttester.h" +#include "btp/btp.h" static void on_reset(int reason) From 2d4c591e27066cd17769d0e65bc499a43c17f6c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 7 Jul 2023 14:33:08 +0200 Subject: [PATCH 0754/1333] apps/bttester: refactor BTP handling This commit refactors BTP handling to new model, where API is provided for registration of handlers for BTP commands as callbacks. New API provides also size check and common buffer for response. Removes Controlle Index validation from BTP handlers, as these are always 0. Corrected some formatting for variable declarations. This refactors only core and GAP service into new API, rest of services will not work but are compiled. They will be refactored in following commits. --- apps/bttester/src/btp/btp.h | 8 + apps/bttester/src/btp/btp_gap.h | 7 + apps/bttester/src/btp/bttester.h | 32 +- apps/bttester/src/btp_core.c | 176 +++--- apps/bttester/src/btp_gap.c | 900 ++++++++++++++++--------------- apps/bttester/src/btp_gatt.c | 181 +++---- apps/bttester/src/btp_gatt_cl.c | 111 ++-- apps/bttester/src/btp_l2cap.c | 66 +-- apps/bttester/src/btp_mesh.c | 91 ++-- apps/bttester/src/bttester.c | 142 +++-- apps/bttester/src/glue.h | 19 + 11 files changed, 929 insertions(+), 804 deletions(-) diff --git a/apps/bttester/src/btp/btp.h b/apps/bttester/src/btp/btp.h index 3cf172f9b5..996ab7912b 100644 --- a/apps/bttester/src/btp/btp.h +++ b/apps/bttester/src/btp/btp.h @@ -44,6 +44,7 @@ #define BTP_DATA_MAX_SIZE (BTP_MTU - sizeof(struct btp_hdr)) #define BTP_INDEX_NONE 0xff +#define BTP_INDEX 0x00 #define BTP_SERVICE_ID_CORE 0 #define BTP_SERVICE_ID_GAP 1 @@ -52,11 +53,18 @@ #define BTP_SERVICE_ID_MESH 4 #define BTP_SERVICE_ID_GATTC 6 +#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_GATTC + #define BTP_STATUS_SUCCESS 0x00 #define BTP_STATUS_FAILED 0x01 #define BTP_STATUS_UNKNOWN_CMD 0x02 #define BTP_STATUS_NOT_READY 0x03 +/* TODO indicate delay response, should be removed when all commands are + * converted to cmd+status+ev pattern + */ +#define BTP_STATUS_DELAY_REPLY 0xFF + #define SYS_LOG_DBG(fmt, ...) \ if (MYNEWT_VAL(BTTESTER_DEBUG)) { \ console_printf("[DBG] %s: " fmt "\n", \ diff --git a/apps/bttester/src/btp/btp_gap.h b/apps/bttester/src/btp/btp_gap.h index 4a24df678d..5ef756113f 100644 --- a/apps/bttester/src/btp/btp_gap.h +++ b/apps/bttester/src/btp/btp_gap.h @@ -121,6 +121,12 @@ struct btp_gap_start_advertising_cmd { uint8_t scan_rsp_len; uint8_t adv_data[0]; uint8_t scan_rsp[0]; +/* + * This command is very unfortunate because it has two fields after variable + * data. Those needs to be handled explicitly by handler. + * uint32_t duration; + * uint8_t own_addr_type; + */ } __packed; struct btp_gap_start_advertising_rp { uint32_t current_settings; @@ -148,6 +154,7 @@ struct btp_gap_start_discovery_cmd { struct btp_gap_connect_cmd { uint8_t address_type; uint8_t address[6]; + uint8_t own_addr_type; } __packed; #define BTP_GAP_DISCONNECT 0x0f diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h index 06ea5833e1..e13400ae96 100644 --- a/apps/bttester/src/btp/bttester.h +++ b/apps/bttester/src/btp/bttester.h @@ -36,6 +36,7 @@ #else #include "glue.h" #endif +#include static inline void tester_set_bit(uint8_t *addr, unsigned int bit) @@ -57,10 +58,21 @@ tester_test_bit(const uint8_t *addr, unsigned int bit) void tester_init(void); void -tester_rsp(uint8_t service, uint8_t opcode, uint8_t index, uint8_t status); +tester_rsp(uint8_t service, uint8_t opcode, uint8_t status); void -tester_send(uint8_t service, uint8_t opcode, uint8_t index, uint8_t *data, - size_t len); +tester_send(uint8_t service, uint8_t opcode, uint8_t *data, size_t len); + +struct btp_handler { + uint8_t opcode; + uint8_t index; + ssize_t expect_len; + uint8_t (*func)(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len); +}; + +void tester_register_command_handlers(uint8_t service, + const struct btp_handler *handlers, + size_t num); void tester_send_buf(uint8_t service, uint8_t opcode, uint8_t index, struct os_mbuf *buf); @@ -70,20 +82,16 @@ tester_init_gap(void); uint8_t tester_unregister_gap(void); void -tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len); -void -tester_handle_core(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len); +tester_init_core(void); uint8_t tester_init_gatt(void); uint8_t tester_unregister_gatt(void); void -tester_handle_gatt(uint8_t opcode, uint8_t index, uint8_t *data, +tester_handle_gatt(uint8_t opcode, uint8_t *data, uint16_t len); void -tester_handle_gattc(uint8_t opcode, uint8_t index, uint8_t *data, +tester_handle_gattc(uint8_t opcode, uint8_t *data, uint16_t len); int tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, @@ -103,7 +111,7 @@ tester_init_l2cap(void); uint8_t tester_unregister_l2cap(void); void -tester_handle_l2cap(uint8_t opcode, uint8_t index, uint8_t *data, +tester_handle_l2cap(uint8_t opcode, uint8_t *data, uint16_t len); #endif @@ -113,7 +121,7 @@ tester_init_mesh(void); uint8_t tester_unregister_mesh(void); void -tester_handle_mesh(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len); +tester_handle_mesh(uint8_t opcode, uint8_t *data, uint16_t len); #endif /* MYNEWT_VAL(BLE_MESH) */ void diff --git a/apps/bttester/src/btp_core.c b/apps/bttester/src/btp_core.c index afcac7c52b..4aee11d347 100644 --- a/apps/bttester/src/btp_core.c +++ b/apps/bttester/src/btp_core.c @@ -26,71 +26,80 @@ */ #include "btp/btp.h" +#include "atomic.h" -static void -supported_commands(uint8_t *data, uint16_t len) +static ATOMIC_DEFINE(registered_services, BTP_SERVICE_ID_MAX); + +static uint8_t +supported_commands(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - uint8_t buf[1]; - struct core_read_supported_commands_rp *rp = (void *) buf; + struct btp_core_read_supported_commands_rp *rp = rsp; - memset(buf, 0, sizeof(buf)); + tester_set_bit(rp->data, BTP_CORE_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_CORE_READ_SUPPORTED_SERVICES); + tester_set_bit(rp->data, BTP_CORE_REGISTER_SERVICE); + tester_set_bit(rp->data, BTP_CORE_UNREGISTER_SERVICE); - tester_set_bit(buf, BTP_CORE_READ_SUPPORTED_COMMANDS); - tester_set_bit(buf, BTP_CORE_READ_SUPPORTED_SERVICES); - tester_set_bit(buf, BTP_CORE_REGISTER_SERVICE); - tester_set_bit(buf, BTP_CORE_UNREGISTER_SERVICE); + *rsp_len = sizeof(*rp) + 1; - tester_send(BTP_SERVICE_ID_CORE, BTP_CORE_READ_SUPPORTED_COMMANDS, - BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); + return BTP_STATUS_SUCCESS; } -static void -supported_services(uint8_t *data, uint16_t len) +static uint8_t +supported_services(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - uint8_t buf[1]; - struct core_read_supported_services_rp *rp = (void *) buf; - - memset(buf, 0, sizeof(buf)); + struct btp_core_read_supported_services_rp *rp = rsp; - tester_set_bit(buf, BTP_SERVICE_ID_CORE); - tester_set_bit(buf, BTP_SERVICE_ID_GAP); - tester_set_bit(buf, BTP_SERVICE_ID_GATT); + /* octet 0 */ + tester_set_bit(rp->data, BTP_SERVICE_ID_CORE); + tester_set_bit(rp->data, BTP_SERVICE_ID_GAP); + tester_set_bit(rp->data, BTP_SERVICE_ID_GATT); #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) - tester_set_bit(buf, BTP_SERVICE_ID_L2CAP); + tester_set_bit(rp->data, BTP_SERVICE_ID_L2CAP); #endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */ #if MYNEWT_VAL(BLE_MESH) - tester_set_bit(buf, BTP_SERVICE_ID_MESH); + tester_set_bit(rp->data, BTP_SERVICE_ID_MESH); #endif /* MYNEWT_VAL(BLE_MESH) */ - tester_set_bit(buf, BTP_SERVICE_ID_GATTC); + tester_set_bit(rp->data, BTP_SERVICE_ID_GATTC); + + *rsp_len = sizeof(*rp) + 2; - tester_send(BTP_SERVICE_ID_CORE, BTP_CORE_READ_SUPPORTED_SERVICES, - BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); + return BTP_STATUS_SUCCESS; } -static void -register_service(uint8_t *data, uint16_t len) +static uint8_t +register_service(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - struct core_register_service_cmd *cmd = (void *) data; + const struct btp_core_register_service_cmd *cp = cmd; uint8_t status; - switch (cmd->id) { + /* invalid service */ + if ((cp->id == BTP_SERVICE_ID_CORE) || (cp->id > BTP_SERVICE_ID_MAX)) { + return BTP_STATUS_FAILED; + } + + /* already registered */ + if (atomic_test_bit(registered_services, cp->id)) { + return BTP_STATUS_FAILED; + } + + switch (cp->id) { case BTP_SERVICE_ID_GAP: status = tester_init_gap(); - /* Rsp with success status will be handled by bt enable cb */ - if (status == BTP_STATUS_FAILED) { - goto rsp; - } - return; + break; case BTP_SERVICE_ID_GATT: status = tester_init_gatt(); break; #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) - case BTP_SERVICE_ID_L2CAP: + case BTP_SERVICE_ID_L2CAP: status = tester_init_l2cap(); break; #endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */ #if MYNEWT_VAL(BLE_MESH) - case BTP_SERVICE_ID_MESH: + case BTP_SERVICE_ID_MESH: status = tester_init_mesh(); break; #endif /* MYNEWT_VAL(BLE_MESH) */ @@ -99,18 +108,31 @@ register_service(uint8_t *data, uint16_t len) break; } -rsp: - tester_rsp(BTP_SERVICE_ID_CORE, BTP_CORE_REGISTER_SERVICE, BTP_INDEX_NONE, - status); + if (status == BTP_STATUS_SUCCESS) { + atomic_set_bit(registered_services, cp->id); + } + + return status; } -static void -unregister_service(uint8_t *data, uint16_t len) +static uint8_t +unregister_service(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - struct core_unregister_service_cmd *cmd = (void *) data; + const struct btp_core_unregister_service_cmd *cp = cmd; uint8_t status; - switch (cmd->id) { + /* invalid service ID */ + if ((cp->id == BTP_SERVICE_ID_CORE) || (cp->id > BTP_SERVICE_ID_MAX)) { + return BTP_STATUS_FAILED; + } + + /* not registered */ + if (!atomic_test_bit(registered_services, cp->id)) { + return BTP_STATUS_FAILED; + } + + switch (cp->id) { case BTP_SERVICE_ID_GAP: status = tester_unregister_gap(); break; @@ -118,12 +140,12 @@ unregister_service(uint8_t *data, uint16_t len) status = tester_unregister_gatt(); break; #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) - case BTP_SERVICE_ID_L2CAP: + case BTP_SERVICE_ID_L2CAP: status = tester_unregister_l2cap(); break; #endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */ #if MYNEWT_VAL(BLE_MESH) - case BTP_SERVICE_ID_MESH: + case BTP_SERVICE_ID_MESH: status = tester_unregister_mesh(); break; #endif /* MYNEWT_VAL(BLE_MESH) */ @@ -132,36 +154,44 @@ unregister_service(uint8_t *data, uint16_t len) break; } - tester_rsp(BTP_SERVICE_ID_CORE, BTP_CORE_UNREGISTER_SERVICE, BTP_INDEX_NONE, - status); + if (status == BTP_STATUS_SUCCESS) { + atomic_clear_bit(registered_services, cp->id); + } + + return status; } +static const struct btp_handler handlers[] = { + { + .opcode = BTP_CORE_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = supported_commands, + }, + { + .opcode = BTP_CORE_READ_SUPPORTED_SERVICES, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = supported_services, + }, + { + .opcode = BTP_CORE_REGISTER_SERVICE, + .index = BTP_INDEX_NONE, + .expect_len = sizeof(struct btp_core_register_service_cmd), + .func = register_service, + }, + { + .opcode = BTP_CORE_UNREGISTER_SERVICE, + .index = BTP_INDEX_NONE, + .expect_len = sizeof(struct btp_core_unregister_service_cmd), + .func = unregister_service, + }, +}; + void -tester_handle_core(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len) +tester_init_core(void) { - if (index != BTP_INDEX_NONE) { - tester_rsp(BTP_SERVICE_ID_CORE, opcode, index, - BTP_STATUS_FAILED); - return; - } - - switch (opcode) { - case BTP_CORE_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - return; - case BTP_CORE_READ_SUPPORTED_SERVICES: - supported_services(data, len); - return; - case BTP_CORE_REGISTER_SERVICE: - register_service(data, len); - return; - case BTP_CORE_UNREGISTER_SERVICE: - unregister_service(data, len); - return; - default: - tester_rsp(BTP_SERVICE_ID_CORE, opcode, BTP_INDEX_NONE, - BTP_STATUS_UNKNOWN_CMD); - return; - } + tester_register_command_handlers(BTP_SERVICE_ID_CORE, handlers, + ARRAY_SIZE(handlers)); + atomic_set_bit(registered_services, BTP_SERVICE_ID_CORE); } diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 24f7f82dcc..66b88a6802 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -85,9 +85,6 @@ static const struct ble_gap_conn_params dflt_conn_params = { .max_ce_len = 0x0300, }; -static void -conn_param_update(struct os_event *ev); - static int gap_conn_find_by_addr(const ble_addr_t *dev_addr, struct ble_gap_conn_desc *out_desc) @@ -121,66 +118,70 @@ gap_conn_find_by_addr(const ble_addr_t *dev_addr, static int gap_event_cb(struct ble_gap_event *event, void *arg); -static void -supported_commands(uint8_t *data, uint16_t len) +static uint8_t +supported_commands(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - uint8_t cmds[3]; - struct btp_gap_read_supported_commands_rp *rp = (void *) &cmds; + struct btp_gap_read_supported_commands_rp *rp = rsp; + + /* octet 0 */ + tester_set_bit(rp->data, BTP_GAP_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_GAP_READ_CONTROLLER_INDEX_LIST); + tester_set_bit(rp->data, BTP_GAP_READ_CONTROLLER_INFO); + tester_set_bit(rp->data, BTP_GAP_SET_CONNECTABLE); + + /* octet 1 */ + tester_set_bit(rp->data, BTP_GAP_SET_DISCOVERABLE); + tester_set_bit(rp->data, BTP_GAP_SET_BONDABLE); + tester_set_bit(rp->data, BTP_GAP_START_ADVERTISING); + tester_set_bit(rp->data, BTP_GAP_STOP_ADVERTISING); + tester_set_bit(rp->data, BTP_GAP_START_DISCOVERY); + tester_set_bit(rp->data, BTP_GAP_STOP_DISCOVERY); + tester_set_bit(rp->data, BTP_GAP_CONNECT); + tester_set_bit(rp->data, BTP_GAP_DISCONNECT); + + /* octet 2 */ + tester_set_bit(rp->data, BTP_GAP_SET_IO_CAP); + tester_set_bit(rp->data, BTP_GAP_PAIR); + tester_set_bit(rp->data, BTP_GAP_UNPAIR); + tester_set_bit(rp->data, BTP_GAP_PASSKEY_ENTRY); + tester_set_bit(rp->data, BTP_GAP_PASSKEY_CONFIRM); + tester_set_bit(rp->data, BTP_GAP_START_DIRECT_ADV); + tester_set_bit(rp->data, BTP_GAP_CONN_PARAM_UPDATE); + + /* octet 3 */ + tester_set_bit(rp->data, BTP_GAP_OOB_LEGACY_SET_DATA); + tester_set_bit(rp->data, BTP_GAP_OOB_SC_GET_LOCAL_DATA); + tester_set_bit(rp->data, BTP_GAP_OOB_SC_SET_REMOTE_DATA); + tester_set_bit(rp->data, BTP_GAP_SET_MITM); + + *rsp_len = sizeof(*rp) + 4; - SYS_LOG_DBG(""); - - memset(cmds, 0, sizeof(cmds)); - - tester_set_bit(cmds, BTP_GAP_READ_SUPPORTED_COMMANDS); - tester_set_bit(cmds, BTP_GAP_READ_CONTROLLER_INDEX_LIST); - tester_set_bit(cmds, BTP_GAP_READ_CONTROLLER_INFO); - tester_set_bit(cmds, BTP_GAP_SET_CONNECTABLE); - tester_set_bit(cmds, BTP_GAP_SET_DISCOVERABLE); - tester_set_bit(cmds, BTP_GAP_SET_BONDABLE); - tester_set_bit(cmds, BTP_GAP_START_ADVERTISING); - tester_set_bit(cmds, BTP_GAP_STOP_ADVERTISING); - tester_set_bit(cmds, BTP_GAP_START_DISCOVERY); - tester_set_bit(cmds, BTP_GAP_STOP_DISCOVERY); - tester_set_bit(cmds, BTP_GAP_CONNECT); - tester_set_bit(cmds, BTP_GAP_DISCONNECT); - tester_set_bit(cmds, BTP_GAP_SET_IO_CAP); - tester_set_bit(cmds, BTP_GAP_PAIR); - tester_set_bit(cmds, BTP_GAP_UNPAIR); - tester_set_bit(cmds, BTP_GAP_PASSKEY_ENTRY); - tester_set_bit(cmds, BTP_GAP_PASSKEY_CONFIRM); - tester_set_bit(cmds, BTP_GAP_START_DIRECT_ADV); - tester_set_bit(cmds, BTP_GAP_CONN_PARAM_UPDATE); - tester_set_bit(cmds, BTP_GAP_OOB_LEGACY_SET_DATA); - tester_set_bit(cmds, BTP_GAP_OOB_SC_GET_LOCAL_DATA); - tester_set_bit(cmds, BTP_GAP_OOB_SC_SET_REMOTE_DATA); - tester_set_bit(cmds, BTP_GAP_SET_MITM); - - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_READ_SUPPORTED_COMMANDS, - CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); + return BTP_STATUS_SUCCESS; } -static void -controller_index_list(uint8_t *data, uint16_t len) +static uint8_t +controller_index_list(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - struct btp_gap_read_controller_index_list_rp *rp; - uint8_t buf[sizeof(*rp) + 1]; + struct btp_gap_read_controller_index_list_rp *rp = rsp; SYS_LOG_DBG(""); - rp = (void *) buf; - rp->num = 1; rp->index[0] = CONTROLLER_INDEX; - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_READ_CONTROLLER_INDEX_LIST, - BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf)); + *rsp_len = sizeof(*rp) + 1; + + return BTP_STATUS_SUCCESS; } -static void -controller_info(uint8_t *data, uint16_t len) +static uint8_t +controller_info(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - struct btp_gap_read_controller_info_rp rp; - uint32_t supported_settings = 0; + struct btp_gap_read_controller_info_rp *rp = rsp; + uint32_t supported_settings = 0; ble_addr_t addr; int rc; @@ -189,8 +190,6 @@ controller_info(uint8_t *data, uint16_t len) rc = ble_hs_pvcy_set_our_irk(irk); assert(rc == 0); - memset(&rp, 0, sizeof(rp)); - /* Make sure we have proper identity address set (public preferred) */ rc = ble_hs_util_ensure_addr(1); assert(rc == 0); @@ -209,12 +208,12 @@ controller_info(uint8_t *data, uint16_t len) } current_settings |= BIT(BTP_GAP_SETTINGS_PRIVACY); supported_settings |= BIT(BTP_GAP_SETTINGS_PRIVACY); - memcpy(rp.address, addr.val, sizeof(rp.address)); + memcpy(rp->address, addr.val, sizeof(rp->address)); } else { - rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, rp.address, NULL); + rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, rp->address, NULL); if (rc) { own_addr_type = BLE_OWN_ADDR_RANDOM; - memcpy(rp.address, addr.val, sizeof(rp.address)); + memcpy(rp->address, addr.val, sizeof(rp->address)); supported_settings |= BIT(BTP_GAP_SETTINGS_STATIC_ADDRESS); current_settings |= BIT(BTP_GAP_SETTINGS_STATIC_ADDRESS); } else { @@ -236,13 +235,14 @@ controller_info(uint8_t *data, uint16_t len) current_settings |= BIT(BTP_GAP_SETTINGS_SC); } - rp.supported_settings = sys_cpu_to_le32(supported_settings); - rp.current_settings = sys_cpu_to_le32(current_settings); + rp->supported_settings = sys_cpu_to_le32(supported_settings); + rp->current_settings = sys_cpu_to_le32(current_settings); + + memcpy(rp->name, CONTROLLER_NAME, sizeof(CONTROLLER_NAME)); - memcpy(rp.name, CONTROLLER_NAME, sizeof(CONTROLLER_NAME)); + *rsp_len = sizeof(*rp); - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_READ_CONTROLLER_INFO, - CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); + return BTP_STATUS_SUCCESS; } static struct ble_gap_adv_params adv_params = { @@ -282,15 +282,16 @@ static void rotate_nrpa_cb(struct os_event *ev) } #endif -static void -set_connectable(uint8_t *data, uint16_t len) +static uint8_t +set_connectable(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gap_set_connectable_cmd *cmd = (void *) data; - struct btp_gap_set_connectable_rp rp; + const struct btp_gap_set_connectable_cmd *cp = cmd; + struct btp_gap_set_connectable_rp *rp = rsp; SYS_LOG_DBG(""); - if (cmd->connectable) { + if (cp->connectable) { current_settings |= BIT(BTP_GAP_SETTINGS_CONNECTABLE); adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; } else { @@ -298,23 +299,25 @@ set_connectable(uint8_t *data, uint16_t len) adv_params.conn_mode = BLE_GAP_CONN_MODE_NON; } - rp.current_settings = sys_cpu_to_le32(current_settings); + rp->current_settings = sys_cpu_to_le32(current_settings); + + *rsp_len = sizeof(*rp); - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_SET_CONNECTABLE, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); + return BTP_STATUS_SUCCESS; } static uint8_t ad_flags = BLE_HS_ADV_F_BREDR_UNSUP; -static void -set_discoverable(uint8_t *data, uint16_t len) +static uint8_t +set_discoverable(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gap_set_discoverable_cmd *cmd = (void *) data; - struct btp_gap_set_discoverable_rp rp; + const struct btp_gap_set_discoverable_cmd *cp = cmd; + struct btp_gap_set_discoverable_rp *rp = rsp; SYS_LOG_DBG(""); - switch (cmd->discoverable) { + switch (cp->discoverable) { case BTP_GAP_NON_DISCOVERABLE: ad_flags &= ~(BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_DISC_LTD); adv_params.disc_mode = BLE_GAP_DISC_MODE_NON; @@ -333,36 +336,35 @@ set_discoverable(uint8_t *data, uint16_t len) current_settings |= BIT(BTP_GAP_SETTINGS_DISCOVERABLE); break; default: - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_SET_DISCOVERABLE, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - return; + return BTP_STATUS_FAILED; } - rp.current_settings = sys_cpu_to_le32(current_settings); + rp->current_settings = sys_cpu_to_le32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_SET_DISCOVERABLE, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); + *rsp_len = sizeof(*rp); + + return BTP_STATUS_SUCCESS; } -static void -set_bondable(const uint8_t *data, uint16_t len) +static uint8_t +set_bondable(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gap_set_bondable_cmd *cmd = (void *) data; - struct btp_gap_set_bondable_rp rp; + const struct btp_gap_set_bondable_cmd *cp = cmd; + struct btp_gap_set_bondable_rp *rp = rsp; - SYS_LOG_DBG(""); + SYS_LOG_DBG("bondable: %d", cp->bondable); - ble_hs_cfg.sm_bonding = cmd->bondable; + ble_hs_cfg.sm_bonding = cp->bondable; if (ble_hs_cfg.sm_bonding) { current_settings |= BIT(BTP_GAP_SETTINGS_BONDABLE); } else { current_settings &= ~BIT(BTP_GAP_SETTINGS_BONDABLE); } - rp.current_settings = sys_cpu_to_le32(current_settings); - - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_SET_BONDABLE, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); + rp->current_settings = sys_cpu_to_le32(current_settings); + *rsp_len = sizeof(*rp); + return BTP_STATUS_SUCCESS; } static struct bt_data ad[10] = { @@ -371,70 +373,91 @@ static struct bt_data ad[10] = { static struct bt_data sd[10]; static int -set_ad(const struct bt_data *ad, size_t ad_len, +set_ad(const struct bt_data *ad_data, size_t ad_len, uint8_t *buf, uint8_t *buf_len) { int i; for (i = 0; i < ad_len; i++) { - buf[(*buf_len)++] = ad[i].data_len + 1; - buf[(*buf_len)++] = ad[i].type; + buf[(*buf_len)++] = ad_data[i].data_len + 1; + buf[(*buf_len)++] = ad_data[i].type; - memcpy(&buf[*buf_len], ad[i].data, - ad[i].data_len); - *buf_len += ad[i].data_len; + memcpy(&buf[*buf_len], ad_data[i].data, + ad_data[i].data_len); + *buf_len += ad_data[i].data_len; } return 0; } -static void -start_advertising(const uint8_t *data, uint16_t len) +static uint8_t +start_advertising(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gap_start_advertising_cmd *cmd = (void *) data; - struct btp_gap_start_advertising_rp rp; - int32_t duration_ms = BLE_HS_FOREVER; + const struct btp_gap_start_advertising_cmd *cp = cmd; + struct btp_gap_start_advertising_rp *rp = rsp; + int32_t duration_ms = BLE_HS_FOREVER; uint8_t buf[BLE_HS_ADV_MAX_SZ]; uint8_t buf_len = 0; uint8_t adv_len, sd_len; + uint8_t addr_type; + uint32_t duration; + int err; int i; SYS_LOG_DBG(""); - for (i = 0, adv_len = 1; i < cmd->adv_data_len; adv_len++) { + /* This command is very unfortunate since after variable data there is + * additional 5 bytes (4 bytes for duration, 1 byte for own address + * type. + */ + if ((cmd_len < sizeof(*cp)) || + (cmd_len != sizeof(*cp) + cp->adv_data_len + cp->scan_rsp_len + + sizeof(duration) + sizeof(own_addr_type))) { + return BTP_STATUS_FAILED; + } + + /* currently ignored */ + duration = get_le32(cp->adv_data + cp->adv_data_len + cp->scan_rsp_len); + (void)duration; + addr_type = cp->adv_data[cp->adv_data_len + + cp->scan_rsp_len + + sizeof(duration)]; + + for (i = 0, adv_len = 1U; i < cp->adv_data_len; adv_len++) { if (adv_len >= ARRAY_SIZE(ad)) { SYS_LOG_ERR("ad[] Out of memory"); - goto fail; + return BTP_STATUS_FAILED; } - ad[adv_len].type = cmd->adv_data[i++]; - ad[adv_len].data_len = cmd->adv_data[i++]; - ad[adv_len].data = &cmd->adv_data[i]; + ad[adv_len].type = cp->scan_rsp[i++]; + ad[adv_len].data_len = cp->scan_rsp[i++]; + ad[adv_len].data = &cp->scan_rsp[i]; i += ad[adv_len].data_len; } - for (i = 0, sd_len = 0; i < cmd->scan_rsp_len; sd_len++) { + for (sd_len = 0U; i < cp->scan_rsp_len; sd_len++) { if (sd_len >= ARRAY_SIZE(sd)) { SYS_LOG_ERR("sd[] Out of memory"); - goto fail; + return BTP_STATUS_FAILED; } - sd[sd_len].type = cmd->scan_rsp[i++]; - sd[sd_len].data_len = cmd->scan_rsp[i++]; - sd[sd_len].data = &cmd->scan_rsp[i]; + sd[sd_len].type = cp->scan_rsp[i++]; + sd[sd_len].data_len = cp->scan_rsp[i++]; + sd[sd_len].data = &cp->scan_rsp[i]; i += sd[sd_len].data_len; } err = set_ad(ad, adv_len, buf, &buf_len); if (err) { - goto fail; + return BTP_STATUS_FAILED; } err = ble_gap_adv_set_data(buf, buf_len); if (err != 0) { - goto fail; + return BTP_STATUS_FAILED; } if (sd_len) { @@ -443,13 +466,13 @@ start_advertising(const uint8_t *data, uint16_t len) err = set_ad(sd, sd_len, buf, &buf_len); if (err) { SYS_LOG_ERR("Advertising failed: err %d", err); - goto fail; + return BTP_STATUS_FAILED; } err = ble_gap_adv_rsp_set_data(buf, buf_len); if (err != 0) { SYS_LOG_ERR("Advertising failed: err %d", err); - goto fail; + return BTP_STATUS_FAILED; } } @@ -457,6 +480,30 @@ start_advertising(const uint8_t *data, uint16_t len) duration_ms = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); } + /* In NimBLE, own_addr_type is configured in `controller_info` function. + * Let's just verify restrictions for Privacy options. + */ + switch (addr_type) { + case 0x00: + break; +#if defined(CONFIG_BT_PRIVACY) + case 0x01: + /* RPA usage is is controlled via privacy settings */ + if (!atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_PRIVACY)) { + return BTP_STATUS_FAILED; + } + break; + case 0x02: + /* NRPA is used only for non-connectable advertising */ + if (atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_CONNECTABLE)) { + return BTP_STATUS_FAILED; + } + break; +#endif + default: + return BTP_STATUS_FAILED; + } + #if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) if (MYNEWT_VAL(BTTESTER_NRPA_TIMEOUT) < duration_ms / 1000) { advertising_start = os_get_uptime_usec(); @@ -468,38 +515,37 @@ start_advertising(const uint8_t *data, uint16_t len) &adv_params, gap_event_cb, NULL); if (err) { SYS_LOG_ERR("Advertising failed: err %d", err); - goto fail; + return BTP_STATUS_FAILED; } current_settings |= BIT(BTP_GAP_SETTINGS_ADVERTISING); - rp.current_settings = sys_cpu_to_le32(current_settings); + rp->current_settings = sys_cpu_to_le32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_START_ADVERTISING, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); - return; -fail: - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_START_ADVERTISING, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + *rsp_len = sizeof(*rp); + + return BTP_STATUS_SUCCESS; } -static void -stop_advertising(const uint8_t *data, uint16_t len) +static uint8_t +stop_advertising(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - struct btp_gap_stop_advertising_rp rp; + struct btp_gap_stop_advertising_rp *rp = rsp; + int err; SYS_LOG_DBG(""); - if (ble_gap_adv_stop() != 0) { - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_STOP_ADVERTISING, - CONTROLLER_INDEX, BTP_STATUS_FAILED); - return; + err = ble_gap_adv_stop(); + if (err != 0) { + return BTP_STATUS_FAILED; } current_settings &= ~BIT(BTP_GAP_SETTINGS_ADVERTISING); - rp.current_settings = sys_cpu_to_le32(current_settings); + rp->current_settings = sys_cpu_to_le32(current_settings); + + *rsp_len = sizeof(*rp); - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_STOP_ADVERTISING, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); + return BTP_STATUS_SUCCESS; } static uint8_t @@ -557,7 +603,7 @@ device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, const uint8_t *data, uint8_t len) { struct btp_gap_device_found_ev *ev; - ble_addr_t a; + ble_addr_t a; /* if General/Limited Discovery - parse Advertising data to get flags */ if (!(discovery_flags & BTP_GAP_DISCOVERY_FLAG_LE_OBSERVE) && @@ -614,8 +660,7 @@ device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, */ if (adv_buf->om_len) { tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_FOUND, - CONTROLLER_INDEX, adv_buf->om_data, - adv_buf->om_len); + adv_buf->om_data, adv_buf->om_len); } store_adv(addr, rssi, data, len); @@ -629,7 +674,7 @@ device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, } done: tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_FOUND, - CONTROLLER_INDEX, adv_buf->om_data, adv_buf->om_len); + adv_buf->om_data, adv_buf->om_len); } static int @@ -644,53 +689,46 @@ discovery_cb(struct ble_gap_event *event, void *arg) return 0; } -static void -start_discovery(const uint8_t *data, uint16_t len) +static uint8_t +start_discovery(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gap_start_discovery_cmd *cmd = (void *) data; - struct ble_gap_disc_params params = {0}; - uint8_t status; + const struct btp_gap_start_discovery_cmd *cp = cmd; + struct ble_gap_disc_params params = {0}; SYS_LOG_DBG(""); /* only LE scan is supported */ - if (cmd->flags & BTP_GAP_DISCOVERY_FLAG_BREDR) { - status = BTP_STATUS_FAILED; - goto reply; + if (cp->flags & BTP_GAP_DISCOVERY_FLAG_BREDR) { + return BTP_STATUS_FAILED; } - params.passive = (cmd->flags & BTP_GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN) == 0; - params.limited = (cmd->flags & BTP_GAP_DISCOVERY_FLAG_LIMITED) > 0; + params.passive = (cp->flags & BTP_GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN) == 0; + params.limited = (cp->flags & BTP_GAP_DISCOVERY_FLAG_LIMITED) > 0; params.filter_duplicates = 1; if (ble_gap_disc(own_addr_type, BLE_HS_FOREVER, ¶ms, discovery_cb, NULL) != 0) { - status = BTP_STATUS_FAILED; - goto reply; + return BTP_STATUS_FAILED; } net_buf_simple_init(adv_buf, 0); - discovery_flags = cmd->flags; + discovery_flags = cp->flags; - status = BTP_STATUS_SUCCESS; -reply: - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_START_DISCOVERY, CONTROLLER_INDEX, - status); + return BTP_STATUS_SUCCESS; } -static void -stop_discovery(const uint8_t *data, uint16_t len) +static uint8_t +stop_discovery(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - uint8_t status = BTP_STATUS_SUCCESS; - SYS_LOG_DBG(""); if (ble_gap_disc_cancel() != 0) { - status = BTP_STATUS_FAILED; + return BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_STOP_DISCOVERY, CONTROLLER_INDEX, - status); + return BTP_STATUS_SUCCESS; } /* Bluetooth Core Spec v5.1 | Section 10.7.1 @@ -729,12 +767,12 @@ device_connected_ev_send(struct os_event *ev) rc = gap_conn_find_by_addr((ble_addr_t *) &connected_ev, &desc); if (rc) { tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_CONNECTED, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + BTP_STATUS_FAILED); return; } tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_CONNECTED, - CONTROLLER_INDEX, (uint8_t *) &connected_ev, + (uint8_t *) &connected_ev, sizeof(connected_ev)); periph_privacy(desc); @@ -775,7 +813,7 @@ le_connected(uint16_t conn_handle, int status) CONNECTED_EV_DELAY_MS(desc.conn_itvl))); #else tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_CONNECTED, - CONTROLLER_INDEX, (uint8_t *) &connected_ev, + (uint8_t *) &connected_ev, sizeof(connected_ev)); #endif } @@ -784,7 +822,7 @@ static void le_disconnected(struct ble_gap_conn_desc *conn, int reason) { struct btp_gap_device_disconnected_ev ev; - ble_addr_t *addr = &conn->peer_ota_addr; + ble_addr_t *addr = &conn->peer_ota_addr; SYS_LOG_DBG(""); @@ -819,7 +857,7 @@ le_disconnected(struct ble_gap_conn_desc *conn, int reason) ev.address_type = addr->type; tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_DISCONNECTED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); } static void @@ -846,9 +884,9 @@ auth_passkey_oob(uint16_t conn_handle) static void auth_passkey_display(uint16_t conn_handle, unsigned int passkey) { - struct ble_gap_conn_desc desc; + struct ble_gap_conn_desc desc; struct btp_gap_passkey_display_ev ev; - ble_addr_t *addr; + ble_addr_t *addr; struct ble_sm_io pk; int rc; @@ -875,15 +913,15 @@ auth_passkey_display(uint16_t conn_handle, unsigned int passkey) ev.passkey = sys_cpu_to_le32(pk.passkey); tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_DISPLAY, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); } static void auth_passkey_entry(uint16_t conn_handle) { - struct ble_gap_conn_desc desc; + struct ble_gap_conn_desc desc; struct btp_gap_passkey_entry_req_ev ev; - ble_addr_t *addr; + ble_addr_t *addr; int rc; SYS_LOG_DBG(""); @@ -899,15 +937,15 @@ auth_passkey_entry(uint16_t conn_handle) ev.address_type = addr->type; tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_ENTRY_REQ, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); } static void auth_passkey_numcmp(uint16_t conn_handle, unsigned int passkey) { - struct ble_gap_conn_desc desc; + struct ble_gap_conn_desc desc; struct btp_gap_passkey_confirm_req_ev ev; - ble_addr_t *addr; + ble_addr_t *addr; int rc; SYS_LOG_DBG(""); @@ -924,7 +962,7 @@ auth_passkey_numcmp(uint16_t conn_handle, unsigned int passkey) ev.passkey = sys_cpu_to_le32(passkey); tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_CONFIRM_REQ, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); } static void @@ -984,9 +1022,9 @@ le_passkey_action(uint16_t conn_handle, static void le_identity_resolved(uint16_t conn_handle) { - struct ble_gap_conn_desc desc; + struct ble_gap_conn_desc desc; struct btp_gap_identity_resolved_ev ev; - int rc; + int rc; SYS_LOG_DBG(""); @@ -1006,15 +1044,15 @@ le_identity_resolved(uint16_t conn_handle) sizeof(ev.identity_address)); tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_IDENTITY_RESOLVED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); } static void le_pairing_failed(uint16_t conn_handle, int reason) { - struct ble_gap_conn_desc desc; + struct ble_gap_conn_desc desc; struct btp_gap_sec_pairing_failed_ev ev; - int rc; + int rc; SYS_LOG_DBG(""); @@ -1032,7 +1070,7 @@ le_pairing_failed(uint16_t conn_handle, int reason) ev.reason = reason; tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_SEC_PAIRING_FAILED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); } static void @@ -1050,7 +1088,7 @@ le_conn_param_update(struct ble_gap_conn_desc *desc) ev.supervision_timeout = desc->supervision_timeout; tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_CONN_PARAM_UPDATE, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); } static void @@ -1079,14 +1117,14 @@ le_encryption_changed(struct ble_gap_conn_desc *desc) } tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_SEC_LEVEL_CHANGED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); } static void bond_lost(uint16_t conn_handle) { struct btp_gap_bond_lost_ev ev; - struct ble_gap_conn_desc desc; + struct ble_gap_conn_desc desc; int rc; rc = ble_gap_conn_find(conn_handle, &desc); @@ -1096,7 +1134,6 @@ bond_lost(uint16_t conn_handle) ev.address_type = desc.peer_id_addr.type; tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_BOND_LOST, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); } @@ -1171,7 +1208,7 @@ adv_complete(void) current_settings &= ~BIT(BTP_GAP_SETTINGS_ADVERTISING); ev.current_settings = sys_cpu_to_le32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_NEW_SETTINGS, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_NEW_SETTINGS, (uint8_t *) &ev, sizeof(ev)); } @@ -1355,11 +1392,13 @@ gap_event_cb(struct ble_gap_event *event, void *arg) return 0; } -static void -connect(const uint8_t *data, uint16_t len) +static uint8_t +connect(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - uint8_t status = BTP_STATUS_SUCCESS; - ble_addr_t *addr = (ble_addr_t *) data; + const struct btp_gap_connect_cmd *cp = cmd; + + ble_addr_t *addr = (ble_addr_t *)&cp->address_type; SYS_LOG_DBG(""); @@ -1369,47 +1408,43 @@ connect(const uint8_t *data, uint16_t len) if (ble_gap_connect(own_addr_type, addr, 0, &dflt_conn_params, gap_event_cb, NULL)) { - status = BTP_STATUS_FAILED; + return BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_CONNECT, CONTROLLER_INDEX, status); + return BTP_STATUS_SUCCESS; } -static void -disconnect(const uint8_t *data, uint16_t len) +static uint8_t +disconnect(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { + const struct btp_gap_disconnect_cmd *cp = cmd; struct ble_gap_conn_desc desc; - uint8_t status; int rc; SYS_LOG_DBG(""); - rc = gap_conn_find_by_addr((ble_addr_t *) data, &desc); + rc = gap_conn_find_by_addr((ble_addr_t *)&cp->address_type, &desc); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } if (ble_gap_terminate(desc.conn_handle, BLE_ERR_REM_USER_CONN_TERM)) { - status = BTP_STATUS_FAILED; - } else { - status = BTP_STATUS_SUCCESS; + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_DISCONNECT, CONTROLLER_INDEX, - status); + return BTP_STATUS_SUCCESS; } -static void -set_io_cap(const uint8_t *data, uint16_t len) +static uint8_t +set_io_cap(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gap_set_io_cap_cmd *cmd = (void *) data; - uint8_t status; + const struct btp_gap_set_io_cap_cmd *cp = cmd; SYS_LOG_DBG(""); - switch (cmd->io_cap) { + switch (cp->io_cap) { case BTP_GAP_IO_CAP_DISPLAY_ONLY: ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_DISP_ONLY; ble_hs_cfg.sm_mitm = 1; @@ -1431,155 +1466,132 @@ set_io_cap(const uint8_t *data, uint16_t len) ble_hs_cfg.sm_mitm = 1; break; default: - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } - status = BTP_STATUS_SUCCESS; - -rsp: - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_SET_IO_CAP, CONTROLLER_INDEX, - status); + return BTP_STATUS_SUCCESS; } -static void -pair(const uint8_t *data, uint16_t len) +static uint8_t +pair(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { + const struct btp_gap_pair_cmd *cp = cmd; struct ble_gap_conn_desc desc; - uint8_t status; int rc; SYS_LOG_DBG(""); - rc = gap_conn_find_by_addr((ble_addr_t *) data, &desc); + rc = gap_conn_find_by_addr((ble_addr_t *)&cp->address_type, &desc); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } rc = ble_gap_security_initiate(desc.conn_handle); if (rc != 0 && rc != BLE_HS_EALREADY) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } - status = BTP_STATUS_SUCCESS; - -rsp: - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_PAIR, CONTROLLER_INDEX, status); + return BTP_STATUS_SUCCESS; } -static void -unpair(const uint8_t *data, uint16_t len) +static uint8_t +unpair(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - uint8_t status; + const struct btp_gap_unpair_cmd *cp = cmd; int err; SYS_LOG_DBG(""); - err = ble_gap_unpair((ble_addr_t *) data); - status = (uint8_t) (err != 0 ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_UNPAIR, CONTROLLER_INDEX, status); + err = ble_gap_unpair((ble_addr_t *)&cp->address_type); + return err != 0 ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS; } -static void -passkey_entry(const uint8_t *data, uint16_t len) +static uint8_t +passkey_entry(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gap_passkey_entry_cmd *cmd = (void *) data; - struct ble_gap_conn_desc desc; + const struct btp_gap_passkey_entry_cmd *cp = cmd; + struct ble_gap_conn_desc desc; struct ble_sm_io pk; - uint8_t status; int rc; SYS_LOG_DBG(""); - rc = gap_conn_find_by_addr((ble_addr_t *) data, &desc); + rc = gap_conn_find_by_addr((ble_addr_t *)&cp->address_type, &desc); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } pk.action = BLE_SM_IOACT_INPUT; - pk.passkey = sys_le32_to_cpu(cmd->passkey); + pk.passkey = sys_le32_to_cpu(cp->passkey); rc = ble_sm_inject_io(desc.conn_handle, &pk); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } - status = BTP_STATUS_SUCCESS; - -rsp: - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_PASSKEY_ENTRY, CONTROLLER_INDEX, - status); + return BTP_STATUS_SUCCESS; } -static void -passkey_confirm(const uint8_t *data, uint16_t len) +static uint8_t +passkey_confirm(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gap_passkey_confirm_cmd *cmd = (void *) data; - struct ble_gap_conn_desc desc; + const struct btp_gap_passkey_confirm_cmd *cp = cmd; + struct ble_gap_conn_desc desc; struct ble_sm_io pk; - uint8_t status; int rc; SYS_LOG_DBG(""); - rc = gap_conn_find_by_addr((ble_addr_t *) data, &desc); + rc = gap_conn_find_by_addr((ble_addr_t *)&cp->address_type, &desc); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } pk.action = BLE_SM_IOACT_NUMCMP; - pk.numcmp_accept = cmd->match; + pk.numcmp_accept = cp->match; rc = ble_sm_inject_io(desc.conn_handle, &pk); if (rc) { console_printf("sm inject io failed"); - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } - status = BTP_STATUS_SUCCESS; - -rsp: - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_PASSKEY_CONFIRM, CONTROLLER_INDEX, - status); + return BTP_STATUS_SUCCESS; } -static void -start_direct_adv(const uint8_t *data, uint16_t len) +static uint8_t +start_direct_adv(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gap_start_direct_adv_cmd *cmd = (void *) data; - struct btp_gap_start_advertising_rp rp; - static struct ble_gap_adv_params adv_params = { + const struct btp_gap_start_direct_adv_cmd *cp = cmd; + struct btp_gap_start_advertising_rp *rp = rsp; + static struct ble_gap_adv_params adv_params = { .conn_mode = BLE_GAP_CONN_MODE_DIR, }; int err; SYS_LOG_DBG(""); - adv_params.high_duty_cycle = cmd->high_duty; + adv_params.high_duty_cycle = cp->high_duty; - err = ble_gap_adv_start(own_addr_type, (ble_addr_t *) data, + err = ble_gap_adv_start(own_addr_type, (ble_addr_t *)&cp->address_type, BLE_HS_FOREVER, &adv_params, gap_event_cb, NULL); if (err) { SYS_LOG_ERR("Advertising failed: err %d", err); - goto fail; + return BTP_STATUS_FAILED; } current_settings |= BIT(BTP_GAP_SETTINGS_ADVERTISING); - rp.current_settings = sys_cpu_to_le32(current_settings); + rp->current_settings = sys_cpu_to_le32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_START_DIRECT_ADV, CONTROLLER_INDEX, - (uint8_t *) &rp, sizeof(rp)); - return; -fail: - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_START_DIRECT_ADV, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + *rsp_len = sizeof(*rp); + + return BTP_STATUS_SUCCESS; } static void @@ -1665,72 +1677,74 @@ conn_param_update(struct os_event *ev) SYS_LOG_ERR("Conn param update fail; rc=%d", rc); } -static void -conn_param_update_async(const uint8_t *data, uint16_t len) +static uint8_t +conn_param_update_async(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gap_conn_param_update_cmd *cmd = (void *) data; - update_params = *cmd; + const struct btp_gap_conn_param_update_cmd *cp = cmd; + update_params = *cp; os_callout_reset(&update_params_co, 0); - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_CONN_PARAM_UPDATE, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } -static void -oob_legacy_set_data(const uint8_t *data, uint16_t len) +static uint8_t +set_oob_legacy_data(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gap_oob_legacy_set_data_cmd *cmd = (void *) data; + const struct btp_gap_oob_legacy_set_data_cmd *cp = cmd; ble_hs_cfg.sm_oob_data_flag = 1; - memcpy(oob, cmd->oob_data, sizeof(oob)); + memcpy(oob, cp->oob_data, sizeof(oob)); - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_OOB_LEGACY_SET_DATA, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } -static void -oob_sc_get_local_data(const uint8_t *data, uint16_t len) +static uint8_t +get_oob_sc_local_data(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - struct btp_gap_oob_sc_get_local_data_rp rp; + struct btp_gap_oob_sc_get_local_data_rp *rp = rsp; + + memcpy(rp->r, oob_data_local.r, 16); + memcpy(rp->c, oob_data_local.c, 16); - memcpy(rp.r, oob_data_local.r, 16); - memcpy(rp.c, oob_data_local.c, 16); + *rsp_len = sizeof(*rp); - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_OOB_SC_GET_LOCAL_DATA, - CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp)); + return BTP_STATUS_SUCCESS; } -static void -oob_sc_set_remote_data(const uint8_t *data, uint16_t len) +static uint8_t +set_oob_sc_remote_data(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gap_oob_sc_set_remote_data_cmd *cmd = (void *) data; + const struct btp_gap_oob_sc_set_remote_data_cmd *cp = cmd; ble_hs_cfg.sm_oob_data_flag = 1; - memcpy(oob_data_remote.r, cmd->r, 16); - memcpy(oob_data_remote.c, cmd->c, 16); + memcpy(oob_data_remote.r, cp->r, 16); + memcpy(oob_data_remote.c, cp->c, 16); - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_OOB_SC_SET_REMOTE_DATA, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } -static void -set_mitm(const uint8_t *data, uint16_t len) +static uint8_t +set_mitm(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gap_set_mitm_cmd *cmd = (void *) data; + const struct btp_gap_set_mitm_cmd *cp = cmd; - ble_hs_cfg.sm_mitm = cmd->mitm; + ble_hs_cfg.sm_mitm = cp->mitm; - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_SET_MITM, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } -static void -set_filter_accept_list(const uint8_t *data, uint16_t len) +static uint8_t +set_filter_accept_list(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - uint8_t status = BTP_STATUS_SUCCESS; - struct btp_gap_set_filter_accept_list_cmd *tmp = - (struct btp_gap_set_filter_accept_list_cmd *) data; + const struct btp_gap_set_filter_accept_list_cmd *cp = cmd; + int err; SYS_LOG_DBG(""); @@ -1738,126 +1752,147 @@ set_filter_accept_list(const uint8_t *data, uint16_t len) * Check if the nb of bytes received matches the len of addrs list. * Then set the filter accept list. */ - if (((len - sizeof(tmp->list_len)) / sizeof(ble_addr_t) != - tmp->list_len) || ble_gap_wl_set(tmp->addrs, tmp->list_len)) { - status = BTP_STATUS_FAILED; + if ((cmd_len < sizeof(*cp)) || + (cmd_len != sizeof(*cp) + (cp->list_len * sizeof(cp->addrs[0])))) { + return BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_GAP, BTP_GAP_SET_FILTER_ACCEPT_LIST, - CONTROLLER_INDEX, status); -} - -void -tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data, - uint16_t len) -{ - switch (opcode) { - case BTP_GAP_READ_SUPPORTED_COMMANDS: - case BTP_GAP_READ_CONTROLLER_INDEX_LIST: - if (index != BTP_INDEX_NONE) { - tester_rsp(BTP_SERVICE_ID_GAP, opcode, index, - BTP_STATUS_FAILED); - return; - } - break; - default: - if (index != CONTROLLER_INDEX) { - tester_rsp(BTP_SERVICE_ID_GAP, opcode, index, - BTP_STATUS_FAILED); - return; - } - break; + err = ble_gap_wl_set(cp->addrs, cp->list_len); + if (err != 0) { + return BTP_STATUS_FAILED; } - switch (opcode) { - case BTP_GAP_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - return; - case BTP_GAP_READ_CONTROLLER_INDEX_LIST: - controller_index_list(data, len); - return; - case BTP_GAP_READ_CONTROLLER_INFO: - controller_info(data, len); - return; - case BTP_GAP_SET_CONNECTABLE: - set_connectable(data, len); - return; - case BTP_GAP_SET_DISCOVERABLE: - set_discoverable(data, len); - return; - case BTP_GAP_SET_BONDABLE: - set_bondable(data, len); - return; - case BTP_GAP_START_ADVERTISING: - start_advertising(data, len); - return; - case BTP_GAP_STOP_ADVERTISING: - stop_advertising(data, len); - return; - case BTP_GAP_START_DISCOVERY: - start_discovery(data, len); - return; - case BTP_GAP_STOP_DISCOVERY: - stop_discovery(data, len); - return; - case BTP_GAP_CONNECT: - connect(data, len); - return; - case BTP_GAP_DISCONNECT: - disconnect(data, len); - return; - case BTP_GAP_SET_IO_CAP: - set_io_cap(data, len); - return; - case BTP_GAP_PAIR: - pair(data, len); - return; - case BTP_GAP_UNPAIR: - unpair(data, len); - return; - case BTP_GAP_PASSKEY_ENTRY: - passkey_entry(data, len); - return; - case BTP_GAP_PASSKEY_CONFIRM: - passkey_confirm(data, len); - return; - case BTP_GAP_START_DIRECT_ADV: - start_direct_adv(data, len); - return; - case BTP_GAP_CONN_PARAM_UPDATE: - conn_param_update_async(data, len); - return; - case BTP_GAP_OOB_LEGACY_SET_DATA: - oob_legacy_set_data(data, len); - return; - case BTP_GAP_OOB_SC_GET_LOCAL_DATA: - oob_sc_get_local_data(data, len); - return; - case BTP_GAP_OOB_SC_SET_REMOTE_DATA: - oob_sc_set_remote_data(data, len); - return; - case BTP_GAP_SET_MITM: - set_mitm(data, len); - return; - case BTP_GAP_SET_FILTER_ACCEPT_LIST: - set_filter_accept_list(data, len); - return; - default: - tester_rsp(BTP_SERVICE_ID_GAP, opcode, index, - BTP_STATUS_UNKNOWN_CMD); - return; - } + return BTP_STATUS_SUCCESS; } +static const struct btp_handler handlers[] = { + { + .opcode = BTP_GAP_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = supported_commands, + }, + { + .opcode = BTP_GAP_READ_CONTROLLER_INDEX_LIST, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = controller_index_list, + }, + { + .opcode = BTP_GAP_READ_CONTROLLER_INFO, + .expect_len = 0, + .func = controller_info, + }, + { + .opcode = BTP_GAP_SET_CONNECTABLE, + .expect_len = sizeof(struct btp_gap_set_connectable_cmd), + .func = set_connectable, + }, + { + .opcode = BTP_GAP_SET_DISCOVERABLE, + .expect_len = sizeof(struct btp_gap_set_discoverable_cmd), + .func = set_discoverable, + }, + { + .opcode = BTP_GAP_SET_BONDABLE, + .expect_len = sizeof(struct btp_gap_set_bondable_cmd), + .func = set_bondable, + }, + { + .opcode = BTP_GAP_START_ADVERTISING, + .expect_len = -1, + .func = start_advertising, + }, + { + .opcode = BTP_GAP_START_DIRECT_ADV, + .expect_len = sizeof(struct btp_gap_start_direct_adv_cmd), + .func = start_direct_adv, + }, + { + .opcode = BTP_GAP_STOP_ADVERTISING, + .expect_len = 0, + .func = stop_advertising, + }, + { + .opcode = BTP_GAP_START_DISCOVERY, + .expect_len = sizeof(struct btp_gap_start_discovery_cmd), + .func = start_discovery, + }, + { + .opcode = BTP_GAP_STOP_DISCOVERY, + .expect_len = 0, + .func = stop_discovery, + }, + { + .opcode = BTP_GAP_CONNECT, + .expect_len = sizeof(struct btp_gap_connect_cmd), + .func = connect, + }, + { + .opcode = BTP_GAP_DISCONNECT, + .expect_len = sizeof(struct btp_gap_disconnect_cmd), + .func = disconnect, + }, + { + .opcode = BTP_GAP_SET_IO_CAP, + .expect_len = sizeof(struct btp_gap_set_io_cap_cmd), + .func = set_io_cap, + }, + { + .opcode = BTP_GAP_PAIR, + .expect_len = sizeof(struct btp_gap_pair_cmd), + .func = pair, + }, + { + .opcode = BTP_GAP_UNPAIR, + .expect_len = sizeof(struct btp_gap_unpair_cmd), + .func = unpair, + }, + { + .opcode = BTP_GAP_PASSKEY_ENTRY, + .expect_len = sizeof(struct btp_gap_passkey_entry_cmd), + .func = passkey_entry, + }, + { + .opcode = BTP_GAP_PASSKEY_CONFIRM, + .expect_len = sizeof(struct btp_gap_passkey_confirm_cmd), + .func = passkey_confirm, + }, + { + .opcode = BTP_GAP_CONN_PARAM_UPDATE, + .expect_len = sizeof(struct btp_gap_conn_param_update_cmd), + .func = conn_param_update_async, + }, + { + .opcode = BTP_GAP_OOB_LEGACY_SET_DATA, + .expect_len = sizeof(struct btp_gap_oob_legacy_set_data_cmd), + .func = set_oob_legacy_data, + }, + { + .opcode = BTP_GAP_OOB_SC_GET_LOCAL_DATA, + .expect_len = 0, + .func = get_oob_sc_local_data, + }, + { + .opcode = BTP_GAP_OOB_SC_SET_REMOTE_DATA, + .expect_len = sizeof(struct btp_gap_oob_sc_set_remote_data_cmd), + .func = set_oob_sc_remote_data, + }, + { + .opcode = BTP_GAP_SET_MITM, + .expect_len = sizeof(struct btp_gap_set_mitm_cmd), + .func = set_mitm, + }, + { + .opcode = BTP_GAP_SET_FILTER_ACCEPT_LIST, + .expect_len = -1, + .func = set_filter_accept_list, + }, +}; + static void -tester_init_gap_cb(int err) +tester_init_gap_cb() { - if (err) { - tester_rsp(BTP_SERVICE_ID_CORE, BTP_CORE_REGISTER_SERVICE, - BTP_INDEX_NONE, BTP_STATUS_FAILED); - return; - } - current_settings = 0; current_settings |= BIT(BTP_GAP_SETTINGS_POWERED); current_settings |= BIT(BTP_GAP_SETTINGS_LE); @@ -1867,9 +1902,6 @@ tester_init_gap_cb(int err) os_callout_init(&connected_ev_co, os_eventq_dflt_get(), device_connected_ev_send, NULL); - - tester_rsp(BTP_SERVICE_ID_CORE, BTP_CORE_REGISTER_SERVICE, BTP_INDEX_NONE, - BTP_STATUS_SUCCESS); } uint8_t @@ -1890,7 +1922,11 @@ tester_init_gap(void) #endif adv_buf = NET_BUF_SIMPLE(ADV_BUF_LEN); - tester_init_gap_cb(BTP_STATUS_SUCCESS); + tester_init_gap_cb(); + + tester_register_command_handlers(BTP_SERVICE_ID_GAP, handlers, + ARRAY_SIZE(handlers)); + return BTP_STATUS_SUCCESS; } diff --git a/apps/bttester/src/btp_gatt.c b/apps/bttester/src/btp_gatt.c index d3b826f53b..5d62a677ad 100644 --- a/apps/bttester/src/btp_gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -256,7 +256,7 @@ static void attr_value_changed_ev(uint16_t handle, struct os_mbuf *data) { struct btp_gatt_attr_value_changed_ev *ev; - struct os_mbuf *buf = os_msys_get(0, 0); + struct os_mbuf *buf = os_msys_get(0, 0); SYS_LOG_DBG(""); @@ -583,7 +583,7 @@ start_server(uint8_t *data, uint16_t len) rp.db_attr_off = 0; rp.db_attr_cnt = 0; - tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_START_SERVER, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_START_SERVER, (uint8_t *) &rp, sizeof(rp)); } @@ -672,29 +672,29 @@ read_cb(uint16_t conn_handle, struct ble_gatt_attr *attr, void *arg) { - struct btp_gatt_read_rp *rp = (void *) gatt_buf.buf; - uint8_t btp_opcode = (uint8_t) (int) arg; + struct btp_gatt_read_rp *rp = (void *) gatt_buf.buf; + uint8_t btp_opcode = (uint8_t) (int) arg; SYS_LOG_DBG("status=%d", error->status); if (error->status != 0 && error->status != BLE_HS_EDONE) { rp->att_response = (uint8_t) BLE_HS_ATT_ERR(error->status); - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + tester_send(BTP_SERVICE_ID_GATT, btp_opcode, gatt_buf.buf, gatt_buf + .len); read_destroy(); return 0; } if (!gatt_buf_add(attr->om->om_data, attr->om->om_len)) { tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + BTP_STATUS_FAILED); read_destroy(); return 0; } rp->data_length += attr->om->om_len; tester_send(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + gatt_buf.buf, gatt_buf.len); read_destroy(); return 0; @@ -704,7 +704,7 @@ static void read(uint8_t *data, uint16_t len) { const struct btp_gatt_read_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; int rc; SYS_LOG_DBG(""); @@ -730,8 +730,7 @@ read(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ, BTP_STATUS_FAILED); } static int @@ -740,29 +739,29 @@ read_long_cb(uint16_t conn_handle, struct ble_gatt_attr *attr, void *arg) { - struct btp_gatt_read_rp *rp = (void *) gatt_buf.buf; - uint8_t btp_opcode = (uint8_t) (int) arg; + struct btp_gatt_read_rp *rp = (void *) gatt_buf.buf; + uint8_t btp_opcode = (uint8_t) (int) arg; SYS_LOG_DBG("status=%d", error->status); if (error->status != 0 && error->status != BLE_HS_EDONE) { rp->att_response = (uint8_t) BLE_HS_ATT_ERR(error->status); - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + tester_send(BTP_SERVICE_ID_GATT, btp_opcode, gatt_buf.buf, gatt_buf + .len); read_destroy(); return 0; } if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + tester_send(BTP_SERVICE_ID_GATT, btp_opcode, gatt_buf.buf, gatt_buf + .len); read_destroy(); return 0; } if (gatt_buf_add(attr->om->om_data, attr->om->om_len) == NULL) { tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + BTP_STATUS_FAILED); read_destroy(); return BLE_HS_ENOMEM; } @@ -776,7 +775,7 @@ static void read_long(uint8_t *data, uint16_t len) { const struct btp_gatt_read_long_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; int rc; SYS_LOG_DBG(""); @@ -804,15 +803,14 @@ read_long(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ_LONG, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ_LONG, BTP_STATUS_FAILED); } static void read_multiple(uint8_t *data, uint16_t len) { const struct btp_gatt_read_multiple_cmd *cmd = (void *) data; - uint16_t handles[cmd->handles_count]; + uint16_t handles[cmd->handles_count]; struct ble_gap_conn_desc conn; int rc, i; @@ -844,15 +842,14 @@ read_multiple(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ_MULTIPLE, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ_MULTIPLE, BTP_STATUS_FAILED); } static void write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) { const struct btp_gatt_write_without_rsp_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -871,7 +868,7 @@ write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) } rsp: - tester_rsp(BTP_SERVICE_ID_GATT, op, CONTROLLER_INDEX, status); + tester_rsp(BTP_SERVICE_ID_GATT, op, status); } static int @@ -885,7 +882,7 @@ write_rsp(uint16_t conn_handle, const struct ble_gatt_error *error, SYS_LOG_DBG(""); tester_send(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, &err, sizeof(err)); + &err, sizeof(err)); return 0; } @@ -893,7 +890,7 @@ static void write(uint8_t *data, uint16_t len) { const struct btp_gatt_write_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; int rc; SYS_LOG_DBG(""); @@ -912,15 +909,14 @@ write(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE, BTP_STATUS_FAILED); } static void write_long(uint8_t *data, uint16_t len) { const struct btp_gatt_write_long_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; struct os_mbuf *om = NULL; int rc = 0; @@ -949,8 +945,7 @@ write_long(uint8_t *data, uint16_t len) fail: SYS_LOG_ERR("Failed to send Write Long request, rc=%d", rc); os_mbuf_free_chain(om); - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE_LONG, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE_LONG, BTP_STATUS_FAILED); } static int @@ -965,7 +960,7 @@ reliable_write_rsp(uint16_t conn_handle, SYS_LOG_DBG("Reliable write status %d", err); tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_RELIABLE_WRITE, - CONTROLLER_INDEX, &err, sizeof(err)); + &err, sizeof(err)); return 0; } @@ -973,7 +968,7 @@ static void reliable_write(uint8_t *data, uint16_t len) { const struct btp_gatt_reliable_write_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; struct ble_gatt_attr attr; struct os_mbuf *om = NULL; int rc; @@ -1007,8 +1002,7 @@ reliable_write(uint8_t *data, uint16_t len) fail: os_mbuf_free_chain(om); - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE_LONG, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE_LONG, BTP_STATUS_FAILED); } static struct bt_gatt_subscribe_params { @@ -1021,7 +1015,7 @@ static void read_uuid(uint8_t *data, uint16_t len) { const struct btp_gatt_read_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; ble_uuid_any_t uuid; int rc; @@ -1054,8 +1048,7 @@ read_uuid(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ, BTP_STATUS_FAILED); } static int @@ -1064,8 +1057,8 @@ disc_prim_uuid_cb(uint16_t conn_handle, const struct ble_gatt_svc *gatt_svc, void *arg) { struct btp_gatt_disc_prim_uuid_rp *rp = (void *) gatt_buf.buf; - struct btp_gatt_service *service; - const ble_uuid_any_t *uuid; + struct btp_gatt_service *service; + const ble_uuid_any_t *uuid; uint8_t uuid_length; uint8_t opcode = (uint8_t) (int) arg; @@ -1073,14 +1066,13 @@ disc_prim_uuid_cb(uint16_t conn_handle, if (error->status != 0 && error->status != BLE_HS_EDONE) { tester_rsp(BTP_SERVICE_ID_GATT, opcode, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + BTP_STATUS_FAILED); discover_destroy(); return 0; } if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, opcode, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + tester_send(BTP_SERVICE_ID_GATT, opcode, gatt_buf.buf, gatt_buf.len); discover_destroy(); return 0; } @@ -1091,7 +1083,7 @@ disc_prim_uuid_cb(uint16_t conn_handle, service = gatt_buf_reserve(sizeof(*service) + uuid_length); if (!service) { tester_rsp(BTP_SERVICE_ID_GATT, opcode, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + BTP_STATUS_FAILED); discover_destroy(); return BLE_HS_ENOMEM; } @@ -1121,22 +1113,22 @@ disc_all_desc_cb(uint16_t conn_handle, void *arg) { struct btp_gatt_disc_all_desc_rp *rp = (void *) gatt_buf.buf; - struct btp_gatt_descriptor *dsc; - const ble_uuid_any_t *uuid; + struct btp_gatt_descriptor *dsc; + const ble_uuid_any_t *uuid; uint8_t uuid_length; SYS_LOG_DBG(""); if (error->status != 0 && error->status != BLE_HS_EDONE) { tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + BTP_STATUS_FAILED); discover_destroy(); return 0; } if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC, gatt_buf + .buf, gatt_buf.len); discover_destroy(); return 0; } @@ -1147,7 +1139,7 @@ disc_all_desc_cb(uint16_t conn_handle, dsc = gatt_buf_reserve(sizeof(*dsc) + uuid_length); if (!dsc) { tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + BTP_STATUS_FAILED); discover_destroy(); return BLE_HS_ENOMEM; } @@ -1194,14 +1186,14 @@ disc_all_prim_svcs(uint8_t *data, uint16_t len) fail: tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_PRIM_SVCS, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + BTP_STATUS_FAILED); } static void disc_all_desc(uint8_t *data, uint16_t len) { const struct btp_gatt_disc_all_desc_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; int rc; @@ -1232,8 +1224,7 @@ disc_all_desc(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC, BTP_STATUS_FAILED); } static int @@ -1242,8 +1233,8 @@ find_included_cb(uint16_t conn_handle, const struct ble_gatt_svc *gatt_svc, void *arg) { struct btp_gatt_find_included_rp *rp = (void *) gatt_buf.buf; - struct btp_gatt_included *included; - const ble_uuid_any_t *uuid; + struct btp_gatt_included *included; + const ble_uuid_any_t *uuid; int service_handle = (int) arg; uint8_t uuid_length; @@ -1251,14 +1242,14 @@ find_included_cb(uint16_t conn_handle, if (error->status != 0 && error->status != BLE_HS_EDONE) { tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + BTP_STATUS_FAILED); discover_destroy(); return 0; } if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, gatt_buf + .buf, gatt_buf.len); discover_destroy(); return 0; } @@ -1269,7 +1260,7 @@ find_included_cb(uint16_t conn_handle, included = gatt_buf_reserve(sizeof(*included) + uuid_length); if (!included) { tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + BTP_STATUS_FAILED); discover_destroy(); return BLE_HS_ENOMEM; } @@ -1301,7 +1292,7 @@ disc_chrc_cb(uint16_t conn_handle, { struct btp_gatt_disc_chrc_rp *rp = (void *) gatt_buf.buf; struct btp_gatt_characteristic *chrc; - const ble_uuid_any_t *uuid; + const ble_uuid_any_t *uuid; uint8_t btp_opcode = (uint8_t) (int) arg; uint8_t uuid_length; @@ -1309,14 +1300,14 @@ disc_chrc_cb(uint16_t conn_handle, if (error->status != 0 && error->status != BLE_HS_EDONE) { tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + BTP_STATUS_FAILED); discover_destroy(); return 0; } if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, gatt_buf.buf, gatt_buf.len); + tester_send(BTP_SERVICE_ID_GATT, btp_opcode, gatt_buf.buf, gatt_buf + .len); discover_destroy(); return 0; } @@ -1327,7 +1318,7 @@ disc_chrc_cb(uint16_t conn_handle, chrc = gatt_buf_reserve(sizeof(*chrc) + uuid_length); if (!chrc) { tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + BTP_STATUS_FAILED); discover_destroy(); return BLE_HS_ENOMEM; } @@ -1354,7 +1345,7 @@ static void disc_chrc_uuid(uint8_t *data, uint16_t len) { const struct btp_gatt_disc_chrc_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; ble_uuid_any_t uuid; int rc; @@ -1387,7 +1378,7 @@ disc_chrc_uuid(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_CHRC_UUID, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_CHRC_UUID, BTP_STATUS_FAILED); } @@ -1395,7 +1386,7 @@ static void disc_prim_uuid(uint8_t *data, uint16_t len) { const struct btp_gatt_disc_prim_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; ble_uuid_any_t uuid; int rc; @@ -1424,7 +1415,7 @@ disc_prim_uuid(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_PRIM_UUID, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_PRIM_UUID, BTP_STATUS_FAILED); } @@ -1462,15 +1453,14 @@ disc_all_chrc(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_CHRC, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_CHRC, BTP_STATUS_FAILED); } static void find_included(uint8_t *data, uint16_t len) { const struct btp_gatt_find_included_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; int service_handle_arg; int rc; @@ -1500,8 +1490,7 @@ find_included(uint8_t *data, uint16_t len) return; fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, BTP_STATUS_FAILED); } static int @@ -1513,13 +1502,12 @@ exchange_func(uint16_t conn_handle, if (error->status) { tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_EXCHANGE_MTU, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + BTP_STATUS_FAILED); return 0; } - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_EXCHANGE_MTU, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_EXCHANGE_MTU, BTP_STATUS_SUCCESS); return 0; } @@ -1544,7 +1532,7 @@ exchange_mtu(uint8_t *data, uint16_t len) return; fail: tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_EXCHANGE_MTU, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + BTP_STATUS_FAILED); } static int @@ -1564,8 +1552,7 @@ enable_subscription(uint16_t conn_handle, uint16_t ccc_handle, subscribe_params.ccc_handle = value; - tester_rsp(BTP_SERVICE_ID_GATT, op, CONTROLLER_INDEX, - BTP_STATUS_SUCCESS); + tester_rsp(BTP_SERVICE_ID_GATT, op, BTP_STATUS_SUCCESS); return 0; } @@ -1595,7 +1582,7 @@ static void config_subscription(uint8_t *data, uint16_t len, uint8_t op) { const struct btp_gatt_cfg_notify_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; uint16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle); uint8_t status; int rc; @@ -1604,8 +1591,7 @@ config_subscription(uint8_t *data, uint16_t len, uint8_t op) rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); if (rc) { - tester_rsp(BTP_SERVICE_ID_GATT, op, CONTROLLER_INDEX, - BTP_STATUS_FAILED); + tester_rsp(BTP_SERVICE_ID_GATT, op, BTP_STATUS_FAILED); return; } @@ -1635,7 +1621,7 @@ config_subscription(uint8_t *data, uint16_t len, uint8_t op) SYS_LOG_DBG("Config subscription (op %u) status %u", op, status); - tester_rsp(BTP_SERVICE_ID_GATT, op, CONTROLLER_INDEX, status); + tester_rsp(BTP_SERVICE_ID_GATT, op, status); } #define BTP_PERM_F_READ 0x01 @@ -1678,8 +1664,8 @@ get_attrs(uint8_t *data, uint16_t len) { const struct btp_gatt_get_attributes_cmd *cmd = (void *) data; struct btp_gatt_get_attributes_rp *rp; - struct btp_gatt_attr *gatt_attr; - struct os_mbuf *buf = os_msys_get(0, 0); + struct btp_gatt_attr *gatt_attr; + struct os_mbuf *buf = os_msys_get(0, 0); uint16_t start_handle, end_handle; struct ble_att_svr_entry *entry = NULL; ble_uuid_any_t uuid; @@ -1747,7 +1733,7 @@ get_attrs(uint8_t *data, uint16_t len) goto free; fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_GET_ATTRIBUTES, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_GET_ATTRIBUTES, BTP_STATUS_FAILED); free: os_mbuf_free_chain(buf); @@ -1757,8 +1743,8 @@ static void get_attr_val(uint8_t *data, uint16_t len) { const struct btp_gatt_get_attribute_value_cmd *cmd = (void *) data; - struct btp_gatt_get_attribute_value_rp *rp; - struct ble_gap_conn_desc conn; + struct btp_gatt_get_attribute_value_rp *rp; + struct ble_gap_conn_desc conn; struct os_mbuf *buf = os_msys_get(0, 0); uint16_t handle = sys_cpu_to_le16(cmd->handle); uint8_t out_att_err = 0; @@ -1813,7 +1799,7 @@ change_database(uint8_t *data, uint16_t len) ble_svc_gatt_changed(cmd->start_handle, cmd->end_handle); - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_CHANGE_DATABASE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_CHANGE_DATABASE, BTP_STATUS_SUCCESS); return; @@ -1822,7 +1808,7 @@ change_database(uint8_t *data, uint16_t len) static void supported_commands(uint8_t *data, uint16_t len) { - uint8_t cmds[4]; + uint8_t cmds[4]; struct btp_gatt_read_supported_commands_rp *rp = (void *) cmds; SYS_LOG_DBG(""); @@ -1854,7 +1840,7 @@ supported_commands(uint8_t *data, uint16_t len) tester_set_bit(cmds, BTP_GATT_CHANGE_DATABASE); tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_READ_SUPPORTED_COMMANDS, - CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); + (uint8_t *) rp, sizeof(cmds)); } enum attr_type { @@ -1864,7 +1850,7 @@ enum attr_type { }; void -tester_handle_gatt(uint8_t opcode, uint8_t index, uint8_t *data, +tester_handle_gatt(uint8_t opcode, uint8_t *data, uint16_t len) { switch (opcode) { @@ -1941,8 +1927,7 @@ tester_handle_gatt(uint8_t opcode, uint8_t index, uint8_t *data, get_attr_val(data, len); return; default: - tester_rsp(BTP_SERVICE_ID_GATT, opcode, index, - BTP_STATUS_UNKNOWN_CMD); + tester_rsp(BTP_SERVICE_ID_GATT, opcode, BTP_STATUS_UNKNOWN_CMD); return; } } @@ -1952,7 +1937,7 @@ tester_gatt_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, uint8_t indication, struct os_mbuf *om) { struct btp_gatt_notification_ev *ev; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; diff --git a/apps/bttester/src/btp_gatt_cl.c b/apps/bttester/src/btp_gatt_cl.c index af33f17ee4..f734c9c4e4 100644 --- a/apps/bttester/src/btp_gatt_cl.c +++ b/apps/bttester/src/btp_gatt_cl.c @@ -124,7 +124,7 @@ tester_mtu_exchanged_ev(uint16_t conn_handle, uint16_t mtu, void *arg) { struct btp_gattc_exchange_mtu_ev *ev; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; @@ -175,7 +175,7 @@ exchange_mtu(uint8_t *data, uint16_t len) rsp: tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_EXCHANGE_MTU, - CONTROLLER_INDEX, status); + status); } static int @@ -184,9 +184,9 @@ disc_prim_svcs_cb(uint16_t conn_handle, const struct ble_gatt_svc *gatt_svc, void *arg) { struct btp_gattc_disc_prim_svcs_rp *rp; - struct ble_gap_conn_desc conn; - struct btp_gatt_service *service; - const ble_uuid_any_t *uuid; + struct ble_gap_conn_desc conn; + struct btp_gatt_service *service; + const ble_uuid_any_t *uuid; const ble_addr_t *addr; uint8_t uuid_length; struct os_mbuf *buf = os_msys_get(0, 0); @@ -280,14 +280,14 @@ disc_all_prim_svcs(uint8_t *data, uint16_t len) rsp: tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_PRIM_SVCS, - CONTROLLER_INDEX, status); + status); } static void disc_prim_uuid(uint8_t *data, uint16_t len) { const struct btp_gattc_disc_prim_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; ble_uuid_any_t uuid; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -314,8 +314,7 @@ disc_prim_uuid(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_PRIM_UUID, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_PRIM_UUID, status); } static int @@ -324,8 +323,8 @@ find_included_cb(uint16_t conn_handle, const struct ble_gatt_svc *gatt_svc, void *arg) { struct btp_gattc_find_included_rp *rp; - struct btp_gatt_included *included; - const ble_uuid_any_t *uuid; + struct btp_gatt_included *included; + const ble_uuid_any_t *uuid; int service_handle = (int) arg; uint8_t uuid_length; uint8_t err = (uint8_t) error->status; @@ -405,7 +404,7 @@ static void find_included(uint8_t *data, uint16_t len) { const struct btp_gattc_find_included_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; int service_handle_arg; uint8_t status = BTP_STATUS_SUCCESS; @@ -432,8 +431,7 @@ find_included(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_FIND_INCLUDED, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_FIND_INCLUDED, status); } static int @@ -443,7 +441,7 @@ disc_chrc_cb(uint16_t conn_handle, { struct btp_gattc_disc_chrc_rp *rp; struct btp_gatt_characteristic *chrc; - const ble_uuid_any_t *uuid; + const ble_uuid_any_t *uuid; uint8_t uuid_length; uint8_t opcode = (uint8_t) (int) arg; uint8_t err = (uint8_t) error->status; @@ -523,7 +521,7 @@ static void disc_all_chrc(uint8_t *data, uint16_t len) { const struct btp_gattc_disc_all_chrc_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -552,15 +550,14 @@ disc_all_chrc(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_CHRC, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_CHRC, status); } static void disc_chrc_uuid(uint8_t *data, uint16_t len) { const struct btp_gattc_disc_chrc_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; ble_uuid_any_t uuid; uint8_t status = BTP_STATUS_SUCCESS; @@ -592,8 +589,7 @@ disc_chrc_uuid(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_CHRC_UUID, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_CHRC_UUID, status); } static int @@ -604,8 +600,8 @@ disc_all_desc_cb(uint16_t conn_handle, void *arg) { struct btp_gattc_disc_all_desc_rp *rp; - struct btp_gatt_descriptor *dsc; - const ble_uuid_any_t *uuid; + struct btp_gatt_descriptor *dsc; + const ble_uuid_any_t *uuid; uint8_t uuid_length; uint8_t err = (uint8_t) error->status; struct os_mbuf *buf = os_msys_get(0, 0); @@ -679,7 +675,7 @@ static void disc_all_desc(uint8_t *data, uint16_t len) { const struct btp_gattc_disc_all_desc_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -710,8 +706,7 @@ disc_all_desc(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_DESC, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_DESC, status); } static int @@ -721,7 +716,7 @@ read_cb(uint16_t conn_handle, void *arg) { struct btp_gattc_read_rp *rp; - uint8_t opcode = (uint8_t) (int) arg; + uint8_t opcode = (uint8_t) (int) arg; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; struct ble_gap_conn_desc conn; @@ -772,7 +767,7 @@ static void read(uint8_t *data, uint16_t len) { const struct btp_gattc_read_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -795,8 +790,7 @@ read(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ, status); } static int @@ -807,7 +801,7 @@ read_uuid_cb(uint16_t conn_handle, { struct btp_gattc_read_uuid_rp *rp; struct btp_gatt_read_uuid_chr *chr; - uint8_t opcode = (uint8_t) (int) arg; + uint8_t opcode = (uint8_t) (int) arg; uint8_t err = (uint8_t) error->status; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; @@ -875,7 +869,7 @@ static void read_uuid(uint8_t *data, uint16_t len) { const struct btp_gattc_read_uuid_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; ble_uuid_any_t uuid; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -905,8 +899,7 @@ read_uuid(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_UUID, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_UUID, status); } static int @@ -975,7 +968,7 @@ static void read_long(uint8_t *data, uint16_t len) { const struct btp_gattc_read_long_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -999,15 +992,14 @@ read_long(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_LONG, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_LONG, status); } static void read_multiple(uint8_t *data, uint16_t len) { const struct btp_gattc_read_multiple_cmd *cmd = (void *) data; - uint16_t handles[cmd->handles_count]; + uint16_t handles[cmd->handles_count]; struct ble_gap_conn_desc conn; uint8_t status = BTP_STATUS_SUCCESS; int rc, i; @@ -1037,15 +1029,14 @@ read_multiple(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_MULTIPLE, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_MULTIPLE, status); } static void write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) { const struct btp_gattc_write_without_rsp_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -1064,7 +1055,7 @@ write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, op, CONTROLLER_INDEX, status); + tester_rsp(BTP_SERVICE_ID_GATTC, op, status); } static int @@ -1073,7 +1064,7 @@ write_cb(uint16_t conn_handle, const struct ble_gatt_error *error, void *arg) { struct btp_gattc_write_rp *rp; - uint8_t err = (uint8_t) error->status; + uint8_t err = (uint8_t) error->status; uint8_t opcode = (uint8_t) (int) arg; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; @@ -1107,7 +1098,7 @@ static void write(uint8_t *data, uint16_t len) { const struct btp_gattc_write_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -1126,15 +1117,14 @@ write(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_WRITE, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_WRITE, status); } static void write_long(uint8_t *data, uint16_t len) { const struct btp_gattc_write_long_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; struct os_mbuf *om = NULL; uint8_t status = BTP_STATUS_SUCCESS; int rc = 0; @@ -1168,8 +1158,7 @@ write_long(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to send Write Long request, rc=%d", rc); os_mbuf_free_chain(om); rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_WRITE_LONG, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_WRITE_LONG, status); } static int @@ -1180,7 +1169,7 @@ reliable_write_cb(uint16_t conn_handle, void *arg) { struct btp_gattc_write_rp *rp; - uint8_t err = (uint8_t) error->status; + uint8_t err = (uint8_t) error->status; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; struct ble_gap_conn_desc conn; @@ -1213,7 +1202,7 @@ static void reliable_write(uint8_t *data, uint16_t len) { const struct btp_gattc_reliable_write_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; struct ble_gatt_attr attr; struct os_mbuf *om = NULL; uint8_t status = BTP_STATUS_SUCCESS; @@ -1251,8 +1240,7 @@ reliable_write(uint8_t *data, uint16_t len) fail: os_mbuf_free_chain(om); rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_WRITE_LONG, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_WRITE_LONG, status); } static int @@ -1262,7 +1250,7 @@ subscribe_cb(uint16_t conn_handle, void *arg) { struct btp_subscribe_rp *rp; - uint8_t err = (uint8_t) error->status; + uint8_t err = (uint8_t) error->status; uint8_t opcode = (uint8_t) (int) arg; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; @@ -1351,7 +1339,7 @@ static void config_subscription(uint8_t *data, uint16_t len, uint8_t op) { const struct btp_gattc_cfg_notify_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; uint16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle); uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -1389,7 +1377,7 @@ config_subscription(uint8_t *data, uint16_t len, uint8_t op) rsp: SYS_LOG_DBG("Config subscription (op %u) status %u", op, status); - tester_rsp(BTP_SERVICE_ID_GATTC, op, CONTROLLER_INDEX, status); + tester_rsp(BTP_SERVICE_ID_GATTC, op, status); } int @@ -1397,7 +1385,7 @@ tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, uint8_t indication, struct os_mbuf *om) { struct btp_gattc_notification_ev *ev; - struct ble_gap_conn_desc conn; + struct ble_gap_conn_desc conn; struct os_mbuf *buf = os_msys_get(0, 0); const ble_addr_t *addr; @@ -1434,7 +1422,7 @@ tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, static void supported_commands(uint8_t *data, uint16_t len) { - uint8_t cmds[3]; + uint8_t cmds[3]; struct btp_gatt_read_supported_commands_rp *rp = (void *) cmds; SYS_LOG_DBG(""); @@ -1464,11 +1452,11 @@ supported_commands(uint8_t *data, uint16_t len) tester_set_bit(cmds, BTP_GATTC_CFG_INDICATE); tester_send(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_SUPPORTED_COMMANDS, - CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); + (uint8_t *) rp, sizeof(cmds)); } void -tester_handle_gattc(uint8_t opcode, uint8_t index, uint8_t *data, +tester_handle_gattc(uint8_t opcode, uint8_t *data, uint16_t len) { switch (opcode) { @@ -1533,8 +1521,7 @@ tester_handle_gattc(uint8_t opcode, uint8_t index, uint8_t *data, config_subscription(data, len, opcode); return; default: - tester_rsp(BTP_SERVICE_ID_GATTC, opcode, index, - BTP_STATUS_UNKNOWN_CMD); + tester_rsp(BTP_SERVICE_ID_GATTC, opcode, BTP_STATUS_UNKNOWN_CMD); return; } } \ No newline at end of file diff --git a/apps/bttester/src/btp_l2cap.c b/apps/bttester/src/btp_l2cap.c index 93435943a4..03d70688a2 100644 --- a/apps/bttester/src/btp_l2cap.c +++ b/apps/bttester/src/btp_l2cap.c @@ -122,8 +122,8 @@ static void recv_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, struct os_mbuf *buf, void *arg) { - struct btp_l2cap_data_received_ev *ev = (void *) recv_cb_buf; - struct channel *channel = find_channel(chan); + struct btp_l2cap_data_received_ev *ev = (void *) recv_cb_buf; + struct channel *channel = find_channel(chan); assert(channel != NULL); ev->chan_id = channel->chan_id; @@ -136,7 +136,7 @@ recv_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, os_mbuf_copydata(buf, 0, ev->data_length, ev->data); tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_DATA_RECEIVED, - CONTROLLER_INDEX, recv_cb_buf, sizeof(*ev) + ev->data_length); + recv_cb_buf, sizeof(*ev) + ev->data_length); tester_l2cap_coc_recv(chan, buf); } @@ -147,10 +147,10 @@ unstalled_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, { if (status) { tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, - CONTROLLER_INDEX, BTP_STATUS_FAILED); + BTP_STATUS_FAILED); } else { tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); + BTP_STATUS_SUCCESS); } } @@ -160,7 +160,7 @@ reconfigured_ev(uint16_t conn_handle, struct ble_l2cap_chan *chan, int status) { struct btp_l2cap_reconfigured_ev ev; - struct channel *channel; + struct channel *channel; if (status != 0) { return; @@ -176,7 +176,7 @@ reconfigured_ev(uint16_t conn_handle, struct ble_l2cap_chan *chan, ev.our_mps = chan_info->our_l2cap_mtu; tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_RECONFIGURED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); } static void @@ -184,7 +184,7 @@ connected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, struct ble_l2cap_chan_info *chan_info, void *arg) { struct btp_l2cap_connected_ev ev; - struct ble_gap_conn_desc desc; + struct ble_gap_conn_desc desc; struct channel *channel = find_channel(chan); if (channel == NULL) { @@ -206,7 +206,7 @@ connected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, sizeof(ev.address)); } - tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_CONNECTED, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_CONNECTED, (uint8_t *) &ev, sizeof(ev)); } @@ -215,7 +215,7 @@ disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, struct ble_l2cap_chan_info *chan_info, void *arg) { struct btp_l2cap_disconnected_ev ev; - struct ble_gap_conn_desc desc; + struct ble_gap_conn_desc desc; struct channel *channel; memset(&ev, 0, sizeof(struct btp_l2cap_disconnected_ev)); @@ -235,7 +235,7 @@ disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, } tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_DISCONNECTED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); } static int @@ -407,9 +407,9 @@ static void connect(uint8_t *data, uint16_t len) { const struct btp_l2cap_connect_cmd *cmd = (void *) data; - uint8_t rp_buf[sizeof(struct btp_l2cap_connect_rp) + cmd->num]; - struct btp_l2cap_connect_rp *rp = (void *) rp_buf; - struct ble_gap_conn_desc desc; + uint8_t rp_buf[sizeof(struct btp_l2cap_connect_rp) + cmd->num]; + struct btp_l2cap_connect_rp *rp = (void *) rp_buf; + struct ble_gap_conn_desc desc; struct channel *chan; struct os_mbuf *sdu_rx[cmd->num]; ble_addr_t *addr = (void *) data; @@ -481,13 +481,13 @@ connect(uint8_t *data, uint16_t len) goto fail; } - tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CONNECT, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CONNECT, (uint8_t *) rp, sizeof(rp_buf)); return; fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CONNECT, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CONNECT, BTP_STATUS_FAILED); } @@ -495,7 +495,7 @@ static void disconnect(const uint8_t *data, uint16_t len) { const struct btp_l2cap_disconnect_cmd *cmd = (void *) data; - struct channel *chan; + struct channel *chan; uint8_t status; int err; @@ -513,15 +513,15 @@ disconnect(const uint8_t *data, uint16_t len) status = BTP_STATUS_SUCCESS; rsp: - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_DISCONNECT, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_DISCONNECT, status); } static void send_data(const uint8_t *data, uint16_t len) { - const struct btp_l2cap_send_data_cmd *cmd = (void *) data; - struct os_mbuf *sdu_tx = NULL; + const struct btp_l2cap_send_data_cmd *cmd = (void *) data; + struct os_mbuf *sdu_tx = NULL; int rc; uint16_t data_len = sys_le16_to_cpu(cmd->data_len); struct channel *chan = get_channel(cmd->chan_id); @@ -550,7 +550,7 @@ send_data(const uint8_t *data, uint16_t len) /* ble_l2cap_send takes ownership of the sdu */ rc = ble_l2cap_send(chan->chan, sdu_tx); if (rc == 0 || rc == BLE_HS_ESTALLED) { - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, BTP_STATUS_SUCCESS); return; } @@ -559,7 +559,7 @@ send_data(const uint8_t *data, uint16_t len) os_mbuf_free_chain(sdu_tx); fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, BTP_STATUS_FAILED); } @@ -582,12 +582,12 @@ listen(const uint8_t *data, uint16_t len) goto fail; } - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_LISTEN, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_LISTEN, BTP_STATUS_SUCCESS); return; fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_LISTEN, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_LISTEN, BTP_STATUS_FAILED); } @@ -595,7 +595,7 @@ static void credits(uint8_t *data, uint16_t len) { const struct btp_l2cap_credits_cmd *cmd = (void *) data; - struct os_mbuf *sdu; + struct os_mbuf *sdu; int rc; struct channel *channel = get_channel(cmd->chan_id); @@ -613,11 +613,11 @@ credits(uint8_t *data, uint16_t len) if (rc != 0) { goto fail; } - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CREDITS, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CREDITS, BTP_STATUS_SUCCESS); return; fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CREDITS, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CREDITS, BTP_STATUS_FAILED); } @@ -658,19 +658,19 @@ reconfigure(const uint8_t *data, uint16_t len) goto fail; } - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_RECONFIGURE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_RECONFIGURE, BTP_STATUS_SUCCESS); return; fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_RECONFIGURE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_RECONFIGURE, BTP_STATUS_FAILED); } static void supported_commands(uint8_t *data, uint16_t len) { - uint8_t cmds[1]; + uint8_t cmds[1]; struct btp_l2cap_read_supported_commands_rp *rp = (void *) cmds; memset(cmds, 0, sizeof(cmds)); @@ -683,11 +683,11 @@ supported_commands(uint8_t *data, uint16_t len) tester_set_bit(cmds, BTP_L2CAP_RECONFIGURE); tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_READ_SUPPORTED_COMMANDS, - CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds)); + (uint8_t *) rp, sizeof(cmds)); } void -tester_handle_l2cap(uint8_t opcode, uint8_t index, uint8_t *data, +tester_handle_l2cap(uint8_t opcode, uint8_t *data, uint16_t len) { switch (opcode) { @@ -713,7 +713,7 @@ tester_handle_l2cap(uint8_t opcode, uint8_t index, uint8_t *data, credits(data, len); return; default: - tester_rsp(BTP_SERVICE_ID_L2CAP, opcode, index, + tester_rsp(BTP_SERVICE_ID_L2CAP, opcode, BTP_STATUS_UNKNOWN_CMD); return; } diff --git a/apps/bttester/src/btp_mesh.c b/apps/bttester/src/btp_mesh.c index cc36515a4e..3e0668ea74 100644 --- a/apps/bttester/src/btp_mesh.c +++ b/apps/bttester/src/btp_mesh.c @@ -284,7 +284,7 @@ link_open(bt_mesh_prov_bearer_t bearer) } tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROV_LINK_OPEN, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); } static void @@ -308,7 +308,7 @@ link_close(bt_mesh_prov_bearer_t bearer) } tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROV_LINK_CLOSED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); } static int @@ -322,7 +322,7 @@ output_number(bt_mesh_output_action_t action, uint32_t number) ev.number = sys_cpu_to_le32(number); tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_OUT_NUMBER_ACTION, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); return 0; } @@ -331,7 +331,7 @@ static int output_string(const char *str) { struct btp_mesh_out_string_action_ev *ev; - struct os_mbuf *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE); + struct os_mbuf *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE); SYS_LOG_DBG("str %s", str); @@ -361,7 +361,7 @@ input(bt_mesh_input_action_t action, uint8_t size) ev.action = sys_cpu_to_le16(action); ev.size = size; - tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_IN_ACTION, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_IN_ACTION, (uint8_t *) &ev, sizeof(ev)); return 0; @@ -379,7 +379,7 @@ prov_complete(uint16_t net_idx, uint16_t addr) net.local = addr; net.dst = addr; - tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROVISIONED, CONTROLLER_INDEX, + tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROVISIONED, NULL, 0); } @@ -426,7 +426,7 @@ config_prov(uint8_t *data, uint16_t len) prov.input_actions = sys_le16_to_cpu(cmd->in_actions); tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_CONFIG_PROVISIONING, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); + BTP_STATUS_SUCCESS); } static void @@ -445,7 +445,7 @@ provision_node(uint8_t *data, uint16_t len) net_key_idx = sys_le16_to_cpu(cmd->net_key_idx); tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_PROVISION_NODE, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); + BTP_STATUS_SUCCESS); } static void @@ -477,8 +477,7 @@ init(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_INIT, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_INIT, status); } static void @@ -488,15 +487,15 @@ reset(uint8_t *data, uint16_t len) bt_mesh_reset(); - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_RESET, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_RESET, BTP_STATUS_SUCCESS); } static void input_number(uint8_t *data, uint16_t len) { - const struct btp_mesh_input_number_cmd *cmd = (void *) data; - uint8_t status = BTP_STATUS_SUCCESS; + const struct btp_mesh_input_number_cmd *cmd = (void *) data; + uint8_t status = BTP_STATUS_SUCCESS; uint32_t number; int err; @@ -509,15 +508,14 @@ input_number(uint8_t *data, uint16_t len) status = BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_INPUT_NUMBER, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_INPUT_NUMBER, status); } static void input_string(uint8_t *data, uint16_t len) { - const struct btp_mesh_input_string_cmd *cmd = (void *) data; - uint8_t status = BTP_STATUS_SUCCESS; + const struct btp_mesh_input_string_cmd *cmd = (void *) data; + uint8_t status = BTP_STATUS_SUCCESS; uint8_t str_auth[16]; int err; @@ -541,8 +539,7 @@ input_string(uint8_t *data, uint16_t len) } rsp: - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_INPUT_STRING, CONTROLLER_INDEX, - status); + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_INPUT_STRING, status); } static void @@ -554,7 +551,7 @@ ivu_test_mode(uint8_t *data, uint16_t len) bt_mesh_iv_update_test(cmd->enable ? true : false); - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_IVU_TEST_MODE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_IVU_TEST_MODE, BTP_STATUS_SUCCESS); } @@ -570,7 +567,7 @@ ivu_toggle_state(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to toggle the IV Update state"); } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_IVU_TOGGLE_STATE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_IVU_TOGGLE_STATE, result ? BTP_STATUS_SUCCESS : BTP_STATUS_FAILED); } @@ -589,7 +586,7 @@ lpn(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to toggle LPN (err %d)", err); } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } @@ -605,7 +602,7 @@ lpn_poll(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to send poll msg (err %d)", err); } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN_POLL, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN_POLL, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } @@ -613,7 +610,7 @@ static void net_send(uint8_t *data, uint16_t len) { struct btp_mesh_net_send_cmd *cmd = (void *) data; - struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); + struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); struct bt_mesh_msg_ctx ctx = { .net_idx = net.net_idx, .app_idx = vnd_app_key_idx, @@ -638,7 +635,7 @@ net_send(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to send (err %d)", err); } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_NET_SEND, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_NET_SEND, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); os_mbuf_free_chain(msg); @@ -648,8 +645,8 @@ static void health_generate_faults(uint8_t *data, uint16_t len) { struct btp_mesh_health_generate_faults_rp *rp; - struct os_mbuf *buf = NET_BUF_SIMPLE(sizeof(*rp) + sizeof(cur_faults) + - sizeof(reg_faults)); + struct os_mbuf *buf = NET_BUF_SIMPLE(sizeof(*rp) + sizeof(cur_faults) + + sizeof(reg_faults)); uint8_t some_faults[] = {0x01, 0x02, 0x03, 0xff, 0x06}; uint8_t cur_faults_count, reg_faults_count; @@ -682,14 +679,14 @@ health_clear_faults(uint8_t *data, uint16_t len) bt_mesh_fault_update(&elements[0]); tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_HEALTH_CLEAR_FAULTS, - CONTROLLER_INDEX, BTP_STATUS_SUCCESS); + BTP_STATUS_SUCCESS); } static void model_send(uint8_t *data, uint16_t len) { struct btp_mesh_model_send_cmd *cmd = (void *) data; - struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); + struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); struct bt_mesh_msg_ctx ctx = { .net_idx = net.net_idx, .app_idx = BT_MESH_KEY_DEV, @@ -728,7 +725,7 @@ model_send(uint8_t *data, uint16_t len) } fail: - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_MODEL_SEND, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_MODEL_SEND, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); os_mbuf_free_chain(msg); @@ -739,8 +736,8 @@ model_send(uint8_t *data, uint16_t len) static void lpn_subscribe(uint8_t *data, uint16_t len) { - struct btp_mesh_lpn_subscribe_cmd *cmd = (void *) data; - uint16_t address = sys_le16_to_cpu(cmd->address); + struct btp_mesh_lpn_subscribe_cmd *cmd = (void *) data; + uint16_t address = sys_le16_to_cpu(cmd->address); int err; SYS_LOG_DBG("address 0x%04x", address); @@ -750,15 +747,15 @@ lpn_subscribe(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to subscribe (err %d)", err); } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN_SUBSCRIBE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN_SUBSCRIBE, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } static void lpn_unsubscribe(uint8_t *data, uint16_t len) { - struct btp_mesh_lpn_unsubscribe_cmd *cmd = (void *) data; - uint16_t address = sys_le16_to_cpu(cmd->address); + struct btp_mesh_lpn_unsubscribe_cmd *cmd = (void *) data; + uint16_t address = sys_le16_to_cpu(cmd->address); int err; SYS_LOG_DBG("address 0x%04x", address); @@ -768,7 +765,7 @@ lpn_unsubscribe(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to unsubscribe (err %d)", err); } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN_UNSUBSCRIBE, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN_UNSUBSCRIBE, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } @@ -784,7 +781,7 @@ rpl_clear(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to clear RPL (err %d)", err); } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_RPL_CLEAR, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_RPL_CLEAR, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } @@ -802,12 +799,12 @@ proxy_identity_enable(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to enable proxy identity (err %d)", err); } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_PROXY_IDENTITY, CONTROLLER_INDEX, + tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_PROXY_IDENTITY, err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); } void -tester_handle_mesh(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len) +tester_handle_mesh(uint8_t opcode, uint8_t *data, uint16_t len) { switch (opcode) { case BTP_MESH_READ_SUPPORTED_COMMANDS: @@ -870,7 +867,7 @@ tester_handle_mesh(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len) proxy_identity_enable(data, len); break; default: - tester_rsp(BTP_SERVICE_ID_MESH, opcode, index, + tester_rsp(BTP_SERVICE_ID_MESH, opcode, BTP_STATUS_UNKNOWN_CMD); break; } @@ -884,7 +881,7 @@ net_recv_ev(uint8_t ttl, const void *payload, size_t payload_len) { - struct os_mbuf *buf = NET_BUF_SIMPLE(UINT8_MAX); + struct os_mbuf *buf = NET_BUF_SIMPLE(UINT8_MAX); struct btp_mesh_net_recv_ev *ev; SYS_LOG_DBG("ttl 0x%02x ctl 0x%02x src 0x%04x dst 0x%04x " @@ -964,14 +961,14 @@ invalid_bearer_cb(uint8_t opcode) SYS_LOG_DBG("opcode 0x%02x", opcode); tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_INVALID_BEARER, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); } static void incomp_timer_exp_cb(void) { tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_INCOMP_TIMER_EXP, - CONTROLLER_INDEX, NULL, 0); + NULL, 0); } static struct bt_test_cb bt_test_cb = { @@ -996,20 +993,20 @@ lpn_established(uint16_t friend_addr) friend_addr, lpn->queue_size, lpn->recv_win); tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_LPN_ESTABLISHED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); } static void lpn_terminated(uint16_t friend_addr) { - struct bt_mesh_lpn *lpn = &bt_mesh.lpn; - struct btp_mesh_lpn_terminated_ev ev = {lpn->sub->net_idx, friend_addr}; + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + struct btp_mesh_lpn_terminated_ev ev = {lpn->sub->net_idx, friend_addr}; SYS_LOG_DBG("Friendship (as LPN) lost with Friend " "0x%04x", friend_addr); tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_LPN_TERMINATED, - CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev)); + (uint8_t *) &ev, sizeof(ev)); } void diff --git a/apps/bttester/src/bttester.c b/apps/bttester/src/bttester.c index 1bb22e7cfc..f0d0886302 100644 --- a/apps/bttester/src/bttester.c +++ b/apps/bttester/src/bttester.c @@ -47,15 +47,60 @@ struct btp_buf { uint8_t data[BTP_MTU]; struct btp_hdr hdr; }; + uint8_t rsp[BTP_MTU]; }; static struct btp_buf cmd_buf[CMD_QUEUED]; +static struct { + const struct btp_handler *handlers; + uint8_t num; +} service_handler[BTP_SERVICE_ID_MAX + 1]; + +static void +tester_send_with_index(uint8_t service, uint8_t opcode, uint8_t index, + uint8_t *data, size_t len); +static void +tester_rsp_with_index(uint8_t service, uint8_t opcode, uint8_t index, + uint8_t status); + +void +tester_register_command_handlers(uint8_t service, + const struct btp_handler *handlers, + size_t num) +{ + __ASSERT_NO_MSG(service <= BTP_SERVICE_ID_MAX); + __ASSERT_NO_MSG(service_handler[service].handlers == NULL); + + service_handler[service].handlers = handlers; + service_handler[service].num = num; +} + +static const struct btp_handler * +find_btp_handler(uint8_t service, uint8_t opcode) +{ + if ((service > BTP_SERVICE_ID_MAX) || + (service_handler[service].handlers == NULL)) { + return NULL; + } + + for (uint8_t i = 0; i < service_handler[service].num; i++) { + if (service_handler[service].handlers[i].opcode == opcode) { + return &service_handler[service].handlers[i]; + } + } + + return NULL; +} + static void cmd_handler(struct os_event *ev) { + const struct btp_handler *btp; uint16_t len; struct btp_buf *cmd; + uint8_t status; + uint16_t rsp_len = 0; if (!ev || !ev->ev_arg) { return; @@ -71,43 +116,30 @@ cmd_handler(struct os_event *ev) sizeof(cmd->hdr) + len)); } - /* TODO - * verify if service is registered before calling handler - */ - - switch (cmd->hdr.service) { - case BTP_SERVICE_ID_CORE: - tester_handle_core(cmd->hdr.opcode, cmd->hdr.index, - cmd->hdr.data, len); - break; - case BTP_SERVICE_ID_GAP: - tester_handle_gap(cmd->hdr.opcode, cmd->hdr.index, - cmd->hdr.data, len); - break; - case BTP_SERVICE_ID_GATT: - tester_handle_gatt(cmd->hdr.opcode, cmd->hdr.index, - cmd->hdr.data, len); - break; -#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) - case BTP_SERVICE_ID_L2CAP: - tester_handle_l2cap(cmd->hdr.opcode, cmd->hdr.index, - cmd->hdr.data, len); - break; -#endif /* MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) */ -#if MYNEWT_VAL(BLE_MESH) - case BTP_SERVICE_ID_MESH: - tester_handle_mesh(cmd->hdr.opcode, cmd->hdr.index, - cmd->hdr.data, len); - break; -#endif /* MYNEWT_VAL(BLE_MESH) */ - case BTP_SERVICE_ID_GATTC: - tester_handle_gattc(cmd->hdr.opcode, cmd->hdr.index, - cmd->hdr.data, len); - break; - default: - tester_rsp(cmd->hdr.service, cmd->hdr.opcode, - cmd->hdr.index, BTP_STATUS_FAILED); - break; + btp = find_btp_handler(cmd->hdr.service, cmd->hdr.opcode); + if (btp) { + if (btp->index != cmd->hdr.index) { + status = BTP_STATUS_FAILED; + } else if ((btp->expect_len >= 0) && (btp->expect_len != len)) { + status = BTP_STATUS_FAILED; + } else { + status = btp->func(cmd->hdr.data, len, + cmd->rsp, &rsp_len); + } + + __ASSERT_NO_MSG((rsp_len + sizeof(struct btp_hdr)) <= BTP_MTU); + } else { + status = BTP_STATUS_UNKNOWN_CMD; + } + + if (status != BTP_STATUS_DELAY_REPLY) { + if ((status == BTP_STATUS_SUCCESS) && rsp_len > 0) { + tester_send_with_index(cmd->hdr.service, cmd->hdr.opcode, + cmd->hdr.index, cmd->rsp, rsp_len); + } else { + tester_rsp_with_index(cmd->hdr.service, cmd->hdr.opcode, + cmd->hdr.index, status); + } } os_eventq_put(&avail_queue, ev); @@ -191,20 +223,23 @@ tester_init(void) bttester_pipe_register(buf->data, BTP_MTU, recv_cb); - tester_send(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, BTP_INDEX_NONE, - NULL, 0); + /* core service is always available */ + tester_init_core(); + + tester_send_with_index(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, + BTP_INDEX_NONE, NULL, 0); } -void -tester_send(uint8_t service, uint8_t opcode, uint8_t index, uint8_t *data, - size_t len) +static void +tester_send_with_index(uint8_t service, uint8_t opcode, uint8_t index, + uint8_t *data, size_t len) { struct btp_hdr msg; msg.service = service; msg.opcode = opcode; msg.index = index; - msg.len = len; + msg.len = sys_cpu_to_le16(len); bttester_pipe_send((uint8_t *) &msg, sizeof(msg)); if (data && len) { @@ -238,16 +273,29 @@ tester_send_buf(uint8_t service, uint8_t opcode, uint8_t index, } } -void -tester_rsp(uint8_t service, uint8_t opcode, uint8_t index, uint8_t status) +static void +tester_rsp_with_index(uint8_t service, uint8_t opcode, uint8_t index, + uint8_t status) { struct btp_status s; if (status == BTP_STATUS_SUCCESS) { - tester_send(service, opcode, index, NULL, 0); + tester_send_with_index(service, opcode, index, NULL, 0); return; } s.code = status; - tester_send(service, BTP_STATUS, index, (uint8_t *) &s, sizeof(s)); + tester_send_with_index(service, BTP_STATUS, index, (uint8_t *) &s, sizeof(s)); +} + +void +tester_send(uint8_t service, uint8_t opcode, uint8_t *data, size_t len) +{ + tester_send_with_index(service, opcode, BTP_INDEX, data, len); +} + +void +tester_rsp(uint8_t service, uint8_t opcode, uint8_t status) +{ + tester_rsp_with_index(service, opcode, BTP_INDEX, status); } diff --git a/apps/bttester/src/glue.h b/apps/bttester/src/glue.h index 0372d757fe..024f795643 100644 --- a/apps/bttester/src/glue.h +++ b/apps/bttester/src/glue.h @@ -67,4 +67,23 @@ net_buf_simple_push(struct os_mbuf *om, uint8_t len); const char * bt_hex(const void *buf, size_t len); +/** + * INTERNAL_HIDDEN @endcond + */ + +/** + * @brief Define an array of atomic variables. + * + * This macro defines an array of atomic variables containing at least + * @a num_bits bits. + * + * @note + * If used from file scope, the bits of the array are initialized to zero; + * if used from within a function, the bits are left uninitialized. + * + * @param name Name of array of atomic variables. + * @param num_bits Number of bits needed. + */ +#define ATOMIC_DEFINE(name, num_bits) \ + atomic_t name[1 + ((num_bits) - 1) / ATOMIC_BITS] #endif /* __GLUE_H__ */ From ba8a946fba175a20a85760d118221151fbfa1aed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 10 Jul 2023 13:26:50 +0200 Subject: [PATCH 0755/1333] apps/bttester: drop `glue` module There is no need to be dependent on `glue` module and it can be dropped from application. Mesh part of bttester can still use one from `"mesh/glue.h"` --- apps/bttester/src/btp/btp.h | 10 -- apps/bttester/src/btp/btp_gap.h | 15 +++ apps/bttester/src/btp/bttester.h | 15 ++- apps/bttester/src/btp_gap.c | 64 +++++++----- apps/bttester/src/btp_gatt.c | 143 ++++++++++++++------------ apps/bttester/src/btp_gatt_cl.c | 166 +++++++++++++++++++------------ apps/bttester/src/btp_l2cap.c | 8 +- apps/bttester/src/btp_mesh.c | 14 +-- apps/bttester/src/bttester.c | 53 ++++++++-- apps/bttester/src/glue.c | 129 ------------------------ apps/bttester/src/glue.h | 89 ----------------- 11 files changed, 298 insertions(+), 408 deletions(-) delete mode 100644 apps/bttester/src/glue.c delete mode 100644 apps/bttester/src/glue.h diff --git a/apps/bttester/src/btp/btp.h b/apps/bttester/src/btp/btp.h index 996ab7912b..5e1a172e9f 100644 --- a/apps/bttester/src/btp/btp.h +++ b/apps/bttester/src/btp/btp.h @@ -34,12 +34,6 @@ #include "btp_l2cap.h" #include "btp_mesh.h" -#if MYNEWT_VAL(BLE_MESH) -#include "mesh/glue.h" -#else -#include "../glue.h" -#endif - #define BTP_MTU MYNEWT_VAL(BTTESTER_BTP_DATA_SIZE_MAX) #define BTP_DATA_MAX_SIZE (BTP_MTU - sizeof(struct btp_hdr)) @@ -78,10 +72,6 @@ #define SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG #define SYS_LOG_DOMAIN "bttester" -#define sys_cpu_to_le32 htole32 -#define sys_le32_to_cpu le32toh -#define sys_cpu_to_le16 htole16 - struct btp_hdr { uint8_t service; uint8_t opcode; diff --git a/apps/bttester/src/btp/btp_gap.h b/apps/bttester/src/btp/btp_gap.h index 5ef756113f..ca60b81037 100644 --- a/apps/bttester/src/btp/btp_gap.h +++ b/apps/bttester/src/btp/btp_gap.h @@ -26,6 +26,21 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "nimble/ble.h" + +struct adv_data { + uint8_t type; + uint8_t data_len; + const uint8_t *data; +}; + +#define ADV_DATA(_type, _data, _data_len) \ + { \ + .type = (_type), \ + .data_len = (_data_len), \ + .data = (const uint8_t *)(_data), \ + } + /* GAP Service */ /* commands */ #define BTP_GAP_READ_SUPPORTED_COMMANDS 0x01 diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h index e13400ae96..3aed917796 100644 --- a/apps/bttester/src/btp/bttester.h +++ b/apps/bttester/src/btp/bttester.h @@ -31,13 +31,18 @@ #include "syscfg/syscfg.h" #include "host/ble_gatt.h" -#if MYNEWT_VAL(BLE_MESH) -#include "mesh/glue.h" -#else -#include "glue.h" -#endif +#include "os/os_mbuf.h" #include +#define BIT(n) (1UL << (n)) + +/* Reset os_mbuf to reusable state */ +void +tester_mbuf_reset(struct os_mbuf *buf); + +const char * +string_from_bytes(const void *buf, size_t len); + static inline void tester_set_bit(uint8_t *addr, unsigned int bit) { diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 66b88a6802..378e3ae5b2 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -35,6 +35,8 @@ #include "btp/btp.h" +#include + #define CONTROLLER_INDEX 0 #define CONTROLLER_NAME "btp_tester" @@ -235,8 +237,8 @@ controller_info(const void *cmd, uint16_t cmd_len, current_settings |= BIT(BTP_GAP_SETTINGS_SC); } - rp->supported_settings = sys_cpu_to_le32(supported_settings); - rp->current_settings = sys_cpu_to_le32(current_settings); + rp->supported_settings = htole32(supported_settings); + rp->current_settings = htole32(current_settings); memcpy(rp->name, CONTROLLER_NAME, sizeof(CONTROLLER_NAME)); @@ -299,7 +301,7 @@ set_connectable(const void *cmd, uint16_t cmd_len, adv_params.conn_mode = BLE_GAP_CONN_MODE_NON; } - rp->current_settings = sys_cpu_to_le32(current_settings); + rp->current_settings = htole32(current_settings); *rsp_len = sizeof(*rp); @@ -339,7 +341,7 @@ set_discoverable(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } - rp->current_settings = sys_cpu_to_le32(current_settings); + rp->current_settings = htole32(current_settings); *rsp_len = sizeof(*rp); @@ -362,18 +364,18 @@ set_bondable(const void *cmd, uint16_t cmd_len, current_settings &= ~BIT(BTP_GAP_SETTINGS_BONDABLE); } - rp->current_settings = sys_cpu_to_le32(current_settings); + rp->current_settings = htole32(current_settings); *rsp_len = sizeof(*rp); return BTP_STATUS_SUCCESS; } -static struct bt_data ad[10] = { - BT_DATA(BLE_HS_ADV_TYPE_FLAGS, &ad_flags, sizeof(ad_flags)), +static struct adv_data ad[10] = { + ADV_DATA(BLE_HS_ADV_TYPE_FLAGS, &ad_flags, sizeof(ad_flags)), }; -static struct bt_data sd[10]; +static struct adv_data sd[10]; static int -set_ad(const struct bt_data *ad_data, size_t ad_len, +set_ad(const struct adv_data *ad_data, size_t ad_len, uint8_t *buf, uint8_t *buf_len) { int i; @@ -519,7 +521,7 @@ start_advertising(const void *cmd, uint16_t cmd_len, } current_settings |= BIT(BTP_GAP_SETTINGS_ADVERTISING); - rp->current_settings = sys_cpu_to_le32(current_settings); + rp->current_settings = htole32(current_settings); *rsp_len = sizeof(*rp); @@ -541,7 +543,7 @@ stop_advertising(const void *cmd, uint16_t cmd_len, } current_settings &= ~BIT(BTP_GAP_SETTINGS_ADVERTISING); - rp->current_settings = sys_cpu_to_le32(current_settings); + rp->current_settings = htole32(current_settings); *rsp_len = sizeof(*rp); @@ -584,18 +586,27 @@ store_adv(const ble_addr_t *addr, int8_t rssi, const uint8_t *data, uint8_t len) { struct btp_gap_device_found_ev *ev; - + void *adv_data; /* cleanup */ - net_buf_simple_init(adv_buf, 0); + tester_mbuf_reset(adv_buf); - ev = net_buf_simple_add(adv_buf, sizeof(*ev)); + ev = os_mbuf_extend(adv_buf, sizeof(*ev)); + if (!ev) { + return; + } memcpy(ev->address, addr->val, sizeof(ev->address)); ev->address_type = addr->type; ev->rssi = rssi; ev->flags = BTP_GAP_DEVICE_FOUND_FLAG_AD | BTP_GAP_DEVICE_FOUND_FLAG_RSSI; ev->eir_data_len = len; - memcpy(net_buf_simple_add(adv_buf, len), data, len); + + adv_data = os_mbuf_extend(adv_buf, len); + if (!adv_data) { + return; + } + + memcpy(adv_data, data, len); } static void @@ -603,6 +614,7 @@ device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, const uint8_t *data, uint8_t len) { struct btp_gap_device_found_ev *ev; + void *adv_data; ble_addr_t a; /* if General/Limited Discovery - parse Advertising data to get flags */ @@ -649,7 +661,12 @@ device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, ev->eir_data_len += len; ev->flags |= BTP_GAP_DEVICE_FOUND_FLAG_SD; - memcpy(net_buf_simple_add(adv_buf, len), data, len); + adv_data = os_mbuf_extend(adv_buf, len); + if (!adv_data) { + return; + } + + memcpy(adv_data, data, len); goto done; } @@ -712,7 +729,7 @@ start_discovery(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } - net_buf_simple_init(adv_buf, 0); + tester_mbuf_reset(adv_buf); discovery_flags = cp->flags; return BTP_STATUS_SUCCESS; @@ -910,7 +927,7 @@ auth_passkey_display(uint16_t conn_handle, unsigned int passkey) memcpy(ev.address, addr->val, sizeof(ev.address)); ev.address_type = addr->type; - ev.passkey = sys_cpu_to_le32(pk.passkey); + ev.passkey = htole32(pk.passkey); tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_DISPLAY, (uint8_t *) &ev, sizeof(ev)); @@ -959,7 +976,7 @@ auth_passkey_numcmp(uint16_t conn_handle, unsigned int passkey) memcpy(ev.address, addr->val, sizeof(ev.address)); ev.address_type = addr->type; - ev.passkey = sys_cpu_to_le32(passkey); + ev.passkey = htole32(passkey); tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_CONFIRM_REQ, (uint8_t *) &ev, sizeof(ev)); @@ -1206,7 +1223,7 @@ adv_complete(void) struct btp_gap_new_settings_ev ev; current_settings &= ~BIT(BTP_GAP_SETTINGS_ADVERTISING); - ev.current_settings = sys_cpu_to_le32(current_settings); + ev.current_settings = htole32(current_settings); tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_NEW_SETTINGS, (uint8_t *) &ev, sizeof(ev)); @@ -1525,7 +1542,7 @@ passkey_entry(const void *cmd, uint16_t cmd_len, } pk.action = BLE_SM_IOACT_INPUT; - pk.passkey = sys_le32_to_cpu(cp->passkey); + pk.passkey = le32toh(cp->passkey); rc = ble_sm_inject_io(desc.conn_handle, &pk); if (rc) { @@ -1587,7 +1604,7 @@ start_direct_adv(const void *cmd, uint16_t cmd_len, } current_settings |= BIT(BTP_GAP_SETTINGS_ADVERTISING); - rp->current_settings = sys_cpu_to_le32(current_settings); + rp->current_settings = htole32(current_settings); *rsp_len = sizeof(*rp); @@ -1920,7 +1937,8 @@ tester_init_gap(void) os_callout_init(&bttester_nrpa_rotate_timer, os_eventq_dflt_get(), rotate_nrpa_cb, NULL); #endif - adv_buf = NET_BUF_SIMPLE(ADV_BUF_LEN); + adv_buf = os_msys_get(ADV_BUF_LEN, 0); + assert(adv_buf); tester_init_gap_cb(); diff --git a/apps/bttester/src/btp_gatt.c b/apps/bttester/src/btp_gatt.c index 5d62a677ad..ef6a805b75 100644 --- a/apps/bttester/src/btp_gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -260,11 +260,13 @@ attr_value_changed_ev(uint16_t handle, struct os_mbuf *data) SYS_LOG_DBG(""); - net_buf_simple_init(buf, 0); - ev = net_buf_simple_add(buf, sizeof(*ev)); + ev = os_mbuf_extend(buf, sizeof(*ev)); + if (!ev) { + return; + } - ev->handle = sys_cpu_to_le16(handle); - ev->data_length = sys_cpu_to_le16(os_mbuf_len(data)); + ev->handle = htole16(handle); + ev->data_length = htole16(os_mbuf_len(data)); os_mbuf_appendfrom(buf, data, 0, os_mbuf_len(data)); tester_send_buf(BTP_SERVICE_ID_GATT, BTP_GATT_EV_ATTR_VALUE_CHANGED, @@ -598,7 +600,7 @@ btp2bt_uuid(const uint8_t *uuid, uint8_t len, case 0x02: /* UUID 16 */ bt_uuid->u.type = BLE_UUID_TYPE_16; memcpy(&le16, uuid, sizeof(le16)); - BLE_UUID16(bt_uuid)->value = sys_le16_to_cpu(le16); + BLE_UUID16(bt_uuid)->value = le16toh(le16); break; case 0x10: /* UUID 128*/ bt_uuid->u.type = BLE_UUID_TYPE_128; @@ -721,7 +723,7 @@ read(uint8_t *data, uint16_t len) goto fail; } - if (ble_gattc_read(conn.conn_handle, sys_le16_to_cpu(cmd->handle), + if (ble_gattc_read(conn.conn_handle, le16toh(cmd->handle), read_cb, (void *) BTP_GATT_READ)) { read_destroy(); goto fail; @@ -793,8 +795,8 @@ read_long(uint8_t *data, uint16_t len) } if (ble_gattc_read_long(conn.conn_handle, - sys_le16_to_cpu(cmd->handle), - sys_le16_to_cpu(cmd->offset), + le16toh(cmd->handle), + le16toh(cmd->offset), read_long_cb, (void *) BTP_GATT_READ_LONG)) { read_destroy(); goto fail; @@ -817,7 +819,7 @@ read_multiple(uint8_t *data, uint16_t len) SYS_LOG_DBG(""); for (i = 0; i < ARRAY_SIZE(handles); i++) { - handles[i] = sys_le16_to_cpu(cmd->handles[i]); + handles[i] = le16toh(cmd->handles[i]); } rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); @@ -862,8 +864,8 @@ write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) } if (ble_gattc_write_no_rsp_flat(conn.conn_handle, - sys_le16_to_cpu(cmd->handle), cmd->data, - sys_le16_to_cpu(cmd->data_length))) { + le16toh(cmd->handle), cmd->data, + le16toh(cmd->data_length))) { status = BTP_STATUS_FAILED; } @@ -900,8 +902,8 @@ write(uint8_t *data, uint16_t len) goto fail; } - if (ble_gattc_write_flat(conn.conn_handle, sys_le16_to_cpu(cmd->handle), - cmd->data, sys_le16_to_cpu(cmd->data_length), + if (ble_gattc_write_flat(conn.conn_handle, le16toh(cmd->handle), + cmd->data, le16toh(cmd->data_length), write_rsp, (void *) BTP_GATT_WRITE)) { goto fail; } @@ -927,15 +929,15 @@ write_long(uint8_t *data, uint16_t len) goto fail; } - om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); + om = ble_hs_mbuf_from_flat(cmd->data, le16toh(cmd->data_length)); if (!om) { SYS_LOG_ERR("Insufficient resources"); goto fail; } rc = ble_gattc_write_long(conn.conn_handle, - sys_le16_to_cpu(cmd->handle), - sys_le16_to_cpu(cmd->offset), + le16toh(cmd->handle), + le16toh(cmd->offset), om, write_rsp, (void *) BTP_GATT_WRITE_LONG); if (!rc) { @@ -980,16 +982,16 @@ reliable_write(uint8_t *data, uint16_t len) goto fail; } - om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); + om = ble_hs_mbuf_from_flat(cmd->data, le16toh(cmd->data_length)); /* This is required, because Nimble checks if * the data is longer than offset */ - if (os_mbuf_extend(om, sys_le16_to_cpu(cmd->offset) + 1) == NULL) { + if (os_mbuf_extend(om, le16toh(cmd->offset) + 1) == NULL) { goto fail; } - attr.handle = sys_le16_to_cpu(cmd->handle); - attr.offset = sys_le16_to_cpu(cmd->offset); + attr.handle = le16toh(cmd->handle); + attr.offset = le16toh(cmd->offset); attr.om = om; if (ble_gattc_write_reliable(conn.conn_handle, &attr, 1, @@ -1038,8 +1040,8 @@ read_uuid(uint8_t *data, uint16_t len) } if (ble_gattc_read_by_uuid(conn.conn_handle, - sys_le16_to_cpu(cmd->start_handle), - sys_le16_to_cpu(cmd->end_handle), &uuid.u, + le16toh(cmd->start_handle), + le16toh(cmd->end_handle), &uuid.u, read_long_cb, (void *) BTP_GATT_READ_UUID)) { read_destroy(); goto fail; @@ -1088,12 +1090,12 @@ disc_prim_uuid_cb(uint16_t conn_handle, return BLE_HS_ENOMEM; } - service->start_handle = sys_cpu_to_le16(gatt_svc->start_handle); - service->end_handle = sys_cpu_to_le16(gatt_svc->end_handle); + service->start_handle = htole16(gatt_svc->start_handle); + service->end_handle = htole16(gatt_svc->end_handle); service->uuid_length = uuid_length; if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + uint16_t u16 = htole16(BLE_UUID16(uuid)->value); memcpy(service->uuid, &u16, uuid_length); } else { memcpy(service->uuid, BLE_UUID128(uuid)->value, @@ -1144,11 +1146,11 @@ disc_all_desc_cb(uint16_t conn_handle, return BLE_HS_ENOMEM; } - dsc->descriptor_handle = sys_cpu_to_le16(gatt_dsc->handle); + dsc->descriptor_handle = htole16(gatt_dsc->handle); dsc->uuid_length = uuid_length; if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + uint16_t u16 = htole16(BLE_UUID16(uuid)->value); memcpy(dsc->uuid, &u16, uuid_length); } else { memcpy(dsc->uuid, BLE_UUID128(uuid)->value, uuid_length); @@ -1208,8 +1210,8 @@ disc_all_desc(uint8_t *data, uint16_t len) goto fail; } - start_handle = sys_le16_to_cpu(cmd->start_handle) - 1; - end_handle = sys_le16_to_cpu(cmd->end_handle); + start_handle = le16toh(cmd->start_handle) - 1; + end_handle = le16toh(cmd->end_handle); rc = ble_gattc_disc_all_dscs(conn.conn_handle, start_handle, end_handle, disc_all_desc_cb, NULL); @@ -1266,14 +1268,14 @@ find_included_cb(uint16_t conn_handle, } /* FIXME */ - included->included_handle = sys_cpu_to_le16(service_handle + 1 + + included->included_handle = htole16(service_handle + 1 + rp->services_count); - included->service.start_handle = sys_cpu_to_le16(gatt_svc->start_handle); - included->service.end_handle = sys_cpu_to_le16(gatt_svc->end_handle); + included->service.start_handle = htole16(gatt_svc->start_handle); + included->service.end_handle = htole16(gatt_svc->end_handle); included->service.uuid_length = uuid_length; if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + uint16_t u16 = htole16(BLE_UUID16(uuid)->value); memcpy(included->service.uuid, &u16, uuid_length); } else { memcpy(included->service.uuid, BLE_UUID128(uuid)->value, @@ -1323,13 +1325,13 @@ disc_chrc_cb(uint16_t conn_handle, return BLE_HS_ENOMEM; } - chrc->characteristic_handle = sys_cpu_to_le16(gatt_chr->def_handle); + chrc->characteristic_handle = htole16(gatt_chr->def_handle); chrc->properties = gatt_chr->properties; - chrc->value_handle = sys_cpu_to_le16(gatt_chr->val_handle); + chrc->value_handle = htole16(gatt_chr->val_handle); chrc->uuid_length = uuid_length; if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + uint16_t u16 = htole16(BLE_UUID16(uuid)->value); memcpy(chrc->uuid, &u16, uuid_length); } else { memcpy(chrc->uuid, BLE_UUID128(uuid)->value, @@ -1365,8 +1367,8 @@ disc_chrc_uuid(uint8_t *data, uint16_t len) goto fail; } - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); + start_handle = le16toh(cmd->start_handle); + end_handle = le16toh(cmd->end_handle); if (ble_gattc_disc_chrs_by_uuid(conn.conn_handle, start_handle, end_handle, &uuid.u, disc_chrc_cb, @@ -1440,8 +1442,8 @@ disc_all_chrc(uint8_t *data, uint16_t len) goto fail; } - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); + start_handle = le16toh(cmd->start_handle); + end_handle = le16toh(cmd->end_handle); rc = ble_gattc_disc_all_chrs(conn.conn_handle, start_handle, end_handle, disc_chrc_cb, (void *) BTP_GATT_DISC_ALL_CHRC); @@ -1476,8 +1478,8 @@ find_included(uint8_t *data, uint16_t len) goto fail; } - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); + start_handle = le16toh(cmd->start_handle); + end_handle = le16toh(cmd->end_handle); service_handle_arg = start_handle; if (ble_gattc_find_inc_svcs(conn.conn_handle, start_handle, end_handle, @@ -1583,7 +1585,7 @@ config_subscription(uint8_t *data, uint16_t len, uint8_t op) { const struct btp_gatt_cfg_notify_cmd *cmd = (void *) data; struct ble_gap_conn_desc conn; - uint16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle); + uint16_t ccc_handle = le16toh(cmd->ccc_handle); uint8_t status; int rc; @@ -1677,8 +1679,8 @@ get_attrs(uint8_t *data, uint16_t len) memset(str, 0, sizeof(str)); memset(&uuid, 0, sizeof(uuid)); - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); + start_handle = le16toh(cmd->start_handle); + end_handle = le16toh(cmd->end_handle); if (cmd->type_length) { if (btp2bt_uuid(cmd->type, cmd->type_length, &uuid)) { @@ -1694,8 +1696,10 @@ get_attrs(uint8_t *data, uint16_t len) SYS_LOG_DBG("start 0x%04x end 0x%04x", start_handle, end_handle); } - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + rp = os_mbuf_extend(buf, sizeof(*rp)); + if (!rp) { + goto fail; + } entry = ble_att_svr_find_by_uuid(entry, uuid_ptr, end_handle); while (entry) { @@ -1706,19 +1710,23 @@ get_attrs(uint8_t *data, uint16_t len) continue; } - gatt_attr = net_buf_simple_add(buf, sizeof(*gatt_attr)); - gatt_attr->handle = sys_cpu_to_le16(entry->ha_handle_id); + gatt_attr = os_mbuf_extend(buf, sizeof(*gatt_attr)); + if (!gatt_attr) { + goto fail; + } + gatt_attr->handle = htole16(entry->ha_handle_id); gatt_attr->permission = flags_hs2btp(entry->ha_flags); if (entry->ha_uuid->type == BLE_UUID_TYPE_16) { + uint16_t uuid_val; + gatt_attr->type_length = 2; - net_buf_simple_add_le16(buf, - BLE_UUID16(entry->ha_uuid)->value); + uuid_val = htole16(BLE_UUID16(entry->ha_uuid)->value); + os_mbuf_append(buf, &uuid_val, sizeof(uuid_val)); } else { gatt_attr->type_length = 16; - net_buf_simple_add_mem(buf, - BLE_UUID128(entry->ha_uuid)->value, - gatt_attr->type_length); + os_mbuf_append(buf, BLE_UUID128(entry->ha_uuid)->value, + gatt_attr->type_length); } count++; @@ -1746,15 +1754,17 @@ get_attr_val(uint8_t *data, uint16_t len) struct btp_gatt_get_attribute_value_rp *rp; struct ble_gap_conn_desc conn; struct os_mbuf *buf = os_msys_get(0, 0); - uint16_t handle = sys_cpu_to_le16(cmd->handle); + uint16_t handle = le16toh(cmd->handle); uint8_t out_att_err = 0; int conn_status; conn_status = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); if (conn_status) { - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + rp = os_mbuf_extend(buf, sizeof(*rp)); + if (!rp) { + goto free; + } ble_att_svr_read_handle(BLE_HS_CONN_HANDLE_NONE, handle, 0, buf, @@ -1768,8 +1778,10 @@ get_attr_val(uint8_t *data, uint16_t len) goto free; } else { - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + rp = os_mbuf_extend(buf, sizeof(*rp)); + if (!rp) { + goto free; + } ble_att_svr_read_handle(conn.conn_handle, handle, 0, buf, @@ -1951,16 +1963,17 @@ tester_gatt_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, goto fail; } - net_buf_simple_init(buf, 0); - ev = net_buf_simple_add(buf, sizeof(*ev)); + ev = os_mbuf_extend(buf, sizeof(*ev)); + if (!ev) { + goto fail; + } addr = &conn.peer_ota_addr; - ev->address_type = addr->type; - memcpy(ev->address, addr->val, sizeof(ev->address)); + memcpy(&ev->address, addr, sizeof(ev->address)); ev->type = (uint8_t) (indication ? 0x02 : 0x01); - ev->handle = sys_cpu_to_le16(attr_handle); - ev->data_length = sys_cpu_to_le16(os_mbuf_len(om)); + ev->handle = htole16(attr_handle); + ev->data_length = htole16(os_mbuf_len(om)); os_mbuf_appendfrom(buf, om, 0, os_mbuf_len(om)); tester_send_buf(BTP_SERVICE_ID_GATT, BTP_GATT_EV_NOTIFICATION, diff --git a/apps/bttester/src/btp_gatt_cl.c b/apps/bttester/src/btp_gatt_cl.c index f734c9c4e4..3f7a09f2f8 100644 --- a/apps/bttester/src/btp_gatt_cl.c +++ b/apps/bttester/src/btp_gatt_cl.c @@ -44,7 +44,7 @@ btp2bt_uuid(const uint8_t *uuid, uint8_t len, case 0x02: /* UUID 16 */ bt_uuid->u.type = BLE_UUID_TYPE_16; memcpy(&le16, uuid, sizeof(le16)); - BLE_UUID16(bt_uuid)->value = sys_le16_to_cpu(le16); + BLE_UUID16(bt_uuid)->value = le16toh(le16); break; case 0x10: /* UUID 128*/ bt_uuid->u.type = BLE_UUID_TYPE_128; @@ -134,8 +134,10 @@ tester_mtu_exchanged_ev(uint16_t conn_handle, goto fail; } - net_buf_simple_init(buf, 0); - ev = net_buf_simple_add(buf, sizeof(*ev)); + ev = os_mbuf_extend(buf, sizeof(*ev)); + if (!ev) { + return 0; + } addr = &conn.peer_ota_addr; @@ -200,8 +202,11 @@ disc_prim_svcs_cb(uint16_t conn_handle, goto free; } - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + rp = os_mbuf_extend(buf, sizeof(*rp)); + if (!rp) { + rc = BLE_HS_ENOMEM; + goto free; + } addr = &conn.peer_ota_addr; @@ -237,12 +242,12 @@ disc_prim_svcs_cb(uint16_t conn_handle, goto free; } - service->start_handle = sys_cpu_to_le16(gatt_svc->start_handle); - service->end_handle = sys_cpu_to_le16(gatt_svc->end_handle); + service->start_handle = htole16(gatt_svc->start_handle); + service->end_handle = htole16(gatt_svc->end_handle); service->uuid_length = uuid_length; if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + uint16_t u16 = htole16(BLE_UUID16(uuid)->value); memcpy(service->uuid, &u16, uuid_length); } else { memcpy(service->uuid, BLE_UUID128(uuid)->value, @@ -340,8 +345,11 @@ find_included_cb(uint16_t conn_handle, goto free; } - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + rp = os_mbuf_extend(buf, sizeof(*rp)); + if (!rp) { + rc = BLE_HS_ENOMEM; + goto free; + } addr = &conn.peer_ota_addr; @@ -379,14 +387,14 @@ find_included_cb(uint16_t conn_handle, goto free; } - included->included_handle = sys_cpu_to_le16(service_handle + 1 + + included->included_handle = htole16(service_handle + 1 + rp->services_count); - included->service.start_handle = sys_cpu_to_le16(gatt_svc->start_handle); - included->service.end_handle = sys_cpu_to_le16(gatt_svc->end_handle); + included->service.start_handle = htole16(gatt_svc->start_handle); + included->service.end_handle = htole16(gatt_svc->end_handle); included->service.uuid_length = uuid_length; if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + uint16_t u16 = htole16(BLE_UUID16(uuid)->value); memcpy(included->service.uuid, &u16, uuid_length); } else { memcpy(included->service.uuid, BLE_UUID128(uuid)->value, @@ -418,8 +426,8 @@ find_included(uint8_t *data, uint16_t len) goto rsp; } - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); + start_handle = le16toh(cmd->start_handle); + end_handle = le16toh(cmd->end_handle); service_handle_arg = start_handle; if (ble_gattc_find_inc_svcs(conn.conn_handle, start_handle, end_handle, @@ -455,8 +463,11 @@ disc_chrc_cb(uint16_t conn_handle, goto free; } - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + rp = os_mbuf_extend(buf, sizeof(*rp)); + if (!rp) { + rc = BLE_HS_ENOMEM; + goto free; + } addr = &conn.peer_ota_addr; @@ -498,13 +509,13 @@ disc_chrc_cb(uint16_t conn_handle, goto free; } - chrc->characteristic_handle = sys_cpu_to_le16(gatt_chr->def_handle); + chrc->characteristic_handle = htole16(gatt_chr->def_handle); chrc->properties = gatt_chr->properties; - chrc->value_handle = sys_cpu_to_le16(gatt_chr->val_handle); + chrc->value_handle = htole16(gatt_chr->val_handle); chrc->uuid_length = uuid_length; if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + uint16_t u16 = htole16(BLE_UUID16(uuid)->value); memcpy(chrc->uuid, &u16, uuid_length); } else { memcpy(chrc->uuid, BLE_UUID128(uuid)->value, @@ -535,8 +546,8 @@ disc_all_chrc(uint8_t *data, uint16_t len) goto rsp; } - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); + start_handle = le16toh(cmd->start_handle); + end_handle = le16toh(cmd->end_handle); rc = ble_gattc_disc_all_chrs(conn.conn_handle, start_handle, @@ -576,8 +587,8 @@ disc_chrc_uuid(uint8_t *data, uint16_t len) goto rsp; } - start_handle = sys_le16_to_cpu(cmd->start_handle); - end_handle = sys_le16_to_cpu(cmd->end_handle); + start_handle = le16toh(cmd->start_handle); + end_handle = le16toh(cmd->end_handle); rc = ble_gattc_disc_chrs_by_uuid(conn.conn_handle, start_handle, end_handle, &uuid.u, disc_chrc_cb, @@ -616,8 +627,11 @@ disc_all_desc_cb(uint16_t conn_handle, goto free; } - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + rp = os_mbuf_extend(buf, sizeof(*rp)); + if (!rp) { + rc = BLE_HS_ENOMEM; + goto free; + } addr = &conn.peer_ota_addr; @@ -654,11 +668,11 @@ disc_all_desc_cb(uint16_t conn_handle, goto free; } - dsc->descriptor_handle = sys_cpu_to_le16(gatt_dsc->handle); + dsc->descriptor_handle = htole16(gatt_dsc->handle); dsc->uuid_length = uuid_length; if (uuid->u.type == BLE_UUID_TYPE_16) { - uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value); + uint16_t u16 = htole16(BLE_UUID16(uuid)->value); memcpy(dsc->uuid, &u16, uuid_length); } else { memcpy(dsc->uuid, BLE_UUID128(uuid)->value, uuid_length); @@ -688,8 +702,8 @@ disc_all_desc(uint8_t *data, uint16_t len) goto rsp; } - start_handle = sys_le16_to_cpu(cmd->start_handle) - 1; - end_handle = sys_le16_to_cpu(cmd->end_handle); + start_handle = le16toh(cmd->start_handle) - 1; + end_handle = le16toh(cmd->end_handle); rc = ble_gattc_disc_all_dscs(conn.conn_handle, start_handle, @@ -727,8 +741,11 @@ read_cb(uint16_t conn_handle, goto free; } - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + rp = os_mbuf_extend(buf, sizeof(*rp)); + if (!rp) { + rc = BLE_HS_ENOMEM; + goto free; + } addr = &conn.peer_ota_addr; @@ -782,7 +799,7 @@ read(uint8_t *data, uint16_t len) /* Clear buffer */ read_destroy(); - if (ble_gattc_read(conn.conn_handle, sys_le16_to_cpu(cmd->handle), + if (ble_gattc_read(conn.conn_handle, le16toh(cmd->handle), read_cb, (void *) BTP_GATTC_READ_RP)) { read_destroy(); status = BTP_STATUS_FAILED; @@ -816,8 +833,11 @@ read_uuid_cb(uint16_t conn_handle, goto free; } - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + rp = os_mbuf_extend(buf, sizeof(*rp)); + if (!rp) { + rc = BLE_HS_ENOMEM; + goto free; + } addr = &conn.peer_ota_addr; @@ -857,7 +877,7 @@ read_uuid_cb(uint16_t conn_handle, goto free; } - chr->handle = sys_cpu_to_be16(attr->handle); + chr->handle = htobe16(attr->handle); memcpy(chr->data, attr->om->om_data, attr->om->om_len); free: @@ -891,8 +911,8 @@ read_uuid(uint8_t *data, uint16_t len) read_destroy(); if (ble_gattc_read_by_uuid(conn.conn_handle, - sys_le16_to_cpu(cmd->start_handle), - sys_le16_to_cpu(cmd->end_handle), &uuid.u, + le16toh(cmd->start_handle), + le16toh(cmd->end_handle), &uuid.u, read_uuid_cb, (void *) BTP_GATTC_READ_UUID_RP)) { read_destroy(); status = BTP_STATUS_FAILED; @@ -923,8 +943,11 @@ read_long_cb(uint16_t conn_handle, goto free; } - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + rp = os_mbuf_extend(buf, sizeof(*rp)); + if (!rp) { + rc = BLE_HS_ENOMEM; + goto free; + } addr = &conn.peer_ota_addr; @@ -984,8 +1007,8 @@ read_long(uint8_t *data, uint16_t len) read_destroy(); if (ble_gattc_read_long(conn.conn_handle, - sys_le16_to_cpu(cmd->handle), - sys_le16_to_cpu(cmd->offset), + le16toh(cmd->handle), + le16toh(cmd->offset), read_long_cb, (void *) BTP_GATTC_READ_LONG_RP)) { read_destroy(); status = BTP_STATUS_FAILED; @@ -1007,7 +1030,7 @@ read_multiple(uint8_t *data, uint16_t len) SYS_LOG_DBG(""); for (i = 0; i < ARRAY_SIZE(handles); i++) { - handles[i] = sys_le16_to_cpu(cmd->handles[i]); + handles[i] = le16toh(cmd->handles[i]); } rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); @@ -1049,8 +1072,8 @@ write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) } if (ble_gattc_write_no_rsp_flat(conn.conn_handle, - sys_le16_to_cpu(cmd->handle), cmd->data, - sys_le16_to_cpu(cmd->data_length))) { + le16toh(cmd->handle), cmd->data, + le16toh(cmd->data_length))) { status = BTP_STATUS_FAILED; } @@ -1078,8 +1101,11 @@ write_cb(uint16_t conn_handle, const struct ble_gatt_error *error, goto free; } - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + rp = os_mbuf_extend(buf, sizeof(*rp)); + if (!rp) { + rc = BLE_HS_ENOMEM; + goto free; + } addr = &conn.peer_ota_addr; @@ -1110,8 +1136,8 @@ write(uint8_t *data, uint16_t len) goto rsp; } - if (ble_gattc_write_flat(conn.conn_handle, sys_le16_to_cpu(cmd->handle), - cmd->data, sys_le16_to_cpu(cmd->data_length), + if (ble_gattc_write_flat(conn.conn_handle, le16toh(cmd->handle), + cmd->data, le16toh(cmd->data_length), write_cb, (void *) BTP_GATTC_WRITE_RP)) { status = BTP_STATUS_FAILED; } @@ -1136,7 +1162,7 @@ write_long(uint8_t *data, uint16_t len) goto fail; } - om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); + om = ble_hs_mbuf_from_flat(cmd->data, le16toh(cmd->data_length)); if (!om) { SYS_LOG_ERR("Insufficient resources"); status = BTP_STATUS_FAILED; @@ -1144,8 +1170,8 @@ write_long(uint8_t *data, uint16_t len) } rc = ble_gattc_write_long(conn.conn_handle, - sys_le16_to_cpu(cmd->handle), - sys_le16_to_cpu(cmd->offset), + le16toh(cmd->handle), + le16toh(cmd->offset), om, write_cb, (void *) BTP_GATTC_WRITE_LONG_RP); if (rc) { @@ -1182,8 +1208,11 @@ reliable_write_cb(uint16_t conn_handle, goto free; } - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + rp = os_mbuf_extend(buf, sizeof(*rp)); + if (!rp) { + rc = BLE_HS_ENOMEM; + goto free; + } addr = &conn.peer_ota_addr; @@ -1216,17 +1245,17 @@ reliable_write(uint8_t *data, uint16_t len) goto fail; } - om = ble_hs_mbuf_from_flat(cmd->data, sys_le16_to_cpu(cmd->data_length)); + om = ble_hs_mbuf_from_flat(cmd->data, le16toh(cmd->data_length)); /* This is required, because Nimble checks if * the data is longer than offset */ - if (os_mbuf_extend(om, sys_le16_to_cpu(cmd->offset) + 1) == NULL) { + if (os_mbuf_extend(om, le16toh(cmd->offset) + 1) == NULL) { status = BTP_STATUS_FAILED; goto fail; } - attr.handle = sys_le16_to_cpu(cmd->handle); - attr.offset = sys_le16_to_cpu(cmd->offset); + attr.handle = le16toh(cmd->handle); + attr.offset = le16toh(cmd->offset); attr.om = om; if (ble_gattc_write_reliable(conn.conn_handle, &attr, 1, @@ -1264,8 +1293,11 @@ subscribe_cb(uint16_t conn_handle, goto free; } - net_buf_simple_init(buf, 0); - rp = net_buf_simple_add(buf, sizeof(*rp)); + rp = os_mbuf_extend(buf, sizeof(*rp)); + if (!rp) { + rc = BLE_HS_ENOMEM; + goto free; + } addr = &conn.peer_ota_addr; @@ -1340,7 +1372,7 @@ config_subscription(uint8_t *data, uint16_t len, uint8_t op) { const struct btp_gattc_cfg_notify_cmd *cmd = (void *) data; struct ble_gap_conn_desc conn; - uint16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle); + uint16_t ccc_handle = le16toh(cmd->ccc_handle); uint8_t status = BTP_STATUS_SUCCESS; int rc; @@ -1399,16 +1431,18 @@ tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, goto fail; } - net_buf_simple_init(buf, 0); - ev = net_buf_simple_add(buf, sizeof(*ev)); + ev = os_mbuf_extend(buf, sizeof(*ev)); + if (!ev) { + return 0; + } addr = &conn.peer_ota_addr; ev->address_type = addr->type; memcpy(ev->address, addr->val, sizeof(ev->address)); ev->type = (uint8_t) (indication ? 0x02 : 0x01); - ev->handle = sys_cpu_to_le16(attr_handle); - ev->data_length = sys_cpu_to_le16(os_mbuf_len(om)); + ev->handle = htole16(attr_handle); + ev->data_length = htole16(os_mbuf_len(om)); os_mbuf_appendfrom(buf, om, 0, os_mbuf_len(om)); tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_EV_NOTIFICATION_RXED, diff --git a/apps/bttester/src/btp_l2cap.c b/apps/bttester/src/btp_l2cap.c index 03d70688a2..498d22604b 100644 --- a/apps/bttester/src/btp_l2cap.c +++ b/apps/bttester/src/btp_l2cap.c @@ -421,7 +421,7 @@ connect(uint8_t *data, uint16_t len) SYS_LOG_DBG("connect: type: %d addr: %s", addr->type, - bt_hex(addr->val, 6)); + string_from_bytes(addr->val, 6)); if (mtu == 0 || mtu > TESTER_COC_MTU) { mtu = TESTER_COC_MTU; @@ -523,7 +523,7 @@ send_data(const uint8_t *data, uint16_t len) const struct btp_l2cap_send_data_cmd *cmd = (void *) data; struct os_mbuf *sdu_tx = NULL; int rc; - uint16_t data_len = sys_le16_to_cpu(cmd->data_len); + uint16_t data_len = le16toh(cmd->data_len); struct channel *chan = get_channel(cmd->chan_id); SYS_LOG_DBG("cmd->chan_id=%d", cmd->chan_id); @@ -567,7 +567,7 @@ static void listen(const uint8_t *data, uint16_t len) { const struct btp_l2cap_listen_cmd *cmd = (void *) data; - uint16_t mtu = htole16(cmd->mtu); + uint16_t mtu = htole16(cmd->mtu); int rc; SYS_LOG_DBG(""); @@ -625,7 +625,7 @@ static void reconfigure(const uint8_t *data, uint16_t len) { const struct btp_l2cap_reconfigure_cmd *cmd = (void *) data; - uint16_t mtu = htole16(cmd->mtu); + uint16_t mtu = htole16(cmd->mtu); struct ble_gap_conn_desc desc; ble_addr_t *addr = (void *) data; struct ble_l2cap_chan *chans[cmd->num]; diff --git a/apps/bttester/src/btp_mesh.c b/apps/bttester/src/btp_mesh.c index 3e0668ea74..7642f8ea7f 100644 --- a/apps/bttester/src/btp_mesh.c +++ b/apps/bttester/src/btp_mesh.c @@ -318,8 +318,8 @@ output_number(bt_mesh_output_action_t action, uint32_t number) SYS_LOG_DBG("action 0x%04x number 0x%08lx", action, number); - ev.action = sys_cpu_to_le16(action); - ev.number = sys_cpu_to_le32(number); + ev.action = htole16(action); + ev.number = htole32(number); tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_OUT_NUMBER_ACTION, (uint8_t *) &ev, sizeof(ev)); @@ -358,7 +358,7 @@ input(bt_mesh_input_action_t action, uint8_t size) input_size = size; - ev.action = sys_cpu_to_le16(action); + ev.action = htole16(action); ev.size = size; tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_IN_ACTION, @@ -441,7 +441,7 @@ provision_node(uint8_t *data, uint16_t len) addr = sys_le16_to_cpu(cmd->addr); flags = cmd->flags; - iv_index = sys_le32_to_cpu(cmd->iv_index); + iv_index = le32toh(cmd->iv_index); net_key_idx = sys_le16_to_cpu(cmd->net_key_idx); tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_PROVISION_NODE, @@ -499,7 +499,7 @@ input_number(uint8_t *data, uint16_t len) uint32_t number; int err; - number = sys_le32_to_cpu(cmd->number); + number = le32toh(cmd->number); SYS_LOG_DBG("number 0x%04lx", number); @@ -896,8 +896,8 @@ net_recv_ev(uint8_t ttl, ev = net_buf_simple_add(buf, sizeof(*ev)); ev->ttl = ttl; ev->ctl = ctl; - ev->src = sys_cpu_to_le16(src); - ev->dst = sys_cpu_to_le16(dst); + ev->src = htole16(src); + ev->dst = htole16(dst); ev->payload_len = payload_len; net_buf_simple_add_mem(buf, payload, payload_len); diff --git a/apps/bttester/src/bttester.c b/apps/bttester/src/bttester.c index f0d0886302..7245bcb461 100644 --- a/apps/bttester/src/bttester.c +++ b/apps/bttester/src/bttester.c @@ -57,6 +57,14 @@ static struct { uint8_t num; } service_handler[BTP_SERVICE_ID_MAX + 1]; + +void +tester_mbuf_reset(struct os_mbuf *buf) +{ + buf->om_data = &buf->om_databuf[buf->om_pkthdr_len]; + buf->om_len = 0; +} + static void tester_send_with_index(uint8_t service, uint8_t opcode, uint8_t index, uint8_t *data, size_t len); @@ -69,13 +77,38 @@ tester_register_command_handlers(uint8_t service, const struct btp_handler *handlers, size_t num) { - __ASSERT_NO_MSG(service <= BTP_SERVICE_ID_MAX); - __ASSERT_NO_MSG(service_handler[service].handlers == NULL); + assert(service <= BTP_SERVICE_ID_MAX); + assert(service_handler[service].handlers == NULL); service_handler[service].handlers = handlers; service_handler[service].num = num; } +const char * +string_from_bytes(const void *buf, size_t len) +{ + static const char hex[] = "0123456789abcdef"; + static char hexbufs[4][137]; + static uint8_t curbuf; + const uint8_t *b = buf; + char *str; + int i; + + str = hexbufs[curbuf++]; + curbuf %= ARRAY_SIZE(hexbufs); + + len = min(len, (sizeof(hexbufs[0]) - 1) / 2); + + for (i = 0; i < len; i++) { + str[i * 2] = hex[b[i] >> 4]; + str[i * 2 + 1] = hex[b[i] & 0xf]; + } + + str[i * 2] = '\0'; + + return str; +} + static const struct btp_handler * find_btp_handler(uint8_t service, uint8_t opcode) { @@ -108,12 +141,12 @@ cmd_handler(struct os_event *ev) cmd = ev->ev_arg; - len = sys_le16_to_cpu(cmd->hdr.len); + len = le16toh(cmd->hdr.len); if (MYNEWT_VAL(BTTESTER_BTP_LOG)) { console_printf("[DBG] received %d bytes: %s\n", sizeof(cmd->hdr) + len, - bt_hex(cmd->data, - sizeof(cmd->hdr) + len)); + string_from_bytes(cmd->data, + sizeof(cmd->hdr) + len)); } btp = find_btp_handler(cmd->hdr.service, cmd->hdr.opcode); @@ -127,7 +160,7 @@ cmd_handler(struct os_event *ev) cmd->rsp, &rsp_len); } - __ASSERT_NO_MSG((rsp_len + sizeof(struct btp_hdr)) <= BTP_MTU); + assert((rsp_len + sizeof(struct btp_hdr)) <= BTP_MTU); } else { status = BTP_STATUS_UNKNOWN_CMD; } @@ -157,7 +190,7 @@ recv_cb(uint8_t *buf, size_t *off) return buf; } - len = sys_le16_to_cpu(cmd->len); + len = le16toh(cmd->len); if (len > BTP_MTU - sizeof(*cmd)) { *off = 0; return buf; @@ -239,7 +272,7 @@ tester_send_with_index(uint8_t service, uint8_t opcode, uint8_t index, msg.service = service; msg.opcode = opcode; msg.index = index; - msg.len = sys_cpu_to_le16(len); + msg.len = htole16(len); bttester_pipe_send((uint8_t *) &msg, sizeof(msg)); if (data && len) { @@ -248,10 +281,10 @@ tester_send_with_index(uint8_t service, uint8_t opcode, uint8_t index, if (MYNEWT_VAL(BTTESTER_BTP_LOG)) { console_printf("[DBG] send %d bytes hdr: %s\n", sizeof(msg), - bt_hex((char *) &msg, sizeof(msg))); + string_from_bytes((char *) &msg, sizeof(msg))); if (data && len) { console_printf("[DBG] send %d bytes data: %s\n", len, - bt_hex((char *) data, len)); + string_from_bytes((char *) data, len)); } } } diff --git a/apps/bttester/src/glue.c b/apps/bttester/src/glue.c deleted file mode 100644 index f4c838184b..0000000000 --- a/apps/bttester/src/glue.c +++ /dev/null @@ -1,129 +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. - */ - -#include "syscfg/syscfg.h" - -#if !MYNEWT_VAL(BLE_MESH) -#include -#include -#include "os/os.h" -#include "os/os_mbuf.h" -#include "glue.h" - - -#define ASSERT_NOT_CHAIN(om) assert(SLIST_NEXT(om, om_next) == NULL) - -const char *bt_hex(const void *buf, size_t len) -{ - static const char hex[] = "0123456789abcdef"; - static char hexbufs[4][137]; - static uint8_t curbuf; - const uint8_t *b = buf; - char *str; - int i; - - str = hexbufs[curbuf++]; - curbuf %= ARRAY_SIZE(hexbufs); - - len = min(len, (sizeof(hexbufs[0]) - 1) / 2); - - for (i = 0; i < len; i++) { - str[i * 2] = hex[b[i] >> 4]; - str[i * 2 + 1] = hex[b[i] & 0xf]; - } - - str[i * 2] = '\0'; - - return str; -} - -struct os_mbuf * NET_BUF_SIMPLE(uint16_t size) -{ - struct os_mbuf *buf; - - buf = os_msys_get(size, 0); - assert(buf); - - return buf; -} - -/* This is by purpose */ -void net_buf_simple_init(struct os_mbuf *buf, - size_t reserve_head) -{ - /* This is called in Zephyr after init. - * Note in Mynewt case we don't care abour reserved head*/ - buf->om_data = &buf->om_databuf[buf->om_pkthdr_len] + reserve_head; - buf->om_len = 0; -} - -void -net_buf_simple_add_le16(struct os_mbuf *om, uint16_t val) -{ - val = htole16(val); - os_mbuf_append(om, &val, sizeof(val)); - ASSERT_NOT_CHAIN(om); -} - -void -net_buf_simple_add_be16(struct os_mbuf *om, uint16_t val) -{ - val = htobe16(val); - os_mbuf_append(om, &val, sizeof(val)); - ASSERT_NOT_CHAIN(om); -} - -void -net_buf_simple_add_be32(struct os_mbuf *om, uint32_t val) -{ - val = htobe32(val); - os_mbuf_append(om, &val, sizeof(val)); - ASSERT_NOT_CHAIN(om); -} - -void -net_buf_simple_add_u8(struct os_mbuf *om, uint8_t val) -{ - os_mbuf_append(om, &val, 1); - ASSERT_NOT_CHAIN(om); -} - -void* -net_buf_simple_add(struct os_mbuf *om, uint8_t len) -{ - void * tmp; - - tmp = os_mbuf_extend(om, len); - ASSERT_NOT_CHAIN(om); - - return tmp; -} - -uint8_t * -net_buf_simple_push(struct os_mbuf *om, uint8_t len) -{ - uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len]; - - assert(headroom >= len); - om->om_data -= len; - om->om_len += len; - - return om->om_data; -} -#endif diff --git a/apps/bttester/src/glue.h b/apps/bttester/src/glue.h deleted file mode 100644 index 024f795643..0000000000 --- a/apps/bttester/src/glue.h +++ /dev/null @@ -1,89 +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 __GLUE_H__ -#define __GLUE_H__ - -#include "os/endian.h" - -#define uint8_t uint8_t -#define int8_t int8_t -#define uint16_t uint16_t -#define uint32_t uint32_t -#define int32_t int32_t - -#ifndef BIT -#define BIT(n) (1UL << (n)) -#endif - -#define __packed __attribute__((__packed__)) - -#define sys_le16_to_cpu le16toh - -struct bt_data { - uint8_t type; - uint8_t data_len; - const uint8_t *data; -}; - -#define BT_DATA(_type, _data, _data_len) \ - { \ - .type = (_type), \ - .data_len = (_data_len), \ - .data = (const uint8_t *)(_data), \ - } - -struct os_mbuf * -NET_BUF_SIMPLE(uint16_t size); -void -net_buf_simple_init(struct os_mbuf *buf, size_t reserve_head); -void -net_buf_simple_add_le16(struct os_mbuf *om, uint16_t val); -void -net_buf_simple_add_u8(struct os_mbuf *om, uint8_t val); -void * -net_buf_simple_add(struct os_mbuf *om, uint8_t len); -uint8_t * -net_buf_simple_push(struct os_mbuf *om, uint8_t len); - -#define net_buf_simple_add_mem(a, b, c) os_mbuf_append(a,b,c) - -const char * -bt_hex(const void *buf, size_t len); - -/** - * INTERNAL_HIDDEN @endcond - */ - -/** - * @brief Define an array of atomic variables. - * - * This macro defines an array of atomic variables containing at least - * @a num_bits bits. - * - * @note - * If used from file scope, the bits of the array are initialized to zero; - * if used from within a function, the bits are left uninitialized. - * - * @param name Name of array of atomic variables. - * @param num_bits Number of bits needed. - */ -#define ATOMIC_DEFINE(name, num_bits) \ - atomic_t name[1 + ((num_bits) - 1) / ATOMIC_BITS] -#endif /* __GLUE_H__ */ From d8789347942ae76759b009606c89820c8a171ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 10 Jul 2023 14:10:11 +0200 Subject: [PATCH 0756/1333] apps/bttester: drop atomic.h There is no need of porting extra atomic API in tester. --- apps/bttester/src/atomic.h | 417 ------------------------------- apps/bttester/src/btp/bttester.h | 8 + apps/bttester/src/btp_core.c | 13 +- 3 files changed, 14 insertions(+), 424 deletions(-) delete mode 100644 apps/bttester/src/atomic.h diff --git a/apps/bttester/src/atomic.h b/apps/bttester/src/atomic.h deleted file mode 100644 index 4376ad5bb7..0000000000 --- a/apps/bttester/src/atomic.h +++ /dev/null @@ -1,417 +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. - */ - -/* atomic operations */ - -/* - * Copyright (c) 1997-2015, Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __ATOMIC_H__ -#define __ATOMIC_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -typedef int atomic_t; -typedef atomic_t atomic_val_t; - -/** - * @defgroup atomic_apis Atomic Services APIs - * @ingroup kernel_apis - * @{ - */ - -/** - * @brief Atomic compare-and-set. - * - * This routine performs an atomic compare-and-set on @a target. If the current - * value of @a target equals @a old_value, @a target is set to @a new_value. - * If the current value of @a target does not equal @a old_value, @a target - * is left unchanged. - * - * @param target Address of atomic variable. - * @param old_value Original value to compare against. - * @param new_value New value to store. - * @return 1 if @a new_value is written, 0 otherwise. - */ -static inline int -atomic_cas(atomic_t *target, atomic_val_t old_value, - atomic_val_t new_value) -{ - return __atomic_compare_exchange_n(target, &old_value, new_value, - 0, __ATOMIC_SEQ_CST, - __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic addition. - * - * This routine performs an atomic addition on @a target. - * - * @param target Address of atomic variable. - * @param value Value to add. - * - * @return Previous value of @a target. - */ -static inline atomic_val_t -atomic_add(atomic_t *target, atomic_val_t value) -{ - return __atomic_fetch_add(target, value, __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic subtraction. - * - * This routine performs an atomic subtraction on @a target. - * - * @param target Address of atomic variable. - * @param value Value to subtract. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t -atomic_sub(atomic_t *target, atomic_val_t value) -{ - return __atomic_fetch_sub(target, value, __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic increment. - * - * This routine performs an atomic increment by 1 on @a target. - * - * @param target Address of atomic variable. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t -atomic_inc(atomic_t *target) -{ - return atomic_add(target, 1); -} - -/** - * - * @brief Atomic decrement. - * - * This routine performs an atomic decrement by 1 on @a target. - * - * @param target Address of atomic variable. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t -atomic_dec(atomic_t *target) -{ - return atomic_sub(target, 1); -} - -/** - * - * @brief Atomic get. - * - * This routine performs an atomic read on @a target. - * - * @param target Address of atomic variable. - * - * @return Value of @a target. - */ - -static inline atomic_val_t -atomic_get(const atomic_t *target) -{ - return __atomic_load_n(target, __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic get-and-set. - * - * This routine atomically sets @a target to @a value and returns - * the previous value of @a target. - * - * @param target Address of atomic variable. - * @param value Value to write to @a target. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t -atomic_set(atomic_t *target, atomic_val_t value) -{ - /* This builtin, as described by Intel, is not a traditional - * test-and-set operation, but rather an atomic exchange operation. It - * writes value into *ptr, and returns the previous contents of *ptr. - */ - return __atomic_exchange_n(target, value, __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic clear. - * - * This routine atomically sets @a target to zero and returns its previous - * value. (Hence, it is equivalent to atomic_set(target, 0).) - * - * @param target Address of atomic variable. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t -atomic_clear(atomic_t *target) -{ - return atomic_set(target, 0); -} - -/** - * - * @brief Atomic bitwise inclusive OR. - * - * This routine atomically sets @a target to the bitwise inclusive OR of - * @a target and @a value. - * - * @param target Address of atomic variable. - * @param value Value to OR. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t -atomic_or(atomic_t *target, atomic_val_t value) -{ - return __atomic_fetch_or(target, value, __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic bitwise exclusive OR (XOR). - * - * This routine atomically sets @a target to the bitwise exclusive OR (XOR) of - * @a target and @a value. - * - * @param target Address of atomic variable. - * @param value Value to XOR - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t -atomic_xor(atomic_t *target, atomic_val_t value) -{ - return __atomic_fetch_xor(target, value, __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic bitwise AND. - * - * This routine atomically sets @a target to the bitwise AND of @a target - * and @a value. - * - * @param target Address of atomic variable. - * @param value Value to AND. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t -atomic_and(atomic_t *target, atomic_val_t value) -{ - return __atomic_fetch_and(target, value, __ATOMIC_SEQ_CST); -} - -/** - * - * @brief Atomic bitwise NAND. - * - * This routine atomically sets @a target to the bitwise NAND of @a target - * and @a value. (This operation is equivalent to target = ~(target & value).) - * - * @param target Address of atomic variable. - * @param value Value to NAND. - * - * @return Previous value of @a target. - */ - -static inline atomic_val_t -atomic_nand(atomic_t *target, atomic_val_t value) -{ - return __atomic_fetch_nand(target, value, __ATOMIC_SEQ_CST); -} - -/** - * @brief Initialize an atomic variable. - * - * This macro can be used to initialize an atomic variable. For example, - * @code atomic_t my_var = ATOMIC_INIT(75); @endcode - * - * @param i Value to assign to atomic variable. - */ -#define ATOMIC_INIT(i) (i) - -/** - * @cond INTERNAL_HIDDEN - */ - -#define ATOMIC_BITS (sizeof(atomic_val_t) * 8) -#define ATOMIC_MASK(bit) (1 << ((bit) & (ATOMIC_BITS - 1))) -#define ATOMIC_ELEM(addr, bit) ((addr) + ((bit) / ATOMIC_BITS)) - -/** - * INTERNAL_HIDDEN @endcond - */ - -/** - * @brief Define an array of atomic variables. - * - * This macro defines an array of atomic variables containing at least - * @a num_bits bits. - * - * @note - * If used from file scope, the bits of the array are initialized to zero; - * if used from within a function, the bits are left uninitialized. - * - * @param name Name of array of atomic variables. - * @param num_bits Number of bits needed. - */ -#define ATOMIC_DEFINE(name, num_bits) \ - atomic_t name[1 + ((num_bits) - 1) / ATOMIC_BITS] - -/** - * @brief Atomically test a bit. - * - * This routine tests whether bit number @a bit of @a target is set or not. - * The target may be a single atomic variable or an array of them. - * - * @param target Address of atomic variable or array. - * @param bit Bit number (starting from 0). - * - * @return 1 if the bit was set, 0 if it wasn't. - */ -static inline int -atomic_test_bit(const atomic_t *target, int bit) -{ - atomic_val_t val = atomic_get(ATOMIC_ELEM(target, bit)); - - return (1 & (val >> (bit & (ATOMIC_BITS - 1)))); -} - -/** - * @brief Atomically test and clear a bit. - * - * Atomically clear bit number @a bit of @a target and return its old value. - * The target may be a single atomic variable or an array of them. - * - * @param target Address of atomic variable or array. - * @param bit Bit number (starting from 0). - * - * @return 1 if the bit was set, 0 if it wasn't. - */ -static inline int -atomic_test_and_clear_bit(atomic_t *target, int bit) -{ - atomic_val_t mask = ATOMIC_MASK(bit); - atomic_val_t old; - - old = atomic_and(ATOMIC_ELEM(target, bit), ~mask); - - return (old & mask) != 0; -} - -/** - * @brief Atomically set a bit. - * - * Atomically set bit number @a bit of @a target and return its old value. - * The target may be a single atomic variable or an array of them. - * - * @param target Address of atomic variable or array. - * @param bit Bit number (starting from 0). - * - * @return 1 if the bit was set, 0 if it wasn't. - */ -static inline int -atomic_test_and_set_bit(atomic_t *target, int bit) -{ - atomic_val_t mask = ATOMIC_MASK(bit); - atomic_val_t old; - - old = atomic_or(ATOMIC_ELEM(target, bit), mask); - - return (old & mask) != 0; -} - -/** - * @brief Atomically clear a bit. - * - * Atomically clear bit number @a bit of @a target. - * The target may be a single atomic variable or an array of them. - * - * @param target Address of atomic variable or array. - * @param bit Bit number (starting from 0). - * - * @return N/A - */ -static inline void -atomic_clear_bit(atomic_t *target, int bit) -{ - atomic_val_t mask = ATOMIC_MASK(bit); - - atomic_and(ATOMIC_ELEM(target, bit), ~mask); -} - -/** - * @brief Atomically set a bit. - * - * Atomically set bit number @a bit of @a target. - * The target may be a single atomic variable or an array of them. - * - * @param target Address of atomic variable or array. - * @param bit Bit number (starting from 0). - * - * @return N/A - */ -static inline void -atomic_set_bit(atomic_t *target, int bit) -{ - atomic_val_t mask = ATOMIC_MASK(bit); - - atomic_or(ATOMIC_ELEM(target, bit), mask); -} - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ATOMIC_H__ */ diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h index 3aed917796..ea24600c19 100644 --- a/apps/bttester/src/btp/bttester.h +++ b/apps/bttester/src/btp/bttester.h @@ -59,6 +59,14 @@ tester_test_bit(const uint8_t *addr, unsigned int bit) return *p & BIT(bit % 8); } +static inline void +tester_clear_bit(uint8_t *addr, unsigned int bit) +{ + uint8_t *p = addr + (bit / 8); + + *p &= ~BIT(bit % 8); +} + void tester_init(void); diff --git a/apps/bttester/src/btp_core.c b/apps/bttester/src/btp_core.c index 4aee11d347..fe1b8d4450 100644 --- a/apps/bttester/src/btp_core.c +++ b/apps/bttester/src/btp_core.c @@ -26,9 +26,8 @@ */ #include "btp/btp.h" -#include "atomic.h" -static ATOMIC_DEFINE(registered_services, BTP_SERVICE_ID_MAX); +static uint8_t registered_services[((BTP_SERVICE_ID_MAX - 1) / 8) + 1]; static uint8_t supported_commands(const void *cmd, uint16_t cmd_len, @@ -82,7 +81,7 @@ register_service(const void *cmd, uint16_t cmd_len, } /* already registered */ - if (atomic_test_bit(registered_services, cp->id)) { + if (tester_test_bit(registered_services, cp->id)) { return BTP_STATUS_FAILED; } @@ -109,7 +108,7 @@ register_service(const void *cmd, uint16_t cmd_len, } if (status == BTP_STATUS_SUCCESS) { - atomic_set_bit(registered_services, cp->id); + tester_set_bit(registered_services, cp->id); } return status; @@ -128,7 +127,7 @@ unregister_service(const void *cmd, uint16_t cmd_len, } /* not registered */ - if (!atomic_test_bit(registered_services, cp->id)) { + if (!tester_test_bit(registered_services, cp->id)) { return BTP_STATUS_FAILED; } @@ -155,7 +154,7 @@ unregister_service(const void *cmd, uint16_t cmd_len, } if (status == BTP_STATUS_SUCCESS) { - atomic_clear_bit(registered_services, cp->id); + tester_clear_bit(registered_services, cp->id); } return status; @@ -193,5 +192,5 @@ tester_init_core(void) { tester_register_command_handlers(BTP_SERVICE_ID_CORE, handlers, ARRAY_SIZE(handlers)); - atomic_set_bit(registered_services, BTP_SERVICE_ID_CORE); + tester_set_bit(registered_services, BTP_SERVICE_ID_CORE); } From acf9f156fedd975f0459001de73af78bdb43e67f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 11 Jul 2023 08:36:47 +0200 Subject: [PATCH 0757/1333] apps/bttester: use ble_addr_t whenever possible We should use ble_addr_t instead of pair {address_type, address} whenever possible, as suggested in 35c71a4dcd2ad859e66746088042c50b8a0add39 This simplifies code to single memcpy. --- apps/bttester/src/btp/btp_gap.h | 65 +++++++++----------------- apps/bttester/src/btp/btp_gatt.h | 54 +++++++-------------- apps/bttester/src/btp/btp_gattc.h | 78 +++++++++++-------------------- apps/bttester/src/btp/btp_l2cap.h | 15 ++---- apps/bttester/src/btp_gap.c | 55 +++++++++------------- apps/bttester/src/btp_gatt_cl.c | 72 +++++----------------------- apps/bttester/src/btp_l2cap.c | 8 +--- 7 files changed, 106 insertions(+), 241 deletions(-) diff --git a/apps/bttester/src/btp/btp_gap.h b/apps/bttester/src/btp/btp_gap.h index ca60b81037..5e3e1b8372 100644 --- a/apps/bttester/src/btp/btp_gap.h +++ b/apps/bttester/src/btp/btp_gap.h @@ -167,15 +167,13 @@ struct btp_gap_start_discovery_cmd { #define BTP_GAP_CONNECT 0x0e struct btp_gap_connect_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t own_addr_type; } __packed; #define BTP_GAP_DISCONNECT 0x0f struct btp_gap_disconnect_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; } __packed; #define BTP_GAP_IO_CAP_DISPLAY_ONLY 0 @@ -191,41 +189,35 @@ struct btp_gap_set_io_cap_cmd { #define BTP_GAP_PAIR 0x11 struct btp_gap_pair_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; } __packed; #define BTP_GAP_UNPAIR 0x12 struct btp_gap_unpair_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; } __packed; #define BTP_GAP_PASSKEY_ENTRY 0x13 struct btp_gap_passkey_entry_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint32_t passkey; } __packed; #define BTP_GAP_PASSKEY_CONFIRM 0x14 struct btp_gap_passkey_confirm_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t match; } __packed; #define BTP_GAP_START_DIRECT_ADV 0x15 struct btp_gap_start_direct_adv_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t high_duty; } __packed; #define BTP_GAP_CONN_PARAM_UPDATE 0x16 struct btp_gap_conn_param_update_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t conn_itvl_min; uint16_t conn_itvl_max; uint16_t conn_latency; @@ -234,8 +226,7 @@ struct btp_gap_conn_param_update_cmd { #define BTP_GAP_PAIRING_CONSENT_RSP 0x17 struct btp_gap_pairing_consent_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t consent; } __packed; @@ -278,8 +269,7 @@ struct btp_gap_new_settings_ev { #define BTP_GAP_EV_DEVICE_FOUND 0x81 struct btp_gap_device_found_ev { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; int8_t rssi; uint8_t flags; uint16_t eir_data_len; @@ -288,8 +278,7 @@ struct btp_gap_device_found_ev { #define BTP_GAP_EV_DEVICE_CONNECTED 0x82 struct btp_gap_device_connected_ev { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t conn_itvl; uint16_t conn_latency; uint16_t supervision_timeout; @@ -297,42 +286,36 @@ struct btp_gap_device_connected_ev { #define BTP_GAP_EV_DEVICE_DISCONNECTED 0x83 struct btp_gap_device_disconnected_ev { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; } __packed; #define BTP_GAP_EV_PASSKEY_DISPLAY 0x84 struct btp_gap_passkey_display_ev { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint32_t passkey; } __packed; #define BTP_GAP_EV_PASSKEY_ENTRY_REQ 0x85 struct btp_gap_passkey_entry_req_ev { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; } __packed; #define BTP_GAP_EV_PASSKEY_CONFIRM_REQ 0x86 struct btp_gap_passkey_confirm_req_ev { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint32_t passkey; } __packed; #define BTP_GAP_EV_IDENTITY_RESOLVED 0x87 struct btp_gap_identity_resolved_ev { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t identity_address_type; - uint8_t identity_address[6]; + uint8_t identity_address; } __packed; #define BTP_GAP_EV_CONN_PARAM_UPDATE 0x88 struct btp_gap_conn_param_update_ev { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t conn_itvl; uint16_t conn_latency; uint16_t supervision_timeout; @@ -340,26 +323,22 @@ struct btp_gap_conn_param_update_ev { #define BTP_GAP_EV_SEC_LEVEL_CHANGED 0x89 struct btp_gap_sec_level_changed_ev { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t level; } __packed; #define BTP_GAP_EV_PAIRING_CONSENT_REQ 0x8a struct btp_gap_pairing_consent_req_ev { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; } __packed; #define BTP_GAP_EV_BOND_LOST 0x8b struct btp_gap_bond_lost_ev { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; } __packed; #define BTP_GAP_EV_SEC_PAIRING_FAILED 0x8c struct btp_gap_sec_pairing_failed_ev { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t reason; } __packed; diff --git a/apps/bttester/src/btp/btp_gatt.h b/apps/bttester/src/btp/btp_gatt.h index 6e23366460..41f5ae7ec2 100644 --- a/apps/bttester/src/btp/btp_gatt.h +++ b/apps/bttester/src/btp/btp_gatt.h @@ -131,8 +131,7 @@ struct btp_gatt_descriptor { #define BTP_GATT_DISC_ALL_PRIM_SVCS 0x0b struct btp_gatt_disc_all_prim_svcs_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; } __packed; struct btp_gatt_disc_all_prim_svcs_rp { uint8_t services_count; @@ -141,8 +140,7 @@ struct btp_gatt_disc_all_prim_svcs_rp { #define BTP_GATT_DISC_PRIM_UUID 0x0c struct btp_gatt_disc_prim_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t uuid_length; uint8_t uuid[0]; } __packed; @@ -153,8 +151,7 @@ struct btp_gatt_disc_prim_uuid_rp { #define BTP_GATT_FIND_INCLUDED 0x0d struct btp_gatt_find_included_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t start_handle; uint16_t end_handle; } __packed; @@ -165,8 +162,7 @@ struct btp_gatt_find_included_rp { #define BTP_GATT_DISC_ALL_CHRC 0x0e struct btp_gatt_disc_all_chrc_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t start_handle; uint16_t end_handle; } __packed; @@ -177,8 +173,7 @@ struct btp_gatt_disc_chrc_rp { #define BTP_GATT_DISC_CHRC_UUID 0x0f struct btp_gatt_disc_chrc_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t start_handle; uint16_t end_handle; uint8_t uuid_length; @@ -187,8 +182,7 @@ struct btp_gatt_disc_chrc_uuid_cmd { #define BTP_GATT_DISC_ALL_DESC 0x10 struct btp_gatt_disc_all_desc_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t start_handle; uint16_t end_handle; } __packed; @@ -199,8 +193,7 @@ struct btp_gatt_disc_all_desc_rp { #define BTP_GATT_READ 0x11 struct btp_gatt_read_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t handle; } __packed; struct btp_gatt_read_rp { @@ -211,8 +204,7 @@ struct btp_gatt_read_rp { #define BTP_GATT_READ_UUID 0x12 struct btp_gatt_read_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t start_handle; uint16_t end_handle; uint8_t uuid_length; @@ -221,24 +213,21 @@ struct btp_gatt_read_uuid_cmd { #define BTP_GATT_READ_LONG 0x13 struct btp_gatt_read_long_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t handle; uint16_t offset; } __packed; #define BTP_GATT_READ_MULTIPLE 0x14 struct btp_gatt_read_multiple_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t handles_count; uint16_t handles[0]; } __packed; #define BTP_GATT_WRITE_WITHOUT_RSP 0x15 struct btp_gatt_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t handle; uint16_t data_length; uint8_t data[0]; @@ -246,8 +235,7 @@ struct btp_gatt_write_without_rsp_cmd { #define BTP_GATT_SIGNED_WRITE_WITHOUT_RSP 0x16 struct btp_gatt_signed_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t handle; uint16_t data_length; uint8_t data[0]; @@ -255,8 +243,7 @@ struct btp_gatt_signed_write_without_rsp_cmd { #define BTP_GATT_WRITE 0x17 struct btp_gatt_write_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t handle; uint16_t data_length; uint8_t data[0]; @@ -264,8 +251,7 @@ struct btp_gatt_write_cmd { #define BTP_GATT_WRITE_LONG 0x18 struct btp_gatt_write_long_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t handle; uint16_t offset; uint16_t data_length; @@ -274,8 +260,7 @@ struct btp_gatt_write_long_cmd { #define BTP_GATT_RELIABLE_WRITE 0x19 struct btp_gatt_reliable_write_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t handle; uint16_t offset; uint16_t data_length; @@ -285,8 +270,7 @@ struct btp_gatt_reliable_write_cmd { #define BTP_GATT_CFG_NOTIFY 0x1a #define BTP_GATT_CFG_INDICATE 0x1b struct btp_gatt_cfg_notify_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t enable; uint16_t ccc_handle; } __packed; @@ -311,8 +295,7 @@ struct btp_gatt_attr { #define BTP_GATT_GET_ATTRIBUTE_VALUE 0x1d struct btp_gatt_get_attribute_value_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t handle; } __packed; struct btp_gatt_get_attribute_value_rp { @@ -331,8 +314,7 @@ struct btp_gatt_change_database { /* GATT events */ #define BTP_GATT_EV_NOTIFICATION 0x80 struct btp_gatt_notification_ev { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t type; uint16_t handle; uint16_t data_length; diff --git a/apps/bttester/src/btp/btp_gattc.h b/apps/bttester/src/btp/btp_gattc.h index 0b946a52b1..7c642fdd67 100644 --- a/apps/bttester/src/btp/btp_gattc.h +++ b/apps/bttester/src/btp/btp_gattc.h @@ -37,38 +37,33 @@ struct btp_gattc_read_supported_commands_rp { #define BTP_GATTC_DISC_ALL_PRIM_SVCS 0x03 struct btp_gattc_disc_all_prim_svcs_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; } __packed; #define BTP_GATTC_DISC_PRIM_UUID 0x04 struct btp_gattc_disc_prim_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t uuid_length; uint8_t uuid[0]; } __packed; #define BTP_GATTC_FIND_INCLUDED 0x05 struct btp_gattc_find_included_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t start_handle; uint16_t end_handle; } __packed; #define BTP_GATTC_DISC_ALL_CHRC 0x06 struct btp_gattc_disc_all_chrc_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t start_handle; uint16_t end_handle; } __packed; #define BTP_GATTC_DISC_CHRC_UUID 0x07 struct btp_gattc_disc_chrc_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t start_handle; uint16_t end_handle; uint8_t uuid_length; @@ -77,31 +72,27 @@ struct btp_gattc_disc_chrc_uuid_cmd { #define BTP_GATTC_DISC_ALL_DESC 0x08 struct btp_gattc_disc_all_desc_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t start_handle; uint16_t end_handle; } __packed; #define BTP_GATTC_READ 0x09 struct btp_gattc_read_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t handle; } __packed; #define BTP_GATTC_READ_UUID 0x0a struct btp_gattc_read_uuid_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t start_handle; uint16_t end_handle; uint8_t uuid_length; uint8_t uuid[0]; } __packed; struct btp_gattc_read_uuid_rp { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t status; uint16_t data_length; uint8_t value_length; @@ -110,24 +101,21 @@ struct btp_gattc_read_uuid_rp { #define BTP_GATTC_READ_LONG 0x0b struct btp_gattc_read_long_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t handle; uint16_t offset; } __packed; #define BTP_GATTC_READ_MULTIPLE 0x0c struct btp_gattc_read_multiple_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t handles_count; uint16_t handles[0]; } __packed; #define BTP_GATTC_WRITE_WITHOUT_RSP 0x0d struct btp_gattc_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t handle; uint16_t data_length; uint8_t data[0]; @@ -135,8 +123,7 @@ struct btp_gattc_write_without_rsp_cmd { #define BTP_GATTC_SIGNED_WRITE_WITHOUT_RSP 0x0e struct btp_gattc_signed_write_without_rsp_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t handle; uint16_t data_length; uint8_t data[0]; @@ -144,8 +131,7 @@ struct btp_gattc_signed_write_without_rsp_cmd { #define BTP_GATTC_WRITE 0x0f struct btp_gattc_write_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t handle; uint16_t data_length; uint8_t data[0]; @@ -153,8 +139,7 @@ struct btp_gattc_write_cmd { #define BTP_GATTC_WRITE_LONG 0x10 struct btp_gattc_write_long_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t handle; uint16_t offset; uint16_t data_length; @@ -163,8 +148,7 @@ struct btp_gattc_write_long_cmd { #define BTP_GATTC_RELIABLE_WRITE 0x11 struct btp_gattc_reliable_write_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t handle; uint16_t offset; uint16_t data_length; @@ -174,8 +158,7 @@ struct btp_gattc_reliable_write_cmd { #define BTP_GATTC_CFG_NOTIFY 0x12 #define BTP_GATTC_CFG_INDICATE 0x13 struct btp_gattc_cfg_notify_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t enable; uint16_t ccc_handle; } __packed; @@ -183,15 +166,13 @@ struct btp_gattc_cfg_notify_cmd { /* events */ #define BTP_GATTC_EV_MTU_EXCHANGED 0x80 struct btp_gattc_exchange_mtu_ev { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t mtu; } __packed; #define BTP_GATTC_DISC_ALL_PRIM_RP 0x81 struct btp_gattc_disc_prim_svcs_rp { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t status; uint8_t services_count; uint8_t data[0]; @@ -201,8 +182,7 @@ struct btp_gattc_disc_prim_svcs_rp { #define BTP_GATTC_FIND_INCLUDED_RP 0x83 struct btp_gattc_find_included_rp { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t status; uint8_t services_count; struct btp_gatt_included included[0]; @@ -211,8 +191,7 @@ struct btp_gattc_find_included_rp { #define BTP_GATTC_DISC_ALL_CHRC_RP 0x84 #define BTP_GATTC_DISC_CHRC_UUID_RP 0x85 struct btp_gattc_disc_chrc_rp { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t status; uint8_t characteristics_count; struct btp_gatt_characteristic characteristics[0]; @@ -220,8 +199,7 @@ struct btp_gattc_disc_chrc_rp { #define BTP_GATTC_DISC_ALL_DESC_RP 0x86 struct btp_gattc_disc_all_desc_rp { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t status; uint8_t descriptors_count; struct btp_gatt_descriptor descriptors[0]; @@ -232,8 +210,7 @@ struct btp_gattc_disc_all_desc_rp { #define BTP_GATTC_READ_LONG_RP 0x89 #define BTP_GATTC_READ_MULTIPLE_RP 0x8a struct btp_gattc_read_rp { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t status; uint16_t data_length; uint8_t data[0]; @@ -241,8 +218,7 @@ struct btp_gattc_read_rp { #define BTP_GATTC_WRITE_RP 0x8b struct btp_gattc_write_rp { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t status; } __packed; #define BTP_GATTC_WRITE_LONG_RP 0x8c @@ -250,15 +226,13 @@ struct btp_gattc_write_rp { #define BTP_GATTC_CFG_NOTIFY_RP 0x8e #define BTP_GATTC_CFG_INDICATE_RP 0x8f struct btp_subscribe_rp { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t status; } __packed; #define BTP_GATTC_EV_NOTIFICATION_RXED 0x90 struct btp_gattc_notification_ev { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint8_t type; uint16_t handle; uint16_t data_length; diff --git a/apps/bttester/src/btp/btp_l2cap.h b/apps/bttester/src/btp/btp_l2cap.h index 5916345531..7d2adcaea6 100644 --- a/apps/bttester/src/btp/btp_l2cap.h +++ b/apps/bttester/src/btp/btp_l2cap.h @@ -38,8 +38,7 @@ struct btp_l2cap_read_supported_commands_rp { #define BTP_L2CAP_CONNECT 0x02 struct btp_l2cap_connect_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t psm; uint16_t mtu; uint8_t num; @@ -82,8 +81,7 @@ struct l2cap_accept_connection_cmd { #define BTP_L2CAP_RECONFIGURE 0x07 struct btp_l2cap_reconfigure_cmd { - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; uint16_t mtu; uint8_t num; uint8_t idxs[]; @@ -99,8 +97,7 @@ struct btp_l2cap_credits_cmd { struct btp_l2cap_connection_req_ev { uint8_t chan_id; uint16_t psm; - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; } __packed; #define BTP_L2CAP_EV_CONNECTED 0x81 @@ -111,8 +108,7 @@ struct btp_l2cap_connected_ev { uint16_t peer_mps; uint16_t our_mtu; uint16_t our_mps; - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; } __packed; #define BTP_L2CAP_EV_DISCONNECTED 0x82 @@ -120,8 +116,7 @@ struct btp_l2cap_disconnected_ev { uint16_t result; uint8_t chan_id; uint16_t psm; - uint8_t address_type; - uint8_t address[6]; + ble_addr_t address; } __packed; #define BTP_L2CAP_EV_DATA_RECEIVED 0x83 diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 378e3ae5b2..946bda75e2 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -210,7 +210,7 @@ controller_info(const void *cmd, uint16_t cmd_len, } current_settings |= BIT(BTP_GAP_SETTINGS_PRIVACY); supported_settings |= BIT(BTP_GAP_SETTINGS_PRIVACY); - memcpy(rp->address, addr.val, sizeof(rp->address)); + memcpy(&rp->address, &addr, sizeof(rp->address)); } else { rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, rp->address, NULL); if (rc) { @@ -595,8 +595,7 @@ store_adv(const ble_addr_t *addr, int8_t rssi, return; } - memcpy(ev->address, addr->val, sizeof(ev->address)); - ev->address_type = addr->type; + memcpy(&ev->address, addr, sizeof(ev->address)); ev->rssi = rssi; ev->flags = BTP_GAP_DEVICE_FOUND_FLAG_AD | BTP_GAP_DEVICE_FOUND_FLAG_RSSI; ev->eir_data_len = len; @@ -645,8 +644,7 @@ device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, } ev = (void *) adv_buf->om_data; - a.type = ev->address_type; - memcpy(a.val, ev->address, sizeof(a.val)); + memcpy(&a, &ev->address, sizeof(a)); /* * in general, the Scan Response comes right after the @@ -818,8 +816,7 @@ le_connected(uint16_t conn_handle, int status) addr = &desc.peer_id_addr; - memcpy(connected_ev.address, addr->val, sizeof(connected_ev.address)); - connected_ev.address_type = addr->type; + memcpy(&connected_ev.address, addr, sizeof(connected_ev.address)); connected_ev.conn_itvl = desc.conn_itvl; connected_ev.conn_latency = desc.conn_latency; connected_ev.supervision_timeout = desc.supervision_timeout; @@ -870,8 +867,7 @@ le_disconnected(struct ble_gap_conn_desc *conn, int reason) connection_attempts = 0; memset(&connected_ev, 0, sizeof(connected_ev)); - memcpy(ev.address, addr->val, sizeof(ev.address)); - ev.address_type = addr->type; + memcpy(&ev.address, addr, sizeof(ev.address)); tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_DISCONNECTED, (uint8_t *) &ev, sizeof(ev)); @@ -925,8 +921,7 @@ auth_passkey_display(uint16_t conn_handle, unsigned int passkey) addr = &desc.peer_ota_addr; - memcpy(ev.address, addr->val, sizeof(ev.address)); - ev.address_type = addr->type; + memcpy(&ev.address, addr, sizeof(ev.address)); ev.passkey = htole32(pk.passkey); tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_DISPLAY, @@ -950,8 +945,7 @@ auth_passkey_entry(uint16_t conn_handle) addr = &desc.peer_ota_addr; - memcpy(ev.address, addr->val, sizeof(ev.address)); - ev.address_type = addr->type; + memcpy(&ev.address, addr, sizeof(ev.address)); tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_ENTRY_REQ, (uint8_t *) &ev, sizeof(ev)); @@ -974,8 +968,7 @@ auth_passkey_numcmp(uint16_t conn_handle, unsigned int passkey) addr = &desc.peer_ota_addr; - memcpy(ev.address, addr->val, sizeof(ev.address)); - ev.address_type = addr->type; + memcpy(&ev.address, addr, sizeof(ev.address)); ev.passkey = htole32(passkey); tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_CONFIRM_REQ, @@ -1053,11 +1046,9 @@ le_identity_resolved(uint16_t conn_handle) peer_id_addr = desc.peer_id_addr; peer_ota_addr = desc.peer_ota_addr; - ev.address_type = desc.peer_ota_addr.type; - memcpy(ev.address, desc.peer_ota_addr.val, sizeof(ev.address)); + memcpy(&ev.address, &desc.peer_ota_addr, sizeof(ev.address)); - ev.identity_address_type = desc.peer_id_addr.type; - memcpy(ev.identity_address, desc.peer_id_addr.val, + memcpy(&ev.identity_address, &desc.peer_id_addr, sizeof(ev.identity_address)); tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_IDENTITY_RESOLVED, @@ -1081,8 +1072,7 @@ le_pairing_failed(uint16_t conn_handle, int reason) peer_id_addr = desc.peer_id_addr; peer_ota_addr = desc.peer_ota_addr; - ev.address_type = desc.peer_ota_addr.type; - memcpy(ev.address, desc.peer_ota_addr.val, sizeof(ev.address)); + memcpy(&ev.address, &desc.peer_ota_addr, sizeof(ev.address)); ev.reason = reason; @@ -1097,8 +1087,7 @@ le_conn_param_update(struct ble_gap_conn_desc *desc) SYS_LOG_DBG(""); - ev.address_type = desc->peer_ota_addr.type; - memcpy(ev.address, desc->peer_ota_addr.val, sizeof(ev.address)); + memcpy(&ev.address, &desc->peer_ota_addr, sizeof(ev.address)); ev.conn_itvl = desc->conn_itvl; ev.conn_latency = desc->conn_latency; @@ -1117,8 +1106,7 @@ le_encryption_changed(struct ble_gap_conn_desc *desc) encrypted = (bool) desc->sec_state.encrypted; - ev.address_type = desc->peer_ota_addr.type; - memcpy(ev.address, desc->peer_ota_addr.val, sizeof(ev.address)); + memcpy(&ev.address, &desc->peer_ota_addr, sizeof(ev.address)); ev.level = 0; if (desc->sec_state.encrypted) { @@ -1147,8 +1135,7 @@ bond_lost(uint16_t conn_handle) rc = ble_gap_conn_find(conn_handle, &desc); assert(rc == 0); - memcpy(ev.address, &desc.peer_id_addr, sizeof(ev.address)); - ev.address_type = desc.peer_id_addr.type; + memcpy(&ev.address, &desc.peer_id_addr, sizeof(ev.address)); tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_BOND_LOST, (uint8_t *) &ev, @@ -1415,7 +1402,7 @@ connect(const void *cmd, uint16_t cmd_len, { const struct btp_gap_connect_cmd *cp = cmd; - ble_addr_t *addr = (ble_addr_t *)&cp->address_type; + ble_addr_t *addr = (ble_addr_t *)&cp->address; SYS_LOG_DBG(""); @@ -1441,7 +1428,7 @@ disconnect(const void *cmd, uint16_t cmd_len, SYS_LOG_DBG(""); - rc = gap_conn_find_by_addr((ble_addr_t *)&cp->address_type, &desc); + rc = gap_conn_find_by_addr(&cp->address, &desc); if (rc) { return BTP_STATUS_FAILED; } @@ -1499,7 +1486,7 @@ pair(const void *cmd, uint16_t cmd_len, SYS_LOG_DBG(""); - rc = gap_conn_find_by_addr((ble_addr_t *)&cp->address_type, &desc); + rc = gap_conn_find_by_addr(&cp->address, &desc); if (rc) { return BTP_STATUS_FAILED; } @@ -1521,7 +1508,7 @@ unpair(const void *cmd, uint16_t cmd_len, SYS_LOG_DBG(""); - err = ble_gap_unpair((ble_addr_t *)&cp->address_type); + err = ble_gap_unpair(&cp->address); return err != 0 ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS; } @@ -1536,7 +1523,7 @@ passkey_entry(const void *cmd, uint16_t cmd_len, SYS_LOG_DBG(""); - rc = gap_conn_find_by_addr((ble_addr_t *)&cp->address_type, &desc); + rc = gap_conn_find_by_addr(&cp->address, &desc); if (rc) { return BTP_STATUS_FAILED; } @@ -1563,7 +1550,7 @@ passkey_confirm(const void *cmd, uint16_t cmd_len, SYS_LOG_DBG(""); - rc = gap_conn_find_by_addr((ble_addr_t *)&cp->address_type, &desc); + rc = gap_conn_find_by_addr(&cp->address, &desc); if (rc) { return BTP_STATUS_FAILED; } @@ -1595,7 +1582,7 @@ start_direct_adv(const void *cmd, uint16_t cmd_len, adv_params.high_duty_cycle = cp->high_duty; - err = ble_gap_adv_start(own_addr_type, (ble_addr_t *)&cp->address_type, + err = ble_gap_adv_start(own_addr_type, &cp->address, BLE_HS_FOREVER, &adv_params, gap_event_cb, NULL); if (err) { diff --git a/apps/bttester/src/btp_gatt_cl.c b/apps/bttester/src/btp_gatt_cl.c index 3f7a09f2f8..0ba494a10c 100644 --- a/apps/bttester/src/btp_gatt_cl.c +++ b/apps/bttester/src/btp_gatt_cl.c @@ -126,7 +126,6 @@ tester_mtu_exchanged_ev(uint16_t conn_handle, struct btp_gattc_exchange_mtu_ev *ev; struct ble_gap_conn_desc conn; struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; SYS_LOG_DBG(""); @@ -139,10 +138,7 @@ tester_mtu_exchanged_ev(uint16_t conn_handle, return 0; } - addr = &conn.peer_ota_addr; - - ev->address_type = addr->type; - memcpy(ev->address, addr->val, sizeof(ev->address)); + memcpy(&ev->address, &conn.peer_ota_addr, sizeof(ev->address)); ev->mtu = mtu; @@ -189,7 +185,6 @@ disc_prim_svcs_cb(uint16_t conn_handle, struct ble_gap_conn_desc conn; struct btp_gatt_service *service; const ble_uuid_any_t *uuid; - const ble_addr_t *addr; uint8_t uuid_length; struct os_mbuf *buf = os_msys_get(0, 0); uint8_t opcode = (uint8_t) (int) arg; @@ -208,10 +203,7 @@ disc_prim_svcs_cb(uint16_t conn_handle, goto free; } - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); + memcpy(&rp->address, &conn.peer_ota_addr, sizeof(rp->address)); rp->status = err; if (error->status != 0 && error->status != BLE_HS_EDONE) { @@ -334,7 +326,6 @@ find_included_cb(uint16_t conn_handle, uint8_t uuid_length; uint8_t err = (uint8_t) error->status; struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; struct ble_gap_conn_desc conn; int rc = 0; @@ -351,10 +342,7 @@ find_included_cb(uint16_t conn_handle, goto free; } - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); + memcpy(&rp->address, &conn.peer_ota_addr, sizeof(rp->address)); rp->status = err; @@ -454,7 +442,6 @@ disc_chrc_cb(uint16_t conn_handle, uint8_t opcode = (uint8_t) (int) arg; uint8_t err = (uint8_t) error->status; struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; struct ble_gap_conn_desc conn; int rc = 0; @@ -469,10 +456,7 @@ disc_chrc_cb(uint16_t conn_handle, goto free; } - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); + memcpy(&rp->address, &conn.peer_ota_addr, sizeof(rp->address)); rp->status = err; @@ -616,7 +600,6 @@ disc_all_desc_cb(uint16_t conn_handle, uint8_t uuid_length; uint8_t err = (uint8_t) error->status; struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; struct ble_gap_conn_desc conn; int rc = 0; @@ -633,10 +616,7 @@ disc_all_desc_cb(uint16_t conn_handle, goto free; } - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); + memcpy(&rp->address, &conn.peer_ota_addr, sizeof(rp->address)); rp->status = err; @@ -732,7 +712,6 @@ read_cb(uint16_t conn_handle, struct btp_gattc_read_rp *rp; uint8_t opcode = (uint8_t) (int) arg; struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; struct ble_gap_conn_desc conn; int rc = 0; @@ -747,10 +726,7 @@ read_cb(uint16_t conn_handle, goto free; } - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); + memcpy(&rp->address, &conn.peer_ota_addr, sizeof(rp->address)); SYS_LOG_DBG("status=%d", error->status); @@ -821,7 +797,6 @@ read_uuid_cb(uint16_t conn_handle, uint8_t opcode = (uint8_t) (int) arg; uint8_t err = (uint8_t) error->status; struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; struct ble_gap_conn_desc conn; int rc = 0; static uint16_t attr_len; @@ -839,10 +814,7 @@ read_uuid_cb(uint16_t conn_handle, goto free; } - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); + memcpy(&rp->address, &conn.peer_ota_addr, sizeof(rp->address)); rp->status = err; @@ -932,7 +904,6 @@ read_long_cb(uint16_t conn_handle, uint8_t opcode = (uint8_t) (int) arg; uint8_t err = (uint8_t) error->status; struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; struct ble_gap_conn_desc conn; int rc = 0; @@ -949,10 +920,7 @@ read_long_cb(uint16_t conn_handle, goto free; } - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); + memcpy(&rp->address, &conn.peer_ota_addr, sizeof(rp->address)); rp->status = err; @@ -1090,7 +1058,6 @@ write_cb(uint16_t conn_handle, const struct ble_gatt_error *error, uint8_t err = (uint8_t) error->status; uint8_t opcode = (uint8_t) (int) arg; struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; struct ble_gap_conn_desc conn; int rc = 0; @@ -1107,10 +1074,7 @@ write_cb(uint16_t conn_handle, const struct ble_gatt_error *error, goto free; } - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); + memcpy(&rp->address, &conn.peer_ota_addr, sizeof(rp->address)); rp->status = err; tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, @@ -1197,7 +1161,6 @@ reliable_write_cb(uint16_t conn_handle, struct btp_gattc_write_rp *rp; uint8_t err = (uint8_t) error->status; struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; struct ble_gap_conn_desc conn; int rc = 0; @@ -1214,10 +1177,7 @@ reliable_write_cb(uint16_t conn_handle, goto free; } - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); + memcpy(&rp->address, &conn.peer_ota_addr, sizeof(rp->address)); rp->status = err; tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_RELIABLE_WRITE_RP, @@ -1282,7 +1242,6 @@ subscribe_cb(uint16_t conn_handle, uint8_t err = (uint8_t) error->status; uint8_t opcode = (uint8_t) (int) arg; struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; struct ble_gap_conn_desc conn; int rc = 0; @@ -1299,10 +1258,7 @@ subscribe_cb(uint16_t conn_handle, goto free; } - addr = &conn.peer_ota_addr; - - rp->address_type = addr->type; - memcpy(rp->address, addr->val, sizeof(rp->address)); + memcpy(&rp->address, &conn.peer_ota_addr, sizeof(rp->address)); rp->status = err; tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, @@ -1419,7 +1375,6 @@ tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, struct btp_gattc_notification_ev *ev; struct ble_gap_conn_desc conn; struct os_mbuf *buf = os_msys_get(0, 0); - const ble_addr_t *addr; SYS_LOG_DBG(""); @@ -1436,10 +1391,7 @@ tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, return 0; } - addr = &conn.peer_ota_addr; - - ev->address_type = addr->type; - memcpy(ev->address, addr->val, sizeof(ev->address)); + memcpy(&ev->address, &conn.peer_ota_addr, sizeof(ev->address)); ev->type = (uint8_t) (indication ? 0x02 : 0x01); ev->handle = htole16(attr_handle); ev->data_length = htole16(os_mbuf_len(om)); diff --git a/apps/bttester/src/btp_l2cap.c b/apps/bttester/src/btp_l2cap.c index 498d22604b..389bb8fd79 100644 --- a/apps/bttester/src/btp_l2cap.c +++ b/apps/bttester/src/btp_l2cap.c @@ -201,9 +201,7 @@ connected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, channel->chan = chan; if (!ble_gap_conn_find(conn_handle, &desc)) { - ev.address_type = desc.peer_ota_addr.type; - memcpy(ev.address, desc.peer_ota_addr.val, - sizeof(ev.address)); + memcpy(&ev.address, &desc.peer_ota_addr, sizeof(ev.address)); } tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_CONNECTED, @@ -229,9 +227,7 @@ disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, ev.psm = chan_info->psm; if (!ble_gap_conn_find(conn_handle, &desc)) { - ev.address_type = desc.peer_ota_addr.type; - memcpy(ev.address, desc.peer_ota_addr.val, - sizeof(ev.address)); + memcpy(&ev.address, &desc.peer_ota_addr, sizeof(ev.address)); } tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_DISCONNECTED, From 6f34f7c923edc0c0a30037f8cfa7c85098657ed9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 11 Jul 2023 13:45:55 +0200 Subject: [PATCH 0758/1333] apps/bttester: refactor GATT service Accomodated to new API. --- apps/bttester/src/btp/btp_gatt.h | 5 +- apps/bttester/src/btp/bttester.h | 3 - apps/bttester/src/btp_gatt.c | 805 +++++++++++++++++-------------- 3 files changed, 443 insertions(+), 370 deletions(-) diff --git a/apps/bttester/src/btp/btp_gatt.h b/apps/bttester/src/btp/btp_gatt.h index 41f5ae7ec2..88f2e62a9a 100644 --- a/apps/bttester/src/btp/btp_gatt.h +++ b/apps/bttester/src/btp/btp_gatt.h @@ -128,6 +128,9 @@ struct btp_gatt_descriptor { } __packed; #define BTP_GATT_EXCHANGE_MTU 0x0a +struct btp_gatt_exchange_mtu_cmd { + ble_addr_t address; +} __packed; #define BTP_GATT_DISC_ALL_PRIM_SVCS 0x0b struct btp_gatt_disc_all_prim_svcs_cmd { @@ -305,7 +308,7 @@ struct btp_gatt_get_attribute_value_rp { } __packed; #define BTP_GATT_CHANGE_DATABASE 0x1e -struct btp_gatt_change_database { +struct btp_gatt_change_database_cmd { uint16_t start_handle; uint16_t end_handle; uint8_t visibility; diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h index ea24600c19..9d66cd946b 100644 --- a/apps/bttester/src/btp/bttester.h +++ b/apps/bttester/src/btp/bttester.h @@ -101,9 +101,6 @@ tester_init_gatt(void); uint8_t tester_unregister_gatt(void); void -tester_handle_gatt(uint8_t opcode, uint8_t *data, - uint16_t len); -void tester_handle_gattc(uint8_t opcode, uint8_t *data, uint16_t len); int diff --git a/apps/bttester/src/btp_gatt.c b/apps/bttester/src/btp_gatt.c index ef6a805b75..09bd8d7236 100644 --- a/apps/bttester/src/btp_gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -571,10 +571,11 @@ gatt_svr_rel_write_test(uint16_t conn_handle, uint16_t attr_handle, } } -static void -start_server(uint8_t *data, uint16_t len) +static uint8_t +start_server(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - struct btp_gatt_start_server_rp rp; + struct btp_gatt_start_server_rp *rp = rsp; SYS_LOG_DBG(""); @@ -582,11 +583,12 @@ start_server(uint8_t *data, uint16_t len) ble_svc_gatt_changed(0x0001, 0xffff); - rp.db_attr_off = 0; - rp.db_attr_cnt = 0; + rp->db_attr_off = 0; + rp->db_attr_cnt = 0; + + *rsp_len = sizeof(*rp); - tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_START_SERVER, - (uint8_t *) &rp, sizeof(rp)); + return BTP_STATUS_SUCCESS; } /* Convert UUID from BTP command to bt_uuid */ @@ -702,37 +704,35 @@ read_cb(uint16_t conn_handle, return 0; } -static void -read(uint8_t *data, uint16_t len) +static uint8_t +read_data(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_read_cmd *cmd = (void *) data; + const struct btp_gatt_read_cmd *cp = cmd; struct ble_gap_conn_desc conn; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - goto fail; + return BTP_STATUS_FAILED; } /* Clear buffer */ read_destroy(); if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) { - goto fail; + return BTP_STATUS_FAILED; } - if (ble_gattc_read(conn.conn_handle, le16toh(cmd->handle), + if (ble_gattc_read(conn.conn_handle, le16toh(cp->handle), read_cb, (void *) BTP_GATT_READ)) { read_destroy(); - goto fail; + return BTP_STATUS_FAILED; } - return; - -fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ, BTP_STATUS_FAILED); + return BTP_STATUS_SUCCESS; } static int @@ -773,104 +773,103 @@ read_long_cb(uint16_t conn_handle, return 0; } -static void -read_long(uint8_t *data, uint16_t len) +static uint8_t +read_long(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_read_long_cmd *cmd = (void *) data; + const struct btp_gatt_read_long_cmd *cp = cmd; struct ble_gap_conn_desc conn; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - goto fail; + return BTP_STATUS_FAILED; } /* Clear buffer */ read_destroy(); if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) { - goto fail; + return BTP_STATUS_FAILED; } if (ble_gattc_read_long(conn.conn_handle, - le16toh(cmd->handle), - le16toh(cmd->offset), + le16toh(cp->handle), + le16toh(cp->offset), read_long_cb, (void *) BTP_GATT_READ_LONG)) { read_destroy(); - goto fail; + return BTP_STATUS_FAILED; } - return; - -fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ_LONG, BTP_STATUS_FAILED); + return BTP_STATUS_SUCCESS; } -static void -read_multiple(uint8_t *data, uint16_t len) +static uint8_t +read_multiple(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_read_multiple_cmd *cmd = (void *) data; - uint16_t handles[cmd->handles_count]; + const struct btp_gatt_read_multiple_cmd *cp = cmd; + uint16_t handles[cp->handles_count]; struct ble_gap_conn_desc conn; int rc, i; SYS_LOG_DBG(""); for (i = 0; i < ARRAY_SIZE(handles); i++) { - handles[i] = le16toh(cmd->handles[i]); + handles[i] = le16toh(cp->handles[i]); } - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - goto fail; + return BTP_STATUS_FAILED; } /* Clear buffer */ read_destroy(); if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) { - goto fail; + return BTP_STATUS_FAILED; } if (ble_gattc_read_mult(conn.conn_handle, handles, - cmd->handles_count, read_cb, + cp->handles_count, read_cb, (void *) BTP_GATT_READ_MULTIPLE)) { read_destroy(); - goto fail; + return BTP_STATUS_FAILED; } - return; - -fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ_MULTIPLE, BTP_STATUS_FAILED); + return BTP_STATUS_SUCCESS; } -static void -write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) +static uint8_t +write_without_rsp(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_write_without_rsp_cmd *cmd = (void *) data; + const struct btp_gatt_write_without_rsp_cmd *cp = cmd; struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (cmd_len < sizeof(*cp) || + cmd_len != sizeof(*cp) + le16toh(cp->data_length)) { + return BTP_STATUS_FAILED; + } + + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } if (ble_gattc_write_no_rsp_flat(conn.conn_handle, - le16toh(cmd->handle), cmd->data, - le16toh(cmd->data_length))) { - status = BTP_STATUS_FAILED; + le16toh(cp->handle), cp->data, + le16toh(cp->data_length))) { + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_GATT, op, status); + return BTP_STATUS_SUCCESS; } static int @@ -888,66 +887,75 @@ write_rsp(uint16_t conn_handle, const struct ble_gatt_error *error, return 0; } -static void -write(uint8_t *data, uint16_t len) +static uint8_t +write_data(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_write_cmd *cmd = (void *) data; + const struct btp_gatt_write_cmd *cp = cmd; struct ble_gap_conn_desc conn; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (cmd_len < sizeof(*cp) || + cmd_len != sizeof(*cp) + le16toh(cp->data_length)) { + return BTP_STATUS_FAILED; + } + + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - goto fail; + return BTP_STATUS_FAILED; } - if (ble_gattc_write_flat(conn.conn_handle, le16toh(cmd->handle), - cmd->data, le16toh(cmd->data_length), + if (ble_gattc_write_flat(conn.conn_handle, le16toh(cp->handle), + cp->data, le16toh(cp->data_length), write_rsp, (void *) BTP_GATT_WRITE)) { - goto fail; + return BTP_STATUS_FAILED; } - return; - -fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE, BTP_STATUS_FAILED); + return BTP_STATUS_DELAY_REPLY; } -static void -write_long(uint8_t *data, uint16_t len) +static uint8_t +write_long(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_write_long_cmd *cmd = (void *) data; + const struct btp_gatt_write_long_cmd *cp = cmd; struct ble_gap_conn_desc conn; struct os_mbuf *om = NULL; int rc = 0; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (cmd_len < sizeof(*cp) || + cmd_len != sizeof(*cp) + le16toh(cp->data_length)) { + goto fail; + } + + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { goto fail; } - om = ble_hs_mbuf_from_flat(cmd->data, le16toh(cmd->data_length)); + om = ble_hs_mbuf_from_flat(cp->data, le16toh(cp->data_length)); if (!om) { SYS_LOG_ERR("Insufficient resources"); goto fail; } rc = ble_gattc_write_long(conn.conn_handle, - le16toh(cmd->handle), - le16toh(cmd->offset), + le16toh(cp->handle), + le16toh(cp->offset), om, write_rsp, (void *) BTP_GATT_WRITE_LONG); if (!rc) { - return; + return BTP_STATUS_DELAY_REPLY; } fail: SYS_LOG_ERR("Failed to send Write Long request, rc=%d", rc); os_mbuf_free_chain(om); - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE_LONG, BTP_STATUS_FAILED); + return BTP_STATUS_FAILED; } static int @@ -966,10 +974,11 @@ reliable_write_rsp(uint16_t conn_handle, return 0; } -static void -reliable_write(uint8_t *data, uint16_t len) +static uint8_t +reliable_write(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_reliable_write_cmd *cmd = (void *) data; + const struct btp_gatt_reliable_write_cmd *cp = cmd; struct ble_gap_conn_desc conn; struct ble_gatt_attr attr; struct os_mbuf *om = NULL; @@ -977,21 +986,21 @@ reliable_write(uint8_t *data, uint16_t len) SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { goto fail; } - om = ble_hs_mbuf_from_flat(cmd->data, le16toh(cmd->data_length)); + om = ble_hs_mbuf_from_flat(cp->data, le16toh(cp->data_length)); /* This is required, because Nimble checks if * the data is longer than offset */ - if (os_mbuf_extend(om, le16toh(cmd->offset) + 1) == NULL) { + if (os_mbuf_extend(om, le16toh(cp->offset) + 1) == NULL) { goto fail; } - attr.handle = le16toh(cmd->handle); - attr.offset = le16toh(cmd->offset); + attr.handle = le16toh(cp->handle); + attr.offset = le16toh(cp->offset); attr.om = om; if (ble_gattc_write_reliable(conn.conn_handle, &attr, 1, @@ -999,12 +1008,12 @@ reliable_write(uint8_t *data, uint16_t len) goto fail; } - return; + return BTP_STATUS_SUCCESS; fail: os_mbuf_free_chain(om); - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE_LONG, BTP_STATUS_FAILED); + return BTP_STATUS_FAILED; } static struct bt_gatt_subscribe_params { @@ -1013,44 +1022,42 @@ static struct bt_gatt_subscribe_params { uint16_t value_handle; } subscribe_params; -static void -read_uuid(uint8_t *data, uint16_t len) +static uint8_t +read_uuid(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_read_uuid_cmd *cmd = (void *) data; + const struct btp_gatt_read_uuid_cmd *cp = cmd; struct ble_gap_conn_desc conn; ble_uuid_any_t uuid; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - goto fail; + return BTP_STATUS_FAILED; } - if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { - goto fail; + if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid)) { + return BTP_STATUS_FAILED; } /* Clear buffer */ read_destroy(); if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) { - goto fail; + return BTP_STATUS_FAILED; } if (ble_gattc_read_by_uuid(conn.conn_handle, - le16toh(cmd->start_handle), - le16toh(cmd->end_handle), &uuid.u, + le16toh(cp->start_handle), + le16toh(cp->end_handle), &uuid.u, read_long_cb, (void *) BTP_GATT_READ_UUID)) { read_destroy(); - goto fail; + return BTP_STATUS_FAILED; } - return; - -fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_READ, BTP_STATUS_FAILED); + return BTP_STATUS_SUCCESS; } static int @@ -1161,57 +1168,56 @@ disc_all_desc_cb(uint16_t conn_handle, return 0; } -static void -disc_all_prim_svcs(uint8_t *data, uint16_t len) +static uint8_t +disc_all_prim_svcs(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { + const struct btp_gatt_disc_all_prim_svcs_cmd *cp = cmd; struct ble_gap_conn_desc conn; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - goto fail; + return BTP_STATUS_FAILED; } if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_all_prim_svcs_rp))) { - goto fail; + return BTP_STATUS_FAILED; } if (ble_gattc_disc_all_svcs(conn.conn_handle, disc_prim_uuid_cb, (void *) BTP_GATT_DISC_ALL_PRIM_SVCS)) { discover_destroy(); - goto fail; + return BTP_STATUS_FAILED; } - return; - -fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_PRIM_SVCS, - BTP_STATUS_FAILED); + return BTP_STATUS_DELAY_REPLY; } -static void -disc_all_desc(uint8_t *data, uint16_t len) +static uint8_t +disc_all_desc(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_disc_all_desc_cmd *cmd = (void *) data; + const struct btp_gatt_disc_all_desc_cmd *cp = cmd; struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - goto fail; + return BTP_STATUS_FAILED; } if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_all_desc_rp))) { - goto fail; + return BTP_STATUS_FAILED; } - start_handle = le16toh(cmd->start_handle) - 1; - end_handle = le16toh(cmd->end_handle); + start_handle = le16toh(cp->start_handle) - 1; + end_handle = le16toh(cp->end_handle); rc = ble_gattc_disc_all_dscs(conn.conn_handle, start_handle, end_handle, disc_all_desc_cb, NULL); @@ -1220,13 +1226,10 @@ disc_all_desc(uint8_t *data, uint16_t len) if (rc) { discover_destroy(); - goto fail; + return BTP_STATUS_FAILED; } - return; - -fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC, BTP_STATUS_FAILED); + return BTP_STATUS_DELAY_REPLY; } static int @@ -1251,7 +1254,7 @@ find_included_cb(uint16_t conn_handle, if (error->status == BLE_HS_EDONE) { tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, gatt_buf - .buf, gatt_buf.len); + .buf, gatt_buf.len); discover_destroy(); return 0; } @@ -1267,9 +1270,8 @@ find_included_cb(uint16_t conn_handle, return BLE_HS_ENOMEM; } - /* FIXME */ included->included_handle = htole16(service_handle + 1 + - rp->services_count); + rp->services_count); included->service.start_handle = htole16(gatt_svc->start_handle); included->service.end_handle = htole16(gatt_svc->end_handle); included->service.uuid_length = uuid_length; @@ -1292,7 +1294,7 @@ disc_chrc_cb(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_chr *gatt_chr, void *arg) { - struct btp_gatt_disc_chrc_rp *rp = (void *) gatt_buf.buf; + struct btp_gatt_disc_chrc_rp *rp = (void *) gatt_buf.buf; struct btp_gatt_characteristic *chrc; const ble_uuid_any_t *uuid; uint8_t btp_opcode = (uint8_t) (int) arg; @@ -1309,7 +1311,7 @@ disc_chrc_cb(uint16_t conn_handle, if (error->status == BLE_HS_EDONE) { tester_send(BTP_SERVICE_ID_GATT, btp_opcode, gatt_buf.buf, gatt_buf - .len); + .len); discover_destroy(); return 0; } @@ -1343,10 +1345,11 @@ disc_chrc_cb(uint16_t conn_handle, return 0; } -static void -disc_chrc_uuid(uint8_t *data, uint16_t len) +static uint8_t +disc_chrc_uuid(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_disc_chrc_uuid_cmd *cmd = (void *) data; + const struct btp_gatt_disc_chrc_uuid_cmd *cp = cmd; struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; ble_uuid_any_t uuid; @@ -1354,114 +1357,111 @@ disc_chrc_uuid(uint8_t *data, uint16_t len) SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - goto fail; + return BTP_STATUS_FAILED; } - if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { - goto fail; + if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid)) { + return BTP_STATUS_FAILED; } if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_chrc_rp))) { - goto fail; + return BTP_STATUS_FAILED; } - start_handle = le16toh(cmd->start_handle); - end_handle = le16toh(cmd->end_handle); + start_handle = le16toh(cp->start_handle); + end_handle = le16toh(cp->end_handle); if (ble_gattc_disc_chrs_by_uuid(conn.conn_handle, start_handle, end_handle, &uuid.u, disc_chrc_cb, (void *) BTP_GATT_DISC_CHRC_UUID)) { discover_destroy(); - goto fail; + return BTP_STATUS_FAILED; } - return; - -fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_CHRC_UUID, - BTP_STATUS_FAILED); + return BTP_STATUS_DELAY_REPLY; } -static void -disc_prim_uuid(uint8_t *data, uint16_t len) +static uint8_t +disc_prim_uuid(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_disc_prim_uuid_cmd *cmd = (void *) data; + const struct btp_gatt_disc_prim_uuid_cmd *cp = cmd; struct ble_gap_conn_desc conn; ble_uuid_any_t uuid; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if ((cmd_len < sizeof(*cp)) || + (cmd_len != sizeof(*cp) + cp->uuid_length)) { + return BTP_STATUS_FAILED; + } + + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - goto fail; + return BTP_STATUS_FAILED; } - if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { - goto fail; + if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid)) { + return BTP_STATUS_FAILED; } if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_prim_uuid_rp))) { - goto fail; + return BTP_STATUS_FAILED; } if (ble_gattc_disc_svc_by_uuid(conn.conn_handle, &uuid.u, disc_prim_uuid_cb, (void *) BTP_GATT_DISC_PRIM_UUID)) { discover_destroy(); - goto fail; + return BTP_STATUS_FAILED; } - return; - -fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_PRIM_UUID, - BTP_STATUS_FAILED); + return BTP_STATUS_DELAY_REPLY; } -static void -disc_all_chrc(uint8_t *data, uint16_t len) +static uint8_t +disc_all_chrc(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_disc_all_chrc_cmd *cmd = (void *) data; - struct ble_gap_conn_desc conn; + const struct btp_gatt_disc_all_chrc_cmd *cp = cmd; + struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { SYS_LOG_DBG("Conn find failed"); - goto fail; + return BTP_STATUS_FAILED; } if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_chrc_rp))) { SYS_LOG_DBG("Buf reserve failed"); - goto fail; + return BTP_STATUS_FAILED; } - start_handle = le16toh(cmd->start_handle); - end_handle = le16toh(cmd->end_handle); + start_handle = le16toh(cp->start_handle); + end_handle = le16toh(cp->end_handle); rc = ble_gattc_disc_all_chrs(conn.conn_handle, start_handle, end_handle, disc_chrc_cb, (void *) BTP_GATT_DISC_ALL_CHRC); if (rc) { discover_destroy(); - goto fail; + return BTP_STATUS_FAILED; } - return; - -fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_CHRC, BTP_STATUS_FAILED); + return BTP_STATUS_DELAY_REPLY; } -static void -find_included(uint8_t *data, uint16_t len) +static uint8_t +find_included(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_find_included_cmd *cmd = (void *) data; + const struct btp_gatt_find_included_cmd *cp = cmd; struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; int service_handle_arg; @@ -1469,30 +1469,27 @@ find_included(uint8_t *data, uint16_t len) SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - goto fail; + return BTP_STATUS_FAILED; } if (!gatt_buf_reserve(sizeof(struct btp_gatt_find_included_rp))) { - goto fail; + return BTP_STATUS_FAILED; } - start_handle = le16toh(cmd->start_handle); - end_handle = le16toh(cmd->end_handle); + start_handle = le16toh(cp->start_handle); + end_handle = le16toh(cp->end_handle); service_handle_arg = start_handle; if (ble_gattc_find_inc_svcs(conn.conn_handle, start_handle, end_handle, find_included_cb, (void *) service_handle_arg)) { discover_destroy(); - goto fail; + return BTP_STATUS_FAILED; } - return; - -fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, BTP_STATUS_FAILED); + return BTP_STATUS_DELAY_REPLY; } static int @@ -1503,38 +1500,39 @@ exchange_func(uint16_t conn_handle, SYS_LOG_DBG(""); if (error->status) { - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_EXCHANGE_MTU, - BTP_STATUS_FAILED); + SYS_LOG_DBG("MTU exchange failed"); return 0; } - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_EXCHANGE_MTU, BTP_STATUS_SUCCESS); + SYS_LOG_DBG("MTU exchange succeed"); return 0; } -static void -exchange_mtu(uint8_t *data, uint16_t len) +static uint8_t +exchange_mtu(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { + const struct btp_gatt_exchange_mtu_cmd *cp = cmd; struct ble_gap_conn_desc conn; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - goto fail; + return BTP_STATUS_FAILED; } if (ble_gattc_exchange_mtu(conn.conn_handle, exchange_func, NULL)) { - goto fail; + return BTP_STATUS_FAILED; } - return; -fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_EXCHANGE_MTU, - BTP_STATUS_FAILED); + /* this BTP command is about initiating MTU exchange, no need to wait + * for procedure to complete. + */ + return BTP_STATUS_SUCCESS; } static int @@ -1580,36 +1578,64 @@ disable_subscription(uint16_t conn_handle, uint16_t ccc_handle) return 0; } -static void -config_subscription(uint8_t *data, uint16_t len, uint8_t op) +static uint8_t +config_subscription_notif(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_cfg_notify_cmd *cmd = (void *) data; + const struct btp_gatt_cfg_notify_cmd *cp = cmd; struct ble_gap_conn_desc conn; - uint16_t ccc_handle = le16toh(cmd->ccc_handle); + uint16_t ccc_handle = le16toh(cp->ccc_handle); uint8_t status; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - tester_rsp(BTP_SERVICE_ID_GATT, op, BTP_STATUS_FAILED); - return; + return BTP_STATUS_FAILED; } - if (cmd->enable) { - uint16_t value; + if (cp->enable) { + /* on success response will be sent from callback */ + if (enable_subscription(conn.conn_handle, + ccc_handle, 0x0001) == 0) { + return BTP_STATUS_DELAY_REPLY; + } - if (op == BTP_GATT_CFG_NOTIFY) { - value = 0x0001; + status = BTP_STATUS_FAILED; + } else { + if (disable_subscription(conn.conn_handle, ccc_handle) < 0) { + status = BTP_STATUS_FAILED; } else { - value = 0x0002; + status = BTP_STATUS_SUCCESS; } + } + + return status; +} + +static uint8_t +config_subscription_ind(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_gatt_cfg_notify_cmd *cp = cmd; + struct ble_gap_conn_desc conn; + uint16_t ccc_handle = le16toh(cp->ccc_handle); + uint8_t status; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); + if (rc) { + return BTP_STATUS_FAILED; + } + if (cp->enable) { /* on success response will be sent from callback */ if (enable_subscription(conn.conn_handle, - ccc_handle, value) == 0) { - return; + ccc_handle, 0x0002) == 0) { + return BTP_STATUS_DELAY_REPLY; } status = BTP_STATUS_FAILED; @@ -1621,9 +1647,7 @@ config_subscription(uint8_t *data, uint16_t len, uint8_t op) } } - SYS_LOG_DBG("Config subscription (op %u) status %u", op, status); - - tester_rsp(BTP_SERVICE_ID_GATT, op, status); + return status; } #define BTP_PERM_F_READ 0x01 @@ -1661,11 +1685,12 @@ flags_hs2btp(uint8_t flags) return ret; } -static void -get_attrs(uint8_t *data, uint16_t len) +static uint8_t +get_attrs(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_get_attributes_cmd *cmd = (void *) data; - struct btp_gatt_get_attributes_rp *rp; + const struct btp_gatt_get_attributes_cmd *cp = cmd; + struct btp_gatt_get_attributes_rp *rp = rsp; struct btp_gatt_attr *gatt_attr; struct os_mbuf *buf = os_msys_get(0, 0); uint16_t start_handle, end_handle; @@ -1674,17 +1699,19 @@ get_attrs(uint8_t *data, uint16_t len) ble_uuid_t *uuid_ptr = NULL; uint8_t count = 0; char str[BLE_UUID_STR_LEN]; + uint8_t status = BTP_STATUS_SUCCESS; SYS_LOG_DBG(""); memset(str, 0, sizeof(str)); memset(&uuid, 0, sizeof(uuid)); - start_handle = le16toh(cmd->start_handle); - end_handle = le16toh(cmd->end_handle); + start_handle = le16toh(cp->start_handle); + end_handle = le16toh(cp->end_handle); - if (cmd->type_length) { - if (btp2bt_uuid(cmd->type, cmd->type_length, &uuid)) { - goto fail; + if (cp->type_length) { + if (btp2bt_uuid(cp->type, cp->type_length, &uuid)) { + status = BTP_STATUS_FAILED; + goto free; } ble_uuid_to_str(&uuid.u, str); @@ -1698,7 +1725,8 @@ get_attrs(uint8_t *data, uint16_t len) rp = os_mbuf_extend(buf, sizeof(*rp)); if (!rp) { - goto fail; + status = BTP_STATUS_FAILED; + goto free; } entry = ble_att_svr_find_by_uuid(entry, uuid_ptr, end_handle); @@ -1712,7 +1740,8 @@ get_attrs(uint8_t *data, uint16_t len) gatt_attr = os_mbuf_extend(buf, sizeof(*gatt_attr)); if (!gatt_attr) { - goto fail; + status = BTP_STATUS_FAILED; + goto free; } gatt_attr->handle = htole16(entry->ha_handle_id); gatt_attr->permission = flags_hs2btp(entry->ha_flags); @@ -1736,33 +1765,32 @@ get_attrs(uint8_t *data, uint16_t len) rp->attrs_count = count; - tester_send_buf(BTP_SERVICE_ID_GATT, BTP_GATT_GET_ATTRIBUTES, - CONTROLLER_INDEX, buf); + *rsp_len = sizeof(*rp) + buf->om_len; - goto free; -fail: - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_GET_ATTRIBUTES, - BTP_STATUS_FAILED); free: os_mbuf_free_chain(buf); + return status; } -static void -get_attr_val(uint8_t *data, uint16_t len) +static uint8_t +get_attr_val(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_get_attribute_value_cmd *cmd = (void *) data; + const struct btp_gatt_get_attribute_value_cmd *cp = cmd; struct btp_gatt_get_attribute_value_rp *rp; struct ble_gap_conn_desc conn; struct os_mbuf *buf = os_msys_get(0, 0); - uint16_t handle = le16toh(cmd->handle); + uint16_t handle = le16toh(cp->handle); uint8_t out_att_err = 0; int conn_status; + uint8_t status = BTP_STATUS_SUCCESS; - conn_status = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + conn_status = ble_gap_conn_find_by_addr(&cp->address, &conn); if (conn_status) { rp = os_mbuf_extend(buf, sizeof(*rp)); if (!rp) { + status = BTP_STATUS_FAILED; goto free; } @@ -1773,13 +1801,14 @@ get_attr_val(uint8_t *data, uint16_t len) rp->att_response = out_att_err; rp->value_length = os_mbuf_len(buf) - sizeof(*rp); - tester_send_buf(BTP_SERVICE_ID_GATT, BTP_GATT_GET_ATTRIBUTE_VALUE, - CONTROLLER_INDEX, buf); + (void)memcpy(rsp, buf->om_data, buf->om_len); + *rsp_len = buf->om_len; goto free; } else { rp = os_mbuf_extend(buf, sizeof(*rp)); if (!rp) { + status = BTP_STATUS_FAILED; goto free; } @@ -1790,69 +1819,72 @@ get_attr_val(uint8_t *data, uint16_t len) rp->att_response = out_att_err; rp->value_length = os_mbuf_len(buf) - sizeof(*rp); - tester_send_buf(BTP_SERVICE_ID_GATT, BTP_GATT_GET_ATTRIBUTE_VALUE, - CONTROLLER_INDEX, buf); + (void)memcpy(rsp, buf->om_data, buf->om_len); + *rsp_len = buf->om_len; goto free; } free: os_mbuf_free_chain(buf); + return status; } -static void -change_database(uint8_t *data, uint16_t len) +static uint8_t +change_database(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gatt_change_database *cmd = (void *) data; + const struct btp_gatt_change_database_cmd *cp = cmd; SYS_LOG_DBG("") ble_gatts_show_local(); - ble_svc_gatt_changed(cmd->start_handle, cmd->end_handle); - - tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_CHANGE_DATABASE, - BTP_STATUS_SUCCESS); + ble_svc_gatt_changed(cp->start_handle, cp->end_handle); - return; + return BTP_STATUS_SUCCESS; } -static void -supported_commands(uint8_t *data, uint16_t len) +static uint8_t +supported_commands(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - uint8_t cmds[4]; - struct btp_gatt_read_supported_commands_rp *rp = (void *) cmds; - - SYS_LOG_DBG(""); - - memset(cmds, 0, sizeof(cmds)); - - tester_set_bit(cmds, BTP_GATT_READ_SUPPORTED_COMMANDS); - tester_set_bit(cmds, BTP_GATT_START_SERVER); - tester_set_bit(cmds, BTP_GATT_EXCHANGE_MTU); - tester_set_bit(cmds, BTP_GATT_DISC_ALL_PRIM_SVCS); - tester_set_bit(cmds, BTP_GATT_DISC_PRIM_UUID); - tester_set_bit(cmds, BTP_GATT_FIND_INCLUDED); - tester_set_bit(cmds, BTP_GATT_DISC_ALL_CHRC); - tester_set_bit(cmds, BTP_GATT_DISC_CHRC_UUID); - tester_set_bit(cmds, BTP_GATT_DISC_ALL_DESC); - tester_set_bit(cmds, BTP_GATT_READ); - tester_set_bit(cmds, BTP_GATT_READ_LONG); - tester_set_bit(cmds, BTP_GATT_READ_MULTIPLE); - tester_set_bit(cmds, BTP_GATT_WRITE_WITHOUT_RSP); + struct btp_gatt_read_supported_commands_rp *rp = rsp; + + /* octet 0 */ + tester_set_bit(rp->data, BTP_GATT_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_GATT_START_SERVER); + + /* octet 1 */ + tester_set_bit(rp->data, BTP_GATT_EXCHANGE_MTU); + tester_set_bit(rp->data, BTP_GATT_DISC_ALL_PRIM_SVCS); + tester_set_bit(rp->data, BTP_GATT_DISC_PRIM_UUID); + tester_set_bit(rp->data, BTP_GATT_FIND_INCLUDED); + tester_set_bit(rp->data, BTP_GATT_DISC_ALL_CHRC); + tester_set_bit(rp->data, BTP_GATT_DISC_CHRC_UUID); + + /* octet 2 */ + tester_set_bit(rp->data, BTP_GATT_DISC_ALL_DESC); + tester_set_bit(rp->data, BTP_GATT_READ); + tester_set_bit(rp->data, BTP_GATT_READ_LONG); + tester_set_bit(rp->data, BTP_GATT_READ_MULTIPLE); + tester_set_bit(rp->data, BTP_GATT_WRITE_WITHOUT_RSP); #if 0 - tester_set_bit(cmds, BTP_GATT_SIGNED_WRITE_WITHOUT_RSP); + tester_set_bit(rp->data, BTP_GATT_SIGNED_WRITE_WITHOUT_RSP); #endif - tester_set_bit(cmds, BTP_GATT_WRITE); - tester_set_bit(cmds, BTP_GATT_WRITE_LONG); - tester_set_bit(cmds, BTP_GATT_CFG_NOTIFY); - tester_set_bit(cmds, BTP_GATT_CFG_INDICATE); - tester_set_bit(cmds, BTP_GATT_GET_ATTRIBUTES); - tester_set_bit(cmds, BTP_GATT_GET_ATTRIBUTE_VALUE); - tester_set_bit(cmds, BTP_GATT_CHANGE_DATABASE); - - tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_READ_SUPPORTED_COMMANDS, - (uint8_t *) rp, sizeof(cmds)); + tester_set_bit(rp->data, BTP_GATT_WRITE); + + /* octet 3 */ + tester_set_bit(rp->data, BTP_GATT_WRITE_LONG); + tester_set_bit(rp->data, BTP_GATT_CFG_NOTIFY); + tester_set_bit(rp->data, BTP_GATT_CFG_INDICATE); + tester_set_bit(rp->data, BTP_GATT_GET_ATTRIBUTES); + tester_set_bit(rp->data, BTP_GATT_GET_ATTRIBUTE_VALUE); + tester_set_bit(rp->data, BTP_GATT_CHANGE_DATABASE); + + *rsp_len = sizeof(*rp) + 4; + + return BTP_STATUS_SUCCESS; } enum attr_type { @@ -1861,88 +1893,126 @@ enum attr_type { BLE_GATT_ATTR_DSC, }; -void -tester_handle_gatt(uint8_t opcode, uint8_t *data, - uint16_t len) -{ - switch (opcode) { - case BTP_GATT_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - return; - case BTP_GATT_START_SERVER: - start_server(data, len); - return; - case BTP_GATT_EXCHANGE_MTU: - exchange_mtu(data, len); - return; - case BTP_GATT_DISC_ALL_PRIM_SVCS: - disc_all_prim_svcs(data, len); - return; - case BTP_GATT_DISC_PRIM_UUID: - disc_prim_uuid(data, len); - return; - case BTP_GATT_FIND_INCLUDED: - find_included(data, len); - return; - case BTP_GATT_DISC_ALL_CHRC: - disc_all_chrc(data, len); - return; - case BTP_GATT_DISC_CHRC_UUID: - disc_chrc_uuid(data, len); - return; - case BTP_GATT_DISC_ALL_DESC: - disc_all_desc(data, len); - return; - case BTP_GATT_CHANGE_DATABASE: - change_database(data, len); - return; - case BTP_GATT_READ: - read(data, len); - return; - case BTP_GATT_READ_UUID: - read_uuid(data, len); - return; - case BTP_GATT_READ_LONG: - read_long(data, len); - return; - case BTP_GATT_READ_MULTIPLE: - read_multiple(data, len); - return; - case BTP_GATT_WRITE_WITHOUT_RSP: - write_without_rsp(data, - len, - opcode, - false); - return; +static const struct btp_handler handlers[] = { + { + .opcode = BTP_GATT_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = supported_commands, + }, + { + .opcode = BTP_GATT_START_SERVER, + .expect_len = 0, + .func = start_server, + }, + { + .opcode = BTP_GATT_EXCHANGE_MTU, + .expect_len = sizeof(struct btp_gatt_exchange_mtu_cmd), + .func = exchange_mtu, + }, + { + .opcode = BTP_GATT_DISC_ALL_PRIM_SVCS, + .expect_len = sizeof(struct btp_gatt_disc_all_prim_svcs_cmd), + .func = disc_all_prim_svcs, + }, + { + .opcode = BTP_GATT_DISC_PRIM_UUID, + .expect_len = -1, + .func = disc_prim_uuid, + }, + { + .opcode = BTP_GATT_FIND_INCLUDED, + .expect_len = sizeof(struct btp_gatt_find_included_cmd), + .func = find_included, + }, + { + .opcode = BTP_GATT_DISC_ALL_CHRC, + .expect_len = sizeof(struct btp_gatt_disc_all_chrc_cmd), + .func = disc_all_chrc, + }, + { + .opcode = BTP_GATT_DISC_CHRC_UUID, + .expect_len = -1, + .func = disc_chrc_uuid, + }, + { + .opcode = BTP_GATT_DISC_ALL_DESC, + .expect_len = sizeof(struct btp_gatt_disc_all_desc_cmd), + .func = disc_all_desc, + }, + { + .opcode = BTP_GATT_CHANGE_DATABASE, + .expect_len = sizeof(struct btp_gatt_change_database_cmd), + .func = change_database, + }, + { + .opcode = BTP_GATT_READ, + .expect_len = sizeof(struct btp_gatt_read_cmd), + .func = read_data, + }, + { + .opcode = BTP_GATT_READ_UUID, + .expect_len = -1, + .func = read_uuid, + }, + { + .opcode = BTP_GATT_READ_LONG, + .expect_len = sizeof(struct btp_gatt_read_long_cmd), + .func = read_long, + }, + { + .opcode = BTP_GATT_READ_MULTIPLE, + .expect_len = -1, + .func = read_multiple, + }, + { + .opcode = BTP_GATT_WRITE_WITHOUT_RSP, + .expect_len = -1, + .func = write_without_rsp, + }, #if 0 - case BTP_GATT_SIGNED_WRITE_WITHOUT_RSP: - write_without_rsp(data, len, opcode, true); - return; + { + .opcode = BTP_GATT_SIGNED_WRITE_WITHOUT_RSP, + .expect_len = -1, + .func = write_signed_without_rsp, + }, #endif - case BTP_GATT_WRITE: - write(data, len); - return; - case BTP_GATT_WRITE_LONG: - write_long(data, len); - return; - case BTP_GATT_RELIABLE_WRITE: - reliable_write(data, len); - return; - case BTP_GATT_CFG_NOTIFY: - case BTP_GATT_CFG_INDICATE: - config_subscription(data, len, opcode); - return; - case BTP_GATT_GET_ATTRIBUTES: - get_attrs(data, len); - return; - case BTP_GATT_GET_ATTRIBUTE_VALUE: - get_attr_val(data, len); - return; - default: - tester_rsp(BTP_SERVICE_ID_GATT, opcode, BTP_STATUS_UNKNOWN_CMD); - return; - } -} + { + .opcode = BTP_GATT_WRITE, + .expect_len = -1, + .func = write_data, + }, + { + .opcode = BTP_GATT_WRITE_LONG, + .expect_len = -1, + .func = write_long, + }, + { + .opcode = BTP_GATT_RELIABLE_WRITE, + .expect_len = -1, + .func = reliable_write, + }, + { + .opcode = BTP_GATT_CFG_NOTIFY, + .expect_len = sizeof(struct btp_gatt_cfg_notify_cmd), + .func = config_subscription_notif, + }, + { + .opcode = BTP_GATT_CFG_INDICATE, + .expect_len = sizeof(struct btp_gatt_cfg_notify_cmd), + .func = config_subscription_ind, + }, + { + .opcode = BTP_GATT_GET_ATTRIBUTES, + .expect_len = -1, + .func = get_attrs, + }, + { + .opcode = BTP_GATT_GET_ATTRIBUTE_VALUE, + .expect_len = sizeof(struct btp_gatt_get_attribute_value_cmd), + .func = get_attr_val, + }, +}; int tester_gatt_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, @@ -2148,6 +2218,9 @@ tester_init_gatt(void) os_callout_init(¬ify_tx_timer, os_eventq_dflt_get(), notify_test, NULL); + tester_register_command_handlers(BTP_SERVICE_ID_GATT, handlers, + ARRAY_SIZE(handlers)); + return BTP_STATUS_SUCCESS; } From 2210018c0492806e62503882e0d0c235f9e98d8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 12 Jul 2023 10:24:06 +0200 Subject: [PATCH 0759/1333] apps/bttester: refactor L2CAP service Accomodated to new API. --- apps/bttester/src/btp/bttester.h | 3 - apps/bttester/src/btp_l2cap.c | 361 +++++++++++++++++-------------- 2 files changed, 198 insertions(+), 166 deletions(-) diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h index 9d66cd946b..4112a51307 100644 --- a/apps/bttester/src/btp/bttester.h +++ b/apps/bttester/src/btp/bttester.h @@ -120,9 +120,6 @@ uint8_t tester_init_l2cap(void); uint8_t tester_unregister_l2cap(void); -void -tester_handle_l2cap(uint8_t opcode, uint8_t *data, - uint16_t len); #endif #if MYNEWT_VAL(BLE_MESH) diff --git a/apps/bttester/src/btp_l2cap.c b/apps/bttester/src/btp_l2cap.c index 389bb8fd79..aa6e158d32 100644 --- a/apps/bttester/src/btp_l2cap.c +++ b/apps/bttester/src/btp_l2cap.c @@ -72,7 +72,6 @@ get_free_channel(void) chan = &channels[i]; chan->chan_id = i; - return chan; } @@ -399,43 +398,45 @@ tester_l2cap_event(struct ble_l2cap_event *event, void *arg) } } -static void -connect(uint8_t *data, uint16_t len) +static uint8_t +connect(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_l2cap_connect_cmd *cmd = (void *) data; - uint8_t rp_buf[sizeof(struct btp_l2cap_connect_rp) + cmd->num]; - struct btp_l2cap_connect_rp *rp = (void *) rp_buf; + const struct btp_l2cap_connect_cmd *cp = cmd; + struct btp_l2cap_connect_rp *rp = rsp; struct ble_gap_conn_desc desc; struct channel *chan; - struct os_mbuf *sdu_rx[cmd->num]; - ble_addr_t *addr = (void *) data; - uint16_t mtu = htole16(cmd->mtu); + struct os_mbuf *sdu_rx[cp->num]; + ble_addr_t *addr = (void *)&cp->address; + uint16_t mtu = le16toh(cp->mtu); + uint16_t psm = le16toh(cp->psm); int rc; int i, j; - bool ecfc = cmd->options & BTP_L2CAP_CONNECT_OPT_ECFC; - hold_credit = cmd->options & BTP_L2CAP_CONNECT_OPT_HOLD_CREDIT; + uint8_t status = BTP_STATUS_SUCCESS; + bool ecfc = cp->options & BTP_L2CAP_CONNECT_OPT_ECFC; + hold_credit = cp->options & BTP_L2CAP_CONNECT_OPT_HOLD_CREDIT; SYS_LOG_DBG("connect: type: %d addr: %s", addr->type, string_from_bytes(addr->val, 6)); - if (mtu == 0 || mtu > TESTER_COC_MTU) { - mtu = TESTER_COC_MTU; + rc = ble_gap_conn_find_by_addr(addr, &desc); + if (cp->num == 0 || cp->num > CHANNELS || + mtu > TESTER_COC_MTU || mtu == 0) { + return BTP_STATUS_FAILED; } - rc = ble_gap_conn_find_by_addr(addr, &desc); if (rc) { SYS_LOG_ERR("GAP conn find failed"); - goto fail; + return BTP_STATUS_FAILED; } - rp->num = cmd->num; - - for (i = 0; i < cmd->num; i++) { + for (i = 0; i < cp->num; i++) { chan = get_free_channel(); if (!chan) { SYS_LOG_ERR("No free channels"); - goto fail; + status = BTP_STATUS_FAILED; + goto done; } /* temporarily mark channel as used to select next one */ chan->state = 1; @@ -445,186 +446,203 @@ connect(uint8_t *data, uint16_t len) sdu_rx[i] = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); if (sdu_rx[i] == NULL) { SYS_LOG_ERR("Failed to alloc buf"); - goto fail; - } - } - - /* mark selected channels as unused again */ - for (i = 0; i < cmd->num; i++) { - for (j = 0; j < CHANNELS; j++) { - if (rp->chan_ids[i] == channels[j].chan_id) { - channels[j].state = 0; - } + status = BTP_STATUS_FAILED; + goto done; } } - if (cmd->num == 1 && !ecfc) { - rc = ble_l2cap_connect(desc.conn_handle, htole16(cmd->psm), + if (cp->num == 1 && !ecfc) { + rc = ble_l2cap_connect(desc.conn_handle, psm, mtu, sdu_rx[0], tester_l2cap_event, NULL); } else if (ecfc) { rc = ble_l2cap_enhanced_connect(desc.conn_handle, - htole16(cmd->psm), mtu, - cmd->num, sdu_rx, + psm, mtu, + cp->num, sdu_rx, tester_l2cap_event, NULL); } else { SYS_LOG_ERR("Invalid 'num' parameter value"); - goto fail; + status = BTP_STATUS_FAILED; + goto done; } if (rc) { SYS_LOG_ERR("L2CAP connect failed\n"); - goto fail; + status = BTP_STATUS_FAILED; + goto done; } - tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CONNECT, - (uint8_t *) rp, sizeof(rp_buf)); + rp->num = cp->num; - return; + *rsp_len = sizeof(*rp) + (rp->num * sizeof(rp->chan_ids[0])); +done: + /* mark selected channels as unused again */ + for (i = 0; i < cp->num; i++) { + for (j = 0; j < CHANNELS; j++) { + if (rp->chan_ids[i] == channels[j].chan_id) { + channels[j].state = 0; + } + } + } -fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CONNECT, - BTP_STATUS_FAILED); + return status; } -static void -disconnect(const uint8_t *data, uint16_t len) +static uint8_t +disconnect(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_l2cap_disconnect_cmd *cmd = (void *) data; + const struct btp_l2cap_disconnect_cmd *cp = cmd; struct channel *chan; - uint8_t status; int err; SYS_LOG_DBG(""); - chan = get_channel(cmd->chan_id); + if (cp->chan_id >= CHANNELS) { + return BTP_STATUS_FAILED; + } + + chan = get_channel(cp->chan_id); assert(chan != NULL); err = ble_l2cap_disconnect(chan->chan); if (err) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } - status = BTP_STATUS_SUCCESS; - -rsp: - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_DISCONNECT, - status); + return BTP_STATUS_SUCCESS; } -static void -send_data(const uint8_t *data, uint16_t len) +static uint8_t +send_data(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_l2cap_send_data_cmd *cmd = (void *) data; + const struct btp_l2cap_send_data_cmd *cp = cmd; + struct channel *chan; struct os_mbuf *sdu_tx = NULL; int rc; - uint16_t data_len = le16toh(cmd->data_len); - struct channel *chan = get_channel(cmd->chan_id); + uint16_t data_len; - SYS_LOG_DBG("cmd->chan_id=%d", cmd->chan_id); + SYS_LOG_DBG("cmd->chan_id=%d", cp->chan_id); + + if (cmd_len < sizeof(*cp) || + cmd_len != sizeof(*cp) + le16toh(cp->data_len)) { + return BTP_STATUS_FAILED; + } + + if (cp->chan_id >= CHANNELS) { + return BTP_STATUS_FAILED; + } + + chan = get_channel(cp->chan_id); + data_len = le16toh(cp->data_len); if (!chan) { SYS_LOG_ERR("Invalid channel\n"); - goto fail; + return BTP_STATUS_FAILED; } /* FIXME: For now, fail if data length exceeds buffer length */ if (data_len > TESTER_COC_MTU) { SYS_LOG_ERR("Data length exceeds buffer length"); - goto fail; + return BTP_STATUS_FAILED; } sdu_tx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); if (sdu_tx == NULL) { SYS_LOG_ERR("No memory in the test sdu pool\n"); + rc = BLE_HS_ENOMEM; goto fail; } - os_mbuf_append(sdu_tx, cmd->data, data_len); + os_mbuf_append(sdu_tx, cp->data, data_len); /* ble_l2cap_send takes ownership of the sdu */ rc = ble_l2cap_send(chan->chan, sdu_tx); if (rc == 0 || rc == BLE_HS_ESTALLED) { - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, - BTP_STATUS_SUCCESS); - return; + return BTP_STATUS_SUCCESS; } +fail: SYS_LOG_ERR("Unable to send data: %d", rc); os_mbuf_free_chain(sdu_tx); -fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, - BTP_STATUS_FAILED); + return BTP_STATUS_FAILED; } -static void -listen(const uint8_t *data, uint16_t len) +static uint8_t +listen(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_l2cap_listen_cmd *cmd = (void *) data; - uint16_t mtu = htole16(cmd->mtu); + const struct btp_l2cap_listen_cmd *cp = cmd; + uint16_t mtu = htole16(cp->mtu); + uint16_t psm = htole16(cp->psm); int rc; SYS_LOG_DBG(""); + if (psm == 0) { + return BTP_STATUS_FAILED; + } + if (mtu == 0 || mtu > TESTER_COC_MTU) { mtu = TESTER_COC_MTU; } - /* TODO: Handle cmd->transport flag */ - rc = ble_l2cap_create_server(cmd->psm, mtu, tester_l2cap_event, NULL); - if (rc) { - goto fail; + /* We do not support BR/EDR transport */ + if (cp->transport == 0) { + return BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_LISTEN, - BTP_STATUS_SUCCESS); - return; + rc = ble_l2cap_create_server(psm, mtu, tester_l2cap_event, NULL); + if (rc) { + return BTP_STATUS_FAILED; + } -fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_LISTEN, - BTP_STATUS_FAILED); + return BTP_STATUS_SUCCESS; } -static void -credits(uint8_t *data, uint16_t len) +static uint8_t +credits(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_l2cap_credits_cmd *cmd = (void *) data; + const struct btp_l2cap_credits_cmd *cp = cmd; + struct channel *chan; struct os_mbuf *sdu; int rc; - struct channel *channel = get_channel(cmd->chan_id); - if (channel == NULL) { - goto fail; + if (cp->chan_id >= CHANNELS) { + return BTP_STATUS_FAILED; + } + + chan = get_channel(cp->chan_id); + if (chan == NULL) { + return BTP_STATUS_FAILED; } sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); if (sdu == NULL) { os_mbuf_free_chain(sdu); - goto fail; + return BTP_STATUS_FAILED; } - rc = ble_l2cap_recv_ready(channel->chan, sdu); + rc = ble_l2cap_recv_ready(chan->chan, sdu); if (rc != 0) { - goto fail; + return BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CREDITS, - BTP_STATUS_SUCCESS); - return; -fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_CREDITS, - BTP_STATUS_FAILED); + + return BTP_STATUS_SUCCESS; } -static void -reconfigure(const uint8_t *data, uint16_t len) +static uint8_t +reconfigure(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_l2cap_reconfigure_cmd *cmd = (void *) data; - uint16_t mtu = htole16(cmd->mtu); + const struct btp_l2cap_reconfigure_cmd *cp = cmd; + uint16_t mtu = le16toh(cp->mtu); struct ble_gap_conn_desc desc; - ble_addr_t *addr = (void *) data; - struct ble_l2cap_chan *chans[cmd->num]; + ble_addr_t *addr = (ble_addr_t *)&cp->address; + struct ble_l2cap_chan *chans[cp->num]; struct channel *channel; int rc; int i; @@ -638,82 +656,96 @@ reconfigure(const uint8_t *data, uint16_t len) rc = ble_gap_conn_find_by_addr(addr, &desc); if (rc) { SYS_LOG_ERR("GAP conn find failed"); - goto fail; + return BTP_STATUS_FAILED; + } + + if (cmd_len < sizeof(*cp) || + cmd_len != sizeof(*cp) + cp->num) { + return BTP_STATUS_FAILED; } - for (i = 0; i < cmd->num; ++i) { - channel = get_channel(cmd->idxs[i]); + if (cp->num > CHANNELS) { + return BTP_STATUS_FAILED; + } + + mtu = le16toh(cp->mtu); + if (mtu > TESTER_COC_MTU) { + return BTP_STATUS_FAILED; + } + + for (i = 0; i < cp->num; ++i) { + channel = get_channel(cp->idxs[i]); if (channel == NULL) { - goto fail; + return BTP_STATUS_FAILED; } chans[i] = channel->chan; } - rc = ble_l2cap_reconfig(chans, cmd->num, mtu); + rc = ble_l2cap_reconfig(chans, cp->num, mtu); if (rc) { - goto fail; + return BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_RECONFIGURE, - BTP_STATUS_SUCCESS); - return; - -fail: - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_RECONFIGURE, - BTP_STATUS_FAILED); + return BTP_STATUS_SUCCESS; } -static void -supported_commands(uint8_t *data, uint16_t len) +static uint8_t +supported_commands(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - uint8_t cmds[1]; - struct btp_l2cap_read_supported_commands_rp *rp = (void *) cmds; + struct btp_l2cap_read_supported_commands_rp *rp = rsp; + + /* octet 0 */ + tester_set_bit(rp->data, BTP_L2CAP_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_L2CAP_CONNECT); + tester_set_bit(rp->data, BTP_L2CAP_DISCONNECT); + tester_set_bit(rp->data, BTP_L2CAP_SEND_DATA); + tester_set_bit(rp->data, BTP_L2CAP_LISTEN); + /* octet 1 */ + tester_set_bit(rp->data, BTP_L2CAP_CREDITS); + *rsp_len = sizeof(*rp) + 2; - memset(cmds, 0, sizeof(cmds)); - - tester_set_bit(cmds, BTP_L2CAP_READ_SUPPORTED_COMMANDS); - tester_set_bit(cmds, BTP_L2CAP_CONNECT); - tester_set_bit(cmds, BTP_L2CAP_DISCONNECT); - tester_set_bit(cmds, BTP_L2CAP_LISTEN); - tester_set_bit(cmds, BTP_L2CAP_SEND_DATA); - tester_set_bit(cmds, BTP_L2CAP_RECONFIGURE); - - tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_READ_SUPPORTED_COMMANDS, - (uint8_t *) rp, sizeof(cmds)); + return BTP_STATUS_SUCCESS; } -void -tester_handle_l2cap(uint8_t opcode, uint8_t *data, - uint16_t len) -{ - switch (opcode) { - case BTP_L2CAP_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - return; - case BTP_L2CAP_CONNECT: - connect(data, len); - return; - case BTP_L2CAP_DISCONNECT: - disconnect(data, len); - return; - case BTP_L2CAP_SEND_DATA: - send_data(data, len); - return; - case BTP_L2CAP_LISTEN: - listen(data, len); - return; - case BTP_L2CAP_RECONFIGURE: - reconfigure(data, len); - return; - case BTP_L2CAP_CREDITS: - credits(data, len); - return; - default: - tester_rsp(BTP_SERVICE_ID_L2CAP, opcode, - BTP_STATUS_UNKNOWN_CMD); - return; - } -} +static const struct btp_handler handlers[] = { + { + .opcode = BTP_L2CAP_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = supported_commands, + }, + { + .opcode = BTP_L2CAP_CONNECT, + .expect_len = sizeof(struct btp_l2cap_connect_cmd), + .func = connect, + }, + { + .opcode = BTP_L2CAP_DISCONNECT, + .expect_len = sizeof(struct btp_l2cap_disconnect_cmd), + .func = disconnect, + }, + { + .opcode = BTP_L2CAP_SEND_DATA, + .expect_len = -1, + .func = send_data, + }, + { + .opcode = BTP_L2CAP_LISTEN, + .expect_len = sizeof(struct btp_l2cap_listen_cmd), + .func = listen, + }, + { + .opcode = BTP_L2CAP_RECONFIGURE, + .expect_len = -1, + .func = reconfigure, + }, + { + .opcode = BTP_L2CAP_CREDITS, + .expect_len = sizeof(struct btp_l2cap_credits_cmd), + .func = credits, + }, +}; uint8_t tester_init_l2cap(void) @@ -730,6 +762,9 @@ tester_init_l2cap(void) TESTER_COC_MTU, TESTER_COC_BUF_COUNT); assert(rc == 0); + tester_register_command_handlers(BTP_SERVICE_ID_L2CAP, handlers, + ARRAY_SIZE(handlers)); + return BTP_STATUS_SUCCESS; } From 8abb2ecef8a0589957a192315f4773b9e5e52e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 12 Jul 2023 12:21:16 +0200 Subject: [PATCH 0760/1333] apps/bttester: refactor Mesh service Accomodate to new API. --- apps/bttester/src/btp/bttester.h | 2 - apps/bttester/src/btp_mesh.c | 545 +++++++++++++++++-------------- 2 files changed, 301 insertions(+), 246 deletions(-) diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h index 4112a51307..0c8db52a46 100644 --- a/apps/bttester/src/btp/bttester.h +++ b/apps/bttester/src/btp/bttester.h @@ -127,8 +127,6 @@ uint8_t tester_init_mesh(void); uint8_t tester_unregister_mesh(void); -void -tester_handle_mesh(uint8_t opcode, uint8_t *data, uint16_t len); #endif /* MYNEWT_VAL(BLE_MESH) */ void diff --git a/apps/bttester/src/btp_mesh.c b/apps/bttester/src/btp_mesh.c index 7642f8ea7f..3b9054a813 100644 --- a/apps/bttester/src/btp_mesh.c +++ b/apps/bttester/src/btp_mesh.c @@ -84,42 +84,40 @@ static struct { .dst = BT_MESH_ADDR_UNASSIGNED, }; -static void -supported_commands(uint8_t *data, uint16_t len) +static uint8_t +supported_commands(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - struct os_mbuf *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE); - - net_buf_simple_init(buf, 0); - - /* 1st octet */ - memset(net_buf_simple_add(buf, 1), 0, 1); - tester_set_bit(buf->om_data, BTP_MESH_READ_SUPPORTED_COMMANDS); - tester_set_bit(buf->om_data, BTP_MESH_CONFIG_PROVISIONING); - tester_set_bit(buf->om_data, BTP_MESH_PROVISION_NODE); - tester_set_bit(buf->om_data, BTP_MESH_INIT); - tester_set_bit(buf->om_data, BTP_MESH_RESET); - tester_set_bit(buf->om_data, BTP_MESH_INPUT_NUMBER); - tester_set_bit(buf->om_data, BTP_MESH_INPUT_STRING); - /* 2nd octet */ - tester_set_bit(buf->om_data, BTP_MESH_IVU_TEST_MODE); - tester_set_bit(buf->om_data, BTP_MESH_IVU_TOGGLE_STATE); - tester_set_bit(buf->om_data, BTP_MESH_NET_SEND); - tester_set_bit(buf->om_data, BTP_MESH_HEALTH_GENERATE_FAULTS); - tester_set_bit(buf->om_data, BTP_MESH_HEALTH_CLEAR_FAULTS); - tester_set_bit(buf->om_data, BTP_MESH_LPN); - tester_set_bit(buf->om_data, BTP_MESH_LPN_POLL); - tester_set_bit(buf->om_data, BTP_MESH_MODEL_SEND); - /* 3rd octet */ - memset(net_buf_simple_add(buf, 1), 0, 1); + struct btp_mesh_read_supported_commands_rp *rp = rsp; + + /* octet 0 */ + tester_set_bit(rp->data, BTP_MESH_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_MESH_CONFIG_PROVISIONING); + tester_set_bit(rp->data, BTP_MESH_PROVISION_NODE); + tester_set_bit(rp->data, BTP_MESH_INIT); + tester_set_bit(rp->data, BTP_MESH_RESET); + tester_set_bit(rp->data, BTP_MESH_INPUT_NUMBER); + tester_set_bit(rp->data, BTP_MESH_INPUT_STRING); + /* octet 1 */ + tester_set_bit(rp->data, BTP_MESH_IVU_TEST_MODE); + tester_set_bit(rp->data, BTP_MESH_IVU_TOGGLE_STATE); + tester_set_bit(rp->data, BTP_MESH_NET_SEND); + tester_set_bit(rp->data, BTP_MESH_HEALTH_GENERATE_FAULTS); + tester_set_bit(rp->data, BTP_MESH_HEALTH_CLEAR_FAULTS); + tester_set_bit(rp->data, BTP_MESH_LPN); + tester_set_bit(rp->data, BTP_MESH_LPN_POLL); + tester_set_bit(rp->data, BTP_MESH_MODEL_SEND); + /* octet 2 */ #if MYNEWT_VAL(BLE_MESH_TESTING) - tester_set_bit(buf->om_data, BTP_MESH_LPN_SUBSCRIBE); - tester_set_bit(buf->om_data, BTP_MESH_LPN_UNSUBSCRIBE); - tester_set_bit(buf->om_data, BTP_MESH_RPL_CLEAR); + tester_set_bit(rp->data, BTP_MESH_LPN_SUBSCRIBE); + tester_set_bit(rp->data, BTP_MESH_LPN_UNSUBSCRIBE); + tester_set_bit(rp->data, BTP_MESH_RPL_CLEAR); #endif /* CONFIG_BT_TESTING */ - tester_set_bit(buf->om_data, BTP_MESH_PROXY_IDENTITY); + tester_set_bit(rp->data, BTP_MESH_PROXY_IDENTITY); - tester_send_buf(BTP_SERVICE_ID_MESH, BTP_MESH_READ_SUPPORTED_COMMANDS, - CONTROLLER_INDEX, buf); + *rsp_len = sizeof(*rp) + 3; + + return BTP_STATUS_SUCCESS; } static void @@ -410,153 +408,161 @@ static struct bt_mesh_prov prov = { .reset = prov_reset, }; -static void -config_prov(uint8_t *data, uint16_t len) +static uint8_t +config_prov(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_mesh_config_provisioning_cmd *cmd = (void *) data; + const struct btp_mesh_config_provisioning_cmd *cp = cmd; SYS_LOG_DBG(""); - memcpy(dev_uuid, cmd->uuid, sizeof(dev_uuid)); - memcpy(static_auth, cmd->static_auth, sizeof(static_auth)); + if (cmd_len < sizeof(*cp)) { + return BTP_STATUS_FAILED; + } + + memcpy(dev_uuid, cp->uuid, sizeof(dev_uuid)); + memcpy(static_auth, cp->static_auth, sizeof(static_auth)); - prov.output_size = cmd->out_size; - prov.output_actions = sys_le16_to_cpu(cmd->out_actions); - prov.input_size = cmd->in_size; - prov.input_actions = sys_le16_to_cpu(cmd->in_actions); + prov.output_size = cp->out_size; + prov.output_actions = sys_le16_to_cpu(cp->out_actions); + prov.input_size = cp->in_size; + prov.input_actions = sys_le16_to_cpu(cp->in_actions); - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_CONFIG_PROVISIONING, - BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } -static void -provision_node(uint8_t *data, uint16_t len) +static uint8_t +provision_node(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_mesh_provision_node_cmd *cmd = (void *) data; + const struct btp_mesh_provision_node_cmd *cp = cmd; SYS_LOG_DBG(""); - memcpy(dev_key, cmd->dev_key, sizeof(dev_key)); - memcpy(net_key, cmd->net_key, sizeof(net_key)); + if (cmd_len != sizeof(*cp)) { + return BTP_STATUS_FAILED; + } + + memcpy(dev_key, cp->dev_key, sizeof(dev_key)); + memcpy(net_key, cp->net_key, sizeof(net_key)); - addr = sys_le16_to_cpu(cmd->addr); - flags = cmd->flags; - iv_index = le32toh(cmd->iv_index); - net_key_idx = sys_le16_to_cpu(cmd->net_key_idx); + addr = sys_le16_to_cpu(cp->addr); + flags = cp->flags; + iv_index = le32toh(cp->iv_index); + net_key_idx = sys_le16_to_cpu(cp->net_key_idx); - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_PROVISION_NODE, - BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } -static void -init(uint8_t *data, uint16_t len) +static uint8_t +init(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - uint8_t status = BTP_STATUS_SUCCESS; int err; SYS_LOG_DBG(""); err = bt_mesh_init(own_addr_type, &prov, &comp); if (err) { - status = BTP_STATUS_FAILED; - - goto rsp; + return BTP_STATUS_FAILED; } if (addr) { err = bt_mesh_provision(net_key, net_key_idx, flags, iv_index, addr, dev_key); if (err) { - status = BTP_STATUS_FAILED; + return BTP_STATUS_FAILED; } } else { err = bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); if (err) { - status = BTP_STATUS_FAILED; + return BTP_STATUS_FAILED; } } -rsp: - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_INIT, status); + return BTP_STATUS_SUCCESS; } -static void -reset(uint8_t *data, uint16_t len) +static uint8_t +reset(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { SYS_LOG_DBG(""); bt_mesh_reset(); - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_RESET, - BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } -static void -input_number(uint8_t *data, uint16_t len) +static uint8_t +input_number(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_mesh_input_number_cmd *cmd = (void *) data; - uint8_t status = BTP_STATUS_SUCCESS; + const struct btp_mesh_input_number_cmd *cp = cmd; uint32_t number; int err; - number = le32toh(cmd->number); + number = le32toh(cp->number); SYS_LOG_DBG("number 0x%04lx", number); err = bt_mesh_input_number(number); if (err) { - status = BTP_STATUS_FAILED; + return BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_INPUT_NUMBER, status); + return BTP_STATUS_SUCCESS; } -static void -input_string(uint8_t *data, uint16_t len) +static uint8_t +input_string(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_mesh_input_string_cmd *cmd = (void *) data; - uint8_t status = BTP_STATUS_SUCCESS; - uint8_t str_auth[16]; + const struct btp_mesh_input_string_cmd *cp = cmd; int err; SYS_LOG_DBG(""); - if (cmd->string_len > sizeof(str_auth)) { - SYS_LOG_ERR("Too long input (%u chars required)", input_size); - status = BTP_STATUS_FAILED; - goto rsp; - } else if (cmd->string_len < input_size) { - SYS_LOG_ERR("Too short input (%u chars required)", input_size); - status = BTP_STATUS_FAILED; - goto rsp; + if (cmd_len < sizeof(*cp) && + cmd_len != (sizeof(*cp) + cp->string_len)) { + return BTP_STATUS_FAILED; } - strncpy((char *) str_auth, (char *) cmd->string, cmd->string_len); + /* for historical reasons this commands must send NULL terminated + * string + */ + if (cp->string[cp->string_len] != '\0') { + return BTP_STATUS_FAILED; + } - err = bt_mesh_input_string((char *) str_auth); + if (strlen((char *)cp->string) < input_size) { + SYS_LOG_ERR("Too short input (%u chars required)", input_size); + return BTP_STATUS_FAILED; + } + err = bt_mesh_input_string((char *)cp->string); if (err) { - status = BTP_STATUS_FAILED; + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_INPUT_STRING, status); + return BTP_STATUS_SUCCESS; } -static void -ivu_test_mode(uint8_t *data, uint16_t len) +static uint8_t +ivu_test_mode(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_mesh_ivu_test_mode_cmd *cmd = (void *) data; + const struct btp_mesh_ivu_test_mode_cmd *cp = cmd; - SYS_LOG_DBG("enable 0x%02x", cmd->enable); + SYS_LOG_DBG("enable 0x%02x", cp->enable); - bt_mesh_iv_update_test(cmd->enable ? true : false); + bt_mesh_iv_update_test(cp->enable ? true : false); - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_IVU_TEST_MODE, - BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } -static void -ivu_toggle_state(uint8_t *data, uint16_t len) +static uint8_t +ivu_toggle_state(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { bool result; @@ -565,33 +571,35 @@ ivu_toggle_state(uint8_t *data, uint16_t len) result = bt_mesh_iv_update(); if (!result) { SYS_LOG_ERR("Failed to toggle the IV Update state"); + return BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_IVU_TOGGLE_STATE, - result ? BTP_STATUS_SUCCESS : BTP_STATUS_FAILED); + return BTP_STATUS_SUCCESS; } -static void -lpn(uint8_t *data, uint16_t len) +static uint8_t +lpn(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - struct btp_mesh_lpn_set_cmd *cmd = (void *) data; + const struct btp_mesh_lpn_set_cmd *cp = cmd; bool enable; int err; - SYS_LOG_DBG("enable 0x%02x", cmd->enable); + SYS_LOG_DBG("enable 0x%02x", cp->enable); - enable = cmd->enable ? true : false; + enable = cp->enable ? true : false; err = bt_mesh_lpn_set(enable); if (err) { SYS_LOG_ERR("Failed to toggle LPN (err %d)", err); + return BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } -static void -lpn_poll(uint8_t *data, uint16_t len) +static uint8_t +lpn_poll(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { int err; @@ -600,27 +608,34 @@ lpn_poll(uint8_t *data, uint16_t len) err = bt_mesh_lpn_poll(); if (err) { SYS_LOG_ERR("Failed to send poll msg (err %d)", err); + return BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN_POLL, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } -static void -net_send(uint8_t *data, uint16_t len) +static uint8_t +net_send(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - struct btp_mesh_net_send_cmd *cmd = (void *) data; + const struct btp_mesh_net_send_cmd *cp = cmd; struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); struct bt_mesh_msg_ctx ctx = { .net_idx = net.net_idx, .app_idx = vnd_app_key_idx, - .addr = sys_le16_to_cpu(cmd->dst), - .send_ttl = cmd->ttl, + .addr = sys_le16_to_cpu(cp->dst), + .send_ttl = cp->ttl, }; int err; + int status = BTP_STATUS_SUCCESS; + + if (cmd_len < sizeof(*cp) && + cmd_len != (sizeof(*cp) + cp->payload_len)) { + return BTP_STATUS_FAILED; + } SYS_LOG_DBG("ttl 0x%02x dst 0x%04x payload_len %d", ctx.send_ttl, - ctx.addr, cmd->payload_len); + ctx.addr, cp->payload_len); if (!bt_mesh_app_key_exists(vnd_app_key_idx)) { (void) bt_mesh_app_key_add(vnd_app_key_idx, net.net_idx, @@ -628,48 +643,47 @@ net_send(uint8_t *data, uint16_t len) vnd_models[0].keys[0] = vnd_app_key_idx; } - net_buf_simple_add_mem(msg, cmd->payload, cmd->payload_len); + net_buf_simple_add_mem(msg, cp->payload, cp->payload_len); err = bt_mesh_model_send(&vnd_models[0], &ctx, msg, NULL, NULL); if (err) { SYS_LOG_ERR("Failed to send (err %d)", err); + status = BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_NET_SEND, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); - os_mbuf_free_chain(msg); + + return status; } -static void -health_generate_faults(uint8_t *data, uint16_t len) +static uint8_t +health_generate_faults(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - struct btp_mesh_health_generate_faults_rp *rp; - struct os_mbuf *buf = NET_BUF_SIMPLE(sizeof(*rp) + sizeof(cur_faults) + - sizeof(reg_faults)); + struct btp_mesh_health_generate_faults_rp *rp = rsp; uint8_t some_faults[] = {0x01, 0x02, 0x03, 0xff, 0x06}; uint8_t cur_faults_count, reg_faults_count; - rp = net_buf_simple_add(buf, sizeof(*rp)); - cur_faults_count = min(sizeof(cur_faults), sizeof(some_faults)); memcpy(cur_faults, some_faults, cur_faults_count); - net_buf_simple_add_mem(buf, cur_faults, cur_faults_count); + memcpy(rp->current_faults, cur_faults, cur_faults_count); rp->cur_faults_count = cur_faults_count; reg_faults_count = min(sizeof(reg_faults), sizeof(some_faults)); memcpy(reg_faults, some_faults, reg_faults_count); - net_buf_simple_add_mem(buf, reg_faults, reg_faults_count); + memcpy(rp->registered_faults + cur_faults_count, reg_faults, reg_faults_count); rp->reg_faults_count = reg_faults_count; bt_mesh_fault_update(&elements[0]); - tester_send_buf(BTP_SERVICE_ID_MESH, BTP_MESH_HEALTH_GENERATE_FAULTS, - CONTROLLER_INDEX, buf); + *rsp_len = sizeof(*rp) + cur_faults_count + reg_faults_count; + + return BTP_STATUS_SUCCESS; } -static void -health_clear_faults(uint8_t *data, uint16_t len) +static uint8_t +health_clear_faults(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { SYS_LOG_DBG(""); @@ -678,24 +692,33 @@ health_clear_faults(uint8_t *data, uint16_t len) bt_mesh_fault_update(&elements[0]); - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_HEALTH_CLEAR_FAULTS, - BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } -static void -model_send(uint8_t *data, uint16_t len) +static uint8_t +model_send(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - struct btp_mesh_model_send_cmd *cmd = (void *) data; + const struct btp_mesh_model_send_cmd *cp = cmd; struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX); + struct bt_mesh_model *model = NULL; + int err, i; + uint16_t src; + int status = BTP_STATUS_SUCCESS; + + if (cmd_len < sizeof(*cp) && + cmd_len != (sizeof(*cp) + cp->payload_len)) { + return BTP_STATUS_FAILED; + } + struct bt_mesh_msg_ctx ctx = { .net_idx = net.net_idx, .app_idx = BT_MESH_KEY_DEV, - .addr = sys_le16_to_cpu(cmd->dst), + .addr = sys_le16_to_cpu(cp->dst), .send_ttl = BT_MESH_TTL_DEFAULT, }; - struct bt_mesh_model *model = NULL; - int err, i; - uint16_t src = sys_le16_to_cpu(cmd->src); + + src = sys_le16_to_cpu(cp->src); /* Lookup source address */ for (i = 0; i < ARRAY_SIZE(model_bound); i++) { @@ -709,35 +732,35 @@ model_send(uint8_t *data, uint16_t len) if (!model) { SYS_LOG_ERR("Model not found"); - err = -EINVAL; + status = BTP_STATUS_FAILED; - goto fail; + goto rsp; } SYS_LOG_DBG("src 0x%04x dst 0x%04x model %p payload_len %d", src, - ctx.addr, model, cmd->payload_len); + ctx.addr, model, cp->payload_len); - net_buf_simple_add_mem(msg, cmd->payload, cmd->payload_len); + net_buf_simple_add_mem(msg, cp->payload, cp->payload_len); err = bt_mesh_model_send(model, &ctx, msg, NULL, NULL); if (err) { SYS_LOG_ERR("Failed to send (err %d)", err); + status = BTP_STATUS_FAILED; } -fail: - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_MODEL_SEND, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); - +rsp: os_mbuf_free_chain(msg); + return status; } #if MYNEWT_VAL(BLE_MESH_TESTING) -static void -lpn_subscribe(uint8_t *data, uint16_t len) +static uint8_t +lpn_subscribe(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - struct btp_mesh_lpn_subscribe_cmd *cmd = (void *) data; - uint16_t address = sys_le16_to_cpu(cmd->address); + const struct btp_mesh_lpn_subscribe_cmd *cp = cmd; + uint16_t address = sys_le16_to_cpu(cp->address); int err; SYS_LOG_DBG("address 0x%04x", address); @@ -747,15 +770,15 @@ lpn_subscribe(uint8_t *data, uint16_t len) SYS_LOG_ERR("Failed to subscribe (err %d)", err); } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN_SUBSCRIBE, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } -static void -lpn_unsubscribe(uint8_t *data, uint16_t len) +static uint8_t +lpn_unsubscribe(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - struct btp_mesh_lpn_unsubscribe_cmd *cmd = (void *) data; - uint16_t address = sys_le16_to_cpu(cmd->address); + const struct btp_mesh_lpn_unsubscribe_cmd *cp = cmd; + uint16_t address = sys_le16_to_cpu(cp->address); int err; SYS_LOG_DBG("address 0x%04x", address); @@ -763,14 +786,15 @@ lpn_unsubscribe(uint8_t *data, uint16_t len) err = bt_test_mesh_lpn_group_remove(&address, 1); if (err) { SYS_LOG_ERR("Failed to unsubscribe (err %d)", err); + return BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_LPN_UNSUBSCRIBE, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } -static void -rpl_clear(uint8_t *data, uint16_t len) +static uint8_t +rpl_clear(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { int err; @@ -779,16 +803,17 @@ rpl_clear(uint8_t *data, uint16_t len) err = bt_test_mesh_rpl_clear(); if (err) { SYS_LOG_ERR("Failed to clear RPL (err %d)", err); + return BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_RPL_CLEAR, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } #endif /* MYNEWT_VAL(BLE_MESH_TESTING) */ -static void -proxy_identity_enable(uint8_t *data, uint16_t len) +static uint8_t +proxy_identity_enable(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { int err; @@ -797,81 +822,110 @@ proxy_identity_enable(uint8_t *data, uint16_t len) err = bt_mesh_proxy_identity_enable(); if (err) { SYS_LOG_ERR("Failed to enable proxy identity (err %d)", err); + return BTP_STATUS_FAILED; } - tester_rsp(BTP_SERVICE_ID_MESH, BTP_MESH_PROXY_IDENTITY, - err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS); + return BTP_STATUS_SUCCESS; } -void -tester_handle_mesh(uint8_t opcode, uint8_t *data, uint16_t len) -{ - switch (opcode) { - case BTP_MESH_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - break; - case BTP_MESH_CONFIG_PROVISIONING: - config_prov(data, len); - break; - case BTP_MESH_PROVISION_NODE: - provision_node(data, len); - break; - case BTP_MESH_INIT: - init(data, len); - break; - case BTP_MESH_RESET: - reset(data, len); - break; - case BTP_MESH_INPUT_NUMBER: - input_number(data, len); - break; - case BTP_MESH_INPUT_STRING: - input_string(data, len); - break; - case BTP_MESH_IVU_TEST_MODE: - ivu_test_mode(data, len); - break; - case BTP_MESH_IVU_TOGGLE_STATE: - ivu_toggle_state(data, len); - break; - case BTP_MESH_LPN: - lpn(data, len); - break; - case BTP_MESH_LPN_POLL: - lpn_poll(data, len); - break; - case BTP_MESH_NET_SEND: - net_send(data, len); - break; - case BTP_MESH_HEALTH_GENERATE_FAULTS: - health_generate_faults(data, len); - break; - case BTP_MESH_HEALTH_CLEAR_FAULTS: - health_clear_faults(data, len); - break; - case BTP_MESH_MODEL_SEND: - model_send(data, len); - break; -#if MYNEWT_VAL(BLE_MESH_TESTING) - case BTP_MESH_LPN_SUBSCRIBE: - lpn_subscribe(data, len); - break; - case BTP_MESH_LPN_UNSUBSCRIBE: - lpn_unsubscribe(data, len); - break; - case BTP_MESH_RPL_CLEAR: - rpl_clear(data, len); - break; -#endif /* MYNEWT_VAL(BLE_MESH_TESTING) */ - case BTP_MESH_PROXY_IDENTITY: - proxy_identity_enable(data, len); - break; - default: - tester_rsp(BTP_SERVICE_ID_MESH, opcode, - BTP_STATUS_UNKNOWN_CMD); - break; - } -} +static const struct btp_handler handlers[] = { + { + .opcode = BTP_MESH_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = supported_commands, + }, + { + .opcode = BTP_MESH_CONFIG_PROVISIONING, + .expect_len = -1, + .func = config_prov, + }, + { + .opcode = BTP_MESH_PROVISION_NODE, + .expect_len = -1, + .func = provision_node, + }, + { + .opcode = BTP_MESH_INIT, + .expect_len = 0, + .func = init, + }, + { + .opcode = BTP_MESH_RESET, + .expect_len = 0, + .func = reset, + }, + { + .opcode = BTP_MESH_INPUT_NUMBER, + .expect_len = sizeof(struct btp_mesh_input_number_cmd), + .func = input_number, + }, + { + .opcode = BTP_MESH_INPUT_STRING, + .expect_len = -1, + .func = input_string, + }, + { + .opcode = BTP_MESH_IVU_TEST_MODE, + .expect_len = sizeof(struct btp_mesh_ivu_test_mode_cmd), + .func = ivu_test_mode, + }, + { + .opcode = BTP_MESH_IVU_TOGGLE_STATE, + .expect_len = 0, + .func = ivu_toggle_state, + }, + { + .opcode = BTP_MESH_LPN, + .expect_len = sizeof(struct btp_mesh_lpn_set_cmd), + .func = lpn, + }, + { + .opcode = BTP_MESH_LPN_POLL, + .expect_len = 0, + .func = lpn_poll, + }, + { + .opcode = BTP_MESH_NET_SEND, + .expect_len = -1, + .func = net_send, + }, + { + .opcode = BTP_MESH_HEALTH_GENERATE_FAULTS, + .expect_len = 0, + .func = health_generate_faults, + }, + { + .opcode = BTP_MESH_HEALTH_CLEAR_FAULTS, + .expect_len = 0, + .func = health_clear_faults, + }, + { + .opcode = BTP_MESH_MODEL_SEND, + .expect_len = -1, + .func = model_send, + }, + { + .opcode = BTP_MESH_LPN_SUBSCRIBE, + .expect_len = sizeof(struct btp_mesh_lpn_subscribe_cmd), + .func = lpn_subscribe, + }, + { + .opcode = BTP_MESH_LPN_UNSUBSCRIBE, + .expect_len = sizeof(struct btp_mesh_lpn_unsubscribe_cmd), + .func = lpn_unsubscribe, + }, + { + .opcode = BTP_MESH_RPL_CLEAR, + .expect_len = 0, + .func = rpl_clear, + }, + { + .opcode = BTP_MESH_PROXY_IDENTITY, + .expect_len = 0, + .func = proxy_identity_enable, + }, +}; void net_recv_ev(uint8_t ttl, @@ -1029,6 +1083,9 @@ tester_init_mesh(void) bt_test_cb_register(&bt_test_cb); } + tester_register_command_handlers(BTP_SERVICE_ID_MESH, handlers, + ARRAY_SIZE(handlers)); + return BTP_STATUS_SUCCESS; } From 7d25c1c71821ab15af415e0b26b5500d81825655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 13 Jul 2023 09:09:38 +0200 Subject: [PATCH 0761/1333] apps/bttester: refactor GATT Client service Accomodated to new API. --- apps/bttester/src/btp/btp_gattc.h | 3 + apps/bttester/src/btp/bttester.h | 8 +- apps/bttester/src/btp_core.c | 6 + apps/bttester/src/btp_gatt_cl.c | 676 ++++++++++++++++-------------- 4 files changed, 373 insertions(+), 320 deletions(-) diff --git a/apps/bttester/src/btp/btp_gattc.h b/apps/bttester/src/btp/btp_gattc.h index 7c642fdd67..76510b47af 100644 --- a/apps/bttester/src/btp/btp_gattc.h +++ b/apps/bttester/src/btp/btp_gattc.h @@ -34,6 +34,9 @@ struct btp_gattc_read_supported_commands_rp { } __packed; #define BTP_GATTC_EXCHANGE_MTU 0x02 +struct btp_gattc_exchange_mtu_cmd { + ble_addr_t address; +} __packed; #define BTP_GATTC_DISC_ALL_PRIM_SVCS 0x03 struct btp_gattc_disc_all_prim_svcs_cmd { diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h index 0c8db52a46..c986a7e97e 100644 --- a/apps/bttester/src/btp/bttester.h +++ b/apps/bttester/src/btp/bttester.h @@ -100,9 +100,6 @@ uint8_t tester_init_gatt(void); uint8_t tester_unregister_gatt(void); -void -tester_handle_gattc(uint8_t opcode, uint8_t *data, - uint16_t len); int tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, uint8_t indication, struct os_mbuf *om); @@ -128,7 +125,10 @@ tester_init_mesh(void); uint8_t tester_unregister_mesh(void); #endif /* MYNEWT_VAL(BLE_MESH) */ - +uint8_t +tester_init_gatt_cl(void); +uint8_t +tester_unregister_gatt_cl(void); void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); diff --git a/apps/bttester/src/btp_core.c b/apps/bttester/src/btp_core.c index fe1b8d4450..35dcd824b7 100644 --- a/apps/bttester/src/btp_core.c +++ b/apps/bttester/src/btp_core.c @@ -101,6 +101,9 @@ register_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_MESH: status = tester_init_mesh(); break; + case BTP_SERVICE_ID_GATTC: + status = tester_init_gatt_cl(); + break; #endif /* MYNEWT_VAL(BLE_MESH) */ default: status = BTP_STATUS_FAILED; @@ -148,6 +151,9 @@ unregister_service(const void *cmd, uint16_t cmd_len, status = tester_unregister_mesh(); break; #endif /* MYNEWT_VAL(BLE_MESH) */ + case BTP_SERVICE_ID_GATTC: + status = tester_unregister_gatt_cl(); + break; default: status = BTP_STATUS_FAILED; break; diff --git a/apps/bttester/src/btp_gatt_cl.c b/apps/bttester/src/btp_gatt_cl.c index 0ba494a10c..501c46030e 100644 --- a/apps/bttester/src/btp_gatt_cl.c +++ b/apps/bttester/src/btp_gatt_cl.c @@ -149,31 +149,28 @@ tester_mtu_exchanged_ev(uint16_t conn_handle, return 0; } -static void -exchange_mtu(uint8_t *data, uint16_t len) +static uint8_t +exchange_mtu(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { + const struct btp_gattc_exchange_mtu_cmd *cp = cmd; struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } if (ble_gattc_exchange_mtu(conn.conn_handle, tester_mtu_exchanged_ev, NULL)) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_EXCHANGE_MTU, - status); + return BTP_STATUS_SUCCESS; } static int @@ -253,65 +250,58 @@ disc_prim_svcs_cb(uint16_t conn_handle, return rc; } -static void -disc_all_prim_svcs(uint8_t *data, uint16_t len) +static uint8_t +disc_all_prim_svcs(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { + const struct btp_gattc_disc_all_prim_svcs_cmd *cp = cmd; struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } if (ble_gattc_disc_all_svcs(conn.conn_handle, disc_prim_svcs_cb, (void *) BTP_GATTC_DISC_ALL_PRIM_RP)) { discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_PRIM_SVCS, - status); + return BTP_STATUS_SUCCESS; } -static void -disc_prim_uuid(uint8_t *data, uint16_t len) +static uint8_t +disc_prim_uuid(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gattc_disc_prim_uuid_cmd *cmd = (void *) data; + const struct btp_gattc_disc_prim_uuid_cmd *cp = cmd; struct ble_gap_conn_desc conn; ble_uuid_any_t uuid; - uint8_t status = BTP_STATUS_SUCCESS; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } - if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { - status = BTP_STATUS_FAILED; - goto rsp; + if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid)) { + return BTP_STATUS_FAILED; } if (ble_gattc_disc_svc_by_uuid(conn.conn_handle, &uuid.u, disc_prim_svcs_cb, (void *) BTP_GATTC_DISC_PRIM_UUID_RP)) { discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_PRIM_UUID, status); + return BTP_STATUS_SUCCESS; } static int @@ -396,38 +386,35 @@ find_included_cb(uint16_t conn_handle, return rc; } -static void -find_included(uint8_t *data, uint16_t len) +static uint8_t +find_included(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gattc_find_included_cmd *cmd = (void *) data; + const struct btp_gattc_find_included_cmd *cp = cmd; struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; int service_handle_arg; - uint8_t status = BTP_STATUS_SUCCESS; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } - start_handle = le16toh(cmd->start_handle); - end_handle = le16toh(cmd->end_handle); + start_handle = le16toh(cp->start_handle); + end_handle = le16toh(cp->end_handle); service_handle_arg = start_handle; if (ble_gattc_find_inc_svcs(conn.conn_handle, start_handle, end_handle, find_included_cb, (void *) service_handle_arg)) { discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_FIND_INCLUDED, status); + return BTP_STATUS_SUCCESS; } static int @@ -512,26 +499,25 @@ disc_chrc_cb(uint16_t conn_handle, return rc; } -static void -disc_all_chrc(uint8_t *data, uint16_t len) +static uint8_t +disc_all_chrc(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gattc_disc_all_chrc_cmd *cmd = (void *) data; + const struct btp_gattc_disc_all_chrc_cmd *cp = cmd; struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; - uint8_t status = BTP_STATUS_SUCCESS; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { SYS_LOG_DBG("Conn find rsped"); - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } - start_handle = le16toh(cmd->start_handle); - end_handle = le16toh(cmd->end_handle); + start_handle = le16toh(cp->start_handle); + end_handle = le16toh(cp->end_handle); rc = ble_gattc_disc_all_chrs(conn.conn_handle, start_handle, @@ -540,51 +526,45 @@ disc_all_chrc(uint8_t *data, uint16_t len) (void *) BTP_GATTC_DISC_ALL_CHRC_RP); if (rc) { discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_CHRC, status); + return BTP_STATUS_SUCCESS; } -static void -disc_chrc_uuid(uint8_t *data, uint16_t len) +static uint8_t +disc_chrc_uuid(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gattc_disc_chrc_uuid_cmd *cmd = (void *) data; + const struct btp_gattc_disc_chrc_uuid_cmd *cp = cmd; struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; ble_uuid_any_t uuid; - uint8_t status = BTP_STATUS_SUCCESS; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } - if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { - status = BTP_STATUS_FAILED; - goto rsp; + if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid)) { + return BTP_STATUS_FAILED; } - start_handle = le16toh(cmd->start_handle); - end_handle = le16toh(cmd->end_handle); + start_handle = le16toh(cp->start_handle); + end_handle = le16toh(cp->end_handle); rc = ble_gattc_disc_chrs_by_uuid(conn.conn_handle, start_handle, end_handle, &uuid.u, disc_chrc_cb, (void *) BTP_GATTC_DISC_CHRC_UUID_RP); if (rc) { discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_CHRC_UUID, status); + return BTP_STATUS_SUCCESS; } static int @@ -665,25 +645,24 @@ disc_all_desc_cb(uint16_t conn_handle, return rc; } -static void -disc_all_desc(uint8_t *data, uint16_t len) +static uint8_t +disc_all_desc(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gattc_disc_all_desc_cmd *cmd = (void *) data; + const struct btp_gattc_disc_all_desc_cmd *cp = cmd; struct ble_gap_conn_desc conn; uint16_t start_handle, end_handle; - uint8_t status = BTP_STATUS_SUCCESS; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } - start_handle = le16toh(cmd->start_handle) - 1; - end_handle = le16toh(cmd->end_handle); + start_handle = le16toh(cp->start_handle) - 1; + end_handle = le16toh(cp->end_handle); rc = ble_gattc_disc_all_dscs(conn.conn_handle, start_handle, @@ -695,12 +674,10 @@ disc_all_desc(uint8_t *data, uint16_t len) if (rc) { discover_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_DESC, status); + return BTP_STATUS_SUCCESS; } static int @@ -756,34 +733,31 @@ read_cb(uint16_t conn_handle, return rc; } -static void -read(uint8_t *data, uint16_t len) +static uint8_t +read(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gattc_read_cmd *cmd = (void *) data; + const struct btp_gattc_read_cmd *cp = cmd; struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } /* Clear buffer */ read_destroy(); - if (ble_gattc_read(conn.conn_handle, le16toh(cmd->handle), + if (ble_gattc_read(conn.conn_handle, le16toh(cp->handle), read_cb, (void *) BTP_GATTC_READ_RP)) { read_destroy(); - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ, status); + return BTP_STATUS_SUCCESS; } static int @@ -857,41 +831,38 @@ read_uuid_cb(uint16_t conn_handle, return rc; } -static void -read_uuid(uint8_t *data, uint16_t len) +static uint8_t +read_uuid(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gattc_read_uuid_cmd *cmd = (void *) data; + const struct btp_gattc_read_uuid_cmd *cp = cmd; struct ble_gap_conn_desc conn; ble_uuid_any_t uuid; - uint8_t status = BTP_STATUS_SUCCESS; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } - if (btp2bt_uuid(cmd->uuid, cmd->uuid_length, &uuid)) { - status = BTP_STATUS_FAILED; - goto rsp; + if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid)) { + return BTP_STATUS_FAILED; } /* Clear buffer */ read_destroy(); if (ble_gattc_read_by_uuid(conn.conn_handle, - le16toh(cmd->start_handle), - le16toh(cmd->end_handle), &uuid.u, + le16toh(cp->start_handle), + le16toh(cp->end_handle), &uuid.u, read_uuid_cb, (void *) BTP_GATTC_READ_UUID_RP)) { read_destroy(); - status = BTP_STATUS_FAILED; + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_UUID, status); + return BTP_STATUS_SUCCESS; } static int @@ -955,56 +926,53 @@ read_long_cb(uint16_t conn_handle, return rc; } -static void -read_long(uint8_t *data, uint16_t len) +static uint8_t +read_long(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gattc_read_long_cmd *cmd = (void *) data; + const struct btp_gattc_read_long_cmd *cp = cmd; struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } /* Clear buffer */ read_destroy(); if (ble_gattc_read_long(conn.conn_handle, - le16toh(cmd->handle), - le16toh(cmd->offset), + le16toh(cp->handle), + le16toh(cp->offset), read_long_cb, (void *) BTP_GATTC_READ_LONG_RP)) { read_destroy(); - status = BTP_STATUS_FAILED; + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_LONG, status); + return BTP_STATUS_SUCCESS; } -static void -read_multiple(uint8_t *data, uint16_t len) +static uint8_t +read_multiple(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gattc_read_multiple_cmd *cmd = (void *) data; - uint16_t handles[cmd->handles_count]; + const struct btp_gattc_read_multiple_cmd *cp = cmd; + uint16_t handles[cp->handles_count]; struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; int rc, i; SYS_LOG_DBG(""); for (i = 0; i < ARRAY_SIZE(handles); i++) { - handles[i] = le16toh(cmd->handles[i]); + handles[i] = le16toh(cp->handles[i]); } - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } /* Clear buffer */ @@ -1012,41 +980,43 @@ read_multiple(uint8_t *data, uint16_t len) if (ble_gattc_read_mult(conn.conn_handle, handles, - cmd->handles_count, + cp->handles_count, read_cb, (void *) BTP_GATTC_READ_MULTIPLE_RP)) { read_destroy(); - status = BTP_STATUS_FAILED; + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_MULTIPLE, status); + return BTP_STATUS_SUCCESS; } -static void -write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign) +static uint8_t +write_without_rsp(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gattc_write_without_rsp_cmd *cmd = (void *) data; + const struct btp_gattc_write_without_rsp_cmd *cp = cmd; struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (cmd_len < sizeof(*cp) || + cmd_len != sizeof(*cp) + le16toh(cp->data_length)) { + return BTP_STATUS_FAILED; + } + + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } if (ble_gattc_write_no_rsp_flat(conn.conn_handle, - le16toh(cmd->handle), cmd->data, - le16toh(cmd->data_length))) { - status = BTP_STATUS_FAILED; + le16toh(cp->handle), cp->data, + le16toh(cp->data_length))) { + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, op, status); + return BTP_STATUS_SUCCESS; } static int @@ -1084,71 +1054,75 @@ write_cb(uint16_t conn_handle, const struct ble_gatt_error *error, return rc; } -static void -write(uint8_t *data, uint16_t len) +static uint8_t +write(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gattc_write_cmd *cmd = (void *) data; + const struct btp_gattc_write_cmd *cp = cmd; struct ble_gap_conn_desc conn; - uint8_t status = BTP_STATUS_SUCCESS; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (cmd_len < sizeof(*cp) || + cmd_len != sizeof(*cp) + le16toh(cp->data_length)) { + return BTP_STATUS_FAILED; + } + + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } - if (ble_gattc_write_flat(conn.conn_handle, le16toh(cmd->handle), - cmd->data, le16toh(cmd->data_length), + if (ble_gattc_write_flat(conn.conn_handle, le16toh(cp->handle), + cp->data, le16toh(cp->data_length), write_cb, (void *) BTP_GATTC_WRITE_RP)) { - status = BTP_STATUS_FAILED; + return BTP_STATUS_FAILED; } -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_WRITE, status); + return BTP_STATUS_SUCCESS; } -static void -write_long(uint8_t *data, uint16_t len) +static uint8_t +write_long(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gattc_write_long_cmd *cmd = (void *) data; + const struct btp_gattc_write_long_cmd *cp = cmd; struct ble_gap_conn_desc conn; struct os_mbuf *om = NULL; - uint8_t status = BTP_STATUS_SUCCESS; int rc = 0; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + if (cmd_len < sizeof(*cp) || + cmd_len != sizeof(*cp) + le16toh(cp->data_length)) { + goto fail; + } + + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { goto fail; } - om = ble_hs_mbuf_from_flat(cmd->data, le16toh(cmd->data_length)); + om = ble_hs_mbuf_from_flat(cp->data, le16toh(cp->data_length)); if (!om) { SYS_LOG_ERR("Insufficient resources"); - status = BTP_STATUS_FAILED; goto fail; } rc = ble_gattc_write_long(conn.conn_handle, - le16toh(cmd->handle), - le16toh(cmd->offset), + le16toh(cp->handle), + le16toh(cp->offset), om, write_cb, (void *) BTP_GATTC_WRITE_LONG_RP); - if (rc) { - status = BTP_STATUS_FAILED; - } else { - goto rsp; + if (!rc) { + return BTP_STATUS_DELAY_REPLY; } fail: SYS_LOG_ERR("Failed to send Write Long request, rc=%d", rc); os_mbuf_free_chain(om); -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_WRITE_LONG, status); + return BTP_STATUS_FAILED; } static int @@ -1187,49 +1161,46 @@ reliable_write_cb(uint16_t conn_handle, return rc; } -static void -reliable_write(uint8_t *data, uint16_t len) +static uint8_t +reliable_write(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gattc_reliable_write_cmd *cmd = (void *) data; + const struct btp_gattc_reliable_write_cmd *cp = cmd; struct ble_gap_conn_desc conn; struct ble_gatt_attr attr; struct os_mbuf *om = NULL; - uint8_t status = BTP_STATUS_SUCCESS; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - status = BTP_STATUS_FAILED; - goto fail; + return BTP_STATUS_SUCCESS; } - om = ble_hs_mbuf_from_flat(cmd->data, le16toh(cmd->data_length)); + om = ble_hs_mbuf_from_flat(cp->data, le16toh(cp->data_length)); /* This is required, because Nimble checks if * the data is longer than offset */ - if (os_mbuf_extend(om, le16toh(cmd->offset) + 1) == NULL) { - status = BTP_STATUS_FAILED; - goto fail; + if (os_mbuf_extend(om, le16toh(cp->offset) + 1) == NULL) { + return BTP_STATUS_SUCCESS; } - attr.handle = le16toh(cmd->handle); - attr.offset = le16toh(cmd->offset); + attr.handle = le16toh(cp->handle); + attr.offset = le16toh(cp->offset); attr.om = om; if (ble_gattc_write_reliable(conn.conn_handle, &attr, 1, reliable_write_cb, NULL)) { - status = BTP_STATUS_FAILED; goto fail; - } else { - goto rsp; } + return BTP_STATUS_SUCCESS; + fail: os_mbuf_free_chain(om); -rsp: - tester_rsp(BTP_SERVICE_ID_GATTC, BTP_GATTC_WRITE_LONG, status); + + return BTP_STATUS_FAILED; } static int @@ -1323,37 +1294,65 @@ disable_subscription(uint16_t conn_handle, uint16_t ccc_handle) return 0; } -static void -config_subscription(uint8_t *data, uint16_t len, uint8_t op) +static uint8_t +config_subscription_notif(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - const struct btp_gattc_cfg_notify_cmd *cmd = (void *) data; + const struct btp_gattc_cfg_notify_cmd *cp = cmd; struct ble_gap_conn_desc conn; - uint16_t ccc_handle = le16toh(cmd->ccc_handle); - uint8_t status = BTP_STATUS_SUCCESS; + uint16_t ccc_handle = le16toh(cp->ccc_handle); + uint8_t status; int rc; SYS_LOG_DBG(""); - rc = ble_gap_conn_find_by_addr((ble_addr_t *) data, &conn); + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); if (rc) { - status = BTP_STATUS_FAILED; - goto rsp; + return BTP_STATUS_FAILED; } - if (cmd->enable) { - uint16_t value; + if (cp->enable) { + if (enable_subscription(conn.conn_handle, + ccc_handle, 0x0001) == 0) { + return BTP_STATUS_SUCCESS; + } - if (op == BTP_GATTC_CFG_NOTIFY) { - value = 0x0001; + status = BTP_STATUS_FAILED; + } else { + if (disable_subscription(conn.conn_handle, ccc_handle) < 0) { + status = BTP_STATUS_FAILED; } else { - value = 0x0002; + status = BTP_STATUS_SUCCESS; } + } + + return status; +} + +static uint8_t +config_subscription_ind(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_gattc_cfg_notify_cmd *cp = cmd; + struct ble_gap_conn_desc conn; + uint16_t ccc_handle = le16toh(cp->ccc_handle); + uint8_t status; + int rc; + + SYS_LOG_DBG(""); + + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); + if (rc) { + return BTP_STATUS_FAILED; + } + if (cp->enable) { if (enable_subscription(conn.conn_handle, - ccc_handle, value) != 0) { - status = BTP_STATUS_FAILED; - goto rsp; + ccc_handle, 0x0002) == 0) { + return BTP_STATUS_SUCCESS; } + + status = BTP_STATUS_FAILED; } else { if (disable_subscription(conn.conn_handle, ccc_handle) < 0) { status = BTP_STATUS_FAILED; @@ -1362,10 +1361,7 @@ config_subscription(uint8_t *data, uint16_t len, uint8_t op) } } -rsp: - SYS_LOG_DBG("Config subscription (op %u) status %u", op, status); - - tester_rsp(BTP_SERVICE_ID_GATTC, op, status); + return status; } int @@ -1405,109 +1401,157 @@ tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, return 0; } -static void -supported_commands(uint8_t *data, uint16_t len) +static uint8_t +supported_commands(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) { - uint8_t cmds[3]; - struct btp_gatt_read_supported_commands_rp *rp = (void *) cmds; + struct btp_gattc_read_supported_commands_rp *rp = rsp; SYS_LOG_DBG(""); - memset(cmds, 0, sizeof(cmds)); - - tester_set_bit(cmds, BTP_GATTC_READ_SUPPORTED_COMMANDS); - tester_set_bit(cmds, BTP_GATTC_EXCHANGE_MTU); - tester_set_bit(cmds, BTP_GATTC_DISC_ALL_PRIM_SVCS); - tester_set_bit(cmds, BTP_GATTC_DISC_PRIM_UUID); - tester_set_bit(cmds, BTP_GATTC_FIND_INCLUDED); - tester_set_bit(cmds, BTP_GATTC_DISC_ALL_CHRC); - tester_set_bit(cmds, BTP_GATTC_DISC_CHRC_UUID); - tester_set_bit(cmds, BTP_GATTC_DISC_ALL_DESC); - tester_set_bit(cmds, BTP_GATTC_READ); - tester_set_bit(cmds, BTP_GATTC_READ_UUID); - tester_set_bit(cmds, BTP_GATTC_READ_LONG); - tester_set_bit(cmds, BTP_GATTC_READ_MULTIPLE); - tester_set_bit(cmds, BTP_GATTC_WRITE_WITHOUT_RSP); + /* octet 0 */ + tester_set_bit(rp->data, BTP_GATTC_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_GATTC_EXCHANGE_MTU); + tester_set_bit(rp->data, BTP_GATTC_DISC_ALL_PRIM_SVCS); + tester_set_bit(rp->data, BTP_GATTC_DISC_PRIM_UUID); + tester_set_bit(rp->data, BTP_GATTC_FIND_INCLUDED); + tester_set_bit(rp->data, BTP_GATTC_DISC_ALL_CHRC); + tester_set_bit(rp->data, BTP_GATTC_DISC_CHRC_UUID); + /* octet 1 */ + tester_set_bit(rp->data, BTP_GATTC_DISC_ALL_DESC); + tester_set_bit(rp->data, BTP_GATTC_READ); + tester_set_bit(rp->data, BTP_GATTC_READ_UUID); + tester_set_bit(rp->data, BTP_GATTC_READ_LONG); + tester_set_bit(rp->data, BTP_GATTC_READ_MULTIPLE); + tester_set_bit(rp->data, BTP_GATTC_WRITE_WITHOUT_RSP); #if 0 - tester_set_bit(cmds, BTP_GATTC_SIGNED_WRITE_WITHOUT_RSP); + tester_set_bit(rp->data, BTP_GATTC_SIGNED_WRITE_WITHOUT_RSP); #endif - tester_set_bit(cmds, BTP_GATTC_WRITE); - tester_set_bit(cmds, BTP_GATTC_WRITE_LONG); - tester_set_bit(cmds, BTP_GATTC_RELIABLE_WRITE); - tester_set_bit(cmds, BTP_GATTC_CFG_NOTIFY); - tester_set_bit(cmds, BTP_GATTC_CFG_INDICATE); - - tester_send(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_SUPPORTED_COMMANDS, - (uint8_t *) rp, sizeof(cmds)); + tester_set_bit(rp->data, BTP_GATTC_WRITE); + /* octet 2 */ + tester_set_bit(rp->data, BTP_GATTC_WRITE_LONG); + tester_set_bit(rp->data, BTP_GATTC_RELIABLE_WRITE); + tester_set_bit(rp->data, BTP_GATTC_CFG_NOTIFY); + tester_set_bit(rp->data, BTP_GATTC_CFG_INDICATE); + + *rsp_len = sizeof(*rp) + 3; + + return BTP_STATUS_SUCCESS; } -void -tester_handle_gattc(uint8_t opcode, uint8_t *data, - uint16_t len) -{ - switch (opcode) { - case BTP_GATTC_READ_SUPPORTED_COMMANDS: - supported_commands(data, len); - return; - case BTP_GATTC_EXCHANGE_MTU: - exchange_mtu(data, len); - return; - case BTP_GATTC_DISC_ALL_PRIM_SVCS: - disc_all_prim_svcs(data, len); - return; - case BTP_GATTC_DISC_PRIM_UUID: - disc_prim_uuid(data, len); - return; - case BTP_GATTC_FIND_INCLUDED: - find_included(data, len); - return; - case BTP_GATTC_DISC_ALL_CHRC: - disc_all_chrc(data, len); - return; - case BTP_GATTC_DISC_CHRC_UUID: - disc_chrc_uuid(data, len); - return; - case BTP_GATTC_DISC_ALL_DESC: - disc_all_desc(data, len); - return; - case BTP_GATTC_READ: - read(data, len); - return; - case BTP_GATTC_READ_UUID: - read_uuid(data, len); - return; - case BTP_GATTC_READ_LONG: - read_long(data, len); - return; - case BTP_GATTC_READ_MULTIPLE: - read_multiple(data, len); - return; - case BTP_GATTC_WRITE_WITHOUT_RSP: - write_without_rsp(data, - len, - opcode, - false); - return; + +static const struct btp_handler handlers[] = { + { + .opcode = BTP_GATTC_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = supported_commands, + }, + { + .opcode = BTP_GATTC_EXCHANGE_MTU, + .expect_len = sizeof(struct btp_gattc_exchange_mtu_cmd), + .func = exchange_mtu, + }, + { + .opcode = BTP_GATTC_DISC_ALL_PRIM_SVCS, + .expect_len = sizeof(struct btp_gattc_disc_all_prim_svcs_cmd), + .func = disc_all_prim_svcs, + }, + { + .opcode = BTP_GATTC_DISC_PRIM_UUID, + .expect_len = -1, + .func = disc_prim_uuid, + }, + { + .opcode = BTP_GATTC_FIND_INCLUDED, + .expect_len = sizeof(struct btp_gattc_find_included_cmd), + .func = find_included, + }, + { + .opcode = BTP_GATTC_DISC_ALL_CHRC, + .expect_len = sizeof(struct btp_gattc_disc_all_chrc_cmd), + .func = disc_all_chrc, + }, + { + .opcode = BTP_GATTC_DISC_CHRC_UUID, + .expect_len = -1, + .func = disc_chrc_uuid, + }, + { + .opcode = BTP_GATTC_DISC_ALL_DESC, + .expect_len = sizeof(struct btp_gattc_disc_all_desc_cmd), + .func = disc_all_desc, + }, + { + .opcode = BTP_GATTC_READ, + .expect_len = sizeof(struct btp_gattc_read_cmd), + .func = read, + }, + { + .opcode = BTP_GATTC_READ_UUID, + .expect_len = -1, + .func = read_uuid, + }, + { + .opcode = BTP_GATTC_READ_LONG, + .expect_len = sizeof(struct btp_gattc_read_long_cmd), + .func = read_long, + }, + { + .opcode = BTP_GATTC_READ_MULTIPLE, + .expect_len = -1, + .func = read_multiple, + }, + { + .opcode = BTP_GATTC_WRITE_WITHOUT_RSP, + .expect_len = -1, + .func = write_without_rsp, + }, #if 0 - case BTP_GATTC_SIGNED_WRITE_WITHOUT_RSP: - write_without_rsp(data, len, opcode, true); - return; + { + .opcode = BTP_GATTC_SIGNED_WRITE_WITHOUT_RSP, + .expect_len = -1, + .func = write_signed_without_rsp, + }, #endif - case BTP_GATTC_WRITE: - write(data, len); - return; - case BTP_GATTC_WRITE_LONG: - write_long(data, len); - return; - case BTP_GATTC_RELIABLE_WRITE: - reliable_write(data, len); - return; - case BTP_GATTC_CFG_NOTIFY: - case BTP_GATTC_CFG_INDICATE: - config_subscription(data, len, opcode); - return; - default: - tester_rsp(BTP_SERVICE_ID_GATTC, opcode, BTP_STATUS_UNKNOWN_CMD); - return; - } -} \ No newline at end of file + { + .opcode = BTP_GATTC_WRITE, + .expect_len = -1, + .func = write, + }, + { + .opcode = BTP_GATTC_WRITE_LONG, + .expect_len = -1, + .func = write_long, + }, + { + .opcode = BTP_GATTC_RELIABLE_WRITE, + .expect_len = -1, + .func = reliable_write, + }, + { + .opcode = BTP_GATTC_CFG_NOTIFY, + .expect_len = sizeof(struct btp_gattc_cfg_notify_cmd), + .func = config_subscription_notif, + }, + { + .opcode = BTP_GATTC_CFG_INDICATE, + .expect_len = sizeof(struct btp_gattc_cfg_notify_cmd), + .func = config_subscription_ind, + }, +}; + +uint8_t +tester_init_gatt_cl(void) +{ + tester_register_command_handlers(BTP_SERVICE_ID_GATTC, handlers, + ARRAY_SIZE(handlers)); + + return BTP_STATUS_SUCCESS; +} + +uint8_t +tester_unregister_gatt_cl(void) +{ + return BTP_STATUS_SUCCESS; +} From e88212a5dad05f7d6ac469d85bd9a1bb99bccbf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 12 Jul 2023 13:49:28 +0200 Subject: [PATCH 0762/1333] apps/bttester: Keep BTP command in buffer for delayed response This allows to avoid copying data for async callbacks. --- apps/bttester/src/bttester.c | 50 ++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/apps/bttester/src/bttester.c b/apps/bttester/src/bttester.c index 7245bcb461..b07661d781 100644 --- a/apps/bttester/src/bttester.c +++ b/apps/bttester/src/bttester.c @@ -40,6 +40,7 @@ static struct os_eventq avail_queue; static struct os_eventq *cmds_queue; static struct os_event bttester_ev[CMD_QUEUED]; +static struct btp_buf *delayed_cmd; struct btp_buf { struct os_event *ev; @@ -165,14 +166,22 @@ cmd_handler(struct os_event *ev) status = BTP_STATUS_UNKNOWN_CMD; } - if (status != BTP_STATUS_DELAY_REPLY) { - if ((status == BTP_STATUS_SUCCESS) && rsp_len > 0) { - tester_send_with_index(cmd->hdr.service, cmd->hdr.opcode, - cmd->hdr.index, cmd->rsp, rsp_len); - } else { - tester_rsp_with_index(cmd->hdr.service, cmd->hdr.opcode, - cmd->hdr.index, status); - } + /* Allow to delay only 1 command. This is for convenience only + * of using cmd data without need of copying those in async + * functions. Should be not needed eventually. + */ + if (status == BTP_STATUS_DELAY_REPLY) { + assert(delayed_cmd == NULL); + delayed_cmd = cmd; + return; + } + + if ((status == BTP_STATUS_SUCCESS) && rsp_len > 0) { + tester_send_with_index(cmd->hdr.service, cmd->hdr.opcode, + cmd->hdr.index, cmd->rsp, rsp_len); + } else { + tester_rsp_with_index(cmd->hdr.service, cmd->hdr.opcode, + cmd->hdr.index, status); } os_eventq_put(&avail_queue, ev); @@ -325,10 +334,35 @@ void tester_send(uint8_t service, uint8_t opcode, uint8_t *data, size_t len) { tester_send_with_index(service, opcode, BTP_INDEX, data, len); + + /* async response to command */ + if (opcode < 0x80) { + struct btp_buf *cmd; + + assert(delayed_cmd != NULL); + + cmd = delayed_cmd; + delayed_cmd = NULL; + + (void)memset(cmd, 0, sizeof(*cmd)); + os_eventq_put(&avail_queue, + CONTAINER_OF(cmd, struct btp_buf, data)->ev); + } } void tester_rsp(uint8_t service, uint8_t opcode, uint8_t status) { + struct btp_buf *cmd; + tester_rsp_with_index(service, opcode, BTP_INDEX, status); + + assert(delayed_cmd != NULL); + + cmd = delayed_cmd; + delayed_cmd = NULL; + + (void)memset(cmd, 0, sizeof(*cmd)); + os_eventq_put(&avail_queue, + CONTAINER_OF(cmd, struct btp_buf, data)->ev); } From 6871cec5f6bdbabdd326cf4e2d1962ec032e056e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 13 Jul 2023 10:04:56 +0200 Subject: [PATCH 0763/1333] bluetooth: tester: Add explicit functions for event and response This make is easier to verify if proper use of BTP is maintained. tester_rsp and tester_rsp_full will be removed eventually when BTP is fully async. --- apps/bttester/src/btp/bttester.h | 4 +- apps/bttester/src/btp_gap.c | 61 ++++++++++++------------- apps/bttester/src/btp_gatt.c | 47 +++++++++---------- apps/bttester/src/btp_gatt_cl.c | 78 ++++++++++++++++---------------- apps/bttester/src/btp_l2cap.c | 16 +++---- apps/bttester/src/btp_mesh.c | 36 +++++++-------- apps/bttester/src/bttester.c | 37 +++++++++------ 7 files changed, 143 insertions(+), 136 deletions(-) diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h index c986a7e97e..120e623db3 100644 --- a/apps/bttester/src/btp/bttester.h +++ b/apps/bttester/src/btp/bttester.h @@ -73,7 +73,9 @@ tester_init(void); void tester_rsp(uint8_t service, uint8_t opcode, uint8_t status); void -tester_send(uint8_t service, uint8_t opcode, uint8_t *data, size_t len); +tester_rsp_full(uint8_t service, uint8_t opcode, const void *rsp, size_t len); +void +tester_event(uint8_t service, uint8_t opcode, const void *data, size_t len); struct btp_handler { uint8_t opcode; diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 946bda75e2..30c36e2291 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -674,8 +674,8 @@ device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, * current one */ if (adv_buf->om_len) { - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_FOUND, - adv_buf->om_data, adv_buf->om_len); + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_FOUND, + adv_buf->om_data, adv_buf->om_len); } store_adv(addr, rssi, data, len); @@ -688,8 +688,8 @@ device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype, return; } done: - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_FOUND, - adv_buf->om_data, adv_buf->om_len); + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_FOUND, + adv_buf->om_data, adv_buf->om_len); } static int @@ -786,9 +786,8 @@ device_connected_ev_send(struct os_event *ev) return; } - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_CONNECTED, - (uint8_t *) &connected_ev, - sizeof(connected_ev)); + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_CONNECTED, + (uint8_t *) &connected_ev, sizeof(connected_ev)); periph_privacy(desc); } @@ -826,9 +825,9 @@ le_connected(uint16_t conn_handle, int status) os_time_ms_to_ticks32( CONNECTED_EV_DELAY_MS(desc.conn_itvl))); #else - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_CONNECTED, - (uint8_t *) &connected_ev, - sizeof(connected_ev)); + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_CONNECTED, + (uint8_t *) &connected_ev, + sizeof(connected_ev)); #endif } @@ -869,8 +868,8 @@ le_disconnected(struct ble_gap_conn_desc *conn, int reason) memcpy(&ev.address, addr, sizeof(ev.address)); - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_DISCONNECTED, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_DEVICE_DISCONNECTED, + (uint8_t *) &ev, sizeof(ev)); } static void @@ -924,8 +923,8 @@ auth_passkey_display(uint16_t conn_handle, unsigned int passkey) memcpy(&ev.address, addr, sizeof(ev.address)); ev.passkey = htole32(pk.passkey); - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_DISPLAY, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_DISPLAY, + (uint8_t *) &ev, sizeof(ev)); } static void @@ -947,8 +946,8 @@ auth_passkey_entry(uint16_t conn_handle) memcpy(&ev.address, addr, sizeof(ev.address)); - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_ENTRY_REQ, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_ENTRY_REQ, + (uint8_t *) &ev, sizeof(ev)); } static void @@ -971,8 +970,8 @@ auth_passkey_numcmp(uint16_t conn_handle, unsigned int passkey) memcpy(&ev.address, addr, sizeof(ev.address)); ev.passkey = htole32(passkey); - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_CONFIRM_REQ, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PASSKEY_CONFIRM_REQ, + (uint8_t *) &ev, sizeof(ev)); } static void @@ -1051,8 +1050,8 @@ le_identity_resolved(uint16_t conn_handle) memcpy(&ev.identity_address, &desc.peer_id_addr, sizeof(ev.identity_address)); - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_IDENTITY_RESOLVED, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_IDENTITY_RESOLVED, + (uint8_t *) &ev, sizeof(ev)); } static void @@ -1076,8 +1075,8 @@ le_pairing_failed(uint16_t conn_handle, int reason) ev.reason = reason; - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_SEC_PAIRING_FAILED, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_SEC_PAIRING_FAILED, + (uint8_t *) &ev, sizeof(ev)); } static void @@ -1093,8 +1092,8 @@ le_conn_param_update(struct ble_gap_conn_desc *desc) ev.conn_latency = desc->conn_latency; ev.supervision_timeout = desc->supervision_timeout; - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_CONN_PARAM_UPDATE, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_CONN_PARAM_UPDATE, + (uint8_t *) &ev, sizeof(ev)); } static void @@ -1121,8 +1120,8 @@ le_encryption_changed(struct ble_gap_conn_desc *desc) } } - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_SEC_LEVEL_CHANGED, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_SEC_LEVEL_CHANGED, + (uint8_t *) &ev, sizeof(ev)); } static void @@ -1136,10 +1135,8 @@ bond_lost(uint16_t conn_handle) assert(rc == 0); memcpy(&ev.address, &desc.peer_id_addr, sizeof(ev.address)); - tester_send(BTP_SERVICE_ID_GAP, - BTP_GAP_EV_BOND_LOST, - (uint8_t *) &ev, - sizeof(ev)); + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_BOND_LOST, + (uint8_t *) &ev, sizeof(ev)); } static void @@ -1212,8 +1209,8 @@ adv_complete(void) current_settings &= ~BIT(BTP_GAP_SETTINGS_ADVERTISING); ev.current_settings = htole32(current_settings); - tester_send(BTP_SERVICE_ID_GAP, BTP_GAP_EV_NEW_SETTINGS, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_NEW_SETTINGS, + (uint8_t *) &ev, sizeof(ev)); } static int diff --git a/apps/bttester/src/btp_gatt.c b/apps/bttester/src/btp_gatt.c index 09bd8d7236..b77919466f 100644 --- a/apps/bttester/src/btp_gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -269,8 +269,8 @@ attr_value_changed_ev(uint16_t handle, struct os_mbuf *data) ev->data_length = htole16(os_mbuf_len(data)); os_mbuf_appendfrom(buf, data, 0, os_mbuf_len(data)); - tester_send_buf(BTP_SERVICE_ID_GATT, BTP_GATT_EV_ATTR_VALUE_CHANGED, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATT, BTP_GATT_EV_ATTR_VALUE_CHANGED, + buf->om_data, buf->om_len); } static int @@ -683,8 +683,8 @@ read_cb(uint16_t conn_handle, if (error->status != 0 && error->status != BLE_HS_EDONE) { rp->att_response = (uint8_t) BLE_HS_ATT_ERR(error->status); - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, gatt_buf.buf, gatt_buf - .len); + tester_rsp_full(BTP_SERVICE_ID_GATT, btp_opcode, + gatt_buf.buf, gatt_buf.len); read_destroy(); return 0; } @@ -697,8 +697,8 @@ read_cb(uint16_t conn_handle, } rp->data_length += attr->om->om_len; - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, - gatt_buf.buf, gatt_buf.len); + tester_rsp_full(BTP_SERVICE_ID_GATT, btp_opcode, + gatt_buf.buf, gatt_buf.len); read_destroy(); return 0; @@ -748,15 +748,15 @@ read_long_cb(uint16_t conn_handle, if (error->status != 0 && error->status != BLE_HS_EDONE) { rp->att_response = (uint8_t) BLE_HS_ATT_ERR(error->status); - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, gatt_buf.buf, gatt_buf - .len); + tester_rsp_full(BTP_SERVICE_ID_GATT, btp_opcode, + gatt_buf.buf, gatt_buf.len); read_destroy(); return 0; } if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, gatt_buf.buf, gatt_buf - .len); + tester_rsp_full(BTP_SERVICE_ID_GATT, btp_opcode, + gatt_buf.buf, gatt_buf.len); read_destroy(); return 0; } @@ -882,8 +882,8 @@ write_rsp(uint16_t conn_handle, const struct ble_gatt_error *error, SYS_LOG_DBG(""); - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, - &err, sizeof(err)); + tester_rsp_full(BTP_SERVICE_ID_GATT, btp_opcode, + &err, sizeof(err)); return 0; } @@ -969,8 +969,8 @@ reliable_write_rsp(uint16_t conn_handle, SYS_LOG_DBG("Reliable write status %d", err); - tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_RELIABLE_WRITE, - &err, sizeof(err)); + tester_rsp_full(BTP_SERVICE_ID_GATT, BTP_GATT_RELIABLE_WRITE, + &err, sizeof(err)); return 0; } @@ -1081,7 +1081,8 @@ disc_prim_uuid_cb(uint16_t conn_handle, } if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, opcode, gatt_buf.buf, gatt_buf.len); + tester_rsp_full(BTP_SERVICE_ID_GATT, opcode, + gatt_buf.buf, gatt_buf.len); discover_destroy(); return 0; } @@ -1136,8 +1137,8 @@ disc_all_desc_cb(uint16_t conn_handle, } if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC, gatt_buf - .buf, gatt_buf.len); + tester_rsp_full(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC, + gatt_buf.buf, gatt_buf.len); discover_destroy(); return 0; } @@ -1253,8 +1254,8 @@ find_included_cb(uint16_t conn_handle, } if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, gatt_buf - .buf, gatt_buf.len); + tester_rsp_full(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, + gatt_buf.buf, gatt_buf.len); discover_destroy(); return 0; } @@ -1310,8 +1311,8 @@ disc_chrc_cb(uint16_t conn_handle, } if (error->status == BLE_HS_EDONE) { - tester_send(BTP_SERVICE_ID_GATT, btp_opcode, gatt_buf.buf, gatt_buf - .len); + tester_rsp_full(BTP_SERVICE_ID_GATT, btp_opcode, + gatt_buf.buf, gatt_buf.len); discover_destroy(); return 0; } @@ -2046,8 +2047,8 @@ tester_gatt_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, ev->data_length = htole16(os_mbuf_len(om)); os_mbuf_appendfrom(buf, om, 0, os_mbuf_len(om)); - tester_send_buf(BTP_SERVICE_ID_GATT, BTP_GATT_EV_NOTIFICATION, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATT, BTP_GATT_EV_NOTIFICATION, + buf->om_data, buf->om_len); fail: os_mbuf_free_chain(buf); diff --git a/apps/bttester/src/btp_gatt_cl.c b/apps/bttester/src/btp_gatt_cl.c index 501c46030e..63f6575626 100644 --- a/apps/bttester/src/btp_gatt_cl.c +++ b/apps/bttester/src/btp_gatt_cl.c @@ -142,8 +142,8 @@ tester_mtu_exchanged_ev(uint16_t conn_handle, ev->mtu = mtu; - tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_EV_MTU_EXCHANGED, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, BTP_GATTC_EV_MTU_EXCHANGED, + buf->om_data, buf->om_len); fail: os_mbuf_free_chain(buf); return 0; @@ -205,8 +205,8 @@ disc_prim_svcs_cb(uint16_t conn_handle, rp->status = err; if (error->status != 0 && error->status != BLE_HS_EDONE) { rp->services_count = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, opcode, + buf->om_data, buf->om_len); discover_destroy(); goto free; } @@ -215,8 +215,8 @@ disc_prim_svcs_cb(uint16_t conn_handle, rp->status = 0; rp->services_count = gatt_buf.cnt; os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, opcode, + buf->om_data, buf->om_len); discover_destroy(); goto free; } @@ -339,8 +339,8 @@ find_included_cb(uint16_t conn_handle, SYS_LOG_DBG(""); if (error->status != 0 && error->status != BLE_HS_EDONE) { rp->services_count = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_FIND_INCLUDED_RP, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, BTP_GATTC_FIND_INCLUDED_RP, + buf->om_data, buf->om_len); discover_destroy(); goto free; } @@ -349,8 +349,8 @@ find_included_cb(uint16_t conn_handle, rp->status = 0; rp->services_count = gatt_buf.cnt; os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_FIND_INCLUDED_RP, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, BTP_GATTC_FIND_INCLUDED_RP, + buf->om_data, buf->om_len); discover_destroy(); goto free; } @@ -454,8 +454,8 @@ disc_chrc_cb(uint16_t conn_handle, if (error->status != 0 && error->status != BLE_HS_EDONE) { rp->characteristics_count = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, opcode, + buf->om_data, buf->om_len); discover_destroy(); goto free; } @@ -464,8 +464,8 @@ disc_chrc_cb(uint16_t conn_handle, rp->status = 0; rp->characteristics_count = gatt_buf.cnt; os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, opcode, + buf->om_data, buf->om_len); discover_destroy(); goto free; } @@ -602,8 +602,8 @@ disc_all_desc_cb(uint16_t conn_handle, if (error->status != 0 && error->status != BLE_HS_EDONE) { rp->descriptors_count = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_DESC_RP, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_DESC_RP, + buf->om_data, buf->om_len); discover_destroy(); goto free; } @@ -612,8 +612,8 @@ disc_all_desc_cb(uint16_t conn_handle, rp->status = 0; rp->descriptors_count = gatt_buf.cnt; os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_DESC_RP, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, BTP_GATTC_DISC_ALL_DESC_RP, + buf->om_data, buf->om_len); discover_destroy(); goto free; } @@ -710,8 +710,8 @@ read_cb(uint16_t conn_handle, if (error->status != 0 && error->status != BLE_HS_EDONE) { rp->status = (uint8_t) BLE_HS_ATT_ERR(error->status); rp->data_length = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, opcode, + buf->om_data, buf->om_len); read_destroy(); goto free; } @@ -725,8 +725,8 @@ read_cb(uint16_t conn_handle, rp->status = 0; rp->data_length = attr->om->om_len; os_mbuf_appendfrom(buf, attr->om, 0, os_mbuf_len(attr->om)); - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, opcode, + buf->om_data, buf->om_len); read_destroy(); free: os_mbuf_free_chain(buf); @@ -794,8 +794,8 @@ read_uuid_cb(uint16_t conn_handle, if (error->status != 0 && error->status != BLE_HS_EDONE) { rp->data_length = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, opcode, + buf->om_data, buf->om_len); read_destroy(); goto free; } @@ -806,8 +806,8 @@ read_uuid_cb(uint16_t conn_handle, rp->status = 0; os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, opcode, + buf->om_data, buf->om_len); read_destroy(); goto free; } @@ -897,8 +897,8 @@ read_long_cb(uint16_t conn_handle, if (error->status != 0 && error->status != BLE_HS_EDONE) { rp->data_length = 0; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, opcode, + buf->om_data, buf->om_len); read_destroy(); goto free; } @@ -907,8 +907,8 @@ read_long_cb(uint16_t conn_handle, rp->status = 0; rp->data_length = gatt_buf.len; os_mbuf_append(buf, gatt_buf.buf, gatt_buf.len); - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, opcode, + buf->om_data, buf->om_len); read_destroy(); goto free; } @@ -1047,8 +1047,8 @@ write_cb(uint16_t conn_handle, const struct ble_gatt_error *error, memcpy(&rp->address, &conn.peer_ota_addr, sizeof(rp->address)); rp->status = err; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, opcode, + buf->om_data, buf->om_len); free: os_mbuf_free_chain(buf); return rc; @@ -1116,7 +1116,7 @@ write_long(const void *cmd, uint16_t cmd_len, om, write_cb, (void *) BTP_GATTC_WRITE_LONG_RP); if (!rc) { - return BTP_STATUS_DELAY_REPLY; + return BTP_STATUS_SUCCESS; } fail: @@ -1154,8 +1154,8 @@ reliable_write_cb(uint16_t conn_handle, memcpy(&rp->address, &conn.peer_ota_addr, sizeof(rp->address)); rp->status = err; - tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_RELIABLE_WRITE_RP, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, BTP_GATTC_RELIABLE_WRITE_RP, + buf->om_data, buf->om_len); free: os_mbuf_free_chain(buf); return rc; @@ -1232,8 +1232,8 @@ subscribe_cb(uint16_t conn_handle, memcpy(&rp->address, &conn.peer_ota_addr, sizeof(rp->address)); rp->status = err; - tester_send_buf(BTP_SERVICE_ID_GATTC, opcode, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, opcode, + buf->om_data, buf->om_len); free: os_mbuf_free_chain(buf); return rc; @@ -1393,8 +1393,8 @@ tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, ev->data_length = htole16(os_mbuf_len(om)); os_mbuf_appendfrom(buf, om, 0, os_mbuf_len(om)); - tester_send_buf(BTP_SERVICE_ID_GATTC, BTP_GATTC_EV_NOTIFICATION_RXED, - CONTROLLER_INDEX, buf); + tester_event(BTP_SERVICE_ID_GATTC, BTP_GATTC_EV_NOTIFICATION_RXED, + buf->om_data, buf->om_len); fail: os_mbuf_free_chain(buf); diff --git a/apps/bttester/src/btp_l2cap.c b/apps/bttester/src/btp_l2cap.c index aa6e158d32..f8450760b1 100644 --- a/apps/bttester/src/btp_l2cap.c +++ b/apps/bttester/src/btp_l2cap.c @@ -134,8 +134,8 @@ recv_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, } os_mbuf_copydata(buf, 0, ev->data_length, ev->data); - tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_DATA_RECEIVED, - recv_cb_buf, sizeof(*ev) + ev->data_length); + tester_event(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_DATA_RECEIVED, + recv_cb_buf, sizeof(*ev) + ev->data_length); tester_l2cap_coc_recv(chan, buf); } @@ -174,8 +174,8 @@ reconfigured_ev(uint16_t conn_handle, struct ble_l2cap_chan *chan, ev.our_mtu = chan_info->our_coc_mtu; ev.our_mps = chan_info->our_l2cap_mtu; - tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_RECONFIGURED, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_RECONFIGURED, + (uint8_t *) &ev, sizeof(ev)); } static void @@ -203,8 +203,8 @@ connected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, memcpy(&ev.address, &desc.peer_ota_addr, sizeof(ev.address)); } - tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_CONNECTED, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_CONNECTED, + (uint8_t *) &ev, sizeof(ev)); } static void @@ -229,8 +229,8 @@ disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, memcpy(&ev.address, &desc.peer_ota_addr, sizeof(ev.address)); } - tester_send(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_DISCONNECTED, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_DISCONNECTED, + (uint8_t *) &ev, sizeof(ev)); } static int diff --git a/apps/bttester/src/btp_mesh.c b/apps/bttester/src/btp_mesh.c index 3b9054a813..8d557e2af9 100644 --- a/apps/bttester/src/btp_mesh.c +++ b/apps/bttester/src/btp_mesh.c @@ -281,8 +281,8 @@ link_open(bt_mesh_prov_bearer_t bearer) return; } - tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROV_LINK_OPEN, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROV_LINK_OPEN, + (uint8_t *) &ev, sizeof(ev)); } static void @@ -305,8 +305,8 @@ link_close(bt_mesh_prov_bearer_t bearer) return; } - tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROV_LINK_CLOSED, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROV_LINK_CLOSED, + (uint8_t *) &ev, sizeof(ev)); } static int @@ -319,8 +319,8 @@ output_number(bt_mesh_output_action_t action, uint32_t number) ev.action = htole16(action); ev.number = htole32(number); - tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_OUT_NUMBER_ACTION, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_OUT_NUMBER_ACTION, + (uint8_t *) &ev, sizeof(ev)); return 0; } @@ -359,8 +359,8 @@ input(bt_mesh_input_action_t action, uint8_t size) ev.action = htole16(action); ev.size = size; - tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_IN_ACTION, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_IN_ACTION, + (uint8_t *) &ev, sizeof(ev)); return 0; } @@ -377,8 +377,8 @@ prov_complete(uint16_t net_idx, uint16_t addr) net.local = addr; net.dst = addr; - tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROVISIONED, - NULL, 0); + tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_PROVISIONED, + NULL, 0); } static void @@ -1014,15 +1014,15 @@ invalid_bearer_cb(uint8_t opcode) SYS_LOG_DBG("opcode 0x%02x", opcode); - tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_INVALID_BEARER, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_INVALID_BEARER, + (uint8_t *) &ev, sizeof(ev)); } static void incomp_timer_exp_cb(void) { - tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_INCOMP_TIMER_EXP, - NULL, 0); + tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_INCOMP_TIMER_EXP, + NULL, 0); } static struct bt_test_cb bt_test_cb = { @@ -1046,8 +1046,8 @@ lpn_established(uint16_t friend_addr) "Friend 0x%04x Queue Size %d Receive Window %d", friend_addr, lpn->queue_size, lpn->recv_win); - tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_LPN_ESTABLISHED, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_LPN_ESTABLISHED, + (uint8_t *) &ev, sizeof(ev)); } static void @@ -1059,8 +1059,8 @@ lpn_terminated(uint16_t friend_addr) SYS_LOG_DBG("Friendship (as LPN) lost with Friend " "0x%04x", friend_addr); - tester_send(BTP_SERVICE_ID_MESH, BTP_MESH_EV_LPN_TERMINATED, - (uint8_t *) &ev, sizeof(ev)); + tester_event(BTP_SERVICE_ID_MESH, BTP_MESH_EV_LPN_TERMINATED, + (uint8_t *) &ev, sizeof(ev)); } void diff --git a/apps/bttester/src/bttester.c b/apps/bttester/src/bttester.c index b07661d781..d5e0399a49 100644 --- a/apps/bttester/src/bttester.c +++ b/apps/bttester/src/bttester.c @@ -68,7 +68,7 @@ tester_mbuf_reset(struct os_mbuf *buf) static void tester_send_with_index(uint8_t service, uint8_t opcode, uint8_t index, - uint8_t *data, size_t len); + const uint8_t *data, size_t len); static void tester_rsp_with_index(uint8_t service, uint8_t opcode, uint8_t index, uint8_t status); @@ -274,7 +274,7 @@ tester_init(void) static void tester_send_with_index(uint8_t service, uint8_t opcode, uint8_t index, - uint8_t *data, size_t len) + const uint8_t *data, size_t len) { struct btp_hdr msg; @@ -331,23 +331,29 @@ tester_rsp_with_index(uint8_t service, uint8_t opcode, uint8_t index, } void -tester_send(uint8_t service, uint8_t opcode, uint8_t *data, size_t len) +tester_event(uint8_t service, uint8_t opcode, const void *data, size_t len) { + assert(opcode >= 0x80); tester_send_with_index(service, opcode, BTP_INDEX, data, len); +} - /* async response to command */ - if (opcode < 0x80) { - struct btp_buf *cmd; +void +tester_rsp_full(uint8_t service, uint8_t opcode, const void *rsp, size_t len) +{ + struct btp_buf *cmd; - assert(delayed_cmd != NULL); + assert(opcode < 0x80); + assert(delayed_cmd != NULL); - cmd = delayed_cmd; - delayed_cmd = NULL; + tester_send_with_index(service, opcode, BTP_INDEX, rsp, len); - (void)memset(cmd, 0, sizeof(*cmd)); - os_eventq_put(&avail_queue, - CONTAINER_OF(cmd, struct btp_buf, data)->ev); - } + cmd = delayed_cmd; + delayed_cmd = NULL; + + (void)memset(cmd, 0, sizeof(*cmd)); + + os_eventq_put(&avail_queue, + CONTAINER_OF(cmd, struct btp_buf, data)->ev); } void @@ -355,10 +361,11 @@ tester_rsp(uint8_t service, uint8_t opcode, uint8_t status) { struct btp_buf *cmd; - tester_rsp_with_index(service, opcode, BTP_INDEX, status); - + assert(opcode < 0x80); assert(delayed_cmd != NULL); + tester_rsp_with_index(service, opcode, BTP_INDEX, status); + cmd = delayed_cmd; delayed_cmd = NULL; From e2065a6016dc2fbe439458eb09ebfa599e4e3cba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 13 Jul 2023 10:09:14 +0200 Subject: [PATCH 0764/1333] bluetooth: tester: Use define for variable length BTP commands This makes code a bit easier to follow. --- apps/bttester/src/btp/bttester.h | 5 +++++ apps/bttester/src/btp_gap.c | 4 ++-- apps/bttester/src/btp_gatt.c | 20 ++++++++++---------- apps/bttester/src/btp_gatt_cl.c | 18 +++++++++--------- apps/bttester/src/btp_l2cap.c | 4 ++-- apps/bttester/src/btp_mesh.c | 10 +++++----- 6 files changed, 33 insertions(+), 28 deletions(-) diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h index 120e623db3..8e8b98b5ad 100644 --- a/apps/bttester/src/btp/bttester.h +++ b/apps/bttester/src/btp/bttester.h @@ -77,6 +77,11 @@ tester_rsp_full(uint8_t service, uint8_t opcode, const void *rsp, size_t len); void tester_event(uint8_t service, uint8_t opcode, const void *data, size_t len); +/* Used to indicate that command length is variable and that validation will + * be done in handler. + */ +#define BTP_HANDLER_LENGTH_VARIABLE (-1) + struct btp_handler { uint8_t opcode; uint8_t index; diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 30c36e2291..ebd076315c 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -1801,7 +1801,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_GAP_START_ADVERTISING, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = start_advertising, }, { @@ -1886,7 +1886,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_GAP_SET_FILTER_ACCEPT_LIST, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = set_filter_accept_list, }, }; diff --git a/apps/bttester/src/btp_gatt.c b/apps/bttester/src/btp_gatt.c index b77919466f..72115e21ad 100644 --- a/apps/bttester/src/btp_gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -1918,7 +1918,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_GATT_DISC_PRIM_UUID, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = disc_prim_uuid, }, { @@ -1933,7 +1933,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_GATT_DISC_CHRC_UUID, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = disc_chrc_uuid, }, { @@ -1953,7 +1953,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_GATT_READ_UUID, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = read_uuid, }, { @@ -1963,34 +1963,34 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_GATT_READ_MULTIPLE, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = read_multiple, }, { .opcode = BTP_GATT_WRITE_WITHOUT_RSP, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = write_without_rsp, }, #if 0 { .opcode = BTP_GATT_SIGNED_WRITE_WITHOUT_RSP, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = write_signed_without_rsp, }, #endif { .opcode = BTP_GATT_WRITE, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = write_data, }, { .opcode = BTP_GATT_WRITE_LONG, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = write_long, }, { .opcode = BTP_GATT_RELIABLE_WRITE, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = reliable_write, }, { @@ -2005,7 +2005,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_GATT_GET_ATTRIBUTES, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = get_attrs, }, { diff --git a/apps/bttester/src/btp_gatt_cl.c b/apps/bttester/src/btp_gatt_cl.c index 63f6575626..ff76d7dd7f 100644 --- a/apps/bttester/src/btp_gatt_cl.c +++ b/apps/bttester/src/btp_gatt_cl.c @@ -1459,7 +1459,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_GATTC_DISC_PRIM_UUID, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = disc_prim_uuid, }, { @@ -1474,7 +1474,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_GATTC_DISC_CHRC_UUID, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = disc_chrc_uuid, }, { @@ -1489,7 +1489,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_GATTC_READ_UUID, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = read_uuid, }, { @@ -1499,34 +1499,34 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_GATTC_READ_MULTIPLE, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = read_multiple, }, { .opcode = BTP_GATTC_WRITE_WITHOUT_RSP, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = write_without_rsp, }, #if 0 { .opcode = BTP_GATTC_SIGNED_WRITE_WITHOUT_RSP, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = write_signed_without_rsp, }, #endif { .opcode = BTP_GATTC_WRITE, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = write, }, { .opcode = BTP_GATTC_WRITE_LONG, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = write_long, }, { .opcode = BTP_GATTC_RELIABLE_WRITE, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = reliable_write, }, { diff --git a/apps/bttester/src/btp_l2cap.c b/apps/bttester/src/btp_l2cap.c index f8450760b1..34749af7fb 100644 --- a/apps/bttester/src/btp_l2cap.c +++ b/apps/bttester/src/btp_l2cap.c @@ -727,7 +727,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_L2CAP_SEND_DATA, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = send_data, }, { @@ -737,7 +737,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_L2CAP_RECONFIGURE, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = reconfigure, }, { diff --git a/apps/bttester/src/btp_mesh.c b/apps/bttester/src/btp_mesh.c index 8d557e2af9..96eaaf81f5 100644 --- a/apps/bttester/src/btp_mesh.c +++ b/apps/bttester/src/btp_mesh.c @@ -837,12 +837,12 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_MESH_CONFIG_PROVISIONING, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = config_prov, }, { .opcode = BTP_MESH_PROVISION_NODE, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = provision_node, }, { @@ -862,7 +862,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_MESH_INPUT_STRING, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = input_string, }, { @@ -887,7 +887,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_MESH_NET_SEND, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = net_send, }, { @@ -902,7 +902,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_MESH_MODEL_SEND, - .expect_len = -1, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = model_send, }, { From 65f32e5f87b0513a92824c6c05de80f995a79464 Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Tue, 25 Jul 2023 19:17:22 +0400 Subject: [PATCH 0765/1333] nimble/host: fix gcc 13 warnings --- nimble/host/src/ble_gap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 488613c03c..9390708f9b 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -6461,6 +6461,9 @@ ble_gap_preempt_done(void) void *arg; } slaves[BLE_ADV_INSTANCES]; + master_cb = NULL; + master_arg = NULL; + disc_preempted = 0; /* Protects slaves from accessing by multiple threads */ From c8743c683a14499b72dc81b64c736aa46cdae9a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 27 Jul 2023 12:51:03 +0200 Subject: [PATCH 0766/1333] apps/bttester: fix get_attrs response buffer Assigning rsp pointer to new value caused wrong behavior and corrupted response. Data should be copied into buffer instead. --- apps/bttester/src/btp_gatt.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/apps/bttester/src/btp_gatt.c b/apps/bttester/src/btp_gatt.c index 72115e21ad..a9d8d7f439 100644 --- a/apps/bttester/src/btp_gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -1704,6 +1704,10 @@ get_attrs(const void *cmd, uint16_t cmd_len, SYS_LOG_DBG(""); + if (!buf) { + return BTP_STATUS_FAILED; + } + memset(str, 0, sizeof(str)); memset(&uuid, 0, sizeof(uuid)); start_handle = le16toh(cp->start_handle); @@ -1712,7 +1716,7 @@ get_attrs(const void *cmd, uint16_t cmd_len, if (cp->type_length) { if (btp2bt_uuid(cp->type, cp->type_length, &uuid)) { status = BTP_STATUS_FAILED; - goto free; + goto done; } ble_uuid_to_str(&uuid.u, str); @@ -1724,12 +1728,6 @@ get_attrs(const void *cmd, uint16_t cmd_len, SYS_LOG_DBG("start 0x%04x end 0x%04x", start_handle, end_handle); } - rp = os_mbuf_extend(buf, sizeof(*rp)); - if (!rp) { - status = BTP_STATUS_FAILED; - goto free; - } - entry = ble_att_svr_find_by_uuid(entry, uuid_ptr, end_handle); while (entry) { @@ -1742,7 +1740,7 @@ get_attrs(const void *cmd, uint16_t cmd_len, gatt_attr = os_mbuf_extend(buf, sizeof(*gatt_attr)); if (!gatt_attr) { status = BTP_STATUS_FAILED; - goto free; + goto done; } gatt_attr->handle = htole16(entry->ha_handle_id); gatt_attr->permission = flags_hs2btp(entry->ha_flags); @@ -1765,10 +1763,11 @@ get_attrs(const void *cmd, uint16_t cmd_len, } rp->attrs_count = count; + memcpy(rp->attrs, buf->om_data, buf->om_len); *rsp_len = sizeof(*rp) + buf->om_len; -free: +done: os_mbuf_free_chain(buf); return status; } From 7585a01e43d9c24ebcf7aa5c9955122d777869d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 28 Jul 2023 13:04:18 +0200 Subject: [PATCH 0767/1333] apps/bttester: copy whole mbuf chain in get_attrs Whole GATT database can be big and data may be missing from rsp. --- apps/bttester/src/btp_gatt.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/bttester/src/btp_gatt.c b/apps/bttester/src/btp_gatt.c index a9d8d7f439..c96593a3df 100644 --- a/apps/bttester/src/btp_gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -1750,11 +1750,17 @@ get_attrs(const void *cmd, uint16_t cmd_len, gatt_attr->type_length = 2; uuid_val = htole16(BLE_UUID16(entry->ha_uuid)->value); - os_mbuf_append(buf, &uuid_val, sizeof(uuid_val)); + if (os_mbuf_append(buf, &uuid_val, sizeof(uuid_val))) { + status = BTP_STATUS_FAILED; + goto done; + } } else { gatt_attr->type_length = 16; - os_mbuf_append(buf, BLE_UUID128(entry->ha_uuid)->value, - gatt_attr->type_length); + if (os_mbuf_append(buf, BLE_UUID128(entry->ha_uuid)->value, + gatt_attr->type_length)) { + status = BTP_STATUS_FAILED; + goto done; + } } count++; @@ -1763,9 +1769,9 @@ get_attrs(const void *cmd, uint16_t cmd_len, } rp->attrs_count = count; - memcpy(rp->attrs, buf->om_data, buf->om_len); + os_mbuf_copydata(buf, 0, os_mbuf_len(buf), rp->attrs); - *rsp_len = sizeof(*rp) + buf->om_len; + *rsp_len = sizeof(*rp) + os_mbuf_len(buf); done: os_mbuf_free_chain(buf); From 3720e7656c9b6906a4475f551bfd7f40040ab10c Mon Sep 17 00:00:00 2001 From: Petro Karashchenko Date: Mon, 31 Jul 2023 12:40:19 +0300 Subject: [PATCH 0768/1333] porting/examples/linux: update steps in README.md Signed-off-by: Petro Karashchenko --- porting/examples/linux/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/porting/examples/linux/README.md b/porting/examples/linux/README.md index bbf68bb5e3..562da266b2 100644 --- a/porting/examples/linux/README.md +++ b/porting/examples/linux/README.md @@ -59,7 +59,7 @@ in sysconfig.h to use hci0. ```no-highlight cd porting/examples/linux - sudo ./_build/nimble_linux.out + sudo ./nimble-linux ``` 3. Build and run the unit tests @@ -68,6 +68,6 @@ The Operating System Abstraction Layer (OSAL) used to port Nimble to Linux has a suite of unit tests. ```no-highlight - cd tests/unit/porting/npl + cd porting/npl/linux/test make test ``` From b4cf7fe97834f9e609af2391d9b88988672f9b2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 31 Jul 2023 13:02:46 +0200 Subject: [PATCH 0769/1333] apps/bttester: fix preprocessor directive for registering Mesh service If statements encapsulates GATT_CL too. --- apps/bttester/src/btp_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bttester/src/btp_core.c b/apps/bttester/src/btp_core.c index 35dcd824b7..5ab290d937 100644 --- a/apps/bttester/src/btp_core.c +++ b/apps/bttester/src/btp_core.c @@ -101,10 +101,10 @@ register_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_MESH: status = tester_init_mesh(); break; +#endif /* MYNEWT_VAL(BLE_MESH) */ case BTP_SERVICE_ID_GATTC: status = tester_init_gatt_cl(); break; -#endif /* MYNEWT_VAL(BLE_MESH) */ default: status = BTP_STATUS_FAILED; break; From 8da39bc40e6c900f51b7153fc4e3a679a62326bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 31 Jul 2023 14:07:12 +0200 Subject: [PATCH 0770/1333] apps/bttester: fix start_direct_adv command high_duty_cycle is defined in flags field that is 2 octet long, as first bit. --- apps/bttester/src/btp/btp_gap.h | 2 +- apps/bttester/src/btp_gap.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/bttester/src/btp/btp_gap.h b/apps/bttester/src/btp/btp_gap.h index 5e3e1b8372..93b62c484d 100644 --- a/apps/bttester/src/btp/btp_gap.h +++ b/apps/bttester/src/btp/btp_gap.h @@ -212,7 +212,7 @@ struct btp_gap_passkey_confirm_cmd { #define BTP_GAP_START_DIRECT_ADV 0x15 struct btp_gap_start_direct_adv_cmd { ble_addr_t address; - uint8_t high_duty; + uint16_t options; } __packed; #define BTP_GAP_CONN_PARAM_UPDATE 0x16 diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index ebd076315c..e0d43a4348 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -1577,7 +1577,7 @@ start_direct_adv(const void *cmd, uint16_t cmd_len, SYS_LOG_DBG(""); - adv_params.high_duty_cycle = cp->high_duty; + adv_params.high_duty_cycle = cp->options & BIT(1); err = ble_gap_adv_start(own_addr_type, &cp->address, BLE_HS_FOREVER, &adv_params, From 6081de3754b530732d4e2b0638fd9534ecf49944 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 31 Jul 2023 13:58:39 +0200 Subject: [PATCH 0771/1333] nimble/ll: Fix assert on scan start LL_STATE_BIG was not handled properly when trying to start scan window. --- nimble/controller/src/ble_ll_scan.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 3c5073238f..d1c3c8ad7d 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1134,6 +1134,11 @@ ble_ll_scan_event_proc(struct ble_npl_event *ev) ble_ll_state_set(BLE_LL_STATE_STANDBY); } break; +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + case BLE_LL_STATE_BIG: + start_scan = false; + break; +#endif case BLE_LL_STATE_STANDBY: break; default: From 6ccf8208e0ae2ad1051117be12c0faefa97277e7 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 1 Aug 2023 12:33:53 +0200 Subject: [PATCH 0772/1333] nimble/phy/nrf5x: Fix compilation with nrfx 2.11 This release change NRF_FICR_NS->TRIMCNF[index].ADDR from (uint32_t *) to uint32_t. --- nimble/drivers/nrf5x/src/ble_phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 3ba359c8f3..481ed619d1 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -1570,7 +1570,7 @@ ble_phy_init(void) #ifdef NRF53_SERIES /* Errata 158: load trim values after toggling power */ for (uint32_t index = 0; index < 32ul && - NRF_FICR_NS->TRIMCNF[index].ADDR != (uint32_t *)0xFFFFFFFFul; index++) { + NRF_FICR_NS->TRIMCNF[index].ADDR != 0xFFFFFFFFul; index++) { if (((uint32_t)NRF_FICR_NS->TRIMCNF[index].ADDR & 0xFFFFF000ul) == (volatile uint32_t)NRF_RADIO_NS) { *((volatile uint32_t *)NRF_FICR_NS->TRIMCNF[index].ADDR) = NRF_FICR_NS->TRIMCNF[index].DATA; } From 3c4bc60cae01fa19091749f67cf08403c2807491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 1 Aug 2023 13:44:22 +0200 Subject: [PATCH 0773/1333] apps/bttester: copy whole buffer to response of get_attr_val Characteristic values can be long and not fit into single os_mbuf - copy whole chain instead. --- apps/bttester/src/btp_gatt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/bttester/src/btp_gatt.c b/apps/bttester/src/btp_gatt.c index c96593a3df..1c6320510d 100644 --- a/apps/bttester/src/btp_gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -1807,8 +1807,8 @@ get_attr_val(const void *cmd, uint16_t cmd_len, rp->att_response = out_att_err; rp->value_length = os_mbuf_len(buf) - sizeof(*rp); - (void)memcpy(rsp, buf->om_data, buf->om_len); - *rsp_len = buf->om_len; + os_mbuf_copydata(buf, 0, os_mbuf_len(buf), rsp); + *rsp_len = os_mbuf_len(buf); goto free; } else { @@ -1825,8 +1825,8 @@ get_attr_val(const void *cmd, uint16_t cmd_len, rp->att_response = out_att_err; rp->value_length = os_mbuf_len(buf) - sizeof(*rp); - (void)memcpy(rsp, buf->om_data, buf->om_len); - *rsp_len = buf->om_len; + os_mbuf_copydata(buf, 0, os_mbuf_len(buf), rsp); + *rsp_len = os_mbuf_len(buf); goto free; } From 338cb747f049c1cd67be9665fe60c8aa2f6eeda7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 1 Aug 2023 09:08:33 +0200 Subject: [PATCH 0774/1333] apps/bttester: fix check for address type in advertising_start() Encapsulated cases in correct configuration check (BTTESTER_PRIVACY_MODE). Used simple bit comparison, as glue module was dropped. --- apps/bttester/src/btp_gap.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index e0d43a4348..8056eaf13d 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -488,19 +488,19 @@ start_advertising(const void *cmd, uint16_t cmd_len, switch (addr_type) { case 0x00: break; -#if defined(CONFIG_BT_PRIVACY) +#if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) case 0x01: - /* RPA usage is is controlled via privacy settings */ - if (!atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_PRIVACY)) { - return BTP_STATUS_FAILED; - } - break; - case 0x02: - /* NRPA is used only for non-connectable advertising */ - if (atomic_test_bit(¤t_settings, BTP_GAP_SETTINGS_CONNECTABLE)) { - return BTP_STATUS_FAILED; - } - break; + /* RPA usage is is controlled via privacy settings */ + if (!(current_settings & BIT(BTP_GAP_SETTINGS_PRIVACY))) { + return BTP_STATUS_FAILED; + } + break; + case 0x02: + /* NRPA is used only for non-connectable advertising */ + if (!(current_settings & BIT(BTP_GAP_SETTINGS_CONNECTABLE))) { + return BTP_STATUS_FAILED; + } + break; #endif default: return BTP_STATUS_FAILED; From e718a2fb22a56141ddb6a63cab875489a6a08f25 Mon Sep 17 00:00:00 2001 From: "yuzhigang84@gmail.com" Date: Mon, 27 Sep 2021 07:41:45 -0400 Subject: [PATCH 0775/1333] porting/npl/linux: support C library (for example:musl) which didn't have PTHREAD_MUTEX_RECURSIVE_NP --- porting/npl/linux/src/os_atomic.c | 8 +++++++- porting/npl/linux/src/os_mutex.c | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/porting/npl/linux/src/os_atomic.c b/porting/npl/linux/src/os_atomic.c index 51260149ce..b01e234b08 100644 --- a/porting/npl/linux/src/os_atomic.c +++ b/porting/npl/linux/src/os_atomic.c @@ -23,10 +23,16 @@ #include "nimble/nimble_npl.h" -static pthread_mutex_t s_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +static pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER; +static uint8_t s_mutex_inited = 0; uint32_t ble_npl_hw_enter_critical(void) { + if( !s_mutex_inited ) { + pthread_mutexattr_settype(&s_mutex, PTHREAD_MUTEX_RECURSIVE); + s_mutex_inited = 1; + } + pthread_mutex_lock(&s_mutex); return 0; } diff --git a/porting/npl/linux/src/os_mutex.c b/porting/npl/linux/src/os_mutex.c index c7d6190e89..86cad965da 100644 --- a/porting/npl/linux/src/os_mutex.c +++ b/porting/npl/linux/src/os_mutex.c @@ -31,7 +31,7 @@ ble_npl_mutex_init(struct ble_npl_mutex *mu) } pthread_mutexattr_init(&mu->attr); - pthread_mutexattr_settype(&mu->attr, PTHREAD_MUTEX_RECURSIVE_NP); + pthread_mutexattr_settype(&mu->attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&mu->lock, &mu->attr); return BLE_NPL_OK; From 601b1056aa5f371964343f851610104880ff2e29 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Wed, 26 Jul 2023 16:41:37 +0200 Subject: [PATCH 0776/1333] host/gatt: add and update doxygen comments for the header file Adds missing macros and structures documentation. Corrects arguments names in functions documentation. --- nimble/host/include/host/ble_gatt.h | 184 +++++++++++++++++++++++++--- 1 file changed, 170 insertions(+), 14 deletions(-) diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index 312126f532..b3bea2bdc4 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -38,80 +38,220 @@ struct ble_hs_conn; struct ble_att_error_rsp; struct ble_hs_cfg; +/** + * @defgroup ble_gatt_register_op_codes Generic Attribute Profile (GATT) Registration Operation Codes + * @{ + */ + +/** GATT Service registration. */ #define BLE_GATT_REGISTER_OP_SVC 1 + +/** GATT Characteristic registration. */ #define BLE_GATT_REGISTER_OP_CHR 2 + +/** GATT Descriptor registration. */ #define BLE_GATT_REGISTER_OP_DSC 3 +/** @} */ + +/** + * @defgroup ble_gatt_uuid Generic Attribute Profile (GATT) Service and Descriptor UUIDs + * @{ + */ + +/** GATT service 16-bit UUID. */ #define BLE_GATT_SVC_UUID16 0x1801 + +/** GATT Client Characteristic Configuration descriptor 16-bit UUID. */ #define BLE_GATT_DSC_CLT_CFG_UUID16 0x2902 +/** @} */ + +/** + * @defgroup ble_gatt_chr_properties Generic Attribute Profile (GATT) Characteristic Properties + * @{ + */ + +/** Characteristic property: Broadcast. */ #define BLE_GATT_CHR_PROP_BROADCAST 0x01 + +/** Characteristic property: Read. */ #define BLE_GATT_CHR_PROP_READ 0x02 + +/** Characteristic property: Write Without Response. */ #define BLE_GATT_CHR_PROP_WRITE_NO_RSP 0x04 + +/** Characteristic property: Write. */ #define BLE_GATT_CHR_PROP_WRITE 0x08 + +/** Characteristic property: Notify. */ #define BLE_GATT_CHR_PROP_NOTIFY 0x10 + +/** Characteristic property: Indicate. */ #define BLE_GATT_CHR_PROP_INDICATE 0x20 + +/** Characteristic property: Authenticated Signed Write. */ #define BLE_GATT_CHR_PROP_AUTH_SIGN_WRITE 0x40 + +/** Characteristic property: Extended Properties. */ #define BLE_GATT_CHR_PROP_EXTENDED 0x80 +/** @} */ + +/** @defgroup ble_gatt_access_op_codes Generic Attribute Profile (GATT) Access Operation Codes + * @{ + */ + +/** GATT attribute access operation: Read characteristic. */ #define BLE_GATT_ACCESS_OP_READ_CHR 0 + +/** GATT attribute access operation: Write characteristic. */ #define BLE_GATT_ACCESS_OP_WRITE_CHR 1 + +/** GATT attribute access operation: Read descriptor. */ #define BLE_GATT_ACCESS_OP_READ_DSC 2 + +/** GATT attribute access operation: Write descriptor. */ #define BLE_GATT_ACCESS_OP_WRITE_DSC 3 +/** @} */ + +/** + * @defgroup ble_gatt_chr_flags Generic Attribute Profile (GATT) Characteristic Flags + * @{ + */ + +/** GATT Characteristic Flag: Broadcast. */ #define BLE_GATT_CHR_F_BROADCAST 0x0001 + +/** GATT Characteristic Flag: Read. */ #define BLE_GATT_CHR_F_READ 0x0002 + +/** GATT Characteristic Flag: Write without Response. */ #define BLE_GATT_CHR_F_WRITE_NO_RSP 0x0004 + +/** GATT Characteristic Flag: Write. */ #define BLE_GATT_CHR_F_WRITE 0x0008 + +/** GATT Characteristic Flag: Notify. */ #define BLE_GATT_CHR_F_NOTIFY 0x0010 + +/** GATT Characteristic Flag: Indicate. */ #define BLE_GATT_CHR_F_INDICATE 0x0020 + +/** GATT Characteristic Flag: Authenticated Signed Writes. */ #define BLE_GATT_CHR_F_AUTH_SIGN_WRITE 0x0040 + +/** GATT Characteristic Flag: Reliable Writes. */ #define BLE_GATT_CHR_F_RELIABLE_WRITE 0x0080 + +/** GATT Characteristic Flag: Auxiliary Writes. */ #define BLE_GATT_CHR_F_AUX_WRITE 0x0100 + +/** GATT Characteristic Flag: Read Encrypted. */ #define BLE_GATT_CHR_F_READ_ENC 0x0200 + +/** GATT Characteristic Flag: Read Authenticated. */ #define BLE_GATT_CHR_F_READ_AUTHEN 0x0400 + +/** GATT Characteristic Flag: Read Authorized. */ #define BLE_GATT_CHR_F_READ_AUTHOR 0x0800 + +/** GATT Characteristic Flag: Write Encrypted. */ #define BLE_GATT_CHR_F_WRITE_ENC 0x1000 + +/** GATT Characteristic Flag: Write Authenticated. */ #define BLE_GATT_CHR_F_WRITE_AUTHEN 0x2000 + +/** GATT Characteristic Flag: Write Authorized. */ #define BLE_GATT_CHR_F_WRITE_AUTHOR 0x4000 + +/** @} */ + +/** + * @defgroup ble_gatt_service_types Generic Attribute Profile (GATT) Service Types + * @{ + */ + +/** GATT Service Type: End of Services. */ #define BLE_GATT_SVC_TYPE_END 0 + +/** GATT Service Type: Primary Service. */ #define BLE_GATT_SVC_TYPE_PRIMARY 1 + +/** GATT Service Type: Secondary Service. */ #define BLE_GATT_SVC_TYPE_SECONDARY 2 +/** @} */ + /*** @client. */ +/** Represents a GATT error. */ struct ble_gatt_error { + /** The GATT status code indicating the type of error. */ uint16_t status; + + /** The attribute handle associated with the error. */ uint16_t att_handle; }; +/** Represents a GATT Service. */ struct ble_gatt_svc { + /** The start handle of the GATT service. */ uint16_t start_handle; + + /** The end handle of the GATT service. */ uint16_t end_handle; + + /** The UUID of the GATT service. */ ble_uuid_any_t uuid; }; + +/** Represents a GATT attribute. */ struct ble_gatt_attr { + /** The handle of the GATT attribute. */ uint16_t handle; + + /** The offset of the data within the attribute. */ uint16_t offset; + + /** Pointer to the data buffer represented by an os_mbuf. */ struct os_mbuf *om; }; + +/** Represents a GATT characteristic. */ struct ble_gatt_chr { + /** The handle of the GATT characteristic definition. */ uint16_t def_handle; + + /** The handle of the GATT characteristic value. */ uint16_t val_handle; + + /** The properties of the GATT characteristic. */ uint8_t properties; + + /** The UUID of the GATT characteristic. */ ble_uuid_any_t uuid; }; + +/** Represents a GATT descriptor. */ struct ble_gatt_dsc { + /** The handle of the GATT descriptor. */ uint16_t handle; + + /** The UUID of the GATT descriptor. */ ble_uuid_any_t uuid; }; +/** Function prototype for the GATT MTU exchange callback. */ typedef int ble_gatt_mtu_fn(uint16_t conn_handle, const struct ble_gatt_error *error, uint16_t mtu, void *arg); + +/** Function prototype for the GATT service discovery callback. */ typedef int ble_gatt_disc_svc_fn(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_svc *service, @@ -137,10 +277,12 @@ typedef int ble_gatt_reliable_attr_fn(uint16_t conn_handle, struct ble_gatt_attr *attrs, uint8_t num_attrs, void *arg); +/** Function prototype for the GATT characteristic callback. */ typedef int ble_gatt_chr_fn(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_chr *chr, void *arg); +/** Function prototype for the GATT descriptor callback. */ typedef int ble_gatt_dsc_fn(uint16_t conn_handle, const struct ble_gatt_error *error, uint16_t chr_val_handle, @@ -180,7 +322,7 @@ int ble_gattc_disc_all_svcs(uint16_t conn_handle, * * @param conn_handle The connection over which to execute the * procedure. - * @param service_uuid128 The 128-bit UUID of the service to discover. + * @param uuid The 128-bit UUID of the service to discover. * @param cb The function to call to report procedure status * updates; null for no callback. * @param cb_arg The optional argument to pass to the callback @@ -240,7 +382,7 @@ int ble_gattc_disc_all_chrs(uint16_t conn_handle, uint16_t start_handle, * the service definition handle). * @param end_handle The handle to end the search at (generally the * last handle in the service). - * @param chr_uuid128 The 128-bit UUID of the characteristic to + * @param uuid The 128-bit UUID of the characteristic to * discover. * @param cb The function to call to report procedure status * updates; null for no callback. @@ -258,9 +400,9 @@ int ble_gattc_disc_chrs_by_uuid(uint16_t conn_handle, uint16_t start_handle, * * @param conn_handle The connection over which to execute the * procedure. - * @param chr_val_handle The handle of the characteristic value + * @param start_handle The handle of the characteristic value * attribute. - * @param chr_end_handle The last handle in the characteristic + * @param end_handle The last handle in the characteristic * definition. * @param cb The function to call to report procedure status * updates; null for no callback. @@ -298,6 +440,8 @@ int ble_gattc_read(uint16_t conn_handle, uint16_t attr_handle, * handle of the service definition). * @param end_handle The last handle to search (generally the * last handle in the service definition). + * @param uuid The 128-bit UUID of the characteristic to + * read. * @param cb The function to call to report procedure status * updates; null for no callback. * @param cb_arg The optional argument to pass to the callback @@ -315,6 +459,8 @@ int ble_gattc_read_by_uuid(uint16_t conn_handle, uint16_t start_handle, * @param conn_handle The connection over which to execute the * procedure. * @param handle The handle of the characteristic value to read. + * @param offset The offset within the characteristic value to + * start reading. * @param cb The function to call to report procedure status * updates; null for no callback. * @param cb_arg The optional argument to pass to the callback @@ -351,7 +497,7 @@ int ble_gattc_read_mult(uint16_t conn_handle, const uint16_t *handles, * procedure. * @param attr_handle The handle of the characteristic value to write * to. - * @param txom The value to write to the characteristic. + * @param om The value to write to the characteristic. * * @return 0 on success; nonzero on failure. */ @@ -366,8 +512,8 @@ int ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle, * procedure. * @param attr_handle The handle of the characteristic value to write * to. - * @param value The value to write to the characteristic. - * @param value_len The number of bytes to write. + * @param data The value to write to the characteristic. + * @param data_len The number of bytes to write. * * @return 0 on success; nonzero on failure. */ @@ -382,7 +528,7 @@ int ble_gattc_write_no_rsp_flat(uint16_t conn_handle, uint16_t attr_handle, * procedure. * @param attr_handle The handle of the characteristic value to write * to. - * @param txom The value to write to the characteristic. + * @param om The value to write to the characteristic. * @param cb The function to call to report procedure status * updates; null for no callback. * @param cb_arg The optional argument to pass to the callback @@ -401,8 +547,8 @@ int ble_gattc_write(uint16_t conn_handle, uint16_t attr_handle, * procedure. * @param attr_handle The handle of the characteristic value to write * to. - * @param value The value to write to the characteristic. - * @param value_len The number of bytes to write. + * @param data The value to write to the characteristic. + * @param data_len The number of bytes to write. * @param cb The function to call to report procedure status * updates; null for no callback. * @param cb_arg The optional argument to pass to the callback @@ -422,7 +568,8 @@ int ble_gattc_write_flat(uint16_t conn_handle, uint16_t attr_handle, * procedure. * @param attr_handle The handle of the characteristic value to write * to. - * @param txom The value to write to the characteristic. + * @param offset The offset at which to begin writing the value. + * @param om The value to write to the characteristic. * @param cb The function to call to report procedure status * updates; null for no callback. * @param cb_arg The optional argument to pass to the callback @@ -464,9 +611,9 @@ int ble_gattc_write_reliable(uint16_t conn_handle, * * @param conn_handle The connection over which to execute the * procedure. - * @param chr_val_handle The attribute handle to indicate in the + * @param att_handle The attribute handle to indicate in the * outgoing notification. - * @param txom The value to write to the characteristic. + * @param om The value to write to the characteristic. * * @return 0 on success; nonzero on failure. */ @@ -539,16 +686,21 @@ int ble_gatts_indicate(uint16_t conn_handle, uint16_t chr_val_handle); */ int ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle); +/** Initialize the BLE GATT client. */ int ble_gattc_init(void); /*** @server. */ struct ble_gatt_access_ctxt; + +/** Type definition for GATT access callback function. */ typedef int ble_gatt_access_fn(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); +/** Type definition for GATT characteristic flags. */ typedef uint16_t ble_gatt_chr_flags; +/** Represents the definition of a GATT characteristic. */ struct ble_gatt_chr_def { /** * Pointer to characteristic UUID; use BLE_UUIDxx_DECLARE macros to declare @@ -585,6 +737,7 @@ struct ble_gatt_chr_def { uint16_t *val_handle; }; +/** Represents the definition of a GATT service. */ struct ble_gatt_svc_def { /** * One of the following: @@ -614,6 +767,7 @@ struct ble_gatt_svc_def { const struct ble_gatt_chr_def *characteristics; }; +/** Represents the definition of a GATT descriptor. */ struct ble_gatt_dsc_def { /** * Pointer to descriptor UUID; use BLE_UUIDxx_DECLARE macros to declare @@ -759,6 +913,7 @@ struct ble_gatt_register_ctxt { }; }; +/** Type definition for GATT registration callback function. */ typedef void ble_gatt_register_fn(struct ble_gatt_register_ctxt *ctxt, void *arg); @@ -855,7 +1010,7 @@ int ble_gatts_find_chr(const ble_uuid_t *svc_uuid, const ble_uuid_t *chr_uuid, * @param svc_uuid The UUID of the grandparent service. * @param chr_uuid The UUID of the parent characteristic. * @param dsc_uuid The UUID of the descriptor ro look up. - * @param out_handle On success, populated with the handle + * @param out_dsc_handle On success, populated with the handle * of the descriptor attribute. Pass null if * you don't need this value. * @@ -867,6 +1022,7 @@ int ble_gatts_find_chr(const ble_uuid_t *svc_uuid, const ble_uuid_t *chr_uuid, int ble_gatts_find_dsc(const ble_uuid_t *svc_uuid, const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid, uint16_t *out_dsc_handle); +/** Type definition for GATT service iteration callback function. */ typedef void (*ble_gatt_svc_foreach_fn)(const struct ble_gatt_svc_def *svc, uint16_t handle, uint16_t end_group_handle, From 4cf74c3bf50cc68302e2ce87176f300cac3afcac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 1 Aug 2023 09:48:06 +0200 Subject: [PATCH 0777/1333] apps/bttester: remove unstalled_cb from btp_l2cap.c Response to BTP_L2CAP_SEND_DATA command is already sent in command handler (`send_data()`). Sending further responses to already answered command is confusing - we cannot fail successful procedure retroactively. Data sending is already confirmed to be started successfully and no further responses are expected - more so, it appears to break `available_queue` management and further commands cannot be processed correctly. Similar callback may be proposed in the future if confirmation of sending data is needed, but not in form of BTP response, but BTP event. --- apps/bttester/src/btp_l2cap.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/apps/bttester/src/btp_l2cap.c b/apps/bttester/src/btp_l2cap.c index 34749af7fb..916e714e7d 100644 --- a/apps/bttester/src/btp_l2cap.c +++ b/apps/bttester/src/btp_l2cap.c @@ -140,19 +140,6 @@ recv_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, tester_l2cap_coc_recv(chan, buf); } -static void -unstalled_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, - int status, void *arg) -{ - if (status) { - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, - BTP_STATUS_FAILED); - } else { - tester_rsp(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_SEND_DATA, - BTP_STATUS_SUCCESS); - } -} - static void reconfigured_ev(uint16_t conn_handle, struct ble_l2cap_chan *chan, struct ble_l2cap_chan_info *chan_info, @@ -349,10 +336,6 @@ tester_l2cap_event(struct ble_l2cap_event *event, void *arg) (uint32_t) event->tx_unstalled.chan, event->tx_unstalled.conn_handle, event->tx_unstalled.status); - - unstalled_cb(event->tx_unstalled.conn_handle, - event->tx_unstalled.chan, - event->tx_unstalled.status, arg); return 0; case BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED: if (ble_l2cap_get_chan_info(event->reconfigured.chan, From 765f9d97ba545578dacffae059a12478edcce995 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Mon, 19 Jun 2023 16:26:34 +0200 Subject: [PATCH 0778/1333] host/l2cap: add doxygen comments for the header file Adds missing macros, structures and functions documentation. --- nimble/host/include/host/ble_l2cap.h | 368 ++++++++++++++++++++++++++- 1 file changed, 366 insertions(+), 2 deletions(-) diff --git a/nimble/host/include/host/ble_l2cap.h b/nimble/host/include/host/ble_l2cap.h index 6edfa85d78..f836e97c6c 100644 --- a/nimble/host/include/host/ble_l2cap.h +++ b/nimble/host/include/host/ble_l2cap.h @@ -17,6 +17,20 @@ * under the License. */ +/** + * @file ble_l2cap.h + * + * @brief L2CAP (Logical Link Control and Adaptation Protocol) API + * + * This header file provides the public API for interacting with the L2CAP layer of the BLE + * (Bluetooth Low Energy) stack. L2CAP is responsible for managing logical channels between + * two connected BLE devices. + * + * @defgroup bt_host_l2cap Bluetooth Host Logical Link Control and Adaptation Protocol + * @ingroup bt_host + * @{ + */ + #ifndef H_BLE_L2CAP_ #define H_BLE_L2CAP_ @@ -25,89 +39,311 @@ extern "C" { #endif +/** + * @brief L2CAP Signaling Connection Parameters Update Request. + * + * This structure represents a request to update the L2CAP connection parameters. + */ struct ble_l2cap_sig_update_req; + +/** + * @brief BLE Host Connection structure. + * + * This structure represents a connection between the BLE host and a remote device. + */ struct ble_hs_conn; +/** + * @defgroup ble_l2cap_channel_ids Channel Identifiers + * @{ + */ +/** Attribute Protocol (ATT) CID. */ #define BLE_L2CAP_CID_ATT 4 + +/** L2CAP LE Signaling CID. */ #define BLE_L2CAP_CID_SIG 5 + +/** Security Manager (SM) CID. */ #define BLE_L2CAP_CID_SM 6 +/** @} */ + +/** + * @defgroup ble_l2cap_signaling_op_codes Signaling Commands Operation Codes + * @{ + */ + +/** Reject */ #define BLE_L2CAP_SIG_OP_REJECT 0x01 + +/** Connect Request */ #define BLE_L2CAP_SIG_OP_CONNECT_REQ 0x02 + +/** Connect Response */ #define BLE_L2CAP_SIG_OP_CONNECT_RSP 0x03 + +/** Configuration Request */ #define BLE_L2CAP_SIG_OP_CONFIG_REQ 0x04 + +/** Configuration Response */ #define BLE_L2CAP_SIG_OP_CONFIG_RSP 0x05 + +/** Disconnect Request */ #define BLE_L2CAP_SIG_OP_DISCONN_REQ 0x06 + +/** Disconnect Response */ #define BLE_L2CAP_SIG_OP_DISCONN_RSP 0x07 + +/** Echo Request */ #define BLE_L2CAP_SIG_OP_ECHO_REQ 0x08 + +/** Echo Response */ #define BLE_L2CAP_SIG_OP_ECHO_RSP 0x09 + +/** Information Request */ #define BLE_L2CAP_SIG_OP_INFO_REQ 0x0a + +/** Information Response */ #define BLE_L2CAP_SIG_OP_INFO_RSP 0x0b + +/** Create Channel Request */ #define BLE_L2CAP_SIG_OP_CREATE_CHAN_REQ 0x0c + +/** Create Channel Response */ #define BLE_L2CAP_SIG_OP_CREATE_CHAN_RSP 0x0d + +/** Move Channel Request */ #define BLE_L2CAP_SIG_OP_MOVE_CHAN_REQ 0x0e + +/** Move Channel Response */ #define BLE_L2CAP_SIG_OP_MOVE_CHAN_RSP 0x0f + +/** Move Channel Confirmation Request */ #define BLE_L2CAP_SIG_OP_MOVE_CHAN_CONF_REQ 0x10 + +/** Move Channel Confirmation Response */ #define BLE_L2CAP_SIG_OP_MOVE_CHAN_CONF_RSP 0x11 + +/** Update Request */ #define BLE_L2CAP_SIG_OP_UPDATE_REQ 0x12 + +/** Update Response */ #define BLE_L2CAP_SIG_OP_UPDATE_RSP 0x13 + +/** LE Credit Based Connection Request */ #define BLE_L2CAP_SIG_OP_LE_CREDIT_CONNECT_REQ 0x14 + +/** LE Credit Based Connection Response */ #define BLE_L2CAP_SIG_OP_LE_CREDIT_CONNECT_RSP 0x15 + +/** Credit Based Flow Control Credit */ #define BLE_L2CAP_SIG_OP_FLOW_CTRL_CREDIT 0x16 + +/** Credit Based Connection Request */ #define BLE_L2CAP_SIG_OP_CREDIT_CONNECT_REQ 0x17 + +/** Credit Based Connection Response */ #define BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP 0x18 + +/** Credit Based Reconfiguration Request */ #define BLE_L2CAP_SIG_OP_CREDIT_RECONFIG_REQ 0x19 + +/** Credit Based Reconfiguration Response */ #define BLE_L2CAP_SIG_OP_CREDIT_RECONFIG_RSP 0x1A + +/** Signaling Command Maximum Value */ #define BLE_L2CAP_SIG_OP_MAX 0x1B +/** @} */ + +/** + * @defgroup ble_l2cap_signaling_err_codes Signaling Commands Error Codes + * @{ + */ + +/** Command Not Understood */ #define BLE_L2CAP_SIG_ERR_CMD_NOT_UNDERSTOOD 0x0000 + +/** Maximum Transmission Unit (MTU) Exceeded */ #define BLE_L2CAP_SIG_ERR_MTU_EXCEEDED 0x0001 + +/** Invalid CID */ #define BLE_L2CAP_SIG_ERR_INVALID_CID 0x0002 +/** @} */ + +/** + * @defgroup ble_l2cap_coc_err_codes Connection-Oriented Channels (CoC) Error Codes + * @{ + */ + +/** Connection Success */ #define BLE_L2CAP_COC_ERR_CONNECTION_SUCCESS 0x0000 + +/** Unknown LE Protocol/Service Multiplexer (PSM) */ #define BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM 0x0002 + +/** No Resources */ #define BLE_L2CAP_COC_ERR_NO_RESOURCES 0x0004 + +/** Insufficient Authentication */ #define BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN 0x0005 + +/** Insufficient Authorization */ #define BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR 0x0006 + +/** Insufficient Key Size */ #define BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ 0x0007 + +/** Insufficient Encryption */ #define BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC 0x0008 + +/** Invalid Source CID */ #define BLE_L2CAP_COC_ERR_INVALID_SOURCE_CID 0x0009 + +/** Source CID Already Used */ #define BLE_L2CAP_COC_ERR_SOURCE_CID_ALREADY_USED 0x000A + +/** Unacceptable Parameters */ #define BLE_L2CAP_COC_ERR_UNACCEPTABLE_PARAMETERS 0x000B + +/** Invalid Parameters */ #define BLE_L2CAP_COC_ERR_INVALID_PARAMETERS 0x000C +/** @} */ + +/** + * @defgroup ble_l2cap_reconfig_err_codes Channel Reconfiguration Error Codes + * @{ + */ + +/** Reconfiguration Succeeded */ #define BLE_L2CAP_ERR_RECONFIG_SUCCEED 0x0000 + +/** Reduction of Maximum Transmission Unit (MTU) Not Allowed */ #define BLE_L2CAP_ERR_RECONFIG_REDUCTION_MTU_NOT_ALLOWED 0x0001 + +/** Reduction of Maximum Packet Size (MPS) Not Allowed */ #define BLE_L2CAP_ERR_RECONFIG_REDUCTION_MPS_NOT_ALLOWED 0x0002 + +/** Invalid Destination CID */ #define BLE_L2CAP_ERR_RECONFIG_INVALID_DCID 0x0003 + +/** Unaccepted Parameters */ #define BLE_L2CAP_ERR_RECONFIG_UNACCEPTED_PARAM 0x0004 +/** @} */ + +/** + * @defgroup ble_l2cap_coc_event_types Connection-Oriented Channel (CoC) Event Types + * @{ + */ + +/** CoC Connected */ #define BLE_L2CAP_EVENT_COC_CONNECTED 0 + +/** CoC Disconnected */ #define BLE_L2CAP_EVENT_COC_DISCONNECTED 1 + +/** CoC Accept */ #define BLE_L2CAP_EVENT_COC_ACCEPT 2 + +/** CoC Data Received */ #define BLE_L2CAP_EVENT_COC_DATA_RECEIVED 3 + +/** CoC Transmission Unstalled */ #define BLE_L2CAP_EVENT_COC_TX_UNSTALLED 4 + +/** CoC Reconfiguration Completed */ #define BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED 5 + +/** CoC Peer Reconfigured */ #define BLE_L2CAP_EVENT_COC_PEER_RECONFIGURED 6 +/** @} */ + + +/** + * @brief Function signature for L2CAP signaling update event callback. + * + * This function is used to handle signaling update events in the L2CAP layer, + * such as changes in connection parameters. + * + * @param conn_handle The connection handle associated with the signaling update event. + * @param status The status of the signaling update event. + * @param arg A pointer to additional arguments passed to the callback function. + */ typedef void ble_l2cap_sig_update_fn(uint16_t conn_handle, int status, void *arg); +/** + * @brief Represents the signaling update in L2CAP. + * + * This structure holds the parameters required for initiating a signaling update in the L2CAP layer. + * It defines the connection interval, slave latency, and supervision timeout multiplier for the update. + */ struct ble_l2cap_sig_update_params { + /** + * The minimum desired connection interval in increments of 1.25 ms. + * This value defines the lower bound for the connection interval range. + */ uint16_t itvl_min; + + /** + * The maximum desired connection interval in increments of 1.25 ms. + * This value defines the upper bound for the connection interval range. + */ uint16_t itvl_max; + + /** + * The desired number of connection events that a slave device can skip. + * It specifies the maximum allowed latency between consecutive connection events. + */ uint16_t slave_latency; + + /** + * The desired supervision timeout multiplier. + * The supervision timeout defines the time limit for detecting the loss of a connection. + * This value is multiplied by the connection interval to determine the supervision timeout duration. + */ uint16_t timeout_multiplier; }; +/** + * @brief Initiate an L2CAP connection update procedure. + * + * This function initiates an L2CAP connection update procedure for the specified connection handle. + * The update procedure is used to modify the connection parameters, such as interval, latency, and timeout. + * + * @param conn_handle The connection handle of the L2CAP connection. + * + * @param params A pointer to a structure containing the desired update parameters. + * This includes the new connection interval, slave latency, and + * supervision timeout multiplier. + * + * @param cb The callback function to be called when the update request completes. + * The function signature for the callback is defined by `ble_l2cap_sig_update_fn`. + * + * @param cb_arg An optional argument to be passed to the callback function. + * + * @return 0 on success; + * A non-zero value on failure. + */ int ble_l2cap_sig_update(uint16_t conn_handle, struct ble_l2cap_sig_update_params *params, ble_l2cap_sig_update_fn *cb, void *cb_arg); +/** + * @brief Structure representing a L2CAP channel. + * + * It is used to maintain the state and track the properties of an L2CAP channel + * during its lifecycle. + */ struct ble_l2cap_chan; /** - * Represents a L2CAP-related event. + * @brief Represents a L2CAP-related event. + * * When such an event occurs, the host notifies the application by passing an * instance of this structure to an application-specified callback. */ @@ -234,33 +470,161 @@ struct ble_l2cap_event { }; }; +/** + * @brief Represents information about an L2CAP channel. + * + * This structure is typically used to retrieve or provide information about an existing L2CAP channel. + */ struct ble_l2cap_chan_info { + /** Source Channel Identifier. */ uint16_t scid; + + /** Destination Channel Identifier. */ uint16_t dcid; + + /** Local L2CAP Maximum Transmission Unit. */ uint16_t our_l2cap_mtu; + + /** Peer L2CAP Maximum Transmission Unit. */ uint16_t peer_l2cap_mtu; + + /** Protocol/Service Multiplexer of the channel. */ uint16_t psm; + + /** Local CoC Maximum Transmission Unit. */ uint16_t our_coc_mtu; + + /** Peer CoC Maximum Transmission Unit. */ uint16_t peer_coc_mtu; }; +/** + * @brief Function pointer type for handling L2CAP events. + * + * @param event A pointer to the L2CAP event structure. + * @param arg A pointer to additional arguments passed to the callback function. + * + * @return Integer value representing the status or result of the event handling. + */ typedef int ble_l2cap_event_fn(struct ble_l2cap_event *event, void *arg); - +/** + * @brief Get the connection handle associated with an L2CAP channel. + * + * This function retrieves the connection handle associated with the specified L2CAP channel. + * + * @param chan A pointer to the L2CAP channel structure. + * + * @return The connection handle associated with the L2CAP channel on success; + * A Bluetooth Host Error Code on failure: + * BLE_HS_CONN_HANDLE_NONE: if the provided channel pointer is NULL. + */ uint16_t ble_l2cap_get_conn_handle(struct ble_l2cap_chan *chan); + +/** + * @brief Create an L2CAP server. + * + * This function creates an L2CAP server with the specified Protocol/Service Multiplexer (PSM) and Maximum + * Transmission Unit (MTU) size. The server is used to accept incoming L2CAP connections from remote clients. + * When a connection request is received, the provided callback function will be invoked with the corresponding + * event information. + * + * @param psm The Protocol/Service Multiplexer (PSM) for the server. + * @param mtu The Maximum Transmission Unit (MTU) size for the server. + * @param cb Pointer to the callback function to be invoked when a connection request is received. + * @param cb_arg An optional argument to be passed to the callback function. + * + * @return 0 on success; + * A non-zero value on failure. + */ int ble_l2cap_create_server(uint16_t psm, uint16_t mtu, ble_l2cap_event_fn *cb, void *cb_arg); +/** + * @brief Initiate an L2CAP connection. + * + * This function initiates an L2CAP connection to a remote device with the specified connection handle, + * Protocol/Service Multiplexer (PSM), Maximum Transmission Unit (MTU) size, and receive SDU buffer. + * When the connection is established or if there is an error during the connection process, the provided + * callback function will be invoked with the corresponding event information. + * + * @param conn_handle The connection handle for the remote device. + * @param psm The Protocol/Service Multiplexer (PSM) for the connection. + * @param mtu The Maximum Transmission Unit (MTU) size for the connection. + * @param sdu_rx Pointer to the receive Service Data Unit (SDU) buffer. + * @param cb Pointer to the callback function to be invoked when the connection is established. + * @param cb_arg An optional argument to be passed to the callback function. + * + * @return 0 on success; + * A non-zero value on failure. + */ int ble_l2cap_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, struct os_mbuf *sdu_rx, ble_l2cap_event_fn *cb, void *cb_arg); + +/** + * @brief Disconnect an L2CAP channel. + * + * This function disconnects the specified L2CAP channel by sending a disconnect signal. + * + * @param chan Pointer to the L2CAP channel structure representing the channel to disconnect. + * + * @return 0 on success; + * A non-zero value on failure. + */ int ble_l2cap_disconnect(struct ble_l2cap_chan *chan); + +/** + * @brief Send an SDU (Service Data Unit) over an L2CAP channel. + * + * This function sends an SDU over the specified L2CAP channel. The SDU is encapsulated + * in L2CAP frames and transmitted to the remote device. + * + * @param chan Pointer to the L2CAP channel structure representing the channel to send the SDU on. + * @param sdu_tx Pointer to the os_mbuf structure containing the SDU (Service Data Unit) to send. + * + * @return 0 on success; + * BLE_HS_ESTALLED: if there was not enough credits available to send whole SDU. + * The application needs to wait for the event 'BLE_L2CAP_EVENT_COC_TX_UNSTALLED' + * before being able to transmit more data; + * Another non-zero value on failure. + */ int ble_l2cap_send(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_tx); + +/** + * @brief Check if the L2CAP channel is ready to receive an SDU. + * + * This function checks if the specified L2CAP channel is ready to receive an SDU (Service Data Unit). + * It can be used to determine if the channel is in a state where it can accept incoming data. + * + * @param chan Pointer to the L2CAP channel structure to check. + * @param sdu_rx Pointer to the os_mbuf structure to receive the incoming SDU. + * + * @return 0 if the channel is ready to receive an SDU; + * A non-zero value on failure. + */ int ble_l2cap_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx); + +/** + * @brief Get information about an L2CAP channel. + * + * This function retrieves information about the specified L2CAP channel and populates + * the provided `ble_l2cap_chan_info` structure with the channel's details. + * + * @param chan Pointer to the L2CAP channel structure to retrieve information from. + * @param chan_info Pointer to the `ble_l2cap_chan_info` structure to populate with channel information. + * + * @return 0 on success; + * A non-zero value on failure. + */ int ble_l2cap_get_chan_info(struct ble_l2cap_chan *chan, struct ble_l2cap_chan_info *chan_info); #ifdef __cplusplus } #endif +/** + * @} + */ + #endif From 99e6c0e8fa8baa72ba1d76c31ecd69af2e17a4ae Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Wed, 19 Jul 2023 17:56:51 +0200 Subject: [PATCH 0779/1333] host/hs: add doxygen comments for the header file Adds missing macros and structures documentation. --- nimble/host/include/host/ble_hs.h | 63 +++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/nimble/host/include/host/ble_hs.h b/nimble/host/include/host/ble_hs.h index 1f4f19041f..09900fd39d 100644 --- a/nimble/host/include/host/ble_hs.h +++ b/nimble/host/include/host/ble_hs.h @@ -49,6 +49,7 @@ extern "C" { #endif +/** Represents an infinite value for timeouts or durations. */ #define BLE_HS_FOREVER INT32_MAX /** Connection handle not present */ @@ -64,36 +65,97 @@ extern "C" { * @{ */ +/** Operation failed and should be retried later. */ #define BLE_HS_EAGAIN 1 + +/** Operation already in progress. */ #define BLE_HS_EALREADY 2 + +/** Invalid parameter. */ #define BLE_HS_EINVAL 3 + +/** Message too long. */ #define BLE_HS_EMSGSIZE 4 + +/** No such entry. */ #define BLE_HS_ENOENT 5 + +/** Out of memory. */ #define BLE_HS_ENOMEM 6 + +/** Not connected. */ #define BLE_HS_ENOTCONN 7 + +/** Not supported. */ #define BLE_HS_ENOTSUP 8 + +/** Application error. */ #define BLE_HS_EAPP 9 + +/** Bad data. */ #define BLE_HS_EBADDATA 10 + +/** Operating System error. */ #define BLE_HS_EOS 11 + +/** Controller error. */ #define BLE_HS_ECONTROLLER 12 + +/** Operation timed out. */ #define BLE_HS_ETIMEOUT 13 + +/** Operation completed. */ #define BLE_HS_EDONE 14 + +/** Resource busy. */ #define BLE_HS_EBUSY 15 + +/** Operation rejected. */ #define BLE_HS_EREJECT 16 + +/** Unknown error. */ #define BLE_HS_EUNKNOWN 17 + +/** Role error. */ #define BLE_HS_EROLE 18 + +/** HCI operation timed out. */ #define BLE_HS_ETIMEOUT_HCI 19 + +/** Out of memory to handle an event. */ #define BLE_HS_ENOMEM_EVT 20 + +/** No valid address. */ #define BLE_HS_ENOADDR 21 + +/** Not synchronized with the controller. */ #define BLE_HS_ENOTSYNCED 22 + +/** Authentication error. */ #define BLE_HS_EAUTHEN 23 + +/** Authorization error. */ #define BLE_HS_EAUTHOR 24 + +/** Encryption error. */ #define BLE_HS_EENCRYPT 25 + +/** Invalid encryption key size. */ #define BLE_HS_EENCRYPT_KEY_SZ 26 + +/** Storage capacity exceeded. */ #define BLE_HS_ESTORE_CAP 27 + +/** Storage operation failed. */ #define BLE_HS_ESTORE_FAIL 28 + +/** Operation was preempted. */ #define BLE_HS_EPREEMPTED 29 + +/** Operation disabled. */ #define BLE_HS_EDISABLED 30 + +/** Operation stalled. */ #define BLE_HS_ESTALLED 31 /** Error base for ATT errors */ @@ -305,6 +367,7 @@ struct ble_hs_cfg { void *store_status_arg; }; +/** Configuration structure for the NimBLE Host stack. */ extern struct ble_hs_cfg ble_hs_cfg; /** From 68447ea14d4b5b9aa5cb2fb103db9084186a18e7 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 4 Aug 2023 13:17:29 +0200 Subject: [PATCH 0780/1333] ci: Fix build due to nrfx update We should move to using "newt upgrade" eventually. --- .github/workflows/build_targets.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_targets.yml b/.github/workflows/build_targets.yml index 235a8c2840..3112cac803 100644 --- a/.github/workflows/build_targets.yml +++ b/.github/workflows/build_targets.yml @@ -54,7 +54,7 @@ jobs: git clone --depth=1 https://github.com/mcu-tools/mcuboot.git repos/mcuboot git clone --depth=1 https://github.com/apache/mynewt-mcumgr repos/apache-mynewt-mcumgr git clone --depth=1 https://github.com/hathach/tinyusb.git repos/tinyusb - git clone --depth=1 https://github.com/NordicSemiconductor/nrfx --branch v2.8.0 repos/nordic-nrfx + git clone --depth=1 https://github.com/NordicSemiconductor/nrfx --branch v2.11.0 repos/nordic-nrfx - name: Build targets shell: bash run: | From 5812f7d9824554eedaf49ebcc16f3618dcd24ac0 Mon Sep 17 00:00:00 2001 From: Jakub Rotkiewicz Date: Fri, 28 Jul 2023 16:10:17 +0200 Subject: [PATCH 0781/1333] host: Added function to parse UUID from string --- nimble/host/include/host/ble_uuid.h | 19 ++++ nimble/host/src/ble_uuid.c | 150 ++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) diff --git a/nimble/host/include/host/ble_uuid.h b/nimble/host/include/host/ble_uuid.h index a63104b4c1..be96bb4227 100644 --- a/nimble/host/include/host/ble_uuid.h +++ b/nimble/host/include/host/ble_uuid.h @@ -253,6 +253,25 @@ void ble_uuid_copy(ble_uuid_any_t *dst, const ble_uuid_t *src); */ char *ble_uuid_to_str(const ble_uuid_t *uuid, char *dst); +/** + * @brief Converts the specified UUID string to ble_uuid_any_t representation. + * If the UUID is recognised as Bluetooth SIG UUID, it will provide its + * 32-bit or 16-bit representation. + * + * Example 128-bit string representations: + * o "12345678-1234-1234-1234-123456789abc" + * o "12345678123412341234123456789abc" + * + * @param uuid Destination UUID. + * @param str The source string UUID. + * + * @return 0 on success, + * BLE_HS_EINVAL if the specified UUID string has wrong size or + * contains disallowed characters. + */ +int +ble_uuid_from_str(ble_uuid_any_t *uuid, const char *str); + /** @brief Converts the specified 16-bit UUID to a uint16_t. * * @param uuid The source UUID to convert. diff --git a/nimble/host/src/ble_uuid.c b/nimble/host/src/ble_uuid.c index acf016a136..afc437b786 100644 --- a/nimble/host/src/ble_uuid.c +++ b/nimble/host/src/ble_uuid.c @@ -26,6 +26,10 @@ #include "ble_hs_priv.h" #include "host/ble_uuid.h" +#define BLE_UUID16_STR_MAX_LEN 6 +#define BLE_UUID32_STR_MAX_LEN 10 +#define BLE_UUID128_STR_MAX_LEN 36 + static uint8_t ble_uuid_base[16] = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 @@ -40,6 +44,52 @@ static uint8_t ble_uuid_base[16] = { #define VERIFY_UUID(uuid) #endif +static int +hex2val(char c, uint8_t *value) +{ + if (c >= '0' && c <= '9') { + *value = c - '0'; + } else if (c >= 'a' && c <= 'f') { + *value = c - 'a' + 10; + } else if (c >= 'A' && c <= 'F') { + *value = c - 'A' + 10; + } else { + return BLE_HS_EINVAL; + } + return 0; +} + + +static size_t +hex2bin(const char *hex, uint8_t *bin, size_t bin_len) +{ + size_t len = 0; + uint8_t tmp_val; + int rc; + + while (*hex && len < bin_len) { + rc = hex2val(*hex++, &tmp_val); + if (rc < 0) { + return 0; + } + + bin[len] = tmp_val << 4; + + if (!*hex) { + len++; + break; + } + + rc = hex2val(*hex++, &tmp_val); + if (rc < 0) { + return 0; + } + bin[len++] |= tmp_val; + } + + return len; +} + int ble_uuid_init_from_buf(ble_uuid_any_t *uuid, const void *buf, size_t len) { @@ -136,6 +186,106 @@ ble_uuid_to_str(const ble_uuid_t *uuid, char *dst) return dst; } +int +ble_uuid_from_str(ble_uuid_any_t *uuid, const char *str) +{ + uint8_t tmp_rslt = 0; + uint8_t *u8p; + const char *str_ptr; + uint16_t u16 = 0; + uint32_t u32 = 0; + int len = (int) strlen(str); + + if ((len < 4) || (len % 2 != 0)) { + return BLE_HS_EINVAL; + } + + str_ptr = &str[len - 2]; + + if (len <= BLE_UUID16_STR_MAX_LEN) { + uuid->u.type = BLE_UUID_TYPE_16; + } else if (len <= BLE_UUID32_STR_MAX_LEN) { + uuid->u.type = BLE_UUID_TYPE_32; + } else if (len <= BLE_UUID128_STR_MAX_LEN) { + uuid->u.type = BLE_UUID_TYPE_128; + } else { + return BLE_HS_EINVAL; + } + + switch (uuid->u.type) { + case BLE_UUID_TYPE_128: + uuid->u.type = BLE_UUID_TYPE_128; + u8p = uuid->u128.value; + for (int i = 0; i < 16; i++) { + if (hex2bin(str_ptr, u8p, 1) != 1) { + return BLE_HS_EINVAL; + } + + /* Check if string end */ + if (str_ptr == str) { + break; + } + + /* Remove '-' */ + if (*(str_ptr - 1) == '-') { + str_ptr--; + } + + str_ptr -= 2; + u8p++; + } + + if (memcmp(ble_uuid_base, uuid->u128.value, 12) == 0) { + uint8_t *tmp_ptr = &uuid->u128.value[12]; + uint32_t tmp_val32 = 0; + for (int i = 0; i < 4; i++) { + tmp_val32 |= ((uint32_t)(*tmp_ptr++) << 8 * i); + } + + if (tmp_val32 <= UINT16_MAX) { + uuid->u.type = BLE_UUID_TYPE_16; + uuid->u16.value = (uint16_t) tmp_val32; + } else { + uuid->u.type = BLE_UUID_TYPE_32; + uuid->u32.value = tmp_val32; + } + } + break; + case BLE_UUID_TYPE_32: + for (int i = 0; i < 4; i++) { + if (hex2bin(str_ptr, &tmp_rslt, 1) != 1) { + return BLE_HS_EINVAL; + } + u32 |= ((uint32_t) tmp_rslt) << (i * 8); + + if (str_ptr == str) { + break; + } + str_ptr -= 2; + } + uuid->u32.value = u32; + break; + case BLE_UUID_TYPE_16: + for (int i = 0; i < 2; i++) { + if (hex2bin(str_ptr, &tmp_rslt, 1) != 1) { + return BLE_HS_EINVAL; + } + u16 |= ((uint32_t) tmp_rslt) << (i * 8); + + if (str_ptr == str) { + break; + } + str_ptr -= 2; + } + uuid->u16.value = u16; + break; + default: + return BLE_HS_EINVAL; + } + + return 0; +} + uint16_t ble_uuid_u16(const ble_uuid_t *uuid) { From ebae7a2252b14ad43a687cebfe7a29e0bcba315f Mon Sep 17 00:00:00 2001 From: Jakub Rotkiewicz Date: Fri, 28 Jul 2023 16:10:57 +0200 Subject: [PATCH 0782/1333] nimble/host/test: Added unit tests for UUID from string --- nimble/host/test/src/ble_uuid_test.c | 229 ++++++++++++++++++++++++++- 1 file changed, 225 insertions(+), 4 deletions(-) diff --git a/nimble/host/test/src/ble_uuid_test.c b/nimble/host/test/src/ble_uuid_test.c index 786e371ac4..379fd1f441 100644 --- a/nimble/host/test/src/ble_uuid_test.c +++ b/nimble/host/test/src/ble_uuid_test.c @@ -24,8 +24,75 @@ #include "host/ble_uuid.h" #include "ble_hs_test_util.h" -TEST_CASE_SELF(ble_uuid_test) -{ +#define DEBUG 0 + +#if DEBUG +#define DEBUG_PRINT(fmt, ...) printf(fmt, ## __VA_ARGS__) +#else +#define DEBUG_PRINT(fmt, ...) +#endif + +#define TEST_UUID_128_1_STR "0329a25a-c4c4-4923-8039-4bacfa18eb72" +#define TEST_UUID_128_1 \ + 0x72, 0xeb, 0x18, 0xfa, 0xac, 0x4b, 0x39, 0x80, \ + 0x23, 0x49, 0xc4, 0xc4, 0x5a, 0xa2, 0x29, 0x03 + +#define TEST_UUID_128_2_STR "e3ec4966df944981a772985ff8d75dff" +#define TEST_UUID_128_2 \ + 0xff, 0x5d, 0xd7, 0xf8, 0x5f, 0x98, 0x72, 0xa7, \ + 0x81, 0x49, 0x94, 0xdf, 0x66, 0x49, 0xec, 0xe3 + +#define TEST_UUID_128_3_STR "00002a37-0000-1000-8000-00805f9b34fb" +#define TEST_UUID_128_3 \ + 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, \ + 0x00, 0x10, 0x00, 0x00, 0x37, 0x2a, 0x00, 0x00 +#define TEST_UUID_128_3_AS_16 ((uint16_t) 0x2a37) + +#define TEST_32UUID1_STR "0x0329a25a" +#define TEST_32UUID1 ((uint32_t)0x0329a25a) + +#define TEST_32UUID2_STR "e3ec4966" +#define TEST_32UUID2 ((uint32_t)0xe3ec4966) + +#define TEST_16UUID1_STR "0x0329" +#define TEST_16UUID1 ((uint16_t)0x0329) + +#define TEST_16UUID2_STR "e3ec" +#define TEST_16UUID2 ((uint16_t)0xe3ec) + +static const ble_uuid128_t test_uuid128[4] = { + BLE_UUID128_INIT(TEST_UUID_128_1), + BLE_UUID128_INIT(TEST_UUID_128_2), + BLE_UUID128_INIT(TEST_UUID_128_3) +}; + +static const char test_str128[][100] = { + TEST_UUID_128_1_STR, + TEST_UUID_128_2_STR, + TEST_UUID_128_3_STR +}; + +static const ble_uuid32_t test_uuid32[3] = { + BLE_UUID32_INIT(TEST_32UUID1), + BLE_UUID32_INIT(TEST_32UUID2), +}; + +static const char test_str32[][100] = { + TEST_32UUID1_STR, + TEST_32UUID2_STR, +}; + +static const ble_uuid16_t test_uuid16[3] = { + BLE_UUID16_INIT(TEST_16UUID1), + BLE_UUID16_INIT(TEST_16UUID2), +}; + +static const char test_str16[][100] = { + TEST_16UUID1_STR, + TEST_16UUID2_STR, +}; + +TEST_CASE_SELF(ble_uuid_test) { uint8_t buf_16[2] = { 0x00, 0x18 }; uint8_t buf_128[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; @@ -70,7 +137,161 @@ TEST_CASE_SELF(ble_uuid_test) ble_hs_test_util_assert_mbufs_freed(NULL); } -TEST_SUITE(ble_uuid_test_suite) -{ +TEST_CASE_SELF(ble_uuid_from_string_test) { + int rc; + ble_uuid_any_t uuid128[3]; + ble_uuid_any_t uuid32[3]; + ble_uuid_any_t uuid16[3]; + + for (int i = 0; i < 2; i++) { + DEBUG_PRINT("Test 128bit: %d\n", i); + ble_uuid_from_str((ble_uuid_any_t * ) &uuid128[i], test_str128[i]); + DEBUG_PRINT("Original:\n"); + for (int j = 0; j < 16; j++) { + DEBUG_PRINT("%2x, ", test_uuid128[i].value[j]); + } + DEBUG_PRINT("\nConverted:\n"); + for (int j = 0; j < 16; j++) { + DEBUG_PRINT("%2x, ", uuid128[i].u128.value[j]); + } + DEBUG_PRINT("\n"); + DEBUG_PRINT("The same: %s\n", + ble_uuid_cmp((const ble_uuid_t *) &uuid128[i].u128, + (const ble_uuid_t *) &test_uuid128[i]) == 0 + ? "true" : "false"); + rc = ble_uuid_cmp((const ble_uuid_t *) &uuid128[i].u128, + (const ble_uuid_t *) &test_uuid128[i]); + TEST_ASSERT(rc == 0); + } + + DEBUG_PRINT("\n"); + DEBUG_PRINT("\n"); + + for (int i = 0; i < 2; i++) { + DEBUG_PRINT("Test 32bit: %d\n", i); + ble_uuid_from_str((ble_uuid_any_t * ) &uuid32[i], test_str32[i]); + DEBUG_PRINT("Original:\n"); + DEBUG_PRINT("%x, ", test_uuid32[i].value); + DEBUG_PRINT("\nConverted:\n"); + DEBUG_PRINT("%x, ", uuid32[i].u32.value); + DEBUG_PRINT("\n"); + DEBUG_PRINT("The same: %s\n", + ble_uuid_cmp((const ble_uuid_t *) &uuid32[i].u32, + (const ble_uuid_t *) &test_uuid32[i]) == 0 + ? "true" : "false"); + rc = ble_uuid_cmp((const ble_uuid_t *) &uuid32[i].u32, + (const ble_uuid_t *) &test_uuid32[i]); + TEST_ASSERT(rc == 0); + } + + DEBUG_PRINT("\n"); + DEBUG_PRINT("\n"); + + for (int i = 0; i < 2; i++) { + DEBUG_PRINT("Test 16bit: %d\n", i); + ble_uuid_from_str((ble_uuid_any_t * ) &uuid16[i], test_str16[i]); + DEBUG_PRINT("Original:\n"); + DEBUG_PRINT("%x, ", test_uuid16[i].value); + DEBUG_PRINT("\nConverted:\n"); + DEBUG_PRINT("%x, ", uuid16[i].u16.value); + DEBUG_PRINT("\n"); + DEBUG_PRINT("The same: %s\n", + ble_uuid_cmp((const ble_uuid_t *) &uuid16[i].u16, + (const ble_uuid_t *) &test_uuid16[i]) == 0 + ? "true" : "false"); + rc = ble_uuid_cmp((const ble_uuid_t *) &uuid16[i].u16, + (const ble_uuid_t *) &test_uuid16[i]); + TEST_ASSERT(rc == 0); + } + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + +TEST_CASE_SELF(ble_uuid_from_string_sig_test) { + int rc; + ble_uuid_any_t uuid; + + ble_uuid16_t test_uuid = BLE_UUID16_INIT(TEST_UUID_128_3_AS_16); + + DEBUG_PRINT("Test %d\n", 0); + ble_uuid_from_str(&uuid, test_str128[2]); + DEBUG_PRINT("Original:\n"); + for (int j = 0; j < 16; j++) { + DEBUG_PRINT("%2x, ", test_uuid128[2].value[j]); + } + DEBUG_PRINT("\nConverted:\n"); + DEBUG_PRINT("%x\n", uuid.u16.value); + DEBUG_PRINT("The same: %s\n", + ble_uuid_cmp((const ble_uuid_t *) &uuid.u16, + (const ble_uuid_t *) &test_uuid) == 0 ? "true" + : "false"); + rc = ble_uuid_cmp((const ble_uuid_t *)&uuid.u16, + (const ble_uuid_t *)&test_uuid); + TEST_ASSERT(rc == 0); + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + +TEST_CASE_SELF(ble_uuid_to_str_and_back_test) { + int rc; + ble_uuid128_t uuid = BLE_UUID128_INIT(TEST_UUID_128_1); + ble_uuid_any_t final_uuid; + char uuid_str[100]; + + ble_uuid_to_str((const ble_uuid_t *)&uuid, uuid_str); + + DEBUG_PRINT("String: %s\n", uuid_str); + + rc = ble_uuid_from_str(&final_uuid, (const char *)uuid_str); + TEST_ASSERT(rc == 0); + + rc = ble_uuid_cmp((const ble_uuid_t *)&uuid, (const ble_uuid_t *)&final_uuid.u128); + TEST_ASSERT(rc == 0); + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + +TEST_CASE_SELF(ble_uuid_to_str_too_short) { + int rc; + ble_uuid_any_t final_uuid; + char uuid_str[4] = "012"; + + DEBUG_PRINT("String: %s\n", uuid_str); + + rc = ble_uuid_from_str(&final_uuid, (const char *)uuid_str); + TEST_ASSERT(rc == BLE_HS_EINVAL); + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + +TEST_CASE_SELF(ble_uuid_to_str_sig_to_16_and_32) { + int rc; + ble_uuid_any_t final_uuid; + char uuid_str16[37] = "0000ffff-0000-1000-8000-00805f9b34fb"; + char uuid_str32[37] = "ffffffff-0000-1000-8000-00805f9b34fb"; + + DEBUG_PRINT("String16: %s\n", uuid_str16); + DEBUG_PRINT("String32: %s\n", uuid_str32); + + rc = ble_uuid_from_str(&final_uuid, (const char *)uuid_str16); + TEST_ASSERT(rc == 0); + TEST_ASSERT(final_uuid.u.type == BLE_UUID_TYPE_16); + TEST_ASSERT(final_uuid.u16.value == UINT16_MAX); + memset(&final_uuid, 0, sizeof(ble_uuid_any_t)); + + rc = ble_uuid_from_str(&final_uuid, (const char *)uuid_str32); + TEST_ASSERT(rc == 0); + TEST_ASSERT(final_uuid.u.type == BLE_UUID_TYPE_32); + TEST_ASSERT(final_uuid.u32.value == UINT32_MAX); + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + +TEST_SUITE(ble_uuid_test_suite) { ble_uuid_test(); + ble_uuid_from_string_test(); + ble_uuid_from_string_sig_test(); + ble_uuid_to_str_and_back_test(); + ble_uuid_to_str_too_short(); + ble_uuid_to_str_sig_to_16_and_32(); } From 74517c7e7658c6afac52c895f06cc9707e344931 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 7 Aug 2023 10:13:00 +0200 Subject: [PATCH 0783/1333] nimble/ll: Fix build with BLE_LL_HCI_LLCP_TRACE enabled This was not updated after HCI VS event sending cleanup. --- nimble/controller/src/ble_ll_hci_ev.c | 6 +++--- nimble/include/nimble/hci_common.h | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index fb4424a596..dc74806258 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -643,16 +643,16 @@ void ble_ll_hci_ev_send_vs_llcp_trace(uint8_t type, uint16_t handle, uint16_t count, void *pdu, size_t length) { - struct ble_hci_ev_vs_debug *ev; + struct ble_hci_ev_vs *ev; struct ble_hci_ev *hci_ev; hci_ev = ble_transport_alloc_evt(1); if (hci_ev) { - hci_ev->opcode = BLE_HCI_EVCODE_VS_DEBUG; + hci_ev->opcode = BLE_HCI_EVCODE_VS; hci_ev->length = sizeof(*ev) + 8 + length; ev = (void *) hci_ev->data; - ev->id = 0x17; + ev->id = BLE_HCI_VS_SUBEV_ID_LLCP_TRACE; ev->data[0] = type; put_le16(&ev->data[1], handle); put_le16(&ev->data[3], count); diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 93429a2f52..742824d877 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1611,6 +1611,8 @@ struct ble_hci_ev_vs_css_slot_changed { uint16_t slot_idx; }; +#define BLE_HCI_VS_SUBEV_ID_LLCP_TRACE (0x17) + /* LE sub-event codes */ #define BLE_HCI_LE_SUBEV_CONN_COMPLETE (0x01) struct ble_hci_ev_le_subev_conn_complete { From fa5cc4702b46ab96003902921ba678db4cf67c98 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 7 Aug 2023 10:14:36 +0200 Subject: [PATCH 0784/1333] ci: Enable BLE_LL_HCI_LLCP_TRACE when building blehci nordic_pca10056_blehci_all_enabled was missing BLE_LL_HCI_LLCP_TRACE setting. --- .github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml b/.github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml index eace456a5c..5bb326eb62 100644 --- a/.github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml +++ b/.github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml @@ -36,3 +36,4 @@ syscfg.vals: BLE_PHY_DBG_TIME_TXRXEN_READY_PIN: 12 BLE_PHY_DBG_TIME_WFR_PIN: 16 BLE_XTAL_SETTLE_TIME: 1500 + BLE_LL_HCI_LLCP_TRACE: 1 From 25439ada84ae0c94bde85af84cfb07d2fc1e3305 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 7 Aug 2023 17:55:25 +0200 Subject: [PATCH 0785/1333] Update missing licenses and rat excludes --- .github/workflows/compliance_check.yml | 5 ++--- .rat-excludes | 12 +++++------- LICENSE | 10 ++++++++++ nimble/host/mesh/src/light_model.c | 5 +++++ nimble/host/mesh/src/shell.h | 6 ++++++ .../targets/nordic_pca10040_boot/pkg.yml | 17 +++++++++++++++++ .../targets/nordic_pca10040_boot/syscfg.yml | 0 .../targets/nordic_pca10040_boot/target.yml | 17 +++++++++++++++++ .../targets/nordic_pca10056_boot/pkg.yml | 17 +++++++++++++++++ .../targets/nordic_pca10056_boot/syscfg.yml | 0 .../targets/nordic_pca10056_boot/target.yml | 17 +++++++++++++++++ 11 files changed, 96 insertions(+), 10 deletions(-) delete mode 100644 tools/hci_throughput/targets/nordic_pca10040_boot/syscfg.yml delete mode 100644 tools/hci_throughput/targets/nordic_pca10056_boot/syscfg.yml diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index edacc93f6d..b73142abf9 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -50,9 +50,8 @@ jobs: run: | mkdir repos git clone --depth=1 https://github.com/apache/mynewt-core repos/apache-mynewt-core - wget https://dlcdn.apache.org//creadur/apache-rat-0.15/apache-rat-0.15-bin.tar.gz - tar zxf apache-rat-0.15-bin.tar.gz apache-rat-0.15/apache-rat-0.15.jar - mv apache-rat-0.15/apache-rat-0.15.jar apache-rat.jar + wget https://repository.apache.org/content/repositories/snapshots/org/apache/rat/apache-rat/0.16-SNAPSHOT/apache-rat-0.16-20230807.065048-315.jar + mv apache-rat-0.16-20230807.065048-315.jar apache-rat.jar - name: check licensing run: | ./repos/apache-mynewt-core/.github/check_license.py diff --git a/.rat-excludes b/.rat-excludes index a4bcb91b73..f29a97eb1d 100644 --- a/.rat-excludes +++ b/.rat-excludes @@ -17,21 +17,19 @@ pts-sm.txt uncrustify.cfg .style_ignored_dirs .mailmap +requirements.txt # tinycrypt - BSD License. tinycrypt -# Bluetooth Mesh - Apache 2.0 License -mesh - # Queue implementation - BSD License queue.h # mbuf implementation - BSD License os_mbuf.c -# Bluetooth Mesh badge sample - Apache 2.0 License -mesh_badge +# Nordic nRF5 SDK - BSD License +system_nrf52.c -#BabbleSim and EDDT - Apache 2.0 License -babblesim +# CMSIS-CORE - BSD License. +cmsis_nvic.h diff --git a/LICENSE b/LICENSE index 08b9b218a2..960e8257e9 100644 --- a/LICENSE +++ b/LICENSE @@ -215,3 +215,13 @@ under the following license: This product bundles tinycrypt, which is available under the "3-clause BSD" license. For details, and bundled files see: * ext/tinycrypt/LICENSE + +This product bundles and partly derives from parts of the Nordic nRF52 SDK, +which are available under a BSD style license. Relevant files are: + * babblesim/hw/mcu/nordic/nrf52_bsim/src/system_nrf52.c + +This product bundles additional files from CMSIS-CORE, but these files are +missing licensing information. The BSD license was subsequently added to +these files in later releases. These files are: + * babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/cmsis_nvic.h + diff --git a/nimble/host/mesh/src/light_model.c b/nimble/host/mesh/src/light_model.c index e7199519bb..5f0af48578 100644 --- a/nimble/host/mesh/src/light_model.c +++ b/nimble/host/mesh/src/light_model.c @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "syscfg/syscfg.h" diff --git a/nimble/host/mesh/src/shell.h b/nimble/host/mesh/src/shell.h index 53cc83a278..98d3f8c667 100644 --- a/nimble/host/mesh/src/shell.h +++ b/nimble/host/mesh/src/shell.h @@ -1,3 +1,9 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + #ifndef __SHELL_H__ #define __SHELL_H__ diff --git a/tools/hci_throughput/targets/nordic_pca10040_boot/pkg.yml b/tools/hci_throughput/targets/nordic_pca10040_boot/pkg.yml index dfcb1b63b7..b4f0ee6c19 100644 --- a/tools/hci_throughput/targets/nordic_pca10040_boot/pkg.yml +++ b/tools/hci_throughput/targets/nordic_pca10040_boot/pkg.yml @@ -1,3 +1,20 @@ +# 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: targets/nordic_pca10040_boot pkg.type: target pkg.description: diff --git a/tools/hci_throughput/targets/nordic_pca10040_boot/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10040_boot/syscfg.yml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tools/hci_throughput/targets/nordic_pca10040_boot/target.yml b/tools/hci_throughput/targets/nordic_pca10040_boot/target.yml index bbf2531475..ad6f05a347 100644 --- a/tools/hci_throughput/targets/nordic_pca10040_boot/target.yml +++ b/tools/hci_throughput/targets/nordic_pca10040_boot/target.yml @@ -1,3 +1,20 @@ +# 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. + target.app: "@mcuboot/boot/mynewt" target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10040" target.build_profile: optimized diff --git a/tools/hci_throughput/targets/nordic_pca10056_boot/pkg.yml b/tools/hci_throughput/targets/nordic_pca10056_boot/pkg.yml index 1b9a6cde18..5546afa89a 100644 --- a/tools/hci_throughput/targets/nordic_pca10056_boot/pkg.yml +++ b/tools/hci_throughput/targets/nordic_pca10056_boot/pkg.yml @@ -1,3 +1,20 @@ +# 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: targets/nordic_pca10056_boot pkg.type: target pkg.description: diff --git a/tools/hci_throughput/targets/nordic_pca10056_boot/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10056_boot/syscfg.yml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tools/hci_throughput/targets/nordic_pca10056_boot/target.yml b/tools/hci_throughput/targets/nordic_pca10056_boot/target.yml index 9cde39ac02..ff3aec125a 100644 --- a/tools/hci_throughput/targets/nordic_pca10056_boot/target.yml +++ b/tools/hci_throughput/targets/nordic_pca10056_boot/target.yml @@ -1,3 +1,20 @@ +# 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. + target.app: "@mcuboot/boot/mynewt" target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" target.build_profile: optimized From 3ea8edd45e27cb794896fc7350c3c7a09f0f1c26 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 9 Aug 2023 16:03:25 +0200 Subject: [PATCH 0786/1333] ci: Fix build after nrfx and mbedtls updates --- .github/workflows/build_targets.yml | 1 + .github/workflows/newt_test_all.yml | 2 ++ .github/workflows/ports_syscfg_check.yml | 2 ++ 3 files changed, 5 insertions(+) diff --git a/.github/workflows/build_targets.yml b/.github/workflows/build_targets.yml index 3112cac803..d1946f0478 100644 --- a/.github/workflows/build_targets.yml +++ b/.github/workflows/build_targets.yml @@ -55,6 +55,7 @@ jobs: git clone --depth=1 https://github.com/apache/mynewt-mcumgr repos/apache-mynewt-mcumgr git clone --depth=1 https://github.com/hathach/tinyusb.git repos/tinyusb git clone --depth=1 https://github.com/NordicSemiconductor/nrfx --branch v2.11.0 repos/nordic-nrfx + git clone --depth=1 https://github.com/Mbed-TLS/mbedtls.git --branch v2.28.4 repos/mbedtls - name: Build targets shell: bash run: | diff --git a/.github/workflows/newt_test_all.yml b/.github/workflows/newt_test_all.yml index 988ba09fd9..44bf601494 100644 --- a/.github/workflows/newt_test_all.yml +++ b/.github/workflows/newt_test_all.yml @@ -46,5 +46,7 @@ jobs: git clone --depth=1 https://github.com/mcu-tools/mcuboot.git repos/mcuboot git clone --depth=1 https://github.com/apache/mynewt-mcumgr repos/apache-mynewt-mcumgr git clone --depth=1 https://github.com/hathach/tinyusb.git repos/tinyusb + git clone --depth=1 https://github.com/NordicSemiconductor/nrfx --branch v2.11.0 repos/nordic-nrfx + git clone --depth=1 https://github.com/Mbed-TLS/mbedtls.git --branch v2.28.4 repos/mbedtls - name: newt test all run: newt test all diff --git a/.github/workflows/ports_syscfg_check.yml b/.github/workflows/ports_syscfg_check.yml index 07f1300544..e3c41633a4 100644 --- a/.github/workflows/ports_syscfg_check.yml +++ b/.github/workflows/ports_syscfg_check.yml @@ -50,6 +50,8 @@ jobs: git clone --depth=1 https://github.com/mcu-tools/mcuboot.git /tmp/proj/repos/mcuboot git clone --depth=1 https://github.com/apache/mynewt-mcumgr /tmp/proj/repos/apache-mynewt-mcumgr git clone --depth=1 https://github.com/hathach/tinyusb.git /tmp/proj/repos/tinyusb + git clone --depth=1 https://github.com/NordicSemiconductor/nrfx --branch v2.11.0 repos/nordic-nrfx + git clone --depth=1 https://github.com/Mbed-TLS/mbedtls.git --branch v2.28.4 repos/mbedtls cp -r `pwd` /tmp/proj/repos/apache-mynewt-nimble - name: Build ports tests targets run: | From df0718d7eacf414b2f4ed1e28f866250d92cadcb Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 9 Aug 2023 15:44:34 +0200 Subject: [PATCH 0787/1333] Prepare for NimBLE 1.6.0 release --- NOTICE | 2 +- README.md | 8 ++++---- RELEASE_NOTES.md | 18 +++++++----------- repository.yml | 4 ++++ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/NOTICE b/NOTICE index 0b205146a4..7e95f43482 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ Apache Mynewt NimBLE -Copyright 2015-2022 The Apache Software Foundation +Copyright 2015-2023 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). diff --git a/README.md b/README.md index fe75773da0..00cb27c636 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@

-Apache NimBLE is an open-source Bluetooth 5.1 stack (both Host & Controller) +Apache NimBLE is an open-source Bluetooth 5.4 stack (both Host & Controller) that completely replaces the proprietary SoftDevice on Nordic chipsets. It is part of [Apache Mynewt project](https://github.com/apache/mynewt-core). @@ -55,9 +55,9 @@ Feature highlight: ## Supported hardware -Controller supports Nordic nRF51 and nRF52 chipsets. Host runs on any board -and architecture [supported](https://github.com/apache/mynewt-core#overview) -by Apache Mynewt OS. +Controller supports Nordic nRF51, nRF52 and nRF5340 chipsets as well as DA1469x (cmac) +from Renesas. Host runs on any board and architecture +[supported](https://github.com/apache/mynewt-core#overview) by Apache Mynewt OS. ## Browsing diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index cde2ce272c..afd5e92a85 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,24 +1,20 @@ # RELEASE NOTES -20 April 2022 - Apache NimBLE v1.5.0 +09 August 2023 - Apache NimBLE v1.6.0 For full release notes, please visit the [Apache Mynewt Wiki](https://cwiki.apache.org/confluence/display/MYNEWT/Release+Notes). -Apache NimBLE is an open-source Bluetooth 5.3 stack (both Host & Controller) that completely +Apache NimBLE is an open-source Bluetooth 5.4 stack (both Host & Controller) that completely replaces the proprietary SoftDevice on Nordic chipsets. New features in this version of NimBLE include: -* Fake dual-mode option for controller -* LLCP tracing via HCI events -* Code size optimization for disabled GAP roles -* Support for PA/LNA -* LE Secure Connections Only mode -* Support for Bluetooth Core Specification 5.3 -* Connection subrating -* BabbleSim support -* Various bugfixes and improvements +* Initial support for ISO broacaster +* Support for Bluetooth Core Specification 5.4 +* FEM antenna control +* nRF PHY driver unification +* IPC HCI transport improvements If working on next-generation RTOS and Bluetooth protocol stack sounds exciting to you, get in touch, by sending a mail to the Apache Mynewt diff --git a/repository.yml b/repository.yml index 256bc6b20f..797edaa761 100644 --- a/repository.yml +++ b/repository.yml @@ -31,6 +31,7 @@ repo.versions: "1.3.0": "nimble_1_3_0_tag" "1.4.0": "nimble_1_4_0_tag" "1.5.0": "nimble_1_5_0_tag" + "1.6.0": "nimble_1_6_0_tag" "1.0-latest": "1.0.0" "1.1-latest": "1.1.0" @@ -38,6 +39,7 @@ repo.versions: "1.3-latest": "1.3.0" "1.4-latest": "1.4.0" "1.5-latest": "1.5.0" + "1.6-latest": "1.6.0" repo.newt_compatibility: 0.0.0: @@ -54,3 +56,5 @@ repo.newt_compatibility: 1.9.0: good 1.5.0: 1.10.0: good + 1.6.0: + 1.11.0: good From 66797d56e5d88a2741d38d39065cf74561e1191c Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 17 Aug 2023 12:10:01 +0200 Subject: [PATCH 0788/1333] ci: Use RAT 0.15 for compliance check RAT 0.16 will have support for SPDX but snapshots links are not permanent so for time being use 0.15. --- .github/workflows/compliance_check.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index b73142abf9..edacc93f6d 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -50,8 +50,9 @@ jobs: run: | mkdir repos git clone --depth=1 https://github.com/apache/mynewt-core repos/apache-mynewt-core - wget https://repository.apache.org/content/repositories/snapshots/org/apache/rat/apache-rat/0.16-SNAPSHOT/apache-rat-0.16-20230807.065048-315.jar - mv apache-rat-0.16-20230807.065048-315.jar apache-rat.jar + wget https://dlcdn.apache.org//creadur/apache-rat-0.15/apache-rat-0.15-bin.tar.gz + tar zxf apache-rat-0.15-bin.tar.gz apache-rat-0.15/apache-rat-0.15.jar + mv apache-rat-0.15/apache-rat-0.15.jar apache-rat.jar - name: check licensing run: | ./repos/apache-mynewt-core/.github/check_license.py From dd4e011ed6242d1e7fde78b3f582dfd42056177d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Wed, 12 Feb 2020 21:37:02 +0100 Subject: [PATCH 0789/1333] nimble/host: Make gap init before att This is needed as eatt is registering listener in gap nowadays --- nimble/host/src/ble_hs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index e130c1ca14..bab8fe1116 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -734,6 +734,11 @@ ble_hs_init(void) rc = ble_l2cap_init(); SYSINIT_PANIC_ASSERT(rc == 0); +#endif + rc = ble_gap_init(); + SYSINIT_PANIC_ASSERT(rc == 0); +#if NIMBLE_BLE_CONNECT + rc = ble_att_init(); SYSINIT_PANIC_ASSERT(rc == 0); @@ -746,8 +751,6 @@ ble_hs_init(void) rc = ble_gatts_init(); SYSINIT_PANIC_ASSERT(rc == 0); #endif - rc = ble_gap_init(); - SYSINIT_PANIC_ASSERT(rc == 0); ble_hs_stop_init(); From 86c77a41dfc507adf9cd9857ab23d38a38fea854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Sun, 8 Mar 2020 00:34:51 +0100 Subject: [PATCH 0790/1333] nimble/gatt: Prepare GATT for EATT This patch adds CID to the data path for all the GATT operations. It also updates unit tests after the change. --- nimble/host/src/ble_att.c | 85 ++++++- nimble/host/src/ble_att_clt.c | 136 ++++++----- nimble/host/src/ble_att_cmd.c | 46 +++- nimble/host/src/ble_att_cmd_priv.h | 10 +- nimble/host/src/ble_att_priv.h | 95 ++++---- nimble/host/src/ble_att_svr.c | 106 ++++---- nimble/host/src/ble_gatt_priv.h | 38 +-- nimble/host/src/ble_gattc.c | 252 ++++++++++++-------- nimble/host/src/ble_hs_conn.c | 1 + nimble/host/src/ble_hs_conn_priv.h | 3 + nimble/host/test/src/ble_att_clt_test.c | 32 +-- nimble/host/test/src/ble_att_svr_test.c | 27 ++- nimble/host/test/src/ble_gatt_disc_c_test.c | 32 +-- nimble/host/test/src/ble_gatt_disc_d_test.c | 24 +- nimble/host/test/src/ble_gatt_disc_s_test.c | 52 ++-- nimble/host/test/src/ble_gatt_find_s_test.c | 37 +-- nimble/host/test/src/ble_gatt_read_test.c | 44 ++-- nimble/host/test/src/ble_gatt_write_test.c | 73 +++--- nimble/host/test/src/ble_hs_test_util.c | 9 +- nimble/host/test/src/ble_hs_test_util.h | 6 +- 20 files changed, 650 insertions(+), 458 deletions(-) diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index 436a55077d..9d58bad1ca 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -35,7 +35,7 @@ static uint16_t ble_att_preferred_mtu_val; /** Dispatch table for incoming ATT requests. Sorted by op code. */ -typedef int ble_att_rx_fn(uint16_t conn_handle, struct os_mbuf **om); +typedef int ble_att_rx_fn(uint16_t conn_handle, uint16_t cid, struct os_mbuf **om); struct ble_att_rx_dispatch_entry { uint8_t bde_op; ble_att_rx_fn *bde_fn; @@ -154,13 +154,20 @@ ble_att_rx_dispatch_entry_find(uint8_t op) } int -ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn, +ble_att_conn_chan_find(uint16_t conn_handle, uint16_t cid, struct ble_hs_conn **out_conn, struct ble_l2cap_chan **out_chan) { - return ble_hs_misc_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT, + return ble_hs_misc_conn_chan_find(conn_handle, cid, out_conn, out_chan); } +int +ble_att_conn_chan_find_by_psm(uint16_t conn_handle, uint16_t psm, struct ble_hs_conn **out_conn, + struct ble_l2cap_chan **out_chan) +{ + return ble_hs_misc_conn_chan_find(conn_handle, psm, out_conn, out_chan); +} + void ble_att_inc_tx_stat(uint8_t att_op) { @@ -410,7 +417,7 @@ ble_att_truncate_to_mtu(const struct ble_l2cap_chan *att_chan, } uint16_t -ble_att_mtu(uint16_t conn_handle) +ble_att_mtu_by_cid(uint16_t conn_handle, uint16_t cid) { struct ble_l2cap_chan *chan; struct ble_hs_conn *conn; @@ -419,7 +426,7 @@ ble_att_mtu(uint16_t conn_handle) ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); + rc = ble_att_conn_chan_find(conn_handle, cid, &conn, &chan); if (rc == 0) { mtu = ble_att_chan_mtu(chan); } else { @@ -431,6 +438,12 @@ ble_att_mtu(uint16_t conn_handle) return mtu; } +uint16_t +ble_att_mtu(uint16_t conn_handle) +{ + return ble_att_mtu_by_cid(conn_handle, BLE_L2CAP_CID_ATT); +} + void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu) { @@ -446,6 +459,13 @@ ble_att_chan_mtu(const struct ble_l2cap_chan *chan) { uint16_t mtu; +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 + if (chan->scid != BLE_L2CAP_CID_ATT) { + /* EATT case */ + return chan->coc_tx.mtu; + } +#endif + /* If either side has not exchanged MTU size, use the default. Otherwise, * use the lesser of the two exchanged values. */ @@ -464,7 +484,7 @@ ble_att_chan_mtu(const struct ble_l2cap_chan *chan) static void ble_att_rx_handle_unknown_request(uint8_t op, uint16_t conn_handle, - struct os_mbuf **om) + uint16_t cid, struct os_mbuf **om) { /* If this is command (bit6 is set to 1), do nothing */ if (op & 0x40) { @@ -472,12 +492,13 @@ ble_att_rx_handle_unknown_request(uint8_t op, uint16_t conn_handle, } os_mbuf_adj(*om, OS_MBUF_PKTLEN(*om)); - ble_att_svr_tx_error_rsp(conn_handle, *om, op, 0, + ble_att_svr_tx_error_rsp(conn_handle, cid, *om, op, 0, BLE_ATT_ERR_REQ_NOT_SUPPORTED); *om = NULL; } + static int ble_att_rx(struct ble_l2cap_chan *chan) { @@ -502,7 +523,7 @@ ble_att_rx(struct ble_l2cap_chan *chan) entry = ble_att_rx_dispatch_entry_find(op); if (entry == NULL) { - ble_att_rx_handle_unknown_request(op, conn_handle, om); + ble_att_rx_handle_unknown_request(op, conn_handle, chan->scid, om); return BLE_HS_ENOTSUP; } @@ -511,10 +532,10 @@ ble_att_rx(struct ble_l2cap_chan *chan) /* Strip L2CAP ATT header from the front of the mbuf. */ os_mbuf_adj(*om, 1); - rc = entry->bde_fn(conn_handle, om); + rc = entry->bde_fn(conn_handle, chan->scid, om); if (rc != 0) { if (rc == BLE_HS_ENOTSUP) { - ble_att_rx_handle_unknown_request(op, conn_handle, om); + ble_att_rx_handle_unknown_request(op, conn_handle, chan->scid, om); } return rc; } @@ -582,6 +603,50 @@ ble_att_create_chan(uint16_t conn_handle) return chan; } +bool +ble_att_is_request_op(uint8_t opcode) +{ + switch (opcode) { + case BLE_ATT_OP_MTU_REQ: + case BLE_ATT_OP_FIND_INFO_REQ: + case BLE_ATT_OP_FIND_TYPE_VALUE_REQ: + case BLE_ATT_OP_READ_TYPE_REQ: + case BLE_ATT_OP_READ_REQ: + case BLE_ATT_OP_READ_BLOB_REQ: + case BLE_ATT_OP_READ_MULT_REQ: + case BLE_ATT_OP_READ_GROUP_TYPE_REQ: + case BLE_ATT_OP_WRITE_REQ: + case BLE_ATT_OP_PREP_WRITE_REQ: + case BLE_ATT_OP_EXEC_WRITE_REQ: + case BLE_ATT_OP_INDICATE_REQ: + return true; + } + return false; +} + +bool +ble_att_is_response_op(uint8_t opcode) +{ + switch (opcode) { + case BLE_ATT_OP_MTU_RSP: + case BLE_ATT_OP_ERROR_RSP: + case BLE_ATT_OP_FIND_INFO_RSP: + case BLE_ATT_OP_FIND_TYPE_VALUE_RSP: + case BLE_ATT_OP_READ_TYPE_RSP: + case BLE_ATT_OP_INDICATE_RSP: + case BLE_ATT_OP_READ_RSP: + case BLE_ATT_OP_READ_BLOB_RSP: + case BLE_ATT_OP_READ_MULT_RSP: + case BLE_ATT_OP_READ_GROUP_TYPE_RSP: + case BLE_ATT_OP_WRITE_RSP: + case BLE_ATT_OP_PREP_WRITE_RSP: + case BLE_ATT_OP_EXEC_WRITE_RSP: + return true; + } + + return false; +} + int ble_att_init(void) { diff --git a/nimble/host/src/ble_att_clt.c b/nimble/host/src/ble_att_clt.c index b500f416c1..27478a9a6a 100644 --- a/nimble/host/src/ble_att_clt.c +++ b/nimble/host/src/ble_att_clt.c @@ -32,7 +32,7 @@ *****************************************************************************/ int -ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_error(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { struct ble_att_error_rsp *rsp; int rc; @@ -44,7 +44,7 @@ ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **rxom) rsp = (struct ble_att_error_rsp *)(*rxom)->om_data; - ble_gattc_rx_err(conn_handle, le16toh(rsp->baep_handle), + ble_gattc_rx_err(conn_handle, cid, le16toh(rsp->baep_handle), le16toh(rsp->baep_error_code)); return 0; @@ -69,7 +69,7 @@ ble_att_clt_tx_mtu(uint16_t conn_handle, uint16_t mtu) ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); + rc = ble_att_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT, &conn, &chan); if (rc != 0) { rc = BLE_HS_ENOTCONN; } else if (chan->flags & BLE_L2CAP_CHAN_F_TXED_MTU) { @@ -90,14 +90,14 @@ ble_att_clt_tx_mtu(uint16_t conn_handle, uint16_t mtu) req->bamc_mtu = htole16(mtu); - rc = ble_att_tx(conn_handle, txom); + rc = ble_att_tx(conn_handle, BLE_L2CAP_CID_ATT, txom); if (rc != 0) { return rc; } ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); + rc = ble_att_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT, &conn, &chan); if (rc == 0) { chan->flags |= BLE_L2CAP_CHAN_F_TXED_MTU; } @@ -108,7 +108,7 @@ ble_att_clt_tx_mtu(uint16_t conn_handle, uint16_t mtu) } int -ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_mtu(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { struct ble_att_mtu_cmd *cmd; struct ble_l2cap_chan *chan; @@ -117,13 +117,20 @@ ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) mtu = 0; +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 + if (cid != BLE_L2CAP_CID_ATT) { + /*FIXME reject ?*/ + assert(0); + } +#endif + rc = ble_hs_mbuf_pullup_base(rxom, sizeof(*cmd)); if (rc == 0) { cmd = (struct ble_att_mtu_cmd *)(*rxom)->om_data; ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, NULL, &chan); + rc = ble_att_conn_chan_find(conn_handle, cid, NULL, &chan); if (rc == 0) { ble_att_set_peer_mtu(chan, le16toh(cmd->bamc_mtu)); mtu = ble_att_chan_mtu(chan); @@ -136,7 +143,7 @@ ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) } } - ble_gattc_rx_mtu(conn_handle, rc, mtu); + ble_gattc_rx_mtu(conn_handle, BLE_L2CAP_CID_ATT, rc, mtu); return rc; } @@ -145,7 +152,7 @@ ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) *****************************************************************************/ int -ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t start_handle, +ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle) { #if !NIMBLE_BLE_ATT_CLT_FIND_INFO @@ -167,7 +174,7 @@ ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t start_handle, req->bafq_start_handle = htole16(start_handle); req->bafq_end_handle = htole16(end_handle); - return ble_att_tx(conn_handle, txom); + return ble_att_tx(conn_handle, cid, txom); } static int @@ -222,7 +229,7 @@ ble_att_clt_parse_find_info_entry(struct os_mbuf **rxom, uint8_t rsp_format, } int -ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **om) +ble_att_clt_rx_find_info(uint16_t conn_handle, uint16_t cid, struct os_mbuf **om) { #if !NIMBLE_BLE_ATT_CLT_FIND_INFO return BLE_HS_ENOTSUP; @@ -249,14 +256,14 @@ ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **om) } /* Hand find-info entry to GATT. */ - ble_gattc_rx_find_info_idata(conn_handle, &idata); + ble_gattc_rx_find_info_idata(conn_handle, cid, &idata); } rc = 0; done: /* Notify GATT that response processing is done. */ - ble_gattc_rx_find_info_complete(conn_handle, rc); + ble_gattc_rx_find_info_complete(conn_handle, cid, rc); return rc; } @@ -269,8 +276,9 @@ ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **om) * anyway */ int -ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t start_handle, - uint16_t end_handle, uint16_t attribute_type, +ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t cid, + uint16_t start_handle, uint16_t end_handle, + uint16_t attribute_type, const void *attribute_value, int value_len) { #if !NIMBLE_BLE_ATT_CLT_FIND_TYPE @@ -295,7 +303,7 @@ ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t start_handle, req->bavq_attr_type = htole16(attribute_type); memcpy(req->bavq_value, attribute_value, value_len); - return ble_att_tx(conn_handle, txom); + return ble_att_tx(conn_handle, cid, txom); } static int @@ -321,7 +329,7 @@ ble_att_clt_parse_find_type_value_hinfo( } int -ble_att_clt_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_find_type_value(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_FIND_TYPE return BLE_HS_ENOTSUP; @@ -338,11 +346,11 @@ ble_att_clt_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom) break; } - ble_gattc_rx_find_type_value_hinfo(conn_handle, &hinfo); + ble_gattc_rx_find_type_value_hinfo(conn_handle, cid, &hinfo); } /* Notify GATT client that the full response has been parsed. */ - ble_gattc_rx_find_type_value_complete(conn_handle, rc); + ble_gattc_rx_find_type_value_complete(conn_handle, cid, rc); return 0; } @@ -352,7 +360,7 @@ ble_att_clt_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom) *****************************************************************************/ int -ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t start_handle, +ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, const ble_uuid_t *uuid) { #if !NIMBLE_BLE_ATT_CLT_READ_TYPE @@ -377,11 +385,11 @@ ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t start_handle, ble_uuid_flat(uuid, req->uuid); - return ble_att_tx(conn_handle, txom); + return ble_att_tx(conn_handle, cid, txom); } int -ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_read_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_READ_TYPE return BLE_HS_ENOTSUP; @@ -423,13 +431,13 @@ ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom) adata.value_len = data_len - sizeof(*data); adata.value = data->value; - ble_gattc_rx_read_type_adata(conn_handle, &adata); + ble_gattc_rx_read_type_adata(conn_handle, cid, &adata); os_mbuf_adj(*rxom, data_len); } done: /* Notify GATT that the response is done being parsed. */ - ble_gattc_rx_read_type_complete(conn_handle, rc); + ble_gattc_rx_read_type_complete(conn_handle, cid, rc); return rc; } @@ -439,7 +447,7 @@ ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom) *****************************************************************************/ int -ble_att_clt_tx_read(uint16_t conn_handle, uint16_t handle) +ble_att_clt_tx_read(uint16_t conn_handle, uint16_t cid, uint16_t handle) { #if !NIMBLE_BLE_ATT_CLT_READ return BLE_HS_ENOTSUP; @@ -460,7 +468,7 @@ ble_att_clt_tx_read(uint16_t conn_handle, uint16_t handle) req->barq_handle = htole16(handle); - rc = ble_att_tx(conn_handle, txom); + rc = ble_att_tx(conn_handle, cid, txom); if (rc != 0) { return rc; } @@ -469,14 +477,14 @@ ble_att_clt_tx_read(uint16_t conn_handle, uint16_t handle) } int -ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_read(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_READ return BLE_HS_ENOTSUP; #endif /* Pass the Attribute Value field to GATT. */ - ble_gattc_rx_read_rsp(conn_handle, 0, rxom); + ble_gattc_rx_read_rsp(conn_handle, cid, 0, rxom); return 0; } @@ -485,7 +493,7 @@ ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom) *****************************************************************************/ int -ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t handle, uint16_t offset) +ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t cid, uint16_t handle, uint16_t offset) { #if !NIMBLE_BLE_ATT_CLT_READ_BLOB return BLE_HS_ENOTSUP; @@ -507,7 +515,7 @@ ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t handle, uint16_t offset) req->babq_handle = htole16(handle); req->babq_offset = htole16(offset); - rc = ble_att_tx(conn_handle, txom); + rc = ble_att_tx(conn_handle, cid, txom); if (rc != 0) { return rc; } @@ -516,14 +524,14 @@ ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t handle, uint16_t offset) } int -ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_read_blob(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_READ_BLOB return BLE_HS_ENOTSUP; #endif /* Pass the Attribute Value field to GATT. */ - ble_gattc_rx_read_blob_rsp(conn_handle, 0, rxom); + ble_gattc_rx_read_blob_rsp(conn_handle, cid, 0, rxom); return 0; } @@ -531,7 +539,7 @@ ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom) * $read multiple * *****************************************************************************/ int -ble_att_clt_tx_read_mult(uint16_t conn_handle, const uint16_t *handles, +ble_att_clt_tx_read_mult(uint16_t conn_handle, uint16_t cid, const uint16_t *handles, int num_handles) { #if !NIMBLE_BLE_ATT_CLT_READ_MULT @@ -557,18 +565,18 @@ ble_att_clt_tx_read_mult(uint16_t conn_handle, const uint16_t *handles, req->handles[i] = htole16(handles[i]); } - return ble_att_tx(conn_handle, txom); + return ble_att_tx(conn_handle, cid, txom); } int -ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_read_mult(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_READ_MULT return BLE_HS_ENOTSUP; #endif /* Pass the Attribute Value field to GATT. */ - ble_gattc_rx_read_mult_rsp(conn_handle, 0, rxom); + ble_gattc_rx_read_mult_rsp(conn_handle, cid, 0, rxom); return 0; } @@ -577,7 +585,7 @@ ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom) *****************************************************************************/ int -ble_att_clt_tx_read_group_type(uint16_t conn_handle, +ble_att_clt_tx_read_group_type(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, const ble_uuid_t *uuid) { @@ -602,7 +610,7 @@ ble_att_clt_tx_read_group_type(uint16_t conn_handle, req->bagq_end_handle = htole16(end_handle); ble_uuid_flat(uuid, req->uuid); - return ble_att_tx(conn_handle, txom); + return ble_att_tx(conn_handle, cid, txom); } static int @@ -630,7 +638,7 @@ ble_att_clt_parse_read_group_type_adata( } int -ble_att_clt_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_read_group_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_READ_GROUP_TYPE return BLE_HS_ENOTSUP; @@ -660,13 +668,13 @@ ble_att_clt_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom) goto done; } - ble_gattc_rx_read_group_type_adata(conn_handle, &adata); + ble_gattc_rx_read_group_type_adata(conn_handle, cid, &adata); os_mbuf_adj(*rxom, len); } done: /* Notify GATT that the response is done being parsed. */ - ble_gattc_rx_read_group_type_complete(conn_handle, rc); + ble_gattc_rx_read_group_type_complete(conn_handle, cid, rc); return rc; } @@ -675,7 +683,7 @@ ble_att_clt_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom) *****************************************************************************/ int -ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t handle, +ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t cid, uint16_t handle, struct os_mbuf *txom) { #if !NIMBLE_BLE_ATT_CLT_WRITE @@ -694,12 +702,12 @@ ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t handle, req->bawq_handle = htole16(handle); os_mbuf_concat(txom2, txom); - return ble_att_tx(conn_handle, txom2); + return ble_att_tx(conn_handle, cid, txom2); } int -ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t handle, - struct os_mbuf *txom) +ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t cid, + uint16_t handle, struct os_mbuf *txom) { #if !NIMBLE_BLE_ATT_CLT_WRITE_NO_RSP return BLE_HS_ENOTSUP; @@ -733,18 +741,18 @@ ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t handle, cmd->handle = htole16(handle); os_mbuf_concat(txom2, txom); - return ble_att_tx(conn_handle, txom2); + return ble_att_tx(conn_handle, cid, txom2); } int -ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_WRITE return BLE_HS_ENOTSUP; #endif /* No payload. */ - ble_gattc_rx_write_rsp(conn_handle); + ble_gattc_rx_write_rsp(conn_handle, cid); return 0; } @@ -753,7 +761,7 @@ ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom) *****************************************************************************/ int -ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle, +ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t cid, uint16_t handle, uint16_t offset, struct os_mbuf *txom) { #if !NIMBLE_BLE_ATT_CLT_PREP_WRITE @@ -775,7 +783,7 @@ ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle, } if (OS_MBUF_PKTLEN(txom) > - ble_att_mtu(conn_handle) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ) { + ble_att_mtu_by_cid(conn_handle, cid) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ) { rc = BLE_HS_EINVAL; goto err; } @@ -790,7 +798,7 @@ ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle, req->bapc_offset = htole16(offset); os_mbuf_concat(txom2, txom); - return ble_att_tx(conn_handle, txom2); + return ble_att_tx(conn_handle, cid, txom2); err: os_mbuf_free_chain(txom); @@ -798,7 +806,7 @@ ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle, } int -ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_prep_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_PREP_WRITE return BLE_HS_ENOTSUP; @@ -827,7 +835,7 @@ ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom) done: /* Notify GATT client that the full response has been parsed. */ - ble_gattc_rx_prep_write_rsp(conn_handle, rc, handle, offset, rxom); + ble_gattc_rx_prep_write_rsp(conn_handle, cid, rc, handle, offset, rxom); return rc; } @@ -836,7 +844,7 @@ ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom) *****************************************************************************/ int -ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags) +ble_att_clt_tx_exec_write(uint16_t conn_handle, uint16_t cid, uint8_t flags) { #if !NIMBLE_BLE_ATT_CLT_EXEC_WRITE return BLE_HS_ENOTSUP; @@ -853,7 +861,7 @@ ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags) req->baeq_flags = flags; - rc = ble_att_tx(conn_handle, txom); + rc = ble_att_tx(conn_handle, cid, txom); if (rc != 0) { return rc; } @@ -862,13 +870,13 @@ ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags) } int -ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_exec_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_EXEC_WRITE return BLE_HS_ENOTSUP; #endif - ble_gattc_rx_exec_write_rsp(conn_handle, 0); + ble_gattc_rx_exec_write_rsp(conn_handle, cid, 0); return 0; } @@ -886,6 +894,7 @@ ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle, struct ble_att_notify_req *req; struct os_mbuf *txom2; + uint16_t cid; int rc; if (handle == 0) { @@ -902,7 +911,8 @@ ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle, req->banq_handle = htole16(handle); os_mbuf_concat(txom2, txom); - return ble_att_tx(conn_handle, txom2); + cid = BLE_L2CAP_CID_ATT; + return ble_att_tx(conn_handle, cid, txom2); err: os_mbuf_free_chain(txom); @@ -914,8 +924,8 @@ ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle, *****************************************************************************/ int -ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle, - struct os_mbuf *txom) +ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t cid, + uint16_t handle, struct os_mbuf *txom) { #if !NIMBLE_BLE_ATT_CLT_INDICATE return BLE_HS_ENOTSUP; @@ -939,7 +949,7 @@ ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle, req->baiq_handle = htole16(handle); os_mbuf_concat(txom2, txom); - return ble_att_tx(conn_handle, txom2); + return ble_att_tx(conn_handle, cid, txom2); err: os_mbuf_free_chain(txom); @@ -947,14 +957,14 @@ ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle, } int -ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_clt_rx_indicate(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !NIMBLE_BLE_ATT_CLT_INDICATE return BLE_HS_ENOTSUP; #endif /* No payload. */ - ble_gatts_rx_indicate_rsp(conn_handle); + ble_gatts_rx_indicate_rsp(conn_handle, cid); return 0; } diff --git a/nimble/host/src/ble_att_cmd.c b/nimble/host/src/ble_att_cmd.c index 6669392f1e..ac882a9c65 100644 --- a/nimble/host/src/ble_att_cmd.c +++ b/nimble/host/src/ble_att_cmd.c @@ -55,28 +55,58 @@ ble_att_cmd_get(uint8_t opcode, size_t len, struct os_mbuf **txom) } int -ble_att_tx(uint16_t conn_handle, struct os_mbuf *txom) +ble_att_tx_with_conn(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, struct os_mbuf *txom) { - struct ble_l2cap_chan *chan; - struct ble_hs_conn *conn; int rc; + struct os_mbuf_pkthdr *omp; + + if (!txom) { + if (conn->client_att_busy) { + return 0; + } + omp = STAILQ_FIRST(&conn->att_tx_q); + if (omp == NULL) { + return 0; + } + STAILQ_REMOVE_HEAD(&conn->att_tx_q, omp_next); + txom = OS_MBUF_PKTHDR_TO_MBUF(omp); + } BLE_HS_DBG_ASSERT_EVAL(txom->om_len >= 1); + + if (ble_att_is_request_op(txom->om_data[0])) { + if (conn->client_att_busy) { + STAILQ_INSERT_TAIL(&conn->att_tx_q, OS_MBUF_PKTHDR(txom), omp_next); + return 0; + } + conn->client_att_busy = true; + } + ble_att_inc_tx_stat(txom->om_data[0]); - ble_hs_lock(); + ble_att_truncate_to_mtu(chan, txom); + rc = ble_l2cap_tx(conn, chan, txom); + assert(rc == 0); + return rc; +} +int +ble_att_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom) +{ + struct ble_l2cap_chan *chan; + struct ble_hs_conn *conn; + int rc; + + ble_hs_lock(); rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT, &conn, &chan); if (rc != 0) { os_mbuf_free_chain(txom); - } else { - ble_att_truncate_to_mtu(chan, txom); - rc = ble_l2cap_tx(conn, chan, txom); + return rc; } + rc = ble_att_tx_with_conn(conn, chan, txom); ble_hs_unlock(); - return rc; } diff --git a/nimble/host/src/ble_att_cmd_priv.h b/nimble/host/src/ble_att_cmd_priv.h index 70f33260a7..7202e0b76d 100644 --- a/nimble/host/src/ble_att_cmd_priv.h +++ b/nimble/host/src/ble_att_cmd_priv.h @@ -440,8 +440,14 @@ void ble_att_indicate_rsp_write(void *payload, int len); void *ble_att_cmd_prepare(uint8_t opcode, size_t len, struct os_mbuf *txom); void *ble_att_cmd_get(uint8_t opcode, size_t len, struct os_mbuf **txom); -int ble_att_tx(uint16_t conn_handle, struct os_mbuf *txom); - +int ble_att_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom); + +struct ble_l2cap_chan; +struct ble_hs_conn; +int ble_att_tx_with_conn(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, + struct os_mbuf *txom); +bool ble_att_is_response_op(uint8_t opcode); +bool ble_att_is_request_op(uint8_t opcode); #ifdef __cplusplus } #endif diff --git a/nimble/host/src/ble_att_priv.h b/nimble/host/src/ble_att_priv.h index a2a9f9797b..f596cf9175 100644 --- a/nimble/host/src/ble_att_priv.h +++ b/nimble/host/src/ble_att_priv.h @@ -161,13 +161,15 @@ SLIST_HEAD(ble_att_clt_entry_list, ble_att_clt_entry); /*** @gen */ struct ble_l2cap_chan *ble_att_create_chan(uint16_t conn_handle); -int ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn, +int ble_att_conn_chan_find(uint16_t conn_handle, uint16_t cid, + struct ble_hs_conn **out_conn, struct ble_l2cap_chan **out_chan); void ble_att_inc_tx_stat(uint8_t att_op); void ble_att_truncate_to_mtu(const struct ble_l2cap_chan *att_chan, struct os_mbuf *txom); void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu); uint16_t ble_att_chan_mtu(const struct ble_l2cap_chan *chan); +uint16_t ble_att_mtu_by_cid(uint16_t conn_handle, uint16_t cid); int ble_att_init(void); /*** @svr */ @@ -179,33 +181,33 @@ ble_att_svr_find_by_uuid(struct ble_att_svr_entry *start_at, const ble_uuid_t *uuid, uint16_t end_handle); uint16_t ble_att_svr_prev_handle(void); -int ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_svr_rx_mtu(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); struct ble_att_svr_entry *ble_att_svr_find_by_handle(uint16_t handle_id); int32_t ble_att_svr_ticks_until_tmo(const struct ble_att_svr_conn *svr, ble_npl_time_t now); -int ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_svr_rx_find_type_value(uint16_t conn_handle, +int ble_att_svr_rx_find_info(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_svr_rx_find_type_value(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_read_type(uint16_t conn_handle, +int ble_att_svr_rx_read_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_read_group_type(uint16_t conn_handle, +int ble_att_svr_rx_read_group_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_read(uint16_t conn_handle, +int ble_att_svr_rx_read(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_read_blob(uint16_t conn_handle, +int ble_att_svr_rx_read_blob(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_read_mult(uint16_t conn_handle, +int ble_att_svr_rx_read_mult(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_write(uint16_t conn_handle, +int ble_att_svr_rx_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_svr_rx_prep_write(uint16_t conn_handle, +int ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_svr_rx_prep_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_exec_write(uint16_t conn_handle, +int ble_att_svr_rx_exec_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_notify(uint16_t conn_handle, +int ble_att_svr_rx_notify(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_svr_rx_indicate(uint16_t conn_handle, +int ble_att_svr_rx_indicate(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); void ble_att_svr_prep_clear(struct ble_att_prep_entry_list *prep_list); int ble_att_svr_read_handle(uint16_t conn_handle, uint16_t attr_handle, @@ -217,7 +219,7 @@ int ble_att_svr_init(void); void ble_att_svr_hide_range(uint16_t start_handle, uint16_t end_handle); void ble_att_svr_restore_range(uint16_t start_handle, uint16_t end_handle); -int ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom, +int ble_att_svr_tx_error_rsp(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom, uint8_t req_op, uint16_t handle, uint8_t error_code); /*** $clt */ @@ -250,48 +252,51 @@ struct ble_att_read_group_type_adata { uint8_t *value; }; -int ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_rx_error(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); int ble_att_clt_tx_mtu(uint16_t conn_handle, uint16_t mtu); -int ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_tx_read(uint16_t conn_handle, uint16_t handle); -int ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t handle, +int ble_att_clt_rx_mtu(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_tx_read(uint16_t conn_handle, uint16_t cid, uint16_t handle); +int ble_att_clt_rx_read(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t cid, uint16_t handle, uint16_t offset); -int ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_tx_read_mult(uint16_t conn_handle, +int ble_att_clt_rx_read_blob(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_tx_read_mult(uint16_t conn_handle, uint16_t cid, const uint16_t *handles, int num_handles); -int ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t start_handle, +int ble_att_clt_rx_read_mult(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, const ble_uuid_t *uuid); -int ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_tx_read_group_type(uint16_t conn_handle, +int ble_att_clt_rx_read_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_tx_read_group_type(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, const ble_uuid_t *uuid128); -int ble_att_clt_rx_read_group_type(uint16_t conn_handle, +int ble_att_clt_rx_read_group_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t start_handle, +int ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle); -int ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t start_handle, +int ble_att_clt_rx_find_info(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, uint16_t attribute_type, const void *attribute_value, int value_len); -int ble_att_clt_rx_find_type_value(uint16_t conn_handle, +int ble_att_clt_rx_find_type_value(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); -int ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t handle, - struct os_mbuf *txom); -int ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t handle, - struct os_mbuf *txom); -int ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle, - uint16_t offset, struct os_mbuf *txom); -int ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags); -int ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom); -int ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t cid, + uint16_t handle, struct os_mbuf *txom); +int ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t cid, + uint16_t handle, struct os_mbuf *txom); +int ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t cid, + uint16_t handle, uint16_t offset, + struct os_mbuf *txom); +int ble_att_clt_rx_prep_write(uint16_t conn_handle, uint16_t cid, + struct os_mbuf **rxom); +int ble_att_clt_tx_exec_write(uint16_t conn_handle, uint16_t cid, + uint8_t flags); +int ble_att_clt_rx_exec_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_rx_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); int ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle, struct os_mbuf *txom); -int ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle, - struct os_mbuf *txom); -int ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t cid, + uint16_t handle, struct os_mbuf *txom); +int ble_att_clt_rx_indicate(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); #ifdef __cplusplus } diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 8612d36963..74f910d744 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -578,7 +578,7 @@ ble_att_svr_write_handle(uint16_t conn_handle, uint16_t attr_handle, } int -ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom, +ble_att_svr_tx_error_rsp(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom, uint8_t req_op, uint16_t handle, uint8_t error_code) { struct ble_att_error_rsp *rsp; @@ -595,7 +595,7 @@ ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom, rsp->baep_handle = htole16(handle); rsp->baep_error_code = error_code; - return ble_att_tx(conn_handle, txom); + return ble_att_tx(conn_handle, cid, txom); } /** @@ -622,7 +622,7 @@ ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom, * field. */ static int -ble_att_svr_tx_rsp(uint16_t conn_handle, int hs_status, struct os_mbuf *om, +ble_att_svr_tx_rsp(uint16_t conn_handle, uint16_t cid, int hs_status, struct os_mbuf *om, uint8_t att_op, uint8_t err_status, uint16_t err_handle) { struct ble_l2cap_chan *chan; @@ -640,7 +640,7 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, int hs_status, struct os_mbuf *om, if (do_tx) { ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); + rc = ble_att_conn_chan_find(conn_handle, cid, &conn, &chan); if (rc != 0) { /* No longer connected. */ hs_status = rc; @@ -670,7 +670,7 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, int hs_status, struct os_mbuf *om, os_mbuf_adj(om, OS_MBUF_PKTLEN(om)); } if (om != NULL) { - ble_att_svr_tx_error_rsp(conn_handle, om, att_op, + ble_att_svr_tx_error_rsp(conn_handle, cid, om, att_op, err_handle, err_status); om = NULL; } @@ -697,7 +697,7 @@ ble_att_svr_build_mtu_rsp(uint16_t conn_handle, struct os_mbuf **rxom, txom = NULL; ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, NULL, &chan); + rc = ble_att_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT, NULL, &chan); if (rc == 0) { mtu = chan->my_mtu; } @@ -729,7 +729,7 @@ ble_att_svr_build_mtu_rsp(uint16_t conn_handle, struct os_mbuf **rxom, } int -ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_mtu(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { struct ble_att_mtu_cmd *cmd; struct ble_l2cap_chan *chan; @@ -742,6 +742,11 @@ ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) txom = NULL; mtu = 0; + if (cid != BLE_L2CAP_CID_ATT) { + /*TODO */ + return BLE_ATT_ERR_INVALID_PDU; + } + rc = ble_att_svr_pullup_req_base(rxom, sizeof(*cmd), &att_err); if (rc != 0) { goto done; @@ -759,12 +764,12 @@ ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_MTU_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, BLE_L2CAP_CID_ATT, rc, txom, BLE_ATT_OP_MTU_REQ, att_err, 0); if (rc == 0) { ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); + rc = ble_att_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT, &conn, &chan); if (rc == 0) { ble_att_set_peer_mtu(chan, mtu); chan->flags |= BLE_L2CAP_CHAN_F_TXED_MTU; @@ -863,7 +868,7 @@ ble_att_svr_fill_info(uint16_t start_handle, uint16_t end_handle, } static int -ble_att_svr_build_find_info_rsp(uint16_t conn_handle, +ble_att_svr_build_find_info_rsp(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, struct os_mbuf **rxom, struct os_mbuf **out_txom, @@ -892,7 +897,7 @@ ble_att_svr_build_find_info_rsp(uint16_t conn_handle, /* Write the variable length Information Data field, populating the format * field as appropriate. */ - mtu = ble_att_mtu(conn_handle); + mtu = ble_att_mtu_by_cid(conn_handle, cid); rc = ble_att_svr_fill_info(start_handle, end_handle, txom, mtu, &rsp->bafp_format); if (rc != 0) { @@ -909,7 +914,7 @@ ble_att_svr_build_find_info_rsp(uint16_t conn_handle, } int -ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_find_info(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_FIND_INFO) return BLE_HS_ENOTSUP; @@ -946,7 +951,7 @@ ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom) goto done; } - rc = ble_att_svr_build_find_info_rsp(conn_handle, + rc = ble_att_svr_build_find_info_rsp(conn_handle, cid, start_handle, end_handle, rxom, &txom, &att_err); if (rc != 0) { @@ -957,7 +962,7 @@ ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_FIND_INFO_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_FIND_INFO_REQ, att_err, err_handle); return rc; } @@ -1172,7 +1177,7 @@ ble_att_svr_fill_type_value(uint16_t conn_handle, } static int -ble_att_svr_build_find_type_value_rsp(uint16_t conn_handle, +ble_att_svr_build_find_type_value_rsp(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, ble_uuid16_t attr_type, @@ -1199,7 +1204,7 @@ ble_att_svr_build_find_type_value_rsp(uint16_t conn_handle, } /* Write the variable length Information Data field. */ - mtu = ble_att_mtu(conn_handle); + mtu = ble_att_mtu_by_cid(conn_handle, cid); rc = ble_att_svr_fill_type_value(conn_handle, start_handle, end_handle, attr_type, *rxom, txom, mtu, @@ -1216,7 +1221,7 @@ ble_att_svr_build_find_type_value_rsp(uint16_t conn_handle, } int -ble_att_svr_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_find_type_value(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_FIND_TYPE) return BLE_HS_ENOTSUP; @@ -1254,7 +1259,7 @@ ble_att_svr_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom) rc = BLE_HS_EBADDATA; goto done; } - rc = ble_att_svr_build_find_type_value_rsp(conn_handle, start_handle, + rc = ble_att_svr_build_find_type_value_rsp(conn_handle, cid, start_handle, end_handle, attr_type, rxom, &txom, &att_err); if (rc != 0) { @@ -1265,14 +1270,14 @@ ble_att_svr_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_FIND_TYPE_VALUE_REQ, att_err, err_handle); return rc; } static int -ble_att_svr_build_read_type_rsp(uint16_t conn_handle, +ble_att_svr_build_read_type_rsp(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, const ble_uuid_t *uuid, struct os_mbuf **rxom, @@ -1315,7 +1320,7 @@ ble_att_svr_build_read_type_rsp(uint16_t conn_handle, goto done; } - mtu = ble_att_mtu(conn_handle); + mtu = ble_att_mtu_by_cid(conn_handle, cid); /* Find all matching attributes, writing a record for each. */ entry = NULL; @@ -1387,7 +1392,7 @@ ble_att_svr_build_read_type_rsp(uint16_t conn_handle, } int -ble_att_svr_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_read_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_READ_TYPE) return BLE_HS_ENOTSUP; @@ -1439,7 +1444,7 @@ ble_att_svr_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom) goto done; } - rc = ble_att_svr_build_read_type_rsp(conn_handle, start_handle, end_handle, + rc = ble_att_svr_build_read_type_rsp(conn_handle, cid, start_handle, end_handle, &uuid.u, rxom, &txom, &att_err, &err_handle); if (rc != 0) { @@ -1449,13 +1454,13 @@ ble_att_svr_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_READ_TYPE_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_READ_TYPE_REQ, att_err, err_handle); return rc; } int -ble_att_svr_rx_read(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_read(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_READ) return BLE_HS_ENOTSUP; @@ -1498,13 +1503,13 @@ ble_att_svr_rx_read(uint16_t conn_handle, struct os_mbuf **rxom) } done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_READ_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_READ_REQ, att_err, err_handle); return rc; } int -ble_att_svr_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_read_blob(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_READ_BLOB) return BLE_HS_ENOTSUP; @@ -1551,13 +1556,13 @@ ble_att_svr_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_READ_BLOB_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_READ_BLOB_REQ, att_err, err_handle); return rc; } static int -ble_att_svr_build_read_mult_rsp(uint16_t conn_handle, +ble_att_svr_build_read_mult_rsp(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom, struct os_mbuf **out_txom, uint8_t *att_err, @@ -1568,7 +1573,7 @@ ble_att_svr_build_read_mult_rsp(uint16_t conn_handle, uint16_t mtu; int rc; - mtu = ble_att_mtu(conn_handle); + mtu = ble_att_mtu_by_cid(conn_handle, cid); rc = ble_att_svr_pkt(rxom, &txom, att_err); if (rc != 0) { @@ -1618,7 +1623,7 @@ ble_att_svr_build_read_mult_rsp(uint16_t conn_handle, } int -ble_att_svr_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_read_mult(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_READ_MULT) return BLE_HS_ENOTSUP; @@ -1634,10 +1639,10 @@ ble_att_svr_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom) err_handle = 0; att_err = 0; - rc = ble_att_svr_build_read_mult_rsp(conn_handle, rxom, &txom, &att_err, + rc = ble_att_svr_build_read_mult_rsp(conn_handle, cid, rxom, &txom, &att_err, &err_handle); - return ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_READ_MULT_REQ, + return ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_READ_MULT_REQ, att_err, err_handle); } @@ -1705,7 +1710,7 @@ ble_att_svr_read_group_type_entry_write(struct os_mbuf *om, uint16_t mtu, * @return 0 on success; BLE_HS error code on failure. */ static int -ble_att_svr_build_read_group_type_rsp(uint16_t conn_handle, +ble_att_svr_build_read_group_type_rsp(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, const ble_uuid_t *group_uuid, @@ -1732,7 +1737,7 @@ ble_att_svr_build_read_group_type_rsp(uint16_t conn_handle, *att_err = 0; *err_handle = start_handle; - mtu = ble_att_mtu(conn_handle); + mtu = ble_att_mtu_by_cid(conn_handle, cid); /* Just reuse the request buffer for the response. */ txom = *rxom; @@ -1874,7 +1879,7 @@ ble_att_svr_build_read_group_type_rsp(uint16_t conn_handle, } int -ble_att_svr_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_read_group_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_READ_GROUP_TYPE) return BLE_HS_ENOTSUP; @@ -1934,9 +1939,10 @@ ble_att_svr_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom) goto done; } - rc = ble_att_svr_build_read_group_type_rsp(conn_handle, start_handle, - end_handle, &uuid.u, - rxom, &txom, &att_err, + rc = ble_att_svr_build_read_group_type_rsp(conn_handle, cid, + start_handle, end_handle, + &uuid.u, rxom, + &txom, &att_err, &err_handle); if (rc != 0) { goto done; @@ -1945,7 +1951,7 @@ ble_att_svr_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_READ_GROUP_TYPE_REQ, att_err, err_handle); return rc; @@ -1980,7 +1986,7 @@ ble_att_svr_build_write_rsp(struct os_mbuf **rxom, struct os_mbuf **out_txom, } int -ble_att_svr_rx_write(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_WRITE) return BLE_HS_ENOTSUP; @@ -2025,13 +2031,13 @@ ble_att_svr_rx_write(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_WRITE_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_WRITE_REQ, att_err, handle); return rc; } int -ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_WRITE_NO_RSP) return BLE_HS_ENOTSUP; @@ -2317,7 +2323,7 @@ ble_att_svr_insert_prep_entry(uint16_t conn_handle, } int -ble_att_svr_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_prep_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_QUEUED_WRITE) return BLE_HS_ENOTSUP; @@ -2392,13 +2398,13 @@ ble_att_svr_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_PREP_WRITE_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_PREP_WRITE_REQ, att_err, err_handle); return rc; } int -ble_att_svr_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_exec_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_QUEUED_WRITE) return BLE_HS_ENOTSUP; @@ -2467,13 +2473,13 @@ ble_att_svr_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom) ble_att_svr_prep_clear(&prep_list); } - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_EXEC_WRITE_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_EXEC_WRITE_REQ, att_err, err_handle); return rc; } int -ble_att_svr_rx_notify(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_notify(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_NOTIFY) return BLE_HS_ENOTSUP; @@ -2548,7 +2554,7 @@ ble_att_svr_build_indicate_rsp(struct os_mbuf **rxom, } int -ble_att_svr_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom) +ble_att_svr_rx_indicate(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) { #if !MYNEWT_VAL(BLE_ATT_SVR_INDICATE) return BLE_HS_ENOTSUP; @@ -2606,7 +2612,7 @@ ble_att_svr_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom) rc = 0; done: - rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_INDICATE_REQ, + rc = ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, BLE_ATT_OP_INDICATE_REQ, att_err, handle); return rc; } diff --git a/nimble/host/src/ble_gatt_priv.h b/nimble/host/src/ble_gatt_priv.h index 2b1705a10f..595a813d2d 100644 --- a/nimble/host/src/ble_gatt_priv.h +++ b/nimble/host/src/ble_gatt_priv.h @@ -103,32 +103,32 @@ struct ble_gatts_conn { int ble_gattc_locked_by_cur_task(void); void ble_gatts_indicate_fail_notconn(uint16_t conn_handle); -void ble_gattc_rx_err(uint16_t conn_handle, uint16_t handle, uint16_t status); -void ble_gattc_rx_mtu(uint16_t conn_handle, int status, uint16_t chan_mtu); -void ble_gattc_rx_read_type_adata(uint16_t conn_handle, +void ble_gattc_rx_err(uint16_t conn_handle, uint16_t cid, uint16_t handle, uint16_t status); +void ble_gattc_rx_mtu(uint16_t conn_handle, uint16_t cid, int status, uint16_t chan_mtu); +void ble_gattc_rx_read_type_adata(uint16_t conn_handle, uint16_t cid, struct ble_att_read_type_adata *adata); -void ble_gattc_rx_read_type_complete(uint16_t conn_handle, int status); -void ble_gattc_rx_read_rsp(uint16_t conn_handle, int status, +void ble_gattc_rx_read_type_complete(uint16_t conn_handle, uint16_t cid, int status); +void ble_gattc_rx_read_rsp(uint16_t conn_handle, uint16_t cid, int status, struct os_mbuf **rxom); -void ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, int status, +void ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, uint16_t cid, int status, struct os_mbuf **rxom); -void ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, int status, +void ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, uint16_t cid, int status, struct os_mbuf **rxom); -void ble_gattc_rx_read_group_type_adata( - uint16_t conn_handle, struct ble_att_read_group_type_adata *adata); -void ble_gattc_rx_read_group_type_complete(uint16_t conn_handle, int rc); -void ble_gattc_rx_find_type_value_hinfo( - uint16_t conn_handle, struct ble_att_find_type_value_hinfo *hinfo); -void ble_gattc_rx_find_type_value_complete(uint16_t conn_handle, int status); -void ble_gattc_rx_write_rsp(uint16_t conn_handle); -void ble_gattc_rx_prep_write_rsp(uint16_t conn_handle, int status, +void ble_gattc_rx_read_group_type_adata(uint16_t conn_handle, uint16_t cid, + struct ble_att_read_group_type_adata *adata); +void ble_gattc_rx_read_group_type_complete(uint16_t conn_handle, uint16_t cid, int rc); +void ble_gattc_rx_find_type_value_hinfo(uint16_t conn_handle, uint16_t cid, + struct ble_att_find_type_value_hinfo *hinfo); +void ble_gattc_rx_find_type_value_complete(uint16_t conn_handle, uint16_t cid, int status); +void ble_gattc_rx_write_rsp(uint16_t conn_handle, uint16_t cid); +void ble_gattc_rx_prep_write_rsp(uint16_t conn_handle, uint16_t cid, int status, uint16_t handle, uint16_t offset, struct os_mbuf **rxom); -void ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, int status); -void ble_gatts_rx_indicate_rsp(uint16_t conn_handle); -void ble_gattc_rx_find_info_idata(uint16_t conn_handle, +void ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, uint16_t cid, int status); +void ble_gatts_rx_indicate_rsp(uint16_t conn_handle, uint16_t cid); +void ble_gattc_rx_find_info_idata(uint16_t conn_handle, uint16_t cid, struct ble_att_find_info_idata *idata); -void ble_gattc_rx_find_info_complete(uint16_t conn_handle, int status); +void ble_gattc_rx_find_info_complete(uint16_t conn_handle, uint16_t cid, int status); void ble_gattc_connection_txable(uint16_t conn_handle); void ble_gattc_connection_broken(uint16_t conn_handle); int32_t ble_gattc_timer(void); diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index 63d967b490..7346adf389 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -108,6 +108,7 @@ struct ble_gattc_proc { uint32_t exp_os_ticks; uint16_t conn_handle; + uint16_t cid; uint8_t op; uint8_t flags; @@ -694,6 +695,14 @@ ble_gattc_proc_alloc(void) return proc; } +static void +ble_gattc_proc_prepare(struct ble_gattc_proc *proc, uint16_t conn_handle, uint8_t op) +{ + proc->conn_handle = conn_handle; + proc->op = op; + proc->cid = BLE_L2CAP_CID_ATT; +} + /** * Frees the specified proc entry. No-op if passed a null pointer. */ @@ -845,6 +854,7 @@ typedef int ble_gattc_match_fn(struct ble_gattc_proc *proc, void *arg); struct ble_gattc_criteria_conn_op { uint16_t conn_handle; + uint16_t psm; uint8_t op; }; @@ -876,6 +886,28 @@ ble_gattc_proc_matches_conn_op(struct ble_gattc_proc *proc, void *arg) return 1; } +static int +ble_gattc_proc_matches_conn_cid_op(struct ble_gattc_proc *proc, void *arg) +{ + const struct ble_gattc_criteria_conn_op *criteria; + + criteria = arg; + + if (criteria->conn_handle != proc->conn_handle) { + return 0; + } + + if (criteria->psm != proc->cid) { + return 0; + } + + if (criteria->op != proc->op && criteria->op != BLE_GATT_OP_NONE) { + return 0; + } + + return 1; +} + struct ble_gattc_criteria_exp { ble_npl_time_t now; int32_t next_exp_in; @@ -905,6 +937,7 @@ ble_gattc_proc_matches_expired(struct ble_gattc_proc *proc, void *arg) struct ble_gattc_criteria_conn_rx_entry { uint16_t conn_handle; + uint16_t cid; const void *rx_entries; int num_rx_entries; const void *matching_rx_entry; @@ -918,7 +951,8 @@ ble_gattc_proc_matches_conn_rx_entry(struct ble_gattc_proc *proc, void *arg) criteria = arg; if (criteria->conn_handle != BLE_HS_CONN_HANDLE_NONE && - criteria->conn_handle != proc->conn_handle) { + criteria->conn_handle != proc->conn_handle && + criteria->cid != proc->cid) { return 0; } @@ -997,12 +1031,26 @@ ble_gattc_extract_by_conn_op(uint16_t conn_handle, uint8_t op, int max_procs, ble_gattc_extract(ble_gattc_proc_matches_conn_op, &criteria, max_procs, dst_list); } +static void +ble_gattc_extract_by_conn_cid_op(uint16_t conn_handle, uint16_t psm, uint8_t op, + int max_procs, + struct ble_gattc_proc_list *dst_list) +{ + struct ble_gattc_criteria_conn_op criteria; + + criteria.conn_handle = conn_handle; + criteria.op = op; + criteria.psm = psm; + + ble_gattc_extract(ble_gattc_proc_matches_conn_cid_op, &criteria, max_procs, dst_list); +} + static struct ble_gattc_proc * -ble_gattc_extract_first_by_conn_op(uint16_t conn_handle, uint8_t op) +ble_gattc_extract_first_by_conn_cid_op(uint16_t conn_handle, uint16_t cid, uint8_t op) { struct ble_gattc_proc_list dst_list; - ble_gattc_extract_by_conn_op(conn_handle, op, 1, &dst_list); + ble_gattc_extract_by_conn_cid_op(conn_handle, cid, op, 1, &dst_list); return STAILQ_FIRST(&dst_list); } @@ -1037,7 +1085,7 @@ ble_gattc_extract_expired(struct ble_gattc_proc_list *dst_list) } static struct ble_gattc_proc * -ble_gattc_extract_with_rx_entry(uint16_t conn_handle, +ble_gattc_extract_with_rx_entry(uint16_t conn_handle, uint16_t cid, const void *rx_entries, int num_rx_entries, const void **out_rx_entry) { @@ -1045,6 +1093,7 @@ ble_gattc_extract_with_rx_entry(uint16_t conn_handle, struct ble_gattc_proc *proc; criteria.conn_handle = conn_handle; + criteria.cid = cid; criteria.rx_entries = rx_entries; criteria.num_rx_entries = num_rx_entries; criteria.matching_rx_entry = NULL; @@ -1062,6 +1111,7 @@ ble_gattc_extract_with_rx_entry(uint16_t conn_handle, * list and returned. * * @param conn_handle The connection handle to match against. + * @param cid Source CID of L2CAP channel used * @param rx_entries The array of rx entries corresponding to the * op code of the incoming response. * @param out_rx_entry On success, the address of the matching rx @@ -1070,9 +1120,9 @@ ble_gattc_extract_with_rx_entry(uint16_t conn_handle, * @return The matching proc entry on success; * null on failure. */ -#define BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, rx_entries, out_rx_entry) \ +#define BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, cid, rx_entries, out_rx_entry) \ ble_gattc_extract_with_rx_entry( \ - (conn_handle), (rx_entries), \ + (conn_handle), (cid), (rx_entries), \ sizeof (rx_entries) / sizeof (rx_entries)[0], \ (const void **)(out_rx_entry)) @@ -1290,7 +1340,7 @@ ble_gattc_mtu_tx(struct ble_gattc_proc *proc) int rc; ble_hs_lock(); - rc = ble_att_conn_chan_find(proc->conn_handle, &conn, &chan); + rc = ble_att_conn_chan_find(proc->conn_handle, proc->cid, &conn, &chan); if (rc == 0) { mtu = chan->my_mtu; } @@ -1319,6 +1369,7 @@ ble_gattc_exchange_mtu(uint16_t conn_handle, ble_gatt_mtu_fn *cb, void *cb_arg) proc->op = BLE_GATT_OP_MTU; proc->conn_handle = conn_handle; + proc->cid = BLE_L2CAP_CID_ATT; proc->mtu.cb = cb; proc->mtu.cb_arg = cb_arg; @@ -1395,7 +1446,7 @@ ble_gattc_disc_all_svcs_tx(struct ble_gattc_proc *proc) ble_gattc_dbg_assert_proc_not_inserted(proc); - rc = ble_att_clt_tx_read_group_type(proc->conn_handle, + rc = ble_att_clt_tx_read_group_type(proc->conn_handle, proc->cid, proc->disc_all_svcs.prev_handle + 1, 0xffff, &uuid.u); if (rc != 0) { @@ -1541,8 +1592,8 @@ ble_gattc_disc_all_svcs(uint16_t conn_handle, ble_gatt_disc_svc_fn *cb, goto done; } - proc->op = BLE_GATT_OP_DISC_ALL_SVCS; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_DISC_ALL_SVCS); + proc->disc_all_svcs.prev_handle = 0x0000; proc->disc_all_svcs.cb = cb; proc->disc_all_svcs.cb_arg = cb_arg; @@ -1621,7 +1672,7 @@ ble_gattc_disc_svc_uuid_tx(struct ble_gattc_proc *proc) ble_gattc_dbg_assert_proc_not_inserted(proc); ble_uuid_flat(&proc->disc_svc_uuid.service_uuid.u, val); - rc = ble_att_clt_tx_find_type_value(proc->conn_handle, + rc = ble_att_clt_tx_find_type_value(proc->conn_handle, proc->cid, proc->disc_svc_uuid.prev_handle + 1, 0xffff, BLE_ATT_UUID_PRIMARY_SERVICE, val, @@ -1754,8 +1805,8 @@ ble_gattc_disc_svc_by_uuid(uint16_t conn_handle, const ble_uuid_t *uuid, goto done; } - proc->op = BLE_GATT_OP_DISC_SVC_UUID; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_DISC_SVC_UUID); + ble_uuid_to_any(uuid, &proc->disc_svc_uuid.service_uuid); proc->disc_svc_uuid.prev_handle = 0x0000; proc->disc_svc_uuid.cb = cb; @@ -1836,7 +1887,7 @@ ble_gattc_find_inc_svcs_tx(struct ble_gattc_proc *proc) if (proc->find_inc_svcs.cur_start == 0) { /* Find the next included service. */ - rc = ble_att_clt_tx_read_type(proc->conn_handle, + rc = ble_att_clt_tx_read_type(proc->conn_handle, proc->cid, proc->find_inc_svcs.prev_handle + 1, proc->find_inc_svcs.end_handle, &uuid.u); if (rc != 0) { @@ -1844,7 +1895,7 @@ ble_gattc_find_inc_svcs_tx(struct ble_gattc_proc *proc) } } else { /* Read the UUID of the previously found service. */ - rc = ble_att_clt_tx_read(proc->conn_handle, + rc = ble_att_clt_tx_read(proc->conn_handle, proc->cid, proc->find_inc_svcs.cur_start); if (rc != 0) { return rc; @@ -2070,8 +2121,8 @@ ble_gattc_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle, goto done; } - proc->op = BLE_GATT_OP_FIND_INC_SVCS; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_FIND_INC_SVCS); + proc->find_inc_svcs.prev_handle = start_handle - 1; proc->find_inc_svcs.end_handle = end_handle; proc->find_inc_svcs.cb = cb; @@ -2150,7 +2201,7 @@ ble_gattc_disc_all_chrs_tx(struct ble_gattc_proc *proc) ble_gattc_dbg_assert_proc_not_inserted(proc); - rc = ble_att_clt_tx_read_type(proc->conn_handle, + rc = ble_att_clt_tx_read_type(proc->conn_handle, proc->cid, proc->disc_all_chrs.prev_handle + 1, proc->disc_all_chrs.end_handle, &uuid.u); if (rc != 0) { @@ -2298,8 +2349,8 @@ ble_gattc_disc_all_chrs(uint16_t conn_handle, uint16_t start_handle, goto done; } - proc->op = BLE_GATT_OP_DISC_ALL_CHRS; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_DISC_ALL_CHRS); + proc->disc_all_chrs.prev_handle = start_handle - 1; proc->disc_all_chrs.end_handle = end_handle; proc->disc_all_chrs.cb = cb; @@ -2378,7 +2429,7 @@ ble_gattc_disc_chr_uuid_tx(struct ble_gattc_proc *proc) ble_gattc_dbg_assert_proc_not_inserted(proc); - rc = ble_att_clt_tx_read_type(proc->conn_handle, + rc = ble_att_clt_tx_read_type(proc->conn_handle, proc->cid, proc->disc_chr_uuid.prev_handle + 1, proc->disc_chr_uuid.end_handle, &uuid.u); if (rc != 0) { @@ -2537,8 +2588,8 @@ ble_gattc_disc_chrs_by_uuid(uint16_t conn_handle, uint16_t start_handle, goto done; } - proc->op = BLE_GATT_OP_DISC_CHR_UUID; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_DISC_CHR_UUID); + ble_uuid_to_any(uuid, &proc->disc_chr_uuid.chr_uuid); proc->disc_chr_uuid.prev_handle = start_handle - 1; proc->disc_chr_uuid.end_handle = end_handle; @@ -2617,7 +2668,7 @@ ble_gattc_disc_all_dscs_tx(struct ble_gattc_proc *proc) ble_gattc_dbg_assert_proc_not_inserted(proc); - rc = ble_att_clt_tx_find_info(proc->conn_handle, + rc = ble_att_clt_tx_find_info(proc->conn_handle, proc->cid, proc->disc_all_dscs.prev_handle + 1, proc->disc_all_dscs.end_handle); if (rc != 0) { @@ -2747,8 +2798,8 @@ ble_gattc_disc_all_dscs(uint16_t conn_handle, uint16_t start_handle, goto done; } - proc->op = BLE_GATT_OP_DISC_ALL_DSCS; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_DISC_ALL_DSCS); + proc->disc_all_dscs.chr_val_handle = start_handle; proc->disc_all_dscs.prev_handle = start_handle; proc->disc_all_dscs.end_handle = end_handle; @@ -2858,7 +2909,7 @@ ble_gattc_read_tx(struct ble_gattc_proc *proc) { int rc; - rc = ble_att_clt_tx_read(proc->conn_handle, proc->read.handle); + rc = ble_att_clt_tx_read(proc->conn_handle, proc->cid, proc->read.handle); if (rc != 0) { return rc; } @@ -2885,8 +2936,8 @@ ble_gattc_read(uint16_t conn_handle, uint16_t attr_handle, goto done; } - proc->op = BLE_GATT_OP_READ; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_READ); + proc->read.handle = attr_handle; proc->read.cb = cb; proc->read.cb_arg = cb_arg; @@ -3021,7 +3072,7 @@ ble_gattc_read_uuid_rx_complete(struct ble_gattc_proc *proc, int status) static int ble_gattc_read_uuid_tx(struct ble_gattc_proc *proc) { - return ble_att_clt_tx_read_type(proc->conn_handle, + return ble_att_clt_tx_read_type(proc->conn_handle, proc->cid, proc->read_uuid.start_handle, proc->read_uuid.end_handle, &proc->read_uuid.chr_uuid.u); @@ -3047,8 +3098,8 @@ ble_gattc_read_by_uuid(uint16_t conn_handle, uint16_t start_handle, goto done; } - proc->op = BLE_GATT_OP_READ_UUID; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_READ_UUID); + ble_uuid_to_any(uuid, &proc->read_uuid.chr_uuid); proc->read_uuid.start_handle = start_handle; proc->read_uuid.end_handle = end_handle; @@ -3126,12 +3177,12 @@ ble_gattc_read_long_tx(struct ble_gattc_proc *proc) ble_gattc_dbg_assert_proc_not_inserted(proc); if (proc->read_long.offset == 0) { - rc = ble_att_clt_tx_read(proc->conn_handle, proc->read_long.handle); + rc = ble_att_clt_tx_read(proc->conn_handle, proc->cid, proc->read_long.handle); if (rc != 0) { return rc; } } else { - rc = ble_att_clt_tx_read_blob(proc->conn_handle, + rc = ble_att_clt_tx_read_blob(proc->conn_handle, proc->cid, proc->read_long.handle, proc->read_long.offset); if (rc != 0) { @@ -3202,7 +3253,7 @@ ble_gattc_read_long_rx_read_rsp(struct ble_gattc_proc *proc, int status, } /* Determine if this is the end of the attribute value. */ - mtu = ble_att_mtu(proc->conn_handle); + mtu = ble_att_mtu_by_cid(proc->conn_handle, proc->cid); if (mtu == 0) { /* No longer connected. */ return BLE_HS_EDONE; @@ -3243,8 +3294,8 @@ ble_gattc_read_long(uint16_t conn_handle, uint16_t handle, uint16_t offset, goto done; } - proc->op = BLE_GATT_OP_READ_LONG; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_READ_LONG); + proc->read_long.handle = handle; proc->read_long.offset = offset; proc->read_long.cb = cb; @@ -3342,7 +3393,7 @@ ble_gattc_read_mult_tx(struct ble_gattc_proc *proc) { int rc; - rc = ble_att_clt_tx_read_mult(proc->conn_handle, proc->read_mult.handles, + rc = ble_att_clt_tx_read_mult(proc->conn_handle, proc->cid, proc->read_mult.handles, proc->read_mult.num_handles); if (rc != 0) { return rc; @@ -3379,8 +3430,8 @@ ble_gattc_read_mult(uint16_t conn_handle, const uint16_t *handles, goto done; } - proc->op = BLE_GATT_OP_READ_MULT; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_READ_MULT); + memcpy(proc->read_mult.handles, handles, num_handles * sizeof *handles); proc->read_mult.num_handles = num_handles; proc->read_mult.cb = cb; @@ -3419,7 +3470,7 @@ ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle, ble_gattc_log_write(attr_handle, OS_MBUF_PKTLEN(txom), 0); - rc = ble_att_clt_tx_write_cmd(conn_handle, attr_handle, txom); + rc = ble_att_clt_tx_write_cmd(conn_handle, BLE_L2CAP_CID_ATT, attr_handle, txom); if (rc != 0) { STATS_INC(ble_gattc_stats, write); } @@ -3525,15 +3576,15 @@ ble_gattc_write(uint16_t conn_handle, uint16_t attr_handle, goto done; } - proc->op = BLE_GATT_OP_WRITE; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_WRITE); + proc->write.att_handle = attr_handle; proc->write.cb = cb; proc->write.cb_arg = cb_arg; ble_gattc_log_write(attr_handle, OS_MBUF_PKTLEN(txom), 1); - rc = ble_att_clt_tx_write_req(conn_handle, attr_handle, txom); + rc = ble_att_clt_tx_write_req(conn_handle, proc->cid, attr_handle, txom); txom = NULL; if (rc != 0) { goto done; @@ -3633,7 +3684,7 @@ ble_gattc_write_long_tx(struct ble_gattc_proc *proc) om = NULL; - max_sz = ble_att_mtu(proc->conn_handle) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; + max_sz = ble_att_mtu_by_cid(proc->conn_handle, proc->cid) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; if (max_sz <= 0) { /* Not connected. */ rc = BLE_HS_ENOTCONN; @@ -3645,7 +3696,7 @@ ble_gattc_write_long_tx(struct ble_gattc_proc *proc) proc->write_long.attr.offset); if (write_len <= 0) { - rc = ble_att_clt_tx_exec_write(proc->conn_handle, + rc = ble_att_clt_tx_exec_write(proc->conn_handle, proc->cid, BLE_ATT_EXEC_WRITE_F_EXECUTE); goto done; } @@ -3665,7 +3716,7 @@ ble_gattc_write_long_tx(struct ble_gattc_proc *proc) goto done; } - rc = ble_att_clt_tx_prep_write(proc->conn_handle, + rc = ble_att_clt_tx_prep_write(proc->conn_handle, proc->cid, proc->write_long.attr.handle, proc->write_long.attr.offset, om); om = NULL; @@ -3709,9 +3760,9 @@ ble_gattc_write_long_err(struct ble_gattc_proc *proc, int status, */ if (proc->write_long.attr.offset > 0 && proc->write_long.attr.offset < - OS_MBUF_PKTLEN(proc->write_long.attr.om)) { + OS_MBUF_PKTLEN(proc->write_long.attr.om)) { - ble_att_clt_tx_exec_write(proc->conn_handle, + ble_att_clt_tx_exec_write(proc->conn_handle, proc->cid, BLE_ATT_EXEC_WRITE_F_CANCEL); } @@ -3777,7 +3828,8 @@ ble_gattc_write_long_rx_prep(struct ble_gattc_proc *proc, rc = BLE_HS_EBADDATA; /* if data doesn't match up send cancel write */ - ble_att_clt_tx_exec_write(proc->conn_handle, BLE_ATT_EXEC_WRITE_F_CANCEL); + ble_att_clt_tx_exec_write(proc->conn_handle, proc->cid, + BLE_ATT_EXEC_WRITE_F_CANCEL); goto err; } else { /* Send follow-up request. */ @@ -3838,8 +3890,8 @@ ble_gattc_write_long(uint16_t conn_handle, uint16_t attr_handle, goto done; } - proc->op = BLE_GATT_OP_WRITE_LONG; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_WRITE_LONG); + proc->write_long.attr.handle = attr_handle; proc->write_long.attr.offset = offset; proc->write_long.attr.om = txom; @@ -3934,14 +3986,14 @@ ble_gattc_write_reliable_tx(struct ble_gattc_proc *proc) attr_idx = proc->write_reliable.cur_attr; if (attr_idx >= proc->write_reliable.num_attrs) { - rc = ble_att_clt_tx_exec_write(proc->conn_handle, + rc = ble_att_clt_tx_exec_write(proc->conn_handle, proc->cid, BLE_ATT_EXEC_WRITE_F_EXECUTE); goto done; } attr = proc->write_reliable.attrs + attr_idx; - max_sz = ble_att_mtu(proc->conn_handle) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; + max_sz = ble_att_mtu_by_cid(proc->conn_handle, proc->cid) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; if (max_sz <= 0) { /* Not connected. */ rc = BLE_HS_ENOTCONN; @@ -3964,8 +4016,8 @@ ble_gattc_write_reliable_tx(struct ble_gattc_proc *proc) goto done; } - rc = ble_att_clt_tx_prep_write(proc->conn_handle, attr->handle, - attr->offset, om); + rc = ble_att_clt_tx_prep_write(proc->conn_handle, proc->cid, + attr->handle, attr->offset, om); om = NULL; if (rc != 0) { goto done; @@ -4008,7 +4060,7 @@ ble_gattc_write_reliable_err(struct ble_gattc_proc *proc, int status, */ if (proc->write_reliable.cur_attr < proc->write_reliable.num_attrs) { - ble_att_clt_tx_exec_write(proc->conn_handle, + ble_att_clt_tx_exec_write(proc->conn_handle, proc->cid, BLE_ATT_EXEC_WRITE_F_CANCEL); } } @@ -4121,8 +4173,8 @@ ble_gattc_write_reliable(uint16_t conn_handle, goto done; } - proc->op = BLE_GATT_OP_WRITE_RELIABLE; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_WRITE_RELIABLE); + proc->write_reliable.num_attrs = num_attrs; proc->write_reliable.cur_attr = 0; proc->write_reliable.cb = cb; @@ -4344,8 +4396,8 @@ ble_gatts_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, goto done; } - proc->op = BLE_GATT_OP_INDICATE; - proc->conn_handle = conn_handle; + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_INDICATE); + proc->indicate.chr_val_handle = chr_val_handle; ble_gattc_log_indicate(chr_val_handle); @@ -4370,7 +4422,7 @@ ble_gatts_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, } } - rc = ble_att_clt_tx_indicate(conn_handle, chr_val_handle, txom); + rc = ble_att_clt_tx_indicate(conn_handle, proc->cid, chr_val_handle, txom); txom = NULL; if (rc != 0) { goto done; @@ -4431,12 +4483,12 @@ ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle) * procedure. */ void -ble_gattc_rx_err(uint16_t conn_handle, uint16_t handle, uint16_t status) +ble_gattc_rx_err(uint16_t conn_handle, uint16_t cid, uint16_t handle, uint16_t status) { struct ble_gattc_proc *proc; ble_gattc_err_fn *err_cb; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, BLE_GATT_OP_NONE); + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, BLE_GATT_OP_NONE); if (proc != NULL) { err_cb = ble_gattc_err_dispatch_get(proc->op); if (err_cb != NULL) { @@ -4451,11 +4503,13 @@ ble_gattc_rx_err(uint16_t conn_handle, uint16_t handle, uint16_t status) * GATT procedure. */ void -ble_gattc_rx_mtu(uint16_t conn_handle, int status, uint16_t chan_mtu) +ble_gattc_rx_mtu(uint16_t conn_handle, uint16_t cid, int status, uint16_t chan_mtu) { struct ble_gattc_proc *proc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, BLE_GATT_OP_MTU); + assert(cid == BLE_L2CAP_CID_ATT); + + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, BLE_L2CAP_CID_ATT, BLE_GATT_OP_MTU); if (proc != NULL) { ble_gattc_mtu_cb(proc, status, 0, chan_mtu); ble_gattc_process_status(proc, BLE_HS_EDONE); @@ -4467,7 +4521,7 @@ ble_gattc_rx_mtu(uint16_t conn_handle, int status, uint16_t chan_mtu) * find-information-response to the appropriate active GATT procedure. */ void -ble_gattc_rx_find_info_idata(uint16_t conn_handle, +ble_gattc_rx_find_info_idata(uint16_t conn_handle, uint16_t cid, struct ble_att_find_info_idata *idata) { #if !NIMBLE_BLE_ATT_CLT_FIND_INFO @@ -4477,7 +4531,7 @@ ble_gattc_rx_find_info_idata(uint16_t conn_handle, struct ble_gattc_proc *proc; int rc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, BLE_GATT_OP_DISC_ALL_DSCS); if (proc != NULL) { rc = ble_gattc_disc_all_dscs_rx_idata(proc, idata); @@ -4490,7 +4544,7 @@ ble_gattc_rx_find_info_idata(uint16_t conn_handle, * find-information-response to the appropriate active GATT procedure. */ void -ble_gattc_rx_find_info_complete(uint16_t conn_handle, int status) +ble_gattc_rx_find_info_complete(uint16_t conn_handle, uint16_t cid, int status) { #if !NIMBLE_BLE_ATT_CLT_FIND_INFO return; @@ -4499,8 +4553,8 @@ ble_gattc_rx_find_info_complete(uint16_t conn_handle, int status) struct ble_gattc_proc *proc; int rc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, - BLE_GATT_OP_DISC_ALL_DSCS); + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, + BLE_GATT_OP_DISC_ALL_DSCS); if (proc != NULL) { rc = ble_gattc_disc_all_dscs_rx_complete(proc, status); ble_gattc_process_status(proc, rc); @@ -4512,7 +4566,7 @@ ble_gattc_rx_find_info_complete(uint16_t conn_handle, int status) * find-by-type-value-response to the appropriate active GATT procedure. */ void -ble_gattc_rx_find_type_value_hinfo(uint16_t conn_handle, +ble_gattc_rx_find_type_value_hinfo(uint16_t conn_handle, uint16_t cid, struct ble_att_find_type_value_hinfo *hinfo) { #if !NIMBLE_BLE_ATT_CLT_FIND_TYPE @@ -4522,7 +4576,7 @@ ble_gattc_rx_find_type_value_hinfo(uint16_t conn_handle, struct ble_gattc_proc *proc; int rc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, BLE_GATT_OP_DISC_SVC_UUID); if (proc != NULL) { rc = ble_gattc_disc_svc_uuid_rx_hinfo(proc, hinfo); @@ -4535,7 +4589,7 @@ ble_gattc_rx_find_type_value_hinfo(uint16_t conn_handle, * find-by-type-value-response to the appropriate active GATT procedure. */ void -ble_gattc_rx_find_type_value_complete(uint16_t conn_handle, int status) +ble_gattc_rx_find_type_value_complete(uint16_t conn_handle, uint16_t cid, int status) { #if !NIMBLE_BLE_ATT_CLT_FIND_TYPE return; @@ -4544,8 +4598,8 @@ ble_gattc_rx_find_type_value_complete(uint16_t conn_handle, int status) struct ble_gattc_proc *proc; int rc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, - BLE_GATT_OP_DISC_SVC_UUID); + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, + BLE_GATT_OP_DISC_SVC_UUID); if (proc != NULL) { rc = ble_gattc_disc_svc_uuid_rx_complete(proc, status); ble_gattc_process_status(proc, rc); @@ -4557,7 +4611,7 @@ ble_gattc_rx_find_type_value_complete(uint16_t conn_handle, int status) * to the appropriate active GATT procedure. */ void -ble_gattc_rx_read_type_adata(uint16_t conn_handle, +ble_gattc_rx_read_type_adata(uint16_t conn_handle, uint16_t cid, struct ble_att_read_type_adata *adata) { #if !NIMBLE_BLE_ATT_CLT_READ_TYPE @@ -4568,7 +4622,7 @@ ble_gattc_rx_read_type_adata(uint16_t conn_handle, struct ble_gattc_proc *proc; int rc; - proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, + proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, cid, ble_gattc_rx_read_type_elem_entries, &rx_entry); if (proc != NULL) { @@ -4582,7 +4636,7 @@ ble_gattc_rx_read_type_adata(uint16_t conn_handle, * the appropriate active GATT procedure. */ void -ble_gattc_rx_read_type_complete(uint16_t conn_handle, int status) +ble_gattc_rx_read_type_complete(uint16_t conn_handle, uint16_t cid, int status) { #if !NIMBLE_BLE_ATT_CLT_READ_TYPE return; @@ -4593,7 +4647,7 @@ ble_gattc_rx_read_type_complete(uint16_t conn_handle, int status) int rc; proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY( - conn_handle, ble_gattc_rx_read_type_complete_entries, + conn_handle, cid, ble_gattc_rx_read_type_complete_entries, &rx_entry); if (proc != NULL) { rc = rx_entry->cb(proc, status); @@ -4606,7 +4660,7 @@ ble_gattc_rx_read_type_complete(uint16_t conn_handle, int status) * read-by-group-type-response to the appropriate active GATT procedure. */ void -ble_gattc_rx_read_group_type_adata(uint16_t conn_handle, +ble_gattc_rx_read_group_type_adata(uint16_t conn_handle, uint16_t cid, struct ble_att_read_group_type_adata *adata) { #if !NIMBLE_BLE_ATT_CLT_READ_GROUP_TYPE @@ -4616,7 +4670,7 @@ ble_gattc_rx_read_group_type_adata(uint16_t conn_handle, struct ble_gattc_proc *proc; int rc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, BLE_GATT_OP_DISC_ALL_SVCS); if (proc != NULL) { rc = ble_gattc_disc_all_svcs_rx_adata(proc, adata); @@ -4629,7 +4683,7 @@ ble_gattc_rx_read_group_type_adata(uint16_t conn_handle, * read-by-group-type-response to the appropriate active GATT procedure. */ void -ble_gattc_rx_read_group_type_complete(uint16_t conn_handle, int status) +ble_gattc_rx_read_group_type_complete(uint16_t conn_handle, uint16_t cid, int status) { #if !NIMBLE_BLE_ATT_CLT_READ_GROUP_TYPE return; @@ -4638,8 +4692,8 @@ ble_gattc_rx_read_group_type_complete(uint16_t conn_handle, int status) struct ble_gattc_proc *proc; int rc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, - BLE_GATT_OP_DISC_ALL_SVCS); + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, + BLE_GATT_OP_DISC_ALL_SVCS); if (proc != NULL) { rc = ble_gattc_disc_all_svcs_rx_complete(proc, status); ble_gattc_process_status(proc, rc); @@ -4651,7 +4705,7 @@ ble_gattc_rx_read_group_type_complete(uint16_t conn_handle, int status) * procedure. */ void -ble_gattc_rx_read_rsp(uint16_t conn_handle, int status, struct os_mbuf **om) +ble_gattc_rx_read_rsp(uint16_t conn_handle, uint16_t cid, int status, struct os_mbuf **om) { #if !NIMBLE_BLE_ATT_CLT_READ return; @@ -4661,7 +4715,7 @@ ble_gattc_rx_read_rsp(uint16_t conn_handle, int status, struct os_mbuf **om) struct ble_gattc_proc *proc; int rc; - proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, + proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, cid, ble_gattc_rx_read_rsp_entries, &rx_entry); if (proc != NULL) { @@ -4675,7 +4729,7 @@ ble_gattc_rx_read_rsp(uint16_t conn_handle, int status, struct os_mbuf **om) * procedure. */ void -ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, int status, +ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, uint16_t cid, int status, struct os_mbuf **om) { #if !NIMBLE_BLE_ATT_CLT_READ_BLOB @@ -4685,7 +4739,7 @@ ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, int status, struct ble_gattc_proc *proc; int rc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, BLE_GATT_OP_READ_LONG); if (proc != NULL) { rc = ble_gattc_read_long_rx_read_rsp(proc, status, om); @@ -4698,7 +4752,7 @@ ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, int status, * GATT procedure. */ void -ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, int status, +ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, uint16_t cid, int status, struct os_mbuf **om) { #if !NIMBLE_BLE_ATT_CLT_READ_MULT @@ -4707,7 +4761,7 @@ ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, int status, struct ble_gattc_proc *proc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, BLE_GATT_OP_READ_MULT); if (proc != NULL) { ble_gattc_read_mult_cb(proc, status, 0, om); @@ -4720,7 +4774,7 @@ ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, int status, * procedure. */ void -ble_gattc_rx_write_rsp(uint16_t conn_handle) +ble_gattc_rx_write_rsp(uint16_t conn_handle, uint16_t cid) { #if !NIMBLE_BLE_ATT_CLT_WRITE return; @@ -4728,7 +4782,7 @@ ble_gattc_rx_write_rsp(uint16_t conn_handle) struct ble_gattc_proc *proc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, BLE_GATT_OP_WRITE); if (proc != NULL) { ble_gattc_write_cb(proc, 0, 0); @@ -4741,7 +4795,7 @@ ble_gattc_rx_write_rsp(uint16_t conn_handle) * GATT procedure. */ void -ble_gattc_rx_prep_write_rsp(uint16_t conn_handle, int status, +ble_gattc_rx_prep_write_rsp(uint16_t conn_handle, uint16_t cid, int status, uint16_t handle, uint16_t offset, struct os_mbuf **om) { @@ -4753,7 +4807,7 @@ ble_gattc_rx_prep_write_rsp(uint16_t conn_handle, int status, struct ble_gattc_proc *proc; int rc; - proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, + proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, cid, ble_gattc_rx_prep_entries, &rx_entry); if (proc != NULL) { @@ -4767,7 +4821,7 @@ ble_gattc_rx_prep_write_rsp(uint16_t conn_handle, int status, * GATT procedure. */ void -ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, int status) +ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, uint16_t cid, int status) { #if !NIMBLE_BLE_ATT_CLT_EXEC_WRITE return; @@ -4777,7 +4831,7 @@ ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, int status) struct ble_gattc_proc *proc; int rc; - proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, + proc = BLE_GATTC_RX_EXTRACT_RX_ENTRY(conn_handle, cid, ble_gattc_rx_exec_entries, &rx_entry); if (proc != NULL) { rc = rx_entry->cb(proc, status); @@ -4790,7 +4844,7 @@ ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, int status) * active GATT procedure. */ void -ble_gatts_rx_indicate_rsp(uint16_t conn_handle) +ble_gatts_rx_indicate_rsp(uint16_t conn_handle, uint16_t cid) { #if !NIMBLE_BLE_ATT_CLT_INDICATE return; @@ -4798,7 +4852,7 @@ ble_gatts_rx_indicate_rsp(uint16_t conn_handle) struct ble_gattc_proc *proc; - proc = ble_gattc_extract_first_by_conn_op(conn_handle, + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, BLE_GATT_OP_INDICATE); if (proc != NULL) { ble_gatts_indicate_rx_rsp(proc); diff --git a/nimble/host/src/ble_hs_conn.c b/nimble/host/src/ble_hs_conn.c index ea89460cc4..9b7bdbb3d0 100644 --- a/nimble/host/src/ble_hs_conn.c +++ b/nimble/host/src/ble_hs_conn.c @@ -193,6 +193,7 @@ ble_hs_conn_alloc(uint16_t conn_handle) } STAILQ_INIT(&conn->bhc_tx_q); + STAILQ_INIT(&conn->att_tx_q); STATS_INC(ble_hs_stats, conn_create); diff --git a/nimble/host/src/ble_hs_conn_priv.h b/nimble/host/src/ble_hs_conn_priv.h index 0e451194d1..31e831c878 100644 --- a/nimble/host/src/ble_hs_conn_priv.h +++ b/nimble/host/src/ble_hs_conn_priv.h @@ -102,6 +102,9 @@ struct ble_hs_conn { #if MYNEWT_VAL(BLE_PERIODIC_ADV) struct ble_hs_periodic_sync *psync; #endif + + STAILQ_HEAD(, os_mbuf_pkthdr) att_tx_q; + bool client_att_busy; }; struct ble_hs_conn_addrs { diff --git a/nimble/host/test/src/ble_att_clt_test.c b/nimble/host/test/src/ble_att_clt_test.c index 787d4bca3b..7d41371ef9 100644 --- a/nimble/host/test/src/ble_att_clt_test.c +++ b/nimble/host/test/src/ble_att_clt_test.c @@ -67,9 +67,9 @@ ble_att_clt_test_tx_write_req_or_cmd(uint16_t conn_handle, uint16_t handle, om = ble_hs_test_util_om_from_flat(value, value_len); if (is_req) { - rc = ble_att_clt_tx_write_req(conn_handle, handle, om); + rc = ble_att_clt_tx_write_req(conn_handle, BLE_L2CAP_CID_ATT, handle, om); } else { - rc = ble_att_clt_tx_write_cmd(conn_handle, handle, om); + rc = ble_att_clt_tx_write_cmd(conn_handle, BLE_L2CAP_CID_ATT, handle, om); } TEST_ASSERT(rc == 0); } @@ -84,19 +84,19 @@ TEST_CASE_SELF(ble_att_clt_test_tx_find_info) conn_handle = ble_att_clt_test_misc_init(); /*** Success. */ - rc = ble_att_clt_tx_find_info(conn_handle, 1, 0xffff); + rc = ble_att_clt_tx_find_info(conn_handle, BLE_L2CAP_CID_ATT, 1, 0xffff); TEST_ASSERT(rc == 0); /*** Error: start handle of 0. */ - rc = ble_att_clt_tx_find_info(conn_handle, 0, 0xffff); + rc = ble_att_clt_tx_find_info(conn_handle, BLE_L2CAP_CID_ATT, 0, 0xffff); TEST_ASSERT(rc == BLE_HS_EINVAL); /*** Error: start handle greater than end handle. */ - rc = ble_att_clt_tx_find_info(conn_handle, 500, 499); + rc = ble_att_clt_tx_find_info(conn_handle, BLE_L2CAP_CID_ATT, 500, 499); TEST_ASSERT(rc == BLE_HS_EINVAL); /*** Success; start and end handles equal. */ - rc = ble_att_clt_tx_find_info(conn_handle, 500, 500); + rc = ble_att_clt_tx_find_info(conn_handle, BLE_L2CAP_CID_ATT, 500, 500); TEST_ASSERT(rc == 0); ble_hs_test_util_assert_mbufs_freed(NULL); @@ -206,7 +206,7 @@ ble_att_clt_test_misc_prep_good(uint16_t handle, uint16_t offset, conn_handle = ble_att_clt_test_misc_init(); om = ble_hs_test_util_om_from_flat(attr_data, attr_data_len); - rc = ble_att_clt_tx_prep_write(conn_handle, handle, offset, om); + rc = ble_att_clt_tx_prep_write(conn_handle, BLE_L2CAP_CID_ATT, handle, offset, om); TEST_ASSERT(rc == 0); om = ble_hs_test_util_prev_tx_dequeue_pullup(); @@ -232,7 +232,7 @@ ble_att_clt_test_misc_exec_good(uint8_t flags) conn_handle = ble_att_clt_test_misc_init(); - rc = ble_att_clt_tx_exec_write(conn_handle, flags); + rc = ble_att_clt_tx_exec_write(conn_handle, BLE_L2CAP_CID_ATT, flags); TEST_ASSERT(rc == 0); om = ble_hs_test_util_prev_tx_dequeue_pullup(); @@ -256,7 +256,7 @@ ble_att_clt_test_misc_prep_bad(uint16_t handle, uint16_t offset, om = ble_hs_test_util_om_from_flat(attr_data, attr_data_len); - rc = ble_att_clt_tx_prep_write(conn_handle, handle, offset, om); + rc = ble_att_clt_tx_prep_write(conn_handle, BLE_L2CAP_CID_ATT, handle, offset, om); TEST_ASSERT(rc == status); } @@ -287,11 +287,11 @@ TEST_CASE_SELF(ble_att_clt_test_tx_read) conn_handle = ble_att_clt_test_misc_init(); /*** Success. */ - rc = ble_att_clt_tx_read(conn_handle, 1); + rc = ble_att_clt_tx_read(conn_handle, BLE_L2CAP_CID_ATT, 1); TEST_ASSERT(rc == 0); /*** Error: handle of 0. */ - rc = ble_att_clt_tx_read(conn_handle, 0); + rc = ble_att_clt_tx_read(conn_handle, BLE_L2CAP_CID_ATT, 0); TEST_ASSERT(rc == BLE_HS_EINVAL); ble_hs_test_util_assert_mbufs_freed(NULL); @@ -333,11 +333,11 @@ TEST_CASE_SELF(ble_att_clt_test_tx_read_blob) conn_handle = ble_att_clt_test_misc_init(); /*** Success. */ - rc = ble_att_clt_tx_read_blob(conn_handle, 1, 0); + rc = ble_att_clt_tx_read_blob(conn_handle, BLE_L2CAP_CID_ATT, 1, 0); TEST_ASSERT(rc == 0); /*** Error: handle of 0. */ - rc = ble_att_clt_tx_read_blob(conn_handle, 0, 0); + rc = ble_att_clt_tx_read_blob(conn_handle, BLE_L2CAP_CID_ATT, 0, 0); TEST_ASSERT(rc == BLE_HS_EINVAL); ble_hs_test_util_assert_mbufs_freed(NULL); @@ -380,7 +380,7 @@ TEST_CASE_SELF(ble_att_clt_test_tx_read_mult) conn_handle = ble_att_clt_test_misc_init(); /*** Success. */ - rc = ble_att_clt_tx_read_mult(conn_handle, ((uint16_t[]){ 1, 2 }), 2); + rc = ble_att_clt_tx_read_mult(conn_handle, BLE_L2CAP_CID_ATT, ((uint16_t[]){ 1, 2 }), 2); TEST_ASSERT(rc == 0); om = ble_hs_test_util_prev_tx_dequeue_pullup(); @@ -392,7 +392,7 @@ TEST_CASE_SELF(ble_att_clt_test_tx_read_mult) TEST_ASSERT(get_le16(om->om_data + BLE_ATT_READ_MULT_REQ_BASE_SZ + 2) == 2); /*** Error: no handles. */ - rc = ble_att_clt_tx_read_mult(conn_handle, NULL, 0); + rc = ble_att_clt_tx_read_mult(conn_handle, BLE_L2CAP_CID_ATT, NULL, 0); TEST_ASSERT(rc == BLE_HS_EINVAL); ble_hs_test_util_assert_mbufs_freed(NULL); @@ -508,7 +508,7 @@ TEST_CASE_SELF(ble_att_clt_test_tx_exec_write) ble_att_clt_test_misc_exec_good(BLE_ATT_EXEC_WRITE_F_EXECUTE); /*** Success: nonzero == execute. */ - rc = ble_att_clt_tx_exec_write(conn_handle, 0x02); + rc = ble_att_clt_tx_exec_write(conn_handle, BLE_L2CAP_CID_ATT, 0x02); TEST_ASSERT(rc == 0); ble_hs_test_util_assert_mbufs_freed(NULL); diff --git a/nimble/host/test/src/ble_att_svr_test.c b/nimble/host/test/src/ble_att_svr_test.c index 60ab14b4e1..84394d6a56 100644 --- a/nimble/host/test/src/ble_att_svr_test.c +++ b/nimble/host/test/src/ble_att_svr_test.c @@ -24,6 +24,7 @@ #include "nimble/hci_common.h" #include "ble_hs_test.h" #include "host/ble_uuid.h" +#include "host/ble_l2cap.h" #include "ble_hs_test_util.h" static uint8_t *ble_att_svr_test_attr_r_1; @@ -478,7 +479,7 @@ ble_att_svr_test_misc_verify_all_read_mult( } static void -ble_att_svr_test_misc_verify_tx_mtu_rsp(uint16_t conn_handle) +ble_att_svr_test_misc_verify_tx_mtu_rsp(uint16_t conn_handle, uint16_t cid) { struct ble_l2cap_chan *chan; struct ble_hs_conn *conn; @@ -487,7 +488,7 @@ ble_att_svr_test_misc_verify_tx_mtu_rsp(uint16_t conn_handle) ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); + rc = ble_att_conn_chan_find(conn_handle, cid, &conn, &chan); assert(rc == 0); my_mtu = chan->my_mtu; @@ -644,7 +645,7 @@ ble_att_svr_test_misc_mtu_exchange(uint16_t my_mtu, uint16_t peer_sent, buf, sizeof buf); TEST_ASSERT(rc == 0); - ble_att_svr_test_misc_verify_tx_mtu_rsp(conn_handle); + ble_att_svr_test_misc_verify_tx_mtu_rsp(conn_handle, BLE_L2CAP_CID_ATT); ble_hs_lock(); rc = ble_hs_misc_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT, @@ -1138,19 +1139,19 @@ TEST_CASE_SELF(ble_att_svr_test_find_info) conn_handle = ble_att_svr_test_misc_init(128); /*** Start handle of 0. */ - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, 0, 0); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, 0, 0); TEST_ASSERT(rc != 0); ble_hs_test_util_verify_tx_err_rsp( BLE_ATT_OP_FIND_INFO_REQ, 0, BLE_ATT_ERR_INVALID_HANDLE); /*** Start handle > end handle. */ - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, 101, 100); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, 101, 100); TEST_ASSERT(rc != 0); ble_hs_test_util_verify_tx_err_rsp( BLE_ATT_OP_FIND_INFO_REQ, 101, BLE_ATT_ERR_INVALID_HANDLE); /*** No attributes. */ - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, 200, 300); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, 200, 300); TEST_ASSERT(rc != 0); ble_hs_test_util_verify_tx_err_rsp( BLE_ATT_OP_FIND_INFO_REQ, 200, BLE_ATT_ERR_ATTR_NOT_FOUND); @@ -1160,13 +1161,13 @@ TEST_CASE_SELF(ble_att_svr_test_find_info) ble_att_svr_test_misc_attr_fn_r_1, NULL); TEST_ASSERT(rc == 0); - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, 200, 300); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, 200, 300); TEST_ASSERT(rc != 0); ble_hs_test_util_verify_tx_err_rsp( BLE_ATT_OP_FIND_INFO_REQ, 200, BLE_ATT_ERR_ATTR_NOT_FOUND); /*** One 128-bit entry. */ - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, handle1, handle1); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, handle1, handle1); TEST_ASSERT(rc == 0); ble_hs_test_util_verify_tx_find_info_rsp( ((struct ble_hs_test_util_att_info_entry[]) { { @@ -1181,7 +1182,7 @@ TEST_CASE_SELF(ble_att_svr_test_find_info) ble_att_svr_test_misc_attr_fn_r_1, NULL); TEST_ASSERT(rc == 0); - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, handle1, handle2); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, handle1, handle2); TEST_ASSERT(rc == 0); ble_hs_test_util_verify_tx_find_info_rsp( ((struct ble_hs_test_util_att_info_entry[]) { { @@ -1199,7 +1200,7 @@ TEST_CASE_SELF(ble_att_svr_test_find_info) ble_att_svr_test_misc_attr_fn_r_1, NULL); TEST_ASSERT(rc == 0); - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, handle1, handle3); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, handle1, handle3); TEST_ASSERT(rc == 0); ble_hs_test_util_verify_tx_find_info_rsp( ((struct ble_hs_test_util_att_info_entry[]) { { @@ -1213,7 +1214,7 @@ TEST_CASE_SELF(ble_att_svr_test_find_info) } })); /*** Remaining 16-bit entry requested. */ - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, handle3, handle3); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, handle3, handle3); TEST_ASSERT(rc == 0); ble_hs_test_util_verify_tx_find_info_rsp( ((struct ble_hs_test_util_att_info_entry[]) { { @@ -1936,13 +1937,13 @@ TEST_CASE_SELF(ble_att_svr_test_oom) TEST_ASSERT_FATAL(rc == 0); /* Ensure we were able to send a real response. */ - ble_att_svr_test_misc_verify_tx_mtu_rsp(conn_handle); + ble_att_svr_test_misc_verify_tx_mtu_rsp(conn_handle, BLE_L2CAP_CID_ATT); /*** Find information; always respond affirmatively, even when no mbufs. */ ble_hs_test_util_prev_tx_dequeue(); /* Receive a request. */ - rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, 1, 100); + rc = ble_hs_test_util_rx_att_find_info_req(conn_handle, BLE_L2CAP_CID_ATT, 1, 100); TEST_ASSERT_FATAL(rc == 0); /* Ensure we were able to send a real response. */ diff --git a/nimble/host/test/src/ble_gatt_disc_c_test.c b/nimble/host/test/src/ble_gatt_disc_c_test.c index e19db341bb..d0034889f0 100644 --- a/nimble/host/test/src/ble_gatt_disc_c_test.c +++ b/nimble/host/test/src/ble_gatt_disc_c_test.c @@ -25,6 +25,7 @@ #include "ble_hs_test.h" #include "host/ble_gatt.h" #include "host/ble_uuid.h" +#include "host/ble_l2cap.h" #include "ble_hs_test_util.h" struct ble_gatt_disc_c_test_char { @@ -50,8 +51,8 @@ ble_gatt_disc_c_test_init(void) } static int -ble_gatt_disc_c_test_misc_rx_rsp_once( - uint16_t conn_handle, struct ble_gatt_disc_c_test_char *chars) +ble_gatt_disc_c_test_misc_rx_rsp_once(uint16_t conn_handle, uint16_t cid, + struct ble_gatt_disc_c_test_char *chars) { struct ble_att_read_type_rsp rsp; uint8_t buf[1024]; @@ -86,14 +87,14 @@ ble_gatt_disc_c_test_misc_rx_rsp_once( if (chars[i].uuid->type == BLE_UUID_TYPE_16) { if (off + BLE_ATT_READ_TYPE_ADATA_SZ_16 > - ble_att_mtu(conn_handle)) { + ble_att_mtu_by_cid(conn_handle, cid)) { /* Can't fit any more entries. */ break; } } else { if (off + BLE_ATT_READ_TYPE_ADATA_SZ_128 > - ble_att_mtu(conn_handle)) { + ble_att_mtu_by_cid(conn_handle, cid)) { /* Can't fit any more entries. */ break; @@ -121,7 +122,7 @@ ble_gatt_disc_c_test_misc_rx_rsp_once( } static void -ble_gatt_disc_c_test_misc_rx_rsp(uint16_t conn_handle, +ble_gatt_disc_c_test_misc_rx_rsp(uint16_t conn_handle, uint16_t cid, uint16_t end_handle, struct ble_gatt_disc_c_test_char *chars) { @@ -130,7 +131,7 @@ ble_gatt_disc_c_test_misc_rx_rsp(uint16_t conn_handle, idx = 0; while (chars[idx].def_handle != 0) { - count = ble_gatt_disc_c_test_misc_rx_rsp_once(conn_handle, + count = ble_gatt_disc_c_test_misc_rx_rsp_once(conn_handle, cid, chars + idx); if (count == 0) { break; @@ -140,7 +141,8 @@ ble_gatt_disc_c_test_misc_rx_rsp(uint16_t conn_handle, if (chars[idx - 1].def_handle != end_handle) { /* Send the pending ATT Request. */ - ble_hs_test_util_rx_att_err_rsp(conn_handle, BLE_ATT_OP_READ_TYPE_REQ, + ble_hs_test_util_rx_att_err_rsp(conn_handle, cid, + BLE_ATT_OP_READ_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, chars[idx - 1].def_handle); } @@ -229,7 +231,7 @@ ble_gatt_disc_c_test_misc_all(uint16_t start_handle, uint16_t end_handle, ble_gatt_disc_c_test_misc_cb, &num_left); TEST_ASSERT(rc == 0); - ble_gatt_disc_c_test_misc_rx_rsp(2, end_handle, chars); + ble_gatt_disc_c_test_misc_rx_rsp(2, BLE_L2CAP_CID_ATT, end_handle, chars); ble_gatt_disc_c_test_misc_verify_chars(chars, stop_after); } @@ -252,7 +254,7 @@ ble_gatt_disc_c_test_misc_uuid(uint16_t start_handle, uint16_t end_handle, &stop_after); TEST_ASSERT(rc == 0); - ble_gatt_disc_c_test_misc_rx_rsp(2, end_handle, rsp_chars); + ble_gatt_disc_c_test_misc_rx_rsp(2, BLE_L2CAP_CID_ATT, end_handle, rsp_chars); ble_gatt_disc_c_test_misc_verify_chars(ret_chars, 0); } @@ -574,7 +576,7 @@ TEST_CASE_SELF(ble_gatt_disc_c_test_oom_all) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - num_chrs = ble_gatt_disc_c_test_misc_rx_rsp_once(1, chrs); + num_chrs = ble_gatt_disc_c_test_misc_rx_rsp_once(1, BLE_L2CAP_CID_ATT, chrs); /* Make sure there are still undiscovered characteristics. */ TEST_ASSERT_FATAL(num_chrs < sizeof chrs / sizeof chrs[0] - 1); @@ -598,7 +600,7 @@ TEST_CASE_SELF(ble_gatt_disc_c_test_oom_all) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_disc_c_test_misc_rx_rsp_once(1, chrs + num_chrs); + ble_gatt_disc_c_test_misc_rx_rsp_once(1, BLE_L2CAP_CID_ATT, chrs + num_chrs); /* Ensure no follow-up request got sent. It should not have gotten sent * due to mbuf exhaustion. @@ -617,7 +619,7 @@ TEST_CASE_SELF(ble_gatt_disc_c_test_oom_all) os_time_advance(ticks_until); ble_gattc_timer(); - ble_hs_test_util_rx_att_err_rsp(1, + ble_hs_test_util_rx_att_err_rsp(1, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, 1); @@ -663,7 +665,7 @@ TEST_CASE_SELF(ble_gatt_disc_c_test_oom_uuid) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - num_chrs = ble_gatt_disc_c_test_misc_rx_rsp_once(1, chrs); + num_chrs = ble_gatt_disc_c_test_misc_rx_rsp_once(1, BLE_L2CAP_CID_ATT, chrs); /* Make sure there are still undiscovered characteristics. */ TEST_ASSERT_FATAL(num_chrs < sizeof chrs / sizeof chrs[0] - 1); @@ -686,7 +688,7 @@ TEST_CASE_SELF(ble_gatt_disc_c_test_oom_uuid) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_disc_c_test_misc_rx_rsp_once(1, chrs + num_chrs); + ble_gatt_disc_c_test_misc_rx_rsp_once(1, BLE_L2CAP_CID_ATT, chrs + num_chrs); /* Ensure no follow-up request got sent. It should not have gotten sent * due to mbuf exhaustion. @@ -704,7 +706,7 @@ TEST_CASE_SELF(ble_gatt_disc_c_test_oom_uuid) os_time_advance(ticks_until); ble_gattc_timer(); - ble_hs_test_util_rx_att_err_rsp(1, + ble_hs_test_util_rx_att_err_rsp(1, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, 1); diff --git a/nimble/host/test/src/ble_gatt_disc_d_test.c b/nimble/host/test/src/ble_gatt_disc_d_test.c index e405c86f1d..acee2ef8d6 100644 --- a/nimble/host/test/src/ble_gatt_disc_d_test.c +++ b/nimble/host/test/src/ble_gatt_disc_d_test.c @@ -49,8 +49,8 @@ ble_gatt_disc_d_test_init(void) } static int -ble_gatt_disc_d_test_misc_rx_rsp_once( - uint16_t conn_handle, struct ble_gatt_disc_d_test_dsc *dscs) +ble_gatt_disc_d_test_misc_rx_rsp_once(uint16_t conn_handle, uint16_t cid, + struct ble_gatt_disc_d_test_dsc *dscs) { struct ble_att_find_info_rsp rsp; uint8_t buf[1024]; @@ -77,14 +77,14 @@ ble_gatt_disc_d_test_misc_rx_rsp_once( if (dscs[i].dsc_uuid.u.type == BLE_UUID_TYPE_16) { if (off + BLE_ATT_FIND_INFO_IDATA_16_SZ > - ble_att_mtu(conn_handle)) { + ble_att_mtu_by_cid(conn_handle, cid)) { /* Can't fit any more entries. */ break; } } else { if (off + BLE_ATT_FIND_INFO_IDATA_128_SZ > - ble_att_mtu(conn_handle)) { + ble_att_mtu_by_cid(conn_handle, cid)) { /* Can't fit any more entries. */ break; @@ -104,7 +104,7 @@ ble_gatt_disc_d_test_misc_rx_rsp_once( off += ble_uuid_length(&dscs[i].dsc_uuid.u); } - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, off); TEST_ASSERT(rc == 0); @@ -113,6 +113,7 @@ ble_gatt_disc_d_test_misc_rx_rsp_once( static void ble_gatt_disc_d_test_misc_rx_rsp(uint16_t conn_handle, + uint16_t cid, uint16_t end_handle, struct ble_gatt_disc_d_test_dsc *dscs) { @@ -121,7 +122,7 @@ ble_gatt_disc_d_test_misc_rx_rsp(uint16_t conn_handle, idx = 0; while (dscs[idx].chr_val_handle != 0) { - count = ble_gatt_disc_d_test_misc_rx_rsp_once(conn_handle, dscs + idx); + count = ble_gatt_disc_d_test_misc_rx_rsp_once(conn_handle, cid, dscs + idx); if (count == 0) { break; } @@ -130,7 +131,8 @@ ble_gatt_disc_d_test_misc_rx_rsp(uint16_t conn_handle, if (dscs[idx - 1].dsc_handle != end_handle) { /* Send the pending ATT Request. */ - ble_hs_test_util_rx_att_err_rsp(conn_handle, BLE_ATT_OP_FIND_INFO_REQ, + ble_hs_test_util_rx_att_err_rsp(conn_handle, cid, + BLE_ATT_OP_FIND_INFO_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, end_handle); } @@ -223,7 +225,7 @@ ble_gatt_disc_d_test_misc_all(uint16_t chr_val_handle, uint16_t end_handle, ble_gatt_disc_d_test_misc_cb, &num_left); TEST_ASSERT(rc == 0); - ble_gatt_disc_d_test_misc_rx_rsp(2, end_handle, dscs); + ble_gatt_disc_d_test_misc_rx_rsp(2, BLE_L2CAP_CID_ATT, end_handle, dscs); ble_gatt_disc_d_test_misc_verify_dscs(dscs, stop_after); } @@ -389,7 +391,7 @@ TEST_CASE_SELF(ble_gatt_disc_d_test_oom_all) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - num_dscs = ble_gatt_disc_d_test_misc_rx_rsp_once(1, dscs); + num_dscs = ble_gatt_disc_d_test_misc_rx_rsp_once(1, BLE_L2CAP_CID_ATT, dscs); /* Make sure there are still undiscovered services. */ TEST_ASSERT_FATAL(num_dscs < sizeof dscs / sizeof dscs[0] - 1); @@ -412,7 +414,7 @@ TEST_CASE_SELF(ble_gatt_disc_d_test_oom_all) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_disc_d_test_misc_rx_rsp_once(1, dscs + num_dscs); + ble_gatt_disc_d_test_misc_rx_rsp_once(1, BLE_L2CAP_CID_ATT, dscs + num_dscs); /* Ensure no follow-up request got sent. It should not have gotten sent * due to mbuf exhaustion. @@ -430,7 +432,7 @@ TEST_CASE_SELF(ble_gatt_disc_d_test_oom_all) os_time_advance(ticks_until); ble_gattc_timer(); - ble_hs_test_util_rx_att_err_rsp(1, + ble_hs_test_util_rx_att_err_rsp(1, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, 1); diff --git a/nimble/host/test/src/ble_gatt_disc_s_test.c b/nimble/host/test/src/ble_gatt_disc_s_test.c index 3e7a30266c..87735f7dff 100644 --- a/nimble/host/test/src/ble_gatt_disc_s_test.c +++ b/nimble/host/test/src/ble_gatt_disc_s_test.c @@ -56,8 +56,8 @@ ble_gatt_disc_s_test_misc_svc_length(struct ble_gatt_disc_s_test_svc *service) } static int -ble_gatt_disc_s_test_misc_rx_all_rsp_once( - uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services) +ble_gatt_disc_s_test_misc_rx_all_rsp_once(uint16_t conn_handle, uint16_t cid, + struct ble_gatt_disc_s_test_svc *services) { struct ble_att_read_group_type_rsp rsp; uint8_t buf[1024]; @@ -86,14 +86,14 @@ ble_gatt_disc_s_test_misc_rx_all_rsp_once( if (services[i].uuid->type == BLE_UUID_TYPE_16) { if (off + BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_16 > - ble_att_mtu(conn_handle)) { + ble_att_mtu_by_cid(conn_handle, cid)) { /* Can't fit any more entries. */ break; } } else { if (off + BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_128 > - ble_att_mtu(conn_handle)) { + ble_att_mtu_by_cid(conn_handle,cid)) { /* Can't fit any more entries. */ break; @@ -110,7 +110,7 @@ ble_gatt_disc_s_test_misc_rx_all_rsp_once( off += ble_uuid_length(services[i].uuid); } - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, off); TEST_ASSERT(rc == 0); @@ -118,22 +118,22 @@ ble_gatt_disc_s_test_misc_rx_all_rsp_once( } static void -ble_gatt_disc_s_test_misc_rx_all_rsp( - uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services) +ble_gatt_disc_s_test_misc_rx_all_rsp(uint16_t conn_handle, uint16_t cid, + struct ble_gatt_disc_s_test_svc *services) { int count; int idx; idx = 0; while (services[idx].start_handle != 0) { - count = ble_gatt_disc_s_test_misc_rx_all_rsp_once(conn_handle, + count = ble_gatt_disc_s_test_misc_rx_all_rsp_once(conn_handle, cid, services + idx); idx += count; } if (services[idx - 1].end_handle != 0xffff) { /* Send the pending ATT Request. */ - ble_hs_test_util_rx_att_err_rsp(conn_handle, + ble_hs_test_util_rx_att_err_rsp(conn_handle, cid, BLE_ATT_OP_READ_GROUP_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, services[idx - 1].start_handle); @@ -141,8 +141,8 @@ ble_gatt_disc_s_test_misc_rx_all_rsp( } static int -ble_gatt_disc_s_test_misc_rx_uuid_rsp_once( - uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services) +ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(uint16_t conn_handle, uint16_t cid, + struct ble_gatt_disc_s_test_svc *services) { uint8_t buf[1024]; int off; @@ -160,7 +160,7 @@ ble_gatt_disc_s_test_misc_rx_uuid_rsp_once( } if (off + BLE_ATT_FIND_TYPE_VALUE_HINFO_BASE_SZ > - ble_att_mtu(conn_handle)) { + ble_att_mtu_by_cid(conn_handle, cid)) { /* Can't fit any more entries. */ break; @@ -173,7 +173,7 @@ ble_gatt_disc_s_test_misc_rx_uuid_rsp_once( off += 2; } - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, off); TEST_ASSERT(rc == 0); @@ -181,22 +181,22 @@ ble_gatt_disc_s_test_misc_rx_uuid_rsp_once( } static void -ble_gatt_disc_s_test_misc_rx_uuid_rsp( - uint16_t conn_handle, struct ble_gatt_disc_s_test_svc *services) +ble_gatt_disc_s_test_misc_rx_uuid_rsp(uint16_t conn_handle, uint16_t cid, + struct ble_gatt_disc_s_test_svc *services) { int count; int idx; idx = 0; while (services[idx].start_handle != 0) { - count = ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(conn_handle, + count = ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(conn_handle, cid, services + idx); idx += count; } if (services[idx - 1].end_handle != 0xffff) { /* Send the pending ATT Request. */ - ble_hs_test_util_rx_att_err_rsp(conn_handle, + ble_hs_test_util_rx_att_err_rsp(conn_handle, cid, BLE_ATT_OP_FIND_TYPE_VALUE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, services[idx - 1].start_handle); @@ -269,7 +269,7 @@ ble_gatt_disc_s_test_misc_good_all(struct ble_gatt_disc_s_test_svc *services) rc = ble_gattc_disc_all_svcs(2, ble_gatt_disc_s_test_misc_disc_cb, NULL); TEST_ASSERT(rc == 0); - ble_gatt_disc_s_test_misc_rx_all_rsp(2, services); + ble_gatt_disc_s_test_misc_rx_all_rsp(2, BLE_L2CAP_CID_ATT, services); ble_gatt_disc_s_test_misc_verify_services(services); } @@ -290,7 +290,7 @@ ble_gatt_disc_s_test_misc_good_uuid( ble_hs_test_util_verify_tx_disc_svc_uuid(services[0].uuid); - ble_gatt_disc_s_test_misc_rx_uuid_rsp(2, services); + ble_gatt_disc_s_test_misc_rx_uuid_rsp(2, BLE_L2CAP_CID_ATT, services); ble_gatt_disc_s_test_misc_verify_services(services); } @@ -425,7 +425,7 @@ TEST_CASE_SELF(ble_gatt_disc_s_test_oom_all) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - num_svcs = ble_gatt_disc_s_test_misc_rx_all_rsp_once(1, svcs); + num_svcs = ble_gatt_disc_s_test_misc_rx_all_rsp_once(1, BLE_L2CAP_CID_ATT, svcs); /* Make sure there are still undiscovered services. */ TEST_ASSERT_FATAL(num_svcs < sizeof svcs / sizeof svcs[0] - 1); @@ -448,7 +448,7 @@ TEST_CASE_SELF(ble_gatt_disc_s_test_oom_all) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_disc_s_test_misc_rx_all_rsp_once(1, svcs + num_svcs); + ble_gatt_disc_s_test_misc_rx_all_rsp_once(1, BLE_L2CAP_CID_ATT, svcs + num_svcs); /* Ensure no follow-up request got sent. It should not have gotten sent * due to mbuf exhaustion. @@ -465,7 +465,7 @@ TEST_CASE_SELF(ble_gatt_disc_s_test_oom_all) os_time_advance(ticks_until); ble_gattc_timer(); - ble_hs_test_util_rx_att_err_rsp(1, + ble_hs_test_util_rx_att_err_rsp(1, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_GROUP_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, 1); @@ -504,7 +504,7 @@ TEST_CASE_SELF(ble_gatt_disc_s_test_oom_uuid) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - num_svcs = ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(1, svcs); + num_svcs = ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(1, BLE_L2CAP_CID_ATT, svcs); /* Make sure there are still undiscovered services. */ TEST_ASSERT_FATAL(num_svcs < sizeof svcs / sizeof svcs[0] - 1); @@ -527,7 +527,7 @@ TEST_CASE_SELF(ble_gatt_disc_s_test_oom_uuid) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(1, svcs + num_svcs); + ble_gatt_disc_s_test_misc_rx_uuid_rsp_once(1, BLE_L2CAP_CID_ATT, svcs + num_svcs); /* Ensure no follow-up request got sent. It should not have gotten sent * due to mbuf exhaustion. @@ -545,7 +545,7 @@ TEST_CASE_SELF(ble_gatt_disc_s_test_oom_uuid) os_time_advance(ticks_until); ble_gattc_timer(); - ble_hs_test_util_rx_att_err_rsp(1, + ble_hs_test_util_rx_att_err_rsp(1, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_GROUP_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, 1); @@ -579,7 +579,7 @@ TEST_CASE_SELF(ble_gatt_disc_s_test_oom_timeout) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_disc_s_test_misc_rx_all_rsp_once(1, svcs); + ble_gatt_disc_s_test_misc_rx_all_rsp_once(1, BLE_L2CAP_CID_ATT, svcs); /* Keep trying to resume for 30 seconds, but never free any mbufs. Verify * procedure eventually times out. diff --git a/nimble/host/test/src/ble_gatt_find_s_test.c b/nimble/host/test/src/ble_gatt_find_s_test.c index 172bdd3321..5f8075c9a8 100644 --- a/nimble/host/test/src/ble_gatt_find_s_test.c +++ b/nimble/host/test/src/ble_gatt_find_s_test.c @@ -90,8 +90,8 @@ ble_gatt_find_s_test_misc_verify_incs( } static int -ble_gatt_find_s_test_misc_rx_read_type( - uint16_t conn_handle, struct ble_gatt_find_s_test_entry *entries) +ble_gatt_find_s_test_misc_rx_read_type(uint16_t conn_handle, uint16_t cid, + struct ble_gatt_find_s_test_entry *entries) { struct ble_att_read_type_rsp rsp; uint8_t buf[1024]; @@ -134,14 +134,15 @@ ble_gatt_find_s_test_misc_rx_read_type( } if (i == 0) { - ble_hs_test_util_rx_att_err_rsp(conn_handle, BLE_ATT_OP_READ_TYPE_REQ, + ble_hs_test_util_rx_att_err_rsp(conn_handle, cid, + BLE_ATT_OP_READ_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, 0); return 0; } ble_att_read_type_rsp_write(buf + 0, BLE_ATT_READ_TYPE_RSP_BASE_SZ, &rsp); - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, off); TEST_ASSERT(rc == 0); @@ -149,7 +150,7 @@ ble_gatt_find_s_test_misc_rx_read_type( } static void -ble_gatt_find_s_test_misc_rx_read(uint16_t conn_handle, const ble_uuid_t *uuid) +ble_gatt_find_s_test_misc_rx_read(uint16_t conn_handle, uint16_t cid, const ble_uuid_t *uuid) { uint8_t buf[17]; int rc; @@ -159,7 +160,7 @@ ble_gatt_find_s_test_misc_rx_read(uint16_t conn_handle, const ble_uuid_t *uuid) buf[0] = BLE_ATT_OP_READ_RSP; ble_uuid_flat(uuid, buf + 1); - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, 17); TEST_ASSERT(rc == 0); } @@ -200,7 +201,7 @@ ble_gatt_find_s_test_misc_verify_tx_read(uint16_t handle) } static void -ble_gatt_find_s_test_misc_find_inc(uint16_t conn_handle, +ble_gatt_find_s_test_misc_find_inc(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, struct ble_gatt_find_s_test_entry *entries) { @@ -219,7 +220,7 @@ ble_gatt_find_s_test_misc_find_inc(uint16_t conn_handle, idx = 0; while (1) { ble_gatt_find_s_test_misc_verify_tx_read_type(cur_start, end_handle); - num_found = ble_gatt_find_s_test_misc_rx_read_type(conn_handle, + num_found = ble_gatt_find_s_test_misc_rx_read_type(conn_handle, cid, entries + idx); if (num_found == 0) { break; @@ -229,7 +230,7 @@ ble_gatt_find_s_test_misc_find_inc(uint16_t conn_handle, TEST_ASSERT(num_found == 1); ble_gatt_find_s_test_misc_verify_tx_read( entries[idx].start_handle); - ble_gatt_find_s_test_misc_rx_read(conn_handle, + ble_gatt_find_s_test_misc_rx_read(conn_handle, cid, entries[idx].uuid); } @@ -255,7 +256,7 @@ TEST_CASE_SELF(ble_gatt_find_s_test_1) ble_gatt_find_s_test_misc_init(); ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), NULL, NULL); - ble_gatt_find_s_test_misc_find_inc(2, 5, 10, + ble_gatt_find_s_test_misc_find_inc(2, BLE_L2CAP_CID_ATT, 5, 10, ((struct ble_gatt_find_s_test_entry[]) { { .inc_handle = 6, .start_handle = 35, @@ -275,7 +276,7 @@ TEST_CASE_SELF(ble_gatt_find_s_test_1) ble_gatt_find_s_test_misc_init(); ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), NULL, NULL); - ble_gatt_find_s_test_misc_find_inc(2, 34, 100, + ble_gatt_find_s_test_misc_find_inc(2, BLE_L2CAP_CID_ATT, 34, 100, ((struct ble_gatt_find_s_test_entry[]) { { .inc_handle = 36, .start_handle = 403, @@ -290,7 +291,7 @@ TEST_CASE_SELF(ble_gatt_find_s_test_1) ble_gatt_find_s_test_misc_init(); ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), NULL, NULL); - ble_gatt_find_s_test_misc_find_inc(2, 34, 100, + ble_gatt_find_s_test_misc_find_inc(2, BLE_L2CAP_CID_ATT, 34, 100, ((struct ble_gatt_find_s_test_entry[]) { { .inc_handle = 36, .start_handle = 403, @@ -310,7 +311,7 @@ TEST_CASE_SELF(ble_gatt_find_s_test_1) ble_gatt_find_s_test_misc_init(); ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), NULL, NULL); - ble_gatt_find_s_test_misc_find_inc(2, 1, 100, + ble_gatt_find_s_test_misc_find_inc(2, BLE_L2CAP_CID_ATT, 1, 100, ((struct ble_gatt_find_s_test_entry[]) { { .inc_handle = 36, .start_handle = 403, @@ -379,7 +380,7 @@ TEST_CASE_SELF(ble_gatt_find_s_test_oom) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_find_s_test_misc_rx_read_type(1, incs); + ble_gatt_find_s_test_misc_rx_read_type(1, BLE_L2CAP_CID_ATT, incs); /* Ensure no follow-up request got sent. It should not have gotten sent * due to mbuf exhaustion. @@ -402,11 +403,11 @@ TEST_CASE_SELF(ble_gatt_find_s_test_oom) * follow-up request, so there is always an mbuf available. */ /* XXX: Find a way to test this. */ - ble_gatt_find_s_test_misc_rx_read(1, incs[0].uuid); + ble_gatt_find_s_test_misc_rx_read(1, BLE_L2CAP_CID_ATT, incs[0].uuid); /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_find_s_test_misc_rx_read_type(1, incs + 1); + ble_gatt_find_s_test_misc_rx_read_type(1, BLE_L2CAP_CID_ATT, incs + 1); /* Verify the procedure succeeds after mbufs become available. */ rc = os_mbuf_free_chain(oms); @@ -414,9 +415,9 @@ TEST_CASE_SELF(ble_gatt_find_s_test_oom) os_time_advance(ticks_until); ble_gattc_timer(); - ble_gatt_find_s_test_misc_rx_read(1, incs[1].uuid); + ble_gatt_find_s_test_misc_rx_read(1, BLE_L2CAP_CID_ATT, incs[1].uuid); - ble_hs_test_util_rx_att_err_rsp(1, + ble_hs_test_util_rx_att_err_rsp(1, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, 1); diff --git a/nimble/host/test/src/ble_gatt_read_test.c b/nimble/host/test/src/ble_gatt_read_test.c index 572b0bf1c6..a22e5a559f 100644 --- a/nimble/host/test/src/ble_gatt_read_test.c +++ b/nimble/host/test/src/ble_gatt_read_test.c @@ -160,7 +160,7 @@ ble_gatt_read_test_long_cb(uint16_t conn_handle, } static void -ble_gatt_read_test_misc_rx_rsp_good_raw(uint16_t conn_handle, +ble_gatt_read_test_misc_rx_rsp_good_raw(uint16_t conn_handle, uint16_t cid, uint8_t att_op, const void *data, int data_len) { @@ -174,27 +174,28 @@ ble_gatt_read_test_misc_rx_rsp_good_raw(uint16_t conn_handle, buf[0] = att_op; memcpy(buf + 1, data, data_len); - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, 1 + data_len); TEST_ASSERT(rc == 0); } static void -ble_gatt_read_test_misc_rx_rsp_good(uint16_t conn_handle, +ble_gatt_read_test_misc_rx_rsp_good(uint16_t conn_handle, uint16_t cid, struct ble_hs_test_util_flat_attr *attr) { - ble_gatt_read_test_misc_rx_rsp_good_raw(conn_handle, BLE_ATT_OP_READ_RSP, + ble_gatt_read_test_misc_rx_rsp_good_raw(conn_handle, cid, + BLE_ATT_OP_READ_RSP, attr->value, attr->value_len); } static void -ble_gatt_read_test_misc_rx_rsp_bad(uint16_t conn_handle, +ble_gatt_read_test_misc_rx_rsp_bad(uint16_t conn_handle, uint16_t cid, uint8_t att_error, uint16_t err_handle) { /* Send the pending ATT Read Request. */ - ble_hs_test_util_rx_att_err_rsp(conn_handle, BLE_ATT_OP_READ_REQ, + ble_hs_test_util_rx_att_err_rsp(conn_handle, cid, BLE_ATT_OP_READ_REQ, att_error, err_handle); } @@ -255,7 +256,7 @@ ble_gatt_read_test_misc_verify_good(struct ble_hs_test_util_flat_attr *attr) rc = ble_gattc_read(2, attr->handle, ble_gatt_read_test_cb, NULL); TEST_ASSERT_FATAL(rc == 0); - ble_gatt_read_test_misc_rx_rsp_good(2, attr); + ble_gatt_read_test_misc_rx_rsp_good(2, BLE_L2CAP_CID_ATT, attr); TEST_ASSERT(ble_gatt_read_test_num_attrs == 1); TEST_ASSERT(ble_gatt_read_test_attrs[0].conn_handle == 2); @@ -278,7 +279,7 @@ ble_gatt_read_test_misc_verify_bad(uint8_t att_status, rc = ble_gattc_read(2, attr->handle, ble_gatt_read_test_cb, NULL); TEST_ASSERT_FATAL(rc == 0); - ble_gatt_read_test_misc_rx_rsp_bad(2, att_status, attr->handle); + ble_gatt_read_test_misc_rx_rsp_bad(2, BLE_L2CAP_CID_ATT, att_status, attr->handle); TEST_ASSERT(ble_gatt_read_test_num_attrs == 0); TEST_ASSERT(ble_gatt_read_test_bad_conn_handle == 2); @@ -309,7 +310,8 @@ ble_gatt_read_test_misc_uuid_verify_good( while (1) { num_read = ble_gatt_read_test_misc_uuid_rx_rsp_good(2, attrs + idx); if (num_read == 0) { - ble_hs_test_util_rx_att_err_rsp(2, BLE_ATT_OP_READ_TYPE_REQ, + ble_hs_test_util_rx_att_err_rsp(2, BLE_L2CAP_CID_ATT, + BLE_ATT_OP_READ_TYPE_REQ, BLE_ATT_ERR_ATTR_NOT_FOUND, start_handle); break; @@ -369,7 +371,7 @@ ble_gatt_read_test_misc_long_verify_good( } else { att_op = BLE_ATT_OP_READ_BLOB_RSP; } - ble_gatt_read_test_misc_rx_rsp_good_raw(2, att_op, + ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_L2CAP_CID_ATT, att_op, attr->value + off, chunk_sz); rem_len -= chunk_sz; off += chunk_sz; @@ -401,7 +403,7 @@ ble_gatt_read_test_misc_long_verify_bad( ble_gatt_read_test_long_cb, NULL); TEST_ASSERT_FATAL(rc == 0); - ble_gatt_read_test_misc_rx_rsp_bad(2, att_status, attr->handle); + ble_gatt_read_test_misc_rx_rsp_bad(2, BLE_L2CAP_CID_ATT, att_status, attr->handle); TEST_ASSERT(ble_gatt_read_test_num_attrs == 0); TEST_ASSERT(ble_gatt_read_test_bad_conn_handle == 2); @@ -458,7 +460,7 @@ ble_gatt_read_test_misc_mult_verify_good( ble_gatt_read_test_cb, NULL); TEST_ASSERT_FATAL(rc == 0); - ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_ATT_OP_READ_MULT_RSP, + ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_MULT_RSP, expected_value, off); TEST_ASSERT(ble_gatt_read_test_complete); @@ -488,7 +490,7 @@ ble_gatt_read_test_misc_mult_verify_bad( ble_gatt_read_test_cb, NULL); TEST_ASSERT_FATAL(rc == 0); - ble_gatt_read_test_misc_rx_rsp_bad(2, att_status, err_handle); + ble_gatt_read_test_misc_rx_rsp_bad(2, BLE_L2CAP_CID_ATT, att_status, err_handle); TEST_ASSERT(ble_gatt_read_test_num_attrs == 0); TEST_ASSERT(ble_gatt_read_test_bad_conn_handle == 2); @@ -801,9 +803,9 @@ TEST_CASE_SELF(ble_gatt_read_test_concurrent) rc = ble_gattc_read(2, attrs[2].handle, ble_gatt_read_test_cb, NULL); TEST_ASSERT_FATAL(rc == 0); - ble_gatt_read_test_misc_rx_rsp_good(2, attrs + 0); - ble_gatt_read_test_misc_rx_rsp_good(2, attrs + 1); - ble_gatt_read_test_misc_rx_rsp_good(2, attrs + 2); + ble_gatt_read_test_misc_rx_rsp_good(2, BLE_L2CAP_CID_ATT, attrs + 0); + ble_gatt_read_test_misc_rx_rsp_good(2, BLE_L2CAP_CID_ATT, attrs + 1); + ble_gatt_read_test_misc_rx_rsp_good(2, BLE_L2CAP_CID_ATT, attrs + 2); TEST_ASSERT(ble_gatt_read_test_num_attrs == 3); @@ -852,8 +854,8 @@ TEST_CASE_SELF(ble_gatt_read_test_long_oom) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - chunk_sz = ble_att_mtu(2) - BLE_ATT_READ_RSP_BASE_SZ; - ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_ATT_OP_READ_RSP, + chunk_sz = ble_att_mtu_by_cid(2, BLE_L2CAP_CID_ATT) - BLE_ATT_READ_RSP_BASE_SZ; + ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_RSP, attr.value + off, chunk_sz); off += chunk_sz; @@ -875,8 +877,8 @@ TEST_CASE_SELF(ble_gatt_read_test_long_oom) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - chunk_sz = ble_att_mtu(2) - BLE_ATT_READ_RSP_BASE_SZ; - ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_ATT_OP_READ_RSP, + chunk_sz = ble_att_mtu_by_cid(2, BLE_L2CAP_CID_ATT) - BLE_ATT_READ_RSP_BASE_SZ; + ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_RSP, attr.value + off, chunk_sz); off += chunk_sz; @@ -897,7 +899,7 @@ TEST_CASE_SELF(ble_gatt_read_test_long_oom) ble_gattc_timer(); chunk_sz = attr.value_len - off; - ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_ATT_OP_READ_RSP, + ble_gatt_read_test_misc_rx_rsp_good_raw(2, BLE_L2CAP_CID_ATT, BLE_ATT_OP_READ_RSP, attr.value + off, chunk_sz); off += chunk_sz; diff --git a/nimble/host/test/src/ble_gatt_write_test.c b/nimble/host/test/src/ble_gatt_write_test.c index caa8e56571..ea815c0d5c 100644 --- a/nimble/host/test/src/ble_gatt_write_test.c +++ b/nimble/host/test/src/ble_gatt_write_test.c @@ -87,8 +87,8 @@ ble_gatt_write_test_rx_rsp(uint16_t conn_handle) } static void -ble_gatt_write_test_rx_prep_rsp(uint16_t conn_handle, uint16_t attr_handle, - uint16_t offset, +ble_gatt_write_test_rx_prep_rsp(uint16_t conn_handle, uint16_t cid, + uint16_t attr_handle, uint16_t offset, const void *attr_data, uint16_t attr_data_len) { struct ble_att_prep_write_cmd rsp; @@ -102,19 +102,19 @@ ble_gatt_write_test_rx_prep_rsp(uint16_t conn_handle, uint16_t attr_handle, memcpy(buf + BLE_ATT_PREP_WRITE_CMD_BASE_SZ, attr_data, attr_data_len); rc = ble_hs_test_util_l2cap_rx_payload_flat( - conn_handle, BLE_L2CAP_CID_ATT, buf, + conn_handle, cid, buf, BLE_ATT_PREP_WRITE_CMD_BASE_SZ + attr_data_len); TEST_ASSERT(rc == 0); } static void -ble_gatt_write_test_rx_exec_rsp(uint16_t conn_handle) +ble_gatt_write_test_rx_exec_rsp(uint16_t conn_handle, uint16_t cid) { uint8_t op; int rc; op = BLE_ATT_OP_EXEC_WRITE_RSP; - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, &op, 1); TEST_ASSERT(rc == 0); } @@ -129,10 +129,10 @@ ble_gatt_write_test_misc_long_good(int attr_len) ble_gatt_write_test_init(); - ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), + ble_hs_test_util_create_conn(2, ((uint8_t[]) {2,3,4,5,6,7,8,9}), NULL, NULL); - mtu = ble_att_mtu(2); + mtu = ble_att_mtu_by_cid(2, BLE_L2CAP_CID_ATT); rc = ble_hs_test_util_gatt_write_long_flat( 2, 100, ble_gatt_write_test_attr_value, attr_len, @@ -152,7 +152,7 @@ ble_gatt_write_test_misc_long_good(int attr_len) /* Receive Prep Write response. */ ble_gatt_write_test_rx_prep_rsp( - 2, 100, off, ble_gatt_write_test_attr_value + off, len); + 2, BLE_L2CAP_CID_ATT, 100, off, ble_gatt_write_test_attr_value + off, len); /* Verify callback hasn't gotten called. */ TEST_ASSERT(!ble_gatt_write_test_cb_called); @@ -164,13 +164,13 @@ ble_gatt_write_test_misc_long_good(int attr_len) ble_hs_test_util_verify_tx_exec_write(BLE_ATT_EXEC_WRITE_F_EXECUTE); /* Receive Exec Write response. */ - ble_gatt_write_test_rx_exec_rsp(2); + ble_gatt_write_test_rx_exec_rsp(2, BLE_L2CAP_CID_ATT); /* Verify callback got called. */ TEST_ASSERT(ble_gatt_write_test_cb_called); } -typedef void ble_gatt_write_test_long_fail_fn(uint16_t conn_handle, +typedef void ble_gatt_write_test_long_fail_fn(uint16_t conn_handle, uint16_t cid, int off, int len); static void @@ -185,9 +185,9 @@ ble_gatt_write_test_misc_long_bad(int attr_len, ble_gatt_write_test_init(); - ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), + ble_hs_test_util_create_conn(2, ((uint8_t[]) {2,3,4,5,6,7,8,9}), NULL, NULL); - mtu = ble_att_mtu(2); + mtu = ble_att_mtu_by_cid(2, BLE_L2CAP_CID_ATT); rc = ble_hs_test_util_gatt_write_long_flat( 2, 100, ble_gatt_write_test_attr_value, attr_len, @@ -214,9 +214,9 @@ ble_gatt_write_test_misc_long_bad(int attr_len, } if (!fail_now) { ble_gatt_write_test_rx_prep_rsp( - 2, 100, off, ble_gatt_write_test_attr_value + off, len); + 2, BLE_L2CAP_CID_ATT, 100, off, ble_gatt_write_test_attr_value + off, len); } else { - cb(2, off, len); + cb(2, BLE_L2CAP_CID_ATT, off, len); break; } @@ -233,38 +233,38 @@ ble_gatt_write_test_misc_long_bad(int attr_len, } static void -ble_gatt_write_test_misc_long_fail_handle(uint16_t conn_handle, +ble_gatt_write_test_misc_long_fail_handle(uint16_t conn_handle, uint16_t cid, int off, int len) { ble_gatt_write_test_rx_prep_rsp( - conn_handle, 99, off, ble_gatt_write_test_attr_value + off, + conn_handle, cid, 99, off, ble_gatt_write_test_attr_value + off, len); } static void -ble_gatt_write_test_misc_long_fail_offset(uint16_t conn_handle, +ble_gatt_write_test_misc_long_fail_offset(uint16_t conn_handle, uint16_t cid, int off, int len) { ble_gatt_write_test_rx_prep_rsp( - conn_handle, 100, off + 1, ble_gatt_write_test_attr_value + off, + conn_handle, cid, 100, off + 1, ble_gatt_write_test_attr_value + off, len); } static void -ble_gatt_write_test_misc_long_fail_value(uint16_t conn_handle, +ble_gatt_write_test_misc_long_fail_value(uint16_t conn_handle, uint16_t cid, int off, int len) { ble_gatt_write_test_rx_prep_rsp( - conn_handle, 100, off, ble_gatt_write_test_attr_value + off + 1, + conn_handle, cid, 100, off, ble_gatt_write_test_attr_value + off + 1, len); } static void -ble_gatt_write_test_misc_long_fail_length(uint16_t conn_handle, +ble_gatt_write_test_misc_long_fail_length(uint16_t conn_handle, uint16_t cid, int off, int len) { ble_gatt_write_test_rx_prep_rsp( - conn_handle, 100, off, ble_gatt_write_test_attr_value + off, + conn_handle, cid, 100, off, ble_gatt_write_test_attr_value + off, len - 1); } @@ -313,9 +313,9 @@ ble_gatt_write_test_misc_reliable_good( flat_attrs + num_attrs); } - ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), + ble_hs_test_util_create_conn(2, ((uint8_t[]) {2,3,4,5,6,7,8,9}), NULL, NULL); - mtu = ble_att_mtu(2); + mtu = ble_att_mtu_by_cid(2, BLE_L2CAP_CID_ATT); rc = ble_gattc_write_reliable(2, attrs, num_attrs, ble_gatt_write_test_reliable_cb_good, NULL); @@ -336,7 +336,7 @@ ble_gatt_write_test_misc_reliable_good( attr->value + off, len); /* Receive Prep Write response. */ - ble_gatt_write_test_rx_prep_rsp(2, attr->handle, off, + ble_gatt_write_test_rx_prep_rsp(2, BLE_L2CAP_CID_ATT, attr->handle, off, attr->value + off, len); /* Verify callback hasn't gotten called. */ @@ -353,7 +353,7 @@ ble_gatt_write_test_misc_reliable_good( ble_hs_test_util_verify_tx_exec_write(BLE_ATT_EXEC_WRITE_F_EXECUTE); /* Receive Exec Write response. */ - ble_gatt_write_test_rx_exec_rsp(2); + ble_gatt_write_test_rx_exec_rsp(2, BLE_L2CAP_CID_ATT); /* Verify callback got called. */ TEST_ASSERT(ble_gatt_write_test_cb_called); @@ -599,7 +599,7 @@ TEST_CASE_SELF(ble_gatt_write_test_long_queue_full) /* Receive Prep Write response. */ len = BLE_ATT_MTU_DFLT - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; ble_gatt_write_test_rx_prep_rsp( - 2, 100, off, ble_gatt_write_test_attr_value + off, len); + 2, BLE_L2CAP_CID_ATT, 100, off, ble_gatt_write_test_attr_value + off, len); /* Verify callback hasn't gotten called. */ TEST_ASSERT(!ble_gatt_write_test_cb_called); @@ -611,7 +611,8 @@ TEST_CASE_SELF(ble_gatt_write_test_long_queue_full) TEST_ASSERT(ble_hs_test_util_prev_tx_dequeue() != NULL); /* Receive queue full error. */ - ble_hs_test_util_rx_att_err_rsp(2, BLE_ATT_OP_PREP_WRITE_REQ, + ble_hs_test_util_rx_att_err_rsp(2, BLE_L2CAP_CID_ATT, + BLE_ATT_OP_PREP_WRITE_REQ, BLE_ATT_ERR_PREPARE_QUEUE_FULL, 100); /* Verify callback was called. */ @@ -654,14 +655,14 @@ TEST_CASE_SELF(ble_gatt_write_test_long_oom) ble_gatt_write_test_cb_good, NULL); TEST_ASSERT_FATAL(rc == 0); - chunk_sz = ble_att_mtu(2) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; + chunk_sz = ble_att_mtu_by_cid(2, BLE_L2CAP_CID_ATT) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; ble_hs_test_util_verify_tx_prep_write(attr.handle, off, attr.value + off, chunk_sz); /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_write_test_rx_prep_rsp(2, attr.handle, off, attr.value + off, + ble_gatt_write_test_rx_prep_rsp(2, BLE_L2CAP_CID_ATT, attr.handle, off, attr.value + off, chunk_sz); off += chunk_sz; @@ -688,7 +689,7 @@ TEST_CASE_SELF(ble_gatt_write_test_long_oom) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); ble_gatt_write_test_rx_prep_rsp( - 2, attr.handle, off, attr.value + off, chunk_sz); + 2, BLE_L2CAP_CID_ATT, attr.handle, off, attr.value + off, chunk_sz); off += chunk_sz; /* Ensure no follow-up request got sent. It should not have gotten sent @@ -711,7 +712,7 @@ TEST_CASE_SELF(ble_gatt_write_test_long_oom) ble_hs_test_util_verify_tx_exec_write(BLE_ATT_EXEC_WRITE_F_EXECUTE); /* Receive Exec Write response. */ - ble_gatt_write_test_rx_exec_rsp(2); + ble_gatt_write_test_rx_exec_rsp(2, BLE_L2CAP_CID_ATT); /* Verify callback got called. */ TEST_ASSERT(ble_gatt_write_test_cb_called); @@ -750,14 +751,14 @@ TEST_CASE_SELF(ble_gatt_write_test_reliable_oom) ble_gatt_write_test_reliable_cb_good, NULL); TEST_ASSERT_FATAL(rc == 0); - chunk_sz = ble_att_mtu(2) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; + chunk_sz = ble_att_mtu_by_cid(2, BLE_L2CAP_CID_ATT) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ; ble_hs_test_util_verify_tx_prep_write(attr.handle, off, attr.value + off, chunk_sz); /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); - ble_gatt_write_test_rx_prep_rsp(2, attr.handle, off, attr.value + off, + ble_gatt_write_test_rx_prep_rsp(2, BLE_L2CAP_CID_ATT, attr.handle, off, attr.value + off, chunk_sz); off += chunk_sz; @@ -784,7 +785,7 @@ TEST_CASE_SELF(ble_gatt_write_test_reliable_oom) /* Exhaust the msys pool. Leave one mbuf for the forthcoming response. */ oms = ble_hs_test_util_mbuf_alloc_all_but(1); ble_gatt_write_test_rx_prep_rsp( - 2, attr.handle, off, attr.value + off, chunk_sz); + 2, BLE_L2CAP_CID_ATT, attr.handle, off, attr.value + off, chunk_sz); off += chunk_sz; /* Ensure no follow-up request got sent. It should not have gotten sent @@ -807,7 +808,7 @@ TEST_CASE_SELF(ble_gatt_write_test_reliable_oom) ble_hs_test_util_verify_tx_exec_write(BLE_ATT_EXEC_WRITE_F_EXECUTE); /* Receive Exec Write response. */ - ble_gatt_write_test_rx_exec_rsp(2); + ble_gatt_write_test_rx_exec_rsp(2, BLE_L2CAP_CID_ATT); /* Verify callback got called. */ TEST_ASSERT(ble_gatt_write_test_cb_called); diff --git a/nimble/host/test/src/ble_hs_test_util.c b/nimble/host/test/src/ble_hs_test_util.c index c336ddf923..f5463b3ea4 100644 --- a/nimble/host/test/src/ble_hs_test_util.c +++ b/nimble/host/test/src/ble_hs_test_util.c @@ -741,7 +741,7 @@ ble_hs_test_util_set_att_mtu(uint16_t conn_handle, uint16_t mtu) ble_hs_lock(); - rc = ble_att_conn_chan_find(conn_handle, &conn, &chan); + rc = ble_att_conn_chan_find(conn_handle, BLE_L2CAP_CID_ATT, &conn, &chan); assert(rc == 0); chan->my_mtu = mtu; chan->peer_mtu = mtu; @@ -772,6 +772,7 @@ ble_hs_test_util_rx_att_mtu_cmd(uint16_t conn_handle, int is_req, uint16_t mtu) int ble_hs_test_util_rx_att_find_info_req(uint16_t conn_handle, + uint16_t cid, uint16_t start_handle, uint16_t end_handle) { @@ -784,7 +785,7 @@ ble_hs_test_util_rx_att_find_info_req(uint16_t conn_handle, ble_att_find_info_req_write(buf, sizeof buf, &req); - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, sizeof buf); return rc; @@ -1070,7 +1071,7 @@ ble_hs_test_util_rx_att_indicate_req(uint16_t conn_handle, } void -ble_hs_test_util_rx_att_err_rsp(uint16_t conn_handle, uint8_t req_op, +ble_hs_test_util_rx_att_err_rsp(uint16_t conn_handle, uint16_t cid, uint8_t req_op, uint8_t error_code, uint16_t err_handle) { struct ble_att_error_rsp rsp; @@ -1083,7 +1084,7 @@ ble_hs_test_util_rx_att_err_rsp(uint16_t conn_handle, uint8_t req_op, ble_att_error_rsp_write(buf, sizeof buf, &rsp); - rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT, + rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, cid, buf, sizeof buf); TEST_ASSERT(rc == 0); } diff --git a/nimble/host/test/src/ble_hs_test_util.h b/nimble/host/test/src/ble_hs_test_util.h index 7a0aa3eb19..6d5d04c05d 100644 --- a/nimble/host/test/src/ble_hs_test_util.h +++ b/nimble/host/test/src/ble_hs_test_util.h @@ -173,6 +173,7 @@ void ble_hs_test_util_set_att_mtu(uint16_t conn_handle, uint16_t mtu); int ble_hs_test_util_rx_att_mtu_cmd(uint16_t conn_handle, int is_req, uint16_t mtu); int ble_hs_test_util_rx_att_find_info_req(uint16_t conn_handle, + uint16_t cid, uint16_t start_handle, uint16_t end_handle); int ble_hs_test_util_rx_att_find_type_value_req(uint16_t conn_handle, @@ -228,8 +229,9 @@ int ble_hs_test_util_rx_att_indicate_req(uint16_t conn_handle, uint16_t attr_handle, void *attr_val, uint16_t attr_len); -void ble_hs_test_util_rx_att_err_rsp(uint16_t conn_handle, uint8_t req_op, - uint8_t error_code, uint16_t err_handle); +void ble_hs_test_util_rx_att_err_rsp(uint16_t conn_handle, uint16_t cid, + uint8_t req_op, uint8_t error_code, + uint16_t err_handle); void ble_hs_test_util_verify_tx_prep_write(uint16_t attr_handle, uint16_t offset, const void *data, int data_len); From 133cafdac2d371df905149ca2fa1a8203d5cfa0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Tue, 28 Jan 2020 11:13:17 +0100 Subject: [PATCH 0791/1333] nimble/host: Initial EATT support The idea for EATT in Mynewt is as follow. EATT is not exposed to the user i.e. GATT API stays the same. User can define number of EATT channels supported by the host and it is host managing those channels. EATT will be fist choice channel for every ATT operation. In the future we can make it smarted and make a choice based on the ATT data in the packet TODO: * handle reading and setting client/server Supported features in the stack instead of eatt code * add test API to choose channel to use (needed by PTS) --- nimble/host/pkg.yml | 3 + .../gatt/include/services/gatt/ble_svc_gatt.h | 5 +- nimble/host/services/gatt/src/ble_svc_gatt.c | 90 ++- nimble/host/src/ble_att.c | 52 +- nimble/host/src/ble_att_clt.c | 3 +- nimble/host/src/ble_att_cmd.c | 9 + nimble/host/src/ble_att_svr.c | 29 +- nimble/host/src/ble_eatt.c | 552 ++++++++++++++++++ nimble/host/src/ble_eatt_priv.h | 64 ++ nimble/host/src/ble_gattc.c | 13 +- nimble/host/src/ble_hs_priv.h | 1 + nimble/host/syscfg.yml | 21 + nimble/host/test/syscfg.yml | 1 + .../examples/linux/include/logcfg/logcfg.h | 7 + .../examples/linux/include/syscfg/syscfg.h | 16 + .../linux_blemesh/include/logcfg/logcfg.h | 7 + .../linux_blemesh/include/syscfg/syscfg.h | 16 + porting/nimble/include/logcfg/logcfg.h | 7 + porting/nimble/include/syscfg/syscfg.h | 16 + porting/npl/riot/include/logcfg/logcfg.h | 7 + porting/npl/riot/include/syscfg/syscfg.h | 16 + 21 files changed, 888 insertions(+), 47 deletions(-) create mode 100644 nimble/host/src/ble_eatt.c create mode 100644 nimble/host/src/ble_eatt_priv.h diff --git a/nimble/host/pkg.yml b/nimble/host/pkg.yml index c069283cf0..cab496caed 100644 --- a/nimble/host/pkg.yml +++ b/nimble/host/pkg.yml @@ -41,6 +41,9 @@ pkg.deps.BLE_SM_SC: pkg.deps.BLE_MESH: - nimble/host/mesh +pkg.deps.BLE_EATT_CHAN_NUM: + - nimble/host/services/gatt + pkg.req_apis: - ble_transport - console diff --git a/nimble/host/services/gatt/include/services/gatt/ble_svc_gatt.h b/nimble/host/services/gatt/include/services/gatt/ble_svc_gatt.h index 06c44784af..eefd412f57 100644 --- a/nimble/host/services/gatt/include/services/gatt/ble_svc_gatt.h +++ b/nimble/host/services/gatt/include/services/gatt/ble_svc_gatt.h @@ -28,8 +28,11 @@ extern "C" { struct ble_hs_cfg; -#define BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16 0x2a05 +#define BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16 0x2a05 +#define BLE_SVC_GATT_CHR_SERVER_SUPPORTED_FEAT_UUID16 0x2b3a +#define BLE_SVC_GATT_CHR_CLIENT_SUPPORTED_FEAT_UUID16 0x2b29 +uint8_t ble_svc_gatt_get_local_cl_supported_feat(void); void ble_svc_gatt_changed(uint16_t start_handle, uint16_t end_handle); void ble_svc_gatt_init(void); diff --git a/nimble/host/services/gatt/src/ble_svc_gatt.c b/nimble/host/services/gatt/src/ble_svc_gatt.c index 78b4a0683c..961c23fc57 100644 --- a/nimble/host/services/gatt/src/ble_svc_gatt.c +++ b/nimble/host/services/gatt/src/ble_svc_gatt.c @@ -27,23 +27,55 @@ static uint16_t ble_svc_gatt_changed_val_handle; static uint16_t ble_svc_gatt_start_handle; static uint16_t ble_svc_gatt_end_handle; +/* Server supported features */ +#define BLE_SVC_GATT_SRV_SUP_FEAT_EATT_BIT (0x00) + +/* Client supported features */ +#define BLE_SVC_GATT_CLI_SUP_FEAT_ROBUST_CATCHING_BIT (0x00) +#define BLE_SVC_GATT_CLI_SUP_FEAT_EATT_BIT (0x01) +#define BLE_SVC_GATT_CLI_SUP_FEAT_MULT_NTF_BIT (0x02) + +static uint8_t ble_svc_gatt_srv_sup_feat = 0; +static uint8_t ble_svc_gatt_cl_sup_feat = 0; + static int ble_svc_gatt_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); +static int +ble_svc_gatt_srv_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); + +static int +ble_svc_gatt_cl_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); + static const struct ble_gatt_svc_def ble_svc_gatt_defs[] = { { /*** Service: GATT */ .type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = BLE_UUID16_DECLARE(BLE_GATT_SVC_UUID16), - .characteristics = (struct ble_gatt_chr_def[]) { { - .uuid = BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16), - .access_cb = ble_svc_gatt_access, - .val_handle = &ble_svc_gatt_changed_val_handle, - .flags = BLE_GATT_CHR_F_INDICATE, - }, { - 0, /* No more characteristics in this service. */ - } }, + .characteristics = (struct ble_gatt_chr_def[]) { + { + .uuid = BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16), + .access_cb = ble_svc_gatt_access, + .val_handle = &ble_svc_gatt_changed_val_handle, + .flags = BLE_GATT_CHR_F_INDICATE, + }, + { + .uuid = BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_SERVER_SUPPORTED_FEAT_UUID16), + .access_cb = ble_svc_gatt_srv_sup_feat_access, + .flags = BLE_GATT_CHR_F_READ, + }, + { + .uuid = BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_CLIENT_SUPPORTED_FEAT_UUID16), + .access_cb = ble_svc_gatt_cl_sup_feat_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE, + }, + { + 0, /* No more characteristics in this service. */ + } + }, }, { @@ -51,6 +83,34 @@ static const struct ble_gatt_svc_def ble_svc_gatt_defs[] = { }, }; +static int +ble_svc_gatt_srv_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + if (ctxt->op != BLE_GATT_ACCESS_OP_READ_CHR) { + return BLE_ATT_ERR_WRITE_NOT_PERMITTED; + } + + os_mbuf_append(ctxt->om, &ble_svc_gatt_srv_sup_feat, sizeof(ble_svc_gatt_srv_sup_feat)); + + return 0; +} + +static int +ble_svc_gatt_cl_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + /* TODO For now just send 1*/ + uint8_t eatt_supported = 2; + os_mbuf_append(ctxt->om, &eatt_supported, sizeof(eatt_supported)); + return 0; + } + /* TODO For write just return OK */ + + return 0; +} + static int ble_svc_gatt_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) @@ -77,6 +137,12 @@ ble_svc_gatt_access(uint16_t conn_handle, uint16_t attr_handle, return 0; } +uint8_t +ble_svc_gatt_get_local_cl_supported_feat(void) +{ + return ble_svc_gatt_cl_sup_feat; +} + /** * Indicates a change in attribute assignment to all subscribed peers. * Unconnected bonded peers receive an indication when they next connect. @@ -105,4 +171,12 @@ ble_svc_gatt_init(void) rc = ble_gatts_add_svcs(ble_svc_gatt_defs); SYSINIT_PANIC_ASSERT(rc == 0); + + if (MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0) { + ble_svc_gatt_srv_sup_feat |= (1 << BLE_SVC_GATT_SRV_SUP_FEAT_EATT_BIT); + } + + if (MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0) { + ble_svc_gatt_cl_sup_feat |= (1 << BLE_SVC_GATT_CLI_SUP_FEAT_EATT_BIT); + } } diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index 9d58bad1ca..ae5041f69f 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -498,22 +498,31 @@ ble_att_rx_handle_unknown_request(uint8_t op, uint16_t conn_handle, *om = NULL; } +static void +ble_att_send_outstanding_after_response(uint16_t conn_handle) +{ + struct ble_hs_conn *conn; + struct ble_l2cap_chan *chan; + int rc; + + ble_hs_lock(); + rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT, &conn, + &chan); + if (rc) { + return; + } + conn->client_att_busy = false; + ble_att_tx_with_conn(conn, chan, NULL); + ble_hs_unlock(); +} static int -ble_att_rx(struct ble_l2cap_chan *chan) +ble_att_rx_extended(uint16_t conn_handle, uint16_t cid, struct os_mbuf **om) { const struct ble_att_rx_dispatch_entry *entry; uint8_t op; - uint16_t conn_handle; - struct os_mbuf **om; int rc; - conn_handle = ble_l2cap_get_conn_handle(chan); - if (conn_handle == BLE_HS_CONN_HANDLE_NONE) { - return BLE_HS_ENOTCONN; - } - - om = &chan->rx_buf; BLE_HS_DBG_ASSERT(*om != NULL); rc = os_mbuf_copydata(*om, 0, 1, &op); @@ -521,9 +530,13 @@ ble_att_rx(struct ble_l2cap_chan *chan) return BLE_HS_EMSGSIZE; } + if (cid == BLE_L2CAP_CID_ATT && ble_att_is_response_op(op)) { + ble_att_send_outstanding_after_response(conn_handle); + } + entry = ble_att_rx_dispatch_entry_find(op); if (entry == NULL) { - ble_att_rx_handle_unknown_request(op, conn_handle, chan->scid, om); + ble_att_rx_handle_unknown_request(op, conn_handle, cid, om); return BLE_HS_ENOTSUP; } @@ -532,10 +545,10 @@ ble_att_rx(struct ble_l2cap_chan *chan) /* Strip L2CAP ATT header from the front of the mbuf. */ os_mbuf_adj(*om, 1); - rc = entry->bde_fn(conn_handle, chan->scid, om); + rc = entry->bde_fn(conn_handle, cid, om); if (rc != 0) { if (rc == BLE_HS_ENOTSUP) { - ble_att_rx_handle_unknown_request(op, conn_handle, chan->scid, om); + ble_att_rx_handle_unknown_request(op, conn_handle, cid, om); } return rc; } @@ -543,6 +556,19 @@ ble_att_rx(struct ble_l2cap_chan *chan) return 0; } +static int +ble_att_rx(struct ble_l2cap_chan *chan) +{ + uint16_t conn_handle; + + conn_handle = ble_l2cap_get_conn_handle(chan); + if (conn_handle == BLE_HS_CONN_HANDLE_NONE) { + return BLE_HS_ENOTCONN; + } + + return ble_att_rx_extended(conn_handle, chan->scid, &chan->rx_buf); +} + uint16_t ble_att_preferred_mtu(void) { @@ -661,6 +687,8 @@ ble_att_init(void) return BLE_HS_EOS; } + ble_eatt_init(ble_att_rx_extended); + return 0; } diff --git a/nimble/host/src/ble_att_clt.c b/nimble/host/src/ble_att_clt.c index 27478a9a6a..7fcccbb9d7 100644 --- a/nimble/host/src/ble_att_clt.c +++ b/nimble/host/src/ble_att_clt.c @@ -911,8 +911,9 @@ ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle, req->banq_handle = htole16(handle); os_mbuf_concat(txom2, txom); - cid = BLE_L2CAP_CID_ATT; + cid = ble_eatt_get_available_chan_cid(conn_handle, BLE_GATT_OP_DUMMY); return ble_att_tx(conn_handle, cid, txom2); + ble_eatt_release_chan(conn_handle, BLE_GATT_OP_DUMMY); err: os_mbuf_free_chain(txom); diff --git a/nimble/host/src/ble_att_cmd.c b/nimble/host/src/ble_att_cmd.c index ac882a9c65..34521954e9 100644 --- a/nimble/host/src/ble_att_cmd.c +++ b/nimble/host/src/ble_att_cmd.c @@ -66,16 +66,19 @@ ble_att_tx_with_conn(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, stru } omp = STAILQ_FIRST(&conn->att_tx_q); if (omp == NULL) { + BLE_EATT_LOG_ERROR("%s: wakeup but nothing in the queue\n", __func__); return 0; } STAILQ_REMOVE_HEAD(&conn->att_tx_q, omp_next); txom = OS_MBUF_PKTHDR_TO_MBUF(omp); + BLE_EATT_LOG_DEBUG("%s: wakeup will send %p\n", __func__, txom); } BLE_HS_DBG_ASSERT_EVAL(txom->om_len >= 1); if (ble_att_is_request_op(txom->om_data[0])) { if (conn->client_att_busy) { + BLE_EATT_LOG_DEBUG("ATT Queue %p, client busy %d\n", txom, conn->client_att_busy); STAILQ_INSERT_TAIL(&conn->att_tx_q, OS_MBUF_PKTHDR(txom), omp_next); return 0; } @@ -97,6 +100,12 @@ ble_att_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom) struct ble_hs_conn *conn; int rc; +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 + if (cid != BLE_L2CAP_CID_ATT) { + return ble_eatt_tx(conn_handle, cid, txom); + } +#endif + ble_hs_lock(); rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT, &conn, &chan); diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 74f910d744..7cdcd1dbbd 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -625,10 +625,7 @@ static int ble_att_svr_tx_rsp(uint16_t conn_handle, uint16_t cid, int hs_status, struct os_mbuf *om, uint8_t att_op, uint8_t err_status, uint16_t err_handle) { - struct ble_l2cap_chan *chan; - struct ble_hs_conn *conn; int do_tx; - int rc; if (hs_status != 0 && err_status == 0) { /* Processing failed, but err_status of 0 means don't send error. */ @@ -638,28 +635,14 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, uint16_t cid, int hs_status, struct os_ } if (do_tx) { - ble_hs_lock(); - - rc = ble_att_conn_chan_find(conn_handle, cid, &conn, &chan); - if (rc != 0) { - /* No longer connected. */ - hs_status = rc; - } else { - if (hs_status == 0) { - BLE_HS_DBG_ASSERT(om != NULL); - - ble_att_inc_tx_stat(om->om_data[0]); - ble_att_truncate_to_mtu(chan, om); - hs_status = ble_l2cap_tx(conn, chan, om); - om = NULL; - if (hs_status != 0) { - err_status = BLE_ATT_ERR_UNLIKELY; - } - } + if (hs_status == 0) { + hs_status = ble_att_tx(conn_handle, cid, om); + om = NULL; + if (hs_status) { + err_status = BLE_ATT_ERR_UNLIKELY; + } } - ble_hs_unlock(); - if (hs_status != 0) { STATS_INC(ble_att_stats, error_rsp_tx); diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c new file mode 100644 index 0000000000..093bcda941 --- /dev/null +++ b/nimble/host/src/ble_eatt.c @@ -0,0 +1,552 @@ +/* + * 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. + */ + +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 + +#include "os/mynewt.h" +#include "mem/mem.h" +#include "host/ble_hs_log.h" +#include "ble_att_cmd_priv.h" +#include "ble_hs_priv.h" +#include "ble_l2cap_priv.h" +#include "ble_eatt_priv.h" +#include "services/gatt/ble_svc_gatt.h" + +struct ble_eatt { + SLIST_ENTRY(ble_eatt) next; + uint16_t conn_handle; + struct ble_l2cap_chan *chan; + uint8_t client_op; + bool client_proceed; + + bool server_proceed; + /* Packet transmit queue */ + STAILQ_HEAD(, os_mbuf_pkthdr) eatt_tx_q; + + struct ble_npl_event setup_ev; + struct ble_npl_event wakeup_ev; +}; + +SLIST_HEAD(ble_eatt_list, ble_eatt); + +static struct ble_eatt_list g_ble_eatt_list; +static ble_eatt_att_rx_fn ble_eatt_att_rx_cb; + +#define BLE_EATT_DATABUF_SIZE ( \ + MYNEWT_VAL(BLE_EATT_MTU) + \ + 2 + \ + sizeof (struct os_mbuf_pkthdr) + \ + sizeof (struct os_mbuf)) + +#define BLE_EATT_MEMBLOCK_SIZE \ + (OS_ALIGN(BLE_EATT_DATABUF_SIZE, 4)) + +#define BLE_EATT_MEMPOOL_SIZE \ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_EATT_CHAN_NUM) + 1, BLE_EATT_MEMBLOCK_SIZE) +static os_membuf_t ble_eatt_conn_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_EATT_CHAN_NUM), + sizeof(struct ble_eatt)) +]; +static struct os_mempool ble_eatt_conn_pool; +static os_membuf_t ble_eatt_sdu_coc_mem[BLE_EATT_MEMPOOL_SIZE]; +struct os_mbuf_pool ble_eatt_sdu_os_mbuf_pool; +static struct os_mempool ble_eatt_sdu_mbuf_mempool; + +static struct ble_gap_event_listener ble_eatt_listener; + +static struct ble_npl_event g_read_sup_cl_feat_ev; +static struct ble_npl_event g_read_sup_srv_feat_ev; + +static void ble_eatt_setup_cb(struct ble_npl_event *ev); + +static struct ble_eatt * +ble_eatt_find_not_busy(uint16_t conn_handle) +{ + struct ble_eatt *eatt; + + SLIST_FOREACH(eatt, &g_ble_eatt_list, next) { + if ((eatt->conn_handle == conn_handle) && !eatt->client_op) { + return eatt; + } + } + return NULL; +} + +static struct ble_eatt * +ble_eatt_find_by_conn_handle(uint16_t conn_handle) +{ + struct ble_eatt *eatt; + + SLIST_FOREACH(eatt, &g_ble_eatt_list, next) { + if (eatt->conn_handle == conn_handle) { + return eatt; + } + } + return NULL; + +} + +static struct ble_eatt * +ble_eatt_find_by_conn_handle_and_busy_op(uint16_t conn_handle, uint8_t op) +{ + struct ble_eatt *eatt; + + SLIST_FOREACH(eatt, &g_ble_eatt_list, next) { + if (eatt->conn_handle == conn_handle && eatt->client_op == op) { + return eatt; + } + } + return NULL; + +} + +static struct ble_eatt * +ble_eatt_find(uint16_t conn_handle, uint16_t cid) +{ + struct ble_eatt *eatt; + + SLIST_FOREACH(eatt, &g_ble_eatt_list, next) { + if ((eatt->conn_handle == conn_handle) && + (eatt->chan) && + (eatt->chan->scid == cid)) { + return eatt; + } + } + return NULL; + +} + +static int +ble_eatt_prepare_rx_sdu(struct ble_l2cap_chan *chan) +{ + int rc; + struct os_mbuf *om; + + om = os_mbuf_get_pkthdr(&ble_eatt_sdu_os_mbuf_pool, 0); + if (!om) { + BLE_EATT_LOG_ERROR("eatt: no memory for sdu\n"); + return BLE_HS_ENOMEM; + } + + rc = ble_l2cap_recv_ready(chan, om); + return rc; +} + +static void +ble_eatt_wakeup_cb(struct ble_npl_event *ev) +{ + struct ble_eatt *eatt; + struct os_mbuf *txom; + struct os_mbuf_pkthdr *omp; + struct ble_l2cap_chan_info info; + + eatt = ble_npl_event_get_arg(ev); + assert(eatt); + + omp = STAILQ_FIRST(&eatt->eatt_tx_q); + if (omp != NULL) { + STAILQ_REMOVE_HEAD(&eatt->eatt_tx_q, omp_next); + + txom = OS_MBUF_PKTHDR_TO_MBUF(omp); + ble_l2cap_get_chan_info(eatt->chan, &info); + ble_eatt_tx(eatt->conn_handle, info.dcid, txom); + } +} + +static struct ble_eatt * +ble_eatt_alloc(void) +{ + struct ble_eatt *eatt; + + eatt = os_memblock_get(&ble_eatt_conn_pool); + if (eatt) { + SLIST_INSERT_HEAD(&g_ble_eatt_list, eatt, next); + } + + eatt->conn_handle = BLE_HS_CONN_HANDLE_NONE; + eatt->chan = NULL; + eatt->client_op = 0; + + STAILQ_INIT(&eatt->eatt_tx_q); + ble_npl_event_init(&eatt->setup_ev, ble_eatt_setup_cb, eatt); + ble_npl_event_init(&eatt->wakeup_ev, ble_eatt_wakeup_cb, eatt); + return eatt; +} + +static void +ble_eatt_free(struct ble_eatt *eatt) +{ + struct os_mbuf_pkthdr *omp; + + while ((omp = STAILQ_FIRST(&eatt->eatt_tx_q)) != NULL) { + STAILQ_REMOVE_HEAD(&eatt->eatt_tx_q, omp_next); + os_mbuf_free_chain(OS_MBUF_PKTHDR_TO_MBUF(omp)); + } + + SLIST_REMOVE(&g_ble_eatt_list, eatt, ble_eatt, next); + os_memblock_put(&ble_eatt_conn_pool, eatt); +} + +static int +ble_eatt_l2cap_event_fn(struct ble_l2cap_event *event, void *arg) +{ + struct ble_eatt *eatt = arg; + uint8_t opcode; + int rc; + + switch (event->type) { + case BLE_L2CAP_EVENT_COC_CONNECTED: + BLE_EATT_LOG_DEBUG("eatt: Connected \n"); + if (event->connect.status) { + ble_eatt_free(eatt); + return 0; + } + eatt->chan = event->connect.chan; + break; + case BLE_L2CAP_EVENT_COC_DISCONNECTED: + BLE_EATT_LOG_DEBUG("eatt: Disconnected \n"); + ble_eatt_free(eatt); + break; + case BLE_L2CAP_EVENT_COC_ACCEPT: + BLE_EATT_LOG_DEBUG("eatt: Accept request\n"); + eatt = ble_eatt_find_by_conn_handle(event->accept.conn_handle); + if (eatt) { + /* For now we accept only one additional coc channel per ACL + * TODO: improve it + */ + return BLE_HS_ENOMEM; + } + + eatt = ble_eatt_alloc(); + if (!eatt) { + return BLE_HS_ENOMEM; + } + eatt->conn_handle = event->accept.conn_handle; + event->accept.chan->cb_arg = eatt; + + rc = ble_eatt_prepare_rx_sdu(event->accept.chan); + if (rc) { + ble_eatt_free(eatt); + } + assert(rc == 0); + return 0; + case BLE_L2CAP_EVENT_COC_TX_UNSTALLED: + ble_npl_eventq_put(ble_hs_evq_get(), &eatt->wakeup_ev); + break; + case BLE_L2CAP_EVENT_COC_DATA_RECEIVED: + assert(eatt->chan == event->receive.chan); + opcode = event->receive.sdu_rx->om_data[0]; + if (ble_att_is_request_op(opcode)) { + eatt->server_proceed = true; + } else if (ble_att_is_response_op(opcode)) { + eatt->client_proceed = false; + ble_npl_eventq_put(ble_hs_evq_get(), &eatt->wakeup_ev); + } else { + assert(0); + } + ble_eatt_att_rx_cb(event->receive.conn_handle, eatt->chan->scid, &event->receive.sdu_rx); + if (event->receive.sdu_rx) { + os_mbuf_free_chain(event->receive.sdu_rx); + event->receive.sdu_rx = NULL; + } + rc = ble_eatt_prepare_rx_sdu(event->receive.chan); + + /* FIXME Figure out what to do here, probably disconnect EATT */ + assert(rc == 0); + break; + default: + break; + } + + return 0; +} + +static void +ble_eatt_setup_cb(struct ble_npl_event *ev) +{ + struct ble_eatt *eatt; + struct os_mbuf *om; + + eatt = ble_npl_event_get_arg(ev); + assert(eatt); + + om = os_mbuf_get_pkthdr(&ble_eatt_sdu_os_mbuf_pool, 0); + if (!om) { + ble_eatt_free(eatt); + BLE_EATT_LOG_ERROR("eatt: no memory for sdu\n"); + return; + } + + BLE_EATT_LOG_DEBUG("eatt: connecting eatt on conn_handle 0x%04x\n", eatt->conn_handle); + ble_l2cap_enhanced_connect(eatt->conn_handle, BLE_EATT_PSM, + MYNEWT_VAL(BLE_EATT_MTU), 1, &om, ble_eatt_l2cap_event_fn, eatt); +} + +static int +ble_gatt_eatt_write_cl_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg) +{ + if (error == NULL || (error->status != 0 && error->status != BLE_HS_EDONE)) { + BLE_EATT_LOG_DEBUG("eatt: Cannot write to Client Supported features on peer device\n"); + return 0; + } + + ble_eatt_start(conn_handle); + return 0; +} + +static int +ble_gatt_eatt_read_cl_uuid_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg) +{ + uint8_t client_supported_feat; + int rc; + + if (error == NULL || (error->status != 0 && error->status != BLE_HS_EDONE)) { + BLE_EATT_LOG_DEBUG("eatt: Cannot find Client Supported features on peer device\n"); + return BLE_HS_EDONE; + } + + if (attr == NULL) { + BLE_EATT_LOG_ERROR("eatt: Invalid attribute \n"); + return BLE_HS_EDONE; + } + + if (error->status == 0) { + client_supported_feat = ble_svc_gatt_get_local_cl_supported_feat(); + rc = ble_gattc_write_flat(conn_handle, attr->handle, &client_supported_feat, 1, + ble_gatt_eatt_write_cl_cb, NULL); + BLE_EATT_LOG_DEBUG("eatt: %s , write rc = %d \n", __func__, rc); + assert(rc == 0); + return 0; + } + + return BLE_HS_EDONE; +} + +static int +ble_gatt_eatt_read_uuid_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg) +{ + uint8_t supported_features; + int rc; + + if (error == NULL || (error->status != 0 && error->status != BLE_HS_EDONE)) { + BLE_EATT_LOG_DEBUG("eatt: Cannot find Server Supported features on peer device\n"); + return BLE_HS_EDONE; + } + + if (attr == NULL) { + BLE_EATT_LOG_ERROR("eatt: Invalid attribute \n"); + return BLE_HS_EDONE; + } + + rc = os_mbuf_copydata(attr->om, 0, 1, &supported_features); + if (rc) { + BLE_EATT_LOG_ERROR("eatt: Cannot read srv supported features \n"); + return BLE_HS_EDONE; + } + + if (supported_features & 0x01) { + ble_npl_event_set_arg(&g_read_sup_cl_feat_ev, UINT_TO_POINTER(conn_handle)); + ble_npl_eventq_put(ble_hs_evq_get(), &g_read_sup_cl_feat_ev); + } + return BLE_HS_EDONE; +} + +static void +ble_gatt_eatt_read_svr_uuid(struct ble_npl_event *ev) +{ + uint16_t conn_handle; + + conn_handle = POINTER_TO_UINT(ble_npl_event_get_arg(ev)); + + ble_gattc_read_by_uuid(conn_handle, 1, 0xffff, + BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_SERVER_SUPPORTED_FEAT_UUID16), + ble_gatt_eatt_read_uuid_cb, NULL); +} + +static void +ble_gatt_eatt_read_cl_uuid(struct ble_npl_event *ev) +{ + uint16_t conn_handle; + + conn_handle = POINTER_TO_UINT(ble_npl_event_get_arg(ev)); + + ble_gattc_read_by_uuid(conn_handle, 1, 0xffff, + BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_CLIENT_SUPPORTED_FEAT_UUID16), + ble_gatt_eatt_read_cl_uuid_cb, NULL); +} + +static int +ble_eatt_gap_event(struct ble_gap_event *event, void *arg) +{ + struct ble_eatt *eatt; + + switch (event->type) { + case BLE_GAP_EVENT_CONNECT: + if (event->connect.status != 0) { + return 0; + } + + BLE_EATT_LOG_DEBUG("eatt: Device connected, waiting to write into " + "client supported features\n"); + + ble_npl_event_set_arg(&g_read_sup_srv_feat_ev, UINT_TO_POINTER(event->connect.conn_handle)); + ble_npl_eventq_put(ble_hs_evq_get(), &g_read_sup_srv_feat_ev); + + break; + case BLE_GAP_EVENT_DISCONNECT: + eatt = ble_eatt_find_by_conn_handle(event->disconnect.conn.conn_handle); + assert(eatt == NULL); + break; + default: + break; + } + return 0; +} + +uint16_t +ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op) +{ + struct ble_eatt * eatt; + + eatt = ble_eatt_find_not_busy(conn_handle); + if (!eatt) { + return BLE_L2CAP_CID_ATT; + } + + eatt->client_op = op; + return eatt->chan->scid; +} + +void +ble_eatt_release_chan(uint16_t conn_handle, uint8_t op) +{ + struct ble_eatt * eatt; + + eatt = ble_eatt_find_by_conn_handle_and_busy_op(conn_handle, op); + if (!eatt) { + BLE_EATT_LOG_WARN("ble_eatt_release_chan:" + "EATT not found for conn_handle 0x%04x, operation 0x%02\n", conn_handle, op); + return; + } + + eatt->client_op = 0; +} + +int +ble_eatt_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom) +{ + struct ble_eatt *eatt; + int rc; + + BLE_EATT_LOG_DEBUG("eatt: %s, size %d ", __func__, OS_MBUF_PKTLEN(txom)); + eatt = ble_eatt_find(conn_handle, cid); + if (!eatt || !eatt->chan) { + BLE_EATT_LOG_ERROR("Eatt not available"); + rc = BLE_HS_ENOENT; + goto error; + } + + rc = ble_l2cap_send(eatt->chan, txom); + if (rc == 0) { + goto done; + } + + if (rc == BLE_HS_ESTALLED) { + BLE_EATT_LOG_DEBUG("ble_eatt_tx: Eatt stalled"); + } else if (rc == BLE_HS_EBUSY) { + BLE_EATT_LOG_DEBUG("ble_eatt_tx: Message queued"); + STAILQ_INSERT_HEAD(&eatt->eatt_tx_q, OS_MBUF_PKTHDR(txom), omp_next); + ble_npl_eventq_put(ble_hs_evq_get(), &eatt->wakeup_ev); + } else { + BLE_EATT_LOG_ERROR("eatt: %s, ERROR %d ", __func__, rc); + assert(0); + } +done: + return 0; + +error: + os_mbuf_free_chain(txom); + return rc; +} + +int +ble_eatt_start(uint16_t conn_handle) +{ + struct ble_gap_conn_desc desc; + struct ble_eatt *eatt; + int rc; + + rc = ble_gap_conn_find(conn_handle, &desc); + assert(rc == 0); + if (desc.role != BLE_GAP_ROLE_MASTER) { + /* Let master to create ecoc. + * TODO: Slave could setup after some timeout + */ + return 0; + } + + eatt = ble_eatt_alloc(); + if (!eatt) { + BLE_EATT_LOG_ERROR("eatt: no available eatt resources\n"); + return 0; + } + + eatt->conn_handle = conn_handle; + + /* Setup EATT */ + ble_npl_eventq_put(ble_hs_evq_get(), &eatt->setup_ev); + + return 0; +} + +void +ble_eatt_init(ble_eatt_att_rx_fn att_rx_cb) +{ + int rc; + + rc = mem_init_mbuf_pool(ble_eatt_sdu_coc_mem, + &ble_eatt_sdu_mbuf_mempool, + &ble_eatt_sdu_os_mbuf_pool, + MYNEWT_VAL(BLE_EATT_CHAN_NUM) + 1, + BLE_EATT_MEMBLOCK_SIZE, + "ble_eatt_sdu"); + BLE_HS_DBG_ASSERT_EVAL(rc == 0); + + rc = os_mempool_init(&ble_eatt_conn_pool, MYNEWT_VAL(BLE_EATT_CHAN_NUM), + sizeof (struct ble_eatt), + ble_eatt_conn_mem, "ble_eatt_conn_pool"); + BLE_HS_DBG_ASSERT_EVAL(rc == 0); + + ble_gap_event_listener_register(&ble_eatt_listener, ble_eatt_gap_event, NULL); + ble_l2cap_create_server(BLE_EATT_PSM, MYNEWT_VAL(BLE_EATT_MTU), ble_eatt_l2cap_event_fn, NULL); + + ble_npl_event_init(&g_read_sup_srv_feat_ev, ble_gatt_eatt_read_svr_uuid, NULL); + ble_npl_event_init(&g_read_sup_cl_feat_ev, ble_gatt_eatt_read_cl_uuid, NULL); + + ble_eatt_att_rx_cb = att_rx_cb; +} +#endif diff --git a/nimble/host/src/ble_eatt_priv.h b/nimble/host/src/ble_eatt_priv.h new file mode 100644 index 0000000000..d5d01bd0ee --- /dev/null +++ b/nimble/host/src/ble_eatt_priv.h @@ -0,0 +1,64 @@ +/* + * 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. + */ + +#include "syscfg/syscfg.h" +#include "os/os_mbuf.h" +#include "host/ble_l2cap.h" + +#ifndef BLE_EATT_H_ +#define BLE_EATT_H_ + +typedef int (* ble_eatt_att_rx_fn)(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rx_buf); + +#define BLE_EATT_PSM (0x0027) + +#define BLE_GATT_OP_SERVER 0xF1 +#define BLE_GATT_OP_DUMMY 0xF2 + +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 +void ble_eatt_init(ble_eatt_att_rx_fn att_rx_fn); +uint16_t ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op); +void ble_eatt_release_chan(uint16_t conn_handle, uint8_t op); +int ble_eatt_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom); +int ble_eatt_start(uint16_t conn_handle); +#else +static inline void +ble_eatt_init(ble_eatt_att_rx_fn att_rx_fn) +{ +} + +static inline void +ble_eatt_release_chan(uint16_t conn_handle, uint8_t op) +{ + +} + +static inline uint16_t +ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op) +{ + return BLE_L2CAP_CID_ATT; +} + +static inline int +ble_eatt_start(uint16_t conn_handle) +{ + return 0; +} +#endif +#endif diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index 7346adf389..7467ff6075 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -700,7 +700,7 @@ ble_gattc_proc_prepare(struct ble_gattc_proc *proc, uint16_t conn_handle, uint8_ { proc->conn_handle = conn_handle; proc->op = op; - proc->cid = BLE_L2CAP_CID_ATT; + proc->cid = ble_eatt_get_available_chan_cid(conn_handle, op); } /** @@ -734,6 +734,12 @@ ble_gattc_proc_free(struct ble_gattc_proc *proc) break; } +#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 + if (proc->cid != BLE_L2CAP_CID_ATT) { + ble_eatt_release_chan(proc->conn_handle, proc->op); + } +#endif + #if MYNEWT_VAL(BLE_HS_DEBUG) memset(proc, 0xff, sizeof *proc); #endif @@ -3465,15 +3471,18 @@ ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle, #endif int rc; + uint16_t cid; STATS_INC(ble_gattc_stats, write_no_rsp); ble_gattc_log_write(attr_handle, OS_MBUF_PKTLEN(txom), 0); - rc = ble_att_clt_tx_write_cmd(conn_handle, BLE_L2CAP_CID_ATT, attr_handle, txom); + cid = ble_eatt_get_available_chan_cid(conn_handle, BLE_GATT_OP_DUMMY); + rc = ble_att_clt_tx_write_cmd(conn_handle, cid, attr_handle, txom); if (rc != 0) { STATS_INC(ble_gattc_stats, write); } + ble_eatt_release_chan(conn_handle, BLE_GATT_OP_DUMMY); return rc; } diff --git a/nimble/host/src/ble_hs_priv.h b/nimble/host/src/ble_hs_priv.h index d8949cbc98..393b4d4323 100644 --- a/nimble/host/src/ble_hs_priv.h +++ b/nimble/host/src/ble_hs_priv.h @@ -24,6 +24,7 @@ #include #include "ble_att_cmd_priv.h" #include "ble_att_priv.h" +#include "ble_eatt_priv.h" #include "ble_gap_priv.h" #include "ble_gatt_priv.h" #include "ble_hs_hci_priv.h" diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index cf35be243c..bfe381924a 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -295,6 +295,16 @@ syscfg.defs: value: 1000 # Supported server ATT commands. (0/1) + BLE_EATT_CHAN_NUM: + description: > + Number of CoC channels allocated to EATT + value: 0 + + BLE_EATT_MTU: + description: > + MTU used for EATT channels. + value: 128 + BLE_ATT_SVR_FIND_INFO: description: > Enables processing of incoming Find Information Request ATT @@ -462,11 +472,22 @@ syscfg.defs: description: 'Minimum level for the BLE host log.' value: 1 + BLE_EATT_LOG_MOD: + description: 'Numeric module ID to use for BLE EATT log messages.' + value: 27 + BLE_EATT_LOG_LVL: + description: 'Minimum level for the BLE EATT log.' + value: 1 + syscfg.logs: BLE_HS_LOG: module: MYNEWT_VAL(BLE_HS_LOG_MOD) level: MYNEWT_VAL(BLE_HS_LOG_LVL) + BLE_EATT_LOG: + module: MYNEWT_VAL(BLE_EATT_LOG_MOD) + level: MYNEWT_VAL(BLE_EATT_LOG_LVL) + syscfg.vals.BLE_MESH: BLE_SM_SC: 1 diff --git a/nimble/host/test/syscfg.yml b/nimble/host/test/syscfg.yml index 031b6c8ba1..cfb3a8178c 100644 --- a/nimble/host/test/syscfg.yml +++ b/nimble/host/test/syscfg.yml @@ -30,3 +30,4 @@ syscfg.vals: BLE_VERSION: 52 BLE_L2CAP_ENHANCED_COC: 1 BLE_TRANSPORT_LL: custom + BLE_EATT_CHAN_NUM: 0 diff --git a/porting/examples/linux/include/logcfg/logcfg.h b/porting/examples/linux/include/logcfg/logcfg.h index 89af353092..4fe2ee015b 100644 --- a/porting/examples/linux/include/logcfg/logcfg.h +++ b/porting/examples/linux/include/logcfg/logcfg.h @@ -8,6 +8,13 @@ #include "modlog/modlog.h" #include "log_common/log_common.h" +#define BLE_EATT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__) +#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__) +#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__) +#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__) +#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__) + #define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) #define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__) #define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__) diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index f60846de7f..c262ff8a00 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -571,6 +571,22 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM +#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL +#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD +#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_MTU +#define MYNEWT_VAL_BLE_EATT_MTU (128) +#endif + #ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE #define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1) #endif diff --git a/porting/examples/linux_blemesh/include/logcfg/logcfg.h b/porting/examples/linux_blemesh/include/logcfg/logcfg.h index 520c658c6b..99afa084ff 100644 --- a/porting/examples/linux_blemesh/include/logcfg/logcfg.h +++ b/porting/examples/linux_blemesh/include/logcfg/logcfg.h @@ -8,6 +8,13 @@ #include "modlog/modlog.h" #include "log_common/log_common.h" +#define BLE_EATT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__) +#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__) +#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__) +#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__) +#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__) + #define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) #define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__) #define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__) diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 3af3ecc095..2aba7d619c 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -572,6 +572,22 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM +#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL +#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD +#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_MTU +#define MYNEWT_VAL_BLE_EATT_MTU (128) +#endif + #ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE #define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1) #endif diff --git a/porting/nimble/include/logcfg/logcfg.h b/porting/nimble/include/logcfg/logcfg.h index 89af353092..4fe2ee015b 100644 --- a/porting/nimble/include/logcfg/logcfg.h +++ b/porting/nimble/include/logcfg/logcfg.h @@ -8,6 +8,13 @@ #include "modlog/modlog.h" #include "log_common/log_common.h" +#define BLE_EATT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__) +#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__) +#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__) +#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__) +#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__) + #define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) #define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__) #define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__) diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index 612afbd8eb..f0732c2113 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -570,6 +570,22 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM +#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL +#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD +#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_MTU +#define MYNEWT_VAL_BLE_EATT_MTU (128) +#endif + #ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE #define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1) #endif diff --git a/porting/npl/riot/include/logcfg/logcfg.h b/porting/npl/riot/include/logcfg/logcfg.h index 89af353092..4fe2ee015b 100644 --- a/porting/npl/riot/include/logcfg/logcfg.h +++ b/porting/npl/riot/include/logcfg/logcfg.h @@ -8,6 +8,13 @@ #include "modlog/modlog.h" #include "log_common/log_common.h" +#define BLE_EATT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) +#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__) +#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__) +#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__) +#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__) +#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__) + #define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) #define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__) #define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 75752c0279..b70d7b900b 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1434,6 +1434,22 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM +#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL +#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD +#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_MTU +#define MYNEWT_VAL_BLE_EATT_MTU (128) +#endif + #ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE #define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1) #endif From 0711811c9f002391c7cd3c86dc96be3e411dd816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Thu, 12 Mar 2020 13:50:52 +0100 Subject: [PATCH 0792/1333] nimble/gatt: Add support for newt ATT opcodes This is initial implementation of handling new GATT opcodes. Gatt Client supports now: ATT multi Variable read req receiving ATT multi notifications Gatt server supports now: ATT multi Variable read rsp --- nimble/host/include/host/ble_att.h | 8 + nimble/host/include/host/ble_gatt.h | 14 ++ nimble/host/services/gatt/src/ble_svc_gatt.c | 4 + nimble/host/src/ble_att.c | 3 + nimble/host/src/ble_att_clt.c | 21 ++- nimble/host/src/ble_att_cmd_priv.h | 14 ++ nimble/host/src/ble_att_priv.h | 7 +- nimble/host/src/ble_att_svr.c | 164 ++++++++++++++++++ nimble/host/src/ble_gatt_priv.h | 2 +- nimble/host/src/ble_gattc.c | 144 ++++++++++++--- nimble/host/syscfg.yml | 11 ++ nimble/host/test/src/ble_att_clt_test.c | 4 +- nimble/include/nimble/nimble_opt_auto.h | 4 + .../examples/linux/include/syscfg/syscfg.h | 8 + .../linux_blemesh/include/syscfg/syscfg.h | 8 + porting/nimble/include/syscfg/syscfg.h | 8 + porting/npl/riot/include/syscfg/syscfg.h | 8 + 17 files changed, 405 insertions(+), 27 deletions(-) diff --git a/nimble/host/include/host/ble_att.h b/nimble/host/include/host/ble_att.h index cb98eab478..5a3a2a1ff0 100644 --- a/nimble/host/include/host/ble_att.h +++ b/nimble/host/include/host/ble_att.h @@ -195,6 +195,14 @@ struct os_mbuf; /** Indicate Response. */ #define BLE_ATT_OP_INDICATE_RSP 0x1e +/** Read Multiple Variable Lenght Request */ +#define BLE_ATT_OP_READ_MULT_VAR_REQ 0x20 + +/** Read Multiple Variable Lenght Response */ +#define BLE_ATT_OP_READ_MULT_VAR_RSP 0x21 + +/** Notify Multiple Request */ +#define BLE_ATT_OP_NOTIFY_MULTI_REQ 0x23 /** Write Command. */ #define BLE_ATT_OP_WRITE_CMD 0x52 diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index b3bea2bdc4..b38dd32b25 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -267,6 +267,17 @@ typedef int ble_gatt_attr_fn(uint16_t conn_handle, struct ble_gatt_attr *attr, void *arg); +/** + * The host will free the attribute mbuf automatically after the callback is + * executed. The application can take ownership of the mbuf and prevent it + * from being freed by assigning NULL to attr->om. + */ +typedef int ble_gatt_attr_mult_fn(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attrs, + uint8_t num_attrs, + void *arg); + /** * The host will free the attribute mbufs automatically after the callback is * executed. The application can take ownership of the mbufs and prevent them @@ -489,6 +500,9 @@ int ble_gattc_read_mult(uint16_t conn_handle, const uint16_t *handles, uint8_t num_handles, ble_gatt_attr_fn *cb, void *cb_arg); +int ble_gattc_read_mult_var(uint16_t conn_handle, const uint16_t *handles, + uint8_t num_handles, ble_gatt_attr_mult_fn *cb, + void *cb_arg); /** * Initiates GATT procedure: Write Without Response. This function consumes * the supplied mbuf regardless of the outcome. diff --git a/nimble/host/services/gatt/src/ble_svc_gatt.c b/nimble/host/services/gatt/src/ble_svc_gatt.c index 961c23fc57..501164d5fa 100644 --- a/nimble/host/services/gatt/src/ble_svc_gatt.c +++ b/nimble/host/services/gatt/src/ble_svc_gatt.c @@ -179,4 +179,8 @@ ble_svc_gatt_init(void) if (MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0) { ble_svc_gatt_cl_sup_feat |= (1 << BLE_SVC_GATT_CLI_SUP_FEAT_EATT_BIT); } + + if (MYNEWT_VAL(BLE_ATT_SVR_NOTIFY_MULTI) > 0) { + ble_svc_gatt_cl_sup_feat |= (1 << BLE_SVC_GATT_CLI_SUP_FEAT_MULT_NTF_BIT); + } } diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index ae5041f69f..3295bc869c 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -69,6 +69,9 @@ static const struct ble_att_rx_dispatch_entry ble_att_rx_dispatch[] = { { BLE_ATT_OP_NOTIFY_REQ, ble_att_svr_rx_notify }, { BLE_ATT_OP_INDICATE_REQ, ble_att_svr_rx_indicate }, { BLE_ATT_OP_INDICATE_RSP, ble_att_clt_rx_indicate }, + { BLE_ATT_OP_READ_MULT_VAR_REQ, ble_att_svr_rx_read_mult_var }, + { BLE_ATT_OP_READ_MULT_VAR_RSP, ble_att_clt_rx_read_mult_var }, + { BLE_ATT_OP_NOTIFY_MULTI_REQ, ble_att_svr_rx_notify_multi}, { BLE_ATT_OP_WRITE_CMD, ble_att_svr_rx_write_no_rsp }, }; diff --git a/nimble/host/src/ble_att_clt.c b/nimble/host/src/ble_att_clt.c index 7fcccbb9d7..1bbb32f17a 100644 --- a/nimble/host/src/ble_att_clt.c +++ b/nimble/host/src/ble_att_clt.c @@ -540,7 +540,7 @@ ble_att_clt_rx_read_blob(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rx *****************************************************************************/ int ble_att_clt_tx_read_mult(uint16_t conn_handle, uint16_t cid, const uint16_t *handles, - int num_handles) + int num_handles, bool variable) { #if !NIMBLE_BLE_ATT_CLT_READ_MULT return BLE_HS_ENOTSUP; @@ -549,12 +549,15 @@ ble_att_clt_tx_read_mult(uint16_t conn_handle, uint16_t cid, const uint16_t *han struct ble_att_read_mult_req *req; struct os_mbuf *txom; int i; + uint8_t op; if (num_handles < 1) { return BLE_HS_EINVAL; } - req = ble_att_cmd_get(BLE_ATT_OP_READ_MULT_REQ, + op = variable ? BLE_ATT_OP_READ_MULT_VAR_REQ : BLE_ATT_OP_READ_MULT_REQ; + + req = ble_att_cmd_get(op, sizeof(req->handles[0]) * num_handles, &txom); if (req == NULL) { @@ -576,7 +579,19 @@ ble_att_clt_rx_read_mult(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rx #endif /* Pass the Attribute Value field to GATT. */ - ble_gattc_rx_read_mult_rsp(conn_handle, cid, 0, rxom); + ble_gattc_rx_read_mult_rsp(conn_handle, cid, 0, rxom, false); + return 0; +} + +int +ble_att_clt_rx_read_mult_var(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) +{ +#if !NIMBLE_BLE_ATT_CLT_READ_MULT_VAR + return BLE_HS_ENOTSUP; +#endif + + /* Pass the Attribute Value field to GATT. */ + ble_gattc_rx_read_mult_rsp(conn_handle, cid, 0, rxom, true); return 0; } diff --git a/nimble/host/src/ble_att_cmd_priv.h b/nimble/host/src/ble_att_cmd_priv.h index 7202e0b76d..78c60d5ef4 100644 --- a/nimble/host/src/ble_att_cmd_priv.h +++ b/nimble/host/src/ble_att_cmd_priv.h @@ -309,6 +309,20 @@ struct ble_att_exec_write_req { */ #define BLE_ATT_EXEC_WRITE_RSP_SZ 1 +/** + * | Parameter | Size (octets) | + * +-----------------------------------------------+-------------------+ + * | Attribute Opcode | 1 | + * | Attribute Handle Length Value Tuple List | 8 to (ATT_MTU-1) | + */ +#define BLE_ATT_NOTIFY_MULTI_REQ_BASE_SZ 9 + +struct ble_att_tuple_list { + uint16_t handle; + uint16_t value_len; + uint8_t data[0]; +} __attribute__((packed)); + /** * | Parameter | Size (octets) | * +------------------------------------+-------------------+ diff --git a/nimble/host/src/ble_att_priv.h b/nimble/host/src/ble_att_priv.h index f596cf9175..ac65250f93 100644 --- a/nimble/host/src/ble_att_priv.h +++ b/nimble/host/src/ble_att_priv.h @@ -198,6 +198,8 @@ int ble_att_svr_rx_read_blob(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); int ble_att_svr_rx_read_mult(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_svr_rx_read_mult_var(uint16_t conn_handle, uint16_t cid, + struct os_mbuf **rxom); int ble_att_svr_rx_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); int ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); @@ -207,6 +209,8 @@ int ble_att_svr_rx_exec_write(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); int ble_att_svr_rx_notify(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_svr_rx_notify_multi(uint16_t conn_handle, uint16_t cid, + struct os_mbuf **rxom); int ble_att_svr_rx_indicate(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); void ble_att_svr_prep_clear(struct ble_att_prep_entry_list *prep_list); @@ -261,8 +265,9 @@ int ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t cid, uint16_t handle uint16_t offset); int ble_att_clt_rx_read_blob(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); int ble_att_clt_tx_read_mult(uint16_t conn_handle, uint16_t cid, - const uint16_t *handles, int num_handles); + const uint16_t *handles, int num_handles, bool variable); int ble_att_clt_rx_read_mult(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_rx_read_mult_var(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); int ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t cid, uint16_t start_handle, uint16_t end_handle, const ble_uuid_t *uuid); int ble_att_clt_rx_read_type(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 7cdcd1dbbd..eb91e3e149 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -1629,6 +1629,113 @@ ble_att_svr_rx_read_mult(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rx att_err, err_handle); } +static int +ble_att_svr_build_read_mult_rsp_var(uint16_t conn_handle, uint16_t cid, + struct os_mbuf **rxom, + struct os_mbuf **out_txom, + uint8_t *att_err, + uint16_t *err_handle) +{ + struct os_mbuf *txom; + uint16_t handle; + uint16_t mtu; + uint16_t tuple_len; + struct os_mbuf *tmp = NULL; + int rc; + + mtu = ble_att_mtu_by_cid(conn_handle, cid); + + rc = ble_att_svr_pkt(rxom, &txom, att_err); + if (rc != 0) { + *err_handle = 0; + goto done; + } + + if (ble_att_cmd_prepare(BLE_ATT_OP_READ_MULT_VAR_RSP, 0, txom) == NULL) { + *att_err = BLE_ATT_ERR_INSUFFICIENT_RES; + *err_handle = 0; + rc = BLE_HS_ENOMEM; + goto done; + } + + tmp = os_msys_get_pkthdr(2, 0); + + /* Iterate through requested handles, reading the corresponding attribute + * for each. Stop when there are no more handles to process, or the + * response is full. + */ + while (OS_MBUF_PKTLEN(*rxom) >= 2 && OS_MBUF_PKTLEN(txom) < mtu) { + /* Ensure the full 16-bit handle is contiguous at the start of the + * mbuf. + */ + rc = ble_att_svr_pullup_req_base(rxom, 2, att_err); + if (rc != 0) { + *err_handle = 0; + goto done; + } + + /* Extract the 16-bit handle and strip it from the front of the + * mbuf. + */ + handle = get_le16((*rxom)->om_data); + os_mbuf_adj(*rxom, 2); + + rc = ble_att_svr_read_handle(conn_handle, handle, 0, tmp, att_err); + if (rc != 0) { + *err_handle = handle; + goto done; + } + tuple_len = OS_MBUF_PKTLEN(tmp); + rc = os_mbuf_append(txom, &tuple_len, sizeof(tuple_len)); + if (rc != 0) { + *err_handle = handle; + goto done; + } + if (tuple_len != 0) { + rc = os_mbuf_appendfrom(txom, tmp, 0, tuple_len); + if (rc != 0) { + *err_handle = handle; + goto done; + } + os_mbuf_adj(tmp, tuple_len); + } + } + rc = 0; + +done: + + if (tmp) { + os_mbuf_free_chain(tmp); + } + *out_txom = txom; + return rc; +} + +int +ble_att_svr_rx_read_mult_var(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) +{ +#if (!MYNEWT_VAL(BLE_ATT_SVR_READ_MULT) || (MYNEWT_VAL(BLE_VERSION) < 52)) + return BLE_HS_ENOTSUP; +#endif + + struct os_mbuf *txom; + uint16_t err_handle; + uint8_t att_err; + int rc; + + /* Initialize some values in case of early error. */ + txom = NULL; + err_handle = 0; + att_err = 0; + + rc = ble_att_svr_build_read_mult_rsp_var(conn_handle, cid, rxom, &txom, &att_err, + &err_handle); + + return ble_att_svr_tx_rsp(conn_handle, cid, rc, txom, + BLE_ATT_OP_READ_MULT_VAR_REQ, + att_err, err_handle); +} + static int ble_att_svr_is_valid_read_group_type(const ble_uuid_t *uuid) { @@ -2504,6 +2611,63 @@ ble_att_svr_rx_notify(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) return 0; } +int +ble_att_svr_rx_notify_multi(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) +{ +#if !MYNEWT_VAL(BLE_ATT_SVR_NOTIFY_MULTI) + return BLE_HS_ENOTSUP; +#endif + + struct ble_att_tuple_list *req; + uint16_t handle; + int rc; + uint16_t pkt_len; + struct os_mbuf *tmp; + uint16_t attr_len; + + pkt_len = OS_MBUF_PKTLEN(*rxom); + while (pkt_len > 0) { + rc = ble_att_svr_pullup_req_base(rxom, sizeof(struct ble_att_tuple_list), NULL); + if (rc != 0) { + return BLE_HS_ENOMEM; + } + + req = (struct ble_att_tuple_list *)(*rxom)->om_data; + + handle = le16toh(req->handle); + attr_len = le16toh(req->value_len); + + os_mbuf_adj(*rxom, 4); + + if (attr_len > BLE_ATT_ATTR_MAX_LEN) { + /*TODO Figure out what to do here */ + break; + } + + tmp = os_msys_get_pkthdr(attr_len, 0); + if (!tmp) { + /*TODO Figure out what to do here */ + break; + } + + rc = os_mbuf_appendfrom(tmp, *rxom, 0, attr_len); + if (rc) { + /*TODO Figure out what to do here */ + break; + } + + ble_gap_notify_rx_event(conn_handle, handle, tmp, 0); + + os_mbuf_adj(*rxom, attr_len); + pkt_len = OS_MBUF_PKTLEN(*rxom); + } + + os_mbuf_free_chain(*rxom); + *rxom = NULL; + + return 0; +} + /** * @return 0 on success; nonzero on failure. */ diff --git a/nimble/host/src/ble_gatt_priv.h b/nimble/host/src/ble_gatt_priv.h index 595a813d2d..f77c78ad8a 100644 --- a/nimble/host/src/ble_gatt_priv.h +++ b/nimble/host/src/ble_gatt_priv.h @@ -113,7 +113,7 @@ void ble_gattc_rx_read_rsp(uint16_t conn_handle, uint16_t cid, int status, void ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, uint16_t cid, int status, struct os_mbuf **rxom); void ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, uint16_t cid, int status, - struct os_mbuf **rxom); + struct os_mbuf **rxom, bool variable); void ble_gattc_rx_read_group_type_adata(uint16_t conn_handle, uint16_t cid, struct ble_att_read_group_type_adata *adata); void ble_gattc_rx_read_group_type_complete(uint16_t conn_handle, uint16_t cid, int rc); diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index 7467ff6075..17f302cd9f 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -93,11 +93,12 @@ #define BLE_GATT_OP_READ_UUID 8 #define BLE_GATT_OP_READ_LONG 9 #define BLE_GATT_OP_READ_MULT 10 -#define BLE_GATT_OP_WRITE 11 -#define BLE_GATT_OP_WRITE_LONG 12 -#define BLE_GATT_OP_WRITE_RELIABLE 13 -#define BLE_GATT_OP_INDICATE 14 -#define BLE_GATT_OP_CNT 15 +#define BLE_GATT_OP_READ_MULT_VAR 11 +#define BLE_GATT_OP_WRITE 12 +#define BLE_GATT_OP_WRITE_LONG 13 +#define BLE_GATT_OP_WRITE_RELIABLE 14 +#define BLE_GATT_OP_INDICATE 15 +#define BLE_GATT_OP_CNT 16 /** Procedure stalled due to resource exhaustion. */ #define BLE_GATTC_PROC_F_STALLED 0x01 @@ -189,7 +190,9 @@ struct ble_gattc_proc { struct { uint16_t handles[MYNEWT_VAL(BLE_GATT_READ_MAX_ATTRS)]; uint8_t num_handles; + bool variable; ble_gatt_attr_fn *cb; + ble_gatt_attr_mult_fn *cb_mult; void *cb_arg; } read_mult; @@ -584,7 +587,7 @@ ble_gattc_log_read_long(struct ble_gattc_proc *proc) } static void -ble_gattc_log_read_mult(const uint16_t *handles, uint8_t num_handles) +ble_gattc_log_read_mult(const uint16_t *handles, uint8_t num_handles, bool variable) { int i; @@ -3324,8 +3327,74 @@ ble_gattc_read_long(uint16_t conn_handle, uint16_t handle, uint16_t offset, } /***************************************************************************** - * $read multiple * - *****************************************************************************/ +* $read multiple * +*****************************************************************************/ + +static int +ble_gattc_read_mult_cb_var(struct ble_gattc_proc *proc, int status, + uint16_t att_handle, struct os_mbuf **om) +{ + struct ble_gatt_attr attr[proc->read_mult.num_handles]; + int rc; + int i; + uint16_t attr_len; + + if (proc->read_mult.cb_mult == NULL) { + return 0; + } + + memset(attr, 0, sizeof(*attr)); + + for (i = 0; i < proc->read_mult.num_handles; i++) { + attr[i].handle = proc->read_mult.handles[i]; + attr[i].offset = 0; + if (om == NULL || OS_MBUF_PKTLEN(*om) == 0) { + continue; + } + + *om = os_mbuf_pullup(*om, 2); + assert(*om); + + attr_len = get_le16((*om)->om_data); + + os_mbuf_adj(*om, 2); + + if (attr_len > BLE_ATT_ATTR_MAX_LEN) { + /*TODO Figure out what to do here */ + break; + } + + attr[i].om = os_msys_get_pkthdr(attr_len, 0); + if (!attr[i].om) { + /*TODO Figure out what to do here */ + break; + } + + rc = os_mbuf_appendfrom(attr[i].om, *om, 0, attr_len); + if (rc) { + /*TODO Figure out what to do here */ + break; + } + + os_mbuf_adj(*om, attr_len); + } + + /*FIXME Testing assert */ + assert(i == proc->read_mult.num_handles); + + proc->read_mult.cb_mult(proc->conn_handle, + ble_gattc_error(status, att_handle), &attr[0], + i, + proc->read_mult.cb_arg); + + for (i = 0; i < proc->read_mult.num_handles; i++) { + if (attr[i].om != NULL) { + os_mbuf_free_chain(attr[i].om); + } + } + + return 0; +} /** * Calls a read-multiple-characteristics proc's callback with the specified @@ -3349,6 +3418,10 @@ ble_gattc_read_mult_cb(struct ble_gattc_proc *proc, int status, STATS_INC(ble_gattc_stats, read_mult_fail); } + if (proc->read_mult.variable) { + return ble_gattc_read_mult_cb_var(proc, status, att_handle, om); + } + attr.handle = 0; attr.offset = 0; if (om == NULL) { @@ -3400,7 +3473,7 @@ ble_gattc_read_mult_tx(struct ble_gattc_proc *proc) int rc; rc = ble_att_clt_tx_read_mult(proc->conn_handle, proc->cid, proc->read_mult.handles, - proc->read_mult.num_handles); + proc->read_mult.num_handles, proc->read_mult.variable); if (rc != 0) { return rc; } @@ -3409,10 +3482,11 @@ ble_gattc_read_mult_tx(struct ble_gattc_proc *proc) } -int -ble_gattc_read_mult(uint16_t conn_handle, const uint16_t *handles, - uint8_t num_handles, ble_gatt_attr_fn *cb, - void *cb_arg) +static int +ble_gattc_read_mult_internal(uint16_t conn_handle, const uint16_t *handles, + uint8_t num_handles, bool variable, ble_gatt_attr_fn *cb, + ble_gatt_attr_mult_fn *cb_mult, + void *cb_arg) { #if !MYNEWT_VAL(BLE_GATT_READ_MULT) return BLE_HS_ENOTSUP; @@ -3436,14 +3510,20 @@ ble_gattc_read_mult(uint16_t conn_handle, const uint16_t *handles, goto done; } - ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_READ_MULT); + if (variable) { + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_READ_MULT_VAR); + } else { + ble_gattc_proc_prepare(proc, conn_handle, BLE_GATT_OP_READ_MULT); + } memcpy(proc->read_mult.handles, handles, num_handles * sizeof *handles); proc->read_mult.num_handles = num_handles; + proc->read_mult.variable = variable; proc->read_mult.cb = cb; + proc->read_mult.cb_mult = cb_mult; proc->read_mult.cb_arg = cb_arg; - ble_gattc_log_read_mult(handles, num_handles); + ble_gattc_log_read_mult(handles, num_handles, variable); rc = ble_gattc_read_mult_tx(proc); if (rc != 0) { goto done; @@ -3458,9 +3538,31 @@ ble_gattc_read_mult(uint16_t conn_handle, const uint16_t *handles, return rc; } +int +ble_gattc_read_mult(uint16_t conn_handle, const uint16_t *handles, + uint8_t num_handles, ble_gatt_attr_fn *cb, + void *cb_arg) +{ + return ble_gattc_read_mult_internal(conn_handle, handles, + num_handles, false, cb, NULL, cb_arg); +} + +int +ble_gattc_read_mult_var(uint16_t conn_handle, const uint16_t *handles, + uint8_t num_handles, ble_gatt_attr_mult_fn *cb, + void *cb_arg) +{ +#if MYNEWT_VAL(BLE_GATT_READ_MULT_VAR) + return ble_gattc_read_mult_internal(conn_handle, handles, num_handles, + true, NULL, cb, cb_arg); +#else + return BLE_HS_ENOTSUP; +#endif +} + /***************************************************************************** - * $write no response * - *****************************************************************************/ +* $write no response * +*****************************************************************************/ int ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle, @@ -4762,16 +4864,18 @@ ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, uint16_t cid, int status, */ void ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, uint16_t cid, int status, - struct os_mbuf **om) + struct os_mbuf **om, bool variable) { #if !NIMBLE_BLE_ATT_CLT_READ_MULT return; #endif struct ble_gattc_proc *proc; + uint8_t op; - proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, - BLE_GATT_OP_READ_MULT); + op = variable ? BLE_GATT_OP_READ_MULT_VAR : BLE_GATT_OP_READ_MULT; + + proc = ble_gattc_extract_first_by_conn_cid_op(conn_handle, cid, op); if (proc != NULL) { ble_gattc_read_mult_cb(proc, status, 0, om); ble_gattc_process_status(proc, BLE_HS_EDONE); diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index bfe381924a..f94111c61d 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -244,6 +244,11 @@ syscfg.defs: Enables the Read Multiple Characteristic Values GATT procedure. (0/1) value: MYNEWT_VAL_BLE_ROLE_CENTRAL + BLE_GATT_READ_MULT_VAR: + description: > + Enables the Read Multiple Variable Characteristic Values GATT procedure. + (0/1) + value: MYNEWT_VAL_BLE_ROLE_CENTRAL && (MYNEWT_VAL_BLE_VERSION >= 52) BLE_GATT_WRITE_NO_RSP: description: > Enables the Write Without Response GATT procedure. (0/1) @@ -362,6 +367,12 @@ syscfg.defs: Enables processing of incoming Handle Value Notification ATT commands. (0/1) value: 1 + BLE_ATT_SVR_NOTIFY_MULTI: + description: > + Enables processing of incoming Multi Handle Value Notification ATT + commands. (0/1) + value: MYNEWT_VAL_BLE_ATT_SVR_NOTIFY && (MYNEWT_VAL_BLE_VERSION >= 52) + BLE_ATT_SVR_INDICATE: description: > Enables processing of incoming Handle Value Indication ATT diff --git a/nimble/host/test/src/ble_att_clt_test.c b/nimble/host/test/src/ble_att_clt_test.c index 7d41371ef9..a944f6ee78 100644 --- a/nimble/host/test/src/ble_att_clt_test.c +++ b/nimble/host/test/src/ble_att_clt_test.c @@ -380,7 +380,7 @@ TEST_CASE_SELF(ble_att_clt_test_tx_read_mult) conn_handle = ble_att_clt_test_misc_init(); /*** Success. */ - rc = ble_att_clt_tx_read_mult(conn_handle, BLE_L2CAP_CID_ATT, ((uint16_t[]){ 1, 2 }), 2); + rc = ble_att_clt_tx_read_mult(conn_handle, BLE_L2CAP_CID_ATT, ((uint16_t[]) { 1, 2 }), 2, false); TEST_ASSERT(rc == 0); om = ble_hs_test_util_prev_tx_dequeue_pullup(); @@ -392,7 +392,7 @@ TEST_CASE_SELF(ble_att_clt_test_tx_read_mult) TEST_ASSERT(get_le16(om->om_data + BLE_ATT_READ_MULT_REQ_BASE_SZ + 2) == 2); /*** Error: no handles. */ - rc = ble_att_clt_tx_read_mult(conn_handle, BLE_L2CAP_CID_ATT, NULL, 0); + rc = ble_att_clt_tx_read_mult(conn_handle, BLE_L2CAP_CID_ATT, NULL, 0, false); TEST_ASSERT(rc == BLE_HS_EINVAL); ble_hs_test_util_assert_mbufs_freed(NULL); diff --git a/nimble/include/nimble/nimble_opt_auto.h b/nimble/include/nimble/nimble_opt_auto.h index 33a1e2aac9..55f6219917 100644 --- a/nimble/include/nimble/nimble_opt_auto.h +++ b/nimble/include/nimble/nimble_opt_auto.h @@ -77,6 +77,10 @@ extern "C" { #define NIMBLE_BLE_ATT_CLT_READ_MULT \ (MYNEWT_VAL(BLE_GATT_READ_MULT)) +#undef NIMBLE_BLE_ATT_CLT_READ_MULT_VAR +#define NIMBLE_BLE_ATT_CLT_READ_MULT_VAR \ + (MYNEWT_VAL(BLE_GATT_READ_MULT_VAR)) + #undef NIMBLE_BLE_ATT_CLT_READ_GROUP_TYPE #define NIMBLE_BLE_ATT_CLT_READ_GROUP_TYPE \ (MYNEWT_VAL(BLE_GATT_DISC_ALL_SVCS)) diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index c262ff8a00..04438c215c 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -531,6 +531,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI +#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI (MYNEWT_VAL_BLE_ATT_SVR_NOTIFY && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE #define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1) #endif @@ -643,6 +647,10 @@ #define MYNEWT_VAL_BLE_GATT_READ_MULT (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif +#ifndef MYNEWT_VAL_BLE_GATT_READ_MULT_VAR +#define MYNEWT_VAL_BLE_GATT_READ_MULT_VAR (MYNEWT_VAL_BLE_ROLE_CENTRAL && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ_UUID #define MYNEWT_VAL_BLE_GATT_READ_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 2aba7d619c..c9fd541127 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -532,6 +532,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI +#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI (MYNEWT_VAL_BLE_ATT_SVR_NOTIFY && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE #define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1) #endif @@ -644,6 +648,10 @@ #define MYNEWT_VAL_BLE_GATT_READ_MULT (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif +#ifndef MYNEWT_VAL_BLE_GATT_READ_MULT_VAR +#define MYNEWT_VAL_BLE_GATT_READ_MULT_VAR (MYNEWT_VAL_BLE_ROLE_CENTRAL && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ_UUID #define MYNEWT_VAL_BLE_GATT_READ_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index f0732c2113..dcea02fd60 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -530,6 +530,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI +#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI (MYNEWT_VAL_BLE_ATT_SVR_NOTIFY && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE #define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1) #endif @@ -642,6 +646,10 @@ #define MYNEWT_VAL_BLE_GATT_READ_MULT (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif +#ifndef MYNEWT_VAL_BLE_GATT_READ_MULT_VAR +#define MYNEWT_VAL_BLE_GATT_READ_MULT_VAR (MYNEWT_VAL_BLE_ROLE_CENTRAL && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ_UUID #define MYNEWT_VAL_BLE_GATT_READ_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index b70d7b900b..b381d3289c 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1394,6 +1394,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI +#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI (MYNEWT_VAL_BLE_ATT_SVR_NOTIFY && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE #define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1) #endif @@ -1506,6 +1510,10 @@ #define MYNEWT_VAL_BLE_GATT_READ_MULT (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif +#ifndef MYNEWT_VAL_BLE_GATT_READ_MULT_VAR +#define MYNEWT_VAL_BLE_GATT_READ_MULT_VAR (MYNEWT_VAL_BLE_ROLE_CENTRAL && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ_UUID #define MYNEWT_VAL_BLE_GATT_READ_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif From d5f1d55222724250c06ad55b78e5cf071fb4e283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Thu, 12 Mar 2020 13:23:49 +0100 Subject: [PATCH 0793/1333] btshell: Add support for read multi variable --- apps/btshell/src/btshell.h | 10 ++++----- apps/btshell/src/cmd.c | 1 + apps/btshell/src/cmd_gatt.c | 9 +++++++- apps/btshell/src/main.c | 43 ++++++++++++++++++++++++++++++++----- 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h index 134eb01625..021f54c88d 100644 --- a/apps/btshell/src/btshell.h +++ b/apps/btshell/src/btshell.h @@ -100,22 +100,22 @@ int btshell_exchange_mtu(uint16_t conn_handle); int btshell_disc_svcs(uint16_t conn_handle); int btshell_disc_svc_by_uuid(uint16_t conn_handle, const ble_uuid_t *uuid); int btshell_disc_all_chrs(uint16_t conn_handle, uint16_t start_handle, - uint16_t end_handle); + uint16_t end_handle); int btshell_disc_all_chrs_in_svc(uint16_t conn_handle, struct btshell_svc *svc); int btshell_disc_chrs_by_uuid(uint16_t conn_handle, uint16_t start_handle, - uint16_t end_handle, const ble_uuid_t *uuid); + uint16_t end_handle, const ble_uuid_t *uuid); int btshell_disc_all_dscs(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle); int btshell_disc_full(uint16_t conn_handle); int btshell_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle, - uint16_t end_handle); + uint16_t end_handle); int btshell_read(uint16_t conn_handle, uint16_t attr_handle); int btshell_read_long(uint16_t conn_handle, uint16_t attr_handle, uint16_t offset); int btshell_read_by_uuid(uint16_t conn_handle, uint16_t start_handle, - uint16_t end_handle, const ble_uuid_t *uuid); + uint16_t end_handle, const ble_uuid_t *uuid); int btshell_read_mult(uint16_t conn_handle, uint16_t *attr_handles, - int num_attr_handles); + int num_attr_handles, bool variable); int btshell_write(uint16_t conn_handle, uint16_t attr_handle, struct os_mbuf *om); int btshell_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle, diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index 4148b8e8a1..22819219aa 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -3404,6 +3404,7 @@ static const struct shell_param gatt_read_params[] = { {"uuid", "read by uuid, usage: =[UUID]"}, {"start", "start handle, usage: ="}, {"end", "end handle, usage: ="}, + {"variable", "used in case of multi read, usage: =[0-1], default=0"}, {NULL, NULL} }; diff --git a/apps/btshell/src/cmd_gatt.c b/apps/btshell/src/cmd_gatt.c index ba3799e56f..4c57b42d6c 100644 --- a/apps/btshell/src/cmd_gatt.c +++ b/apps/btshell/src/cmd_gatt.c @@ -238,6 +238,7 @@ cmd_gatt_read(int argc, char **argv) uint8_t num_attr_handles; int is_uuid; int is_long; + bool is_var; int rc; rc = parse_arg_all(argc - 1, argv + 1); @@ -259,6 +260,12 @@ cmd_gatt_read(int argc, char **argv) return rc; } + is_var = parse_arg_bool_dflt("variable", 0, &rc); + if (rc != 0) { + console_printf("invalid 'variable' parameter\n"); + return rc; + } + for (num_attr_handles = 0; num_attr_handles < CMD_READ_MAX_ATTRS; num_attr_handles++) { @@ -313,7 +320,7 @@ cmd_gatt_read(int argc, char **argv) rc = btshell_read(conn_handle, attr_handles[0]); } } else if (num_attr_handles > 1) { - rc = btshell_read_mult(conn_handle, attr_handles, num_attr_handles); + rc = btshell_read_mult(conn_handle, attr_handles, num_attr_handles, is_var); } else if (is_uuid) { if (start == 0 || end == 0) { rc = EINVAL; diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index 2df3719117..4c4a6bb787 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -869,6 +869,35 @@ btshell_on_disc_d(uint16_t conn_handle, const struct ble_gatt_error *error, return 0; } +static int +btshell_on_read_var(uint16_t conn_handle, const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, uint8_t num_attrs, void *arg) +{ + int i; + + switch (error->status) { + case 0: + console_printf("characteristic read; conn_handle=%d , number of attributes=%d\n", conn_handle, num_attrs); + + for (i = 0; i < num_attrs; i++) { + console_printf("\t attr_handle=%d, len=%d value=", + attr[i].handle, OS_MBUF_PKTLEN(attr[i].om)); + print_mbuf(attr[i].om); + console_printf("\n"); + } + break; + + case BLE_HS_EDONE: + console_printf("characteristic read complete\n"); + break; + + default: + btshell_print_error(NULL, conn_handle, error); + break; + } + + return 0; +} static int btshell_on_read(uint16_t conn_handle, const struct ble_gatt_error *error, @@ -1670,13 +1699,17 @@ btshell_read_by_uuid(uint16_t conn_handle, uint16_t start_handle, int btshell_read_mult(uint16_t conn_handle, uint16_t *attr_handles, - int num_attr_handles) + int num_attr_handles, bool variable) { - int rc; + if (variable) { + return ble_gattc_read_mult_var(conn_handle, attr_handles, num_attr_handles, + btshell_on_read_var, NULL); + } + + return ble_gattc_read_mult(conn_handle, attr_handles, + num_attr_handles, + btshell_on_read, NULL); - rc = ble_gattc_read_mult(conn_handle, attr_handles, num_attr_handles, - btshell_on_read, NULL); - return rc; } int From 2b53de8820008c52081fe7d9c964f4c6d72a066a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 17 Jul 2023 11:53:17 +0200 Subject: [PATCH 0794/1333] nimle/tests: reset conn->client_att_busy between requests In real case, requests are scheduled to be sent after previous one completes. That happens after response is received. In unittests, internal API is used for holding pending requests, from which they can be manually dequeued. Because dequeue operation is always manual and does not happed after response reception (when will never arrive, there is no second device) we need to clear flag to be able to start another procedure. --- nimble/host/test/src/ble_att_clt_test.c | 21 ++++++++++++- nimble/host/test/src/ble_gatt_conn_test.c | 36 +++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/nimble/host/test/src/ble_att_clt_test.c b/nimble/host/test/src/ble_att_clt_test.c index a944f6ee78..849603daac 100644 --- a/nimble/host/test/src/ble_att_clt_test.c +++ b/nimble/host/test/src/ble_att_clt_test.c @@ -78,24 +78,34 @@ TEST_CASE_SELF(ble_att_clt_test_tx_find_info) { uint16_t conn_handle; int rc; + struct ble_hs_conn *conn; ble_hs_test_util_assert_mbufs_freed(NULL); conn_handle = ble_att_clt_test_misc_init(); + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + ble_hs_unlock(); /*** Success. */ rc = ble_att_clt_tx_find_info(conn_handle, BLE_L2CAP_CID_ATT, 1, 0xffff); TEST_ASSERT(rc == 0); /*** Error: start handle of 0. */ + /** In unit tests we don't are not receiving response - procedure will + * not complete. Reset `client_att_busy` flag so new request can be sent + */ + conn->client_att_busy = false; rc = ble_att_clt_tx_find_info(conn_handle, BLE_L2CAP_CID_ATT, 0, 0xffff); TEST_ASSERT(rc == BLE_HS_EINVAL); /*** Error: start handle greater than end handle. */ + conn->client_att_busy = false; rc = ble_att_clt_tx_find_info(conn_handle, BLE_L2CAP_CID_ATT, 500, 499); TEST_ASSERT(rc == BLE_HS_EINVAL); /*** Success; start and end handles equal. */ + conn->client_att_busy = false; rc = ble_att_clt_tx_find_info(conn_handle, BLE_L2CAP_CID_ATT, 500, 500); TEST_ASSERT(rc == 0); @@ -175,9 +185,14 @@ ble_att_clt_test_case_tx_write_req_or_cmd(int is_req) uint16_t conn_handle; uint8_t value300[500] = { 0 }; uint8_t value5[5] = { 6, 7, 54, 34, 8 }; + struct ble_hs_conn *conn; conn_handle = ble_att_clt_test_misc_init(); + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + ble_hs_unlock(); + /*** 5-byte write. */ ble_att_clt_test_tx_write_req_or_cmd(conn_handle, 0x1234, value5, sizeof value5, is_req); @@ -185,6 +200,10 @@ ble_att_clt_test_case_tx_write_req_or_cmd(int is_req) is_req); /*** Overlong write; verify command truncated to ATT MTU. */ + /** In unit tests we are not receiving response - procedure will + * not complete. Reset `client_att_busy` flag so new request can be sent + */ + conn->client_att_busy = false; ble_att_clt_test_tx_write_req_or_cmd(conn_handle, 0xab83, value300, sizeof value300, is_req); ble_att_clt_test_misc_verify_tx_write(0xab83, value300, @@ -501,13 +520,13 @@ TEST_CASE_SELF(ble_att_clt_test_tx_exec_write) uint16_t conn_handle; int rc; - conn_handle = ble_att_clt_test_misc_init(); /*** Success. */ ble_att_clt_test_misc_exec_good(BLE_ATT_EXEC_WRITE_F_CANCEL); ble_att_clt_test_misc_exec_good(BLE_ATT_EXEC_WRITE_F_EXECUTE); /*** Success: nonzero == execute. */ + conn_handle = ble_att_clt_test_misc_init(); rc = ble_att_clt_tx_exec_write(conn_handle, BLE_L2CAP_CID_ATT, 0x02); TEST_ASSERT(rc == 0); diff --git a/nimble/host/test/src/ble_gatt_conn_test.c b/nimble/host/test/src/ble_gatt_conn_test.c index 5cb94ce828..d74dd6fcfe 100644 --- a/nimble/host/test/src/ble_gatt_conn_test.c +++ b/nimble/host/test/src/ble_gatt_conn_test.c @@ -385,6 +385,7 @@ TEST_CASE_SELF(ble_gatt_conn_test_disconnect) uint16_t attr_handle; uint16_t offset = 0; int rc; + struct ble_hs_conn *conn; ble_gatt_conn_test_util_init(); @@ -405,65 +406,92 @@ TEST_CASE_SELF(ble_gatt_conn_test_disconnect) /*** Schedule some GATT procedures. */ /* Connection 1. */ mtu_arg.exp_conn_handle = 1; + ble_hs_lock(); + conn = ble_hs_conn_find(1); + ble_hs_unlock(); + + /** In unit tests we are not receiving response - procedure will + * not complete. Reset `client_att_busy` flag so new request can be sent + */ + conn->client_att_busy = false; ble_gattc_exchange_mtu(1, ble_gatt_conn_test_mtu_cb, &mtu_arg); disc_all_svcs_arg.exp_conn_handle = 1; + conn->client_att_busy = false; rc = ble_gattc_disc_all_svcs(1, ble_gatt_conn_test_disc_all_svcs_cb, &disc_all_svcs_arg); TEST_ASSERT_FATAL(rc == 0); disc_svc_uuid_arg.exp_conn_handle = 1; + conn->client_att_busy = false; rc = ble_gattc_disc_svc_by_uuid(1, BLE_UUID16_DECLARE(0x1111), ble_gatt_conn_test_disc_svc_uuid_cb, &disc_svc_uuid_arg); TEST_ASSERT_FATAL(rc == 0); find_inc_svcs_arg.exp_conn_handle = 1; + conn->client_att_busy = false; rc = ble_gattc_find_inc_svcs(1, 1, 0xffff, ble_gatt_conn_test_find_inc_svcs_cb, &find_inc_svcs_arg); TEST_ASSERT_FATAL(rc == 0); disc_all_chrs_arg.exp_conn_handle = 1; + conn->client_att_busy = false; rc = ble_gattc_disc_all_chrs(1, 1, 0xffff, ble_gatt_conn_test_disc_all_chrs_cb, &disc_all_chrs_arg); TEST_ASSERT_FATAL(rc == 0); /* Connection 2. */ + ble_hs_lock(); + conn = ble_hs_conn_find(2); + ble_hs_unlock(); + disc_all_dscs_arg.exp_conn_handle = 2; + conn->client_att_busy = false; rc = ble_gattc_disc_all_dscs(2, 3, 0xffff, ble_gatt_conn_test_disc_all_dscs_cb, &disc_all_dscs_arg); disc_chr_uuid_arg.exp_conn_handle = 2; + conn->client_att_busy = false; rc = ble_gattc_disc_chrs_by_uuid(2, 2, 0xffff, BLE_UUID16_DECLARE(0x2222), ble_gatt_conn_test_disc_chr_uuid_cb, &disc_chr_uuid_arg); read_arg.exp_conn_handle = 2; + conn->client_att_busy = false; rc = ble_gattc_read(2, BLE_GATT_BREAK_TEST_READ_ATTR_HANDLE, ble_gatt_conn_test_read_cb, &read_arg); TEST_ASSERT_FATAL(rc == 0); read_uuid_arg.exp_conn_handle = 2; + conn->client_att_busy = false; rc = ble_gattc_read_by_uuid(2, 1, 0xffff, BLE_UUID16_DECLARE(0x3333), ble_gatt_conn_test_read_uuid_cb, &read_uuid_arg); TEST_ASSERT_FATAL(rc == 0); read_long_arg.exp_conn_handle = 2; + conn->client_att_busy = false; rc = ble_gattc_read_long(2, BLE_GATT_BREAK_TEST_READ_ATTR_HANDLE, offset, ble_gatt_conn_test_read_long_cb, &read_long_arg); TEST_ASSERT_FATAL(rc == 0); /* Connection 3. */ + ble_hs_lock(); + conn = ble_hs_conn_find(3); + ble_hs_unlock(); + read_mult_arg.exp_conn_handle = 3; + conn->client_att_busy = false; rc = ble_gattc_read_mult(3, ((uint16_t[3]){5,6,7}), 3, ble_gatt_conn_test_read_mult_cb, &read_mult_arg); TEST_ASSERT_FATAL(rc == 0); write_arg.exp_conn_handle = 3; + conn->client_att_busy = false; rc = ble_hs_test_util_gatt_write_flat( 3, BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE, ble_gatt_conn_test_write_value, sizeof ble_gatt_conn_test_write_value, @@ -471,6 +499,7 @@ TEST_CASE_SELF(ble_gatt_conn_test_disconnect) TEST_ASSERT_FATAL(rc == 0); write_long_arg.exp_conn_handle = 3; + conn->client_att_busy = false; rc = ble_hs_test_util_gatt_write_long_flat( 3, BLE_GATT_BREAK_TEST_WRITE_ATTR_HANDLE, ble_gatt_conn_test_write_value, sizeof ble_gatt_conn_test_write_value, @@ -481,10 +510,12 @@ TEST_CASE_SELF(ble_gatt_conn_test_disconnect) attr.offset = 0; attr.om = os_msys_get_pkthdr(0, 0); write_rel_arg.exp_conn_handle = 3; + conn->client_att_busy = false; rc = ble_gattc_write_reliable( 3, &attr, 1, ble_gatt_conn_test_write_rel_cb, &write_rel_arg); TEST_ASSERT_FATAL(rc == 0); + conn->client_att_busy = false; rc = ble_gatts_indicate(3, attr_handle); TEST_ASSERT_FATAL(rc == 0); @@ -528,6 +559,11 @@ TEST_CASE_SELF(ble_gatt_conn_test_disconnect) TEST_ASSERT(ble_gatt_conn_test_gap_event.type == 255); /* Connection 3. */ + /** This is required because of call ble_att_clt_tx_exec_write + * from ble_att_clt_tx_exec_write after broken connection - + * ble_gattc_fail_procs is called + */ + conn->client_att_busy = false; ble_gattc_connection_broken(3); TEST_ASSERT(mtu_arg.called == 1); TEST_ASSERT(disc_all_svcs_arg.called == 1); From 1f837e4d5771c5a2b7f84d420242e5ec3c9a8f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 24 Jul 2023 08:20:02 +0200 Subject: [PATCH 0795/1333] host: add error handler cb for Read Multiple Variable Length This is needed to properly handle failed procedure, and pass error to the app. --- nimble/host/src/ble_gattc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index 17f302cd9f..2d42856b8f 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -243,6 +243,7 @@ static ble_gattc_err_fn ble_gattc_read_err; static ble_gattc_err_fn ble_gattc_read_uuid_err; static ble_gattc_err_fn ble_gattc_read_long_err; static ble_gattc_err_fn ble_gattc_read_mult_err; +static ble_gattc_err_fn ble_gattc_read_mult_var_err; static ble_gattc_err_fn ble_gattc_write_err; static ble_gattc_err_fn ble_gattc_write_long_err; static ble_gattc_err_fn ble_gattc_write_reliable_err; @@ -260,6 +261,7 @@ static ble_gattc_err_fn * const ble_gattc_err_dispatch[BLE_GATT_OP_CNT] = { [BLE_GATT_OP_READ_UUID] = ble_gattc_read_uuid_err, [BLE_GATT_OP_READ_LONG] = ble_gattc_read_long_err, [BLE_GATT_OP_READ_MULT] = ble_gattc_read_mult_err, + [BLE_GATT_OP_READ_MULT_VAR] = ble_gattc_read_mult_var_err, [BLE_GATT_OP_WRITE] = ble_gattc_write_err, [BLE_GATT_OP_WRITE_LONG] = ble_gattc_write_long_err, [BLE_GATT_OP_WRITE_RELIABLE] = ble_gattc_write_reliable_err, @@ -3467,6 +3469,18 @@ ble_gattc_read_mult_err(struct ble_gattc_proc *proc, int status, ble_gattc_read_mult_cb(proc, status, att_handle, NULL); } +/** + * Handles an incoming ATT error response for the specified + * read-multiple-variable-lengthcharacteristics proc. + */ +static void +ble_gattc_read_mult_var_err(struct ble_gattc_proc *proc, int status, + uint16_t att_handle) +{ + ble_gattc_dbg_assert_proc_not_inserted(proc); + ble_gattc_read_mult_cb_var(proc, status, att_handle, NULL); +} + static int ble_gattc_read_mult_tx(struct ble_gattc_proc *proc) { From b047179dbc038238eecba0d61db54c0530c40af3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 4 Aug 2023 11:36:42 +0200 Subject: [PATCH 0796/1333] host/ble_att.c: add missing op code for BLE_ATT_OP_READ_MULT_VAR REQ/RSP This was missing and assert in ble_eatt_l2cap_event_fn was hit --- nimble/host/src/ble_att.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index 3295bc869c..a65bc939f2 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -648,6 +648,7 @@ ble_att_is_request_op(uint8_t opcode) case BLE_ATT_OP_PREP_WRITE_REQ: case BLE_ATT_OP_EXEC_WRITE_REQ: case BLE_ATT_OP_INDICATE_REQ: + case BLE_ATT_OP_READ_MULT_VAR_REQ: return true; } return false; @@ -670,6 +671,7 @@ ble_att_is_response_op(uint8_t opcode) case BLE_ATT_OP_WRITE_RSP: case BLE_ATT_OP_PREP_WRITE_RSP: case BLE_ATT_OP_EXEC_WRITE_RSP: + case BLE_ATT_OP_READ_MULT_VAR_RSP: return true; } From 085447d74c32690ce9262863bac87eb6fffd4c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 20 Jul 2023 13:24:10 +0200 Subject: [PATCH 0797/1333] apps/bttester: add support for GATT Read Multiple Variable Length Adds required command and response event. --- apps/bttester/src/btp/btp_gattc.h | 9 ++++ apps/bttester/src/btp_gatt_cl.c | 89 +++++++++++++++++++++++++++++++ apps/bttester/syscfg.yml | 2 + 3 files changed, 100 insertions(+) diff --git a/apps/bttester/src/btp/btp_gattc.h b/apps/bttester/src/btp/btp_gattc.h index 76510b47af..df90ef0d96 100644 --- a/apps/bttester/src/btp/btp_gattc.h +++ b/apps/bttester/src/btp/btp_gattc.h @@ -166,6 +166,13 @@ struct btp_gattc_cfg_notify_cmd { uint16_t ccc_handle; } __packed; +#define BTP_GATTC_READ_MULTIPLE_VAR 0x14 +struct btp_gattc_read_multiple_var_cmd { + ble_addr_t address; + uint8_t handles_count; + uint16_t handles[0]; +} __packed; + /* events */ #define BTP_GATTC_EV_MTU_EXCHANGED 0x80 struct btp_gattc_exchange_mtu_ev { @@ -241,3 +248,5 @@ struct btp_gattc_notification_ev { uint16_t data_length; uint8_t data[0]; } __packed; + +#define BTP_GATTC_READ_MULTIPLE_VAR_RP 0x91 diff --git a/apps/bttester/src/btp_gatt_cl.c b/apps/bttester/src/btp_gatt_cl.c index ff76d7dd7f..4b1af0ff85 100644 --- a/apps/bttester/src/btp_gatt_cl.c +++ b/apps/bttester/src/btp_gatt_cl.c @@ -1364,6 +1364,89 @@ config_subscription_ind(const void *cmd, uint16_t cmd_len, return status; } +static int +read_var_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + uint8_t num_attrs, + void *arg) +{ + struct btp_gattc_read_rp *rp = (void *) gatt_buf.buf; + struct ble_gap_conn_desc conn; + uint8_t rp_data_off = 0; + struct ble_gatt_attr attrs[num_attrs]; + + SYS_LOG_DBG("status=%d", error->status); + + if (ble_gap_conn_find(conn_handle, &conn)) { + return BTP_STATUS_FAILED; + } + + memcpy(attrs, attr, sizeof(struct ble_gatt_attr) * num_attrs); + + memcpy(&rp->address, &conn.peer_ota_addr, sizeof(rp->address)); + + rp->status = (uint8_t) BLE_HS_ATT_ERR(error->status); + + if (error->status != 0) { + rp->data_length = 0; + tester_event(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_MULTIPLE_VAR_RP, + rp, sizeof(*rp)); + } + + for (int i = 0; i < num_attrs; i++) { + memcpy(rp->data + rp_data_off, &attrs[i].om->om_len, 2); + rp_data_off += 2; + memcpy(rp->data + rp_data_off, attrs[i].om->om_data, + attrs[i].om->om_len); + rp_data_off += attrs[i].om->om_len; + } + + rp->data_length = rp_data_off; + + if (error->status == 0) { + tester_event(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_MULTIPLE_VAR_RP, + rp, sizeof(*rp) + rp->data_length); + read_destroy(); + return 0; + } + + return 0; +} + +static uint8_t +read_multiple_var(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_gattc_read_multiple_var_cmd *cp = cmd; + uint16_t handles[cp->handles_count]; + struct ble_gap_conn_desc conn; + int rc, i; + + SYS_LOG_DBG(""); + + for (i = 0; i < ARRAY_SIZE(handles); i++) { + handles[i] = le16toh(cp->handles[i]); + } + + rc = ble_gap_conn_find_by_addr(&cp->address, &conn); + if (rc) { + return BTP_STATUS_FAILED; + } + + if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) { + return BTP_STATUS_FAILED; + } + + if (ble_gattc_read_mult_var(conn.conn_handle, handles, + cp->handles_count, read_var_cb, + NULL)) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + int tester_gattc_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle, uint8_t indication, struct os_mbuf *om) @@ -1433,6 +1516,7 @@ supported_commands(const void *cmd, uint16_t cmd_len, tester_set_bit(rp->data, BTP_GATTC_RELIABLE_WRITE); tester_set_bit(rp->data, BTP_GATTC_CFG_NOTIFY); tester_set_bit(rp->data, BTP_GATTC_CFG_INDICATE); + tester_set_bit(rp->data, BTP_GATTC_READ_MULTIPLE_VAR); *rsp_len = sizeof(*rp) + 3; @@ -1539,6 +1623,11 @@ static const struct btp_handler handlers[] = { .expect_len = sizeof(struct btp_gattc_cfg_notify_cmd), .func = config_subscription_ind, }, + { + .opcode = BTP_GATTC_READ_MULTIPLE_VAR, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = read_multiple_var, + }, }; uint8_t diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 5db9af2ea8..4bd16fc79c 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -144,3 +144,5 @@ syscfg.vals: BLE_MESH_ADV_BUF_COUNT: 20 BLE_MESH_TX_SEG_MAX: 6 + + BLE_EATT_CHAN_NUM: 1 From d64581c0b1c6ec26f5df34855fe20f695199b574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 3 Aug 2023 13:50:01 +0200 Subject: [PATCH 0798/1333] host/gatts: save reported Client Supported Features per connection GATT Client by writing to Client Supported Features characteristic reports to server what features it supports. These features should be saved for future use so appropriate subprocedures can be selected. --- nimble/host/include/host/ble_gatt.h | 20 ++++++++ nimble/host/services/gatt/src/ble_svc_gatt.c | 18 ++++--- nimble/host/src/ble_gatt_priv.h | 13 ++++- nimble/host/src/ble_gatts.c | 54 ++++++++++++++++++++ 4 files changed, 95 insertions(+), 10 deletions(-) diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index b38dd32b25..cd17cc26c0 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -1076,6 +1076,26 @@ int ble_gatts_reset(void); */ int ble_gatts_start(void); +/** + * Saves Client Supported Features for specified connection. + * + * @param conn_handle Connection handle identifying connection for + * which Client Supported Features should be saved + * @param om The mbuf chain to set value from. + * + * @return 0 on success; + * BLE_HS_ENOTCONN if no matching connection + * was found + * BLE_HS_EINVAL if supplied buffer is empty or + * if any Client Supported Feature was + * attempted to be disabled. + * A BLE host core return code on unexpected + * error. + * + */ +int ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, + struct os_mbuf *om); + #ifdef __cplusplus } #endif diff --git a/nimble/host/services/gatt/src/ble_svc_gatt.c b/nimble/host/services/gatt/src/ble_svc_gatt.c index 501164d5fa..54162afabf 100644 --- a/nimble/host/services/gatt/src/ble_svc_gatt.c +++ b/nimble/host/services/gatt/src/ble_svc_gatt.c @@ -35,8 +35,8 @@ static uint16_t ble_svc_gatt_end_handle; #define BLE_SVC_GATT_CLI_SUP_FEAT_EATT_BIT (0x01) #define BLE_SVC_GATT_CLI_SUP_FEAT_MULT_NTF_BIT (0x02) -static uint8_t ble_svc_gatt_srv_sup_feat = 0; -static uint8_t ble_svc_gatt_cl_sup_feat = 0; +static uint8_t ble_svc_gatt_local_srv_sup_feat = 0; +static uint8_t ble_svc_gatt_local_cl_sup_feat = 0; static int ble_svc_gatt_access(uint16_t conn_handle, uint16_t attr_handle, @@ -91,7 +91,7 @@ ble_svc_gatt_srv_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle, return BLE_ATT_ERR_WRITE_NOT_PERMITTED; } - os_mbuf_append(ctxt->om, &ble_svc_gatt_srv_sup_feat, sizeof(ble_svc_gatt_srv_sup_feat)); + os_mbuf_append(ctxt->om, &ble_svc_gatt_local_srv_sup_feat, sizeof(ble_svc_gatt_local_srv_sup_feat)); return 0; } @@ -106,7 +106,9 @@ ble_svc_gatt_cl_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle, os_mbuf_append(ctxt->om, &eatt_supported, sizeof(eatt_supported)); return 0; } - /* TODO For write just return OK */ + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + return ble_gatts_peer_cl_sup_feat_update(conn_handle, ctxt->om); + } return 0; } @@ -140,7 +142,7 @@ ble_svc_gatt_access(uint16_t conn_handle, uint16_t attr_handle, uint8_t ble_svc_gatt_get_local_cl_supported_feat(void) { - return ble_svc_gatt_cl_sup_feat; + return ble_svc_gatt_local_cl_sup_feat; } /** @@ -173,14 +175,14 @@ ble_svc_gatt_init(void) SYSINIT_PANIC_ASSERT(rc == 0); if (MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0) { - ble_svc_gatt_srv_sup_feat |= (1 << BLE_SVC_GATT_SRV_SUP_FEAT_EATT_BIT); + ble_svc_gatt_local_srv_sup_feat |= (1 << BLE_SVC_GATT_SRV_SUP_FEAT_EATT_BIT); } if (MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0) { - ble_svc_gatt_cl_sup_feat |= (1 << BLE_SVC_GATT_CLI_SUP_FEAT_EATT_BIT); + ble_svc_gatt_local_cl_sup_feat |= (1 << BLE_SVC_GATT_CLI_SUP_FEAT_EATT_BIT); } if (MYNEWT_VAL(BLE_ATT_SVR_NOTIFY_MULTI) > 0) { - ble_svc_gatt_cl_sup_feat |= (1 << BLE_SVC_GATT_CLI_SUP_FEAT_MULT_NTF_BIT); + ble_svc_gatt_local_cl_sup_feat |= (1 << BLE_SVC_GATT_CLI_SUP_FEAT_MULT_NTF_BIT); } } diff --git a/nimble/host/src/ble_gatt_priv.h b/nimble/host/src/ble_gatt_priv.h index f77c78ad8a..ba0b806735 100644 --- a/nimble/host/src/ble_gatt_priv.h +++ b/nimble/host/src/ble_gatt_priv.h @@ -86,8 +86,9 @@ STATS_SECT_START(ble_gatts_stats) STATS_SECT_END extern STATS_SECT_DECL(ble_gatts_stats) ble_gatts_stats; -#define BLE_GATT_CHR_DECL_SZ_16 5 -#define BLE_GATT_CHR_DECL_SZ_128 19 +#define BLE_GATT_CHR_DECL_SZ_16 5 +#define BLE_GATT_CHR_DECL_SZ_128 19 +#define BLE_GATT_CHR_CLI_SUP_FEAT_SZ 1 typedef uint8_t ble_gatts_conn_flags; @@ -96,6 +97,14 @@ struct ble_gatts_conn { int num_clt_cfgs; uint16_t indicate_val_handle; + + /** + * For now only 3 bits in one octet are defined, but specification expects + * this service to be variable length with no upper bound. Let's make this + * future proof if more octets might be used. + * (Vol. 3, Part G, 7.2) + */ + uint8_t peer_cl_sup_feat[BLE_GATT_CHR_CLI_SUP_FEAT_SZ]; }; /*** @client. */ diff --git a/nimble/host/src/ble_gatts.c b/nimble/host/src/ble_gatts.c index 6732bc1662..ce5f1709e0 100644 --- a/nimble/host/src/ble_gatts.c +++ b/nimble/host/src/ble_gatts.c @@ -1580,6 +1580,60 @@ ble_gatts_chr_updated(uint16_t chr_val_handle) } } +int +ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, struct os_mbuf *om) +{ + struct ble_hs_conn *conn; + int rc = 0; + int feat_idx = 0; + int i; + + BLE_HS_LOG(DEBUG, ""); + + if (!om) { + return BLE_HS_EINVAL; + } + + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + if (conn == NULL) { + rc = BLE_HS_ENOTCONN; + goto done; + } + if (om->om_len == 0) { + /* Nothing to do */ + goto done; + } else if (os_mbuf_len(om) > BLE_ATT_ATTR_MAX_LEN) { + rc = BLE_HS_ENOMEM; + goto done; + } + + while(om) { + for (i = 0; i < om->om_len; i++) { + /** + * Disabling already enabled features is not permitted + * (Vol. 3, Part F, 3.3.3) + * If value of saved octet, as uint8_t, is greatet than requested + * it means more bits are set. + */ + if (conn->bhc_gatt_svr.peer_cl_sup_feat[feat_idx] > + om->om_data[i]) { + rc = BLE_HS_EINVAL; + goto done; + } + + conn->bhc_gatt_svr.peer_cl_sup_feat[feat_idx] |= om->om_data[i]; + + feat_idx++; + } + om = SLIST_NEXT(om, om_next); + } + +done: + ble_hs_unlock(); + return rc; +} + /** * Sends notifications or indications for the specified characteristic to all * connected devices. The bluetooth spec does not allow more than one From 91507e85c6295344fad1d269da69403b4b23a701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 7 Aug 2023 12:27:39 +0200 Subject: [PATCH 0799/1333] host/ble_att_ctl.c: release eatt chan in ble_att_clt_tx_notify Channel was taken and function returns before release. --- nimble/host/src/ble_att_clt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_att_clt.c b/nimble/host/src/ble_att_clt.c index 1bbb32f17a..3423e25e86 100644 --- a/nimble/host/src/ble_att_clt.c +++ b/nimble/host/src/ble_att_clt.c @@ -927,8 +927,9 @@ ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle, os_mbuf_concat(txom2, txom); cid = ble_eatt_get_available_chan_cid(conn_handle, BLE_GATT_OP_DUMMY); - return ble_att_tx(conn_handle, cid, txom2); + rc = ble_att_tx(conn_handle, cid, txom2); ble_eatt_release_chan(conn_handle, BLE_GATT_OP_DUMMY); + return rc; err: os_mbuf_free_chain(txom); From 74a157a6194610576ef44dfa8bf473bb1a8be2b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 16 Aug 2023 08:39:23 +0200 Subject: [PATCH 0800/1333] host/ble_att.c: add missing OP code in ble_att_is_request_op Assert was hit when BLE_ATT_OP_NOTIFY_MULTI_REQ was received. --- nimble/host/src/ble_att.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index a65bc939f2..3c5eaf75e1 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -649,6 +649,7 @@ ble_att_is_request_op(uint8_t opcode) case BLE_ATT_OP_EXEC_WRITE_REQ: case BLE_ATT_OP_INDICATE_REQ: case BLE_ATT_OP_READ_MULT_VAR_REQ: + case BLE_ATT_OP_NOTIFY_MULTI_REQ: return true; } return false; From 27e02e6a2ff388f4a47084c9a6371416d2a3a681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 18 Aug 2023 14:01:58 +0200 Subject: [PATCH 0801/1333] host/ble_svc_gatt.c: return local Client supported features based on config EATT supported bit is returned when EATT channel number is greater than 0 and Multiple Handle notification based on BLE_ATT_SVR_NOTIFY_MULTI. --- nimble/host/services/gatt/src/ble_svc_gatt.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nimble/host/services/gatt/src/ble_svc_gatt.c b/nimble/host/services/gatt/src/ble_svc_gatt.c index 54162afabf..5dcc4fa29c 100644 --- a/nimble/host/services/gatt/src/ble_svc_gatt.c +++ b/nimble/host/services/gatt/src/ble_svc_gatt.c @@ -101,9 +101,10 @@ ble_svc_gatt_cl_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { - /* TODO For now just send 1*/ - uint8_t eatt_supported = 2; - os_mbuf_append(ctxt->om, &eatt_supported, sizeof(eatt_supported)); + uint8_t supported_feat = + (MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0) << 1 | + (MYNEWT_VAL(BLE_ATT_SVR_NOTIFY_MULTI) == 1) << 2; + os_mbuf_append(ctxt->om, &supported_feat, sizeof(supported_feat)); return 0; } if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { From 5b00265f0263c98c17e32b733dc95953092de83c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 21 Aug 2023 10:16:34 +0200 Subject: [PATCH 0802/1333] host/ble_att.c: fix ATT MTU for EATT channels For EATT bearer, ATT MTU is same for bot RX and TX and is minimum of the two. L2CAP Credit Based Reconfigure Request can be used to change its value. --- nimble/host/src/ble_att.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index 3c5eaf75e1..5e221824c3 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -463,9 +463,12 @@ ble_att_chan_mtu(const struct ble_l2cap_chan *chan) uint16_t mtu; #if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 - if (chan->scid != BLE_L2CAP_CID_ATT) { - /* EATT case */ - return chan->coc_tx.mtu; + if (chan->psm == BLE_EATT_PSM) { + /* The ATT_MTU for the Enhanced ATT bearer shall be set to the minimum of the + * MTU field values of the two devices. Reference: + * Core v5.0, Vol 6, Part B, section 1.3.2.1 + */ + return min(chan->coc_tx.mtu, chan->coc_rx.mtu); } #endif From 6ba79ca7230307802858dd48c2a81025de545670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 21 Aug 2023 14:08:54 +0200 Subject: [PATCH 0803/1333] host/ble_eatt: improve PDU rx management Added check for link encryption. Removed unused flags for client/server process. Before processing it is checked if PDU is an ATT one, and channel is disconnected if not. If after processing PDU next one can't be received link is discconnected. --- nimble/host/src/ble_eatt.c | 44 ++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c index 093bcda941..ff2b580238 100644 --- a/nimble/host/src/ble_eatt.c +++ b/nimble/host/src/ble_eatt.c @@ -35,9 +35,7 @@ struct ble_eatt { uint16_t conn_handle; struct ble_l2cap_chan *chan; uint8_t client_op; - bool client_proceed; - bool server_proceed; /* Packet transmit queue */ STAILQ_HEAD(, os_mbuf_pkthdr) eatt_tx_q; @@ -209,6 +207,7 @@ static int ble_eatt_l2cap_event_fn(struct ble_l2cap_event *event, void *arg) { struct ble_eatt *eatt = arg; + struct ble_gap_conn_desc desc; uint8_t opcode; int rc; @@ -254,23 +253,46 @@ ble_eatt_l2cap_event_fn(struct ble_l2cap_event *event, void *arg) case BLE_L2CAP_EVENT_COC_DATA_RECEIVED: assert(eatt->chan == event->receive.chan); opcode = event->receive.sdu_rx->om_data[0]; - if (ble_att_is_request_op(opcode)) { - eatt->server_proceed = true; - } else if (ble_att_is_response_op(opcode)) { - eatt->client_proceed = false; + if (ble_att_is_response_op(opcode)) { ble_npl_eventq_put(ble_hs_evq_get(), &eatt->wakeup_ev); - } else { - assert(0); + } else if (!ble_att_is_request_op(opcode)) { + /* As per BLE 5.4 Standard, Vol. 3, Part F, section 5.3.2 + * (ENHANCED ATT BEARER L2CAP INTEROPERABILITY REQUIREMENTS: + * Channel Requirements): + * All packets sent on this L2CAP channel shall be Attribute PDUs. + * + * Disconnect peer with invalid behavior. + */ + ble_l2cap_disconnect(eatt->chan); + return BLE_HS_EREJECT; + } + + assert (!ble_gap_conn_find(event->receive.conn_handle, &desc)); + /* As per BLE 5.4 Standard, Vol. 3, Part F, section 5.3.2 + * (ENHANCED ATT BEARER L2CAP INTEROPERABILITY REQUIREMENTS: + * Channel Requirements): + * The channel shall be encrypted. + * + * Disconnect peer with invalid behavior - ATT PDU received before + * encryption. + */ + if (!desc.sec_state.encrypted) { + ble_l2cap_disconnect(eatt->chan); + return BLE_HS_EREJECT; } + ble_eatt_att_rx_cb(event->receive.conn_handle, eatt->chan->scid, &event->receive.sdu_rx); if (event->receive.sdu_rx) { os_mbuf_free_chain(event->receive.sdu_rx); event->receive.sdu_rx = NULL; } - rc = ble_eatt_prepare_rx_sdu(event->receive.chan); - /* FIXME Figure out what to do here, probably disconnect EATT */ - assert(rc == 0); + /* Receiving L2CAP data is no longer possible, terminate connection */ + rc = ble_eatt_prepare_rx_sdu(event->receive.chan); + if (rc) { + ble_l2cap_disconnect(eatt->chan); + return BLE_HS_ENOMEM; + } break; default: break; From 10b3aa043ef7c2c023cd9418b5f35e40e07bb34f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 22 Aug 2023 13:41:25 +0200 Subject: [PATCH 0804/1333] host/ble_att_svr.c: handle errors in ble_att_svr_rx_notify_multi --- nimble/host/src/ble_att_svr.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index eb91e3e149..aad64f687d 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -2620,7 +2620,7 @@ ble_att_svr_rx_notify_multi(uint16_t conn_handle, uint16_t cid, struct os_mbuf * struct ble_att_tuple_list *req; uint16_t handle; - int rc; + int rc = 0; uint16_t pkt_len; struct os_mbuf *tmp; uint16_t attr_len; @@ -2640,20 +2640,24 @@ ble_att_svr_rx_notify_multi(uint16_t conn_handle, uint16_t cid, struct os_mbuf * os_mbuf_adj(*rxom, 4); if (attr_len > BLE_ATT_ATTR_MAX_LEN) { - /*TODO Figure out what to do here */ - break; + BLE_HS_LOG_ERROR("attr length (%d) > max (%d)", + attr_len, BLE_ATT_ATTR_MAX_LEN); + rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + goto done; } tmp = os_msys_get_pkthdr(attr_len, 0); if (!tmp) { - /*TODO Figure out what to do here */ - break; + BLE_HS_LOG_ERROR("not enough resources, aborting"); + rc = BLE_ATT_ERR_INSUFFICIENT_RES; + goto done; } rc = os_mbuf_appendfrom(tmp, *rxom, 0, attr_len); if (rc) { - /*TODO Figure out what to do here */ - break; + BLE_HS_LOG_ERROR("not enough resources, aborting"); + rc = BLE_ATT_ERR_INSUFFICIENT_RES; + goto done; } ble_gap_notify_rx_event(conn_handle, handle, tmp, 0); @@ -2661,11 +2665,11 @@ ble_att_svr_rx_notify_multi(uint16_t conn_handle, uint16_t cid, struct os_mbuf * os_mbuf_adj(*rxom, attr_len); pkt_len = OS_MBUF_PKTLEN(*rxom); } - +done: os_mbuf_free_chain(*rxom); *rxom = NULL; - return 0; + return rc; } /** From b5e107e9c55f32d18b16e5afc0a7e1720b901b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 31 Aug 2023 11:07:59 +0200 Subject: [PATCH 0805/1333] apps/bttester: disable EATT in default config EATT causes issues with tests GAP/SEC/SEM/BV-{65-67}-C. It is experimental feature and should not influence config for current test plan. --- apps/bttester/syscfg.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 4bd16fc79c..5db9af2ea8 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -144,5 +144,3 @@ syscfg.vals: BLE_MESH_ADV_BUF_COUNT: 20 BLE_MESH_TX_SEG_MAX: 6 - - BLE_EATT_CHAN_NUM: 1 From 3a161c8e3e50bbf201fbebcb92558240eaf71aaf Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 7 Sep 2023 10:53:20 +0200 Subject: [PATCH 0806/1333] Apache NimBLE 1.6.0 release --- repository.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/repository.yml b/repository.yml index 797edaa761..2dc50fb8ac 100644 --- a/repository.yml +++ b/repository.yml @@ -22,8 +22,8 @@ repo.versions: "0.0.0": "master" "0-dev": "0.0.0" - "0-latest": "1.5.0" - "1-latest": "1.5.0" + "0-latest": "1.6.0" + "1-latest": "1.6.0" "1.0.0": "nimble_1_0_0_tag" "1.1.0": "nimble_1_1_0_tag" From b2b28243f95731b867bdcf4b37b4e665fb29f898 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 9 Aug 2023 11:58:42 +0200 Subject: [PATCH 0807/1333] nimble/ll: Add DTM extension for unmodulated carrier This may be useful for HW validation. Implemented for nRF5x driver based on Nordic DTM sample. --- .../controller/include/controller/ble_phy.h | 3 +++ nimble/controller/src/ble_ll_dtm.c | 24 ++++++++++++++++++- nimble/drivers/dialog_cmac/src/ble_phy.c | 8 +++++++ nimble/drivers/nrf5x/src/ble_phy.c | 16 +++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/nimble/controller/include/controller/ble_phy.h b/nimble/controller/include/controller/ble_phy.h index ab96cb9c70..fe70044234 100644 --- a/nimble/controller/include/controller/ble_phy.h +++ b/nimble/controller/include/controller/ble_phy.h @@ -238,6 +238,9 @@ static inline int ble_ll_phy_to_phy_mode(int phy, int phy_options) #if MYNEWT_VAL(BLE_LL_DTM) void ble_phy_enable_dtm(void); void ble_phy_disable_dtm(void); +#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS) +int ble_phy_dtm_carrier(uint8_t rf_channel); +#endif #endif #ifdef __cplusplus diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index 07e25fe2f8..c57a1357a1 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -342,6 +342,18 @@ ble_ll_dtm_tx_create_ctx(uint8_t packet_payload, uint8_t len, case 0x07: byte_pattern = 0xAA; break; +#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS) + case 0xff: + ble_ll_tx_power_set(g_ble_ll_tx_power); + rc = ble_phy_dtm_carrier(channel_rf_to_index[rf_channel]); + if (rc) { + return 1; + } + + /* this is special as it doesn't involve scheduling */ + g_ble_ll_dtm_ctx.active = 1; + return 0; +#endif default: return 1; } @@ -478,10 +490,20 @@ ble_ll_dtm_tx_test(uint8_t tx_chan, uint8_t len, uint8_t packet_payload, return BLE_ERR_INV_HCI_CMD_PARMS; } - if (tx_chan > 0x27 || packet_payload > 0x07) { + if (tx_chan > 0x27) { return BLE_ERR_INV_HCI_CMD_PARMS; } + if (packet_payload > 0x07) { +#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS) + if (packet_payload != 255) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } +#else + return BLE_ERR_INV_HCI_CMD_PARMS; +#endif + } + if (ble_ll_dtm_tx_create_ctx(packet_payload, len, tx_chan, phy_mode, interval, pkt_count)) { return BLE_ERR_UNSPECIFIED; diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index 938455bbbd..d146e07e39 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -1796,4 +1796,12 @@ ble_phy_disable_dtm(void) { g_ble_phy_data.phy_whitening = 1; } + +#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS) +int +ble_phy_dtm_carrier(uint8_t rf_channel) +{ + return 1; +} +#endif #endif diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 481ed619d1..cea18144ad 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -2286,6 +2286,22 @@ void ble_phy_disable_dtm(void) /* Enable whitening */ NRF_RADIO->PCNF1 |= RADIO_PCNF1_WHITEEN_Msk; } + +#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS) +int +ble_phy_dtm_carrier(uint8_t rf_channel) +{ + /* based on Nordic DTM sample */ + ble_phy_disable(); + ble_phy_enable_dtm(); + ble_phy_mode_apply(BLE_PHY_MODE_1M); + nrf_radio_shorts_enable(NRF_RADIO, NRF_RADIO_SHORT_READY_START_MASK); + NRF_RADIO->FREQUENCY = g_ble_phy_chan_freq[rf_channel]; + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_TXEN); + + return 0; +} +#endif #endif void From 492629e9772c4c8172a17d4ce2519bea18c0b437 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 9 Aug 2023 11:59:01 +0200 Subject: [PATCH 0808/1333] apps/dtm: Fix handling of unmodulated carrier We now provide unmodulated carrier via DTM extension (payload=255). Previously implemented command was never upstream and thus was not working. --- apps/dtm/src/main.c | 102 ++------------------------------------------ 1 file changed, 3 insertions(+), 99 deletions(-) diff --git a/apps/dtm/src/main.c b/apps/dtm/src/main.c index e5e0689c80..11f41160b4 100644 --- a/apps/dtm/src/main.c +++ b/apps/dtm/src/main.c @@ -105,7 +105,7 @@ cmd_tx_test(int argc, char **argv) } params.payload = parse_arg_uint8("payload", &rc); - if ((rc != 0) || ((params.payload > 7))) { + if ((rc != 0) || ((params.payload > 7 && params.payload != 255))) { console_printf("invalid 'payload' parameter\n"); return rc; } @@ -205,75 +205,6 @@ cmd_set_antenna(int argc, char **argv) return 0; } -#define BLE_HCI_OCF_VS_TEST_CARRIER (0x0020) - -static bool tx_carrier_running = false; - -static int -cmd_tx_carrier(int argc, char **argv) -{ - uint8_t cmd[2]; - int rc; - - rc = parse_arg_all(argc - 1, argv + 1); - if (rc != 0) { - return rc; - } - - if (tx_carrier_running) { - console_printf("TX carrier already started\n"); - return 0; - } - - cmd[0] = 1; - cmd[1] = parse_arg_uint8("channel", &rc); - if ((rc != 0) || (cmd[1] > 39)) { - console_printf("invalid channel\n"); - return rc; - } - - rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_TEST_CARRIER, &cmd, sizeof(cmd), - NULL, 0); - if (rc) { - console_printf("failed to start TX carrier\n"); - return rc; - } - - console_printf("TX carrier started\n"); - tx_carrier_running = true; - return 0; -} - -static int -cmd_stop_carrier(int argc, char **argv) -{ - uint8_t cmd[2]; - int rc; - - rc = parse_arg_all(argc - 1, argv + 1); - if (rc != 0) { - return rc; - } - - if (!tx_carrier_running) { - console_printf("TX carrier not started\n"); - return 0; - } - cmd[0] = 0; - cmd[1] = 0; - - rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_TEST_CARRIER, &cmd, sizeof(cmd), - NULL, 0); - if (rc) { - console_printf("failed to stop TX carrier\n"); - return rc; - } - - console_printf("TX carrier stopped\n"); - tx_carrier_running = false; - return 0; -} - static const struct shell_param cmd_rx_test_params[] = { {"channel", "RX channel, usage: =[0-39]"}, {"phy", "usage: =[1M|2M], default: 1M"}, @@ -288,10 +219,10 @@ static const struct shell_cmd_help cmd_rx_test_help = { }; static const struct shell_param cmd_tx_test_params[] = { - {"channel", "RX channel, usage: =[0-39]"}, + {"channel", "TX channel, usage: =[0-39]"}, {"phy", "usage: =[1M|2M], default: 1M"}, {"data_length", "usage: =[0-255], default: 0"}, - {"payload", "usage: =[0-7]"}, + {"payload", "usage: =[0-7, 255]"}, {NULL} }; @@ -329,23 +260,6 @@ static const struct shell_cmd_help cmd_set_antenna_help = { .params = cmd_set_antenna_params, }; -static const struct shell_param cmd_tx_carrier_params[] = { - {"channel", "TX channel, usage: =[0-39]"}, - {NULL} -}; - -static const struct shell_cmd_help cmd_tx_carrier_help = { - .summary = "TX unmodulated carrier", - .usage = NULL, - .params = cmd_tx_carrier_params, -}; - -static const struct shell_cmd_help cmd_stop_carrier_help = { - .summary = "stop TX unmodulated carrier", - .usage = NULL, - .params = NULL, -}; - static const struct shell_cmd dtm_commands[] = { { .sc_cmd = "rx-test", @@ -372,16 +286,6 @@ static const struct shell_cmd dtm_commands[] = { .sc_cmd_func = cmd_set_antenna, .help = &cmd_set_antenna_help, }, - { - .sc_cmd = "tx-carrier", - .sc_cmd_func = cmd_tx_carrier, - .help = &cmd_tx_carrier_help, - }, - { - .sc_cmd = "stop-carrier", - .sc_cmd_func = cmd_stop_carrier, - .help = &cmd_stop_carrier_help, - }, { } }; From 170728f2ae3435eb13a04532559c5a1b6fadb35a Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 14 Sep 2023 12:28:26 +0200 Subject: [PATCH 0809/1333] nimble/phy/nrfx: Add support for extending T_IFS This allows to extend T_ifs (inter-frame spacing) by additional microseconds to improve interoperability with peripherals that send packets too late (eg 153us). This prolongs reception time by additional microseconds. Defaults to 2us to improve operations with devices already on the market. --- nimble/drivers/nrf5x/src/ble_phy.c | 2 ++ nimble/drivers/nrf5x/syscfg.yml | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index cea18144ad..0c37f2aa76 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -852,6 +852,8 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) * by waiting 1 usec more. */ end_time += 1; + + end_time += MYNEWT_VAL(BLE_PHY_EXTENDED_TIFS); } else { /* * RX shall start no later than wfr_usecs after RX enabled. diff --git a/nimble/drivers/nrf5x/syscfg.yml b/nimble/drivers/nrf5x/syscfg.yml index 07c9042f67..f5a227305c 100644 --- a/nimble/drivers/nrf5x/syscfg.yml +++ b/nimble/drivers/nrf5x/syscfg.yml @@ -26,6 +26,16 @@ syscfg.defs: experimental: 1 value: 0 + BLE_PHY_EXTENDED_TIFS: + description: > + This allows to extend T_ifs (inter-frame spacing) by additional + microseconds to improve interoperability with peripherals that + send packets too late (eg 153us). This prolongs reception time by + additional microseconds. Defaults to 2us to improve operations with + devices already on the market. + range: 0..4 + value: 2 + BLE_PHY_SYSVIEW: description: > Enable SystemView tracing module for radio driver. From 4d01f96d7b7507d4404dfa737c99b35fb6b2b952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 1 Aug 2022 12:51:54 +0200 Subject: [PATCH 0810/1333] apps/bttester: add support for Periodic Sync Transfer Added BTP commands required to execute Periodic Advertising tests. Added support for using basic functionalities of Extended Advertising. --- apps/bttester/src/btp/btp_gap.h | 99 +++++++ apps/bttester/src/btp_gap.c | 448 +++++++++++++++++++++++++++++++- 2 files changed, 540 insertions(+), 7 deletions(-) diff --git a/apps/bttester/src/btp/btp_gap.h b/apps/bttester/src/btp/btp_gap.h index 93b62c484d..65b56818cf 100644 --- a/apps/bttester/src/btp/btp_gap.h +++ b/apps/bttester/src/btp/btp_gap.h @@ -70,6 +70,7 @@ struct btp_gap_read_controller_index_list_rp { #define BTP_GAP_SETTINGS_PRIVACY 13 #define BTP_GAP_SETTINGS_CONTROLLER_CONFIG 14 #define BTP_GAP_SETTINGS_STATIC_ADDRESS 15 +#define BTP_GAP_SETTINGS_PERIODIC_ADVERTISING 18 #define BTP_GAP_READ_CONTROLLER_INFO 0x03 struct btp_gap_read_controller_info_rp { @@ -257,6 +258,67 @@ struct btp_gap_set_filter_accept_list_cmd { uint8_t list_len; ble_addr_t addrs[]; } __packed; + +#define GAP_PADV_CONFIGURE 0x22 +struct gap_periodic_adv_configure_cmd { + uint8_t flags; + uint16_t itvl_min; + uint16_t itvl_max; +} __packed; + +struct btp_gap_periodic_adv_configure_rp { + uint32_t current_settings; +} __packed; + +#define GAP_PADV_START 0x23 +struct gap_periodic_adv_start_cmd { + uint8_t flags; +} __packed; + +struct btp_gap_periodic_adv_start_rp { + uint32_t current_settings; +} __packed; + +#define GAP_PADV_STOP 0x24 +struct btp_gap_periodic_adv_stop_rp { + uint32_t current_settings; +} __packed; + +#define GAP_PADV_SET_DATA 0x25 +struct gap_periodic_adv_set_data_cmd { + uint16_t adv_data_len; + uint8_t adv_data[0]; +} __packed; + +#define GAP_PADV_CREATE_SYNC 0x26 +struct gap_periodic_adv_create_sync_cmd { + ble_addr_t addr; + uint8_t adv_sid; + uint16_t skip; + uint16_t sync_timeout; + uint8_t flags; +} __packed; + +#define GAP_PADV_SYNC_TRANSFER_SET_INFO 0x27 +struct gap_periodic_adv_sync_transfer_set_info_cmd { + ble_addr_t addr; + uint16_t svc_data; +} __packed; + +#define GAP_PADV_SYNC_TRANSFER_START 0x28 +struct gap_periodic_adv_sync_transfer_start_cmd { + uint16_t sync_handle; + ble_addr_t addr; + uint16_t svc_data; +} __packed; + +#define GAP_PADV_SYNC_TRANSFER_RECV 0x29 +struct gap_periodic_adv_sync_transfer_recv_cmd { + ble_addr_t addr; + uint16_t skip; + uint16_t sync_timeout; + uint8_t flags; +} __packed; /* events */ #define BTP_GAP_EV_NEW_SETTINGS 0x80 struct btp_gap_new_settings_ev { @@ -342,3 +404,40 @@ struct btp_gap_sec_pairing_failed_ev { ble_addr_t address; uint8_t reason; } __packed; + +#define GAP_EV_PERIODIC_SYNC_ESTABLISHED 0x8d +struct gap_periodic_sync_est_ev { + ble_addr_t peer_addr; + uint16_t sync_handle; + uint8_t status; +} __packed; + +#define GAP_EV_PERIODIC_SYNC_LOST 0x8e +struct gap_periodic_sync_lost_ev { + uint16_t sync_handle; + uint8_t reason; +} __packed; + +#define GAP_EV_PERIODIC_REPORT 0x8f +struct gap_periodic_report_ev { + uint16_t sync_handle; + int8_t tx_power; + int8_t rssi; + uint8_t cte_type; + uint8_t data_status; + uint8_t data_length; + uint8_t data[247]; +} __packed; + +#define GAP_EV_PERIODIC_TRANSFER_RECEIVED 0x90 +struct gap_periodic_transfer_recieved_ev { + uint8_t status; + uint16_t sync_handle; + uint16_t conn_handle; + uint16_t service_data; + uint8_t sid; + ble_addr_t adv_addr; + uint8_t adv_phy; + uint16_t per_adv_itvl; + uint8_t adv_clk_accuracy; +} __packed; \ No newline at end of file diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 8056eaf13d..5d30cbb08d 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -156,8 +156,24 @@ supported_commands(const void *cmd, uint16_t cmd_len, tester_set_bit(rp->data, BTP_GAP_OOB_SC_GET_LOCAL_DATA); tester_set_bit(rp->data, BTP_GAP_OOB_SC_SET_REMOTE_DATA); tester_set_bit(rp->data, BTP_GAP_SET_MITM); + tester_set_bit(rp->data, BTP_GAP_SET_FILTER_ACCEPT_LIST); + + /* octet 4 */ +#if MYNEWT_VAL(BLE_PERIODIC_ADV) + tester_set_bit(rp->data, GAP_PADV_CONFIGURE); + tester_set_bit(rp->data, GAP_PADV_START); + tester_set_bit(rp->data, GAP_PADV_SET_DATA); + tester_set_bit(rp->data, GAP_PADV_CREATE_SYNC); +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) + tester_set_bit(rp->data, GAP_PADV_SYNC_TRANSFER_SET_INFO); + tester_set_bit(rp->data, GAP_PADV_SYNC_TRANSFER_START); + tester_set_bit(rp->data, GAP_PADV_SYNC_TRANSFER_START); +#endif - *rsp_len = sizeof(*rp) + 4; + *rsp_len = sizeof(*rp) + 4 + + (MYNEWT_VAL(BLE_PERIODIC_ADV) || + MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) ? 1 : 0); return BTP_STATUS_SUCCESS; } @@ -247,10 +263,20 @@ controller_info(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +#if MYNEWT_VAL(BLE_EXT_ADV) +int adv_duration = 0; +static struct ble_gap_ext_adv_params adv_params = { + .primary_phy = BLE_HCI_LE_PHY_1M, + .secondary_phy = BLE_HCI_LE_PHY_1M, + .sid = 1, + .legacy_pdu = 1, +}; +#else static struct ble_gap_adv_params adv_params = { .conn_mode = BLE_GAP_CONN_MODE_NON, .disc_mode = BLE_GAP_DISC_MODE_NON, }; +#endif #if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) static void rotate_nrpa_cb(struct os_event *ev) @@ -295,10 +321,20 @@ set_connectable(const void *cmd, uint16_t cmd_len, if (cp->connectable) { current_settings |= BIT(BTP_GAP_SETTINGS_CONNECTABLE); +#if MYNEWT_VAL(BLE_EXT_ADV) + adv_params.connectable = 1; + adv_params.scannable = 1; +#else adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; +#endif } else { current_settings &= ~BIT(BTP_GAP_SETTINGS_CONNECTABLE); +#if MYNEWT_VAL(BLE_EXT_ADV) + adv_params.connectable = 0; + adv_params.scannable = 0; +#else adv_params.conn_mode = BLE_GAP_CONN_MODE_NON; +#endif } rp->current_settings = htole32(current_settings); @@ -314,6 +350,7 @@ static uint8_t set_discoverable(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { +#if !MYNEWT_VAL(BLE_EXT_ADV) const struct btp_gap_set_discoverable_cmd *cp = cmd; struct btp_gap_set_discoverable_rp *rp = rsp; @@ -346,6 +383,9 @@ set_discoverable(const void *cmd, uint16_t cmd_len, *rsp_len = sizeof(*rp); return BTP_STATUS_SUCCESS; +#else + return BTP_STATUS_FAILED; +#endif } static uint8_t @@ -457,11 +497,28 @@ start_advertising(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } - err = ble_gap_adv_set_data(buf, buf_len); - if (err != 0) { +#if MYNEWT_VAL(BLE_EXT_ADV) + struct os_mbuf *ad_buf; + + adv_params.own_addr_type = own_addr_type; + err = ble_gap_ext_adv_configure(0, &adv_params, NULL, gap_event_cb, NULL); + if (err) { + SYS_LOG_ERR("Failed to configure extended advertiser; rc=%d", err); return BTP_STATUS_FAILED; } + ad_buf = os_msys_get_pkthdr(BLE_HS_ADV_MAX_SZ, 0); + + if (os_mbuf_append(ad_buf, buf, buf_len)) { + os_mbuf_free_chain(ad_buf); + return BTP_STATUS_FAILED; + } + + err = ble_gap_ext_adv_set_data(0, ad_buf); +#else + err = ble_gap_adv_set_data(buf, buf_len); +#endif + if (sd_len) { buf_len = 0; @@ -478,9 +535,13 @@ start_advertising(const void *cmd, uint16_t cmd_len, } } +#if !MYNEWT_VAL(BLE_EXT_ADV) if (adv_params.disc_mode == BLE_GAP_DISC_MODE_LTD) { duration_ms = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); } +#else + adv_duration = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); +#endif /* In NimBLE, own_addr_type is configured in `controller_info` function. * Let's just verify restrictions for Privacy options. @@ -513,8 +574,13 @@ start_advertising(const void *cmd, uint16_t cmd_len, OS_TICKS_PER_SEC * MYNEWT_VAL(BTTESTER_NRPA_TIMEOUT)); } #endif + +#if MYNEWT_VAL(BLE_EXT_ADV) + err = ble_gap_ext_adv_start(0, duration_ms, 0); +#else err = ble_gap_adv_start(own_addr_type, NULL, duration_ms, - &adv_params, gap_event_cb, NULL); + &adv_params, gap_event_cb, NULL); +#endif if (err) { SYS_LOG_ERR("Advertising failed: err %d", err); return BTP_STATUS_FAILED; @@ -533,14 +599,18 @@ stop_advertising(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { struct btp_gap_stop_advertising_rp *rp = rsp; - int err; SYS_LOG_DBG(""); - err = ble_gap_adv_stop(); - if (err != 0) { +#if MYNEWT_VAL(BLE_EXT_ADV) + if (ble_gap_ext_adv_stop(0) != 0) { + return BTP_STATUS_FAILED; + } +#else + if (ble_gap_adv_stop() != 0) { return BTP_STATUS_FAILED; } +#endif current_settings &= ~BIT(BTP_GAP_SETTINGS_ADVERTISING); rp->current_settings = htole32(current_settings); @@ -1139,6 +1209,71 @@ bond_lost(uint16_t conn_handle) (uint8_t *) &ev, sizeof(ev)); } +#if MYNEWT_VAL(BLE_PERIODIC_ADV) +static void +sync_established(struct ble_gap_event *event) +{ + struct gap_periodic_sync_est_ev ev; + + ev.status = event->periodic_sync.status; + ev.sync_handle = event->periodic_sync.sync_handle; + + tester_event(BTP_SERVICE_ID_GAP, GAP_EV_PERIODIC_SYNC_ESTABLISHED, + (uint8_t *) &ev, sizeof(ev)); +} + +static void +sync_lost(struct ble_gap_event *event) +{ + struct gap_periodic_sync_lost_ev ev; + + ev.reason = event->periodic_sync_lost.reason; + ev.sync_handle = event->periodic_sync_lost.sync_handle; + + tester_event(BTP_SERVICE_ID_GAP, GAP_EV_PERIODIC_SYNC_LOST, + (uint8_t *) &ev, sizeof(ev)); +} + +static void +periodic_report(struct ble_gap_event *event) +{ + struct gap_periodic_report_ev ev; + + ev.sync_handle = event->periodic_report.sync_handle; + ev.tx_power = event->periodic_report.tx_power; + ev.rssi = event->periodic_report.rssi; + ev.cte_type = 0xFF; + ev.data_status = event->periodic_report.data_status; + ev.data_length = event->periodic_report.data_length; + memcpy(ev.data, event->periodic_report.data, + event->periodic_report.data_length); + + tester_event(BTP_SERVICE_ID_GAP, GAP_EV_PERIODIC_REPORT, + (uint8_t *) &ev, sizeof(ev)); +} +#endif + +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) +static void +periodic_transfer_received(struct ble_gap_event *event) +{ + struct gap_periodic_transfer_recieved_ev ev; + + ev.status = event->periodic_transfer.status; + ev.sync_handle = event->periodic_transfer.sync_handle; + ev.conn_handle = event->periodic_transfer.conn_handle; + ev.service_data = event->periodic_transfer.service_data; + ev.sid = event->periodic_transfer.sid; + ev.adv_addr = event->periodic_transfer.adv_addr; + ev.adv_phy = event->periodic_transfer.adv_phy; + ev.per_adv_itvl = event->periodic_transfer.per_adv_itvl; + ev.adv_clk_accuracy = event->periodic_transfer.adv_clk_accuracy; + + tester_event(BTP_SERVICE_ID_GAP, GAP_EV_PERIODIC_TRANSFER_RECEIVED, + (uint8_t *) &ev, sizeof(ev)); +} +#endif + static void print_bytes(const uint8_t *bytes, int len) { @@ -1386,6 +1521,58 @@ gap_event_cb(struct ble_gap_event *event, void *arg) event->pairing_complete.status); } break; +#if MYNEWT_VAL(BLE_PERIODIC_ADV) + case BLE_GAP_EVENT_PERIODIC_SYNC: + console_printf("Periodic Sync established: " + "sync_handle=%d, status=%d sid=%d adv_addr=", + event->periodic_sync.sync_handle, + event->periodic_sync.status, event->periodic_sync.sid); + print_addr(event->periodic_sync.adv_addr.val); + console_printf("adv_phy=%d per_adv_ival=%d adv_clk_accuracy=%d\n", + event->periodic_sync.adv_phy, + event->periodic_sync.per_adv_ival, + event->periodic_sync.adv_clk_accuracy); + sync_established(event); + break; + case BLE_GAP_EVENT_PERIODIC_REPORT: + console_printf("Periodic Sync Report: " + "sync_handle=%d, tx_power=%d rssi=%d data_status=%d" + "data_length=%d data=", + event->periodic_report.sync_handle, + event->periodic_report.tx_power, + event->periodic_report.rssi, + event->periodic_report.data_status, + event->periodic_report.data_length); + print_bytes(event->periodic_report.data, + event->periodic_report.data_length); + console_printf("\n"); + periodic_report(event); + break; + case BLE_GAP_EVENT_PERIODIC_SYNC_LOST: + console_printf("Periodic Sync lost: " + "sync_handle=%d, reason=%d\n", + event->periodic_sync_lost.sync_handle, + event->periodic_sync_lost.reason); + sync_lost(event); + break; +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) + case BLE_GAP_EVENT_PERIODIC_TRANSFER: + console_printf("Periodic transfer received:" + "status=%d, sync_handle=%d, conn_handle=%d, service_data=%d, sid=%d addr=", + event->periodic_transfer.status, + event->periodic_transfer.sync_handle, + event->periodic_transfer.conn_handle, + event->periodic_transfer.service_data, + event->periodic_transfer.sid); + print_addr(event->periodic_sync.adv_addr.val); + console_printf(" adv_phy=%d, per_adv_itvl=%d, adv_clk_accuracy=%d\n", + event->periodic_transfer.adv_phy, + event->periodic_transfer.per_adv_itvl, + event->periodic_transfer.adv_clk_accuracy); + periodic_transfer_received(event); + break; +#endif default: break; } @@ -1766,6 +1953,213 @@ set_filter_accept_list(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +#if MYNEWT_VAL(BLE_PERIODIC_ADV) +static uint8_t +periodic_adv_configure(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct ble_gap_ext_adv_params ext_params = {0}; + struct ble_gap_periodic_adv_params params = {0}; + const struct gap_periodic_adv_configure_cmd *cp = cmd; + struct btp_gap_periodic_adv_configure_rp *rp = rsp; + + int rc; + + memset(¶ms, 0, sizeof(params)); + params.include_tx_power = cp->flags & 0x01; + params.itvl_min = cp->itvl_min; + params.itvl_max = cp->itvl_max; + + ext_params.connectable = 0; + ext_params.scannable = 0; + ext_params.legacy_pdu = 0; + ext_params.anonymous = 0; + ext_params.own_addr_type = own_addr_type; + ext_params.primary_phy = BLE_HCI_LE_PHY_1M; + ext_params.secondary_phy = BLE_HCI_LE_PHY_1M; + ext_params.sid = 1; + + rc = ble_gap_ext_adv_configure(1, &ext_params, NULL, gap_event_cb, NULL); + if (rc) { + SYS_LOG_ERR("Failed to configure extended advertiser; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + rc = ble_gap_periodic_adv_configure(1, ¶ms); + if (rc) { + SYS_LOG_ERR("Failed to configure periodic advertiser; rc=%d\n" + "params.itvl_min %d\n" + "params.itvl_max %d\n", rc, params.itvl_min, + params.itvl_max); + return BTP_STATUS_FAILED; + } + + current_settings |= BIT(BTP_GAP_SETTINGS_PERIODIC_ADVERTISING); + + rp->current_settings = htole32(current_settings); + *rsp_len = sizeof(*rp); + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +periodic_adv_start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int rc; + struct btp_gap_periodic_adv_start_rp *rp = rsp; + + rc = ble_gap_ext_adv_start(1, 0, 0); + if (rc) { + SYS_LOG_ERR("Failed to start extended advertiser; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + rc = ble_gap_periodic_adv_start(1); + if (rc) { + SYS_LOG_ERR("Failed to start periodic advertiser; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + rp->current_settings = htole32(current_settings); + *rsp_len = sizeof(*rp); + return BTP_STATUS_SUCCESS; +} + +static uint8_t +periodic_adv_set_data(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct os_mbuf *adv_data; + const struct gap_periodic_adv_set_data_cmd *cp = cmd; + int rc; + uint16_t data_len = le16toh(cp->adv_data_len); + + adv_data = os_msys_get_pkthdr(data_len, 0); + if (!adv_data) { + return BTP_STATUS_FAILED; + } + + if (os_mbuf_append(adv_data, cp->adv_data, data_len)) { + return BTP_STATUS_FAILED; + } + + rc = ble_gap_periodic_adv_set_data(1, adv_data); + if (rc) { + SYS_LOG_ERR("Failed to set periodic advertiser data; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +periodic_adv_create_sync(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct gap_periodic_adv_create_sync_cmd *cp = cmd; + struct ble_gap_periodic_sync_params params; + struct ble_gap_disc_params scan_params = {0}; + int rc; + + params.reports_disabled = BIT(0) & cp->flags; + params.skip = cp->skip; + params.sync_timeout = cp->sync_timeout; + SYS_LOG_DBG("\nreports_disabled %d\nskip %d\nsync_timeout %d\n", + params.reports_disabled, params.skip, params.sync_timeout); + + scan_params.passive = 0; + scan_params.limited = 0; + scan_params.filter_duplicates = 0; + + ble_gap_disc(own_addr_type, BLE_HS_FOREVER, &scan_params, NULL, NULL); + rc = ble_gap_periodic_adv_sync_create(&cp->addr, cp->adv_sid, ¶ms, + gap_event_cb, NULL); + if (rc) { + SYS_LOG_ERR("Failed to create sync; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) +static uint8_t +periodic_adv_sync_transfer_start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct gap_periodic_adv_sync_transfer_start_cmd *cp = cmd; + struct ble_gap_conn_desc desc; + int rc; + + rc = gap_conn_find_by_addr(&cp->addr, &desc); + if (rc) { + return BTP_STATUS_FAILED; + } + + rc = ble_gap_periodic_adv_sync_transfer(cp->sync_handle, desc.conn_handle, + cp->svc_data); + if (rc) { + SYS_LOG_ERR("Failed to initiate sync transfer; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +periodic_adv_sync_transfer_recv(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct gap_periodic_adv_sync_transfer_recv_cmd *cp = cmd; + struct ble_gap_conn_desc desc; + struct ble_gap_periodic_sync_params params; + int rc; + + rc = gap_conn_find_by_addr(&cp->addr, &desc); + if (rc) { + return BTP_STATUS_FAILED; + } + + params.reports_disabled = BIT(0) & cp->flags; + params.skip = cp->skip; + params.sync_timeout = cp->sync_timeout; + + rc = ble_gap_periodic_adv_sync_receive(desc.conn_handle, ¶ms, + gap_event_cb, NULL); + if (rc) { + SYS_LOG_ERR("Failed to receive periodic sync; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +periodic_adv_sync_transfer_set_info(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct gap_periodic_adv_sync_transfer_set_info_cmd *cp = cmd; + struct ble_gap_conn_desc desc; + int rc; + + rc = gap_conn_find_by_addr(&cp->addr, &desc); + if (rc) { + return BTP_STATUS_FAILED; + } + + rc = ble_gap_periodic_adv_sync_set_info(1, desc.conn_handle, + cp->svc_data); + if (rc) { + SYS_LOG_ERR("Failed to set info; rc=%d", rc); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} +#endif + static const struct btp_handler handlers[] = { { .opcode = BTP_GAP_READ_SUPPORTED_COMMANDS, @@ -1889,6 +2283,46 @@ static const struct btp_handler handlers[] = { .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = set_filter_accept_list, }, +#if MYNEWT_VAL(BLE_PERIODIC_ADV) + { + .opcode = GAP_PADV_CONFIGURE, + .expect_len = sizeof(struct gap_periodic_adv_configure_cmd), + .func = periodic_adv_configure, + }, + { + .opcode = GAP_PADV_START, + .expect_len = sizeof(struct gap_periodic_adv_start_cmd), + .func = periodic_adv_start, + }, + { + .opcode = GAP_PADV_SET_DATA, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = periodic_adv_set_data, + }, + { + .opcode = GAP_PADV_CREATE_SYNC, + .expect_len = sizeof(struct gap_periodic_adv_create_sync_cmd), + .func = periodic_adv_create_sync, + }, +#endif +#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) + { + .opcode = GAP_PADV_SYNC_TRANSFER_SET_INFO, + .expect_len = + sizeof(struct gap_periodic_adv_sync_transfer_set_info_cmd), + .func = periodic_adv_sync_transfer_set_info, + }, + { + .opcode = GAP_PADV_SYNC_TRANSFER_START, + .expect_len = sizeof(struct gap_periodic_adv_sync_transfer_start_cmd), + .func = periodic_adv_sync_transfer_start, + }, + { + .opcode = GAP_PADV_SYNC_TRANSFER_RECV, + .expect_len = sizeof(struct gap_periodic_adv_sync_transfer_recv_cmd), + .func = periodic_adv_sync_transfer_recv, + }, +#endif }; static void From 037c8d50ac2592948d3e20e761299e2496fa2fba Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Mon, 7 Aug 2023 15:53:46 +0200 Subject: [PATCH 0811/1333] host/gap: add and update doxygen comments for the header file Adds missing macros, functions and structures documentation. Corrects arguments names in functions documentation. --- nimble/host/include/host/ble_gap.h | 266 +++++++++++++++++++++++++++-- 1 file changed, 254 insertions(+), 12 deletions(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index c6d9dc817f..2a311db2a8 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -39,13 +39,36 @@ extern "C" { struct hci_le_conn_complete; struct hci_conn_update; +/** + * @defgroup ble_gap_ms_convert Generic Access Profile (GAP) Time Conversion Macros + * @{ + */ + +/** Convert advertising interval from milliseconds to BLE HCI units. */ #define BLE_GAP_ADV_ITVL_MS(t) ((t) * 1000 / BLE_HCI_ADV_ITVL) + +/** Convert scan interval from milliseconds to BLE HCI units. */ #define BLE_GAP_SCAN_ITVL_MS(t) ((t) * 1000 / BLE_HCI_SCAN_ITVL) + +/** Convert scan window from milliseconds to BLE HCI units. */ #define BLE_GAP_SCAN_WIN_MS(t) ((t) * 1000 / BLE_HCI_SCAN_ITVL) + +/** Convert connection interval from milliseconds to BLE HCI units. */ #define BLE_GAP_CONN_ITVL_MS(t) ((t) * 1000 / BLE_HCI_CONN_ITVL) + +/** Convert supervision timeout from milliseconds to BLE HCI units. */ #define BLE_GAP_SUPERVISION_TIMEOUT_MS(t) ((t) / 10) + +/** Convert periodic advertising interval from milliseconds to BLE HCI units. */ #define BLE_GAP_PERIODIC_ITVL_MS(t) ((t) * 1000 / BLE_HCI_PERIODIC_ADV_ITVL) +/** @} */ + +/** + * @defgroup ble_gap_intervals Generic Access Profile (GAP) Intervals and Durations + * @{ + */ + /** 30 ms. */ #define BLE_GAP_ADV_FAST_INTERVAL1_MIN BLE_GAP_ADV_ITVL_MS(30) @@ -73,7 +96,7 @@ struct hci_conn_update; /** 30 ms; active scanning. */ #define BLE_GAP_SCAN_FAST_WINDOW BLE_GAP_SCAN_WIN_MS(30) -/* 30.72 seconds; active scanning. */ +/** 30.72 seconds; active scanning. */ #define BLE_GAP_SCAN_FAST_PERIOD BLE_GAP_SCAN_ITVL_MS(30.72) /** 1.28 seconds; background scanning. */ @@ -94,56 +117,153 @@ struct hci_conn_update; /** 5 seconds. */ #define BLE_GAP_CONN_PAUSE_PERIPHERAL (5 * 1000) -/* 30 ms. */ +/** 30 ms. */ #define BLE_GAP_INITIAL_CONN_ITVL_MIN BLE_GAP_CONN_ITVL_MS(30) -/* 50 ms. */ +/** 50 ms. */ #define BLE_GAP_INITIAL_CONN_ITVL_MAX BLE_GAP_CONN_ITVL_MS(50) +/** @} */ + /** Default channels mask: all three channels are used. */ #define BLE_GAP_ADV_DFLT_CHANNEL_MAP 0x07 +/** + * @defgroup ble_gap_initial_conn_params Generic Access Profile (GAP) Initial Connection Parameters + * @{ + */ + +/** Initial connection latency. */ #define BLE_GAP_INITIAL_CONN_LATENCY 0 + +/** Initial supervision timeout. */ #define BLE_GAP_INITIAL_SUPERVISION_TIMEOUT 0x0100 + +/** Initial minimum connection event length. */ #define BLE_GAP_INITIAL_CONN_MIN_CE_LEN 0x0000 + +/** Initial maximum connection event length. */ #define BLE_GAP_INITIAL_CONN_MAX_CE_LEN 0x0000 +/** @} */ + +/** + * @defgroup ble_gap_roles Generic Access Profile (GAP) Roles + * @{ + */ + +/** GAP role: Master */ #define BLE_GAP_ROLE_MASTER 0 + +/** GAP role: Slave */ #define BLE_GAP_ROLE_SLAVE 1 +/** @} */ + +/** + * @defgroup ble_gap_events Generic Access Profile (GAP) Events + * @{ + */ + +/** GAP event: Connection established */ #define BLE_GAP_EVENT_CONNECT 0 + +/** GAP event: Connection terminated */ #define BLE_GAP_EVENT_DISCONNECT 1 + +/** GAP event: Reserved for future use */ /* Reserved 2 */ + +/** GAP event: Connection update */ #define BLE_GAP_EVENT_CONN_UPDATE 3 + +/** GAP event: Connection update request */ #define BLE_GAP_EVENT_CONN_UPDATE_REQ 4 + +/** GAP event: L2CAP update request */ #define BLE_GAP_EVENT_L2CAP_UPDATE_REQ 5 + +/** GAP event: Termination failure */ #define BLE_GAP_EVENT_TERM_FAILURE 6 + +/** GAP event: Discovery event */ #define BLE_GAP_EVENT_DISC 7 + +/** GAP event: Discovery complete */ #define BLE_GAP_EVENT_DISC_COMPLETE 8 + +/** GAP event: Advertising complete */ #define BLE_GAP_EVENT_ADV_COMPLETE 9 + +/** GAP event: Encryption change */ #define BLE_GAP_EVENT_ENC_CHANGE 10 + +/** GAP event: Passkey action */ #define BLE_GAP_EVENT_PASSKEY_ACTION 11 + +/** GAP event: Notification received */ #define BLE_GAP_EVENT_NOTIFY_RX 12 + +/** GAP event: Notification transmitted */ #define BLE_GAP_EVENT_NOTIFY_TX 13 + +/** GAP event: Subscription */ #define BLE_GAP_EVENT_SUBSCRIBE 14 + +/** GAP event: MTU event */ #define BLE_GAP_EVENT_MTU 15 + +/** GAP event: Identity resolved */ #define BLE_GAP_EVENT_IDENTITY_RESOLVED 16 + +/** GAP event: Repeat pairing */ #define BLE_GAP_EVENT_REPEAT_PAIRING 17 + +/** GAP event: PHY update complete */ #define BLE_GAP_EVENT_PHY_UPDATE_COMPLETE 18 + +/** GAP event: Extended discovery */ #define BLE_GAP_EVENT_EXT_DISC 19 + +/** GAP event: Periodic synchronization */ #define BLE_GAP_EVENT_PERIODIC_SYNC 20 + +/** GAP event: Periodic report */ #define BLE_GAP_EVENT_PERIODIC_REPORT 21 + +/** GAP event: Periodic synchronization lost */ #define BLE_GAP_EVENT_PERIODIC_SYNC_LOST 22 + +/** GAP event: Scan request received */ #define BLE_GAP_EVENT_SCAN_REQ_RCVD 23 + +/** GAP event: Periodic transfer */ #define BLE_GAP_EVENT_PERIODIC_TRANSFER 24 + +/** GAP event: Pathloss threshold */ #define BLE_GAP_EVENT_PATHLOSS_THRESHOLD 25 + +/** GAP event: Transmit power */ #define BLE_GAP_EVENT_TRANSMIT_POWER 26 + +/** GAP event: Pairing complete */ #define BLE_GAP_EVENT_PARING_COMPLETE 27 + +/** GAP event: Subrate change */ #define BLE_GAP_EVENT_SUBRATE_CHANGE 28 + +/** GAP event: Vendor specific HCI event */ #define BLE_GAP_EVENT_VS_HCI 29 + +/** GAP event: BIG (Broadcast Isochronous Group) information report */ #define BLE_GAP_EVENT_BIGINFO_REPORT 30 -/*** Reason codes for the subscribe GAP event. */ +/** @} */ + +/** + * @defgroup ble_gap_subscribe_reasons Generic Access Profile (GAP) Subscribe Event Reason Codes + * @{ + */ /** Peer's CCCD subscription state changed due to a descriptor write. */ #define BLE_GAP_SUBSCRIBE_REASON_WRITE 1 @@ -157,9 +277,21 @@ struct hci_conn_update; */ #define BLE_GAP_SUBSCRIBE_REASON_RESTORE 3 +/** @} */ + +/** + * @defgroup ble_gap_repeat_pairing_options Generic Access Profile (GAP) Repeat Pairing Options + * @{ + */ + +/** GAP repeat pairing option: Retry the pairing procedure. */ #define BLE_GAP_REPEAT_PAIRING_RETRY 1 + +/** GAP repeat pairing option: Ignore the pairing procedure. */ #define BLE_GAP_REPEAT_PAIRING_IGNORE 2 +/** @} */ + /** Connection security state */ struct ble_gap_sec_state { /** If connection is encrypted */ @@ -442,22 +574,53 @@ struct ble_gap_disc_desc { ble_addr_t direct_addr; }; +/** + * Represents a repeat pairing operation between two devices. + * + * This structure contains information about a repeat pairing operation between + * two devices. The host can use this information to determine whether it needs + * to initiate a pairing procedure with a remote device again. + */ struct ble_gap_repeat_pairing { /** The handle of the relevant connection. */ uint16_t conn_handle; /** Properties of the existing bond. */ + /** The size of the current encryption key in octets. */ uint8_t cur_key_size; + + /** A flag indicating whether the current connection is authenticated. */ uint8_t cur_authenticated:1; + + /** + * A flag indicating whether the current connection is using secure + * connections. + */ uint8_t cur_sc:1; /** * Properties of the imminent secure link if the pairing procedure is * allowed to continue. */ + + /** The size of the imminent encryption key in octets. */ uint8_t new_key_size; + + /** + * A flag indicating whether the imminent connection will be authenticated. + */ uint8_t new_authenticated:1; + + /** + * A flag indicating whether the imminent connection will use secure + * connections. + */ uint8_t new_sc:1; + + /** + * A flag indicating whether the pairing procedure will result in a new + * bonding, + */ uint8_t new_bonding:1; }; @@ -1140,17 +1303,39 @@ struct ble_gap_event { }; }; +/** Callback function type for handling BLE GAP events. */ typedef int ble_gap_event_fn(struct ble_gap_event *event, void *arg); + +/** Callback function type for iterating through BLE connection handles. */ typedef int ble_gap_conn_foreach_handle_fn(uint16_t conn_handle, void *arg); +/** + * @defgroup ble_gap_advertising_modes Generic Access Profile (GAP) Advertising Modes + * @{ + */ + +/** Non-connectable mode for advertising. */ #define BLE_GAP_CONN_MODE_NON 0 + +/** Directed connectable mode for advertising. */ #define BLE_GAP_CONN_MODE_DIR 1 + +/** Undirected connectable mode for advertising. */ #define BLE_GAP_CONN_MODE_UND 2 + +/** Non-discoverable mode for advertising. */ #define BLE_GAP_DISC_MODE_NON 0 + +/** Limited discoverable mode for advertising. */ #define BLE_GAP_DISC_MODE_LTD 1 + +/** General discoverable mode for advertising. */ #define BLE_GAP_DISC_MODE_GEN 2 +/** @} */ + + /** * Searches for a connection with the specified handle. If a matching * connection is found, the supplied connection descriptor is filled @@ -1294,13 +1479,13 @@ int ble_gap_adv_rsp_set_data(const uint8_t *data, int data_len); * fit in an advertisement, * other error code on failure. */ -int ble_gap_adv_set_fields(const struct ble_hs_adv_fields *rsp_fields); +int ble_gap_adv_set_fields(const struct ble_hs_adv_fields *adv_fields); /** * Configures the fields to include in subsequent scan responses. This is a * convenience wrapper for ble_gap_adv_rsp_set_data(). * - * @param adv_fields Specifies the scan response data. + * @param rsp_fields Specifies the scan response data. * * @return 0 on success, * BLE_HS_EBUSY if advertising is in progress, @@ -1852,7 +2037,7 @@ int ble_gap_disc_active(void); * On expiration, the procedure ends and a * BLE_GAP_EVENT_DISC_COMPLETE event is * reported. Units are milliseconds. - * @param conn_params Additional arguments specifying the particulars + * @param params Additional arguments specifying the particulars * of the connect procedure. Specify null for * default values. * @param cb The callback to associate with this connect @@ -2099,7 +2284,7 @@ int ble_gap_pair_initiate(uint16_t conn_handle); * start encryption. * @param key_size Encryption key size * @param ltk Long Term Key to be used for encryption. - * @param udiv Encryption Diversifier for LTK + * @param ediv Encryption Diversifier for LTK * @param rand_val Random Value for EDIV and LTK * @param auth If LTK provided is authenticated. * @@ -2171,9 +2356,20 @@ int ble_gap_unpair_oldest_peer(void); */ int ble_gap_unpair_oldest_except(const ble_addr_t *peer_addr); +/** + * @defgroup ble_gap_privacy_modes Generic Access Profile (GAP) Privacy Modes + * @{ + */ + +/** Network privacy mode. */ #define BLE_GAP_PRIVATE_MODE_NETWORK 0 + +/** Device privacy mode. */ #define BLE_GAP_PRIVATE_MODE_DEVICE 1 +/** @} */ + + /** * Set privacy mode for specified peer device * @@ -2187,9 +2383,22 @@ int ble_gap_unpair_oldest_except(const ble_addr_t *peer_addr); */ int ble_gap_set_priv_mode(const ble_addr_t *peer_addr, uint8_t priv_mode); +/** + * @defgroup ble_gap_physical_layers Generic Access Profile (GAP) Physical Layers + * @{ + */ + +/** Physical layer: 1M PHY. */ #define BLE_GAP_LE_PHY_1M 1 + +/** Physical layer: 2M PHY. */ #define BLE_GAP_LE_PHY_2M 2 + +/** Physical layer: Coded PHY. */ #define BLE_GAP_LE_PHY_CODED 3 + +/** @} */ + /** * Read PHYs used for specified connection. * @@ -2209,20 +2418,35 @@ int ble_gap_set_priv_mode(const ble_addr_t *peer_addr, uint8_t priv_mode); */ int ble_gap_read_le_phy(uint16_t conn_handle, uint8_t *tx_phy, uint8_t *rx_phy); +/** + * @defgroup ble_gap_phy_masks Generic Access Profile (GAP) PHY Masks + * @{ + */ + +/** Bitmask for 1M PHY. */ #define BLE_GAP_LE_PHY_1M_MASK 0x01 + +/** Bitmask for 2M PHY. */ #define BLE_GAP_LE_PHY_2M_MASK 0x02 + +/** Bitmask for Coded PHY. */ #define BLE_GAP_LE_PHY_CODED_MASK 0x04 + +/** Bitmask for any PHY. */ #define BLE_GAP_LE_PHY_ANY_MASK 0x0F + +/** @} */ + /** * Set preferred default PHYs to be used for connections. * - * @params tx_phys_mask Preferred TX PHY. Can be mask of following + * @param tx_phys_mask Preferred TX PHY. Can be mask of following * constants: * - BLE_GAP_LE_PHY_1M_MASK * - BLE_GAP_LE_PHY_2M_MASK * - BLE_GAP_LE_PHY_CODED_MASK * - BLE_GAP_LE_PHY_ANY_MASK - * @params rx_phys_mask Preferred RX PHY. Can be mask of following + * @param rx_phys_mask Preferred RX PHY. Can be mask of following * constants: * - BLE_GAP_LE_PHY_1M_MASK * - BLE_GAP_LE_PHY_2M_MASK @@ -2234,20 +2458,33 @@ int ble_gap_read_le_phy(uint16_t conn_handle, uint8_t *tx_phy, uint8_t *rx_phy); int ble_gap_set_prefered_default_le_phy(uint8_t tx_phys_mask, uint8_t rx_phys_mask); +/** + * @defgroup ble_gap_coded_phy_schemes Generic Access Profile (GAP) Coded PHY Schemes + * @{ + */ + +/** Coded PHY: any coding scheme. */ #define BLE_GAP_LE_PHY_CODED_ANY 0 + +/** Coded PHY: S2 coding scheme. */ #define BLE_GAP_LE_PHY_CODED_S2 1 + +/** Coded PHY: S8 coding scheme. */ #define BLE_GAP_LE_PHY_CODED_S8 2 + +/** @} */ + /** * Set preferred PHYs to be used for connection. * * @param conn_handle Connection handle - * @params tx_phys_mask Preferred TX PHY. Can be mask of following + * @param tx_phys_mask Preferred TX PHY. Can be mask of following * constants: * - BLE_GAP_LE_PHY_1M_MASK * - BLE_GAP_LE_PHY_2M_MASK * - BLE_GAP_LE_PHY_CODED_MASK * - BLE_GAP_LE_PHY_ANY_MASK - * @params rx_phys_mask Preferred RX PHY. Can be mask of following + * @param rx_phys_mask Preferred RX PHY. Can be mask of following * constants: * - BLE_GAP_LE_PHY_1M_MASK * - BLE_GAP_LE_PHY_2M_MASK @@ -2308,8 +2545,13 @@ ble_gap_subrate_req(uint16_t conn_handle, uint16_t subrate_min, uint16_t subrate * This should be used as an opaque structure and not modified manually. */ struct ble_gap_event_listener { + /** The function to call when a GAP event occurs. */ ble_gap_event_fn *fn; + + /** An optional argument to pass to the event handler function. */ void *arg; + + /** Singly-linked list entry. */ SLIST_ENTRY(ble_gap_event_listener) link; }; From cb41532dc8c4919c9e24deae7ef3974fe6396985 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Fri, 11 Aug 2023 16:21:17 +0200 Subject: [PATCH 0812/1333] host/hs_adv: add and update doxygen comments for the header file Adds missing macros, functions and structures documentation. --- nimble/host/include/host/ble_hs_adv.h | 225 ++++++++++++++++++++++++-- 1 file changed, 210 insertions(+), 15 deletions(-) diff --git a/nimble/host/include/host/ble_hs_adv.h b/nimble/host/include/host/ble_hs_adv.h index e3b6ea7098..fabeca64dc 100644 --- a/nimble/host/include/host/ble_hs_adv.h +++ b/nimble/host/include/host/ble_hs_adv.h @@ -20,6 +20,13 @@ #ifndef H_BLE_HS_ADV_ #define H_BLE_HS_ADV_ +/** + * @brief Bluetooth Host Advertising API + * @defgroup bt_adv Bluetooth Host Advertising API + * @ingroup bt_host + * @{ + */ + #include #include "host/ble_uuid.h" @@ -27,115 +34,245 @@ extern "C" { #endif +/** Max Advertising Data Size. */ #define BLE_HS_ADV_MAX_SZ BLE_HCI_MAX_ADV_DATA_LEN /** Max field payload size (account for 2-byte header). */ #define BLE_HS_ADV_MAX_FIELD_SZ (BLE_HS_ADV_MAX_SZ - 2) +/** Represents advertising data packet in BLE advertisement or scan response. */ struct ble_hs_adv_field { + /** Length of the advertising data (type and value). */ uint8_t length; + + /** Type of the advertising data field. */ uint8_t type; + + /** Value of the advertising data field. */ uint8_t value[0]; }; +/** Function pointer typedef for parsing an advertising data field. */ typedef int (* ble_hs_adv_parse_func_t) (const struct ble_hs_adv_field *, void *); +/** Advertising Data Fields. */ struct ble_hs_adv_fields { - /*** 0x01 - Flags. */ + /** 0x01 - Flags. */ uint8_t flags; - /*** 0x02,0x03 - 16-bit service class UUIDs. */ + /** 0x02,0x03 - 16-bit service class UUIDs. */ const ble_uuid16_t *uuids16; + + /** Number of 16-bit UUIDs. */ uint8_t num_uuids16; + + /** Indicates if the list of 16-bit UUIDs is complete. */ unsigned uuids16_is_complete:1; - /*** 0x04,0x05 - 32-bit service class UUIDs. */ + + /** 0x04,0x05 - 32-bit service class UUIDs. */ const ble_uuid32_t *uuids32; + + /** Number of 32-bit UUIDs. */ uint8_t num_uuids32; + + /** Indicates if the list of 32-bit UUIDs is complete. */ unsigned uuids32_is_complete:1; - /*** 0x06,0x07 - 128-bit service class UUIDs. */ + + /** 0x06,0x07 - 128-bit service class UUIDs. */ const ble_uuid128_t *uuids128; + + /** Number of 128-bit UUIDs. */ uint8_t num_uuids128; + + /** Indicates if the list of 128-bit UUIDs is complete. */ unsigned uuids128_is_complete:1; - /*** 0x08,0x09 - Local name. */ + + /** 0x08,0x09 - Local name. */ const uint8_t *name; + + /** Length of the local name. */ uint8_t name_len; + + /** Indicates if the list of local names if complete. */ unsigned name_is_complete:1; - /*** 0x0a - Tx power level. */ + + /** 0x0a - Tx power level. */ int8_t tx_pwr_lvl; + + /** Indicates if Tx power level is present. */ unsigned tx_pwr_lvl_is_present:1; - /*** 0x0d - Slave connection interval range. */ + + /** 0x12 - Slave connection interval range. */ const uint8_t *slave_itvl_range; - /*** 0x16 - Service data - 16-bit UUID. */ + /** 0x16 - Service data - 16-bit UUID. */ const uint8_t *svc_data_uuid16; + + /** Length of the service data with 16-bit UUID. */ uint8_t svc_data_uuid16_len; - /*** 0x17 - Public target address. */ + + /** 0x17 - Public target address. */ const uint8_t *public_tgt_addr; + + /** Number of public target addresses. */ uint8_t num_public_tgt_addrs; - /*** 0x19 - Appearance. */ + /** 0x19 - Appearance. */ uint16_t appearance; + + /** Indicates if Appearance is present. */ unsigned appearance_is_present:1; - /*** 0x1a - Advertising interval. */ + + /** 0x1a - Advertising interval. */ uint16_t adv_itvl; + + /** Indicates if advertising interval is present. */ unsigned adv_itvl_is_present:1; - /*** 0x20 - Service data - 32-bit UUID. */ + + /** 0x20 - Service data - 32-bit UUID. */ const uint8_t *svc_data_uuid32; + + /** Length of the service data with 32-bit UUID. */ uint8_t svc_data_uuid32_len; - /*** 0x21 - Service data - 128-bit UUID. */ + + /** 0x21 - Service data - 128-bit UUID. */ const uint8_t *svc_data_uuid128; + + /** Length of service data with 128-bit UUID. */ uint8_t svc_data_uuid128_len; - /*** 0x24 - URI. */ + + /** 0x24 - URI. */ const uint8_t *uri; + + /** Length of the URI. */ uint8_t uri_len; - /*** 0xff - Manufacturer specific data. */ + + /** 0xff - Manufacturer specific data. */ const uint8_t *mfg_data; + + /** Length of manufacturer specific data. */ uint8_t mfg_data_len; }; +/** + * @defgroup ble_hs_adv_types BLE Advertising Common Data Types + * @{ + */ + +/** Common Data Type: Flags. */ #define BLE_HS_ADV_TYPE_FLAGS 0x01 + +/** Common Data Type: Incomplete List of 16-bit Service Class UUIDs. */ #define BLE_HS_ADV_TYPE_INCOMP_UUIDS16 0x02 + +/** Common Data Type: Complete List of 16-bit Service Class UUIDs. */ #define BLE_HS_ADV_TYPE_COMP_UUIDS16 0x03 + +/** Common Data Type: Incomplete List of 32-bit Service Class UUIDs. */ #define BLE_HS_ADV_TYPE_INCOMP_UUIDS32 0x04 + +/** Common Data Type: Complete List of 32-bit Service Class UUIDs. */ #define BLE_HS_ADV_TYPE_COMP_UUIDS32 0x05 + +/** Common Data Type: Incomplete List of 128-bit Service Class UUIDs. */ #define BLE_HS_ADV_TYPE_INCOMP_UUIDS128 0x06 + +/** Common Data Type: Complete List of 128-bit Service Class UUIDs. */ #define BLE_HS_ADV_TYPE_COMP_UUIDS128 0x07 + +/** Common Data Type: Shortened Local Name. */ #define BLE_HS_ADV_TYPE_INCOMP_NAME 0x08 + +/** Common Data Type: Complete Local Name. */ #define BLE_HS_ADV_TYPE_COMP_NAME 0x09 + +/** Common Data Type: Tx Power Level. */ #define BLE_HS_ADV_TYPE_TX_PWR_LVL 0x0a + +/** Common Data Type: Peripheral Connection Interval Range. */ #define BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE 0x12 + +/** Common Data Type: List of 16-bit Service Solicitation UUIDs. */ #define BLE_HS_ADV_TYPE_SOL_UUIDS16 0x14 + +/** Common Data Type: List of 128-bit Service Solicitation UUIDs. */ #define BLE_HS_ADV_TYPE_SOL_UUIDS128 0x15 + +/** Common Data Type: Service Data - 16-bit UUID. */ #define BLE_HS_ADV_TYPE_SVC_DATA_UUID16 0x16 + +/** Common Data Type: Public Target Address. */ #define BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR 0x17 + +/** Common Data Type: Random Target Address. */ #define BLE_HS_ADV_TYPE_RANDOM_TGT_ADDR 0x18 + +/** Common Data Type: Appearance. */ #define BLE_HS_ADV_TYPE_APPEARANCE 0x19 + +/** Common Data Type: Advertising Interval. */ #define BLE_HS_ADV_TYPE_ADV_ITVL 0x1a + +/** Common Data Type: Service Data - 32-bit UUID. */ #define BLE_HS_ADV_TYPE_SVC_DATA_UUID32 0x20 + +/** Common Data Type: Service Data - 128-bit UUID. */ #define BLE_HS_ADV_TYPE_SVC_DATA_UUID128 0x21 + +/** Common Data Type: URI. */ #define BLE_HS_ADV_TYPE_URI 0x24 + +/** Common Data Type: PB-ADV. */ #define BLE_HS_ADV_TYPE_MESH_PROV 0x29 + +/** Common Data Type: Mesh Message. */ #define BLE_HS_ADV_TYPE_MESH_MESSAGE 0x2a + +/** Common Data Type: Mesh Beacon. */ #define BLE_HS_ADV_TYPE_MESH_BEACON 0x2b + +/** Common Data Type: Manufacturer Specific Data. */ #define BLE_HS_ADV_TYPE_MFG_DATA 0xff +/** + * @} + */ + +/** + * @defgroup ble_hs_adv_flags BLE Advertising Flags + * @{ + */ +/** Length of BLE Advertising Flags field. */ #define BLE_HS_ADV_FLAGS_LEN 1 + +/** Limited Discoverable Mode Flag. */ #define BLE_HS_ADV_F_DISC_LTD 0x01 + +/** General Discoverable Mode Flag. */ #define BLE_HS_ADV_F_DISC_GEN 0x02 + +/** BR/EDR Not Supported Flag. */ #define BLE_HS_ADV_F_BREDR_UNSUP 0x04 +/** @} */ + +/** + * @defgroup ble_hs_adv_misc BLE Advertising Miscellaneous + * @{ + */ +/** Length of BLE advertising transmit power level field. */ #define BLE_HS_ADV_TX_PWR_LVL_LEN 1 /** @@ -144,29 +281,83 @@ struct ble_hs_adv_fields { */ #define BLE_HS_ADV_TX_PWR_LVL_AUTO (-128) +/** Length of the Peripheral Connection Interval Range field. */ #define BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN 4 +/** Minimum length of the Service Data - 16-bit UUID field. */ #define BLE_HS_ADV_SVC_DATA_UUID16_MIN_LEN 2 +/** Length of a Public Target Address entry. */ #define BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN 6 +/** Length of the Appearance field. */ #define BLE_HS_ADV_APPEARANCE_LEN 2 +/** Length of the Advertising Interval field. */ #define BLE_HS_ADV_ADV_ITVL_LEN 2 +/** Minimum length of the Service Data - 32-bit UUID field. */ #define BLE_HS_ADV_SVC_DATA_UUID32_MIN_LEN 4 +/** Minimum length of the Service Data - 128-bit UUID field. */ #define BLE_HS_ADV_SVC_DATA_UUID128_MIN_LEN 16 +/** + * @} + */ + +/** + * Set the advertising data fields in an os_mbuf. + * + * @param adv_fields Pointer to the advertising data structure. + * @param om Pointer to the memory buffer that will be written with + * advertising data. + * + * @return 0 on success; non-zero on failure. + */ int ble_hs_adv_set_fields_mbuf(const struct ble_hs_adv_fields *adv_fields, struct os_mbuf *om); +/** + * Set the advertising data fields in a destination buffer. + * + * @param adv_fields Pointer to the advertising data structure. + * @param dst Pointer to the destination buffer that will be written + * with advertising data. + * @param dst_len Pointer to the variable that will hold the length of + * the data written. + * @param max_len Maximum length of the destination buffer. + * + * @return 0 on success; nonzero on failure. + */ int ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields, uint8_t *dst, uint8_t *dst_len, uint8_t max_len); +/** + * Parse the advertising data fields from a source buffer. + * + * @param adv_fields Pointer to the advertising data fields structure + * to populate. + * @param src Pointer to the source buffer containing the data + * to parse. + * @param src_len Length of the source buffer. + * + * @return 0 on success; nonzero on failure. + */ int ble_hs_adv_parse_fields(struct ble_hs_adv_fields *adv_fields, const uint8_t *src, uint8_t src_len); +/** + * Parse the advertising data using the provided parsing function. + * + * @param data Pointer to the advertising data buffer to parse. + * @param length Length of the advertising data buffer. + * @param func Pointer to the parsing function to apply to each + * field. + * @param user_data User-defined data to pass to the parsing function. + * + * @return 0 on success; nonzero on failure. + */ int ble_hs_adv_parse(const uint8_t *data, uint8_t length, ble_hs_adv_parse_func_t func, void *user_data); @@ -174,4 +365,8 @@ int ble_hs_adv_parse(const uint8_t *data, uint8_t length, } #endif +/** + * @} + */ + #endif From a35cb28ef066ee32ef0b24991f5b2f9e8ea4bc25 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 15 Sep 2023 16:41:18 +0200 Subject: [PATCH 0813/1333] nimble/ll: Drop received PDU if it is handled after scan was stopped When doing continuous scan and channel is changed close to scan stop it is possible that PDU is received before interval timer is cancelled and RX is disabled. This may lead to processing received PDU only after scanner is already stopped. While this case was already handled in LL task it was not correctly handled in ISR. If this happen simply mark PDU to be ignored by LL and don't process it in ISR. This is more likely to happen when small scan window is used. Mostly affects initiator state as this may lead to assert when happen after CONNECTION_IND was already sent. --- nimble/controller/include/controller/ble_ll.h | 1 + nimble/controller/src/ble_ll.c | 1 + nimble/controller/src/ble_ll_scan.c | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 408f03b690..7247f31df4 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -179,6 +179,7 @@ STATS_SECT_START(ble_ll_stats) STATS_SECT_ENTRY(rx_connect_reqs) STATS_SECT_ENTRY(rx_scan_ind) STATS_SECT_ENTRY(rx_aux_connect_rsp) + STATS_SECT_ENTRY(rx_pdu_on_scan_disabled) STATS_SECT_ENTRY(adv_txg) STATS_SECT_ENTRY(adv_late_starts) STATS_SECT_ENTRY(adv_resched_pdu_fail) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 84475c32b2..fd96f7d625 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -320,6 +320,7 @@ STATS_NAME_START(ble_ll_stats) STATS_NAME(ble_ll_stats, rx_connect_reqs) STATS_NAME(ble_ll_stats, rx_scan_ind) STATS_NAME(ble_ll_stats, rx_aux_connect_rsp) + STATS_NAME(ble_ll_stats, rx_pdu_on_scan_disabled) STATS_NAME(ble_ll_stats, adv_txg) STATS_NAME(ble_ll_stats, adv_late_starts) STATS_NAME(ble_ll_stats, adv_resched_pdu_fail) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index d1c3c8ad7d..445cbb58f6 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1610,6 +1610,11 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) goto scan_rx_isr_ignore; } + if (!scansm->scan_enabled) { + STATS_INC(ble_ll_stats, rx_pdu_on_scan_disabled); + goto scan_rx_isr_ignore; + } + rxbuf = rxpdu->om_data; pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK; From c1e26371c6fed7a18e7b6d06b0b182a2bafba969 Mon Sep 17 00:00:00 2001 From: Deomid Ryabkov Date: Thu, 14 Sep 2023 03:27:04 +0100 Subject: [PATCH 0814/1333] Fix a bug in ble_l2cap_sig_extract_expired Next should be updated to point at the previous element in the list for removal to work correctly. --- nimble/host/src/ble_l2cap_sig.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index 42459179bb..029e855383 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -1905,9 +1905,10 @@ ble_l2cap_sig_extract_expired(struct ble_l2cap_sig_proc_list *dst_list) ble_hs_lock(); - prev = NULL; + next = NULL; proc = STAILQ_FIRST(&ble_l2cap_sig_procs); while (proc != NULL) { + prev = next; next = STAILQ_NEXT(proc, next); time_diff = proc->exp_os_ticks - now; From 9d4f474bf8c867a289e8111aa1cc43fedf7b0b62 Mon Sep 17 00:00:00 2001 From: Hang Fan Date: Sun, 10 Sep 2023 14:33:07 +0800 Subject: [PATCH 0815/1333] porting/linux: fix deadlock in ble_npl_hw_enter_critical Fix wrong mutex attributes in pthread_mutexattr_settype. It can cause deadlock after locked. Signed-off-by: Hang Fan --- porting/npl/linux/src/os_atomic.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/porting/npl/linux/src/os_atomic.c b/porting/npl/linux/src/os_atomic.c index b01e234b08..743a8470e2 100644 --- a/porting/npl/linux/src/os_atomic.c +++ b/porting/npl/linux/src/os_atomic.c @@ -23,21 +23,21 @@ #include "nimble/nimble_npl.h" -static pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER; +static struct ble_npl_mutex s_mutex; static uint8_t s_mutex_inited = 0; uint32_t ble_npl_hw_enter_critical(void) { if( !s_mutex_inited ) { - pthread_mutexattr_settype(&s_mutex, PTHREAD_MUTEX_RECURSIVE); + ble_npl_mutex_init(&s_mutex); s_mutex_inited = 1; } - pthread_mutex_lock(&s_mutex); + pthread_mutex_lock(&s_mutex.lock); return 0; } void ble_npl_hw_exit_critical(uint32_t ctx) { - pthread_mutex_unlock(&s_mutex); + pthread_mutex_unlock(&s_mutex.lock); } From 829e47bba4eeedde401d7894d9bdfd85f1a00596 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Tue, 11 Jul 2023 15:42:14 +0530 Subject: [PATCH 0816/1333] nimble/host: Added return type handling for npl_mutex_init --- nimble/host/src/ble_gap.c | 7 ++++++- nimble/transport/src/monitor.c | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 9390708f9b..3a63050b40 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -6596,7 +6596,12 @@ ble_gap_init(void) memset(&ble_gap_sync, 0, sizeof(ble_gap_sync)); #endif - ble_npl_mutex_init(&preempt_done_mutex); + rc = ble_npl_mutex_init(&preempt_done_mutex); + + if (rc) { + BLE_HS_LOG(ERROR, "mutex init failed with reason %d \n", rc); + return rc; + } SLIST_INIT(&ble_gap_update_entries); SLIST_INIT(&ble_gap_event_listener_list); diff --git a/nimble/transport/src/monitor.c b/nimble/transport/src/monitor.c index b21dd93058..c67b18df21 100644 --- a/nimble/transport/src/monitor.c +++ b/nimble/transport/src/monitor.c @@ -299,6 +299,7 @@ void ble_monitor_init(void) { SYSINIT_ASSERT_ACTIVE(); + ble_npl_error_t rc; #if MYNEWT_VAL(BLE_MONITOR_UART) struct uart_conf uc = { @@ -340,7 +341,8 @@ ble_monitor_init(void) SYSINIT_PANIC_ASSERT(rtt_index >= 0); #endif - ble_npl_mutex_init(&lock); + rc = ble_npl_mutex_init(&lock); + SYSINIT_PANIC_ASSERT(rc == 0); #if BLE_MONITOR ble_monitor_new_index(0, (uint8_t[6]){ }, "nimble0"); From 0bfb9b2bd780c9e52c93750a09b89e7fe6353f0b Mon Sep 17 00:00:00 2001 From: CW-B-W Date: Thu, 17 Aug 2023 04:04:58 +0800 Subject: [PATCH 0817/1333] transport/hci_h4: fix compilation error min() was not defined --- nimble/transport/common/hci_h4/src/hci_h4.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nimble/transport/common/hci_h4/src/hci_h4.c b/nimble/transport/common/hci_h4/src/hci_h4.c index ea30f4293b..e787bf5ef2 100644 --- a/nimble/transport/common/hci_h4/src/hci_h4.c +++ b/nimble/transport/common/hci_h4/src/hci_h4.c @@ -27,6 +27,14 @@ #include #include +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef max +#define max(a, b) ((a) > (b) ? (a) : (b)) +#endif + #define HCI_H4_SM_W4_PKT_TYPE 0 #define HCI_H4_SM_W4_HEADER 1 #define HCI_H4_SM_W4_PAYLOAD 2 From bf761837418da4cc1d55abb4be50b8308e7bf18a Mon Sep 17 00:00:00 2001 From: CW-B-W Date: Thu, 17 Aug 2023 04:43:29 +0800 Subject: [PATCH 0818/1333] porting/nimble_port: fix controller not initialized When using external controller, ble_transport_ll_init() was not run because of NIMBLE_CFG_CONTROLLER was not defined. But under current architecture ble_transport_ll_init() should also be run to initialize the communication interface. --- porting/nimble/src/nimble_port.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/porting/nimble/src/nimble_port.c b/porting/nimble/src/nimble_port.c index 1bd57f2b04..bb26f22a3f 100644 --- a/porting/nimble/src/nimble_port.c +++ b/porting/nimble/src/nimble_port.c @@ -22,9 +22,9 @@ #include "sysinit/sysinit.h" #include "host/ble_hs.h" #include "nimble/nimble_port.h" +#include "nimble/transport.h" #if NIMBLE_CFG_CONTROLLER #include "controller/ble_ll.h" -#include "nimble/transport.h" #endif static struct ble_npl_eventq g_eventq_dflt; @@ -50,8 +50,10 @@ nimble_port_init(void) hal_timer_init(5, NULL); os_cputime_init(32768); #endif - ble_transport_ll_init(); #endif + + /* Initialize the controller */ + ble_transport_ll_init(); } void From 912d0ee13cd4be88189fdbc2b40b2a83f4236031 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Tue, 22 Aug 2023 14:39:49 +0200 Subject: [PATCH 0819/1333] host/eddystone: add and update doxygen comments for the header file Adds missing macros documentation and corrects an argument name in function's header. --- nimble/host/include/host/ble_eddystone.h | 51 +++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/nimble/host/include/host/ble_eddystone.h b/nimble/host/include/host/ble_eddystone.h index 76b7e2b01e..3b75fdccf9 100644 --- a/nimble/host/include/host/ble_eddystone.h +++ b/nimble/host/include/host/ble_eddystone.h @@ -34,30 +34,79 @@ extern "C" { struct ble_hs_adv_fields; +/** + * @defgroup ble_eddystone Eddystone Constants + * @ingroup bt_host + * @{ + */ + +/** Maximum number of 16-bit UUIDs in Eddystone advertisement data. */ #define BLE_EDDYSTONE_MAX_UUIDS16 3 + +/** Maximum length of Eddystone URL. */ #define BLE_EDDYSTONE_URL_MAX_LEN 17 + +/** Eddystone URL Scheme: "http://www./" prefix. */ #define BLE_EDDYSTONE_URL_SCHEME_HTTP_WWW 0 + +/** Eddystone URL Scheme: "https://www./" prefix. */ #define BLE_EDDYSTONE_URL_SCHEME_HTTPS_WWW 1 + +/** Eddystone URL Scheme: "http://" prefix. */ #define BLE_EDDYSTONE_URL_SCHEME_HTTP 2 + +/** Eddystone URL Scheme: "https://" prefix. */ #define BLE_EDDYSTONE_URL_SCHEME_HTTPS 3 + +/** Eddystone URL Suffix: ".com/". */ #define BLE_EDDYSTONE_URL_SUFFIX_COM_SLASH 0x00 + +/** Eddystone URL Suffix: ".org/". */ #define BLE_EDDYSTONE_URL_SUFFIX_ORG_SLASH 0x01 + +/** Eddystone URL Suffix: ".edu/". */ #define BLE_EDDYSTONE_URL_SUFFIX_EDU_SLASH 0x02 + +/** Eddystone URL Suffix: ".net/". */ #define BLE_EDDYSTONE_URL_SUFFIX_NET_SLASH 0x03 + +/** Eddystone URL Suffix: ".info/". */ #define BLE_EDDYSTONE_URL_SUFFIX_INFO_SLASH 0x04 + +/** Eddystone URL Suffix: ".biz/". */ #define BLE_EDDYSTONE_URL_SUFFIX_BIZ_SLASH 0x05 + +/** Eddystone URL Suffix: ".gov/". */ #define BLE_EDDYSTONE_URL_SUFFIX_GOV_SLASH 0x06 + +/** Eddystone URL Suffix: ".com". */ #define BLE_EDDYSTONE_URL_SUFFIX_COM 0x07 + +/** Eddystone URL Suffix: ".org". */ #define BLE_EDDYSTONE_URL_SUFFIX_ORG 0x08 + +/** Eddystone URL Suffix: ".edu". */ #define BLE_EDDYSTONE_URL_SUFFIX_EDU 0x09 + +/** Eddystone URL Suffix: ".net". */ #define BLE_EDDYSTONE_URL_SUFFIX_NET 0x0a + +/** Eddystone URL Suffix: ".info". */ #define BLE_EDDYSTONE_URL_SUFFIX_INFO 0x0b + +/** Eddystone URL Suffix: ".biz". */ #define BLE_EDDYSTONE_URL_SUFFIX_BIZ 0x0c + +/** Eddystone URL Suffix: ".gov". */ #define BLE_EDDYSTONE_URL_SUFFIX_GOV 0x0d + +/** Eddystone URL Suffix: None. */ #define BLE_EDDYSTONE_URL_SUFFIX_NONE 0xff +/** @} */ + /** * Configures the device to advertise Eddystone UID beacons. * @@ -103,7 +152,7 @@ int ble_eddystone_set_adv_data_uid(struct ble_hs_adv_fields *adv_fields, */ int ble_eddystone_set_adv_data_url(struct ble_hs_adv_fields *adv_fields, uint8_t url_scheme, char *url_body, - uint8_t url_body_len, uint8_t suffix, + uint8_t url_body_len, uint8_t url_suffix, int8_t measured_power); #ifdef __cplusplus From 5dc71f25cfad5380d3cfefc8daedfbc57ecef250 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 20 Sep 2023 09:42:14 +0200 Subject: [PATCH 0820/1333] ci: Don't build all targets on Windows and Mac Mac and (especially) Windows VMs are much slower than Linux. There is no need to build all targets on all platforms and thus build only few selected targets on slow VMs. --- .../{targets_native => targets_linux}/native_btshell/pkg.yml | 0 .../native_btshell/syscfg.yml | 0 .../native_btshell/target.yml | 0 .../{targets => targets_linux}/nordic_pca10028_boot/README | 0 .../{targets => targets_linux}/nordic_pca10028_boot/pkg.yml | 0 .../nordic_pca10028_boot/syscfg.yml | 0 .../nordic_pca10028_boot/target.yml | 0 .../nordic_pca10028_bt5_blehci/pkg.yml | 0 .../nordic_pca10028_bt5_blehci/syscfg.yml | 0 .../nordic_pca10028_bt5_blehci/target.yml | 0 .../nordic_pca10056-blehci-usb/pkg.yml | 0 .../nordic_pca10056-blehci-usb/syscfg.yml | 0 .../nordic_pca10056-blehci-usb/target.yml | 0 .../nordic_pca10056_advertiser/pkg.yml | 0 .../nordic_pca10056_advertiser/target.yml | 0 .../nordic_pca10056_blecent/pkg.yml | 0 .../nordic_pca10056_blecent/target.yml | 0 .../{targets => targets_linux}/nordic_pca10056_blecsc/pkg.yml | 0 .../nordic_pca10056_blecsc/target.yml | 0 .../{targets => targets_linux}/nordic_pca10056_blehci/pkg.yml | 0 .../nordic_pca10056_blehci/target.yml | 0 .../nordic_pca10056_blehci_all_enabled/pkg.yml | 0 .../nordic_pca10056_blehci_all_enabled/syscfg.yml | 0 .../nordic_pca10056_blehci_all_enabled/target.yml | 0 .../nordic_pca10056_blehci_no_privacy/pkg.yml | 0 .../nordic_pca10056_blehci_no_privacy/syscfg.yml | 0 .../nordic_pca10056_blehci_no_privacy/target.yml | 0 .../{targets => targets_linux}/nordic_pca10056_blehr/pkg.yml | 0 .../nordic_pca10056_blehr/target.yml | 0 .../nordic_pca10056_blemesh/pkg.yml | 0 .../nordic_pca10056_blemesh/target.yml | 0 .../nordic_pca10056_blemesh_cdb/pkg.yml | 0 .../nordic_pca10056_blemesh_cdb/syscfg.yml | 0 .../nordic_pca10056_blemesh_cdb/target.yml | 0 .../nordic_pca10056_blemesh_ext_adv/pkg.yml | 0 .../nordic_pca10056_blemesh_ext_adv/syscfg.yml | 0 .../nordic_pca10056_blemesh_ext_adv/target.yml | 0 .../nordic_pca10056_blemesh_light/pkg.yml | 0 .../nordic_pca10056_blemesh_light/target.yml | 0 .../nordic_pca10056_blemesh_models_example_1/pkg.yml | 0 .../nordic_pca10056_blemesh_models_example_1/target.yml | 0 .../nordic_pca10056_blemesh_models_example_2/pkg.yml | 0 .../nordic_pca10056_blemesh_models_example_2/target.yml | 0 .../nordic_pca10056_blemesh_shell/pkg.yml | 0 .../nordic_pca10056_blemesh_shell/target.yml | 0 .../nordic_pca10056_blemesh_storage/pkg.yml | 0 .../nordic_pca10056_blemesh_storage/syscfg.yml | 0 .../nordic_pca10056_blemesh_storage/target.yml | 0 .../nordic_pca10056_bleprph/pkg.yml | 0 .../nordic_pca10056_bleprph/target.yml | 0 .../nordic_pca10056_bleprph_oic/pkg.yml | 0 .../nordic_pca10056_bleprph_oic/target.yml | 0 .../nordic_pca10056_blesplit/pkg.yml | 0 .../nordic_pca10056_blesplit/target.yml | 0 .../nordic_pca10056_bleuart/pkg.yml | 0 .../nordic_pca10056_bleuart/target.yml | 0 .../nordic_pca10056_btshell_2M/pkg.yml | 0 .../nordic_pca10056_btshell_2M/syscfg.yml | 0 .../nordic_pca10056_btshell_2M/target.yml | 0 .../nordic_pca10056_btshell_2M_coded/pkg.yml | 0 .../nordic_pca10056_btshell_2M_coded/syscfg.yml | 0 .../nordic_pca10056_btshell_2M_coded/target.yml | 0 .../nordic_pca10056_btshell_all/pkg.yml | 0 .../nordic_pca10056_btshell_all/syscfg.h | 0 .../nordic_pca10056_btshell_all/target.yml | 0 .../nordic_pca10056_btshell_all_v52/pkg.yml | 0 .../nordic_pca10056_btshell_all_v52/syscfg.h | 0 .../nordic_pca10056_btshell_all_v52/target.yml | 0 .../nordic_pca10056_btshell_coded/pkg.yml | 0 .../nordic_pca10056_btshell_coded/syscfg.yml | 0 .../nordic_pca10056_btshell_coded/target.yml | 0 .../nordic_pca10056_btshell_ext_adv/pkg.yml | 0 .../nordic_pca10056_btshell_ext_adv/syscfg.yml | 0 .../nordic_pca10056_btshell_ext_adv/target.yml | 0 .../nordic_pca10056_btshell_periodic_adv/pkg.yml | 0 .../nordic_pca10056_btshell_periodic_adv/syscfg.yml | 0 .../nordic_pca10056_btshell_periodic_adv/target.yml | 0 .../nordic_pca10056_btshell_sm_legacy/pkg.yml | 0 .../nordic_pca10056_btshell_sm_legacy/syscfg.yml | 0 .../nordic_pca10056_btshell_sm_legacy/target.yml | 0 .../nordic_pca10056_btshell_sm_none/pkg.yml | 0 .../nordic_pca10056_btshell_sm_none/syscfg.yml | 0 .../nordic_pca10056_btshell_sm_none/target.yml | 0 .../nordic_pca10056_btshell_sm_sc/pkg.yml | 0 .../nordic_pca10056_btshell_sm_sc/syscfg.yml | 0 .../nordic_pca10056_btshell_sm_sc/target.yml | 0 .../nordic_pca10056_btshell_sm_sc_legacy/pkg.yml | 0 .../nordic_pca10056_btshell_sm_sc_legacy/syscfg.yml | 0 .../nordic_pca10056_btshell_sm_sc_legacy/target.yml | 0 .../nordic_pca10056_btshell_xtal_settle_0/pkg.yml | 0 .../nordic_pca10056_btshell_xtal_settle_0/syscfg.yml | 0 .../nordic_pca10056_btshell_xtal_settle_0/target.yml | 0 .../nordic_pca10056_bttester/pkg.yml | 0 .../nordic_pca10056_bttester/target.yml | 0 .../{targets => targets_linux}/nordic_pca10056_dtm/pkg.yml | 0 .../{targets => targets_linux}/nordic_pca10056_dtm/target.yml | 0 .../nordic_pca10056_ext_advertiser/pkg.yml | 0 .../nordic_pca10056_ext_advertiser/target.yml | 0 .../nordic_pca10056_scanner/pkg.yml | 0 .../nordic_pca10056_scanner/target.yml | 0 .../{targets => targets_linux}/nordic_pca10095_blehci/pkg.yml | 0 .../nordic_pca10095_blehci/syscfg.yml | 0 .../nordic_pca10095_blehci/target.yml | 0 .github/workflows/build_targets.yml | 4 ++-- 104 files changed, 2 insertions(+), 2 deletions(-) rename .github/{targets_native => targets_linux}/native_btshell/pkg.yml (100%) rename .github/{targets_native => targets_linux}/native_btshell/syscfg.yml (100%) rename .github/{targets_native => targets_linux}/native_btshell/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10028_boot/README (100%) rename .github/{targets => targets_linux}/nordic_pca10028_boot/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10028_boot/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10028_boot/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10028_bt5_blehci/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10028_bt5_blehci/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10028_bt5_blehci/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056-blehci-usb/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056-blehci-usb/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056-blehci-usb/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_advertiser/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_advertiser/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blecent/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blecent/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blecsc/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blecsc/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blehci/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blehci/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blehci_all_enabled/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blehci_all_enabled/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blehci_all_enabled/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blehci_no_privacy/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blehci_no_privacy/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blehci_no_privacy/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blehr/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blehr/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_cdb/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_cdb/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_cdb/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_ext_adv/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_ext_adv/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_ext_adv/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_light/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_light/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_models_example_1/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_models_example_1/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_models_example_2/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_models_example_2/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_shell/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_shell/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_storage/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_storage/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blemesh_storage/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_bleprph/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_bleprph/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_bleprph_oic/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_bleprph_oic/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blesplit/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_blesplit/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_bleuart/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_bleuart/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_2M/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_2M/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_2M/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_2M_coded/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_2M_coded/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_2M_coded/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_all/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_all/syscfg.h (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_all/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_all_v52/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_all_v52/syscfg.h (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_all_v52/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_coded/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_coded/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_coded/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_ext_adv/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_ext_adv/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_ext_adv/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_periodic_adv/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_periodic_adv/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_periodic_adv/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_sm_legacy/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_sm_legacy/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_sm_legacy/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_sm_none/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_sm_none/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_sm_none/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_sm_sc/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_sm_sc/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_sm_sc/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_sm_sc_legacy/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_sm_sc_legacy/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_xtal_settle_0/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_xtal_settle_0/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_btshell_xtal_settle_0/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_bttester/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_bttester/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_dtm/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_dtm/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_ext_advertiser/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_ext_advertiser/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_scanner/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10056_scanner/target.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10095_blehci/pkg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10095_blehci/syscfg.yml (100%) rename .github/{targets => targets_linux}/nordic_pca10095_blehci/target.yml (100%) diff --git a/.github/targets_native/native_btshell/pkg.yml b/.github/targets_linux/native_btshell/pkg.yml similarity index 100% rename from .github/targets_native/native_btshell/pkg.yml rename to .github/targets_linux/native_btshell/pkg.yml diff --git a/.github/targets_native/native_btshell/syscfg.yml b/.github/targets_linux/native_btshell/syscfg.yml similarity index 100% rename from .github/targets_native/native_btshell/syscfg.yml rename to .github/targets_linux/native_btshell/syscfg.yml diff --git a/.github/targets_native/native_btshell/target.yml b/.github/targets_linux/native_btshell/target.yml similarity index 100% rename from .github/targets_native/native_btshell/target.yml rename to .github/targets_linux/native_btshell/target.yml diff --git a/.github/targets/nordic_pca10028_boot/README b/.github/targets_linux/nordic_pca10028_boot/README similarity index 100% rename from .github/targets/nordic_pca10028_boot/README rename to .github/targets_linux/nordic_pca10028_boot/README diff --git a/.github/targets/nordic_pca10028_boot/pkg.yml b/.github/targets_linux/nordic_pca10028_boot/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10028_boot/pkg.yml rename to .github/targets_linux/nordic_pca10028_boot/pkg.yml diff --git a/.github/targets/nordic_pca10028_boot/syscfg.yml b/.github/targets_linux/nordic_pca10028_boot/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10028_boot/syscfg.yml rename to .github/targets_linux/nordic_pca10028_boot/syscfg.yml diff --git a/.github/targets/nordic_pca10028_boot/target.yml b/.github/targets_linux/nordic_pca10028_boot/target.yml similarity index 100% rename from .github/targets/nordic_pca10028_boot/target.yml rename to .github/targets_linux/nordic_pca10028_boot/target.yml diff --git a/.github/targets/nordic_pca10028_bt5_blehci/pkg.yml b/.github/targets_linux/nordic_pca10028_bt5_blehci/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10028_bt5_blehci/pkg.yml rename to .github/targets_linux/nordic_pca10028_bt5_blehci/pkg.yml diff --git a/.github/targets/nordic_pca10028_bt5_blehci/syscfg.yml b/.github/targets_linux/nordic_pca10028_bt5_blehci/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10028_bt5_blehci/syscfg.yml rename to .github/targets_linux/nordic_pca10028_bt5_blehci/syscfg.yml diff --git a/.github/targets/nordic_pca10028_bt5_blehci/target.yml b/.github/targets_linux/nordic_pca10028_bt5_blehci/target.yml similarity index 100% rename from .github/targets/nordic_pca10028_bt5_blehci/target.yml rename to .github/targets_linux/nordic_pca10028_bt5_blehci/target.yml diff --git a/.github/targets/nordic_pca10056-blehci-usb/pkg.yml b/.github/targets_linux/nordic_pca10056-blehci-usb/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056-blehci-usb/pkg.yml rename to .github/targets_linux/nordic_pca10056-blehci-usb/pkg.yml diff --git a/.github/targets/nordic_pca10056-blehci-usb/syscfg.yml b/.github/targets_linux/nordic_pca10056-blehci-usb/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056-blehci-usb/syscfg.yml rename to .github/targets_linux/nordic_pca10056-blehci-usb/syscfg.yml diff --git a/.github/targets/nordic_pca10056-blehci-usb/target.yml b/.github/targets_linux/nordic_pca10056-blehci-usb/target.yml similarity index 100% rename from .github/targets/nordic_pca10056-blehci-usb/target.yml rename to .github/targets_linux/nordic_pca10056-blehci-usb/target.yml diff --git a/.github/targets/nordic_pca10056_advertiser/pkg.yml b/.github/targets_linux/nordic_pca10056_advertiser/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_advertiser/pkg.yml rename to .github/targets_linux/nordic_pca10056_advertiser/pkg.yml diff --git a/.github/targets/nordic_pca10056_advertiser/target.yml b/.github/targets_linux/nordic_pca10056_advertiser/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_advertiser/target.yml rename to .github/targets_linux/nordic_pca10056_advertiser/target.yml diff --git a/.github/targets/nordic_pca10056_blecent/pkg.yml b/.github/targets_linux/nordic_pca10056_blecent/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blecent/pkg.yml rename to .github/targets_linux/nordic_pca10056_blecent/pkg.yml diff --git a/.github/targets/nordic_pca10056_blecent/target.yml b/.github/targets_linux/nordic_pca10056_blecent/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_blecent/target.yml rename to .github/targets_linux/nordic_pca10056_blecent/target.yml diff --git a/.github/targets/nordic_pca10056_blecsc/pkg.yml b/.github/targets_linux/nordic_pca10056_blecsc/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blecsc/pkg.yml rename to .github/targets_linux/nordic_pca10056_blecsc/pkg.yml diff --git a/.github/targets/nordic_pca10056_blecsc/target.yml b/.github/targets_linux/nordic_pca10056_blecsc/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_blecsc/target.yml rename to .github/targets_linux/nordic_pca10056_blecsc/target.yml diff --git a/.github/targets/nordic_pca10056_blehci/pkg.yml b/.github/targets_linux/nordic_pca10056_blehci/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blehci/pkg.yml rename to .github/targets_linux/nordic_pca10056_blehci/pkg.yml diff --git a/.github/targets/nordic_pca10056_blehci/target.yml b/.github/targets_linux/nordic_pca10056_blehci/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_blehci/target.yml rename to .github/targets_linux/nordic_pca10056_blehci/target.yml diff --git a/.github/targets/nordic_pca10056_blehci_all_enabled/pkg.yml b/.github/targets_linux/nordic_pca10056_blehci_all_enabled/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blehci_all_enabled/pkg.yml rename to .github/targets_linux/nordic_pca10056_blehci_all_enabled/pkg.yml diff --git a/.github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml b/.github/targets_linux/nordic_pca10056_blehci_all_enabled/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blehci_all_enabled/syscfg.yml rename to .github/targets_linux/nordic_pca10056_blehci_all_enabled/syscfg.yml diff --git a/.github/targets/nordic_pca10056_blehci_all_enabled/target.yml b/.github/targets_linux/nordic_pca10056_blehci_all_enabled/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_blehci_all_enabled/target.yml rename to .github/targets_linux/nordic_pca10056_blehci_all_enabled/target.yml diff --git a/.github/targets/nordic_pca10056_blehci_no_privacy/pkg.yml b/.github/targets_linux/nordic_pca10056_blehci_no_privacy/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blehci_no_privacy/pkg.yml rename to .github/targets_linux/nordic_pca10056_blehci_no_privacy/pkg.yml diff --git a/.github/targets/nordic_pca10056_blehci_no_privacy/syscfg.yml b/.github/targets_linux/nordic_pca10056_blehci_no_privacy/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blehci_no_privacy/syscfg.yml rename to .github/targets_linux/nordic_pca10056_blehci_no_privacy/syscfg.yml diff --git a/.github/targets/nordic_pca10056_blehci_no_privacy/target.yml b/.github/targets_linux/nordic_pca10056_blehci_no_privacy/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_blehci_no_privacy/target.yml rename to .github/targets_linux/nordic_pca10056_blehci_no_privacy/target.yml diff --git a/.github/targets/nordic_pca10056_blehr/pkg.yml b/.github/targets_linux/nordic_pca10056_blehr/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blehr/pkg.yml rename to .github/targets_linux/nordic_pca10056_blehr/pkg.yml diff --git a/.github/targets/nordic_pca10056_blehr/target.yml b/.github/targets_linux/nordic_pca10056_blehr/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_blehr/target.yml rename to .github/targets_linux/nordic_pca10056_blehr/target.yml diff --git a/.github/targets/nordic_pca10056_blemesh/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh/pkg.yml rename to .github/targets_linux/nordic_pca10056_blemesh/pkg.yml diff --git a/.github/targets/nordic_pca10056_blemesh/target.yml b/.github/targets_linux/nordic_pca10056_blemesh/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh/target.yml rename to .github/targets_linux/nordic_pca10056_blemesh/target.yml diff --git a/.github/targets/nordic_pca10056_blemesh_cdb/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_cdb/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_cdb/pkg.yml rename to .github/targets_linux/nordic_pca10056_blemesh_cdb/pkg.yml diff --git a/.github/targets/nordic_pca10056_blemesh_cdb/syscfg.yml b/.github/targets_linux/nordic_pca10056_blemesh_cdb/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_cdb/syscfg.yml rename to .github/targets_linux/nordic_pca10056_blemesh_cdb/syscfg.yml diff --git a/.github/targets/nordic_pca10056_blemesh_cdb/target.yml b/.github/targets_linux/nordic_pca10056_blemesh_cdb/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_cdb/target.yml rename to .github/targets_linux/nordic_pca10056_blemesh_cdb/target.yml diff --git a/.github/targets/nordic_pca10056_blemesh_ext_adv/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_ext_adv/pkg.yml rename to .github/targets_linux/nordic_pca10056_blemesh_ext_adv/pkg.yml diff --git a/.github/targets/nordic_pca10056_blemesh_ext_adv/syscfg.yml b/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_ext_adv/syscfg.yml rename to .github/targets_linux/nordic_pca10056_blemesh_ext_adv/syscfg.yml diff --git a/.github/targets/nordic_pca10056_blemesh_ext_adv/target.yml b/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_ext_adv/target.yml rename to .github/targets_linux/nordic_pca10056_blemesh_ext_adv/target.yml diff --git a/.github/targets/nordic_pca10056_blemesh_light/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_light/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_light/pkg.yml rename to .github/targets_linux/nordic_pca10056_blemesh_light/pkg.yml diff --git a/.github/targets/nordic_pca10056_blemesh_light/target.yml b/.github/targets_linux/nordic_pca10056_blemesh_light/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_light/target.yml rename to .github/targets_linux/nordic_pca10056_blemesh_light/target.yml diff --git a/.github/targets/nordic_pca10056_blemesh_models_example_1/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_models_example_1/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_models_example_1/pkg.yml rename to .github/targets_linux/nordic_pca10056_blemesh_models_example_1/pkg.yml diff --git a/.github/targets/nordic_pca10056_blemesh_models_example_1/target.yml b/.github/targets_linux/nordic_pca10056_blemesh_models_example_1/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_models_example_1/target.yml rename to .github/targets_linux/nordic_pca10056_blemesh_models_example_1/target.yml diff --git a/.github/targets/nordic_pca10056_blemesh_models_example_2/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_models_example_2/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_models_example_2/pkg.yml rename to .github/targets_linux/nordic_pca10056_blemesh_models_example_2/pkg.yml diff --git a/.github/targets/nordic_pca10056_blemesh_models_example_2/target.yml b/.github/targets_linux/nordic_pca10056_blemesh_models_example_2/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_models_example_2/target.yml rename to .github/targets_linux/nordic_pca10056_blemesh_models_example_2/target.yml diff --git a/.github/targets/nordic_pca10056_blemesh_shell/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_shell/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_shell/pkg.yml rename to .github/targets_linux/nordic_pca10056_blemesh_shell/pkg.yml diff --git a/.github/targets/nordic_pca10056_blemesh_shell/target.yml b/.github/targets_linux/nordic_pca10056_blemesh_shell/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_shell/target.yml rename to .github/targets_linux/nordic_pca10056_blemesh_shell/target.yml diff --git a/.github/targets/nordic_pca10056_blemesh_storage/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_storage/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_storage/pkg.yml rename to .github/targets_linux/nordic_pca10056_blemesh_storage/pkg.yml diff --git a/.github/targets/nordic_pca10056_blemesh_storage/syscfg.yml b/.github/targets_linux/nordic_pca10056_blemesh_storage/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_storage/syscfg.yml rename to .github/targets_linux/nordic_pca10056_blemesh_storage/syscfg.yml diff --git a/.github/targets/nordic_pca10056_blemesh_storage/target.yml b/.github/targets_linux/nordic_pca10056_blemesh_storage/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_blemesh_storage/target.yml rename to .github/targets_linux/nordic_pca10056_blemesh_storage/target.yml diff --git a/.github/targets/nordic_pca10056_bleprph/pkg.yml b/.github/targets_linux/nordic_pca10056_bleprph/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_bleprph/pkg.yml rename to .github/targets_linux/nordic_pca10056_bleprph/pkg.yml diff --git a/.github/targets/nordic_pca10056_bleprph/target.yml b/.github/targets_linux/nordic_pca10056_bleprph/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_bleprph/target.yml rename to .github/targets_linux/nordic_pca10056_bleprph/target.yml diff --git a/.github/targets/nordic_pca10056_bleprph_oic/pkg.yml b/.github/targets_linux/nordic_pca10056_bleprph_oic/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_bleprph_oic/pkg.yml rename to .github/targets_linux/nordic_pca10056_bleprph_oic/pkg.yml diff --git a/.github/targets/nordic_pca10056_bleprph_oic/target.yml b/.github/targets_linux/nordic_pca10056_bleprph_oic/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_bleprph_oic/target.yml rename to .github/targets_linux/nordic_pca10056_bleprph_oic/target.yml diff --git a/.github/targets/nordic_pca10056_blesplit/pkg.yml b/.github/targets_linux/nordic_pca10056_blesplit/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_blesplit/pkg.yml rename to .github/targets_linux/nordic_pca10056_blesplit/pkg.yml diff --git a/.github/targets/nordic_pca10056_blesplit/target.yml b/.github/targets_linux/nordic_pca10056_blesplit/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_blesplit/target.yml rename to .github/targets_linux/nordic_pca10056_blesplit/target.yml diff --git a/.github/targets/nordic_pca10056_bleuart/pkg.yml b/.github/targets_linux/nordic_pca10056_bleuart/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_bleuart/pkg.yml rename to .github/targets_linux/nordic_pca10056_bleuart/pkg.yml diff --git a/.github/targets/nordic_pca10056_bleuart/target.yml b/.github/targets_linux/nordic_pca10056_bleuart/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_bleuart/target.yml rename to .github/targets_linux/nordic_pca10056_bleuart/target.yml diff --git a/.github/targets/nordic_pca10056_btshell_2M/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_2M/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_2M/pkg.yml rename to .github/targets_linux/nordic_pca10056_btshell_2M/pkg.yml diff --git a/.github/targets/nordic_pca10056_btshell_2M/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_2M/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_2M/syscfg.yml rename to .github/targets_linux/nordic_pca10056_btshell_2M/syscfg.yml diff --git a/.github/targets/nordic_pca10056_btshell_2M/target.yml b/.github/targets_linux/nordic_pca10056_btshell_2M/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_2M/target.yml rename to .github/targets_linux/nordic_pca10056_btshell_2M/target.yml diff --git a/.github/targets/nordic_pca10056_btshell_2M_coded/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_2M_coded/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_2M_coded/pkg.yml rename to .github/targets_linux/nordic_pca10056_btshell_2M_coded/pkg.yml diff --git a/.github/targets/nordic_pca10056_btshell_2M_coded/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_2M_coded/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_2M_coded/syscfg.yml rename to .github/targets_linux/nordic_pca10056_btshell_2M_coded/syscfg.yml diff --git a/.github/targets/nordic_pca10056_btshell_2M_coded/target.yml b/.github/targets_linux/nordic_pca10056_btshell_2M_coded/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_2M_coded/target.yml rename to .github/targets_linux/nordic_pca10056_btshell_2M_coded/target.yml diff --git a/.github/targets/nordic_pca10056_btshell_all/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_all/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_all/pkg.yml rename to .github/targets_linux/nordic_pca10056_btshell_all/pkg.yml diff --git a/.github/targets/nordic_pca10056_btshell_all/syscfg.h b/.github/targets_linux/nordic_pca10056_btshell_all/syscfg.h similarity index 100% rename from .github/targets/nordic_pca10056_btshell_all/syscfg.h rename to .github/targets_linux/nordic_pca10056_btshell_all/syscfg.h diff --git a/.github/targets/nordic_pca10056_btshell_all/target.yml b/.github/targets_linux/nordic_pca10056_btshell_all/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_all/target.yml rename to .github/targets_linux/nordic_pca10056_btshell_all/target.yml diff --git a/.github/targets/nordic_pca10056_btshell_all_v52/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_all_v52/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_all_v52/pkg.yml rename to .github/targets_linux/nordic_pca10056_btshell_all_v52/pkg.yml diff --git a/.github/targets/nordic_pca10056_btshell_all_v52/syscfg.h b/.github/targets_linux/nordic_pca10056_btshell_all_v52/syscfg.h similarity index 100% rename from .github/targets/nordic_pca10056_btshell_all_v52/syscfg.h rename to .github/targets_linux/nordic_pca10056_btshell_all_v52/syscfg.h diff --git a/.github/targets/nordic_pca10056_btshell_all_v52/target.yml b/.github/targets_linux/nordic_pca10056_btshell_all_v52/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_all_v52/target.yml rename to .github/targets_linux/nordic_pca10056_btshell_all_v52/target.yml diff --git a/.github/targets/nordic_pca10056_btshell_coded/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_coded/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_coded/pkg.yml rename to .github/targets_linux/nordic_pca10056_btshell_coded/pkg.yml diff --git a/.github/targets/nordic_pca10056_btshell_coded/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_coded/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_coded/syscfg.yml rename to .github/targets_linux/nordic_pca10056_btshell_coded/syscfg.yml diff --git a/.github/targets/nordic_pca10056_btshell_coded/target.yml b/.github/targets_linux/nordic_pca10056_btshell_coded/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_coded/target.yml rename to .github/targets_linux/nordic_pca10056_btshell_coded/target.yml diff --git a/.github/targets/nordic_pca10056_btshell_ext_adv/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_ext_adv/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_ext_adv/pkg.yml rename to .github/targets_linux/nordic_pca10056_btshell_ext_adv/pkg.yml diff --git a/.github/targets/nordic_pca10056_btshell_ext_adv/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_ext_adv/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_ext_adv/syscfg.yml rename to .github/targets_linux/nordic_pca10056_btshell_ext_adv/syscfg.yml diff --git a/.github/targets/nordic_pca10056_btshell_ext_adv/target.yml b/.github/targets_linux/nordic_pca10056_btshell_ext_adv/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_ext_adv/target.yml rename to .github/targets_linux/nordic_pca10056_btshell_ext_adv/target.yml diff --git a/.github/targets/nordic_pca10056_btshell_periodic_adv/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_periodic_adv/pkg.yml rename to .github/targets_linux/nordic_pca10056_btshell_periodic_adv/pkg.yml diff --git a/.github/targets/nordic_pca10056_btshell_periodic_adv/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_periodic_adv/syscfg.yml rename to .github/targets_linux/nordic_pca10056_btshell_periodic_adv/syscfg.yml diff --git a/.github/targets/nordic_pca10056_btshell_periodic_adv/target.yml b/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_periodic_adv/target.yml rename to .github/targets_linux/nordic_pca10056_btshell_periodic_adv/target.yml diff --git a/.github/targets/nordic_pca10056_btshell_sm_legacy/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_sm_legacy/pkg.yml rename to .github/targets_linux/nordic_pca10056_btshell_sm_legacy/pkg.yml diff --git a/.github/targets/nordic_pca10056_btshell_sm_legacy/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_sm_legacy/syscfg.yml rename to .github/targets_linux/nordic_pca10056_btshell_sm_legacy/syscfg.yml diff --git a/.github/targets/nordic_pca10056_btshell_sm_legacy/target.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_sm_legacy/target.yml rename to .github/targets_linux/nordic_pca10056_btshell_sm_legacy/target.yml diff --git a/.github/targets/nordic_pca10056_btshell_sm_none/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_none/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_sm_none/pkg.yml rename to .github/targets_linux/nordic_pca10056_btshell_sm_none/pkg.yml diff --git a/.github/targets/nordic_pca10056_btshell_sm_none/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_none/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_sm_none/syscfg.yml rename to .github/targets_linux/nordic_pca10056_btshell_sm_none/syscfg.yml diff --git a/.github/targets/nordic_pca10056_btshell_sm_none/target.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_none/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_sm_none/target.yml rename to .github/targets_linux/nordic_pca10056_btshell_sm_none/target.yml diff --git a/.github/targets/nordic_pca10056_btshell_sm_sc/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_sc/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_sm_sc/pkg.yml rename to .github/targets_linux/nordic_pca10056_btshell_sm_sc/pkg.yml diff --git a/.github/targets/nordic_pca10056_btshell_sm_sc/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_sc/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_sm_sc/syscfg.yml rename to .github/targets_linux/nordic_pca10056_btshell_sm_sc/syscfg.yml diff --git a/.github/targets/nordic_pca10056_btshell_sm_sc/target.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_sc/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_sm_sc/target.yml rename to .github/targets_linux/nordic_pca10056_btshell_sm_sc/target.yml diff --git a/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml rename to .github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml diff --git a/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_sm_sc_legacy/syscfg.yml rename to .github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/syscfg.yml diff --git a/.github/targets/nordic_pca10056_btshell_sm_sc_legacy/target.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_sm_sc_legacy/target.yml rename to .github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/target.yml diff --git a/.github/targets/nordic_pca10056_btshell_xtal_settle_0/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_xtal_settle_0/pkg.yml rename to .github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/pkg.yml diff --git a/.github/targets/nordic_pca10056_btshell_xtal_settle_0/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_xtal_settle_0/syscfg.yml rename to .github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/syscfg.yml diff --git a/.github/targets/nordic_pca10056_btshell_xtal_settle_0/target.yml b/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_btshell_xtal_settle_0/target.yml rename to .github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/target.yml diff --git a/.github/targets/nordic_pca10056_bttester/pkg.yml b/.github/targets_linux/nordic_pca10056_bttester/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_bttester/pkg.yml rename to .github/targets_linux/nordic_pca10056_bttester/pkg.yml diff --git a/.github/targets/nordic_pca10056_bttester/target.yml b/.github/targets_linux/nordic_pca10056_bttester/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_bttester/target.yml rename to .github/targets_linux/nordic_pca10056_bttester/target.yml diff --git a/.github/targets/nordic_pca10056_dtm/pkg.yml b/.github/targets_linux/nordic_pca10056_dtm/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_dtm/pkg.yml rename to .github/targets_linux/nordic_pca10056_dtm/pkg.yml diff --git a/.github/targets/nordic_pca10056_dtm/target.yml b/.github/targets_linux/nordic_pca10056_dtm/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_dtm/target.yml rename to .github/targets_linux/nordic_pca10056_dtm/target.yml diff --git a/.github/targets/nordic_pca10056_ext_advertiser/pkg.yml b/.github/targets_linux/nordic_pca10056_ext_advertiser/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_ext_advertiser/pkg.yml rename to .github/targets_linux/nordic_pca10056_ext_advertiser/pkg.yml diff --git a/.github/targets/nordic_pca10056_ext_advertiser/target.yml b/.github/targets_linux/nordic_pca10056_ext_advertiser/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_ext_advertiser/target.yml rename to .github/targets_linux/nordic_pca10056_ext_advertiser/target.yml diff --git a/.github/targets/nordic_pca10056_scanner/pkg.yml b/.github/targets_linux/nordic_pca10056_scanner/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10056_scanner/pkg.yml rename to .github/targets_linux/nordic_pca10056_scanner/pkg.yml diff --git a/.github/targets/nordic_pca10056_scanner/target.yml b/.github/targets_linux/nordic_pca10056_scanner/target.yml similarity index 100% rename from .github/targets/nordic_pca10056_scanner/target.yml rename to .github/targets_linux/nordic_pca10056_scanner/target.yml diff --git a/.github/targets/nordic_pca10095_blehci/pkg.yml b/.github/targets_linux/nordic_pca10095_blehci/pkg.yml similarity index 100% rename from .github/targets/nordic_pca10095_blehci/pkg.yml rename to .github/targets_linux/nordic_pca10095_blehci/pkg.yml diff --git a/.github/targets/nordic_pca10095_blehci/syscfg.yml b/.github/targets_linux/nordic_pca10095_blehci/syscfg.yml similarity index 100% rename from .github/targets/nordic_pca10095_blehci/syscfg.yml rename to .github/targets_linux/nordic_pca10095_blehci/syscfg.yml diff --git a/.github/targets/nordic_pca10095_blehci/target.yml b/.github/targets_linux/nordic_pca10095_blehci/target.yml similarity index 100% rename from .github/targets/nordic_pca10095_blehci/target.yml rename to .github/targets_linux/nordic_pca10095_blehci/target.yml diff --git a/.github/workflows/build_targets.yml b/.github/workflows/build_targets.yml index d1946f0478..05b13eb94f 100644 --- a/.github/workflows/build_targets.yml +++ b/.github/workflows/build_targets.yml @@ -62,9 +62,9 @@ jobs: cp -r .github/targets targets_ci ls targets_ci | xargs -n1 sh -c 'echo "Testing $0"; newt build -q targets_ci/$0' rm -rf targets_ci - - name: Build native targets + - name: Build Linux-only targets if: matrix.os == 'ubuntu-latest' run: | - cp -r .github/targets_native targets_ci + cp -r .github/targets_linux targets_ci ls targets_ci | xargs -n1 sh -c 'echo "Testing $0"; newt build -q targets_ci/$0' rm -rf targets_ci From 10f1270f06edc97ddedc6b23405428f4e6090a02 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 20 Sep 2023 15:19:07 +0200 Subject: [PATCH 0821/1333] ci: Use latest RAT snapshots SPDX support is only available in unreleased RAT snapshot so for now use latest snapshots. --- .github/workflows/compliance_check.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index edacc93f6d..71ac7f1c73 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -48,11 +48,15 @@ jobs: fetch-depth: 0 - name: Install Dependencies run: | + sudo apt-get update + sudo apt-get install -y libxml2-utils mkdir repos git clone --depth=1 https://github.com/apache/mynewt-core repos/apache-mynewt-core - wget https://dlcdn.apache.org//creadur/apache-rat-0.15/apache-rat-0.15-bin.tar.gz - tar zxf apache-rat-0.15-bin.tar.gz apache-rat-0.15/apache-rat-0.15.jar - mv apache-rat-0.15/apache-rat-0.15.jar apache-rat.jar + wget https://repository.apache.org/content/repositories/snapshots/org/apache/rat/apache-rat/maven-metadata.xml -O snapshot.xml + SNAPSHOT=`xmllint --xpath "//latest/text()" snapshot.xml` + wget https://repository.apache.org/content/repositories/snapshots/org/apache/rat/apache-rat/$SNAPSHOT/maven-metadata.xml -O version.xml + VERSION=`xmllint --xpath "//snapshotVersion[1]/value/text()" version.xml` + wget https://repository.apache.org/content/repositories/snapshots/org/apache/rat/apache-rat/$SNAPSHOT/apache-rat-$VERSION.jar -O apache-rat.jar - name: check licensing run: | ./repos/apache-mynewt-core/.github/check_license.py From 57cdc5c1c2e0d24923ec8328d989e6b97c484a0f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 22 Sep 2023 02:34:45 +0200 Subject: [PATCH 0822/1333] nimble/host: Add optional GAP event for unhandled HCI events This adds option to enabled additional GAP event which is called for a HCI event that host doesn't know how to handle. It can be used to test controller features that host doesn't yet support. It also removes dedicated BLE_GAP_EVENT_VS_HCI as this is handled now by the same event. --- nimble/host/include/host/ble_gap.h | 16 ++++++++++------ nimble/host/src/ble_gap.c | 13 ++++++++----- nimble/host/src/ble_gap_priv.h | 3 ++- nimble/host/src/ble_hs_hci_evt.c | 11 ++++++++++- nimble/host/syscfg.yml | 7 +++++++ 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index 2a311db2a8..690e427bd7 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -252,8 +252,8 @@ struct hci_conn_update; /** GAP event: Subrate change */ #define BLE_GAP_EVENT_SUBRATE_CHANGE 28 -/** GAP event: Vendor specific HCI event */ -#define BLE_GAP_EVENT_VS_HCI 29 +/** GAP event: Unhandled HCI event */ +#define BLE_GAP_EVENT_UNHANDLED_HCI_EVENT 29 /** GAP event: BIG (Broadcast Isochronous Group) information report */ #define BLE_GAP_EVENT_BIGINFO_REPORT 30 @@ -1288,17 +1288,21 @@ struct ble_gap_event { } subrate_change; #endif -#if MYNEWT_VAL(BLE_HCI_VS) +#if MYNEWT_VAL(BLE_HS_GAP_UNHANDLED_HCI_EVENT) /** - * Represents a received vendor-specific HCI event + * Represents an HCI event received from controller that is not handled + * by the host. The event may be a regular event, LE meta event or + * vendor specific event which is denoted by included flags. * * Valid for the following event types: - * o BLE_GAP_EVENT_VS_HCI + * o BLE_GAP_EVENT_UNHANDLED_HCI_EVENT */ struct { + bool is_le_meta; + bool is_vs; const void *ev; uint8_t length; - } vs_hci; + } unhandled_hci; #endif }; }; diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 3a63050b40..4736415a37 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -6357,16 +6357,19 @@ ble_gap_mtu_event(uint16_t conn_handle, uint16_t cid, uint16_t mtu) #endif } -#if MYNEWT_VAL(BLE_HCI_VS) +#if MYNEWT_VAL(BLE_HS_GAP_UNHANDLED_HCI_EVENT) void -ble_gap_vs_hci_event(const void *buf, uint8_t len) +ble_gap_unhandled_hci_event(bool is_le_meta, bool is_vs, const void *buf, + uint8_t len) { struct ble_gap_event event; memset(&event, 0, sizeof event); - event.type = BLE_GAP_EVENT_VS_HCI; - event.vs_hci.ev = buf; - event.vs_hci.length = len; + event.type = BLE_GAP_EVENT_UNHANDLED_HCI_EVENT; + event.unhandled_hci.is_le_meta = is_le_meta; + event.unhandled_hci.is_vs = is_vs; + event.unhandled_hci.ev = buf; + event.unhandled_hci.length = len; ble_gap_event_listener_call(&event); } diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h index 0be949da60..2f875ddf0e 100644 --- a/nimble/host/src/ble_gap_priv.h +++ b/nimble/host/src/ble_gap_priv.h @@ -141,7 +141,8 @@ void ble_gap_mtu_event(uint16_t conn_handle, uint16_t cid, uint16_t mtu); void ble_gap_identity_event(uint16_t conn_handle, const ble_addr_t *peer_id_addr); int ble_gap_repeat_pairing_event(const struct ble_gap_repeat_pairing *rp); void ble_gap_pairing_complete_event(uint16_t conn_handle, int status); -void ble_gap_vs_hci_event(const void *buf, uint8_t len); +void ble_gap_unhandled_hci_event(bool is_le_meta, bool is_vs, const void *buf, + uint8_t len); int ble_gap_master_in_progress(void); void ble_gap_preempt(void); diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index e7af2243b8..a128e3ab6b 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -296,7 +296,9 @@ ble_hs_hci_evt_vs(uint8_t event_code, const void *data, unsigned int len) return BLE_HS_ECONTROLLER; } - ble_gap_vs_hci_event(data, len); +#if MYNEWT_VAL(BLE_HS_GAP_UNHANDLED_HCI_EVENT) + ble_gap_unhandled_hci_event(false, true, data, len); +#endif return 0; } @@ -315,6 +317,10 @@ ble_hs_hci_evt_le_meta(uint8_t event_code, const void *data, unsigned int len) fn = ble_hs_hci_evt_le_dispatch_find(ev->subevent); if (fn) { return fn(ev->subevent, data, len); + } else { +#if MYNEWT_VAL(BLE_HS_GAP_UNHANDLED_HCI_EVENT) + ble_gap_unhandled_hci_event(true, false, data, len); +#endif } return 0; @@ -910,6 +916,9 @@ ble_hs_hci_evt_process(struct ble_hci_ev *ev) entry = ble_hs_hci_evt_dispatch_find(ev->opcode); if (entry == NULL) { +#if MYNEWT_VAL(BLE_HS_GAP_UNHANDLED_HCI_EVENT) + ble_gap_unhandled_hci_event(false, false, ev->data, ev->length); +#endif STATS_INC(ble_hs_stats, hci_unknown_event); rc = BLE_HS_ENOTSUP; } else { diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index f94111c61d..8218b9e769 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -474,6 +474,13 @@ syscfg.defs: Sysinit stage for the NimBLE host. value: 200 + BLE_HS_GAP_UNHANDLED_HCI_EVENT: + description: > + Enables GAP event for received HCI events that are not handled by + host. This can be used to implement/test features that are not yet + supported by host. + value: 0 + ### Log settings. BLE_HS_LOG_MOD: From a161f0abcdcb6a669d395c4a58be12976de0c126 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 20 Jul 2023 15:27:48 +0200 Subject: [PATCH 0823/1333] apps/btshell: Convert to parse_arg module Mkae use of common argument parsing code. --- apps/btshell/pkg.yml | 1 + apps/btshell/src/cmd.c | 122 +++---- apps/btshell/src/cmd.h | 40 +-- apps/btshell/src/cmd_gatt.c | 30 +- apps/btshell/src/cmd_l2cap.c | 14 +- apps/btshell/src/parse.c | 624 ----------------------------------- 6 files changed, 89 insertions(+), 742 deletions(-) diff --git a/apps/btshell/pkg.yml b/apps/btshell/pkg.yml index b50b371c38..d98f541f06 100644 --- a/apps/btshell/pkg.yml +++ b/apps/btshell/pkg.yml @@ -29,6 +29,7 @@ pkg.deps: - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/console" - "@apache-mynewt-core/sys/shell" + - "@apache-mynewt-core/util/parse_arg" - nimble/host - nimble/host/services/gap - nimble/host/services/gatt diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index 22819219aa..e0fc57acaa 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -69,7 +69,7 @@ cmd_parse_conn_start_end(uint16_t *out_conn, uint16_t *out_start, return 0; } -static const struct kv_pair cmd_own_addr_types[] = { +static const struct parse_arg_kv_pair cmd_own_addr_types[] = { { "public", BLE_OWN_ADDR_PUBLIC }, { "random", BLE_OWN_ADDR_RANDOM }, { "rpa_pub", BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT }, @@ -77,7 +77,7 @@ static const struct kv_pair cmd_own_addr_types[] = { { NULL } }; -static const struct kv_pair cmd_peer_addr_types[] = { +static const struct parse_arg_kv_pair cmd_peer_addr_types[] = { { "public", BLE_ADDR_PUBLIC }, { "random", BLE_ADDR_RANDOM }, { "public_id", BLE_ADDR_PUBLIC_ID }, @@ -85,7 +85,7 @@ static const struct kv_pair cmd_peer_addr_types[] = { { NULL } }; -static const struct kv_pair cmd_addr_type[] = { +static const struct parse_arg_kv_pair cmd_addr_type[] = { { "public", BLE_ADDR_PUBLIC }, { "random", BLE_ADDR_RANDOM }, { NULL } @@ -93,7 +93,7 @@ static const struct kv_pair cmd_addr_type[] = { static int -parse_dev_addr(const char *prefix, const struct kv_pair *addr_types, +parse_dev_addr(const char *prefix, const struct parse_arg_kv_pair *addr_types, ble_addr_t *addr) { char name[32]; @@ -115,7 +115,7 @@ parse_dev_addr(const char *prefix, const struct kv_pair *addr_types, } written += rc; - rc = parse_arg_addr(name, addr); + rc = parse_arg_ble_addr(name, addr); if (rc == ENOENT) { /* not found */ return rc; @@ -153,7 +153,7 @@ parse_dev_addr(const char *prefix, const struct kv_pair *addr_types, /***************************************************************************** * $advertise * *****************************************************************************/ -static const struct kv_pair cmd_adv_filt_types[] = { +static const struct parse_arg_kv_pair cmd_adv_filt_types[] = { { "none", BLE_HCI_ADV_FILT_NONE }, { "scan", BLE_HCI_ADV_FILT_SCAN }, { "conn", BLE_HCI_ADV_FILT_CONN }, @@ -162,7 +162,7 @@ static const struct kv_pair cmd_adv_filt_types[] = { }; #if MYNEWT_VAL(BLE_EXT_ADV) -static struct kv_pair cmd_ext_adv_phy_opts[] = { +static struct parse_arg_kv_pair cmd_ext_adv_phy_opts[] = { { "1M", 0x01 }, { "2M", 0x02 }, { "coded", 0x03 }, @@ -177,7 +177,7 @@ cmd_advertise_configure(int argc, char **argv) uint8_t instance; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -338,7 +338,7 @@ cmd_advertise_set_addr(int argc, char **argv) uint8_t instance; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -349,7 +349,7 @@ cmd_advertise_set_addr(int argc, char **argv) return rc; } - rc = parse_arg_mac("addr", addr.val); + rc = parse_arg_mac_addr("addr", addr.val); if (rc != 0) { console_printf("invalid 'addr' parameter\n"); return rc; @@ -375,7 +375,7 @@ cmd_advertise_start(int argc, char **argv) bool restart; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -419,7 +419,7 @@ cmd_advertise_stop(int argc, char **argv) uint8_t instance; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -445,7 +445,7 @@ cmd_advertise_remove(int argc, char **argv) uint8_t instance; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -546,14 +546,14 @@ static const struct shell_cmd_help advertise_remove_help = { #endif #else -static const struct kv_pair cmd_adv_conn_modes[] = { +static const struct parse_arg_kv_pair cmd_adv_conn_modes[] = { { "non", BLE_GAP_CONN_MODE_NON }, { "und", BLE_GAP_CONN_MODE_UND }, { "dir", BLE_GAP_CONN_MODE_DIR }, { NULL } }; -static const struct kv_pair cmd_adv_disc_modes[] = { +static const struct parse_arg_kv_pair cmd_adv_disc_modes[] = { { "non", BLE_GAP_DISC_MODE_NON }, { "ltd", BLE_GAP_DISC_MODE_LTD }, { "gen", BLE_GAP_DISC_MODE_GEN }, @@ -571,7 +571,7 @@ cmd_advertise(int argc, char **argv) bool restart; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -699,7 +699,7 @@ static const struct shell_cmd_help advertise_help = { * $connect * *****************************************************************************/ -static struct kv_pair cmd_ext_conn_phy_opts[] = { +static struct parse_arg_kv_pair cmd_ext_conn_phy_opts[] = { { "none", 0x00 }, { "1M", 0x01 }, { "coded", 0x02 }, @@ -721,7 +721,7 @@ cmd_connect(int argc, char **argv) int own_addr_type; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -1014,7 +1014,7 @@ cmd_disconnect(int argc, char **argv) uint8_t reason; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -1117,7 +1117,7 @@ cmd_set_scan_opts(int argc, char **argv) char *name_filter; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -1173,7 +1173,7 @@ static const struct shell_cmd_help set_scan_opts_help = { * $scan * *****************************************************************************/ -static const struct kv_pair cmd_scan_filt_policies[] = { +static const struct parse_arg_kv_pair cmd_scan_filt_policies[] = { { "no_wl", BLE_HCI_SCAN_FILT_NO_WL }, { "use_wl", BLE_HCI_SCAN_FILT_USE_WL }, { "no_wl_inita", BLE_HCI_SCAN_FILT_NO_WL_INITA }, @@ -1181,7 +1181,7 @@ static const struct kv_pair cmd_scan_filt_policies[] = { { NULL } }; -static struct kv_pair cmd_scan_ext_types[] = { +static struct parse_arg_kv_pair cmd_scan_ext_types[] = { { "none", 0x00 }, { "1M", 0x01 }, { "coded", 0x02 }, @@ -1204,7 +1204,7 @@ cmd_scan(int argc, char **argv) uint16_t period; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -1428,7 +1428,7 @@ cmd_set(int argc, char **argv) int good = 0; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -1544,11 +1544,11 @@ cmd_set_adv_data_or_scan_rsp(int argc, char **argv, bool scan_rsp, int8_t eddystone_measured_power = 0; char eddystone_url_body[BLE_EDDYSTONE_URL_MAX_LEN]; char *eddystone_url_full; - int svc_data_uuid16_len; - int svc_data_uuid32_len; - int svc_data_uuid128_len; - int uri_len; - int mfg_data_len; + unsigned int svc_data_uuid16_len; + unsigned int svc_data_uuid32_len; + unsigned int svc_data_uuid128_len; + unsigned int uri_len; + unsigned int mfg_data_len; int tmp; int rc; #if MYNEWT_VAL(BLE_EXT_ADV) @@ -1566,7 +1566,7 @@ cmd_set_adv_data_or_scan_rsp(int argc, char **argv, bool scan_rsp, memset(&adv_fields, 0, sizeof adv_fields); - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -1753,9 +1753,9 @@ cmd_set_adv_data_or_scan_rsp(int argc, char **argv, bool scan_rsp, return rc; } - rc = parse_arg_byte_stream("service_data_uuid128", + rc = parse_arg_byte_stream_custom("service_data_uuid128", ":-", CMD_ADV_DATA_SVC_DATA_UUID128_MAX_LEN, - svc_data_uuid128, &svc_data_uuid128_len); + svc_data_uuid128, 0, &svc_data_uuid128_len); if (rc == 0) { adv_fields.svc_data_uuid128 = svc_data_uuid128; adv_fields.svc_data_uuid128_len = svc_data_uuid128_len; @@ -1932,7 +1932,7 @@ cmd_set_priv_mode(int argc, char **argv) uint8_t priv_mode; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -1980,7 +1980,7 @@ cmd_white_list(int argc, char **argv) int addrs_cnt; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -2036,7 +2036,7 @@ cmd_conn_rssi(int argc, char **argv) int8_t rssi; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -2082,7 +2082,7 @@ cmd_conn_update_params(int argc, char **argv) uint16_t conn_handle; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -2176,7 +2176,7 @@ cmd_conn_datalen(int argc, char **argv) uint16_t tx_time; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -2229,7 +2229,7 @@ static const struct shell_cmd_help conn_datalen_help = { * keystore * *****************************************************************************/ -static const struct kv_pair cmd_keystore_entry_type[] = { +static const struct parse_arg_kv_pair cmd_keystore_entry_type[] = { { "msec", BLE_STORE_OBJ_TYPE_PEER_SEC }, { "ssec", BLE_STORE_OBJ_TYPE_OUR_SEC }, { "cccd", BLE_STORE_OBJ_TYPE_CCCD }, @@ -2327,7 +2327,7 @@ cmd_keystore_add(int argc, char **argv) int obj_type; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -2391,7 +2391,7 @@ cmd_keystore_del(int argc, char **argv) int obj_type; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -2480,7 +2480,7 @@ cmd_keystore_show(int argc, char **argv) int type; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -2546,7 +2546,7 @@ cmd_auth_passkey(int argc, char **argv) char *yesno; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -2666,7 +2666,7 @@ cmd_security_pair(int argc, char **argv) uint16_t conn_handle; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -2710,7 +2710,7 @@ cmd_security_unpair(int argc, char **argv) int rc; int oldest; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -2767,7 +2767,7 @@ cmd_security_start(int argc, char **argv) uint16_t conn_handle; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -2815,7 +2815,7 @@ cmd_security_encryption(int argc, char **argv) int rc; int auth; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -2896,7 +2896,7 @@ cmd_security_set_data(int argc, char **argv) good = 0; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -3010,7 +3010,7 @@ cmd_test_tx(int argc, char **argv) uint16_t num; uint8_t stop; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -3087,7 +3087,7 @@ cmd_phy_set(int argc, char **argv) uint16_t phy_opts; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -3147,7 +3147,7 @@ cmd_phy_set_default(int argc, char **argv) uint8_t rx_phys_mask; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -3193,7 +3193,7 @@ cmd_phy_read(int argc, char **argv) uint8_t rx_phy; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -3634,7 +3634,7 @@ cmd_periodic_configure(int argc, char **argv) uint8_t instance; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -3690,7 +3690,7 @@ cmd_periodic_start(int argc, char **argv) uint8_t instance; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -3716,7 +3716,7 @@ cmd_periodic_stop(int argc, char **argv) uint8_t instance; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -3783,7 +3783,7 @@ cmd_sync_create(int argc, char **argv) uint8_t sid; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -3868,7 +3868,7 @@ cmd_sync_transfer(int argc, char **argv) uint16_t sync_handle; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -3907,7 +3907,7 @@ cmd_sync_reporting(int argc, char **argv) bool enable; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -3968,7 +3968,7 @@ cmd_sync_transfer_set_info(int argc, char **argv) uint8_t instance; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -4023,7 +4023,7 @@ cmd_sync_transfer_receive(int argc, char **argv) bool disable; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -4100,7 +4100,7 @@ cmd_sync_terminate(int argc, char **argv) uint16_t sync_handle; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -4138,7 +4138,7 @@ cmd_sync_stats(int argc, char **argv) uint16_t sync_handle; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } diff --git a/apps/btshell/src/cmd.h b/apps/btshell/src/cmd.h index 63bd50d1b8..0984d009b0 100644 --- a/apps/btshell/src/cmd.h +++ b/apps/btshell/src/cmd.h @@ -22,44 +22,14 @@ #include #include "host/ble_uuid.h" +#include -struct kv_pair { - char *key; - int val; -}; - -uint32_t parse_arg_time_dflt(char *name, int step, uint32_t dflt, int *out_status); -const struct kv_pair *parse_kv_find(const struct kv_pair *kvs, char *name); -int parse_arg_find_idx(const char *key); -char *parse_arg_extract(const char *key); -long parse_arg_long_bounds(char *name, long min, long max, int *out_status); -long parse_arg_long_bounds_dflt(char *name, long min, long max, - long dflt, int *out_status); -uint64_t parse_arg_uint64_bounds(char *name, uint64_t min, - uint64_t max, int *out_status); -long parse_arg_long(char *name, int *staus); -uint8_t parse_arg_bool(char *name, int *status); -uint8_t parse_arg_bool_dflt(char *name, uint8_t dflt, int *out_status); -uint8_t parse_arg_uint8(char *name, int *status); -uint8_t parse_arg_uint8_dflt(char *name, uint8_t dflt, int *out_status); -uint16_t parse_arg_uint16(char *name, int *status); -uint16_t parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status); -uint32_t parse_arg_uint32(char *name, int *out_status); -uint32_t parse_arg_uint32_dflt(char *name, uint32_t dflt, int *out_status); -uint64_t parse_arg_uint64(char *name, int *out_status); -int parse_arg_kv(char *name, const struct kv_pair *kvs, int *out_status); -int parse_arg_kv_dflt(char *name, const struct kv_pair *kvs, int def_val, - int *out_status); -int parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len); -int parse_arg_uint8_list_with_separator(char *name, char *separator, int max_len, - uint8_t *dst, int *out_len); -int parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len); -int parse_arg_mac(char *name, uint8_t *dst); -int parse_arg_addr(char *name, ble_addr_t *addr); -int parse_arg_uuid(char *name, ble_uuid_any_t *uuid); -int parse_arg_all(int argc, char **argv); +//int parse_arg_mac(char *name, uint8_t *dst); +//int parse_arg_addr(char *name, ble_addr_t *addr); +//int parse_arg_uuid(char *name, ble_uuid_any_t *uuid); int parse_eddystone_url(char *full_url, uint8_t *out_scheme, char *out_body, uint8_t *out_body_len, uint8_t *out_suffix); + int cmd_parse_conn_start_end(uint16_t *out_conn, uint16_t *out_start, uint16_t *out_end); diff --git a/apps/btshell/src/cmd_gatt.c b/apps/btshell/src/cmd_gatt.c index 4c57b42d6c..734b100476 100644 --- a/apps/btshell/src/cmd_gatt.c +++ b/apps/btshell/src/cmd_gatt.c @@ -45,7 +45,7 @@ cmd_gatt_discover_characteristic(int argc, char **argv) ble_uuid_any_t uuid; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -56,7 +56,7 @@ cmd_gatt_discover_characteristic(int argc, char **argv) return rc; } - rc = parse_arg_uuid("uuid", &uuid); + rc = parse_arg_ble_uuid("uuid", &uuid); if (rc == 0) { rc = btshell_disc_chrs_by_uuid(conn_handle, start_handle, end_handle, &uuid.u); @@ -82,7 +82,7 @@ cmd_gatt_discover_descriptor(int argc, char **argv) uint16_t end_handle; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -109,7 +109,7 @@ cmd_gatt_discover_service(int argc, char **argv) int conn_handle; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -120,7 +120,7 @@ cmd_gatt_discover_service(int argc, char **argv) return rc; } - rc = parse_arg_uuid("uuid", &uuid); + rc = parse_arg_ble_uuid("uuid", &uuid); if (rc == 0) { rc = btshell_disc_svc_by_uuid(conn_handle, &uuid.u); } else if (rc == ENOENT) { @@ -144,7 +144,7 @@ cmd_gatt_discover_full(int argc, char **argv) int conn_handle; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -174,7 +174,7 @@ cmd_gatt_exchange_mtu(int argc, char **argv) uint16_t conn_handle; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -204,7 +204,7 @@ cmd_gatt_notify(int argc, char **argv) uint16_t attr_handle; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -241,7 +241,7 @@ cmd_gatt_read(int argc, char **argv) bool is_var; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -279,7 +279,7 @@ cmd_gatt_read(int argc, char **argv) } } - rc = parse_arg_uuid("uuid", &uuid); + rc = parse_arg_ble_uuid("uuid", &uuid); if (rc == ENOENT) { is_uuid = 0; } else if (rc == 0) { @@ -351,7 +351,7 @@ cmd_gatt_service_changed(int argc, char **argv) uint16_t end; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -384,7 +384,7 @@ cmd_gatt_service_visibility(int argc, char **argv) bool vis; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -418,7 +418,7 @@ cmd_gatt_find_included_services(int argc, char **argv) uint16_t end_handle; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -482,13 +482,13 @@ cmd_gatt_write(int argc, char **argv) uint16_t offset; int total_attr_len; int num_attrs; - int attr_len; + unsigned int attr_len; int is_long; int no_rsp; int rc; int i; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } diff --git a/apps/btshell/src/cmd_l2cap.c b/apps/btshell/src/cmd_l2cap.c index e74e3bf33d..0c9d6a45fb 100644 --- a/apps/btshell/src/cmd_l2cap.c +++ b/apps/btshell/src/cmd_l2cap.c @@ -40,7 +40,7 @@ cmd_l2cap_update(int argc, char **argv) uint16_t conn_handle; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -101,7 +101,7 @@ cmd_l2cap_create_server(int argc, char **argv) int accept_response = 0; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -159,7 +159,7 @@ cmd_l2cap_connect(int argc, char **argv) uint8_t num; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -202,7 +202,7 @@ cmd_l2cap_disconnect(int argc, char **argv) uint16_t idx; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -234,7 +234,7 @@ cmd_l2cap_send(int argc, char **argv) uint16_t bytes; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -294,7 +294,7 @@ cmd_l2cap_reconfig(int argc, char **argv) int num; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -311,7 +311,7 @@ cmd_l2cap_reconfig(int argc, char **argv) return rc; } - rc = parse_arg_uint8_list_with_separator("idxs", ",", 5, idxs, &num); + rc = parse_arg_byte_stream_custom("idxs", ",", 5, idxs, 0, &num); if (rc != 0) { console_printf("invalid 'idxs' parameter\n"); return rc; diff --git a/apps/btshell/src/parse.c b/apps/btshell/src/parse.c index e4dbade420..d759511adc 100644 --- a/apps/btshell/src/parse.c +++ b/apps/btshell/src/parse.c @@ -19,633 +19,9 @@ #include #include -#include -#include -#include -#include -#include -#include "console/console.h" #include "host/ble_hs.h" -#include "host/ble_uuid.h" #include "host/ble_eddystone.h" #include "cmd.h" -#include "btshell.h" - -#define CMD_MAX_ARGS 16 - -static char *cmd_args[CMD_MAX_ARGS][2]; -static int cmd_num_args; - -int -parse_arg_find_idx(const char *key) -{ - int i; - - for (i = 0; i < cmd_num_args; i++) { - if (strcmp(cmd_args[i][0], key) == 0) { - return i; - } - } - - return -1; -} - -char * -parse_arg_peek(const char *key) -{ - int i; - - for (i = 0; i < cmd_num_args; i++) { - if (strcmp(cmd_args[i][0], key) == 0) { - return cmd_args[i][1]; - } - } - - return NULL; -} - -char * -parse_arg_extract(const char *key) -{ - int i; - - for (i = 0; i < cmd_num_args; i++) { - if (strcmp(cmd_args[i][0], key) == 0) { - /* Erase parameter. */ - cmd_args[i][0][0] = '\0'; - - return cmd_args[i][1]; - } - } - - return NULL; -} - -/** - * Determines which number base to use when parsing the specified numeric - * string. This just avoids base '0' so that numbers don't get interpreted as - * octal. - */ -static int -parse_arg_long_base(char *sval) -{ - if (sval[0] == '0' && sval[1] == 'x') { - return 0; - } else { - return 10; - } -} - -long -parse_long_bounds(char *sval, long min, long max, int *out_status) -{ - char *endptr; - long lval; - - lval = strtol(sval, &endptr, parse_arg_long_base(sval)); - if (sval[0] != '\0' && *endptr == '\0' && - lval >= min && lval <= max) { - - *out_status = 0; - return lval; - } - - *out_status = EINVAL; - return 0; -} - -long -parse_arg_long_bounds_peek(char *name, long min, long max, int *out_status) -{ - char *sval; - - sval = parse_arg_peek(name); - if (sval == NULL) { - *out_status = ENOENT; - return 0; - } - return parse_long_bounds(sval, min, max, out_status); -} - -long -parse_arg_long_bounds(char *name, long min, long max, int *out_status) -{ - char *sval; - - sval = parse_arg_extract(name); - if (sval == NULL) { - *out_status = ENOENT; - return 0; - } - return parse_long_bounds(sval, min, max, out_status); -} - -long -parse_arg_long_bounds_dflt(char *name, long min, long max, - long dflt, int *out_status) -{ - long val; - int rc; - - val = parse_arg_long_bounds(name, min, max, &rc); - if (rc == ENOENT) { - rc = 0; - val = dflt; - } - - *out_status = rc; - - return val; -} - -uint64_t -parse_arg_uint64_bounds(char *name, uint64_t min, uint64_t max, int *out_status) -{ - char *endptr; - char *sval; - uint64_t lval; - - sval = parse_arg_extract(name); - if (sval == NULL) { - *out_status = ENOENT; - return 0; - } - - lval = strtoull(sval, &endptr, parse_arg_long_base(sval)); - if (sval[0] != '\0' && *endptr == '\0' && - lval >= min && lval <= max) { - - *out_status = 0; - return lval; - } - - *out_status = EINVAL; - return 0; -} - -long -parse_arg_long(char *name, int *out_status) -{ - return parse_arg_long_bounds(name, LONG_MIN, LONG_MAX, out_status); -} - -uint8_t -parse_arg_bool(char *name, int *out_status) -{ - return parse_arg_long_bounds(name, 0, 1, out_status); -} - -uint8_t -parse_arg_bool_dflt(char *name, uint8_t dflt, int *out_status) -{ - return parse_arg_long_bounds_dflt(name, 0, 1, dflt, out_status); -} - -uint8_t -parse_arg_uint8(char *name, int *out_status) -{ - return parse_arg_long_bounds(name, 0, UINT8_MAX, out_status); -} - -uint16_t -parse_arg_uint16(char *name, int *out_status) -{ - return parse_arg_long_bounds(name, 0, UINT16_MAX, out_status); -} - -uint16_t -parse_arg_uint16_peek(char *name, int *out_status) -{ - return parse_arg_long_bounds_peek(name, 0, UINT16_MAX, out_status); -} - -uint32_t -parse_arg_uint32(char *name, int *out_status) -{ - return parse_arg_uint64_bounds(name, 0, UINT32_MAX, out_status); -} - -uint64_t -parse_arg_uint64(char *name, int *out_status) -{ - return parse_arg_uint64_bounds(name, 0, UINT64_MAX, out_status); -} - -uint8_t -parse_arg_uint8_dflt(char *name, uint8_t dflt, int *out_status) -{ - uint8_t val; - int rc; - - val = parse_arg_uint8(name, &rc); - if (rc == ENOENT) { - val = dflt; - rc = 0; - } - - *out_status = rc; - return val; -} - -uint16_t -parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status) -{ - uint16_t val; - int rc; - - val = parse_arg_uint16(name, &rc); - if (rc == ENOENT) { - val = dflt; - rc = 0; - } - - *out_status = rc; - return val; -} - -uint32_t -parse_arg_uint32_dflt(char *name, uint32_t dflt, int *out_status) -{ - uint32_t val; - int rc; - - val = parse_arg_uint32(name, &rc); - if (rc == ENOENT) { - val = dflt; - rc = 0; - } - - *out_status = rc; - return val; -} - -static uint32_t -parse_time_unit_mult(const char *str) -{ - if (!strcasecmp(str, "us")) { - return 1; - } else if (!strcasecmp(str, "ms")) { - return 1000; - } else if (!strcasecmp(str, "s")) { - return 1000000; - } - - return 0; -} - -static uint32_t -parse_time_us(const char *str, int *out_status) -{ - uint32_t val = 0; - uint32_t val_div = 1; - uint32_t val_mult = 1; - uint32_t val_us; - - while (isdigit((unsigned char)*str)) { - val *= 10; - val += *str - '0'; - str++; - } - - if (*str == '.') { - str++; - while (isdigit((unsigned char)*str)) { - val *= 10; - val += *str - '0'; - val_div *= 10; - str++; - } - } - - val_mult = parse_time_unit_mult(str); - if (val_mult == 0) { - *out_status = EINVAL; - return 0; - } - - if (val_mult > val_div) { - val_us = val * (val_mult / val_div); - } else { - val_us = val * (val_div / val_mult); - } - - *out_status = 0; - - return val_us; -} - -uint32_t -parse_arg_time_dflt(char *name, int step_us, uint32_t dflt, int *out_status) -{ - const char *arg; - uint32_t val; - int rc; - - arg = parse_arg_peek(name); - if (!arg) { - *out_status = 0; - return dflt; - } - - val = parse_time_us(arg, &rc); - if (rc) { - val = parse_arg_uint32(name, &rc); - if (rc == ENOENT) { - *out_status = 0; - return dflt; - } - } else { - val /= step_us; - parse_arg_extract(name); - } - - *out_status = rc; - return val; -} - -const struct kv_pair * -parse_kv_find(const struct kv_pair *kvs, char *name) -{ - const struct kv_pair *kv; - int i; - - for (i = 0; kvs[i].key != NULL; i++) { - kv = kvs + i; - if (strcmp(name, kv->key) == 0) { - return kv; - } - } - - return NULL; -} - -int -parse_arg_kv(char *name, const struct kv_pair *kvs, int *out_status) -{ - const struct kv_pair *kv; - char *sval; - - sval = parse_arg_extract(name); - if (sval == NULL) { - *out_status = ENOENT; - return -1; - } - - kv = parse_kv_find(kvs, sval); - if (kv == NULL) { - *out_status = EINVAL; - return -1; - } - - *out_status = 0; - return kv->val; -} - -int -parse_arg_kv_dflt(char *name, const struct kv_pair *kvs, int def_val, - int *out_status) -{ - int val; - int rc; - - val = parse_arg_kv(name, kvs, &rc); - if (rc == ENOENT) { - rc = 0; - val = def_val; - } - - *out_status = rc; - - return val; -} - - -static int -parse_arg_byte_stream_delim(char *sval, char *delims, int max_len, - uint8_t *dst, int *out_len) -{ - unsigned long ul; - char *endptr; - char *token; - int i; - char *tok_ptr; - - i = 0; - for (token = strtok_r(sval, delims, &tok_ptr); - token != NULL; - token = strtok_r(NULL, delims, &tok_ptr)) { - - if (i >= max_len) { - return EINVAL; - } - - ul = strtoul(token, &endptr, 16); - if (sval[0] == '\0' || *endptr != '\0' || ul > UINT8_MAX) { - return -1; - } - - dst[i] = ul; - i++; - } - - *out_len = i; - - return 0; -} - -int -parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len) -{ - char *sval; - - sval = parse_arg_extract(name); - if (sval == NULL) { - return ENOENT; - } - - return parse_arg_byte_stream_delim(sval, ":-", max_len, dst, out_len); -} - -int -parse_arg_uint8_list_with_separator(char *name, char *separator, int max_len, - uint8_t *dst, int *out_len) -{ - char *sval; - - sval = parse_arg_extract(name); - if (sval == NULL) { - return ENOENT; - } - - return parse_arg_byte_stream_delim(sval, separator, max_len, dst, out_len); -} - -int -parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len) -{ - int actual_len; - int rc; - - rc = parse_arg_byte_stream(name, len, dst, &actual_len); - if (rc != 0) { - return rc; - } - - if (actual_len != len) { - return EINVAL; - } - - return 0; -} - -static void -parse_reverse_bytes(uint8_t *bytes, int len) -{ - uint8_t tmp; - int i; - - for (i = 0; i < len / 2; i++) { - tmp = bytes[i]; - bytes[i] = bytes[len - i - 1]; - bytes[len - i - 1] = tmp; - } -} - -int -parse_arg_mac(char *name, uint8_t *dst) -{ - int rc; - - rc = parse_arg_byte_stream_exact_length(name, dst, 6); - if (rc != 0) { - return rc; - } - - parse_reverse_bytes(dst, 6); - - return 0; -} - -int -parse_arg_addr(char *name, ble_addr_t *addr) -{ - char *arg; - size_t len; - uint8_t addr_type; - bool addr_type_found; - int rc; - - arg = parse_arg_peek(name); - if (!arg) { - return ENOENT; - } - - len = strlen(arg); - if (len < 2) { - return EINVAL; - } - - addr_type_found = false; - if ((arg[len - 2] == ':') || (arg[len - 2] == '-')) { - if (tolower(arg[len - 1]) == 'p') { - addr_type = BLE_ADDR_PUBLIC; - addr_type_found = true; - } else if (tolower(arg[len - 1]) == 'r') { - addr_type = BLE_ADDR_RANDOM; - addr_type_found = true; - } - - if (addr_type_found) { - arg[len - 2] = '\0'; - } -} - - rc = parse_arg_mac(name, addr->val); - if (rc != 0) { - return rc; - } - - if (addr_type_found) { - addr->type = addr_type; - } else { - rc = EAGAIN; - } - - return rc; -} - -int -parse_arg_uuid(char *str, ble_uuid_any_t *uuid) -{ - uint16_t uuid16; - uint8_t val[16]; - int len; - int rc; - - uuid16 = parse_arg_uint16_peek(str, &rc); - switch (rc) { - case ENOENT: - parse_arg_extract(str); - return ENOENT; - - case 0: - len = 2; - val[0] = uuid16; - val[1] = uuid16 >> 8; - parse_arg_extract(str); - break; - - default: - len = 16; - rc = parse_arg_byte_stream_exact_length(str, val, 16); - if (rc != 0) { - return EINVAL; - } - parse_reverse_bytes(val, 16); - break; - } - - rc = ble_uuid_init_from_buf(uuid, val, len); - if (rc != 0) { - return EINVAL; - } else { - return 0; - } -} - -int -parse_arg_all(int argc, char **argv) -{ - char *key; - char *val; - int i; - char *tok_ptr; - - cmd_num_args = 0; - - for (i = 0; i < argc; i++) { - key = strtok_r(argv[i], "=", &tok_ptr); - val = strtok_r(NULL, "=", &tok_ptr); - - if (key != NULL && val != NULL) { - if (strlen(key) == 0) { - console_printf("Error: invalid argument: %s\n", argv[i]); - return -1; - } - - if (cmd_num_args >= CMD_MAX_ARGS) { - console_printf("Error: too many arguments"); - return -1; - } - - cmd_args[cmd_num_args][0] = key; - cmd_args[cmd_num_args][1] = val; - cmd_num_args++; - } - } - - return 0; -} int parse_eddystone_url(char *full_url, uint8_t *out_scheme, char *out_body, From 61e724ab23572889bab317f71012f463ecc1383b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 20 Jul 2023 15:28:16 +0200 Subject: [PATCH 0824/1333] apps/dtm: Port to parse_arg module Make use of common argument parsing code. --- apps/btshell/src/cmd.h | 3 - apps/dtm/pkg.yml | 1 + apps/dtm/src/main.c | 16 +- apps/dtm/src/parse.c | 529 ----------------------------------------- apps/dtm/src/parse.h | 58 ----- 5 files changed, 9 insertions(+), 598 deletions(-) delete mode 100644 apps/dtm/src/parse.c delete mode 100644 apps/dtm/src/parse.h diff --git a/apps/btshell/src/cmd.h b/apps/btshell/src/cmd.h index 0984d009b0..1477ea85c7 100644 --- a/apps/btshell/src/cmd.h +++ b/apps/btshell/src/cmd.h @@ -24,9 +24,6 @@ #include "host/ble_uuid.h" #include -//int parse_arg_mac(char *name, uint8_t *dst); -//int parse_arg_addr(char *name, ble_addr_t *addr); -//int parse_arg_uuid(char *name, ble_uuid_any_t *uuid); int parse_eddystone_url(char *full_url, uint8_t *out_scheme, char *out_body, uint8_t *out_body_len, uint8_t *out_suffix); diff --git a/apps/dtm/pkg.yml b/apps/dtm/pkg.yml index 2204befc41..bf1ced3640 100644 --- a/apps/dtm/pkg.yml +++ b/apps/dtm/pkg.yml @@ -28,6 +28,7 @@ pkg.deps: - "@apache-mynewt-core/sys/shell" - "@apache-mynewt-core/sys/console" - "@apache-mynewt-core/kernel/os" + - "@apache-mynewt-core/util/parse_arg" - "@apache-mynewt-nimble/nimble/host" - "@apache-mynewt-mcumgr/cmd/img_mgmt" - "@mcuboot/boot/bootutil" diff --git a/apps/dtm/src/main.c b/apps/dtm/src/main.c index 11f41160b4..3b1716180e 100644 --- a/apps/dtm/src/main.c +++ b/apps/dtm/src/main.c @@ -19,7 +19,7 @@ #include "os/mynewt.h" #include -#include +#include #include #include "nimble/ble.h" #include "nimble/nimble_opt.h" @@ -28,14 +28,14 @@ #include #include -static const struct kv_pair phy_opts[] = { +static const struct parse_arg_kv_pair phy_opts[] = { { "1M", 0x01 }, { "2M", 0x02 }, { "coded", 0x03 }, { NULL } }; -static const struct kv_pair modulation_index_opts[] = { +static const struct parse_arg_kv_pair modulation_index_opts[] = { { "standard", 0x00 }, { "stable", 0x01 }, { NULL } @@ -47,7 +47,7 @@ cmd_rx_test(int argc, char **argv) struct ble_dtm_rx_params params; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -87,7 +87,7 @@ cmd_tx_test(int argc, char **argv) struct ble_dtm_tx_params params; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -132,7 +132,7 @@ cmd_stop_test(int argc, char **argv) uint16_t num_packets; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -154,7 +154,7 @@ cmd_tx_power(int argc, char **argv) struct ble_hci_vs_set_tx_pwr_rp rsp; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } @@ -183,7 +183,7 @@ cmd_set_antenna(int argc, char **argv) struct ble_hci_vs_set_antenna_cp cmd; int rc; - rc = parse_arg_all(argc - 1, argv + 1); + rc = parse_arg_init(argc - 1, argv + 1); if (rc != 0) { return rc; } diff --git a/apps/dtm/src/parse.c b/apps/dtm/src/parse.c deleted file mode 100644 index ed79d74042..0000000000 --- a/apps/dtm/src/parse.c +++ /dev/null @@ -1,529 +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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "console/console.h" - -#define CMD_MAX_ARGS 16 - -static char *cmd_args[CMD_MAX_ARGS][2]; -static int cmd_num_args; - -int -parse_arg_find_idx(const char *key) -{ - int i; - - for (i = 0; i < cmd_num_args; i++) { - if (strcmp(cmd_args[i][0], key) == 0) { - return i; - } - } - - return -1; -} - -char * -parse_arg_peek(const char *key) -{ - int i; - - for (i = 0; i < cmd_num_args; i++) { - if (strcmp(cmd_args[i][0], key) == 0) { - return cmd_args[i][1]; - } - } - - return NULL; -} - -char * -parse_arg_extract(const char *key) -{ - int i; - - for (i = 0; i < cmd_num_args; i++) { - if (strcmp(cmd_args[i][0], key) == 0) { - /* Erase parameter. */ - cmd_args[i][0][0] = '\0'; - - return cmd_args[i][1]; - } - } - - return NULL; -} - -/** - * Determines which number base to use when parsing the specified numeric - * string. This just avoids base '0' so that numbers don't get interpreted as - * octal. - */ -static int -parse_arg_long_base(char *sval) -{ - if (sval[0] == '0' && sval[1] == 'x') { - return 0; - } else { - return 10; - } -} - -long -parse_long_bounds(char *sval, long min, long max, int *out_status) -{ - char *endptr; - long lval; - - lval = strtol(sval, &endptr, parse_arg_long_base(sval)); - if (sval[0] != '\0' && *endptr == '\0' && - lval >= min && lval <= max) { - - *out_status = 0; - return lval; - } - - *out_status = EINVAL; - return 0; -} - -long -parse_arg_long_bounds_peek(char *name, long min, long max, int *out_status) -{ - char *sval; - - sval = parse_arg_peek(name); - if (sval == NULL) { - *out_status = ENOENT; - return 0; - } - return parse_long_bounds(sval, min, max, out_status); -} - -long -parse_arg_long_bounds(char *name, long min, long max, int *out_status) -{ - char *sval; - - sval = parse_arg_extract(name); - if (sval == NULL) { - *out_status = ENOENT; - return 0; - } - return parse_long_bounds(sval, min, max, out_status); -} - -long -parse_arg_long_bounds_dflt(char *name, long min, long max, - long dflt, int *out_status) -{ - long val; - int rc; - - val = parse_arg_long_bounds(name, min, max, &rc); - if (rc == ENOENT) { - rc = 0; - val = dflt; - } - - *out_status = rc; - - return val; -} - -uint64_t -parse_arg_uint64_bounds(char *name, uint64_t min, uint64_t max, int *out_status) -{ - char *endptr; - char *sval; - uint64_t lval; - - sval = parse_arg_extract(name); - if (sval == NULL) { - *out_status = ENOENT; - return 0; - } - - lval = strtoull(sval, &endptr, parse_arg_long_base(sval)); - if (sval[0] != '\0' && *endptr == '\0' && - lval >= min && lval <= max) { - - *out_status = 0; - return lval; - } - - *out_status = EINVAL; - return 0; -} - -long -parse_arg_long(char *name, int *out_status) -{ - return parse_arg_long_bounds(name, LONG_MIN, LONG_MAX, out_status); -} - -uint8_t -parse_arg_bool(char *name, int *out_status) -{ - return parse_arg_long_bounds(name, 0, 1, out_status); -} - -uint8_t -parse_arg_bool_dflt(char *name, uint8_t dflt, int *out_status) -{ - return parse_arg_long_bounds_dflt(name, 0, 1, dflt, out_status); -} - -uint8_t -parse_arg_uint8(char *name, int *out_status) -{ - return parse_arg_long_bounds(name, 0, UINT8_MAX, out_status); -} - -uint16_t -parse_arg_uint16(char *name, int *out_status) -{ - return parse_arg_long_bounds(name, 0, UINT16_MAX, out_status); -} - -uint16_t -parse_arg_uint16_peek(char *name, int *out_status) -{ - return parse_arg_long_bounds_peek(name, 0, UINT16_MAX, out_status); -} - -uint32_t -parse_arg_uint32(char *name, int *out_status) -{ - return parse_arg_uint64_bounds(name, 0, UINT32_MAX, out_status); -} - -uint64_t -parse_arg_uint64(char *name, int *out_status) -{ - return parse_arg_uint64_bounds(name, 0, UINT64_MAX, out_status); -} - -uint8_t -parse_arg_uint8_dflt(char *name, uint8_t dflt, int *out_status) -{ - uint8_t val; - int rc; - - val = parse_arg_uint8(name, &rc); - if (rc == ENOENT) { - val = dflt; - rc = 0; - } - - *out_status = rc; - return val; -} - -uint16_t -parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status) -{ - uint16_t val; - int rc; - - val = parse_arg_uint16(name, &rc); - if (rc == ENOENT) { - val = dflt; - rc = 0; - } - - *out_status = rc; - return val; -} - -uint32_t -parse_arg_uint32_dflt(char *name, uint32_t dflt, int *out_status) -{ - uint32_t val; - int rc; - - val = parse_arg_uint32(name, &rc); - if (rc == ENOENT) { - val = dflt; - rc = 0; - } - - *out_status = rc; - return val; -} - -static uint32_t -parse_time_unit_mult(const char *str) -{ - if (!strcasecmp(str, "us")) { - return 1; - } else if (!strcasecmp(str, "ms")) { - return 1000; - } else if (!strcasecmp(str, "s")) { - return 1000000; - } - - return 0; -} - -static uint32_t -parse_time_us(const char *str, int *out_status) -{ - uint32_t val = 0; - uint32_t val_div = 1; - uint32_t val_mult = 1; - uint32_t val_us; - - while (isdigit((unsigned char)*str)) { - val *= 10; - val += *str - '0'; - str++; - } - - if (*str == '.') { - str++; - while (isdigit((unsigned char)*str)) { - val *= 10; - val += *str - '0'; - val_div *= 10; - str++; - } - } - - val_mult = parse_time_unit_mult(str); - if (val_mult == 0) { - *out_status = EINVAL; - return 0; - } - - if (val_mult > val_div) { - val_us = val * (val_mult / val_div); - } else { - val_us = val * (val_div / val_mult); - } - - *out_status = 0; - - return val_us; -} - -uint32_t -parse_arg_time_dflt(char *name, int step_us, uint32_t dflt, int *out_status) -{ - const char *arg; - uint32_t val; - int rc; - - arg = parse_arg_peek(name); - if (!arg) { - *out_status = 0; - return dflt; - } - - val = parse_time_us(arg, &rc); - if (rc) { - val = parse_arg_uint32(name, &rc); - if (rc == ENOENT) { - *out_status = 0; - return dflt; - } - } else { - val /= step_us; - parse_arg_extract(name); - } - - *out_status = rc; - return val; -} - -const struct kv_pair * -parse_kv_find(const struct kv_pair *kvs, char *name) -{ - const struct kv_pair *kv; - int i; - - for (i = 0; kvs[i].key != NULL; i++) { - kv = kvs + i; - if (strcmp(name, kv->key) == 0) { - return kv; - } - } - - return NULL; -} - -int -parse_arg_kv(char *name, const struct kv_pair *kvs, int *out_status) -{ - const struct kv_pair *kv; - char *sval; - - sval = parse_arg_extract(name); - if (sval == NULL) { - *out_status = ENOENT; - return -1; - } - - kv = parse_kv_find(kvs, sval); - if (kv == NULL) { - *out_status = EINVAL; - return -1; - } - - *out_status = 0; - return kv->val; -} - -int -parse_arg_kv_dflt(char *name, const struct kv_pair *kvs, int def_val, - int *out_status) -{ - int val; - int rc; - - val = parse_arg_kv(name, kvs, &rc); - if (rc == ENOENT) { - rc = 0; - val = def_val; - } - - *out_status = rc; - - return val; -} - - -static int -parse_arg_byte_stream_delim(char *sval, char *delims, int max_len, - uint8_t *dst, int *out_len) -{ - unsigned long ul; - char *endptr; - char *token; - int i; - char *tok_ptr; - - i = 0; - for (token = strtok_r(sval, delims, &tok_ptr); - token != NULL; - token = strtok_r(NULL, delims, &tok_ptr)) { - - if (i >= max_len) { - return EINVAL; - } - - ul = strtoul(token, &endptr, 16); - if (sval[0] == '\0' || *endptr != '\0' || ul > UINT8_MAX) { - return -1; - } - - dst[i] = ul; - i++; - } - - *out_len = i; - - return 0; -} - -int -parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len) -{ - char *sval; - - sval = parse_arg_extract(name); - if (sval == NULL) { - return ENOENT; - } - - return parse_arg_byte_stream_delim(sval, ":-", max_len, dst, out_len); -} - -int -parse_arg_uint8_list_with_separator(char *name, char *separator, int max_len, - uint8_t *dst, int *out_len) -{ - char *sval; - - sval = parse_arg_extract(name); - if (sval == NULL) { - return ENOENT; - } - - return parse_arg_byte_stream_delim(sval, separator, max_len, dst, out_len); -} - -int -parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len) -{ - int actual_len; - int rc; - - rc = parse_arg_byte_stream(name, len, dst, &actual_len); - if (rc != 0) { - return rc; - } - - if (actual_len != len) { - return EINVAL; - } - - return 0; -} - -int -parse_arg_all(int argc, char **argv) -{ - char *key; - char *val; - int i; - char *tok_ptr; - - cmd_num_args = 0; - - for (i = 0; i < argc; i++) { - key = strtok_r(argv[i], "=", &tok_ptr); - val = strtok_r(NULL, "=", &tok_ptr); - - if (key != NULL && val != NULL) { - if (strlen(key) == 0) { - console_printf("Error: invalid argument: %s\n", argv[i]); - return -1; - } - - if (cmd_num_args >= CMD_MAX_ARGS) { - console_printf("Error: too many arguments"); - return -1; - } - - cmd_args[cmd_num_args][0] = key; - cmd_args[cmd_num_args][1] = val; - cmd_num_args++; - } - } - - return 0; -} diff --git a/apps/dtm/src/parse.h b/apps/dtm/src/parse.h deleted file mode 100644 index a0255d368f..0000000000 --- a/apps/dtm/src/parse.h +++ /dev/null @@ -1,58 +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 PARSE_H -#define PARSE_H - -#include - -struct kv_pair { - char *key; - int val; -}; - -uint32_t parse_arg_time_dflt(char *name, int step, uint32_t dflt, int *out_status); -const struct kv_pair *parse_kv_find(const struct kv_pair *kvs, char *name); -int parse_arg_find_idx(const char *key); -char *parse_arg_extract(const char *key); -long parse_arg_long_bounds(char *name, long min, long max, int *out_status); -long parse_arg_long_bounds_dflt(char *name, long min, long max, - long dflt, int *out_status); -uint64_t parse_arg_uint64_bounds(char *name, uint64_t min, - uint64_t max, int *out_status); -long parse_arg_long(char *name, int *staus); -uint8_t parse_arg_bool(char *name, int *status); -uint8_t parse_arg_bool_dflt(char *name, uint8_t dflt, int *out_status); -uint8_t parse_arg_uint8(char *name, int *status); -uint8_t parse_arg_uint8_dflt(char *name, uint8_t dflt, int *out_status); -uint16_t parse_arg_uint16(char *name, int *status); -uint16_t parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status); -uint32_t parse_arg_uint32(char *name, int *out_status); -uint32_t parse_arg_uint32_dflt(char *name, uint32_t dflt, int *out_status); -uint64_t parse_arg_uint64(char *name, int *out_status); -int parse_arg_kv(char *name, const struct kv_pair *kvs, int *out_status); -int parse_arg_kv_dflt(char *name, const struct kv_pair *kvs, int def_val, - int *out_status); -int parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len); -int parse_arg_uint8_list_with_separator(char *name, char *separator, int max_len, - uint8_t *dst, int *out_len); -int parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len); -int parse_arg_all(int argc, char **argv); - -#endif From acc3ee912a0b973f85ad912c20e2e390e0d33484 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 25 Sep 2023 13:45:02 +0200 Subject: [PATCH 0825/1333] Update samples to use mynewt_main instead of main Mynewt core was updated to use mynewt_main. --- apps/advertiser/src/main.c | 2 +- apps/blecent/src/main.c | 17 ++------------- apps/blecsc/src/main.c | 2 +- apps/blehci/src/main.c | 17 ++------------- apps/blehr/src/main.c | 2 +- apps/blemesh/src/main.c | 7 +------ apps/blemesh_light/src/main.c | 2 +- apps/blemesh_models_example_1/src/main.c | 7 ++----- apps/blemesh_models_example_2/src/main.c | 7 ++----- apps/blemesh_shell/src/main.c | 2 +- apps/bleprph/src/main.c | 17 ++------------- apps/blestress/src/main.c | 2 +- apps/btshell/src/main.c | 21 ++----------------- apps/bttester/src/main.c | 6 +----- apps/central/src/main.c | 2 +- apps/dtm/src/main.c | 2 +- apps/ext_advertiser/src/main.c | 2 +- apps/mesh_badge/src/main.c | 3 ++- apps/peripheral/src/main.c | 2 +- apps/scanner/src/main.c | 2 +- babblesim/core/src/main_config.c | 4 ++-- .../nordic/nrf52_bsim/include/mcu/mcu_sim.h | 2 -- docs/ble_setup/ble_sync_cb.rst | 2 +- 23 files changed, 30 insertions(+), 102 deletions(-) diff --git a/apps/advertiser/src/main.c b/apps/advertiser/src/main.c index 486d5c59a0..245d7410b2 100644 --- a/apps/advertiser/src/main.c +++ b/apps/advertiser/src/main.c @@ -114,7 +114,7 @@ on_reset(int reason) } int -main(int argc, char **argv) +mynewt_main(int argc, char **argv) { int rc; diff --git a/apps/blecent/src/main.c b/apps/blecent/src/main.c index f794937e22..57d5d10910 100644 --- a/apps/blecent/src/main.c +++ b/apps/blecent/src/main.c @@ -495,8 +495,8 @@ blecent_on_sync(void) * * @return int NOTE: this function should never return! */ -static int -main_fn(int argc, char **argv) +int +mynewt_main(int argc, char **argv) { int rc; @@ -523,16 +523,3 @@ main_fn(int argc, char **argv) return 0; } - -int -main(int argc, char **argv) -{ -#if BABBLESIM - extern void bsim_init(int argc, char** argv, void *main_fn); - bsim_init(argc, argv, main_fn); -#else - main_fn(argc, argv); -#endif - - return 0; -} diff --git a/apps/blecsc/src/main.c b/apps/blecsc/src/main.c index 5cca6b77ec..993824084a 100644 --- a/apps/blecsc/src/main.c +++ b/apps/blecsc/src/main.c @@ -278,7 +278,7 @@ blecsc_on_sync(void) * @return int NOTE: this function should never return! */ int -main(void) +mynewt_main(int argc, char **argv) { int rc; diff --git a/apps/blehci/src/main.c b/apps/blehci/src/main.c index e97e54270f..848d705031 100644 --- a/apps/blehci/src/main.c +++ b/apps/blehci/src/main.c @@ -19,8 +19,8 @@ #include "os/mynewt.h" -static int -main_fn(int argc, char **argv) +int +mynewt_main(int argc, char **argv) { /* Initialize OS */ sysinit(); @@ -30,16 +30,3 @@ main_fn(int argc, char **argv) } return 0; } - -int -main(int argc, char **argv) -{ -#if BABBLESIM - extern void bsim_init(int argc, char** argv, void *main_fn); - bsim_init(argc, argv, main_fn); -#else - main_fn(argc, argv); -#endif - - return 0; -} \ No newline at end of file diff --git a/apps/blehr/src/main.c b/apps/blehr/src/main.c index e6dac7ce62..dad16c7b2b 100644 --- a/apps/blehr/src/main.c +++ b/apps/blehr/src/main.c @@ -229,7 +229,7 @@ blehr_on_sync(void) * @return int NOTE: this function should never return! */ int -main(void) +mynewt_main(int argc, char **argv) { int rc; diff --git a/apps/blemesh/src/main.c b/apps/blemesh/src/main.c index 56d0476f86..e11ceb8f5c 100644 --- a/apps/blemesh/src/main.c +++ b/apps/blemesh/src/main.c @@ -442,13 +442,8 @@ blemesh_on_sync(void) } int -main(int argc, char **argv) +mynewt_main(int argc, char **argv) { - -#ifdef ARCH_sim - mcu_sim_parse_args(argc, argv); -#endif - /* Initialize OS */ sysinit(); diff --git a/apps/blemesh_light/src/main.c b/apps/blemesh_light/src/main.c index 70deede10a..b90888c2c5 100644 --- a/apps/blemesh_light/src/main.c +++ b/apps/blemesh_light/src/main.c @@ -96,7 +96,7 @@ blemesh_on_sync(void) } int -main(void) +mynewt_main(int argc, char **argv) { /* Initialize OS */ sysinit(); diff --git a/apps/blemesh_models_example_1/src/main.c b/apps/blemesh_models_example_1/src/main.c index 80a69c7052..e3ab7559e3 100644 --- a/apps/blemesh_models_example_1/src/main.c +++ b/apps/blemesh_models_example_1/src/main.c @@ -652,12 +652,9 @@ blemesh_on_sync(void) console_printf("Mesh initialized\n"); } -int main(void) +int +mynewt_main(int argc, char **argv) { -#ifdef ARCH_sim - mcu_sim_parse_args(argc, argv); -#endif - /* Initialize OS */ sysinit(); diff --git a/apps/blemesh_models_example_2/src/main.c b/apps/blemesh_models_example_2/src/main.c index 741367b401..979395d219 100644 --- a/apps/blemesh_models_example_2/src/main.c +++ b/apps/blemesh_models_example_2/src/main.c @@ -214,12 +214,9 @@ void bt_initialized(void) short_time_multireset_bt_mesh_unprovisioning(); } -int main(void) +int +mynewt_main(int argc, char **argv) { -#ifdef ARCH_sim - mcu_sim_parse_args(argc, argv); -#endif - /* Initialize OS */ sysinit(); diff --git a/apps/blemesh_shell/src/main.c b/apps/blemesh_shell/src/main.c index fcf80127f0..fb9c9e6915 100644 --- a/apps/blemesh_shell/src/main.c +++ b/apps/blemesh_shell/src/main.c @@ -95,7 +95,7 @@ blemesh_on_sync(void) } int -main(void) +mynewt_main(int argc, char **argv) { /* Initialize OS */ sysinit(); diff --git a/apps/bleprph/src/main.c b/apps/bleprph/src/main.c index 60a3aea9dc..b9f2d26416 100644 --- a/apps/bleprph/src/main.c +++ b/apps/bleprph/src/main.c @@ -302,8 +302,8 @@ bleprph_on_sync(void) * * @return int NOTE: this function should never return! */ -static int -main_fn(int argc, char **argv) +int +mynewt_main(int argc, char **argv) { #if MYNEWT_VAL(BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM) >= 0 struct image_version ver; @@ -357,16 +357,3 @@ main_fn(int argc, char **argv) } return 0; } - -int -main(int argc, char **argv) -{ -#if BABBLESIM - extern void bsim_init(int argc, char** argv, void *main_fn); - bsim_init(argc, argv, main_fn); -#else - main_fn(argc, argv); -#endif - - return 0; -} diff --git a/apps/blestress/src/main.c b/apps/blestress/src/main.c index ec28ed8a65..c19e0cdd32 100644 --- a/apps/blestress/src/main.c +++ b/apps/blestress/src/main.c @@ -66,7 +66,7 @@ stress_test_on_sync(void) * @return int NOTE: this function should never return! */ int -main(void) +mynewt_main(int argc, char **argv) { int rc; diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index 4c4a6bb787..aaa423ea8b 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -2626,15 +2626,11 @@ btshell_get_default_own_addr_type(void) * * @return int NOTE: this function should never return! */ -static int -main_fn(int argc, char **argv) +int +mynewt_main(int argc, char **argv) { int rc; -#ifdef ARCH_sim - mcu_sim_parse_args(argc, argv); -#endif - /* Initialize OS */ sysinit(); @@ -2703,16 +2699,3 @@ main_fn(int argc, char **argv) return 0; } - -int -main(int argc, char **argv) -{ -#if BABBLESIM - extern void bsim_init(int argc, char** argv, void *main_fn); - bsim_init(argc, argv, main_fn); -#else - main_fn(argc, argv); -#endif - - return 0; -} diff --git a/apps/bttester/src/main.c b/apps/bttester/src/main.c index 99dff7e3de..242133056e 100644 --- a/apps/bttester/src/main.c +++ b/apps/bttester/src/main.c @@ -48,14 +48,10 @@ on_sync(void) } int -main(int argc, char **argv) +mynewt_main(int argc, char **argv) { int rc; -#ifdef ARCH_sim - mcu_sim_parse_args(argc, argv); -#endif - /* Initialize OS */ sysinit(); diff --git a/apps/central/src/main.c b/apps/central/src/main.c index c088b947f2..1373ad07b5 100755 --- a/apps/central/src/main.c +++ b/apps/central/src/main.c @@ -168,7 +168,7 @@ on_reset(int reason) } int -main(int argc, char **argv) +mynewt_main(int argc, char **argv) { /* Initialize all packages. */ sysinit(); diff --git a/apps/dtm/src/main.c b/apps/dtm/src/main.c index 3b1716180e..f3e218bc88 100644 --- a/apps/dtm/src/main.c +++ b/apps/dtm/src/main.c @@ -302,7 +302,7 @@ on_reset(int reason) } int -main(void) +mynewt_main(int argc, char **argv) { struct image_version the_version; char prompt[50]; diff --git a/apps/ext_advertiser/src/main.c b/apps/ext_advertiser/src/main.c index ec7649ef43..ca450b1441 100644 --- a/apps/ext_advertiser/src/main.c +++ b/apps/ext_advertiser/src/main.c @@ -526,7 +526,7 @@ on_sync(void) * @return int NOTE: this function should never return! */ int -main(void) +mynewt_main(int argc, char **argv) { /* Initialize OS */ sysinit(); diff --git a/apps/mesh_badge/src/main.c b/apps/mesh_badge/src/main.c index d856d81632..b6b931fce7 100644 --- a/apps/mesh_badge/src/main.c +++ b/apps/mesh_badge/src/main.c @@ -360,7 +360,8 @@ int bt_set_name(const char *name) return 0; } -int main(void) +int +mynewt_main(int argc, char **argv) { int err; diff --git a/apps/peripheral/src/main.c b/apps/peripheral/src/main.c index 28e8afb141..03816b4db4 100755 --- a/apps/peripheral/src/main.c +++ b/apps/peripheral/src/main.c @@ -145,7 +145,7 @@ on_reset(int reason) } int -main(int argc, char **argv) +mynewt_main(int argc, char **argv) { int rc; diff --git a/apps/scanner/src/main.c b/apps/scanner/src/main.c index 5158d0d5cb..016a567c77 100644 --- a/apps/scanner/src/main.c +++ b/apps/scanner/src/main.c @@ -243,7 +243,7 @@ on_reset(int reason) } int -main(int argc, char **argv) +mynewt_main(int argc, char **argv) { /* Initialize all packages. */ sysinit(); diff --git a/babblesim/core/src/main_config.c b/babblesim/core/src/main_config.c index ef8cb04d2e..467ae6234b 100644 --- a/babblesim/core/src/main_config.c +++ b/babblesim/core/src/main_config.c @@ -47,7 +47,7 @@ main_clean_up_trace_wrap(void) } void -bsim_init(int argc, char** argv, int (*main_fn)(int argc, char **arg)) +main(int argc, char** argv) { setvbuf(stdout, NULL, _IOLBF, 512); setvbuf(stderr, NULL, _IOLBF, 512); @@ -64,7 +64,7 @@ bsim_init(int argc, char** argv, int (*main_fn)(int argc, char **arg)) bs_read_function_names_from_Tsymbols(argv[0]); nrf_hw_initialize(&args->nrf_hw); - os_init(main_fn); + os_init(mynewt_main); os_start(); while (1) { diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/mcu_sim.h b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/mcu_sim.h index 26f6cb9842..0cb6fc52b7 100644 --- a/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/mcu_sim.h +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/mcu_sim.h @@ -27,8 +27,6 @@ extern char *native_flash_file; extern char *native_uart_log_file; extern const char *native_uart_dev_strs[]; -void mcu_sim_parse_args(int argc, char **argv); - void static inline hal_debug_break(void) {} #ifdef __cplusplus diff --git a/docs/ble_setup/ble_sync_cb.rst b/docs/ble_setup/ble_sync_cb.rst index b14a3582a4..a01d51475e 100644 --- a/docs/ble_setup/ble_sync_cb.rst +++ b/docs/ble_setup/ble_sync_cb.rst @@ -65,7 +65,7 @@ reset callbacks. } int - main(void) + mynewt_main(int argc, char **argv) { /* Initialize all packages. */ sysinit(); From f9c3512d2a687130c16b725ae83a1c0ca3946169 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 25 Sep 2023 15:41:54 +0200 Subject: [PATCH 0826/1333] ci: Build tests under standard project folder tree This uses standard folder tree to build tests (where nimble is in repos folder, and not as a top project folder). --- .github/project.yml | 28 ++-------- .github/project_ports.yml | 56 ------------------- .../targets/nordic_pca10028_blehci/pkg.yml | 4 +- .../targets/nordic_pca10056_btshell/pkg.yml | 4 +- .../targets/nordic_pca10095_btshell/pkg.yml | 4 +- .github/targets_linux/native_btshell/pkg.yml | 2 +- .../nordic_pca10028_boot/pkg.yml | 4 +- .../nordic_pca10028_bt5_blehci/pkg.yml | 4 +- .../nordic_pca10056-blehci-usb/pkg.yml | 2 +- .../nordic_pca10056_advertiser/pkg.yml | 2 +- .../nordic_pca10056_blecent/pkg.yml | 2 +- .../nordic_pca10056_blecsc/pkg.yml | 2 +- .../nordic_pca10056_blehci/pkg.yml | 2 +- .../pkg.yml | 2 +- .../nordic_pca10056_blehci_no_privacy/pkg.yml | 2 +- .../nordic_pca10056_blehr/pkg.yml | 2 +- .../nordic_pca10056_blemesh/pkg.yml | 2 +- .../nordic_pca10056_blemesh_cdb/pkg.yml | 2 +- .../nordic_pca10056_blemesh_ext_adv/pkg.yml | 2 +- .../nordic_pca10056_blemesh_light/pkg.yml | 2 +- .../pkg.yml | 2 +- .../pkg.yml | 2 +- .../nordic_pca10056_blemesh_shell/pkg.yml | 2 +- .../nordic_pca10056_blemesh_storage/pkg.yml | 2 +- .../nordic_pca10056_bleprph/pkg.yml | 2 +- .../nordic_pca10056_bleprph_oic/pkg.yml | 2 +- .../nordic_pca10056_blesplit/pkg.yml | 2 +- .../nordic_pca10056_bleuart/pkg.yml | 2 +- .../nordic_pca10056_btshell_2M/pkg.yml | 2 +- .../nordic_pca10056_btshell_2M_coded/pkg.yml | 2 +- .../nordic_pca10056_btshell_all/pkg.yml | 4 +- .../nordic_pca10056_btshell_all_v52/pkg.yml | 4 +- .../nordic_pca10056_btshell_coded/pkg.yml | 2 +- .../nordic_pca10056_btshell_ext_adv/pkg.yml | 2 +- .../pkg.yml | 2 +- .../nordic_pca10056_btshell_sm_legacy/pkg.yml | 2 +- .../nordic_pca10056_btshell_sm_none/pkg.yml | 2 +- .../nordic_pca10056_btshell_sm_sc/pkg.yml | 2 +- .../pkg.yml | 2 +- .../pkg.yml | 4 +- .../nordic_pca10056_bttester/pkg.yml | 4 +- .../targets_linux/nordic_pca10056_dtm/pkg.yml | 4 +- .../nordic_pca10056_ext_advertiser/pkg.yml | 4 +- .../nordic_pca10056_scanner/pkg.yml | 2 +- .../nordic_pca10095_blehci/pkg.yml | 4 +- .github/workflows/build_ports.yml | 3 + .github/workflows/build_targets.yml | 36 +++++++----- .github/workflows/compliance_check.yml | 4 ++ .github/workflows/newt_test_all.yml | 23 +++++--- .github/workflows/ports_syscfg_check.yml | 25 +++++---- 50 files changed, 117 insertions(+), 168 deletions(-) delete mode 100644 .github/project_ports.yml diff --git a/.github/project.yml b/.github/project.yml index 10eb2dfce2..4d81374169 100644 --- a/.github/project.yml +++ b/.github/project.yml @@ -6,7 +6,7 @@ # 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, @@ -17,34 +17,16 @@ # under the License. # -project.name: "apache-mynewt-nimble" +project.name: "my_project" project.repositories: - apache-mynewt-core - - mcuboot - - apache-mynewt-mcumgr +# Use github's distribution mechanism for core ASF libraries. +# This provides mirroring automatically for us. +# repository.apache-mynewt-core: type: github vers: 0.0.0 user: apache repo: mynewt-core - -repository.mcuboot: - type: github - vers: 0.0.0 - user: mcu-tools - repo: mcuboot - branch: main - -repository.apache-mynewt-mcumgr: - type: github - vers: 0.0.0 - user: apache - repo: mynewt-mcumgr - -repository.tinyusb: - type: github - vers: 0.0.0 - user: hathach - repo: tinyusb diff --git a/.github/project_ports.yml b/.github/project_ports.yml deleted file mode 100644 index 0a9b2cf01b..0000000000 --- a/.github/project_ports.yml +++ /dev/null @@ -1,56 +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. -# - -project.name: "apache-mynewt-nimble" - -project.repositories: - - apache-mynewt-core - - mcuboot - - apache-mynewt-mcumgr - -repository.apache-mynewt-core: - type: github - vers: 0.0.0 - user: apache - repo: mynewt-core - -repository.apache-mynewt-nimble: - type: github - vers: 0.0.0 - user: apache - repo: mynewt-nimble - -repository.mcuboot: - type: github - vers: 0.0.0 - user: mcu-tools - repo: mcuboot - branch: main - -repository.apache-mynewt-mcumgr: - type: github - vers: 0.0.0 - user: apache - repo: mynewt-mcumgr - -repository.tinyusb: - type: github - vers: 0.0.0 - user: hathach - repo: tinyusb diff --git a/.github/targets/nordic_pca10028_blehci/pkg.yml b/.github/targets/nordic_pca10028_blehci/pkg.yml index b3504c3d90..1cf0a3629c 100644 --- a/.github/targets/nordic_pca10028_blehci/pkg.yml +++ b/.github/targets/nordic_pca10028_blehci/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: "targets_ci/blehci-nordic_pca10028 -pkg.name: "targets_ci/nordic_pca10028_blehci" +### Package: "targets/blehci-nordic_pca10028 +pkg.name: "targets/nordic_pca10028_blehci" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10056_btshell/pkg.yml b/.github/targets/nordic_pca10056_btshell/pkg.yml index 287ca4e3c3..adcbd6990a 100644 --- a/.github/targets/nordic_pca10056_btshell/pkg.yml +++ b/.github/targets/nordic_pca10056_btshell/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: "targets_ci/nordic_pca10056_btshell -pkg.name: "targets_ci/nordic_pca10056_btshell" +### Package: "targets/nordic_pca10056_btshell +pkg.name: "targets/nordic_pca10056_btshell" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets/nordic_pca10095_btshell/pkg.yml b/.github/targets/nordic_pca10095_btshell/pkg.yml index 889405d345..c669e30ea3 100644 --- a/.github/targets/nordic_pca10095_btshell/pkg.yml +++ b/.github/targets/nordic_pca10095_btshell/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: "targets_ci/nordic_pca10056_btshell -pkg.name: "targets_ci/nordic_pca10095_btshell" +### Package: "targets/nordic_pca10056_btshell +pkg.name: "targets/nordic_pca10095_btshell" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/native_btshell/pkg.yml b/.github/targets_linux/native_btshell/pkg.yml index 870ccae9ca..a252525536 100644 --- a/.github/targets_linux/native_btshell/pkg.yml +++ b/.github/targets_linux/native_btshell/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: targets_ci/native_btshell +pkg.name: targets/native_btshell pkg.type: target pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10028_boot/pkg.yml b/.github/targets_linux/nordic_pca10028_boot/pkg.yml index 6cf0c922e3..de320d8b7a 100644 --- a/.github/targets_linux/nordic_pca10028_boot/pkg.yml +++ b/.github/targets_linux/nordic_pca10028_boot/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: "targets_ci/nordic_pca10028_boot -pkg.name: "targets_ci/nordic_pca10028_boot" +### Package: "targets/nordic_pca10028_boot +pkg.name: "targets/nordic_pca10028_boot" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10028_bt5_blehci/pkg.yml b/.github/targets_linux/nordic_pca10028_bt5_blehci/pkg.yml index 80774bfd45..02bb6e8e4e 100644 --- a/.github/targets_linux/nordic_pca10028_bt5_blehci/pkg.yml +++ b/.github/targets_linux/nordic_pca10028_bt5_blehci/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: "targets_ci/nordic_pca10028_bt5_blehci -pkg.name: "targets_ci/nordic_pca10028_bt5_blehci" +### Package: "targets/nordic_pca10028_bt5_blehci +pkg.name: "targets/nordic_pca10028_bt5_blehci" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056-blehci-usb/pkg.yml b/.github/targets_linux/nordic_pca10056-blehci-usb/pkg.yml index 4f92d9b96a..2c8307d3df 100644 --- a/.github/targets_linux/nordic_pca10056-blehci-usb/pkg.yml +++ b/.github/targets_linux/nordic_pca10056-blehci-usb/pkg.yml @@ -16,7 +16,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056-blehci-usb" +pkg.name: "targets/nordic_pca10056-blehci-usb" pkg.type: target pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_advertiser/pkg.yml b/.github/targets_linux/nordic_pca10056_advertiser/pkg.yml index 6de3362b52..84d0c05b34 100644 --- a/.github/targets_linux/nordic_pca10056_advertiser/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_advertiser/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_advertiser" +pkg.name: "targets/nordic_pca10056_advertiser" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_blecent/pkg.yml b/.github/targets_linux/nordic_pca10056_blecent/pkg.yml index 64dbe8b51a..d47c0544da 100644 --- a/.github/targets_linux/nordic_pca10056_blecent/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_blecent/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_blecent" +pkg.name: "targets/nordic_pca10056_blecent" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_blecsc/pkg.yml b/.github/targets_linux/nordic_pca10056_blecsc/pkg.yml index 65a125ca35..f26c7df69a 100644 --- a/.github/targets_linux/nordic_pca10056_blecsc/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_blecsc/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_blecsc" +pkg.name: "targets/nordic_pca10056_blecsc" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_blehci/pkg.yml b/.github/targets_linux/nordic_pca10056_blehci/pkg.yml index 204f4a5f36..b66dab9879 100644 --- a/.github/targets_linux/nordic_pca10056_blehci/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_blehci/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_blehci" +pkg.name: "targets/nordic_pca10056_blehci" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_blehci_all_enabled/pkg.yml b/.github/targets_linux/nordic_pca10056_blehci_all_enabled/pkg.yml index 6ede68c23a..c44ac2824a 100644 --- a/.github/targets_linux/nordic_pca10056_blehci_all_enabled/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_blehci_all_enabled/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_blehci_all_enabled" +pkg.name: "targets/nordic_pca10056_blehci_all_enabled" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_blehci_no_privacy/pkg.yml b/.github/targets_linux/nordic_pca10056_blehci_no_privacy/pkg.yml index ed7e725dd1..539a36409e 100644 --- a/.github/targets_linux/nordic_pca10056_blehci_no_privacy/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_blehci_no_privacy/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_blehci_no_privacy" +pkg.name: "targets/nordic_pca10056_blehci_no_privacy" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_blehr/pkg.yml b/.github/targets_linux/nordic_pca10056_blehr/pkg.yml index aa37aa0e1c..fd7e6fa90d 100644 --- a/.github/targets_linux/nordic_pca10056_blehr/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_blehr/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_blehr" +pkg.name: "targets/nordic_pca10056_blehr" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_blemesh/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh/pkg.yml index 04f35835ae..b1785b01b5 100644 --- a/.github/targets_linux/nordic_pca10056_blemesh/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_blemesh/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_blemesh" +pkg.name: "targets/nordic_pca10056_blemesh" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_blemesh_cdb/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_cdb/pkg.yml index 1c059a402e..2a85a98817 100644 --- a/.github/targets_linux/nordic_pca10056_blemesh_cdb/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_blemesh_cdb/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_blemesh_cdb" +pkg.name: "targets/nordic_pca10056_blemesh_cdb" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/pkg.yml index 1f8c88d3b8..3fec50f689 100644 --- a/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_blemesh_ext_adv" +pkg.name: "targets/nordic_pca10056_blemesh_ext_adv" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_blemesh_light/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_light/pkg.yml index cfb98f674a..991cccfd73 100644 --- a/.github/targets_linux/nordic_pca10056_blemesh_light/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_blemesh_light/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_blemesh_light" +pkg.name: "targets/nordic_pca10056_blemesh_light" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_blemesh_models_example_1/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_models_example_1/pkg.yml index 68b8325b87..38c54781ae 100644 --- a/.github/targets_linux/nordic_pca10056_blemesh_models_example_1/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_blemesh_models_example_1/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_blemesh_models_example_1" +pkg.name: "targets/nordic_pca10056_blemesh_models_example_1" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_blemesh_models_example_2/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_models_example_2/pkg.yml index 2944216a51..b17b652583 100644 --- a/.github/targets_linux/nordic_pca10056_blemesh_models_example_2/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_blemesh_models_example_2/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_blemesh_models_example_2" +pkg.name: "targets/nordic_pca10056_blemesh_models_example_2" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_blemesh_shell/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_shell/pkg.yml index e0bb36a941..4636feb41a 100644 --- a/.github/targets_linux/nordic_pca10056_blemesh_shell/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_blemesh_shell/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_blemesh_shell" +pkg.name: "targets/nordic_pca10056_blemesh_shell" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_blemesh_storage/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_storage/pkg.yml index 7a04e49ac5..ff17acfcc0 100644 --- a/.github/targets_linux/nordic_pca10056_blemesh_storage/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_blemesh_storage/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_blemesh_storage" +pkg.name: "targets/nordic_pca10056_blemesh_storage" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_bleprph/pkg.yml b/.github/targets_linux/nordic_pca10056_bleprph/pkg.yml index 4beaa1fca0..d1e7b95eea 100644 --- a/.github/targets_linux/nordic_pca10056_bleprph/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_bleprph/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_bleprph" +pkg.name: "targets/nordic_pca10056_bleprph" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_bleprph_oic/pkg.yml b/.github/targets_linux/nordic_pca10056_bleprph_oic/pkg.yml index 2c2f231e58..aef9c2eb2e 100644 --- a/.github/targets_linux/nordic_pca10056_bleprph_oic/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_bleprph_oic/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_bleprph_oic" +pkg.name: "targets/nordic_pca10056_bleprph_oic" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_blesplit/pkg.yml b/.github/targets_linux/nordic_pca10056_blesplit/pkg.yml index d62ab79c46..8781b07ae0 100644 --- a/.github/targets_linux/nordic_pca10056_blesplit/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_blesplit/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_blesplit" +pkg.name: "targets/nordic_pca10056_blesplit" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_bleuart/pkg.yml b/.github/targets_linux/nordic_pca10056_bleuart/pkg.yml index 0ae1073dec..f3f3ce922d 100644 --- a/.github/targets_linux/nordic_pca10056_bleuart/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_bleuart/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_bleuart" +pkg.name: "targets/nordic_pca10056_bleuart" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_btshell_2M/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_2M/pkg.yml index e555575641..fc2db1d019 100644 --- a/.github/targets_linux/nordic_pca10056_btshell_2M/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_btshell_2M/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_btshell_2M" +pkg.name: "targets/nordic_pca10056_btshell_2M" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_btshell_2M_coded/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_2M_coded/pkg.yml index a0b8ad888a..0ddee925fb 100644 --- a/.github/targets_linux/nordic_pca10056_btshell_2M_coded/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_btshell_2M_coded/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_btshell_2M_coded" +pkg.name: "targets/nordic_pca10056_btshell_2M_coded" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_btshell_all/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_all/pkg.yml index 5ac5cc77d9..4a867f7aa9 100644 --- a/.github/targets_linux/nordic_pca10056_btshell_all/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_btshell_all/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: "targets_ci/nordic_pca10056_btshell_all -pkg.name: "targets_ci/nordic_pca10056_btshell_all" +### Package: "targets/nordic_pca10056_btshell_all +pkg.name: "targets/nordic_pca10056_btshell_all" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_btshell_all_v52/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_all_v52/pkg.yml index e218c511c1..d677ba1c24 100644 --- a/.github/targets_linux/nordic_pca10056_btshell_all_v52/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_btshell_all_v52/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: "targets_ci/nordic_pca10056_btshell_all_v52 -pkg.name: "targets_ci/nordic_pca10056_btshell_all_v52" +### Package: "targets/nordic_pca10056_btshell_all_v52 +pkg.name: "targets/nordic_pca10056_btshell_all_v52" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_btshell_coded/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_coded/pkg.yml index 87a1eb64cf..c3ec70a308 100644 --- a/.github/targets_linux/nordic_pca10056_btshell_coded/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_btshell_coded/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_btshell_coded" +pkg.name: "targets/nordic_pca10056_btshell_coded" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_btshell_ext_adv/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_ext_adv/pkg.yml index b39ebae190..c8cce29975 100644 --- a/.github/targets_linux/nordic_pca10056_btshell_ext_adv/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_btshell_ext_adv/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_btshell_ext_adv" +pkg.name: "targets/nordic_pca10056_btshell_ext_adv" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/pkg.yml index 3a3a7d1eb3..b4f519e241 100644 --- a/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_btshell_periodic_adv" +pkg.name: "targets/nordic_pca10056_btshell_periodic_adv" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/pkg.yml index 79dbec4447..4c3d331ebe 100644 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_btshell_sm_legacy" +pkg.name: "targets/nordic_pca10056_btshell_sm_legacy" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_none/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_none/pkg.yml index 1061c2fa83..a8ccee1f45 100644 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_none/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_btshell_sm_none/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_btshell_sm_none" +pkg.name: "targets/nordic_pca10056_btshell_sm_none" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_sc/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_sc/pkg.yml index 0de1653943..611096aa36 100644 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_sc/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_btshell_sm_sc/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_btshell_sm_sc" +pkg.name: "targets/nordic_pca10056_btshell_sm_sc" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml index e75836015e..3983ec0cae 100644 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_btshell_sm_sc_legacy" +pkg.name: "targets/nordic_pca10056_btshell_sm_sc_legacy" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/pkg.yml index 2dde3239c3..aeb3d88b39 100644 --- a/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: "targets_ci/nordic_pca10056_btshell_xtal_settle_0 -pkg.name: "targets_ci/nordic_pca10056_btshell_xtal_settle_0" +### Package: "targets/nordic_pca10056_btshell_xtal_settle_0 +pkg.name: "targets/nordic_pca10056_btshell_xtal_settle_0" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_bttester/pkg.yml b/.github/targets_linux/nordic_pca10056_bttester/pkg.yml index 5f72b58da8..56a5f686eb 100644 --- a/.github/targets_linux/nordic_pca10056_bttester/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_bttester/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: "targets_ci/nordic_pca10056_bttester -pkg.name: "targets_ci/nordic_pca10056_bttester" +### Package: "targets/nordic_pca10056_bttester +pkg.name: "targets/nordic_pca10056_bttester" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_dtm/pkg.yml b/.github/targets_linux/nordic_pca10056_dtm/pkg.yml index 9cbab32434..9fde92a61e 100644 --- a/.github/targets_linux/nordic_pca10056_dtm/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_dtm/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: "targets_ci/nordic_pca10056_dtm -pkg.name: "targets_ci/nordic_pca10056_dtm" +### Package: "targets/nordic_pca10056_dtm +pkg.name: "targets/nordic_pca10056_dtm" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_ext_advertiser/pkg.yml b/.github/targets_linux/nordic_pca10056_ext_advertiser/pkg.yml index 7a196568ee..23a8c1446f 100644 --- a/.github/targets_linux/nordic_pca10056_ext_advertiser/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_ext_advertiser/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: "targets_ci/nordic_pca10056_btshell -pkg.name: "targets_ci/nordic_pca10056_ext_advertiser" +### Package: "targets/nordic_pca10056_btshell +pkg.name: "targets/nordic_pca10056_ext_advertiser" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10056_scanner/pkg.yml b/.github/targets_linux/nordic_pca10056_scanner/pkg.yml index 04b210a878..dfc3c8b015 100644 --- a/.github/targets_linux/nordic_pca10056_scanner/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_scanner/pkg.yml @@ -17,7 +17,7 @@ # under the License. # -pkg.name: "targets_ci/nordic_pca10056_scanner" +pkg.name: "targets/nordic_pca10056_scanner" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/targets_linux/nordic_pca10095_blehci/pkg.yml b/.github/targets_linux/nordic_pca10095_blehci/pkg.yml index 2cb827ecb4..21fa5f2cd7 100644 --- a/.github/targets_linux/nordic_pca10095_blehci/pkg.yml +++ b/.github/targets_linux/nordic_pca10095_blehci/pkg.yml @@ -17,8 +17,8 @@ # under the License. # -### Package: "targets_ci/blehci-nordic_pca10095 -pkg.name: "targets_ci/nordic_pca10095_blehci" +### Package: "targets/blehci-nordic_pca10095 +pkg.name: "targets/nordic_pca10095_blehci" pkg.type: "target" pkg.description: pkg.author: diff --git a/.github/workflows/build_ports.yml b/.github/workflows/build_ports.yml index 70a3349593..8c49d1f513 100644 --- a/.github/workflows/build_ports.yml +++ b/.github/workflows/build_ports.yml @@ -31,16 +31,19 @@ jobs: with: release: '12.2.Rel1' - name: Install Dependencies + shell: bash run: | sudo apt-get update sudo apt-get install -y make ccache gcc-multilib g++-multilib - name: Build example ports + shell: bash run: | make -C porting/examples/dummy/ clean all make -C porting/examples/linux/ clean all make -C porting/examples/linux_blemesh/ clean all make -C porting/npl/linux/test/ clean all test - name: Build RIOT port + shell: bash if: success() || failure() continue-on-error: true run: | diff --git a/.github/workflows/build_targets.yml b/.github/workflows/build_targets.yml index 05b13eb94f..b666a0cb22 100644 --- a/.github/workflows/build_targets.yml +++ b/.github/workflows/build_targets.yml @@ -38,33 +38,41 @@ jobs: with: release: '12.2.Rel1' - name: Install Dependencies + shell: bash if: matrix.os == 'ubuntu-latest' run: | sudo apt-get update sudo apt-get install -y gcc-multilib - name: Install newt + shell: bash run: | go version go install mynewt.apache.org/newt/newt@latest - name: Setup project + shell: bash run: | - cp .github/project.yml project.yml - mkdir repos - git clone --depth=1 https://github.com/apache/mynewt-core repos/apache-mynewt-core - git clone --depth=1 https://github.com/mcu-tools/mcuboot.git repos/mcuboot - git clone --depth=1 https://github.com/apache/mynewt-mcumgr repos/apache-mynewt-mcumgr - git clone --depth=1 https://github.com/hathach/tinyusb.git repos/tinyusb - git clone --depth=1 https://github.com/NordicSemiconductor/nrfx --branch v2.11.0 repos/nordic-nrfx - git clone --depth=1 https://github.com/Mbed-TLS/mbedtls.git --branch v2.28.4 repos/mbedtls + newt new build + cp -f .github/project.yml build/project.yml + cd build + newt upgrade --shallow=1 + rm -rf targets + rm -rf repos/apache-mynewt-nimble + git clone .. repos/apache-mynewt-nimble + cd .. - name: Build targets shell: bash run: | - cp -r .github/targets targets_ci - ls targets_ci | xargs -n1 sh -c 'echo "Testing $0"; newt build -q targets_ci/$0' - rm -rf targets_ci + cp -r .github/targets build/targets + cd build + ls targets | xargs -n1 sh -c 'echo "Testing $0"; newt build -q $0' + rm -rf targets + cd .. - name: Build Linux-only targets + shell: bash if: matrix.os == 'ubuntu-latest' run: | - cp -r .github/targets_linux targets_ci - ls targets_ci | xargs -n1 sh -c 'echo "Testing $0"; newt build -q targets_ci/$0' - rm -rf targets_ci + cp -r .github/targets_linux build/targets + cd build + ls targets | xargs -n1 sh -c 'echo "Testing $0"; newt build -q $0' + rm -rf targets + cd .. diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index 71ac7f1c73..c76225a8e6 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -30,12 +30,14 @@ jobs: with: fetch-depth: 0 - name: Install Dependencies + shell: bash run: | sudo apt-get update sudo apt-get install -y uncrustify mkdir repos git clone --depth=1 https://github.com/apache/mynewt-core repos/apache-mynewt-core - name: check style + shell: bash run: | ./repos/apache-mynewt-core/.github/check_style.py @@ -47,6 +49,7 @@ jobs: with: fetch-depth: 0 - name: Install Dependencies + shell: bash run: | sudo apt-get update sudo apt-get install -y libxml2-utils @@ -58,5 +61,6 @@ jobs: VERSION=`xmllint --xpath "//snapshotVersion[1]/value/text()" version.xml` wget https://repository.apache.org/content/repositories/snapshots/org/apache/rat/apache-rat/$SNAPSHOT/apache-rat-$VERSION.jar -O apache-rat.jar - name: check licensing + shell: bash run: | ./repos/apache-mynewt-core/.github/check_license.py diff --git a/.github/workflows/newt_test_all.yml b/.github/workflows/newt_test_all.yml index 44bf601494..8299b54d5e 100644 --- a/.github/workflows/newt_test_all.yml +++ b/.github/workflows/newt_test_all.yml @@ -31,22 +31,27 @@ jobs: with: go-version: 'stable' - name: Install Dependencies + shell: bash run: | sudo apt-get update sudo apt-get install -y gcc-multilib - name: Install newt + shell: bash run: | go version go install mynewt.apache.org/newt/newt@latest - name: Setup project + shell: bash run: | - cp .github/project.yml project.yml - mkdir repos - git clone --depth=1 https://github.com/apache/mynewt-core repos/apache-mynewt-core - git clone --depth=1 https://github.com/mcu-tools/mcuboot.git repos/mcuboot - git clone --depth=1 https://github.com/apache/mynewt-mcumgr repos/apache-mynewt-mcumgr - git clone --depth=1 https://github.com/hathach/tinyusb.git repos/tinyusb - git clone --depth=1 https://github.com/NordicSemiconductor/nrfx --branch v2.11.0 repos/nordic-nrfx - git clone --depth=1 https://github.com/Mbed-TLS/mbedtls.git --branch v2.28.4 repos/mbedtls + newt new build + cp -f .github/project.yml build/project.yml + cd build + newt upgrade --shallow=1 + rm -rf repos/apache-mynewt-nimble + git clone .. repos/apache-mynewt-nimble + cd .. - name: newt test all - run: newt test all + shell: bash + run: | + cd build + newt test all diff --git a/.github/workflows/ports_syscfg_check.yml b/.github/workflows/ports_syscfg_check.yml index e3c41633a4..66d47a2350 100644 --- a/.github/workflows/ports_syscfg_check.yml +++ b/.github/workflows/ports_syscfg_check.yml @@ -34,35 +34,38 @@ jobs: with: release: '12.2.Rel1' - name: Install Dependencies + shell: bash run: | sudo apt-get update sudo apt-get install -y gcc-multilib - name: Install newt + shell: bash run: | go version go install mynewt.apache.org/newt/newt@latest - name: Setup project + shell: bash run: | - mkdir /tmp/proj - mkdir /tmp/proj/repos - cp .github/project_ports.yml /tmp/proj/project.yml - git clone --depth=1 https://github.com/apache/mynewt-core /tmp/proj/repos/apache-mynewt-core - git clone --depth=1 https://github.com/mcu-tools/mcuboot.git /tmp/proj/repos/mcuboot - git clone --depth=1 https://github.com/apache/mynewt-mcumgr /tmp/proj/repos/apache-mynewt-mcumgr - git clone --depth=1 https://github.com/hathach/tinyusb.git /tmp/proj/repos/tinyusb - git clone --depth=1 https://github.com/NordicSemiconductor/nrfx --branch v2.11.0 repos/nordic-nrfx - git clone --depth=1 https://github.com/Mbed-TLS/mbedtls.git --branch v2.28.4 repos/mbedtls - cp -r `pwd` /tmp/proj/repos/apache-mynewt-nimble + newt new build + cp -f .github/project.yml build/project.yml + cd build + newt upgrade --shallow=1 + rm -rf repos/apache-mynewt-nimble + git clone .. repos/apache-mynewt-nimble + cd .. - name: Build ports tests targets + shell: bash run: | - cd /tmp/proj + cd build ./repos/apache-mynewt-nimble/porting/update_generated_files.sh cd repos/apache-mynewt-nimble - name: Check ports syscfg (debug) + shell: bash if: runner.debug == '1' run: | git diff - name: Check ports syscfg + shell: bash run: | git diff --quiet || (\ echo -e "\033[0;31mChanges in system configration files detected."; From 9616b929d22da2cc02de1f14257c3bd8d0a46c8e Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Tue, 8 Aug 2023 11:16:09 +0200 Subject: [PATCH 0827/1333] nimble/host: Add connection handle realated GAP APIs to header file This adds the declarations of two GAP APIs that were previously defined in the ble_gap.c. Now both APIs can be used in other source files. --- nimble/host/include/host/ble_gap.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index 690e427bd7..af0defa9fc 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -2587,6 +2587,25 @@ int ble_gap_event_listener_register(struct ble_gap_event_listener *listener, */ int ble_gap_event_listener_unregister(struct ble_gap_event_listener *listener); +/** + * Calls function defined by the user for every connection that is currently established + * + * @param cb Callback function + * @param arg Callback argument + */ +void ble_gap_conn_foreach_handle(ble_gap_conn_foreach_handle_fn *cb, void *arg); + +/** + * Looks for the connection with specified address. + * + * @param addr Address to look for + * @param out_conn_handle Pointer to the variable in which conn_handle will be saved if found + * + * @return 0 on success + * BLE_HS_ENOTCONN if connection with specified address was not found + */ +int ble_gap_conn_find_handle_by_addr(const ble_addr_t *addr, uint16_t *out_conn_handle); + #if MYNEWT_VAL(BLE_POWER_CONTROL) /** * Enable Set Path Loss Reporting. From 5d764711e3129dc877b0e8c3da3ffd0edda3c2ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 26 Sep 2023 11:14:21 +0200 Subject: [PATCH 0828/1333] apps/btshell: fix cmd_l2cap_reconfig command parse_arg_byte_stream_custom takes unsigned int as argument for result lenght. --- apps/btshell/src/cmd_l2cap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/btshell/src/cmd_l2cap.c b/apps/btshell/src/cmd_l2cap.c index 0c9d6a45fb..66965bf6fc 100644 --- a/apps/btshell/src/cmd_l2cap.c +++ b/apps/btshell/src/cmd_l2cap.c @@ -291,7 +291,7 @@ cmd_l2cap_reconfig(int argc, char **argv) uint16_t conn; uint16_t mtu; uint8_t idxs[5]; - int num; + unsigned int num; int rc; rc = parse_arg_init(argc - 1, argv + 1); From f4d8b7dde8b8473339112df0dce7da8a8899fa37 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 26 Sep 2023 11:18:59 +0200 Subject: [PATCH 0829/1333] ci: Enable BLE_L2CAP_ENHANCED_COC in btshell_all target This allows to test more code. --- .github/targets_linux/nordic_pca10056_btshell_all/syscfg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/targets_linux/nordic_pca10056_btshell_all/syscfg.h b/.github/targets_linux/nordic_pca10056_btshell_all/syscfg.h index 1fd335a1e8..f7011fd0b0 100644 --- a/.github/targets_linux/nordic_pca10056_btshell_all/syscfg.h +++ b/.github/targets_linux/nordic_pca10056_btshell_all/syscfg.h @@ -3,7 +3,7 @@ BLE_EXT_ADV: 1 BLE_EXT_ADV_MAX_SIZE: 1650 BLE_HS_DEBUG: 1 BLE_L2CAP_COC_MAX_NUM: 5 - +BLE_L2CAP_ENHANCED_COC: 1 BLE_MAX_CONNECTIONS: 5 BLE_MONITOR_RTT: 1 BLE_MULTI_ADV_INSTANCES: 5 @@ -14,7 +14,7 @@ BLE_SM_BONDING: 1 BLE_SM_LEGACY: 1 BLE_SM_SC: 1 BLE_STORE_MAX_BONDS: 5 -BLE_VERSION: 51 +BLE_VERSION: 53 BLE_LL_CFG_FEAT_LE_2M_PHY: 1 BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 From 6b51531432deb8b551aa5054730291e2a82bb650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Hj=C3=A4rtquist?= Date: Fri, 11 Aug 2023 15:59:29 +0200 Subject: [PATCH 0830/1333] porting/npl/freertos: Add way of including HW specific header --- porting/npl/freertos/src/npl_os_freertos.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/porting/npl/freertos/src/npl_os_freertos.c b/porting/npl/freertos/src/npl_os_freertos.c index ecc5cd7b1e..eeebe9fd78 100644 --- a/porting/npl/freertos/src/npl_os_freertos.c +++ b/porting/npl/freertos/src/npl_os_freertos.c @@ -22,6 +22,10 @@ #include #include "nimble/nimble_npl.h" +#ifdef NIMBLE_NPL_OS_EXTRA_INCLUDE +#include NIMBLE_NPL_OS_EXTRA_INCLUDE +#endif + static inline bool in_isr(void) { From 080e6d31359ff7dcbc7553b41934dad250331385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Hj=C3=A4rtquist?= Date: Mon, 2 Oct 2023 08:41:21 +0200 Subject: [PATCH 0831/1333] Add comment about NIMBLE_NPL_OS_EXTRA_INCLUDE --- porting/npl/freertos/src/npl_os_freertos.c | 1 + 1 file changed, 1 insertion(+) diff --git a/porting/npl/freertos/src/npl_os_freertos.c b/porting/npl/freertos/src/npl_os_freertos.c index eeebe9fd78..a671a80ea0 100644 --- a/porting/npl/freertos/src/npl_os_freertos.c +++ b/porting/npl/freertos/src/npl_os_freertos.c @@ -22,6 +22,7 @@ #include #include "nimble/nimble_npl.h" +/* Include the file that defines the SCB for your HW. */ #ifdef NIMBLE_NPL_OS_EXTRA_INCLUDE #include NIMBLE_NPL_OS_EXTRA_INCLUDE #endif From 05dd20cc4a0fca78f9a7b0bff9b10b4addd5b306 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Thu, 29 Jun 2023 16:10:02 +0530 Subject: [PATCH 0832/1333] nimble/host: Set length correctly in periodic_set_adv_data This change sets length field only if data is non NULL, else sets length to zero. --- nimble/host/src/ble_gap.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 4736415a37..6cf612db3f 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -3711,18 +3711,25 @@ ble_gap_periodic_adv_set(uint8_t instance, struct os_mbuf **data) static uint8_t buf[sizeof(struct ble_hci_le_set_periodic_adv_data_cp) + MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)]; struct ble_hci_le_set_periodic_adv_data_cp *cmd = (void *) buf; - uint16_t len = OS_MBUF_PKTLEN(*data); + uint16_t len = 0; uint16_t opcode; + if (*data) { + len = OS_MBUF_PKTLEN(*data); + } + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_DATA); cmd->adv_handle = instance; cmd->operation = BLE_HCI_LE_SET_DATA_OPER_COMPLETE; cmd->adv_data_len = len; - os_mbuf_copydata(*data, 0, len, cmd->adv_data); - os_mbuf_adj(*data, len); - *data = os_mbuf_trim_front(*data); + if (len) { + os_mbuf_copydata(*data, 0, len, cmd->adv_data); + + os_mbuf_adj(*data, len); + *data = os_mbuf_trim_front(*data); + } return ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, NULL, 0); @@ -3730,11 +3737,15 @@ ble_gap_periodic_adv_set(uint8_t instance, struct os_mbuf **data) static uint8_t buf[sizeof(struct ble_hci_le_set_periodic_adv_data_cp) + BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN]; struct ble_hci_le_set_periodic_adv_data_cp *cmd = (void *) buf; - uint16_t len = OS_MBUF_PKTLEN(*data); + uint16_t len = 0; uint16_t opcode; uint8_t op; int rc; + if (*data) { + len = OS_MBUF_PKTLEN(*data); + } + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_DATA); cmd->adv_handle = instance; @@ -3742,10 +3753,13 @@ ble_gap_periodic_adv_set(uint8_t instance, struct os_mbuf **data) if (len <= BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN) { cmd->operation = BLE_HCI_LE_SET_DATA_OPER_COMPLETE; cmd->adv_data_len = len; - os_mbuf_copydata(*data, 0, len, cmd->adv_data); - os_mbuf_adj(*data, len); - *data = os_mbuf_trim_front(*data); + if (len) { + os_mbuf_copydata(*data, 0, len, cmd->adv_data); + + os_mbuf_adj(*data, len); + *data = os_mbuf_trim_front(*data); + } return ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, NULL, 0); From 1306a780b138da9240573d059fcdc43d288f0859 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 29 Sep 2023 09:26:09 +0200 Subject: [PATCH 0833/1333] ci: Fix test targets configurations Some test targets were not configured properly. --- .../targets_linux/nordic_pca10028_boot/README | 3 -- .../nordic_pca10056_btshell_all/syscfg.h | 24 -------------- .../syscfg.yml} | 31 +++++++++++++++---- .../nordic_pca10056_btshell_all_v52/syscfg.h | 25 --------------- .../syscfg.yml} | 30 +++++++++++++++--- .../syscfg.yml | 11 ++++--- 6 files changed, 57 insertions(+), 67 deletions(-) delete mode 100644 .github/targets_linux/nordic_pca10028_boot/README delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_all/syscfg.h rename .github/targets_linux/{nordic_pca10028_boot/pkg.yml => nordic_pca10056_btshell_all/syscfg.yml} (55%) delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_all_v52/syscfg.h rename .github/targets_linux/{nordic_pca10028_boot/target.yml => nordic_pca10056_btshell_all_v52/syscfg.yml} (55%) rename .github/targets_linux/{nordic_pca10028_boot => nordic_pca10056_bttester}/syscfg.yml (84%) diff --git a/.github/targets_linux/nordic_pca10028_boot/README b/.github/targets_linux/nordic_pca10028_boot/README deleted file mode 100644 index d2d1760bbc..0000000000 --- a/.github/targets_linux/nordic_pca10028_boot/README +++ /dev/null @@ -1,3 +0,0 @@ -*** targets/nordic_pca10028_boot -Note: security is disabled in this boot loader target. With security, -the boot loader is just barely too large to fit on the nRF51. diff --git a/.github/targets_linux/nordic_pca10056_btshell_all/syscfg.h b/.github/targets_linux/nordic_pca10056_btshell_all/syscfg.h deleted file mode 100644 index f7011fd0b0..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_all/syscfg.h +++ /dev/null @@ -1,24 +0,0 @@ -BLE_EDDYSTONE: 1 -BLE_EXT_ADV: 1 -BLE_EXT_ADV_MAX_SIZE: 1650 -BLE_HS_DEBUG: 1 -BLE_L2CAP_COC_MAX_NUM: 5 -BLE_L2CAP_ENHANCED_COC: 1 -BLE_MAX_CONNECTIONS: 5 -BLE_MONITOR_RTT: 1 -BLE_MULTI_ADV_INSTANCES: 5 -BLE_PERIODIC_ADV: 1 -BLE_MAX_PERIODIC_SYNCS: 5 -BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 -BLE_SM_BONDING: 1 -BLE_SM_LEGACY: 1 -BLE_SM_SC: 1 -BLE_STORE_MAX_BONDS: 5 -BLE_VERSION: 53 - -BLE_LL_CFG_FEAT_LE_2M_PHY: 1 -BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 -BLE_LL_CFG_FEAT_LL_PRIVACY: 1 -BLE_LL_CONN_INIT_MAX_TX_BYTES: 251 -BLE_LL_DTM: 1 -BLE_LL_DTM_EXTENSIONS: 1 diff --git a/.github/targets_linux/nordic_pca10028_boot/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_all/syscfg.yml similarity index 55% rename from .github/targets_linux/nordic_pca10028_boot/pkg.yml rename to .github/targets_linux/nordic_pca10056_btshell_all/syscfg.yml index de320d8b7a..513eec9b03 100644 --- a/.github/targets_linux/nordic_pca10028_boot/pkg.yml +++ b/.github/targets_linux/nordic_pca10056_btshell_all/syscfg.yml @@ -17,9 +17,28 @@ # under the License. # -### Package: "targets/nordic_pca10028_boot -pkg.name: "targets/nordic_pca10028_boot" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: +syscfg.vals: + BLE_EDDYSTONE: 1 + BLE_EXT_ADV: 1 + BLE_EXT_ADV_MAX_SIZE: 1650 + BLE_HS_DEBUG: 1 + BLE_L2CAP_COC_MAX_NUM: 5 + BLE_L2CAP_ENHANCED_COC: 1 + BLE_MAX_CONNECTIONS: 5 + BLE_MONITOR_RTT: 1 + BLE_MULTI_ADV_INSTANCES: 5 + BLE_PERIODIC_ADV: 1 + BLE_MAX_PERIODIC_SYNCS: 5 + BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 + BLE_SM_BONDING: 1 + BLE_SM_LEGACY: 1 + BLE_SM_SC: 1 + BLE_STORE_MAX_BONDS: 5 + BLE_VERSION: 54 + + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 + BLE_LL_CFG_FEAT_LL_PRIVACY: 1 + BLE_LL_CONN_INIT_MAX_TX_BYTES: 251 + BLE_LL_DTM: 1 + BLE_LL_DTM_EXTENSIONS: 1 diff --git a/.github/targets_linux/nordic_pca10056_btshell_all_v52/syscfg.h b/.github/targets_linux/nordic_pca10056_btshell_all_v52/syscfg.h deleted file mode 100644 index fc43e89844..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_all_v52/syscfg.h +++ /dev/null @@ -1,25 +0,0 @@ -BLE_EDDYSTONE: 1 -BLE_EXT_ADV: 1 -BLE_EXT_ADV_MAX_SIZE: 1650 -BLE_HS_DEBUG: 1 -BLE_L2CAP_COC_MAX_NUM: 5 -BLE_L2CAP_ENHANCED_COC: 1 - -BLE_MAX_CONNECTIONS: 5 -BLE_MONITOR_RTT: 1 -BLE_MULTI_ADV_INSTANCES: 5 -BLE_PERIODIC_ADV: 1 -BLE_MAX_PERIODIC_SYNCS: 5 -BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 -BLE_SM_BONDING: 1 -BLE_SM_LEGACY: 1 -BLE_SM_SC: 1 -BLE_STORE_MAX_BONDS: 5 -BLE_VERSION: 52 - -BLE_LL_CFG_FEAT_LE_2M_PHY: 1 -BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 -BLE_LL_CFG_FEAT_LL_PRIVACY: 1 -BLE_LL_CONN_INIT_MAX_TX_BYTES: 251 -BLE_LL_DTM: 1 -BLE_LL_DTM_EXTENSIONS: 1 diff --git a/.github/targets_linux/nordic_pca10028_boot/target.yml b/.github/targets_linux/nordic_pca10056_btshell_all_v52/syscfg.yml similarity index 55% rename from .github/targets_linux/nordic_pca10028_boot/target.yml rename to .github/targets_linux/nordic_pca10056_btshell_all_v52/syscfg.yml index 0bc319fe0e..2e37f63f9a 100644 --- a/.github/targets_linux/nordic_pca10028_boot/target.yml +++ b/.github/targets_linux/nordic_pca10056_btshell_all_v52/syscfg.yml @@ -17,7 +17,29 @@ # under the License. # -### Target: targets/nordic_pca10028_boot -target.app: "@mcuboot/boot/mynewt" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10028" -target.build_profile: "optimized" +syscfg.vals: + BLE_EDDYSTONE: 1 + BLE_EXT_ADV: 1 + BLE_EXT_ADV_MAX_SIZE: 1650 + BLE_HS_DEBUG: 1 + BLE_L2CAP_COC_MAX_NUM: 5 + BLE_L2CAP_ENHANCED_COC: 1 + + BLE_MAX_CONNECTIONS: 5 + BLE_MONITOR_RTT: 1 + BLE_MULTI_ADV_INSTANCES: 5 + BLE_PERIODIC_ADV: 1 + BLE_MAX_PERIODIC_SYNCS: 5 + BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 + BLE_SM_BONDING: 1 + BLE_SM_LEGACY: 1 + BLE_SM_SC: 1 + BLE_STORE_MAX_BONDS: 5 + BLE_VERSION: 52 + + BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 + BLE_LL_CFG_FEAT_LL_PRIVACY: 1 + BLE_LL_CONN_INIT_MAX_TX_BYTES: 251 + BLE_LL_DTM: 1 + BLE_LL_DTM_EXTENSIONS: 1 diff --git a/.github/targets_linux/nordic_pca10028_boot/syscfg.yml b/.github/targets_linux/nordic_pca10056_bttester/syscfg.yml similarity index 84% rename from .github/targets_linux/nordic_pca10028_boot/syscfg.yml rename to .github/targets_linux/nordic_pca10056_bttester/syscfg.yml index 7719a48ac2..288a45c123 100644 --- a/.github/targets_linux/nordic_pca10028_boot/syscfg.yml +++ b/.github/targets_linux/nordic_pca10056_bttester/syscfg.yml @@ -18,8 +18,9 @@ # syscfg.vals: - BOOTUTIL_SIGN_RSA: 0 - BOOTUTIL_SIGN_ECC: 0 - UART_0: 0 - TIMER_0: 0 - OS_CPUTIME_TIMER_NUM: -1 + BLE_EXT_ADV: 1 + BLE_MULTI_ADV_INSTANCES: 1 + BLE_PERIODIC_ADV: 1 + BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 + BLE_SM_LEGACY: 1 + BLE_SM_SC: 1 From 20241c29c0b2348e8db246fbe111e0e7653c6dc4 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 26 Sep 2023 10:42:50 +0200 Subject: [PATCH 0834/1333] nimble/host: Fix not catching conversion error in hex2bin hex2val returns BLE_HS_EINVAL on error which is positive value. This could result in UUID conversion errors as hex2bin is used by ble_uuid_from_str. This was also causing build error with GCC 9: repos/apache-mynewt-nimble/nimble/host/src/ble_uuid.c:76:28: error: 'tmp_val' may be used uninitialized in this function [-Werror=maybe-uninitialized] 76 | bin[len] = tmp_val << 4; | ~~~~~~~~^~~~ cc1: all warnings being treated as errors --- nimble/host/src/ble_uuid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_uuid.c b/nimble/host/src/ble_uuid.c index afc437b786..15f6637480 100644 --- a/nimble/host/src/ble_uuid.c +++ b/nimble/host/src/ble_uuid.c @@ -69,7 +69,7 @@ hex2bin(const char *hex, uint8_t *bin, size_t bin_len) while (*hex && len < bin_len) { rc = hex2val(*hex++, &tmp_val); - if (rc < 0) { + if (rc != 0) { return 0; } @@ -81,7 +81,7 @@ hex2bin(const char *hex, uint8_t *bin, size_t bin_len) } rc = hex2val(*hex++, &tmp_val); - if (rc < 0) { + if (rc != 0) { return 0; } bin[len++] |= tmp_val; From 076686b01d2e8ab7ef66a61e2502cc30dc0203a6 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 26 Sep 2023 10:57:49 +0200 Subject: [PATCH 0835/1333] ci: Add workflow for testing various GCC versions This will help make sure we build correctly with more GCC version. --- .github/workflows/build_cc_target.yml | 62 +++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 .github/workflows/build_cc_target.yml diff --git a/.github/workflows/build_cc_target.yml b/.github/workflows/build_cc_target.yml new file mode 100644 index 0000000000..58646db905 --- /dev/null +++ b/.github/workflows/build_cc_target.yml @@ -0,0 +1,62 @@ +# +# 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. +# + +name: Build check + +on: [push, pull_request] + +jobs: + targets: + name: Build GCC test target + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + gcc: ['12.2.Rel1', '11.3.Rel1', '10.3-2021.10', '9-2020-q2', '8-2019-q3'] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: 'stable' + - uses: carlosperate/arm-none-eabi-gcc-action@48db4484a55750df7a0ccca63347fcdea6534d78 + with: + release: ${{ matrix.gcc }} + - name: Install newt + shell: bash + run: | + go version + go install mynewt.apache.org/newt/newt@latest + - name: Setup project + shell: bash + run: | + newt new build + cp -f .github/project.yml build/project.yml + cd build + newt upgrade --shallow=1 + rm -rf repos/apache-mynewt-nimble + git clone .. repos/apache-mynewt-nimble + rm -rf targets + cd .. + - name: Build targets + shell: bash + run: | + cp -r .github/targets_linux build/targets + cd build + newt build -j 1 nordic_pca10056_btshell_all From fb12dbbdeffba3dbfb9bb3652d7b0557b174944e Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 4 Oct 2023 16:45:42 +0530 Subject: [PATCH 0836/1333] Fix compilation issue when Max Bonds or CCCD is set as 0 --- nimble/host/src/ble_gap.c | 4 ++ nimble/host/src/ble_store_util.c | 3 +- .../host/store/config/src/ble_store_config.c | 58 ++++++++++++++-- nimble/host/store/ram/src/ble_store_ram.c | 66 ++++++++++++++++++- 4 files changed, 123 insertions(+), 8 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 6cf612db3f..a391675546 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -6120,6 +6120,7 @@ int ble_gap_unpair_oldest_except(const ble_addr_t *peer_addr) { #if NIMBLE_BLE_SM +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; int num_peers; int rc, i; @@ -6152,6 +6153,9 @@ ble_gap_unpair_oldest_except(const ble_addr_t *peer_addr) #else return BLE_HS_ENOTSUP; #endif +#else + return BLE_HS_ENOTSUP; +#endif } void diff --git a/nimble/host/src/ble_store_util.c b/nimble/host/src/ble_store_util.c index 508fa00db2..19b049a4c4 100644 --- a/nimble/host/src/ble_store_util.c +++ b/nimble/host/src/ble_store_util.c @@ -192,6 +192,7 @@ ble_store_util_count(int type, int *out_count) int ble_store_util_delete_oldest_peer(void) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; int num_peers; int rc; @@ -211,7 +212,7 @@ ble_store_util_delete_oldest_peer(void) if (rc != 0) { return rc; } - +#endif return 0; } diff --git a/nimble/host/store/config/src/ble_store_config.c b/nimble/host/store/config/src/ble_store_config.c index 0220ba760e..0ee8906c69 100644 --- a/nimble/host/store/config/src/ble_store_config.c +++ b/nimble/host/store/config/src/ble_store_config.c @@ -27,22 +27,31 @@ #include "store/config/ble_store_config.h" #include "ble_store_config_priv.h" +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) struct ble_store_value_sec ble_store_config_our_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; +#endif int ble_store_config_num_our_secs; +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) struct ble_store_value_sec ble_store_config_peer_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; +#endif + int ble_store_config_num_peer_secs; +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) struct ble_store_value_cccd ble_store_config_cccds[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)]; +#endif + int ble_store_config_num_cccds; /***************************************************************************** * $sec * *****************************************************************************/ +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) static void ble_store_config_print_value_sec(const struct ble_store_value_sec *sec) { @@ -65,6 +74,7 @@ ble_store_config_print_value_sec(const struct ble_store_value_sec *sec) BLE_HS_LOG(DEBUG, "\n"); } +#endif static void ble_store_config_print_key_sec(const struct ble_store_key_sec *key_sec) @@ -77,6 +87,7 @@ ble_store_config_print_key_sec(const struct ble_store_key_sec *key_sec) } } +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) static int ble_store_config_find_sec(const struct ble_store_key_sec *key_sec, const struct ble_store_value_sec *value_secs, @@ -101,11 +112,13 @@ ble_store_config_find_sec(const struct ble_store_key_sec *key_sec, return -1; } +#endif static int ble_store_config_read_our_sec(const struct ble_store_key_sec *key_sec, struct ble_store_value_sec *value_sec) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int idx; idx = ble_store_config_find_sec(key_sec, ble_store_config_our_secs, @@ -116,12 +129,16 @@ ble_store_config_read_our_sec(const struct ble_store_key_sec *key_sec, *value_sec = ble_store_config_our_secs[idx]; return 0; +#else + return BLE_HS_ENOENT; +#endif } static int ble_store_config_write_our_sec(const struct ble_store_value_sec *value_sec) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) struct ble_store_key_sec key_sec; int idx; int rc; @@ -151,8 +168,13 @@ ble_store_config_write_our_sec(const struct ble_store_value_sec *value_sec) } return 0; +#else + return BLE_HS_ENOENT; +#endif + } +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) static int ble_store_config_delete_obj(void *values, int value_size, int idx, int *num_values) @@ -195,10 +217,12 @@ ble_store_config_delete_sec(const struct ble_store_key_sec *key_sec, return 0; } +#endif static int ble_store_config_delete_our_sec(const struct ble_store_key_sec *key_sec) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int rc; rc = ble_store_config_delete_sec(key_sec, ble_store_config_our_secs, @@ -213,11 +237,15 @@ ble_store_config_delete_our_sec(const struct ble_store_key_sec *key_sec) } return 0; +#else + return BLE_HS_ENOENT; +#endif } static int ble_store_config_delete_peer_sec(const struct ble_store_key_sec *key_sec) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int rc; rc = ble_store_config_delete_sec(key_sec, ble_store_config_peer_secs, @@ -230,14 +258,17 @@ ble_store_config_delete_peer_sec(const struct ble_store_key_sec *key_sec) if (rc != 0) { return rc; } - return 0; +#else + return BLE_HS_ENOENT; +#endif } static int ble_store_config_read_peer_sec(const struct ble_store_key_sec *key_sec, struct ble_store_value_sec *value_sec) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int idx; idx = ble_store_config_find_sec(key_sec, ble_store_config_peer_secs, @@ -248,11 +279,16 @@ ble_store_config_read_peer_sec(const struct ble_store_key_sec *key_sec, *value_sec = ble_store_config_peer_secs[idx]; return 0; +#else + return BLE_HS_ENOENT; +#endif + } static int ble_store_config_write_peer_sec(const struct ble_store_value_sec *value_sec) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) struct ble_store_key_sec key_sec; int idx; int rc; @@ -280,14 +316,17 @@ ble_store_config_write_peer_sec(const struct ble_store_value_sec *value_sec) if (rc != 0) { return rc; } - return 0; +#else + return BLE_HS_ENOENT; +#endif } /***************************************************************************** * $cccd * *****************************************************************************/ +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) static int ble_store_config_find_cccd(const struct ble_store_key_cccd *key) { @@ -318,13 +357,14 @@ ble_store_config_find_cccd(const struct ble_store_key_cccd *key) return i; } - return -1; } +#endif static int ble_store_config_delete_cccd(const struct ble_store_key_cccd *key_cccd) { +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) int idx; int rc; @@ -345,14 +385,17 @@ ble_store_config_delete_cccd(const struct ble_store_key_cccd *key_cccd) if (rc != 0) { return rc; } - return 0; +#else + return BLE_HS_ENOENT; +#endif } static int ble_store_config_read_cccd(const struct ble_store_key_cccd *key_cccd, struct ble_store_value_cccd *value_cccd) { +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) int idx; idx = ble_store_config_find_cccd(key_cccd); @@ -362,11 +405,15 @@ ble_store_config_read_cccd(const struct ble_store_key_cccd *key_cccd, *value_cccd = ble_store_config_cccds[idx]; return 0; +#else + return BLE_HS_ENOENT; +#endif } static int ble_store_config_write_cccd(const struct ble_store_value_cccd *value_cccd) { +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) struct ble_store_key_cccd key_cccd; int idx; int rc; @@ -392,6 +439,9 @@ ble_store_config_write_cccd(const struct ble_store_value_cccd *value_cccd) } return 0; +#else + return BLE_HS_ENOENT; +#endif } /***************************************************************************** diff --git a/nimble/host/store/ram/src/ble_store_ram.c b/nimble/host/store/ram/src/ble_store_ram.c index 450be717d2..9359f6d399 100644 --- a/nimble/host/store/ram/src/ble_store_ram.c +++ b/nimble/host/store/ram/src/ble_store_ram.c @@ -36,22 +36,32 @@ #include "host/ble_hs.h" #include "store/ram/ble_store_ram.h" +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) static struct ble_store_value_sec ble_store_ram_our_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; +#endif + static int ble_store_ram_num_our_secs; +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) static struct ble_store_value_sec ble_store_ram_peer_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; +#endif + static int ble_store_ram_num_peer_secs; +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) static struct ble_store_value_cccd ble_store_ram_cccds[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)]; +#endif + static int ble_store_ram_num_cccds; /***************************************************************************** * $sec * *****************************************************************************/ +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) static void ble_store_ram_print_value_sec(const struct ble_store_value_sec *sec) { @@ -74,6 +84,7 @@ ble_store_ram_print_value_sec(const struct ble_store_value_sec *sec) BLE_HS_LOG(DEBUG, "\n"); } +#endif static void ble_store_ram_print_key_sec(const struct ble_store_key_sec *key_sec) @@ -86,6 +97,7 @@ ble_store_ram_print_key_sec(const struct ble_store_key_sec *key_sec) } } +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) static int ble_store_ram_find_sec(const struct ble_store_key_sec *key_sec, const struct ble_store_value_sec *value_secs, @@ -110,11 +122,13 @@ ble_store_ram_find_sec(const struct ble_store_key_sec *key_sec, return -1; } +#endif static int ble_store_ram_read_our_sec(const struct ble_store_key_sec *key_sec, struct ble_store_value_sec *value_sec) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int idx; idx = ble_store_ram_find_sec(key_sec, ble_store_ram_our_secs, @@ -125,11 +139,16 @@ ble_store_ram_read_our_sec(const struct ble_store_key_sec *key_sec, *value_sec = ble_store_ram_our_secs[idx]; return 0; +#else + return BLE_HS_ENOENT; +#endif + } static int ble_store_ram_write_our_sec(const struct ble_store_value_sec *value_sec) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) struct ble_store_key_sec key_sec; int idx; @@ -151,9 +170,15 @@ ble_store_ram_write_our_sec(const struct ble_store_value_sec *value_sec) } ble_store_ram_our_secs[idx] = *value_sec; + return 0; +#else + return BLE_HS_ENOENT; +#endif + } +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) static int ble_store_ram_delete_obj(void *values, int value_size, int idx, int *num_values) @@ -196,10 +221,12 @@ ble_store_ram_delete_sec(const struct ble_store_key_sec *key_sec, return 0; } +#endif static int ble_store_ram_delete_our_sec(const struct ble_store_key_sec *key_sec) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int rc; rc = ble_store_ram_delete_sec(key_sec, ble_store_ram_our_secs, @@ -207,13 +234,17 @@ ble_store_ram_delete_our_sec(const struct ble_store_key_sec *key_sec) if (rc != 0) { return rc; } - return 0; +#else + return BLE_HS_ENOENT; +#endif + } static int ble_store_ram_delete_peer_sec(const struct ble_store_key_sec *key_sec) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int rc; rc = ble_store_ram_delete_sec(key_sec, ble_store_ram_peer_secs, @@ -221,14 +252,18 @@ ble_store_ram_delete_peer_sec(const struct ble_store_key_sec *key_sec) if (rc != 0) { return rc; } - return 0; +#else + return BLE_HS_ENOENT; +#endif + } static int ble_store_ram_read_peer_sec(const struct ble_store_key_sec *key_sec, struct ble_store_value_sec *value_sec) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int idx; idx = ble_store_ram_find_sec(key_sec, ble_store_ram_peer_secs, @@ -239,11 +274,16 @@ ble_store_ram_read_peer_sec(const struct ble_store_key_sec *key_sec, *value_sec = ble_store_ram_peer_secs[idx]; return 0; +#else + return BLE_HS_ENOENT; +#endif + } static int ble_store_ram_write_peer_sec(const struct ble_store_value_sec *value_sec) { +#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) struct ble_store_key_sec key_sec; int idx; @@ -266,12 +306,17 @@ ble_store_ram_write_peer_sec(const struct ble_store_value_sec *value_sec) ble_store_ram_peer_secs[idx] = *value_sec; return 0; +#else + return BLE_HS_ENOENT; +#endif + } /***************************************************************************** * $cccd * *****************************************************************************/ +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) static int ble_store_ram_find_cccd(const struct ble_store_key_cccd *key) { @@ -305,10 +350,12 @@ ble_store_ram_find_cccd(const struct ble_store_key_cccd *key) return -1; } +#endif static int ble_store_ram_delete_cccd(const struct ble_store_key_cccd *key_cccd) { +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) int idx; int rc; @@ -324,14 +371,18 @@ ble_store_ram_delete_cccd(const struct ble_store_key_cccd *key_cccd) if (rc != 0) { return rc; } - return 0; +#else + return BLE_HS_ENOENT; +#endif + } static int ble_store_ram_read_cccd(const struct ble_store_key_cccd *key_cccd, struct ble_store_value_cccd *value_cccd) { +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) int idx; idx = ble_store_ram_find_cccd(key_cccd); @@ -340,12 +391,17 @@ ble_store_ram_read_cccd(const struct ble_store_key_cccd *key_cccd, } *value_cccd = ble_store_ram_cccds[idx]; + return 0; +#else + return BLE_HS_ENOENT; +#endif } static int ble_store_ram_write_cccd(const struct ble_store_value_cccd *value_cccd) { +#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) struct ble_store_key_cccd key_cccd; int idx; @@ -364,6 +420,10 @@ ble_store_ram_write_cccd(const struct ble_store_value_cccd *value_cccd) ble_store_ram_cccds[idx] = *value_cccd; return 0; +#else + return BLE_HS_ENOENT; +#endif + } /***************************************************************************** From 8247d690f000fa49079f8bf44ef7687f71aaf0dc Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 4 Oct 2023 17:11:37 +0200 Subject: [PATCH 0837/1333] nimble/ll: Fix typo in BLE_HCI_OCF_LE_SET_CIG_PARAMS_TEST Fixes build failure with BLE_LL_CFG_FEAT_LL_ISO_TEST enabled. --- nimble/controller/src/ble_ll_hci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index c2b3af71ab..719fa6924a 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1279,7 +1279,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, case BLE_HCI_OCF_LE_READ_ISO_TX_SYNC: rc = ble_ll_iso_read_tx_sync(cmdbuf, len); break; - case BLE_HCI_OCF_LE_SET_CIG_PARAM: + case BLE_HCI_OCF_LE_SET_CIG_PARAMS: rc = ble_ll_iso_set_cig_param(cmdbuf, len, rspbuf, rsplen); break; case BLE_HCI_OCF_LE_CREATE_CIS: @@ -1318,7 +1318,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, break; #endif /* BLE_LL_ISO */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO_TEST) - case BLE_HCI_OCF_LE_SET_CIG_PARAM_TEST: + case BLE_HCI_OCF_LE_SET_CIG_PARAMS_TEST: rc = ble_ll_iso_set_cig_param_test(cmdbuf, len, rspbuf, rsplen); break; case BLE_HCI_OCF_LE_CREATE_BIG_TEST: From e1f7546556b160f633fd847d6fdc6da213a37a21 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 4 Oct 2023 17:12:55 +0200 Subject: [PATCH 0838/1333] ci: Build all sample applications Instead of custom targets, this builds all sample aplications with default and 'all-enabled' configuration for Nordic PCA10056 DK. Some additional custom targets are also present to cover other boards and special configurations. --- .../nordic_pca10056-blehci-usb/pkg.yml | 0 .../nordic_pca10056-blehci-usb/syscfg.yml | 0 .../nordic_pca10056-blehci-usb/target.yml | 0 .../nordic_pca10056_blehci/pkg.yml | 0 .../nordic_pca10056_blehci/target.yml | 0 .../nordic_pca10095_blehci/pkg.yml | 0 .../nordic_pca10095_blehci/syscfg.yml | 0 .../nordic_pca10095_blehci/target.yml | 0 .../nordic_pca10028_bt5_blehci/pkg.yml | 25 ------- .../nordic_pca10028_bt5_blehci/syscfg.yml | 21 ------ .../nordic_pca10028_bt5_blehci/target.yml | 23 ------- .../nordic_pca10056_advertiser/pkg.yml | 24 ------- .../nordic_pca10056_advertiser/target.yml | 21 ------ .../nordic_pca10056_blecent/pkg.yml | 25 ------- .../nordic_pca10056_blecent/target.yml | 21 ------ .../nordic_pca10056_blecsc/pkg.yml | 25 ------- .../nordic_pca10056_blecsc/target.yml | 21 ------ .../pkg.yml | 25 ------- .../syscfg.yml | 39 ----------- .../target.yml | 21 ------ .../nordic_pca10056_blehci_no_privacy/pkg.yml | 25 ------- .../syscfg.yml | 22 ------ .../target.yml | 21 ------ .../nordic_pca10056_blehr/pkg.yml | 25 ------- .../nordic_pca10056_blehr/target.yml | 21 ------ .../nordic_pca10056_blemesh/pkg.yml | 25 ------- .../nordic_pca10056_blemesh/target.yml | 21 ------ .../nordic_pca10056_blemesh_cdb/pkg.yml | 25 ------- .../nordic_pca10056_blemesh_cdb/syscfg.yml | 21 ------ .../nordic_pca10056_blemesh_cdb/target.yml | 21 ------ .../nordic_pca10056_blemesh_ext_adv/pkg.yml | 25 ------- .../syscfg.yml | 22 ------ .../target.yml | 21 ------ .../nordic_pca10056_blemesh_light/pkg.yml | 25 ------- .../nordic_pca10056_blemesh_light/target.yml | 21 ------ .../pkg.yml | 24 ------- .../target.yml | 22 ------ .../pkg.yml | 25 ------- .../target.yml | 22 ------ .../nordic_pca10056_blemesh_shell/pkg.yml | 25 ------- .../nordic_pca10056_blemesh_shell/target.yml | 21 ------ .../nordic_pca10056_blemesh_storage/pkg.yml | 25 ------- .../syscfg.yml | 22 ------ .../target.yml | 21 ------ .../nordic_pca10056_bleprph/pkg.yml | 25 ------- .../nordic_pca10056_bleprph/target.yml | 21 ------ .../nordic_pca10056_bleprph_oic/pkg.yml | 25 ------- .../nordic_pca10056_bleprph_oic/target.yml | 21 ------ .../nordic_pca10056_blesplit/pkg.yml | 25 ------- .../nordic_pca10056_blesplit/target.yml | 21 ------ .../nordic_pca10056_bleuart/pkg.yml | 25 ------- .../nordic_pca10056_bleuart/target.yml | 21 ------ .../nordic_pca10056_btshell_2M/pkg.yml | 24 ------- .../nordic_pca10056_btshell_2M/syscfg.yml | 21 ------ .../nordic_pca10056_btshell_2M/target.yml | 22 ------ .../nordic_pca10056_btshell_2M_coded/pkg.yml | 24 ------- .../syscfg.yml | 22 ------ .../target.yml | 22 ------ .../nordic_pca10056_btshell_all/pkg.yml | 25 ------- .../nordic_pca10056_btshell_all/target.yml | 23 ------- .../nordic_pca10056_btshell_all_v52/pkg.yml | 25 ------- .../syscfg.yml | 45 ------------ .../target.yml | 23 ------- .../nordic_pca10056_btshell_coded/pkg.yml | 24 ------- .../nordic_pca10056_btshell_coded/syscfg.yml | 21 ------ .../nordic_pca10056_btshell_coded/target.yml | 22 ------ .../nordic_pca10056_btshell_ext_adv/pkg.yml | 24 ------- .../syscfg.yml | 21 ------ .../target.yml | 22 ------ .../pkg.yml | 24 ------- .../syscfg.yml | 22 ------ .../target.yml | 22 ------ .../nordic_pca10056_btshell_sm_legacy/pkg.yml | 24 ------- .../syscfg.yml | 22 ------ .../target.yml | 22 ------ .../nordic_pca10056_btshell_sm_none/pkg.yml | 24 ------- .../syscfg.yml | 22 ------ .../target.yml | 22 ------ .../nordic_pca10056_btshell_sm_sc/pkg.yml | 24 ------- .../nordic_pca10056_btshell_sm_sc/syscfg.yml | 22 ------ .../nordic_pca10056_btshell_sm_sc/target.yml | 22 ------ .../pkg.yml | 24 ------- .../syscfg.yml | 22 ------ .../target.yml | 22 ------ .../pkg.yml | 25 ------- .../syscfg.yml | 21 ------ .../target.yml | 23 ------- .../nordic_pca10056_bttester/pkg.yml | 25 ------- .../nordic_pca10056_bttester/syscfg.yml | 26 ------- .../nordic_pca10056_bttester/target.yml | 23 ------- .../targets_linux/nordic_pca10056_dtm/pkg.yml | 25 ------- .../nordic_pca10056_dtm/target.yml | 23 ------- .../nordic_pca10056_ext_advertiser/pkg.yml | 25 ------- .../nordic_pca10056_ext_advertiser/target.yml | 23 ------- .../nordic_pca10056_scanner/pkg.yml | 24 ------- .../nordic_pca10056_scanner/target.yml | 21 ------ .github/test_build_apps.sh | 60 ++++++++++++++++ .../syscfg.yml => test_build_apps_syscfg.yml} | 26 +++++-- .github/workflows/build_all_apps.yml | 68 +++++++++++++++++++ .github/workflows/build_cc_target.yml | 10 +-- 100 files changed, 155 insertions(+), 2066 deletions(-) rename .github/{targets_linux => targets}/nordic_pca10056-blehci-usb/pkg.yml (100%) rename .github/{targets_linux => targets}/nordic_pca10056-blehci-usb/syscfg.yml (100%) rename .github/{targets_linux => targets}/nordic_pca10056-blehci-usb/target.yml (100%) rename .github/{targets_linux => targets}/nordic_pca10056_blehci/pkg.yml (100%) rename .github/{targets_linux => targets}/nordic_pca10056_blehci/target.yml (100%) rename .github/{targets_linux => targets}/nordic_pca10095_blehci/pkg.yml (100%) rename .github/{targets_linux => targets}/nordic_pca10095_blehci/syscfg.yml (100%) rename .github/{targets_linux => targets}/nordic_pca10095_blehci/target.yml (100%) delete mode 100644 .github/targets_linux/nordic_pca10028_bt5_blehci/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10028_bt5_blehci/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10028_bt5_blehci/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_advertiser/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_advertiser/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blecent/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blecent/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blecsc/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blecsc/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blehci_all_enabled/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blehci_all_enabled/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blehci_all_enabled/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blehci_no_privacy/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blehci_no_privacy/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blehci_no_privacy/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blehr/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blehr/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_cdb/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_cdb/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_cdb/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_ext_adv/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_ext_adv/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_ext_adv/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_light/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_light/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_models_example_1/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_models_example_1/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_models_example_2/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_models_example_2/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_shell/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_shell/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_storage/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_storage/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blemesh_storage/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_bleprph/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_bleprph/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_bleprph_oic/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_bleprph_oic/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blesplit/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_blesplit/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_bleuart/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_bleuart/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_2M/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_2M/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_2M/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_2M_coded/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_2M_coded/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_2M_coded/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_all/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_all/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_all_v52/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_all_v52/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_all_v52/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_coded/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_coded/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_coded/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_ext_adv/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_ext_adv/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_ext_adv/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_periodic_adv/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_periodic_adv/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_periodic_adv/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_sm_legacy/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_sm_legacy/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_sm_legacy/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_sm_none/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_sm_none/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_sm_none/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_sm_sc/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_sm_sc/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_sm_sc/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_bttester/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_bttester/syscfg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_bttester/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_dtm/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_dtm/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_ext_advertiser/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_ext_advertiser/target.yml delete mode 100644 .github/targets_linux/nordic_pca10056_scanner/pkg.yml delete mode 100644 .github/targets_linux/nordic_pca10056_scanner/target.yml create mode 100644 .github/test_build_apps.sh rename .github/{targets_linux/nordic_pca10056_btshell_all/syscfg.yml => test_build_apps_syscfg.yml} (80%) create mode 100644 .github/workflows/build_all_apps.yml diff --git a/.github/targets_linux/nordic_pca10056-blehci-usb/pkg.yml b/.github/targets/nordic_pca10056-blehci-usb/pkg.yml similarity index 100% rename from .github/targets_linux/nordic_pca10056-blehci-usb/pkg.yml rename to .github/targets/nordic_pca10056-blehci-usb/pkg.yml diff --git a/.github/targets_linux/nordic_pca10056-blehci-usb/syscfg.yml b/.github/targets/nordic_pca10056-blehci-usb/syscfg.yml similarity index 100% rename from .github/targets_linux/nordic_pca10056-blehci-usb/syscfg.yml rename to .github/targets/nordic_pca10056-blehci-usb/syscfg.yml diff --git a/.github/targets_linux/nordic_pca10056-blehci-usb/target.yml b/.github/targets/nordic_pca10056-blehci-usb/target.yml similarity index 100% rename from .github/targets_linux/nordic_pca10056-blehci-usb/target.yml rename to .github/targets/nordic_pca10056-blehci-usb/target.yml diff --git a/.github/targets_linux/nordic_pca10056_blehci/pkg.yml b/.github/targets/nordic_pca10056_blehci/pkg.yml similarity index 100% rename from .github/targets_linux/nordic_pca10056_blehci/pkg.yml rename to .github/targets/nordic_pca10056_blehci/pkg.yml diff --git a/.github/targets_linux/nordic_pca10056_blehci/target.yml b/.github/targets/nordic_pca10056_blehci/target.yml similarity index 100% rename from .github/targets_linux/nordic_pca10056_blehci/target.yml rename to .github/targets/nordic_pca10056_blehci/target.yml diff --git a/.github/targets_linux/nordic_pca10095_blehci/pkg.yml b/.github/targets/nordic_pca10095_blehci/pkg.yml similarity index 100% rename from .github/targets_linux/nordic_pca10095_blehci/pkg.yml rename to .github/targets/nordic_pca10095_blehci/pkg.yml diff --git a/.github/targets_linux/nordic_pca10095_blehci/syscfg.yml b/.github/targets/nordic_pca10095_blehci/syscfg.yml similarity index 100% rename from .github/targets_linux/nordic_pca10095_blehci/syscfg.yml rename to .github/targets/nordic_pca10095_blehci/syscfg.yml diff --git a/.github/targets_linux/nordic_pca10095_blehci/target.yml b/.github/targets/nordic_pca10095_blehci/target.yml similarity index 100% rename from .github/targets_linux/nordic_pca10095_blehci/target.yml rename to .github/targets/nordic_pca10095_blehci/target.yml diff --git a/.github/targets_linux/nordic_pca10028_bt5_blehci/pkg.yml b/.github/targets_linux/nordic_pca10028_bt5_blehci/pkg.yml deleted file mode 100644 index 02bb6e8e4e..0000000000 --- a/.github/targets_linux/nordic_pca10028_bt5_blehci/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -### Package: "targets/nordic_pca10028_bt5_blehci -pkg.name: "targets/nordic_pca10028_bt5_blehci" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10028_bt5_blehci/syscfg.yml b/.github/targets_linux/nordic_pca10028_bt5_blehci/syscfg.yml deleted file mode 100644 index a5526dfeb8..0000000000 --- a/.github/targets_linux/nordic_pca10028_bt5_blehci/syscfg.yml +++ /dev/null @@ -1,21 +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. -# - -syscfg.vals: - BLE_EXT_ADV: 1 diff --git a/.github/targets_linux/nordic_pca10028_bt5_blehci/target.yml b/.github/targets_linux/nordic_pca10028_bt5_blehci/target.yml deleted file mode 100644 index 48a385b621..0000000000 --- a/.github/targets_linux/nordic_pca10028_bt5_blehci/target.yml +++ /dev/null @@ -1,23 +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. -# - -### Target: targets/nordic_pca10028_bt5_blehci -target.app: "@apache-mynewt-nimble/apps/blehci" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10028" -target.build_profile: "optimized" diff --git a/.github/targets_linux/nordic_pca10056_advertiser/pkg.yml b/.github/targets_linux/nordic_pca10056_advertiser/pkg.yml deleted file mode 100644 index 84d0c05b34..0000000000 --- a/.github/targets_linux/nordic_pca10056_advertiser/pkg.yml +++ /dev/null @@ -1,24 +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. -# - -pkg.name: "targets/nordic_pca10056_advertiser" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_advertiser/target.yml b/.github/targets_linux/nordic_pca10056_advertiser/target.yml deleted file mode 100644 index 863751aac8..0000000000 --- a/.github/targets_linux/nordic_pca10056_advertiser/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-nimble/apps/advertiser" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_blecent/pkg.yml b/.github/targets_linux/nordic_pca10056_blecent/pkg.yml deleted file mode 100644 index d47c0544da..0000000000 --- a/.github/targets_linux/nordic_pca10056_blecent/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_blecent" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_blecent/target.yml b/.github/targets_linux/nordic_pca10056_blecent/target.yml deleted file mode 100644 index a2da5bf678..0000000000 --- a/.github/targets_linux/nordic_pca10056_blecent/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-nimble/apps/blecent" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_blecsc/pkg.yml b/.github/targets_linux/nordic_pca10056_blecsc/pkg.yml deleted file mode 100644 index f26c7df69a..0000000000 --- a/.github/targets_linux/nordic_pca10056_blecsc/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_blecsc" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_blecsc/target.yml b/.github/targets_linux/nordic_pca10056_blecsc/target.yml deleted file mode 100644 index b665aaf399..0000000000 --- a/.github/targets_linux/nordic_pca10056_blecsc/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-nimble/apps/blecsc" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_blehci_all_enabled/pkg.yml b/.github/targets_linux/nordic_pca10056_blehci_all_enabled/pkg.yml deleted file mode 100644 index c44ac2824a..0000000000 --- a/.github/targets_linux/nordic_pca10056_blehci_all_enabled/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_blehci_all_enabled" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_blehci_all_enabled/syscfg.yml b/.github/targets_linux/nordic_pca10056_blehci_all_enabled/syscfg.yml deleted file mode 100644 index 5bb326eb62..0000000000 --- a/.github/targets_linux/nordic_pca10056_blehci_all_enabled/syscfg.yml +++ /dev/null @@ -1,39 +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. -# - -syscfg.vals: - BLE_EXT_ADV: 1 - BLE_EXT_ADV_MAX_SIZE: 1650 - BLE_TRANSPORT_UART_BAUDRATE: 1000000 - BLE_TRANSPORT_UART_FLOW_CONTROL: rtscts - BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 - BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 - BLE_LL_CFG_FEAT_LL_PRIVACY: 1 - BLE_LL_CONN_INIT_MAX_TX_BYTES: 251 - BLE_LL_DTM: 1 - BLE_MAX_CONNECTIONS: 5 - BLE_MAX_PERIODIC_SYNCS: 5 - BLE_MULTI_ADV_INSTANCES: 6 - BLE_PERIODIC_ADV: 1 - BLE_PHY_DBG_TIME_ADDRESS_END_PIN: 14 - BLE_PHY_DBG_TIME_TXRXEN_READY_PIN: 12 - BLE_PHY_DBG_TIME_WFR_PIN: 16 - BLE_XTAL_SETTLE_TIME: 1500 - BLE_LL_HCI_LLCP_TRACE: 1 diff --git a/.github/targets_linux/nordic_pca10056_blehci_all_enabled/target.yml b/.github/targets_linux/nordic_pca10056_blehci_all_enabled/target.yml deleted file mode 100644 index 103dd2996c..0000000000 --- a/.github/targets_linux/nordic_pca10056_blehci_all_enabled/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-nimble/apps/blehci" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_blehci_no_privacy/pkg.yml b/.github/targets_linux/nordic_pca10056_blehci_no_privacy/pkg.yml deleted file mode 100644 index 539a36409e..0000000000 --- a/.github/targets_linux/nordic_pca10056_blehci_no_privacy/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_blehci_no_privacy" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_blehci_no_privacy/syscfg.yml b/.github/targets_linux/nordic_pca10056_blehci_no_privacy/syscfg.yml deleted file mode 100644 index 8d1f9afff8..0000000000 --- a/.github/targets_linux/nordic_pca10056_blehci_no_privacy/syscfg.yml +++ /dev/null @@ -1,22 +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. -# - -syscfg.vals: - BLE_LL_CFG_FEAT_LL_PRIVACY: 0 - diff --git a/.github/targets_linux/nordic_pca10056_blehci_no_privacy/target.yml b/.github/targets_linux/nordic_pca10056_blehci_no_privacy/target.yml deleted file mode 100644 index 103dd2996c..0000000000 --- a/.github/targets_linux/nordic_pca10056_blehci_no_privacy/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-nimble/apps/blehci" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_blehr/pkg.yml b/.github/targets_linux/nordic_pca10056_blehr/pkg.yml deleted file mode 100644 index fd7e6fa90d..0000000000 --- a/.github/targets_linux/nordic_pca10056_blehr/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_blehr" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_blehr/target.yml b/.github/targets_linux/nordic_pca10056_blehr/target.yml deleted file mode 100644 index 104b2ea5ae..0000000000 --- a/.github/targets_linux/nordic_pca10056_blehr/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-nimble/apps/blehr" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_blemesh/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh/pkg.yml deleted file mode 100644 index b1785b01b5..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_blemesh" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_blemesh/target.yml b/.github/targets_linux/nordic_pca10056_blemesh/target.yml deleted file mode 100644 index 0146506c39..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-nimble/apps/blemesh" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_blemesh_cdb/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_cdb/pkg.yml deleted file mode 100644 index 2a85a98817..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_cdb/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_blemesh_cdb" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_blemesh_cdb/syscfg.yml b/.github/targets_linux/nordic_pca10056_blemesh_cdb/syscfg.yml deleted file mode 100644 index b17ebb3a18..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_cdb/syscfg.yml +++ /dev/null @@ -1,21 +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. -# - -syscfg.vals: - BLE_MESH_CDB: 1 diff --git a/.github/targets_linux/nordic_pca10056_blemesh_cdb/target.yml b/.github/targets_linux/nordic_pca10056_blemesh_cdb/target.yml deleted file mode 100644 index 0146506c39..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_cdb/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-nimble/apps/blemesh" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/pkg.yml deleted file mode 100644 index 3fec50f689..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_blemesh_ext_adv" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/syscfg.yml b/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/syscfg.yml deleted file mode 100644 index 1bb5ba41ce..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/syscfg.yml +++ /dev/null @@ -1,22 +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. -# - -syscfg.vals: - BLE_MULTI_ADV_INSTANCES: 1 - BLE_EXT_ADV: 1 diff --git a/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/target.yml b/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/target.yml deleted file mode 100644 index 0146506c39..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_ext_adv/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-nimble/apps/blemesh" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_blemesh_light/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_light/pkg.yml deleted file mode 100644 index 991cccfd73..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_light/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_blemesh_light" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_blemesh_light/target.yml b/.github/targets_linux/nordic_pca10056_blemesh_light/target.yml deleted file mode 100644 index 400ed4b6a9..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_light/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-nimble/apps/blemesh_light" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_blemesh_models_example_1/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_models_example_1/pkg.yml deleted file mode 100644 index 38c54781ae..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_models_example_1/pkg.yml +++ /dev/null @@ -1,24 +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. -# - -pkg.name: "targets/nordic_pca10056_blemesh_models_example_1" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_blemesh_models_example_1/target.yml b/.github/targets_linux/nordic_pca10056_blemesh_models_example_1/target.yml deleted file mode 100644 index 963ea6f087..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_models_example_1/target.yml +++ /dev/null @@ -1,22 +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. -# - -target.app: "@apache-mynewt-nimble/apps/blemesh_models_example_1" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_blemesh_models_example_2/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_models_example_2/pkg.yml deleted file mode 100644 index b17b652583..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_models_example_2/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_blemesh_models_example_2" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_blemesh_models_example_2/target.yml b/.github/targets_linux/nordic_pca10056_blemesh_models_example_2/target.yml deleted file mode 100644 index 9461ceff7e..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_models_example_2/target.yml +++ /dev/null @@ -1,22 +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. -# - -target.app: "@apache-mynewt-nimble/apps/blemesh_models_example_2" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_blemesh_shell/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_shell/pkg.yml deleted file mode 100644 index 4636feb41a..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_shell/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_blemesh_shell" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_blemesh_shell/target.yml b/.github/targets_linux/nordic_pca10056_blemesh_shell/target.yml deleted file mode 100644 index 1236f8cc8e..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_shell/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-nimble/apps/blemesh_shell" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_blemesh_storage/pkg.yml b/.github/targets_linux/nordic_pca10056_blemesh_storage/pkg.yml deleted file mode 100644 index ff17acfcc0..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_storage/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_blemesh_storage" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_blemesh_storage/syscfg.yml b/.github/targets_linux/nordic_pca10056_blemesh_storage/syscfg.yml deleted file mode 100644 index e64a2655bb..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_storage/syscfg.yml +++ /dev/null @@ -1,22 +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. -# - -syscfg.vals: - BLE_MESH_SETTINGS: 1 - CONFIG_NFFS: 1 diff --git a/.github/targets_linux/nordic_pca10056_blemesh_storage/target.yml b/.github/targets_linux/nordic_pca10056_blemesh_storage/target.yml deleted file mode 100644 index 0146506c39..0000000000 --- a/.github/targets_linux/nordic_pca10056_blemesh_storage/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-nimble/apps/blemesh" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_bleprph/pkg.yml b/.github/targets_linux/nordic_pca10056_bleprph/pkg.yml deleted file mode 100644 index d1e7b95eea..0000000000 --- a/.github/targets_linux/nordic_pca10056_bleprph/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_bleprph" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_bleprph/target.yml b/.github/targets_linux/nordic_pca10056_bleprph/target.yml deleted file mode 100644 index ef3bfacb08..0000000000 --- a/.github/targets_linux/nordic_pca10056_bleprph/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-nimble/apps/bleprph" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_bleprph_oic/pkg.yml b/.github/targets_linux/nordic_pca10056_bleprph_oic/pkg.yml deleted file mode 100644 index aef9c2eb2e..0000000000 --- a/.github/targets_linux/nordic_pca10056_bleprph_oic/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_bleprph_oic" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_bleprph_oic/target.yml b/.github/targets_linux/nordic_pca10056_bleprph_oic/target.yml deleted file mode 100644 index b9e3747fa2..0000000000 --- a/.github/targets_linux/nordic_pca10056_bleprph_oic/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-core/apps/bleprph_oic" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_blesplit/pkg.yml b/.github/targets_linux/nordic_pca10056_blesplit/pkg.yml deleted file mode 100644 index 8781b07ae0..0000000000 --- a/.github/targets_linux/nordic_pca10056_blesplit/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_blesplit" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_blesplit/target.yml b/.github/targets_linux/nordic_pca10056_blesplit/target.yml deleted file mode 100644 index 402d56434d..0000000000 --- a/.github/targets_linux/nordic_pca10056_blesplit/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-core/apps/blesplit" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_bleuart/pkg.yml b/.github/targets_linux/nordic_pca10056_bleuart/pkg.yml deleted file mode 100644 index f3f3ce922d..0000000000 --- a/.github/targets_linux/nordic_pca10056_bleuart/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -pkg.name: "targets/nordic_pca10056_bleuart" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: - diff --git a/.github/targets_linux/nordic_pca10056_bleuart/target.yml b/.github/targets_linux/nordic_pca10056_bleuart/target.yml deleted file mode 100644 index 89b118bdd0..0000000000 --- a/.github/targets_linux/nordic_pca10056_bleuart/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-core/apps/bleuart" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/targets_linux/nordic_pca10056_btshell_2M/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_2M/pkg.yml deleted file mode 100644 index fc2db1d019..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_2M/pkg.yml +++ /dev/null @@ -1,24 +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. -# - -pkg.name: "targets/nordic_pca10056_btshell_2M" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_btshell_2M/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_2M/syscfg.yml deleted file mode 100644 index 95d75dedd9..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_2M/syscfg.yml +++ /dev/null @@ -1,21 +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. -# - -syscfg.vals: - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 diff --git a/.github/targets_linux/nordic_pca10056_btshell_2M/target.yml b/.github/targets_linux/nordic_pca10056_btshell_2M/target.yml deleted file mode 100644 index 396524b428..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_2M/target.yml +++ /dev/null @@ -1,22 +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. -# - -target.app: "@apache-mynewt-nimble/apps/btshell" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_btshell_2M_coded/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_2M_coded/pkg.yml deleted file mode 100644 index 0ddee925fb..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_2M_coded/pkg.yml +++ /dev/null @@ -1,24 +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. -# - -pkg.name: "targets/nordic_pca10056_btshell_2M_coded" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_btshell_2M_coded/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_2M_coded/syscfg.yml deleted file mode 100644 index 83359127e5..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_2M_coded/syscfg.yml +++ /dev/null @@ -1,22 +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. -# - -syscfg.vals: - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 - BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 diff --git a/.github/targets_linux/nordic_pca10056_btshell_2M_coded/target.yml b/.github/targets_linux/nordic_pca10056_btshell_2M_coded/target.yml deleted file mode 100644 index 396524b428..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_2M_coded/target.yml +++ /dev/null @@ -1,22 +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. -# - -target.app: "@apache-mynewt-nimble/apps/btshell" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_btshell_all/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_all/pkg.yml deleted file mode 100644 index 4a867f7aa9..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_all/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -### Package: "targets/nordic_pca10056_btshell_all -pkg.name: "targets/nordic_pca10056_btshell_all" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_btshell_all/target.yml b/.github/targets_linux/nordic_pca10056_btshell_all/target.yml deleted file mode 100644 index 8ad43d72b4..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_all/target.yml +++ /dev/null @@ -1,23 +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. -# - -### Target: targets/nordic_pca10056_btshell_all -target.app: "@apache-mynewt-nimble/apps/btshell" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_btshell_all_v52/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_all_v52/pkg.yml deleted file mode 100644 index d677ba1c24..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_all_v52/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -### Package: "targets/nordic_pca10056_btshell_all_v52 -pkg.name: "targets/nordic_pca10056_btshell_all_v52" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_btshell_all_v52/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_all_v52/syscfg.yml deleted file mode 100644 index 2e37f63f9a..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_all_v52/syscfg.yml +++ /dev/null @@ -1,45 +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. -# - -syscfg.vals: - BLE_EDDYSTONE: 1 - BLE_EXT_ADV: 1 - BLE_EXT_ADV_MAX_SIZE: 1650 - BLE_HS_DEBUG: 1 - BLE_L2CAP_COC_MAX_NUM: 5 - BLE_L2CAP_ENHANCED_COC: 1 - - BLE_MAX_CONNECTIONS: 5 - BLE_MONITOR_RTT: 1 - BLE_MULTI_ADV_INSTANCES: 5 - BLE_PERIODIC_ADV: 1 - BLE_MAX_PERIODIC_SYNCS: 5 - BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 - BLE_SM_BONDING: 1 - BLE_SM_LEGACY: 1 - BLE_SM_SC: 1 - BLE_STORE_MAX_BONDS: 5 - BLE_VERSION: 52 - - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 - BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 - BLE_LL_CFG_FEAT_LL_PRIVACY: 1 - BLE_LL_CONN_INIT_MAX_TX_BYTES: 251 - BLE_LL_DTM: 1 - BLE_LL_DTM_EXTENSIONS: 1 diff --git a/.github/targets_linux/nordic_pca10056_btshell_all_v52/target.yml b/.github/targets_linux/nordic_pca10056_btshell_all_v52/target.yml deleted file mode 100644 index 85a2ae90db..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_all_v52/target.yml +++ /dev/null @@ -1,23 +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. -# - -### Target: targets/nordic_pca10056_btshell_all_v52 -target.app: "@apache-mynewt-nimble/apps/btshell" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_btshell_coded/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_coded/pkg.yml deleted file mode 100644 index c3ec70a308..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_coded/pkg.yml +++ /dev/null @@ -1,24 +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. -# - -pkg.name: "targets/nordic_pca10056_btshell_coded" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_btshell_coded/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_coded/syscfg.yml deleted file mode 100644 index 849aad7d0e..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_coded/syscfg.yml +++ /dev/null @@ -1,21 +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. -# - -syscfg.vals: - BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 diff --git a/.github/targets_linux/nordic_pca10056_btshell_coded/target.yml b/.github/targets_linux/nordic_pca10056_btshell_coded/target.yml deleted file mode 100644 index 396524b428..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_coded/target.yml +++ /dev/null @@ -1,22 +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. -# - -target.app: "@apache-mynewt-nimble/apps/btshell" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_btshell_ext_adv/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_ext_adv/pkg.yml deleted file mode 100644 index c8cce29975..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_ext_adv/pkg.yml +++ /dev/null @@ -1,24 +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. -# - -pkg.name: "targets/nordic_pca10056_btshell_ext_adv" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_btshell_ext_adv/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_ext_adv/syscfg.yml deleted file mode 100644 index a5526dfeb8..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_ext_adv/syscfg.yml +++ /dev/null @@ -1,21 +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. -# - -syscfg.vals: - BLE_EXT_ADV: 1 diff --git a/.github/targets_linux/nordic_pca10056_btshell_ext_adv/target.yml b/.github/targets_linux/nordic_pca10056_btshell_ext_adv/target.yml deleted file mode 100644 index 396524b428..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_ext_adv/target.yml +++ /dev/null @@ -1,22 +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. -# - -target.app: "@apache-mynewt-nimble/apps/btshell" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/pkg.yml deleted file mode 100644 index b4f519e241..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/pkg.yml +++ /dev/null @@ -1,24 +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. -# - -pkg.name: "targets/nordic_pca10056_btshell_periodic_adv" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/syscfg.yml deleted file mode 100644 index 2f01ccabb3..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/syscfg.yml +++ /dev/null @@ -1,22 +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. -# - -syscfg.vals: - BLE_EXT_ADV: 1 - BLE_PERIODIC_ADV: 1 diff --git a/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/target.yml b/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/target.yml deleted file mode 100644 index 396524b428..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_periodic_adv/target.yml +++ /dev/null @@ -1,22 +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. -# - -target.app: "@apache-mynewt-nimble/apps/btshell" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/pkg.yml deleted file mode 100644 index 4c3d331ebe..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/pkg.yml +++ /dev/null @@ -1,24 +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. -# - -pkg.name: "targets/nordic_pca10056_btshell_sm_legacy" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/syscfg.yml deleted file mode 100644 index a7789d626f..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/syscfg.yml +++ /dev/null @@ -1,22 +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. -# - -syscfg.vals: - BLE_SM_LEGACY: 1 - BLE_SM_SC: 0 diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/target.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/target.yml deleted file mode 100644 index 396524b428..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_legacy/target.yml +++ /dev/null @@ -1,22 +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. -# - -target.app: "@apache-mynewt-nimble/apps/btshell" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_none/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_none/pkg.yml deleted file mode 100644 index a8ccee1f45..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_none/pkg.yml +++ /dev/null @@ -1,24 +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. -# - -pkg.name: "targets/nordic_pca10056_btshell_sm_none" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_none/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_none/syscfg.yml deleted file mode 100644 index 9ee2ab8f6d..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_none/syscfg.yml +++ /dev/null @@ -1,22 +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. -# - -syscfg.vals: - BLE_SM_LEGACY: 0 - BLE_SM_SC: 0 diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_none/target.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_none/target.yml deleted file mode 100644 index 396524b428..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_none/target.yml +++ /dev/null @@ -1,22 +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. -# - -target.app: "@apache-mynewt-nimble/apps/btshell" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_sc/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_sc/pkg.yml deleted file mode 100644 index 611096aa36..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_sc/pkg.yml +++ /dev/null @@ -1,24 +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. -# - -pkg.name: "targets/nordic_pca10056_btshell_sm_sc" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_sc/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_sc/syscfg.yml deleted file mode 100644 index d6b579ceb4..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_sc/syscfg.yml +++ /dev/null @@ -1,22 +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. -# - -syscfg.vals: - BLE_SM_LEGACY: 0 - BLE_SM_SC: 1 diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_sc/target.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_sc/target.yml deleted file mode 100644 index 396524b428..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_sc/target.yml +++ /dev/null @@ -1,22 +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. -# - -target.app: "@apache-mynewt-nimble/apps/btshell" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml deleted file mode 100644 index 3983ec0cae..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/pkg.yml +++ /dev/null @@ -1,24 +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. -# - -pkg.name: "targets/nordic_pca10056_btshell_sm_sc_legacy" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/syscfg.yml deleted file mode 100644 index d62f1f0f1c..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/syscfg.yml +++ /dev/null @@ -1,22 +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. -# - -syscfg.vals: - BLE_SM_LEGACY: 1 - BLE_SM_SC: 1 diff --git a/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/target.yml b/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/target.yml deleted file mode 100644 index 396524b428..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_sm_sc_legacy/target.yml +++ /dev/null @@ -1,22 +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. -# - -target.app: "@apache-mynewt-nimble/apps/btshell" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/pkg.yml b/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/pkg.yml deleted file mode 100644 index aeb3d88b39..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -### Package: "targets/nordic_pca10056_btshell_xtal_settle_0 -pkg.name: "targets/nordic_pca10056_btshell_xtal_settle_0" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/syscfg.yml b/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/syscfg.yml deleted file mode 100644 index 324a679fa4..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/syscfg.yml +++ /dev/null @@ -1,21 +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. -# - -syscfg.vals: - BLE_XTAL_SETTLE_TIME: 0 diff --git a/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/target.yml b/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/target.yml deleted file mode 100644 index 988da49e16..0000000000 --- a/.github/targets_linux/nordic_pca10056_btshell_xtal_settle_0/target.yml +++ /dev/null @@ -1,23 +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. -# - -### Target: targets/nordic_pca10056_btshell_xtal_settle_0 -target.app: "@apache-mynewt-nimble/apps/btshell" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_bttester/pkg.yml b/.github/targets_linux/nordic_pca10056_bttester/pkg.yml deleted file mode 100644 index 56a5f686eb..0000000000 --- a/.github/targets_linux/nordic_pca10056_bttester/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -### Package: "targets/nordic_pca10056_bttester -pkg.name: "targets/nordic_pca10056_bttester" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_bttester/syscfg.yml b/.github/targets_linux/nordic_pca10056_bttester/syscfg.yml deleted file mode 100644 index 288a45c123..0000000000 --- a/.github/targets_linux/nordic_pca10056_bttester/syscfg.yml +++ /dev/null @@ -1,26 +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. -# - -syscfg.vals: - BLE_EXT_ADV: 1 - BLE_MULTI_ADV_INSTANCES: 1 - BLE_PERIODIC_ADV: 1 - BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 - BLE_SM_LEGACY: 1 - BLE_SM_SC: 1 diff --git a/.github/targets_linux/nordic_pca10056_bttester/target.yml b/.github/targets_linux/nordic_pca10056_bttester/target.yml deleted file mode 100644 index 36f8f128a7..0000000000 --- a/.github/targets_linux/nordic_pca10056_bttester/target.yml +++ /dev/null @@ -1,23 +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. -# - -### Target: targets/nordic_pca10056_bttester -target.app: "@apache-mynewt-nimble/apps/bttester" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_dtm/pkg.yml b/.github/targets_linux/nordic_pca10056_dtm/pkg.yml deleted file mode 100644 index 9fde92a61e..0000000000 --- a/.github/targets_linux/nordic_pca10056_dtm/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -### Package: "targets/nordic_pca10056_dtm -pkg.name: "targets/nordic_pca10056_dtm" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_dtm/target.yml b/.github/targets_linux/nordic_pca10056_dtm/target.yml deleted file mode 100644 index 8c6b21a736..0000000000 --- a/.github/targets_linux/nordic_pca10056_dtm/target.yml +++ /dev/null @@ -1,23 +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. -# - -### Target: targets/nordic_pca10056_dtm -target.app: "@apache-mynewt-nimble/apps/dtm" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_ext_advertiser/pkg.yml b/.github/targets_linux/nordic_pca10056_ext_advertiser/pkg.yml deleted file mode 100644 index 23a8c1446f..0000000000 --- a/.github/targets_linux/nordic_pca10056_ext_advertiser/pkg.yml +++ /dev/null @@ -1,25 +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. -# - -### Package: "targets/nordic_pca10056_btshell -pkg.name: "targets/nordic_pca10056_ext_advertiser" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_ext_advertiser/target.yml b/.github/targets_linux/nordic_pca10056_ext_advertiser/target.yml deleted file mode 100644 index 6761de7ab9..0000000000 --- a/.github/targets_linux/nordic_pca10056_ext_advertiser/target.yml +++ /dev/null @@ -1,23 +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. -# - -### Target: targets/nordic_pca10056_btshell -target.app: "@apache-mynewt-nimble/apps/ext_advertiser" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" -target.build_profile: "debug" diff --git a/.github/targets_linux/nordic_pca10056_scanner/pkg.yml b/.github/targets_linux/nordic_pca10056_scanner/pkg.yml deleted file mode 100644 index dfc3c8b015..0000000000 --- a/.github/targets_linux/nordic_pca10056_scanner/pkg.yml +++ /dev/null @@ -1,24 +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. -# - -pkg.name: "targets/nordic_pca10056_scanner" -pkg.type: "target" -pkg.description: -pkg.author: -pkg.homepage: diff --git a/.github/targets_linux/nordic_pca10056_scanner/target.yml b/.github/targets_linux/nordic_pca10056_scanner/target.yml deleted file mode 100644 index 904549cb75..0000000000 --- a/.github/targets_linux/nordic_pca10056_scanner/target.yml +++ /dev/null @@ -1,21 +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. -# - -target.app: "@apache-mynewt-nimble/apps/scanner" -target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" diff --git a/.github/test_build_apps.sh b/.github/test_build_apps.sh new file mode 100644 index 0000000000..cbf25cfffa --- /dev/null +++ b/.github/test_build_apps.sh @@ -0,0 +1,60 @@ +#!/bin/bash -x + +# 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. + +EXIT_CODE=0 + +APPS=$(basename -a `ls -d repos/apache-mynewt-nimble/apps/*/`) + +IGNORED_APPS="mesh_badge" + +for app in ${APPS}; do + # NOTE: do not remove the spaces around IGNORED_APPS; it's required to + # match against the first and last entries + if [[ " ${IGNORED_APPS} " =~ [[:blank:]]${app}[[:blank:]] ]]; then + echo "Skipping $app" + continue + fi + + echo "Testing $app" + + target="test-$app" + newt target delete -s -f $target &> /dev/null + newt target create -s $target + newt target set -s $target bsp="@apache-mynewt-core/hw/bsp/nordic_pca10056" + newt target set -s $target app="@apache-mynewt-nimble/apps/$app" + + echo "Building with app default config" + newt build -q $target + + rc=$? + [[ $rc -ne 0 ]] && EXIT_CODE=$rc + + echo "Building with all-enabled config" + newt clean $target + cp -f ../.github/test_build_apps_syscfg.yml targets/$target/syscfg.yml + newt build -q $target + + rc=$? + [[ $rc -ne 0 ]] && EXIT_CODE=$rc + + newt clean $target + newt target delete -s -f $target +done + +exit $EXIT_CODE diff --git a/.github/targets_linux/nordic_pca10056_btshell_all/syscfg.yml b/.github/test_build_apps_syscfg.yml similarity index 80% rename from .github/targets_linux/nordic_pca10056_btshell_all/syscfg.yml rename to .github/test_build_apps_syscfg.yml index 513eec9b03..9722b51c73 100644 --- a/.github/targets_linux/nordic_pca10056_btshell_all/syscfg.yml +++ b/.github/test_build_apps_syscfg.yml @@ -18,24 +18,40 @@ # syscfg.vals: - BLE_EDDYSTONE: 1 + # common + BLE_ROLE_CENTRAL: 1 + BLE_ROLE_PERIPHERAL: 1 + BLE_ROLE_BROADCASTER: 1 + BLE_ROLE_OBSERVER: 1 + BLE_WHITELIST: 1 + BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: 1 + BLE_ISO: 1 + BLE_ISO_TEST: 1 + BLE_HCI_VS: 1 + BLE_POWER_CONTROL: 1 + BLE_CONN_SUBRATING: 1 BLE_EXT_ADV: 1 BLE_EXT_ADV_MAX_SIZE: 1650 + BLE_VERSION: 54 + BLE_MULTI_ADV_INSTANCES: 5 + BLE_PERIODIC_ADV: 1 + BLE_MAX_PERIODIC_SYNCS: 5 + + # host + BLE_EDDYSTONE: 1 BLE_HS_DEBUG: 1 BLE_L2CAP_COC_MAX_NUM: 5 BLE_L2CAP_ENHANCED_COC: 1 BLE_MAX_CONNECTIONS: 5 BLE_MONITOR_RTT: 1 - BLE_MULTI_ADV_INSTANCES: 5 - BLE_PERIODIC_ADV: 1 - BLE_MAX_PERIODIC_SYNCS: 5 BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 BLE_SM_BONDING: 1 BLE_SM_LEGACY: 1 BLE_SM_SC: 1 BLE_STORE_MAX_BONDS: 5 - BLE_VERSION: 54 + BLE_EATT_CHAN_NUM: 2 + # controller BLE_LL_CFG_FEAT_LE_2M_PHY: 1 BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 BLE_LL_CFG_FEAT_LL_PRIVACY: 1 diff --git a/.github/workflows/build_all_apps.yml b/.github/workflows/build_all_apps.yml new file mode 100644 index 0000000000..7881d96c62 --- /dev/null +++ b/.github/workflows/build_all_apps.yml @@ -0,0 +1,68 @@ +# +# 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. +# + +name: Build check + +on: [push, pull_request] + +jobs: + targets: + name: Build all apps + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: 'stable' + - uses: carlosperate/arm-none-eabi-gcc-action@48db4484a55750df7a0ccca63347fcdea6534d78 + with: + release: '12.2.Rel1' + - name: Install Dependencies + shell: bash + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get update + sudo apt-get install -y gcc-multilib + - name: Install newt + shell: bash + run: | + go version + go install mynewt.apache.org/newt/newt@latest + - name: Setup project + shell: bash + run: | + newt new build + cp -f .github/project.yml build/project.yml + cd build + newt upgrade --shallow=1 + rm -rf targets + rm -rf repos/apache-mynewt-nimble + git clone .. repos/apache-mynewt-nimble + cd .. + - name: Build applications + shell: bash + if: matrix.os == 'ubuntu-latest' + run: | + cd build + bash ../.github/test_build_apps.sh + cd .. diff --git a/.github/workflows/build_cc_target.yml b/.github/workflows/build_cc_target.yml index 58646db905..e76c809c60 100644 --- a/.github/workflows/build_cc_target.yml +++ b/.github/workflows/build_cc_target.yml @@ -52,11 +52,13 @@ jobs: newt upgrade --shallow=1 rm -rf repos/apache-mynewt-nimble git clone .. repos/apache-mynewt-nimble - rm -rf targets cd .. - - name: Build targets + - name: Build test target shell: bash run: | - cp -r .github/targets_linux build/targets cd build - newt build -j 1 nordic_pca10056_btshell_all + newt target create cc_test + newt target set cc_test bsp="@apache-mynewt-core/hw/bsp/nordic_pca10056" + newt target set cc_test app="@apache-mynewt-nimble/apps/btshell" + cp -f ../.github/test_build_apps_syscfg.yml targets/cc_test/syscfg.yml + newt build -j 1 cc_test From da4e2f0f12859079f1bde47cbd69f39026c3cc73 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 26 Jul 2023 16:37:02 +0200 Subject: [PATCH 0839/1333] porting: Remove dependency on Mynewt logging system Define NPL interface that can be used by ports to implement logging. --- apps/blemesh_shell/src/main.c | 2 - nimble/host/include/host/ble_hs_log.h | 22 ++- nimble/host/mesh/include/mesh/glue.h | 19 +-- nimble/host/mesh/src/access.c | 4 +- nimble/host/mesh/src/adv.c | 3 +- nimble/host/mesh/src/adv_ext.c | 4 +- nimble/host/mesh/src/adv_legacy.c | 3 +- nimble/host/mesh/src/aes-ccm.c | 4 +- nimble/host/mesh/src/app_keys.c | 7 +- nimble/host/mesh/src/beacon.c | 5 +- nimble/host/mesh/src/cdb.c | 5 +- nimble/host/mesh/src/cfg.c | 6 +- nimble/host/mesh/src/cfg_cli.c | 5 +- nimble/host/mesh/src/cfg_srv.c | 4 +- nimble/host/mesh/src/crypto.c | 4 +- nimble/host/mesh/src/friend.c | 5 +- nimble/host/mesh/src/glue.c | 4 +- nimble/host/mesh/src/health_cli.c | 4 +- nimble/host/mesh/src/health_srv.c | 4 +- nimble/host/mesh/src/heartbeat.c | 3 +- nimble/host/mesh/src/lpn.c | 4 +- nimble/host/mesh/src/mesh.c | 4 +- nimble/host/mesh/src/model_cli.c | 4 +- nimble/host/mesh/src/model_srv.c | 5 +- nimble/host/mesh/src/net.c | 4 +- nimble/host/mesh/src/pb_adv.c | 4 +- nimble/host/mesh/src/pb_gatt.c | 3 +- nimble/host/mesh/src/pb_gatt_srv.c | 3 +- nimble/host/mesh/src/prov.c | 4 +- nimble/host/mesh/src/prov_device.c | 3 +- nimble/host/mesh/src/provisioner.c | 3 +- nimble/host/mesh/src/proxy_msg.c | 4 +- nimble/host/mesh/src/proxy_srv.c | 3 +- nimble/host/mesh/src/rpl.c | 4 +- nimble/host/mesh/src/settings.c | 4 +- nimble/host/mesh/src/subnet.c | 4 +- nimble/host/mesh/src/transport.c | 4 +- nimble/host/src/ble_att_cmd.c | 4 + nimble/host/src/ble_eatt.c | 2 + nimble/host/src/ble_hs_log.c | 2 - nimble/include/nimble/nimble_npl_log.h | 57 +++++++ .../examples/linux/include/logcfg/logcfg.h | 32 ---- .../linux_blemesh/include/logcfg/logcfg.h | 158 ------------------ .../examples/nuttx/include/logcfg/logcfg.h | 25 --- porting/nimble/include/log_common/ignore.h | 64 ------- .../nimble/include/log_common/log_common.h | 144 ---------------- porting/nimble/include/logcfg/logcfg.h | 32 ---- porting/nimble/include/modlog/modlog.h | 68 -------- .../dummy/include/nimble/nimble_npl_os_log.h | 27 +++ .../include/nimble/nimble_npl_os_log.h | 36 ++++ .../linux/include/nimble/nimble_npl_os_log.h | 37 ++++ .../include/nimble/nimble_npl_os_log.h} | 33 +--- porting/npl/nuttx/include/modlog/modlog.h | 68 -------- .../nuttx/include/nimble/nimble_npl_os_log.h | 36 ++++ porting/npl/riot/include/logcfg/logcfg.h | 32 ---- .../riot/include/nimble/nimble_npl_os_log.h | 36 ++++ 56 files changed, 352 insertions(+), 722 deletions(-) create mode 100644 nimble/include/nimble/nimble_npl_log.h delete mode 100644 porting/examples/linux/include/logcfg/logcfg.h delete mode 100644 porting/examples/linux_blemesh/include/logcfg/logcfg.h delete mode 100644 porting/examples/nuttx/include/logcfg/logcfg.h delete mode 100644 porting/nimble/include/log_common/ignore.h delete mode 100644 porting/nimble/include/log_common/log_common.h delete mode 100644 porting/nimble/include/logcfg/logcfg.h delete mode 100644 porting/nimble/include/modlog/modlog.h create mode 100644 porting/npl/dummy/include/nimble/nimble_npl_os_log.h create mode 100644 porting/npl/freertos/include/nimble/nimble_npl_os_log.h create mode 100644 porting/npl/linux/include/nimble/nimble_npl_os_log.h rename porting/{nimble/include/log/log.h => npl/mynewt/include/nimble/nimble_npl_os_log.h} (58%) delete mode 100644 porting/npl/nuttx/include/modlog/modlog.h create mode 100644 porting/npl/nuttx/include/nimble/nimble_npl_os_log.h delete mode 100644 porting/npl/riot/include/logcfg/logcfg.h create mode 100644 porting/npl/riot/include/nimble/nimble_npl_os_log.h diff --git a/apps/blemesh_shell/src/main.c b/apps/blemesh_shell/src/main.c index fb9c9e6915..ee6f763e73 100644 --- a/apps/blemesh_shell/src/main.c +++ b/apps/blemesh_shell/src/main.c @@ -17,8 +17,6 @@ * under the License. */ -#define MESH_LOG_MODULE BLE_MESH_LOG - #include #include "os/mynewt.h" #include "mesh/mesh.h" diff --git a/nimble/host/include/host/ble_hs_log.h b/nimble/host/include/host/ble_hs_log.h index a89b1e6629..3e1ded4cdd 100644 --- a/nimble/host/include/host/ble_hs_log.h +++ b/nimble/host/include/host/ble_hs_log.h @@ -20,6 +20,12 @@ #ifndef H_BLE_HS_LOG_ #define H_BLE_HS_LOG_ +#ifndef BLE_NPL_LOG_MODULE +#define BLE_NPL_LOG_MODULE BLE_HS_LOG +#endif + +#include + /** * @file ble_hs_log.h * @@ -33,14 +39,6 @@ * @{ */ -#include "modlog/modlog.h" -#include "log/log.h" - -/* Only include the logcfg header if this version of newt can generate it. */ -#if MYNEWT_VAL(NEWT_FEATURE_LOGCFG) -#include "logcfg/logcfg.h" -#endif - #ifdef __cplusplus extern "C" { #endif @@ -57,7 +55,7 @@ struct os_mbuf; * @param ... The format string and additional arguments for the log message. */ #define BLE_HS_LOG(lvl, ...) \ - BLE_HS_LOG_ ## lvl(__VA_ARGS__) + BLE_NPL_LOG(lvl, __VA_ARGS__) /** * @brief Macro for logging a Bluetooth address at a specified log level. @@ -69,9 +67,9 @@ struct os_mbuf; * @param addr The Bluetooth address to be logged. */ #define BLE_HS_LOG_ADDR(lvl, addr) \ - BLE_HS_LOG_ ## lvl("%02x:%02x:%02x:%02x:%02x:%02x", \ - (addr)[5], (addr)[4], (addr)[3], \ - (addr)[2], (addr)[1], (addr)[0]) + BLE_NPL_LOG(lvl, "%02x:%02x:%02x:%02x:%02x:%02x", \ + (addr)[5], (addr)[4], (addr)[3], \ + (addr)[2], (addr)[1], (addr)[0]) /** diff --git a/nimble/host/mesh/include/mesh/glue.h b/nimble/host/mesh/include/mesh/glue.h index 36b82cf5dd..de36e6fbb6 100644 --- a/nimble/host/mesh/include/mesh/glue.h +++ b/nimble/host/mesh/include/mesh/glue.h @@ -24,8 +24,6 @@ #include #include "syscfg/syscfg.h" -#include "logcfg/logcfg.h" -#include "modlog/modlog.h" #include "nimble/nimble_npl.h" #include "os/os_mbuf.h" @@ -182,19 +180,10 @@ extern "C" { #define BT_GAP_ADV_SLOW_INT_MIN 0x0640 /* 1 s */ #define BT_GAP_ADV_SLOW_INT_MAX 0x0780 /* 1.2 s */ -#ifndef MESH_LOG_MODULE -#define MESH_LOG_MODULE BLE_MESH_LOG -#endif - -#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__) -#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__ - -#define BLE_MESH_LOG(lvl, ...) CAT(MESH_LOG_MODULE, CAT(_, lvl))(__VA_ARGS__) - -#define BT_DBG(fmt, ...) BLE_MESH_LOG(DEBUG, "%s: " fmt "\n", __func__, ## __VA_ARGS__); -#define BT_INFO(fmt, ...) BLE_MESH_LOG(INFO, "%s: " fmt "\n", __func__, ## __VA_ARGS__); -#define BT_WARN(fmt, ...) BLE_MESH_LOG(WARN, "%s: " fmt "\n", __func__, ## __VA_ARGS__); -#define BT_ERR(fmt, ...) BLE_MESH_LOG(ERROR, "%s: " fmt "\n", __func__, ## __VA_ARGS__); +#define BT_DBG(fmt, ...) BLE_NPL_LOG(DEBUG, "%s: " fmt "\n", __func__, ## __VA_ARGS__); +#define BT_INFO(fmt, ...) BLE_NPL_LOG(INFO, "%s: " fmt "\n", __func__, ## __VA_ARGS__); +#define BT_WARN(fmt, ...) BLE_NPL_LOG(WARN, "%s: " fmt "\n", __func__, ## __VA_ARGS__); +#define BT_ERR(fmt, ...) BLE_NPL_LOG(ERROR, "%s: " fmt "\n", __func__, ## __VA_ARGS__); #define BT_GATT_ERR(_att_err) (-(_att_err)) typedef ble_addr_t bt_addr_le_t; diff --git a/nimble/host/mesh/src/access.c b/nimble/host/mesh/src/access.c index 2c07b09478..40395fe445 100644 --- a/nimble/host/mesh/src/access.c +++ b/nimble/host/mesh/src/access.c @@ -7,7 +7,9 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_ACCESS_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_ACCESS_LOG +#include #include #include diff --git a/nimble/host/mesh/src/adv.c b/nimble/host/mesh/src/adv.c index d7a8c123c9..b2c54ae928 100644 --- a/nimble/host/mesh/src/adv.c +++ b/nimble/host/mesh/src/adv.c @@ -8,7 +8,8 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_ADV_LOG +#define BLE_NPL_LOG_MODULE BLE_MESH_ADV_LOG +#include #include "mesh/mesh.h" #include "host/ble_hs_adv.h" diff --git a/nimble/host/mesh/src/adv_ext.c b/nimble/host/mesh/src/adv_ext.c index 07c693dea1..c5689e5652 100644 --- a/nimble/host/mesh/src/adv_ext.c +++ b/nimble/host/mesh/src/adv_ext.c @@ -7,8 +7,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define MESH_LOG_MODULE BLE_MESH_ADV_LOG - +#define BLE_NPL_LOG_MODULE BLE_MESH_ADV_LOG +#include #include "adv.h" #include "net.h" diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index 26865058e9..6d6a666df5 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -7,7 +7,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define MESH_LOG_MODULE BLE_MESH_ADV_LOG +#define BLE_NPL_LOG_MODULE BLE_MESH_ADV_LOG +#include #include "adv.h" #include "net.h" diff --git a/nimble/host/mesh/src/aes-ccm.c b/nimble/host/mesh/src/aes-ccm.c index ab23c26446..4814438b3c 100644 --- a/nimble/host/mesh/src/aes-ccm.c +++ b/nimble/host/mesh/src/aes-ccm.c @@ -5,8 +5,10 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define BLE_NPL_LOG_MODULE BLE_MESH_LOG +#include + #include "crypto.h" -#define MESH_LOG_MODULE BLE_MESH_LOG static inline void xor16(uint8_t *dst, const uint8_t *a, const uint8_t *b) { diff --git a/nimble/host/mesh/src/app_keys.c b/nimble/host/mesh/src/app_keys.c index cfe82576ab..ab7ab0597f 100644 --- a/nimble/host/mesh/src/app_keys.c +++ b/nimble/host/mesh/src/app_keys.c @@ -5,6 +5,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define BLE_NPL_LOG_MODULE BLE_MESH_LOG +#include + #include #include #include "mesh/mesh.h" @@ -21,10 +24,6 @@ #include "access.h" #include "subnet.h" -#define MESH_LOG_MODULE BLE_MESH_LOG - -#include "log/log.h" - /* Tracking of what storage changes are pending for App Keys. We track this in * a separate array here instead of within the respective bt_mesh_app_key * struct itselve, since once a key gets deleted its struct becomes invalid diff --git a/nimble/host/mesh/src/beacon.c b/nimble/host/mesh/src/beacon.c index 2b678f9008..e646fc6a31 100644 --- a/nimble/host/mesh/src/beacon.c +++ b/nimble/host/mesh/src/beacon.c @@ -7,7 +7,10 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_BEACON_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_BEACON_LOG +#include + #include #include diff --git a/nimble/host/mesh/src/cdb.c b/nimble/host/mesh/src/cdb.c index 98084ee3d0..ed97ce539c 100644 --- a/nimble/host/mesh/src/cdb.c +++ b/nimble/host/mesh/src/cdb.c @@ -4,8 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define MESH_LOG_MODULE BLE_MESH_LOG -#include "log/log.h" +#define BLE_NPL_LOG_MODULE BLE_MESH_LOG +#include + #include #include "cdb_priv.h" diff --git a/nimble/host/mesh/src/cfg.c b/nimble/host/mesh/src/cfg.c index 282aefaf43..122ab4dc74 100644 --- a/nimble/host/mesh/src/cfg.c +++ b/nimble/host/mesh/src/cfg.c @@ -4,6 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define BLE_NPL_LOG_MODULE BLE_MESH_LOG +#include + #include "mesh/mesh.h" #include "mesh_priv.h" #include "net.h" @@ -15,9 +18,6 @@ #include "cfg.h" #include "mesh/glue.h" -#define MESH_LOG_MODULE BLE_MESH_LOG -#include "log/log.h" - /* Miscellaneous configuration server model states */ struct cfg_val { uint8_t net_transmit; diff --git a/nimble/host/mesh/src/cfg_cli.c b/nimble/host/mesh/src/cfg_cli.c index 2a68b40a12..6195f2ac29 100644 --- a/nimble/host/mesh/src/cfg_cli.c +++ b/nimble/host/mesh/src/cfg_cli.c @@ -7,7 +7,10 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_MODEL_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_MODEL_LOG +#include + #if MYNEWT_VAL(BLE_MESH_CFG_CLI) #include "mesh/mesh.h" diff --git a/nimble/host/mesh/src/cfg_srv.c b/nimble/host/mesh/src/cfg_srv.c index cdbd0400ca..2b4c046cbd 100644 --- a/nimble/host/mesh/src/cfg_srv.c +++ b/nimble/host/mesh/src/cfg_srv.c @@ -7,7 +7,9 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_MODEL_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_MODEL_LOG +#include #include #include diff --git a/nimble/host/mesh/src/crypto.c b/nimble/host/mesh/src/crypto.c index 3111a6efa1..79378da928 100644 --- a/nimble/host/mesh/src/crypto.c +++ b/nimble/host/mesh/src/crypto.c @@ -7,7 +7,9 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_CRYPTO_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_CRYPTO_LOG +#include #include #include diff --git a/nimble/host/mesh/src/friend.c b/nimble/host/mesh/src/friend.c index 4ce0bbdece..2c99d8d711 100644 --- a/nimble/host/mesh/src/friend.c +++ b/nimble/host/mesh/src/friend.c @@ -7,7 +7,10 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_FRIEND_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_FRIEND_LOG +#include + #if MYNEWT_VAL(BLE_MESH_FRIEND) diff --git a/nimble/host/mesh/src/glue.c b/nimble/host/mesh/src/glue.c index bcacf833c6..7dfcaa3492 100644 --- a/nimble/host/mesh/src/glue.c +++ b/nimble/host/mesh/src/glue.c @@ -18,7 +18,9 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_LOG +#include #include "mesh/glue.h" #include "adv.h" diff --git a/nimble/host/mesh/src/health_cli.c b/nimble/host/mesh/src/health_cli.c index caa70215b7..7765cf11b7 100644 --- a/nimble/host/mesh/src/health_cli.c +++ b/nimble/host/mesh/src/health_cli.c @@ -7,7 +7,9 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_MODEL_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_MODEL_LOG +#include #include #include diff --git a/nimble/host/mesh/src/health_srv.c b/nimble/host/mesh/src/health_srv.c index 4065d24f83..0ea81380e8 100644 --- a/nimble/host/mesh/src/health_srv.c +++ b/nimble/host/mesh/src/health_srv.c @@ -7,7 +7,9 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_MODEL_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_MODEL_LOG +#include #include #include diff --git a/nimble/host/mesh/src/heartbeat.c b/nimble/host/mesh/src/heartbeat.c index faf2f76611..8d15d7642e 100644 --- a/nimble/host/mesh/src/heartbeat.c +++ b/nimble/host/mesh/src/heartbeat.c @@ -4,7 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define MESH_LOG_MODULE BLE_MESH_HEARTBEAT_LOG +#define BLE_NPL_LOG_MODULE BLE_MESH_HEARTBEAT_LOG +#include #include "mesh_priv.h" #include "net.h" diff --git a/nimble/host/mesh/src/lpn.c b/nimble/host/mesh/src/lpn.c index 6e164c1352..13eb7d1386 100644 --- a/nimble/host/mesh/src/lpn.c +++ b/nimble/host/mesh/src/lpn.c @@ -7,7 +7,9 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_LOW_POWER_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_LOW_POWER_LOG +#include #if MYNEWT_VAL(BLE_MESH_LOW_POWER) diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c index 6ab71e8b11..d3ffb28d97 100644 --- a/nimble/host/mesh/src/mesh.c +++ b/nimble/host/mesh/src/mesh.c @@ -7,7 +7,9 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_LOG +#include #include #include diff --git a/nimble/host/mesh/src/model_cli.c b/nimble/host/mesh/src/model_cli.c index 22f9b99ee8..72c2fa0390 100644 --- a/nimble/host/mesh/src/model_cli.c +++ b/nimble/host/mesh/src/model_cli.c @@ -5,7 +5,9 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_MODEL_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_MODEL_LOG +#include #include "mesh/mesh.h" #include "mesh/model_cli.h" diff --git a/nimble/host/mesh/src/model_srv.c b/nimble/host/mesh/src/model_srv.c index 96981cbab6..02b002fd1b 100644 --- a/nimble/host/mesh/src/model_srv.c +++ b/nimble/host/mesh/src/model_srv.c @@ -5,7 +5,10 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_MODEL_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_MODEL_LOG +#include + #include "mesh/mesh.h" #include "mesh/model_srv.h" diff --git a/nimble/host/mesh/src/net.c b/nimble/host/mesh/src/net.c index 229e40546e..15fabb1090 100644 --- a/nimble/host/mesh/src/net.c +++ b/nimble/host/mesh/src/net.c @@ -7,7 +7,9 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_NET_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_NET_LOG +#include #include #include diff --git a/nimble/host/mesh/src/pb_adv.c b/nimble/host/mesh/src/pb_adv.c index 35a02b0dc0..19d179c850 100644 --- a/nimble/host/mesh/src/pb_adv.c +++ b/nimble/host/mesh/src/pb_adv.c @@ -8,7 +8,9 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_PROV_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_PROV_LOG +#include #include #include diff --git a/nimble/host/mesh/src/pb_gatt.c b/nimble/host/mesh/src/pb_gatt.c index 865356eeb5..ddf8ed7363 100644 --- a/nimble/host/mesh/src/pb_gatt.c +++ b/nimble/host/mesh/src/pb_gatt.c @@ -7,7 +7,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define MESH_LOG_MODULE BLE_MESH_PROV_LOG +#define BLE_NPL_LOG_MODULE BLE_MESH_PROV_LOG +#include #include "mesh/mesh.h" #include "prov.h" diff --git a/nimble/host/mesh/src/pb_gatt_srv.c b/nimble/host/mesh/src/pb_gatt_srv.c index 046c942449..2aecec0ced 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.c +++ b/nimble/host/mesh/src/pb_gatt_srv.c @@ -5,7 +5,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define MESH_LOG_MODULE BLE_MESH_PROV_LOG +#define BLE_NPL_LOG_MODULE BLE_MESH_PROV_LOG +#include #include "mesh_priv.h" #include "adv.h" diff --git a/nimble/host/mesh/src/prov.c b/nimble/host/mesh/src/prov.c index cdadbb45ba..730061bb1b 100644 --- a/nimble/host/mesh/src/prov.c +++ b/nimble/host/mesh/src/prov.c @@ -7,7 +7,9 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_PROV_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_PROV_LOG +#include #include diff --git a/nimble/host/mesh/src/prov_device.c b/nimble/host/mesh/src/prov_device.c index e9e2d2b122..ba15c175b2 100644 --- a/nimble/host/mesh/src/prov_device.c +++ b/nimble/host/mesh/src/prov_device.c @@ -7,7 +7,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define MESH_LOG_MODULE BLE_MESH_PROV_LOG +#define BLE_NPL_LOG_MODULE BLE_MESH_PROV_LOG +#include #include "testing.h" #include "crypto.h" diff --git a/nimble/host/mesh/src/provisioner.c b/nimble/host/mesh/src/provisioner.c index f4278e110b..36a20a0cfd 100644 --- a/nimble/host/mesh/src/provisioner.c +++ b/nimble/host/mesh/src/provisioner.c @@ -8,7 +8,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define MESH_LOG_MODULE BLE_MESH_PROV_LOG +#define BLE_NPL_LOG_MODULE BLE_MESH_PROV_LOG +#include #include "testing.h" diff --git a/nimble/host/mesh/src/proxy_msg.c b/nimble/host/mesh/src/proxy_msg.c index 44613af16d..e3aff56274 100644 --- a/nimble/host/mesh/src/proxy_msg.c +++ b/nimble/host/mesh/src/proxy_msg.c @@ -8,7 +8,9 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_PROXY_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_PROXY_LOG +#include #if MYNEWT_VAL(BLE_MESH_PROXY) diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index 91c87e50fc..15939cfea6 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -7,7 +7,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define MESH_LOG_MODULE BLE_MESH_PROXY_LOG +#define BLE_NPL_LOG_MODULE BLE_MESH_PROXY_LOG +#include #include "mesh/slist.h" #include "mesh/mesh.h" diff --git a/nimble/host/mesh/src/rpl.c b/nimble/host/mesh/src/rpl.c index 3a54414cea..ffee94a5d7 100644 --- a/nimble/host/mesh/src/rpl.c +++ b/nimble/host/mesh/src/rpl.c @@ -7,9 +7,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define MESH_LOG_MODULE BLE_MESH_RPL_LOG +#define BLE_NPL_LOG_MODULE BLE_MESH_RPL_LOG +#include -#include "log/log.h" #include #include "mesh_priv.h" diff --git a/nimble/host/mesh/src/settings.c b/nimble/host/mesh/src/settings.c index cddf025f92..a3b6ae6dc0 100644 --- a/nimble/host/mesh/src/settings.c +++ b/nimble/host/mesh/src/settings.c @@ -5,7 +5,9 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_SETTINGS_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_SETTINGS_LOG +#include #if MYNEWT_VAL(BLE_MESH_SETTINGS) diff --git a/nimble/host/mesh/src/subnet.c b/nimble/host/mesh/src/subnet.c index 9108cc471f..d8c27c371a 100644 --- a/nimble/host/mesh/src/subnet.c +++ b/nimble/host/mesh/src/subnet.c @@ -6,9 +6,9 @@ */ #include #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_NET_KEYS_LOG -#include "log/log.h" +#define BLE_NPL_LOG_MODULE BLE_MESH_NET_KEYS_LOG +#include #include "crypto.h" #include "adv.h" diff --git a/nimble/host/mesh/src/transport.c b/nimble/host/mesh/src/transport.c index b3c9d52395..10d4442013 100644 --- a/nimble/host/mesh/src/transport.c +++ b/nimble/host/mesh/src/transport.c @@ -7,7 +7,9 @@ */ #include "syscfg/syscfg.h" -#define MESH_LOG_MODULE BLE_MESH_TRANS_LOG + +#define BLE_NPL_LOG_MODULE BLE_MESH_TRANS_LOG +#include #include #include diff --git a/nimble/host/src/ble_att_cmd.c b/nimble/host/src/ble_att_cmd.c index 34521954e9..4106cd0609 100644 --- a/nimble/host/src/ble_att_cmd.c +++ b/nimble/host/src/ble_att_cmd.c @@ -17,6 +17,10 @@ * under the License. */ +#include +#define BLE_NPL_LOG_MODULE BLE_EATT_LOG +#include + #include #include #include "os/os.h" diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c index ff2b580238..de1c0d7153 100644 --- a/nimble/host/src/ble_eatt.c +++ b/nimble/host/src/ble_eatt.c @@ -18,6 +18,8 @@ */ #include "syscfg/syscfg.h" +#define BLE_NPL_LOG_MODULE BLE_EATT_LOG +#include #if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0 diff --git a/nimble/host/src/ble_hs_log.c b/nimble/host/src/ble_hs_log.c index 0670dca6ee..01f1ea641b 100644 --- a/nimble/host/src/ble_hs_log.c +++ b/nimble/host/src/ble_hs_log.c @@ -21,8 +21,6 @@ #include "host/ble_hs.h" #include "host/ble_hs_log.h" -struct log ble_hs_log; - void ble_hs_log_mbuf(const struct os_mbuf *om) { diff --git a/nimble/include/nimble/nimble_npl_log.h b/nimble/include/nimble/nimble_npl_log.h new file mode 100644 index 0000000000..1b49054aa5 --- /dev/null +++ b/nimble/include/nimble/nimble_npl_log.h @@ -0,0 +1,57 @@ +/* + * 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 _NIMBLE_NPL_LOG_H_ +#define _NIMBLE_NPL_LOG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef BLE_NPL_LOG_MODULE +#error "NPL Logging module not specified" +#endif + +/* helper macros */ +#define _BLE_NPL_LOG_CAT(a, ...) _BLE_NPL_LOG_PRIMITIVE_CAT(a, __VA_ARGS__) +#define _BLE_NPL_LOG_PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__ + +/* used to generate proper log function call (used by stack) */ +#define BLE_NPL_LOG(lvl, ...) _BLE_NPL_LOG_CAT(BLE_NPL_LOG_MODULE, _BLE_NPL_LOG_CAT(_, lvl))(__VA_ARGS__) + +/* Include OS-specific LOG implementation, should provide implementation for + * logging macros used by NiBLE (eg via modlog) or BLE_NPL_LOG_IMPL + * macro implementation that generates required logging functions/macros + */ +#include "nimble/nimble_npl_os_log.h" + +/* generate logging functions for modules, can be macro or function */ +#ifdef BLE_NPL_LOG_IMPL +BLE_NPL_LOG_IMPL(DEBUG); +BLE_NPL_LOG_IMPL(INFO); +BLE_NPL_LOG_IMPL(WARN); +BLE_NPL_LOG_IMPL(ERROR); +BLE_NPL_LOG_IMPL(CRITICAL); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _NIMBLE_NPL_LOG_H_ */ diff --git a/porting/examples/linux/include/logcfg/logcfg.h b/porting/examples/linux/include/logcfg/logcfg.h deleted file mode 100644 index 4fe2ee015b..0000000000 --- a/porting/examples/linux/include/logcfg/logcfg.h +++ /dev/null @@ -1,32 +0,0 @@ -/** - * This file was generated by Apache newt version: 1.11.0-dev - */ - -#ifndef H_MYNEWT_LOGCFG_ -#define H_MYNEWT_LOGCFG_ - -#include "modlog/modlog.h" -#include "log_common/log_common.h" - -#define BLE_EATT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__) -#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__) -#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__) -#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__) -#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__) - -#define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__) -#define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__) -#define BLE_HS_LOG_ERROR(...) MODLOG_ERROR(4, __VA_ARGS__) -#define BLE_HS_LOG_CRITICAL(...) MODLOG_CRITICAL(4, __VA_ARGS__) -#define BLE_HS_LOG_DISABLED(...) MODLOG_DISABLED(4, __VA_ARGS__) - -#define DFLT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define DFLT_LOG_INFO(...) MODLOG_INFO(0, __VA_ARGS__) -#define DFLT_LOG_WARN(...) MODLOG_WARN(0, __VA_ARGS__) -#define DFLT_LOG_ERROR(...) MODLOG_ERROR(0, __VA_ARGS__) -#define DFLT_LOG_CRITICAL(...) MODLOG_CRITICAL(0, __VA_ARGS__) -#define DFLT_LOG_DISABLED(...) MODLOG_DISABLED(0, __VA_ARGS__) - -#endif diff --git a/porting/examples/linux_blemesh/include/logcfg/logcfg.h b/porting/examples/linux_blemesh/include/logcfg/logcfg.h deleted file mode 100644 index 99afa084ff..0000000000 --- a/porting/examples/linux_blemesh/include/logcfg/logcfg.h +++ /dev/null @@ -1,158 +0,0 @@ -/** - * This file was generated by Apache newt version: 1.11.0-dev - */ - -#ifndef H_MYNEWT_LOGCFG_ -#define H_MYNEWT_LOGCFG_ - -#include "modlog/modlog.h" -#include "log_common/log_common.h" - -#define BLE_EATT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__) -#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__) -#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__) -#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__) -#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__) - -#define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__) -#define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__) -#define BLE_HS_LOG_ERROR(...) MODLOG_ERROR(4, __VA_ARGS__) -#define BLE_HS_LOG_CRITICAL(...) MODLOG_CRITICAL(4, __VA_ARGS__) -#define BLE_HS_LOG_DISABLED(...) MODLOG_DISABLED(4, __VA_ARGS__) - -#define BLE_MESH_ACCESS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_ACCESS_LOG_INFO(...) MODLOG_INFO(10, __VA_ARGS__) -#define BLE_MESH_ACCESS_LOG_WARN(...) MODLOG_WARN(10, __VA_ARGS__) -#define BLE_MESH_ACCESS_LOG_ERROR(...) MODLOG_ERROR(10, __VA_ARGS__) -#define BLE_MESH_ACCESS_LOG_CRITICAL(...) MODLOG_CRITICAL(10, __VA_ARGS__) -#define BLE_MESH_ACCESS_LOG_DISABLED(...) MODLOG_DISABLED(10, __VA_ARGS__) - -#define BLE_MESH_ADV_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_ADV_LOG_INFO(...) MODLOG_INFO(11, __VA_ARGS__) -#define BLE_MESH_ADV_LOG_WARN(...) MODLOG_WARN(11, __VA_ARGS__) -#define BLE_MESH_ADV_LOG_ERROR(...) MODLOG_ERROR(11, __VA_ARGS__) -#define BLE_MESH_ADV_LOG_CRITICAL(...) MODLOG_CRITICAL(11, __VA_ARGS__) -#define BLE_MESH_ADV_LOG_DISABLED(...) MODLOG_DISABLED(11, __VA_ARGS__) - -#define BLE_MESH_BEACON_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_BEACON_LOG_INFO(...) MODLOG_INFO(12, __VA_ARGS__) -#define BLE_MESH_BEACON_LOG_WARN(...) MODLOG_WARN(12, __VA_ARGS__) -#define BLE_MESH_BEACON_LOG_ERROR(...) MODLOG_ERROR(12, __VA_ARGS__) -#define BLE_MESH_BEACON_LOG_CRITICAL(...) MODLOG_CRITICAL(12, __VA_ARGS__) -#define BLE_MESH_BEACON_LOG_DISABLED(...) MODLOG_DISABLED(12, __VA_ARGS__) - -#define BLE_MESH_CRYPTO_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_CRYPTO_LOG_INFO(...) MODLOG_INFO(13, __VA_ARGS__) -#define BLE_MESH_CRYPTO_LOG_WARN(...) MODLOG_WARN(13, __VA_ARGS__) -#define BLE_MESH_CRYPTO_LOG_ERROR(...) MODLOG_ERROR(13, __VA_ARGS__) -#define BLE_MESH_CRYPTO_LOG_CRITICAL(...) MODLOG_CRITICAL(13, __VA_ARGS__) -#define BLE_MESH_CRYPTO_LOG_DISABLED(...) MODLOG_DISABLED(13, __VA_ARGS__) - -#define BLE_MESH_FRIEND_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_FRIEND_LOG_INFO(...) MODLOG_INFO(14, __VA_ARGS__) -#define BLE_MESH_FRIEND_LOG_WARN(...) MODLOG_WARN(14, __VA_ARGS__) -#define BLE_MESH_FRIEND_LOG_ERROR(...) MODLOG_ERROR(14, __VA_ARGS__) -#define BLE_MESH_FRIEND_LOG_CRITICAL(...) MODLOG_CRITICAL(14, __VA_ARGS__) -#define BLE_MESH_FRIEND_LOG_DISABLED(...) MODLOG_DISABLED(14, __VA_ARGS__) - -#define BLE_MESH_HEARTBEAT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_HEARTBEAT_LOG_INFO(...) MODLOG_INFO(26, __VA_ARGS__) -#define BLE_MESH_HEARTBEAT_LOG_WARN(...) MODLOG_WARN(26, __VA_ARGS__) -#define BLE_MESH_HEARTBEAT_LOG_ERROR(...) MODLOG_ERROR(26, __VA_ARGS__) -#define BLE_MESH_HEARTBEAT_LOG_CRITICAL(...) MODLOG_CRITICAL(26, __VA_ARGS__) -#define BLE_MESH_HEARTBEAT_LOG_DISABLED(...) MODLOG_DISABLED(26, __VA_ARGS__) - -#define BLE_MESH_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_LOG_INFO(...) MODLOG_INFO(9, __VA_ARGS__) -#define BLE_MESH_LOG_WARN(...) MODLOG_WARN(9, __VA_ARGS__) -#define BLE_MESH_LOG_ERROR(...) MODLOG_ERROR(9, __VA_ARGS__) -#define BLE_MESH_LOG_CRITICAL(...) MODLOG_CRITICAL(9, __VA_ARGS__) -#define BLE_MESH_LOG_DISABLED(...) MODLOG_DISABLED(9, __VA_ARGS__) - -#define BLE_MESH_LOW_POWER_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_LOW_POWER_LOG_INFO(...) MODLOG_INFO(15, __VA_ARGS__) -#define BLE_MESH_LOW_POWER_LOG_WARN(...) MODLOG_WARN(15, __VA_ARGS__) -#define BLE_MESH_LOW_POWER_LOG_ERROR(...) MODLOG_ERROR(15, __VA_ARGS__) -#define BLE_MESH_LOW_POWER_LOG_CRITICAL(...) MODLOG_CRITICAL(15, __VA_ARGS__) -#define BLE_MESH_LOW_POWER_LOG_DISABLED(...) MODLOG_DISABLED(15, __VA_ARGS__) - -#define BLE_MESH_MODEL_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_MODEL_LOG_INFO(...) MODLOG_INFO(16, __VA_ARGS__) -#define BLE_MESH_MODEL_LOG_WARN(...) MODLOG_WARN(16, __VA_ARGS__) -#define BLE_MESH_MODEL_LOG_ERROR(...) MODLOG_ERROR(16, __VA_ARGS__) -#define BLE_MESH_MODEL_LOG_CRITICAL(...) MODLOG_CRITICAL(16, __VA_ARGS__) -#define BLE_MESH_MODEL_LOG_DISABLED(...) MODLOG_DISABLED(16, __VA_ARGS__) - -#define BLE_MESH_NET_KEYS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_NET_KEYS_LOG_INFO(...) MODLOG_INFO(23, __VA_ARGS__) -#define BLE_MESH_NET_KEYS_LOG_WARN(...) MODLOG_WARN(23, __VA_ARGS__) -#define BLE_MESH_NET_KEYS_LOG_ERROR(...) MODLOG_ERROR(23, __VA_ARGS__) -#define BLE_MESH_NET_KEYS_LOG_CRITICAL(...) MODLOG_CRITICAL(23, __VA_ARGS__) -#define BLE_MESH_NET_KEYS_LOG_DISABLED(...) MODLOG_DISABLED(23, __VA_ARGS__) - -#define BLE_MESH_NET_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_NET_LOG_INFO(...) MODLOG_INFO(17, __VA_ARGS__) -#define BLE_MESH_NET_LOG_WARN(...) MODLOG_WARN(17, __VA_ARGS__) -#define BLE_MESH_NET_LOG_ERROR(...) MODLOG_ERROR(17, __VA_ARGS__) -#define BLE_MESH_NET_LOG_CRITICAL(...) MODLOG_CRITICAL(17, __VA_ARGS__) -#define BLE_MESH_NET_LOG_DISABLED(...) MODLOG_DISABLED(17, __VA_ARGS__) - -#define BLE_MESH_PROVISIONER_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_PROVISIONER_LOG_INFO(...) MODLOG_INFO(25, __VA_ARGS__) -#define BLE_MESH_PROVISIONER_LOG_WARN(...) MODLOG_WARN(25, __VA_ARGS__) -#define BLE_MESH_PROVISIONER_LOG_ERROR(...) MODLOG_ERROR(25, __VA_ARGS__) -#define BLE_MESH_PROVISIONER_LOG_CRITICAL(...) MODLOG_CRITICAL(25, __VA_ARGS__) -#define BLE_MESH_PROVISIONER_LOG_DISABLED(...) MODLOG_DISABLED(25, __VA_ARGS__) - -#define BLE_MESH_PROV_DEVICE_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_PROV_DEVICE_LOG_INFO(...) MODLOG_INFO(24, __VA_ARGS__) -#define BLE_MESH_PROV_DEVICE_LOG_WARN(...) MODLOG_WARN(24, __VA_ARGS__) -#define BLE_MESH_PROV_DEVICE_LOG_ERROR(...) MODLOG_ERROR(24, __VA_ARGS__) -#define BLE_MESH_PROV_DEVICE_LOG_CRITICAL(...) MODLOG_CRITICAL(24, __VA_ARGS__) -#define BLE_MESH_PROV_DEVICE_LOG_DISABLED(...) MODLOG_DISABLED(24, __VA_ARGS__) - -#define BLE_MESH_PROV_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_PROV_LOG_INFO(...) MODLOG_INFO(18, __VA_ARGS__) -#define BLE_MESH_PROV_LOG_WARN(...) MODLOG_WARN(18, __VA_ARGS__) -#define BLE_MESH_PROV_LOG_ERROR(...) MODLOG_ERROR(18, __VA_ARGS__) -#define BLE_MESH_PROV_LOG_CRITICAL(...) MODLOG_CRITICAL(18, __VA_ARGS__) -#define BLE_MESH_PROV_LOG_DISABLED(...) MODLOG_DISABLED(18, __VA_ARGS__) - -#define BLE_MESH_PROXY_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_PROXY_LOG_INFO(...) MODLOG_INFO(19, __VA_ARGS__) -#define BLE_MESH_PROXY_LOG_WARN(...) MODLOG_WARN(19, __VA_ARGS__) -#define BLE_MESH_PROXY_LOG_ERROR(...) MODLOG_ERROR(19, __VA_ARGS__) -#define BLE_MESH_PROXY_LOG_CRITICAL(...) MODLOG_CRITICAL(19, __VA_ARGS__) -#define BLE_MESH_PROXY_LOG_DISABLED(...) MODLOG_DISABLED(19, __VA_ARGS__) - -#define BLE_MESH_RPL_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_RPL_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__) -#define BLE_MESH_RPL_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__) -#define BLE_MESH_RPL_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__) -#define BLE_MESH_RPL_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__) -#define BLE_MESH_RPL_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__) - -#define BLE_MESH_SETTINGS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_SETTINGS_LOG_INFO(...) MODLOG_INFO(20, __VA_ARGS__) -#define BLE_MESH_SETTINGS_LOG_WARN(...) MODLOG_WARN(20, __VA_ARGS__) -#define BLE_MESH_SETTINGS_LOG_ERROR(...) MODLOG_ERROR(20, __VA_ARGS__) -#define BLE_MESH_SETTINGS_LOG_CRITICAL(...) MODLOG_CRITICAL(20, __VA_ARGS__) -#define BLE_MESH_SETTINGS_LOG_DISABLED(...) MODLOG_DISABLED(20, __VA_ARGS__) - -#define BLE_MESH_TRANS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_MESH_TRANS_LOG_INFO(...) MODLOG_INFO(21, __VA_ARGS__) -#define BLE_MESH_TRANS_LOG_WARN(...) MODLOG_WARN(21, __VA_ARGS__) -#define BLE_MESH_TRANS_LOG_ERROR(...) MODLOG_ERROR(21, __VA_ARGS__) -#define BLE_MESH_TRANS_LOG_CRITICAL(...) MODLOG_CRITICAL(21, __VA_ARGS__) -#define BLE_MESH_TRANS_LOG_DISABLED(...) MODLOG_DISABLED(21, __VA_ARGS__) - -#define DFLT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define DFLT_LOG_INFO(...) MODLOG_INFO(0, __VA_ARGS__) -#define DFLT_LOG_WARN(...) MODLOG_WARN(0, __VA_ARGS__) -#define DFLT_LOG_ERROR(...) MODLOG_ERROR(0, __VA_ARGS__) -#define DFLT_LOG_CRITICAL(...) MODLOG_CRITICAL(0, __VA_ARGS__) -#define DFLT_LOG_DISABLED(...) MODLOG_DISABLED(0, __VA_ARGS__) - -#endif diff --git a/porting/examples/nuttx/include/logcfg/logcfg.h b/porting/examples/nuttx/include/logcfg/logcfg.h deleted file mode 100644 index 89af353092..0000000000 --- a/porting/examples/nuttx/include/logcfg/logcfg.h +++ /dev/null @@ -1,25 +0,0 @@ -/** - * This file was generated by Apache newt version: 1.11.0-dev - */ - -#ifndef H_MYNEWT_LOGCFG_ -#define H_MYNEWT_LOGCFG_ - -#include "modlog/modlog.h" -#include "log_common/log_common.h" - -#define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__) -#define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__) -#define BLE_HS_LOG_ERROR(...) MODLOG_ERROR(4, __VA_ARGS__) -#define BLE_HS_LOG_CRITICAL(...) MODLOG_CRITICAL(4, __VA_ARGS__) -#define BLE_HS_LOG_DISABLED(...) MODLOG_DISABLED(4, __VA_ARGS__) - -#define DFLT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define DFLT_LOG_INFO(...) MODLOG_INFO(0, __VA_ARGS__) -#define DFLT_LOG_WARN(...) MODLOG_WARN(0, __VA_ARGS__) -#define DFLT_LOG_ERROR(...) MODLOG_ERROR(0, __VA_ARGS__) -#define DFLT_LOG_CRITICAL(...) MODLOG_CRITICAL(0, __VA_ARGS__) -#define DFLT_LOG_DISABLED(...) MODLOG_DISABLED(0, __VA_ARGS__) - -#endif diff --git a/porting/nimble/include/log_common/ignore.h b/porting/nimble/include/log_common/ignore.h deleted file mode 100644 index 46282a0298..0000000000 --- a/porting/nimble/include/log_common/ignore.h +++ /dev/null @@ -1,64 +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_IGNORE_ -#define H_IGNORE_ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * These macros prevent the "set but not used" warnings for log writes below - * the log level. - */ - -#define IGN_1(X) ((void)(X)) -#define IGN_2(X, ...) ((void)(X));IGN_1(__VA_ARGS__) -#define IGN_3(X, ...) ((void)(X));IGN_2(__VA_ARGS__) -#define IGN_4(X, ...) ((void)(X));IGN_3(__VA_ARGS__) -#define IGN_5(X, ...) ((void)(X));IGN_4(__VA_ARGS__) -#define IGN_6(X, ...) ((void)(X));IGN_5(__VA_ARGS__) -#define IGN_7(X, ...) ((void)(X));IGN_6(__VA_ARGS__) -#define IGN_8(X, ...) ((void)(X));IGN_7(__VA_ARGS__) -#define IGN_9(X, ...) ((void)(X));IGN_8(__VA_ARGS__) -#define IGN_10(X, ...) ((void)(X));IGN_9(__VA_ARGS__) -#define IGN_11(X, ...) ((void)(X));IGN_10(__VA_ARGS__) -#define IGN_12(X, ...) ((void)(X));IGN_11(__VA_ARGS__) -#define IGN_13(X, ...) ((void)(X));IGN_12(__VA_ARGS__) -#define IGN_14(X, ...) ((void)(X));IGN_13(__VA_ARGS__) -#define IGN_15(X, ...) ((void)(X));IGN_14(__VA_ARGS__) -#define IGN_16(X, ...) ((void)(X));IGN_15(__VA_ARGS__) -#define IGN_17(X, ...) ((void)(X));IGN_16(__VA_ARGS__) -#define IGN_18(X, ...) ((void)(X));IGN_17(__VA_ARGS__) -#define IGN_19(X, ...) ((void)(X));IGN_18(__VA_ARGS__) -#define IGN_20(X, ...) ((void)(X));IGN_19(__VA_ARGS__) - -#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, \ - _13, _14, _15, _16, _17, _18, _19, _20, NAME, ...) NAME -#define IGNORE(...) \ - GET_MACRO(__VA_ARGS__, IGN_20, IGN_19, IGN_18, IGN_17, IGN_16, IGN_15, \ - IGN_14, IGN_13, IGN_12, IGN_11, IGN_10, IGN_9, IGN_8, IGN_7, \ - IGN_6, IGN_5, IGN_4, IGN_3, IGN_2, IGN_1)(__VA_ARGS__) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/porting/nimble/include/log_common/log_common.h b/porting/nimble/include/log_common/log_common.h deleted file mode 100644 index ed590b6b0a..0000000000 --- a/porting/nimble/include/log_common/log_common.h +++ /dev/null @@ -1,144 +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_LOG_COMMON_ -#define H_LOG_COMMON_ - -#include -#include "log_common/ignore.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct log; - -#define LOG_VERSION_V3 3 - -#define LOG_TYPE_STREAM (0) -#define LOG_TYPE_MEMORY (1) -#define LOG_TYPE_STORAGE (2) - -#define LOG_LEVEL_DEBUG (0) -#define LOG_LEVEL_INFO (1) -#define LOG_LEVEL_WARN (2) -#define LOG_LEVEL_ERROR (3) -#define LOG_LEVEL_CRITICAL (4) -/* Up to 10 custom log levels. */ -#define LOG_LEVEL_MAX (15) - -#define LOG_LEVEL_STR(level) \ - (LOG_LEVEL_DEBUG == level ? "DEBUG" :\ - (LOG_LEVEL_INFO == level ? "INFO" :\ - (LOG_LEVEL_WARN == level ? "WARN" :\ - (LOG_LEVEL_ERROR == level ? "ERROR" :\ - (LOG_LEVEL_CRITICAL == level ? "CRITICAL" :\ - "UNKNOWN"))))) - -/* XXX: These module IDs are defined for backwards compatibility. Application - * code should use the syscfg settings directly. These defines will be removed - * in a future release. - */ -#define LOG_MODULE_DEFAULT 0 -#define LOG_MODULE_OS 1 -#define LOG_MODULE_NEWTMGR 2 -#define LOG_MODULE_NIMBLE_CTLR 3 -#define LOG_MODULE_NIMBLE_HOST 4 -#define LOG_MODULE_NFFS 5 -#define LOG_MODULE_REBOOT 6 -#define LOG_MODULE_IOTIVITY 7 -#define LOG_MODULE_TEST 8 - -#define LOG_MODULE_PERUSER 64 -#define LOG_MODULE_MAX (255) - -#define LOG_ETYPE_STRING (0) -#define LOG_ETYPE_CBOR (1) -#define LOG_ETYPE_BINARY (2) - -/* UTC Timestamp for Jan 2016 00:00:00 */ -#define UTC01_01_2016 1451606400 - -#define LOG_NAME_MAX_LEN (64) - -#ifndef MYNEWT_VAL_LOG_LEVEL -#define LOG_SYSLEVEL ((uint8_t)LOG_LEVEL_MAX) -#else -#define LOG_SYSLEVEL ((uint8_t)MYNEWT_VAL_LOG_LEVEL) -#endif - -/** - * @brief Determines if a log module will accept an entry with a given level. - * - * A log entry is only accepted if its level is less than or equal to both: - * o Global log level setting (LOG_LEVEL), and - * o The specified module log level - * - * @param mod_level The module's minimum log level. - * @param entry_level The level of the entry to be logged. - * - * @return true if the entry would be logged; - * false otherwise. - */ -#define LOG_MOD_LEVEL_IS_ACTIVE(mod_level, entry_level) \ - (LOG_LEVEL <= (entry_level) && (mod_level) <= (entry_level)) - -/* Newtmgr Log opcodes */ -#define LOGS_NMGR_OP_READ (0) -#define LOGS_NMGR_OP_CLEAR (1) -#define LOGS_NMGR_OP_APPEND (2) -#define LOGS_NMGR_OP_MODULE_LIST (3) -#define LOGS_NMGR_OP_LEVEL_LIST (4) -#define LOGS_NMGR_OP_LOGS_LIST (5) -#define LOGS_NMGR_OP_SET_WATERMARK (6) -#define LOGS_NMGR_OP_MODLEVEL (8) - -#define LOG_PRINTF_MAX_ENTRY_LEN (128) - -/* Global log info */ -struct log_info { -#if MYNEWT_VAL(LOG_GLOBAL_IDX) - uint32_t li_next_index; -#endif - uint8_t li_version; -}; - -extern struct log_info g_log_info; - -/** @typedef log_append_cb - * @brief Callback that is executed each time the corresponding log is appended - * to. - * - * @param log The log that was just appended to. - * @param idx The index of newly appended log entry. - */ -typedef void log_append_cb(struct log *log, uint32_t idx); - -/** @typdef log_notify_rotate_cb - * @brief Callback that is executed each time we are about to rotate a log. - * - * @param log The log that is about to rotate - */ -typedef void log_notify_rotate_cb(const struct log *log); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/porting/nimble/include/logcfg/logcfg.h b/porting/nimble/include/logcfg/logcfg.h deleted file mode 100644 index 4fe2ee015b..0000000000 --- a/porting/nimble/include/logcfg/logcfg.h +++ /dev/null @@ -1,32 +0,0 @@ -/** - * This file was generated by Apache newt version: 1.11.0-dev - */ - -#ifndef H_MYNEWT_LOGCFG_ -#define H_MYNEWT_LOGCFG_ - -#include "modlog/modlog.h" -#include "log_common/log_common.h" - -#define BLE_EATT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__) -#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__) -#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__) -#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__) -#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__) - -#define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__) -#define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__) -#define BLE_HS_LOG_ERROR(...) MODLOG_ERROR(4, __VA_ARGS__) -#define BLE_HS_LOG_CRITICAL(...) MODLOG_CRITICAL(4, __VA_ARGS__) -#define BLE_HS_LOG_DISABLED(...) MODLOG_DISABLED(4, __VA_ARGS__) - -#define DFLT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define DFLT_LOG_INFO(...) MODLOG_INFO(0, __VA_ARGS__) -#define DFLT_LOG_WARN(...) MODLOG_WARN(0, __VA_ARGS__) -#define DFLT_LOG_ERROR(...) MODLOG_ERROR(0, __VA_ARGS__) -#define DFLT_LOG_CRITICAL(...) MODLOG_CRITICAL(0, __VA_ARGS__) -#define DFLT_LOG_DISABLED(...) MODLOG_DISABLED(0, __VA_ARGS__) - -#endif diff --git a/porting/nimble/include/modlog/modlog.h b/porting/nimble/include/modlog/modlog.h deleted file mode 100644 index 0390461069..0000000000 --- a/porting/nimble/include/modlog/modlog.h +++ /dev/null @@ -1,68 +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_MODLOG_ -#define H_MODLOG_ - -#include - -#include "log_common/log_common.h" -#include "log/log.h" - -#define MODLOG_MODULE_DFLT 255 - -#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_DEBUG || defined __DOXYGEN__ -#define MODLOG_DEBUG(ml_mod_, ml_msg_, ...) \ - printf((ml_msg_), ##__VA_ARGS__) -#else -#define MODLOG_DEBUG(ml_mod_, ...) IGNORE(__VA_ARGS__) -#endif - -#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_INFO || defined __DOXYGEN__ -#define MODLOG_INFO(ml_mod_, ml_msg_, ...) \ - printf((ml_msg_), ##__VA_ARGS__) -#else -#define MODLOG_INFO(ml_mod_, ...) IGNORE(__VA_ARGS__) -#endif - -#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_WARN || defined __DOXYGEN__ -#define MODLOG_WARN(ml_mod_, ml_msg_, ...) \ - printf((ml_msg_), ##__VA_ARGS__) -#else -#define MODLOG_WARN(ml_mod_, ...) IGNORE(__VA_ARGS__) -#endif - -#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_ERROR || defined __DOXYGEN__ -#define MODLOG_ERROR(ml_mod_, ml_msg_, ...) \ - printf((ml_msg_), ##__VA_ARGS__) -#else -#define MODLOG_ERROR(ml_mod_, ...) IGNORE(__VA_ARGS__) -#endif - -#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_CRITICAL || defined __DOXYGEN__ -#define MODLOG_CRITICAL(ml_mod_, ml_msg_, ...) \ - printf((ml_msg_), ##__VA_ARGS__) -#else -#define MODLOG_CRITICAL(ml_mod_, ...) IGNORE(__VA_ARGS__) -#endif - -#define MODLOG(ml_lvl_, ml_mod_, ...) \ - MODLOG_ ## ml_lvl_((ml_mod_), __VA_ARGS__) - -#endif diff --git a/porting/npl/dummy/include/nimble/nimble_npl_os_log.h b/porting/npl/dummy/include/nimble/nimble_npl_os_log.h new file mode 100644 index 0000000000..7391c7435a --- /dev/null +++ b/porting/npl/dummy/include/nimble/nimble_npl_os_log.h @@ -0,0 +1,27 @@ +/* + * 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 _NIMBLE_NPL_OS_LOG_H_ +#define _NIMBLE_NPL_OS_LOG_H_ + +#define BLE_NPL_LOG_IMPL(lvl) \ + static inline void _BLE_NPL_LOG_CAT(BLE_NPL_LOG_MODULE, \ + _BLE_NPL_LOG_CAT(_, lvl))(const char *fmt, ...) { } + +#endif /* _NIMBLE_NPL_OS_LOG_H_ */ diff --git a/porting/npl/freertos/include/nimble/nimble_npl_os_log.h b/porting/npl/freertos/include/nimble/nimble_npl_os_log.h new file mode 100644 index 0000000000..5fcce6aeec --- /dev/null +++ b/porting/npl/freertos/include/nimble/nimble_npl_os_log.h @@ -0,0 +1,36 @@ +/* + * 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 _NIMBLE_NPL_OS_LOG_H_ +#define _NIMBLE_NPL_OS_LOG_H_ + +#include + +/* Example on how to use macro to generate module logging functions */ +#define BLE_NPL_LOG_IMPL(lvl) \ + static inline void _BLE_NPL_LOG_CAT(BLE_NPL_LOG_MODULE, \ + _BLE_NPL_LOG_CAT(_, lvl))(const char *fmt, ...)\ + { \ + va_list args; \ + va_start(args, fmt); \ + vprintf(fmt, args); \ + va_end(args); \ + } + +#endif /* _NIMBLE_NPL_OS_LOG_H_ */ diff --git a/porting/npl/linux/include/nimble/nimble_npl_os_log.h b/porting/npl/linux/include/nimble/nimble_npl_os_log.h new file mode 100644 index 0000000000..24315a21a7 --- /dev/null +++ b/porting/npl/linux/include/nimble/nimble_npl_os_log.h @@ -0,0 +1,37 @@ +/* + * 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 _NIMBLE_NPL_OS_LOG_H_ +#define _NIMBLE_NPL_OS_LOG_H_ + +#include +#include + +/* Example on how to use macro to generate module logging functions */ +#define BLE_NPL_LOG_IMPL(lvl) \ + static inline void _BLE_NPL_LOG_CAT(BLE_NPL_LOG_MODULE, \ + _BLE_NPL_LOG_CAT(_, lvl))(const char *fmt, ...)\ + { \ + va_list args; \ + va_start(args, fmt); \ + vprintf(fmt, args); \ + va_end(args); \ + } + +#endif /* _NIMBLE_NPL_OS_LOG_H_ */ diff --git a/porting/nimble/include/log/log.h b/porting/npl/mynewt/include/nimble/nimble_npl_os_log.h similarity index 58% rename from porting/nimble/include/log/log.h rename to porting/npl/mynewt/include/nimble/nimble_npl_os_log.h index be9237c524..3ec47344ad 100644 --- a/porting/nimble/include/log/log.h +++ b/porting/npl/mynewt/include/nimble/nimble_npl_os_log.h @@ -17,32 +17,15 @@ * under the License. */ -#ifndef __LOG_H__ -#define __LOG_H__ +#ifndef _NIMBLE_NPL_OS_LOG_H_ +#define _NIMBLE_NPL_OS_LOG_H_ -#ifdef __cplusplus -extern "C" { -#endif - -static inline void -log_dummy(void *log, ...) -{ - (void)log; -} - -#ifdef MYNEWT -#define LOG_DEBUG(_log, _mod, ...) log_dummy(_log, ## __VA_ARGS__) -#define LOG_INFO(_log, _mod, ...) log_dummy(_log, ## __VA_ARGS__) -#define LOG_WARN(_log, _mod, ...) log_dummy(_log, ## __VA_ARGS__) -#define LOG_ERROR(_log, _mod, ...) log_dummy(_log, ## __VA_ARGS__) -#define LOG_CRITICAL(_log, _mod, ...) log_dummy(_log, ## __VA_ARGS__) -#endif - -struct log { -}; +#include +#include -#ifdef __cplusplus -} +/* Only include the logcfg header if this version of newt can generate it. */ +#if MYNEWT_VAL(NEWT_FEATURE_LOGCFG) +#include #endif -#endif /* __LOG_H__ */ +#endif /* _NIMBLE_NPL_OS_LOG_H_ */ diff --git a/porting/npl/nuttx/include/modlog/modlog.h b/porting/npl/nuttx/include/modlog/modlog.h deleted file mode 100644 index 5e51b50102..0000000000 --- a/porting/npl/nuttx/include/modlog/modlog.h +++ /dev/null @@ -1,68 +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_MODLOG_ -#define H_MODLOG_ - -#include -#include - -#include "log_common/log_common.h" - -#define MODLOG_MODULE_DFLT 255 - -#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_DEBUG || defined __DOXYGEN__ -#define MODLOG_DEBUG(ml_mod_, ml_msg_, ...) \ - printf((ml_msg_), ##__VA_ARGS__) -#else -#define MODLOG_DEBUG(ml_mod_, ...) IGNORE(__VA_ARGS__) -#endif - -#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_INFO || defined __DOXYGEN__ -#define MODLOG_INFO(ml_mod_, ml_msg_, ...) \ - printf((ml_msg_), ##__VA_ARGS__) -#else -#define MODLOG_INFO(ml_mod_, ...) IGNORE(__VA_ARGS__) -#endif - -#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_WARN || defined __DOXYGEN__ -#define MODLOG_WARN(ml_mod_, ml_msg_, ...) \ - printf((ml_msg_), ##__VA_ARGS__) -#else -#define MODLOG_WARN(ml_mod_, ...) IGNORE(__VA_ARGS__) -#endif - -#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_ERROR || defined __DOXYGEN__ -#define MODLOG_ERROR(ml_mod_, ml_msg_, ...) \ - printf((ml_msg_), ##__VA_ARGS__) -#else -#define MODLOG_ERROR(ml_mod_, ...) IGNORE(__VA_ARGS__) -#endif - -#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_CRITICAL || defined __DOXYGEN__ -#define MODLOG_CRITICAL(ml_mod_, ml_msg_, ...) \ - printf((ml_msg_), ##__VA_ARGS__) -#else -#define MODLOG_CRITICAL(ml_mod_, ...) IGNORE(__VA_ARGS__) -#endif - -#define MODLOG(ml_lvl_, ml_mod_, ...) \ - MODLOG_ ## ml_lvl_((ml_mod_), __VA_ARGS__) - -#endif diff --git a/porting/npl/nuttx/include/nimble/nimble_npl_os_log.h b/porting/npl/nuttx/include/nimble/nimble_npl_os_log.h new file mode 100644 index 0000000000..5fcce6aeec --- /dev/null +++ b/porting/npl/nuttx/include/nimble/nimble_npl_os_log.h @@ -0,0 +1,36 @@ +/* + * 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 _NIMBLE_NPL_OS_LOG_H_ +#define _NIMBLE_NPL_OS_LOG_H_ + +#include + +/* Example on how to use macro to generate module logging functions */ +#define BLE_NPL_LOG_IMPL(lvl) \ + static inline void _BLE_NPL_LOG_CAT(BLE_NPL_LOG_MODULE, \ + _BLE_NPL_LOG_CAT(_, lvl))(const char *fmt, ...)\ + { \ + va_list args; \ + va_start(args, fmt); \ + vprintf(fmt, args); \ + va_end(args); \ + } + +#endif /* _NIMBLE_NPL_OS_LOG_H_ */ diff --git a/porting/npl/riot/include/logcfg/logcfg.h b/porting/npl/riot/include/logcfg/logcfg.h deleted file mode 100644 index 4fe2ee015b..0000000000 --- a/porting/npl/riot/include/logcfg/logcfg.h +++ /dev/null @@ -1,32 +0,0 @@ -/** - * This file was generated by Apache newt version: 1.11.0-dev - */ - -#ifndef H_MYNEWT_LOGCFG_ -#define H_MYNEWT_LOGCFG_ - -#include "modlog/modlog.h" -#include "log_common/log_common.h" - -#define BLE_EATT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__) -#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__) -#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__) -#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__) -#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__) - -#define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__) -#define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__) -#define BLE_HS_LOG_ERROR(...) MODLOG_ERROR(4, __VA_ARGS__) -#define BLE_HS_LOG_CRITICAL(...) MODLOG_CRITICAL(4, __VA_ARGS__) -#define BLE_HS_LOG_DISABLED(...) MODLOG_DISABLED(4, __VA_ARGS__) - -#define DFLT_LOG_DEBUG(...) IGNORE(__VA_ARGS__) -#define DFLT_LOG_INFO(...) MODLOG_INFO(0, __VA_ARGS__) -#define DFLT_LOG_WARN(...) MODLOG_WARN(0, __VA_ARGS__) -#define DFLT_LOG_ERROR(...) MODLOG_ERROR(0, __VA_ARGS__) -#define DFLT_LOG_CRITICAL(...) MODLOG_CRITICAL(0, __VA_ARGS__) -#define DFLT_LOG_DISABLED(...) MODLOG_DISABLED(0, __VA_ARGS__) - -#endif diff --git a/porting/npl/riot/include/nimble/nimble_npl_os_log.h b/porting/npl/riot/include/nimble/nimble_npl_os_log.h new file mode 100644 index 0000000000..5fcce6aeec --- /dev/null +++ b/porting/npl/riot/include/nimble/nimble_npl_os_log.h @@ -0,0 +1,36 @@ +/* + * 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 _NIMBLE_NPL_OS_LOG_H_ +#define _NIMBLE_NPL_OS_LOG_H_ + +#include + +/* Example on how to use macro to generate module logging functions */ +#define BLE_NPL_LOG_IMPL(lvl) \ + static inline void _BLE_NPL_LOG_CAT(BLE_NPL_LOG_MODULE, \ + _BLE_NPL_LOG_CAT(_, lvl))(const char *fmt, ...)\ + { \ + va_list args; \ + va_start(args, fmt); \ + vprintf(fmt, args); \ + va_end(args); \ + } + +#endif /* _NIMBLE_NPL_OS_LOG_H_ */ From 861877636c77ba215e7de0abbb4c4c7ae4961fab Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 5 Oct 2023 16:14:48 +0200 Subject: [PATCH 0840/1333] apps/bttester: Fix compilation with GCC 13 GCC 13 is complaining about zero elemen array that is not at the end of structure. Error: repos/apache-mynewt-nimble/apps/bttester/src/btp_gap.c: In function 'start_advertising': repos/apache-mynewt-nimble/apps/bttester/src/btp_gap.c:467:29: error: array subscript 514 is outside the bounds of an interior zero-length array 'const uint8_t[0]' {aka 'const unsigned char[]'} [-Werror=zero-length-bounds] 467 | addr_type = cp->adv_data[cp->adv_data_len + | ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~ 468 | cp->scan_rsp_len + | ~~~~~~~~~~~~~~~~~~ 469 | sizeof(duration)]; | ~~~~~~~~~~~~~~~~~ In file included from repos/apache-mynewt-nimble/apps/bttester/src/btp/btp.h:31, from repos/apache-mynewt-nimble/apps/bttester/src/btp_gap.c:36: repos/apache-mynewt-nimble/apps/bttester/src/btp/btp_gap.h:138:13: note: while referencing 'adv_data' 138 | uint8_t adv_data[0]; | ^~~~~~~~ cc1: all warnings being treated as errors --- apps/bttester/src/btp/btp_gap.h | 5 ++--- apps/bttester/src/btp_gap.c | 16 ++++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/apps/bttester/src/btp/btp_gap.h b/apps/bttester/src/btp/btp_gap.h index 65b56818cf..f49173c6dc 100644 --- a/apps/bttester/src/btp/btp_gap.h +++ b/apps/bttester/src/btp/btp_gap.h @@ -135,8 +135,7 @@ struct btp_gap_set_bondable_rp { struct btp_gap_start_advertising_cmd { uint8_t adv_data_len; uint8_t scan_rsp_len; - uint8_t adv_data[0]; - uint8_t scan_rsp[0]; + uint8_t adv_sr_data[]; /* * This command is very unfortunate because it has two fields after variable * data. Those needs to be handled explicitly by handler. @@ -440,4 +439,4 @@ struct gap_periodic_transfer_recieved_ev { uint8_t adv_phy; uint16_t per_adv_itvl; uint8_t adv_clk_accuracy; -} __packed; \ No newline at end of file +} __packed; diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 5d30cbb08d..4af463e1bf 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -462,9 +462,9 @@ start_advertising(const void *cmd, uint16_t cmd_len, } /* currently ignored */ - duration = get_le32(cp->adv_data + cp->adv_data_len + cp->scan_rsp_len); + duration = get_le32(cp->adv_sr_data + cp->adv_data_len + cp->scan_rsp_len); (void)duration; - addr_type = cp->adv_data[cp->adv_data_len + + addr_type = cp->adv_sr_data[cp->adv_data_len + cp->scan_rsp_len + sizeof(duration)]; @@ -474,9 +474,9 @@ start_advertising(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } - ad[adv_len].type = cp->scan_rsp[i++]; - ad[adv_len].data_len = cp->scan_rsp[i++]; - ad[adv_len].data = &cp->scan_rsp[i]; + ad[adv_len].type = cp->adv_sr_data[i++]; + ad[adv_len].data_len = cp->adv_sr_data[i++]; + ad[adv_len].data = &cp->adv_sr_data[i]; i += ad[adv_len].data_len; } @@ -486,9 +486,9 @@ start_advertising(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } - sd[sd_len].type = cp->scan_rsp[i++]; - sd[sd_len].data_len = cp->scan_rsp[i++]; - sd[sd_len].data = &cp->scan_rsp[i]; + sd[sd_len].type = cp->adv_sr_data[i++]; + sd[sd_len].data_len = cp->adv_sr_data[i++]; + sd[sd_len].data = &cp->adv_sr_data[i]; i += sd[sd_len].data_len; } From f2cb1ec98ea60baaafd8f79a2d974555691ad2f2 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Thu, 5 Oct 2023 10:44:23 +0200 Subject: [PATCH 0841/1333] host/sm: Add CSIS SIRK encryption This adds functions and algorithms to encrypt and decrypt SIRK from Coordinated Set Identification Service. This also adds API to resolve RSI. Application can use it to find devices that are part of Coordinated Set. --- nimble/host/include/host/ble_sm.h | 19 +++++ nimble/host/src/ble_sm.c | 103 ++++++++++++++++++++++ nimble/host/src/ble_sm_alg.c | 133 +++++++++++++++++++++++++++++ nimble/host/src/ble_sm_priv.h | 13 +++ nimble/host/syscfg.yml | 5 ++ nimble/host/test/src/ble_sm_test.c | 98 +++++++++++++++++++++ nimble/host/test/syscfg.yml | 1 + 7 files changed, 372 insertions(+) diff --git a/nimble/host/include/host/ble_sm.h b/nimble/host/include/host/ble_sm.h index ff381cf25b..51e745f36c 100644 --- a/nimble/host/include/host/ble_sm.h +++ b/nimble/host/include/host/ble_sm.h @@ -22,6 +22,8 @@ #include #include "syscfg/syscfg.h" +#include +#include "nimble/ble.h" #ifdef __cplusplus extern "C" { @@ -112,6 +114,23 @@ struct ble_sm_io { int ble_sm_sc_oob_generate_data(struct ble_sm_sc_oob_data *oob_data); +#if MYNEWT_VAL(BLE_SM_CSIS_SIRK) +/** + * Resolves CSIS RSI to check if advertising device is part of the same Coordinated Set, + * as the device with specified SIRK + * + * @param rsi RSI value from Advertising Data + * @param sirk SIRK + * @param ltk_peer_addr If SIRK is in plaintext form this should be set to NULL, + * otherwise peer address should be passed here to get + * LTK and decrypt SIRK + * + * @return 0 if RSI was resolved succesfully; nonzero on failure. + */ +int ble_sm_csis_resolve_rsi(const uint8_t *rsi, const uint8_t *sirk, + const ble_addr_t *ltk_peer_addr); +#endif + #if NIMBLE_BLE_SM int ble_sm_inject_io(uint16_t conn_handle, struct ble_sm_io *pkey); #else diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 831cf0fcb2..0b7c28db59 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -2910,4 +2910,107 @@ ble_sm_create_chan(uint16_t conn_handle) return chan; } +#if MYNEWT_VAL(BLE_SM_CSIS_SIRK) +int +ble_sm_csis_decrypt_sirk(const uint8_t *ltk, const uint8_t *enc_sirk, uint8_t *out) +{ + int rc; + + /* Decrypt SIRK with sdf(K, EncSIRK) */ + rc = ble_sm_alg_csis_sdf(ltk, enc_sirk, out); + + return rc; +} + +int +ble_sm_csis_resolve_rsi(const uint8_t *rsi, const uint8_t *sirk, + const ble_addr_t *ltk_peer_addr) +{ + struct ble_store_key_sec key_sec; + struct ble_store_value_sec value_sec; + uint8_t plaintext_sirk[16] = {0}; + uint8_t local_hash[3] = {0}; + uint8_t prand[3] = {0}; + uint8_t hash[3] = {0}; + int rc; + + memcpy(hash, rsi, 3); + memcpy(prand, rsi + 3, 3); + + if (ltk_peer_addr) { + memset(&key_sec, 0, sizeof(key_sec)); + key_sec.peer_addr = *ltk_peer_addr; + + rc = ble_store_read_peer_sec(&key_sec, &value_sec); + if (rc != 0) { + return rc; + } else if (!value_sec.ltk_present) { + return BLE_HS_ENOENT; + } + + rc = ble_sm_csis_decrypt_sirk(value_sec.ltk, sirk, plaintext_sirk); + if (rc != 0) { + return rc; + } + } else { + memcpy(plaintext_sirk, sirk, 16); + } + + rc = ble_sm_alg_csis_sih(plaintext_sirk, prand, local_hash); + if (rc != 0) { + return rc; + } + + if (memcmp(local_hash, hash, 3)) { + return BLE_HS_EAUTHEN; + } + + return 0; +} + +int +ble_sm_csis_encrypt_sirk(const uint8_t *ltk, const uint8_t *plaintext_sirk, uint8_t *out) +{ + int rc; + + /* Encrypt SIRK with sef(K, SIRK) */ + rc = ble_sm_alg_csis_sef(ltk, plaintext_sirk, out); + + return rc; +} + +int +ble_sm_csis_generate_rsi(const uint8_t *sirk, uint8_t *out) +{ + const uint8_t prand_check_all_set[3] = {0xff, 0xff, 0xef}; + const uint8_t prand_check_all_reset[3] = {0x0, 0x0, 0x40}; + uint8_t prand[3] = {0}; + uint8_t hash[3] = {0}; + int rc; + + do { + rc = ble_hs_hci_rand(prand, 3); + if (rc != 0) { + return rc; + } + /* Two MSBs of prand shall be equal to 0 and 1 */ + prand[2] &= ~0xc0; + prand[2] |= 0x40; + + /* prand's random part shall not be all 0s nor all 1s */ + } while (memcmp(prand, prand_check_all_set, 3) || + memcmp(prand, prand_check_all_reset, 3)); + + rc = ble_sm_alg_csis_sih(sirk, prand, hash); + if (rc != 0) { + return rc; + } + + memcpy(out, hash, 3); + memcpy(out + 3, prand, 3); + + return 0; +} + +#endif #endif diff --git a/nimble/host/src/ble_sm_alg.c b/nimble/host/src/ble_sm_alg.c index 282a2b13f6..bf81f21ffb 100644 --- a/nimble/host/src/ble_sm_alg.c +++ b/nimble/host/src/ble_sm_alg.c @@ -418,6 +418,139 @@ ble_sm_alg_g2(const uint8_t *u, const uint8_t *v, const uint8_t *x, return 0; } +int +ble_sm_alg_csis_k1(const uint8_t *n, size_t n_len, const uint8_t *salt, + const uint8_t *p, size_t p_len, uint8_t *out) +{ + int rc; + uint8_t t[16] = {0}; + uint8_t salt_be[16] = {0}; + uint8_t n_be[16] = {0}; + + /* XXX: Spec does not specify the maximum N and P parameters length. + * We assume that 16 bytes is enough and return error if passed len value is greater + * than that */ + if ((n_len > 16) || (p_len > 16)) { + return BLE_HS_EINVAL; + } + + swap_buf(salt_be, salt, 16); + swap_buf(n_be, n, n_len); + + /* T = AES-CMAC_SALT (N) */ + rc = ble_sm_alg_aes_cmac(salt_be, n_be, n_len, t); + if (rc != 0) { + return rc; + } + + /* AES-CMAC_T (P) */ + rc = ble_sm_alg_aes_cmac(t, p, p_len, out); + if (rc != 0) { + return rc; + } + + swap_in_place(out, 16); + + return 0; +} + +int +ble_sm_alg_csis_s1(const uint8_t *m, size_t m_len, uint8_t *out) +{ + int rc; + uint8_t k_zero[16] = {0}; + + /* XXX: Spec does not specify the maximum M parameter length. + * We assume that 16 bytes is enough and return error if passed len value is greater + * than that */ + if (m_len > 16) { + return BLE_HS_EINVAL; + } + + /* AES-CMAC_zero (M) */ + rc = ble_sm_alg_aes_cmac(k_zero, m, m_len, out); + if (rc != 0) { + return rc; + } + + swap_in_place(out, 16); + + return 0; +} + +int +ble_sm_alg_csis_sef(const uint8_t *k, const uint8_t *plaintext_sirk, uint8_t *out) +{ + uint8_t salt[16]; + int rc; + int i; + + /* s1("SIRKenc") */ + rc = ble_sm_alg_csis_s1((const uint8_t *) "SIRKenc", 7, salt); + if (rc != 0) { + return rc; + } + + /* k1(K, s1("SIRKenc"), "csis") */ + rc = ble_sm_alg_csis_k1(k, 16, salt, (const uint8_t *) "csis", 4, out); + if (rc != 0) { + return rc; + } + + /* k1(K, s1("SIRKenc"), "csis") ^ SIRK */ + for (i = 0; i < 16; i++) { + out[i] ^= plaintext_sirk[i]; + } + + return 0; +} + +int +ble_sm_alg_csis_sdf(const uint8_t *k, const uint8_t *enc_sirk, uint8_t *out) +{ + uint8_t salt[16]; + int rc; + int i; + + /* s1("SIRKenc") */ + rc = ble_sm_alg_csis_s1((const uint8_t *) "SIRKenc", 7, salt); + if (rc != 0) { + return rc; + } + + /* k1(K, s1("SIRKenc"), "csis") */ + rc = ble_sm_alg_csis_k1(k, 16, salt, (const uint8_t *) "csis", 4, out); + if (rc != 0) { + return rc; + } + + /* k1(K, s1("SIRKenc"), "csis") ^ EncSIRK */ + for (i = 0; i < 16; i++) { + out[i] ^= enc_sirk[i]; + } + + return 0; +} + +int +ble_sm_alg_csis_sih(const uint8_t *k, const uint8_t *r, uint8_t *out) +{ + uint8_t r1[16]; + int rc; + + memcpy(r1, r, 3); + memset(r1 + 3, 0, 13); + + rc = ble_sm_alg_encrypt(k, r1, r1); + if (rc != 0) { + return rc; + } + + memcpy(out, r1, 3); + + return 0; +} + int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey) diff --git a/nimble/host/src/ble_sm_priv.h b/nimble/host/src/ble_sm_priv.h index 5e761c1e1a..d8e1f0358e 100644 --- a/nimble/host/src/ble_sm_priv.h +++ b/nimble/host/src/ble_sm_priv.h @@ -314,12 +314,25 @@ int ble_sm_alg_f6(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, const uint8_t *r, const uint8_t *iocap, uint8_t a1t, const uint8_t *a1, uint8_t a2t, const uint8_t *a2, uint8_t *check); +int ble_sm_alg_csis_k1(const uint8_t *n, size_t n_len, const uint8_t *salt, + const uint8_t *p, size_t p_len, uint8_t *out); +int ble_sm_alg_csis_s1(const uint8_t *m, size_t m_len, uint8_t *out); +int ble_sm_alg_csis_sef(const uint8_t *k, const uint8_t *plaintext_sirk, + uint8_t *out); +int ble_sm_alg_csis_sdf(const uint8_t *k, const uint8_t *enc_sirk, + uint8_t *out); +int ble_sm_alg_csis_sih(const uint8_t *k, const uint8_t *r, uint8_t *out); int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv); void ble_sm_alg_ecc_init(void); +int ble_sm_csis_generate_rsi(const uint8_t *sirk, uint8_t *out); +int ble_sm_csis_encrypt_sirk(const uint8_t *ltk, const uint8_t *plaintext_sirk, + uint8_t *out); +int ble_sm_csis_decrypt_sirk(const uint8_t *ltk, const uint8_t *enc_sirk, uint8_t *out); + void ble_sm_enc_change_rx(const struct ble_hci_ev_enrypt_chg *ev); void ble_sm_enc_key_refresh_rx(const struct ble_hci_ev_enc_key_refresh *ev); int ble_sm_ltk_req_rx(const struct ble_hci_ev_le_subev_lt_key_req *ev); diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index 8218b9e769..f667eee985 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -188,6 +188,11 @@ syscfg.defs: allows to decrypt air traffic easily and thus should be only used for debugging. value: 0 + BLE_SM_CSIS_SIRK: + description: > + Enable LE Audio CSIS SIRK Encryption and Decryption API. + value: 0 + experimental: 1 # GAP options. BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE: diff --git a/nimble/host/test/src/ble_sm_test.c b/nimble/host/test/src/ble_sm_test.c index be4285fdce..2ba1678d7b 100644 --- a/nimble/host/test/src/ble_sm_test.c +++ b/nimble/host/test/src/ble_sm_test.c @@ -142,6 +142,99 @@ TEST_CASE_SELF(ble_sm_test_case_g2) ble_hs_test_util_assert_mbufs_freed(NULL); } +TEST_CASE_SELF(ble_sm_test_case_csis_sih) +{ + uint8_t sirk[16] = { 0xcd, 0xcc, 0x72, 0xdd, 0x86, 0x8c, 0xcd, 0xce, + 0x22, 0xfd, 0xa1, 0x21, 0x09, 0x7d, 0x7d, 0x45 }; + uint8_t prand[3] = { 0x63, 0xf5, 0x69 }; + const uint8_t ah_expected[3] = { 0xda, 0x48, 0x19 }; + uint8_t ah_out[3]; + int err; + + err = ble_sm_alg_csis_sih(sirk, prand, ah_out); + TEST_ASSERT_FATAL(err == 0); + TEST_ASSERT(memcmp(ah_out, ah_expected, 3) == 0); + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + +TEST_CASE_SELF(ble_sm_test_case_csis_sef) +{ + uint8_t sirk[16] = { 0xcd, 0xcc, 0x72, 0xdd, 0x86, 0x8c, 0xcd, 0xce, + 0x22, 0xfd, 0xa1, 0x21, 0x09, 0x7d, 0x7d, 0x45 }; + uint8_t k[16] = { 0xd9, 0xce, 0xe5, 0x3c, 0x22, 0xc6, 0x1e, 0x06, + 0x6f, 0x69, 0x48, 0xd4, 0x9b, 0x1b, 0x6e, 0x67 }; + const uint8_t sef_expected[16] = { 0x46, 0xd3, 0x5f, 0xf2, 0xd5, 0x62, 0x25, 0x7e, + 0xa0, 0x24, 0x35, 0xe1, 0x35, 0x38, 0x0a, 0x17 }; + uint8_t sef_out[16]; + int err; + + err = ble_sm_alg_csis_sef(k, sirk, sef_out); + TEST_ASSERT_FATAL(err == 0); + TEST_ASSERT(memcmp(sef_out, sef_expected, 16) == 0); + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + +TEST_CASE_SELF(ble_sm_test_case_csis_s1_sirkenc) +{ + const uint8_t s1_expected[16] = { 0x72, 0x45, 0x77, 0x7d, 0x3a, 0x13, 0x7d, 0x3c, + 0x82, 0x9e, 0x14, 0x18, 0x3f, 0x98, 0x01, 0x69 }; + uint8_t s1_out[16]; + int err; + + err = ble_sm_alg_csis_s1((const uint8_t *) "SIRKenc", 7, s1_out); + + TEST_ASSERT_FATAL(err == 0); + TEST_ASSERT(memcmp(s1_out, s1_expected, 16) == 0); + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + +TEST_CASE_SELF(ble_sm_test_case_csis_k1_csis) +{ + uint8_t k[16] = { 0xd9, 0xce, 0xe5, 0x3c, 0x22, 0xc6, 0x1e, 0x06, + 0x6f, 0x69, 0x48, 0xd4, 0x9b, 0x1b, 0x6e, 0x67 }; + uint8_t k1_expected[16] = { 0x8b, 0x1f, 0x2d, 0x2f, 0x53, 0xee, 0xe8, 0xb0, + 0x82, 0xd9, 0x94, 0xc0, 0x3c, 0x45, 0x77, 0x52 }; + uint8_t k1_out[16]; + uint8_t s1_out[16]; + int err; + + err = ble_sm_alg_csis_s1((const uint8_t *) "SIRKenc", 7, s1_out); + TEST_ASSERT_FATAL(err == 0); + + err = ble_sm_alg_csis_k1(k, 16, s1_out, (const uint8_t *) "csis", 4, k1_out); + + TEST_ASSERT_FATAL(err == 0); + TEST_ASSERT(memcmp(k1_out, k1_expected, 16) == 0); + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + +TEST_CASE_SELF(ble_sm_test_case_csis_enc_dec_sirk) +{ + uint8_t plaintext_sirk[16] = { 0xcd, 0xcc, 0x72, 0xdd, 0x86, 0x8c, 0xcd, 0xce, + 0x22, 0xfd, 0xa1, 0x21, 0x09, 0x7d, 0x7d, 0x45 }; + uint8_t k[16] = { 0xd9, 0xce, 0xe5, 0x3c, 0x22, 0xc6, 0x1e, 0x06, + 0x6f, 0x69, 0x48, 0xd4, 0x9b, 0x1b, 0x6e, 0x67 }; + uint8_t enc_sirk[16] = {0}; + uint8_t dec_sirk[16] = {0}; + uint8_t rsi[6] = {0x0, 0x0, 0x0, 0xab, 0x34, 0xef}; + int err; + + /* Generate only hash part of rsi, as random part is already hard-coded */ + err = ble_sm_alg_csis_sih(plaintext_sirk, rsi + 3, rsi); + TEST_ASSERT_FATAL(err == 0); + + ble_sm_csis_encrypt_sirk(k, plaintext_sirk, enc_sirk); + TEST_ASSERT_FATAL(err == 0); + + ble_sm_csis_decrypt_sirk(k, enc_sirk, dec_sirk); + TEST_ASSERT_FATAL(err == 0); + TEST_ASSERT(memcmp(dec_sirk, plaintext_sirk, 16) == 0); +} + TEST_CASE_SELF(ble_sm_test_case_conn_broken) { struct ble_hci_ev_disconn_cmp disconn_evt; @@ -403,6 +496,11 @@ TEST_SUITE(ble_sm_gen_test_suite) ble_sm_test_case_f5(); ble_sm_test_case_f6(); ble_sm_test_case_g2(); + ble_sm_test_case_csis_sih(); + ble_sm_test_case_csis_sef(); + ble_sm_test_case_csis_s1_sirkenc(); + ble_sm_test_case_csis_k1_csis(); + ble_sm_test_case_csis_enc_dec_sirk(); ble_sm_test_case_peer_fail_inval(); ble_sm_test_case_peer_lgcy_fail_confirm(); diff --git a/nimble/host/test/syscfg.yml b/nimble/host/test/syscfg.yml index cfb3a8178c..dfafb8e76b 100644 --- a/nimble/host/test/syscfg.yml +++ b/nimble/host/test/syscfg.yml @@ -24,6 +24,7 @@ syscfg.vals: BLE_GATT_MAX_PROCS: 16 BLE_SM: 1 BLE_SM_SC: 1 + BLE_SM_CSIS_SIRK: 1 MSYS_1_BLOCK_COUNT: 100 BLE_L2CAP_COC_MAX_NUM: 2 CONFIG_FCB: 1 From bf3f950369e554b3fb69e0973ef88c5bfdf09d3c Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Fri, 28 Apr 2023 14:34:30 +0530 Subject: [PATCH 0842/1333] nimble/host: Add support to send power control event in registered callback --- nimble/host/src/ble_gap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index a391675546..7922c52432 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -1721,27 +1721,30 @@ void ble_gap_rx_le_pathloss_threshold(const struct ble_hci_ev_le_subev_path_loss_threshold *ev) { struct ble_gap_event event; + uint16_t conn_handle = le16toh(ev->conn_handle); memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_PATHLOSS_THRESHOLD; - event.pathloss_threshold.conn_handle = le16toh(ev->conn_handle); + event.pathloss_threshold.conn_handle = conn_handle; event.pathloss_threshold.current_path_loss = ev->current_path_loss; event.pathloss_threshold.zone_entered = ev->zone_entered; ble_gap_event_listener_call(&event); + ble_gap_call_conn_event_cb(&event, conn_handle); } void ble_gap_rx_transmit_power_report(const struct ble_hci_ev_le_subev_transmit_power_report *ev) { struct ble_gap_event event; + uint16_t conn_handle = le16toh(ev->conn_handle); memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_TRANSMIT_POWER; event.transmit_power.status = ev->status; - event.transmit_power.conn_handle = le16toh(ev->conn_handle); + event.transmit_power.conn_handle = conn_handle; event.transmit_power.reason = ev->reason; event.transmit_power.phy = ev->phy; event.transmit_power.transmit_power_level = ev->transmit_power_level; @@ -1749,6 +1752,7 @@ ble_gap_rx_transmit_power_report(const struct ble_hci_ev_le_subev_transmit_power event.transmit_power.delta = ev->delta; ble_gap_event_listener_call(&event); + ble_gap_call_conn_event_cb(&event, conn_handle); } #endif From d7950095b1a3e61001509895c9ff4a064f43e0c6 Mon Sep 17 00:00:00 2001 From: ESPAbhinav <128136388+ESPAbhinav@users.noreply.github.com> Date: Tue, 10 Oct 2023 12:03:25 +0530 Subject: [PATCH 0843/1333] nimble/host: Fix not handling error on RL element removal To remove the device from the RPA List ble_gap_unpair() API is used which sends a command to the controller. This command shall not be used when address resolution is enabled in the Controller and: Advertising (other than periodic advertising) is enabled, Scanning is enabled, or an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or HCI_LE_Periodic_Advertising_Create_Sync command is pending. An error check is added for the API ble_hs_pvcy_remove_entry which is invoked by ble_gap_unpair(). --- nimble/host/src/ble_gap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 7922c52432..807796dd52 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -6059,6 +6059,7 @@ int ble_gap_unpair(const ble_addr_t *peer_addr) { #if NIMBLE_BLE_SM + int rc; struct ble_hs_conn *conn; if (!ble_hs_is_enabled()) { @@ -6078,8 +6079,11 @@ ble_gap_unpair(const ble_addr_t *peer_addr) ble_hs_unlock(); - ble_hs_pvcy_remove_entry(peer_addr->type, + rc = ble_hs_pvcy_remove_entry(peer_addr->type, peer_addr->val); + if (rc != 0) { + return rc; + } return ble_store_util_delete_peer(peer_addr); #else From 3eb3f0a0aa61207807e89c63b0dc2e38b3cc5947 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 31 Jan 2023 00:53:59 +0100 Subject: [PATCH 0844/1333] nimble/ll: Improve scheduling of 1st BIG event This improves BIG scheduling in case periodic advertising interval is an integer multiple of ISO interval. In such case placing BIG event directly before periodic advertising event makes sure both won't overlap even if periodic advertising data changes in future. Note that there may still be conflicts with other instances and this patch doesn't resolve that. --- .../include/controller/ble_ll_adv.h | 3 ++ .../include/controller/ble_ll_sched.h | 2 +- nimble/controller/src/ble_ll_adv.c | 18 +++++++++ nimble/controller/src/ble_ll_iso_big.c | 38 ++++++++++++++----- nimble/controller/src/ble_ll_sched.c | 4 +- 5 files changed, 52 insertions(+), 13 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_adv.h b/nimble/controller/include/controller/ble_ll_adv.h index ba17ed5e07..b861d19dba 100644 --- a/nimble/controller/include/controller/ble_ll_adv.h +++ b/nimble/controller/include/controller/ble_ll_adv.h @@ -201,6 +201,9 @@ int ble_ll_adv_periodic_set_info_transfer(const uint8_t *cmdbuf, uint8_t len, /* Get advertising instance with periodic advertising configured */ struct ble_ll_adv_sm *ble_ll_adv_sync_get(uint8_t handle); +/* Get periodic advertising event scheduled time */ +int ble_ll_adv_sync_sched_get(struct ble_ll_adv_sm *advsm, + uint32_t *start_time, uint32_t *end_time); #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) struct ble_ll_iso_big; diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h index cceb96ce11..5daa647fab 100644 --- a/nimble/controller/include/controller/ble_ll_sched.h +++ b/nimble/controller/include/controller/ble_ll_sched.h @@ -219,7 +219,7 @@ uint32_t ble_ll_sched_css_get_conn_interval_us(void); #endif #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) -int ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first); +int ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first, int fixed); #endif /* BLE_LL_ISO_BROADCASTER */ #ifdef __cplusplus diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 7056c8de93..db07f8965b 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -5309,6 +5309,24 @@ ble_ll_adv_sync_get(uint8_t handle) return advsm; } +int +ble_ll_adv_sync_sched_get(struct ble_ll_adv_sm *advsm, uint32_t *start_time, + uint32_t *end_time) +{ + struct ble_ll_adv_sync *sync; + + if (!advsm || !advsm->periodic_adv_active) { + return -EIO; + } + + sync = SYNC_CURRENT(advsm); + + *start_time = sync->sch.start_time + g_ble_ll_sched_offset_ticks; + *end_time = sync->sch.end_time; + + return 0; +} + int ble_ll_adv_sync_big_add(struct ble_ll_adv_sm *advsm, struct ble_ll_iso_big *big) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 31bcd21f0f..b836fed0b8 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -498,7 +498,7 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) } /* XXX this should always succeed since we preempt anything for now */ - rc = ble_ll_sched_iso_big(&big->sch, 0); + rc = ble_ll_sched_iso_big(&big->sch, 0, 0); assert(rc == 0); } while (rc < 0); @@ -1029,18 +1029,36 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, * not enough for some phys to run scheduler item. */ - /* Schedule 1st event a bit in future */ - /* FIXME schedule 6ms in the future to avoid conflict with periodic - * advertising when both are started at the same time; we should - * select this value in some smart way later... - */ - big->sch.start_time = ble_ll_tmr_get() + ble_ll_tmr_u2t(6000); + uint32_t start_time, end_time, big_time; + uint32_t sync_delay_ticks = ble_ll_tmr_u2t_up(big->sync_delay); + uint32_t iso_interval_ticks = ble_ll_tmr_u2t_up(big->iso_interval * 1250); + int big_event_fixed; + + rc = ble_ll_adv_sync_sched_get(big->advsm, &start_time, &end_time); + if (rc) { + /* Set 1st BIG one interval after "now", this ensures it's always + * scheduled in the future. + */ + big_time = ble_ll_tmr_get() + iso_interval_ticks; + big_event_fixed = 0; + } else { + /* Set 1st BIG event directly before periodic advertising event, this + * way it will not overlap it even if periodic advertising data changes. + * Make sure it's in the future. + */ + big_time = start_time - g_ble_ll_sched_offset_ticks - sync_delay_ticks - 1; + while (big_time - g_ble_ll_sched_offset_ticks < ble_ll_tmr_get()) { + big_time += iso_interval_ticks; + } + big_event_fixed = 1; + } + + big->sch.start_time = big_time; big->sch.remainder = 0; - big->sch.end_time = big->sch.start_time + - ble_ll_tmr_u2t_up(big->sync_delay) + 1; + big->sch.end_time = big->sch.start_time + sync_delay_ticks + 1; big->sch.start_time -= g_ble_ll_sched_offset_ticks; - rc = ble_ll_sched_iso_big(&big->sch, 1); + rc = ble_ll_sched_iso_big(&big->sch, 1, big_event_fixed); if (rc < 0) { ble_ll_iso_big_free(big); return -EFAULT; diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 8e8cee18fe..5cd01e04a5 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -844,14 +844,14 @@ ble_ll_sched_adv_resched_pdu(struct ble_ll_sched_item *sch) #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) int -ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first) +ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first, int fixed) { os_sr_t sr; int rc; OS_ENTER_CRITICAL(sr); - if (first) { + if (first && !fixed) { rc = ble_ll_sched_insert(sch, BLE_LL_SCHED_MAX_DELAY_ANY, preempt_none); } else { /* XXX provide better strategy for preemption */ From 12996809617836dabdc370c10f334020b2e9f75e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 17 Oct 2023 09:10:16 +0200 Subject: [PATCH 0845/1333] apps/bttester: enable EATT by default Set max of 5 channels. --- apps/bttester/syscfg.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 5db9af2ea8..bc5e0085a1 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -100,6 +100,7 @@ syscfg.vals: BLE_L2CAP_COC_MAX_NUM: 2 BLE_L2CAP_SIG_MAX_PROCS: 2 BLE_L2CAP_ENHANCED_COC: 1 + BLE_EATT_CHAN_NUM: 5 BLE_VERSION: 53 # Some testcases require MPS < MTU BLE_L2CAP_COC_MPS: 100 From d20c0109221055fab3a2e5a377efe74c5cd94f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 17 Oct 2023 08:08:49 +0200 Subject: [PATCH 0846/1333] nimble/ll: remove unsupported ISO code and configs This patch removes boilerplate for ISO code. This code causes conflicts when proper implementation is introduced, as new LL flags are introduced. This causes bugs like duplicated case for BLE_HCI_OCF_LE_READ_ISO_TX_SYNC OP Code. Unsupported functions were removed, along with BLE_LL_CFG_FEAT_LL_ISO and BLE_LL_CFG_FEAT_LL_ISO_TEST flag (BLE_LL_ISO and BLE_LL_ISO_TEST are currently used). BLE_ISO_BROADCAST flag was introduced, and BLE_LL_ISO_BROADCASTER inherits its value, by default. Similary, BLE_LL_ISO inherits default value from BLE_ISO now. --- nimble/controller/src/ble_ll.c | 6 -- nimble/controller/src/ble_ll_ctrl.c | 47 --------- nimble/controller/src/ble_ll_hci.c | 52 ---------- nimble/controller/src/ble_ll_iso.c | 146 ---------------------------- nimble/controller/syscfg.yml | 19 +--- nimble/syscfg.yml | 7 +- 6 files changed, 8 insertions(+), 269 deletions(-) delete mode 100644 nimble/controller/src/ble_ll_iso.c diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index fd96f7d625..620e1b1be7 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1925,12 +1925,6 @@ ble_ll_init(void) features |= BLE_LL_FEAT_SCA_UPDATE; #endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) - features |= BLE_LL_FEAT_CIS_CENTRAL; - features |= BLE_LL_FEAT_CIS_PERIPH; - features |= BLE_LL_FEAT_CIS_HOST; -#endif - #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) features |= BLE_LL_FEAT_ISO_BROADCASTER; #endif diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index ed03fd10f9..053c62881a 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1296,27 +1296,6 @@ ble_ll_ctrl_rx_subrate_ind(struct ble_ll_conn_sm *connsm, uint8_t *req, } #endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) -static uint8_t -ble_ll_ctrl_rx_cis_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, - uint8_t *rspdata) -{ - return BLE_LL_CTRL_UNKNOWN_RSP; -} - -static uint8_t -ble_ll_ctrl_rx_cis_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, - uint8_t *rspdata) -{ - return BLE_LL_CTRL_UNKNOWN_RSP; -} - -static uint8_t -ble_ll_ctrl_rx_cis_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr) -{ - return BLE_LL_CTRL_UNKNOWN_RSP; -} -#endif /** * Create a link layer length request or length response PDU. * @@ -1522,15 +1501,6 @@ ble_ll_ctrl_start_enc_send(struct ble_ll_conn_sm *connsm) return rc; } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) -static void -ble_ll_ctrl_cis_create(struct ble_ll_conn_sm *connsm, uint8_t *dptr) -{ - /* TODO Implement */ - return; -} -#endif - /** * Create a link layer control "encrypt request" PDU. * @@ -2544,12 +2514,6 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc, void *data) ble_ll_ctrl_sca_req_rsp_make(connsm, ctrdata); break; #endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) - case BLE_LL_CTRL_PROC_CIS_CREATE: - opcode = BLE_LL_CTRL_CIS_REQ; - ble_ll_ctrl_cis_create(connsm, ctrdata); - break; -#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_CTRL_PROC_SUBRATE_REQ: @@ -3013,17 +2977,6 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) break; #endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) - case BLE_LL_CTRL_CIS_REQ: - rsp_opcode = ble_ll_ctrl_rx_cis_req(connsm, dptr, rspdata); - break; - case BLE_LL_CTRL_CIS_RSP: - rsp_opcode = ble_ll_ctrl_rx_cis_rsp(connsm, dptr, rspdata); - break; - case BLE_LL_CTRL_CIS_IND: - rsp_opcode = ble_ll_ctrl_rx_cis_ind(connsm, dptr); - break; -#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) case BLE_LL_CTRL_PERIODIC_SYNC_IND: rsp_opcode = ble_ll_ctrl_rx_periodic_sync_ind(connsm, dptr); diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 719fa6924a..1be14ceeec 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1275,32 +1275,6 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, rc = ble_ll_iso_big_hci_terminate(cmdbuf, len); break; #endif /* BLE_LL_ISO_BROADCASTER */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) - case BLE_HCI_OCF_LE_READ_ISO_TX_SYNC: - rc = ble_ll_iso_read_tx_sync(cmdbuf, len); - break; - case BLE_HCI_OCF_LE_SET_CIG_PARAMS: - rc = ble_ll_iso_set_cig_param(cmdbuf, len, rspbuf, rsplen); - break; - case BLE_HCI_OCF_LE_CREATE_CIS: - rc = ble_ll_iso_create_cis(cmdbuf, len); - break; - case BLE_HCI_OCF_LE_REMOVE_CIG: - rc = ble_ll_iso_remove_cig(cmdbuf, len, rspbuf, rsplen); - break; - case BLE_HCI_OCF_LE_ACCEPT_CIS_REQ: - rc = ble_ll_iso_accept_cis_req(cmdbuf, len); - break; - case BLE_HCI_OCF_LE_REJECT_CIS_REQ: - rc = ble_ll_iso_reject_cis_req(cmdbuf, len); - break; - case BLE_HCI_OCF_LE_BIG_CREATE_SYNC: - rc = ble_ll_iso_big_create_sync(cmdbuf, len); - break; - case BLE_HCI_OCF_LE_BIG_TERMINATE_SYNC: - rc = ble_ll_iso_big_terminate_sync(cmdbuf,len); - break; -#endif #if MYNEWT_VAL(BLE_LL_ISO) case BLE_HCI_OCF_LE_SETUP_ISO_DATA_PATH: rc = ble_ll_isoal_hci_setup_iso_data_path(cmdbuf, len, rspbuf, rsplen); @@ -1317,26 +1291,6 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, } break; #endif /* BLE_LL_ISO */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO_TEST) - case BLE_HCI_OCF_LE_SET_CIG_PARAMS_TEST: - rc = ble_ll_iso_set_cig_param_test(cmdbuf, len, rspbuf, rsplen); - break; - case BLE_HCI_OCF_LE_CREATE_BIG_TEST: - rc = ble_ll_iso_create_big_test(cmdbuf, len); - break; - case BLE_HCI_OCF_LE_ISO_TRANSMIT_TEST: - rc = ble_ll_iso_transmit_test(cmdbuf, len); - break; - case BLE_HCI_OCF_LE_ISO_RECEIVE_TEST: - rc = ble_ll_iso_receive_test(cmdbuf, len); - break; - case BLE_HCI_OCF_LE_ISO_READ_TEST_COUNTERS: - rc = ble_ll_iso_read_counters_test(cmdbuf, len); - break; - case BLE_HCI_OCF_LE_ISO_TEST_END: - rc = ble_ll_iso_end_test(cmdbuf, len); - break; -#endif #if MYNEWT_VAL(BLE_VERSION) >= 52 case BLE_HCI_OCF_LE_SET_HOST_FEATURE: rc = ble_ll_set_host_feat(cmdbuf, len); @@ -1385,12 +1339,6 @@ ble_ll_hci_disconnect(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) - if (le16toh(cmd->conn_handle) >= BLE_LL_CONN_HANDLE_ISO_OFFSET) { - return ble_ll_iso_disconnect_cmd(cmd); - } -#endif - return ble_ll_conn_hci_disconnect_cmd(cmd); } #endif diff --git a/nimble/controller/src/ble_ll_iso.c b/nimble/controller/src/ble_ll_iso.c deleted file mode 100644 index a6186fe1a5..0000000000 --- a/nimble/controller/src/ble_ll_iso.c +++ /dev/null @@ -1,146 +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. - */ - -#include -#include "syscfg/syscfg.h" -#include "nimble/ble.h" -#include "nimble/hci_common.h" -#include "controller/ble_ll_iso.h" - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO) - -int -ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t len) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_set_cig_param(const uint8_t *cmdbuf, uint8_t len, - uint8_t *rspbuf, uint8_t *rsplen) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_create_cis(const uint8_t *cmdbuf, uint8_t len) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_disconnect_cmd(const struct ble_hci_lc_disconnect_cp *cmd) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_remove_cig(const uint8_t *cmdbuf, uint8_t len, - uint8_t *rspbuf, uint8_t *rsplen) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_accept_cis_req(const uint8_t *cmdbuf, uint8_t len) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_reject_cis_req(const uint8_t *cmdbuf, uint8_t len) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t len) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t len) -{ - /* Nothing to do here for now when HCI is supported */ - return 0; -} -int -ble_ll_iso_create_big(const uint8_t *cmdbuf, uint8_t len) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_terminate_big(const uint8_t *cmdbuf, uint8_t len) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_big_create_sync(const uint8_t *cmdbuf, uint8_t len) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_big_terminate_sync(const uint8_t *cmdbuf, uint8_t len) -{ - return BLE_ERR_UNSUPPORTED; -} - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO_TEST) -int -ble_ll_iso_set_cig_param_test(const uint8_t *cmdbuf, uint8_t len, - uint8_t *rspbuf, uint8_t *rsplen) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_create_big_test(const uint8_t *cmdbuf, uint8_t len) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_transmit_test(const uint8_t *cmdbuf, uint8_t len) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_receive_test(const uint8_t *cmdbuf, uint8_t len) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_read_counters_test(const uint8_t *cmdbuf, uint8_t len) -{ - return BLE_ERR_UNSUPPORTED; -} - -int -ble_ll_iso_end_test(const uint8_t *cmdbuf, uint8_t len) -{ - return BLE_ERR_UNSUPPORTED; -} -#endif -#endif diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index f02b04dfe4..8a28b1c528 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -348,21 +348,6 @@ syscfg.defs: restrictions: - '(BLE_VERSION >= 53) if 1' - BLE_LL_CFG_FEAT_LL_ISO: - description: > - This option is used to enable/disable support for LE Isochronous Channels - as per Bluetooth v5.2 channels - value: MYNEWT_VAL(BLE_ISO) - restrictions: - - '(BLE_VERSION >= 52) if 1' - - BLE_LL_CFG_FEAT_LL_ISO_TEST: - description: > - This option is used to enable/disbale test commands for ISO support - value: MYNEWT_VAL(BLE_ISO_TEST) - restrictions: - - 'BLE_LL_CFG_FEAT_LL_ISO if 1' - BLE_LL_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: description: > This option is used to enable/disable support for @@ -479,14 +464,14 @@ syscfg.defs: data, particular ISO features have to be enabled separately. restrictions: - (BLE_VERSION >= 52) if 1 - value: 0 + value: MYNEWT_VAL(BLE_ISO) state: experimental BLE_LL_ISO_BROADCASTER: description: > Enable support for Isochronous Broadcasting state. restrictions: - BLE_LL_ISO if 1 - value: 0 + value: MYNEWT_VAL(BLE_ISO_BROADCASTER) state: experimental BLE_LL_SYSINIT_STAGE: diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index ce43a00b1d..eaaec96896 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -95,7 +95,12 @@ syscfg.defs: value: 0 restrictions: - '(BLE_VERSION >= 52) if 1' - + BLE_ISO_BROADCASTER: + description: > + This enables LE Audio Broadcaster feature + value: 0 + restrictions: + - '(BLE_VERSION >= 52) if 1' BLE_ISO_TEST: description: > Enables BLE ISO Testing commands From 60dcd0f38317f4ff90903cb1ba9d39d60f51bf89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 16 Oct 2023 14:40:36 +0200 Subject: [PATCH 0847/1333] nimble/ll: silence compiler warning in ble_ll_iso_big_event_done Silences error: 'hci_ev_ncp' may be used uninitialized: it is derived from hci_ev, and only used when hci_ev != NULL. So it'll never be NULL when used. --- nimble/controller/src/ble_ll_iso_big.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index b836fed0b8..6725f30ab9 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -398,7 +398,7 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) { struct ble_ll_iso_bis *bis; struct ble_hci_ev *hci_ev; - struct ble_hci_ev_num_comp_pkts *hci_ev_ncp; + struct ble_hci_ev_num_comp_pkts *hci_ev_ncp = NULL; int num_completed_pkt; int rc; From cfe8b1be5dcca3e2a956534e862c1455d6745c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 16 Oct 2023 14:49:52 +0200 Subject: [PATCH 0848/1333] CI: add BLE_ISO_BROADCASTER to test_build_apps_syscfg.yml --- .github/test_build_apps_syscfg.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/test_build_apps_syscfg.yml b/.github/test_build_apps_syscfg.yml index 9722b51c73..169dfa7235 100644 --- a/.github/test_build_apps_syscfg.yml +++ b/.github/test_build_apps_syscfg.yml @@ -27,6 +27,7 @@ syscfg.vals: BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: 1 BLE_ISO: 1 BLE_ISO_TEST: 1 + BLE_ISO_BROADCASTER: 1 BLE_HCI_VS: 1 BLE_POWER_CONTROL: 1 BLE_CONN_SUBRATING: 1 From 5680da3c6a26f02f5323984aa00ec0f94c9314a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 23 Oct 2023 09:58:51 +0200 Subject: [PATCH 0849/1333] nimble: add sysconfig for enabling additional PHYs Three new configs are introduced: BLE_ADDITIONAL_PHY that enables additional PHY and two configs that specify what additional PHY shall be enabled (2M or CODED) --- .../targets/nordic_pca10095_blehci/syscfg.yml | 5 +++-- .github/test_build_apps_syscfg.yml | 4 ++-- apps/blestress/syscfg.yml | 4 ++-- apps/dtm/syscfg.yml | 5 +++-- babblesim/targets/edtthci/syscfg.yml | 3 ++- nimble/controller/syscfg.yml | 4 ++-- nimble/syscfg.yml | 17 +++++++++++++++++ targets/dialog_cmac/syscfg.yml | 3 +-- targets/nordic_pca10095_net-blehci/syscfg.yml | 4 ++-- .../targets/nordic_pca10040_blehci/syscfg.yml | 2 +- .../targets/nordic_pca10056_blehci/syscfg.yml | 2 +- .../targets/nordic_pca10059_blehci/syscfg.yml | 2 +- .../nordic_pca10095_app_blehci/syscfg.yml | 2 +- .../nordic_pca10095_net_blehci/syscfg.yml | 3 ++- 14 files changed, 40 insertions(+), 20 deletions(-) diff --git a/.github/targets/nordic_pca10095_blehci/syscfg.yml b/.github/targets/nordic_pca10095_blehci/syscfg.yml index 3ffe99c7db..aae8d12769 100644 --- a/.github/targets/nordic_pca10095_blehci/syscfg.yml +++ b/.github/targets/nordic_pca10095_blehci/syscfg.yml @@ -19,10 +19,11 @@ syscfg.vals: BLE_MAX_CONNECTIONS: 4 + BLE_PHY_2M: 1 + BLE_PHY_CODED: 1 + BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 - BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 BLE_LL_CFG_FEAT_LL_PRIVACY: 1 BLE_LL_CONN_INIT_MAX_TX_BYTES: 251 BLE_LL_CONN_INIT_SLOTS: 4 diff --git a/.github/test_build_apps_syscfg.yml b/.github/test_build_apps_syscfg.yml index 169dfa7235..44bcb5efe9 100644 --- a/.github/test_build_apps_syscfg.yml +++ b/.github/test_build_apps_syscfg.yml @@ -51,10 +51,10 @@ syscfg.vals: BLE_SM_SC: 1 BLE_STORE_MAX_BONDS: 5 BLE_EATT_CHAN_NUM: 2 + BLE_PHY_2M: 1 + BLE_PHY_CODED: 1 # controller - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 - BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 BLE_LL_CFG_FEAT_LL_PRIVACY: 1 BLE_LL_CONN_INIT_MAX_TX_BYTES: 251 BLE_LL_DTM: 1 diff --git a/apps/blestress/syscfg.yml b/apps/blestress/syscfg.yml index 5e16ed1f41..4f7fa4daca 100644 --- a/apps/blestress/syscfg.yml +++ b/apps/blestress/syscfg.yml @@ -75,10 +75,10 @@ syscfg.vals: BLE_L2CAP_COC_SDU_BUFF_COUNT: 1 # Enable 2M PHY - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_PHY_2M: 1 # Enable CODED PHY - BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 + BLE_PHY_CODED: 1 # Whether to save data to sys/config, or just keep it in RAM. BLE_STORE_CONFIG_PERSIST: 0 diff --git a/apps/dtm/syscfg.yml b/apps/dtm/syscfg.yml index b88c387a11..7e00a4736a 100644 --- a/apps/dtm/syscfg.yml +++ b/apps/dtm/syscfg.yml @@ -22,7 +22,8 @@ syscfg.vals: CONSOLE_HISTORY: ram CONSOLE_HISTORY_RAM_HISTORY_SIZE: 50 + BLE_PHY_2M: 1 + BLE_PHY_CODED: 1 + BLE_LL_DTM: 1 BLE_LL_DTM_EXTENSIONS: 1 - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 - BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 diff --git a/babblesim/targets/edtthci/syscfg.yml b/babblesim/targets/edtthci/syscfg.yml index 0476ccf36b..6b32ddc653 100644 --- a/babblesim/targets/edtthci/syscfg.yml +++ b/babblesim/targets/edtthci/syscfg.yml @@ -34,7 +34,6 @@ syscfg.vals: BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 BLE_LL_CFG_FEAT_LL_PRIVACY: 1 BLE_LL_CFG_FEAT_LE_CSA2: 1 - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 # BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 # not modeled in bsim BLE_LL_CFG_FEAT_LL_EXT_ADV: 1 BLE_LL_CFG_FEAT_LL_PERIODIC_ADV: 1 @@ -42,6 +41,8 @@ syscfg.vals: BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL: 1 BLE_LL_CFG_FEAT_LL_SCA_UPDATE: 1 + BLE_PHY_2M: 1 + BLE_ROLE_CENTRAL: 1 BLE_ROLE_PERIPHERAL: 1 BLE_ROLE_BROADCASTER: 1 diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 8a28b1c528..5988e807f2 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -287,12 +287,12 @@ syscfg.defs: BLE_LL_CFG_FEAT_LE_2M_PHY: description: > This option is used to enable/disable support for the 2Mbps PHY. - value: '0' + value: MYNEWT_VAL(BLE_PHY_2M) BLE_LL_CFG_FEAT_LE_CODED_PHY: description: > This option is used to enable/disable support for the coded PHY. - value: '0' + value: MYNEWT_VAL(BLE_PHY_CODED) BLE_LL_CFG_FEAT_LL_EXT_ADV: description: > diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index eaaec96896..68432e28b2 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -130,6 +130,23 @@ syscfg.defs: This enables LE Connection Subrating feature value: 0 + BLE_PHY_2M: + description: > + This enables support for addtitional 2M PHY + value: 0 + restrictions: + - 'BLE_PHY if 1' + + BLE_PHY_CODED: + description: > + This enables support for addtitional CODED PHY + value: 0 + restrictions: + - 'BLE_PHY if 1' + +syscfg.defs.'BLE_PHY_2M || BLE_PHY_CODED': + BLE_PHY: 1 + # Allow periodic sync transfer only if 5.1 or higher syscfg.restrictions: - "'BLE_PERIODIC_ADV_SYNC_TRANSFER == 0' || 'BLE_VERSION >= 51'" diff --git a/targets/dialog_cmac/syscfg.yml b/targets/dialog_cmac/syscfg.yml index f73d4e01ba..daf84a4ca9 100644 --- a/targets/dialog_cmac/syscfg.yml +++ b/targets/dialog_cmac/syscfg.yml @@ -51,9 +51,8 @@ syscfg.vals: BLE_MULTI_ADV_INSTANCES: 4 BLE_MAX_PERIODIC_SYNCS: 4 BLE_MAX_CONNECTIONS: 4 + BLE_PHY_2M: 1 BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 - BLE_LL_CFG_FEAT_LE_CODED_PHY: 0 BLE_LL_CFG_FEAT_LL_PRIVACY: 1 BLE_LL_CFG_FEAT_LL_SCA_UPDATE: 1 BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE: 1 diff --git a/targets/nordic_pca10095_net-blehci/syscfg.yml b/targets/nordic_pca10095_net-blehci/syscfg.yml index b679e9ae7a..f20f40e69f 100644 --- a/targets/nordic_pca10095_net-blehci/syscfg.yml +++ b/targets/nordic_pca10095_net-blehci/syscfg.yml @@ -23,8 +23,8 @@ syscfg.vals: MSYS_1_BLOCK_COUNT: 12 MSYS_1_BLOCK_SIZE: 292 BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 - BLE_LL_CFG_FEAT_LE_CODED_PHY: 1 + BLE_PHY_2M: 1 + BLE_PHY_CODED: 1 BLE_LL_CFG_FEAT_LL_PRIVACY: 1 BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL: 1 BLE_LL_CONN_INIT_MAX_TX_BYTES: 251 diff --git a/tools/hci_throughput/targets/nordic_pca10040_blehci/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10040_blehci/syscfg.yml index 1c2bbee274..8751b379b5 100644 --- a/tools/hci_throughput/targets/nordic_pca10040_blehci/syscfg.yml +++ b/tools/hci_throughput/targets/nordic_pca10040_blehci/syscfg.yml @@ -19,7 +19,7 @@ syscfg.vals: BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_PHY_2M: 1 BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 MSYS_1_BLOCK_COUNT: 80 MSYS_1_BLOCK_SIZE: 308 diff --git a/tools/hci_throughput/targets/nordic_pca10056_blehci/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10056_blehci/syscfg.yml index 1c65d055bb..f054a3ff46 100644 --- a/tools/hci_throughput/targets/nordic_pca10056_blehci/syscfg.yml +++ b/tools/hci_throughput/targets/nordic_pca10056_blehci/syscfg.yml @@ -18,8 +18,8 @@ # syscfg.vals: + BLE_PHY_2M: 1 BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 BLE_TRANSPORT_HS: usb USBD_VID: 0xDCAB diff --git a/tools/hci_throughput/targets/nordic_pca10059_blehci/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10059_blehci/syscfg.yml index 6fc26b9db1..618bd4506f 100644 --- a/tools/hci_throughput/targets/nordic_pca10059_blehci/syscfg.yml +++ b/tools/hci_throughput/targets/nordic_pca10059_blehci/syscfg.yml @@ -19,7 +19,7 @@ syscfg.vals: BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_PHY_2M: 1 BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 BLE_TRANSPORT_HS: usb USBD_VID: 0xDCAB diff --git a/tools/hci_throughput/targets/nordic_pca10095_app_blehci/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10095_app_blehci/syscfg.yml index c7ff62bba0..420e5f58f7 100644 --- a/tools/hci_throughput/targets/nordic_pca10095_app_blehci/syscfg.yml +++ b/tools/hci_throughput/targets/nordic_pca10095_app_blehci/syscfg.yml @@ -38,5 +38,5 @@ syscfg.vals: IPC_NRF5340_BUF_SZ: 3072 BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 + BLE_PHY_2M: 1 BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 diff --git a/tools/hci_throughput/targets/nordic_pca10095_net_blehci/syscfg.yml b/tools/hci_throughput/targets/nordic_pca10095_net_blehci/syscfg.yml index 7f0b5b60f8..1328c03b22 100644 --- a/tools/hci_throughput/targets/nordic_pca10095_net_blehci/syscfg.yml +++ b/tools/hci_throughput/targets/nordic_pca10095_net_blehci/syscfg.yml @@ -23,8 +23,9 @@ syscfg.vals: BLE_LL_SCA: 50 OS_CRASH_FILE_LINE: 1 + BLE_PHY_2M: 1 + BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 - BLE_LL_CFG_FEAT_LE_2M_PHY: 1 BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 BLE_TRANSPORT_ACL_COUNT: 80 From ba1a746b8f17bab073999bc903ea866392ba50cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 23 Oct 2023 11:33:16 +0200 Subject: [PATCH 0850/1333] nimble/ll: add BLE_LL_PHY config This config infers value from PHY flags and replaces BLE_LL_BT5_PHY_SUPPORTED define. --- nimble/controller/include/controller/ble_ll.h | 6 --- .../include/controller/ble_ll_conn.h | 2 +- nimble/controller/src/ble_ll_adv.c | 6 +-- nimble/controller/src/ble_ll_conn.c | 38 +++++++++---------- nimble/controller/src/ble_ll_conn_hci.c | 2 +- nimble/controller/src/ble_ll_ctrl.c | 14 +++---- nimble/controller/src/ble_ll_hci.c | 4 +- nimble/controller/src/ble_ll_hci_ev.c | 2 +- nimble/controller/src/ble_ll_hci_supp_cmd.c | 2 +- nimble/controller/src/ble_ll_iso_big.c | 4 +- nimble/controller/src/ble_ll_scan.c | 4 +- nimble/controller/src/ble_ll_scan_aux.c | 4 +- nimble/controller/src/ble_ll_sync.c | 4 +- nimble/controller/syscfg.yml | 3 ++ nimble/drivers/dialog_cmac/src/ble_phy.c | 12 +++--- nimble/drivers/nrf5x/src/ble_phy.c | 18 ++++----- 16 files changed, 61 insertions(+), 64 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 7247f31df4..0b5e1d52cb 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -53,12 +53,6 @@ void ble_ll_assert(const char *file, unsigned line) __attribute((noreturn)); #define BLE_LL_ASSERT(cond) assert(cond) #endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) || MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) -#define BLE_LL_BT5_PHY_SUPPORTED (1) -#else -#define BLE_LL_BT5_PHY_SUPPORTED (0) -#endif - /* Controller revision. */ #define BLE_LL_SUB_VERS_NR (0x0000) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index cb7ad60ae6..88e7934b1f 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -233,7 +233,7 @@ struct ble_ll_conn_sm uint16_t host_req_max_rx_time; #endif -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) struct ble_ll_conn_phy_data phy_data; uint16_t phy_instant; uint8_t phy_tx_transition; diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index db07f8965b..fad0bcc7df 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1123,7 +1123,7 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch) rc = ble_phy_setchan(advsm->adv_chan, BLE_ACCESS_ADDR_ADV, BLE_LL_CRCINIT_ADV); BLE_LL_ASSERT(rc == 0); -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) /* Set phy mode */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) { @@ -1269,7 +1269,7 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch) BLE_LL_CRCINIT_ADV); BLE_LL_ASSERT(rc == 0); -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) /* Set phy mode */ ble_phy_mode_set(advsm->sec_phy, advsm->sec_phy); #endif @@ -2264,7 +2264,7 @@ ble_ll_adv_sync_tx_start_cb(struct ble_ll_sched_item *sch) BLE_LL_ASSERT(rc == 0); -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) /* Set phy mode */ ble_phy_mode_set(advsm->sec_phy, advsm->sec_phy); #endif diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 3565e10424..0221d6a916 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -554,7 +554,7 @@ ble_ll_conn_find_by_peer_addr(const uint8_t *addr, uint8_t addr_type) return NULL; } -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) static inline int ble_ll_conn_phy_should_update(uint8_t pref_mask, uint8_t curr_mask) { @@ -1003,7 +1003,7 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm) } /* Check if we need to send PHY update complete event */ -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) if (connsm->flags.phy_update_host_w4event) { if (!ble_ll_hci_ev_phy_update(connsm, BLE_ERR_SUCCESS)) { /* Sent event. Clear flag */ @@ -1040,7 +1040,7 @@ ble_ll_conn_adjust_pyld_len(struct ble_ll_conn_sm *connsm, uint16_t pyld_len) uint16_t max_pyld_len; uint16_t ret; -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) uint8_t phy_mode; if (connsm->phy_tx_transition) { @@ -1268,7 +1268,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) * now. This is not the most accurate especially if we have * received a frame and we are replying to it. */ -#if BLE_LL_BT5_PHY_SUPPORTED +#if MYNEWT_VAL(BLE_LL_PHY) tx_phy_mode = connsm->phy_data.tx_phy_mode; #else tx_phy_mode = BLE_PHY_MODE_1M; @@ -1522,7 +1522,7 @@ ble_ll_conn_event_start_cb(struct ble_ll_sched_item *sch) ble_phy_resolv_list_disable(); #endif -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) ble_phy_mode_set(connsm->phy_data.tx_phy_mode, connsm->phy_data.rx_phy_mode); #endif @@ -1659,7 +1659,7 @@ ble_ll_conn_can_send_next_pdu(struct ble_ll_conn_sm *connsm, uint32_t begtime, uint32_t allowed_usecs; int tx_phy_mode; -#if BLE_LL_BT5_PHY_SUPPORTED +#if MYNEWT_VAL(BLE_LL_PHY) tx_phy_mode = connsm->phy_data.tx_phy_mode; #else tx_phy_mode = BLE_PHY_MODE_1M; @@ -1868,7 +1868,7 @@ ble_ll_conn_set_data_len(struct ble_ll_conn_sm *connsm, } #endif -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) static void ble_ll_conn_set_phy(struct ble_ll_conn_sm *connsm, int tx_phy, int rx_phy) @@ -2005,7 +2005,7 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) #endif /* XXX: TODO set these based on PHY that started connection */ -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) connsm->phy_data.cur_tx_phy = BLE_PHY_1M; connsm->phy_data.cur_rx_phy = BLE_PHY_1M; connsm->phy_data.tx_phy_mode = BLE_PHY_MODE_1M; @@ -2136,7 +2136,7 @@ ble_ll_conn_update_eff_data_len(struct ble_ll_conn_sm *connsm) * connection events timings. */ if (ota_max_rx_time_calc) { -#if BLE_LL_BT5_PHY_SUPPORTED +#if MYNEWT_VAL(BLE_LL_PHY) phy_mode = ble_ll_phy_to_phy_mode(connsm->phy_data.cur_rx_phy, BLE_HCI_LE_PHY_CODED_S8_PREF); #else @@ -2639,7 +2639,7 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) } #endif -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) if (connsm->flags.phy_update_sched && (connsm->event_cntr == connsm->phy_instant)) { @@ -2846,7 +2846,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) /* Send connection complete event to inform host of connection */ if (rc) { -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) && MYNEWT_VAL(BLE_LL_CONN_PHY_INIT_UPDATE) +#if MYNEWT_VAL(BLE_LL_PHY) && MYNEWT_VAL(BLE_LL_CONN_PHY_INIT_UPDATE) /* * If we have default phy preferences and they are different than * the current PHY's in use, start update procedure. @@ -3216,7 +3216,7 @@ ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu, #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (ext) { -#if BLE_LL_BT5_PHY_SUPPORTED +#if MYNEWT_VAL(BLE_LL_PHY) phy = rxhdr->rxinfo.phy; #else phy = BLE_PHY_1M; @@ -3240,7 +3240,7 @@ ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu, return -1; } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && BLE_LL_BT5_PHY_SUPPORTED +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && MYNEWT_VAL(BLE_LL_PHY) if (ext) { ble_ll_conn_init_phy(connsm, phy); } @@ -3288,7 +3288,7 @@ ble_ll_conn_central_start(uint8_t phy, uint8_t csa, #endif ble_ll_conn_set_csa(connsm, csa); -#if BLE_LL_BT5_PHY_SUPPORTED +#if MYNEWT_VAL(BLE_LL_PHY) ble_ll_conn_init_phy(connsm, phy); #endif ble_ll_conn_created(connsm, NULL); @@ -3316,12 +3316,12 @@ ble_ll_conn_created_on_aux(struct os_mbuf *rxpdu, struct ble_ll_scan_addr_data *addrd, uint8_t *targeta) { -#if BLE_LL_BT5_PHY_SUPPORTED +#if MYNEWT_VAL(BLE_LL_PHY) struct ble_mbuf_hdr *rxhdr; #endif uint8_t phy; -#if BLE_LL_BT5_PHY_SUPPORTED +#if MYNEWT_VAL(BLE_LL_PHY) rxhdr = BLE_MBUF_HDR_PTR(rxpdu); phy = rxhdr->rxinfo.phy; #else @@ -3698,7 +3698,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) * to the 'additional usecs' field to save some calculations. */ begtime = rxhdr->beg_cputime; -#if BLE_LL_BT5_PHY_SUPPORTED +#if MYNEWT_VAL(BLE_LL_PHY) rx_phy_mode = connsm->phy_data.rx_phy_mode; #else rx_phy_mode = BLE_PHY_MODE_1M; @@ -3834,7 +3834,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) rem_bytes = OS_MBUF_PKTLEN(txpdu) - txhdr->txinfo.offset; /* Adjust payload for max TX time and octets */ -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) if (BLE_LL_LLID_IS_CTRL(hdr_byte) && CONN_IS_PERIPHERAL(connsm) && (opcode == BLE_LL_CTRL_PHY_UPDATE_IND)) { @@ -4167,7 +4167,7 @@ ble_ll_conn_periph_start(uint8_t *rxbuf, uint8_t pat, struct ble_mbuf_hdr *rxhdr connsm->conn_role = BLE_LL_CONN_ROLE_PERIPHERAL; ble_ll_conn_sm_new(connsm); -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) /* Use the same PHY as we received CONNECT_REQ on */ ble_ll_conn_init_phy(connsm, rxhdr->rxinfo.phy); #endif diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 7f5ab699bf..dd32da565f 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1917,7 +1917,7 @@ ble_ll_conn_hci_wr_auth_pyld_tmo(const uint8_t *cmdbuf, uint8_t len, } #endif -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) /** * Read current phy for connection (OGF=8, OCF==0x0030) * diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 053c62881a..d0989d65f5 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -184,7 +184,7 @@ ble_ll_ctrl_rej_ext_ind_make(uint8_t rej_opcode, uint8_t err, uint8_t *ctrdata) ctrdata[1] = err; } -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) /** * Called to cancel a phy update procedure. * @@ -546,7 +546,7 @@ ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t * ctrl_proc = BLE_LL_CTRL_PROC_LE_PING; BLE_LL_CONN_CLEAR_FEATURE(connsm, BLE_LL_FEAT_LE_PING); break; -#if (BLE_LL_BT5_PHY_SUPPORTED ==1) +#if MYNEWT_VAL(BLE_LL_PHY) case BLE_LL_CTRL_PHY_REQ: ble_ll_ctrl_phy_update_cancel(connsm, BLE_ERR_UNSUPP_REM_FEATURE); ctrl_proc = BLE_LL_CTRL_PROC_PHY_UPDATE; @@ -656,7 +656,7 @@ ble_ll_ctrl_phy_from_phy_mask(uint8_t phy_mask) return phy; } -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) uint8_t ble_ll_ctrl_phy_tx_transition_get(uint8_t phy_mask) { @@ -1970,7 +1970,7 @@ ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, connsm->enc_data.enc_state = CONN_ENC_S_UNENCRYPTED; break; #endif -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) case BLE_LL_CTRL_PROC_PHY_UPDATE: ble_ll_ctrl_phy_update_cancel(connsm, ble_error); ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_PHY_UPDATE); @@ -2502,7 +2502,7 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc, void *data) } break; #endif -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) case BLE_LL_CTRL_PROC_PHY_UPDATE: opcode = BLE_LL_CTRL_PHY_REQ; ble_ll_ctrl_phy_req_rsp_make(connsm, ctrdata); @@ -2957,7 +2957,7 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) /* Sometimes reject triggers sending other LL CTRL msg */ rsp_opcode = ble_ll_ctrl_rx_reject_ind(connsm, dptr, opcode, rspdata); break; -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) case BLE_LL_CTRL_PHY_REQ: rsp_opcode = ble_ll_ctrl_rx_phy_req(connsm, dptr, rspdata); break; @@ -3177,7 +3177,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) break; #endif #endif -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_CTRL_PHY_REQ: if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 1be14ceeec..af46653945 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -365,7 +365,7 @@ ble_ll_hci_le_read_bufsize_v2(uint8_t *rspbuf, uint8_t *rsplen) } #endif -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) /** * Checks the preferred phy masks for validity and places the preferred masks * in the input phy masks @@ -1110,7 +1110,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, } break; #endif -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_HCI_OCF_LE_RD_PHY: rc = ble_ll_conn_hci_le_rd_phy(cmdbuf, len, rspbuf, rsplen); diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index dc74806258..06d3706875 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -432,7 +432,7 @@ ble_ll_hci_ev_send_adv_set_terminated(uint8_t status, uint8_t adv_handle, * @param connsm Pointer to connection state machine * @param status error status of event */ -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) int ble_ll_hci_ev_phy_update(struct ble_ll_conn_sm *connsm, uint8_t status) { diff --git a/nimble/controller/src/ble_ll_hci_supp_cmd.c b/nimble/controller/src/ble_ll_hci_supp_cmd.c index f10c89890d..8d9822fd6e 100644 --- a/nimble/controller/src/ble_ll_hci_supp_cmd.c +++ b/nimble/controller/src/ble_ll_hci_supp_cmd.c @@ -161,7 +161,7 @@ static const uint8_t octet_35 = OCTET( BIT(2) /* HCI LE Set Resolvable Private Address Timeout */ #endif BIT(3) /* HCI LE Read Maximum Data Length */ -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) BIT(4) /* HCI LE Read PHY */ BIT(5) /* HCI LE Set Default PHY */ diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 6725f30ab9..f9268d9721 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -741,7 +741,7 @@ ble_ll_iso_big_event_sched_cb(struct ble_ll_sched_item *sch) { struct ble_ll_iso_big *big; struct ble_ll_iso_bis *bis; -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) uint8_t phy_mode; #endif int rc; @@ -755,7 +755,7 @@ ble_ll_iso_big_event_sched_cb(struct ble_ll_sched_item *sch) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) ble_phy_resolv_list_disable(); #endif -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) phy_mode = ble_ll_phy_to_phy_mode(big->phy, 0); ble_phy_mode_set(phy_mode, phy_mode); #endif diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 445cbb58f6..5530eabb26 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -749,7 +749,7 @@ ble_ll_scan_start(struct ble_ll_scan_sm *scansm) int rc; struct ble_ll_scan_phy *scanp = scansm->scanp; uint8_t chan; -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) uint8_t phy_mode; int phy; #endif @@ -779,7 +779,7 @@ ble_ll_scan_start(struct ble_ll_scan_sm *scansm) } #endif -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) phy = scanp->phy; phy_mode = ble_ll_phy_to_phy_mode(phy, BLE_HCI_LE_PHY_CODED_ANY); ble_phy_mode_set(phy_mode, phy_mode); diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 3d5f27753a..7b3b0a168f 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -111,7 +111,7 @@ static int ble_ll_scan_aux_sched_cb(struct ble_ll_sched_item *sch) { struct ble_ll_scan_aux_data *aux = sch->cb_arg; -#if BLE_LL_BT5_PHY_SUPPORTED +#if MYNEWT_VAL(BLE_LL_PHY) uint8_t phy_mode; #endif uint8_t lls; @@ -137,7 +137,7 @@ ble_ll_scan_aux_sched_cb(struct ble_ll_sched_item *sch) } #endif -#if BLE_LL_BT5_PHY_SUPPORTED +#if MYNEWT_VAL(BLE_LL_PHY) phy_mode = ble_ll_phy_to_phy_mode(aux->sec_phy, BLE_HCI_LE_PHY_CODED_ANY); ble_phy_mode_set(phy_mode, phy_mode); #endif diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 8aef8e2c82..31c8ec04d8 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -228,7 +228,7 @@ ble_ll_sync_sm_clear(struct ble_ll_sync_sm *sm) static uint8_t ble_ll_sync_phy_mode_to_hci(int8_t phy_mode) { -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) switch (phy_mode) { case BLE_PHY_MODE_1M: return BLE_HCI_LE_PHY_1M; @@ -475,7 +475,7 @@ ble_ll_sync_event_start_cb(struct ble_ll_sched_item *sch) ble_phy_encrypt_disable(); #endif -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) ble_phy_mode_set(sm->phy_mode, sm->phy_mode); #endif diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 5988e807f2..045cd50c5e 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -564,6 +564,9 @@ syscfg.defs: This is the stack size for LL task. value: 120 +syscfg.defs.'BLE_LL_CFG_FEAT_LE_2M_PHY || BLE_LL_CFG_FEAT_LE_CODED_PHY': + BLE_LL_PHY: 1 + syscfg.vals.BLE_LL_CFG_FEAT_LL_EXT_ADV: BLE_LL_CFG_FEAT_LE_CSA2: 1 BLE_HW_WHITELIST_ENABLE: 0 diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index d146e07e39..4c0e4c942a 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -639,7 +639,7 @@ ble_phy_irq_frame_tx_exc_bs_stop(void) (void)CMAC->CM_TS1_REG; if (g_ble_phy_data.end_transition == BLE_PHY_TRANSITION_TX_RX) { -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) ble_phy_mode_apply(g_ble_phy_data.phy_mode_rx); #endif ble_phy_rx_setup_fields(); @@ -895,7 +895,7 @@ ble_phy_irq_frame_rx_exc_phy_to_idle_4this(void) CMAC->CM_EXC_STAT_REG = CMAC_CM_EXC_STAT_REG_EXC_PHY_TO_IDLE_4THIS_Msk; /* We are here only on transition, so switch to TX */ -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) ble_phy_mode_apply(g_ble_phy_data.phy_mode_tx); #endif rf_chan = g_ble_phy_chan_to_rf[g_ble_phy_data.channel]; @@ -1016,7 +1016,7 @@ ble_phy_mode_set(uint8_t tx_phy_mode, uint8_t rx_phy_mode) static int ble_phy_get_cur_phy(void) { -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) switch (g_ble_phy_data.phy_mode_cur) { case BLE_PHY_MODE_1M: return BLE_PHY_1M; @@ -1357,7 +1357,7 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) MCU_DIAG_SER('r'); -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) ble_phy_mode_apply(g_ble_phy_data.phy_mode_rx); #endif @@ -1485,7 +1485,7 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) MCU_DIAG_SER('t'); -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) ble_phy_mode_apply(g_ble_phy_data.phy_mode_tx); #endif @@ -1712,7 +1712,7 @@ ble_phy_restart_rx(void) ble_phy_disable(); /* Apply mode before starting RX */ -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) ble_phy_mode_apply(g_ble_phy_data.phy_mode_rx); #endif diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 0c37f2aa76..a4d47cef7b 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -183,7 +183,7 @@ static const uint8_t g_ble_phy_chan_freq[BLE_PHY_NUM_CHANS] = { 66, 68, 70, 72, 74, 76, 78, 2, 26, 80, /* 30-39 */ }; -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) /* packet start offsets (in usecs) */ static const uint16_t g_ble_phy_mode_pkt_start_off[BLE_PHY_NUM_MODE] = { [BLE_PHY_MODE_1M] = 40, @@ -338,7 +338,7 @@ struct nrf_ccm_data struct nrf_ccm_data g_nrf_ccm_data; #endif -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) /* Packet start offset (in usecs). This is the preamble plus access address. * For LE Coded PHY this also includes CI and TERM1. */ @@ -451,7 +451,7 @@ ble_phy_mode_pdu_start_off(int phy_mode) static int ble_phy_get_cur_phy(void) { -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) switch (g_ble_phy_data.phy_cur_phy_mode) { case BLE_PHY_MODE_1M: return BLE_PHY_1M; @@ -904,7 +904,7 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) static uint32_t ble_phy_get_ccm_datarate(void) { -#if BLE_LL_BT5_PHY_SUPPORTED +#if MYNEWT_VAL(BLE_LL_PHY) switch (g_ble_phy_data.phy_cur_phy_mode) { case BLE_PHY_MODE_1M: return CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos; @@ -981,7 +981,7 @@ ble_phy_rx_xcvr_setup(void) g_ble_phy_data.phy_rx_started = 0; g_ble_phy_data.phy_state = BLE_PHY_STATE_RX; -#if BLE_LL_BT5_PHY_SUPPORTED +#if MYNEWT_VAL(BLE_LL_PHY) /* * On Coded PHY there are CI and TERM1 fields before PDU starts so we need * to take this into account when setting up BCC. @@ -1067,7 +1067,7 @@ ble_phy_tx_end_isr(void) } if (transition == BLE_PHY_TRANSITION_TX_RX) { -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); #endif @@ -1244,7 +1244,7 @@ ble_phy_rx_end_isr(void) #endif } -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) ble_phy_mode_apply(g_ble_phy_data.phy_tx_phy_mode); #endif @@ -1812,7 +1812,7 @@ ble_phy_tx_set_start_time(uint32_t cputime, uint8_t rem_usecs) ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_TX, cputime, rem_usecs); -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) ble_phy_mode_apply(g_ble_phy_data.phy_tx_phy_mode); #endif @@ -1854,7 +1854,7 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) ble_phy_trace_u32x2(BLE_PHY_TRACE_ID_START_RX, cputime, rem_usecs); -#if (BLE_LL_BT5_PHY_SUPPORTED == 1) +#if MYNEWT_VAL(BLE_LL_PHY) ble_phy_mode_apply(g_ble_phy_data.phy_rx_phy_mode); #endif From fb3ccfdcdd2dbcc9e01aecb7ecefc25c47dc8a86 Mon Sep 17 00:00:00 2001 From: Roshan Bangar Date: Wed, 28 Jun 2023 15:14:35 +0530 Subject: [PATCH 0851/1333] added periodic adv feature updates in ble 5.3 --- apps/btshell/src/cmd.c | 6 +- apps/bttester/src/btp_gap.c | 4 +- apps/ext_advertiser/src/main.c | 4 +- nimble/host/include/host/ble_gap.h | 62 ++++++++++++++- nimble/host/src/ble_gap.c | 120 +++++++++++++++++++++++++++-- 5 files changed, 178 insertions(+), 18 deletions(-) diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index e0fc57acaa..1bdd48e89d 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -1845,7 +1845,7 @@ cmd_set_adv_data_or_scan_rsp(int argc, char **argv, bool scan_rsp, rc = ble_gap_ext_adv_rsp_set_data(instance, adv_data); #if MYNEWT_VAL(BLE_PERIODIC_ADV) } else if (periodic) { - rc = ble_gap_periodic_adv_set_data(instance, adv_data); + rc = ble_gap_periodic_adv_set_data(instance, adv_data, NULL); #endif } else { rc = ble_gap_ext_adv_set_data(instance, adv_data); @@ -3701,7 +3701,7 @@ cmd_periodic_start(int argc, char **argv) return rc; } - rc = ble_gap_periodic_adv_start(instance); + rc = ble_gap_periodic_adv_start(instance, NULL); if (rc) { console_printf("failed to start periodic advertising\n"); return rc; @@ -3924,7 +3924,7 @@ cmd_sync_reporting(int argc, char **argv) return rc; } - rc = ble_gap_periodic_adv_sync_reporting(sync_handle, enable); + rc = ble_gap_periodic_adv_sync_reporting(sync_handle, enable, NULL); if (rc) { console_printf("Failed to %s reporting (%d)\n", enable ? "enable" : "disable", rc); diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 4af463e1bf..0b2239149b 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -2015,7 +2015,7 @@ periodic_adv_start(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } - rc = ble_gap_periodic_adv_start(1); + rc = ble_gap_periodic_adv_start(1, NULL); if (rc) { SYS_LOG_ERR("Failed to start periodic advertiser; rc=%d", rc); return BTP_STATUS_FAILED; @@ -2044,7 +2044,7 @@ periodic_adv_set_data(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } - rc = ble_gap_periodic_adv_set_data(1, adv_data); + rc = ble_gap_periodic_adv_set_data(1, adv_data, NULL); if (rc) { SYS_LOG_ERR("Failed to set periodic advertiser data; rc=%d", rc); return BTP_STATUS_FAILED; diff --git a/apps/ext_advertiser/src/main.c b/apps/ext_advertiser/src/main.c index ca450b1441..13c8955834 100644 --- a/apps/ext_advertiser/src/main.c +++ b/apps/ext_advertiser/src/main.c @@ -475,11 +475,11 @@ static void start_periodic(void) rc = os_mbuf_append(data, ext_adv_pattern_1, sizeof(ext_adv_pattern_1)); assert(rc == 0); - rc = ble_gap_periodic_adv_set_data(instance, data); + rc = ble_gap_periodic_adv_set_data(instance, data, NULL); assert (rc == 0); /* start periodic advertising */ - rc = ble_gap_periodic_adv_start(instance); + rc = ble_gap_periodic_adv_start(instance, NULL); assert (rc == 0); /* start advertising */ diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index af0defa9fc..fd70b94afb 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -1713,6 +1713,30 @@ struct ble_gap_periodic_adv_params { uint16_t itvl_max; }; +/** @brief Periodic advertising enable parameters */ +struct ble_gap_periodic_adv_start_params { +#if MYNEWT_VAL(BLE_VERSION) >= 53 + /** If include adi in aux_sync_ind PDU */ + unsigned int include_adi : 1; +#endif +}; + +/** @brief Periodic advertising sync reporting parameters */ +struct ble_gap_periodic_adv_sync_reporting_params { +#if MYNEWT_VAL(BLE_VERSION) >= 53 + /** If filter duplicates */ + unsigned int filter_duplicates : 1; +#endif +}; + +/** @brief Periodic adv set data parameters */ +struct ble_gap_periodic_adv_set_data_params { +#if MYNEWT_VAL(BLE_VERSION) >= 53 + /** If include adi in aux_sync_ind PDU */ + unsigned int update_did : 1; +#endif +}; + /** @brief Periodic sync parameters */ struct ble_gap_periodic_sync_params { /** The maximum number of periodic advertising events that controller can @@ -1725,7 +1749,13 @@ struct ble_gap_periodic_sync_params { uint16_t sync_timeout; /** If reports should be initially disabled when sync is created */ - unsigned int reports_disabled:1; + unsigned int reports_disabled : 1; + +#if MYNEWT_VAL(BLE_VERSION) >= 53 + /** If duplicate filtering should be should be initially enabled when sync is + created */ + unsigned int filter_duplicates : 1; +#endif }; /** @@ -1747,10 +1777,15 @@ int ble_gap_periodic_adv_configure(uint8_t instance, * Start periodic advertising for specified advertising instance. * * @param instance Instance ID + * @param params Additional arguments specifying the particulars + * of periodic advertising. * * @return 0 on success, error code on failure. */ -int ble_gap_periodic_adv_start(uint8_t instance); +int +ble_gap_periodic_adv_start(uint8_t instance, + const struct ble_gap_periodic_adv_start_params *params); + /** * Stop periodic advertising for specified advertising instance. @@ -1767,10 +1802,14 @@ int ble_gap_periodic_adv_stop(uint8_t instance); * * @param instance Instance ID * @param data Chain containing the periodic advertising data. + * @param params Additional arguments specifying the particulars + of periodic advertising data. * * @return 0 on success or error code on failure. */ -int ble_gap_periodic_adv_set_data(uint8_t instance, struct os_mbuf *data); +int ble_gap_periodic_adv_set_data(uint8_t instance, + struct os_mbuf *data, + const struct ble_gap_periodic_adv_set_data_params *params); /** * Performs the Synchronization procedure with periodic advertiser. @@ -1814,10 +1853,14 @@ int ble_gap_periodic_adv_sync_terminate(uint16_t sync_handle); * * @param sync_handle Handle identifying synchronization. * @param enable If reports should be enabled. + * @param params Additional arguments specifying the particulars + * of periodic reports. * * @return 0 on success; nonzero on failure. */ -int ble_gap_periodic_adv_sync_reporting(uint16_t sync_handle, bool enable); +int ble_gap_periodic_adv_sync_reporting(uint16_t sync_handle, + bool enable, + const struct ble_gap_periodic_adv_sync_reporting_params *params); /** * Initialize sync transfer procedure for specified handles. @@ -1849,6 +1892,17 @@ int ble_gap_periodic_adv_sync_set_info(uint8_t instance, uint16_t conn_handle, uint16_t service_data); +/** + * Set the default periodic sync transfer params. + * + * + * @param conn_handle Handle identifying connection. + * @param params Default Parameters for periodic sync transfer. + * + * @return 0 on success; nonzero on failure. + */ +int periodic_adv_set_default_sync_params(const struct ble_gap_periodic_sync_params *params); + /** * Enables or disables sync transfer reception on specified connection. * When sync transfer arrives, BLE_GAP_EVENT_PERIODIC_TRANSFER is sent to the user. diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 807796dd52..015a70d877 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -41,6 +41,8 @@ #define bssnz_t #endif +#define SET_BIT(t, n) (t |= 1UL << (n)) + /** * GAP - Generic Access Profile. * @@ -3668,7 +3670,7 @@ ble_gap_periodic_adv_configure(uint8_t instance, } int -ble_gap_periodic_adv_start(uint8_t instance) +ble_gap_periodic_adv_start(uint8_t instance, const struct ble_gap_periodic_adv_start_params *params) { struct ble_hci_le_set_periodic_adv_enable_cp cmd; uint16_t opcode; @@ -3693,6 +3695,12 @@ ble_gap_periodic_adv_start(uint8_t instance) opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_ENABLE); cmd.enable = 0x01; + +#if MYNEWT_VAL(BLE_VERSION) >= 53 + if (params && params->include_adi) { + SET_BIT(cmd.enable, 1); + } +#endif cmd.adv_handle = instance; rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); @@ -3707,6 +3715,27 @@ ble_gap_periodic_adv_start(uint8_t instance) return 0; } +#if MYNEWT_VAL(BLE_VERSION) >= 53 +static int +ble_gap_periodic_adv_update_did(uint8_t instance) +{ + static uint8_t buf[sizeof(struct ble_hci_le_set_periodic_adv_data_cp)]; + struct ble_hci_le_set_periodic_adv_data_cp *cmd = (void *) buf; + uint16_t opcode; + + memset(buf, 0, sizeof(buf)); + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_PERIODIC_ADV_DATA); + + cmd->adv_handle = instance; + cmd->operation = BLE_HCI_LE_SET_DATA_OPER_UNCHANGED; + cmd->adv_data_len = 0; + + return ble_hs_hci_cmd_tx(opcode, cmd, sizeof(*cmd) + cmd->adv_data_len, + NULL, 0); +} +#endif + static int ble_gap_periodic_adv_set(uint8_t instance, struct os_mbuf **data) { @@ -3835,7 +3864,9 @@ ble_gap_periodic_adv_set_data_validate(uint8_t instance, } int -ble_gap_periodic_adv_set_data(uint8_t instance, struct os_mbuf *data) +ble_gap_periodic_adv_set_data(uint8_t instance, + struct os_mbuf *data, + const struct ble_gap_periodic_adv_set_data_params *params) { int rc; if (instance >= BLE_ADV_INSTANCES) { @@ -3848,6 +3879,14 @@ ble_gap_periodic_adv_set_data(uint8_t instance, struct os_mbuf *data) goto done; } +#if MYNEWT_VAL(BLE_VERSION) >= 53 + /* update_did and data cannot be set at the same time */ + if (params && params->update_did && data) { + rc = BLE_HS_EINVAL; + goto done; + } +#endif + ble_hs_lock(); rc = ble_gap_periodic_adv_set_data_validate(instance, data); @@ -3856,7 +3895,15 @@ ble_gap_periodic_adv_set_data(uint8_t instance, struct os_mbuf *data) goto done; } +#if MYNEWT_VAL(BLE_VERSION) >= 53 + if (params && params->update_did) { + rc = ble_gap_periodic_adv_update_did(instance); + } else { + rc = ble_gap_periodic_adv_set(instance, &data); + } +#else rc = ble_gap_periodic_adv_set(instance, &data); +#endif ble_hs_unlock(); @@ -3993,6 +4040,15 @@ ble_gap_periodic_adv_sync_create(const ble_addr_t *addr, uint8_t adv_sid, memcpy(cmd.peer_addr, BLE_ADDR_ANY->val, BLE_DEV_ADDR_LEN); } +#if MYNEWT_VAL(BLE_VERSION) >= 53 + /* LE Periodic Advertising Create Sync command */ + if (params->reports_disabled) { + SET_BIT(cmd.options, 1); + } + if (params->filter_duplicates) { + SET_BIT(cmd.options, 2); + } +#endif cmd.sid = adv_sid; cmd.skip = params->skip; cmd.sync_timeout = htole16(params->sync_timeout); @@ -4090,8 +4146,11 @@ ble_gap_periodic_adv_sync_terminate(uint16_t sync_handle) return rc; } #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) +/* LE Set Periodic Advertising Receive Enable command */ int -ble_gap_periodic_adv_sync_reporting(uint16_t sync_handle, bool enable) +ble_gap_periodic_adv_sync_reporting(uint16_t sync_handle, + bool enable, + const struct ble_gap_periodic_adv_sync_reporting_params *params) { struct ble_hci_le_periodic_adv_receive_enable_cp cmd; struct ble_hs_periodic_sync *psync; @@ -4119,6 +4178,11 @@ ble_gap_periodic_adv_sync_reporting(uint16_t sync_handle, bool enable) cmd.sync_handle = htole16(sync_handle); cmd.enable = enable ? 0x01 : 0x00; +#if MYNEWT_VAL(BLE_VERSION) >= 53 + if (params && params->filter_duplicates) { + SET_BIT(cmd.enable, 1); + } +#endif rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); @@ -4230,11 +4294,22 @@ periodic_adv_transfer_enable(uint16_t conn_handle, opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_PERIODIC_ADV_SYNC_TRANSFER_PARAMS); + memset(&cmd, 0, sizeof(cmd)); cmd.conn_handle = htole16(conn_handle); - cmd.sync_cte_type = 0x00; - cmd.mode = params->reports_disabled ? 0x01 : 0x02; - cmd.skip = htole16(params->skip); - cmd.sync_timeout = htole16(params->sync_timeout); + + if (params != NULL) { + cmd.sync_cte_type = 0x00; + cmd.mode = params->reports_disabled ? 0x01 : 0x02; + +#if MYNEWT_VAL(BLE_VERSION) >= 53 + if (!params->reports_disabled && params->filter_duplicates) { + cmd.mode = 0x03; + } +#endif + + cmd.skip = htole16(params->skip); + cmd.sync_timeout = htole16(params->sync_timeout); + } rc = ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), &rsp, sizeof(rsp)); if (!rc) { @@ -4244,6 +4319,37 @@ periodic_adv_transfer_enable(uint16_t conn_handle, return rc; } +int +periodic_adv_set_default_sync_params(const struct ble_gap_periodic_sync_params *params) +{ + struct ble_hci_le_set_default_periodic_sync_transfer_params_cp cmd; + uint16_t opcode; + + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + + opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_DEFAULT_SYNC_TRANSFER_PARAMS); + + memset(&cmd, 0, sizeof(cmd)); + + if (params != NULL) { + cmd.sync_cte_type = 0x00; + cmd.mode = params->reports_disabled ? 0x01 : 0x02; + +#if MYNEWT_VAL(BLE_VERSION) >= 53 + if (!params->reports_disabled && params->filter_duplicates) { + cmd.mode = 0x03; + } +#endif + + cmd.skip = htole16(params->skip); + cmd.sync_timeout = htole16(params->sync_timeout); + } + + return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); +} + int ble_gap_periodic_adv_sync_receive(uint16_t conn_handle, const struct ble_gap_periodic_sync_params *params, From 8e1bc7250ff6f41a6633ff41388e51644f031c22 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 3 Oct 2023 15:12:44 +0200 Subject: [PATCH 0852/1333] nimble/ll: Add vs hci to set local IRK This adds vendor-specific HCI command to set local IRK in controller. IRK can be set for both public and static random addresses separately. Local IRK, if set, is used to generate local RPA in use cases where own address type was set to 0x02 or 0x03 but peer address is not added to resolving list. This for example allows to handle initiating connection to a new peer using RPA as our local address entirely in LL. Without that command it would be required for host to generate an RPA, set it as random address and connect using random address. This however doesn't work well with NimBLE host. If no IRK is set (or set to all-zero), the controller behaves as usual which makes it safe to enable as it won't break anything. --- .../include/controller/ble_ll_resolv.h | 11 ++ nimble/controller/src/ble_ll_adv.c | 4 +- nimble/controller/src/ble_ll_conn.c | 21 +-- nimble/controller/src/ble_ll_hci_vs.c | 32 +++++ nimble/controller/src/ble_ll_resolv.c | 126 +++++++++++++++--- nimble/controller/syscfg.yml | 12 ++ nimble/include/nimble/hci_common.h | 7 +- 7 files changed, 183 insertions(+), 30 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_resolv.h b/nimble/controller/include/controller/ble_ll_resolv.h index b9ca7fd387..ff28e783ce 100644 --- a/nimble/controller/include/controller/ble_ll_resolv.h +++ b/nimble/controller/include/controller/ble_ll_resolv.h @@ -115,6 +115,17 @@ int ble_ll_resolv_peer_rpa_any(const uint8_t *rpa); /* Initialize resolv*/ void ble_ll_resolv_init(void); +#if MYNEWT_VAL(BLE_LL_HCI_VS_LOCAL_IRK) +int ble_ll_resolv_local_irk_set(uint8_t own_addr_type, const uint8_t *irk); +int ble_ll_resolv_local_rpa_get(uint8_t own_addr_type, uint8_t *rpa); +#else +static inline int +ble_ll_resolv_local_rpa_get(uint8_t own_addr_type, uint8_t *rpa) +{ + return -1; +} +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index fad0bcc7df..52606f93e6 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -332,7 +332,9 @@ static void ble_ll_adv_rpa_update(struct ble_ll_adv_sm *advsm) { if (ble_ll_resolv_gen_rpa(advsm->peer_addr, advsm->peer_addr_type, - advsm->adva, 1)) { + advsm->adva, 1) || + (ble_ll_resolv_local_rpa_get(advsm->own_addr_type & 1, + advsm->adva) == 0)) { ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_TX_ADD); } else { if (advsm->own_addr_type & 1) { diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 0221d6a916..cee6f976b2 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3118,15 +3118,20 @@ ble_ll_conn_prepare_connect_ind(struct ble_ll_conn_sm *connsm, /* XXX: do this ahead of time? Calculate the local rpa I mean */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - if ((connsm->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) && - (addrd->rpa_index >= 0)) { - /* We are using RPA and advertiser was on our resolving list, so - * we'll use RPA to reply (see Core 5.3, Vol 6, Part B, 6.4). - */ - rl = &g_ble_ll_resolv_list[addrd->rpa_index]; - if (rl->rl_has_local) { + if (connsm->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) { + if (addrd->rpa_index >= 0) { + /* We are using RPA and advertiser was on our resolving list, so + * we'll use RPA to reply (see Core 5.3, Vol 6, Part B, 6.4). + */ + rl = &g_ble_ll_resolv_list[addrd->rpa_index]; + if (rl->rl_has_local) { + hdr |= BLE_ADV_PDU_HDR_TXADD_RAND; + ble_ll_resolv_get_priv_addr(rl, 1, pdu_data->inita); + addr = NULL; + } + } else if (ble_ll_resolv_local_rpa_get(connsm->own_addr_type & 1, + pdu_data->inita) == 0) { hdr |= BLE_ADV_PDU_HDR_TXADD_RAND; - ble_ll_resolv_get_priv_addr(rl, 1, pdu_data->inita); addr = NULL; } } diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index 7fd9a6ea6b..1710e456fe 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -29,6 +29,7 @@ #include "controller/ble_fem.h" #include "ble_ll_conn_priv.h" #include "ble_ll_priv.h" +#include "controller/ble_ll_resolv.h" #if MYNEWT_VAL(BLE_LL_HCI_VS) @@ -328,6 +329,33 @@ ble_ll_hci_vs_set_antenna(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, } #endif +#if MYNEWT_VAL(BLE_LL_HCI_VS_LOCAL_IRK) +static int +ble_ll_hci_vs_set_local_irk(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_vs_set_local_irk_cp *cmd = (const void *)cmdbuf; + int rc; + + if (cmdlen != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (ble_ll_is_busy(BLE_LL_BUSY_EXCLUDE_CONNECTIONS)) { + return BLE_ERR_CMD_DISALLOWED; + } + + rc = ble_ll_resolv_local_irk_set(cmd->own_addr_type, cmd->irk); + if (rc) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + *rsplen = 0; + + return 0; +} +#endif + static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_RD_STATIC_ADDR, ble_ll_hci_vs_rd_static_addr), @@ -354,6 +382,10 @@ static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { #if MYNEWT_VAL(BLE_FEM_ANTENNA) BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_ANTENNA, ble_ll_hci_vs_set_antenna), #endif +#if MYNEWT_VAL(BLE_LL_HCI_VS_LOCAL_IRK) + BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_LOCAL_IRK, + ble_ll_hci_vs_set_local_irk), +#endif }; static struct ble_ll_hci_vs_cmd * diff --git a/nimble/controller/src/ble_ll_resolv.c b/nimble/controller/src/ble_ll_resolv.c index 8ec9a97d1b..3566876e09 100644 --- a/nimble/controller/src/ble_ll_resolv.c +++ b/nimble/controller/src/ble_ll_resolv.c @@ -48,6 +48,16 @@ struct ble_ll_resolv_data g_ble_ll_resolv_data; __attribute__((aligned(4))) struct ble_ll_resolv_entry g_ble_ll_resolv_list[MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE)]; +#if MYNEWT_VAL(BLE_LL_HCI_VS_LOCAL_IRK) +struct local_irk_data { + uint8_t is_set; + uint8_t irk[16]; + uint8_t rpa[6]; +}; +/* 0 is for public, 1 is for static address */ +static struct local_irk_data g_local_irk[2]; +#endif + /** * Called to determine if a change is allowed to the resolving list at this * time. We are not allowed to modify the resolving list if address translation @@ -70,6 +80,30 @@ ble_ll_resolv_list_chg_allowed(void) return rc; } +static void +generate_rpa(const uint8_t *irk, uint8_t *rpa) +{ + uint8_t *prand; + struct ble_encryption_block ecb; + + /* Get prand */ + prand = rpa + 3; + ble_ll_rand_prand_get(prand); + + /* Calculate hash, hash = ah(local IRK, prand) */ + memcpy(ecb.key, irk, 16); + memset(ecb.plain_text, 0, 13); + ecb.plain_text[13] = prand[2]; + ecb.plain_text[14] = prand[1]; + ecb.plain_text[15] = prand[0]; + + /* Calculate hash */ + ble_hw_encrypt_block(&ecb); + + rpa[0] = ecb.cipher_text[15]; + rpa[1] = ecb.cipher_text[14]; + rpa[2] = ecb.cipher_text[13]; +} /** * Called to generate a resolvable private address in rl structure @@ -81,8 +115,6 @@ static void ble_ll_resolv_gen_priv_addr(struct ble_ll_resolv_entry *rl, int local) { uint8_t *irk; - uint8_t *prand; - struct ble_encryption_block ecb; uint8_t *addr; BLE_LL_ASSERT(rl != NULL); @@ -95,23 +127,7 @@ ble_ll_resolv_gen_priv_addr(struct ble_ll_resolv_entry *rl, int local) irk = rl->rl_peer_irk; } - /* Get prand */ - prand = addr + 3; - ble_ll_rand_prand_get(prand); - - /* Calculate hash, hash = ah(local IRK, prand) */ - memcpy(ecb.key, irk, 16); - memset(ecb.plain_text, 0, 13); - ecb.plain_text[13] = prand[2]; - ecb.plain_text[14] = prand[1]; - ecb.plain_text[15] = prand[0]; - - /* Calculate hash */ - ble_hw_encrypt_block(&ecb); - - addr[0] = ecb.cipher_text[15]; - addr[1] = ecb.cipher_text[14]; - addr[2] = ecb.cipher_text[13]; + generate_rpa(irk, addr); } /** @@ -124,6 +140,10 @@ ble_ll_resolv_rpa_timer_cb(struct ble_npl_event *ev) int i; os_sr_t sr; struct ble_ll_resolv_entry *rl; +#if MYNEWT_VAL(BLE_LL_HCI_VS_LOCAL_IRK) + struct local_irk_data *irk_data; + uint8_t rpa[6]; +#endif rl = &g_ble_ll_resolv_list[0]; for (i = 0; i < g_ble_ll_resolv_data.rl_cnt; ++i) { @@ -141,6 +161,18 @@ ble_ll_resolv_rpa_timer_cb(struct ble_npl_event *ev) ++rl; } +#if MYNEWT_VAL(BLE_LL_HCI_VS_LOCAL_IRK) + for (i = 0; i < ARRAY_SIZE(g_local_irk); i++) { + irk_data = &g_local_irk[i]; + if (irk_data->is_set) { + generate_rpa(irk_data->irk, rpa); + OS_ENTER_CRITICAL(sr); + memcpy(irk_data->rpa, rpa, 6); + OS_EXIT_CRITICAL(sr); + } + } +#endif + ble_npl_callout_reset(&g_ble_ll_resolv_data.rpa_timer, g_ble_ll_resolv_data.rpa_tmo); @@ -637,6 +669,58 @@ ble_ll_resolv_gen_rpa(uint8_t *addr, uint8_t addr_type, uint8_t *rpa, int local) return 0; } +#if MYNEWT_VAL(BLE_LL_HCI_VS_LOCAL_IRK) +int +ble_ll_resolv_local_irk_set(uint8_t own_addr_type, const uint8_t *irk) +{ + struct local_irk_data *irk_data; + int i; + + if (own_addr_type >= 2) { + return -1; + } + + irk_data = &g_local_irk[own_addr_type]; + + memcpy(irk_data->irk, irk, 16); + + irk_data->is_set = 0; + + for (i = 0; i < 16; i++) { + if (irk[i]) { + irk_data->is_set = 1; + break; + } + } + + if (irk_data->is_set) { + generate_rpa(irk_data->irk, irk_data->rpa); + } + + return 0; +} + +int +ble_ll_resolv_local_rpa_get(uint8_t own_addr_type, uint8_t *rpa) +{ + struct local_irk_data *irk_data; + + if (own_addr_type >= 2) { + return -1; + } + + irk_data = &g_local_irk[own_addr_type]; + + if (!irk_data->is_set) { + return -1; + } + + memcpy(rpa, irk_data->rpa, 6); + + return 0; +} +#endif + /** * Resolve a Resolvable Private Address * @@ -738,6 +822,10 @@ ble_ll_resolv_init(void) &g_ble_ll_data.ll_evq, ble_ll_resolv_rpa_timer_cb, NULL); + +#if MYNEWT_VAL(BLE_LL_HCI_VS_LOCAL_IRK) + memset(&g_local_irk, 0, sizeof(g_local_irk)); +#endif } #endif /* if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) */ diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 045cd50c5e..43f3682f70 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -402,6 +402,18 @@ syscfg.defs: value: 0 restrictions: - BLE_LL_HCI_VS if 1 + BLE_LL_HCI_VS_LOCAL_IRK: + description: > + Enables HCI command to set local IRK. + The local IRK is used by controller to generate RPA address in case + own address type 0x02 or 0x03 was requested by host but there is no + corresponding entry on resolving list. This allows to handle privacy + scenarios almost entirely in controller. If no local IRK is set, the + controller behaves as if feature is not enabled. + value: 0 + restrictions: + - BLE_LL_HCI_VS if 1 + BLE_LL_HCI_VS_EVENT_ON_ASSERT: description: > diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 742824d877..ba1735baa0 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1208,8 +1208,11 @@ struct ble_hci_vs_set_data_len_rp { struct ble_hci_vs_set_antenna_cp { uint8_t antenna; } __attribute__((packed)); - - +#define BLE_HCI_OCF_VS_SET_LOCAL_IRK (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x000A)) +struct ble_hci_vs_set_local_irk_cp { + uint8_t own_addr_type; + uint8_t irk[16]; +} __attribute__((packed)); /* Command Specific Definitions */ /* --- Set controller to host flow control (OGF 0x03, OCF 0x0031) --- */ From aa627397bf5ca216acd54e05fffee930a6dc5749 Mon Sep 17 00:00:00 2001 From: b4yuan <89487381+b4yuan@users.noreply.github.com> Date: Thu, 26 Oct 2023 07:22:52 -0400 Subject: [PATCH 0853/1333] Add CodeQL Workflow for Code Security Analysis This introduces a CodeQL workflow to enhance the security analysis of our repository. CodeQL is a powerful static analysis tool that helps identify and mitigate security vulnerabilities in our codebase. By integrating this workflow into our GitHub Actions, we can proactively identify and address potential issues before they become security threats. We added a new CodeQL workflow file (.github/workflows/codeql.yml) that - Runs on every push and pull request to the main branch. - Excludes queries with a high false positive rate or low-severity findings. - Does not display results for third-party code, focusing only on our own codebase. Testing: To validate the functionality of this workflow, we have run several test scans on the codebase and reviewed the results. The workflow successfully compiles the project, identifies issues, and provides actionable insights while reducing noise by excluding certain queries and third-party code. Deployment: Once this pull request is merged, the CodeQL workflow will be active and automatically run on every push and pull request to the main branch. To view the results of these code scans, please follow these steps: 1. Under the repository name, click on the Security tab. 2. In the left sidebar, click Code scanning alerts. Additional Information: - You can further customize the workflow to adapt to your specific needs by modifying the workflow file. - For more information on CodeQL and how to interpret its results, refer to the GitHub documentation and the CodeQL documentation. Signed-off-by: Brian --- .github/workflows/codeql-buildscript.sh | 8 ++ .github/workflows/codeql.yml | 126 ++++++++++++++++++++++++ .github/workflows/fail_on_error.py | 34 +++++++ 3 files changed, 168 insertions(+) create mode 100644 .github/workflows/codeql-buildscript.sh create mode 100644 .github/workflows/codeql.yml create mode 100755 .github/workflows/fail_on_error.py diff --git a/.github/workflows/codeql-buildscript.sh b/.github/workflows/codeql-buildscript.sh new file mode 100644 index 0000000000..46f73397f6 --- /dev/null +++ b/.github/workflows/codeql-buildscript.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +sudo apt-get update +sudo apt-get install -y make ccache gcc-multilib g++-multilib + +make -C porting/examples/dummy/ clean all +make -C porting/examples/linux/ clean all +make -C porting/examples/linux_blemesh/ clean all diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..816492278e --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,126 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + # push: + # branches: [ "main", "master" ] + schedule: + - cron: '0 0 * * *' + pull_request: + branches: '*' + +jobs: + analyze: + name: Analyze + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners + # Consider using larger runners for possible analysis time improvements. + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-20.04' }} + timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'cpp' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ] + # Use only 'java' to analyze code written in Java, Kotlin or both + # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + queries: security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). + # If this step fails, then you should remove it and run the build manually (see below) + #- name: Autobuild + # uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + - run: | + ./.github/workflows/codeql-buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" + upload: false + id: step1 + + # Filter out rules with low severity or high false positve rate + # Also filter out warnings in third-party code + - name: Filter out unwanted errors and warnings + uses: advanced-security/filter-sarif@v1 + with: + patterns: | + -**:cpp/path-injection + -**:cpp/world-writable-file-creation + -**:cpp/poorly-documented-function + -**:cpp/potentially-dangerous-function + -**:cpp/use-of-goto + -**:cpp/integer-multiplication-cast-to-long + -**:cpp/comparison-with-wider-type + -**:cpp/leap-year/* + -**:cpp/ambiguously-signed-bit-field + -**:cpp/suspicious-pointer-scaling + -**:cpp/suspicious-pointer-scaling-void + -**:cpp/unsigned-comparison-zero + -**/cmake*/Modules/** + input: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif + output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif + + - name: Upload CodeQL results to code scanning + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: ${{ steps.step1.outputs.sarif-output }} + category: "/language:${{matrix.language}}" + + - name: Upload CodeQL results as an artifact + if: success() || failure() + uses: actions/upload-artifact@v3 + with: + name: codeql-results + path: ${{ steps.step1.outputs.sarif-output }} + retention-days: 5 + + - name: Fail if an error is found + run: | + ./.github/workflows/fail_on_error.py \ + ${{ steps.step1.outputs.sarif-output }}/cpp.sarif diff --git a/.github/workflows/fail_on_error.py b/.github/workflows/fail_on_error.py new file mode 100755 index 0000000000..29791742b2 --- /dev/null +++ b/.github/workflows/fail_on_error.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 + +import json +import sys + +# Return whether SARIF file contains error-level results +def codeql_sarif_contain_error(filename): + with open(filename, 'r') as f: + s = json.load(f) + + for run in s.get('runs', []): + rules_metadata = run['tool']['driver']['rules'] + if not rules_metadata: + rules_metadata = run['tool']['extensions'][0]['rules'] + + for res in run.get('results', []): + if 'ruleIndex' in res: + rule_index = res['ruleIndex'] + elif 'rule' in res and 'index' in res['rule']: + rule_index = res['rule']['index'] + else: + continue + try: + rule_level = rules_metadata[rule_index]['defaultConfiguration']['level'] + except IndexError as e: + print(e, rule_index, len(rules_metadata)) + else: + if rule_level == 'error': + return True + return False + +if __name__ == "__main__": + if codeql_sarif_contain_error(sys.argv[1]): + sys.exit(1) From 2fe17d11a3cfb98add53edd430776594d779eeba Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Fri, 20 Oct 2023 17:48:14 +0200 Subject: [PATCH 0854/1333] host/store: add and update doxygen comments for the header file Adds missing structures and functions documentation. Moves the documentation entries from sources to the header file. --- nimble/host/include/host/ble_store.h | 434 ++++++++++++++++++++++++++- nimble/host/src/ble_store_util.c | 41 --- 2 files changed, 430 insertions(+), 45 deletions(-) diff --git a/nimble/host/include/host/ble_store.h b/nimble/host/include/host/ble_store.h index 24b208a09d..83b1c4f15f 100644 --- a/nimble/host/include/host/ble_store.h +++ b/nimble/host/include/host/ble_store.h @@ -20,6 +20,13 @@ #ifndef H_BLE_STORE_ #define H_BLE_STORE_ +/** + * @brief Bluetooth Store API + * @defgroup bt_store Bluetooth Store + * @ingroup bt_host + * @{ + */ + #include #include "nimble/ble.h" @@ -27,16 +34,35 @@ extern "C" { #endif +/** + * @defgroup bt_store_obj_types Bluetooth Store Object Types + * @ingroup bt_host + * @{ + */ +/** Object type: Our security material. */ #define BLE_STORE_OBJ_TYPE_OUR_SEC 1 + +/** Object type: Peer security material. */ #define BLE_STORE_OBJ_TYPE_PEER_SEC 2 + +/** Object type: Client Characteristic Configuration Descriptor. */ #define BLE_STORE_OBJ_TYPE_CCCD 3 +/** @} */ + +/** + * @defgroup bt_store_event_types Bluetooth Store Event Types + * @ingroup bt_host + * @{ + */ /** Failed to persist record; insufficient storage capacity. */ #define BLE_STORE_EVENT_OVERFLOW 1 /** About to execute a procedure that may fail due to overflow. */ #define BLE_STORE_EVENT_FULL 2 +/** @} */ + /** * Used as a key for lookups of security material. This struct corresponds to * the following store object types: @@ -61,21 +87,33 @@ struct ble_store_key_sec { * o BLE_STORE_OBJ_TYPE_PEER_SEC */ struct ble_store_value_sec { + /** Peer address for which the security material is stored. */ ble_addr_t peer_addr; + /** Encryption key size. */ uint8_t key_size; + /** Encrypted Diversifier used for encryption key generation. */ uint16_t ediv; + /** Random number used for encryption key generation. */ uint64_t rand_num; + /** Long Term Key. */ uint8_t ltk[16]; + /** Flag indicating whether Long Term Key is present. */ uint8_t ltk_present:1; + /** Identity Resolving Key. */ uint8_t irk[16]; + /** Flag indicating whether Identity Resolving Key is present. */ uint8_t irk_present:1; + /** Connection Signature Resolving Key. */ uint8_t csrk[16]; + /** Flag indicating if Connection Signature Resolving Key is present. */ uint8_t csrk_present:1; + /** Flag indicating whether the connection is authenticated. */ unsigned authenticated:1; + /** Flag indicating Secure Connections support. */ uint8_t sc:1; }; @@ -106,9 +144,13 @@ struct ble_store_key_cccd { * This struct corresponds to the BLE_STORE_OBJ_TYPE_CCCD store object type. */ struct ble_store_value_cccd { + /** The peer address associated with the stored CCCD. */ ble_addr_t peer_addr; + /** The handle of the characteristic value. */ uint16_t chr_val_handle; + /** Flags associated with the CCCD. */ uint16_t flags; + /** Flag indicating whether the value has changed. */ unsigned value_changed:1; }; @@ -117,7 +159,9 @@ struct ble_store_value_cccd { * object type code to indicate which field is valid. */ union ble_store_key { + /** Key for security material store lookups. */ struct ble_store_key_sec sec; + /** Key for Client Characteristic Configuration Descriptor store lookups. */ struct ble_store_key_cccd cccd; }; @@ -126,10 +170,13 @@ union ble_store_key { * code to indicate which field is valid. */ union ble_store_value { + /** Stored security material. */ struct ble_store_value_sec sec; + /** Stored Client Characteristic Configuration Descriptor. */ struct ble_store_value_cccd cccd; }; +/** Represents an event associated with the BLE Store. */ struct ble_store_status_event { /** * The type of event being reported; one of the BLE_STORE_EVENT_TYPE_[...] @@ -170,20 +217,26 @@ struct ble_store_status_event { }; }; -/* Generate LTK, EDIT and Rand */ +/** Generate LTK, EDIT and Rand. */ #define BLE_STORE_GEN_KEY_LTK 0x01 -/* Generate IRK */ +/** Generate IRK. */ #define BLE_STORE_GEN_KEY_IRK 0x02 -/* Generate CSRK */ +/** Generate CSRK. */ #define BLE_STORE_GEN_KEY_CSRK 0x03 +/** Represents a storage for generated key. */ struct ble_store_gen_key { union { + /** Long Term Key (LTK) for peripheral role. */ uint8_t ltk_periph[16]; + /** Identity Resolving Key (IRK). */ uint8_t irk[16]; + /** Connection Signature Resolving Key (CSRK). */ uint8_t csrk[16]; }; + /** Encrypted Diversifier (EDIV). */ uint16_t ediv; + /** Random Number for key generation. */ uint64_t rand; }; @@ -273,59 +326,432 @@ typedef int ble_store_delete_fn(int obj_type, const union ble_store_key *key); typedef int ble_store_status_fn(struct ble_store_status_event *event, void *arg); +/** + * Reads data from a storage. + * + * @param obj_type The type of the object to read. + * @param key Pointer to the key used for the lookup. + * @param val Pointer to store the retrieved data. + * + * @return 0 if the read operation is successful; + * Non-zero on error. + */ int ble_store_read(int obj_type, const union ble_store_key *key, union ble_store_value *val); + +/** + * Writes data to a storage. + * + * @param obj_type The type of the object to write. + * @param val Pointer to the data to be written. + * + * @return 0 if the write operation is successful; + * Non-zero on error. + */ int ble_store_write(int obj_type, const union ble_store_value *val); + +/** + * Deletes data from a storage. + * + * @param obj_type The type of the object to delete. + * @param key Pointer to the key used for the lookup. + * + * @return 0 if the deletion operation is successful; + * Non-zero on error. + */ int ble_store_delete(int obj_type, const union ble_store_key *key); + +/** + * @brief Handles a storage overflow event. + * + * This function is called when a storage overflow event occurs. It constructs + * an event structure and passes it to the general storage status handler using + * the `ble_store_status` function. + * + * @param obj_type The type of the object for which the overflow + * occurred. + * @param value Pointer to the value associated with the + * overflow. + * + * @return 0 if the event is successfully handled; + * Non-zero on error. + */ int ble_store_overflow_event(int obj_type, const union ble_store_value *value); + +/** + * @brief Handles a storage full event. + * + * This function is called when a storage full event occurs, typically during + * a write operation. It constructs an event structure and passes it to the + * general storage status handler using the `ble_store_status` function. + * + * @param obj_type The type of the object that may fail to be + * written. + * @param conn_handle The connection handle associated with the write + * operation. + * + * @return 0 if the event is successfully handled; + * Non-zero on error. + */ int ble_store_full_event(int obj_type, uint16_t conn_handle); +/** + * @brief Reads our security material from a storage. + * + * This function reads our security material from a storage, using the provided + * key and populates the `ble_store_value_sec` structure with the retrieved data. + * + * @param key_sec The key identifying the security material to + * read. + * @param value_sec A pointer to a `ble_store_value_sec` structure + * where the retrieved security material will + * be stored. + * + * @return 0 if the security material was successfully read + * from a storage; + * Non-zero on error. + */ int ble_store_read_our_sec(const struct ble_store_key_sec *key_sec, struct ble_store_value_sec *value_sec); + +/** + * @brief Writes our security material to a storage. + * + * This function writes our security material to a storage, using the provided + * `ble_store_value_sec` structure. + * + * @param value_sec A pointer to a `ble_store_value_sec` structure + * containing the security material to be + * stored. + * + * @return 0 if the security material was successfully + * written to a storage; + * Non-zero on error. + */ int ble_store_write_our_sec(const struct ble_store_value_sec *value_sec); + +/** + * @brief Deletes our security material from a storage. + * + * This function deletes our security material from a storage, identified by the + * provided `ble_store_key_sec`. + * + * @param key_sec A pointer to a `ble_store_key_sec` structure + * that specifies the security material to be + * deleted. + * + * @return 0 if the security material was successfully + * deleted from a storage; + * Non-zero on error. + */ int ble_store_delete_our_sec(const struct ble_store_key_sec *key_sec); + +/** + * @brief Reads peer security material from a storage. + * + * This function reads peer security material from a storage, identified by the + * provided `ble_store_key_sec`. The retrieved security material is stored in + * the `ble_store_value_sec` structure. + * + * @param key_sec A pointer to a `ble_store_key_sec` structure + * that specifies the peer's security material + * to be retrieved. + * @param value_sec A pointer to a `ble_store_value_sec` structure + * where the retrieved security material will + * be stored. + * + * @return 0 if the security material was successfully + * retrieved; + * Non-zero on error. + */ int ble_store_read_peer_sec(const struct ble_store_key_sec *key_sec, struct ble_store_value_sec *value_sec); + +/** + * @brief Writes peer security material to a storage. + * + * This function writes the provided peer security material, specified by a + * `ble_store_value_sec` structure, to a storage. Additionally, if the provided + * peer IRK is present and the peer address is not `BLE_ADDR_ANY`, it is also + * written to the controller's key cache. + * + * @param value_sec A pointer to a `ble_store_value_sec` structure + * containing the peer's security material + * to be written. + * + * @return 0 if the peer's security material was + * successfully written to a storage and + * the peer IRK was added to the controller key + * cache if present; + * Non-zero on error. + */ int ble_store_write_peer_sec(const struct ble_store_value_sec *value_sec); + +/** + * @brief Deletes peer security material from a storage. + * + * This function deletes the peer security material associated with the provided + * key from a storage. + * + * @param key_sec A pointer to a `ble_store_key_sec` structure + * identifying the security material to be + * deleted. + * + * @return 0 if the peer's security material was + * successfully deleted from a storage; + * Non-zero on error. + */ int ble_store_delete_peer_sec(const struct ble_store_key_sec *key_sec); + +/** + * @brief Reads a Client Characteristic Configuration Descriptor (CCCD) from + * a storage. + * + * This function reads a CCCD from a storage based on the provided key and + * stores the retrieved value in the specified output structure. + * + * @param key A pointer to a `ble_store_key_cccd` structure + * representing the key to identify the CCCD to + * be read. + * @param out_value A pointer to a `ble_store_value_cccd` structure + * to store the CCCD value read from a storage. + * + * @return 0 if the CCCD was successfully read and stored + * in the `out_value` structure; + * Non-zero on error. + */ int ble_store_read_cccd(const struct ble_store_key_cccd *key, struct ble_store_value_cccd *out_value); + +/** + * @brief Writes a Client Characteristic Configuration Descriptor (CCCD) to + * a storage. + * + * This function writes a CCCD to a storage based on the provided value. + * + * @param value A pointer to a `ble_store_value_cccd` structure + * representing the CCCD value to be written to + * a storage. + * + * @return 0 if the CCCD was successfully written to + * a storage; + * Non-zero on error. + */ int ble_store_write_cccd(const struct ble_store_value_cccd *value); + +/** + * @brief Deletes a Client Characteristic Configuration Descriptor (CCCD) from + * a storage. + * + * This function deletes a CCCD from a storage based on the provided key. + * + * @param key A pointer to a `ble_store_key_cccd` structure + * identifying the CCCD to be deleted from + * a storage. + * + * @return 0 if the CCCD was successfully deleted from + * a storage; + * Non-zero on error. + */ int ble_store_delete_cccd(const struct ble_store_key_cccd *key); + +/** + * @brief Generates a storage key for a security material entry from its value. + * + * This function generates a storage key for a security material entry based on + * the provided security material value. + * + * @param out_key A pointer to a `ble_store_key_sec` structure + * where the generated key will be stored. + * @param value A pointer to a `ble_store_value_sec` structure + * containing the security material value from + * which the key will be generated. + */ void ble_store_key_from_value_sec(struct ble_store_key_sec *out_key, const struct ble_store_value_sec *value); + +/** + * @brief Generates a storage key for a CCCD entry from its value. + * + * This function generates a storage key for a Client Characteristic + * Configuration Descriptor (CCCD) entry based on the provided CCCD value. + * + * @param out_key A pointer to a `ble_store_key_cccd` structure + * where the generated key will be stored. + * @param value A pointer to a `ble_store_value_cccd` structure + * containing the CCCD value from which the key + * will be generated. + */ void ble_store_key_from_value_cccd(struct ble_store_key_cccd *out_key, const struct ble_store_value_cccd *value); + +/** + * @brief Generates a storage key from a value based on the object type. + * + * This function generates a storage key from a value based on the provided + * object type. + * + * @param obj_type The type of object for which the key is + * generated. + * @param out_key A pointer to a `ble_store_key` union where + * the generated key will be stored. + * @param value A pointer to a `ble_store_value` union + * containing the value from which the key will + * be generated. + */ void ble_store_key_from_value(int obj_type, union ble_store_key *out_key, const union ble_store_value *value); + +/** + * @brief Function signature for the storage iterator callback. + * + * This function signature represents a callback function used for iterating + * over stored objects in a store. + * + * @param obj_type The type of object being iterated. + * @param val A pointer to the stored value of the object. + * @param cookie A user-defined pointer for additional data. + * + * @return 0 to continue iterating; + * Non-zero value to stop the iteration. + */ typedef int ble_store_iterator_fn(int obj_type, union ble_store_value *val, void *cookie); + +/** + * @brief Iterates over stored objects of a specific type in a store. + * + * This function allows you to iterate over stored objects of a specific type in + * the store and invoke a user-defined callback function for each object. + * + * @param obj_type The type of objects to iterate over. + * @param callback A pointer to the user-defined callback function + * that will be invoked for each stored object. + * @param cookie A user-defined pointer for additional data to + * pass to the callback function. + * + * @return 0 on success; + * Non-zero on error. + */ int ble_store_iterate(int obj_type, ble_store_iterator_fn *callback, void *cookie); + +/** + * @brief Clears all stored objects from a store. + * + * This function removes all stored objects from a store, effectively clearing + * the storage. + * + * @return 0 on success; + * Non-zero on error. + */ int ble_store_clear(void); -/*** Utility functions. */ +/** + * @defgroup ble_store_util Bluetooth Store Utility Functions + * @{ + */ +/** + * Retrieves the set of peer addresses for which a bond has been established. + * + * @param out_peer_id_addrs The set of bonded peer addresses. + * @param out_num_peers The number of bonds that have been established. + * @param max_peers The capacity of the destination buffer. + * + * @return 0 on success; + * BLE_HS_ENOMEM if the destination buffer is too + * small; + * Other non-zero on error. + */ int ble_store_util_bonded_peers(ble_addr_t *out_peer_id_addrs, int *out_num_peers, int max_peers); + +/** + * Deletes all entries from a store that match the specified key. + * + * @param type The type of store entry to delete. + * @param key Entries matching this key get deleted. + * + * @return 0 on success; + * Non-zero on error. + */ int ble_store_util_delete_all(int type, const union ble_store_key *key); + +/** + * Deletes all entries from a store that are attached to the specified peer + * address. This function deletes security entries and CCCD records. + * + * @param peer_id_addr Entries with this peer address get deleted. + * + * @return 0 on success; + * Non-zero on error. + */ int ble_store_util_delete_peer(const ble_addr_t *peer_id_addr); + +/** + * @brief Deletes the oldest peer from a store. + * + * This function deletes the oldest bonded peer from the storage. If there are + * no bonded peers in the storage, the function returns success. + * + * @return 0 on success; + * Non-zero on error. + */ int ble_store_util_delete_oldest_peer(void); + +/** + * @brief Counts the number of stored objects of a given type. + * + * This function counts the number of stored objects of a specific type in + * a store and returns the count in the `out_count` parameter. + * + * @param type The type of the objects to count. + * @param out_count The count of stored objects. + * + * @return 0 on success; + * Non-zero on error. + */ int ble_store_util_count(int type, int *out_count); + +/** + * @brief Round-robin status callback for handling store status events. + * + * This function handles store status events, particularly in cases where there + * is insufficient storage capacity for new records. + * It attempts to resolve overflow issues by deleting the oldest bond and + * proceeds with the persist operation. + * + * @note This behavior may not be suitable for production use as it may lead to + * removal of important bonds by less relevant peers. It is more useful for + * demonstration purposes and sample applications. + * + * @param event A pointer to the store status event. + * @param arg A pointer to additional user-defined arguments. + * + * @return 0 on success; + * Non-zero on error. + */ int ble_store_util_status_rr(struct ble_store_status_event *event, void *arg); +/** @} */ + #ifdef __cplusplus } #endif +/** + * @} + */ + #endif diff --git a/nimble/host/src/ble_store_util.c b/nimble/host/src/ble_store_util.c index 19b049a4c4..6dcbca25a1 100644 --- a/nimble/host/src/ble_store_util.c +++ b/nimble/host/src/ble_store_util.c @@ -59,20 +59,6 @@ ble_store_util_iter_unique_peer(int obj_type, return 0; } -/** - * Retrieves the set of peer addresses for which a bond has been established. - * - * @param out_peer_id_addrs On success, the set of bonded peer addresses - * gets written here. - * @param out_num_peers On success, the number of bonds gets written - * here. - * @param max_peers The capacity of the destination buffer. - * - * @return 0 on success; - * BLE_HS_ENOMEM if the destination buffer is too - * small; - * Other nonzero on error. - */ int ble_store_util_bonded_peers(ble_addr_t *out_peer_id_addrs, int *out_num_peers, int max_peers) @@ -96,15 +82,6 @@ ble_store_util_bonded_peers(ble_addr_t *out_peer_id_addrs, int *out_num_peers, return 0; } -/** - * Deletes all entries from the store that are attached to the specified peer - * address. This function deletes security entries and CCCD records. - * - * @param peer_id_addr Entries with this peer address get deleted. - * - * @return 0 on success; - * Other nonzero on error. - */ int ble_store_util_delete_peer(const ble_addr_t *peer_id_addr) { @@ -135,15 +112,6 @@ ble_store_util_delete_peer(const ble_addr_t *peer_id_addr) return 0; } -/** - * Deletes all entries from the store that match the specified key. - * - * @param type The type of store entry to delete. - * @param key Entries matching this key get deleted. - * - * @return 0 on success; - * Other nonzero on error. - */ int ble_store_util_delete_all(int type, const union ble_store_key *key) { @@ -216,15 +184,6 @@ ble_store_util_delete_oldest_peer(void) return 0; } -/** - * Round-robin status callback. If a there is insufficient storage capacity - * for a new record, delete the oldest bond and proceed with the persist - * operation. - * - * Note: This is not the best behavior for an actual product because - * uninteresting peers could cause important bonds to be deleted. This is - * useful for demonstrations and sample apps. - */ int ble_store_util_status_rr(struct ble_store_status_event *event, void *arg) { From 1f2fa515402d65991f9cad1c206cd79443be09a6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 10 Oct 2023 15:28:25 +0200 Subject: [PATCH 0855/1333] nimble/ll: Add counter for queued SDUs This avoid looping through queue to find number of SDUs in event. --- .../include/controller/ble_ll_isoal.h | 1 + nimble/controller/src/ble_ll_isoal.c | 23 ++++++++----------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_isoal.h b/nimble/controller/include/controller/ble_ll_isoal.h index 5104ea979e..73ceaf76d6 100644 --- a/nimble/controller/include/controller/ble_ll_isoal.h +++ b/nimble/controller/include/controller/ble_ll_isoal.h @@ -39,6 +39,7 @@ struct ble_ll_isoal_mux { uint8_t sdu_in_event; STAILQ_HEAD(, os_mbuf_pkthdr) sdu_q; + uint16_t sdu_q_len; struct os_mbuf *frag; diff --git a/nimble/controller/src/ble_ll_isoal.c b/nimble/controller/src/ble_ll_isoal.c index b028844316..3ccf986dd1 100644 --- a/nimble/controller/src/ble_ll_isoal.c +++ b/nimble/controller/src/ble_ll_isoal.c @@ -46,6 +46,7 @@ ble_ll_isoal_mux_init(struct ble_ll_isoal_mux *mux, uint8_t max_pdu, mux->sdu_per_event = (1 + pte) * mux->sdu_per_interval; STAILQ_INIT(&mux->sdu_q); + mux->sdu_q_len = 0; } void @@ -117,23 +118,14 @@ ble_ll_isoal_mux_tx_pkt_in(struct ble_ll_isoal_mux *mux, struct os_mbuf *om, OS_ENTER_CRITICAL(sr); pkthdr = OS_MBUF_PKTHDR(om); STAILQ_INSERT_TAIL(&mux->sdu_q, pkthdr, omp_next); + mux->sdu_q_len++; OS_EXIT_CRITICAL(sr); } int ble_ll_isoal_mux_event_start(struct ble_ll_isoal_mux *mux, uint32_t timestamp) { - struct os_mbuf_pkthdr *pkthdr; - uint8_t num_sdu; - - num_sdu = mux->sdu_per_event; - - pkthdr = STAILQ_FIRST(&mux->sdu_q); - while (pkthdr && num_sdu--) { - pkthdr = STAILQ_NEXT(pkthdr, omp_next); - } - - mux->sdu_in_event = mux->sdu_per_event - num_sdu; + mux->sdu_in_event = min(mux->sdu_q_len, mux->sdu_per_event); mux->event_tx_timestamp = timestamp; return mux->sdu_in_event; @@ -148,6 +140,7 @@ ble_ll_isoal_mux_event_done(struct ble_ll_isoal_mux *mux) struct os_mbuf *om_next; uint8_t num_sdu; int pkt_freed = 0; + os_sr_t sr; num_sdu = min(mux->sdu_in_event, mux->sdu_per_interval); @@ -160,8 +153,13 @@ ble_ll_isoal_mux_event_done(struct ble_ll_isoal_mux *mux) } while (pkthdr && num_sdu--) { - om = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); + OS_ENTER_CRITICAL(sr); + STAILQ_REMOVE_HEAD(&mux->sdu_q, omp_next); + BLE_LL_ASSERT(mux->sdu_q_len > 0); + mux->sdu_q_len--; + OS_EXIT_CRITICAL(sr); + om = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); while (om) { om_next = SLIST_NEXT(om, om_next); os_mbuf_free(om); @@ -169,7 +167,6 @@ ble_ll_isoal_mux_event_done(struct ble_ll_isoal_mux *mux) om = om_next; } - STAILQ_REMOVE_HEAD(&mux->sdu_q, omp_next); pkthdr = STAILQ_FIRST(&mux->sdu_q); } From 81faaa5c8f8cb676b75f4f9c91c5ece0170550a3 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 11 Oct 2023 01:38:10 +0200 Subject: [PATCH 0856/1333] nimble/ll: Add ISO sync feedback over HCI This adds optional synchronization feedback over HCI for ISO. See syscfg descrption for details. --- nimble/controller/src/ble_ll_iso_big.c | 64 ++++++++++++++++++++++++-- nimble/controller/syscfg.yml | 17 +++++++ nimble/include/nimble/hci_common.h | 12 +++++ 3 files changed, 88 insertions(+), 5 deletions(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index f9268d9721..e41f3f94c8 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -144,6 +144,10 @@ struct ble_ll_iso_big { struct ble_ll_iso_bis_q bis_q; +#if MYNEWT_VAL(BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS) + uint32_t last_feedback; +#endif + uint8_t cstf : 1; uint8_t cssn : 4; uint8_t control_active : 3; @@ -398,8 +402,16 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) { struct ble_ll_iso_bis *bis; struct ble_hci_ev *hci_ev; +#if MYNEWT_VAL(BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS) + struct ble_hci_ev *fb_hci_ev = NULL; + struct ble_hci_ev_vs *fb_hci_ev_vs; + struct ble_hci_vs_subev_iso_hci_feedback *fb_hci_subev = NULL; + uint16_t exp; + uint32_t now; +#endif struct ble_hci_ev_num_comp_pkts *hci_ev_ncp = NULL; int num_completed_pkt; + int idx; int rc; ble_ll_rfmgmt_release(); @@ -417,18 +429,49 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) hci_ev_ncp->count = 0; } +#if MYNEWT_VAL(BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS) + now = os_time_get(); + if (OS_TIME_TICK_GEQ(now, big->last_feedback + + os_time_ms_to_ticks32(MYNEWT_VAL(BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS)))) { + fb_hci_ev = ble_transport_alloc_evt(1); + if (fb_hci_ev) { + fb_hci_ev->opcode = BLE_HCI_EVCODE_VS; + fb_hci_ev->length = sizeof(*fb_hci_ev_vs) + sizeof(*fb_hci_subev); + fb_hci_ev_vs = (void *)fb_hci_ev->data; + fb_hci_ev_vs->id = BLE_HCI_VS_SUBEV_ISO_HCI_FEEDBACK; + fb_hci_subev = (void *)fb_hci_ev_vs->data; + fb_hci_subev->big_handle = big->handle; + fb_hci_subev->count = 0; + } + } +#endif + STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) { num_completed_pkt = ble_ll_isoal_mux_event_done(&bis->mux); if (hci_ev && num_completed_pkt) { - hci_ev_ncp->completed[hci_ev_ncp->count].handle = - htole16(bis->conn_handle); - hci_ev_ncp->completed[hci_ev_ncp->count].packets = - htole16(num_completed_pkt + bis->num_completed_pkt); + idx = hci_ev_ncp->count++; + hci_ev_ncp->completed[idx].handle = htole16(bis->conn_handle); + hci_ev_ncp->completed[idx].packets = htole16(num_completed_pkt + + bis->num_completed_pkt); bis->num_completed_pkt = 0; - hci_ev_ncp->count++; } else { bis->num_completed_pkt += num_completed_pkt; } + +#if MYNEWT_VAL(BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS) + if (fb_hci_ev) { + /* Expected SDUs in queue after an event -> host should send + * sdu_per_interval SDUs until next event so there are sdu_per_event + * SDUs queued at next event. Feedback value is the difference between + * expected and actual SDUs count. + */ + exp = bis->mux.sdu_per_event - bis->mux.sdu_per_interval; + idx = fb_hci_subev->count++; + fb_hci_subev->feedback[idx].handle = htole16(bis->conn_handle); + fb_hci_subev->feedback[idx].sdu_per_interval = bis->mux.sdu_per_interval; + fb_hci_subev->feedback[idx].diff = (int8_t)(bis->mux.sdu_q_len - exp); + } +#endif } if (hci_ev) { @@ -441,6 +484,15 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) } } +#if MYNEWT_VAL(BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS) + if (fb_hci_ev) { + fb_hci_ev->length = sizeof(*fb_hci_ev_vs) + sizeof(*fb_hci_subev) + + fb_hci_subev->count * sizeof(fb_hci_subev->feedback[0]); + ble_transport_to_hs_evt(fb_hci_ev); + big->last_feedback = now; + } +#endif + big->sch.start_time = big->event_start; big->sch.remainder = big->event_start_us; @@ -760,6 +812,8 @@ ble_ll_iso_big_event_sched_cb(struct ble_ll_sched_item *sch) ble_phy_mode_set(phy_mode, phy_mode); #endif + ble_ll_tx_power_set(g_ble_ll_tx_power); + BLE_LL_ASSERT(!big->framed); /* XXX calculate this in advance at the end of previous event? */ diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 43f3682f70..ae4b3c2402 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -485,6 +485,23 @@ syscfg.defs: - BLE_LL_ISO if 1 value: MYNEWT_VAL(BLE_ISO_BROADCASTER) state: experimental + BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS: + description: > + Enables ISO synchronization feedback using vendor-specific HCI event. + The event is sent at configured interval after completed ISO event + and contains BIG handle, number of expected SDUs per ISO interval + and difference between expected vs actual number of SDUs queued in + controller. + The expected number of SDUs queued after each event is number of + SDUs required for each ISO event (i.e. including pre-transmissions) + minus number of SDUs expected per each ISO interval. + The host can use feedback to e.g. adjust for jitter between audio + clock and LL clock. + Set to 0 to disable. + value: 0 + experimental: 1 + restrictions: + - BLE_LL_HCI_VS || BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS == 0 BLE_LL_SYSINIT_STAGE: description: > diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index ba1735baa0..aa7428d86a 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1614,6 +1614,18 @@ struct ble_hci_ev_vs_css_slot_changed { uint16_t slot_idx; }; +#define BLE_HCI_VS_SUBEV_ISO_HCI_FEEDBACK (0x03) +struct feedback_pkt { + uint16_t handle; + uint8_t sdu_per_interval; + int8_t diff; +} __attribute__((packed)); +struct ble_hci_vs_subev_iso_hci_feedback { + uint8_t big_handle; + uint8_t count; + struct feedback_pkt feedback[0]; +} __attribute__((packed)); + #define BLE_HCI_VS_SUBEV_ID_LLCP_TRACE (0x17) /* LE sub-event codes */ From f92361828f9bc0bc12884173af820f80483d0df6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 12 Oct 2023 19:06:04 +0200 Subject: [PATCH 0857/1333] nimble/ll: Add option to discard excessive ISO SDUs See syscfg description for details. --- nimble/controller/src/ble_ll_isoal.c | 14 ++++++++++++++ nimble/controller/syscfg.yml | 12 ++++++++++++ 2 files changed, 26 insertions(+) diff --git a/nimble/controller/src/ble_ll_isoal.c b/nimble/controller/src/ble_ll_isoal.c index 3ccf986dd1..fd9d205fe5 100644 --- a/nimble/controller/src/ble_ll_isoal.c +++ b/nimble/controller/src/ble_ll_isoal.c @@ -152,6 +152,20 @@ ble_ll_isoal_mux_event_done(struct ble_ll_isoal_mux *mux) mux->last_tx_packet_seq_num = blehdr->txiso.packet_seq_num; } +#if MYNEWT_VAL(BLE_LL_ISO_HCI_DISCARD_THRESHOLD) + /* Drop queued SDUs if number of queued SDUs exceeds defined threshold. + * Threshold is defined as number of ISO events. If number of queued SDUs + * exceeds number of SDUs required for single event (i.e. including pt) + * and number of subsequent ISO events defined by threshold value, we'll + * drop any excessive SDUs and notify host as if they were sent. + */ + uint32_t thr = MYNEWT_VAL(BLE_LL_ISO_HCI_DISCARD_THRESHOLD); + if (mux->sdu_q_len > mux->sdu_per_event + thr * mux->sdu_per_interval) { + num_sdu = mux->sdu_q_len - mux->sdu_per_event - + thr * mux->sdu_per_interval; + } +#endif + while (pkthdr && num_sdu--) { OS_ENTER_CRITICAL(sr); STAILQ_REMOVE_HEAD(&mux->sdu_q, omp_next); diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index ae4b3c2402..f125891744 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -502,6 +502,18 @@ syscfg.defs: experimental: 1 restrictions: - BLE_LL_HCI_VS || BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS == 0 + BLE_LL_ISO_HCI_DISCARD_THRESHOLD: + description: > + Enables automatic discarding of excessive ISO SDUs to avoid exhaustion + of HCI ISO buffers in case host sends too many SDUs. + Threshold is defined as number of ISO events. If number of queued + SDUs exceeds number of SDUs required for single event (i.e. including + pre-transmissions) and number of subsequent ISO events defined by + threshold value, the controller will drop any excessive SDUs and + notify to host as if they were already sent. + Set to 0 to disable. + value: 0 + experimental: 1 BLE_LL_SYSINIT_STAGE: description: > From d84b41eac17e2a7c829f9a4289791281f2fa0aaf Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 8 Nov 2023 17:21:50 +0100 Subject: [PATCH 0858/1333] nimble/ll: Split LL initialization This splits LL intiialization into two phases, one that initialize all LL internals and second that is called when LL side of transport is initialized. This makes sure that all internals are fully initialized before host sends any commands or LL sends any events (since HS side of transport is initialized before LL side) regardless of how much time pass between those HS and LL transport initialization. --- nimble/controller/pkg.yml | 5 +++++ nimble/controller/src/ble_ll.c | 8 +++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/nimble/controller/pkg.yml b/nimble/controller/pkg.yml index 5e43ba39db..2f22e3ebf5 100644 --- a/nimble/controller/pkg.yml +++ b/nimble/controller/pkg.yml @@ -41,3 +41,8 @@ pkg.deps: - "@apache-mynewt-core/crypto/tinycrypt" - nimble - nimble/transport + +pkg.init: + ble_ll_init: + - $before:ble_transport_hs_init + - $before:ble_transport_ll_init diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 620e1b1be7..998f8d4f03 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1371,9 +1371,6 @@ ble_ll_task(void *arg) MYNEWT_VAL(BLE_LL_TX_PWR_MAX_DBM))); g_ble_ll_tx_power_phy_current = INT8_MAX; - /* Tell the host that we are ready to receive packets */ - ble_ll_hci_send_noop(); - while (1) { ev = ble_npl_eventq_get(&g_ble_ll_data.ll_evq, BLE_NPL_TIME_FOREVER); BLE_LL_ASSERT(ev); @@ -1767,7 +1764,7 @@ ble_ll_assert(const char *file, unsigned line) * * @return int */ -static void +void ble_ll_init(void) { int rc; @@ -2003,7 +2000,8 @@ ble_transport_to_ll_iso_impl(struct os_mbuf *om) void ble_transport_ll_init(void) { - ble_ll_init(); + /* Tell the host that we are ready to receive packets */ + ble_ll_hci_send_noop(); } int From 512ed55ecd4a694644b83ac9971487f8131348e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 15 Nov 2023 14:19:23 +0100 Subject: [PATCH 0859/1333] controller/ble_ll_hci: fix ble_ll_hci_le_read_bufsize_v2 compilation ISO can be used without connection (for example for Auracast). Then, g_ble_ll_data has no ACL members and compilation will fail. --- nimble/controller/src/ble_ll_hci.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index af46653945..356869eee6 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -355,8 +355,14 @@ ble_ll_hci_le_read_bufsize_v2(uint8_t *rspbuf, uint8_t *rsplen) { struct ble_hci_le_rd_buf_size_v2_rp *rp = (void *) rspbuf; + +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) rp->data_len = htole16(g_ble_ll_data.ll_acl_pkt_size); rp->data_packets = g_ble_ll_data.ll_num_acl_pkts; +#else + rp->data_len = 0; + rp->data_packets = 0; +#endif rp->iso_data_len = htole16(g_ble_ll_data.ll_iso_pkt_size); rp->iso_data_packets = g_ble_ll_data.ll_num_iso_pkts; From d2059936b58be50612de92624320ffc1180a8605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 17 Nov 2023 13:51:32 +0100 Subject: [PATCH 0860/1333] apps/bttester: update Mesh commands BTP_MESH_INIT now only initialises Mesh. It expects additional field defining which composition data to use. For now it's parsed but ignored (we use always same composition data) Introduced BTP_MESH_START command that enables Mesh advertising, as before it was in BTP_MESH_INIT. Command may be longer now, because static_auth can be 32 octets long. Additional field `static_auth_length` is ignored for now, as we support only 16 octet long auth. --- apps/bttester/src/btp/btp_mesh.h | 8 +++++- apps/bttester/src/btp_mesh.c | 49 +++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/apps/bttester/src/btp/btp_mesh.h b/apps/bttester/src/btp/btp_mesh.h index 0a356e40ff..b51706ab1b 100644 --- a/apps/bttester/src/btp/btp_mesh.h +++ b/apps/bttester/src/btp/btp_mesh.h @@ -47,7 +47,8 @@ struct btp_mesh_read_supported_commands_rp { #define BTP_MESH_CONFIG_PROVISIONING 0x02 struct btp_mesh_config_provisioning_cmd { uint8_t uuid[16]; - uint8_t static_auth[16]; + uint8_t static_auth[32]; + uint8_t static_auth_length; uint8_t out_size; uint16_t out_actions; uint8_t in_size; @@ -66,6 +67,10 @@ struct btp_mesh_provision_node_cmd { } __packed; #define BTP_MESH_INIT 0x04 +struct btp_mesh_init_cmd { + uint8_t comp; +} __packed; + #define BTP_MESH_RESET 0x05 #define BTP_MESH_INPUT_NUMBER 0x06 struct btp_mesh_input_number_cmd { @@ -132,6 +137,7 @@ struct btp_mesh_lpn_unsubscribe_cmd { #define BTP_MESH_RPL_CLEAR 0x12 #define BTP_MESH_PROXY_IDENTITY 0x13 +#define BTP_MESH_START 0x78 /* events */ #define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80 diff --git a/apps/bttester/src/btp_mesh.c b/apps/bttester/src/btp_mesh.c index 96eaaf81f5..2dc3eb4d4c 100644 --- a/apps/bttester/src/btp_mesh.c +++ b/apps/bttester/src/btp_mesh.c @@ -458,26 +458,18 @@ static uint8_t init(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { + const struct btp_mesh_init_cmd *cp = cmd; int err; SYS_LOG_DBG(""); - err = bt_mesh_init(own_addr_type, &prov, &comp); - if (err) { + if (cmd_len != sizeof(*cp)) { return BTP_STATUS_FAILED; } - if (addr) { - err = bt_mesh_provision(net_key, net_key_idx, flags, iv_index, - addr, dev_key); - if (err) { - return BTP_STATUS_FAILED; - } - } else { - err = bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); - if (err) { - return BTP_STATUS_FAILED; - } + err = bt_mesh_init(own_addr_type, &prov, &comp); + if (err) { + return BTP_STATUS_FAILED; } return BTP_STATUS_SUCCESS; @@ -828,6 +820,30 @@ proxy_identity_enable(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +static uint8_t +start(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int err; + + SYS_LOG_DBG(""); + + if (addr) { + err = bt_mesh_provision(net_key, net_key_idx, flags, iv_index, + addr, dev_key); + if (err) { + return BTP_STATUS_FAILED; + } + } else { + err = bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); + if (err) { + return BTP_STATUS_FAILED; + } + } + + return BTP_STATUS_SUCCESS; +} + static const struct btp_handler handlers[] = { { .opcode = BTP_MESH_READ_SUPPORTED_COMMANDS, @@ -847,7 +863,7 @@ static const struct btp_handler handlers[] = { }, { .opcode = BTP_MESH_INIT, - .expect_len = 0, + .expect_len = 1, .func = init, }, { @@ -925,6 +941,11 @@ static const struct btp_handler handlers[] = { .expect_len = 0, .func = proxy_identity_enable, }, + { + .opcode = BTP_MESH_START, + .expect_len = 0, + .func = start, + }, }; void From 619032f52a093ace90dc6809df224a4b73ad4a71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 17 Nov 2023 14:45:52 +0100 Subject: [PATCH 0861/1333] apps/bttester: add TTL to model_send command Field was missing. --- apps/bttester/src/btp/btp_mesh.h | 1 + apps/bttester/src/btp_mesh.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/bttester/src/btp/btp_mesh.h b/apps/bttester/src/btp/btp_mesh.h index b51706ab1b..096c398060 100644 --- a/apps/bttester/src/btp/btp_mesh.h +++ b/apps/bttester/src/btp/btp_mesh.h @@ -119,6 +119,7 @@ struct btp_mesh_lpn_set_cmd { #define BTP_MESH_MODEL_SEND 0x0f struct btp_mesh_model_send_cmd { + uint8_t ttl; uint16_t src; uint16_t dst; uint8_t payload_len; diff --git a/apps/bttester/src/btp_mesh.c b/apps/bttester/src/btp_mesh.c index 2dc3eb4d4c..2825329aa6 100644 --- a/apps/bttester/src/btp_mesh.c +++ b/apps/bttester/src/btp_mesh.c @@ -707,7 +707,7 @@ model_send(const void *cmd, uint16_t cmd_len, .net_idx = net.net_idx, .app_idx = BT_MESH_KEY_DEV, .addr = sys_le16_to_cpu(cp->dst), - .send_ttl = BT_MESH_TTL_DEFAULT, + .send_ttl = cp->ttl, }; src = sys_le16_to_cpu(cp->src); From 7d4762b4e24041f49756d0a81adfed21beafd2ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 28 Nov 2023 10:50:16 +0100 Subject: [PATCH 0862/1333] controller: increase BLE_LL_STACK_SIZE for LE Audio Broadcast BIG encryption takes additional space on stack, due to crypto functions. --- nimble/controller/syscfg.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index f125891744..ae5e9373da 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -613,6 +613,9 @@ syscfg.vals.BLE_LL_CFG_FEAT_LL_EXT_ADV: BLE_HW_WHITELIST_ENABLE: 0 BLE_LL_SCAN_AUX_SEGMENT_CNT: 8 +syscfg.vals.BLE_LL_ISO_BROADCASTER: + BLE_LL_STACK_SIZE: 180 + # Enable vendor event on assert in standalone build to make failed assertions in # controller code visible when connected to external host syscfg.vals.'!BLE_HOST && !BABBLESIM': From 1d9e968ead8d1d1243de318bd619f099e68849a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 21 Nov 2023 13:16:44 +0100 Subject: [PATCH 0863/1333] ll/ble_ll_sched: fix preprocessor directives in ble_ll_sched_preempt BLE_LL_SCHED_TYPE_PERIODIC does not require BLE_LL_CFG_FEAT_LL_EXT_ADV. --- nimble/controller/src/ble_ll_sched.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 5cd01e04a5..bfec620d01 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -159,19 +159,19 @@ ble_ll_sched_preempt(struct ble_ll_sched_item *sch, case BLE_LL_SCHED_TYPE_SCAN_AUX: ble_ll_scan_aux_break(entry->cb_arg); break; +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) #if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) case BLE_LL_SCHED_TYPE_PERIODIC: ble_ll_adv_periodic_rmvd_from_sched(entry->cb_arg); break; #endif -#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) case BLE_LL_SCHED_TYPE_SYNC: ble_ll_sync_rmvd_from_sched(entry->cb_arg); break; #endif #endif -#endif #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) case BLE_LL_SCHED_TYPE_BIG: /* FIXME sometimes it may be useful to preempt... */ From 9fb79eb8557054ca2be006f0dbd5e96c663a4341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 20 Nov 2023 08:47:42 +0100 Subject: [PATCH 0864/1333] controller: fix build of ISO on nRF52 with connection disabled This fixes build of ISO when only Brodacster is enabled. `ble_phy_ccm_isr` is used ony when BLE_LL_CFG_FEAT_LE_ENCRYPTION (in ble_phy_init) BLE_LL_CFG_FEAT_LE_ENCRYPTION should be enabled when ISO is used, even connection-less ble_ll_conn_hci_rd_auth_pyld_tmo and ble_ll_conn_hci_wr_auth_pyld_tmo are built only with BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE enabled --- nimble/controller/src/ble_ll_hci.c | 3 ++- nimble/controller/syscfg.yml | 2 +- nimble/drivers/nrf5x/src/ble_phy.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 356869eee6..6e5f46891a 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1503,7 +1503,8 @@ ble_ll_hci_ctlr_bb_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, case BLE_HCI_OCF_CB_SET_EVENT_MASK2: rc = ble_ll_hci_cb_set_event_mask2(cmdbuf, len); break; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) +#if (MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL)) \ + && MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) case BLE_HCI_OCF_CB_RD_AUTH_PYLD_TMO: rc = ble_ll_conn_hci_rd_auth_pyld_tmo(cmdbuf, len, rspbuf, rsplen); break; diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index ae5e9373da..22a4c1b57c 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -242,7 +242,7 @@ syscfg.defs: description: > This option enables/disables encryption support in the controller. This option saves both both code and RAM. - value: 'MYNEWT_VAL_BLE_LL_ROLE_CENTRAL || MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL' + value: 'MYNEWT_VAL_BLE_LL_ROLE_CENTRAL || MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL || MYNEWT_VAL_BLE_LL_ISO' BLE_LL_CFG_FEAT_CONN_PARAM_REQ: description: > diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index a4d47cef7b..ec5507c9fa 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -1527,7 +1527,7 @@ ble_phy_isr(void) os_trace_isr_exit(); } -#if PHY_USE_HEADERMASK_WORKAROUND +#if PHY_USE_HEADERMASK_WORKAROUND && MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) static void ble_phy_ccm_isr(void) { From ebf69eed27fecc6c85520f88041a354f8de8268d Mon Sep 17 00:00:00 2001 From: Etienne Ruffieux Date: Wed, 29 Nov 2023 14:22:23 +0100 Subject: [PATCH 0865/1333] Fix identity address not being ble_addr_t --- apps/bttester/src/btp/btp_gap.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/bttester/src/btp/btp_gap.h b/apps/bttester/src/btp/btp_gap.h index f49173c6dc..2a87b12930 100644 --- a/apps/bttester/src/btp/btp_gap.h +++ b/apps/bttester/src/btp/btp_gap.h @@ -370,8 +370,7 @@ struct btp_gap_passkey_confirm_req_ev { #define BTP_GAP_EV_IDENTITY_RESOLVED 0x87 struct btp_gap_identity_resolved_ev { ble_addr_t address; - uint8_t identity_address_type; - uint8_t identity_address; + ble_addr_t identity_address; } __packed; #define BTP_GAP_EV_CONN_PARAM_UPDATE 0x88 From b0fdcb9d5014b4fa57b797e125b2c935708d1d06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 28 Sep 2023 13:42:51 +0200 Subject: [PATCH 0866/1333] nimble/host: Broadcast Source and Auracast API design This is a design of API that could be used to create BASE configuration manage its broadcast (setup extended advertising, periodic advertising and BASE advertisements, stop, resume, terminate and modify them) --- .../host/include/host/ble_audio_broadcast.h | 245 ++++++++++++++++++ nimble/host/include/host/ble_audio_common.h | 195 ++++++++++++++ nimble/host/include/host/ble_hs_adv.h | 6 + nimble/host/include/host/ble_iso.h | 127 +++++++++ .../services/auracast/ble_svc_auracast.h | 132 ++++++++++ 5 files changed, 705 insertions(+) create mode 100644 nimble/host/include/host/ble_audio_broadcast.h create mode 100644 nimble/host/include/host/ble_audio_common.h create mode 100644 nimble/host/include/host/ble_iso.h create mode 100644 nimble/host/services/auracast/include/services/auracast/ble_svc_auracast.h diff --git a/nimble/host/include/host/ble_audio_broadcast.h b/nimble/host/include/host/ble_audio_broadcast.h new file mode 100644 index 0000000000..acfc5734ec --- /dev/null +++ b/nimble/host/include/host/ble_audio_broadcast.h @@ -0,0 +1,245 @@ +/* + * 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_BLE_AUDIO_BROADCAST_ +#define H_BLE_AUDIO_BROADCAST_ + +#include +#include "host/ble_gap.h" +#include "host/ble_iso.h" +#include "host/ble_audio_common.h" + +struct ble_broadcast_create_params { + /** Broadcast Audio Source Endpoint */ + struct ble_audio_base *base; + + /** Parameters used to configure Extended advertising */ + struct ble_gap_ext_adv_params *extended_params; + + /** Parameters used to configure Periodic advertising */ + struct ble_gap_periodic_adv_params *periodic_params; + + /** Broadcast name - null terminated. + * Set NULL to not include in advertising. + * Length must be in range of 4 to 32 chars. + */ + const char *name; + + /** Advertising instance */ + uint8_t adv_instance; + + /** BIG parameters */ + struct ble_iso_big_params *big_params; + + /** Additional data to include in Extended Advertising */ + uint8_t *svc_data; + + /** Additional data length */ + uint16_t svc_data_len; +}; + +struct ble_broadcast_update_params { + /** Broadcast name - null terminated. + * Set NULL to not include in advertising + */ + const char *name; + + /** Advertising instance */ + uint8_t adv_instance; + + /** Additional data to include in Extended Advertising */ + uint8_t *svc_data; + + /** Additional data length */ + uint16_t svc_data_len; + + /** Broadcast ID */ + uint32_t broadcast_id; +}; + +typedef int ble_audio_broadcast_destroy_fn(struct ble_audio_base *base, + void *args); + +/** + * @brief Create Broadcast Audio Source Endpoint and configure advertising + * instance + * + * This function configures advertising instance for extended and periodic + * advertisements to be ready for broadcast with BASE configuration. + * + * @param[in] params Pointer to a `ble_broadcast_base_params` + * structure that defines BASE, extended + * advertising and periodic advertising + * configuration. + * @param[in] destroy_cb Optional callback to be invoked on + * `ble_audio_broadcast_destroy` call. + * @param[in] args Optional arguments to be passed to `destroy_cb` + * @param[in] gap_cb GAP event callback to be associated with BASE + * advertisement. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_broadcast_create(const struct ble_broadcast_create_params + *params, + ble_audio_broadcast_destroy_fn *destroy_cb, + void *args, + ble_gap_event_fn *gap_cb); + +/** + * @brief Start advertisements for given BASE configuration + * + * This function starts BASE advertisement by enabling extended, periodic + * and BIGInfo advertisements for this instance. + * + * @param[in] adv_instance Advertising instance used by broadcast. + * @param[in] cb Pointer to an ISO event handler. + * @param[in] cb_arg Arguments to an ISO event handler. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_broadcast_start(uint8_t adv_instance, + ble_iso_event_fn *cb, void *cb_arg); + +/** + * @brief Stop advertisements for given BASE configuration + * + * This function stops BASE advertisement by disabling extended and periodic + * advertising. Advertising instance is still configured and ready for resume. + * + * @param[in] adv_instance Advertising instance used by broadcast. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_broadcast_stop(uint8_t adv_instance); + +/** + * @brief Destroy advertisements for given BASE configuration + * + * This function terminates BASE advertisement instance. + * After return advertising instance is free and must be configured again + * for future advertisements. + * + * @param[in] adv_instance Advertising instance used by broadcast. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_broadcast_destroy(uint8_t adv_instance); + +/** + * @brief Update advertisements for given BASE configuration + * + * This function updates extended advertisements. + * + * @param[in] params Pointer to structure with new advertising data + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_broadcast_update(const struct ble_broadcast_update_params + *params); + +/** BIG Subgroup parameters */ +struct ble_broadcast_subgroup_params { + /** Subgroup level Codec information */ + struct ble_audio_codec_id *codec_id; + + /** Subgroup level Codec Specific Configuration */ + uint8_t *codec_spec_config; + + /** Subgroup level Codec Specific Configuration length */ + uint8_t codec_spec_config_len; + + /** Subgroup Metadata */ + uint8_t *metadata; + + /** Subgroup Metadata length*/ + uint8_t metadata_len; +}; + +/** + * @brief Build BIG subgroup structure + * + * This is a helper function can be used to fill out `ble_audio_big_subgroup` + * structure. Created subgroup extends subgroup list in provided BASE. + * This function increases `num_subgroups` in BASE structure. + * + * @param[in/out] base Pointer to a `ble_audio_base` structure, + * that will be extended by the new subgroup. + * In case of error, filled out data may be + * erroneous. + * @param[out] subgroup Pointer to a `ble_audio_big_subgroup` + * structure, that will be filled out with + * supplied configuration. In case of error, + * filled out data may be erroneous. + * @param[in] params Pointer to a `ble_broadcast_subgroup_params` + * structure, containing information about new + * subgroup + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_broadcast_build_sub(struct ble_audio_base *base, + struct ble_audio_big_subgroup *subgroup, + const struct ble_broadcast_subgroup_params + *params); + +/** BIS parameters */ +struct ble_broadcast_bis_params { + /** BIS index */ + uint8_t idx; + + /** BIS level Codec Specific Configuration */ + uint8_t *codec_spec_config; + + /** BIS level Codec Specific Configuration length */ + uint8_t codec_spec_config_len; +}; + +/** + * @brief Build BIS structure + * + * This is a helper function can be used to fill out `ble_broadcast_bis` + * structure. Created BIS extends BIS list in provided subgroup. + * This function increases `bis_cnt` in subgroup structure. + * + * @param[in/out] subgroup Pointer to a updated `ble_audio_big_subgroup` + * structure, that will be extended by the new + * BIS. In case of error, filled out data may be + * erroneous. + * @param[out] bis Pointer to a `ble_broadcast_bis` + * structure, that will be filled out with + * supplied configuration. In case of error, + * filled out data may be erroneous. + * @param[in] params Pointer to a `ble_broadcast_bis_params` + * structure, containing information about new + * BIS + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_broadcast_build_bis(struct ble_audio_big_subgroup *subgroup, + struct ble_audio_bis *bis, + const struct ble_broadcast_bis_params + *params); + +int ble_audio_broadcast_init(void); +#endif diff --git a/nimble/host/include/host/ble_audio_common.h b/nimble/host/include/host/ble_audio_common.h new file mode 100644 index 0000000000..43f88ea2ba --- /dev/null +++ b/nimble/host/include/host/ble_audio_common.h @@ -0,0 +1,195 @@ +/* + * 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_BLE_AUDIO_COMMON_ +#define H_BLE_AUDIO_COMMON_ + +#include "stdint.h" +#include "os/queue.h" + +/** Helper macros for BLE_AUDIO_BUILD_CODEC_CONFIG */ +#define FIELD_LEN_2(_len, _type, _field) _len, _type, _field, +#define FIELD_LEN_5(_len, _type, _field) _len, _type, _field, \ + _field >> 8, _field >> 16, \ + _field >> 24, + +#define FIELD_TESTED_0(_len, _type, _field) +#define FIELD_TESTED_1(_len, _type, _field) FIELD_LEN_ ## _len(_len, \ + _type, \ + _field) +#define EMPTY() FIELD_TESTED_0 +#define PRESENT(X) FIELD_TESTED_1 +#define TEST(x, A, FUNC, ...) FUNC +#define TEST_FIELD(...) TEST(, ## __VA_ARGS__, \ + PRESENT(__VA_ARGS__), \ + EMPTY(__VA_ARGS__)) +#define FIELD_TESTED(_test, _len, _type, _field) _test(_len, _type, _field) +#define OPTIONAL_FIELD(_len, _type, ...) FIELD_TESTED(TEST_FIELD \ + (__VA_ARGS__), \ + _len, \ + _type, \ + __VA_ARGS__) + +#define BLE_BROADCAST_AUDIO_ANNOUNCEMENT_SVC_UUID 0x1852 + +#define BLE_AUDIO_SAMPLING_RATE_8000_HZ 0x01 +#define BLE_AUDIO_SAMPLING_RATE_11025_HZ 0x02 +#define BLE_AUDIO_SAMPLING_RATE_16000_HZ 0x03 +#define BLE_AUDIO_SAMPLING_RATE_22050_HZ 0x04 +#define BLE_AUDIO_SAMPLING_RATE_24000_HZ 0x05 +#define BLE_AUDIO_SAMPLING_RATE_32000_HZ 0x06 +#define BLE_AUDIO_SAMPLING_RATE_44100_HZ 0x07 +#define BLE_AUDIO_SAMPLING_RATE_48000_HZ 0x08 +#define BLE_AUDIO_SAMPLING_RATE_88200_HZ 0x09 +#define BLE_AUDIO_SAMPLING_RATE_96000_HZ 0x0A +#define BLE_AUDIO_SAMPLING_RATE_176400_HZ 0x0B +#define BLE_AUDIO_SAMPLING_RATE_192000_HZ 0x0C +#define BLE_AUDIO_SAMPLING_RATE_384000_HZ 0x0D + +#define BLE_AUDIO_SELECTED_FRAME_DURATION_7_5_MS 0x00 +#define BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS 0x01 + +#define BLE_AUDIO_LOCATION_FRONT_LEFT (1ULL) +#define BLE_AUDIO_LOCATION_FRONT_RIGHT (1ULL << 1) +#define BLE_AUDIO_LOCATION_FRONT_CENTER (1ULL << 2) +#define BLE_AUDIO_LOCATION_LOW_FREQ_EFFECTS_1 (1ULL << 3) +#define BLE_AUDIO_LOCATION_BACK_LEFT (1ULL << 4) +#define BLE_AUDIO_LOCATION_FRONT_LEFT_CENTER (1ULL << 5) +#define BLE_AUDIO_LOCATION_FRONT_RIGHT_CENTER (1ULL << 6) +#define BLE_AUDIO_LOCATION_BACK_CENTER (1ULL << 7) +#define BLE_AUDIO_LOCATION_LOW_FREQ_EFFECTS_2 (1ULL << 8) +#define BLE_AUDIO_LOCATION_SIDE_LEFT (1ULL << 9) +#define BLE_AUDIO_LOCATION_SIDE_RIGHT (1ULL << 10) +#define BLE_AUDIO_LOCATION_TOP_FRONT_LEFT (1ULL << 11) +#define BLE_AUDIO_LOCATION_TOP_FRONT_RIGHT (1ULL << 12) +#define BLE_AUDIO_LOCATION_TOP_FRONT_CENTER (1ULL << 13) +#define BLE_AUDIO_LOCATION_TOP_CENTER (1ULL << 14) +#define BLE_AUDIO_LOCATION_TOP_BACK_LEFT (1ULL << 15) +#define BLE_AUDIO_LOCATION_TOP_BACK_RIGHT (1ULL << 16) +#define BLE_AUDIO_LOCATION_TOP_SIDE_LEFT (1ULL << 17) +#define BLE_AUDIO_LOCATION_TOP_SIDE_RIGHT (1ULL << 18) +#define BLE_AUDIO_LOCATION_TOP_BACK_CENTER (1ULL << 19) +#define BLE_AUDIO_LOCATION_BOTTOM_FRONT_CENTER (1ULL << 20) +#define BLE_AUDIO_LOCATION_BOTTOM_FRONT_LEFT (1ULL << 21) +#define BLE_AUDIO_LOCATION_BOTTOM_FRONT_RIGHT (1ULL << 22) +#define BLE_AUDIO_LOCATION_LEFT_SURROUND (1ULL << 23) +#define BLE_AUDIO_LOCATION_RIGHT_SURROUND (1ULL << 24) + +#define BLE_AUDIO_CODEC_SAMPLING_FREQ_TYPE 0x01 +#define BLE_AUDIO_CODEC_FRAME_DURATION_TYPE 0x02 +#define BLE_AUDIO_CODEC_AUDIO_CHANNEL_ALLOCATION_TYPE 0x03 +#define BLE_AUDIO_CODEC_OCTETS_PER_CODEC_FRAME_TYPE 0x04 +#define BLE_AUDIO_CODEC_FRAME_BLOCKS_PER_SDU_TYPE 0x05 + +/** + * @brief Helper macro used to build LTV array of Codec_Specific_Configuration. + * + * @param _sampling_freq Sampling_Frequency - single octet value + * @param _frame_duration Frame_Duration - single octet value + * @param _audio_channel_alloc Audio_Channel_Allocation - + * four octet value + * @param _octets_per_codec_frame Octets_Per_Codec_Frame - + * two octet value + * @param _codec_frame_blocks_per_sdu Codec_Frame_Blocks_Per_SDU - + * single octet value + * + * @return Pointer to a `ble_uuid16_t` structure. + */ +#define BLE_AUDIO_BUILD_CODEC_CONFIG(_sampling_freq, \ + _frame_duration, \ + _audio_channel_alloc, \ + _octets_per_codec_frame, \ + _codec_frame_blocks_per_sdu) \ + { \ + 2, BLE_AUDIO_CODEC_SAMPLING_FREQ_TYPE, _sampling_freq, \ + 2, BLE_AUDIO_CODEC_FRAME_DURATION_TYPE, _frame_duration, \ + OPTIONAL_FIELD(5, BLE_AUDIO_CODEC_AUDIO_CHANNEL_ALLOCATION_TYPE, \ + _audio_channel_alloc) \ + 3, BLE_AUDIO_CODEC_OCTETS_PER_CODEC_FRAME_TYPE, \ + (_octets_per_codec_frame), ((_octets_per_codec_frame) >> 8), \ + OPTIONAL_FIELD(2, BLE_AUDIO_CODEC_FRAME_BLOCKS_PER_SDU_TYPE, \ + _codec_frame_blocks_per_sdu) \ + } + +struct ble_audio_codec_id { + /** Coding Fromat */ + uint8_t format; + + /** Company ID */ + uint16_t company_id; + + /** Vendor Specific Codec ID */ + uint16_t vendor_specific; +}; + +struct ble_audio_bis { + /** Pointer to next BIS in subgroup */ + STAILQ_ENTRY(ble_audio_bis) next; + + /** BIS index */ + uint8_t idx; + + /** BIS level Codec Specific Configuration */ + uint8_t codec_spec_config_len; + + /** BIS level Codec Specific Configuration length */ + uint8_t *codec_spec_config; +}; + +struct ble_audio_big_subgroup { + /** Pointer to next subgroup in BIG */ + STAILQ_ENTRY(ble_audio_big_subgroup) next; + + /** Number of BISes in subgroup */ + uint8_t bis_cnt; + + /** Codec ID */ + struct ble_audio_codec_id codec_id; + + /** Subgroup level Codec Specific Configuration */ + uint8_t *codec_spec_config; + + /** Subgroup level Codec Specific Configuration length */ + uint8_t codec_spec_config_len; + + /** Subgroup Metadata */ + uint8_t *metadata; + + /** Subgroup Metadata length*/ + uint8_t metadata_len; + + /** Link list of BISes */ + STAILQ_HEAD(, ble_audio_bis) bises; +}; + +struct ble_audio_base { + /** Broadcast ID */ + uint32_t broadcast_id; + + /** Presentation Delay */ + uint32_t presentation_delay; + + /** Number of subgroups in BIG */ + uint8_t num_subgroups; + + /** Link list of subgroups */ + STAILQ_HEAD(, ble_audio_big_subgroup) subs; +}; + +#endif /* H_BLE_AUDIO_COMMON_ */ diff --git a/nimble/host/include/host/ble_hs_adv.h b/nimble/host/include/host/ble_hs_adv.h index fabeca64dc..a644add698 100644 --- a/nimble/host/include/host/ble_hs_adv.h +++ b/nimble/host/include/host/ble_hs_adv.h @@ -164,6 +164,12 @@ struct ble_hs_adv_fields { /** Length of manufacturer specific data. */ uint8_t mfg_data_len; + + /** 0x30 - Broadcast name. */ + const uint8_t *broadcast_name; + + /** Length of the Broadcast name. */ + uint8_t broadcast_name_len; }; /** diff --git a/nimble/host/include/host/ble_iso.h b/nimble/host/include/host/ble_iso.h new file mode 100644 index 0000000000..653b0acc79 --- /dev/null +++ b/nimble/host/include/host/ble_iso.h @@ -0,0 +1,127 @@ +/* + * 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_BLE_ISO_ +#define H_BLE_ISO_ +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(BLE_ISO) + +/** ISO event: BIG Create Completed */ +#define BLE_ISO_EVENT_BIG_CREATE_COMPLETE 0 + +/** ISO event: BIG Terminate Completed */ +#define BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE 1 + +#include + +struct ble_iso_big_desc +{ + uint8_t big_handle; + uint32_t big_sync_delay; + uint32_t transport_latency_big; + uint8_t phy; + uint8_t nse; + uint8_t bn; + uint8_t pto; + uint8_t irc; + uint16_t max_pdu; + uint16_t iso_interval; + uint8_t num_bis; + uint16_t conn_handle[MYNEWT_VAL(BLE_MAX_BIS)]; +}; + +/** + * Represents a ISO-related event. When such an event occurs, the host + * notifies the application by passing an instance of this structure to an + * application-specified callback. + */ +struct ble_iso_event { + /** + * Indicates the type of ISO event that occurred. This is one of the + * BLE_ISO_EVENT codes. + */ + uint8_t type; + + /** + * A discriminated union containing additional details concerning the ISO + * event. The 'type' field indicates which member of the union is valid. + */ + union { + /** + * Represents a completion of BIG creation. Valid for the following + * event types: + * o BLE_ISO_EVENT_BIG_CREATE_COMPLETE + */ + struct { + struct ble_iso_big_desc desc; + } big_created; + + /** + * Represents a completion of BIG termination. Valid for the following + * event types: + * o BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE + */ + struct { + uint16_t big_handle; + uint8_t reason; + } big_terminated; + }; +}; + +typedef int ble_iso_event_fn(struct ble_iso_event *event, void *arg); + +struct ble_iso_big_params { + uint32_t sdu_interval; + uint16_t max_sdu; + uint16_t max_transport_latency; + uint8_t rtn; + uint8_t phy; + uint8_t packing; + uint8_t framing; + uint8_t encryption; + const char *broadcast_code; +}; + +struct ble_iso_create_big_params { + uint8_t adv_handle; + uint8_t bis_cnt; + ble_iso_event_fn *cb; + void *cb_arg; +}; + +int ble_iso_create_big(const struct ble_iso_create_big_params *create_params, + const struct ble_iso_big_params *big_params); + +int ble_iso_terminate_big(uint8_t big_id); + +void +ble_gap_rx_create_big_complete(const struct + ble_hci_ev_le_subev_create_big_complete *ev); +void +ble_gap_rx_terminate_big_complete(const struct + ble_hci_ev_le_subev_terminate_big_complete + *ev); + +int ble_iso_tx(uint16_t conn_handle, void *data, uint16_t data_len); + +int ble_iso_init(void); + +#endif +#endif diff --git a/nimble/host/services/auracast/include/services/auracast/ble_svc_auracast.h b/nimble/host/services/auracast/include/services/auracast/ble_svc_auracast.h new file mode 100644 index 0000000000..7a31dfc3c6 --- /dev/null +++ b/nimble/host/services/auracast/include/services/auracast/ble_svc_auracast.h @@ -0,0 +1,132 @@ +/* + * 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. + */ + +#include +#include "host/ble_gap.h" +#include "host/ble_audio_common.h" +#include "host/ble_audio_broadcast.h" + +struct ble_svc_auracast_create_params { + /** Broadcast Audio Source Endpoint */ + struct ble_audio_base *base; + + /** BIG parameters */ + struct ble_iso_big_params *big_params; + + /** Broadcast name - null terminated. + * Set NULL to not include in advertising. + * Length must be in range of 4 to 32 chars. + */ + const char *name; + + /** Own address type to be used by advertising instance */ + uint8_t own_addr_type; + + /** PHY to be used for auxiliary advertisements */ + uint8_t secondary_phy; + + /** Advertising Set ID */ + uint8_t sid; + + /** Frame duration, in us */ + uint16_t frame_duration; + + /** sampling frequency, in Hz */ + uint16_t sampling_frequency; + + /** bitrate, in Hz */ + uint32_t bitrate; + + /** Program info - null terminated. + * Set NULL to not include in advertising. + */ + const char *program_info; +}; + +/** + * @brief Create Auracast Endpoint and configure advertising instance + * + * This function configures advertising instance for extended and periodic + * advertisements to be ready for Auracast broadcast. + * + * @param[in] params Pointer to a `ble_svc_auracast_create_params` + * structure that defines BIG and broadcast name. + * @param[out] auracast_instance Pointer to a advertising instance used by + * created Auracast. + * @param[in] destroy_cb Optional callback to be called when Auracast + * advertisement is destroyed. + * @param[in] args Optional arguments to be passed to `destroy_cb` + * @param[in] gap_cb GAP event callback to be associated with + * Auracast advertisement. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_svc_auracast_create(const struct + ble_svc_auracast_create_params *params, + uint8_t *auracast_instance, + ble_audio_broadcast_destroy_fn *destroy_cb, + void *args, + ble_gap_event_fn *gap_cb); +/** + * @brief Terminate all active advertisements and free resources associated + * with given Auracast broadcast. + * + * This function stops Auracast advertisement by disabling extended and + * periodic advertising and terminates them. After return advertising instance + * is free and must be configured again for future advertisements. + * + * @param[in] auracast_instance Pointer to a advertising instance used by + * Auracast. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_svc_auracast_terminate(uint8_t auracast_instance); + +/** + * @brief Start advertisements for given Auracast broadcast + * + * This function starts Auracast broadcast on by enabling extended and periodic + * advertising. + * + * @param[in] auracast_instance Pointer to a advertising instance used by + * Auracast. + * @param[in] cb Pointer to an ISO event handler. + * @param[in] cb_arg Arguments to an ISO event handler. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_svc_auracast_start(uint8_t auracast_instance, + ble_iso_event_fn *cb, void *cb_arg); + +/** + * @brief Stop advertisements for given Auracast broadcast + * + * This function stops Auracast broadcast by disabling extended and periodic + * advertising. Advertising instance is still configured and ready for resume. + * + * @param[in] auracast_instance Pointer to a advertising instance used by + * Auracast. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_svc_auracast_stop(uint8_t auracast_instance); From 7e7b4f00c46ce79adef4415d143369ec5f099b16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 20 Oct 2023 12:44:04 +0200 Subject: [PATCH 0867/1333] nimble/host: initial Broadcast source implementation This patch implements Broadcast feature in host. It includes implementation of ISO in host, with application API, HCI commands and ISO event handling. Host is now capable of managing BIGs with subgroups and BISes, updating Broadcast announcements and pushing data to ISO, to send in BIS events. Maximum extended advertising size was set to 251 to fit Periodic advertising data connected with Broadcast Audio Announcement Service advertisements by default. This patch does not implement Broadcast sink, only source. --- nimble/host/include/host/ble_hs.h | 1 + nimble/host/include/host/ble_hs_adv.h | 3 + nimble/host/include/host/ble_iso.h | 3 - nimble/host/src/ble_audio_broadcast.c | 486 ++++++++++++++++++++++++++ nimble/host/src/ble_hs.c | 10 + nimble/host/src/ble_hs_adv.c | 11 + nimble/host/src/ble_hs_hci_evt.c | 44 +++ nimble/host/src/ble_iso.c | 386 ++++++++++++++++++++ nimble/host/src/ble_iso_priv.h | 38 ++ nimble/host/syscfg.yml | 14 + 10 files changed, 993 insertions(+), 3 deletions(-) create mode 100644 nimble/host/src/ble_audio_broadcast.c create mode 100644 nimble/host/src/ble_iso.c create mode 100644 nimble/host/src/ble_iso_priv.h diff --git a/nimble/host/include/host/ble_hs.h b/nimble/host/include/host/ble_hs.h index 09900fd39d..5079648fad 100644 --- a/nimble/host/include/host/ble_hs.h +++ b/nimble/host/include/host/ble_hs.h @@ -43,6 +43,7 @@ #include "host/ble_sm.h" #include "host/ble_store.h" #include "host/ble_uuid.h" +#include "host/ble_iso.h" #include "nimble/nimble_npl.h" #ifdef __cplusplus diff --git a/nimble/host/include/host/ble_hs_adv.h b/nimble/host/include/host/ble_hs_adv.h index a644add698..b498f67542 100644 --- a/nimble/host/include/host/ble_hs_adv.h +++ b/nimble/host/include/host/ble_hs_adv.h @@ -249,6 +249,9 @@ struct ble_hs_adv_fields { /** Common Data Type: Mesh Beacon. */ #define BLE_HS_ADV_TYPE_MESH_BEACON 0x2b +/** Common Data Type: Broadcast Name. */ +#define BLE_HS_ADV_TYPE_BROADCAST_NAME 0x30 + /** Common Data Type: Manufacturer Specific Data. */ #define BLE_HS_ADV_TYPE_MFG_DATA 0xff diff --git a/nimble/host/include/host/ble_iso.h b/nimble/host/include/host/ble_iso.h index 653b0acc79..44877dca68 100644 --- a/nimble/host/include/host/ble_iso.h +++ b/nimble/host/include/host/ble_iso.h @@ -21,8 +21,6 @@ #define H_BLE_ISO_ #include "syscfg/syscfg.h" -#if MYNEWT_VAL(BLE_ISO) - /** ISO event: BIG Create Completed */ #define BLE_ISO_EVENT_BIG_CREATE_COMPLETE 0 @@ -124,4 +122,3 @@ int ble_iso_tx(uint16_t conn_handle, void *data, uint16_t data_len); int ble_iso_init(void); #endif -#endif diff --git a/nimble/host/src/ble_audio_broadcast.c b/nimble/host/src/ble_audio_broadcast.c new file mode 100644 index 0000000000..b3ec29ce21 --- /dev/null +++ b/nimble/host/src/ble_audio_broadcast.c @@ -0,0 +1,486 @@ +/* + * 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. + */ + +#include "host/ble_uuid.h" +#include "host/ble_audio_broadcast.h" + +#include "os/util.h" + +#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +struct ble_audio_broadcast { + SLIST_ENTRY(ble_audio_broadcast) next; + uint8_t adv_instance; + struct ble_audio_base *base; + struct ble_iso_big_params *big_params; + ble_audio_broadcast_destroy_fn *destroy_cb; + void *args; +}; + +static SLIST_HEAD(, ble_audio_broadcast) ble_audio_broadcasts; +static struct os_mempool ble_audio_broadcast_pool; +static os_membuf_t ble_audio_broadcast_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIG), + sizeof(struct ble_audio_broadcast))]; + +static bool +broadcast_bis_idx_ok(uint8_t bis_idx, struct ble_audio_base *base) +{ + struct ble_audio_big_subgroup *big; + struct ble_audio_bis *bis; + uint8_t idx_cnt = 0; + + STAILQ_FOREACH(big, &base->subs, next) { + STAILQ_FOREACH(bis, &big->bises, next) { + if (bis_idx == bis->idx) { + idx_cnt++; + } + } + } + + return idx_cnt == 1; +} + +static bool +broadcast_ltv_ok(uint8_t total_len, uint8_t *data) +{ + if (total_len == 0 && data == NULL) { + return true; + } + uint8_t len = data[0]; + uint8_t sum_len = 0; + + while (total_len > sum_len) { + sum_len += len + 1; + len = data[sum_len]; + } + + return total_len == sum_len; +} + +static struct ble_audio_broadcast * +ble_audio_broadcast_find(uint8_t adv_instance) +{ + struct ble_audio_broadcast *broadcast; + + SLIST_FOREACH(broadcast, &ble_audio_broadcasts, next) { + if (broadcast->adv_instance == adv_instance) { + return broadcast; + } + } + + return NULL; +} + +static struct ble_audio_broadcast * +ble_audio_broadcast_find_last() +{ + struct ble_audio_broadcast *broadcast; + + SLIST_FOREACH(broadcast, &ble_audio_broadcasts, next) { + } + + return broadcast; +} + +int +ble_audio_broadcast_create(const struct ble_broadcast_create_params *params, + ble_audio_broadcast_destroy_fn *destroy_cb, + void *args, + ble_gap_event_fn *gap_cb) +{ + int rc; + uint8_t offset = 2; + uint8_t service_data[5] = {0x52, 0x18 }; + uint8_t per_svc_data[MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE)] = { 0x51, 0x18 }; + struct ble_audio_big_subgroup *subgroup; + struct ble_audio_bis *bis; + struct ble_hs_adv_fields adv_fields = { + .broadcast_name = (uint8_t *) params->name, + .broadcast_name_len = params->name != NULL ? strlen(params->name) : 0, + .svc_data_uuid16 = service_data, + .svc_data_uuid16_len = sizeof(service_data), + }; + struct ble_hs_adv_fields per_adv_fields = { 0 }; + struct os_mbuf *adv_data; + ble_uuid16_t audio_announcement_uuid[1]; + uint8_t broadcast_id[3]; + struct ble_audio_broadcast *broadcast; + + if (strlen(params->name) < 4 || strlen(params->name) > 32) { + return BLE_HS_EINVAL; + } + + broadcast = ble_audio_broadcast_find(params->adv_instance); + if (broadcast) { + return BLE_HS_EALREADY; + } + + ble_hs_hci_rand(broadcast_id, 3); + params->base->broadcast_id = get_le24(broadcast_id); + + broadcast = os_memblock_get(&ble_audio_broadcast_pool); + + broadcast->adv_instance = params->adv_instance; + broadcast->base = params->base; + broadcast->big_params = params->big_params; + broadcast->destroy_cb = destroy_cb; + broadcast->args = args; + + if (SLIST_EMPTY(&ble_audio_broadcasts)) { + SLIST_INSERT_HEAD(&ble_audio_broadcasts, broadcast, next); + } else { + SLIST_INSERT_AFTER(ble_audio_broadcast_find_last(), broadcast, next); + } + + if (params->base->num_subgroups == 0) { + /** + * BAP specification 3.7.2.2 Basic Audio Announcements: + * Rule 1: There shall be at least one subgroup. + */ + BLE_HS_LOG_ERROR("No subgroups in BASE!\n"); + return BLE_HS_EINVAL; + } + + put_le24(&service_data[2], broadcast->base->broadcast_id); + put_le24(&per_svc_data[offset], params->base->presentation_delay); + offset += 3; + per_svc_data[offset] = params->base->num_subgroups; + offset++; + + STAILQ_FOREACH(subgroup, ¶ms->base->subs, next) { + if (subgroup->bis_cnt == 0) { + /** + * BAP specification 3.7.2.2 Basic Audio Announcements: + * Rule 2: There shall be at least one BIS per subgroup. + */ + BLE_HS_LOG_ERROR("No BIS in BIG!\n"); + return BLE_HS_EINVAL; + } + + if (!broadcast_ltv_ok(subgroup->metadata_len, subgroup->metadata)) { + BLE_HS_LOG_ERROR("Invalid Metadata!\n"); + return BLE_HS_EINVAL; + } + + if (!broadcast_ltv_ok(subgroup->codec_spec_config_len, subgroup->codec_spec_config)) { + BLE_HS_LOG_ERROR("Invalid Codec Configuration in subgroup!\n"); + return BLE_HS_EINVAL; + } + + per_svc_data[offset] = subgroup->bis_cnt; + offset++; + memcpy(&per_svc_data[offset], &subgroup->codec_id, 5); + offset += 5; + per_svc_data[offset] = subgroup->codec_spec_config_len; + offset++; + memcpy(&per_svc_data[offset], &subgroup->codec_spec_config, + subgroup->codec_spec_config_len); + offset += subgroup->codec_spec_config_len; + per_svc_data[offset] = subgroup->metadata_len; + offset++; + memcpy(&per_svc_data[offset], &subgroup->metadata, + subgroup->metadata_len); + offset += subgroup->metadata_len; + STAILQ_FOREACH(bis, &subgroup->bises, next) { + if (!broadcast_bis_idx_ok(bis->idx, params->base)) { + /** + * BAP specification 3.7.2.2 Basic Audio Announcements: + * Rule 3: Every BIS in the BIG, denoted by its BIS_index + * value, shall only be present in one subgroup. + */ + BLE_HS_LOG_ERROR("Duplicated BIS index!\n"); + return BLE_HS_EINVAL; + } + + if (!broadcast_ltv_ok(bis->codec_spec_config_len, + bis->codec_spec_config)) { + BLE_HS_LOG_ERROR("Invalid Codec Configuration in BIS!\n"); + return BLE_HS_EINVAL; + } + per_svc_data[offset] = bis->idx; + offset++; + per_svc_data[offset] = bis->codec_spec_config_len; + offset++; + memcpy(&per_svc_data[offset], bis->codec_spec_config, + bis->codec_spec_config_len); + offset += bis->codec_spec_config_len; + } + } + + audio_announcement_uuid[0] = (ble_uuid16_t) BLE_UUID16_INIT(BLE_BROADCAST_AUDIO_ANNOUNCEMENT_SVC_UUID); + per_adv_fields.uuids16 = audio_announcement_uuid; + per_adv_fields.num_uuids16 = 1; + per_adv_fields.uuids16_is_complete = 1; + per_adv_fields.svc_data_uuid16 = per_svc_data; + per_adv_fields.svc_data_uuid16_len = offset; + + rc = ble_gap_ext_adv_configure(params->adv_instance, + params->extended_params, 0, + gap_cb, NULL); + if (rc) { + BLE_HS_LOG_ERROR("Could not configure the broadcast (rc=%d)\n", rc); + return 0; + } + + adv_data = os_msys_get_pkthdr(BLE_HCI_MAX_EXT_ADV_DATA_LEN, 0); + if (!adv_data) { + BLE_HS_LOG_ERROR("No memory\n"); + return BLE_HS_ENOMEM; + } + + /* Set ext advertising data */ + rc = ble_hs_adv_set_fields_mbuf(&adv_fields, adv_data); + if (rc) { + BLE_HS_LOG_ERROR("Failed to set extended advertising fields" + "(rc=%d)\n", rc); + return rc; + } + + os_mbuf_append(adv_data, params->svc_data, params->svc_data_len); + + rc = ble_gap_ext_adv_set_data(params->adv_instance, adv_data); + if (rc) { + BLE_HS_LOG_ERROR("Failed to set extended advertising data" + "(rc=%d)\n", rc); + return rc; + } + + /* Clear buffer */ + adv_data = os_msys_get_pkthdr(BLE_HCI_MAX_EXT_ADV_DATA_LEN, 0); + if (!adv_data) { + BLE_HS_LOG_ERROR("No memory\n"); + return BLE_HS_ENOMEM; + } + + rc = ble_gap_periodic_adv_configure(params->adv_instance, params->periodic_params); + if (rc) { + BLE_HS_LOG_ERROR("failed to configure periodic advertising" + "(rc=%d)\n", rc); + return rc; + } + + rc = ble_hs_adv_set_fields_mbuf(&per_adv_fields, adv_data); + if (rc) { + BLE_HS_LOG_ERROR("Failed to set periodic advertising fields" + "(rc=%d)\n", rc); + return rc; + } + + rc = ble_gap_periodic_adv_set_data(params->adv_instance, adv_data, NULL); + if (rc) { + BLE_HS_LOG_ERROR("Failed to set periodic advertising data" + "(rc=%d)\n", rc); + } + + return rc; +} + +int +ble_audio_broadcast_start(uint8_t adv_instance, + ble_iso_event_fn *cb, void *cb_arg) +{ + struct ble_audio_big_subgroup *subgroup; + struct ble_iso_create_big_params create_big_params = { 0 }; + struct ble_audio_broadcast *broadcast; + int rc; + + broadcast = ble_audio_broadcast_find(adv_instance); + if (!broadcast) { + return BLE_HS_ENOENT; + } + + STAILQ_FOREACH(subgroup, &broadcast->base->subs, next) { + create_big_params.bis_cnt += subgroup->bis_cnt; + } + + create_big_params.adv_handle = broadcast->adv_instance; + create_big_params.cb = cb; + create_big_params.cb_arg = cb_arg; + + rc = ble_gap_ext_adv_start(broadcast->adv_instance, 0, 0); + if (rc) { + BLE_HS_LOG_ERROR("Failed to start extended advertising (rc=%d)\n", rc); + return rc; + } + + rc = ble_gap_periodic_adv_start(broadcast->adv_instance, NULL); + if (rc) { + BLE_HS_LOG_ERROR("Failed to start periodic advertising (rc=%d)\n", rc); + return rc; + } + + rc = ble_iso_create_big(&create_big_params, broadcast->big_params); + if (rc) { + BLE_HS_LOG_ERROR("Failed to create BIG (rc=%d)\n", rc); + return rc; + } + + return 0; +} + +int +ble_audio_broadcast_stop(uint8_t adv_instance) +{ + int rc; + + rc = ble_gap_ext_adv_stop(adv_instance); + if (rc) { + BLE_HS_LOG_ERROR("Failed to stop extended advertising (rc=%d)\n", rc); + return rc; + } + + rc = ble_gap_periodic_adv_stop(adv_instance); + if (rc) { + BLE_HS_LOG_ERROR("Failed to stop periodic advertising (rc=%d)\n", rc); + return rc; + } + + return 0; +} + +int +ble_audio_broadcast_destroy(uint8_t adv_instance) +{ + struct ble_audio_broadcast *broadcast; + int rc; + + broadcast = ble_audio_broadcast_find(adv_instance); + if (!broadcast) { + return BLE_HS_ENOENT; + } + + rc = ble_gap_ext_adv_remove(adv_instance); + if (rc) { + BLE_HS_LOG_ERROR("Failed to remove extended advertising\n"); + return rc; + } + + rc = ble_iso_terminate_big(adv_instance); + if (rc) { + BLE_HS_LOG_ERROR("Failed to terminate BIG\n"); + return rc; + } + + os_memblock_put(&ble_audio_broadcast_pool, broadcast); + SLIST_REMOVE(&ble_audio_broadcasts, broadcast, ble_audio_broadcast, next); + + return 0; +} + +int +ble_audio_broadcast_update(const struct ble_broadcast_update_params *params) +{ + uint8_t service_data[5] = {0x52, 0x18 }; + struct ble_hs_adv_fields adv_fields = { + .broadcast_name = (uint8_t *) params->name, + .broadcast_name_len = params->name != NULL ? strlen(params->name) : 0, + .svc_data_uuid16 = service_data, + .svc_data_uuid16_len = sizeof(service_data) + }; + struct os_mbuf *adv_data; + int rc; + + if (strlen(params->name) < 4 || strlen(params->name) > 32) { + return BLE_HS_EINVAL; + } + + memcpy(&service_data[2], ¶ms->broadcast_id, 3); + + adv_data = os_msys_get_pkthdr(BLE_HCI_MAX_EXT_ADV_DATA_LEN, 0); + + os_mbuf_append(adv_data, params->svc_data, params->svc_data_len); + + /* Set ext advertising data */ + rc = ble_hs_adv_set_fields_mbuf(&adv_fields, adv_data); + if (rc) { + BLE_HS_LOG_ERROR("Failed to set extended advertising fields\n"); + return rc; + } + + rc = ble_gap_ext_adv_set_data(params->adv_instance, adv_data); + if (rc) { + BLE_HS_LOG_ERROR("Failed to set extended advertising data\n"); + return rc; + } + + return 0; +} + +int +ble_audio_broadcast_build_sub(struct ble_audio_base *base, + struct ble_audio_big_subgroup *sub, + const struct ble_broadcast_subgroup_params + *params) +{ + sub->codec_id = *params->codec_id; + memcpy(sub->codec_spec_config, params->codec_spec_config, + params->codec_spec_config_len); + sub->codec_spec_config_len = params->codec_spec_config_len; + memcpy(sub->metadata, params->metadata, + params->metadata_len); + sub->metadata_len = params->metadata_len; + + if (STAILQ_EMPTY(&base->subs)) { + STAILQ_INSERT_HEAD(&base->subs, sub, next); + } else { + STAILQ_INSERT_TAIL(&base->subs, sub, next); + } + + base->num_subgroups++; + return 0; +} + +int +ble_audio_broadcast_build_bis(struct ble_audio_big_subgroup *sub, + struct ble_audio_bis *bis, + const struct ble_broadcast_bis_params + *params) +{ + bis->idx = params->idx; + memcpy(bis->codec_spec_config, params->codec_spec_config, + params->codec_spec_config_len); + bis->codec_spec_config_len = params->codec_spec_config_len; + + if (STAILQ_EMPTY(&sub->bises)) { + STAILQ_INSERT_HEAD(&sub->bises, bis, next); + } else { + STAILQ_INSERT_TAIL(&sub->bises, bis, next); + } + + sub->bis_cnt++; + return 0; +} + + +int +ble_audio_broadcast_init(void) +{ + int rc; + + SLIST_INIT(&ble_audio_broadcasts); + + rc = os_mempool_init(&ble_audio_broadcast_pool, + MYNEWT_VAL(BLE_MAX_BIG), + sizeof(struct ble_audio_broadcast), + ble_audio_broadcast_mem, "ble_audio_broadcast_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); + + return 0; +} +#endif diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index bab8fe1116..41bf5e2c3a 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -24,6 +24,7 @@ #include "syscfg/syscfg.h" #include "stats/stats.h" #include "host/ble_hs.h" +#include "host/ble_audio_broadcast.h" #include "ble_hs_priv.h" #include "nimble/nimble_npl.h" #ifndef MYNEWT @@ -752,6 +753,15 @@ ble_hs_init(void) SYSINIT_PANIC_ASSERT(rc == 0); #endif +#if MYNEWT_VAL(BLE_ISO) + rc = ble_iso_init(); + SYSINIT_PANIC_ASSERT(rc == 0); +#if MYNEWT_VAL(BLE_ISO_BROADCASTER) + rc = ble_audio_broadcast_init(); + SYSINIT_PANIC_ASSERT(rc == 0); +#endif +#endif + ble_hs_stop_init(); ble_mqueue_init(&ble_hs_rx_q, ble_hs_event_rx_data, NULL); diff --git a/nimble/host/src/ble_hs_adv.c b/nimble/host/src/ble_hs_adv.c index 1d938b958c..44c28c0cc6 100644 --- a/nimble/host/src/ble_hs_adv.c +++ b/nimble/host/src/ble_hs_adv.c @@ -354,6 +354,17 @@ adv_set_fields(const struct ble_hs_adv_fields *adv_fields, } } + /*** 0x30 - Broadcast name. */ + if (adv_fields->broadcast_name != NULL && adv_fields->broadcast_name_len > 0) { + rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_BROADCAST_NAME, + adv_fields->broadcast_name_len, + adv_fields->broadcast_name, dst, + &dst_len_local, max_len, om); + if (rc != 0) { + return rc; + } + } + /*** 0x16 - Service data - 16-bit UUID. */ if (adv_fields->svc_data_uuid16 != NULL && adv_fields->svc_data_uuid16_len) { rc = ble_hs_adv_set_flat_mbuf(BLE_HS_ADV_TYPE_SVC_DATA_UUID16, diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index a128e3ab6b..49a0993c3e 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -23,7 +23,9 @@ #include "os/os.h" #include "nimble/hci_common.h" #include "host/ble_gap.h" +#include "host/ble_iso.h" #include "ble_hs_priv.h" +#include "ble_iso_priv.h" _Static_assert(sizeof (struct hci_data_hdr) == BLE_HCI_DATA_HDR_SZ, "struct hci_data_hdr must be 4 bytes"); @@ -63,6 +65,10 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_rpt; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_lost; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_scan_req_rcvd; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_transfer; +#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_create_big_complete; +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_terminate_big_complete; +#endif #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_biginfo_adv_report; #endif @@ -131,6 +137,12 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = { [BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED] = ble_hs_hci_evt_le_adv_set_terminated, [BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD] = ble_hs_hci_evt_le_scan_req_rcvd, [BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_TRANSFER] = ble_hs_hci_evt_le_periodic_adv_sync_transfer, +#if MYNEWT_VAL(BLE_ISO_BROADCASTER) + [BLE_HCI_LE_SUBEV_CREATE_BIG_COMPLETE] = + ble_hs_hci_evt_le_create_big_complete, + [BLE_HCI_LE_SUBEV_TERMINATE_BIG_COMPLETE] = + ble_hs_hci_evt_le_terminate_big_complete, +#endif #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) [BLE_HCI_LE_SUBEV_BIGINFO_ADV_REPORT] = ble_hs_hci_evt_le_biginfo_adv_report, #endif @@ -735,6 +747,38 @@ ble_hs_hci_evt_le_periodic_adv_sync_transfer(uint8_t subevent, const void *data, return 0; } +#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +static int +ble_hs_hci_evt_le_create_big_complete(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_create_big_complete *ev = data; + + if (len != sizeof(*ev) + (ev->num_bis * sizeof(ev->conn_handle[0]))) { + return BLE_HS_EBADDATA; + } + + ble_iso_rx_create_big_complete(ev); + + return 0; +} + +static int +ble_hs_hci_evt_le_terminate_big_complete(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_terminate_big_complete *ev = data; + + if (len != sizeof(*ev)) { + return BLE_HS_EBADDATA; + } + + ble_iso_rx_terminate_big_complete(ev); + + return 0; +} +#endif + #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) static int ble_hs_hci_evt_le_biginfo_adv_report(uint8_t subevent, const void *data, diff --git a/nimble/host/src/ble_iso.c b/nimble/host/src/ble_iso.c new file mode 100644 index 0000000000..ba0fd3056c --- /dev/null +++ b/nimble/host/src/ble_iso.c @@ -0,0 +1,386 @@ +/* + * 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. + */ + +#include +#include "syscfg/syscfg.h" +#include "ble_hs_mbuf_priv.h" + +#if MYNEWT_VAL(BLE_ISO) + +#include "os/os_mbuf.h" +#include "host/ble_hs_log.h" +#include "host/ble_hs.h" +#include "host/ble_iso.h" +#include "nimble/hci_common.h" +#include "sys/queue.h" +#include "ble_hs_hci_priv.h" + +struct ble_iso_big { + SLIST_ENTRY(ble_iso_big) next; + uint8_t id; + uint16_t max_pdu; + uint8_t num_bis; + uint16_t conn_handles[MYNEWT_VAL(BLE_MAX_BIS)]; + + ble_iso_event_fn *cb; + void *cb_arg; +}; + +static SLIST_HEAD(, ble_iso_big) ble_iso_bigs; +static struct os_mempool ble_iso_big_pool; +static os_membuf_t ble_iso_big_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIG), sizeof (struct ble_iso_big))]; + +static struct ble_iso_big * +ble_iso_big_alloc(uint8_t adv_handle) +{ + struct ble_iso_big *new_big; + struct ble_iso_big *big; + + if (adv_handle >= BLE_ADV_INSTANCES) { + BLE_HS_LOG_ERROR("Invalid advertising instance"); + return NULL; + } + + if (!ble_gap_ext_adv_active(adv_handle)) { + BLE_HS_LOG_ERROR("Instance not active"); + return NULL; + } + + new_big = os_memblock_get(&ble_iso_big_pool); + if (new_big == NULL) { + BLE_HS_LOG_ERROR("No more memory in pool"); + /* Out of memory. */ + return NULL; + } + + memset(new_big, 0, sizeof *new_big); + + SLIST_FOREACH(big, &ble_iso_bigs, next) { + if (big->id == adv_handle) { + BLE_HS_LOG_ERROR("Advertising instance (%d) already in use", + adv_handle); + return NULL; + } + } + + new_big->id = adv_handle; + + if (SLIST_EMPTY(&ble_iso_bigs)) { + SLIST_INSERT_HEAD(&ble_iso_bigs, new_big, next); + } else { + SLIST_INSERT_AFTER(big, new_big, next); + } + + return new_big; +} + +static struct ble_iso_big * +ble_iso_big_find_by_id(uint8_t big_id) +{ + struct ble_iso_big *big; + + SLIST_FOREACH(big, &ble_iso_bigs, next) { + if (big->id == big_id) { + return big; + } + } + + return NULL; +} + +static int +ble_iso_big_free(struct ble_iso_big *big) +{ + SLIST_REMOVE(&ble_iso_bigs, big, ble_iso_big, next); + os_memblock_put(&ble_iso_big_pool, big); + return 0; +} + +int +ble_iso_create_big(const struct ble_iso_create_big_params *create_params, + const struct ble_iso_big_params *big_params) +{ + struct ble_hci_le_create_big_cp cp = { 0 }; + struct ble_iso_big *big; + + big = ble_iso_big_alloc(create_params->adv_handle); + if (big == NULL) { + return BLE_HS_ENOENT; + } + + big->cb = create_params->cb; + big->cb_arg = create_params->cb_arg; + + cp.big_handle = create_params->adv_handle; + + cp.adv_handle = create_params->adv_handle; + if (create_params->bis_cnt > MYNEWT_VAL(BLE_MAX_BIS)) { + return BLE_HS_EINVAL; + } + + cp.num_bis = create_params->bis_cnt; + put_le24(cp.sdu_interval, big_params->sdu_interval); + cp.max_sdu = big_params->max_sdu; + cp.max_transport_latency = big_params->max_transport_latency; + cp.rtn = big_params->rtn; + cp.phy = big_params->phy; + cp.packing = big_params->packing; + cp.framing = big_params->framing; + cp.encryption = big_params->encryption; + if (big_params->encryption) { + memcpy(cp.broadcast_code, big_params->broadcast_code, 16); + } + + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CREATE_BIG), + &cp, sizeof(cp),NULL, 0); +} + +int +ble_iso_terminate_big(uint8_t big_id) +{ + struct ble_hci_le_terminate_big_cp cp; + struct ble_iso_big *big; + int rc; + + big = ble_iso_big_find_by_id(big_id); + if (big == NULL) { + BLE_HS_LOG_ERROR("No BIG with id=%d\n", big_id); + return BLE_HS_ENOENT; + } + + cp.big_handle = big->id; + cp.reason = BLE_ERR_CONN_TERM_LOCAL; + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_TERMINATE_BIG), + &cp, sizeof(cp),NULL, 0); + + return rc; +} + +int +ble_iso_init(void) +{ + int rc; + + SLIST_INIT(&ble_iso_bigs); + + rc = os_mempool_init(&ble_iso_big_pool, + MYNEWT_VAL(BLE_MAX_BIG), + sizeof (struct ble_iso_big), + ble_iso_big_mem, "ble_iso_big_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); + + return 0; +} + +void +ble_iso_rx_create_big_complete(const struct ble_hci_ev_le_subev_create_big_complete *ev) +{ + struct ble_iso_event event; + + struct ble_iso_big *big; + int i; + + big = ble_iso_big_find_by_id(ev->big_handle); + + big->num_bis = ev->num_bis; + + for (i = 0; i < ev->num_bis; i++) { + big->conn_handles[i] = ev->conn_handle[i]; + } + + big->max_pdu = ev->max_pdu; + + event.type = BLE_ISO_EVENT_BIG_CREATE_COMPLETE; + event.big_created.desc.big_handle = ev->big_handle; + event.big_created.desc.big_sync_delay = get_le24(ev->big_sync_delay); + event.big_created.desc.transport_latency_big = + get_le24(ev->transport_latency_big); + event.big_created.desc.phy = ev->phy; + event.big_created.desc.nse = ev->nse; + event.big_created.desc.bn = ev->bn; + event.big_created.desc.pto = ev->pto; + event.big_created.desc.irc = ev->irc; + event.big_created.desc.max_pdu = ev->max_pdu; + event.big_created.desc.iso_interval = ev->iso_interval; + event.big_created.desc.num_bis = ev->num_bis; + memcpy(event.big_created.desc.conn_handle, ev->conn_handle, + ev->num_bis * sizeof(uint16_t)); + + if (big->cb != NULL) { + big->cb(&event, big->cb_arg); + } +} + +void +ble_iso_rx_terminate_big_complete(const struct ble_hci_ev_le_subev_terminate_big_complete *ev) +{ + struct ble_iso_event event; + struct ble_iso_big *big; + + big = ble_iso_big_find_by_id(ev->big_handle); + + event.type = BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE; + event.big_terminated.big_handle = ev->big_handle; + event.big_terminated.reason = ev->reason; + + if (big->cb != NULL) { + big->cb(&event, big->cb_arg); + } + + ble_iso_big_free(big); +} + +static int +ble_iso_tx_complete(uint16_t conn_handle, const uint8_t *data, + uint16_t data_len) +{ + struct os_mbuf *om; + int rc; + + om = ble_hs_mbuf_bare_pkt(); + if (!om) { + return BLE_HS_ENOMEM; + } + + os_mbuf_extend(om, 8); + /* Connection_Handle, PB_Flag, TS_Flag */ + put_le16(&om->om_data[0], + BLE_HCI_ISO_HANDLE(conn_handle, BLE_HCI_ISO_PB_COMPLETE, 0)); + /* Data_Total_Length = Data length + Packet_Sequence_Number placeholder */ + put_le16(&om->om_data[2], data_len + 4); + /* Packet_Sequence_Number placeholder */ + put_le16(&om->om_data[4], 0); + /* ISO_SDU_Length */ + put_le16(&om->om_data[6], data_len); + + rc = os_mbuf_append(om, data, data_len); + if (rc) { + return rc; + } + + return ble_transport_to_ll_iso(om); +} + +static int +ble_iso_tx_segmented(uint16_t conn_handle, uint16_t max_pdu, + const uint8_t *data, uint16_t data_len) +{ + struct os_mbuf *om; + uint16_t data_left = data_len; + uint16_t packet_len; + uint16_t offset = 0; + uint8_t pb; + uint8_t ts; + int rc; + + while (data_left) { + packet_len = min(max_pdu - (BLE_HCI_DATA_HDR_SZ + 4), data_left); + if (data_left == data_len) { + pb = BLE_HCI_ISO_PB_FIRST; + ts = 1; + } else if (packet_len == data_left) { + pb = BLE_HCI_ISO_PB_LAST; + ts = 0; + } else { + pb = BLE_HCI_ISO_PB_CONTINUATION; + ts = 0; + } + + om = ble_hs_mbuf_bare_pkt(); + if (!om) { + return BLE_HS_ENOMEM; + } + + os_mbuf_extend(om, ts == 1 ? 10: 8); + + /* Connection_Handle, PB_Flag, TS_Flag */ + put_le16(&om->om_data[0], + BLE_HCI_ISO_HANDLE(conn_handle, pb, ts)); + /* Data_Total_Length = Data length + + * Packet_Sequence_Number placeholder + + * optional timestamp*/ + put_le16(&om->om_data[2], packet_len + 4 + 2 * ts); + + if (ts) { + /* Timestamp placeholder */ + put_le16(&om->om_data[4], 0); + + /* Packet_Sequence_Number placeholder */ + put_le16(&om->om_data[6], 0); + + /* ISO_SDU_Length */ + put_le16(&om->om_data[8], packet_len); + } + + /* Packet_Sequence_Number placeholder */ + put_le16(&om->om_data[4], 0); + /* ISO_SDU_Length */ + put_le16(&om->om_data[6], packet_len); + + rc = os_mbuf_append(om, data + offset, packet_len); + if (rc) { + return rc; + } + + ble_transport_to_ll_iso(om); + + offset += packet_len; + data_len -= packet_len; + } + + return 0; +} + +int +ble_iso_tx(uint16_t conn_handle, const uint8_t *data, uint16_t data_len) +{ + struct ble_iso_big *big; + uint16_t max_pdu = 0; + int rc; + int i; + + SLIST_FOREACH(big, &ble_iso_bigs, next) { + for (i = 0; i < big->num_bis; i++) { + if (big->conn_handles[i] == conn_handle) { + max_pdu = big->max_pdu; + break; + } + } + if (max_pdu > 0) { + break; + } + } + + if (!max_pdu) { + return BLE_HS_ENOENT; + } + + if (data_len <= max_pdu) { + rc = ble_iso_tx_complete(conn_handle, data, data_len); + } else { + rc = ble_iso_tx_segmented(conn_handle, max_pdu, data, data_len); + } + + return rc; +} +#endif diff --git a/nimble/host/src/ble_iso_priv.h b/nimble/host/src/ble_iso_priv.h new file mode 100644 index 0000000000..fb0a6aab3e --- /dev/null +++ b/nimble/host/src/ble_iso_priv.h @@ -0,0 +1,38 @@ +/* + * 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_BLE_ISO_PRIV_ +#define H_BLE_ISO_PRIV_ + +#include "nimble/hci_common.h" +#ifdef __cplusplus +extern "C" { +#endif + +void +ble_iso_rx_create_big_complete(const struct ble_hci_ev_le_subev_create_big_complete *ev); + +void +ble_iso_rx_terminate_big_complete(const struct ble_hci_ev_le_subev_terminate_big_complete *ev); + +#ifdef __cplusplus +} +#endif + +#endif /* H_BLE_ISO_PRIV_ */ diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index f667eee985..558e31e8d2 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -486,6 +486,20 @@ syscfg.defs: supported by host. value: 0 + BLE_MAX_BIG: + desciptrion: > + Number of available BIGs + value: 'MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES' + restrictions: + - 'BLE_ISO_BROADCASTER if 0' + + BLE_MAX_BIS: + description: > + Number of supported BISes + value: 4 + restrictions: + - 'BLE_ISO_BROADCASTER if 0' + ### Log settings. BLE_HS_LOG_MOD: From a621805349979bf32ca687a6ef55dd47ed83203b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 20 Oct 2023 12:50:39 +0200 Subject: [PATCH 0868/1333] apps/btshell: implement Broadcast source API This patch adds commands to btshell to allow creating BIGs, BIG subgroups and BISe and create and manage Broadcast advertisements. --- apps/btshell/src/btshell.h | 33 +++ apps/btshell/src/cmd.c | 193 +++++++++++++++++ apps/btshell/src/cmd_leaudio.c | 385 +++++++++++++++++++++++++++++++++ apps/btshell/src/cmd_leaudio.h | 46 ++++ apps/btshell/src/main.c | 359 ++++++++++++++++++++++++++++++ nimble/host/src/ble_iso.c | 63 ++---- 6 files changed, 1033 insertions(+), 46 deletions(-) create mode 100644 apps/btshell/src/cmd_leaudio.c create mode 100644 apps/btshell/src/cmd_leaudio.h diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h index 021f54c88d..17b07458a9 100644 --- a/apps/btshell/src/btshell.h +++ b/apps/btshell/src/btshell.h @@ -28,6 +28,9 @@ #include "host/ble_gatt.h" #include "host/ble_gap.h" +#if (MYNEWT_VAL(BLE_ISO_BROADCASTER)) +#include "host/ble_audio_broadcast.h" +#endif #ifdef __cplusplus extern "C" { @@ -182,6 +185,36 @@ int btshell_l2cap_send(uint16_t conn, uint16_t idx, uint16_t bytes); int btshell_l2cap_reconfig(uint16_t conn_handle, uint16_t mtu, uint8_t num, uint8_t idxs[]); +#if (MYNEWT_VAL(BLE_ISO_BROADCASTER)) +int btshell_broadcast_base_add(uint8_t adv_instance, uint32_t presentation_delay); +int btshell_broadcast_big_sub_add(uint8_t adv_instance, + uint8_t codec_fmt, + uint16_t company_id, + uint16_t vendor_spec, + uint8_t *metadata, + unsigned int metadata_len, + uint8_t *codec_spec_cfg, + unsigned int codec_spec_cfg_len); +int btshell_broadcast_bis_add(uint8_t adv_instance, + uint8_t *codec_spec_cfg, + unsigned int codec_spec_cfg_len); +int btshell_broadcast_create(uint8_t adv_instance, + struct ble_gap_ext_adv_params *ext_params, + struct ble_gap_periodic_adv_params + *per_params, + const char *name, + struct ble_iso_big_params big_params, + uint8_t *extra_data, + unsigned int extra_data_len); +int btshell_broadcast_destroy(uint8_t adv_instance); +int btshell_broadcast_update(uint8_t adv_instance, + const char *name, + uint8_t *extra_data, + unsigned int extra_data_len); +int btshell_broadcast_start(uint8_t adv_instance); +int btshell_broadcast_stop(uint8_t adv_instance); +#endif + int btshell_gap_event(struct ble_gap_event *event, void *arg); void btshell_sync_stats(uint16_t handle); uint8_t btshell_get_default_own_addr_type(void); diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index 1bdd48e89d..bba5022dfd 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -42,6 +42,7 @@ #include "btshell.h" #include "cmd_gatt.h" #include "cmd_l2cap.h" +#include "cmd_leaudio.h" #define BTSHELL_MODULE "btshell" @@ -4168,6 +4169,140 @@ static const struct shell_cmd_help sync_stats_help = { #endif #endif +#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +#if MYNEWT_VAL(SHELL_CMD_HELP) +static const struct shell_param leaudio_base_add_params[] = { + {"adv_instance", "Advertising instance, usage: ="}, + { "presentation_delay", "usage: =" }, + + { NULL, NULL} +}; + +static const struct shell_cmd_help leaudio_base_add_help = { + .summary = "Add BASE configuration for broadcast", + .usage = NULL, + .params = leaudio_base_add_params, +}; + +static const struct shell_param leaudio_big_sub_add_params[] = { + {"adv_instance", "Advertising instance, usage: ="}, + { "codec_fmt", "usage: " }, + { "company_id", "usage: =" }, + { "vendor_spec", "usage: =" }, + { "codec_spec_config", "usage: =[XX:XX...]" }, + { "metadata", "usage: =[XX:XX...]" }, + + { NULL, NULL} +}; + +static const struct shell_cmd_help leaudio_big_sub_add_help = { + .summary = "Add BIG subgroup configuration for broadcast", + .usage = NULL, + .params = leaudio_big_sub_add_params, +}; + +static const struct shell_param leaudio_bis_add_params[] = { + {"adv_instance", "Advertising instance, usage: ="}, + { "codec_spec_config", "usage: =[XX:XX...]" }, + + { NULL, NULL} +}; + +static const struct shell_cmd_help leaudio_bis_add_help = { + .summary = "Add BIS configuration for broadcast announcements to last " + "added BIG subgroup", + .usage = NULL, + .params = leaudio_bis_add_params, +}; + +static const struct shell_param leaudio_broadcast_create_params[] = { + {"adv_instance", "Advertising instance, usage: ="}, + {"ext_interval_min", "usage: =[0-UINT16_MAX], default: 0"}, + {"ext_interval_max", "usage: =[0-UINT16_MAX], default: 0"}, + {"per_interval_min", "usage: =[0-UINT16_MAX], default: 0"}, + {"per_interval_max", "usage: =[0-UINT16_MAX], default: 0"}, + + {"name", "usage: =[string]"}, + + {"sdu_interval", "SDU interval, in us, usage: ="}, + {"max_sdu", "max SDU size, in octets, usage: ="}, + {"max_latency", "max transport latency, in ms, usage: ="}, + {"rtn", "RTN, usage: ="}, + {"phy", "PHY, usage: ="}, + {"packing", "packing, optional, true if not given, usage: ="}, + {"framing", "framing, optional, false if not given, usage: ="}, + {"encryption", "optional, encryption, usage: ="}, + {"broadcast_code", "optional, obligatory if encryption is enabled, " + "usage: =, len=16 octets"}, + {"extra_data", "usage: =[XX:XX...]"}, + + { NULL, NULL} +}; + +static const struct shell_cmd_help leaudio_broadcast_create_help = { + .summary = "Add BIS configuration for broadcast to last added BIG " + "subgroup", + .usage = NULL, + .params = leaudio_broadcast_create_params, +}; + +static const struct shell_param leaudio_broadcast_destroy_params[] = { + {"adv_instance", "Advertising instance, usage: ="}, + + { NULL, NULL} +}; + +static const struct shell_cmd_help leaudio_broadcast_destroy_help = { + .summary = "Destroy BASE", + .usage = NULL, + + .params = leaudio_broadcast_destroy_params, +}; + +static const struct shell_param leaudio_broadcast_update_params[] = { + {"adv_instance", "Advertising instance, usage: ="}, + {"name", "usage: =[string]"}, + {"extra_data_len", "usage: ="}, + {"extra_data", "usage: =[XX:XX...]"}, + + { NULL, NULL} +}; + +static const struct shell_cmd_help leaudio_broadcast_update_help = { + .summary = "Update broadcast", + .usage = NULL, + + .params = leaudio_broadcast_update_params, +}; + +static const struct shell_param leaudio_broadcast_start_params[] = { + {"adv_instance", "Advertising instance, usage: ="}, + + { NULL, NULL} +}; + +static const struct shell_cmd_help leaudio_broadcast_start_help = { + .summary = "Start broadcast", + .usage = NULL, + + .params = leaudio_broadcast_start_params, +}; + +static const struct shell_param leaudio_broadcast_stop_params[] = { + {"adv_instance", "Advertising instance, usage: ="}, + + { NULL, NULL} +}; + +static const struct shell_cmd_help leaudio_broadcast_stop_help = { + .summary = "Stop broadcast", + .usage = NULL, + + .params = leaudio_broadcast_stop_params, +}; +#endif +#endif + static const struct shell_cmd btshell_commands[] = { #if MYNEWT_VAL(BLE_EXT_ADV) { @@ -4664,6 +4799,64 @@ static const struct shell_cmd btshell_commands[] = { #endif }, #endif +#endif +#if MYNEWT_VAL(BLE_ISO) + { + .sc_cmd = "base_add", + .sc_cmd_func = cmd_leaudio_base_add, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &leaudio_base_add_help, +#endif + }, + { + .sc_cmd = "big_sub_add", + .sc_cmd_func = cmd_leaudio_big_sub_add, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &leaudio_big_sub_add_help, +#endif + }, + { + .sc_cmd = "bis_add", + .sc_cmd_func = cmd_leaudio_bis_add, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &leaudio_bis_add_help, +#endif + }, + { + .sc_cmd = "broadcast_create", + .sc_cmd_func = cmd_leaudio_broadcast_create, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &leaudio_broadcast_create_help, +#endif + }, + { + .sc_cmd = "broadcast_destroy", + .sc_cmd_func = cmd_leaudio_broadcast_destroy, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &leaudio_broadcast_destroy_help, +#endif + }, + { + .sc_cmd = "broadcast_update", + .sc_cmd_func = cmd_leaudio_broadcast_update, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &leaudio_broadcast_update_help, +#endif + }, + { + .sc_cmd = "broadcast_start", + .sc_cmd_func = cmd_leaudio_broadcast_start, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &leaudio_broadcast_start_help, +#endif + }, + { + .sc_cmd = "broadcast_stop", + .sc_cmd_func = cmd_leaudio_broadcast_stop, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &leaudio_broadcast_stop_help, +#endif + }, #endif { 0 }, }; diff --git a/apps/btshell/src/cmd_leaudio.c b/apps/btshell/src/cmd_leaudio.c new file mode 100644 index 0000000000..bdbc825843 --- /dev/null +++ b/apps/btshell/src/cmd_leaudio.c @@ -0,0 +1,385 @@ +/* + * 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. + */ + +#include "host/ble_audio_broadcast.h" +#include "cmd_leaudio.h" +#include "btshell.h" +#include "console/console.h" +#include "errno.h" + +#if (MYNEWT_VAL(BLE_ISO_BROADCASTER)) +int +cmd_leaudio_base_add(int argc, char **argv) +{ + uint32_t presentation_delay; + uint8_t adv_instance; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + adv_instance = parse_arg_uint8("adv_instance", &rc); + if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { + console_printf("invalid advertising instance\n"); + return rc; + } + + presentation_delay = parse_arg_uint32("presentation_delay", &rc); + if (rc != 0) { + return rc; + } + + return btshell_broadcast_base_add(adv_instance, presentation_delay); +} + +int +cmd_leaudio_big_sub_add(int argc, char **argv) +{ + uint8_t adv_instance; + uint8_t codec_fmt; + uint16_t company_id; + uint16_t vendor_spec; + static uint8_t metadata[CMD_ADV_DATA_METADATA_MAX_SZ]; + unsigned int metadata_len; + static uint8_t codec_spec_cfg[CMD_ADV_DATA_CODEC_SPEC_CFG_MAX_SZ]; + unsigned int codec_spec_cfg_len; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + adv_instance = parse_arg_uint8("adv_instance", &rc); + if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { + console_printf("invalid advertising instance\n"); + return rc; + } + + codec_fmt = parse_arg_uint8("codec_fmt", &rc); + if (rc != 0) { + return rc; + } + + company_id = parse_arg_uint16("company_id", &rc); + if (rc != 0) { + return rc; + } + + vendor_spec = parse_arg_uint16("vendor_spec", &rc); + if (rc != 0) { + return rc; + } + + rc = parse_arg_byte_stream("codec_spec_config", + CMD_ADV_DATA_CODEC_SPEC_CFG_MAX_SZ, + codec_spec_cfg, &codec_spec_cfg_len); + if (rc != 0 && rc != ENOENT) { + return rc; + } + + rc = parse_arg_byte_stream("metadata", CMD_ADV_DATA_METADATA_MAX_SZ, + metadata, &metadata_len); + if (rc != 0 && rc != ENOENT) { + return rc; + } + + return btshell_broadcast_big_sub_add(adv_instance, + codec_fmt, company_id, + vendor_spec, + metadata, metadata_len, + codec_spec_cfg, codec_spec_cfg_len); +} + +int +cmd_leaudio_bis_add(int argc, char **argv) +{ + uint8_t adv_instance; + static uint8_t codec_spec_cfg[CMD_ADV_DATA_CODEC_SPEC_CFG_MAX_SZ]; + unsigned int codec_spec_cfg_len; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + adv_instance = parse_arg_uint8("adv_instance", &rc); + if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { + console_printf("invalid advertising instance\n"); + return rc; + } + + rc = parse_arg_byte_stream("codec_spec_config", + CMD_ADV_DATA_CODEC_SPEC_CFG_MAX_SZ, + codec_spec_cfg, &codec_spec_cfg_len); + if (rc != 0) { + return rc; + } + + return btshell_broadcast_bis_add(adv_instance, codec_spec_cfg, + codec_spec_cfg_len); +} + +int +cmd_leaudio_broadcast_create(int argc, char **argv) +{ + struct ble_iso_big_params big_params; + uint8_t adv_instance; + const char *name; + uint8_t extra_data[CMD_ADV_DATA_EXTRA_MAX_SZ]; + static uint8_t own_addr_type; + unsigned int extra_data_len; + struct ble_gap_periodic_adv_params periodic_params; + struct ble_gap_ext_adv_params extended_params = { + .scannable = 0, + .connectable = 0, + .primary_phy = BLE_HCI_LE_PHY_1M, + }; + int rc; + + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + return rc; + } + + extended_params.own_addr_type = own_addr_type; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + adv_instance = parse_arg_uint8("adv_instance", &rc); + if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { + console_printf("invalid advertising instance\n"); + return rc; + } + + extended_params.sid = adv_instance; + extended_params.itvl_min = parse_arg_uint8_dflt("ext_interval_min", + 0, &rc); + if (rc != 0 && rc != ENOENT) { + console_printf("invalid extended advertising interval (min)\n"); + return rc; + } + + extended_params.itvl_max = parse_arg_uint8_dflt("ext_interval_max", 0, + &rc); + if (rc != 0 && rc != ENOENT) { + console_printf("invalid extended advertising interval (max)\n"); + return rc; + } + + periodic_params.itvl_min = parse_arg_uint8_dflt("per_interval_min", 0, + &rc); + if (rc != 0 && rc != ENOENT) { + console_printf("invalid periodic advertising interval (min)\n"); + return rc; + } + + periodic_params.itvl_max = parse_arg_uint8_dflt("per_interval_max", 0, + &rc); + if (rc != 0 && rc != ENOENT) { + console_printf("invalid periodic advertising interval (max)\n"); + return rc; + } + + name = parse_arg_extract("name"); + + big_params.sdu_interval = parse_arg_uint32_bounds("sdu_interval", + 0x0000FF, 0x0FFFFF, + &rc); + if (rc != 0) { + console_printf("invalid SDU interval\n"); + return rc; + } + + big_params.max_sdu = parse_arg_uint16_bounds("max_sdu", 0x0001, 0x0FFF, + &rc); + if (rc != 0) { + console_printf("invalid max SDU size\n"); + return rc; + } + + big_params.max_transport_latency = parse_arg_uint16_bounds("max_latency", + 0x0005, 0x0FA0, + &rc); + if (rc != 0) { + console_printf("invalid max transport latency\n"); + return rc; + } + + big_params.rtn = parse_arg_uint8_bounds("rtn", 0x00, 0x1E, &rc); + if (rc != 0) { + console_printf("invalid RTN\n"); + return rc; + } + + big_params.phy = parse_arg_uint8_bounds("phy", 0, 2, &rc); + if (rc != 0) { + console_printf("invalid PHY\n"); + return rc; + } + + extended_params.secondary_phy = big_params.phy; + + big_params.packing = parse_arg_uint8_bounds_dflt("packing", 0, 1, 1, &rc); + if (rc != 0) { + console_printf("invalid packing\n"); + return rc; + } + + big_params.framing = parse_arg_uint8_bounds_dflt("framing", 0, 1, 0, &rc); + if (rc != 0) { + console_printf("invalid framing\n"); + return rc; + } + + big_params.encryption = parse_arg_uint8_bounds_dflt("encryption", 0, 1, 0, &rc); + if (rc != 0) { + console_printf("invalid encryption\n"); + return rc; + } + + if (big_params.encryption) { + big_params.broadcast_code = parse_arg_extract("broadcast_code"); + if (big_params.broadcast_code == NULL) { + console_printf("broadcast code missing\n"); + return ENOENT; + } + + if (strlen(big_params.broadcast_code) > 16) { + console_printf("broadcast code too long\n"); + return ENOENT; + } + } + + rc = parse_arg_byte_stream("extra_data", + CMD_ADV_DATA_EXTRA_MAX_SZ, + extra_data, &extra_data_len); + if (rc == ENOENT) { + extra_data_len = 0; + } else if (rc != 0) { + return rc; + } + + return btshell_broadcast_create(adv_instance, + &extended_params, + &periodic_params, + name, + big_params, + extra_data, + extra_data_len); +} + +int +cmd_leaudio_broadcast_destroy(int argc, char **argv) +{ + uint8_t adv_instance; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + adv_instance = parse_arg_uint8("adv_instance", &rc); + if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { + console_printf("invalid advertising instance\n"); + return rc; + } + + return btshell_broadcast_destroy(adv_instance); +} + +int +cmd_leaudio_broadcast_update(int argc, char **argv) +{ + uint8_t adv_instance; + uint8_t extra_data[CMD_ADV_DATA_EXTRA_MAX_SZ]; + unsigned int extra_data_len; + const char *name; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + adv_instance = parse_arg_uint8("adv_instance", &rc); + if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { + console_printf("invalid advertising instance\n"); + return rc; + } + + rc = parse_arg_byte_stream("extra_data", + CMD_ADV_DATA_EXTRA_MAX_SZ, + extra_data, &extra_data_len); + if (rc != 0 && rc != ENOENT) { + return rc; + } + + name = parse_arg_extract("name"); + + return btshell_broadcast_update(adv_instance, name, extra_data, extra_data_len); +} + +int +cmd_leaudio_broadcast_start(int argc, char **argv) +{ + uint8_t adv_instance; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + adv_instance = parse_arg_uint8("adv_instance", &rc); + if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { + console_printf("invalid advertising instance\n"); + return rc; + } + + return btshell_broadcast_start(adv_instance); +} + +int +cmd_leaudio_broadcast_stop(int argc, char **argv) +{ + uint8_t adv_instance; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + adv_instance = parse_arg_uint8("adv_instance", &rc); + if (rc != 0 || adv_instance >= BLE_ADV_INSTANCES) { + console_printf("invalid advertising instance\n"); + return rc; + } + + return btshell_broadcast_stop(adv_instance); +} +#endif diff --git a/apps/btshell/src/cmd_leaudio.h b/apps/btshell/src/cmd_leaudio.h new file mode 100644 index 0000000000..84fc458626 --- /dev/null +++ b/apps/btshell/src/cmd_leaudio.h @@ -0,0 +1,46 @@ +/* + * 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_CMD_LEAUDIO_ +#define H_CMD_LEAUDIO_ + +#include "cmd.h" + +#define CMD_ADV_DATA_CODEC_SPEC_CFG_MAX_SZ (9) +/** + * Maximum Metadata size is maximum adv size minus minimum size of other + * fields in BASE advertising + */ +#define CMD_ADV_DATA_METADATA_MAX_SZ (MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) - 27) +/** + * Maximum size of extra data included in BASE advertising. Assumes minimum + * size of other fields. + */ +#define CMD_ADV_DATA_EXTRA_MAX_SZ (MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) - 27) + +int cmd_leaudio_base_add(int argc, char **argv); +int cmd_leaudio_big_sub_add(int argc, char **argv); +int cmd_leaudio_bis_add(int argc, char **argv); +int cmd_leaudio_broadcast_create(int argc, char **argv); +int cmd_leaudio_broadcast_destroy(int argc, char **argv); +int cmd_leaudio_broadcast_update(int argc, char **argv); +int cmd_leaudio_broadcast_start(int argc, char **argv); +int cmd_leaudio_broadcast_stop(int argc, char **argv); + +#endif /* H_CMD_LEAUDIO_ */ diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index aaa423ea8b..8224f42a5e 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -41,6 +41,8 @@ #include "host/ble_gatt.h" #include "host/ble_store.h" #include "host/ble_sm.h" +#include "host/ble_audio_common.h" +#include "host/ble_audio_broadcast.h" #include "host/util/util.h" /* Mandatory services. */ @@ -123,6 +125,57 @@ int btshell_full_disc_prev_chr_val; struct ble_sm_sc_oob_data oob_data_local; struct ble_sm_sc_oob_data oob_data_remote; +#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +static struct {struct ble_audio_base *base; uint8_t adv_instance;} +btshell_base_list[MYNEWT_VAL(BLE_MAX_BIG)]; + +static os_membuf_t btshell_base_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIG), + sizeof(struct ble_audio_base)) +]; +static struct os_mempool btshell_base_pool; + +static os_membuf_t btshell_big_params_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIG), + sizeof(struct ble_iso_big_params)) +]; +static struct os_mempool btshell_big_params_pool; + +/** Mempool size: in worst case every BIS is in separate subgroup */ +static os_membuf_t btshell_big_sub_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIS), + sizeof(struct ble_audio_big_subgroup)) +]; +static struct os_mempool btshell_big_sub_pool; + +static os_membuf_t btshell_bis_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIS), + sizeof(struct ble_audio_bis)) +]; +static struct os_mempool btshell_bis_pool; + +static os_membuf_t btshell_metadata_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIS), + MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) - 27) +]; +static struct os_mempool btshell_metadata_pool; + +/** + * Mempool size: theoretically it is possible that every BIG Subgroup has + * codec specific configuration, every BIS is in separate subgroup and also + * has one. This is inefficient but possible and should not cause error if + * used that way */ +static os_membuf_t btshell_codec_spec_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIS) * 2, 9) +]; +static struct os_mempool btshell_codec_spec_pool; + +static os_membuf_t btshell_big_params_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIG), sizeof(struct ble_iso_big_params)) +]; +static struct os_mempool btshell_big_params_pool; +#endif + #define XSTR(s) STR(s) #ifndef STR #define STR(s) #s @@ -2618,6 +2671,276 @@ btshell_get_default_own_addr_type(void) return default_own_addr_type; } +#if (MYNEWT_VAL(BLE_ISO_BROADCASTER)) +static int +btshell_base_find_free(void) +{ + int i; + for (i = 0; i < MYNEWT_VAL(BLE_MAX_BIG); i++) { + if (btshell_base_list[i].base == NULL) { + return i; + } + } + + return -ENOMEM; +} + +static struct ble_audio_base * +btshell_base_find(uint8_t adv_instance) +{ + int i; + for (i = 0; i < MYNEWT_VAL(BLE_MAX_BIG); i++) { + if (btshell_base_list[i].adv_instance == adv_instance) { + return btshell_base_list[i].base; + } + } + + return NULL; +} + +static int +btshell_broadcast_destroy_fn(struct ble_audio_base *base, void *args) +{ + struct ble_iso_big_params *big_params = + (struct ble_iso_big_params *)args; + struct ble_audio_big_subgroup *big_sub; + struct ble_audio_bis *bis; + + STAILQ_FOREACH(big_sub, &base->subs, next) { + STAILQ_FOREACH(bis, &big_sub->bises, next) { + os_memblock_put(&btshell_bis_pool, bis); + os_memblock_put(&btshell_codec_spec_pool, bis->codec_spec_config); + STAILQ_REMOVE(&big_sub->bises, bis, ble_audio_bis, next); + } + os_memblock_put(&btshell_big_sub_pool, big_sub); + os_memblock_put(&btshell_codec_spec_pool, big_sub->codec_spec_config); + os_memblock_put(&btshell_metadata_pool, big_sub->metadata); + STAILQ_REMOVE(&base->subs, big_sub, ble_audio_big_subgroup, next); + } + + os_memblock_put(&btshell_big_params_pool, big_params); + + return 0; +} + +int +btshell_broadcast_base_add(uint8_t adv_instance, uint32_t presentation_delay) +{ + struct ble_audio_base *base; + int free_base_idx; + + base = os_memblock_get(&btshell_base_pool); + if (!base) { + return ENOMEM; + } + + free_base_idx = btshell_base_find_free(); + if (free_base_idx < 0) { + return ENOMEM; + } + + base->presentation_delay = presentation_delay; + + btshell_base_list[free_base_idx].base = base; + btshell_base_list[free_base_idx].adv_instance = adv_instance; + + return 0; +} + +int +btshell_broadcast_big_sub_add(uint8_t adv_instance, + uint8_t codec_fmt, uint16_t company_id, + uint16_t vendor_spec, + uint8_t *metadata, + unsigned int metadata_len, + uint8_t *codec_spec_cfg, + unsigned int codec_spec_cfg_len) +{ + struct ble_audio_big_subgroup *big_sub; + struct ble_audio_base *base; + uint8_t *new_metadata = NULL; + uint8_t *new_codec_spec_cfg = NULL; + + big_sub = os_memblock_get(&btshell_big_sub_pool); + if (!big_sub) { + return ENOMEM; + } + + base = btshell_base_find(adv_instance); + if (!base) { + os_memblock_put(&btshell_big_sub_pool, big_sub); + return ENOENT; + } + + if (metadata_len > 0) { + new_metadata = os_memblock_get(&btshell_metadata_pool); + if (!new_metadata) { + os_memblock_put(&btshell_big_sub_pool, big_sub); + return ENOMEM; + } + memcpy(new_metadata, metadata, metadata_len); + } + + if (codec_spec_cfg_len > 0) { + new_codec_spec_cfg = os_memblock_get(&btshell_codec_spec_pool); + if (!new_codec_spec_cfg) { + os_memblock_put(&btshell_big_sub_pool, big_sub); + os_memblock_put(&btshell_metadata_pool, new_metadata); + return ENOMEM; + } + memcpy(new_codec_spec_cfg, codec_spec_cfg, codec_spec_cfg_len); + } + + big_sub->codec_id.format = codec_fmt; + big_sub->codec_id.company_id = company_id; + big_sub->codec_id.vendor_specific = vendor_spec; + big_sub->codec_id.vendor_specific = vendor_spec; + big_sub->codec_spec_config = codec_spec_cfg_len > 0 ? + new_codec_spec_cfg : NULL; + big_sub->codec_spec_config_len = codec_spec_cfg_len; + big_sub->metadata = metadata_len > 0 ? new_metadata : NULL; + big_sub->metadata_len = metadata_len; + + if (STAILQ_EMPTY(&base->subs)) { + STAILQ_INSERT_HEAD(&base->subs, big_sub, next); + } else { + STAILQ_INSERT_TAIL(&base->subs, big_sub, next); + } + + base->num_subgroups++; + + return 0; +} + +int +btshell_broadcast_bis_add(uint8_t adv_instance, + uint8_t *codec_spec_cfg, + unsigned int codec_spec_cfg_len) +{ + struct ble_audio_bis *bis; + struct ble_audio_base *base; + struct ble_audio_big_subgroup *big_sub; + uint8_t *new_codec_spec_cfg; + + base = btshell_base_find(adv_instance); + if (!base) { + return ENOENT; + } + + big_sub = STAILQ_LAST(&base->subs, ble_audio_big_subgroup, next); + if (!big_sub) { + return ENOENT; + } + + bis = os_memblock_get(&btshell_bis_pool); + if (!bis) { + return ENOMEM; + } + + if (codec_spec_cfg_len > 0) { + new_codec_spec_cfg = os_memblock_get(&btshell_codec_spec_pool); + if (!new_codec_spec_cfg) { + os_memblock_put(&btshell_bis_pool, bis); + return ENOMEM; + } + memcpy(new_codec_spec_cfg, codec_spec_cfg, codec_spec_cfg_len); + } + + bis->codec_spec_config = codec_spec_cfg_len > 0 ? + new_codec_spec_cfg : NULL; + bis->codec_spec_config_len = codec_spec_cfg_len; + + if (STAILQ_EMPTY(&big_sub->bises)) { + STAILQ_INSERT_HEAD(&big_sub->bises, bis, next); + } else { + STAILQ_INSERT_TAIL(&big_sub->bises, bis, next); + } + + big_sub->bis_cnt++; + return 0; +} + +int +btshell_broadcast_create(uint8_t adv_instance, + struct ble_gap_ext_adv_params *ext_params, + struct ble_gap_periodic_adv_params *per_params, + const char *name, + struct ble_iso_big_params big_params, + uint8_t *extra_data, + unsigned int extra_data_len) +{ + struct ble_audio_base *base; + struct ble_broadcast_create_params create_params; + struct ble_iso_big_params *big_params_ptr; + int rc; + + base = btshell_base_find(adv_instance); + if (!base) { + return ENOENT; + } + + big_params_ptr = os_memblock_get(&btshell_big_params_pool); + if (!big_params_ptr) { + return ENOMEM; + } + + *big_params_ptr = big_params; + + create_params.base = base; + create_params.extended_params = ext_params; + create_params.periodic_params = per_params; + create_params.name = name; + create_params.adv_instance = adv_instance; + create_params.big_params = big_params_ptr; + create_params.svc_data = extra_data; + create_params.svc_data_len = extra_data_len; + + rc = ble_audio_broadcast_create(&create_params, + btshell_broadcast_destroy_fn, + (void *)big_params_ptr, + btshell_gap_event); + return rc; +} + +int +btshell_broadcast_destroy(uint8_t adv_instance) +{ + return ble_audio_broadcast_destroy(adv_instance); +} + +int +btshell_broadcast_update(uint8_t adv_instance, + const char *name, + uint8_t *extra_data, + unsigned int extra_data_len) +{ + struct ble_audio_base *base; + struct ble_broadcast_update_params params; + + base = btshell_base_find(adv_instance); + + params.name = name; + params.adv_instance = adv_instance; + params.svc_data = extra_data; + params.svc_data_len = extra_data_len; + params.broadcast_id = base->broadcast_id; + + return ble_audio_broadcast_update(¶ms); +} + +int +btshell_broadcast_start(uint8_t adv_instance) +{ + return ble_audio_broadcast_start(adv_instance, NULL, NULL); +} + +int +btshell_broadcast_stop(uint8_t adv_instance) +{ + return ble_audio_broadcast_stop(adv_instance); +} +#endif + /** * main * @@ -2667,7 +2990,43 @@ mynewt_main(int argc, char **argv) "btshell_coc_conn_pool"); assert(rc == 0); #endif +#if (MYNEWT_VAL(BLE_ISO_BROADCASTER)) + rc = os_mempool_init(&btshell_base_pool, MYNEWT_VAL(BLE_MAX_BIG), + sizeof(struct ble_audio_base), + btshell_base_mem, + "btshell_base_pool"); + assert(rc == 0); + rc = os_mempool_init(&btshell_big_params_pool, MYNEWT_VAL(BLE_MAX_BIG), + sizeof(struct ble_iso_big_params), + btshell_big_params_mem, + "btshell_big_params_pool"); + assert(rc == 0); + rc = os_mempool_init(&btshell_big_sub_pool, MYNEWT_VAL(BLE_MAX_BIS), + sizeof(struct ble_audio_big_subgroup), + btshell_big_sub_mem, + "btshell_big_sub_pool"); + assert(rc == 0); + rc = os_mempool_init(&btshell_bis_pool, MYNEWT_VAL(BLE_MAX_BIS), + sizeof(struct ble_audio_bis), btshell_bis_mem, + "btshell_bis_pool"); + assert(rc == 0); + + rc = os_mempool_init(&btshell_metadata_pool, MYNEWT_VAL(BLE_MAX_BIS), + MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) - 27, + btshell_metadata_mem, "btshell_metadata_pool"); + assert(rc == 0); + rc = os_mempool_init(&btshell_codec_spec_pool, + MYNEWT_VAL(BLE_MAX_BIS) * 2, 19, + btshell_codec_spec_mem, "btshell_codec_spec_pool"); + assert(rc == 0); + + rc = os_mempool_init(&btshell_big_params_pool, + MYNEWT_VAL(BLE_MAX_BIG), + sizeof(struct ble_iso_big_params), + btshell_big_params_mem, "btshell_big_params_pool"); + assert(rc == 0); +#endif /* Initialize the NimBLE host configuration. */ ble_hs_cfg.reset_cb = btshell_on_reset; ble_hs_cfg.sync_cb = btshell_on_sync; diff --git a/nimble/host/src/ble_iso.c b/nimble/host/src/ble_iso.c index ba0fd3056c..e1115a1d5a 100644 --- a/nimble/host/src/ble_iso.c +++ b/nimble/host/src/ble_iso.c @@ -282,28 +282,24 @@ ble_iso_tx_complete(uint16_t conn_handle, const uint8_t *data, } static int -ble_iso_tx_segmented(uint16_t conn_handle, uint16_t max_pdu, - const uint8_t *data, uint16_t data_len) +ble_iso_tx_segmented(uint16_t conn_handle, const uint8_t *data, + uint16_t data_len) { struct os_mbuf *om; uint16_t data_left = data_len; uint16_t packet_len; uint16_t offset = 0; uint8_t pb; - uint8_t ts; int rc; while (data_left) { - packet_len = min(max_pdu - (BLE_HCI_DATA_HDR_SZ + 4), data_left); + packet_len = min(MYNEWT_VAL(BLE_TRANSPORT_ISO_SIZE), data_left); if (data_left == data_len) { pb = BLE_HCI_ISO_PB_FIRST; - ts = 1; } else if (packet_len == data_left) { pb = BLE_HCI_ISO_PB_LAST; - ts = 0; } else { pb = BLE_HCI_ISO_PB_CONTINUATION; - ts = 0; } om = ble_hs_mbuf_bare_pkt(); @@ -311,32 +307,26 @@ ble_iso_tx_segmented(uint16_t conn_handle, uint16_t max_pdu, return BLE_HS_ENOMEM; } - os_mbuf_extend(om, ts == 1 ? 10: 8); + os_mbuf_extend(om, pb == BLE_HCI_ISO_PB_FIRST ? 8: 4); /* Connection_Handle, PB_Flag, TS_Flag */ put_le16(&om->om_data[0], - BLE_HCI_ISO_HANDLE(conn_handle, pb, ts)); - /* Data_Total_Length = Data length + - * Packet_Sequence_Number placeholder + - * optional timestamp*/ - put_le16(&om->om_data[2], packet_len + 4 + 2 * ts); + BLE_HCI_ISO_HANDLE(conn_handle, pb, 0)); - if (ts) { - /* Timestamp placeholder */ - put_le16(&om->om_data[4], 0); + if (pb == BLE_HCI_ISO_PB_FIRST) { + /* Data_Total_Length = Data length + + * Packet_Sequence_Number placeholder*/ + put_le16(&om->om_data[2], packet_len + 4); /* Packet_Sequence_Number placeholder */ - put_le16(&om->om_data[6], 0); + put_le16(&om->om_data[8], 0); /* ISO_SDU_Length */ - put_le16(&om->om_data[8], packet_len); + put_le16(&om->om_data[10], packet_len); + } else { + put_le16(&om->om_data[2], packet_len); } - /* Packet_Sequence_Number placeholder */ - put_le16(&om->om_data[4], 0); - /* ISO_SDU_Length */ - put_le16(&om->om_data[6], packet_len); - rc = os_mbuf_append(om, data + offset, packet_len); if (rc) { return rc; @@ -345,40 +335,21 @@ ble_iso_tx_segmented(uint16_t conn_handle, uint16_t max_pdu, ble_transport_to_ll_iso(om); offset += packet_len; - data_len -= packet_len; + data_left -= packet_len; } return 0; } int -ble_iso_tx(uint16_t conn_handle, const uint8_t *data, uint16_t data_len) +ble_iso_tx(uint16_t conn_handle, void *data, uint16_t data_len) { - struct ble_iso_big *big; - uint16_t max_pdu = 0; int rc; - int i; - - SLIST_FOREACH(big, &ble_iso_bigs, next) { - for (i = 0; i < big->num_bis; i++) { - if (big->conn_handles[i] == conn_handle) { - max_pdu = big->max_pdu; - break; - } - } - if (max_pdu > 0) { - break; - } - } - - if (!max_pdu) { - return BLE_HS_ENOENT; - } - if (data_len <= max_pdu) { + if (data_len <= MYNEWT_VAL(BLE_TRANSPORT_ISO_SIZE)) { rc = ble_iso_tx_complete(conn_handle, data, data_len); } else { - rc = ble_iso_tx_segmented(conn_handle, max_pdu, data, data_len); + rc = ble_iso_tx_segmented(conn_handle, data, data_len); } return rc; From ca7aeaad9e07be1c75cefca63521679e7f307573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 17 Nov 2023 08:40:24 +0100 Subject: [PATCH 0869/1333] host/gap: add function that returns free advertising instance ble_gap_adv_get_free_instance browses through list of advertising instances and returns first that is not yet configured. Previously, user had to track which instance is used by themselves, and could only check if advertising is active, via ble_gap_ext_adv_active --- nimble/host/include/host/ble_gap.h | 8 ++++++++ nimble/host/src/ble_gap.c | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index fd70b94afb..d884596a67 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -1692,6 +1692,14 @@ int ble_gap_ext_adv_clear(void); * */ int ble_gap_ext_adv_active(uint8_t instance); + +/** + * Returns first not configured advertising instance. + * + * @return advertising instance if one was found, negative error code otherwise + * + */ +int ble_gap_adv_get_free_instance(void); #endif /* Periodic Advertising */ diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 015a70d877..02e4f28881 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -1390,6 +1390,20 @@ int ble_gap_ext_adv_active(uint8_t instance) } return ble_gap_adv_active_instance(instance); } + +int +ble_gap_adv_get_free_instance(void) +{ + int i; + + for (i = 0; i < BLE_ADV_INSTANCES; i++) { + if (!ble_gap_slave[i].configured) { + return i; + } + } + + return -BLE_HS_ENOENT; +} #endif /** From 043bf6ea5b6240f752970996ca7be4a31d55ce5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 24 Oct 2023 07:42:29 +0200 Subject: [PATCH 0870/1333] implementation of Auracast package This is simplified wrapper for Broadcast, that allows to create Broadcast advertisements with sane defaults for advertising parameters. Application still needs to build BASE configuration to use it. --- nimble/host/services/auracast/pkg.yml | 30 ++++ .../services/auracast/src/ble_svc_auracast.c | 128 ++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 nimble/host/services/auracast/pkg.yml create mode 100644 nimble/host/services/auracast/src/ble_svc_auracast.c diff --git a/nimble/host/services/auracast/pkg.yml b/nimble/host/services/auracast/pkg.yml new file mode 100644 index 0000000000..a4d0013f93 --- /dev/null +++ b/nimble/host/services/auracast/pkg.yml @@ -0,0 +1,30 @@ +# 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: nimble/host/services/auracast +pkg.description: Implements Auracast service +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - ble + - bluetooth + - auracast + - nimble + +pkg.deps: + - nimble/host diff --git a/nimble/host/services/auracast/src/ble_svc_auracast.c b/nimble/host/services/auracast/src/ble_svc_auracast.c new file mode 100644 index 0000000000..4446ff90d4 --- /dev/null +++ b/nimble/host/services/auracast/src/ble_svc_auracast.c @@ -0,0 +1,128 @@ +/* + * 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. + */ + +#include "syscfg/syscfg.h" + +#include "host/ble_gap.h" +#include "host/ble_hs.h" +#include "host/ble_audio_broadcast.h" +#include "services/auracast/ble_svc_auracast.h" + +int +ble_svc_auracast_create(const struct ble_svc_auracast_create_params *params, + uint8_t *auracast_instance, + ble_audio_broadcast_destroy_fn *destroy_cb, + void *args, ble_gap_event_fn *gap_cb) +{ + struct ble_broadcast_create_params create_params; + struct ble_gap_periodic_adv_params periodic_params = { 0 }; + struct ble_gap_ext_adv_params extended_params = { + .scannable = 0, + .connectable = 0, + .primary_phy = BLE_HCI_LE_PHY_1M, + }; + uint8_t adv_instance; + uint8_t auracast_svc_data[251] = { 0 }; + uint8_t data_offset = 1; + + uint8_t features = 0; + + features |= params->big_params->encryption; + + if ((params->frame_duration == 10000) && + (((params->sampling_frequency == 16000) && + (params->bitrate == 32000)) || + ((params->sampling_frequency == 24000) && + (params->bitrate == 48000)))) { + features |= 0x02; + } + + if (params->sampling_frequency == 48000) { + features |= 0x04; + } + + + auracast_svc_data[data_offset] = BLE_HS_ADV_TYPE_SVC_DATA_UUID16; + data_offset++; + put_le16(&auracast_svc_data[data_offset], 0x1856); + data_offset += 2; + auracast_svc_data[data_offset] = features; + data_offset++; + /** Metadata */ + if (params->program_info != NULL) { + auracast_svc_data[data_offset] = strlen(params->program_info) + 2; + data_offset++; + auracast_svc_data[data_offset] = strlen(params->program_info) + 1; + data_offset++; + auracast_svc_data[data_offset] = 3; + data_offset++; + memcpy(&auracast_svc_data[data_offset], params->program_info, + strlen(params->program_info)); + data_offset += strlen(params->program_info); + } + + auracast_svc_data[0] = data_offset - 1; + + adv_instance = ble_gap_adv_get_free_instance(); + if (adv_instance < 0) { + return BLE_HS_ENOENT; + } + + if (params->secondary_phy == BLE_HCI_LE_PHY_2M && + !MYNEWT_VAL(BLE_PHY_2M)) { + return BLE_HS_EINVAL; + } + + extended_params.own_addr_type = params->own_addr_type; + extended_params.sid = params->sid; + extended_params.secondary_phy = params->secondary_phy; + + create_params.base = params->base; + create_params.extended_params = &extended_params; + create_params.periodic_params = &periodic_params; + create_params.name = params->name; + create_params.adv_instance = adv_instance; + create_params.big_params = params->big_params; + create_params.svc_data = auracast_svc_data; + create_params.svc_data_len = data_offset; + + *auracast_instance = adv_instance; + + return ble_audio_broadcast_create(&create_params, + destroy_cb, args, gap_cb); +} + +int +ble_svc_auracast_terminate(uint8_t auracast_instance) +{ + return ble_audio_broadcast_destroy(auracast_instance); +} + +int +ble_svc_auracast_start(uint8_t auracast_instance, ble_iso_event_fn *cb, void *cb_arg) +{ + + return ble_audio_broadcast_start(auracast_instance, cb, cb_arg); +} + +int +ble_svc_auracast_stop(uint8_t auracast_instance) +{ + return ble_audio_broadcast_stop(auracast_instance); +} From ba36cb41e274e6d46dabe66f1fc89361a203f4c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 15 Nov 2023 09:26:11 +0100 Subject: [PATCH 0871/1333] apps/leaudio_broadcaster: add sample application for broadcast feature Added application that has stored LC3 coded audio in form of sine sweep from 100Hz to 20kHz. Application creates Broadcast announcement, builds BIG with 1 or 2 BISes and starts to broadcast sample data. --- apps/leaudio_broadcaster/pkg.yml | 38 + apps/leaudio_broadcaster/src/audio_data.h | 4412 +++++++++++++++++ apps/leaudio_broadcaster/src/main.c | 404 ++ apps/leaudio_broadcaster/syscfg.yml | 65 + .../pkg.yml | 24 + .../syscfg.yml | 47 + .../target.yml | 22 + 7 files changed, 5012 insertions(+) create mode 100644 apps/leaudio_broadcaster/pkg.yml create mode 100644 apps/leaudio_broadcaster/src/audio_data.h create mode 100644 apps/leaudio_broadcaster/src/main.c create mode 100644 apps/leaudio_broadcaster/syscfg.yml create mode 100644 targets/nordic_pca10095_net-blehci_broadcaster/pkg.yml create mode 100644 targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml create mode 100644 targets/nordic_pca10095_net-blehci_broadcaster/target.yml diff --git a/apps/leaudio_broadcaster/pkg.yml b/apps/leaudio_broadcaster/pkg.yml new file mode 100644 index 0000000000..0955da906b --- /dev/null +++ b/apps/leaudio_broadcaster/pkg.yml @@ -0,0 +1,38 @@ +# 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: apps/leaudio_broadcaster +pkg.type: app +pkg.description: LE Audio Broadcast sample application. + +pkg.author: "Krzysztof Kopyściński" +pkg.email: "krzysztof.kopyscinski@codecoup.pl" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - nimble/host + - nimble/host/util + - nimble/host/services/gap + - nimble/host/store/config + - "@apache-mynewt-core/kernel/os" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" + - "@apache-mynewt-core/sys/stats" + - "@apache-mynewt-core/sys/sysinit" + - "@apache-mynewt-core/sys/id" diff --git a/apps/leaudio_broadcaster/src/audio_data.h b/apps/leaudio_broadcaster/src/audio_data.h new file mode 100644 index 0000000000..0bb90a4a1f --- /dev/null +++ b/apps/leaudio_broadcaster/src/audio_data.h @@ -0,0 +1,4412 @@ +/* + * 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. + */ + +/** LC3 coded audio data, with 48kHz sample rate. + * Audio signal coded here is 100Hz-20kHz sweep signal, in sinus form + */ +const uint8_t audio_data[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x33, 0x99, 0xb9, 0x51, 0x64, 0x62, 0x1d, 0x6c, 0x3c, 0xf8, 0xae, 0xb5, 0xbd, 0x64, 0xba, 0x9e, + 0xe2, 0x0c, 0x72, 0x7a, 0x4c, 0xdc, 0xed, 0x84, 0x9d, 0x8a, 0x75, 0x28, 0x61, 0x88, 0xcc, 0x11, + 0xef, 0x66, 0x35, 0x9e, 0xbf, 0x34, 0xdd, 0x56, 0xcb, 0x39, 0x9a, 0xed, 0x53, 0xe7, 0xc6, 0x6e, + 0x73, 0x53, 0x29, 0x4e, 0x02, 0x2f, 0xb2, 0x65, 0x81, 0xe9, 0xb6, 0xee, 0xf5, 0x35, 0x20, 0xfc, + 0xc1, 0x31, 0x7e, 0x63, 0x28, 0x9f, 0x03, 0xe0, 0x7e, 0x07, 0xe0, 0x7e, 0x07, 0xe0, 0x3d, 0xe0, + 0xf9, 0x11, 0xcf, 0x5d, 0xab, 0x9c, 0xc4, 0x78, 0xed, 0x64, 0xbd, 0x3e, 0x4c, 0x6b, 0x06, 0x27, + 0x1a, 0x80, 0xf1, 0xb0, 0xec, 0x96, 0x4a, 0x21, 0x07, 0xb2, 0x13, 0xf0, 0x3f, 0x03, 0xf3, 0x02, + 0x38, 0x26, 0x1e, 0x8b, 0x82, 0x6a, 0x63, 0x34, 0x33, 0x9e, 0x72, 0xd8, 0xa9, 0x96, 0xbe, 0x10, + 0x87, 0xca, 0x68, 0x69, 0x81, 0xa0, 0x5e, 0x6d, 0xeb, 0xbb, 0x09, 0x50, 0x8c, 0x3c, 0xda, 0xbd, + 0x5b, 0x20, 0x77, 0xae, 0xa8, 0x4f, 0x74, 0xde, 0x0a, 0xa7, 0xe4, 0x2f, 0x0a, 0x8c, 0x91, 0x84, + 0xb5, 0x97, 0x9e, 0xdf, 0x04, 0x86, 0xce, 0x02, 0xdc, 0xa2, 0xf2, 0x33, 0x0c, 0xe5, 0x0d, 0x2a, + 0x36, 0x59, 0xd7, 0x03, 0x0c, 0xb7, 0xb3, 0xa1, 0xe3, 0x7f, 0x21, 0x58, 0xd1, 0x5d, 0xb8, 0x3f, + 0x03, 0xf0, 0x3f, 0x01, 0xfc, 0x07, 0xf0, 0x0f, 0xe0, 0x5f, 0x83, 0xb8, 0x07, 0x8b, 0x04, 0xe4, + 0x32, 0x08, 0x21, 0x4a, 0x97, 0x4a, 0x76, 0x4a, 0x06, 0x71, 0xba, 0x1b, 0xb9, 0x6f, 0x05, 0xb4, + 0x67, 0xf1, 0x0b, 0xee, 0x03, 0xf0, 0x1f, 0x18, 0x38, 0x26, 0x1e, 0x8f, 0x82, 0x6a, 0x63, 0x34, + 0x33, 0x99, 0xb9, 0x7c, 0x0f, 0xda, 0x8d, 0xcf, 0x8f, 0x01, 0xff, 0x62, 0x63, 0xf0, 0x32, 0x2f, + 0xd1, 0x7f, 0xc9, 0x4a, 0xe1, 0x4f, 0x8c, 0x0f, 0xf3, 0x9b, 0x09, 0xb7, 0xad, 0xdd, 0xe8, 0xba, + 0xd5, 0x9c, 0xf1, 0x88, 0x8d, 0x7f, 0x56, 0x46, 0x8b, 0x8d, 0x5a, 0x1e, 0xd1, 0xe7, 0xdf, 0x70, + 0xf5, 0x06, 0x80, 0x58, 0xb7, 0xe1, 0x9d, 0x60, 0x1e, 0xcf, 0x07, 0x7c, 0xfb, 0xdf, 0x3a, 0x26, + 0x27, 0x53, 0x54, 0xe3, 0x33, 0x8f, 0x42, 0x0f, 0x0f, 0x87, 0x81, 0xf8, 0x0f, 0xc0, 0xfe, 0x07, + 0xe0, 0x7b, 0xad, 0x59, 0x8a, 0xea, 0x1f, 0xaa, 0x87, 0x79, 0x6b, 0x6e, 0x60, 0x0c, 0x81, 0xf0, + 0x60, 0x2d, 0x62, 0x78, 0xc8, 0x1d, 0x27, 0x28, 0x0f, 0xc0, 0x3d, 0x98, 0x07, 0xe0, 0x1f, 0x10, + 0x38, 0xed, 0x92, 0x2b, 0x82, 0x6a, 0x73, 0x2c, 0xaf, 0xdd, 0x4d, 0x39, 0x00, 0xfc, 0x8e, 0x80, + 0x31, 0x4b, 0xdc, 0x52, 0x82, 0x9c, 0x16, 0x03, 0x87, 0xd5, 0xca, 0x62, 0xe5, 0xd4, 0xb3, 0x0b, + 0xe2, 0xae, 0x6c, 0x4f, 0xfe, 0x46, 0xf7, 0x90, 0xdd, 0x29, 0xf5, 0xb6, 0x42, 0x3f, 0xd1, 0x5a, + 0xa1, 0xdf, 0x46, 0x4c, 0x20, 0x4a, 0x86, 0x72, 0x5f, 0x5b, 0xc6, 0xff, 0x0d, 0x44, 0x35, 0x91, + 0xf7, 0x3d, 0xbe, 0x78, 0x7c, 0xb7, 0x03, 0x0e, 0x7d, 0x91, 0x24, 0xf2, 0xe8, 0x78, 0x1f, 0x03, + 0xf8, 0x0f, 0xe0, 0x7f, 0x03, 0xf0, 0x3e, 0x1f, 0x64, 0x1b, 0x84, 0x67, 0x94, 0x12, 0x20, 0x78, + 0xf3, 0x20, 0x26, 0x56, 0x7f, 0xd7, 0x1c, 0xf3, 0xfd, 0xf0, 0xe8, 0x29, 0xf0, 0x7c, 0xf2, 0x82, + 0x6f, 0x81, 0x07, 0x90, 0x3f, 0x03, 0xe2, 0x88, 0x31, 0x2b, 0xc8, 0x3d, 0xd2, 0x6a, 0x03, 0xcc, + 0x63, 0xc0, 0x39, 0xbf, 0x1b, 0x8d, 0x08, 0xa5, 0xfd, 0xdd, 0x32, 0x8e, 0x3c, 0x8e, 0x4c, 0x58, + 0xd8, 0x33, 0x7f, 0xa7, 0xb8, 0xbf, 0x8a, 0xbb, 0xe2, 0xd8, 0x12, 0xc5, 0x52, 0x1a, 0xe1, 0xb1, + 0x42, 0x07, 0xcc, 0x22, 0x76, 0x3e, 0x90, 0xb3, 0x00, 0xa6, 0x41, 0xb2, 0xa1, 0xd6, 0xfb, 0x57, + 0x00, 0x5b, 0xd3, 0x1e, 0x83, 0x1c, 0xab, 0x1d, 0x13, 0x25, 0x0b, 0xac, 0xff, 0x98, 0xd4, 0x57, + 0x9b, 0x0c, 0xb8, 0x0f, 0x0f, 0x87, 0xe0, 0x7e, 0x07, 0xf0, 0x1f, 0xc0, 0xf8, 0x05, 0xff, 0x9e, + 0x3b, 0x45, 0xc0, 0xfc, 0x69, 0xfc, 0x75, 0x6b, 0x4b, 0x2c, 0xc7, 0xf6, 0xbf, 0x22, 0x2c, 0xea, + 0x17, 0x89, 0xc3, 0x7f, 0x08, 0xee, 0x38, 0x22, 0x67, 0x74, 0x65, 0x0f, 0x7f, 0x00, 0xf7, 0x04, + 0x27, 0x38, 0xa9, 0xbf, 0xd2, 0x6a, 0x23, 0x1c, 0x63, 0xc6, 0xc2, 0x42, 0xcd, 0x56, 0x9d, 0x10, + 0x13, 0xbe, 0xdb, 0x5f, 0x7c, 0x58, 0x95, 0x42, 0xb0, 0xf7, 0x0c, 0xe7, 0xa2, 0x41, 0x72, 0x06, + 0xd0, 0xa2, 0x50, 0xd7, 0x6e, 0x9b, 0xd3, 0x91, 0xf9, 0x36, 0xea, 0x12, 0x6b, 0x10, 0xdc, 0x17, + 0xd5, 0x1d, 0xab, 0x1a, 0xea, 0x55, 0xe8, 0xba, 0xf4, 0x3d, 0x68, 0x0a, 0x46, 0x18, 0xc7, 0xef, + 0xfe, 0x94, 0x1f, 0x80, 0x52, 0x23, 0x36, 0x0e, 0x7a, 0xf4, 0xb7, 0x03, 0xf0, 0x7e, 0x07, 0xe0, + 0x7e, 0x07, 0xe0, 0x3f, 0x03, 0xe0, 0xeb, 0xed, 0xd1, 0x6a, 0xb9, 0xd0, 0xaa, 0x93, 0x61, 0xe7, + 0x00, 0xea, 0x7a, 0x34, 0x0e, 0x80, 0x04, 0x20, 0x86, 0x8f, 0xd7, 0x96, 0x22, 0xff, 0x64, 0x45, + 0xed, 0xc0, 0x44, 0xf7, 0x30, 0x44, 0xf2, 0x92, 0x27, 0x50, 0x01, 0x3f, 0xd2, 0x6a, 0x23, 0x5c, + 0xa7, 0x93, 0x9c, 0x4e, 0x56, 0x0f, 0xc9, 0x0e, 0x09, 0x8f, 0x16, 0x16, 0x67, 0x00, 0xc3, 0x9c, + 0x78, 0x02, 0xca, 0xb1, 0x24, 0x26, 0x40, 0x37, 0xce, 0xd5, 0x00, 0xee, 0x86, 0x26, 0x76, 0x6b, + 0xb0, 0xb3, 0x97, 0x5f, 0x92, 0x10, 0x13, 0x95, 0xcf, 0xf6, 0x49, 0x33, 0x7b, 0x85, 0xf6, 0x01, + 0x26, 0x4e, 0x12, 0xe2, 0xc6, 0xa5, 0x19, 0x1d, 0x63, 0x97, 0xd1, 0x60, 0xfa, 0x44, 0xf8, 0x75, + 0x8f, 0x50, 0xb2, 0x2a, 0x9f, 0x07, 0xe0, 0xfc, 0x0f, 0x80, 0xfe, 0x07, 0xf0, 0x3e, 0x0f, 0xb1, + 0x05, 0x05, 0x19, 0x2c, 0x20, 0x39, 0xaf, 0x8a, 0x48, 0xe9, 0xfb, 0x4e, 0xed, 0xc7, 0xbe, 0x6f, + 0x5b, 0xac, 0x58, 0x02, 0x3c, 0x84, 0xc6, 0xf6, 0xc0, 0x40, 0xf7, 0x78, 0x4d, 0xdd, 0x8b, 0x0d, + 0xe7, 0x50, 0x01, 0x3f, 0xd2, 0x6a, 0x43, 0x2c, 0xaf, 0xdd, 0xed, 0xea, 0x51, 0x7d, 0x91, 0x2c, + 0x07, 0x57, 0x30, 0x76, 0x1d, 0xd0, 0xe8, 0x5e, 0xf5, 0x2e, 0x02, 0xa0, 0xf5, 0x04, 0x52, 0x9d, + 0x22, 0xbf, 0xda, 0x21, 0x3b, 0x04, 0x96, 0x7e, 0x4f, 0xea, 0x2d, 0x0f, 0x69, 0xf0, 0xc3, 0xc2, + 0xea, 0x8e, 0x0f, 0xd9, 0xed, 0x9f, 0x91, 0x6a, 0x71, 0x7a, 0x1b, 0x5d, 0x3f, 0xc4, 0x5b, 0x93, + 0x64, 0xfb, 0x08, 0x49, 0x96, 0xd1, 0xd5, 0xf3, 0x2e, 0x38, 0x9f, 0x96, 0xd7, 0x43, 0xc3, 0xe0, + 0xf0, 0x7c, 0x1f, 0x81, 0xf8, 0x1f, 0x83, 0xd6, 0xb7, 0x69, 0x60, 0x02, 0xec, 0x37, 0xb8, 0x28, + 0x6f, 0x34, 0x37, 0xf5, 0x1d, 0x4b, 0x4b, 0x9f, 0x97, 0xb5, 0xfa, 0x5a, 0x50, 0xa6, 0xec, 0x01, + 0x3f, 0xb0, 0x07, 0x9a, 0x42, 0x7f, 0xc3, 0x09, 0xe7, 0x50, 0x01, 0x3f, 0xd2, 0x6a, 0x14, 0x34, + 0x33, 0xd3, 0xb2, 0xb7, 0x84, 0x00, 0x6e, 0x91, 0xe1, 0x20, 0x56, 0xef, 0x8b, 0x8e, 0x44, 0x6e, + 0xe5, 0xa7, 0x44, 0x89, 0x53, 0x82, 0xb6, 0xb2, 0xa1, 0xef, 0xa8, 0x9d, 0x42, 0x98, 0xa5, 0xde, + 0x26, 0xe5, 0xf2, 0xe6, 0x33, 0x76, 0x66, 0x58, 0x45, 0xeb, 0x40, 0x57, 0xc6, 0x91, 0x06, 0x8b, + 0x1c, 0xcf, 0x58, 0x89, 0xd9, 0x41, 0x93, 0x51, 0x18, 0xfe, 0x08, 0x86, 0x4f, 0x68, 0xbf, 0x21, + 0x65, 0x19, 0x76, 0xa6, 0x87, 0xe0, 0x7e, 0x0f, 0xc0, 0xfc, 0x0f, 0xe0, 0x3f, 0x81, 0xf8, 0x73, + 0x82, 0xc4, 0x87, 0x41, 0xe7, 0x37, 0x70, 0xf0, 0x0a, 0x9e, 0xeb, 0xa3, 0x02, 0x7c, 0x17, 0x81, + 0x2c, 0x26, 0xab, 0xa3, 0xa4, 0x84, 0xe0, 0x07, 0xf3, 0x00, 0x1f, 0x6e, 0x10, 0xf3, 0xc3, 0x06, + 0x27, 0x50, 0x01, 0x3f, 0xd2, 0x6a, 0x43, 0x34, 0xaf, 0xdd, 0x47, 0x5c, 0xd0, 0x54, 0x05, 0x05, + 0xec, 0x4a, 0x53, 0xf8, 0x78, 0x29, 0xbc, 0x82, 0x18, 0x56, 0x38, 0xd4, 0xcd, 0x63, 0xde, 0x94, + 0x75, 0xba, 0xcc, 0xd3, 0xaa, 0xcb, 0xce, 0x4e, 0x27, 0x05, 0x71, 0x74, 0xa6, 0xba, 0xa7, 0xae, + 0xe2, 0x30, 0x16, 0x21, 0x1f, 0x59, 0x51, 0x74, 0xac, 0x13, 0x24, 0xd8, 0x89, 0x5b, 0x7a, 0x61, + 0xa4, 0x49, 0x3e, 0xac, 0x0e, 0xe1, 0xa1, 0xf0, 0x10, 0x78, 0x17, 0xcd, 0x04, 0xf9, 0xb7, 0xac, + 0x9f, 0x0f, 0x83, 0xe0, 0xf8, 0x1f, 0x81, 0xf8, 0x1f, 0x83, 0xc0, 0x0e, 0x9f, 0x5b, 0xda, 0x2f, + 0xdc, 0x72, 0x49, 0x73, 0x02, 0xcf, 0x94, 0x18, 0xa7, 0x16, 0x1b, 0x52, 0x14, 0x1f, 0x1b, 0x7a, + 0xfd, 0x04, 0xcf, 0xc0, 0xfc, 0x07, 0xc6, 0x82, 0x67, 0x52, 0xfc, 0x3f, 0xd2, 0x6a, 0x23, 0x44, + 0x69, 0xd4, 0x3e, 0xe9, 0x79, 0x25, 0x1d, 0x3f, 0xe3, 0x88, 0x05, 0x0b, 0x8c, 0x76, 0x29, 0x7e, + 0xe7, 0xd5, 0x8a, 0xb6, 0x5f, 0x02, 0x85, 0x0e, 0x92, 0x70, 0xb8, 0x44, 0xff, 0x73, 0x7e, 0x47, + 0xe4, 0x30, 0xa4, 0x7f, 0x8a, 0x52, 0x2d, 0x18, 0xa6, 0x28, 0xa1, 0x43, 0x41, 0x2f, 0xaa, 0x69, + 0xba, 0xdb, 0x82, 0xd2, 0xc7, 0x8b, 0xa4, 0x31, 0x85, 0x9b, 0x87, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x73, 0xec, 0x31, 0x42, 0xd2, 0xa7, 0xf9, 0x71, 0x47, 0xc3, 0xe1, 0xf8, 0x1f, 0x81, 0xf8, 0x3e, + 0x0f, 0x11, 0xe9, 0xd3, 0x35, 0xef, 0x37, 0xd6, 0xe4, 0x1a, 0xed, 0x15, 0x73, 0xa7, 0xf3, 0x93, + 0x76, 0xb1, 0x56, 0x5f, 0x78, 0xdc, 0x92, 0x39, 0xbb, 0x90, 0x03, 0xf8, 0x1f, 0x83, 0xf3, 0x05, + 0x67, 0xe7, 0xfa, 0x3f, 0xd2, 0x6a, 0x26, 0x34, 0x35, 0x15, 0x69, 0xd5, 0x3a, 0xa2, 0xc3, 0x59, + 0x46, 0x4c, 0x85, 0x96, 0xaa, 0xc2, 0x9f, 0x34, 0x4c, 0x72, 0x21, 0x98, 0xa7, 0xea, 0xfb, 0xce, + 0xf8, 0xec, 0xce, 0x01, 0x02, 0xa1, 0x70, 0x16, 0x25, 0x1b, 0x7c, 0xb2, 0x38, 0x91, 0x9c, 0xbf, + 0xb8, 0x0a, 0xd4, 0x06, 0xf7, 0x30, 0xcb, 0x51, 0xbf, 0x76, 0x56, 0x2e, 0x9a, 0xeb, 0xb5, 0x8f, + 0x2d, 0x97, 0x6c, 0xc2, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x76, 0x62, 0xab, 0xeb, 0x7d, + 0x4f, 0x07, 0xc1, 0xf0, 0x7e, 0x07, 0xe0, 0x7e, 0x0f, 0x83, 0x9c, 0x10, 0x6d, 0x2a, 0x41, 0x2c, + 0x62, 0x51, 0xc2, 0x35, 0x2d, 0xb3, 0x88, 0x9e, 0x77, 0xc1, 0xe7, 0xad, 0x83, 0xe6, 0x48, 0x80, + 0xde, 0x80, 0x0f, 0xb2, 0x03, 0xf0, 0x3e, 0x88, 0x27, 0xe7, 0xfa, 0x3f, 0xd2, 0x6a, 0x36, 0x3c, + 0xa7, 0x91, 0xec, 0x56, 0xe1, 0x98, 0x95, 0xe9, 0x1d, 0xbc, 0xc2, 0x4a, 0x52, 0x0b, 0x1c, 0x89, + 0x27, 0x28, 0x9b, 0x34, 0x2c, 0x75, 0xb2, 0x56, 0x2f, 0x2c, 0x3f, 0x02, 0x00, 0xc6, 0x99, 0xff, + 0x88, 0x4e, 0x09, 0xde, 0xde, 0x4f, 0xec, 0xe1, 0xdf, 0x4d, 0x20, 0x62, 0x10, 0x56, 0x83, 0x17, + 0x96, 0x25, 0x37, 0x43, 0xc4, 0x8b, 0x9b, 0xaf, 0xd1, 0x13, 0x84, 0x3c, 0x08, 0x4a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x76, 0x0f, 0xdb, 0xda, 0x39, 0xd6, 0xf0, 0x7c, 0x1e, 0x07, 0xc1, 0xf8, + 0x1f, 0x83, 0xc3, 0xdc, 0x81, 0x20, 0x60, 0x23, 0x26, 0x5c, 0x10, 0x75, 0xc4, 0x4b, 0x4e, 0xa8, + 0x84, 0x8c, 0x3b, 0x5c, 0xc4, 0xdc, 0x28, 0x39, 0x91, 0x01, 0xe7, 0x03, 0xf8, 0x0f, 0xc3, 0x0b, + 0x27, 0xe7, 0xfa, 0x3f, 0xd2, 0x6a, 0x66, 0x1c, 0xaf, 0xdd, 0xe6, 0x14, 0x51, 0x1d, 0x3e, 0x4d, + 0xf9, 0x6e, 0xb8, 0x18, 0x1f, 0x89, 0x35, 0xa4, 0xc6, 0x79, 0x15, 0x60, 0xeb, 0x82, 0xb7, 0xae, + 0x98, 0x7c, 0x70, 0x5c, 0x5d, 0xab, 0x99, 0x44, 0xd0, 0x4d, 0x7d, 0xb2, 0xb2, 0x18, 0x15, 0x99, + 0x4b, 0x1d, 0x06, 0xad, 0x85, 0x51, 0xd7, 0x4f, 0xe8, 0x3b, 0xbf, 0x3b, 0x20, 0x5d, 0xb5, 0x9e, + 0xec, 0x2b, 0x9d, 0xa1, 0xd8, 0x8b, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xb5, 0x43, 0xbf, + 0xbc, 0x78, 0x3e, 0x0f, 0x83, 0xf0, 0x1f, 0x83, 0xc3, 0x9a, 0x3c, 0xc6, 0x22, 0x02, 0x31, 0x0d, + 0x74, 0xd6, 0x10, 0xb1, 0x8a, 0x37, 0xab, 0x8d, 0xdb, 0xa0, 0xc8, 0x26, 0x8d, 0x8e, 0x44, 0x5f, + 0x60, 0xbc, 0xe0, 0x3f, 0x01, 0xf8, 0x1f, 0x04, 0x27, 0xe7, 0xfa, 0x3f, 0xd2, 0x6a, 0x45, 0xa4, + 0x3f, 0xa9, 0x40, 0x35, 0xdd, 0x67, 0x11, 0x0b, 0xa4, 0x4d, 0x3c, 0xc4, 0xc1, 0x33, 0x8d, 0xe7, + 0xcc, 0x54, 0xe6, 0xf9, 0x68, 0x49, 0xa7, 0x13, 0x19, 0x19, 0xe1, 0x34, 0x9e, 0xc9, 0xcc, 0x42, + 0x08, 0x36, 0xb6, 0x53, 0x01, 0xc2, 0x13, 0x36, 0x48, 0xe5, 0x05, 0x1c, 0xa1, 0x51, 0xa7, 0x17, + 0x43, 0x1e, 0x4e, 0xe4, 0x2c, 0x56, 0xbe, 0x00, 0x00, 0x00, 0x0a, 0x96, 0x82, 0xdd, 0x7b, 0xa1, + 0xdc, 0x9b, 0xc7, 0xae, 0xce, 0xd3, 0x6a, 0x04, 0x8a, 0x5c, 0x0c, 0xf8, 0x70, 0x0f, 0xbf, 0x57, + 0x5a, 0xdc, 0x3a, 0x27, 0xd0, 0x9f, 0x66, 0xda, 0x2c, 0xbd, 0x47, 0x2f, 0xbe, 0x1a, 0x91, 0x47, + 0xe8, 0x8e, 0x27, 0x8b, 0x9a, 0xcb, 0xf2, 0x48, 0x7e, 0x07, 0xc1, 0xf8, 0x1e, 0xf6, 0x0a, 0x87, + 0x27, 0xe7, 0xfa, 0x3f, 0xd2, 0x79, 0xf6, 0x3c, 0x33, 0x99, 0xb9, 0xa2, 0xb8, 0x20, 0xa8, 0xd0, + 0x14, 0xc3, 0xc7, 0xbd, 0x56, 0x64, 0x68, 0x11, 0x39, 0x6c, 0xd6, 0x71, 0x8f, 0xca, 0x73, 0x0f, + 0x39, 0xce, 0xf3, 0x2d, 0xd2, 0xb6, 0xc2, 0x0d, 0x00, 0x0d, 0xd7, 0xda, 0xb7, 0xa8, 0xa7, 0x2f, + 0x64, 0xdd, 0x61, 0x33, 0x6a, 0xe5, 0x01, 0x56, 0xdb, 0x57, 0xc8, 0xd0, 0x99, 0x25, 0xa3, 0xbf, + 0xe8, 0x99, 0xad, 0x1b, 0x14, 0xe5, 0x19, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, + 0xff, 0xe3, 0xc0, 0xfc, 0x0f, 0xc0, 0xfc, 0x07, 0xe0, 0x78, 0x0f, 0x66, 0x77, 0xb9, 0xf7, 0xfc, + 0x8e, 0xa8, 0x45, 0xe2, 0xed, 0xcc, 0xa3, 0xbc, 0x63, 0x25, 0xe0, 0x8c, 0xdb, 0xf1, 0x03, 0x99, + 0x03, 0xf6, 0x00, 0x9f, 0xe0, 0x1f, 0xc3, 0x0d, 0x27, 0xe7, 0x96, 0x3f, 0xd2, 0x6a, 0x55, 0xbc, + 0x69, 0xac, 0x33, 0x2a, 0x32, 0xd6, 0x00, 0xf5, 0x23, 0x68, 0xb5, 0x0a, 0x0d, 0x7a, 0xcf, 0x1f, + 0xf7, 0xa3, 0x8e, 0xf6, 0x01, 0x61, 0x3c, 0x7d, 0x41, 0x95, 0x21, 0xce, 0x2f, 0xe9, 0x70, 0xb3, + 0xc3, 0x30, 0x21, 0xc6, 0xe5, 0x8a, 0x27, 0x72, 0x7f, 0x0f, 0xcc, 0x0a, 0x90, 0x9f, 0xbd, 0xcd, + 0x5a, 0x8c, 0xf5, 0x59, 0xcb, 0x29, 0xff, 0xc5, 0x58, 0x00, 0x79, 0x88, 0xdc, 0xf3, 0x8a, 0x19, + 0x7f, 0x5f, 0x1d, 0x73, 0x4b, 0x32, 0xa4, 0xdb, 0x74, 0xe1, 0xac, 0x3e, 0x0f, 0xc0, 0x00, 0xd0, + 0xe2, 0x5e, 0xa2, 0x12, 0x93, 0x5b, 0x2f, 0x83, 0x88, 0x00, 0x52, 0xdd, 0x2a, 0xd0, 0x12, 0x31, + 0x85, 0x4f, 0x62, 0x18, 0x7f, 0xae, 0x3e, 0x90, 0x3c, 0x3e, 0x0f, 0xc1, 0xf1, 0x91, 0x3a, 0x16, + 0x27, 0xe7, 0x96, 0x3b, 0xd2, 0x7a, 0x06, 0x3c, 0xaf, 0xdc, 0xb8, 0x33, 0x53, 0x0e, 0x82, 0xd0, + 0x2d, 0x35, 0x02, 0x56, 0x8b, 0xa3, 0x75, 0x19, 0xce, 0x1d, 0xd0, 0x3f, 0x25, 0x19, 0x13, 0xc6, + 0x96, 0xc5, 0x1d, 0x4a, 0x0f, 0x06, 0xae, 0x07, 0x3e, 0xf1, 0x0d, 0x05, 0x99, 0x16, 0xce, 0x7d, + 0x6e, 0x50, 0xed, 0xdb, 0x6e, 0x7e, 0x7d, 0x90, 0xb4, 0xd0, 0x78, 0x5a, 0x98, 0x33, 0xa1, 0x7f, + 0xfc, 0x43, 0x27, 0x4b, 0x2a, 0xe3, 0x8c, 0xd0, 0x90, 0x1f, 0xae, 0x5f, 0x26, 0x1e, 0x1e, 0x0f, + 0xc0, 0xfc, 0x0f, 0xc1, 0xf0, 0x3f, 0x8e, 0x2a, 0x7b, 0xdc, 0x96, 0x1f, 0x9b, 0x7c, 0x27, 0x8f, + 0x6e, 0x0d, 0x0c, 0xd8, 0xa4, 0xf8, 0xd6, 0x9e, 0x3b, 0xf1, 0x4f, 0x01, 0xc0, 0x86, 0x63, 0xb6, + 0x01, 0xf8, 0x23, 0xee, 0x07, 0xe0, 0x3e, 0x9f, 0x26, 0x4c, 0x20, 0xfb, 0xd2, 0x6a, 0x03, 0xec, + 0x17, 0x53, 0xd0, 0x86, 0xa5, 0xe8, 0x6d, 0x4d, 0xbe, 0x39, 0xb9, 0xa5, 0x84, 0xc6, 0x65, 0x73, + 0x7c, 0x85, 0x03, 0x8b, 0xa7, 0xda, 0x83, 0x20, 0x7d, 0x0b, 0x4d, 0xcf, 0x76, 0xcb, 0x5c, 0x2e, + 0x2c, 0x4a, 0x51, 0xfc, 0xed, 0xf5, 0xb2, 0x0b, 0x0f, 0x0f, 0xe5, 0xe1, 0x2d, 0x10, 0x1a, 0xa3, + 0xcb, 0x72, 0x90, 0xab, 0xda, 0x00, 0xda, 0xcf, 0x45, 0xcc, 0x92, 0xb1, 0x56, 0x88, 0xae, 0x86, + 0x27, 0x58, 0x70, 0x80, 0x20, 0x0f, 0xe0, 0x3e, 0x07, 0xf0, 0x1f, 0x80, 0xfe, 0x07, 0x8f, 0xb0, + 0x83, 0xb1, 0xc0, 0x27, 0x20, 0x70, 0xa1, 0xc8, 0x62, 0x2a, 0xdc, 0xae, 0x70, 0xe8, 0xd5, 0xec, + 0x9e, 0xfb, 0xfe, 0xcd, 0x42, 0x2f, 0x80, 0x0f, 0xb8, 0x0f, 0xf0, 0x0f, 0xb7, 0x00, 0xfa, 0x95, + 0x27, 0xce, 0x0d, 0xbb, 0xd2, 0x6a, 0x43, 0xdc, 0x35, 0x7f, 0x0d, 0x4c, 0x15, 0xef, 0xff, 0x79, + 0x66, 0x85, 0x1c, 0x28, 0xef, 0x72, 0x31, 0xf1, 0x4a, 0x76, 0x45, 0x5a, 0xd5, 0xf2, 0xed, 0xb9, + 0x36, 0xad, 0x63, 0x9c, 0x43, 0x33, 0xc0, 0xf2, 0x26, 0xad, 0x99, 0x18, 0xb7, 0xdf, 0x09, 0x9e, + 0xd2, 0xc1, 0x55, 0x5b, 0x95, 0xa5, 0xba, 0x98, 0xec, 0x96, 0x3b, 0x93, 0x0d, 0x94, 0x6d, 0xc9, + 0x0e, 0xae, 0x65, 0xcc, 0x9b, 0x1a, 0xd8, 0x54, 0x18, 0xe1, 0x80, 0x0a, 0xe0, 0x1c, 0xe4, 0xf3, + 0xe0, 0x7c, 0x1f, 0x83, 0xf0, 0x1f, 0xc0, 0xf8, 0x3c, 0x1f, 0xab, 0xa9, 0xe8, 0xee, 0x30, 0x5d, + 0x8f, 0x19, 0x57, 0xf5, 0xaa, 0x78, 0xe5, 0x69, 0xf4, 0x11, 0x13, 0x73, 0x17, 0x47, 0xfd, 0xc0, + 0x3d, 0xc8, 0x1f, 0xc0, 0xfc, 0x07, 0xe2, 0xa0, 0xc6, 0x3d, 0xab, 0x3b, 0xd2, 0x6a, 0x24, 0x5c, + 0xb7, 0xcc, 0x62, 0xe4, 0x68, 0xfe, 0x89, 0x40, 0x8a, 0x0a, 0xc0, 0x0e, 0xf8, 0x35, 0x2d, 0xc7, + 0x90, 0xc0, 0x07, 0xbf, 0x4e, 0x32, 0xd5, 0x0a, 0xb2, 0x89, 0xe3, 0xa5, 0x6c, 0x0f, 0xe7, 0x49, + 0x27, 0xe3, 0xa8, 0xf5, 0xb5, 0x51, 0x96, 0x00, 0x4b, 0x3a, 0x4a, 0xbd, 0x2f, 0xd8, 0x45, 0x20, + 0x14, 0x82, 0xd8, 0xaf, 0xd5, 0x17, 0x3d, 0xf5, 0x1b, 0xd9, 0x37, 0x8a, 0x56, 0xf6, 0x19, 0x16, + 0xd3, 0x02, 0x37, 0xb5, 0xc0, 0xf1, 0x7e, 0xf3, 0x87, 0xc3, 0xf0, 0xfc, 0x3e, 0x1f, 0x03, 0xa6, + 0xa6, 0xbd, 0x86, 0x87, 0x7f, 0xee, 0xef, 0x69, 0x80, 0x7c, 0xee, 0x8b, 0x3f, 0xf2, 0x04, 0x82, + 0xc1, 0xad, 0xe9, 0x10, 0x56, 0x98, 0xa9, 0x4c, 0xb2, 0xa3, 0x9d, 0xf0, 0x3c, 0xf8, 0x7a, 0x17, + 0x07, 0xcb, 0x15, 0xbb, 0xd2, 0x79, 0xf5, 0x7c, 0xaf, 0xdd, 0x5d, 0x70, 0x6c, 0xfd, 0x44, 0x6a, + 0x11, 0x28, 0x28, 0x00, 0x01, 0x20, 0x77, 0x41, 0xb0, 0x01, 0xde, 0x49, 0x2e, 0x48, 0x76, 0xa1, + 0x4b, 0x17, 0xe0, 0x0e, 0x04, 0x23, 0xca, 0x32, 0x74, 0x27, 0x50, 0x02, 0xcc, 0x4d, 0xc6, 0x49, + 0x5b, 0xbb, 0x7e, 0xa4, 0xbf, 0xa0, 0x6c, 0x12, 0x85, 0xa8, 0x0f, 0x26, 0xfe, 0x97, 0x52, 0x68, + 0xc7, 0xfc, 0x0f, 0x5d, 0x9c, 0xbb, 0x6c, 0x13, 0xf9, 0xd1, 0x86, 0x83, 0x58, 0x79, 0xef, 0x61, + 0x87, 0x8d, 0x06, 0x30, 0xe3, 0xf8, 0x49, 0x11, 0x76, 0x45, 0x21, 0x2a, 0x4f, 0x46, 0x57, 0xf6, + 0x38, 0xce, 0xb4, 0x2b, 0x2f, 0xe7, 0x74, 0x68, 0x49, 0x5e, 0x64, 0x62, 0x5f, 0x1d, 0xe6, 0x3e, + 0x50, 0x78, 0x7c, 0x18, 0x0f, 0xe0, 0x3e, 0x35, 0x07, 0xcb, 0x15, 0xbb, 0xd2, 0x79, 0xe4, 0xf4, + 0x69, 0xd4, 0x53, 0xa1, 0xf3, 0x0e, 0xec, 0xe2, 0xa2, 0x7e, 0xde, 0xe0, 0x5d, 0x49, 0x92, 0x4e, + 0xd9, 0xca, 0x6c, 0x1f, 0x60, 0x07, 0x32, 0x68, 0xab, 0x6d, 0xb7, 0x0d, 0x45, 0xa5, 0x93, 0x71, + 0xd3, 0x2c, 0x11, 0x24, 0xfc, 0xbb, 0x5e, 0x0f, 0xea, 0xdd, 0x33, 0x13, 0xcd, 0x83, 0x46, 0x14, + 0x3d, 0x11, 0xcc, 0x97, 0x03, 0x18, 0x90, 0x2e, 0x52, 0x83, 0xae, 0xff, 0xa8, 0x79, 0x15, 0x2a, + 0x2f, 0xac, 0x3b, 0x0b, 0x4c, 0xea, 0xa0, 0x63, 0x38, 0xf0, 0x7f, 0xfd, 0xa7, 0xfb, 0xa3, 0xca, + 0x5f, 0x79, 0xeb, 0x67, 0x49, 0x51, 0x09, 0x44, 0x02, 0x41, 0x2d, 0xa0, 0xc2, 0x1c, 0x9f, 0x99, + 0x3b, 0xab, 0xdb, 0x09, 0x59, 0xca, 0xb4, 0xd0, 0xc7, 0xc0, 0xfc, 0x1f, 0xb0, 0x88, 0xfe, 0xab, + 0x06, 0x3d, 0xab, 0x3b, 0xd2, 0x79, 0xc4, 0x34, 0xb0, 0xdc, 0x62, 0xbe, 0x61, 0x09, 0x75, 0x38, + 0x4f, 0x05, 0x02, 0xd7, 0xea, 0xbb, 0x0b, 0x1e, 0xb9, 0x2f, 0x21, 0x73, 0x59, 0x34, 0x24, 0x53, + 0x10, 0x1f, 0xa4, 0x1c, 0xc2, 0xf3, 0x7c, 0x46, 0x5a, 0x20, 0x6b, 0x6f, 0x0a, 0x76, 0xc7, 0x10, + 0xeb, 0x21, 0x8c, 0x46, 0x57, 0xf9, 0x2d, 0xd9, 0x54, 0x4c, 0x51, 0x7a, 0xf0, 0xdd, 0x77, 0xae, + 0x94, 0xe3, 0x9e, 0xaa, 0xb4, 0x01, 0xc6, 0x7a, 0x00, 0x00, 0x00, 0x02, 0x37, 0xed, 0x8b, 0x51, + 0x48, 0xc7, 0x0f, 0x0e, 0x0f, 0x07, 0xf9, 0x1a, 0x0a, 0x06, 0xa0, 0x83, 0x00, 0x52, 0x9e, 0xf9, + 0xee, 0xbe, 0xc2, 0x1d, 0xab, 0x26, 0xa6, 0x5c, 0x95, 0x51, 0x0b, 0x55, 0xee, 0x4f, 0x8b, 0x19, + 0x8f, 0x33, 0x01, 0x07, 0xe1, 0x83, 0xc6, 0x39, 0x47, 0xcb, 0x15, 0xbf, 0xd2, 0x79, 0xf5, 0x84, + 0x69, 0xd5, 0x7f, 0x4f, 0xd0, 0xba, 0xd5, 0xf0, 0xca, 0xf9, 0x55, 0x53, 0x2d, 0x5d, 0xdd, 0x68, + 0x17, 0x3c, 0xa0, 0x7f, 0x91, 0xde, 0xfe, 0x79, 0x26, 0x2c, 0x56, 0x0d, 0x6d, 0xbc, 0x41, 0x2c, + 0xb6, 0x6e, 0xdf, 0x46, 0x8f, 0x3a, 0xbd, 0x82, 0x4b, 0xd1, 0x64, 0xb2, 0x65, 0xb6, 0x5c, 0x11, + 0x7a, 0xb1, 0xfc, 0x37, 0xda, 0x1d, 0x15, 0x9c, 0x73, 0x2f, 0x39, 0x0e, 0xc8, 0xf9, 0x00, 0x00, + 0x00, 0x00, 0x32, 0x44, 0x6c, 0x0c, 0xb5, 0x36, 0x6e, 0xe1, 0xf0, 0x1e, 0x9f, 0x1d, 0x73, 0xab, + 0x16, 0x46, 0x7e, 0xfb, 0x8e, 0x41, 0xd1, 0xb6, 0x4e, 0xa6, 0x92, 0xe3, 0x5b, 0x6b, 0xd7, 0x28, + 0xfc, 0x56, 0x60, 0x6d, 0x8b, 0x11, 0x2f, 0x38, 0x37, 0xe7, 0x1f, 0x1e, 0x1f, 0x80, 0xf2, 0x95, + 0x06, 0x3d, 0x3d, 0x3f, 0xd2, 0x79, 0xe5, 0x64, 0x69, 0x36, 0x3a, 0x20, 0x8b, 0xb3, 0x05, 0xc1, + 0x8d, 0xe6, 0x37, 0xe2, 0xef, 0xf6, 0xf5, 0xee, 0x37, 0x32, 0xb7, 0x81, 0xc1, 0x18, 0xe6, 0x32, + 0xf3, 0x50, 0x34, 0x2a, 0x5c, 0xba, 0x54, 0xab, 0x34, 0x15, 0x96, 0xb0, 0x9e, 0xb2, 0x8e, 0xe8, + 0x28, 0xac, 0x26, 0xd9, 0xf5, 0x46, 0xbd, 0x94, 0x28, 0x3f, 0x7a, 0x32, 0x28, 0xe7, 0x60, 0x20, + 0x9c, 0xe7, 0x1b, 0x88, 0xfa, 0x7b, 0x18, 0x45, 0xfc, 0xdd, 0x20, 0xd0, 0xe3, 0x4e, 0xe6, 0x62, + 0xc3, 0x87, 0x07, 0xc1, 0xfb, 0x2e, 0xec, 0xbe, 0xe6, 0xb2, 0x98, 0xa8, 0x8d, 0x00, 0x8e, 0x64, + 0xa3, 0xb4, 0x36, 0xc0, 0x9c, 0x87, 0x14, 0xc4, 0x14, 0x72, 0xd8, 0xa3, 0x34, 0x13, 0x0b, 0x41, + 0x7e, 0x71, 0x81, 0xe1, 0xf8, 0x80, 0xf6, 0x88, 0xe7, 0xcc, 0x07, 0xbf, 0xd2, 0x79, 0xe6, 0x2c, + 0x69, 0xf1, 0xf5, 0x5a, 0x22, 0xc4, 0xa2, 0x02, 0x0f, 0x0f, 0xb1, 0xc4, 0x35, 0xad, 0x7d, 0x21, + 0x7b, 0x26, 0xb6, 0x63, 0xe4, 0xa4, 0xe7, 0xc7, 0x26, 0xcc, 0xf7, 0x6d, 0x7e, 0x33, 0x1a, 0xd2, + 0x9d, 0xd7, 0xb4, 0xca, 0x97, 0x5b, 0x15, 0xc0, 0x99, 0xb4, 0xe8, 0x3e, 0xad, 0xcb, 0x14, 0x87, + 0xc4, 0x96, 0x1e, 0x78, 0xad, 0x9d, 0x40, 0x31, 0x51, 0x02, 0xdb, 0x18, 0x33, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x81, 0x64, 0xdb, 0xf1, 0xe1, 0xf0, 0x7c, 0x1f, 0x03, 0xfb, 0x93, 0x0c, + 0x33, 0x50, 0x84, 0x93, 0xc8, 0x54, 0xed, 0x60, 0xe6, 0x1a, 0x78, 0xc4, 0x78, 0x91, 0x96, 0xaa, + 0x6c, 0x7d, 0x77, 0xd8, 0x3e, 0x1d, 0x19, 0x3b, 0xf3, 0x01, 0xc1, 0xf8, 0x7e, 0x07, 0xe2, 0x97, + 0x26, 0x3d, 0x3d, 0x3f, 0xd2, 0x79, 0xd6, 0x14, 0x69, 0xd4, 0x53, 0xa3, 0xe8, 0x70, 0x4a, 0x81, + 0xf6, 0xd3, 0x9c, 0x63, 0xec, 0x68, 0x9c, 0x8e, 0x6f, 0x1f, 0xde, 0xce, 0x4c, 0xcf, 0xa4, 0x67, + 0x8a, 0x6b, 0x6e, 0x1e, 0x80, 0x26, 0x85, 0x95, 0xe8, 0x72, 0x78, 0x6f, 0xca, 0xb7, 0x41, 0xe1, + 0x34, 0x8f, 0xdb, 0x72, 0x39, 0xd0, 0xc8, 0x29, 0xf9, 0x57, 0xd3, 0x74, 0x8c, 0x2d, 0xcb, 0xf0, + 0x33, 0x50, 0x09, 0x12, 0x31, 0xea, 0x1f, 0xc0, 0xe4, 0x6d, 0x7f, 0x00, 0x00, 0x0e, 0x50, 0xd9, + 0x0a, 0x23, 0xe1, 0xc0, 0xf8, 0x3e, 0x07, 0x96, 0x4e, 0x4f, 0x83, 0x5c, 0xef, 0xea, 0xf2, 0xd9, + 0x5c, 0xf9, 0x62, 0x0b, 0x5b, 0xf5, 0xb0, 0xaa, 0xd0, 0x38, 0x17, 0x16, 0x93, 0x6f, 0x0f, 0xc0, + 0xce, 0x72, 0x30, 0xf8, 0xfc, 0x20, 0xfa, 0x8b, 0x27, 0xcc, 0x07, 0xbf, 0xd2, 0x79, 0xf6, 0x14, + 0x69, 0xd4, 0x8e, 0x07, 0x5e, 0x1e, 0xb3, 0x98, 0x6c, 0x51, 0x60, 0xba, 0xd9, 0x89, 0xde, 0xb9, + 0x2a, 0x19, 0xcf, 0x18, 0xd0, 0x53, 0x46, 0x8a, 0x36, 0xe6, 0xf6, 0x48, 0x89, 0xb4, 0x96, 0x8b, + 0x86, 0xe9, 0xb4, 0x36, 0xec, 0x19, 0x7e, 0x88, 0x8f, 0x0d, 0xd3, 0xd6, 0x6a, 0xd0, 0xc8, 0x3e, + 0xf7, 0xe7, 0x03, 0xac, 0xb8, 0xaa, 0x0f, 0xd1, 0x66, 0x30, 0x13, 0x44, 0x12, 0x98, 0xc3, 0x64, + 0x5b, 0x90, 0x08, 0x4d, 0xb5, 0x4d, 0xde, 0x6f, 0x20, 0x2d, 0xf8, 0x7d, 0xb9, 0x57, 0x8f, 0x0f, + 0x83, 0xfc, 0xd4, 0x10, 0xcd, 0xe5, 0x65, 0xd7, 0xb8, 0x54, 0x7c, 0x78, 0xe6, 0xb4, 0xe0, 0xc3, + 0x74, 0x04, 0xf9, 0x0e, 0xdd, 0xf2, 0x69, 0xc1, 0x69, 0xcc, 0x82, 0x67, 0x8c, 0x0f, 0xe2, 0x96, + 0x27, 0xcc, 0x07, 0xbf, 0xd2, 0x79, 0xc6, 0x3c, 0xaa, 0xf5, 0xee, 0xed, 0x94, 0x04, 0x6b, 0x57, + 0x87, 0xef, 0xe1, 0xd8, 0x8b, 0x2f, 0x73, 0x7e, 0xbf, 0xbe, 0x65, 0x4a, 0x47, 0xe4, 0xea, 0x59, + 0x02, 0xde, 0xdd, 0x6e, 0xd0, 0xf6, 0x07, 0x3f, 0x8d, 0x19, 0x4b, 0x8e, 0xa0, 0x35, 0xb7, 0x93, + 0xe2, 0x6a, 0xd8, 0x58, 0xbb, 0x32, 0xa9, 0xcc, 0xe4, 0xa4, 0xbf, 0x73, 0xfe, 0xfd, 0xf8, 0x34, + 0x45, 0x00, 0x00, 0xdd, 0xf7, 0x80, 0x28, 0x98, 0x95, 0x80, 0x28, 0xd1, 0x78, 0x30, 0x55, 0x82, + 0x70, 0xe1, 0xe0, 0x7e, 0x03, 0x1d, 0xfe, 0xd3, 0xf1, 0xe0, 0x7c, 0x17, 0x3f, 0x46, 0x0b, 0x04, + 0xbb, 0xc4, 0x24, 0x0c, 0x0b, 0xa2, 0xb3, 0x08, 0xa4, 0x97, 0xa2, 0x2b, 0x8d, 0xe9, 0xd1, 0xaf, + 0xf8, 0x61, 0xc1, 0xe7, 0xf0, 0x08, 0xfa, 0x9e, 0x27, 0xcc, 0x07, 0xbf, 0xd2, 0x79, 0xd5, 0x44, + 0x69, 0xd4, 0x54, 0x54, 0x30, 0x36, 0x69, 0x18, 0x07, 0xe4, 0xba, 0x8e, 0xd5, 0x08, 0xe6, 0x1b, + 0xf4, 0x6f, 0x93, 0xe0, 0xb0, 0xf5, 0xa7, 0x30, 0x34, 0x47, 0x53, 0x4f, 0xde, 0xbb, 0x83, 0xd9, + 0x24, 0x1e, 0xa3, 0xd5, 0x8a, 0x63, 0xda, 0x21, 0xf5, 0xfe, 0xe2, 0x61, 0x05, 0x10, 0xc2, 0x95, + 0xe7, 0xc4, 0x35, 0xcb, 0xa9, 0xe5, 0xe4, 0xe8, 0xde, 0x10, 0xc7, 0xcd, 0x16, 0x15, 0x03, 0xa3, + 0xa7, 0x00, 0x00, 0x42, 0xcc, 0x9c, 0x39, 0x31, 0xcc, 0x66, 0x8f, 0x0f, 0x0f, 0x83, 0xf0, 0x42, + 0xff, 0xee, 0xd0, 0x26, 0x62, 0x0b, 0x80, 0xd0, 0x86, 0xee, 0x19, 0x19, 0x41, 0xcf, 0x8d, 0xfa, + 0x7e, 0x51, 0xd4, 0x46, 0x81, 0x84, 0x45, 0x84, 0x7b, 0x87, 0x87, 0xc7, 0xf0, 0x00, 0xf2, 0x95, + 0x27, 0xcc, 0x07, 0xbf, 0xd2, 0x79, 0xe6, 0x2c, 0xaf, 0xdd, 0x74, 0x2e, 0x0e, 0x76, 0xa9, 0x35, + 0xf5, 0xa3, 0x37, 0xa7, 0x42, 0xd0, 0x54, 0x22, 0x66, 0xf7, 0xb4, 0x42, 0x4f, 0x70, 0x9f, 0x2c, + 0x9b, 0xf8, 0x69, 0x44, 0x94, 0xae, 0xf8, 0x40, 0xd0, 0x67, 0x52, 0x53, 0xdd, 0x46, 0xf5, 0xc8, + 0xa4, 0x08, 0xfc, 0x4f, 0xcb, 0xc5, 0x31, 0x69, 0xc2, 0x4b, 0x60, 0x1d, 0x6a, 0x4a, 0xba, 0x46, + 0x7b, 0xc8, 0xad, 0x97, 0x83, 0x3b, 0x38, 0x02, 0xdd, 0xf9, 0x49, 0x76, 0xfa, 0xbf, 0xc2, 0xf6, + 0xcf, 0x98, 0xfe, 0x02, 0xcf, 0xc7, 0x43, 0xaa, 0xc8, 0x0f, 0xe3, 0xcc, 0x2d, 0x32, 0x58, 0x75, + 0x93, 0x36, 0x08, 0x3f, 0x70, 0x55, 0xda, 0x2f, 0x68, 0x67, 0x6b, 0x97, 0x3b, 0x69, 0xd4, 0xf1, + 0x3d, 0x2c, 0x03, 0x97, 0xc0, 0x77, 0xe2, 0x0f, 0x27, 0xd4, 0x8f, 0x3f, 0xd2, 0x79, 0xc5, 0x8c, + 0xaf, 0xae, 0x9d, 0x0f, 0x5d, 0x27, 0xcd, 0xc5, 0x34, 0x0d, 0xe2, 0x2b, 0x3e, 0xcf, 0x3b, 0x14, + 0xa2, 0xc5, 0x5f, 0x8b, 0x51, 0x2f, 0x5e, 0x93, 0x79, 0x92, 0xbc, 0x5f, 0x61, 0xb2, 0xfe, 0xa1, + 0x69, 0xc9, 0x22, 0x6c, 0xb3, 0xfc, 0xd2, 0x19, 0xbe, 0x36, 0x6e, 0x50, 0x24, 0xbe, 0xc8, 0x78, + 0xc6, 0xfc, 0x9a, 0xe2, 0xa0, 0x78, 0x53, 0x05, 0xef, 0x1d, 0xe9, 0x97, 0x11, 0x45, 0xa6, 0x3a, + 0xf5, 0x5e, 0x00, 0x02, 0x5a, 0x27, 0x4e, 0x69, 0x44, 0x36, 0x47, 0x0f, 0xc0, 0x7c, 0xb8, 0xad, + 0x43, 0xea, 0xe3, 0x81, 0x07, 0x0a, 0xd3, 0x5b, 0x09, 0x4f, 0x08, 0x3d, 0x95, 0xca, 0x49, 0xed, + 0x56, 0x4e, 0xe9, 0x1a, 0xec, 0xc1, 0x61, 0x1f, 0x08, 0x84, 0xef, 0x8c, 0x71, 0xf0, 0x3e, 0x0c, + 0x27, 0xd4, 0x8f, 0x3f, 0xd2, 0x79, 0xd5, 0x5c, 0xaf, 0x08, 0x0c, 0xb0, 0xd5, 0x02, 0xc9, 0xe1, + 0xde, 0x81, 0xec, 0xbf, 0x8e, 0x50, 0x01, 0x65, 0x64, 0x09, 0xc1, 0xd9, 0x1e, 0x6f, 0x1c, 0x05, + 0x0f, 0xde, 0x11, 0xa3, 0x05, 0xc8, 0xc8, 0xda, 0x48, 0xae, 0x1d, 0x18, 0xfb, 0xd6, 0x3b, 0xe7, + 0x8a, 0x3c, 0xb9, 0xe8, 0x5a, 0x45, 0xa1, 0x58, 0xd0, 0xfe, 0xf7, 0xde, 0x8e, 0x43, 0x1c, 0xd2, + 0xbc, 0x63, 0x48, 0xde, 0xce, 0x7a, 0x52, 0xa2, 0x83, 0x2a, 0x7f, 0x10, 0x52, 0x1c, 0x1f, 0x95, + 0x11, 0x5c, 0x7e, 0x01, 0xfb, 0x0c, 0x2b, 0x1c, 0xc0, 0x77, 0xaf, 0x0f, 0xf5, 0xff, 0x1f, 0xa8, + 0x56, 0x40, 0xcb, 0x7a, 0xfc, 0xa9, 0x5d, 0x05, 0x1c, 0x96, 0x95, 0x49, 0x6b, 0x85, 0xc5, 0x5c, + 0x59, 0x95, 0xfe, 0x18, 0xe0, 0x7b, 0x22, 0x06, 0x27, 0xd4, 0x8f, 0x3f, 0xd2, 0x79, 0xd4, 0x7c, + 0x69, 0xd5, 0x83, 0x56, 0xab, 0xe8, 0xbe, 0xf6, 0x6b, 0x41, 0x7a, 0x2c, 0xf4, 0x58, 0x26, 0xfc, + 0x33, 0x23, 0xd2, 0x32, 0x34, 0x7a, 0x01, 0xaa, 0x66, 0xe1, 0x6c, 0x54, 0x0a, 0xe0, 0xae, 0x92, + 0x63, 0xea, 0x1b, 0x40, 0x05, 0xd6, 0x19, 0xfe, 0xe8, 0x56, 0x4a, 0xd7, 0x4c, 0xee, 0xd4, 0x3f, + 0x99, 0xd5, 0x56, 0x57, 0x34, 0xb1, 0x9b, 0x5a, 0x00, 0x00, 0x00, 0x06, 0x1f, 0x5f, 0x00, 0x10, + 0xc4, 0x91, 0x33, 0xea, 0xbb, 0x2f, 0x2a, 0xee, 0x87, 0xa0, 0x00, 0x06, 0xe1, 0xd8, 0xb4, 0x92, + 0xfd, 0xc1, 0xab, 0x6a, 0x1b, 0x2a, 0x32, 0x9c, 0x9f, 0xf6, 0xf5, 0xb7, 0x4c, 0x73, 0x16, 0xca, + 0x42, 0xc7, 0xd0, 0x0d, 0x7e, 0x5d, 0x41, 0x4a, 0x0f, 0x33, 0xe1, 0xe3, 0xf1, 0x19, 0x36, 0x0e, + 0x3b, 0xc6, 0x06, 0x9e, 0xe2, 0x79, 0xd6, 0x3c, 0x69, 0xd4, 0x53, 0xa1, 0xf3, 0x6d, 0xc1, 0x0c, + 0x7b, 0xab, 0xe2, 0xf3, 0xe0, 0xb6, 0x7c, 0x32, 0xe5, 0xe4, 0x15, 0x1f, 0x09, 0x5d, 0xf6, 0x30, + 0x93, 0x8e, 0xb2, 0x70, 0x09, 0x55, 0x78, 0xb4, 0x7c, 0x12, 0xe8, 0x38, 0x3b, 0x9d, 0x4a, 0x4e, + 0x4c, 0xa1, 0xc7, 0x46, 0xad, 0x6f, 0xb0, 0xbf, 0x9f, 0x98, 0x64, 0xb6, 0x4b, 0x25, 0x6d, 0xd1, + 0xf4, 0xbd, 0xc8, 0x9f, 0xfe, 0x15, 0x1b, 0xe0, 0xe2, 0xb3, 0x57, 0xc2, 0x94, 0xb9, 0x81, 0xfc, + 0x28, 0xd4, 0x74, 0x28, 0x22, 0x92, 0x0b, 0xd8, 0x40, 0x9c, 0x66, 0x95, 0x4c, 0xa1, 0x0b, 0x5f, + 0x0f, 0xfc, 0xf7, 0x83, 0x4a, 0x3b, 0x87, 0x8c, 0xe7, 0xd6, 0x19, 0xe8, 0x57, 0x03, 0x8f, 0x1e, + 0x0f, 0xc1, 0xf0, 0x7f, 0x00, 0x4c, 0xee, 0x88, 0x3b, 0xc6, 0x06, 0x9e, 0xe2, 0x79, 0xc5, 0x44, + 0xaf, 0xdd, 0x90, 0x4e, 0xf2, 0x1c, 0xb4, 0x53, 0xed, 0x62, 0x62, 0x07, 0xe8, 0xff, 0x8b, 0x75, + 0x9a, 0xae, 0xca, 0x1b, 0x89, 0xd0, 0x3c, 0x5f, 0x68, 0x9e, 0xe5, 0x46, 0xdd, 0x74, 0x5a, 0x7d, + 0x73, 0xbc, 0xe4, 0x94, 0xa5, 0x14, 0xd6, 0x53, 0x83, 0x2c, 0x3d, 0x6f, 0x3c, 0xa1, 0x3d, 0x39, + 0x79, 0xe6, 0xa7, 0xb3, 0x24, 0x00, 0x1d, 0x36, 0x16, 0x00, 0x02, 0x64, 0xed, 0x01, 0x6d, 0x15, + 0x57, 0x89, 0xa3, 0x29, 0x10, 0x6d, 0xbe, 0x03, 0x79, 0xdb, 0xcf, 0xad, 0xa1, 0x86, 0x77, 0x75, + 0x19, 0x3c, 0x19, 0x58, 0x6a, 0xf2, 0x3a, 0xd9, 0x3e, 0xbb, 0x24, 0x75, 0xd5, 0x42, 0xf0, 0x54, + 0x26, 0xe6, 0x98, 0x19, 0x1d, 0x36, 0xaf, 0x70, 0xc3, 0x83, 0xc7, 0x80, 0xf6, 0x42, 0x22, 0x05, + 0x7b, 0xc6, 0x06, 0x9e, 0xe2, 0x79, 0xc5, 0xd4, 0x69, 0xd5, 0x83, 0x27, 0xa4, 0x2f, 0xb1, 0xee, + 0xfe, 0xfb, 0x55, 0x90, 0x7c, 0xf9, 0xa6, 0x08, 0x7d, 0x96, 0x78, 0x1f, 0x8d, 0x21, 0xb7, 0xb5, + 0x9b, 0x23, 0x0a, 0x25, 0x6d, 0x7d, 0xc1, 0x06, 0x3d, 0xb8, 0x45, 0x5b, 0x4e, 0x03, 0x91, 0x2d, + 0xef, 0x07, 0x89, 0xd7, 0xb2, 0xe3, 0xd8, 0xe1, 0xf2, 0x31, 0xe7, 0xd8, 0xf1, 0x94, 0x9a, 0x4d, + 0xe5, 0xb4, 0x00, 0x00, 0x00, 0xe5, 0x49, 0xfe, 0x76, 0x9f, 0x61, 0x2e, 0x22, 0xf2, 0x08, 0xd6, + 0xc7, 0xe0, 0x02, 0x62, 0xf1, 0x1c, 0xa0, 0x8b, 0x85, 0x28, 0x14, 0x91, 0xf2, 0x0a, 0xc8, 0xeb, + 0x51, 0x64, 0xc0, 0x1d, 0xaa, 0x64, 0x4d, 0xdd, 0x6d, 0x71, 0xd5, 0x49, 0x87, 0x76, 0x05, 0xcc, + 0x64, 0x96, 0xf0, 0xe1, 0xc7, 0x38, 0x1e, 0x0a, 0x3b, 0xc6, 0x06, 0x9e, 0xe2, 0x79, 0xc6, 0x3c, + 0x37, 0xca, 0x9f, 0xb8, 0x92, 0xad, 0xf0, 0xa9, 0xc0, 0x45, 0x97, 0x26, 0x99, 0xa0, 0x58, 0xa5, + 0xfb, 0x57, 0x8f, 0x72, 0x42, 0x94, 0xed, 0xc2, 0x7b, 0xa6, 0x49, 0xb0, 0x16, 0x71, 0x54, 0xb1, + 0x8c, 0xa8, 0x65, 0xc6, 0x68, 0xbc, 0xcd, 0xc5, 0xf5, 0x0d, 0xe2, 0x12, 0x21, 0xf5, 0xfd, 0xd1, + 0x6b, 0xe9, 0xe2, 0x1f, 0x68, 0x9c, 0xb8, 0xe6, 0x5c, 0x41, 0xd7, 0xb2, 0x4d, 0xba, 0xaf, 0xf4, + 0x61, 0x7e, 0x02, 0xcd, 0x05, 0x32, 0xa0, 0xc3, 0x1f, 0x18, 0x70, 0xe0, 0xf9, 0x1e, 0x09, 0xc1, + 0x9d, 0x3e, 0x4d, 0x35, 0x21, 0x84, 0x3d, 0x75, 0xe1, 0xac, 0x52, 0x20, 0xaa, 0xa9, 0x85, 0xe8, + 0x93, 0x8a, 0x0d, 0xe1, 0x6a, 0x63, 0x9c, 0xa1, 0x5b, 0xa1, 0xc7, 0x07, 0x38, 0x3f, 0x83, 0x01, + 0x1d, 0xe3, 0x03, 0x4f, 0x71, 0x3a, 0x05, 0xe9, 0x69, 0xd4, 0x53, 0x77, 0xbb, 0xff, 0x67, 0x70, + 0x39, 0x68, 0x91, 0x89, 0x3c, 0xd1, 0x1f, 0x23, 0x75, 0x50, 0xae, 0x4b, 0x77, 0xa2, 0xe3, 0x76, + 0x5c, 0xf4, 0x72, 0x1d, 0xa8, 0x0f, 0x55, 0x7a, 0x73, 0x45, 0xbe, 0xd4, 0xe0, 0xe8, 0x99, 0x95, + 0x9a, 0xc9, 0x98, 0xb8, 0x34, 0x03, 0xd1, 0xee, 0x2a, 0x96, 0xde, 0x05, 0xd5, 0xe3, 0x3a, 0x64, + 0xa7, 0x23, 0xdd, 0xe4, 0x00, 0x00, 0x00, 0x0b, 0xd8, 0x35, 0xfd, 0x8c, 0x47, 0x0d, 0xe9, 0xba, + 0xd0, 0xfd, 0xf0, 0x38, 0xf3, 0xe0, 0xf8, 0x33, 0xfa, 0x08, 0x77, 0x0a, 0xc3, 0xca, 0x7b, 0x9f, + 0x25, 0xa7, 0x0c, 0x84, 0xbd, 0x28, 0xa1, 0x72, 0x6c, 0x95, 0x59, 0xb7, 0x35, 0x31, 0xda, 0x8b, + 0xe3, 0xe2, 0x80, 0xdb, 0x8d, 0xf0, 0x3b, 0x06, 0x1d, 0xe3, 0x03, 0x4f, 0x71, 0x3a, 0x35, 0xf1, + 0x69, 0xd4, 0x53, 0x7a, 0xa6, 0x57, 0xdf, 0xe0, 0xec, 0xd6, 0x52, 0x4c, 0x37, 0x16, 0xbc, 0x17, + 0xd6, 0x92, 0x5e, 0xf8, 0x71, 0xa2, 0xb3, 0x49, 0xf2, 0x3b, 0x94, 0xb1, 0x4d, 0xe9, 0x39, 0x1e, + 0xb7, 0x3c, 0x2d, 0xdd, 0x5f, 0xfe, 0x9c, 0x89, 0x26, 0x7b, 0xfd, 0x7c, 0x1f, 0xcc, 0xbd, 0x6f, + 0x35, 0x7f, 0x6f, 0x2d, 0x5b, 0xe3, 0x53, 0x1c, 0x7c, 0x04, 0x77, 0x08, 0x30, 0xc1, 0xa1, 0xa2, + 0xed, 0x99, 0x8a, 0x91, 0x26, 0x61, 0xb2, 0x72, 0x99, 0x92, 0xce, 0x1e, 0x0e, 0x1e, 0x0c, 0x3f, + 0xea, 0x80, 0xde, 0x29, 0xef, 0x60, 0xd3, 0xf3, 0xac, 0xa5, 0x09, 0x18, 0x42, 0x0b, 0x6e, 0x63, + 0xe1, 0x31, 0xdb, 0x8d, 0x6b, 0xe7, 0x84, 0xac, 0xc7, 0x18, 0x19, 0x98, 0x6f, 0x80, 0x78, 0xc2, + 0x1d, 0xe3, 0x03, 0x4f, 0x71, 0x3a, 0x26, 0x39, 0x05, 0xc2, 0xd1, 0x02, 0xeb, 0x04, 0x30, 0x1f, + 0xcf, 0x8f, 0x99, 0x5a, 0x19, 0xa7, 0x82, 0xcb, 0x70, 0xf0, 0xf2, 0xa9, 0xc3, 0xfe, 0x36, 0x90, + 0xd7, 0x19, 0xda, 0xce, 0x16, 0xf6, 0xcc, 0x85, 0xe9, 0x73, 0x15, 0x2a, 0xeb, 0x53, 0xdf, 0x4b, + 0xec, 0x7f, 0x01, 0x5b, 0x50, 0x75, 0xcc, 0x9d, 0x62, 0xfd, 0x8b, 0x11, 0x7e, 0x07, 0xfb, 0x79, + 0x22, 0xdb, 0xdc, 0x15, 0x2c, 0xc9, 0xc9, 0x54, 0xd3, 0x39, 0x61, 0xf6, 0xe1, 0x6c, 0x48, 0x06, + 0x70, 0xf8, 0xe7, 0x73, 0xc1, 0xf8, 0x3b, 0x72, 0x45, 0x80, 0x23, 0x87, 0x34, 0x28, 0xed, 0x10, + 0x70, 0x70, 0x48, 0xec, 0x62, 0x03, 0xe2, 0x5b, 0x33, 0x9a, 0xea, 0x72, 0xa1, 0x20, 0x5f, 0x60, + 0x7e, 0x0f, 0xc0, 0xf8, 0x3f, 0x03, 0xf0, 0x03, 0x3c, 0xa4, 0x87, 0x67, 0x71, 0x2a, 0x25, 0x21, + 0x00, 0x01, 0x61, 0xb5, 0x61, 0x7c, 0x6c, 0x47, 0xba, 0x3d, 0xba, 0x3b, 0x5c, 0x42, 0xd7, 0x8e, + 0x8c, 0xe2, 0xb3, 0x20, 0x0d, 0x14, 0x0b, 0x6b, 0x95, 0x91, 0x80, 0x4d, 0x74, 0x86, 0x41, 0x97, + 0x14, 0xb9, 0x72, 0xeb, 0x77, 0xd4, 0x8e, 0x6e, 0xe5, 0xba, 0x3b, 0xe6, 0x83, 0x28, 0xa4, 0xd0, + 0x57, 0x9f, 0xc9, 0x04, 0x3a, 0x71, 0xf3, 0xa4, 0x1b, 0xf5, 0x32, 0xfd, 0x20, 0x36, 0x0d, 0x48, + 0xd3, 0x76, 0x46, 0x67, 0x17, 0xed, 0x1c, 0x1c, 0x38, 0x3c, 0x1e, 0x0f, 0x87, 0x87, 0x87, 0x83, + 0xe1, 0xe5, 0xce, 0x1e, 0x07, 0xae, 0x46, 0xc6, 0x79, 0x46, 0x26, 0xaa, 0x9e, 0x61, 0x4a, 0xef, + 0x81, 0xa6, 0x18, 0xc3, 0xa3, 0x6b, 0xb8, 0x09, 0xf0, 0x3f, 0x01, 0xfc, 0x0f, 0x87, 0xc2, 0x03, + 0x1c, 0xa4, 0x87, 0x67, 0x71, 0x2a, 0x55, 0x79, 0x05, 0xc2, 0x3c, 0xe5, 0x45, 0x6c, 0xe7, 0x10, + 0x4e, 0xd9, 0xe5, 0x84, 0x46, 0x9c, 0x3f, 0x9c, 0x5b, 0x14, 0xe8, 0x9d, 0xd7, 0xf5, 0x7f, 0xd1, + 0x0d, 0x54, 0x3f, 0xca, 0x46, 0x33, 0xf2, 0xc0, 0x0c, 0xfc, 0x2c, 0x7b, 0xd0, 0xb0, 0xf0, 0xa6, + 0xad, 0x21, 0x47, 0x74, 0x16, 0xb2, 0xa6, 0x37, 0x18, 0xfc, 0x2b, 0x65, 0x57, 0x2e, 0xec, 0x69, + 0x08, 0x72, 0x41, 0x29, 0xcf, 0x2c, 0xf1, 0x5d, 0x9d, 0x78, 0x02, 0xe2, 0x7d, 0x86, 0x83, 0x19, + 0x0e, 0xc3, 0x8c, 0x87, 0x83, 0xc3, 0xdd, 0x0d, 0x0c, 0x40, 0xb6, 0x0f, 0xdc, 0x82, 0x5c, 0x09, + 0x6a, 0x42, 0x75, 0x02, 0x0e, 0x47, 0x6b, 0x00, 0xe6, 0x26, 0x13, 0xa8, 0xe2, 0xfa, 0x1a, 0x0f, + 0x0f, 0xc0, 0xf8, 0x3f, 0x07, 0x83, 0xf0, 0x84, 0x1c, 0xa4, 0x87, 0x67, 0x71, 0x2a, 0x45, 0x01, + 0x19, 0xad, 0x36, 0xf5, 0xc8, 0x09, 0xde, 0x74, 0x71, 0x9e, 0xf3, 0x33, 0x31, 0x6a, 0x35, 0xad, + 0x7c, 0xdd, 0xea, 0xa3, 0x79, 0x54, 0x4f, 0xdb, 0x1b, 0x15, 0x41, 0xb0, 0xf9, 0xf6, 0x07, 0xfd, + 0xe7, 0xcb, 0xe2, 0x24, 0x4f, 0xf1, 0x53, 0x0f, 0x0a, 0xd8, 0xc1, 0xdf, 0xdc, 0x0f, 0x47, 0x2a, + 0x18, 0x0d, 0x2b, 0x0b, 0x78, 0x34, 0x82, 0x11, 0xd7, 0x4d, 0x35, 0x03, 0xeb, 0xce, 0x70, 0x1a, + 0xf5, 0xfd, 0x70, 0x71, 0xf5, 0x2e, 0x3c, 0x3c, 0x3f, 0x03, 0xc3, 0xc3, 0xe1, 0xf0, 0xf8, 0x1d, + 0x6c, 0x9d, 0x2b, 0x22, 0x3c, 0x18, 0x0d, 0x2a, 0x8c, 0xe8, 0x06, 0x16, 0xd6, 0x9c, 0x15, 0x40, + 0x16, 0x06, 0xad, 0xea, 0x9d, 0x0b, 0x8a, 0x83, 0xf3, 0x83, 0xf0, 0x7e, 0x30, 0x7c, 0x0e, 0xc3, + 0xfc, 0xa0, 0x37, 0x47, 0x71, 0x3a, 0x15, 0x01, 0x05, 0xc2, 0x3f, 0x59, 0xce, 0x7c, 0x6c, 0x44, + 0xf7, 0x52, 0xb7, 0x2b, 0x89, 0x80, 0x09, 0x61, 0xd7, 0x77, 0x57, 0x63, 0x87, 0x7b, 0x88, 0xc8, + 0xa5, 0x72, 0xed, 0x94, 0x0c, 0x84, 0x47, 0xdc, 0xc7, 0x89, 0x7d, 0xef, 0x8d, 0x2a, 0xf4, 0x06, + 0xbd, 0x21, 0x6e, 0x3c, 0x50, 0x9b, 0xcc, 0x01, 0x93, 0xa0, 0xac, 0x4a, 0x38, 0xb6, 0x58, 0xdd, + 0x62, 0x84, 0x87, 0x22, 0x90, 0xb1, 0xa6, 0xa9, 0x91, 0xaf, 0xd8, 0x90, 0xcc, 0x0b, 0xb1, 0x20, + 0xf0, 0xe1, 0x86, 0x66, 0x1c, 0x3c, 0x78, 0xe1, 0x1e, 0x76, 0xd8, 0xf5, 0xe4, 0x57, 0xbd, 0xee, + 0xe6, 0x9f, 0x95, 0x13, 0x10, 0x35, 0xcb, 0x1e, 0x84, 0x14, 0x69, 0x8c, 0x06, 0xa6, 0x7c, 0x3e, + 0x0f, 0xc0, 0xfc, 0x0f, 0xc0, 0xfc, 0x0e, 0x05, 0x1c, 0xa0, 0x37, 0x47, 0x71, 0x2a, 0x64, 0xc9, + 0x05, 0xc2, 0x2d, 0xbf, 0x94, 0x18, 0x2b, 0x9e, 0x1e, 0xff, 0x82, 0x28, 0x5f, 0x6c, 0x46, 0x76, + 0x50, 0x29, 0x5e, 0x59, 0x73, 0xfd, 0x6b, 0x8e, 0x64, 0x33, 0xf6, 0xf6, 0x84, 0x2e, 0x95, 0xba, + 0xb2, 0x8d, 0x72, 0xbb, 0x17, 0x71, 0x91, 0x96, 0xae, 0xab, 0x89, 0xa5, 0xa4, 0xad, 0xaa, 0x48, + 0xe9, 0xdc, 0x69, 0xba, 0x16, 0x99, 0xde, 0x56, 0x69, 0x30, 0xfe, 0xe6, 0xab, 0x1c, 0xe4, 0x50, + 0x71, 0x75, 0x5d, 0xd3, 0x09, 0xa2, 0x13, 0xdc, 0x67, 0x3c, 0x3e, 0x3c, 0x3c, 0x3c, 0x1e, 0x1e, + 0x1d, 0xe7, 0x09, 0x3a, 0x24, 0x66, 0xe1, 0xbe, 0x1b, 0x4f, 0x2a, 0xd3, 0x0b, 0xed, 0xd4, 0xbf, + 0x54, 0xf5, 0x4e, 0x5b, 0x71, 0x7a, 0xe8, 0x0f, 0x07, 0xe0, 0x3e, 0x0f, 0x81, 0xe1, 0xf0, 0x06, + 0x1c, 0xa0, 0x37, 0x47, 0x71, 0x2a, 0x24, 0xd9, 0x19, 0xa1, 0x2c, 0x66, 0x90, 0xb6, 0x0a, 0x0d, + 0x39, 0xb6, 0x11, 0x69, 0x65, 0x6e, 0x92, 0x1c, 0x0d, 0xaf, 0x1a, 0x82, 0x29, 0x7f, 0xbb, 0x9c, + 0x8b, 0x12, 0x8b, 0x66, 0x8d, 0xd7, 0x61, 0xad, 0xa1, 0x5c, 0x47, 0x2d, 0x62, 0x01, 0x0f, 0xe3, + 0xb6, 0xdd, 0x68, 0xee, 0x2b, 0x8c, 0xed, 0xf9, 0xea, 0x43, 0x61, 0x65, 0x57, 0xa3, 0xfd, 0xd9, + 0xcb, 0x10, 0xf9, 0x3a, 0xcc, 0x87, 0x09, 0x8f, 0x10, 0xfe, 0xb1, 0x7f, 0x4f, 0xa2, 0xc7, 0xfc, + 0x1c, 0x38, 0x7e, 0x07, 0xe0, 0x7e, 0x07, 0xe0, 0x3f, 0x81, 0x7e, 0x3f, 0xd1, 0xee, 0xb8, 0xad, + 0xf8, 0x0f, 0x28, 0x0f, 0x58, 0x84, 0x12, 0xac, 0x21, 0x96, 0x78, 0x7a, 0xbb, 0x76, 0x06, 0x26, + 0x38, 0x63, 0x3b, 0xc0, 0xe4, 0x1c, 0x0e, 0xc5, 0xfc, 0xa0, 0x0e, 0x47, 0x71, 0x3a, 0x46, 0x29, + 0x00, 0x00, 0x0f, 0x6f, 0xb2, 0x94, 0x5d, 0x10, 0x2f, 0xca, 0x99, 0xc5, 0xc6, 0x84, 0xa9, 0xd4, + 0xe0, 0x81, 0x3e, 0xbf, 0x51, 0x7a, 0x44, 0xdb, 0xc4, 0xf9, 0x33, 0xa3, 0x59, 0xae, 0x80, 0x5b, + 0x47, 0xee, 0x2d, 0xe4, 0xf8, 0xec, 0xcf, 0x46, 0xc5, 0x9f, 0xb2, 0xa4, 0xb2, 0x11, 0xee, 0xaf, + 0x77, 0xbe, 0x76, 0xf4, 0xac, 0xd8, 0x28, 0xe9, 0xf3, 0x5b, 0x93, 0x59, 0x1f, 0xb5, 0x29, 0xf6, + 0xb7, 0xe5, 0xc5, 0x6f, 0xa2, 0x51, 0xe1, 0xf8, 0x7e, 0x0f, 0xc0, 0x7e, 0x07, 0xe0, 0x7c, 0x38, + 0x1d, 0xeb, 0xc8, 0xea, 0xc6, 0x3e, 0x6b, 0xa1, 0xac, 0xfa, 0xdf, 0xa8, 0xf8, 0xc2, 0x6f, 0x1d, + 0x39, 0xa2, 0x89, 0x2a, 0xb0, 0x6b, 0x2e, 0x3d, 0x40, 0x7c, 0x0f, 0xe0, 0x7c, 0x1f, 0x98, 0x07, + 0x1a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x04, 0x79, 0x04, 0x80, 0xfc, 0x37, 0x46, 0x6c, 0xbf, 0xeb, + 0x78, 0xa1, 0xbc, 0x1e, 0x54, 0x0c, 0x33, 0x62, 0x9f, 0x55, 0x6e, 0x5b, 0x00, 0xb2, 0x38, 0x41, + 0x97, 0x66, 0xc6, 0x45, 0x8b, 0xa7, 0x2c, 0xb9, 0xe7, 0x90, 0x7f, 0x40, 0x99, 0x1a, 0x55, 0x84, + 0xc9, 0x0b, 0x80, 0xe8, 0xea, 0xe0, 0x5d, 0x84, 0xc0, 0x56, 0x70, 0xb8, 0x1b, 0x23, 0x82, 0xe7, + 0xff, 0x70, 0xe6, 0x3c, 0xef, 0xb8, 0x9c, 0x87, 0x7b, 0x35, 0xc9, 0x38, 0xd0, 0xec, 0xeb, 0x0f, + 0x0f, 0xc1, 0xf0, 0x3f, 0x03, 0xf0, 0x78, 0xf8, 0xe2, 0xe2, 0x14, 0x96, 0xc0, 0x57, 0x68, 0x89, + 0x74, 0xb7, 0xc1, 0xb2, 0xd6, 0xa9, 0x7e, 0x26, 0xde, 0x28, 0xf0, 0x13, 0xce, 0x07, 0x0f, 0xc3, + 0xe0, 0x7e, 0x07, 0xe0, 0x7e, 0x07, 0xc2, 0x08, 0x1a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x05, 0x21, + 0x00, 0x00, 0x60, 0xee, 0x8d, 0x54, 0xb8, 0xbc, 0x11, 0xe4, 0x59, 0xa0, 0xac, 0xee, 0x13, 0x3d, + 0x28, 0xb3, 0xa0, 0x3b, 0x69, 0x42, 0xe1, 0xb9, 0xe0, 0x71, 0xdf, 0x4f, 0x17, 0xfc, 0x0c, 0xd5, + 0x79, 0x28, 0x28, 0xfe, 0x04, 0xf9, 0x79, 0xa7, 0x6f, 0xea, 0x6f, 0xdd, 0x6a, 0x46, 0x72, 0xc4, + 0x13, 0x8c, 0x1e, 0x91, 0x34, 0x09, 0xc3, 0xb1, 0x61, 0x48, 0xbc, 0xe6, 0x1c, 0x69, 0x51, 0xff, + 0xd2, 0xb7, 0xf5, 0xc4, 0x0c, 0x21, 0x98, 0x7c, 0x0f, 0x83, 0xc0, 0xfc, 0x0f, 0x87, 0xc7, 0xe8, + 0xec, 0x7e, 0x23, 0xa1, 0x7d, 0x07, 0x0c, 0x40, 0xbf, 0x0c, 0x50, 0xf4, 0x95, 0xce, 0xe2, 0x97, + 0x1a, 0x49, 0x1b, 0x38, 0x14, 0xc0, 0x4b, 0x37, 0xe0, 0xfc, 0x0f, 0x81, 0xf0, 0x78, 0xf0, 0x09, + 0x1a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x14, 0xf9, 0x00, 0x00, 0x62, 0x61, 0xf7, 0x2f, 0x30, 0xbc, + 0x28, 0xbc, 0x28, 0x65, 0x7a, 0x47, 0xd7, 0x8f, 0x22, 0xf4, 0xb5, 0x5f, 0x97, 0xcf, 0x28, 0x51, + 0x42, 0x1f, 0x9b, 0x83, 0x7e, 0x50, 0xbb, 0xf0, 0x6d, 0x6a, 0x62, 0x59, 0x3d, 0x99, 0x05, 0x14, + 0xeb, 0x3a, 0xb1, 0x88, 0xf8, 0xdb, 0x8b, 0x3e, 0xb1, 0x24, 0x58, 0xd6, 0x1f, 0xd0, 0x56, 0xa1, + 0x8c, 0x7a, 0x37, 0xd4, 0x03, 0xd8, 0x0e, 0x9d, 0x8b, 0xe2, 0xf1, 0x53, 0x90, 0x31, 0x87, 0x87, + 0xc1, 0xf0, 0x7c, 0x07, 0xe0, 0x7e, 0x07, 0x86, 0x06, 0xfb, 0x6d, 0xf6, 0x0b, 0x19, 0x9c, 0x5a, + 0x65, 0xfb, 0x3c, 0xf5, 0xd8, 0x15, 0xa1, 0xc3, 0xbd, 0x01, 0x8d, 0x64, 0xd1, 0x51, 0xaf, 0xc3, + 0xf0, 0x3f, 0x81, 0xf8, 0x1f, 0x87, 0xe0, 0x0a, 0x1a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x44, 0x59, + 0x05, 0xc0, 0x9d, 0xa7, 0x4c, 0x88, 0x55, 0x01, 0xc8, 0x85, 0xaa, 0xbb, 0x7c, 0xb5, 0x2c, 0x5d, + 0xce, 0x53, 0x94, 0x4f, 0x0d, 0xa6, 0x09, 0x22, 0x42, 0x9e, 0xef, 0xff, 0xfb, 0xcb, 0x4f, 0xa2, + 0xe8, 0xc7, 0xc9, 0x5c, 0xa1, 0x27, 0x9f, 0xfc, 0x47, 0xcb, 0x4d, 0x52, 0xfe, 0x6d, 0x37, 0xc9, + 0x55, 0x15, 0xba, 0xb4, 0xf4, 0xf0, 0xc8, 0xef, 0x07, 0x52, 0xc6, 0xe9, 0x3f, 0xcc, 0xf4, 0xff, + 0x99, 0x32, 0x60, 0x89, 0x07, 0x4d, 0xe3, 0x1e, 0x07, 0x81, 0xf8, 0x1f, 0x07, 0x8f, 0xc1, 0x19, + 0x10, 0x21, 0x44, 0x9a, 0x82, 0x82, 0xb8, 0x65, 0x94, 0xc8, 0x13, 0x9d, 0x8e, 0xdd, 0x32, 0xc4, + 0xd2, 0x4c, 0xa9, 0xc2, 0xa0, 0x43, 0xe1, 0xf8, 0x0f, 0xc0, 0xfc, 0x0f, 0xc0, 0x7e, 0x06, 0x0b, + 0x1a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x24, 0x71, 0x05, 0xc0, 0x29, 0x32, 0x84, 0x40, 0x4b, 0xb4, + 0xb8, 0xf8, 0xd6, 0xa6, 0xec, 0x18, 0xb0, 0xaa, 0x08, 0xbf, 0x29, 0x3f, 0x51, 0xbe, 0xe3, 0x8c, + 0x18, 0xb9, 0x76, 0xe0, 0xe8, 0x18, 0x4d, 0x1f, 0x99, 0x41, 0x25, 0x1c, 0x65, 0x5c, 0x2c, 0x0e, + 0x44, 0x04, 0x9f, 0x4d, 0x70, 0x89, 0x16, 0xf1, 0xe6, 0xc9, 0xc4, 0x51, 0x0a, 0x40, 0x90, 0x0a, + 0xa8, 0x00, 0x5f, 0x3a, 0xca, 0x1f, 0x42, 0xdc, 0x31, 0xd5, 0x47, 0x16, 0x1f, 0x8d, 0xcf, 0x0f, + 0x07, 0x81, 0xf0, 0x3e, 0x07, 0xe0, 0x78, 0x78, 0x89, 0x16, 0xf6, 0xbb, 0x98, 0x92, 0x3d, 0x56, + 0xa6, 0xb5, 0xff, 0x76, 0x03, 0x89, 0x04, 0xcf, 0x1e, 0xfc, 0x72, 0x3b, 0x80, 0x54, 0xf8, 0x7c, + 0x07, 0xf0, 0x3f, 0x03, 0xf0, 0x3f, 0x06, 0x0c, 0x0a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x34, 0xd9, + 0x00, 0x00, 0x17, 0xa1, 0xff, 0x37, 0x32, 0x54, 0xf2, 0x35, 0xaa, 0xbc, 0x3d, 0x44, 0x8c, 0x73, + 0xeb, 0xa4, 0x59, 0x99, 0xa1, 0xcf, 0x35, 0x8b, 0x40, 0xc4, 0xb5, 0x6c, 0xa2, 0x1f, 0x25, 0x4e, + 0x8f, 0x2f, 0xca, 0x57, 0x8c, 0x06, 0xae, 0xce, 0xcc, 0x52, 0x45, 0x6b, 0x6b, 0xe6, 0x72, 0x66, + 0x4d, 0x58, 0x5d, 0x70, 0xb4, 0x7c, 0xbf, 0xeb, 0x84, 0x5e, 0x17, 0x42, 0x4a, 0x37, 0x1a, 0x27, + 0x66, 0x74, 0x80, 0xf2, 0x2f, 0x53, 0xb7, 0x06, 0x79, 0xc3, 0xc1, 0xf0, 0x3e, 0x0f, 0xc0, 0xf8, + 0x3f, 0x0e, 0x1e, 0xfb, 0xa4, 0x49, 0xea, 0x48, 0x10, 0x32, 0x23, 0x18, 0xd7, 0xa7, 0x29, 0xb3, + 0x7c, 0xf1, 0xc4, 0xab, 0x9c, 0xdb, 0xcf, 0x9c, 0x1e, 0x0f, 0xc0, 0xfc, 0x0f, 0x83, 0x82, 0x0e, + 0x0a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x34, 0xd9, 0x05, 0xc0, 0x28, 0xf5, 0x8d, 0xd8, 0x07, 0x04, + 0xd3, 0x2e, 0x17, 0x79, 0x42, 0x9b, 0x5b, 0x69, 0x9b, 0xb8, 0xee, 0xe0, 0x97, 0xdb, 0x2a, 0x6b, + 0x94, 0xbe, 0xca, 0x5d, 0x74, 0x7a, 0x45, 0x21, 0xc5, 0x46, 0x9c, 0x7a, 0x6f, 0x80, 0xf6, 0x6c, + 0x26, 0xcb, 0xa9, 0xee, 0x25, 0xd1, 0xd5, 0x23, 0xb5, 0x01, 0x13, 0xae, 0x47, 0xb3, 0xb7, 0x76, + 0x88, 0x52, 0x40, 0x18, 0xa4, 0xf9, 0xa1, 0x11, 0xc1, 0x39, 0xed, 0x9f, 0xf6, 0x33, 0xc7, 0x87, + 0x80, 0xfc, 0x1f, 0x81, 0xf8, 0x1f, 0x0f, 0x0f, 0xf7, 0xbf, 0x33, 0xec, 0xe9, 0x9f, 0x66, 0x64, + 0xd1, 0xe7, 0xe5, 0xd3, 0x27, 0x20, 0x57, 0xe2, 0x08, 0x36, 0x1d, 0xaa, 0x4d, 0x4e, 0x60, 0xf0, + 0x7e, 0x07, 0xe0, 0x7e, 0x07, 0xc0, 0xf8, 0x0f, 0x0a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x34, 0x99, + 0x05, 0xc2, 0x3c, 0xe5, 0x45, 0xc1, 0x14, 0xf5, 0x9f, 0x92, 0x87, 0x2b, 0x4f, 0x8f, 0x46, 0xf7, + 0x90, 0x7f, 0x33, 0x60, 0xf1, 0xa6, 0xbc, 0xd0, 0x0e, 0xbb, 0x47, 0xdb, 0xbe, 0xb2, 0xe5, 0x2a, + 0x2c, 0x90, 0xc3, 0x1f, 0x2c, 0xa6, 0xbd, 0x4f, 0x10, 0x7a, 0x4f, 0x0e, 0xe6, 0xdc, 0xfa, 0xef, + 0x51, 0x99, 0xeb, 0x94, 0x13, 0x73, 0xaa, 0xdc, 0x4c, 0xc9, 0xa7, 0x35, 0x7d, 0xd7, 0x00, 0x00, + 0x02, 0x65, 0xd2, 0x97, 0xea, 0x16, 0x68, 0x32, 0x97, 0x29, 0xe1, 0xf1, 0xf0, 0x7c, 0x3c, 0x1e, + 0x28, 0xf8, 0x3f, 0x2a, 0x64, 0xb1, 0x82, 0xe4, 0x95, 0xab, 0xb6, 0xb8, 0xcb, 0x1c, 0xba, 0x03, + 0x6e, 0x9d, 0xf4, 0x0b, 0x15, 0xa8, 0x63, 0xf0, 0x3f, 0x80, 0xfc, 0x0f, 0xc0, 0xfc, 0x0e, 0x11, + 0x0a, 0x28, 0x8c, 0x57, 0x71, 0x2a, 0x66, 0x29, 0x00, 0x00, 0x20, 0x84, 0xdc, 0x03, 0x04, 0xeb, + 0x4f, 0xb6, 0x88, 0x4a, 0xe0, 0x3f, 0x33, 0x8e, 0xdc, 0x7d, 0x6f, 0xee, 0xf6, 0x84, 0xeb, 0xbf, + 0x91, 0x69, 0x4b, 0xce, 0x33, 0xfb, 0x0a, 0x66, 0x8e, 0x79, 0xd6, 0x11, 0x63, 0x25, 0x95, 0xcd, + 0x58, 0x73, 0x02, 0xa7, 0xb6, 0x01, 0x06, 0xc4, 0xd3, 0xfa, 0xbf, 0x4c, 0xc1, 0xc3, 0xb6, 0xd3, + 0xc4, 0x33, 0x99, 0x3f, 0xb1, 0x72, 0xe8, 0xd1, 0xed, 0xd5, 0xad, 0x20, 0x95, 0x84, 0x9c, 0x39, + 0xf0, 0x7e, 0x07, 0xe0, 0x7f, 0x07, 0xe0, 0xf0, 0x7e, 0x9b, 0xb9, 0x9d, 0x29, 0xca, 0x3b, 0x35, + 0xd9, 0xc6, 0x3a, 0xf0, 0x09, 0x69, 0xcd, 0xbd, 0xd6, 0xda, 0xf0, 0x91, 0x3d, 0xcd, 0xb3, 0x73, + 0x81, 0xe0, 0x7e, 0x07, 0xe0, 0x7c, 0x4c, 0x12, 0x0a, 0x68, 0xcf, 0xf7, 0x71, 0x2a, 0x04, 0xf1, + 0x07, 0x82, 0x14, 0xfc, 0x2b, 0x0d, 0x9f, 0xbe, 0xb2, 0xbe, 0x70, 0x4e, 0x05, 0x14, 0x2f, 0x36, + 0xc4, 0x7a, 0x3e, 0xe7, 0xd9, 0xf8, 0x64, 0xde, 0xce, 0x4a, 0x9c, 0x6a, 0xbd, 0xd1, 0x46, 0x78, + 0x18, 0x7a, 0xd8, 0x4c, 0x5f, 0x4d, 0x16, 0xfe, 0xca, 0xee, 0x57, 0x0d, 0x32, 0x27, 0xe9, 0x70, + 0x3b, 0x6a, 0xb4, 0xce, 0xc5, 0x67, 0x35, 0x00, 0xbf, 0x31, 0x34, 0xb6, 0xf1, 0xff, 0x92, 0x83, + 0x10, 0x69, 0x98, 0x04, 0xed, 0x5c, 0x3e, 0x1f, 0x83, 0xf0, 0x7e, 0x07, 0xc1, 0xe1, 0xf7, 0x01, + 0x89, 0x86, 0x9a, 0xec, 0x1a, 0xcc, 0x2a, 0xa6, 0xdf, 0x0a, 0x77, 0x4d, 0x19, 0x7b, 0xdf, 0xd0, + 0xdd, 0xf3, 0xbd, 0x78, 0x71, 0x87, 0x07, 0xe0, 0x3f, 0x03, 0xf0, 0x1f, 0x81, 0xfc, 0x0e, 0x14, + 0x0a, 0x68, 0xcf, 0xf7, 0x71, 0x2a, 0x33, 0xc1, 0x07, 0x82, 0x13, 0x5b, 0xf5, 0x2d, 0xee, 0xfd, + 0x7f, 0xfb, 0x76, 0x44, 0x85, 0x6c, 0xdd, 0x4c, 0xa6, 0x95, 0xa9, 0x01, 0x31, 0x90, 0x49, 0xc4, + 0x3d, 0x4b, 0x96, 0xce, 0x4b, 0x00, 0xc9, 0x69, 0x94, 0xca, 0xd2, 0x72, 0xc6, 0xe5, 0xa5, 0x12, + 0x69, 0x52, 0x37, 0x74, 0x64, 0x8f, 0x89, 0x5a, 0x1e, 0x97, 0x9a, 0x00, 0x55, 0x45, 0x78, 0x0a, + 0x72, 0xff, 0x94, 0x26, 0x4e, 0xcd, 0x20, 0x36, 0xb5, 0x7f, 0x77, 0x3a, 0x3d, 0x38, 0x4a, 0x75, + 0x2e, 0x7c, 0x3e, 0x07, 0xc1, 0xf0, 0x78, 0x71, 0xc0, 0xa6, 0x75, 0x7f, 0xe9, 0x8a, 0x8b, 0xd1, + 0x33, 0x41, 0x0d, 0xcc, 0xd1, 0x18, 0x5d, 0x23, 0x57, 0x1b, 0x09, 0x38, 0x8c, 0x1f, 0x9c, 0x0f, + 0xc0, 0x7e, 0x07, 0xf0, 0x3f, 0x03, 0xf0, 0x16, 0x0a, 0x28, 0x8c, 0x57, 0x71, 0x2a, 0x56, 0x11, + 0x05, 0xc0, 0x9b, 0x63, 0x39, 0x73, 0x53, 0x95, 0x15, 0xe7, 0x15, 0xe0, 0x44, 0x4d, 0x15, 0xbf, + 0xde, 0x98, 0x1a, 0x4b, 0xb0, 0x85, 0x5f, 0x68, 0xb2, 0x5b, 0x4d, 0x6a, 0x3d, 0x83, 0xd4, 0xd4, + 0xe4, 0xd8, 0x47, 0x67, 0x80, 0x3b, 0xe3, 0xad, 0xfe, 0x78, 0xba, 0x10, 0x3c, 0x9f, 0x82, 0x30, + 0xf6, 0x8a, 0xbc, 0x1b, 0xf6, 0xab, 0x50, 0x0a, 0x6a, 0x96, 0xf5, 0x29, 0x24, 0xde, 0x06, 0x3b, + 0xf7, 0x9f, 0x93, 0xcf, 0x66, 0x29, 0xec, 0x7c, 0x3c, 0x0f, 0xc0, 0xfc, 0x1f, 0x0f, 0x91, 0xc3, + 0x1f, 0xad, 0x34, 0xc0, 0x86, 0xc4, 0x44, 0xcb, 0xae, 0xc7, 0x9d, 0xc9, 0x21, 0xf0, 0xa1, 0x6b, + 0xb0, 0x94, 0x45, 0x63, 0x08, 0x8f, 0x9e, 0x07, 0xe0, 0x7e, 0x03, 0xe0, 0x7f, 0x01, 0xf8, 0x19, + 0x0a, 0x68, 0xcf, 0xf7, 0x71, 0x2a, 0x34, 0x51, 0x00, 0x00, 0x00, 0x37, 0x6e, 0x5c, 0x01, 0x8c, + 0x3f, 0xff, 0x62, 0x2d, 0x0d, 0x9e, 0x43, 0x75, 0x69, 0xb0, 0x78, 0x55, 0x7e, 0x0f, 0x78, 0x26, + 0x7c, 0xd5, 0xb4, 0x5c, 0x1a, 0x30, 0x27, 0x9d, 0x48, 0x73, 0x70, 0x77, 0x0f, 0xf5, 0x30, 0x53, + 0xbc, 0x63, 0x38, 0x99, 0x77, 0x69, 0x3d, 0xd1, 0xa6, 0xad, 0x22, 0xf7, 0xc2, 0x6b, 0x53, 0x45, + 0xe5, 0x19, 0x13, 0x44, 0x4f, 0x02, 0x32, 0xfd, 0x03, 0x6f, 0x29, 0xac, 0x78, 0xae, 0x20, 0x62, + 0x9c, 0xf8, 0x3e, 0x0f, 0x81, 0xf8, 0x3f, 0x07, 0xc7, 0x07, 0x5d, 0x8f, 0x14, 0x34, 0xdc, 0xee, + 0xd5, 0xd4, 0x64, 0xbd, 0x7f, 0x9d, 0x45, 0x5f, 0xa1, 0x9c, 0xa3, 0x05, 0xe9, 0x23, 0xa2, 0x05, + 0x1b, 0x38, 0x7e, 0x07, 0xe0, 0x7c, 0x0c, 0x1b, 0x0a, 0x28, 0x8c, 0x57, 0x71, 0x2a, 0x36, 0x39, + 0x05, 0xc2, 0x2d, 0xb6, 0x06, 0x49, 0x18, 0xb9, 0xe1, 0x64, 0xf4, 0x2a, 0x15, 0xeb, 0xac, 0x33, + 0xea, 0xcb, 0x6d, 0x69, 0x4f, 0x5c, 0x10, 0x44, 0xbd, 0x31, 0xce, 0x3c, 0xba, 0xb9, 0xf0, 0x83, + 0x0b, 0x3e, 0x14, 0x7a, 0x56, 0x51, 0x5e, 0xcb, 0x95, 0x39, 0x71, 0xed, 0xd3, 0x33, 0x9a, 0x4d, + 0xa3, 0x8b, 0x9b, 0xcd, 0x16, 0xa3, 0x25, 0xae, 0x6c, 0x9f, 0x00, 0x00, 0x00, 0x91, 0xba, 0xd0, + 0x02, 0x44, 0x89, 0xfa, 0xbf, 0xa2, 0xf1, 0x11, 0x1d, 0x4e, 0x0f, 0x81, 0xf8, 0x1f, 0x03, 0xe1, + 0xe1, 0x35, 0x2d, 0x5d, 0x61, 0xc5, 0x78, 0xe4, 0xea, 0x5c, 0x86, 0x9b, 0x8e, 0x92, 0x54, 0xce, + 0x63, 0x30, 0xc1, 0xce, 0xd1, 0x4f, 0x87, 0xc1, 0xf0, 0x3f, 0x03, 0xf0, 0x3f, 0x81, 0xf0, 0x1f, + 0x0a, 0x70, 0xbc, 0x77, 0x71, 0x2a, 0x56, 0x11, 0x00, 0x00, 0x02, 0x46, 0x64, 0x63, 0x12, 0xa4, + 0x19, 0xda, 0x38, 0xd9, 0x99, 0xf8, 0xc7, 0xd6, 0x5a, 0xaf, 0x79, 0x14, 0x40, 0xbf, 0xda, 0xcc, + 0x59, 0xed, 0xff, 0xc4, 0x6e, 0x25, 0xa8, 0x83, 0x2f, 0x91, 0xbf, 0xf4, 0xb5, 0x60, 0x1f, 0x44, + 0x1c, 0x53, 0x27, 0x71, 0x4c, 0x3a, 0x84, 0x6d, 0x59, 0xfd, 0x68, 0x72, 0x16, 0x24, 0xc8, 0x22, + 0x04, 0xfd, 0x9d, 0xc3, 0x00, 0x0f, 0xc3, 0x4f, 0xf6, 0x9b, 0x99, 0x66, 0xe5, 0xe8, 0x9c, 0x13, + 0x63, 0x83, 0xe0, 0xf8, 0x1f, 0x81, 0xf0, 0x7e, 0x1c, 0x00, 0xdc, 0x6e, 0x2b, 0xe7, 0x9b, 0xa9, + 0xaa, 0x33, 0xb6, 0x37, 0xea, 0xdc, 0x11, 0xbb, 0xf4, 0xeb, 0x30, 0xd2, 0xf1, 0x65, 0x11, 0x5b, + 0xf0, 0xf8, 0x3e, 0x07, 0x83, 0xc7, 0xe0, 0x22, 0x0a, 0x70, 0xbc, 0x77, 0x71, 0x2a, 0x46, 0x31, + 0x00, 0x00, 0x00, 0x05, 0xc7, 0x20, 0x0c, 0x68, 0x5d, 0xb4, 0xd7, 0x65, 0xe2, 0x7e, 0x64, 0x69, + 0xc0, 0x79, 0x17, 0x8c, 0x04, 0xa0, 0xcd, 0xc7, 0x6c, 0x20, 0x96, 0x7c, 0x1a, 0x70, 0x8c, 0xdc, + 0x26, 0x89, 0x28, 0xfa, 0xca, 0x49, 0x17, 0xe8, 0x28, 0xa2, 0x5f, 0xa2, 0xfb, 0xd5, 0xc1, 0x91, + 0x6a, 0x18, 0x89, 0xe7, 0x92, 0x05, 0x50, 0x0f, 0xef, 0x5a, 0x5a, 0xdd, 0x0f, 0x6b, 0x9a, 0xd7, + 0x27, 0x98, 0x13, 0x4f, 0x94, 0x5e, 0xe4, 0xd0, 0xf0, 0xf0, 0xfc, 0x0f, 0xc1, 0xf8, 0x1f, 0x81, + 0xf0, 0x78, 0x7c, 0x93, 0x14, 0x0e, 0x50, 0xbd, 0x13, 0x0f, 0x7f, 0x25, 0x3c, 0x11, 0x04, 0x81, + 0x1c, 0x7f, 0xe7, 0x25, 0x7d, 0xe6, 0xe3, 0x8c, 0x61, 0x27, 0xc1, 0xf8, 0x3c, 0x70, 0xf0, 0x26, + 0x0a, 0x6f, 0x43, 0x77, 0x71, 0x2a, 0x25, 0x19, 0x05, 0xc0, 0x26, 0x36, 0xf3, 0x8a, 0xec, 0x1c, + 0xd5, 0x9c, 0x29, 0xf5, 0xb1, 0xb9, 0xc8, 0xb0, 0x3b, 0xa8, 0xc3, 0xe3, 0x2d, 0xca, 0x7b, 0x90, + 0xe6, 0x7d, 0x9a, 0xa6, 0x40, 0xd2, 0xd8, 0xda, 0x56, 0xf7, 0xfe, 0x56, 0xad, 0xfc, 0x3b, 0xae, + 0xd3, 0x95, 0x6d, 0xba, 0xde, 0x8c, 0x0b, 0x76, 0x9d, 0xe7, 0x56, 0xe3, 0x97, 0x14, 0x2c, 0x3c, + 0xb8, 0xa7, 0x7c, 0x9e, 0x00, 0xfc, 0x43, 0xaa, 0xed, 0x58, 0x9b, 0xc5, 0xf2, 0x01, 0xd6, 0x3c, + 0x7c, 0x1f, 0x03, 0xe0, 0x7e, 0x07, 0x87, 0x87, 0x86, 0x3c, 0xd1, 0xf4, 0xb5, 0x4a, 0x29, 0x93, + 0xad, 0x53, 0x30, 0x85, 0x95, 0x26, 0x4f, 0x45, 0xb5, 0xc3, 0x51, 0x31, 0xa5, 0x7a, 0x18, 0xc1, + 0xf0, 0x7e, 0x07, 0xe1, 0xf0, 0x3c, 0x06, 0x0e, 0x0a, 0xde, 0x40, 0xa7, 0x71, 0x2a, 0x24, 0x71, + 0x0d, 0xc1, 0xee, 0xba, 0xbd, 0x82, 0x50, 0xa0, 0x25, 0x0a, 0xed, 0x97, 0xce, 0x60, 0x2d, 0xf9, + 0xa6, 0x97, 0x2f, 0xe8, 0x05, 0xda, 0x37, 0x2b, 0x0e, 0xd5, 0x67, 0x48, 0x29, 0xb1, 0x94, 0x6f, + 0x1a, 0x31, 0xb4, 0x72, 0xba, 0xeb, 0x59, 0x91, 0xb7, 0xbc, 0x5e, 0xeb, 0xb1, 0xae, 0xa8, 0xd5, + 0x1c, 0xf8, 0x47, 0x27, 0x9c, 0x73, 0xb9, 0x80, 0xc9, 0xcd, 0x77, 0x0a, 0x99, 0x00, 0xa9, 0x04, + 0x4f, 0xe6, 0xb3, 0x10, 0x46, 0x70, 0xf0, 0x7e, 0x07, 0xe0, 0xfc, 0x1e, 0x0e, 0x3c, 0x26, 0x00, + 0xa0, 0xe7, 0x02, 0x0e, 0x19, 0x0b, 0x90, 0xa8, 0xbb, 0x24, 0x11, 0xb4, 0x13, 0xe2, 0x6d, 0xb9, + 0xec, 0x1f, 0x38, 0xd7, 0x64, 0xf0, 0x7e, 0x03, 0xf8, 0x1f, 0x81, 0xf8, 0x1f, 0x83, 0xf0, 0x11, + 0x0a, 0xde, 0x40, 0xa7, 0x71, 0x2a, 0x44, 0x31, 0x00, 0x00, 0x00, 0x5c, 0x89, 0x73, 0x30, 0x0e, + 0xb1, 0x92, 0xb9, 0x1e, 0xb0, 0x56, 0x34, 0x72, 0x4f, 0x7d, 0x1b, 0xca, 0x05, 0x95, 0xd5, 0xc5, + 0x98, 0xee, 0x37, 0x97, 0xa8, 0xfb, 0xb8, 0x61, 0xb1, 0x99, 0x00, 0x90, 0x96, 0xee, 0x1a, 0x6a, + 0x24, 0x6e, 0xeb, 0x9f, 0x53, 0xdc, 0x09, 0xaa, 0xfb, 0xc3, 0x8d, 0x1d, 0xa1, 0xee, 0x48, 0x97, + 0x60, 0xd2, 0xdd, 0x3c, 0x7f, 0xf4, 0xee, 0x11, 0x12, 0x9c, 0xdc, 0xa6, 0xba, 0x61, 0xc3, 0xe0, + 0x7e, 0x0f, 0xc0, 0xfc, 0x0f, 0x81, 0xe0, 0x99, 0x7d, 0xa2, 0xcc, 0x85, 0x43, 0xc5, 0xe5, 0xd6, + 0x64, 0xb5, 0x78, 0x70, 0xd0, 0xe9, 0x70, 0xe6, 0x75, 0x84, 0x3f, 0x0a, 0x7c, 0x86, 0x39, 0x88, + 0x88, 0x7f, 0x03, 0xe0, 0xf8, 0xf8, 0xf2, 0x15, 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x2a, 0x04, 0xb9, + 0x05, 0xc2, 0x71, 0x5c, 0x02, 0x99, 0xdc, 0x5e, 0xb9, 0x6c, 0x6f, 0xdf, 0x52, 0x9e, 0x2d, 0x5b, + 0x67, 0x0e, 0xb4, 0x18, 0x43, 0x89, 0x6a, 0x8f, 0xa6, 0xe6, 0xbc, 0x96, 0xf0, 0x9f, 0x9d, 0x79, + 0x3d, 0x03, 0x25, 0xfe, 0x2b, 0xa3, 0xf9, 0xca, 0x64, 0x77, 0xe7, 0x2c, 0x96, 0x69, 0x99, 0xa6, + 0xbe, 0x13, 0xcb, 0xa2, 0x0a, 0x6f, 0xa1, 0xc7, 0x36, 0xcc, 0xae, 0xd1, 0xba, 0x39, 0x05, 0xd0, + 0x9c, 0x17, 0xa2, 0xec, 0xff, 0x1c, 0x3e, 0x1f, 0x03, 0xf0, 0x3f, 0x07, 0xc0, 0xf0, 0xeb, 0xd0, + 0x52, 0x02, 0xe5, 0x4b, 0x24, 0x82, 0x0e, 0x6f, 0x8b, 0x2a, 0x88, 0x86, 0xb2, 0xaf, 0x77, 0x56, + 0xc3, 0xaf, 0xbe, 0x54, 0x80, 0x4f, 0x81, 0xf0, 0x7e, 0x0f, 0xc1, 0xf8, 0x1f, 0x03, 0xf0, 0x19, + 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x2a, 0x23, 0xc9, 0x37, 0xe7, 0x14, 0xf3, 0xd2, 0xc0, 0xce, 0x02, + 0x93, 0x8f, 0x9b, 0x1a, 0x50, 0x5a, 0x47, 0x8c, 0xdc, 0x53, 0x4d, 0x5c, 0xb4, 0xb1, 0x18, 0x31, + 0x8b, 0xad, 0x6f, 0xe6, 0x94, 0xbf, 0x01, 0x34, 0x04, 0x61, 0x26, 0xd3, 0xe1, 0xdb, 0x07, 0xf9, + 0xfd, 0x7f, 0x33, 0xf4, 0x54, 0x09, 0xfa, 0x10, 0x08, 0x85, 0x92, 0xb6, 0xe1, 0x32, 0x49, 0x94, + 0xa8, 0xd2, 0xb9, 0x34, 0x33, 0x34, 0x18, 0x72, 0x56, 0xdd, 0x19, 0x80, 0x50, 0xc0, 0x9c, 0x3e, + 0x0f, 0x87, 0xe0, 0x7e, 0x03, 0xf8, 0x1c, 0x01, 0x4b, 0x4b, 0xe6, 0x6c, 0x9d, 0x29, 0x01, 0xf6, + 0x9c, 0x38, 0x1d, 0x4c, 0x42, 0xaf, 0x61, 0xda, 0x8a, 0xe2, 0x6f, 0xb4, 0x32, 0x38, 0x4a, 0x44, + 0x03, 0x1b, 0xc6, 0x33, 0x03, 0xbc, 0x0e, 0xc8, 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x39, 0xf4, 0x31, + 0x05, 0xc7, 0xf5, 0x2a, 0x9f, 0x0e, 0x68, 0x80, 0x79, 0xe7, 0x0f, 0xd5, 0x1c, 0xbc, 0x9a, 0x6d, + 0xd6, 0x2a, 0x2e, 0xc9, 0x11, 0x80, 0xc7, 0xba, 0x44, 0x31, 0x0e, 0xf3, 0x02, 0xe4, 0x5b, 0x80, + 0x77, 0x70, 0x52, 0x7e, 0x49, 0x7e, 0xa1, 0xad, 0xff, 0xbe, 0xa0, 0x1b, 0x3b, 0xf6, 0x72, 0x30, + 0x1d, 0xdd, 0x5b, 0xe8, 0x64, 0xd4, 0x65, 0x2e, 0x94, 0xa3, 0xae, 0xb2, 0x67, 0xff, 0x16, 0x70, + 0x52, 0xc5, 0x0c, 0x7f, 0x70, 0x78, 0x1f, 0x81, 0xf8, 0x0f, 0xe0, 0x7c, 0x3f, 0x00, 0x41, 0xc3, + 0x29, 0x1b, 0x12, 0xb0, 0xe8, 0xe8, 0x03, 0xa2, 0x09, 0x02, 0x2e, 0xa9, 0x2c, 0xa9, 0x81, 0x6a, + 0xce, 0xe1, 0xe2, 0x51, 0xd9, 0xfd, 0xc0, 0x7c, 0x0f, 0xc0, 0xf0, 0x7c, 0x1f, 0x0f, 0x0e, 0x0d, + 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x2a, 0x14, 0x21, 0xb0, 0xd1, 0xfe, 0x02, 0x0c, 0xb3, 0xb6, 0x83, + 0x75, 0x81, 0xa0, 0x4b, 0x9d, 0x3a, 0x23, 0x6f, 0x51, 0x41, 0x4d, 0x7f, 0x12, 0x44, 0xf4, 0x60, + 0x50, 0x45, 0x95, 0x2f, 0x88, 0x02, 0xda, 0x5f, 0x55, 0x46, 0xe4, 0xcd, 0x0d, 0x60, 0xd7, 0xd5, + 0x8e, 0x46, 0xc2, 0x3b, 0x89, 0xe0, 0x4b, 0xd0, 0xe4, 0x97, 0x98, 0x58, 0xae, 0x7a, 0xca, 0x3e, + 0x36, 0xc8, 0x83, 0x54, 0xd5, 0x46, 0x39, 0xc6, 0xd6, 0xca, 0x29, 0x4a, 0x4e, 0x58, 0xf1, 0xe0, + 0xfc, 0x07, 0xf0, 0x1f, 0x81, 0xf8, 0x0f, 0xc3, 0xfe, 0xb0, 0x8d, 0xff, 0xed, 0xd6, 0xf0, 0xe5, + 0xc7, 0x8e, 0x3d, 0x4a, 0xa6, 0xb3, 0xe9, 0x92, 0xa1, 0xd3, 0xc6, 0x95, 0x0b, 0x66, 0xcf, 0xa4, + 0x2b, 0xe0, 0x7d, 0xe4, 0xfb, 0x9a, 0x73, 0x12, 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x3a, 0x34, 0x51, + 0x69, 0xf1, 0xe5, 0x5c, 0x4a, 0x49, 0xd5, 0xe9, 0xe1, 0x77, 0xd2, 0xa7, 0x0f, 0xaa, 0x5a, 0x24, + 0xe2, 0x43, 0xa0, 0xa7, 0xdb, 0x58, 0xfe, 0xeb, 0xe8, 0x14, 0x7d, 0x48, 0xda, 0x99, 0x7a, 0x03, + 0x9b, 0x72, 0x29, 0x8d, 0x06, 0xc2, 0x06, 0x3b, 0x4f, 0xa9, 0xc1, 0xc5, 0x40, 0x92, 0x93, 0xed, + 0xe8, 0x14, 0x4d, 0x2e, 0x89, 0x73, 0x03, 0x83, 0xdb, 0xee, 0xe3, 0xe2, 0x4b, 0x59, 0xef, 0xcb, + 0x0e, 0x14, 0xe8, 0x91, 0xc2, 0xb8, 0xf8, 0x3e, 0x07, 0xc1, 0xf0, 0x3f, 0x03, 0xf1, 0x10, 0x04, + 0xe0, 0x02, 0x43, 0x60, 0xa3, 0x65, 0xb9, 0xe2, 0x7e, 0xbe, 0x52, 0x1f, 0xcc, 0x0f, 0x33, 0x44, + 0x9c, 0xfa, 0x8a, 0x58, 0xf2, 0x60, 0xb9, 0x5a, 0x51, 0xbd, 0xe2, 0x1a, 0xf8, 0x6e, 0x06, 0xda, + 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x3a, 0x04, 0xf1, 0x69, 0xd4, 0x41, 0x0b, 0x57, 0xdc, 0xd0, 0x46, + 0x81, 0xf4, 0xba, 0xa0, 0x3b, 0x8a, 0xd5, 0x3f, 0x15, 0x89, 0x23, 0x10, 0x82, 0xcb, 0x6a, 0xe6, + 0x2a, 0x95, 0x3f, 0xfa, 0x5b, 0x0b, 0x07, 0x41, 0xd6, 0x3d, 0x40, 0x29, 0x99, 0x8a, 0x79, 0x56, + 0x9b, 0xb3, 0x6c, 0x58, 0x21, 0x02, 0x01, 0x3b, 0xf1, 0x7c, 0x62, 0x56, 0x94, 0xdb, 0x3a, 0x3b, + 0x02, 0xae, 0x17, 0xb0, 0xea, 0xe7, 0xc2, 0x8d, 0x71, 0x0f, 0x54, 0xa3, 0x99, 0xa3, 0x8f, 0x87, + 0xc1, 0xf8, 0x1f, 0x81, 0xf8, 0x1f, 0x81, 0xfe, 0x08, 0xe2, 0x50, 0x52, 0xe4, 0x31, 0xa3, 0x20, + 0x0c, 0x49, 0xd7, 0xc6, 0x46, 0x60, 0xf2, 0xe1, 0xa2, 0x10, 0x96, 0xfe, 0x6a, 0xba, 0x1c, 0x2a, + 0x41, 0x03, 0x3e, 0x3a, 0xbf, 0x7c, 0x1e, 0xe6, 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x3a, 0x04, 0xe9, + 0xaa, 0xf6, 0x07, 0x75, 0x88, 0x63, 0x97, 0x76, 0xb2, 0x9f, 0x74, 0x03, 0x59, 0x45, 0x41, 0x64, + 0x44, 0xea, 0x56, 0xdd, 0x86, 0x5a, 0x08, 0x90, 0x09, 0xc2, 0xb0, 0x32, 0x2b, 0x21, 0x2d, 0xcd, + 0x6a, 0x7b, 0x10, 0x67, 0x57, 0xd0, 0x81, 0x62, 0x51, 0x53, 0x3e, 0x3b, 0x8c, 0x66, 0x1d, 0xe1, + 0xff, 0x9b, 0x9d, 0x50, 0xfe, 0x4b, 0x58, 0xc7, 0xe7, 0x69, 0xb9, 0xda, 0x2d, 0x04, 0x00, 0xaa, + 0xd7, 0xd5, 0x32, 0x17, 0x09, 0x87, 0x87, 0xc3, 0xe0, 0x7e, 0x07, 0xe0, 0xfc, 0x0f, 0x83, 0xec, + 0x3c, 0x60, 0x68, 0x2e, 0x87, 0x02, 0x42, 0x92, 0xf6, 0xb0, 0xe6, 0xab, 0x37, 0x16, 0xdc, 0x6d, + 0xdb, 0x1c, 0x9c, 0xc9, 0x39, 0x92, 0x09, 0xe9, 0x46, 0x9f, 0xc9, 0xb1, 0x69, 0x83, 0xf1, 0x35, + 0x4a, 0xde, 0x40, 0xa7, 0x71, 0x3a, 0x15, 0x49, 0xaa, 0xf5, 0xa7, 0x07, 0x1a, 0x24, 0xd7, 0x61, + 0x47, 0x97, 0x6d, 0xc7, 0xc2, 0xc0, 0x26, 0xe0, 0x2c, 0x82, 0x92, 0x48, 0x4b, 0x73, 0x2b, 0x20, + 0x89, 0x48, 0xd6, 0x5f, 0x35, 0x8e, 0xa8, 0xe1, 0xb9, 0x2f, 0x76, 0xc1, 0x24, 0x1f, 0xaf, 0xea, + 0x46, 0x96, 0x6c, 0x6f, 0xa1, 0x60, 0x3d, 0xb2, 0x9e, 0x5d, 0xe4, 0xdb, 0xe3, 0x20, 0x66, 0x06, + 0x79, 0x24, 0xa9, 0xfa, 0x90, 0x59, 0x7d, 0x95, 0x7e, 0x56, 0x56, 0x60, 0x00, 0x4f, 0xb7, 0xf0, + 0xf0, 0xf0, 0x3f, 0x07, 0xe0, 0x7c, 0x0f, 0xc0, 0xf1, 0xc2, 0xd4, 0x7e, 0x7f, 0x1f, 0x15, 0x02, + 0x91, 0x30, 0xa8, 0xcf, 0xe1, 0xd3, 0xbe, 0x39, 0x18, 0xa7, 0xd8, 0x27, 0x07, 0xe0, 0x8e, 0xba, + 0x64, 0x2c, 0xe3, 0x4e, 0x38, 0x93, 0xf1, 0x00, 0x0a, 0xde, 0x40, 0xa7, 0x71, 0x3a, 0x25, 0x49, + 0xaf, 0xdd, 0x49, 0xd0, 0x00, 0x2f, 0x1f, 0x73, 0x84, 0xbf, 0xb1, 0x1c, 0xd3, 0x01, 0xac, 0x45, + 0x65, 0xbf, 0xc2, 0xf9, 0x94, 0x70, 0xbd, 0x72, 0x2f, 0xeb, 0x2f, 0xed, 0xff, 0x1d, 0x00, 0x29, + 0x63, 0xa9, 0xa4, 0x2a, 0x32, 0x19, 0xc5, 0x17, 0xb8, 0x44, 0x9d, 0x35, 0x26, 0x80, 0x22, 0xc2, + 0xbd, 0x0f, 0x41, 0xea, 0x16, 0x51, 0x4d, 0x03, 0xcc, 0xaf, 0xb2, 0x4f, 0xe9, 0xa9, 0x48, 0xf9, + 0xed, 0x8f, 0xbd, 0xeb, 0xb8, 0x70, 0x7c, 0x0f, 0xe0, 0x7e, 0x03, 0xf0, 0x1f, 0x20, 0x3f, 0xc7, + 0x17, 0x44, 0x2c, 0x38, 0x3b, 0x6e, 0xa3, 0xbb, 0x95, 0xe6, 0x5a, 0xb0, 0x4a, 0xdb, 0xf1, 0xeb, + 0x06, 0x37, 0x12, 0x64, 0x90, 0xac, 0x4d, 0xef, 0x41, 0x0c, 0xb3, 0x81, 0xcc, 0x97, 0x87, 0x40, + 0x1b, 0x58, 0xca, 0xf7, 0x71, 0x39, 0xf4, 0x61, 0x69, 0xd4, 0x41, 0xd9, 0xdd, 0xe2, 0xaa, 0xbb, + 0x30, 0x4b, 0x61, 0x43, 0x0d, 0xcd, 0x67, 0x0a, 0x07, 0x99, 0x18, 0xa5, 0xf7, 0x78, 0x7d, 0x2a, + 0xaf, 0x8d, 0xda, 0xae, 0x4c, 0x0e, 0x07, 0x2b, 0x45, 0x54, 0x80, 0x0f, 0xd4, 0x4b, 0x87, 0x78, + 0x0b, 0x91, 0xb1, 0x2e, 0x37, 0x35, 0x62, 0xd7, 0xc6, 0x3f, 0xcf, 0x54, 0x66, 0xbc, 0xe8, 0x38, + 0xe6, 0xf9, 0xab, 0x8e, 0xda, 0x31, 0x2b, 0x01, 0x9b, 0x8b, 0x4e, 0x50, 0x91, 0x71, 0xe4, 0x61, + 0x4b, 0x87, 0x83, 0xe0, 0xfc, 0x1f, 0x81, 0xf8, 0x3f, 0x01, 0xff, 0xd5, 0x67, 0xbe, 0x3a, 0x6e, + 0xa3, 0xd6, 0x25, 0x10, 0xe6, 0x36, 0xca, 0xc3, 0xb4, 0xcd, 0xfd, 0xe9, 0xf0, 0xdd, 0xed, 0x7c, + 0xbd, 0xb9, 0x58, 0x95, 0xa7, 0xf3, 0xc8, 0xfc, 0x4a, 0xde, 0x40, 0xa7, 0x71, 0x1a, 0x35, 0xb1, + 0x69, 0x22, 0x08, 0x97, 0x59, 0xc6, 0xef, 0xda, 0x00, 0x19, 0xde, 0x54, 0x54, 0xea, 0xcd, 0xb9, + 0x7e, 0x65, 0x42, 0x94, 0x20, 0x3f, 0x4b, 0xa9, 0xfb, 0x31, 0xd5, 0x9e, 0x68, 0xa0, 0xc5, 0x27, + 0x24, 0xa4, 0x5e, 0x36, 0xd5, 0xe1, 0x64, 0x88, 0x08, 0xd4, 0xe5, 0xae, 0x1e, 0x3f, 0x37, 0x3d, + 0xcf, 0x5d, 0x03, 0x9a, 0x4e, 0xa2, 0x2e, 0xb6, 0xf5, 0x47, 0x01, 0x46, 0xb4, 0x3b, 0x84, 0x66, + 0x4c, 0x87, 0xfb, 0x3b, 0x01, 0xd9, 0x87, 0x87, 0x87, 0xe0, 0xf8, 0x1f, 0x81, 0xf8, 0x03, 0xfd, + 0xb2, 0x4c, 0x82, 0xd6, 0xce, 0x40, 0x2d, 0x5e, 0xfc, 0x72, 0x70, 0x29, 0x92, 0xc9, 0xe7, 0xd0, + 0x2d, 0xd9, 0x44, 0x87, 0x97, 0x1c, 0xf4, 0xe7, 0x59, 0x1c, 0xfc, 0xf0, 0xcc, 0x73, 0xe1, 0x77, + 0xec, 0xac, 0xa7, 0x07, 0x59, 0x3a, 0x34, 0xd1, 0x33, 0xd7, 0xfa, 0x76, 0x00, 0xee, 0xf2, 0xed, + 0xf8, 0x94, 0x94, 0xc0, 0xb9, 0xa4, 0x3d, 0x73, 0x2e, 0xd2, 0x6c, 0x0a, 0xbe, 0x1d, 0xb1, 0x2d, + 0xee, 0xa3, 0x3e, 0x04, 0x14, 0xc0, 0xfa, 0xd6, 0xc1, 0xad, 0x3a, 0xd5, 0x3a, 0x08, 0x3a, 0x82, + 0xed, 0xeb, 0x60, 0xab, 0x90, 0xb0, 0x5c, 0xd0, 0x9e, 0xec, 0xe7, 0xf3, 0x32, 0x70, 0x21, 0x8e, + 0xb4, 0xe7, 0x55, 0x09, 0xc3, 0x7a, 0xb9, 0x51, 0x5c, 0xe4, 0x03, 0x68, 0x1f, 0x80, 0xfe, 0x07, + 0xc1, 0xf6, 0x33, 0x12, 0x00, 0x69, 0xc8, 0xe7, 0x7c, 0x01, 0xd8, 0x78, 0x52, 0xef, 0x20, 0xde, + 0xd5, 0x6c, 0xfc, 0x67, 0xaf, 0x12, 0x8d, 0x3c, 0x17, 0x6d, 0x00, 0x3e, 0x0f, 0x90, 0x0f, 0xe0, + 0x1f, 0xc0, 0xfc, 0x1f, 0x81, 0xfc, 0x0f, 0x44, 0x19, 0x59, 0x4e, 0x0e, 0xb2, 0x6a, 0x13, 0x2c, + 0xa8, 0x0b, 0x9b, 0x86, 0xe8, 0xe9, 0x76, 0x98, 0xdc, 0xb9, 0x70, 0x9c, 0xac, 0xe8, 0xb2, 0xe0, + 0x03, 0x3c, 0xf9, 0xe9, 0x7e, 0xdc, 0x5f, 0x5b, 0x4e, 0x7c, 0xe8, 0x5c, 0xfc, 0xff, 0x23, 0x5e, + 0x64, 0x01, 0x67, 0x29, 0x2e, 0x85, 0x07, 0xf0, 0x11, 0x30, 0xc3, 0xc1, 0xa4, 0xfa, 0x3b, 0x7f, + 0x15, 0xa9, 0x98, 0x19, 0x76, 0x6c, 0x77, 0x61, 0x5f, 0x64, 0x7c, 0x7c, 0x74, 0x82, 0xbe, 0x76, + 0xb3, 0x6c, 0xcf, 0xca, 0xf1, 0xc0, 0xfe, 0x03, 0xf8, 0x1f, 0x0e, 0xf3, 0x21, 0x46, 0x9e, 0x63, + 0x18, 0x71, 0x2a, 0x07, 0x74, 0x18, 0x38, 0x57, 0x8a, 0x15, 0x1b, 0xdf, 0xb5, 0x4a, 0x5d, 0xad, + 0xe8, 0x07, 0xbe, 0x00, 0xf0, 0x7e, 0x07, 0xf0, 0x1f, 0xc0, 0x7e, 0x0f, 0xc1, 0xfc, 0x0f, 0x2a, + 0x19, 0x59, 0x4e, 0x0e, 0xb2, 0x6a, 0x43, 0x34, 0x69, 0xd5, 0x7a, 0xea, 0x8d, 0xa6, 0x94, 0x80, + 0xd3, 0x10, 0x5b, 0x5b, 0x86, 0xad, 0x0d, 0x0b, 0x31, 0xee, 0x21, 0xef, 0x0c, 0xd5, 0x0e, 0xf2, + 0x6d, 0x34, 0xd6, 0x6a, 0x11, 0xaf, 0x64, 0x96, 0xff, 0x14, 0x50, 0x9d, 0xd5, 0xe2, 0x07, 0xf4, + 0x00, 0x63, 0x2e, 0x2c, 0x94, 0xfc, 0xc5, 0x87, 0xfb, 0x73, 0x2e, 0xe3, 0xfd, 0xfe, 0xfe, 0xea, + 0x88, 0xc9, 0xb3, 0x3f, 0x38, 0xb7, 0x65, 0xc2, 0x48, 0xb1, 0xf2, 0x57, 0x78, 0xf0, 0x3e, 0x0f, + 0xc0, 0x7f, 0x03, 0xfe, 0x38, 0xbc, 0x78, 0x67, 0x36, 0xb0, 0xbf, 0x00, 0xa1, 0x93, 0x04, 0xfa, + 0x55, 0x44, 0xb8, 0xfb, 0xc8, 0xc3, 0xf7, 0x42, 0x67, 0x50, 0x79, 0x6a, 0x4e, 0x80, 0xbe, 0xc5, + 0xeb, 0xa2, 0x8c, 0xc3, 0x87, 0x21, 0xf9, 0x0f, 0x0c, 0xac, 0xa7, 0x07, 0x59, 0x3a, 0x04, 0x69, + 0x69, 0xd4, 0x3e, 0x17, 0xb0, 0x98, 0x04, 0x05, 0x75, 0x62, 0x2f, 0x8f, 0x3f, 0x5e, 0x54, 0x3e, + 0x5a, 0x21, 0x5e, 0xcb, 0xd7, 0x50, 0x7b, 0x89, 0x50, 0x16, 0xdb, 0x47, 0x9f, 0x8a, 0xf0, 0xa3, + 0x12, 0xe8, 0x0e, 0xf3, 0x32, 0x6b, 0xf4, 0x10, 0x12, 0xa8, 0x3d, 0x2b, 0x69, 0x26, 0xe1, 0x02, + 0x3f, 0x22, 0xd7, 0x13, 0x22, 0x67, 0x8b, 0x5d, 0x8f, 0x1c, 0x8c, 0x56, 0x22, 0x0c, 0x93, 0x19, + 0xb0, 0x83, 0xff, 0x31, 0x2b, 0x3c, 0x36, 0x31, 0xc6, 0x3e, 0x0f, 0xc0, 0xfc, 0x0f, 0xc0, 0x7c, + 0x0f, 0xfe, 0xd4, 0xc0, 0xa2, 0x0d, 0xa1, 0x10, 0xf3, 0xaf, 0xae, 0x98, 0x30, 0xe0, 0x4d, 0xb0, + 0xc3, 0x08, 0x7d, 0x39, 0x00, 0x47, 0xac, 0xaa, 0xfd, 0xe1, 0xc8, 0x3b, 0x8c, 0x7c, 0x0e, 0xc9, + 0x1c, 0xac, 0xa7, 0x07, 0x59, 0x3a, 0x25, 0xc9, 0xb0, 0xd2, 0xbf, 0x90, 0x45, 0xba, 0xcf, 0x4f, + 0x87, 0x7e, 0x31, 0x8d, 0xf2, 0xc5, 0x31, 0x44, 0x7f, 0x49, 0x8b, 0x3f, 0xd4, 0xde, 0xf5, 0x31, + 0x66, 0x82, 0xe2, 0xbf, 0x2d, 0x87, 0xbd, 0x21, 0xb4, 0xb1, 0x56, 0x42, 0x74, 0xfd, 0x5a, 0x44, + 0x03, 0x98, 0x1a, 0x22, 0x91, 0x2d, 0x63, 0x2a, 0xac, 0x87, 0x61, 0x2d, 0x26, 0xe9, 0x1a, 0xa5, + 0xff, 0xdf, 0x65, 0xe6, 0xfb, 0x97, 0x16, 0x3d, 0xcb, 0x01, 0xe3, 0x46, 0x4b, 0x26, 0xe7, 0x87, + 0xc0, 0xfc, 0x0f, 0xc0, 0xfc, 0x1f, 0x81, 0xff, 0x01, 0x0e, 0x43, 0xa4, 0x08, 0x8e, 0x02, 0xe1, + 0xf9, 0x47, 0x77, 0xd6, 0xe0, 0x31, 0x67, 0x40, 0x2f, 0xf9, 0xe0, 0x93, 0x68, 0xb8, 0x61, 0xea, + 0xb1, 0xc0, 0x9e, 0x49, 0x85, 0x83, 0x89, 0x06, 0x1c, 0x32, 0x1c, 0xb7, 0x59, 0x3a, 0x25, 0x71, + 0x69, 0xd5, 0x7a, 0x69, 0x7a, 0x00, 0x00, 0x00, 0x5e, 0xcd, 0x5d, 0x5d, 0x9f, 0xe1, 0x34, 0x7f, + 0x41, 0x1f, 0x3e, 0x58, 0x11, 0xd7, 0x0b, 0xc5, 0xff, 0x81, 0x59, 0x5d, 0x18, 0x0f, 0x3a, 0xc4, + 0x1d, 0x36, 0x73, 0x5a, 0x43, 0x92, 0xf7, 0x4c, 0x58, 0x75, 0xba, 0x19, 0x39, 0xeb, 0x22, 0x49, + 0x03, 0xd5, 0x9a, 0xa0, 0xec, 0x9a, 0x77, 0xd4, 0x59, 0x8a, 0x8a, 0x86, 0x6e, 0x73, 0x42, 0x25, + 0x5f, 0xe9, 0x15, 0x7e, 0x51, 0x3c, 0x07, 0xc7, 0x91, 0xc7, 0x87, 0x83, 0xf0, 0x3e, 0x07, 0xe0, + 0x78, 0x00, 0x2b, 0x98, 0xf9, 0x3e, 0xe7, 0x5d, 0x8b, 0xe1, 0x46, 0x29, 0x6d, 0xb1, 0x9c, 0xaf, + 0x4c, 0x0e, 0x49, 0x7c, 0xe9, 0xc1, 0x22, 0x17, 0x17, 0xa4, 0x60, 0x47, 0x09, 0xef, 0x85, 0x03, + 0x1c, 0x32, 0x1c, 0xb7, 0x59, 0x3a, 0x15, 0xb1, 0x66, 0x56, 0xfc, 0x34, 0x6c, 0x0a, 0x7c, 0x00, + 0x31, 0xe7, 0x9b, 0x3e, 0x8b, 0xe6, 0x8e, 0x9b, 0x9f, 0x19, 0x61, 0x3a, 0xd0, 0x2d, 0xca, 0xba, + 0x73, 0xc6, 0xf2, 0x04, 0x09, 0x48, 0x28, 0x24, 0x67, 0xbe, 0x51, 0xf8, 0xc4, 0x8c, 0xdc, 0x81, + 0x46, 0x13, 0x86, 0x85, 0x4d, 0x25, 0x2b, 0xb4, 0x64, 0x23, 0x77, 0x62, 0x64, 0xf0, 0x52, 0x6e, + 0xd6, 0x59, 0x17, 0xdc, 0xd7, 0x44, 0x07, 0xd7, 0x05, 0x6f, 0x6e, 0x66, 0x81, 0x15, 0x11, 0x60, + 0x67, 0x8f, 0x83, 0xf0, 0x3f, 0x01, 0xf0, 0x78, 0x3e, 0x00, 0x1c, 0x54, 0x4e, 0x17, 0x85, 0x28, + 0x30, 0x08, 0xc8, 0xa3, 0x18, 0xab, 0x25, 0x2a, 0x03, 0x7d, 0x4d, 0xc4, 0x73, 0x7a, 0xdb, 0xdc, + 0xdc, 0x39, 0x15, 0x4b, 0x45, 0x31, 0xf1, 0x01, 0x1c, 0x32, 0x8b, 0xb7, 0x59, 0x3a, 0x36, 0x29, + 0xb0, 0xdc, 0x58, 0x9c, 0x3d, 0xf8, 0x63, 0x7f, 0xcc, 0xc6, 0x86, 0xb4, 0x12, 0xbb, 0xc1, 0xa6, + 0x45, 0x22, 0x34, 0xe9, 0xcb, 0x2d, 0xf6, 0x45, 0x0a, 0x74, 0x9a, 0x04, 0xaa, 0x90, 0xfa, 0xfe, + 0x2e, 0xc2, 0xb7, 0x5b, 0x04, 0x95, 0x5b, 0x1c, 0xbb, 0x27, 0x4c, 0x23, 0x74, 0x29, 0x65, 0xb3, + 0x29, 0x83, 0x0c, 0xff, 0xca, 0x2c, 0x9b, 0x02, 0x71, 0x97, 0x97, 0xfc, 0x2a, 0x5e, 0xe8, 0xa5, + 0xcb, 0x5b, 0xf4, 0xf5, 0x3e, 0x3e, 0x1f, 0x1f, 0x0f, 0xc1, 0xf0, 0xf8, 0x38, 0x39, 0xf7, 0xed, + 0xfd, 0xb5, 0xbf, 0x3d, 0xc6, 0xe4, 0x97, 0x53, 0xd5, 0xdb, 0x24, 0x1a, 0x2d, 0x59, 0x46, 0xd2, + 0x78, 0xcf, 0x44, 0x64, 0xc8, 0x97, 0x87, 0x00, 0x00, 0x5b, 0x76, 0x23, 0x1e, 0x3e, 0x0f, 0x40, + 0x1c, 0x31, 0xa2, 0xb7, 0x59, 0x3a, 0x44, 0xc1, 0x33, 0xd3, 0x8d, 0x2f, 0x14, 0xf2, 0x6a, 0x70, + 0xdb, 0x8e, 0x7a, 0xb3, 0x95, 0xcb, 0x81, 0x5c, 0xf8, 0x5c, 0xb0, 0x30, 0xb8, 0x50, 0xb8, 0xcd, + 0x5f, 0x61, 0xe5, 0xfc, 0x54, 0xd0, 0xcc, 0xb0, 0x32, 0xa3, 0x79, 0x23, 0x30, 0xbf, 0xa6, 0x60, + 0xb0, 0x91, 0x48, 0x28, 0xdb, 0xa6, 0x6d, 0x06, 0x7d, 0x8c, 0x41, 0x4d, 0x9d, 0x79, 0xec, 0xde, + 0x45, 0xf9, 0xb2, 0x3b, 0x8c, 0x84, 0x4f, 0x89, 0xca, 0x2f, 0xa9, 0xfb, 0x6a, 0x83, 0xf0, 0x3e, + 0x1c, 0x7c, 0x68, 0x4e, 0x04, 0x06, 0x2e, 0x0b, 0xf1, 0x9b, 0x10, 0x41, 0x34, 0xde, 0x34, 0x46, + 0xc1, 0x25, 0x43, 0x02, 0xe8, 0xaa, 0x72, 0x89, 0xa2, 0xb8, 0x99, 0xe1, 0xf8, 0x1f, 0xc0, 0x7e, + 0x03, 0xf8, 0x07, 0xe0, 0x7e, 0x07, 0xe2, 0x98, 0x38, 0x63, 0x2d, 0x6e, 0xb2, 0x6a, 0x13, 0x7c, + 0xa7, 0x93, 0xab, 0x53, 0x7c, 0x44, 0xa6, 0xa3, 0x5c, 0x6e, 0x15, 0x16, 0xc0, 0x70, 0x24, 0x37, + 0x5e, 0xed, 0x86, 0x81, 0x07, 0x22, 0x6d, 0xfa, 0x2b, 0xb4, 0xbc, 0x96, 0x97, 0x5d, 0xf1, 0x41, + 0x46, 0x6b, 0x74, 0x19, 0x83, 0x62, 0xb5, 0xf6, 0x5a, 0x82, 0x66, 0x62, 0x21, 0x40, 0x53, 0xb6, + 0x3e, 0x02, 0xf0, 0xe1, 0x78, 0x1d, 0x7d, 0x09, 0x1d, 0x32, 0x2c, 0x03, 0xac, 0x48, 0x36, 0xfd, + 0x00, 0x00, 0x62, 0x87, 0x11, 0x9d, 0xee, 0x1f, 0x81, 0xf8, 0xe3, 0x98, 0x09, 0x2a, 0x02, 0xf1, + 0x43, 0xba, 0xc3, 0x0f, 0xe8, 0x3a, 0xb6, 0x16, 0x3e, 0x19, 0xd3, 0xca, 0x0d, 0xac, 0x66, 0x44, + 0x29, 0x66, 0x02, 0x11, 0xc3, 0xe1, 0xf8, 0x0f, 0xe0, 0x3f, 0x81, 0xfc, 0x0f, 0x8c, 0xe2, 0x94, + 0x38, 0x63, 0x2d, 0x6e, 0xb2, 0x6a, 0x04, 0xfc, 0x33, 0x99, 0x90, 0x39, 0x20, 0x30, 0xff, 0xb4, + 0x30, 0xb8, 0xc4, 0x12, 0xb1, 0xe9, 0x0f, 0x96, 0xdb, 0x03, 0xcd, 0x52, 0xe2, 0x14, 0x56, 0xf6, + 0x04, 0x3c, 0x4a, 0x5e, 0x8f, 0x15, 0xee, 0xc2, 0x67, 0x8b, 0x94, 0xf7, 0xdc, 0x90, 0x0b, 0xf3, + 0x4e, 0x58, 0xf1, 0x50, 0x5c, 0xa2, 0x6f, 0xa7, 0xa2, 0x7e, 0xb3, 0xf3, 0x5f, 0x90, 0x15, 0x67, + 0xd4, 0xeb, 0xa4, 0x7f, 0x2b, 0x1c, 0xb9, 0x0c, 0x41, 0xc5, 0x02, 0x16, 0xa8, 0xf1, 0xe0, 0xfc, + 0x0f, 0x87, 0x82, 0x1b, 0xdf, 0x89, 0x5e, 0x36, 0x79, 0xbe, 0x67, 0xef, 0xfc, 0x10, 0x3b, 0x67, + 0x30, 0x8e, 0xc5, 0x3f, 0x39, 0x00, 0x2c, 0x4f, 0xf8, 0xe4, 0x46, 0x5d, 0x83, 0xf0, 0x3f, 0x03, + 0xf0, 0x3f, 0x03, 0xf0, 0x3c, 0x3c, 0x1e, 0x90, 0x38, 0x63, 0x2d, 0x6e, 0xb2, 0x69, 0xf3, 0xd4, + 0x33, 0xd8, 0x0e, 0xc2, 0x9f, 0x37, 0x79, 0x60, 0x9a, 0xfc, 0xf2, 0x74, 0xf3, 0x6f, 0x3a, 0x72, + 0x71, 0x2d, 0xb0, 0xd3, 0xf7, 0x25, 0x57, 0x4a, 0x2f, 0xeb, 0xcf, 0x94, 0xce, 0x06, 0x4e, 0x2c, + 0x72, 0xbc, 0xf8, 0xf4, 0x26, 0xde, 0xb9, 0x51, 0xea, 0xba, 0xe8, 0x09, 0x79, 0x57, 0xa0, 0x97, + 0xbf, 0xf5, 0x41, 0xfb, 0x9b, 0x94, 0x77, 0x67, 0x5e, 0xfc, 0xb8, 0xc1, 0xe8, 0x27, 0x86, 0x12, + 0x09, 0x3c, 0xf9, 0xba, 0x0f, 0x4c, 0xe0, 0x7e, 0x0e, 0x1c, 0x42, 0x9e, 0x7d, 0x1d, 0xfa, 0x47, + 0x21, 0xa5, 0xa7, 0x83, 0xdb, 0x4b, 0x22, 0x0f, 0xda, 0x11, 0x07, 0x36, 0x97, 0x0d, 0x1a, 0x4a, + 0x3e, 0x42, 0x58, 0xfc, 0x70, 0x3f, 0x03, 0xf8, 0x1f, 0x81, 0xfc, 0x0f, 0xc1, 0xf0, 0x3e, 0x8c, + 0x38, 0x63, 0x2d, 0x6e, 0xb2, 0x6a, 0x23, 0x6c, 0x69, 0xd4, 0x3e, 0x17, 0xac, 0x21, 0x55, 0x93, + 0x90, 0xdc, 0x64, 0xe3, 0x94, 0x46, 0x58, 0x16, 0x64, 0x08, 0x07, 0x57, 0xea, 0xe7, 0x8d, 0xe6, + 0x3c, 0xff, 0x72, 0xe9, 0xee, 0x44, 0xa1, 0x91, 0xe0, 0xa5, 0x8d, 0xf8, 0x00, 0x42, 0xf4, 0x4f, + 0x12, 0xaa, 0x8d, 0x53, 0xe5, 0x04, 0x23, 0x9a, 0xb0, 0xdf, 0x36, 0x57, 0x8d, 0x80, 0xce, 0x61, + 0x42, 0x79, 0x4e, 0x9a, 0x98, 0x80, 0x36, 0x76, 0xb1, 0x12, 0x52, 0x09, 0x04, 0x3b, 0xc3, 0x07, + 0x83, 0xc3, 0xc1, 0xce, 0xe7, 0x38, 0xd9, 0x76, 0x6f, 0x6f, 0x4d, 0xf7, 0xca, 0xf3, 0x15, 0x07, + 0xf4, 0xa4, 0x45, 0x43, 0xe6, 0x1e, 0x2b, 0x38, 0x95, 0x22, 0x62, 0x7e, 0x09, 0x2a, 0x75, 0x4d, + 0xbe, 0x8a, 0xb3, 0xf8, 0xe7, 0x28, 0xf1, 0x45, 0x15, 0x36, 0xf0, 0xaa, 0x59, 0x3a, 0x05, 0x61, + 0x17, 0x53, 0xba, 0x39, 0x92, 0x10, 0x28, 0x29, 0x42, 0x01, 0x0d, 0x63, 0x30, 0xf6, 0xa2, 0x2e, + 0x2e, 0x94, 0x22, 0x45, 0x69, 0x24, 0x9c, 0xed, 0xc9, 0x03, 0xbb, 0xfa, 0x1b, 0x87, 0x07, 0x18, + 0x7b, 0x1c, 0x81, 0xcc, 0x46, 0x10, 0x0c, 0x05, 0x37, 0xa8, 0xc9, 0xf0, 0x54, 0x77, 0x46, 0xbb, + 0x32, 0x7e, 0xad, 0x89, 0x17, 0xdb, 0x80, 0x3b, 0xcb, 0x56, 0x1c, 0xc4, 0x60, 0x62, 0x11, 0x1b, + 0x0d, 0x2b, 0x8a, 0xfa, 0x5f, 0x9b, 0x03, 0xe3, 0xc3, 0xe3, 0x08, 0x19, 0x41, 0xf9, 0xb0, 0x75, + 0x90, 0x35, 0xf1, 0x6b, 0xde, 0x52, 0x86, 0xb0, 0xa8, 0x45, 0xf5, 0x31, 0x38, 0xbc, 0x42, 0x74, + 0x11, 0x0e, 0x67, 0x07, 0xc0, 0xfc, 0x07, 0xf0, 0x1f, 0xc0, 0x7e, 0x07, 0xc0, 0xf8, 0x1e, 0x88, + 0x2a, 0x6d, 0xe1, 0x54, 0xb2, 0x69, 0xf4, 0x84, 0x33, 0x99, 0x90, 0x14, 0xce, 0x01, 0x5d, 0xb0, + 0x5e, 0x96, 0x0e, 0x6e, 0xab, 0x5c, 0xe5, 0x6d, 0xbb, 0x37, 0x38, 0xb9, 0xb2, 0x1b, 0x05, 0x8c, + 0x78, 0x2c, 0x60, 0xcb, 0xf6, 0x63, 0xc2, 0xaa, 0xcf, 0x45, 0xe3, 0xe7, 0x83, 0xfc, 0x3b, 0xd6, + 0x02, 0x76, 0x96, 0x16, 0x4c, 0xf2, 0xdb, 0x01, 0x14, 0xee, 0x3d, 0x4f, 0xfa, 0x79, 0xe6, 0xee, + 0xcf, 0x2e, 0x8b, 0x05, 0x95, 0xce, 0x11, 0xdd, 0x00, 0x06, 0x76, 0xa4, 0xd0, 0x72, 0xe6, 0x0f, + 0x83, 0xcf, 0x01, 0x37, 0xba, 0xad, 0xa4, 0x76, 0x0e, 0xf2, 0x49, 0xa9, 0xf3, 0xf3, 0xdf, 0xa4, + 0x60, 0x91, 0x77, 0xd7, 0x02, 0x6d, 0x81, 0x16, 0xc1, 0x6a, 0x3f, 0x11, 0xdc, 0x78, 0x1f, 0x81, + 0xfc, 0x07, 0xf0, 0x3f, 0x07, 0x87, 0x86, 0x84, 0x2a, 0x6d, 0xe1, 0x54, 0xb2, 0x69, 0xf5, 0x2c, + 0x33, 0xd3, 0x8c, 0x58, 0xe1, 0x9c, 0xb2, 0x59, 0xfc, 0xdc, 0xd0, 0xc0, 0xf3, 0xe2, 0x7b, 0x0d, + 0x82, 0x03, 0x79, 0xc8, 0x02, 0x05, 0xa5, 0xc0, 0xa3, 0x32, 0x5e, 0xa7, 0x59, 0x35, 0x90, 0x72, + 0xba, 0x77, 0x62, 0x47, 0x75, 0xe5, 0xe7, 0x87, 0xff, 0x6f, 0xf6, 0x54, 0x3c, 0x3c, 0x04, 0xa5, + 0x61, 0x6b, 0x51, 0xb2, 0xef, 0x43, 0xfc, 0xe5, 0x5a, 0x49, 0xd8, 0xa2, 0x90, 0x2d, 0xf4, 0xc9, + 0x92, 0x34, 0x04, 0x4d, 0xbc, 0x44, 0x1b, 0x3c, 0x1f, 0x0f, 0x07, 0xe7, 0x1e, 0x4c, 0x8e, 0x93, + 0x84, 0xc3, 0x84, 0xf0, 0x53, 0xdf, 0x8f, 0x39, 0x31, 0xeb, 0x80, 0xfb, 0x07, 0xa7, 0xc4, 0x62, + 0xdb, 0xe9, 0xe8, 0x64, 0x1e, 0x0f, 0x80, 0xfc, 0x07, 0xe0, 0x7e, 0x07, 0x83, 0x81, 0xe2, 0x82, + 0x2a, 0x6d, 0xe1, 0x54, 0xb2, 0x69, 0xd5, 0x14, 0xa7, 0x9c, 0xd9, 0x8f, 0xdd, 0x6b, 0x3d, 0x76, + 0xf7, 0xc3, 0x0e, 0x97, 0x50, 0x17, 0x2a, 0xf3, 0xb1, 0xc9, 0x00, 0x11, 0x47, 0x58, 0xb6, 0x37, + 0x42, 0x00, 0x82, 0x81, 0xef, 0x39, 0xd7, 0x5c, 0xd4, 0x53, 0xa8, 0x2e, 0xf6, 0xbf, 0x6b, 0x6b, + 0xed, 0xbb, 0x79, 0x5f, 0x4e, 0x7f, 0x5c, 0x9c, 0x36, 0xde, 0xd0, 0xc3, 0xe0, 0xa2, 0x2e, 0xf6, + 0xdc, 0x8b, 0x53, 0x7a, 0x9c, 0xb5, 0xd2, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x86, 0xe7, 0xe0, 0xe7, + 0x03, 0xae, 0x3b, 0xcf, 0xdc, 0xa2, 0x6e, 0x9d, 0x9c, 0x27, 0xe3, 0x71, 0x00, 0x53, 0xcf, 0x51, + 0x41, 0xab, 0x75, 0x93, 0x63, 0x0f, 0x17, 0x53, 0x8f, 0x43, 0xc1, 0xf9, 0x01, 0xfb, 0x08, 0x3f, + 0xc0, 0xfc, 0x07, 0xc0, 0xfc, 0x07, 0xe2, 0x82, 0x38, 0x37, 0x7f, 0xee, 0xb2, 0x6a, 0x05, 0x04, + 0xaf, 0xdd, 0x47, 0xae, 0x91, 0xb9, 0x15, 0x00, 0x00, 0x35, 0x1c, 0x0e, 0xf4, 0x88, 0x7b, 0x3b, + 0x20, 0x11, 0x45, 0xff, 0x9b, 0xc9, 0x49, 0x92, 0x5c, 0xa8, 0x15, 0xc6, 0x2f, 0x00, 0x65, 0xd9, + 0x0c, 0xa6, 0xc1, 0x57, 0x59, 0xfe, 0x6c, 0xa8, 0xb9, 0xca, 0x85, 0x17, 0x43, 0x10, 0x50, 0x89, + 0x2a, 0x32, 0xf0, 0xe9, 0x21, 0xb0, 0x76, 0x84, 0xd6, 0x2c, 0x02, 0x2d, 0xca, 0x00, 0xe4, 0xe7, + 0x70, 0xfc, 0x0d, 0x62, 0x61, 0x29, 0x9b, 0x87, 0x1f, 0x0f, 0xc1, 0xf8, 0x1f, 0x83, 0xe0, 0xe3, + 0x86, 0x05, 0x8b, 0x60, 0x65, 0xfa, 0x56, 0x07, 0xe6, 0x3c, 0x06, 0x1a, 0x85, 0xda, 0x16, 0xa8, + 0xe5, 0x5d, 0x56, 0x66, 0x21, 0xce, 0x99, 0xa2, 0xd4, 0xeb, 0x17, 0x0b, 0xe6, 0x20, 0x53, 0x48, + 0x15, 0xa9, 0xc6, 0x9a, 0x59, 0x3a, 0x15, 0x19, 0xa8, 0x0a, 0xd8, 0xfb, 0x8e, 0x91, 0xcf, 0x81, + 0xf5, 0x95, 0x4a, 0x3c, 0xbf, 0x7b, 0x07, 0x47, 0x4c, 0x06, 0xfb, 0xb8, 0x8e, 0x89, 0x7a, 0xe4, + 0x77, 0xd5, 0xfe, 0xa2, 0x5d, 0x91, 0x3b, 0x3a, 0x4e, 0x73, 0x87, 0x6e, 0x9e, 0xb1, 0x18, 0x3f, + 0x20, 0x0f, 0x97, 0xc7, 0x92, 0xbd, 0x38, 0xa4, 0x5a, 0xdf, 0x04, 0x0d, 0xd6, 0xee, 0xe5, 0x37, + 0x91, 0x4d, 0xd6, 0xf1, 0x39, 0x0a, 0x77, 0xf4, 0x28, 0x18, 0xd6, 0x4e, 0x1b, 0x1f, 0x07, 0x30, + 0x0d, 0x89, 0xf3, 0xe2, 0xa3, 0x96, 0x01, 0xfa, 0x00, 0x69, 0x46, 0x83, 0x58, 0xf8, 0x7d, 0x50, + 0xe5, 0x1c, 0x72, 0x20, 0x12, 0x0a, 0x40, 0x31, 0x94, 0x3f, 0xe1, 0xe0, 0x7e, 0x07, 0xf0, 0x1f, + 0xc0, 0x7e, 0x07, 0xe0, 0x7e, 0x07, 0xe2, 0x8e, 0x31, 0x44, 0x9f, 0x94, 0xb2, 0x6a, 0x04, 0x14, + 0x62, 0xa1, 0x41, 0x6d, 0x58, 0xb3, 0xd6, 0x54, 0x5d, 0x8e, 0x1b, 0xf9, 0xf7, 0xe1, 0xdc, 0xb2, + 0x0a, 0x45, 0xcd, 0xfa, 0x6e, 0x8d, 0x63, 0x73, 0x21, 0x99, 0x55, 0x5c, 0x2c, 0x3a, 0xbf, 0x9c, + 0xe7, 0xad, 0xb0, 0xa9, 0x88, 0xcb, 0x00, 0xd0, 0x1b, 0x3b, 0x87, 0xe4, 0x34, 0x74, 0xd6, 0x41, + 0x01, 0x5a, 0x90, 0x50, 0xd8, 0x61, 0x22, 0xb8, 0xdf, 0xbe, 0xab, 0xa6, 0xf9, 0xd2, 0x05, 0x81, + 0xe6, 0x82, 0x20, 0x7c, 0x3c, 0x60, 0x18, 0x64, 0x7d, 0x2c, 0x7c, 0xc3, 0xf1, 0xfb, 0xbb, 0x77, + 0x59, 0xf4, 0x7b, 0xf2, 0x06, 0x8d, 0x50, 0x8d, 0x9f, 0x4c, 0xc1, 0xa1, 0x0f, 0x69, 0x56, 0x91, + 0xee, 0x6c, 0x3c, 0x0f, 0xc0, 0x7f, 0x01, 0xfc, 0x07, 0xf0, 0x3f, 0x00, 0xfe, 0x03, 0xe2, 0x8c, + 0x31, 0x44, 0x9f, 0x94, 0xb2, 0x6a, 0x04, 0x2c, 0x33, 0xd7, 0xfb, 0x2c, 0x1a, 0x47, 0x41, 0x14, + 0xaa, 0xbb, 0x2f, 0x89, 0x27, 0x2c, 0x14, 0x19, 0x47, 0x2c, 0x09, 0x2b, 0xb7, 0x86, 0x2a, 0x41, + 0xcd, 0xea, 0x0a, 0xc0, 0x62, 0x0d, 0x1a, 0xfd, 0xf2, 0x27, 0x4f, 0x87, 0xfa, 0x66, 0x41, 0x22, + 0xf0, 0xc0, 0x7d, 0x12, 0x3c, 0xff, 0xd8, 0x37, 0x5b, 0x53, 0x07, 0x9b, 0x31, 0x48, 0x1e, 0x74, + 0xa3, 0xf6, 0x2c, 0x3f, 0x81, 0xf5, 0x8a, 0xaa, 0xa1, 0xdc, 0x84, 0x92, 0x7d, 0x56, 0x0f, 0x83, + 0x8f, 0xf0, 0x45, 0x63, 0x5e, 0x0b, 0x34, 0x10, 0x60, 0xc9, 0x8b, 0xf9, 0x00, 0x0b, 0x35, 0xf6, + 0x63, 0xf4, 0x00, 0xc7, 0x64, 0x11, 0xef, 0x57, 0xa0, 0x76, 0x84, 0xe1, 0xf0, 0x1f, 0x81, 0xf8, + 0x1f, 0x80, 0xfc, 0x0f, 0xc0, 0xfc, 0x1e, 0x8a, 0x31, 0x44, 0x9f, 0x94, 0xb2, 0x69, 0xf4, 0x24, + 0x37, 0xdf, 0x74, 0xd5, 0xec, 0x89, 0x25, 0xf8, 0x06, 0x62, 0xdb, 0x69, 0xec, 0x25, 0xdc, 0x0f, + 0x00, 0xff, 0x4e, 0x2f, 0xa4, 0xfa, 0x75, 0x06, 0x49, 0x05, 0xde, 0xc4, 0x47, 0x9a, 0x70, 0x2d, + 0xa8, 0xbf, 0x43, 0xb5, 0x73, 0xb5, 0x6b, 0xbd, 0x7f, 0xd3, 0x51, 0xd3, 0x4a, 0xd9, 0x29, 0xfc, + 0x69, 0xd6, 0xdc, 0x20, 0xa8, 0x28, 0x3f, 0xa6, 0x59, 0x57, 0x81, 0xa7, 0x2f, 0x3e, 0x61, 0xaf, + 0x9f, 0xa5, 0x61, 0x1f, 0xb9, 0x0d, 0x44, 0xf7, 0xee, 0x5e, 0xd9, 0xd7, 0x0a, 0x59, 0xe6, 0x09, + 0x6d, 0xc8, 0xd8, 0xe2, 0x42, 0x98, 0xa5, 0x7b, 0x7e, 0xcc, 0xcc, 0xe9, 0x1b, 0x0b, 0xc5, 0x35, + 0x31, 0x73, 0xa5, 0x75, 0x96, 0xa6, 0x00, 0x1c, 0x3e, 0x1e, 0x07, 0x1c, 0xf1, 0xe0, 0x3e, 0x08, + 0x31, 0x44, 0x9f, 0x94, 0xb2, 0x79, 0x95, 0xcc, 0x33, 0x9e, 0x5d, 0x41, 0x8f, 0x8a, 0x96, 0xc7, + 0xe1, 0x70, 0x65, 0xe7, 0xdb, 0x04, 0xd5, 0xd1, 0x32, 0xef, 0x93, 0xc9, 0x18, 0x8f, 0xe0, 0xe1, + 0x65, 0x45, 0x99, 0x6e, 0x1c, 0x2b, 0xc9, 0x31, 0x1c, 0x79, 0x1b, 0x83, 0x4e, 0xff, 0xda, 0x66, + 0x7e, 0x8c, 0xe7, 0x4e, 0x49, 0x2a, 0x1d, 0x4f, 0x7a, 0x6a, 0xb4, 0xe7, 0xa0, 0x05, 0x0c, 0xc2, + 0x46, 0xd2, 0x31, 0x87, 0xa6, 0x36, 0x6c, 0x25, 0x7e, 0x12, 0xfb, 0x1c, 0x24, 0xc3, 0xe0, 0xf1, + 0xee, 0x58, 0x4a, 0x5e, 0xa5, 0x27, 0x85, 0xc0, 0x61, 0xcd, 0xf2, 0xbc, 0xb1, 0x17, 0xc3, 0xd6, + 0xd6, 0x54, 0xc7, 0xff, 0xa1, 0xe7, 0xc1, 0x0f, 0xbf, 0xf9, 0x4a, 0x23, 0xc3, 0xf0, 0x3f, 0x03, + 0xf8, 0x0f, 0xe0, 0x78, 0x7c, 0x0e, 0x1e, 0x86, 0x31, 0x44, 0x9f, 0x94, 0xb2, 0x69, 0xe4, 0x34, + 0x37, 0xdf, 0x74, 0x6e, 0x24, 0x93, 0x69, 0xca, 0xf0, 0x42, 0x18, 0xc9, 0x65, 0x85, 0x6f, 0x58, + 0x9b, 0xba, 0x9a, 0x97, 0xd0, 0x62, 0xc1, 0xac, 0x90, 0xd2, 0x42, 0x31, 0x2d, 0x7c, 0xc0, 0x2b, + 0xa1, 0x0b, 0xc8, 0x50, 0xf9, 0xbb, 0xa5, 0x7d, 0x4b, 0x87, 0xe8, 0x2f, 0xd0, 0xbb, 0x82, 0xfd, + 0x16, 0x10, 0x19, 0x1f, 0x93, 0x96, 0xb8, 0x62, 0x32, 0xd6, 0x75, 0xbb, 0x2d, 0x8c, 0x48, 0x20, + 0xcc, 0xa6, 0xef, 0x97, 0x6d, 0x51, 0xe5, 0x73, 0x65, 0x9c, 0xdd, 0x79, 0x7c, 0xee, 0x7b, 0xc3, + 0xb7, 0xbf, 0xe4, 0x8f, 0x24, 0xf3, 0x6a, 0x48, 0x7a, 0x33, 0x35, 0x97, 0x37, 0x57, 0x7f, 0x5e, + 0x61, 0x75, 0x1c, 0x3e, 0xdb, 0x57, 0xc4, 0x85, 0x0d, 0xc3, 0xe1, 0x87, 0x81, 0xc6, 0x7d, 0x07, + 0x91, 0x44, 0x9f, 0x94, 0xb2, 0x39, 0xa5, 0xdc, 0x69, 0xd4, 0x53, 0xa1, 0xf2, 0xb1, 0x90, 0x83, + 0xe6, 0x47, 0x9c, 0xb0, 0x39, 0x1c, 0xa0, 0x8e, 0xd1, 0x26, 0xbe, 0xaa, 0x8e, 0xab, 0xad, 0x5b, + 0x71, 0x66, 0xc4, 0xf1, 0xd4, 0x0b, 0x50, 0x92, 0xb0, 0xd3, 0x44, 0xe3, 0x56, 0x3f, 0xb0, 0x84, + 0xc8, 0xdf, 0x80, 0xf9, 0x66, 0xd9, 0x19, 0x17, 0xe0, 0xe2, 0x12, 0x84, 0x1c, 0xcf, 0x57, 0xa9, + 0x56, 0x79, 0x70, 0x7f, 0xb9, 0xa7, 0x58, 0x53, 0xea, 0x65, 0xe9, 0x91, 0x5c, 0x3b, 0x1c, 0xe7, + 0xa4, 0xff, 0xac, 0xa9, 0xfb, 0xde, 0xf9, 0xfc, 0x3c, 0x45, 0x36, 0x2d, 0x7c, 0xdc, 0x83, 0x69, + 0x12, 0x6a, 0xb1, 0x6a, 0x29, 0x02, 0x12, 0xd0, 0x00, 0x93, 0x93, 0xe8, 0x90, 0xbb, 0x5c, 0xa5, + 0x8c, 0xf6, 0x08, 0x7c, 0x37, 0x86, 0x3e, 0x07, 0x98, 0x44, 0x69, 0x6e, 0xb2, 0x39, 0xc6, 0x3c, + 0x69, 0xd4, 0x53, 0xa1, 0xf2, 0xa1, 0xf1, 0xaa, 0xf4, 0x4c, 0x39, 0xb2, 0xc2, 0xa4, 0xa6, 0xf1, + 0xcf, 0x85, 0xb4, 0xd3, 0xc9, 0xc7, 0xa3, 0x33, 0xf3, 0x5a, 0x04, 0xbb, 0x04, 0x8f, 0x8f, 0x80, + 0x7a, 0x24, 0x12, 0x88, 0x2b, 0xb9, 0x56, 0xbe, 0x39, 0x92, 0xf1, 0xb4, 0x80, 0x4b, 0xc1, 0xb3, + 0x7b, 0x23, 0xfc, 0x48, 0x7e, 0x7f, 0xea, 0x3d, 0x49, 0xc4, 0x32, 0x04, 0x69, 0x36, 0xed, 0x68, + 0x03, 0x75, 0x5d, 0x79, 0xc1, 0xcc, 0xa3, 0x21, 0x3d, 0x84, 0xd4, 0x23, 0x16, 0x48, 0x67, 0x80, + 0x3c, 0x76, 0x4e, 0x57, 0x39, 0x4f, 0x1a, 0xbf, 0x6e, 0xf7, 0x2a, 0xac, 0xb9, 0x3d, 0x1c, 0xf1, + 0x72, 0x6b, 0xff, 0x78, 0xec, 0xff, 0x15, 0xe1, 0x35, 0x44, 0x5e, 0x07, 0xc1, 0xfc, 0x61, 0xf8, + 0x98, 0x44, 0x69, 0x6e, 0xb2, 0x39, 0xc6, 0x3c, 0x37, 0xe7, 0x3d, 0xc9, 0x8e, 0xff, 0xc4, 0x6e, + 0x98, 0x6d, 0x0c, 0xe7, 0x5b, 0xa2, 0x9d, 0x70, 0xf9, 0x49, 0x65, 0x08, 0x3c, 0x9d, 0x4c, 0xbe, + 0xab, 0x06, 0x7f, 0x44, 0xcd, 0x5c, 0x3c, 0x0f, 0x45, 0x11, 0x44, 0xa6, 0x5c, 0x39, 0x10, 0xe4, + 0x5e, 0xaa, 0xff, 0x83, 0x97, 0xbb, 0x26, 0x41, 0x9f, 0x65, 0xc0, 0x70, 0x59, 0xea, 0x44, 0xd1, + 0x9d, 0x60, 0x8b, 0x95, 0xdc, 0xee, 0xa5, 0x97, 0x57, 0xb9, 0xc8, 0x53, 0x6b, 0x50, 0x93, 0xef, + 0x46, 0x29, 0xd1, 0x37, 0x23, 0xc8, 0xb8, 0x72, 0x83, 0xd8, 0x10, 0xde, 0xe4, 0x5d, 0xde, 0xc5, + 0xb0, 0x95, 0x28, 0x52, 0xe5, 0x78, 0xea, 0x33, 0xff, 0x45, 0x02, 0x67, 0x5e, 0x1d, 0x80, 0x1e, + 0x2a, 0x64, 0xe0, 0x17, 0x1f, 0x0d, 0x81, 0xf5, 0x98, 0x44, 0x69, 0x6e, 0xb2, 0x39, 0xb6, 0x34, + 0xaf, 0xdd, 0x5d, 0x72, 0x51, 0x9c, 0xbc, 0x0c, 0xcc, 0x10, 0xab, 0x8c, 0xc2, 0x7d, 0x59, 0x42, + 0x30, 0xe9, 0x9d, 0x1a, 0x5c, 0x84, 0x23, 0x4e, 0x22, 0xd6, 0x5f, 0x48, 0x7b, 0x28, 0x9c, 0x30, + 0x8e, 0x91, 0x70, 0xc9, 0x7a, 0x47, 0x8e, 0x19, 0xee, 0xbf, 0x26, 0xbe, 0x14, 0x32, 0xda, 0x90, + 0xa9, 0xb1, 0x01, 0x31, 0x7b, 0x70, 0x6f, 0x7a, 0x92, 0xb9, 0x20, 0x11, 0x61, 0x36, 0xf1, 0x68, + 0x3b, 0x55, 0x89, 0xbc, 0x57, 0x9b, 0xa1, 0x25, 0xf6, 0x2a, 0x0d, 0xbf, 0x06, 0x3c, 0x04, 0x81, + 0x70, 0xc1, 0xc2, 0xc1, 0x75, 0x90, 0xfe, 0x28, 0x0e, 0xf3, 0x46, 0x00, 0xd2, 0xc0, 0xb0, 0x25, + 0xa9, 0x95, 0xba, 0x98, 0x32, 0xc6, 0x64, 0xa8, 0x42, 0xac, 0x6c, 0x1e, 0x6c, 0x3c, 0x91, 0xf8, + 0x98, 0x44, 0xa5, 0x6e, 0xb2, 0x39, 0xf6, 0x2c, 0xaf, 0xdd, 0x5d, 0x70, 0x12, 0x34, 0x02, 0x21, + 0x2e, 0x2a, 0xa5, 0x29, 0x16, 0x21, 0x2b, 0x6b, 0xa6, 0x00, 0x62, 0x1a, 0x85, 0x11, 0xfe, 0x27, + 0x96, 0xc0, 0xe3, 0xca, 0xf9, 0x46, 0xdf, 0x0f, 0x6e, 0x7b, 0x04, 0xb5, 0x60, 0x0b, 0xd7, 0x23, + 0x62, 0x79, 0xd6, 0x0c, 0x1a, 0xd2, 0xed, 0x99, 0xc4, 0x11, 0x6a, 0x80, 0x3a, 0x1f, 0x6c, 0x4a, + 0x47, 0xa4, 0xc2, 0x1c, 0x5b, 0x94, 0x64, 0x8c, 0x26, 0x04, 0xfb, 0xfd, 0x16, 0xc5, 0x1f, 0x97, + 0x58, 0xcd, 0x2c, 0xec, 0xa5, 0xe7, 0x78, 0x58, 0xa7, 0x88, 0x7e, 0xb5, 0xaa, 0x2c, 0xbf, 0x1d, + 0x7d, 0xf1, 0xe0, 0x41, 0x8e, 0x4d, 0x3a, 0x58, 0x34, 0x6e, 0x28, 0x41, 0x75, 0x15, 0xeb, 0xc8, + 0xf2, 0x43, 0xc7, 0x21, 0x6d, 0xe3, 0x9e, 0x07, 0x78, 0x44, 0xa5, 0x6e, 0xb2, 0x39, 0xc6, 0x3c, + 0xb0, 0xdc, 0x12, 0xcc, 0x4c, 0xcc, 0x48, 0xed, 0x80, 0x64, 0xa3, 0x51, 0xff, 0x3d, 0xf0, 0x22, + 0xd1, 0x9b, 0xd6, 0xd3, 0x68, 0x90, 0x43, 0x3f, 0x1b, 0x71, 0x66, 0xd9, 0xa2, 0xbf, 0xc9, 0xe5, + 0xeb, 0x73, 0x46, 0xc1, 0xad, 0x24, 0xfd, 0xf3, 0x39, 0x11, 0x8f, 0xaa, 0x4c, 0x5e, 0xb6, 0x4e, + 0x11, 0xa1, 0xb4, 0xdb, 0x1a, 0xe4, 0xa5, 0xe5, 0xc5, 0xb7, 0xec, 0x9c, 0x1d, 0x17, 0xb7, 0x75, + 0xc5, 0x7e, 0x7d, 0xf1, 0x28, 0xa2, 0x14, 0x9f, 0x10, 0xde, 0x56, 0xb4, 0xe1, 0x83, 0xef, 0x57, + 0x87, 0xda, 0x25, 0x28, 0x35, 0x38, 0x90, 0x50, 0xa4, 0xb5, 0x5d, 0x7d, 0x94, 0xc3, 0xda, 0x73, + 0xdb, 0xe7, 0x28, 0x29, 0xbb, 0x59, 0x5c, 0xb5, 0x83, 0x72, 0x3b, 0x45, 0xc2, 0x56, 0xc7, 0x79, + 0x98, 0x44, 0xa5, 0x6e, 0xb2, 0x39, 0xc6, 0x1c, 0xb0, 0xdc, 0x62, 0x63, 0x93, 0x7b, 0xc3, 0x48, + 0xe7, 0x95, 0x2c, 0x81, 0x44, 0x14, 0xd3, 0xad, 0xf5, 0x39, 0x80, 0x5e, 0xee, 0x45, 0xc0, 0xbd, + 0x79, 0xc3, 0x00, 0x4b, 0x0a, 0xe2, 0x40, 0x24, 0xbc, 0xc5, 0xf6, 0x61, 0x16, 0xa6, 0x76, 0xa2, + 0x59, 0xaa, 0x1c, 0xe5, 0x07, 0x22, 0x89, 0x27, 0xce, 0x4a, 0x3d, 0xd3, 0x95, 0x29, 0x8f, 0xd4, + 0xc9, 0xa4, 0x9c, 0xfd, 0x00, 0x8f, 0x51, 0x80, 0x2a, 0xc8, 0xaa, 0xed, 0xf5, 0xb1, 0x54, 0xf3, + 0x42, 0xd4, 0x2b, 0xa0, 0x34, 0xd0, 0x01, 0x44, 0xf8, 0x28, 0x78, 0x1f, 0x77, 0xf4, 0xf1, 0x9a, + 0xc7, 0x75, 0x42, 0xbd, 0x06, 0xf8, 0x0c, 0xba, 0x99, 0xc7, 0xd4, 0xa9, 0xdd, 0x9b, 0xb6, 0xd0, + 0x86, 0x02, 0x31, 0xe3, 0x18, 0x7c, 0x00, 0xfc, 0x78, 0x44, 0xa5, 0x6e, 0xb2, 0x39, 0xc6, 0x24, + 0x69, 0xd5, 0x7e, 0xf4, 0x56, 0xff, 0xd6, 0xb8, 0x39, 0x42, 0xb8, 0xea, 0x1e, 0x44, 0x7d, 0xdb, + 0x3a, 0xb6, 0x27, 0xe9, 0xc5, 0xe9, 0xce, 0x0b, 0x27, 0x53, 0x53, 0x03, 0x18, 0x9b, 0x40, 0xa5, + 0xd1, 0x72, 0x39, 0x94, 0x3c, 0xb2, 0x50, 0x91, 0x4f, 0x84, 0xa1, 0xa4, 0x88, 0x6e, 0x7b, 0x48, + 0x4a, 0x99, 0x55, 0x38, 0xab, 0x70, 0x69, 0x53, 0x6f, 0xe9, 0x2d, 0xec, 0x15, 0xc8, 0x2f, 0xf6, + 0x1f, 0x48, 0x7d, 0xdf, 0x34, 0x16, 0xc3, 0x6f, 0x06, 0x64, 0x26, 0x9c, 0x20, 0xd0, 0x1c, 0xb0, + 0x6c, 0x57, 0x24, 0xc7, 0xa9, 0x5d, 0xea, 0x8e, 0xd1, 0xeb, 0x56, 0xfc, 0x10, 0x4d, 0xbd, 0xa4, + 0xe4, 0xa0, 0xac, 0xe2, 0xcc, 0x79, 0xb0, 0x7f, 0xae, 0x41, 0xcf, 0x9a, 0x1e, 0x61, 0x81, 0xfc, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xd5, 0x34, 0xae, 0xec, 0x1e, 0xe4, 0xe0, 0xd5, 0xb6, 0x00, + 0x00, 0xa5, 0x9f, 0x96, 0xcd, 0x72, 0xe7, 0x6b, 0xbd, 0x30, 0xbc, 0x87, 0x98, 0xed, 0xa5, 0x60, + 0x96, 0x46, 0x0e, 0xdb, 0xda, 0x89, 0x3e, 0x73, 0xed, 0xb8, 0x31, 0x33, 0x96, 0xfc, 0x5f, 0xe5, + 0x7f, 0xe9, 0xad, 0x25, 0x07, 0x2c, 0xec, 0x4c, 0xc4, 0x0f, 0x9c, 0x76, 0xe8, 0xaf, 0x0b, 0x62, + 0x23, 0xd7, 0xb2, 0x23, 0xaf, 0x62, 0x5c, 0xb4, 0xdd, 0x13, 0x51, 0x25, 0x86, 0x0c, 0xec, 0x91, + 0x22, 0x56, 0xaf, 0x7b, 0xe0, 0x30, 0x4c, 0x66, 0x14, 0x01, 0xfa, 0x42, 0x04, 0x4b, 0x91, 0xf9, + 0x65, 0xf4, 0x63, 0xd8, 0x58, 0xfb, 0xbb, 0xbe, 0x96, 0xe2, 0xdc, 0x0a, 0x9e, 0x43, 0xba, 0xd2, + 0xe4, 0xa9, 0x23, 0x01, 0xe7, 0x33, 0xb1, 0xe4, 0x78, 0x44, 0xa5, 0x6e, 0xb2, 0x39, 0xc6, 0x34, + 0x69, 0xd5, 0x7e, 0xef, 0x47, 0x1d, 0x1a, 0x06, 0x63, 0xd2, 0xd7, 0x56, 0x12, 0x77, 0x40, 0x88, + 0x00, 0xfd, 0x53, 0xa5, 0x52, 0x98, 0xd9, 0xf7, 0xd4, 0x97, 0xa1, 0x06, 0x7e, 0xc6, 0x9d, 0x5f, + 0x2c, 0x45, 0x27, 0x10, 0xee, 0x32, 0x36, 0xeb, 0x5e, 0x8a, 0x42, 0x23, 0x8b, 0x9c, 0x4b, 0x5d, + 0x14, 0x0a, 0x16, 0x2c, 0xfa, 0x6d, 0x9a, 0x64, 0xe8, 0xc2, 0xeb, 0x23, 0x51, 0x74, 0xe2, 0xbe, + 0x86, 0x3e, 0x9e, 0x4e, 0x3d, 0xf4, 0x10, 0xea, 0xb8, 0xc8, 0x0f, 0x35, 0xee, 0xba, 0x1f, 0x85, + 0xed, 0x2b, 0x5c, 0xe0, 0x65, 0xfc, 0x7f, 0xe3, 0xb5, 0x4c, 0xa2, 0x16, 0x68, 0xfc, 0xf0, 0x41, + 0x22, 0x2a, 0xea, 0x8e, 0x3f, 0xb2, 0x73, 0x66, 0x9e, 0xfe, 0x60, 0x66, 0x29, 0x86, 0x81, 0xf8, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xb6, 0x3c, 0x66, 0x3c, 0x02, 0x2d, 0xef, 0xe3, 0x94, 0xd8, + 0x80, 0x92, 0x4a, 0x95, 0x73, 0x76, 0x38, 0xc1, 0x72, 0x0b, 0xdd, 0xdd, 0x56, 0x98, 0x8c, 0xc6, + 0x13, 0x03, 0xdd, 0x3a, 0xd6, 0x0f, 0x63, 0xbb, 0xde, 0x18, 0x3a, 0x07, 0x21, 0xf8, 0x9d, 0xe8, + 0xb6, 0xca, 0x75, 0x31, 0x2e, 0x28, 0x6b, 0x1b, 0xd9, 0x19, 0x49, 0xe6, 0xf0, 0x1c, 0x54, 0xa8, + 0x10, 0xeb, 0xc2, 0x27, 0x50, 0x22, 0x03, 0x7a, 0x64, 0xbd, 0xf9, 0x0e, 0xdf, 0x80, 0xec, 0xd4, + 0xa3, 0xac, 0x4c, 0x0f, 0xb6, 0xc0, 0xe4, 0xb0, 0x8b, 0x74, 0x6c, 0xf0, 0x14, 0x5a, 0xa7, 0x55, + 0xb6, 0x2e, 0xdd, 0xdb, 0x0e, 0x29, 0xed, 0x6f, 0x93, 0x9c, 0x51, 0x14, 0x41, 0x34, 0xa8, 0x4f, + 0x62, 0x0e, 0x31, 0xb1, 0x71, 0x64, 0x87, 0xf0, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa5, 0xfc, + 0xb0, 0xdc, 0x62, 0x57, 0xd3, 0x36, 0xf2, 0xac, 0x75, 0xf7, 0xe4, 0x7e, 0xad, 0xe3, 0x52, 0x9d, + 0x36, 0x68, 0xd7, 0xde, 0xa5, 0xd5, 0x2e, 0xbd, 0x2a, 0x54, 0x3c, 0xe7, 0x64, 0xec, 0x4f, 0xb8, + 0x89, 0xba, 0x8e, 0xf0, 0x3d, 0x8f, 0x1c, 0xc5, 0x36, 0xec, 0x31, 0x31, 0x1c, 0x18, 0x72, 0x55, + 0xb0, 0x48, 0x18, 0x4a, 0xef, 0xb9, 0xe6, 0xc9, 0xdc, 0xe9, 0x60, 0x61, 0x64, 0x90, 0x85, 0x22, + 0x55, 0x9f, 0x06, 0x3c, 0xd1, 0xde, 0x8f, 0x2a, 0xa2, 0xbf, 0x80, 0x84, 0x58, 0x33, 0x0f, 0x28, + 0x57, 0x88, 0x40, 0x90, 0x88, 0x22, 0xf2, 0xf8, 0xfc, 0x27, 0x10, 0x78, 0x52, 0x79, 0xb5, 0x27, + 0x9a, 0x79, 0xcb, 0x0e, 0x23, 0xfe, 0x8f, 0x80, 0x53, 0x20, 0x61, 0xf3, 0xc1, 0x9d, 0xfe, 0x07, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xd6, 0x2c, 0x69, 0xd4, 0x6a, 0x42, 0x75, 0xb2, 0x56, 0x45, + 0xdb, 0x97, 0x98, 0x7c, 0xf8, 0x26, 0x81, 0xdd, 0x03, 0x6f, 0xd2, 0x5b, 0x85, 0x92, 0xb5, 0x9c, + 0x5b, 0x60, 0x4d, 0xaf, 0x25, 0x78, 0xce, 0xfd, 0x38, 0xc0, 0xd1, 0xf1, 0x1e, 0x99, 0xa7, 0xb2, + 0xf1, 0xae, 0x19, 0x59, 0x9a, 0xba, 0x97, 0x57, 0xcf, 0x6b, 0xee, 0x95, 0xdf, 0xa5, 0x95, 0xc3, + 0xa3, 0xa5, 0x93, 0xc3, 0x19, 0xd3, 0x48, 0x1a, 0x2a, 0x82, 0xe7, 0x5e, 0xdd, 0xff, 0x66, 0xd6, + 0xc1, 0xae, 0xa2, 0xcf, 0xff, 0x86, 0x08, 0x85, 0x94, 0x41, 0xc5, 0x17, 0xf6, 0xfa, 0x02, 0x3b, + 0x16, 0xe1, 0xa5, 0x38, 0x0d, 0x9c, 0x86, 0xef, 0x05, 0x9b, 0x96, 0x9c, 0x24, 0x07, 0x9c, 0xff, + 0x82, 0xf7, 0x07, 0x13, 0x38, 0xec, 0xf2, 0xda, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa5, 0xe4, + 0x69, 0xd4, 0x53, 0xbf, 0x32, 0xf9, 0xec, 0x78, 0xf3, 0x36, 0xd1, 0xaa, 0xac, 0x07, 0x21, 0xd3, + 0x6c, 0x15, 0x8f, 0xbc, 0x88, 0xa1, 0x7e, 0x52, 0xef, 0xd6, 0xf4, 0x15, 0xf5, 0x35, 0x93, 0xb7, + 0xd8, 0x36, 0x6f, 0xa5, 0xbe, 0xe0, 0x06, 0xf8, 0x9d, 0x49, 0x5a, 0x27, 0x40, 0x03, 0x09, 0xdf, + 0x34, 0x47, 0x3d, 0x32, 0xab, 0x10, 0x19, 0x0c, 0x43, 0x54, 0x2e, 0xda, 0xe5, 0x7b, 0xcd, 0x02, + 0xb8, 0x46, 0x14, 0x10, 0x05, 0xc7, 0x6b, 0xac, 0x48, 0x9d, 0x1c, 0x1f, 0xc4, 0x49, 0x78, 0x0c, + 0x63, 0xbf, 0x0a, 0x4e, 0xcf, 0x04, 0x3c, 0x65, 0x64, 0x7a, 0x89, 0xe6, 0xd3, 0x77, 0xd6, 0x1f, + 0xcf, 0x43, 0x9c, 0xe5, 0x75, 0xde, 0x16, 0x71, 0x37, 0x61, 0x4c, 0xf6, 0x87, 0x2b, 0xfc, 0x07, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xd6, 0x2c, 0xaf, 0xdd, 0x8e, 0xee, 0x15, 0xf5, 0x46, 0xb7, + 0xde, 0xd7, 0xa3, 0x50, 0xac, 0x8e, 0xc2, 0x34, 0x02, 0xd2, 0x2a, 0xdd, 0xff, 0xdc, 0xf0, 0xba, + 0x8a, 0x5a, 0x96, 0x77, 0xca, 0x80, 0xa6, 0x60, 0x0a, 0x2a, 0x5b, 0x73, 0x5d, 0x0e, 0xeb, 0x52, + 0x76, 0x6b, 0x67, 0x3b, 0x59, 0x81, 0xc9, 0xfa, 0x8d, 0x82, 0x01, 0x76, 0x2c, 0x29, 0x9a, 0xa6, + 0xbf, 0xd2, 0x9a, 0x8a, 0x0b, 0x0d, 0xfb, 0x29, 0xb9, 0x7b, 0x37, 0x42, 0xa6, 0xe0, 0xbc, 0x13, + 0x45, 0x57, 0x37, 0x60, 0x3f, 0xe0, 0xeb, 0xb5, 0xbf, 0x39, 0x9f, 0x1d, 0xdc, 0x4c, 0xee, 0xea, + 0xb4, 0xb5, 0x1f, 0x80, 0xe6, 0x12, 0xf0, 0x85, 0x54, 0x3d, 0x58, 0x8b, 0x21, 0x8a, 0x8e, 0xdb, + 0xab, 0xf3, 0xf8, 0x26, 0x63, 0x19, 0x61, 0xf8, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xb6, 0x34, + 0xaf, 0xdd, 0x5d, 0x70, 0x77, 0xc6, 0x5b, 0x81, 0x61, 0x35, 0x4d, 0x00, 0x3e, 0x7e, 0x5e, 0x7e, + 0xe4, 0x20, 0x03, 0xc2, 0x6e, 0x06, 0xd4, 0x13, 0x02, 0x05, 0xc9, 0x34, 0xcd, 0x9a, 0x72, 0xaa, + 0x2c, 0x54, 0x83, 0xdc, 0x30, 0x1b, 0xc1, 0xa6, 0x5e, 0xd7, 0x94, 0xae, 0x1a, 0x55, 0xba, 0x28, + 0xa3, 0x28, 0xde, 0xb6, 0x34, 0xa6, 0x34, 0xbb, 0xd1, 0xa1, 0xd2, 0x0d, 0x5f, 0xcd, 0xe2, 0xe8, + 0x5b, 0xb3, 0xe7, 0x07, 0x0b, 0xbf, 0x07, 0xd9, 0x03, 0x10, 0x6b, 0xde, 0x07, 0xbb, 0xc2, 0x30, + 0x5b, 0x34, 0x7f, 0xd6, 0xbe, 0x0e, 0x2f, 0xe9, 0x33, 0xbe, 0x7c, 0x86, 0x1f, 0x5f, 0xae, 0x34, + 0xe0, 0xad, 0x7e, 0xa2, 0x02, 0x7e, 0x10, 0x2f, 0x91, 0x19, 0x94, 0xc3, 0x3c, 0xe6, 0x0f, 0x1e, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa5, 0xfc, 0xaf, 0xdd, 0x5d, 0x72, 0x40, 0x99, 0x6f, 0xc2, + 0x1b, 0xde, 0x55, 0x98, 0xc8, 0xd0, 0x3c, 0x25, 0xd4, 0xe3, 0x93, 0x2c, 0x6e, 0x62, 0xaf, 0xb2, + 0xdb, 0xab, 0xd4, 0xaf, 0x14, 0x09, 0x1e, 0x1a, 0xde, 0x12, 0xba, 0xc8, 0x63, 0x9d, 0xa2, 0x67, + 0x75, 0xd8, 0x3e, 0xe6, 0xe2, 0x8c, 0xf7, 0xd2, 0xcd, 0x83, 0x33, 0x09, 0x95, 0xea, 0x42, 0x51, + 0x17, 0xad, 0x45, 0xbe, 0x80, 0xd2, 0x64, 0x18, 0x00, 0x7f, 0x59, 0x56, 0xd6, 0xb8, 0x0d, 0x43, + 0x0a, 0x8e, 0xad, 0xa4, 0x7f, 0x11, 0xc7, 0x8b, 0x90, 0x83, 0x43, 0xed, 0xf1, 0x88, 0x74, 0xd1, + 0x1d, 0x0d, 0x3c, 0xeb, 0xfb, 0x10, 0x0c, 0xed, 0xa0, 0xa5, 0x98, 0xec, 0xa7, 0xdd, 0xab, 0x5c, + 0xd4, 0x63, 0xa2, 0x19, 0x09, 0x4e, 0x7f, 0x03, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc6, 0x3c, + 0x69, 0x22, 0xe8, 0x73, 0x20, 0x58, 0x38, 0x1d, 0xfd, 0x9e, 0xa2, 0xb7, 0x7b, 0x72, 0x36, 0xfa, + 0x26, 0x3e, 0xc4, 0x03, 0xe2, 0x8f, 0x86, 0x5b, 0xdf, 0xa9, 0x39, 0xcb, 0xac, 0xd4, 0x2e, 0xbd, + 0xeb, 0x4b, 0x27, 0x06, 0xf9, 0xff, 0x26, 0x50, 0xe8, 0x4e, 0xeb, 0xae, 0x9f, 0x93, 0x95, 0xf2, + 0x68, 0xb7, 0xba, 0x84, 0x0d, 0x9c, 0xbe, 0x08, 0x7a, 0x70, 0x62, 0x51, 0x22, 0x27, 0x43, 0x23, + 0xd7, 0x8b, 0x2a, 0x7c, 0xac, 0xe0, 0xa4, 0x6e, 0x1f, 0xde, 0x6b, 0x65, 0x8c, 0x7f, 0xfd, 0x87, + 0x36, 0x40, 0xa8, 0xd5, 0xbb, 0x86, 0xed, 0xf3, 0xd8, 0x0c, 0x1d, 0x0b, 0x8b, 0x5a, 0x80, 0xd4, + 0xca, 0xcb, 0x72, 0x52, 0x95, 0xa7, 0xea, 0xa9, 0xe4, 0xec, 0xed, 0x06, 0xd8, 0xcc, 0x3e, 0x07, + 0x79, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xb6, 0x2c, 0xb0, 0xd2, 0xdb, 0xe7, 0x6a, 0xb8, 0xa5, 0x31, + 0x37, 0xee, 0x2f, 0x89, 0x78, 0x18, 0xf9, 0x03, 0xd4, 0xab, 0xfb, 0x14, 0x26, 0xf8, 0xe2, 0x1c, + 0x20, 0x4c, 0x35, 0xe8, 0x8c, 0x56, 0x17, 0xaa, 0xb4, 0x68, 0xda, 0xb9, 0x19, 0x39, 0xd2, 0x13, + 0x8d, 0xa6, 0x21, 0xc4, 0xec, 0xd6, 0xcb, 0xa1, 0xb6, 0xc2, 0x06, 0xc1, 0x96, 0xed, 0x18, 0x46, + 0x09, 0x1e, 0x39, 0x1c, 0xeb, 0x36, 0xa1, 0x99, 0x8a, 0xfd, 0x14, 0x33, 0x80, 0x35, 0x31, 0xf1, + 0x24, 0x85, 0x80, 0x1f, 0x90, 0x84, 0x82, 0xa9, 0x32, 0xc3, 0x01, 0xc1, 0xda, 0x1d, 0x43, 0x8f, + 0xed, 0x8b, 0x3e, 0xe9, 0x57, 0xd8, 0x56, 0x0c, 0xc6, 0x77, 0x7d, 0x4b, 0xd0, 0x83, 0x14, 0xf4, + 0x5a, 0x4a, 0x21, 0x05, 0x86, 0x41, 0xa7, 0xc1, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc5, 0xfc, + 0xae, 0xed, 0x1b, 0x9f, 0x80, 0x9b, 0x46, 0xc9, 0xee, 0xe6, 0xaa, 0x41, 0xa7, 0x40, 0x48, 0xa1, + 0x08, 0x99, 0x82, 0x48, 0x0a, 0xc8, 0x52, 0x66, 0x58, 0x96, 0x70, 0x6e, 0x50, 0xe3, 0x43, 0xa5, + 0x74, 0x31, 0xc7, 0x0c, 0x15, 0x94, 0x74, 0x02, 0xd2, 0x96, 0x3a, 0x15, 0x4a, 0xd3, 0x28, 0x07, + 0x6a, 0x8d, 0x97, 0x21, 0x33, 0xbf, 0xe8, 0x80, 0xaf, 0xec, 0x35, 0xb4, 0x2b, 0xba, 0xad, 0xec, + 0xc8, 0xe4, 0x80, 0x3e, 0x90, 0x19, 0x02, 0x5d, 0x48, 0x47, 0x90, 0xf3, 0xbe, 0x0f, 0x7f, 0xde, + 0x13, 0xbd, 0x72, 0x97, 0xf0, 0x87, 0xbc, 0x4f, 0x1d, 0x7a, 0xa8, 0xd2, 0x06, 0x19, 0xbb, 0xe4, + 0xbe, 0x5d, 0x4d, 0x24, 0x54, 0xaa, 0xa1, 0x4b, 0x27, 0x2f, 0x1b, 0x4b, 0x7c, 0x26, 0x59, 0x58, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc6, 0x34, 0xaf, 0xdd, 0x5d, 0x57, 0xcc, 0xa3, 0x86, 0x1d, + 0x6d, 0xdd, 0x40, 0xe6, 0x3a, 0x6c, 0xca, 0x2d, 0xb9, 0xbd, 0xaf, 0xf4, 0x89, 0x12, 0x83, 0x82, + 0xcd, 0x72, 0x04, 0x91, 0xdd, 0xe4, 0x9c, 0xdd, 0x5f, 0x2d, 0x77, 0xf9, 0x7c, 0xa7, 0x5c, 0x9a, + 0xf4, 0x20, 0x33, 0x6b, 0x59, 0x3d, 0xe1, 0xb7, 0x91, 0xa1, 0xac, 0xc3, 0xad, 0x4c, 0xea, 0xec, + 0x6a, 0x06, 0xe4, 0xfa, 0xf2, 0x9a, 0x33, 0xea, 0x18, 0x12, 0xa0, 0xdc, 0xfc, 0x37, 0xd9, 0x4c, + 0xaa, 0x11, 0xe7, 0x03, 0x39, 0x72, 0xbf, 0x1c, 0xca, 0xd3, 0x5f, 0x1b, 0x02, 0xff, 0xa7, 0x67, + 0x7c, 0x14, 0x4f, 0xed, 0x54, 0x77, 0x73, 0x2c, 0x48, 0x48, 0x0f, 0xa6, 0x47, 0x87, 0x08, 0x1f, + 0x41, 0xb2, 0x4f, 0xfc, 0x39, 0x0f, 0x77, 0xc1, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa6, 0x3c, + 0x69, 0xd4, 0x6a, 0x42, 0x63, 0xb5, 0x97, 0x25, 0xe0, 0xa6, 0x00, 0x93, 0xdc, 0x9c, 0x68, 0xb5, + 0x58, 0x2e, 0x3c, 0x24, 0x05, 0xf7, 0xa7, 0x33, 0xc6, 0x48, 0x94, 0x63, 0xdd, 0x8e, 0xd1, 0xe2, + 0x14, 0x7e, 0x33, 0xfc, 0xec, 0x43, 0x1b, 0x78, 0x02, 0x1b, 0x5a, 0x78, 0xae, 0x2e, 0x2d, 0x95, + 0x7f, 0x41, 0x2f, 0x90, 0x46, 0x57, 0xc0, 0xf0, 0xd3, 0xde, 0x1d, 0xa9, 0x86, 0x4d, 0x5d, 0x76, + 0x58, 0x44, 0x76, 0x1f, 0x47, 0x26, 0x38, 0xf8, 0xc4, 0x9a, 0x02, 0xb7, 0x1c, 0xfc, 0x39, 0xe6, + 0x72, 0x94, 0x78, 0x70, 0x2e, 0x51, 0xfc, 0xf4, 0xba, 0x5c, 0x17, 0xcf, 0x14, 0xc0, 0x2d, 0x7b, + 0xb6, 0x5c, 0x49, 0x72, 0x92, 0xdc, 0x83, 0xa7, 0x90, 0x3b, 0x96, 0xc9, 0x07, 0x8e, 0x7c, 0x63, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa6, 0x34, 0xaf, 0xdd, 0x72, 0x00, 0xd7, 0xcf, 0x22, 0x79, + 0xce, 0xce, 0x21, 0xcf, 0x85, 0xd9, 0x2a, 0xd8, 0xd4, 0x1d, 0x00, 0x49, 0xae, 0x4e, 0x01, 0x08, + 0xf8, 0x7e, 0xc2, 0x91, 0x69, 0x68, 0x1d, 0x04, 0xf9, 0x06, 0x30, 0xf3, 0x15, 0x53, 0xd6, 0x08, + 0xf3, 0x0f, 0x96, 0xac, 0x17, 0x9d, 0x42, 0xc5, 0xdb, 0xa2, 0x15, 0xbb, 0x2e, 0xd1, 0x6e, 0x9e, + 0xed, 0x97, 0xd1, 0xb0, 0x2e, 0x89, 0xa8, 0x8e, 0x89, 0x27, 0x2c, 0xfd, 0x9a, 0x22, 0x84, 0x21, + 0x91, 0x6b, 0x64, 0x96, 0x00, 0xfe, 0x5d, 0x07, 0x0b, 0xa2, 0x7e, 0xab, 0xd0, 0xee, 0xeb, 0xb7, + 0x8e, 0xbb, 0x85, 0x78, 0x9f, 0xa0, 0x5e, 0x6c, 0x62, 0x47, 0x5d, 0xe1, 0x65, 0x0e, 0x0e, 0xc7, + 0x1d, 0x00, 0x75, 0x9b, 0x4a, 0x42, 0x5f, 0x01, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc5, 0xbc, + 0xb0, 0xdc, 0x62, 0x56, 0xd4, 0x50, 0x19, 0x30, 0x62, 0x00, 0x93, 0x48, 0x23, 0xd8, 0x8a, 0x44, + 0xe5, 0xdb, 0x09, 0x9c, 0x08, 0x8d, 0x74, 0xbf, 0x33, 0x1a, 0x33, 0x3e, 0xe3, 0xc0, 0x4c, 0x79, + 0x28, 0x9c, 0x4a, 0x19, 0x27, 0x97, 0x7f, 0x42, 0x74, 0x3f, 0xa5, 0x7c, 0xe0, 0x3e, 0xf4, 0x39, + 0x22, 0xa0, 0x05, 0x2e, 0x0a, 0x83, 0xa0, 0x55, 0x47, 0xc2, 0xed, 0xb1, 0x14, 0x20, 0x5f, 0xff, + 0x7a, 0x32, 0x19, 0x50, 0xdb, 0x16, 0x80, 0x7d, 0x1f, 0x6a, 0x9b, 0xc2, 0x8e, 0xfc, 0x70, 0x40, + 0x1a, 0x91, 0xb0, 0x87, 0xad, 0x8b, 0xb7, 0x8e, 0x44, 0xad, 0x0d, 0x70, 0x7b, 0x7a, 0x40, 0xae, + 0x15, 0x3f, 0x73, 0x02, 0xe0, 0xbe, 0x9f, 0xcf, 0x6d, 0xbf, 0x4a, 0x3a, 0x0c, 0x92, 0x76, 0x1e, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xb6, 0x3c, 0x69, 0xd4, 0x53, 0xbd, 0x32, 0xc2, 0x82, 0x19, + 0xbf, 0x3c, 0x5c, 0x7a, 0xac, 0x01, 0xfc, 0x94, 0x76, 0xf9, 0x6b, 0x28, 0x39, 0x72, 0xce, 0x1c, + 0x1a, 0x3a, 0x81, 0x04, 0xc8, 0x07, 0x55, 0xca, 0x05, 0x2c, 0x0b, 0xb8, 0x64, 0x65, 0xf5, 0x38, + 0xa7, 0x01, 0x29, 0xd5, 0x6a, 0x00, 0xef, 0x4a, 0xcf, 0x97, 0x8c, 0x1b, 0xd5, 0x27, 0x32, 0x9a, + 0xf3, 0x93, 0x58, 0x30, 0x5c, 0x7e, 0xfb, 0xed, 0x58, 0x6e, 0x8a, 0x96, 0xd0, 0xc6, 0x72, 0x01, + 0xc3, 0x8a, 0x5a, 0x69, 0x19, 0x01, 0xe5, 0xa7, 0xfc, 0x1e, 0x78, 0x3f, 0x98, 0xec, 0xae, 0xe3, + 0x9a, 0x88, 0x1a, 0xea, 0x9e, 0xda, 0x15, 0xf6, 0x85, 0x6c, 0x04, 0x94, 0x57, 0x8e, 0xd7, 0x3f, + 0xca, 0x5c, 0x39, 0xde, 0xe0, 0x63, 0xbc, 0x07, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc6, 0x2c, + 0x69, 0xd4, 0x8a, 0x58, 0x8e, 0xc0, 0x35, 0x85, 0x61, 0x67, 0xd5, 0x84, 0x18, 0x61, 0xee, 0xc4, + 0xc5, 0x01, 0xe4, 0xca, 0xbb, 0xea, 0xa2, 0x35, 0x61, 0xbb, 0x6b, 0x86, 0x9c, 0x9f, 0xba, 0x0f, + 0x85, 0x76, 0xe5, 0x87, 0x82, 0x79, 0xf5, 0x53, 0x72, 0x58, 0x77, 0x5c, 0xb9, 0x81, 0x0a, 0xe3, + 0xbe, 0xae, 0xd5, 0x6b, 0xe8, 0x4d, 0xdb, 0x08, 0xf6, 0x94, 0xed, 0x5a, 0xe9, 0x55, 0x2d, 0x0f, + 0x54, 0xcd, 0x6f, 0x9f, 0xaa, 0x98, 0x47, 0x84, 0xfb, 0xb8, 0xd9, 0x99, 0x08, 0x0f, 0xe1, 0x1f, + 0x35, 0xad, 0xf7, 0x64, 0x04, 0xf2, 0xb6, 0x5d, 0x90, 0x62, 0x6f, 0xee, 0x7e, 0x62, 0x89, 0xfc, + 0x4e, 0xef, 0x82, 0x8f, 0x03, 0x5a, 0x58, 0x28, 0x22, 0x0d, 0xa3, 0xcc, 0x23, 0xc6, 0x3c, 0x0f, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc5, 0xd4, 0x69, 0xd4, 0x53, 0x87, 0x0f, 0xf2, 0x3d, 0xef, + 0xd0, 0x40, 0x99, 0x3c, 0xe2, 0xcc, 0x21, 0x07, 0x34, 0x09, 0x82, 0x32, 0x55, 0x25, 0xd8, 0xe5, + 0xc8, 0xc4, 0x4f, 0x97, 0x27, 0xd0, 0x14, 0x1c, 0x54, 0x88, 0x92, 0xa1, 0x2c, 0xc6, 0xd6, 0xf3, + 0xe3, 0x18, 0x39, 0xa8, 0x79, 0x9f, 0x85, 0x36, 0xb1, 0xa2, 0x66, 0xf2, 0x35, 0xf0, 0xb1, 0x05, + 0x4e, 0xcf, 0x61, 0x4f, 0x7f, 0x77, 0xe8, 0xf5, 0x74, 0xd9, 0x1f, 0x75, 0x7e, 0x12, 0x8e, 0xf7, + 0xd5, 0x65, 0x34, 0xd4, 0x7e, 0x27, 0xbc, 0x6f, 0xe2, 0xb2, 0xf5, 0x2a, 0x7c, 0x36, 0xb0, 0x46, + 0x74, 0x8d, 0x03, 0x3e, 0x50, 0x6b, 0x2e, 0xed, 0xa6, 0xa6, 0x90, 0xee, 0x6b, 0xac, 0xe1, 0x30, + 0x72, 0x6b, 0xff, 0x04, 0xda, 0x9e, 0x38, 0x3e, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa6, 0x3c, + 0xb0, 0xdc, 0x62, 0x6f, 0xa5, 0x3a, 0x56, 0xe6, 0x06, 0xa8, 0x75, 0x42, 0x00, 0x27, 0x19, 0xf9, + 0xb6, 0xf4, 0x19, 0x6e, 0xb3, 0x73, 0x5b, 0x69, 0x18, 0xc3, 0x23, 0x2d, 0x6c, 0xf2, 0x40, 0x80, + 0xef, 0x26, 0xe6, 0x53, 0xfd, 0xce, 0xbb, 0x47, 0xe5, 0xda, 0x38, 0x82, 0xc0, 0x19, 0x69, 0x0b, + 0xa2, 0xcc, 0x9a, 0x6a, 0x38, 0xb9, 0x18, 0xab, 0x9b, 0xd9, 0x5e, 0x19, 0xec, 0x35, 0x01, 0x9c, + 0x4b, 0x55, 0x2d, 0xec, 0xaa, 0x84, 0x98, 0x2a, 0xe6, 0xb8, 0x03, 0x8e, 0xd9, 0xe5, 0x1b, 0x92, + 0xec, 0x43, 0xf6, 0x50, 0xbf, 0x7f, 0xe9, 0xee, 0x9b, 0x0a, 0x36, 0x68, 0xd4, 0xda, 0xd4, 0x69, + 0x22, 0x56, 0xdb, 0x6c, 0xd7, 0x09, 0x85, 0x10, 0x01, 0xaf, 0xf0, 0x63, 0xc3, 0xe1, 0x9f, 0x07, + 0x9b, 0xc5, 0x37, 0xee, 0xb2, 0x39, 0xc5, 0xe4, 0x00, 0xc0, 0x5f, 0xba, 0x85, 0x0b, 0x4f, 0x32, + 0x77, 0xe0, 0x1b, 0xc9, 0xdf, 0x64, 0x30, 0x0c, 0x39, 0x0f, 0xdd, 0xce, 0x93, 0xfc, 0x85, 0xb9, + 0x62, 0xc4, 0x1b, 0x32, 0x49, 0x0e, 0x04, 0x6d, 0x42, 0x78, 0xfb, 0x7a, 0x3d, 0x7b, 0x26, 0x17, + 0x12, 0xab, 0x24, 0x49, 0x7f, 0xbd, 0xf5, 0x32, 0xa2, 0x24, 0xd7, 0x1e, 0x6f, 0xe0, 0xc2, 0xda, + 0x85, 0xdc, 0x78, 0x1a, 0xf2, 0x76, 0xea, 0x90, 0xa1, 0x32, 0x6d, 0x72, 0x10, 0x2b, 0x20, 0x6c, + 0x1b, 0x91, 0xcf, 0x38, 0x3e, 0x0f, 0x87, 0x86, 0x67, 0xb1, 0xc2, 0xe8, 0xb6, 0x78, 0xe8, 0x36, + 0x1a, 0x2e, 0xa3, 0xb9, 0xdb, 0xe9, 0x02, 0xee, 0x8d, 0xaa, 0xa1, 0x72, 0xbc, 0xb1, 0x32, 0x03, + 0xe0, 0x7e, 0x07, 0xf0, 0x3f, 0x01, 0xe5, 0x83, 0x3d, 0xe2, 0x9b, 0xf7, 0x59, 0x0a, 0x25, 0xca, + 0x37, 0xc7, 0xc2, 0xa2, 0x56, 0x44, 0xb6, 0x00, 0x00, 0x1a, 0x32, 0xe9, 0xbc, 0x47, 0xbe, 0x1c, + 0x9f, 0x82, 0xf7, 0xda, 0xa5, 0x58, 0xa9, 0x04, 0x3c, 0x68, 0xed, 0x36, 0x07, 0x81, 0xe4, 0xc1, + 0x33, 0xbe, 0x92, 0x8b, 0x82, 0xe2, 0x48, 0xc7, 0x44, 0xf2, 0x0f, 0x25, 0xb1, 0x2d, 0xde, 0xbe, + 0xc1, 0x73, 0x0c, 0xb4, 0x8e, 0xe3, 0xcc, 0x70, 0x91, 0xfc, 0xc6, 0x35, 0x94, 0xb3, 0x5c, 0x4b, + 0xd3, 0x99, 0x5b, 0x44, 0xed, 0xf2, 0x94, 0x7f, 0x7c, 0x58, 0x63, 0x1b, 0x93, 0x9e, 0x3c, 0x38, + 0xf8, 0x16, 0x70, 0x29, 0xab, 0xba, 0xfb, 0x2d, 0x5b, 0xa8, 0x10, 0x62, 0xe9, 0xe6, 0x8c, 0xe2, + 0xc0, 0xe8, 0x56, 0xb0, 0x13, 0xc7, 0x73, 0x38, 0x20, 0xf0, 0xd3, 0x67, 0x1c, 0xf0, 0xf8, 0x43, + 0xcd, 0xe2, 0x9b, 0xf7, 0x59, 0x1a, 0x06, 0x32, 0x37, 0xca, 0x74, 0x3f, 0xcb, 0x5e, 0xc6, 0xaa, + 0x00, 0x01, 0xa0, 0xea, 0xed, 0x68, 0x7c, 0x8c, 0x51, 0x4d, 0x94, 0x12, 0x69, 0x2c, 0x00, 0x69, + 0x75, 0xcf, 0x95, 0x54, 0xb5, 0x2d, 0x63, 0x60, 0x5e, 0x9b, 0xbc, 0x51, 0xc0, 0x07, 0xba, 0x61, + 0x87, 0x08, 0xba, 0xe6, 0xfd, 0x98, 0xf2, 0x06, 0x80, 0x0d, 0x20, 0x7c, 0x48, 0x23, 0x3a, 0xb9, + 0x74, 0x59, 0x6f, 0xec, 0x9d, 0x2f, 0xb1, 0x4a, 0xd4, 0xb3, 0x4e, 0xfc, 0x7a, 0x33, 0xb0, 0x9a, + 0x0b, 0xa4, 0xce, 0x61, 0x8c, 0xf1, 0x83, 0xc1, 0xe0, 0xa7, 0x06, 0x41, 0x65, 0xb0, 0xee, 0x18, + 0x34, 0x8f, 0x8a, 0x15, 0x42, 0x71, 0x1d, 0xf7, 0x99, 0xe6, 0x2d, 0x7d, 0x86, 0xf9, 0x5e, 0x3a, + 0x64, 0x8a, 0xe6, 0x32, 0x58, 0xc7, 0x11, 0xc3, 0xdd, 0xe2, 0x9b, 0xf7, 0x59, 0x1a, 0x06, 0x32, + 0xaf, 0xdd, 0x47, 0xaf, 0xed, 0xa3, 0xde, 0x00, 0x00, 0x01, 0x43, 0x12, 0x7e, 0x61, 0xbb, 0x2b, + 0x1d, 0x25, 0xb9, 0x7d, 0x8e, 0x56, 0x64, 0x31, 0xdb, 0x3a, 0xf8, 0x23, 0x8b, 0x55, 0x1c, 0xdd, + 0x2d, 0x44, 0x75, 0x2f, 0xc4, 0x86, 0x11, 0x96, 0x4c, 0xf5, 0xc0, 0x8c, 0x1d, 0xc0, 0x70, 0x85, + 0x01, 0x36, 0x29, 0x4b, 0x30, 0xf9, 0x0c, 0x2e, 0x2e, 0xab, 0x75, 0xca, 0x0f, 0xb5, 0x98, 0x2d, + 0x85, 0x23, 0x95, 0x15, 0xd9, 0x3a, 0xd1, 0x47, 0x38, 0xc1, 0xcf, 0x0e, 0x07, 0xc0, 0xf8, 0x1c, + 0x39, 0x7b, 0xbd, 0x31, 0xda, 0xb7, 0x54, 0xc7, 0xce, 0x1a, 0xf3, 0x62, 0x6d, 0xf2, 0x33, 0x4e, + 0x0c, 0x84, 0x04, 0x14, 0xd1, 0x3b, 0x42, 0xb2, 0x11, 0x3a, 0x3a, 0x48, 0x95, 0xc1, 0x29, 0xfe, + 0x5d, 0xd7, 0x8e, 0xf7, 0x59, 0x1a, 0x16, 0x2a, 0x00, 0x00, 0x00, 0x5c, 0x28, 0x11, 0x53, 0x00, + 0x8c, 0xdc, 0x43, 0x04, 0x31, 0x3f, 0x9d, 0x4a, 0x0b, 0xf6, 0x08, 0xd3, 0x72, 0x9c, 0x3f, 0x79, + 0x25, 0x35, 0x5f, 0x40, 0xdb, 0xae, 0x90, 0xbe, 0x35, 0xf4, 0x76, 0xaa, 0x39, 0xba, 0x07, 0x23, + 0xc6, 0x4c, 0x83, 0xbc, 0xee, 0x94, 0x25, 0x80, 0x2a, 0x8d, 0x1a, 0x7f, 0x80, 0xa7, 0x24, 0x50, + 0x17, 0x5b, 0x24, 0x09, 0xe7, 0x28, 0xf6, 0x9b, 0xcd, 0x57, 0x4f, 0x9c, 0x60, 0xef, 0x16, 0xcc, + 0x16, 0x16, 0x7b, 0x34, 0xc8, 0xe1, 0xf0, 0x88, 0x30, 0xb4, 0xb2, 0xcb, 0x30, 0xc9, 0x44, 0x28, + 0xfa, 0xb3, 0xe0, 0x21, 0x20, 0x00, 0xc0, 0x5a, 0xcb, 0x01, 0x0f, 0x06, 0x34, 0x67, 0x8e, 0xf8, + 0x7c, 0x1f, 0x80, 0xfe, 0x07, 0xc0, 0xf8, 0x32, 0xcb, 0x21, 0x8b, 0x97, 0x59, 0x0a, 0x06, 0x3a, + 0xb0, 0xd2, 0xc2, 0xb5, 0xa3, 0xc7, 0x39, 0x0e, 0x03, 0xf4, 0xb2, 0xef, 0x07, 0xda, 0xb6, 0xfd, + 0xfa, 0x68, 0xc1, 0x01, 0xe1, 0x5a, 0x65, 0xe7, 0x5b, 0x3a, 0xf3, 0x1a, 0xe7, 0x68, 0xda, 0xb9, + 0x19, 0x4d, 0xb4, 0xd8, 0x9f, 0x2d, 0x49, 0xba, 0x8c, 0x34, 0x95, 0x40, 0x35, 0x86, 0xfc, 0xd1, + 0x25, 0x6c, 0x90, 0x81, 0xd5, 0x1c, 0xb9, 0xb7, 0xfa, 0x6e, 0x47, 0xd5, 0xbc, 0x83, 0xcf, 0xdb, + 0x58, 0x54, 0x41, 0xf5, 0x28, 0xe2, 0x40, 0x72, 0x7c, 0x19, 0x98, 0x54, 0xe7, 0x07, 0x9c, 0xfe, + 0x10, 0xe5, 0xd3, 0x45, 0xaf, 0x2c, 0x05, 0x07, 0xe7, 0xca, 0x90, 0x28, 0xe4, 0xb0, 0x44, 0x99, + 0x7a, 0x8a, 0xf2, 0x71, 0x8e, 0x64, 0x8a, 0xf4, 0x21, 0xc0, 0x90, 0x53, 0x7e, 0x78, 0x12, 0x1c, + 0x5b, 0x21, 0x8b, 0x97, 0x59, 0x1a, 0x16, 0x2a, 0xaf, 0xde, 0xcb, 0xf9, 0xc9, 0x12, 0x54, 0xc3, + 0xb6, 0xbf, 0xc6, 0xdd, 0x33, 0xef, 0x43, 0xbb, 0x3f, 0x61, 0x00, 0xdf, 0x78, 0x66, 0x7c, 0x52, + 0x78, 0x22, 0x5a, 0x11, 0x2f, 0xa6, 0x2d, 0x29, 0xd3, 0xf5, 0x2b, 0x54, 0x7d, 0x23, 0xc3, 0x14, + 0x17, 0x5c, 0x47, 0x14, 0x3e, 0x40, 0xf9, 0x87, 0x56, 0x0b, 0x97, 0x3a, 0xa9, 0x71, 0x0f, 0x84, + 0xee, 0xa0, 0xa0, 0xc2, 0xc3, 0xf3, 0x10, 0xbc, 0xa1, 0x1b, 0x7b, 0xcd, 0x21, 0x87, 0x66, 0x05, + 0x87, 0x9e, 0x18, 0x7b, 0x33, 0x26, 0x7c, 0xc5, 0x42, 0xe2, 0x04, 0x2c, 0xfc, 0xd2, 0xcc, 0x09, + 0x39, 0xa3, 0x8c, 0x74, 0xda, 0xc6, 0x4b, 0xa6, 0x53, 0xda, 0xc2, 0x51, 0x5f, 0x77, 0x6a, 0x14, + 0x75, 0x95, 0xe7, 0x9c, 0x0a, 0x26, 0x59, 0x81, 0xdb, 0x21, 0x8b, 0x97, 0x59, 0x1a, 0x26, 0x32, + 0xaf, 0xde, 0xcb, 0xf9, 0xd9, 0x8b, 0x32, 0x47, 0x46, 0x01, 0xfe, 0xdc, 0xee, 0xca, 0xbb, 0x21, + 0xe2, 0x27, 0xf6, 0xc0, 0x74, 0x81, 0xd9, 0xaa, 0xab, 0xf8, 0x70, 0x9d, 0x8d, 0x88, 0xd7, 0x08, + 0x4b, 0x17, 0x2f, 0xd9, 0xa6, 0xe0, 0x2f, 0x93, 0x48, 0xf7, 0x33, 0xb2, 0xb3, 0x2d, 0x19, 0x18, + 0x12, 0xfd, 0x31, 0xb8, 0xcc, 0xfe, 0x64, 0x87, 0x69, 0xdc, 0xe4, 0x5c, 0x65, 0xe5, 0x77, 0xb0, + 0x68, 0xb0, 0x06, 0xb4, 0x3b, 0x59, 0x19, 0x83, 0x3c, 0x38, 0x3c, 0x3c, 0x38, 0x78, 0x83, 0x61, + 0xd0, 0x31, 0x81, 0x97, 0x03, 0xb8, 0xef, 0x01, 0x15, 0x40, 0x82, 0xed, 0x8b, 0x08, 0x4f, 0x71, + 0x32, 0xf5, 0xc9, 0x29, 0x1b, 0x2b, 0xac, 0x4c, 0x10, 0x70, 0xa7, 0x97, 0x07, 0x0e, 0x49, 0xe3, + 0xdb, 0x21, 0x4b, 0x97, 0x59, 0x1a, 0x26, 0x12, 0xae, 0xec, 0x11, 0x26, 0xe8, 0x37, 0x92, 0x31, + 0xe5, 0x7f, 0x28, 0xd9, 0x53, 0x25, 0xa2, 0x66, 0x43, 0xcd, 0x52, 0x54, 0x1d, 0x5b, 0xc6, 0x8a, + 0x80, 0xb8, 0x1c, 0x95, 0x07, 0xbc, 0xd0, 0x16, 0xe2, 0x9d, 0x9e, 0x69, 0x70, 0x19, 0xe3, 0x82, + 0x2c, 0xb5, 0x68, 0xe8, 0x7d, 0x89, 0x1a, 0xcd, 0x5a, 0x2e, 0x31, 0x6a, 0x09, 0x5b, 0xb5, 0x65, + 0x8b, 0xd3, 0x84, 0x69, 0xae, 0xaa, 0xd1, 0xbf, 0x98, 0x54, 0x1f, 0xbe, 0x56, 0xfe, 0x6c, 0x38, + 0x47, 0x8f, 0x73, 0x0c, 0xc7, 0xe0, 0x43, 0x58, 0x7e, 0xba, 0xbf, 0x42, 0x48, 0xe0, 0x02, 0xaa, + 0x07, 0x30, 0xfe, 0x2f, 0xcb, 0xc4, 0xd0, 0xd8, 0x90, 0xf7, 0xab, 0x12, 0xee, 0x44, 0x87, 0x70, + 0x74, 0xa0, 0x63, 0xfb, 0xc1, 0xe2, 0x6c, 0x9e, 0x5b, 0x21, 0x8b, 0x97, 0x59, 0x19, 0xf6, 0x2a, + 0xaf, 0xa6, 0xc8, 0x17, 0x83, 0x85, 0xb2, 0x00, 0x04, 0x26, 0x17, 0x1b, 0xb0, 0x82, 0x3d, 0x92, + 0x55, 0x92, 0x2c, 0xcb, 0x67, 0x59, 0x5d, 0xa4, 0x57, 0xb5, 0xf4, 0x0b, 0xcd, 0x2d, 0x28, 0x50, + 0x40, 0x15, 0x90, 0x80, 0x09, 0xb6, 0x09, 0x0b, 0x90, 0x65, 0xdb, 0xc6, 0xf1, 0x86, 0xd9, 0x38, + 0xd8, 0xa2, 0x03, 0x25, 0xc0, 0x97, 0x38, 0x86, 0xfd, 0x86, 0x46, 0x1a, 0xb9, 0xce, 0xa9, 0x5e, + 0xb6, 0xa4, 0x22, 0x2f, 0x9a, 0x86, 0x38, 0xc2, 0x7b, 0x9e, 0x78, 0x3c, 0x1e, 0x1c, 0x1f, 0x07, + 0x1a, 0x08, 0x32, 0x5b, 0x03, 0x89, 0x1d, 0x5b, 0x9f, 0x94, 0x9e, 0x97, 0xde, 0x51, 0xf2, 0x0d, + 0x17, 0xe9, 0x94, 0xa7, 0xfd, 0x5e, 0xea, 0x1d, 0xe2, 0xa8, 0x0b, 0xc0, 0xc2, 0x00, 0xc1, 0xec, + 0x4b, 0x21, 0x4b, 0x97, 0x59, 0x1a, 0x06, 0x1a, 0xaf, 0xde, 0xcb, 0xf9, 0xbd, 0x13, 0x73, 0x0c, + 0x76, 0x0e, 0x78, 0x17, 0x02, 0x17, 0xd2, 0xd1, 0x02, 0xfc, 0x16, 0xa1, 0x3f, 0x01, 0x7d, 0x07, + 0x4a, 0xc9, 0x36, 0x24, 0x45, 0xff, 0xd4, 0x75, 0x8f, 0x51, 0x98, 0xd1, 0x81, 0x98, 0x2a, 0x87, + 0xdc, 0x6f, 0xb8, 0x72, 0xcc, 0x0f, 0x1f, 0xd1, 0x7b, 0x47, 0x57, 0xe5, 0xd0, 0x37, 0xa1, 0x06, + 0x28, 0x7d, 0x54, 0xeb, 0xca, 0x35, 0xc5, 0x77, 0x08, 0x7a, 0x5b, 0x8e, 0x13, 0x60, 0x93, 0x27, + 0x12, 0x38, 0x61, 0xe7, 0x8f, 0xe2, 0x86, 0x8d, 0x73, 0x04, 0x06, 0xf8, 0xb1, 0x98, 0xe6, 0x3a, + 0x4c, 0x2f, 0x31, 0x97, 0x5d, 0x3d, 0xda, 0xb8, 0xc3, 0x38, 0x03, 0xc6, 0xe1, 0x67, 0x68, 0x23, + 0x75, 0x64, 0x4a, 0x24, 0x80, 0x0c, 0x38, 0x26, 0x5b, 0x21, 0x4b, 0x97, 0x59, 0x19, 0xe6, 0x12, + 0xb0, 0xdc, 0x58, 0x39, 0x3d, 0x8b, 0x23, 0x72, 0x96, 0x1a, 0x93, 0x6a, 0x4f, 0xce, 0x7c, 0x61, + 0x4b, 0xec, 0xc2, 0xd4, 0x2b, 0xbc, 0xbe, 0x07, 0xc6, 0xe1, 0x67, 0x09, 0xbc, 0x3f, 0x3a, 0x43, + 0x0e, 0xc1, 0x55, 0x4e, 0xe1, 0x45, 0xf2, 0x9d, 0x7a, 0x6c, 0x8a, 0x15, 0x85, 0x68, 0xb5, 0x9e, + 0xe4, 0x21, 0xc2, 0x5c, 0x9a, 0x7f, 0xfd, 0x12, 0x4d, 0xdb, 0x57, 0x4a, 0x82, 0x57, 0xf1, 0x15, + 0x9e, 0x9b, 0xa3, 0xeb, 0xf2, 0x9a, 0x16, 0xc3, 0x65, 0x38, 0xe7, 0x38, 0x60, 0xe0, 0xff, 0x5e, + 0xdd, 0x32, 0xfb, 0x28, 0x6a, 0xf7, 0x4e, 0x4c, 0x5e, 0x78, 0x82, 0x5a, 0x6e, 0x9f, 0x99, 0xbf, + 0x21, 0x3f, 0x87, 0x94, 0xf0, 0x70, 0x7c, 0xc9, 0x0e, 0x2b, 0x4c, 0x63, 0x83, 0xce, 0x97, 0xc3, + 0xdb, 0x21, 0x4b, 0x97, 0x59, 0x1a, 0x06, 0x32, 0xb0, 0xdc, 0xac, 0xc2, 0x74, 0xa1, 0x3d, 0x48, + 0x3a, 0x03, 0x09, 0x80, 0x9b, 0x70, 0x44, 0x4f, 0xeb, 0x7d, 0xc6, 0xa5, 0x9f, 0xd8, 0xad, 0x96, + 0x2b, 0xbf, 0x90, 0x15, 0x58, 0x86, 0x2c, 0xec, 0xd1, 0x0a, 0xa1, 0xe6, 0x4e, 0x6a, 0xf4, 0x93, + 0x3e, 0x8c, 0xf0, 0x79, 0x70, 0x49, 0xa2, 0x36, 0x54, 0x72, 0xaf, 0x3f, 0xcd, 0x73, 0xf0, 0x0e, + 0x8c, 0x0f, 0xf0, 0xbc, 0xfe, 0xcf, 0x1e, 0xc7, 0x10, 0xf2, 0x8a, 0x7d, 0xf0, 0xe5, 0x4b, 0x27, + 0x1e, 0x0e, 0x18, 0x0f, 0xea, 0xd8, 0xb6, 0x07, 0x4a, 0x5f, 0xdf, 0x0c, 0x9b, 0x3d, 0xc2, 0x1a, + 0x6f, 0x80, 0xe1, 0x9e, 0xea, 0x44, 0xe5, 0x60, 0x48, 0xb2, 0x83, 0xa4, 0x3c, 0xd6, 0xce, 0xc0, + 0xe6, 0x64, 0xef, 0x11, 0xcf, 0x07, 0x98, 0x63, 0xd3, 0xbf, 0xd0, 0x17, 0x59, 0x19, 0xe6, 0x0a, + 0xaf, 0xa6, 0xca, 0x13, 0xf8, 0x16, 0xcc, 0x00, 0x2e, 0x16, 0x74, 0x2c, 0x96, 0x75, 0x81, 0xc1, + 0x54, 0x0f, 0xd8, 0x5f, 0x66, 0x50, 0xed, 0x38, 0xbc, 0x76, 0xb2, 0x05, 0x47, 0x58, 0xa7, 0xdc, + 0x28, 0x22, 0x37, 0xba, 0x80, 0xc1, 0xce, 0xfc, 0xc3, 0x01, 0xf5, 0xa7, 0x48, 0x74, 0x2b, 0x7a, + 0xf6, 0x3c, 0xed, 0xd3, 0x7a, 0xf7, 0xcf, 0xcd, 0x5a, 0x3a, 0xe2, 0xe7, 0x4a, 0x9e, 0xb8, 0x20, + 0x26, 0x3c, 0xc9, 0x42, 0x4f, 0x84, 0xde, 0x70, 0xe3, 0xe1, 0xf0, 0x7c, 0x1f, 0xf0, 0x08, 0x2b, + 0x86, 0x18, 0x8d, 0x41, 0x97, 0x22, 0x64, 0xd0, 0xe4, 0xf9, 0x77, 0xcc, 0x4d, 0x27, 0x79, 0x60, + 0x8d, 0x40, 0x8f, 0x8e, 0x03, 0x73, 0xd1, 0xe6, 0x27, 0x1f, 0x34, 0xfc, 0x58, 0x09, 0x9e, 0x33, + 0x53, 0xbf, 0xd0, 0x17, 0x59, 0x19, 0xd6, 0x0a, 0xae, 0xec, 0x11, 0x26, 0xb9, 0x70, 0xd6, 0x00, + 0x1d, 0xb3, 0x75, 0x85, 0x2c, 0xf6, 0x85, 0xce, 0x68, 0x9f, 0xd0, 0x02, 0xde, 0x6d, 0xd0, 0xae, + 0x0f, 0x3a, 0x8d, 0x29, 0xf0, 0x62, 0x61, 0x80, 0x25, 0x49, 0x49, 0xcd, 0xa5, 0xad, 0x6e, 0xdb, + 0xb5, 0x0f, 0x50, 0x45, 0x12, 0xb1, 0xae, 0x86, 0xe6, 0xe5, 0x5f, 0x0c, 0x95, 0x17, 0x24, 0xd3, + 0xd6, 0x45, 0x8e, 0x4c, 0x28, 0x38, 0x20, 0xfc, 0x96, 0xea, 0x05, 0xe4, 0x13, 0xd8, 0x90, 0xdc, + 0x31, 0xc3, 0x83, 0xc1, 0xf0, 0xf0, 0xbf, 0x1b, 0x6a, 0x44, 0x76, 0xe5, 0xfd, 0xdf, 0x14, 0xcf, + 0xe3, 0x43, 0x50, 0xa4, 0xe2, 0x8e, 0x4c, 0x46, 0x7a, 0x15, 0xb5, 0xc8, 0x1c, 0xd3, 0x39, 0x23, + 0x21, 0x67, 0x9a, 0xae, 0xf4, 0x0e, 0x19, 0x99, 0xd3, 0xbf, 0xd0, 0x17, 0x59, 0x19, 0xc6, 0x1a, + 0xb0, 0xd3, 0x95, 0x9c, 0x58, 0x00, 0x00, 0x00, 0xf5, 0x3c, 0x01, 0xbc, 0x50, 0x4b, 0x8a, 0x3b, + 0xbe, 0xb0, 0x2c, 0xd8, 0x89, 0x14, 0x24, 0xd0, 0xeb, 0x2b, 0x46, 0x10, 0x67, 0x88, 0xd3, 0xd3, + 0xda, 0x0f, 0x5c, 0x59, 0x59, 0x2c, 0x25, 0x0f, 0x4c, 0x65, 0x0a, 0x9b, 0x0a, 0x21, 0xef, 0xdc, + 0x43, 0xe3, 0x91, 0xf6, 0x38, 0x2d, 0x60, 0xfe, 0x48, 0xec, 0xff, 0x1b, 0xac, 0x69, 0x69, 0x14, + 0x84, 0x18, 0x2d, 0xfb, 0x0d, 0xe8, 0x64, 0xaa, 0x27, 0x87, 0xc7, 0x87, 0xc7, 0xfc, 0x93, 0x00, + 0x84, 0x46, 0xae, 0xd8, 0xb5, 0x8d, 0x59, 0x05, 0xca, 0xd3, 0x74, 0xc9, 0xc5, 0xfb, 0x9c, 0x69, + 0x49, 0xcc, 0xb9, 0xa2, 0x46, 0xca, 0x20, 0xd8, 0xdb, 0xfa, 0xf7, 0xe1, 0x84, 0x8e, 0x35, 0x40, + 0x03, 0xbf, 0xd0, 0x17, 0x59, 0x39, 0xc6, 0x3a, 0xaf, 0xdd, 0x49, 0xd0, 0x58, 0x01, 0x68, 0x7b, + 0x15, 0x25, 0xbc, 0xbd, 0x68, 0xca, 0x4a, 0xaa, 0x1e, 0x7c, 0xca, 0x07, 0xf0, 0x8b, 0xe2, 0x53, + 0xa1, 0xba, 0xcf, 0x90, 0xae, 0xec, 0x67, 0xd5, 0x18, 0xc8, 0xe7, 0xcf, 0xdf, 0x2a, 0x54, 0xef, + 0x84, 0x3c, 0x94, 0x02, 0xc3, 0xc2, 0x71, 0x3b, 0x0e, 0xc5, 0xa1, 0x6d, 0x0a, 0xb9, 0x20, 0xad, + 0xfa, 0xff, 0x3f, 0x40, 0xcf, 0x3a, 0x78, 0x7f, 0x3c, 0xd9, 0x35, 0x70, 0xe3, 0x33, 0xb3, 0x83, + 0xe0, 0xfc, 0x0f, 0xc0, 0xfc, 0x1f, 0x00, 0x73, 0x1f, 0x5f, 0xd1, 0xc7, 0x12, 0x2f, 0xa6, 0x64, + 0x53, 0xbe, 0xe4, 0x8c, 0x0d, 0x97, 0x0f, 0xcd, 0xb3, 0xd2, 0x58, 0xb6, 0xba, 0x18, 0xb8, 0x62, + 0x78, 0x32, 0x88, 0x44, 0x2a, 0xf3, 0x33, 0x33, 0xdb, 0x21, 0x37, 0x97, 0x59, 0x19, 0xf5, 0xca, + 0xaf, 0xdd, 0x49, 0xcf, 0xc5, 0x1e, 0x8a, 0xa2, 0x00, 0xf6, 0x9a, 0xa4, 0x8c, 0x5f, 0xa2, 0x92, + 0x0a, 0x8c, 0x05, 0x2a, 0x5b, 0x3d, 0x0c, 0x7a, 0x22, 0xeb, 0xb9, 0x07, 0xe0, 0x57, 0xc1, 0xd5, + 0x2e, 0x6a, 0x68, 0x8d, 0xcb, 0xd0, 0x32, 0xc8, 0x4a, 0x3f, 0x86, 0x21, 0xc9, 0x08, 0x97, 0x21, + 0x27, 0xa9, 0xb0, 0x38, 0xa1, 0xf3, 0xdd, 0xf5, 0xca, 0x95, 0xab, 0xe6, 0xa9, 0xed, 0x72, 0x36, + 0x30, 0xd1, 0x6f, 0x53, 0xdb, 0xb4, 0x39, 0x64, 0xcc, 0xe3, 0xe0, 0xf8, 0x3c, 0x1e, 0x00, 0x5c, + 0xec, 0xbe, 0xee, 0x62, 0xee, 0x30, 0x47, 0x27, 0x12, 0x4c, 0x50, 0xb1, 0x4b, 0xee, 0xe4, 0x74, + 0x51, 0xf6, 0x91, 0x68, 0xee, 0x17, 0x12, 0xa6, 0xed, 0xdb, 0x20, 0xe8, 0x25, 0xec, 0x72, 0xc9, + 0xdb, 0x21, 0x37, 0x97, 0x59, 0x19, 0xf5, 0x8a, 0xaf, 0xa6, 0xc8, 0x17, 0x7f, 0x81, 0x39, 0x12, + 0x00, 0x8c, 0x3f, 0xc9, 0x35, 0x8a, 0x38, 0x56, 0xa2, 0xee, 0xa0, 0x6a, 0x00, 0x15, 0xde, 0x4d, + 0xd3, 0xca, 0xd3, 0x0a, 0x6e, 0xcd, 0x17, 0xcf, 0x7e, 0x26, 0xde, 0x16, 0x06, 0xdf, 0x37, 0x99, + 0x56, 0xf8, 0x09, 0xf0, 0x77, 0x96, 0xe7, 0xd9, 0x35, 0xf0, 0x67, 0xfa, 0x28, 0x1f, 0x04, 0xa7, + 0x80, 0x95, 0x55, 0xfa, 0xd0, 0x3f, 0x07, 0x1c, 0x82, 0x18, 0x34, 0x74, 0x9c, 0x1e, 0x3c, 0x1f, + 0x07, 0xc0, 0xfe, 0x07, 0xe0, 0xe7, 0x99, 0xdc, 0x6f, 0x24, 0xe4, 0x59, 0xd0, 0x63, 0x86, 0xe2, + 0x7a, 0xa0, 0xa2, 0x48, 0x62, 0x54, 0xff, 0x81, 0x25, 0x64, 0xb8, 0x1f, 0xa0, 0xd6, 0x5c, 0x0b, + 0x23, 0xee, 0xbe, 0x8f, 0x2e, 0xdb, 0x86, 0x41, 0xdb, 0x21, 0x37, 0x97, 0x59, 0x19, 0xe5, 0x7a, + 0xaf, 0xa6, 0xca, 0xa1, 0x55, 0xbe, 0xff, 0xdc, 0x00, 0x04, 0xf7, 0x23, 0x29, 0x46, 0xf6, 0xb4, + 0x53, 0x22, 0x0a, 0x40, 0x7e, 0x6f, 0x58, 0xb9, 0x8c, 0xdb, 0xa1, 0x3c, 0x7b, 0xa5, 0x37, 0xc7, + 0xb3, 0x99, 0xc5, 0x50, 0x17, 0x39, 0x75, 0x8e, 0xb7, 0xfb, 0x7c, 0x3a, 0xd5, 0xa4, 0x7e, 0xd0, + 0x3f, 0xff, 0xe7, 0xb1, 0x37, 0x20, 0x50, 0xf1, 0xb3, 0xef, 0x1b, 0x2f, 0x41, 0x11, 0x82, 0xc1, + 0xa0, 0x6e, 0xdb, 0x4b, 0x76, 0x92, 0x4b, 0x06, 0xb1, 0xc1, 0xf0, 0x7c, 0x0f, 0x83, 0x80, 0x0f, + 0x3f, 0xdd, 0xeb, 0xe5, 0xf6, 0x76, 0x84, 0x46, 0x89, 0x97, 0x5a, 0x4a, 0xa7, 0x01, 0x83, 0xff, + 0x30, 0x0d, 0x1a, 0x37, 0x65, 0xdd, 0x88, 0xa6, 0x32, 0x01, 0x36, 0x2d, 0x96, 0xfb, 0x25, 0xb3, + 0xdb, 0x21, 0x37, 0x97, 0x59, 0x1a, 0x15, 0x6a, 0xaf, 0xdd, 0x47, 0xae, 0x87, 0xb3, 0x6e, 0x00, + 0x2d, 0xd4, 0x97, 0x7a, 0xa6, 0xdf, 0x22, 0x80, 0x85, 0x1b, 0x4f, 0xc2, 0x1f, 0x2c, 0x3c, 0x0b, + 0x5d, 0xbf, 0xc4, 0x84, 0x2b, 0xff, 0x91, 0x11, 0x42, 0x6c, 0xb4, 0xec, 0x24, 0xb7, 0xd3, 0x15, + 0x41, 0xb1, 0x42, 0x15, 0xf2, 0x76, 0x8d, 0x3a, 0x20, 0x9d, 0x6f, 0x84, 0x9f, 0x75, 0x54, 0xe3, + 0x17, 0xbf, 0x03, 0x0f, 0xcb, 0x00, 0xdf, 0x7d, 0x83, 0xeb, 0xa5, 0x5b, 0x09, 0x1c, 0xe3, 0xe0, + 0xf8, 0x0f, 0xc0, 0x7e, 0x07, 0xe1, 0x87, 0x8c, 0x27, 0xc1, 0xfd, 0x79, 0xea, 0xde, 0xdd, 0xa3, + 0x4f, 0xb8, 0x14, 0x51, 0x14, 0xd3, 0x9f, 0x0c, 0x07, 0xa2, 0xaf, 0xcf, 0xb0, 0x5d, 0x13, 0x5a, + 0xa6, 0x97, 0x1a, 0x4c, 0x96, 0x3f, 0xe4, 0x48, 0xdb, 0x21, 0x37, 0x97, 0x59, 0x19, 0xf5, 0x7a, + 0xae, 0xed, 0x18, 0xc3, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x21, 0x1a, 0x23, 0x22, 0x82, + 0xde, 0x56, 0x00, 0x03, 0x39, 0xab, 0x1a, 0x5e, 0x2d, 0x76, 0x3a, 0x8a, 0x3b, 0x7a, 0x9f, 0x90, + 0x8a, 0xba, 0x2c, 0xc0, 0x57, 0xf6, 0x52, 0xbf, 0xc5, 0x90, 0xe2, 0x46, 0x3b, 0x94, 0xfd, 0x1b, + 0x68, 0x50, 0xf6, 0x8c, 0x81, 0x5f, 0x61, 0xa9, 0x06, 0x0a, 0x0b, 0x42, 0x58, 0x0c, 0x8c, 0xfe, + 0x0b, 0xb1, 0x94, 0x78, 0xa0, 0x7e, 0x0f, 0x3c, 0x7c, 0x0f, 0x81, 0xfc, 0x0f, 0xe0, 0xf8, 0xf2, + 0x26, 0x1d, 0x88, 0x44, 0xb8, 0xd3, 0x1d, 0xb4, 0x2b, 0xe8, 0x64, 0x42, 0xb7, 0x2c, 0x72, 0x7d, + 0x93, 0x77, 0xa6, 0xc5, 0x1e, 0x26, 0xfb, 0x7e, 0x40, 0xdf, 0xd0, 0xd5, 0xf4, 0xe7, 0x80, 0xe0, + 0x5b, 0x21, 0x37, 0x97, 0x59, 0x19, 0xf5, 0xd2, 0xae, 0xed, 0x18, 0xc3, 0x34, 0x00, 0x00, 0x00, + 0x0e, 0xd4, 0xbc, 0x15, 0xaa, 0xb6, 0x06, 0x47, 0x8d, 0x6e, 0x00, 0x57, 0x6b, 0xa6, 0xed, 0xff, + 0xdf, 0xc2, 0x48, 0x94, 0x1a, 0xbb, 0xb6, 0xb7, 0x18, 0xd1, 0x28, 0xac, 0x2e, 0x52, 0x81, 0xc1, + 0xa9, 0xa0, 0x62, 0x11, 0xeb, 0xf2, 0xdf, 0xb5, 0xb9, 0x5e, 0xd4, 0x85, 0x94, 0x5a, 0x46, 0xe4, + 0xde, 0x7e, 0xdb, 0x7b, 0xe1, 0x37, 0x57, 0x31, 0x46, 0xd4, 0x02, 0xca, 0x34, 0xe1, 0xfc, 0x70, + 0xf0, 0x3f, 0x01, 0xf0, 0x3e, 0x07, 0x9f, 0x21, 0xd3, 0x9c, 0x19, 0xb1, 0x91, 0x52, 0xbf, 0xf7, + 0xbb, 0x6e, 0xf1, 0x68, 0x99, 0xec, 0x8c, 0x3a, 0x2d, 0x5f, 0x1a, 0x16, 0xaa, 0x97, 0xa7, 0xad, + 0xfd, 0x72, 0x17, 0x32, 0x6f, 0x42, 0xd4, 0x0f, 0xcb, 0x21, 0x37, 0x97, 0x59, 0x19, 0xf5, 0xda, + 0xae, 0xec, 0x0f, 0xb3, 0x42, 0x12, 0xd3, 0x00, 0x00, 0x00, 0xdc, 0x94, 0x9d, 0x84, 0xb1, 0xa5, + 0x70, 0x6a, 0xdb, 0xef, 0x0a, 0xe3, 0xcb, 0x15, 0x2e, 0xb4, 0x56, 0x8f, 0xbd, 0x51, 0xc2, 0x83, + 0x91, 0xa7, 0x98, 0xc0, 0xf5, 0xee, 0xdb, 0x79, 0x1d, 0xb2, 0x13, 0x9d, 0x23, 0x3c, 0xaa, 0x66, + 0x7e, 0x45, 0x17, 0xf3, 0x2c, 0x5f, 0x2c, 0x3b, 0x5d, 0xa5, 0x8a, 0x1c, 0x37, 0x62, 0x8c, 0xaa, + 0x8f, 0x52, 0xa3, 0x35, 0x94, 0x57, 0x34, 0xcd, 0xa6, 0xe4, 0xe1, 0xc3, 0xc3, 0xf8, 0x1f, 0x07, + 0x00, 0x08, 0xe5, 0x13, 0x34, 0x5a, 0x6e, 0x33, 0x24, 0xe6, 0xc1, 0x17, 0xab, 0xfa, 0x52, 0x10, + 0x78, 0x33, 0x95, 0xa6, 0xec, 0x53, 0x1e, 0x72, 0xe2, 0x91, 0x85, 0x51, 0x96, 0x6f, 0x99, 0xa4, + 0xdb, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x06, 0x3a, 0xb0, 0xdc, 0xac, 0x99, 0xfc, 0xa7, 0x25, 0x91, + 0xff, 0x02, 0x20, 0x74, 0x42, 0x2a, 0x7a, 0x0c, 0x09, 0x7f, 0xbf, 0x91, 0x04, 0x4f, 0x0d, 0xe0, + 0xe9, 0xc9, 0xf2, 0x79, 0x05, 0xbc, 0x3c, 0xb1, 0x5d, 0x4b, 0x07, 0xfc, 0xc4, 0xa6, 0x05, 0x94, + 0x12, 0xf3, 0x70, 0xf6, 0x4a, 0xf1, 0x4c, 0x1f, 0x04, 0xe3, 0x43, 0x14, 0xed, 0x08, 0xaa, 0x75, + 0xe0, 0x9d, 0xb4, 0xe2, 0x3b, 0x03, 0xeb, 0x98, 0x58, 0xd1, 0xf1, 0xc0, 0xf6, 0x1a, 0x1e, 0x71, + 0xc1, 0xf0, 0x7f, 0x03, 0xc1, 0xc3, 0x82, 0xb1, 0xdc, 0x01, 0xc1, 0xd3, 0x82, 0x68, 0x7e, 0x1f, + 0xa1, 0xd1, 0x19, 0xa8, 0x64, 0xc8, 0x03, 0x1b, 0x0f, 0x1d, 0x3b, 0x85, 0xf2, 0x4a, 0x1f, 0xc4, + 0x77, 0x35, 0xc2, 0x0e, 0x3e, 0x44, 0x1b, 0xc9, 0x5b, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x06, 0x0a, + 0xaf, 0xde, 0xcb, 0x94, 0xe0, 0xe7, 0x7a, 0x12, 0x00, 0x00, 0x3b, 0xd0, 0x3d, 0xc1, 0x34, 0x00, + 0x00, 0x25, 0xbc, 0xbe, 0x5e, 0x36, 0xae, 0xc3, 0xf9, 0xb2, 0xec, 0x2f, 0x96, 0x83, 0xd5, 0xaf, + 0xce, 0x9f, 0x73, 0xd2, 0xc1, 0xc4, 0x36, 0x12, 0x01, 0x35, 0xe4, 0x0f, 0x7f, 0x74, 0x91, 0xeb, + 0xec, 0x1c, 0x6e, 0x7d, 0x17, 0x17, 0xd1, 0x8a, 0x02, 0xb0, 0xbb, 0x49, 0x62, 0x7f, 0x96, 0xfd, + 0x74, 0xd9, 0xcf, 0x5b, 0x74, 0x84, 0xc1, 0xb3, 0x3c, 0x70, 0x7c, 0x0f, 0x81, 0xf8, 0x1c, 0x20, + 0xc5, 0xa2, 0x58, 0x94, 0xe3, 0xd8, 0xe3, 0x14, 0xd8, 0x70, 0x08, 0xda, 0x59, 0x77, 0x30, 0x9c, + 0x39, 0x8a, 0x54, 0xce, 0xb1, 0x23, 0x5d, 0x90, 0xbc, 0xe5, 0x2c, 0xb7, 0x25, 0x0f, 0x08, 0x40, + 0xdb, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x16, 0x12, 0xaf, 0xde, 0xcb, 0xe0, 0x87, 0x0d, 0x93, 0x07, + 0x00, 0x04, 0x00, 0x29, 0x9b, 0x99, 0x97, 0x35, 0x52, 0x0d, 0x40, 0x00, 0x00, 0x10, 0x0d, 0x7a, + 0x70, 0x35, 0x2f, 0x80, 0x3c, 0x14, 0xca, 0x10, 0x3f, 0x6a, 0x18, 0x6d, 0x29, 0xa9, 0x72, 0xf6, + 0xbe, 0xd4, 0x19, 0xd1, 0xc4, 0x29, 0x16, 0x24, 0xb3, 0x02, 0xa9, 0x72, 0x9b, 0xe3, 0xe8, 0xdd, + 0x71, 0x5d, 0xb6, 0x83, 0xae, 0x26, 0x28, 0x23, 0xb5, 0x52, 0xad, 0x16, 0x29, 0x84, 0xbf, 0x6a, + 0x3c, 0xae, 0x51, 0x03, 0xe3, 0xe0, 0xf8, 0x3f, 0x07, 0xe1, 0xe6, 0x67, 0xad, 0xc4, 0x79, 0x2e, + 0xfe, 0xc0, 0x72, 0x34, 0xde, 0x5c, 0xc6, 0x5b, 0xc1, 0xcb, 0xb0, 0x38, 0x50, 0x02, 0x89, 0xd4, + 0x18, 0xdf, 0x30, 0x71, 0x56, 0x27, 0xfe, 0x57, 0x5b, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x15, 0xf2, + 0xaf, 0xdd, 0x49, 0xcf, 0xcc, 0xa4, 0x07, 0x3f, 0x00, 0x08, 0xba, 0xea, 0x33, 0x83, 0xf2, 0x1d, + 0x4a, 0xe8, 0x2b, 0x00, 0x26, 0x46, 0xff, 0xc5, 0x59, 0xdc, 0x04, 0x76, 0xc7, 0x1a, 0x70, 0x6c, + 0xb1, 0x71, 0xe6, 0xd7, 0xc3, 0x71, 0xb8, 0x85, 0x8e, 0xf7, 0x24, 0x6f, 0x6d, 0x8b, 0xde, 0x37, + 0xc9, 0x4c, 0x48, 0xd6, 0x0e, 0x2a, 0x29, 0x33, 0x56, 0x9b, 0xcd, 0x28, 0xb4, 0x62, 0x82, 0x9e, + 0x70, 0x2a, 0x16, 0x0e, 0xfb, 0x6c, 0x82, 0x8b, 0x30, 0x71, 0xe1, 0xf8, 0x3f, 0x07, 0xc1, 0xf8, + 0x3b, 0xb8, 0x9b, 0x2f, 0x22, 0x79, 0x7d, 0x71, 0x14, 0x41, 0x6d, 0x70, 0x84, 0x45, 0x44, 0x06, + 0xa4, 0x86, 0xc9, 0x36, 0x7d, 0x80, 0xda, 0xcc, 0xf2, 0xc1, 0x2d, 0x16, 0x31, 0x2e, 0x7a, 0x8e, + 0x5b, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x15, 0xaa, 0xae, 0xec, 0x11, 0x26, 0xb7, 0x2f, 0x3f, 0xb4, + 0xb4, 0x00, 0x6e, 0x1a, 0x2b, 0xc2, 0xbc, 0x22, 0x6e, 0xf3, 0xf2, 0x6b, 0x3d, 0xec, 0x29, 0x95, + 0x53, 0xdd, 0xaa, 0x8c, 0x3d, 0xce, 0x81, 0x97, 0x61, 0x19, 0x2f, 0x5e, 0x13, 0xf1, 0x9c, 0xb6, + 0x3f, 0xcd, 0x77, 0x53, 0xf5, 0x90, 0x47, 0x07, 0xda, 0x9b, 0x63, 0x02, 0x4a, 0x30, 0xff, 0x3a, + 0x76, 0xe8, 0x42, 0x96, 0x6d, 0x1a, 0x64, 0xe4, 0xee, 0x86, 0x6d, 0xeb, 0x05, 0x66, 0x6c, 0xc3, + 0x8f, 0x81, 0xf8, 0x1f, 0x80, 0xfc, 0x1e, 0x07, 0xfe, 0x22, 0xc0, 0x2b, 0x82, 0x22, 0xa5, 0x60, + 0x5e, 0x4f, 0xef, 0x5c, 0x4a, 0xd8, 0x42, 0x5b, 0xca, 0xbc, 0xf0, 0x6b, 0xaa, 0xc3, 0x69, 0x6f, + 0x6b, 0xbe, 0xc8, 0x18, 0x3f, 0x00, 0x19, 0x8d, 0xcb, 0x22, 0x97, 0x17, 0x59, 0x19, 0xd5, 0x8a, + 0xaf, 0xa6, 0xc8, 0x6c, 0x5a, 0x28, 0x8f, 0x78, 0xe5, 0x00, 0x52, 0x7c, 0x34, 0x94, 0xa7, 0x12, + 0x1d, 0x1d, 0x0f, 0x27, 0x84, 0x09, 0xab, 0xd8, 0xc5, 0xf7, 0x69, 0xde, 0xcd, 0xf0, 0xbd, 0x50, + 0xdc, 0x4a, 0x32, 0xc3, 0x92, 0x6c, 0xb5, 0xa8, 0xd2, 0x87, 0x56, 0x5d, 0x57, 0x63, 0x68, 0x13, + 0x24, 0x2f, 0xdd, 0x92, 0x9a, 0xc8, 0x90, 0x83, 0x70, 0x09, 0x77, 0x16, 0xc2, 0x76, 0xb3, 0xe1, + 0xc5, 0xc0, 0x9a, 0x5c, 0x63, 0xe3, 0x9c, 0x3e, 0x1f, 0x07, 0xf0, 0x1f, 0x80, 0xfc, 0x1f, 0x0e, + 0xed, 0x87, 0xf2, 0x17, 0xaf, 0x9d, 0xdc, 0x64, 0x12, 0x56, 0x3e, 0x2c, 0x56, 0xd0, 0xe0, 0x92, + 0x09, 0xd3, 0xc4, 0x6d, 0xca, 0x42, 0x7c, 0x72, 0x29, 0x02, 0xc0, 0x40, 0x04, 0x3f, 0xf6, 0x5f, + 0x5b, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x05, 0x9a, 0xae, 0xec, 0x0f, 0x7b, 0x69, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x41, 0xaf, 0xfc, 0x8a, 0xb4, 0xa6, 0x16, 0xf1, 0x30, 0x4a, 0x32, 0x65, 0x7b, 0xb8, + 0x15, 0x84, 0xe4, 0x15, 0x21, 0x24, 0x8e, 0xdc, 0xbd, 0x52, 0xbf, 0x4d, 0x97, 0x48, 0xff, 0xf2, + 0x35, 0x2f, 0xfc, 0x4c, 0xe2, 0x4b, 0x34, 0x66, 0x4b, 0x5b, 0xcf, 0xbc, 0xa3, 0x22, 0x7b, 0xd7, + 0x8b, 0x5e, 0xc5, 0x3b, 0x1d, 0xca, 0x9b, 0x63, 0x47, 0x36, 0x0c, 0x80, 0x64, 0xec, 0x6d, 0x26, + 0xb8, 0xe3, 0xe3, 0xf0, 0x0f, 0x81, 0xf8, 0x1e, 0x03, 0xbd, 0xe3, 0xe9, 0x7c, 0x73, 0xd5, 0xff, + 0xed, 0x9b, 0xb6, 0xa5, 0xdd, 0x0a, 0xa0, 0x88, 0xf8, 0xad, 0x8f, 0x0a, 0xc5, 0x85, 0x2f, 0x57, + 0x52, 0x60, 0xd9, 0x9f, 0x66, 0xd3, 0x7b, 0xa6, 0xdb, 0x22, 0x97, 0x17, 0x59, 0x19, 0xf5, 0xc2, + 0xaf, 0xde, 0xcb, 0x85, 0xa7, 0x00, 0x00, 0x00, 0x01, 0x55, 0xe8, 0x5f, 0x8a, 0x56, 0xbc, 0x0c, + 0x12, 0x0a, 0x2a, 0x1e, 0xa9, 0xdc, 0x71, 0xef, 0x73, 0xb5, 0x83, 0x0c, 0x00, 0x5a, 0x54, 0xc1, + 0xe2, 0x96, 0x5a, 0xfe, 0xd4, 0x70, 0xb8, 0x8d, 0x0f, 0x9e, 0xdd, 0xad, 0x2d, 0x24, 0x27, 0x8e, + 0xba, 0xe4, 0xfe, 0x43, 0xab, 0x43, 0x7a, 0x80, 0x27, 0x7e, 0x02, 0x55, 0x17, 0x88, 0x51, 0xcb, + 0x8e, 0x29, 0x97, 0x2f, 0x25, 0x2d, 0xd3, 0x54, 0x9e, 0x3c, 0x3e, 0x0f, 0xc0, 0xf8, 0x1f, 0x07, + 0xfc, 0x61, 0x65, 0xc8, 0x2a, 0x81, 0xda, 0x49, 0x4e, 0x23, 0xec, 0x61, 0xb4, 0xb1, 0xb2, 0xf1, + 0x65, 0x61, 0xad, 0x53, 0x22, 0xda, 0x54, 0x33, 0x9b, 0x86, 0xbe, 0x86, 0xb6, 0xa0, 0x06, 0x55, + 0x5b, 0x22, 0x97, 0x17, 0x59, 0x19, 0xe5, 0x9a, 0x69, 0xd4, 0x3b, 0x63, 0x50, 0x77, 0xfb, 0x38, + 0x00, 0x00, 0x14, 0x4a, 0x4e, 0xe5, 0x7e, 0x3d, 0x1b, 0x13, 0x1f, 0x00, 0x28, 0x86, 0x0d, 0x5c, + 0x8f, 0xf8, 0x26, 0xd1, 0x0c, 0xc6, 0x10, 0x54, 0x78, 0xb4, 0xc4, 0xc9, 0x7a, 0xe7, 0xb0, 0xf1, + 0x91, 0xc8, 0x4e, 0x69, 0x0f, 0x4d, 0xd6, 0x43, 0x2b, 0x58, 0x3c, 0x66, 0x06, 0x07, 0x9c, 0x09, + 0xed, 0x1c, 0x1d, 0x0a, 0x74, 0x0d, 0xb6, 0xcf, 0x0e, 0x81, 0x13, 0xdd, 0x35, 0x6b, 0x34, 0x0f, + 0x97, 0xc7, 0x1e, 0x1e, 0x1f, 0x81, 0xf8, 0x3f, 0x07, 0xe1, 0x04, 0xa5, 0xd0, 0xff, 0x03, 0x33, + 0xab, 0xe3, 0xbe, 0xaa, 0x3f, 0xf1, 0x26, 0x29, 0x16, 0x61, 0xf8, 0x67, 0x5e, 0x48, 0x9d, 0x6a, + 0x57, 0x3d, 0xd8, 0xcd, 0x89, 0xe1, 0x97, 0x45, 0xeb, 0x22, 0x97, 0x17, 0x59, 0x39, 0xf5, 0xc2, + 0xae, 0xed, 0x18, 0xc3, 0x35, 0x47, 0xf3, 0x82, 0x00, 0x00, 0x0a, 0x8d, 0xee, 0x0c, 0x3f, 0x00, + 0x00, 0x00, 0x02, 0x78, 0xdb, 0x9b, 0xa0, 0xe1, 0xe2, 0x22, 0xb6, 0x06, 0x3f, 0xbe, 0xc7, 0x5f, + 0x62, 0xb0, 0x15, 0x12, 0xec, 0xcf, 0x7c, 0xf8, 0x92, 0x96, 0x5a, 0x4a, 0xbd, 0xf4, 0xb6, 0xc0, + 0xcd, 0xd6, 0x83, 0x6d, 0xbf, 0x39, 0xae, 0x56, 0x6c, 0xf6, 0x06, 0x1e, 0xe0, 0xe8, 0x78, 0xa1, + 0x50, 0x9b, 0x7f, 0xba, 0xa0, 0xc7, 0xed, 0xfa, 0x03, 0xa9, 0x0c, 0x7c, 0xf8, 0x7c, 0x1f, 0x03, + 0xf0, 0x7e, 0x1e, 0x03, 0x0b, 0x87, 0xe4, 0x16, 0x30, 0x8f, 0x2f, 0xf4, 0x6d, 0x82, 0xd1, 0x5e, + 0xd9, 0x3a, 0xe5, 0x38, 0x99, 0x56, 0xe7, 0x76, 0x89, 0x6c, 0x8c, 0x0a, 0x4c, 0xf1, 0x9f, 0x8e, + 0xcb, 0x23, 0x63, 0x97, 0x59, 0x19, 0xe6, 0x32, 0xaf, 0xe4, 0xc5, 0x79, 0xc2, 0x5a, 0xff, 0x30, + 0x6b, 0x09, 0x2f, 0xdb, 0x49, 0x80, 0xa7, 0xdc, 0xb8, 0x00, 0x00, 0x00, 0x0a, 0xb2, 0x5f, 0x67, + 0x82, 0x1a, 0x72, 0xdf, 0xfc, 0x95, 0xe3, 0xa4, 0xcf, 0xa3, 0x4e, 0x2b, 0x05, 0x71, 0x98, 0x3b, + 0x08, 0xcc, 0xd8, 0xe0, 0xa3, 0x34, 0xf9, 0xa9, 0xfd, 0xeb, 0xea, 0xfc, 0x18, 0xb7, 0x98, 0x1a, + 0x74, 0x61, 0xb8, 0xc6, 0xf9, 0x99, 0x25, 0x7d, 0x6b, 0xfd, 0xbf, 0x91, 0x58, 0xef, 0x0d, 0x14, + 0xce, 0x61, 0xc0, 0xfe, 0x07, 0xc0, 0xf8, 0x3e, 0x1f, 0xc8, 0xa0, 0x38, 0x93, 0x48, 0x9e, 0x2f, + 0x32, 0x57, 0x4f, 0x26, 0x9f, 0x8e, 0x99, 0xe5, 0x02, 0xa4, 0x48, 0x5a, 0x3d, 0xf7, 0xe5, 0x54, + 0x79, 0x3b, 0xae, 0xcf, 0x6c, 0x5d, 0x20, 0x8a, 0x5b, 0x23, 0x63, 0x97, 0x59, 0x1a, 0x06, 0x0a, + 0xaf, 0x07, 0x59, 0x7c, 0x19, 0x03, 0xa9, 0x3c, 0x00, 0x14, 0x24, 0x32, 0xde, 0x23, 0x1e, 0x64, + 0x00, 0x00, 0x00, 0x02, 0x78, 0x2b, 0x20, 0xce, 0x2f, 0x68, 0xf5, 0xbf, 0x05, 0xeb, 0x26, 0x55, + 0x29, 0x53, 0x4c, 0x7e, 0x61, 0xf9, 0xad, 0x8f, 0xc2, 0x8a, 0x41, 0x34, 0x8d, 0xc9, 0x28, 0xc6, + 0xf8, 0x8b, 0x08, 0xa3, 0xd4, 0x35, 0x7a, 0x7e, 0x53, 0xa0, 0x52, 0x5d, 0x56, 0xd6, 0xd1, 0xdf, + 0xc9, 0xc4, 0x58, 0x68, 0x78, 0x86, 0xf0, 0xa8, 0x62, 0x31, 0x98, 0xf0, 0xe0, 0xf8, 0x3c, 0x1f, + 0x87, 0x8f, 0x00, 0x18, 0x31, 0x02, 0x8c, 0x85, 0xa0, 0xa6, 0x11, 0x2b, 0x61, 0x36, 0xdf, 0x97, + 0xc1, 0x2b, 0x02, 0xba, 0xad, 0xc2, 0x2b, 0xd3, 0x85, 0xe4, 0x28, 0x75, 0xaa, 0xa9, 0x20, 0x72, + 0x5b, 0x23, 0x63, 0x97, 0x59, 0x1a, 0x16, 0x32, 0xaf, 0xde, 0xcb, 0xe0, 0xab, 0x2b, 0xe8, 0xed, + 0x50, 0xe3, 0x86, 0x47, 0xe5, 0x26, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x4f, 0xb5, 0xa6, + 0x0f, 0x22, 0x99, 0x27, 0x10, 0x6e, 0x3f, 0x2c, 0x8c, 0xa3, 0x70, 0xa0, 0x31, 0x5f, 0xec, 0xd2, + 0x6b, 0x19, 0x59, 0x24, 0x59, 0x31, 0xe6, 0x5c, 0x7b, 0x58, 0x91, 0xf2, 0x1f, 0xe5, 0xef, 0xe1, + 0x69, 0x7c, 0x89, 0x15, 0xd6, 0xf0, 0x90, 0x04, 0xf1, 0x1f, 0x4b, 0x6f, 0xd6, 0x20, 0x0e, 0x9b, + 0xf5, 0xb2, 0x26, 0xce, 0x3c, 0x78, 0xf0, 0x7c, 0x1f, 0x81, 0xf8, 0x1e, 0x0c, 0xc3, 0xb7, 0xec, + 0xcd, 0x3f, 0xa9, 0x4d, 0x80, 0x23, 0x7a, 0x9c, 0x52, 0xec, 0x07, 0xb9, 0xcf, 0x14, 0xfe, 0x1d, + 0x31, 0xaf, 0x97, 0xd8, 0x3c, 0xb4, 0xfc, 0x09, 0xdb, 0x23, 0x63, 0x97, 0x59, 0x1a, 0x16, 0x0a, + 0xaf, 0xde, 0xcb, 0xe0, 0x85, 0xa8, 0x27, 0x59, 0x00, 0x01, 0xbf, 0x14, 0x21, 0x94, 0xb6, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4a, 0xbe, 0xff, 0x68, 0x3f, 0x33, 0x88, 0xc8, 0xea, 0x78, 0x68, 0x02, + 0x5d, 0x09, 0x28, 0x00, 0x6d, 0x52, 0x33, 0xaf, 0x64, 0x95, 0x5e, 0xa3, 0xed, 0x4c, 0x68, 0x8f, + 0xef, 0x24, 0x88, 0x45, 0xa1, 0x68, 0x3a, 0x1f, 0x25, 0x2d, 0xe7, 0x52, 0x34, 0xd4, 0x24, 0x55, + 0x52, 0x60, 0x48, 0x63, 0xe2, 0x23, 0x1a, 0xca, 0xce, 0x20, 0xc3, 0x87, 0xc1, 0xf8, 0x7c, 0x0f, + 0x06, 0x07, 0x73, 0x81, 0xec, 0x4e, 0x4d, 0x9d, 0x5d, 0x11, 0xfe, 0xf0, 0x4f, 0x32, 0xa4, 0x6e, + 0xc9, 0xf9, 0x47, 0x2a, 0x54, 0x86, 0x1b, 0xa0, 0xa8, 0x64, 0x9e, 0x07, 0x08, 0x36, 0x1b, 0x8c, + 0xdb, 0x23, 0x63, 0x97, 0x59, 0x1a, 0x26, 0x32, 0xae, 0xec, 0x0f, 0x7b, 0x69, 0x00, 0x00, 0x00, + 0x0b, 0x2e, 0x68, 0x94, 0x87, 0x37, 0x64, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xa8, 0xb0, 0x06, + 0x83, 0x1b, 0x2d, 0x62, 0x14, 0xb3, 0x22, 0xb6, 0x22, 0xa3, 0xf7, 0xbe, 0xd0, 0x7c, 0x75, 0xff, + 0x33, 0xcb, 0x97, 0x1d, 0xd4, 0x6e, 0x8d, 0x22, 0xfc, 0xe0, 0x98, 0xba, 0x9a, 0x65, 0x82, 0x5c, + 0x37, 0xe7, 0xd3, 0xa9, 0xdf, 0x0d, 0x69, 0xaa, 0x27, 0xfa, 0x1d, 0x2c, 0x08, 0x75, 0x0c, 0x7b, + 0x01, 0xee, 0x19, 0xe7, 0x0f, 0x87, 0xc1, 0xf8, 0x1f, 0x0f, 0xe6, 0x7d, 0xeb, 0x69, 0xbb, 0xa6, + 0x5f, 0x9f, 0x6a, 0xb2, 0xba, 0xac, 0x84, 0x14, 0xde, 0xe9, 0x6e, 0xd4, 0x31, 0x9a, 0xf3, 0x32, + 0x22, 0xa5, 0xe2, 0xf6, 0x3e, 0x75, 0xe8, 0x4d, 0x4b, 0x23, 0x63, 0x97, 0x59, 0x19, 0xe5, 0xa2, + 0xb0, 0xdc, 0xac, 0x9f, 0x4f, 0x3a, 0xa2, 0xc7, 0x00, 0x02, 0x30, 0x4e, 0x88, 0x25, 0x1c, 0x25, + 0xa7, 0x3a, 0x72, 0xc3, 0xf3, 0x65, 0xb3, 0x05, 0x32, 0x8d, 0x45, 0x6f, 0xba, 0x21, 0x22, 0xb1, + 0x50, 0xd3, 0xf2, 0x53, 0x0e, 0xba, 0xd5, 0x99, 0x07, 0xfb, 0x5b, 0x93, 0x74, 0x90, 0x08, 0xcc, + 0xd2, 0xd9, 0xd4, 0x91, 0x5f, 0x96, 0xef, 0xcd, 0x06, 0xcf, 0x04, 0x0e, 0xa1, 0x73, 0x54, 0xa3, + 0xdc, 0x55, 0xd4, 0xe3, 0xc8, 0xb9, 0xab, 0xb7, 0xf3, 0x38, 0x1d, 0xb3, 0x34, 0x63, 0xe1, 0xf0, + 0x7c, 0x18, 0x3f, 0x6f, 0xe2, 0xc6, 0x1c, 0xbc, 0xca, 0xbb, 0x19, 0x8e, 0x89, 0x8a, 0x83, 0xfa, + 0x2b, 0xac, 0x1e, 0x7f, 0xc1, 0x06, 0x99, 0x54, 0x84, 0x06, 0x90, 0x3e, 0x9e, 0x17, 0xfe, 0x07, + 0xcb, 0x59, 0x68, 0x27, 0x59, 0x1a, 0x26, 0x3a, 0xaf, 0xdd, 0x47, 0xaf, 0x45, 0x72, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xa8, 0x00, 0x00, 0x84, 0xa0, 0x2f, 0xbe, 0x6a, 0xff, + 0x0b, 0xd8, 0xf2, 0x6f, 0x0a, 0x4d, 0x8b, 0xd4, 0xce, 0x90, 0xa5, 0xbe, 0xcd, 0x84, 0x89, 0xc6, + 0xaa, 0xc2, 0xd7, 0xe0, 0xfc, 0xf4, 0x44, 0xb5, 0x78, 0x7e, 0xd7, 0xdb, 0x9e, 0x7e, 0x18, 0x40, + 0xcf, 0x2a, 0xa8, 0x93, 0xa4, 0x57, 0xc8, 0x26, 0xec, 0x8a, 0x1e, 0xb2, 0x61, 0x89, 0xf2, 0xca, + 0xef, 0xdc, 0x63, 0xc3, 0xe1, 0xf8, 0x0f, 0xc1, 0xe3, 0xe1, 0xbd, 0xd3, 0xfc, 0xee, 0x01, 0x57, + 0xce, 0xa2, 0x20, 0x72, 0xac, 0x90, 0xd7, 0xa3, 0xef, 0x4d, 0x93, 0x3d, 0x65, 0xaa, 0x03, 0xb8, + 0xbd, 0x28, 0x81, 0xa4, 0xcd, 0x81, 0x22, 0x7f, 0xdb, 0x59, 0x68, 0x27, 0x59, 0x1a, 0x06, 0x1a, + 0xb6, 0xaf, 0xa6, 0xa4, 0x0f, 0xc8, 0x00, 0x00, 0x00, 0x8e, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x1f, + 0x89, 0x3f, 0x1e, 0xe4, 0xbd, 0x9e, 0x69, 0xe4, 0xc8, 0x3f, 0xa1, 0x01, 0x8b, 0x3c, 0xd4, 0x7b, + 0xa3, 0x0a, 0x2b, 0xac, 0x9c, 0x76, 0x1a, 0x93, 0x9f, 0x3e, 0xe8, 0x3a, 0x5c, 0x1c, 0x61, 0x84, + 0xe2, 0xe5, 0x2a, 0xb2, 0x1c, 0x19, 0x45, 0x8c, 0xe1, 0x2b, 0x4f, 0xde, 0xc3, 0xfd, 0x59, 0x25, + 0x92, 0x59, 0xc8, 0xef, 0x02, 0xff, 0x86, 0xd5, 0x7e, 0x61, 0x71, 0x9c, 0x3e, 0x1f, 0x07, 0xe0, + 0x7e, 0x1c, 0x61, 0xc4, 0xe7, 0xf9, 0x13, 0xe5, 0x97, 0x8c, 0x19, 0xcf, 0x4b, 0xdd, 0xca, 0xa0, + 0x45, 0xc7, 0x42, 0x81, 0x85, 0xdb, 0x2c, 0x7b, 0x2c, 0x93, 0x4d, 0xbe, 0x0f, 0xab, 0x60, 0x66, + 0x5b, 0x59, 0x68, 0x27, 0x59, 0x1a, 0x05, 0xfa, 0x69, 0x22, 0xde, 0xdd, 0xd2, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0xcd, 0x03, 0xa3, 0x66, 0x74, 0x51, 0x0c, 0xfd, + 0x96, 0x0e, 0xc4, 0xa1, 0xa5, 0x02, 0x16, 0x3e, 0x54, 0xdc, 0x7b, 0xbf, 0xd1, 0x7f, 0x34, 0xe2, + 0xfc, 0x41, 0x33, 0xf9, 0xe8, 0x4c, 0x0a, 0x66, 0xfb, 0x40, 0x24, 0xd7, 0x1a, 0x5e, 0x80, 0xa4, + 0xa8, 0x60, 0x8b, 0x47, 0x99, 0xd3, 0xa4, 0x7c, 0x01, 0x58, 0x1a, 0x51, 0x8b, 0x43, 0xba, 0xb4, + 0x0a, 0x01, 0x31, 0x8f, 0x0f, 0x0f, 0xc0, 0xf8, 0x1f, 0x87, 0x9f, 0x0e, 0x62, 0x3d, 0xe5, 0x1b, + 0x23, 0x29, 0x1b, 0x32, 0x0d, 0x49, 0xc9, 0x8c, 0x2a, 0x31, 0x17, 0x14, 0x1d, 0x7b, 0x26, 0x54, + 0x07, 0x46, 0xb5, 0x00, 0x2f, 0x97, 0x96, 0x00, 0x5b, 0x59, 0x68, 0x27, 0x59, 0x19, 0xf6, 0x32, + 0xaf, 0xdd, 0x4a, 0x8e, 0x8a, 0x00, 0x00, 0x04, 0x16, 0x72, 0x00, 0x00, 0x00, 0x01, 0x3c, 0x65, + 0x00, 0x00, 0x06, 0xc2, 0x8d, 0x61, 0x32, 0xec, 0x63, 0x9f, 0xd5, 0x3b, 0x41, 0x19, 0x48, 0x92, + 0x5b, 0x79, 0xdf, 0x4e, 0xe0, 0x56, 0xab, 0x10, 0xad, 0xb6, 0x70, 0x26, 0xd8, 0x3b, 0x04, 0x1a, + 0x26, 0x3f, 0x1e, 0xfb, 0x61, 0x9b, 0x2c, 0xcd, 0xc3, 0x1a, 0x45, 0xbe, 0x86, 0xb5, 0x80, 0xbf, + 0x58, 0xe5, 0xf1, 0xc4, 0xfa, 0x70, 0xc3, 0x28, 0xe1, 0x66, 0xe6, 0x3e, 0x1f, 0x1f, 0x1f, 0x07, + 0xc1, 0x86, 0x07, 0x3f, 0x01, 0x4a, 0x24, 0x08, 0xb1, 0x9d, 0x34, 0x0f, 0xd4, 0x9a, 0x67, 0xa5, + 0x2c, 0x41, 0xcc, 0xd6, 0xb1, 0x4d, 0xb6, 0x30, 0x9e, 0x87, 0x1b, 0x81, 0x9b, 0x8a, 0x1b, 0x1f, + 0xdb, 0x59, 0x68, 0x27, 0x59, 0x1a, 0x06, 0x2a, 0x69, 0xab, 0xe1, 0x95, 0x02, 0xf7, 0x56, 0xf1, + 0x00, 0x00, 0x6f, 0x0a, 0x1d, 0x00, 0x00, 0x00, 0x85, 0x49, 0x3a, 0xc8, 0xa2, 0xa7, 0xd2, 0x5a, + 0xa9, 0xdf, 0xe8, 0x8c, 0x63, 0x9f, 0xa4, 0x30, 0xad, 0x60, 0xc9, 0xeb, 0x68, 0x08, 0x85, 0xc7, + 0x58, 0x80, 0x08, 0xa1, 0xb6, 0x36, 0xd8, 0xe9, 0x6a, 0x7b, 0x0b, 0xc1, 0xd6, 0x5e, 0x3f, 0x82, + 0x55, 0x55, 0x9c, 0x24, 0x89, 0x0d, 0x17, 0xf5, 0x4e, 0xf7, 0x62, 0x1a, 0x50, 0xb6, 0x11, 0xe5, + 0x96, 0xa1, 0xea, 0xc7, 0xf3, 0xc7, 0x87, 0xc3, 0xe0, 0xf8, 0x3e, 0x0f, 0x1f, 0x71, 0x01, 0x0a, + 0x69, 0x82, 0xa7, 0xe9, 0x15, 0xa2, 0xb7, 0xd0, 0x26, 0x0c, 0x4d, 0x9f, 0xd9, 0x37, 0x1f, 0x09, + 0x3f, 0x68, 0x19, 0xcc, 0xf5, 0xec, 0x70, 0x2b, 0x4b, 0x59, 0x68, 0x27, 0x59, 0x19, 0xe6, 0x3a, + 0xaf, 0xa6, 0xc8, 0x17, 0x7f, 0x00, 0x00, 0x00, 0x17, 0x06, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x90, 0x4d, 0x7e, 0x2d, 0x3b, 0x28, 0x83, 0xe1, 0x07, 0x76, 0x76, 0xcf, 0xba, 0x15, 0x34, + 0xb2, 0x39, 0x94, 0xdb, 0x89, 0xe9, 0x6d, 0x1a, 0xaf, 0xd6, 0x16, 0xa8, 0x64, 0x82, 0xb0, 0x29, + 0x5e, 0x24, 0xdd, 0x6b, 0x36, 0x83, 0xba, 0x3a, 0xf6, 0x36, 0x7a, 0x39, 0xd7, 0x81, 0xb2, 0x27, + 0xaf, 0x4c, 0x76, 0xc9, 0x2d, 0x17, 0x4c, 0x66, 0x99, 0x8d, 0x36, 0x38, 0xf0, 0xf8, 0x1f, 0x83, + 0xe1, 0xe0, 0xf8, 0x50, 0x30, 0xfe, 0x6c, 0x6f, 0x1c, 0x5a, 0x7b, 0x2e, 0x88, 0x59, 0x3b, 0xec, + 0xca, 0xde, 0x54, 0x84, 0xc2, 0x74, 0xc8, 0xa9, 0x40, 0x21, 0x70, 0x1d, 0x4f, 0xb4, 0xea, 0x06, + 0xcb, 0x59, 0x68, 0x27, 0x59, 0x19, 0xf6, 0x0a, 0xaf, 0xdd, 0x47, 0xae, 0x79, 0x00, 0x1f, 0x83, + 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0xdb, 0x11, 0x71, 0xcf, 0xbd, + 0x91, 0x1c, 0x8e, 0xc5, 0x83, 0xc4, 0xe6, 0x94, 0xef, 0x6e, 0x0e, 0x9e, 0x6a, 0x42, 0xa9, 0x2a, + 0x2a, 0xd0, 0x12, 0xae, 0x29, 0x75, 0xa5, 0xbf, 0xd1, 0xa3, 0x08, 0x7e, 0xee, 0xfc, 0xaa, 0x6b, + 0x9e, 0xfa, 0x66, 0x0f, 0x9d, 0xef, 0x40, 0x26, 0xe0, 0x10, 0x37, 0x20, 0x7b, 0x47, 0x23, 0xa4, + 0x2a, 0xb7, 0x61, 0xc7, 0x0f, 0x0f, 0x83, 0xe0, 0x7c, 0x0f, 0x83, 0xc0, 0xfd, 0xbe, 0xb6, 0xff, + 0xfa, 0x50, 0x5b, 0x22, 0x16, 0xc5, 0x40, 0x94, 0x44, 0x34, 0x24, 0x3b, 0xc8, 0xa3, 0x46, 0x42, + 0xa9, 0xf3, 0xb0, 0x22, 0x4b, 0xa8, 0x02, 0x1d, 0x4b, 0x59, 0x68, 0x27, 0x59, 0x19, 0xe6, 0x22, + 0xaf, 0xdd, 0x47, 0x5c, 0xb0, 0x00, 0x00, 0x00, 0x09, 0xa7, 0x33, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x51, 0x3a, 0x47, 0x73, 0x14, 0xdc, 0x14, 0x55, 0x01, 0xad, 0xc9, 0x84, 0xf5, 0x04, 0xca, + 0x57, 0xf3, 0x4d, 0xa5, 0x4e, 0x52, 0x7c, 0x3c, 0xb4, 0xac, 0x71, 0xe4, 0x05, 0x1f, 0x32, 0xd5, + 0x66, 0xee, 0x2e, 0x65, 0x11, 0x2b, 0xf8, 0x17, 0x9f, 0x1c, 0x31, 0xc1, 0x45, 0x92, 0xf7, 0xec, + 0x52, 0x11, 0xaf, 0xf8, 0x38, 0xe2, 0x4f, 0x46, 0x0e, 0xa7, 0x7d, 0x8c, 0x61, 0xe0, 0xf0, 0x1e, + 0x1f, 0x1f, 0x80, 0x20, 0x74, 0x20, 0x33, 0xd0, 0x97, 0xf4, 0x65, 0xe5, 0x0f, 0x72, 0x9a, 0xf8, + 0x6a, 0x30, 0x93, 0x48, 0x44, 0x87, 0x45, 0x57, 0x15, 0x89, 0x56, 0xf2, 0x61, 0x92, 0xcb, 0x2f, + 0x5b, 0x59, 0x68, 0x27, 0x59, 0x19, 0xe6, 0x3a, 0xb0, 0xdc, 0x57, 0x1e, 0x7c, 0x00, 0x00, 0x3f, + 0x74, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x39, 0xc0, 0xa6, 0x1f, 0xdd, 0xdd, 0xf7, + 0x8b, 0x46, 0x51, 0xe9, 0xbf, 0x18, 0x60, 0x29, 0x50, 0x4f, 0x93, 0x93, 0xcd, 0x14, 0x7b, 0x2a, + 0x53, 0x8f, 0xca, 0x5a, 0xa7, 0xe9, 0xb6, 0xb2, 0xa0, 0x81, 0x52, 0x7a, 0x5d, 0x89, 0xfd, 0xde, + 0x59, 0x8a, 0x16, 0xa5, 0xe5, 0x2c, 0x17, 0xb3, 0x89, 0xde, 0x88, 0x0c, 0xd6, 0xbe, 0x89, 0x47, + 0xdd, 0x4d, 0x03, 0xe0, 0x70, 0xf8, 0xf8, 0x7c, 0x3c, 0x78, 0xf7, 0x83, 0xda, 0x69, 0x3e, 0x11, + 0xbc, 0x3f, 0x2e, 0x0e, 0x4e, 0x55, 0x11, 0xdd, 0x4a, 0xd8, 0xd2, 0xbc, 0xe0, 0x9e, 0x70, 0xf9, + 0x06, 0x5c, 0x0d, 0xe9, 0x1a, 0x5c, 0x8a, 0xfd, 0x5b, 0x53, 0xe8, 0xa7, 0x59, 0x1a, 0x36, 0x3a, + 0xb6, 0xae, 0x86, 0x8b, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaf, 0x71, 0xb2, 0x01, 0x10, 0x2f, 0x58, 0xa8, 0xda, 0xb2, 0x6b, 0xea, 0x17, 0x82, 0x2a, 0xbc, + 0x17, 0x6c, 0xb8, 0xd7, 0x60, 0xec, 0xac, 0x27, 0x51, 0x63, 0xbd, 0x84, 0xe8, 0x16, 0x96, 0xd8, + 0x10, 0x67, 0xce, 0x90, 0xe4, 0x82, 0x54, 0x9c, 0xab, 0x44, 0x53, 0x78, 0x5c, 0xb3, 0x3e, 0x1f, + 0xf6, 0x95, 0x2a, 0x8a, 0x8f, 0xed, 0x7d, 0x66, 0x2a, 0xf5, 0xb8, 0xe3, 0xe1, 0xc7, 0xc7, 0x1f, + 0x1e, 0x1e, 0x38, 0xfe, 0x01, 0x07, 0x40, 0x10, 0x17, 0x93, 0xba, 0x8e, 0x86, 0xb0, 0x0f, 0x29, + 0x1f, 0xd8, 0x67, 0x5b, 0x07, 0xb3, 0x8b, 0x89, 0x4e, 0xbe, 0xde, 0xc6, 0xad, 0xf3, 0x18, 0x25, + 0xdb, 0x53, 0xe8, 0xa7, 0x59, 0x19, 0xf6, 0x3a, 0x69, 0xd4, 0x3d, 0x80, 0x5f, 0x44, 0xf0, 0x1b, + 0x03, 0x78, 0x03, 0xdd, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x9c, 0x1f, 0xba, 0x9f, 0x49, 0x68, + 0x95, 0xbb, 0xa2, 0x6e, 0x80, 0xcc, 0x35, 0xdc, 0xff, 0xc9, 0x1f, 0x10, 0x2c, 0xdc, 0x79, 0x16, + 0x99, 0xef, 0xf3, 0xd4, 0x9a, 0x9a, 0x00, 0x44, 0x82, 0x10, 0x10, 0x24, 0x3a, 0xd1, 0x86, 0x0e, + 0x4b, 0xa7, 0xb0, 0x31, 0x0d, 0xbb, 0x79, 0xd0, 0xc0, 0xe9, 0x30, 0xf2, 0x9f, 0xcc, 0x2a, 0x67, + 0xad, 0xec, 0x1e, 0x0f, 0x81, 0xf1, 0xf8, 0x7c, 0x1c, 0x3c, 0x1e, 0x1f, 0x1c, 0x00, 0x02, 0x87, + 0x80, 0xd1, 0x3c, 0xd8, 0x47, 0xbf, 0xc9, 0xec, 0x76, 0x76, 0xe5, 0xcd, 0x14, 0x99, 0x89, 0xe5, + 0x7a, 0xd2, 0x9b, 0x22, 0xc2, 0xc2, 0x13, 0xc3, 0x4b, 0x53, 0xe8, 0xa7, 0x59, 0x19, 0xe6, 0x32, + 0xaf, 0xa6, 0xca, 0x13, 0x93, 0x00, 0xeb, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x80, 0x9d, 0xf7, 0xc3, 0x46, 0x0b, 0x53, 0x53, 0x73, 0x89, 0xc2, 0x97, 0x55, + 0x72, 0x5c, 0xff, 0x9a, 0xdc, 0x02, 0xf7, 0xf0, 0xcf, 0x21, 0x75, 0x66, 0xe6, 0x6c, 0x3b, 0xba, + 0x79, 0x7c, 0xcc, 0x09, 0x13, 0xba, 0xb1, 0x7e, 0x92, 0x48, 0x08, 0xfb, 0xcc, 0x16, 0xb3, 0xbf, + 0x95, 0x42, 0x12, 0x23, 0x7b, 0x8b, 0xc4, 0xa1, 0xe7, 0x05, 0x3f, 0xc7, 0x86, 0x1c, 0x3c, 0x7e, + 0x1f, 0x0f, 0x0f, 0x0c, 0x0f, 0x37, 0xcb, 0xcd, 0x3b, 0x4b, 0x74, 0x4e, 0xa6, 0x1f, 0x4b, 0x8a, + 0x9e, 0xfb, 0x19, 0x56, 0xfd, 0xc8, 0x31, 0x86, 0x38, 0xf0, 0x61, 0xef, 0x30, 0x56, 0x57, 0xb9, + 0xcb, 0x53, 0xe8, 0xa7, 0x59, 0x19, 0xf6, 0x3a, 0xaf, 0xa6, 0xc8, 0x17, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x62, 0x75, 0x00, 0x00, 0x69, 0x8c, 0xb5, 0x9f, 0x6d, 0x91, 0x16, 0xec, 0x45, 0x2d, + 0xd7, 0x21, 0x0a, 0xd3, 0x74, 0x15, 0x95, 0x67, 0x89, 0x8f, 0xb7, 0x07, 0x97, 0xb4, 0x98, 0x68, + 0x61, 0xec, 0x05, 0xc5, 0x91, 0x0b, 0x6f, 0x0f, 0xd6, 0x08, 0xbf, 0x6d, 0x57, 0x68, 0xb3, 0x3e, + 0xd6, 0x22, 0x91, 0x89, 0x3d, 0xd3, 0xcf, 0x0f, 0x02, 0x68, 0x0c, 0xc5, 0xd9, 0x61, 0xb5, 0x6c, + 0xa3, 0x68, 0x38, 0xc3, 0xc3, 0x83, 0xe7, 0x83, 0xc3, 0x8c, 0x1d, 0xc9, 0xc7, 0x32, 0x2b, 0x70, + 0x8e, 0x87, 0x12, 0x53, 0x43, 0x41, 0x24, 0xe9, 0x59, 0x03, 0xa3, 0xc4, 0x4b, 0xf9, 0x63, 0xd3, + 0x86, 0x6f, 0x28, 0x60, 0xe1, 0x17, 0xdb, 0x42, 0x0b, 0x53, 0xe8, 0xa7, 0x59, 0x3a, 0x16, 0x0a, + 0xae, 0xec, 0x11, 0x26, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x40, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xbc, 0x19, 0x14, 0x6e, 0x12, 0xa1, 0x3a, 0xba, 0x04, 0x5e, 0xea, 0x69, 0x8d, + 0xb1, 0x09, 0xf8, 0xfb, 0x64, 0x6a, 0x78, 0x8d, 0x47, 0x40, 0x96, 0x40, 0xa1, 0x65, 0x8c, 0x09, + 0x2a, 0xa1, 0x36, 0x57, 0x11, 0x6e, 0x99, 0x4b, 0x31, 0x58, 0x23, 0x85, 0x8e, 0x38, 0x0f, 0x57, + 0x47, 0xee, 0x44, 0x32, 0x6f, 0x04, 0x5c, 0xbf, 0xd2, 0xf1, 0xf8, 0x3e, 0x1f, 0x03, 0x87, 0x1e, + 0x1f, 0x07, 0x83, 0x8e, 0x1f, 0xfe, 0xe2, 0x0b, 0xe9, 0x36, 0x03, 0xae, 0x74, 0xa7, 0x7f, 0x11, + 0x66, 0xc6, 0x9a, 0xe9, 0xdc, 0x9c, 0x99, 0xba, 0xd6, 0x42, 0xb8, 0x3a, 0x9e, 0x95, 0xee, 0x41, + 0xcb, 0x53, 0xe8, 0xa7, 0x59, 0x19, 0xf6, 0x3a, 0xb0, 0xd2, 0xbf, 0x90, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x01, 0x4f, 0x00, 0x03, 0x1f, 0x9c, 0x00, 0x00, 0x00, 0x24, 0x0d, 0x60, 0x8b, 0x80, + 0x3b, 0x7a, 0x02, 0x8e, 0xea, 0x5e, 0xa6, 0xc9, 0x36, 0x07, 0xac, 0xae, 0x7e, 0x91, 0xd7, 0x6e, + 0xdc, 0xa1, 0x54, 0xc9, 0x75, 0x9c, 0xce, 0x7d, 0x7d, 0x04, 0xc1, 0xd1, 0x71, 0x1c, 0xbf, 0x8c, + 0x27, 0xb8, 0x20, 0xc9, 0xba, 0xa3, 0x8f, 0xfa, 0x44, 0xc3, 0x2f, 0x0a, 0xb3, 0x56, 0xa0, 0xab, + 0x6e, 0x1f, 0xc7, 0x8e, 0x3e, 0x1e, 0xf8, 0xf0, 0xf8, 0x78, 0x70, 0x0f, 0xfe, 0x78, 0x15, 0xb8, + 0xcf, 0x1d, 0xb9, 0x69, 0x24, 0x7a, 0x50, 0x85, 0x62, 0x26, 0xf7, 0x93, 0x2b, 0x00, 0x75, 0x4f, + 0x16, 0xdc, 0x23, 0x06, 0x99, 0xb0, 0x06, 0x1f, 0xdb, 0x53, 0xe8, 0xa7, 0x59, 0x1a, 0x06, 0x32, + 0xaf, 0xde, 0xcb, 0x94, 0xcb, 0x00, 0x12, 0x26, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0xc0, 0x55, 0xea, 0xd5, 0x22, 0xd8, 0x60, 0xe5, 0xa1, 0xab, 0x14, 0x67, + 0x2f, 0x34, 0x1c, 0x63, 0x68, 0xe1, 0x58, 0x09, 0x83, 0x4d, 0x6d, 0x27, 0xaa, 0xa9, 0x2a, 0x23, + 0x93, 0xea, 0x4e, 0x52, 0x55, 0xd3, 0x9e, 0x04, 0xf0, 0x69, 0xa2, 0x55, 0xa1, 0x20, 0x84, 0xe8, + 0xed, 0x95, 0x73, 0x9a, 0x67, 0x25, 0x84, 0xc8, 0x8e, 0x7e, 0x0f, 0x83, 0xf0, 0x78, 0xf0, 0xf3, + 0xc3, 0xc7, 0x04, 0x1d, 0x3a, 0xbf, 0xfe, 0xcd, 0xd6, 0x67, 0xb0, 0xfb, 0x4b, 0x60, 0x83, 0x17, + 0x32, 0x8f, 0x84, 0xcb, 0xf4, 0xe2, 0xec, 0x57, 0xe9, 0xf4, 0xd9, 0x00, 0x50, 0x34, 0xc4, 0x8f, + 0xeb, 0x53, 0xe8, 0xa7, 0x59, 0x1a, 0x26, 0x32, 0xae, 0xec, 0x11, 0x27, 0x19, 0xd0, 0x62, 0x4b, + 0x9f, 0x92, 0x14, 0xbc, 0x07, 0x1c, 0xcd, 0x60, 0x00, 0x3f, 0x57, 0x72, 0x78, 0xb6, 0x2b, 0xb9, + 0x23, 0xf9, 0xf4, 0x88, 0x94, 0xe5, 0xdd, 0x61, 0xef, 0x21, 0x28, 0x38, 0x79, 0x91, 0x0a, 0xcb, + 0x97, 0xa2, 0x5d, 0xa7, 0x18, 0x3b, 0x3a, 0x52, 0xac, 0xfe, 0xc5, 0x69, 0x48, 0x07, 0xf0, 0xa5, + 0xf4, 0x06, 0xed, 0xbb, 0x6c, 0x5a, 0xae, 0x56, 0x4b, 0x1e, 0xf1, 0x21, 0xc2, 0xf6, 0xb5, 0xc8, + 0xfa, 0x2f, 0xa3, 0x9c, 0xe1, 0xe3, 0xe7, 0xb0, 0xb1, 0x50, 0xdc, 0xe2, 0x49, 0x0b, 0x91, 0x08, + 0xdc, 0x4d, 0x8b, 0xf2, 0xb8, 0x83, 0xcc, 0x45, 0x26, 0xb3, 0xc9, 0x08, 0x1c, 0x71, 0xe9, 0x75, + 0xff, 0x16, 0x10, 0x2e, 0x83, 0x32, 0x45, 0xc4, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0xa5, 0xca, + 0x69, 0x22, 0x06, 0xbe, 0xb8, 0x00, 0x00, 0x55, 0x5b, 0xef, 0x00, 0x00, 0x00, 0x65, 0x5b, 0x53, + 0x00, 0x00, 0x00, 0x01, 0xe4, 0x3c, 0x66, 0x44, 0xb7, 0x31, 0x12, 0x8e, 0xf8, 0x46, 0x36, 0x48, + 0xa3, 0x84, 0xae, 0x9a, 0xde, 0xcf, 0xbe, 0x67, 0xa1, 0x24, 0x81, 0xa9, 0x4c, 0xfd, 0x11, 0x1a, + 0xca, 0xbb, 0x75, 0x5e, 0x95, 0x2b, 0xda, 0xc3, 0xd6, 0x2e, 0x7c, 0xc1, 0x9a, 0x98, 0x7a, 0xf9, + 0xe6, 0xb3, 0x4d, 0x7e, 0x50, 0xd3, 0x9c, 0x0e, 0x8d, 0xa1, 0xe2, 0x87, 0xcf, 0xc7, 0xc3, 0xc3, + 0xc0, 0xf0, 0x79, 0xff, 0x33, 0xfa, 0x2b, 0xe2, 0x2e, 0x7c, 0xcd, 0xee, 0x04, 0xd5, 0xae, 0xd3, + 0x49, 0x0a, 0x97, 0x36, 0x42, 0x31, 0xd5, 0xcc, 0xa3, 0xe5, 0x35, 0xcc, 0x6a, 0xe0, 0xfb, 0x61, + 0x5b, 0x53, 0xe8, 0xa7, 0x59, 0x19, 0xe6, 0x22, 0xb0, 0xd2, 0xc2, 0xb5, 0x9b, 0x5e, 0x0d, 0x49, + 0xbb, 0x31, 0x14, 0xd0, 0x16, 0x61, 0xd1, 0x9a, 0x00, 0x16, 0x0e, 0x09, 0x69, 0x56, 0xae, 0x13, + 0x2b, 0x91, 0x7b, 0xe0, 0x64, 0x29, 0xff, 0xfd, 0xdc, 0x02, 0x5e, 0xde, 0xc4, 0x61, 0x77, 0x7b, + 0xe0, 0xe9, 0xcf, 0xeb, 0x5e, 0x2d, 0x46, 0x50, 0x6c, 0xd3, 0x95, 0xd8, 0x14, 0x31, 0xc5, 0x72, + 0xce, 0xc4, 0xde, 0x03, 0x51, 0xb6, 0xd0, 0xd5, 0xc2, 0x7f, 0x5d, 0xa8, 0xcc, 0x34, 0x3c, 0xad, + 0x33, 0x75, 0x5a, 0x65, 0x96, 0x22, 0x18, 0x78, 0xf1, 0x80, 0x42, 0x04, 0xf5, 0x2f, 0x00, 0xda, + 0x4e, 0x5f, 0x29, 0xbb, 0xeb, 0x49, 0x53, 0x4c, 0x90, 0x29, 0x99, 0x37, 0xe0, 0x2c, 0xe3, 0xdc, + 0x40, 0x0a, 0x29, 0xc4, 0x2b, 0x81, 0x1a, 0x64, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0xb6, 0x32, + 0x00, 0x00, 0x7b, 0x8a, 0x4f, 0xb1, 0xcd, 0x72, 0xeb, 0x2f, 0x0c, 0x8d, 0x21, 0x4d, 0xce, 0xba, + 0xa1, 0x37, 0x98, 0x35, 0xd6, 0x85, 0xed, 0x39, 0x22, 0x9c, 0x85, 0x49, 0x87, 0x8a, 0xcf, 0x4c, + 0xab, 0x48, 0x69, 0x6b, 0xbc, 0x6a, 0x38, 0x4e, 0xe0, 0x93, 0x9b, 0xe2, 0x8d, 0x23, 0x54, 0x0e, + 0x4b, 0x6f, 0x17, 0x7d, 0x05, 0x5a, 0xc2, 0x02, 0x5a, 0x10, 0x0f, 0x6e, 0xf2, 0x94, 0x81, 0x7a, + 0x99, 0xc7, 0x9b, 0xe5, 0xff, 0xf9, 0xc7, 0x27, 0x37, 0x80, 0x2a, 0x98, 0x98, 0x71, 0xce, 0x07, + 0x0d, 0x5d, 0x01, 0xdf, 0x03, 0x24, 0xc2, 0xd0, 0x47, 0xab, 0x5c, 0xb6, 0x57, 0x2f, 0x08, 0xb8, + 0x6c, 0xbf, 0xef, 0x56, 0x4d, 0x98, 0xc7, 0x1c, 0x78, 0x1f, 0x03, 0xf8, 0x38, 0x3e, 0x11, 0x2a, + 0xc8, 0x34, 0x8f, 0xe7, 0x79, 0x09, 0x95, 0x9a, 0xaf, 0xa6, 0xca, 0xa0, 0xc4, 0x9c, 0x8d, 0xe3, + 0xce, 0xbf, 0xbc, 0x6a, 0x2e, 0xe0, 0xbe, 0xbd, 0xa2, 0x3a, 0x6d, 0x84, 0x19, 0x2d, 0x7e, 0xe4, + 0x7a, 0x69, 0x85, 0x11, 0xc4, 0x7e, 0x27, 0x96, 0x4a, 0x91, 0x96, 0x58, 0x21, 0xa8, 0x30, 0xe8, + 0xd4, 0x07, 0xe5, 0x04, 0x9c, 0x80, 0x4d, 0x07, 0x26, 0x1f, 0xcf, 0x74, 0xc9, 0x1e, 0x0a, 0xf9, + 0xe9, 0x4f, 0x23, 0xd1, 0x6f, 0x46, 0x7f, 0x5a, 0x5a, 0x27, 0x9e, 0x9b, 0x72, 0xca, 0xea, 0x6f, + 0x38, 0x4b, 0x43, 0x70, 0xc3, 0xc3, 0x83, 0xc3, 0x9b, 0x60, 0x7e, 0x06, 0xb3, 0xc4, 0x53, 0x16, + 0x70, 0xf3, 0xb0, 0x8d, 0x02, 0x50, 0x97, 0x83, 0x55, 0x2d, 0x4c, 0xbc, 0xc8, 0x1b, 0x25, 0xb6, + 0xdc, 0x79, 0x75, 0xfc, 0xf3, 0x32, 0xcb, 0x1a, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x75, 0xaa, + 0xb0, 0xd2, 0xbf, 0x90, 0x50, 0xd0, 0xf0, 0x42, 0x44, 0x70, 0x24, 0x60, 0x1a, 0x2c, 0xbd, 0x2a, + 0x5f, 0x4b, 0x37, 0x70, 0x95, 0x79, 0xff, 0x07, 0xad, 0x00, 0x68, 0x44, 0xfe, 0xde, 0x89, 0x98, + 0x3c, 0x3d, 0x96, 0x3c, 0x08, 0x2d, 0x2f, 0xfc, 0xa9, 0xe7, 0xce, 0x1d, 0x91, 0x3e, 0xb1, 0x89, + 0xdc, 0x7d, 0xbd, 0x2f, 0x0d, 0x56, 0x15, 0x6c, 0xde, 0x0e, 0x57, 0x29, 0x67, 0x78, 0x41, 0xfb, + 0xf7, 0x2d, 0xea, 0xab, 0x5f, 0x85, 0xce, 0x39, 0xd1, 0x9d, 0xfb, 0x96, 0xec, 0x70, 0xf8, 0x61, + 0xe1, 0x9d, 0x87, 0xa3, 0x56, 0x63, 0x78, 0x7b, 0x40, 0x6b, 0x5f, 0x1e, 0x7e, 0x33, 0x23, 0x0c, + 0xd9, 0xc4, 0x2d, 0xf2, 0x0d, 0x32, 0x15, 0x7c, 0x10, 0xef, 0xd1, 0x52, 0xd8, 0x22, 0x2b, 0xd7, + 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x86, 0x02, 0x00, 0x00, 0x00, 0x5c, 0x4f, 0x5c, 0x9d, 0xdd, + 0x23, 0xea, 0x8f, 0x47, 0xb9, 0xed, 0xc2, 0x20, 0x63, 0x74, 0x8e, 0x6e, 0x88, 0x0f, 0xdf, 0x76, + 0x0a, 0xac, 0x64, 0xc4, 0x55, 0x19, 0x4a, 0xb7, 0x7a, 0xeb, 0xf9, 0xa0, 0xcf, 0x58, 0x59, 0xd6, + 0xe8, 0xc0, 0xee, 0x3b, 0x7e, 0xb1, 0x30, 0x26, 0x9b, 0x33, 0x1a, 0x56, 0xc7, 0x15, 0xe5, 0xa2, + 0x7c, 0xf3, 0x54, 0xff, 0x8f, 0x7a, 0xd6, 0xf0, 0x84, 0x6c, 0xeb, 0xcd, 0xe1, 0x80, 0x5e, 0x45, + 0x8b, 0x8c, 0x2e, 0x9e, 0x71, 0xe3, 0xc3, 0x1f, 0xb2, 0x18, 0x0e, 0x45, 0x1a, 0x22, 0x77, 0xcf, + 0x03, 0x41, 0xd7, 0x84, 0x37, 0x88, 0x4f, 0xf3, 0x87, 0xec, 0x9b, 0xd1, 0x0d, 0x1b, 0xab, 0x01, + 0x8f, 0x81, 0xf8, 0x3f, 0x03, 0xe1, 0xe7, 0x17, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x09, 0xb5, 0x9a, + 0xae, 0xed, 0x19, 0x12, 0xa7, 0xec, 0xb5, 0x78, 0xea, 0x3c, 0x5f, 0x3c, 0x65, 0x32, 0xc1, 0x96, + 0x17, 0x53, 0xb5, 0x8a, 0xc8, 0xa4, 0xbc, 0x00, 0x16, 0xff, 0x66, 0xad, 0x27, 0x95, 0x20, 0x99, + 0xe4, 0x92, 0x8e, 0x0d, 0x73, 0x94, 0xbe, 0xed, 0x8b, 0xb9, 0x83, 0xa8, 0x30, 0xc6, 0xc3, 0x6e, + 0xb3, 0xa6, 0xe5, 0x1b, 0x7a, 0xd0, 0x90, 0x5a, 0x70, 0x05, 0x7e, 0x13, 0xb0, 0xb5, 0xf4, 0x50, + 0xa3, 0xb3, 0x42, 0x45, 0x57, 0x1f, 0x3c, 0x4d, 0x1b, 0xbd, 0xa8, 0x8c, 0x65, 0xb7, 0x27, 0x07, + 0x07, 0x8f, 0x85, 0x0f, 0x51, 0x5c, 0x2d, 0x32, 0x33, 0x61, 0x39, 0x8b, 0x92, 0x23, 0x9e, 0x2f, + 0xa2, 0x19, 0x4c, 0x65, 0xb1, 0xc5, 0xdb, 0x79, 0x58, 0x18, 0x2a, 0x26, 0x3e, 0x81, 0x44, 0x63, + 0xc8, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x96, 0x0a, 0x00, 0x00, 0x00, 0x5c, 0x4f, 0x57, 0xe1, 0xe3, + 0xbc, 0x37, 0x2a, 0xaf, 0x44, 0x7a, 0xf6, 0x6e, 0x08, 0x0a, 0x68, 0xf8, 0xea, 0x64, 0x83, 0x2c, + 0xd9, 0xce, 0x39, 0xce, 0xa9, 0x4e, 0xd4, 0xae, 0x45, 0xe9, 0x30, 0xab, 0x44, 0xb3, 0x4e, 0xa0, + 0xde, 0x8c, 0x5b, 0x17, 0x8d, 0xd0, 0xb8, 0xcf, 0x93, 0xd4, 0xa8, 0x7e, 0xbc, 0x40, 0x1c, 0x52, + 0x3b, 0x05, 0x69, 0x0a, 0x0f, 0xba, 0x99, 0xc6, 0x07, 0xce, 0x7a, 0xc5, 0x00, 0x49, 0x8c, 0xf9, + 0x57, 0xce, 0x01, 0x47, 0x1e, 0x38, 0x78, 0xf0, 0x3d, 0xd5, 0x46, 0x8b, 0x19, 0x01, 0xd8, 0xdd, + 0xe5, 0x1a, 0xac, 0x3b, 0xff, 0x51, 0xb2, 0x89, 0x2e, 0x41, 0xfc, 0x4f, 0xdd, 0x9b, 0x88, 0x1c, + 0x3f, 0x01, 0xf8, 0x1e, 0x0f, 0x87, 0x8e, 0x11, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x09, 0x95, 0xda, + 0xb0, 0xd2, 0xc2, 0xb4, 0xcd, 0x00, 0x67, 0xfa, 0x11, 0xab, 0x00, 0x06, 0x12, 0x0c, 0xca, 0x82, + 0x9f, 0xb2, 0x61, 0x98, 0x46, 0x1f, 0xb7, 0x04, 0x6c, 0x91, 0x49, 0xa9, 0xd4, 0xbe, 0x87, 0xf6, + 0xdd, 0xf6, 0x4c, 0x82, 0x4f, 0x2b, 0xea, 0xbf, 0x67, 0x6b, 0x86, 0x96, 0x4e, 0x33, 0x2a, 0xbb, + 0x52, 0x29, 0x73, 0x7d, 0x2b, 0x2d, 0x15, 0xb3, 0x84, 0x68, 0x93, 0x06, 0x94, 0x0a, 0x05, 0x5f, + 0x8f, 0x9c, 0xd1, 0x77, 0xa1, 0x4f, 0x5c, 0x1d, 0xfd, 0xaf, 0xec, 0x3e, 0x3c, 0x1e, 0x1e, 0x0f, + 0x0d, 0x22, 0xc0, 0x41, 0x0b, 0x7c, 0x0a, 0xc3, 0x3e, 0x29, 0x3e, 0x1b, 0x8e, 0xf8, 0xc0, 0xb0, + 0x66, 0x2e, 0x45, 0xea, 0xea, 0xa3, 0x0a, 0x1a, 0x6b, 0xa3, 0x9b, 0x40, 0x78, 0x48, 0x7a, 0xd7, + 0xd8, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x85, 0xe2, 0xaf, 0xa6, 0xc8, 0x17, 0x7f, 0x07, 0xd7, 0x80, + 0x85, 0x13, 0x00, 0x01, 0xd1, 0x39, 0x98, 0xdf, 0x2f, 0x6d, 0x9a, 0x18, 0x38, 0xbd, 0xfd, 0x90, + 0xc0, 0xd5, 0x26, 0x43, 0x07, 0x65, 0x0a, 0x21, 0x38, 0x54, 0xe0, 0x51, 0x55, 0x53, 0x11, 0xe7, + 0x46, 0x6c, 0x32, 0x98, 0x69, 0xe2, 0x99, 0x27, 0x20, 0x1d, 0xab, 0x1e, 0x3b, 0x0d, 0x20, 0x08, + 0xaf, 0x40, 0xa3, 0x69, 0x19, 0xb5, 0xa4, 0x97, 0x85, 0xd3, 0xb9, 0x10, 0x45, 0x45, 0x95, 0x76, + 0x55, 0x2d, 0x20, 0xc5, 0x1e, 0x8e, 0x3c, 0x3c, 0x1e, 0x1f, 0x2e, 0xf4, 0x8f, 0x52, 0xf3, 0x11, + 0x12, 0x09, 0x55, 0x8d, 0x65, 0x73, 0x76, 0x12, 0x0a, 0x31, 0x30, 0x99, 0x63, 0x6a, 0x70, 0x82, + 0xda, 0x1b, 0xca, 0xa0, 0xc6, 0x1f, 0x48, 0x30, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x76, 0x3a, + 0xb0, 0xd2, 0xc2, 0xb4, 0xe8, 0x03, 0xc5, 0x58, 0xf9, 0x16, 0x0c, 0x7d, 0x98, 0xd8, 0xc6, 0x8b, + 0x15, 0x7a, 0x10, 0x1e, 0xd9, 0xf5, 0xda, 0x2e, 0x55, 0x0e, 0x00, 0x1e, 0xf8, 0x72, 0x0c, 0xa5, + 0xe0, 0xe7, 0x31, 0x5b, 0xf7, 0xe7, 0x17, 0x85, 0x0f, 0x3c, 0x37, 0x27, 0xff, 0xef, 0x9f, 0xee, + 0xd9, 0xba, 0x49, 0xac, 0xb8, 0xaf, 0x82, 0xc8, 0x3c, 0x3a, 0x40, 0x41, 0xfb, 0x93, 0x48, 0x9a, + 0x75, 0x8c, 0x74, 0x6f, 0xaf, 0xbc, 0x29, 0x1d, 0x0d, 0xa2, 0x17, 0xc2, 0x78, 0xf4, 0xe8, 0x4c, + 0x71, 0xf8, 0x08, 0x01, 0x4b, 0x48, 0x10, 0xb8, 0x82, 0x41, 0xc9, 0x98, 0xca, 0xb5, 0x20, 0x00, + 0x4f, 0x46, 0xed, 0x59, 0x64, 0xfc, 0x57, 0x0a, 0x50, 0xb5, 0x52, 0x7d, 0x46, 0xd1, 0xe2, 0x79, + 0xc9, 0x18, 0x7f, 0xb7, 0x79, 0x19, 0x86, 0x3a, 0xaf, 0xdd, 0x47, 0xaf, 0xd9, 0x97, 0xb6, 0x49, + 0x9c, 0xea, 0x94, 0x11, 0x6e, 0x68, 0xd4, 0xbc, 0x72, 0xbe, 0xc1, 0xe3, 0xbe, 0xfe, 0x53, 0x05, + 0x2b, 0x0f, 0x14, 0x1f, 0xa1, 0xcd, 0x19, 0xfd, 0x44, 0x78, 0x5d, 0x0e, 0xb6, 0x7a, 0x0b, 0x07, + 0xbf, 0xae, 0x97, 0x1c, 0x4f, 0x97, 0xa1, 0x92, 0xcb, 0x5a, 0xea, 0x36, 0xc3, 0xdf, 0x33, 0x5c, + 0x12, 0xc9, 0x14, 0x25, 0x7b, 0x9a, 0x35, 0xea, 0x63, 0x00, 0xa4, 0x6e, 0x9d, 0x7c, 0x14, 0x25, + 0xe2, 0x9e, 0x43, 0x5f, 0xca, 0x8c, 0x78, 0x7c, 0x3e, 0x3e, 0x1e, 0x62, 0x7f, 0x36, 0x1b, 0xb5, + 0x3e, 0x9e, 0x03, 0xce, 0x27, 0x63, 0xca, 0x5a, 0xd5, 0x4d, 0x72, 0x6b, 0x4f, 0xfb, 0xa1, 0xf2, + 0xc2, 0x65, 0x11, 0x02, 0x41, 0x87, 0x90, 0xc6, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x96, 0x12, + 0xaf, 0xa6, 0xca, 0xa0, 0xd1, 0x87, 0xbe, 0x89, 0xd0, 0xce, 0x85, 0x59, 0x7a, 0x65, 0x23, 0x50, + 0xc8, 0x53, 0x5c, 0xd8, 0x14, 0x4f, 0x2e, 0xb5, 0x66, 0x49, 0x0f, 0x52, 0x12, 0x21, 0xfb, 0x7f, + 0x6d, 0xa6, 0x80, 0x20, 0x95, 0x30, 0xdc, 0xfc, 0xee, 0x23, 0xd5, 0x30, 0xa7, 0x9e, 0x11, 0x2b, + 0x52, 0xf2, 0x3e, 0x5b, 0x9e, 0xeb, 0x6b, 0xa0, 0x5f, 0x15, 0x68, 0x8e, 0xe9, 0x78, 0x59, 0xd9, + 0xe6, 0xc9, 0x05, 0x0d, 0x73, 0x26, 0xf8, 0x3b, 0x34, 0x2f, 0x1f, 0x91, 0x9e, 0x99, 0x63, 0x8c, + 0x33, 0xf4, 0x84, 0x0e, 0x27, 0x25, 0xb6, 0x1b, 0x98, 0x0e, 0xee, 0xcf, 0xd8, 0x15, 0xd5, 0xaa, + 0xd9, 0xbf, 0x82, 0xfb, 0x5a, 0x91, 0x4c, 0xa3, 0x6b, 0x4a, 0x17, 0x07, 0x99, 0xcc, 0x7a, 0x01, + 0xd9, 0x18, 0x7f, 0xb7, 0x79, 0x19, 0x96, 0x2a, 0xb6, 0xba, 0x94, 0x47, 0x96, 0x0a, 0x24, 0x0e, + 0x1d, 0x13, 0x4c, 0xd0, 0x98, 0x46, 0x8e, 0xe9, 0x00, 0x09, 0xa0, 0x5f, 0x54, 0x00, 0x0a, 0x27, + 0xd9, 0x45, 0xcf, 0xcf, 0x1a, 0xb1, 0xb9, 0x23, 0xd3, 0x8f, 0x2b, 0xa0, 0x6c, 0xf0, 0x94, 0xc5, + 0xec, 0xa0, 0x25, 0x4c, 0x03, 0x95, 0x9a, 0xb0, 0xe8, 0x17, 0x31, 0xcc, 0x58, 0xae, 0x26, 0xd5, + 0x19, 0x74, 0xd0, 0x5d, 0x2a, 0xcf, 0x73, 0xb2, 0xd0, 0xf2, 0x0e, 0x6e, 0x20, 0xef, 0xb2, 0x5d, + 0x74, 0xc2, 0x33, 0x9d, 0x8c, 0xe3, 0x8f, 0x1e, 0x0f, 0x0f, 0x87, 0x9c, 0x5a, 0x72, 0x8c, 0x3d, + 0x84, 0x9d, 0x8c, 0xf9, 0x92, 0x6a, 0x27, 0x11, 0xb6, 0x7c, 0x1f, 0x5c, 0x20, 0xa5, 0x31, 0x10, + 0x53, 0xfa, 0x70, 0xc1, 0x57, 0x77, 0x41, 0x9c, 0xd8, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x95, 0xf2, + 0xae, 0xec, 0x0f, 0xb3, 0x25, 0xd2, 0x48, 0x45, 0xcc, 0x96, 0x18, 0x73, 0x3f, 0x05, 0xf8, 0xf1, + 0x77, 0x06, 0xb8, 0x84, 0x9f, 0x94, 0x3a, 0x01, 0x59, 0xef, 0x5e, 0x07, 0xb8, 0x44, 0x7c, 0xb5, + 0x08, 0xdd, 0xae, 0x57, 0x5b, 0x81, 0x1a, 0xc7, 0x62, 0x6c, 0xf9, 0x0a, 0x4a, 0xb6, 0xf3, 0x44, + 0x11, 0x93, 0xb8, 0x1e, 0xb8, 0xa9, 0x4f, 0xbc, 0x79, 0xf6, 0x95, 0xfd, 0xfb, 0xf3, 0x57, 0x4b, + 0xb9, 0xe9, 0xb5, 0xcd, 0x8d, 0xd4, 0x39, 0x21, 0x88, 0x43, 0xda, 0x37, 0xb8, 0x78, 0xfc, 0x1e, + 0x0f, 0x87, 0x04, 0x2d, 0x7e, 0xf0, 0xad, 0x32, 0xd2, 0xef, 0x5c, 0xa7, 0xd6, 0x56, 0x84, 0xcc, + 0xbc, 0x3b, 0x95, 0x32, 0x8b, 0xaa, 0x20, 0xb2, 0x89, 0x90, 0x61, 0x00, 0xc9, 0xe9, 0xe9, 0x42, + 0xc8, 0x34, 0x8f, 0xe7, 0x79, 0x39, 0x86, 0x0a, 0xaf, 0xdd, 0x49, 0x47, 0x93, 0x57, 0xb2, 0x73, + 0x98, 0x0a, 0x4a, 0x00, 0x02, 0xdc, 0x10, 0x12, 0x0d, 0xa8, 0x69, 0xb4, 0xff, 0xbb, 0xd4, 0x79, + 0x00, 0x10, 0x9a, 0xd9, 0x29, 0x03, 0x07, 0x8d, 0xe2, 0xeb, 0x51, 0x78, 0xff, 0x8f, 0xde, 0x43, + 0xb8, 0x6b, 0x59, 0xf8, 0xa5, 0x52, 0x56, 0x92, 0xa2, 0x86, 0xb2, 0x2d, 0x49, 0xf6, 0x12, 0x4b, + 0x9a, 0xf3, 0x65, 0x5c, 0xb3, 0x2c, 0xc1, 0x2f, 0x02, 0x43, 0x35, 0xe5, 0xab, 0x9b, 0xa6, 0x19, + 0xf3, 0xd4, 0x73, 0xc1, 0x83, 0x07, 0x1c, 0xc5, 0xb7, 0x8f, 0x20, 0xc2, 0xa4, 0x18, 0x21, 0x83, + 0xc0, 0x58, 0xea, 0xb3, 0xcf, 0x90, 0x80, 0x92, 0x34, 0xd0, 0xc6, 0x2f, 0x39, 0x13, 0xbf, 0x92, + 0xbd, 0x02, 0x92, 0x14, 0x88, 0x75, 0x17, 0x8f, 0x58, 0x31, 0x9e, 0xe7, 0x79, 0x19, 0x96, 0x32, + 0x00, 0x00, 0x00, 0x17, 0xce, 0xd6, 0x4b, 0x99, 0x74, 0x49, 0x5b, 0xfd, 0x44, 0xe4, 0xd0, 0xf0, + 0x28, 0x47, 0x5e, 0xff, 0x1b, 0xc0, 0xe7, 0x04, 0x71, 0x3d, 0x0d, 0xd6, 0xca, 0x4c, 0x60, 0xc4, + 0x25, 0xe3, 0xef, 0x6b, 0xc8, 0x44, 0xdf, 0x67, 0xf4, 0xa2, 0x3c, 0x99, 0xf2, 0xeb, 0x63, 0x2b, + 0x4f, 0x57, 0xb0, 0xb4, 0xd3, 0x15, 0x11, 0xd9, 0x4a, 0x4d, 0xe0, 0xfc, 0x8d, 0x7e, 0xbb, 0xdf, + 0x51, 0x9b, 0xd6, 0x78, 0x46, 0x08, 0x84, 0x21, 0x19, 0x9a, 0x9e, 0x1c, 0x26, 0x98, 0x45, 0xfa, + 0x96, 0xd6, 0xe3, 0xe3, 0x86, 0x79, 0x95, 0xa4, 0x90, 0x73, 0xe5, 0x0c, 0x93, 0xed, 0x60, 0x04, + 0x16, 0x48, 0x1c, 0x2d, 0xe0, 0xf3, 0x18, 0x2f, 0xc9, 0x87, 0x8f, 0x0f, 0x0e, 0x0e, 0x35, 0x04, + 0x0a, 0xa2, 0x25, 0xbe, 0x79, 0x29, 0xd6, 0x22, 0xaf, 0xdd, 0x49, 0xd0, 0x01, 0x07, 0x26, 0x24, + 0x1a, 0x30, 0xf7, 0x6a, 0x7c, 0x6d, 0x9b, 0x33, 0x48, 0x02, 0x8d, 0x03, 0x92, 0x80, 0x00, 0x00, + 0x00, 0x9b, 0x5f, 0x92, 0xdf, 0x60, 0x50, 0x67, 0x44, 0xa0, 0xed, 0xb2, 0xaa, 0xdf, 0x6f, 0xfc, + 0x8d, 0x08, 0xfb, 0xb1, 0x55, 0x21, 0x9c, 0x5d, 0x89, 0xc5, 0x0f, 0x69, 0x54, 0xaa, 0x9b, 0x7c, + 0x6e, 0x86, 0x21, 0x29, 0xb8, 0x84, 0xa3, 0xd5, 0x82, 0x0b, 0xdc, 0xe0, 0x0f, 0xa8, 0x5e, 0x5d, + 0x77, 0xdb, 0x0f, 0x83, 0x83, 0xc3, 0x8c, 0x27, 0x38, 0x79, 0x87, 0x31, 0x4c, 0xcc, 0xa5, 0x12, + 0x52, 0x98, 0x6b, 0x9b, 0x18, 0x09, 0x51, 0x91, 0x73, 0x8f, 0x76, 0xe2, 0x04, 0x4c, 0x4c, 0x19, + 0xc5, 0x7b, 0xd6, 0x24, 0x31, 0x97, 0xf9, 0x53, 0x4a, 0xa2, 0x25, 0xbe, 0x79, 0x39, 0xb6, 0x22, + 0xaf, 0xdd, 0x47, 0x5c, 0xd4, 0x87, 0xe9, 0x38, 0x67, 0x02, 0xb6, 0xd5, 0x9e, 0x32, 0x3e, 0x50, + 0x4e, 0x41, 0x80, 0xeb, 0x01, 0x11, 0x93, 0x00, 0x00, 0xc1, 0x6f, 0x39, 0x60, 0x40, 0xe1, 0x8f, + 0xe0, 0xde, 0x4a, 0x1c, 0x46, 0x43, 0x6c, 0xd0, 0x4d, 0x6f, 0x87, 0xfd, 0x26, 0xc9, 0xac, 0xef, + 0x65, 0x1f, 0x08, 0xd4, 0x2d, 0xe3, 0xbb, 0x95, 0x06, 0x98, 0x02, 0x6f, 0xc3, 0x4b, 0x70, 0xb5, + 0xd4, 0x1d, 0xcc, 0x12, 0x9e, 0xd0, 0x4b, 0xc0, 0x83, 0x5e, 0x5c, 0x43, 0xe0, 0x61, 0xfc, 0x70, + 0x85, 0xb9, 0xe1, 0xce, 0x81, 0x81, 0x74, 0x0f, 0x71, 0x24, 0x04, 0xe7, 0x0b, 0x3d, 0x89, 0x87, + 0x1f, 0x22, 0x73, 0xef, 0x71, 0xca, 0x0e, 0xac, 0x13, 0x9a, 0xab, 0x6f, 0x08, 0x10, 0x58, 0x63, + 0xda, 0xa2, 0x25, 0xbe, 0x79, 0x19, 0xb6, 0x2a, 0xaf, 0xde, 0xcb, 0xf9, 0xda, 0x75, 0x22, 0xeb, + 0x42, 0x79, 0x4d, 0xf9, 0x26, 0x61, 0xa1, 0xde, 0x6f, 0x04, 0x69, 0x01, 0x56, 0x71, 0x00, 0x00, + 0x00, 0xc9, 0x21, 0xc5, 0x11, 0x2d, 0x68, 0xb3, 0x00, 0x0d, 0x1b, 0x31, 0x17, 0xa5, 0x05, 0x0b, + 0x0c, 0x4a, 0x5e, 0x20, 0xbf, 0x2c, 0x0d, 0x5c, 0x6c, 0x89, 0x64, 0x68, 0xe2, 0xcd, 0x31, 0xb3, + 0x25, 0x74, 0x83, 0x25, 0x47, 0x80, 0xba, 0x98, 0xa2, 0xaa, 0x5c, 0x20, 0x84, 0x5d, 0x84, 0x77, + 0xa6, 0x57, 0x5f, 0xc0, 0x7e, 0x0f, 0xc0, 0xf0, 0xf1, 0xf9, 0x1c, 0x78, 0x25, 0xe7, 0xf6, 0xbe, + 0x41, 0x60, 0x4b, 0x07, 0xd9, 0x03, 0x1a, 0x7a, 0xfa, 0xc9, 0x8c, 0x49, 0x67, 0x61, 0x68, 0xbe, + 0x6b, 0x94, 0x67, 0xce, 0x01, 0x7f, 0xbd, 0x03, 0xda, 0xa2, 0x25, 0xbe, 0x79, 0x19, 0xb6, 0x32, + 0xb6, 0xae, 0x86, 0x8b, 0xf6, 0x97, 0xbd, 0x1d, 0x21, 0x8d, 0xd3, 0xc1, 0x14, 0xa5, 0xb4, 0x74, + 0xcb, 0x2c, 0x68, 0x95, 0x58, 0x6e, 0x9d, 0xd8, 0x67, 0xd7, 0x00, 0x28, 0x59, 0xe1, 0x22, 0x0f, + 0x08, 0x16, 0x8c, 0xbc, 0x39, 0x08, 0xc8, 0xf2, 0xd5, 0x63, 0x96, 0x2a, 0x4d, 0xe4, 0xb8, 0x45, + 0x8d, 0xe0, 0xe6, 0x7e, 0x09, 0xe7, 0xba, 0xdb, 0x8c, 0x84, 0x06, 0xd1, 0xa0, 0xcf, 0x15, 0xd8, + 0xe6, 0x6e, 0x30, 0x2c, 0xf3, 0x92, 0xe8, 0x69, 0xbf, 0xdb, 0xe0, 0xe2, 0x18, 0xe5, 0x38, 0x7c, + 0x70, 0x58, 0xab, 0x5a, 0xb3, 0x41, 0xa2, 0x39, 0x1d, 0xe8, 0x60, 0x13, 0x37, 0xa0, 0xea, 0x94, + 0xa9, 0x3f, 0xc2, 0xa8, 0x02, 0xa8, 0xc9, 0xc9, 0x5b, 0x82, 0x58, 0xa0, 0x7e, 0x58, 0xc0, 0xbc, + 0xda, 0xa2, 0x25, 0xbe, 0x79, 0x19, 0x85, 0xe2, 0x33, 0xd8, 0x04, 0x09, 0x22, 0xac, 0x4b, 0x30, + 0x26, 0xa5, 0xce, 0x2b, 0x8b, 0xe4, 0xdd, 0x49, 0xde, 0xf3, 0x71, 0xdb, 0x41, 0x0b, 0x9c, 0x9e, + 0x37, 0x87, 0x37, 0x00, 0x30, 0x51, 0x30, 0xf8, 0x07, 0x9d, 0xd5, 0xaf, 0x2d, 0xa0, 0x72, 0x91, + 0xf5, 0xf6, 0xff, 0x28, 0xe7, 0x8c, 0x19, 0x61, 0xc9, 0x90, 0x69, 0xd0, 0xb6, 0x18, 0x57, 0x2b, + 0xbb, 0x7d, 0x94, 0xbd, 0xbb, 0x1b, 0xd1, 0xf3, 0xe2, 0x7b, 0x00, 0x00, 0x00, 0x5e, 0xb5, 0x7d, + 0x88, 0x13, 0x70, 0x37, 0xc7, 0x09, 0xf1, 0xff, 0x00, 0xf4, 0xda, 0xfd, 0xf8, 0xc8, 0xeb, 0x4e, + 0x20, 0x64, 0x24, 0xe8, 0x83, 0x33, 0xdd, 0x21, 0xf1, 0x98, 0xa9, 0x4a, 0x2a, 0x22, 0x38, 0xd0, + 0x50, 0x44, 0x3e, 0x12, 0x97, 0xf5, 0x0a, 0x4f, 0xb5, 0x45, 0x00, 0xbc, 0xf2, 0x39, 0x96, 0x24, + 0xb6, 0xaf, 0xa6, 0xf9, 0xcd, 0x37, 0xd5, 0x1c, 0x78, 0xf8, 0x77, 0x78, 0xdd, 0x48, 0x14, 0x86, + 0x42, 0xb8, 0xa5, 0x3f, 0x61, 0x53, 0x26, 0x14, 0x48, 0x00, 0x3a, 0x99, 0xa8, 0xc0, 0x35, 0x0d, + 0x65, 0x76, 0x0d, 0x54, 0x20, 0x78, 0x1f, 0xf5, 0x28, 0xdd, 0x90, 0x38, 0xb0, 0xae, 0x63, 0xe6, + 0x31, 0x7b, 0xd9, 0x68, 0x06, 0x49, 0x53, 0xda, 0x75, 0x93, 0x00, 0x15, 0x70, 0x7f, 0xa1, 0x2f, + 0x4d, 0xf6, 0xb4, 0x42, 0x29, 0xfd, 0xfd, 0xa7, 0x50, 0xf9, 0x4e, 0xb1, 0x67, 0x06, 0x3c, 0xc0, + 0x6f, 0x38, 0x79, 0x0b, 0x3e, 0x0e, 0x94, 0x82, 0x42, 0x70, 0x9a, 0xc5, 0x1b, 0x63, 0x61, 0x3e, + 0x4b, 0xb3, 0x17, 0xbb, 0x40, 0x09, 0x2a, 0xff, 0x7e, 0xe5, 0x44, 0xdf, 0x48, 0x4a, 0x75, 0x8b, + 0x5a, 0xa2, 0x80, 0x5e, 0x79, 0x19, 0x96, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6d, 0x73, 0x7c, + 0x9f, 0x67, 0xa0, 0xef, 0xa0, 0xa7, 0xeb, 0xe2, 0xe1, 0x85, 0x96, 0x6a, 0xe4, 0x5b, 0xa3, 0xc6, + 0x67, 0x86, 0xd3, 0x74, 0x6c, 0x13, 0xb2, 0x27, 0x47, 0x70, 0x4c, 0x11, 0x7f, 0x31, 0xa6, 0xc0, + 0x2d, 0x9f, 0xc1, 0x91, 0x91, 0x1b, 0xa9, 0xb6, 0xee, 0x29, 0x8d, 0x51, 0xbf, 0xab, 0xad, 0xed, + 0x28, 0x95, 0xf9, 0x44, 0x3d, 0x92, 0x01, 0x45, 0x09, 0x32, 0xb3, 0x82, 0x55, 0xf4, 0x7b, 0x46, + 0x43, 0x48, 0xac, 0x84, 0xd9, 0x86, 0xd3, 0x0f, 0xc2, 0xa5, 0x42, 0x20, 0x89, 0x96, 0x99, 0xba, + 0xe6, 0x22, 0x7b, 0x43, 0x99, 0xa0, 0x7a, 0xce, 0x14, 0x67, 0x08, 0x47, 0x76, 0xe0, 0xf9, 0x4d, + 0xd4, 0x42, 0xd1, 0xe0, 0xf0, 0x78, 0x71, 0xb6, 0x3a, 0xa2, 0x80, 0x5e, 0x79, 0x09, 0xc6, 0x22, + 0x35, 0x16, 0xd8, 0x03, 0xc2, 0xd2, 0x32, 0x65, 0x0f, 0x49, 0xb5, 0x22, 0x2f, 0x98, 0x3e, 0x96, + 0x6b, 0x25, 0xef, 0xf6, 0x08, 0x01, 0xc4, 0xf3, 0xf1, 0xf2, 0x31, 0xf1, 0xa5, 0x00, 0x3b, 0x24, + 0x7d, 0x52, 0x00, 0xe5, 0x7e, 0xbe, 0xb5, 0x73, 0xf3, 0xe8, 0x4b, 0xbf, 0x91, 0xf5, 0x54, 0x7f, + 0x21, 0x72, 0x51, 0xd8, 0xe1, 0x31, 0xa6, 0x40, 0x8a, 0xcc, 0x5f, 0xfb, 0x40, 0x94, 0x61, 0x54, + 0x7d, 0x74, 0x71, 0x5e, 0xc4, 0x00, 0x10, 0x92, 0x02, 0x93, 0x30, 0x37, 0x6f, 0xac, 0xf4, 0xad, + 0xe6, 0x90, 0xc0, 0x9c, 0x32, 0xc4, 0x42, 0x2b, 0x38, 0x99, 0x1c, 0x60, 0xa8, 0x5e, 0x49, 0xb0, + 0x0f, 0x27, 0xab, 0x4c, 0x98, 0x81, 0x8e, 0x77, 0x3b, 0xd3, 0x1c, 0xb4, 0xfd, 0x1f, 0x3a, 0xa7, + 0x95, 0x45, 0x00, 0xbc, 0xf2, 0x39, 0x65, 0x94, 0x33, 0x99, 0xa3, 0x6b, 0xc6, 0x11, 0xc8, 0xea, + 0xb8, 0x61, 0x56, 0x62, 0x54, 0xef, 0x09, 0xac, 0xa7, 0x9c, 0xad, 0x88, 0x72, 0xaf, 0xf2, 0xa8, + 0x81, 0x9f, 0x94, 0x00, 0x00, 0x02, 0xf0, 0xb9, 0xf9, 0xc6, 0xf8, 0x3d, 0x1a, 0x27, 0x3f, 0xf5, + 0xb9, 0xac, 0x99, 0xf8, 0x85, 0x99, 0xcf, 0x49, 0x9f, 0xaf, 0x12, 0x30, 0x09, 0xfe, 0xd0, 0xbd, + 0x86, 0x1a, 0xac, 0xfa, 0xbb, 0x6a, 0x66, 0x24, 0xed, 0x00, 0x00, 0x03, 0x54, 0xca, 0x7c, 0x4a, + 0xfa, 0xe6, 0xc8, 0x40, 0x26, 0x05, 0x34, 0x56, 0x3b, 0x79, 0x50, 0xcf, 0x27, 0x43, 0x18, 0xb1, + 0xc0, 0x8a, 0xf1, 0x82, 0x94, 0x12, 0x71, 0xba, 0x16, 0x61, 0x76, 0x5c, 0x54, 0x36, 0x73, 0xc6, + 0x31, 0x89, 0x38, 0x20, 0x3f, 0x47, 0x1b, 0xb1, 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x76, 0x2c, + 0xa7, 0x93, 0xb3, 0x3a, 0x0e, 0xd7, 0x1c, 0x1f, 0xf4, 0x4b, 0x21, 0xd0, 0xc4, 0xe0, 0xcc, 0xef, + 0x91, 0x75, 0x3d, 0xa5, 0xb0, 0x40, 0xb3, 0xb9, 0x31, 0x00, 0x6e, 0x00, 0x00, 0x0d, 0x11, 0x8c, + 0xe6, 0x15, 0x6c, 0xb2, 0x90, 0x0e, 0xe8, 0xdc, 0xce, 0xd0, 0x62, 0xb0, 0x91, 0xbe, 0x4b, 0xbd, + 0x94, 0x45, 0x10, 0xa5, 0x09, 0x1f, 0x7f, 0x18, 0xbe, 0xf9, 0xc8, 0x0d, 0x8d, 0xd5, 0xf1, 0x5d, + 0x99, 0x2b, 0xb7, 0xa7, 0x00, 0x00, 0x00, 0xd8, 0x5e, 0x54, 0x19, 0xb5, 0xff, 0x6d, 0x16, 0xdd, + 0xfa, 0xf5, 0x7d, 0x1d, 0xbe, 0x3e, 0x7d, 0x91, 0xd9, 0xaa, 0x2a, 0xcd, 0xe0, 0x6a, 0x90, 0x8b, + 0xc8, 0x0c, 0xad, 0x60, 0xde, 0x00, 0xfd, 0xb4, 0x1c, 0x57, 0xe0, 0x1b, 0x7f, 0x56, 0x68, 0xd6, + 0x87, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x85, 0xcc, 0x33, 0xd3, 0x9e, 0x22, 0x68, 0x6b, 0xaf, 0xd6, + 0xa4, 0x58, 0xc7, 0xa3, 0xf3, 0x00, 0xe2, 0x5c, 0xf3, 0xf6, 0xdb, 0x75, 0xba, 0x17, 0xd3, 0xc1, + 0xaf, 0x7f, 0x00, 0x00, 0x00, 0x43, 0x84, 0xe7, 0xfc, 0x20, 0xd6, 0xee, 0xb0, 0xb9, 0xed, 0x0a, + 0xf0, 0xde, 0x63, 0x4a, 0xa1, 0x5a, 0x58, 0x07, 0xb1, 0x38, 0x42, 0x56, 0x56, 0xf7, 0xaa, 0x64, + 0x84, 0xab, 0x74, 0xc9, 0xc4, 0xa0, 0x09, 0xdd, 0x00, 0x00, 0x00, 0x03, 0x0d, 0x63, 0x4e, 0xbe, + 0xce, 0x98, 0xb5, 0x50, 0xae, 0x78, 0xc0, 0xb0, 0x5c, 0x0f, 0xca, 0x14, 0x15, 0x68, 0x01, 0x1f, + 0xc6, 0x0d, 0x51, 0x5f, 0x40, 0xe1, 0x48, 0xed, 0x2d, 0xe4, 0x64, 0xd2, 0x7e, 0x16, 0x99, 0x89, + 0x75, 0x25, 0x63, 0x66, 0x12, 0x08, 0xb4, 0x51, 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0xa6, 0x24, + 0x33, 0x99, 0xa3, 0x6b, 0xc6, 0x40, 0x4e, 0xf2, 0x28, 0x89, 0x9e, 0x2b, 0x8a, 0x6f, 0xe1, 0x1e, + 0x33, 0x5a, 0x70, 0x73, 0xb0, 0x05, 0xc7, 0xcc, 0xb7, 0x27, 0x00, 0x00, 0x00, 0x0b, 0x3f, 0x43, + 0x7c, 0xa0, 0x5d, 0x2e, 0x1f, 0x82, 0x46, 0x80, 0x39, 0xe0, 0xf3, 0x1a, 0x5f, 0x44, 0xc2, 0x81, + 0x92, 0xb1, 0xa3, 0xf6, 0x56, 0x71, 0x57, 0xf5, 0x30, 0xa1, 0x39, 0x74, 0xbb, 0x23, 0xd9, 0x1d, + 0x5c, 0x49, 0x00, 0x4b, 0xee, 0x8c, 0x85, 0xe2, 0x4c, 0x03, 0x1d, 0x7c, 0xc1, 0x88, 0x32, 0x63, + 0x36, 0xec, 0x9a, 0x8c, 0x20, 0xdc, 0xe8, 0x9c, 0x7d, 0x11, 0x80, 0xda, 0x23, 0xe6, 0x41, 0xfa, + 0x0c, 0x27, 0xa9, 0xb4, 0x8a, 0x26, 0xa9, 0x3c, 0x0b, 0x78, 0x4b, 0xc4, 0x84, 0xa2, 0x32, 0x83, + 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x96, 0x14, 0xa8, 0x0a, 0x97, 0xaf, 0xfe, 0xac, 0xa6, 0x0a, + 0xe1, 0x39, 0xca, 0xb8, 0x3a, 0x4f, 0x2b, 0xe3, 0x36, 0x00, 0x10, 0xcb, 0x27, 0xd9, 0xe2, 0x7c, + 0x79, 0xd0, 0x00, 0x00, 0x04, 0x7c, 0xe0, 0x82, 0xcc, 0x6e, 0x97, 0x2d, 0x88, 0x6e, 0x5b, 0xbd, + 0x20, 0x79, 0x51, 0xc5, 0x6f, 0xff, 0xad, 0xde, 0x5f, 0x02, 0x72, 0x31, 0x96, 0x2a, 0x7c, 0xaa, + 0x94, 0x32, 0x5c, 0xae, 0xa5, 0x49, 0x0b, 0x84, 0x0a, 0x00, 0x1d, 0xbc, 0x9d, 0x0f, 0x9e, 0xa3, + 0x1a, 0xe5, 0xe6, 0x00, 0xc0, 0xf2, 0xb6, 0x6e, 0x9e, 0xf5, 0x6b, 0x0c, 0xfd, 0x92, 0x6c, 0x01, + 0x87, 0xc8, 0x1f, 0xb3, 0x10, 0x81, 0x64, 0xb9, 0xb3, 0x71, 0xa5, 0x36, 0x42, 0x27, 0xdb, 0x79, + 0x41, 0x84, 0x07, 0x08, 0x49, 0xf5, 0x38, 0xae, 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x96, 0x3c, + 0xae, 0xf1, 0x98, 0x15, 0x69, 0xd4, 0x07, 0x00, 0x00, 0x29, 0xde, 0xff, 0x8b, 0xc6, 0x7b, 0x35, + 0xf8, 0x26, 0x07, 0x42, 0xe9, 0x0e, 0xf2, 0x5a, 0xdb, 0x75, 0xd8, 0xbd, 0x00, 0x21, 0xce, 0x65, + 0x8f, 0x1a, 0x4c, 0xfb, 0xcf, 0xaf, 0xba, 0x6d, 0xc4, 0x98, 0x48, 0xd8, 0xa8, 0xf5, 0x3a, 0xbe, + 0x01, 0xb6, 0x93, 0x98, 0x34, 0xae, 0x75, 0x79, 0x26, 0xa4, 0x44, 0xf1, 0x17, 0x4a, 0x2c, 0x6e, + 0x05, 0x29, 0x36, 0x4d, 0xe5, 0x23, 0xb9, 0xff, 0x5b, 0xa2, 0xcc, 0xfe, 0x06, 0x71, 0x48, 0x46, + 0x66, 0xae, 0x88, 0x67, 0x87, 0xa3, 0xd0, 0xb8, 0x67, 0xfa, 0x6f, 0x3a, 0xa2, 0x85, 0xa5, 0xa3, + 0xd5, 0xa5, 0x28, 0x10, 0xe3, 0xed, 0x5b, 0x11, 0x63, 0xa0, 0xb8, 0x1f, 0x1f, 0xdb, 0x47, 0x2c, + 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x66, 0x3c, 0x33, 0xd3, 0xb5, 0xb8, 0x9d, 0xe5, 0x92, 0xaa, + 0x00, 0x2a, 0x00, 0x06, 0x30, 0x9a, 0x3d, 0x97, 0xe8, 0x11, 0x6f, 0x8f, 0xeb, 0x98, 0xa1, 0xc5, + 0x00, 0x00, 0x00, 0xcc, 0x4d, 0x31, 0x19, 0xf2, 0x0a, 0x32, 0x12, 0x5e, 0xce, 0x61, 0xb6, 0x12, + 0xbd, 0xb0, 0xf3, 0xc6, 0xd2, 0xe9, 0x3c, 0xa0, 0x40, 0x98, 0x33, 0x39, 0x4f, 0xf4, 0x5c, 0xdd, + 0x5b, 0x17, 0x1e, 0x26, 0xe1, 0x15, 0xb2, 0xff, 0x2c, 0x00, 0x46, 0xe4, 0xc4, 0xe2, 0x07, 0x2e, + 0x4e, 0xbf, 0x0d, 0xc0, 0x7f, 0xde, 0x73, 0xc6, 0xb4, 0xb8, 0x04, 0xde, 0xb8, 0x16, 0xdb, 0x9e, + 0xa1, 0xa5, 0xd1, 0x25, 0x5b, 0x50, 0x0d, 0xf1, 0x4f, 0xc2, 0xd6, 0xc9, 0x83, 0x58, 0x18, 0x4d, + 0x26, 0x19, 0x1c, 0xa8, 0x0e, 0xd7, 0xcd, 0x38, 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x96, 0x1c, + 0x33, 0xd2, 0xc1, 0x91, 0x36, 0x06, 0x73, 0x74, 0x55, 0x63, 0x0f, 0x0d, 0xc6, 0xc5, 0x37, 0x32, + 0x23, 0x57, 0xa2, 0x52, 0x26, 0xe6, 0x0e, 0x44, 0xbd, 0xf7, 0xe2, 0x00, 0x01, 0x2f, 0x59, 0xed, + 0xea, 0x0b, 0xd5, 0xe1, 0x8c, 0x48, 0x5c, 0x76, 0xc5, 0x26, 0xcf, 0x00, 0x6a, 0x14, 0x55, 0xa5, + 0x7e, 0xef, 0xd8, 0xb0, 0xc1, 0x4a, 0xc1, 0x8f, 0x43, 0x7d, 0xb1, 0xef, 0x32, 0x78, 0x04, 0xfd, + 0x6a, 0xa2, 0x01, 0x16, 0xaf, 0x74, 0x19, 0xe8, 0xc1, 0xce, 0x9f, 0xe0, 0x43, 0xc8, 0x9c, 0xa9, + 0xd0, 0x6e, 0xb0, 0x29, 0xbb, 0x78, 0x31, 0xcc, 0x45, 0xb7, 0x4a, 0xff, 0x80, 0x53, 0xb9, 0x57, + 0x97, 0xe9, 0x60, 0xce, 0x5d, 0x26, 0x0c, 0xd6, 0xe3, 0xd2, 0xd1, 0x59, 0x68, 0x82, 0xd4, 0xc3, + 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x86, 0x14, 0xaa, 0x72, 0x28, 0x1c, 0x23, 0xca, 0x8d, 0x54, + 0x31, 0x9f, 0x7a, 0x0c, 0x0b, 0xf9, 0x00, 0x00, 0x13, 0x8d, 0x44, 0xaa, 0x44, 0x4a, 0x06, 0x00, + 0x00, 0x00, 0x02, 0x62, 0xc7, 0xf0, 0xf8, 0x6a, 0xbd, 0x1d, 0x75, 0x02, 0x11, 0x50, 0xcf, 0x51, + 0x7d, 0x12, 0xa8, 0xfe, 0x93, 0xad, 0x29, 0x0a, 0xbf, 0xbb, 0x3b, 0xf3, 0x63, 0x98, 0x6e, 0x85, + 0x73, 0xc1, 0x02, 0x41, 0x87, 0x9c, 0x53, 0xc7, 0x00, 0x57, 0x04, 0x4a, 0x78, 0xda, 0xcb, 0xe0, + 0xed, 0xe5, 0x3f, 0x3f, 0x8d, 0x1c, 0xc9, 0x28, 0xf5, 0x12, 0xcb, 0x34, 0x68, 0x30, 0x7c, 0xe6, + 0x86, 0xbd, 0xe0, 0x48, 0x40, 0x3f, 0xb5, 0x1f, 0x35, 0x6b, 0x32, 0x3b, 0x61, 0x6c, 0xe4, 0xde, + 0x81, 0x3a, 0x96, 0xc4, 0x20, 0xa9, 0xee, 0x87, 0x87, 0x98, 0x05, 0x3c, 0xf2, 0x79, 0x96, 0x3c, + 0x35, 0x1d, 0x6f, 0xd0, 0x0b, 0xbd, 0x6c, 0x0e, 0x54, 0x6a, 0xbe, 0xdd, 0x5b, 0x56, 0x75, 0x13, + 0xc7, 0x42, 0x28, 0x79, 0xc3, 0xfa, 0x0b, 0xc3, 0xaa, 0x5d, 0x99, 0x23, 0xe8, 0xdb, 0x04, 0x7a, + 0xd8, 0x78, 0x50, 0xab, 0x97, 0x12, 0xff, 0xa6, 0xf5, 0x85, 0xa9, 0xae, 0xd4, 0x57, 0xc2, 0x05, + 0x19, 0x3b, 0x6a, 0xac, 0x1b, 0x78, 0x10, 0xad, 0xde, 0x20, 0xc1, 0xa3, 0xdf, 0x57, 0xc4, 0x8f, + 0x2a, 0x00, 0x00, 0x02, 0x96, 0x4e, 0x79, 0x2b, 0xda, 0x72, 0x78, 0xdc, 0x3b, 0x03, 0x55, 0xd0, + 0xa3, 0xc1, 0xf2, 0x22, 0xee, 0x09, 0xf6, 0x72, 0x47, 0xf1, 0x57, 0x46, 0xd9, 0xc9, 0x0b, 0xa0, + 0xb9, 0x66, 0xaa, 0x7b, 0xea, 0x13, 0xc2, 0x08, 0x01, 0x66, 0x8f, 0xb3, 0x55, 0xe3, 0xe2, 0x89, + 0x85, 0xa6, 0xf0, 0xfe, 0xf2, 0x79, 0x86, 0x24, 0x33, 0x99, 0x9b, 0x83, 0xf8, 0x2a, 0x63, 0x47, + 0xa8, 0x98, 0xe4, 0x80, 0xf9, 0x98, 0x38, 0x29, 0x1a, 0xaf, 0x7e, 0xc1, 0x84, 0xfd, 0xc7, 0x07, + 0x8d, 0xc8, 0x92, 0x14, 0x00, 0x03, 0x50, 0xdf, 0xdd, 0x23, 0xc8, 0xd1, 0xa6, 0xb0, 0xa3, 0x10, + 0xd3, 0xe2, 0xdc, 0x57, 0x83, 0xd5, 0x84, 0xb3, 0x47, 0x04, 0x5b, 0xd2, 0xa9, 0xd1, 0xe3, 0xee, + 0xd3, 0x1c, 0x9c, 0xb1, 0x4f, 0xa0, 0x00, 0x00, 0x39, 0x21, 0xe6, 0x8b, 0xa3, 0xd9, 0xbf, 0x1c, + 0x03, 0x7e, 0x78, 0x7c, 0x39, 0x00, 0xe1, 0x70, 0x03, 0x34, 0x10, 0x6e, 0x42, 0xac, 0x8c, 0x40, + 0x4d, 0xe0, 0x71, 0x80, 0x54, 0x1d, 0x67, 0x43, 0x69, 0x34, 0x8a, 0x16, 0x78, 0x56, 0x85, 0xdd, + 0x91, 0x36, 0x51, 0x79, 0x6b, 0x6f, 0x7e, 0x8c, 0x85, 0xa6, 0xf0, 0xfe, 0xf2, 0x79, 0x96, 0x3c, + 0x35, 0x15, 0x1c, 0x7a, 0xf9, 0xb9, 0x15, 0xe0, 0xbb, 0xd6, 0x30, 0xcd, 0x56, 0x50, 0x2b, 0xc4, + 0x80, 0x2b, 0x4e, 0xa8, 0xd5, 0xf6, 0x54, 0x89, 0xbc, 0xbb, 0xc8, 0xfe, 0xa5, 0xd1, 0x00, 0x2d, + 0xcd, 0xb7, 0x7f, 0xd2, 0x26, 0x62, 0xff, 0xc4, 0x7e, 0xf3, 0x6f, 0xfe, 0x5c, 0x06, 0x09, 0xc2, + 0xf6, 0x16, 0x14, 0x4b, 0xaf, 0x70, 0xc8, 0x3b, 0xca, 0xed, 0x32, 0xb6, 0xff, 0x62, 0x16, 0x0b, + 0x57, 0x57, 0x01, 0x38, 0x00, 0x00, 0x9e, 0x5f, 0xc7, 0xf1, 0x08, 0x01, 0xb6, 0x9e, 0x5f, 0xfb, + 0x2e, 0xbf, 0x72, 0xd3, 0x6c, 0x14, 0x21, 0xfb, 0xa6, 0x0c, 0xa3, 0x7a, 0xa0, 0xe9, 0x91, 0xe7, + 0xa7, 0x90, 0xb3, 0x59, 0x84, 0x67, 0x0b, 0x94, 0x88, 0xce, 0x52, 0xd3, 0xfe, 0x67, 0x95, 0x92, + 0xa7, 0x96, 0x3c, 0xfc, 0xf2, 0x39, 0x76, 0x14, 0x65, 0xdb, 0x77, 0x74, 0x9b, 0xd1, 0x69, 0x04, + 0xa5, 0xab, 0x66, 0x61, 0x14, 0x5a, 0xc4, 0xc2, 0x97, 0x58, 0xb2, 0x79, 0x19, 0xe3, 0x67, 0xad, + 0x01, 0x95, 0x51, 0x52, 0x00, 0x01, 0x1a, 0x75, 0xd4, 0xa2, 0x96, 0x59, 0x20, 0x64, 0x25, 0x05, + 0x13, 0xdb, 0x41, 0xe0, 0x85, 0xa5, 0xb0, 0x6d, 0x5b, 0x3c, 0x6a, 0x4c, 0x6c, 0xa4, 0x4a, 0x66, + 0x37, 0x36, 0xa8, 0x1d, 0x4b, 0x1b, 0x17, 0x3c, 0x43, 0x00, 0x00, 0x0f, 0xf6, 0xf6, 0xb0, 0x3a, + 0xff, 0x2d, 0xc1, 0x2b, 0x8c, 0xf8, 0x20, 0x38, 0xb7, 0x83, 0x49, 0x13, 0x72, 0x58, 0xa3, 0xff, + 0x96, 0x2d, 0xd7, 0x2c, 0x60, 0xe6, 0x23, 0x13, 0xe9, 0x12, 0xdc, 0xc7, 0x29, 0x52, 0x97, 0x61, + 0x27, 0x07, 0x8d, 0xb7, 0x10, 0x12, 0x47, 0x34, 0xa5, 0xa6, 0xf0, 0xfe, 0xf2, 0x39, 0x86, 0x34, + 0x33, 0x99, 0xad, 0xf5, 0xb8, 0x20, 0x69, 0x36, 0xc3, 0x36, 0x38, 0x69, 0x6c, 0x55, 0x45, 0x82, + 0xc1, 0x47, 0xb5, 0x00, 0xe6, 0x9e, 0xec, 0x9f, 0xee, 0x9d, 0xda, 0xd3, 0x2b, 0x6e, 0xd8, 0x0b, + 0xa7, 0xab, 0xca, 0xf5, 0xe8, 0xd6, 0x02, 0xfb, 0xfe, 0xa3, 0x2b, 0x5f, 0x27, 0xa7, 0xd3, 0x6a, + 0x26, 0xfb, 0x88, 0x1c, 0xc5, 0xa4, 0xfa, 0x7f, 0x29, 0xfa, 0xd3, 0x67, 0x91, 0x97, 0xae, 0x84, + 0x47, 0x28, 0x00, 0x01, 0x0c, 0x1c, 0x69, 0x6f, 0xde, 0x2c, 0x8b, 0x31, 0x90, 0x4a, 0x1f, 0x06, + 0x39, 0x85, 0x14, 0x2f, 0xf2, 0x66, 0x4e, 0xff, 0x8a, 0xef, 0x13, 0x03, 0x84, 0xc1, 0x09, 0xb8, + 0x35, 0xd2, 0x8b, 0x54, 0xb9, 0x92, 0x86, 0xbe, 0xa8, 0xa5, 0x7c, 0x1c, 0x42, 0xcd, 0x35, 0x91, + 0xa5, 0xa6, 0xf0, 0xfe, 0xf2, 0x39, 0x86, 0x34, 0xaf, 0xde, 0xd3, 0xde, 0x29, 0xed, 0x28, 0x0d, + 0x99, 0xdd, 0xfa, 0x24, 0x1f, 0x60, 0x23, 0x8f, 0x5b, 0x2b, 0x71, 0x00, 0x00, 0x00, 0x18, 0xb9, + 0xe5, 0xc0, 0x40, 0x00, 0x04, 0x38, 0x27, 0x36, 0x94, 0xd7, 0x17, 0x8b, 0x70, 0x4c, 0x86, 0x34, + 0x7b, 0xef, 0x53, 0x59, 0x91, 0x66, 0x04, 0x41, 0xa7, 0x00, 0xcf, 0x10, 0x27, 0xf0, 0xdf, 0x0b, + 0xe1, 0xdb, 0xf8, 0x57, 0x3b, 0x2b, 0x02, 0x49, 0x2b, 0x98, 0x1f, 0x79, 0x70, 0x42, 0x2b, 0xac, + 0x12, 0x63, 0x0f, 0x91, 0x9c, 0xc0, 0x65, 0x85, 0xa5, 0x63, 0x2c, 0xb0, 0x4c, 0x3b, 0x98, 0x88, + 0x18, 0x71, 0x64, 0x0d, 0xdb, 0x8c, 0xeb, 0x07, 0xd4, 0x36, 0x0f, 0xd4, 0x30, 0x84, 0x61, 0x5c, + 0x1f, 0xd1, 0x8c, 0x7e, 0x0f, 0xdf, 0xb0, 0x9c, 0xa4, 0xa7, 0x0a, 0x7e, 0xf2, 0x39, 0x76, 0x34, + 0x33, 0xd7, 0x8c, 0x35, 0x71, 0x03, 0x71, 0x5c, 0x0e, 0x58, 0xb3, 0xc3, 0x3c, 0x24, 0x94, 0x53, + 0x0f, 0x65, 0x75, 0xd3, 0xbc, 0xae, 0x3c, 0x84, 0xde, 0x62, 0x00, 0x21, 0x7b, 0x79, 0x01, 0x6f, + 0xce, 0x47, 0x16, 0xd8, 0x82, 0x42, 0xe2, 0x1c, 0x52, 0x2e, 0xaf, 0x3b, 0xf7, 0xb5, 0x7f, 0xb9, + 0xd6, 0xe7, 0x8f, 0x84, 0x3f, 0xd2, 0x99, 0x4e, 0x15, 0xe1, 0x00, 0xcf, 0x2d, 0x30, 0x00, 0x1b, + 0x38, 0xa2, 0xc8, 0xeb, 0x02, 0x91, 0xdf, 0xfa, 0x7e, 0x00, 0x09, 0x17, 0x86, 0x70, 0x64, 0x95, + 0xa6, 0xb0, 0x5a, 0x5c, 0x18, 0xf1, 0x52, 0xa9, 0x09, 0x1e, 0xb5, 0x79, 0x35, 0x49, 0xe9, 0xb4, + 0xf5, 0xc7, 0x76, 0xea, 0x2c, 0x8f, 0x8e, 0x58, 0x17, 0xaa, 0x5e, 0xa8, 0x80, 0x7a, 0xdb, 0xf8, + 0xa5, 0xaf, 0x06, 0xfe, 0xf2, 0x39, 0x96, 0x34, 0x69, 0xad, 0x39, 0xda, 0x09, 0x4e, 0x4d, 0x05, + 0x63, 0x35, 0x94, 0xf7, 0x7d, 0xae, 0xdc, 0x29, 0x81, 0xb0, 0xdc, 0xae, 0x0f, 0x94, 0x17, 0x00, + 0xce, 0x1e, 0x72, 0x1b, 0x3d, 0x8b, 0xc9, 0x6a, 0x45, 0x35, 0x59, 0x23, 0x13, 0xf9, 0x28, 0x7b, + 0x2a, 0xb1, 0x88, 0xf3, 0x75, 0x67, 0x46, 0xe3, 0xb2, 0x07, 0x9e, 0xc9, 0x85, 0x55, 0x29, 0x05, + 0x2f, 0x7a, 0x1f, 0xe9, 0xed, 0x67, 0x1d, 0x0f, 0xbe, 0x00, 0x29, 0x71, 0xfc, 0xdb, 0xe3, 0x50, + 0x81, 0x10, 0x8d, 0x27, 0x30, 0x00, 0xcc, 0x63, 0x84, 0x3e, 0xd3, 0xd0, 0x61, 0xbd, 0xe2, 0x5b, + 0x5c, 0x0f, 0x9d, 0xd4, 0x69, 0x7e, 0x1f, 0x78, 0xf7, 0xaa, 0xad, 0xfb, 0x56, 0x92, 0xfe, 0x76, + 0x02, 0x38, 0xf6, 0x61, 0x13, 0x95, 0x07, 0x28, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x39, 0x76, 0x14, + 0x35, 0x16, 0xeb, 0x64, 0x8e, 0x38, 0x4c, 0x9d, 0xa2, 0x33, 0x03, 0x67, 0x77, 0x01, 0x8b, 0x94, + 0xda, 0x0d, 0xba, 0x85, 0xab, 0xbb, 0xa7, 0xcd, 0x52, 0xd2, 0x28, 0x48, 0xfd, 0x6a, 0x9e, 0xb3, + 0x97, 0x2a, 0x67, 0x7f, 0x61, 0x7a, 0xd3, 0xc2, 0x95, 0xbc, 0xf3, 0x13, 0xbb, 0x38, 0x2c, 0x5e, + 0xf5, 0x25, 0xd5, 0x35, 0xdd, 0x30, 0xbd, 0x47, 0x6d, 0x7a, 0xdf, 0xbe, 0xe5, 0xf8, 0x87, 0xaa, + 0x00, 0x05, 0x76, 0x4e, 0x2c, 0xfc, 0x61, 0x4a, 0x0a, 0xea, 0xa0, 0xef, 0xe0, 0xce, 0xfd, 0xb2, + 0xca, 0x73, 0xa2, 0x79, 0x6c, 0x79, 0x6b, 0x05, 0xb3, 0x26, 0xd0, 0x6e, 0x98, 0xac, 0x3f, 0x08, + 0xed, 0x75, 0x09, 0xeb, 0xd5, 0xb9, 0xee, 0xd7, 0xca, 0xbe, 0x37, 0xa8, 0x31, 0x09, 0x26, 0xc6, + 0xa5, 0xaf, 0x06, 0xfe, 0xf2, 0x39, 0x76, 0x24, 0x35, 0x7f, 0x23, 0xcf, 0x33, 0x12, 0xde, 0x3c, + 0x10, 0xbc, 0xd5, 0xab, 0xb5, 0x31, 0xde, 0x73, 0xa5, 0xcf, 0xe9, 0xcd, 0xd6, 0xd8, 0xf5, 0x87, + 0x44, 0x23, 0x15, 0x25, 0x51, 0x9e, 0xb2, 0x1f, 0xa3, 0x37, 0xe5, 0x08, 0x12, 0x97, 0xf7, 0x2f, + 0x22, 0x63, 0x53, 0x76, 0x8b, 0x95, 0x50, 0x02, 0x42, 0x2f, 0x94, 0xd5, 0x56, 0x61, 0xa7, 0xde, + 0xa8, 0xcd, 0x25, 0x49, 0x6b, 0xa8, 0x93, 0x33, 0xbd, 0x25, 0x79, 0x9a, 0x79, 0xb9, 0x97, 0xe4, + 0x09, 0xd1, 0x1f, 0xfa, 0x2f, 0xb0, 0x1f, 0x03, 0xc0, 0x79, 0xe0, 0x07, 0x2c, 0xaf, 0x7b, 0xb3, + 0xbf, 0x09, 0x0d, 0x0e, 0x57, 0x8f, 0x5d, 0xa7, 0x79, 0x52, 0x13, 0xf7, 0x24, 0x90, 0x26, 0x9e, + 0x6b, 0xb3, 0x9e, 0x06, 0x3c, 0x1f, 0xd1, 0x2c, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0x96, 0x3c, + 0xaf, 0xdd, 0xec, 0xcd, 0x0b, 0x42, 0x00, 0x00, 0x2e, 0x7a, 0x81, 0xcb, 0x68, 0x5f, 0x8b, 0x27, + 0x5a, 0x66, 0x42, 0x8b, 0xcb, 0xa7, 0xf2, 0x55, 0x8c, 0xf1, 0xbd, 0xff, 0xed, 0x97, 0x68, 0x26, + 0x8d, 0xdc, 0x19, 0x36, 0xc2, 0x4a, 0xa6, 0x3a, 0x55, 0xf0, 0x04, 0x2c, 0xa2, 0x72, 0xac, 0x64, + 0xe9, 0xf3, 0x1c, 0x9d, 0x2d, 0x41, 0xb7, 0x04, 0x2a, 0x28, 0x81, 0x41, 0x4b, 0xf5, 0xc6, 0x12, + 0x71, 0xb9, 0x3a, 0x2b, 0x7d, 0xaf, 0x12, 0xa3, 0xf1, 0xbc, 0x37, 0xb5, 0x78, 0xfe, 0x0f, 0x07, + 0xe1, 0xf1, 0x7f, 0x8d, 0x2e, 0x47, 0x5c, 0x3a, 0x11, 0xa8, 0x02, 0x8a, 0x1f, 0x6b, 0xa3, 0x1e, + 0xa5, 0xb3, 0x7b, 0x04, 0xcc, 0xf9, 0x05, 0xf6, 0xad, 0xe2, 0xe2, 0x27, 0x0f, 0x0f, 0xe5, 0xdc, + 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0x96, 0x3c, 0x64, 0x11, 0x5d, 0x4e, 0x5b, 0x2d, 0x0d, 0x23, + 0xf3, 0x0c, 0x6d, 0x9b, 0x66, 0x35, 0x84, 0xb9, 0x6e, 0x3d, 0x59, 0x00, 0x52, 0xfb, 0x2f, 0x5a, + 0x0d, 0x4e, 0x83, 0x36, 0xdb, 0x38, 0xa4, 0x8f, 0x17, 0x70, 0x3f, 0x1c, 0xd9, 0xba, 0xb5, 0x08, + 0x23, 0x42, 0xe0, 0xae, 0x6b, 0xb7, 0xcc, 0x59, 0xc4, 0xdb, 0xeb, 0xc6, 0x06, 0x8c, 0x3e, 0xfc, + 0xf5, 0x86, 0x6d, 0xf7, 0xc9, 0x28, 0xba, 0x5f, 0xee, 0x8f, 0x52, 0xb4, 0x9b, 0xa7, 0xe7, 0xdb, + 0x94, 0x55, 0x09, 0xbf, 0x72, 0x00, 0x7f, 0x00, 0x7e, 0x07, 0xe1, 0xc0, 0x9f, 0xd2, 0x34, 0xad, + 0x0c, 0xcc, 0xc5, 0x71, 0x48, 0x37, 0xfc, 0xaa, 0x0d, 0x1c, 0x8d, 0xf7, 0x4c, 0x98, 0x79, 0x3a, + 0xe7, 0xba, 0x6b, 0x21, 0xc7, 0x87, 0xf7, 0x2c, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0xa6, 0x3c, + 0x37, 0x6c, 0x53, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x4b, 0x8b, 0xf6, 0x32, 0x39, 0x48, 0x5b, 0x22, + 0x4f, 0x00, 0x00, 0x00, 0xff, 0x87, 0x00, 0x75, 0x5c, 0xf4, 0x0c, 0xd0, 0xec, 0x07, 0x73, 0x83, + 0x31, 0x29, 0xdd, 0x09, 0x57, 0xd3, 0x3c, 0xda, 0xa2, 0x04, 0xb9, 0xad, 0x13, 0xa8, 0x88, 0x84, + 0x87, 0x00, 0x7a, 0xbf, 0x83, 0x33, 0x15, 0xb1, 0xb0, 0xfd, 0x78, 0x12, 0x21, 0x3f, 0x1d, 0x6f, + 0x63, 0x17, 0x1f, 0xac, 0x1c, 0xec, 0x49, 0xfd, 0xa9, 0x85, 0x4f, 0x0d, 0x3d, 0x4f, 0xc0, 0xfc, + 0x3c, 0x0f, 0x0b, 0xf2, 0x04, 0x02, 0x90, 0xff, 0x07, 0x0a, 0x8b, 0x80, 0x71, 0x85, 0xc6, 0x69, + 0xb3, 0x10, 0xa1, 0xd2, 0xdb, 0x27, 0x48, 0xc5, 0x5b, 0xbb, 0xf1, 0xe8, 0x87, 0x3c, 0x3c, 0xd5, + 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0xa6, 0x3c, 0x35, 0x16, 0xad, 0x1b, 0x11, 0x11, 0x2c, 0x31, + 0x9b, 0x11, 0xa4, 0xb4, 0x21, 0x9f, 0x58, 0xa7, 0x69, 0x72, 0x41, 0xff, 0x6d, 0xd2, 0x08, 0x82, + 0x05, 0x1f, 0x5f, 0x56, 0xb5, 0x4f, 0x9c, 0xe6, 0x63, 0xf0, 0x5f, 0xf3, 0x59, 0x48, 0xba, 0x0f, + 0xba, 0x84, 0x33, 0x25, 0x9a, 0x6a, 0x3d, 0x78, 0x05, 0xbc, 0x2f, 0x04, 0xb7, 0x68, 0xac, 0x54, + 0x2b, 0x74, 0xed, 0x1f, 0xef, 0x85, 0x94, 0xd6, 0x82, 0x33, 0xae, 0xc1, 0x19, 0x5b, 0xed, 0x5d, + 0x93, 0x50, 0xac, 0xba, 0xcf, 0xc1, 0x1f, 0xe0, 0x3f, 0x03, 0xe3, 0xc4, 0x01, 0xd7, 0x00, 0xf6, + 0xdf, 0xa6, 0xb8, 0x30, 0x7a, 0xee, 0x1a, 0x36, 0x7f, 0x38, 0x94, 0xc2, 0x6c, 0xc5, 0xab, 0xbe, + 0xc7, 0x82, 0x6b, 0xc8, 0x61, 0xc5, 0xd6, 0xfe, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0xa6, 0x34, + 0xa7, 0x93, 0xab, 0x17, 0xbc, 0xeb, 0xc1, 0x81, 0x22, 0x09, 0x43, 0x88, 0x90, 0x6f, 0x57, 0xec, + 0x00, 0x00, 0x43, 0x7c, 0x81, 0xea, 0x88, 0x05, 0xb7, 0x66, 0xc1, 0x19, 0xc7, 0xb0, 0xbd, 0x0e, + 0x1f, 0x14, 0xc9, 0x40, 0x05, 0xab, 0x02, 0xdf, 0x36, 0x96, 0xec, 0x3c, 0x43, 0xe9, 0x48, 0xba, + 0x41, 0x77, 0x10, 0x1c, 0xc9, 0xa3, 0x68, 0xa4, 0x3c, 0xf0, 0xcd, 0x87, 0x12, 0xb2, 0xc4, 0xef, + 0xd0, 0x2d, 0x71, 0xe5, 0xe6, 0x4d, 0xbf, 0x17, 0xe1, 0x98, 0xc1, 0x4f, 0x60, 0x1f, 0xc0, 0x7e, + 0x07, 0xe0, 0xf8, 0x80, 0xba, 0xbc, 0x7d, 0xe4, 0x47, 0x11, 0xde, 0xe4, 0x65, 0xe1, 0x9b, 0xc0, + 0x7a, 0x3e, 0x40, 0x76, 0x3c, 0x94, 0xe3, 0x1d, 0x5e, 0x5a, 0x40, 0xdb, 0xe8, 0x18, 0x29, 0x7c, + 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0xb6, 0x34, 0x65, 0xca, 0x46, 0xb9, 0x0b, 0x52, 0x79, 0x41, + 0x19, 0xc3, 0x73, 0x41, 0x1c, 0x52, 0xc7, 0x42, 0xc6, 0xcc, 0x7f, 0xb4, 0xf0, 0x18, 0x20, 0x04, + 0x05, 0xc7, 0x3d, 0x84, 0x7a, 0x66, 0xbf, 0x9e, 0xb3, 0x80, 0xf8, 0x8c, 0xb8, 0x90, 0x9a, 0xc0, + 0x59, 0x00, 0x50, 0xa7, 0xf1, 0x3b, 0xf6, 0xbe, 0x59, 0xf8, 0x13, 0xae, 0x02, 0x45, 0xe9, 0xb5, + 0x3c, 0x3d, 0xa3, 0x50, 0xab, 0x50, 0x84, 0x22, 0xfa, 0xc3, 0xc7, 0x70, 0x15, 0x5a, 0x18, 0x73, + 0xae, 0xb3, 0xdb, 0x73, 0x9f, 0x71, 0x55, 0xfc, 0x03, 0xf0, 0x1f, 0x81, 0xc1, 0x4f, 0x75, 0xd8, + 0x5a, 0x3d, 0x42, 0xfc, 0xc3, 0x81, 0x58, 0x1a, 0xb3, 0x61, 0xf4, 0xa5, 0x5d, 0xbd, 0x1c, 0xd3, + 0x7e, 0xfe, 0xbc, 0xf4, 0x1c, 0xe7, 0xda, 0x55, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0x96, 0x3c, + 0x63, 0xc0, 0x39, 0x41, 0x09, 0x13, 0x33, 0xb4, 0x49, 0x82, 0x56, 0xb8, 0x0c, 0xaf, 0x54, 0x24, + 0x61, 0x6b, 0x00, 0x02, 0x55, 0xf8, 0x02, 0x36, 0x24, 0x97, 0x94, 0x17, 0x16, 0xff, 0xc5, 0x5a, + 0x22, 0x7c, 0x45, 0x25, 0xe0, 0x41, 0xe4, 0x40, 0xf9, 0x20, 0x3c, 0xe0, 0x48, 0xbe, 0xa1, 0x54, + 0xef, 0x5d, 0x3a, 0xfb, 0x00, 0xf2, 0x43, 0xda, 0x97, 0x91, 0x47, 0xeb, 0xaf, 0x0a, 0x51, 0x4e, + 0x1c, 0x1d, 0xe5, 0x97, 0x28, 0x4b, 0xa7, 0x23, 0xf4, 0x01, 0xac, 0x53, 0x22, 0x1c, 0xff, 0x07, + 0xf8, 0x0f, 0xc0, 0xfc, 0x1e, 0x02, 0x1d, 0xa7, 0xa3, 0x6b, 0x16, 0x58, 0x99, 0xd1, 0xd9, 0xd7, + 0x5a, 0x5c, 0x25, 0x4f, 0x1b, 0x83, 0x10, 0x9b, 0x65, 0x52, 0xc8, 0xaf, 0x76, 0x22, 0x1c, 0xde, + 0xa5, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0xb6, 0x3c, 0x65, 0xc6, 0xcd, 0x55, 0x50, 0x3d, 0x97, 0x82, + 0x9f, 0x19, 0x08, 0xd8, 0x1e, 0x75, 0xd2, 0x61, 0xc1, 0x35, 0x05, 0xfb, 0x13, 0xa6, 0x14, 0x63, + 0x87, 0x4d, 0x51, 0x0e, 0x16, 0x3b, 0x43, 0xaa, 0xc2, 0x72, 0xbf, 0x1f, 0x9c, 0xf5, 0xc1, 0x07, + 0xc2, 0xc5, 0xd2, 0x77, 0xe1, 0x39, 0xff, 0x43, 0x15, 0x29, 0x64, 0x5b, 0xa3, 0x44, 0x78, 0x93, + 0x88, 0xc1, 0x82, 0x3a, 0x25, 0x6d, 0x0c, 0xbc, 0x4b, 0xba, 0xca, 0xbe, 0xbb, 0x19, 0xe4, 0x8e, + 0x76, 0x0c, 0xe5, 0x8c, 0x8d, 0xcf, 0xe0, 0x7c, 0x3c, 0xc6, 0x0c, 0xfb, 0xdb, 0x2e, 0x16, 0x35, + 0x91, 0x51, 0x29, 0x18, 0x54, 0xad, 0x0b, 0x07, 0x76, 0x42, 0xd7, 0x55, 0x12, 0x6d, 0xce, 0x2f, + 0x7f, 0xe0, 0x78, 0xe0, 0xfe, 0xe6, 0xb2, 0x27, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x46, 0x3c, + 0xa7, 0x93, 0xab, 0x44, 0xbe, 0xa7, 0x80, 0x9c, 0xd3, 0xf8, 0xe1, 0x27, 0x07, 0x73, 0x64, 0x42, + 0xc1, 0x1d, 0x6c, 0x8b, 0xe3, 0xc5, 0x99, 0x2d, 0xf9, 0x62, 0x2e, 0xda, 0xf6, 0xb7, 0x19, 0x5a, + 0x06, 0x49, 0x62, 0x8f, 0x30, 0xe9, 0xb1, 0xc4, 0xd1, 0x09, 0x46, 0x15, 0xc2, 0xd6, 0x7e, 0x50, + 0xf7, 0xef, 0x31, 0x82, 0xef, 0xfb, 0xe2, 0xee, 0xd2, 0x20, 0xcb, 0xe4, 0x73, 0x7b, 0x49, 0x44, + 0x67, 0x23, 0x2e, 0xb8, 0x22, 0xa0, 0xd8, 0xe9, 0xbd, 0x30, 0x34, 0x65, 0x51, 0x6c, 0x01, 0xf7, + 0x80, 0x7e, 0x0f, 0x87, 0xc6, 0x78, 0xcf, 0x07, 0x77, 0x6c, 0x92, 0x63, 0xd6, 0xab, 0x53, 0xbd, + 0x59, 0x26, 0x10, 0xd2, 0xbe, 0xc8, 0x61, 0x41, 0xf0, 0x34, 0x63, 0xf1, 0x10, 0x4c, 0xaa, 0x2c, + 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0x86, 0x3c, 0xaa, 0x5a, 0xbb, 0xd7, 0xf8, 0xbb, 0x6f, 0xc4, + 0xc0, 0x30, 0x3e, 0x19, 0xe0, 0xf5, 0x55, 0x89, 0x37, 0x28, 0xd4, 0x29, 0x0d, 0x1f, 0xfa, 0xc2, + 0x00, 0x12, 0xad, 0x18, 0xd3, 0x85, 0x03, 0xd1, 0x26, 0xba, 0xc3, 0x95, 0x73, 0x0a, 0xff, 0x05, + 0x55, 0xee, 0x12, 0x41, 0x6d, 0x0c, 0x06, 0xf7, 0x01, 0x63, 0x20, 0xf6, 0xf5, 0x75, 0xcb, 0xf4, + 0x34, 0xf4, 0x0d, 0x55, 0x2e, 0x64, 0x61, 0x96, 0xc1, 0x14, 0x18, 0xf0, 0x06, 0xc1, 0x36, 0xa1, + 0xcb, 0xd5, 0x81, 0x08, 0xa3, 0x8a, 0xc0, 0x7f, 0x01, 0xf8, 0x3e, 0x0e, 0x47, 0x81, 0xc7, 0x8c, + 0xa3, 0xf0, 0x44, 0x41, 0x97, 0x61, 0xbd, 0x28, 0x73, 0x24, 0xa1, 0xfc, 0x76, 0x76, 0x57, 0x68, + 0x00, 0x00, 0x08, 0xc3, 0xc1, 0x08, 0xa3, 0x8e, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0x96, 0x3c, + 0x69, 0xb1, 0xb3, 0x14, 0xc6, 0x0a, 0xef, 0xfa, 0x49, 0x55, 0xc7, 0xd6, 0xd6, 0x6f, 0xca, 0x4d, + 0x80, 0x0c, 0x07, 0x98, 0xef, 0xb9, 0xdd, 0xf0, 0x2c, 0x72, 0xfb, 0x82, 0x00, 0xc4, 0xf9, 0x7a, + 0x77, 0x18, 0xf7, 0x13, 0xcd, 0x32, 0x82, 0x84, 0xf3, 0xde, 0x5d, 0xee, 0xec, 0x4a, 0x5a, 0xca, + 0xcd, 0xe0, 0xbe, 0x24, 0xd0, 0xcf, 0xfa, 0xa2, 0x60, 0x8a, 0x57, 0xa1, 0x74, 0x0e, 0xe1, 0xf9, + 0xc5, 0xe7, 0x75, 0x25, 0xe2, 0x19, 0xb8, 0xab, 0x49, 0xea, 0xe3, 0x48, 0x22, 0x98, 0x7e, 0x0f, + 0x81, 0xf1, 0xc1, 0x70, 0xe7, 0xc4, 0xea, 0x0e, 0x16, 0xd8, 0xfb, 0xb9, 0x93, 0x5c, 0x6d, 0x54, + 0x08, 0x7e, 0xc7, 0x90, 0xb6, 0xe5, 0xa7, 0x1f, 0xf1, 0xea, 0xcf, 0xc7, 0xf1, 0xea, 0x71, 0x4c, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, 0x66, 0x71, 0x12, 0xfb, 0xfc, 0xc3, 0xd6, 0xee, + 0x81, 0x60, 0xf5, 0x11, 0x13, 0x17, 0xd4, 0xe0, 0x47, 0x5f, 0x2b, 0x34, 0x69, 0x01, 0x01, 0xfa, + 0xe3, 0x71, 0x62, 0xd5, 0xfd, 0xc6, 0xad, 0xa8, 0xa1, 0x71, 0x0d, 0x50, 0x8b, 0x5f, 0x94, 0xa9, + 0xc6, 0x7b, 0xea, 0x99, 0x12, 0x7b, 0xcf, 0x33, 0xe1, 0x70, 0x52, 0x96, 0x14, 0xb9, 0xb6, 0x56, + 0x20, 0xcf, 0x88, 0x7a, 0x3c, 0x00, 0xf5, 0x8d, 0x82, 0xdc, 0x0c, 0xc0, 0x57, 0xfd, 0xb5, 0xb5, + 0x59, 0x4f, 0xd7, 0xde, 0xa0, 0x3e, 0x03, 0xf0, 0x7c, 0x38, 0x2f, 0x82, 0x4a, 0x02, 0x18, 0xcf, + 0xca, 0xe8, 0xd2, 0x49, 0xee, 0x11, 0x96, 0x2e, 0x8a, 0x02, 0xf1, 0x62, 0x10, 0x78, 0x87, 0x8e, + 0x41, 0x1f, 0x08, 0xc1, 0xa7, 0x11, 0xc5, 0xfc, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, + 0xaf, 0xa6, 0xc8, 0x17, 0xa3, 0x84, 0xdd, 0xa9, 0x0a, 0x0e, 0x89, 0xbc, 0x1f, 0xf0, 0x65, 0x09, + 0x6a, 0x1d, 0x56, 0x2f, 0xf0, 0xcd, 0xa6, 0xba, 0xcb, 0xa2, 0x5d, 0xcf, 0xe8, 0x89, 0x91, 0x7d, + 0x62, 0x41, 0x4e, 0xf4, 0x85, 0xf9, 0x49, 0xeb, 0xaa, 0x66, 0xb7, 0xd9, 0x79, 0x47, 0xfd, 0x78, + 0x49, 0x3b, 0x68, 0x11, 0xfb, 0xee, 0x8a, 0x55, 0x05, 0x04, 0x35, 0xb7, 0x0d, 0x1a, 0xe3, 0xdd, + 0x59, 0xbe, 0xf7, 0xfc, 0x1a, 0xac, 0x1c, 0x3d, 0x70, 0xce, 0xfe, 0x98, 0x40, 0xd7, 0x0f, 0xd0, + 0x7e, 0x1f, 0x0c, 0x1c, 0x32, 0xbe, 0x5f, 0x1a, 0xc2, 0xab, 0xfc, 0xb0, 0xbd, 0x6c, 0x64, 0xf5, + 0x7f, 0x9b, 0xd3, 0x42, 0x77, 0x73, 0xe2, 0x04, 0xdc, 0xf5, 0x7f, 0x9e, 0x3e, 0xdc, 0x61, 0xd7, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, 0x66, 0x6e, 0xc7, 0xba, 0x0b, 0x00, 0x5e, 0x7e, + 0x17, 0x39, 0xe6, 0x76, 0xdb, 0x13, 0xa6, 0x5b, 0x1a, 0x16, 0x1c, 0x88, 0x6f, 0x59, 0x98, 0xe0, + 0x7e, 0x5d, 0xe7, 0xd0, 0xb9, 0x93, 0xdd, 0xf9, 0x87, 0xc2, 0x84, 0xf1, 0xab, 0x86, 0x07, 0x37, + 0x72, 0x2b, 0xcb, 0xb4, 0xe6, 0x9b, 0x62, 0x26, 0x81, 0xde, 0xae, 0xf2, 0x4a, 0x5d, 0xf8, 0xb8, + 0xaa, 0xfa, 0x96, 0x1c, 0x54, 0x35, 0x43, 0xfe, 0xda, 0xeb, 0xc7, 0x9d, 0x8f, 0xbf, 0xc6, 0xb5, + 0x87, 0x7a, 0xc3, 0x90, 0x02, 0x4e, 0xb0, 0x3f, 0x03, 0xf0, 0x78, 0x79, 0x1f, 0x8e, 0x15, 0x14, + 0xa1, 0xae, 0x84, 0x3b, 0x09, 0x62, 0x15, 0x7c, 0x50, 0xf7, 0x78, 0xed, 0x72, 0x41, 0x63, 0xcf, + 0xb3, 0xf0, 0xb0, 0x08, 0x70, 0x26, 0x49, 0xd6, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x2c, + 0x69, 0xd5, 0x7a, 0x69, 0x80, 0x89, 0x16, 0x0e, 0x00, 0x8e, 0xdd, 0xe8, 0xba, 0x4a, 0xb8, 0xd4, + 0x9f, 0x71, 0xd7, 0x2a, 0xd2, 0xf5, 0x0c, 0xc3, 0x4f, 0xfb, 0x22, 0x11, 0x30, 0xb1, 0x93, 0x21, + 0x19, 0x9a, 0xb8, 0x73, 0x51, 0x9e, 0x2a, 0x77, 0x0f, 0x61, 0xbb, 0x18, 0x26, 0x3a, 0x10, 0x35, + 0x4a, 0xa3, 0x35, 0x10, 0x92, 0x56, 0xf5, 0xf5, 0x6e, 0xb8, 0x73, 0x7f, 0xf7, 0x78, 0xd2, 0x36, + 0x2e, 0x72, 0xfa, 0x9d, 0x7a, 0xdd, 0xe3, 0x6a, 0x0e, 0x47, 0x06, 0xa3, 0x23, 0x9f, 0x60, 0x7c, + 0x0f, 0x87, 0x99, 0x1e, 0x63, 0x8f, 0x66, 0xc4, 0x31, 0x76, 0x2d, 0x6a, 0x06, 0xc4, 0xd0, 0x4d, + 0x39, 0x53, 0x65, 0x85, 0x6c, 0xd7, 0x65, 0xdd, 0xf9, 0xa6, 0xf2, 0x18, 0x18, 0x9c, 0x8a, 0xd5, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, 0xaf, 0xae, 0x7f, 0x37, 0x7c, 0x7e, 0xc8, 0x66, + 0x0c, 0xdb, 0xf9, 0x2a, 0xd1, 0xdc, 0x4b, 0xd9, 0xa3, 0x2d, 0xb4, 0x03, 0xae, 0x50, 0x54, 0x60, + 0xdb, 0xbe, 0x75, 0xe2, 0xb8, 0x20, 0xee, 0x0d, 0x6f, 0x53, 0xaf, 0xce, 0x03, 0x41, 0xc2, 0xc2, + 0xbb, 0xd5, 0x1f, 0xb8, 0x7f, 0x2c, 0xad, 0x56, 0x3b, 0x9b, 0xd7, 0xc9, 0xfc, 0xaf, 0x0a, 0x43, + 0x4c, 0xa2, 0xde, 0x6d, 0xf0, 0x57, 0x61, 0x8a, 0x55, 0x0b, 0x3c, 0x37, 0xbc, 0xf5, 0x9f, 0xda, + 0x35, 0xf9, 0x86, 0x34, 0xd4, 0x57, 0x30, 0x7f, 0x07, 0x83, 0xe1, 0xc0, 0x3e, 0x44, 0x81, 0x64, + 0x89, 0x31, 0xd2, 0xa8, 0x04, 0xe1, 0x52, 0x99, 0x84, 0x7b, 0x8b, 0x4d, 0x00, 0x92, 0x95, 0x49, + 0x52, 0x69, 0x84, 0xf8, 0xc7, 0x9a, 0x89, 0xe7, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x56, 0x3c, + 0x33, 0xd2, 0xb4, 0x9f, 0x05, 0xe1, 0xfa, 0x45, 0x00, 0x6f, 0x0a, 0x22, 0x3e, 0x60, 0xae, 0xcf, + 0xa0, 0x2f, 0xfc, 0xb6, 0xa8, 0x52, 0x88, 0x72, 0x12, 0xbe, 0xe9, 0xf3, 0xdc, 0xca, 0xa7, 0xe4, + 0xdd, 0x5a, 0x49, 0x6b, 0x42, 0x48, 0xc7, 0xde, 0x5b, 0x86, 0xf8, 0xd1, 0xc3, 0x56, 0x13, 0x97, + 0x12, 0x80, 0x6b, 0xab, 0x24, 0x24, 0x85, 0xb5, 0x76, 0x41, 0x3a, 0xeb, 0xa4, 0x51, 0xfd, 0x78, + 0x00, 0xd0, 0xa4, 0x3c, 0x79, 0xce, 0x54, 0xc2, 0x36, 0x15, 0x99, 0x46, 0xe7, 0x23, 0x00, 0x7f, + 0x01, 0xe0, 0xf8, 0x78, 0x37, 0xe3, 0x44, 0xf0, 0xc0, 0x24, 0xd0, 0xc9, 0x9c, 0x03, 0xe4, 0x7f, + 0x96, 0x92, 0x05, 0x40, 0xdf, 0xdf, 0x5c, 0xe6, 0xd3, 0xb9, 0xb8, 0x09, 0x04, 0x3b, 0x9c, 0x8c, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x76, 0x3c, 0xaa, 0x72, 0x73, 0xe5, 0x5b, 0x51, 0x7c, 0xb3, + 0x87, 0x46, 0x40, 0x43, 0xe4, 0x19, 0x48, 0x8a, 0xe9, 0x8c, 0x51, 0x10, 0x86, 0x49, 0x47, 0x2b, + 0xdc, 0x88, 0x66, 0xe1, 0x44, 0x5c, 0x6e, 0x7b, 0xcd, 0x5d, 0xb6, 0x3b, 0xb2, 0xd5, 0x9f, 0x93, + 0xd0, 0x94, 0xef, 0xe0, 0x13, 0x33, 0x83, 0xa1, 0x37, 0xb6, 0xc8, 0xc7, 0x15, 0xdb, 0xbf, 0xac, + 0x97, 0xaa, 0x34, 0xe2, 0x45, 0x35, 0xaf, 0x75, 0x67, 0xf1, 0x7a, 0x71, 0xa6, 0xd1, 0x73, 0xdf, + 0x9f, 0x72, 0x46, 0xf8, 0x20, 0xfe, 0x07, 0xc1, 0xf8, 0x3c, 0x1f, 0xc7, 0x06, 0xc5, 0xe4, 0x52, + 0xd2, 0x6f, 0x92, 0x73, 0x58, 0x22, 0xbb, 0xda, 0x8d, 0xc1, 0xa4, 0xf4, 0xa8, 0x4f, 0x5a, 0xb1, + 0x90, 0x29, 0x48, 0x66, 0x47, 0x8d, 0x3a, 0x0c, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x2c, + 0xaf, 0xdd, 0x47, 0x5c, 0xbe, 0xa2, 0xfd, 0xbc, 0xa0, 0x77, 0xc9, 0x9e, 0x7b, 0xc3, 0x7e, 0x20, + 0xd5, 0x15, 0x36, 0xfd, 0x0d, 0xbd, 0xf2, 0x45, 0xb9, 0x05, 0x4f, 0x58, 0xe0, 0xe6, 0x09, 0x9a, + 0x6a, 0xf0, 0xdc, 0x35, 0x0d, 0xe7, 0x80, 0x71, 0xff, 0x81, 0x7f, 0x77, 0xc4, 0xd4, 0x30, 0x13, + 0xdc, 0x3a, 0x2f, 0x79, 0x06, 0x88, 0x87, 0xe1, 0xb9, 0x0c, 0x54, 0xb7, 0xa9, 0xf8, 0x38, 0xed, + 0xa1, 0x82, 0xdd, 0x87, 0xfd, 0x51, 0x3b, 0xe4, 0x1b, 0xb1, 0x30, 0x4e, 0xb7, 0x9e, 0x03, 0xfc, + 0x3e, 0x07, 0xc3, 0xec, 0x43, 0xb8, 0xb3, 0x8d, 0x19, 0xc6, 0x43, 0x27, 0x8f, 0x09, 0x63, 0xe5, + 0xc4, 0x07, 0x41, 0x6f, 0x13, 0x00, 0x79, 0xdd, 0x09, 0x27, 0xde, 0xc4, 0x71, 0x4b, 0xf7, 0xbc, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x56, 0x3c, 0xaa, 0x55, 0xb7, 0x24, 0x58, 0x31, 0x2f, 0x97, + 0x1f, 0x7f, 0x50, 0x76, 0x2c, 0x74, 0x2d, 0xf6, 0xd9, 0xdb, 0xbd, 0x07, 0x39, 0xb5, 0x5a, 0xed, + 0x8d, 0xdc, 0x64, 0x0c, 0x5b, 0x27, 0xc7, 0x96, 0xf2, 0xfc, 0x31, 0x3d, 0x42, 0x39, 0x15, 0x6a, + 0x6b, 0x9d, 0x6e, 0xaf, 0x1e, 0x9a, 0x9c, 0x38, 0x0f, 0xe3, 0x9e, 0xec, 0xd5, 0xed, 0x41, 0x3c, + 0xf8, 0x11, 0xb0, 0x5e, 0x42, 0x46, 0x77, 0xde, 0xb3, 0x5c, 0xd0, 0xba, 0x83, 0xa8, 0xf0, 0x34, + 0x96, 0x44, 0x95, 0xee, 0xfc, 0x07, 0xf0, 0x1f, 0x81, 0xf0, 0xfc, 0x41, 0xfb, 0x1f, 0x47, 0xf8, + 0xcf, 0xef, 0xce, 0xef, 0xaf, 0x96, 0xdf, 0x00, 0x58, 0x72, 0x83, 0xdb, 0x24, 0x20, 0x01, 0xef, + 0x9f, 0x44, 0xb9, 0xa4, 0xe2, 0x91, 0x94, 0xec, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, + 0x66, 0x6e, 0xc7, 0xe6, 0x2e, 0x32, 0x8e, 0x22, 0x9e, 0x55, 0x80, 0x61, 0xe0, 0x8a, 0xa5, 0x3f, + 0x95, 0xe0, 0x55, 0x60, 0x2e, 0xba, 0xaa, 0x4e, 0xd2, 0xfa, 0x76, 0x7c, 0x31, 0xcd, 0x9a, 0xd4, + 0xfc, 0x7d, 0xd3, 0xd3, 0x8c, 0x33, 0x03, 0x2d, 0x76, 0x18, 0xfb, 0x43, 0x89, 0x31, 0xd6, 0x02, + 0xa0, 0x6d, 0x55, 0x10, 0xe8, 0xae, 0x37, 0xe5, 0x60, 0x47, 0xcf, 0xf7, 0x22, 0x25, 0xe6, 0xf7, + 0xcb, 0x99, 0x6d, 0x2d, 0xdb, 0x02, 0x69, 0x16, 0x15, 0x56, 0x6b, 0x07, 0xb1, 0x69, 0xf3, 0x80, + 0xfc, 0x07, 0xf0, 0x7c, 0x70, 0xe6, 0xfd, 0x75, 0x86, 0x94, 0x6b, 0xf8, 0x28, 0x5b, 0x49, 0xf8, + 0x74, 0xc2, 0xba, 0x58, 0xc7, 0x55, 0xb8, 0xc9, 0x9e, 0x2f, 0xfc, 0x03, 0x0f, 0xe2, 0xd3, 0xce, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, 0xaa, 0x6f, 0x07, 0xbb, 0x3f, 0xd8, 0x79, 0x25, + 0x03, 0x41, 0x4e, 0x0b, 0x33, 0x5a, 0x0b, 0x82, 0x3d, 0xae, 0xe8, 0x10, 0x72, 0xb5, 0x7b, 0x96, + 0xe7, 0xd0, 0xc0, 0x40, 0x2f, 0x17, 0x6a, 0x9e, 0xbd, 0xe2, 0x7f, 0xbb, 0x36, 0x3a, 0xb9, 0x0f, + 0x7f, 0x96, 0xf2, 0xfe, 0x0b, 0x12, 0xe9, 0xca, 0xe8, 0x2f, 0x0f, 0x1e, 0x27, 0xf6, 0x80, 0x27, + 0x01, 0x37, 0x81, 0xfe, 0x86, 0x2a, 0x0e, 0x79, 0x90, 0x70, 0xf5, 0xe4, 0xe9, 0x8e, 0x3c, 0x79, + 0xff, 0x3f, 0xf1, 0xc9, 0x02, 0x0b, 0xf1, 0x1f, 0x81, 0xf0, 0x3e, 0xc1, 0xe1, 0x72, 0x33, 0xaf, + 0x29, 0xd5, 0x37, 0x5e, 0x2b, 0x97, 0xdc, 0x9a, 0x12, 0x5c, 0xaf, 0x19, 0x79, 0x9f, 0xa0, 0xef, + 0x02, 0x66, 0xbf, 0x03, 0x82, 0x96, 0x5a, 0xf1, 0x71, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x56, 0x2c, + 0x66, 0x71, 0x55, 0x28, 0xc7, 0xcb, 0x12, 0xbc, 0x67, 0x7c, 0x14, 0xa5, 0xed, 0x35, 0x49, 0x59, + 0x92, 0xd0, 0x51, 0x5d, 0xf1, 0x08, 0x93, 0x64, 0x87, 0xe2, 0x37, 0xe7, 0x02, 0xb8, 0x39, 0xd9, + 0xef, 0xb3, 0x82, 0xd5, 0x1b, 0x32, 0xaa, 0xc6, 0x89, 0x03, 0x80, 0x1c, 0xd4, 0x95, 0x85, 0xc5, + 0xeb, 0x0e, 0x7a, 0x53, 0x7b, 0xfb, 0x24, 0xed, 0x64, 0x1a, 0xe0, 0x87, 0xb8, 0xe5, 0xcf, 0xbe, + 0x6c, 0x17, 0xf2, 0xd6, 0x02, 0x6e, 0x78, 0xa0, 0xc9, 0xfd, 0x8e, 0xd0, 0x00, 0x3f, 0x80, 0xf8, + 0x7e, 0x1f, 0x01, 0x83, 0xe7, 0x04, 0xf8, 0x8c, 0xf0, 0xb5, 0x6f, 0x92, 0xff, 0x8c, 0x32, 0xf8, + 0x12, 0xba, 0xad, 0x59, 0x59, 0x9d, 0x25, 0x6a, 0x6c, 0x4c, 0x81, 0x04, 0xf7, 0x9e, 0xce, 0x80, + 0x71, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x34, 0x65, 0xc9, 0xf7, 0x20, 0x2d, 0xee, 0x82, 0xd8, + 0x1b, 0xb4, 0x62, 0x09, 0x60, 0x29, 0xa1, 0xe1, 0x0d, 0xa7, 0x29, 0xab, 0x31, 0x41, 0x5d, 0x5b, + 0x6c, 0xdf, 0x28, 0xd1, 0x8f, 0x35, 0xa7, 0x24, 0x46, 0xaf, 0x3d, 0xf8, 0xb1, 0xc8, 0x97, 0x1b, + 0x15, 0xae, 0xc8, 0x97, 0x73, 0x95, 0x1d, 0x45, 0x8b, 0xc9, 0x51, 0xeb, 0x9e, 0x15, 0x5d, 0xc4, + 0x20, 0x6b, 0x11, 0x03, 0x23, 0xb9, 0x7d, 0x95, 0xe5, 0x4a, 0x8b, 0x03, 0x69, 0x3c, 0x1f, 0xbe, + 0x8e, 0xf6, 0xe8, 0x93, 0xb3, 0x07, 0xe0, 0x7e, 0x07, 0x81, 0xe0, 0xf1, 0xc7, 0xcc, 0xc3, 0xb1, + 0x6f, 0x14, 0x01, 0x4d, 0xd9, 0x3c, 0xf1, 0x06, 0x1f, 0x35, 0x98, 0x90, 0xaf, 0x1f, 0x19, 0x61, + 0x82, 0x33, 0xfd, 0xe0, 0xa1, 0x0a, 0x62, 0x63, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x56, 0x3c, + 0x63, 0xbe, 0x62, 0x88, 0xda, 0xfc, 0x1e, 0x11, 0x29, 0x0c, 0xe5, 0x1b, 0xe5, 0x41, 0xba, 0xb3, + 0xcf, 0x4a, 0xda, 0xa2, 0x7e, 0x6d, 0x8b, 0xf8, 0xfc, 0xf1, 0x9e, 0x17, 0x6c, 0x9d, 0x19, 0xdd, + 0x81, 0x15, 0xa4, 0x32, 0x73, 0x7e, 0xba, 0xc3, 0x7d, 0x0b, 0xbc, 0x10, 0x11, 0x2f, 0x5f, 0xed, + 0xad, 0xc7, 0x7c, 0x0a, 0xc1, 0xb3, 0xef, 0x0a, 0xec, 0x13, 0x08, 0x9e, 0x12, 0x64, 0xce, 0xf8, + 0xe8, 0x23, 0xf6, 0x67, 0xac, 0x53, 0x50, 0xdc, 0x4a, 0xfc, 0xc3, 0xc0, 0x92, 0x0b, 0x2b, 0xf8, + 0x1f, 0xc1, 0xfc, 0x0f, 0x0f, 0x38, 0xf8, 0x91, 0xa0, 0x10, 0x29, 0x4c, 0xb2, 0xd0, 0x3d, 0x2a, + 0x06, 0xbc, 0x8b, 0x82, 0x18, 0x90, 0x62, 0x7f, 0x67, 0x7e, 0x75, 0xc1, 0xf5, 0x2c, 0x82, 0xc3, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x76, 0x3c, 0x65, 0xdb, 0x69, 0x4c, 0x00, 0x13, 0x80, 0x00, + 0xa5, 0x3d, 0x13, 0x89, 0x11, 0xac, 0x4b, 0x54, 0xdf, 0x73, 0xd1, 0x09, 0x20, 0xc5, 0xd0, 0xd5, + 0x16, 0x47, 0xd8, 0x32, 0x19, 0x4c, 0xa9, 0x7b, 0xb5, 0x42, 0x72, 0x3c, 0x77, 0x89, 0xad, 0xbc, + 0xc0, 0x34, 0xdd, 0xb3, 0x24, 0x80, 0x12, 0x92, 0x8b, 0x8c, 0x31, 0xe9, 0x75, 0x5d, 0x72, 0xc9, + 0x27, 0x0f, 0x5c, 0xc0, 0xb4, 0xbe, 0x67, 0xa3, 0xcc, 0x0f, 0x48, 0x47, 0xbd, 0x9b, 0x05, 0x1c, + 0xbc, 0xa6, 0x41, 0x21, 0x8c, 0x51, 0x78, 0x0f, 0xc0, 0xfc, 0x3f, 0x87, 0xe3, 0x0e, 0x0e, 0xba, + 0xad, 0x50, 0x32, 0xf1, 0x76, 0xa4, 0xf9, 0x0c, 0x36, 0xc1, 0xdd, 0xbc, 0xbf, 0x68, 0x70, 0x01, + 0xc4, 0xe4, 0x17, 0xe2, 0x12, 0x28, 0xc5, 0x9f, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, + 0x35, 0x0a, 0x9e, 0x71, 0xc2, 0xab, 0x24, 0xaf, 0x16, 0xa5, 0x65, 0x01, 0x3c, 0x0e, 0x39, 0x42, + 0x75, 0xf5, 0x02, 0xf0, 0x1a, 0xf6, 0xec, 0xa3, 0x9d, 0xda, 0x93, 0x3d, 0x5f, 0xa8, 0x95, 0xa8, + 0xd0, 0xc3, 0x2c, 0xa8, 0x3a, 0x02, 0x84, 0x45, 0x79, 0x0a, 0x6f, 0x0f, 0x3c, 0xae, 0x11, 0x18, + 0xd9, 0xfe, 0xf6, 0x1c, 0xb0, 0xe0, 0x09, 0x42, 0xd7, 0xe4, 0xec, 0xd2, 0x47, 0xd4, 0xf6, 0xd7, + 0x6e, 0xe3, 0xdf, 0x4e, 0xa0, 0xd7, 0xb3, 0xaa, 0xf6, 0x28, 0x1a, 0xbb, 0x01, 0xc3, 0xaf, 0xc0, + 0xfe, 0x03, 0xf0, 0x7e, 0x3e, 0x70, 0x7c, 0x66, 0x21, 0xe9, 0x30, 0x96, 0xae, 0x2e, 0x1c, 0x3c, + 0xcc, 0x68, 0xec, 0xb1, 0x25, 0x1f, 0xed, 0xaf, 0xeb, 0xd8, 0x89, 0x3c, 0x27, 0x62, 0x38, 0xb1, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, 0xaf, 0xd8, 0x66, 0x50, 0x91, 0xce, 0x6e, 0x00, + 0x93, 0x92, 0xf8, 0x3f, 0x41, 0xce, 0x85, 0xf2, 0xea, 0x59, 0x43, 0x74, 0x9f, 0x02, 0x89, 0x7c, + 0xae, 0xc0, 0x18, 0x11, 0x3d, 0x87, 0x63, 0xe9, 0x07, 0xe0, 0xe7, 0x0b, 0x24, 0x7b, 0x46, 0xb2, + 0x3b, 0x4b, 0x21, 0xa9, 0x3e, 0x9b, 0xaa, 0x34, 0x12, 0xa5, 0xbb, 0x35, 0x52, 0xcc, 0x1f, 0xf2, + 0x15, 0x35, 0x3d, 0xa9, 0x0b, 0xd4, 0xbc, 0xbc, 0x06, 0x48, 0x40, 0x53, 0x29, 0x4d, 0x96, 0x1f, + 0xdc, 0x41, 0x94, 0xd4, 0x06, 0x0f, 0xc1, 0xf1, 0xe1, 0xc4, 0x47, 0xc0, 0xf2, 0xb8, 0x9c, 0xc0, + 0x18, 0x92, 0xe2, 0x92, 0x79, 0x25, 0x6a, 0x4e, 0x5c, 0xa5, 0x43, 0x03, 0x9d, 0x56, 0x9e, 0x04, + 0x0c, 0x47, 0xc3, 0x07, 0x86, 0x7d, 0x51, 0xb0, 0x71, 0x72, 0x90, 0x4e, 0xf2, 0x19, 0x36, 0x3c, + 0xaf, 0xde, 0xd9, 0x76, 0xbf, 0xd7, 0xe9, 0x42, 0x20, 0x1c, 0xba, 0xc5, 0xd2, 0x84, 0x1a, 0xc9, + 0xfe, 0xe0, 0xa4, 0x27, 0x91, 0x41, 0x2c, 0x90, 0x21, 0x2f, 0x13, 0xa4, 0x90, 0x44, 0x9c, 0xe3, + 0x21, 0x0b, 0x2f, 0x1b, 0x7a, 0x7c, 0x3d, 0x4b, 0xf1, 0x4d, 0x92, 0x96, 0xea, 0xbe, 0x8b, 0xa2, + 0x21, 0xad, 0x9a, 0x4f, 0x38, 0xb1, 0xe6, 0x7b, 0x70, 0xe0, 0x53, 0xf4, 0xbb, 0x30, 0xf4, 0xa4, + 0xc8, 0x9c, 0x64, 0x84, 0xb5, 0x79, 0xb3, 0x29, 0x8a, 0x99, 0xc4, 0x2c, 0x0e, 0xb8, 0x70, 0xfe, + 0x0f, 0xfc, 0x42, 0x32, 0x6f, 0x4b, 0x8d, 0x8a, 0x00, 0xc9, 0x86, 0x90, 0xbf, 0x0d, 0x82, 0xc1, + 0x3c, 0xc6, 0x77, 0xaa, 0xcc, 0x84, 0xeb, 0xb7, 0xe3, 0x4b, 0xf7, 0x93, 0x88, 0x32, 0x99, 0xf8, + 0x91, 0x72, 0x90, 0x4e, 0xf2, 0x39, 0x26, 0x24, 0x69, 0xd4, 0x3b, 0x66, 0x16, 0x03, 0x00, 0x90, + 0x22, 0x40, 0xfa, 0x1a, 0x04, 0x41, 0xa5, 0xc1, 0xf6, 0xa7, 0x21, 0xd0, 0x0c, 0x43, 0x97, 0x96, + 0x55, 0x0d, 0x1c, 0x01, 0xb6, 0x85, 0x74, 0x0a, 0x78, 0xf3, 0x9b, 0x7c, 0x18, 0x8f, 0x6a, 0x0f, + 0x08, 0x89, 0xbe, 0x3b, 0x7e, 0xe1, 0x0e, 0x27, 0xa2, 0xea, 0xad, 0x9c, 0xcf, 0xd9, 0x4b, 0x40, + 0x73, 0x35, 0x6b, 0xcb, 0x5e, 0x0e, 0xff, 0x17, 0x3c, 0x44, 0x6d, 0xdc, 0x26, 0xbf, 0x28, 0x96, + 0xb2, 0x8d, 0x8d, 0x9e, 0x7d, 0xca, 0x82, 0x51, 0xf0, 0x79, 0xf0, 0xf9, 0x3e, 0x07, 0xff, 0x6c, + 0x30, 0xe9, 0xaf, 0xab, 0x1f, 0x91, 0x02, 0xd7, 0x94, 0xbe, 0x82, 0x8a, 0x58, 0xb6, 0x2c, 0x06, + 0x09, 0x88, 0xfb, 0x99, 0xe3, 0xfd, 0x96, 0xa5, 0x91, 0x72, 0x90, 0x4e, 0xf2, 0x19, 0x56, 0x3c, + 0xaa, 0x55, 0xb7, 0x24, 0x66, 0x3c, 0xcb, 0xe6, 0x01, 0x0d, 0x56, 0xf4, 0x3f, 0x74, 0xbf, 0xfb, + 0x3b, 0x05, 0xdf, 0xcd, 0x00, 0x00, 0x00, 0x00, 0xdd, 0xd3, 0x47, 0x59, 0x30, 0x43, 0xb7, 0x3c, + 0xb8, 0x17, 0xd4, 0x51, 0xe1, 0xa4, 0xb0, 0x52, 0xa9, 0x13, 0xd9, 0xf3, 0x04, 0x48, 0xe2, 0x65, + 0xa7, 0xbb, 0xa8, 0x3c, 0xe1, 0xe7, 0x72, 0x3e, 0x8f, 0x0d, 0xc2, 0x88, 0x6b, 0x25, 0x07, 0x6a, + 0x3c, 0x9b, 0xb7, 0x4e, 0xd7, 0x40, 0x21, 0x03, 0xa6, 0xbb, 0x01, 0x14, 0x4d, 0x59, 0xaf, 0x07, + 0xf0, 0x78, 0x3e, 0x0f, 0xb0, 0x3f, 0x07, 0x2e, 0xca, 0xe0, 0x35, 0xb8, 0x63, 0x37, 0x46, 0xce, + 0x97, 0xb8, 0xcb, 0x3a, 0xce, 0x3e, 0x5b, 0xf9, 0xb6, 0xb2, 0x83, 0x30, 0x70, 0x45, 0x4d, 0xb8, + 0x91, 0x72, 0x90, 0x4e, 0xf2, 0x19, 0x66, 0x3c, 0x69, 0xd4, 0xd7, 0x0f, 0x56, 0xb8, 0x0a, 0x16, + 0xd2, 0xa2, 0x0a, 0xd6, 0x86, 0x63, 0x1d, 0xf5, 0x79, 0x28, 0x93, 0x0f, 0x2e, 0x60, 0x7a, 0x0b, + 0x85, 0x00, 0x03, 0x59, 0x79, 0x93, 0xfb, 0xa4, 0x95, 0xbe, 0xd3, 0x99, 0x09, 0x31, 0x6d, 0xb1, + 0x92, 0xa6, 0x2e, 0x08, 0x89, 0x6a, 0xd8, 0x42, 0x39, 0x62, 0x22, 0x42, 0x9e, 0xb7, 0x0b, 0xbf, + 0xdf, 0xf9, 0xa7, 0x55, 0x5a, 0x0e, 0x93, 0xbe, 0x39, 0x71, 0xb0, 0x97, 0x5d, 0x4f, 0x8e, 0x97, + 0x98, 0xae, 0xd8, 0x3e, 0x94, 0xea, 0x7e, 0x0f, 0x87, 0xe0, 0xe1, 0x8f, 0xe0, 0xff, 0x8e, 0x7d, + 0xc7, 0x5d, 0x99, 0xec, 0x13, 0xf8, 0x27, 0x05, 0x8a, 0x01, 0xb1, 0xd8, 0x84, 0xa4, 0xbd, 0x59, + 0xc6, 0xf6, 0xfe, 0xf7, 0x0e, 0x4d, 0xb4, 0xa8, 0x71, 0x72, 0x90, 0x4e, 0xf2, 0x19, 0x56, 0x3c, + 0xaa, 0x6f, 0xa2, 0xf5, 0xd8, 0xb5, 0x5e, 0xbd, 0x40, 0x81, 0xb1, 0x5e, 0x70, 0x21, 0xab, 0x00, + 0x00, 0x00, 0x00, 0xcd, 0xb9, 0xa5, 0x00, 0xed, 0xc7, 0xf5, 0xf3, 0x79, 0xa1, 0x72, 0xa6, 0xf4, + 0x97, 0x3a, 0x66, 0xf0, 0x06, 0x52, 0xce, 0x4d, 0x40, 0xb0, 0xd7, 0x56, 0x11, 0x36, 0xeb, 0x5f, + 0x76, 0x0e, 0x27, 0x89, 0x4f, 0x90, 0x4e, 0x5f, 0xa4, 0xbb, 0x65, 0x18, 0x7f, 0xbe, 0x5d, 0x33, + 0x3b, 0xf0, 0xee, 0xf3, 0x0c, 0xab, 0x98, 0x21, 0x4f, 0x7f, 0xa8, 0xbd, 0x67, 0xfe, 0x03, 0xf8, + 0x1f, 0xe0, 0x3e, 0x1c, 0x78, 0xc0, 0xfd, 0x3f, 0x79, 0x8b, 0x5c, 0xd1, 0xc2, 0x51, 0x43, 0x45, + 0x1b, 0x0e, 0xeb, 0x9c, 0xc7, 0x1d, 0x54, 0x4d, 0x75, 0x75, 0x30, 0xe8, 0xfc, 0x3c, 0x52, 0xb3, + 0x96, 0xeb, 0x66, 0xaf, 0x72, 0x19, 0x96, 0x3c, 0xaa, 0x6f, 0x27, 0x9f, 0x71, 0x1f, 0xaf, 0xb1, + 0xb2, 0xaa, 0x21, 0x2b, 0x65, 0x0b, 0xb4, 0x98, 0x0f, 0xad, 0x8e, 0x7b, 0xa1, 0xa9, 0x01, 0xf6, + 0x5c, 0x20, 0xcb, 0x10, 0x89, 0x09, 0xdc, 0x57, 0xb2, 0x77, 0x20, 0xc5, 0xa8, 0xd1, 0x2d, 0xa8, + 0xee, 0x9f, 0x47, 0xeb, 0x5e, 0x25, 0x31, 0x90, 0x6b, 0x53, 0x5e, 0x40, 0xda, 0xce, 0x70, 0xc5, + 0x6c, 0xb2, 0xee, 0x9e, 0xfa, 0x48, 0x07, 0x91, 0xdf, 0x85, 0x52, 0x46, 0xc9, 0xd0, 0x4f, 0xb7, + 0xb4, 0xe8, 0x1a, 0x4e, 0xab, 0x03, 0x9e, 0x3e, 0x00, 0x1c, 0x08, 0x5d, 0x0d, 0xa9, 0x97, 0xe4, + 0x32, 0x30, 0x6f, 0x4a, 0xab, 0x3d, 0x4a, 0x09, 0x0a, 0x98, 0xc3, 0x60, 0x4f, 0xb8, 0x7d, 0x0e, + 0x88, 0xb4, 0x68, 0x82, 0xa0, 0x03, 0x5d, 0x9c, 0x96, 0xeb, 0x66, 0xaf, 0x72, 0x39, 0x56, 0x2c, + 0x65, 0xd9, 0x97, 0x01, 0xee, 0x4a, 0x66, 0x11, 0x45, 0x5b, 0xde, 0x86, 0xac, 0xba, 0x65, 0xf1, + 0x3f, 0x56, 0x54, 0x05, 0x5a, 0x39, 0x00, 0x3e, 0x79, 0x2f, 0xbb, 0xcd, 0x63, 0x69, 0xa5, 0x45, + 0x64, 0xab, 0xfe, 0xc9, 0x8f, 0xf9, 0x25, 0xb1, 0x69, 0x21, 0x4b, 0x7f, 0xbb, 0x5c, 0x6b, 0x30, + 0x21, 0xdb, 0x98, 0x32, 0x9e, 0x9f, 0xe5, 0xf3, 0x11, 0x60, 0xeb, 0xc6, 0xcb, 0x74, 0x72, 0xd0, + 0x1c, 0x94, 0xd4, 0xe6, 0xf0, 0x05, 0x5b, 0x02, 0xa4, 0x9f, 0xea, 0x44, 0xb8, 0x0d, 0xf4, 0x73, + 0x08, 0x3c, 0xce, 0x29, 0xf0, 0xb5, 0xe0, 0x48, 0x13, 0xab, 0x4a, 0x47, 0x89, 0xb1, 0x33, 0x8a, + 0xc7, 0xae, 0x39, 0xee, 0xbb, 0x65, 0xb9, 0xe2, 0xa0, 0x72, 0x6e, 0x3e, 0xa0, 0x33, 0x56, 0xa6, + 0x96, 0xeb, 0x66, 0xaf, 0x72, 0x39, 0x76, 0x34, 0x65, 0x57, 0x24, 0xfc, 0x7e, 0x20, 0x8e, 0xb5, + 0x9b, 0x37, 0x73, 0x06, 0x19, 0x9a, 0x84, 0x40, 0x00, 0xeb, 0x19, 0x30, 0xd1, 0x54, 0xd5, 0x11, + 0x6d, 0xaa, 0xac, 0xd6, 0xb9, 0x08, 0xd7, 0x79, 0x4f, 0x4d, 0xe8, 0x27, 0x5b, 0xe1, 0xe6, 0x41, + 0x7b, 0xd4, 0x30, 0x66, 0xc3, 0x67, 0x28, 0x70, 0xaf, 0x1b, 0xcc, 0x6b, 0x7b, 0x12, 0x2a, 0xe6, + 0xfa, 0x7e, 0x23, 0xb9, 0x24, 0x56, 0x92, 0x3b, 0x42, 0xc3, 0xb4, 0x2a, 0x22, 0x3d, 0xae, 0xfb, + 0x8d, 0x73, 0xb5, 0x20, 0x18, 0x5f, 0x63, 0x02, 0x75, 0x91, 0x7d, 0x16, 0xa5, 0xfd, 0x20, 0xe9, + 0x27, 0x80, 0x13, 0xdc, 0xaa, 0xc1, 0x4d, 0xcc, 0x99, 0x00, 0xf8, 0x48, 0x30, 0x2c, 0xb0, 0xa4, + 0x3c, 0x0b, 0x08, 0xbf, 0x63, 0x3d, 0x61, 0xa8, 0xb6, 0xeb, 0x66, 0xaf, 0x72, 0x39, 0x66, 0x34, + 0x63, 0xb3, 0xbd, 0x96, 0xb3, 0x4d, 0xd2, 0xf2, 0xee, 0xa4, 0x40, 0x95, 0x46, 0x7d, 0x46, 0x9e, + 0xa5, 0x6f, 0x5c, 0xe2, 0xfc, 0x70, 0xcf, 0xe0, 0x25, 0xe2, 0x44, 0x10, 0x05, 0x8a, 0xe9, 0xe9, + 0x43, 0xcc, 0x0d, 0x4c, 0x47, 0x14, 0x97, 0xac, 0xf5, 0x79, 0x36, 0x9d, 0xb7, 0xfd, 0xbe, 0xda, + 0x64, 0xa2, 0x70, 0x09, 0x52, 0x83, 0xf9, 0x91, 0xfa, 0x8b, 0x47, 0xd1, 0x2d, 0xee, 0xf4, 0xd9, + 0x41, 0xd9, 0xb2, 0x99, 0xf0, 0x0a, 0x93, 0x8c, 0x30, 0x27, 0xb0, 0x05, 0xfc, 0x58, 0x30, 0x5a, + 0x3f, 0x46, 0x13, 0x90, 0x9a, 0x29, 0x53, 0x60, 0xae, 0x82, 0xad, 0xc1, 0x2b, 0x27, 0x6a, 0x4f, + 0x3e, 0xeb, 0x9b, 0x6e, 0x34, 0x6a, 0x48, 0xf1, 0xb7, 0x33, 0x5a, 0x00, 0x3a, 0x11, 0x4e, 0xea, + 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x66, 0x3c, 0xb6, 0x91, 0xd0, 0xbc, 0x85, 0xad, 0x1c, 0xc1, + 0xc5, 0x74, 0xa3, 0x65, 0x58, 0x79, 0x04, 0x76, 0x1a, 0xba, 0x32, 0xcd, 0xc3, 0xbc, 0x10, 0x62, + 0x17, 0x92, 0x1a, 0x73, 0xac, 0x21, 0xa4, 0xc1, 0x08, 0xc1, 0xfd, 0x0e, 0x4a, 0x33, 0xf2, 0xe8, + 0xfd, 0xab, 0x37, 0x23, 0x66, 0x9d, 0x84, 0xad, 0xa6, 0xc3, 0xf7, 0x8c, 0x0e, 0x73, 0x01, 0x0e, + 0x23, 0xb8, 0x6d, 0x19, 0x5c, 0xed, 0xaf, 0x76, 0xf7, 0x83, 0x0d, 0x7e, 0x89, 0x98, 0x1c, 0x5b, + 0x99, 0x95, 0xb7, 0xe0, 0x48, 0xcf, 0xa0, 0xc6, 0x10, 0x44, 0x89, 0x24, 0xb5, 0x79, 0xc4, 0xfc, + 0xa1, 0xc2, 0x3b, 0x41, 0x53, 0x89, 0xad, 0xce, 0x3e, 0x39, 0xb2, 0x92, 0xea, 0x36, 0xda, 0x4a, + 0xc9, 0x52, 0xc0, 0x19, 0xd9, 0x2a, 0x7d, 0x1e, 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x45, 0xe4, + 0x6e, 0xba, 0xba, 0xbc, 0xf5, 0x92, 0xd9, 0x00, 0x2d, 0x18, 0x51, 0x21, 0x42, 0x93, 0x43, 0xce, + 0x38, 0xfb, 0x80, 0x6f, 0x6f, 0x0d, 0x0b, 0x9f, 0xdc, 0x9e, 0x09, 0xb4, 0x68, 0x96, 0xbb, 0x25, + 0x36, 0xe6, 0x05, 0x3b, 0x83, 0xc4, 0x7c, 0x97, 0x04, 0xf0, 0xf0, 0x31, 0x12, 0x53, 0x28, 0xf5, + 0x3a, 0xb3, 0x4b, 0x50, 0xbc, 0xf6, 0x58, 0x53, 0xe1, 0x94, 0xe2, 0xe0, 0xec, 0x61, 0x35, 0x73, + 0x6c, 0xc2, 0xb6, 0x4b, 0xa6, 0x12, 0x7d, 0x28, 0xbc, 0x29, 0x02, 0x74, 0x71, 0x41, 0xeb, 0xe1, + 0xa5, 0x68, 0xbe, 0xac, 0xde, 0xcf, 0x1a, 0x25, 0x79, 0x66, 0x4f, 0x68, 0xdb, 0xb0, 0x67, 0x7f, + 0xc2, 0xfa, 0x52, 0x88, 0xf8, 0x11, 0x75, 0x0c, 0x37, 0x9b, 0x3c, 0x4d, 0xe2, 0x48, 0x17, 0xa6, + 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x56, 0x3c, 0xaf, 0xe4, 0xa2, 0x89, 0x12, 0x82, 0x0c, 0x29, + 0xbf, 0x24, 0x3d, 0xce, 0x5e, 0x00, 0x0c, 0xb4, 0xea, 0xf0, 0x83, 0x87, 0x99, 0xd9, 0xda, 0xbb, + 0xe1, 0x31, 0xa9, 0x85, 0xd1, 0xdc, 0x6e, 0xff, 0xba, 0xb1, 0xfd, 0x54, 0x95, 0x64, 0xbb, 0x8f, + 0x9e, 0x6f, 0x2a, 0x8a, 0x85, 0xd5, 0xef, 0x6f, 0x2a, 0xdb, 0xb9, 0x1e, 0x90, 0xd0, 0x3d, 0xb3, + 0xb4, 0xd5, 0x21, 0xf7, 0xcc, 0xa0, 0x56, 0x37, 0xd2, 0x04, 0xac, 0xa6, 0xba, 0x35, 0x9b, 0xf8, + 0x54, 0x4f, 0x56, 0x8e, 0x03, 0xba, 0xb7, 0xbe, 0x42, 0xc4, 0x8b, 0xf1, 0x3b, 0x97, 0x91, 0x6e, + 0xa9, 0x3b, 0x56, 0x63, 0x21, 0xe4, 0x32, 0x00, 0x40, 0x49, 0x96, 0x2d, 0x2f, 0x42, 0x1f, 0xce, + 0x9e, 0x2b, 0x45, 0x5f, 0xba, 0x22, 0x4f, 0x66, 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x66, 0x2c, + 0x65, 0xca, 0x4a, 0x9e, 0x20, 0x90, 0xd5, 0xeb, 0xdf, 0xb8, 0x17, 0x31, 0xd9, 0x80, 0x30, 0x3b, + 0x26, 0xd8, 0xa2, 0xbd, 0x5b, 0x02, 0x22, 0x53, 0x50, 0x98, 0xa5, 0x6a, 0x9b, 0x17, 0xd8, 0x89, + 0x3e, 0xf7, 0x00, 0x3d, 0x93, 0xeb, 0x5c, 0x37, 0x12, 0x20, 0x94, 0x6d, 0x2c, 0x0d, 0xcc, 0x20, + 0x04, 0x55, 0xa2, 0x73, 0xbb, 0xc0, 0xaa, 0x95, 0xa2, 0x02, 0x52, 0x9c, 0xf6, 0xb2, 0xd0, 0xc9, + 0xd4, 0x8d, 0xcf, 0xfe, 0xee, 0xa6, 0xc9, 0xf4, 0xd2, 0xd3, 0xca, 0xf8, 0x88, 0x0d, 0xf3, 0xcd, + 0x90, 0xff, 0x03, 0x3e, 0xb9, 0x22, 0x9f, 0x5b, 0x67, 0x40, 0xc7, 0x86, 0x67, 0xba, 0xf2, 0x10, + 0x6a, 0x38, 0xbc, 0x8f, 0x6a, 0x35, 0x69, 0xbf, 0xda, 0xeb, 0xbf, 0x41, 0x56, 0x71, 0x55, 0x4f, + 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x56, 0x34, 0xb6, 0x90, 0xce, 0x2f, 0x9f, 0xa6, 0x39, 0xdb, + 0x76, 0xc2, 0x48, 0x94, 0x8c, 0xd3, 0xc2, 0xc0, 0xde, 0xa3, 0x37, 0xc0, 0x1c, 0x11, 0x2c, 0x9b, + 0x06, 0x3a, 0xbf, 0x47, 0x64, 0x38, 0x2c, 0x56, 0x2b, 0x5d, 0x1d, 0xf6, 0x6e, 0xd3, 0x62, 0x89, + 0x10, 0x2b, 0x5d, 0x15, 0x48, 0x2f, 0x03, 0xa8, 0x07, 0xf3, 0x78, 0xcd, 0xb9, 0xb8, 0xce, 0xe7, + 0x69, 0x39, 0x3c, 0x13, 0x14, 0xd6, 0xb8, 0x8c, 0xe0, 0xcd, 0x8a, 0x23, 0x15, 0x89, 0x83, 0x31, + 0x3a, 0x0c, 0x95, 0xc0, 0xe9, 0xbf, 0x9f, 0xbd, 0x05, 0x61, 0x67, 0xe3, 0x3f, 0x10, 0x9a, 0x29, + 0x72, 0x3c, 0x5a, 0x38, 0xe0, 0xf4, 0x9a, 0x59, 0x9f, 0xd5, 0x44, 0x62, 0xcd, 0xed, 0x00, 0x78, + 0xc2, 0x1c, 0x7c, 0x47, 0xf4, 0xb3, 0x55, 0x13, 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x56, 0x0c, + 0xaf, 0xe5, 0x67, 0xb2, 0x9d, 0xfd, 0x91, 0xaf, 0x74, 0xcd, 0xd3, 0x13, 0x5c, 0xa8, 0x96, 0x7b, + 0x63, 0x82, 0xa3, 0x3f, 0x19, 0xa9, 0xd5, 0xc7, 0x7c, 0x3c, 0x64, 0x11, 0x80, 0x9b, 0xbc, 0x11, + 0x43, 0xf3, 0x6a, 0x02, 0xb4, 0x70, 0x52, 0x0f, 0xeb, 0xf0, 0x41, 0x9f, 0x15, 0x9e, 0xf5, 0xd7, + 0x72, 0x98, 0x4b, 0x06, 0x1a, 0x74, 0x8f, 0x29, 0x1f, 0x0d, 0x38, 0xf7, 0xea, 0xd8, 0xa4, 0x3e, + 0x37, 0xba, 0x03, 0xa9, 0xef, 0x6d, 0x0b, 0x1b, 0x48, 0x97, 0xd7, 0x76, 0x06, 0x66, 0xf0, 0x7d, + 0x2b, 0xe4, 0x56, 0x38, 0x87, 0x5d, 0xb6, 0x00, 0x64, 0x55, 0xe5, 0x31, 0x11, 0xa1, 0xac, 0x9c, + 0x88, 0x28, 0x04, 0xae, 0x9d, 0x14, 0xc5, 0x61, 0x9d, 0x11, 0x54, 0x3e, 0xb3, 0x46, 0x61, 0x0d, + 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x76, 0x34, 0x66, 0x57, 0xfe, 0x3a, 0x35, 0x14, 0xf0, 0x24, + 0x07, 0x8c, 0x8c, 0x9b, 0xdb, 0x06, 0xd7, 0x4c, 0x45, 0xf2, 0x1e, 0x75, 0x12, 0x9a, 0x0e, 0x66, + 0xbe, 0xb8, 0x15, 0x6c, 0x4c, 0xfc, 0x8a, 0x98, 0xac, 0xc0, 0xb0, 0x9c, 0x9a, 0x68, 0xd2, 0xab, + 0x41, 0x7d, 0xb4, 0x82, 0x2c, 0x8f, 0x0f, 0x93, 0xf4, 0xfa, 0x4d, 0x87, 0x76, 0xea, 0x45, 0xe6, + 0x66, 0x05, 0xe3, 0x09, 0x0e, 0x56, 0xf8, 0x16, 0xd6, 0x7e, 0x8f, 0xde, 0x9a, 0x61, 0x67, 0xbd, + 0xe3, 0x77, 0xb9, 0x73, 0x7b, 0xf2, 0x3f, 0x38, 0x88, 0x29, 0x36, 0x88, 0x84, 0x0c, 0x10, 0xd8, + 0x80, 0x6d, 0xbc, 0x26, 0xc8, 0x2c, 0xdd, 0x68, 0xfe, 0x2b, 0x23, 0x73, 0xd2, 0x38, 0x54, 0x63, + 0xc6, 0x57, 0xc7, 0xfe, 0x7e, 0xf7, 0xac, 0xab, 0xb1, 0x2d, 0x5a, 0x8e, 0xf2, 0x39, 0x35, 0x84, + 0xaf, 0xa7, 0x15, 0x3e, 0x78, 0xcd, 0x36, 0xc0, 0x19, 0x4c, 0x1d, 0x8d, 0x0b, 0xc6, 0x83, 0x8e, + 0xcc, 0xc7, 0xb7, 0x14, 0x15, 0x87, 0x95, 0x8b, 0xfb, 0xac, 0x9b, 0xdd, 0x72, 0xdf, 0xef, 0xfe, + 0x15, 0xc7, 0xce, 0xcc, 0xb4, 0x51, 0x23, 0xea, 0x70, 0x2e, 0x1b, 0x60, 0x3e, 0x70, 0x01, 0xb6, + 0xa4, 0xe9, 0xb7, 0x1c, 0x32, 0x64, 0xe3, 0xea, 0x57, 0x1c, 0x65, 0x7f, 0xfd, 0x05, 0x8c, 0xae, + 0x96, 0x79, 0x53, 0x17, 0x42, 0xbf, 0xfd, 0x35, 0x27, 0x6e, 0x3b, 0xd0, 0xb3, 0x3f, 0x90, 0x03, + 0xc4, 0x4a, 0xf3, 0x5a, 0x0f, 0x39, 0xb2, 0x65, 0x8e, 0x4f, 0x0a, 0xb8, 0xfb, 0x03, 0x3e, 0x4f, + 0x8d, 0xf1, 0xa6, 0x2d, 0x8d, 0x85, 0x25, 0x72, 0xe2, 0xcb, 0xec, 0xf7, 0xe1, 0x98, 0xef, 0xe6, + 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x76, 0x2c, 0xaf, 0xde, 0xd3, 0xde, 0x29, 0xec, 0xcb, 0xa8, + 0xa4, 0xa7, 0xdb, 0x9f, 0x13, 0xaa, 0x7c, 0xff, 0x2e, 0x7d, 0x26, 0x00, 0xb7, 0xa0, 0x49, 0x04, + 0x6b, 0x78, 0x0b, 0xfe, 0x7c, 0x8c, 0x2c, 0x86, 0x78, 0x04, 0x92, 0xa5, 0x06, 0x05, 0x40, 0xe5, + 0x5f, 0xe8, 0x5e, 0x1b, 0x4b, 0x53, 0x6e, 0xe4, 0x52, 0xeb, 0x96, 0x18, 0x33, 0xa7, 0x3a, 0xf5, + 0x59, 0xa8, 0xb3, 0x81, 0x20, 0xd7, 0x88, 0x92, 0x6a, 0xdb, 0x6e, 0x81, 0xe5, 0x47, 0xda, 0x84, + 0x83, 0x9a, 0x9e, 0x5e, 0x78, 0x8c, 0x12, 0xf0, 0xc0, 0x35, 0x03, 0x58, 0x3f, 0xec, 0x8f, 0xb7, + 0xe8, 0x74, 0xa6, 0xfb, 0xd1, 0xa2, 0xe2, 0x20, 0x18, 0x86, 0x03, 0x22, 0x43, 0x46, 0x23, 0x76, + 0x22, 0x2f, 0x38, 0x83, 0xdb, 0x90, 0xd3, 0x13, 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x56, 0x3c, + 0x69, 0x22, 0xe4, 0xca, 0x53, 0x96, 0xc7, 0x1b, 0xed, 0xf3, 0x0a, 0xc8, 0xfc, 0x00, 0x5d, 0xa2, + 0x8c, 0x2b, 0x14, 0x70, 0x6d, 0x84, 0x76, 0x1e, 0x00, 0xcc, 0x13, 0xdb, 0xf3, 0x48, 0xbd, 0x79, + 0x77, 0x56, 0x2e, 0x91, 0x75, 0x37, 0x14, 0x9f, 0x29, 0x9a, 0x4f, 0xb9, 0x0e, 0x77, 0x77, 0x5a, + 0x7a, 0x3d, 0xe3, 0x76, 0x36, 0x61, 0xd5, 0xa9, 0xda, 0x5e, 0x27, 0xa5, 0xb8, 0xc9, 0x27, 0xc8, + 0x4f, 0x50, 0x77, 0x0f, 0x14, 0x1e, 0x80, 0x1b, 0xbf, 0xb1, 0xc5, 0x39, 0xaf, 0xe6, 0x82, 0x60, + 0xb0, 0x5e, 0x32, 0xc1, 0xdf, 0xa8, 0x33, 0x70, 0xaf, 0x78, 0x08, 0x1f, 0xce, 0x63, 0x45, 0xbb, + 0xf0, 0xf9, 0x90, 0x3e, 0x11, 0xf3, 0x7e, 0x5d, 0x44, 0x61, 0xe3, 0xa8, 0xbc, 0xaa, 0x71, 0x33, + 0xb1, 0x2d, 0x5a, 0x8e, 0xf2, 0x39, 0x16, 0x2c, 0x65, 0xc7, 0x3e, 0xca, 0xc3, 0x81, 0xb0, 0xa1, + 0x95, 0xf1, 0x83, 0xb4, 0x2a, 0x9f, 0xd9, 0xed, 0xb6, 0x66, 0x25, 0xcd, 0x41, 0x1d, 0x06, 0x01, + 0x57, 0x3c, 0xb7, 0x75, 0xee, 0x9a, 0x64, 0xd7, 0x83, 0x2c, 0x34, 0x42, 0xae, 0x59, 0x21, 0x9c, + 0xaa, 0xc8, 0xfa, 0xfc, 0x6e, 0xb5, 0x4d, 0x14, 0x8d, 0xe4, 0x5a, 0x85, 0xe9, 0xb7, 0xa1, 0x76, + 0x4b, 0x57, 0x1b, 0x8b, 0xa5, 0x91, 0x48, 0xdd, 0x76, 0x47, 0x3d, 0xdf, 0xe3, 0xbd, 0x5f, 0x54, + 0x14, 0x25, 0x9f, 0x11, 0x81, 0xcc, 0x62, 0x83, 0x8f, 0x20, 0x5c, 0xa7, 0x39, 0x37, 0xcd, 0x5f, + 0xb2, 0x30, 0x10, 0x9e, 0x2c, 0xec, 0xb6, 0x65, 0x45, 0xd2, 0x0c, 0x5b, 0xa2, 0x4f, 0x8b, 0xb6, + 0xa1, 0x0b, 0xc2, 0xbb, 0x8c, 0xa5, 0x15, 0x87, 0xb1, 0x2d, 0x5a, 0x8e, 0xf2, 0x39, 0x25, 0xe4, + 0x65, 0xc6, 0xd3, 0xa6, 0x52, 0x43, 0x2a, 0xef, 0x33, 0x6c, 0x87, 0xeb, 0x3a, 0xcf, 0x5d, 0xf0, + 0xc0, 0x08, 0x10, 0x7e, 0x05, 0xb0, 0x45, 0x65, 0x24, 0xd9, 0xe8, 0xb5, 0xf1, 0x9a, 0xbf, 0xc8, + 0xbf, 0x69, 0x46, 0x6a, 0x23, 0xb9, 0x2e, 0x01, 0xea, 0x4d, 0xdf, 0x67, 0xfa, 0x07, 0x84, 0x2e, + 0x59, 0xa2, 0x09, 0x20, 0xdd, 0xf6, 0x02, 0x98, 0xbd, 0xc7, 0x57, 0x85, 0x72, 0x36, 0x1a, 0x2a, + 0x4f, 0x84, 0x15, 0xa8, 0x47, 0x57, 0x9f, 0x57, 0x23, 0xd6, 0xc0, 0x7c, 0x3e, 0xf6, 0x02, 0x3a, + 0xc4, 0x97, 0x5c, 0xc0, 0x52, 0x4c, 0x05, 0x1f, 0x1a, 0xfb, 0x4c, 0x4f, 0x31, 0x4c, 0xc8, 0x02, + 0xfd, 0x73, 0xed, 0x7b, 0x24, 0xe0, 0xc1, 0x61, 0xb8, 0x52, 0x8d, 0x2c, 0x8a, 0xb3, 0x7e, 0xf8, + 0xb1, 0x2d, 0x5a, 0x8e, 0xf2, 0x39, 0x25, 0x84, 0xaf, 0xdd, 0x74, 0x71, 0x44, 0x68, 0xff, 0x2b, + 0x57, 0x71, 0x24, 0x5c, 0x55, 0xa5, 0x54, 0x83, 0x19, 0xf7, 0x1a, 0xc2, 0xe7, 0xdc, 0x46, 0xf0, + 0x09, 0x8b, 0xf5, 0xf3, 0x91, 0x04, 0x22, 0xa1, 0x27, 0x34, 0x0f, 0x64, 0xeb, 0x1f, 0xe5, 0x9b, + 0xcb, 0x22, 0x0f, 0xc3, 0x54, 0x10, 0x78, 0x8c, 0x61, 0xf9, 0xf4, 0x6f, 0xc9, 0xbb, 0x88, 0x86, + 0x73, 0x8a, 0x4c, 0xff, 0x4e, 0x44, 0xc9, 0x5d, 0x96, 0x9f, 0x80, 0x19, 0xe6, 0x78, 0x1f, 0x6b, + 0x00, 0x0c, 0x9f, 0x04, 0x24, 0x74, 0xf0, 0x3c, 0x53, 0x08, 0x2b, 0x3b, 0x50, 0xa9, 0xe8, 0x65, + 0x87, 0x69, 0xf7, 0xd4, 0x59, 0x0e, 0x0b, 0x9d, 0x1e, 0x11, 0x0a, 0xe6, 0x57, 0x11, 0x78, 0x08, + 0xd0, 0x64, 0x47, 0x05, 0xae, 0x94, 0x89, 0xbc, 0xb1, 0x31, 0xa7, 0x0e, 0xf2, 0x39, 0x15, 0xfc, + 0xb6, 0x85, 0x63, 0x1f, 0x20, 0xc0, 0x06, 0x36, 0xe0, 0xa7, 0x4a, 0xc5, 0xad, 0x13, 0x1f, 0xa7, + 0x8a, 0xd5, 0x1a, 0xab, 0xdc, 0xc1, 0x6b, 0xa9, 0x50, 0xfb, 0x62, 0xc5, 0x48, 0xf1, 0x9b, 0x9b, + 0x2c, 0xe8, 0x56, 0xcf, 0x2a, 0x04, 0xa4, 0x0b, 0xd5, 0x36, 0xda, 0x6a, 0xa8, 0xa7, 0xa9, 0x58, + 0xef, 0xa2, 0x35, 0x74, 0x48, 0xc9, 0xa2, 0xb5, 0x48, 0xeb, 0x2f, 0x99, 0x26, 0x75, 0xf9, 0xeb, + 0x35, 0xc1, 0x92, 0xec, 0xda, 0x01, 0xee, 0x4e, 0xef, 0x15, 0xe6, 0x87, 0x03, 0xf7, 0x73, 0xc5, + 0x6f, 0x02, 0xf5, 0xbe, 0x1f, 0x49, 0x0f, 0x88, 0x0b, 0xe3, 0x24, 0x06, 0xed, 0xe1, 0xa1, 0xe3, + 0x33, 0x5b, 0xbb, 0xae, 0x10, 0x01, 0xd0, 0xd8, 0x63, 0xe2, 0x15, 0x44, 0xdf, 0xd3, 0x7b, 0x5b, + 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x76, 0x0c, 0x69, 0x22, 0x72, 0xe4, 0x98, 0xd5, 0x8a, 0x89, + 0x1c, 0x65, 0xc4, 0x6e, 0x00, 0x17, 0x29, 0x54, 0x3d, 0xd5, 0x58, 0x43, 0xc0, 0x33, 0x85, 0x15, + 0x9d, 0xf1, 0x19, 0x3f, 0x72, 0x51, 0xcf, 0x81, 0xb7, 0x6b, 0xd7, 0x35, 0x69, 0x08, 0xe1, 0x13, + 0x3b, 0x78, 0x0a, 0xe1, 0x1b, 0xa7, 0xe8, 0x72, 0x10, 0x55, 0xb9, 0x20, 0x11, 0x50, 0xa4, 0x17, + 0x87, 0x12, 0xfa, 0xf9, 0xf4, 0x1d, 0x4f, 0x08, 0x95, 0x82, 0x72, 0x9e, 0xc9, 0x0f, 0xe9, 0x01, + 0x21, 0x7f, 0xde, 0xf8, 0x10, 0x38, 0x56, 0x3b, 0x20, 0xa7, 0x02, 0x3f, 0x16, 0x3c, 0x36, 0x81, + 0x69, 0xa6, 0x1a, 0xcc, 0x51, 0xac, 0x6d, 0x79, 0x9a, 0xda, 0x1c, 0xca, 0xa7, 0x96, 0x95, 0x6b, + 0x00, 0xb0, 0x61, 0x1c, 0xce, 0xc3, 0x6f, 0xb7, 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x55, 0x84, + 0xaa, 0x56, 0xbf, 0xa9, 0xda, 0x3c, 0x9d, 0xc3, 0xf5, 0xac, 0x60, 0x1e, 0x1a, 0xd8, 0x19, 0xdf, + 0x0a, 0x71, 0x4a, 0xfc, 0xe5, 0xc4, 0x08, 0x23, 0xec, 0x2f, 0x4c, 0x6c, 0xa6, 0x7c, 0x21, 0x4a, + 0xdd, 0xb3, 0xca, 0x0f, 0xbb, 0x13, 0x27, 0x92, 0x69, 0xde, 0x0e, 0xe7, 0x16, 0xd4, 0x62, 0x1a, + 0x7c, 0xd8, 0xef, 0xcd, 0xcd, 0xdd, 0x83, 0xbd, 0x7f, 0xaa, 0x22, 0xc3, 0x04, 0xe2, 0x4d, 0x2b, + 0xe4, 0x6f, 0xd2, 0x4e, 0xb8, 0x46, 0x41, 0x47, 0xbe, 0x19, 0x09, 0xfc, 0x60, 0x43, 0x60, 0x39, + 0x1d, 0xda, 0x13, 0x3e, 0x0d, 0x1d, 0xc8, 0x68, 0xbc, 0x05, 0x49, 0xa7, 0xc1, 0x3b, 0x2a, 0x03, + 0x60, 0x25, 0xba, 0xac, 0xd5, 0x4b, 0x2c, 0x64, 0x83, 0x96, 0x80, 0x4d, 0xa0, 0x66, 0xab, 0x1e, + 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x55, 0xf4, 0xaa, 0x56, 0x81, 0x76, 0xd9, 0xc8, 0x2c, 0x73, + 0x36, 0x0f, 0xea, 0x62, 0xe2, 0x2c, 0x3b, 0x4b, 0x43, 0xdc, 0x2e, 0x7a, 0x64, 0xf5, 0xc9, 0xb4, + 0xd3, 0x00, 0x02, 0x38, 0xc4, 0x99, 0x45, 0x1a, 0x98, 0x04, 0x95, 0xd5, 0xbe, 0x36, 0xa9, 0xd1, + 0x88, 0xf0, 0xc3, 0x1f, 0xe5, 0x6a, 0x61, 0xac, 0x5d, 0x5e, 0x7d, 0xf0, 0xc3, 0x0a, 0x06, 0x20, + 0xde, 0xe4, 0xe3, 0x4a, 0x50, 0xae, 0xea, 0xbd, 0x97, 0xb0, 0xe4, 0xe6, 0x13, 0x25, 0x13, 0x3c, + 0x9d, 0xd1, 0x00, 0xfb, 0x94, 0xff, 0xb8, 0x13, 0x63, 0x79, 0x7c, 0x38, 0xbf, 0x96, 0x4e, 0xec, + 0x8b, 0x24, 0xd3, 0x67, 0xf1, 0x6a, 0x56, 0x7b, 0xca, 0xf1, 0xee, 0x32, 0x3b, 0x01, 0x12, 0x00, + 0x37, 0xa9, 0x23, 0xe6, 0xf7, 0x12, 0x74, 0xe1, 0x95, 0xed, 0xae, 0xab, 0x72, 0x39, 0x65, 0xbc, + 0x65, 0xc7, 0x3e, 0xba, 0x36, 0x09, 0x27, 0x54, 0x8f, 0xf1, 0xe9, 0x4f, 0x64, 0x30, 0xaa, 0x29, + 0x9f, 0x5d, 0x65, 0x00, 0x00, 0x53, 0x82, 0x0f, 0xdd, 0x1c, 0x37, 0x3a, 0xbf, 0xb6, 0xba, 0xf1, + 0xbe, 0x00, 0xc8, 0x58, 0x9b, 0xbf, 0x78, 0xc5, 0xbe, 0x78, 0x7f, 0xd3, 0xb0, 0xdc, 0x2f, 0xd4, + 0xbd, 0x16, 0x7f, 0xbb, 0x36, 0xd3, 0x5f, 0x75, 0x99, 0x27, 0x3c, 0xd8, 0x44, 0xed, 0xbd, 0xb7, + 0xc1, 0xe7, 0x56, 0x27, 0x63, 0x3c, 0xa2, 0x25, 0x5b, 0xc6, 0x93, 0x9d, 0x03, 0x96, 0x19, 0xa4, + 0xd9, 0x58, 0xeb, 0xf9, 0xf4, 0xcb, 0x05, 0xa2, 0x20, 0xac, 0xf4, 0xed, 0x1a, 0xc8, 0x32, 0xa8, + 0x88, 0xc3, 0xad, 0x15, 0xcc, 0x10, 0x65, 0xd1, 0x83, 0xe4, 0x99, 0xf9, 0xfe, 0xaa, 0x44, 0xd0, + 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x76, 0x1c, 0x69, 0x22, 0x06, 0xbe, 0xcf, 0xbb, 0x90, 0x18, + 0x52, 0x80, 0x9a, 0xbc, 0x72, 0x5b, 0x82, 0xed, 0x4f, 0x22, 0x04, 0xca, 0xe6, 0xf0, 0x1d, 0x3e, + 0x19, 0x9d, 0xcc, 0xb2, 0x6a, 0x37, 0x5a, 0xa8, 0x24, 0x0d, 0x27, 0x00, 0xeb, 0x99, 0xa9, 0x6c, + 0x96, 0xd9, 0x30, 0x39, 0x3f, 0xcb, 0x4d, 0x9f, 0x97, 0x8d, 0x5a, 0xd6, 0x71, 0x42, 0x8b, 0x1d, + 0xf5, 0x72, 0x87, 0x7d, 0x4c, 0x2c, 0x80, 0x01, 0x8a, 0x1a, 0x30, 0x68, 0x6f, 0xfb, 0x6c, 0x5b, + 0xc0, 0xe8, 0x73, 0x0f, 0x77, 0xae, 0x69, 0xa2, 0xba, 0x3b, 0x86, 0xf3, 0x22, 0x1e, 0xda, 0x7b, + 0xc8, 0x50, 0xc9, 0x12, 0x89, 0xff, 0xe6, 0x57, 0xe2, 0x50, 0xef, 0x1e, 0x37, 0xda, 0xc5, 0x1d, + 0xcf, 0x63, 0xcf, 0x1c, 0x79, 0x8e, 0xf8, 0xb8, 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x29, 0x56, 0x2c, + 0x65, 0xca, 0x0c, 0x46, 0xc6, 0x0f, 0x6d, 0xc2, 0xc1, 0x9d, 0x46, 0x6b, 0x63, 0x2f, 0x24, 0x80, + 0xf9, 0x0e, 0x34, 0xbf, 0x1b, 0x00, 0x23, 0x4d, 0xef, 0x2f, 0x3f, 0x36, 0xfc, 0x5e, 0x98, 0x6d, + 0x00, 0xf5, 0x32, 0x7b, 0x17, 0x4e, 0xb7, 0xc8, 0x7f, 0x4f, 0xcb, 0x75, 0x42, 0x94, 0x8f, 0x1c, + 0x77, 0x91, 0x21, 0x58, 0x0a, 0x9f, 0xe2, 0xf0, 0x24, 0x82, 0x60, 0x38, 0x15, 0x9c, 0x66, 0xa4, + 0x0c, 0xce, 0xd7, 0x98, 0x92, 0x21, 0x82, 0xad, 0x64, 0x05, 0x9f, 0x1c, 0x81, 0x78, 0x31, 0x2e, + 0xb3, 0x35, 0xd8, 0x39, 0x26, 0xa0, 0xae, 0x18, 0xdf, 0x9b, 0x15, 0xc8, 0x54, 0x3f, 0x72, 0x73, + 0xaa, 0x6c, 0x99, 0xf3, 0x01, 0x82, 0x3f, 0x06, 0xf9, 0x22, 0x80, 0x50, 0x3f, 0xb4, 0x5d, 0x64, + 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x76, 0x34, 0x65, 0xc7, 0x3e, 0xbd, 0x54, 0x3b, 0x16, 0x90, + 0xdc, 0x7d, 0x82, 0x5b, 0x33, 0x8a, 0xc1, 0x6a, 0x59, 0x44, 0x23, 0x87, 0x50, 0xa1, 0xc5, 0x00, + 0x00, 0x6c, 0xf6, 0x1e, 0x90, 0xfc, 0x00, 0x04, 0x36, 0x8c, 0x59, 0x9a, 0x9d, 0x6a, 0x98, 0x8f, + 0x31, 0xb2, 0x25, 0xe6, 0xca, 0x2c, 0x83, 0x26, 0x7b, 0x52, 0xdc, 0x27, 0x9f, 0xda, 0x74, 0x90, + 0xba, 0xc2, 0x2e, 0x09, 0x02, 0xec, 0xe6, 0xf4, 0x1a, 0x97, 0xc7, 0x82, 0xcf, 0x75, 0x6a, 0x2c, + 0x26, 0x04, 0x81, 0xd3, 0x70, 0xd0, 0x9c, 0x6a, 0x4e, 0x50, 0x87, 0x3f, 0x15, 0x8e, 0x6f, 0x20, + 0x50, 0xa9, 0x84, 0xea, 0xfd, 0xdf, 0x55, 0xd9, 0xb3, 0x49, 0x67, 0xc0, 0x43, 0xd2, 0xf5, 0x68, + 0x0a, 0x65, 0x54, 0x12, 0xcb, 0x7a, 0x6d, 0x50, 0xb5, 0xe9, 0x62, 0x2b, 0x72, 0x39, 0x75, 0xec, + 0xaa, 0x72, 0x28, 0x1c, 0x23, 0xca, 0x8c, 0x31, 0x24, 0xa3, 0x04, 0x8f, 0x88, 0xe2, 0xd0, 0x51, + 0x97, 0x8f, 0x00, 0xee, 0xb9, 0x2c, 0x03, 0xa3, 0x1a, 0x73, 0xd9, 0x42, 0xbc, 0x46, 0x13, 0x46, + 0x00, 0x00, 0xee, 0xc8, 0xb4, 0xc5, 0x3c, 0xe6, 0xa4, 0xe8, 0x67, 0x45, 0xf7, 0xcc, 0x7d, 0xdd, + 0x15, 0x48, 0xcf, 0xc1, 0x49, 0x8c, 0xef, 0x61, 0x96, 0xd6, 0xd9, 0x36, 0x6d, 0xb5, 0x2d, 0x39, + 0x73, 0x56, 0x21, 0xa7, 0x00, 0xf6, 0xe3, 0x6e, 0xc2, 0xf8, 0x82, 0xf9, 0x01, 0x70, 0xd3, 0x0a, + 0x44, 0xed, 0xe6, 0x74, 0xfe, 0xbe, 0xbd, 0xc4, 0xff, 0x43, 0x28, 0x18, 0xa1, 0xa4, 0x95, 0xde, + 0x49, 0x6c, 0x24, 0xc7, 0xcb, 0x7c, 0x5e, 0x71, 0xc1, 0xf9, 0x37, 0xcb, 0x11, 0xc9, 0x4a, 0xa4, + 0x95, 0xe9, 0x62, 0x2b, 0x72, 0x39, 0x65, 0x8c, 0xaf, 0xdd, 0x47, 0x5c, 0xb0, 0x00, 0x49, 0x93, + 0x33, 0x62, 0x33, 0xea, 0x01, 0x96, 0x10, 0xe9, 0xad, 0x31, 0x60, 0x63, 0xf9, 0x70, 0xb5, 0x05, + 0x93, 0x21, 0x00, 0x00, 0x00, 0x1b, 0xf0, 0xb4, 0x11, 0x74, 0xb8, 0x13, 0x3f, 0xe9, 0xa0, 0x87, + 0xa9, 0xeb, 0xf4, 0x90, 0xcd, 0xf1, 0xd5, 0x98, 0xa1, 0xc7, 0xc4, 0xf3, 0x2d, 0xe2, 0x38, 0x12, + 0x1b, 0x59, 0x0c, 0xa0, 0x6f, 0x2d, 0x00, 0xd6, 0xfb, 0xfd, 0x1f, 0x4f, 0xac, 0x83, 0x66, 0xe6, + 0x30, 0xf0, 0xe1, 0xe6, 0x5f, 0xfe, 0x37, 0x82, 0xde, 0x01, 0xe0, 0x63, 0x6f, 0x7a, 0x5b, 0x81, + 0x01, 0xf1, 0x7c, 0x58, 0x9f, 0x4a, 0x7d, 0x11, 0xd2, 0xd3, 0x20, 0x4e, 0xb5, 0xfc, 0xe3, 0x28, + 0xd9, 0x0b, 0xf6, 0x5d, 0x8e, 0x1c, 0x1c, 0xec, 0xb5, 0xed, 0xae, 0xab, 0x72, 0x29, 0x85, 0xcb, + 0xb0, 0xdc, 0x57, 0x20, 0xf0, 0xa7, 0x97, 0x09, 0x74, 0xb4, 0x8e, 0xbb, 0x8a, 0x26, 0x54, 0xe4, + 0xcd, 0x48, 0x58, 0xcc, 0xea, 0xe0, 0x6f, 0x98, 0xb6, 0x00, 0xa4, 0x1b, 0x6d, 0x00, 0x2b, 0x3a, + 0xcf, 0x5b, 0xb7, 0x5e, 0xc5, 0x12, 0x68, 0xd3, 0xaf, 0x2c, 0x53, 0x43, 0x57, 0x1f, 0xe2, 0xb6, + 0x6e, 0xb0, 0xe1, 0x95, 0x7e, 0x6d, 0x63, 0x04, 0x32, 0x58, 0x9d, 0x3a, 0xe8, 0xe2, 0x21, 0xc5, + 0x2e, 0x45, 0x56, 0xec, 0x38, 0x53, 0xe1, 0x0c, 0x98, 0xcd, 0x8f, 0x00, 0xc0, 0x58, 0x8f, 0x80, + 0x4e, 0x14, 0x9d, 0x44, 0x39, 0x0f, 0xa9, 0x8f, 0x67, 0xc8, 0xed, 0xf4, 0x69, 0x45, 0x64, 0x76, + 0x98, 0x5f, 0x96, 0xa1, 0x88, 0x8c, 0xdf, 0x5f, 0x19, 0x7e, 0xc7, 0x26, 0xc1, 0x18, 0x78, 0xdc, + 0xb4, 0x71, 0x61, 0x8b, 0x72, 0x29, 0x85, 0xf3, 0xaf, 0xdd, 0x47, 0x5c, 0xf8, 0xf7, 0x5d, 0x32, + 0xb2, 0x35, 0x24, 0x6f, 0x38, 0xf4, 0x7c, 0x9b, 0x23, 0x39, 0xdd, 0xd4, 0x86, 0x97, 0xff, 0xc8, + 0x61, 0x9b, 0xf3, 0xf2, 0xad, 0x9b, 0xb1, 0x5d, 0x07, 0x94, 0x64, 0x06, 0x3a, 0x87, 0xec, 0x50, + 0x74, 0x21, 0x00, 0xc6, 0x46, 0x09, 0xba, 0xd1, 0x31, 0x47, 0xa6, 0xeb, 0x5f, 0x5a, 0xd6, 0x49, + 0x18, 0xeb, 0x1b, 0x99, 0xf5, 0x21, 0x5a, 0xe8, 0xb0, 0xa7, 0x38, 0xc6, 0xc7, 0xf9, 0x21, 0x4a, + 0x13, 0x0a, 0xf8, 0xe6, 0xae, 0xf9, 0x9f, 0x9f, 0x40, 0x68, 0x50, 0xb8, 0x9f, 0x0c, 0xe8, 0x70, + 0xc4, 0x70, 0x33, 0x08, 0xdd, 0x46, 0x76, 0x76, 0x55, 0x74, 0x43, 0x17, 0xc9, 0xcc, 0xbb, 0x6b, + 0x50, 0x86, 0xda, 0x12, 0x79, 0x9f, 0x04, 0xaf, 0xb4, 0x4d, 0x18, 0x0b, 0x72, 0x29, 0x75, 0x83, + 0x37, 0xe8, 0x78, 0x4c, 0xdd, 0x28, 0xd1, 0xf1, 0xa5, 0x1f, 0xea, 0x9c, 0x2d, 0x1f, 0xfc, 0x29, + 0x3b, 0xca, 0x42, 0xdd, 0x56, 0x2f, 0x55, 0xaa, 0x11, 0x41, 0x23, 0x4b, 0xe0, 0x8a, 0xfe, 0x4d, + 0x49, 0x93, 0x7e, 0xd0, 0x3a, 0x26, 0x94, 0xcf, 0x54, 0xd2, 0x73, 0x43, 0xa5, 0x86, 0x08, 0x3b, + 0xdb, 0x9c, 0x33, 0x0b, 0xde, 0xd1, 0x22, 0x51, 0xa9, 0xff, 0x73, 0xe3, 0xe2, 0x0d, 0x78, 0x3b, + 0xc0, 0x66, 0xc1, 0x2b, 0x3f, 0x97, 0x7e, 0x13, 0xc7, 0x4a, 0x5b, 0x87, 0x8f, 0x43, 0xa4, 0xc2, + 0x3c, 0xad, 0xf1, 0x1a, 0x7c, 0x94, 0xfa, 0x33, 0x6a, 0xa2, 0x0c, 0x5c, 0x62, 0x75, 0x00, 0x42, + 0xab, 0xed, 0x05, 0x25, 0x58, 0x69, 0x4e, 0xc1, 0xcc, 0x53, 0xc6, 0x54, 0xc6, 0x1c, 0xce, 0x94, + 0xb4, 0x4d, 0x18, 0x0b, 0x72, 0x39, 0x55, 0xab, 0xaf, 0xa7, 0x15, 0xa8, 0xfa, 0xa5, 0x34, 0x80, + 0x03, 0xb3, 0x75, 0xe8, 0x13, 0x94, 0x18, 0xdc, 0xd8, 0x42, 0xea, 0x90, 0x95, 0x6b, 0x37, 0x53, + 0x2e, 0x0f, 0xc1, 0x0f, 0xa9, 0x55, 0x71, 0xa2, 0xbe, 0xee, 0xe2, 0x16, 0xb0, 0x47, 0x82, 0x1f, + 0x91, 0x53, 0xc1, 0xa2, 0x19, 0xc8, 0x5e, 0x37, 0x98, 0x7f, 0x20, 0x33, 0x91, 0x1b, 0x8a, 0x12, + 0xc1, 0x67, 0xa5, 0xbf, 0x6a, 0xa6, 0xc2, 0xe9, 0xf2, 0xe6, 0x21, 0x4a, 0xf0, 0xba, 0xed, 0xa3, + 0x9f, 0x8d, 0xe3, 0xc3, 0x54, 0xac, 0x01, 0x62, 0x53, 0x20, 0x7c, 0x7c, 0x53, 0x59, 0x5b, 0xd3, + 0x8a, 0x6d, 0x86, 0x32, 0x50, 0x58, 0xc5, 0xe8, 0xe3, 0xf8, 0xff, 0xc4, 0x91, 0x89, 0x75, 0x2e, + 0x8a, 0xe4, 0x9e, 0x73, 0xda, 0x64, 0x27, 0x83, 0x94, 0x3c, 0x71, 0x0b, 0x72, 0x39, 0x55, 0x6b, + 0xaf, 0xdd, 0x47, 0x5c, 0xc7, 0x48, 0xbf, 0x31, 0x23, 0xf9, 0x44, 0x19, 0xad, 0x87, 0xee, 0x99, + 0xce, 0xdd, 0xbe, 0xba, 0x25, 0x83, 0x36, 0x59, 0x62, 0x45, 0x2f, 0xcc, 0xb3, 0x56, 0xae, 0x24, + 0xc9, 0xf1, 0x9d, 0x05, 0x11, 0x5d, 0x68, 0x98, 0x71, 0xd4, 0xef, 0xa6, 0xc2, 0x21, 0x6e, 0x39, + 0x11, 0x0b, 0x96, 0x04, 0xc0, 0xfc, 0x74, 0xa4, 0xe5, 0x0e, 0xef, 0x05, 0x1a, 0x4d, 0x1e, 0x83, + 0xa8, 0xdd, 0x5f, 0xcd, 0x23, 0x89, 0x26, 0xad, 0x27, 0x0f, 0x14, 0xa0, 0xba, 0x22, 0x87, 0x05, + 0x98, 0xab, 0x84, 0x4e, 0x9f, 0x7d, 0x8e, 0x28, 0x09, 0x8f, 0xf2, 0xe1, 0xe6, 0xbe, 0xa3, 0x9e, + 0xf4, 0xb4, 0xd3, 0x2d, 0x93, 0xb5, 0x8c, 0xe6, 0x3b, 0x7e, 0x27, 0x17, 0x9c, 0x31, 0x26, 0x42, + 0xb4, 0x3c, 0x71, 0x0b, 0x72, 0x29, 0x65, 0x4b, 0xaf, 0xdc, 0xf2, 0xe1, 0x37, 0x69, 0x8f, 0x62, + 0x94, 0xaa, 0x2e, 0x8f, 0x4c, 0x13, 0x76, 0x24, 0xa7, 0xc5, 0x6a, 0xeb, 0xcd, 0xe4, 0x11, 0x6e, + 0xaa, 0x4d, 0x5a, 0xbc, 0x30, 0x81, 0xcb, 0xaf, 0x22, 0x20, 0x00, 0x55, 0x45, 0x25, 0x83, 0xf9, + 0xb2, 0x42, 0x42, 0x5c, 0x7f, 0x20, 0x1c, 0x45, 0x7d, 0x12, 0xa8, 0xfe, 0x93, 0xad, 0x29, 0x9e, + 0xb1, 0xdc, 0xc6, 0xaa, 0xc1, 0xb5, 0x4d, 0xae, 0xe6, 0xe2, 0x50, 0x62, 0x66, 0xb7, 0x13, 0x9e, + 0x84, 0xe3, 0xed, 0x02, 0x90, 0x01, 0x84, 0x09, 0x8e, 0x18, 0x12, 0xe0, 0xf9, 0x0f, 0x38, 0x35, + 0xb1, 0x62, 0x99, 0x3a, 0xc5, 0x21, 0x65, 0xa1, 0x4e, 0xe5, 0x63, 0x3f, 0x9c, 0x43, 0x63, 0xb4, + 0xae, 0xc8, 0x52, 0x31, 0xa2, 0x2a, 0xf5, 0xf3, 0x94, 0x3c, 0x71, 0x0b, 0x72, 0x39, 0x55, 0x53, + 0xaf, 0xa6, 0xca, 0x13, 0x95, 0x17, 0x6c, 0x2d, 0x47, 0x4e, 0xf4, 0x3a, 0xb8, 0xf0, 0x27, 0x55, + 0xf9, 0x78, 0x67, 0x4e, 0x50, 0x6a, 0xc0, 0x2b, 0x9f, 0xe5, 0xda, 0x28, 0xcc, 0x23, 0xae, 0x95, + 0xd0, 0xc0, 0xff, 0x90, 0xcf, 0xf1, 0x89, 0x7e, 0xc9, 0x79, 0x70, 0x48, 0xc4, 0x47, 0x85, 0x26, + 0x37, 0x26, 0xc4, 0x55, 0x42, 0xd7, 0xd3, 0x69, 0x9f, 0x2f, 0xe7, 0xf4, 0x2c, 0x5d, 0x96, 0x37, + 0xb0, 0xb7, 0x47, 0x3d, 0x1e, 0x3d, 0xf3, 0x39, 0xe5, 0xdc, 0xe7, 0x81, 0xf1, 0x7d, 0x22, 0xd7, + 0x09, 0xee, 0x56, 0x19, 0xe7, 0xc6, 0x53, 0x43, 0x0c, 0x8b, 0x37, 0x62, 0x68, 0x9e, 0x90, 0xa8, + 0x88, 0x9b, 0x14, 0x5d, 0x29, 0xdf, 0xaf, 0xfa, 0x7d, 0x7e, 0x0f, 0x63, 0xb3, 0xc7, 0x2e, 0xbf, + 0x94, 0x3c, 0x71, 0x0b, 0x72, 0x29, 0x45, 0x4b, 0x69, 0xab, 0xe4, 0x62, 0x9f, 0xb0, 0x4e, 0xd3, + 0x48, 0xa7, 0xb8, 0xa8, 0x6b, 0x21, 0xd6, 0x1a, 0x0d, 0xcc, 0xe5, 0x36, 0xc5, 0x24, 0xba, 0xad, + 0xdf, 0x35, 0xe1, 0x45, 0xa8, 0xd4, 0x8c, 0x4e, 0x88, 0x37, 0x5f, 0x09, 0x05, 0x0d, 0x8d, 0x14, + 0x44, 0xd7, 0x7e, 0x17, 0x13, 0xa4, 0xd4, 0x74, 0x9d, 0x64, 0x6d, 0x60, 0xd0, 0x4c, 0x82, 0x4e, + 0x3a, 0xb4, 0x3b, 0xd6, 0xe3, 0xa9, 0xe3, 0xda, 0x0b, 0x97, 0xec, 0xc4, 0x1a, 0x65, 0x64, 0x4a, + 0x00, 0x38, 0xf2, 0x3c, 0x3f, 0x09, 0x9e, 0x22, 0x2b, 0x00, 0xaf, 0x4c, 0xac, 0x3b, 0x00, 0x1d, + 0x25, 0xab, 0x0b, 0x1a, 0x56, 0xe1, 0x7b, 0x8e, 0xc8, 0x80, 0x4e, 0x68, 0xcf, 0x18, 0x74, 0x19, + 0x10, 0x2c, 0xa0, 0x8c, 0x42, 0x04, 0x38, 0xf7, 0xb4, 0x4d, 0x18, 0x0b, 0x72, 0x29, 0x65, 0x4b, + 0xb0, 0xd2, 0xbf, 0xfa, 0x22, 0x62, 0xa0, 0x3a, 0xbe, 0x16, 0x43, 0x4e, 0xd1, 0x9e, 0x40, 0x98, + 0x3c, 0x1c, 0x26, 0xe8, 0x69, 0xae, 0x0e, 0x13, 0xa9, 0x1e, 0x42, 0x47, 0x9e, 0x7a, 0x56, 0xf6, + 0xc0, 0xb6, 0xbb, 0x80, 0x00, 0x34, 0xd4, 0x27, 0x3b, 0x31, 0x20, 0xa2, 0xdb, 0x0e, 0x81, 0xe9, + 0x23, 0x27, 0x8c, 0xd2, 0x20, 0xf6, 0x1a, 0x79, 0xe7, 0x23, 0x51, 0xec, 0x6f, 0x15, 0x7c, 0x7f, + 0x7b, 0xce, 0xa9, 0x30, 0xf9, 0xb4, 0x4a, 0x1e, 0x27, 0x3e, 0xc3, 0xe1, 0x10, 0x60, 0xfa, 0xc1, + 0x62, 0x6a, 0x67, 0x43, 0x62, 0xe1, 0x9d, 0x30, 0x75, 0x2a, 0x19, 0xf1, 0x5e, 0xd6, 0x06, 0xaf, + 0x46, 0xb7, 0x1c, 0x47, 0x0d, 0xc8, 0xd3, 0xc3, 0x65, 0xf0, 0x66, 0x83, 0xc5, 0x9e, 0xe3, 0x1c, + 0xb4, 0x3c, 0x71, 0x0b, 0x72, 0x29, 0x45, 0x63, 0xb0, 0xd2, 0xc2, 0x06, 0xf4, 0x6c, 0xfb, 0xc1, + 0x8f, 0x89, 0x8a, 0x74, 0x0a, 0xd2, 0x5f, 0x4a, 0xf9, 0x7c, 0x3c, 0x51, 0xcf, 0x28, 0x07, 0x36, + 0xca, 0xbd, 0x7a, 0xcd, 0xd0, 0x57, 0x1f, 0x54, 0x01, 0x19, 0x8c, 0xd0, 0x8b, 0x1e, 0x40, 0xa5, + 0x76, 0x7f, 0xb0, 0x25, 0x79, 0x3c, 0xa4, 0x51, 0x74, 0xa3, 0x6a, 0x53, 0x44, 0xbb, 0x9a, 0x39, + 0xa7, 0x8b, 0xd4, 0x66, 0xe5, 0x8e, 0x52, 0xc9, 0xbb, 0x9e, 0x2a, 0x19, 0x31, 0x12, 0x15, 0x5d, + 0x4b, 0x8f, 0xfc, 0x08, 0xb2, 0xd3, 0x0a, 0xb8, 0xad, 0xa7, 0x38, 0xba, 0xd6, 0x83, 0xb3, 0xe8, + 0x74, 0x04, 0xd4, 0x19, 0x01, 0xc4, 0xc3, 0x96, 0xe5, 0x8a, 0xe1, 0x17, 0x09, 0xf0, 0xd4, 0x40, + 0x9a, 0xce, 0x1b, 0x1e, 0x1c, 0x9c, 0x3d, 0x0b, 0xb2, 0xfc, 0xd5, 0xcb, 0x72, 0x29, 0x55, 0x43, + 0xaf, 0xdd, 0x92, 0x47, 0xe0, 0x4e, 0xf8, 0xd3, 0x44, 0x79, 0xec, 0x05, 0x38, 0xd5, 0x9d, 0xfe, + 0xec, 0x81, 0xc0, 0xd3, 0x3d, 0xcd, 0x5c, 0x3b, 0x04, 0x92, 0x44, 0x6b, 0x60, 0x15, 0xc9, 0x08, + 0xc9, 0x19, 0xe7, 0xc3, 0x95, 0x00, 0x06, 0xf0, 0x63, 0x39, 0x2f, 0x9d, 0xca, 0xe7, 0xdd, 0x5e, + 0xe8, 0x42, 0x60, 0xae, 0xf7, 0x3d, 0x54, 0x97, 0xc8, 0xf0, 0xae, 0xe7, 0xc9, 0x19, 0xc0, 0xba, + 0xeb, 0xff, 0x21, 0xa9, 0xe4, 0xbd, 0x3f, 0xfb, 0xb8, 0x4a, 0x9c, 0x3e, 0x48, 0x8c, 0x19, 0xc2, + 0x61, 0xcf, 0x94, 0xd6, 0x20, 0x58, 0x2e, 0x7f, 0x00, 0x95, 0x6f, 0x65, 0x5d, 0x45, 0xc6, 0x76, + 0x59, 0x54, 0x9c, 0xa5, 0x52, 0x15, 0x68, 0x05, 0x92, 0x9e, 0xd3, 0x98, 0x75, 0xdc, 0x37, 0x6e, + 0xb2, 0xfc, 0xd5, 0xcb, 0x72, 0x39, 0x45, 0x3b, 0xaf, 0xa6, 0xc8, 0x6c, 0x71, 0xa7, 0x64, 0xc8, + 0x03, 0xf6, 0x41, 0x91, 0xe2, 0xaa, 0x0d, 0x16, 0x53, 0xcc, 0x0b, 0xaf, 0xcf, 0x29, 0x88, 0x88, + 0xc5, 0x52, 0x40, 0x05, 0x03, 0x49, 0xbe, 0xcf, 0x29, 0x47, 0xdf, 0x86, 0x00, 0x00, 0x0d, 0xa8, + 0x9a, 0x70, 0xe5, 0x7d, 0xbc, 0x39, 0xd0, 0xee, 0x27, 0x3b, 0xea, 0xfa, 0xaa, 0xb5, 0x90, 0x9d, + 0xfc, 0xb9, 0x2d, 0x43, 0xa0, 0xb7, 0xc5, 0xb3, 0xb4, 0x38, 0xfa, 0x6c, 0xe8, 0x55, 0x2e, 0xba, + 0xd9, 0xe1, 0xdc, 0xe1, 0x38, 0x0e, 0xf7, 0xe6, 0x8b, 0x29, 0xbc, 0xe9, 0x93, 0x90, 0x6a, 0x66, + 0x5b, 0x06, 0x91, 0x5d, 0x4c, 0xfe, 0x15, 0x15, 0x8f, 0xd5, 0xd3, 0x82, 0xfd, 0x0b, 0xc9, 0x02, + 0x71, 0x31, 0x8d, 0xc7, 0x03, 0x0e, 0x1e, 0x33, 0xb2, 0xfc, 0xd5, 0xcb, 0x72, 0x29, 0x45, 0x43, + 0xaf, 0xdd, 0x49, 0x48, 0xd3, 0x75, 0x5e, 0xb0, 0xd0, 0xb0, 0x73, 0x72, 0x7d, 0x02, 0x7b, 0x87, + 0x8e, 0x21, 0xd1, 0xd1, 0xac, 0x4a, 0xb8, 0x7d, 0x1a, 0x56, 0x42, 0x43, 0x9a, 0x3b, 0xfe, 0xda, + 0x43, 0xb4, 0x11, 0x0a, 0x88, 0x0e, 0x16, 0xf1, 0xfe, 0x0c, 0x9b, 0x62, 0x20, 0x22, 0x25, 0x69, + 0xb6, 0x6d, 0x50, 0x93, 0x3e, 0xa7, 0x40, 0x85, 0x5a, 0xd0, 0x9d, 0x33, 0x8c, 0x92, 0xf5, 0x19, + 0xdd, 0xef, 0x2b, 0x3e, 0xb3, 0xdb, 0xf7, 0x91, 0xd6, 0x0d, 0xd3, 0x21, 0x10, 0xc0, 0xaf, 0x56, + 0x95, 0xac, 0x9e, 0x9c, 0xde, 0xb4, 0x81, 0x1f, 0x47, 0xf9, 0x0f, 0xdd, 0xbe, 0x03, 0xab, 0x3a, + 0x4c, 0x2e, 0x80, 0x3a, 0xc2, 0x27, 0x1c, 0x68, 0x60, 0x65, 0xce, 0x31, 0x43, 0x9d, 0x32, 0x63, + 0xb2, 0xfc, 0xd5, 0xcb, 0x72, 0x29, 0x35, 0x43, 0xaf, 0xdd, 0x47, 0x5c, 0xf9, 0x00, 0xce, 0xda, + 0x72, 0x75, 0xe5, 0xce, 0x0f, 0xda, 0x63, 0xf1, 0xbb, 0x2f, 0x6e, 0x27, 0xaf, 0xc9, 0xf9, 0x05, + 0x2f, 0x3b, 0x77, 0x81, 0x72, 0xfe, 0x1c, 0x01, 0xb7, 0x00, 0xf3, 0x32, 0x27, 0x6c, 0xfa, 0x1e, + 0xeb, 0x80, 0x00, 0x1b, 0xe5, 0x20, 0x2d, 0x53, 0x50, 0xe1, 0x92, 0x72, 0x7d, 0x1d, 0x9b, 0x6f, + 0xaa, 0x9d, 0x8a, 0x3c, 0x5a, 0xa6, 0xa0, 0x19, 0xf7, 0x4b, 0x4f, 0x1a, 0xc7, 0x13, 0xae, 0xcf, + 0xa1, 0x80, 0x05, 0x8a, 0x1b, 0x78, 0x51, 0xe3, 0x70, 0x5e, 0x7f, 0x7a, 0x5b, 0x7b, 0x03, 0x67, + 0x5c, 0x30, 0xb4, 0xbe, 0xc5, 0xf1, 0x4d, 0x2b, 0x9d, 0x95, 0xf2, 0xe0, 0x68, 0x3f, 0x9c, 0x71, + 0xe0, 0x3c, 0x0f, 0x82, 0x06, 0xc1, 0xb1, 0xdc, 0xb2, 0xf7, 0x96, 0xcf, 0x72, 0x29, 0x25, 0x1b, + 0xaf, 0xa7, 0x16, 0x19, 0x40, 0xf1, 0x9c, 0x25, 0x92, 0x3f, 0x33, 0xb2, 0xbf, 0x20, 0xb3, 0xa0, + 0x2d, 0x5d, 0xae, 0x21, 0xf2, 0xc5, 0xb8, 0x11, 0x55, 0x11, 0x4b, 0x02, 0xc7, 0x79, 0x44, 0x5f, + 0x48, 0xb5, 0x1e, 0x16, 0x00, 0x07, 0x9a, 0xbe, 0xf0, 0x4d, 0x7d, 0x00, 0x20, 0x8a, 0x54, 0xf4, + 0x21, 0xf3, 0x81, 0x1d, 0x49, 0x66, 0x9c, 0xb5, 0xf2, 0x32, 0xa6, 0xcb, 0x96, 0xd0, 0x2c, 0xd0, + 0x20, 0x1c, 0xfa, 0xce, 0xa2, 0x43, 0x4a, 0x0f, 0xf1, 0x51, 0x82, 0x6f, 0x87, 0xde, 0x9d, 0x20, + 0x17, 0x72, 0x69, 0x02, 0xe2, 0x8d, 0x0c, 0x3f, 0x68, 0x87, 0x07, 0xaa, 0xf2, 0xd7, 0xec, 0xd4, + 0x8c, 0x01, 0xc2, 0x79, 0x02, 0xbf, 0xfb, 0xc6, 0x29, 0xa4, 0x65, 0x31, 0xdb, 0x5a, 0x65, 0xbc, + 0xb2, 0xf7, 0x96, 0xcb, 0x72, 0x39, 0x55, 0x34, 0xaf, 0xa6, 0xc8, 0x17, 0xb7, 0x7d, 0xd5, 0xca, + 0x74, 0xc2, 0x5c, 0x37, 0x77, 0xf3, 0xf9, 0x9b, 0x22, 0xa2, 0x30, 0x43, 0x24, 0x9d, 0x13, 0xb0, + 0x8c, 0x2c, 0xb4, 0x26, 0x5b, 0x91, 0xcb, 0xd0, 0x02, 0xe9, 0xea, 0x3e, 0xb9, 0xbd, 0xc7, 0xd3, + 0x12, 0x4c, 0x44, 0xcf, 0xfe, 0xee, 0xb3, 0xfc, 0xf8, 0x7d, 0xd0, 0x28, 0xd0, 0xc9, 0x5e, 0xbc, + 0x0a, 0xd6, 0xf6, 0xa7, 0x19, 0x4a, 0x53, 0x3b, 0x45, 0xfb, 0x17, 0x90, 0x9b, 0xd2, 0xf2, 0x03, + 0xea, 0x1f, 0x0f, 0x0a, 0x3d, 0x82, 0xd0, 0x92, 0x50, 0x3c, 0xaa, 0x8f, 0x0c, 0x9c, 0x2a, 0x03, + 0xb0, 0x76, 0x51, 0xab, 0x45, 0x27, 0xa8, 0x00, 0x0e, 0x31, 0xf1, 0x68, 0x25, 0x0d, 0x5f, 0x8a, + 0xf2, 0x87, 0xf8, 0x7c, 0x38, 0xdf, 0x67, 0x04, 0x92, 0xf7, 0x96, 0xcb, 0x72, 0x29, 0x25, 0x4b, + 0x69, 0xd4, 0x6d, 0x1c, 0xb8, 0xb2, 0x19, 0x82, 0x7a, 0xc5, 0x7e, 0x26, 0xbd, 0x0c, 0x51, 0xe1, + 0xb3, 0x8e, 0xe9, 0xf5, 0x0e, 0xec, 0x92, 0x79, 0x9c, 0x5d, 0x5a, 0xec, 0x4d, 0x1f, 0x9d, 0x03, + 0x5e, 0xcf, 0x10, 0x00, 0x00, 0x55, 0xb2, 0xb3, 0x23, 0xfd, 0xa2, 0x86, 0x58, 0xeb, 0xdd, 0xe8, + 0x29, 0xc3, 0x02, 0x4a, 0x66, 0x04, 0x41, 0xa8, 0x85, 0x6d, 0xc4, 0x07, 0xd7, 0x1f, 0xec, 0x46, + 0x3d, 0xbf, 0x8b, 0xf1, 0x3d, 0xb8, 0xf0, 0x7d, 0x6c, 0xd3, 0xaf, 0x80, 0x5a, 0x1b, 0x43, 0xd9, + 0x89, 0xd4, 0x91, 0xbd, 0x3c, 0xf1, 0x53, 0x86, 0x1c, 0x31, 0x38, 0x7f, 0x08, 0x17, 0x77, 0x73, + 0x60, 0x20, 0x4f, 0x4b, 0x66, 0x09, 0x76, 0x38, 0xdf, 0x8e, 0x00, 0x20, 0x19, 0xfb, 0x36, 0xe8, + 0xd2, 0xf7, 0x96, 0xcb, 0x72, 0x39, 0x55, 0x44, 0x69, 0xd5, 0x83, 0xaf, 0xc3, 0x79, 0x09, 0x0e, + 0x52, 0xd2, 0x55, 0x8d, 0x78, 0xcc, 0x3a, 0x6c, 0x65, 0xc1, 0xcc, 0x02, 0xac, 0x02, 0x40, 0x73, + 0x29, 0x63, 0x1f, 0x13, 0x45, 0x67, 0x03, 0xf9, 0x08, 0xa2, 0x20, 0x00, 0x00, 0x91, 0x15, 0xe4, + 0x27, 0x74, 0xe0, 0xf0, 0x90, 0x05, 0x2f, 0xda, 0x12, 0xdd, 0xaa, 0x2d, 0x00, 0x25, 0xf0, 0xd5, + 0xaa, 0x72, 0xa6, 0x30, 0xc6, 0x7f, 0x9d, 0x33, 0xce, 0x22, 0xcd, 0x65, 0x84, 0x35, 0xe8, 0xe2, + 0xb8, 0x0d, 0xf0, 0xa5, 0x40, 0x79, 0x01, 0x28, 0x6b, 0x0c, 0x32, 0x89, 0x4e, 0xc0, 0xe7, 0xef, + 0xb6, 0x85, 0xd9, 0x63, 0x91, 0x85, 0xee, 0x0c, 0xa5, 0x7d, 0x71, 0xf3, 0x29, 0x01, 0xbd, 0x52, + 0x57, 0xd7, 0x48, 0x13, 0x63, 0xb8, 0xb0, 0x09, 0xb2, 0xf7, 0x96, 0xcb, 0x72, 0x39, 0x55, 0x44, + 0x69, 0xd9, 0xef, 0x6c, 0xb2, 0x38, 0xbe, 0x9e, 0x51, 0xd0, 0xd9, 0x42, 0xfd, 0xf2, 0xa0, 0x1d, + 0x83, 0x0d, 0xb8, 0xeb, 0xbe, 0xfd, 0xdd, 0xc4, 0x1b, 0x86, 0xb7, 0xa3, 0x2d, 0x79, 0x91, 0xc5, + 0x58, 0x6c, 0x47, 0x20, 0x4f, 0xe9, 0x53, 0xab, 0x16, 0x22, 0x45, 0x5c, 0xa5, 0xce, 0x7c, 0x0f, + 0xd6, 0xd0, 0xd1, 0x15, 0x95, 0x10, 0xb9, 0xb1, 0x25, 0x79, 0x74, 0x07, 0x2e, 0xb8, 0x2a, 0x55, + 0x42, 0x4f, 0xd6, 0x45, 0x3d, 0x5e, 0x19, 0x86, 0x0a, 0x28, 0xc1, 0x36, 0xf7, 0xeb, 0x9e, 0x8e, + 0xe0, 0x34, 0x21, 0x87, 0x47, 0xdb, 0x03, 0x3f, 0x4a, 0x88, 0x12, 0x43, 0x86, 0x68, 0x7a, 0x1c, + 0x55, 0x66, 0x1d, 0x6b, 0x0a, 0xb3, 0x03, 0x12, 0x7e, 0x30, 0xd2, 0xc4, 0x89, 0x6a, 0xc8, 0x71, + 0xb2, 0xf7, 0x96, 0xcb, 0x72, 0x39, 0x35, 0x2c, 0x04, 0x80, 0xcf, 0x6e, 0xba, 0x53, 0x7e, 0xfc, + 0x48, 0x13, 0xb0, 0xb2, 0xe0, 0x4a, 0x27, 0x0a, 0x77, 0x12, 0x5e, 0x41, 0x52, 0xd7, 0xe2, 0x25, + 0x8a, 0x30, 0x0a, 0x64, 0x05, 0x9b, 0x60, 0x62, 0x7f, 0x5a, 0x06, 0x2a, 0x60, 0x8f, 0x2d, 0xbd, + 0x03, 0xc8, 0xaf, 0xcb, 0x2b, 0x0c, 0x6e, 0x17, 0x2d, 0x8b, 0x4d, 0xf9, 0x2d, 0x9f, 0x50, 0x28, + 0x0e, 0x87, 0x60, 0xa5, 0x32, 0x00, 0x1c, 0x80, 0x4a, 0x6b, 0x1a, 0xf1, 0x7b, 0xe5, 0x0c, 0x36, + 0x6f, 0x09, 0xe1, 0xf1, 0x39, 0x0c, 0x14, 0x43, 0xa0, 0x85, 0x69, 0x0c, 0x4d, 0x63, 0xcc, 0x13, + 0x2e, 0x06, 0x29, 0x29, 0x3e, 0x62, 0xeb, 0xea, 0xf9, 0xb3, 0x6d, 0x39, 0x82, 0x04, 0xf8, 0xe3, + 0xdc, 0xe0, 0xf8, 0x7c, 0x67, 0x13, 0x84, 0xf2, 0xab, 0x26, 0x2d, 0xe5, 0x72, 0x09, 0x55, 0x3c, + 0x00, 0x02, 0x0b, 0xfd, 0x34, 0x96, 0xcd, 0x2c, 0x13, 0xf5, 0x15, 0x62, 0xb3, 0x0c, 0xbc, 0xb0, + 0xf2, 0x55, 0x65, 0x77, 0x8a, 0x88, 0x33, 0xde, 0x29, 0xdc, 0xa7, 0xaa, 0xf1, 0x3b, 0xb7, 0xe1, + 0xf0, 0x3f, 0x7e, 0x0b, 0xd3, 0xc2, 0xca, 0x1c, 0x82, 0x29, 0x75, 0xd3, 0x40, 0x44, 0x2c, 0x35, + 0x60, 0x0b, 0xe3, 0x7c, 0xf0, 0x8d, 0x92, 0x6b, 0xa1, 0xad, 0x23, 0x83, 0x51, 0x37, 0xe4, 0x7e, + 0xdf, 0x43, 0xf8, 0xb0, 0xac, 0x3a, 0x03, 0x9d, 0xad, 0xcd, 0x2f, 0x0c, 0xc0, 0xca, 0x10, 0x80, + 0xb6, 0x78, 0x9d, 0x02, 0x39, 0xd5, 0x1b, 0xa6, 0x4b, 0x1c, 0x4b, 0x13, 0xf0, 0xf2, 0xf0, 0x3e, + 0x83, 0xc4, 0x95, 0x57, 0xc3, 0x9a, 0x38, 0xf0, 0x7c, 0x1f, 0x1c, 0x1e, 0x73, 0x25, 0x99, 0xe1, + 0xcb, 0x26, 0x2d, 0xe5, 0x72, 0x09, 0x65, 0x44, 0x00, 0x00, 0x5c, 0x72, 0x41, 0xbd, 0xd3, 0x72, + 0xc5, 0x97, 0xa1, 0x09, 0x85, 0xb7, 0xb5, 0xcd, 0x87, 0xb2, 0x14, 0xf7, 0xe4, 0xa2, 0x56, 0xf3, + 0x24, 0xd9, 0x78, 0xeb, 0x77, 0x74, 0x15, 0x2d, 0x80, 0xee, 0xd7, 0xd1, 0x9b, 0x8f, 0xd9, 0x48, + 0xcf, 0x65, 0x14, 0x8b, 0xd3, 0xed, 0x61, 0x71, 0xd3, 0x58, 0x6d, 0x8f, 0xb9, 0x3a, 0x12, 0xb8, + 0x11, 0xf0, 0x7f, 0x98, 0x0f, 0xf7, 0x0d, 0xf0, 0x6a, 0x30, 0x63, 0xc4, 0xa3, 0xf7, 0x6f, 0x30, + 0x1e, 0x7a, 0x8f, 0x5f, 0x02, 0x0a, 0xa1, 0x76, 0x95, 0x11, 0x0e, 0xb3, 0x25, 0xc1, 0x24, 0xed, + 0x84, 0x1a, 0xa0, 0x02, 0x74, 0x91, 0x93, 0xe5, 0x53, 0x6a, 0x01, 0xdb, 0x68, 0x00, 0x70, 0xec, + 0xc7, 0x0f, 0x8f, 0x3f, 0x87, 0x33, 0xd4, 0x3b, 0xab, 0x26, 0x2d, 0xe5, 0x72, 0x09, 0x65, 0x3c, + 0x00, 0x00, 0xa8, 0xe7, 0x3f, 0x87, 0x15, 0x13, 0x4d, 0x2e, 0xb6, 0x5d, 0x73, 0x44, 0x5c, 0x0f, + 0x96, 0xbd, 0x9a, 0x07, 0xe4, 0xe8, 0x25, 0x9e, 0x4e, 0xb8, 0xec, 0x83, 0xac, 0xd8, 0x21, 0x8c, + 0x49, 0xb6, 0x03, 0xf8, 0x10, 0x7d, 0x94, 0x7c, 0x00, 0xb2, 0xad, 0x2c, 0xfa, 0x1e, 0xd2, 0x5a, + 0x4d, 0xa3, 0x3e, 0x84, 0x85, 0x6e, 0x6a, 0x75, 0x12, 0x86, 0x12, 0xed, 0xfe, 0x12, 0xb6, 0x7f, + 0x44, 0x20, 0x88, 0x9f, 0x74, 0xcc, 0x4b, 0x8f, 0x8c, 0xed, 0xf2, 0x1e, 0x2e, 0xd2, 0x25, 0x93, + 0x1f, 0x5c, 0xd2, 0x6c, 0xcb, 0x4e, 0x4a, 0x01, 0xd7, 0xe0, 0xb9, 0x6d, 0x4a, 0x95, 0xcb, 0x98, + 0x5b, 0x12, 0x7c, 0x7e, 0xa4, 0x37, 0x87, 0x99, 0xc7, 0x87, 0x87, 0xc3, 0xc1, 0x87, 0x1b, 0x3b, + 0xab, 0x26, 0x2d, 0xe5, 0x72, 0x09, 0x65, 0x4c, 0x00, 0x00, 0x49, 0x66, 0xcd, 0x0f, 0xe2, 0x90, + 0x44, 0x22, 0xa7, 0xe4, 0x98, 0x09, 0x9e, 0xc8, 0x8e, 0x98, 0xff, 0x70, 0x84, 0xb0, 0x2b, 0xaf, + 0xd0, 0x13, 0xb2, 0xa3, 0xc1, 0xd0, 0xe2, 0x9a, 0xac, 0xf5, 0xeb, 0x1e, 0xa4, 0x99, 0x49, 0x97, + 0x16, 0x6d, 0x1f, 0xcc, 0x78, 0x57, 0xec, 0x44, 0x2a, 0x18, 0x86, 0x60, 0x85, 0x9d, 0x9e, 0x14, + 0x7b, 0x1b, 0x42, 0xa8, 0x40, 0x17, 0xa1, 0x89, 0xc8, 0xe9, 0xd8, 0x98, 0x78, 0x56, 0x8a, 0x32, + 0x00, 0x46, 0x03, 0x4d, 0x13, 0x13, 0x5f, 0x7c, 0x7f, 0xb6, 0x03, 0x8f, 0x67, 0x95, 0x59, 0xcf, + 0xf4, 0xc6, 0x21, 0x57, 0x38, 0x2b, 0x78, 0x77, 0x88, 0x07, 0x66, 0x1c, 0x38, 0x60, 0x39, 0xf1, + 0xf0, 0xf0, 0xf0, 0x7d, 0xe1, 0xeb, 0x5c, 0x48, 0xb2, 0xf7, 0x8a, 0xcb, 0x72, 0x09, 0x35, 0x3c, + 0xb6, 0xba, 0x95, 0xeb, 0x8c, 0xcb, 0x32, 0x16, 0x68, 0x08, 0xe8, 0xf3, 0x54, 0xed, 0xd0, 0x23, + 0xb8, 0xd8, 0xfe, 0x83, 0x49, 0x8a, 0x2c, 0xed, 0x74, 0x11, 0x5a, 0xe3, 0xe9, 0x3a, 0x74, 0x01, + 0x6f, 0x93, 0xa5, 0x68, 0xf6, 0xc2, 0xb0, 0x27, 0xab, 0xed, 0x83, 0xfe, 0x73, 0x59, 0x33, 0xf2, + 0x9a, 0xa0, 0x43, 0xd5, 0xce, 0x9d, 0xbc, 0xe6, 0x06, 0x13, 0x52, 0x2e, 0xaf, 0x50, 0x10, 0x02, + 0xb8, 0xf8, 0x78, 0x81, 0xf8, 0x21, 0xb2, 0xe7, 0xbd, 0x7c, 0x79, 0x56, 0x1d, 0xc1, 0x9f, 0x98, + 0xd9, 0x81, 0xd6, 0x38, 0x54, 0x41, 0x32, 0xa1, 0x1c, 0x62, 0x3e, 0x1e, 0x25, 0x7f, 0xb8, 0xbd, + 0x34, 0x93, 0x90, 0x08, 0x27, 0xc1, 0xe0, 0xf8, 0xf0, 0x7e, 0x1e, 0x1e, 0x1f, 0xb3, 0x62, 0x33, + 0xa6, 0x97, 0x6d, 0x65, 0x72, 0x19, 0x55, 0x4c, 0x00, 0x00, 0xad, 0xf5, 0xb8, 0x70, 0x1c, 0x3d, + 0x42, 0x6e, 0x7f, 0x08, 0x9a, 0x82, 0x46, 0x2b, 0x81, 0x4c, 0xbe, 0xaa, 0x01, 0xdb, 0x75, 0x89, + 0x79, 0x95, 0xc3, 0xbc, 0x16, 0x20, 0x87, 0x3c, 0xca, 0x15, 0xee, 0x26, 0xcf, 0x22, 0xce, 0x43, + 0xc0, 0xd3, 0x55, 0xd6, 0xac, 0x9c, 0x24, 0x66, 0xb5, 0xb0, 0x59, 0x76, 0x60, 0x23, 0xd4, 0xc8, + 0x62, 0xa3, 0x10, 0xe4, 0x25, 0x8e, 0x35, 0x1a, 0xd1, 0x49, 0x59, 0x1b, 0x8a, 0x54, 0xfc, 0x01, + 0x1a, 0xa8, 0xdf, 0x01, 0x51, 0x54, 0x5f, 0x58, 0x65, 0x22, 0xcc, 0xca, 0x31, 0xcd, 0x5f, 0xd2, + 0x6e, 0x5c, 0xbe, 0x4f, 0xc7, 0x6c, 0x0a, 0x6d, 0xc4, 0x26, 0x42, 0x1e, 0xbd, 0x86, 0x20, 0x8e, + 0x18, 0x73, 0x9e, 0x7b, 0xc0, 0x31, 0xa2, 0x2d, 0xb2, 0xf7, 0x8a, 0xcb, 0x72, 0x09, 0x45, 0x54, + 0xb7, 0x90, 0x1e, 0x6d, 0xf4, 0xf7, 0xba, 0x1c, 0x9d, 0x28, 0xa9, 0x49, 0xa0, 0xd4, 0x89, 0xa5, + 0xbb, 0x2d, 0xb1, 0xe6, 0xb5, 0x6f, 0x41, 0x76, 0x40, 0x59, 0x6b, 0x67, 0x1f, 0x5d, 0xae, 0x4c, + 0xbf, 0x68, 0x0c, 0xdc, 0x06, 0xa1, 0x0c, 0xf6, 0x02, 0xf9, 0xc2, 0x57, 0xe0, 0x02, 0xb6, 0x81, + 0x80, 0xac, 0x8b, 0x94, 0x6b, 0x89, 0xb2, 0x6d, 0x54, 0xa3, 0xf1, 0xb7, 0x49, 0x0f, 0x12, 0xc7, + 0xf2, 0x84, 0x97, 0x89, 0xf2, 0x63, 0x9f, 0x11, 0xcb, 0xbe, 0x0f, 0x91, 0x12, 0x80, 0x8a, 0x40, + 0xde, 0x5e, 0x9a, 0x92, 0xb6, 0x7b, 0xd1, 0x42, 0xf6, 0xa5, 0xef, 0x98, 0xc2, 0x4b, 0x74, 0x4e, + 0xe2, 0x39, 0x84, 0x78, 0x86, 0x3e, 0x0f, 0x1e, 0x3c, 0x38, 0xf8, 0x39, 0xd6, 0x7a, 0xf1, 0xf8, + 0xb2, 0xf7, 0x8a, 0xcb, 0x72, 0x19, 0x45, 0x5c, 0xb7, 0x8e, 0x57, 0xf0, 0x5a, 0xe1, 0xbe, 0x1d, + 0xde, 0x3a, 0xfc, 0x59, 0x2f, 0x95, 0x9a, 0x2e, 0xa3, 0x5a, 0xc6, 0xed, 0x24, 0x61, 0x10, 0xc8, + 0xff, 0x18, 0xef, 0xaa, 0x5b, 0xbc, 0xd9, 0x6e, 0xd7, 0x71, 0xb8, 0x95, 0x91, 0x0f, 0x74, 0xf3, + 0xa9, 0x87, 0x80, 0x37, 0xff, 0x65, 0xef, 0x3a, 0x46, 0x7e, 0xa1, 0x15, 0xd4, 0x23, 0x3e, 0xa5, + 0xb4, 0x7a, 0x13, 0x60, 0x61, 0xb8, 0x5d, 0xb5, 0x2b, 0xf5, 0x73, 0xb0, 0xd0, 0x20, 0x38, 0x0a, + 0x37, 0xce, 0xad, 0x7b, 0xc6, 0x3c, 0x15, 0x9e, 0x16, 0xfd, 0x0b, 0x97, 0x2f, 0x26, 0xbd, 0x18, + 0x98, 0xb9, 0xc9, 0x30, 0x13, 0x5c, 0x35, 0xf2, 0x58, 0xf2, 0x1d, 0xfa, 0xc0, 0x00, 0xf8, 0x7c, + 0x3c, 0x7c, 0x3c, 0x3e, 0x0f, 0xd7, 0x8e, 0xa9, 0xa6, 0x97, 0x6d, 0x65, 0x72, 0x19, 0x55, 0x5c, + 0x00, 0x00, 0x4a, 0xaa, 0xdf, 0xc3, 0xea, 0xc1, 0x91, 0xcc, 0x7b, 0x65, 0x32, 0xc1, 0xdf, 0x7c, + 0x26, 0xcf, 0xc7, 0xcc, 0x1c, 0x96, 0x4c, 0x19, 0xaa, 0x8e, 0x4b, 0xed, 0x33, 0xf8, 0x71, 0xfe, + 0xe8, 0x69, 0xbf, 0x44, 0x25, 0x77, 0x34, 0xe9, 0x85, 0xfc, 0xa4, 0xfb, 0xef, 0xd2, 0xaf, 0xe5, + 0x2e, 0xcb, 0xe8, 0x6f, 0x56, 0x61, 0xa8, 0x92, 0xa7, 0x6d, 0x0f, 0xd5, 0x4b, 0xc9, 0x7b, 0x9a, + 0x1d, 0x09, 0x73, 0x8f, 0x2f, 0x3d, 0xed, 0x1f, 0xf2, 0xad, 0xfc, 0x4a, 0x1e, 0x13, 0x00, 0x3a, + 0x92, 0x23, 0xce, 0x82, 0xa6, 0xca, 0xce, 0xef, 0x49, 0xb9, 0x0c, 0x13, 0x96, 0x63, 0x95, 0x58, + 0xf8, 0x90, 0xde, 0xc3, 0xc1, 0xe1, 0xe1, 0xc0, 0xf8, 0x78, 0x39, 0xde, 0x61, 0xf3, 0xcc, 0x93, + 0xc6, 0x97, 0x6d, 0x65, 0x72, 0x09, 0x55, 0x5c, 0x00, 0x00, 0x04, 0x64, 0xc2, 0x65, 0xa5, 0x9b, + 0x1b, 0xf5, 0x1e, 0x7c, 0x69, 0x02, 0x66, 0x02, 0xf5, 0x67, 0x3d, 0x74, 0xc1, 0x94, 0x28, 0x45, + 0xee, 0xf2, 0x61, 0xd7, 0x6c, 0x4f, 0xc3, 0xf7, 0xf6, 0x7c, 0x0a, 0xf2, 0xe1, 0xad, 0x80, 0xab, + 0x29, 0xb5, 0xb6, 0x0e, 0x9c, 0xc8, 0xb9, 0x73, 0xa3, 0xa4, 0x9b, 0x08, 0x78, 0x46, 0x33, 0x05, + 0x59, 0x73, 0x38, 0x7e, 0x53, 0x82, 0xab, 0xb4, 0xd8, 0x3e, 0xc0, 0xd0, 0xf4, 0x6f, 0xf1, 0x37, + 0xbc, 0x62, 0xfb, 0xf8, 0x14, 0x2f, 0x8f, 0xc0, 0xf5, 0xdc, 0xb0, 0x69, 0x43, 0x1e, 0x1f, 0x70, + 0x33, 0xad, 0xd1, 0x5e, 0xd1, 0x5a, 0x2b, 0xfb, 0xff, 0x2c, 0x90, 0x03, 0x8f, 0x31, 0xce, 0x1f, + 0x07, 0xc1, 0xf8, 0x70, 0xee, 0x79, 0xe1, 0x77, 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x55, 0x5c, + 0x00, 0x00, 0x51, 0xd6, 0xd8, 0xe3, 0xc4, 0x8c, 0x8e, 0x67, 0xea, 0x5f, 0xa8, 0xf3, 0x29, 0x5f, + 0x08, 0x8d, 0x93, 0x99, 0x5e, 0x36, 0xe5, 0x76, 0x06, 0x6a, 0x30, 0xa4, 0x32, 0x32, 0xfc, 0xce, + 0xab, 0x13, 0x89, 0xa5, 0xe1, 0x82, 0xfb, 0xd5, 0x65, 0x45, 0xa6, 0x17, 0x87, 0x51, 0xbc, 0x8a, + 0xce, 0x5a, 0xf2, 0x1a, 0xba, 0x33, 0xf1, 0x3c, 0x75, 0x96, 0x66, 0xe7, 0x9c, 0x47, 0xa8, 0x75, + 0xc4, 0xb0, 0x6c, 0x56, 0x50, 0xcf, 0xe9, 0xa7, 0xdf, 0x0d, 0xf0, 0xf8, 0x41, 0x91, 0xfe, 0x21, + 0x76, 0x2c, 0xb4, 0x59, 0x22, 0x27, 0x1f, 0x33, 0x15, 0xdd, 0x33, 0xb4, 0xf6, 0x0d, 0xb1, 0x1f, + 0x64, 0x94, 0x6f, 0x8c, 0x63, 0x87, 0x0f, 0x0f, 0x87, 0xc1, 0xe0, 0x61, 0x85, 0xde, 0x1b, 0x23, + 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x55, 0x64, 0xaf, 0xde, 0xaf, 0x87, 0x46, 0xfd, 0x1e, 0xf4, + 0xe9, 0x93, 0x89, 0xda, 0x9f, 0xac, 0x1b, 0x3a, 0x4c, 0x26, 0x6c, 0x39, 0x5b, 0x6d, 0xe6, 0x29, + 0xdb, 0x44, 0x8c, 0xe6, 0x6c, 0x78, 0x88, 0xac, 0x59, 0xea, 0xdf, 0x09, 0xef, 0x2a, 0x0c, 0x2f, + 0x2e, 0x58, 0x29, 0x55, 0xbf, 0xa4, 0xa5, 0xdc, 0xc4, 0x26, 0xde, 0x68, 0xa1, 0x2c, 0x20, 0x26, + 0xa9, 0xa6, 0xe2, 0x39, 0x2c, 0xd9, 0x0e, 0xfb, 0xb4, 0x3e, 0x3d, 0x57, 0xb4, 0xb4, 0xd7, 0xcc, + 0x19, 0x89, 0x27, 0x7d, 0xfb, 0xaa, 0x2e, 0x9c, 0x63, 0x57, 0x49, 0x39, 0x88, 0xcb, 0xb4, 0xca, + 0x52, 0x0e, 0x56, 0xea, 0xfc, 0x78, 0xfe, 0x6b, 0x73, 0xff, 0x04, 0xf1, 0xc3, 0x8f, 0x87, 0xc3, + 0xe0, 0xfb, 0x46, 0x92, 0xf0, 0x9d, 0xc8, 0xec, 0xa4, 0x4f, 0xee, 0x21, 0x72, 0x19, 0x25, 0x54, + 0x38, 0x63, 0x03, 0x45, 0x3f, 0x0d, 0x4f, 0x28, 0xdb, 0x46, 0xb1, 0x7d, 0xf8, 0x2a, 0xbb, 0xb6, + 0x9f, 0xa9, 0x15, 0xb0, 0xb3, 0x12, 0x6b, 0xe8, 0xe5, 0x1e, 0x74, 0x70, 0x91, 0x13, 0x34, 0x4d, + 0x4a, 0xb8, 0x7b, 0xe6, 0x6d, 0xfe, 0x85, 0x4e, 0xba, 0xac, 0x12, 0xff, 0x58, 0x16, 0x10, 0xc1, + 0x70, 0x7e, 0x89, 0xb4, 0x84, 0x21, 0xc7, 0x7a, 0x35, 0x56, 0x2e, 0x6a, 0x02, 0xb0, 0xa0, 0x10, + 0x49, 0x33, 0xd6, 0x57, 0x4b, 0x4a, 0x66, 0xcb, 0x3b, 0x00, 0xdc, 0xeb, 0x5f, 0x41, 0xdc, 0x40, + 0x3b, 0x3f, 0xa4, 0xf9, 0x56, 0x0c, 0x33, 0xa2, 0x2f, 0x1c, 0x8a, 0x42, 0x54, 0xae, 0xf7, 0xbb, + 0xf1, 0x2b, 0xcb, 0x91, 0x95, 0xa0, 0xf4, 0x1e, 0x19, 0xc2, 0x10, 0xe7, 0x18, 0x70, 0xfb, 0x88, + 0xa6, 0x97, 0x6d, 0x65, 0x72, 0x29, 0x35, 0x64, 0xaf, 0xdd, 0x47, 0x5d, 0x46, 0xc5, 0xfd, 0x81, + 0x82, 0x41, 0x59, 0xad, 0x3b, 0x24, 0x2f, 0x86, 0x49, 0x9b, 0xfb, 0x82, 0xb6, 0xdf, 0xf1, 0x54, + 0x52, 0xca, 0x10, 0xfd, 0x91, 0x73, 0x58, 0xbc, 0xb4, 0x47, 0x3f, 0xb9, 0x2f, 0xe5, 0x54, 0x1f, + 0xcf, 0x61, 0x2e, 0xba, 0xd3, 0x78, 0x64, 0x12, 0xb2, 0xdc, 0x19, 0xa7, 0x89, 0xd3, 0x00, 0x56, + 0x61, 0x09, 0x75, 0x8b, 0x0f, 0xa7, 0xa1, 0xdc, 0xd0, 0x15, 0xe5, 0xf5, 0x8c, 0x75, 0x21, 0x41, + 0x82, 0x9e, 0x49, 0xf0, 0xb2, 0xd8, 0xf3, 0x28, 0xf0, 0x5e, 0x11, 0x39, 0x88, 0x2e, 0xfe, 0x2f, + 0xb7, 0x8e, 0xd2, 0x1e, 0x93, 0xf1, 0x00, 0x27, 0x3a, 0x98, 0x72, 0x3e, 0x1c, 0x70, 0xc7, 0xc7, + 0x83, 0x81, 0xc8, 0xd3, 0x62, 0x23, 0x32, 0x26, 0xa4, 0x4f, 0xee, 0x21, 0x72, 0x19, 0x35, 0x6c, + 0x00, 0x06, 0x98, 0x1d, 0x78, 0x1c, 0x4f, 0xae, 0x3c, 0x0b, 0xfd, 0x61, 0x38, 0x3e, 0x2f, 0x10, + 0x1b, 0x48, 0x6c, 0x3e, 0x43, 0x08, 0x25, 0x07, 0xa7, 0xb0, 0x4f, 0x1b, 0xa4, 0xca, 0x9d, 0x68, + 0xd0, 0x2a, 0x22, 0x3e, 0x04, 0xd4, 0xe6, 0x76, 0x8c, 0xac, 0x74, 0xdb, 0x71, 0x53, 0xe8, 0x71, + 0xc9, 0x0d, 0x24, 0xb5, 0x27, 0xe4, 0xaa, 0xb5, 0xc3, 0x7f, 0xf6, 0x52, 0x81, 0xaf, 0x30, 0xf0, + 0xe6, 0x88, 0x65, 0xa9, 0xf4, 0x6a, 0x7d, 0xb6, 0x06, 0x87, 0xc4, 0x6c, 0x1a, 0x71, 0x0b, 0x20, + 0x60, 0x82, 0x24, 0xe2, 0x57, 0x3d, 0x6d, 0x5e, 0xbe, 0x37, 0xab, 0xa1, 0xa7, 0x37, 0xf7, 0x3d, + 0x5e, 0x80, 0x1c, 0xc6, 0x0c, 0x1c, 0x1c, 0x3e, 0x07, 0xc3, 0xe1, 0xe1, 0xe7, 0x36, 0xa6, 0x50, + 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x45, 0x64, 0xb0, 0xd2, 0xbf, 0xf9, 0x4d, 0xc8, 0xe1, 0x95, + 0x22, 0x86, 0x89, 0x6c, 0x3a, 0xdb, 0x05, 0x25, 0xcd, 0x73, 0x92, 0xe3, 0x20, 0xdd, 0x46, 0xff, + 0x1b, 0xb2, 0x0b, 0xc3, 0x29, 0x0b, 0xf2, 0x78, 0x08, 0xca, 0x9b, 0xfe, 0xd5, 0x80, 0xc4, 0xfc, + 0x56, 0xb7, 0xcf, 0x1e, 0x15, 0xd5, 0xab, 0x9b, 0x18, 0x7a, 0xa8, 0xcb, 0x92, 0x08, 0x39, 0x55, + 0xc6, 0x5b, 0xa6, 0xa4, 0x23, 0x76, 0x1f, 0xaa, 0xdf, 0x5c, 0xe6, 0x90, 0x38, 0xbc, 0x65, 0x6d, + 0xe8, 0x92, 0x37, 0x8c, 0x0c, 0x04, 0xec, 0x5b, 0x52, 0xce, 0x90, 0x10, 0x84, 0x3a, 0x32, 0x7a, + 0x2d, 0xdd, 0x6a, 0xed, 0x0d, 0xe2, 0xf7, 0xba, 0xbc, 0xe3, 0xce, 0x48, 0x8e, 0x38, 0x70, 0xf0, + 0xf8, 0xf0, 0x78, 0x3e, 0x65, 0x58, 0x92, 0x1e, 0xa4, 0x4f, 0xee, 0x21, 0x72, 0x19, 0x45, 0x6c, + 0x04, 0x80, 0xe4, 0x10, 0x35, 0x6d, 0x65, 0x13, 0x4b, 0xc1, 0x05, 0x47, 0x8f, 0x67, 0xa9, 0x43, + 0x6e, 0x6a, 0x3f, 0x3b, 0xa7, 0x8f, 0x82, 0xad, 0x0e, 0x6b, 0x96, 0xfe, 0xb4, 0xe7, 0x35, 0x3a, + 0x23, 0x38, 0xbf, 0x16, 0x7a, 0xea, 0x0d, 0x55, 0x7d, 0x79, 0x89, 0x69, 0xb4, 0xd4, 0x93, 0xae, + 0xfe, 0xb4, 0xed, 0x25, 0xcc, 0x22, 0xd7, 0x89, 0xf6, 0xbf, 0xff, 0x87, 0x81, 0xf5, 0xf3, 0xe3, + 0xca, 0x90, 0xb8, 0xf0, 0xc8, 0xcc, 0x49, 0x36, 0x60, 0x54, 0x98, 0x6f, 0x16, 0xeb, 0xc7, 0x5e, + 0xc1, 0x49, 0x30, 0xea, 0x12, 0xdd, 0xfa, 0x44, 0x78, 0xa4, 0xe0, 0x42, 0xc3, 0xd7, 0xcb, 0x7b, + 0x55, 0x86, 0x43, 0xb8, 0xe3, 0xcc, 0x78, 0xf0, 0x3e, 0x1e, 0x63, 0x8c, 0x78, 0xe0, 0x8a, 0x73, + 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x35, 0x74, 0x00, 0x00, 0x24, 0x08, 0x30, 0xb0, 0xd7, 0x30, + 0xa7, 0x09, 0xff, 0xd2, 0x36, 0x01, 0x9a, 0x80, 0xe8, 0x35, 0x7b, 0xa9, 0x39, 0xe9, 0x64, 0x79, + 0x72, 0x11, 0xe1, 0xc1, 0x58, 0x57, 0xc1, 0x5a, 0x8d, 0xe9, 0x3e, 0x51, 0x42, 0x9a, 0x7a, 0x76, + 0x1f, 0x1b, 0xbb, 0x9f, 0xd4, 0xa3, 0x80, 0x9d, 0xc9, 0x76, 0x9f, 0xef, 0x19, 0x52, 0xd6, 0xd9, + 0x65, 0x25, 0x59, 0x40, 0x8c, 0x26, 0x72, 0x99, 0x0b, 0xb4, 0x85, 0x4f, 0xa1, 0xd9, 0x98, 0x08, + 0x9d, 0xb0, 0xf7, 0x9d, 0xd1, 0x7c, 0x16, 0xf2, 0x54, 0x61, 0xab, 0x18, 0xf9, 0xbe, 0x9f, 0xa6, + 0x64, 0x3d, 0x79, 0x71, 0x20, 0xf1, 0x9d, 0x2f, 0xfb, 0x1f, 0xd1, 0xe7, 0x83, 0xe1, 0xfc, 0x0e, + 0x3e, 0x38, 0xdf, 0x46, 0x78, 0x7e, 0x34, 0x98, 0xc2, 0x08, 0x6e, 0xe5, 0x72, 0x09, 0x25, 0x74, + 0x00, 0x00, 0x28, 0x94, 0x58, 0x2b, 0x0d, 0xc2, 0x12, 0xc0, 0x7b, 0x14, 0x6d, 0xe5, 0x12, 0xfc, + 0x91, 0xd4, 0x8e, 0xe4, 0x6f, 0x2b, 0x95, 0xe0, 0xc6, 0xa3, 0x98, 0xee, 0x3a, 0x76, 0x26, 0x2b, + 0xaa, 0xea, 0x23, 0x52, 0xc9, 0xab, 0xb5, 0x86, 0x09, 0xf3, 0xbc, 0x38, 0x9e, 0xef, 0x63, 0x58, + 0xbc, 0x23, 0xbf, 0x52, 0xa0, 0x5c, 0x8f, 0x69, 0x25, 0x1b, 0x8f, 0x66, 0xa2, 0xb1, 0x27, 0x91, + 0x74, 0x3c, 0x6f, 0xf6, 0x7a, 0x8c, 0x50, 0x78, 0x6e, 0x13, 0xc6, 0x9c, 0xf9, 0x15, 0x1f, 0x44, + 0x22, 0x20, 0x60, 0x7a, 0xdd, 0xa0, 0x61, 0xc5, 0xe2, 0x41, 0x59, 0x0f, 0xbd, 0xb3, 0xf1, 0xe6, + 0xfe, 0x90, 0x70, 0x1f, 0x38, 0xf8, 0xfc, 0x0e, 0x07, 0x87, 0x9e, 0x7c, 0x58, 0x27, 0x8f, 0x33, + 0xa2, 0x08, 0x6e, 0xe5, 0x72, 0x09, 0x45, 0x74, 0x00, 0x00, 0x38, 0x24, 0x7a, 0xaa, 0xf1, 0xb5, + 0x93, 0x2d, 0x8b, 0xb4, 0xcd, 0x51, 0xd9, 0xd4, 0xdc, 0xad, 0x05, 0x18, 0x07, 0x9a, 0xf3, 0xe7, + 0x1a, 0x15, 0x02, 0xa7, 0x1d, 0xbf, 0x22, 0xb7, 0xc3, 0xee, 0x54, 0x97, 0x93, 0x2c, 0x33, 0x01, + 0x4c, 0xcb, 0x7d, 0x8c, 0xc7, 0x38, 0xdd, 0xbe, 0x57, 0xe4, 0x12, 0x88, 0xe7, 0x6b, 0x2c, 0x3f, + 0xbf, 0x56, 0x90, 0x87, 0x0c, 0x6f, 0x2e, 0xd4, 0xf5, 0x59, 0xfc, 0xcd, 0xb0, 0x1f, 0xdc, 0x58, + 0xfa, 0xba, 0x30, 0x0f, 0xf7, 0x99, 0x1e, 0x42, 0xed, 0xd7, 0xde, 0x15, 0x5c, 0xc1, 0x82, 0xc5, + 0xd2, 0x2d, 0x18, 0x12, 0xda, 0x95, 0x58, 0xfd, 0xf6, 0xda, 0x0d, 0x24, 0x30, 0xf8, 0x1f, 0x07, + 0xf0, 0x71, 0xce, 0x2b, 0x10, 0x77, 0xe9, 0x61, 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x45, 0x7c, + 0x00, 0xc0, 0x4e, 0x5d, 0x55, 0x18, 0x8a, 0x1b, 0xf9, 0x01, 0xef, 0x8a, 0x03, 0xaf, 0x2f, 0xd8, + 0x1d, 0x02, 0xe6, 0xea, 0xa5, 0xf5, 0xca, 0x93, 0xcd, 0x94, 0xbe, 0x68, 0xd0, 0xc2, 0x1f, 0x14, + 0x83, 0x9c, 0x9d, 0xb4, 0x54, 0xa8, 0x9e, 0x0f, 0x85, 0x55, 0x2a, 0x75, 0x8f, 0x2b, 0x9f, 0x82, + 0xbd, 0xcc, 0x06, 0xf2, 0x15, 0x20, 0x9e, 0xe7, 0xc5, 0x36, 0xc4, 0x95, 0x17, 0x24, 0xdf, 0x79, + 0x82, 0x8f, 0x97, 0xcf, 0xff, 0xf0, 0xc2, 0x26, 0x8c, 0x44, 0xb7, 0xe0, 0x90, 0x9c, 0xd9, 0xd4, + 0xa3, 0x46, 0x12, 0x28, 0x35, 0x50, 0xaf, 0x87, 0x54, 0x78, 0x46, 0x68, 0x96, 0x47, 0x5d, 0x61, + 0xc9, 0x60, 0x3c, 0x31, 0x3c, 0x2f, 0x83, 0xe1, 0xf0, 0x65, 0xe1, 0xec, 0x6d, 0xfd, 0xcc, 0x16, + 0xa4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x35, 0x74, 0x00, 0x00, 0x52, 0x04, 0x91, 0x6d, 0x5c, 0xf3, + 0x05, 0x5a, 0x7a, 0xa2, 0xe9, 0x6b, 0xde, 0x98, 0xb1, 0x08, 0xe1, 0x5c, 0x6d, 0xa1, 0xd8, 0x20, + 0xeb, 0x51, 0xe3, 0x8d, 0x00, 0x0d, 0xcd, 0x57, 0x77, 0x2a, 0x3d, 0xe2, 0x05, 0x92, 0x5e, 0xce, + 0x33, 0x58, 0x77, 0x06, 0x6c, 0x72, 0x3e, 0xbb, 0xbd, 0x8f, 0x57, 0x06, 0x05, 0x05, 0xe4, 0x54, + 0xed, 0x6a, 0x8b, 0xc1, 0x08, 0x90, 0x16, 0x09, 0xfa, 0xd0, 0x4f, 0xa6, 0x17, 0xcf, 0x43, 0x1f, + 0xa4, 0xf4, 0x91, 0xff, 0x43, 0x30, 0x3f, 0x55, 0xce, 0x77, 0xe1, 0xed, 0x08, 0xeb, 0xa6, 0xfa, + 0xd0, 0xea, 0x8f, 0x4b, 0xe1, 0x85, 0x08, 0x35, 0x3c, 0x00, 0xfc, 0x73, 0xb8, 0x87, 0x87, 0x03, + 0x83, 0xc7, 0x3c, 0xe7, 0xe5, 0x39, 0x13, 0x9a, 0xa4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x25, 0x74, + 0x00, 0x01, 0x69, 0x46, 0xb4, 0x9f, 0x19, 0x25, 0xfe, 0x51, 0x09, 0xe7, 0x36, 0x89, 0x73, 0xd8, + 0x2c, 0x7a, 0xee, 0x1e, 0xe9, 0xb5, 0x26, 0x4f, 0x67, 0x8d, 0xdb, 0xc3, 0x40, 0xe2, 0x4c, 0x9e, + 0x4d, 0x52, 0x0e, 0xfb, 0xae, 0x34, 0x4a, 0xbf, 0x58, 0xe6, 0xf5, 0xb4, 0x4c, 0xc2, 0xca, 0xd1, + 0xd9, 0xb9, 0x98, 0x6b, 0x5f, 0x35, 0x68, 0x2d, 0xc7, 0x4a, 0x92, 0xf3, 0x4b, 0x3f, 0x36, 0x3f, + 0x49, 0xfa, 0x0d, 0xff, 0x91, 0xb6, 0x06, 0x18, 0xa6, 0xea, 0x41, 0xdf, 0x3d, 0xc2, 0x2f, 0xa8, + 0x36, 0x52, 0xb9, 0xc0, 0x73, 0x29, 0x0c, 0xc8, 0xef, 0x3c, 0x32, 0x65, 0xb0, 0x1d, 0x02, 0x03, + 0xb0, 0xca, 0x8f, 0xbe, 0x83, 0x07, 0x87, 0x8e, 0x0f, 0x87, 0xe7, 0x19, 0x8d, 0x9b, 0x52, 0xe3, + 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x35, 0x7c, 0x04, 0x81, 0xd0, 0x1a, 0x52, 0x2c, 0x52, 0x15, + 0x28, 0x18, 0x3e, 0xd7, 0x70, 0x05, 0x04, 0xa9, 0xc1, 0x9b, 0xb0, 0xac, 0xd4, 0xab, 0x23, 0xda, + 0xa1, 0xbf, 0x91, 0x8a, 0xc0, 0x58, 0x6f, 0x58, 0x08, 0x9c, 0x0f, 0x00, 0xb7, 0xba, 0xd9, 0x54, + 0x84, 0x13, 0x18, 0xa9, 0xfc, 0x95, 0x18, 0x31, 0x7e, 0x3e, 0xb6, 0xdd, 0x4d, 0xac, 0xac, 0x07, + 0x61, 0xb3, 0x5f, 0x30, 0x24, 0x40, 0x83, 0x77, 0xf7, 0x94, 0x7d, 0x0b, 0xbb, 0x57, 0x86, 0xf5, + 0x0a, 0x83, 0xd3, 0x34, 0xe2, 0xcf, 0xd3, 0x8d, 0xe0, 0x66, 0x8f, 0x79, 0xc9, 0xfa, 0x5e, 0x51, + 0x59, 0x50, 0xda, 0x57, 0xcb, 0x54, 0x04, 0xf3, 0x2b, 0x01, 0xd1, 0x9c, 0x63, 0xc1, 0xe0, 0x7c, + 0x3e, 0x10, 0x32, 0x14, 0x1f, 0x1e, 0x60, 0xe4, 0xc4, 0x50, 0x05, 0x21, 0x72, 0x09, 0x15, 0x74, + 0x00, 0x00, 0x02, 0x2c, 0x30, 0x2e, 0x0d, 0x66, 0x68, 0xc2, 0xbc, 0x54, 0x27, 0x50, 0xab, 0x11, + 0x04, 0x84, 0x49, 0x68, 0xc5, 0x34, 0xb3, 0x54, 0x0e, 0x16, 0x86, 0xe7, 0x6c, 0xfb, 0x63, 0x9d, + 0xc3, 0xdc, 0x24, 0x10, 0x63, 0xce, 0xe9, 0x24, 0x92, 0x48, 0xf3, 0x98, 0x79, 0x67, 0x8a, 0xe4, + 0x9f, 0x97, 0x0b, 0x0f, 0xce, 0x76, 0x31, 0x14, 0x68, 0xed, 0xe7, 0xd9, 0xe6, 0x48, 0xbb, 0x56, + 0x45, 0x9e, 0x5a, 0xd6, 0x6e, 0xea, 0xa5, 0xdf, 0x8e, 0x6a, 0x49, 0xcd, 0xe9, 0xf3, 0x27, 0x5d, + 0xdd, 0xe3, 0x56, 0x6d, 0xa0, 0xc1, 0xa8, 0xcb, 0xcb, 0xdb, 0xb1, 0xec, 0x15, 0x06, 0x00, 0x27, + 0x33, 0xe1, 0x87, 0x87, 0x87, 0xc0, 0xf8, 0x7c, 0x1c, 0x3e, 0x1e, 0x38, 0x7c, 0x78, 0xf5, 0x9c, + 0xc4, 0x50, 0x05, 0x21, 0x72, 0x09, 0x45, 0x7c, 0x00, 0xc0, 0x5f, 0xe9, 0x53, 0x55, 0x61, 0x1d, + 0x48, 0xa7, 0xe6, 0xdf, 0xa3, 0x82, 0xa9, 0x07, 0x81, 0x70, 0x8f, 0x20, 0x75, 0xa6, 0x79, 0x46, + 0xe0, 0x77, 0x1c, 0x5f, 0x7e, 0xee, 0x1d, 0x9f, 0x64, 0x15, 0x34, 0x3e, 0xc5, 0xb1, 0x96, 0x5e, + 0x00, 0x9d, 0x21, 0xb2, 0x6d, 0x52, 0x2d, 0x5a, 0xdc, 0xb9, 0x9d, 0x1d, 0x10, 0xe3, 0x49, 0x5f, + 0xe1, 0xec, 0x9b, 0x12, 0x17, 0x55, 0x03, 0x26, 0x94, 0x27, 0xfb, 0xfd, 0x20, 0x50, 0xba, 0x96, + 0x12, 0x45, 0x19, 0x36, 0xcf, 0xdf, 0xfe, 0xc1, 0xcb, 0xc7, 0x4d, 0x49, 0x20, 0x18, 0xc8, 0x89, + 0xa4, 0x28, 0xbe, 0x84, 0xf4, 0xa5, 0x1d, 0x85, 0x1d, 0x92, 0x05, 0xb2, 0x10, 0x66, 0x70, 0xf8, + 0xf8, 0x7e, 0x3e, 0x39, 0xb2, 0x3b, 0xc9, 0xee, 0xa4, 0x65, 0x4a, 0x41, 0x72, 0x09, 0x45, 0x8c, + 0x00, 0x00, 0x4e, 0x3f, 0xf7, 0x13, 0x0a, 0x6b, 0x85, 0xc9, 0x41, 0x44, 0x68, 0x48, 0xe7, 0xbc, + 0xe6, 0x89, 0xc2, 0x30, 0xef, 0x98, 0x65, 0x30, 0x2b, 0xbb, 0x35, 0x35, 0xe5, 0xa5, 0xa6, 0xe6, + 0x74, 0xc2, 0xa8, 0x66, 0xbe, 0x85, 0x22, 0x64, 0x7f, 0xcb, 0x2d, 0xf8, 0xbb, 0xa2, 0x14, 0x8a, + 0x19, 0x37, 0x4d, 0x10, 0x0e, 0x00, 0x01, 0x79, 0x71, 0x7f, 0x48, 0x69, 0x7c, 0x3e, 0x92, 0xe6, + 0xca, 0x0b, 0x90, 0x93, 0xab, 0x94, 0x3e, 0xec, 0x3f, 0xe1, 0x78, 0xec, 0x89, 0x28, 0x05, 0xb2, + 0x58, 0x45, 0x56, 0x43, 0xe9, 0x03, 0xfa, 0x01, 0x24, 0xc2, 0xf7, 0xc4, 0x85, 0x52, 0x15, 0xcc, + 0x86, 0x2f, 0x39, 0x8e, 0x60, 0x83, 0xc7, 0xc3, 0xc7, 0xc1, 0xdf, 0x4b, 0x5a, 0x28, 0xdf, 0xac, + 0xc4, 0x65, 0x4a, 0x41, 0x72, 0x09, 0x15, 0x94, 0x00, 0x00, 0x03, 0x61, 0x03, 0x38, 0x9c, 0x15, + 0xe6, 0xba, 0x02, 0x23, 0x84, 0x2e, 0x4f, 0xb2, 0x5d, 0xd6, 0xa6, 0x86, 0xfa, 0x03, 0xdf, 0xe8, + 0xcf, 0x2a, 0x3f, 0x94, 0x7e, 0xd1, 0x30, 0x53, 0x7f, 0x9d, 0x03, 0x54, 0x70, 0x77, 0xa7, 0x48, + 0xa3, 0x59, 0xb1, 0xd3, 0xea, 0x06, 0x82, 0x64, 0x53, 0x05, 0x0e, 0x81, 0xff, 0xd4, 0x57, 0x4c, + 0xd4, 0x0e, 0x2c, 0xfb, 0xd6, 0x8f, 0x35, 0x01, 0x01, 0x6b, 0x12, 0x21, 0xe7, 0x18, 0x15, 0x88, + 0xdd, 0xe2, 0x91, 0x24, 0x7e, 0x0f, 0xa2, 0x11, 0x45, 0x01, 0xfa, 0xa1, 0x45, 0xf9, 0xb4, 0x6f, + 0x70, 0xd1, 0x7b, 0x94, 0xc2, 0xf3, 0x9a, 0xc0, 0x04, 0x27, 0xc3, 0xe1, 0x8e, 0x0f, 0x0f, 0x80, + 0xe1, 0xc1, 0xc7, 0x0f, 0x18, 0xe5, 0xa2, 0x6d, 0xa6, 0xac, 0xc9, 0x85, 0x72, 0x09, 0x25, 0x94, + 0x00, 0x00, 0x5e, 0x8d, 0x23, 0xf9, 0xfa, 0x0d, 0xf3, 0xfe, 0xe5, 0xec, 0xbb, 0x2a, 0xe6, 0x25, + 0x70, 0x55, 0x07, 0x29, 0x79, 0xeb, 0x07, 0x66, 0x63, 0x76, 0xd7, 0xcc, 0x2d, 0x82, 0xaf, 0x89, + 0xaf, 0x90, 0xd2, 0x22, 0x2f, 0x35, 0x23, 0x84, 0x07, 0x33, 0x70, 0x32, 0x04, 0x75, 0xd5, 0x24, + 0xe6, 0x5d, 0xa8, 0xfa, 0x74, 0x9e, 0x23, 0x77, 0xf0, 0xff, 0xc4, 0xfc, 0xe0, 0x94, 0x37, 0x38, + 0x93, 0x3a, 0xeb, 0xdb, 0x66, 0x7d, 0xe5, 0x69, 0xda, 0x7f, 0x6e, 0x8e, 0xe9, 0xfe, 0xb6, 0x76, + 0xe0, 0x84, 0xe3, 0xc6, 0xe0, 0x0e, 0x10, 0x20, 0xcc, 0x53, 0x94, 0x20, 0xe4, 0x04, 0xf2, 0x9c, + 0xb6, 0xcd, 0x21, 0x86, 0x0f, 0x07, 0xc1, 0xe3, 0xc1, 0xc1, 0xc3, 0x85, 0xb6, 0x64, 0xfa, 0xd7, + 0xc4, 0x65, 0x4a, 0x41, 0x72, 0x09, 0x35, 0x8c, 0x00, 0xc3, 0x2e, 0x07, 0x4d, 0xcf, 0x40, 0xe3, + 0xc4, 0x6a, 0xbd, 0x87, 0xa0, 0x32, 0xc2, 0xf7, 0x32, 0xa2, 0x74, 0xf4, 0x62, 0xeb, 0x64, 0xac, + 0x75, 0x6d, 0x4c, 0xa0, 0x2f, 0xa5, 0xe7, 0x48, 0x75, 0x1b, 0x28, 0x84, 0x57, 0x6f, 0x72, 0x54, + 0x6b, 0xb6, 0x9e, 0xda, 0x48, 0xe3, 0xa9, 0xd6, 0x41, 0xe8, 0xc3, 0x12, 0x16, 0x20, 0x2c, 0x64, + 0xee, 0xad, 0x6c, 0xbb, 0x3e, 0x84, 0xff, 0x19, 0x5e, 0x42, 0xf1, 0x29, 0xc9, 0x67, 0x6d, 0x28, + 0x00, 0x73, 0x62, 0x00, 0x42, 0xdc, 0xc5, 0x6b, 0x46, 0x21, 0x2f, 0x22, 0x4f, 0xf0, 0x2d, 0x7e, + 0x52, 0x78, 0x76, 0x5a, 0x61, 0x99, 0x0f, 0xcf, 0x0f, 0xfa, 0x38, 0x38, 0x3e, 0x1f, 0x03, 0xc3, + 0xf0, 0xfc, 0x0c, 0x1e, 0x13, 0x46, 0x22, 0x8c, 0xc4, 0x65, 0x4a, 0x41, 0x72, 0x09, 0x25, 0x94, + 0x00, 0x00, 0x90, 0x17, 0x7a, 0x70, 0x6b, 0x33, 0xce, 0x57, 0x32, 0x9d, 0x05, 0x11, 0x10, 0xf2, + 0xef, 0x31, 0xe9, 0xcb, 0x2d, 0x86, 0x68, 0xdf, 0xcc, 0x6a, 0x7b, 0x59, 0x33, 0x52, 0x51, 0x0d, + 0xb0, 0xb8, 0x03, 0xe7, 0x91, 0x37, 0xc8, 0xe4, 0xa8, 0xf5, 0x3d, 0x36, 0x19, 0x72, 0xf3, 0xb9, + 0xa8, 0x79, 0xa5, 0x47, 0x52, 0x9a, 0xfd, 0x65, 0x0a, 0x75, 0x49, 0xc3, 0x3c, 0x15, 0xc4, 0x5f, + 0x88, 0x89, 0x96, 0x84, 0xf7, 0x6e, 0xa6, 0xb3, 0x40, 0x8c, 0xb2, 0x90, 0xc1, 0xfc, 0x19, 0x01, + 0xbb, 0xaf, 0xd4, 0xb5, 0x32, 0x48, 0xcf, 0x00, 0x43, 0x21, 0xb6, 0x04, 0xe9, 0x90, 0xc8, 0x60, + 0x4e, 0xdf, 0xd1, 0x8f, 0x07, 0x83, 0xc0, 0x7f, 0x07, 0xe7, 0xf0, 0x7c, 0xe2, 0x26, 0xc3, 0x4f, + 0xa4, 0x65, 0x4a, 0x41, 0x72, 0x09, 0x35, 0x94, 0x04, 0x84, 0x22, 0x81, 0x1a, 0xea, 0x9f, 0x75, + 0xa9, 0x1c, 0xcd, 0x73, 0xa5, 0xe9, 0x4c, 0xf7, 0x7f, 0x57, 0x3a, 0xb0, 0x97, 0xb6, 0x50, 0xf2, + 0x2b, 0x83, 0x69, 0x79, 0xc0, 0xe4, 0x32, 0x57, 0x55, 0xc8, 0x42, 0x07, 0xdf, 0xdd, 0xbc, 0x12, + 0xae, 0x05, 0xac, 0xe3, 0x3c, 0x81, 0x8f, 0x42, 0x43, 0x06, 0xf3, 0x21, 0xcf, 0x0e, 0x95, 0x01, + 0x67, 0x41, 0xb2, 0x9a, 0x64, 0x4a, 0x4b, 0xd7, 0xb1, 0x74, 0xbb, 0x65, 0xde, 0xcf, 0x7c, 0x02, + 0x16, 0x4a, 0x5d, 0xa7, 0xc8, 0xf0, 0x09, 0x9b, 0xac, 0x34, 0xc2, 0x4a, 0x04, 0x0a, 0x3a, 0x0e, + 0x0b, 0x86, 0x92, 0x8e, 0x2f, 0x21, 0xbb, 0xd6, 0x1d, 0x26, 0x61, 0x1f, 0xce, 0x38, 0x7c, 0x1e, + 0x1e, 0x03, 0xe0, 0xe4, 0xab, 0x52, 0x07, 0xcb, 0xa6, 0xac, 0xc9, 0x85, 0x72, 0x09, 0x35, 0x9c, + 0x00, 0x01, 0xf1, 0x6d, 0x83, 0xa1, 0xd4, 0xf4, 0xb9, 0xa8, 0xd9, 0xf0, 0xc3, 0x81, 0x40, 0xa0, + 0x6b, 0x6f, 0x26, 0x29, 0x64, 0x9f, 0x81, 0x6c, 0x01, 0x6c, 0xf4, 0x39, 0xf2, 0x67, 0xdd, 0x4c, + 0xba, 0x3a, 0x89, 0xc6, 0xc3, 0x4d, 0x4b, 0xa5, 0xeb, 0x7e, 0x67, 0xa9, 0x33, 0x30, 0xd9, 0x02, + 0xdc, 0x2a, 0x20, 0x82, 0x64, 0x54, 0x31, 0x43, 0x09, 0x71, 0x50, 0xdb, 0x3e, 0xf8, 0xb5, 0x68, + 0x2c, 0xcc, 0xb6, 0x95, 0xf6, 0x5e, 0x3c, 0x45, 0xea, 0x9c, 0x87, 0xf4, 0x3a, 0x3d, 0x82, 0xdf, + 0x62, 0xd5, 0x42, 0x60, 0x77, 0x0f, 0x85, 0x0d, 0x6d, 0x3a, 0x14, 0xdb, 0xaf, 0x35, 0x39, 0xdd, + 0xf2, 0x67, 0x42, 0x77, 0x38, 0x67, 0x0f, 0x0e, 0x0f, 0x1f, 0x0f, 0x51, 0xcc, 0xb1, 0xe7, 0x60, + 0xa6, 0xac, 0xc9, 0x85, 0x72, 0x09, 0x25, 0x9c, 0x00, 0xc0, 0xb8, 0x4b, 0x99, 0xf0, 0xf2, 0x0c, + 0x2d, 0xf0, 0x4c, 0xc3, 0xaf, 0x13, 0x4e, 0x1f, 0x8c, 0x8a, 0x9a, 0x24, 0xc5, 0x99, 0x9a, 0x91, + 0x95, 0xe2, 0x8f, 0x32, 0x01, 0x82, 0x23, 0x68, 0x4d, 0x79, 0xdf, 0x56, 0x6a, 0xf2, 0xfe, 0x02, + 0xb9, 0x73, 0xf2, 0xb3, 0x30, 0x7e, 0xab, 0xf5, 0x2f, 0x3a, 0x05, 0xdd, 0x4b, 0xae, 0x9b, 0xeb, + 0xd4, 0x5d, 0x97, 0x8f, 0xbd, 0x60, 0xcf, 0xa5, 0x6c, 0x17, 0x1a, 0x06, 0x98, 0x13, 0x12, 0x53, + 0xd3, 0x05, 0x5e, 0xb6, 0x98, 0x44, 0x83, 0x81, 0xef, 0x1c, 0xf6, 0x2a, 0x7c, 0x1d, 0xef, 0x4c, + 0x8e, 0x59, 0xd4, 0x7d, 0x74, 0x40, 0x57, 0x4c, 0x39, 0x04, 0xfc, 0x8f, 0x0f, 0x0c, 0x1e, 0x1f, + 0x08, 0x06, 0x18, 0x7d, 0x7d, 0xe3, 0x23, 0x7c, 0xb4, 0x39, 0x63, 0x0f, 0x72, 0x09, 0x25, 0xa4, + 0x00, 0x08, 0xa1, 0xf9, 0x79, 0xc3, 0x62, 0x17, 0x8c, 0xe5, 0xf8, 0xe3, 0x83, 0x33, 0x49, 0x18, + 0x31, 0x50, 0x6e, 0x27, 0x7f, 0x64, 0x22, 0x71, 0x6f, 0x98, 0x01, 0x0c, 0xb3, 0x86, 0x92, 0xa1, + 0x6b, 0xa3, 0x38, 0x9d, 0xce, 0x85, 0x71, 0x8e, 0x9a, 0x57, 0x44, 0x64, 0x5f, 0x29, 0x86, 0x05, + 0x0b, 0xe7, 0x26, 0x83, 0xb3, 0x90, 0x09, 0x08, 0x08, 0xe4, 0x61, 0xb2, 0x83, 0xd4, 0xda, 0xaf, + 0x82, 0x14, 0xdc, 0xf4, 0x26, 0x77, 0x61, 0xab, 0x7e, 0x3c, 0xed, 0xe6, 0x7c, 0x1c, 0x13, 0x78, + 0x9c, 0xc3, 0xcf, 0x08, 0x0d, 0x37, 0x7c, 0x63, 0x60, 0x33, 0xf1, 0xbd, 0x6b, 0x61, 0x53, 0xf5, + 0x68, 0x70, 0x07, 0xe8, 0x70, 0x78, 0x38, 0x70, 0x7c, 0x31, 0xdd, 0x9e, 0x4b, 0x33, 0xa4, 0x99, + 0xd4, 0x39, 0x63, 0x0f, 0x72, 0x09, 0x35, 0xa4, 0x04, 0x80, 0xd6, 0x01, 0x56, 0x1c, 0x09, 0x80, + 0xce, 0x23, 0x84, 0xbb, 0x48, 0x63, 0x43, 0xdc, 0x0a, 0x0c, 0xfe, 0xc3, 0xdc, 0xd9, 0x96, 0x4e, + 0x52, 0x80, 0x51, 0x35, 0x32, 0xd5, 0x63, 0x95, 0xbb, 0x1a, 0xf1, 0xce, 0xf9, 0x06, 0xa0, 0x19, + 0xb4, 0xf1, 0x24, 0x17, 0xe0, 0x13, 0x36, 0x9f, 0x71, 0x62, 0x96, 0x35, 0x84, 0x6d, 0x6d, 0x53, + 0x54, 0x69, 0xeb, 0x1a, 0x82, 0x11, 0x98, 0x10, 0xce, 0x8c, 0x8f, 0x66, 0xee, 0x30, 0xb6, 0x35, + 0x9b, 0x46, 0x72, 0xb9, 0x0d, 0x30, 0x34, 0xc2, 0x4a, 0xa2, 0x39, 0x5c, 0x0e, 0x3e, 0xe0, 0xe4, + 0x0c, 0x9a, 0xaa, 0xe0, 0xe8, 0x7a, 0x26, 0x2c, 0xc0, 0x41, 0x87, 0x0f, 0x03, 0xf0, 0x3f, 0x83, + 0xd0, 0x7e, 0x0e, 0x39, 0xd2, 0x1e, 0x2d, 0x14, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x35, 0xa4, + 0x3c, 0x03, 0xc7, 0xd2, 0x58, 0x84, 0xd2, 0x42, 0xee, 0x0e, 0xb8, 0x99, 0xe2, 0x91, 0xa5, 0x83, + 0x5e, 0x05, 0x58, 0x22, 0x32, 0xa1, 0x26, 0x54, 0xca, 0x12, 0x19, 0xaa, 0xab, 0xa7, 0xce, 0x8c, + 0x15, 0xdc, 0x68, 0xf3, 0x5b, 0x40, 0x81, 0xa1, 0x68, 0x60, 0x50, 0x52, 0x39, 0x70, 0x02, 0x11, + 0xe9, 0xef, 0x7c, 0x23, 0x6e, 0xdf, 0xf5, 0xea, 0x08, 0x19, 0x4e, 0x87, 0xd7, 0x68, 0x6f, 0x49, + 0xc6, 0xb6, 0x43, 0x9b, 0xa1, 0x66, 0xfd, 0x04, 0x96, 0x38, 0x6d, 0xba, 0xdf, 0xb4, 0xc4, 0x39, + 0xab, 0xbf, 0x6f, 0xa7, 0x12, 0x9d, 0xb9, 0xba, 0x39, 0x9e, 0xba, 0x45, 0x24, 0x22, 0x64, 0xe8, + 0xe2, 0x5e, 0x7f, 0xf0, 0xf1, 0xa1, 0xe1, 0xf4, 0x7a, 0x1e, 0x8e, 0x1c, 0xc7, 0x3c, 0x13, 0xc3, + 0xc2, 0x1d, 0xcb, 0x05, 0x72, 0x29, 0x15, 0xac, 0x00, 0x01, 0x2e, 0x19, 0xf0, 0x63, 0x1c, 0x64, + 0xa4, 0x1a, 0x45, 0xa2, 0x1c, 0xb8, 0x58, 0xab, 0x02, 0x4d, 0xd4, 0xb0, 0x01, 0xd3, 0xd3, 0x49, + 0x3d, 0xbc, 0xcc, 0x10, 0xad, 0xf4, 0xb7, 0xd9, 0x0e, 0xde, 0x14, 0x13, 0x3b, 0xa2, 0x5b, 0xdf, + 0xe7, 0x6a, 0x8a, 0x55, 0x20, 0xf9, 0x25, 0x46, 0x31, 0xd0, 0xbf, 0x71, 0x24, 0x72, 0xcf, 0xc3, + 0x50, 0xa1, 0x1f, 0xff, 0x40, 0x7b, 0x49, 0xc5, 0xea, 0x4f, 0xea, 0x59, 0x34, 0x44, 0x00, 0x5e, + 0x16, 0x0c, 0xa6, 0xa5, 0x7b, 0xc7, 0xd5, 0x39, 0x09, 0xb5, 0xfa, 0x9c, 0x9b, 0x81, 0x04, 0xcd, + 0xda, 0x35, 0xb6, 0x04, 0x44, 0x76, 0x66, 0x10, 0x3b, 0xec, 0xe1, 0xe0, 0x78, 0xf8, 0x1f, 0x81, + 0xe0, 0xfc, 0x33, 0xc4, 0x35, 0x18, 0xc3, 0x35, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x25, 0xac, + 0x69, 0xd4, 0x3b, 0xc2, 0x6e, 0x3b, 0x8f, 0xa9, 0x9b, 0x85, 0x62, 0x7b, 0xa2, 0x8b, 0xf5, 0xb3, + 0x17, 0x37, 0xfa, 0x96, 0x46, 0xb5, 0xfc, 0x72, 0xf6, 0x6c, 0x85, 0xe6, 0xfa, 0x79, 0xb8, 0x97, + 0xab, 0xc6, 0xc8, 0xe1, 0xcc, 0xb6, 0x29, 0x6d, 0x0f, 0xb9, 0x1c, 0xb1, 0xa1, 0xf4, 0x84, 0xe4, + 0x4f, 0x41, 0x17, 0x6b, 0xe7, 0x81, 0xbe, 0x7c, 0x03, 0xed, 0xee, 0xb9, 0xa9, 0xf9, 0xaa, 0x8b, + 0x8b, 0x15, 0x6d, 0x75, 0xe9, 0x03, 0x57, 0x45, 0x2b, 0x8f, 0x8a, 0xf5, 0xa8, 0xa0, 0x32, 0x11, + 0x77, 0x82, 0x15, 0x9f, 0x9a, 0x12, 0x75, 0x2c, 0x79, 0xd6, 0x8f, 0xd8, 0xe4, 0xfa, 0xd4, 0x13, + 0x54, 0xe9, 0x9c, 0x2d, 0x2c, 0x1b, 0x0f, 0xe0, 0xf8, 0x38, 0xd6, 0x66, 0x61, 0x8f, 0xc4, 0x6e, + 0xc2, 0x1d, 0xcb, 0x05, 0x72, 0x29, 0x15, 0xb4, 0x00, 0xc0, 0x66, 0x40, 0x7f, 0x3a, 0x68, 0x22, + 0x23, 0x2d, 0x81, 0xe6, 0x6f, 0x70, 0xf4, 0x3d, 0x5a, 0x5e, 0x8f, 0xd3, 0x0c, 0x36, 0x37, 0xd5, + 0xb5, 0x4f, 0xd7, 0x30, 0x19, 0x34, 0xaf, 0x2d, 0x85, 0xac, 0xf0, 0x7b, 0x7f, 0xd8, 0x91, 0x6b, + 0x11, 0xac, 0x64, 0x61, 0x16, 0x67, 0x73, 0x1b, 0x3e, 0xac, 0x10, 0xc7, 0xef, 0xb0, 0x43, 0xf6, + 0xe5, 0xc4, 0x98, 0x56, 0x21, 0xf7, 0xe8, 0x18, 0xd5, 0x36, 0xa1, 0xff, 0xcd, 0xac, 0xc6, 0xdc, + 0xee, 0xb2, 0xe9, 0xc4, 0xf7, 0xf1, 0xfc, 0x63, 0xce, 0x3e, 0xf6, 0x56, 0x33, 0x17, 0x13, 0x6e, + 0x45, 0x36, 0x95, 0x4e, 0x27, 0x32, 0x34, 0x13, 0x79, 0x8c, 0x38, 0x3c, 0x3e, 0x07, 0xe0, 0xfc, + 0x1c, 0x78, 0xe7, 0xfe, 0xc6, 0x07, 0x7c, 0x03, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x05, 0xb4, + 0x05, 0xc0, 0x97, 0x65, 0xaa, 0xb1, 0xdb, 0x33, 0x1d, 0x8f, 0x3e, 0xde, 0x42, 0x98, 0x77, 0xbf, + 0xd4, 0xf9, 0x31, 0x08, 0x0c, 0x22, 0x12, 0xef, 0x7b, 0xe4, 0x87, 0x47, 0xf9, 0xda, 0x34, 0x83, + 0x46, 0x0c, 0x01, 0x06, 0xd9, 0x6d, 0xdd, 0xe9, 0x38, 0xb9, 0xd1, 0xf4, 0xcf, 0xb6, 0xa7, 0xdb, + 0xd7, 0x4b, 0x67, 0x23, 0xad, 0xb8, 0x45, 0x03, 0x3c, 0xd2, 0xf6, 0x6b, 0xc8, 0x25, 0x8d, 0x1e, + 0xca, 0x4e, 0x48, 0x15, 0xa5, 0x4d, 0xa6, 0x00, 0xf5, 0xd3, 0x5d, 0xa0, 0xfe, 0x05, 0xde, 0x77, + 0x7c, 0xfc, 0x60, 0xd6, 0x42, 0x5c, 0xf0, 0xa0, 0x41, 0x14, 0x95, 0x5a, 0x5d, 0x0e, 0xa6, 0xb1, + 0xc4, 0xe0, 0x07, 0x07, 0x80, 0xf8, 0x78, 0x1f, 0x07, 0x03, 0x81, 0xe7, 0xa4, 0x6e, 0x3b, 0x16, + 0x82, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x15, 0xac, 0x04, 0x8e, 0x7b, 0x4b, 0x56, 0xca, 0x47, 0xa0, + 0x1d, 0xcf, 0x25, 0x47, 0x3c, 0xe5, 0x19, 0x82, 0x38, 0xb7, 0xdb, 0x0f, 0x0d, 0xb5, 0x0e, 0xd5, + 0x16, 0x2a, 0x45, 0xd5, 0xcc, 0xa2, 0xee, 0xa8, 0xf6, 0xad, 0xc8, 0xbc, 0x52, 0x85, 0x3c, 0x3e, + 0x63, 0x9a, 0x3d, 0xe8, 0xf3, 0x33, 0x53, 0xe7, 0x84, 0xa8, 0x16, 0x3b, 0x22, 0xf5, 0x94, 0xd1, + 0x4c, 0xf7, 0x03, 0x0d, 0xd4, 0xb4, 0x32, 0x59, 0xc9, 0xdb, 0x48, 0x6b, 0xdd, 0x03, 0xd4, 0xcc, + 0xff, 0xb7, 0xa7, 0x97, 0x1d, 0x83, 0x14, 0x3c, 0x0c, 0x4a, 0xc6, 0x1c, 0xa0, 0x3a, 0xd4, 0xbb, + 0x13, 0xa7, 0xd6, 0xd6, 0x44, 0x48, 0x4f, 0x79, 0xf8, 0xf0, 0x7c, 0x1f, 0xa0, 0x79, 0x01, 0xfc, + 0x83, 0xe3, 0x62, 0x37, 0x13, 0x8c, 0x90, 0x47, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x05, 0xac, + 0x00, 0x01, 0x26, 0xf7, 0x02, 0x45, 0xe6, 0xe1, 0xc8, 0xab, 0xbc, 0x2d, 0x72, 0xbb, 0x90, 0xb5, + 0xde, 0x32, 0xbe, 0x60, 0x37, 0x82, 0x31, 0x31, 0x2a, 0x9b, 0x18, 0xca, 0x48, 0xf0, 0xb5, 0xa7, + 0x46, 0x73, 0x53, 0x97, 0x83, 0xc4, 0x73, 0xaf, 0xf6, 0xd0, 0x9a, 0x01, 0xf1, 0x90, 0x4a, 0xb0, + 0x29, 0x00, 0x0f, 0x84, 0xc0, 0x91, 0x07, 0x0f, 0x66, 0x06, 0x55, 0x79, 0x81, 0x03, 0xd8, 0x2b, + 0xbf, 0xce, 0xaf, 0x58, 0x00, 0x5d, 0xa3, 0x51, 0x10, 0x01, 0x67, 0x83, 0x8c, 0xc8, 0x52, 0x71, + 0x2c, 0x72, 0x07, 0x0e, 0xc5, 0xb4, 0x70, 0xf2, 0x3a, 0x97, 0x84, 0x7e, 0xd7, 0xd6, 0xae, 0xf0, + 0x5b, 0xe3, 0xe3, 0xe0, 0x1f, 0xc0, 0xfd, 0x07, 0xc3, 0xf1, 0xcb, 0x31, 0x93, 0x9d, 0xc3, 0x7d, + 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x15, 0xbc, 0x04, 0x80, 0x27, 0x96, 0xe5, 0x9f, 0x1d, 0x98, + 0x7f, 0xde, 0xa9, 0x06, 0x6d, 0xc7, 0xd7, 0xc3, 0xd7, 0x0d, 0xbe, 0xbc, 0xfe, 0xc4, 0xbb, 0x57, + 0x49, 0x0e, 0x1b, 0x73, 0x4e, 0x9e, 0xe9, 0xbd, 0x85, 0xb6, 0xb8, 0x53, 0x7b, 0x9d, 0x8f, 0x2c, + 0x36, 0x77, 0xcc, 0x79, 0x69, 0x4a, 0xd0, 0x70, 0x5a, 0x7a, 0x48, 0x88, 0xe5, 0x54, 0x6b, 0x83, + 0xad, 0x36, 0x6a, 0x20, 0xeb, 0x58, 0x8d, 0x8f, 0x2b, 0x0e, 0xd7, 0xfd, 0x28, 0x0d, 0xb4, 0x3e, + 0x8d, 0xa3, 0x0f, 0x85, 0xb9, 0xde, 0xbe, 0x06, 0x1a, 0x1a, 0x00, 0x55, 0x89, 0xa8, 0x1f, 0xec, + 0x45, 0x8a, 0x42, 0x58, 0x88, 0x64, 0xa0, 0x3e, 0xc4, 0x1f, 0x07, 0xc0, 0xf0, 0x70, 0x1f, 0x85, + 0xf0, 0x5c, 0x1f, 0xc6, 0x79, 0x30, 0x2b, 0x5c, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xf5, 0xa4, + 0x00, 0xc0, 0x1a, 0x82, 0xb9, 0xa8, 0x96, 0x29, 0xa5, 0x81, 0x9f, 0x39, 0x3b, 0x70, 0x23, 0x39, + 0x35, 0x0a, 0x95, 0x81, 0x24, 0xb3, 0xa0, 0x58, 0x6c, 0xf3, 0x5d, 0xd1, 0x39, 0xc1, 0x71, 0x21, + 0x10, 0xc2, 0x4b, 0x28, 0x89, 0x97, 0x94, 0x06, 0x7c, 0x8a, 0x5d, 0xaa, 0xba, 0x73, 0xaa, 0x37, + 0x76, 0x1c, 0x58, 0x7b, 0x78, 0x53, 0x13, 0xd9, 0x1d, 0xcc, 0x11, 0x3d, 0x87, 0xc9, 0x70, 0x9c, + 0x4a, 0xe5, 0x84, 0x26, 0x63, 0x1c, 0x21, 0xbb, 0x4e, 0x17, 0xb0, 0x80, 0x04, 0xbc, 0x61, 0x90, + 0x93, 0xc2, 0x90, 0x33, 0xf4, 0xbd, 0xe4, 0x6e, 0x57, 0xaa, 0xf0, 0xb6, 0x4b, 0x4e, 0x1f, 0xc3, + 0xe0, 0xf8, 0x3f, 0x04, 0xf5, 0x9a, 0x7e, 0xa7, 0xe0, 0x68, 0xe2, 0xe3, 0xc0, 0xf2, 0x01, 0xb3, + 0xa4, 0x65, 0x4a, 0x45, 0x72, 0x09, 0x05, 0xb4, 0x00, 0x01, 0xf0, 0xd7, 0x1b, 0x3d, 0x12, 0xfe, + 0x87, 0xbc, 0xf1, 0x46, 0x7f, 0xaf, 0xe8, 0x8e, 0xd8, 0xa8, 0x0f, 0x35, 0x81, 0xf6, 0xf3, 0x53, + 0xa1, 0xee, 0x9e, 0x47, 0x32, 0x60, 0x41, 0x56, 0x19, 0x5e, 0xcd, 0x91, 0x93, 0x3c, 0xd2, 0xb0, + 0xef, 0x03, 0x36, 0x91, 0xaa, 0x9a, 0x8f, 0x06, 0x90, 0xfe, 0x02, 0xce, 0x1f, 0xbc, 0x5f, 0x43, + 0x9e, 0x0d, 0xbf, 0x81, 0x52, 0xb4, 0xb0, 0xcf, 0x9f, 0xd6, 0xf4, 0x80, 0xe1, 0x9c, 0xa3, 0x54, + 0xa7, 0xcb, 0xae, 0x65, 0xa0, 0xbb, 0x60, 0x04, 0x5f, 0x2b, 0x58, 0x25, 0xd7, 0x1c, 0x18, 0x8c, + 0x6b, 0x87, 0x21, 0x29, 0x51, 0x92, 0xc2, 0x46, 0x2e, 0xbc, 0x38, 0x60, 0xfc, 0x0e, 0xc7, 0x87, + 0x0e, 0x0c, 0x3e, 0xde, 0x3d, 0x31, 0x45, 0x11, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xe5, 0xbc, + 0x00, 0x00, 0x40, 0x70, 0xf1, 0xc9, 0x87, 0xe9, 0x1b, 0x2a, 0x08, 0xfb, 0x57, 0x88, 0xb6, 0x0a, + 0x8e, 0x86, 0x71, 0x2b, 0x11, 0x1c, 0x02, 0x56, 0xbf, 0xbd, 0x5f, 0x02, 0xca, 0x76, 0x93, 0x36, + 0x6e, 0x68, 0xfd, 0xfe, 0x4d, 0xb0, 0x70, 0xfb, 0xfe, 0x93, 0xab, 0x7e, 0xe2, 0xdd, 0x26, 0x32, + 0x82, 0x73, 0x95, 0x17, 0x35, 0x0a, 0x59, 0x2c, 0xe7, 0x31, 0x16, 0xe6, 0xd2, 0xc5, 0x4a, 0x94, + 0x1c, 0xa5, 0xfb, 0x30, 0x7e, 0xec, 0x23, 0x7a, 0xf2, 0x1d, 0x92, 0x4f, 0xe2, 0xcf, 0xbf, 0x9a, + 0xec, 0xc2, 0x31, 0x03, 0x61, 0x81, 0x9a, 0x2b, 0xcc, 0xd6, 0xe7, 0x3f, 0x9c, 0x6e, 0x6f, 0x8f, + 0xf0, 0x5e, 0x7f, 0x21, 0xe6, 0x5f, 0xf0, 0x68, 0xfa, 0xa7, 0x28, 0x7a, 0xee, 0x4b, 0x56, 0xde, + 0xa4, 0x65, 0x4a, 0x45, 0x72, 0x08, 0xe5, 0xbc, 0x00, 0xc3, 0x1c, 0xbf, 0x03, 0xf7, 0xa9, 0x45, + 0xe6, 0xe9, 0x53, 0x2c, 0xa3, 0x3e, 0xd3, 0x05, 0x55, 0xc8, 0x9e, 0xf4, 0xf3, 0xa5, 0x9c, 0x17, + 0x7d, 0x48, 0x7e, 0x0b, 0x90, 0xe1, 0xd4, 0xae, 0x28, 0xb7, 0xfc, 0x5f, 0x7f, 0x3f, 0x84, 0x86, + 0xcc, 0x56, 0x0a, 0x75, 0x23, 0x72, 0x68, 0x0e, 0x1b, 0x59, 0xd5, 0x06, 0xfb, 0x2e, 0xaa, 0x30, + 0x5a, 0x37, 0x88, 0x6d, 0x75, 0xf8, 0x3a, 0x91, 0xbb, 0x72, 0x21, 0xfa, 0xad, 0x9a, 0x92, 0x6c, + 0x8e, 0xd5, 0xa2, 0xda, 0x89, 0x7d, 0x64, 0xf5, 0x9d, 0x55, 0xc8, 0x86, 0x06, 0x9e, 0xc1, 0x99, + 0xf2, 0x33, 0xd7, 0x89, 0xd4, 0xf2, 0x27, 0x87, 0x03, 0xf0, 0x0f, 0xe8, 0x0e, 0xe0, 0x0f, 0x03, + 0xfa, 0x38, 0x7f, 0x0f, 0x04, 0xa8, 0x31, 0x79, 0xa4, 0x65, 0x4a, 0x45, 0x72, 0x08, 0xe5, 0xbc, + 0x04, 0x82, 0x1b, 0xa4, 0x01, 0xe0, 0x13, 0x37, 0x59, 0xe0, 0xd9, 0x2b, 0x95, 0x47, 0x1c, 0x57, + 0xac, 0xdd, 0x50, 0x7d, 0xfb, 0xb2, 0x1b, 0xb9, 0xcb, 0xd5, 0xac, 0x55, 0x76, 0xde, 0x79, 0x88, + 0xff, 0xcd, 0x3f, 0xa9, 0x7c, 0x2c, 0x75, 0x4a, 0x1a, 0x26, 0xd2, 0xe1, 0x26, 0x94, 0x79, 0x08, + 0x5e, 0x25, 0x2d, 0x71, 0xa9, 0x95, 0xb9, 0x2a, 0xcf, 0x78, 0x15, 0x88, 0x84, 0x5b, 0xc3, 0xf2, + 0xca, 0x49, 0x1c, 0x54, 0xda, 0xf5, 0x9f, 0x94, 0xff, 0x8f, 0x98, 0x4a, 0x83, 0x1e, 0x01, 0x90, + 0x58, 0x53, 0x67, 0x24, 0x68, 0x8a, 0x6f, 0xc7, 0x15, 0xfc, 0x0d, 0xf5, 0x61, 0xe3, 0xfd, 0xfc, + 0x1d, 0xc3, 0xf0, 0x3f, 0x01, 0xe1, 0xd8, 0x1f, 0x07, 0xc0, 0xc6, 0xf1, 0xe7, 0x31, 0x8f, 0x73, + 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x05, 0xcc, 0x05, 0xbf, 0xeb, 0x69, 0x94, 0x99, 0xa8, 0xf1, + 0x0e, 0x92, 0x78, 0xaf, 0x01, 0xdc, 0x41, 0x3e, 0xd9, 0x4d, 0xb5, 0xc3, 0xe6, 0x5e, 0x56, 0x0e, + 0xdb, 0x69, 0x6b, 0x2a, 0x17, 0xbe, 0xd8, 0x2a, 0x71, 0xec, 0x70, 0x96, 0x8e, 0xda, 0xf1, 0x2e, + 0xeb, 0x40, 0x3f, 0x94, 0x3d, 0x1c, 0x7b, 0x73, 0x92, 0x4f, 0x25, 0x3d, 0x4a, 0x1a, 0x00, 0x96, + 0xa1, 0xee, 0xad, 0xdc, 0xf5, 0x98, 0xea, 0x1c, 0x29, 0x20, 0x01, 0x5e, 0x7b, 0x38, 0x3b, 0x43, + 0x0e, 0x27, 0xcb, 0x30, 0x93, 0xe7, 0x9e, 0xbe, 0x6f, 0xb3, 0xdf, 0x0e, 0xec, 0xc8, 0x54, 0x02, + 0x9f, 0x24, 0xdb, 0x5c, 0x4f, 0x1a, 0xd2, 0x52, 0x1d, 0xe3, 0xcf, 0x8f, 0xe0, 0xf8, 0x07, 0xf1, + 0x3a, 0x8f, 0x08, 0x82, 0x63, 0x92, 0x07, 0x32, 0x82, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xe5, 0xd4, + 0x00, 0x06, 0x94, 0xa8, 0xb5, 0xb8, 0x7f, 0xec, 0x80, 0x29, 0x5d, 0xd8, 0xc1, 0x32, 0xdd, 0xd1, + 0x05, 0x53, 0x33, 0x6b, 0x58, 0x00, 0xcf, 0x48, 0xa4, 0xd6, 0xce, 0x18, 0x6a, 0xbe, 0xec, 0x08, + 0xa1, 0x16, 0x39, 0xd6, 0xcd, 0x75, 0x06, 0x8e, 0xdc, 0x22, 0x03, 0x83, 0x24, 0xd1, 0x5e, 0x0c, + 0x6c, 0xa1, 0xa4, 0x36, 0x06, 0xb8, 0xc8, 0x16, 0x32, 0xbe, 0x8c, 0x78, 0x04, 0xbe, 0x84, 0xf2, + 0x4a, 0xed, 0x94, 0x75, 0xde, 0xb4, 0xdc, 0x91, 0x8d, 0xb5, 0x96, 0x61, 0x43, 0xee, 0x3e, 0x69, + 0x03, 0x84, 0xb5, 0x43, 0xad, 0xa5, 0x35, 0x42, 0x75, 0x08, 0x3d, 0x0a, 0x27, 0x76, 0x6c, 0x7b, + 0xc3, 0x07, 0x81, 0xf9, 0x81, 0xf8, 0x7c, 0x07, 0xe8, 0xf1, 0xa2, 0x5e, 0x3c, 0xf4, 0x29, 0x51, + 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xf5, 0xcc, 0x04, 0x8e, 0x04, 0x00, 0xff, 0x7a, 0x54, 0x6b, + 0x4a, 0x61, 0x23, 0x36, 0xd4, 0x6b, 0x8f, 0x20, 0x5c, 0xa3, 0xfb, 0x43, 0xde, 0x27, 0x6a, 0x30, + 0x65, 0xd6, 0x6f, 0x2c, 0x6b, 0xa1, 0x25, 0xbc, 0xa3, 0x4e, 0xbf, 0x32, 0x9b, 0xf0, 0x68, 0x3d, + 0xf9, 0xe8, 0x10, 0x34, 0xfa, 0xb4, 0x5d, 0x40, 0x02, 0x97, 0xa7, 0x90, 0x0c, 0xf9, 0xdf, 0x6c, + 0x21, 0xad, 0x56, 0xcc, 0xe4, 0xb6, 0xc0, 0x7b, 0x8f, 0x5b, 0x15, 0xe2, 0x34, 0xc8, 0x47, 0x2b, + 0x32, 0xc7, 0x48, 0x70, 0x23, 0xd9, 0x08, 0x31, 0x02, 0xa4, 0x99, 0x10, 0xf0, 0x20, 0x72, 0x89, + 0x11, 0xe2, 0x4b, 0x9a, 0x0b, 0x0a, 0x13, 0x04, 0xe1, 0xe0, 0x3c, 0x2e, 0x60, 0x7e, 0x1f, 0xc0, + 0x78, 0x7c, 0x78, 0xce, 0x37, 0x58, 0x68, 0xd8, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xe5, 0xcc, + 0x04, 0x90, 0x07, 0x33, 0x07, 0x60, 0xfd, 0xe3, 0xec, 0x7e, 0x9b, 0xe3, 0xd1, 0x30, 0x29, 0x22, + 0x2a, 0x23, 0x7b, 0x65, 0x26, 0x4d, 0xba, 0xfc, 0xd2, 0xfa, 0xe0, 0xf9, 0x20, 0x2f, 0x01, 0x72, + 0x86, 0xaf, 0x5b, 0x7f, 0x49, 0xaf, 0xbc, 0xbb, 0x31, 0x35, 0x9b, 0xda, 0xbf, 0x63, 0x88, 0xd5, + 0x5e, 0x2c, 0xbf, 0xb7, 0x44, 0xc1, 0xf9, 0x23, 0xde, 0x5a, 0x01, 0x4a, 0x44, 0x41, 0x2c, 0x32, + 0x34, 0x86, 0xac, 0x49, 0x62, 0xef, 0xb7, 0x8b, 0xfe, 0xfa, 0xf2, 0x66, 0x0e, 0x88, 0x72, 0x90, + 0x88, 0x7b, 0x83, 0x9b, 0x05, 0xd1, 0x51, 0x8f, 0xbf, 0x79, 0xc1, 0x79, 0xf2, 0x78, 0x40, 0x8c, + 0x3c, 0x3e, 0x03, 0xfc, 0x2d, 0xc1, 0xf8, 0x0f, 0x0f, 0xba, 0x8c, 0x86, 0x98, 0x47, 0x5c, 0xf2, + 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xf5, 0xcc, 0x00, 0xcc, 0x0f, 0x92, 0x03, 0x75, 0x12, 0xdb, + 0x72, 0x37, 0x8b, 0x66, 0xc9, 0xe9, 0x64, 0xa3, 0x17, 0x5f, 0xa0, 0x2e, 0x6e, 0x60, 0xc1, 0xa6, + 0x8c, 0xfd, 0x02, 0x3b, 0xa7, 0x98, 0xa7, 0xda, 0x9e, 0x16, 0xcb, 0x8d, 0x65, 0x7a, 0x7e, 0xb7, + 0xc4, 0xf5, 0x37, 0x88, 0x71, 0x38, 0x2c, 0x32, 0x52, 0x17, 0x70, 0x3f, 0xd1, 0x6a, 0x6d, 0x8d, + 0xed, 0x5f, 0xa4, 0xed, 0x42, 0x06, 0x4b, 0xa8, 0x5e, 0x62, 0x4e, 0x4b, 0x02, 0xe7, 0xfe, 0x54, + 0xde, 0x88, 0xf7, 0xfd, 0xd3, 0x3d, 0x6f, 0x1b, 0xc9, 0x94, 0x74, 0x57, 0xc4, 0x3d, 0xdc, 0x54, + 0x91, 0xd5, 0xe7, 0x36, 0x17, 0x11, 0xac, 0x28, 0x2b, 0xe6, 0x1c, 0x1f, 0x03, 0xe4, 0xfc, 0x1f, + 0x85, 0x78, 0xe3, 0x32, 0x78, 0x57, 0x69, 0x2d, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xf5, 0xdc, + 0x00, 0x06, 0xa0, 0x3e, 0xa9, 0x76, 0x09, 0x2a, 0x4e, 0xa0, 0xcb, 0xdc, 0xf0, 0x30, 0x4d, 0xdf, + 0x8d, 0xd3, 0x19, 0x7b, 0x2c, 0x79, 0x1e, 0x6a, 0x23, 0xc5, 0xf9, 0x46, 0x91, 0xd0, 0x26, 0x1b, + 0xf8, 0x46, 0x50, 0x56, 0x83, 0x98, 0x27, 0x1a, 0xa7, 0x7c, 0xeb, 0x90, 0x9b, 0x94, 0x6f, 0x17, + 0x54, 0x89, 0x21, 0x94, 0xd2, 0x04, 0x00, 0x45, 0x98, 0x30, 0xb4, 0xcf, 0x4a, 0x90, 0xed, 0x77, + 0x51, 0x67, 0xe4, 0xf1, 0xd3, 0xaf, 0xec, 0x3c, 0x03, 0x0a, 0xf3, 0x83, 0xf5, 0x40, 0x49, 0x3f, + 0x15, 0x21, 0xf4, 0x41, 0x6f, 0xd7, 0x58, 0xc5, 0x6e, 0xcd, 0x4a, 0xbd, 0x91, 0x6f, 0x64, 0x08, + 0xf0, 0xf8, 0x7e, 0x1f, 0x80, 0xfe, 0x1f, 0xc7, 0x97, 0xb8, 0x63, 0x70, 0x0c, 0x18, 0x3f, 0xc8, + 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x05, 0xd4, 0x00, 0x00, 0xf2, 0xb4, 0x00, 0x7b, 0xf6, 0x30, + 0x4b, 0xd2, 0x57, 0xae, 0x2e, 0xf3, 0x08, 0x05, 0x34, 0x38, 0x6e, 0xac, 0xfd, 0x94, 0xb9, 0xf9, + 0xd8, 0x5b, 0xef, 0x7c, 0x81, 0x95, 0xe9, 0xe0, 0x6b, 0x7d, 0x8a, 0xb8, 0x6f, 0x66, 0x82, 0x11, + 0xb7, 0x6a, 0x63, 0x28, 0xf7, 0x91, 0x58, 0x38, 0xce, 0xc8, 0x53, 0xb2, 0x9a, 0xb4, 0x07, 0x3c, + 0x81, 0x27, 0x4a, 0x88, 0x33, 0x6d, 0x37, 0xb1, 0xa7, 0xcb, 0x6e, 0xdd, 0xc7, 0x9a, 0x6e, 0xdc, + 0xb5, 0x21, 0x7f, 0xd3, 0x02, 0x0a, 0x79, 0x83, 0xb4, 0xaf, 0x74, 0x1b, 0xb4, 0x0f, 0xe2, 0xaf, + 0x15, 0x6d, 0x0d, 0x01, 0xc7, 0x02, 0x06, 0x33, 0xeb, 0xd8, 0x33, 0xe6, 0xe5, 0xe3, 0x2e, 0xf0, + 0x5f, 0x0f, 0x21, 0xcb, 0x6d, 0x86, 0x06, 0xb9, 0xb4, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd5, 0xdc, + 0x00, 0xc3, 0xf5, 0xf9, 0xd6, 0xe4, 0x55, 0xeb, 0x8c, 0xb5, 0x6c, 0xc9, 0xe2, 0x92, 0x54, 0xcb, + 0x36, 0x2d, 0x90, 0x55, 0x22, 0x29, 0x91, 0xbe, 0xfd, 0xd4, 0xba, 0x06, 0xcb, 0x7d, 0x5a, 0x1e, + 0x5a, 0xef, 0xb4, 0x5e, 0x44, 0xee, 0xd9, 0x9d, 0xae, 0x61, 0xfc, 0x66, 0x66, 0x1d, 0x2d, 0xd8, + 0x88, 0xd4, 0x4b, 0xf5, 0x0f, 0xcc, 0x70, 0xc7, 0x5e, 0xa4, 0x1b, 0xa0, 0xcc, 0x6f, 0x14, 0xa2, + 0x28, 0x84, 0x56, 0xdf, 0x9b, 0x9b, 0x1d, 0x31, 0x77, 0x7b, 0xbc, 0x6f, 0x3d, 0xae, 0x37, 0x24, + 0xe4, 0xef, 0xab, 0xb6, 0xc0, 0x00, 0xad, 0x44, 0xf1, 0x9e, 0x98, 0x19, 0x0b, 0xfd, 0x70, 0x67, + 0x9f, 0x9e, 0x1e, 0x87, 0xa1, 0xa0, 0xd0, 0x1c, 0x9d, 0x1a, 0x3d, 0x1b, 0xf6, 0x2c, 0xd9, 0xd3, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xc5, 0xdc, 0x04, 0x8c, 0x0a, 0xd0, 0x8b, 0x08, 0x59, 0xea, + 0x37, 0x08, 0xa4, 0x24, 0x01, 0x0c, 0xa3, 0xaa, 0xb6, 0x2b, 0xca, 0x29, 0x89, 0x31, 0x5d, 0xa3, + 0xf5, 0xdc, 0xd1, 0x78, 0x34, 0xda, 0xce, 0xbe, 0x18, 0xff, 0x18, 0xd4, 0x8a, 0xf4, 0x80, 0x40, + 0x8e, 0xe5, 0x8f, 0x26, 0x02, 0xa1, 0x19, 0x3a, 0xa7, 0x4a, 0x85, 0x8b, 0xc8, 0xe2, 0xed, 0xfa, + 0xd3, 0x58, 0x19, 0xea, 0xe5, 0x7d, 0x86, 0xe8, 0x1b, 0x59, 0x73, 0x0f, 0x92, 0xfd, 0x6e, 0xb9, + 0x05, 0xb2, 0x21, 0x1d, 0xdd, 0xbc, 0xea, 0xfe, 0x15, 0xf9, 0x96, 0x7e, 0x39, 0x45, 0xa1, 0xfa, + 0xf9, 0x77, 0xca, 0x50, 0x47, 0x81, 0xa3, 0x4d, 0xf3, 0xc3, 0xc1, 0xce, 0x1d, 0x03, 0x9c, 0x9d, + 0x0b, 0x02, 0x9f, 0x43, 0x9d, 0x67, 0x93, 0xab, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xe5, 0xdc, + 0x00, 0x08, 0xa3, 0xf4, 0x59, 0x6e, 0x0b, 0x46, 0xee, 0xce, 0x77, 0xfe, 0x27, 0x55, 0xf6, 0xd6, + 0xf4, 0xf7, 0x2b, 0xab, 0xb3, 0x99, 0x0c, 0x42, 0xe4, 0x05, 0x9d, 0x21, 0x3b, 0x34, 0x6d, 0x0c, + 0x33, 0xf2, 0xee, 0x72, 0x2e, 0xd1, 0x1e, 0xeb, 0x70, 0x36, 0xd9, 0x45, 0x08, 0xd7, 0x3c, 0x79, + 0x05, 0x63, 0x41, 0x7c, 0x78, 0xc3, 0xaa, 0x76, 0x14, 0x22, 0xdf, 0xc4, 0x5b, 0x1b, 0x23, 0x88, + 0xac, 0xd9, 0x38, 0x7e, 0x84, 0x1c, 0x81, 0x80, 0x3c, 0x57, 0xa7, 0x2c, 0xe8, 0xf2, 0x59, 0xb4, + 0x9c, 0x8a, 0x56, 0xb3, 0xd0, 0x29, 0x1a, 0x0e, 0x3f, 0x19, 0x29, 0xbb, 0x8a, 0xf3, 0xfb, 0x03, + 0x31, 0xcf, 0xc1, 0xe0, 0x70, 0x70, 0xc6, 0x1f, 0x0d, 0x8e, 0x43, 0xf0, 0x73, 0xc1, 0x44, 0xfc, + 0xb4, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xf5, 0xe4, 0x00, 0x04, 0x6e, 0x94, 0x9d, 0xaa, 0x6b, 0x43, + 0x9d, 0x6b, 0x8f, 0x14, 0x3b, 0xb0, 0x78, 0xb0, 0x33, 0x31, 0xc1, 0x8e, 0xf3, 0x75, 0x71, 0xbe, + 0xb9, 0x84, 0x5c, 0xfb, 0x3d, 0x2c, 0x0c, 0x32, 0x6a, 0xef, 0x90, 0x51, 0xdf, 0x6f, 0x43, 0x7b, + 0x96, 0x17, 0xd9, 0x81, 0x2c, 0xb6, 0x12, 0xd9, 0x8f, 0x4f, 0xbf, 0x44, 0xcc, 0x46, 0xab, 0xef, + 0xf3, 0xd1, 0xa1, 0x10, 0x28, 0xa4, 0x6d, 0xcc, 0x77, 0xd3, 0xf8, 0xd5, 0xd5, 0x95, 0xcf, 0xde, + 0xb4, 0x9e, 0xeb, 0xb2, 0x3f, 0x7d, 0xef, 0xbd, 0x2d, 0x86, 0x29, 0xfe, 0xd9, 0x70, 0x7a, 0x3d, + 0x48, 0xcd, 0xf0, 0x03, 0xe4, 0x04, 0x18, 0x8a, 0xce, 0x76, 0x66, 0x0c, 0x3c, 0x1c, 0x27, 0x33, + 0x81, 0x0e, 0x97, 0xd0, 0x77, 0xa3, 0x52, 0xe1, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd5, 0xf4, + 0x04, 0x80, 0xb9, 0xd1, 0xea, 0x0b, 0x6d, 0x5b, 0x0a, 0xd6, 0xda, 0xe7, 0xa9, 0xe7, 0x58, 0x40, + 0x74, 0xdb, 0x35, 0xf6, 0x73, 0xc7, 0x81, 0x7c, 0xc1, 0x6e, 0xd3, 0xa8, 0xaa, 0xef, 0xe2, 0xf7, + 0x20, 0x16, 0xbc, 0x3e, 0x32, 0x32, 0x17, 0x5d, 0xfc, 0x7b, 0x2b, 0x95, 0x6c, 0x89, 0x9a, 0xd0, + 0xe4, 0xe9, 0x63, 0x5b, 0x56, 0x4f, 0x74, 0x16, 0x51, 0x96, 0x07, 0xe2, 0x2b, 0x78, 0xb7, 0x22, + 0x11, 0x0b, 0x86, 0x06, 0xa7, 0xa1, 0x93, 0xb8, 0xc4, 0x8a, 0x3f, 0x17, 0xb6, 0xef, 0x2c, 0x0f, + 0xa1, 0x7c, 0x56, 0x44, 0x22, 0x73, 0x7b, 0x4e, 0x3f, 0xbd, 0x5e, 0x9d, 0x79, 0xad, 0xbc, 0x57, + 0x4c, 0xe6, 0x07, 0x83, 0x18, 0x4f, 0x1f, 0x26, 0x8e, 0x1f, 0x1d, 0x8f, 0x84, 0x73, 0x97, 0x93, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xf5, 0xe4, 0x05, 0xc0, 0xee, 0xc4, 0xb6, 0xf1, 0x78, 0x1c, + 0x92, 0xa3, 0x44, 0xa6, 0x8e, 0x34, 0x54, 0x3c, 0xf9, 0x70, 0x11, 0x72, 0xf7, 0xc3, 0xf8, 0xad, + 0x77, 0x05, 0x7e, 0x9c, 0x87, 0x4e, 0x37, 0xfe, 0x70, 0x58, 0x3e, 0x56, 0xb0, 0x6c, 0xca, 0xfc, + 0x7e, 0x7c, 0x9f, 0x2c, 0xf0, 0x7f, 0x0a, 0x88, 0xec, 0x6f, 0x83, 0xfd, 0xe8, 0xd4, 0x8a, 0x04, + 0x1f, 0xd5, 0x6c, 0x5e, 0x75, 0xdb, 0x2f, 0x2b, 0x44, 0x69, 0xbf, 0xdc, 0xeb, 0x71, 0xe6, 0xd0, + 0x53, 0xf1, 0xfa, 0x6d, 0x0f, 0xe1, 0x1e, 0x1f, 0x47, 0xe4, 0xbc, 0x23, 0x78, 0x89, 0xe5, 0x78, + 0x8c, 0x68, 0xc7, 0x3b, 0x54, 0x4e, 0xf7, 0x80, 0xbe, 0x3c, 0x78, 0x7c, 0x3e, 0x78, 0x78, 0xe3, + 0x17, 0x81, 0x1a, 0x4a, 0x1d, 0xec, 0x1a, 0xe3, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd5, 0xf4, + 0x00, 0x07, 0xf9, 0xc9, 0xf0, 0xe6, 0x4c, 0x15, 0x5e, 0x3d, 0x52, 0x3a, 0xa8, 0x4a, 0x61, 0xe0, + 0x03, 0x4e, 0x61, 0x7a, 0xef, 0x54, 0x60, 0x34, 0x45, 0x5c, 0xd9, 0x41, 0xfc, 0x6e, 0x6c, 0x25, + 0xf6, 0xab, 0x6e, 0x7a, 0x2c, 0x3f, 0x2a, 0x6b, 0x3c, 0x46, 0x44, 0x43, 0x08, 0x95, 0xcd, 0xda, + 0xc3, 0x53, 0x0a, 0xac, 0x72, 0x02, 0x3e, 0xd6, 0x8c, 0xcc, 0x32, 0x1c, 0x4d, 0x64, 0x94, 0xc5, + 0xfb, 0xb0, 0x68, 0xe7, 0xaf, 0x6e, 0xbc, 0x9e, 0xbf, 0x27, 0xe0, 0x0a, 0x84, 0x6b, 0x28, 0x53, + 0xa7, 0xc1, 0xf3, 0xf1, 0xad, 0x27, 0xf2, 0xd6, 0xad, 0x45, 0x33, 0x0f, 0xde, 0x9d, 0x6b, 0x43, + 0x01, 0xe1, 0xf1, 0xe0, 0x78, 0x68, 0x2c, 0x12, 0x73, 0x05, 0x4b, 0x4c, 0xd9, 0x79, 0xa3, 0x4c, + 0xb4, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xe5, 0xfc, 0x04, 0x83, 0xf2, 0x43, 0x5c, 0x3b, 0xb7, 0x22, + 0xf4, 0x83, 0x1a, 0x13, 0xf1, 0x44, 0x26, 0x9c, 0x93, 0xed, 0xf4, 0xfd, 0xc0, 0xb6, 0xef, 0xcb, + 0x43, 0x5d, 0xde, 0xf0, 0xeb, 0x01, 0x1b, 0x76, 0x82, 0xbb, 0x78, 0xa2, 0x26, 0x9b, 0x63, 0xb0, + 0x91, 0xa5, 0xd2, 0xd7, 0xc5, 0x54, 0xd9, 0x20, 0x51, 0x6e, 0xb0, 0x0b, 0x7d, 0x13, 0x46, 0x39, + 0xbd, 0xf9, 0x45, 0xeb, 0x7d, 0x41, 0xb4, 0x37, 0x3e, 0x09, 0xb5, 0xd2, 0xec, 0x67, 0x93, 0xcf, + 0x6d, 0xa9, 0xd0, 0x67, 0x10, 0x80, 0x08, 0x13, 0x66, 0x42, 0xe1, 0x77, 0x38, 0x4c, 0x54, 0xb4, + 0x87, 0xe5, 0xff, 0x95, 0x61, 0x25, 0x4d, 0x18, 0xff, 0x47, 0xbe, 0x3e, 0x1c, 0x16, 0xea, 0x1c, + 0x5e, 0x0f, 0x0f, 0x2b, 0x4f, 0x45, 0xce, 0x0b, 0xb4, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd5, 0xf4, + 0x04, 0x80, 0x89, 0x37, 0xc9, 0xab, 0x0b, 0x9d, 0xb6, 0x8a, 0xd4, 0x9b, 0x41, 0x45, 0x5a, 0xba, + 0xc7, 0xa5, 0x1b, 0x4e, 0xe8, 0xe3, 0x3f, 0xbf, 0x5d, 0x32, 0x99, 0xb8, 0x18, 0xb0, 0x4c, 0x0b, + 0x7a, 0xf4, 0x78, 0xe5, 0xb0, 0x90, 0x99, 0xaa, 0xf0, 0xb4, 0xc5, 0xec, 0xc4, 0x4f, 0xae, 0x75, + 0x57, 0x9f, 0x7b, 0x46, 0x7c, 0x0a, 0xee, 0xf1, 0x41, 0xc1, 0x74, 0x4d, 0x0b, 0xe1, 0xa3, 0x75, + 0xeb, 0x64, 0xc8, 0xbc, 0x29, 0x00, 0x21, 0x91, 0x9d, 0x0c, 0x29, 0x1f, 0xcd, 0xc2, 0x19, 0xc7, + 0x70, 0x7f, 0x12, 0x30, 0x3d, 0x9a, 0x37, 0xa6, 0x83, 0x08, 0x2c, 0x75, 0xf2, 0x65, 0x9f, 0x60, + 0x73, 0xe3, 0xf1, 0xc0, 0x7c, 0x3c, 0x7e, 0x1e, 0x78, 0xe1, 0xf5, 0xe8, 0xee, 0x3e, 0x7d, 0xb9, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xe5, 0xfc, 0x04, 0x80, 0x29, 0xc1, 0xc4, 0x2f, 0x9d, 0x30, + 0x83, 0x82, 0x73, 0x6c, 0x33, 0xb6, 0x37, 0xcf, 0xec, 0xb3, 0xe8, 0x48, 0x24, 0xd6, 0x82, 0xab, + 0x23, 0xcb, 0x9d, 0xcb, 0x6b, 0x1a, 0xad, 0x96, 0x32, 0x3a, 0xed, 0x43, 0xf1, 0xdf, 0x02, 0xde, + 0x66, 0x4a, 0x8b, 0x5c, 0x1a, 0x8f, 0x70, 0x0a, 0xf2, 0xaa, 0x04, 0x2d, 0xa6, 0x23, 0x35, 0x8a, + 0x7f, 0x1e, 0xf9, 0x24, 0xec, 0x67, 0x7e, 0x7f, 0x1e, 0x7d, 0x4c, 0x99, 0x43, 0x3d, 0xb8, 0xed, + 0xef, 0xea, 0xb6, 0x25, 0x06, 0x20, 0x69, 0x25, 0xe4, 0x97, 0xd0, 0x9d, 0x0c, 0xb5, 0x3d, 0x3d, + 0x08, 0xe2, 0x54, 0x9d, 0xc2, 0xf8, 0x5f, 0x70, 0x78, 0xf1, 0xf8, 0x3e, 0x3c, 0x2e, 0x0f, 0xc4, + 0x20, 0x9f, 0x80, 0x42, 0x6e, 0xe7, 0xc6, 0x17, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x09, 0x05, 0xf4, + 0x04, 0x80, 0x62, 0xdf, 0x2f, 0x51, 0xcc, 0x97, 0x7e, 0x59, 0xa8, 0x2a, 0xd7, 0x36, 0x6c, 0x58, + 0x4a, 0x4b, 0x7b, 0x51, 0x19, 0x51, 0x3d, 0xb2, 0x05, 0xfc, 0xe0, 0xcc, 0x89, 0xa9, 0xc6, 0xc7, + 0x24, 0xdd, 0x06, 0x2d, 0x74, 0xb4, 0x72, 0xc4, 0xbe, 0x2b, 0x17, 0xb5, 0x87, 0x6e, 0x3f, 0x6a, + 0x84, 0x9c, 0x59, 0x7a, 0x07, 0x64, 0xf0, 0x8a, 0x54, 0x2c, 0x1a, 0x5e, 0x8a, 0x5d, 0xd3, 0x8b, + 0xe0, 0x6f, 0x06, 0x0d, 0x7a, 0xc8, 0x6d, 0x9f, 0x0e, 0x15, 0x6b, 0x8f, 0xa7, 0xdf, 0x39, 0x2f, + 0x45, 0x1a, 0xdb, 0xc4, 0x36, 0xfc, 0xa2, 0xa5, 0xb1, 0x93, 0xd4, 0xea, 0x73, 0x91, 0x1f, 0x83, + 0x03, 0xc3, 0x81, 0xe0, 0x70, 0xf0, 0xf1, 0x87, 0x0b, 0x18, 0xfe, 0x55, 0xc4, 0xfc, 0x70, 0xde, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xe6, 0x04, 0x00, 0x10, 0xbe, 0xbf, 0xc1, 0x4c, 0x3c, 0x03, + 0xe8, 0xeb, 0x0a, 0x6c, 0x91, 0xcb, 0xa3, 0xf1, 0xe3, 0xd5, 0x64, 0x95, 0x46, 0x53, 0xe1, 0x02, + 0x5f, 0x30, 0x79, 0x44, 0xd0, 0x69, 0x4d, 0xa1, 0xeb, 0x7f, 0x6f, 0x76, 0x59, 0x9b, 0xd4, 0x88, + 0x22, 0x14, 0x38, 0x7f, 0xaa, 0x4e, 0x5f, 0x90, 0xb9, 0x20, 0xf6, 0x8e, 0x58, 0x89, 0x05, 0x85, + 0xbf, 0x3f, 0xbc, 0x8b, 0xb2, 0x6c, 0xaa, 0x18, 0x66, 0xd8, 0xdf, 0x29, 0xea, 0x75, 0xf3, 0xb3, + 0x33, 0x17, 0x3a, 0x15, 0x63, 0xe0, 0x66, 0x04, 0x1d, 0xd6, 0x2b, 0x29, 0x01, 0x11, 0x48, 0x86, + 0xfa, 0x15, 0x8a, 0xd2, 0x06, 0x01, 0x4c, 0xcf, 0xe3, 0x8f, 0x1c, 0x61, 0xf3, 0xf4, 0x1e, 0xd8, + 0x1d, 0x3f, 0x7d, 0x1e, 0x5a, 0x85, 0xc3, 0x1e, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd6, 0x04, + 0x00, 0xd0, 0x76, 0xf2, 0x7f, 0x99, 0x06, 0x42, 0xba, 0x96, 0xa4, 0x66, 0xa1, 0x65, 0x02, 0x8e, + 0x0b, 0x06, 0xb9, 0x14, 0x5b, 0xf5, 0x89, 0x5b, 0x66, 0xf4, 0x69, 0x54, 0x4e, 0x58, 0x4d, 0xd9, + 0xd3, 0xab, 0xd2, 0x53, 0x92, 0xc5, 0x77, 0x20, 0x12, 0x1c, 0xe8, 0xa6, 0x3e, 0xb7, 0x9f, 0x88, + 0xff, 0x50, 0x5b, 0xeb, 0x68, 0xb2, 0xe8, 0x7a, 0xbb, 0x9c, 0x05, 0x5f, 0x10, 0x4c, 0xc4, 0x8f, + 0x55, 0xd9, 0x6c, 0xf6, 0xb3, 0xbc, 0x53, 0x99, 0xa9, 0xfb, 0x82, 0x3f, 0xee, 0xcf, 0x37, 0x72, + 0xfa, 0x8b, 0xe5, 0x63, 0x9b, 0x43, 0xde, 0x64, 0x3d, 0x37, 0xbe, 0x00, 0xdd, 0x9a, 0x4d, 0x4e, + 0xa7, 0x8e, 0x0c, 0xf8, 0x7c, 0x2c, 0x3a, 0x69, 0x38, 0x94, 0x89, 0x6b, 0x31, 0xdc, 0xa7, 0x30, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xc6, 0x0c, 0x04, 0x92, 0xbc, 0x03, 0x7e, 0xd0, 0xea, 0xb9, + 0x7b, 0xd3, 0x5f, 0xcb, 0xdf, 0x36, 0x51, 0x32, 0x20, 0x0f, 0x25, 0x93, 0xce, 0x92, 0xdc, 0x67, + 0x85, 0xf8, 0xa7, 0x11, 0x0b, 0x52, 0x1c, 0x67, 0x7f, 0x11, 0xf7, 0xbd, 0x73, 0x99, 0x32, 0xb3, + 0x85, 0x2b, 0x47, 0x6d, 0x06, 0x3c, 0xa6, 0x12, 0x4b, 0xa7, 0x65, 0x2f, 0x5a, 0xb9, 0xb9, 0xb8, + 0xf9, 0x0e, 0x07, 0x38, 0xf8, 0x16, 0x00, 0x16, 0x29, 0xee, 0xc0, 0xf6, 0x7a, 0x70, 0x17, 0x7a, + 0x0b, 0x6b, 0xb6, 0xba, 0x81, 0x15, 0x7d, 0xe9, 0x72, 0x05, 0x3d, 0xb0, 0x2c, 0xe9, 0xe0, 0x6d, + 0x72, 0x06, 0xfc, 0x3e, 0x1a, 0x23, 0x83, 0xe0, 0xc1, 0xf3, 0xe0, 0xf1, 0xe0, 0xff, 0xce, 0xfe, + 0x3c, 0x4c, 0x5f, 0x5c, 0x0c, 0xd4, 0x72, 0xf2, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xc6, 0x0c, + 0x00, 0x07, 0x36, 0x63, 0xdb, 0xdc, 0xae, 0x38, 0x21, 0x1b, 0xe5, 0xf8, 0x09, 0x1f, 0xd9, 0x49, + 0xb5, 0x70, 0xc3, 0x04, 0x20, 0xc7, 0x91, 0x5f, 0x41, 0x67, 0x58, 0x9e, 0xcc, 0x6f, 0x19, 0x17, + 0xba, 0xbb, 0x8f, 0x6b, 0x96, 0xea, 0xae, 0x01, 0x48, 0xac, 0xd3, 0x00, 0xa6, 0x22, 0xed, 0xbf, + 0x9c, 0x95, 0x21, 0x51, 0xe7, 0xf7, 0xda, 0x00, 0x14, 0xc1, 0x6e, 0xc5, 0x6d, 0xb5, 0x37, 0x0f, + 0xa0, 0xa2, 0xae, 0x80, 0x0b, 0x8d, 0x03, 0x1e, 0x8b, 0x0f, 0x81, 0x19, 0x1b, 0xaf, 0x80, 0x06, + 0xdc, 0xb0, 0x9d, 0x32, 0xaf, 0x09, 0x59, 0xbc, 0xfe, 0xc0, 0x0f, 0xe9, 0x14, 0x22, 0x16, 0xbc, + 0x78, 0xf1, 0xc7, 0x82, 0xa0, 0xd3, 0x3a, 0x79, 0x63, 0x61, 0xd0, 0xb8, 0x24, 0xc4, 0x7b, 0xc5, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd6, 0x0c, 0x02, 0x0e, 0x25, 0x72, 0x42, 0xbd, 0xb4, 0xc0, + 0xf2, 0x6f, 0x60, 0x06, 0x8a, 0x98, 0xa8, 0xef, 0xe8, 0x44, 0x26, 0x84, 0xe7, 0x86, 0xfb, 0x51, + 0x3c, 0x8c, 0x19, 0x84, 0x2a, 0x50, 0x74, 0x24, 0xf3, 0xd0, 0x37, 0xa4, 0x5c, 0x0d, 0x54, 0xf1, + 0xaf, 0x99, 0xb6, 0x5d, 0xf4, 0x72, 0x41, 0x06, 0x61, 0xec, 0xd2, 0x2d, 0xe5, 0xe6, 0xa1, 0x56, + 0xb3, 0x00, 0x09, 0xef, 0x3b, 0x48, 0xda, 0xee, 0xce, 0x68, 0x4c, 0x27, 0x5d, 0x7e, 0x0a, 0x03, + 0xfa, 0x7d, 0xf0, 0x29, 0x30, 0xa8, 0xbc, 0xff, 0x66, 0x26, 0xc7, 0x9a, 0xf1, 0xe3, 0x8e, 0xc2, + 0xae, 0xa9, 0x3f, 0x26, 0xd8, 0x9f, 0xdd, 0x8e, 0x61, 0xe1, 0xc7, 0x87, 0x07, 0x4e, 0x38, 0x03, + 0xc3, 0xc1, 0xfe, 0x0a, 0x30, 0x95, 0x41, 0x31, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xc6, 0x0c, + 0x00, 0x09, 0x4a, 0xba, 0x20, 0x0e, 0xdd, 0xb5, 0x71, 0x59, 0x9b, 0x48, 0xf7, 0xbd, 0x32, 0x2e, + 0x70, 0xf2, 0xb3, 0x61, 0x13, 0xd1, 0x27, 0xa7, 0xc3, 0xa3, 0xce, 0x3a, 0xbf, 0x7e, 0xc9, 0x87, + 0x8d, 0x2d, 0xa7, 0xa4, 0x10, 0x1d, 0x84, 0x94, 0xcd, 0x82, 0x0b, 0xa6, 0x3e, 0x87, 0x40, 0x2a, + 0x96, 0x04, 0x81, 0x4f, 0x3a, 0x8a, 0xe7, 0x15, 0x54, 0xaf, 0xb8, 0xb8, 0x55, 0x9b, 0x5c, 0x03, + 0x6d, 0xc1, 0x8e, 0x8c, 0xfd, 0x91, 0xb2, 0x44, 0xae, 0xc8, 0x8e, 0x54, 0xb2, 0x24, 0xf8, 0xe7, + 0x63, 0x79, 0x1d, 0x8a, 0x26, 0x04, 0xcc, 0x36, 0x28, 0xf5, 0x18, 0x11, 0x50, 0xa3, 0xf1, 0xfc, + 0xc6, 0x38, 0x63, 0xf0, 0x38, 0x68, 0x9e, 0xf7, 0x8e, 0x16, 0x77, 0xf0, 0x77, 0xf6, 0x59, 0x59, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd6, 0x0c, 0x02, 0x00, 0x42, 0x97, 0xbb, 0x39, 0xe8, 0x03, + 0xce, 0xd5, 0x36, 0x74, 0xc7, 0x31, 0x63, 0x1b, 0x4f, 0x59, 0xd8, 0x86, 0x4a, 0xe7, 0x5b, 0x0e, + 0xb9, 0x07, 0x66, 0xc9, 0xee, 0x38, 0x38, 0x0c, 0x07, 0xf7, 0x3b, 0xa5, 0x2b, 0x3c, 0x23, 0x3f, + 0x0c, 0x7b, 0x3a, 0x77, 0x87, 0xb3, 0x31, 0x7b, 0xcb, 0x2a, 0xf2, 0x27, 0x40, 0x3c, 0x49, 0x00, + 0x7b, 0x02, 0x97, 0xea, 0x0b, 0x68, 0x92, 0x64, 0x40, 0x87, 0x84, 0x16, 0x5d, 0xaa, 0xd6, 0x04, + 0xe2, 0xf8, 0x1b, 0x6c, 0xd0, 0x5b, 0xc0, 0x47, 0x96, 0xa3, 0x43, 0xa0, 0x76, 0x34, 0x63, 0xac, + 0x35, 0xff, 0x87, 0xf5, 0x7e, 0x5f, 0x6f, 0x81, 0x83, 0xcf, 0x83, 0x83, 0xc1, 0xae, 0xee, 0x31, + 0x3a, 0xd9, 0x39, 0xc1, 0xec, 0x58, 0xcd, 0xaa, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xb6, 0x1c, + 0x04, 0x84, 0x23, 0xaf, 0x99, 0xd5, 0x0c, 0x08, 0x4e, 0xf2, 0x00, 0xf3, 0x8d, 0x76, 0x65, 0xd4, + 0x95, 0x1a, 0x35, 0xb3, 0x28, 0xa2, 0x5d, 0xa3, 0xe6, 0x91, 0x75, 0xa9, 0x55, 0x61, 0xbd, 0x18, + 0xd9, 0xc3, 0xff, 0x69, 0xb2, 0x01, 0xba, 0xfa, 0x42, 0xa0, 0x53, 0xa2, 0xb1, 0x54, 0x2d, 0xd1, + 0x09, 0xf1, 0xbb, 0xc2, 0xe6, 0xa1, 0x5e, 0x01, 0xe9, 0x59, 0x8b, 0x23, 0x84, 0x74, 0x70, 0x47, + 0x6a, 0x6c, 0x2d, 0xee, 0x29, 0x86, 0x24, 0xdd, 0x90, 0x93, 0x8b, 0xfa, 0x89, 0x54, 0xbb, 0xbf, + 0x5e, 0xc9, 0xcf, 0xfd, 0x99, 0x85, 0xf1, 0xad, 0x54, 0xe8, 0x16, 0x48, 0x02, 0x10, 0x40, 0x07, + 0xfc, 0x3c, 0x30, 0x78, 0x7f, 0x03, 0xe6, 0xe2, 0x25, 0x38, 0xc1, 0x6d, 0xc7, 0x2e, 0x33, 0xa0, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xe6, 0x1c, 0x00, 0xcd, 0xe3, 0x69, 0xf7, 0x40, 0x1e, 0x74, + 0x25, 0x44, 0x00, 0x92, 0x99, 0xed, 0x26, 0x50, 0x0b, 0x9f, 0x30, 0x0d, 0x8f, 0x1b, 0xe6, 0xa7, + 0x41, 0x36, 0xd5, 0x43, 0x3a, 0x1d, 0x24, 0x88, 0xc3, 0x28, 0x8f, 0x79, 0x70, 0x2f, 0xe3, 0x70, + 0x9b, 0x91, 0x93, 0xd8, 0xcc, 0x13, 0x9a, 0x15, 0xa1, 0xea, 0xb0, 0x07, 0xbc, 0x69, 0x82, 0x01, + 0xd4, 0xff, 0xc9, 0xbc, 0x58, 0x50, 0xc1, 0x69, 0xa8, 0x88, 0xd9, 0x8f, 0x05, 0x5d, 0xb5, 0xf8, + 0xbd, 0x17, 0x23, 0x9e, 0xae, 0x9f, 0x4c, 0xcd, 0x03, 0x29, 0xcc, 0x77, 0x3e, 0x15, 0x09, 0x15, + 0xc1, 0x5b, 0x8a, 0x59, 0xfe, 0x22, 0x66, 0x54, 0xff, 0x78, 0x3e, 0x3c, 0x3f, 0x07, 0x98, 0x7a, + 0x1f, 0x1f, 0x37, 0x20, 0xca, 0x39, 0xb9, 0x39, 0x95, 0x7a, 0xef, 0x6f, 0x72, 0x08, 0xd6, 0x14, + 0x04, 0x80, 0x10, 0x7b, 0xd8, 0x54, 0xad, 0xc6, 0x86, 0x84, 0x25, 0x8a, 0x23, 0x50, 0x2e, 0x21, + 0x07, 0x97, 0x1a, 0xab, 0xff, 0x1b, 0x4a, 0xab, 0x59, 0xea, 0x72, 0x68, 0x69, 0x76, 0xf3, 0x72, + 0x33, 0x74, 0x9c, 0xd9, 0xe1, 0x98, 0x96, 0x73, 0x92, 0xc6, 0x1f, 0xa1, 0xc7, 0x77, 0x6d, 0xf1, + 0x59, 0xdf, 0x86, 0xbd, 0x2e, 0xcf, 0x61, 0x42, 0x19, 0x0c, 0x08, 0xd5, 0x79, 0xdb, 0x9d, 0xe4, + 0xb5, 0x7a, 0x8e, 0xa7, 0xf2, 0xd8, 0xdd, 0x3b, 0xb0, 0xf3, 0x9f, 0x8c, 0xe8, 0xaa, 0x10, 0x01, + 0x41, 0xd8, 0xf9, 0x89, 0x06, 0xdb, 0xa6, 0x9c, 0x90, 0x2d, 0xa9, 0x50, 0x6b, 0x00, 0xce, 0x24, + 0x3c, 0x0f, 0xe3, 0xf8, 0x9e, 0x0f, 0xc0, 0xf8, 0x46, 0x66, 0xcb, 0xd7, 0x2a, 0xc0, 0x15, 0xd2, + 0x95, 0x7a, 0xef, 0x6f, 0x72, 0x08, 0xd6, 0x14, 0x00, 0xc0, 0x18, 0x52, 0x09, 0x56, 0x62, 0x26, + 0x69, 0x3e, 0x1e, 0xbf, 0x78, 0x75, 0xe9, 0x11, 0x95, 0x8d, 0x93, 0xa2, 0xc4, 0xf5, 0x83, 0x96, + 0xf7, 0x2c, 0x50, 0x79, 0x1c, 0x60, 0xb2, 0x28, 0x3a, 0x71, 0x84, 0x2c, 0xe8, 0xa6, 0x4c, 0xfd, + 0xdd, 0x61, 0x94, 0xaa, 0x41, 0xb8, 0xea, 0x9a, 0x9d, 0x51, 0xe4, 0x0a, 0x7d, 0x14, 0x4c, 0x06, + 0x05, 0x3a, 0xc6, 0x89, 0xad, 0x6e, 0xc1, 0x00, 0x88, 0x30, 0xa5, 0x60, 0x6a, 0x83, 0x5f, 0xc5, + 0xc6, 0x5a, 0xa8, 0xbd, 0x53, 0xcf, 0xe2, 0x15, 0x13, 0x28, 0x72, 0xc6, 0x94, 0x38, 0xe0, 0x02, + 0xb5, 0x98, 0x49, 0xbe, 0x65, 0xf8, 0xbc, 0x74, 0x4c, 0xe0, 0xf0, 0x78, 0x0f, 0xf0, 0xf0, 0x7f, + 0x94, 0xc0, 0x7c, 0xfa, 0xa5, 0x9f, 0x2b, 0x06, 0x95, 0x7a, 0xef, 0x6f, 0x72, 0x08, 0xd6, 0x24, + 0x07, 0x80, 0x4e, 0xc1, 0x89, 0x46, 0x26, 0xc4, 0x5e, 0xaa, 0x70, 0x30, 0xa7, 0xfb, 0x1f, 0x76, + 0xe7, 0xba, 0x40, 0xdf, 0xc2, 0x8b, 0x3a, 0x34, 0xbd, 0xae, 0xb2, 0x0c, 0x47, 0x4d, 0x75, 0xfa, + 0xca, 0x74, 0xf3, 0x9a, 0x93, 0x77, 0xe5, 0x6c, 0x8f, 0x18, 0x15, 0x8e, 0x78, 0xa5, 0xf6, 0xce, + 0x35, 0xd3, 0xc3, 0x92, 0x90, 0xe1, 0x57, 0xb8, 0x00, 0x4f, 0x2b, 0xf1, 0xcd, 0x8c, 0x6f, 0x32, + 0x9f, 0x1c, 0xc8, 0x4d, 0xd9, 0x6e, 0x64, 0xe5, 0xc1, 0xc6, 0x34, 0xad, 0x22, 0x74, 0x01, 0x2f, + 0x38, 0xc7, 0x1c, 0xac, 0x61, 0x21, 0x7a, 0xce, 0x4e, 0x8c, 0x8d, 0x8e, 0x1e, 0xe7, 0x9d, 0x92, + 0xf9, 0xe1, 0xf0, 0xf1, 0x1e, 0x0d, 0x6b, 0xd5, 0x3a, 0x37, 0x88, 0x71, 0xea, 0x38, 0x2e, 0x5e, + 0x95, 0x7a, 0xef, 0x6f, 0x72, 0x08, 0xb6, 0x1c, 0x0c, 0x08, 0x67, 0x4c, 0x0e, 0xad, 0xf1, 0x49, + 0x37, 0xa9, 0x04, 0xaa, 0xff, 0x81, 0xfb, 0xcd, 0xd6, 0xc4, 0x36, 0xcb, 0x0d, 0x4e, 0x54, 0x00, + 0x94, 0xa0, 0x08, 0x2d, 0x8a, 0x3b, 0xbc, 0x48, 0x14, 0x1c, 0x9a, 0x2a, 0x28, 0xa4, 0xb8, 0x44, + 0xfa, 0xa1, 0x5c, 0xc6, 0x38, 0x3b, 0x38, 0x56, 0xa6, 0xbd, 0xa4, 0x23, 0x0d, 0x51, 0x13, 0xd8, + 0x82, 0xb7, 0xd6, 0xb2, 0x0c, 0xb1, 0xbb, 0xee, 0x3c, 0xe9, 0xae, 0x8f, 0xa1, 0x58, 0xd3, 0xa4, + 0xf0, 0xb0, 0xd2, 0x1a, 0x47, 0xdc, 0x23, 0xa9, 0xeb, 0xd6, 0xed, 0x4b, 0xf8, 0x54, 0xd2, 0x6a, + 0x9a, 0xbd, 0xa9, 0xf3, 0x78, 0xd4, 0xec, 0x6c, 0x71, 0xe3, 0xf0, 0xfc, 0x0f, 0x07, 0x0f, 0x1a, + 0x41, 0xd3, 0x83, 0xed, 0x4d, 0x9b, 0x39, 0xb9, 0x86, 0xac, 0xc9, 0x85, 0x72, 0x08, 0xc6, 0x34, + 0x00, 0xc0, 0x50, 0x63, 0x0a, 0xf2, 0xb2, 0x04, 0xfb, 0xa2, 0xad, 0x2c, 0x66, 0x3c, 0x75, 0x78, + 0x71, 0x49, 0x83, 0x23, 0x56, 0x1d, 0x76, 0xf9, 0xfb, 0xdf, 0x6c, 0xf3, 0x8e, 0x7d, 0x79, 0x75, + 0x49, 0xa0, 0xea, 0xbc, 0xd4, 0x64, 0x06, 0x01, 0x4b, 0xae, 0x65, 0x0a, 0xe6, 0xa1, 0x4a, 0xea, + 0x4d, 0x7c, 0xa9, 0x87, 0xb2, 0x00, 0xed, 0xb8, 0xb8, 0x1d, 0x91, 0x66, 0x60, 0xbe, 0x75, 0x8c, + 0x8a, 0xec, 0x52, 0x3b, 0xcd, 0x11, 0x00, 0x86, 0x6b, 0x85, 0xc9, 0xbb, 0xbd, 0x7f, 0x8e, 0x6b, + 0x0d, 0x3c, 0x88, 0xc9, 0x5e, 0x5d, 0x7e, 0x50, 0x49, 0xdb, 0x5e, 0x21, 0x6f, 0x27, 0x47, 0xc7, + 0x88, 0x27, 0x1c, 0x3e, 0x18, 0x3d, 0x43, 0xe1, 0xf1, 0xc1, 0x64, 0xa7, 0x3b, 0x8c, 0x63, 0xd6, + 0x66, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x2c, 0x00, 0x00, 0xd6, 0xba, 0x0a, 0xde, 0x0d, 0x61, + 0x67, 0xd8, 0xe3, 0x78, 0x6a, 0xff, 0x7d, 0x19, 0x94, 0xee, 0x63, 0x36, 0x3a, 0xe5, 0xad, 0xbe, + 0xd7, 0xa9, 0xa6, 0x9e, 0x01, 0x5a, 0x9e, 0x43, 0x1c, 0xa9, 0x0b, 0x96, 0xf7, 0xb7, 0x0d, 0x9e, + 0xfd, 0xfd, 0x1d, 0x8c, 0xe9, 0xdf, 0xe5, 0x75, 0x92, 0x38, 0x51, 0x8b, 0x11, 0x3a, 0x98, 0x91, + 0x48, 0x8d, 0xce, 0xdf, 0xf7, 0xf3, 0x36, 0x84, 0x06, 0x51, 0x0c, 0xa4, 0x04, 0xbb, 0x0e, 0xaa, + 0x3a, 0x32, 0xe6, 0x76, 0x90, 0x6e, 0xcc, 0x32, 0x22, 0xc0, 0x50, 0x53, 0x5a, 0xe4, 0xef, 0x68, + 0xe5, 0x5e, 0x42, 0x3a, 0x92, 0x48, 0xa2, 0x42, 0x92, 0x7f, 0x61, 0xf0, 0xf1, 0xf0, 0x1e, 0x0e, + 0x1e, 0x0c, 0x78, 0xe8, 0x7a, 0x19, 0x83, 0xa0, 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xe6, 0x3c, + 0x00, 0x00, 0x0a, 0xff, 0x7b, 0xe7, 0x5b, 0x83, 0xba, 0x0c, 0x69, 0xdf, 0x15, 0x0f, 0x07, 0xbf, + 0xb0, 0x1d, 0xbc, 0xf4, 0x00, 0xec, 0x08, 0x89, 0x68, 0x80, 0x04, 0xdf, 0x2f, 0x2a, 0xb8, 0xbd, + 0x5b, 0x65, 0x6c, 0x7b, 0x32, 0xf3, 0x9d, 0x55, 0x70, 0xc5, 0xfb, 0xf8, 0xe3, 0x87, 0x28, 0xe7, + 0x71, 0xe7, 0x54, 0xd0, 0x2f, 0xec, 0xb5, 0x75, 0x2b, 0x46, 0xf4, 0x56, 0xac, 0xf6, 0xb6, 0xa0, + 0x28, 0xac, 0x21, 0x0f, 0x7e, 0x13, 0xe1, 0xe8, 0x80, 0x6c, 0x48, 0xd2, 0xb1, 0xcc, 0x2e, 0x65, + 0x01, 0xa8, 0x98, 0x0c, 0x68, 0x7f, 0xb2, 0x05, 0x2e, 0x9e, 0xb1, 0xff, 0x26, 0x55, 0xf0, 0x66, + 0xe7, 0xa1, 0x82, 0x16, 0x60, 0x1c, 0x7c, 0xf8, 0x70, 0x75, 0xa3, 0x84, 0xcd, 0x2b, 0x0a, 0x9d, + 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xf6, 0x3c, 0x00, 0x02, 0x0e, 0x27, 0x82, 0x99, 0xe0, 0xe8, + 0x31, 0xb9, 0xde, 0x8e, 0x62, 0xa3, 0x93, 0x5b, 0x5a, 0x38, 0x66, 0x19, 0x54, 0xb2, 0x40, 0x91, + 0xbc, 0xbb, 0x17, 0x7f, 0x83, 0x0a, 0x3d, 0xe4, 0xc2, 0xbd, 0x75, 0xd3, 0x37, 0x22, 0x13, 0x41, + 0x28, 0xe4, 0x4c, 0x72, 0x8f, 0x26, 0x2e, 0xd9, 0x8f, 0x06, 0xc9, 0x7f, 0xbb, 0x7c, 0x31, 0xb2, + 0xb0, 0x7c, 0xd8, 0xa4, 0xa0, 0x33, 0x0d, 0x11, 0xfe, 0xb7, 0x75, 0xf2, 0x5a, 0x36, 0x1d, 0x1d, + 0x51, 0x78, 0xb5, 0x63, 0x7d, 0xd8, 0x11, 0xf5, 0x11, 0x15, 0x86, 0xde, 0xd6, 0xc7, 0x3d, 0xd2, + 0x3d, 0xd8, 0x50, 0x25, 0x2e, 0x10, 0x8b, 0xf0, 0xc7, 0xfa, 0x66, 0xa7, 0x1f, 0xce, 0x10, 0x53, + 0xb6, 0x41, 0xe6, 0xac, 0xd2, 0xe6, 0x7c, 0x52, 0xa6, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x34, + 0x00, 0x02, 0x11, 0xd1, 0xf6, 0x74, 0xac, 0x18, 0x97, 0x32, 0x76, 0x76, 0x5a, 0x4b, 0x29, 0x5e, + 0xb0, 0xd3, 0x25, 0xb8, 0x55, 0x79, 0x84, 0x50, 0xce, 0x82, 0x68, 0xd1, 0x82, 0xd2, 0x01, 0x50, + 0x2d, 0xb7, 0x83, 0xfd, 0x1d, 0x6b, 0x00, 0x7f, 0x39, 0xc3, 0x51, 0x18, 0x64, 0x87, 0x42, 0xf2, + 0xa3, 0x6d, 0x4c, 0x76, 0x43, 0xe4, 0x04, 0x59, 0xc7, 0x6b, 0xad, 0x01, 0x9d, 0x8c, 0xdc, 0x4e, + 0x88, 0x3e, 0x0b, 0x06, 0xe2, 0xbd, 0xb6, 0x04, 0x77, 0x0b, 0x7a, 0x57, 0x9f, 0x00, 0x64, 0x18, + 0xbe, 0x03, 0x4d, 0x87, 0x13, 0x3f, 0x07, 0x0c, 0x48, 0xf5, 0x42, 0x31, 0x78, 0x67, 0xae, 0xf6, + 0xf8, 0x1e, 0x70, 0xe8, 0x78, 0x1e, 0x1e, 0x07, 0xc0, 0x47, 0xc5, 0x1a, 0xe8, 0xf4, 0x15, 0x45, + 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xf6, 0x3c, 0x00, 0x00, 0x11, 0xb5, 0xe6, 0xc1, 0x00, 0x51, + 0x31, 0x12, 0xd9, 0x99, 0xfb, 0x0a, 0x15, 0x55, 0x1a, 0x94, 0xb5, 0x00, 0x76, 0xe2, 0x1a, 0xcf, + 0xe5, 0x93, 0xfc, 0xe1, 0x09, 0xcf, 0x27, 0xca, 0xd2, 0x88, 0xf5, 0x05, 0xa0, 0xb5, 0x9a, 0x72, + 0xf3, 0xcc, 0x46, 0xdd, 0x6e, 0xd2, 0xd6, 0x21, 0x3a, 0xb0, 0xa4, 0x22, 0x0c, 0xfc, 0xee, 0xc0, + 0x06, 0xba, 0x1c, 0xe5, 0x9f, 0x15, 0xac, 0x63, 0xa5, 0x14, 0xa5, 0x62, 0x4a, 0xbf, 0x0b, 0x74, + 0xde, 0x60, 0x22, 0x2b, 0xb7, 0x1b, 0x70, 0x45, 0xb8, 0xa8, 0x9d, 0xb0, 0x76, 0xf4, 0x51, 0x2c, + 0xc5, 0x2e, 0xeb, 0x1b, 0x76, 0x44, 0x3b, 0x63, 0x2f, 0x69, 0xa5, 0x20, 0x3b, 0x87, 0x8e, 0x78, + 0x7c, 0x3c, 0x1e, 0x86, 0xb8, 0xe6, 0x98, 0x5d, 0x66, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xf6, 0x3c, + 0x0a, 0xff, 0xf1, 0x47, 0xd8, 0x22, 0x24, 0x56, 0xcc, 0x72, 0xf5, 0x72, 0x9c, 0xd8, 0x45, 0xb2, + 0x33, 0x94, 0xc7, 0xba, 0x3c, 0xb2, 0x1d, 0x7b, 0xf6, 0x6c, 0xc3, 0x5b, 0xe3, 0xeb, 0x71, 0xc8, + 0x62, 0xa5, 0xe9, 0x65, 0xd9, 0x67, 0x96, 0x6b, 0xd3, 0x77, 0xbf, 0xb0, 0x69, 0xce, 0xf3, 0xb2, + 0x95, 0xfc, 0x9d, 0xf5, 0xc1, 0x94, 0x33, 0xd7, 0x83, 0x10, 0x17, 0xbb, 0xb8, 0x58, 0x78, 0x0e, + 0x9f, 0xd0, 0xa8, 0xaf, 0x06, 0xfb, 0xb7, 0x4f, 0xad, 0x46, 0x84, 0x45, 0x11, 0xf0, 0x07, 0xe7, + 0xee, 0x1e, 0x3a, 0x7b, 0xe5, 0x53, 0xcf, 0x81, 0xd2, 0x55, 0x55, 0xfb, 0xf2, 0x72, 0x47, 0x04, + 0xc6, 0xfb, 0x38, 0xf1, 0xe0, 0x39, 0x3c, 0x0f, 0x8f, 0xc5, 0x18, 0x69, 0x17, 0x18, 0x51, 0x84, + 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xe6, 0x3c, 0x00, 0x00, 0x4e, 0x9e, 0xb3, 0x62, 0xa1, 0x80, + 0x3c, 0xee, 0x6e, 0xcf, 0x55, 0xf6, 0xa5, 0xc3, 0x08, 0x2e, 0x79, 0xd4, 0xc2, 0x36, 0x30, 0x02, + 0xe4, 0xd9, 0x0e, 0x73, 0xd6, 0x03, 0x44, 0x6b, 0x47, 0x7c, 0x0c, 0xac, 0x1a, 0xa0, 0xe6, 0xf8, + 0xf7, 0x2e, 0xc9, 0x30, 0xa4, 0xe2, 0x16, 0x07, 0x6f, 0x02, 0x83, 0x3f, 0xba, 0x00, 0x96, 0xe4, + 0x5a, 0xca, 0x2e, 0xde, 0x08, 0xee, 0x91, 0xcd, 0x96, 0x84, 0x6f, 0xd0, 0xb9, 0xf7, 0x7b, 0x9d, + 0xa6, 0x07, 0x18, 0x93, 0x43, 0x80, 0x02, 0x30, 0xd9, 0x23, 0x47, 0xc8, 0x18, 0x3d, 0xb6, 0x1c, + 0x69, 0x9b, 0x04, 0x58, 0xe0, 0x7b, 0xd4, 0x33, 0xc6, 0x36, 0x3c, 0x11, 0xd0, 0x37, 0x0d, 0x82, + 0xe3, 0xcd, 0x62, 0xb6, 0x42, 0x8c, 0x5d, 0x3c, 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x3c, + 0x00, 0x06, 0xa8, 0xec, 0x30, 0xf8, 0x02, 0xa1, 0x07, 0xfa, 0x5b, 0x5c, 0x8c, 0xc3, 0x42, 0x0c, + 0xe1, 0x29, 0xa5, 0x53, 0x1e, 0x51, 0x10, 0x26, 0x71, 0x87, 0x44, 0xaf, 0xee, 0x39, 0xaf, 0x5f, + 0x3f, 0xdd, 0x78, 0xec, 0xc0, 0x1c, 0xad, 0xf2, 0xb9, 0x85, 0x42, 0x67, 0x5d, 0x89, 0x9a, 0x09, + 0x80, 0x84, 0xb0, 0x18, 0xd6, 0x31, 0x00, 0x32, 0x0b, 0x3d, 0x09, 0x81, 0x4c, 0x0e, 0xcf, 0x17, + 0x6f, 0xaa, 0x1b, 0x05, 0x81, 0x33, 0xa8, 0x98, 0x2f, 0x59, 0xbc, 0xf7, 0x3b, 0x6f, 0x65, 0x0f, + 0x88, 0x3f, 0xeb, 0x50, 0x44, 0xc0, 0x9c, 0xe7, 0xa5, 0xf0, 0x80, 0xa0, 0x8e, 0x27, 0xe1, 0xb7, + 0xd1, 0x1e, 0xf0, 0x6e, 0x83, 0xf0, 0xdf, 0xbe, 0x1d, 0x1c, 0xf2, 0xdc, 0x10, 0x2e, 0xb1, 0x6e, + 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x3c, 0x00, 0xc3, 0x46, 0xcc, 0xea, 0x31, 0xbc, 0xda, + 0x50, 0xd5, 0xd8, 0x31, 0xdb, 0xd6, 0xfa, 0x60, 0x5b, 0xf3, 0x68, 0x9c, 0xd3, 0x1c, 0x21, 0x39, + 0x8d, 0x20, 0x7e, 0x2b, 0x5e, 0xbb, 0x55, 0x62, 0x37, 0x9d, 0xbc, 0x96, 0xd7, 0x08, 0x18, 0x69, + 0x94, 0x6c, 0x3b, 0xed, 0x7a, 0xb9, 0xe4, 0xb4, 0x31, 0x38, 0x6b, 0x80, 0x00, 0x32, 0x83, 0x71, + 0x2e, 0x4c, 0xc4, 0xa8, 0x50, 0xf0, 0xce, 0xe8, 0xc6, 0xcc, 0x22, 0x79, 0x6b, 0x89, 0xed, 0x9a, + 0x3d, 0x81, 0x9e, 0x42, 0x0f, 0x88, 0x28, 0x35, 0xcb, 0x2c, 0x24, 0xf8, 0x09, 0x28, 0x1a, 0x43, + 0x8b, 0x4f, 0xb3, 0x90, 0x55, 0x1f, 0x16, 0x22, 0xf0, 0x09, 0xcc, 0x3d, 0xa7, 0x0e, 0xca, 0x71, + 0xe9, 0x0a, 0x27, 0x0e, 0x72, 0x79, 0x8b, 0x76, 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x3c, + 0x00, 0x07, 0x5f, 0xc8, 0xe3, 0xa6, 0xd0, 0x3b, 0x8e, 0x82, 0x7a, 0xd8, 0x1a, 0x9f, 0x9f, 0x8a, + 0x9c, 0x91, 0x57, 0x5c, 0x78, 0x55, 0x30, 0x77, 0x38, 0xe1, 0x3a, 0x34, 0x48, 0x9b, 0x71, 0xdf, + 0x4f, 0xcf, 0x6b, 0x8a, 0xbe, 0xd6, 0x3e, 0x4c, 0x70, 0xc5, 0x75, 0x1c, 0x66, 0x3a, 0xa7, 0x49, + 0x24, 0x92, 0xb3, 0x00, 0x12, 0xda, 0xab, 0x09, 0x82, 0x4d, 0x33, 0x74, 0x8c, 0xe7, 0x7c, 0x3e, + 0x90, 0xf2, 0x88, 0x96, 0xa9, 0xeb, 0x40, 0x7a, 0x77, 0x28, 0xad, 0x6c, 0xf5, 0xb8, 0x80, 0x34, + 0x5f, 0x81, 0x47, 0xa2, 0x42, 0xc8, 0x70, 0xf4, 0x7f, 0x85, 0xd5, 0x93, 0x45, 0x1f, 0x47, 0x19, + 0xc4, 0xc8, 0x00, 0x71, 0x13, 0xec, 0xb2, 0xe2, 0x60, 0x70, 0xce, 0xb4, 0x41, 0xb5, 0x92, 0xe1, + 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xe6, 0x3c, 0x00, 0x00, 0x84, 0xbd, 0x00, 0xfc, 0x0a, 0xf7, + 0xb4, 0x15, 0x10, 0xe4, 0xe0, 0xad, 0x2d, 0x1f, 0x1c, 0x7c, 0x1f, 0xeb, 0xa9, 0x43, 0x10, 0x58, + 0x41, 0x1e, 0x99, 0x52, 0x0d, 0x41, 0xf3, 0x1d, 0xec, 0x63, 0xc2, 0xcc, 0xe2, 0x8b, 0xc1, 0x09, + 0xc6, 0x3f, 0xd8, 0xbf, 0x3e, 0x08, 0x5e, 0x2e, 0x7a, 0x5a, 0x23, 0xe3, 0xb7, 0x53, 0x1c, 0x9e, + 0x27, 0xe5, 0x3d, 0x04, 0x5a, 0xdc, 0xa3, 0xc5, 0x94, 0x6b, 0xcb, 0x09, 0x1e, 0x71, 0x29, 0x47, + 0xd3, 0xbe, 0x4f, 0x08, 0xbe, 0x07, 0xf5, 0xbf, 0x98, 0xa7, 0xbc, 0xc5, 0x25, 0x51, 0xb7, 0x24, + 0x29, 0x21, 0x45, 0x41, 0x11, 0x0d, 0x40, 0x0f, 0x87, 0x78, 0xf4, 0xfc, 0x9f, 0x03, 0xc0, 0x25, + 0xd6, 0xb3, 0xe6, 0x8e, 0x2b, 0xcd, 0xc5, 0x59, 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x3c, + 0x00, 0x01, 0x96, 0x93, 0x10, 0xac, 0x08, 0xb7, 0x3e, 0xc4, 0x99, 0x57, 0x08, 0x27, 0x1c, 0x8c, + 0x85, 0x3b, 0xb2, 0x7a, 0x65, 0x12, 0x36, 0x02, 0x13, 0x5a, 0x4b, 0x74, 0x08, 0xd4, 0x2f, 0xcb, + 0xe7, 0x6d, 0x1f, 0xe0, 0xa7, 0x35, 0x71, 0x09, 0x4b, 0x1e, 0xe5, 0x46, 0xc4, 0xd1, 0x23, 0x69, + 0xa8, 0x36, 0xa6, 0xaa, 0x17, 0x9d, 0x00, 0x03, 0xc5, 0x6e, 0xc2, 0x22, 0x2c, 0x97, 0xbe, 0x22, + 0xa2, 0x28, 0xb7, 0xfe, 0xd3, 0xdb, 0x97, 0x85, 0x75, 0x8f, 0x11, 0x55, 0xef, 0x2c, 0xa9, 0xd1, + 0xbe, 0x97, 0x3d, 0x3b, 0x27, 0x66, 0xcc, 0xb7, 0x2e, 0x2f, 0xe8, 0x13, 0x87, 0x02, 0x60, 0xfd, + 0x39, 0x3c, 0x9b, 0x9f, 0xd1, 0xd8, 0xde, 0x51, 0x7e, 0xb8, 0xc6, 0x15, 0xc2, 0xf3, 0x49, 0xce, + 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xb6, 0x3c, 0x00, 0xc0, 0xea, 0xe4, 0x95, 0x80, 0x8d, 0x68, + 0xa0, 0x21, 0xd3, 0xb5, 0xc1, 0xda, 0x11, 0x65, 0x6e, 0xb6, 0xe1, 0xbf, 0x2d, 0xb8, 0x05, 0x78, + 0x44, 0x1f, 0xcf, 0x65, 0xce, 0x0f, 0x1e, 0x00, 0x61, 0x6d, 0xa4, 0x8f, 0x06, 0x03, 0xfb, 0x8d, + 0x7d, 0x9a, 0xbc, 0xf1, 0xf4, 0x24, 0x49, 0xfb, 0x12, 0x82, 0x12, 0xae, 0x1f, 0x5f, 0x00, 0xe8, + 0x79, 0x1a, 0xc1, 0x95, 0x79, 0x91, 0xec, 0x22, 0x15, 0xea, 0x8e, 0xb8, 0x41, 0x8e, 0xd2, 0xd4, + 0xac, 0x90, 0x3a, 0xfe, 0xad, 0xc8, 0x1e, 0x7f, 0x54, 0x7f, 0x5c, 0xe6, 0x78, 0xef, 0xdd, 0xe6, + 0x7d, 0x53, 0x46, 0x8b, 0x8b, 0xf4, 0x38, 0xce, 0x13, 0xd3, 0x78, 0xf0, 0x3c, 0x3f, 0x81, 0xb2, + 0x70, 0x98, 0x73, 0x85, 0xab, 0xf3, 0xc0, 0x41, 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xe6, 0x3c, + 0x04, 0x80, 0xaa, 0x12, 0x97, 0xdc, 0xaa, 0x03, 0xa0, 0x77, 0xb1, 0x92, 0x08, 0x81, 0x46, 0x0c, + 0x6a, 0xd0, 0x59, 0x2f, 0x45, 0x77, 0xcc, 0xea, 0x25, 0x2a, 0xe3, 0xc4, 0xef, 0x93, 0x94, 0x07, + 0x04, 0xa9, 0x83, 0xbf, 0x71, 0x40, 0xa0, 0x0e, 0xbf, 0x89, 0x20, 0xe4, 0x0c, 0x33, 0xd5, 0x46, + 0xce, 0xb3, 0x82, 0xe6, 0xf5, 0x70, 0x4e, 0x30, 0x84, 0xb0, 0xd5, 0x7f, 0x41, 0x7c, 0x37, 0x6a, + 0x6e, 0xab, 0xf3, 0x46, 0x8d, 0xa8, 0x50, 0x4e, 0x42, 0xb8, 0xaa, 0xa7, 0x51, 0x60, 0x73, 0x64, + 0x89, 0xd0, 0xac, 0x08, 0x59, 0x36, 0xce, 0x12, 0x3f, 0xb5, 0x5c, 0x1a, 0x63, 0xf5, 0xb6, 0x41, + 0x19, 0x98, 0xf8, 0x71, 0xe1, 0x9c, 0xe8, 0xf0, 0x71, 0x56, 0x0e, 0x24, 0x34, 0xbd, 0xdd, 0x24, + 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xc6, 0x3c, 0x04, 0x80, 0x8a, 0xc7, 0x95, 0x58, 0x0d, 0x38, + 0xb6, 0xc4, 0xc1, 0xd1, 0x23, 0x9a, 0x65, 0x8e, 0x7a, 0xd0, 0xcc, 0xdf, 0x30, 0xd4, 0x93, 0xd5, + 0x99, 0xf4, 0xa3, 0x34, 0xd7, 0xae, 0x5c, 0xb9, 0x4e, 0xf5, 0x3d, 0x85, 0x58, 0xff, 0x24, 0x04, + 0xba, 0xd7, 0x3e, 0xf8, 0xba, 0x43, 0x83, 0x08, 0x4d, 0xaa, 0x8d, 0x8a, 0x95, 0x0b, 0x1c, 0x00, + 0x00, 0x24, 0x0e, 0xfe, 0x14, 0xa3, 0xd9, 0x89, 0x57, 0x8c, 0xa6, 0x0a, 0x5a, 0x93, 0xaa, 0x9f, + 0xc0, 0xf7, 0x0f, 0x2e, 0xfa, 0xb1, 0xff, 0x22, 0x93, 0x32, 0xce, 0x42, 0x13, 0x17, 0x06, 0x0f, + 0xd1, 0xa0, 0xdb, 0xcb, 0x87, 0xe0, 0xe0, 0x84, 0x81, 0xc2, 0xc3, 0xe1, 0xe0, 0xf0, 0x3e, 0x7b, + 0x83, 0x9a, 0xb8, 0xf2, 0x76, 0x2f, 0x0c, 0x52, 0xa6, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xc6, 0x3c, + 0x0d, 0xd9, 0x17, 0x1d, 0x9a, 0xd5, 0x20, 0xac, 0xd6, 0x8e, 0xd8, 0x3a, 0x75, 0x82, 0x41, 0x18, + 0x7d, 0xa2, 0x7d, 0x11, 0xd0, 0x21, 0x95, 0xe5, 0x11, 0x3a, 0x54, 0xb2, 0xda, 0x82, 0x94, 0xe1, + 0x2b, 0xb7, 0x6a, 0xca, 0xed, 0x38, 0x57, 0x99, 0x72, 0x64, 0x07, 0x03, 0x34, 0xb1, 0x34, 0x8b, + 0x0a, 0xe1, 0xce, 0xa2, 0x38, 0x53, 0xfe, 0x0c, 0x37, 0x99, 0x2e, 0x27, 0xa1, 0xc5, 0x3c, 0x04, + 0x28, 0xf1, 0xaa, 0x54, 0x63, 0x4b, 0x82, 0x25, 0x19, 0xab, 0xa0, 0x5d, 0x32, 0x65, 0x56, 0x64, + 0xc7, 0x3b, 0x65, 0x53, 0x33, 0x35, 0x55, 0x52, 0xaa, 0xaa, 0xa6, 0x66, 0xaa, 0xaa, 0xa6, 0x66, + 0x65, 0x55, 0x54, 0xcc, 0xcc, 0xcc, 0xca, 0xaa, 0x99, 0x99, 0x99, 0x99, 0x95, 0x56, 0x66, 0x66, + 0x45, 0xcf, 0xee, 0x5c, 0xf2, 0x0b, 0xa6, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, +}; diff --git a/apps/leaudio_broadcaster/src/main.c b/apps/leaudio_broadcaster/src/main.c new file mode 100644 index 0000000000..5ea818e36d --- /dev/null +++ b/apps/leaudio_broadcaster/src/main.c @@ -0,0 +1,404 @@ +/* + * 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. + */ + +#include "console/console.h" +#include "config/config.h" + +#include "nimble/ble.h" +#include "host/ble_hs.h" +#include "host/util/util.h" + +#include "host/ble_audio_broadcast.h" +#include "host/ble_audio_common.h" +#include "host/ble_iso.h" + +#include "hal/hal_gpio.h" +#include "bsp/bsp.h" + +#include "audio_data.h" + +#define BROADCAST_ADV_INSTANCE 1 +#define BROADCAST_MAX_SDU 120 +#define BROADCAST_SDU_INTVL 10000 +#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_48000_HZ + +#define BROADCASTER_INTERRUPT_TASK_PRIO 4 +#define BROADCASTER_INTERRUPT_TASK_STACK_SZ 512 + +static uint8_t id_addr_type; + +static struct ble_audio_base broadcaster_base; +static struct ble_audio_big_subgroup big_subgroup; + +static os_membuf_t bis_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BROADCASTER_CHAN_NUM), + sizeof(struct ble_audio_bis)) +]; +static struct os_mempool bis_pool; + +static os_membuf_t codec_spec_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIS) * 2, 19) +]; +static struct os_mempool codec_spec_pool; + +static uint16_t bis_handles[MYNEWT_VAL(BROADCASTER_CHAN_NUM)]; +/* The timer callout */ +static struct os_callout audio_broadcast_callout; + +static int audio_data_offset; +static struct os_task broadcaster_interrupt_task_str; +static struct os_eventq broadcaster_interrupt_eventq; +static os_stack_t broadcaster_interrupt_task_stack[BROADCASTER_INTERRUPT_TASK_STACK_SZ]; + +static void +broadcaster_interrupt_task(void *arg) +{ + while (1) { + os_eventq_run(&broadcaster_interrupt_eventq); + } +} + +static void +broadcast_stop_ev_cb(struct os_event *ev) +{ + ble_audio_broadcast_stop(BROADCAST_ADV_INSTANCE); + ble_audio_broadcast_destroy(BROADCAST_ADV_INSTANCE); +} + +static struct os_event broadcast_stop_ev = { + .ev_cb = broadcast_stop_ev_cb, +}; + +static void +broadcaster_gpio_irq(void *arg) +{ + os_eventq_put(&broadcaster_interrupt_eventq, &broadcast_stop_ev); +} + +static void +audio_broadcast_event_cb(struct os_event *ev) +{ + assert(ev != NULL); + uint32_t ev_start_time = os_cputime_ticks_to_usecs(os_cputime_get32()); + + +#if MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 + if (audio_data_offset + BROADCAST_MAX_SDU >= sizeof(audio_data)) { + audio_data_offset = 0; + } + + ble_iso_tx(bis_handles[0], (void *)(audio_data + audio_data_offset), + BROADCAST_MAX_SDU); + ble_iso_tx(bis_handles[1], (void *)(audio_data + audio_data_offset), + BROADCAST_MAX_SDU); +#else + if (audio_data_offset + 2 * BROADCAST_MAX_SDU >= sizeof(audio_data)) { + audio_data_offset = 0; + } + + uint8_t lr_payload[BROADCAST_MAX_SDU * 2]; + memcpy(lr_payload, audio_data + audio_data_offset, BROADCAST_MAX_SDU); + memcpy(lr_payload + BROADCAST_MAX_SDU, audio_data + audio_data_offset, + BROADCAST_MAX_SDU); + ble_iso_tx(bis_handles[0], (void *)(lr_payload), + BROADCAST_MAX_SDU * 2); +#endif + audio_data_offset += BROADCAST_MAX_SDU; + + /** Use cputime to time BROADCAST_SDU_INTVL, as these ticks are more + * accurate than os_time ones. This assures that we do not push + * LC3 data to ISO before interval, which could lead to + * controller running out of buffers. This is only needed because + * we already have coded data in an array - in real world application + * we usually wait for new audio to arrive, and lose time to code it too. + */ + while (os_cputime_ticks_to_usecs(os_cputime_get32()) - ev_start_time < + (BROADCAST_SDU_INTVL)); + + os_callout_reset(&audio_broadcast_callout, 0); +} +static int +broadcast_audio() +{ + os_callout_reset(&audio_broadcast_callout, 0); + + return 0; +} + +static int +iso_event(struct ble_iso_event *event, void *arg) +{ + int i; + + switch (event->type) { + case BLE_ISO_EVENT_BIG_CREATE_COMPLETE: + console_printf("BIG created\n"); + if (event->big_created.desc.num_bis > + MYNEWT_VAL(BROADCASTER_CHAN_NUM)) { + return BLE_HS_EINVAL; + } + for (i = 0; i < MYNEWT_VAL(BROADCASTER_CHAN_NUM); i++) { + bis_handles[i] = event->big_created.desc.conn_handle[i]; + } + broadcast_audio(); + return 0; + case BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE: + console_printf("BIG terminated\n"); + return 0; + default: + return BLE_HS_ENOTSUP; + } +} + +static void +broadcaster_init() +{ + int rc; + + os_callout_init(&audio_broadcast_callout, os_eventq_dflt_get(), + audio_broadcast_event_cb, NULL); + + assert(MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 0); + + rc = os_mempool_init(&bis_pool, MYNEWT_VAL(BROADCASTER_CHAN_NUM), + sizeof(struct ble_audio_bis), bis_mem, + "bis_pool"); + assert(rc == 0); + + rc = os_mempool_init(&codec_spec_pool, + MYNEWT_VAL(BLE_MAX_BIS) * 2, 19, + codec_spec_mem, "codec_spec_pool"); + assert(rc == 0); +} + +static int +base_create() +{ +#if MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 + struct ble_audio_bis *bis_left; + struct ble_audio_bis *bis_right; + uint8_t codec_spec_config_left_chan[] = + BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, + BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS, + BLE_AUDIO_LOCATION_FRONT_LEFT, + BROADCAST_MAX_SDU, ); + uint8_t codec_spec_config_right_chan[] = + BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, + BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS, + BLE_AUDIO_LOCATION_FRONT_RIGHT, + BROADCAST_MAX_SDU, ); +#else + uint16_t chan_loc = BLE_AUDIO_LOCATION_FRONT_LEFT | + BLE_AUDIO_LOCATION_FRONT_RIGHT; + uint8_t codec_spec_config[] = + BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, + BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS, + chan_loc, + BROADCAST_MAX_SDU * 2, ); + + struct ble_audio_bis *bis; +#endif + broadcaster_base.broadcast_id = 0x42; + broadcaster_base.presentation_delay = 20000; + + big_subgroup.bis_cnt = MYNEWT_VAL(BROADCASTER_CHAN_NUM); + + /** LC3 */ + big_subgroup.codec_id.format = 0x06; + + big_subgroup.codec_spec_config_len = 0; +#if MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 + bis_left = os_memblock_get(&bis_pool); + if (!bis_left) { + return BLE_HS_ENOMEM; + } + + bis_left->codec_spec_config = os_memblock_get(&codec_spec_pool); + memcpy(bis_left->codec_spec_config, + codec_spec_config_left_chan, + sizeof(codec_spec_config_left_chan)); + bis_left->codec_spec_config_len = sizeof(codec_spec_config_left_chan); + bis_left->idx = 1; + + bis_right = os_memblock_get(&bis_pool); + if (!bis_right) { + return BLE_HS_ENOMEM; + } + + bis_right->codec_spec_config = os_memblock_get(&codec_spec_pool); + memcpy(bis_right->codec_spec_config, + codec_spec_config_right_chan, + sizeof(codec_spec_config_right_chan)); + bis_right->codec_spec_config_len = sizeof(codec_spec_config_right_chan); + bis_right->idx = 2; + + STAILQ_INSERT_HEAD(&big_subgroup.bises, bis_left, next); + STAILQ_INSERT_TAIL(&big_subgroup.bises, bis_right, next); +#else + bis = os_memblock_get(&bis_pool); + if (!bis) { + return BLE_HS_ENOMEM; + } + + bis->codec_spec_config = os_memblock_get(&codec_spec_pool); + memcpy(bis->codec_spec_config, + codec_spec_config, + sizeof(codec_spec_config)); + bis->codec_spec_config_len = sizeof(codec_spec_config); + STAILQ_INSERT_HEAD(&big_subgroup.bises, bis, next); +#endif + + STAILQ_INSERT_HEAD(&broadcaster_base.subs, &big_subgroup, next); + broadcaster_base.num_subgroups++; + return 0; +} + +static int +broadcast_destroy_fn(struct ble_audio_base *base, void *args) +{ + struct ble_audio_bis *bis; + + STAILQ_FOREACH(bis, &big_subgroup.bises, next) { + os_memblock_put(&codec_spec_pool, bis->codec_spec_config); + os_memblock_put(&bis_pool, bis); + } + + memset(&big_subgroup, 0, sizeof(big_subgroup)); + + return 0; +} + +static int +broadcast_create() +{ + struct ble_gap_periodic_adv_params periodic_params = { + .itvl_min = 30, + .itvl_max = 30, + }; + + struct ble_gap_ext_adv_params extended_params = { + .itvl_min = 50, + .itvl_max = 50, + .scannable = 0, + .connectable = 0, + .primary_phy = BLE_HCI_LE_PHY_1M, + .secondary_phy = BLE_HCI_LE_PHY_2M, + .own_addr_type = id_addr_type, + .sid = BROADCAST_ADV_INSTANCE, + }; + + static struct ble_iso_big_params big_params = { + .sdu_interval = BROADCAST_SDU_INTVL, + .max_sdu = MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 ? + BROADCAST_MAX_SDU : BROADCAST_MAX_SDU * 2, + .max_transport_latency = BROADCAST_SDU_INTVL / 1000, + .rtn = 0, + .phy = BLE_HCI_LE_PHY_2M, + .packing = 0, + .framing = 0, + .encryption = 0, + }; + + struct ble_broadcast_create_params create_params = { + .base = &broadcaster_base, + .extended_params = &extended_params, + .periodic_params = &periodic_params, + .name = MYNEWT_VAL(BROADCASTER_BROADCAST_NAME), + .adv_instance = BROADCAST_ADV_INSTANCE, + .big_params = &big_params, + .svc_data = NULL, + .svc_data_len = 0, + }; + + return ble_audio_broadcast_create(&create_params, + broadcast_destroy_fn, + NULL, + NULL); +} + +static int +broadcast_start() +{ + return ble_audio_broadcast_start(BROADCAST_ADV_INSTANCE, iso_event, NULL); +} + +static void +on_sync(void) +{ + int rc; + + console_printf("Bluetooth initialized\n"); + + /* Make sure we have proper identity address set (public preferred) */ + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* configure global address */ + rc = ble_hs_id_infer_auto(0, &id_addr_type); + assert(rc == 0); + + broadcaster_init(); + + rc = base_create(); + assert(rc == 0); + + rc = broadcast_create(); + assert(rc == 0); + + rc = broadcast_start(); + assert(rc == 0); +} + +/* + * main + * + * The main task for the project. This function initializes the packages, + * then starts serving events from default event queue. + * + * @return int NOTE: this function should never return! + */ +int +mynewt_main(int argc, char **argv) +{ + /* Initialize OS */ + sysinit(); + + console_printf("LE Audio Broadcast sample application\n"); + + /* Set sync callback */ + ble_hs_cfg.sync_cb = on_sync; + + os_eventq_init(&broadcaster_interrupt_eventq); + os_task_init(&broadcaster_interrupt_task_str, "broadcaster_interrupt_task", + broadcaster_interrupt_task, NULL, + BROADCASTER_INTERRUPT_TASK_PRIO, OS_WAIT_FOREVER, + broadcaster_interrupt_task_stack, + BROADCASTER_INTERRUPT_TASK_STACK_SZ); + + hal_gpio_irq_init(BUTTON_3, broadcaster_gpio_irq, NULL, + HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_UP); + hal_gpio_irq_enable(BUTTON_3); + + /* As the last thing, process events from default event queue */ + while (1) { + os_eventq_run(os_eventq_dflt_get()); + } + + return 0; +} diff --git a/apps/leaudio_broadcaster/syscfg.yml b/apps/leaudio_broadcaster/syscfg.yml new file mode 100644 index 0000000000..7fc1873376 --- /dev/null +++ b/apps/leaudio_broadcaster/syscfg.yml @@ -0,0 +1,65 @@ +# 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. + +syscfg.defs: + BROADCASTER_CHAN_NUM: 2 + BROADCASTER_BROADCAST_NAME: '"NimBLE Broadcast"' + +syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + + # Disable not used GAP roles (we only do non-connectable + # advertising here) + BLE_ROLE_BROADCASTER: 1 + BLE_ROLE_CENTRAL: 0 + BLE_ROLE_OBSERVER: 0 + BLE_ROLE_PERIPHERAL: 0 + + # Enable Extended Advertising + BLE_EXT_ADV: 1 + + # Enable Periodic Advertising + BLE_PERIODIC_ADV: 1 + + # Max advertising data size + BLE_EXT_ADV_MAX_SIZE: 261 + + # Number of multi-advertising instances. Note that due + # to historical reasonds total number of advertising + # instances is BLE_MULTI_ADV_INSTANCES + 1 as instance + # 0 is always available + BLE_MULTI_ADV_INSTANCES: 1 + + # Controller uses msys pool for storing advertising data and scan responses. + # Since we advertise a lot of data (~6k in total) at the same time we need + # to increase block count. + MSYS_1_BLOCK_COUNT: 32 + + BLE_VERSION: 54 + BLE_ISO: 1 + BLE_ISO_BROADCASTER: 1 + BLE_MAX_BIG: 1 + BLE_MAX_BIS: 2 + +syscfg.vals.BSP_NRF5340: + MCU_MPU_ENABLE: 1 + MCU_CACHE_ENABLED: 1 + BSP_NRF5340_NET_ENABLE: 1 + NRF5340_EMBED_NET_CORE: 1 + NET_CORE_IMAGE_TARGET_NAME: "@apache-mynewt-nimble/targets/nordic_pca10095_net-blehci_broadcaster" diff --git a/targets/nordic_pca10095_net-blehci_broadcaster/pkg.yml b/targets/nordic_pca10095_net-blehci_broadcaster/pkg.yml new file mode 100644 index 0000000000..b8548dbb37 --- /dev/null +++ b/targets/nordic_pca10095_net-blehci_broadcaster/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: targets/nordic_pca10095_net-blehci_broadcaster +pkg.type: target +pkg.description: Sample target for BLE controller on NRF5340 with enable LE Audio broadcaster +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" diff --git a/targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml b/targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml new file mode 100644 index 0000000000..22fd743e8d --- /dev/null +++ b/targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml @@ -0,0 +1,47 @@ +# +# 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. +# + +syscfg.vals: + BLE_TRANSPORT_HS: nrf5340 + + MSYS_1_BLOCK_COUNT: 12 + MSYS_1_BLOCK_SIZE: 292 + BLE_LL_CFG_FEAT_DATA_LEN_EXT: 1 + BLE_PHY_2M: 1 + BLE_PHY_CODED: 1 + BLE_LL_CFG_FEAT_LL_PRIVACY: 1 + BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL: 1 + BLE_LL_CONN_INIT_MAX_TX_BYTES: 251 + BLE_LL_CONN_INIT_SLOTS: 4 + BLE_LL_DTM: 1 + BLE_LL_DTM_EXTENSIONS: 1 + BLE_LL_VND_EVENT_ON_ASSERT: 1 + BLE_MAX_CONNECTIONS: 5 + BLE_EXT_ADV: 1 + BLE_EXT_ADV_MAX_SIZE: 1650 + BLE_MAX_PERIODIC_SYNCS: 5 + BLE_MULTI_ADV_INSTANCES: 5 + BLE_PERIODIC_ADV: 1 + BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 + + BLE_VERSION: 54 + BLE_ISO: 1 + BLE_ISO_BROADCASTER: 1 + BLE_MAX_BIG: 1 + BLE_MAX_BIS: 2 diff --git a/targets/nordic_pca10095_net-blehci_broadcaster/target.yml b/targets/nordic_pca10095_net-blehci_broadcaster/target.yml new file mode 100644 index 0000000000..4d2641b77c --- /dev/null +++ b/targets/nordic_pca10095_net-blehci_broadcaster/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/blehci" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10095_net" +target.build_profile: debug From d8312d89e4e269cac8ae3671c0692cc7494681f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 17 Nov 2023 10:23:10 +0100 Subject: [PATCH 0872/1333] apps: add Auracast sample This sample uses Auracast package to broadcast audio --- apps/auracast/pkg.yml | 39 + apps/auracast/src/audio_data.h | 4412 ++++++++++++++++++++++++++++++++ apps/auracast/src/main.c | 393 +++ apps/auracast/syscfg.yml | 62 + 4 files changed, 4906 insertions(+) create mode 100644 apps/auracast/pkg.yml create mode 100644 apps/auracast/src/audio_data.h create mode 100644 apps/auracast/src/main.c create mode 100644 apps/auracast/syscfg.yml diff --git a/apps/auracast/pkg.yml b/apps/auracast/pkg.yml new file mode 100644 index 0000000000..54eb3be599 --- /dev/null +++ b/apps/auracast/pkg.yml @@ -0,0 +1,39 @@ +# 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: apps/auracast +pkg.type: app +pkg.description: Auracast sample application. + +pkg.author: "Krzysztof Kopyściński" +pkg.email: "krzysztof.kopyscinski@codecoup.pl" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - nimble/host + - nimble/host/util + - nimble/host/services/gap + - nimble/host/store/config + - "@apache-mynewt-core/kernel/os" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" + - "@apache-mynewt-core/sys/stats" + - "@apache-mynewt-core/sys/sysinit" + - "@apache-mynewt-core/sys/id" + - "@apache-mynewt-nimble/nimble/host/services/auracast" diff --git a/apps/auracast/src/audio_data.h b/apps/auracast/src/audio_data.h new file mode 100644 index 0000000000..0bb90a4a1f --- /dev/null +++ b/apps/auracast/src/audio_data.h @@ -0,0 +1,4412 @@ +/* + * 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. + */ + +/** LC3 coded audio data, with 48kHz sample rate. + * Audio signal coded here is 100Hz-20kHz sweep signal, in sinus form + */ +const uint8_t audio_data[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x33, 0x99, 0xb9, 0x51, 0x64, 0x62, 0x1d, 0x6c, 0x3c, 0xf8, 0xae, 0xb5, 0xbd, 0x64, 0xba, 0x9e, + 0xe2, 0x0c, 0x72, 0x7a, 0x4c, 0xdc, 0xed, 0x84, 0x9d, 0x8a, 0x75, 0x28, 0x61, 0x88, 0xcc, 0x11, + 0xef, 0x66, 0x35, 0x9e, 0xbf, 0x34, 0xdd, 0x56, 0xcb, 0x39, 0x9a, 0xed, 0x53, 0xe7, 0xc6, 0x6e, + 0x73, 0x53, 0x29, 0x4e, 0x02, 0x2f, 0xb2, 0x65, 0x81, 0xe9, 0xb6, 0xee, 0xf5, 0x35, 0x20, 0xfc, + 0xc1, 0x31, 0x7e, 0x63, 0x28, 0x9f, 0x03, 0xe0, 0x7e, 0x07, 0xe0, 0x7e, 0x07, 0xe0, 0x3d, 0xe0, + 0xf9, 0x11, 0xcf, 0x5d, 0xab, 0x9c, 0xc4, 0x78, 0xed, 0x64, 0xbd, 0x3e, 0x4c, 0x6b, 0x06, 0x27, + 0x1a, 0x80, 0xf1, 0xb0, 0xec, 0x96, 0x4a, 0x21, 0x07, 0xb2, 0x13, 0xf0, 0x3f, 0x03, 0xf3, 0x02, + 0x38, 0x26, 0x1e, 0x8b, 0x82, 0x6a, 0x63, 0x34, 0x33, 0x9e, 0x72, 0xd8, 0xa9, 0x96, 0xbe, 0x10, + 0x87, 0xca, 0x68, 0x69, 0x81, 0xa0, 0x5e, 0x6d, 0xeb, 0xbb, 0x09, 0x50, 0x8c, 0x3c, 0xda, 0xbd, + 0x5b, 0x20, 0x77, 0xae, 0xa8, 0x4f, 0x74, 0xde, 0x0a, 0xa7, 0xe4, 0x2f, 0x0a, 0x8c, 0x91, 0x84, + 0xb5, 0x97, 0x9e, 0xdf, 0x04, 0x86, 0xce, 0x02, 0xdc, 0xa2, 0xf2, 0x33, 0x0c, 0xe5, 0x0d, 0x2a, + 0x36, 0x59, 0xd7, 0x03, 0x0c, 0xb7, 0xb3, 0xa1, 0xe3, 0x7f, 0x21, 0x58, 0xd1, 0x5d, 0xb8, 0x3f, + 0x03, 0xf0, 0x3f, 0x01, 0xfc, 0x07, 0xf0, 0x0f, 0xe0, 0x5f, 0x83, 0xb8, 0x07, 0x8b, 0x04, 0xe4, + 0x32, 0x08, 0x21, 0x4a, 0x97, 0x4a, 0x76, 0x4a, 0x06, 0x71, 0xba, 0x1b, 0xb9, 0x6f, 0x05, 0xb4, + 0x67, 0xf1, 0x0b, 0xee, 0x03, 0xf0, 0x1f, 0x18, 0x38, 0x26, 0x1e, 0x8f, 0x82, 0x6a, 0x63, 0x34, + 0x33, 0x99, 0xb9, 0x7c, 0x0f, 0xda, 0x8d, 0xcf, 0x8f, 0x01, 0xff, 0x62, 0x63, 0xf0, 0x32, 0x2f, + 0xd1, 0x7f, 0xc9, 0x4a, 0xe1, 0x4f, 0x8c, 0x0f, 0xf3, 0x9b, 0x09, 0xb7, 0xad, 0xdd, 0xe8, 0xba, + 0xd5, 0x9c, 0xf1, 0x88, 0x8d, 0x7f, 0x56, 0x46, 0x8b, 0x8d, 0x5a, 0x1e, 0xd1, 0xe7, 0xdf, 0x70, + 0xf5, 0x06, 0x80, 0x58, 0xb7, 0xe1, 0x9d, 0x60, 0x1e, 0xcf, 0x07, 0x7c, 0xfb, 0xdf, 0x3a, 0x26, + 0x27, 0x53, 0x54, 0xe3, 0x33, 0x8f, 0x42, 0x0f, 0x0f, 0x87, 0x81, 0xf8, 0x0f, 0xc0, 0xfe, 0x07, + 0xe0, 0x7b, 0xad, 0x59, 0x8a, 0xea, 0x1f, 0xaa, 0x87, 0x79, 0x6b, 0x6e, 0x60, 0x0c, 0x81, 0xf0, + 0x60, 0x2d, 0x62, 0x78, 0xc8, 0x1d, 0x27, 0x28, 0x0f, 0xc0, 0x3d, 0x98, 0x07, 0xe0, 0x1f, 0x10, + 0x38, 0xed, 0x92, 0x2b, 0x82, 0x6a, 0x73, 0x2c, 0xaf, 0xdd, 0x4d, 0x39, 0x00, 0xfc, 0x8e, 0x80, + 0x31, 0x4b, 0xdc, 0x52, 0x82, 0x9c, 0x16, 0x03, 0x87, 0xd5, 0xca, 0x62, 0xe5, 0xd4, 0xb3, 0x0b, + 0xe2, 0xae, 0x6c, 0x4f, 0xfe, 0x46, 0xf7, 0x90, 0xdd, 0x29, 0xf5, 0xb6, 0x42, 0x3f, 0xd1, 0x5a, + 0xa1, 0xdf, 0x46, 0x4c, 0x20, 0x4a, 0x86, 0x72, 0x5f, 0x5b, 0xc6, 0xff, 0x0d, 0x44, 0x35, 0x91, + 0xf7, 0x3d, 0xbe, 0x78, 0x7c, 0xb7, 0x03, 0x0e, 0x7d, 0x91, 0x24, 0xf2, 0xe8, 0x78, 0x1f, 0x03, + 0xf8, 0x0f, 0xe0, 0x7f, 0x03, 0xf0, 0x3e, 0x1f, 0x64, 0x1b, 0x84, 0x67, 0x94, 0x12, 0x20, 0x78, + 0xf3, 0x20, 0x26, 0x56, 0x7f, 0xd7, 0x1c, 0xf3, 0xfd, 0xf0, 0xe8, 0x29, 0xf0, 0x7c, 0xf2, 0x82, + 0x6f, 0x81, 0x07, 0x90, 0x3f, 0x03, 0xe2, 0x88, 0x31, 0x2b, 0xc8, 0x3d, 0xd2, 0x6a, 0x03, 0xcc, + 0x63, 0xc0, 0x39, 0xbf, 0x1b, 0x8d, 0x08, 0xa5, 0xfd, 0xdd, 0x32, 0x8e, 0x3c, 0x8e, 0x4c, 0x58, + 0xd8, 0x33, 0x7f, 0xa7, 0xb8, 0xbf, 0x8a, 0xbb, 0xe2, 0xd8, 0x12, 0xc5, 0x52, 0x1a, 0xe1, 0xb1, + 0x42, 0x07, 0xcc, 0x22, 0x76, 0x3e, 0x90, 0xb3, 0x00, 0xa6, 0x41, 0xb2, 0xa1, 0xd6, 0xfb, 0x57, + 0x00, 0x5b, 0xd3, 0x1e, 0x83, 0x1c, 0xab, 0x1d, 0x13, 0x25, 0x0b, 0xac, 0xff, 0x98, 0xd4, 0x57, + 0x9b, 0x0c, 0xb8, 0x0f, 0x0f, 0x87, 0xe0, 0x7e, 0x07, 0xf0, 0x1f, 0xc0, 0xf8, 0x05, 0xff, 0x9e, + 0x3b, 0x45, 0xc0, 0xfc, 0x69, 0xfc, 0x75, 0x6b, 0x4b, 0x2c, 0xc7, 0xf6, 0xbf, 0x22, 0x2c, 0xea, + 0x17, 0x89, 0xc3, 0x7f, 0x08, 0xee, 0x38, 0x22, 0x67, 0x74, 0x65, 0x0f, 0x7f, 0x00, 0xf7, 0x04, + 0x27, 0x38, 0xa9, 0xbf, 0xd2, 0x6a, 0x23, 0x1c, 0x63, 0xc6, 0xc2, 0x42, 0xcd, 0x56, 0x9d, 0x10, + 0x13, 0xbe, 0xdb, 0x5f, 0x7c, 0x58, 0x95, 0x42, 0xb0, 0xf7, 0x0c, 0xe7, 0xa2, 0x41, 0x72, 0x06, + 0xd0, 0xa2, 0x50, 0xd7, 0x6e, 0x9b, 0xd3, 0x91, 0xf9, 0x36, 0xea, 0x12, 0x6b, 0x10, 0xdc, 0x17, + 0xd5, 0x1d, 0xab, 0x1a, 0xea, 0x55, 0xe8, 0xba, 0xf4, 0x3d, 0x68, 0x0a, 0x46, 0x18, 0xc7, 0xef, + 0xfe, 0x94, 0x1f, 0x80, 0x52, 0x23, 0x36, 0x0e, 0x7a, 0xf4, 0xb7, 0x03, 0xf0, 0x7e, 0x07, 0xe0, + 0x7e, 0x07, 0xe0, 0x3f, 0x03, 0xe0, 0xeb, 0xed, 0xd1, 0x6a, 0xb9, 0xd0, 0xaa, 0x93, 0x61, 0xe7, + 0x00, 0xea, 0x7a, 0x34, 0x0e, 0x80, 0x04, 0x20, 0x86, 0x8f, 0xd7, 0x96, 0x22, 0xff, 0x64, 0x45, + 0xed, 0xc0, 0x44, 0xf7, 0x30, 0x44, 0xf2, 0x92, 0x27, 0x50, 0x01, 0x3f, 0xd2, 0x6a, 0x23, 0x5c, + 0xa7, 0x93, 0x9c, 0x4e, 0x56, 0x0f, 0xc9, 0x0e, 0x09, 0x8f, 0x16, 0x16, 0x67, 0x00, 0xc3, 0x9c, + 0x78, 0x02, 0xca, 0xb1, 0x24, 0x26, 0x40, 0x37, 0xce, 0xd5, 0x00, 0xee, 0x86, 0x26, 0x76, 0x6b, + 0xb0, 0xb3, 0x97, 0x5f, 0x92, 0x10, 0x13, 0x95, 0xcf, 0xf6, 0x49, 0x33, 0x7b, 0x85, 0xf6, 0x01, + 0x26, 0x4e, 0x12, 0xe2, 0xc6, 0xa5, 0x19, 0x1d, 0x63, 0x97, 0xd1, 0x60, 0xfa, 0x44, 0xf8, 0x75, + 0x8f, 0x50, 0xb2, 0x2a, 0x9f, 0x07, 0xe0, 0xfc, 0x0f, 0x80, 0xfe, 0x07, 0xf0, 0x3e, 0x0f, 0xb1, + 0x05, 0x05, 0x19, 0x2c, 0x20, 0x39, 0xaf, 0x8a, 0x48, 0xe9, 0xfb, 0x4e, 0xed, 0xc7, 0xbe, 0x6f, + 0x5b, 0xac, 0x58, 0x02, 0x3c, 0x84, 0xc6, 0xf6, 0xc0, 0x40, 0xf7, 0x78, 0x4d, 0xdd, 0x8b, 0x0d, + 0xe7, 0x50, 0x01, 0x3f, 0xd2, 0x6a, 0x43, 0x2c, 0xaf, 0xdd, 0xed, 0xea, 0x51, 0x7d, 0x91, 0x2c, + 0x07, 0x57, 0x30, 0x76, 0x1d, 0xd0, 0xe8, 0x5e, 0xf5, 0x2e, 0x02, 0xa0, 0xf5, 0x04, 0x52, 0x9d, + 0x22, 0xbf, 0xda, 0x21, 0x3b, 0x04, 0x96, 0x7e, 0x4f, 0xea, 0x2d, 0x0f, 0x69, 0xf0, 0xc3, 0xc2, + 0xea, 0x8e, 0x0f, 0xd9, 0xed, 0x9f, 0x91, 0x6a, 0x71, 0x7a, 0x1b, 0x5d, 0x3f, 0xc4, 0x5b, 0x93, + 0x64, 0xfb, 0x08, 0x49, 0x96, 0xd1, 0xd5, 0xf3, 0x2e, 0x38, 0x9f, 0x96, 0xd7, 0x43, 0xc3, 0xe0, + 0xf0, 0x7c, 0x1f, 0x81, 0xf8, 0x1f, 0x83, 0xd6, 0xb7, 0x69, 0x60, 0x02, 0xec, 0x37, 0xb8, 0x28, + 0x6f, 0x34, 0x37, 0xf5, 0x1d, 0x4b, 0x4b, 0x9f, 0x97, 0xb5, 0xfa, 0x5a, 0x50, 0xa6, 0xec, 0x01, + 0x3f, 0xb0, 0x07, 0x9a, 0x42, 0x7f, 0xc3, 0x09, 0xe7, 0x50, 0x01, 0x3f, 0xd2, 0x6a, 0x14, 0x34, + 0x33, 0xd3, 0xb2, 0xb7, 0x84, 0x00, 0x6e, 0x91, 0xe1, 0x20, 0x56, 0xef, 0x8b, 0x8e, 0x44, 0x6e, + 0xe5, 0xa7, 0x44, 0x89, 0x53, 0x82, 0xb6, 0xb2, 0xa1, 0xef, 0xa8, 0x9d, 0x42, 0x98, 0xa5, 0xde, + 0x26, 0xe5, 0xf2, 0xe6, 0x33, 0x76, 0x66, 0x58, 0x45, 0xeb, 0x40, 0x57, 0xc6, 0x91, 0x06, 0x8b, + 0x1c, 0xcf, 0x58, 0x89, 0xd9, 0x41, 0x93, 0x51, 0x18, 0xfe, 0x08, 0x86, 0x4f, 0x68, 0xbf, 0x21, + 0x65, 0x19, 0x76, 0xa6, 0x87, 0xe0, 0x7e, 0x0f, 0xc0, 0xfc, 0x0f, 0xe0, 0x3f, 0x81, 0xf8, 0x73, + 0x82, 0xc4, 0x87, 0x41, 0xe7, 0x37, 0x70, 0xf0, 0x0a, 0x9e, 0xeb, 0xa3, 0x02, 0x7c, 0x17, 0x81, + 0x2c, 0x26, 0xab, 0xa3, 0xa4, 0x84, 0xe0, 0x07, 0xf3, 0x00, 0x1f, 0x6e, 0x10, 0xf3, 0xc3, 0x06, + 0x27, 0x50, 0x01, 0x3f, 0xd2, 0x6a, 0x43, 0x34, 0xaf, 0xdd, 0x47, 0x5c, 0xd0, 0x54, 0x05, 0x05, + 0xec, 0x4a, 0x53, 0xf8, 0x78, 0x29, 0xbc, 0x82, 0x18, 0x56, 0x38, 0xd4, 0xcd, 0x63, 0xde, 0x94, + 0x75, 0xba, 0xcc, 0xd3, 0xaa, 0xcb, 0xce, 0x4e, 0x27, 0x05, 0x71, 0x74, 0xa6, 0xba, 0xa7, 0xae, + 0xe2, 0x30, 0x16, 0x21, 0x1f, 0x59, 0x51, 0x74, 0xac, 0x13, 0x24, 0xd8, 0x89, 0x5b, 0x7a, 0x61, + 0xa4, 0x49, 0x3e, 0xac, 0x0e, 0xe1, 0xa1, 0xf0, 0x10, 0x78, 0x17, 0xcd, 0x04, 0xf9, 0xb7, 0xac, + 0x9f, 0x0f, 0x83, 0xe0, 0xf8, 0x1f, 0x81, 0xf8, 0x1f, 0x83, 0xc0, 0x0e, 0x9f, 0x5b, 0xda, 0x2f, + 0xdc, 0x72, 0x49, 0x73, 0x02, 0xcf, 0x94, 0x18, 0xa7, 0x16, 0x1b, 0x52, 0x14, 0x1f, 0x1b, 0x7a, + 0xfd, 0x04, 0xcf, 0xc0, 0xfc, 0x07, 0xc6, 0x82, 0x67, 0x52, 0xfc, 0x3f, 0xd2, 0x6a, 0x23, 0x44, + 0x69, 0xd4, 0x3e, 0xe9, 0x79, 0x25, 0x1d, 0x3f, 0xe3, 0x88, 0x05, 0x0b, 0x8c, 0x76, 0x29, 0x7e, + 0xe7, 0xd5, 0x8a, 0xb6, 0x5f, 0x02, 0x85, 0x0e, 0x92, 0x70, 0xb8, 0x44, 0xff, 0x73, 0x7e, 0x47, + 0xe4, 0x30, 0xa4, 0x7f, 0x8a, 0x52, 0x2d, 0x18, 0xa6, 0x28, 0xa1, 0x43, 0x41, 0x2f, 0xaa, 0x69, + 0xba, 0xdb, 0x82, 0xd2, 0xc7, 0x8b, 0xa4, 0x31, 0x85, 0x9b, 0x87, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x73, 0xec, 0x31, 0x42, 0xd2, 0xa7, 0xf9, 0x71, 0x47, 0xc3, 0xe1, 0xf8, 0x1f, 0x81, 0xf8, 0x3e, + 0x0f, 0x11, 0xe9, 0xd3, 0x35, 0xef, 0x37, 0xd6, 0xe4, 0x1a, 0xed, 0x15, 0x73, 0xa7, 0xf3, 0x93, + 0x76, 0xb1, 0x56, 0x5f, 0x78, 0xdc, 0x92, 0x39, 0xbb, 0x90, 0x03, 0xf8, 0x1f, 0x83, 0xf3, 0x05, + 0x67, 0xe7, 0xfa, 0x3f, 0xd2, 0x6a, 0x26, 0x34, 0x35, 0x15, 0x69, 0xd5, 0x3a, 0xa2, 0xc3, 0x59, + 0x46, 0x4c, 0x85, 0x96, 0xaa, 0xc2, 0x9f, 0x34, 0x4c, 0x72, 0x21, 0x98, 0xa7, 0xea, 0xfb, 0xce, + 0xf8, 0xec, 0xce, 0x01, 0x02, 0xa1, 0x70, 0x16, 0x25, 0x1b, 0x7c, 0xb2, 0x38, 0x91, 0x9c, 0xbf, + 0xb8, 0x0a, 0xd4, 0x06, 0xf7, 0x30, 0xcb, 0x51, 0xbf, 0x76, 0x56, 0x2e, 0x9a, 0xeb, 0xb5, 0x8f, + 0x2d, 0x97, 0x6c, 0xc2, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x76, 0x62, 0xab, 0xeb, 0x7d, + 0x4f, 0x07, 0xc1, 0xf0, 0x7e, 0x07, 0xe0, 0x7e, 0x0f, 0x83, 0x9c, 0x10, 0x6d, 0x2a, 0x41, 0x2c, + 0x62, 0x51, 0xc2, 0x35, 0x2d, 0xb3, 0x88, 0x9e, 0x77, 0xc1, 0xe7, 0xad, 0x83, 0xe6, 0x48, 0x80, + 0xde, 0x80, 0x0f, 0xb2, 0x03, 0xf0, 0x3e, 0x88, 0x27, 0xe7, 0xfa, 0x3f, 0xd2, 0x6a, 0x36, 0x3c, + 0xa7, 0x91, 0xec, 0x56, 0xe1, 0x98, 0x95, 0xe9, 0x1d, 0xbc, 0xc2, 0x4a, 0x52, 0x0b, 0x1c, 0x89, + 0x27, 0x28, 0x9b, 0x34, 0x2c, 0x75, 0xb2, 0x56, 0x2f, 0x2c, 0x3f, 0x02, 0x00, 0xc6, 0x99, 0xff, + 0x88, 0x4e, 0x09, 0xde, 0xde, 0x4f, 0xec, 0xe1, 0xdf, 0x4d, 0x20, 0x62, 0x10, 0x56, 0x83, 0x17, + 0x96, 0x25, 0x37, 0x43, 0xc4, 0x8b, 0x9b, 0xaf, 0xd1, 0x13, 0x84, 0x3c, 0x08, 0x4a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x76, 0x0f, 0xdb, 0xda, 0x39, 0xd6, 0xf0, 0x7c, 0x1e, 0x07, 0xc1, 0xf8, + 0x1f, 0x83, 0xc3, 0xdc, 0x81, 0x20, 0x60, 0x23, 0x26, 0x5c, 0x10, 0x75, 0xc4, 0x4b, 0x4e, 0xa8, + 0x84, 0x8c, 0x3b, 0x5c, 0xc4, 0xdc, 0x28, 0x39, 0x91, 0x01, 0xe7, 0x03, 0xf8, 0x0f, 0xc3, 0x0b, + 0x27, 0xe7, 0xfa, 0x3f, 0xd2, 0x6a, 0x66, 0x1c, 0xaf, 0xdd, 0xe6, 0x14, 0x51, 0x1d, 0x3e, 0x4d, + 0xf9, 0x6e, 0xb8, 0x18, 0x1f, 0x89, 0x35, 0xa4, 0xc6, 0x79, 0x15, 0x60, 0xeb, 0x82, 0xb7, 0xae, + 0x98, 0x7c, 0x70, 0x5c, 0x5d, 0xab, 0x99, 0x44, 0xd0, 0x4d, 0x7d, 0xb2, 0xb2, 0x18, 0x15, 0x99, + 0x4b, 0x1d, 0x06, 0xad, 0x85, 0x51, 0xd7, 0x4f, 0xe8, 0x3b, 0xbf, 0x3b, 0x20, 0x5d, 0xb5, 0x9e, + 0xec, 0x2b, 0x9d, 0xa1, 0xd8, 0x8b, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xb5, 0x43, 0xbf, + 0xbc, 0x78, 0x3e, 0x0f, 0x83, 0xf0, 0x1f, 0x83, 0xc3, 0x9a, 0x3c, 0xc6, 0x22, 0x02, 0x31, 0x0d, + 0x74, 0xd6, 0x10, 0xb1, 0x8a, 0x37, 0xab, 0x8d, 0xdb, 0xa0, 0xc8, 0x26, 0x8d, 0x8e, 0x44, 0x5f, + 0x60, 0xbc, 0xe0, 0x3f, 0x01, 0xf8, 0x1f, 0x04, 0x27, 0xe7, 0xfa, 0x3f, 0xd2, 0x6a, 0x45, 0xa4, + 0x3f, 0xa9, 0x40, 0x35, 0xdd, 0x67, 0x11, 0x0b, 0xa4, 0x4d, 0x3c, 0xc4, 0xc1, 0x33, 0x8d, 0xe7, + 0xcc, 0x54, 0xe6, 0xf9, 0x68, 0x49, 0xa7, 0x13, 0x19, 0x19, 0xe1, 0x34, 0x9e, 0xc9, 0xcc, 0x42, + 0x08, 0x36, 0xb6, 0x53, 0x01, 0xc2, 0x13, 0x36, 0x48, 0xe5, 0x05, 0x1c, 0xa1, 0x51, 0xa7, 0x17, + 0x43, 0x1e, 0x4e, 0xe4, 0x2c, 0x56, 0xbe, 0x00, 0x00, 0x00, 0x0a, 0x96, 0x82, 0xdd, 0x7b, 0xa1, + 0xdc, 0x9b, 0xc7, 0xae, 0xce, 0xd3, 0x6a, 0x04, 0x8a, 0x5c, 0x0c, 0xf8, 0x70, 0x0f, 0xbf, 0x57, + 0x5a, 0xdc, 0x3a, 0x27, 0xd0, 0x9f, 0x66, 0xda, 0x2c, 0xbd, 0x47, 0x2f, 0xbe, 0x1a, 0x91, 0x47, + 0xe8, 0x8e, 0x27, 0x8b, 0x9a, 0xcb, 0xf2, 0x48, 0x7e, 0x07, 0xc1, 0xf8, 0x1e, 0xf6, 0x0a, 0x87, + 0x27, 0xe7, 0xfa, 0x3f, 0xd2, 0x79, 0xf6, 0x3c, 0x33, 0x99, 0xb9, 0xa2, 0xb8, 0x20, 0xa8, 0xd0, + 0x14, 0xc3, 0xc7, 0xbd, 0x56, 0x64, 0x68, 0x11, 0x39, 0x6c, 0xd6, 0x71, 0x8f, 0xca, 0x73, 0x0f, + 0x39, 0xce, 0xf3, 0x2d, 0xd2, 0xb6, 0xc2, 0x0d, 0x00, 0x0d, 0xd7, 0xda, 0xb7, 0xa8, 0xa7, 0x2f, + 0x64, 0xdd, 0x61, 0x33, 0x6a, 0xe5, 0x01, 0x56, 0xdb, 0x57, 0xc8, 0xd0, 0x99, 0x25, 0xa3, 0xbf, + 0xe8, 0x99, 0xad, 0x1b, 0x14, 0xe5, 0x19, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, + 0xff, 0xe3, 0xc0, 0xfc, 0x0f, 0xc0, 0xfc, 0x07, 0xe0, 0x78, 0x0f, 0x66, 0x77, 0xb9, 0xf7, 0xfc, + 0x8e, 0xa8, 0x45, 0xe2, 0xed, 0xcc, 0xa3, 0xbc, 0x63, 0x25, 0xe0, 0x8c, 0xdb, 0xf1, 0x03, 0x99, + 0x03, 0xf6, 0x00, 0x9f, 0xe0, 0x1f, 0xc3, 0x0d, 0x27, 0xe7, 0x96, 0x3f, 0xd2, 0x6a, 0x55, 0xbc, + 0x69, 0xac, 0x33, 0x2a, 0x32, 0xd6, 0x00, 0xf5, 0x23, 0x68, 0xb5, 0x0a, 0x0d, 0x7a, 0xcf, 0x1f, + 0xf7, 0xa3, 0x8e, 0xf6, 0x01, 0x61, 0x3c, 0x7d, 0x41, 0x95, 0x21, 0xce, 0x2f, 0xe9, 0x70, 0xb3, + 0xc3, 0x30, 0x21, 0xc6, 0xe5, 0x8a, 0x27, 0x72, 0x7f, 0x0f, 0xcc, 0x0a, 0x90, 0x9f, 0xbd, 0xcd, + 0x5a, 0x8c, 0xf5, 0x59, 0xcb, 0x29, 0xff, 0xc5, 0x58, 0x00, 0x79, 0x88, 0xdc, 0xf3, 0x8a, 0x19, + 0x7f, 0x5f, 0x1d, 0x73, 0x4b, 0x32, 0xa4, 0xdb, 0x74, 0xe1, 0xac, 0x3e, 0x0f, 0xc0, 0x00, 0xd0, + 0xe2, 0x5e, 0xa2, 0x12, 0x93, 0x5b, 0x2f, 0x83, 0x88, 0x00, 0x52, 0xdd, 0x2a, 0xd0, 0x12, 0x31, + 0x85, 0x4f, 0x62, 0x18, 0x7f, 0xae, 0x3e, 0x90, 0x3c, 0x3e, 0x0f, 0xc1, 0xf1, 0x91, 0x3a, 0x16, + 0x27, 0xe7, 0x96, 0x3b, 0xd2, 0x7a, 0x06, 0x3c, 0xaf, 0xdc, 0xb8, 0x33, 0x53, 0x0e, 0x82, 0xd0, + 0x2d, 0x35, 0x02, 0x56, 0x8b, 0xa3, 0x75, 0x19, 0xce, 0x1d, 0xd0, 0x3f, 0x25, 0x19, 0x13, 0xc6, + 0x96, 0xc5, 0x1d, 0x4a, 0x0f, 0x06, 0xae, 0x07, 0x3e, 0xf1, 0x0d, 0x05, 0x99, 0x16, 0xce, 0x7d, + 0x6e, 0x50, 0xed, 0xdb, 0x6e, 0x7e, 0x7d, 0x90, 0xb4, 0xd0, 0x78, 0x5a, 0x98, 0x33, 0xa1, 0x7f, + 0xfc, 0x43, 0x27, 0x4b, 0x2a, 0xe3, 0x8c, 0xd0, 0x90, 0x1f, 0xae, 0x5f, 0x26, 0x1e, 0x1e, 0x0f, + 0xc0, 0xfc, 0x0f, 0xc1, 0xf0, 0x3f, 0x8e, 0x2a, 0x7b, 0xdc, 0x96, 0x1f, 0x9b, 0x7c, 0x27, 0x8f, + 0x6e, 0x0d, 0x0c, 0xd8, 0xa4, 0xf8, 0xd6, 0x9e, 0x3b, 0xf1, 0x4f, 0x01, 0xc0, 0x86, 0x63, 0xb6, + 0x01, 0xf8, 0x23, 0xee, 0x07, 0xe0, 0x3e, 0x9f, 0x26, 0x4c, 0x20, 0xfb, 0xd2, 0x6a, 0x03, 0xec, + 0x17, 0x53, 0xd0, 0x86, 0xa5, 0xe8, 0x6d, 0x4d, 0xbe, 0x39, 0xb9, 0xa5, 0x84, 0xc6, 0x65, 0x73, + 0x7c, 0x85, 0x03, 0x8b, 0xa7, 0xda, 0x83, 0x20, 0x7d, 0x0b, 0x4d, 0xcf, 0x76, 0xcb, 0x5c, 0x2e, + 0x2c, 0x4a, 0x51, 0xfc, 0xed, 0xf5, 0xb2, 0x0b, 0x0f, 0x0f, 0xe5, 0xe1, 0x2d, 0x10, 0x1a, 0xa3, + 0xcb, 0x72, 0x90, 0xab, 0xda, 0x00, 0xda, 0xcf, 0x45, 0xcc, 0x92, 0xb1, 0x56, 0x88, 0xae, 0x86, + 0x27, 0x58, 0x70, 0x80, 0x20, 0x0f, 0xe0, 0x3e, 0x07, 0xf0, 0x1f, 0x80, 0xfe, 0x07, 0x8f, 0xb0, + 0x83, 0xb1, 0xc0, 0x27, 0x20, 0x70, 0xa1, 0xc8, 0x62, 0x2a, 0xdc, 0xae, 0x70, 0xe8, 0xd5, 0xec, + 0x9e, 0xfb, 0xfe, 0xcd, 0x42, 0x2f, 0x80, 0x0f, 0xb8, 0x0f, 0xf0, 0x0f, 0xb7, 0x00, 0xfa, 0x95, + 0x27, 0xce, 0x0d, 0xbb, 0xd2, 0x6a, 0x43, 0xdc, 0x35, 0x7f, 0x0d, 0x4c, 0x15, 0xef, 0xff, 0x79, + 0x66, 0x85, 0x1c, 0x28, 0xef, 0x72, 0x31, 0xf1, 0x4a, 0x76, 0x45, 0x5a, 0xd5, 0xf2, 0xed, 0xb9, + 0x36, 0xad, 0x63, 0x9c, 0x43, 0x33, 0xc0, 0xf2, 0x26, 0xad, 0x99, 0x18, 0xb7, 0xdf, 0x09, 0x9e, + 0xd2, 0xc1, 0x55, 0x5b, 0x95, 0xa5, 0xba, 0x98, 0xec, 0x96, 0x3b, 0x93, 0x0d, 0x94, 0x6d, 0xc9, + 0x0e, 0xae, 0x65, 0xcc, 0x9b, 0x1a, 0xd8, 0x54, 0x18, 0xe1, 0x80, 0x0a, 0xe0, 0x1c, 0xe4, 0xf3, + 0xe0, 0x7c, 0x1f, 0x83, 0xf0, 0x1f, 0xc0, 0xf8, 0x3c, 0x1f, 0xab, 0xa9, 0xe8, 0xee, 0x30, 0x5d, + 0x8f, 0x19, 0x57, 0xf5, 0xaa, 0x78, 0xe5, 0x69, 0xf4, 0x11, 0x13, 0x73, 0x17, 0x47, 0xfd, 0xc0, + 0x3d, 0xc8, 0x1f, 0xc0, 0xfc, 0x07, 0xe2, 0xa0, 0xc6, 0x3d, 0xab, 0x3b, 0xd2, 0x6a, 0x24, 0x5c, + 0xb7, 0xcc, 0x62, 0xe4, 0x68, 0xfe, 0x89, 0x40, 0x8a, 0x0a, 0xc0, 0x0e, 0xf8, 0x35, 0x2d, 0xc7, + 0x90, 0xc0, 0x07, 0xbf, 0x4e, 0x32, 0xd5, 0x0a, 0xb2, 0x89, 0xe3, 0xa5, 0x6c, 0x0f, 0xe7, 0x49, + 0x27, 0xe3, 0xa8, 0xf5, 0xb5, 0x51, 0x96, 0x00, 0x4b, 0x3a, 0x4a, 0xbd, 0x2f, 0xd8, 0x45, 0x20, + 0x14, 0x82, 0xd8, 0xaf, 0xd5, 0x17, 0x3d, 0xf5, 0x1b, 0xd9, 0x37, 0x8a, 0x56, 0xf6, 0x19, 0x16, + 0xd3, 0x02, 0x37, 0xb5, 0xc0, 0xf1, 0x7e, 0xf3, 0x87, 0xc3, 0xf0, 0xfc, 0x3e, 0x1f, 0x03, 0xa6, + 0xa6, 0xbd, 0x86, 0x87, 0x7f, 0xee, 0xef, 0x69, 0x80, 0x7c, 0xee, 0x8b, 0x3f, 0xf2, 0x04, 0x82, + 0xc1, 0xad, 0xe9, 0x10, 0x56, 0x98, 0xa9, 0x4c, 0xb2, 0xa3, 0x9d, 0xf0, 0x3c, 0xf8, 0x7a, 0x17, + 0x07, 0xcb, 0x15, 0xbb, 0xd2, 0x79, 0xf5, 0x7c, 0xaf, 0xdd, 0x5d, 0x70, 0x6c, 0xfd, 0x44, 0x6a, + 0x11, 0x28, 0x28, 0x00, 0x01, 0x20, 0x77, 0x41, 0xb0, 0x01, 0xde, 0x49, 0x2e, 0x48, 0x76, 0xa1, + 0x4b, 0x17, 0xe0, 0x0e, 0x04, 0x23, 0xca, 0x32, 0x74, 0x27, 0x50, 0x02, 0xcc, 0x4d, 0xc6, 0x49, + 0x5b, 0xbb, 0x7e, 0xa4, 0xbf, 0xa0, 0x6c, 0x12, 0x85, 0xa8, 0x0f, 0x26, 0xfe, 0x97, 0x52, 0x68, + 0xc7, 0xfc, 0x0f, 0x5d, 0x9c, 0xbb, 0x6c, 0x13, 0xf9, 0xd1, 0x86, 0x83, 0x58, 0x79, 0xef, 0x61, + 0x87, 0x8d, 0x06, 0x30, 0xe3, 0xf8, 0x49, 0x11, 0x76, 0x45, 0x21, 0x2a, 0x4f, 0x46, 0x57, 0xf6, + 0x38, 0xce, 0xb4, 0x2b, 0x2f, 0xe7, 0x74, 0x68, 0x49, 0x5e, 0x64, 0x62, 0x5f, 0x1d, 0xe6, 0x3e, + 0x50, 0x78, 0x7c, 0x18, 0x0f, 0xe0, 0x3e, 0x35, 0x07, 0xcb, 0x15, 0xbb, 0xd2, 0x79, 0xe4, 0xf4, + 0x69, 0xd4, 0x53, 0xa1, 0xf3, 0x0e, 0xec, 0xe2, 0xa2, 0x7e, 0xde, 0xe0, 0x5d, 0x49, 0x92, 0x4e, + 0xd9, 0xca, 0x6c, 0x1f, 0x60, 0x07, 0x32, 0x68, 0xab, 0x6d, 0xb7, 0x0d, 0x45, 0xa5, 0x93, 0x71, + 0xd3, 0x2c, 0x11, 0x24, 0xfc, 0xbb, 0x5e, 0x0f, 0xea, 0xdd, 0x33, 0x13, 0xcd, 0x83, 0x46, 0x14, + 0x3d, 0x11, 0xcc, 0x97, 0x03, 0x18, 0x90, 0x2e, 0x52, 0x83, 0xae, 0xff, 0xa8, 0x79, 0x15, 0x2a, + 0x2f, 0xac, 0x3b, 0x0b, 0x4c, 0xea, 0xa0, 0x63, 0x38, 0xf0, 0x7f, 0xfd, 0xa7, 0xfb, 0xa3, 0xca, + 0x5f, 0x79, 0xeb, 0x67, 0x49, 0x51, 0x09, 0x44, 0x02, 0x41, 0x2d, 0xa0, 0xc2, 0x1c, 0x9f, 0x99, + 0x3b, 0xab, 0xdb, 0x09, 0x59, 0xca, 0xb4, 0xd0, 0xc7, 0xc0, 0xfc, 0x1f, 0xb0, 0x88, 0xfe, 0xab, + 0x06, 0x3d, 0xab, 0x3b, 0xd2, 0x79, 0xc4, 0x34, 0xb0, 0xdc, 0x62, 0xbe, 0x61, 0x09, 0x75, 0x38, + 0x4f, 0x05, 0x02, 0xd7, 0xea, 0xbb, 0x0b, 0x1e, 0xb9, 0x2f, 0x21, 0x73, 0x59, 0x34, 0x24, 0x53, + 0x10, 0x1f, 0xa4, 0x1c, 0xc2, 0xf3, 0x7c, 0x46, 0x5a, 0x20, 0x6b, 0x6f, 0x0a, 0x76, 0xc7, 0x10, + 0xeb, 0x21, 0x8c, 0x46, 0x57, 0xf9, 0x2d, 0xd9, 0x54, 0x4c, 0x51, 0x7a, 0xf0, 0xdd, 0x77, 0xae, + 0x94, 0xe3, 0x9e, 0xaa, 0xb4, 0x01, 0xc6, 0x7a, 0x00, 0x00, 0x00, 0x02, 0x37, 0xed, 0x8b, 0x51, + 0x48, 0xc7, 0x0f, 0x0e, 0x0f, 0x07, 0xf9, 0x1a, 0x0a, 0x06, 0xa0, 0x83, 0x00, 0x52, 0x9e, 0xf9, + 0xee, 0xbe, 0xc2, 0x1d, 0xab, 0x26, 0xa6, 0x5c, 0x95, 0x51, 0x0b, 0x55, 0xee, 0x4f, 0x8b, 0x19, + 0x8f, 0x33, 0x01, 0x07, 0xe1, 0x83, 0xc6, 0x39, 0x47, 0xcb, 0x15, 0xbf, 0xd2, 0x79, 0xf5, 0x84, + 0x69, 0xd5, 0x7f, 0x4f, 0xd0, 0xba, 0xd5, 0xf0, 0xca, 0xf9, 0x55, 0x53, 0x2d, 0x5d, 0xdd, 0x68, + 0x17, 0x3c, 0xa0, 0x7f, 0x91, 0xde, 0xfe, 0x79, 0x26, 0x2c, 0x56, 0x0d, 0x6d, 0xbc, 0x41, 0x2c, + 0xb6, 0x6e, 0xdf, 0x46, 0x8f, 0x3a, 0xbd, 0x82, 0x4b, 0xd1, 0x64, 0xb2, 0x65, 0xb6, 0x5c, 0x11, + 0x7a, 0xb1, 0xfc, 0x37, 0xda, 0x1d, 0x15, 0x9c, 0x73, 0x2f, 0x39, 0x0e, 0xc8, 0xf9, 0x00, 0x00, + 0x00, 0x00, 0x32, 0x44, 0x6c, 0x0c, 0xb5, 0x36, 0x6e, 0xe1, 0xf0, 0x1e, 0x9f, 0x1d, 0x73, 0xab, + 0x16, 0x46, 0x7e, 0xfb, 0x8e, 0x41, 0xd1, 0xb6, 0x4e, 0xa6, 0x92, 0xe3, 0x5b, 0x6b, 0xd7, 0x28, + 0xfc, 0x56, 0x60, 0x6d, 0x8b, 0x11, 0x2f, 0x38, 0x37, 0xe7, 0x1f, 0x1e, 0x1f, 0x80, 0xf2, 0x95, + 0x06, 0x3d, 0x3d, 0x3f, 0xd2, 0x79, 0xe5, 0x64, 0x69, 0x36, 0x3a, 0x20, 0x8b, 0xb3, 0x05, 0xc1, + 0x8d, 0xe6, 0x37, 0xe2, 0xef, 0xf6, 0xf5, 0xee, 0x37, 0x32, 0xb7, 0x81, 0xc1, 0x18, 0xe6, 0x32, + 0xf3, 0x50, 0x34, 0x2a, 0x5c, 0xba, 0x54, 0xab, 0x34, 0x15, 0x96, 0xb0, 0x9e, 0xb2, 0x8e, 0xe8, + 0x28, 0xac, 0x26, 0xd9, 0xf5, 0x46, 0xbd, 0x94, 0x28, 0x3f, 0x7a, 0x32, 0x28, 0xe7, 0x60, 0x20, + 0x9c, 0xe7, 0x1b, 0x88, 0xfa, 0x7b, 0x18, 0x45, 0xfc, 0xdd, 0x20, 0xd0, 0xe3, 0x4e, 0xe6, 0x62, + 0xc3, 0x87, 0x07, 0xc1, 0xfb, 0x2e, 0xec, 0xbe, 0xe6, 0xb2, 0x98, 0xa8, 0x8d, 0x00, 0x8e, 0x64, + 0xa3, 0xb4, 0x36, 0xc0, 0x9c, 0x87, 0x14, 0xc4, 0x14, 0x72, 0xd8, 0xa3, 0x34, 0x13, 0x0b, 0x41, + 0x7e, 0x71, 0x81, 0xe1, 0xf8, 0x80, 0xf6, 0x88, 0xe7, 0xcc, 0x07, 0xbf, 0xd2, 0x79, 0xe6, 0x2c, + 0x69, 0xf1, 0xf5, 0x5a, 0x22, 0xc4, 0xa2, 0x02, 0x0f, 0x0f, 0xb1, 0xc4, 0x35, 0xad, 0x7d, 0x21, + 0x7b, 0x26, 0xb6, 0x63, 0xe4, 0xa4, 0xe7, 0xc7, 0x26, 0xcc, 0xf7, 0x6d, 0x7e, 0x33, 0x1a, 0xd2, + 0x9d, 0xd7, 0xb4, 0xca, 0x97, 0x5b, 0x15, 0xc0, 0x99, 0xb4, 0xe8, 0x3e, 0xad, 0xcb, 0x14, 0x87, + 0xc4, 0x96, 0x1e, 0x78, 0xad, 0x9d, 0x40, 0x31, 0x51, 0x02, 0xdb, 0x18, 0x33, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x81, 0x64, 0xdb, 0xf1, 0xe1, 0xf0, 0x7c, 0x1f, 0x03, 0xfb, 0x93, 0x0c, + 0x33, 0x50, 0x84, 0x93, 0xc8, 0x54, 0xed, 0x60, 0xe6, 0x1a, 0x78, 0xc4, 0x78, 0x91, 0x96, 0xaa, + 0x6c, 0x7d, 0x77, 0xd8, 0x3e, 0x1d, 0x19, 0x3b, 0xf3, 0x01, 0xc1, 0xf8, 0x7e, 0x07, 0xe2, 0x97, + 0x26, 0x3d, 0x3d, 0x3f, 0xd2, 0x79, 0xd6, 0x14, 0x69, 0xd4, 0x53, 0xa3, 0xe8, 0x70, 0x4a, 0x81, + 0xf6, 0xd3, 0x9c, 0x63, 0xec, 0x68, 0x9c, 0x8e, 0x6f, 0x1f, 0xde, 0xce, 0x4c, 0xcf, 0xa4, 0x67, + 0x8a, 0x6b, 0x6e, 0x1e, 0x80, 0x26, 0x85, 0x95, 0xe8, 0x72, 0x78, 0x6f, 0xca, 0xb7, 0x41, 0xe1, + 0x34, 0x8f, 0xdb, 0x72, 0x39, 0xd0, 0xc8, 0x29, 0xf9, 0x57, 0xd3, 0x74, 0x8c, 0x2d, 0xcb, 0xf0, + 0x33, 0x50, 0x09, 0x12, 0x31, 0xea, 0x1f, 0xc0, 0xe4, 0x6d, 0x7f, 0x00, 0x00, 0x0e, 0x50, 0xd9, + 0x0a, 0x23, 0xe1, 0xc0, 0xf8, 0x3e, 0x07, 0x96, 0x4e, 0x4f, 0x83, 0x5c, 0xef, 0xea, 0xf2, 0xd9, + 0x5c, 0xf9, 0x62, 0x0b, 0x5b, 0xf5, 0xb0, 0xaa, 0xd0, 0x38, 0x17, 0x16, 0x93, 0x6f, 0x0f, 0xc0, + 0xce, 0x72, 0x30, 0xf8, 0xfc, 0x20, 0xfa, 0x8b, 0x27, 0xcc, 0x07, 0xbf, 0xd2, 0x79, 0xf6, 0x14, + 0x69, 0xd4, 0x8e, 0x07, 0x5e, 0x1e, 0xb3, 0x98, 0x6c, 0x51, 0x60, 0xba, 0xd9, 0x89, 0xde, 0xb9, + 0x2a, 0x19, 0xcf, 0x18, 0xd0, 0x53, 0x46, 0x8a, 0x36, 0xe6, 0xf6, 0x48, 0x89, 0xb4, 0x96, 0x8b, + 0x86, 0xe9, 0xb4, 0x36, 0xec, 0x19, 0x7e, 0x88, 0x8f, 0x0d, 0xd3, 0xd6, 0x6a, 0xd0, 0xc8, 0x3e, + 0xf7, 0xe7, 0x03, 0xac, 0xb8, 0xaa, 0x0f, 0xd1, 0x66, 0x30, 0x13, 0x44, 0x12, 0x98, 0xc3, 0x64, + 0x5b, 0x90, 0x08, 0x4d, 0xb5, 0x4d, 0xde, 0x6f, 0x20, 0x2d, 0xf8, 0x7d, 0xb9, 0x57, 0x8f, 0x0f, + 0x83, 0xfc, 0xd4, 0x10, 0xcd, 0xe5, 0x65, 0xd7, 0xb8, 0x54, 0x7c, 0x78, 0xe6, 0xb4, 0xe0, 0xc3, + 0x74, 0x04, 0xf9, 0x0e, 0xdd, 0xf2, 0x69, 0xc1, 0x69, 0xcc, 0x82, 0x67, 0x8c, 0x0f, 0xe2, 0x96, + 0x27, 0xcc, 0x07, 0xbf, 0xd2, 0x79, 0xc6, 0x3c, 0xaa, 0xf5, 0xee, 0xed, 0x94, 0x04, 0x6b, 0x57, + 0x87, 0xef, 0xe1, 0xd8, 0x8b, 0x2f, 0x73, 0x7e, 0xbf, 0xbe, 0x65, 0x4a, 0x47, 0xe4, 0xea, 0x59, + 0x02, 0xde, 0xdd, 0x6e, 0xd0, 0xf6, 0x07, 0x3f, 0x8d, 0x19, 0x4b, 0x8e, 0xa0, 0x35, 0xb7, 0x93, + 0xe2, 0x6a, 0xd8, 0x58, 0xbb, 0x32, 0xa9, 0xcc, 0xe4, 0xa4, 0xbf, 0x73, 0xfe, 0xfd, 0xf8, 0x34, + 0x45, 0x00, 0x00, 0xdd, 0xf7, 0x80, 0x28, 0x98, 0x95, 0x80, 0x28, 0xd1, 0x78, 0x30, 0x55, 0x82, + 0x70, 0xe1, 0xe0, 0x7e, 0x03, 0x1d, 0xfe, 0xd3, 0xf1, 0xe0, 0x7c, 0x17, 0x3f, 0x46, 0x0b, 0x04, + 0xbb, 0xc4, 0x24, 0x0c, 0x0b, 0xa2, 0xb3, 0x08, 0xa4, 0x97, 0xa2, 0x2b, 0x8d, 0xe9, 0xd1, 0xaf, + 0xf8, 0x61, 0xc1, 0xe7, 0xf0, 0x08, 0xfa, 0x9e, 0x27, 0xcc, 0x07, 0xbf, 0xd2, 0x79, 0xd5, 0x44, + 0x69, 0xd4, 0x54, 0x54, 0x30, 0x36, 0x69, 0x18, 0x07, 0xe4, 0xba, 0x8e, 0xd5, 0x08, 0xe6, 0x1b, + 0xf4, 0x6f, 0x93, 0xe0, 0xb0, 0xf5, 0xa7, 0x30, 0x34, 0x47, 0x53, 0x4f, 0xde, 0xbb, 0x83, 0xd9, + 0x24, 0x1e, 0xa3, 0xd5, 0x8a, 0x63, 0xda, 0x21, 0xf5, 0xfe, 0xe2, 0x61, 0x05, 0x10, 0xc2, 0x95, + 0xe7, 0xc4, 0x35, 0xcb, 0xa9, 0xe5, 0xe4, 0xe8, 0xde, 0x10, 0xc7, 0xcd, 0x16, 0x15, 0x03, 0xa3, + 0xa7, 0x00, 0x00, 0x42, 0xcc, 0x9c, 0x39, 0x31, 0xcc, 0x66, 0x8f, 0x0f, 0x0f, 0x83, 0xf0, 0x42, + 0xff, 0xee, 0xd0, 0x26, 0x62, 0x0b, 0x80, 0xd0, 0x86, 0xee, 0x19, 0x19, 0x41, 0xcf, 0x8d, 0xfa, + 0x7e, 0x51, 0xd4, 0x46, 0x81, 0x84, 0x45, 0x84, 0x7b, 0x87, 0x87, 0xc7, 0xf0, 0x00, 0xf2, 0x95, + 0x27, 0xcc, 0x07, 0xbf, 0xd2, 0x79, 0xe6, 0x2c, 0xaf, 0xdd, 0x74, 0x2e, 0x0e, 0x76, 0xa9, 0x35, + 0xf5, 0xa3, 0x37, 0xa7, 0x42, 0xd0, 0x54, 0x22, 0x66, 0xf7, 0xb4, 0x42, 0x4f, 0x70, 0x9f, 0x2c, + 0x9b, 0xf8, 0x69, 0x44, 0x94, 0xae, 0xf8, 0x40, 0xd0, 0x67, 0x52, 0x53, 0xdd, 0x46, 0xf5, 0xc8, + 0xa4, 0x08, 0xfc, 0x4f, 0xcb, 0xc5, 0x31, 0x69, 0xc2, 0x4b, 0x60, 0x1d, 0x6a, 0x4a, 0xba, 0x46, + 0x7b, 0xc8, 0xad, 0x97, 0x83, 0x3b, 0x38, 0x02, 0xdd, 0xf9, 0x49, 0x76, 0xfa, 0xbf, 0xc2, 0xf6, + 0xcf, 0x98, 0xfe, 0x02, 0xcf, 0xc7, 0x43, 0xaa, 0xc8, 0x0f, 0xe3, 0xcc, 0x2d, 0x32, 0x58, 0x75, + 0x93, 0x36, 0x08, 0x3f, 0x70, 0x55, 0xda, 0x2f, 0x68, 0x67, 0x6b, 0x97, 0x3b, 0x69, 0xd4, 0xf1, + 0x3d, 0x2c, 0x03, 0x97, 0xc0, 0x77, 0xe2, 0x0f, 0x27, 0xd4, 0x8f, 0x3f, 0xd2, 0x79, 0xc5, 0x8c, + 0xaf, 0xae, 0x9d, 0x0f, 0x5d, 0x27, 0xcd, 0xc5, 0x34, 0x0d, 0xe2, 0x2b, 0x3e, 0xcf, 0x3b, 0x14, + 0xa2, 0xc5, 0x5f, 0x8b, 0x51, 0x2f, 0x5e, 0x93, 0x79, 0x92, 0xbc, 0x5f, 0x61, 0xb2, 0xfe, 0xa1, + 0x69, 0xc9, 0x22, 0x6c, 0xb3, 0xfc, 0xd2, 0x19, 0xbe, 0x36, 0x6e, 0x50, 0x24, 0xbe, 0xc8, 0x78, + 0xc6, 0xfc, 0x9a, 0xe2, 0xa0, 0x78, 0x53, 0x05, 0xef, 0x1d, 0xe9, 0x97, 0x11, 0x45, 0xa6, 0x3a, + 0xf5, 0x5e, 0x00, 0x02, 0x5a, 0x27, 0x4e, 0x69, 0x44, 0x36, 0x47, 0x0f, 0xc0, 0x7c, 0xb8, 0xad, + 0x43, 0xea, 0xe3, 0x81, 0x07, 0x0a, 0xd3, 0x5b, 0x09, 0x4f, 0x08, 0x3d, 0x95, 0xca, 0x49, 0xed, + 0x56, 0x4e, 0xe9, 0x1a, 0xec, 0xc1, 0x61, 0x1f, 0x08, 0x84, 0xef, 0x8c, 0x71, 0xf0, 0x3e, 0x0c, + 0x27, 0xd4, 0x8f, 0x3f, 0xd2, 0x79, 0xd5, 0x5c, 0xaf, 0x08, 0x0c, 0xb0, 0xd5, 0x02, 0xc9, 0xe1, + 0xde, 0x81, 0xec, 0xbf, 0x8e, 0x50, 0x01, 0x65, 0x64, 0x09, 0xc1, 0xd9, 0x1e, 0x6f, 0x1c, 0x05, + 0x0f, 0xde, 0x11, 0xa3, 0x05, 0xc8, 0xc8, 0xda, 0x48, 0xae, 0x1d, 0x18, 0xfb, 0xd6, 0x3b, 0xe7, + 0x8a, 0x3c, 0xb9, 0xe8, 0x5a, 0x45, 0xa1, 0x58, 0xd0, 0xfe, 0xf7, 0xde, 0x8e, 0x43, 0x1c, 0xd2, + 0xbc, 0x63, 0x48, 0xde, 0xce, 0x7a, 0x52, 0xa2, 0x83, 0x2a, 0x7f, 0x10, 0x52, 0x1c, 0x1f, 0x95, + 0x11, 0x5c, 0x7e, 0x01, 0xfb, 0x0c, 0x2b, 0x1c, 0xc0, 0x77, 0xaf, 0x0f, 0xf5, 0xff, 0x1f, 0xa8, + 0x56, 0x40, 0xcb, 0x7a, 0xfc, 0xa9, 0x5d, 0x05, 0x1c, 0x96, 0x95, 0x49, 0x6b, 0x85, 0xc5, 0x5c, + 0x59, 0x95, 0xfe, 0x18, 0xe0, 0x7b, 0x22, 0x06, 0x27, 0xd4, 0x8f, 0x3f, 0xd2, 0x79, 0xd4, 0x7c, + 0x69, 0xd5, 0x83, 0x56, 0xab, 0xe8, 0xbe, 0xf6, 0x6b, 0x41, 0x7a, 0x2c, 0xf4, 0x58, 0x26, 0xfc, + 0x33, 0x23, 0xd2, 0x32, 0x34, 0x7a, 0x01, 0xaa, 0x66, 0xe1, 0x6c, 0x54, 0x0a, 0xe0, 0xae, 0x92, + 0x63, 0xea, 0x1b, 0x40, 0x05, 0xd6, 0x19, 0xfe, 0xe8, 0x56, 0x4a, 0xd7, 0x4c, 0xee, 0xd4, 0x3f, + 0x99, 0xd5, 0x56, 0x57, 0x34, 0xb1, 0x9b, 0x5a, 0x00, 0x00, 0x00, 0x06, 0x1f, 0x5f, 0x00, 0x10, + 0xc4, 0x91, 0x33, 0xea, 0xbb, 0x2f, 0x2a, 0xee, 0x87, 0xa0, 0x00, 0x06, 0xe1, 0xd8, 0xb4, 0x92, + 0xfd, 0xc1, 0xab, 0x6a, 0x1b, 0x2a, 0x32, 0x9c, 0x9f, 0xf6, 0xf5, 0xb7, 0x4c, 0x73, 0x16, 0xca, + 0x42, 0xc7, 0xd0, 0x0d, 0x7e, 0x5d, 0x41, 0x4a, 0x0f, 0x33, 0xe1, 0xe3, 0xf1, 0x19, 0x36, 0x0e, + 0x3b, 0xc6, 0x06, 0x9e, 0xe2, 0x79, 0xd6, 0x3c, 0x69, 0xd4, 0x53, 0xa1, 0xf3, 0x6d, 0xc1, 0x0c, + 0x7b, 0xab, 0xe2, 0xf3, 0xe0, 0xb6, 0x7c, 0x32, 0xe5, 0xe4, 0x15, 0x1f, 0x09, 0x5d, 0xf6, 0x30, + 0x93, 0x8e, 0xb2, 0x70, 0x09, 0x55, 0x78, 0xb4, 0x7c, 0x12, 0xe8, 0x38, 0x3b, 0x9d, 0x4a, 0x4e, + 0x4c, 0xa1, 0xc7, 0x46, 0xad, 0x6f, 0xb0, 0xbf, 0x9f, 0x98, 0x64, 0xb6, 0x4b, 0x25, 0x6d, 0xd1, + 0xf4, 0xbd, 0xc8, 0x9f, 0xfe, 0x15, 0x1b, 0xe0, 0xe2, 0xb3, 0x57, 0xc2, 0x94, 0xb9, 0x81, 0xfc, + 0x28, 0xd4, 0x74, 0x28, 0x22, 0x92, 0x0b, 0xd8, 0x40, 0x9c, 0x66, 0x95, 0x4c, 0xa1, 0x0b, 0x5f, + 0x0f, 0xfc, 0xf7, 0x83, 0x4a, 0x3b, 0x87, 0x8c, 0xe7, 0xd6, 0x19, 0xe8, 0x57, 0x03, 0x8f, 0x1e, + 0x0f, 0xc1, 0xf0, 0x7f, 0x00, 0x4c, 0xee, 0x88, 0x3b, 0xc6, 0x06, 0x9e, 0xe2, 0x79, 0xc5, 0x44, + 0xaf, 0xdd, 0x90, 0x4e, 0xf2, 0x1c, 0xb4, 0x53, 0xed, 0x62, 0x62, 0x07, 0xe8, 0xff, 0x8b, 0x75, + 0x9a, 0xae, 0xca, 0x1b, 0x89, 0xd0, 0x3c, 0x5f, 0x68, 0x9e, 0xe5, 0x46, 0xdd, 0x74, 0x5a, 0x7d, + 0x73, 0xbc, 0xe4, 0x94, 0xa5, 0x14, 0xd6, 0x53, 0x83, 0x2c, 0x3d, 0x6f, 0x3c, 0xa1, 0x3d, 0x39, + 0x79, 0xe6, 0xa7, 0xb3, 0x24, 0x00, 0x1d, 0x36, 0x16, 0x00, 0x02, 0x64, 0xed, 0x01, 0x6d, 0x15, + 0x57, 0x89, 0xa3, 0x29, 0x10, 0x6d, 0xbe, 0x03, 0x79, 0xdb, 0xcf, 0xad, 0xa1, 0x86, 0x77, 0x75, + 0x19, 0x3c, 0x19, 0x58, 0x6a, 0xf2, 0x3a, 0xd9, 0x3e, 0xbb, 0x24, 0x75, 0xd5, 0x42, 0xf0, 0x54, + 0x26, 0xe6, 0x98, 0x19, 0x1d, 0x36, 0xaf, 0x70, 0xc3, 0x83, 0xc7, 0x80, 0xf6, 0x42, 0x22, 0x05, + 0x7b, 0xc6, 0x06, 0x9e, 0xe2, 0x79, 0xc5, 0xd4, 0x69, 0xd5, 0x83, 0x27, 0xa4, 0x2f, 0xb1, 0xee, + 0xfe, 0xfb, 0x55, 0x90, 0x7c, 0xf9, 0xa6, 0x08, 0x7d, 0x96, 0x78, 0x1f, 0x8d, 0x21, 0xb7, 0xb5, + 0x9b, 0x23, 0x0a, 0x25, 0x6d, 0x7d, 0xc1, 0x06, 0x3d, 0xb8, 0x45, 0x5b, 0x4e, 0x03, 0x91, 0x2d, + 0xef, 0x07, 0x89, 0xd7, 0xb2, 0xe3, 0xd8, 0xe1, 0xf2, 0x31, 0xe7, 0xd8, 0xf1, 0x94, 0x9a, 0x4d, + 0xe5, 0xb4, 0x00, 0x00, 0x00, 0xe5, 0x49, 0xfe, 0x76, 0x9f, 0x61, 0x2e, 0x22, 0xf2, 0x08, 0xd6, + 0xc7, 0xe0, 0x02, 0x62, 0xf1, 0x1c, 0xa0, 0x8b, 0x85, 0x28, 0x14, 0x91, 0xf2, 0x0a, 0xc8, 0xeb, + 0x51, 0x64, 0xc0, 0x1d, 0xaa, 0x64, 0x4d, 0xdd, 0x6d, 0x71, 0xd5, 0x49, 0x87, 0x76, 0x05, 0xcc, + 0x64, 0x96, 0xf0, 0xe1, 0xc7, 0x38, 0x1e, 0x0a, 0x3b, 0xc6, 0x06, 0x9e, 0xe2, 0x79, 0xc6, 0x3c, + 0x37, 0xca, 0x9f, 0xb8, 0x92, 0xad, 0xf0, 0xa9, 0xc0, 0x45, 0x97, 0x26, 0x99, 0xa0, 0x58, 0xa5, + 0xfb, 0x57, 0x8f, 0x72, 0x42, 0x94, 0xed, 0xc2, 0x7b, 0xa6, 0x49, 0xb0, 0x16, 0x71, 0x54, 0xb1, + 0x8c, 0xa8, 0x65, 0xc6, 0x68, 0xbc, 0xcd, 0xc5, 0xf5, 0x0d, 0xe2, 0x12, 0x21, 0xf5, 0xfd, 0xd1, + 0x6b, 0xe9, 0xe2, 0x1f, 0x68, 0x9c, 0xb8, 0xe6, 0x5c, 0x41, 0xd7, 0xb2, 0x4d, 0xba, 0xaf, 0xf4, + 0x61, 0x7e, 0x02, 0xcd, 0x05, 0x32, 0xa0, 0xc3, 0x1f, 0x18, 0x70, 0xe0, 0xf9, 0x1e, 0x09, 0xc1, + 0x9d, 0x3e, 0x4d, 0x35, 0x21, 0x84, 0x3d, 0x75, 0xe1, 0xac, 0x52, 0x20, 0xaa, 0xa9, 0x85, 0xe8, + 0x93, 0x8a, 0x0d, 0xe1, 0x6a, 0x63, 0x9c, 0xa1, 0x5b, 0xa1, 0xc7, 0x07, 0x38, 0x3f, 0x83, 0x01, + 0x1d, 0xe3, 0x03, 0x4f, 0x71, 0x3a, 0x05, 0xe9, 0x69, 0xd4, 0x53, 0x77, 0xbb, 0xff, 0x67, 0x70, + 0x39, 0x68, 0x91, 0x89, 0x3c, 0xd1, 0x1f, 0x23, 0x75, 0x50, 0xae, 0x4b, 0x77, 0xa2, 0xe3, 0x76, + 0x5c, 0xf4, 0x72, 0x1d, 0xa8, 0x0f, 0x55, 0x7a, 0x73, 0x45, 0xbe, 0xd4, 0xe0, 0xe8, 0x99, 0x95, + 0x9a, 0xc9, 0x98, 0xb8, 0x34, 0x03, 0xd1, 0xee, 0x2a, 0x96, 0xde, 0x05, 0xd5, 0xe3, 0x3a, 0x64, + 0xa7, 0x23, 0xdd, 0xe4, 0x00, 0x00, 0x00, 0x0b, 0xd8, 0x35, 0xfd, 0x8c, 0x47, 0x0d, 0xe9, 0xba, + 0xd0, 0xfd, 0xf0, 0x38, 0xf3, 0xe0, 0xf8, 0x33, 0xfa, 0x08, 0x77, 0x0a, 0xc3, 0xca, 0x7b, 0x9f, + 0x25, 0xa7, 0x0c, 0x84, 0xbd, 0x28, 0xa1, 0x72, 0x6c, 0x95, 0x59, 0xb7, 0x35, 0x31, 0xda, 0x8b, + 0xe3, 0xe2, 0x80, 0xdb, 0x8d, 0xf0, 0x3b, 0x06, 0x1d, 0xe3, 0x03, 0x4f, 0x71, 0x3a, 0x35, 0xf1, + 0x69, 0xd4, 0x53, 0x7a, 0xa6, 0x57, 0xdf, 0xe0, 0xec, 0xd6, 0x52, 0x4c, 0x37, 0x16, 0xbc, 0x17, + 0xd6, 0x92, 0x5e, 0xf8, 0x71, 0xa2, 0xb3, 0x49, 0xf2, 0x3b, 0x94, 0xb1, 0x4d, 0xe9, 0x39, 0x1e, + 0xb7, 0x3c, 0x2d, 0xdd, 0x5f, 0xfe, 0x9c, 0x89, 0x26, 0x7b, 0xfd, 0x7c, 0x1f, 0xcc, 0xbd, 0x6f, + 0x35, 0x7f, 0x6f, 0x2d, 0x5b, 0xe3, 0x53, 0x1c, 0x7c, 0x04, 0x77, 0x08, 0x30, 0xc1, 0xa1, 0xa2, + 0xed, 0x99, 0x8a, 0x91, 0x26, 0x61, 0xb2, 0x72, 0x99, 0x92, 0xce, 0x1e, 0x0e, 0x1e, 0x0c, 0x3f, + 0xea, 0x80, 0xde, 0x29, 0xef, 0x60, 0xd3, 0xf3, 0xac, 0xa5, 0x09, 0x18, 0x42, 0x0b, 0x6e, 0x63, + 0xe1, 0x31, 0xdb, 0x8d, 0x6b, 0xe7, 0x84, 0xac, 0xc7, 0x18, 0x19, 0x98, 0x6f, 0x80, 0x78, 0xc2, + 0x1d, 0xe3, 0x03, 0x4f, 0x71, 0x3a, 0x26, 0x39, 0x05, 0xc2, 0xd1, 0x02, 0xeb, 0x04, 0x30, 0x1f, + 0xcf, 0x8f, 0x99, 0x5a, 0x19, 0xa7, 0x82, 0xcb, 0x70, 0xf0, 0xf2, 0xa9, 0xc3, 0xfe, 0x36, 0x90, + 0xd7, 0x19, 0xda, 0xce, 0x16, 0xf6, 0xcc, 0x85, 0xe9, 0x73, 0x15, 0x2a, 0xeb, 0x53, 0xdf, 0x4b, + 0xec, 0x7f, 0x01, 0x5b, 0x50, 0x75, 0xcc, 0x9d, 0x62, 0xfd, 0x8b, 0x11, 0x7e, 0x07, 0xfb, 0x79, + 0x22, 0xdb, 0xdc, 0x15, 0x2c, 0xc9, 0xc9, 0x54, 0xd3, 0x39, 0x61, 0xf6, 0xe1, 0x6c, 0x48, 0x06, + 0x70, 0xf8, 0xe7, 0x73, 0xc1, 0xf8, 0x3b, 0x72, 0x45, 0x80, 0x23, 0x87, 0x34, 0x28, 0xed, 0x10, + 0x70, 0x70, 0x48, 0xec, 0x62, 0x03, 0xe2, 0x5b, 0x33, 0x9a, 0xea, 0x72, 0xa1, 0x20, 0x5f, 0x60, + 0x7e, 0x0f, 0xc0, 0xf8, 0x3f, 0x03, 0xf0, 0x03, 0x3c, 0xa4, 0x87, 0x67, 0x71, 0x2a, 0x25, 0x21, + 0x00, 0x01, 0x61, 0xb5, 0x61, 0x7c, 0x6c, 0x47, 0xba, 0x3d, 0xba, 0x3b, 0x5c, 0x42, 0xd7, 0x8e, + 0x8c, 0xe2, 0xb3, 0x20, 0x0d, 0x14, 0x0b, 0x6b, 0x95, 0x91, 0x80, 0x4d, 0x74, 0x86, 0x41, 0x97, + 0x14, 0xb9, 0x72, 0xeb, 0x77, 0xd4, 0x8e, 0x6e, 0xe5, 0xba, 0x3b, 0xe6, 0x83, 0x28, 0xa4, 0xd0, + 0x57, 0x9f, 0xc9, 0x04, 0x3a, 0x71, 0xf3, 0xa4, 0x1b, 0xf5, 0x32, 0xfd, 0x20, 0x36, 0x0d, 0x48, + 0xd3, 0x76, 0x46, 0x67, 0x17, 0xed, 0x1c, 0x1c, 0x38, 0x3c, 0x1e, 0x0f, 0x87, 0x87, 0x87, 0x83, + 0xe1, 0xe5, 0xce, 0x1e, 0x07, 0xae, 0x46, 0xc6, 0x79, 0x46, 0x26, 0xaa, 0x9e, 0x61, 0x4a, 0xef, + 0x81, 0xa6, 0x18, 0xc3, 0xa3, 0x6b, 0xb8, 0x09, 0xf0, 0x3f, 0x01, 0xfc, 0x0f, 0x87, 0xc2, 0x03, + 0x1c, 0xa4, 0x87, 0x67, 0x71, 0x2a, 0x55, 0x79, 0x05, 0xc2, 0x3c, 0xe5, 0x45, 0x6c, 0xe7, 0x10, + 0x4e, 0xd9, 0xe5, 0x84, 0x46, 0x9c, 0x3f, 0x9c, 0x5b, 0x14, 0xe8, 0x9d, 0xd7, 0xf5, 0x7f, 0xd1, + 0x0d, 0x54, 0x3f, 0xca, 0x46, 0x33, 0xf2, 0xc0, 0x0c, 0xfc, 0x2c, 0x7b, 0xd0, 0xb0, 0xf0, 0xa6, + 0xad, 0x21, 0x47, 0x74, 0x16, 0xb2, 0xa6, 0x37, 0x18, 0xfc, 0x2b, 0x65, 0x57, 0x2e, 0xec, 0x69, + 0x08, 0x72, 0x41, 0x29, 0xcf, 0x2c, 0xf1, 0x5d, 0x9d, 0x78, 0x02, 0xe2, 0x7d, 0x86, 0x83, 0x19, + 0x0e, 0xc3, 0x8c, 0x87, 0x83, 0xc3, 0xdd, 0x0d, 0x0c, 0x40, 0xb6, 0x0f, 0xdc, 0x82, 0x5c, 0x09, + 0x6a, 0x42, 0x75, 0x02, 0x0e, 0x47, 0x6b, 0x00, 0xe6, 0x26, 0x13, 0xa8, 0xe2, 0xfa, 0x1a, 0x0f, + 0x0f, 0xc0, 0xf8, 0x3f, 0x07, 0x83, 0xf0, 0x84, 0x1c, 0xa4, 0x87, 0x67, 0x71, 0x2a, 0x45, 0x01, + 0x19, 0xad, 0x36, 0xf5, 0xc8, 0x09, 0xde, 0x74, 0x71, 0x9e, 0xf3, 0x33, 0x31, 0x6a, 0x35, 0xad, + 0x7c, 0xdd, 0xea, 0xa3, 0x79, 0x54, 0x4f, 0xdb, 0x1b, 0x15, 0x41, 0xb0, 0xf9, 0xf6, 0x07, 0xfd, + 0xe7, 0xcb, 0xe2, 0x24, 0x4f, 0xf1, 0x53, 0x0f, 0x0a, 0xd8, 0xc1, 0xdf, 0xdc, 0x0f, 0x47, 0x2a, + 0x18, 0x0d, 0x2b, 0x0b, 0x78, 0x34, 0x82, 0x11, 0xd7, 0x4d, 0x35, 0x03, 0xeb, 0xce, 0x70, 0x1a, + 0xf5, 0xfd, 0x70, 0x71, 0xf5, 0x2e, 0x3c, 0x3c, 0x3f, 0x03, 0xc3, 0xc3, 0xe1, 0xf0, 0xf8, 0x1d, + 0x6c, 0x9d, 0x2b, 0x22, 0x3c, 0x18, 0x0d, 0x2a, 0x8c, 0xe8, 0x06, 0x16, 0xd6, 0x9c, 0x15, 0x40, + 0x16, 0x06, 0xad, 0xea, 0x9d, 0x0b, 0x8a, 0x83, 0xf3, 0x83, 0xf0, 0x7e, 0x30, 0x7c, 0x0e, 0xc3, + 0xfc, 0xa0, 0x37, 0x47, 0x71, 0x3a, 0x15, 0x01, 0x05, 0xc2, 0x3f, 0x59, 0xce, 0x7c, 0x6c, 0x44, + 0xf7, 0x52, 0xb7, 0x2b, 0x89, 0x80, 0x09, 0x61, 0xd7, 0x77, 0x57, 0x63, 0x87, 0x7b, 0x88, 0xc8, + 0xa5, 0x72, 0xed, 0x94, 0x0c, 0x84, 0x47, 0xdc, 0xc7, 0x89, 0x7d, 0xef, 0x8d, 0x2a, 0xf4, 0x06, + 0xbd, 0x21, 0x6e, 0x3c, 0x50, 0x9b, 0xcc, 0x01, 0x93, 0xa0, 0xac, 0x4a, 0x38, 0xb6, 0x58, 0xdd, + 0x62, 0x84, 0x87, 0x22, 0x90, 0xb1, 0xa6, 0xa9, 0x91, 0xaf, 0xd8, 0x90, 0xcc, 0x0b, 0xb1, 0x20, + 0xf0, 0xe1, 0x86, 0x66, 0x1c, 0x3c, 0x78, 0xe1, 0x1e, 0x76, 0xd8, 0xf5, 0xe4, 0x57, 0xbd, 0xee, + 0xe6, 0x9f, 0x95, 0x13, 0x10, 0x35, 0xcb, 0x1e, 0x84, 0x14, 0x69, 0x8c, 0x06, 0xa6, 0x7c, 0x3e, + 0x0f, 0xc0, 0xfc, 0x0f, 0xc0, 0xfc, 0x0e, 0x05, 0x1c, 0xa0, 0x37, 0x47, 0x71, 0x2a, 0x64, 0xc9, + 0x05, 0xc2, 0x2d, 0xbf, 0x94, 0x18, 0x2b, 0x9e, 0x1e, 0xff, 0x82, 0x28, 0x5f, 0x6c, 0x46, 0x76, + 0x50, 0x29, 0x5e, 0x59, 0x73, 0xfd, 0x6b, 0x8e, 0x64, 0x33, 0xf6, 0xf6, 0x84, 0x2e, 0x95, 0xba, + 0xb2, 0x8d, 0x72, 0xbb, 0x17, 0x71, 0x91, 0x96, 0xae, 0xab, 0x89, 0xa5, 0xa4, 0xad, 0xaa, 0x48, + 0xe9, 0xdc, 0x69, 0xba, 0x16, 0x99, 0xde, 0x56, 0x69, 0x30, 0xfe, 0xe6, 0xab, 0x1c, 0xe4, 0x50, + 0x71, 0x75, 0x5d, 0xd3, 0x09, 0xa2, 0x13, 0xdc, 0x67, 0x3c, 0x3e, 0x3c, 0x3c, 0x3c, 0x1e, 0x1e, + 0x1d, 0xe7, 0x09, 0x3a, 0x24, 0x66, 0xe1, 0xbe, 0x1b, 0x4f, 0x2a, 0xd3, 0x0b, 0xed, 0xd4, 0xbf, + 0x54, 0xf5, 0x4e, 0x5b, 0x71, 0x7a, 0xe8, 0x0f, 0x07, 0xe0, 0x3e, 0x0f, 0x81, 0xe1, 0xf0, 0x06, + 0x1c, 0xa0, 0x37, 0x47, 0x71, 0x2a, 0x24, 0xd9, 0x19, 0xa1, 0x2c, 0x66, 0x90, 0xb6, 0x0a, 0x0d, + 0x39, 0xb6, 0x11, 0x69, 0x65, 0x6e, 0x92, 0x1c, 0x0d, 0xaf, 0x1a, 0x82, 0x29, 0x7f, 0xbb, 0x9c, + 0x8b, 0x12, 0x8b, 0x66, 0x8d, 0xd7, 0x61, 0xad, 0xa1, 0x5c, 0x47, 0x2d, 0x62, 0x01, 0x0f, 0xe3, + 0xb6, 0xdd, 0x68, 0xee, 0x2b, 0x8c, 0xed, 0xf9, 0xea, 0x43, 0x61, 0x65, 0x57, 0xa3, 0xfd, 0xd9, + 0xcb, 0x10, 0xf9, 0x3a, 0xcc, 0x87, 0x09, 0x8f, 0x10, 0xfe, 0xb1, 0x7f, 0x4f, 0xa2, 0xc7, 0xfc, + 0x1c, 0x38, 0x7e, 0x07, 0xe0, 0x7e, 0x07, 0xe0, 0x3f, 0x81, 0x7e, 0x3f, 0xd1, 0xee, 0xb8, 0xad, + 0xf8, 0x0f, 0x28, 0x0f, 0x58, 0x84, 0x12, 0xac, 0x21, 0x96, 0x78, 0x7a, 0xbb, 0x76, 0x06, 0x26, + 0x38, 0x63, 0x3b, 0xc0, 0xe4, 0x1c, 0x0e, 0xc5, 0xfc, 0xa0, 0x0e, 0x47, 0x71, 0x3a, 0x46, 0x29, + 0x00, 0x00, 0x0f, 0x6f, 0xb2, 0x94, 0x5d, 0x10, 0x2f, 0xca, 0x99, 0xc5, 0xc6, 0x84, 0xa9, 0xd4, + 0xe0, 0x81, 0x3e, 0xbf, 0x51, 0x7a, 0x44, 0xdb, 0xc4, 0xf9, 0x33, 0xa3, 0x59, 0xae, 0x80, 0x5b, + 0x47, 0xee, 0x2d, 0xe4, 0xf8, 0xec, 0xcf, 0x46, 0xc5, 0x9f, 0xb2, 0xa4, 0xb2, 0x11, 0xee, 0xaf, + 0x77, 0xbe, 0x76, 0xf4, 0xac, 0xd8, 0x28, 0xe9, 0xf3, 0x5b, 0x93, 0x59, 0x1f, 0xb5, 0x29, 0xf6, + 0xb7, 0xe5, 0xc5, 0x6f, 0xa2, 0x51, 0xe1, 0xf8, 0x7e, 0x0f, 0xc0, 0x7e, 0x07, 0xe0, 0x7c, 0x38, + 0x1d, 0xeb, 0xc8, 0xea, 0xc6, 0x3e, 0x6b, 0xa1, 0xac, 0xfa, 0xdf, 0xa8, 0xf8, 0xc2, 0x6f, 0x1d, + 0x39, 0xa2, 0x89, 0x2a, 0xb0, 0x6b, 0x2e, 0x3d, 0x40, 0x7c, 0x0f, 0xe0, 0x7c, 0x1f, 0x98, 0x07, + 0x1a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x04, 0x79, 0x04, 0x80, 0xfc, 0x37, 0x46, 0x6c, 0xbf, 0xeb, + 0x78, 0xa1, 0xbc, 0x1e, 0x54, 0x0c, 0x33, 0x62, 0x9f, 0x55, 0x6e, 0x5b, 0x00, 0xb2, 0x38, 0x41, + 0x97, 0x66, 0xc6, 0x45, 0x8b, 0xa7, 0x2c, 0xb9, 0xe7, 0x90, 0x7f, 0x40, 0x99, 0x1a, 0x55, 0x84, + 0xc9, 0x0b, 0x80, 0xe8, 0xea, 0xe0, 0x5d, 0x84, 0xc0, 0x56, 0x70, 0xb8, 0x1b, 0x23, 0x82, 0xe7, + 0xff, 0x70, 0xe6, 0x3c, 0xef, 0xb8, 0x9c, 0x87, 0x7b, 0x35, 0xc9, 0x38, 0xd0, 0xec, 0xeb, 0x0f, + 0x0f, 0xc1, 0xf0, 0x3f, 0x03, 0xf0, 0x78, 0xf8, 0xe2, 0xe2, 0x14, 0x96, 0xc0, 0x57, 0x68, 0x89, + 0x74, 0xb7, 0xc1, 0xb2, 0xd6, 0xa9, 0x7e, 0x26, 0xde, 0x28, 0xf0, 0x13, 0xce, 0x07, 0x0f, 0xc3, + 0xe0, 0x7e, 0x07, 0xe0, 0x7e, 0x07, 0xc2, 0x08, 0x1a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x05, 0x21, + 0x00, 0x00, 0x60, 0xee, 0x8d, 0x54, 0xb8, 0xbc, 0x11, 0xe4, 0x59, 0xa0, 0xac, 0xee, 0x13, 0x3d, + 0x28, 0xb3, 0xa0, 0x3b, 0x69, 0x42, 0xe1, 0xb9, 0xe0, 0x71, 0xdf, 0x4f, 0x17, 0xfc, 0x0c, 0xd5, + 0x79, 0x28, 0x28, 0xfe, 0x04, 0xf9, 0x79, 0xa7, 0x6f, 0xea, 0x6f, 0xdd, 0x6a, 0x46, 0x72, 0xc4, + 0x13, 0x8c, 0x1e, 0x91, 0x34, 0x09, 0xc3, 0xb1, 0x61, 0x48, 0xbc, 0xe6, 0x1c, 0x69, 0x51, 0xff, + 0xd2, 0xb7, 0xf5, 0xc4, 0x0c, 0x21, 0x98, 0x7c, 0x0f, 0x83, 0xc0, 0xfc, 0x0f, 0x87, 0xc7, 0xe8, + 0xec, 0x7e, 0x23, 0xa1, 0x7d, 0x07, 0x0c, 0x40, 0xbf, 0x0c, 0x50, 0xf4, 0x95, 0xce, 0xe2, 0x97, + 0x1a, 0x49, 0x1b, 0x38, 0x14, 0xc0, 0x4b, 0x37, 0xe0, 0xfc, 0x0f, 0x81, 0xf0, 0x78, 0xf0, 0x09, + 0x1a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x14, 0xf9, 0x00, 0x00, 0x62, 0x61, 0xf7, 0x2f, 0x30, 0xbc, + 0x28, 0xbc, 0x28, 0x65, 0x7a, 0x47, 0xd7, 0x8f, 0x22, 0xf4, 0xb5, 0x5f, 0x97, 0xcf, 0x28, 0x51, + 0x42, 0x1f, 0x9b, 0x83, 0x7e, 0x50, 0xbb, 0xf0, 0x6d, 0x6a, 0x62, 0x59, 0x3d, 0x99, 0x05, 0x14, + 0xeb, 0x3a, 0xb1, 0x88, 0xf8, 0xdb, 0x8b, 0x3e, 0xb1, 0x24, 0x58, 0xd6, 0x1f, 0xd0, 0x56, 0xa1, + 0x8c, 0x7a, 0x37, 0xd4, 0x03, 0xd8, 0x0e, 0x9d, 0x8b, 0xe2, 0xf1, 0x53, 0x90, 0x31, 0x87, 0x87, + 0xc1, 0xf0, 0x7c, 0x07, 0xe0, 0x7e, 0x07, 0x86, 0x06, 0xfb, 0x6d, 0xf6, 0x0b, 0x19, 0x9c, 0x5a, + 0x65, 0xfb, 0x3c, 0xf5, 0xd8, 0x15, 0xa1, 0xc3, 0xbd, 0x01, 0x8d, 0x64, 0xd1, 0x51, 0xaf, 0xc3, + 0xf0, 0x3f, 0x81, 0xf8, 0x1f, 0x87, 0xe0, 0x0a, 0x1a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x44, 0x59, + 0x05, 0xc0, 0x9d, 0xa7, 0x4c, 0x88, 0x55, 0x01, 0xc8, 0x85, 0xaa, 0xbb, 0x7c, 0xb5, 0x2c, 0x5d, + 0xce, 0x53, 0x94, 0x4f, 0x0d, 0xa6, 0x09, 0x22, 0x42, 0x9e, 0xef, 0xff, 0xfb, 0xcb, 0x4f, 0xa2, + 0xe8, 0xc7, 0xc9, 0x5c, 0xa1, 0x27, 0x9f, 0xfc, 0x47, 0xcb, 0x4d, 0x52, 0xfe, 0x6d, 0x37, 0xc9, + 0x55, 0x15, 0xba, 0xb4, 0xf4, 0xf0, 0xc8, 0xef, 0x07, 0x52, 0xc6, 0xe9, 0x3f, 0xcc, 0xf4, 0xff, + 0x99, 0x32, 0x60, 0x89, 0x07, 0x4d, 0xe3, 0x1e, 0x07, 0x81, 0xf8, 0x1f, 0x07, 0x8f, 0xc1, 0x19, + 0x10, 0x21, 0x44, 0x9a, 0x82, 0x82, 0xb8, 0x65, 0x94, 0xc8, 0x13, 0x9d, 0x8e, 0xdd, 0x32, 0xc4, + 0xd2, 0x4c, 0xa9, 0xc2, 0xa0, 0x43, 0xe1, 0xf8, 0x0f, 0xc0, 0xfc, 0x0f, 0xc0, 0x7e, 0x06, 0x0b, + 0x1a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x24, 0x71, 0x05, 0xc0, 0x29, 0x32, 0x84, 0x40, 0x4b, 0xb4, + 0xb8, 0xf8, 0xd6, 0xa6, 0xec, 0x18, 0xb0, 0xaa, 0x08, 0xbf, 0x29, 0x3f, 0x51, 0xbe, 0xe3, 0x8c, + 0x18, 0xb9, 0x76, 0xe0, 0xe8, 0x18, 0x4d, 0x1f, 0x99, 0x41, 0x25, 0x1c, 0x65, 0x5c, 0x2c, 0x0e, + 0x44, 0x04, 0x9f, 0x4d, 0x70, 0x89, 0x16, 0xf1, 0xe6, 0xc9, 0xc4, 0x51, 0x0a, 0x40, 0x90, 0x0a, + 0xa8, 0x00, 0x5f, 0x3a, 0xca, 0x1f, 0x42, 0xdc, 0x31, 0xd5, 0x47, 0x16, 0x1f, 0x8d, 0xcf, 0x0f, + 0x07, 0x81, 0xf0, 0x3e, 0x07, 0xe0, 0x78, 0x78, 0x89, 0x16, 0xf6, 0xbb, 0x98, 0x92, 0x3d, 0x56, + 0xa6, 0xb5, 0xff, 0x76, 0x03, 0x89, 0x04, 0xcf, 0x1e, 0xfc, 0x72, 0x3b, 0x80, 0x54, 0xf8, 0x7c, + 0x07, 0xf0, 0x3f, 0x03, 0xf0, 0x3f, 0x06, 0x0c, 0x0a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x34, 0xd9, + 0x00, 0x00, 0x17, 0xa1, 0xff, 0x37, 0x32, 0x54, 0xf2, 0x35, 0xaa, 0xbc, 0x3d, 0x44, 0x8c, 0x73, + 0xeb, 0xa4, 0x59, 0x99, 0xa1, 0xcf, 0x35, 0x8b, 0x40, 0xc4, 0xb5, 0x6c, 0xa2, 0x1f, 0x25, 0x4e, + 0x8f, 0x2f, 0xca, 0x57, 0x8c, 0x06, 0xae, 0xce, 0xcc, 0x52, 0x45, 0x6b, 0x6b, 0xe6, 0x72, 0x66, + 0x4d, 0x58, 0x5d, 0x70, 0xb4, 0x7c, 0xbf, 0xeb, 0x84, 0x5e, 0x17, 0x42, 0x4a, 0x37, 0x1a, 0x27, + 0x66, 0x74, 0x80, 0xf2, 0x2f, 0x53, 0xb7, 0x06, 0x79, 0xc3, 0xc1, 0xf0, 0x3e, 0x0f, 0xc0, 0xf8, + 0x3f, 0x0e, 0x1e, 0xfb, 0xa4, 0x49, 0xea, 0x48, 0x10, 0x32, 0x23, 0x18, 0xd7, 0xa7, 0x29, 0xb3, + 0x7c, 0xf1, 0xc4, 0xab, 0x9c, 0xdb, 0xcf, 0x9c, 0x1e, 0x0f, 0xc0, 0xfc, 0x0f, 0x83, 0x82, 0x0e, + 0x0a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x34, 0xd9, 0x05, 0xc0, 0x28, 0xf5, 0x8d, 0xd8, 0x07, 0x04, + 0xd3, 0x2e, 0x17, 0x79, 0x42, 0x9b, 0x5b, 0x69, 0x9b, 0xb8, 0xee, 0xe0, 0x97, 0xdb, 0x2a, 0x6b, + 0x94, 0xbe, 0xca, 0x5d, 0x74, 0x7a, 0x45, 0x21, 0xc5, 0x46, 0x9c, 0x7a, 0x6f, 0x80, 0xf6, 0x6c, + 0x26, 0xcb, 0xa9, 0xee, 0x25, 0xd1, 0xd5, 0x23, 0xb5, 0x01, 0x13, 0xae, 0x47, 0xb3, 0xb7, 0x76, + 0x88, 0x52, 0x40, 0x18, 0xa4, 0xf9, 0xa1, 0x11, 0xc1, 0x39, 0xed, 0x9f, 0xf6, 0x33, 0xc7, 0x87, + 0x80, 0xfc, 0x1f, 0x81, 0xf8, 0x1f, 0x0f, 0x0f, 0xf7, 0xbf, 0x33, 0xec, 0xe9, 0x9f, 0x66, 0x64, + 0xd1, 0xe7, 0xe5, 0xd3, 0x27, 0x20, 0x57, 0xe2, 0x08, 0x36, 0x1d, 0xaa, 0x4d, 0x4e, 0x60, 0xf0, + 0x7e, 0x07, 0xe0, 0x7e, 0x07, 0xc0, 0xf8, 0x0f, 0x0a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x34, 0x99, + 0x05, 0xc2, 0x3c, 0xe5, 0x45, 0xc1, 0x14, 0xf5, 0x9f, 0x92, 0x87, 0x2b, 0x4f, 0x8f, 0x46, 0xf7, + 0x90, 0x7f, 0x33, 0x60, 0xf1, 0xa6, 0xbc, 0xd0, 0x0e, 0xbb, 0x47, 0xdb, 0xbe, 0xb2, 0xe5, 0x2a, + 0x2c, 0x90, 0xc3, 0x1f, 0x2c, 0xa6, 0xbd, 0x4f, 0x10, 0x7a, 0x4f, 0x0e, 0xe6, 0xdc, 0xfa, 0xef, + 0x51, 0x99, 0xeb, 0x94, 0x13, 0x73, 0xaa, 0xdc, 0x4c, 0xc9, 0xa7, 0x35, 0x7d, 0xd7, 0x00, 0x00, + 0x02, 0x65, 0xd2, 0x97, 0xea, 0x16, 0x68, 0x32, 0x97, 0x29, 0xe1, 0xf1, 0xf0, 0x7c, 0x3c, 0x1e, + 0x28, 0xf8, 0x3f, 0x2a, 0x64, 0xb1, 0x82, 0xe4, 0x95, 0xab, 0xb6, 0xb8, 0xcb, 0x1c, 0xba, 0x03, + 0x6e, 0x9d, 0xf4, 0x0b, 0x15, 0xa8, 0x63, 0xf0, 0x3f, 0x80, 0xfc, 0x0f, 0xc0, 0xfc, 0x0e, 0x11, + 0x0a, 0x28, 0x8c, 0x57, 0x71, 0x2a, 0x66, 0x29, 0x00, 0x00, 0x20, 0x84, 0xdc, 0x03, 0x04, 0xeb, + 0x4f, 0xb6, 0x88, 0x4a, 0xe0, 0x3f, 0x33, 0x8e, 0xdc, 0x7d, 0x6f, 0xee, 0xf6, 0x84, 0xeb, 0xbf, + 0x91, 0x69, 0x4b, 0xce, 0x33, 0xfb, 0x0a, 0x66, 0x8e, 0x79, 0xd6, 0x11, 0x63, 0x25, 0x95, 0xcd, + 0x58, 0x73, 0x02, 0xa7, 0xb6, 0x01, 0x06, 0xc4, 0xd3, 0xfa, 0xbf, 0x4c, 0xc1, 0xc3, 0xb6, 0xd3, + 0xc4, 0x33, 0x99, 0x3f, 0xb1, 0x72, 0xe8, 0xd1, 0xed, 0xd5, 0xad, 0x20, 0x95, 0x84, 0x9c, 0x39, + 0xf0, 0x7e, 0x07, 0xe0, 0x7f, 0x07, 0xe0, 0xf0, 0x7e, 0x9b, 0xb9, 0x9d, 0x29, 0xca, 0x3b, 0x35, + 0xd9, 0xc6, 0x3a, 0xf0, 0x09, 0x69, 0xcd, 0xbd, 0xd6, 0xda, 0xf0, 0x91, 0x3d, 0xcd, 0xb3, 0x73, + 0x81, 0xe0, 0x7e, 0x07, 0xe0, 0x7c, 0x4c, 0x12, 0x0a, 0x68, 0xcf, 0xf7, 0x71, 0x2a, 0x04, 0xf1, + 0x07, 0x82, 0x14, 0xfc, 0x2b, 0x0d, 0x9f, 0xbe, 0xb2, 0xbe, 0x70, 0x4e, 0x05, 0x14, 0x2f, 0x36, + 0xc4, 0x7a, 0x3e, 0xe7, 0xd9, 0xf8, 0x64, 0xde, 0xce, 0x4a, 0x9c, 0x6a, 0xbd, 0xd1, 0x46, 0x78, + 0x18, 0x7a, 0xd8, 0x4c, 0x5f, 0x4d, 0x16, 0xfe, 0xca, 0xee, 0x57, 0x0d, 0x32, 0x27, 0xe9, 0x70, + 0x3b, 0x6a, 0xb4, 0xce, 0xc5, 0x67, 0x35, 0x00, 0xbf, 0x31, 0x34, 0xb6, 0xf1, 0xff, 0x92, 0x83, + 0x10, 0x69, 0x98, 0x04, 0xed, 0x5c, 0x3e, 0x1f, 0x83, 0xf0, 0x7e, 0x07, 0xc1, 0xe1, 0xf7, 0x01, + 0x89, 0x86, 0x9a, 0xec, 0x1a, 0xcc, 0x2a, 0xa6, 0xdf, 0x0a, 0x77, 0x4d, 0x19, 0x7b, 0xdf, 0xd0, + 0xdd, 0xf3, 0xbd, 0x78, 0x71, 0x87, 0x07, 0xe0, 0x3f, 0x03, 0xf0, 0x1f, 0x81, 0xfc, 0x0e, 0x14, + 0x0a, 0x68, 0xcf, 0xf7, 0x71, 0x2a, 0x33, 0xc1, 0x07, 0x82, 0x13, 0x5b, 0xf5, 0x2d, 0xee, 0xfd, + 0x7f, 0xfb, 0x76, 0x44, 0x85, 0x6c, 0xdd, 0x4c, 0xa6, 0x95, 0xa9, 0x01, 0x31, 0x90, 0x49, 0xc4, + 0x3d, 0x4b, 0x96, 0xce, 0x4b, 0x00, 0xc9, 0x69, 0x94, 0xca, 0xd2, 0x72, 0xc6, 0xe5, 0xa5, 0x12, + 0x69, 0x52, 0x37, 0x74, 0x64, 0x8f, 0x89, 0x5a, 0x1e, 0x97, 0x9a, 0x00, 0x55, 0x45, 0x78, 0x0a, + 0x72, 0xff, 0x94, 0x26, 0x4e, 0xcd, 0x20, 0x36, 0xb5, 0x7f, 0x77, 0x3a, 0x3d, 0x38, 0x4a, 0x75, + 0x2e, 0x7c, 0x3e, 0x07, 0xc1, 0xf0, 0x78, 0x71, 0xc0, 0xa6, 0x75, 0x7f, 0xe9, 0x8a, 0x8b, 0xd1, + 0x33, 0x41, 0x0d, 0xcc, 0xd1, 0x18, 0x5d, 0x23, 0x57, 0x1b, 0x09, 0x38, 0x8c, 0x1f, 0x9c, 0x0f, + 0xc0, 0x7e, 0x07, 0xf0, 0x3f, 0x03, 0xf0, 0x16, 0x0a, 0x28, 0x8c, 0x57, 0x71, 0x2a, 0x56, 0x11, + 0x05, 0xc0, 0x9b, 0x63, 0x39, 0x73, 0x53, 0x95, 0x15, 0xe7, 0x15, 0xe0, 0x44, 0x4d, 0x15, 0xbf, + 0xde, 0x98, 0x1a, 0x4b, 0xb0, 0x85, 0x5f, 0x68, 0xb2, 0x5b, 0x4d, 0x6a, 0x3d, 0x83, 0xd4, 0xd4, + 0xe4, 0xd8, 0x47, 0x67, 0x80, 0x3b, 0xe3, 0xad, 0xfe, 0x78, 0xba, 0x10, 0x3c, 0x9f, 0x82, 0x30, + 0xf6, 0x8a, 0xbc, 0x1b, 0xf6, 0xab, 0x50, 0x0a, 0x6a, 0x96, 0xf5, 0x29, 0x24, 0xde, 0x06, 0x3b, + 0xf7, 0x9f, 0x93, 0xcf, 0x66, 0x29, 0xec, 0x7c, 0x3c, 0x0f, 0xc0, 0xfc, 0x1f, 0x0f, 0x91, 0xc3, + 0x1f, 0xad, 0x34, 0xc0, 0x86, 0xc4, 0x44, 0xcb, 0xae, 0xc7, 0x9d, 0xc9, 0x21, 0xf0, 0xa1, 0x6b, + 0xb0, 0x94, 0x45, 0x63, 0x08, 0x8f, 0x9e, 0x07, 0xe0, 0x7e, 0x03, 0xe0, 0x7f, 0x01, 0xf8, 0x19, + 0x0a, 0x68, 0xcf, 0xf7, 0x71, 0x2a, 0x34, 0x51, 0x00, 0x00, 0x00, 0x37, 0x6e, 0x5c, 0x01, 0x8c, + 0x3f, 0xff, 0x62, 0x2d, 0x0d, 0x9e, 0x43, 0x75, 0x69, 0xb0, 0x78, 0x55, 0x7e, 0x0f, 0x78, 0x26, + 0x7c, 0xd5, 0xb4, 0x5c, 0x1a, 0x30, 0x27, 0x9d, 0x48, 0x73, 0x70, 0x77, 0x0f, 0xf5, 0x30, 0x53, + 0xbc, 0x63, 0x38, 0x99, 0x77, 0x69, 0x3d, 0xd1, 0xa6, 0xad, 0x22, 0xf7, 0xc2, 0x6b, 0x53, 0x45, + 0xe5, 0x19, 0x13, 0x44, 0x4f, 0x02, 0x32, 0xfd, 0x03, 0x6f, 0x29, 0xac, 0x78, 0xae, 0x20, 0x62, + 0x9c, 0xf8, 0x3e, 0x0f, 0x81, 0xf8, 0x3f, 0x07, 0xc7, 0x07, 0x5d, 0x8f, 0x14, 0x34, 0xdc, 0xee, + 0xd5, 0xd4, 0x64, 0xbd, 0x7f, 0x9d, 0x45, 0x5f, 0xa1, 0x9c, 0xa3, 0x05, 0xe9, 0x23, 0xa2, 0x05, + 0x1b, 0x38, 0x7e, 0x07, 0xe0, 0x7c, 0x0c, 0x1b, 0x0a, 0x28, 0x8c, 0x57, 0x71, 0x2a, 0x36, 0x39, + 0x05, 0xc2, 0x2d, 0xb6, 0x06, 0x49, 0x18, 0xb9, 0xe1, 0x64, 0xf4, 0x2a, 0x15, 0xeb, 0xac, 0x33, + 0xea, 0xcb, 0x6d, 0x69, 0x4f, 0x5c, 0x10, 0x44, 0xbd, 0x31, 0xce, 0x3c, 0xba, 0xb9, 0xf0, 0x83, + 0x0b, 0x3e, 0x14, 0x7a, 0x56, 0x51, 0x5e, 0xcb, 0x95, 0x39, 0x71, 0xed, 0xd3, 0x33, 0x9a, 0x4d, + 0xa3, 0x8b, 0x9b, 0xcd, 0x16, 0xa3, 0x25, 0xae, 0x6c, 0x9f, 0x00, 0x00, 0x00, 0x91, 0xba, 0xd0, + 0x02, 0x44, 0x89, 0xfa, 0xbf, 0xa2, 0xf1, 0x11, 0x1d, 0x4e, 0x0f, 0x81, 0xf8, 0x1f, 0x03, 0xe1, + 0xe1, 0x35, 0x2d, 0x5d, 0x61, 0xc5, 0x78, 0xe4, 0xea, 0x5c, 0x86, 0x9b, 0x8e, 0x92, 0x54, 0xce, + 0x63, 0x30, 0xc1, 0xce, 0xd1, 0x4f, 0x87, 0xc1, 0xf0, 0x3f, 0x03, 0xf0, 0x3f, 0x81, 0xf0, 0x1f, + 0x0a, 0x70, 0xbc, 0x77, 0x71, 0x2a, 0x56, 0x11, 0x00, 0x00, 0x02, 0x46, 0x64, 0x63, 0x12, 0xa4, + 0x19, 0xda, 0x38, 0xd9, 0x99, 0xf8, 0xc7, 0xd6, 0x5a, 0xaf, 0x79, 0x14, 0x40, 0xbf, 0xda, 0xcc, + 0x59, 0xed, 0xff, 0xc4, 0x6e, 0x25, 0xa8, 0x83, 0x2f, 0x91, 0xbf, 0xf4, 0xb5, 0x60, 0x1f, 0x44, + 0x1c, 0x53, 0x27, 0x71, 0x4c, 0x3a, 0x84, 0x6d, 0x59, 0xfd, 0x68, 0x72, 0x16, 0x24, 0xc8, 0x22, + 0x04, 0xfd, 0x9d, 0xc3, 0x00, 0x0f, 0xc3, 0x4f, 0xf6, 0x9b, 0x99, 0x66, 0xe5, 0xe8, 0x9c, 0x13, + 0x63, 0x83, 0xe0, 0xf8, 0x1f, 0x81, 0xf0, 0x7e, 0x1c, 0x00, 0xdc, 0x6e, 0x2b, 0xe7, 0x9b, 0xa9, + 0xaa, 0x33, 0xb6, 0x37, 0xea, 0xdc, 0x11, 0xbb, 0xf4, 0xeb, 0x30, 0xd2, 0xf1, 0x65, 0x11, 0x5b, + 0xf0, 0xf8, 0x3e, 0x07, 0x83, 0xc7, 0xe0, 0x22, 0x0a, 0x70, 0xbc, 0x77, 0x71, 0x2a, 0x46, 0x31, + 0x00, 0x00, 0x00, 0x05, 0xc7, 0x20, 0x0c, 0x68, 0x5d, 0xb4, 0xd7, 0x65, 0xe2, 0x7e, 0x64, 0x69, + 0xc0, 0x79, 0x17, 0x8c, 0x04, 0xa0, 0xcd, 0xc7, 0x6c, 0x20, 0x96, 0x7c, 0x1a, 0x70, 0x8c, 0xdc, + 0x26, 0x89, 0x28, 0xfa, 0xca, 0x49, 0x17, 0xe8, 0x28, 0xa2, 0x5f, 0xa2, 0xfb, 0xd5, 0xc1, 0x91, + 0x6a, 0x18, 0x89, 0xe7, 0x92, 0x05, 0x50, 0x0f, 0xef, 0x5a, 0x5a, 0xdd, 0x0f, 0x6b, 0x9a, 0xd7, + 0x27, 0x98, 0x13, 0x4f, 0x94, 0x5e, 0xe4, 0xd0, 0xf0, 0xf0, 0xfc, 0x0f, 0xc1, 0xf8, 0x1f, 0x81, + 0xf0, 0x78, 0x7c, 0x93, 0x14, 0x0e, 0x50, 0xbd, 0x13, 0x0f, 0x7f, 0x25, 0x3c, 0x11, 0x04, 0x81, + 0x1c, 0x7f, 0xe7, 0x25, 0x7d, 0xe6, 0xe3, 0x8c, 0x61, 0x27, 0xc1, 0xf8, 0x3c, 0x70, 0xf0, 0x26, + 0x0a, 0x6f, 0x43, 0x77, 0x71, 0x2a, 0x25, 0x19, 0x05, 0xc0, 0x26, 0x36, 0xf3, 0x8a, 0xec, 0x1c, + 0xd5, 0x9c, 0x29, 0xf5, 0xb1, 0xb9, 0xc8, 0xb0, 0x3b, 0xa8, 0xc3, 0xe3, 0x2d, 0xca, 0x7b, 0x90, + 0xe6, 0x7d, 0x9a, 0xa6, 0x40, 0xd2, 0xd8, 0xda, 0x56, 0xf7, 0xfe, 0x56, 0xad, 0xfc, 0x3b, 0xae, + 0xd3, 0x95, 0x6d, 0xba, 0xde, 0x8c, 0x0b, 0x76, 0x9d, 0xe7, 0x56, 0xe3, 0x97, 0x14, 0x2c, 0x3c, + 0xb8, 0xa7, 0x7c, 0x9e, 0x00, 0xfc, 0x43, 0xaa, 0xed, 0x58, 0x9b, 0xc5, 0xf2, 0x01, 0xd6, 0x3c, + 0x7c, 0x1f, 0x03, 0xe0, 0x7e, 0x07, 0x87, 0x87, 0x86, 0x3c, 0xd1, 0xf4, 0xb5, 0x4a, 0x29, 0x93, + 0xad, 0x53, 0x30, 0x85, 0x95, 0x26, 0x4f, 0x45, 0xb5, 0xc3, 0x51, 0x31, 0xa5, 0x7a, 0x18, 0xc1, + 0xf0, 0x7e, 0x07, 0xe1, 0xf0, 0x3c, 0x06, 0x0e, 0x0a, 0xde, 0x40, 0xa7, 0x71, 0x2a, 0x24, 0x71, + 0x0d, 0xc1, 0xee, 0xba, 0xbd, 0x82, 0x50, 0xa0, 0x25, 0x0a, 0xed, 0x97, 0xce, 0x60, 0x2d, 0xf9, + 0xa6, 0x97, 0x2f, 0xe8, 0x05, 0xda, 0x37, 0x2b, 0x0e, 0xd5, 0x67, 0x48, 0x29, 0xb1, 0x94, 0x6f, + 0x1a, 0x31, 0xb4, 0x72, 0xba, 0xeb, 0x59, 0x91, 0xb7, 0xbc, 0x5e, 0xeb, 0xb1, 0xae, 0xa8, 0xd5, + 0x1c, 0xf8, 0x47, 0x27, 0x9c, 0x73, 0xb9, 0x80, 0xc9, 0xcd, 0x77, 0x0a, 0x99, 0x00, 0xa9, 0x04, + 0x4f, 0xe6, 0xb3, 0x10, 0x46, 0x70, 0xf0, 0x7e, 0x07, 0xe0, 0xfc, 0x1e, 0x0e, 0x3c, 0x26, 0x00, + 0xa0, 0xe7, 0x02, 0x0e, 0x19, 0x0b, 0x90, 0xa8, 0xbb, 0x24, 0x11, 0xb4, 0x13, 0xe2, 0x6d, 0xb9, + 0xec, 0x1f, 0x38, 0xd7, 0x64, 0xf0, 0x7e, 0x03, 0xf8, 0x1f, 0x81, 0xf8, 0x1f, 0x83, 0xf0, 0x11, + 0x0a, 0xde, 0x40, 0xa7, 0x71, 0x2a, 0x44, 0x31, 0x00, 0x00, 0x00, 0x5c, 0x89, 0x73, 0x30, 0x0e, + 0xb1, 0x92, 0xb9, 0x1e, 0xb0, 0x56, 0x34, 0x72, 0x4f, 0x7d, 0x1b, 0xca, 0x05, 0x95, 0xd5, 0xc5, + 0x98, 0xee, 0x37, 0x97, 0xa8, 0xfb, 0xb8, 0x61, 0xb1, 0x99, 0x00, 0x90, 0x96, 0xee, 0x1a, 0x6a, + 0x24, 0x6e, 0xeb, 0x9f, 0x53, 0xdc, 0x09, 0xaa, 0xfb, 0xc3, 0x8d, 0x1d, 0xa1, 0xee, 0x48, 0x97, + 0x60, 0xd2, 0xdd, 0x3c, 0x7f, 0xf4, 0xee, 0x11, 0x12, 0x9c, 0xdc, 0xa6, 0xba, 0x61, 0xc3, 0xe0, + 0x7e, 0x0f, 0xc0, 0xfc, 0x0f, 0x81, 0xe0, 0x99, 0x7d, 0xa2, 0xcc, 0x85, 0x43, 0xc5, 0xe5, 0xd6, + 0x64, 0xb5, 0x78, 0x70, 0xd0, 0xe9, 0x70, 0xe6, 0x75, 0x84, 0x3f, 0x0a, 0x7c, 0x86, 0x39, 0x88, + 0x88, 0x7f, 0x03, 0xe0, 0xf8, 0xf8, 0xf2, 0x15, 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x2a, 0x04, 0xb9, + 0x05, 0xc2, 0x71, 0x5c, 0x02, 0x99, 0xdc, 0x5e, 0xb9, 0x6c, 0x6f, 0xdf, 0x52, 0x9e, 0x2d, 0x5b, + 0x67, 0x0e, 0xb4, 0x18, 0x43, 0x89, 0x6a, 0x8f, 0xa6, 0xe6, 0xbc, 0x96, 0xf0, 0x9f, 0x9d, 0x79, + 0x3d, 0x03, 0x25, 0xfe, 0x2b, 0xa3, 0xf9, 0xca, 0x64, 0x77, 0xe7, 0x2c, 0x96, 0x69, 0x99, 0xa6, + 0xbe, 0x13, 0xcb, 0xa2, 0x0a, 0x6f, 0xa1, 0xc7, 0x36, 0xcc, 0xae, 0xd1, 0xba, 0x39, 0x05, 0xd0, + 0x9c, 0x17, 0xa2, 0xec, 0xff, 0x1c, 0x3e, 0x1f, 0x03, 0xf0, 0x3f, 0x07, 0xc0, 0xf0, 0xeb, 0xd0, + 0x52, 0x02, 0xe5, 0x4b, 0x24, 0x82, 0x0e, 0x6f, 0x8b, 0x2a, 0x88, 0x86, 0xb2, 0xaf, 0x77, 0x56, + 0xc3, 0xaf, 0xbe, 0x54, 0x80, 0x4f, 0x81, 0xf0, 0x7e, 0x0f, 0xc1, 0xf8, 0x1f, 0x03, 0xf0, 0x19, + 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x2a, 0x23, 0xc9, 0x37, 0xe7, 0x14, 0xf3, 0xd2, 0xc0, 0xce, 0x02, + 0x93, 0x8f, 0x9b, 0x1a, 0x50, 0x5a, 0x47, 0x8c, 0xdc, 0x53, 0x4d, 0x5c, 0xb4, 0xb1, 0x18, 0x31, + 0x8b, 0xad, 0x6f, 0xe6, 0x94, 0xbf, 0x01, 0x34, 0x04, 0x61, 0x26, 0xd3, 0xe1, 0xdb, 0x07, 0xf9, + 0xfd, 0x7f, 0x33, 0xf4, 0x54, 0x09, 0xfa, 0x10, 0x08, 0x85, 0x92, 0xb6, 0xe1, 0x32, 0x49, 0x94, + 0xa8, 0xd2, 0xb9, 0x34, 0x33, 0x34, 0x18, 0x72, 0x56, 0xdd, 0x19, 0x80, 0x50, 0xc0, 0x9c, 0x3e, + 0x0f, 0x87, 0xe0, 0x7e, 0x03, 0xf8, 0x1c, 0x01, 0x4b, 0x4b, 0xe6, 0x6c, 0x9d, 0x29, 0x01, 0xf6, + 0x9c, 0x38, 0x1d, 0x4c, 0x42, 0xaf, 0x61, 0xda, 0x8a, 0xe2, 0x6f, 0xb4, 0x32, 0x38, 0x4a, 0x44, + 0x03, 0x1b, 0xc6, 0x33, 0x03, 0xbc, 0x0e, 0xc8, 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x39, 0xf4, 0x31, + 0x05, 0xc7, 0xf5, 0x2a, 0x9f, 0x0e, 0x68, 0x80, 0x79, 0xe7, 0x0f, 0xd5, 0x1c, 0xbc, 0x9a, 0x6d, + 0xd6, 0x2a, 0x2e, 0xc9, 0x11, 0x80, 0xc7, 0xba, 0x44, 0x31, 0x0e, 0xf3, 0x02, 0xe4, 0x5b, 0x80, + 0x77, 0x70, 0x52, 0x7e, 0x49, 0x7e, 0xa1, 0xad, 0xff, 0xbe, 0xa0, 0x1b, 0x3b, 0xf6, 0x72, 0x30, + 0x1d, 0xdd, 0x5b, 0xe8, 0x64, 0xd4, 0x65, 0x2e, 0x94, 0xa3, 0xae, 0xb2, 0x67, 0xff, 0x16, 0x70, + 0x52, 0xc5, 0x0c, 0x7f, 0x70, 0x78, 0x1f, 0x81, 0xf8, 0x0f, 0xe0, 0x7c, 0x3f, 0x00, 0x41, 0xc3, + 0x29, 0x1b, 0x12, 0xb0, 0xe8, 0xe8, 0x03, 0xa2, 0x09, 0x02, 0x2e, 0xa9, 0x2c, 0xa9, 0x81, 0x6a, + 0xce, 0xe1, 0xe2, 0x51, 0xd9, 0xfd, 0xc0, 0x7c, 0x0f, 0xc0, 0xf0, 0x7c, 0x1f, 0x0f, 0x0e, 0x0d, + 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x2a, 0x14, 0x21, 0xb0, 0xd1, 0xfe, 0x02, 0x0c, 0xb3, 0xb6, 0x83, + 0x75, 0x81, 0xa0, 0x4b, 0x9d, 0x3a, 0x23, 0x6f, 0x51, 0x41, 0x4d, 0x7f, 0x12, 0x44, 0xf4, 0x60, + 0x50, 0x45, 0x95, 0x2f, 0x88, 0x02, 0xda, 0x5f, 0x55, 0x46, 0xe4, 0xcd, 0x0d, 0x60, 0xd7, 0xd5, + 0x8e, 0x46, 0xc2, 0x3b, 0x89, 0xe0, 0x4b, 0xd0, 0xe4, 0x97, 0x98, 0x58, 0xae, 0x7a, 0xca, 0x3e, + 0x36, 0xc8, 0x83, 0x54, 0xd5, 0x46, 0x39, 0xc6, 0xd6, 0xca, 0x29, 0x4a, 0x4e, 0x58, 0xf1, 0xe0, + 0xfc, 0x07, 0xf0, 0x1f, 0x81, 0xf8, 0x0f, 0xc3, 0xfe, 0xb0, 0x8d, 0xff, 0xed, 0xd6, 0xf0, 0xe5, + 0xc7, 0x8e, 0x3d, 0x4a, 0xa6, 0xb3, 0xe9, 0x92, 0xa1, 0xd3, 0xc6, 0x95, 0x0b, 0x66, 0xcf, 0xa4, + 0x2b, 0xe0, 0x7d, 0xe4, 0xfb, 0x9a, 0x73, 0x12, 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x3a, 0x34, 0x51, + 0x69, 0xf1, 0xe5, 0x5c, 0x4a, 0x49, 0xd5, 0xe9, 0xe1, 0x77, 0xd2, 0xa7, 0x0f, 0xaa, 0x5a, 0x24, + 0xe2, 0x43, 0xa0, 0xa7, 0xdb, 0x58, 0xfe, 0xeb, 0xe8, 0x14, 0x7d, 0x48, 0xda, 0x99, 0x7a, 0x03, + 0x9b, 0x72, 0x29, 0x8d, 0x06, 0xc2, 0x06, 0x3b, 0x4f, 0xa9, 0xc1, 0xc5, 0x40, 0x92, 0x93, 0xed, + 0xe8, 0x14, 0x4d, 0x2e, 0x89, 0x73, 0x03, 0x83, 0xdb, 0xee, 0xe3, 0xe2, 0x4b, 0x59, 0xef, 0xcb, + 0x0e, 0x14, 0xe8, 0x91, 0xc2, 0xb8, 0xf8, 0x3e, 0x07, 0xc1, 0xf0, 0x3f, 0x03, 0xf1, 0x10, 0x04, + 0xe0, 0x02, 0x43, 0x60, 0xa3, 0x65, 0xb9, 0xe2, 0x7e, 0xbe, 0x52, 0x1f, 0xcc, 0x0f, 0x33, 0x44, + 0x9c, 0xfa, 0x8a, 0x58, 0xf2, 0x60, 0xb9, 0x5a, 0x51, 0xbd, 0xe2, 0x1a, 0xf8, 0x6e, 0x06, 0xda, + 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x3a, 0x04, 0xf1, 0x69, 0xd4, 0x41, 0x0b, 0x57, 0xdc, 0xd0, 0x46, + 0x81, 0xf4, 0xba, 0xa0, 0x3b, 0x8a, 0xd5, 0x3f, 0x15, 0x89, 0x23, 0x10, 0x82, 0xcb, 0x6a, 0xe6, + 0x2a, 0x95, 0x3f, 0xfa, 0x5b, 0x0b, 0x07, 0x41, 0xd6, 0x3d, 0x40, 0x29, 0x99, 0x8a, 0x79, 0x56, + 0x9b, 0xb3, 0x6c, 0x58, 0x21, 0x02, 0x01, 0x3b, 0xf1, 0x7c, 0x62, 0x56, 0x94, 0xdb, 0x3a, 0x3b, + 0x02, 0xae, 0x17, 0xb0, 0xea, 0xe7, 0xc2, 0x8d, 0x71, 0x0f, 0x54, 0xa3, 0x99, 0xa3, 0x8f, 0x87, + 0xc1, 0xf8, 0x1f, 0x81, 0xf8, 0x1f, 0x81, 0xfe, 0x08, 0xe2, 0x50, 0x52, 0xe4, 0x31, 0xa3, 0x20, + 0x0c, 0x49, 0xd7, 0xc6, 0x46, 0x60, 0xf2, 0xe1, 0xa2, 0x10, 0x96, 0xfe, 0x6a, 0xba, 0x1c, 0x2a, + 0x41, 0x03, 0x3e, 0x3a, 0xbf, 0x7c, 0x1e, 0xe6, 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x3a, 0x04, 0xe9, + 0xaa, 0xf6, 0x07, 0x75, 0x88, 0x63, 0x97, 0x76, 0xb2, 0x9f, 0x74, 0x03, 0x59, 0x45, 0x41, 0x64, + 0x44, 0xea, 0x56, 0xdd, 0x86, 0x5a, 0x08, 0x90, 0x09, 0xc2, 0xb0, 0x32, 0x2b, 0x21, 0x2d, 0xcd, + 0x6a, 0x7b, 0x10, 0x67, 0x57, 0xd0, 0x81, 0x62, 0x51, 0x53, 0x3e, 0x3b, 0x8c, 0x66, 0x1d, 0xe1, + 0xff, 0x9b, 0x9d, 0x50, 0xfe, 0x4b, 0x58, 0xc7, 0xe7, 0x69, 0xb9, 0xda, 0x2d, 0x04, 0x00, 0xaa, + 0xd7, 0xd5, 0x32, 0x17, 0x09, 0x87, 0x87, 0xc3, 0xe0, 0x7e, 0x07, 0xe0, 0xfc, 0x0f, 0x83, 0xec, + 0x3c, 0x60, 0x68, 0x2e, 0x87, 0x02, 0x42, 0x92, 0xf6, 0xb0, 0xe6, 0xab, 0x37, 0x16, 0xdc, 0x6d, + 0xdb, 0x1c, 0x9c, 0xc9, 0x39, 0x92, 0x09, 0xe9, 0x46, 0x9f, 0xc9, 0xb1, 0x69, 0x83, 0xf1, 0x35, + 0x4a, 0xde, 0x40, 0xa7, 0x71, 0x3a, 0x15, 0x49, 0xaa, 0xf5, 0xa7, 0x07, 0x1a, 0x24, 0xd7, 0x61, + 0x47, 0x97, 0x6d, 0xc7, 0xc2, 0xc0, 0x26, 0xe0, 0x2c, 0x82, 0x92, 0x48, 0x4b, 0x73, 0x2b, 0x20, + 0x89, 0x48, 0xd6, 0x5f, 0x35, 0x8e, 0xa8, 0xe1, 0xb9, 0x2f, 0x76, 0xc1, 0x24, 0x1f, 0xaf, 0xea, + 0x46, 0x96, 0x6c, 0x6f, 0xa1, 0x60, 0x3d, 0xb2, 0x9e, 0x5d, 0xe4, 0xdb, 0xe3, 0x20, 0x66, 0x06, + 0x79, 0x24, 0xa9, 0xfa, 0x90, 0x59, 0x7d, 0x95, 0x7e, 0x56, 0x56, 0x60, 0x00, 0x4f, 0xb7, 0xf0, + 0xf0, 0xf0, 0x3f, 0x07, 0xe0, 0x7c, 0x0f, 0xc0, 0xf1, 0xc2, 0xd4, 0x7e, 0x7f, 0x1f, 0x15, 0x02, + 0x91, 0x30, 0xa8, 0xcf, 0xe1, 0xd3, 0xbe, 0x39, 0x18, 0xa7, 0xd8, 0x27, 0x07, 0xe0, 0x8e, 0xba, + 0x64, 0x2c, 0xe3, 0x4e, 0x38, 0x93, 0xf1, 0x00, 0x0a, 0xde, 0x40, 0xa7, 0x71, 0x3a, 0x25, 0x49, + 0xaf, 0xdd, 0x49, 0xd0, 0x00, 0x2f, 0x1f, 0x73, 0x84, 0xbf, 0xb1, 0x1c, 0xd3, 0x01, 0xac, 0x45, + 0x65, 0xbf, 0xc2, 0xf9, 0x94, 0x70, 0xbd, 0x72, 0x2f, 0xeb, 0x2f, 0xed, 0xff, 0x1d, 0x00, 0x29, + 0x63, 0xa9, 0xa4, 0x2a, 0x32, 0x19, 0xc5, 0x17, 0xb8, 0x44, 0x9d, 0x35, 0x26, 0x80, 0x22, 0xc2, + 0xbd, 0x0f, 0x41, 0xea, 0x16, 0x51, 0x4d, 0x03, 0xcc, 0xaf, 0xb2, 0x4f, 0xe9, 0xa9, 0x48, 0xf9, + 0xed, 0x8f, 0xbd, 0xeb, 0xb8, 0x70, 0x7c, 0x0f, 0xe0, 0x7e, 0x03, 0xf0, 0x1f, 0x20, 0x3f, 0xc7, + 0x17, 0x44, 0x2c, 0x38, 0x3b, 0x6e, 0xa3, 0xbb, 0x95, 0xe6, 0x5a, 0xb0, 0x4a, 0xdb, 0xf1, 0xeb, + 0x06, 0x37, 0x12, 0x64, 0x90, 0xac, 0x4d, 0xef, 0x41, 0x0c, 0xb3, 0x81, 0xcc, 0x97, 0x87, 0x40, + 0x1b, 0x58, 0xca, 0xf7, 0x71, 0x39, 0xf4, 0x61, 0x69, 0xd4, 0x41, 0xd9, 0xdd, 0xe2, 0xaa, 0xbb, + 0x30, 0x4b, 0x61, 0x43, 0x0d, 0xcd, 0x67, 0x0a, 0x07, 0x99, 0x18, 0xa5, 0xf7, 0x78, 0x7d, 0x2a, + 0xaf, 0x8d, 0xda, 0xae, 0x4c, 0x0e, 0x07, 0x2b, 0x45, 0x54, 0x80, 0x0f, 0xd4, 0x4b, 0x87, 0x78, + 0x0b, 0x91, 0xb1, 0x2e, 0x37, 0x35, 0x62, 0xd7, 0xc6, 0x3f, 0xcf, 0x54, 0x66, 0xbc, 0xe8, 0x38, + 0xe6, 0xf9, 0xab, 0x8e, 0xda, 0x31, 0x2b, 0x01, 0x9b, 0x8b, 0x4e, 0x50, 0x91, 0x71, 0xe4, 0x61, + 0x4b, 0x87, 0x83, 0xe0, 0xfc, 0x1f, 0x81, 0xf8, 0x3f, 0x01, 0xff, 0xd5, 0x67, 0xbe, 0x3a, 0x6e, + 0xa3, 0xd6, 0x25, 0x10, 0xe6, 0x36, 0xca, 0xc3, 0xb4, 0xcd, 0xfd, 0xe9, 0xf0, 0xdd, 0xed, 0x7c, + 0xbd, 0xb9, 0x58, 0x95, 0xa7, 0xf3, 0xc8, 0xfc, 0x4a, 0xde, 0x40, 0xa7, 0x71, 0x1a, 0x35, 0xb1, + 0x69, 0x22, 0x08, 0x97, 0x59, 0xc6, 0xef, 0xda, 0x00, 0x19, 0xde, 0x54, 0x54, 0xea, 0xcd, 0xb9, + 0x7e, 0x65, 0x42, 0x94, 0x20, 0x3f, 0x4b, 0xa9, 0xfb, 0x31, 0xd5, 0x9e, 0x68, 0xa0, 0xc5, 0x27, + 0x24, 0xa4, 0x5e, 0x36, 0xd5, 0xe1, 0x64, 0x88, 0x08, 0xd4, 0xe5, 0xae, 0x1e, 0x3f, 0x37, 0x3d, + 0xcf, 0x5d, 0x03, 0x9a, 0x4e, 0xa2, 0x2e, 0xb6, 0xf5, 0x47, 0x01, 0x46, 0xb4, 0x3b, 0x84, 0x66, + 0x4c, 0x87, 0xfb, 0x3b, 0x01, 0xd9, 0x87, 0x87, 0x87, 0xe0, 0xf8, 0x1f, 0x81, 0xf8, 0x03, 0xfd, + 0xb2, 0x4c, 0x82, 0xd6, 0xce, 0x40, 0x2d, 0x5e, 0xfc, 0x72, 0x70, 0x29, 0x92, 0xc9, 0xe7, 0xd0, + 0x2d, 0xd9, 0x44, 0x87, 0x97, 0x1c, 0xf4, 0xe7, 0x59, 0x1c, 0xfc, 0xf0, 0xcc, 0x73, 0xe1, 0x77, + 0xec, 0xac, 0xa7, 0x07, 0x59, 0x3a, 0x34, 0xd1, 0x33, 0xd7, 0xfa, 0x76, 0x00, 0xee, 0xf2, 0xed, + 0xf8, 0x94, 0x94, 0xc0, 0xb9, 0xa4, 0x3d, 0x73, 0x2e, 0xd2, 0x6c, 0x0a, 0xbe, 0x1d, 0xb1, 0x2d, + 0xee, 0xa3, 0x3e, 0x04, 0x14, 0xc0, 0xfa, 0xd6, 0xc1, 0xad, 0x3a, 0xd5, 0x3a, 0x08, 0x3a, 0x82, + 0xed, 0xeb, 0x60, 0xab, 0x90, 0xb0, 0x5c, 0xd0, 0x9e, 0xec, 0xe7, 0xf3, 0x32, 0x70, 0x21, 0x8e, + 0xb4, 0xe7, 0x55, 0x09, 0xc3, 0x7a, 0xb9, 0x51, 0x5c, 0xe4, 0x03, 0x68, 0x1f, 0x80, 0xfe, 0x07, + 0xc1, 0xf6, 0x33, 0x12, 0x00, 0x69, 0xc8, 0xe7, 0x7c, 0x01, 0xd8, 0x78, 0x52, 0xef, 0x20, 0xde, + 0xd5, 0x6c, 0xfc, 0x67, 0xaf, 0x12, 0x8d, 0x3c, 0x17, 0x6d, 0x00, 0x3e, 0x0f, 0x90, 0x0f, 0xe0, + 0x1f, 0xc0, 0xfc, 0x1f, 0x81, 0xfc, 0x0f, 0x44, 0x19, 0x59, 0x4e, 0x0e, 0xb2, 0x6a, 0x13, 0x2c, + 0xa8, 0x0b, 0x9b, 0x86, 0xe8, 0xe9, 0x76, 0x98, 0xdc, 0xb9, 0x70, 0x9c, 0xac, 0xe8, 0xb2, 0xe0, + 0x03, 0x3c, 0xf9, 0xe9, 0x7e, 0xdc, 0x5f, 0x5b, 0x4e, 0x7c, 0xe8, 0x5c, 0xfc, 0xff, 0x23, 0x5e, + 0x64, 0x01, 0x67, 0x29, 0x2e, 0x85, 0x07, 0xf0, 0x11, 0x30, 0xc3, 0xc1, 0xa4, 0xfa, 0x3b, 0x7f, + 0x15, 0xa9, 0x98, 0x19, 0x76, 0x6c, 0x77, 0x61, 0x5f, 0x64, 0x7c, 0x7c, 0x74, 0x82, 0xbe, 0x76, + 0xb3, 0x6c, 0xcf, 0xca, 0xf1, 0xc0, 0xfe, 0x03, 0xf8, 0x1f, 0x0e, 0xf3, 0x21, 0x46, 0x9e, 0x63, + 0x18, 0x71, 0x2a, 0x07, 0x74, 0x18, 0x38, 0x57, 0x8a, 0x15, 0x1b, 0xdf, 0xb5, 0x4a, 0x5d, 0xad, + 0xe8, 0x07, 0xbe, 0x00, 0xf0, 0x7e, 0x07, 0xf0, 0x1f, 0xc0, 0x7e, 0x0f, 0xc1, 0xfc, 0x0f, 0x2a, + 0x19, 0x59, 0x4e, 0x0e, 0xb2, 0x6a, 0x43, 0x34, 0x69, 0xd5, 0x7a, 0xea, 0x8d, 0xa6, 0x94, 0x80, + 0xd3, 0x10, 0x5b, 0x5b, 0x86, 0xad, 0x0d, 0x0b, 0x31, 0xee, 0x21, 0xef, 0x0c, 0xd5, 0x0e, 0xf2, + 0x6d, 0x34, 0xd6, 0x6a, 0x11, 0xaf, 0x64, 0x96, 0xff, 0x14, 0x50, 0x9d, 0xd5, 0xe2, 0x07, 0xf4, + 0x00, 0x63, 0x2e, 0x2c, 0x94, 0xfc, 0xc5, 0x87, 0xfb, 0x73, 0x2e, 0xe3, 0xfd, 0xfe, 0xfe, 0xea, + 0x88, 0xc9, 0xb3, 0x3f, 0x38, 0xb7, 0x65, 0xc2, 0x48, 0xb1, 0xf2, 0x57, 0x78, 0xf0, 0x3e, 0x0f, + 0xc0, 0x7f, 0x03, 0xfe, 0x38, 0xbc, 0x78, 0x67, 0x36, 0xb0, 0xbf, 0x00, 0xa1, 0x93, 0x04, 0xfa, + 0x55, 0x44, 0xb8, 0xfb, 0xc8, 0xc3, 0xf7, 0x42, 0x67, 0x50, 0x79, 0x6a, 0x4e, 0x80, 0xbe, 0xc5, + 0xeb, 0xa2, 0x8c, 0xc3, 0x87, 0x21, 0xf9, 0x0f, 0x0c, 0xac, 0xa7, 0x07, 0x59, 0x3a, 0x04, 0x69, + 0x69, 0xd4, 0x3e, 0x17, 0xb0, 0x98, 0x04, 0x05, 0x75, 0x62, 0x2f, 0x8f, 0x3f, 0x5e, 0x54, 0x3e, + 0x5a, 0x21, 0x5e, 0xcb, 0xd7, 0x50, 0x7b, 0x89, 0x50, 0x16, 0xdb, 0x47, 0x9f, 0x8a, 0xf0, 0xa3, + 0x12, 0xe8, 0x0e, 0xf3, 0x32, 0x6b, 0xf4, 0x10, 0x12, 0xa8, 0x3d, 0x2b, 0x69, 0x26, 0xe1, 0x02, + 0x3f, 0x22, 0xd7, 0x13, 0x22, 0x67, 0x8b, 0x5d, 0x8f, 0x1c, 0x8c, 0x56, 0x22, 0x0c, 0x93, 0x19, + 0xb0, 0x83, 0xff, 0x31, 0x2b, 0x3c, 0x36, 0x31, 0xc6, 0x3e, 0x0f, 0xc0, 0xfc, 0x0f, 0xc0, 0x7c, + 0x0f, 0xfe, 0xd4, 0xc0, 0xa2, 0x0d, 0xa1, 0x10, 0xf3, 0xaf, 0xae, 0x98, 0x30, 0xe0, 0x4d, 0xb0, + 0xc3, 0x08, 0x7d, 0x39, 0x00, 0x47, 0xac, 0xaa, 0xfd, 0xe1, 0xc8, 0x3b, 0x8c, 0x7c, 0x0e, 0xc9, + 0x1c, 0xac, 0xa7, 0x07, 0x59, 0x3a, 0x25, 0xc9, 0xb0, 0xd2, 0xbf, 0x90, 0x45, 0xba, 0xcf, 0x4f, + 0x87, 0x7e, 0x31, 0x8d, 0xf2, 0xc5, 0x31, 0x44, 0x7f, 0x49, 0x8b, 0x3f, 0xd4, 0xde, 0xf5, 0x31, + 0x66, 0x82, 0xe2, 0xbf, 0x2d, 0x87, 0xbd, 0x21, 0xb4, 0xb1, 0x56, 0x42, 0x74, 0xfd, 0x5a, 0x44, + 0x03, 0x98, 0x1a, 0x22, 0x91, 0x2d, 0x63, 0x2a, 0xac, 0x87, 0x61, 0x2d, 0x26, 0xe9, 0x1a, 0xa5, + 0xff, 0xdf, 0x65, 0xe6, 0xfb, 0x97, 0x16, 0x3d, 0xcb, 0x01, 0xe3, 0x46, 0x4b, 0x26, 0xe7, 0x87, + 0xc0, 0xfc, 0x0f, 0xc0, 0xfc, 0x1f, 0x81, 0xff, 0x01, 0x0e, 0x43, 0xa4, 0x08, 0x8e, 0x02, 0xe1, + 0xf9, 0x47, 0x77, 0xd6, 0xe0, 0x31, 0x67, 0x40, 0x2f, 0xf9, 0xe0, 0x93, 0x68, 0xb8, 0x61, 0xea, + 0xb1, 0xc0, 0x9e, 0x49, 0x85, 0x83, 0x89, 0x06, 0x1c, 0x32, 0x1c, 0xb7, 0x59, 0x3a, 0x25, 0x71, + 0x69, 0xd5, 0x7a, 0x69, 0x7a, 0x00, 0x00, 0x00, 0x5e, 0xcd, 0x5d, 0x5d, 0x9f, 0xe1, 0x34, 0x7f, + 0x41, 0x1f, 0x3e, 0x58, 0x11, 0xd7, 0x0b, 0xc5, 0xff, 0x81, 0x59, 0x5d, 0x18, 0x0f, 0x3a, 0xc4, + 0x1d, 0x36, 0x73, 0x5a, 0x43, 0x92, 0xf7, 0x4c, 0x58, 0x75, 0xba, 0x19, 0x39, 0xeb, 0x22, 0x49, + 0x03, 0xd5, 0x9a, 0xa0, 0xec, 0x9a, 0x77, 0xd4, 0x59, 0x8a, 0x8a, 0x86, 0x6e, 0x73, 0x42, 0x25, + 0x5f, 0xe9, 0x15, 0x7e, 0x51, 0x3c, 0x07, 0xc7, 0x91, 0xc7, 0x87, 0x83, 0xf0, 0x3e, 0x07, 0xe0, + 0x78, 0x00, 0x2b, 0x98, 0xf9, 0x3e, 0xe7, 0x5d, 0x8b, 0xe1, 0x46, 0x29, 0x6d, 0xb1, 0x9c, 0xaf, + 0x4c, 0x0e, 0x49, 0x7c, 0xe9, 0xc1, 0x22, 0x17, 0x17, 0xa4, 0x60, 0x47, 0x09, 0xef, 0x85, 0x03, + 0x1c, 0x32, 0x1c, 0xb7, 0x59, 0x3a, 0x15, 0xb1, 0x66, 0x56, 0xfc, 0x34, 0x6c, 0x0a, 0x7c, 0x00, + 0x31, 0xe7, 0x9b, 0x3e, 0x8b, 0xe6, 0x8e, 0x9b, 0x9f, 0x19, 0x61, 0x3a, 0xd0, 0x2d, 0xca, 0xba, + 0x73, 0xc6, 0xf2, 0x04, 0x09, 0x48, 0x28, 0x24, 0x67, 0xbe, 0x51, 0xf8, 0xc4, 0x8c, 0xdc, 0x81, + 0x46, 0x13, 0x86, 0x85, 0x4d, 0x25, 0x2b, 0xb4, 0x64, 0x23, 0x77, 0x62, 0x64, 0xf0, 0x52, 0x6e, + 0xd6, 0x59, 0x17, 0xdc, 0xd7, 0x44, 0x07, 0xd7, 0x05, 0x6f, 0x6e, 0x66, 0x81, 0x15, 0x11, 0x60, + 0x67, 0x8f, 0x83, 0xf0, 0x3f, 0x01, 0xf0, 0x78, 0x3e, 0x00, 0x1c, 0x54, 0x4e, 0x17, 0x85, 0x28, + 0x30, 0x08, 0xc8, 0xa3, 0x18, 0xab, 0x25, 0x2a, 0x03, 0x7d, 0x4d, 0xc4, 0x73, 0x7a, 0xdb, 0xdc, + 0xdc, 0x39, 0x15, 0x4b, 0x45, 0x31, 0xf1, 0x01, 0x1c, 0x32, 0x8b, 0xb7, 0x59, 0x3a, 0x36, 0x29, + 0xb0, 0xdc, 0x58, 0x9c, 0x3d, 0xf8, 0x63, 0x7f, 0xcc, 0xc6, 0x86, 0xb4, 0x12, 0xbb, 0xc1, 0xa6, + 0x45, 0x22, 0x34, 0xe9, 0xcb, 0x2d, 0xf6, 0x45, 0x0a, 0x74, 0x9a, 0x04, 0xaa, 0x90, 0xfa, 0xfe, + 0x2e, 0xc2, 0xb7, 0x5b, 0x04, 0x95, 0x5b, 0x1c, 0xbb, 0x27, 0x4c, 0x23, 0x74, 0x29, 0x65, 0xb3, + 0x29, 0x83, 0x0c, 0xff, 0xca, 0x2c, 0x9b, 0x02, 0x71, 0x97, 0x97, 0xfc, 0x2a, 0x5e, 0xe8, 0xa5, + 0xcb, 0x5b, 0xf4, 0xf5, 0x3e, 0x3e, 0x1f, 0x1f, 0x0f, 0xc1, 0xf0, 0xf8, 0x38, 0x39, 0xf7, 0xed, + 0xfd, 0xb5, 0xbf, 0x3d, 0xc6, 0xe4, 0x97, 0x53, 0xd5, 0xdb, 0x24, 0x1a, 0x2d, 0x59, 0x46, 0xd2, + 0x78, 0xcf, 0x44, 0x64, 0xc8, 0x97, 0x87, 0x00, 0x00, 0x5b, 0x76, 0x23, 0x1e, 0x3e, 0x0f, 0x40, + 0x1c, 0x31, 0xa2, 0xb7, 0x59, 0x3a, 0x44, 0xc1, 0x33, 0xd3, 0x8d, 0x2f, 0x14, 0xf2, 0x6a, 0x70, + 0xdb, 0x8e, 0x7a, 0xb3, 0x95, 0xcb, 0x81, 0x5c, 0xf8, 0x5c, 0xb0, 0x30, 0xb8, 0x50, 0xb8, 0xcd, + 0x5f, 0x61, 0xe5, 0xfc, 0x54, 0xd0, 0xcc, 0xb0, 0x32, 0xa3, 0x79, 0x23, 0x30, 0xbf, 0xa6, 0x60, + 0xb0, 0x91, 0x48, 0x28, 0xdb, 0xa6, 0x6d, 0x06, 0x7d, 0x8c, 0x41, 0x4d, 0x9d, 0x79, 0xec, 0xde, + 0x45, 0xf9, 0xb2, 0x3b, 0x8c, 0x84, 0x4f, 0x89, 0xca, 0x2f, 0xa9, 0xfb, 0x6a, 0x83, 0xf0, 0x3e, + 0x1c, 0x7c, 0x68, 0x4e, 0x04, 0x06, 0x2e, 0x0b, 0xf1, 0x9b, 0x10, 0x41, 0x34, 0xde, 0x34, 0x46, + 0xc1, 0x25, 0x43, 0x02, 0xe8, 0xaa, 0x72, 0x89, 0xa2, 0xb8, 0x99, 0xe1, 0xf8, 0x1f, 0xc0, 0x7e, + 0x03, 0xf8, 0x07, 0xe0, 0x7e, 0x07, 0xe2, 0x98, 0x38, 0x63, 0x2d, 0x6e, 0xb2, 0x6a, 0x13, 0x7c, + 0xa7, 0x93, 0xab, 0x53, 0x7c, 0x44, 0xa6, 0xa3, 0x5c, 0x6e, 0x15, 0x16, 0xc0, 0x70, 0x24, 0x37, + 0x5e, 0xed, 0x86, 0x81, 0x07, 0x22, 0x6d, 0xfa, 0x2b, 0xb4, 0xbc, 0x96, 0x97, 0x5d, 0xf1, 0x41, + 0x46, 0x6b, 0x74, 0x19, 0x83, 0x62, 0xb5, 0xf6, 0x5a, 0x82, 0x66, 0x62, 0x21, 0x40, 0x53, 0xb6, + 0x3e, 0x02, 0xf0, 0xe1, 0x78, 0x1d, 0x7d, 0x09, 0x1d, 0x32, 0x2c, 0x03, 0xac, 0x48, 0x36, 0xfd, + 0x00, 0x00, 0x62, 0x87, 0x11, 0x9d, 0xee, 0x1f, 0x81, 0xf8, 0xe3, 0x98, 0x09, 0x2a, 0x02, 0xf1, + 0x43, 0xba, 0xc3, 0x0f, 0xe8, 0x3a, 0xb6, 0x16, 0x3e, 0x19, 0xd3, 0xca, 0x0d, 0xac, 0x66, 0x44, + 0x29, 0x66, 0x02, 0x11, 0xc3, 0xe1, 0xf8, 0x0f, 0xe0, 0x3f, 0x81, 0xfc, 0x0f, 0x8c, 0xe2, 0x94, + 0x38, 0x63, 0x2d, 0x6e, 0xb2, 0x6a, 0x04, 0xfc, 0x33, 0x99, 0x90, 0x39, 0x20, 0x30, 0xff, 0xb4, + 0x30, 0xb8, 0xc4, 0x12, 0xb1, 0xe9, 0x0f, 0x96, 0xdb, 0x03, 0xcd, 0x52, 0xe2, 0x14, 0x56, 0xf6, + 0x04, 0x3c, 0x4a, 0x5e, 0x8f, 0x15, 0xee, 0xc2, 0x67, 0x8b, 0x94, 0xf7, 0xdc, 0x90, 0x0b, 0xf3, + 0x4e, 0x58, 0xf1, 0x50, 0x5c, 0xa2, 0x6f, 0xa7, 0xa2, 0x7e, 0xb3, 0xf3, 0x5f, 0x90, 0x15, 0x67, + 0xd4, 0xeb, 0xa4, 0x7f, 0x2b, 0x1c, 0xb9, 0x0c, 0x41, 0xc5, 0x02, 0x16, 0xa8, 0xf1, 0xe0, 0xfc, + 0x0f, 0x87, 0x82, 0x1b, 0xdf, 0x89, 0x5e, 0x36, 0x79, 0xbe, 0x67, 0xef, 0xfc, 0x10, 0x3b, 0x67, + 0x30, 0x8e, 0xc5, 0x3f, 0x39, 0x00, 0x2c, 0x4f, 0xf8, 0xe4, 0x46, 0x5d, 0x83, 0xf0, 0x3f, 0x03, + 0xf0, 0x3f, 0x03, 0xf0, 0x3c, 0x3c, 0x1e, 0x90, 0x38, 0x63, 0x2d, 0x6e, 0xb2, 0x69, 0xf3, 0xd4, + 0x33, 0xd8, 0x0e, 0xc2, 0x9f, 0x37, 0x79, 0x60, 0x9a, 0xfc, 0xf2, 0x74, 0xf3, 0x6f, 0x3a, 0x72, + 0x71, 0x2d, 0xb0, 0xd3, 0xf7, 0x25, 0x57, 0x4a, 0x2f, 0xeb, 0xcf, 0x94, 0xce, 0x06, 0x4e, 0x2c, + 0x72, 0xbc, 0xf8, 0xf4, 0x26, 0xde, 0xb9, 0x51, 0xea, 0xba, 0xe8, 0x09, 0x79, 0x57, 0xa0, 0x97, + 0xbf, 0xf5, 0x41, 0xfb, 0x9b, 0x94, 0x77, 0x67, 0x5e, 0xfc, 0xb8, 0xc1, 0xe8, 0x27, 0x86, 0x12, + 0x09, 0x3c, 0xf9, 0xba, 0x0f, 0x4c, 0xe0, 0x7e, 0x0e, 0x1c, 0x42, 0x9e, 0x7d, 0x1d, 0xfa, 0x47, + 0x21, 0xa5, 0xa7, 0x83, 0xdb, 0x4b, 0x22, 0x0f, 0xda, 0x11, 0x07, 0x36, 0x97, 0x0d, 0x1a, 0x4a, + 0x3e, 0x42, 0x58, 0xfc, 0x70, 0x3f, 0x03, 0xf8, 0x1f, 0x81, 0xfc, 0x0f, 0xc1, 0xf0, 0x3e, 0x8c, + 0x38, 0x63, 0x2d, 0x6e, 0xb2, 0x6a, 0x23, 0x6c, 0x69, 0xd4, 0x3e, 0x17, 0xac, 0x21, 0x55, 0x93, + 0x90, 0xdc, 0x64, 0xe3, 0x94, 0x46, 0x58, 0x16, 0x64, 0x08, 0x07, 0x57, 0xea, 0xe7, 0x8d, 0xe6, + 0x3c, 0xff, 0x72, 0xe9, 0xee, 0x44, 0xa1, 0x91, 0xe0, 0xa5, 0x8d, 0xf8, 0x00, 0x42, 0xf4, 0x4f, + 0x12, 0xaa, 0x8d, 0x53, 0xe5, 0x04, 0x23, 0x9a, 0xb0, 0xdf, 0x36, 0x57, 0x8d, 0x80, 0xce, 0x61, + 0x42, 0x79, 0x4e, 0x9a, 0x98, 0x80, 0x36, 0x76, 0xb1, 0x12, 0x52, 0x09, 0x04, 0x3b, 0xc3, 0x07, + 0x83, 0xc3, 0xc1, 0xce, 0xe7, 0x38, 0xd9, 0x76, 0x6f, 0x6f, 0x4d, 0xf7, 0xca, 0xf3, 0x15, 0x07, + 0xf4, 0xa4, 0x45, 0x43, 0xe6, 0x1e, 0x2b, 0x38, 0x95, 0x22, 0x62, 0x7e, 0x09, 0x2a, 0x75, 0x4d, + 0xbe, 0x8a, 0xb3, 0xf8, 0xe7, 0x28, 0xf1, 0x45, 0x15, 0x36, 0xf0, 0xaa, 0x59, 0x3a, 0x05, 0x61, + 0x17, 0x53, 0xba, 0x39, 0x92, 0x10, 0x28, 0x29, 0x42, 0x01, 0x0d, 0x63, 0x30, 0xf6, 0xa2, 0x2e, + 0x2e, 0x94, 0x22, 0x45, 0x69, 0x24, 0x9c, 0xed, 0xc9, 0x03, 0xbb, 0xfa, 0x1b, 0x87, 0x07, 0x18, + 0x7b, 0x1c, 0x81, 0xcc, 0x46, 0x10, 0x0c, 0x05, 0x37, 0xa8, 0xc9, 0xf0, 0x54, 0x77, 0x46, 0xbb, + 0x32, 0x7e, 0xad, 0x89, 0x17, 0xdb, 0x80, 0x3b, 0xcb, 0x56, 0x1c, 0xc4, 0x60, 0x62, 0x11, 0x1b, + 0x0d, 0x2b, 0x8a, 0xfa, 0x5f, 0x9b, 0x03, 0xe3, 0xc3, 0xe3, 0x08, 0x19, 0x41, 0xf9, 0xb0, 0x75, + 0x90, 0x35, 0xf1, 0x6b, 0xde, 0x52, 0x86, 0xb0, 0xa8, 0x45, 0xf5, 0x31, 0x38, 0xbc, 0x42, 0x74, + 0x11, 0x0e, 0x67, 0x07, 0xc0, 0xfc, 0x07, 0xf0, 0x1f, 0xc0, 0x7e, 0x07, 0xc0, 0xf8, 0x1e, 0x88, + 0x2a, 0x6d, 0xe1, 0x54, 0xb2, 0x69, 0xf4, 0x84, 0x33, 0x99, 0x90, 0x14, 0xce, 0x01, 0x5d, 0xb0, + 0x5e, 0x96, 0x0e, 0x6e, 0xab, 0x5c, 0xe5, 0x6d, 0xbb, 0x37, 0x38, 0xb9, 0xb2, 0x1b, 0x05, 0x8c, + 0x78, 0x2c, 0x60, 0xcb, 0xf6, 0x63, 0xc2, 0xaa, 0xcf, 0x45, 0xe3, 0xe7, 0x83, 0xfc, 0x3b, 0xd6, + 0x02, 0x76, 0x96, 0x16, 0x4c, 0xf2, 0xdb, 0x01, 0x14, 0xee, 0x3d, 0x4f, 0xfa, 0x79, 0xe6, 0xee, + 0xcf, 0x2e, 0x8b, 0x05, 0x95, 0xce, 0x11, 0xdd, 0x00, 0x06, 0x76, 0xa4, 0xd0, 0x72, 0xe6, 0x0f, + 0x83, 0xcf, 0x01, 0x37, 0xba, 0xad, 0xa4, 0x76, 0x0e, 0xf2, 0x49, 0xa9, 0xf3, 0xf3, 0xdf, 0xa4, + 0x60, 0x91, 0x77, 0xd7, 0x02, 0x6d, 0x81, 0x16, 0xc1, 0x6a, 0x3f, 0x11, 0xdc, 0x78, 0x1f, 0x81, + 0xfc, 0x07, 0xf0, 0x3f, 0x07, 0x87, 0x86, 0x84, 0x2a, 0x6d, 0xe1, 0x54, 0xb2, 0x69, 0xf5, 0x2c, + 0x33, 0xd3, 0x8c, 0x58, 0xe1, 0x9c, 0xb2, 0x59, 0xfc, 0xdc, 0xd0, 0xc0, 0xf3, 0xe2, 0x7b, 0x0d, + 0x82, 0x03, 0x79, 0xc8, 0x02, 0x05, 0xa5, 0xc0, 0xa3, 0x32, 0x5e, 0xa7, 0x59, 0x35, 0x90, 0x72, + 0xba, 0x77, 0x62, 0x47, 0x75, 0xe5, 0xe7, 0x87, 0xff, 0x6f, 0xf6, 0x54, 0x3c, 0x3c, 0x04, 0xa5, + 0x61, 0x6b, 0x51, 0xb2, 0xef, 0x43, 0xfc, 0xe5, 0x5a, 0x49, 0xd8, 0xa2, 0x90, 0x2d, 0xf4, 0xc9, + 0x92, 0x34, 0x04, 0x4d, 0xbc, 0x44, 0x1b, 0x3c, 0x1f, 0x0f, 0x07, 0xe7, 0x1e, 0x4c, 0x8e, 0x93, + 0x84, 0xc3, 0x84, 0xf0, 0x53, 0xdf, 0x8f, 0x39, 0x31, 0xeb, 0x80, 0xfb, 0x07, 0xa7, 0xc4, 0x62, + 0xdb, 0xe9, 0xe8, 0x64, 0x1e, 0x0f, 0x80, 0xfc, 0x07, 0xe0, 0x7e, 0x07, 0x83, 0x81, 0xe2, 0x82, + 0x2a, 0x6d, 0xe1, 0x54, 0xb2, 0x69, 0xd5, 0x14, 0xa7, 0x9c, 0xd9, 0x8f, 0xdd, 0x6b, 0x3d, 0x76, + 0xf7, 0xc3, 0x0e, 0x97, 0x50, 0x17, 0x2a, 0xf3, 0xb1, 0xc9, 0x00, 0x11, 0x47, 0x58, 0xb6, 0x37, + 0x42, 0x00, 0x82, 0x81, 0xef, 0x39, 0xd7, 0x5c, 0xd4, 0x53, 0xa8, 0x2e, 0xf6, 0xbf, 0x6b, 0x6b, + 0xed, 0xbb, 0x79, 0x5f, 0x4e, 0x7f, 0x5c, 0x9c, 0x36, 0xde, 0xd0, 0xc3, 0xe0, 0xa2, 0x2e, 0xf6, + 0xdc, 0x8b, 0x53, 0x7a, 0x9c, 0xb5, 0xd2, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x86, 0xe7, 0xe0, 0xe7, + 0x03, 0xae, 0x3b, 0xcf, 0xdc, 0xa2, 0x6e, 0x9d, 0x9c, 0x27, 0xe3, 0x71, 0x00, 0x53, 0xcf, 0x51, + 0x41, 0xab, 0x75, 0x93, 0x63, 0x0f, 0x17, 0x53, 0x8f, 0x43, 0xc1, 0xf9, 0x01, 0xfb, 0x08, 0x3f, + 0xc0, 0xfc, 0x07, 0xc0, 0xfc, 0x07, 0xe2, 0x82, 0x38, 0x37, 0x7f, 0xee, 0xb2, 0x6a, 0x05, 0x04, + 0xaf, 0xdd, 0x47, 0xae, 0x91, 0xb9, 0x15, 0x00, 0x00, 0x35, 0x1c, 0x0e, 0xf4, 0x88, 0x7b, 0x3b, + 0x20, 0x11, 0x45, 0xff, 0x9b, 0xc9, 0x49, 0x92, 0x5c, 0xa8, 0x15, 0xc6, 0x2f, 0x00, 0x65, 0xd9, + 0x0c, 0xa6, 0xc1, 0x57, 0x59, 0xfe, 0x6c, 0xa8, 0xb9, 0xca, 0x85, 0x17, 0x43, 0x10, 0x50, 0x89, + 0x2a, 0x32, 0xf0, 0xe9, 0x21, 0xb0, 0x76, 0x84, 0xd6, 0x2c, 0x02, 0x2d, 0xca, 0x00, 0xe4, 0xe7, + 0x70, 0xfc, 0x0d, 0x62, 0x61, 0x29, 0x9b, 0x87, 0x1f, 0x0f, 0xc1, 0xf8, 0x1f, 0x83, 0xe0, 0xe3, + 0x86, 0x05, 0x8b, 0x60, 0x65, 0xfa, 0x56, 0x07, 0xe6, 0x3c, 0x06, 0x1a, 0x85, 0xda, 0x16, 0xa8, + 0xe5, 0x5d, 0x56, 0x66, 0x21, 0xce, 0x99, 0xa2, 0xd4, 0xeb, 0x17, 0x0b, 0xe6, 0x20, 0x53, 0x48, + 0x15, 0xa9, 0xc6, 0x9a, 0x59, 0x3a, 0x15, 0x19, 0xa8, 0x0a, 0xd8, 0xfb, 0x8e, 0x91, 0xcf, 0x81, + 0xf5, 0x95, 0x4a, 0x3c, 0xbf, 0x7b, 0x07, 0x47, 0x4c, 0x06, 0xfb, 0xb8, 0x8e, 0x89, 0x7a, 0xe4, + 0x77, 0xd5, 0xfe, 0xa2, 0x5d, 0x91, 0x3b, 0x3a, 0x4e, 0x73, 0x87, 0x6e, 0x9e, 0xb1, 0x18, 0x3f, + 0x20, 0x0f, 0x97, 0xc7, 0x92, 0xbd, 0x38, 0xa4, 0x5a, 0xdf, 0x04, 0x0d, 0xd6, 0xee, 0xe5, 0x37, + 0x91, 0x4d, 0xd6, 0xf1, 0x39, 0x0a, 0x77, 0xf4, 0x28, 0x18, 0xd6, 0x4e, 0x1b, 0x1f, 0x07, 0x30, + 0x0d, 0x89, 0xf3, 0xe2, 0xa3, 0x96, 0x01, 0xfa, 0x00, 0x69, 0x46, 0x83, 0x58, 0xf8, 0x7d, 0x50, + 0xe5, 0x1c, 0x72, 0x20, 0x12, 0x0a, 0x40, 0x31, 0x94, 0x3f, 0xe1, 0xe0, 0x7e, 0x07, 0xf0, 0x1f, + 0xc0, 0x7e, 0x07, 0xe0, 0x7e, 0x07, 0xe2, 0x8e, 0x31, 0x44, 0x9f, 0x94, 0xb2, 0x6a, 0x04, 0x14, + 0x62, 0xa1, 0x41, 0x6d, 0x58, 0xb3, 0xd6, 0x54, 0x5d, 0x8e, 0x1b, 0xf9, 0xf7, 0xe1, 0xdc, 0xb2, + 0x0a, 0x45, 0xcd, 0xfa, 0x6e, 0x8d, 0x63, 0x73, 0x21, 0x99, 0x55, 0x5c, 0x2c, 0x3a, 0xbf, 0x9c, + 0xe7, 0xad, 0xb0, 0xa9, 0x88, 0xcb, 0x00, 0xd0, 0x1b, 0x3b, 0x87, 0xe4, 0x34, 0x74, 0xd6, 0x41, + 0x01, 0x5a, 0x90, 0x50, 0xd8, 0x61, 0x22, 0xb8, 0xdf, 0xbe, 0xab, 0xa6, 0xf9, 0xd2, 0x05, 0x81, + 0xe6, 0x82, 0x20, 0x7c, 0x3c, 0x60, 0x18, 0x64, 0x7d, 0x2c, 0x7c, 0xc3, 0xf1, 0xfb, 0xbb, 0x77, + 0x59, 0xf4, 0x7b, 0xf2, 0x06, 0x8d, 0x50, 0x8d, 0x9f, 0x4c, 0xc1, 0xa1, 0x0f, 0x69, 0x56, 0x91, + 0xee, 0x6c, 0x3c, 0x0f, 0xc0, 0x7f, 0x01, 0xfc, 0x07, 0xf0, 0x3f, 0x00, 0xfe, 0x03, 0xe2, 0x8c, + 0x31, 0x44, 0x9f, 0x94, 0xb2, 0x6a, 0x04, 0x2c, 0x33, 0xd7, 0xfb, 0x2c, 0x1a, 0x47, 0x41, 0x14, + 0xaa, 0xbb, 0x2f, 0x89, 0x27, 0x2c, 0x14, 0x19, 0x47, 0x2c, 0x09, 0x2b, 0xb7, 0x86, 0x2a, 0x41, + 0xcd, 0xea, 0x0a, 0xc0, 0x62, 0x0d, 0x1a, 0xfd, 0xf2, 0x27, 0x4f, 0x87, 0xfa, 0x66, 0x41, 0x22, + 0xf0, 0xc0, 0x7d, 0x12, 0x3c, 0xff, 0xd8, 0x37, 0x5b, 0x53, 0x07, 0x9b, 0x31, 0x48, 0x1e, 0x74, + 0xa3, 0xf6, 0x2c, 0x3f, 0x81, 0xf5, 0x8a, 0xaa, 0xa1, 0xdc, 0x84, 0x92, 0x7d, 0x56, 0x0f, 0x83, + 0x8f, 0xf0, 0x45, 0x63, 0x5e, 0x0b, 0x34, 0x10, 0x60, 0xc9, 0x8b, 0xf9, 0x00, 0x0b, 0x35, 0xf6, + 0x63, 0xf4, 0x00, 0xc7, 0x64, 0x11, 0xef, 0x57, 0xa0, 0x76, 0x84, 0xe1, 0xf0, 0x1f, 0x81, 0xf8, + 0x1f, 0x80, 0xfc, 0x0f, 0xc0, 0xfc, 0x1e, 0x8a, 0x31, 0x44, 0x9f, 0x94, 0xb2, 0x69, 0xf4, 0x24, + 0x37, 0xdf, 0x74, 0xd5, 0xec, 0x89, 0x25, 0xf8, 0x06, 0x62, 0xdb, 0x69, 0xec, 0x25, 0xdc, 0x0f, + 0x00, 0xff, 0x4e, 0x2f, 0xa4, 0xfa, 0x75, 0x06, 0x49, 0x05, 0xde, 0xc4, 0x47, 0x9a, 0x70, 0x2d, + 0xa8, 0xbf, 0x43, 0xb5, 0x73, 0xb5, 0x6b, 0xbd, 0x7f, 0xd3, 0x51, 0xd3, 0x4a, 0xd9, 0x29, 0xfc, + 0x69, 0xd6, 0xdc, 0x20, 0xa8, 0x28, 0x3f, 0xa6, 0x59, 0x57, 0x81, 0xa7, 0x2f, 0x3e, 0x61, 0xaf, + 0x9f, 0xa5, 0x61, 0x1f, 0xb9, 0x0d, 0x44, 0xf7, 0xee, 0x5e, 0xd9, 0xd7, 0x0a, 0x59, 0xe6, 0x09, + 0x6d, 0xc8, 0xd8, 0xe2, 0x42, 0x98, 0xa5, 0x7b, 0x7e, 0xcc, 0xcc, 0xe9, 0x1b, 0x0b, 0xc5, 0x35, + 0x31, 0x73, 0xa5, 0x75, 0x96, 0xa6, 0x00, 0x1c, 0x3e, 0x1e, 0x07, 0x1c, 0xf1, 0xe0, 0x3e, 0x08, + 0x31, 0x44, 0x9f, 0x94, 0xb2, 0x79, 0x95, 0xcc, 0x33, 0x9e, 0x5d, 0x41, 0x8f, 0x8a, 0x96, 0xc7, + 0xe1, 0x70, 0x65, 0xe7, 0xdb, 0x04, 0xd5, 0xd1, 0x32, 0xef, 0x93, 0xc9, 0x18, 0x8f, 0xe0, 0xe1, + 0x65, 0x45, 0x99, 0x6e, 0x1c, 0x2b, 0xc9, 0x31, 0x1c, 0x79, 0x1b, 0x83, 0x4e, 0xff, 0xda, 0x66, + 0x7e, 0x8c, 0xe7, 0x4e, 0x49, 0x2a, 0x1d, 0x4f, 0x7a, 0x6a, 0xb4, 0xe7, 0xa0, 0x05, 0x0c, 0xc2, + 0x46, 0xd2, 0x31, 0x87, 0xa6, 0x36, 0x6c, 0x25, 0x7e, 0x12, 0xfb, 0x1c, 0x24, 0xc3, 0xe0, 0xf1, + 0xee, 0x58, 0x4a, 0x5e, 0xa5, 0x27, 0x85, 0xc0, 0x61, 0xcd, 0xf2, 0xbc, 0xb1, 0x17, 0xc3, 0xd6, + 0xd6, 0x54, 0xc7, 0xff, 0xa1, 0xe7, 0xc1, 0x0f, 0xbf, 0xf9, 0x4a, 0x23, 0xc3, 0xf0, 0x3f, 0x03, + 0xf8, 0x0f, 0xe0, 0x78, 0x7c, 0x0e, 0x1e, 0x86, 0x31, 0x44, 0x9f, 0x94, 0xb2, 0x69, 0xe4, 0x34, + 0x37, 0xdf, 0x74, 0x6e, 0x24, 0x93, 0x69, 0xca, 0xf0, 0x42, 0x18, 0xc9, 0x65, 0x85, 0x6f, 0x58, + 0x9b, 0xba, 0x9a, 0x97, 0xd0, 0x62, 0xc1, 0xac, 0x90, 0xd2, 0x42, 0x31, 0x2d, 0x7c, 0xc0, 0x2b, + 0xa1, 0x0b, 0xc8, 0x50, 0xf9, 0xbb, 0xa5, 0x7d, 0x4b, 0x87, 0xe8, 0x2f, 0xd0, 0xbb, 0x82, 0xfd, + 0x16, 0x10, 0x19, 0x1f, 0x93, 0x96, 0xb8, 0x62, 0x32, 0xd6, 0x75, 0xbb, 0x2d, 0x8c, 0x48, 0x20, + 0xcc, 0xa6, 0xef, 0x97, 0x6d, 0x51, 0xe5, 0x73, 0x65, 0x9c, 0xdd, 0x79, 0x7c, 0xee, 0x7b, 0xc3, + 0xb7, 0xbf, 0xe4, 0x8f, 0x24, 0xf3, 0x6a, 0x48, 0x7a, 0x33, 0x35, 0x97, 0x37, 0x57, 0x7f, 0x5e, + 0x61, 0x75, 0x1c, 0x3e, 0xdb, 0x57, 0xc4, 0x85, 0x0d, 0xc3, 0xe1, 0x87, 0x81, 0xc6, 0x7d, 0x07, + 0x91, 0x44, 0x9f, 0x94, 0xb2, 0x39, 0xa5, 0xdc, 0x69, 0xd4, 0x53, 0xa1, 0xf2, 0xb1, 0x90, 0x83, + 0xe6, 0x47, 0x9c, 0xb0, 0x39, 0x1c, 0xa0, 0x8e, 0xd1, 0x26, 0xbe, 0xaa, 0x8e, 0xab, 0xad, 0x5b, + 0x71, 0x66, 0xc4, 0xf1, 0xd4, 0x0b, 0x50, 0x92, 0xb0, 0xd3, 0x44, 0xe3, 0x56, 0x3f, 0xb0, 0x84, + 0xc8, 0xdf, 0x80, 0xf9, 0x66, 0xd9, 0x19, 0x17, 0xe0, 0xe2, 0x12, 0x84, 0x1c, 0xcf, 0x57, 0xa9, + 0x56, 0x79, 0x70, 0x7f, 0xb9, 0xa7, 0x58, 0x53, 0xea, 0x65, 0xe9, 0x91, 0x5c, 0x3b, 0x1c, 0xe7, + 0xa4, 0xff, 0xac, 0xa9, 0xfb, 0xde, 0xf9, 0xfc, 0x3c, 0x45, 0x36, 0x2d, 0x7c, 0xdc, 0x83, 0x69, + 0x12, 0x6a, 0xb1, 0x6a, 0x29, 0x02, 0x12, 0xd0, 0x00, 0x93, 0x93, 0xe8, 0x90, 0xbb, 0x5c, 0xa5, + 0x8c, 0xf6, 0x08, 0x7c, 0x37, 0x86, 0x3e, 0x07, 0x98, 0x44, 0x69, 0x6e, 0xb2, 0x39, 0xc6, 0x3c, + 0x69, 0xd4, 0x53, 0xa1, 0xf2, 0xa1, 0xf1, 0xaa, 0xf4, 0x4c, 0x39, 0xb2, 0xc2, 0xa4, 0xa6, 0xf1, + 0xcf, 0x85, 0xb4, 0xd3, 0xc9, 0xc7, 0xa3, 0x33, 0xf3, 0x5a, 0x04, 0xbb, 0x04, 0x8f, 0x8f, 0x80, + 0x7a, 0x24, 0x12, 0x88, 0x2b, 0xb9, 0x56, 0xbe, 0x39, 0x92, 0xf1, 0xb4, 0x80, 0x4b, 0xc1, 0xb3, + 0x7b, 0x23, 0xfc, 0x48, 0x7e, 0x7f, 0xea, 0x3d, 0x49, 0xc4, 0x32, 0x04, 0x69, 0x36, 0xed, 0x68, + 0x03, 0x75, 0x5d, 0x79, 0xc1, 0xcc, 0xa3, 0x21, 0x3d, 0x84, 0xd4, 0x23, 0x16, 0x48, 0x67, 0x80, + 0x3c, 0x76, 0x4e, 0x57, 0x39, 0x4f, 0x1a, 0xbf, 0x6e, 0xf7, 0x2a, 0xac, 0xb9, 0x3d, 0x1c, 0xf1, + 0x72, 0x6b, 0xff, 0x78, 0xec, 0xff, 0x15, 0xe1, 0x35, 0x44, 0x5e, 0x07, 0xc1, 0xfc, 0x61, 0xf8, + 0x98, 0x44, 0x69, 0x6e, 0xb2, 0x39, 0xc6, 0x3c, 0x37, 0xe7, 0x3d, 0xc9, 0x8e, 0xff, 0xc4, 0x6e, + 0x98, 0x6d, 0x0c, 0xe7, 0x5b, 0xa2, 0x9d, 0x70, 0xf9, 0x49, 0x65, 0x08, 0x3c, 0x9d, 0x4c, 0xbe, + 0xab, 0x06, 0x7f, 0x44, 0xcd, 0x5c, 0x3c, 0x0f, 0x45, 0x11, 0x44, 0xa6, 0x5c, 0x39, 0x10, 0xe4, + 0x5e, 0xaa, 0xff, 0x83, 0x97, 0xbb, 0x26, 0x41, 0x9f, 0x65, 0xc0, 0x70, 0x59, 0xea, 0x44, 0xd1, + 0x9d, 0x60, 0x8b, 0x95, 0xdc, 0xee, 0xa5, 0x97, 0x57, 0xb9, 0xc8, 0x53, 0x6b, 0x50, 0x93, 0xef, + 0x46, 0x29, 0xd1, 0x37, 0x23, 0xc8, 0xb8, 0x72, 0x83, 0xd8, 0x10, 0xde, 0xe4, 0x5d, 0xde, 0xc5, + 0xb0, 0x95, 0x28, 0x52, 0xe5, 0x78, 0xea, 0x33, 0xff, 0x45, 0x02, 0x67, 0x5e, 0x1d, 0x80, 0x1e, + 0x2a, 0x64, 0xe0, 0x17, 0x1f, 0x0d, 0x81, 0xf5, 0x98, 0x44, 0x69, 0x6e, 0xb2, 0x39, 0xb6, 0x34, + 0xaf, 0xdd, 0x5d, 0x72, 0x51, 0x9c, 0xbc, 0x0c, 0xcc, 0x10, 0xab, 0x8c, 0xc2, 0x7d, 0x59, 0x42, + 0x30, 0xe9, 0x9d, 0x1a, 0x5c, 0x84, 0x23, 0x4e, 0x22, 0xd6, 0x5f, 0x48, 0x7b, 0x28, 0x9c, 0x30, + 0x8e, 0x91, 0x70, 0xc9, 0x7a, 0x47, 0x8e, 0x19, 0xee, 0xbf, 0x26, 0xbe, 0x14, 0x32, 0xda, 0x90, + 0xa9, 0xb1, 0x01, 0x31, 0x7b, 0x70, 0x6f, 0x7a, 0x92, 0xb9, 0x20, 0x11, 0x61, 0x36, 0xf1, 0x68, + 0x3b, 0x55, 0x89, 0xbc, 0x57, 0x9b, 0xa1, 0x25, 0xf6, 0x2a, 0x0d, 0xbf, 0x06, 0x3c, 0x04, 0x81, + 0x70, 0xc1, 0xc2, 0xc1, 0x75, 0x90, 0xfe, 0x28, 0x0e, 0xf3, 0x46, 0x00, 0xd2, 0xc0, 0xb0, 0x25, + 0xa9, 0x95, 0xba, 0x98, 0x32, 0xc6, 0x64, 0xa8, 0x42, 0xac, 0x6c, 0x1e, 0x6c, 0x3c, 0x91, 0xf8, + 0x98, 0x44, 0xa5, 0x6e, 0xb2, 0x39, 0xf6, 0x2c, 0xaf, 0xdd, 0x5d, 0x70, 0x12, 0x34, 0x02, 0x21, + 0x2e, 0x2a, 0xa5, 0x29, 0x16, 0x21, 0x2b, 0x6b, 0xa6, 0x00, 0x62, 0x1a, 0x85, 0x11, 0xfe, 0x27, + 0x96, 0xc0, 0xe3, 0xca, 0xf9, 0x46, 0xdf, 0x0f, 0x6e, 0x7b, 0x04, 0xb5, 0x60, 0x0b, 0xd7, 0x23, + 0x62, 0x79, 0xd6, 0x0c, 0x1a, 0xd2, 0xed, 0x99, 0xc4, 0x11, 0x6a, 0x80, 0x3a, 0x1f, 0x6c, 0x4a, + 0x47, 0xa4, 0xc2, 0x1c, 0x5b, 0x94, 0x64, 0x8c, 0x26, 0x04, 0xfb, 0xfd, 0x16, 0xc5, 0x1f, 0x97, + 0x58, 0xcd, 0x2c, 0xec, 0xa5, 0xe7, 0x78, 0x58, 0xa7, 0x88, 0x7e, 0xb5, 0xaa, 0x2c, 0xbf, 0x1d, + 0x7d, 0xf1, 0xe0, 0x41, 0x8e, 0x4d, 0x3a, 0x58, 0x34, 0x6e, 0x28, 0x41, 0x75, 0x15, 0xeb, 0xc8, + 0xf2, 0x43, 0xc7, 0x21, 0x6d, 0xe3, 0x9e, 0x07, 0x78, 0x44, 0xa5, 0x6e, 0xb2, 0x39, 0xc6, 0x3c, + 0xb0, 0xdc, 0x12, 0xcc, 0x4c, 0xcc, 0x48, 0xed, 0x80, 0x64, 0xa3, 0x51, 0xff, 0x3d, 0xf0, 0x22, + 0xd1, 0x9b, 0xd6, 0xd3, 0x68, 0x90, 0x43, 0x3f, 0x1b, 0x71, 0x66, 0xd9, 0xa2, 0xbf, 0xc9, 0xe5, + 0xeb, 0x73, 0x46, 0xc1, 0xad, 0x24, 0xfd, 0xf3, 0x39, 0x11, 0x8f, 0xaa, 0x4c, 0x5e, 0xb6, 0x4e, + 0x11, 0xa1, 0xb4, 0xdb, 0x1a, 0xe4, 0xa5, 0xe5, 0xc5, 0xb7, 0xec, 0x9c, 0x1d, 0x17, 0xb7, 0x75, + 0xc5, 0x7e, 0x7d, 0xf1, 0x28, 0xa2, 0x14, 0x9f, 0x10, 0xde, 0x56, 0xb4, 0xe1, 0x83, 0xef, 0x57, + 0x87, 0xda, 0x25, 0x28, 0x35, 0x38, 0x90, 0x50, 0xa4, 0xb5, 0x5d, 0x7d, 0x94, 0xc3, 0xda, 0x73, + 0xdb, 0xe7, 0x28, 0x29, 0xbb, 0x59, 0x5c, 0xb5, 0x83, 0x72, 0x3b, 0x45, 0xc2, 0x56, 0xc7, 0x79, + 0x98, 0x44, 0xa5, 0x6e, 0xb2, 0x39, 0xc6, 0x1c, 0xb0, 0xdc, 0x62, 0x63, 0x93, 0x7b, 0xc3, 0x48, + 0xe7, 0x95, 0x2c, 0x81, 0x44, 0x14, 0xd3, 0xad, 0xf5, 0x39, 0x80, 0x5e, 0xee, 0x45, 0xc0, 0xbd, + 0x79, 0xc3, 0x00, 0x4b, 0x0a, 0xe2, 0x40, 0x24, 0xbc, 0xc5, 0xf6, 0x61, 0x16, 0xa6, 0x76, 0xa2, + 0x59, 0xaa, 0x1c, 0xe5, 0x07, 0x22, 0x89, 0x27, 0xce, 0x4a, 0x3d, 0xd3, 0x95, 0x29, 0x8f, 0xd4, + 0xc9, 0xa4, 0x9c, 0xfd, 0x00, 0x8f, 0x51, 0x80, 0x2a, 0xc8, 0xaa, 0xed, 0xf5, 0xb1, 0x54, 0xf3, + 0x42, 0xd4, 0x2b, 0xa0, 0x34, 0xd0, 0x01, 0x44, 0xf8, 0x28, 0x78, 0x1f, 0x77, 0xf4, 0xf1, 0x9a, + 0xc7, 0x75, 0x42, 0xbd, 0x06, 0xf8, 0x0c, 0xba, 0x99, 0xc7, 0xd4, 0xa9, 0xdd, 0x9b, 0xb6, 0xd0, + 0x86, 0x02, 0x31, 0xe3, 0x18, 0x7c, 0x00, 0xfc, 0x78, 0x44, 0xa5, 0x6e, 0xb2, 0x39, 0xc6, 0x24, + 0x69, 0xd5, 0x7e, 0xf4, 0x56, 0xff, 0xd6, 0xb8, 0x39, 0x42, 0xb8, 0xea, 0x1e, 0x44, 0x7d, 0xdb, + 0x3a, 0xb6, 0x27, 0xe9, 0xc5, 0xe9, 0xce, 0x0b, 0x27, 0x53, 0x53, 0x03, 0x18, 0x9b, 0x40, 0xa5, + 0xd1, 0x72, 0x39, 0x94, 0x3c, 0xb2, 0x50, 0x91, 0x4f, 0x84, 0xa1, 0xa4, 0x88, 0x6e, 0x7b, 0x48, + 0x4a, 0x99, 0x55, 0x38, 0xab, 0x70, 0x69, 0x53, 0x6f, 0xe9, 0x2d, 0xec, 0x15, 0xc8, 0x2f, 0xf6, + 0x1f, 0x48, 0x7d, 0xdf, 0x34, 0x16, 0xc3, 0x6f, 0x06, 0x64, 0x26, 0x9c, 0x20, 0xd0, 0x1c, 0xb0, + 0x6c, 0x57, 0x24, 0xc7, 0xa9, 0x5d, 0xea, 0x8e, 0xd1, 0xeb, 0x56, 0xfc, 0x10, 0x4d, 0xbd, 0xa4, + 0xe4, 0xa0, 0xac, 0xe2, 0xcc, 0x79, 0xb0, 0x7f, 0xae, 0x41, 0xcf, 0x9a, 0x1e, 0x61, 0x81, 0xfc, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xd5, 0x34, 0xae, 0xec, 0x1e, 0xe4, 0xe0, 0xd5, 0xb6, 0x00, + 0x00, 0xa5, 0x9f, 0x96, 0xcd, 0x72, 0xe7, 0x6b, 0xbd, 0x30, 0xbc, 0x87, 0x98, 0xed, 0xa5, 0x60, + 0x96, 0x46, 0x0e, 0xdb, 0xda, 0x89, 0x3e, 0x73, 0xed, 0xb8, 0x31, 0x33, 0x96, 0xfc, 0x5f, 0xe5, + 0x7f, 0xe9, 0xad, 0x25, 0x07, 0x2c, 0xec, 0x4c, 0xc4, 0x0f, 0x9c, 0x76, 0xe8, 0xaf, 0x0b, 0x62, + 0x23, 0xd7, 0xb2, 0x23, 0xaf, 0x62, 0x5c, 0xb4, 0xdd, 0x13, 0x51, 0x25, 0x86, 0x0c, 0xec, 0x91, + 0x22, 0x56, 0xaf, 0x7b, 0xe0, 0x30, 0x4c, 0x66, 0x14, 0x01, 0xfa, 0x42, 0x04, 0x4b, 0x91, 0xf9, + 0x65, 0xf4, 0x63, 0xd8, 0x58, 0xfb, 0xbb, 0xbe, 0x96, 0xe2, 0xdc, 0x0a, 0x9e, 0x43, 0xba, 0xd2, + 0xe4, 0xa9, 0x23, 0x01, 0xe7, 0x33, 0xb1, 0xe4, 0x78, 0x44, 0xa5, 0x6e, 0xb2, 0x39, 0xc6, 0x34, + 0x69, 0xd5, 0x7e, 0xef, 0x47, 0x1d, 0x1a, 0x06, 0x63, 0xd2, 0xd7, 0x56, 0x12, 0x77, 0x40, 0x88, + 0x00, 0xfd, 0x53, 0xa5, 0x52, 0x98, 0xd9, 0xf7, 0xd4, 0x97, 0xa1, 0x06, 0x7e, 0xc6, 0x9d, 0x5f, + 0x2c, 0x45, 0x27, 0x10, 0xee, 0x32, 0x36, 0xeb, 0x5e, 0x8a, 0x42, 0x23, 0x8b, 0x9c, 0x4b, 0x5d, + 0x14, 0x0a, 0x16, 0x2c, 0xfa, 0x6d, 0x9a, 0x64, 0xe8, 0xc2, 0xeb, 0x23, 0x51, 0x74, 0xe2, 0xbe, + 0x86, 0x3e, 0x9e, 0x4e, 0x3d, 0xf4, 0x10, 0xea, 0xb8, 0xc8, 0x0f, 0x35, 0xee, 0xba, 0x1f, 0x85, + 0xed, 0x2b, 0x5c, 0xe0, 0x65, 0xfc, 0x7f, 0xe3, 0xb5, 0x4c, 0xa2, 0x16, 0x68, 0xfc, 0xf0, 0x41, + 0x22, 0x2a, 0xea, 0x8e, 0x3f, 0xb2, 0x73, 0x66, 0x9e, 0xfe, 0x60, 0x66, 0x29, 0x86, 0x81, 0xf8, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xb6, 0x3c, 0x66, 0x3c, 0x02, 0x2d, 0xef, 0xe3, 0x94, 0xd8, + 0x80, 0x92, 0x4a, 0x95, 0x73, 0x76, 0x38, 0xc1, 0x72, 0x0b, 0xdd, 0xdd, 0x56, 0x98, 0x8c, 0xc6, + 0x13, 0x03, 0xdd, 0x3a, 0xd6, 0x0f, 0x63, 0xbb, 0xde, 0x18, 0x3a, 0x07, 0x21, 0xf8, 0x9d, 0xe8, + 0xb6, 0xca, 0x75, 0x31, 0x2e, 0x28, 0x6b, 0x1b, 0xd9, 0x19, 0x49, 0xe6, 0xf0, 0x1c, 0x54, 0xa8, + 0x10, 0xeb, 0xc2, 0x27, 0x50, 0x22, 0x03, 0x7a, 0x64, 0xbd, 0xf9, 0x0e, 0xdf, 0x80, 0xec, 0xd4, + 0xa3, 0xac, 0x4c, 0x0f, 0xb6, 0xc0, 0xe4, 0xb0, 0x8b, 0x74, 0x6c, 0xf0, 0x14, 0x5a, 0xa7, 0x55, + 0xb6, 0x2e, 0xdd, 0xdb, 0x0e, 0x29, 0xed, 0x6f, 0x93, 0x9c, 0x51, 0x14, 0x41, 0x34, 0xa8, 0x4f, + 0x62, 0x0e, 0x31, 0xb1, 0x71, 0x64, 0x87, 0xf0, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa5, 0xfc, + 0xb0, 0xdc, 0x62, 0x57, 0xd3, 0x36, 0xf2, 0xac, 0x75, 0xf7, 0xe4, 0x7e, 0xad, 0xe3, 0x52, 0x9d, + 0x36, 0x68, 0xd7, 0xde, 0xa5, 0xd5, 0x2e, 0xbd, 0x2a, 0x54, 0x3c, 0xe7, 0x64, 0xec, 0x4f, 0xb8, + 0x89, 0xba, 0x8e, 0xf0, 0x3d, 0x8f, 0x1c, 0xc5, 0x36, 0xec, 0x31, 0x31, 0x1c, 0x18, 0x72, 0x55, + 0xb0, 0x48, 0x18, 0x4a, 0xef, 0xb9, 0xe6, 0xc9, 0xdc, 0xe9, 0x60, 0x61, 0x64, 0x90, 0x85, 0x22, + 0x55, 0x9f, 0x06, 0x3c, 0xd1, 0xde, 0x8f, 0x2a, 0xa2, 0xbf, 0x80, 0x84, 0x58, 0x33, 0x0f, 0x28, + 0x57, 0x88, 0x40, 0x90, 0x88, 0x22, 0xf2, 0xf8, 0xfc, 0x27, 0x10, 0x78, 0x52, 0x79, 0xb5, 0x27, + 0x9a, 0x79, 0xcb, 0x0e, 0x23, 0xfe, 0x8f, 0x80, 0x53, 0x20, 0x61, 0xf3, 0xc1, 0x9d, 0xfe, 0x07, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xd6, 0x2c, 0x69, 0xd4, 0x6a, 0x42, 0x75, 0xb2, 0x56, 0x45, + 0xdb, 0x97, 0x98, 0x7c, 0xf8, 0x26, 0x81, 0xdd, 0x03, 0x6f, 0xd2, 0x5b, 0x85, 0x92, 0xb5, 0x9c, + 0x5b, 0x60, 0x4d, 0xaf, 0x25, 0x78, 0xce, 0xfd, 0x38, 0xc0, 0xd1, 0xf1, 0x1e, 0x99, 0xa7, 0xb2, + 0xf1, 0xae, 0x19, 0x59, 0x9a, 0xba, 0x97, 0x57, 0xcf, 0x6b, 0xee, 0x95, 0xdf, 0xa5, 0x95, 0xc3, + 0xa3, 0xa5, 0x93, 0xc3, 0x19, 0xd3, 0x48, 0x1a, 0x2a, 0x82, 0xe7, 0x5e, 0xdd, 0xff, 0x66, 0xd6, + 0xc1, 0xae, 0xa2, 0xcf, 0xff, 0x86, 0x08, 0x85, 0x94, 0x41, 0xc5, 0x17, 0xf6, 0xfa, 0x02, 0x3b, + 0x16, 0xe1, 0xa5, 0x38, 0x0d, 0x9c, 0x86, 0xef, 0x05, 0x9b, 0x96, 0x9c, 0x24, 0x07, 0x9c, 0xff, + 0x82, 0xf7, 0x07, 0x13, 0x38, 0xec, 0xf2, 0xda, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa5, 0xe4, + 0x69, 0xd4, 0x53, 0xbf, 0x32, 0xf9, 0xec, 0x78, 0xf3, 0x36, 0xd1, 0xaa, 0xac, 0x07, 0x21, 0xd3, + 0x6c, 0x15, 0x8f, 0xbc, 0x88, 0xa1, 0x7e, 0x52, 0xef, 0xd6, 0xf4, 0x15, 0xf5, 0x35, 0x93, 0xb7, + 0xd8, 0x36, 0x6f, 0xa5, 0xbe, 0xe0, 0x06, 0xf8, 0x9d, 0x49, 0x5a, 0x27, 0x40, 0x03, 0x09, 0xdf, + 0x34, 0x47, 0x3d, 0x32, 0xab, 0x10, 0x19, 0x0c, 0x43, 0x54, 0x2e, 0xda, 0xe5, 0x7b, 0xcd, 0x02, + 0xb8, 0x46, 0x14, 0x10, 0x05, 0xc7, 0x6b, 0xac, 0x48, 0x9d, 0x1c, 0x1f, 0xc4, 0x49, 0x78, 0x0c, + 0x63, 0xbf, 0x0a, 0x4e, 0xcf, 0x04, 0x3c, 0x65, 0x64, 0x7a, 0x89, 0xe6, 0xd3, 0x77, 0xd6, 0x1f, + 0xcf, 0x43, 0x9c, 0xe5, 0x75, 0xde, 0x16, 0x71, 0x37, 0x61, 0x4c, 0xf6, 0x87, 0x2b, 0xfc, 0x07, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xd6, 0x2c, 0xaf, 0xdd, 0x8e, 0xee, 0x15, 0xf5, 0x46, 0xb7, + 0xde, 0xd7, 0xa3, 0x50, 0xac, 0x8e, 0xc2, 0x34, 0x02, 0xd2, 0x2a, 0xdd, 0xff, 0xdc, 0xf0, 0xba, + 0x8a, 0x5a, 0x96, 0x77, 0xca, 0x80, 0xa6, 0x60, 0x0a, 0x2a, 0x5b, 0x73, 0x5d, 0x0e, 0xeb, 0x52, + 0x76, 0x6b, 0x67, 0x3b, 0x59, 0x81, 0xc9, 0xfa, 0x8d, 0x82, 0x01, 0x76, 0x2c, 0x29, 0x9a, 0xa6, + 0xbf, 0xd2, 0x9a, 0x8a, 0x0b, 0x0d, 0xfb, 0x29, 0xb9, 0x7b, 0x37, 0x42, 0xa6, 0xe0, 0xbc, 0x13, + 0x45, 0x57, 0x37, 0x60, 0x3f, 0xe0, 0xeb, 0xb5, 0xbf, 0x39, 0x9f, 0x1d, 0xdc, 0x4c, 0xee, 0xea, + 0xb4, 0xb5, 0x1f, 0x80, 0xe6, 0x12, 0xf0, 0x85, 0x54, 0x3d, 0x58, 0x8b, 0x21, 0x8a, 0x8e, 0xdb, + 0xab, 0xf3, 0xf8, 0x26, 0x63, 0x19, 0x61, 0xf8, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xb6, 0x34, + 0xaf, 0xdd, 0x5d, 0x70, 0x77, 0xc6, 0x5b, 0x81, 0x61, 0x35, 0x4d, 0x00, 0x3e, 0x7e, 0x5e, 0x7e, + 0xe4, 0x20, 0x03, 0xc2, 0x6e, 0x06, 0xd4, 0x13, 0x02, 0x05, 0xc9, 0x34, 0xcd, 0x9a, 0x72, 0xaa, + 0x2c, 0x54, 0x83, 0xdc, 0x30, 0x1b, 0xc1, 0xa6, 0x5e, 0xd7, 0x94, 0xae, 0x1a, 0x55, 0xba, 0x28, + 0xa3, 0x28, 0xde, 0xb6, 0x34, 0xa6, 0x34, 0xbb, 0xd1, 0xa1, 0xd2, 0x0d, 0x5f, 0xcd, 0xe2, 0xe8, + 0x5b, 0xb3, 0xe7, 0x07, 0x0b, 0xbf, 0x07, 0xd9, 0x03, 0x10, 0x6b, 0xde, 0x07, 0xbb, 0xc2, 0x30, + 0x5b, 0x34, 0x7f, 0xd6, 0xbe, 0x0e, 0x2f, 0xe9, 0x33, 0xbe, 0x7c, 0x86, 0x1f, 0x5f, 0xae, 0x34, + 0xe0, 0xad, 0x7e, 0xa2, 0x02, 0x7e, 0x10, 0x2f, 0x91, 0x19, 0x94, 0xc3, 0x3c, 0xe6, 0x0f, 0x1e, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa5, 0xfc, 0xaf, 0xdd, 0x5d, 0x72, 0x40, 0x99, 0x6f, 0xc2, + 0x1b, 0xde, 0x55, 0x98, 0xc8, 0xd0, 0x3c, 0x25, 0xd4, 0xe3, 0x93, 0x2c, 0x6e, 0x62, 0xaf, 0xb2, + 0xdb, 0xab, 0xd4, 0xaf, 0x14, 0x09, 0x1e, 0x1a, 0xde, 0x12, 0xba, 0xc8, 0x63, 0x9d, 0xa2, 0x67, + 0x75, 0xd8, 0x3e, 0xe6, 0xe2, 0x8c, 0xf7, 0xd2, 0xcd, 0x83, 0x33, 0x09, 0x95, 0xea, 0x42, 0x51, + 0x17, 0xad, 0x45, 0xbe, 0x80, 0xd2, 0x64, 0x18, 0x00, 0x7f, 0x59, 0x56, 0xd6, 0xb8, 0x0d, 0x43, + 0x0a, 0x8e, 0xad, 0xa4, 0x7f, 0x11, 0xc7, 0x8b, 0x90, 0x83, 0x43, 0xed, 0xf1, 0x88, 0x74, 0xd1, + 0x1d, 0x0d, 0x3c, 0xeb, 0xfb, 0x10, 0x0c, 0xed, 0xa0, 0xa5, 0x98, 0xec, 0xa7, 0xdd, 0xab, 0x5c, + 0xd4, 0x63, 0xa2, 0x19, 0x09, 0x4e, 0x7f, 0x03, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc6, 0x3c, + 0x69, 0x22, 0xe8, 0x73, 0x20, 0x58, 0x38, 0x1d, 0xfd, 0x9e, 0xa2, 0xb7, 0x7b, 0x72, 0x36, 0xfa, + 0x26, 0x3e, 0xc4, 0x03, 0xe2, 0x8f, 0x86, 0x5b, 0xdf, 0xa9, 0x39, 0xcb, 0xac, 0xd4, 0x2e, 0xbd, + 0xeb, 0x4b, 0x27, 0x06, 0xf9, 0xff, 0x26, 0x50, 0xe8, 0x4e, 0xeb, 0xae, 0x9f, 0x93, 0x95, 0xf2, + 0x68, 0xb7, 0xba, 0x84, 0x0d, 0x9c, 0xbe, 0x08, 0x7a, 0x70, 0x62, 0x51, 0x22, 0x27, 0x43, 0x23, + 0xd7, 0x8b, 0x2a, 0x7c, 0xac, 0xe0, 0xa4, 0x6e, 0x1f, 0xde, 0x6b, 0x65, 0x8c, 0x7f, 0xfd, 0x87, + 0x36, 0x40, 0xa8, 0xd5, 0xbb, 0x86, 0xed, 0xf3, 0xd8, 0x0c, 0x1d, 0x0b, 0x8b, 0x5a, 0x80, 0xd4, + 0xca, 0xcb, 0x72, 0x52, 0x95, 0xa7, 0xea, 0xa9, 0xe4, 0xec, 0xed, 0x06, 0xd8, 0xcc, 0x3e, 0x07, + 0x79, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xb6, 0x2c, 0xb0, 0xd2, 0xdb, 0xe7, 0x6a, 0xb8, 0xa5, 0x31, + 0x37, 0xee, 0x2f, 0x89, 0x78, 0x18, 0xf9, 0x03, 0xd4, 0xab, 0xfb, 0x14, 0x26, 0xf8, 0xe2, 0x1c, + 0x20, 0x4c, 0x35, 0xe8, 0x8c, 0x56, 0x17, 0xaa, 0xb4, 0x68, 0xda, 0xb9, 0x19, 0x39, 0xd2, 0x13, + 0x8d, 0xa6, 0x21, 0xc4, 0xec, 0xd6, 0xcb, 0xa1, 0xb6, 0xc2, 0x06, 0xc1, 0x96, 0xed, 0x18, 0x46, + 0x09, 0x1e, 0x39, 0x1c, 0xeb, 0x36, 0xa1, 0x99, 0x8a, 0xfd, 0x14, 0x33, 0x80, 0x35, 0x31, 0xf1, + 0x24, 0x85, 0x80, 0x1f, 0x90, 0x84, 0x82, 0xa9, 0x32, 0xc3, 0x01, 0xc1, 0xda, 0x1d, 0x43, 0x8f, + 0xed, 0x8b, 0x3e, 0xe9, 0x57, 0xd8, 0x56, 0x0c, 0xc6, 0x77, 0x7d, 0x4b, 0xd0, 0x83, 0x14, 0xf4, + 0x5a, 0x4a, 0x21, 0x05, 0x86, 0x41, 0xa7, 0xc1, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc5, 0xfc, + 0xae, 0xed, 0x1b, 0x9f, 0x80, 0x9b, 0x46, 0xc9, 0xee, 0xe6, 0xaa, 0x41, 0xa7, 0x40, 0x48, 0xa1, + 0x08, 0x99, 0x82, 0x48, 0x0a, 0xc8, 0x52, 0x66, 0x58, 0x96, 0x70, 0x6e, 0x50, 0xe3, 0x43, 0xa5, + 0x74, 0x31, 0xc7, 0x0c, 0x15, 0x94, 0x74, 0x02, 0xd2, 0x96, 0x3a, 0x15, 0x4a, 0xd3, 0x28, 0x07, + 0x6a, 0x8d, 0x97, 0x21, 0x33, 0xbf, 0xe8, 0x80, 0xaf, 0xec, 0x35, 0xb4, 0x2b, 0xba, 0xad, 0xec, + 0xc8, 0xe4, 0x80, 0x3e, 0x90, 0x19, 0x02, 0x5d, 0x48, 0x47, 0x90, 0xf3, 0xbe, 0x0f, 0x7f, 0xde, + 0x13, 0xbd, 0x72, 0x97, 0xf0, 0x87, 0xbc, 0x4f, 0x1d, 0x7a, 0xa8, 0xd2, 0x06, 0x19, 0xbb, 0xe4, + 0xbe, 0x5d, 0x4d, 0x24, 0x54, 0xaa, 0xa1, 0x4b, 0x27, 0x2f, 0x1b, 0x4b, 0x7c, 0x26, 0x59, 0x58, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc6, 0x34, 0xaf, 0xdd, 0x5d, 0x57, 0xcc, 0xa3, 0x86, 0x1d, + 0x6d, 0xdd, 0x40, 0xe6, 0x3a, 0x6c, 0xca, 0x2d, 0xb9, 0xbd, 0xaf, 0xf4, 0x89, 0x12, 0x83, 0x82, + 0xcd, 0x72, 0x04, 0x91, 0xdd, 0xe4, 0x9c, 0xdd, 0x5f, 0x2d, 0x77, 0xf9, 0x7c, 0xa7, 0x5c, 0x9a, + 0xf4, 0x20, 0x33, 0x6b, 0x59, 0x3d, 0xe1, 0xb7, 0x91, 0xa1, 0xac, 0xc3, 0xad, 0x4c, 0xea, 0xec, + 0x6a, 0x06, 0xe4, 0xfa, 0xf2, 0x9a, 0x33, 0xea, 0x18, 0x12, 0xa0, 0xdc, 0xfc, 0x37, 0xd9, 0x4c, + 0xaa, 0x11, 0xe7, 0x03, 0x39, 0x72, 0xbf, 0x1c, 0xca, 0xd3, 0x5f, 0x1b, 0x02, 0xff, 0xa7, 0x67, + 0x7c, 0x14, 0x4f, 0xed, 0x54, 0x77, 0x73, 0x2c, 0x48, 0x48, 0x0f, 0xa6, 0x47, 0x87, 0x08, 0x1f, + 0x41, 0xb2, 0x4f, 0xfc, 0x39, 0x0f, 0x77, 0xc1, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa6, 0x3c, + 0x69, 0xd4, 0x6a, 0x42, 0x63, 0xb5, 0x97, 0x25, 0xe0, 0xa6, 0x00, 0x93, 0xdc, 0x9c, 0x68, 0xb5, + 0x58, 0x2e, 0x3c, 0x24, 0x05, 0xf7, 0xa7, 0x33, 0xc6, 0x48, 0x94, 0x63, 0xdd, 0x8e, 0xd1, 0xe2, + 0x14, 0x7e, 0x33, 0xfc, 0xec, 0x43, 0x1b, 0x78, 0x02, 0x1b, 0x5a, 0x78, 0xae, 0x2e, 0x2d, 0x95, + 0x7f, 0x41, 0x2f, 0x90, 0x46, 0x57, 0xc0, 0xf0, 0xd3, 0xde, 0x1d, 0xa9, 0x86, 0x4d, 0x5d, 0x76, + 0x58, 0x44, 0x76, 0x1f, 0x47, 0x26, 0x38, 0xf8, 0xc4, 0x9a, 0x02, 0xb7, 0x1c, 0xfc, 0x39, 0xe6, + 0x72, 0x94, 0x78, 0x70, 0x2e, 0x51, 0xfc, 0xf4, 0xba, 0x5c, 0x17, 0xcf, 0x14, 0xc0, 0x2d, 0x7b, + 0xb6, 0x5c, 0x49, 0x72, 0x92, 0xdc, 0x83, 0xa7, 0x90, 0x3b, 0x96, 0xc9, 0x07, 0x8e, 0x7c, 0x63, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa6, 0x34, 0xaf, 0xdd, 0x72, 0x00, 0xd7, 0xcf, 0x22, 0x79, + 0xce, 0xce, 0x21, 0xcf, 0x85, 0xd9, 0x2a, 0xd8, 0xd4, 0x1d, 0x00, 0x49, 0xae, 0x4e, 0x01, 0x08, + 0xf8, 0x7e, 0xc2, 0x91, 0x69, 0x68, 0x1d, 0x04, 0xf9, 0x06, 0x30, 0xf3, 0x15, 0x53, 0xd6, 0x08, + 0xf3, 0x0f, 0x96, 0xac, 0x17, 0x9d, 0x42, 0xc5, 0xdb, 0xa2, 0x15, 0xbb, 0x2e, 0xd1, 0x6e, 0x9e, + 0xed, 0x97, 0xd1, 0xb0, 0x2e, 0x89, 0xa8, 0x8e, 0x89, 0x27, 0x2c, 0xfd, 0x9a, 0x22, 0x84, 0x21, + 0x91, 0x6b, 0x64, 0x96, 0x00, 0xfe, 0x5d, 0x07, 0x0b, 0xa2, 0x7e, 0xab, 0xd0, 0xee, 0xeb, 0xb7, + 0x8e, 0xbb, 0x85, 0x78, 0x9f, 0xa0, 0x5e, 0x6c, 0x62, 0x47, 0x5d, 0xe1, 0x65, 0x0e, 0x0e, 0xc7, + 0x1d, 0x00, 0x75, 0x9b, 0x4a, 0x42, 0x5f, 0x01, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc5, 0xbc, + 0xb0, 0xdc, 0x62, 0x56, 0xd4, 0x50, 0x19, 0x30, 0x62, 0x00, 0x93, 0x48, 0x23, 0xd8, 0x8a, 0x44, + 0xe5, 0xdb, 0x09, 0x9c, 0x08, 0x8d, 0x74, 0xbf, 0x33, 0x1a, 0x33, 0x3e, 0xe3, 0xc0, 0x4c, 0x79, + 0x28, 0x9c, 0x4a, 0x19, 0x27, 0x97, 0x7f, 0x42, 0x74, 0x3f, 0xa5, 0x7c, 0xe0, 0x3e, 0xf4, 0x39, + 0x22, 0xa0, 0x05, 0x2e, 0x0a, 0x83, 0xa0, 0x55, 0x47, 0xc2, 0xed, 0xb1, 0x14, 0x20, 0x5f, 0xff, + 0x7a, 0x32, 0x19, 0x50, 0xdb, 0x16, 0x80, 0x7d, 0x1f, 0x6a, 0x9b, 0xc2, 0x8e, 0xfc, 0x70, 0x40, + 0x1a, 0x91, 0xb0, 0x87, 0xad, 0x8b, 0xb7, 0x8e, 0x44, 0xad, 0x0d, 0x70, 0x7b, 0x7a, 0x40, 0xae, + 0x15, 0x3f, 0x73, 0x02, 0xe0, 0xbe, 0x9f, 0xcf, 0x6d, 0xbf, 0x4a, 0x3a, 0x0c, 0x92, 0x76, 0x1e, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xb6, 0x3c, 0x69, 0xd4, 0x53, 0xbd, 0x32, 0xc2, 0x82, 0x19, + 0xbf, 0x3c, 0x5c, 0x7a, 0xac, 0x01, 0xfc, 0x94, 0x76, 0xf9, 0x6b, 0x28, 0x39, 0x72, 0xce, 0x1c, + 0x1a, 0x3a, 0x81, 0x04, 0xc8, 0x07, 0x55, 0xca, 0x05, 0x2c, 0x0b, 0xb8, 0x64, 0x65, 0xf5, 0x38, + 0xa7, 0x01, 0x29, 0xd5, 0x6a, 0x00, 0xef, 0x4a, 0xcf, 0x97, 0x8c, 0x1b, 0xd5, 0x27, 0x32, 0x9a, + 0xf3, 0x93, 0x58, 0x30, 0x5c, 0x7e, 0xfb, 0xed, 0x58, 0x6e, 0x8a, 0x96, 0xd0, 0xc6, 0x72, 0x01, + 0xc3, 0x8a, 0x5a, 0x69, 0x19, 0x01, 0xe5, 0xa7, 0xfc, 0x1e, 0x78, 0x3f, 0x98, 0xec, 0xae, 0xe3, + 0x9a, 0x88, 0x1a, 0xea, 0x9e, 0xda, 0x15, 0xf6, 0x85, 0x6c, 0x04, 0x94, 0x57, 0x8e, 0xd7, 0x3f, + 0xca, 0x5c, 0x39, 0xde, 0xe0, 0x63, 0xbc, 0x07, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc6, 0x2c, + 0x69, 0xd4, 0x8a, 0x58, 0x8e, 0xc0, 0x35, 0x85, 0x61, 0x67, 0xd5, 0x84, 0x18, 0x61, 0xee, 0xc4, + 0xc5, 0x01, 0xe4, 0xca, 0xbb, 0xea, 0xa2, 0x35, 0x61, 0xbb, 0x6b, 0x86, 0x9c, 0x9f, 0xba, 0x0f, + 0x85, 0x76, 0xe5, 0x87, 0x82, 0x79, 0xf5, 0x53, 0x72, 0x58, 0x77, 0x5c, 0xb9, 0x81, 0x0a, 0xe3, + 0xbe, 0xae, 0xd5, 0x6b, 0xe8, 0x4d, 0xdb, 0x08, 0xf6, 0x94, 0xed, 0x5a, 0xe9, 0x55, 0x2d, 0x0f, + 0x54, 0xcd, 0x6f, 0x9f, 0xaa, 0x98, 0x47, 0x84, 0xfb, 0xb8, 0xd9, 0x99, 0x08, 0x0f, 0xe1, 0x1f, + 0x35, 0xad, 0xf7, 0x64, 0x04, 0xf2, 0xb6, 0x5d, 0x90, 0x62, 0x6f, 0xee, 0x7e, 0x62, 0x89, 0xfc, + 0x4e, 0xef, 0x82, 0x8f, 0x03, 0x5a, 0x58, 0x28, 0x22, 0x0d, 0xa3, 0xcc, 0x23, 0xc6, 0x3c, 0x0f, + 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc5, 0xd4, 0x69, 0xd4, 0x53, 0x87, 0x0f, 0xf2, 0x3d, 0xef, + 0xd0, 0x40, 0x99, 0x3c, 0xe2, 0xcc, 0x21, 0x07, 0x34, 0x09, 0x82, 0x32, 0x55, 0x25, 0xd8, 0xe5, + 0xc8, 0xc4, 0x4f, 0x97, 0x27, 0xd0, 0x14, 0x1c, 0x54, 0x88, 0x92, 0xa1, 0x2c, 0xc6, 0xd6, 0xf3, + 0xe3, 0x18, 0x39, 0xa8, 0x79, 0x9f, 0x85, 0x36, 0xb1, 0xa2, 0x66, 0xf2, 0x35, 0xf0, 0xb1, 0x05, + 0x4e, 0xcf, 0x61, 0x4f, 0x7f, 0x77, 0xe8, 0xf5, 0x74, 0xd9, 0x1f, 0x75, 0x7e, 0x12, 0x8e, 0xf7, + 0xd5, 0x65, 0x34, 0xd4, 0x7e, 0x27, 0xbc, 0x6f, 0xe2, 0xb2, 0xf5, 0x2a, 0x7c, 0x36, 0xb0, 0x46, + 0x74, 0x8d, 0x03, 0x3e, 0x50, 0x6b, 0x2e, 0xed, 0xa6, 0xa6, 0x90, 0xee, 0x6b, 0xac, 0xe1, 0x30, + 0x72, 0x6b, 0xff, 0x04, 0xda, 0x9e, 0x38, 0x3e, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa6, 0x3c, + 0xb0, 0xdc, 0x62, 0x6f, 0xa5, 0x3a, 0x56, 0xe6, 0x06, 0xa8, 0x75, 0x42, 0x00, 0x27, 0x19, 0xf9, + 0xb6, 0xf4, 0x19, 0x6e, 0xb3, 0x73, 0x5b, 0x69, 0x18, 0xc3, 0x23, 0x2d, 0x6c, 0xf2, 0x40, 0x80, + 0xef, 0x26, 0xe6, 0x53, 0xfd, 0xce, 0xbb, 0x47, 0xe5, 0xda, 0x38, 0x82, 0xc0, 0x19, 0x69, 0x0b, + 0xa2, 0xcc, 0x9a, 0x6a, 0x38, 0xb9, 0x18, 0xab, 0x9b, 0xd9, 0x5e, 0x19, 0xec, 0x35, 0x01, 0x9c, + 0x4b, 0x55, 0x2d, 0xec, 0xaa, 0x84, 0x98, 0x2a, 0xe6, 0xb8, 0x03, 0x8e, 0xd9, 0xe5, 0x1b, 0x92, + 0xec, 0x43, 0xf6, 0x50, 0xbf, 0x7f, 0xe9, 0xee, 0x9b, 0x0a, 0x36, 0x68, 0xd4, 0xda, 0xd4, 0x69, + 0x22, 0x56, 0xdb, 0x6c, 0xd7, 0x09, 0x85, 0x10, 0x01, 0xaf, 0xf0, 0x63, 0xc3, 0xe1, 0x9f, 0x07, + 0x9b, 0xc5, 0x37, 0xee, 0xb2, 0x39, 0xc5, 0xe4, 0x00, 0xc0, 0x5f, 0xba, 0x85, 0x0b, 0x4f, 0x32, + 0x77, 0xe0, 0x1b, 0xc9, 0xdf, 0x64, 0x30, 0x0c, 0x39, 0x0f, 0xdd, 0xce, 0x93, 0xfc, 0x85, 0xb9, + 0x62, 0xc4, 0x1b, 0x32, 0x49, 0x0e, 0x04, 0x6d, 0x42, 0x78, 0xfb, 0x7a, 0x3d, 0x7b, 0x26, 0x17, + 0x12, 0xab, 0x24, 0x49, 0x7f, 0xbd, 0xf5, 0x32, 0xa2, 0x24, 0xd7, 0x1e, 0x6f, 0xe0, 0xc2, 0xda, + 0x85, 0xdc, 0x78, 0x1a, 0xf2, 0x76, 0xea, 0x90, 0xa1, 0x32, 0x6d, 0x72, 0x10, 0x2b, 0x20, 0x6c, + 0x1b, 0x91, 0xcf, 0x38, 0x3e, 0x0f, 0x87, 0x86, 0x67, 0xb1, 0xc2, 0xe8, 0xb6, 0x78, 0xe8, 0x36, + 0x1a, 0x2e, 0xa3, 0xb9, 0xdb, 0xe9, 0x02, 0xee, 0x8d, 0xaa, 0xa1, 0x72, 0xbc, 0xb1, 0x32, 0x03, + 0xe0, 0x7e, 0x07, 0xf0, 0x3f, 0x01, 0xe5, 0x83, 0x3d, 0xe2, 0x9b, 0xf7, 0x59, 0x0a, 0x25, 0xca, + 0x37, 0xc7, 0xc2, 0xa2, 0x56, 0x44, 0xb6, 0x00, 0x00, 0x1a, 0x32, 0xe9, 0xbc, 0x47, 0xbe, 0x1c, + 0x9f, 0x82, 0xf7, 0xda, 0xa5, 0x58, 0xa9, 0x04, 0x3c, 0x68, 0xed, 0x36, 0x07, 0x81, 0xe4, 0xc1, + 0x33, 0xbe, 0x92, 0x8b, 0x82, 0xe2, 0x48, 0xc7, 0x44, 0xf2, 0x0f, 0x25, 0xb1, 0x2d, 0xde, 0xbe, + 0xc1, 0x73, 0x0c, 0xb4, 0x8e, 0xe3, 0xcc, 0x70, 0x91, 0xfc, 0xc6, 0x35, 0x94, 0xb3, 0x5c, 0x4b, + 0xd3, 0x99, 0x5b, 0x44, 0xed, 0xf2, 0x94, 0x7f, 0x7c, 0x58, 0x63, 0x1b, 0x93, 0x9e, 0x3c, 0x38, + 0xf8, 0x16, 0x70, 0x29, 0xab, 0xba, 0xfb, 0x2d, 0x5b, 0xa8, 0x10, 0x62, 0xe9, 0xe6, 0x8c, 0xe2, + 0xc0, 0xe8, 0x56, 0xb0, 0x13, 0xc7, 0x73, 0x38, 0x20, 0xf0, 0xd3, 0x67, 0x1c, 0xf0, 0xf8, 0x43, + 0xcd, 0xe2, 0x9b, 0xf7, 0x59, 0x1a, 0x06, 0x32, 0x37, 0xca, 0x74, 0x3f, 0xcb, 0x5e, 0xc6, 0xaa, + 0x00, 0x01, 0xa0, 0xea, 0xed, 0x68, 0x7c, 0x8c, 0x51, 0x4d, 0x94, 0x12, 0x69, 0x2c, 0x00, 0x69, + 0x75, 0xcf, 0x95, 0x54, 0xb5, 0x2d, 0x63, 0x60, 0x5e, 0x9b, 0xbc, 0x51, 0xc0, 0x07, 0xba, 0x61, + 0x87, 0x08, 0xba, 0xe6, 0xfd, 0x98, 0xf2, 0x06, 0x80, 0x0d, 0x20, 0x7c, 0x48, 0x23, 0x3a, 0xb9, + 0x74, 0x59, 0x6f, 0xec, 0x9d, 0x2f, 0xb1, 0x4a, 0xd4, 0xb3, 0x4e, 0xfc, 0x7a, 0x33, 0xb0, 0x9a, + 0x0b, 0xa4, 0xce, 0x61, 0x8c, 0xf1, 0x83, 0xc1, 0xe0, 0xa7, 0x06, 0x41, 0x65, 0xb0, 0xee, 0x18, + 0x34, 0x8f, 0x8a, 0x15, 0x42, 0x71, 0x1d, 0xf7, 0x99, 0xe6, 0x2d, 0x7d, 0x86, 0xf9, 0x5e, 0x3a, + 0x64, 0x8a, 0xe6, 0x32, 0x58, 0xc7, 0x11, 0xc3, 0xdd, 0xe2, 0x9b, 0xf7, 0x59, 0x1a, 0x06, 0x32, + 0xaf, 0xdd, 0x47, 0xaf, 0xed, 0xa3, 0xde, 0x00, 0x00, 0x01, 0x43, 0x12, 0x7e, 0x61, 0xbb, 0x2b, + 0x1d, 0x25, 0xb9, 0x7d, 0x8e, 0x56, 0x64, 0x31, 0xdb, 0x3a, 0xf8, 0x23, 0x8b, 0x55, 0x1c, 0xdd, + 0x2d, 0x44, 0x75, 0x2f, 0xc4, 0x86, 0x11, 0x96, 0x4c, 0xf5, 0xc0, 0x8c, 0x1d, 0xc0, 0x70, 0x85, + 0x01, 0x36, 0x29, 0x4b, 0x30, 0xf9, 0x0c, 0x2e, 0x2e, 0xab, 0x75, 0xca, 0x0f, 0xb5, 0x98, 0x2d, + 0x85, 0x23, 0x95, 0x15, 0xd9, 0x3a, 0xd1, 0x47, 0x38, 0xc1, 0xcf, 0x0e, 0x07, 0xc0, 0xf8, 0x1c, + 0x39, 0x7b, 0xbd, 0x31, 0xda, 0xb7, 0x54, 0xc7, 0xce, 0x1a, 0xf3, 0x62, 0x6d, 0xf2, 0x33, 0x4e, + 0x0c, 0x84, 0x04, 0x14, 0xd1, 0x3b, 0x42, 0xb2, 0x11, 0x3a, 0x3a, 0x48, 0x95, 0xc1, 0x29, 0xfe, + 0x5d, 0xd7, 0x8e, 0xf7, 0x59, 0x1a, 0x16, 0x2a, 0x00, 0x00, 0x00, 0x5c, 0x28, 0x11, 0x53, 0x00, + 0x8c, 0xdc, 0x43, 0x04, 0x31, 0x3f, 0x9d, 0x4a, 0x0b, 0xf6, 0x08, 0xd3, 0x72, 0x9c, 0x3f, 0x79, + 0x25, 0x35, 0x5f, 0x40, 0xdb, 0xae, 0x90, 0xbe, 0x35, 0xf4, 0x76, 0xaa, 0x39, 0xba, 0x07, 0x23, + 0xc6, 0x4c, 0x83, 0xbc, 0xee, 0x94, 0x25, 0x80, 0x2a, 0x8d, 0x1a, 0x7f, 0x80, 0xa7, 0x24, 0x50, + 0x17, 0x5b, 0x24, 0x09, 0xe7, 0x28, 0xf6, 0x9b, 0xcd, 0x57, 0x4f, 0x9c, 0x60, 0xef, 0x16, 0xcc, + 0x16, 0x16, 0x7b, 0x34, 0xc8, 0xe1, 0xf0, 0x88, 0x30, 0xb4, 0xb2, 0xcb, 0x30, 0xc9, 0x44, 0x28, + 0xfa, 0xb3, 0xe0, 0x21, 0x20, 0x00, 0xc0, 0x5a, 0xcb, 0x01, 0x0f, 0x06, 0x34, 0x67, 0x8e, 0xf8, + 0x7c, 0x1f, 0x80, 0xfe, 0x07, 0xc0, 0xf8, 0x32, 0xcb, 0x21, 0x8b, 0x97, 0x59, 0x0a, 0x06, 0x3a, + 0xb0, 0xd2, 0xc2, 0xb5, 0xa3, 0xc7, 0x39, 0x0e, 0x03, 0xf4, 0xb2, 0xef, 0x07, 0xda, 0xb6, 0xfd, + 0xfa, 0x68, 0xc1, 0x01, 0xe1, 0x5a, 0x65, 0xe7, 0x5b, 0x3a, 0xf3, 0x1a, 0xe7, 0x68, 0xda, 0xb9, + 0x19, 0x4d, 0xb4, 0xd8, 0x9f, 0x2d, 0x49, 0xba, 0x8c, 0x34, 0x95, 0x40, 0x35, 0x86, 0xfc, 0xd1, + 0x25, 0x6c, 0x90, 0x81, 0xd5, 0x1c, 0xb9, 0xb7, 0xfa, 0x6e, 0x47, 0xd5, 0xbc, 0x83, 0xcf, 0xdb, + 0x58, 0x54, 0x41, 0xf5, 0x28, 0xe2, 0x40, 0x72, 0x7c, 0x19, 0x98, 0x54, 0xe7, 0x07, 0x9c, 0xfe, + 0x10, 0xe5, 0xd3, 0x45, 0xaf, 0x2c, 0x05, 0x07, 0xe7, 0xca, 0x90, 0x28, 0xe4, 0xb0, 0x44, 0x99, + 0x7a, 0x8a, 0xf2, 0x71, 0x8e, 0x64, 0x8a, 0xf4, 0x21, 0xc0, 0x90, 0x53, 0x7e, 0x78, 0x12, 0x1c, + 0x5b, 0x21, 0x8b, 0x97, 0x59, 0x1a, 0x16, 0x2a, 0xaf, 0xde, 0xcb, 0xf9, 0xc9, 0x12, 0x54, 0xc3, + 0xb6, 0xbf, 0xc6, 0xdd, 0x33, 0xef, 0x43, 0xbb, 0x3f, 0x61, 0x00, 0xdf, 0x78, 0x66, 0x7c, 0x52, + 0x78, 0x22, 0x5a, 0x11, 0x2f, 0xa6, 0x2d, 0x29, 0xd3, 0xf5, 0x2b, 0x54, 0x7d, 0x23, 0xc3, 0x14, + 0x17, 0x5c, 0x47, 0x14, 0x3e, 0x40, 0xf9, 0x87, 0x56, 0x0b, 0x97, 0x3a, 0xa9, 0x71, 0x0f, 0x84, + 0xee, 0xa0, 0xa0, 0xc2, 0xc3, 0xf3, 0x10, 0xbc, 0xa1, 0x1b, 0x7b, 0xcd, 0x21, 0x87, 0x66, 0x05, + 0x87, 0x9e, 0x18, 0x7b, 0x33, 0x26, 0x7c, 0xc5, 0x42, 0xe2, 0x04, 0x2c, 0xfc, 0xd2, 0xcc, 0x09, + 0x39, 0xa3, 0x8c, 0x74, 0xda, 0xc6, 0x4b, 0xa6, 0x53, 0xda, 0xc2, 0x51, 0x5f, 0x77, 0x6a, 0x14, + 0x75, 0x95, 0xe7, 0x9c, 0x0a, 0x26, 0x59, 0x81, 0xdb, 0x21, 0x8b, 0x97, 0x59, 0x1a, 0x26, 0x32, + 0xaf, 0xde, 0xcb, 0xf9, 0xd9, 0x8b, 0x32, 0x47, 0x46, 0x01, 0xfe, 0xdc, 0xee, 0xca, 0xbb, 0x21, + 0xe2, 0x27, 0xf6, 0xc0, 0x74, 0x81, 0xd9, 0xaa, 0xab, 0xf8, 0x70, 0x9d, 0x8d, 0x88, 0xd7, 0x08, + 0x4b, 0x17, 0x2f, 0xd9, 0xa6, 0xe0, 0x2f, 0x93, 0x48, 0xf7, 0x33, 0xb2, 0xb3, 0x2d, 0x19, 0x18, + 0x12, 0xfd, 0x31, 0xb8, 0xcc, 0xfe, 0x64, 0x87, 0x69, 0xdc, 0xe4, 0x5c, 0x65, 0xe5, 0x77, 0xb0, + 0x68, 0xb0, 0x06, 0xb4, 0x3b, 0x59, 0x19, 0x83, 0x3c, 0x38, 0x3c, 0x3c, 0x38, 0x78, 0x83, 0x61, + 0xd0, 0x31, 0x81, 0x97, 0x03, 0xb8, 0xef, 0x01, 0x15, 0x40, 0x82, 0xed, 0x8b, 0x08, 0x4f, 0x71, + 0x32, 0xf5, 0xc9, 0x29, 0x1b, 0x2b, 0xac, 0x4c, 0x10, 0x70, 0xa7, 0x97, 0x07, 0x0e, 0x49, 0xe3, + 0xdb, 0x21, 0x4b, 0x97, 0x59, 0x1a, 0x26, 0x12, 0xae, 0xec, 0x11, 0x26, 0xe8, 0x37, 0x92, 0x31, + 0xe5, 0x7f, 0x28, 0xd9, 0x53, 0x25, 0xa2, 0x66, 0x43, 0xcd, 0x52, 0x54, 0x1d, 0x5b, 0xc6, 0x8a, + 0x80, 0xb8, 0x1c, 0x95, 0x07, 0xbc, 0xd0, 0x16, 0xe2, 0x9d, 0x9e, 0x69, 0x70, 0x19, 0xe3, 0x82, + 0x2c, 0xb5, 0x68, 0xe8, 0x7d, 0x89, 0x1a, 0xcd, 0x5a, 0x2e, 0x31, 0x6a, 0x09, 0x5b, 0xb5, 0x65, + 0x8b, 0xd3, 0x84, 0x69, 0xae, 0xaa, 0xd1, 0xbf, 0x98, 0x54, 0x1f, 0xbe, 0x56, 0xfe, 0x6c, 0x38, + 0x47, 0x8f, 0x73, 0x0c, 0xc7, 0xe0, 0x43, 0x58, 0x7e, 0xba, 0xbf, 0x42, 0x48, 0xe0, 0x02, 0xaa, + 0x07, 0x30, 0xfe, 0x2f, 0xcb, 0xc4, 0xd0, 0xd8, 0x90, 0xf7, 0xab, 0x12, 0xee, 0x44, 0x87, 0x70, + 0x74, 0xa0, 0x63, 0xfb, 0xc1, 0xe2, 0x6c, 0x9e, 0x5b, 0x21, 0x8b, 0x97, 0x59, 0x19, 0xf6, 0x2a, + 0xaf, 0xa6, 0xc8, 0x17, 0x83, 0x85, 0xb2, 0x00, 0x04, 0x26, 0x17, 0x1b, 0xb0, 0x82, 0x3d, 0x92, + 0x55, 0x92, 0x2c, 0xcb, 0x67, 0x59, 0x5d, 0xa4, 0x57, 0xb5, 0xf4, 0x0b, 0xcd, 0x2d, 0x28, 0x50, + 0x40, 0x15, 0x90, 0x80, 0x09, 0xb6, 0x09, 0x0b, 0x90, 0x65, 0xdb, 0xc6, 0xf1, 0x86, 0xd9, 0x38, + 0xd8, 0xa2, 0x03, 0x25, 0xc0, 0x97, 0x38, 0x86, 0xfd, 0x86, 0x46, 0x1a, 0xb9, 0xce, 0xa9, 0x5e, + 0xb6, 0xa4, 0x22, 0x2f, 0x9a, 0x86, 0x38, 0xc2, 0x7b, 0x9e, 0x78, 0x3c, 0x1e, 0x1c, 0x1f, 0x07, + 0x1a, 0x08, 0x32, 0x5b, 0x03, 0x89, 0x1d, 0x5b, 0x9f, 0x94, 0x9e, 0x97, 0xde, 0x51, 0xf2, 0x0d, + 0x17, 0xe9, 0x94, 0xa7, 0xfd, 0x5e, 0xea, 0x1d, 0xe2, 0xa8, 0x0b, 0xc0, 0xc2, 0x00, 0xc1, 0xec, + 0x4b, 0x21, 0x4b, 0x97, 0x59, 0x1a, 0x06, 0x1a, 0xaf, 0xde, 0xcb, 0xf9, 0xbd, 0x13, 0x73, 0x0c, + 0x76, 0x0e, 0x78, 0x17, 0x02, 0x17, 0xd2, 0xd1, 0x02, 0xfc, 0x16, 0xa1, 0x3f, 0x01, 0x7d, 0x07, + 0x4a, 0xc9, 0x36, 0x24, 0x45, 0xff, 0xd4, 0x75, 0x8f, 0x51, 0x98, 0xd1, 0x81, 0x98, 0x2a, 0x87, + 0xdc, 0x6f, 0xb8, 0x72, 0xcc, 0x0f, 0x1f, 0xd1, 0x7b, 0x47, 0x57, 0xe5, 0xd0, 0x37, 0xa1, 0x06, + 0x28, 0x7d, 0x54, 0xeb, 0xca, 0x35, 0xc5, 0x77, 0x08, 0x7a, 0x5b, 0x8e, 0x13, 0x60, 0x93, 0x27, + 0x12, 0x38, 0x61, 0xe7, 0x8f, 0xe2, 0x86, 0x8d, 0x73, 0x04, 0x06, 0xf8, 0xb1, 0x98, 0xe6, 0x3a, + 0x4c, 0x2f, 0x31, 0x97, 0x5d, 0x3d, 0xda, 0xb8, 0xc3, 0x38, 0x03, 0xc6, 0xe1, 0x67, 0x68, 0x23, + 0x75, 0x64, 0x4a, 0x24, 0x80, 0x0c, 0x38, 0x26, 0x5b, 0x21, 0x4b, 0x97, 0x59, 0x19, 0xe6, 0x12, + 0xb0, 0xdc, 0x58, 0x39, 0x3d, 0x8b, 0x23, 0x72, 0x96, 0x1a, 0x93, 0x6a, 0x4f, 0xce, 0x7c, 0x61, + 0x4b, 0xec, 0xc2, 0xd4, 0x2b, 0xbc, 0xbe, 0x07, 0xc6, 0xe1, 0x67, 0x09, 0xbc, 0x3f, 0x3a, 0x43, + 0x0e, 0xc1, 0x55, 0x4e, 0xe1, 0x45, 0xf2, 0x9d, 0x7a, 0x6c, 0x8a, 0x15, 0x85, 0x68, 0xb5, 0x9e, + 0xe4, 0x21, 0xc2, 0x5c, 0x9a, 0x7f, 0xfd, 0x12, 0x4d, 0xdb, 0x57, 0x4a, 0x82, 0x57, 0xf1, 0x15, + 0x9e, 0x9b, 0xa3, 0xeb, 0xf2, 0x9a, 0x16, 0xc3, 0x65, 0x38, 0xe7, 0x38, 0x60, 0xe0, 0xff, 0x5e, + 0xdd, 0x32, 0xfb, 0x28, 0x6a, 0xf7, 0x4e, 0x4c, 0x5e, 0x78, 0x82, 0x5a, 0x6e, 0x9f, 0x99, 0xbf, + 0x21, 0x3f, 0x87, 0x94, 0xf0, 0x70, 0x7c, 0xc9, 0x0e, 0x2b, 0x4c, 0x63, 0x83, 0xce, 0x97, 0xc3, + 0xdb, 0x21, 0x4b, 0x97, 0x59, 0x1a, 0x06, 0x32, 0xb0, 0xdc, 0xac, 0xc2, 0x74, 0xa1, 0x3d, 0x48, + 0x3a, 0x03, 0x09, 0x80, 0x9b, 0x70, 0x44, 0x4f, 0xeb, 0x7d, 0xc6, 0xa5, 0x9f, 0xd8, 0xad, 0x96, + 0x2b, 0xbf, 0x90, 0x15, 0x58, 0x86, 0x2c, 0xec, 0xd1, 0x0a, 0xa1, 0xe6, 0x4e, 0x6a, 0xf4, 0x93, + 0x3e, 0x8c, 0xf0, 0x79, 0x70, 0x49, 0xa2, 0x36, 0x54, 0x72, 0xaf, 0x3f, 0xcd, 0x73, 0xf0, 0x0e, + 0x8c, 0x0f, 0xf0, 0xbc, 0xfe, 0xcf, 0x1e, 0xc7, 0x10, 0xf2, 0x8a, 0x7d, 0xf0, 0xe5, 0x4b, 0x27, + 0x1e, 0x0e, 0x18, 0x0f, 0xea, 0xd8, 0xb6, 0x07, 0x4a, 0x5f, 0xdf, 0x0c, 0x9b, 0x3d, 0xc2, 0x1a, + 0x6f, 0x80, 0xe1, 0x9e, 0xea, 0x44, 0xe5, 0x60, 0x48, 0xb2, 0x83, 0xa4, 0x3c, 0xd6, 0xce, 0xc0, + 0xe6, 0x64, 0xef, 0x11, 0xcf, 0x07, 0x98, 0x63, 0xd3, 0xbf, 0xd0, 0x17, 0x59, 0x19, 0xe6, 0x0a, + 0xaf, 0xa6, 0xca, 0x13, 0xf8, 0x16, 0xcc, 0x00, 0x2e, 0x16, 0x74, 0x2c, 0x96, 0x75, 0x81, 0xc1, + 0x54, 0x0f, 0xd8, 0x5f, 0x66, 0x50, 0xed, 0x38, 0xbc, 0x76, 0xb2, 0x05, 0x47, 0x58, 0xa7, 0xdc, + 0x28, 0x22, 0x37, 0xba, 0x80, 0xc1, 0xce, 0xfc, 0xc3, 0x01, 0xf5, 0xa7, 0x48, 0x74, 0x2b, 0x7a, + 0xf6, 0x3c, 0xed, 0xd3, 0x7a, 0xf7, 0xcf, 0xcd, 0x5a, 0x3a, 0xe2, 0xe7, 0x4a, 0x9e, 0xb8, 0x20, + 0x26, 0x3c, 0xc9, 0x42, 0x4f, 0x84, 0xde, 0x70, 0xe3, 0xe1, 0xf0, 0x7c, 0x1f, 0xf0, 0x08, 0x2b, + 0x86, 0x18, 0x8d, 0x41, 0x97, 0x22, 0x64, 0xd0, 0xe4, 0xf9, 0x77, 0xcc, 0x4d, 0x27, 0x79, 0x60, + 0x8d, 0x40, 0x8f, 0x8e, 0x03, 0x73, 0xd1, 0xe6, 0x27, 0x1f, 0x34, 0xfc, 0x58, 0x09, 0x9e, 0x33, + 0x53, 0xbf, 0xd0, 0x17, 0x59, 0x19, 0xd6, 0x0a, 0xae, 0xec, 0x11, 0x26, 0xb9, 0x70, 0xd6, 0x00, + 0x1d, 0xb3, 0x75, 0x85, 0x2c, 0xf6, 0x85, 0xce, 0x68, 0x9f, 0xd0, 0x02, 0xde, 0x6d, 0xd0, 0xae, + 0x0f, 0x3a, 0x8d, 0x29, 0xf0, 0x62, 0x61, 0x80, 0x25, 0x49, 0x49, 0xcd, 0xa5, 0xad, 0x6e, 0xdb, + 0xb5, 0x0f, 0x50, 0x45, 0x12, 0xb1, 0xae, 0x86, 0xe6, 0xe5, 0x5f, 0x0c, 0x95, 0x17, 0x24, 0xd3, + 0xd6, 0x45, 0x8e, 0x4c, 0x28, 0x38, 0x20, 0xfc, 0x96, 0xea, 0x05, 0xe4, 0x13, 0xd8, 0x90, 0xdc, + 0x31, 0xc3, 0x83, 0xc1, 0xf0, 0xf0, 0xbf, 0x1b, 0x6a, 0x44, 0x76, 0xe5, 0xfd, 0xdf, 0x14, 0xcf, + 0xe3, 0x43, 0x50, 0xa4, 0xe2, 0x8e, 0x4c, 0x46, 0x7a, 0x15, 0xb5, 0xc8, 0x1c, 0xd3, 0x39, 0x23, + 0x21, 0x67, 0x9a, 0xae, 0xf4, 0x0e, 0x19, 0x99, 0xd3, 0xbf, 0xd0, 0x17, 0x59, 0x19, 0xc6, 0x1a, + 0xb0, 0xd3, 0x95, 0x9c, 0x58, 0x00, 0x00, 0x00, 0xf5, 0x3c, 0x01, 0xbc, 0x50, 0x4b, 0x8a, 0x3b, + 0xbe, 0xb0, 0x2c, 0xd8, 0x89, 0x14, 0x24, 0xd0, 0xeb, 0x2b, 0x46, 0x10, 0x67, 0x88, 0xd3, 0xd3, + 0xda, 0x0f, 0x5c, 0x59, 0x59, 0x2c, 0x25, 0x0f, 0x4c, 0x65, 0x0a, 0x9b, 0x0a, 0x21, 0xef, 0xdc, + 0x43, 0xe3, 0x91, 0xf6, 0x38, 0x2d, 0x60, 0xfe, 0x48, 0xec, 0xff, 0x1b, 0xac, 0x69, 0x69, 0x14, + 0x84, 0x18, 0x2d, 0xfb, 0x0d, 0xe8, 0x64, 0xaa, 0x27, 0x87, 0xc7, 0x87, 0xc7, 0xfc, 0x93, 0x00, + 0x84, 0x46, 0xae, 0xd8, 0xb5, 0x8d, 0x59, 0x05, 0xca, 0xd3, 0x74, 0xc9, 0xc5, 0xfb, 0x9c, 0x69, + 0x49, 0xcc, 0xb9, 0xa2, 0x46, 0xca, 0x20, 0xd8, 0xdb, 0xfa, 0xf7, 0xe1, 0x84, 0x8e, 0x35, 0x40, + 0x03, 0xbf, 0xd0, 0x17, 0x59, 0x39, 0xc6, 0x3a, 0xaf, 0xdd, 0x49, 0xd0, 0x58, 0x01, 0x68, 0x7b, + 0x15, 0x25, 0xbc, 0xbd, 0x68, 0xca, 0x4a, 0xaa, 0x1e, 0x7c, 0xca, 0x07, 0xf0, 0x8b, 0xe2, 0x53, + 0xa1, 0xba, 0xcf, 0x90, 0xae, 0xec, 0x67, 0xd5, 0x18, 0xc8, 0xe7, 0xcf, 0xdf, 0x2a, 0x54, 0xef, + 0x84, 0x3c, 0x94, 0x02, 0xc3, 0xc2, 0x71, 0x3b, 0x0e, 0xc5, 0xa1, 0x6d, 0x0a, 0xb9, 0x20, 0xad, + 0xfa, 0xff, 0x3f, 0x40, 0xcf, 0x3a, 0x78, 0x7f, 0x3c, 0xd9, 0x35, 0x70, 0xe3, 0x33, 0xb3, 0x83, + 0xe0, 0xfc, 0x0f, 0xc0, 0xfc, 0x1f, 0x00, 0x73, 0x1f, 0x5f, 0xd1, 0xc7, 0x12, 0x2f, 0xa6, 0x64, + 0x53, 0xbe, 0xe4, 0x8c, 0x0d, 0x97, 0x0f, 0xcd, 0xb3, 0xd2, 0x58, 0xb6, 0xba, 0x18, 0xb8, 0x62, + 0x78, 0x32, 0x88, 0x44, 0x2a, 0xf3, 0x33, 0x33, 0xdb, 0x21, 0x37, 0x97, 0x59, 0x19, 0xf5, 0xca, + 0xaf, 0xdd, 0x49, 0xcf, 0xc5, 0x1e, 0x8a, 0xa2, 0x00, 0xf6, 0x9a, 0xa4, 0x8c, 0x5f, 0xa2, 0x92, + 0x0a, 0x8c, 0x05, 0x2a, 0x5b, 0x3d, 0x0c, 0x7a, 0x22, 0xeb, 0xb9, 0x07, 0xe0, 0x57, 0xc1, 0xd5, + 0x2e, 0x6a, 0x68, 0x8d, 0xcb, 0xd0, 0x32, 0xc8, 0x4a, 0x3f, 0x86, 0x21, 0xc9, 0x08, 0x97, 0x21, + 0x27, 0xa9, 0xb0, 0x38, 0xa1, 0xf3, 0xdd, 0xf5, 0xca, 0x95, 0xab, 0xe6, 0xa9, 0xed, 0x72, 0x36, + 0x30, 0xd1, 0x6f, 0x53, 0xdb, 0xb4, 0x39, 0x64, 0xcc, 0xe3, 0xe0, 0xf8, 0x3c, 0x1e, 0x00, 0x5c, + 0xec, 0xbe, 0xee, 0x62, 0xee, 0x30, 0x47, 0x27, 0x12, 0x4c, 0x50, 0xb1, 0x4b, 0xee, 0xe4, 0x74, + 0x51, 0xf6, 0x91, 0x68, 0xee, 0x17, 0x12, 0xa6, 0xed, 0xdb, 0x20, 0xe8, 0x25, 0xec, 0x72, 0xc9, + 0xdb, 0x21, 0x37, 0x97, 0x59, 0x19, 0xf5, 0x8a, 0xaf, 0xa6, 0xc8, 0x17, 0x7f, 0x81, 0x39, 0x12, + 0x00, 0x8c, 0x3f, 0xc9, 0x35, 0x8a, 0x38, 0x56, 0xa2, 0xee, 0xa0, 0x6a, 0x00, 0x15, 0xde, 0x4d, + 0xd3, 0xca, 0xd3, 0x0a, 0x6e, 0xcd, 0x17, 0xcf, 0x7e, 0x26, 0xde, 0x16, 0x06, 0xdf, 0x37, 0x99, + 0x56, 0xf8, 0x09, 0xf0, 0x77, 0x96, 0xe7, 0xd9, 0x35, 0xf0, 0x67, 0xfa, 0x28, 0x1f, 0x04, 0xa7, + 0x80, 0x95, 0x55, 0xfa, 0xd0, 0x3f, 0x07, 0x1c, 0x82, 0x18, 0x34, 0x74, 0x9c, 0x1e, 0x3c, 0x1f, + 0x07, 0xc0, 0xfe, 0x07, 0xe0, 0xe7, 0x99, 0xdc, 0x6f, 0x24, 0xe4, 0x59, 0xd0, 0x63, 0x86, 0xe2, + 0x7a, 0xa0, 0xa2, 0x48, 0x62, 0x54, 0xff, 0x81, 0x25, 0x64, 0xb8, 0x1f, 0xa0, 0xd6, 0x5c, 0x0b, + 0x23, 0xee, 0xbe, 0x8f, 0x2e, 0xdb, 0x86, 0x41, 0xdb, 0x21, 0x37, 0x97, 0x59, 0x19, 0xe5, 0x7a, + 0xaf, 0xa6, 0xca, 0xa1, 0x55, 0xbe, 0xff, 0xdc, 0x00, 0x04, 0xf7, 0x23, 0x29, 0x46, 0xf6, 0xb4, + 0x53, 0x22, 0x0a, 0x40, 0x7e, 0x6f, 0x58, 0xb9, 0x8c, 0xdb, 0xa1, 0x3c, 0x7b, 0xa5, 0x37, 0xc7, + 0xb3, 0x99, 0xc5, 0x50, 0x17, 0x39, 0x75, 0x8e, 0xb7, 0xfb, 0x7c, 0x3a, 0xd5, 0xa4, 0x7e, 0xd0, + 0x3f, 0xff, 0xe7, 0xb1, 0x37, 0x20, 0x50, 0xf1, 0xb3, 0xef, 0x1b, 0x2f, 0x41, 0x11, 0x82, 0xc1, + 0xa0, 0x6e, 0xdb, 0x4b, 0x76, 0x92, 0x4b, 0x06, 0xb1, 0xc1, 0xf0, 0x7c, 0x0f, 0x83, 0x80, 0x0f, + 0x3f, 0xdd, 0xeb, 0xe5, 0xf6, 0x76, 0x84, 0x46, 0x89, 0x97, 0x5a, 0x4a, 0xa7, 0x01, 0x83, 0xff, + 0x30, 0x0d, 0x1a, 0x37, 0x65, 0xdd, 0x88, 0xa6, 0x32, 0x01, 0x36, 0x2d, 0x96, 0xfb, 0x25, 0xb3, + 0xdb, 0x21, 0x37, 0x97, 0x59, 0x1a, 0x15, 0x6a, 0xaf, 0xdd, 0x47, 0xae, 0x87, 0xb3, 0x6e, 0x00, + 0x2d, 0xd4, 0x97, 0x7a, 0xa6, 0xdf, 0x22, 0x80, 0x85, 0x1b, 0x4f, 0xc2, 0x1f, 0x2c, 0x3c, 0x0b, + 0x5d, 0xbf, 0xc4, 0x84, 0x2b, 0xff, 0x91, 0x11, 0x42, 0x6c, 0xb4, 0xec, 0x24, 0xb7, 0xd3, 0x15, + 0x41, 0xb1, 0x42, 0x15, 0xf2, 0x76, 0x8d, 0x3a, 0x20, 0x9d, 0x6f, 0x84, 0x9f, 0x75, 0x54, 0xe3, + 0x17, 0xbf, 0x03, 0x0f, 0xcb, 0x00, 0xdf, 0x7d, 0x83, 0xeb, 0xa5, 0x5b, 0x09, 0x1c, 0xe3, 0xe0, + 0xf8, 0x0f, 0xc0, 0x7e, 0x07, 0xe1, 0x87, 0x8c, 0x27, 0xc1, 0xfd, 0x79, 0xea, 0xde, 0xdd, 0xa3, + 0x4f, 0xb8, 0x14, 0x51, 0x14, 0xd3, 0x9f, 0x0c, 0x07, 0xa2, 0xaf, 0xcf, 0xb0, 0x5d, 0x13, 0x5a, + 0xa6, 0x97, 0x1a, 0x4c, 0x96, 0x3f, 0xe4, 0x48, 0xdb, 0x21, 0x37, 0x97, 0x59, 0x19, 0xf5, 0x7a, + 0xae, 0xed, 0x18, 0xc3, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x21, 0x1a, 0x23, 0x22, 0x82, + 0xde, 0x56, 0x00, 0x03, 0x39, 0xab, 0x1a, 0x5e, 0x2d, 0x76, 0x3a, 0x8a, 0x3b, 0x7a, 0x9f, 0x90, + 0x8a, 0xba, 0x2c, 0xc0, 0x57, 0xf6, 0x52, 0xbf, 0xc5, 0x90, 0xe2, 0x46, 0x3b, 0x94, 0xfd, 0x1b, + 0x68, 0x50, 0xf6, 0x8c, 0x81, 0x5f, 0x61, 0xa9, 0x06, 0x0a, 0x0b, 0x42, 0x58, 0x0c, 0x8c, 0xfe, + 0x0b, 0xb1, 0x94, 0x78, 0xa0, 0x7e, 0x0f, 0x3c, 0x7c, 0x0f, 0x81, 0xfc, 0x0f, 0xe0, 0xf8, 0xf2, + 0x26, 0x1d, 0x88, 0x44, 0xb8, 0xd3, 0x1d, 0xb4, 0x2b, 0xe8, 0x64, 0x42, 0xb7, 0x2c, 0x72, 0x7d, + 0x93, 0x77, 0xa6, 0xc5, 0x1e, 0x26, 0xfb, 0x7e, 0x40, 0xdf, 0xd0, 0xd5, 0xf4, 0xe7, 0x80, 0xe0, + 0x5b, 0x21, 0x37, 0x97, 0x59, 0x19, 0xf5, 0xd2, 0xae, 0xed, 0x18, 0xc3, 0x34, 0x00, 0x00, 0x00, + 0x0e, 0xd4, 0xbc, 0x15, 0xaa, 0xb6, 0x06, 0x47, 0x8d, 0x6e, 0x00, 0x57, 0x6b, 0xa6, 0xed, 0xff, + 0xdf, 0xc2, 0x48, 0x94, 0x1a, 0xbb, 0xb6, 0xb7, 0x18, 0xd1, 0x28, 0xac, 0x2e, 0x52, 0x81, 0xc1, + 0xa9, 0xa0, 0x62, 0x11, 0xeb, 0xf2, 0xdf, 0xb5, 0xb9, 0x5e, 0xd4, 0x85, 0x94, 0x5a, 0x46, 0xe4, + 0xde, 0x7e, 0xdb, 0x7b, 0xe1, 0x37, 0x57, 0x31, 0x46, 0xd4, 0x02, 0xca, 0x34, 0xe1, 0xfc, 0x70, + 0xf0, 0x3f, 0x01, 0xf0, 0x3e, 0x07, 0x9f, 0x21, 0xd3, 0x9c, 0x19, 0xb1, 0x91, 0x52, 0xbf, 0xf7, + 0xbb, 0x6e, 0xf1, 0x68, 0x99, 0xec, 0x8c, 0x3a, 0x2d, 0x5f, 0x1a, 0x16, 0xaa, 0x97, 0xa7, 0xad, + 0xfd, 0x72, 0x17, 0x32, 0x6f, 0x42, 0xd4, 0x0f, 0xcb, 0x21, 0x37, 0x97, 0x59, 0x19, 0xf5, 0xda, + 0xae, 0xec, 0x0f, 0xb3, 0x42, 0x12, 0xd3, 0x00, 0x00, 0x00, 0xdc, 0x94, 0x9d, 0x84, 0xb1, 0xa5, + 0x70, 0x6a, 0xdb, 0xef, 0x0a, 0xe3, 0xcb, 0x15, 0x2e, 0xb4, 0x56, 0x8f, 0xbd, 0x51, 0xc2, 0x83, + 0x91, 0xa7, 0x98, 0xc0, 0xf5, 0xee, 0xdb, 0x79, 0x1d, 0xb2, 0x13, 0x9d, 0x23, 0x3c, 0xaa, 0x66, + 0x7e, 0x45, 0x17, 0xf3, 0x2c, 0x5f, 0x2c, 0x3b, 0x5d, 0xa5, 0x8a, 0x1c, 0x37, 0x62, 0x8c, 0xaa, + 0x8f, 0x52, 0xa3, 0x35, 0x94, 0x57, 0x34, 0xcd, 0xa6, 0xe4, 0xe1, 0xc3, 0xc3, 0xf8, 0x1f, 0x07, + 0x00, 0x08, 0xe5, 0x13, 0x34, 0x5a, 0x6e, 0x33, 0x24, 0xe6, 0xc1, 0x17, 0xab, 0xfa, 0x52, 0x10, + 0x78, 0x33, 0x95, 0xa6, 0xec, 0x53, 0x1e, 0x72, 0xe2, 0x91, 0x85, 0x51, 0x96, 0x6f, 0x99, 0xa4, + 0xdb, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x06, 0x3a, 0xb0, 0xdc, 0xac, 0x99, 0xfc, 0xa7, 0x25, 0x91, + 0xff, 0x02, 0x20, 0x74, 0x42, 0x2a, 0x7a, 0x0c, 0x09, 0x7f, 0xbf, 0x91, 0x04, 0x4f, 0x0d, 0xe0, + 0xe9, 0xc9, 0xf2, 0x79, 0x05, 0xbc, 0x3c, 0xb1, 0x5d, 0x4b, 0x07, 0xfc, 0xc4, 0xa6, 0x05, 0x94, + 0x12, 0xf3, 0x70, 0xf6, 0x4a, 0xf1, 0x4c, 0x1f, 0x04, 0xe3, 0x43, 0x14, 0xed, 0x08, 0xaa, 0x75, + 0xe0, 0x9d, 0xb4, 0xe2, 0x3b, 0x03, 0xeb, 0x98, 0x58, 0xd1, 0xf1, 0xc0, 0xf6, 0x1a, 0x1e, 0x71, + 0xc1, 0xf0, 0x7f, 0x03, 0xc1, 0xc3, 0x82, 0xb1, 0xdc, 0x01, 0xc1, 0xd3, 0x82, 0x68, 0x7e, 0x1f, + 0xa1, 0xd1, 0x19, 0xa8, 0x64, 0xc8, 0x03, 0x1b, 0x0f, 0x1d, 0x3b, 0x85, 0xf2, 0x4a, 0x1f, 0xc4, + 0x77, 0x35, 0xc2, 0x0e, 0x3e, 0x44, 0x1b, 0xc9, 0x5b, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x06, 0x0a, + 0xaf, 0xde, 0xcb, 0x94, 0xe0, 0xe7, 0x7a, 0x12, 0x00, 0x00, 0x3b, 0xd0, 0x3d, 0xc1, 0x34, 0x00, + 0x00, 0x25, 0xbc, 0xbe, 0x5e, 0x36, 0xae, 0xc3, 0xf9, 0xb2, 0xec, 0x2f, 0x96, 0x83, 0xd5, 0xaf, + 0xce, 0x9f, 0x73, 0xd2, 0xc1, 0xc4, 0x36, 0x12, 0x01, 0x35, 0xe4, 0x0f, 0x7f, 0x74, 0x91, 0xeb, + 0xec, 0x1c, 0x6e, 0x7d, 0x17, 0x17, 0xd1, 0x8a, 0x02, 0xb0, 0xbb, 0x49, 0x62, 0x7f, 0x96, 0xfd, + 0x74, 0xd9, 0xcf, 0x5b, 0x74, 0x84, 0xc1, 0xb3, 0x3c, 0x70, 0x7c, 0x0f, 0x81, 0xf8, 0x1c, 0x20, + 0xc5, 0xa2, 0x58, 0x94, 0xe3, 0xd8, 0xe3, 0x14, 0xd8, 0x70, 0x08, 0xda, 0x59, 0x77, 0x30, 0x9c, + 0x39, 0x8a, 0x54, 0xce, 0xb1, 0x23, 0x5d, 0x90, 0xbc, 0xe5, 0x2c, 0xb7, 0x25, 0x0f, 0x08, 0x40, + 0xdb, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x16, 0x12, 0xaf, 0xde, 0xcb, 0xe0, 0x87, 0x0d, 0x93, 0x07, + 0x00, 0x04, 0x00, 0x29, 0x9b, 0x99, 0x97, 0x35, 0x52, 0x0d, 0x40, 0x00, 0x00, 0x10, 0x0d, 0x7a, + 0x70, 0x35, 0x2f, 0x80, 0x3c, 0x14, 0xca, 0x10, 0x3f, 0x6a, 0x18, 0x6d, 0x29, 0xa9, 0x72, 0xf6, + 0xbe, 0xd4, 0x19, 0xd1, 0xc4, 0x29, 0x16, 0x24, 0xb3, 0x02, 0xa9, 0x72, 0x9b, 0xe3, 0xe8, 0xdd, + 0x71, 0x5d, 0xb6, 0x83, 0xae, 0x26, 0x28, 0x23, 0xb5, 0x52, 0xad, 0x16, 0x29, 0x84, 0xbf, 0x6a, + 0x3c, 0xae, 0x51, 0x03, 0xe3, 0xe0, 0xf8, 0x3f, 0x07, 0xe1, 0xe6, 0x67, 0xad, 0xc4, 0x79, 0x2e, + 0xfe, 0xc0, 0x72, 0x34, 0xde, 0x5c, 0xc6, 0x5b, 0xc1, 0xcb, 0xb0, 0x38, 0x50, 0x02, 0x89, 0xd4, + 0x18, 0xdf, 0x30, 0x71, 0x56, 0x27, 0xfe, 0x57, 0x5b, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x15, 0xf2, + 0xaf, 0xdd, 0x49, 0xcf, 0xcc, 0xa4, 0x07, 0x3f, 0x00, 0x08, 0xba, 0xea, 0x33, 0x83, 0xf2, 0x1d, + 0x4a, 0xe8, 0x2b, 0x00, 0x26, 0x46, 0xff, 0xc5, 0x59, 0xdc, 0x04, 0x76, 0xc7, 0x1a, 0x70, 0x6c, + 0xb1, 0x71, 0xe6, 0xd7, 0xc3, 0x71, 0xb8, 0x85, 0x8e, 0xf7, 0x24, 0x6f, 0x6d, 0x8b, 0xde, 0x37, + 0xc9, 0x4c, 0x48, 0xd6, 0x0e, 0x2a, 0x29, 0x33, 0x56, 0x9b, 0xcd, 0x28, 0xb4, 0x62, 0x82, 0x9e, + 0x70, 0x2a, 0x16, 0x0e, 0xfb, 0x6c, 0x82, 0x8b, 0x30, 0x71, 0xe1, 0xf8, 0x3f, 0x07, 0xc1, 0xf8, + 0x3b, 0xb8, 0x9b, 0x2f, 0x22, 0x79, 0x7d, 0x71, 0x14, 0x41, 0x6d, 0x70, 0x84, 0x45, 0x44, 0x06, + 0xa4, 0x86, 0xc9, 0x36, 0x7d, 0x80, 0xda, 0xcc, 0xf2, 0xc1, 0x2d, 0x16, 0x31, 0x2e, 0x7a, 0x8e, + 0x5b, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x15, 0xaa, 0xae, 0xec, 0x11, 0x26, 0xb7, 0x2f, 0x3f, 0xb4, + 0xb4, 0x00, 0x6e, 0x1a, 0x2b, 0xc2, 0xbc, 0x22, 0x6e, 0xf3, 0xf2, 0x6b, 0x3d, 0xec, 0x29, 0x95, + 0x53, 0xdd, 0xaa, 0x8c, 0x3d, 0xce, 0x81, 0x97, 0x61, 0x19, 0x2f, 0x5e, 0x13, 0xf1, 0x9c, 0xb6, + 0x3f, 0xcd, 0x77, 0x53, 0xf5, 0x90, 0x47, 0x07, 0xda, 0x9b, 0x63, 0x02, 0x4a, 0x30, 0xff, 0x3a, + 0x76, 0xe8, 0x42, 0x96, 0x6d, 0x1a, 0x64, 0xe4, 0xee, 0x86, 0x6d, 0xeb, 0x05, 0x66, 0x6c, 0xc3, + 0x8f, 0x81, 0xf8, 0x1f, 0x80, 0xfc, 0x1e, 0x07, 0xfe, 0x22, 0xc0, 0x2b, 0x82, 0x22, 0xa5, 0x60, + 0x5e, 0x4f, 0xef, 0x5c, 0x4a, 0xd8, 0x42, 0x5b, 0xca, 0xbc, 0xf0, 0x6b, 0xaa, 0xc3, 0x69, 0x6f, + 0x6b, 0xbe, 0xc8, 0x18, 0x3f, 0x00, 0x19, 0x8d, 0xcb, 0x22, 0x97, 0x17, 0x59, 0x19, 0xd5, 0x8a, + 0xaf, 0xa6, 0xc8, 0x6c, 0x5a, 0x28, 0x8f, 0x78, 0xe5, 0x00, 0x52, 0x7c, 0x34, 0x94, 0xa7, 0x12, + 0x1d, 0x1d, 0x0f, 0x27, 0x84, 0x09, 0xab, 0xd8, 0xc5, 0xf7, 0x69, 0xde, 0xcd, 0xf0, 0xbd, 0x50, + 0xdc, 0x4a, 0x32, 0xc3, 0x92, 0x6c, 0xb5, 0xa8, 0xd2, 0x87, 0x56, 0x5d, 0x57, 0x63, 0x68, 0x13, + 0x24, 0x2f, 0xdd, 0x92, 0x9a, 0xc8, 0x90, 0x83, 0x70, 0x09, 0x77, 0x16, 0xc2, 0x76, 0xb3, 0xe1, + 0xc5, 0xc0, 0x9a, 0x5c, 0x63, 0xe3, 0x9c, 0x3e, 0x1f, 0x07, 0xf0, 0x1f, 0x80, 0xfc, 0x1f, 0x0e, + 0xed, 0x87, 0xf2, 0x17, 0xaf, 0x9d, 0xdc, 0x64, 0x12, 0x56, 0x3e, 0x2c, 0x56, 0xd0, 0xe0, 0x92, + 0x09, 0xd3, 0xc4, 0x6d, 0xca, 0x42, 0x7c, 0x72, 0x29, 0x02, 0xc0, 0x40, 0x04, 0x3f, 0xf6, 0x5f, + 0x5b, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x05, 0x9a, 0xae, 0xec, 0x0f, 0x7b, 0x69, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x41, 0xaf, 0xfc, 0x8a, 0xb4, 0xa6, 0x16, 0xf1, 0x30, 0x4a, 0x32, 0x65, 0x7b, 0xb8, + 0x15, 0x84, 0xe4, 0x15, 0x21, 0x24, 0x8e, 0xdc, 0xbd, 0x52, 0xbf, 0x4d, 0x97, 0x48, 0xff, 0xf2, + 0x35, 0x2f, 0xfc, 0x4c, 0xe2, 0x4b, 0x34, 0x66, 0x4b, 0x5b, 0xcf, 0xbc, 0xa3, 0x22, 0x7b, 0xd7, + 0x8b, 0x5e, 0xc5, 0x3b, 0x1d, 0xca, 0x9b, 0x63, 0x47, 0x36, 0x0c, 0x80, 0x64, 0xec, 0x6d, 0x26, + 0xb8, 0xe3, 0xe3, 0xf0, 0x0f, 0x81, 0xf8, 0x1e, 0x03, 0xbd, 0xe3, 0xe9, 0x7c, 0x73, 0xd5, 0xff, + 0xed, 0x9b, 0xb6, 0xa5, 0xdd, 0x0a, 0xa0, 0x88, 0xf8, 0xad, 0x8f, 0x0a, 0xc5, 0x85, 0x2f, 0x57, + 0x52, 0x60, 0xd9, 0x9f, 0x66, 0xd3, 0x7b, 0xa6, 0xdb, 0x22, 0x97, 0x17, 0x59, 0x19, 0xf5, 0xc2, + 0xaf, 0xde, 0xcb, 0x85, 0xa7, 0x00, 0x00, 0x00, 0x01, 0x55, 0xe8, 0x5f, 0x8a, 0x56, 0xbc, 0x0c, + 0x12, 0x0a, 0x2a, 0x1e, 0xa9, 0xdc, 0x71, 0xef, 0x73, 0xb5, 0x83, 0x0c, 0x00, 0x5a, 0x54, 0xc1, + 0xe2, 0x96, 0x5a, 0xfe, 0xd4, 0x70, 0xb8, 0x8d, 0x0f, 0x9e, 0xdd, 0xad, 0x2d, 0x24, 0x27, 0x8e, + 0xba, 0xe4, 0xfe, 0x43, 0xab, 0x43, 0x7a, 0x80, 0x27, 0x7e, 0x02, 0x55, 0x17, 0x88, 0x51, 0xcb, + 0x8e, 0x29, 0x97, 0x2f, 0x25, 0x2d, 0xd3, 0x54, 0x9e, 0x3c, 0x3e, 0x0f, 0xc0, 0xf8, 0x1f, 0x07, + 0xfc, 0x61, 0x65, 0xc8, 0x2a, 0x81, 0xda, 0x49, 0x4e, 0x23, 0xec, 0x61, 0xb4, 0xb1, 0xb2, 0xf1, + 0x65, 0x61, 0xad, 0x53, 0x22, 0xda, 0x54, 0x33, 0x9b, 0x86, 0xbe, 0x86, 0xb6, 0xa0, 0x06, 0x55, + 0x5b, 0x22, 0x97, 0x17, 0x59, 0x19, 0xe5, 0x9a, 0x69, 0xd4, 0x3b, 0x63, 0x50, 0x77, 0xfb, 0x38, + 0x00, 0x00, 0x14, 0x4a, 0x4e, 0xe5, 0x7e, 0x3d, 0x1b, 0x13, 0x1f, 0x00, 0x28, 0x86, 0x0d, 0x5c, + 0x8f, 0xf8, 0x26, 0xd1, 0x0c, 0xc6, 0x10, 0x54, 0x78, 0xb4, 0xc4, 0xc9, 0x7a, 0xe7, 0xb0, 0xf1, + 0x91, 0xc8, 0x4e, 0x69, 0x0f, 0x4d, 0xd6, 0x43, 0x2b, 0x58, 0x3c, 0x66, 0x06, 0x07, 0x9c, 0x09, + 0xed, 0x1c, 0x1d, 0x0a, 0x74, 0x0d, 0xb6, 0xcf, 0x0e, 0x81, 0x13, 0xdd, 0x35, 0x6b, 0x34, 0x0f, + 0x97, 0xc7, 0x1e, 0x1e, 0x1f, 0x81, 0xf8, 0x3f, 0x07, 0xe1, 0x04, 0xa5, 0xd0, 0xff, 0x03, 0x33, + 0xab, 0xe3, 0xbe, 0xaa, 0x3f, 0xf1, 0x26, 0x29, 0x16, 0x61, 0xf8, 0x67, 0x5e, 0x48, 0x9d, 0x6a, + 0x57, 0x3d, 0xd8, 0xcd, 0x89, 0xe1, 0x97, 0x45, 0xeb, 0x22, 0x97, 0x17, 0x59, 0x39, 0xf5, 0xc2, + 0xae, 0xed, 0x18, 0xc3, 0x35, 0x47, 0xf3, 0x82, 0x00, 0x00, 0x0a, 0x8d, 0xee, 0x0c, 0x3f, 0x00, + 0x00, 0x00, 0x02, 0x78, 0xdb, 0x9b, 0xa0, 0xe1, 0xe2, 0x22, 0xb6, 0x06, 0x3f, 0xbe, 0xc7, 0x5f, + 0x62, 0xb0, 0x15, 0x12, 0xec, 0xcf, 0x7c, 0xf8, 0x92, 0x96, 0x5a, 0x4a, 0xbd, 0xf4, 0xb6, 0xc0, + 0xcd, 0xd6, 0x83, 0x6d, 0xbf, 0x39, 0xae, 0x56, 0x6c, 0xf6, 0x06, 0x1e, 0xe0, 0xe8, 0x78, 0xa1, + 0x50, 0x9b, 0x7f, 0xba, 0xa0, 0xc7, 0xed, 0xfa, 0x03, 0xa9, 0x0c, 0x7c, 0xf8, 0x7c, 0x1f, 0x03, + 0xf0, 0x7e, 0x1e, 0x03, 0x0b, 0x87, 0xe4, 0x16, 0x30, 0x8f, 0x2f, 0xf4, 0x6d, 0x82, 0xd1, 0x5e, + 0xd9, 0x3a, 0xe5, 0x38, 0x99, 0x56, 0xe7, 0x76, 0x89, 0x6c, 0x8c, 0x0a, 0x4c, 0xf1, 0x9f, 0x8e, + 0xcb, 0x23, 0x63, 0x97, 0x59, 0x19, 0xe6, 0x32, 0xaf, 0xe4, 0xc5, 0x79, 0xc2, 0x5a, 0xff, 0x30, + 0x6b, 0x09, 0x2f, 0xdb, 0x49, 0x80, 0xa7, 0xdc, 0xb8, 0x00, 0x00, 0x00, 0x0a, 0xb2, 0x5f, 0x67, + 0x82, 0x1a, 0x72, 0xdf, 0xfc, 0x95, 0xe3, 0xa4, 0xcf, 0xa3, 0x4e, 0x2b, 0x05, 0x71, 0x98, 0x3b, + 0x08, 0xcc, 0xd8, 0xe0, 0xa3, 0x34, 0xf9, 0xa9, 0xfd, 0xeb, 0xea, 0xfc, 0x18, 0xb7, 0x98, 0x1a, + 0x74, 0x61, 0xb8, 0xc6, 0xf9, 0x99, 0x25, 0x7d, 0x6b, 0xfd, 0xbf, 0x91, 0x58, 0xef, 0x0d, 0x14, + 0xce, 0x61, 0xc0, 0xfe, 0x07, 0xc0, 0xf8, 0x3e, 0x1f, 0xc8, 0xa0, 0x38, 0x93, 0x48, 0x9e, 0x2f, + 0x32, 0x57, 0x4f, 0x26, 0x9f, 0x8e, 0x99, 0xe5, 0x02, 0xa4, 0x48, 0x5a, 0x3d, 0xf7, 0xe5, 0x54, + 0x79, 0x3b, 0xae, 0xcf, 0x6c, 0x5d, 0x20, 0x8a, 0x5b, 0x23, 0x63, 0x97, 0x59, 0x1a, 0x06, 0x0a, + 0xaf, 0x07, 0x59, 0x7c, 0x19, 0x03, 0xa9, 0x3c, 0x00, 0x14, 0x24, 0x32, 0xde, 0x23, 0x1e, 0x64, + 0x00, 0x00, 0x00, 0x02, 0x78, 0x2b, 0x20, 0xce, 0x2f, 0x68, 0xf5, 0xbf, 0x05, 0xeb, 0x26, 0x55, + 0x29, 0x53, 0x4c, 0x7e, 0x61, 0xf9, 0xad, 0x8f, 0xc2, 0x8a, 0x41, 0x34, 0x8d, 0xc9, 0x28, 0xc6, + 0xf8, 0x8b, 0x08, 0xa3, 0xd4, 0x35, 0x7a, 0x7e, 0x53, 0xa0, 0x52, 0x5d, 0x56, 0xd6, 0xd1, 0xdf, + 0xc9, 0xc4, 0x58, 0x68, 0x78, 0x86, 0xf0, 0xa8, 0x62, 0x31, 0x98, 0xf0, 0xe0, 0xf8, 0x3c, 0x1f, + 0x87, 0x8f, 0x00, 0x18, 0x31, 0x02, 0x8c, 0x85, 0xa0, 0xa6, 0x11, 0x2b, 0x61, 0x36, 0xdf, 0x97, + 0xc1, 0x2b, 0x02, 0xba, 0xad, 0xc2, 0x2b, 0xd3, 0x85, 0xe4, 0x28, 0x75, 0xaa, 0xa9, 0x20, 0x72, + 0x5b, 0x23, 0x63, 0x97, 0x59, 0x1a, 0x16, 0x32, 0xaf, 0xde, 0xcb, 0xe0, 0xab, 0x2b, 0xe8, 0xed, + 0x50, 0xe3, 0x86, 0x47, 0xe5, 0x26, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x4f, 0xb5, 0xa6, + 0x0f, 0x22, 0x99, 0x27, 0x10, 0x6e, 0x3f, 0x2c, 0x8c, 0xa3, 0x70, 0xa0, 0x31, 0x5f, 0xec, 0xd2, + 0x6b, 0x19, 0x59, 0x24, 0x59, 0x31, 0xe6, 0x5c, 0x7b, 0x58, 0x91, 0xf2, 0x1f, 0xe5, 0xef, 0xe1, + 0x69, 0x7c, 0x89, 0x15, 0xd6, 0xf0, 0x90, 0x04, 0xf1, 0x1f, 0x4b, 0x6f, 0xd6, 0x20, 0x0e, 0x9b, + 0xf5, 0xb2, 0x26, 0xce, 0x3c, 0x78, 0xf0, 0x7c, 0x1f, 0x81, 0xf8, 0x1e, 0x0c, 0xc3, 0xb7, 0xec, + 0xcd, 0x3f, 0xa9, 0x4d, 0x80, 0x23, 0x7a, 0x9c, 0x52, 0xec, 0x07, 0xb9, 0xcf, 0x14, 0xfe, 0x1d, + 0x31, 0xaf, 0x97, 0xd8, 0x3c, 0xb4, 0xfc, 0x09, 0xdb, 0x23, 0x63, 0x97, 0x59, 0x1a, 0x16, 0x0a, + 0xaf, 0xde, 0xcb, 0xe0, 0x85, 0xa8, 0x27, 0x59, 0x00, 0x01, 0xbf, 0x14, 0x21, 0x94, 0xb6, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4a, 0xbe, 0xff, 0x68, 0x3f, 0x33, 0x88, 0xc8, 0xea, 0x78, 0x68, 0x02, + 0x5d, 0x09, 0x28, 0x00, 0x6d, 0x52, 0x33, 0xaf, 0x64, 0x95, 0x5e, 0xa3, 0xed, 0x4c, 0x68, 0x8f, + 0xef, 0x24, 0x88, 0x45, 0xa1, 0x68, 0x3a, 0x1f, 0x25, 0x2d, 0xe7, 0x52, 0x34, 0xd4, 0x24, 0x55, + 0x52, 0x60, 0x48, 0x63, 0xe2, 0x23, 0x1a, 0xca, 0xce, 0x20, 0xc3, 0x87, 0xc1, 0xf8, 0x7c, 0x0f, + 0x06, 0x07, 0x73, 0x81, 0xec, 0x4e, 0x4d, 0x9d, 0x5d, 0x11, 0xfe, 0xf0, 0x4f, 0x32, 0xa4, 0x6e, + 0xc9, 0xf9, 0x47, 0x2a, 0x54, 0x86, 0x1b, 0xa0, 0xa8, 0x64, 0x9e, 0x07, 0x08, 0x36, 0x1b, 0x8c, + 0xdb, 0x23, 0x63, 0x97, 0x59, 0x1a, 0x26, 0x32, 0xae, 0xec, 0x0f, 0x7b, 0x69, 0x00, 0x00, 0x00, + 0x0b, 0x2e, 0x68, 0x94, 0x87, 0x37, 0x64, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xa8, 0xb0, 0x06, + 0x83, 0x1b, 0x2d, 0x62, 0x14, 0xb3, 0x22, 0xb6, 0x22, 0xa3, 0xf7, 0xbe, 0xd0, 0x7c, 0x75, 0xff, + 0x33, 0xcb, 0x97, 0x1d, 0xd4, 0x6e, 0x8d, 0x22, 0xfc, 0xe0, 0x98, 0xba, 0x9a, 0x65, 0x82, 0x5c, + 0x37, 0xe7, 0xd3, 0xa9, 0xdf, 0x0d, 0x69, 0xaa, 0x27, 0xfa, 0x1d, 0x2c, 0x08, 0x75, 0x0c, 0x7b, + 0x01, 0xee, 0x19, 0xe7, 0x0f, 0x87, 0xc1, 0xf8, 0x1f, 0x0f, 0xe6, 0x7d, 0xeb, 0x69, 0xbb, 0xa6, + 0x5f, 0x9f, 0x6a, 0xb2, 0xba, 0xac, 0x84, 0x14, 0xde, 0xe9, 0x6e, 0xd4, 0x31, 0x9a, 0xf3, 0x32, + 0x22, 0xa5, 0xe2, 0xf6, 0x3e, 0x75, 0xe8, 0x4d, 0x4b, 0x23, 0x63, 0x97, 0x59, 0x19, 0xe5, 0xa2, + 0xb0, 0xdc, 0xac, 0x9f, 0x4f, 0x3a, 0xa2, 0xc7, 0x00, 0x02, 0x30, 0x4e, 0x88, 0x25, 0x1c, 0x25, + 0xa7, 0x3a, 0x72, 0xc3, 0xf3, 0x65, 0xb3, 0x05, 0x32, 0x8d, 0x45, 0x6f, 0xba, 0x21, 0x22, 0xb1, + 0x50, 0xd3, 0xf2, 0x53, 0x0e, 0xba, 0xd5, 0x99, 0x07, 0xfb, 0x5b, 0x93, 0x74, 0x90, 0x08, 0xcc, + 0xd2, 0xd9, 0xd4, 0x91, 0x5f, 0x96, 0xef, 0xcd, 0x06, 0xcf, 0x04, 0x0e, 0xa1, 0x73, 0x54, 0xa3, + 0xdc, 0x55, 0xd4, 0xe3, 0xc8, 0xb9, 0xab, 0xb7, 0xf3, 0x38, 0x1d, 0xb3, 0x34, 0x63, 0xe1, 0xf0, + 0x7c, 0x18, 0x3f, 0x6f, 0xe2, 0xc6, 0x1c, 0xbc, 0xca, 0xbb, 0x19, 0x8e, 0x89, 0x8a, 0x83, 0xfa, + 0x2b, 0xac, 0x1e, 0x7f, 0xc1, 0x06, 0x99, 0x54, 0x84, 0x06, 0x90, 0x3e, 0x9e, 0x17, 0xfe, 0x07, + 0xcb, 0x59, 0x68, 0x27, 0x59, 0x1a, 0x26, 0x3a, 0xaf, 0xdd, 0x47, 0xaf, 0x45, 0x72, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xa8, 0x00, 0x00, 0x84, 0xa0, 0x2f, 0xbe, 0x6a, 0xff, + 0x0b, 0xd8, 0xf2, 0x6f, 0x0a, 0x4d, 0x8b, 0xd4, 0xce, 0x90, 0xa5, 0xbe, 0xcd, 0x84, 0x89, 0xc6, + 0xaa, 0xc2, 0xd7, 0xe0, 0xfc, 0xf4, 0x44, 0xb5, 0x78, 0x7e, 0xd7, 0xdb, 0x9e, 0x7e, 0x18, 0x40, + 0xcf, 0x2a, 0xa8, 0x93, 0xa4, 0x57, 0xc8, 0x26, 0xec, 0x8a, 0x1e, 0xb2, 0x61, 0x89, 0xf2, 0xca, + 0xef, 0xdc, 0x63, 0xc3, 0xe1, 0xf8, 0x0f, 0xc1, 0xe3, 0xe1, 0xbd, 0xd3, 0xfc, 0xee, 0x01, 0x57, + 0xce, 0xa2, 0x20, 0x72, 0xac, 0x90, 0xd7, 0xa3, 0xef, 0x4d, 0x93, 0x3d, 0x65, 0xaa, 0x03, 0xb8, + 0xbd, 0x28, 0x81, 0xa4, 0xcd, 0x81, 0x22, 0x7f, 0xdb, 0x59, 0x68, 0x27, 0x59, 0x1a, 0x06, 0x1a, + 0xb6, 0xaf, 0xa6, 0xa4, 0x0f, 0xc8, 0x00, 0x00, 0x00, 0x8e, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x1f, + 0x89, 0x3f, 0x1e, 0xe4, 0xbd, 0x9e, 0x69, 0xe4, 0xc8, 0x3f, 0xa1, 0x01, 0x8b, 0x3c, 0xd4, 0x7b, + 0xa3, 0x0a, 0x2b, 0xac, 0x9c, 0x76, 0x1a, 0x93, 0x9f, 0x3e, 0xe8, 0x3a, 0x5c, 0x1c, 0x61, 0x84, + 0xe2, 0xe5, 0x2a, 0xb2, 0x1c, 0x19, 0x45, 0x8c, 0xe1, 0x2b, 0x4f, 0xde, 0xc3, 0xfd, 0x59, 0x25, + 0x92, 0x59, 0xc8, 0xef, 0x02, 0xff, 0x86, 0xd5, 0x7e, 0x61, 0x71, 0x9c, 0x3e, 0x1f, 0x07, 0xe0, + 0x7e, 0x1c, 0x61, 0xc4, 0xe7, 0xf9, 0x13, 0xe5, 0x97, 0x8c, 0x19, 0xcf, 0x4b, 0xdd, 0xca, 0xa0, + 0x45, 0xc7, 0x42, 0x81, 0x85, 0xdb, 0x2c, 0x7b, 0x2c, 0x93, 0x4d, 0xbe, 0x0f, 0xab, 0x60, 0x66, + 0x5b, 0x59, 0x68, 0x27, 0x59, 0x1a, 0x05, 0xfa, 0x69, 0x22, 0xde, 0xdd, 0xd2, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0xcd, 0x03, 0xa3, 0x66, 0x74, 0x51, 0x0c, 0xfd, + 0x96, 0x0e, 0xc4, 0xa1, 0xa5, 0x02, 0x16, 0x3e, 0x54, 0xdc, 0x7b, 0xbf, 0xd1, 0x7f, 0x34, 0xe2, + 0xfc, 0x41, 0x33, 0xf9, 0xe8, 0x4c, 0x0a, 0x66, 0xfb, 0x40, 0x24, 0xd7, 0x1a, 0x5e, 0x80, 0xa4, + 0xa8, 0x60, 0x8b, 0x47, 0x99, 0xd3, 0xa4, 0x7c, 0x01, 0x58, 0x1a, 0x51, 0x8b, 0x43, 0xba, 0xb4, + 0x0a, 0x01, 0x31, 0x8f, 0x0f, 0x0f, 0xc0, 0xf8, 0x1f, 0x87, 0x9f, 0x0e, 0x62, 0x3d, 0xe5, 0x1b, + 0x23, 0x29, 0x1b, 0x32, 0x0d, 0x49, 0xc9, 0x8c, 0x2a, 0x31, 0x17, 0x14, 0x1d, 0x7b, 0x26, 0x54, + 0x07, 0x46, 0xb5, 0x00, 0x2f, 0x97, 0x96, 0x00, 0x5b, 0x59, 0x68, 0x27, 0x59, 0x19, 0xf6, 0x32, + 0xaf, 0xdd, 0x4a, 0x8e, 0x8a, 0x00, 0x00, 0x04, 0x16, 0x72, 0x00, 0x00, 0x00, 0x01, 0x3c, 0x65, + 0x00, 0x00, 0x06, 0xc2, 0x8d, 0x61, 0x32, 0xec, 0x63, 0x9f, 0xd5, 0x3b, 0x41, 0x19, 0x48, 0x92, + 0x5b, 0x79, 0xdf, 0x4e, 0xe0, 0x56, 0xab, 0x10, 0xad, 0xb6, 0x70, 0x26, 0xd8, 0x3b, 0x04, 0x1a, + 0x26, 0x3f, 0x1e, 0xfb, 0x61, 0x9b, 0x2c, 0xcd, 0xc3, 0x1a, 0x45, 0xbe, 0x86, 0xb5, 0x80, 0xbf, + 0x58, 0xe5, 0xf1, 0xc4, 0xfa, 0x70, 0xc3, 0x28, 0xe1, 0x66, 0xe6, 0x3e, 0x1f, 0x1f, 0x1f, 0x07, + 0xc1, 0x86, 0x07, 0x3f, 0x01, 0x4a, 0x24, 0x08, 0xb1, 0x9d, 0x34, 0x0f, 0xd4, 0x9a, 0x67, 0xa5, + 0x2c, 0x41, 0xcc, 0xd6, 0xb1, 0x4d, 0xb6, 0x30, 0x9e, 0x87, 0x1b, 0x81, 0x9b, 0x8a, 0x1b, 0x1f, + 0xdb, 0x59, 0x68, 0x27, 0x59, 0x1a, 0x06, 0x2a, 0x69, 0xab, 0xe1, 0x95, 0x02, 0xf7, 0x56, 0xf1, + 0x00, 0x00, 0x6f, 0x0a, 0x1d, 0x00, 0x00, 0x00, 0x85, 0x49, 0x3a, 0xc8, 0xa2, 0xa7, 0xd2, 0x5a, + 0xa9, 0xdf, 0xe8, 0x8c, 0x63, 0x9f, 0xa4, 0x30, 0xad, 0x60, 0xc9, 0xeb, 0x68, 0x08, 0x85, 0xc7, + 0x58, 0x80, 0x08, 0xa1, 0xb6, 0x36, 0xd8, 0xe9, 0x6a, 0x7b, 0x0b, 0xc1, 0xd6, 0x5e, 0x3f, 0x82, + 0x55, 0x55, 0x9c, 0x24, 0x89, 0x0d, 0x17, 0xf5, 0x4e, 0xf7, 0x62, 0x1a, 0x50, 0xb6, 0x11, 0xe5, + 0x96, 0xa1, 0xea, 0xc7, 0xf3, 0xc7, 0x87, 0xc3, 0xe0, 0xf8, 0x3e, 0x0f, 0x1f, 0x71, 0x01, 0x0a, + 0x69, 0x82, 0xa7, 0xe9, 0x15, 0xa2, 0xb7, 0xd0, 0x26, 0x0c, 0x4d, 0x9f, 0xd9, 0x37, 0x1f, 0x09, + 0x3f, 0x68, 0x19, 0xcc, 0xf5, 0xec, 0x70, 0x2b, 0x4b, 0x59, 0x68, 0x27, 0x59, 0x19, 0xe6, 0x3a, + 0xaf, 0xa6, 0xc8, 0x17, 0x7f, 0x00, 0x00, 0x00, 0x17, 0x06, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x90, 0x4d, 0x7e, 0x2d, 0x3b, 0x28, 0x83, 0xe1, 0x07, 0x76, 0x76, 0xcf, 0xba, 0x15, 0x34, + 0xb2, 0x39, 0x94, 0xdb, 0x89, 0xe9, 0x6d, 0x1a, 0xaf, 0xd6, 0x16, 0xa8, 0x64, 0x82, 0xb0, 0x29, + 0x5e, 0x24, 0xdd, 0x6b, 0x36, 0x83, 0xba, 0x3a, 0xf6, 0x36, 0x7a, 0x39, 0xd7, 0x81, 0xb2, 0x27, + 0xaf, 0x4c, 0x76, 0xc9, 0x2d, 0x17, 0x4c, 0x66, 0x99, 0x8d, 0x36, 0x38, 0xf0, 0xf8, 0x1f, 0x83, + 0xe1, 0xe0, 0xf8, 0x50, 0x30, 0xfe, 0x6c, 0x6f, 0x1c, 0x5a, 0x7b, 0x2e, 0x88, 0x59, 0x3b, 0xec, + 0xca, 0xde, 0x54, 0x84, 0xc2, 0x74, 0xc8, 0xa9, 0x40, 0x21, 0x70, 0x1d, 0x4f, 0xb4, 0xea, 0x06, + 0xcb, 0x59, 0x68, 0x27, 0x59, 0x19, 0xf6, 0x0a, 0xaf, 0xdd, 0x47, 0xae, 0x79, 0x00, 0x1f, 0x83, + 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0xdb, 0x11, 0x71, 0xcf, 0xbd, + 0x91, 0x1c, 0x8e, 0xc5, 0x83, 0xc4, 0xe6, 0x94, 0xef, 0x6e, 0x0e, 0x9e, 0x6a, 0x42, 0xa9, 0x2a, + 0x2a, 0xd0, 0x12, 0xae, 0x29, 0x75, 0xa5, 0xbf, 0xd1, 0xa3, 0x08, 0x7e, 0xee, 0xfc, 0xaa, 0x6b, + 0x9e, 0xfa, 0x66, 0x0f, 0x9d, 0xef, 0x40, 0x26, 0xe0, 0x10, 0x37, 0x20, 0x7b, 0x47, 0x23, 0xa4, + 0x2a, 0xb7, 0x61, 0xc7, 0x0f, 0x0f, 0x83, 0xe0, 0x7c, 0x0f, 0x83, 0xc0, 0xfd, 0xbe, 0xb6, 0xff, + 0xfa, 0x50, 0x5b, 0x22, 0x16, 0xc5, 0x40, 0x94, 0x44, 0x34, 0x24, 0x3b, 0xc8, 0xa3, 0x46, 0x42, + 0xa9, 0xf3, 0xb0, 0x22, 0x4b, 0xa8, 0x02, 0x1d, 0x4b, 0x59, 0x68, 0x27, 0x59, 0x19, 0xe6, 0x22, + 0xaf, 0xdd, 0x47, 0x5c, 0xb0, 0x00, 0x00, 0x00, 0x09, 0xa7, 0x33, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x51, 0x3a, 0x47, 0x73, 0x14, 0xdc, 0x14, 0x55, 0x01, 0xad, 0xc9, 0x84, 0xf5, 0x04, 0xca, + 0x57, 0xf3, 0x4d, 0xa5, 0x4e, 0x52, 0x7c, 0x3c, 0xb4, 0xac, 0x71, 0xe4, 0x05, 0x1f, 0x32, 0xd5, + 0x66, 0xee, 0x2e, 0x65, 0x11, 0x2b, 0xf8, 0x17, 0x9f, 0x1c, 0x31, 0xc1, 0x45, 0x92, 0xf7, 0xec, + 0x52, 0x11, 0xaf, 0xf8, 0x38, 0xe2, 0x4f, 0x46, 0x0e, 0xa7, 0x7d, 0x8c, 0x61, 0xe0, 0xf0, 0x1e, + 0x1f, 0x1f, 0x80, 0x20, 0x74, 0x20, 0x33, 0xd0, 0x97, 0xf4, 0x65, 0xe5, 0x0f, 0x72, 0x9a, 0xf8, + 0x6a, 0x30, 0x93, 0x48, 0x44, 0x87, 0x45, 0x57, 0x15, 0x89, 0x56, 0xf2, 0x61, 0x92, 0xcb, 0x2f, + 0x5b, 0x59, 0x68, 0x27, 0x59, 0x19, 0xe6, 0x3a, 0xb0, 0xdc, 0x57, 0x1e, 0x7c, 0x00, 0x00, 0x3f, + 0x74, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x39, 0xc0, 0xa6, 0x1f, 0xdd, 0xdd, 0xf7, + 0x8b, 0x46, 0x51, 0xe9, 0xbf, 0x18, 0x60, 0x29, 0x50, 0x4f, 0x93, 0x93, 0xcd, 0x14, 0x7b, 0x2a, + 0x53, 0x8f, 0xca, 0x5a, 0xa7, 0xe9, 0xb6, 0xb2, 0xa0, 0x81, 0x52, 0x7a, 0x5d, 0x89, 0xfd, 0xde, + 0x59, 0x8a, 0x16, 0xa5, 0xe5, 0x2c, 0x17, 0xb3, 0x89, 0xde, 0x88, 0x0c, 0xd6, 0xbe, 0x89, 0x47, + 0xdd, 0x4d, 0x03, 0xe0, 0x70, 0xf8, 0xf8, 0x7c, 0x3c, 0x78, 0xf7, 0x83, 0xda, 0x69, 0x3e, 0x11, + 0xbc, 0x3f, 0x2e, 0x0e, 0x4e, 0x55, 0x11, 0xdd, 0x4a, 0xd8, 0xd2, 0xbc, 0xe0, 0x9e, 0x70, 0xf9, + 0x06, 0x5c, 0x0d, 0xe9, 0x1a, 0x5c, 0x8a, 0xfd, 0x5b, 0x53, 0xe8, 0xa7, 0x59, 0x1a, 0x36, 0x3a, + 0xb6, 0xae, 0x86, 0x8b, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaf, 0x71, 0xb2, 0x01, 0x10, 0x2f, 0x58, 0xa8, 0xda, 0xb2, 0x6b, 0xea, 0x17, 0x82, 0x2a, 0xbc, + 0x17, 0x6c, 0xb8, 0xd7, 0x60, 0xec, 0xac, 0x27, 0x51, 0x63, 0xbd, 0x84, 0xe8, 0x16, 0x96, 0xd8, + 0x10, 0x67, 0xce, 0x90, 0xe4, 0x82, 0x54, 0x9c, 0xab, 0x44, 0x53, 0x78, 0x5c, 0xb3, 0x3e, 0x1f, + 0xf6, 0x95, 0x2a, 0x8a, 0x8f, 0xed, 0x7d, 0x66, 0x2a, 0xf5, 0xb8, 0xe3, 0xe1, 0xc7, 0xc7, 0x1f, + 0x1e, 0x1e, 0x38, 0xfe, 0x01, 0x07, 0x40, 0x10, 0x17, 0x93, 0xba, 0x8e, 0x86, 0xb0, 0x0f, 0x29, + 0x1f, 0xd8, 0x67, 0x5b, 0x07, 0xb3, 0x8b, 0x89, 0x4e, 0xbe, 0xde, 0xc6, 0xad, 0xf3, 0x18, 0x25, + 0xdb, 0x53, 0xe8, 0xa7, 0x59, 0x19, 0xf6, 0x3a, 0x69, 0xd4, 0x3d, 0x80, 0x5f, 0x44, 0xf0, 0x1b, + 0x03, 0x78, 0x03, 0xdd, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x9c, 0x1f, 0xba, 0x9f, 0x49, 0x68, + 0x95, 0xbb, 0xa2, 0x6e, 0x80, 0xcc, 0x35, 0xdc, 0xff, 0xc9, 0x1f, 0x10, 0x2c, 0xdc, 0x79, 0x16, + 0x99, 0xef, 0xf3, 0xd4, 0x9a, 0x9a, 0x00, 0x44, 0x82, 0x10, 0x10, 0x24, 0x3a, 0xd1, 0x86, 0x0e, + 0x4b, 0xa7, 0xb0, 0x31, 0x0d, 0xbb, 0x79, 0xd0, 0xc0, 0xe9, 0x30, 0xf2, 0x9f, 0xcc, 0x2a, 0x67, + 0xad, 0xec, 0x1e, 0x0f, 0x81, 0xf1, 0xf8, 0x7c, 0x1c, 0x3c, 0x1e, 0x1f, 0x1c, 0x00, 0x02, 0x87, + 0x80, 0xd1, 0x3c, 0xd8, 0x47, 0xbf, 0xc9, 0xec, 0x76, 0x76, 0xe5, 0xcd, 0x14, 0x99, 0x89, 0xe5, + 0x7a, 0xd2, 0x9b, 0x22, 0xc2, 0xc2, 0x13, 0xc3, 0x4b, 0x53, 0xe8, 0xa7, 0x59, 0x19, 0xe6, 0x32, + 0xaf, 0xa6, 0xca, 0x13, 0x93, 0x00, 0xeb, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x80, 0x9d, 0xf7, 0xc3, 0x46, 0x0b, 0x53, 0x53, 0x73, 0x89, 0xc2, 0x97, 0x55, + 0x72, 0x5c, 0xff, 0x9a, 0xdc, 0x02, 0xf7, 0xf0, 0xcf, 0x21, 0x75, 0x66, 0xe6, 0x6c, 0x3b, 0xba, + 0x79, 0x7c, 0xcc, 0x09, 0x13, 0xba, 0xb1, 0x7e, 0x92, 0x48, 0x08, 0xfb, 0xcc, 0x16, 0xb3, 0xbf, + 0x95, 0x42, 0x12, 0x23, 0x7b, 0x8b, 0xc4, 0xa1, 0xe7, 0x05, 0x3f, 0xc7, 0x86, 0x1c, 0x3c, 0x7e, + 0x1f, 0x0f, 0x0f, 0x0c, 0x0f, 0x37, 0xcb, 0xcd, 0x3b, 0x4b, 0x74, 0x4e, 0xa6, 0x1f, 0x4b, 0x8a, + 0x9e, 0xfb, 0x19, 0x56, 0xfd, 0xc8, 0x31, 0x86, 0x38, 0xf0, 0x61, 0xef, 0x30, 0x56, 0x57, 0xb9, + 0xcb, 0x53, 0xe8, 0xa7, 0x59, 0x19, 0xf6, 0x3a, 0xaf, 0xa6, 0xc8, 0x17, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x62, 0x75, 0x00, 0x00, 0x69, 0x8c, 0xb5, 0x9f, 0x6d, 0x91, 0x16, 0xec, 0x45, 0x2d, + 0xd7, 0x21, 0x0a, 0xd3, 0x74, 0x15, 0x95, 0x67, 0x89, 0x8f, 0xb7, 0x07, 0x97, 0xb4, 0x98, 0x68, + 0x61, 0xec, 0x05, 0xc5, 0x91, 0x0b, 0x6f, 0x0f, 0xd6, 0x08, 0xbf, 0x6d, 0x57, 0x68, 0xb3, 0x3e, + 0xd6, 0x22, 0x91, 0x89, 0x3d, 0xd3, 0xcf, 0x0f, 0x02, 0x68, 0x0c, 0xc5, 0xd9, 0x61, 0xb5, 0x6c, + 0xa3, 0x68, 0x38, 0xc3, 0xc3, 0x83, 0xe7, 0x83, 0xc3, 0x8c, 0x1d, 0xc9, 0xc7, 0x32, 0x2b, 0x70, + 0x8e, 0x87, 0x12, 0x53, 0x43, 0x41, 0x24, 0xe9, 0x59, 0x03, 0xa3, 0xc4, 0x4b, 0xf9, 0x63, 0xd3, + 0x86, 0x6f, 0x28, 0x60, 0xe1, 0x17, 0xdb, 0x42, 0x0b, 0x53, 0xe8, 0xa7, 0x59, 0x3a, 0x16, 0x0a, + 0xae, 0xec, 0x11, 0x26, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x40, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xbc, 0x19, 0x14, 0x6e, 0x12, 0xa1, 0x3a, 0xba, 0x04, 0x5e, 0xea, 0x69, 0x8d, + 0xb1, 0x09, 0xf8, 0xfb, 0x64, 0x6a, 0x78, 0x8d, 0x47, 0x40, 0x96, 0x40, 0xa1, 0x65, 0x8c, 0x09, + 0x2a, 0xa1, 0x36, 0x57, 0x11, 0x6e, 0x99, 0x4b, 0x31, 0x58, 0x23, 0x85, 0x8e, 0x38, 0x0f, 0x57, + 0x47, 0xee, 0x44, 0x32, 0x6f, 0x04, 0x5c, 0xbf, 0xd2, 0xf1, 0xf8, 0x3e, 0x1f, 0x03, 0x87, 0x1e, + 0x1f, 0x07, 0x83, 0x8e, 0x1f, 0xfe, 0xe2, 0x0b, 0xe9, 0x36, 0x03, 0xae, 0x74, 0xa7, 0x7f, 0x11, + 0x66, 0xc6, 0x9a, 0xe9, 0xdc, 0x9c, 0x99, 0xba, 0xd6, 0x42, 0xb8, 0x3a, 0x9e, 0x95, 0xee, 0x41, + 0xcb, 0x53, 0xe8, 0xa7, 0x59, 0x19, 0xf6, 0x3a, 0xb0, 0xd2, 0xbf, 0x90, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x01, 0x4f, 0x00, 0x03, 0x1f, 0x9c, 0x00, 0x00, 0x00, 0x24, 0x0d, 0x60, 0x8b, 0x80, + 0x3b, 0x7a, 0x02, 0x8e, 0xea, 0x5e, 0xa6, 0xc9, 0x36, 0x07, 0xac, 0xae, 0x7e, 0x91, 0xd7, 0x6e, + 0xdc, 0xa1, 0x54, 0xc9, 0x75, 0x9c, 0xce, 0x7d, 0x7d, 0x04, 0xc1, 0xd1, 0x71, 0x1c, 0xbf, 0x8c, + 0x27, 0xb8, 0x20, 0xc9, 0xba, 0xa3, 0x8f, 0xfa, 0x44, 0xc3, 0x2f, 0x0a, 0xb3, 0x56, 0xa0, 0xab, + 0x6e, 0x1f, 0xc7, 0x8e, 0x3e, 0x1e, 0xf8, 0xf0, 0xf8, 0x78, 0x70, 0x0f, 0xfe, 0x78, 0x15, 0xb8, + 0xcf, 0x1d, 0xb9, 0x69, 0x24, 0x7a, 0x50, 0x85, 0x62, 0x26, 0xf7, 0x93, 0x2b, 0x00, 0x75, 0x4f, + 0x16, 0xdc, 0x23, 0x06, 0x99, 0xb0, 0x06, 0x1f, 0xdb, 0x53, 0xe8, 0xa7, 0x59, 0x1a, 0x06, 0x32, + 0xaf, 0xde, 0xcb, 0x94, 0xcb, 0x00, 0x12, 0x26, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0xc0, 0x55, 0xea, 0xd5, 0x22, 0xd8, 0x60, 0xe5, 0xa1, 0xab, 0x14, 0x67, + 0x2f, 0x34, 0x1c, 0x63, 0x68, 0xe1, 0x58, 0x09, 0x83, 0x4d, 0x6d, 0x27, 0xaa, 0xa9, 0x2a, 0x23, + 0x93, 0xea, 0x4e, 0x52, 0x55, 0xd3, 0x9e, 0x04, 0xf0, 0x69, 0xa2, 0x55, 0xa1, 0x20, 0x84, 0xe8, + 0xed, 0x95, 0x73, 0x9a, 0x67, 0x25, 0x84, 0xc8, 0x8e, 0x7e, 0x0f, 0x83, 0xf0, 0x78, 0xf0, 0xf3, + 0xc3, 0xc7, 0x04, 0x1d, 0x3a, 0xbf, 0xfe, 0xcd, 0xd6, 0x67, 0xb0, 0xfb, 0x4b, 0x60, 0x83, 0x17, + 0x32, 0x8f, 0x84, 0xcb, 0xf4, 0xe2, 0xec, 0x57, 0xe9, 0xf4, 0xd9, 0x00, 0x50, 0x34, 0xc4, 0x8f, + 0xeb, 0x53, 0xe8, 0xa7, 0x59, 0x1a, 0x26, 0x32, 0xae, 0xec, 0x11, 0x27, 0x19, 0xd0, 0x62, 0x4b, + 0x9f, 0x92, 0x14, 0xbc, 0x07, 0x1c, 0xcd, 0x60, 0x00, 0x3f, 0x57, 0x72, 0x78, 0xb6, 0x2b, 0xb9, + 0x23, 0xf9, 0xf4, 0x88, 0x94, 0xe5, 0xdd, 0x61, 0xef, 0x21, 0x28, 0x38, 0x79, 0x91, 0x0a, 0xcb, + 0x97, 0xa2, 0x5d, 0xa7, 0x18, 0x3b, 0x3a, 0x52, 0xac, 0xfe, 0xc5, 0x69, 0x48, 0x07, 0xf0, 0xa5, + 0xf4, 0x06, 0xed, 0xbb, 0x6c, 0x5a, 0xae, 0x56, 0x4b, 0x1e, 0xf1, 0x21, 0xc2, 0xf6, 0xb5, 0xc8, + 0xfa, 0x2f, 0xa3, 0x9c, 0xe1, 0xe3, 0xe7, 0xb0, 0xb1, 0x50, 0xdc, 0xe2, 0x49, 0x0b, 0x91, 0x08, + 0xdc, 0x4d, 0x8b, 0xf2, 0xb8, 0x83, 0xcc, 0x45, 0x26, 0xb3, 0xc9, 0x08, 0x1c, 0x71, 0xe9, 0x75, + 0xff, 0x16, 0x10, 0x2e, 0x83, 0x32, 0x45, 0xc4, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0xa5, 0xca, + 0x69, 0x22, 0x06, 0xbe, 0xb8, 0x00, 0x00, 0x55, 0x5b, 0xef, 0x00, 0x00, 0x00, 0x65, 0x5b, 0x53, + 0x00, 0x00, 0x00, 0x01, 0xe4, 0x3c, 0x66, 0x44, 0xb7, 0x31, 0x12, 0x8e, 0xf8, 0x46, 0x36, 0x48, + 0xa3, 0x84, 0xae, 0x9a, 0xde, 0xcf, 0xbe, 0x67, 0xa1, 0x24, 0x81, 0xa9, 0x4c, 0xfd, 0x11, 0x1a, + 0xca, 0xbb, 0x75, 0x5e, 0x95, 0x2b, 0xda, 0xc3, 0xd6, 0x2e, 0x7c, 0xc1, 0x9a, 0x98, 0x7a, 0xf9, + 0xe6, 0xb3, 0x4d, 0x7e, 0x50, 0xd3, 0x9c, 0x0e, 0x8d, 0xa1, 0xe2, 0x87, 0xcf, 0xc7, 0xc3, 0xc3, + 0xc0, 0xf0, 0x79, 0xff, 0x33, 0xfa, 0x2b, 0xe2, 0x2e, 0x7c, 0xcd, 0xee, 0x04, 0xd5, 0xae, 0xd3, + 0x49, 0x0a, 0x97, 0x36, 0x42, 0x31, 0xd5, 0xcc, 0xa3, 0xe5, 0x35, 0xcc, 0x6a, 0xe0, 0xfb, 0x61, + 0x5b, 0x53, 0xe8, 0xa7, 0x59, 0x19, 0xe6, 0x22, 0xb0, 0xd2, 0xc2, 0xb5, 0x9b, 0x5e, 0x0d, 0x49, + 0xbb, 0x31, 0x14, 0xd0, 0x16, 0x61, 0xd1, 0x9a, 0x00, 0x16, 0x0e, 0x09, 0x69, 0x56, 0xae, 0x13, + 0x2b, 0x91, 0x7b, 0xe0, 0x64, 0x29, 0xff, 0xfd, 0xdc, 0x02, 0x5e, 0xde, 0xc4, 0x61, 0x77, 0x7b, + 0xe0, 0xe9, 0xcf, 0xeb, 0x5e, 0x2d, 0x46, 0x50, 0x6c, 0xd3, 0x95, 0xd8, 0x14, 0x31, 0xc5, 0x72, + 0xce, 0xc4, 0xde, 0x03, 0x51, 0xb6, 0xd0, 0xd5, 0xc2, 0x7f, 0x5d, 0xa8, 0xcc, 0x34, 0x3c, 0xad, + 0x33, 0x75, 0x5a, 0x65, 0x96, 0x22, 0x18, 0x78, 0xf1, 0x80, 0x42, 0x04, 0xf5, 0x2f, 0x00, 0xda, + 0x4e, 0x5f, 0x29, 0xbb, 0xeb, 0x49, 0x53, 0x4c, 0x90, 0x29, 0x99, 0x37, 0xe0, 0x2c, 0xe3, 0xdc, + 0x40, 0x0a, 0x29, 0xc4, 0x2b, 0x81, 0x1a, 0x64, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0xb6, 0x32, + 0x00, 0x00, 0x7b, 0x8a, 0x4f, 0xb1, 0xcd, 0x72, 0xeb, 0x2f, 0x0c, 0x8d, 0x21, 0x4d, 0xce, 0xba, + 0xa1, 0x37, 0x98, 0x35, 0xd6, 0x85, 0xed, 0x39, 0x22, 0x9c, 0x85, 0x49, 0x87, 0x8a, 0xcf, 0x4c, + 0xab, 0x48, 0x69, 0x6b, 0xbc, 0x6a, 0x38, 0x4e, 0xe0, 0x93, 0x9b, 0xe2, 0x8d, 0x23, 0x54, 0x0e, + 0x4b, 0x6f, 0x17, 0x7d, 0x05, 0x5a, 0xc2, 0x02, 0x5a, 0x10, 0x0f, 0x6e, 0xf2, 0x94, 0x81, 0x7a, + 0x99, 0xc7, 0x9b, 0xe5, 0xff, 0xf9, 0xc7, 0x27, 0x37, 0x80, 0x2a, 0x98, 0x98, 0x71, 0xce, 0x07, + 0x0d, 0x5d, 0x01, 0xdf, 0x03, 0x24, 0xc2, 0xd0, 0x47, 0xab, 0x5c, 0xb6, 0x57, 0x2f, 0x08, 0xb8, + 0x6c, 0xbf, 0xef, 0x56, 0x4d, 0x98, 0xc7, 0x1c, 0x78, 0x1f, 0x03, 0xf8, 0x38, 0x3e, 0x11, 0x2a, + 0xc8, 0x34, 0x8f, 0xe7, 0x79, 0x09, 0x95, 0x9a, 0xaf, 0xa6, 0xca, 0xa0, 0xc4, 0x9c, 0x8d, 0xe3, + 0xce, 0xbf, 0xbc, 0x6a, 0x2e, 0xe0, 0xbe, 0xbd, 0xa2, 0x3a, 0x6d, 0x84, 0x19, 0x2d, 0x7e, 0xe4, + 0x7a, 0x69, 0x85, 0x11, 0xc4, 0x7e, 0x27, 0x96, 0x4a, 0x91, 0x96, 0x58, 0x21, 0xa8, 0x30, 0xe8, + 0xd4, 0x07, 0xe5, 0x04, 0x9c, 0x80, 0x4d, 0x07, 0x26, 0x1f, 0xcf, 0x74, 0xc9, 0x1e, 0x0a, 0xf9, + 0xe9, 0x4f, 0x23, 0xd1, 0x6f, 0x46, 0x7f, 0x5a, 0x5a, 0x27, 0x9e, 0x9b, 0x72, 0xca, 0xea, 0x6f, + 0x38, 0x4b, 0x43, 0x70, 0xc3, 0xc3, 0x83, 0xc3, 0x9b, 0x60, 0x7e, 0x06, 0xb3, 0xc4, 0x53, 0x16, + 0x70, 0xf3, 0xb0, 0x8d, 0x02, 0x50, 0x97, 0x83, 0x55, 0x2d, 0x4c, 0xbc, 0xc8, 0x1b, 0x25, 0xb6, + 0xdc, 0x79, 0x75, 0xfc, 0xf3, 0x32, 0xcb, 0x1a, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x75, 0xaa, + 0xb0, 0xd2, 0xbf, 0x90, 0x50, 0xd0, 0xf0, 0x42, 0x44, 0x70, 0x24, 0x60, 0x1a, 0x2c, 0xbd, 0x2a, + 0x5f, 0x4b, 0x37, 0x70, 0x95, 0x79, 0xff, 0x07, 0xad, 0x00, 0x68, 0x44, 0xfe, 0xde, 0x89, 0x98, + 0x3c, 0x3d, 0x96, 0x3c, 0x08, 0x2d, 0x2f, 0xfc, 0xa9, 0xe7, 0xce, 0x1d, 0x91, 0x3e, 0xb1, 0x89, + 0xdc, 0x7d, 0xbd, 0x2f, 0x0d, 0x56, 0x15, 0x6c, 0xde, 0x0e, 0x57, 0x29, 0x67, 0x78, 0x41, 0xfb, + 0xf7, 0x2d, 0xea, 0xab, 0x5f, 0x85, 0xce, 0x39, 0xd1, 0x9d, 0xfb, 0x96, 0xec, 0x70, 0xf8, 0x61, + 0xe1, 0x9d, 0x87, 0xa3, 0x56, 0x63, 0x78, 0x7b, 0x40, 0x6b, 0x5f, 0x1e, 0x7e, 0x33, 0x23, 0x0c, + 0xd9, 0xc4, 0x2d, 0xf2, 0x0d, 0x32, 0x15, 0x7c, 0x10, 0xef, 0xd1, 0x52, 0xd8, 0x22, 0x2b, 0xd7, + 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x86, 0x02, 0x00, 0x00, 0x00, 0x5c, 0x4f, 0x5c, 0x9d, 0xdd, + 0x23, 0xea, 0x8f, 0x47, 0xb9, 0xed, 0xc2, 0x20, 0x63, 0x74, 0x8e, 0x6e, 0x88, 0x0f, 0xdf, 0x76, + 0x0a, 0xac, 0x64, 0xc4, 0x55, 0x19, 0x4a, 0xb7, 0x7a, 0xeb, 0xf9, 0xa0, 0xcf, 0x58, 0x59, 0xd6, + 0xe8, 0xc0, 0xee, 0x3b, 0x7e, 0xb1, 0x30, 0x26, 0x9b, 0x33, 0x1a, 0x56, 0xc7, 0x15, 0xe5, 0xa2, + 0x7c, 0xf3, 0x54, 0xff, 0x8f, 0x7a, 0xd6, 0xf0, 0x84, 0x6c, 0xeb, 0xcd, 0xe1, 0x80, 0x5e, 0x45, + 0x8b, 0x8c, 0x2e, 0x9e, 0x71, 0xe3, 0xc3, 0x1f, 0xb2, 0x18, 0x0e, 0x45, 0x1a, 0x22, 0x77, 0xcf, + 0x03, 0x41, 0xd7, 0x84, 0x37, 0x88, 0x4f, 0xf3, 0x87, 0xec, 0x9b, 0xd1, 0x0d, 0x1b, 0xab, 0x01, + 0x8f, 0x81, 0xf8, 0x3f, 0x03, 0xe1, 0xe7, 0x17, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x09, 0xb5, 0x9a, + 0xae, 0xed, 0x19, 0x12, 0xa7, 0xec, 0xb5, 0x78, 0xea, 0x3c, 0x5f, 0x3c, 0x65, 0x32, 0xc1, 0x96, + 0x17, 0x53, 0xb5, 0x8a, 0xc8, 0xa4, 0xbc, 0x00, 0x16, 0xff, 0x66, 0xad, 0x27, 0x95, 0x20, 0x99, + 0xe4, 0x92, 0x8e, 0x0d, 0x73, 0x94, 0xbe, 0xed, 0x8b, 0xb9, 0x83, 0xa8, 0x30, 0xc6, 0xc3, 0x6e, + 0xb3, 0xa6, 0xe5, 0x1b, 0x7a, 0xd0, 0x90, 0x5a, 0x70, 0x05, 0x7e, 0x13, 0xb0, 0xb5, 0xf4, 0x50, + 0xa3, 0xb3, 0x42, 0x45, 0x57, 0x1f, 0x3c, 0x4d, 0x1b, 0xbd, 0xa8, 0x8c, 0x65, 0xb7, 0x27, 0x07, + 0x07, 0x8f, 0x85, 0x0f, 0x51, 0x5c, 0x2d, 0x32, 0x33, 0x61, 0x39, 0x8b, 0x92, 0x23, 0x9e, 0x2f, + 0xa2, 0x19, 0x4c, 0x65, 0xb1, 0xc5, 0xdb, 0x79, 0x58, 0x18, 0x2a, 0x26, 0x3e, 0x81, 0x44, 0x63, + 0xc8, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x96, 0x0a, 0x00, 0x00, 0x00, 0x5c, 0x4f, 0x57, 0xe1, 0xe3, + 0xbc, 0x37, 0x2a, 0xaf, 0x44, 0x7a, 0xf6, 0x6e, 0x08, 0x0a, 0x68, 0xf8, 0xea, 0x64, 0x83, 0x2c, + 0xd9, 0xce, 0x39, 0xce, 0xa9, 0x4e, 0xd4, 0xae, 0x45, 0xe9, 0x30, 0xab, 0x44, 0xb3, 0x4e, 0xa0, + 0xde, 0x8c, 0x5b, 0x17, 0x8d, 0xd0, 0xb8, 0xcf, 0x93, 0xd4, 0xa8, 0x7e, 0xbc, 0x40, 0x1c, 0x52, + 0x3b, 0x05, 0x69, 0x0a, 0x0f, 0xba, 0x99, 0xc6, 0x07, 0xce, 0x7a, 0xc5, 0x00, 0x49, 0x8c, 0xf9, + 0x57, 0xce, 0x01, 0x47, 0x1e, 0x38, 0x78, 0xf0, 0x3d, 0xd5, 0x46, 0x8b, 0x19, 0x01, 0xd8, 0xdd, + 0xe5, 0x1a, 0xac, 0x3b, 0xff, 0x51, 0xb2, 0x89, 0x2e, 0x41, 0xfc, 0x4f, 0xdd, 0x9b, 0x88, 0x1c, + 0x3f, 0x01, 0xf8, 0x1e, 0x0f, 0x87, 0x8e, 0x11, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x09, 0x95, 0xda, + 0xb0, 0xd2, 0xc2, 0xb4, 0xcd, 0x00, 0x67, 0xfa, 0x11, 0xab, 0x00, 0x06, 0x12, 0x0c, 0xca, 0x82, + 0x9f, 0xb2, 0x61, 0x98, 0x46, 0x1f, 0xb7, 0x04, 0x6c, 0x91, 0x49, 0xa9, 0xd4, 0xbe, 0x87, 0xf6, + 0xdd, 0xf6, 0x4c, 0x82, 0x4f, 0x2b, 0xea, 0xbf, 0x67, 0x6b, 0x86, 0x96, 0x4e, 0x33, 0x2a, 0xbb, + 0x52, 0x29, 0x73, 0x7d, 0x2b, 0x2d, 0x15, 0xb3, 0x84, 0x68, 0x93, 0x06, 0x94, 0x0a, 0x05, 0x5f, + 0x8f, 0x9c, 0xd1, 0x77, 0xa1, 0x4f, 0x5c, 0x1d, 0xfd, 0xaf, 0xec, 0x3e, 0x3c, 0x1e, 0x1e, 0x0f, + 0x0d, 0x22, 0xc0, 0x41, 0x0b, 0x7c, 0x0a, 0xc3, 0x3e, 0x29, 0x3e, 0x1b, 0x8e, 0xf8, 0xc0, 0xb0, + 0x66, 0x2e, 0x45, 0xea, 0xea, 0xa3, 0x0a, 0x1a, 0x6b, 0xa3, 0x9b, 0x40, 0x78, 0x48, 0x7a, 0xd7, + 0xd8, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x85, 0xe2, 0xaf, 0xa6, 0xc8, 0x17, 0x7f, 0x07, 0xd7, 0x80, + 0x85, 0x13, 0x00, 0x01, 0xd1, 0x39, 0x98, 0xdf, 0x2f, 0x6d, 0x9a, 0x18, 0x38, 0xbd, 0xfd, 0x90, + 0xc0, 0xd5, 0x26, 0x43, 0x07, 0x65, 0x0a, 0x21, 0x38, 0x54, 0xe0, 0x51, 0x55, 0x53, 0x11, 0xe7, + 0x46, 0x6c, 0x32, 0x98, 0x69, 0xe2, 0x99, 0x27, 0x20, 0x1d, 0xab, 0x1e, 0x3b, 0x0d, 0x20, 0x08, + 0xaf, 0x40, 0xa3, 0x69, 0x19, 0xb5, 0xa4, 0x97, 0x85, 0xd3, 0xb9, 0x10, 0x45, 0x45, 0x95, 0x76, + 0x55, 0x2d, 0x20, 0xc5, 0x1e, 0x8e, 0x3c, 0x3c, 0x1e, 0x1f, 0x2e, 0xf4, 0x8f, 0x52, 0xf3, 0x11, + 0x12, 0x09, 0x55, 0x8d, 0x65, 0x73, 0x76, 0x12, 0x0a, 0x31, 0x30, 0x99, 0x63, 0x6a, 0x70, 0x82, + 0xda, 0x1b, 0xca, 0xa0, 0xc6, 0x1f, 0x48, 0x30, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x76, 0x3a, + 0xb0, 0xd2, 0xc2, 0xb4, 0xe8, 0x03, 0xc5, 0x58, 0xf9, 0x16, 0x0c, 0x7d, 0x98, 0xd8, 0xc6, 0x8b, + 0x15, 0x7a, 0x10, 0x1e, 0xd9, 0xf5, 0xda, 0x2e, 0x55, 0x0e, 0x00, 0x1e, 0xf8, 0x72, 0x0c, 0xa5, + 0xe0, 0xe7, 0x31, 0x5b, 0xf7, 0xe7, 0x17, 0x85, 0x0f, 0x3c, 0x37, 0x27, 0xff, 0xef, 0x9f, 0xee, + 0xd9, 0xba, 0x49, 0xac, 0xb8, 0xaf, 0x82, 0xc8, 0x3c, 0x3a, 0x40, 0x41, 0xfb, 0x93, 0x48, 0x9a, + 0x75, 0x8c, 0x74, 0x6f, 0xaf, 0xbc, 0x29, 0x1d, 0x0d, 0xa2, 0x17, 0xc2, 0x78, 0xf4, 0xe8, 0x4c, + 0x71, 0xf8, 0x08, 0x01, 0x4b, 0x48, 0x10, 0xb8, 0x82, 0x41, 0xc9, 0x98, 0xca, 0xb5, 0x20, 0x00, + 0x4f, 0x46, 0xed, 0x59, 0x64, 0xfc, 0x57, 0x0a, 0x50, 0xb5, 0x52, 0x7d, 0x46, 0xd1, 0xe2, 0x79, + 0xc9, 0x18, 0x7f, 0xb7, 0x79, 0x19, 0x86, 0x3a, 0xaf, 0xdd, 0x47, 0xaf, 0xd9, 0x97, 0xb6, 0x49, + 0x9c, 0xea, 0x94, 0x11, 0x6e, 0x68, 0xd4, 0xbc, 0x72, 0xbe, 0xc1, 0xe3, 0xbe, 0xfe, 0x53, 0x05, + 0x2b, 0x0f, 0x14, 0x1f, 0xa1, 0xcd, 0x19, 0xfd, 0x44, 0x78, 0x5d, 0x0e, 0xb6, 0x7a, 0x0b, 0x07, + 0xbf, 0xae, 0x97, 0x1c, 0x4f, 0x97, 0xa1, 0x92, 0xcb, 0x5a, 0xea, 0x36, 0xc3, 0xdf, 0x33, 0x5c, + 0x12, 0xc9, 0x14, 0x25, 0x7b, 0x9a, 0x35, 0xea, 0x63, 0x00, 0xa4, 0x6e, 0x9d, 0x7c, 0x14, 0x25, + 0xe2, 0x9e, 0x43, 0x5f, 0xca, 0x8c, 0x78, 0x7c, 0x3e, 0x3e, 0x1e, 0x62, 0x7f, 0x36, 0x1b, 0xb5, + 0x3e, 0x9e, 0x03, 0xce, 0x27, 0x63, 0xca, 0x5a, 0xd5, 0x4d, 0x72, 0x6b, 0x4f, 0xfb, 0xa1, 0xf2, + 0xc2, 0x65, 0x11, 0x02, 0x41, 0x87, 0x90, 0xc6, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x96, 0x12, + 0xaf, 0xa6, 0xca, 0xa0, 0xd1, 0x87, 0xbe, 0x89, 0xd0, 0xce, 0x85, 0x59, 0x7a, 0x65, 0x23, 0x50, + 0xc8, 0x53, 0x5c, 0xd8, 0x14, 0x4f, 0x2e, 0xb5, 0x66, 0x49, 0x0f, 0x52, 0x12, 0x21, 0xfb, 0x7f, + 0x6d, 0xa6, 0x80, 0x20, 0x95, 0x30, 0xdc, 0xfc, 0xee, 0x23, 0xd5, 0x30, 0xa7, 0x9e, 0x11, 0x2b, + 0x52, 0xf2, 0x3e, 0x5b, 0x9e, 0xeb, 0x6b, 0xa0, 0x5f, 0x15, 0x68, 0x8e, 0xe9, 0x78, 0x59, 0xd9, + 0xe6, 0xc9, 0x05, 0x0d, 0x73, 0x26, 0xf8, 0x3b, 0x34, 0x2f, 0x1f, 0x91, 0x9e, 0x99, 0x63, 0x8c, + 0x33, 0xf4, 0x84, 0x0e, 0x27, 0x25, 0xb6, 0x1b, 0x98, 0x0e, 0xee, 0xcf, 0xd8, 0x15, 0xd5, 0xaa, + 0xd9, 0xbf, 0x82, 0xfb, 0x5a, 0x91, 0x4c, 0xa3, 0x6b, 0x4a, 0x17, 0x07, 0x99, 0xcc, 0x7a, 0x01, + 0xd9, 0x18, 0x7f, 0xb7, 0x79, 0x19, 0x96, 0x2a, 0xb6, 0xba, 0x94, 0x47, 0x96, 0x0a, 0x24, 0x0e, + 0x1d, 0x13, 0x4c, 0xd0, 0x98, 0x46, 0x8e, 0xe9, 0x00, 0x09, 0xa0, 0x5f, 0x54, 0x00, 0x0a, 0x27, + 0xd9, 0x45, 0xcf, 0xcf, 0x1a, 0xb1, 0xb9, 0x23, 0xd3, 0x8f, 0x2b, 0xa0, 0x6c, 0xf0, 0x94, 0xc5, + 0xec, 0xa0, 0x25, 0x4c, 0x03, 0x95, 0x9a, 0xb0, 0xe8, 0x17, 0x31, 0xcc, 0x58, 0xae, 0x26, 0xd5, + 0x19, 0x74, 0xd0, 0x5d, 0x2a, 0xcf, 0x73, 0xb2, 0xd0, 0xf2, 0x0e, 0x6e, 0x20, 0xef, 0xb2, 0x5d, + 0x74, 0xc2, 0x33, 0x9d, 0x8c, 0xe3, 0x8f, 0x1e, 0x0f, 0x0f, 0x87, 0x9c, 0x5a, 0x72, 0x8c, 0x3d, + 0x84, 0x9d, 0x8c, 0xf9, 0x92, 0x6a, 0x27, 0x11, 0xb6, 0x7c, 0x1f, 0x5c, 0x20, 0xa5, 0x31, 0x10, + 0x53, 0xfa, 0x70, 0xc1, 0x57, 0x77, 0x41, 0x9c, 0xd8, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x95, 0xf2, + 0xae, 0xec, 0x0f, 0xb3, 0x25, 0xd2, 0x48, 0x45, 0xcc, 0x96, 0x18, 0x73, 0x3f, 0x05, 0xf8, 0xf1, + 0x77, 0x06, 0xb8, 0x84, 0x9f, 0x94, 0x3a, 0x01, 0x59, 0xef, 0x5e, 0x07, 0xb8, 0x44, 0x7c, 0xb5, + 0x08, 0xdd, 0xae, 0x57, 0x5b, 0x81, 0x1a, 0xc7, 0x62, 0x6c, 0xf9, 0x0a, 0x4a, 0xb6, 0xf3, 0x44, + 0x11, 0x93, 0xb8, 0x1e, 0xb8, 0xa9, 0x4f, 0xbc, 0x79, 0xf6, 0x95, 0xfd, 0xfb, 0xf3, 0x57, 0x4b, + 0xb9, 0xe9, 0xb5, 0xcd, 0x8d, 0xd4, 0x39, 0x21, 0x88, 0x43, 0xda, 0x37, 0xb8, 0x78, 0xfc, 0x1e, + 0x0f, 0x87, 0x04, 0x2d, 0x7e, 0xf0, 0xad, 0x32, 0xd2, 0xef, 0x5c, 0xa7, 0xd6, 0x56, 0x84, 0xcc, + 0xbc, 0x3b, 0x95, 0x32, 0x8b, 0xaa, 0x20, 0xb2, 0x89, 0x90, 0x61, 0x00, 0xc9, 0xe9, 0xe9, 0x42, + 0xc8, 0x34, 0x8f, 0xe7, 0x79, 0x39, 0x86, 0x0a, 0xaf, 0xdd, 0x49, 0x47, 0x93, 0x57, 0xb2, 0x73, + 0x98, 0x0a, 0x4a, 0x00, 0x02, 0xdc, 0x10, 0x12, 0x0d, 0xa8, 0x69, 0xb4, 0xff, 0xbb, 0xd4, 0x79, + 0x00, 0x10, 0x9a, 0xd9, 0x29, 0x03, 0x07, 0x8d, 0xe2, 0xeb, 0x51, 0x78, 0xff, 0x8f, 0xde, 0x43, + 0xb8, 0x6b, 0x59, 0xf8, 0xa5, 0x52, 0x56, 0x92, 0xa2, 0x86, 0xb2, 0x2d, 0x49, 0xf6, 0x12, 0x4b, + 0x9a, 0xf3, 0x65, 0x5c, 0xb3, 0x2c, 0xc1, 0x2f, 0x02, 0x43, 0x35, 0xe5, 0xab, 0x9b, 0xa6, 0x19, + 0xf3, 0xd4, 0x73, 0xc1, 0x83, 0x07, 0x1c, 0xc5, 0xb7, 0x8f, 0x20, 0xc2, 0xa4, 0x18, 0x21, 0x83, + 0xc0, 0x58, 0xea, 0xb3, 0xcf, 0x90, 0x80, 0x92, 0x34, 0xd0, 0xc6, 0x2f, 0x39, 0x13, 0xbf, 0x92, + 0xbd, 0x02, 0x92, 0x14, 0x88, 0x75, 0x17, 0x8f, 0x58, 0x31, 0x9e, 0xe7, 0x79, 0x19, 0x96, 0x32, + 0x00, 0x00, 0x00, 0x17, 0xce, 0xd6, 0x4b, 0x99, 0x74, 0x49, 0x5b, 0xfd, 0x44, 0xe4, 0xd0, 0xf0, + 0x28, 0x47, 0x5e, 0xff, 0x1b, 0xc0, 0xe7, 0x04, 0x71, 0x3d, 0x0d, 0xd6, 0xca, 0x4c, 0x60, 0xc4, + 0x25, 0xe3, 0xef, 0x6b, 0xc8, 0x44, 0xdf, 0x67, 0xf4, 0xa2, 0x3c, 0x99, 0xf2, 0xeb, 0x63, 0x2b, + 0x4f, 0x57, 0xb0, 0xb4, 0xd3, 0x15, 0x11, 0xd9, 0x4a, 0x4d, 0xe0, 0xfc, 0x8d, 0x7e, 0xbb, 0xdf, + 0x51, 0x9b, 0xd6, 0x78, 0x46, 0x08, 0x84, 0x21, 0x19, 0x9a, 0x9e, 0x1c, 0x26, 0x98, 0x45, 0xfa, + 0x96, 0xd6, 0xe3, 0xe3, 0x86, 0x79, 0x95, 0xa4, 0x90, 0x73, 0xe5, 0x0c, 0x93, 0xed, 0x60, 0x04, + 0x16, 0x48, 0x1c, 0x2d, 0xe0, 0xf3, 0x18, 0x2f, 0xc9, 0x87, 0x8f, 0x0f, 0x0e, 0x0e, 0x35, 0x04, + 0x0a, 0xa2, 0x25, 0xbe, 0x79, 0x29, 0xd6, 0x22, 0xaf, 0xdd, 0x49, 0xd0, 0x01, 0x07, 0x26, 0x24, + 0x1a, 0x30, 0xf7, 0x6a, 0x7c, 0x6d, 0x9b, 0x33, 0x48, 0x02, 0x8d, 0x03, 0x92, 0x80, 0x00, 0x00, + 0x00, 0x9b, 0x5f, 0x92, 0xdf, 0x60, 0x50, 0x67, 0x44, 0xa0, 0xed, 0xb2, 0xaa, 0xdf, 0x6f, 0xfc, + 0x8d, 0x08, 0xfb, 0xb1, 0x55, 0x21, 0x9c, 0x5d, 0x89, 0xc5, 0x0f, 0x69, 0x54, 0xaa, 0x9b, 0x7c, + 0x6e, 0x86, 0x21, 0x29, 0xb8, 0x84, 0xa3, 0xd5, 0x82, 0x0b, 0xdc, 0xe0, 0x0f, 0xa8, 0x5e, 0x5d, + 0x77, 0xdb, 0x0f, 0x83, 0x83, 0xc3, 0x8c, 0x27, 0x38, 0x79, 0x87, 0x31, 0x4c, 0xcc, 0xa5, 0x12, + 0x52, 0x98, 0x6b, 0x9b, 0x18, 0x09, 0x51, 0x91, 0x73, 0x8f, 0x76, 0xe2, 0x04, 0x4c, 0x4c, 0x19, + 0xc5, 0x7b, 0xd6, 0x24, 0x31, 0x97, 0xf9, 0x53, 0x4a, 0xa2, 0x25, 0xbe, 0x79, 0x39, 0xb6, 0x22, + 0xaf, 0xdd, 0x47, 0x5c, 0xd4, 0x87, 0xe9, 0x38, 0x67, 0x02, 0xb6, 0xd5, 0x9e, 0x32, 0x3e, 0x50, + 0x4e, 0x41, 0x80, 0xeb, 0x01, 0x11, 0x93, 0x00, 0x00, 0xc1, 0x6f, 0x39, 0x60, 0x40, 0xe1, 0x8f, + 0xe0, 0xde, 0x4a, 0x1c, 0x46, 0x43, 0x6c, 0xd0, 0x4d, 0x6f, 0x87, 0xfd, 0x26, 0xc9, 0xac, 0xef, + 0x65, 0x1f, 0x08, 0xd4, 0x2d, 0xe3, 0xbb, 0x95, 0x06, 0x98, 0x02, 0x6f, 0xc3, 0x4b, 0x70, 0xb5, + 0xd4, 0x1d, 0xcc, 0x12, 0x9e, 0xd0, 0x4b, 0xc0, 0x83, 0x5e, 0x5c, 0x43, 0xe0, 0x61, 0xfc, 0x70, + 0x85, 0xb9, 0xe1, 0xce, 0x81, 0x81, 0x74, 0x0f, 0x71, 0x24, 0x04, 0xe7, 0x0b, 0x3d, 0x89, 0x87, + 0x1f, 0x22, 0x73, 0xef, 0x71, 0xca, 0x0e, 0xac, 0x13, 0x9a, 0xab, 0x6f, 0x08, 0x10, 0x58, 0x63, + 0xda, 0xa2, 0x25, 0xbe, 0x79, 0x19, 0xb6, 0x2a, 0xaf, 0xde, 0xcb, 0xf9, 0xda, 0x75, 0x22, 0xeb, + 0x42, 0x79, 0x4d, 0xf9, 0x26, 0x61, 0xa1, 0xde, 0x6f, 0x04, 0x69, 0x01, 0x56, 0x71, 0x00, 0x00, + 0x00, 0xc9, 0x21, 0xc5, 0x11, 0x2d, 0x68, 0xb3, 0x00, 0x0d, 0x1b, 0x31, 0x17, 0xa5, 0x05, 0x0b, + 0x0c, 0x4a, 0x5e, 0x20, 0xbf, 0x2c, 0x0d, 0x5c, 0x6c, 0x89, 0x64, 0x68, 0xe2, 0xcd, 0x31, 0xb3, + 0x25, 0x74, 0x83, 0x25, 0x47, 0x80, 0xba, 0x98, 0xa2, 0xaa, 0x5c, 0x20, 0x84, 0x5d, 0x84, 0x77, + 0xa6, 0x57, 0x5f, 0xc0, 0x7e, 0x0f, 0xc0, 0xf0, 0xf1, 0xf9, 0x1c, 0x78, 0x25, 0xe7, 0xf6, 0xbe, + 0x41, 0x60, 0x4b, 0x07, 0xd9, 0x03, 0x1a, 0x7a, 0xfa, 0xc9, 0x8c, 0x49, 0x67, 0x61, 0x68, 0xbe, + 0x6b, 0x94, 0x67, 0xce, 0x01, 0x7f, 0xbd, 0x03, 0xda, 0xa2, 0x25, 0xbe, 0x79, 0x19, 0xb6, 0x32, + 0xb6, 0xae, 0x86, 0x8b, 0xf6, 0x97, 0xbd, 0x1d, 0x21, 0x8d, 0xd3, 0xc1, 0x14, 0xa5, 0xb4, 0x74, + 0xcb, 0x2c, 0x68, 0x95, 0x58, 0x6e, 0x9d, 0xd8, 0x67, 0xd7, 0x00, 0x28, 0x59, 0xe1, 0x22, 0x0f, + 0x08, 0x16, 0x8c, 0xbc, 0x39, 0x08, 0xc8, 0xf2, 0xd5, 0x63, 0x96, 0x2a, 0x4d, 0xe4, 0xb8, 0x45, + 0x8d, 0xe0, 0xe6, 0x7e, 0x09, 0xe7, 0xba, 0xdb, 0x8c, 0x84, 0x06, 0xd1, 0xa0, 0xcf, 0x15, 0xd8, + 0xe6, 0x6e, 0x30, 0x2c, 0xf3, 0x92, 0xe8, 0x69, 0xbf, 0xdb, 0xe0, 0xe2, 0x18, 0xe5, 0x38, 0x7c, + 0x70, 0x58, 0xab, 0x5a, 0xb3, 0x41, 0xa2, 0x39, 0x1d, 0xe8, 0x60, 0x13, 0x37, 0xa0, 0xea, 0x94, + 0xa9, 0x3f, 0xc2, 0xa8, 0x02, 0xa8, 0xc9, 0xc9, 0x5b, 0x82, 0x58, 0xa0, 0x7e, 0x58, 0xc0, 0xbc, + 0xda, 0xa2, 0x25, 0xbe, 0x79, 0x19, 0x85, 0xe2, 0x33, 0xd8, 0x04, 0x09, 0x22, 0xac, 0x4b, 0x30, + 0x26, 0xa5, 0xce, 0x2b, 0x8b, 0xe4, 0xdd, 0x49, 0xde, 0xf3, 0x71, 0xdb, 0x41, 0x0b, 0x9c, 0x9e, + 0x37, 0x87, 0x37, 0x00, 0x30, 0x51, 0x30, 0xf8, 0x07, 0x9d, 0xd5, 0xaf, 0x2d, 0xa0, 0x72, 0x91, + 0xf5, 0xf6, 0xff, 0x28, 0xe7, 0x8c, 0x19, 0x61, 0xc9, 0x90, 0x69, 0xd0, 0xb6, 0x18, 0x57, 0x2b, + 0xbb, 0x7d, 0x94, 0xbd, 0xbb, 0x1b, 0xd1, 0xf3, 0xe2, 0x7b, 0x00, 0x00, 0x00, 0x5e, 0xb5, 0x7d, + 0x88, 0x13, 0x70, 0x37, 0xc7, 0x09, 0xf1, 0xff, 0x00, 0xf4, 0xda, 0xfd, 0xf8, 0xc8, 0xeb, 0x4e, + 0x20, 0x64, 0x24, 0xe8, 0x83, 0x33, 0xdd, 0x21, 0xf1, 0x98, 0xa9, 0x4a, 0x2a, 0x22, 0x38, 0xd0, + 0x50, 0x44, 0x3e, 0x12, 0x97, 0xf5, 0x0a, 0x4f, 0xb5, 0x45, 0x00, 0xbc, 0xf2, 0x39, 0x96, 0x24, + 0xb6, 0xaf, 0xa6, 0xf9, 0xcd, 0x37, 0xd5, 0x1c, 0x78, 0xf8, 0x77, 0x78, 0xdd, 0x48, 0x14, 0x86, + 0x42, 0xb8, 0xa5, 0x3f, 0x61, 0x53, 0x26, 0x14, 0x48, 0x00, 0x3a, 0x99, 0xa8, 0xc0, 0x35, 0x0d, + 0x65, 0x76, 0x0d, 0x54, 0x20, 0x78, 0x1f, 0xf5, 0x28, 0xdd, 0x90, 0x38, 0xb0, 0xae, 0x63, 0xe6, + 0x31, 0x7b, 0xd9, 0x68, 0x06, 0x49, 0x53, 0xda, 0x75, 0x93, 0x00, 0x15, 0x70, 0x7f, 0xa1, 0x2f, + 0x4d, 0xf6, 0xb4, 0x42, 0x29, 0xfd, 0xfd, 0xa7, 0x50, 0xf9, 0x4e, 0xb1, 0x67, 0x06, 0x3c, 0xc0, + 0x6f, 0x38, 0x79, 0x0b, 0x3e, 0x0e, 0x94, 0x82, 0x42, 0x70, 0x9a, 0xc5, 0x1b, 0x63, 0x61, 0x3e, + 0x4b, 0xb3, 0x17, 0xbb, 0x40, 0x09, 0x2a, 0xff, 0x7e, 0xe5, 0x44, 0xdf, 0x48, 0x4a, 0x75, 0x8b, + 0x5a, 0xa2, 0x80, 0x5e, 0x79, 0x19, 0x96, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6d, 0x73, 0x7c, + 0x9f, 0x67, 0xa0, 0xef, 0xa0, 0xa7, 0xeb, 0xe2, 0xe1, 0x85, 0x96, 0x6a, 0xe4, 0x5b, 0xa3, 0xc6, + 0x67, 0x86, 0xd3, 0x74, 0x6c, 0x13, 0xb2, 0x27, 0x47, 0x70, 0x4c, 0x11, 0x7f, 0x31, 0xa6, 0xc0, + 0x2d, 0x9f, 0xc1, 0x91, 0x91, 0x1b, 0xa9, 0xb6, 0xee, 0x29, 0x8d, 0x51, 0xbf, 0xab, 0xad, 0xed, + 0x28, 0x95, 0xf9, 0x44, 0x3d, 0x92, 0x01, 0x45, 0x09, 0x32, 0xb3, 0x82, 0x55, 0xf4, 0x7b, 0x46, + 0x43, 0x48, 0xac, 0x84, 0xd9, 0x86, 0xd3, 0x0f, 0xc2, 0xa5, 0x42, 0x20, 0x89, 0x96, 0x99, 0xba, + 0xe6, 0x22, 0x7b, 0x43, 0x99, 0xa0, 0x7a, 0xce, 0x14, 0x67, 0x08, 0x47, 0x76, 0xe0, 0xf9, 0x4d, + 0xd4, 0x42, 0xd1, 0xe0, 0xf0, 0x78, 0x71, 0xb6, 0x3a, 0xa2, 0x80, 0x5e, 0x79, 0x09, 0xc6, 0x22, + 0x35, 0x16, 0xd8, 0x03, 0xc2, 0xd2, 0x32, 0x65, 0x0f, 0x49, 0xb5, 0x22, 0x2f, 0x98, 0x3e, 0x96, + 0x6b, 0x25, 0xef, 0xf6, 0x08, 0x01, 0xc4, 0xf3, 0xf1, 0xf2, 0x31, 0xf1, 0xa5, 0x00, 0x3b, 0x24, + 0x7d, 0x52, 0x00, 0xe5, 0x7e, 0xbe, 0xb5, 0x73, 0xf3, 0xe8, 0x4b, 0xbf, 0x91, 0xf5, 0x54, 0x7f, + 0x21, 0x72, 0x51, 0xd8, 0xe1, 0x31, 0xa6, 0x40, 0x8a, 0xcc, 0x5f, 0xfb, 0x40, 0x94, 0x61, 0x54, + 0x7d, 0x74, 0x71, 0x5e, 0xc4, 0x00, 0x10, 0x92, 0x02, 0x93, 0x30, 0x37, 0x6f, 0xac, 0xf4, 0xad, + 0xe6, 0x90, 0xc0, 0x9c, 0x32, 0xc4, 0x42, 0x2b, 0x38, 0x99, 0x1c, 0x60, 0xa8, 0x5e, 0x49, 0xb0, + 0x0f, 0x27, 0xab, 0x4c, 0x98, 0x81, 0x8e, 0x77, 0x3b, 0xd3, 0x1c, 0xb4, 0xfd, 0x1f, 0x3a, 0xa7, + 0x95, 0x45, 0x00, 0xbc, 0xf2, 0x39, 0x65, 0x94, 0x33, 0x99, 0xa3, 0x6b, 0xc6, 0x11, 0xc8, 0xea, + 0xb8, 0x61, 0x56, 0x62, 0x54, 0xef, 0x09, 0xac, 0xa7, 0x9c, 0xad, 0x88, 0x72, 0xaf, 0xf2, 0xa8, + 0x81, 0x9f, 0x94, 0x00, 0x00, 0x02, 0xf0, 0xb9, 0xf9, 0xc6, 0xf8, 0x3d, 0x1a, 0x27, 0x3f, 0xf5, + 0xb9, 0xac, 0x99, 0xf8, 0x85, 0x99, 0xcf, 0x49, 0x9f, 0xaf, 0x12, 0x30, 0x09, 0xfe, 0xd0, 0xbd, + 0x86, 0x1a, 0xac, 0xfa, 0xbb, 0x6a, 0x66, 0x24, 0xed, 0x00, 0x00, 0x03, 0x54, 0xca, 0x7c, 0x4a, + 0xfa, 0xe6, 0xc8, 0x40, 0x26, 0x05, 0x34, 0x56, 0x3b, 0x79, 0x50, 0xcf, 0x27, 0x43, 0x18, 0xb1, + 0xc0, 0x8a, 0xf1, 0x82, 0x94, 0x12, 0x71, 0xba, 0x16, 0x61, 0x76, 0x5c, 0x54, 0x36, 0x73, 0xc6, + 0x31, 0x89, 0x38, 0x20, 0x3f, 0x47, 0x1b, 0xb1, 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x76, 0x2c, + 0xa7, 0x93, 0xb3, 0x3a, 0x0e, 0xd7, 0x1c, 0x1f, 0xf4, 0x4b, 0x21, 0xd0, 0xc4, 0xe0, 0xcc, 0xef, + 0x91, 0x75, 0x3d, 0xa5, 0xb0, 0x40, 0xb3, 0xb9, 0x31, 0x00, 0x6e, 0x00, 0x00, 0x0d, 0x11, 0x8c, + 0xe6, 0x15, 0x6c, 0xb2, 0x90, 0x0e, 0xe8, 0xdc, 0xce, 0xd0, 0x62, 0xb0, 0x91, 0xbe, 0x4b, 0xbd, + 0x94, 0x45, 0x10, 0xa5, 0x09, 0x1f, 0x7f, 0x18, 0xbe, 0xf9, 0xc8, 0x0d, 0x8d, 0xd5, 0xf1, 0x5d, + 0x99, 0x2b, 0xb7, 0xa7, 0x00, 0x00, 0x00, 0xd8, 0x5e, 0x54, 0x19, 0xb5, 0xff, 0x6d, 0x16, 0xdd, + 0xfa, 0xf5, 0x7d, 0x1d, 0xbe, 0x3e, 0x7d, 0x91, 0xd9, 0xaa, 0x2a, 0xcd, 0xe0, 0x6a, 0x90, 0x8b, + 0xc8, 0x0c, 0xad, 0x60, 0xde, 0x00, 0xfd, 0xb4, 0x1c, 0x57, 0xe0, 0x1b, 0x7f, 0x56, 0x68, 0xd6, + 0x87, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x85, 0xcc, 0x33, 0xd3, 0x9e, 0x22, 0x68, 0x6b, 0xaf, 0xd6, + 0xa4, 0x58, 0xc7, 0xa3, 0xf3, 0x00, 0xe2, 0x5c, 0xf3, 0xf6, 0xdb, 0x75, 0xba, 0x17, 0xd3, 0xc1, + 0xaf, 0x7f, 0x00, 0x00, 0x00, 0x43, 0x84, 0xe7, 0xfc, 0x20, 0xd6, 0xee, 0xb0, 0xb9, 0xed, 0x0a, + 0xf0, 0xde, 0x63, 0x4a, 0xa1, 0x5a, 0x58, 0x07, 0xb1, 0x38, 0x42, 0x56, 0x56, 0xf7, 0xaa, 0x64, + 0x84, 0xab, 0x74, 0xc9, 0xc4, 0xa0, 0x09, 0xdd, 0x00, 0x00, 0x00, 0x03, 0x0d, 0x63, 0x4e, 0xbe, + 0xce, 0x98, 0xb5, 0x50, 0xae, 0x78, 0xc0, 0xb0, 0x5c, 0x0f, 0xca, 0x14, 0x15, 0x68, 0x01, 0x1f, + 0xc6, 0x0d, 0x51, 0x5f, 0x40, 0xe1, 0x48, 0xed, 0x2d, 0xe4, 0x64, 0xd2, 0x7e, 0x16, 0x99, 0x89, + 0x75, 0x25, 0x63, 0x66, 0x12, 0x08, 0xb4, 0x51, 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0xa6, 0x24, + 0x33, 0x99, 0xa3, 0x6b, 0xc6, 0x40, 0x4e, 0xf2, 0x28, 0x89, 0x9e, 0x2b, 0x8a, 0x6f, 0xe1, 0x1e, + 0x33, 0x5a, 0x70, 0x73, 0xb0, 0x05, 0xc7, 0xcc, 0xb7, 0x27, 0x00, 0x00, 0x00, 0x0b, 0x3f, 0x43, + 0x7c, 0xa0, 0x5d, 0x2e, 0x1f, 0x82, 0x46, 0x80, 0x39, 0xe0, 0xf3, 0x1a, 0x5f, 0x44, 0xc2, 0x81, + 0x92, 0xb1, 0xa3, 0xf6, 0x56, 0x71, 0x57, 0xf5, 0x30, 0xa1, 0x39, 0x74, 0xbb, 0x23, 0xd9, 0x1d, + 0x5c, 0x49, 0x00, 0x4b, 0xee, 0x8c, 0x85, 0xe2, 0x4c, 0x03, 0x1d, 0x7c, 0xc1, 0x88, 0x32, 0x63, + 0x36, 0xec, 0x9a, 0x8c, 0x20, 0xdc, 0xe8, 0x9c, 0x7d, 0x11, 0x80, 0xda, 0x23, 0xe6, 0x41, 0xfa, + 0x0c, 0x27, 0xa9, 0xb4, 0x8a, 0x26, 0xa9, 0x3c, 0x0b, 0x78, 0x4b, 0xc4, 0x84, 0xa2, 0x32, 0x83, + 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x96, 0x14, 0xa8, 0x0a, 0x97, 0xaf, 0xfe, 0xac, 0xa6, 0x0a, + 0xe1, 0x39, 0xca, 0xb8, 0x3a, 0x4f, 0x2b, 0xe3, 0x36, 0x00, 0x10, 0xcb, 0x27, 0xd9, 0xe2, 0x7c, + 0x79, 0xd0, 0x00, 0x00, 0x04, 0x7c, 0xe0, 0x82, 0xcc, 0x6e, 0x97, 0x2d, 0x88, 0x6e, 0x5b, 0xbd, + 0x20, 0x79, 0x51, 0xc5, 0x6f, 0xff, 0xad, 0xde, 0x5f, 0x02, 0x72, 0x31, 0x96, 0x2a, 0x7c, 0xaa, + 0x94, 0x32, 0x5c, 0xae, 0xa5, 0x49, 0x0b, 0x84, 0x0a, 0x00, 0x1d, 0xbc, 0x9d, 0x0f, 0x9e, 0xa3, + 0x1a, 0xe5, 0xe6, 0x00, 0xc0, 0xf2, 0xb6, 0x6e, 0x9e, 0xf5, 0x6b, 0x0c, 0xfd, 0x92, 0x6c, 0x01, + 0x87, 0xc8, 0x1f, 0xb3, 0x10, 0x81, 0x64, 0xb9, 0xb3, 0x71, 0xa5, 0x36, 0x42, 0x27, 0xdb, 0x79, + 0x41, 0x84, 0x07, 0x08, 0x49, 0xf5, 0x38, 0xae, 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x96, 0x3c, + 0xae, 0xf1, 0x98, 0x15, 0x69, 0xd4, 0x07, 0x00, 0x00, 0x29, 0xde, 0xff, 0x8b, 0xc6, 0x7b, 0x35, + 0xf8, 0x26, 0x07, 0x42, 0xe9, 0x0e, 0xf2, 0x5a, 0xdb, 0x75, 0xd8, 0xbd, 0x00, 0x21, 0xce, 0x65, + 0x8f, 0x1a, 0x4c, 0xfb, 0xcf, 0xaf, 0xba, 0x6d, 0xc4, 0x98, 0x48, 0xd8, 0xa8, 0xf5, 0x3a, 0xbe, + 0x01, 0xb6, 0x93, 0x98, 0x34, 0xae, 0x75, 0x79, 0x26, 0xa4, 0x44, 0xf1, 0x17, 0x4a, 0x2c, 0x6e, + 0x05, 0x29, 0x36, 0x4d, 0xe5, 0x23, 0xb9, 0xff, 0x5b, 0xa2, 0xcc, 0xfe, 0x06, 0x71, 0x48, 0x46, + 0x66, 0xae, 0x88, 0x67, 0x87, 0xa3, 0xd0, 0xb8, 0x67, 0xfa, 0x6f, 0x3a, 0xa2, 0x85, 0xa5, 0xa3, + 0xd5, 0xa5, 0x28, 0x10, 0xe3, 0xed, 0x5b, 0x11, 0x63, 0xa0, 0xb8, 0x1f, 0x1f, 0xdb, 0x47, 0x2c, + 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x66, 0x3c, 0x33, 0xd3, 0xb5, 0xb8, 0x9d, 0xe5, 0x92, 0xaa, + 0x00, 0x2a, 0x00, 0x06, 0x30, 0x9a, 0x3d, 0x97, 0xe8, 0x11, 0x6f, 0x8f, 0xeb, 0x98, 0xa1, 0xc5, + 0x00, 0x00, 0x00, 0xcc, 0x4d, 0x31, 0x19, 0xf2, 0x0a, 0x32, 0x12, 0x5e, 0xce, 0x61, 0xb6, 0x12, + 0xbd, 0xb0, 0xf3, 0xc6, 0xd2, 0xe9, 0x3c, 0xa0, 0x40, 0x98, 0x33, 0x39, 0x4f, 0xf4, 0x5c, 0xdd, + 0x5b, 0x17, 0x1e, 0x26, 0xe1, 0x15, 0xb2, 0xff, 0x2c, 0x00, 0x46, 0xe4, 0xc4, 0xe2, 0x07, 0x2e, + 0x4e, 0xbf, 0x0d, 0xc0, 0x7f, 0xde, 0x73, 0xc6, 0xb4, 0xb8, 0x04, 0xde, 0xb8, 0x16, 0xdb, 0x9e, + 0xa1, 0xa5, 0xd1, 0x25, 0x5b, 0x50, 0x0d, 0xf1, 0x4f, 0xc2, 0xd6, 0xc9, 0x83, 0x58, 0x18, 0x4d, + 0x26, 0x19, 0x1c, 0xa8, 0x0e, 0xd7, 0xcd, 0x38, 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x96, 0x1c, + 0x33, 0xd2, 0xc1, 0x91, 0x36, 0x06, 0x73, 0x74, 0x55, 0x63, 0x0f, 0x0d, 0xc6, 0xc5, 0x37, 0x32, + 0x23, 0x57, 0xa2, 0x52, 0x26, 0xe6, 0x0e, 0x44, 0xbd, 0xf7, 0xe2, 0x00, 0x01, 0x2f, 0x59, 0xed, + 0xea, 0x0b, 0xd5, 0xe1, 0x8c, 0x48, 0x5c, 0x76, 0xc5, 0x26, 0xcf, 0x00, 0x6a, 0x14, 0x55, 0xa5, + 0x7e, 0xef, 0xd8, 0xb0, 0xc1, 0x4a, 0xc1, 0x8f, 0x43, 0x7d, 0xb1, 0xef, 0x32, 0x78, 0x04, 0xfd, + 0x6a, 0xa2, 0x01, 0x16, 0xaf, 0x74, 0x19, 0xe8, 0xc1, 0xce, 0x9f, 0xe0, 0x43, 0xc8, 0x9c, 0xa9, + 0xd0, 0x6e, 0xb0, 0x29, 0xbb, 0x78, 0x31, 0xcc, 0x45, 0xb7, 0x4a, 0xff, 0x80, 0x53, 0xb9, 0x57, + 0x97, 0xe9, 0x60, 0xce, 0x5d, 0x26, 0x0c, 0xd6, 0xe3, 0xd2, 0xd1, 0x59, 0x68, 0x82, 0xd4, 0xc3, + 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x86, 0x14, 0xaa, 0x72, 0x28, 0x1c, 0x23, 0xca, 0x8d, 0x54, + 0x31, 0x9f, 0x7a, 0x0c, 0x0b, 0xf9, 0x00, 0x00, 0x13, 0x8d, 0x44, 0xaa, 0x44, 0x4a, 0x06, 0x00, + 0x00, 0x00, 0x02, 0x62, 0xc7, 0xf0, 0xf8, 0x6a, 0xbd, 0x1d, 0x75, 0x02, 0x11, 0x50, 0xcf, 0x51, + 0x7d, 0x12, 0xa8, 0xfe, 0x93, 0xad, 0x29, 0x0a, 0xbf, 0xbb, 0x3b, 0xf3, 0x63, 0x98, 0x6e, 0x85, + 0x73, 0xc1, 0x02, 0x41, 0x87, 0x9c, 0x53, 0xc7, 0x00, 0x57, 0x04, 0x4a, 0x78, 0xda, 0xcb, 0xe0, + 0xed, 0xe5, 0x3f, 0x3f, 0x8d, 0x1c, 0xc9, 0x28, 0xf5, 0x12, 0xcb, 0x34, 0x68, 0x30, 0x7c, 0xe6, + 0x86, 0xbd, 0xe0, 0x48, 0x40, 0x3f, 0xb5, 0x1f, 0x35, 0x6b, 0x32, 0x3b, 0x61, 0x6c, 0xe4, 0xde, + 0x81, 0x3a, 0x96, 0xc4, 0x20, 0xa9, 0xee, 0x87, 0x87, 0x98, 0x05, 0x3c, 0xf2, 0x79, 0x96, 0x3c, + 0x35, 0x1d, 0x6f, 0xd0, 0x0b, 0xbd, 0x6c, 0x0e, 0x54, 0x6a, 0xbe, 0xdd, 0x5b, 0x56, 0x75, 0x13, + 0xc7, 0x42, 0x28, 0x79, 0xc3, 0xfa, 0x0b, 0xc3, 0xaa, 0x5d, 0x99, 0x23, 0xe8, 0xdb, 0x04, 0x7a, + 0xd8, 0x78, 0x50, 0xab, 0x97, 0x12, 0xff, 0xa6, 0xf5, 0x85, 0xa9, 0xae, 0xd4, 0x57, 0xc2, 0x05, + 0x19, 0x3b, 0x6a, 0xac, 0x1b, 0x78, 0x10, 0xad, 0xde, 0x20, 0xc1, 0xa3, 0xdf, 0x57, 0xc4, 0x8f, + 0x2a, 0x00, 0x00, 0x02, 0x96, 0x4e, 0x79, 0x2b, 0xda, 0x72, 0x78, 0xdc, 0x3b, 0x03, 0x55, 0xd0, + 0xa3, 0xc1, 0xf2, 0x22, 0xee, 0x09, 0xf6, 0x72, 0x47, 0xf1, 0x57, 0x46, 0xd9, 0xc9, 0x0b, 0xa0, + 0xb9, 0x66, 0xaa, 0x7b, 0xea, 0x13, 0xc2, 0x08, 0x01, 0x66, 0x8f, 0xb3, 0x55, 0xe3, 0xe2, 0x89, + 0x85, 0xa6, 0xf0, 0xfe, 0xf2, 0x79, 0x86, 0x24, 0x33, 0x99, 0x9b, 0x83, 0xf8, 0x2a, 0x63, 0x47, + 0xa8, 0x98, 0xe4, 0x80, 0xf9, 0x98, 0x38, 0x29, 0x1a, 0xaf, 0x7e, 0xc1, 0x84, 0xfd, 0xc7, 0x07, + 0x8d, 0xc8, 0x92, 0x14, 0x00, 0x03, 0x50, 0xdf, 0xdd, 0x23, 0xc8, 0xd1, 0xa6, 0xb0, 0xa3, 0x10, + 0xd3, 0xe2, 0xdc, 0x57, 0x83, 0xd5, 0x84, 0xb3, 0x47, 0x04, 0x5b, 0xd2, 0xa9, 0xd1, 0xe3, 0xee, + 0xd3, 0x1c, 0x9c, 0xb1, 0x4f, 0xa0, 0x00, 0x00, 0x39, 0x21, 0xe6, 0x8b, 0xa3, 0xd9, 0xbf, 0x1c, + 0x03, 0x7e, 0x78, 0x7c, 0x39, 0x00, 0xe1, 0x70, 0x03, 0x34, 0x10, 0x6e, 0x42, 0xac, 0x8c, 0x40, + 0x4d, 0xe0, 0x71, 0x80, 0x54, 0x1d, 0x67, 0x43, 0x69, 0x34, 0x8a, 0x16, 0x78, 0x56, 0x85, 0xdd, + 0x91, 0x36, 0x51, 0x79, 0x6b, 0x6f, 0x7e, 0x8c, 0x85, 0xa6, 0xf0, 0xfe, 0xf2, 0x79, 0x96, 0x3c, + 0x35, 0x15, 0x1c, 0x7a, 0xf9, 0xb9, 0x15, 0xe0, 0xbb, 0xd6, 0x30, 0xcd, 0x56, 0x50, 0x2b, 0xc4, + 0x80, 0x2b, 0x4e, 0xa8, 0xd5, 0xf6, 0x54, 0x89, 0xbc, 0xbb, 0xc8, 0xfe, 0xa5, 0xd1, 0x00, 0x2d, + 0xcd, 0xb7, 0x7f, 0xd2, 0x26, 0x62, 0xff, 0xc4, 0x7e, 0xf3, 0x6f, 0xfe, 0x5c, 0x06, 0x09, 0xc2, + 0xf6, 0x16, 0x14, 0x4b, 0xaf, 0x70, 0xc8, 0x3b, 0xca, 0xed, 0x32, 0xb6, 0xff, 0x62, 0x16, 0x0b, + 0x57, 0x57, 0x01, 0x38, 0x00, 0x00, 0x9e, 0x5f, 0xc7, 0xf1, 0x08, 0x01, 0xb6, 0x9e, 0x5f, 0xfb, + 0x2e, 0xbf, 0x72, 0xd3, 0x6c, 0x14, 0x21, 0xfb, 0xa6, 0x0c, 0xa3, 0x7a, 0xa0, 0xe9, 0x91, 0xe7, + 0xa7, 0x90, 0xb3, 0x59, 0x84, 0x67, 0x0b, 0x94, 0x88, 0xce, 0x52, 0xd3, 0xfe, 0x67, 0x95, 0x92, + 0xa7, 0x96, 0x3c, 0xfc, 0xf2, 0x39, 0x76, 0x14, 0x65, 0xdb, 0x77, 0x74, 0x9b, 0xd1, 0x69, 0x04, + 0xa5, 0xab, 0x66, 0x61, 0x14, 0x5a, 0xc4, 0xc2, 0x97, 0x58, 0xb2, 0x79, 0x19, 0xe3, 0x67, 0xad, + 0x01, 0x95, 0x51, 0x52, 0x00, 0x01, 0x1a, 0x75, 0xd4, 0xa2, 0x96, 0x59, 0x20, 0x64, 0x25, 0x05, + 0x13, 0xdb, 0x41, 0xe0, 0x85, 0xa5, 0xb0, 0x6d, 0x5b, 0x3c, 0x6a, 0x4c, 0x6c, 0xa4, 0x4a, 0x66, + 0x37, 0x36, 0xa8, 0x1d, 0x4b, 0x1b, 0x17, 0x3c, 0x43, 0x00, 0x00, 0x0f, 0xf6, 0xf6, 0xb0, 0x3a, + 0xff, 0x2d, 0xc1, 0x2b, 0x8c, 0xf8, 0x20, 0x38, 0xb7, 0x83, 0x49, 0x13, 0x72, 0x58, 0xa3, 0xff, + 0x96, 0x2d, 0xd7, 0x2c, 0x60, 0xe6, 0x23, 0x13, 0xe9, 0x12, 0xdc, 0xc7, 0x29, 0x52, 0x97, 0x61, + 0x27, 0x07, 0x8d, 0xb7, 0x10, 0x12, 0x47, 0x34, 0xa5, 0xa6, 0xf0, 0xfe, 0xf2, 0x39, 0x86, 0x34, + 0x33, 0x99, 0xad, 0xf5, 0xb8, 0x20, 0x69, 0x36, 0xc3, 0x36, 0x38, 0x69, 0x6c, 0x55, 0x45, 0x82, + 0xc1, 0x47, 0xb5, 0x00, 0xe6, 0x9e, 0xec, 0x9f, 0xee, 0x9d, 0xda, 0xd3, 0x2b, 0x6e, 0xd8, 0x0b, + 0xa7, 0xab, 0xca, 0xf5, 0xe8, 0xd6, 0x02, 0xfb, 0xfe, 0xa3, 0x2b, 0x5f, 0x27, 0xa7, 0xd3, 0x6a, + 0x26, 0xfb, 0x88, 0x1c, 0xc5, 0xa4, 0xfa, 0x7f, 0x29, 0xfa, 0xd3, 0x67, 0x91, 0x97, 0xae, 0x84, + 0x47, 0x28, 0x00, 0x01, 0x0c, 0x1c, 0x69, 0x6f, 0xde, 0x2c, 0x8b, 0x31, 0x90, 0x4a, 0x1f, 0x06, + 0x39, 0x85, 0x14, 0x2f, 0xf2, 0x66, 0x4e, 0xff, 0x8a, 0xef, 0x13, 0x03, 0x84, 0xc1, 0x09, 0xb8, + 0x35, 0xd2, 0x8b, 0x54, 0xb9, 0x92, 0x86, 0xbe, 0xa8, 0xa5, 0x7c, 0x1c, 0x42, 0xcd, 0x35, 0x91, + 0xa5, 0xa6, 0xf0, 0xfe, 0xf2, 0x39, 0x86, 0x34, 0xaf, 0xde, 0xd3, 0xde, 0x29, 0xed, 0x28, 0x0d, + 0x99, 0xdd, 0xfa, 0x24, 0x1f, 0x60, 0x23, 0x8f, 0x5b, 0x2b, 0x71, 0x00, 0x00, 0x00, 0x18, 0xb9, + 0xe5, 0xc0, 0x40, 0x00, 0x04, 0x38, 0x27, 0x36, 0x94, 0xd7, 0x17, 0x8b, 0x70, 0x4c, 0x86, 0x34, + 0x7b, 0xef, 0x53, 0x59, 0x91, 0x66, 0x04, 0x41, 0xa7, 0x00, 0xcf, 0x10, 0x27, 0xf0, 0xdf, 0x0b, + 0xe1, 0xdb, 0xf8, 0x57, 0x3b, 0x2b, 0x02, 0x49, 0x2b, 0x98, 0x1f, 0x79, 0x70, 0x42, 0x2b, 0xac, + 0x12, 0x63, 0x0f, 0x91, 0x9c, 0xc0, 0x65, 0x85, 0xa5, 0x63, 0x2c, 0xb0, 0x4c, 0x3b, 0x98, 0x88, + 0x18, 0x71, 0x64, 0x0d, 0xdb, 0x8c, 0xeb, 0x07, 0xd4, 0x36, 0x0f, 0xd4, 0x30, 0x84, 0x61, 0x5c, + 0x1f, 0xd1, 0x8c, 0x7e, 0x0f, 0xdf, 0xb0, 0x9c, 0xa4, 0xa7, 0x0a, 0x7e, 0xf2, 0x39, 0x76, 0x34, + 0x33, 0xd7, 0x8c, 0x35, 0x71, 0x03, 0x71, 0x5c, 0x0e, 0x58, 0xb3, 0xc3, 0x3c, 0x24, 0x94, 0x53, + 0x0f, 0x65, 0x75, 0xd3, 0xbc, 0xae, 0x3c, 0x84, 0xde, 0x62, 0x00, 0x21, 0x7b, 0x79, 0x01, 0x6f, + 0xce, 0x47, 0x16, 0xd8, 0x82, 0x42, 0xe2, 0x1c, 0x52, 0x2e, 0xaf, 0x3b, 0xf7, 0xb5, 0x7f, 0xb9, + 0xd6, 0xe7, 0x8f, 0x84, 0x3f, 0xd2, 0x99, 0x4e, 0x15, 0xe1, 0x00, 0xcf, 0x2d, 0x30, 0x00, 0x1b, + 0x38, 0xa2, 0xc8, 0xeb, 0x02, 0x91, 0xdf, 0xfa, 0x7e, 0x00, 0x09, 0x17, 0x86, 0x70, 0x64, 0x95, + 0xa6, 0xb0, 0x5a, 0x5c, 0x18, 0xf1, 0x52, 0xa9, 0x09, 0x1e, 0xb5, 0x79, 0x35, 0x49, 0xe9, 0xb4, + 0xf5, 0xc7, 0x76, 0xea, 0x2c, 0x8f, 0x8e, 0x58, 0x17, 0xaa, 0x5e, 0xa8, 0x80, 0x7a, 0xdb, 0xf8, + 0xa5, 0xaf, 0x06, 0xfe, 0xf2, 0x39, 0x96, 0x34, 0x69, 0xad, 0x39, 0xda, 0x09, 0x4e, 0x4d, 0x05, + 0x63, 0x35, 0x94, 0xf7, 0x7d, 0xae, 0xdc, 0x29, 0x81, 0xb0, 0xdc, 0xae, 0x0f, 0x94, 0x17, 0x00, + 0xce, 0x1e, 0x72, 0x1b, 0x3d, 0x8b, 0xc9, 0x6a, 0x45, 0x35, 0x59, 0x23, 0x13, 0xf9, 0x28, 0x7b, + 0x2a, 0xb1, 0x88, 0xf3, 0x75, 0x67, 0x46, 0xe3, 0xb2, 0x07, 0x9e, 0xc9, 0x85, 0x55, 0x29, 0x05, + 0x2f, 0x7a, 0x1f, 0xe9, 0xed, 0x67, 0x1d, 0x0f, 0xbe, 0x00, 0x29, 0x71, 0xfc, 0xdb, 0xe3, 0x50, + 0x81, 0x10, 0x8d, 0x27, 0x30, 0x00, 0xcc, 0x63, 0x84, 0x3e, 0xd3, 0xd0, 0x61, 0xbd, 0xe2, 0x5b, + 0x5c, 0x0f, 0x9d, 0xd4, 0x69, 0x7e, 0x1f, 0x78, 0xf7, 0xaa, 0xad, 0xfb, 0x56, 0x92, 0xfe, 0x76, + 0x02, 0x38, 0xf6, 0x61, 0x13, 0x95, 0x07, 0x28, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x39, 0x76, 0x14, + 0x35, 0x16, 0xeb, 0x64, 0x8e, 0x38, 0x4c, 0x9d, 0xa2, 0x33, 0x03, 0x67, 0x77, 0x01, 0x8b, 0x94, + 0xda, 0x0d, 0xba, 0x85, 0xab, 0xbb, 0xa7, 0xcd, 0x52, 0xd2, 0x28, 0x48, 0xfd, 0x6a, 0x9e, 0xb3, + 0x97, 0x2a, 0x67, 0x7f, 0x61, 0x7a, 0xd3, 0xc2, 0x95, 0xbc, 0xf3, 0x13, 0xbb, 0x38, 0x2c, 0x5e, + 0xf5, 0x25, 0xd5, 0x35, 0xdd, 0x30, 0xbd, 0x47, 0x6d, 0x7a, 0xdf, 0xbe, 0xe5, 0xf8, 0x87, 0xaa, + 0x00, 0x05, 0x76, 0x4e, 0x2c, 0xfc, 0x61, 0x4a, 0x0a, 0xea, 0xa0, 0xef, 0xe0, 0xce, 0xfd, 0xb2, + 0xca, 0x73, 0xa2, 0x79, 0x6c, 0x79, 0x6b, 0x05, 0xb3, 0x26, 0xd0, 0x6e, 0x98, 0xac, 0x3f, 0x08, + 0xed, 0x75, 0x09, 0xeb, 0xd5, 0xb9, 0xee, 0xd7, 0xca, 0xbe, 0x37, 0xa8, 0x31, 0x09, 0x26, 0xc6, + 0xa5, 0xaf, 0x06, 0xfe, 0xf2, 0x39, 0x76, 0x24, 0x35, 0x7f, 0x23, 0xcf, 0x33, 0x12, 0xde, 0x3c, + 0x10, 0xbc, 0xd5, 0xab, 0xb5, 0x31, 0xde, 0x73, 0xa5, 0xcf, 0xe9, 0xcd, 0xd6, 0xd8, 0xf5, 0x87, + 0x44, 0x23, 0x15, 0x25, 0x51, 0x9e, 0xb2, 0x1f, 0xa3, 0x37, 0xe5, 0x08, 0x12, 0x97, 0xf7, 0x2f, + 0x22, 0x63, 0x53, 0x76, 0x8b, 0x95, 0x50, 0x02, 0x42, 0x2f, 0x94, 0xd5, 0x56, 0x61, 0xa7, 0xde, + 0xa8, 0xcd, 0x25, 0x49, 0x6b, 0xa8, 0x93, 0x33, 0xbd, 0x25, 0x79, 0x9a, 0x79, 0xb9, 0x97, 0xe4, + 0x09, 0xd1, 0x1f, 0xfa, 0x2f, 0xb0, 0x1f, 0x03, 0xc0, 0x79, 0xe0, 0x07, 0x2c, 0xaf, 0x7b, 0xb3, + 0xbf, 0x09, 0x0d, 0x0e, 0x57, 0x8f, 0x5d, 0xa7, 0x79, 0x52, 0x13, 0xf7, 0x24, 0x90, 0x26, 0x9e, + 0x6b, 0xb3, 0x9e, 0x06, 0x3c, 0x1f, 0xd1, 0x2c, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0x96, 0x3c, + 0xaf, 0xdd, 0xec, 0xcd, 0x0b, 0x42, 0x00, 0x00, 0x2e, 0x7a, 0x81, 0xcb, 0x68, 0x5f, 0x8b, 0x27, + 0x5a, 0x66, 0x42, 0x8b, 0xcb, 0xa7, 0xf2, 0x55, 0x8c, 0xf1, 0xbd, 0xff, 0xed, 0x97, 0x68, 0x26, + 0x8d, 0xdc, 0x19, 0x36, 0xc2, 0x4a, 0xa6, 0x3a, 0x55, 0xf0, 0x04, 0x2c, 0xa2, 0x72, 0xac, 0x64, + 0xe9, 0xf3, 0x1c, 0x9d, 0x2d, 0x41, 0xb7, 0x04, 0x2a, 0x28, 0x81, 0x41, 0x4b, 0xf5, 0xc6, 0x12, + 0x71, 0xb9, 0x3a, 0x2b, 0x7d, 0xaf, 0x12, 0xa3, 0xf1, 0xbc, 0x37, 0xb5, 0x78, 0xfe, 0x0f, 0x07, + 0xe1, 0xf1, 0x7f, 0x8d, 0x2e, 0x47, 0x5c, 0x3a, 0x11, 0xa8, 0x02, 0x8a, 0x1f, 0x6b, 0xa3, 0x1e, + 0xa5, 0xb3, 0x7b, 0x04, 0xcc, 0xf9, 0x05, 0xf6, 0xad, 0xe2, 0xe2, 0x27, 0x0f, 0x0f, 0xe5, 0xdc, + 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0x96, 0x3c, 0x64, 0x11, 0x5d, 0x4e, 0x5b, 0x2d, 0x0d, 0x23, + 0xf3, 0x0c, 0x6d, 0x9b, 0x66, 0x35, 0x84, 0xb9, 0x6e, 0x3d, 0x59, 0x00, 0x52, 0xfb, 0x2f, 0x5a, + 0x0d, 0x4e, 0x83, 0x36, 0xdb, 0x38, 0xa4, 0x8f, 0x17, 0x70, 0x3f, 0x1c, 0xd9, 0xba, 0xb5, 0x08, + 0x23, 0x42, 0xe0, 0xae, 0x6b, 0xb7, 0xcc, 0x59, 0xc4, 0xdb, 0xeb, 0xc6, 0x06, 0x8c, 0x3e, 0xfc, + 0xf5, 0x86, 0x6d, 0xf7, 0xc9, 0x28, 0xba, 0x5f, 0xee, 0x8f, 0x52, 0xb4, 0x9b, 0xa7, 0xe7, 0xdb, + 0x94, 0x55, 0x09, 0xbf, 0x72, 0x00, 0x7f, 0x00, 0x7e, 0x07, 0xe1, 0xc0, 0x9f, 0xd2, 0x34, 0xad, + 0x0c, 0xcc, 0xc5, 0x71, 0x48, 0x37, 0xfc, 0xaa, 0x0d, 0x1c, 0x8d, 0xf7, 0x4c, 0x98, 0x79, 0x3a, + 0xe7, 0xba, 0x6b, 0x21, 0xc7, 0x87, 0xf7, 0x2c, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0xa6, 0x3c, + 0x37, 0x6c, 0x53, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x4b, 0x8b, 0xf6, 0x32, 0x39, 0x48, 0x5b, 0x22, + 0x4f, 0x00, 0x00, 0x00, 0xff, 0x87, 0x00, 0x75, 0x5c, 0xf4, 0x0c, 0xd0, 0xec, 0x07, 0x73, 0x83, + 0x31, 0x29, 0xdd, 0x09, 0x57, 0xd3, 0x3c, 0xda, 0xa2, 0x04, 0xb9, 0xad, 0x13, 0xa8, 0x88, 0x84, + 0x87, 0x00, 0x7a, 0xbf, 0x83, 0x33, 0x15, 0xb1, 0xb0, 0xfd, 0x78, 0x12, 0x21, 0x3f, 0x1d, 0x6f, + 0x63, 0x17, 0x1f, 0xac, 0x1c, 0xec, 0x49, 0xfd, 0xa9, 0x85, 0x4f, 0x0d, 0x3d, 0x4f, 0xc0, 0xfc, + 0x3c, 0x0f, 0x0b, 0xf2, 0x04, 0x02, 0x90, 0xff, 0x07, 0x0a, 0x8b, 0x80, 0x71, 0x85, 0xc6, 0x69, + 0xb3, 0x10, 0xa1, 0xd2, 0xdb, 0x27, 0x48, 0xc5, 0x5b, 0xbb, 0xf1, 0xe8, 0x87, 0x3c, 0x3c, 0xd5, + 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0xa6, 0x3c, 0x35, 0x16, 0xad, 0x1b, 0x11, 0x11, 0x2c, 0x31, + 0x9b, 0x11, 0xa4, 0xb4, 0x21, 0x9f, 0x58, 0xa7, 0x69, 0x72, 0x41, 0xff, 0x6d, 0xd2, 0x08, 0x82, + 0x05, 0x1f, 0x5f, 0x56, 0xb5, 0x4f, 0x9c, 0xe6, 0x63, 0xf0, 0x5f, 0xf3, 0x59, 0x48, 0xba, 0x0f, + 0xba, 0x84, 0x33, 0x25, 0x9a, 0x6a, 0x3d, 0x78, 0x05, 0xbc, 0x2f, 0x04, 0xb7, 0x68, 0xac, 0x54, + 0x2b, 0x74, 0xed, 0x1f, 0xef, 0x85, 0x94, 0xd6, 0x82, 0x33, 0xae, 0xc1, 0x19, 0x5b, 0xed, 0x5d, + 0x93, 0x50, 0xac, 0xba, 0xcf, 0xc1, 0x1f, 0xe0, 0x3f, 0x03, 0xe3, 0xc4, 0x01, 0xd7, 0x00, 0xf6, + 0xdf, 0xa6, 0xb8, 0x30, 0x7a, 0xee, 0x1a, 0x36, 0x7f, 0x38, 0x94, 0xc2, 0x6c, 0xc5, 0xab, 0xbe, + 0xc7, 0x82, 0x6b, 0xc8, 0x61, 0xc5, 0xd6, 0xfe, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0xa6, 0x34, + 0xa7, 0x93, 0xab, 0x17, 0xbc, 0xeb, 0xc1, 0x81, 0x22, 0x09, 0x43, 0x88, 0x90, 0x6f, 0x57, 0xec, + 0x00, 0x00, 0x43, 0x7c, 0x81, 0xea, 0x88, 0x05, 0xb7, 0x66, 0xc1, 0x19, 0xc7, 0xb0, 0xbd, 0x0e, + 0x1f, 0x14, 0xc9, 0x40, 0x05, 0xab, 0x02, 0xdf, 0x36, 0x96, 0xec, 0x3c, 0x43, 0xe9, 0x48, 0xba, + 0x41, 0x77, 0x10, 0x1c, 0xc9, 0xa3, 0x68, 0xa4, 0x3c, 0xf0, 0xcd, 0x87, 0x12, 0xb2, 0xc4, 0xef, + 0xd0, 0x2d, 0x71, 0xe5, 0xe6, 0x4d, 0xbf, 0x17, 0xe1, 0x98, 0xc1, 0x4f, 0x60, 0x1f, 0xc0, 0x7e, + 0x07, 0xe0, 0xf8, 0x80, 0xba, 0xbc, 0x7d, 0xe4, 0x47, 0x11, 0xde, 0xe4, 0x65, 0xe1, 0x9b, 0xc0, + 0x7a, 0x3e, 0x40, 0x76, 0x3c, 0x94, 0xe3, 0x1d, 0x5e, 0x5a, 0x40, 0xdb, 0xe8, 0x18, 0x29, 0x7c, + 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0xb6, 0x34, 0x65, 0xca, 0x46, 0xb9, 0x0b, 0x52, 0x79, 0x41, + 0x19, 0xc3, 0x73, 0x41, 0x1c, 0x52, 0xc7, 0x42, 0xc6, 0xcc, 0x7f, 0xb4, 0xf0, 0x18, 0x20, 0x04, + 0x05, 0xc7, 0x3d, 0x84, 0x7a, 0x66, 0xbf, 0x9e, 0xb3, 0x80, 0xf8, 0x8c, 0xb8, 0x90, 0x9a, 0xc0, + 0x59, 0x00, 0x50, 0xa7, 0xf1, 0x3b, 0xf6, 0xbe, 0x59, 0xf8, 0x13, 0xae, 0x02, 0x45, 0xe9, 0xb5, + 0x3c, 0x3d, 0xa3, 0x50, 0xab, 0x50, 0x84, 0x22, 0xfa, 0xc3, 0xc7, 0x70, 0x15, 0x5a, 0x18, 0x73, + 0xae, 0xb3, 0xdb, 0x73, 0x9f, 0x71, 0x55, 0xfc, 0x03, 0xf0, 0x1f, 0x81, 0xc1, 0x4f, 0x75, 0xd8, + 0x5a, 0x3d, 0x42, 0xfc, 0xc3, 0x81, 0x58, 0x1a, 0xb3, 0x61, 0xf4, 0xa5, 0x5d, 0xbd, 0x1c, 0xd3, + 0x7e, 0xfe, 0xbc, 0xf4, 0x1c, 0xe7, 0xda, 0x55, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0x96, 0x3c, + 0x63, 0xc0, 0x39, 0x41, 0x09, 0x13, 0x33, 0xb4, 0x49, 0x82, 0x56, 0xb8, 0x0c, 0xaf, 0x54, 0x24, + 0x61, 0x6b, 0x00, 0x02, 0x55, 0xf8, 0x02, 0x36, 0x24, 0x97, 0x94, 0x17, 0x16, 0xff, 0xc5, 0x5a, + 0x22, 0x7c, 0x45, 0x25, 0xe0, 0x41, 0xe4, 0x40, 0xf9, 0x20, 0x3c, 0xe0, 0x48, 0xbe, 0xa1, 0x54, + 0xef, 0x5d, 0x3a, 0xfb, 0x00, 0xf2, 0x43, 0xda, 0x97, 0x91, 0x47, 0xeb, 0xaf, 0x0a, 0x51, 0x4e, + 0x1c, 0x1d, 0xe5, 0x97, 0x28, 0x4b, 0xa7, 0x23, 0xf4, 0x01, 0xac, 0x53, 0x22, 0x1c, 0xff, 0x07, + 0xf8, 0x0f, 0xc0, 0xfc, 0x1e, 0x02, 0x1d, 0xa7, 0xa3, 0x6b, 0x16, 0x58, 0x99, 0xd1, 0xd9, 0xd7, + 0x5a, 0x5c, 0x25, 0x4f, 0x1b, 0x83, 0x10, 0x9b, 0x65, 0x52, 0xc8, 0xaf, 0x76, 0x22, 0x1c, 0xde, + 0xa5, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0xb6, 0x3c, 0x65, 0xc6, 0xcd, 0x55, 0x50, 0x3d, 0x97, 0x82, + 0x9f, 0x19, 0x08, 0xd8, 0x1e, 0x75, 0xd2, 0x61, 0xc1, 0x35, 0x05, 0xfb, 0x13, 0xa6, 0x14, 0x63, + 0x87, 0x4d, 0x51, 0x0e, 0x16, 0x3b, 0x43, 0xaa, 0xc2, 0x72, 0xbf, 0x1f, 0x9c, 0xf5, 0xc1, 0x07, + 0xc2, 0xc5, 0xd2, 0x77, 0xe1, 0x39, 0xff, 0x43, 0x15, 0x29, 0x64, 0x5b, 0xa3, 0x44, 0x78, 0x93, + 0x88, 0xc1, 0x82, 0x3a, 0x25, 0x6d, 0x0c, 0xbc, 0x4b, 0xba, 0xca, 0xbe, 0xbb, 0x19, 0xe4, 0x8e, + 0x76, 0x0c, 0xe5, 0x8c, 0x8d, 0xcf, 0xe0, 0x7c, 0x3c, 0xc6, 0x0c, 0xfb, 0xdb, 0x2e, 0x16, 0x35, + 0x91, 0x51, 0x29, 0x18, 0x54, 0xad, 0x0b, 0x07, 0x76, 0x42, 0xd7, 0x55, 0x12, 0x6d, 0xce, 0x2f, + 0x7f, 0xe0, 0x78, 0xe0, 0xfe, 0xe6, 0xb2, 0x27, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x46, 0x3c, + 0xa7, 0x93, 0xab, 0x44, 0xbe, 0xa7, 0x80, 0x9c, 0xd3, 0xf8, 0xe1, 0x27, 0x07, 0x73, 0x64, 0x42, + 0xc1, 0x1d, 0x6c, 0x8b, 0xe3, 0xc5, 0x99, 0x2d, 0xf9, 0x62, 0x2e, 0xda, 0xf6, 0xb7, 0x19, 0x5a, + 0x06, 0x49, 0x62, 0x8f, 0x30, 0xe9, 0xb1, 0xc4, 0xd1, 0x09, 0x46, 0x15, 0xc2, 0xd6, 0x7e, 0x50, + 0xf7, 0xef, 0x31, 0x82, 0xef, 0xfb, 0xe2, 0xee, 0xd2, 0x20, 0xcb, 0xe4, 0x73, 0x7b, 0x49, 0x44, + 0x67, 0x23, 0x2e, 0xb8, 0x22, 0xa0, 0xd8, 0xe9, 0xbd, 0x30, 0x34, 0x65, 0x51, 0x6c, 0x01, 0xf7, + 0x80, 0x7e, 0x0f, 0x87, 0xc6, 0x78, 0xcf, 0x07, 0x77, 0x6c, 0x92, 0x63, 0xd6, 0xab, 0x53, 0xbd, + 0x59, 0x26, 0x10, 0xd2, 0xbe, 0xc8, 0x61, 0x41, 0xf0, 0x34, 0x63, 0xf1, 0x10, 0x4c, 0xaa, 0x2c, + 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0x86, 0x3c, 0xaa, 0x5a, 0xbb, 0xd7, 0xf8, 0xbb, 0x6f, 0xc4, + 0xc0, 0x30, 0x3e, 0x19, 0xe0, 0xf5, 0x55, 0x89, 0x37, 0x28, 0xd4, 0x29, 0x0d, 0x1f, 0xfa, 0xc2, + 0x00, 0x12, 0xad, 0x18, 0xd3, 0x85, 0x03, 0xd1, 0x26, 0xba, 0xc3, 0x95, 0x73, 0x0a, 0xff, 0x05, + 0x55, 0xee, 0x12, 0x41, 0x6d, 0x0c, 0x06, 0xf7, 0x01, 0x63, 0x20, 0xf6, 0xf5, 0x75, 0xcb, 0xf4, + 0x34, 0xf4, 0x0d, 0x55, 0x2e, 0x64, 0x61, 0x96, 0xc1, 0x14, 0x18, 0xf0, 0x06, 0xc1, 0x36, 0xa1, + 0xcb, 0xd5, 0x81, 0x08, 0xa3, 0x8a, 0xc0, 0x7f, 0x01, 0xf8, 0x3e, 0x0e, 0x47, 0x81, 0xc7, 0x8c, + 0xa3, 0xf0, 0x44, 0x41, 0x97, 0x61, 0xbd, 0x28, 0x73, 0x24, 0xa1, 0xfc, 0x76, 0x76, 0x57, 0x68, + 0x00, 0x00, 0x08, 0xc3, 0xc1, 0x08, 0xa3, 0x8e, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0x96, 0x3c, + 0x69, 0xb1, 0xb3, 0x14, 0xc6, 0x0a, 0xef, 0xfa, 0x49, 0x55, 0xc7, 0xd6, 0xd6, 0x6f, 0xca, 0x4d, + 0x80, 0x0c, 0x07, 0x98, 0xef, 0xb9, 0xdd, 0xf0, 0x2c, 0x72, 0xfb, 0x82, 0x00, 0xc4, 0xf9, 0x7a, + 0x77, 0x18, 0xf7, 0x13, 0xcd, 0x32, 0x82, 0x84, 0xf3, 0xde, 0x5d, 0xee, 0xec, 0x4a, 0x5a, 0xca, + 0xcd, 0xe0, 0xbe, 0x24, 0xd0, 0xcf, 0xfa, 0xa2, 0x60, 0x8a, 0x57, 0xa1, 0x74, 0x0e, 0xe1, 0xf9, + 0xc5, 0xe7, 0x75, 0x25, 0xe2, 0x19, 0xb8, 0xab, 0x49, 0xea, 0xe3, 0x48, 0x22, 0x98, 0x7e, 0x0f, + 0x81, 0xf1, 0xc1, 0x70, 0xe7, 0xc4, 0xea, 0x0e, 0x16, 0xd8, 0xfb, 0xb9, 0x93, 0x5c, 0x6d, 0x54, + 0x08, 0x7e, 0xc7, 0x90, 0xb6, 0xe5, 0xa7, 0x1f, 0xf1, 0xea, 0xcf, 0xc7, 0xf1, 0xea, 0x71, 0x4c, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, 0x66, 0x71, 0x12, 0xfb, 0xfc, 0xc3, 0xd6, 0xee, + 0x81, 0x60, 0xf5, 0x11, 0x13, 0x17, 0xd4, 0xe0, 0x47, 0x5f, 0x2b, 0x34, 0x69, 0x01, 0x01, 0xfa, + 0xe3, 0x71, 0x62, 0xd5, 0xfd, 0xc6, 0xad, 0xa8, 0xa1, 0x71, 0x0d, 0x50, 0x8b, 0x5f, 0x94, 0xa9, + 0xc6, 0x7b, 0xea, 0x99, 0x12, 0x7b, 0xcf, 0x33, 0xe1, 0x70, 0x52, 0x96, 0x14, 0xb9, 0xb6, 0x56, + 0x20, 0xcf, 0x88, 0x7a, 0x3c, 0x00, 0xf5, 0x8d, 0x82, 0xdc, 0x0c, 0xc0, 0x57, 0xfd, 0xb5, 0xb5, + 0x59, 0x4f, 0xd7, 0xde, 0xa0, 0x3e, 0x03, 0xf0, 0x7c, 0x38, 0x2f, 0x82, 0x4a, 0x02, 0x18, 0xcf, + 0xca, 0xe8, 0xd2, 0x49, 0xee, 0x11, 0x96, 0x2e, 0x8a, 0x02, 0xf1, 0x62, 0x10, 0x78, 0x87, 0x8e, + 0x41, 0x1f, 0x08, 0xc1, 0xa7, 0x11, 0xc5, 0xfc, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, + 0xaf, 0xa6, 0xc8, 0x17, 0xa3, 0x84, 0xdd, 0xa9, 0x0a, 0x0e, 0x89, 0xbc, 0x1f, 0xf0, 0x65, 0x09, + 0x6a, 0x1d, 0x56, 0x2f, 0xf0, 0xcd, 0xa6, 0xba, 0xcb, 0xa2, 0x5d, 0xcf, 0xe8, 0x89, 0x91, 0x7d, + 0x62, 0x41, 0x4e, 0xf4, 0x85, 0xf9, 0x49, 0xeb, 0xaa, 0x66, 0xb7, 0xd9, 0x79, 0x47, 0xfd, 0x78, + 0x49, 0x3b, 0x68, 0x11, 0xfb, 0xee, 0x8a, 0x55, 0x05, 0x04, 0x35, 0xb7, 0x0d, 0x1a, 0xe3, 0xdd, + 0x59, 0xbe, 0xf7, 0xfc, 0x1a, 0xac, 0x1c, 0x3d, 0x70, 0xce, 0xfe, 0x98, 0x40, 0xd7, 0x0f, 0xd0, + 0x7e, 0x1f, 0x0c, 0x1c, 0x32, 0xbe, 0x5f, 0x1a, 0xc2, 0xab, 0xfc, 0xb0, 0xbd, 0x6c, 0x64, 0xf5, + 0x7f, 0x9b, 0xd3, 0x42, 0x77, 0x73, 0xe2, 0x04, 0xdc, 0xf5, 0x7f, 0x9e, 0x3e, 0xdc, 0x61, 0xd7, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, 0x66, 0x6e, 0xc7, 0xba, 0x0b, 0x00, 0x5e, 0x7e, + 0x17, 0x39, 0xe6, 0x76, 0xdb, 0x13, 0xa6, 0x5b, 0x1a, 0x16, 0x1c, 0x88, 0x6f, 0x59, 0x98, 0xe0, + 0x7e, 0x5d, 0xe7, 0xd0, 0xb9, 0x93, 0xdd, 0xf9, 0x87, 0xc2, 0x84, 0xf1, 0xab, 0x86, 0x07, 0x37, + 0x72, 0x2b, 0xcb, 0xb4, 0xe6, 0x9b, 0x62, 0x26, 0x81, 0xde, 0xae, 0xf2, 0x4a, 0x5d, 0xf8, 0xb8, + 0xaa, 0xfa, 0x96, 0x1c, 0x54, 0x35, 0x43, 0xfe, 0xda, 0xeb, 0xc7, 0x9d, 0x8f, 0xbf, 0xc6, 0xb5, + 0x87, 0x7a, 0xc3, 0x90, 0x02, 0x4e, 0xb0, 0x3f, 0x03, 0xf0, 0x78, 0x79, 0x1f, 0x8e, 0x15, 0x14, + 0xa1, 0xae, 0x84, 0x3b, 0x09, 0x62, 0x15, 0x7c, 0x50, 0xf7, 0x78, 0xed, 0x72, 0x41, 0x63, 0xcf, + 0xb3, 0xf0, 0xb0, 0x08, 0x70, 0x26, 0x49, 0xd6, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x2c, + 0x69, 0xd5, 0x7a, 0x69, 0x80, 0x89, 0x16, 0x0e, 0x00, 0x8e, 0xdd, 0xe8, 0xba, 0x4a, 0xb8, 0xd4, + 0x9f, 0x71, 0xd7, 0x2a, 0xd2, 0xf5, 0x0c, 0xc3, 0x4f, 0xfb, 0x22, 0x11, 0x30, 0xb1, 0x93, 0x21, + 0x19, 0x9a, 0xb8, 0x73, 0x51, 0x9e, 0x2a, 0x77, 0x0f, 0x61, 0xbb, 0x18, 0x26, 0x3a, 0x10, 0x35, + 0x4a, 0xa3, 0x35, 0x10, 0x92, 0x56, 0xf5, 0xf5, 0x6e, 0xb8, 0x73, 0x7f, 0xf7, 0x78, 0xd2, 0x36, + 0x2e, 0x72, 0xfa, 0x9d, 0x7a, 0xdd, 0xe3, 0x6a, 0x0e, 0x47, 0x06, 0xa3, 0x23, 0x9f, 0x60, 0x7c, + 0x0f, 0x87, 0x99, 0x1e, 0x63, 0x8f, 0x66, 0xc4, 0x31, 0x76, 0x2d, 0x6a, 0x06, 0xc4, 0xd0, 0x4d, + 0x39, 0x53, 0x65, 0x85, 0x6c, 0xd7, 0x65, 0xdd, 0xf9, 0xa6, 0xf2, 0x18, 0x18, 0x9c, 0x8a, 0xd5, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, 0xaf, 0xae, 0x7f, 0x37, 0x7c, 0x7e, 0xc8, 0x66, + 0x0c, 0xdb, 0xf9, 0x2a, 0xd1, 0xdc, 0x4b, 0xd9, 0xa3, 0x2d, 0xb4, 0x03, 0xae, 0x50, 0x54, 0x60, + 0xdb, 0xbe, 0x75, 0xe2, 0xb8, 0x20, 0xee, 0x0d, 0x6f, 0x53, 0xaf, 0xce, 0x03, 0x41, 0xc2, 0xc2, + 0xbb, 0xd5, 0x1f, 0xb8, 0x7f, 0x2c, 0xad, 0x56, 0x3b, 0x9b, 0xd7, 0xc9, 0xfc, 0xaf, 0x0a, 0x43, + 0x4c, 0xa2, 0xde, 0x6d, 0xf0, 0x57, 0x61, 0x8a, 0x55, 0x0b, 0x3c, 0x37, 0xbc, 0xf5, 0x9f, 0xda, + 0x35, 0xf9, 0x86, 0x34, 0xd4, 0x57, 0x30, 0x7f, 0x07, 0x83, 0xe1, 0xc0, 0x3e, 0x44, 0x81, 0x64, + 0x89, 0x31, 0xd2, 0xa8, 0x04, 0xe1, 0x52, 0x99, 0x84, 0x7b, 0x8b, 0x4d, 0x00, 0x92, 0x95, 0x49, + 0x52, 0x69, 0x84, 0xf8, 0xc7, 0x9a, 0x89, 0xe7, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x56, 0x3c, + 0x33, 0xd2, 0xb4, 0x9f, 0x05, 0xe1, 0xfa, 0x45, 0x00, 0x6f, 0x0a, 0x22, 0x3e, 0x60, 0xae, 0xcf, + 0xa0, 0x2f, 0xfc, 0xb6, 0xa8, 0x52, 0x88, 0x72, 0x12, 0xbe, 0xe9, 0xf3, 0xdc, 0xca, 0xa7, 0xe4, + 0xdd, 0x5a, 0x49, 0x6b, 0x42, 0x48, 0xc7, 0xde, 0x5b, 0x86, 0xf8, 0xd1, 0xc3, 0x56, 0x13, 0x97, + 0x12, 0x80, 0x6b, 0xab, 0x24, 0x24, 0x85, 0xb5, 0x76, 0x41, 0x3a, 0xeb, 0xa4, 0x51, 0xfd, 0x78, + 0x00, 0xd0, 0xa4, 0x3c, 0x79, 0xce, 0x54, 0xc2, 0x36, 0x15, 0x99, 0x46, 0xe7, 0x23, 0x00, 0x7f, + 0x01, 0xe0, 0xf8, 0x78, 0x37, 0xe3, 0x44, 0xf0, 0xc0, 0x24, 0xd0, 0xc9, 0x9c, 0x03, 0xe4, 0x7f, + 0x96, 0x92, 0x05, 0x40, 0xdf, 0xdf, 0x5c, 0xe6, 0xd3, 0xb9, 0xb8, 0x09, 0x04, 0x3b, 0x9c, 0x8c, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x76, 0x3c, 0xaa, 0x72, 0x73, 0xe5, 0x5b, 0x51, 0x7c, 0xb3, + 0x87, 0x46, 0x40, 0x43, 0xe4, 0x19, 0x48, 0x8a, 0xe9, 0x8c, 0x51, 0x10, 0x86, 0x49, 0x47, 0x2b, + 0xdc, 0x88, 0x66, 0xe1, 0x44, 0x5c, 0x6e, 0x7b, 0xcd, 0x5d, 0xb6, 0x3b, 0xb2, 0xd5, 0x9f, 0x93, + 0xd0, 0x94, 0xef, 0xe0, 0x13, 0x33, 0x83, 0xa1, 0x37, 0xb6, 0xc8, 0xc7, 0x15, 0xdb, 0xbf, 0xac, + 0x97, 0xaa, 0x34, 0xe2, 0x45, 0x35, 0xaf, 0x75, 0x67, 0xf1, 0x7a, 0x71, 0xa6, 0xd1, 0x73, 0xdf, + 0x9f, 0x72, 0x46, 0xf8, 0x20, 0xfe, 0x07, 0xc1, 0xf8, 0x3c, 0x1f, 0xc7, 0x06, 0xc5, 0xe4, 0x52, + 0xd2, 0x6f, 0x92, 0x73, 0x58, 0x22, 0xbb, 0xda, 0x8d, 0xc1, 0xa4, 0xf4, 0xa8, 0x4f, 0x5a, 0xb1, + 0x90, 0x29, 0x48, 0x66, 0x47, 0x8d, 0x3a, 0x0c, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x2c, + 0xaf, 0xdd, 0x47, 0x5c, 0xbe, 0xa2, 0xfd, 0xbc, 0xa0, 0x77, 0xc9, 0x9e, 0x7b, 0xc3, 0x7e, 0x20, + 0xd5, 0x15, 0x36, 0xfd, 0x0d, 0xbd, 0xf2, 0x45, 0xb9, 0x05, 0x4f, 0x58, 0xe0, 0xe6, 0x09, 0x9a, + 0x6a, 0xf0, 0xdc, 0x35, 0x0d, 0xe7, 0x80, 0x71, 0xff, 0x81, 0x7f, 0x77, 0xc4, 0xd4, 0x30, 0x13, + 0xdc, 0x3a, 0x2f, 0x79, 0x06, 0x88, 0x87, 0xe1, 0xb9, 0x0c, 0x54, 0xb7, 0xa9, 0xf8, 0x38, 0xed, + 0xa1, 0x82, 0xdd, 0x87, 0xfd, 0x51, 0x3b, 0xe4, 0x1b, 0xb1, 0x30, 0x4e, 0xb7, 0x9e, 0x03, 0xfc, + 0x3e, 0x07, 0xc3, 0xec, 0x43, 0xb8, 0xb3, 0x8d, 0x19, 0xc6, 0x43, 0x27, 0x8f, 0x09, 0x63, 0xe5, + 0xc4, 0x07, 0x41, 0x6f, 0x13, 0x00, 0x79, 0xdd, 0x09, 0x27, 0xde, 0xc4, 0x71, 0x4b, 0xf7, 0xbc, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x56, 0x3c, 0xaa, 0x55, 0xb7, 0x24, 0x58, 0x31, 0x2f, 0x97, + 0x1f, 0x7f, 0x50, 0x76, 0x2c, 0x74, 0x2d, 0xf6, 0xd9, 0xdb, 0xbd, 0x07, 0x39, 0xb5, 0x5a, 0xed, + 0x8d, 0xdc, 0x64, 0x0c, 0x5b, 0x27, 0xc7, 0x96, 0xf2, 0xfc, 0x31, 0x3d, 0x42, 0x39, 0x15, 0x6a, + 0x6b, 0x9d, 0x6e, 0xaf, 0x1e, 0x9a, 0x9c, 0x38, 0x0f, 0xe3, 0x9e, 0xec, 0xd5, 0xed, 0x41, 0x3c, + 0xf8, 0x11, 0xb0, 0x5e, 0x42, 0x46, 0x77, 0xde, 0xb3, 0x5c, 0xd0, 0xba, 0x83, 0xa8, 0xf0, 0x34, + 0x96, 0x44, 0x95, 0xee, 0xfc, 0x07, 0xf0, 0x1f, 0x81, 0xf0, 0xfc, 0x41, 0xfb, 0x1f, 0x47, 0xf8, + 0xcf, 0xef, 0xce, 0xef, 0xaf, 0x96, 0xdf, 0x00, 0x58, 0x72, 0x83, 0xdb, 0x24, 0x20, 0x01, 0xef, + 0x9f, 0x44, 0xb9, 0xa4, 0xe2, 0x91, 0x94, 0xec, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, + 0x66, 0x6e, 0xc7, 0xe6, 0x2e, 0x32, 0x8e, 0x22, 0x9e, 0x55, 0x80, 0x61, 0xe0, 0x8a, 0xa5, 0x3f, + 0x95, 0xe0, 0x55, 0x60, 0x2e, 0xba, 0xaa, 0x4e, 0xd2, 0xfa, 0x76, 0x7c, 0x31, 0xcd, 0x9a, 0xd4, + 0xfc, 0x7d, 0xd3, 0xd3, 0x8c, 0x33, 0x03, 0x2d, 0x76, 0x18, 0xfb, 0x43, 0x89, 0x31, 0xd6, 0x02, + 0xa0, 0x6d, 0x55, 0x10, 0xe8, 0xae, 0x37, 0xe5, 0x60, 0x47, 0xcf, 0xf7, 0x22, 0x25, 0xe6, 0xf7, + 0xcb, 0x99, 0x6d, 0x2d, 0xdb, 0x02, 0x69, 0x16, 0x15, 0x56, 0x6b, 0x07, 0xb1, 0x69, 0xf3, 0x80, + 0xfc, 0x07, 0xf0, 0x7c, 0x70, 0xe6, 0xfd, 0x75, 0x86, 0x94, 0x6b, 0xf8, 0x28, 0x5b, 0x49, 0xf8, + 0x74, 0xc2, 0xba, 0x58, 0xc7, 0x55, 0xb8, 0xc9, 0x9e, 0x2f, 0xfc, 0x03, 0x0f, 0xe2, 0xd3, 0xce, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, 0xaa, 0x6f, 0x07, 0xbb, 0x3f, 0xd8, 0x79, 0x25, + 0x03, 0x41, 0x4e, 0x0b, 0x33, 0x5a, 0x0b, 0x82, 0x3d, 0xae, 0xe8, 0x10, 0x72, 0xb5, 0x7b, 0x96, + 0xe7, 0xd0, 0xc0, 0x40, 0x2f, 0x17, 0x6a, 0x9e, 0xbd, 0xe2, 0x7f, 0xbb, 0x36, 0x3a, 0xb9, 0x0f, + 0x7f, 0x96, 0xf2, 0xfe, 0x0b, 0x12, 0xe9, 0xca, 0xe8, 0x2f, 0x0f, 0x1e, 0x27, 0xf6, 0x80, 0x27, + 0x01, 0x37, 0x81, 0xfe, 0x86, 0x2a, 0x0e, 0x79, 0x90, 0x70, 0xf5, 0xe4, 0xe9, 0x8e, 0x3c, 0x79, + 0xff, 0x3f, 0xf1, 0xc9, 0x02, 0x0b, 0xf1, 0x1f, 0x81, 0xf0, 0x3e, 0xc1, 0xe1, 0x72, 0x33, 0xaf, + 0x29, 0xd5, 0x37, 0x5e, 0x2b, 0x97, 0xdc, 0x9a, 0x12, 0x5c, 0xaf, 0x19, 0x79, 0x9f, 0xa0, 0xef, + 0x02, 0x66, 0xbf, 0x03, 0x82, 0x96, 0x5a, 0xf1, 0x71, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x56, 0x2c, + 0x66, 0x71, 0x55, 0x28, 0xc7, 0xcb, 0x12, 0xbc, 0x67, 0x7c, 0x14, 0xa5, 0xed, 0x35, 0x49, 0x59, + 0x92, 0xd0, 0x51, 0x5d, 0xf1, 0x08, 0x93, 0x64, 0x87, 0xe2, 0x37, 0xe7, 0x02, 0xb8, 0x39, 0xd9, + 0xef, 0xb3, 0x82, 0xd5, 0x1b, 0x32, 0xaa, 0xc6, 0x89, 0x03, 0x80, 0x1c, 0xd4, 0x95, 0x85, 0xc5, + 0xeb, 0x0e, 0x7a, 0x53, 0x7b, 0xfb, 0x24, 0xed, 0x64, 0x1a, 0xe0, 0x87, 0xb8, 0xe5, 0xcf, 0xbe, + 0x6c, 0x17, 0xf2, 0xd6, 0x02, 0x6e, 0x78, 0xa0, 0xc9, 0xfd, 0x8e, 0xd0, 0x00, 0x3f, 0x80, 0xf8, + 0x7e, 0x1f, 0x01, 0x83, 0xe7, 0x04, 0xf8, 0x8c, 0xf0, 0xb5, 0x6f, 0x92, 0xff, 0x8c, 0x32, 0xf8, + 0x12, 0xba, 0xad, 0x59, 0x59, 0x9d, 0x25, 0x6a, 0x6c, 0x4c, 0x81, 0x04, 0xf7, 0x9e, 0xce, 0x80, + 0x71, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x34, 0x65, 0xc9, 0xf7, 0x20, 0x2d, 0xee, 0x82, 0xd8, + 0x1b, 0xb4, 0x62, 0x09, 0x60, 0x29, 0xa1, 0xe1, 0x0d, 0xa7, 0x29, 0xab, 0x31, 0x41, 0x5d, 0x5b, + 0x6c, 0xdf, 0x28, 0xd1, 0x8f, 0x35, 0xa7, 0x24, 0x46, 0xaf, 0x3d, 0xf8, 0xb1, 0xc8, 0x97, 0x1b, + 0x15, 0xae, 0xc8, 0x97, 0x73, 0x95, 0x1d, 0x45, 0x8b, 0xc9, 0x51, 0xeb, 0x9e, 0x15, 0x5d, 0xc4, + 0x20, 0x6b, 0x11, 0x03, 0x23, 0xb9, 0x7d, 0x95, 0xe5, 0x4a, 0x8b, 0x03, 0x69, 0x3c, 0x1f, 0xbe, + 0x8e, 0xf6, 0xe8, 0x93, 0xb3, 0x07, 0xe0, 0x7e, 0x07, 0x81, 0xe0, 0xf1, 0xc7, 0xcc, 0xc3, 0xb1, + 0x6f, 0x14, 0x01, 0x4d, 0xd9, 0x3c, 0xf1, 0x06, 0x1f, 0x35, 0x98, 0x90, 0xaf, 0x1f, 0x19, 0x61, + 0x82, 0x33, 0xfd, 0xe0, 0xa1, 0x0a, 0x62, 0x63, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x56, 0x3c, + 0x63, 0xbe, 0x62, 0x88, 0xda, 0xfc, 0x1e, 0x11, 0x29, 0x0c, 0xe5, 0x1b, 0xe5, 0x41, 0xba, 0xb3, + 0xcf, 0x4a, 0xda, 0xa2, 0x7e, 0x6d, 0x8b, 0xf8, 0xfc, 0xf1, 0x9e, 0x17, 0x6c, 0x9d, 0x19, 0xdd, + 0x81, 0x15, 0xa4, 0x32, 0x73, 0x7e, 0xba, 0xc3, 0x7d, 0x0b, 0xbc, 0x10, 0x11, 0x2f, 0x5f, 0xed, + 0xad, 0xc7, 0x7c, 0x0a, 0xc1, 0xb3, 0xef, 0x0a, 0xec, 0x13, 0x08, 0x9e, 0x12, 0x64, 0xce, 0xf8, + 0xe8, 0x23, 0xf6, 0x67, 0xac, 0x53, 0x50, 0xdc, 0x4a, 0xfc, 0xc3, 0xc0, 0x92, 0x0b, 0x2b, 0xf8, + 0x1f, 0xc1, 0xfc, 0x0f, 0x0f, 0x38, 0xf8, 0x91, 0xa0, 0x10, 0x29, 0x4c, 0xb2, 0xd0, 0x3d, 0x2a, + 0x06, 0xbc, 0x8b, 0x82, 0x18, 0x90, 0x62, 0x7f, 0x67, 0x7e, 0x75, 0xc1, 0xf5, 0x2c, 0x82, 0xc3, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x76, 0x3c, 0x65, 0xdb, 0x69, 0x4c, 0x00, 0x13, 0x80, 0x00, + 0xa5, 0x3d, 0x13, 0x89, 0x11, 0xac, 0x4b, 0x54, 0xdf, 0x73, 0xd1, 0x09, 0x20, 0xc5, 0xd0, 0xd5, + 0x16, 0x47, 0xd8, 0x32, 0x19, 0x4c, 0xa9, 0x7b, 0xb5, 0x42, 0x72, 0x3c, 0x77, 0x89, 0xad, 0xbc, + 0xc0, 0x34, 0xdd, 0xb3, 0x24, 0x80, 0x12, 0x92, 0x8b, 0x8c, 0x31, 0xe9, 0x75, 0x5d, 0x72, 0xc9, + 0x27, 0x0f, 0x5c, 0xc0, 0xb4, 0xbe, 0x67, 0xa3, 0xcc, 0x0f, 0x48, 0x47, 0xbd, 0x9b, 0x05, 0x1c, + 0xbc, 0xa6, 0x41, 0x21, 0x8c, 0x51, 0x78, 0x0f, 0xc0, 0xfc, 0x3f, 0x87, 0xe3, 0x0e, 0x0e, 0xba, + 0xad, 0x50, 0x32, 0xf1, 0x76, 0xa4, 0xf9, 0x0c, 0x36, 0xc1, 0xdd, 0xbc, 0xbf, 0x68, 0x70, 0x01, + 0xc4, 0xe4, 0x17, 0xe2, 0x12, 0x28, 0xc5, 0x9f, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, + 0x35, 0x0a, 0x9e, 0x71, 0xc2, 0xab, 0x24, 0xaf, 0x16, 0xa5, 0x65, 0x01, 0x3c, 0x0e, 0x39, 0x42, + 0x75, 0xf5, 0x02, 0xf0, 0x1a, 0xf6, 0xec, 0xa3, 0x9d, 0xda, 0x93, 0x3d, 0x5f, 0xa8, 0x95, 0xa8, + 0xd0, 0xc3, 0x2c, 0xa8, 0x3a, 0x02, 0x84, 0x45, 0x79, 0x0a, 0x6f, 0x0f, 0x3c, 0xae, 0x11, 0x18, + 0xd9, 0xfe, 0xf6, 0x1c, 0xb0, 0xe0, 0x09, 0x42, 0xd7, 0xe4, 0xec, 0xd2, 0x47, 0xd4, 0xf6, 0xd7, + 0x6e, 0xe3, 0xdf, 0x4e, 0xa0, 0xd7, 0xb3, 0xaa, 0xf6, 0x28, 0x1a, 0xbb, 0x01, 0xc3, 0xaf, 0xc0, + 0xfe, 0x03, 0xf0, 0x7e, 0x3e, 0x70, 0x7c, 0x66, 0x21, 0xe9, 0x30, 0x96, 0xae, 0x2e, 0x1c, 0x3c, + 0xcc, 0x68, 0xec, 0xb1, 0x25, 0x1f, 0xed, 0xaf, 0xeb, 0xd8, 0x89, 0x3c, 0x27, 0x62, 0x38, 0xb1, + 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, 0xaf, 0xd8, 0x66, 0x50, 0x91, 0xce, 0x6e, 0x00, + 0x93, 0x92, 0xf8, 0x3f, 0x41, 0xce, 0x85, 0xf2, 0xea, 0x59, 0x43, 0x74, 0x9f, 0x02, 0x89, 0x7c, + 0xae, 0xc0, 0x18, 0x11, 0x3d, 0x87, 0x63, 0xe9, 0x07, 0xe0, 0xe7, 0x0b, 0x24, 0x7b, 0x46, 0xb2, + 0x3b, 0x4b, 0x21, 0xa9, 0x3e, 0x9b, 0xaa, 0x34, 0x12, 0xa5, 0xbb, 0x35, 0x52, 0xcc, 0x1f, 0xf2, + 0x15, 0x35, 0x3d, 0xa9, 0x0b, 0xd4, 0xbc, 0xbc, 0x06, 0x48, 0x40, 0x53, 0x29, 0x4d, 0x96, 0x1f, + 0xdc, 0x41, 0x94, 0xd4, 0x06, 0x0f, 0xc1, 0xf1, 0xe1, 0xc4, 0x47, 0xc0, 0xf2, 0xb8, 0x9c, 0xc0, + 0x18, 0x92, 0xe2, 0x92, 0x79, 0x25, 0x6a, 0x4e, 0x5c, 0xa5, 0x43, 0x03, 0x9d, 0x56, 0x9e, 0x04, + 0x0c, 0x47, 0xc3, 0x07, 0x86, 0x7d, 0x51, 0xb0, 0x71, 0x72, 0x90, 0x4e, 0xf2, 0x19, 0x36, 0x3c, + 0xaf, 0xde, 0xd9, 0x76, 0xbf, 0xd7, 0xe9, 0x42, 0x20, 0x1c, 0xba, 0xc5, 0xd2, 0x84, 0x1a, 0xc9, + 0xfe, 0xe0, 0xa4, 0x27, 0x91, 0x41, 0x2c, 0x90, 0x21, 0x2f, 0x13, 0xa4, 0x90, 0x44, 0x9c, 0xe3, + 0x21, 0x0b, 0x2f, 0x1b, 0x7a, 0x7c, 0x3d, 0x4b, 0xf1, 0x4d, 0x92, 0x96, 0xea, 0xbe, 0x8b, 0xa2, + 0x21, 0xad, 0x9a, 0x4f, 0x38, 0xb1, 0xe6, 0x7b, 0x70, 0xe0, 0x53, 0xf4, 0xbb, 0x30, 0xf4, 0xa4, + 0xc8, 0x9c, 0x64, 0x84, 0xb5, 0x79, 0xb3, 0x29, 0x8a, 0x99, 0xc4, 0x2c, 0x0e, 0xb8, 0x70, 0xfe, + 0x0f, 0xfc, 0x42, 0x32, 0x6f, 0x4b, 0x8d, 0x8a, 0x00, 0xc9, 0x86, 0x90, 0xbf, 0x0d, 0x82, 0xc1, + 0x3c, 0xc6, 0x77, 0xaa, 0xcc, 0x84, 0xeb, 0xb7, 0xe3, 0x4b, 0xf7, 0x93, 0x88, 0x32, 0x99, 0xf8, + 0x91, 0x72, 0x90, 0x4e, 0xf2, 0x39, 0x26, 0x24, 0x69, 0xd4, 0x3b, 0x66, 0x16, 0x03, 0x00, 0x90, + 0x22, 0x40, 0xfa, 0x1a, 0x04, 0x41, 0xa5, 0xc1, 0xf6, 0xa7, 0x21, 0xd0, 0x0c, 0x43, 0x97, 0x96, + 0x55, 0x0d, 0x1c, 0x01, 0xb6, 0x85, 0x74, 0x0a, 0x78, 0xf3, 0x9b, 0x7c, 0x18, 0x8f, 0x6a, 0x0f, + 0x08, 0x89, 0xbe, 0x3b, 0x7e, 0xe1, 0x0e, 0x27, 0xa2, 0xea, 0xad, 0x9c, 0xcf, 0xd9, 0x4b, 0x40, + 0x73, 0x35, 0x6b, 0xcb, 0x5e, 0x0e, 0xff, 0x17, 0x3c, 0x44, 0x6d, 0xdc, 0x26, 0xbf, 0x28, 0x96, + 0xb2, 0x8d, 0x8d, 0x9e, 0x7d, 0xca, 0x82, 0x51, 0xf0, 0x79, 0xf0, 0xf9, 0x3e, 0x07, 0xff, 0x6c, + 0x30, 0xe9, 0xaf, 0xab, 0x1f, 0x91, 0x02, 0xd7, 0x94, 0xbe, 0x82, 0x8a, 0x58, 0xb6, 0x2c, 0x06, + 0x09, 0x88, 0xfb, 0x99, 0xe3, 0xfd, 0x96, 0xa5, 0x91, 0x72, 0x90, 0x4e, 0xf2, 0x19, 0x56, 0x3c, + 0xaa, 0x55, 0xb7, 0x24, 0x66, 0x3c, 0xcb, 0xe6, 0x01, 0x0d, 0x56, 0xf4, 0x3f, 0x74, 0xbf, 0xfb, + 0x3b, 0x05, 0xdf, 0xcd, 0x00, 0x00, 0x00, 0x00, 0xdd, 0xd3, 0x47, 0x59, 0x30, 0x43, 0xb7, 0x3c, + 0xb8, 0x17, 0xd4, 0x51, 0xe1, 0xa4, 0xb0, 0x52, 0xa9, 0x13, 0xd9, 0xf3, 0x04, 0x48, 0xe2, 0x65, + 0xa7, 0xbb, 0xa8, 0x3c, 0xe1, 0xe7, 0x72, 0x3e, 0x8f, 0x0d, 0xc2, 0x88, 0x6b, 0x25, 0x07, 0x6a, + 0x3c, 0x9b, 0xb7, 0x4e, 0xd7, 0x40, 0x21, 0x03, 0xa6, 0xbb, 0x01, 0x14, 0x4d, 0x59, 0xaf, 0x07, + 0xf0, 0x78, 0x3e, 0x0f, 0xb0, 0x3f, 0x07, 0x2e, 0xca, 0xe0, 0x35, 0xb8, 0x63, 0x37, 0x46, 0xce, + 0x97, 0xb8, 0xcb, 0x3a, 0xce, 0x3e, 0x5b, 0xf9, 0xb6, 0xb2, 0x83, 0x30, 0x70, 0x45, 0x4d, 0xb8, + 0x91, 0x72, 0x90, 0x4e, 0xf2, 0x19, 0x66, 0x3c, 0x69, 0xd4, 0xd7, 0x0f, 0x56, 0xb8, 0x0a, 0x16, + 0xd2, 0xa2, 0x0a, 0xd6, 0x86, 0x63, 0x1d, 0xf5, 0x79, 0x28, 0x93, 0x0f, 0x2e, 0x60, 0x7a, 0x0b, + 0x85, 0x00, 0x03, 0x59, 0x79, 0x93, 0xfb, 0xa4, 0x95, 0xbe, 0xd3, 0x99, 0x09, 0x31, 0x6d, 0xb1, + 0x92, 0xa6, 0x2e, 0x08, 0x89, 0x6a, 0xd8, 0x42, 0x39, 0x62, 0x22, 0x42, 0x9e, 0xb7, 0x0b, 0xbf, + 0xdf, 0xf9, 0xa7, 0x55, 0x5a, 0x0e, 0x93, 0xbe, 0x39, 0x71, 0xb0, 0x97, 0x5d, 0x4f, 0x8e, 0x97, + 0x98, 0xae, 0xd8, 0x3e, 0x94, 0xea, 0x7e, 0x0f, 0x87, 0xe0, 0xe1, 0x8f, 0xe0, 0xff, 0x8e, 0x7d, + 0xc7, 0x5d, 0x99, 0xec, 0x13, 0xf8, 0x27, 0x05, 0x8a, 0x01, 0xb1, 0xd8, 0x84, 0xa4, 0xbd, 0x59, + 0xc6, 0xf6, 0xfe, 0xf7, 0x0e, 0x4d, 0xb4, 0xa8, 0x71, 0x72, 0x90, 0x4e, 0xf2, 0x19, 0x56, 0x3c, + 0xaa, 0x6f, 0xa2, 0xf5, 0xd8, 0xb5, 0x5e, 0xbd, 0x40, 0x81, 0xb1, 0x5e, 0x70, 0x21, 0xab, 0x00, + 0x00, 0x00, 0x00, 0xcd, 0xb9, 0xa5, 0x00, 0xed, 0xc7, 0xf5, 0xf3, 0x79, 0xa1, 0x72, 0xa6, 0xf4, + 0x97, 0x3a, 0x66, 0xf0, 0x06, 0x52, 0xce, 0x4d, 0x40, 0xb0, 0xd7, 0x56, 0x11, 0x36, 0xeb, 0x5f, + 0x76, 0x0e, 0x27, 0x89, 0x4f, 0x90, 0x4e, 0x5f, 0xa4, 0xbb, 0x65, 0x18, 0x7f, 0xbe, 0x5d, 0x33, + 0x3b, 0xf0, 0xee, 0xf3, 0x0c, 0xab, 0x98, 0x21, 0x4f, 0x7f, 0xa8, 0xbd, 0x67, 0xfe, 0x03, 0xf8, + 0x1f, 0xe0, 0x3e, 0x1c, 0x78, 0xc0, 0xfd, 0x3f, 0x79, 0x8b, 0x5c, 0xd1, 0xc2, 0x51, 0x43, 0x45, + 0x1b, 0x0e, 0xeb, 0x9c, 0xc7, 0x1d, 0x54, 0x4d, 0x75, 0x75, 0x30, 0xe8, 0xfc, 0x3c, 0x52, 0xb3, + 0x96, 0xeb, 0x66, 0xaf, 0x72, 0x19, 0x96, 0x3c, 0xaa, 0x6f, 0x27, 0x9f, 0x71, 0x1f, 0xaf, 0xb1, + 0xb2, 0xaa, 0x21, 0x2b, 0x65, 0x0b, 0xb4, 0x98, 0x0f, 0xad, 0x8e, 0x7b, 0xa1, 0xa9, 0x01, 0xf6, + 0x5c, 0x20, 0xcb, 0x10, 0x89, 0x09, 0xdc, 0x57, 0xb2, 0x77, 0x20, 0xc5, 0xa8, 0xd1, 0x2d, 0xa8, + 0xee, 0x9f, 0x47, 0xeb, 0x5e, 0x25, 0x31, 0x90, 0x6b, 0x53, 0x5e, 0x40, 0xda, 0xce, 0x70, 0xc5, + 0x6c, 0xb2, 0xee, 0x9e, 0xfa, 0x48, 0x07, 0x91, 0xdf, 0x85, 0x52, 0x46, 0xc9, 0xd0, 0x4f, 0xb7, + 0xb4, 0xe8, 0x1a, 0x4e, 0xab, 0x03, 0x9e, 0x3e, 0x00, 0x1c, 0x08, 0x5d, 0x0d, 0xa9, 0x97, 0xe4, + 0x32, 0x30, 0x6f, 0x4a, 0xab, 0x3d, 0x4a, 0x09, 0x0a, 0x98, 0xc3, 0x60, 0x4f, 0xb8, 0x7d, 0x0e, + 0x88, 0xb4, 0x68, 0x82, 0xa0, 0x03, 0x5d, 0x9c, 0x96, 0xeb, 0x66, 0xaf, 0x72, 0x39, 0x56, 0x2c, + 0x65, 0xd9, 0x97, 0x01, 0xee, 0x4a, 0x66, 0x11, 0x45, 0x5b, 0xde, 0x86, 0xac, 0xba, 0x65, 0xf1, + 0x3f, 0x56, 0x54, 0x05, 0x5a, 0x39, 0x00, 0x3e, 0x79, 0x2f, 0xbb, 0xcd, 0x63, 0x69, 0xa5, 0x45, + 0x64, 0xab, 0xfe, 0xc9, 0x8f, 0xf9, 0x25, 0xb1, 0x69, 0x21, 0x4b, 0x7f, 0xbb, 0x5c, 0x6b, 0x30, + 0x21, 0xdb, 0x98, 0x32, 0x9e, 0x9f, 0xe5, 0xf3, 0x11, 0x60, 0xeb, 0xc6, 0xcb, 0x74, 0x72, 0xd0, + 0x1c, 0x94, 0xd4, 0xe6, 0xf0, 0x05, 0x5b, 0x02, 0xa4, 0x9f, 0xea, 0x44, 0xb8, 0x0d, 0xf4, 0x73, + 0x08, 0x3c, 0xce, 0x29, 0xf0, 0xb5, 0xe0, 0x48, 0x13, 0xab, 0x4a, 0x47, 0x89, 0xb1, 0x33, 0x8a, + 0xc7, 0xae, 0x39, 0xee, 0xbb, 0x65, 0xb9, 0xe2, 0xa0, 0x72, 0x6e, 0x3e, 0xa0, 0x33, 0x56, 0xa6, + 0x96, 0xeb, 0x66, 0xaf, 0x72, 0x39, 0x76, 0x34, 0x65, 0x57, 0x24, 0xfc, 0x7e, 0x20, 0x8e, 0xb5, + 0x9b, 0x37, 0x73, 0x06, 0x19, 0x9a, 0x84, 0x40, 0x00, 0xeb, 0x19, 0x30, 0xd1, 0x54, 0xd5, 0x11, + 0x6d, 0xaa, 0xac, 0xd6, 0xb9, 0x08, 0xd7, 0x79, 0x4f, 0x4d, 0xe8, 0x27, 0x5b, 0xe1, 0xe6, 0x41, + 0x7b, 0xd4, 0x30, 0x66, 0xc3, 0x67, 0x28, 0x70, 0xaf, 0x1b, 0xcc, 0x6b, 0x7b, 0x12, 0x2a, 0xe6, + 0xfa, 0x7e, 0x23, 0xb9, 0x24, 0x56, 0x92, 0x3b, 0x42, 0xc3, 0xb4, 0x2a, 0x22, 0x3d, 0xae, 0xfb, + 0x8d, 0x73, 0xb5, 0x20, 0x18, 0x5f, 0x63, 0x02, 0x75, 0x91, 0x7d, 0x16, 0xa5, 0xfd, 0x20, 0xe9, + 0x27, 0x80, 0x13, 0xdc, 0xaa, 0xc1, 0x4d, 0xcc, 0x99, 0x00, 0xf8, 0x48, 0x30, 0x2c, 0xb0, 0xa4, + 0x3c, 0x0b, 0x08, 0xbf, 0x63, 0x3d, 0x61, 0xa8, 0xb6, 0xeb, 0x66, 0xaf, 0x72, 0x39, 0x66, 0x34, + 0x63, 0xb3, 0xbd, 0x96, 0xb3, 0x4d, 0xd2, 0xf2, 0xee, 0xa4, 0x40, 0x95, 0x46, 0x7d, 0x46, 0x9e, + 0xa5, 0x6f, 0x5c, 0xe2, 0xfc, 0x70, 0xcf, 0xe0, 0x25, 0xe2, 0x44, 0x10, 0x05, 0x8a, 0xe9, 0xe9, + 0x43, 0xcc, 0x0d, 0x4c, 0x47, 0x14, 0x97, 0xac, 0xf5, 0x79, 0x36, 0x9d, 0xb7, 0xfd, 0xbe, 0xda, + 0x64, 0xa2, 0x70, 0x09, 0x52, 0x83, 0xf9, 0x91, 0xfa, 0x8b, 0x47, 0xd1, 0x2d, 0xee, 0xf4, 0xd9, + 0x41, 0xd9, 0xb2, 0x99, 0xf0, 0x0a, 0x93, 0x8c, 0x30, 0x27, 0xb0, 0x05, 0xfc, 0x58, 0x30, 0x5a, + 0x3f, 0x46, 0x13, 0x90, 0x9a, 0x29, 0x53, 0x60, 0xae, 0x82, 0xad, 0xc1, 0x2b, 0x27, 0x6a, 0x4f, + 0x3e, 0xeb, 0x9b, 0x6e, 0x34, 0x6a, 0x48, 0xf1, 0xb7, 0x33, 0x5a, 0x00, 0x3a, 0x11, 0x4e, 0xea, + 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x66, 0x3c, 0xb6, 0x91, 0xd0, 0xbc, 0x85, 0xad, 0x1c, 0xc1, + 0xc5, 0x74, 0xa3, 0x65, 0x58, 0x79, 0x04, 0x76, 0x1a, 0xba, 0x32, 0xcd, 0xc3, 0xbc, 0x10, 0x62, + 0x17, 0x92, 0x1a, 0x73, 0xac, 0x21, 0xa4, 0xc1, 0x08, 0xc1, 0xfd, 0x0e, 0x4a, 0x33, 0xf2, 0xe8, + 0xfd, 0xab, 0x37, 0x23, 0x66, 0x9d, 0x84, 0xad, 0xa6, 0xc3, 0xf7, 0x8c, 0x0e, 0x73, 0x01, 0x0e, + 0x23, 0xb8, 0x6d, 0x19, 0x5c, 0xed, 0xaf, 0x76, 0xf7, 0x83, 0x0d, 0x7e, 0x89, 0x98, 0x1c, 0x5b, + 0x99, 0x95, 0xb7, 0xe0, 0x48, 0xcf, 0xa0, 0xc6, 0x10, 0x44, 0x89, 0x24, 0xb5, 0x79, 0xc4, 0xfc, + 0xa1, 0xc2, 0x3b, 0x41, 0x53, 0x89, 0xad, 0xce, 0x3e, 0x39, 0xb2, 0x92, 0xea, 0x36, 0xda, 0x4a, + 0xc9, 0x52, 0xc0, 0x19, 0xd9, 0x2a, 0x7d, 0x1e, 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x45, 0xe4, + 0x6e, 0xba, 0xba, 0xbc, 0xf5, 0x92, 0xd9, 0x00, 0x2d, 0x18, 0x51, 0x21, 0x42, 0x93, 0x43, 0xce, + 0x38, 0xfb, 0x80, 0x6f, 0x6f, 0x0d, 0x0b, 0x9f, 0xdc, 0x9e, 0x09, 0xb4, 0x68, 0x96, 0xbb, 0x25, + 0x36, 0xe6, 0x05, 0x3b, 0x83, 0xc4, 0x7c, 0x97, 0x04, 0xf0, 0xf0, 0x31, 0x12, 0x53, 0x28, 0xf5, + 0x3a, 0xb3, 0x4b, 0x50, 0xbc, 0xf6, 0x58, 0x53, 0xe1, 0x94, 0xe2, 0xe0, 0xec, 0x61, 0x35, 0x73, + 0x6c, 0xc2, 0xb6, 0x4b, 0xa6, 0x12, 0x7d, 0x28, 0xbc, 0x29, 0x02, 0x74, 0x71, 0x41, 0xeb, 0xe1, + 0xa5, 0x68, 0xbe, 0xac, 0xde, 0xcf, 0x1a, 0x25, 0x79, 0x66, 0x4f, 0x68, 0xdb, 0xb0, 0x67, 0x7f, + 0xc2, 0xfa, 0x52, 0x88, 0xf8, 0x11, 0x75, 0x0c, 0x37, 0x9b, 0x3c, 0x4d, 0xe2, 0x48, 0x17, 0xa6, + 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x56, 0x3c, 0xaf, 0xe4, 0xa2, 0x89, 0x12, 0x82, 0x0c, 0x29, + 0xbf, 0x24, 0x3d, 0xce, 0x5e, 0x00, 0x0c, 0xb4, 0xea, 0xf0, 0x83, 0x87, 0x99, 0xd9, 0xda, 0xbb, + 0xe1, 0x31, 0xa9, 0x85, 0xd1, 0xdc, 0x6e, 0xff, 0xba, 0xb1, 0xfd, 0x54, 0x95, 0x64, 0xbb, 0x8f, + 0x9e, 0x6f, 0x2a, 0x8a, 0x85, 0xd5, 0xef, 0x6f, 0x2a, 0xdb, 0xb9, 0x1e, 0x90, 0xd0, 0x3d, 0xb3, + 0xb4, 0xd5, 0x21, 0xf7, 0xcc, 0xa0, 0x56, 0x37, 0xd2, 0x04, 0xac, 0xa6, 0xba, 0x35, 0x9b, 0xf8, + 0x54, 0x4f, 0x56, 0x8e, 0x03, 0xba, 0xb7, 0xbe, 0x42, 0xc4, 0x8b, 0xf1, 0x3b, 0x97, 0x91, 0x6e, + 0xa9, 0x3b, 0x56, 0x63, 0x21, 0xe4, 0x32, 0x00, 0x40, 0x49, 0x96, 0x2d, 0x2f, 0x42, 0x1f, 0xce, + 0x9e, 0x2b, 0x45, 0x5f, 0xba, 0x22, 0x4f, 0x66, 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x66, 0x2c, + 0x65, 0xca, 0x4a, 0x9e, 0x20, 0x90, 0xd5, 0xeb, 0xdf, 0xb8, 0x17, 0x31, 0xd9, 0x80, 0x30, 0x3b, + 0x26, 0xd8, 0xa2, 0xbd, 0x5b, 0x02, 0x22, 0x53, 0x50, 0x98, 0xa5, 0x6a, 0x9b, 0x17, 0xd8, 0x89, + 0x3e, 0xf7, 0x00, 0x3d, 0x93, 0xeb, 0x5c, 0x37, 0x12, 0x20, 0x94, 0x6d, 0x2c, 0x0d, 0xcc, 0x20, + 0x04, 0x55, 0xa2, 0x73, 0xbb, 0xc0, 0xaa, 0x95, 0xa2, 0x02, 0x52, 0x9c, 0xf6, 0xb2, 0xd0, 0xc9, + 0xd4, 0x8d, 0xcf, 0xfe, 0xee, 0xa6, 0xc9, 0xf4, 0xd2, 0xd3, 0xca, 0xf8, 0x88, 0x0d, 0xf3, 0xcd, + 0x90, 0xff, 0x03, 0x3e, 0xb9, 0x22, 0x9f, 0x5b, 0x67, 0x40, 0xc7, 0x86, 0x67, 0xba, 0xf2, 0x10, + 0x6a, 0x38, 0xbc, 0x8f, 0x6a, 0x35, 0x69, 0xbf, 0xda, 0xeb, 0xbf, 0x41, 0x56, 0x71, 0x55, 0x4f, + 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x56, 0x34, 0xb6, 0x90, 0xce, 0x2f, 0x9f, 0xa6, 0x39, 0xdb, + 0x76, 0xc2, 0x48, 0x94, 0x8c, 0xd3, 0xc2, 0xc0, 0xde, 0xa3, 0x37, 0xc0, 0x1c, 0x11, 0x2c, 0x9b, + 0x06, 0x3a, 0xbf, 0x47, 0x64, 0x38, 0x2c, 0x56, 0x2b, 0x5d, 0x1d, 0xf6, 0x6e, 0xd3, 0x62, 0x89, + 0x10, 0x2b, 0x5d, 0x15, 0x48, 0x2f, 0x03, 0xa8, 0x07, 0xf3, 0x78, 0xcd, 0xb9, 0xb8, 0xce, 0xe7, + 0x69, 0x39, 0x3c, 0x13, 0x14, 0xd6, 0xb8, 0x8c, 0xe0, 0xcd, 0x8a, 0x23, 0x15, 0x89, 0x83, 0x31, + 0x3a, 0x0c, 0x95, 0xc0, 0xe9, 0xbf, 0x9f, 0xbd, 0x05, 0x61, 0x67, 0xe3, 0x3f, 0x10, 0x9a, 0x29, + 0x72, 0x3c, 0x5a, 0x38, 0xe0, 0xf4, 0x9a, 0x59, 0x9f, 0xd5, 0x44, 0x62, 0xcd, 0xed, 0x00, 0x78, + 0xc2, 0x1c, 0x7c, 0x47, 0xf4, 0xb3, 0x55, 0x13, 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x56, 0x0c, + 0xaf, 0xe5, 0x67, 0xb2, 0x9d, 0xfd, 0x91, 0xaf, 0x74, 0xcd, 0xd3, 0x13, 0x5c, 0xa8, 0x96, 0x7b, + 0x63, 0x82, 0xa3, 0x3f, 0x19, 0xa9, 0xd5, 0xc7, 0x7c, 0x3c, 0x64, 0x11, 0x80, 0x9b, 0xbc, 0x11, + 0x43, 0xf3, 0x6a, 0x02, 0xb4, 0x70, 0x52, 0x0f, 0xeb, 0xf0, 0x41, 0x9f, 0x15, 0x9e, 0xf5, 0xd7, + 0x72, 0x98, 0x4b, 0x06, 0x1a, 0x74, 0x8f, 0x29, 0x1f, 0x0d, 0x38, 0xf7, 0xea, 0xd8, 0xa4, 0x3e, + 0x37, 0xba, 0x03, 0xa9, 0xef, 0x6d, 0x0b, 0x1b, 0x48, 0x97, 0xd7, 0x76, 0x06, 0x66, 0xf0, 0x7d, + 0x2b, 0xe4, 0x56, 0x38, 0x87, 0x5d, 0xb6, 0x00, 0x64, 0x55, 0xe5, 0x31, 0x11, 0xa1, 0xac, 0x9c, + 0x88, 0x28, 0x04, 0xae, 0x9d, 0x14, 0xc5, 0x61, 0x9d, 0x11, 0x54, 0x3e, 0xb3, 0x46, 0x61, 0x0d, + 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x76, 0x34, 0x66, 0x57, 0xfe, 0x3a, 0x35, 0x14, 0xf0, 0x24, + 0x07, 0x8c, 0x8c, 0x9b, 0xdb, 0x06, 0xd7, 0x4c, 0x45, 0xf2, 0x1e, 0x75, 0x12, 0x9a, 0x0e, 0x66, + 0xbe, 0xb8, 0x15, 0x6c, 0x4c, 0xfc, 0x8a, 0x98, 0xac, 0xc0, 0xb0, 0x9c, 0x9a, 0x68, 0xd2, 0xab, + 0x41, 0x7d, 0xb4, 0x82, 0x2c, 0x8f, 0x0f, 0x93, 0xf4, 0xfa, 0x4d, 0x87, 0x76, 0xea, 0x45, 0xe6, + 0x66, 0x05, 0xe3, 0x09, 0x0e, 0x56, 0xf8, 0x16, 0xd6, 0x7e, 0x8f, 0xde, 0x9a, 0x61, 0x67, 0xbd, + 0xe3, 0x77, 0xb9, 0x73, 0x7b, 0xf2, 0x3f, 0x38, 0x88, 0x29, 0x36, 0x88, 0x84, 0x0c, 0x10, 0xd8, + 0x80, 0x6d, 0xbc, 0x26, 0xc8, 0x2c, 0xdd, 0x68, 0xfe, 0x2b, 0x23, 0x73, 0xd2, 0x38, 0x54, 0x63, + 0xc6, 0x57, 0xc7, 0xfe, 0x7e, 0xf7, 0xac, 0xab, 0xb1, 0x2d, 0x5a, 0x8e, 0xf2, 0x39, 0x35, 0x84, + 0xaf, 0xa7, 0x15, 0x3e, 0x78, 0xcd, 0x36, 0xc0, 0x19, 0x4c, 0x1d, 0x8d, 0x0b, 0xc6, 0x83, 0x8e, + 0xcc, 0xc7, 0xb7, 0x14, 0x15, 0x87, 0x95, 0x8b, 0xfb, 0xac, 0x9b, 0xdd, 0x72, 0xdf, 0xef, 0xfe, + 0x15, 0xc7, 0xce, 0xcc, 0xb4, 0x51, 0x23, 0xea, 0x70, 0x2e, 0x1b, 0x60, 0x3e, 0x70, 0x01, 0xb6, + 0xa4, 0xe9, 0xb7, 0x1c, 0x32, 0x64, 0xe3, 0xea, 0x57, 0x1c, 0x65, 0x7f, 0xfd, 0x05, 0x8c, 0xae, + 0x96, 0x79, 0x53, 0x17, 0x42, 0xbf, 0xfd, 0x35, 0x27, 0x6e, 0x3b, 0xd0, 0xb3, 0x3f, 0x90, 0x03, + 0xc4, 0x4a, 0xf3, 0x5a, 0x0f, 0x39, 0xb2, 0x65, 0x8e, 0x4f, 0x0a, 0xb8, 0xfb, 0x03, 0x3e, 0x4f, + 0x8d, 0xf1, 0xa6, 0x2d, 0x8d, 0x85, 0x25, 0x72, 0xe2, 0xcb, 0xec, 0xf7, 0xe1, 0x98, 0xef, 0xe6, + 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x76, 0x2c, 0xaf, 0xde, 0xd3, 0xde, 0x29, 0xec, 0xcb, 0xa8, + 0xa4, 0xa7, 0xdb, 0x9f, 0x13, 0xaa, 0x7c, 0xff, 0x2e, 0x7d, 0x26, 0x00, 0xb7, 0xa0, 0x49, 0x04, + 0x6b, 0x78, 0x0b, 0xfe, 0x7c, 0x8c, 0x2c, 0x86, 0x78, 0x04, 0x92, 0xa5, 0x06, 0x05, 0x40, 0xe5, + 0x5f, 0xe8, 0x5e, 0x1b, 0x4b, 0x53, 0x6e, 0xe4, 0x52, 0xeb, 0x96, 0x18, 0x33, 0xa7, 0x3a, 0xf5, + 0x59, 0xa8, 0xb3, 0x81, 0x20, 0xd7, 0x88, 0x92, 0x6a, 0xdb, 0x6e, 0x81, 0xe5, 0x47, 0xda, 0x84, + 0x83, 0x9a, 0x9e, 0x5e, 0x78, 0x8c, 0x12, 0xf0, 0xc0, 0x35, 0x03, 0x58, 0x3f, 0xec, 0x8f, 0xb7, + 0xe8, 0x74, 0xa6, 0xfb, 0xd1, 0xa2, 0xe2, 0x20, 0x18, 0x86, 0x03, 0x22, 0x43, 0x46, 0x23, 0x76, + 0x22, 0x2f, 0x38, 0x83, 0xdb, 0x90, 0xd3, 0x13, 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x56, 0x3c, + 0x69, 0x22, 0xe4, 0xca, 0x53, 0x96, 0xc7, 0x1b, 0xed, 0xf3, 0x0a, 0xc8, 0xfc, 0x00, 0x5d, 0xa2, + 0x8c, 0x2b, 0x14, 0x70, 0x6d, 0x84, 0x76, 0x1e, 0x00, 0xcc, 0x13, 0xdb, 0xf3, 0x48, 0xbd, 0x79, + 0x77, 0x56, 0x2e, 0x91, 0x75, 0x37, 0x14, 0x9f, 0x29, 0x9a, 0x4f, 0xb9, 0x0e, 0x77, 0x77, 0x5a, + 0x7a, 0x3d, 0xe3, 0x76, 0x36, 0x61, 0xd5, 0xa9, 0xda, 0x5e, 0x27, 0xa5, 0xb8, 0xc9, 0x27, 0xc8, + 0x4f, 0x50, 0x77, 0x0f, 0x14, 0x1e, 0x80, 0x1b, 0xbf, 0xb1, 0xc5, 0x39, 0xaf, 0xe6, 0x82, 0x60, + 0xb0, 0x5e, 0x32, 0xc1, 0xdf, 0xa8, 0x33, 0x70, 0xaf, 0x78, 0x08, 0x1f, 0xce, 0x63, 0x45, 0xbb, + 0xf0, 0xf9, 0x90, 0x3e, 0x11, 0xf3, 0x7e, 0x5d, 0x44, 0x61, 0xe3, 0xa8, 0xbc, 0xaa, 0x71, 0x33, + 0xb1, 0x2d, 0x5a, 0x8e, 0xf2, 0x39, 0x16, 0x2c, 0x65, 0xc7, 0x3e, 0xca, 0xc3, 0x81, 0xb0, 0xa1, + 0x95, 0xf1, 0x83, 0xb4, 0x2a, 0x9f, 0xd9, 0xed, 0xb6, 0x66, 0x25, 0xcd, 0x41, 0x1d, 0x06, 0x01, + 0x57, 0x3c, 0xb7, 0x75, 0xee, 0x9a, 0x64, 0xd7, 0x83, 0x2c, 0x34, 0x42, 0xae, 0x59, 0x21, 0x9c, + 0xaa, 0xc8, 0xfa, 0xfc, 0x6e, 0xb5, 0x4d, 0x14, 0x8d, 0xe4, 0x5a, 0x85, 0xe9, 0xb7, 0xa1, 0x76, + 0x4b, 0x57, 0x1b, 0x8b, 0xa5, 0x91, 0x48, 0xdd, 0x76, 0x47, 0x3d, 0xdf, 0xe3, 0xbd, 0x5f, 0x54, + 0x14, 0x25, 0x9f, 0x11, 0x81, 0xcc, 0x62, 0x83, 0x8f, 0x20, 0x5c, 0xa7, 0x39, 0x37, 0xcd, 0x5f, + 0xb2, 0x30, 0x10, 0x9e, 0x2c, 0xec, 0xb6, 0x65, 0x45, 0xd2, 0x0c, 0x5b, 0xa2, 0x4f, 0x8b, 0xb6, + 0xa1, 0x0b, 0xc2, 0xbb, 0x8c, 0xa5, 0x15, 0x87, 0xb1, 0x2d, 0x5a, 0x8e, 0xf2, 0x39, 0x25, 0xe4, + 0x65, 0xc6, 0xd3, 0xa6, 0x52, 0x43, 0x2a, 0xef, 0x33, 0x6c, 0x87, 0xeb, 0x3a, 0xcf, 0x5d, 0xf0, + 0xc0, 0x08, 0x10, 0x7e, 0x05, 0xb0, 0x45, 0x65, 0x24, 0xd9, 0xe8, 0xb5, 0xf1, 0x9a, 0xbf, 0xc8, + 0xbf, 0x69, 0x46, 0x6a, 0x23, 0xb9, 0x2e, 0x01, 0xea, 0x4d, 0xdf, 0x67, 0xfa, 0x07, 0x84, 0x2e, + 0x59, 0xa2, 0x09, 0x20, 0xdd, 0xf6, 0x02, 0x98, 0xbd, 0xc7, 0x57, 0x85, 0x72, 0x36, 0x1a, 0x2a, + 0x4f, 0x84, 0x15, 0xa8, 0x47, 0x57, 0x9f, 0x57, 0x23, 0xd6, 0xc0, 0x7c, 0x3e, 0xf6, 0x02, 0x3a, + 0xc4, 0x97, 0x5c, 0xc0, 0x52, 0x4c, 0x05, 0x1f, 0x1a, 0xfb, 0x4c, 0x4f, 0x31, 0x4c, 0xc8, 0x02, + 0xfd, 0x73, 0xed, 0x7b, 0x24, 0xe0, 0xc1, 0x61, 0xb8, 0x52, 0x8d, 0x2c, 0x8a, 0xb3, 0x7e, 0xf8, + 0xb1, 0x2d, 0x5a, 0x8e, 0xf2, 0x39, 0x25, 0x84, 0xaf, 0xdd, 0x74, 0x71, 0x44, 0x68, 0xff, 0x2b, + 0x57, 0x71, 0x24, 0x5c, 0x55, 0xa5, 0x54, 0x83, 0x19, 0xf7, 0x1a, 0xc2, 0xe7, 0xdc, 0x46, 0xf0, + 0x09, 0x8b, 0xf5, 0xf3, 0x91, 0x04, 0x22, 0xa1, 0x27, 0x34, 0x0f, 0x64, 0xeb, 0x1f, 0xe5, 0x9b, + 0xcb, 0x22, 0x0f, 0xc3, 0x54, 0x10, 0x78, 0x8c, 0x61, 0xf9, 0xf4, 0x6f, 0xc9, 0xbb, 0x88, 0x86, + 0x73, 0x8a, 0x4c, 0xff, 0x4e, 0x44, 0xc9, 0x5d, 0x96, 0x9f, 0x80, 0x19, 0xe6, 0x78, 0x1f, 0x6b, + 0x00, 0x0c, 0x9f, 0x04, 0x24, 0x74, 0xf0, 0x3c, 0x53, 0x08, 0x2b, 0x3b, 0x50, 0xa9, 0xe8, 0x65, + 0x87, 0x69, 0xf7, 0xd4, 0x59, 0x0e, 0x0b, 0x9d, 0x1e, 0x11, 0x0a, 0xe6, 0x57, 0x11, 0x78, 0x08, + 0xd0, 0x64, 0x47, 0x05, 0xae, 0x94, 0x89, 0xbc, 0xb1, 0x31, 0xa7, 0x0e, 0xf2, 0x39, 0x15, 0xfc, + 0xb6, 0x85, 0x63, 0x1f, 0x20, 0xc0, 0x06, 0x36, 0xe0, 0xa7, 0x4a, 0xc5, 0xad, 0x13, 0x1f, 0xa7, + 0x8a, 0xd5, 0x1a, 0xab, 0xdc, 0xc1, 0x6b, 0xa9, 0x50, 0xfb, 0x62, 0xc5, 0x48, 0xf1, 0x9b, 0x9b, + 0x2c, 0xe8, 0x56, 0xcf, 0x2a, 0x04, 0xa4, 0x0b, 0xd5, 0x36, 0xda, 0x6a, 0xa8, 0xa7, 0xa9, 0x58, + 0xef, 0xa2, 0x35, 0x74, 0x48, 0xc9, 0xa2, 0xb5, 0x48, 0xeb, 0x2f, 0x99, 0x26, 0x75, 0xf9, 0xeb, + 0x35, 0xc1, 0x92, 0xec, 0xda, 0x01, 0xee, 0x4e, 0xef, 0x15, 0xe6, 0x87, 0x03, 0xf7, 0x73, 0xc5, + 0x6f, 0x02, 0xf5, 0xbe, 0x1f, 0x49, 0x0f, 0x88, 0x0b, 0xe3, 0x24, 0x06, 0xed, 0xe1, 0xa1, 0xe3, + 0x33, 0x5b, 0xbb, 0xae, 0x10, 0x01, 0xd0, 0xd8, 0x63, 0xe2, 0x15, 0x44, 0xdf, 0xd3, 0x7b, 0x5b, + 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x76, 0x0c, 0x69, 0x22, 0x72, 0xe4, 0x98, 0xd5, 0x8a, 0x89, + 0x1c, 0x65, 0xc4, 0x6e, 0x00, 0x17, 0x29, 0x54, 0x3d, 0xd5, 0x58, 0x43, 0xc0, 0x33, 0x85, 0x15, + 0x9d, 0xf1, 0x19, 0x3f, 0x72, 0x51, 0xcf, 0x81, 0xb7, 0x6b, 0xd7, 0x35, 0x69, 0x08, 0xe1, 0x13, + 0x3b, 0x78, 0x0a, 0xe1, 0x1b, 0xa7, 0xe8, 0x72, 0x10, 0x55, 0xb9, 0x20, 0x11, 0x50, 0xa4, 0x17, + 0x87, 0x12, 0xfa, 0xf9, 0xf4, 0x1d, 0x4f, 0x08, 0x95, 0x82, 0x72, 0x9e, 0xc9, 0x0f, 0xe9, 0x01, + 0x21, 0x7f, 0xde, 0xf8, 0x10, 0x38, 0x56, 0x3b, 0x20, 0xa7, 0x02, 0x3f, 0x16, 0x3c, 0x36, 0x81, + 0x69, 0xa6, 0x1a, 0xcc, 0x51, 0xac, 0x6d, 0x79, 0x9a, 0xda, 0x1c, 0xca, 0xa7, 0x96, 0x95, 0x6b, + 0x00, 0xb0, 0x61, 0x1c, 0xce, 0xc3, 0x6f, 0xb7, 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x55, 0x84, + 0xaa, 0x56, 0xbf, 0xa9, 0xda, 0x3c, 0x9d, 0xc3, 0xf5, 0xac, 0x60, 0x1e, 0x1a, 0xd8, 0x19, 0xdf, + 0x0a, 0x71, 0x4a, 0xfc, 0xe5, 0xc4, 0x08, 0x23, 0xec, 0x2f, 0x4c, 0x6c, 0xa6, 0x7c, 0x21, 0x4a, + 0xdd, 0xb3, 0xca, 0x0f, 0xbb, 0x13, 0x27, 0x92, 0x69, 0xde, 0x0e, 0xe7, 0x16, 0xd4, 0x62, 0x1a, + 0x7c, 0xd8, 0xef, 0xcd, 0xcd, 0xdd, 0x83, 0xbd, 0x7f, 0xaa, 0x22, 0xc3, 0x04, 0xe2, 0x4d, 0x2b, + 0xe4, 0x6f, 0xd2, 0x4e, 0xb8, 0x46, 0x41, 0x47, 0xbe, 0x19, 0x09, 0xfc, 0x60, 0x43, 0x60, 0x39, + 0x1d, 0xda, 0x13, 0x3e, 0x0d, 0x1d, 0xc8, 0x68, 0xbc, 0x05, 0x49, 0xa7, 0xc1, 0x3b, 0x2a, 0x03, + 0x60, 0x25, 0xba, 0xac, 0xd5, 0x4b, 0x2c, 0x64, 0x83, 0x96, 0x80, 0x4d, 0xa0, 0x66, 0xab, 0x1e, + 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x55, 0xf4, 0xaa, 0x56, 0x81, 0x76, 0xd9, 0xc8, 0x2c, 0x73, + 0x36, 0x0f, 0xea, 0x62, 0xe2, 0x2c, 0x3b, 0x4b, 0x43, 0xdc, 0x2e, 0x7a, 0x64, 0xf5, 0xc9, 0xb4, + 0xd3, 0x00, 0x02, 0x38, 0xc4, 0x99, 0x45, 0x1a, 0x98, 0x04, 0x95, 0xd5, 0xbe, 0x36, 0xa9, 0xd1, + 0x88, 0xf0, 0xc3, 0x1f, 0xe5, 0x6a, 0x61, 0xac, 0x5d, 0x5e, 0x7d, 0xf0, 0xc3, 0x0a, 0x06, 0x20, + 0xde, 0xe4, 0xe3, 0x4a, 0x50, 0xae, 0xea, 0xbd, 0x97, 0xb0, 0xe4, 0xe6, 0x13, 0x25, 0x13, 0x3c, + 0x9d, 0xd1, 0x00, 0xfb, 0x94, 0xff, 0xb8, 0x13, 0x63, 0x79, 0x7c, 0x38, 0xbf, 0x96, 0x4e, 0xec, + 0x8b, 0x24, 0xd3, 0x67, 0xf1, 0x6a, 0x56, 0x7b, 0xca, 0xf1, 0xee, 0x32, 0x3b, 0x01, 0x12, 0x00, + 0x37, 0xa9, 0x23, 0xe6, 0xf7, 0x12, 0x74, 0xe1, 0x95, 0xed, 0xae, 0xab, 0x72, 0x39, 0x65, 0xbc, + 0x65, 0xc7, 0x3e, 0xba, 0x36, 0x09, 0x27, 0x54, 0x8f, 0xf1, 0xe9, 0x4f, 0x64, 0x30, 0xaa, 0x29, + 0x9f, 0x5d, 0x65, 0x00, 0x00, 0x53, 0x82, 0x0f, 0xdd, 0x1c, 0x37, 0x3a, 0xbf, 0xb6, 0xba, 0xf1, + 0xbe, 0x00, 0xc8, 0x58, 0x9b, 0xbf, 0x78, 0xc5, 0xbe, 0x78, 0x7f, 0xd3, 0xb0, 0xdc, 0x2f, 0xd4, + 0xbd, 0x16, 0x7f, 0xbb, 0x36, 0xd3, 0x5f, 0x75, 0x99, 0x27, 0x3c, 0xd8, 0x44, 0xed, 0xbd, 0xb7, + 0xc1, 0xe7, 0x56, 0x27, 0x63, 0x3c, 0xa2, 0x25, 0x5b, 0xc6, 0x93, 0x9d, 0x03, 0x96, 0x19, 0xa4, + 0xd9, 0x58, 0xeb, 0xf9, 0xf4, 0xcb, 0x05, 0xa2, 0x20, 0xac, 0xf4, 0xed, 0x1a, 0xc8, 0x32, 0xa8, + 0x88, 0xc3, 0xad, 0x15, 0xcc, 0x10, 0x65, 0xd1, 0x83, 0xe4, 0x99, 0xf9, 0xfe, 0xaa, 0x44, 0xd0, + 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x76, 0x1c, 0x69, 0x22, 0x06, 0xbe, 0xcf, 0xbb, 0x90, 0x18, + 0x52, 0x80, 0x9a, 0xbc, 0x72, 0x5b, 0x82, 0xed, 0x4f, 0x22, 0x04, 0xca, 0xe6, 0xf0, 0x1d, 0x3e, + 0x19, 0x9d, 0xcc, 0xb2, 0x6a, 0x37, 0x5a, 0xa8, 0x24, 0x0d, 0x27, 0x00, 0xeb, 0x99, 0xa9, 0x6c, + 0x96, 0xd9, 0x30, 0x39, 0x3f, 0xcb, 0x4d, 0x9f, 0x97, 0x8d, 0x5a, 0xd6, 0x71, 0x42, 0x8b, 0x1d, + 0xf5, 0x72, 0x87, 0x7d, 0x4c, 0x2c, 0x80, 0x01, 0x8a, 0x1a, 0x30, 0x68, 0x6f, 0xfb, 0x6c, 0x5b, + 0xc0, 0xe8, 0x73, 0x0f, 0x77, 0xae, 0x69, 0xa2, 0xba, 0x3b, 0x86, 0xf3, 0x22, 0x1e, 0xda, 0x7b, + 0xc8, 0x50, 0xc9, 0x12, 0x89, 0xff, 0xe6, 0x57, 0xe2, 0x50, 0xef, 0x1e, 0x37, 0xda, 0xc5, 0x1d, + 0xcf, 0x63, 0xcf, 0x1c, 0x79, 0x8e, 0xf8, 0xb8, 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x29, 0x56, 0x2c, + 0x65, 0xca, 0x0c, 0x46, 0xc6, 0x0f, 0x6d, 0xc2, 0xc1, 0x9d, 0x46, 0x6b, 0x63, 0x2f, 0x24, 0x80, + 0xf9, 0x0e, 0x34, 0xbf, 0x1b, 0x00, 0x23, 0x4d, 0xef, 0x2f, 0x3f, 0x36, 0xfc, 0x5e, 0x98, 0x6d, + 0x00, 0xf5, 0x32, 0x7b, 0x17, 0x4e, 0xb7, 0xc8, 0x7f, 0x4f, 0xcb, 0x75, 0x42, 0x94, 0x8f, 0x1c, + 0x77, 0x91, 0x21, 0x58, 0x0a, 0x9f, 0xe2, 0xf0, 0x24, 0x82, 0x60, 0x38, 0x15, 0x9c, 0x66, 0xa4, + 0x0c, 0xce, 0xd7, 0x98, 0x92, 0x21, 0x82, 0xad, 0x64, 0x05, 0x9f, 0x1c, 0x81, 0x78, 0x31, 0x2e, + 0xb3, 0x35, 0xd8, 0x39, 0x26, 0xa0, 0xae, 0x18, 0xdf, 0x9b, 0x15, 0xc8, 0x54, 0x3f, 0x72, 0x73, + 0xaa, 0x6c, 0x99, 0xf3, 0x01, 0x82, 0x3f, 0x06, 0xf9, 0x22, 0x80, 0x50, 0x3f, 0xb4, 0x5d, 0x64, + 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x76, 0x34, 0x65, 0xc7, 0x3e, 0xbd, 0x54, 0x3b, 0x16, 0x90, + 0xdc, 0x7d, 0x82, 0x5b, 0x33, 0x8a, 0xc1, 0x6a, 0x59, 0x44, 0x23, 0x87, 0x50, 0xa1, 0xc5, 0x00, + 0x00, 0x6c, 0xf6, 0x1e, 0x90, 0xfc, 0x00, 0x04, 0x36, 0x8c, 0x59, 0x9a, 0x9d, 0x6a, 0x98, 0x8f, + 0x31, 0xb2, 0x25, 0xe6, 0xca, 0x2c, 0x83, 0x26, 0x7b, 0x52, 0xdc, 0x27, 0x9f, 0xda, 0x74, 0x90, + 0xba, 0xc2, 0x2e, 0x09, 0x02, 0xec, 0xe6, 0xf4, 0x1a, 0x97, 0xc7, 0x82, 0xcf, 0x75, 0x6a, 0x2c, + 0x26, 0x04, 0x81, 0xd3, 0x70, 0xd0, 0x9c, 0x6a, 0x4e, 0x50, 0x87, 0x3f, 0x15, 0x8e, 0x6f, 0x20, + 0x50, 0xa9, 0x84, 0xea, 0xfd, 0xdf, 0x55, 0xd9, 0xb3, 0x49, 0x67, 0xc0, 0x43, 0xd2, 0xf5, 0x68, + 0x0a, 0x65, 0x54, 0x12, 0xcb, 0x7a, 0x6d, 0x50, 0xb5, 0xe9, 0x62, 0x2b, 0x72, 0x39, 0x75, 0xec, + 0xaa, 0x72, 0x28, 0x1c, 0x23, 0xca, 0x8c, 0x31, 0x24, 0xa3, 0x04, 0x8f, 0x88, 0xe2, 0xd0, 0x51, + 0x97, 0x8f, 0x00, 0xee, 0xb9, 0x2c, 0x03, 0xa3, 0x1a, 0x73, 0xd9, 0x42, 0xbc, 0x46, 0x13, 0x46, + 0x00, 0x00, 0xee, 0xc8, 0xb4, 0xc5, 0x3c, 0xe6, 0xa4, 0xe8, 0x67, 0x45, 0xf7, 0xcc, 0x7d, 0xdd, + 0x15, 0x48, 0xcf, 0xc1, 0x49, 0x8c, 0xef, 0x61, 0x96, 0xd6, 0xd9, 0x36, 0x6d, 0xb5, 0x2d, 0x39, + 0x73, 0x56, 0x21, 0xa7, 0x00, 0xf6, 0xe3, 0x6e, 0xc2, 0xf8, 0x82, 0xf9, 0x01, 0x70, 0xd3, 0x0a, + 0x44, 0xed, 0xe6, 0x74, 0xfe, 0xbe, 0xbd, 0xc4, 0xff, 0x43, 0x28, 0x18, 0xa1, 0xa4, 0x95, 0xde, + 0x49, 0x6c, 0x24, 0xc7, 0xcb, 0x7c, 0x5e, 0x71, 0xc1, 0xf9, 0x37, 0xcb, 0x11, 0xc9, 0x4a, 0xa4, + 0x95, 0xe9, 0x62, 0x2b, 0x72, 0x39, 0x65, 0x8c, 0xaf, 0xdd, 0x47, 0x5c, 0xb0, 0x00, 0x49, 0x93, + 0x33, 0x62, 0x33, 0xea, 0x01, 0x96, 0x10, 0xe9, 0xad, 0x31, 0x60, 0x63, 0xf9, 0x70, 0xb5, 0x05, + 0x93, 0x21, 0x00, 0x00, 0x00, 0x1b, 0xf0, 0xb4, 0x11, 0x74, 0xb8, 0x13, 0x3f, 0xe9, 0xa0, 0x87, + 0xa9, 0xeb, 0xf4, 0x90, 0xcd, 0xf1, 0xd5, 0x98, 0xa1, 0xc7, 0xc4, 0xf3, 0x2d, 0xe2, 0x38, 0x12, + 0x1b, 0x59, 0x0c, 0xa0, 0x6f, 0x2d, 0x00, 0xd6, 0xfb, 0xfd, 0x1f, 0x4f, 0xac, 0x83, 0x66, 0xe6, + 0x30, 0xf0, 0xe1, 0xe6, 0x5f, 0xfe, 0x37, 0x82, 0xde, 0x01, 0xe0, 0x63, 0x6f, 0x7a, 0x5b, 0x81, + 0x01, 0xf1, 0x7c, 0x58, 0x9f, 0x4a, 0x7d, 0x11, 0xd2, 0xd3, 0x20, 0x4e, 0xb5, 0xfc, 0xe3, 0x28, + 0xd9, 0x0b, 0xf6, 0x5d, 0x8e, 0x1c, 0x1c, 0xec, 0xb5, 0xed, 0xae, 0xab, 0x72, 0x29, 0x85, 0xcb, + 0xb0, 0xdc, 0x57, 0x20, 0xf0, 0xa7, 0x97, 0x09, 0x74, 0xb4, 0x8e, 0xbb, 0x8a, 0x26, 0x54, 0xe4, + 0xcd, 0x48, 0x58, 0xcc, 0xea, 0xe0, 0x6f, 0x98, 0xb6, 0x00, 0xa4, 0x1b, 0x6d, 0x00, 0x2b, 0x3a, + 0xcf, 0x5b, 0xb7, 0x5e, 0xc5, 0x12, 0x68, 0xd3, 0xaf, 0x2c, 0x53, 0x43, 0x57, 0x1f, 0xe2, 0xb6, + 0x6e, 0xb0, 0xe1, 0x95, 0x7e, 0x6d, 0x63, 0x04, 0x32, 0x58, 0x9d, 0x3a, 0xe8, 0xe2, 0x21, 0xc5, + 0x2e, 0x45, 0x56, 0xec, 0x38, 0x53, 0xe1, 0x0c, 0x98, 0xcd, 0x8f, 0x00, 0xc0, 0x58, 0x8f, 0x80, + 0x4e, 0x14, 0x9d, 0x44, 0x39, 0x0f, 0xa9, 0x8f, 0x67, 0xc8, 0xed, 0xf4, 0x69, 0x45, 0x64, 0x76, + 0x98, 0x5f, 0x96, 0xa1, 0x88, 0x8c, 0xdf, 0x5f, 0x19, 0x7e, 0xc7, 0x26, 0xc1, 0x18, 0x78, 0xdc, + 0xb4, 0x71, 0x61, 0x8b, 0x72, 0x29, 0x85, 0xf3, 0xaf, 0xdd, 0x47, 0x5c, 0xf8, 0xf7, 0x5d, 0x32, + 0xb2, 0x35, 0x24, 0x6f, 0x38, 0xf4, 0x7c, 0x9b, 0x23, 0x39, 0xdd, 0xd4, 0x86, 0x97, 0xff, 0xc8, + 0x61, 0x9b, 0xf3, 0xf2, 0xad, 0x9b, 0xb1, 0x5d, 0x07, 0x94, 0x64, 0x06, 0x3a, 0x87, 0xec, 0x50, + 0x74, 0x21, 0x00, 0xc6, 0x46, 0x09, 0xba, 0xd1, 0x31, 0x47, 0xa6, 0xeb, 0x5f, 0x5a, 0xd6, 0x49, + 0x18, 0xeb, 0x1b, 0x99, 0xf5, 0x21, 0x5a, 0xe8, 0xb0, 0xa7, 0x38, 0xc6, 0xc7, 0xf9, 0x21, 0x4a, + 0x13, 0x0a, 0xf8, 0xe6, 0xae, 0xf9, 0x9f, 0x9f, 0x40, 0x68, 0x50, 0xb8, 0x9f, 0x0c, 0xe8, 0x70, + 0xc4, 0x70, 0x33, 0x08, 0xdd, 0x46, 0x76, 0x76, 0x55, 0x74, 0x43, 0x17, 0xc9, 0xcc, 0xbb, 0x6b, + 0x50, 0x86, 0xda, 0x12, 0x79, 0x9f, 0x04, 0xaf, 0xb4, 0x4d, 0x18, 0x0b, 0x72, 0x29, 0x75, 0x83, + 0x37, 0xe8, 0x78, 0x4c, 0xdd, 0x28, 0xd1, 0xf1, 0xa5, 0x1f, 0xea, 0x9c, 0x2d, 0x1f, 0xfc, 0x29, + 0x3b, 0xca, 0x42, 0xdd, 0x56, 0x2f, 0x55, 0xaa, 0x11, 0x41, 0x23, 0x4b, 0xe0, 0x8a, 0xfe, 0x4d, + 0x49, 0x93, 0x7e, 0xd0, 0x3a, 0x26, 0x94, 0xcf, 0x54, 0xd2, 0x73, 0x43, 0xa5, 0x86, 0x08, 0x3b, + 0xdb, 0x9c, 0x33, 0x0b, 0xde, 0xd1, 0x22, 0x51, 0xa9, 0xff, 0x73, 0xe3, 0xe2, 0x0d, 0x78, 0x3b, + 0xc0, 0x66, 0xc1, 0x2b, 0x3f, 0x97, 0x7e, 0x13, 0xc7, 0x4a, 0x5b, 0x87, 0x8f, 0x43, 0xa4, 0xc2, + 0x3c, 0xad, 0xf1, 0x1a, 0x7c, 0x94, 0xfa, 0x33, 0x6a, 0xa2, 0x0c, 0x5c, 0x62, 0x75, 0x00, 0x42, + 0xab, 0xed, 0x05, 0x25, 0x58, 0x69, 0x4e, 0xc1, 0xcc, 0x53, 0xc6, 0x54, 0xc6, 0x1c, 0xce, 0x94, + 0xb4, 0x4d, 0x18, 0x0b, 0x72, 0x39, 0x55, 0xab, 0xaf, 0xa7, 0x15, 0xa8, 0xfa, 0xa5, 0x34, 0x80, + 0x03, 0xb3, 0x75, 0xe8, 0x13, 0x94, 0x18, 0xdc, 0xd8, 0x42, 0xea, 0x90, 0x95, 0x6b, 0x37, 0x53, + 0x2e, 0x0f, 0xc1, 0x0f, 0xa9, 0x55, 0x71, 0xa2, 0xbe, 0xee, 0xe2, 0x16, 0xb0, 0x47, 0x82, 0x1f, + 0x91, 0x53, 0xc1, 0xa2, 0x19, 0xc8, 0x5e, 0x37, 0x98, 0x7f, 0x20, 0x33, 0x91, 0x1b, 0x8a, 0x12, + 0xc1, 0x67, 0xa5, 0xbf, 0x6a, 0xa6, 0xc2, 0xe9, 0xf2, 0xe6, 0x21, 0x4a, 0xf0, 0xba, 0xed, 0xa3, + 0x9f, 0x8d, 0xe3, 0xc3, 0x54, 0xac, 0x01, 0x62, 0x53, 0x20, 0x7c, 0x7c, 0x53, 0x59, 0x5b, 0xd3, + 0x8a, 0x6d, 0x86, 0x32, 0x50, 0x58, 0xc5, 0xe8, 0xe3, 0xf8, 0xff, 0xc4, 0x91, 0x89, 0x75, 0x2e, + 0x8a, 0xe4, 0x9e, 0x73, 0xda, 0x64, 0x27, 0x83, 0x94, 0x3c, 0x71, 0x0b, 0x72, 0x39, 0x55, 0x6b, + 0xaf, 0xdd, 0x47, 0x5c, 0xc7, 0x48, 0xbf, 0x31, 0x23, 0xf9, 0x44, 0x19, 0xad, 0x87, 0xee, 0x99, + 0xce, 0xdd, 0xbe, 0xba, 0x25, 0x83, 0x36, 0x59, 0x62, 0x45, 0x2f, 0xcc, 0xb3, 0x56, 0xae, 0x24, + 0xc9, 0xf1, 0x9d, 0x05, 0x11, 0x5d, 0x68, 0x98, 0x71, 0xd4, 0xef, 0xa6, 0xc2, 0x21, 0x6e, 0x39, + 0x11, 0x0b, 0x96, 0x04, 0xc0, 0xfc, 0x74, 0xa4, 0xe5, 0x0e, 0xef, 0x05, 0x1a, 0x4d, 0x1e, 0x83, + 0xa8, 0xdd, 0x5f, 0xcd, 0x23, 0x89, 0x26, 0xad, 0x27, 0x0f, 0x14, 0xa0, 0xba, 0x22, 0x87, 0x05, + 0x98, 0xab, 0x84, 0x4e, 0x9f, 0x7d, 0x8e, 0x28, 0x09, 0x8f, 0xf2, 0xe1, 0xe6, 0xbe, 0xa3, 0x9e, + 0xf4, 0xb4, 0xd3, 0x2d, 0x93, 0xb5, 0x8c, 0xe6, 0x3b, 0x7e, 0x27, 0x17, 0x9c, 0x31, 0x26, 0x42, + 0xb4, 0x3c, 0x71, 0x0b, 0x72, 0x29, 0x65, 0x4b, 0xaf, 0xdc, 0xf2, 0xe1, 0x37, 0x69, 0x8f, 0x62, + 0x94, 0xaa, 0x2e, 0x8f, 0x4c, 0x13, 0x76, 0x24, 0xa7, 0xc5, 0x6a, 0xeb, 0xcd, 0xe4, 0x11, 0x6e, + 0xaa, 0x4d, 0x5a, 0xbc, 0x30, 0x81, 0xcb, 0xaf, 0x22, 0x20, 0x00, 0x55, 0x45, 0x25, 0x83, 0xf9, + 0xb2, 0x42, 0x42, 0x5c, 0x7f, 0x20, 0x1c, 0x45, 0x7d, 0x12, 0xa8, 0xfe, 0x93, 0xad, 0x29, 0x9e, + 0xb1, 0xdc, 0xc6, 0xaa, 0xc1, 0xb5, 0x4d, 0xae, 0xe6, 0xe2, 0x50, 0x62, 0x66, 0xb7, 0x13, 0x9e, + 0x84, 0xe3, 0xed, 0x02, 0x90, 0x01, 0x84, 0x09, 0x8e, 0x18, 0x12, 0xe0, 0xf9, 0x0f, 0x38, 0x35, + 0xb1, 0x62, 0x99, 0x3a, 0xc5, 0x21, 0x65, 0xa1, 0x4e, 0xe5, 0x63, 0x3f, 0x9c, 0x43, 0x63, 0xb4, + 0xae, 0xc8, 0x52, 0x31, 0xa2, 0x2a, 0xf5, 0xf3, 0x94, 0x3c, 0x71, 0x0b, 0x72, 0x39, 0x55, 0x53, + 0xaf, 0xa6, 0xca, 0x13, 0x95, 0x17, 0x6c, 0x2d, 0x47, 0x4e, 0xf4, 0x3a, 0xb8, 0xf0, 0x27, 0x55, + 0xf9, 0x78, 0x67, 0x4e, 0x50, 0x6a, 0xc0, 0x2b, 0x9f, 0xe5, 0xda, 0x28, 0xcc, 0x23, 0xae, 0x95, + 0xd0, 0xc0, 0xff, 0x90, 0xcf, 0xf1, 0x89, 0x7e, 0xc9, 0x79, 0x70, 0x48, 0xc4, 0x47, 0x85, 0x26, + 0x37, 0x26, 0xc4, 0x55, 0x42, 0xd7, 0xd3, 0x69, 0x9f, 0x2f, 0xe7, 0xf4, 0x2c, 0x5d, 0x96, 0x37, + 0xb0, 0xb7, 0x47, 0x3d, 0x1e, 0x3d, 0xf3, 0x39, 0xe5, 0xdc, 0xe7, 0x81, 0xf1, 0x7d, 0x22, 0xd7, + 0x09, 0xee, 0x56, 0x19, 0xe7, 0xc6, 0x53, 0x43, 0x0c, 0x8b, 0x37, 0x62, 0x68, 0x9e, 0x90, 0xa8, + 0x88, 0x9b, 0x14, 0x5d, 0x29, 0xdf, 0xaf, 0xfa, 0x7d, 0x7e, 0x0f, 0x63, 0xb3, 0xc7, 0x2e, 0xbf, + 0x94, 0x3c, 0x71, 0x0b, 0x72, 0x29, 0x45, 0x4b, 0x69, 0xab, 0xe4, 0x62, 0x9f, 0xb0, 0x4e, 0xd3, + 0x48, 0xa7, 0xb8, 0xa8, 0x6b, 0x21, 0xd6, 0x1a, 0x0d, 0xcc, 0xe5, 0x36, 0xc5, 0x24, 0xba, 0xad, + 0xdf, 0x35, 0xe1, 0x45, 0xa8, 0xd4, 0x8c, 0x4e, 0x88, 0x37, 0x5f, 0x09, 0x05, 0x0d, 0x8d, 0x14, + 0x44, 0xd7, 0x7e, 0x17, 0x13, 0xa4, 0xd4, 0x74, 0x9d, 0x64, 0x6d, 0x60, 0xd0, 0x4c, 0x82, 0x4e, + 0x3a, 0xb4, 0x3b, 0xd6, 0xe3, 0xa9, 0xe3, 0xda, 0x0b, 0x97, 0xec, 0xc4, 0x1a, 0x65, 0x64, 0x4a, + 0x00, 0x38, 0xf2, 0x3c, 0x3f, 0x09, 0x9e, 0x22, 0x2b, 0x00, 0xaf, 0x4c, 0xac, 0x3b, 0x00, 0x1d, + 0x25, 0xab, 0x0b, 0x1a, 0x56, 0xe1, 0x7b, 0x8e, 0xc8, 0x80, 0x4e, 0x68, 0xcf, 0x18, 0x74, 0x19, + 0x10, 0x2c, 0xa0, 0x8c, 0x42, 0x04, 0x38, 0xf7, 0xb4, 0x4d, 0x18, 0x0b, 0x72, 0x29, 0x65, 0x4b, + 0xb0, 0xd2, 0xbf, 0xfa, 0x22, 0x62, 0xa0, 0x3a, 0xbe, 0x16, 0x43, 0x4e, 0xd1, 0x9e, 0x40, 0x98, + 0x3c, 0x1c, 0x26, 0xe8, 0x69, 0xae, 0x0e, 0x13, 0xa9, 0x1e, 0x42, 0x47, 0x9e, 0x7a, 0x56, 0xf6, + 0xc0, 0xb6, 0xbb, 0x80, 0x00, 0x34, 0xd4, 0x27, 0x3b, 0x31, 0x20, 0xa2, 0xdb, 0x0e, 0x81, 0xe9, + 0x23, 0x27, 0x8c, 0xd2, 0x20, 0xf6, 0x1a, 0x79, 0xe7, 0x23, 0x51, 0xec, 0x6f, 0x15, 0x7c, 0x7f, + 0x7b, 0xce, 0xa9, 0x30, 0xf9, 0xb4, 0x4a, 0x1e, 0x27, 0x3e, 0xc3, 0xe1, 0x10, 0x60, 0xfa, 0xc1, + 0x62, 0x6a, 0x67, 0x43, 0x62, 0xe1, 0x9d, 0x30, 0x75, 0x2a, 0x19, 0xf1, 0x5e, 0xd6, 0x06, 0xaf, + 0x46, 0xb7, 0x1c, 0x47, 0x0d, 0xc8, 0xd3, 0xc3, 0x65, 0xf0, 0x66, 0x83, 0xc5, 0x9e, 0xe3, 0x1c, + 0xb4, 0x3c, 0x71, 0x0b, 0x72, 0x29, 0x45, 0x63, 0xb0, 0xd2, 0xc2, 0x06, 0xf4, 0x6c, 0xfb, 0xc1, + 0x8f, 0x89, 0x8a, 0x74, 0x0a, 0xd2, 0x5f, 0x4a, 0xf9, 0x7c, 0x3c, 0x51, 0xcf, 0x28, 0x07, 0x36, + 0xca, 0xbd, 0x7a, 0xcd, 0xd0, 0x57, 0x1f, 0x54, 0x01, 0x19, 0x8c, 0xd0, 0x8b, 0x1e, 0x40, 0xa5, + 0x76, 0x7f, 0xb0, 0x25, 0x79, 0x3c, 0xa4, 0x51, 0x74, 0xa3, 0x6a, 0x53, 0x44, 0xbb, 0x9a, 0x39, + 0xa7, 0x8b, 0xd4, 0x66, 0xe5, 0x8e, 0x52, 0xc9, 0xbb, 0x9e, 0x2a, 0x19, 0x31, 0x12, 0x15, 0x5d, + 0x4b, 0x8f, 0xfc, 0x08, 0xb2, 0xd3, 0x0a, 0xb8, 0xad, 0xa7, 0x38, 0xba, 0xd6, 0x83, 0xb3, 0xe8, + 0x74, 0x04, 0xd4, 0x19, 0x01, 0xc4, 0xc3, 0x96, 0xe5, 0x8a, 0xe1, 0x17, 0x09, 0xf0, 0xd4, 0x40, + 0x9a, 0xce, 0x1b, 0x1e, 0x1c, 0x9c, 0x3d, 0x0b, 0xb2, 0xfc, 0xd5, 0xcb, 0x72, 0x29, 0x55, 0x43, + 0xaf, 0xdd, 0x92, 0x47, 0xe0, 0x4e, 0xf8, 0xd3, 0x44, 0x79, 0xec, 0x05, 0x38, 0xd5, 0x9d, 0xfe, + 0xec, 0x81, 0xc0, 0xd3, 0x3d, 0xcd, 0x5c, 0x3b, 0x04, 0x92, 0x44, 0x6b, 0x60, 0x15, 0xc9, 0x08, + 0xc9, 0x19, 0xe7, 0xc3, 0x95, 0x00, 0x06, 0xf0, 0x63, 0x39, 0x2f, 0x9d, 0xca, 0xe7, 0xdd, 0x5e, + 0xe8, 0x42, 0x60, 0xae, 0xf7, 0x3d, 0x54, 0x97, 0xc8, 0xf0, 0xae, 0xe7, 0xc9, 0x19, 0xc0, 0xba, + 0xeb, 0xff, 0x21, 0xa9, 0xe4, 0xbd, 0x3f, 0xfb, 0xb8, 0x4a, 0x9c, 0x3e, 0x48, 0x8c, 0x19, 0xc2, + 0x61, 0xcf, 0x94, 0xd6, 0x20, 0x58, 0x2e, 0x7f, 0x00, 0x95, 0x6f, 0x65, 0x5d, 0x45, 0xc6, 0x76, + 0x59, 0x54, 0x9c, 0xa5, 0x52, 0x15, 0x68, 0x05, 0x92, 0x9e, 0xd3, 0x98, 0x75, 0xdc, 0x37, 0x6e, + 0xb2, 0xfc, 0xd5, 0xcb, 0x72, 0x39, 0x45, 0x3b, 0xaf, 0xa6, 0xc8, 0x6c, 0x71, 0xa7, 0x64, 0xc8, + 0x03, 0xf6, 0x41, 0x91, 0xe2, 0xaa, 0x0d, 0x16, 0x53, 0xcc, 0x0b, 0xaf, 0xcf, 0x29, 0x88, 0x88, + 0xc5, 0x52, 0x40, 0x05, 0x03, 0x49, 0xbe, 0xcf, 0x29, 0x47, 0xdf, 0x86, 0x00, 0x00, 0x0d, 0xa8, + 0x9a, 0x70, 0xe5, 0x7d, 0xbc, 0x39, 0xd0, 0xee, 0x27, 0x3b, 0xea, 0xfa, 0xaa, 0xb5, 0x90, 0x9d, + 0xfc, 0xb9, 0x2d, 0x43, 0xa0, 0xb7, 0xc5, 0xb3, 0xb4, 0x38, 0xfa, 0x6c, 0xe8, 0x55, 0x2e, 0xba, + 0xd9, 0xe1, 0xdc, 0xe1, 0x38, 0x0e, 0xf7, 0xe6, 0x8b, 0x29, 0xbc, 0xe9, 0x93, 0x90, 0x6a, 0x66, + 0x5b, 0x06, 0x91, 0x5d, 0x4c, 0xfe, 0x15, 0x15, 0x8f, 0xd5, 0xd3, 0x82, 0xfd, 0x0b, 0xc9, 0x02, + 0x71, 0x31, 0x8d, 0xc7, 0x03, 0x0e, 0x1e, 0x33, 0xb2, 0xfc, 0xd5, 0xcb, 0x72, 0x29, 0x45, 0x43, + 0xaf, 0xdd, 0x49, 0x48, 0xd3, 0x75, 0x5e, 0xb0, 0xd0, 0xb0, 0x73, 0x72, 0x7d, 0x02, 0x7b, 0x87, + 0x8e, 0x21, 0xd1, 0xd1, 0xac, 0x4a, 0xb8, 0x7d, 0x1a, 0x56, 0x42, 0x43, 0x9a, 0x3b, 0xfe, 0xda, + 0x43, 0xb4, 0x11, 0x0a, 0x88, 0x0e, 0x16, 0xf1, 0xfe, 0x0c, 0x9b, 0x62, 0x20, 0x22, 0x25, 0x69, + 0xb6, 0x6d, 0x50, 0x93, 0x3e, 0xa7, 0x40, 0x85, 0x5a, 0xd0, 0x9d, 0x33, 0x8c, 0x92, 0xf5, 0x19, + 0xdd, 0xef, 0x2b, 0x3e, 0xb3, 0xdb, 0xf7, 0x91, 0xd6, 0x0d, 0xd3, 0x21, 0x10, 0xc0, 0xaf, 0x56, + 0x95, 0xac, 0x9e, 0x9c, 0xde, 0xb4, 0x81, 0x1f, 0x47, 0xf9, 0x0f, 0xdd, 0xbe, 0x03, 0xab, 0x3a, + 0x4c, 0x2e, 0x80, 0x3a, 0xc2, 0x27, 0x1c, 0x68, 0x60, 0x65, 0xce, 0x31, 0x43, 0x9d, 0x32, 0x63, + 0xb2, 0xfc, 0xd5, 0xcb, 0x72, 0x29, 0x35, 0x43, 0xaf, 0xdd, 0x47, 0x5c, 0xf9, 0x00, 0xce, 0xda, + 0x72, 0x75, 0xe5, 0xce, 0x0f, 0xda, 0x63, 0xf1, 0xbb, 0x2f, 0x6e, 0x27, 0xaf, 0xc9, 0xf9, 0x05, + 0x2f, 0x3b, 0x77, 0x81, 0x72, 0xfe, 0x1c, 0x01, 0xb7, 0x00, 0xf3, 0x32, 0x27, 0x6c, 0xfa, 0x1e, + 0xeb, 0x80, 0x00, 0x1b, 0xe5, 0x20, 0x2d, 0x53, 0x50, 0xe1, 0x92, 0x72, 0x7d, 0x1d, 0x9b, 0x6f, + 0xaa, 0x9d, 0x8a, 0x3c, 0x5a, 0xa6, 0xa0, 0x19, 0xf7, 0x4b, 0x4f, 0x1a, 0xc7, 0x13, 0xae, 0xcf, + 0xa1, 0x80, 0x05, 0x8a, 0x1b, 0x78, 0x51, 0xe3, 0x70, 0x5e, 0x7f, 0x7a, 0x5b, 0x7b, 0x03, 0x67, + 0x5c, 0x30, 0xb4, 0xbe, 0xc5, 0xf1, 0x4d, 0x2b, 0x9d, 0x95, 0xf2, 0xe0, 0x68, 0x3f, 0x9c, 0x71, + 0xe0, 0x3c, 0x0f, 0x82, 0x06, 0xc1, 0xb1, 0xdc, 0xb2, 0xf7, 0x96, 0xcf, 0x72, 0x29, 0x25, 0x1b, + 0xaf, 0xa7, 0x16, 0x19, 0x40, 0xf1, 0x9c, 0x25, 0x92, 0x3f, 0x33, 0xb2, 0xbf, 0x20, 0xb3, 0xa0, + 0x2d, 0x5d, 0xae, 0x21, 0xf2, 0xc5, 0xb8, 0x11, 0x55, 0x11, 0x4b, 0x02, 0xc7, 0x79, 0x44, 0x5f, + 0x48, 0xb5, 0x1e, 0x16, 0x00, 0x07, 0x9a, 0xbe, 0xf0, 0x4d, 0x7d, 0x00, 0x20, 0x8a, 0x54, 0xf4, + 0x21, 0xf3, 0x81, 0x1d, 0x49, 0x66, 0x9c, 0xb5, 0xf2, 0x32, 0xa6, 0xcb, 0x96, 0xd0, 0x2c, 0xd0, + 0x20, 0x1c, 0xfa, 0xce, 0xa2, 0x43, 0x4a, 0x0f, 0xf1, 0x51, 0x82, 0x6f, 0x87, 0xde, 0x9d, 0x20, + 0x17, 0x72, 0x69, 0x02, 0xe2, 0x8d, 0x0c, 0x3f, 0x68, 0x87, 0x07, 0xaa, 0xf2, 0xd7, 0xec, 0xd4, + 0x8c, 0x01, 0xc2, 0x79, 0x02, 0xbf, 0xfb, 0xc6, 0x29, 0xa4, 0x65, 0x31, 0xdb, 0x5a, 0x65, 0xbc, + 0xb2, 0xf7, 0x96, 0xcb, 0x72, 0x39, 0x55, 0x34, 0xaf, 0xa6, 0xc8, 0x17, 0xb7, 0x7d, 0xd5, 0xca, + 0x74, 0xc2, 0x5c, 0x37, 0x77, 0xf3, 0xf9, 0x9b, 0x22, 0xa2, 0x30, 0x43, 0x24, 0x9d, 0x13, 0xb0, + 0x8c, 0x2c, 0xb4, 0x26, 0x5b, 0x91, 0xcb, 0xd0, 0x02, 0xe9, 0xea, 0x3e, 0xb9, 0xbd, 0xc7, 0xd3, + 0x12, 0x4c, 0x44, 0xcf, 0xfe, 0xee, 0xb3, 0xfc, 0xf8, 0x7d, 0xd0, 0x28, 0xd0, 0xc9, 0x5e, 0xbc, + 0x0a, 0xd6, 0xf6, 0xa7, 0x19, 0x4a, 0x53, 0x3b, 0x45, 0xfb, 0x17, 0x90, 0x9b, 0xd2, 0xf2, 0x03, + 0xea, 0x1f, 0x0f, 0x0a, 0x3d, 0x82, 0xd0, 0x92, 0x50, 0x3c, 0xaa, 0x8f, 0x0c, 0x9c, 0x2a, 0x03, + 0xb0, 0x76, 0x51, 0xab, 0x45, 0x27, 0xa8, 0x00, 0x0e, 0x31, 0xf1, 0x68, 0x25, 0x0d, 0x5f, 0x8a, + 0xf2, 0x87, 0xf8, 0x7c, 0x38, 0xdf, 0x67, 0x04, 0x92, 0xf7, 0x96, 0xcb, 0x72, 0x29, 0x25, 0x4b, + 0x69, 0xd4, 0x6d, 0x1c, 0xb8, 0xb2, 0x19, 0x82, 0x7a, 0xc5, 0x7e, 0x26, 0xbd, 0x0c, 0x51, 0xe1, + 0xb3, 0x8e, 0xe9, 0xf5, 0x0e, 0xec, 0x92, 0x79, 0x9c, 0x5d, 0x5a, 0xec, 0x4d, 0x1f, 0x9d, 0x03, + 0x5e, 0xcf, 0x10, 0x00, 0x00, 0x55, 0xb2, 0xb3, 0x23, 0xfd, 0xa2, 0x86, 0x58, 0xeb, 0xdd, 0xe8, + 0x29, 0xc3, 0x02, 0x4a, 0x66, 0x04, 0x41, 0xa8, 0x85, 0x6d, 0xc4, 0x07, 0xd7, 0x1f, 0xec, 0x46, + 0x3d, 0xbf, 0x8b, 0xf1, 0x3d, 0xb8, 0xf0, 0x7d, 0x6c, 0xd3, 0xaf, 0x80, 0x5a, 0x1b, 0x43, 0xd9, + 0x89, 0xd4, 0x91, 0xbd, 0x3c, 0xf1, 0x53, 0x86, 0x1c, 0x31, 0x38, 0x7f, 0x08, 0x17, 0x77, 0x73, + 0x60, 0x20, 0x4f, 0x4b, 0x66, 0x09, 0x76, 0x38, 0xdf, 0x8e, 0x00, 0x20, 0x19, 0xfb, 0x36, 0xe8, + 0xd2, 0xf7, 0x96, 0xcb, 0x72, 0x39, 0x55, 0x44, 0x69, 0xd5, 0x83, 0xaf, 0xc3, 0x79, 0x09, 0x0e, + 0x52, 0xd2, 0x55, 0x8d, 0x78, 0xcc, 0x3a, 0x6c, 0x65, 0xc1, 0xcc, 0x02, 0xac, 0x02, 0x40, 0x73, + 0x29, 0x63, 0x1f, 0x13, 0x45, 0x67, 0x03, 0xf9, 0x08, 0xa2, 0x20, 0x00, 0x00, 0x91, 0x15, 0xe4, + 0x27, 0x74, 0xe0, 0xf0, 0x90, 0x05, 0x2f, 0xda, 0x12, 0xdd, 0xaa, 0x2d, 0x00, 0x25, 0xf0, 0xd5, + 0xaa, 0x72, 0xa6, 0x30, 0xc6, 0x7f, 0x9d, 0x33, 0xce, 0x22, 0xcd, 0x65, 0x84, 0x35, 0xe8, 0xe2, + 0xb8, 0x0d, 0xf0, 0xa5, 0x40, 0x79, 0x01, 0x28, 0x6b, 0x0c, 0x32, 0x89, 0x4e, 0xc0, 0xe7, 0xef, + 0xb6, 0x85, 0xd9, 0x63, 0x91, 0x85, 0xee, 0x0c, 0xa5, 0x7d, 0x71, 0xf3, 0x29, 0x01, 0xbd, 0x52, + 0x57, 0xd7, 0x48, 0x13, 0x63, 0xb8, 0xb0, 0x09, 0xb2, 0xf7, 0x96, 0xcb, 0x72, 0x39, 0x55, 0x44, + 0x69, 0xd9, 0xef, 0x6c, 0xb2, 0x38, 0xbe, 0x9e, 0x51, 0xd0, 0xd9, 0x42, 0xfd, 0xf2, 0xa0, 0x1d, + 0x83, 0x0d, 0xb8, 0xeb, 0xbe, 0xfd, 0xdd, 0xc4, 0x1b, 0x86, 0xb7, 0xa3, 0x2d, 0x79, 0x91, 0xc5, + 0x58, 0x6c, 0x47, 0x20, 0x4f, 0xe9, 0x53, 0xab, 0x16, 0x22, 0x45, 0x5c, 0xa5, 0xce, 0x7c, 0x0f, + 0xd6, 0xd0, 0xd1, 0x15, 0x95, 0x10, 0xb9, 0xb1, 0x25, 0x79, 0x74, 0x07, 0x2e, 0xb8, 0x2a, 0x55, + 0x42, 0x4f, 0xd6, 0x45, 0x3d, 0x5e, 0x19, 0x86, 0x0a, 0x28, 0xc1, 0x36, 0xf7, 0xeb, 0x9e, 0x8e, + 0xe0, 0x34, 0x21, 0x87, 0x47, 0xdb, 0x03, 0x3f, 0x4a, 0x88, 0x12, 0x43, 0x86, 0x68, 0x7a, 0x1c, + 0x55, 0x66, 0x1d, 0x6b, 0x0a, 0xb3, 0x03, 0x12, 0x7e, 0x30, 0xd2, 0xc4, 0x89, 0x6a, 0xc8, 0x71, + 0xb2, 0xf7, 0x96, 0xcb, 0x72, 0x39, 0x35, 0x2c, 0x04, 0x80, 0xcf, 0x6e, 0xba, 0x53, 0x7e, 0xfc, + 0x48, 0x13, 0xb0, 0xb2, 0xe0, 0x4a, 0x27, 0x0a, 0x77, 0x12, 0x5e, 0x41, 0x52, 0xd7, 0xe2, 0x25, + 0x8a, 0x30, 0x0a, 0x64, 0x05, 0x9b, 0x60, 0x62, 0x7f, 0x5a, 0x06, 0x2a, 0x60, 0x8f, 0x2d, 0xbd, + 0x03, 0xc8, 0xaf, 0xcb, 0x2b, 0x0c, 0x6e, 0x17, 0x2d, 0x8b, 0x4d, 0xf9, 0x2d, 0x9f, 0x50, 0x28, + 0x0e, 0x87, 0x60, 0xa5, 0x32, 0x00, 0x1c, 0x80, 0x4a, 0x6b, 0x1a, 0xf1, 0x7b, 0xe5, 0x0c, 0x36, + 0x6f, 0x09, 0xe1, 0xf1, 0x39, 0x0c, 0x14, 0x43, 0xa0, 0x85, 0x69, 0x0c, 0x4d, 0x63, 0xcc, 0x13, + 0x2e, 0x06, 0x29, 0x29, 0x3e, 0x62, 0xeb, 0xea, 0xf9, 0xb3, 0x6d, 0x39, 0x82, 0x04, 0xf8, 0xe3, + 0xdc, 0xe0, 0xf8, 0x7c, 0x67, 0x13, 0x84, 0xf2, 0xab, 0x26, 0x2d, 0xe5, 0x72, 0x09, 0x55, 0x3c, + 0x00, 0x02, 0x0b, 0xfd, 0x34, 0x96, 0xcd, 0x2c, 0x13, 0xf5, 0x15, 0x62, 0xb3, 0x0c, 0xbc, 0xb0, + 0xf2, 0x55, 0x65, 0x77, 0x8a, 0x88, 0x33, 0xde, 0x29, 0xdc, 0xa7, 0xaa, 0xf1, 0x3b, 0xb7, 0xe1, + 0xf0, 0x3f, 0x7e, 0x0b, 0xd3, 0xc2, 0xca, 0x1c, 0x82, 0x29, 0x75, 0xd3, 0x40, 0x44, 0x2c, 0x35, + 0x60, 0x0b, 0xe3, 0x7c, 0xf0, 0x8d, 0x92, 0x6b, 0xa1, 0xad, 0x23, 0x83, 0x51, 0x37, 0xe4, 0x7e, + 0xdf, 0x43, 0xf8, 0xb0, 0xac, 0x3a, 0x03, 0x9d, 0xad, 0xcd, 0x2f, 0x0c, 0xc0, 0xca, 0x10, 0x80, + 0xb6, 0x78, 0x9d, 0x02, 0x39, 0xd5, 0x1b, 0xa6, 0x4b, 0x1c, 0x4b, 0x13, 0xf0, 0xf2, 0xf0, 0x3e, + 0x83, 0xc4, 0x95, 0x57, 0xc3, 0x9a, 0x38, 0xf0, 0x7c, 0x1f, 0x1c, 0x1e, 0x73, 0x25, 0x99, 0xe1, + 0xcb, 0x26, 0x2d, 0xe5, 0x72, 0x09, 0x65, 0x44, 0x00, 0x00, 0x5c, 0x72, 0x41, 0xbd, 0xd3, 0x72, + 0xc5, 0x97, 0xa1, 0x09, 0x85, 0xb7, 0xb5, 0xcd, 0x87, 0xb2, 0x14, 0xf7, 0xe4, 0xa2, 0x56, 0xf3, + 0x24, 0xd9, 0x78, 0xeb, 0x77, 0x74, 0x15, 0x2d, 0x80, 0xee, 0xd7, 0xd1, 0x9b, 0x8f, 0xd9, 0x48, + 0xcf, 0x65, 0x14, 0x8b, 0xd3, 0xed, 0x61, 0x71, 0xd3, 0x58, 0x6d, 0x8f, 0xb9, 0x3a, 0x12, 0xb8, + 0x11, 0xf0, 0x7f, 0x98, 0x0f, 0xf7, 0x0d, 0xf0, 0x6a, 0x30, 0x63, 0xc4, 0xa3, 0xf7, 0x6f, 0x30, + 0x1e, 0x7a, 0x8f, 0x5f, 0x02, 0x0a, 0xa1, 0x76, 0x95, 0x11, 0x0e, 0xb3, 0x25, 0xc1, 0x24, 0xed, + 0x84, 0x1a, 0xa0, 0x02, 0x74, 0x91, 0x93, 0xe5, 0x53, 0x6a, 0x01, 0xdb, 0x68, 0x00, 0x70, 0xec, + 0xc7, 0x0f, 0x8f, 0x3f, 0x87, 0x33, 0xd4, 0x3b, 0xab, 0x26, 0x2d, 0xe5, 0x72, 0x09, 0x65, 0x3c, + 0x00, 0x00, 0xa8, 0xe7, 0x3f, 0x87, 0x15, 0x13, 0x4d, 0x2e, 0xb6, 0x5d, 0x73, 0x44, 0x5c, 0x0f, + 0x96, 0xbd, 0x9a, 0x07, 0xe4, 0xe8, 0x25, 0x9e, 0x4e, 0xb8, 0xec, 0x83, 0xac, 0xd8, 0x21, 0x8c, + 0x49, 0xb6, 0x03, 0xf8, 0x10, 0x7d, 0x94, 0x7c, 0x00, 0xb2, 0xad, 0x2c, 0xfa, 0x1e, 0xd2, 0x5a, + 0x4d, 0xa3, 0x3e, 0x84, 0x85, 0x6e, 0x6a, 0x75, 0x12, 0x86, 0x12, 0xed, 0xfe, 0x12, 0xb6, 0x7f, + 0x44, 0x20, 0x88, 0x9f, 0x74, 0xcc, 0x4b, 0x8f, 0x8c, 0xed, 0xf2, 0x1e, 0x2e, 0xd2, 0x25, 0x93, + 0x1f, 0x5c, 0xd2, 0x6c, 0xcb, 0x4e, 0x4a, 0x01, 0xd7, 0xe0, 0xb9, 0x6d, 0x4a, 0x95, 0xcb, 0x98, + 0x5b, 0x12, 0x7c, 0x7e, 0xa4, 0x37, 0x87, 0x99, 0xc7, 0x87, 0x87, 0xc3, 0xc1, 0x87, 0x1b, 0x3b, + 0xab, 0x26, 0x2d, 0xe5, 0x72, 0x09, 0x65, 0x4c, 0x00, 0x00, 0x49, 0x66, 0xcd, 0x0f, 0xe2, 0x90, + 0x44, 0x22, 0xa7, 0xe4, 0x98, 0x09, 0x9e, 0xc8, 0x8e, 0x98, 0xff, 0x70, 0x84, 0xb0, 0x2b, 0xaf, + 0xd0, 0x13, 0xb2, 0xa3, 0xc1, 0xd0, 0xe2, 0x9a, 0xac, 0xf5, 0xeb, 0x1e, 0xa4, 0x99, 0x49, 0x97, + 0x16, 0x6d, 0x1f, 0xcc, 0x78, 0x57, 0xec, 0x44, 0x2a, 0x18, 0x86, 0x60, 0x85, 0x9d, 0x9e, 0x14, + 0x7b, 0x1b, 0x42, 0xa8, 0x40, 0x17, 0xa1, 0x89, 0xc8, 0xe9, 0xd8, 0x98, 0x78, 0x56, 0x8a, 0x32, + 0x00, 0x46, 0x03, 0x4d, 0x13, 0x13, 0x5f, 0x7c, 0x7f, 0xb6, 0x03, 0x8f, 0x67, 0x95, 0x59, 0xcf, + 0xf4, 0xc6, 0x21, 0x57, 0x38, 0x2b, 0x78, 0x77, 0x88, 0x07, 0x66, 0x1c, 0x38, 0x60, 0x39, 0xf1, + 0xf0, 0xf0, 0xf0, 0x7d, 0xe1, 0xeb, 0x5c, 0x48, 0xb2, 0xf7, 0x8a, 0xcb, 0x72, 0x09, 0x35, 0x3c, + 0xb6, 0xba, 0x95, 0xeb, 0x8c, 0xcb, 0x32, 0x16, 0x68, 0x08, 0xe8, 0xf3, 0x54, 0xed, 0xd0, 0x23, + 0xb8, 0xd8, 0xfe, 0x83, 0x49, 0x8a, 0x2c, 0xed, 0x74, 0x11, 0x5a, 0xe3, 0xe9, 0x3a, 0x74, 0x01, + 0x6f, 0x93, 0xa5, 0x68, 0xf6, 0xc2, 0xb0, 0x27, 0xab, 0xed, 0x83, 0xfe, 0x73, 0x59, 0x33, 0xf2, + 0x9a, 0xa0, 0x43, 0xd5, 0xce, 0x9d, 0xbc, 0xe6, 0x06, 0x13, 0x52, 0x2e, 0xaf, 0x50, 0x10, 0x02, + 0xb8, 0xf8, 0x78, 0x81, 0xf8, 0x21, 0xb2, 0xe7, 0xbd, 0x7c, 0x79, 0x56, 0x1d, 0xc1, 0x9f, 0x98, + 0xd9, 0x81, 0xd6, 0x38, 0x54, 0x41, 0x32, 0xa1, 0x1c, 0x62, 0x3e, 0x1e, 0x25, 0x7f, 0xb8, 0xbd, + 0x34, 0x93, 0x90, 0x08, 0x27, 0xc1, 0xe0, 0xf8, 0xf0, 0x7e, 0x1e, 0x1e, 0x1f, 0xb3, 0x62, 0x33, + 0xa6, 0x97, 0x6d, 0x65, 0x72, 0x19, 0x55, 0x4c, 0x00, 0x00, 0xad, 0xf5, 0xb8, 0x70, 0x1c, 0x3d, + 0x42, 0x6e, 0x7f, 0x08, 0x9a, 0x82, 0x46, 0x2b, 0x81, 0x4c, 0xbe, 0xaa, 0x01, 0xdb, 0x75, 0x89, + 0x79, 0x95, 0xc3, 0xbc, 0x16, 0x20, 0x87, 0x3c, 0xca, 0x15, 0xee, 0x26, 0xcf, 0x22, 0xce, 0x43, + 0xc0, 0xd3, 0x55, 0xd6, 0xac, 0x9c, 0x24, 0x66, 0xb5, 0xb0, 0x59, 0x76, 0x60, 0x23, 0xd4, 0xc8, + 0x62, 0xa3, 0x10, 0xe4, 0x25, 0x8e, 0x35, 0x1a, 0xd1, 0x49, 0x59, 0x1b, 0x8a, 0x54, 0xfc, 0x01, + 0x1a, 0xa8, 0xdf, 0x01, 0x51, 0x54, 0x5f, 0x58, 0x65, 0x22, 0xcc, 0xca, 0x31, 0xcd, 0x5f, 0xd2, + 0x6e, 0x5c, 0xbe, 0x4f, 0xc7, 0x6c, 0x0a, 0x6d, 0xc4, 0x26, 0x42, 0x1e, 0xbd, 0x86, 0x20, 0x8e, + 0x18, 0x73, 0x9e, 0x7b, 0xc0, 0x31, 0xa2, 0x2d, 0xb2, 0xf7, 0x8a, 0xcb, 0x72, 0x09, 0x45, 0x54, + 0xb7, 0x90, 0x1e, 0x6d, 0xf4, 0xf7, 0xba, 0x1c, 0x9d, 0x28, 0xa9, 0x49, 0xa0, 0xd4, 0x89, 0xa5, + 0xbb, 0x2d, 0xb1, 0xe6, 0xb5, 0x6f, 0x41, 0x76, 0x40, 0x59, 0x6b, 0x67, 0x1f, 0x5d, 0xae, 0x4c, + 0xbf, 0x68, 0x0c, 0xdc, 0x06, 0xa1, 0x0c, 0xf6, 0x02, 0xf9, 0xc2, 0x57, 0xe0, 0x02, 0xb6, 0x81, + 0x80, 0xac, 0x8b, 0x94, 0x6b, 0x89, 0xb2, 0x6d, 0x54, 0xa3, 0xf1, 0xb7, 0x49, 0x0f, 0x12, 0xc7, + 0xf2, 0x84, 0x97, 0x89, 0xf2, 0x63, 0x9f, 0x11, 0xcb, 0xbe, 0x0f, 0x91, 0x12, 0x80, 0x8a, 0x40, + 0xde, 0x5e, 0x9a, 0x92, 0xb6, 0x7b, 0xd1, 0x42, 0xf6, 0xa5, 0xef, 0x98, 0xc2, 0x4b, 0x74, 0x4e, + 0xe2, 0x39, 0x84, 0x78, 0x86, 0x3e, 0x0f, 0x1e, 0x3c, 0x38, 0xf8, 0x39, 0xd6, 0x7a, 0xf1, 0xf8, + 0xb2, 0xf7, 0x8a, 0xcb, 0x72, 0x19, 0x45, 0x5c, 0xb7, 0x8e, 0x57, 0xf0, 0x5a, 0xe1, 0xbe, 0x1d, + 0xde, 0x3a, 0xfc, 0x59, 0x2f, 0x95, 0x9a, 0x2e, 0xa3, 0x5a, 0xc6, 0xed, 0x24, 0x61, 0x10, 0xc8, + 0xff, 0x18, 0xef, 0xaa, 0x5b, 0xbc, 0xd9, 0x6e, 0xd7, 0x71, 0xb8, 0x95, 0x91, 0x0f, 0x74, 0xf3, + 0xa9, 0x87, 0x80, 0x37, 0xff, 0x65, 0xef, 0x3a, 0x46, 0x7e, 0xa1, 0x15, 0xd4, 0x23, 0x3e, 0xa5, + 0xb4, 0x7a, 0x13, 0x60, 0x61, 0xb8, 0x5d, 0xb5, 0x2b, 0xf5, 0x73, 0xb0, 0xd0, 0x20, 0x38, 0x0a, + 0x37, 0xce, 0xad, 0x7b, 0xc6, 0x3c, 0x15, 0x9e, 0x16, 0xfd, 0x0b, 0x97, 0x2f, 0x26, 0xbd, 0x18, + 0x98, 0xb9, 0xc9, 0x30, 0x13, 0x5c, 0x35, 0xf2, 0x58, 0xf2, 0x1d, 0xfa, 0xc0, 0x00, 0xf8, 0x7c, + 0x3c, 0x7c, 0x3c, 0x3e, 0x0f, 0xd7, 0x8e, 0xa9, 0xa6, 0x97, 0x6d, 0x65, 0x72, 0x19, 0x55, 0x5c, + 0x00, 0x00, 0x4a, 0xaa, 0xdf, 0xc3, 0xea, 0xc1, 0x91, 0xcc, 0x7b, 0x65, 0x32, 0xc1, 0xdf, 0x7c, + 0x26, 0xcf, 0xc7, 0xcc, 0x1c, 0x96, 0x4c, 0x19, 0xaa, 0x8e, 0x4b, 0xed, 0x33, 0xf8, 0x71, 0xfe, + 0xe8, 0x69, 0xbf, 0x44, 0x25, 0x77, 0x34, 0xe9, 0x85, 0xfc, 0xa4, 0xfb, 0xef, 0xd2, 0xaf, 0xe5, + 0x2e, 0xcb, 0xe8, 0x6f, 0x56, 0x61, 0xa8, 0x92, 0xa7, 0x6d, 0x0f, 0xd5, 0x4b, 0xc9, 0x7b, 0x9a, + 0x1d, 0x09, 0x73, 0x8f, 0x2f, 0x3d, 0xed, 0x1f, 0xf2, 0xad, 0xfc, 0x4a, 0x1e, 0x13, 0x00, 0x3a, + 0x92, 0x23, 0xce, 0x82, 0xa6, 0xca, 0xce, 0xef, 0x49, 0xb9, 0x0c, 0x13, 0x96, 0x63, 0x95, 0x58, + 0xf8, 0x90, 0xde, 0xc3, 0xc1, 0xe1, 0xe1, 0xc0, 0xf8, 0x78, 0x39, 0xde, 0x61, 0xf3, 0xcc, 0x93, + 0xc6, 0x97, 0x6d, 0x65, 0x72, 0x09, 0x55, 0x5c, 0x00, 0x00, 0x04, 0x64, 0xc2, 0x65, 0xa5, 0x9b, + 0x1b, 0xf5, 0x1e, 0x7c, 0x69, 0x02, 0x66, 0x02, 0xf5, 0x67, 0x3d, 0x74, 0xc1, 0x94, 0x28, 0x45, + 0xee, 0xf2, 0x61, 0xd7, 0x6c, 0x4f, 0xc3, 0xf7, 0xf6, 0x7c, 0x0a, 0xf2, 0xe1, 0xad, 0x80, 0xab, + 0x29, 0xb5, 0xb6, 0x0e, 0x9c, 0xc8, 0xb9, 0x73, 0xa3, 0xa4, 0x9b, 0x08, 0x78, 0x46, 0x33, 0x05, + 0x59, 0x73, 0x38, 0x7e, 0x53, 0x82, 0xab, 0xb4, 0xd8, 0x3e, 0xc0, 0xd0, 0xf4, 0x6f, 0xf1, 0x37, + 0xbc, 0x62, 0xfb, 0xf8, 0x14, 0x2f, 0x8f, 0xc0, 0xf5, 0xdc, 0xb0, 0x69, 0x43, 0x1e, 0x1f, 0x70, + 0x33, 0xad, 0xd1, 0x5e, 0xd1, 0x5a, 0x2b, 0xfb, 0xff, 0x2c, 0x90, 0x03, 0x8f, 0x31, 0xce, 0x1f, + 0x07, 0xc1, 0xf8, 0x70, 0xee, 0x79, 0xe1, 0x77, 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x55, 0x5c, + 0x00, 0x00, 0x51, 0xd6, 0xd8, 0xe3, 0xc4, 0x8c, 0x8e, 0x67, 0xea, 0x5f, 0xa8, 0xf3, 0x29, 0x5f, + 0x08, 0x8d, 0x93, 0x99, 0x5e, 0x36, 0xe5, 0x76, 0x06, 0x6a, 0x30, 0xa4, 0x32, 0x32, 0xfc, 0xce, + 0xab, 0x13, 0x89, 0xa5, 0xe1, 0x82, 0xfb, 0xd5, 0x65, 0x45, 0xa6, 0x17, 0x87, 0x51, 0xbc, 0x8a, + 0xce, 0x5a, 0xf2, 0x1a, 0xba, 0x33, 0xf1, 0x3c, 0x75, 0x96, 0x66, 0xe7, 0x9c, 0x47, 0xa8, 0x75, + 0xc4, 0xb0, 0x6c, 0x56, 0x50, 0xcf, 0xe9, 0xa7, 0xdf, 0x0d, 0xf0, 0xf8, 0x41, 0x91, 0xfe, 0x21, + 0x76, 0x2c, 0xb4, 0x59, 0x22, 0x27, 0x1f, 0x33, 0x15, 0xdd, 0x33, 0xb4, 0xf6, 0x0d, 0xb1, 0x1f, + 0x64, 0x94, 0x6f, 0x8c, 0x63, 0x87, 0x0f, 0x0f, 0x87, 0xc1, 0xe0, 0x61, 0x85, 0xde, 0x1b, 0x23, + 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x55, 0x64, 0xaf, 0xde, 0xaf, 0x87, 0x46, 0xfd, 0x1e, 0xf4, + 0xe9, 0x93, 0x89, 0xda, 0x9f, 0xac, 0x1b, 0x3a, 0x4c, 0x26, 0x6c, 0x39, 0x5b, 0x6d, 0xe6, 0x29, + 0xdb, 0x44, 0x8c, 0xe6, 0x6c, 0x78, 0x88, 0xac, 0x59, 0xea, 0xdf, 0x09, 0xef, 0x2a, 0x0c, 0x2f, + 0x2e, 0x58, 0x29, 0x55, 0xbf, 0xa4, 0xa5, 0xdc, 0xc4, 0x26, 0xde, 0x68, 0xa1, 0x2c, 0x20, 0x26, + 0xa9, 0xa6, 0xe2, 0x39, 0x2c, 0xd9, 0x0e, 0xfb, 0xb4, 0x3e, 0x3d, 0x57, 0xb4, 0xb4, 0xd7, 0xcc, + 0x19, 0x89, 0x27, 0x7d, 0xfb, 0xaa, 0x2e, 0x9c, 0x63, 0x57, 0x49, 0x39, 0x88, 0xcb, 0xb4, 0xca, + 0x52, 0x0e, 0x56, 0xea, 0xfc, 0x78, 0xfe, 0x6b, 0x73, 0xff, 0x04, 0xf1, 0xc3, 0x8f, 0x87, 0xc3, + 0xe0, 0xfb, 0x46, 0x92, 0xf0, 0x9d, 0xc8, 0xec, 0xa4, 0x4f, 0xee, 0x21, 0x72, 0x19, 0x25, 0x54, + 0x38, 0x63, 0x03, 0x45, 0x3f, 0x0d, 0x4f, 0x28, 0xdb, 0x46, 0xb1, 0x7d, 0xf8, 0x2a, 0xbb, 0xb6, + 0x9f, 0xa9, 0x15, 0xb0, 0xb3, 0x12, 0x6b, 0xe8, 0xe5, 0x1e, 0x74, 0x70, 0x91, 0x13, 0x34, 0x4d, + 0x4a, 0xb8, 0x7b, 0xe6, 0x6d, 0xfe, 0x85, 0x4e, 0xba, 0xac, 0x12, 0xff, 0x58, 0x16, 0x10, 0xc1, + 0x70, 0x7e, 0x89, 0xb4, 0x84, 0x21, 0xc7, 0x7a, 0x35, 0x56, 0x2e, 0x6a, 0x02, 0xb0, 0xa0, 0x10, + 0x49, 0x33, 0xd6, 0x57, 0x4b, 0x4a, 0x66, 0xcb, 0x3b, 0x00, 0xdc, 0xeb, 0x5f, 0x41, 0xdc, 0x40, + 0x3b, 0x3f, 0xa4, 0xf9, 0x56, 0x0c, 0x33, 0xa2, 0x2f, 0x1c, 0x8a, 0x42, 0x54, 0xae, 0xf7, 0xbb, + 0xf1, 0x2b, 0xcb, 0x91, 0x95, 0xa0, 0xf4, 0x1e, 0x19, 0xc2, 0x10, 0xe7, 0x18, 0x70, 0xfb, 0x88, + 0xa6, 0x97, 0x6d, 0x65, 0x72, 0x29, 0x35, 0x64, 0xaf, 0xdd, 0x47, 0x5d, 0x46, 0xc5, 0xfd, 0x81, + 0x82, 0x41, 0x59, 0xad, 0x3b, 0x24, 0x2f, 0x86, 0x49, 0x9b, 0xfb, 0x82, 0xb6, 0xdf, 0xf1, 0x54, + 0x52, 0xca, 0x10, 0xfd, 0x91, 0x73, 0x58, 0xbc, 0xb4, 0x47, 0x3f, 0xb9, 0x2f, 0xe5, 0x54, 0x1f, + 0xcf, 0x61, 0x2e, 0xba, 0xd3, 0x78, 0x64, 0x12, 0xb2, 0xdc, 0x19, 0xa7, 0x89, 0xd3, 0x00, 0x56, + 0x61, 0x09, 0x75, 0x8b, 0x0f, 0xa7, 0xa1, 0xdc, 0xd0, 0x15, 0xe5, 0xf5, 0x8c, 0x75, 0x21, 0x41, + 0x82, 0x9e, 0x49, 0xf0, 0xb2, 0xd8, 0xf3, 0x28, 0xf0, 0x5e, 0x11, 0x39, 0x88, 0x2e, 0xfe, 0x2f, + 0xb7, 0x8e, 0xd2, 0x1e, 0x93, 0xf1, 0x00, 0x27, 0x3a, 0x98, 0x72, 0x3e, 0x1c, 0x70, 0xc7, 0xc7, + 0x83, 0x81, 0xc8, 0xd3, 0x62, 0x23, 0x32, 0x26, 0xa4, 0x4f, 0xee, 0x21, 0x72, 0x19, 0x35, 0x6c, + 0x00, 0x06, 0x98, 0x1d, 0x78, 0x1c, 0x4f, 0xae, 0x3c, 0x0b, 0xfd, 0x61, 0x38, 0x3e, 0x2f, 0x10, + 0x1b, 0x48, 0x6c, 0x3e, 0x43, 0x08, 0x25, 0x07, 0xa7, 0xb0, 0x4f, 0x1b, 0xa4, 0xca, 0x9d, 0x68, + 0xd0, 0x2a, 0x22, 0x3e, 0x04, 0xd4, 0xe6, 0x76, 0x8c, 0xac, 0x74, 0xdb, 0x71, 0x53, 0xe8, 0x71, + 0xc9, 0x0d, 0x24, 0xb5, 0x27, 0xe4, 0xaa, 0xb5, 0xc3, 0x7f, 0xf6, 0x52, 0x81, 0xaf, 0x30, 0xf0, + 0xe6, 0x88, 0x65, 0xa9, 0xf4, 0x6a, 0x7d, 0xb6, 0x06, 0x87, 0xc4, 0x6c, 0x1a, 0x71, 0x0b, 0x20, + 0x60, 0x82, 0x24, 0xe2, 0x57, 0x3d, 0x6d, 0x5e, 0xbe, 0x37, 0xab, 0xa1, 0xa7, 0x37, 0xf7, 0x3d, + 0x5e, 0x80, 0x1c, 0xc6, 0x0c, 0x1c, 0x1c, 0x3e, 0x07, 0xc3, 0xe1, 0xe1, 0xe7, 0x36, 0xa6, 0x50, + 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x45, 0x64, 0xb0, 0xd2, 0xbf, 0xf9, 0x4d, 0xc8, 0xe1, 0x95, + 0x22, 0x86, 0x89, 0x6c, 0x3a, 0xdb, 0x05, 0x25, 0xcd, 0x73, 0x92, 0xe3, 0x20, 0xdd, 0x46, 0xff, + 0x1b, 0xb2, 0x0b, 0xc3, 0x29, 0x0b, 0xf2, 0x78, 0x08, 0xca, 0x9b, 0xfe, 0xd5, 0x80, 0xc4, 0xfc, + 0x56, 0xb7, 0xcf, 0x1e, 0x15, 0xd5, 0xab, 0x9b, 0x18, 0x7a, 0xa8, 0xcb, 0x92, 0x08, 0x39, 0x55, + 0xc6, 0x5b, 0xa6, 0xa4, 0x23, 0x76, 0x1f, 0xaa, 0xdf, 0x5c, 0xe6, 0x90, 0x38, 0xbc, 0x65, 0x6d, + 0xe8, 0x92, 0x37, 0x8c, 0x0c, 0x04, 0xec, 0x5b, 0x52, 0xce, 0x90, 0x10, 0x84, 0x3a, 0x32, 0x7a, + 0x2d, 0xdd, 0x6a, 0xed, 0x0d, 0xe2, 0xf7, 0xba, 0xbc, 0xe3, 0xce, 0x48, 0x8e, 0x38, 0x70, 0xf0, + 0xf8, 0xf0, 0x78, 0x3e, 0x65, 0x58, 0x92, 0x1e, 0xa4, 0x4f, 0xee, 0x21, 0x72, 0x19, 0x45, 0x6c, + 0x04, 0x80, 0xe4, 0x10, 0x35, 0x6d, 0x65, 0x13, 0x4b, 0xc1, 0x05, 0x47, 0x8f, 0x67, 0xa9, 0x43, + 0x6e, 0x6a, 0x3f, 0x3b, 0xa7, 0x8f, 0x82, 0xad, 0x0e, 0x6b, 0x96, 0xfe, 0xb4, 0xe7, 0x35, 0x3a, + 0x23, 0x38, 0xbf, 0x16, 0x7a, 0xea, 0x0d, 0x55, 0x7d, 0x79, 0x89, 0x69, 0xb4, 0xd4, 0x93, 0xae, + 0xfe, 0xb4, 0xed, 0x25, 0xcc, 0x22, 0xd7, 0x89, 0xf6, 0xbf, 0xff, 0x87, 0x81, 0xf5, 0xf3, 0xe3, + 0xca, 0x90, 0xb8, 0xf0, 0xc8, 0xcc, 0x49, 0x36, 0x60, 0x54, 0x98, 0x6f, 0x16, 0xeb, 0xc7, 0x5e, + 0xc1, 0x49, 0x30, 0xea, 0x12, 0xdd, 0xfa, 0x44, 0x78, 0xa4, 0xe0, 0x42, 0xc3, 0xd7, 0xcb, 0x7b, + 0x55, 0x86, 0x43, 0xb8, 0xe3, 0xcc, 0x78, 0xf0, 0x3e, 0x1e, 0x63, 0x8c, 0x78, 0xe0, 0x8a, 0x73, + 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x35, 0x74, 0x00, 0x00, 0x24, 0x08, 0x30, 0xb0, 0xd7, 0x30, + 0xa7, 0x09, 0xff, 0xd2, 0x36, 0x01, 0x9a, 0x80, 0xe8, 0x35, 0x7b, 0xa9, 0x39, 0xe9, 0x64, 0x79, + 0x72, 0x11, 0xe1, 0xc1, 0x58, 0x57, 0xc1, 0x5a, 0x8d, 0xe9, 0x3e, 0x51, 0x42, 0x9a, 0x7a, 0x76, + 0x1f, 0x1b, 0xbb, 0x9f, 0xd4, 0xa3, 0x80, 0x9d, 0xc9, 0x76, 0x9f, 0xef, 0x19, 0x52, 0xd6, 0xd9, + 0x65, 0x25, 0x59, 0x40, 0x8c, 0x26, 0x72, 0x99, 0x0b, 0xb4, 0x85, 0x4f, 0xa1, 0xd9, 0x98, 0x08, + 0x9d, 0xb0, 0xf7, 0x9d, 0xd1, 0x7c, 0x16, 0xf2, 0x54, 0x61, 0xab, 0x18, 0xf9, 0xbe, 0x9f, 0xa6, + 0x64, 0x3d, 0x79, 0x71, 0x20, 0xf1, 0x9d, 0x2f, 0xfb, 0x1f, 0xd1, 0xe7, 0x83, 0xe1, 0xfc, 0x0e, + 0x3e, 0x38, 0xdf, 0x46, 0x78, 0x7e, 0x34, 0x98, 0xc2, 0x08, 0x6e, 0xe5, 0x72, 0x09, 0x25, 0x74, + 0x00, 0x00, 0x28, 0x94, 0x58, 0x2b, 0x0d, 0xc2, 0x12, 0xc0, 0x7b, 0x14, 0x6d, 0xe5, 0x12, 0xfc, + 0x91, 0xd4, 0x8e, 0xe4, 0x6f, 0x2b, 0x95, 0xe0, 0xc6, 0xa3, 0x98, 0xee, 0x3a, 0x76, 0x26, 0x2b, + 0xaa, 0xea, 0x23, 0x52, 0xc9, 0xab, 0xb5, 0x86, 0x09, 0xf3, 0xbc, 0x38, 0x9e, 0xef, 0x63, 0x58, + 0xbc, 0x23, 0xbf, 0x52, 0xa0, 0x5c, 0x8f, 0x69, 0x25, 0x1b, 0x8f, 0x66, 0xa2, 0xb1, 0x27, 0x91, + 0x74, 0x3c, 0x6f, 0xf6, 0x7a, 0x8c, 0x50, 0x78, 0x6e, 0x13, 0xc6, 0x9c, 0xf9, 0x15, 0x1f, 0x44, + 0x22, 0x20, 0x60, 0x7a, 0xdd, 0xa0, 0x61, 0xc5, 0xe2, 0x41, 0x59, 0x0f, 0xbd, 0xb3, 0xf1, 0xe6, + 0xfe, 0x90, 0x70, 0x1f, 0x38, 0xf8, 0xfc, 0x0e, 0x07, 0x87, 0x9e, 0x7c, 0x58, 0x27, 0x8f, 0x33, + 0xa2, 0x08, 0x6e, 0xe5, 0x72, 0x09, 0x45, 0x74, 0x00, 0x00, 0x38, 0x24, 0x7a, 0xaa, 0xf1, 0xb5, + 0x93, 0x2d, 0x8b, 0xb4, 0xcd, 0x51, 0xd9, 0xd4, 0xdc, 0xad, 0x05, 0x18, 0x07, 0x9a, 0xf3, 0xe7, + 0x1a, 0x15, 0x02, 0xa7, 0x1d, 0xbf, 0x22, 0xb7, 0xc3, 0xee, 0x54, 0x97, 0x93, 0x2c, 0x33, 0x01, + 0x4c, 0xcb, 0x7d, 0x8c, 0xc7, 0x38, 0xdd, 0xbe, 0x57, 0xe4, 0x12, 0x88, 0xe7, 0x6b, 0x2c, 0x3f, + 0xbf, 0x56, 0x90, 0x87, 0x0c, 0x6f, 0x2e, 0xd4, 0xf5, 0x59, 0xfc, 0xcd, 0xb0, 0x1f, 0xdc, 0x58, + 0xfa, 0xba, 0x30, 0x0f, 0xf7, 0x99, 0x1e, 0x42, 0xed, 0xd7, 0xde, 0x15, 0x5c, 0xc1, 0x82, 0xc5, + 0xd2, 0x2d, 0x18, 0x12, 0xda, 0x95, 0x58, 0xfd, 0xf6, 0xda, 0x0d, 0x24, 0x30, 0xf8, 0x1f, 0x07, + 0xf0, 0x71, 0xce, 0x2b, 0x10, 0x77, 0xe9, 0x61, 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x45, 0x7c, + 0x00, 0xc0, 0x4e, 0x5d, 0x55, 0x18, 0x8a, 0x1b, 0xf9, 0x01, 0xef, 0x8a, 0x03, 0xaf, 0x2f, 0xd8, + 0x1d, 0x02, 0xe6, 0xea, 0xa5, 0xf5, 0xca, 0x93, 0xcd, 0x94, 0xbe, 0x68, 0xd0, 0xc2, 0x1f, 0x14, + 0x83, 0x9c, 0x9d, 0xb4, 0x54, 0xa8, 0x9e, 0x0f, 0x85, 0x55, 0x2a, 0x75, 0x8f, 0x2b, 0x9f, 0x82, + 0xbd, 0xcc, 0x06, 0xf2, 0x15, 0x20, 0x9e, 0xe7, 0xc5, 0x36, 0xc4, 0x95, 0x17, 0x24, 0xdf, 0x79, + 0x82, 0x8f, 0x97, 0xcf, 0xff, 0xf0, 0xc2, 0x26, 0x8c, 0x44, 0xb7, 0xe0, 0x90, 0x9c, 0xd9, 0xd4, + 0xa3, 0x46, 0x12, 0x28, 0x35, 0x50, 0xaf, 0x87, 0x54, 0x78, 0x46, 0x68, 0x96, 0x47, 0x5d, 0x61, + 0xc9, 0x60, 0x3c, 0x31, 0x3c, 0x2f, 0x83, 0xe1, 0xf0, 0x65, 0xe1, 0xec, 0x6d, 0xfd, 0xcc, 0x16, + 0xa4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x35, 0x74, 0x00, 0x00, 0x52, 0x04, 0x91, 0x6d, 0x5c, 0xf3, + 0x05, 0x5a, 0x7a, 0xa2, 0xe9, 0x6b, 0xde, 0x98, 0xb1, 0x08, 0xe1, 0x5c, 0x6d, 0xa1, 0xd8, 0x20, + 0xeb, 0x51, 0xe3, 0x8d, 0x00, 0x0d, 0xcd, 0x57, 0x77, 0x2a, 0x3d, 0xe2, 0x05, 0x92, 0x5e, 0xce, + 0x33, 0x58, 0x77, 0x06, 0x6c, 0x72, 0x3e, 0xbb, 0xbd, 0x8f, 0x57, 0x06, 0x05, 0x05, 0xe4, 0x54, + 0xed, 0x6a, 0x8b, 0xc1, 0x08, 0x90, 0x16, 0x09, 0xfa, 0xd0, 0x4f, 0xa6, 0x17, 0xcf, 0x43, 0x1f, + 0xa4, 0xf4, 0x91, 0xff, 0x43, 0x30, 0x3f, 0x55, 0xce, 0x77, 0xe1, 0xed, 0x08, 0xeb, 0xa6, 0xfa, + 0xd0, 0xea, 0x8f, 0x4b, 0xe1, 0x85, 0x08, 0x35, 0x3c, 0x00, 0xfc, 0x73, 0xb8, 0x87, 0x87, 0x03, + 0x83, 0xc7, 0x3c, 0xe7, 0xe5, 0x39, 0x13, 0x9a, 0xa4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x25, 0x74, + 0x00, 0x01, 0x69, 0x46, 0xb4, 0x9f, 0x19, 0x25, 0xfe, 0x51, 0x09, 0xe7, 0x36, 0x89, 0x73, 0xd8, + 0x2c, 0x7a, 0xee, 0x1e, 0xe9, 0xb5, 0x26, 0x4f, 0x67, 0x8d, 0xdb, 0xc3, 0x40, 0xe2, 0x4c, 0x9e, + 0x4d, 0x52, 0x0e, 0xfb, 0xae, 0x34, 0x4a, 0xbf, 0x58, 0xe6, 0xf5, 0xb4, 0x4c, 0xc2, 0xca, 0xd1, + 0xd9, 0xb9, 0x98, 0x6b, 0x5f, 0x35, 0x68, 0x2d, 0xc7, 0x4a, 0x92, 0xf3, 0x4b, 0x3f, 0x36, 0x3f, + 0x49, 0xfa, 0x0d, 0xff, 0x91, 0xb6, 0x06, 0x18, 0xa6, 0xea, 0x41, 0xdf, 0x3d, 0xc2, 0x2f, 0xa8, + 0x36, 0x52, 0xb9, 0xc0, 0x73, 0x29, 0x0c, 0xc8, 0xef, 0x3c, 0x32, 0x65, 0xb0, 0x1d, 0x02, 0x03, + 0xb0, 0xca, 0x8f, 0xbe, 0x83, 0x07, 0x87, 0x8e, 0x0f, 0x87, 0xe7, 0x19, 0x8d, 0x9b, 0x52, 0xe3, + 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x35, 0x7c, 0x04, 0x81, 0xd0, 0x1a, 0x52, 0x2c, 0x52, 0x15, + 0x28, 0x18, 0x3e, 0xd7, 0x70, 0x05, 0x04, 0xa9, 0xc1, 0x9b, 0xb0, 0xac, 0xd4, 0xab, 0x23, 0xda, + 0xa1, 0xbf, 0x91, 0x8a, 0xc0, 0x58, 0x6f, 0x58, 0x08, 0x9c, 0x0f, 0x00, 0xb7, 0xba, 0xd9, 0x54, + 0x84, 0x13, 0x18, 0xa9, 0xfc, 0x95, 0x18, 0x31, 0x7e, 0x3e, 0xb6, 0xdd, 0x4d, 0xac, 0xac, 0x07, + 0x61, 0xb3, 0x5f, 0x30, 0x24, 0x40, 0x83, 0x77, 0xf7, 0x94, 0x7d, 0x0b, 0xbb, 0x57, 0x86, 0xf5, + 0x0a, 0x83, 0xd3, 0x34, 0xe2, 0xcf, 0xd3, 0x8d, 0xe0, 0x66, 0x8f, 0x79, 0xc9, 0xfa, 0x5e, 0x51, + 0x59, 0x50, 0xda, 0x57, 0xcb, 0x54, 0x04, 0xf3, 0x2b, 0x01, 0xd1, 0x9c, 0x63, 0xc1, 0xe0, 0x7c, + 0x3e, 0x10, 0x32, 0x14, 0x1f, 0x1e, 0x60, 0xe4, 0xc4, 0x50, 0x05, 0x21, 0x72, 0x09, 0x15, 0x74, + 0x00, 0x00, 0x02, 0x2c, 0x30, 0x2e, 0x0d, 0x66, 0x68, 0xc2, 0xbc, 0x54, 0x27, 0x50, 0xab, 0x11, + 0x04, 0x84, 0x49, 0x68, 0xc5, 0x34, 0xb3, 0x54, 0x0e, 0x16, 0x86, 0xe7, 0x6c, 0xfb, 0x63, 0x9d, + 0xc3, 0xdc, 0x24, 0x10, 0x63, 0xce, 0xe9, 0x24, 0x92, 0x48, 0xf3, 0x98, 0x79, 0x67, 0x8a, 0xe4, + 0x9f, 0x97, 0x0b, 0x0f, 0xce, 0x76, 0x31, 0x14, 0x68, 0xed, 0xe7, 0xd9, 0xe6, 0x48, 0xbb, 0x56, + 0x45, 0x9e, 0x5a, 0xd6, 0x6e, 0xea, 0xa5, 0xdf, 0x8e, 0x6a, 0x49, 0xcd, 0xe9, 0xf3, 0x27, 0x5d, + 0xdd, 0xe3, 0x56, 0x6d, 0xa0, 0xc1, 0xa8, 0xcb, 0xcb, 0xdb, 0xb1, 0xec, 0x15, 0x06, 0x00, 0x27, + 0x33, 0xe1, 0x87, 0x87, 0x87, 0xc0, 0xf8, 0x7c, 0x1c, 0x3e, 0x1e, 0x38, 0x7c, 0x78, 0xf5, 0x9c, + 0xc4, 0x50, 0x05, 0x21, 0x72, 0x09, 0x45, 0x7c, 0x00, 0xc0, 0x5f, 0xe9, 0x53, 0x55, 0x61, 0x1d, + 0x48, 0xa7, 0xe6, 0xdf, 0xa3, 0x82, 0xa9, 0x07, 0x81, 0x70, 0x8f, 0x20, 0x75, 0xa6, 0x79, 0x46, + 0xe0, 0x77, 0x1c, 0x5f, 0x7e, 0xee, 0x1d, 0x9f, 0x64, 0x15, 0x34, 0x3e, 0xc5, 0xb1, 0x96, 0x5e, + 0x00, 0x9d, 0x21, 0xb2, 0x6d, 0x52, 0x2d, 0x5a, 0xdc, 0xb9, 0x9d, 0x1d, 0x10, 0xe3, 0x49, 0x5f, + 0xe1, 0xec, 0x9b, 0x12, 0x17, 0x55, 0x03, 0x26, 0x94, 0x27, 0xfb, 0xfd, 0x20, 0x50, 0xba, 0x96, + 0x12, 0x45, 0x19, 0x36, 0xcf, 0xdf, 0xfe, 0xc1, 0xcb, 0xc7, 0x4d, 0x49, 0x20, 0x18, 0xc8, 0x89, + 0xa4, 0x28, 0xbe, 0x84, 0xf4, 0xa5, 0x1d, 0x85, 0x1d, 0x92, 0x05, 0xb2, 0x10, 0x66, 0x70, 0xf8, + 0xf8, 0x7e, 0x3e, 0x39, 0xb2, 0x3b, 0xc9, 0xee, 0xa4, 0x65, 0x4a, 0x41, 0x72, 0x09, 0x45, 0x8c, + 0x00, 0x00, 0x4e, 0x3f, 0xf7, 0x13, 0x0a, 0x6b, 0x85, 0xc9, 0x41, 0x44, 0x68, 0x48, 0xe7, 0xbc, + 0xe6, 0x89, 0xc2, 0x30, 0xef, 0x98, 0x65, 0x30, 0x2b, 0xbb, 0x35, 0x35, 0xe5, 0xa5, 0xa6, 0xe6, + 0x74, 0xc2, 0xa8, 0x66, 0xbe, 0x85, 0x22, 0x64, 0x7f, 0xcb, 0x2d, 0xf8, 0xbb, 0xa2, 0x14, 0x8a, + 0x19, 0x37, 0x4d, 0x10, 0x0e, 0x00, 0x01, 0x79, 0x71, 0x7f, 0x48, 0x69, 0x7c, 0x3e, 0x92, 0xe6, + 0xca, 0x0b, 0x90, 0x93, 0xab, 0x94, 0x3e, 0xec, 0x3f, 0xe1, 0x78, 0xec, 0x89, 0x28, 0x05, 0xb2, + 0x58, 0x45, 0x56, 0x43, 0xe9, 0x03, 0xfa, 0x01, 0x24, 0xc2, 0xf7, 0xc4, 0x85, 0x52, 0x15, 0xcc, + 0x86, 0x2f, 0x39, 0x8e, 0x60, 0x83, 0xc7, 0xc3, 0xc7, 0xc1, 0xdf, 0x4b, 0x5a, 0x28, 0xdf, 0xac, + 0xc4, 0x65, 0x4a, 0x41, 0x72, 0x09, 0x15, 0x94, 0x00, 0x00, 0x03, 0x61, 0x03, 0x38, 0x9c, 0x15, + 0xe6, 0xba, 0x02, 0x23, 0x84, 0x2e, 0x4f, 0xb2, 0x5d, 0xd6, 0xa6, 0x86, 0xfa, 0x03, 0xdf, 0xe8, + 0xcf, 0x2a, 0x3f, 0x94, 0x7e, 0xd1, 0x30, 0x53, 0x7f, 0x9d, 0x03, 0x54, 0x70, 0x77, 0xa7, 0x48, + 0xa3, 0x59, 0xb1, 0xd3, 0xea, 0x06, 0x82, 0x64, 0x53, 0x05, 0x0e, 0x81, 0xff, 0xd4, 0x57, 0x4c, + 0xd4, 0x0e, 0x2c, 0xfb, 0xd6, 0x8f, 0x35, 0x01, 0x01, 0x6b, 0x12, 0x21, 0xe7, 0x18, 0x15, 0x88, + 0xdd, 0xe2, 0x91, 0x24, 0x7e, 0x0f, 0xa2, 0x11, 0x45, 0x01, 0xfa, 0xa1, 0x45, 0xf9, 0xb4, 0x6f, + 0x70, 0xd1, 0x7b, 0x94, 0xc2, 0xf3, 0x9a, 0xc0, 0x04, 0x27, 0xc3, 0xe1, 0x8e, 0x0f, 0x0f, 0x80, + 0xe1, 0xc1, 0xc7, 0x0f, 0x18, 0xe5, 0xa2, 0x6d, 0xa6, 0xac, 0xc9, 0x85, 0x72, 0x09, 0x25, 0x94, + 0x00, 0x00, 0x5e, 0x8d, 0x23, 0xf9, 0xfa, 0x0d, 0xf3, 0xfe, 0xe5, 0xec, 0xbb, 0x2a, 0xe6, 0x25, + 0x70, 0x55, 0x07, 0x29, 0x79, 0xeb, 0x07, 0x66, 0x63, 0x76, 0xd7, 0xcc, 0x2d, 0x82, 0xaf, 0x89, + 0xaf, 0x90, 0xd2, 0x22, 0x2f, 0x35, 0x23, 0x84, 0x07, 0x33, 0x70, 0x32, 0x04, 0x75, 0xd5, 0x24, + 0xe6, 0x5d, 0xa8, 0xfa, 0x74, 0x9e, 0x23, 0x77, 0xf0, 0xff, 0xc4, 0xfc, 0xe0, 0x94, 0x37, 0x38, + 0x93, 0x3a, 0xeb, 0xdb, 0x66, 0x7d, 0xe5, 0x69, 0xda, 0x7f, 0x6e, 0x8e, 0xe9, 0xfe, 0xb6, 0x76, + 0xe0, 0x84, 0xe3, 0xc6, 0xe0, 0x0e, 0x10, 0x20, 0xcc, 0x53, 0x94, 0x20, 0xe4, 0x04, 0xf2, 0x9c, + 0xb6, 0xcd, 0x21, 0x86, 0x0f, 0x07, 0xc1, 0xe3, 0xc1, 0xc1, 0xc3, 0x85, 0xb6, 0x64, 0xfa, 0xd7, + 0xc4, 0x65, 0x4a, 0x41, 0x72, 0x09, 0x35, 0x8c, 0x00, 0xc3, 0x2e, 0x07, 0x4d, 0xcf, 0x40, 0xe3, + 0xc4, 0x6a, 0xbd, 0x87, 0xa0, 0x32, 0xc2, 0xf7, 0x32, 0xa2, 0x74, 0xf4, 0x62, 0xeb, 0x64, 0xac, + 0x75, 0x6d, 0x4c, 0xa0, 0x2f, 0xa5, 0xe7, 0x48, 0x75, 0x1b, 0x28, 0x84, 0x57, 0x6f, 0x72, 0x54, + 0x6b, 0xb6, 0x9e, 0xda, 0x48, 0xe3, 0xa9, 0xd6, 0x41, 0xe8, 0xc3, 0x12, 0x16, 0x20, 0x2c, 0x64, + 0xee, 0xad, 0x6c, 0xbb, 0x3e, 0x84, 0xff, 0x19, 0x5e, 0x42, 0xf1, 0x29, 0xc9, 0x67, 0x6d, 0x28, + 0x00, 0x73, 0x62, 0x00, 0x42, 0xdc, 0xc5, 0x6b, 0x46, 0x21, 0x2f, 0x22, 0x4f, 0xf0, 0x2d, 0x7e, + 0x52, 0x78, 0x76, 0x5a, 0x61, 0x99, 0x0f, 0xcf, 0x0f, 0xfa, 0x38, 0x38, 0x3e, 0x1f, 0x03, 0xc3, + 0xf0, 0xfc, 0x0c, 0x1e, 0x13, 0x46, 0x22, 0x8c, 0xc4, 0x65, 0x4a, 0x41, 0x72, 0x09, 0x25, 0x94, + 0x00, 0x00, 0x90, 0x17, 0x7a, 0x70, 0x6b, 0x33, 0xce, 0x57, 0x32, 0x9d, 0x05, 0x11, 0x10, 0xf2, + 0xef, 0x31, 0xe9, 0xcb, 0x2d, 0x86, 0x68, 0xdf, 0xcc, 0x6a, 0x7b, 0x59, 0x33, 0x52, 0x51, 0x0d, + 0xb0, 0xb8, 0x03, 0xe7, 0x91, 0x37, 0xc8, 0xe4, 0xa8, 0xf5, 0x3d, 0x36, 0x19, 0x72, 0xf3, 0xb9, + 0xa8, 0x79, 0xa5, 0x47, 0x52, 0x9a, 0xfd, 0x65, 0x0a, 0x75, 0x49, 0xc3, 0x3c, 0x15, 0xc4, 0x5f, + 0x88, 0x89, 0x96, 0x84, 0xf7, 0x6e, 0xa6, 0xb3, 0x40, 0x8c, 0xb2, 0x90, 0xc1, 0xfc, 0x19, 0x01, + 0xbb, 0xaf, 0xd4, 0xb5, 0x32, 0x48, 0xcf, 0x00, 0x43, 0x21, 0xb6, 0x04, 0xe9, 0x90, 0xc8, 0x60, + 0x4e, 0xdf, 0xd1, 0x8f, 0x07, 0x83, 0xc0, 0x7f, 0x07, 0xe7, 0xf0, 0x7c, 0xe2, 0x26, 0xc3, 0x4f, + 0xa4, 0x65, 0x4a, 0x41, 0x72, 0x09, 0x35, 0x94, 0x04, 0x84, 0x22, 0x81, 0x1a, 0xea, 0x9f, 0x75, + 0xa9, 0x1c, 0xcd, 0x73, 0xa5, 0xe9, 0x4c, 0xf7, 0x7f, 0x57, 0x3a, 0xb0, 0x97, 0xb6, 0x50, 0xf2, + 0x2b, 0x83, 0x69, 0x79, 0xc0, 0xe4, 0x32, 0x57, 0x55, 0xc8, 0x42, 0x07, 0xdf, 0xdd, 0xbc, 0x12, + 0xae, 0x05, 0xac, 0xe3, 0x3c, 0x81, 0x8f, 0x42, 0x43, 0x06, 0xf3, 0x21, 0xcf, 0x0e, 0x95, 0x01, + 0x67, 0x41, 0xb2, 0x9a, 0x64, 0x4a, 0x4b, 0xd7, 0xb1, 0x74, 0xbb, 0x65, 0xde, 0xcf, 0x7c, 0x02, + 0x16, 0x4a, 0x5d, 0xa7, 0xc8, 0xf0, 0x09, 0x9b, 0xac, 0x34, 0xc2, 0x4a, 0x04, 0x0a, 0x3a, 0x0e, + 0x0b, 0x86, 0x92, 0x8e, 0x2f, 0x21, 0xbb, 0xd6, 0x1d, 0x26, 0x61, 0x1f, 0xce, 0x38, 0x7c, 0x1e, + 0x1e, 0x03, 0xe0, 0xe4, 0xab, 0x52, 0x07, 0xcb, 0xa6, 0xac, 0xc9, 0x85, 0x72, 0x09, 0x35, 0x9c, + 0x00, 0x01, 0xf1, 0x6d, 0x83, 0xa1, 0xd4, 0xf4, 0xb9, 0xa8, 0xd9, 0xf0, 0xc3, 0x81, 0x40, 0xa0, + 0x6b, 0x6f, 0x26, 0x29, 0x64, 0x9f, 0x81, 0x6c, 0x01, 0x6c, 0xf4, 0x39, 0xf2, 0x67, 0xdd, 0x4c, + 0xba, 0x3a, 0x89, 0xc6, 0xc3, 0x4d, 0x4b, 0xa5, 0xeb, 0x7e, 0x67, 0xa9, 0x33, 0x30, 0xd9, 0x02, + 0xdc, 0x2a, 0x20, 0x82, 0x64, 0x54, 0x31, 0x43, 0x09, 0x71, 0x50, 0xdb, 0x3e, 0xf8, 0xb5, 0x68, + 0x2c, 0xcc, 0xb6, 0x95, 0xf6, 0x5e, 0x3c, 0x45, 0xea, 0x9c, 0x87, 0xf4, 0x3a, 0x3d, 0x82, 0xdf, + 0x62, 0xd5, 0x42, 0x60, 0x77, 0x0f, 0x85, 0x0d, 0x6d, 0x3a, 0x14, 0xdb, 0xaf, 0x35, 0x39, 0xdd, + 0xf2, 0x67, 0x42, 0x77, 0x38, 0x67, 0x0f, 0x0e, 0x0f, 0x1f, 0x0f, 0x51, 0xcc, 0xb1, 0xe7, 0x60, + 0xa6, 0xac, 0xc9, 0x85, 0x72, 0x09, 0x25, 0x9c, 0x00, 0xc0, 0xb8, 0x4b, 0x99, 0xf0, 0xf2, 0x0c, + 0x2d, 0xf0, 0x4c, 0xc3, 0xaf, 0x13, 0x4e, 0x1f, 0x8c, 0x8a, 0x9a, 0x24, 0xc5, 0x99, 0x9a, 0x91, + 0x95, 0xe2, 0x8f, 0x32, 0x01, 0x82, 0x23, 0x68, 0x4d, 0x79, 0xdf, 0x56, 0x6a, 0xf2, 0xfe, 0x02, + 0xb9, 0x73, 0xf2, 0xb3, 0x30, 0x7e, 0xab, 0xf5, 0x2f, 0x3a, 0x05, 0xdd, 0x4b, 0xae, 0x9b, 0xeb, + 0xd4, 0x5d, 0x97, 0x8f, 0xbd, 0x60, 0xcf, 0xa5, 0x6c, 0x17, 0x1a, 0x06, 0x98, 0x13, 0x12, 0x53, + 0xd3, 0x05, 0x5e, 0xb6, 0x98, 0x44, 0x83, 0x81, 0xef, 0x1c, 0xf6, 0x2a, 0x7c, 0x1d, 0xef, 0x4c, + 0x8e, 0x59, 0xd4, 0x7d, 0x74, 0x40, 0x57, 0x4c, 0x39, 0x04, 0xfc, 0x8f, 0x0f, 0x0c, 0x1e, 0x1f, + 0x08, 0x06, 0x18, 0x7d, 0x7d, 0xe3, 0x23, 0x7c, 0xb4, 0x39, 0x63, 0x0f, 0x72, 0x09, 0x25, 0xa4, + 0x00, 0x08, 0xa1, 0xf9, 0x79, 0xc3, 0x62, 0x17, 0x8c, 0xe5, 0xf8, 0xe3, 0x83, 0x33, 0x49, 0x18, + 0x31, 0x50, 0x6e, 0x27, 0x7f, 0x64, 0x22, 0x71, 0x6f, 0x98, 0x01, 0x0c, 0xb3, 0x86, 0x92, 0xa1, + 0x6b, 0xa3, 0x38, 0x9d, 0xce, 0x85, 0x71, 0x8e, 0x9a, 0x57, 0x44, 0x64, 0x5f, 0x29, 0x86, 0x05, + 0x0b, 0xe7, 0x26, 0x83, 0xb3, 0x90, 0x09, 0x08, 0x08, 0xe4, 0x61, 0xb2, 0x83, 0xd4, 0xda, 0xaf, + 0x82, 0x14, 0xdc, 0xf4, 0x26, 0x77, 0x61, 0xab, 0x7e, 0x3c, 0xed, 0xe6, 0x7c, 0x1c, 0x13, 0x78, + 0x9c, 0xc3, 0xcf, 0x08, 0x0d, 0x37, 0x7c, 0x63, 0x60, 0x33, 0xf1, 0xbd, 0x6b, 0x61, 0x53, 0xf5, + 0x68, 0x70, 0x07, 0xe8, 0x70, 0x78, 0x38, 0x70, 0x7c, 0x31, 0xdd, 0x9e, 0x4b, 0x33, 0xa4, 0x99, + 0xd4, 0x39, 0x63, 0x0f, 0x72, 0x09, 0x35, 0xa4, 0x04, 0x80, 0xd6, 0x01, 0x56, 0x1c, 0x09, 0x80, + 0xce, 0x23, 0x84, 0xbb, 0x48, 0x63, 0x43, 0xdc, 0x0a, 0x0c, 0xfe, 0xc3, 0xdc, 0xd9, 0x96, 0x4e, + 0x52, 0x80, 0x51, 0x35, 0x32, 0xd5, 0x63, 0x95, 0xbb, 0x1a, 0xf1, 0xce, 0xf9, 0x06, 0xa0, 0x19, + 0xb4, 0xf1, 0x24, 0x17, 0xe0, 0x13, 0x36, 0x9f, 0x71, 0x62, 0x96, 0x35, 0x84, 0x6d, 0x6d, 0x53, + 0x54, 0x69, 0xeb, 0x1a, 0x82, 0x11, 0x98, 0x10, 0xce, 0x8c, 0x8f, 0x66, 0xee, 0x30, 0xb6, 0x35, + 0x9b, 0x46, 0x72, 0xb9, 0x0d, 0x30, 0x34, 0xc2, 0x4a, 0xa2, 0x39, 0x5c, 0x0e, 0x3e, 0xe0, 0xe4, + 0x0c, 0x9a, 0xaa, 0xe0, 0xe8, 0x7a, 0x26, 0x2c, 0xc0, 0x41, 0x87, 0x0f, 0x03, 0xf0, 0x3f, 0x83, + 0xd0, 0x7e, 0x0e, 0x39, 0xd2, 0x1e, 0x2d, 0x14, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x35, 0xa4, + 0x3c, 0x03, 0xc7, 0xd2, 0x58, 0x84, 0xd2, 0x42, 0xee, 0x0e, 0xb8, 0x99, 0xe2, 0x91, 0xa5, 0x83, + 0x5e, 0x05, 0x58, 0x22, 0x32, 0xa1, 0x26, 0x54, 0xca, 0x12, 0x19, 0xaa, 0xab, 0xa7, 0xce, 0x8c, + 0x15, 0xdc, 0x68, 0xf3, 0x5b, 0x40, 0x81, 0xa1, 0x68, 0x60, 0x50, 0x52, 0x39, 0x70, 0x02, 0x11, + 0xe9, 0xef, 0x7c, 0x23, 0x6e, 0xdf, 0xf5, 0xea, 0x08, 0x19, 0x4e, 0x87, 0xd7, 0x68, 0x6f, 0x49, + 0xc6, 0xb6, 0x43, 0x9b, 0xa1, 0x66, 0xfd, 0x04, 0x96, 0x38, 0x6d, 0xba, 0xdf, 0xb4, 0xc4, 0x39, + 0xab, 0xbf, 0x6f, 0xa7, 0x12, 0x9d, 0xb9, 0xba, 0x39, 0x9e, 0xba, 0x45, 0x24, 0x22, 0x64, 0xe8, + 0xe2, 0x5e, 0x7f, 0xf0, 0xf1, 0xa1, 0xe1, 0xf4, 0x7a, 0x1e, 0x8e, 0x1c, 0xc7, 0x3c, 0x13, 0xc3, + 0xc2, 0x1d, 0xcb, 0x05, 0x72, 0x29, 0x15, 0xac, 0x00, 0x01, 0x2e, 0x19, 0xf0, 0x63, 0x1c, 0x64, + 0xa4, 0x1a, 0x45, 0xa2, 0x1c, 0xb8, 0x58, 0xab, 0x02, 0x4d, 0xd4, 0xb0, 0x01, 0xd3, 0xd3, 0x49, + 0x3d, 0xbc, 0xcc, 0x10, 0xad, 0xf4, 0xb7, 0xd9, 0x0e, 0xde, 0x14, 0x13, 0x3b, 0xa2, 0x5b, 0xdf, + 0xe7, 0x6a, 0x8a, 0x55, 0x20, 0xf9, 0x25, 0x46, 0x31, 0xd0, 0xbf, 0x71, 0x24, 0x72, 0xcf, 0xc3, + 0x50, 0xa1, 0x1f, 0xff, 0x40, 0x7b, 0x49, 0xc5, 0xea, 0x4f, 0xea, 0x59, 0x34, 0x44, 0x00, 0x5e, + 0x16, 0x0c, 0xa6, 0xa5, 0x7b, 0xc7, 0xd5, 0x39, 0x09, 0xb5, 0xfa, 0x9c, 0x9b, 0x81, 0x04, 0xcd, + 0xda, 0x35, 0xb6, 0x04, 0x44, 0x76, 0x66, 0x10, 0x3b, 0xec, 0xe1, 0xe0, 0x78, 0xf8, 0x1f, 0x81, + 0xe0, 0xfc, 0x33, 0xc4, 0x35, 0x18, 0xc3, 0x35, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x25, 0xac, + 0x69, 0xd4, 0x3b, 0xc2, 0x6e, 0x3b, 0x8f, 0xa9, 0x9b, 0x85, 0x62, 0x7b, 0xa2, 0x8b, 0xf5, 0xb3, + 0x17, 0x37, 0xfa, 0x96, 0x46, 0xb5, 0xfc, 0x72, 0xf6, 0x6c, 0x85, 0xe6, 0xfa, 0x79, 0xb8, 0x97, + 0xab, 0xc6, 0xc8, 0xe1, 0xcc, 0xb6, 0x29, 0x6d, 0x0f, 0xb9, 0x1c, 0xb1, 0xa1, 0xf4, 0x84, 0xe4, + 0x4f, 0x41, 0x17, 0x6b, 0xe7, 0x81, 0xbe, 0x7c, 0x03, 0xed, 0xee, 0xb9, 0xa9, 0xf9, 0xaa, 0x8b, + 0x8b, 0x15, 0x6d, 0x75, 0xe9, 0x03, 0x57, 0x45, 0x2b, 0x8f, 0x8a, 0xf5, 0xa8, 0xa0, 0x32, 0x11, + 0x77, 0x82, 0x15, 0x9f, 0x9a, 0x12, 0x75, 0x2c, 0x79, 0xd6, 0x8f, 0xd8, 0xe4, 0xfa, 0xd4, 0x13, + 0x54, 0xe9, 0x9c, 0x2d, 0x2c, 0x1b, 0x0f, 0xe0, 0xf8, 0x38, 0xd6, 0x66, 0x61, 0x8f, 0xc4, 0x6e, + 0xc2, 0x1d, 0xcb, 0x05, 0x72, 0x29, 0x15, 0xb4, 0x00, 0xc0, 0x66, 0x40, 0x7f, 0x3a, 0x68, 0x22, + 0x23, 0x2d, 0x81, 0xe6, 0x6f, 0x70, 0xf4, 0x3d, 0x5a, 0x5e, 0x8f, 0xd3, 0x0c, 0x36, 0x37, 0xd5, + 0xb5, 0x4f, 0xd7, 0x30, 0x19, 0x34, 0xaf, 0x2d, 0x85, 0xac, 0xf0, 0x7b, 0x7f, 0xd8, 0x91, 0x6b, + 0x11, 0xac, 0x64, 0x61, 0x16, 0x67, 0x73, 0x1b, 0x3e, 0xac, 0x10, 0xc7, 0xef, 0xb0, 0x43, 0xf6, + 0xe5, 0xc4, 0x98, 0x56, 0x21, 0xf7, 0xe8, 0x18, 0xd5, 0x36, 0xa1, 0xff, 0xcd, 0xac, 0xc6, 0xdc, + 0xee, 0xb2, 0xe9, 0xc4, 0xf7, 0xf1, 0xfc, 0x63, 0xce, 0x3e, 0xf6, 0x56, 0x33, 0x17, 0x13, 0x6e, + 0x45, 0x36, 0x95, 0x4e, 0x27, 0x32, 0x34, 0x13, 0x79, 0x8c, 0x38, 0x3c, 0x3e, 0x07, 0xe0, 0xfc, + 0x1c, 0x78, 0xe7, 0xfe, 0xc6, 0x07, 0x7c, 0x03, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x05, 0xb4, + 0x05, 0xc0, 0x97, 0x65, 0xaa, 0xb1, 0xdb, 0x33, 0x1d, 0x8f, 0x3e, 0xde, 0x42, 0x98, 0x77, 0xbf, + 0xd4, 0xf9, 0x31, 0x08, 0x0c, 0x22, 0x12, 0xef, 0x7b, 0xe4, 0x87, 0x47, 0xf9, 0xda, 0x34, 0x83, + 0x46, 0x0c, 0x01, 0x06, 0xd9, 0x6d, 0xdd, 0xe9, 0x38, 0xb9, 0xd1, 0xf4, 0xcf, 0xb6, 0xa7, 0xdb, + 0xd7, 0x4b, 0x67, 0x23, 0xad, 0xb8, 0x45, 0x03, 0x3c, 0xd2, 0xf6, 0x6b, 0xc8, 0x25, 0x8d, 0x1e, + 0xca, 0x4e, 0x48, 0x15, 0xa5, 0x4d, 0xa6, 0x00, 0xf5, 0xd3, 0x5d, 0xa0, 0xfe, 0x05, 0xde, 0x77, + 0x7c, 0xfc, 0x60, 0xd6, 0x42, 0x5c, 0xf0, 0xa0, 0x41, 0x14, 0x95, 0x5a, 0x5d, 0x0e, 0xa6, 0xb1, + 0xc4, 0xe0, 0x07, 0x07, 0x80, 0xf8, 0x78, 0x1f, 0x07, 0x03, 0x81, 0xe7, 0xa4, 0x6e, 0x3b, 0x16, + 0x82, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x15, 0xac, 0x04, 0x8e, 0x7b, 0x4b, 0x56, 0xca, 0x47, 0xa0, + 0x1d, 0xcf, 0x25, 0x47, 0x3c, 0xe5, 0x19, 0x82, 0x38, 0xb7, 0xdb, 0x0f, 0x0d, 0xb5, 0x0e, 0xd5, + 0x16, 0x2a, 0x45, 0xd5, 0xcc, 0xa2, 0xee, 0xa8, 0xf6, 0xad, 0xc8, 0xbc, 0x52, 0x85, 0x3c, 0x3e, + 0x63, 0x9a, 0x3d, 0xe8, 0xf3, 0x33, 0x53, 0xe7, 0x84, 0xa8, 0x16, 0x3b, 0x22, 0xf5, 0x94, 0xd1, + 0x4c, 0xf7, 0x03, 0x0d, 0xd4, 0xb4, 0x32, 0x59, 0xc9, 0xdb, 0x48, 0x6b, 0xdd, 0x03, 0xd4, 0xcc, + 0xff, 0xb7, 0xa7, 0x97, 0x1d, 0x83, 0x14, 0x3c, 0x0c, 0x4a, 0xc6, 0x1c, 0xa0, 0x3a, 0xd4, 0xbb, + 0x13, 0xa7, 0xd6, 0xd6, 0x44, 0x48, 0x4f, 0x79, 0xf8, 0xf0, 0x7c, 0x1f, 0xa0, 0x79, 0x01, 0xfc, + 0x83, 0xe3, 0x62, 0x37, 0x13, 0x8c, 0x90, 0x47, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x05, 0xac, + 0x00, 0x01, 0x26, 0xf7, 0x02, 0x45, 0xe6, 0xe1, 0xc8, 0xab, 0xbc, 0x2d, 0x72, 0xbb, 0x90, 0xb5, + 0xde, 0x32, 0xbe, 0x60, 0x37, 0x82, 0x31, 0x31, 0x2a, 0x9b, 0x18, 0xca, 0x48, 0xf0, 0xb5, 0xa7, + 0x46, 0x73, 0x53, 0x97, 0x83, 0xc4, 0x73, 0xaf, 0xf6, 0xd0, 0x9a, 0x01, 0xf1, 0x90, 0x4a, 0xb0, + 0x29, 0x00, 0x0f, 0x84, 0xc0, 0x91, 0x07, 0x0f, 0x66, 0x06, 0x55, 0x79, 0x81, 0x03, 0xd8, 0x2b, + 0xbf, 0xce, 0xaf, 0x58, 0x00, 0x5d, 0xa3, 0x51, 0x10, 0x01, 0x67, 0x83, 0x8c, 0xc8, 0x52, 0x71, + 0x2c, 0x72, 0x07, 0x0e, 0xc5, 0xb4, 0x70, 0xf2, 0x3a, 0x97, 0x84, 0x7e, 0xd7, 0xd6, 0xae, 0xf0, + 0x5b, 0xe3, 0xe3, 0xe0, 0x1f, 0xc0, 0xfd, 0x07, 0xc3, 0xf1, 0xcb, 0x31, 0x93, 0x9d, 0xc3, 0x7d, + 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x15, 0xbc, 0x04, 0x80, 0x27, 0x96, 0xe5, 0x9f, 0x1d, 0x98, + 0x7f, 0xde, 0xa9, 0x06, 0x6d, 0xc7, 0xd7, 0xc3, 0xd7, 0x0d, 0xbe, 0xbc, 0xfe, 0xc4, 0xbb, 0x57, + 0x49, 0x0e, 0x1b, 0x73, 0x4e, 0x9e, 0xe9, 0xbd, 0x85, 0xb6, 0xb8, 0x53, 0x7b, 0x9d, 0x8f, 0x2c, + 0x36, 0x77, 0xcc, 0x79, 0x69, 0x4a, 0xd0, 0x70, 0x5a, 0x7a, 0x48, 0x88, 0xe5, 0x54, 0x6b, 0x83, + 0xad, 0x36, 0x6a, 0x20, 0xeb, 0x58, 0x8d, 0x8f, 0x2b, 0x0e, 0xd7, 0xfd, 0x28, 0x0d, 0xb4, 0x3e, + 0x8d, 0xa3, 0x0f, 0x85, 0xb9, 0xde, 0xbe, 0x06, 0x1a, 0x1a, 0x00, 0x55, 0x89, 0xa8, 0x1f, 0xec, + 0x45, 0x8a, 0x42, 0x58, 0x88, 0x64, 0xa0, 0x3e, 0xc4, 0x1f, 0x07, 0xc0, 0xf0, 0x70, 0x1f, 0x85, + 0xf0, 0x5c, 0x1f, 0xc6, 0x79, 0x30, 0x2b, 0x5c, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xf5, 0xa4, + 0x00, 0xc0, 0x1a, 0x82, 0xb9, 0xa8, 0x96, 0x29, 0xa5, 0x81, 0x9f, 0x39, 0x3b, 0x70, 0x23, 0x39, + 0x35, 0x0a, 0x95, 0x81, 0x24, 0xb3, 0xa0, 0x58, 0x6c, 0xf3, 0x5d, 0xd1, 0x39, 0xc1, 0x71, 0x21, + 0x10, 0xc2, 0x4b, 0x28, 0x89, 0x97, 0x94, 0x06, 0x7c, 0x8a, 0x5d, 0xaa, 0xba, 0x73, 0xaa, 0x37, + 0x76, 0x1c, 0x58, 0x7b, 0x78, 0x53, 0x13, 0xd9, 0x1d, 0xcc, 0x11, 0x3d, 0x87, 0xc9, 0x70, 0x9c, + 0x4a, 0xe5, 0x84, 0x26, 0x63, 0x1c, 0x21, 0xbb, 0x4e, 0x17, 0xb0, 0x80, 0x04, 0xbc, 0x61, 0x90, + 0x93, 0xc2, 0x90, 0x33, 0xf4, 0xbd, 0xe4, 0x6e, 0x57, 0xaa, 0xf0, 0xb6, 0x4b, 0x4e, 0x1f, 0xc3, + 0xe0, 0xf8, 0x3f, 0x04, 0xf5, 0x9a, 0x7e, 0xa7, 0xe0, 0x68, 0xe2, 0xe3, 0xc0, 0xf2, 0x01, 0xb3, + 0xa4, 0x65, 0x4a, 0x45, 0x72, 0x09, 0x05, 0xb4, 0x00, 0x01, 0xf0, 0xd7, 0x1b, 0x3d, 0x12, 0xfe, + 0x87, 0xbc, 0xf1, 0x46, 0x7f, 0xaf, 0xe8, 0x8e, 0xd8, 0xa8, 0x0f, 0x35, 0x81, 0xf6, 0xf3, 0x53, + 0xa1, 0xee, 0x9e, 0x47, 0x32, 0x60, 0x41, 0x56, 0x19, 0x5e, 0xcd, 0x91, 0x93, 0x3c, 0xd2, 0xb0, + 0xef, 0x03, 0x36, 0x91, 0xaa, 0x9a, 0x8f, 0x06, 0x90, 0xfe, 0x02, 0xce, 0x1f, 0xbc, 0x5f, 0x43, + 0x9e, 0x0d, 0xbf, 0x81, 0x52, 0xb4, 0xb0, 0xcf, 0x9f, 0xd6, 0xf4, 0x80, 0xe1, 0x9c, 0xa3, 0x54, + 0xa7, 0xcb, 0xae, 0x65, 0xa0, 0xbb, 0x60, 0x04, 0x5f, 0x2b, 0x58, 0x25, 0xd7, 0x1c, 0x18, 0x8c, + 0x6b, 0x87, 0x21, 0x29, 0x51, 0x92, 0xc2, 0x46, 0x2e, 0xbc, 0x38, 0x60, 0xfc, 0x0e, 0xc7, 0x87, + 0x0e, 0x0c, 0x3e, 0xde, 0x3d, 0x31, 0x45, 0x11, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xe5, 0xbc, + 0x00, 0x00, 0x40, 0x70, 0xf1, 0xc9, 0x87, 0xe9, 0x1b, 0x2a, 0x08, 0xfb, 0x57, 0x88, 0xb6, 0x0a, + 0x8e, 0x86, 0x71, 0x2b, 0x11, 0x1c, 0x02, 0x56, 0xbf, 0xbd, 0x5f, 0x02, 0xca, 0x76, 0x93, 0x36, + 0x6e, 0x68, 0xfd, 0xfe, 0x4d, 0xb0, 0x70, 0xfb, 0xfe, 0x93, 0xab, 0x7e, 0xe2, 0xdd, 0x26, 0x32, + 0x82, 0x73, 0x95, 0x17, 0x35, 0x0a, 0x59, 0x2c, 0xe7, 0x31, 0x16, 0xe6, 0xd2, 0xc5, 0x4a, 0x94, + 0x1c, 0xa5, 0xfb, 0x30, 0x7e, 0xec, 0x23, 0x7a, 0xf2, 0x1d, 0x92, 0x4f, 0xe2, 0xcf, 0xbf, 0x9a, + 0xec, 0xc2, 0x31, 0x03, 0x61, 0x81, 0x9a, 0x2b, 0xcc, 0xd6, 0xe7, 0x3f, 0x9c, 0x6e, 0x6f, 0x8f, + 0xf0, 0x5e, 0x7f, 0x21, 0xe6, 0x5f, 0xf0, 0x68, 0xfa, 0xa7, 0x28, 0x7a, 0xee, 0x4b, 0x56, 0xde, + 0xa4, 0x65, 0x4a, 0x45, 0x72, 0x08, 0xe5, 0xbc, 0x00, 0xc3, 0x1c, 0xbf, 0x03, 0xf7, 0xa9, 0x45, + 0xe6, 0xe9, 0x53, 0x2c, 0xa3, 0x3e, 0xd3, 0x05, 0x55, 0xc8, 0x9e, 0xf4, 0xf3, 0xa5, 0x9c, 0x17, + 0x7d, 0x48, 0x7e, 0x0b, 0x90, 0xe1, 0xd4, 0xae, 0x28, 0xb7, 0xfc, 0x5f, 0x7f, 0x3f, 0x84, 0x86, + 0xcc, 0x56, 0x0a, 0x75, 0x23, 0x72, 0x68, 0x0e, 0x1b, 0x59, 0xd5, 0x06, 0xfb, 0x2e, 0xaa, 0x30, + 0x5a, 0x37, 0x88, 0x6d, 0x75, 0xf8, 0x3a, 0x91, 0xbb, 0x72, 0x21, 0xfa, 0xad, 0x9a, 0x92, 0x6c, + 0x8e, 0xd5, 0xa2, 0xda, 0x89, 0x7d, 0x64, 0xf5, 0x9d, 0x55, 0xc8, 0x86, 0x06, 0x9e, 0xc1, 0x99, + 0xf2, 0x33, 0xd7, 0x89, 0xd4, 0xf2, 0x27, 0x87, 0x03, 0xf0, 0x0f, 0xe8, 0x0e, 0xe0, 0x0f, 0x03, + 0xfa, 0x38, 0x7f, 0x0f, 0x04, 0xa8, 0x31, 0x79, 0xa4, 0x65, 0x4a, 0x45, 0x72, 0x08, 0xe5, 0xbc, + 0x04, 0x82, 0x1b, 0xa4, 0x01, 0xe0, 0x13, 0x37, 0x59, 0xe0, 0xd9, 0x2b, 0x95, 0x47, 0x1c, 0x57, + 0xac, 0xdd, 0x50, 0x7d, 0xfb, 0xb2, 0x1b, 0xb9, 0xcb, 0xd5, 0xac, 0x55, 0x76, 0xde, 0x79, 0x88, + 0xff, 0xcd, 0x3f, 0xa9, 0x7c, 0x2c, 0x75, 0x4a, 0x1a, 0x26, 0xd2, 0xe1, 0x26, 0x94, 0x79, 0x08, + 0x5e, 0x25, 0x2d, 0x71, 0xa9, 0x95, 0xb9, 0x2a, 0xcf, 0x78, 0x15, 0x88, 0x84, 0x5b, 0xc3, 0xf2, + 0xca, 0x49, 0x1c, 0x54, 0xda, 0xf5, 0x9f, 0x94, 0xff, 0x8f, 0x98, 0x4a, 0x83, 0x1e, 0x01, 0x90, + 0x58, 0x53, 0x67, 0x24, 0x68, 0x8a, 0x6f, 0xc7, 0x15, 0xfc, 0x0d, 0xf5, 0x61, 0xe3, 0xfd, 0xfc, + 0x1d, 0xc3, 0xf0, 0x3f, 0x01, 0xe1, 0xd8, 0x1f, 0x07, 0xc0, 0xc6, 0xf1, 0xe7, 0x31, 0x8f, 0x73, + 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x05, 0xcc, 0x05, 0xbf, 0xeb, 0x69, 0x94, 0x99, 0xa8, 0xf1, + 0x0e, 0x92, 0x78, 0xaf, 0x01, 0xdc, 0x41, 0x3e, 0xd9, 0x4d, 0xb5, 0xc3, 0xe6, 0x5e, 0x56, 0x0e, + 0xdb, 0x69, 0x6b, 0x2a, 0x17, 0xbe, 0xd8, 0x2a, 0x71, 0xec, 0x70, 0x96, 0x8e, 0xda, 0xf1, 0x2e, + 0xeb, 0x40, 0x3f, 0x94, 0x3d, 0x1c, 0x7b, 0x73, 0x92, 0x4f, 0x25, 0x3d, 0x4a, 0x1a, 0x00, 0x96, + 0xa1, 0xee, 0xad, 0xdc, 0xf5, 0x98, 0xea, 0x1c, 0x29, 0x20, 0x01, 0x5e, 0x7b, 0x38, 0x3b, 0x43, + 0x0e, 0x27, 0xcb, 0x30, 0x93, 0xe7, 0x9e, 0xbe, 0x6f, 0xb3, 0xdf, 0x0e, 0xec, 0xc8, 0x54, 0x02, + 0x9f, 0x24, 0xdb, 0x5c, 0x4f, 0x1a, 0xd2, 0x52, 0x1d, 0xe3, 0xcf, 0x8f, 0xe0, 0xf8, 0x07, 0xf1, + 0x3a, 0x8f, 0x08, 0x82, 0x63, 0x92, 0x07, 0x32, 0x82, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xe5, 0xd4, + 0x00, 0x06, 0x94, 0xa8, 0xb5, 0xb8, 0x7f, 0xec, 0x80, 0x29, 0x5d, 0xd8, 0xc1, 0x32, 0xdd, 0xd1, + 0x05, 0x53, 0x33, 0x6b, 0x58, 0x00, 0xcf, 0x48, 0xa4, 0xd6, 0xce, 0x18, 0x6a, 0xbe, 0xec, 0x08, + 0xa1, 0x16, 0x39, 0xd6, 0xcd, 0x75, 0x06, 0x8e, 0xdc, 0x22, 0x03, 0x83, 0x24, 0xd1, 0x5e, 0x0c, + 0x6c, 0xa1, 0xa4, 0x36, 0x06, 0xb8, 0xc8, 0x16, 0x32, 0xbe, 0x8c, 0x78, 0x04, 0xbe, 0x84, 0xf2, + 0x4a, 0xed, 0x94, 0x75, 0xde, 0xb4, 0xdc, 0x91, 0x8d, 0xb5, 0x96, 0x61, 0x43, 0xee, 0x3e, 0x69, + 0x03, 0x84, 0xb5, 0x43, 0xad, 0xa5, 0x35, 0x42, 0x75, 0x08, 0x3d, 0x0a, 0x27, 0x76, 0x6c, 0x7b, + 0xc3, 0x07, 0x81, 0xf9, 0x81, 0xf8, 0x7c, 0x07, 0xe8, 0xf1, 0xa2, 0x5e, 0x3c, 0xf4, 0x29, 0x51, + 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xf5, 0xcc, 0x04, 0x8e, 0x04, 0x00, 0xff, 0x7a, 0x54, 0x6b, + 0x4a, 0x61, 0x23, 0x36, 0xd4, 0x6b, 0x8f, 0x20, 0x5c, 0xa3, 0xfb, 0x43, 0xde, 0x27, 0x6a, 0x30, + 0x65, 0xd6, 0x6f, 0x2c, 0x6b, 0xa1, 0x25, 0xbc, 0xa3, 0x4e, 0xbf, 0x32, 0x9b, 0xf0, 0x68, 0x3d, + 0xf9, 0xe8, 0x10, 0x34, 0xfa, 0xb4, 0x5d, 0x40, 0x02, 0x97, 0xa7, 0x90, 0x0c, 0xf9, 0xdf, 0x6c, + 0x21, 0xad, 0x56, 0xcc, 0xe4, 0xb6, 0xc0, 0x7b, 0x8f, 0x5b, 0x15, 0xe2, 0x34, 0xc8, 0x47, 0x2b, + 0x32, 0xc7, 0x48, 0x70, 0x23, 0xd9, 0x08, 0x31, 0x02, 0xa4, 0x99, 0x10, 0xf0, 0x20, 0x72, 0x89, + 0x11, 0xe2, 0x4b, 0x9a, 0x0b, 0x0a, 0x13, 0x04, 0xe1, 0xe0, 0x3c, 0x2e, 0x60, 0x7e, 0x1f, 0xc0, + 0x78, 0x7c, 0x78, 0xce, 0x37, 0x58, 0x68, 0xd8, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xe5, 0xcc, + 0x04, 0x90, 0x07, 0x33, 0x07, 0x60, 0xfd, 0xe3, 0xec, 0x7e, 0x9b, 0xe3, 0xd1, 0x30, 0x29, 0x22, + 0x2a, 0x23, 0x7b, 0x65, 0x26, 0x4d, 0xba, 0xfc, 0xd2, 0xfa, 0xe0, 0xf9, 0x20, 0x2f, 0x01, 0x72, + 0x86, 0xaf, 0x5b, 0x7f, 0x49, 0xaf, 0xbc, 0xbb, 0x31, 0x35, 0x9b, 0xda, 0xbf, 0x63, 0x88, 0xd5, + 0x5e, 0x2c, 0xbf, 0xb7, 0x44, 0xc1, 0xf9, 0x23, 0xde, 0x5a, 0x01, 0x4a, 0x44, 0x41, 0x2c, 0x32, + 0x34, 0x86, 0xac, 0x49, 0x62, 0xef, 0xb7, 0x8b, 0xfe, 0xfa, 0xf2, 0x66, 0x0e, 0x88, 0x72, 0x90, + 0x88, 0x7b, 0x83, 0x9b, 0x05, 0xd1, 0x51, 0x8f, 0xbf, 0x79, 0xc1, 0x79, 0xf2, 0x78, 0x40, 0x8c, + 0x3c, 0x3e, 0x03, 0xfc, 0x2d, 0xc1, 0xf8, 0x0f, 0x0f, 0xba, 0x8c, 0x86, 0x98, 0x47, 0x5c, 0xf2, + 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xf5, 0xcc, 0x00, 0xcc, 0x0f, 0x92, 0x03, 0x75, 0x12, 0xdb, + 0x72, 0x37, 0x8b, 0x66, 0xc9, 0xe9, 0x64, 0xa3, 0x17, 0x5f, 0xa0, 0x2e, 0x6e, 0x60, 0xc1, 0xa6, + 0x8c, 0xfd, 0x02, 0x3b, 0xa7, 0x98, 0xa7, 0xda, 0x9e, 0x16, 0xcb, 0x8d, 0x65, 0x7a, 0x7e, 0xb7, + 0xc4, 0xf5, 0x37, 0x88, 0x71, 0x38, 0x2c, 0x32, 0x52, 0x17, 0x70, 0x3f, 0xd1, 0x6a, 0x6d, 0x8d, + 0xed, 0x5f, 0xa4, 0xed, 0x42, 0x06, 0x4b, 0xa8, 0x5e, 0x62, 0x4e, 0x4b, 0x02, 0xe7, 0xfe, 0x54, + 0xde, 0x88, 0xf7, 0xfd, 0xd3, 0x3d, 0x6f, 0x1b, 0xc9, 0x94, 0x74, 0x57, 0xc4, 0x3d, 0xdc, 0x54, + 0x91, 0xd5, 0xe7, 0x36, 0x17, 0x11, 0xac, 0x28, 0x2b, 0xe6, 0x1c, 0x1f, 0x03, 0xe4, 0xfc, 0x1f, + 0x85, 0x78, 0xe3, 0x32, 0x78, 0x57, 0x69, 0x2d, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xf5, 0xdc, + 0x00, 0x06, 0xa0, 0x3e, 0xa9, 0x76, 0x09, 0x2a, 0x4e, 0xa0, 0xcb, 0xdc, 0xf0, 0x30, 0x4d, 0xdf, + 0x8d, 0xd3, 0x19, 0x7b, 0x2c, 0x79, 0x1e, 0x6a, 0x23, 0xc5, 0xf9, 0x46, 0x91, 0xd0, 0x26, 0x1b, + 0xf8, 0x46, 0x50, 0x56, 0x83, 0x98, 0x27, 0x1a, 0xa7, 0x7c, 0xeb, 0x90, 0x9b, 0x94, 0x6f, 0x17, + 0x54, 0x89, 0x21, 0x94, 0xd2, 0x04, 0x00, 0x45, 0x98, 0x30, 0xb4, 0xcf, 0x4a, 0x90, 0xed, 0x77, + 0x51, 0x67, 0xe4, 0xf1, 0xd3, 0xaf, 0xec, 0x3c, 0x03, 0x0a, 0xf3, 0x83, 0xf5, 0x40, 0x49, 0x3f, + 0x15, 0x21, 0xf4, 0x41, 0x6f, 0xd7, 0x58, 0xc5, 0x6e, 0xcd, 0x4a, 0xbd, 0x91, 0x6f, 0x64, 0x08, + 0xf0, 0xf8, 0x7e, 0x1f, 0x80, 0xfe, 0x1f, 0xc7, 0x97, 0xb8, 0x63, 0x70, 0x0c, 0x18, 0x3f, 0xc8, + 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x05, 0xd4, 0x00, 0x00, 0xf2, 0xb4, 0x00, 0x7b, 0xf6, 0x30, + 0x4b, 0xd2, 0x57, 0xae, 0x2e, 0xf3, 0x08, 0x05, 0x34, 0x38, 0x6e, 0xac, 0xfd, 0x94, 0xb9, 0xf9, + 0xd8, 0x5b, 0xef, 0x7c, 0x81, 0x95, 0xe9, 0xe0, 0x6b, 0x7d, 0x8a, 0xb8, 0x6f, 0x66, 0x82, 0x11, + 0xb7, 0x6a, 0x63, 0x28, 0xf7, 0x91, 0x58, 0x38, 0xce, 0xc8, 0x53, 0xb2, 0x9a, 0xb4, 0x07, 0x3c, + 0x81, 0x27, 0x4a, 0x88, 0x33, 0x6d, 0x37, 0xb1, 0xa7, 0xcb, 0x6e, 0xdd, 0xc7, 0x9a, 0x6e, 0xdc, + 0xb5, 0x21, 0x7f, 0xd3, 0x02, 0x0a, 0x79, 0x83, 0xb4, 0xaf, 0x74, 0x1b, 0xb4, 0x0f, 0xe2, 0xaf, + 0x15, 0x6d, 0x0d, 0x01, 0xc7, 0x02, 0x06, 0x33, 0xeb, 0xd8, 0x33, 0xe6, 0xe5, 0xe3, 0x2e, 0xf0, + 0x5f, 0x0f, 0x21, 0xcb, 0x6d, 0x86, 0x06, 0xb9, 0xb4, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd5, 0xdc, + 0x00, 0xc3, 0xf5, 0xf9, 0xd6, 0xe4, 0x55, 0xeb, 0x8c, 0xb5, 0x6c, 0xc9, 0xe2, 0x92, 0x54, 0xcb, + 0x36, 0x2d, 0x90, 0x55, 0x22, 0x29, 0x91, 0xbe, 0xfd, 0xd4, 0xba, 0x06, 0xcb, 0x7d, 0x5a, 0x1e, + 0x5a, 0xef, 0xb4, 0x5e, 0x44, 0xee, 0xd9, 0x9d, 0xae, 0x61, 0xfc, 0x66, 0x66, 0x1d, 0x2d, 0xd8, + 0x88, 0xd4, 0x4b, 0xf5, 0x0f, 0xcc, 0x70, 0xc7, 0x5e, 0xa4, 0x1b, 0xa0, 0xcc, 0x6f, 0x14, 0xa2, + 0x28, 0x84, 0x56, 0xdf, 0x9b, 0x9b, 0x1d, 0x31, 0x77, 0x7b, 0xbc, 0x6f, 0x3d, 0xae, 0x37, 0x24, + 0xe4, 0xef, 0xab, 0xb6, 0xc0, 0x00, 0xad, 0x44, 0xf1, 0x9e, 0x98, 0x19, 0x0b, 0xfd, 0x70, 0x67, + 0x9f, 0x9e, 0x1e, 0x87, 0xa1, 0xa0, 0xd0, 0x1c, 0x9d, 0x1a, 0x3d, 0x1b, 0xf6, 0x2c, 0xd9, 0xd3, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xc5, 0xdc, 0x04, 0x8c, 0x0a, 0xd0, 0x8b, 0x08, 0x59, 0xea, + 0x37, 0x08, 0xa4, 0x24, 0x01, 0x0c, 0xa3, 0xaa, 0xb6, 0x2b, 0xca, 0x29, 0x89, 0x31, 0x5d, 0xa3, + 0xf5, 0xdc, 0xd1, 0x78, 0x34, 0xda, 0xce, 0xbe, 0x18, 0xff, 0x18, 0xd4, 0x8a, 0xf4, 0x80, 0x40, + 0x8e, 0xe5, 0x8f, 0x26, 0x02, 0xa1, 0x19, 0x3a, 0xa7, 0x4a, 0x85, 0x8b, 0xc8, 0xe2, 0xed, 0xfa, + 0xd3, 0x58, 0x19, 0xea, 0xe5, 0x7d, 0x86, 0xe8, 0x1b, 0x59, 0x73, 0x0f, 0x92, 0xfd, 0x6e, 0xb9, + 0x05, 0xb2, 0x21, 0x1d, 0xdd, 0xbc, 0xea, 0xfe, 0x15, 0xf9, 0x96, 0x7e, 0x39, 0x45, 0xa1, 0xfa, + 0xf9, 0x77, 0xca, 0x50, 0x47, 0x81, 0xa3, 0x4d, 0xf3, 0xc3, 0xc1, 0xce, 0x1d, 0x03, 0x9c, 0x9d, + 0x0b, 0x02, 0x9f, 0x43, 0x9d, 0x67, 0x93, 0xab, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xe5, 0xdc, + 0x00, 0x08, 0xa3, 0xf4, 0x59, 0x6e, 0x0b, 0x46, 0xee, 0xce, 0x77, 0xfe, 0x27, 0x55, 0xf6, 0xd6, + 0xf4, 0xf7, 0x2b, 0xab, 0xb3, 0x99, 0x0c, 0x42, 0xe4, 0x05, 0x9d, 0x21, 0x3b, 0x34, 0x6d, 0x0c, + 0x33, 0xf2, 0xee, 0x72, 0x2e, 0xd1, 0x1e, 0xeb, 0x70, 0x36, 0xd9, 0x45, 0x08, 0xd7, 0x3c, 0x79, + 0x05, 0x63, 0x41, 0x7c, 0x78, 0xc3, 0xaa, 0x76, 0x14, 0x22, 0xdf, 0xc4, 0x5b, 0x1b, 0x23, 0x88, + 0xac, 0xd9, 0x38, 0x7e, 0x84, 0x1c, 0x81, 0x80, 0x3c, 0x57, 0xa7, 0x2c, 0xe8, 0xf2, 0x59, 0xb4, + 0x9c, 0x8a, 0x56, 0xb3, 0xd0, 0x29, 0x1a, 0x0e, 0x3f, 0x19, 0x29, 0xbb, 0x8a, 0xf3, 0xfb, 0x03, + 0x31, 0xcf, 0xc1, 0xe0, 0x70, 0x70, 0xc6, 0x1f, 0x0d, 0x8e, 0x43, 0xf0, 0x73, 0xc1, 0x44, 0xfc, + 0xb4, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xf5, 0xe4, 0x00, 0x04, 0x6e, 0x94, 0x9d, 0xaa, 0x6b, 0x43, + 0x9d, 0x6b, 0x8f, 0x14, 0x3b, 0xb0, 0x78, 0xb0, 0x33, 0x31, 0xc1, 0x8e, 0xf3, 0x75, 0x71, 0xbe, + 0xb9, 0x84, 0x5c, 0xfb, 0x3d, 0x2c, 0x0c, 0x32, 0x6a, 0xef, 0x90, 0x51, 0xdf, 0x6f, 0x43, 0x7b, + 0x96, 0x17, 0xd9, 0x81, 0x2c, 0xb6, 0x12, 0xd9, 0x8f, 0x4f, 0xbf, 0x44, 0xcc, 0x46, 0xab, 0xef, + 0xf3, 0xd1, 0xa1, 0x10, 0x28, 0xa4, 0x6d, 0xcc, 0x77, 0xd3, 0xf8, 0xd5, 0xd5, 0x95, 0xcf, 0xde, + 0xb4, 0x9e, 0xeb, 0xb2, 0x3f, 0x7d, 0xef, 0xbd, 0x2d, 0x86, 0x29, 0xfe, 0xd9, 0x70, 0x7a, 0x3d, + 0x48, 0xcd, 0xf0, 0x03, 0xe4, 0x04, 0x18, 0x8a, 0xce, 0x76, 0x66, 0x0c, 0x3c, 0x1c, 0x27, 0x33, + 0x81, 0x0e, 0x97, 0xd0, 0x77, 0xa3, 0x52, 0xe1, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd5, 0xf4, + 0x04, 0x80, 0xb9, 0xd1, 0xea, 0x0b, 0x6d, 0x5b, 0x0a, 0xd6, 0xda, 0xe7, 0xa9, 0xe7, 0x58, 0x40, + 0x74, 0xdb, 0x35, 0xf6, 0x73, 0xc7, 0x81, 0x7c, 0xc1, 0x6e, 0xd3, 0xa8, 0xaa, 0xef, 0xe2, 0xf7, + 0x20, 0x16, 0xbc, 0x3e, 0x32, 0x32, 0x17, 0x5d, 0xfc, 0x7b, 0x2b, 0x95, 0x6c, 0x89, 0x9a, 0xd0, + 0xe4, 0xe9, 0x63, 0x5b, 0x56, 0x4f, 0x74, 0x16, 0x51, 0x96, 0x07, 0xe2, 0x2b, 0x78, 0xb7, 0x22, + 0x11, 0x0b, 0x86, 0x06, 0xa7, 0xa1, 0x93, 0xb8, 0xc4, 0x8a, 0x3f, 0x17, 0xb6, 0xef, 0x2c, 0x0f, + 0xa1, 0x7c, 0x56, 0x44, 0x22, 0x73, 0x7b, 0x4e, 0x3f, 0xbd, 0x5e, 0x9d, 0x79, 0xad, 0xbc, 0x57, + 0x4c, 0xe6, 0x07, 0x83, 0x18, 0x4f, 0x1f, 0x26, 0x8e, 0x1f, 0x1d, 0x8f, 0x84, 0x73, 0x97, 0x93, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xf5, 0xe4, 0x05, 0xc0, 0xee, 0xc4, 0xb6, 0xf1, 0x78, 0x1c, + 0x92, 0xa3, 0x44, 0xa6, 0x8e, 0x34, 0x54, 0x3c, 0xf9, 0x70, 0x11, 0x72, 0xf7, 0xc3, 0xf8, 0xad, + 0x77, 0x05, 0x7e, 0x9c, 0x87, 0x4e, 0x37, 0xfe, 0x70, 0x58, 0x3e, 0x56, 0xb0, 0x6c, 0xca, 0xfc, + 0x7e, 0x7c, 0x9f, 0x2c, 0xf0, 0x7f, 0x0a, 0x88, 0xec, 0x6f, 0x83, 0xfd, 0xe8, 0xd4, 0x8a, 0x04, + 0x1f, 0xd5, 0x6c, 0x5e, 0x75, 0xdb, 0x2f, 0x2b, 0x44, 0x69, 0xbf, 0xdc, 0xeb, 0x71, 0xe6, 0xd0, + 0x53, 0xf1, 0xfa, 0x6d, 0x0f, 0xe1, 0x1e, 0x1f, 0x47, 0xe4, 0xbc, 0x23, 0x78, 0x89, 0xe5, 0x78, + 0x8c, 0x68, 0xc7, 0x3b, 0x54, 0x4e, 0xf7, 0x80, 0xbe, 0x3c, 0x78, 0x7c, 0x3e, 0x78, 0x78, 0xe3, + 0x17, 0x81, 0x1a, 0x4a, 0x1d, 0xec, 0x1a, 0xe3, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd5, 0xf4, + 0x00, 0x07, 0xf9, 0xc9, 0xf0, 0xe6, 0x4c, 0x15, 0x5e, 0x3d, 0x52, 0x3a, 0xa8, 0x4a, 0x61, 0xe0, + 0x03, 0x4e, 0x61, 0x7a, 0xef, 0x54, 0x60, 0x34, 0x45, 0x5c, 0xd9, 0x41, 0xfc, 0x6e, 0x6c, 0x25, + 0xf6, 0xab, 0x6e, 0x7a, 0x2c, 0x3f, 0x2a, 0x6b, 0x3c, 0x46, 0x44, 0x43, 0x08, 0x95, 0xcd, 0xda, + 0xc3, 0x53, 0x0a, 0xac, 0x72, 0x02, 0x3e, 0xd6, 0x8c, 0xcc, 0x32, 0x1c, 0x4d, 0x64, 0x94, 0xc5, + 0xfb, 0xb0, 0x68, 0xe7, 0xaf, 0x6e, 0xbc, 0x9e, 0xbf, 0x27, 0xe0, 0x0a, 0x84, 0x6b, 0x28, 0x53, + 0xa7, 0xc1, 0xf3, 0xf1, 0xad, 0x27, 0xf2, 0xd6, 0xad, 0x45, 0x33, 0x0f, 0xde, 0x9d, 0x6b, 0x43, + 0x01, 0xe1, 0xf1, 0xe0, 0x78, 0x68, 0x2c, 0x12, 0x73, 0x05, 0x4b, 0x4c, 0xd9, 0x79, 0xa3, 0x4c, + 0xb4, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xe5, 0xfc, 0x04, 0x83, 0xf2, 0x43, 0x5c, 0x3b, 0xb7, 0x22, + 0xf4, 0x83, 0x1a, 0x13, 0xf1, 0x44, 0x26, 0x9c, 0x93, 0xed, 0xf4, 0xfd, 0xc0, 0xb6, 0xef, 0xcb, + 0x43, 0x5d, 0xde, 0xf0, 0xeb, 0x01, 0x1b, 0x76, 0x82, 0xbb, 0x78, 0xa2, 0x26, 0x9b, 0x63, 0xb0, + 0x91, 0xa5, 0xd2, 0xd7, 0xc5, 0x54, 0xd9, 0x20, 0x51, 0x6e, 0xb0, 0x0b, 0x7d, 0x13, 0x46, 0x39, + 0xbd, 0xf9, 0x45, 0xeb, 0x7d, 0x41, 0xb4, 0x37, 0x3e, 0x09, 0xb5, 0xd2, 0xec, 0x67, 0x93, 0xcf, + 0x6d, 0xa9, 0xd0, 0x67, 0x10, 0x80, 0x08, 0x13, 0x66, 0x42, 0xe1, 0x77, 0x38, 0x4c, 0x54, 0xb4, + 0x87, 0xe5, 0xff, 0x95, 0x61, 0x25, 0x4d, 0x18, 0xff, 0x47, 0xbe, 0x3e, 0x1c, 0x16, 0xea, 0x1c, + 0x5e, 0x0f, 0x0f, 0x2b, 0x4f, 0x45, 0xce, 0x0b, 0xb4, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd5, 0xf4, + 0x04, 0x80, 0x89, 0x37, 0xc9, 0xab, 0x0b, 0x9d, 0xb6, 0x8a, 0xd4, 0x9b, 0x41, 0x45, 0x5a, 0xba, + 0xc7, 0xa5, 0x1b, 0x4e, 0xe8, 0xe3, 0x3f, 0xbf, 0x5d, 0x32, 0x99, 0xb8, 0x18, 0xb0, 0x4c, 0x0b, + 0x7a, 0xf4, 0x78, 0xe5, 0xb0, 0x90, 0x99, 0xaa, 0xf0, 0xb4, 0xc5, 0xec, 0xc4, 0x4f, 0xae, 0x75, + 0x57, 0x9f, 0x7b, 0x46, 0x7c, 0x0a, 0xee, 0xf1, 0x41, 0xc1, 0x74, 0x4d, 0x0b, 0xe1, 0xa3, 0x75, + 0xeb, 0x64, 0xc8, 0xbc, 0x29, 0x00, 0x21, 0x91, 0x9d, 0x0c, 0x29, 0x1f, 0xcd, 0xc2, 0x19, 0xc7, + 0x70, 0x7f, 0x12, 0x30, 0x3d, 0x9a, 0x37, 0xa6, 0x83, 0x08, 0x2c, 0x75, 0xf2, 0x65, 0x9f, 0x60, + 0x73, 0xe3, 0xf1, 0xc0, 0x7c, 0x3c, 0x7e, 0x1e, 0x78, 0xe1, 0xf5, 0xe8, 0xee, 0x3e, 0x7d, 0xb9, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xe5, 0xfc, 0x04, 0x80, 0x29, 0xc1, 0xc4, 0x2f, 0x9d, 0x30, + 0x83, 0x82, 0x73, 0x6c, 0x33, 0xb6, 0x37, 0xcf, 0xec, 0xb3, 0xe8, 0x48, 0x24, 0xd6, 0x82, 0xab, + 0x23, 0xcb, 0x9d, 0xcb, 0x6b, 0x1a, 0xad, 0x96, 0x32, 0x3a, 0xed, 0x43, 0xf1, 0xdf, 0x02, 0xde, + 0x66, 0x4a, 0x8b, 0x5c, 0x1a, 0x8f, 0x70, 0x0a, 0xf2, 0xaa, 0x04, 0x2d, 0xa6, 0x23, 0x35, 0x8a, + 0x7f, 0x1e, 0xf9, 0x24, 0xec, 0x67, 0x7e, 0x7f, 0x1e, 0x7d, 0x4c, 0x99, 0x43, 0x3d, 0xb8, 0xed, + 0xef, 0xea, 0xb6, 0x25, 0x06, 0x20, 0x69, 0x25, 0xe4, 0x97, 0xd0, 0x9d, 0x0c, 0xb5, 0x3d, 0x3d, + 0x08, 0xe2, 0x54, 0x9d, 0xc2, 0xf8, 0x5f, 0x70, 0x78, 0xf1, 0xf8, 0x3e, 0x3c, 0x2e, 0x0f, 0xc4, + 0x20, 0x9f, 0x80, 0x42, 0x6e, 0xe7, 0xc6, 0x17, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x09, 0x05, 0xf4, + 0x04, 0x80, 0x62, 0xdf, 0x2f, 0x51, 0xcc, 0x97, 0x7e, 0x59, 0xa8, 0x2a, 0xd7, 0x36, 0x6c, 0x58, + 0x4a, 0x4b, 0x7b, 0x51, 0x19, 0x51, 0x3d, 0xb2, 0x05, 0xfc, 0xe0, 0xcc, 0x89, 0xa9, 0xc6, 0xc7, + 0x24, 0xdd, 0x06, 0x2d, 0x74, 0xb4, 0x72, 0xc4, 0xbe, 0x2b, 0x17, 0xb5, 0x87, 0x6e, 0x3f, 0x6a, + 0x84, 0x9c, 0x59, 0x7a, 0x07, 0x64, 0xf0, 0x8a, 0x54, 0x2c, 0x1a, 0x5e, 0x8a, 0x5d, 0xd3, 0x8b, + 0xe0, 0x6f, 0x06, 0x0d, 0x7a, 0xc8, 0x6d, 0x9f, 0x0e, 0x15, 0x6b, 0x8f, 0xa7, 0xdf, 0x39, 0x2f, + 0x45, 0x1a, 0xdb, 0xc4, 0x36, 0xfc, 0xa2, 0xa5, 0xb1, 0x93, 0xd4, 0xea, 0x73, 0x91, 0x1f, 0x83, + 0x03, 0xc3, 0x81, 0xe0, 0x70, 0xf0, 0xf1, 0x87, 0x0b, 0x18, 0xfe, 0x55, 0xc4, 0xfc, 0x70, 0xde, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xe6, 0x04, 0x00, 0x10, 0xbe, 0xbf, 0xc1, 0x4c, 0x3c, 0x03, + 0xe8, 0xeb, 0x0a, 0x6c, 0x91, 0xcb, 0xa3, 0xf1, 0xe3, 0xd5, 0x64, 0x95, 0x46, 0x53, 0xe1, 0x02, + 0x5f, 0x30, 0x79, 0x44, 0xd0, 0x69, 0x4d, 0xa1, 0xeb, 0x7f, 0x6f, 0x76, 0x59, 0x9b, 0xd4, 0x88, + 0x22, 0x14, 0x38, 0x7f, 0xaa, 0x4e, 0x5f, 0x90, 0xb9, 0x20, 0xf6, 0x8e, 0x58, 0x89, 0x05, 0x85, + 0xbf, 0x3f, 0xbc, 0x8b, 0xb2, 0x6c, 0xaa, 0x18, 0x66, 0xd8, 0xdf, 0x29, 0xea, 0x75, 0xf3, 0xb3, + 0x33, 0x17, 0x3a, 0x15, 0x63, 0xe0, 0x66, 0x04, 0x1d, 0xd6, 0x2b, 0x29, 0x01, 0x11, 0x48, 0x86, + 0xfa, 0x15, 0x8a, 0xd2, 0x06, 0x01, 0x4c, 0xcf, 0xe3, 0x8f, 0x1c, 0x61, 0xf3, 0xf4, 0x1e, 0xd8, + 0x1d, 0x3f, 0x7d, 0x1e, 0x5a, 0x85, 0xc3, 0x1e, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd6, 0x04, + 0x00, 0xd0, 0x76, 0xf2, 0x7f, 0x99, 0x06, 0x42, 0xba, 0x96, 0xa4, 0x66, 0xa1, 0x65, 0x02, 0x8e, + 0x0b, 0x06, 0xb9, 0x14, 0x5b, 0xf5, 0x89, 0x5b, 0x66, 0xf4, 0x69, 0x54, 0x4e, 0x58, 0x4d, 0xd9, + 0xd3, 0xab, 0xd2, 0x53, 0x92, 0xc5, 0x77, 0x20, 0x12, 0x1c, 0xe8, 0xa6, 0x3e, 0xb7, 0x9f, 0x88, + 0xff, 0x50, 0x5b, 0xeb, 0x68, 0xb2, 0xe8, 0x7a, 0xbb, 0x9c, 0x05, 0x5f, 0x10, 0x4c, 0xc4, 0x8f, + 0x55, 0xd9, 0x6c, 0xf6, 0xb3, 0xbc, 0x53, 0x99, 0xa9, 0xfb, 0x82, 0x3f, 0xee, 0xcf, 0x37, 0x72, + 0xfa, 0x8b, 0xe5, 0x63, 0x9b, 0x43, 0xde, 0x64, 0x3d, 0x37, 0xbe, 0x00, 0xdd, 0x9a, 0x4d, 0x4e, + 0xa7, 0x8e, 0x0c, 0xf8, 0x7c, 0x2c, 0x3a, 0x69, 0x38, 0x94, 0x89, 0x6b, 0x31, 0xdc, 0xa7, 0x30, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xc6, 0x0c, 0x04, 0x92, 0xbc, 0x03, 0x7e, 0xd0, 0xea, 0xb9, + 0x7b, 0xd3, 0x5f, 0xcb, 0xdf, 0x36, 0x51, 0x32, 0x20, 0x0f, 0x25, 0x93, 0xce, 0x92, 0xdc, 0x67, + 0x85, 0xf8, 0xa7, 0x11, 0x0b, 0x52, 0x1c, 0x67, 0x7f, 0x11, 0xf7, 0xbd, 0x73, 0x99, 0x32, 0xb3, + 0x85, 0x2b, 0x47, 0x6d, 0x06, 0x3c, 0xa6, 0x12, 0x4b, 0xa7, 0x65, 0x2f, 0x5a, 0xb9, 0xb9, 0xb8, + 0xf9, 0x0e, 0x07, 0x38, 0xf8, 0x16, 0x00, 0x16, 0x29, 0xee, 0xc0, 0xf6, 0x7a, 0x70, 0x17, 0x7a, + 0x0b, 0x6b, 0xb6, 0xba, 0x81, 0x15, 0x7d, 0xe9, 0x72, 0x05, 0x3d, 0xb0, 0x2c, 0xe9, 0xe0, 0x6d, + 0x72, 0x06, 0xfc, 0x3e, 0x1a, 0x23, 0x83, 0xe0, 0xc1, 0xf3, 0xe0, 0xf1, 0xe0, 0xff, 0xce, 0xfe, + 0x3c, 0x4c, 0x5f, 0x5c, 0x0c, 0xd4, 0x72, 0xf2, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xc6, 0x0c, + 0x00, 0x07, 0x36, 0x63, 0xdb, 0xdc, 0xae, 0x38, 0x21, 0x1b, 0xe5, 0xf8, 0x09, 0x1f, 0xd9, 0x49, + 0xb5, 0x70, 0xc3, 0x04, 0x20, 0xc7, 0x91, 0x5f, 0x41, 0x67, 0x58, 0x9e, 0xcc, 0x6f, 0x19, 0x17, + 0xba, 0xbb, 0x8f, 0x6b, 0x96, 0xea, 0xae, 0x01, 0x48, 0xac, 0xd3, 0x00, 0xa6, 0x22, 0xed, 0xbf, + 0x9c, 0x95, 0x21, 0x51, 0xe7, 0xf7, 0xda, 0x00, 0x14, 0xc1, 0x6e, 0xc5, 0x6d, 0xb5, 0x37, 0x0f, + 0xa0, 0xa2, 0xae, 0x80, 0x0b, 0x8d, 0x03, 0x1e, 0x8b, 0x0f, 0x81, 0x19, 0x1b, 0xaf, 0x80, 0x06, + 0xdc, 0xb0, 0x9d, 0x32, 0xaf, 0x09, 0x59, 0xbc, 0xfe, 0xc0, 0x0f, 0xe9, 0x14, 0x22, 0x16, 0xbc, + 0x78, 0xf1, 0xc7, 0x82, 0xa0, 0xd3, 0x3a, 0x79, 0x63, 0x61, 0xd0, 0xb8, 0x24, 0xc4, 0x7b, 0xc5, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd6, 0x0c, 0x02, 0x0e, 0x25, 0x72, 0x42, 0xbd, 0xb4, 0xc0, + 0xf2, 0x6f, 0x60, 0x06, 0x8a, 0x98, 0xa8, 0xef, 0xe8, 0x44, 0x26, 0x84, 0xe7, 0x86, 0xfb, 0x51, + 0x3c, 0x8c, 0x19, 0x84, 0x2a, 0x50, 0x74, 0x24, 0xf3, 0xd0, 0x37, 0xa4, 0x5c, 0x0d, 0x54, 0xf1, + 0xaf, 0x99, 0xb6, 0x5d, 0xf4, 0x72, 0x41, 0x06, 0x61, 0xec, 0xd2, 0x2d, 0xe5, 0xe6, 0xa1, 0x56, + 0xb3, 0x00, 0x09, 0xef, 0x3b, 0x48, 0xda, 0xee, 0xce, 0x68, 0x4c, 0x27, 0x5d, 0x7e, 0x0a, 0x03, + 0xfa, 0x7d, 0xf0, 0x29, 0x30, 0xa8, 0xbc, 0xff, 0x66, 0x26, 0xc7, 0x9a, 0xf1, 0xe3, 0x8e, 0xc2, + 0xae, 0xa9, 0x3f, 0x26, 0xd8, 0x9f, 0xdd, 0x8e, 0x61, 0xe1, 0xc7, 0x87, 0x07, 0x4e, 0x38, 0x03, + 0xc3, 0xc1, 0xfe, 0x0a, 0x30, 0x95, 0x41, 0x31, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xc6, 0x0c, + 0x00, 0x09, 0x4a, 0xba, 0x20, 0x0e, 0xdd, 0xb5, 0x71, 0x59, 0x9b, 0x48, 0xf7, 0xbd, 0x32, 0x2e, + 0x70, 0xf2, 0xb3, 0x61, 0x13, 0xd1, 0x27, 0xa7, 0xc3, 0xa3, 0xce, 0x3a, 0xbf, 0x7e, 0xc9, 0x87, + 0x8d, 0x2d, 0xa7, 0xa4, 0x10, 0x1d, 0x84, 0x94, 0xcd, 0x82, 0x0b, 0xa6, 0x3e, 0x87, 0x40, 0x2a, + 0x96, 0x04, 0x81, 0x4f, 0x3a, 0x8a, 0xe7, 0x15, 0x54, 0xaf, 0xb8, 0xb8, 0x55, 0x9b, 0x5c, 0x03, + 0x6d, 0xc1, 0x8e, 0x8c, 0xfd, 0x91, 0xb2, 0x44, 0xae, 0xc8, 0x8e, 0x54, 0xb2, 0x24, 0xf8, 0xe7, + 0x63, 0x79, 0x1d, 0x8a, 0x26, 0x04, 0xcc, 0x36, 0x28, 0xf5, 0x18, 0x11, 0x50, 0xa3, 0xf1, 0xfc, + 0xc6, 0x38, 0x63, 0xf0, 0x38, 0x68, 0x9e, 0xf7, 0x8e, 0x16, 0x77, 0xf0, 0x77, 0xf6, 0x59, 0x59, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd6, 0x0c, 0x02, 0x00, 0x42, 0x97, 0xbb, 0x39, 0xe8, 0x03, + 0xce, 0xd5, 0x36, 0x74, 0xc7, 0x31, 0x63, 0x1b, 0x4f, 0x59, 0xd8, 0x86, 0x4a, 0xe7, 0x5b, 0x0e, + 0xb9, 0x07, 0x66, 0xc9, 0xee, 0x38, 0x38, 0x0c, 0x07, 0xf7, 0x3b, 0xa5, 0x2b, 0x3c, 0x23, 0x3f, + 0x0c, 0x7b, 0x3a, 0x77, 0x87, 0xb3, 0x31, 0x7b, 0xcb, 0x2a, 0xf2, 0x27, 0x40, 0x3c, 0x49, 0x00, + 0x7b, 0x02, 0x97, 0xea, 0x0b, 0x68, 0x92, 0x64, 0x40, 0x87, 0x84, 0x16, 0x5d, 0xaa, 0xd6, 0x04, + 0xe2, 0xf8, 0x1b, 0x6c, 0xd0, 0x5b, 0xc0, 0x47, 0x96, 0xa3, 0x43, 0xa0, 0x76, 0x34, 0x63, 0xac, + 0x35, 0xff, 0x87, 0xf5, 0x7e, 0x5f, 0x6f, 0x81, 0x83, 0xcf, 0x83, 0x83, 0xc1, 0xae, 0xee, 0x31, + 0x3a, 0xd9, 0x39, 0xc1, 0xec, 0x58, 0xcd, 0xaa, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xb6, 0x1c, + 0x04, 0x84, 0x23, 0xaf, 0x99, 0xd5, 0x0c, 0x08, 0x4e, 0xf2, 0x00, 0xf3, 0x8d, 0x76, 0x65, 0xd4, + 0x95, 0x1a, 0x35, 0xb3, 0x28, 0xa2, 0x5d, 0xa3, 0xe6, 0x91, 0x75, 0xa9, 0x55, 0x61, 0xbd, 0x18, + 0xd9, 0xc3, 0xff, 0x69, 0xb2, 0x01, 0xba, 0xfa, 0x42, 0xa0, 0x53, 0xa2, 0xb1, 0x54, 0x2d, 0xd1, + 0x09, 0xf1, 0xbb, 0xc2, 0xe6, 0xa1, 0x5e, 0x01, 0xe9, 0x59, 0x8b, 0x23, 0x84, 0x74, 0x70, 0x47, + 0x6a, 0x6c, 0x2d, 0xee, 0x29, 0x86, 0x24, 0xdd, 0x90, 0x93, 0x8b, 0xfa, 0x89, 0x54, 0xbb, 0xbf, + 0x5e, 0xc9, 0xcf, 0xfd, 0x99, 0x85, 0xf1, 0xad, 0x54, 0xe8, 0x16, 0x48, 0x02, 0x10, 0x40, 0x07, + 0xfc, 0x3c, 0x30, 0x78, 0x7f, 0x03, 0xe6, 0xe2, 0x25, 0x38, 0xc1, 0x6d, 0xc7, 0x2e, 0x33, 0xa0, + 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xe6, 0x1c, 0x00, 0xcd, 0xe3, 0x69, 0xf7, 0x40, 0x1e, 0x74, + 0x25, 0x44, 0x00, 0x92, 0x99, 0xed, 0x26, 0x50, 0x0b, 0x9f, 0x30, 0x0d, 0x8f, 0x1b, 0xe6, 0xa7, + 0x41, 0x36, 0xd5, 0x43, 0x3a, 0x1d, 0x24, 0x88, 0xc3, 0x28, 0x8f, 0x79, 0x70, 0x2f, 0xe3, 0x70, + 0x9b, 0x91, 0x93, 0xd8, 0xcc, 0x13, 0x9a, 0x15, 0xa1, 0xea, 0xb0, 0x07, 0xbc, 0x69, 0x82, 0x01, + 0xd4, 0xff, 0xc9, 0xbc, 0x58, 0x50, 0xc1, 0x69, 0xa8, 0x88, 0xd9, 0x8f, 0x05, 0x5d, 0xb5, 0xf8, + 0xbd, 0x17, 0x23, 0x9e, 0xae, 0x9f, 0x4c, 0xcd, 0x03, 0x29, 0xcc, 0x77, 0x3e, 0x15, 0x09, 0x15, + 0xc1, 0x5b, 0x8a, 0x59, 0xfe, 0x22, 0x66, 0x54, 0xff, 0x78, 0x3e, 0x3c, 0x3f, 0x07, 0x98, 0x7a, + 0x1f, 0x1f, 0x37, 0x20, 0xca, 0x39, 0xb9, 0x39, 0x95, 0x7a, 0xef, 0x6f, 0x72, 0x08, 0xd6, 0x14, + 0x04, 0x80, 0x10, 0x7b, 0xd8, 0x54, 0xad, 0xc6, 0x86, 0x84, 0x25, 0x8a, 0x23, 0x50, 0x2e, 0x21, + 0x07, 0x97, 0x1a, 0xab, 0xff, 0x1b, 0x4a, 0xab, 0x59, 0xea, 0x72, 0x68, 0x69, 0x76, 0xf3, 0x72, + 0x33, 0x74, 0x9c, 0xd9, 0xe1, 0x98, 0x96, 0x73, 0x92, 0xc6, 0x1f, 0xa1, 0xc7, 0x77, 0x6d, 0xf1, + 0x59, 0xdf, 0x86, 0xbd, 0x2e, 0xcf, 0x61, 0x42, 0x19, 0x0c, 0x08, 0xd5, 0x79, 0xdb, 0x9d, 0xe4, + 0xb5, 0x7a, 0x8e, 0xa7, 0xf2, 0xd8, 0xdd, 0x3b, 0xb0, 0xf3, 0x9f, 0x8c, 0xe8, 0xaa, 0x10, 0x01, + 0x41, 0xd8, 0xf9, 0x89, 0x06, 0xdb, 0xa6, 0x9c, 0x90, 0x2d, 0xa9, 0x50, 0x6b, 0x00, 0xce, 0x24, + 0x3c, 0x0f, 0xe3, 0xf8, 0x9e, 0x0f, 0xc0, 0xf8, 0x46, 0x66, 0xcb, 0xd7, 0x2a, 0xc0, 0x15, 0xd2, + 0x95, 0x7a, 0xef, 0x6f, 0x72, 0x08, 0xd6, 0x14, 0x00, 0xc0, 0x18, 0x52, 0x09, 0x56, 0x62, 0x26, + 0x69, 0x3e, 0x1e, 0xbf, 0x78, 0x75, 0xe9, 0x11, 0x95, 0x8d, 0x93, 0xa2, 0xc4, 0xf5, 0x83, 0x96, + 0xf7, 0x2c, 0x50, 0x79, 0x1c, 0x60, 0xb2, 0x28, 0x3a, 0x71, 0x84, 0x2c, 0xe8, 0xa6, 0x4c, 0xfd, + 0xdd, 0x61, 0x94, 0xaa, 0x41, 0xb8, 0xea, 0x9a, 0x9d, 0x51, 0xe4, 0x0a, 0x7d, 0x14, 0x4c, 0x06, + 0x05, 0x3a, 0xc6, 0x89, 0xad, 0x6e, 0xc1, 0x00, 0x88, 0x30, 0xa5, 0x60, 0x6a, 0x83, 0x5f, 0xc5, + 0xc6, 0x5a, 0xa8, 0xbd, 0x53, 0xcf, 0xe2, 0x15, 0x13, 0x28, 0x72, 0xc6, 0x94, 0x38, 0xe0, 0x02, + 0xb5, 0x98, 0x49, 0xbe, 0x65, 0xf8, 0xbc, 0x74, 0x4c, 0xe0, 0xf0, 0x78, 0x0f, 0xf0, 0xf0, 0x7f, + 0x94, 0xc0, 0x7c, 0xfa, 0xa5, 0x9f, 0x2b, 0x06, 0x95, 0x7a, 0xef, 0x6f, 0x72, 0x08, 0xd6, 0x24, + 0x07, 0x80, 0x4e, 0xc1, 0x89, 0x46, 0x26, 0xc4, 0x5e, 0xaa, 0x70, 0x30, 0xa7, 0xfb, 0x1f, 0x76, + 0xe7, 0xba, 0x40, 0xdf, 0xc2, 0x8b, 0x3a, 0x34, 0xbd, 0xae, 0xb2, 0x0c, 0x47, 0x4d, 0x75, 0xfa, + 0xca, 0x74, 0xf3, 0x9a, 0x93, 0x77, 0xe5, 0x6c, 0x8f, 0x18, 0x15, 0x8e, 0x78, 0xa5, 0xf6, 0xce, + 0x35, 0xd3, 0xc3, 0x92, 0x90, 0xe1, 0x57, 0xb8, 0x00, 0x4f, 0x2b, 0xf1, 0xcd, 0x8c, 0x6f, 0x32, + 0x9f, 0x1c, 0xc8, 0x4d, 0xd9, 0x6e, 0x64, 0xe5, 0xc1, 0xc6, 0x34, 0xad, 0x22, 0x74, 0x01, 0x2f, + 0x38, 0xc7, 0x1c, 0xac, 0x61, 0x21, 0x7a, 0xce, 0x4e, 0x8c, 0x8d, 0x8e, 0x1e, 0xe7, 0x9d, 0x92, + 0xf9, 0xe1, 0xf0, 0xf1, 0x1e, 0x0d, 0x6b, 0xd5, 0x3a, 0x37, 0x88, 0x71, 0xea, 0x38, 0x2e, 0x5e, + 0x95, 0x7a, 0xef, 0x6f, 0x72, 0x08, 0xb6, 0x1c, 0x0c, 0x08, 0x67, 0x4c, 0x0e, 0xad, 0xf1, 0x49, + 0x37, 0xa9, 0x04, 0xaa, 0xff, 0x81, 0xfb, 0xcd, 0xd6, 0xc4, 0x36, 0xcb, 0x0d, 0x4e, 0x54, 0x00, + 0x94, 0xa0, 0x08, 0x2d, 0x8a, 0x3b, 0xbc, 0x48, 0x14, 0x1c, 0x9a, 0x2a, 0x28, 0xa4, 0xb8, 0x44, + 0xfa, 0xa1, 0x5c, 0xc6, 0x38, 0x3b, 0x38, 0x56, 0xa6, 0xbd, 0xa4, 0x23, 0x0d, 0x51, 0x13, 0xd8, + 0x82, 0xb7, 0xd6, 0xb2, 0x0c, 0xb1, 0xbb, 0xee, 0x3c, 0xe9, 0xae, 0x8f, 0xa1, 0x58, 0xd3, 0xa4, + 0xf0, 0xb0, 0xd2, 0x1a, 0x47, 0xdc, 0x23, 0xa9, 0xeb, 0xd6, 0xed, 0x4b, 0xf8, 0x54, 0xd2, 0x6a, + 0x9a, 0xbd, 0xa9, 0xf3, 0x78, 0xd4, 0xec, 0x6c, 0x71, 0xe3, 0xf0, 0xfc, 0x0f, 0x07, 0x0f, 0x1a, + 0x41, 0xd3, 0x83, 0xed, 0x4d, 0x9b, 0x39, 0xb9, 0x86, 0xac, 0xc9, 0x85, 0x72, 0x08, 0xc6, 0x34, + 0x00, 0xc0, 0x50, 0x63, 0x0a, 0xf2, 0xb2, 0x04, 0xfb, 0xa2, 0xad, 0x2c, 0x66, 0x3c, 0x75, 0x78, + 0x71, 0x49, 0x83, 0x23, 0x56, 0x1d, 0x76, 0xf9, 0xfb, 0xdf, 0x6c, 0xf3, 0x8e, 0x7d, 0x79, 0x75, + 0x49, 0xa0, 0xea, 0xbc, 0xd4, 0x64, 0x06, 0x01, 0x4b, 0xae, 0x65, 0x0a, 0xe6, 0xa1, 0x4a, 0xea, + 0x4d, 0x7c, 0xa9, 0x87, 0xb2, 0x00, 0xed, 0xb8, 0xb8, 0x1d, 0x91, 0x66, 0x60, 0xbe, 0x75, 0x8c, + 0x8a, 0xec, 0x52, 0x3b, 0xcd, 0x11, 0x00, 0x86, 0x6b, 0x85, 0xc9, 0xbb, 0xbd, 0x7f, 0x8e, 0x6b, + 0x0d, 0x3c, 0x88, 0xc9, 0x5e, 0x5d, 0x7e, 0x50, 0x49, 0xdb, 0x5e, 0x21, 0x6f, 0x27, 0x47, 0xc7, + 0x88, 0x27, 0x1c, 0x3e, 0x18, 0x3d, 0x43, 0xe1, 0xf1, 0xc1, 0x64, 0xa7, 0x3b, 0x8c, 0x63, 0xd6, + 0x66, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x2c, 0x00, 0x00, 0xd6, 0xba, 0x0a, 0xde, 0x0d, 0x61, + 0x67, 0xd8, 0xe3, 0x78, 0x6a, 0xff, 0x7d, 0x19, 0x94, 0xee, 0x63, 0x36, 0x3a, 0xe5, 0xad, 0xbe, + 0xd7, 0xa9, 0xa6, 0x9e, 0x01, 0x5a, 0x9e, 0x43, 0x1c, 0xa9, 0x0b, 0x96, 0xf7, 0xb7, 0x0d, 0x9e, + 0xfd, 0xfd, 0x1d, 0x8c, 0xe9, 0xdf, 0xe5, 0x75, 0x92, 0x38, 0x51, 0x8b, 0x11, 0x3a, 0x98, 0x91, + 0x48, 0x8d, 0xce, 0xdf, 0xf7, 0xf3, 0x36, 0x84, 0x06, 0x51, 0x0c, 0xa4, 0x04, 0xbb, 0x0e, 0xaa, + 0x3a, 0x32, 0xe6, 0x76, 0x90, 0x6e, 0xcc, 0x32, 0x22, 0xc0, 0x50, 0x53, 0x5a, 0xe4, 0xef, 0x68, + 0xe5, 0x5e, 0x42, 0x3a, 0x92, 0x48, 0xa2, 0x42, 0x92, 0x7f, 0x61, 0xf0, 0xf1, 0xf0, 0x1e, 0x0e, + 0x1e, 0x0c, 0x78, 0xe8, 0x7a, 0x19, 0x83, 0xa0, 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xe6, 0x3c, + 0x00, 0x00, 0x0a, 0xff, 0x7b, 0xe7, 0x5b, 0x83, 0xba, 0x0c, 0x69, 0xdf, 0x15, 0x0f, 0x07, 0xbf, + 0xb0, 0x1d, 0xbc, 0xf4, 0x00, 0xec, 0x08, 0x89, 0x68, 0x80, 0x04, 0xdf, 0x2f, 0x2a, 0xb8, 0xbd, + 0x5b, 0x65, 0x6c, 0x7b, 0x32, 0xf3, 0x9d, 0x55, 0x70, 0xc5, 0xfb, 0xf8, 0xe3, 0x87, 0x28, 0xe7, + 0x71, 0xe7, 0x54, 0xd0, 0x2f, 0xec, 0xb5, 0x75, 0x2b, 0x46, 0xf4, 0x56, 0xac, 0xf6, 0xb6, 0xa0, + 0x28, 0xac, 0x21, 0x0f, 0x7e, 0x13, 0xe1, 0xe8, 0x80, 0x6c, 0x48, 0xd2, 0xb1, 0xcc, 0x2e, 0x65, + 0x01, 0xa8, 0x98, 0x0c, 0x68, 0x7f, 0xb2, 0x05, 0x2e, 0x9e, 0xb1, 0xff, 0x26, 0x55, 0xf0, 0x66, + 0xe7, 0xa1, 0x82, 0x16, 0x60, 0x1c, 0x7c, 0xf8, 0x70, 0x75, 0xa3, 0x84, 0xcd, 0x2b, 0x0a, 0x9d, + 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xf6, 0x3c, 0x00, 0x02, 0x0e, 0x27, 0x82, 0x99, 0xe0, 0xe8, + 0x31, 0xb9, 0xde, 0x8e, 0x62, 0xa3, 0x93, 0x5b, 0x5a, 0x38, 0x66, 0x19, 0x54, 0xb2, 0x40, 0x91, + 0xbc, 0xbb, 0x17, 0x7f, 0x83, 0x0a, 0x3d, 0xe4, 0xc2, 0xbd, 0x75, 0xd3, 0x37, 0x22, 0x13, 0x41, + 0x28, 0xe4, 0x4c, 0x72, 0x8f, 0x26, 0x2e, 0xd9, 0x8f, 0x06, 0xc9, 0x7f, 0xbb, 0x7c, 0x31, 0xb2, + 0xb0, 0x7c, 0xd8, 0xa4, 0xa0, 0x33, 0x0d, 0x11, 0xfe, 0xb7, 0x75, 0xf2, 0x5a, 0x36, 0x1d, 0x1d, + 0x51, 0x78, 0xb5, 0x63, 0x7d, 0xd8, 0x11, 0xf5, 0x11, 0x15, 0x86, 0xde, 0xd6, 0xc7, 0x3d, 0xd2, + 0x3d, 0xd8, 0x50, 0x25, 0x2e, 0x10, 0x8b, 0xf0, 0xc7, 0xfa, 0x66, 0xa7, 0x1f, 0xce, 0x10, 0x53, + 0xb6, 0x41, 0xe6, 0xac, 0xd2, 0xe6, 0x7c, 0x52, 0xa6, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x34, + 0x00, 0x02, 0x11, 0xd1, 0xf6, 0x74, 0xac, 0x18, 0x97, 0x32, 0x76, 0x76, 0x5a, 0x4b, 0x29, 0x5e, + 0xb0, 0xd3, 0x25, 0xb8, 0x55, 0x79, 0x84, 0x50, 0xce, 0x82, 0x68, 0xd1, 0x82, 0xd2, 0x01, 0x50, + 0x2d, 0xb7, 0x83, 0xfd, 0x1d, 0x6b, 0x00, 0x7f, 0x39, 0xc3, 0x51, 0x18, 0x64, 0x87, 0x42, 0xf2, + 0xa3, 0x6d, 0x4c, 0x76, 0x43, 0xe4, 0x04, 0x59, 0xc7, 0x6b, 0xad, 0x01, 0x9d, 0x8c, 0xdc, 0x4e, + 0x88, 0x3e, 0x0b, 0x06, 0xe2, 0xbd, 0xb6, 0x04, 0x77, 0x0b, 0x7a, 0x57, 0x9f, 0x00, 0x64, 0x18, + 0xbe, 0x03, 0x4d, 0x87, 0x13, 0x3f, 0x07, 0x0c, 0x48, 0xf5, 0x42, 0x31, 0x78, 0x67, 0xae, 0xf6, + 0xf8, 0x1e, 0x70, 0xe8, 0x78, 0x1e, 0x1e, 0x07, 0xc0, 0x47, 0xc5, 0x1a, 0xe8, 0xf4, 0x15, 0x45, + 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xf6, 0x3c, 0x00, 0x00, 0x11, 0xb5, 0xe6, 0xc1, 0x00, 0x51, + 0x31, 0x12, 0xd9, 0x99, 0xfb, 0x0a, 0x15, 0x55, 0x1a, 0x94, 0xb5, 0x00, 0x76, 0xe2, 0x1a, 0xcf, + 0xe5, 0x93, 0xfc, 0xe1, 0x09, 0xcf, 0x27, 0xca, 0xd2, 0x88, 0xf5, 0x05, 0xa0, 0xb5, 0x9a, 0x72, + 0xf3, 0xcc, 0x46, 0xdd, 0x6e, 0xd2, 0xd6, 0x21, 0x3a, 0xb0, 0xa4, 0x22, 0x0c, 0xfc, 0xee, 0xc0, + 0x06, 0xba, 0x1c, 0xe5, 0x9f, 0x15, 0xac, 0x63, 0xa5, 0x14, 0xa5, 0x62, 0x4a, 0xbf, 0x0b, 0x74, + 0xde, 0x60, 0x22, 0x2b, 0xb7, 0x1b, 0x70, 0x45, 0xb8, 0xa8, 0x9d, 0xb0, 0x76, 0xf4, 0x51, 0x2c, + 0xc5, 0x2e, 0xeb, 0x1b, 0x76, 0x44, 0x3b, 0x63, 0x2f, 0x69, 0xa5, 0x20, 0x3b, 0x87, 0x8e, 0x78, + 0x7c, 0x3c, 0x1e, 0x86, 0xb8, 0xe6, 0x98, 0x5d, 0x66, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xf6, 0x3c, + 0x0a, 0xff, 0xf1, 0x47, 0xd8, 0x22, 0x24, 0x56, 0xcc, 0x72, 0xf5, 0x72, 0x9c, 0xd8, 0x45, 0xb2, + 0x33, 0x94, 0xc7, 0xba, 0x3c, 0xb2, 0x1d, 0x7b, 0xf6, 0x6c, 0xc3, 0x5b, 0xe3, 0xeb, 0x71, 0xc8, + 0x62, 0xa5, 0xe9, 0x65, 0xd9, 0x67, 0x96, 0x6b, 0xd3, 0x77, 0xbf, 0xb0, 0x69, 0xce, 0xf3, 0xb2, + 0x95, 0xfc, 0x9d, 0xf5, 0xc1, 0x94, 0x33, 0xd7, 0x83, 0x10, 0x17, 0xbb, 0xb8, 0x58, 0x78, 0x0e, + 0x9f, 0xd0, 0xa8, 0xaf, 0x06, 0xfb, 0xb7, 0x4f, 0xad, 0x46, 0x84, 0x45, 0x11, 0xf0, 0x07, 0xe7, + 0xee, 0x1e, 0x3a, 0x7b, 0xe5, 0x53, 0xcf, 0x81, 0xd2, 0x55, 0x55, 0xfb, 0xf2, 0x72, 0x47, 0x04, + 0xc6, 0xfb, 0x38, 0xf1, 0xe0, 0x39, 0x3c, 0x0f, 0x8f, 0xc5, 0x18, 0x69, 0x17, 0x18, 0x51, 0x84, + 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xe6, 0x3c, 0x00, 0x00, 0x4e, 0x9e, 0xb3, 0x62, 0xa1, 0x80, + 0x3c, 0xee, 0x6e, 0xcf, 0x55, 0xf6, 0xa5, 0xc3, 0x08, 0x2e, 0x79, 0xd4, 0xc2, 0x36, 0x30, 0x02, + 0xe4, 0xd9, 0x0e, 0x73, 0xd6, 0x03, 0x44, 0x6b, 0x47, 0x7c, 0x0c, 0xac, 0x1a, 0xa0, 0xe6, 0xf8, + 0xf7, 0x2e, 0xc9, 0x30, 0xa4, 0xe2, 0x16, 0x07, 0x6f, 0x02, 0x83, 0x3f, 0xba, 0x00, 0x96, 0xe4, + 0x5a, 0xca, 0x2e, 0xde, 0x08, 0xee, 0x91, 0xcd, 0x96, 0x84, 0x6f, 0xd0, 0xb9, 0xf7, 0x7b, 0x9d, + 0xa6, 0x07, 0x18, 0x93, 0x43, 0x80, 0x02, 0x30, 0xd9, 0x23, 0x47, 0xc8, 0x18, 0x3d, 0xb6, 0x1c, + 0x69, 0x9b, 0x04, 0x58, 0xe0, 0x7b, 0xd4, 0x33, 0xc6, 0x36, 0x3c, 0x11, 0xd0, 0x37, 0x0d, 0x82, + 0xe3, 0xcd, 0x62, 0xb6, 0x42, 0x8c, 0x5d, 0x3c, 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x3c, + 0x00, 0x06, 0xa8, 0xec, 0x30, 0xf8, 0x02, 0xa1, 0x07, 0xfa, 0x5b, 0x5c, 0x8c, 0xc3, 0x42, 0x0c, + 0xe1, 0x29, 0xa5, 0x53, 0x1e, 0x51, 0x10, 0x26, 0x71, 0x87, 0x44, 0xaf, 0xee, 0x39, 0xaf, 0x5f, + 0x3f, 0xdd, 0x78, 0xec, 0xc0, 0x1c, 0xad, 0xf2, 0xb9, 0x85, 0x42, 0x67, 0x5d, 0x89, 0x9a, 0x09, + 0x80, 0x84, 0xb0, 0x18, 0xd6, 0x31, 0x00, 0x32, 0x0b, 0x3d, 0x09, 0x81, 0x4c, 0x0e, 0xcf, 0x17, + 0x6f, 0xaa, 0x1b, 0x05, 0x81, 0x33, 0xa8, 0x98, 0x2f, 0x59, 0xbc, 0xf7, 0x3b, 0x6f, 0x65, 0x0f, + 0x88, 0x3f, 0xeb, 0x50, 0x44, 0xc0, 0x9c, 0xe7, 0xa5, 0xf0, 0x80, 0xa0, 0x8e, 0x27, 0xe1, 0xb7, + 0xd1, 0x1e, 0xf0, 0x6e, 0x83, 0xf0, 0xdf, 0xbe, 0x1d, 0x1c, 0xf2, 0xdc, 0x10, 0x2e, 0xb1, 0x6e, + 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x3c, 0x00, 0xc3, 0x46, 0xcc, 0xea, 0x31, 0xbc, 0xda, + 0x50, 0xd5, 0xd8, 0x31, 0xdb, 0xd6, 0xfa, 0x60, 0x5b, 0xf3, 0x68, 0x9c, 0xd3, 0x1c, 0x21, 0x39, + 0x8d, 0x20, 0x7e, 0x2b, 0x5e, 0xbb, 0x55, 0x62, 0x37, 0x9d, 0xbc, 0x96, 0xd7, 0x08, 0x18, 0x69, + 0x94, 0x6c, 0x3b, 0xed, 0x7a, 0xb9, 0xe4, 0xb4, 0x31, 0x38, 0x6b, 0x80, 0x00, 0x32, 0x83, 0x71, + 0x2e, 0x4c, 0xc4, 0xa8, 0x50, 0xf0, 0xce, 0xe8, 0xc6, 0xcc, 0x22, 0x79, 0x6b, 0x89, 0xed, 0x9a, + 0x3d, 0x81, 0x9e, 0x42, 0x0f, 0x88, 0x28, 0x35, 0xcb, 0x2c, 0x24, 0xf8, 0x09, 0x28, 0x1a, 0x43, + 0x8b, 0x4f, 0xb3, 0x90, 0x55, 0x1f, 0x16, 0x22, 0xf0, 0x09, 0xcc, 0x3d, 0xa7, 0x0e, 0xca, 0x71, + 0xe9, 0x0a, 0x27, 0x0e, 0x72, 0x79, 0x8b, 0x76, 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x3c, + 0x00, 0x07, 0x5f, 0xc8, 0xe3, 0xa6, 0xd0, 0x3b, 0x8e, 0x82, 0x7a, 0xd8, 0x1a, 0x9f, 0x9f, 0x8a, + 0x9c, 0x91, 0x57, 0x5c, 0x78, 0x55, 0x30, 0x77, 0x38, 0xe1, 0x3a, 0x34, 0x48, 0x9b, 0x71, 0xdf, + 0x4f, 0xcf, 0x6b, 0x8a, 0xbe, 0xd6, 0x3e, 0x4c, 0x70, 0xc5, 0x75, 0x1c, 0x66, 0x3a, 0xa7, 0x49, + 0x24, 0x92, 0xb3, 0x00, 0x12, 0xda, 0xab, 0x09, 0x82, 0x4d, 0x33, 0x74, 0x8c, 0xe7, 0x7c, 0x3e, + 0x90, 0xf2, 0x88, 0x96, 0xa9, 0xeb, 0x40, 0x7a, 0x77, 0x28, 0xad, 0x6c, 0xf5, 0xb8, 0x80, 0x34, + 0x5f, 0x81, 0x47, 0xa2, 0x42, 0xc8, 0x70, 0xf4, 0x7f, 0x85, 0xd5, 0x93, 0x45, 0x1f, 0x47, 0x19, + 0xc4, 0xc8, 0x00, 0x71, 0x13, 0xec, 0xb2, 0xe2, 0x60, 0x70, 0xce, 0xb4, 0x41, 0xb5, 0x92, 0xe1, + 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xe6, 0x3c, 0x00, 0x00, 0x84, 0xbd, 0x00, 0xfc, 0x0a, 0xf7, + 0xb4, 0x15, 0x10, 0xe4, 0xe0, 0xad, 0x2d, 0x1f, 0x1c, 0x7c, 0x1f, 0xeb, 0xa9, 0x43, 0x10, 0x58, + 0x41, 0x1e, 0x99, 0x52, 0x0d, 0x41, 0xf3, 0x1d, 0xec, 0x63, 0xc2, 0xcc, 0xe2, 0x8b, 0xc1, 0x09, + 0xc6, 0x3f, 0xd8, 0xbf, 0x3e, 0x08, 0x5e, 0x2e, 0x7a, 0x5a, 0x23, 0xe3, 0xb7, 0x53, 0x1c, 0x9e, + 0x27, 0xe5, 0x3d, 0x04, 0x5a, 0xdc, 0xa3, 0xc5, 0x94, 0x6b, 0xcb, 0x09, 0x1e, 0x71, 0x29, 0x47, + 0xd3, 0xbe, 0x4f, 0x08, 0xbe, 0x07, 0xf5, 0xbf, 0x98, 0xa7, 0xbc, 0xc5, 0x25, 0x51, 0xb7, 0x24, + 0x29, 0x21, 0x45, 0x41, 0x11, 0x0d, 0x40, 0x0f, 0x87, 0x78, 0xf4, 0xfc, 0x9f, 0x03, 0xc0, 0x25, + 0xd6, 0xb3, 0xe6, 0x8e, 0x2b, 0xcd, 0xc5, 0x59, 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x3c, + 0x00, 0x01, 0x96, 0x93, 0x10, 0xac, 0x08, 0xb7, 0x3e, 0xc4, 0x99, 0x57, 0x08, 0x27, 0x1c, 0x8c, + 0x85, 0x3b, 0xb2, 0x7a, 0x65, 0x12, 0x36, 0x02, 0x13, 0x5a, 0x4b, 0x74, 0x08, 0xd4, 0x2f, 0xcb, + 0xe7, 0x6d, 0x1f, 0xe0, 0xa7, 0x35, 0x71, 0x09, 0x4b, 0x1e, 0xe5, 0x46, 0xc4, 0xd1, 0x23, 0x69, + 0xa8, 0x36, 0xa6, 0xaa, 0x17, 0x9d, 0x00, 0x03, 0xc5, 0x6e, 0xc2, 0x22, 0x2c, 0x97, 0xbe, 0x22, + 0xa2, 0x28, 0xb7, 0xfe, 0xd3, 0xdb, 0x97, 0x85, 0x75, 0x8f, 0x11, 0x55, 0xef, 0x2c, 0xa9, 0xd1, + 0xbe, 0x97, 0x3d, 0x3b, 0x27, 0x66, 0xcc, 0xb7, 0x2e, 0x2f, 0xe8, 0x13, 0x87, 0x02, 0x60, 0xfd, + 0x39, 0x3c, 0x9b, 0x9f, 0xd1, 0xd8, 0xde, 0x51, 0x7e, 0xb8, 0xc6, 0x15, 0xc2, 0xf3, 0x49, 0xce, + 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xb6, 0x3c, 0x00, 0xc0, 0xea, 0xe4, 0x95, 0x80, 0x8d, 0x68, + 0xa0, 0x21, 0xd3, 0xb5, 0xc1, 0xda, 0x11, 0x65, 0x6e, 0xb6, 0xe1, 0xbf, 0x2d, 0xb8, 0x05, 0x78, + 0x44, 0x1f, 0xcf, 0x65, 0xce, 0x0f, 0x1e, 0x00, 0x61, 0x6d, 0xa4, 0x8f, 0x06, 0x03, 0xfb, 0x8d, + 0x7d, 0x9a, 0xbc, 0xf1, 0xf4, 0x24, 0x49, 0xfb, 0x12, 0x82, 0x12, 0xae, 0x1f, 0x5f, 0x00, 0xe8, + 0x79, 0x1a, 0xc1, 0x95, 0x79, 0x91, 0xec, 0x22, 0x15, 0xea, 0x8e, 0xb8, 0x41, 0x8e, 0xd2, 0xd4, + 0xac, 0x90, 0x3a, 0xfe, 0xad, 0xc8, 0x1e, 0x7f, 0x54, 0x7f, 0x5c, 0xe6, 0x78, 0xef, 0xdd, 0xe6, + 0x7d, 0x53, 0x46, 0x8b, 0x8b, 0xf4, 0x38, 0xce, 0x13, 0xd3, 0x78, 0xf0, 0x3c, 0x3f, 0x81, 0xb2, + 0x70, 0x98, 0x73, 0x85, 0xab, 0xf3, 0xc0, 0x41, 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xe6, 0x3c, + 0x04, 0x80, 0xaa, 0x12, 0x97, 0xdc, 0xaa, 0x03, 0xa0, 0x77, 0xb1, 0x92, 0x08, 0x81, 0x46, 0x0c, + 0x6a, 0xd0, 0x59, 0x2f, 0x45, 0x77, 0xcc, 0xea, 0x25, 0x2a, 0xe3, 0xc4, 0xef, 0x93, 0x94, 0x07, + 0x04, 0xa9, 0x83, 0xbf, 0x71, 0x40, 0xa0, 0x0e, 0xbf, 0x89, 0x20, 0xe4, 0x0c, 0x33, 0xd5, 0x46, + 0xce, 0xb3, 0x82, 0xe6, 0xf5, 0x70, 0x4e, 0x30, 0x84, 0xb0, 0xd5, 0x7f, 0x41, 0x7c, 0x37, 0x6a, + 0x6e, 0xab, 0xf3, 0x46, 0x8d, 0xa8, 0x50, 0x4e, 0x42, 0xb8, 0xaa, 0xa7, 0x51, 0x60, 0x73, 0x64, + 0x89, 0xd0, 0xac, 0x08, 0x59, 0x36, 0xce, 0x12, 0x3f, 0xb5, 0x5c, 0x1a, 0x63, 0xf5, 0xb6, 0x41, + 0x19, 0x98, 0xf8, 0x71, 0xe1, 0x9c, 0xe8, 0xf0, 0x71, 0x56, 0x0e, 0x24, 0x34, 0xbd, 0xdd, 0x24, + 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xc6, 0x3c, 0x04, 0x80, 0x8a, 0xc7, 0x95, 0x58, 0x0d, 0x38, + 0xb6, 0xc4, 0xc1, 0xd1, 0x23, 0x9a, 0x65, 0x8e, 0x7a, 0xd0, 0xcc, 0xdf, 0x30, 0xd4, 0x93, 0xd5, + 0x99, 0xf4, 0xa3, 0x34, 0xd7, 0xae, 0x5c, 0xb9, 0x4e, 0xf5, 0x3d, 0x85, 0x58, 0xff, 0x24, 0x04, + 0xba, 0xd7, 0x3e, 0xf8, 0xba, 0x43, 0x83, 0x08, 0x4d, 0xaa, 0x8d, 0x8a, 0x95, 0x0b, 0x1c, 0x00, + 0x00, 0x24, 0x0e, 0xfe, 0x14, 0xa3, 0xd9, 0x89, 0x57, 0x8c, 0xa6, 0x0a, 0x5a, 0x93, 0xaa, 0x9f, + 0xc0, 0xf7, 0x0f, 0x2e, 0xfa, 0xb1, 0xff, 0x22, 0x93, 0x32, 0xce, 0x42, 0x13, 0x17, 0x06, 0x0f, + 0xd1, 0xa0, 0xdb, 0xcb, 0x87, 0xe0, 0xe0, 0x84, 0x81, 0xc2, 0xc3, 0xe1, 0xe0, 0xf0, 0x3e, 0x7b, + 0x83, 0x9a, 0xb8, 0xf2, 0x76, 0x2f, 0x0c, 0x52, 0xa6, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xc6, 0x3c, + 0x0d, 0xd9, 0x17, 0x1d, 0x9a, 0xd5, 0x20, 0xac, 0xd6, 0x8e, 0xd8, 0x3a, 0x75, 0x82, 0x41, 0x18, + 0x7d, 0xa2, 0x7d, 0x11, 0xd0, 0x21, 0x95, 0xe5, 0x11, 0x3a, 0x54, 0xb2, 0xda, 0x82, 0x94, 0xe1, + 0x2b, 0xb7, 0x6a, 0xca, 0xed, 0x38, 0x57, 0x99, 0x72, 0x64, 0x07, 0x03, 0x34, 0xb1, 0x34, 0x8b, + 0x0a, 0xe1, 0xce, 0xa2, 0x38, 0x53, 0xfe, 0x0c, 0x37, 0x99, 0x2e, 0x27, 0xa1, 0xc5, 0x3c, 0x04, + 0x28, 0xf1, 0xaa, 0x54, 0x63, 0x4b, 0x82, 0x25, 0x19, 0xab, 0xa0, 0x5d, 0x32, 0x65, 0x56, 0x64, + 0xc7, 0x3b, 0x65, 0x53, 0x33, 0x35, 0x55, 0x52, 0xaa, 0xaa, 0xa6, 0x66, 0xaa, 0xaa, 0xa6, 0x66, + 0x65, 0x55, 0x54, 0xcc, 0xcc, 0xcc, 0xca, 0xaa, 0x99, 0x99, 0x99, 0x99, 0x95, 0x56, 0x66, 0x66, + 0x45, 0xcf, 0xee, 0x5c, 0xf2, 0x0b, 0xa6, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, +}; diff --git a/apps/auracast/src/main.c b/apps/auracast/src/main.c new file mode 100644 index 0000000000..3e7349ec89 --- /dev/null +++ b/apps/auracast/src/main.c @@ -0,0 +1,393 @@ +/* + * 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. + */ + +#include "console/console.h" +#include "config/config.h" + +#include "nimble/ble.h" +#include "host/ble_hs.h" +#include "host/util/util.h" + +#include "services/auracast/ble_svc_auracast.h" + +#include "hal/hal_gpio.h" +#include "bsp/bsp.h" + +#include "audio_data.h" + +#define BROADCAST_SID 1 +#define BROADCAST_MAX_SDU 120 +#define BROADCAST_SDU_INTVL 10000 +#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_48000_HZ + +#define BROADCASTER_INTERRUPT_TASK_PRIO 4 +#define BROADCASTER_INTERRUPT_TASK_STACK_SZ 512 + +static uint8_t id_addr_type; + +static struct ble_audio_base auracast_base; +static struct ble_audio_big_subgroup big_subgroup; + +static os_membuf_t bis_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BROADCASTER_CHAN_NUM), + sizeof(struct ble_audio_bis)) +]; +static struct os_mempool bis_pool; + +static os_membuf_t codec_spec_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIS) * 2, 19) +]; +static struct os_mempool codec_spec_pool; + +static uint16_t bis_handles[MYNEWT_VAL(BROADCASTER_CHAN_NUM)]; +/* The timer callout */ +static struct os_callout audio_broadcast_callout; + +static int audio_data_offset; +static struct os_task auracast_interrupt_task_str; +static struct os_eventq auracast_interrupt_eventq; +static os_stack_t auracast_interrupt_task_stack[BROADCASTER_INTERRUPT_TASK_STACK_SZ]; + +static uint8_t auracast_adv_instance; + +static void +auracast_interrupt_task(void *arg) +{ + while (1) { + os_eventq_run(&auracast_interrupt_eventq); + } +} + +static void +broadcast_stop_ev_cb(struct os_event *ev) +{ + ble_svc_auracast_stop(auracast_adv_instance); + ble_svc_auracast_terminate(auracast_adv_instance); +} + +static struct os_event broadcast_stop_ev = { + .ev_cb = broadcast_stop_ev_cb, +}; + +static void +auracast_gpio_irq(void *arg) +{ + os_eventq_put(&auracast_interrupt_eventq, &broadcast_stop_ev); +} + +static void +audio_broadcast_event_cb(struct os_event *ev) +{ + assert(ev != NULL); + uint32_t ev_start_time = os_cputime_ticks_to_usecs(os_cputime_get32()); + +#if MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 + if (audio_data_offset + BROADCAST_MAX_SDU >= sizeof(audio_data)) { + audio_data_offset = 0; + } + + ble_iso_tx(bis_handles[0], (void *)(audio_data + audio_data_offset), + BROADCAST_MAX_SDU); + ble_iso_tx(bis_handles[1], (void *)(audio_data + audio_data_offset), + BROADCAST_MAX_SDU); +#else + if (audio_data_offset + 2 * BROADCAST_MAX_SDU >= sizeof(audio_data)) { + audio_data_offset = 0; + } + + uint8_t lr_payload[BROADCAST_MAX_SDU * 2]; + memcpy(lr_payload, audio_data + audio_data_offset, BROADCAST_MAX_SDU); + memcpy(lr_payload + BROADCAST_MAX_SDU, audio_data + audio_data_offset, + BROADCAST_MAX_SDU); + ble_iso_tx(bis_handles[0], (void *)(lr_payload), + BROADCAST_MAX_SDU * 2); +#endif + audio_data_offset += BROADCAST_MAX_SDU; + + /** Use cputime to time BROADCAST_SDU_INTVL, as these ticks are more + * accurate than os_time ones. This assures that we do not push + * LC3 data to ISO before interval, which could lead to + * controller running out of buffers. This is only needed because + * we already have coded data in an array - in real world application + * we usually wait for new audio to arrive, and lose time to code it too. + */ + while (os_cputime_ticks_to_usecs(os_cputime_get32()) - ev_start_time < + (BROADCAST_SDU_INTVL)); + + os_callout_reset(&audio_broadcast_callout, 0); +} +static int +broadcast_audio() +{ + os_callout_reset(&audio_broadcast_callout, 0); + + return 0; +} + +static void +auracast_init() +{ + int rc; + + os_callout_init(&audio_broadcast_callout, os_eventq_dflt_get(), + audio_broadcast_event_cb, NULL); + + assert(MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 0); + + rc = os_mempool_init(&bis_pool, MYNEWT_VAL(BROADCASTER_CHAN_NUM), + sizeof(struct ble_audio_bis), bis_mem, + "bis_pool"); + assert(rc == 0); + + rc = os_mempool_init(&codec_spec_pool, + MYNEWT_VAL(BLE_MAX_BIS) * 2, 19, + codec_spec_mem, "codec_spec_pool"); + assert(rc == 0); +} + +static int +base_create() +{ +#if MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 + struct ble_audio_bis *bis_left; + struct ble_audio_bis *bis_right; + uint8_t codec_spec_config_left_chan[] = + BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, + BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS, + BLE_AUDIO_LOCATION_FRONT_LEFT, + BROADCAST_MAX_SDU, ); + uint8_t codec_spec_config_right_chan[] = + BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, + BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS, + BLE_AUDIO_LOCATION_FRONT_RIGHT, + BROADCAST_MAX_SDU, ); +#else + uint16_t chan_loc = BLE_AUDIO_LOCATION_FRONT_LEFT | + BLE_AUDIO_LOCATION_FRONT_RIGHT; + uint8_t codec_spec_config[] = + BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, + BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS, + chan_loc, + BROADCAST_MAX_SDU * 2, ); + + struct ble_audio_bis *bis; +#endif + auracast_base.broadcast_id = 0x42; + auracast_base.presentation_delay = 20000; + + big_subgroup.bis_cnt = MYNEWT_VAL(BROADCASTER_CHAN_NUM); + + /** LC3 */ + big_subgroup.codec_id.format = 0x06; + + big_subgroup.codec_spec_config_len = 0; +#if MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 + bis_left = os_memblock_get(&bis_pool); + if (!bis_left) { + return BLE_HS_ENOMEM; + } + + bis_left->codec_spec_config = os_memblock_get(&codec_spec_pool); + memcpy(bis_left->codec_spec_config, + codec_spec_config_left_chan, + sizeof(codec_spec_config_left_chan)); + bis_left->codec_spec_config_len = sizeof(codec_spec_config_left_chan); + bis_left->idx = 1; + + bis_right = os_memblock_get(&bis_pool); + if (!bis_right) { + return BLE_HS_ENOMEM; + } + + bis_right->codec_spec_config = os_memblock_get(&codec_spec_pool); + memcpy(bis_right->codec_spec_config, + codec_spec_config_right_chan, + sizeof(codec_spec_config_right_chan)); + bis_right->codec_spec_config_len = sizeof(codec_spec_config_right_chan); + bis_right->idx = 2; + + STAILQ_INSERT_HEAD(&big_subgroup.bises, bis_left, next); + STAILQ_INSERT_TAIL(&big_subgroup.bises, bis_right, next); +#else + bis = os_memblock_get(&bis_pool); + if (!bis) { + return BLE_HS_ENOMEM; + } + + bis->codec_spec_config = os_memblock_get(&codec_spec_pool); + memcpy(bis->codec_spec_config, + codec_spec_config, + sizeof(codec_spec_config)); + bis->codec_spec_config_len = sizeof(codec_spec_config); + STAILQ_INSERT_HEAD(&big_subgroup.bises, bis, next); +#endif + + STAILQ_INSERT_HEAD(&auracast_base.subs, &big_subgroup, next); + auracast_base.num_subgroups++; + return 0; +} + +static int +auracast_destroy_fn(struct ble_audio_base *base, void *args) +{ + struct ble_audio_bis *bis; + + STAILQ_FOREACH(bis, &big_subgroup.bises, next) { + os_memblock_put(&codec_spec_pool, bis->codec_spec_config); + os_memblock_put(&bis_pool, bis); + } + + memset(&big_subgroup, 0, sizeof(big_subgroup)); + + return 0; +} + +static int +iso_event(struct ble_iso_event *event, void *arg) +{ + int i; + + switch (event->type) { + case BLE_ISO_EVENT_BIG_CREATE_COMPLETE: + console_printf("BIG created\n"); + if (event->big_created.desc.num_bis > + MYNEWT_VAL(BROADCASTER_CHAN_NUM)) { + return BLE_HS_EINVAL; + } + for (i = 0; i < MYNEWT_VAL(BROADCASTER_CHAN_NUM); i++) { + bis_handles[i] = event->big_created.desc.conn_handle[i]; + } + broadcast_audio(); + return 0; + case BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE: + console_printf("BIG terminated\n"); + return 0; + default: + return BLE_HS_ENOTSUP; + } +} + +static int +auracast_create() +{ + const char *program_info = "NimBLE Auracast Test"; + static struct ble_iso_big_params big_params = { + .sdu_interval = BROADCAST_SDU_INTVL, + .max_sdu = MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 ? + BROADCAST_MAX_SDU : BROADCAST_MAX_SDU * 2, + .max_transport_latency = BROADCAST_SDU_INTVL / 1000, + .rtn = 0, + .phy = BLE_HCI_LE_PHY_2M, + .packing = 0, + .framing = 0, + .encryption = 0, + }; + + struct ble_svc_auracast_create_params create_params = { + .base = &auracast_base, + .big_params = &big_params, + .name = MYNEWT_VAL(BROADCASTER_BROADCAST_NAME), + .program_info = program_info, + .own_addr_type = id_addr_type, + .secondary_phy = BLE_HCI_LE_PHY_2M, + .sid = BROADCAST_SID, + .frame_duration = 10000, + .sampling_frequency = 48000, + .bitrate = 48000, + }; + + return ble_svc_auracast_create(&create_params, + &auracast_adv_instance, + auracast_destroy_fn, + NULL, + NULL); +} + +static int +auracast_start() +{ + return ble_svc_auracast_start(auracast_adv_instance, iso_event, NULL); +} + +static void +on_sync(void) +{ + int rc; + + console_printf("Bluetooth initialized\n"); + + /* Make sure we have proper identity address set (public preferred) */ + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* configure global address */ + rc = ble_hs_id_infer_auto(0, &id_addr_type); + assert(rc == 0); + + auracast_init(); + + rc = base_create(); + assert(rc == 0); + + rc = auracast_create(); + assert(rc == 0); + + rc = auracast_start(); + assert(rc == 0); + + broadcast_audio(); +} + +/* + * main + * + * The main task for the project. This function initializes the packages, + * then starts serving events from default event queue. + * + * @return int NOTE: this function should never return! + */ +int +mynewt_main(int argc, char **argv) +{ + /* Initialize OS */ + sysinit(); + + console_printf("LE Audio Broadcast sample application\n"); + + /* Set sync callback */ + ble_hs_cfg.sync_cb = on_sync; + + os_eventq_init(&auracast_interrupt_eventq); + os_task_init(&auracast_interrupt_task_str, "auracast_interrupt_task", + auracast_interrupt_task, NULL, + BROADCASTER_INTERRUPT_TASK_PRIO, OS_WAIT_FOREVER, + auracast_interrupt_task_stack, + BROADCASTER_INTERRUPT_TASK_STACK_SZ); + + hal_gpio_irq_init(BUTTON_3, auracast_gpio_irq, NULL, + HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_UP); + hal_gpio_irq_enable(BUTTON_3); + + /* As the last thing, process events from default event queue */ + while (1) { + os_eventq_run(os_eventq_dflt_get()); + } + + return 0; +} diff --git a/apps/auracast/syscfg.yml b/apps/auracast/syscfg.yml new file mode 100644 index 0000000000..26dbc8da85 --- /dev/null +++ b/apps/auracast/syscfg.yml @@ -0,0 +1,62 @@ +# 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. + +syscfg.defs: + BROADCASTER_CHAN_NUM: 2 + BROADCASTER_BROADCAST_NAME: '"NimBLE Auracast"' + +syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + + # Disable not used GAP roles (we only do non-connectable + # advertising here) + BLE_ROLE_BROADCASTER: 1 + BLE_ROLE_CENTRAL: 0 + BLE_ROLE_OBSERVER: 0 + BLE_ROLE_PERIPHERAL: 0 + + # Enable Extended Advertising + BLE_EXT_ADV: 1 + + # Enable Periodic Advertising + BLE_PERIODIC_ADV: 1 + + # Max advertising data size + BLE_EXT_ADV_MAX_SIZE: 261 + + # Number of multi-advertising instances. Note that due + # to historical reasonds total number of advertising + # instances is BLE_MULTI_ADV_INSTANCES + 1 as instance + # 0 is always available + BLE_MULTI_ADV_INSTANCES: 1 + + # Controller uses msys pool for storing advertising data and scan responses. + # Since we advertise a lot of data (~6k in total) at the same time we need + # to increase block count. + MSYS_1_BLOCK_COUNT: 32 + + BLE_PHY_2M: 1 + + BLE_VERSION: 54 + BLE_ISO: 1 + BLE_ISO_BROADCASTER: 1 + BLE_MAX_BIG: 1 + BLE_MAX_BIS: 2 + + BLE_PHY_NRF52_HEADERMASK_WORKAROUND: 1 \ No newline at end of file From bbba284d528d0e64568b1944ed257bbccb1733e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 29 Nov 2023 14:05:40 +0100 Subject: [PATCH 0873/1333] porting: update syscfg after ISO Broadcast implementation. --- .../examples/linux/include/syscfg/syscfg.h | 62 +++++++- .../linux/include/sysflash/sysflash.h | 8 +- .../linux_blemesh/include/syscfg/syscfg.h | 62 +++++++- .../linux_blemesh/include/sysflash/sysflash.h | 8 +- .../examples/nuttx/include/syscfg/syscfg.h | 86 +++++++++- .../nuttx/include/sysflash/sysflash.h | 8 +- porting/nimble/include/syscfg/syscfg.h | 62 +++++++- porting/nimble/include/sysflash/sysflash.h | 8 +- porting/npl/riot/include/syscfg/syscfg.h | 147 ++++++++++++++++-- porting/npl/riot/include/sysflash/sysflash.h | 8 +- 10 files changed, 428 insertions(+), 31 deletions(-) diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index 04438c215c..85697d5f9e 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.11.0-dev + * This file was generated by Apache newt version: 1.12.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -454,6 +454,10 @@ #define MYNEWT_VAL_BLE_ISO (0) #endif +#ifndef MYNEWT_VAL_BLE_ISO_BROADCASTER +#define MYNEWT_VAL_BLE_ISO_BROADCASTER (0) +#endif + #ifndef MYNEWT_VAL_BLE_ISO_TEST #define MYNEWT_VAL_BLE_ISO_TEST (0) #endif @@ -474,10 +478,22 @@ #define MYNEWT_VAL_BLE_PERIODIC_ADV (0) #endif +#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS +#define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS (0) +#endif + #ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER #define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER (0) #endif +#ifndef MYNEWT_VAL_BLE_PHY_2M +#define MYNEWT_VAL_BLE_PHY_2M (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PHY_CODED +#define MYNEWT_VAL_BLE_PHY_CODED (0) +#endif + #ifndef MYNEWT_VAL_BLE_POWER_CONTROL #define MYNEWT_VAL_BLE_POWER_CONTROL (0) #endif @@ -711,6 +727,10 @@ #define MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT (0) #endif +#ifndef MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT +#define MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT (0) +#endif + #ifndef MYNEWT_VAL_BLE_HS_LOG_LVL #define MYNEWT_VAL_BLE_HS_LOG_LVL (1) #endif @@ -771,6 +791,14 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif +#ifndef MYNEWT_VAL_BLE_MAX_BIG +#define MYNEWT_VAL_BLE_MAX_BIG (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#endif + +#ifndef MYNEWT_VAL_BLE_MAX_BIS +#define MYNEWT_VAL_BLE_MAX_BIS (4) +#endif + #ifndef MYNEWT_VAL_BLE_MESH #define MYNEWT_VAL_BLE_MESH (0) #endif @@ -783,6 +811,10 @@ #define MYNEWT_VAL_BLE_SM_BONDING (0) #endif +#ifndef MYNEWT_VAL_BLE_SM_CSIS_SIRK +#define MYNEWT_VAL_BLE_SM_CSIS_SIRK (0) +#endif + #ifndef MYNEWT_VAL_BLE_SM_IO_CAP #define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_NO_INPUT_OUTPUT) #endif @@ -1116,6 +1148,24 @@ #define MYNEWT_VAL_BLE_TRANSPORT_HS (1) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT (10) +#endif + +/* Value copied from BLE_TRANSPORT_ISO_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT (10) +#endif + +/* Value copied from BLE_TRANSPORT_ISO_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT (10) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE (300) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/linux (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 #define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) @@ -1138,6 +1188,9 @@ #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__socket #define MYNEWT_VAL_BLE_TRANSPORT_LL__socket (1) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__uart_ll +#define MYNEWT_VAL_BLE_TRANSPORT_LL__uart_ll (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif @@ -1265,4 +1318,11 @@ #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_linux 1 +/*** Included APIs */ +#define MYNEWT_API_TRNG_HW_IMPL 1 +#define MYNEWT_API_ble_transport 1 +#define MYNEWT_API_console 1 +#define MYNEWT_API_log 1 +#define MYNEWT_API_stats 1 + #endif diff --git a/porting/examples/linux/include/sysflash/sysflash.h b/porting/examples/linux/include/sysflash/sysflash.h index 8d358ac99a..2f4d843f4c 100644 --- a/porting/examples/linux/include/sysflash/sysflash.h +++ b/porting/examples/linux/include/sysflash/sysflash.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.11.0-dev + * This file was generated by Apache newt version: 1.12.0-dev */ #ifndef H_MYNEWT_SYSFLASH_ @@ -7,12 +7,16 @@ #include "flash_map/flash_map.h" +#define FLASH_AREA_COUNT 6 + /** * This flash map definition is used for two purposes: * 1. To locate the meta area, which contains the true flash map definition. * 2. As a fallback in case the meta area cannot be read from flash. */ -extern const struct flash_area sysflash_map_dflt[6]; +extern const struct flash_area sysflash_map_dflt[FLASH_AREA_COUNT]; + +/* Flash map was defined in @apache-mynewt-core/hw/bsp/native */ #define FLASH_AREA_BOOTLOADER 0 #define FLASH_AREA_BOOTLOADER_DEVICE 0 diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index c9fd541127..750334d954 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.11.0-dev + * This file was generated by Apache newt version: 1.12.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -455,6 +455,10 @@ #define MYNEWT_VAL_BLE_ISO (0) #endif +#ifndef MYNEWT_VAL_BLE_ISO_BROADCASTER +#define MYNEWT_VAL_BLE_ISO_BROADCASTER (0) +#endif + #ifndef MYNEWT_VAL_BLE_ISO_TEST #define MYNEWT_VAL_BLE_ISO_TEST (0) #endif @@ -475,10 +479,22 @@ #define MYNEWT_VAL_BLE_PERIODIC_ADV (0) #endif +#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS +#define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS (0) +#endif + #ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER #define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER (0) #endif +#ifndef MYNEWT_VAL_BLE_PHY_2M +#define MYNEWT_VAL_BLE_PHY_2M (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PHY_CODED +#define MYNEWT_VAL_BLE_PHY_CODED (0) +#endif + #ifndef MYNEWT_VAL_BLE_POWER_CONTROL #define MYNEWT_VAL_BLE_POWER_CONTROL (0) #endif @@ -712,6 +728,10 @@ #define MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT (0) #endif +#ifndef MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT +#define MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT (0) +#endif + #ifndef MYNEWT_VAL_BLE_HS_LOG_LVL #define MYNEWT_VAL_BLE_HS_LOG_LVL (1) #endif @@ -772,6 +792,14 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif +#ifndef MYNEWT_VAL_BLE_MAX_BIG +#define MYNEWT_VAL_BLE_MAX_BIG (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#endif + +#ifndef MYNEWT_VAL_BLE_MAX_BIS +#define MYNEWT_VAL_BLE_MAX_BIS (4) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host) */ #ifndef MYNEWT_VAL_BLE_MESH #define MYNEWT_VAL_BLE_MESH (1) @@ -785,6 +813,10 @@ #define MYNEWT_VAL_BLE_SM_BONDING (0) #endif +#ifndef MYNEWT_VAL_BLE_SM_CSIS_SIRK +#define MYNEWT_VAL_BLE_SM_CSIS_SIRK (0) +#endif + #ifndef MYNEWT_VAL_BLE_SM_IO_CAP #define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_NO_INPUT_OUTPUT) #endif @@ -1691,6 +1723,24 @@ #define MYNEWT_VAL_BLE_TRANSPORT_HS (1) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT (10) +#endif + +/* Value copied from BLE_TRANSPORT_ISO_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT (10) +#endif + +/* Value copied from BLE_TRANSPORT_ISO_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT (10) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE (300) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 #define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) @@ -1713,6 +1763,9 @@ #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__socket #define MYNEWT_VAL_BLE_TRANSPORT_LL__socket (1) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__uart_ll +#define MYNEWT_VAL_BLE_TRANSPORT_LL__uart_ll (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif @@ -1841,4 +1894,11 @@ #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_linux_blemesh 1 +/*** Included APIs */ +#define MYNEWT_API_TRNG_HW_IMPL 1 +#define MYNEWT_API_ble_transport 1 +#define MYNEWT_API_console 1 +#define MYNEWT_API_log 1 +#define MYNEWT_API_stats 1 + #endif diff --git a/porting/examples/linux_blemesh/include/sysflash/sysflash.h b/porting/examples/linux_blemesh/include/sysflash/sysflash.h index 8d358ac99a..2f4d843f4c 100644 --- a/porting/examples/linux_blemesh/include/sysflash/sysflash.h +++ b/porting/examples/linux_blemesh/include/sysflash/sysflash.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.11.0-dev + * This file was generated by Apache newt version: 1.12.0-dev */ #ifndef H_MYNEWT_SYSFLASH_ @@ -7,12 +7,16 @@ #include "flash_map/flash_map.h" +#define FLASH_AREA_COUNT 6 + /** * This flash map definition is used for two purposes: * 1. To locate the meta area, which contains the true flash map definition. * 2. As a fallback in case the meta area cannot be read from flash. */ -extern const struct flash_area sysflash_map_dflt[6]; +extern const struct flash_area sysflash_map_dflt[FLASH_AREA_COUNT]; + +/* Flash map was defined in @apache-mynewt-core/hw/bsp/native */ #define FLASH_AREA_BOOTLOADER 0 #define FLASH_AREA_BOOTLOADER_DEVICE 0 diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index 6035f7966e..0f599f7be4 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.11.0-dev + * This file was generated by Apache newt version: 1.12.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -454,6 +454,10 @@ #define MYNEWT_VAL_BLE_ISO (0) #endif +#ifndef MYNEWT_VAL_BLE_ISO_BROADCASTER +#define MYNEWT_VAL_BLE_ISO_BROADCASTER (0) +#endif + #ifndef MYNEWT_VAL_BLE_ISO_TEST #define MYNEWT_VAL_BLE_ISO_TEST (0) #endif @@ -474,10 +478,22 @@ #define MYNEWT_VAL_BLE_PERIODIC_ADV (0) #endif +#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS +#define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS (0) +#endif + #ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER #define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER (0) #endif +#ifndef MYNEWT_VAL_BLE_PHY_2M +#define MYNEWT_VAL_BLE_PHY_2M (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PHY_CODED +#define MYNEWT_VAL_BLE_PHY_CODED (0) +#endif + #ifndef MYNEWT_VAL_BLE_POWER_CONTROL #define MYNEWT_VAL_BLE_POWER_CONTROL (0) #endif @@ -531,6 +547,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI +#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI (MYNEWT_VAL_BLE_ATT_SVR_NOTIFY && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE #define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1) #endif @@ -571,6 +591,22 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM +#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL +#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD +#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_MTU +#define MYNEWT_VAL_BLE_EATT_MTU (128) +#endif + #ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE #define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1) #endif @@ -627,6 +663,10 @@ #define MYNEWT_VAL_BLE_GATT_READ_MULT (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif +#ifndef MYNEWT_VAL_BLE_GATT_READ_MULT_VAR +#define MYNEWT_VAL_BLE_GATT_READ_MULT_VAR (MYNEWT_VAL_BLE_ROLE_CENTRAL && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ_UUID #define MYNEWT_VAL_BLE_GATT_READ_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif @@ -687,6 +727,10 @@ #define MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT (0) #endif +#ifndef MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT +#define MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT (0) +#endif + #ifndef MYNEWT_VAL_BLE_HS_LOG_LVL #define MYNEWT_VAL_BLE_HS_LOG_LVL (1) #endif @@ -747,6 +791,14 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif +#ifndef MYNEWT_VAL_BLE_MAX_BIG +#define MYNEWT_VAL_BLE_MAX_BIG (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#endif + +#ifndef MYNEWT_VAL_BLE_MAX_BIS +#define MYNEWT_VAL_BLE_MAX_BIS (4) +#endif + #ifndef MYNEWT_VAL_BLE_MESH #define MYNEWT_VAL_BLE_MESH (0) #endif @@ -759,6 +811,10 @@ #define MYNEWT_VAL_BLE_SM_BONDING (0) #endif +#ifndef MYNEWT_VAL_BLE_SM_CSIS_SIRK +#define MYNEWT_VAL_BLE_SM_CSIS_SIRK (0) +#endif + #ifndef MYNEWT_VAL_BLE_SM_IO_CAP #define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_NO_INPUT_OUTPUT) #endif @@ -1094,6 +1150,24 @@ #define MYNEWT_VAL_BLE_TRANSPORT_HS (1) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT (10) +#endif + +/* Value copied from BLE_TRANSPORT_ISO_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT (10) +#endif + +/* Value copied from BLE_TRANSPORT_ISO_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT (10) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE (300) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 #define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) @@ -1116,6 +1190,9 @@ #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__socket #define MYNEWT_VAL_BLE_TRANSPORT_LL__socket (1) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__uart_ll +#define MYNEWT_VAL_BLE_TRANSPORT_LL__uart_ll (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif @@ -1243,4 +1320,11 @@ #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_nuttx 1 +/*** Included APIs */ +#define MYNEWT_API_TRNG_HW_IMPL 1 +#define MYNEWT_API_ble_transport 1 +#define MYNEWT_API_console 1 +#define MYNEWT_API_log 1 +#define MYNEWT_API_stats 1 + #endif diff --git a/porting/examples/nuttx/include/sysflash/sysflash.h b/porting/examples/nuttx/include/sysflash/sysflash.h index 8d358ac99a..2f4d843f4c 100644 --- a/porting/examples/nuttx/include/sysflash/sysflash.h +++ b/porting/examples/nuttx/include/sysflash/sysflash.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.11.0-dev + * This file was generated by Apache newt version: 1.12.0-dev */ #ifndef H_MYNEWT_SYSFLASH_ @@ -7,12 +7,16 @@ #include "flash_map/flash_map.h" +#define FLASH_AREA_COUNT 6 + /** * This flash map definition is used for two purposes: * 1. To locate the meta area, which contains the true flash map definition. * 2. As a fallback in case the meta area cannot be read from flash. */ -extern const struct flash_area sysflash_map_dflt[6]; +extern const struct flash_area sysflash_map_dflt[FLASH_AREA_COUNT]; + +/* Flash map was defined in @apache-mynewt-core/hw/bsp/native */ #define FLASH_AREA_BOOTLOADER 0 #define FLASH_AREA_BOOTLOADER_DEVICE 0 diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index dcea02fd60..ed59c0eada 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.11.0-dev + * This file was generated by Apache newt version: 1.12.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -453,6 +453,10 @@ #define MYNEWT_VAL_BLE_ISO (0) #endif +#ifndef MYNEWT_VAL_BLE_ISO_BROADCASTER +#define MYNEWT_VAL_BLE_ISO_BROADCASTER (0) +#endif + #ifndef MYNEWT_VAL_BLE_ISO_TEST #define MYNEWT_VAL_BLE_ISO_TEST (0) #endif @@ -473,10 +477,22 @@ #define MYNEWT_VAL_BLE_PERIODIC_ADV (0) #endif +#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS +#define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS (0) +#endif + #ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER #define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER (0) #endif +#ifndef MYNEWT_VAL_BLE_PHY_2M +#define MYNEWT_VAL_BLE_PHY_2M (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PHY_CODED +#define MYNEWT_VAL_BLE_PHY_CODED (0) +#endif + #ifndef MYNEWT_VAL_BLE_POWER_CONTROL #define MYNEWT_VAL_BLE_POWER_CONTROL (0) #endif @@ -710,6 +726,10 @@ #define MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT (0) #endif +#ifndef MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT +#define MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT (0) +#endif + #ifndef MYNEWT_VAL_BLE_HS_LOG_LVL #define MYNEWT_VAL_BLE_HS_LOG_LVL (1) #endif @@ -770,6 +790,14 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif +#ifndef MYNEWT_VAL_BLE_MAX_BIG +#define MYNEWT_VAL_BLE_MAX_BIG (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#endif + +#ifndef MYNEWT_VAL_BLE_MAX_BIS +#define MYNEWT_VAL_BLE_MAX_BIS (4) +#endif + #ifndef MYNEWT_VAL_BLE_MESH #define MYNEWT_VAL_BLE_MESH (0) #endif @@ -782,6 +810,10 @@ #define MYNEWT_VAL_BLE_SM_BONDING (0) #endif +#ifndef MYNEWT_VAL_BLE_SM_CSIS_SIRK +#define MYNEWT_VAL_BLE_SM_CSIS_SIRK (0) +#endif + #ifndef MYNEWT_VAL_BLE_SM_IO_CAP #define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_NO_INPUT_OUTPUT) #endif @@ -1115,6 +1147,24 @@ #define MYNEWT_VAL_BLE_TRANSPORT_HS (1) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT (10) +#endif + +/* Value copied from BLE_TRANSPORT_ISO_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT (10) +#endif + +/* Value copied from BLE_TRANSPORT_ISO_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT (10) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE (300) +#endif + /* Overridden by @apache-mynewt-nimble/porting/targets/porting_default (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 #define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) @@ -1137,6 +1187,9 @@ #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__socket #define MYNEWT_VAL_BLE_TRANSPORT_LL__socket (1) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__uart_ll +#define MYNEWT_VAL_BLE_TRANSPORT_LL__uart_ll (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif @@ -1262,4 +1315,11 @@ #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_porting_default 1 +/*** Included APIs */ +#define MYNEWT_API_TRNG_HW_IMPL 1 +#define MYNEWT_API_ble_transport 1 +#define MYNEWT_API_console 1 +#define MYNEWT_API_log 1 +#define MYNEWT_API_stats 1 + #endif diff --git a/porting/nimble/include/sysflash/sysflash.h b/porting/nimble/include/sysflash/sysflash.h index 8d358ac99a..2f4d843f4c 100644 --- a/porting/nimble/include/sysflash/sysflash.h +++ b/porting/nimble/include/sysflash/sysflash.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.11.0-dev + * This file was generated by Apache newt version: 1.12.0-dev */ #ifndef H_MYNEWT_SYSFLASH_ @@ -7,12 +7,16 @@ #include "flash_map/flash_map.h" +#define FLASH_AREA_COUNT 6 + /** * This flash map definition is used for two purposes: * 1. To locate the meta area, which contains the true flash map definition. * 2. As a fallback in case the meta area cannot be read from flash. */ -extern const struct flash_area sysflash_map_dflt[6]; +extern const struct flash_area sysflash_map_dflt[FLASH_AREA_COUNT]; + +/* Flash map was defined in @apache-mynewt-core/hw/bsp/native */ #define FLASH_AREA_BOOTLOADER 0 #define FLASH_AREA_BOOTLOADER_DEVICE 0 diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index b381d3289c..4b8cde70e6 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.11.0-dev + * This file was generated by Apache newt version: 1.12.0-dev */ #ifndef H_MYNEWT_SYSCFG_ @@ -117,6 +117,20 @@ #undef MYNEWT_VAL_I2C_1_PIN_SDA +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ +#ifndef MYNEWT_VAL_MCU_ACCESS_PORT_PROTECTION__default +#define MYNEWT_VAL_MCU_ACCESS_PORT_PROTECTION__default (0) +#endif +#ifndef MYNEWT_VAL_MCU_ACCESS_PORT_PROTECTION__disable +#define MYNEWT_VAL_MCU_ACCESS_PORT_PROTECTION__disable (1) +#endif +#ifndef MYNEWT_VAL_MCU_ACCESS_PORT_PROTECTION__enable +#define MYNEWT_VAL_MCU_ACCESS_PORT_PROTECTION__enable (0) +#endif +#ifndef MYNEWT_VAL_MCU_ACCESS_PORT_PROTECTION +#define MYNEWT_VAL_MCU_ACCESS_PORT_PROTECTION (1) +#endif + #ifndef MYNEWT_VAL_MCU_BUS_DRIVER_I2C_USE_TWIM #define MYNEWT_VAL_MCU_BUS_DRIVER_I2C_USE_TWIM (0) #endif @@ -303,17 +317,17 @@ /* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_SPI_0_MASTER_PIN_MISO -#define MYNEWT_VAL_SPI_0_MASTER_PIN_MISO (47) +#define MYNEWT_VAL_SPI_0_MASTER_PIN_MISO (46) #endif /* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_SPI_0_MASTER_PIN_MOSI -#define MYNEWT_VAL_SPI_0_MASTER_PIN_MOSI (46) +#define MYNEWT_VAL_SPI_0_MASTER_PIN_MOSI (45) #endif /* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_SPI_0_MASTER_PIN_SCK -#define MYNEWT_VAL_SPI_0_MASTER_PIN_SCK (45) +#define MYNEWT_VAL_SPI_0_MASTER_PIN_SCK (47) #endif #ifndef MYNEWT_VAL_SPI_0_SLAVE @@ -322,17 +336,17 @@ /* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_SPI_0_SLAVE_PIN_MISO -#define MYNEWT_VAL_SPI_0_SLAVE_PIN_MISO (47) +#define MYNEWT_VAL_SPI_0_SLAVE_PIN_MISO (46) #endif /* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_SPI_0_SLAVE_PIN_MOSI -#define MYNEWT_VAL_SPI_0_SLAVE_PIN_MOSI (46) +#define MYNEWT_VAL_SPI_0_SLAVE_PIN_MOSI (45) #endif /* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_SPI_0_SLAVE_PIN_SCK -#define MYNEWT_VAL_SPI_0_SLAVE_PIN_SCK (45) +#define MYNEWT_VAL_SPI_0_SLAVE_PIN_SCK (47) #endif /* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ @@ -670,6 +684,17 @@ #define MYNEWT_VAL_WATCHDOG_INTERVAL (30000) #endif +/*** @apache-mynewt-core/libc */ +#ifndef MYNEWT_VAL_LIBC__baselibc +#define MYNEWT_VAL_LIBC__baselibc (1) +#endif +#ifndef MYNEWT_VAL_LIBC__nano +#define MYNEWT_VAL_LIBC__nano (0) +#endif +#ifndef MYNEWT_VAL_LIBC +#define MYNEWT_VAL_LIBC (1) +#endif + /*** @apache-mynewt-core/libc/baselibc */ #ifndef MYNEWT_VAL_BASELIBC_ASSERT_FILE_LINE #define MYNEWT_VAL_BASELIBC_ASSERT_FILE_LINE (0) @@ -830,6 +855,10 @@ #define MYNEWT_VAL_BLE_ISO (0) #endif +#ifndef MYNEWT_VAL_BLE_ISO_BROADCASTER +#define MYNEWT_VAL_BLE_ISO_BROADCASTER (0) +#endif + #ifndef MYNEWT_VAL_BLE_ISO_TEST #define MYNEWT_VAL_BLE_ISO_TEST (0) #endif @@ -851,10 +880,22 @@ #define MYNEWT_VAL_BLE_PERIODIC_ADV (0) #endif +#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS +#define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS (0) +#endif + #ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER #define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER (0) #endif +#ifndef MYNEWT_VAL_BLE_PHY_2M +#define MYNEWT_VAL_BLE_PHY_2M (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PHY_CODED +#define MYNEWT_VAL_BLE_PHY_CODED (0) +#endif + #ifndef MYNEWT_VAL_BLE_POWER_CONTROL #define MYNEWT_VAL_BLE_POWER_CONTROL (0) #endif @@ -964,10 +1005,12 @@ #define MYNEWT_VAL_BLE_LL_CFG_FEAT_DATA_LEN_EXT (0) #endif +/* Value copied from BLE_PHY_2M */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_2M_PHY #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_2M_PHY (0) #endif +/* Value copied from BLE_PHY_CODED */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CODED_PHY #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CODED_PHY (0) #endif @@ -995,16 +1038,6 @@ #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV (0) #endif -/* Value copied from BLE_ISO */ -#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_ISO -#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_ISO (0) -#endif - -/* Value copied from BLE_ISO_TEST */ -#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_ISO_TEST -#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_ISO_TEST (0) -#endif - /* Value copied from BLE_PERIODIC_ADV */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV (0) @@ -1154,6 +1187,28 @@ #define MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_ON_ASSERT (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_HCI_VS_LOCAL_IRK +#define MYNEWT_VAL_BLE_LL_HCI_VS_LOCAL_IRK (0) +#endif + +/* Value copied from BLE_ISO */ +#ifndef MYNEWT_VAL_BLE_LL_ISO +#define MYNEWT_VAL_BLE_LL_ISO (0) +#endif + +/* Value copied from BLE_ISO_BROADCASTER */ +#ifndef MYNEWT_VAL_BLE_LL_ISO_BROADCASTER +#define MYNEWT_VAL_BLE_LL_ISO_BROADCASTER (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_ISO_HCI_DISCARD_THRESHOLD +#define MYNEWT_VAL_BLE_LL_ISO_HCI_DISCARD_THRESHOLD (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS +#define MYNEWT_VAL_BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS (0) +#endif + #ifndef MYNEWT_VAL_BLE_LL_LNA #define MYNEWT_VAL_BLE_LL_LNA (0) #endif @@ -1211,6 +1266,11 @@ #define MYNEWT_VAL_BLE_LL_PA_TURN_ON_US (1) #endif +/* Value copied from BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS */ +#ifndef MYNEWT_VAL_BLE_LL_PERIODIC_ADV_SYNC_BIGINFO_REPORTS +#define MYNEWT_VAL_BLE_LL_PERIODIC_ADV_SYNC_BIGINFO_REPORTS (0) +#endif + #ifndef MYNEWT_VAL_BLE_LL_PRIO #define MYNEWT_VAL_BLE_LL_PRIO (0) #endif @@ -1353,10 +1413,18 @@ #define MYNEWT_VAL_BLE_PHY_DBG_TIME_WFR_PIN (-1) #endif +#ifndef MYNEWT_VAL_BLE_PHY_EXTENDED_TIFS +#define MYNEWT_VAL_BLE_PHY_EXTENDED_TIFS (2) +#endif + #ifndef MYNEWT_VAL_BLE_PHY_NRF52_HEADERMASK_WORKAROUND #define MYNEWT_VAL_BLE_PHY_NRF52_HEADERMASK_WORKAROUND (0) #endif +#ifndef MYNEWT_VAL_BLE_PHY_NRF5340_VDDH +#define MYNEWT_VAL_BLE_PHY_NRF5340_VDDH (0) +#endif + #ifndef MYNEWT_VAL_BLE_PHY_SYSVIEW #define MYNEWT_VAL_BLE_PHY_SYSVIEW (0) #endif @@ -1574,6 +1642,10 @@ #define MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT (0) #endif +#ifndef MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT +#define MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT (0) +#endif + #ifndef MYNEWT_VAL_BLE_HS_LOG_LVL #define MYNEWT_VAL_BLE_HS_LOG_LVL (1) #endif @@ -1634,6 +1706,14 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif +#ifndef MYNEWT_VAL_BLE_MAX_BIG +#define MYNEWT_VAL_BLE_MAX_BIG (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#endif + +#ifndef MYNEWT_VAL_BLE_MAX_BIS +#define MYNEWT_VAL_BLE_MAX_BIS (4) +#endif + #ifndef MYNEWT_VAL_BLE_MESH #define MYNEWT_VAL_BLE_MESH (0) #endif @@ -1646,6 +1726,10 @@ #define MYNEWT_VAL_BLE_SM_BONDING (0) #endif +#ifndef MYNEWT_VAL_BLE_SM_CSIS_SIRK +#define MYNEWT_VAL_BLE_SM_CSIS_SIRK (0) +#endif + #ifndef MYNEWT_VAL_BLE_SM_IO_CAP #define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_NO_INPUT_OUTPUT) #endif @@ -1866,6 +1950,24 @@ #define MYNEWT_VAL_BLE_TRANSPORT_HS (1) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT (10) +#endif + +/* Value copied from BLE_TRANSPORT_ISO_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT (10) +#endif + +/* Value copied from BLE_TRANSPORT_ISO_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT (10) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE (300) +#endif + #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 #define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) #endif @@ -1887,6 +1989,9 @@ #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__socket #define MYNEWT_VAL_BLE_TRANSPORT_LL__socket (0) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__uart_ll +#define MYNEWT_VAL_BLE_TRANSPORT_LL__uart_ll (0) +#endif #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif @@ -1943,6 +2048,7 @@ #define MYNEWT_PKG_apache_mynewt_core__hw_mcu_nordic 1 #define MYNEWT_PKG_apache_mynewt_core__hw_mcu_nordic_nrf52xxx 1 #define MYNEWT_PKG_apache_mynewt_core__kernel_os 1 +#define MYNEWT_PKG_apache_mynewt_core__libc 1 #define MYNEWT_PKG_apache_mynewt_core__libc_baselibc 1 #define MYNEWT_PKG_apache_mynewt_core__sys_console_stub 1 #define MYNEWT_PKG_apache_mynewt_core__sys_defs 1 @@ -1967,4 +2073,11 @@ #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_riot 1 +/*** Included APIs */ +#define MYNEWT_API_ble_driver 1 +#define MYNEWT_API_ble_transport 1 +#define MYNEWT_API_console 1 +#define MYNEWT_API_log 1 +#define MYNEWT_API_stats 1 + #endif diff --git a/porting/npl/riot/include/sysflash/sysflash.h b/porting/npl/riot/include/sysflash/sysflash.h index 05324aaabc..0194dc49a8 100644 --- a/porting/npl/riot/include/sysflash/sysflash.h +++ b/porting/npl/riot/include/sysflash/sysflash.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.11.0-dev + * This file was generated by Apache newt version: 1.12.0-dev */ #ifndef H_MYNEWT_SYSFLASH_ @@ -7,12 +7,16 @@ #include "flash_map/flash_map.h" +#define FLASH_AREA_COUNT 6 + /** * This flash map definition is used for two purposes: * 1. To locate the meta area, which contains the true flash map definition. * 2. As a fallback in case the meta area cannot be read from flash. */ -extern const struct flash_area sysflash_map_dflt[6]; +extern const struct flash_area sysflash_map_dflt[FLASH_AREA_COUNT]; + +/* Flash map was defined in @apache-mynewt-core/hw/bsp/nordic_pca10056 */ #define FLASH_AREA_BOOTLOADER 0 #define FLASH_AREA_BOOTLOADER_DEVICE 0 From a2c79374d0e93d026d91c3f2ba879edab64802bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 22 Nov 2023 14:03:13 +0100 Subject: [PATCH 0874/1333] ext: add LC3 codec library Adds LC3 codec implementation from https://github.com/google/liblc3 --- ext/liblc3/pkg.yml | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 ext/liblc3/pkg.yml diff --git a/ext/liblc3/pkg.yml b/ext/liblc3/pkg.yml new file mode 100644 index 0000000000..9a19fd3cf5 --- /dev/null +++ b/ext/liblc3/pkg.yml @@ -0,0 +1,50 @@ +# +# 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: ext/liblc3 +pkg.description: LC3 Codec library +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - lc3 + +pkg.type: sdk + +pkg.cflags: -O3 -std=c11 -ffast-math -Wno-array-bounds +pkg.lflags: -lm + +pkg.ign_dirs: + - "@liblc3/test" + - "@liblc3/zephyr" + - "@liblc3/fuzz" + - "@liblc3/tables" + - "@liblc3/tools" + +pkg.src_dirs: + - "@liblc3/src" + +pkg.include_dirs: + - "@liblc3/include" + +repository.liblc3: + type: github + vers: v1.0.4-commit + branch: main + user: google + repo: liblc3 From 44e0ccc7c68fd79e2bd481b90a8fd70584592e79 Mon Sep 17 00:00:00 2001 From: Roshan Date: Tue, 12 Dec 2023 14:37:08 +0530 Subject: [PATCH 0875/1333] nimble/gatts: Modify client supported features READ --- nimble/host/include/host/ble_gatt.h | 19 +++++++++++++ nimble/host/services/gatt/src/ble_svc_gatt.c | 10 +++++-- nimble/host/src/ble_gatts.c | 29 ++++++++++++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index cd17cc26c0..0f811e7330 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -1096,6 +1096,25 @@ int ble_gatts_start(void); int ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, struct os_mbuf *om); +/** + * Gets Client Supported Features for specified connection. + * + * @param conn_handle Connection handle identifying connection for + * which Client Supported Features should be saved + * @param out_supported_feat Client supported features to be returned. + * + * @return 0 on success; + * BLE_HS_ENOTCONN if no matching connection + * was found + * BLE_HS_EINVAL if supplied buffer is empty or + * if any Client Supported Feature was + * attempted to be disabled. + * A BLE host core return code on unexpected + * error. + * + */ +int ble_gatts_peer_cl_sup_feat_get(uint16_t conn_handle, uint8_t *out_supported_feat, uint8_t len); + #ifdef __cplusplus } #endif diff --git a/nimble/host/services/gatt/src/ble_svc_gatt.c b/nimble/host/services/gatt/src/ble_svc_gatt.c index 5dcc4fa29c..d3262e17bc 100644 --- a/nimble/host/services/gatt/src/ble_svc_gatt.c +++ b/nimble/host/services/gatt/src/ble_svc_gatt.c @@ -100,10 +100,14 @@ static int ble_svc_gatt_cl_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { + uint8_t supported_feat; + int rc; + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { - uint8_t supported_feat = - (MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0) << 1 | - (MYNEWT_VAL(BLE_ATT_SVR_NOTIFY_MULTI) == 1) << 2; + rc = ble_gatts_peer_cl_sup_feat_get(conn_handle, &supported_feat, 1); + if (rc != 0) { + return BLE_ATT_ERR_UNLIKELY; + } os_mbuf_append(ctxt->om, &supported_feat, sizeof(supported_feat)); return 0; } diff --git a/nimble/host/src/ble_gatts.c b/nimble/host/src/ble_gatts.c index ce5f1709e0..2f95b70e35 100644 --- a/nimble/host/src/ble_gatts.c +++ b/nimble/host/src/ble_gatts.c @@ -1580,6 +1580,35 @@ ble_gatts_chr_updated(uint16_t chr_val_handle) } } +int +ble_gatts_peer_cl_sup_feat_get(uint16_t conn_handle, uint8_t *out_supported_feat, uint8_t len) +{ + struct ble_hs_conn *conn; + int rc = 0; + + if (out_supported_feat == NULL) { + return BLE_HS_EINVAL; + } + + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + if (conn == NULL) { + rc = BLE_HS_ENOTCONN; + goto done; + } + + if (BLE_GATT_CHR_CLI_SUP_FEAT_SZ < len) { + len = BLE_GATT_CHR_CLI_SUP_FEAT_SZ; + } + + memcpy(out_supported_feat, conn->bhc_gatt_svr.peer_cl_sup_feat, + sizeof(uint8_t) * len); + +done: + ble_hs_unlock(); + return rc; +} + int ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, struct os_mbuf *om) { From 64067f5168bd4de097b7830a078862a5df95d9a5 Mon Sep 17 00:00:00 2001 From: Roshan Date: Tue, 12 Dec 2023 09:20:41 +0530 Subject: [PATCH 0876/1333] nimble/gatts: Add check for RFU bits --- nimble/host/include/host/ble_att.h | 3 +++ nimble/host/src/ble_gatt_priv.h | 5 +++++ nimble/host/src/ble_gatts.c | 13 +++++++++---- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/nimble/host/include/host/ble_att.h b/nimble/host/include/host/ble_att.h index 5a3a2a1ff0..bfd7adf10f 100644 --- a/nimble/host/include/host/ble_att.h +++ b/nimble/host/include/host/ble_att.h @@ -110,6 +110,9 @@ struct os_mbuf; /**Insufficient Resources to complete the request. */ #define BLE_ATT_ERR_INSUFFICIENT_RES 0x11 +/**Requested value is not allowed. */ +#define BLE_ATT_ERR_VALUE_NOT_ALLOWED 0x13 + /** @} */ /** diff --git a/nimble/host/src/ble_gatt_priv.h b/nimble/host/src/ble_gatt_priv.h index ba0b806735..eb778293cd 100644 --- a/nimble/host/src/ble_gatt_priv.h +++ b/nimble/host/src/ble_gatt_priv.h @@ -89,6 +89,11 @@ extern STATS_SECT_DECL(ble_gatts_stats) ble_gatts_stats; #define BLE_GATT_CHR_DECL_SZ_16 5 #define BLE_GATT_CHR_DECL_SZ_128 19 #define BLE_GATT_CHR_CLI_SUP_FEAT_SZ 1 +/** + * For now only 3 bits in first octet are defined + * + */ +#define BLE_GATT_CHR_CLI_SUP_FEAT_MASK 7 typedef uint8_t ble_gatts_conn_flags; diff --git a/nimble/host/src/ble_gatts.c b/nimble/host/src/ble_gatts.c index 2f95b70e35..2c18cc4a68 100644 --- a/nimble/host/src/ble_gatts.c +++ b/nimble/host/src/ble_gatts.c @@ -1620,20 +1620,20 @@ ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, struct os_mbuf *om) BLE_HS_LOG(DEBUG, ""); if (!om) { - return BLE_HS_EINVAL; + return BLE_ATT_ERR_INSUFFICIENT_RES; } ble_hs_lock(); conn = ble_hs_conn_find(conn_handle); if (conn == NULL) { - rc = BLE_HS_ENOTCONN; + rc = BLE_ATT_ERR_UNLIKELY; goto done; } if (om->om_len == 0) { /* Nothing to do */ goto done; } else if (os_mbuf_len(om) > BLE_ATT_ATTR_MAX_LEN) { - rc = BLE_HS_ENOMEM; + rc = BLE_ATT_ERR_INSUFFICIENT_RES; goto done; } @@ -1647,10 +1647,15 @@ ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, struct os_mbuf *om) */ if (conn->bhc_gatt_svr.peer_cl_sup_feat[feat_idx] > om->om_data[i]) { - rc = BLE_HS_EINVAL; + rc = BLE_ATT_ERR_VALUE_NOT_ALLOWED; goto done; } + /* All RFU bits should be unset */ + if (feat_idx == 0) { + om->om_data[i] &= BLE_GATT_CHR_CLI_SUP_FEAT_MASK; + } + conn->bhc_gatt_svr.peer_cl_sup_feat[feat_idx] |= om->om_data[i]; feat_idx++; From e6882b5b6deb472e9a11f8ba5cda0e6029f676ba Mon Sep 17 00:00:00 2001 From: Hang Fan Date: Sat, 30 Dec 2023 23:30:51 +0800 Subject: [PATCH 0877/1333] porting/examples: fix ble_hci_sock_init assertion Since HCI socket was initialized by `ble_transport_ll_init` in LL side, we should remove `ble_hci_sock_init` from example apps. Signed-off-by: Hang Fan --- porting/examples/linux/main.c | 2 -- porting/examples/linux_blemesh/main.c | 1 - porting/examples/nuttx/main.c | 4 ---- 3 files changed, 7 deletions(-) diff --git a/porting/examples/linux/main.c b/porting/examples/linux/main.c index 25323b9a0f..e81e60872b 100644 --- a/porting/examples/linux/main.c +++ b/porting/examples/linux/main.c @@ -37,7 +37,6 @@ static struct ble_npl_task s_task_hci; void nimble_host_task(void *param); void ble_hci_sock_ack_handler(void *param); -void ble_hci_sock_init(void); void ble_hci_sock_set_device(int dev); void ble_store_ram_init(void); @@ -67,7 +66,6 @@ int main(int argc, char *argv[]) } nimble_port_init(); - ble_hci_sock_init(); /* This example provides GATT Alert service */ ble_svc_gap_init(); diff --git a/porting/examples/linux_blemesh/main.c b/porting/examples/linux_blemesh/main.c index 5a9befdc10..678062f207 100644 --- a/porting/examples/linux_blemesh/main.c +++ b/porting/examples/linux_blemesh/main.c @@ -80,7 +80,6 @@ int main(int argc, char *argv[]) } nimble_port_init(); - ble_hci_sock_init(); ble_svc_gap_init(); ble_svc_gatt_init(); diff --git a/porting/examples/nuttx/main.c b/porting/examples/nuttx/main.c index 7e289be77d..bd731105df 100644 --- a/porting/examples/nuttx/main.c +++ b/porting/examples/nuttx/main.c @@ -43,7 +43,6 @@ static struct ble_npl_task s_task_hci; void nimble_host_task(void *param); void ble_hci_sock_ack_handler(void *param); -void ble_hci_sock_init(void); void ble_hci_sock_set_device(int dev); void ble_store_ram_init(void); @@ -89,9 +88,6 @@ int main(int argc, char *argv[]) printf("port init\n"); nimble_port_init(); - printf("hci init\n"); - ble_hci_sock_init(); - /* This example provides GATT Alert service */ printf("gap init\n"); ble_svc_gap_init(); From 24a3d58ce236d655ae4fd1caad04d68c33cbcecc Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 2 Jan 2024 16:26:50 +0100 Subject: [PATCH 0878/1333] nimble/host: Fix possible overflow in ble_gatts_peer_cl_sup_feat_update This function would write pass conn->bhc_gatt_svr.peer_cl_sup_feat buffer. Since supported features are likely to be small (currently only 3 bits are defined) lets keep this simple and just make local copy before validation. --- nimble/host/src/ble_gatts.c | 59 ++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/nimble/host/src/ble_gatts.c b/nimble/host/src/ble_gatts.c index 2c18cc4a68..bf50305f4f 100644 --- a/nimble/host/src/ble_gatts.c +++ b/nimble/host/src/ble_gatts.c @@ -1613,8 +1613,9 @@ int ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, struct os_mbuf *om) { struct ble_hs_conn *conn; + uint8_t feat[BLE_GATT_CHR_CLI_SUP_FEAT_SZ] = {}; + uint16_t len; int rc = 0; - int feat_idx = 0; int i; BLE_HS_LOG(DEBUG, ""); @@ -1623,46 +1624,42 @@ ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, struct os_mbuf *om) return BLE_ATT_ERR_INSUFFICIENT_RES; } + /* RFU bits are ignored so we can skip any bytes larger than supported */ + len = os_mbuf_len(om); + if (len > BLE_GATT_CHR_CLI_SUP_FEAT_SZ) { + len = BLE_GATT_CHR_CLI_SUP_FEAT_SZ; + } + + if (os_mbuf_copydata(om, 0, len, feat) < 0) { + return BLE_ATT_ERR_UNLIKELY; + } + + /* clear RFU bits */ + for (i = 0; i < BLE_GATT_CHR_CLI_SUP_FEAT_SZ; i++) { + feat[i] &= (BLE_GATT_CHR_CLI_SUP_FEAT_MASK >> (8 * i)); + } + ble_hs_lock(); conn = ble_hs_conn_find(conn_handle); if (conn == NULL) { rc = BLE_ATT_ERR_UNLIKELY; goto done; } - if (om->om_len == 0) { - /* Nothing to do */ - goto done; - } else if (os_mbuf_len(om) > BLE_ATT_ATTR_MAX_LEN) { - rc = BLE_ATT_ERR_INSUFFICIENT_RES; - goto done; - } - - while(om) { - for (i = 0; i < om->om_len; i++) { - /** - * Disabling already enabled features is not permitted - * (Vol. 3, Part F, 3.3.3) - * If value of saved octet, as uint8_t, is greatet than requested - * it means more bits are set. - */ - if (conn->bhc_gatt_svr.peer_cl_sup_feat[feat_idx] > - om->om_data[i]) { - rc = BLE_ATT_ERR_VALUE_NOT_ALLOWED; - goto done; - } - - /* All RFU bits should be unset */ - if (feat_idx == 0) { - om->om_data[i] &= BLE_GATT_CHR_CLI_SUP_FEAT_MASK; - } - - conn->bhc_gatt_svr.peer_cl_sup_feat[feat_idx] |= om->om_data[i]; - feat_idx++; + /** + * Disabling already enabled features is not permitted + * (Vol. 3, Part F, 3.3.3) + */ + for (i = 0; i < BLE_GATT_CHR_CLI_SUP_FEAT_SZ; i++) { + if ((conn->bhc_gatt_svr.peer_cl_sup_feat[i] & feat[i]) != + conn->bhc_gatt_svr.peer_cl_sup_feat[i]) { + rc = BLE_ATT_ERR_VALUE_NOT_ALLOWED; + goto done; } - om = SLIST_NEXT(om, om_next); } + memcpy(conn->bhc_gatt_svr.peer_cl_sup_feat, feat, BLE_GATT_CHR_CLI_SUP_FEAT_SZ); + done: ble_hs_unlock(); return rc; From 4809e7735a1717c5348331977918587be2e23bf6 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 21 Dec 2023 12:36:23 +0100 Subject: [PATCH 0879/1333] nimble/ll: Fix PHY update instant calculation The instant for PHY update was calculated at the time PDU was enqueued in connsm. This caused new PHY to be always applied at instant regardless if PDU was even dequeued for tx, e.g. in case there encryption procedure pending. This could result in connection being dropped. Currently we calculate instant when PDU is dequeued to make sure this is the next PDU to be sent and thus instant is valid. --- nimble/controller/src/ble_ll_ctrl.c | 38 +++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index d0989d65f5..6c739a3cff 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -765,7 +765,6 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t s_to_m; uint8_t tx_phys; uint8_t rx_phys; - uint16_t instant; uint8_t is_periph_sym = 0; /* Get preferences from PDU */ @@ -839,13 +838,7 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, connsm->flags.phy_update_host_initiated = 0; ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_PHY_UPDATE); } - instant = 0; } else { - /* Determine instant we will use. 6 more is minimum */ - instant = connsm->event_cntr + connsm->periph_latency + 6 + 1; - connsm->phy_instant = instant; - connsm->flags.phy_update_sched = 1; - /* Set new phys to use when instant occurs */ connsm->phy_data.new_tx_phy = m_to_s; connsm->phy_data.new_rx_phy = s_to_m; @@ -862,7 +855,31 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, ctrdata[0] = m_to_s; ctrdata[1] = s_to_m; +} + +static bool +ble_ll_ctrl_phy_update_ind_instant(struct ble_ll_conn_sm *connsm, uint8_t *ctrdata) +{ + uint16_t instant; + uint8_t m_to_s; + uint8_t s_to_m; + bool schedule = false; + + m_to_s = ctrdata[0]; + s_to_m = ctrdata[1]; + + if ((m_to_s == 0) && (s_to_m == 0)) { + instant = 0; + } else { + /* Determine instant we will use. 6 more is minimum */ + instant = connsm->event_cntr + connsm->periph_latency + 6 + 1; + connsm->phy_instant = instant; + schedule = true; + } + put_le16(ctrdata + 2, instant); + + return schedule; } #endif @@ -3089,6 +3106,13 @@ ble_ll_ctrl_tx_start(struct ble_ll_conn_sm *connsm, struct os_mbuf *txpdu) ble_ll_ctrl_conn_update_make_ind_pdu(connsm, ctrdata); connsm->flags.conn_update_sched = 1; break; +#if MYNEWT_VAL(BLE_LL_PHY) + case BLE_LL_CTRL_PHY_UPDATE_IND: + if (ble_ll_ctrl_phy_update_ind_instant(connsm, ctrdata)) { + connsm->flags.phy_update_sched = 1; + } + break; +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) case BLE_LL_CTRL_SUBRATE_IND: connsm->flags.subrate_trans = 1; From e5acfe06c32b1b5806f890997c3ca7d7f32aad52 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 22 Dec 2023 14:10:53 +0100 Subject: [PATCH 0880/1333] nimble/ll: Fix channel map update instant calculation The instant for channel map update was calculated at the time PDU was enqueued in connsm. This caused new map to be always applied at instant regardless if PDU was even dequeued for tx, e.g. in case there encryption procedure pending. This could result in connection being dropped. Currently we calculate instant when PDU is dequeued to make sure this is the next PDU to be sent and thus instant is valid. --- nimble/controller/src/ble_ll_ctrl.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 6c739a3cff..6eb883c82f 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1883,12 +1883,15 @@ ble_ll_ctrl_chanmap_req_make(struct ble_ll_conn_sm *connsm, uint8_t *pyld) memcpy(pyld, g_ble_ll_data.chan_map, BLE_LL_CHAN_MAP_LEN); memcpy(connsm->req_chanmap, pyld, BLE_LL_CHAN_MAP_LEN); + /* Instant is placed in ble_ll_ctrl_chanmap_req_instant()*/ +} + +static void +ble_ll_ctrl_chanmap_req_instant(struct ble_ll_conn_sm *connsm, uint8_t *pyld) +{ /* Place instant into request */ connsm->chanmap_instant = connsm->event_cntr + connsm->periph_latency + 6 + 1; put_le16(pyld + BLE_LL_CHAN_MAP_LEN, connsm->chanmap_instant); - - /* Set scheduled flag */ - connsm->flags.chanmap_update_sched = 1; } /** @@ -3106,6 +3109,10 @@ ble_ll_ctrl_tx_start(struct ble_ll_conn_sm *connsm, struct os_mbuf *txpdu) ble_ll_ctrl_conn_update_make_ind_pdu(connsm, ctrdata); connsm->flags.conn_update_sched = 1; break; + case BLE_LL_CTRL_CHANNEL_MAP_REQ: + ble_ll_ctrl_chanmap_req_instant(connsm, ctrdata); + connsm->flags.chanmap_update_sched = 1; + break; #if MYNEWT_VAL(BLE_LL_PHY) case BLE_LL_CTRL_PHY_UPDATE_IND: if (ble_ll_ctrl_phy_update_ind_instant(connsm, ctrdata)) { From 4d1055b014f57351aed4eb0d877cbcd8fa7afd97 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 24 Jan 2024 09:05:17 +0100 Subject: [PATCH 0881/1333] porting/linux: Fix link in README Readme was using very old (dead) link to BLE guide. --- porting/examples/linux/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porting/examples/linux/README.md b/porting/examples/linux/README.md index 562da266b2..c7e256557a 100644 --- a/porting/examples/linux/README.md +++ b/porting/examples/linux/README.md @@ -23,7 +23,7 @@ ## Overview -See (https://mynewt.apache.org/network/ble/ble_intro/). +See https://mynewt.apache.org/latest/network ## Building From a1ca9615113d7e2a74ed87665cff92a694ba0910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 26 Jan 2024 14:33:27 +0100 Subject: [PATCH 0882/1333] nimble/host: ble_gap_adv_get_free_instance shall return non-negative value All public GAP API functions shall return non-negative error codes. Now, function fills out pointer with found advertising instance and returns correct error code. --- nimble/host/include/host/ble_gap.h | 8 +++++--- nimble/host/services/auracast/src/ble_svc_auracast.c | 5 +++-- nimble/host/src/ble_gap.c | 9 +++++---- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index d884596a67..a8f6e3c54d 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -1694,12 +1694,14 @@ int ble_gap_ext_adv_clear(void); int ble_gap_ext_adv_active(uint8_t instance); /** - * Returns first not configured advertising instance. + * Finds first not configured advertising instance. * - * @return advertising instance if one was found, negative error code otherwise + * @param[out] out_adv_instance Pointer to be filled with found advertising instance + * + * @return 0 if free advertising instance was found, error code otherwise * */ -int ble_gap_adv_get_free_instance(void); +int ble_gap_adv_get_free_instance(uint8_t *out_adv_instance); #endif /* Periodic Advertising */ diff --git a/nimble/host/services/auracast/src/ble_svc_auracast.c b/nimble/host/services/auracast/src/ble_svc_auracast.c index 4446ff90d4..814035b9c8 100644 --- a/nimble/host/services/auracast/src/ble_svc_auracast.c +++ b/nimble/host/services/auracast/src/ble_svc_auracast.c @@ -42,6 +42,7 @@ ble_svc_auracast_create(const struct ble_svc_auracast_create_params *params, uint8_t data_offset = 1; uint8_t features = 0; + int rc; features |= params->big_params->encryption; @@ -79,8 +80,8 @@ ble_svc_auracast_create(const struct ble_svc_auracast_create_params *params, auracast_svc_data[0] = data_offset - 1; - adv_instance = ble_gap_adv_get_free_instance(); - if (adv_instance < 0) { + rc = ble_gap_adv_get_free_instance(&adv_instance); + if (rc) { return BLE_HS_ENOENT; } diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 02e4f28881..eb4e6f6019 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -1392,17 +1392,18 @@ int ble_gap_ext_adv_active(uint8_t instance) } int -ble_gap_adv_get_free_instance(void) +ble_gap_adv_get_free_instance(uint8_t *out_adv_instance) { - int i; + uint8_t i; for (i = 0; i < BLE_ADV_INSTANCES; i++) { if (!ble_gap_slave[i].configured) { - return i; + *out_adv_instance = i; + return 0; } } - return -BLE_HS_ENOENT; + return BLE_HS_ENOENT; } #endif From db932dc2f94a7fab1708048831fd5a5bf888a7a9 Mon Sep 17 00:00:00 2001 From: Donatien Garnier Date: Thu, 21 Dec 2023 11:50:00 +0000 Subject: [PATCH 0883/1333] nimble/host: Read supported HCI commands from controller This patch adds a new function, ble_hs_startup_read_sup_cmd_tx(), which reads the list of supported HCI commands from the controller on HCI startup. This is used to determine whether a HCI Set Event Mask Page 2 command should be sent to the controller. --- nimble/host/src/ble_hs_hci.c | 14 ++++++++++ nimble/host/src/ble_hs_hci_priv.h | 6 ++++ nimble/host/src/ble_hs_startup.c | 31 +++++++++++++++++++-- nimble/host/test/src/ble_hs_test_util_hci.c | 13 +++++++++ 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_hs_hci.c b/nimble/host/src/ble_hs_hci.c index a3a7d2529e..2321b90cb8 100644 --- a/nimble/host/src/ble_hs_hci.c +++ b/nimble/host/src/ble_hs_hci.c @@ -38,6 +38,8 @@ static uint32_t ble_hs_hci_sup_feat; static uint8_t ble_hs_hci_version; +static struct ble_hs_hci_sup_cmd ble_hs_hci_sup_cmd; + #if MYNEWT_VAL(BLE_CONTROLLER) #define BLE_HS_HCI_FRAG_DATABUF_SIZE \ (BLE_ACL_MAX_PKT_SIZE + \ @@ -632,6 +634,18 @@ ble_hs_hci_get_hci_version(void) return ble_hs_hci_version; } +void +ble_hs_hci_set_hci_supported_cmd(struct ble_hs_hci_sup_cmd sup_cmd) +{ + ble_hs_hci_sup_cmd = sup_cmd; +} + +struct ble_hs_hci_sup_cmd +ble_hs_hci_get_hci_supported_cmd(void) +{ + return ble_hs_hci_sup_cmd; +} + void ble_hs_hci_init(void) { diff --git a/nimble/host/src/ble_hs_hci_priv.h b/nimble/host/src/ble_hs_hci_priv.h index 356f3a538d..78621e046a 100644 --- a/nimble/host/src/ble_hs_hci_priv.h +++ b/nimble/host/src/ble_hs_hci_priv.h @@ -79,6 +79,10 @@ struct hci_periodic_adv_params #endif #endif +struct ble_hs_hci_sup_cmd { + unsigned event_mask2 : 1; /** Indicates whether the controller supports the set event mask page 2 command */ +}; + extern uint16_t ble_hs_hci_avail_pkts; /* This function is not waiting for command status/complete HCI events */ @@ -91,6 +95,8 @@ void ble_hs_hci_set_le_supported_feat(uint32_t feat); uint32_t ble_hs_hci_get_le_supported_feat(void); void ble_hs_hci_set_hci_version(uint8_t hci_version); uint8_t ble_hs_hci_get_hci_version(void); +void ble_hs_hci_set_hci_supported_cmd(struct ble_hs_hci_sup_cmd sup_cmd); +struct ble_hs_hci_sup_cmd ble_hs_hci_get_hci_supported_cmd(void); #if MYNEWT_VAL(BLE_HS_PHONY_HCI_ACKS) typedef int ble_hs_hci_phony_ack_fn(uint8_t *ack, int ack_buf_len); diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c index 75e98ebc43..71d46bdbb7 100644 --- a/nimble/host/src/ble_hs_startup.c +++ b/nimble/host/src/ble_hs_startup.c @@ -68,6 +68,27 @@ ble_hs_startup_read_local_ver_tx(void) return 0; } +static int +ble_hs_startup_read_sup_cmd_tx(void) +{ + struct ble_hci_ip_rd_loc_supp_cmd_rp rsp; + struct ble_hs_hci_sup_cmd sup_cmd; + int rc; + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, + BLE_HCI_OCF_IP_RD_LOC_SUPP_CMD), + NULL, 0, &rsp, sizeof(rsp)); + if (rc != 0) { + return rc; + } + + /* Only check support for Set Event ­Mask ­Page ­2 command */ + sup_cmd.event_mask2 = (rsp.commands[22] & 0x04) != 0; + ble_hs_hci_set_hci_supported_cmd(sup_cmd); + + return 0; +} + static int ble_hs_startup_le_read_sup_f_tx(void) { @@ -289,9 +310,11 @@ ble_hs_startup_set_evmask_tx(void) struct ble_hci_cb_set_event_mask_cp cmd; struct ble_hci_cb_set_event_mask2_cp cmd2; uint8_t version; + struct ble_hs_hci_sup_cmd sup_cmd; int rc; version = ble_hs_hci_get_hci_version(); + sup_cmd = ble_hs_hci_get_hci_supported_cmd(); /** * Enable the following events: @@ -311,7 +334,7 @@ ble_hs_startup_set_evmask_tx(void) return rc; } - if (version >= BLE_HCI_VER_BCS_4_1) { + if ((version >= BLE_HCI_VER_BCS_4_1) && sup_cmd.event_mask2) { /** * Enable the following events: * 0x0000000000800000 Authenticated Payload Timeout Event @@ -352,7 +375,11 @@ ble_hs_startup_go(void) return rc; } - /* XXX: Read local supported commands. */ + /* Read local supported commands. */ + rc = ble_hs_startup_read_sup_cmd_tx(); + if (rc != 0) { + return rc; + } /* we need to check this only if using external controller */ #if !MYNEWT_VAL(BLE_CONTROLLER) diff --git a/nimble/host/test/src/ble_hs_test_util_hci.c b/nimble/host/test/src/ble_hs_test_util_hci.c index e8054c2ffa..c27af143aa 100644 --- a/nimble/host/test/src/ble_hs_test_util_hci.c +++ b/nimble/host/test/src/ble_hs_test_util_hci.c @@ -250,6 +250,19 @@ static const struct ble_hs_test_util_hci_ack hci_startup_seq[] = { .evt_params = { 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, .evt_params_len = 8, }, + { + .opcode = ble_hs_hci_util_opcode_join( + BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOC_SUPP_CMD), + .evt_params = { 0x20, 0x00, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x28, 0x22, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0xf7, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xf9, 0xff, 0xff, 0xff, 0xff, 0x07, + 0xe0, 0x63, 0xe0, 0x04, 0x02, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .evt_params_len = 64 + }, { .opcode = ble_hs_hci_util_opcode_join( BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT), From a7c615381fd85522bb5bfb4e085336226b3e53b5 Mon Sep 17 00:00:00 2001 From: Donatien Garnier Date: Thu, 21 Dec 2023 13:29:54 +0000 Subject: [PATCH 0884/1333] nimble/controller: add HCI Set Event Mask Page 2 to supported commands This patch adds HCI Set Event Mask Page 2 to the list of supported commands. This command is already implemented in the controller but was not listed as supported. --- nimble/controller/src/ble_ll_hci_supp_cmd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_hci_supp_cmd.c b/nimble/controller/src/ble_ll_hci_supp_cmd.c index 8d9822fd6e..40b1e947ca 100644 --- a/nimble/controller/src/ble_ll_hci_supp_cmd.c +++ b/nimble/controller/src/ble_ll_hci_supp_cmd.c @@ -64,6 +64,10 @@ static const uint8_t octet_15 = OCTET( #endif ); +static const uint8_t octet_22 = OCTET( + BIT(2) /* HCI Set Event Mask Page 2 */ +); + static const uint8_t octet_25 = OCTET( BIT(0) /* HCI LE Set Event Mask */ BIT(1) /* HCI LE Read Buffer Size [v1] */ @@ -307,7 +311,7 @@ static const uint8_t g_ble_ll_hci_supp_cmds[64] = { 0, 0, 0, - 0, + octet_22, 0, 0, octet_25, From 572e5fb9461b8cabe7c121fc46dd27ef8d943fcd Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Thu, 25 Jan 2024 10:03:46 +0100 Subject: [PATCH 0885/1333] host/gap: fix typo in GAP event macro Corrects spelling in BLE_GAP_EVENT_PAIRING_COMPLETE --- apps/bttester/src/btp_gap.c | 2 +- nimble/host/include/host/ble_gap.h | 8 ++++++-- nimble/host/src/ble_gap.c | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 0b2239149b..79ec5152fc 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -1511,7 +1511,7 @@ gap_event_cb(struct ble_gap_event *event, void *arg) == REJECT_SUPERVISION_TIMEOUT) { return EINVAL; } - case BLE_GAP_EVENT_PARING_COMPLETE: + case BLE_GAP_EVENT_PAIRING_COMPLETE: console_printf("received pairing complete: " "conn_handle=%d status=%d\n", event->pairing_complete.conn_handle, diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index a8f6e3c54d..271933963c 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -247,7 +247,10 @@ struct hci_conn_update; #define BLE_GAP_EVENT_TRANSMIT_POWER 26 /** GAP event: Pairing complete */ -#define BLE_GAP_EVENT_PARING_COMPLETE 27 +#define BLE_GAP_EVENT_PAIRING_COMPLETE 27 + +/** GAP event: Pairing complete (deprecated) */ +#define BLE_GAP_EVENT_PARING_COMPLETE BLE_GAP_EVENT_PAIRING_COMPLETE /** GAP event: Subrate change */ #define BLE_GAP_EVENT_SUBRATE_CHANGE 28 @@ -1245,7 +1248,8 @@ struct ble_gap_event { * Represents a received Pairing Complete message * * Valid for the following event types: - * o BLE_GAP_EVENT_PARING_COMPLETE + * o BLE_GAP_EVENT_PAIRING_COMPLETE + * o BLE_GAP_EVENT_PARING_COMPLETE (deprecated) */ struct { /** diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index eb4e6f6019..85d7a9e4cc 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -6382,7 +6382,7 @@ ble_gap_pairing_complete_event(uint16_t conn_handle, int status) struct ble_gap_event event; memset(&event, 0, sizeof event); - event.type = BLE_GAP_EVENT_PARING_COMPLETE; + event.type = BLE_GAP_EVENT_PAIRING_COMPLETE; event.pairing_complete.conn_handle = conn_handle; event.pairing_complete.status = status; ble_gap_call_conn_event_cb(&event, conn_handle); From 4340db0c5c5a8293c4d9774b9585d7309505426d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 22 Dec 2023 14:10:53 +0100 Subject: [PATCH 0886/1333] nimble/ll: Fix channel map update instant calculation The instant for channel map update was calculated at the time PDU was enqueued in connsm. This caused new map to be always applied at instant regardless if PDU was even dequeued for tx, e.g. in case there encryption procedure pending. This could result in connection being dropped. Currently we calculate instant when PDU is dequeued to make sure this is the next PDU to be sent and thus instant is valid. --- nimble/host/include/host/ble_gatt.h | 20 -------------------- nimble/host/services/gatt/src/ble_svc_gatt.c | 5 ++++- nimble/host/src/ble_gatt_priv.h | 2 ++ 3 files changed, 6 insertions(+), 21 deletions(-) diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index 0f811e7330..b82ab2f40f 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -1076,26 +1076,6 @@ int ble_gatts_reset(void); */ int ble_gatts_start(void); -/** - * Saves Client Supported Features for specified connection. - * - * @param conn_handle Connection handle identifying connection for - * which Client Supported Features should be saved - * @param om The mbuf chain to set value from. - * - * @return 0 on success; - * BLE_HS_ENOTCONN if no matching connection - * was found - * BLE_HS_EINVAL if supplied buffer is empty or - * if any Client Supported Feature was - * attempted to be disabled. - * A BLE host core return code on unexpected - * error. - * - */ -int ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, - struct os_mbuf *om); - /** * Gets Client Supported Features for specified connection. * diff --git a/nimble/host/services/gatt/src/ble_svc_gatt.c b/nimble/host/services/gatt/src/ble_svc_gatt.c index d3262e17bc..91abf9ad65 100644 --- a/nimble/host/services/gatt/src/ble_svc_gatt.c +++ b/nimble/host/services/gatt/src/ble_svc_gatt.c @@ -22,6 +22,7 @@ #include "sysinit/sysinit.h" #include "host/ble_hs.h" #include "services/gatt/ble_svc_gatt.h" +#include "../src/ble_gatt_priv.h" static uint16_t ble_svc_gatt_changed_val_handle; static uint16_t ble_svc_gatt_start_handle; @@ -112,7 +113,9 @@ ble_svc_gatt_cl_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle, return 0; } if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - return ble_gatts_peer_cl_sup_feat_update(conn_handle, ctxt->om); + if (ble_gatts_peer_cl_sup_feat_update(conn_handle, ctxt->om)) { + return BLE_ATT_ERR_UNLIKELY; + } } return 0; diff --git a/nimble/host/src/ble_gatt_priv.h b/nimble/host/src/ble_gatt_priv.h index eb778293cd..50e0a75b91 100644 --- a/nimble/host/src/ble_gatt_priv.h +++ b/nimble/host/src/ble_gatt_priv.h @@ -201,6 +201,8 @@ int ble_gatts_clt_cfg_access(uint16_t conn_handle, uint16_t attr_handle, uint8_t op, uint16_t offset, struct os_mbuf **om, void *arg); +int ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, + struct os_mbuf *om); /*** @misc. */ int ble_gatts_conn_can_alloc(void); int ble_gatts_conn_init(struct ble_gatts_conn *gatts_conn); From f07a77489f4f4b20073b257123ec4fd5123c0b05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 11 Aug 2023 14:17:10 +0200 Subject: [PATCH 0887/1333] host/gatt_srv: Implement sending Multiple Handle Notifications It is mandatory to support sending them if receiving is supported. Implemented functionality and added public API. --- nimble/host/include/host/ble_gatt.h | 63 +++++++++++ nimble/host/src/ble_att_clt.c | 32 ++++++ nimble/host/src/ble_att_priv.h | 1 + nimble/host/src/ble_gattc.c | 133 ++++++++++++++++++++++++ nimble/host/syscfg.yml | 7 ++ nimble/include/nimble/nimble_opt_auto.h | 3 + 6 files changed, 239 insertions(+) diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index b82ab2f40f..a38d3c9345 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -246,6 +246,16 @@ struct ble_gatt_dsc { ble_uuid_any_t uuid; }; + +/** Represents a handle-value tuple for multiple handle notifications. */ +struct ble_gatt_notif { + /** The handle of the GATT characteristic */ + uint16_t handle; + + /** The buffer with GATT characteristic value */ + struct os_mbuf *value; +}; + /** Function prototype for the GATT MTU exchange callback. */ typedef int ble_gatt_mtu_fn(uint16_t conn_handle, const struct ble_gatt_error *error, @@ -634,6 +644,33 @@ int ble_gattc_write_reliable(uint16_t conn_handle, int ble_gatts_notify_custom(uint16_t conn_handle, uint16_t att_handle, struct os_mbuf *om); +/** + * Sends a "free-form" multiple handle variable length characteristic + * notification. This function consumes supplied mbufs regardless of the + * outcome. Notifications are sent in order of supplied entries. + * Function tries to send minimum amount of PDUs. If PDU can't contain all + * of the characteristic values, multiple notifications are sent. If only one + * handle-value pair fits into PDU, or only one characteristic remains in the + * list, regular characteristic notification is sent. + * + * If GATT client doesn't support receiving multiple handle notifications, + * this will use GATT notification for each characteristic, separately. + * + * If value of characteristic is not specified it will be read from local + * GATT database. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param chr_count Number of characteristics to notify about. + * @param tuples Handle-value pairs in form of `ble_gatt_notif` + * structures. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gatts_notify_multiple_custom(uint16_t conn_handle, + uint16_t chr_count, + struct ble_gatt_notif *tuples); + /** * Deprecated. Should not be used. Use ble_gatts_notify_custom instead. */ @@ -659,6 +696,32 @@ int ble_gatts_notify(uint16_t conn_handle, uint16_t chr_val_handle); */ int ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle); +/** + * Sends a multiple handle variable length characteristic notification. The + * content of the message is read from the specified characteristics. + * Notifications are sent in order of supplied handles. Function tries to + * send minimum amount of PDUs. If PDU can't contain all of the + * characteristic values, multiple notifications are sent. If only one + * handle-value pair fits into PDU, or only one characteristic remains in the + * list, regular characteristic notification is sent. + * + * If GATT client doesn't support receiving multiple handle notifications, + * this will use GATT notification for each characteristic, separately. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param num_handles The number of entries in the "chr_val_handles" + * array. + * @param chr_val_handles Array of attribute handles of the + * characteristics to include in the outgoing + * notification. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gatts_notify_multiple(uint16_t conn_handle, + uint8_t num_handles, + const uint16_t *chr_val_handles); + /** * Sends a "free-form" characteristic indication. The provided mbuf contains * the indication payload. This function consumes the supplied mbuf regardless diff --git a/nimble/host/src/ble_att_clt.c b/nimble/host/src/ble_att_clt.c index 3423e25e86..2b60f8b533 100644 --- a/nimble/host/src/ble_att_clt.c +++ b/nimble/host/src/ble_att_clt.c @@ -986,3 +986,35 @@ ble_att_clt_rx_indicate(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxo } #endif + +/***************************************************************************** + * $multiple handle value notification * + *****************************************************************************/ + +int +ble_att_clt_tx_notify_mult(uint16_t conn_handle, struct os_mbuf *txom) +{ +#if !NIMBLE_BLE_ATT_CLT_NOTIFY_MULT + return BLE_HS_ENOTSUP; +#endif + + struct os_mbuf *txom2; + uint16_t cid; + int rc; + + if (ble_att_cmd_get(BLE_ATT_OP_NOTIFY_MULTI_REQ, 0, &txom2) == NULL) { + rc = BLE_HS_ENOMEM; + goto err; + } + + os_mbuf_concat(txom2, txom); + + cid = ble_eatt_get_available_chan_cid(conn_handle, BLE_GATT_OP_DUMMY); + rc = ble_att_tx(conn_handle, cid, txom2); + if (cid != BLE_L2CAP_CID_ATT) { + ble_eatt_release_chan(conn_handle, BLE_GATT_OP_DUMMY); + } + +err: + return rc; +} diff --git a/nimble/host/src/ble_att_priv.h b/nimble/host/src/ble_att_priv.h index ac65250f93..2bc3da361b 100644 --- a/nimble/host/src/ble_att_priv.h +++ b/nimble/host/src/ble_att_priv.h @@ -302,6 +302,7 @@ int ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle, int ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t cid, uint16_t handle, struct os_mbuf *txom); int ble_att_clt_rx_indicate(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom); +int ble_att_clt_tx_notify_mult(uint16_t conn_handle, struct os_mbuf *txom); #ifdef __cplusplus } diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index 2d42856b8f..d40adfd3c9 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -4413,6 +4413,139 @@ ble_gatts_notify(uint16_t conn_handle, uint16_t chr_val_handle) return rc; } +int +ble_gatts_notify_multiple_custom(uint16_t conn_handle, + uint16_t chr_count, + struct ble_gatt_notif *tuples) +{ +#if !MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) + return BLE_HS_ENOTSUP; +#endif + + int rc; + int i = 0; + uint16_t cur_chr_cnt = 0; + /* mtu = MTU - 1 octet (OP code) */ + uint16_t mtu = ble_att_mtu(conn_handle) - 1; + struct os_mbuf *txom; + struct ble_hs_conn *conn; + + txom = ble_hs_mbuf_att_pkt(); + if (txom == NULL) { + return BLE_HS_ENOMEM; + } + + conn = ble_hs_conn_find(conn_handle); + if (conn == NULL) { + return ENOTCONN; + } + + /* Read missing values */ + for (i = 0; i < chr_count; i++) { + if (tuples->handle == 0) { + rc = BLE_HS_EINVAL; + goto done; + } + if (tuples[i].value == NULL) { + rc = ble_att_svr_read_local(tuples[i].handle, &tuples[i].value); + if (rc != 0) { + goto done; + } + } + } + + /* If peer does not support fall back to multiple single value + * Notifications */ + if ((conn->bhc_gatt_svr.peer_cl_sup_feat[0] & 0x04) == 0) { + for (i = 0; i < chr_count; i++) { + rc = ble_att_clt_tx_notify(conn_handle, tuples[chr_count].handle, + tuples[chr_count].value); + if (rc != 0) { + goto done; + } + } + } + + for (i = 0; i < chr_count; i++) { + if (txom->om_len + tuples[i].value->om_len > mtu && cur_chr_cnt < 2) { + rc = ble_att_clt_tx_notify(conn_handle, tuples[i].handle, + tuples[i].value); + if (rc != 0) { + goto done; + } + continue; + } else if (txom->om_len + tuples[i].value->om_len > mtu) { + rc = ble_att_clt_tx_notify_mult(conn_handle, txom); + if (rc != 0) { + goto done; + } + cur_chr_cnt = 0; + /* buffer was consumed, allocate new one */ + txom = ble_hs_mbuf_att_pkt(); + if (txom == NULL) { + return BLE_HS_ENOMEM; + } + } + + os_mbuf_append(txom, &tuples[i].handle, sizeof(uint16_t)); + os_mbuf_append(txom, &tuples[i].value->om_len, + sizeof(uint16_t)); + os_mbuf_concat(txom, tuples[i].value); + cur_chr_cnt++; + } + + if (cur_chr_cnt == 1) { + rc = ble_att_clt_tx_notify(conn_handle, tuples[chr_count].handle, + tuples[chr_count].value); + } else { + rc = ble_att_clt_tx_notify_mult(conn_handle, txom); + } + +done: + return rc; +} + +int +ble_gatts_notify_multiple(uint16_t conn_handle, + uint8_t num_handles, + const uint16_t *chr_val_handles) +{ +#if !MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) + return BLE_HS_ENOTSUP; +#endif + int rc, i; + struct ble_gatt_notif tuples[num_handles]; + struct ble_hs_conn *conn; + + BLE_HS_LOG_DEBUG("conn_handle %d\n", conn_handle); + conn = ble_hs_conn_find(conn_handle); + if (conn == NULL) { + return ENOTCONN; + } + + /** Skip sending to client that doesn't support this feature */ + BLE_HS_LOG_DEBUG("ble_gatts_notify_multiple: peer_cl_sup_feat %d\n", + conn->bhc_gatt_svr.peer_cl_sup_feat[0]); + if ((conn->bhc_gatt_svr.peer_cl_sup_feat[0] & 0x04) == 0) { + for (i = 0; i < num_handles; i++) { + rc = ble_gatts_notify(conn_handle, chr_val_handles[i]); + if (rc != 0) { + return rc; + } + } + return 0; + } + + for (i = 0; i < num_handles; i++) { + tuples[i].handle = chr_val_handles[i]; + tuples[i].value = NULL; + BLE_HS_LOG(DEBUG, "handle 0x%02x\n", tuples[i].handle); + } + + rc = ble_gatts_notify_multiple_custom(conn_handle, num_handles, tuples); + return rc; +} + /** * Deprecated. Should not be used. Use ble_gatts_notify instead. */ diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index 558e31e8d2..79a027d4be 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -282,6 +282,12 @@ syscfg.defs: description: > Enables sending and receiving of GATT indications. (0/1) value: 1 + BLE_GATT_NOTIFY_MULTIPLE: + description: > + Enables sending and receiving of GATT multiple handle notifications. (0/1) + value: (MYNEWT_VAL_BLE_VERSION >= 52) + restrictions: + - '(BLE_VERSION >= 52) if 1' # GATT options. BLE_GATT_READ_MAX_ATTRS: @@ -309,6 +315,7 @@ syscfg.defs: description: > Number of CoC channels allocated to EATT value: 0 + restrictions: BLE_GATT_NOTIFY_MULTIPLE BLE_EATT_MTU: description: > diff --git a/nimble/include/nimble/nimble_opt_auto.h b/nimble/include/nimble/nimble_opt_auto.h index 55f6219917..4663ae8c7c 100644 --- a/nimble/include/nimble/nimble_opt_auto.h +++ b/nimble/include/nimble/nimble_opt_auto.h @@ -109,6 +109,9 @@ extern "C" { #define NIMBLE_BLE_ATT_CLT_INDICATE \ (MYNEWT_VAL(BLE_GATT_INDICATE)) +#undef NIMBLE_BLE_ATT_CLT_NOTIFY_MULT +#define NIMBLE_BLE_ATT_CLT_NOTIFY_MULT \ + (MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE)) /** Security manager settings. */ #undef NIMBLE_BLE_SM From dd1cfe7e307dae1115bd7c8d516a7941edd9d1e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 11 Aug 2023 14:19:41 +0200 Subject: [PATCH 0888/1333] Apps/bttester: add support for sending Multiple Handle Notifications Sending Multiple Handle notifications is triggered by writing multiple values, at once, to GATT database. New values are set and notification is sent for each connection. --- apps/bttester/src/btp/btp_gatt.h | 6 +++ apps/bttester/src/btp_gatt.c | 84 +++++++++++++++++++++++++++++++- apps/bttester/src/btp_gatt_cl.c | 2 +- apps/bttester/syscfg.yml | 2 + 4 files changed, 92 insertions(+), 2 deletions(-) diff --git a/apps/bttester/src/btp/btp_gatt.h b/apps/bttester/src/btp/btp_gatt.h index 88f2e62a9a..8da6f43df8 100644 --- a/apps/bttester/src/btp/btp_gatt.h +++ b/apps/bttester/src/btp/btp_gatt.h @@ -314,6 +314,12 @@ struct btp_gatt_change_database_cmd { uint8_t visibility; } __packed; +#define BTP_GATT_SET_MULT_VALUE 0x20 +struct btp_gatt_set_mult_val_cmd { + uint16_t count; + uint8_t data[0]; +} __packed; + /* GATT events */ #define BTP_GATT_EV_NOTIFICATION 0x80 struct btp_gatt_notification_ev { diff --git a/apps/bttester/src/btp_gatt.c b/apps/bttester/src/btp_gatt.c index 1c6320510d..496779ebb6 100644 --- a/apps/bttester/src/btp_gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -67,6 +67,7 @@ #define PTS_DSC_WRITE 0x000a #define PTS_DSC_READ_WRITE 0x000b #define PTS_CHR_NOTIFY 0x0025 +#define PTS_CHR_NOTIFY_ALT 0x0026 #define PTS_LONG_CHR_READ_WRITE 0x0015 #define PTS_LONG_CHR_READ_WRITE_ALT 0x0016 #define PTS_LONG_DSC_READ_WRITE 0x001b @@ -90,6 +91,11 @@ struct find_attr_data { uint16_t handle; }; +struct notify_mult_cb_data { + size_t tuple_cnt; + uint16_t handles[0]; +}; + static int gatt_svr_read_write_test(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, @@ -230,7 +236,17 @@ static const struct ble_gatt_svc_def gatt_svr_svcs[] = { .uuid = PTS_UUID_DECLARE(PTS_CHR_NOTIFY), .access_cb = gatt_svr_read_write_test, .val_handle = ¬ify_handle, - .flags = BLE_GATT_CHR_F_NOTIFY | + .flags = BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_WRITE | + BLE_GATT_CHR_F_NOTIFY | + BLE_GATT_CHR_F_INDICATE, + }, { + .uuid = PTS_UUID_DECLARE(PTS_CHR_NOTIFY_ALT), + .access_cb = gatt_svr_read_write_test, + .val_handle = ¬ify_handle, + .flags = BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_WRITE | + BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_INDICATE, }, { 0, /* No more characteristics in this service. */ @@ -322,6 +338,8 @@ gatt_svr_read_write_test(uint16_t conn_handle, uint16_t attr_handle, switch (uuid16) { case PTS_CHR_READ_WRITE: case PTS_CHR_READ_WRITE_ALT: + case PTS_CHR_NOTIFY: + case PTS_CHR_NOTIFY_ALT: if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { rc = gatt_svr_chr_write(conn_handle, attr_handle, ctxt->om, 0, @@ -1836,6 +1854,65 @@ get_attr_val(const void *cmd, uint16_t cmd_len, return status; } +int +notify_multiple(uint16_t conn_handle, void *arg) +{ + struct notify_mult_cb_data *notify_data = + (struct notify_mult_cb_data *) arg; + int rc; + + SYS_LOG_DBG("") + + rc = ble_gatts_notify_multiple(conn_handle, + notify_data->tuple_cnt, + notify_data->handles); + + return rc; +} + +static uint8_t +set_mult(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_gatt_set_mult_val_cmd *cp = cmd; + struct ble_gatt_notif tuples[16]; + int i; + int rc = 0; + int data_idx = 0; + uint16_t data_len; + struct notify_mult_cb_data cb_data; + + for (i = 0; i < cp->count; i++) { + tuples[i].handle = get_le16(cp->data + data_idx); + data_idx += 2; + tuples[i].value = ble_hs_mbuf_att_pkt(); + if (tuples[i].value == NULL) { + rc = ENOMEM; + goto done; + } + + data_len = get_le16(cp->data + data_idx); + data_idx += 2; + + os_mbuf_append(tuples[i].value, cp->data + data_idx, data_len); + data_idx += data_len; + } + + for (i = 0; i < cp->count; i++) { + ble_att_svr_write_local(tuples[i].handle, tuples[i].value); + cb_data.handles[i] = tuples[i].handle; + } + + cb_data.tuple_cnt = cp->count; + ble_gap_conn_foreach_handle(notify_multiple, (void *)&cb_data); +done: + if (rc != 0) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + static uint8_t change_database(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) @@ -2018,6 +2095,11 @@ static const struct btp_handler handlers[] = { .expect_len = sizeof(struct btp_gatt_get_attribute_value_cmd), .func = get_attr_val, }, + { + .opcode = BTP_GATT_SET_MULT_VALUE, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = set_mult, + }, }; int diff --git a/apps/bttester/src/btp_gatt_cl.c b/apps/bttester/src/btp_gatt_cl.c index 4b1af0ff85..609d7e504c 100644 --- a/apps/bttester/src/btp_gatt_cl.c +++ b/apps/bttester/src/btp_gatt_cl.c @@ -1379,7 +1379,7 @@ read_var_cb(uint16_t conn_handle, SYS_LOG_DBG("status=%d", error->status); if (ble_gap_conn_find(conn_handle, &conn)) { - return BTP_STATUS_FAILED; + return BTP_STATUS_FAILED; } memcpy(attrs, attr, sizeof(struct ble_gatt_attr) * num_attrs); diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index bc5e0085a1..d1e37ab6d9 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -145,3 +145,5 @@ syscfg.vals: BLE_MESH_ADV_BUF_COUNT: 20 BLE_MESH_TX_SEG_MAX: 6 + + BLE_EATT_CHAN_NUM: 2 From 1f559ab80bd187db8e1e17e74bead3ea30df5865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 18 Aug 2023 07:38:29 +0200 Subject: [PATCH 0889/1333] apps/btshell: add support for sending Multiple handle Notifications Added commands for queueing notifications to be sent using Multiple Handle Notification, sending them and clearing pending queue. --- apps/btshell/src/btshell.h | 6 +++ apps/btshell/src/cmd.c | 58 +++++++++++++++++++++ apps/btshell/src/cmd_gatt.c | 72 ++++++++++++++++++++++++++ apps/btshell/src/cmd_gatt.h | 3 ++ apps/btshell/src/main.c | 78 +++++++++++++++++++++++++++++ nimble/host/include/host/ble_gatt.h | 4 +- nimble/host/src/ble_gattc.c | 4 +- 7 files changed, 221 insertions(+), 4 deletions(-) diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h index 17b07458a9..d7beb14903 100644 --- a/apps/btshell/src/btshell.h +++ b/apps/btshell/src/btshell.h @@ -127,6 +127,12 @@ int btshell_write_long(uint16_t conn_handle, uint16_t attr_handle, uint16_t offset, struct os_mbuf *om); int btshell_write_reliable(uint16_t conn_handle, struct ble_gatt_attr *attrs, int num_attrs); +#if MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) +int btshell_enqueue_notif(uint16_t handle, uint16_t len, uint8_t *value); +int btshell_send_pending_notif(uint16_t conn_handle); +int btshell_clear_pending_notif(void); +#endif + #if MYNEWT_VAL(BLE_EXT_ADV) int btshell_ext_adv_configure(uint8_t instance, const struct ble_gap_ext_adv_params *params, diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index bba5022dfd..f23c4b9234 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -3498,6 +3498,43 @@ static const struct shell_cmd_help gatt_write_help = { .usage = NULL, .params = gatt_write_params, }; + +/***************************************************************************** + * $gatt-enqueue-notify * + *****************************************************************************/ + +static const struct shell_param gatt_enqueue_notif_params[] = { + {"handle", "characteristic handle, usage: ="}, + {"value", "usage: ="}, + {NULL, NULL} +}; + +static const struct shell_cmd_help gatt_enqueue_notif_help = { + .summary = "enqueue notification to be sent", + .usage = NULL, + .params = gatt_enqueue_notif_params, +}; + +/***************************************************************************** + * $gatt-send-pending-notify * + *****************************************************************************/ + +static const struct shell_param gatt_send_pending_notif_params[] = { + {"conn", "connection handle, usage: ="}, + {NULL, NULL} +}; + +static const struct shell_cmd_help gatt_send_pending_notif_help = { + .summary = "send pending notifications", + .usage = NULL, + .params = gatt_send_pending_notif_params, +}; + +static const struct shell_cmd_help gatt_clear_pending_notif_help = { + .summary = "clear pending notifications", + .usage = NULL, + .params = NULL, +}; #endif #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) @@ -4552,6 +4589,27 @@ static const struct shell_cmd btshell_commands[] = { .sc_cmd_func = cmd_gatt_write, #if MYNEWT_VAL(SHELL_CMD_HELP) .help = &gatt_write_help, +#endif + }, + { + .sc_cmd = "gatt-enqueue-notif", + .sc_cmd_func = cmd_gatt_enqueue_notif, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &gatt_enqueue_notif_help, +#endif + }, + { + .sc_cmd = "gatt-send-queued-notif", + .sc_cmd_func = cmd_gatt_send_pending_notif, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &gatt_send_pending_notif_help, +#endif + }, + { + .sc_cmd = "gatt-clear-queued-notif", + .sc_cmd_func = cmd_gatt_clear_pending_notif, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &gatt_clear_pending_notif_help, #endif }, #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) diff --git a/apps/btshell/src/cmd_gatt.c b/apps/btshell/src/cmd_gatt.c index 734b100476..3011dd9cab 100644 --- a/apps/btshell/src/cmd_gatt.c +++ b/apps/btshell/src/cmd_gatt.c @@ -592,3 +592,75 @@ cmd_gatt_write(int argc, char **argv) return rc; } + +int +cmd_gatt_enqueue_notif(int argc, char **argv) +{ +#if MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) + int rc; + uint16_t handle; + unsigned int len; + uint8_t value[BLE_ATT_ATTR_MAX_LEN]; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + handle = parse_arg_uint16("handle", &rc); + if (rc != 0) { + console_printf("invalid 'handle' parameter\n"); + return rc; + } + + if (argc > 1) { + rc = parse_arg_byte_stream("value", BLE_ATT_ATTR_MAX_LEN, value, &len); + if (rc != 0) { + console_printf("invalid 'value' parameter\n"); + return rc; + } + return btshell_enqueue_notif(handle, len, value); + } else { + return btshell_enqueue_notif(handle, 0, NULL); + } +#else + console_printf("To enable this features set BLE_GATT_NOTIFY_MULTIPLE\n"); + return ENOTSUP; +#endif +} + +int +cmd_gatt_send_pending_notif(int argc, char **argv) +{ +#if MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) + uint16_t conn_handle; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + conn_handle = parse_arg_uint16("conn", &rc); + if (rc != 0) { + console_printf("invalid 'conn' parameter\n"); + return rc; + } + + return btshell_send_pending_notif(conn_handle); +#else + console_printf("To enable this features set BLE_GATT_NOTIFY_MULTIPLE\n"); + return ENOTSUP; +#endif +} + +int +cmd_gatt_clear_pending_notif(int argc, char **argv) +{ +#if MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) + return btshell_clear_pending_notif(); +#else + console_printf("To enable this features set BLE_GATT_NOTIFY_MULTIPLE\n"); + return ENOTSUP; +#endif +} diff --git a/apps/btshell/src/cmd_gatt.h b/apps/btshell/src/cmd_gatt.h index 70536d03ce..ae517f9a1c 100644 --- a/apps/btshell/src/cmd_gatt.h +++ b/apps/btshell/src/cmd_gatt.h @@ -35,5 +35,8 @@ int cmd_gatt_service_visibility(int argc, char **argv); int cmd_gatt_show(int argc, char **argv); int cmd_gatt_show_local(int argc, char **argv); int cmd_gatt_write(int argc, char **argv); +int cmd_gatt_enqueue_notif(int argc, char **argv); +int cmd_gatt_send_pending_notif(int argc, char **argv); +int cmd_gatt_clear_pending_notif(int argc, char **argv); #endif diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index 8224f42a5e..f29b98f75c 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -109,6 +109,11 @@ struct os_mbuf_pool sdu_os_mbuf_pool; static struct os_mempool sdu_coc_mbuf_mempool; #endif +#if MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) +static struct ble_gatt_notif pending_notif[BTSHELL_MAX_CHRS]; +static size_t pending_notif_cnt; +#endif + static struct os_callout btshell_tx_timer; struct btshell_tx_data_s { @@ -1814,6 +1819,79 @@ btshell_write_reliable(uint16_t conn_handle, return rc; } +#if MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) +int +btshell_enqueue_notif(uint16_t handle, uint16_t len, uint8_t *value) +{ + struct ble_gatt_notif *notify = NULL; + struct os_mbuf *val_ptr; + int i; + + for (i = 0; i < BTSHELL_MAX_CHRS; i++) { + if (pending_notif[i].handle == 0) { + notify = &pending_notif[i]; + break; + } + } + + if (notify == NULL) { + return ENOMEM; + } + + notify->handle = handle; + if (value != NULL) { + notify->value = os_msys_get(0, 0); + + val_ptr = os_mbuf_extend(notify->value, len); + if (val_ptr == NULL) { + return ENOMEM; + } + memcpy(val_ptr, value, len); + } + + pending_notif_cnt++; + + return 0; +} + +int +btshell_send_pending_notif(uint16_t conn_handle) +{ + int rc = 0; + int i; + + if (pending_notif_cnt == 0) { + return EALREADY; + } + + rc = ble_gatts_notify_multiple_custom(conn_handle, pending_notif_cnt, + pending_notif); + for (i = 0; i < pending_notif_cnt; i++) { + pending_notif[i].handle = 0; + pending_notif[i].value = NULL; + } + + pending_notif_cnt = 0; + + return rc; +} + +int +btshell_clear_pending_notif(void) +{ + int i; + + for (i = 0; i < pending_notif_cnt; i++) { + pending_notif[i].handle = 0; + pending_notif[i].value = NULL; + } + + pending_notif_cnt = 0; + + return 0; +} +#endif + #if MYNEWT_VAL(BLE_EXT_ADV) int btshell_ext_adv_configure(uint8_t instance, diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index a38d3c9345..dbd6c94b58 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -668,7 +668,7 @@ int ble_gatts_notify_custom(uint16_t conn_handle, uint16_t att_handle, * @return 0 on success; nonzero on failure. */ int ble_gatts_notify_multiple_custom(uint16_t conn_handle, - uint16_t chr_count, + size_t chr_count, struct ble_gatt_notif *tuples); /** @@ -719,7 +719,7 @@ int ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle); * @return 0 on success; nonzero on failure. */ int ble_gatts_notify_multiple(uint16_t conn_handle, - uint8_t num_handles, + size_t num_handles, const uint16_t *chr_val_handles); /** diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index d40adfd3c9..91f579c739 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -4415,7 +4415,7 @@ ble_gatts_notify(uint16_t conn_handle, uint16_t chr_val_handle) int ble_gatts_notify_multiple_custom(uint16_t conn_handle, - uint16_t chr_count, + size_t chr_count, struct ble_gatt_notif *tuples) { #if !MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) @@ -4507,7 +4507,7 @@ ble_gatts_notify_multiple_custom(uint16_t conn_handle, int ble_gatts_notify_multiple(uint16_t conn_handle, - uint8_t num_handles, + size_t num_handles, const uint16_t *chr_val_handles) { #if !MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) From 768a6c7165cff32d6a3410cac1f9e2121e57a13a Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 7 Feb 2024 12:51:45 +0530 Subject: [PATCH 0890/1333] nimble/host: Fix compilation issues observed by enabling -O2 optimization --- nimble/host/src/ble_gattc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index 91f579c739..be19f2dc9d 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -1509,7 +1509,7 @@ static int ble_gattc_disc_all_svcs_rx_adata(struct ble_gattc_proc *proc, struct ble_att_read_group_type_adata *adata) { - struct ble_gatt_svc service; + struct ble_gatt_svc service = {0}; int cbrc; int rc; From 02cfd92c29481ebaae99a674b9105d327d422715 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 6 Feb 2024 16:41:36 +0100 Subject: [PATCH 0891/1333] ci: Add GCC 13.2 to compilers test build workflow This will test code with latest version of ARM GCC. --- .github/workflows/build_cc_target.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_cc_target.yml b/.github/workflows/build_cc_target.yml index e76c809c60..a44f3e70c3 100644 --- a/.github/workflows/build_cc_target.yml +++ b/.github/workflows/build_cc_target.yml @@ -28,14 +28,14 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - gcc: ['12.2.Rel1', '11.3.Rel1', '10.3-2021.10', '9-2020-q2', '8-2019-q3'] + gcc: ['13.2.Rel1', '12.2.Rel1', '11.3.Rel1', '10.3-2021.10', '9-2020-q2', '8-2019-q3'] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: go-version: 'stable' - - uses: carlosperate/arm-none-eabi-gcc-action@48db4484a55750df7a0ccca63347fcdea6534d78 + - uses: carlosperate/arm-none-eabi-gcc-action@v1.8.1 with: release: ${{ matrix.gcc }} - name: Install newt From 33d069e5c5edd82e754d33d1c5d2c88418af93e1 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Wed, 7 Feb 2024 14:05:25 +0100 Subject: [PATCH 0892/1333] host/uuid: Amend doxygen comments in the header file Corrects variadic macro documentation (BLE_UUID128_INIT). Adds minor formatting improvements. --- nimble/host/include/host/ble_uuid.h | 30 ++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/nimble/host/include/host/ble_uuid.h b/nimble/host/include/host/ble_uuid.h index be96bb4227..16ba4157fa 100644 --- a/nimble/host/include/host/ble_uuid.h +++ b/nimble/host/include/host/ble_uuid.h @@ -135,7 +135,8 @@ typedef union { * * This macro initializes a 128-bit UUID with the provided value. * - * @param uuid128 The value of the 128-bit UUID. + * @param ... A sequence of values in little-endian order representing + * the 128-bit UUID. * * @return The initialized 128-bit UUID structure. */ @@ -148,7 +149,8 @@ typedef union { } /** - * @brief Macro for declaring a pointer to a 16-bit UUID structure initialized with a specific 16-bit UUID value. + * @brief Macro for declaring a pointer to a 16-bit UUID structure initialized + * with a specific 16-bit UUID value. * * @param uuid16 The 16-bit UUID value to initialize the structure with. * @@ -158,7 +160,8 @@ typedef union { ((ble_uuid_t *) (&(ble_uuid16_t) BLE_UUID16_INIT(uuid16))) /** - * @brief Macro for declaring a pointer to a 32-bit UUID structure initialized with a specific 32-bit UUID value. + * @brief Macro for declaring a pointer to a 32-bit UUID structure initialized + * with a specific 32-bit UUID value. * * @param uuid32 The 32-bit UUID value to initialize the structure with. * @@ -168,7 +171,8 @@ typedef union { ((ble_uuid_t *) (&(ble_uuid32_t) BLE_UUID32_INIT(uuid32))) /** - * @brief Macro for declaring a pointer to a 128-bit UUID structure initialized with specific 128-bit UUID values. + * @brief Macro for declaring a pointer to a 128-bit UUID structure initialized + * with specific 128-bit UUID values. * * @param uuid128 The 128-bit UUID value to initialize the structure with. * @@ -178,7 +182,8 @@ typedef union { ((ble_uuid_t *) (&(ble_uuid128_t) BLE_UUID128_INIT(uuid128))) /** - * @brief Macro for casting a pointer to a `ble_uuid_t` structure to a pointer to 16-bit UUID structure. + * @brief Macro for casting a pointer to a `ble_uuid_t` structure to a pointer + * to 16-bit UUID structure. * * @param u Pointer to a `ble_uuid_t` structure. * @@ -188,7 +193,8 @@ typedef union { ((ble_uuid16_t *) (u)) /** - * @brief Macro for casting a pointer to a `ble_uuid_t` structure to a pointer to 32-bit UUID structure. + * @brief Macro for casting a pointer to a `ble_uuid_t` structure to a pointer + * to 32-bit UUID structure. * * @param u Pointer to a `ble_uuid_t` structure. * @@ -198,7 +204,8 @@ typedef union { ((ble_uuid32_t *) (u)) /** - * @brief Macro for casting a pointer to a `ble_uuid_t` structure to a pointer to 128-bit UUID structure. + * @brief Macro for casting a pointer to a `ble_uuid_t` structure to a pointer + * to 128-bit UUID structure. * * @param u Pointer to a `ble_uuid_t` structure. * @@ -218,8 +225,8 @@ typedef union { * @param buf The source buffer to parse. * @param len The size of the buffer, in bytes. * - * @return 0 on success, BLE_HS_EINVAL if the source buffer does not contain - * a valid UUID. + * @return 0 on success; + * BLE_HS_EINVAL if the source buffer does not contain a valid UUID. */ int ble_uuid_init_from_buf(ble_uuid_any_t *uuid, const void *buf, size_t len); @@ -228,7 +235,8 @@ int ble_uuid_init_from_buf(ble_uuid_any_t *uuid, const void *buf, size_t len); * @param uuid1 The first UUID to compare. * @param uuid2 The second UUID to compare. * - * @return 0 if the two UUIDs are equal, nonzero if the UUIDs differ. + * @return 0 if the two UUIDs are equal; + * nonzero if the UUIDs differ. */ int ble_uuid_cmp(const ble_uuid_t *uuid1, const ble_uuid_t *uuid2); @@ -289,4 +297,4 @@ uint16_t ble_uuid_u16(const ble_uuid_t *uuid); * @} */ -#endif /* _BLE_HOST_UUID_H */ +#endif /* H_BLE_UUID_ */ From ae9273d3af8ef7af4ad653b8eb6d92e6c21f6d6a Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Wed, 7 Feb 2024 15:02:46 +0100 Subject: [PATCH 0893/1333] host/hs_log: Amend doxygen comments in the header file Adds missing macro documentation (BLE_NPL_LOG_MODULE). Adds minor formatting improvements. --- nimble/host/include/host/ble_hs_log.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/nimble/host/include/host/ble_hs_log.h b/nimble/host/include/host/ble_hs_log.h index 3e1ded4cdd..1514a2ba5c 100644 --- a/nimble/host/include/host/ble_hs_log.h +++ b/nimble/host/include/host/ble_hs_log.h @@ -20,12 +20,6 @@ #ifndef H_BLE_HS_LOG_ #define H_BLE_HS_LOG_ -#ifndef BLE_NPL_LOG_MODULE -#define BLE_NPL_LOG_MODULE BLE_HS_LOG -#endif - -#include - /** * @file ble_hs_log.h * @@ -39,6 +33,13 @@ * @{ */ +#ifndef BLE_NPL_LOG_MODULE +/** Defines the logging module for NimBLE Porting Layer (NPL). */ +#define BLE_NPL_LOG_MODULE BLE_HS_LOG +#endif + +#include + #ifdef __cplusplus extern "C" { #endif @@ -103,4 +104,4 @@ void ble_hs_log_flat_buf(const void *data, int len); * @} */ -#endif +#endif /* H_BLE_HS_LOG_*/ From 4080f942f185fe5f52dff7fa5cb6169dfc29769d Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Tue, 23 Jan 2024 16:12:54 +0100 Subject: [PATCH 0894/1333] babblesim: Fix build errors that occurred after recent updates (nordic-nrfx v3.3.0.) --- babblesim/core/include/core_cm4.h | 2 ++ babblesim/core/src/main_config.c | 4 +++- babblesim/edtt/hci_test/src/main.c | 13 ++----------- babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_timer.c | 4 +++- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/babblesim/core/include/core_cm4.h b/babblesim/core/include/core_cm4.h index ef8f9c3fb9..8b35f4a515 100644 --- a/babblesim/core/include/core_cm4.h +++ b/babblesim/core/include/core_cm4.h @@ -17,6 +17,8 @@ extern void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority); extern void NVIC_EnableIRQ(IRQn_Type IRQn); extern void NVIC_DisableIRQ(IRQn_Type IRQn); +extern void NVIC_SetPendingIRQ(IRQn_Type IRQn); +extern void NVIC_ClearPendingIRQ(IRQn_Type IRQn); void __WFI(void); diff --git a/babblesim/core/src/main_config.c b/babblesim/core/src/main_config.c index 467ae6234b..39a03c3cd5 100644 --- a/babblesim/core/src/main_config.c +++ b/babblesim/core/src/main_config.c @@ -23,6 +23,8 @@ uint global_device_nbr; struct nrf52_bsim_args_t *args; +extern int mynewt_main(int argc, char **argv); + void bst_tick(bs_time_t time) { @@ -46,7 +48,7 @@ main_clean_up_trace_wrap(void) return inner_main_clean_up(0); } -void +int main(int argc, char** argv) { setvbuf(stdout, NULL, _IOLBF, 512); diff --git a/babblesim/edtt/hci_test/src/main.c b/babblesim/edtt/hci_test/src/main.c index 0ca152cfc2..43ef621264 100644 --- a/babblesim/edtt/hci_test/src/main.c +++ b/babblesim/edtt/hci_test/src/main.c @@ -22,8 +22,8 @@ #include "os/mynewt.h" #include "ble_hci_edtt.h" -static int -main_fn(int argc, char **argv) +int +mynewt_main(int argc, char **argv) { sysinit(); @@ -34,12 +34,3 @@ main_fn(int argc, char **argv) } return 0; } - -int -main(int argc, char **argv) -{ - extern void bsim_init(int argc, char** argv, void *main_fn); - bsim_init(argc, argv, main_fn); - - return 0; -} diff --git a/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_timer.c b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_timer.c index 0e3d914c98..a847e9b68a 100644 --- a/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_timer.c +++ b/babblesim/hw/mcu/nordic/nrf52_bsim/src/hal_timer.c @@ -663,7 +663,9 @@ hal_timer_config(int timer_num, uint32_t freq_hz) nrf_timer_task_trigger(hwtimer, NRF_TIMER_TASK_CLEAR); /* Put the timer in timer mode using 32 bits. */ - nrf_timer_mode_set(hwtimer, NRF_TIMER_MODE_TIMER); + hwtimer->MODE = (hwtimer->MODE & ~TIMER_MODE_MODE_Msk) | + ((NRF_TIMER_MODE_TIMER << TIMER_MODE_MODE_Pos) & + TIMER_MODE_MODE_Msk); hwtimer->BITMODE = TIMER_BITMODE_BITMODE_32Bit; /* Set the pre-scalar */ From d42a0ebe6632bd0c318560e4293a522634f60594 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 29 Jan 2024 16:28:12 +0100 Subject: [PATCH 0895/1333] nimble/host: Fix disconnect on host connection timeout We don't need to have double loop and lock-unlock host lock when issuing disconnect. ble_gap_terminate_with_conn() can be used to disconnect and it can be called with already provided conn object under host lock. --- nimble/host/src/ble_hs_conn.c | 111 +++++++++++++++------------------- 1 file changed, 49 insertions(+), 62 deletions(-) diff --git a/nimble/host/src/ble_hs_conn.c b/nimble/host/src/ble_hs_conn.c index 9b7bdbb3d0..57ba16af87 100644 --- a/nimble/host/src/ble_hs_conn.c +++ b/nimble/host/src/ble_hs_conn.c @@ -477,86 +477,73 @@ ble_hs_conn_timer(void) #endif struct ble_hs_conn *conn; - ble_npl_time_t now; - int32_t next_exp_in; + ble_npl_time_t now = ble_npl_time_get(); + int32_t next_exp_in = BLE_HS_FOREVER; + int32_t next_exp_in_new; + bool next_exp_in_updated; int32_t time_diff; - uint16_t conn_handle; - for (;;) { - conn_handle = BLE_HS_CONN_HANDLE_NONE; - next_exp_in = BLE_HS_FOREVER; - now = ble_npl_time_get(); + ble_hs_lock(); - ble_hs_lock(); - - /* This loop performs one of two tasks: - * 1. Determine if any connections need to be terminated due to timeout. - * If so, break out of the loop and terminate the connection. This - * function will need to be executed again. - * 2. Otherwise, determine when the next timeout will occur. - */ - SLIST_FOREACH(conn, &ble_hs_conns, bhc_next) { - if (!(conn->bhc_flags & BLE_HS_CONN_F_TERMINATING)) { + /* This loop performs one of two tasks: + * 1. Determine if any connections need to be terminated due to timeout. If + * so connection is disconnected. + * 2. Otherwise, determine when the next timeout will occur. + */ + SLIST_FOREACH(conn, &ble_hs_conns, bhc_next) { + if (!(conn->bhc_flags & BLE_HS_CONN_F_TERMINATING)) { + next_exp_in_updated = false; #if MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT) != 0 - /* Check each connection's rx fragment timer. If too much time - * passes after a partial packet is received, the connection is - * terminated. - */ - if (conn->bhc_rx_chan != NULL) { - time_diff = conn->bhc_rx_timeout - now; - - if (time_diff <= 0) { - /* ACL reassembly has timed out. Remember the connection - * handle so it can be terminated after the mutex is - * unlocked. - */ - conn_handle = conn->bhc_handle; - break; - } - - /* Determine if this connection is the soonest to time out. */ - if (time_diff < next_exp_in) { - next_exp_in = time_diff; - } - } -#endif + /* Check each connection's rx fragment timer. If too much time + * passes after a partial packet is received, the connection is + * terminated. + */ + if (conn->bhc_rx_chan != NULL) { + time_diff = conn->bhc_rx_timeout - now; -#if BLE_HS_ATT_SVR_QUEUED_WRITE_TMO - /* Check each connection's rx queued write timer. If too much - * time passes after a prep write is received, the queue is - * cleared. - */ - time_diff = ble_att_svr_ticks_until_tmo(&conn->bhc_att_svr, now); if (time_diff <= 0) { - /* ACL reassembly has timed out. Remember the connection - * handle so it can be terminated after the mutex is - * unlocked. - */ - conn_handle = conn->bhc_handle; - break; + /* ACL reassembly has timed out.*/ + ble_gap_terminate_with_conn(conn, BLE_ERR_REM_USER_CONN_TERM); + continue; } /* Determine if this connection is the soonest to time out. */ if (time_diff < next_exp_in) { - next_exp_in = time_diff; + next_exp_in_new = time_diff; + next_exp_in_updated = true; } + } #endif + +#if BLE_HS_ATT_SVR_QUEUED_WRITE_TMO + /* Check each connection's rx queued write timer. If too much + * time passes after a prep write is received, the queue is + * cleared. + */ + time_diff = ble_att_svr_ticks_until_tmo(&conn->bhc_att_svr, now); + if (time_diff <= 0) { + /* Queued write has timed out.*/ + ble_gap_terminate_with_conn(conn, BLE_ERR_REM_USER_CONN_TERM); + continue; } - } - ble_hs_unlock(); + /* Determine if this connection is the soonest to time out. */ + if (time_diff < next_exp_in) { + next_exp_in_new = time_diff; + next_exp_in_updated = true; + } +#endif - /* If a connection has timed out, terminate it. We need to repeatedly - * call this function again to determine when the next timeout is. - */ - if (conn_handle != BLE_HS_CONN_HANDLE_NONE) { - ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM); - continue; + if (next_exp_in_updated) { + next_exp_in = next_exp_in_new; + } } - - return next_exp_in; } + + ble_hs_unlock(); + + return next_exp_in; } int From b27535edbc5f8e1bd60824fbe48c1de1014143ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 15 Feb 2024 10:11:52 +0100 Subject: [PATCH 0896/1333] host/ble_iso.h: remove unused functions ble_gap_rx_create_big_complete and ble_gap_rx_terminate_big_complete are a leftover from initial implementation and shall be removed. Correct, implemented funcions are ble_iso_rx_create_big_complete and ble_iso_rx_terminate_big_completem, in private API --- nimble/host/include/host/ble_iso.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/nimble/host/include/host/ble_iso.h b/nimble/host/include/host/ble_iso.h index 44877dca68..0d2ddbb11f 100644 --- a/nimble/host/include/host/ble_iso.h +++ b/nimble/host/include/host/ble_iso.h @@ -109,14 +109,6 @@ int ble_iso_create_big(const struct ble_iso_create_big_params *create_params, int ble_iso_terminate_big(uint8_t big_id); -void -ble_gap_rx_create_big_complete(const struct - ble_hci_ev_le_subev_create_big_complete *ev); -void -ble_gap_rx_terminate_big_complete(const struct - ble_hci_ev_le_subev_terminate_big_complete - *ev); - int ble_iso_tx(uint16_t conn_handle, void *data, uint16_t data_len); int ble_iso_init(void); From 20c55b223be145659a9a69caf644acbfbb8c370b Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Wed, 14 Feb 2024 16:47:43 +0100 Subject: [PATCH 0897/1333] host/audio_broadcast: Amend doxygen comments in the header file Adds missing structures and functions documentation. Corrects usage of 'param' tags. --- .../host/include/host/ble_audio_broadcast.h | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/nimble/host/include/host/ble_audio_broadcast.h b/nimble/host/include/host/ble_audio_broadcast.h index acfc5734ec..9a9fecc7cc 100644 --- a/nimble/host/include/host/ble_audio_broadcast.h +++ b/nimble/host/include/host/ble_audio_broadcast.h @@ -20,11 +20,22 @@ #ifndef H_BLE_AUDIO_BROADCAST_ #define H_BLE_AUDIO_BROADCAST_ +/** + * @file ble_audio_broadcast.h + * + * @brief Bluetooth Low Energy Audio Broadcast API + * + * @defgroup bt_le_audio_broadcast Bluetooth LE Audio Broadcast + * @ingroup bt_host + * @{ + */ + #include #include "host/ble_gap.h" #include "host/ble_iso.h" #include "host/ble_audio_common.h" +/** Parameters used for creating BASE configuration. */ struct ble_broadcast_create_params { /** Broadcast Audio Source Endpoint */ struct ble_audio_base *base; @@ -54,6 +65,7 @@ struct ble_broadcast_create_params { uint16_t svc_data_len; }; +/** Parameters used for updating BASE configuration. */ struct ble_broadcast_update_params { /** Broadcast name - null terminated. * Set NULL to not include in advertising @@ -73,6 +85,7 @@ struct ble_broadcast_update_params { uint32_t broadcast_id; }; +/** Function prototype for broadcast destroy callback. */ typedef int ble_audio_broadcast_destroy_fn(struct ble_audio_base *base, void *args); @@ -182,7 +195,7 @@ struct ble_broadcast_subgroup_params { * structure. Created subgroup extends subgroup list in provided BASE. * This function increases `num_subgroups` in BASE structure. * - * @param[in/out] base Pointer to a `ble_audio_base` structure, + * @param[in,out] base Pointer to a `ble_audio_base` structure, * that will be extended by the new subgroup. * In case of error, filled out data may be * erroneous. @@ -221,7 +234,7 @@ struct ble_broadcast_bis_params { * structure. Created BIS extends BIS list in provided subgroup. * This function increases `bis_cnt` in subgroup structure. * - * @param[in/out] subgroup Pointer to a updated `ble_audio_big_subgroup` + * @param[in,out] subgroup Pointer to a updated `ble_audio_big_subgroup` * structure, that will be extended by the new * BIS. In case of error, filled out data may be * erroneous. @@ -241,5 +254,15 @@ int ble_audio_broadcast_build_bis(struct ble_audio_big_subgroup *subgroup, const struct ble_broadcast_bis_params *params); +/** + * Initializes memory for LE Audio Broadcast. + * + * @return 0 on success + */ int ble_audio_broadcast_init(void); -#endif + +/** + * @} + */ + +#endif /* H_BLE_AUDIO_BROADCAST_*/ From 60aab30a594007df071993d83a920dd005808aec Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 16 Feb 2024 17:31:10 +0100 Subject: [PATCH 0898/1333] ci: Use latest RAT release RAT 0.16.1 was released so we no longer need to use snapshots for SPDX support. --- .github/workflows/compliance_check.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index c76225a8e6..9b2ee76315 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -51,15 +51,11 @@ jobs: - name: Install Dependencies shell: bash run: | - sudo apt-get update - sudo apt-get install -y libxml2-utils mkdir repos git clone --depth=1 https://github.com/apache/mynewt-core repos/apache-mynewt-core - wget https://repository.apache.org/content/repositories/snapshots/org/apache/rat/apache-rat/maven-metadata.xml -O snapshot.xml - SNAPSHOT=`xmllint --xpath "//latest/text()" snapshot.xml` - wget https://repository.apache.org/content/repositories/snapshots/org/apache/rat/apache-rat/$SNAPSHOT/maven-metadata.xml -O version.xml - VERSION=`xmllint --xpath "//snapshotVersion[1]/value/text()" version.xml` - wget https://repository.apache.org/content/repositories/snapshots/org/apache/rat/apache-rat/$SNAPSHOT/apache-rat-$VERSION.jar -O apache-rat.jar + wget https://dlcdn.apache.org//creadur/apache-rat-0.16.1/apache-rat-0.16.1-bin.tar.gz + tar zxf apache-rat-0.16.1-bin.tar.gz apache-rat-0.16.1/apache-rat-0.16.1.jar + mv apache-rat-0.16.1/apache-rat-0.16.1.jar apache-rat.jar - name: check licensing shell: bash run: | From 818e06400ad161facaa41a21678fa47e77dd0d4e Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 12 Jan 2024 16:52:44 +0100 Subject: [PATCH 0899/1333] nimble/phy: Fix compilation error This fixes compilation error caused by value assignment to undefined structure aux_data member. Introduced in 4e58b2724. --- nimble/drivers/native/src/ble_phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/drivers/native/src/ble_phy.c b/nimble/drivers/native/src/ble_phy.c index 4609c2864b..c38e6c8fc3 100644 --- a/nimble/drivers/native/src/ble_phy.c +++ b/nimble/drivers/native/src/ble_phy.c @@ -281,7 +281,7 @@ ble_phy_isr(void) ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan; ble_hdr->rxinfo.phy = BLE_PHY_1M; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - ble_hdr->rxinfo.aux_data = NULL; + ble_hdr->rxinfo.user_data = NULL; #endif /* Count PHY valid packets */ From 13426932440106510d502525d53205e2c56af5eb Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Thu, 8 Feb 2024 11:53:32 +0100 Subject: [PATCH 0900/1333] host/gatt: Amend doxygen comments in the header file Adds missing functions documentation. Adds minor formatting improvements. --- nimble/host/include/host/ble_gatt.h | 31 +++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index dbd6c94b58..1492b1aad6 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -510,6 +510,20 @@ int ble_gattc_read_mult(uint16_t conn_handle, const uint16_t *handles, uint8_t num_handles, ble_gatt_attr_fn *cb, void *cb_arg); +/** + * Initiates GATT procedure: Read Multiple Variable Length Characteristic Values. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param handles An array of 16-bit attribute handles to read. + * @param num_handles The number of entries in the "handles" array. + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ int ble_gattc_read_mult_var(uint16_t conn_handle, const uint16_t *handles, uint8_t num_handles, ble_gatt_attr_mult_fn *cb, void *cb_arg); @@ -1142,18 +1156,19 @@ int ble_gatts_start(void); /** * Gets Client Supported Features for specified connection. * - * @param conn_handle Connection handle identifying connection for - * which Client Supported Features should be saved + * @param conn_handle Connection handle identifying the connection for + * which Client Supported Features should be saved * @param out_supported_feat Client supported features to be returned. + * @param len The size of the Client Supported Features + * characteristic in octets. * * @return 0 on success; * BLE_HS_ENOTCONN if no matching connection - * was found + * was found * BLE_HS_EINVAL if supplied buffer is empty or - * if any Client Supported Feature was - * attempted to be disabled. - * A BLE host core return code on unexpected - * error. + * if any Client Supported Feature was + * attempted to be disabled. + * A BLE host core return code on unexpected error. * */ int ble_gatts_peer_cl_sup_feat_get(uint16_t conn_handle, uint8_t *out_supported_feat, uint8_t len); @@ -1166,4 +1181,4 @@ int ble_gatts_peer_cl_sup_feat_get(uint16_t conn_handle, uint8_t *out_supported_ * @} */ -#endif +#endif /* H_BLE_GATT_ */ From 620064e69d47c01be8b31765de8184eed31a86ce Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Tue, 16 Jan 2024 11:02:36 +0100 Subject: [PATCH 0901/1333] nimble/gap: Fix for resolving list peer removal This commit aims to fix an issue where deleting peer from resolving list would fail due to lack of IRK on the list. --- nimble/host/src/ble_gap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 85d7a9e4cc..8c63610c68 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -6202,7 +6202,12 @@ ble_gap_unpair(const ble_addr_t *peer_addr) rc = ble_hs_pvcy_remove_entry(peer_addr->type, peer_addr->val); - if (rc != 0) { + + /* We allow BLE_ERR_UNK_CONN_ID as the IRK of the peer might not be + * present on the resolving list, but we still should be able to + * remove that entry. + */ + if (rc != 0 && rc != (BLE_HS_ERR_HCI_BASE + BLE_ERR_UNK_CONN_ID)) { return rc; } From e9b1fcf4713910ee9621618210f5d6ab2d719882 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 22 Jan 2024 20:25:33 +0100 Subject: [PATCH 0902/1333] apps/btshell: Fix print format specifier This fixes format specifer for printing CoC channel pointer. --- apps/btshell/src/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index f29b98f75c..27838063fc 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -2374,8 +2374,8 @@ btshell_l2cap_coc_remove(uint16_t conn_handle, struct ble_l2cap_chan *chan) static void btshell_l2cap_coc_recv(struct ble_l2cap_chan *chan, struct os_mbuf *sdu) { - console_printf("LE CoC SDU received, chan: 0x%08lx, data len %d\n", - (uint32_t) chan, OS_MBUF_PKTLEN(sdu)); + console_printf("LE CoC SDU received, chan: %p, data len %d\n", + chan, OS_MBUF_PKTLEN(sdu)); os_mbuf_free_chain(sdu); sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); @@ -2393,8 +2393,8 @@ btshell_l2cap_coc_accept(uint16_t conn_handle, uint16_t peer_mtu, struct os_mbuf *sdu_rx; int rc; - console_printf("LE CoC accepting, chan: 0x%08lx, peer_mtu %d\n", - (uint32_t) chan, peer_mtu); + console_printf("LE CoC accepting, chan: %p, peer_mtu %d\n", + chan, peer_mtu); for (int i = 0; i < MYNEWT_VAL(BLE_L2CAP_COC_SDU_BUFF_COUNT); i++) { sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0); From adfa1b8127478abc7f359215324e572c9117cab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 19 Feb 2024 14:05:58 +0100 Subject: [PATCH 0903/1333] host/ble_audio_broadcast: add clarification for big_params pointer Added clarification for `big_params` pointer in `ble_broadcast_create_params`. --- nimble/host/include/host/ble_audio_broadcast.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nimble/host/include/host/ble_audio_broadcast.h b/nimble/host/include/host/ble_audio_broadcast.h index 9a9fecc7cc..13c17433d9 100644 --- a/nimble/host/include/host/ble_audio_broadcast.h +++ b/nimble/host/include/host/ble_audio_broadcast.h @@ -55,7 +55,9 @@ struct ble_broadcast_create_params { /** Advertising instance */ uint8_t adv_instance; - /** BIG parameters */ + /** BIG parameters. These parameters are not copied and shall be valid for the lifetime + * of the broadcast. + */ struct ble_iso_big_params *big_params; /** Additional data to include in Extended Advertising */ From c102b8b246367033f642f59b00f222d93464e5f3 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 23 Jan 2024 08:17:51 +0100 Subject: [PATCH 0904/1333] nimble/drivers/native: Add missing function stubs This fixes unit test compilation error caused by missing ble_phy_tifs_txtx_set() and ble_phy_encrypt_header_mask_set() function stubs used by ble_ll_iso_big.c and ble_ll_isoal.c. --- nimble/drivers/native/src/ble_phy.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/nimble/drivers/native/src/ble_phy.c b/nimble/drivers/native/src/ble_phy.c index c38e6c8fc3..5969dff1b6 100644 --- a/nimble/drivers/native/src/ble_phy.c +++ b/nimble/drivers/native/src/ble_phy.c @@ -347,6 +347,11 @@ ble_phy_encrypt_enable(const uint8_t *key) { } +void +ble_phy_encrypt_header_mask_set(uint8_t mask) +{ +} + void ble_phy_encrypt_iv_set(const uint8_t *iv) { @@ -651,3 +656,8 @@ void ble_phy_rfclk_disable(void) { } + +void +ble_phy_tifs_txtx_set(uint16_t usecs, uint8_t anchor) +{ +} From 0b59865e3a155fed5f8b4726214f92696d198d9f Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 21 Feb 2024 10:11:03 +0100 Subject: [PATCH 0905/1333] porting: Don't include logcfg in ports logcfg is not used in porting anymore. --- porting/update_generated_files.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/porting/update_generated_files.sh b/porting/update_generated_files.sh index 6309ed2b2e..006498e2fe 100755 --- a/porting/update_generated_files.sh +++ b/porting/update_generated_files.sh @@ -33,6 +33,8 @@ declare -A targets=( for target in "${!targets[@]}"; do echo "Updating target $target" newt build "@apache-mynewt-nimble/porting/targets/$target" > /dev/null 2>&1 + # logcfg is not used in ports + rm -rf "bin/@apache-mynewt-nimble/porting/targets/${target}/generated/include/logcfg" cp "bin/@apache-mynewt-nimble/porting/targets/${target}/generated/include" "${targets[$target]}" -r # Remove repo version and hash MYNEWT_VALS as it doesn't make much sense to commit them and they # defeat the purpose of this script. From 0abf84dc70a2dabbee6a7249a9e71ad1e48f0254 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 21 Feb 2024 10:11:46 +0100 Subject: [PATCH 0906/1333] porting: Use mynewt_main in sample app This app is used to update syscfg for ports. --- porting/targets/dummy_app/src/dummy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porting/targets/dummy_app/src/dummy.c b/porting/targets/dummy_app/src/dummy.c index 0bd431fd99..a54c7fc94c 100644 --- a/porting/targets/dummy_app/src/dummy.c +++ b/porting/targets/dummy_app/src/dummy.c @@ -20,7 +20,7 @@ #pragma message ( "This will probably not compile. Used to generate syscfg.h file and other artifacts." ) int -main(void) +mynewt_main(void) { return 0; } From eeceff90f3f39d56c4c4bb1ab446cecb26efb00d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 21 Feb 2024 10:12:44 +0100 Subject: [PATCH 0907/1333] nimble/ports: Refresh syscfg --- porting/examples/linux/include/syscfg/syscfg.h | 8 ++++++++ porting/examples/linux_blemesh/include/syscfg/syscfg.h | 8 ++++++++ porting/examples/nuttx/include/syscfg/syscfg.h | 8 ++++++++ porting/nimble/include/syscfg/syscfg.h | 8 ++++++++ porting/npl/riot/include/syscfg/syscfg.h | 9 +++++++++ 5 files changed, 41 insertions(+) diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index 85697d5f9e..9489ae1575 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -180,6 +180,10 @@ #define MYNEWT_VAL_OS_DEBUG_MODE (0) #endif +#ifndef MYNEWT_VAL_OS_DEFAULT_IRQ_CB +#define MYNEWT_VAL_OS_DEFAULT_IRQ_CB (0) +#endif + #ifndef MYNEWT_VAL_OS_EVENTQ_DEBUG #define MYNEWT_VAL_OS_EVENTQ_DEBUG (0) #endif @@ -647,6 +651,10 @@ #define MYNEWT_VAL_BLE_GATT_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE +#define MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE ((MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ #define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 750334d954..64ed645eb1 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -181,6 +181,10 @@ #define MYNEWT_VAL_OS_DEBUG_MODE (0) #endif +#ifndef MYNEWT_VAL_OS_DEFAULT_IRQ_CB +#define MYNEWT_VAL_OS_DEFAULT_IRQ_CB (0) +#endif + #ifndef MYNEWT_VAL_OS_EVENTQ_DEBUG #define MYNEWT_VAL_OS_EVENTQ_DEBUG (0) #endif @@ -648,6 +652,10 @@ #define MYNEWT_VAL_BLE_GATT_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE +#define MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE ((MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ #define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index 0f599f7be4..74e67dafd9 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -180,6 +180,10 @@ #define MYNEWT_VAL_OS_DEBUG_MODE (0) #endif +#ifndef MYNEWT_VAL_OS_DEFAULT_IRQ_CB +#define MYNEWT_VAL_OS_DEFAULT_IRQ_CB (0) +#endif + #ifndef MYNEWT_VAL_OS_EVENTQ_DEBUG #define MYNEWT_VAL_OS_EVENTQ_DEBUG (0) #endif @@ -647,6 +651,10 @@ #define MYNEWT_VAL_BLE_GATT_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE +#define MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE ((MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ #define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index ed59c0eada..b53057a243 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -180,6 +180,10 @@ #define MYNEWT_VAL_OS_DEBUG_MODE (0) #endif +#ifndef MYNEWT_VAL_OS_DEFAULT_IRQ_CB +#define MYNEWT_VAL_OS_DEFAULT_IRQ_CB (0) +#endif + #ifndef MYNEWT_VAL_OS_EVENTQ_DEBUG #define MYNEWT_VAL_OS_EVENTQ_DEBUG (0) #endif @@ -646,6 +650,10 @@ #define MYNEWT_VAL_BLE_GATT_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE +#define MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE ((MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ #define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 4b8cde70e6..a4ba6c35b8 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -171,6 +171,7 @@ #define MYNEWT_VAL_MCU_I2C_RECOVERY_DELAY_USEC (100) #endif +/* Overridden by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_MCU_ICACHE_ENABLED #define MYNEWT_VAL_MCU_ICACHE_ENABLED (1) #endif @@ -583,6 +584,10 @@ #define MYNEWT_VAL_OS_DEBUG_MODE (0) #endif +#ifndef MYNEWT_VAL_OS_DEFAULT_IRQ_CB +#define MYNEWT_VAL_OS_DEFAULT_IRQ_CB (0) +#endif + #ifndef MYNEWT_VAL_OS_EVENTQ_DEBUG #define MYNEWT_VAL_OS_EVENTQ_DEBUG (0) #endif @@ -1562,6 +1567,10 @@ #define MYNEWT_VAL_BLE_GATT_NOTIFY (1) #endif +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE +#define MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE ((MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ #define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif From 365468bfeceac62fc1ca7c8bd6a63a56d33974ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 18 Dec 2023 12:30:19 +0100 Subject: [PATCH 0908/1333] nimble/host: prepare for Broadcast sink This patch renames files, functions and configs from `broadcaster` to `broadcast source` so new `broadcast sink` files and functions can be created. Adds `BLE_ISO_BROADCAST_SINK` sysconfig --- .github/test_build_apps_syscfg.yml | 2 +- apps/auracast/syscfg.yml | 2 +- apps/btshell/src/btshell.h | 6 +++--- apps/btshell/src/cmd.c | 2 +- apps/btshell/src/cmd_leaudio.c | 4 ++-- apps/btshell/src/main.c | 8 ++++---- apps/leaudio_broadcaster/src/main.c | 2 +- apps/leaudio_broadcaster/syscfg.yml | 2 +- nimble/controller/syscfg.yml | 2 +- ..._audio_broadcast.h => ble_audio_broadcast_source.h} | 4 ++-- nimble/host/include/host/ble_audio_common.h | 1 + .../include/services/auracast/ble_svc_auracast.h | 2 +- nimble/host/services/auracast/src/ble_svc_auracast.c | 5 +++-- ..._audio_broadcast.c => ble_audio_broadcast_source.c} | 4 ++-- nimble/host/src/ble_hs.c | 4 ++-- nimble/host/src/ble_hs_hci_evt.c | 6 +++--- nimble/host/syscfg.yml | 4 ++-- nimble/syscfg.yml | 10 ++++++++-- porting/examples/linux/include/syscfg/syscfg.h | 8 ++++++-- porting/examples/linux_blemesh/include/syscfg/syscfg.h | 8 ++++++-- porting/examples/nuttx/include/syscfg/syscfg.h | 8 ++++++-- porting/nimble/include/syscfg/syscfg.h | 8 ++++++-- porting/npl/riot/include/syscfg/syscfg.h | 10 +++++++--- .../nordic_pca10095_net-blehci_broadcaster/syscfg.yml | 2 +- 24 files changed, 71 insertions(+), 43 deletions(-) rename nimble/host/include/host/{ble_audio_broadcast.h => ble_audio_broadcast_source.h} (99%) rename nimble/host/src/{ble_audio_broadcast.c => ble_audio_broadcast_source.c} (99%) diff --git a/.github/test_build_apps_syscfg.yml b/.github/test_build_apps_syscfg.yml index 44bcb5efe9..faafa8a3cb 100644 --- a/.github/test_build_apps_syscfg.yml +++ b/.github/test_build_apps_syscfg.yml @@ -27,7 +27,7 @@ syscfg.vals: BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: 1 BLE_ISO: 1 BLE_ISO_TEST: 1 - BLE_ISO_BROADCASTER: 1 + BLE_ISO_BROADCAST_SOURCE: 1 BLE_HCI_VS: 1 BLE_POWER_CONTROL: 1 BLE_CONN_SUBRATING: 1 diff --git a/apps/auracast/syscfg.yml b/apps/auracast/syscfg.yml index 26dbc8da85..e67af5a00c 100644 --- a/apps/auracast/syscfg.yml +++ b/apps/auracast/syscfg.yml @@ -55,7 +55,7 @@ syscfg.vals: BLE_VERSION: 54 BLE_ISO: 1 - BLE_ISO_BROADCASTER: 1 + BLE_ISO_BROADCAST_SOURCE: 1 BLE_MAX_BIG: 1 BLE_MAX_BIS: 2 diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h index d7beb14903..83dadede5a 100644 --- a/apps/btshell/src/btshell.h +++ b/apps/btshell/src/btshell.h @@ -28,8 +28,8 @@ #include "host/ble_gatt.h" #include "host/ble_gap.h" -#if (MYNEWT_VAL(BLE_ISO_BROADCASTER)) -#include "host/ble_audio_broadcast.h" +#if (MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)) +#include "host/ble_audio_broadcast_source.h" #endif #ifdef __cplusplus @@ -191,7 +191,7 @@ int btshell_l2cap_send(uint16_t conn, uint16_t idx, uint16_t bytes); int btshell_l2cap_reconfig(uint16_t conn_handle, uint16_t mtu, uint8_t num, uint8_t idxs[]); -#if (MYNEWT_VAL(BLE_ISO_BROADCASTER)) +#if (MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)) int btshell_broadcast_base_add(uint8_t adv_instance, uint32_t presentation_delay); int btshell_broadcast_big_sub_add(uint8_t adv_instance, uint8_t codec_fmt, diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index f23c4b9234..ff8bae8c75 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -4206,7 +4206,7 @@ static const struct shell_cmd_help sync_stats_help = { #endif #endif -#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) #if MYNEWT_VAL(SHELL_CMD_HELP) static const struct shell_param leaudio_base_add_params[] = { {"adv_instance", "Advertising instance, usage: ="}, diff --git a/apps/btshell/src/cmd_leaudio.c b/apps/btshell/src/cmd_leaudio.c index bdbc825843..fc4fcd17a2 100644 --- a/apps/btshell/src/cmd_leaudio.c +++ b/apps/btshell/src/cmd_leaudio.c @@ -17,13 +17,13 @@ * under the License. */ -#include "host/ble_audio_broadcast.h" +#include "host/ble_audio_broadcast_source.h" #include "cmd_leaudio.h" #include "btshell.h" #include "console/console.h" #include "errno.h" -#if (MYNEWT_VAL(BLE_ISO_BROADCASTER)) +#if (MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)) int cmd_leaudio_base_add(int argc, char **argv) { diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index 27838063fc..0f87b5c236 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -42,7 +42,7 @@ #include "host/ble_store.h" #include "host/ble_sm.h" #include "host/ble_audio_common.h" -#include "host/ble_audio_broadcast.h" +#include "host/ble_audio_broadcast_source.h" #include "host/util/util.h" /* Mandatory services. */ @@ -130,7 +130,7 @@ int btshell_full_disc_prev_chr_val; struct ble_sm_sc_oob_data oob_data_local; struct ble_sm_sc_oob_data oob_data_remote; -#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) static struct {struct ble_audio_base *base; uint8_t adv_instance;} btshell_base_list[MYNEWT_VAL(BLE_MAX_BIG)]; @@ -2749,7 +2749,7 @@ btshell_get_default_own_addr_type(void) return default_own_addr_type; } -#if (MYNEWT_VAL(BLE_ISO_BROADCASTER)) +#if (MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)) static int btshell_base_find_free(void) { @@ -3068,7 +3068,7 @@ mynewt_main(int argc, char **argv) "btshell_coc_conn_pool"); assert(rc == 0); #endif -#if (MYNEWT_VAL(BLE_ISO_BROADCASTER)) +#if (MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)) rc = os_mempool_init(&btshell_base_pool, MYNEWT_VAL(BLE_MAX_BIG), sizeof(struct ble_audio_base), btshell_base_mem, diff --git a/apps/leaudio_broadcaster/src/main.c b/apps/leaudio_broadcaster/src/main.c index 5ea818e36d..a4e7bf98ea 100644 --- a/apps/leaudio_broadcaster/src/main.c +++ b/apps/leaudio_broadcaster/src/main.c @@ -24,7 +24,7 @@ #include "host/ble_hs.h" #include "host/util/util.h" -#include "host/ble_audio_broadcast.h" +#include "host/ble_audio_broadcast_source.h" #include "host/ble_audio_common.h" #include "host/ble_iso.h" diff --git a/apps/leaudio_broadcaster/syscfg.yml b/apps/leaudio_broadcaster/syscfg.yml index 7fc1873376..bed16f05d2 100644 --- a/apps/leaudio_broadcaster/syscfg.yml +++ b/apps/leaudio_broadcaster/syscfg.yml @@ -53,7 +53,7 @@ syscfg.vals: BLE_VERSION: 54 BLE_ISO: 1 - BLE_ISO_BROADCASTER: 1 + BLE_ISO_BROADCAST_SOURCE: 1 BLE_MAX_BIG: 1 BLE_MAX_BIS: 2 diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 22a4c1b57c..c55107bcb1 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -483,7 +483,7 @@ syscfg.defs: Enable support for Isochronous Broadcasting state. restrictions: - BLE_LL_ISO if 1 - value: MYNEWT_VAL(BLE_ISO_BROADCASTER) + value: MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) state: experimental BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS: description: > diff --git a/nimble/host/include/host/ble_audio_broadcast.h b/nimble/host/include/host/ble_audio_broadcast_source.h similarity index 99% rename from nimble/host/include/host/ble_audio_broadcast.h rename to nimble/host/include/host/ble_audio_broadcast_source.h index 13c17433d9..605aa5b207 100644 --- a/nimble/host/include/host/ble_audio_broadcast.h +++ b/nimble/host/include/host/ble_audio_broadcast_source.h @@ -17,8 +17,8 @@ * under the License. */ -#ifndef H_BLE_AUDIO_BROADCAST_ -#define H_BLE_AUDIO_BROADCAST_ +#ifndef H_BLE_AUDIO_BROADCAST_SOURCE_ +#define H_BLE_AUDIO_BROADCAST_SOURCE_ /** * @file ble_audio_broadcast.h diff --git a/nimble/host/include/host/ble_audio_common.h b/nimble/host/include/host/ble_audio_common.h index 43f88ea2ba..d5e0afb68c 100644 --- a/nimble/host/include/host/ble_audio_common.h +++ b/nimble/host/include/host/ble_audio_common.h @@ -47,6 +47,7 @@ __VA_ARGS__) #define BLE_BROADCAST_AUDIO_ANNOUNCEMENT_SVC_UUID 0x1852 +#define BLE_BROADCAST_PUBLIC_BROADCAST_ANNOUNCEMENT_SVC_UUID 0x1856 #define BLE_AUDIO_SAMPLING_RATE_8000_HZ 0x01 #define BLE_AUDIO_SAMPLING_RATE_11025_HZ 0x02 diff --git a/nimble/host/services/auracast/include/services/auracast/ble_svc_auracast.h b/nimble/host/services/auracast/include/services/auracast/ble_svc_auracast.h index 7a31dfc3c6..560adb8b19 100644 --- a/nimble/host/services/auracast/include/services/auracast/ble_svc_auracast.h +++ b/nimble/host/services/auracast/include/services/auracast/ble_svc_auracast.h @@ -20,7 +20,7 @@ #include #include "host/ble_gap.h" #include "host/ble_audio_common.h" -#include "host/ble_audio_broadcast.h" +#include "host/ble_audio_broadcast_source.h" struct ble_svc_auracast_create_params { /** Broadcast Audio Source Endpoint */ diff --git a/nimble/host/services/auracast/src/ble_svc_auracast.c b/nimble/host/services/auracast/src/ble_svc_auracast.c index 814035b9c8..b1bc7d33a6 100644 --- a/nimble/host/services/auracast/src/ble_svc_auracast.c +++ b/nimble/host/services/auracast/src/ble_svc_auracast.c @@ -21,7 +21,7 @@ #include "host/ble_gap.h" #include "host/ble_hs.h" -#include "host/ble_audio_broadcast.h" +#include "host/ble_audio_broadcast_source.h" #include "services/auracast/ble_svc_auracast.h" int @@ -61,7 +61,8 @@ ble_svc_auracast_create(const struct ble_svc_auracast_create_params *params, auracast_svc_data[data_offset] = BLE_HS_ADV_TYPE_SVC_DATA_UUID16; data_offset++; - put_le16(&auracast_svc_data[data_offset], 0x1856); + put_le16(&auracast_svc_data[data_offset], + BLE_BROADCAST_PUBLIC_BROADCAST_ANNOUNCEMENT_SVC_UUID); data_offset += 2; auracast_svc_data[data_offset] = features; data_offset++; diff --git a/nimble/host/src/ble_audio_broadcast.c b/nimble/host/src/ble_audio_broadcast_source.c similarity index 99% rename from nimble/host/src/ble_audio_broadcast.c rename to nimble/host/src/ble_audio_broadcast_source.c index b3ec29ce21..6a3aebf927 100644 --- a/nimble/host/src/ble_audio_broadcast.c +++ b/nimble/host/src/ble_audio_broadcast_source.c @@ -18,11 +18,11 @@ */ #include "host/ble_uuid.h" -#include "host/ble_audio_broadcast.h" +#include "host/ble_audio_broadcast_source.h" #include "os/util.h" -#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) struct ble_audio_broadcast { SLIST_ENTRY(ble_audio_broadcast) next; uint8_t adv_instance; diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index 41bf5e2c3a..801722177e 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -24,7 +24,7 @@ #include "syscfg/syscfg.h" #include "stats/stats.h" #include "host/ble_hs.h" -#include "host/ble_audio_broadcast.h" +#include "host/ble_audio_broadcast_source.h" #include "ble_hs_priv.h" #include "nimble/nimble_npl.h" #ifndef MYNEWT @@ -756,7 +756,7 @@ ble_hs_init(void) #if MYNEWT_VAL(BLE_ISO) rc = ble_iso_init(); SYSINIT_PANIC_ASSERT(rc == 0); -#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) rc = ble_audio_broadcast_init(); SYSINIT_PANIC_ASSERT(rc == 0); #endif diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 49a0993c3e..e4fdad471b 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -65,7 +65,7 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_rpt; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_lost; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_scan_req_rcvd; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_transfer; -#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_create_big_complete; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_terminate_big_complete; #endif @@ -137,7 +137,7 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = { [BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED] = ble_hs_hci_evt_le_adv_set_terminated, [BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD] = ble_hs_hci_evt_le_scan_req_rcvd, [BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_TRANSFER] = ble_hs_hci_evt_le_periodic_adv_sync_transfer, -#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) [BLE_HCI_LE_SUBEV_CREATE_BIG_COMPLETE] = ble_hs_hci_evt_le_create_big_complete, [BLE_HCI_LE_SUBEV_TERMINATE_BIG_COMPLETE] = @@ -747,7 +747,7 @@ ble_hs_hci_evt_le_periodic_adv_sync_transfer(uint8_t subevent, const void *data, return 0; } -#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) static int ble_hs_hci_evt_le_create_big_complete(uint8_t subevent, const void *data, unsigned int len) diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index 79a027d4be..faaaa0052d 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -498,14 +498,14 @@ syscfg.defs: Number of available BIGs value: 'MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES' restrictions: - - 'BLE_ISO_BROADCASTER if 0' + - 'BLE_ISO_BROADCAST_SOURCE if 0' BLE_MAX_BIS: description: > Number of supported BISes value: 4 restrictions: - - 'BLE_ISO_BROADCASTER if 0' + - 'BLE_ISO_BROADCAST_SOURCE if 0' ### Log settings. diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index 68432e28b2..47bd266cea 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -95,9 +95,15 @@ syscfg.defs: value: 0 restrictions: - '(BLE_VERSION >= 52) if 1' - BLE_ISO_BROADCASTER: + BLE_ISO_BROADCAST_SOURCE: description: > - This enables LE Audio Broadcaster feature + This enables LE Audio Broadcast Source feature + value: 0 + restrictions: + - '(BLE_VERSION >= 52) if 1' + BLE_ISO_BROADCAST_SINK: + description: > + This enables LE Audio Broadcast Sink feature value: 0 restrictions: - '(BLE_VERSION >= 52) if 1' diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index 9489ae1575..86da373817 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -458,8 +458,12 @@ #define MYNEWT_VAL_BLE_ISO (0) #endif -#ifndef MYNEWT_VAL_BLE_ISO_BROADCASTER -#define MYNEWT_VAL_BLE_ISO_BROADCASTER (0) +#ifndef MYNEWT_VAL_BLE_ISO_BROADCAST_SINK +#define MYNEWT_VAL_BLE_ISO_BROADCAST_SINK (0) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_BROADCAST_SOURCE +#define MYNEWT_VAL_BLE_ISO_BROADCAST_SOURCE (0) #endif #ifndef MYNEWT_VAL_BLE_ISO_TEST diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 64ed645eb1..c44af9c58d 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -459,8 +459,12 @@ #define MYNEWT_VAL_BLE_ISO (0) #endif -#ifndef MYNEWT_VAL_BLE_ISO_BROADCASTER -#define MYNEWT_VAL_BLE_ISO_BROADCASTER (0) +#ifndef MYNEWT_VAL_BLE_ISO_BROADCAST_SINK +#define MYNEWT_VAL_BLE_ISO_BROADCAST_SINK (0) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_BROADCAST_SOURCE +#define MYNEWT_VAL_BLE_ISO_BROADCAST_SOURCE (0) #endif #ifndef MYNEWT_VAL_BLE_ISO_TEST diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index 74e67dafd9..d087c57451 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -458,8 +458,12 @@ #define MYNEWT_VAL_BLE_ISO (0) #endif -#ifndef MYNEWT_VAL_BLE_ISO_BROADCASTER -#define MYNEWT_VAL_BLE_ISO_BROADCASTER (0) +#ifndef MYNEWT_VAL_BLE_ISO_BROADCAST_SINK +#define MYNEWT_VAL_BLE_ISO_BROADCAST_SINK (0) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_BROADCAST_SOURCE +#define MYNEWT_VAL_BLE_ISO_BROADCAST_SOURCE (0) #endif #ifndef MYNEWT_VAL_BLE_ISO_TEST diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index b53057a243..4910e54e68 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -457,8 +457,12 @@ #define MYNEWT_VAL_BLE_ISO (0) #endif -#ifndef MYNEWT_VAL_BLE_ISO_BROADCASTER -#define MYNEWT_VAL_BLE_ISO_BROADCASTER (0) +#ifndef MYNEWT_VAL_BLE_ISO_BROADCAST_SINK +#define MYNEWT_VAL_BLE_ISO_BROADCAST_SINK (0) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_BROADCAST_SOURCE +#define MYNEWT_VAL_BLE_ISO_BROADCAST_SOURCE (0) #endif #ifndef MYNEWT_VAL_BLE_ISO_TEST diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index a4ba6c35b8..b70ba2b992 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -860,8 +860,12 @@ #define MYNEWT_VAL_BLE_ISO (0) #endif -#ifndef MYNEWT_VAL_BLE_ISO_BROADCASTER -#define MYNEWT_VAL_BLE_ISO_BROADCASTER (0) +#ifndef MYNEWT_VAL_BLE_ISO_BROADCAST_SINK +#define MYNEWT_VAL_BLE_ISO_BROADCAST_SINK (0) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_BROADCAST_SOURCE +#define MYNEWT_VAL_BLE_ISO_BROADCAST_SOURCE (0) #endif #ifndef MYNEWT_VAL_BLE_ISO_TEST @@ -1201,7 +1205,7 @@ #define MYNEWT_VAL_BLE_LL_ISO (0) #endif -/* Value copied from BLE_ISO_BROADCASTER */ +/* Value copied from BLE_LL_ISO_BROADCASTER */ #ifndef MYNEWT_VAL_BLE_LL_ISO_BROADCASTER #define MYNEWT_VAL_BLE_LL_ISO_BROADCASTER (0) #endif diff --git a/targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml b/targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml index 22fd743e8d..d3255ff1c6 100644 --- a/targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml +++ b/targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml @@ -42,6 +42,6 @@ syscfg.vals: BLE_VERSION: 54 BLE_ISO: 1 - BLE_ISO_BROADCASTER: 1 + BLE_ISO_BROADCAST_SOURCE: 1 BLE_MAX_BIG: 1 BLE_MAX_BIS: 2 From 23eec0a5adf44f7dd313d3e7ee882473772cc250 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 23 Jan 2024 08:15:53 +0100 Subject: [PATCH 0909/1333] nimble/controller: Enable LL encryption if BLE_LL_ISO_BROADCASTER To support encrypting/decrypting broadcasts, LL Encryption shall be enabled by BLE_LL_ISO_BROADCASTER. --- nimble/controller/syscfg.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index c55107bcb1..19fae4754a 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -614,6 +614,7 @@ syscfg.vals.BLE_LL_CFG_FEAT_LL_EXT_ADV: BLE_LL_SCAN_AUX_SEGMENT_CNT: 8 syscfg.vals.BLE_LL_ISO_BROADCASTER: + BLE_LL_CFG_FEAT_LE_ENCRYPTION: 1 BLE_LL_STACK_SIZE: 180 # Enable vendor event on assert in standalone build to make failed assertions in From 894a8f497abf305c146662bc6deb6a64d5eeb403 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 19 Jan 2024 14:17:58 +0100 Subject: [PATCH 0910/1333] nimble/iso: Fix BIG handle assignment This fixes BIG handle value assigned on BIG instance allocation. Dedicated function has been added to get unique handle from BIG handles pool. PA dependency has been removed from ISO. The checks have meen moved to ble_audio_broadcast_source.c. --- nimble/host/include/host/ble_iso.h | 2 +- nimble/host/src/ble_audio_broadcast_source.c | 7 ++ nimble/host/src/ble_iso.c | 98 +++++++++++--------- nimble/include/nimble/hci_common.h | 3 + 4 files changed, 66 insertions(+), 44 deletions(-) diff --git a/nimble/host/include/host/ble_iso.h b/nimble/host/include/host/ble_iso.h index 0d2ddbb11f..786d2eb212 100644 --- a/nimble/host/include/host/ble_iso.h +++ b/nimble/host/include/host/ble_iso.h @@ -107,7 +107,7 @@ struct ble_iso_create_big_params { int ble_iso_create_big(const struct ble_iso_create_big_params *create_params, const struct ble_iso_big_params *big_params); -int ble_iso_terminate_big(uint8_t big_id); +int ble_iso_terminate_big(uint8_t big_handle); int ble_iso_tx(uint16_t conn_handle, void *data, uint16_t data_len); diff --git a/nimble/host/src/ble_audio_broadcast_source.c b/nimble/host/src/ble_audio_broadcast_source.c index 6a3aebf927..2891658182 100644 --- a/nimble/host/src/ble_audio_broadcast_source.c +++ b/nimble/host/src/ble_audio_broadcast_source.c @@ -122,12 +122,19 @@ ble_audio_broadcast_create(const struct ble_broadcast_create_params *params, uint8_t broadcast_id[3]; struct ble_audio_broadcast *broadcast; + if (params->adv_instance >= BLE_ADV_INSTANCES) { + BLE_HS_LOG_ERROR("Invalid advertising instance"); + return BLE_HS_EINVAL; + } + if (strlen(params->name) < 4 || strlen(params->name) > 32) { return BLE_HS_EINVAL; } broadcast = ble_audio_broadcast_find(params->adv_instance); if (broadcast) { + BLE_HS_LOG_ERROR("Advertising instance (%d) already in use", + params->adv_instance); return BLE_HS_EALREADY; } diff --git a/nimble/host/src/ble_iso.c b/nimble/host/src/ble_iso.c index e1115a1d5a..5ca94e59fe 100644 --- a/nimble/host/src/ble_iso.c +++ b/nimble/host/src/ble_iso.c @@ -33,7 +33,7 @@ struct ble_iso_big { SLIST_ENTRY(ble_iso_big) next; - uint8_t id; + uint8_t handle; uint16_t max_pdu; uint8_t num_bis; uint16_t conn_handles[MYNEWT_VAL(BLE_MAX_BIS)]; @@ -47,57 +47,71 @@ static struct os_mempool ble_iso_big_pool; static os_membuf_t ble_iso_big_mem[ OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIG), sizeof (struct ble_iso_big))]; -static struct ble_iso_big * -ble_iso_big_alloc(uint8_t adv_handle) +static int +ble_iso_big_handle_set(struct ble_iso_big *big) { - struct ble_iso_big *new_big; - struct ble_iso_big *big; + static uint8_t free_handle; + uint8_t i; - if (adv_handle >= BLE_ADV_INSTANCES) { - BLE_HS_LOG_ERROR("Invalid advertising instance"); - return NULL; - } + /* Set next free handle */ + for (i = BLE_HCI_ISO_BIG_HANDLE_MIN; i < BLE_HCI_ISO_BIG_HANDLE_MAX; i++) { + struct ble_iso_big *node = NULL; - if (!ble_gap_ext_adv_active(adv_handle)) { - BLE_HS_LOG_ERROR("Instance not active"); - return NULL; + if (free_handle > BLE_HCI_ISO_BIG_HANDLE_MAX) { + free_handle = BLE_HCI_ISO_BIG_HANDLE_MIN; + } + + big->handle = free_handle++; + + SLIST_FOREACH(node, &ble_iso_bigs, next) { + if (node->handle == big->handle) { + break; + } + } + + if (node == NULL || node->handle != big->handle) { + return 0; + } } + BLE_HS_DBG_ASSERT(0); + + return BLE_HS_EOS; +} + +static struct ble_iso_big * +ble_iso_big_alloc(void) +{ + struct ble_iso_big *new_big; + int rc; + new_big = os_memblock_get(&ble_iso_big_pool); if (new_big == NULL) { - BLE_HS_LOG_ERROR("No more memory in pool"); + BLE_HS_LOG_ERROR("No more memory in pool\n"); /* Out of memory. */ return NULL; } memset(new_big, 0, sizeof *new_big); - SLIST_FOREACH(big, &ble_iso_bigs, next) { - if (big->id == adv_handle) { - BLE_HS_LOG_ERROR("Advertising instance (%d) already in use", - adv_handle); - return NULL; - } + rc = ble_iso_big_handle_set(new_big); + if (rc != 0) { + os_memblock_put(&ble_iso_big_pool, new_big); + return NULL; } - new_big->id = adv_handle; - - if (SLIST_EMPTY(&ble_iso_bigs)) { - SLIST_INSERT_HEAD(&ble_iso_bigs, new_big, next); - } else { - SLIST_INSERT_AFTER(big, new_big, next); - } + SLIST_INSERT_HEAD(&ble_iso_bigs, new_big, next); return new_big; } static struct ble_iso_big * -ble_iso_big_find_by_id(uint8_t big_id) +ble_iso_big_find_by_handle(uint8_t big_handle) { struct ble_iso_big *big; SLIST_FOREACH(big, &ble_iso_bigs, next) { - if (big->id == big_id) { + if (big->handle == big_handle) { return big; } } @@ -120,21 +134,19 @@ ble_iso_create_big(const struct ble_iso_create_big_params *create_params, struct ble_hci_le_create_big_cp cp = { 0 }; struct ble_iso_big *big; - big = ble_iso_big_alloc(create_params->adv_handle); + cp.adv_handle = create_params->adv_handle; + if (create_params->bis_cnt > MYNEWT_VAL(BLE_MAX_BIS)) { + return BLE_HS_EINVAL; + } + + big = ble_iso_big_alloc(); if (big == NULL) { - return BLE_HS_ENOENT; + return BLE_HS_ENOMEM; } big->cb = create_params->cb; big->cb_arg = create_params->cb_arg; - cp.big_handle = create_params->adv_handle; - - cp.adv_handle = create_params->adv_handle; - if (create_params->bis_cnt > MYNEWT_VAL(BLE_MAX_BIS)) { - return BLE_HS_EINVAL; - } - cp.num_bis = create_params->bis_cnt; put_le24(cp.sdu_interval, big_params->sdu_interval); cp.max_sdu = big_params->max_sdu; @@ -154,19 +166,19 @@ ble_iso_create_big(const struct ble_iso_create_big_params *create_params, } int -ble_iso_terminate_big(uint8_t big_id) +ble_iso_terminate_big(uint8_t big_handle) { struct ble_hci_le_terminate_big_cp cp; struct ble_iso_big *big; int rc; - big = ble_iso_big_find_by_id(big_id); + big = ble_iso_big_find_by_handle(big_handle); if (big == NULL) { - BLE_HS_LOG_ERROR("No BIG with id=%d\n", big_id); + BLE_HS_LOG_ERROR("No BIG with handle=%d\n", big_handle); return BLE_HS_ENOENT; } - cp.big_handle = big->id; + cp.big_handle = big->handle; cp.reason = BLE_ERR_CONN_TERM_LOCAL; rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, @@ -200,7 +212,7 @@ ble_iso_rx_create_big_complete(const struct ble_hci_ev_le_subev_create_big_compl struct ble_iso_big *big; int i; - big = ble_iso_big_find_by_id(ev->big_handle); + big = ble_iso_big_find_by_handle(ev->big_handle); big->num_bis = ev->num_bis; @@ -237,7 +249,7 @@ ble_iso_rx_terminate_big_complete(const struct ble_hci_ev_le_subev_terminate_big struct ble_iso_event event; struct ble_iso_big *big; - big = ble_iso_big_find_by_id(ev->big_handle); + big = ble_iso_big_find_by_handle(ev->big_handle); event.type = BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE; event.big_terminated.big_handle = ev->big_handle; diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index aa7428d86a..62c62d0fb7 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -2104,6 +2104,9 @@ struct hci_data_hdr #define BLE_HCI_ISO_PB_COMPLETE (2) #define BLE_HCI_ISO_PB_LAST (3) +#define BLE_HCI_ISO_BIG_HANDLE_MIN 0x00 +#define BLE_HCI_ISO_BIG_HANDLE_MAX 0xEF + struct ble_hci_iso { uint16_t handle; uint16_t length; From faaa8e821a53bbf483f151e996eb4bbb21467b60 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 19 Jan 2024 14:24:43 +0100 Subject: [PATCH 0911/1333] nimble/iso: Fix missing BIG NULL pointer checks The BIG lookup function returns NULL if BIG has not been found, thus to be safe the return value has to be checked in case functions are called with big_handle value of non-existent BIG. --- nimble/host/src/ble_iso.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/nimble/host/src/ble_iso.c b/nimble/host/src/ble_iso.c index 5ca94e59fe..5c797836f6 100644 --- a/nimble/host/src/ble_iso.c +++ b/nimble/host/src/ble_iso.c @@ -29,6 +29,7 @@ #include "host/ble_iso.h" #include "nimble/hci_common.h" #include "sys/queue.h" +#include "ble_hs_priv.h" #include "ble_hs_hci_priv.h" struct ble_iso_big { @@ -213,6 +214,10 @@ ble_iso_rx_create_big_complete(const struct ble_hci_ev_le_subev_create_big_compl int i; big = ble_iso_big_find_by_handle(ev->big_handle); + if (big == NULL) { + BLE_HS_LOG_ERROR("No BIG with handle=%d\n", ev->big_handle); + return; + } big->num_bis = ev->num_bis; @@ -250,6 +255,10 @@ ble_iso_rx_terminate_big_complete(const struct ble_hci_ev_le_subev_terminate_big struct ble_iso_big *big; big = ble_iso_big_find_by_handle(ev->big_handle); + if (big == NULL) { + BLE_HS_LOG_ERROR("No BIG with handle=%d\n", ev->big_handle); + return; + } event.type = BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE; event.big_terminated.big_handle = ev->big_handle; From 41af6edec8c698ce2d9fa2dd3ac374753cb75edc Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 22 Jan 2024 18:14:00 +0100 Subject: [PATCH 0912/1333] nimble/iso: Fix missing events in LE event mask This fixes missing events: * LE Create BIG Complete event * LE Terminate BIG Complete event in LE event mask. --- nimble/host/src/ble_hs_startup.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c index 71d46bdbb7..d9907f376f 100644 --- a/nimble/host/src/ble_hs_startup.c +++ b/nimble/host/src/ble_hs_startup.c @@ -292,6 +292,17 @@ ble_hs_startup_le_set_evmask_tx(void) } #endif +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) + if (version >= BLE_HCI_VER_BCS_5_2) { + /** + * Enable the following LE events: + * 0x0000000004000000 LE Create BIG Complete event + * 0x0000000008000000 LE Terminate BIG Complete event + */ + mask |= 0x000000000C000000; + } +#endif + cmd.event_mask = htole64(mask); rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, From 26df457d7f2dd1ed5af7dd156d0c5e4fb12e3bba Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Mon, 19 Feb 2024 17:29:24 +0100 Subject: [PATCH 0913/1333] host/audio_common: Add doxygen comments in the header file Adds missing structures and macros documentation. Adds minor corrections to existing entries. --- nimble/host/include/host/ble_audio_common.h | 150 +++++++++++++++++++- 1 file changed, 146 insertions(+), 4 deletions(-) diff --git a/nimble/host/include/host/ble_audio_common.h b/nimble/host/include/host/ble_audio_common.h index d5e0afb68c..815d3f4c0d 100644 --- a/nimble/host/include/host/ble_audio_common.h +++ b/nimble/host/include/host/ble_audio_common.h @@ -20,10 +20,24 @@ #ifndef H_BLE_AUDIO_COMMON_ #define H_BLE_AUDIO_COMMON_ +/** + * @file ble_audio_common.h + * + * @brief Bluetooth Low Energy Audio Common API + * + * @defgroup bt_le_audio_common Bluetooth LE Audio Common + * @ingroup bt_host + * @{ + */ + #include "stdint.h" #include "os/queue.h" -/** Helper macros for BLE_AUDIO_BUILD_CODEC_CONFIG */ +/** + * @cond + * Helper macros for BLE_AUDIO_BUILD_CODEC_CONFIG + * @{ + */ #define FIELD_LEN_2(_len, _type, _field) _len, _type, _field, #define FIELD_LEN_5(_len, _type, _field) _len, _type, _field, \ _field >> 8, _field >> 16, \ @@ -46,58 +60,178 @@ _type, \ __VA_ARGS__) +/** + * @} + * @endcond + */ + +/** Broadcast Audio Announcement Service UUID. */ #define BLE_BROADCAST_AUDIO_ANNOUNCEMENT_SVC_UUID 0x1852 #define BLE_BROADCAST_PUBLIC_BROADCAST_ANNOUNCEMENT_SVC_UUID 0x1856 +/** + * @defgroup ble_audio_sampling_rates Bluetooth Low Energy Audio Sampling Rates + * @{ + */ + +/** LE Audio Sampling Rate: 8000 Hz. */ #define BLE_AUDIO_SAMPLING_RATE_8000_HZ 0x01 + +/** LE Audio Sampling Rate: 11025 Hz. */ #define BLE_AUDIO_SAMPLING_RATE_11025_HZ 0x02 + +/** LE Audio Sampling Rate: 16000 Hz. */ #define BLE_AUDIO_SAMPLING_RATE_16000_HZ 0x03 + +/** LE Audio Sampling Rate: 22050 Hz. */ #define BLE_AUDIO_SAMPLING_RATE_22050_HZ 0x04 + +/** LE Audio Sampling Rate: 24000 Hz. */ #define BLE_AUDIO_SAMPLING_RATE_24000_HZ 0x05 + +/** LE Audio Sampling Rate: 32000 Hz. */ #define BLE_AUDIO_SAMPLING_RATE_32000_HZ 0x06 + +/** LE Audio Sampling Rate: 44100 Hz. */ #define BLE_AUDIO_SAMPLING_RATE_44100_HZ 0x07 + +/** LE Audio Sampling Rate: 48000 Hz. */ #define BLE_AUDIO_SAMPLING_RATE_48000_HZ 0x08 + +/** LE Audio Sampling Rate: 88200 Hz. */ #define BLE_AUDIO_SAMPLING_RATE_88200_HZ 0x09 + +/** LE Audio Sampling Rate: 96000 Hz. */ #define BLE_AUDIO_SAMPLING_RATE_96000_HZ 0x0A + +/** LE Audio Sampling Rate: 176400 Hz. */ #define BLE_AUDIO_SAMPLING_RATE_176400_HZ 0x0B + +/** LE Audio Sampling Rate: 192000 Hz. */ #define BLE_AUDIO_SAMPLING_RATE_192000_HZ 0x0C + +/** LE Audio Sampling Rate: 384000 Hz. */ #define BLE_AUDIO_SAMPLING_RATE_384000_HZ 0x0D +/** @} */ + +/** + * @defgroup ble_audio_frame_durations Bluetooth Low Energy Audio Frame Durations + * @{ + */ + +/** LE Audio Frame Duration: 7.5 ms. */ #define BLE_AUDIO_SELECTED_FRAME_DURATION_7_5_MS 0x00 + +/** LE Audio Frame Duration: 10 ms. */ #define BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS 0x01 +/** @} */ + +/** + * @defgroup ble_audio_locations Bluetooth Low Energy Audio Locations + * @{ + */ + +/** LE Audio Location: Front Left. */ #define BLE_AUDIO_LOCATION_FRONT_LEFT (1ULL) + +/** LE Audio Location: Front Right. */ #define BLE_AUDIO_LOCATION_FRONT_RIGHT (1ULL << 1) + +/** LE Audio Location: Front Center. */ #define BLE_AUDIO_LOCATION_FRONT_CENTER (1ULL << 2) + +/** LE Audio Location: Low Frequency Effects 1. */ #define BLE_AUDIO_LOCATION_LOW_FREQ_EFFECTS_1 (1ULL << 3) + +/** LE Audio Location: Back Left. */ #define BLE_AUDIO_LOCATION_BACK_LEFT (1ULL << 4) + +/** LE Audio Location: Front Left Center. */ #define BLE_AUDIO_LOCATION_FRONT_LEFT_CENTER (1ULL << 5) + +/** LE Audio Location: Front Right Center. */ #define BLE_AUDIO_LOCATION_FRONT_RIGHT_CENTER (1ULL << 6) + +/** LE Audio Location: Back Center. */ #define BLE_AUDIO_LOCATION_BACK_CENTER (1ULL << 7) + +/** LE Audio Location: Low Frequency Effects 2. */ #define BLE_AUDIO_LOCATION_LOW_FREQ_EFFECTS_2 (1ULL << 8) + +/** LE Audio Location: Side Left. */ #define BLE_AUDIO_LOCATION_SIDE_LEFT (1ULL << 9) + +/** LE Audio Location: Side Right. */ #define BLE_AUDIO_LOCATION_SIDE_RIGHT (1ULL << 10) + +/** LE Audio Location: Top Front Left. */ #define BLE_AUDIO_LOCATION_TOP_FRONT_LEFT (1ULL << 11) + +/** LE Audio Location: Top Front Right. */ #define BLE_AUDIO_LOCATION_TOP_FRONT_RIGHT (1ULL << 12) + +/** LE Audio Location: Top Front Center. */ #define BLE_AUDIO_LOCATION_TOP_FRONT_CENTER (1ULL << 13) + +/** LE Audio Location: Top Center. */ #define BLE_AUDIO_LOCATION_TOP_CENTER (1ULL << 14) + +/** LE Audio Location: Top Back Left. */ #define BLE_AUDIO_LOCATION_TOP_BACK_LEFT (1ULL << 15) + +/** LE Audio Location: Top Back Right. */ #define BLE_AUDIO_LOCATION_TOP_BACK_RIGHT (1ULL << 16) + +/** LE Audio Location: Top Side Left. */ #define BLE_AUDIO_LOCATION_TOP_SIDE_LEFT (1ULL << 17) + +/** LE Audio Location: Top Side Right. */ #define BLE_AUDIO_LOCATION_TOP_SIDE_RIGHT (1ULL << 18) + +/** LE Audio Location: Top Back Center. */ #define BLE_AUDIO_LOCATION_TOP_BACK_CENTER (1ULL << 19) + +/** LE Audio Location: Bottom Front Center. */ #define BLE_AUDIO_LOCATION_BOTTOM_FRONT_CENTER (1ULL << 20) + +/** LE Audio Location: Bottom Front Left. */ #define BLE_AUDIO_LOCATION_BOTTOM_FRONT_LEFT (1ULL << 21) + +/** LE Audio Location: Bottom Front Right. */ #define BLE_AUDIO_LOCATION_BOTTOM_FRONT_RIGHT (1ULL << 22) + +/** LE Audio Location: Left Surround. */ #define BLE_AUDIO_LOCATION_LEFT_SURROUND (1ULL << 23) + +/** LE Audio Location: Right Surround. */ #define BLE_AUDIO_LOCATION_RIGHT_SURROUND (1ULL << 24) +/** @} */ + +/** + * @defgroup ble_audio_codec_config Bluetooth Low Energy Audio Codec Specific Config + * @{ + */ + +/** LE Audio Codec Config Type: Sampling Frequency. */ #define BLE_AUDIO_CODEC_SAMPLING_FREQ_TYPE 0x01 + +/** LE Audio Codec Config Type: Frame Duration. */ #define BLE_AUDIO_CODEC_FRAME_DURATION_TYPE 0x02 + +/** LE Audio Codec Config Type: Channel Allocation. */ #define BLE_AUDIO_CODEC_AUDIO_CHANNEL_ALLOCATION_TYPE 0x03 + +/** LE Audio Codec Config Type: Octets Per Codec Frame. */ #define BLE_AUDIO_CODEC_OCTETS_PER_CODEC_FRAME_TYPE 0x04 + +/** LE Audio Codec Config Type: Frame Blocks Per SDU. */ #define BLE_AUDIO_CODEC_FRAME_BLOCKS_PER_SDU_TYPE 0x05 +/** @} */ + /** * @brief Helper macro used to build LTV array of Codec_Specific_Configuration. * @@ -128,8 +262,9 @@ _codec_frame_blocks_per_sdu) \ } +/** Codec Information */ struct ble_audio_codec_id { - /** Coding Fromat */ + /** Coding Format */ uint8_t format; /** Company ID */ @@ -139,6 +274,7 @@ struct ble_audio_codec_id { uint16_t vendor_specific; }; +/** Broadcast Isochronous Streams (BIS) */ struct ble_audio_bis { /** Pointer to next BIS in subgroup */ STAILQ_ENTRY(ble_audio_bis) next; @@ -146,13 +282,14 @@ struct ble_audio_bis { /** BIS index */ uint8_t idx; - /** BIS level Codec Specific Configuration */ + /** BIS level Codec Specific Configuration length */ uint8_t codec_spec_config_len; - /** BIS level Codec Specific Configuration length */ + /** BIS level Codec Specific Configuration */ uint8_t *codec_spec_config; }; +/** Broadcast Isochronous Group (BIG) Subgroup */ struct ble_audio_big_subgroup { /** Pointer to next subgroup in BIG */ STAILQ_ENTRY(ble_audio_big_subgroup) next; @@ -179,6 +316,7 @@ struct ble_audio_big_subgroup { STAILQ_HEAD(, ble_audio_bis) bises; }; +/** Broadcast Audio Source Endpoint */ struct ble_audio_base { /** Broadcast ID */ uint32_t broadcast_id; @@ -193,4 +331,8 @@ struct ble_audio_base { STAILQ_HEAD(, ble_audio_big_subgroup) subs; }; +/** + * @} + */ + #endif /* H_BLE_AUDIO_COMMON_ */ From 90d270dfa1d5b9d80e330aab5c5a65e00734fe93 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 23 Jan 2024 08:12:18 +0100 Subject: [PATCH 0914/1333] nimble/controller: Conditionally enable BLE_LL_ISO_BROADCASTER Enable BLE_LL_ISO_BROADCASTER if BLE_ISO_BROADCAST_SOURCE and/or BLE_ISO_BROADCAST_SINK is enabled. Signed-off-by: Mariusz Skamra --- nimble/controller/syscfg.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 19fae4754a..8a32e2e028 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -483,8 +483,9 @@ syscfg.defs: Enable support for Isochronous Broadcasting state. restrictions: - BLE_LL_ISO if 1 - value: MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) + value: 0 state: experimental + BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS: description: > Enables ISO synchronization feedback using vendor-specific HCI event. @@ -613,6 +614,9 @@ syscfg.vals.BLE_LL_CFG_FEAT_LL_EXT_ADV: BLE_HW_WHITELIST_ENABLE: 0 BLE_LL_SCAN_AUX_SEGMENT_CNT: 8 +syscfg.vals.'BLE_ISO_BROADCAST_SOURCE || BLE_ISO_BROADCAST_SINK': + BLE_LL_ISO_BROADCASTER: 1 + syscfg.vals.BLE_LL_ISO_BROADCASTER: BLE_LL_CFG_FEAT_LE_ENCRYPTION: 1 BLE_LL_STACK_SIZE: 180 From 47d1bb50dfff9bb77736db70f5d93578861bde5a Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 27 Feb 2024 13:08:45 +0100 Subject: [PATCH 0915/1333] nimble/iso: Fix BLE_ISO dependency This adds the BLE_ISO dependency on BLE_ISO_BROADCAST_SOURCE and BLE_ISO_BROADCAST_SINK. Once one of those roles is enabled, the BLE_ISO shall be enabled. --- nimble/syscfg.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index 47bd266cea..6264d0bc2b 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -95,6 +95,7 @@ syscfg.defs: value: 0 restrictions: - '(BLE_VERSION >= 52) if 1' + - '(BLE_ISO_BROADCAST_SOURCE || BLE_ISO_BROADCAST_SINK) if 1' BLE_ISO_BROADCAST_SOURCE: description: > This enables LE Audio Broadcast Source feature @@ -160,3 +161,6 @@ syscfg.restrictions: # Enable VS HCI by default for combined or standalone controller build syscfg.vals.BLE_CONTROLLER: BLE_HCI_VS: 1 + +syscfg.vals.'BLE_ISO_BROADCAST_SOURCE || BLE_ISO_BROADCAST_SINK': + BLE_ISO: 1 From 8c06f256374ae9be9ff43d9270bcee3e9481a01f Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 22 Jan 2024 20:00:49 +0100 Subject: [PATCH 0916/1333] nimble/iso: Add ISO Rx datapath and extend ISO Broadcast API This adds ISO Rx datapath and along with Broadcast Sink ISO API and implementation. --- nimble/host/include/host/ble_iso.h | 230 ++++++- nimble/host/src/ble_hs.c | 5 + nimble/host/src/ble_hs_hci_evt.c | 43 ++ nimble/host/src/ble_hs_startup.c | 11 + nimble/host/src/ble_iso.c | 616 ++++++++++++++++++- nimble/host/src/ble_iso_priv.h | 9 + nimble/include/nimble/hci_common.h | 28 +- nimble/transport/socket/src/ble_hci_socket.c | 38 ++ 8 files changed, 937 insertions(+), 43 deletions(-) diff --git a/nimble/host/include/host/ble_iso.h b/nimble/host/include/host/ble_iso.h index 786d2eb212..8b0182fa67 100644 --- a/nimble/host/include/host/ble_iso.h +++ b/nimble/host/include/host/ble_iso.h @@ -19,22 +19,31 @@ #ifndef H_BLE_ISO_ #define H_BLE_ISO_ +#include + +#include "nimble/hci_common.h" #include "syscfg/syscfg.h" /** ISO event: BIG Create Completed */ -#define BLE_ISO_EVENT_BIG_CREATE_COMPLETE 0 +#define BLE_ISO_EVENT_BIG_CREATE_COMPLETE 0 /** ISO event: BIG Terminate Completed */ -#define BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE 1 +#define BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE 1 -#include +/** ISO event: BIG Sync Established */ +#define BLE_ISO_EVENT_BIG_SYNC_ESTABLISHED 2 -struct ble_iso_big_desc -{ +/** ISO event: BIG Sync Terminated */ +#define BLE_ISO_EVENT_BIG_SYNC_TERMINATED 3 + +/** ISO event: ISO Data received */ +#define BLE_ISO_EVENT_ISO_RX 4 + +/** @brief Broadcast Isochronous Group (BIG) description */ +struct ble_iso_big_desc { uint8_t big_handle; uint32_t big_sync_delay; uint32_t transport_latency_big; - uint8_t phy; uint8_t nse; uint8_t bn; uint8_t pto; @@ -45,6 +54,36 @@ struct ble_iso_big_desc uint16_t conn_handle[MYNEWT_VAL(BLE_MAX_BIS)]; }; +/** @brief Received ISO Data status possible values */ +enum ble_iso_rx_data_status { + /** The complete SDU was received correctly. */ + BLE_ISO_DATA_STATUS_VALID = BLE_HCI_ISO_PKT_STATUS_VALID, + + /** May contain errors or part of the SDU may be missing. */ + BLE_ISO_DATA_STATUS_ERROR = BLE_HCI_ISO_PKT_STATUS_INVALID, + + /** Part(s) of the SDU were not received correctly */ + BLE_ISO_DATA_STATUS_LOST = BLE_HCI_ISO_PKT_STATUS_LOST, +}; + +/** @brief Received ISO data info structure */ +struct ble_iso_rx_data_info { + /** ISO Data timestamp. Valid if @ref ble_iso_data_info.ts_valid is set */ + uint32_t ts; + + /** Packet sequence number */ + uint16_t seq_num; + + /** SDU length */ + uint16_t sdu_len : 12; + + /** ISO Data status. See @ref ble_iso_data_status */ + uint16_t status : 2; + + /** Timestamp is valid */ + uint16_t ts_valid : 1; +}; + /** * Represents a ISO-related event. When such an event occurs, the host * notifies the application by passing an instance of this structure to an @@ -69,17 +108,41 @@ struct ble_iso_event { */ struct { struct ble_iso_big_desc desc; + uint8_t status; + uint8_t phy; } big_created; /** * Represents a completion of BIG termination. Valid for the following * event types: * o BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE + * o BLE_ISO_EVENT_BIG_SYNC_TERMINATED */ struct { uint16_t big_handle; uint8_t reason; } big_terminated; + + /** + * Represents a completion of BIG synchronization. Valid for the following + * event types: + * o BLE_ISO_EVENT_BIG_SYNC_ESTABLISHED + */ + struct { + struct ble_iso_big_desc desc; + uint8_t status; + } big_sync_established; + + /** + * Represents a reception of ISO Data. Valid for the following + * event types: + * o BLE_ISO_EVENT_ISO_RX + */ + struct { + uint16_t conn_handle; + const struct ble_iso_rx_data_info *info; + struct os_mbuf *om; + } iso_rx; }; }; @@ -109,8 +172,161 @@ int ble_iso_create_big(const struct ble_iso_create_big_params *create_params, int ble_iso_terminate_big(uint8_t big_handle); +/** @brief BIS parameters for @ref ble_iso_big_sync_create */ +struct ble_iso_bis_params { + /** BIS index */ + uint8_t bis_index; + + /** The callback to associate with the BIS. + * Received ISO data is reported through this callback. + */ + ble_iso_event_fn *cb; + + /** The optional argument to pass to the callback function */ + void *cb_arg; +}; + +/** @brief BIG Sync parameters for @ref ble_iso_big_sync_create */ +struct ble_iso_big_sync_create_params { + /** Periodic advertising train sync handle */ + uint16_t sync_handle; + + /** Null-terminated broadcast code for encrypted BIG or + * NULL if the BIG is unencrypted + */ + const char *broadcast_code; + + /** Maximum Subevents to be used to receive data payloads in each BIS event */ + uint8_t mse; + + /** The maximum permitted time between successful receptions of BIS PDUs */ + uint16_t sync_timeout; + + /** The callback to associate with this sync procedure. + * Sync establishment and termination are reported through this callback. + */ + ble_iso_event_fn *cb; + + /** The optional argument to pass to the callback function */ + void *cb_arg; + + /** Number of a BISes */ + uint8_t bis_cnt; + + /** BIS parameters */ + struct ble_iso_bis_params *bis_params; +}; + +/** + * @brief Synchronize to Broadcast Isochronous Group (BIG) + * + * This function is used to synchronize to a BIG described in the periodic + * advertising train specified by the @p param->pa_sync_handle parameter. + * + * @param[in] params BIG synchronization parameters + * @param[out] big_handle BIG instance handle + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_iso_big_sync_create(const struct ble_iso_big_sync_create_params *params, + uint8_t *big_handle); + +/** + * @brief Terminate Broadcast Isochronous Group (BIG) sync + * + * This function is used to stop synchronizing or cancel the process of + * synchronizing to the BIG identified by the @p big_handle parameter. + * The command also terminates the reception of BISes in the BIG. + * + * @param[in] big_handle BIG handle + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_iso_big_sync_terminate(uint8_t big_handle); + +/** @brief ISO Data direction */ +enum ble_iso_data_dir { + BLE_ISO_DATA_DIR_TX, + BLE_ISO_DATA_DIR_RX, +}; + +/** @brief ISO Codec ID */ +struct ble_iso_codec_id { + /** Coding Format */ + uint8_t format; + + /** Company ID */ + uint16_t company_id; + + /** Vendor Specific Codec ID */ + uint16_t vendor_specific; +}; + +/** @brief Setup ISO Data Path parameters */ +struct ble_iso_data_path_setup_params { + /** Connection handle of the CIS or BIS */ + uint16_t conn_handle; + + /** Data path direction */ + enum ble_iso_data_dir data_path_dir; + + /** Data path ID. 0x00 for HCI */ + uint8_t data_path_id; + + /** Controller delay */ + uint32_t ctrl_delay; + + /** Codec ID */ + struct ble_iso_codec_id codec_id; + + /** Codec Configuration Length */ + uint8_t codec_config_len; + + /** Codec Configuration */ + const uint8_t *codec_config; +}; + +/** + * @brief Setup ISO Data Path + * + * This function is used to identify and create the isochronous data path + * between the Host and the Controller for a CIS, CIS configuration, or BIS + * identified by the @p param->conn_handle parameter. + * + * @param[in] params BIG synchronization parameters + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_iso_data_path_setup(const struct ble_iso_data_path_setup_params *param); + +/** @brief @brief Remove ISO Data Path parameters */ +struct ble_iso_data_path_remove_params { + /** Connection handle of the CIS or BIS */ + uint16_t conn_handle; + + /** Data path direction */ + enum ble_iso_data_dir data_path_dir; +}; + +/** + * @brief Remove ISO Data Path + * + * This function is used to remove the input and/or output data path(s) + * associated with a CIS, CIS configuration, or BIS identified by the + * @p param->conn_handle parameter. + * + * @param[in] params BIG synchronization parameters + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_iso_data_path_remove(const struct ble_iso_data_path_remove_params *param); + int ble_iso_tx(uint16_t conn_handle, void *data, uint16_t data_len); int ble_iso_init(void); -#endif +#endif /* H_BLE_ISO_ */ diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index 801722177e..d084c041a1 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -26,6 +26,7 @@ #include "host/ble_hs.h" #include "host/ble_audio_broadcast_source.h" #include "ble_hs_priv.h" +#include "ble_iso_priv.h" #include "nimble/nimble_npl.h" #ifndef MYNEWT #include "nimble/nimble_port.h" @@ -815,9 +816,13 @@ ble_transport_to_hs_acl_impl(struct os_mbuf *om) int ble_transport_to_hs_iso_impl(struct os_mbuf *om) { +#if MYNEWT_VAL(BLE_ISO) + return ble_iso_rx_data(om, NULL); +#else os_mbuf_free_chain(om); return 0; +#endif } void diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index e4fdad471b..cc88bfd838 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -69,6 +69,10 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_periodic_adv_sync_transfer; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_create_big_complete; static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_terminate_big_complete; #endif +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK) +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_big_sync_established; +static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_big_sync_lost; +#endif #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_biginfo_adv_report; #endif @@ -143,6 +147,12 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = { [BLE_HCI_LE_SUBEV_TERMINATE_BIG_COMPLETE] = ble_hs_hci_evt_le_terminate_big_complete, #endif +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK) + [BLE_HCI_LE_SUBEV_BIG_SYNC_ESTABLISHED] = + ble_hs_hci_evt_le_big_sync_established, + [BLE_HCI_LE_SUBEV_BIG_SYNC_LOST] = + ble_hs_hci_evt_le_big_sync_lost, +#endif #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) [BLE_HCI_LE_SUBEV_BIGINFO_ADV_REPORT] = ble_hs_hci_evt_le_biginfo_adv_report, #endif @@ -779,6 +789,39 @@ ble_hs_hci_evt_le_terminate_big_complete(uint8_t subevent, const void *data, } #endif +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK) +static int +ble_hs_hci_evt_le_big_sync_established(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_big_sync_established *ev = data; + + if (len < sizeof(*ev) || + len != (sizeof(*ev) + ev->num_bis * sizeof(ev->conn_handle[0]))) { + return BLE_HS_EBADDATA; + } + + ble_iso_rx_big_sync_established(ev); + + return 0; +} + +static int +ble_hs_hci_evt_le_big_sync_lost(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_big_sync_lost *ev = data; + + if (len != sizeof(*ev)) { + return BLE_HS_EBADDATA; + } + + ble_iso_rx_big_sync_lost(ev); + + return 0; +} +#endif + #if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS) static int ble_hs_hci_evt_le_biginfo_adv_report(uint8_t subevent, const void *data, diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c index d9907f376f..827c00d2a1 100644 --- a/nimble/host/src/ble_hs_startup.c +++ b/nimble/host/src/ble_hs_startup.c @@ -303,6 +303,17 @@ ble_hs_startup_le_set_evmask_tx(void) } #endif +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK) + if (version >= BLE_HCI_VER_BCS_5_2) { + /** + * Enable the following LE events: + * 0x0000000010000000 LE BIG Sync Established Complete event + * 0x0000000020000000 LE BIG Sync lost event + */ + mask |= 0x0000000030000000; + } +#endif + cmd.event_mask = htole64(mask); rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, diff --git a/nimble/host/src/ble_iso.c b/nimble/host/src/ble_iso.c index 5c797836f6..271bd27cbb 100644 --- a/nimble/host/src/ble_iso.c +++ b/nimble/host/src/ble_iso.c @@ -17,12 +17,9 @@ * under the License. */ -#include #include "syscfg/syscfg.h" -#include "ble_hs_mbuf_priv.h" #if MYNEWT_VAL(BLE_ISO) - #include "os/os_mbuf.h" #include "host/ble_hs_log.h" #include "host/ble_hs.h" @@ -31,22 +28,85 @@ #include "sys/queue.h" #include "ble_hs_priv.h" #include "ble_hs_hci_priv.h" +#include "ble_hs_mbuf_priv.h" + +#define ble_iso_big_conn_handles_init(_big, _handles, _num_handles) \ + do { \ + struct ble_iso_conn *conn = SLIST_FIRST(&ble_iso_conns); \ + \ + for (uint8_t i = 0; i < (_num_handles); i++) { \ + while (conn != NULL) { \ + if (conn->type == BLE_ISO_CONN_BIS) { \ + struct ble_iso_bis *bis; \ + \ + bis = CONTAINER_OF(conn, struct ble_iso_bis, conn); \ + if (bis->big == (_big)) { \ + conn->handle = le16toh((_handles)[i]); \ + conn = SLIST_NEXT(conn, next); \ + break; \ + } \ + } \ + \ + conn = SLIST_NEXT(conn, next); \ + } \ + } \ + } while (0); + +enum ble_iso_conn_type { + BLE_ISO_CONN_BIS, +}; struct ble_iso_big { SLIST_ENTRY(ble_iso_big) next; uint8_t handle; uint16_t max_pdu; - uint8_t num_bis; - uint16_t conn_handles[MYNEWT_VAL(BLE_MAX_BIS)]; + uint8_t bis_cnt; ble_iso_event_fn *cb; void *cb_arg; }; +struct ble_iso_conn { + SLIST_ENTRY(ble_iso_conn) next; + enum ble_iso_conn_type type; + uint8_t handle; + + struct ble_iso_rx_data_info rx_info; + struct os_mbuf *rx_buf; + + ble_iso_event_fn *cb; + void *cb_arg; +}; + +struct ble_iso_bis { + struct ble_iso_conn conn; + struct ble_iso_big *big; +}; + static SLIST_HEAD(, ble_iso_big) ble_iso_bigs; +static SLIST_HEAD(, ble_iso_conn) ble_iso_conns; static struct os_mempool ble_iso_big_pool; static os_membuf_t ble_iso_big_mem[ OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIG), sizeof (struct ble_iso_big))]; +static struct os_mempool ble_iso_bis_pool; +static os_membuf_t ble_iso_bis_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIS), sizeof (struct ble_iso_bis))]; + +static void +ble_iso_conn_append(struct ble_iso_conn *conn) +{ + struct ble_iso_conn *entry, *prev = NULL; + + SLIST_FOREACH(entry, &ble_iso_conns, next) { + prev = entry; + } + + if (prev == NULL) { + SLIST_INSERT_HEAD(&ble_iso_conns, conn, next); + } else { + SLIST_INSERT_AFTER(prev, conn, next); + } +} static int ble_iso_big_handle_set(struct ble_iso_big *big) @@ -106,6 +166,27 @@ ble_iso_big_alloc(void) return new_big; } +static struct ble_iso_bis * +ble_iso_bis_alloc(struct ble_iso_big *big) +{ + struct ble_iso_bis *new_bis; + + new_bis = os_memblock_get(&ble_iso_bis_pool); + if (new_bis == NULL) { + BLE_HS_LOG_ERROR("No more memory in pool\n"); + /* Out of memory. */ + return NULL; + } + + memset(new_bis, 0, sizeof *new_bis); + new_bis->conn.type = BLE_ISO_CONN_BIS; + new_bis->big = big; + + ble_iso_conn_append(&new_bis->conn); + + return new_bis; +} + static struct ble_iso_big * ble_iso_big_find_by_handle(uint8_t big_handle) { @@ -123,6 +204,22 @@ ble_iso_big_find_by_handle(uint8_t big_handle) static int ble_iso_big_free(struct ble_iso_big *big) { + struct ble_iso_conn *conn; + + SLIST_FOREACH(conn, &ble_iso_conns, next) { + struct ble_iso_bis *bis; + + if (conn->type != BLE_ISO_CONN_BIS) { + continue; + } + + bis = CONTAINER_OF(conn, struct ble_iso_bis, conn); + if (bis->big == big) { + SLIST_REMOVE(&ble_iso_conns, conn, ble_iso_conn, next); + os_memblock_put(&ble_iso_bis_pool, bis); + } + } + SLIST_REMOVE(&ble_iso_bigs, big, ble_iso_big, next); os_memblock_put(&ble_iso_big_pool, big); return 0; @@ -145,9 +242,21 @@ ble_iso_create_big(const struct ble_iso_create_big_params *create_params, return BLE_HS_ENOMEM; } + big->bis_cnt = create_params->bis_cnt; big->cb = create_params->cb; big->cb_arg = create_params->cb_arg; + for (uint8_t i = 0; i < create_params->bis_cnt; i++) { + struct ble_iso_bis *bis; + + bis = ble_iso_bis_alloc(big); + if (bis == NULL) { + ble_iso_big_free(big); + return BLE_HS_ENOMEM; + } + } + + cp.adv_handle = create_params->adv_handle; cp.num_bis = create_params->bis_cnt; put_le24(cp.sdu_interval, big_params->sdu_interval); cp.max_sdu = big_params->max_sdu; @@ -202,6 +311,12 @@ ble_iso_init(void) ble_iso_big_mem, "ble_iso_big_pool"); SYSINIT_PANIC_ASSERT(rc == 0); + rc = os_mempool_init(&ble_iso_bis_pool, + MYNEWT_VAL(BLE_MAX_BIS), + sizeof (struct ble_iso_bis), + ble_iso_bis_mem, "ble_iso_bis_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); + return 0; } @@ -209,9 +324,7 @@ void ble_iso_rx_create_big_complete(const struct ble_hci_ev_le_subev_create_big_complete *ev) { struct ble_iso_event event; - struct ble_iso_big *big; - int i; big = ble_iso_big_find_by_handle(ev->big_handle); if (big == NULL) { @@ -219,29 +332,38 @@ ble_iso_rx_create_big_complete(const struct ble_hci_ev_le_subev_create_big_compl return; } - big->num_bis = ev->num_bis; - - for (i = 0; i < ev->num_bis; i++) { - big->conn_handles[i] = ev->conn_handle[i]; - } + memset(&event, 0, sizeof(event)); + event.type = BLE_ISO_EVENT_BIG_CREATE_COMPLETE; + event.big_created.status = ev->status; - big->max_pdu = ev->max_pdu; + if (event.big_created.status != 0) { + ble_iso_big_free(big); + } else { + if (big->bis_cnt != ev->num_bis) { + BLE_HS_LOG_ERROR("Unexpected num_bis=%d != bis_cnt=%d\n", + ev->num_bis, big->bis_cnt); + /* XXX: Should we destroy the group? */ + } - event.type = BLE_ISO_EVENT_BIG_CREATE_COMPLETE; - event.big_created.desc.big_handle = ev->big_handle; - event.big_created.desc.big_sync_delay = get_le24(ev->big_sync_delay); - event.big_created.desc.transport_latency_big = - get_le24(ev->transport_latency_big); - event.big_created.desc.phy = ev->phy; - event.big_created.desc.nse = ev->nse; - event.big_created.desc.bn = ev->bn; - event.big_created.desc.pto = ev->pto; - event.big_created.desc.irc = ev->irc; - event.big_created.desc.max_pdu = ev->max_pdu; - event.big_created.desc.iso_interval = ev->iso_interval; - event.big_created.desc.num_bis = ev->num_bis; - memcpy(event.big_created.desc.conn_handle, ev->conn_handle, - ev->num_bis * sizeof(uint16_t)); + ble_iso_big_conn_handles_init(big, ev->conn_handle, ev->num_bis); + + big->max_pdu = ev->max_pdu; + + event.big_created.desc.big_handle = ev->big_handle; + event.big_created.desc.big_sync_delay = get_le24(ev->big_sync_delay); + event.big_created.desc.transport_latency_big = + get_le24(ev->transport_latency_big); + event.big_created.desc.nse = ev->nse; + event.big_created.desc.bn = ev->bn; + event.big_created.desc.pto = ev->pto; + event.big_created.desc.irc = ev->irc; + event.big_created.desc.max_pdu = ev->max_pdu; + event.big_created.desc.iso_interval = ev->iso_interval; + event.big_created.desc.num_bis = ev->num_bis; + memcpy(event.big_created.desc.conn_handle, ev->conn_handle, + ev->num_bis * sizeof(uint16_t)); + event.big_created.phy = ev->phy; + } if (big->cb != NULL) { big->cb(&event, big->cb_arg); @@ -375,4 +497,440 @@ ble_iso_tx(uint16_t conn_handle, void *data, uint16_t data_len) return rc; } -#endif + +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK) +static struct ble_iso_conn * +ble_iso_conn_lookup_handle(uint16_t handle) +{ + struct ble_iso_conn *conn; + + SLIST_FOREACH(conn, &ble_iso_conns, next) { + if (conn->handle == handle) { + return conn; + } + } + + return NULL; +} + +int +ble_iso_big_sync_create(const struct ble_iso_big_sync_create_params *param, + uint8_t *big_handle) +{ + struct ble_hci_le_big_create_sync_cp *cp; + uint8_t buf[sizeof(*cp) + MYNEWT_VAL(BLE_MAX_BIS)]; + struct ble_iso_big *big; + int rc; + + big = ble_iso_big_alloc(); + if (big == NULL) { + return BLE_HS_ENOMEM; + } + + big->bis_cnt = param->bis_cnt; + big->cb = param->cb; + big->cb_arg = param->cb_arg; + + cp = (void *)buf; + cp->big_handle = big->handle; + put_le16(&cp->sync_handle, param->sync_handle); + + if (param->broadcast_code != NULL) { + cp->encryption = BLE_HCI_ISO_BIG_ENCRYPTION_ENCRYPTED; + memcpy(cp->broadcast_code, param->broadcast_code, sizeof(cp->broadcast_code)); + } else { + cp->encryption = BLE_HCI_ISO_BIG_ENCRYPTION_UNENCRYPTED; + memset(cp->broadcast_code, 0, sizeof(cp->broadcast_code)); + } + + cp->mse = param->mse; + put_le16(&cp->sync_timeout, param->sync_timeout); + cp->num_bis = param->bis_cnt; + + for (uint8_t i = 0; i < param->bis_cnt; i++) { + struct ble_iso_bis *bis; + + bis = ble_iso_bis_alloc(big); + if (bis == NULL) { + ble_iso_big_free(big); + return BLE_HS_ENOMEM; + } + + bis->conn.cb = param->bis_params[i].cb; + bis->conn.cb_arg = param->bis_params[i].cb_arg; + + cp->bis[i] = param->bis_params[i].bis_index; + } + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_BIG_CREATE_SYNC), + cp, sizeof(*cp) + cp->num_bis, NULL, 0); + if (rc != 0) { + ble_iso_big_free(big); + } else { + *big_handle = big->handle; + } + + return rc; +} + +int +ble_iso_big_sync_terminate(uint8_t big_handle) +{ + struct ble_hci_le_big_terminate_sync_cp cp; + struct ble_hci_le_big_terminate_sync_rp rp; + struct ble_iso_big *big; + int rc; + + big = ble_iso_big_find_by_handle(big_handle); + if (big == NULL) { + BLE_HS_LOG_ERROR("No BIG with handle=%d\n", big_handle); + return BLE_HS_ENOENT; + } + + cp.big_handle = big->handle; + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_BIG_TERMINATE_SYNC), + &cp, sizeof(cp), &rp, sizeof(rp)); + if (rc == 0) { + struct ble_iso_event event; + ble_iso_event_fn *cb; + void *cb_arg; + + event.type = BLE_ISO_EVENT_BIG_SYNC_TERMINATED; + event.big_terminated.big_handle = big_handle; + event.big_terminated.reason = BLE_ERR_CONN_TERM_LOCAL; + + cb = big->cb; + cb_arg = big->cb_arg; + + ble_iso_big_free(big); + + if (cb != NULL) { + cb(&event, cb_arg); + } + } + + return rc; +} + +void +ble_iso_rx_big_sync_established(const struct ble_hci_ev_le_subev_big_sync_established *ev) +{ + struct ble_iso_event event; + struct ble_iso_big *big; + ble_iso_event_fn *cb; + void *cb_arg; + + big = ble_iso_big_find_by_handle(ev->big_handle); + if (big == NULL) { + return; + } + + cb = big->cb; + cb_arg = big->cb_arg; + + memset(&event, 0, sizeof(event)); + event.type = BLE_ISO_EVENT_BIG_SYNC_ESTABLISHED; + event.big_sync_established.status = ev->status; + + if (event.big_sync_established.status != 0) { + ble_iso_big_free(big); + } else { + if (big->bis_cnt != ev->num_bis) { + BLE_HS_LOG_ERROR("Unexpected num_bis=%d != bis_cnt=%d\n", + ev->num_bis, big->bis_cnt); + /* XXX: Should we destroy the group? */ + } + + ble_iso_big_conn_handles_init(big, ev->conn_handle, ev->num_bis); + + event.big_sync_established.desc.big_handle = ev->big_handle; + event.big_sync_established.desc.transport_latency_big = + get_le24(ev->transport_latency_big); + event.big_sync_established.desc.nse = ev->nse; + event.big_sync_established.desc.bn = ev->bn; + event.big_sync_established.desc.pto = ev->pto; + event.big_sync_established.desc.irc = ev->irc; + event.big_sync_established.desc.max_pdu = le16toh(ev->max_pdu); + event.big_sync_established.desc.iso_interval = le16toh(ev->iso_interval); + event.big_sync_established.desc.num_bis = ev->num_bis; + memcpy(event.big_sync_established.desc.conn_handle, ev->conn_handle, + ev->num_bis * sizeof(uint16_t)); + } + + if (cb != NULL) { + cb(&event, cb_arg); + } +} + +void +ble_iso_rx_big_sync_lost(const struct ble_hci_ev_le_subev_big_sync_lost *ev) +{ + struct ble_iso_event event; + struct ble_iso_big *big; + ble_iso_event_fn *cb; + void *cb_arg; + + big = ble_iso_big_find_by_handle(ev->big_handle); + if (big == NULL) { + BLE_HS_LOG_ERROR("No BIG with handle=%d\n", ev->big_handle); + return; + } + + event.type = BLE_ISO_EVENT_BIG_SYNC_TERMINATED; + event.big_terminated.big_handle = ev->big_handle; + event.big_terminated.reason = ev->reason; + + cb = big->cb; + cb_arg = big->cb_arg; + + ble_iso_big_free(big); + + if (cb != NULL) { + cb(&event, cb_arg); + } +} + +static int +ble_iso_rx_data_info_parse(struct os_mbuf *om, bool ts_available, + struct ble_iso_rx_data_info *info) +{ + struct ble_hci_iso_data *iso_data; + uint16_t u16; + + if (ts_available) { + if (os_mbuf_len(om) < sizeof(info->ts)) { + BLE_HS_LOG_DEBUG("Data missing\n"); + return BLE_HS_EMSGSIZE; + } + + info->ts = get_le32(om->om_data); + os_mbuf_adj(om, sizeof(info->ts)); + } else { + info->ts = 0; + } + + if (os_mbuf_len(om) < sizeof(*iso_data)) { + BLE_HS_LOG_DEBUG("Data missing\n"); + return BLE_HS_EMSGSIZE; + } + + iso_data = (void *)(om->om_data); + + info->seq_num = le16toh(iso_data->packet_seq_num); + u16 = le16toh(iso_data->sdu_len); + info->sdu_len = BLE_HCI_ISO_SDU_LENGTH(u16); + info->status = BLE_HCI_ISO_PKT_STATUS_FLAG(u16); + info->ts_valid = ts_available; + + os_mbuf_adj(om, sizeof(*iso_data)); + + return 0; +} + +static void +ble_iso_conn_rx_reset(struct ble_iso_conn *conn) +{ + memset(&conn->rx_info, 0, sizeof(conn->rx_info)); + conn->rx_buf = NULL; +} + +static void +ble_iso_conn_rx_data_discard(struct ble_iso_conn *conn) +{ + os_mbuf_free_chain(conn->rx_buf); + ble_iso_conn_rx_reset(conn); +} + +static void +ble_iso_event_iso_rx_emit(struct ble_iso_conn *conn) +{ + struct ble_iso_event event = { + .type = BLE_ISO_EVENT_ISO_RX, + .iso_rx.conn_handle = conn->handle, + .iso_rx.info = &conn->rx_info, + .iso_rx.om = conn->rx_buf, + }; + + if (conn->cb != NULL) { + conn->cb(&event, conn->cb_arg); + } +} + +static int +ble_iso_conn_rx_data_load(struct ble_iso_conn *conn, struct os_mbuf *frag, + uint8_t pb_flag, bool ts_available, void *arg) +{ + int len_remaining; + int rc; + + switch (pb_flag) { + case BLE_HCI_ISO_PB_FIRST: + case BLE_HCI_ISO_PB_COMPLETE: + if (conn->rx_buf != NULL) { + /* Previous data packet never completed. Discard old packet. */ + ble_iso_conn_rx_data_discard(conn); + } + + rc = ble_iso_rx_data_info_parse(frag, ts_available, &conn->rx_info); + if (rc != 0) { + return rc; + } + + conn->rx_buf = frag; + break; + + case BLE_HCI_ISO_PB_CONTINUATION: + case BLE_HCI_ISO_PB_LAST: + if (conn->rx_buf == NULL) { + /* Last fragment without the start. Discard new packet. */ + return BLE_HS_EBADDATA; + } + + /* Determine whether the total length won't exceed the declared SDU length */ + len_remaining = conn->rx_info.sdu_len - OS_MBUF_PKTLEN(conn->rx_buf); + if (len_remaining - os_mbuf_len(frag) < 0) { + /* SDU Length exceeded. Discard all packets. */ + ble_iso_conn_rx_data_discard(conn); + return BLE_HS_EBADDATA; + } + + os_mbuf_concat(conn->rx_buf, frag); + break; + + default: + BLE_HS_LOG_ERROR("Invalid pb_flag %d\n", pb_flag); + return BLE_HS_EBADDATA; + } + + if (pb_flag == BLE_HCI_ISO_PB_COMPLETE || pb_flag == BLE_HCI_ISO_PB_LAST) { + ble_iso_event_iso_rx_emit(conn); + ble_iso_conn_rx_reset(conn); + } + + return 0; +} + +int +ble_iso_rx_data(struct os_mbuf *om, void *arg) +{ + struct ble_iso_conn *conn; + struct ble_hci_iso *hci_iso; + uint16_t conn_handle; + uint16_t length; + uint16_t pb_flag; + uint16_t ts_flag; + uint16_t u16; + int rc; + + if (os_mbuf_len(om) < sizeof(*hci_iso)) { + BLE_HS_LOG_DEBUG("Data missing\n"); + os_mbuf_free_chain(om); + return BLE_HS_EMSGSIZE; + } + + hci_iso = (void *)om->om_data; + + u16 = le16toh(hci_iso->handle); + conn_handle = BLE_HCI_ISO_CONN_HANDLE(u16); + pb_flag = BLE_HCI_ISO_PB_FLAG(u16); + ts_flag = BLE_HCI_ISO_TS_FLAG(u16); + length = BLE_HCI_ISO_LENGTH(le16toh(hci_iso->length)); + + os_mbuf_adj(om, sizeof(*hci_iso)); + + if (os_mbuf_len(om) < length) { + BLE_HS_LOG_DEBUG("Data missing\n"); + os_mbuf_free_chain(om); + return BLE_HS_EMSGSIZE; + } + + conn = ble_iso_conn_lookup_handle(conn_handle); + if (conn == NULL) { + BLE_HS_LOG_DEBUG("Unknown handle=%d\n", conn_handle); + os_mbuf_free_chain(om); + return BLE_HS_EMSGSIZE; + } + + rc = ble_iso_conn_rx_data_load(conn, om, pb_flag, ts_flag > 0, arg); + if (rc != 0) { + os_mbuf_free_chain(om); + return rc; + } + + return 0; +} +#endif /* BLE_ISO_BROADCAST_SINK */ + +int +ble_iso_data_path_setup(const struct ble_iso_data_path_setup_params *param) +{ + struct ble_hci_le_setup_iso_data_path_rp rp; + struct ble_hci_le_setup_iso_data_path_cp *cp; + uint8_t buf[sizeof(*cp) + UINT8_MAX]; + int rc; + + if (param->codec_config_len > 0 && param->codec_config == NULL) { + BLE_HS_LOG_ERROR("Missing codec_config\n"); + return BLE_HS_EINVAL; + } + + cp = (void *)buf; + put_le16(&cp->conn_handle, param->conn_handle); + cp->data_path_dir = 0; + + if (param->data_path_dir & BLE_ISO_DATA_DIR_TX) { + /* Input (Host to Controller) */ + cp->data_path_dir |= BLE_HCI_ISO_DATA_PATH_DIR_INPUT; + } + + if (param->data_path_dir & BLE_ISO_DATA_DIR_RX) { + /* Output (Controller to Host) */ + cp->data_path_dir |= BLE_HCI_ISO_DATA_PATH_DIR_OUTPUT; + } + + cp->data_path_id = param->data_path_id; + cp->codec_id[0] = param->codec_id.format; + put_le16(&cp->codec_id[1], param->codec_id.company_id); + put_le16(&cp->codec_id[3], param->codec_id.vendor_specific); + put_le24(cp->controller_delay, param->ctrl_delay); + + cp->codec_config_len = param->codec_config_len; + memcpy(cp->codec_config, param->codec_config, cp->codec_config_len); + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_SETUP_ISO_DATA_PATH), + cp, sizeof(*cp) + cp->codec_config_len, &rp, + sizeof(rp)); + + return rc; +} + +int +ble_iso_data_path_remove(const struct ble_iso_data_path_remove_params *param) +{ + struct ble_hci_le_remove_iso_data_path_rp rp; + struct ble_hci_le_remove_iso_data_path_cp cp = { 0 }; + int rc; + + put_le16(&cp.conn_handle, param->conn_handle); + + if (param->data_path_dir & BLE_ISO_DATA_DIR_TX) { + /* Input (Host to Controller) */ + cp.data_path_dir |= BLE_HCI_ISO_DATA_PATH_DIR_INPUT; + } + + if (param->data_path_dir & BLE_ISO_DATA_DIR_RX) { + /* Output (Controller to Host) */ + cp.data_path_dir |= BLE_HCI_ISO_DATA_PATH_DIR_OUTPUT; + } + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_REMOVE_ISO_DATA_PATH), + &cp, sizeof(cp), &rp, sizeof(rp)); + + return rc; +} +#endif /* BLE_ISO */ diff --git a/nimble/host/src/ble_iso_priv.h b/nimble/host/src/ble_iso_priv.h index fb0a6aab3e..9005b5067f 100644 --- a/nimble/host/src/ble_iso_priv.h +++ b/nimble/host/src/ble_iso_priv.h @@ -31,6 +31,15 @@ ble_iso_rx_create_big_complete(const struct ble_hci_ev_le_subev_create_big_compl void ble_iso_rx_terminate_big_complete(const struct ble_hci_ev_le_subev_terminate_big_complete *ev); +void +ble_iso_rx_big_sync_established(const struct ble_hci_ev_le_subev_big_sync_established *ev); + +void +ble_iso_rx_big_sync_lost(const struct ble_hci_ev_le_subev_big_sync_lost *ev); + +int +ble_iso_rx_data(struct os_mbuf *om, void *arg); + #ifdef __cplusplus } #endif diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 62c62d0fb7..fb74c24aa2 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -2087,31 +2087,45 @@ struct hci_data_hdr #define BLE_HCI_PB_FIRST_FLUSH 2 #define BLE_HCI_PB_FULL 3 -#define BLE_HCI_ISO_CONN_HANDLE_MASK (0x07ff) -#define BLE_HCI_ISO_PB_FLAG_MASK (0x3000) -#define BLE_HCI_ISO_TS_FLAG_MASK (0x4000) -#define BLE_HCI_ISO_LENGTH_MASK (0x7fff) +#define BLE_HCI_ISO_CONN_HANDLE_MASK (0x07ff) +#define BLE_HCI_ISO_PB_FLAG_MASK (0x3000) +#define BLE_HCI_ISO_TS_FLAG_MASK (0x4000) +#define BLE_HCI_ISO_LENGTH_MASK (0x7fff) +#define BLE_HCI_ISO_SDU_LENGTH_MASK (0x0fff) +#define BLE_HCI_ISO_PKT_STATUS_FLAG_MASK (0xC000) #define BLE_HCI_ISO_HANDLE(ch, pb, ts) ((ch) | ((pb) << 12) | ((ts) << 14)) #define BLE_HCI_ISO_CONN_HANDLE(h) ((h) & BLE_HCI_ISO_CONN_HANDLE_MASK) #define BLE_HCI_ISO_PB_FLAG(h) (((h) & BLE_HCI_ISO_PB_FLAG_MASK) >> 12) -#define BLE_HCI_ISO_TS_FLAG(h) ((h) & BLE_HCI_ISO_TS_FLAG_MASK) +#define BLE_HCI_ISO_TS_FLAG(h) (((h) & BLE_HCI_ISO_TS_FLAG_MASK) >> 14) #define BLE_HCI_ISO_LENGTH(l) ((l) & BLE_HCI_ISO_LENGTH_MASK) +#define BLE_HCI_ISO_SDU_LENGTH(l) ((l) & BLE_HCI_ISO_SDU_LENGTH_MASK) +#define BLE_HCI_ISO_PKT_STATUS_FLAG(l) (((l) & BLE_HCI_ISO_PKT_STATUS_FLAG_MASK) >> 14) #define BLE_HCI_ISO_PB_FIRST (0) #define BLE_HCI_ISO_PB_CONTINUATION (1) #define BLE_HCI_ISO_PB_COMPLETE (2) #define BLE_HCI_ISO_PB_LAST (3) +#define BLE_HCI_ISO_PKT_STATUS_VALID 0x00 +#define BLE_HCI_ISO_PKT_STATUS_INVALID 0x01 +#define BLE_HCI_ISO_PKT_STATUS_LOST 0x10 + #define BLE_HCI_ISO_BIG_HANDLE_MIN 0x00 #define BLE_HCI_ISO_BIG_HANDLE_MAX 0xEF +#define BLE_HCI_ISO_BIG_ENCRYPTION_UNENCRYPTED 0x00 +#define BLE_HCI_ISO_BIG_ENCRYPTION_ENCRYPTED 0x01 + +#define BLE_HCI_ISO_DATA_PATH_DIR_INPUT 0x00 +#define BLE_HCI_ISO_DATA_PATH_DIR_OUTPUT 0x01 + struct ble_hci_iso { uint16_t handle; uint16_t length; uint8_t data[0]; -}; +} __attribute__((packed)); #define BLE_HCI_ISO_HDR_SDU_LENGTH_MASK (0x07ff) @@ -2119,7 +2133,7 @@ struct ble_hci_iso_data { uint16_t packet_seq_num; uint16_t sdu_len; uint8_t data[0]; -}; +} __attribute__((packed)); #ifdef __cplusplus } diff --git a/nimble/transport/socket/src/ble_hci_socket.c b/nimble/transport/socket/src/ble_hci_socket.c index 75a813dba3..0d52ec584f 100644 --- a/nimble/transport/socket/src/ble_hci_socket.c +++ b/nimble/transport/socket/src/ble_hci_socket.c @@ -103,11 +103,13 @@ STATS_SECT_START(hci_sock_stats) STATS_SECT_ENTRY(icmd) STATS_SECT_ENTRY(ievt) STATS_SECT_ENTRY(iacl) + STATS_SECT_ENTRY(iiso) STATS_SECT_ENTRY(ibytes) STATS_SECT_ENTRY(ierr) STATS_SECT_ENTRY(imem) STATS_SECT_ENTRY(omsg) STATS_SECT_ENTRY(oacl) + STATS_SECT_ENTRY(oiso) STATS_SECT_ENTRY(ocmd) STATS_SECT_ENTRY(oevt) STATS_SECT_ENTRY(obytes) @@ -120,11 +122,13 @@ STATS_NAME_START(hci_sock_stats) STATS_NAME(hci_sock_stats, icmd) STATS_NAME(hci_sock_stats, ievt) STATS_NAME(hci_sock_stats, iacl) + STATS_NAME(hci_sock_stats, iiso) STATS_NAME(hci_sock_stats, ibytes) STATS_NAME(hci_sock_stats, ierr) STATS_NAME(hci_sock_stats, imem) STATS_NAME(hci_sock_stats, omsg) STATS_NAME(hci_sock_stats, oacl) + STATS_NAME(hci_sock_stats, oiso) STATS_NAME(hci_sock_stats, ocmd) STATS_NAME(hci_sock_stats, oevt) STATS_NAME(hci_sock_stats, obytes) @@ -142,6 +146,7 @@ STATS_NAME_END(hci_sock_stats) #define BLE_HCI_UART_H4_ACL 0x02 #define BLE_HCI_UART_H4_SCO 0x03 #define BLE_HCI_UART_H4_EVT 0x04 +#define BLE_HCI_UART_H4_ISO 0x05 #define BLE_HCI_UART_H4_SYNC_LOSS 0x80 #define BLE_HCI_UART_H4_SKIP_CMD 0x81 #define BLE_HCI_UART_H4_SKIP_ACL 0x82 @@ -483,6 +488,39 @@ ble_hci_sock_rx_msg(void) ble_transport_to_ll_acl(m); #else ble_transport_to_hs_acl(m); +#endif + OS_EXIT_CRITICAL(sr); + break; + case BLE_HCI_UART_H4_ISO: + if (bhss->rx_off < BLE_HCI_DATA_HDR_SZ) { + return -1; + } + len = 1 + BLE_HCI_DATA_HDR_SZ + (bhss->rx_data[4] << 8) + + bhss->rx_data[3]; + if (bhss->rx_off < len) { + return -1; + } + STATS_INC(hci_sock_stats, imsg); + STATS_INC(hci_sock_stats, iiso); +#if MYNEWT_VAL(BLE_CONTROLLER) + m = ble_transport_alloc_iso_from_hs(); +#else + m = ble_transport_alloc_iso_from_ll(); +#endif + if (!m) { + STATS_INC(hci_sock_stats, imem); + break; + } + if (os_mbuf_append(m, &bhss->rx_data[1], len - 1)) { + STATS_INC(hci_sock_stats, imem); + os_mbuf_free_chain(m); + break; + } + OS_ENTER_CRITICAL(sr); +#if MYNEWT_VAL(BLE_CONTROLLER) + ble_transport_to_ll_iso(m); +#else + ble_transport_to_hs_iso(m); #endif OS_EXIT_CRITICAL(sr); break; From eacdbc36e020a270181a7c8bf36dd352beec4d13 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 23 Feb 2024 09:39:52 +0100 Subject: [PATCH 0917/1333] nimble/iso: Fix missing BLE_ISO_BROADCAST_SOURCE guard This makes Broadcast ISO source related code dependent on BLE_ISO_BROADCAST_SOURCE mynewt option. --- nimble/host/src/ble_iso.c | 46 ++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/nimble/host/src/ble_iso.c b/nimble/host/src/ble_iso.c index 271bd27cbb..90bd613d05 100644 --- a/nimble/host/src/ble_iso.c +++ b/nimble/host/src/ble_iso.c @@ -225,6 +225,7 @@ ble_iso_big_free(struct ble_iso_big *big) return 0; } +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) int ble_iso_create_big(const struct ble_iso_create_big_params *create_params, const struct ble_iso_big_params *big_params) @@ -298,28 +299,6 @@ ble_iso_terminate_big(uint8_t big_handle) return rc; } -int -ble_iso_init(void) -{ - int rc; - - SLIST_INIT(&ble_iso_bigs); - - rc = os_mempool_init(&ble_iso_big_pool, - MYNEWT_VAL(BLE_MAX_BIG), - sizeof (struct ble_iso_big), - ble_iso_big_mem, "ble_iso_big_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - rc = os_mempool_init(&ble_iso_bis_pool, - MYNEWT_VAL(BLE_MAX_BIS), - sizeof (struct ble_iso_bis), - ble_iso_bis_mem, "ble_iso_bis_pool"); - SYSINIT_PANIC_ASSERT(rc == 0); - - return 0; -} - void ble_iso_rx_create_big_complete(const struct ble_hci_ev_le_subev_create_big_complete *ev) { @@ -497,6 +476,7 @@ ble_iso_tx(uint16_t conn_handle, void *data, uint16_t data_len) return rc; } +#endif /* BLE_ISO_BROADCAST_SOURCE */ #if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK) static struct ble_iso_conn * @@ -933,4 +913,26 @@ ble_iso_data_path_remove(const struct ble_iso_data_path_remove_params *param) return rc; } + +int +ble_iso_init(void) +{ + int rc; + + SLIST_INIT(&ble_iso_bigs); + + rc = os_mempool_init(&ble_iso_big_pool, + MYNEWT_VAL(BLE_MAX_BIG), + sizeof (struct ble_iso_big), + ble_iso_big_mem, "ble_iso_big_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = os_mempool_init(&ble_iso_bis_pool, + MYNEWT_VAL(BLE_MAX_BIS), + sizeof (struct ble_iso_bis), + ble_iso_bis_mem, "ble_iso_bis_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); + + return 0; +} #endif /* BLE_ISO */ From a2e68282f57b206c5a6ba6146a019877cae5a994 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 22 Feb 2024 16:03:22 +0100 Subject: [PATCH 0918/1333] apps/btshell: Add ISO related commands This adds ISO related commands to the btshell application. The commands can be used for testing purposes. --- apps/btshell/src/cmd.c | 51 +++- apps/btshell/src/cmd_iso.c | 513 +++++++++++++++++++++++++++++++++++++ apps/btshell/src/cmd_iso.h | 39 +++ 3 files changed, 602 insertions(+), 1 deletion(-) create mode 100644 apps/btshell/src/cmd_iso.c create mode 100644 apps/btshell/src/cmd_iso.h diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index ff8bae8c75..1b20078e85 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -41,6 +41,7 @@ #include "cmd.h" #include "btshell.h" #include "cmd_gatt.h" +#include "cmd_iso.h" #include "cmd_l2cap.h" #include "cmd_leaudio.h" @@ -4858,7 +4859,7 @@ static const struct shell_cmd btshell_commands[] = { }, #endif #endif -#if MYNEWT_VAL(BLE_ISO) +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) { .sc_cmd = "base_add", .sc_cmd_func = cmd_leaudio_base_add, @@ -4915,7 +4916,55 @@ static const struct shell_cmd btshell_commands[] = { .help = &leaudio_broadcast_stop_help, #endif }, +#endif /* BLE_ISO_BROADCAST_SOURCE */ +#if MYNEWT_VAL(BLE_ISO) +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) + { + .sc_cmd = "big-create", + .sc_cmd_func = cmd_iso_big_create, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &cmd_iso_big_create_help, +#endif + }, + { + .sc_cmd = "big-terminate", + .sc_cmd_func = cmd_iso_big_terminate, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &cmd_iso_big_terminate_help, +#endif + }, +#endif /* BLE_ISO_BROADCAST_SOURCE */ +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK) + { + .sc_cmd = "big-sync-create", + .sc_cmd_func = cmd_iso_big_sync_create, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &cmd_iso_big_sync_create_help, #endif + }, + { + .sc_cmd = "big-sync-terminate", + .sc_cmd_func = cmd_iso_big_sync_terminate, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &cmd_iso_big_sync_terminate_help, +#endif + }, +#endif /* BLE_ISO_BROADCAST_SINK */ + { + .sc_cmd = "iso-data-path-setup", + .sc_cmd_func = cmd_iso_data_path_setup, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &cmd_iso_data_path_setup_help, +#endif + }, + { + .sc_cmd = "iso-data-path-remove", + .sc_cmd_func = cmd_iso_data_path_remove, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &cmd_iso_data_path_remove_help, +#endif + }, +#endif /* BLE_ISO */ { 0 }, }; diff --git a/apps/btshell/src/cmd_iso.c b/apps/btshell/src/cmd_iso.c new file mode 100644 index 0000000000..8d0ef343d8 --- /dev/null +++ b/apps/btshell/src/cmd_iso.c @@ -0,0 +1,513 @@ +/* + * 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. + */ + +#include "host/ble_iso.h" + +#include "cmd_iso.h" + +#include "console/console.h" +#include "shell/shell.h" + +#if (MYNEWT_VAL(BLE_ISO)) +static struct iso_rx_stats { + uint8_t bis_index; + bool ts_valid; + uint32_t ts; + uint16_t seq_num; + uint64_t total_cnt; + uint64_t valid_cnt; + uint64_t error_cnt; + uint64_t lost_cnt; +} rx_stats_pool[MYNEWT_VAL(BLE_MAX_BIS)]; + +static void +iso_rx_stats_update(uint16_t conn_handle, const struct ble_iso_rx_data_info *info, + struct iso_rx_stats *stats) +{ + stats->ts_valid = info->ts_valid; + if (stats->ts_valid) { + stats->ts = info->ts; + } + + stats->seq_num = info->seq_num; + + if (info->status == BLE_ISO_DATA_STATUS_VALID) { + stats->valid_cnt++; + } else if (info->status == BLE_ISO_DATA_STATUS_ERROR) { + stats->error_cnt++; + } else if (info->status == BLE_ISO_DATA_STATUS_LOST) { + stats->lost_cnt++; + } + + stats->total_cnt++; + + if ((stats->total_cnt % 100) == 0) { + console_printf("BIS=%d, seq_num=%d, num_rx=%lld, " + "(valid=%lld, error=%lld, lost=%lld) ", + stats->bis_index, stats->seq_num, + stats->total_cnt, stats->valid_cnt, + stats->error_cnt, stats->lost_cnt); + + if (stats->ts_valid) { + console_printf("ts=10%" PRIu32, stats->ts); + } + + console_printf("\n"); + } +} + +static void +print_iso_big_desc(const struct ble_iso_big_desc *desc) +{ + console_printf(" big_handle=0x%02x, big_sync_delay=%" PRIu32 "," + " transport_latency=%" PRIu32 ", nse=%u, bn=%u, pto=%u," + " irc=%u, max_pdu=%u, iso_interval=%u num_bis=%u", + desc->big_handle, desc->big_sync_delay, + desc->transport_latency_big, desc->nse, desc->bn, desc->pto, + desc->irc, desc->max_pdu, desc->iso_interval, desc->num_bis); + + if (desc->num_bis > 0) { + console_printf(" conn_handles="); + } + + for (uint8_t i = 0; i < desc->num_bis; i++) { + console_printf("0x%04x,", desc->conn_handle[i]); + } +} + +static int +ble_iso_event_handler(struct ble_iso_event *event, void *arg) +{ + switch (event->type) { + case BLE_ISO_EVENT_BIG_CREATE_COMPLETE: + console_printf("BIG Create Completed status: %u", + event->big_created.status); + + if (event->big_created.status == 0) { + print_iso_big_desc(&event->big_created.desc); + console_printf(" phy=0x%02x", event->big_created.phy); + } + + console_printf("\n"); + break; + + case BLE_ISO_EVENT_BIG_SYNC_ESTABLISHED: + console_printf("BIG Sync Established status: %u", + event->big_sync_established.status); + + if (event->big_sync_established.status == 0) { + print_iso_big_desc(&event->big_sync_established.desc); + } + + console_printf("\n"); + break; + + case BLE_ISO_EVENT_BIG_SYNC_TERMINATED: + console_printf("BIG Sync Terminated handle=0x%02x reason: %u\n", + event->big_terminated.big_handle, + event->big_terminated.reason); + break; + + case BLE_ISO_EVENT_ISO_RX: + iso_rx_stats_update(event->iso_rx.conn_handle, event->iso_rx.info, arg); + os_mbuf_free_chain(event->iso_rx.om); + break; + + default: + break; + } + + return 0; +} + +#if MYNEWT_VAL(SHELL_CMD_HELP) +static const struct shell_param cmd_iso_big_create_params[] = { + {"adv_handle", "PA advertising handle, usage: ="}, + {"bis_cnt", "BIS count, usage: ="}, + {"sdu_interval", "SDU interval, usage: ="}, + {"max_sdu", "Maximum SDU size, usage: ="}, + {"max_latency", "Maximum transport latency, usage: ="}, + {"rtn", "Retransmission number, usage: ="}, + {"phy", "PHY, usage: ="}, + {"packing", "Packing, usage: =, default: 1"}, + {"framing", "Framing, usage: =, default: 0"}, + {"broadcast_code", "Broadcast Code, usage: =[string], default: NULL"}, + + { NULL, NULL} +}; + +const struct shell_cmd_help cmd_iso_big_create_help = { + .summary = "Create BIG", + .usage = NULL, + .params = cmd_iso_big_create_params, +}; +#endif /* SHELL_CMD_HELP */ + +int +cmd_iso_big_create(int argc, char **argv) +{ + struct ble_iso_create_big_params params = { 0 }; + struct ble_iso_big_params big_params = { 0 }; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + params.adv_handle = parse_arg_uint8("adv_handle", &rc); + if (rc != 0) { + console_printf("invalid 'adv_handle' parameter\n"); + return rc; + } + + params.cb = ble_iso_event_handler; + + params.bis_cnt = parse_arg_uint8("bis_cnt", &rc); + if (rc != 0) { + console_printf("invalid 'bis_cnt' parameter\n"); + return rc; + } + + big_params.sdu_interval = parse_arg_uint32_bounds("sdu_interval", + 0x0000FF, 0x0FFFFF, + &rc); + if (rc != 0) { + console_printf("invalid 'sdu_interval' parameter\n"); + return rc; + } + + big_params.max_sdu = parse_arg_uint16_bounds("max_sdu", 0x0001, 0x0FFF, + &rc); + if (rc != 0) { + console_printf("invalid 'max_sdu' parameter\n"); + return rc; + } + + big_params.max_transport_latency = parse_arg_uint16_bounds("max_latency", + 0x0005, 0x0FA0, + &rc); + if (rc != 0) { + console_printf("invalid 'max_latency' parameter\n"); + return rc; + } + + big_params.rtn = parse_arg_uint8_bounds("rtn", 0x00, 0x1E, &rc); + if (rc != 0) { + console_printf("invalid 'rtn' parameter\n"); + return rc; + } + + big_params.phy = parse_arg_uint8_bounds("phy", 0, 2, &rc); + if (rc != 0) { + console_printf("invalid 'phy' parameter\n"); + return rc; + } + + big_params.packing = parse_arg_uint8_bounds_dflt("packing", 0, 1, 1, &rc); + if (rc != 0) { + console_printf("invalid 'packing' parameter\n"); + return rc; + } + + big_params.framing = parse_arg_uint8_bounds_dflt("framing", 0, 1, 0, &rc); + if (rc != 0) { + console_printf("invalid 'framing' parameter\n"); + return rc; + } + + big_params.broadcast_code = parse_arg_extract("broadcast_code"); + big_params.encryption = big_params.broadcast_code ? 1 : 0; + + rc = ble_iso_create_big(¶ms, &big_params); + if (rc != 0) { + console_printf("BIG create failed (%d)\n", rc); + return rc; + } + + return 0; +} + +#if MYNEWT_VAL(SHELL_CMD_HELP) +static const struct shell_param cmd_iso_big_terminate_params[] = { + {"big_handle", "BIG handle, usage: ="}, + + { NULL, NULL} +}; + +const struct shell_cmd_help cmd_iso_big_terminate_help = { + .summary = "Terminate BIG", + .usage = NULL, + .params = cmd_iso_big_terminate_params, +}; +#endif /* SHELL_CMD_HELP */ + +int +cmd_iso_big_terminate(int argc, char **argv) +{ + uint8_t big_handle; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + big_handle = parse_arg_uint8("big_handle", &rc); + if (rc != 0) { + console_printf("invalid 'big_handle' parameter\n"); + return rc; + } + + rc = ble_iso_terminate_big(big_handle); + if (rc != 0) { + console_printf("BIG terminate failed (%d)\n", rc); + return rc; + } + + return 0; +} + +#if MYNEWT_VAL(SHELL_CMD_HELP) +static const struct shell_param cmd_iso_big_sync_create_params[] = { + {"sync_handle", "PA sync handle, usage: ="}, + {"broadcast_code", "Broadcast Code, usage: =[string], default: NULL"}, + {"mse", "Maximum Subevents to receive data, usage: ="}, + {"sync_timeout", "BIG sync timeout, usage: ="}, + {"idxs", "BIS indexes, usage: =XX,YY,..."}, + + { NULL, NULL} +}; + +const struct shell_cmd_help cmd_iso_big_sync_create_help = { + .summary = "Synchronize to BIG", + .usage = NULL, + .params = cmd_iso_big_sync_create_params, +}; +#endif /* SHELL_CMD_HELP */ + +int +cmd_iso_big_sync_create(int argc, char **argv) +{ + struct ble_iso_bis_params bis_params[MYNEWT_VAL(BLE_MAX_BIS)]; + struct ble_iso_big_sync_create_params params = { 0 }; + uint8_t bis_idxs[MYNEWT_VAL(BLE_MAX_BIS)]; + uint8_t big_handle; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + params.sync_handle = parse_arg_uint16("sync_handle", &rc); + if (rc != 0) { + console_printf("invalid 'sync_handle' parameter\n"); + return rc; + } + + params.broadcast_code = parse_arg_extract("broadcast_code"); + + params.mse = parse_arg_uint8_dflt("mse", 0, &rc); + if (rc != 0) { + console_printf("invalid 'mse' parameter\n"); + return rc; + } + + params.sync_timeout = parse_arg_uint16("sync_timeout", &rc); + if (rc != 0) { + console_printf("invalid 'sync_timeout' parameter\n"); + return rc; + } + + rc = parse_arg_byte_stream_custom("idxs", ",", ARRAY_SIZE(bis_idxs), + bis_idxs, 0, + (unsigned int *)¶ms.bis_cnt); + if (rc != 0) { + console_printf("invalid 'idxs' parameter\n"); + return rc; + } + + for (uint8_t i = 0; i < params.bis_cnt; i++) { + bis_params[i].bis_index = bis_idxs[i]; + bis_params[i].cb = ble_iso_event_handler; + bis_params[i].cb_arg = &rx_stats_pool[i]; + + /* Reset stats */ + memset(&rx_stats_pool[i], 0, sizeof(rx_stats_pool[i])); + rx_stats_pool[i].bis_index = bis_idxs[i]; + } + + params.bis_params = bis_params; + params.cb = ble_iso_event_handler; + + rc = ble_iso_big_sync_create(¶ms, &big_handle); + if (rc != 0) { + console_printf("BIG Sync create failed (%d)\n", rc); + return rc; + } + + console_printf("New big_handle %u created\n", big_handle); + + return 0; +} + +#if MYNEWT_VAL(SHELL_CMD_HELP) +static const struct shell_param cmd_iso_big_sync_terminate_params[] = { + {"big_handle", "BIG handle, usage: ="}, + + { NULL, NULL} +}; + +const struct shell_cmd_help cmd_iso_big_sync_terminate_help = { + .summary = "Terminate BIG sync", + .usage = NULL, + .params = cmd_iso_big_sync_terminate_params, +}; +#endif /* SHELL_CMD_HELP */ + +int +cmd_iso_big_sync_terminate(int argc, char **argv) +{ + uint8_t big_handle; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + big_handle = parse_arg_uint8("big_handle", &rc); + if (rc != 0) { + console_printf("invalid 'big_handle' parameter\n"); + return rc; + } + + rc = ble_iso_big_sync_terminate(big_handle); + if (rc != 0) { + console_printf("BIG Sync terminate failed (%d)\n", rc); + return rc; + } + + return 0; +} + +static const struct parse_arg_kv_pair cmd_iso_data_dir[] = { + { "tx", BLE_ISO_DATA_DIR_TX }, + { "rx", BLE_ISO_DATA_DIR_RX }, + + { NULL } +}; + +#if MYNEWT_VAL(SHELL_CMD_HELP) +static const struct shell_param cmd_iso_data_path_setup_params[] = { + {"conn_handle", "Connection handle, usage: ="}, + {"dir", "Data path direction, usage: =[tx|rx]"}, + + { NULL, NULL} +}; + +const struct shell_cmd_help cmd_iso_data_path_setup_help = { + .summary = "Setup ISO Data Path", + .usage = NULL, + .params = cmd_iso_data_path_setup_params, +}; +#endif /* SHELL_CMD_HELP */ + +int +cmd_iso_data_path_setup(int argc, char **argv) +{ + struct ble_iso_data_path_setup_params params = { 0 }; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + params.conn_handle = parse_arg_uint16("conn_handle", &rc); + if (rc != 0) { + console_printf("invalid 'conn_handle' parameter\n"); + return rc; + } + + params.data_path_dir = parse_arg_kv("dir", cmd_iso_data_dir, &rc); + if (rc != 0) { + console_printf("invalid 'dir' parameter\n"); + return rc; + } + + /* For now, the Data Path ID is set to HCI by default */ + + rc = ble_iso_data_path_setup(¶ms); + if (rc != 0) { + console_printf("ISO Data Path setup failed (%d)\n", rc); + return rc; + } + + return 0; +} + +#if MYNEWT_VAL(SHELL_CMD_HELP) +static const struct shell_param cmd_iso_data_path_remove_params[] = { + {"conn_handle", "Connection handle, usage: ="}, + {"dir", "Data path direction, usage: =[tx|rx]"}, + + { NULL, NULL} +}; + +const struct shell_cmd_help cmd_iso_data_path_remove_help = { + .summary = "Remove ISO Data Path", + .usage = NULL, + .params = cmd_iso_data_path_remove_params, +}; +#endif /* SHELL_CMD_HELP */ + +int +cmd_iso_data_path_remove(int argc, char **argv) +{ + struct ble_iso_data_path_remove_params params = { 0 }; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + params.conn_handle = parse_arg_uint16("conn_handle", &rc); + if (rc != 0) { + console_printf("invalid 'conn_handle' parameter\n"); + return rc; + } + + params.data_path_dir = parse_arg_kv("dir", cmd_iso_data_dir, &rc); + if (rc != 0) { + console_printf("invalid 'dir' parameter\n"); + return rc; + } + + rc = ble_iso_data_path_remove(¶ms); + if (rc != 0) { + console_printf("ISO Data Path remove failed (%d)\n", rc); + return rc; + } + + return 0; +} +#endif /* BLE_ISO */ diff --git a/apps/btshell/src/cmd_iso.h b/apps/btshell/src/cmd_iso.h new file mode 100644 index 0000000000..c027c08855 --- /dev/null +++ b/apps/btshell/src/cmd_iso.h @@ -0,0 +1,39 @@ +/* + * 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_CMD_ISO_ +#define H_CMD_ISO_ + +#include "cmd.h" + +extern const struct shell_cmd_help cmd_iso_big_create_help; +extern const struct shell_cmd_help cmd_iso_big_terminate_help; +extern const struct shell_cmd_help cmd_iso_big_sync_create_help; +extern const struct shell_cmd_help cmd_iso_big_sync_terminate_help; +extern const struct shell_cmd_help cmd_iso_data_path_setup_help; +extern const struct shell_cmd_help cmd_iso_data_path_remove_help; + +int cmd_iso_big_create(int argc, char **argv); +int cmd_iso_big_terminate(int argc, char **argv); +int cmd_iso_big_sync_create(int argc, char **argv); +int cmd_iso_big_sync_terminate(int argc, char **argv); +int cmd_iso_data_path_setup(int argc, char **argv); +int cmd_iso_data_path_remove(int argc, char **argv); + +#endif /* H_CMD_ISO_ */ From 2e368caab2c7d910922f3b281adb5f5f98267014 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 25 Jan 2024 14:04:22 +0100 Subject: [PATCH 0919/1333] nimble/audio: Add LE Audio btshell target This adds btshell for native target build with the LE Audio functionality enabled. --- .../host/audio/targets/btshell_native/pkg.yml | 26 +++++++ .../audio/targets/btshell_native/syscfg.yml | 74 +++++++++++++++++++ .../audio/targets/btshell_native/target.yml | 22 ++++++ 3 files changed, 122 insertions(+) create mode 100644 nimble/host/audio/targets/btshell_native/pkg.yml create mode 100644 nimble/host/audio/targets/btshell_native/syscfg.yml create mode 100644 nimble/host/audio/targets/btshell_native/target.yml diff --git a/nimble/host/audio/targets/btshell_native/pkg.yml b/nimble/host/audio/targets/btshell_native/pkg.yml new file mode 100644 index 0000000000..67eb2d6fe5 --- /dev/null +++ b/nimble/host/audio/targets/btshell_native/pkg.yml @@ -0,0 +1,26 @@ +# +# 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: audio/targets/btshell_native +pkg.type: target +pkg.description: Target for native btshell application with LE Audio + functionality enabled +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.deps: diff --git a/nimble/host/audio/targets/btshell_native/syscfg.yml b/nimble/host/audio/targets/btshell_native/syscfg.yml new file mode 100644 index 0000000000..d631ea7987 --- /dev/null +++ b/nimble/host/audio/targets/btshell_native/syscfg.yml @@ -0,0 +1,74 @@ +# +# 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. +# + +syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + + # Enable the shell task. + SHELL_TASK: 1 + + # Set log level to info (disable debug logging). + LOG_LEVEL: 1 + + # Disable security manager (pairing and bonding). + BLE_SM_LEGACY: 0 + BLE_SM_SC: 0 + + # Default task settings + OS_MAIN_STACK_SIZE: 512 + + # SMP is not supported in this app, so disable smp-over-shell. + SHELL_MGMT: 0 + + # Whether to save data to sys/config, or just keep it in RAM. + BLE_STORE_CONFIG_PERSIST: 0 + + # Enable Extended Advertising + BLE_EXT_ADV: 1 + BLE_EXT_ADV_MAX_SIZE: 261 + + BLE_MULTI_ADV_INSTANCES: 1 + + # Enable Periodic Advertising + BLE_PERIODIC_ADV: 1 + BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 + BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: 1 + + BLE_SOCK_USE_TCP: 0 + BLE_SOCK_USE_LINUX_BLUE: 1 + BLE_SOCK_LINUX_DEV: 1 + BLE_TRANSPORT_HS: native + BLE_TRANSPORT_LL: socket + + BLE_VERSION: 54 + BLE_ISO_BROADCAST_SINK: 1 + BLE_ISO_BROADCAST_SOURCE: 1 + BLE_MAX_BIG: 1 + BLE_MAX_BIS: 2 + + CONSOLE_UART: 1 + CONSOLE_UART_BAUD: 1000000 + CONSOLE_STICKY_PROMPT: 1 + CONSOLE_UART_TX_BUF_SIZE: 256 + STATS_CLI: 1 + STATS_NAMES: 1 + + MSYS_1_BLOCK_COUNT: 100 diff --git a/nimble/host/audio/targets/btshell_native/target.yml b/nimble/host/audio/targets/btshell_native/target.yml new file mode 100644 index 0000000000..30b7d5b744 --- /dev/null +++ b/nimble/host/audio/targets/btshell_native/target.yml @@ -0,0 +1,22 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/btshell" +target.bsp: "@apache-mynewt-core/hw/bsp/native" +target.build_profile: debug From 56a23bc0feafd8726eea65863e882bb036d566af Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 27 Feb 2024 14:08:39 +0100 Subject: [PATCH 0920/1333] apps/btshell: Fix minor coding style issue This fixes minor coding style issue in btshell_scan_opts. --- apps/btshell/src/btshell.h | 4 ++-- apps/btshell/src/cmd.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h index 83dadede5a..c74ca2fa5a 100644 --- a/apps/btshell/src/btshell.h +++ b/apps/btshell/src/btshell.h @@ -90,8 +90,8 @@ struct btshell_conn { struct btshell_scan_opts { uint16_t limit; - uint8_t ignore_legacy:1; - uint8_t periodic_only:1; + uint8_t ignore_legacy : 1; + uint8_t periodic_only : 1; uint8_t name_filter_len; char name_filter[NAME_FILTER_LEN_MAX]; }; diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index 1b20078e85..1924e4f4ea 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -1107,10 +1107,10 @@ static const struct shell_cmd_help disconnect_help = { *****************************************************************************/ static struct btshell_scan_opts g_scan_opts = { - .limit = UINT16_MAX, - .ignore_legacy = 0, - .periodic_only = 0, - .name_filter_len = 0, + .limit = UINT16_MAX, + .ignore_legacy = 0, + .periodic_only = 0, + .name_filter_len = 0, }; static int From 6750a13ccb1e943006d58e8f2c21d749000c4314 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 22 Jan 2024 20:14:37 +0100 Subject: [PATCH 0921/1333] apps/btshell: Add 'silent' option to scan commands This adds option to silent the discovery results. This is useful in case there is another callback listener registered that handles the scan results, and the user does not want the default handler to print the results. --- apps/btshell/src/btshell.h | 1 + apps/btshell/src/cmd.c | 8 ++++++++ apps/btshell/src/main.c | 19 ++++++++++++++++--- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h index c74ca2fa5a..c457fd7f9f 100644 --- a/apps/btshell/src/btshell.h +++ b/apps/btshell/src/btshell.h @@ -92,6 +92,7 @@ struct btshell_scan_opts { uint16_t limit; uint8_t ignore_legacy : 1; uint8_t periodic_only : 1; + uint8_t silent : 1; uint8_t name_filter_len; char name_filter[NAME_FILTER_LEN_MAX]; }; diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index 1924e4f4ea..4c00d7ba35 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -1110,6 +1110,7 @@ static struct btshell_scan_opts g_scan_opts = { .limit = UINT16_MAX, .ignore_legacy = 0, .periodic_only = 0, + .silent = 0, .name_filter_len = 0, }; @@ -1136,6 +1137,12 @@ cmd_set_scan_opts(int argc, char **argv) return rc; } + g_scan_opts.silent = parse_arg_bool_dflt("silent", 0, &rc); + if (rc != 0) { + console_printf("invalid 'silent' parameter\n"); + return rc; + } + g_scan_opts.periodic_only = parse_arg_bool_dflt("periodic_only", 0, &rc); if (rc != 0) { console_printf("invalid 'periodic_only' parameter\n"); @@ -1160,6 +1167,7 @@ static const struct shell_param set_scan_opts_params[] = { {"decode_limit", "usage: =[0-UINT16_MAX], default: UINT16_MAX"}, {"ignore_legacy", "usage: =[0-1], default: 0"}, {"periodic_only", "usage: =[0-1], default: 0"}, + {"silent", "usage: =[0-1], default: 0"}, {"name_filter", "usage: =name, default: {none}"}, {NULL, NULL} }; diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index 0f87b5c236..6424bf6b86 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -1315,11 +1315,23 @@ btshell_gap_event(struct ble_gap_event *event, void *arg) return btshell_restart_adv(event); #if MYNEWT_VAL(BLE_EXT_ADV) - case BLE_GAP_EVENT_EXT_DISC: - btshell_decode_event_type(&event->ext_disc, arg); + case BLE_GAP_EVENT_EXT_DISC: { + struct btshell_scan_opts *scan_opts = arg; + + if (!scan_opts->silent) { + btshell_decode_event_type(&event->ext_disc, arg); + } + return 0; + } #endif - case BLE_GAP_EVENT_DISC: + case BLE_GAP_EVENT_DISC: { + struct btshell_scan_opts *scan_opts = arg; + + if (scan_opts->silent) { + return 0; + } + console_printf("received advertisement; event_type=%d rssi=%d " "addr_type=%d addr=", event->disc.event_type, event->disc.rssi, event->disc.addr.type); @@ -1337,6 +1349,7 @@ btshell_gap_event(struct ble_gap_event *event, void *arg) btshell_decode_adv_data(event->disc.data, event->disc.length_data, arg); return 0; + } case BLE_GAP_EVENT_CONN_UPDATE: console_printf("connection updated; status=%d ", From b3cd0b62805f4c3f27a5deb24d1c8fe7ab47d3d9 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 25 Jan 2024 13:30:12 +0100 Subject: [PATCH 0922/1333] nimble/audio: Add BASE parser This adds BASE parser implementation along with unit tests. --- .../host/audio/include/host/audio/ble_audio.h | 155 ++++++++ nimble/host/audio/pkg.yml | 32 ++ nimble/host/audio/src/ble_audio.c | 298 +++++++++++++++ nimble/host/audio/syscfg.yml | 21 + nimble/host/audio/test/pkg.yml | 38 ++ nimble/host/audio/test/src/ble_audio_test.c | 38 ++ .../src/testcases/ble_audio_base_parse_test.c | 361 ++++++++++++++++++ nimble/host/audio/test/syscfg.yml | 29 ++ 8 files changed, 972 insertions(+) create mode 100644 nimble/host/audio/include/host/audio/ble_audio.h create mode 100644 nimble/host/audio/pkg.yml create mode 100644 nimble/host/audio/src/ble_audio.c create mode 100644 nimble/host/audio/syscfg.yml create mode 100644 nimble/host/audio/test/pkg.yml create mode 100644 nimble/host/audio/test/src/ble_audio_test.c create mode 100644 nimble/host/audio/test/src/testcases/ble_audio_base_parse_test.c create mode 100644 nimble/host/audio/test/syscfg.yml diff --git a/nimble/host/audio/include/host/audio/ble_audio.h b/nimble/host/audio/include/host/audio/ble_audio.h new file mode 100644 index 0000000000..52d1e8a05c --- /dev/null +++ b/nimble/host/audio/include/host/audio/ble_audio.h @@ -0,0 +1,155 @@ +/* + * 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_BLE_AUDIO_ +#define H_BLE_AUDIO_ + +#include + +#include "host/ble_audio_common.h" + +/** + * BASE iterator + * + * The iterator structure used by @ref ble_audio_base_subgroup_iter and + * @ble_audio_base_bis_iter functions to iterate the BASE Level 2 and 3 elements + * (Subgroups and BISes). + * This should be used as an opaque structure and not modified manually. + * + * Example: + * @code{.c} + * struct ble_audio_base_iter subgroup_iter; + * struct ble_audio_base_iter bis_iter; + * struct ble_audio_base_group group; + * struct ble_audio_base_subgroup subgroup; + * struct ble_audio_base_bis bis; + * + * rc = ble_audio_base_parse(data, data_size, &group, &subgroup_iter); + * if (rc == 0) { + * for (uint8_t i = 0; i < group->num_subgroups; i++) { + * rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + * if (rc == 0) { + * for (uint8_t j = 0; j < subgroup->num_bis; j++) { + * rc = ble_audio_base_bis_iter(&bis_iter, &bis); + * if (rc == 0) { + * foo(&group, &subgroup, &bis); + * } + * } + * } + * } + * } + * @endcode + */ +struct ble_audio_base_iter { + /** Data pointer */ + const uint8_t *data; + + /** Base length */ + uint8_t buf_len; + + /** Original BASE pointer */ + const uint8_t *buf; + + /** Remaining number of elements */ + uint8_t num_elements; +}; + +/** @brief Broadcast Audio Source Endpoint Group structure */ +struct ble_audio_base_group { + /** Presentation Delay */ + uint32_t presentation_delay; + + /** Number of subgroups */ + uint8_t num_subgroups; +}; + +/** + * Parse the BASE received from Basic Audio Announcement data. + * + * @param[in] data Pointer to the BASE data buffer to parse. + * @param[in] data_len Length of the BASE data buffer. + * @param[out] group Group object. + * @param[out] subgroup_iter Subgroup iterator object. + * + * @return 0 on success; nonzero on failure. + */ +int ble_audio_base_parse(const uint8_t *data, uint8_t data_len, + struct ble_audio_base_group *group, + struct ble_audio_base_iter *subgroup_iter); + +/** @brief Broadcast Audio Source Endpoint Subgroup structure */ +struct ble_audio_base_subgroup { + /** Codec information for the subgroup */ + struct ble_audio_codec_id codec_id; + + /** Length of the Codec Specific Configuration for the subgroup */ + uint8_t codec_spec_config_len; + + /** Codec Specific Configuration for the subgroup */ + const uint8_t *codec_spec_config; + + /** Length of the Metadata for the subgroup */ + uint8_t metadata_len; + + /** Series of LTV structures containing Metadata */ + const uint8_t *metadata; + + /** Number of BISes in the subgroup */ + uint8_t num_bis; +}; + +/** + * @brief Basic Audio Announcement Subgroup information + * + * @param[in] subgroup_iter Subgroup iterator object. + * @param[out] subgroup Subgroup object. + * @param[out] bis_iter BIS iterator object. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_base_subgroup_iter(struct ble_audio_base_iter *subgroup_iter, + struct ble_audio_base_subgroup *subgroup, + struct ble_audio_base_iter *bis_iter); + +/** @brief Broadcast Audio Source Endpoint BIS structure */ +struct ble_audio_base_bis { + /** BIS_index value for the BIS */ + uint8_t index; + + /** Length of the Codec Specific Configuration for the BIS */ + uint8_t codec_spec_config_len; + + /** Codec Specific Configuration for the BIS */ + const uint8_t *codec_spec_config; +}; + +/** + * @brief Basic Audio Announcement Subgroup information + * + * @param[in] bis_iter BIS iterator object. + * @param[out] bis BIS object. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_base_bis_iter(struct ble_audio_base_iter *bis_iter, + struct ble_audio_base_bis *bis); + +#endif /* H_BLE_AUDIO_ */ diff --git a/nimble/host/audio/pkg.yml b/nimble/host/audio/pkg.yml new file mode 100644 index 0000000000..66d418d311 --- /dev/null +++ b/nimble/host/audio/pkg.yml @@ -0,0 +1,32 @@ +# +# 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: nimble/host/audio +pkg.description: Bluetooth LE Audio +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.experimental: 1 +pkg.keywords: + - ble + - bluetooth + - audio + +pkg.deps: + - nimble + - nimble/host diff --git a/nimble/host/audio/src/ble_audio.c b/nimble/host/audio/src/ble_audio.c new file mode 100644 index 0000000000..2ac5c68e34 --- /dev/null +++ b/nimble/host/audio/src/ble_audio.c @@ -0,0 +1,298 @@ +/* + * 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. + */ + +#include +#include + +#include "host/ble_hs.h" +#include "host/audio/ble_audio.h" + +/* Get the next subgroup data pointer */ +static const uint8_t * +ble_audio_base_subgroup_next(uint8_t num_bis, const uint8_t *data, + uint8_t data_len) +{ + uint8_t offset = 0; + + for (uint8_t i = 0; i < num_bis; i++) { + uint8_t codec_specific_config_len; + + /* BIS_index[i[k]] + Codec_Specific_Configuration_Length[i[k]] */ + if ((data_len - offset) < 2) { + return NULL; + } + + /* Skip BIS_index[i[k]] */ + offset++; + + codec_specific_config_len = data[offset]; + offset++; + + if ((data_len - offset) < codec_specific_config_len) { + return NULL; + } + + offset += codec_specific_config_len; + } + + return &data[offset]; +} + +int +ble_audio_base_parse(const uint8_t *data, uint8_t data_len, + struct ble_audio_base_group *group, + struct ble_audio_base_iter *subgroup_iter) +{ + uint8_t offset = 0; + + if (data == NULL) { + BLE_HS_LOG_ERROR("NULL data!\n"); + return BLE_HS_EINVAL; + } + + if (group == NULL) { + BLE_HS_LOG_ERROR("NULL group!\n"); + return BLE_HS_EINVAL; + } + + /* Presentation_Delay + Num_Subgroups */ + if (data_len < 4) { + return BLE_HS_EMSGSIZE; + } + + group->presentation_delay = get_le24(data); + offset += 3; + + group->num_subgroups = data[offset]; + offset++; + + if (group->num_subgroups < 1) { + BLE_HS_LOG_ERROR("Invalid BASE: no subgroups!\n"); + return BLE_HS_EINVAL; + } + + if (subgroup_iter != NULL) { + subgroup_iter->data = &data[offset]; + subgroup_iter->buf_len = data_len; + subgroup_iter->buf = data; + subgroup_iter->num_elements = group->num_subgroups; + } + + return 0; +} + +int +ble_audio_base_subgroup_iter(struct ble_audio_base_iter *subgroup_iter, + struct ble_audio_base_subgroup *subgroup, + struct ble_audio_base_iter *bis_iter) +{ + const uint8_t *data; + uint8_t data_len; + ptrdiff_t offset; + uint8_t num_subgroups; + + if (subgroup_iter == NULL) { + BLE_HS_LOG_ERROR("NULL subgroup_iter!\n"); + return BLE_HS_EINVAL; + } + + if (subgroup == NULL) { + BLE_HS_LOG_ERROR("NULL subgroup!\n"); + return BLE_HS_EINVAL; + } + + data = subgroup_iter->data; + if (data == NULL) { + return BLE_HS_ENOENT; + } + + offset = data - subgroup_iter->buf; + if (offset < 0 || offset > subgroup_iter->buf_len) { + return BLE_HS_EINVAL; + } + + num_subgroups = subgroup_iter->num_elements; + if (num_subgroups == 0) { + /* All subgroups have been parsed */ + return BLE_HS_ENOENT; + } + + data_len = subgroup_iter->buf_len - offset; + + /* Reset the offset */ + offset = 0; + + memset(subgroup, 0, sizeof(*subgroup)); + + /* Num_BIS + Codec_ID + Codec_Specific_Configuration_Length[i] */ + if (data_len < 7) { + return BLE_HS_EMSGSIZE; + } + + subgroup->num_bis = data[offset]; + offset++; + + if (subgroup->num_bis < 1) { + BLE_HS_LOG_ERROR("Invalid BASE: no BISes!\n"); + return BLE_HS_EINVAL; + } + + subgroup->codec_id.format = data[offset]; + offset++; + + subgroup->codec_id.company_id = get_le16(&data[offset]); + offset += 2; + + subgroup->codec_id.vendor_specific = get_le16(&data[offset]); + offset += 2; + + subgroup->codec_spec_config_len = data[offset]; + offset++; + + if (subgroup->codec_spec_config_len < 1) { + BLE_HS_LOG_DEBUG("Rule 4: Codec_Specific_Configuration parameters shall" + "be present at Level 2\n"); + } + + if ((data_len - offset) < subgroup->codec_spec_config_len) { + return BLE_HS_EMSGSIZE; + } + + subgroup->codec_spec_config = &data[offset]; + offset += subgroup->codec_spec_config_len; + + /* Metadata_Length[i] */ + if ((data_len - offset) < 1) { + return BLE_HS_EMSGSIZE; + } + + subgroup->metadata_len = data[offset]; + offset++; + + if (subgroup->metadata_len > 0) { + if ((data_len - offset) < subgroup->metadata_len) { + return BLE_HS_EMSGSIZE; + } + + subgroup->metadata = &data[offset]; + offset += subgroup->metadata_len; + } else { + subgroup->metadata = NULL; + } + + if (bis_iter != 0) { + bis_iter->data = &data[offset]; + bis_iter->buf_len = subgroup_iter->buf_len; + bis_iter->buf = subgroup_iter->buf; + bis_iter->num_elements = subgroup->num_bis; + } + + num_subgroups--; + + /* Update iterator */ + subgroup_iter->num_elements = num_subgroups; + + if (num_subgroups > 0) { + subgroup_iter->data = ble_audio_base_subgroup_next(subgroup->num_bis, + &data[offset], + data_len - offset); + } else { + subgroup_iter->data = NULL; + } + + return 0; +} + +int +ble_audio_base_bis_iter(struct ble_audio_base_iter *bis_iter, + struct ble_audio_base_bis *bis) +{ + const uint8_t *data; + uint8_t data_len; + ptrdiff_t offset; + uint8_t num_bis; + + if (bis_iter == NULL) { + BLE_HS_LOG_ERROR("NULL bis_iter!\n"); + return BLE_HS_EINVAL; + } + + if (bis == NULL) { + BLE_HS_LOG_ERROR("NULL bis!\n"); + return BLE_HS_EINVAL; + } + + data = bis_iter->data; + if (data == NULL) { + return BLE_HS_ENOENT; + } + + offset = data - bis_iter->buf; + if (offset < 0 || offset > bis_iter->buf_len) { + return BLE_HS_EINVAL; + } + + num_bis = bis_iter->num_elements; + if (num_bis == 0) { + /* All BISes have been parsed */ + return BLE_HS_ENOENT; + } + + data_len = bis_iter->buf_len - offset; + + /* Reset the offset */ + offset = 0; + + memset(bis, 0, sizeof(*bis)); + + /* BIS_index[i[k]] + Codec_Specific_Configuration_Length[i[k]] */ + if (data_len < 2) { + return BLE_HS_EMSGSIZE; + } + + bis->index = data[0]; + offset++; + + bis->codec_spec_config_len = data[offset]; + offset++; + + if (bis->codec_spec_config_len > 0) { + if ((data_len - offset) < bis->codec_spec_config_len) { + return BLE_HS_EMSGSIZE; + } + + bis->codec_spec_config = &data[offset]; + offset += bis->codec_spec_config_len; + } else { + bis->codec_spec_config = NULL; + } + + num_bis--; + + /* Update iterator */ + bis_iter->num_elements = num_bis; + + if (num_bis > 0) { + bis_iter->data = &data[offset]; + } else { + bis_iter->data = NULL; + } + + return 0; +} diff --git a/nimble/host/audio/syscfg.yml b/nimble/host/audio/syscfg.yml new file mode 100644 index 0000000000..d7af13d1a0 --- /dev/null +++ b/nimble/host/audio/syscfg.yml @@ -0,0 +1,21 @@ +# 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. +# + +syscfg.defs: + +syscfg.logs: diff --git a/nimble/host/audio/test/pkg.yml b/nimble/host/audio/test/pkg.yml new file mode 100644 index 0000000000..5020e9fa45 --- /dev/null +++ b/nimble/host/audio/test/pkg.yml @@ -0,0 +1,38 @@ +# +# 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: nimble/host/audio/test +pkg.type: unittest +pkg.description: "BLE Audio unit tests." +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - "@apache-mynewt-core/test/testutil" + - nimble/host/audio + +pkg.deps.SELFTEST: + - "@apache-mynewt-core/sys/console/stub" + - "@apache-mynewt-core/sys/log/full" + - "@apache-mynewt-core/sys/stats/stub" + - nimble/drivers/native + +pkg.apis: + - ble_driver diff --git a/nimble/host/audio/test/src/ble_audio_test.c b/nimble/host/audio/test/src/ble_audio_test.c new file mode 100644 index 0000000000..14fcf15f5f --- /dev/null +++ b/nimble/host/audio/test/src/ble_audio_test.c @@ -0,0 +1,38 @@ +/* + * 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. + */ + +#include "sysinit/sysinit.h" +#include "testutil/testutil.h" + +TEST_SUITE_DECL(ble_audio_base_parse_test_suite); + +TEST_SUITE(ble_audio_test) +{ + ble_audio_base_parse_test_suite(); +} + +int +main(int argc, char **argv) +{ + sysinit(); + + ble_audio_test(); + + return tu_any_failed; +} diff --git a/nimble/host/audio/test/src/testcases/ble_audio_base_parse_test.c b/nimble/host/audio/test/src/testcases/ble_audio_base_parse_test.c new file mode 100644 index 0000000000..2398d62dd2 --- /dev/null +++ b/nimble/host/audio/test/src/testcases/ble_audio_base_parse_test.c @@ -0,0 +1,361 @@ +/* + * 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. + */ + +#include "testutil/testutil.h" + +#include "host/ble_hs.h" +#include "host/audio/ble_audio.h" + +/** + * BAP_v1.0.1 Table 3.16 + * BASE structure for the logical BASE structure example + */ +static const uint8_t example_base[] = { + 0x1e, 0x00, 0x00, /* Presentation_Delay: 40 ms */ + 0x02, /* Num_Subgroups: 2 Subgroups */ + 0x02, /* Num_BIS[0]: 2 BIS in Subgroup[0] */ + 0x06, 0x00, 0x00, 0x00, 0x00, /* Codec_ID[0]: LC3 */ + 0x0a, /* Codec_Specific_Configuration_Length[0] */ + 0x02, 0x01, 0x08, /* LTV 1: Sampling_Frequency: 48000 Hz */ + 0x02, 0x02, 0x02, /* LTV 2: Frame_Duration: 10 ms */ + 0x03, 0x04, 0x64, 0x00, /* LTV 3: Octets_Per_Codec_Frame: 100 octets */ + 0x09, /* Metadata_Length[0] */ + 0x03, 0x02, 0x04, 0x00, /* LTV 1: Streaming_Audio_Contexts: Media */ + 0x04, 0x04, 0x73, 0x70, 0x61, /* LTV 2: Language: Spanish */ + 0x01, /* BIS_index[0[0]] */ + 0x06, /* Codec_Specific_Configuration_Length[0[0]] */ + 0x05, 0x03, 0x01, 0x00, 0x00, 0x00, /* LTV 1 = Audio_Channel_Allocation: FL */ + 0x02, /* BIS_index[0[1]] */ + 0x06, /* Codec_Specific_Configuration_Length[0[1]] */ + 0x05, 0x03, 0x02, 0x00, 0x00, 0x00, /* LTV 1 = Audio_Channel_Allocation: FR */ + 0x02, /* Num_BIS[1]: 2 BIS in Subgroup[0] */ + 0x06, 0x00, 0x00, 0x00, 0x00, /* Codec_ID[1]: LC3 */ + 0x0a, /* Codec_Specific_Configuration_Length[1] */ + 0x02, 0x01, 0x08, /* LTV 1: Sampling_Frequency: 48000 Hz */ + 0x02, 0x02, 0x02, /* LTV 2: Frame_Duration: 10 ms */ + 0x03, 0x04, 0x64, 0x00, /* LTV 3: Octets_Per_Codec_Frame: 100 octets */ + 0x09, /* Metadata_Length[1] */ + 0x03, 0x02, 0x04, 0x00, /* LTV 1: Streaming_Audio_Contexts: Media */ + 0x04, 0x04, 0x65, 0x6e, 0x67, /* LTV 2: Language: English */ + 0x03, /* BIS_index[1[0]] */ + 0x06, /* Codec_Specific_Configuration_Length[1[0]] */ + 0x05, 0x03, 0x01, 0x00, 0x00, 0x00, /* LTV 1 = Audio_Channel_Allocation: FL */ + 0x04, /* BIS_index[1[1]] */ + 0x06, /* Codec_Specific_Configuration_Length[1[1]] */ + 0x05, 0x03, 0x02, 0x00, 0x00, 0x00, /* LTV 1 = Audio_Channel_Allocation: FR */ +}; + +TEST_CASE_SELF(ble_audio_base_parse_test) +{ + struct ble_audio_base_subgroup subgroup; + struct ble_audio_base_group group; + struct ble_audio_base_bis bis; + struct ble_audio_base_iter subgroup_iter; + struct ble_audio_base_iter bis_iter; + int rc; + + rc = ble_audio_base_parse(example_base, (uint8_t)sizeof(example_base), + &group, &subgroup_iter); + TEST_ASSERT(rc == 0); + + TEST_ASSERT(group.presentation_delay == 30); + TEST_ASSERT(group.num_subgroups == 2); + + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == 0); + + TEST_ASSERT(subgroup.codec_id.format == 0x06); + TEST_ASSERT(subgroup.codec_id.company_id == 0x0000); + TEST_ASSERT(subgroup.codec_id.vendor_specific == 0x0000); + TEST_ASSERT(subgroup.codec_spec_config_len == 10); + TEST_ASSERT(subgroup.codec_spec_config != NULL); + TEST_ASSERT(subgroup.metadata_len == 9); + TEST_ASSERT(subgroup.num_bis == 2); + + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == 0); + + TEST_ASSERT(bis.index == 0x01); + TEST_ASSERT(bis.codec_spec_config_len == 6); + TEST_ASSERT(bis.codec_spec_config != NULL); + + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == 0); + + TEST_ASSERT(bis.index == 0x02); + TEST_ASSERT(bis.codec_spec_config_len == 6); + TEST_ASSERT(bis.codec_spec_config != NULL); + + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == BLE_HS_ENOENT); + + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == 0); + + TEST_ASSERT(subgroup.codec_id.format == 0x06); + TEST_ASSERT(subgroup.codec_id.company_id == 0x0000); + TEST_ASSERT(subgroup.codec_id.vendor_specific == 0x0000); + TEST_ASSERT(subgroup.codec_spec_config_len == 10); + TEST_ASSERT(subgroup.codec_spec_config != NULL); + TEST_ASSERT(subgroup.metadata_len == 9); + TEST_ASSERT(subgroup.num_bis == 2); + + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == 0); + + TEST_ASSERT(bis.index == 0x03); + TEST_ASSERT(bis.codec_spec_config_len == 6); + TEST_ASSERT(bis.codec_spec_config != NULL); + + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == 0); + + TEST_ASSERT(bis.index == 0x04); + TEST_ASSERT(bis.codec_spec_config_len == 6); + TEST_ASSERT(bis.codec_spec_config != NULL); + + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == BLE_HS_ENOENT); + + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == BLE_HS_ENOENT); +} + +TEST_CASE_SELF(ble_audio_base_parse_test_params) +{ + struct ble_audio_base_subgroup subgroup; + struct ble_audio_base_group group; + struct ble_audio_base_bis bis; + struct ble_audio_base_iter subgroup_iter; + struct ble_audio_base_iter bis_iter; + int rc; + + rc = ble_audio_base_parse(NULL, (uint8_t)sizeof(example_base), &group, &subgroup_iter); + TEST_ASSERT(rc == BLE_HS_EINVAL); + + rc = ble_audio_base_parse(NULL, (uint8_t)sizeof(example_base), NULL, &subgroup_iter); + TEST_ASSERT(rc == BLE_HS_EINVAL); + + rc = ble_audio_base_parse(example_base, (uint8_t)sizeof(example_base), &group, NULL); + TEST_ASSERT(rc == 0); + + rc = ble_audio_base_parse(example_base, (uint8_t)sizeof(example_base), &group, &subgroup_iter); + TEST_ASSERT(rc == 0); + + rc = ble_audio_base_subgroup_iter(NULL, &subgroup, &bis_iter); + TEST_ASSERT(rc == BLE_HS_EINVAL); + + rc = ble_audio_base_subgroup_iter(&subgroup_iter, NULL, &bis_iter); + TEST_ASSERT(rc == BLE_HS_EINVAL); + + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, NULL); + TEST_ASSERT(rc == 0); + + rc = ble_audio_base_bis_iter(NULL, &bis); + TEST_ASSERT(rc == BLE_HS_EINVAL); + + rc = ble_audio_base_bis_iter(&bis_iter, NULL); + TEST_ASSERT(rc == BLE_HS_EINVAL); +} + +TEST_CASE_SELF(ble_audio_base_parse_test_data_length) +{ + struct ble_audio_base_subgroup subgroup; + struct ble_audio_base_group group; + struct ble_audio_base_bis bis; + struct ble_audio_base_iter subgroup_iter; + struct ble_audio_base_iter bis_iter; + int rc; + + /* Incomplete: empty */ + rc = ble_audio_base_parse(example_base, 0, &group, &subgroup_iter); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Truncated: Presentation_Delay Parameter */ + rc = ble_audio_base_parse(example_base, 2, &group, &subgroup_iter); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Incomplete: no Num_Subgroups[0] Parameter */ + rc = ble_audio_base_parse(example_base, 3, &group, &subgroup_iter); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Incomplete: no Num_BIS[0] Parameter */ + rc = ble_audio_base_parse(example_base, 4, &group, &subgroup_iter); + TEST_ASSERT(rc == 0); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Truncated: Codec_ID[0] Parameter */ + rc = ble_audio_base_parse(example_base, 9, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Incomplete: no Codec_Specific_Configuration_Length[0] Parameter */ + rc = ble_audio_base_parse(example_base, 13, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Truncated: Codec_Specific_Configuration[0] Parameter */ + rc = ble_audio_base_parse(example_base, 14, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Incomplete: no Metadata_Length[0] Parameter */ + rc = ble_audio_base_parse(example_base, 21, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Truncated: Metadata[0] Parameter */ + rc = ble_audio_base_parse(example_base, 30, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Incomplete: no BIS_index[0[0]] Parameter */ + rc = ble_audio_base_parse(example_base, 31, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == 0); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Incomplete: no Codec_Specific_Configuration_Length[0[0]] Parameter */ + rc = ble_audio_base_parse(example_base, 32, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Truncated: Codec_Specific_Configuration_Length[0[0]] Parameter */ + rc = ble_audio_base_parse(example_base, 38, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Incomplete: no BIS_index[0[1]] Parameter */ + rc = ble_audio_base_parse(example_base, 39, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == 0); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Incomplete: no Codec_Specific_Configuration_Length[0[1]] Parameter */ + rc = ble_audio_base_parse(example_base, 40, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Truncated: Codec_Specific_Configuration_Length[0[1]] Parameter */ + rc = ble_audio_base_parse(example_base, 46, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == 0); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Incomplete: no Num_BIS[1] Parameter */ + rc = ble_audio_base_parse(example_base, 47, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == 0); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Truncated: Codec_ID[1] Parameter */ + rc = ble_audio_base_parse(example_base, 52, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Incomplete: no Codec_Specific_Configuration_Length[1] Parameter */ + rc = ble_audio_base_parse(example_base, 53, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Truncated: Codec_Specific_Configuration[1] Parameter */ + rc = ble_audio_base_parse(example_base, 63, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Incomplete: no Metadata_Length[1] Parameter */ + rc = ble_audio_base_parse(example_base, 64, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Truncated: Metadata[1] Parameter */ + rc = ble_audio_base_parse(example_base, 73, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Incomplete: no BIS_index[1[0]] Parameter */ + rc = ble_audio_base_parse(example_base, 74, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + TEST_ASSERT(rc == 0); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Incomplete: no Codec_Specific_Configuration_Length[1[0]] Parameter */ + rc = ble_audio_base_parse(example_base, 75, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Truncated: Codec_Specific_Configuration_Length[1[0]] Parameter */ + rc = ble_audio_base_parse(example_base, 81, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Incomplete: no BIS_index[1[1]] Parameter */ + rc = ble_audio_base_parse(example_base, 82, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == 0); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Incomplete: no Codec_Specific_Configuration_Length[1[1]] Parameter */ + rc = ble_audio_base_parse(example_base, 83, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); + + /* Truncated: Codec_Specific_Configuration_Length[0[1]] Parameter */ + rc = ble_audio_base_parse(example_base, 89, &group, &subgroup_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + TEST_ASSERT(rc == BLE_HS_EMSGSIZE); +} + +TEST_SUITE(ble_audio_base_parse_test_suite) +{ + ble_audio_base_parse_test(); + ble_audio_base_parse_test_params(); + ble_audio_base_parse_test_data_length(); +} diff --git a/nimble/host/audio/test/syscfg.yml b/nimble/host/audio/test/syscfg.yml new file mode 100644 index 0000000000..3c760594c5 --- /dev/null +++ b/nimble/host/audio/test/syscfg.yml @@ -0,0 +1,29 @@ +# +# 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. +# + +syscfg.defs: + +syscfg.vals: + # Prevent priority conflict with controller task. + MCU_TIMER_POLLER_PRIO: 1 + MCU_UART_POLLER_PRIO: 2 + NATIVE_SOCKETS_PRIO: 3 + + BLE_VERSION: 54 + BLE_HS_DEBUG: 1 From a3cef588170b47b7f42bb4f5d1f7588b668d6b16 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Wed, 21 Feb 2024 12:56:26 +0100 Subject: [PATCH 0923/1333] nimble/audio: Add LE Audio event listener This adds dedicated event listener for LE Audio events. --- .../host/audio/include/host/audio/ble_audio.h | 138 +++++++++++ nimble/host/audio/src/ble_audio.c | 232 ++++++++++++++++++ nimble/host/audio/src/ble_audio_priv.h | 27 ++ nimble/host/audio/test/src/ble_audio_test.c | 2 + .../ble_audio_listener_register_test.c | 59 +++++ nimble/host/audio/test/syscfg.yml | 2 + nimble/host/include/host/ble_audio_common.h | 4 +- .../services/auracast/src/ble_svc_auracast.c | 2 +- 8 files changed, 464 insertions(+), 2 deletions(-) create mode 100644 nimble/host/audio/src/ble_audio_priv.h create mode 100644 nimble/host/audio/test/src/testcases/ble_audio_listener_register_test.c diff --git a/nimble/host/audio/include/host/audio/ble_audio.h b/nimble/host/audio/include/host/audio/ble_audio.h index 52d1e8a05c..7d4200bb03 100644 --- a/nimble/host/audio/include/host/audio/ble_audio.h +++ b/nimble/host/audio/include/host/audio/ble_audio.h @@ -21,9 +21,147 @@ #define H_BLE_AUDIO_ #include +#include #include "host/ble_audio_common.h" +/** @brief Public Broadcast Announcement features bits */ +enum ble_audio_pub_bcst_announcement_feat { + /** Broadcast Stream Encryption */ + BLE_AUDIO_PUB_BCST_ANNOUNCEMENT_FEAT_ENCRYPTION = 1 << 0, + + /** Standard Quality Public Broadcast Audio */ + BLE_AUDIO_PUB_BCST_ANNOUNCEMENT_FEAT_SQ = 1 << 1, + + /** High Quality Public Broadcast Audio */ + BLE_AUDIO_PUB_BCST_ANNOUNCEMENT_FEAT_HQ = 1 << 2, +}; + +/** @brief Public Broadcast Announcement structure */ +struct ble_audio_pub_bcst_announcement { + /** Public Broadcast Announcement features bitfield */ + enum ble_audio_pub_bcst_announcement_feat features; + + /** Metadata length */ + uint8_t metadata_len; + + /** Metadata */ + const uint8_t *metadata; +}; + +struct ble_audio_bcst_name { + /** Broadcast Name length */ + uint8_t name_len; + + /** Broadcast Name */ + const char *name; +}; + +/** + * @defgroup ble_audio_events Bluetooth Low Energy Audio Events + * @{ + */ + +/** BLE Audio event: Broadcast Announcement */ +#define BLE_AUDIO_EVENT_BCST_ANNOUNCEMENT 0 + +/** @} */ + +/** @brief Broadcast Announcement */ +struct ble_audio_event_bcst_announcement { + /** Extended advertising report */ + const struct ble_gap_ext_disc_desc *ext_disc; + + /** Broadcast ID */ + uint32_t broadcast_id; + + /** Additional service data included in Broadcast Audio Announcement */ + const uint8_t *svc_data; + + /** Additional service data length */ + uint16_t svc_data_len; + + /** Optional Public Broadcast Announcement data */ + struct ble_audio_pub_bcst_announcement *pub_announcement_data; + + /** Optional Broadcast Name */ + struct ble_audio_bcst_name *name; +}; + +/** + * Represents a BLE Audio related event. When such an event occurs, the host + * notifies the application by passing an instance of this structure to an + * application-specified callback. + */ +struct ble_audio_event { + /** + * Indicates the type of BLE Audio event that occurred. This is one of the + * BLE_AUDIO_EVENT codes. + */ + uint8_t type; + + /** + * A discriminated union containing additional details concerning the event. + * The 'type' field indicates which member of the union is valid. + */ + union { + /** + * @ref BLE_AUDIO_EVENT_BCST_ANNOUNCEMENT + * + * Represents a received Broadcast Announcement. + */ + struct ble_audio_event_bcst_announcement bcst_announcement; + }; +}; + +/** Callback function type for handling BLE Audio events. */ +typedef int ble_audio_event_fn(struct ble_audio_event *event, void *arg); + +/** + * Event listener structure + * + * This should be used as an opaque structure and not modified manually. + */ +struct ble_audio_event_listener { + /** The function to call when a BLE Audio event occurs. */ + ble_audio_event_fn *fn; + + /** An optional argument to pass to the event handler function. */ + void *arg; + + /** Singly-linked list entry. */ + SLIST_ENTRY(ble_audio_event_listener) next; +}; + +/** + * Registers listener for BLE Audio events + * + * On success listener structure will be initialized automatically and does not + * need to be initialized prior to calling this function. To change callback + * and/or argument unregister listener first and register it again. + * + * @param[in] listener Listener structure + * @param[in] event_mask Optional event mask + * @param[in] fn Callback function + * @param[in] arg Optional callback argument + * + * @return 0 on success + * BLE_HS_EINVAL if no callback is specified + * BLE_HS_EALREADY if listener is already registered + */ +int ble_audio_event_listener_register(struct ble_audio_event_listener *listener, + ble_audio_event_fn *fn, void *arg); + +/** + * Unregisters listener for BLE Audio events + * + * @param[in] listener Listener structure + * + * @return 0 on success + * BLE_HS_ENOENT if listener was not registered + */ +int ble_audio_event_listener_unregister(struct ble_audio_event_listener *listener); + /** * BASE iterator * diff --git a/nimble/host/audio/src/ble_audio.c b/nimble/host/audio/src/ble_audio.c index 2ac5c68e34..61c42e4ff8 100644 --- a/nimble/host/audio/src/ble_audio.c +++ b/nimble/host/audio/src/ble_audio.c @@ -23,6 +23,238 @@ #include "host/ble_hs.h" #include "host/audio/ble_audio.h" +#include "ble_audio_priv.h" + +static struct ble_gap_event_listener ble_audio_gap_event_listener; +static SLIST_HEAD(, ble_audio_event_listener) ble_audio_event_listener_list = + SLIST_HEAD_INITIALIZER(ble_audio_event_listener_list); + +struct ble_audio_adv_parse_bcst_announcement_data { + struct ble_audio_event event; + struct ble_audio_pub_bcst_announcement pub; + struct ble_audio_bcst_name name; + bool success; +}; + +static int +ble_audio_adv_parse_bcst_announcement(const struct ble_hs_adv_field *field, + void *user_data) +{ + struct ble_audio_adv_parse_bcst_announcement_data *data = user_data; + struct ble_audio_event_bcst_announcement *event; + const uint8_t value_len = field->length - sizeof(field->length); + ble_uuid16_t uuid16 = BLE_UUID16_INIT(0); + uint8_t offset = 0; + + event = &data->event.bcst_announcement; + + data->success = false; + + switch (field->type) { + case BLE_HS_ADV_TYPE_SVC_DATA_UUID16: + if (value_len < 2) { + break; + } + + uuid16.value = get_le16(&field->value[offset]); + offset += 2; + + switch (uuid16.value) { + case BLE_BROADCAST_AUDIO_ANNOUNCEMENT_SVC_UUID: + if ((value_len - offset) < 3) { + /* Stop parsing */ + data->success = false; + return 0; + } + + event->broadcast_id = get_le24(&field->value[offset]); + offset += 3; + + if (value_len > offset) { + event->svc_data = &field->value[offset]; + event->svc_data_len = value_len - offset; + } + + data->success = true; + break; + + case BLE_BROADCAST_PUB_ANNOUNCEMENT_SVC_UUID: + if (event->pub_announcement_data != NULL) { + /* Ignore */ + break; + } + + if ((value_len - offset) < 2) { + /* Stop parsing */ + data->success = false; + return 0; + } + + data->pub.features = field->value[offset++]; + data->pub.metadata_len = field->value[offset++]; + + if ((value_len - offset) < data->pub.metadata_len) { + break; + } + + data->pub.metadata = &field->value[offset]; + + event->pub_announcement_data = &data->pub; + break; + + default: + break; + } + + break; + + case BLE_HS_ADV_TYPE_BROADCAST_NAME: + if (event->name != NULL) { + /* Ignore */ + break; + } + + if (value_len < 4 || value_len > 32) { + /* Stop parsing */ + data->success = false; + return 0; + } + + data->name.name = (char *)field->value; + data->name.name_len = value_len; + + event->name = &data->name; + break; + + default: + break; + } + + /* Continue parsing */ + return BLE_HS_ENOENT; +} + +static int +ble_audio_gap_event(struct ble_gap_event *gap_event, void *arg) +{ + switch (gap_event->type) { + case BLE_GAP_EVENT_EXT_DISC: { + struct ble_audio_adv_parse_bcst_announcement_data data = { 0 }; + int rc; + + rc = ble_hs_adv_parse(gap_event->ext_disc.data, + gap_event->ext_disc.length_data, + ble_audio_adv_parse_bcst_announcement, &data); + if (rc == 0 && data.success) { + data.event.type = BLE_AUDIO_EVENT_BCST_ANNOUNCEMENT; + data.event.bcst_announcement.ext_disc = &gap_event->ext_disc; + + (void)ble_audio_event_listener_call(&data.event); + } + break; + } + + default: + break; + } + + return 0; +} + +int +ble_audio_event_listener_register(struct ble_audio_event_listener *listener, + ble_audio_event_fn *fn, void *arg) +{ + struct ble_audio_event_listener *evl = NULL; + int rc; + + if (listener == NULL) { + BLE_HS_LOG_ERROR("NULL listener!\n"); + return BLE_HS_EINVAL; + } + + if (fn == NULL) { + BLE_HS_LOG_ERROR("NULL fn!\n"); + return BLE_HS_EINVAL; + } + + SLIST_FOREACH(evl, &ble_audio_event_listener_list, next) { + if (evl == listener) { + break; + } + } + + if (evl) { + return BLE_HS_EALREADY; + } + + if (SLIST_EMPTY(&ble_audio_event_listener_list)) { + rc = ble_gap_event_listener_register( + &ble_audio_gap_event_listener, + ble_audio_gap_event, NULL); + if (rc != 0) { + return rc; + } + } + + memset(listener, 0, sizeof(*listener)); + listener->fn = fn; + listener->arg = arg; + SLIST_INSERT_HEAD(&ble_audio_event_listener_list, listener, next); + + return 0; +} + +int +ble_audio_event_listener_unregister(struct ble_audio_event_listener *listener) +{ + struct ble_audio_event_listener *evl = NULL; + int rc; + + if (listener == NULL) { + BLE_HS_LOG_ERROR("NULL listener!\n"); + return BLE_HS_EINVAL; + } + + /* We check if element exists on the list only for sanity to let caller + * know whether it registered its listener before. + */ + SLIST_FOREACH(evl, &ble_audio_event_listener_list, next) { + if (evl == listener) { + break; + } + } + + if (!evl) { + return BLE_HS_ENOENT; + } + + SLIST_REMOVE(&ble_audio_event_listener_list, listener, + ble_audio_event_listener, next); + + if (SLIST_EMPTY(&ble_audio_event_listener_list)) { + rc = ble_gap_event_listener_unregister( + &ble_audio_gap_event_listener); + if (rc != 0) { + return rc; + } + } + + return 0; +} + +int +ble_audio_event_listener_call(struct ble_audio_event *event) +{ + struct ble_audio_event_listener *evl = NULL; + + SLIST_FOREACH(evl, &ble_audio_event_listener_list, next) { + evl->fn(event, evl->arg); + } + + return 0; +} + /* Get the next subgroup data pointer */ static const uint8_t * ble_audio_base_subgroup_next(uint8_t num_bis, const uint8_t *data, diff --git a/nimble/host/audio/src/ble_audio_priv.h b/nimble/host/audio/src/ble_audio_priv.h new file mode 100644 index 0000000000..bedbdaf058 --- /dev/null +++ b/nimble/host/audio/src/ble_audio_priv.h @@ -0,0 +1,27 @@ +/* + * 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_BLE_AUDIO_PRIV_ +#define H_BLE_AUDIO_PRIV_ + +#include "host/audio/ble_audio.h" + +int ble_audio_event_listener_call(struct ble_audio_event *event); + +#endif /* H_BLE_AUDIO_PRIV_ */ diff --git a/nimble/host/audio/test/src/ble_audio_test.c b/nimble/host/audio/test/src/ble_audio_test.c index 14fcf15f5f..91e4a91449 100644 --- a/nimble/host/audio/test/src/ble_audio_test.c +++ b/nimble/host/audio/test/src/ble_audio_test.c @@ -21,10 +21,12 @@ #include "testutil/testutil.h" TEST_SUITE_DECL(ble_audio_base_parse_test_suite); +TEST_CASE_DECL(ble_audio_listener_register_test); TEST_SUITE(ble_audio_test) { ble_audio_base_parse_test_suite(); + ble_audio_listener_register_test(); } int diff --git a/nimble/host/audio/test/src/testcases/ble_audio_listener_register_test.c b/nimble/host/audio/test/src/testcases/ble_audio_listener_register_test.c new file mode 100644 index 0000000000..f55b51a3c3 --- /dev/null +++ b/nimble/host/audio/test/src/testcases/ble_audio_listener_register_test.c @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#include "testutil/testutil.h" + +#include "host/ble_hs.h" +#include "host/audio/ble_audio.h" + +static struct ble_audio_event_listener event_listener; + +static int +event_handler(struct ble_audio_event *event, void *arg) +{ + return 0; +} + +TEST_CASE_SELF(ble_audio_listener_register_test) +{ + int rc; + + rc = ble_audio_event_listener_register(&event_listener, event_handler, + NULL); + TEST_ASSERT(rc == 0); + + rc = ble_audio_event_listener_register(&event_listener, event_handler, + NULL); + TEST_ASSERT(rc != 0); + + rc = ble_audio_event_listener_unregister(&event_listener); + TEST_ASSERT(rc == 0); + + rc = ble_audio_event_listener_register(NULL, event_handler, NULL); + TEST_ASSERT(rc != 0); + + rc = ble_audio_event_listener_register(&event_listener, NULL, NULL); + TEST_ASSERT(rc != 0); + + rc = ble_audio_event_listener_unregister(NULL); + TEST_ASSERT(rc != 0); + + rc = ble_audio_event_listener_unregister(&event_listener); + TEST_ASSERT(rc != 0); +} diff --git a/nimble/host/audio/test/syscfg.yml b/nimble/host/audio/test/syscfg.yml index 3c760594c5..7fad93f3fe 100644 --- a/nimble/host/audio/test/syscfg.yml +++ b/nimble/host/audio/test/syscfg.yml @@ -27,3 +27,5 @@ syscfg.vals: BLE_VERSION: 54 BLE_HS_DEBUG: 1 + + BLE_EXT_ADV: 1 diff --git a/nimble/host/include/host/ble_audio_common.h b/nimble/host/include/host/ble_audio_common.h index 815d3f4c0d..05780c0797 100644 --- a/nimble/host/include/host/ble_audio_common.h +++ b/nimble/host/include/host/ble_audio_common.h @@ -67,7 +67,9 @@ /** Broadcast Audio Announcement Service UUID. */ #define BLE_BROADCAST_AUDIO_ANNOUNCEMENT_SVC_UUID 0x1852 -#define BLE_BROADCAST_PUBLIC_BROADCAST_ANNOUNCEMENT_SVC_UUID 0x1856 + +/** Public Broadcast Announcement Service UUID. */ +#define BLE_BROADCAST_PUB_ANNOUNCEMENT_SVC_UUID 0x1856 /** * @defgroup ble_audio_sampling_rates Bluetooth Low Energy Audio Sampling Rates diff --git a/nimble/host/services/auracast/src/ble_svc_auracast.c b/nimble/host/services/auracast/src/ble_svc_auracast.c index b1bc7d33a6..7bd9112dfc 100644 --- a/nimble/host/services/auracast/src/ble_svc_auracast.c +++ b/nimble/host/services/auracast/src/ble_svc_auracast.c @@ -62,7 +62,7 @@ ble_svc_auracast_create(const struct ble_svc_auracast_create_params *params, auracast_svc_data[data_offset] = BLE_HS_ADV_TYPE_SVC_DATA_UUID16; data_offset++; put_le16(&auracast_svc_data[data_offset], - BLE_BROADCAST_PUBLIC_BROADCAST_ANNOUNCEMENT_SVC_UUID); + BLE_BROADCAST_PUB_ANNOUNCEMENT_SVC_UUID); data_offset += 2; auracast_svc_data[data_offset] = features; data_offset++; From ebe1e7804d802985bd710712e716df10cdb856fb Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Mon, 19 Feb 2024 13:26:42 +0100 Subject: [PATCH 0924/1333] host/iso: Add doxygen comments in the header file Adds missing structures and functions documentation. --- nimble/host/include/host/ble_iso.h | 184 ++++++++++++++++++++++++++++- 1 file changed, 179 insertions(+), 5 deletions(-) diff --git a/nimble/host/include/host/ble_iso.h b/nimble/host/include/host/ble_iso.h index 8b0182fa67..cdd3df881d 100644 --- a/nimble/host/include/host/ble_iso.h +++ b/nimble/host/include/host/ble_iso.h @@ -19,11 +19,25 @@ #ifndef H_BLE_ISO_ #define H_BLE_ISO_ -#include +/** + * @file ble_iso.h + * + * @brief Bluetooth ISO + * @defgroup bt_iso Bluetooth ISO + * @ingroup bt_host + * @{ + */ + +#include #include "nimble/hci_common.h" #include "syscfg/syscfg.h" +/** + * @defgroup ble_iso_events ISO Events + * @{ + */ + /** ISO event: BIG Create Completed */ #define BLE_ISO_EVENT_BIG_CREATE_COMPLETE 0 @@ -39,18 +53,62 @@ /** ISO event: ISO Data received */ #define BLE_ISO_EVENT_ISO_RX 4 +/** @} */ + /** @brief Broadcast Isochronous Group (BIG) description */ struct ble_iso_big_desc { + /** + * The identifier of the BIG. Assigned by the Host when a new BIG is + * created. + */ uint8_t big_handle; + + /** + * The maximum time in microseconds for transmission of PDUs of all BISes in + * a BIG event. + */ uint32_t big_sync_delay; + + /** + * The actual transport latency of transmitting payloads of all BISes in the + * BIG in microseconds. + */ uint32_t transport_latency_big; + + /** The number of subevents per BIS in each BIG event. */ uint8_t nse; + + /** + * The Burst Number (BN) specifies the number of new payloads in each BIS + * event. + */ uint8_t bn; + + /** + * The Pre-Transmission Offset (PTO) specifies the offset of groups that + * carry data associated with the future BIS events. + */ uint8_t pto; + + /** + * The Immediate Repetition Count (IRC) specifies the number of groups that + * carry the data associated with the current BIS event. + */ uint8_t irc; + + /** + * The maximum number of data octets (excluding the MIC, if any) that can be + * carried in each BIS Data PDU in the BIG. + */ uint16_t max_pdu; + + /** The time between two adjacent BIG anchor points in units of 1.25 ms. */ uint16_t iso_interval; + + /** The total number of BISes in the BIG. */ uint8_t num_bis; + + /** The connection handles of all the BIS in the BIG. */ uint16_t conn_handle[MYNEWT_VAL(BLE_MAX_BIS)]; }; @@ -68,7 +126,7 @@ enum ble_iso_rx_data_status { /** @brief Received ISO data info structure */ struct ble_iso_rx_data_info { - /** ISO Data timestamp. Valid if @ref ble_iso_data_info.ts_valid is set */ + /** ISO Data timestamp. Valid if @ref ble_iso_rx_data_info.ts_valid is set */ uint32_t ts; /** Packet sequence number */ @@ -77,7 +135,7 @@ struct ble_iso_rx_data_info { /** SDU length */ uint16_t sdu_len : 12; - /** ISO Data status. See @ref ble_iso_data_status */ + /** ISO Data status. See @ref ble_iso_rx_data_status */ uint16_t status : 2; /** Timestamp is valid */ @@ -146,30 +204,127 @@ struct ble_iso_event { }; }; +/** Function prototype for isochronous event callback. */ typedef int ble_iso_event_fn(struct ble_iso_event *event, void *arg); +/** Broadcast Isochronous Group (BIG) parameters */ struct ble_iso_big_params { + /** + * The time interval of the periodic SDUs in microseconds. The value shall + * be between 0x0000FF and 0x0FFFFF. + */ uint32_t sdu_interval; + + /** + * The maximum size of an SDU in octets. The value shall be between 0x0001 + * and 0x0FFF. + */ uint16_t max_sdu; + + /** + * The maximum transport latency in milliseconds. The value shall be between + * 0x0005 and 0x0FA0. + */ uint16_t max_transport_latency; + + /** + * The Retransmission Number (RTN) parameter contains the number of times + * every PDU should be retransmitted, irrespective of which BIG events the + * retransmissions occur in. The value shall be between 0x00 and 0x1E. + */ uint8_t rtn; + + /** + * The PHY parameter is a bit field that indicates the PHY used for + * transmission of PDUs of BISes in the BIG. The value shall be one of the + * following: + * o BLE_HCI_LE_PHY_1M_PREF_MASK + * o BLE_HCI_LE_PHY_2M_PREF_MASK + * o BLE_HCI_LE_PHY_CODED_PREF_MASK + */ uint8_t phy; + + /** + * Indicates the preferred method of arranging subevents of multiple BISes. + * The value shall be one of the following: + * o 0x00 - Sequential + * o 0x01 - Interleaved + */ uint8_t packing; + + /** + * Indicates whether the BIG carries framed or unframed data. The value + * shall be one of the following: + * o 0x00 - Unframed + * o 0x01 - Framed + */ uint8_t framing; + + /** + * Indicates whether the BIG is encrypted or not. The value shall be one of + * the following: + * o 0x00 - Unencrypted + * o 0x01 - Encrypted + */ uint8_t encryption; + + /** + * The 128-bit code used to derive the session key that is used to encrypt + * and decrypt BIS payloads. + */ const char *broadcast_code; }; +/** Create BIG parameters */ struct ble_iso_create_big_params { + /** The associated periodic advertising train of the BIG. */ uint8_t adv_handle; + + /** The total number of BISes in the BIG. */ uint8_t bis_cnt; + + /** Callback function for reporting the status of the procedure. */ ble_iso_event_fn *cb; + + /** + * An optional user-defined argument to be passed to the callback function. + */ void *cb_arg; }; +/** + * Initiates the creation of Broadcast Isochronous Group (BIG). It configures + * the BIG parameters based on the provided input and triggers the corresponding + * HCI command. + * + * @param create_params A pointer to the structure holding the + * parameters specific to creating the BIG. + * These parameters define the general settings + * and include a callback function for handling + * creation events. + * @param big_params A pointer to the structure holding detailed + * parameters specific to the configuration of + * the BIG. These parameters include settings + * such as SDU interval, maximum SDU size, + * transport latency, etc. + * + * @return 0 on success; + * an error code on failure. + * + * @note The actual BIG creation result will be reported through the callback + * function specified in @p create_params. + */ int ble_iso_create_big(const struct ble_iso_create_big_params *create_params, const struct ble_iso_big_params *big_params); +/** + * Terminates an existing Broadcast Isochronous Group (BIG). + * + * @param big_handle The identifier of the BIG to be terminated. + * + * @return 0 on success; + * an error code on failure. + */ int ble_iso_terminate_big(uint8_t big_handle); /** @brief BIS parameters for @ref ble_iso_big_sync_create */ @@ -295,7 +450,7 @@ struct ble_iso_data_path_setup_params { * between the Host and the Controller for a CIS, CIS configuration, or BIS * identified by the @p param->conn_handle parameter. * - * @param[in] params BIG synchronization parameters + * @param[in] param BIG synchronization parameters * * @return 0 on success; * A non-zero value on failure. @@ -318,15 +473,34 @@ struct ble_iso_data_path_remove_params { * associated with a CIS, CIS configuration, or BIS identified by the * @p param->conn_handle parameter. * - * @param[in] params BIG synchronization parameters + * @param[in] param BIG synchronization parameters * * @return 0 on success; * A non-zero value on failure. */ int ble_iso_data_path_remove(const struct ble_iso_data_path_remove_params *param); +/** + * Initiates the transmission of isochronous data. + * + * @param conn_handle The connection over which to execute the procedure. + * @param data A pointer to the data to be transmitted. + * @param data_len Number of the data octets to be transmitted. + * + * @return 0 on success; + * an error code on failure. + */ int ble_iso_tx(uint16_t conn_handle, void *data, uint16_t data_len); +/** + * Initializes memory for ISO. + * + * @return 0 on success + */ int ble_iso_init(void); +/** + * @} + */ + #endif /* H_BLE_ISO_ */ From 409aac4866af60a60516e8a50a0028173d6de73f Mon Sep 17 00:00:00 2001 From: piotrnarajowski <119607575+piotrnarajowski@users.noreply.github.com> Date: Thu, 29 Feb 2024 16:14:10 +0100 Subject: [PATCH 0925/1333] apps/bttester: Increase number of supported L2CAP CoC channels Increase BLE_L2CAP_COC_MAX_NUM value to 3. This was affecting L2CAP/ECFC/BV-27-C qualification test case. --- apps/bttester/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index d1e37ab6d9..68a60f6a24 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -97,7 +97,7 @@ syscfg.vals: RTT_NUM_BUFFERS_UP: 0 RTT_NUM_BUFFERS_DOWN: 0 - BLE_L2CAP_COC_MAX_NUM: 2 + BLE_L2CAP_COC_MAX_NUM: 3 BLE_L2CAP_SIG_MAX_PROCS: 2 BLE_L2CAP_ENHANCED_COC: 1 BLE_EATT_CHAN_NUM: 5 From a04a6d2ce642bb0f7f49bf60c8b37988152548c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 1 Mar 2024 09:40:42 +0100 Subject: [PATCH 0926/1333] host: refactor BLE Audio This patch refactors BLE Audio library to conform to new directory tree introduced in a9795706bea035d84d1577680e0814ceedc9dc58. LE Audio related files present in host/include, host/src and host/services were moved to corelated folders in host/audio. Experimental system config BLE_AUDIO enabling LE Audio feature was introduced. Naming convention for BLE Audio functions, structures and files was unified - replaced `bcst` shorthand with `broadcast`. For example, ble_audio_pub_bcst_announcement_feat was renamed to ble_audio_pub_broadcast_announcement_feat. Contents of host/include/ble_audio_common.h was incorporated into host/audio/include/audio/ble_audio.h. Apps and Auracast service were adjusted to new config and include paths. BLE_MAX_BIG and BLE_MAX_BIS renamed to BLE_ISO_MAX_BIGS and BLE_ISO_MAX_BISES, respectevaly. --- .github/test_build_apps_syscfg.yml | 1 + apps/auracast/pkg.yml | 2 +- apps/auracast/src/main.c | 4 +- apps/auracast/syscfg.yml | 6 +- apps/btshell/src/btshell.h | 2 +- apps/btshell/src/cmd_iso.c | 6 +- apps/btshell/src/cmd_leaudio.c | 4 +- apps/btshell/src/main.c | 40 +-- apps/leaudio_broadcaster/pkg.yml | 1 + apps/leaudio_broadcaster/src/main.c | 8 +- apps/leaudio_broadcaster/syscfg.yml | 5 +- .../include/audio/ble_audio.h} | 291 +++++++++++++++-- .../audio}/ble_audio_broadcast_source.h | 2 +- .../host/audio/include/host/audio/ble_audio.h | 293 ------------------ .../services/auracast/ble_svc_auracast.h | 4 +- .../{ => audio}/services/auracast/pkg.yml | 3 +- .../services/auracast/src/ble_svc_auracast.c | 2 +- nimble/host/audio/src/ble_audio.c | 25 +- .../src/ble_audio_broadcast_source.c | 6 +- nimble/host/audio/src/ble_audio_priv.h | 2 +- .../audio/targets/btshell_native/syscfg.yml | 4 +- .../src/testcases/ble_audio_base_parse_test.c | 2 +- .../ble_audio_listener_register_test.c | 2 +- nimble/host/include/host/ble_iso.h | 2 +- nimble/host/pkg.yml | 3 + nimble/host/src/ble_hs.c | 4 +- nimble/host/src/ble_iso.c | 12 +- nimble/host/syscfg.yml | 33 +- .../examples/linux/include/syscfg/syscfg.h | 8 +- .../linux_blemesh/include/syscfg/syscfg.h | 8 +- .../examples/nuttx/include/syscfg/syscfg.h | 8 +- porting/nimble/include/syscfg/syscfg.h | 8 +- porting/npl/riot/include/syscfg/syscfg.h | 8 +- .../syscfg.yml | 4 +- 34 files changed, 393 insertions(+), 420 deletions(-) rename nimble/host/{include/host/ble_audio_common.h => audio/include/audio/ble_audio.h} (58%) rename nimble/host/{include/host => audio/include/audio}/ble_audio_broadcast_source.h (99%) delete mode 100644 nimble/host/audio/include/host/audio/ble_audio.h rename nimble/host/{ => audio}/services/auracast/include/services/auracast/ble_svc_auracast.h (98%) rename nimble/host/{ => audio}/services/auracast/pkg.yml (93%) rename nimble/host/{ => audio}/services/auracast/src/ble_svc_auracast.c (98%) rename nimble/host/{ => audio}/src/ble_audio_broadcast_source.c (99%) diff --git a/.github/test_build_apps_syscfg.yml b/.github/test_build_apps_syscfg.yml index faafa8a3cb..aabcc2979d 100644 --- a/.github/test_build_apps_syscfg.yml +++ b/.github/test_build_apps_syscfg.yml @@ -27,6 +27,7 @@ syscfg.vals: BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: 1 BLE_ISO: 1 BLE_ISO_TEST: 1 + BLE_AUDIO: 1 BLE_ISO_BROADCAST_SOURCE: 1 BLE_HCI_VS: 1 BLE_POWER_CONTROL: 1 diff --git a/apps/auracast/pkg.yml b/apps/auracast/pkg.yml index 54eb3be599..fa33aa31f5 100644 --- a/apps/auracast/pkg.yml +++ b/apps/auracast/pkg.yml @@ -30,10 +30,10 @@ pkg.deps: - nimble/host/util - nimble/host/services/gap - nimble/host/store/config + - nimble/host/audio/services/auracast - "@apache-mynewt-core/kernel/os" - "@apache-mynewt-core/sys/console" - "@apache-mynewt-core/sys/log" - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/sysinit" - "@apache-mynewt-core/sys/id" - - "@apache-mynewt-nimble/nimble/host/services/auracast" diff --git a/apps/auracast/src/main.c b/apps/auracast/src/main.c index 3e7349ec89..977d643cd0 100644 --- a/apps/auracast/src/main.c +++ b/apps/auracast/src/main.c @@ -51,7 +51,7 @@ static os_membuf_t bis_mem[ static struct os_mempool bis_pool; static os_membuf_t codec_spec_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIS) * 2, 19) + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BISES) * 2, 19) ]; static struct os_mempool codec_spec_pool; @@ -156,7 +156,7 @@ auracast_init() assert(rc == 0); rc = os_mempool_init(&codec_spec_pool, - MYNEWT_VAL(BLE_MAX_BIS) * 2, 19, + MYNEWT_VAL(BLE_ISO_MAX_BISES) * 2, 19, codec_spec_mem, "codec_spec_pool"); assert(rc == 0); } diff --git a/apps/auracast/syscfg.yml b/apps/auracast/syscfg.yml index e67af5a00c..f22b92d0b9 100644 --- a/apps/auracast/syscfg.yml +++ b/apps/auracast/syscfg.yml @@ -56,7 +56,7 @@ syscfg.vals: BLE_VERSION: 54 BLE_ISO: 1 BLE_ISO_BROADCAST_SOURCE: 1 - BLE_MAX_BIG: 1 - BLE_MAX_BIS: 2 + BLE_ISO_MAX_BIGS: 1 + BLE_ISO_MAX_BISES: 2 - BLE_PHY_NRF52_HEADERMASK_WORKAROUND: 1 \ No newline at end of file + BLE_AUDIO: 1 diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h index c457fd7f9f..c2a2eb3e29 100644 --- a/apps/btshell/src/btshell.h +++ b/apps/btshell/src/btshell.h @@ -29,7 +29,7 @@ #include "host/ble_gatt.h" #include "host/ble_gap.h" #if (MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)) -#include "host/ble_audio_broadcast_source.h" +#include "audio/ble_audio_broadcast_source.h" #endif #ifdef __cplusplus diff --git a/apps/btshell/src/cmd_iso.c b/apps/btshell/src/cmd_iso.c index 8d0ef343d8..284f02111e 100644 --- a/apps/btshell/src/cmd_iso.c +++ b/apps/btshell/src/cmd_iso.c @@ -34,7 +34,7 @@ static struct iso_rx_stats { uint64_t valid_cnt; uint64_t error_cnt; uint64_t lost_cnt; -} rx_stats_pool[MYNEWT_VAL(BLE_MAX_BIS)]; +} rx_stats_pool[MYNEWT_VAL(BLE_ISO_MAX_BISES)]; static void iso_rx_stats_update(uint16_t conn_handle, const struct ble_iso_rx_data_info *info, @@ -305,9 +305,9 @@ const struct shell_cmd_help cmd_iso_big_sync_create_help = { int cmd_iso_big_sync_create(int argc, char **argv) { - struct ble_iso_bis_params bis_params[MYNEWT_VAL(BLE_MAX_BIS)]; + struct ble_iso_bis_params bis_params[MYNEWT_VAL(BLE_ISO_MAX_BISES)]; struct ble_iso_big_sync_create_params params = { 0 }; - uint8_t bis_idxs[MYNEWT_VAL(BLE_MAX_BIS)]; + uint8_t bis_idxs[MYNEWT_VAL(BLE_ISO_MAX_BISES)]; uint8_t big_handle; int rc; diff --git a/apps/btshell/src/cmd_leaudio.c b/apps/btshell/src/cmd_leaudio.c index fc4fcd17a2..2f31246cf8 100644 --- a/apps/btshell/src/cmd_leaudio.c +++ b/apps/btshell/src/cmd_leaudio.c @@ -17,13 +17,13 @@ * under the License. */ -#include "host/ble_audio_broadcast_source.h" #include "cmd_leaudio.h" #include "btshell.h" #include "console/console.h" #include "errno.h" -#if (MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)) +#if (MYNEWT_VAL(BLE_AUDIO)) +#include "audio/ble_audio_broadcast_source.h" int cmd_leaudio_base_add(int argc, char **argv) { diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index 6424bf6b86..0ba90ff131 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -41,8 +41,10 @@ #include "host/ble_gatt.h" #include "host/ble_store.h" #include "host/ble_sm.h" -#include "host/ble_audio_common.h" -#include "host/ble_audio_broadcast_source.h" +#if MYNEWT_VAL(BLE_AUDIO) +#include "audio/ble_audio_broadcast_source.h" +#include "audio/ble_audio.h" +#endif #include "host/util/util.h" /* Mandatory services. */ @@ -132,35 +134,35 @@ struct ble_sm_sc_oob_data oob_data_remote; #if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) static struct {struct ble_audio_base *base; uint8_t adv_instance;} -btshell_base_list[MYNEWT_VAL(BLE_MAX_BIG)]; +btshell_base_list[MYNEWT_VAL(BLE_ISO_MAX_BIGS)]; static os_membuf_t btshell_base_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIG), + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BIGS), sizeof(struct ble_audio_base)) ]; static struct os_mempool btshell_base_pool; static os_membuf_t btshell_big_params_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIG), + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BIGS), sizeof(struct ble_iso_big_params)) ]; static struct os_mempool btshell_big_params_pool; /** Mempool size: in worst case every BIS is in separate subgroup */ static os_membuf_t btshell_big_sub_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIS), + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BISES), sizeof(struct ble_audio_big_subgroup)) ]; static struct os_mempool btshell_big_sub_pool; static os_membuf_t btshell_bis_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIS), + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BISES), sizeof(struct ble_audio_bis)) ]; static struct os_mempool btshell_bis_pool; static os_membuf_t btshell_metadata_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIS), + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BISES), MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) - 27) ]; static struct os_mempool btshell_metadata_pool; @@ -171,12 +173,12 @@ static struct os_mempool btshell_metadata_pool; * has one. This is inefficient but possible and should not cause error if * used that way */ static os_membuf_t btshell_codec_spec_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIS) * 2, 9) + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BISES) * 2, 9) ]; static struct os_mempool btshell_codec_spec_pool; static os_membuf_t btshell_big_params_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIG), sizeof(struct ble_iso_big_params)) + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BIGS), sizeof(struct ble_iso_big_params)) ]; static struct os_mempool btshell_big_params_pool; #endif @@ -2767,7 +2769,7 @@ static int btshell_base_find_free(void) { int i; - for (i = 0; i < MYNEWT_VAL(BLE_MAX_BIG); i++) { + for (i = 0; i < MYNEWT_VAL(BLE_ISO_MAX_BIGS); i++) { if (btshell_base_list[i].base == NULL) { return i; } @@ -2780,7 +2782,7 @@ static struct ble_audio_base * btshell_base_find(uint8_t adv_instance) { int i; - for (i = 0; i < MYNEWT_VAL(BLE_MAX_BIG); i++) { + for (i = 0; i < MYNEWT_VAL(BLE_ISO_MAX_BIGS); i++) { if (btshell_base_list[i].adv_instance == adv_instance) { return btshell_base_list[i].base; } @@ -3082,38 +3084,38 @@ mynewt_main(int argc, char **argv) assert(rc == 0); #endif #if (MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)) - rc = os_mempool_init(&btshell_base_pool, MYNEWT_VAL(BLE_MAX_BIG), + rc = os_mempool_init(&btshell_base_pool, MYNEWT_VAL(BLE_ISO_MAX_BIGS), sizeof(struct ble_audio_base), btshell_base_mem, "btshell_base_pool"); assert(rc == 0); - rc = os_mempool_init(&btshell_big_params_pool, MYNEWT_VAL(BLE_MAX_BIG), + rc = os_mempool_init(&btshell_big_params_pool, MYNEWT_VAL(BLE_ISO_MAX_BIGS), sizeof(struct ble_iso_big_params), btshell_big_params_mem, "btshell_big_params_pool"); assert(rc == 0); - rc = os_mempool_init(&btshell_big_sub_pool, MYNEWT_VAL(BLE_MAX_BIS), + rc = os_mempool_init(&btshell_big_sub_pool, MYNEWT_VAL(BLE_ISO_MAX_BISES), sizeof(struct ble_audio_big_subgroup), btshell_big_sub_mem, "btshell_big_sub_pool"); assert(rc == 0); - rc = os_mempool_init(&btshell_bis_pool, MYNEWT_VAL(BLE_MAX_BIS), + rc = os_mempool_init(&btshell_bis_pool, MYNEWT_VAL(BLE_ISO_MAX_BISES), sizeof(struct ble_audio_bis), btshell_bis_mem, "btshell_bis_pool"); assert(rc == 0); - rc = os_mempool_init(&btshell_metadata_pool, MYNEWT_VAL(BLE_MAX_BIS), + rc = os_mempool_init(&btshell_metadata_pool, MYNEWT_VAL(BLE_ISO_MAX_BISES), MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) - 27, btshell_metadata_mem, "btshell_metadata_pool"); assert(rc == 0); rc = os_mempool_init(&btshell_codec_spec_pool, - MYNEWT_VAL(BLE_MAX_BIS) * 2, 19, + MYNEWT_VAL(BLE_ISO_MAX_BISES) * 2, 19, btshell_codec_spec_mem, "btshell_codec_spec_pool"); assert(rc == 0); rc = os_mempool_init(&btshell_big_params_pool, - MYNEWT_VAL(BLE_MAX_BIG), + MYNEWT_VAL(BLE_ISO_MAX_BIGS), sizeof(struct ble_iso_big_params), btshell_big_params_mem, "btshell_big_params_pool"); assert(rc == 0); diff --git a/apps/leaudio_broadcaster/pkg.yml b/apps/leaudio_broadcaster/pkg.yml index 0955da906b..95439284c7 100644 --- a/apps/leaudio_broadcaster/pkg.yml +++ b/apps/leaudio_broadcaster/pkg.yml @@ -30,6 +30,7 @@ pkg.deps: - nimble/host/util - nimble/host/services/gap - nimble/host/store/config + - nimble/host/audio - "@apache-mynewt-core/kernel/os" - "@apache-mynewt-core/sys/console" - "@apache-mynewt-core/sys/log" diff --git a/apps/leaudio_broadcaster/src/main.c b/apps/leaudio_broadcaster/src/main.c index a4e7bf98ea..52033250e1 100644 --- a/apps/leaudio_broadcaster/src/main.c +++ b/apps/leaudio_broadcaster/src/main.c @@ -24,8 +24,8 @@ #include "host/ble_hs.h" #include "host/util/util.h" -#include "host/ble_audio_broadcast_source.h" -#include "host/ble_audio_common.h" +#include "audio/ble_audio_broadcast_source.h" +#include "audio/ble_audio.h" #include "host/ble_iso.h" #include "hal/hal_gpio.h" @@ -53,7 +53,7 @@ static os_membuf_t bis_mem[ static struct os_mempool bis_pool; static os_membuf_t codec_spec_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIS) * 2, 19) + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BISES) * 2, 19) ]; static struct os_mempool codec_spec_pool; @@ -182,7 +182,7 @@ broadcaster_init() assert(rc == 0); rc = os_mempool_init(&codec_spec_pool, - MYNEWT_VAL(BLE_MAX_BIS) * 2, 19, + MYNEWT_VAL(BLE_ISO_MAX_BISES) * 2, 19, codec_spec_mem, "codec_spec_pool"); assert(rc == 0); } diff --git a/apps/leaudio_broadcaster/syscfg.yml b/apps/leaudio_broadcaster/syscfg.yml index bed16f05d2..cffb828ed3 100644 --- a/apps/leaudio_broadcaster/syscfg.yml +++ b/apps/leaudio_broadcaster/syscfg.yml @@ -52,10 +52,11 @@ syscfg.vals: MSYS_1_BLOCK_COUNT: 32 BLE_VERSION: 54 + BLE_AUDIO: 1 BLE_ISO: 1 BLE_ISO_BROADCAST_SOURCE: 1 - BLE_MAX_BIG: 1 - BLE_MAX_BIS: 2 + BLE_ISO_MAX_BIGS: 1 + BLE_ISO_MAX_BISES: 2 syscfg.vals.BSP_NRF5340: MCU_MPU_ENABLE: 1 diff --git a/nimble/host/include/host/ble_audio_common.h b/nimble/host/audio/include/audio/ble_audio.h similarity index 58% rename from nimble/host/include/host/ble_audio_common.h rename to nimble/host/audio/include/audio/ble_audio.h index 05780c0797..c1ce1dc9c8 100644 --- a/nimble/host/include/host/ble_audio_common.h +++ b/nimble/host/audio/include/audio/ble_audio.h @@ -17,26 +17,16 @@ * under the License. */ -#ifndef H_BLE_AUDIO_COMMON_ -#define H_BLE_AUDIO_COMMON_ +#ifndef H_BLE_AUDIO_ +#define H_BLE_AUDIO_ -/** - * @file ble_audio_common.h - * - * @brief Bluetooth Low Energy Audio Common API - * - * @defgroup bt_le_audio_common Bluetooth LE Audio Common - * @ingroup bt_host - * @{ - */ - -#include "stdint.h" -#include "os/queue.h" +#include +#include /** * @cond * Helper macros for BLE_AUDIO_BUILD_CODEC_CONFIG - * @{ + * @private @{ */ #define FIELD_LEN_2(_len, _type, _field) _len, _type, _field, #define FIELD_LEN_5(_len, _type, _field) _len, _type, _field, \ @@ -276,6 +266,271 @@ struct ble_audio_codec_id { uint16_t vendor_specific; }; +/** @brief Public Broadcast Announcement features bits */ +enum ble_audio_pub_broadcast_announcement_feat { + /** Broadcast Stream Encryption */ + BLE_AUDIO_PUB_BROADCAST_ANNOUNCEMENT_FEAT_ENCRYPTION = 1 << 0, + + /** Standard Quality Public Broadcast Audio */ + BLE_AUDIO_PUB_BROADCAST_ANNOUNCEMENT_FEAT_SQ = 1 << 1, + + /** High Quality Public Broadcast Audio */ + BLE_AUDIO_PUB_BROADCAST_ANNOUNCEMENT_FEAT_HQ = 1 << 2, +}; + +/** @brief Public Broadcast Announcement structure */ +struct ble_audio_pub_broadcast_announcement { + /** Public Broadcast Announcement features bitfield */ + enum ble_audio_pub_broadcast_announcement_feat features; + + /** Metadata length */ + uint8_t metadata_len; + + /** Metadata */ + const uint8_t *metadata; +}; + +struct ble_audio_broadcast_name { + /** Broadcast Name length */ + uint8_t name_len; + + /** Broadcast Name */ + const char *name; +}; + +/** + * @defgroup ble_audio_events Bluetooth Low Energy Audio Events + * @{ + */ + +/** BLE Audio event: Broadcast Announcement */ +#define BLE_AUDIO_EVENT_BROADCAST_ANNOUNCEMENT 0 + +/** @} */ + +/** @brief Broadcast Announcement */ +struct ble_audio_event_broadcast_announcement { + /** Extended advertising report */ + const struct ble_gap_ext_disc_desc *ext_disc; + + /** Broadcast ID */ + uint32_t broadcast_id; + + /** Additional service data included in Broadcast Audio Announcement */ + const uint8_t *svc_data; + + /** Additional service data length */ + uint16_t svc_data_len; + + /** Optional Public Broadcast Announcement data */ + struct ble_audio_pub_broadcast_announcement *pub_announcement_data; + + /** Optional Broadcast Name */ + struct ble_audio_broadcast_name *name; +}; + +/** + * Represents a BLE Audio related event. When such an event occurs, the host + * notifies the application by passing an instance of this structure to an + * application-specified callback. + */ +struct ble_audio_event { + /** + * Indicates the type of BLE Audio event that occurred. This is one of the + * BLE_AUDIO_EVENT codes. + */ + uint8_t type; + + /** + * A discriminated union containing additional details concerning the event. + * The 'type' field indicates which member of the union is valid. + */ + union { + /** + * @ref BLE_AUDIO_EVENT_BROADCAST_ANNOUNCEMENT + * + * Represents a received Broadcast Announcement. + */ + struct ble_audio_event_broadcast_announcement broadcast_announcement; + }; +}; + +/** Callback function type for handling BLE Audio events. */ +typedef int ble_audio_event_fn(struct ble_audio_event *event, void *arg); + +/** + * Event listener structure + * + * This should be used as an opaque structure and not modified manually. + */ +struct ble_audio_event_listener { + /** The function to call when a BLE Audio event occurs. */ + ble_audio_event_fn *fn; + + /** An optional argument to pass to the event handler function. */ + void *arg; + + /** Singly-linked list entry. */ + SLIST_ENTRY(ble_audio_event_listener) next; +}; + +/** + * Registers listener for BLE Audio events + * + * On success listener structure will be initialized automatically and does not + * need to be initialized prior to calling this function. To change callback + * and/or argument unregister listener first and register it again. + * + * @param[in] listener Listener structure + * @param[in] event_mask Optional event mask + * @param[in] fn Callback function + * @param[in] arg Optional callback argument + * + * @return 0 on success + * BLE_HS_EINVAL if no callback is specified + * BLE_HS_EALREADY if listener is already registered + */ +int ble_audio_event_listener_register(struct ble_audio_event_listener *listener, + ble_audio_event_fn *fn, void *arg); + +/** + * Unregisters listener for BLE Audio events + * + * @param[in] listener Listener structure + * + * @return 0 on success + * BLE_HS_ENOENT if listener was not registered + */ +int ble_audio_event_listener_unregister(struct ble_audio_event_listener *listener); + +/** + * BASE iterator + * + * The iterator structure used by @ref ble_audio_base_subgroup_iter and + * @ble_audio_base_bis_iter functions to iterate the BASE Level 2 and 3 elements + * (Subgroups and BISes). + * This should be used as an opaque structure and not modified manually. + * + * Example: + * @code{.c} + * struct ble_audio_base_iter subgroup_iter; + * struct ble_audio_base_iter bis_iter; + * struct ble_audio_base_group group; + * struct ble_audio_base_subgroup subgroup; + * struct ble_audio_base_bis bis; + * + * rc = ble_audio_base_parse(data, data_size, &group, &subgroup_iter); + * if (rc == 0) { + * for (uint8_t i = 0; i < group->num_subgroups; i++) { + * rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); + * if (rc == 0) { + * for (uint8_t j = 0; j < subgroup->num_bis; j++) { + * rc = ble_audio_base_bis_iter(&bis_iter, &bis); + * if (rc == 0) { + * foo(&group, &subgroup, &bis); + * } + * } + * } + * } + * } + * @endcode + */ +struct ble_audio_base_iter { + /** Data pointer */ + const uint8_t *data; + + /** Base length */ + uint8_t buf_len; + + /** Original BASE pointer */ + const uint8_t *buf; + + /** Remaining number of elements */ + uint8_t num_elements; +}; + +/** @brief Broadcast Audio Source Endpoint Group structure */ +struct ble_audio_base_group { + /** Presentation Delay */ + uint32_t presentation_delay; + + /** Number of subgroups */ + uint8_t num_subgroups; +}; + +/** + * Parse the BASE received from Basic Audio Announcement data. + * + * @param[in] data Pointer to the BASE data buffer to parse. + * @param[in] data_len Length of the BASE data buffer. + * @param[out] group Group object. + * @param[out] subgroup_iter Subgroup iterator object. + * + * @return 0 on success; nonzero on failure. + */ +int ble_audio_base_parse(const uint8_t *data, uint8_t data_len, + struct ble_audio_base_group *group, + struct ble_audio_base_iter *subgroup_iter); + +/** @brief Broadcast Audio Source Endpoint Subgroup structure */ +struct ble_audio_base_subgroup { + /** Codec information for the subgroup */ + struct ble_audio_codec_id codec_id; + + /** Length of the Codec Specific Configuration for the subgroup */ + uint8_t codec_spec_config_len; + + /** Codec Specific Configuration for the subgroup */ + const uint8_t *codec_spec_config; + + /** Length of the Metadata for the subgroup */ + uint8_t metadata_len; + + /** Series of LTV structures containing Metadata */ + const uint8_t *metadata; + + /** Number of BISes in the subgroup */ + uint8_t num_bis; +}; + +/** + * @brief Basic Audio Announcement Subgroup information + * + * @param[in] subgroup_iter Subgroup iterator object. + * @param[out] subgroup Subgroup object. + * @param[out] bis_iter BIS iterator object. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_base_subgroup_iter(struct ble_audio_base_iter *subgroup_iter, + struct ble_audio_base_subgroup *subgroup, + struct ble_audio_base_iter *bis_iter); + +/** @brief Broadcast Audio Source Endpoint BIS structure */ +struct ble_audio_base_bis { + /** BIS_index value for the BIS */ + uint8_t index; + + /** Length of the Codec Specific Configuration for the BIS */ + uint8_t codec_spec_config_len; + + /** Codec Specific Configuration for the BIS */ + const uint8_t *codec_spec_config; +}; + +/** + * @brief Basic Audio Announcement Subgroup information + * + * @param[in] bis_iter BIS iterator object. + * @param[out] bis BIS object. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_base_bis_iter(struct ble_audio_base_iter *bis_iter, + struct ble_audio_base_bis *bis); + /** Broadcast Isochronous Streams (BIS) */ struct ble_audio_bis { /** Pointer to next BIS in subgroup */ @@ -333,8 +588,4 @@ struct ble_audio_base { STAILQ_HEAD(, ble_audio_big_subgroup) subs; }; -/** - * @} - */ - -#endif /* H_BLE_AUDIO_COMMON_ */ +#endif /* H_BLE_AUDIO_ */ diff --git a/nimble/host/include/host/ble_audio_broadcast_source.h b/nimble/host/audio/include/audio/ble_audio_broadcast_source.h similarity index 99% rename from nimble/host/include/host/ble_audio_broadcast_source.h rename to nimble/host/audio/include/audio/ble_audio_broadcast_source.h index 605aa5b207..839449cbe3 100644 --- a/nimble/host/include/host/ble_audio_broadcast_source.h +++ b/nimble/host/audio/include/audio/ble_audio_broadcast_source.h @@ -33,7 +33,7 @@ #include #include "host/ble_gap.h" #include "host/ble_iso.h" -#include "host/ble_audio_common.h" +#include "ble_audio.h" /** Parameters used for creating BASE configuration. */ struct ble_broadcast_create_params { diff --git a/nimble/host/audio/include/host/audio/ble_audio.h b/nimble/host/audio/include/host/audio/ble_audio.h deleted file mode 100644 index 7d4200bb03..0000000000 --- a/nimble/host/audio/include/host/audio/ble_audio.h +++ /dev/null @@ -1,293 +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_BLE_AUDIO_ -#define H_BLE_AUDIO_ - -#include -#include - -#include "host/ble_audio_common.h" - -/** @brief Public Broadcast Announcement features bits */ -enum ble_audio_pub_bcst_announcement_feat { - /** Broadcast Stream Encryption */ - BLE_AUDIO_PUB_BCST_ANNOUNCEMENT_FEAT_ENCRYPTION = 1 << 0, - - /** Standard Quality Public Broadcast Audio */ - BLE_AUDIO_PUB_BCST_ANNOUNCEMENT_FEAT_SQ = 1 << 1, - - /** High Quality Public Broadcast Audio */ - BLE_AUDIO_PUB_BCST_ANNOUNCEMENT_FEAT_HQ = 1 << 2, -}; - -/** @brief Public Broadcast Announcement structure */ -struct ble_audio_pub_bcst_announcement { - /** Public Broadcast Announcement features bitfield */ - enum ble_audio_pub_bcst_announcement_feat features; - - /** Metadata length */ - uint8_t metadata_len; - - /** Metadata */ - const uint8_t *metadata; -}; - -struct ble_audio_bcst_name { - /** Broadcast Name length */ - uint8_t name_len; - - /** Broadcast Name */ - const char *name; -}; - -/** - * @defgroup ble_audio_events Bluetooth Low Energy Audio Events - * @{ - */ - -/** BLE Audio event: Broadcast Announcement */ -#define BLE_AUDIO_EVENT_BCST_ANNOUNCEMENT 0 - -/** @} */ - -/** @brief Broadcast Announcement */ -struct ble_audio_event_bcst_announcement { - /** Extended advertising report */ - const struct ble_gap_ext_disc_desc *ext_disc; - - /** Broadcast ID */ - uint32_t broadcast_id; - - /** Additional service data included in Broadcast Audio Announcement */ - const uint8_t *svc_data; - - /** Additional service data length */ - uint16_t svc_data_len; - - /** Optional Public Broadcast Announcement data */ - struct ble_audio_pub_bcst_announcement *pub_announcement_data; - - /** Optional Broadcast Name */ - struct ble_audio_bcst_name *name; -}; - -/** - * Represents a BLE Audio related event. When such an event occurs, the host - * notifies the application by passing an instance of this structure to an - * application-specified callback. - */ -struct ble_audio_event { - /** - * Indicates the type of BLE Audio event that occurred. This is one of the - * BLE_AUDIO_EVENT codes. - */ - uint8_t type; - - /** - * A discriminated union containing additional details concerning the event. - * The 'type' field indicates which member of the union is valid. - */ - union { - /** - * @ref BLE_AUDIO_EVENT_BCST_ANNOUNCEMENT - * - * Represents a received Broadcast Announcement. - */ - struct ble_audio_event_bcst_announcement bcst_announcement; - }; -}; - -/** Callback function type for handling BLE Audio events. */ -typedef int ble_audio_event_fn(struct ble_audio_event *event, void *arg); - -/** - * Event listener structure - * - * This should be used as an opaque structure and not modified manually. - */ -struct ble_audio_event_listener { - /** The function to call when a BLE Audio event occurs. */ - ble_audio_event_fn *fn; - - /** An optional argument to pass to the event handler function. */ - void *arg; - - /** Singly-linked list entry. */ - SLIST_ENTRY(ble_audio_event_listener) next; -}; - -/** - * Registers listener for BLE Audio events - * - * On success listener structure will be initialized automatically and does not - * need to be initialized prior to calling this function. To change callback - * and/or argument unregister listener first and register it again. - * - * @param[in] listener Listener structure - * @param[in] event_mask Optional event mask - * @param[in] fn Callback function - * @param[in] arg Optional callback argument - * - * @return 0 on success - * BLE_HS_EINVAL if no callback is specified - * BLE_HS_EALREADY if listener is already registered - */ -int ble_audio_event_listener_register(struct ble_audio_event_listener *listener, - ble_audio_event_fn *fn, void *arg); - -/** - * Unregisters listener for BLE Audio events - * - * @param[in] listener Listener structure - * - * @return 0 on success - * BLE_HS_ENOENT if listener was not registered - */ -int ble_audio_event_listener_unregister(struct ble_audio_event_listener *listener); - -/** - * BASE iterator - * - * The iterator structure used by @ref ble_audio_base_subgroup_iter and - * @ble_audio_base_bis_iter functions to iterate the BASE Level 2 and 3 elements - * (Subgroups and BISes). - * This should be used as an opaque structure and not modified manually. - * - * Example: - * @code{.c} - * struct ble_audio_base_iter subgroup_iter; - * struct ble_audio_base_iter bis_iter; - * struct ble_audio_base_group group; - * struct ble_audio_base_subgroup subgroup; - * struct ble_audio_base_bis bis; - * - * rc = ble_audio_base_parse(data, data_size, &group, &subgroup_iter); - * if (rc == 0) { - * for (uint8_t i = 0; i < group->num_subgroups; i++) { - * rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, &bis_iter); - * if (rc == 0) { - * for (uint8_t j = 0; j < subgroup->num_bis; j++) { - * rc = ble_audio_base_bis_iter(&bis_iter, &bis); - * if (rc == 0) { - * foo(&group, &subgroup, &bis); - * } - * } - * } - * } - * } - * @endcode - */ -struct ble_audio_base_iter { - /** Data pointer */ - const uint8_t *data; - - /** Base length */ - uint8_t buf_len; - - /** Original BASE pointer */ - const uint8_t *buf; - - /** Remaining number of elements */ - uint8_t num_elements; -}; - -/** @brief Broadcast Audio Source Endpoint Group structure */ -struct ble_audio_base_group { - /** Presentation Delay */ - uint32_t presentation_delay; - - /** Number of subgroups */ - uint8_t num_subgroups; -}; - -/** - * Parse the BASE received from Basic Audio Announcement data. - * - * @param[in] data Pointer to the BASE data buffer to parse. - * @param[in] data_len Length of the BASE data buffer. - * @param[out] group Group object. - * @param[out] subgroup_iter Subgroup iterator object. - * - * @return 0 on success; nonzero on failure. - */ -int ble_audio_base_parse(const uint8_t *data, uint8_t data_len, - struct ble_audio_base_group *group, - struct ble_audio_base_iter *subgroup_iter); - -/** @brief Broadcast Audio Source Endpoint Subgroup structure */ -struct ble_audio_base_subgroup { - /** Codec information for the subgroup */ - struct ble_audio_codec_id codec_id; - - /** Length of the Codec Specific Configuration for the subgroup */ - uint8_t codec_spec_config_len; - - /** Codec Specific Configuration for the subgroup */ - const uint8_t *codec_spec_config; - - /** Length of the Metadata for the subgroup */ - uint8_t metadata_len; - - /** Series of LTV structures containing Metadata */ - const uint8_t *metadata; - - /** Number of BISes in the subgroup */ - uint8_t num_bis; -}; - -/** - * @brief Basic Audio Announcement Subgroup information - * - * @param[in] subgroup_iter Subgroup iterator object. - * @param[out] subgroup Subgroup object. - * @param[out] bis_iter BIS iterator object. - * - * @return 0 on success; - * A non-zero value on failure. - */ -int ble_audio_base_subgroup_iter(struct ble_audio_base_iter *subgroup_iter, - struct ble_audio_base_subgroup *subgroup, - struct ble_audio_base_iter *bis_iter); - -/** @brief Broadcast Audio Source Endpoint BIS structure */ -struct ble_audio_base_bis { - /** BIS_index value for the BIS */ - uint8_t index; - - /** Length of the Codec Specific Configuration for the BIS */ - uint8_t codec_spec_config_len; - - /** Codec Specific Configuration for the BIS */ - const uint8_t *codec_spec_config; -}; - -/** - * @brief Basic Audio Announcement Subgroup information - * - * @param[in] bis_iter BIS iterator object. - * @param[out] bis BIS object. - * - * @return 0 on success; - * A non-zero value on failure. - */ -int ble_audio_base_bis_iter(struct ble_audio_base_iter *bis_iter, - struct ble_audio_base_bis *bis); - -#endif /* H_BLE_AUDIO_ */ diff --git a/nimble/host/services/auracast/include/services/auracast/ble_svc_auracast.h b/nimble/host/audio/services/auracast/include/services/auracast/ble_svc_auracast.h similarity index 98% rename from nimble/host/services/auracast/include/services/auracast/ble_svc_auracast.h rename to nimble/host/audio/services/auracast/include/services/auracast/ble_svc_auracast.h index 560adb8b19..900b6fddaa 100644 --- a/nimble/host/services/auracast/include/services/auracast/ble_svc_auracast.h +++ b/nimble/host/audio/services/auracast/include/services/auracast/ble_svc_auracast.h @@ -19,8 +19,8 @@ #include #include "host/ble_gap.h" -#include "host/ble_audio_common.h" -#include "host/ble_audio_broadcast_source.h" +#include "audio/ble_audio.h" +#include "audio/ble_audio_broadcast_source.h" struct ble_svc_auracast_create_params { /** Broadcast Audio Source Endpoint */ diff --git a/nimble/host/services/auracast/pkg.yml b/nimble/host/audio/services/auracast/pkg.yml similarity index 93% rename from nimble/host/services/auracast/pkg.yml rename to nimble/host/audio/services/auracast/pkg.yml index a4d0013f93..a2533b29da 100644 --- a/nimble/host/services/auracast/pkg.yml +++ b/nimble/host/audio/services/auracast/pkg.yml @@ -16,7 +16,7 @@ # under the License. # -pkg.name: nimble/host/services/auracast +pkg.name: nimble/host/audio/services/auracast pkg.description: Implements Auracast service pkg.author: "Apache Mynewt " pkg.homepage: "http://mynewt.apache.org/" @@ -28,3 +28,4 @@ pkg.keywords: pkg.deps: - nimble/host + - nimble/host/audio diff --git a/nimble/host/services/auracast/src/ble_svc_auracast.c b/nimble/host/audio/services/auracast/src/ble_svc_auracast.c similarity index 98% rename from nimble/host/services/auracast/src/ble_svc_auracast.c rename to nimble/host/audio/services/auracast/src/ble_svc_auracast.c index 7bd9112dfc..b323e64bf0 100644 --- a/nimble/host/services/auracast/src/ble_svc_auracast.c +++ b/nimble/host/audio/services/auracast/src/ble_svc_auracast.c @@ -21,7 +21,7 @@ #include "host/ble_gap.h" #include "host/ble_hs.h" -#include "host/ble_audio_broadcast_source.h" +#include "audio/ble_audio_broadcast_source.h" #include "services/auracast/ble_svc_auracast.h" int diff --git a/nimble/host/audio/src/ble_audio.c b/nimble/host/audio/src/ble_audio.c index 61c42e4ff8..f7597aaf72 100644 --- a/nimble/host/audio/src/ble_audio.c +++ b/nimble/host/audio/src/ble_audio.c @@ -21,7 +21,7 @@ #include #include "host/ble_hs.h" -#include "host/audio/ble_audio.h" +#include "audio/ble_audio.h" #include "ble_audio_priv.h" @@ -29,24 +29,23 @@ static struct ble_gap_event_listener ble_audio_gap_event_listener; static SLIST_HEAD(, ble_audio_event_listener) ble_audio_event_listener_list = SLIST_HEAD_INITIALIZER(ble_audio_event_listener_list); -struct ble_audio_adv_parse_bcst_announcement_data { +struct ble_audio_adv_parse_broadcast_announcement_data { struct ble_audio_event event; - struct ble_audio_pub_bcst_announcement pub; - struct ble_audio_bcst_name name; + struct ble_audio_pub_broadcast_announcement pub; + struct ble_audio_broadcast_name name; bool success; }; static int -ble_audio_adv_parse_bcst_announcement(const struct ble_hs_adv_field *field, - void *user_data) +ble_audio_adv_parse_broadcast_announcement(const struct ble_hs_adv_field *field, void *user_data) { - struct ble_audio_adv_parse_bcst_announcement_data *data = user_data; - struct ble_audio_event_bcst_announcement *event; + struct ble_audio_adv_parse_broadcast_announcement_data *data = user_data; + struct ble_audio_event_broadcast_announcement *event; const uint8_t value_len = field->length - sizeof(field->length); ble_uuid16_t uuid16 = BLE_UUID16_INIT(0); uint8_t offset = 0; - event = &data->event.bcst_announcement; + event = &data->event.broadcast_announcement; data->success = false; @@ -139,15 +138,15 @@ ble_audio_gap_event(struct ble_gap_event *gap_event, void *arg) { switch (gap_event->type) { case BLE_GAP_EVENT_EXT_DISC: { - struct ble_audio_adv_parse_bcst_announcement_data data = { 0 }; + struct ble_audio_adv_parse_broadcast_announcement_data data = { 0 }; int rc; rc = ble_hs_adv_parse(gap_event->ext_disc.data, gap_event->ext_disc.length_data, - ble_audio_adv_parse_bcst_announcement, &data); + ble_audio_adv_parse_broadcast_announcement, &data); if (rc == 0 && data.success) { - data.event.type = BLE_AUDIO_EVENT_BCST_ANNOUNCEMENT; - data.event.bcst_announcement.ext_disc = &gap_event->ext_disc; + data.event.type = BLE_AUDIO_EVENT_BROADCAST_ANNOUNCEMENT; + data.event.broadcast_announcement.ext_disc = &gap_event->ext_disc; (void)ble_audio_event_listener_call(&data.event); } diff --git a/nimble/host/src/ble_audio_broadcast_source.c b/nimble/host/audio/src/ble_audio_broadcast_source.c similarity index 99% rename from nimble/host/src/ble_audio_broadcast_source.c rename to nimble/host/audio/src/ble_audio_broadcast_source.c index 2891658182..d243a5f197 100644 --- a/nimble/host/src/ble_audio_broadcast_source.c +++ b/nimble/host/audio/src/ble_audio_broadcast_source.c @@ -18,7 +18,7 @@ */ #include "host/ble_uuid.h" -#include "host/ble_audio_broadcast_source.h" +#include "audio/ble_audio_broadcast_source.h" #include "os/util.h" @@ -35,7 +35,7 @@ struct ble_audio_broadcast { static SLIST_HEAD(, ble_audio_broadcast) ble_audio_broadcasts; static struct os_mempool ble_audio_broadcast_pool; static os_membuf_t ble_audio_broadcast_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIG), + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BIGS), sizeof(struct ble_audio_broadcast))]; static bool @@ -483,7 +483,7 @@ ble_audio_broadcast_init(void) SLIST_INIT(&ble_audio_broadcasts); rc = os_mempool_init(&ble_audio_broadcast_pool, - MYNEWT_VAL(BLE_MAX_BIG), + MYNEWT_VAL(BLE_ISO_MAX_BIGS), sizeof(struct ble_audio_broadcast), ble_audio_broadcast_mem, "ble_audio_broadcast_pool"); SYSINIT_PANIC_ASSERT(rc == 0); diff --git a/nimble/host/audio/src/ble_audio_priv.h b/nimble/host/audio/src/ble_audio_priv.h index bedbdaf058..10f0109ddc 100644 --- a/nimble/host/audio/src/ble_audio_priv.h +++ b/nimble/host/audio/src/ble_audio_priv.h @@ -20,7 +20,7 @@ #ifndef H_BLE_AUDIO_PRIV_ #define H_BLE_AUDIO_PRIV_ -#include "host/audio/ble_audio.h" +#include "audio/ble_audio.h" int ble_audio_event_listener_call(struct ble_audio_event *event); diff --git a/nimble/host/audio/targets/btshell_native/syscfg.yml b/nimble/host/audio/targets/btshell_native/syscfg.yml index d631ea7987..e9db007074 100644 --- a/nimble/host/audio/targets/btshell_native/syscfg.yml +++ b/nimble/host/audio/targets/btshell_native/syscfg.yml @@ -61,8 +61,8 @@ syscfg.vals: BLE_VERSION: 54 BLE_ISO_BROADCAST_SINK: 1 BLE_ISO_BROADCAST_SOURCE: 1 - BLE_MAX_BIG: 1 - BLE_MAX_BIS: 2 + BLE_ISO_MAX_BIGS: 1 + BLE_ISO_MAX_BISES: 2 CONSOLE_UART: 1 CONSOLE_UART_BAUD: 1000000 diff --git a/nimble/host/audio/test/src/testcases/ble_audio_base_parse_test.c b/nimble/host/audio/test/src/testcases/ble_audio_base_parse_test.c index 2398d62dd2..3231b8539b 100644 --- a/nimble/host/audio/test/src/testcases/ble_audio_base_parse_test.c +++ b/nimble/host/audio/test/src/testcases/ble_audio_base_parse_test.c @@ -20,7 +20,7 @@ #include "testutil/testutil.h" #include "host/ble_hs.h" -#include "host/audio/ble_audio.h" +#include "audio/ble_audio.h" /** * BAP_v1.0.1 Table 3.16 diff --git a/nimble/host/audio/test/src/testcases/ble_audio_listener_register_test.c b/nimble/host/audio/test/src/testcases/ble_audio_listener_register_test.c index f55b51a3c3..363632ecba 100644 --- a/nimble/host/audio/test/src/testcases/ble_audio_listener_register_test.c +++ b/nimble/host/audio/test/src/testcases/ble_audio_listener_register_test.c @@ -20,7 +20,7 @@ #include "testutil/testutil.h" #include "host/ble_hs.h" -#include "host/audio/ble_audio.h" +#include "audio/ble_audio.h" static struct ble_audio_event_listener event_listener; diff --git a/nimble/host/include/host/ble_iso.h b/nimble/host/include/host/ble_iso.h index cdd3df881d..1bae3366d4 100644 --- a/nimble/host/include/host/ble_iso.h +++ b/nimble/host/include/host/ble_iso.h @@ -109,7 +109,7 @@ struct ble_iso_big_desc { uint8_t num_bis; /** The connection handles of all the BIS in the BIG. */ - uint16_t conn_handle[MYNEWT_VAL(BLE_MAX_BIS)]; + uint16_t conn_handle[MYNEWT_VAL(BLE_ISO_MAX_BISES)]; }; /** @brief Received ISO Data status possible values */ diff --git a/nimble/host/pkg.yml b/nimble/host/pkg.yml index cab496caed..b4df8f8712 100644 --- a/nimble/host/pkg.yml +++ b/nimble/host/pkg.yml @@ -32,6 +32,9 @@ pkg.deps: - nimble - nimble/transport +pkg.deps.BLE_AUDIO: + - nimble/host/audio + pkg.deps.BLE_SM_LEGACY: - "@apache-mynewt-core/crypto/tinycrypt" diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index d084c041a1..147837d9f3 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -24,7 +24,9 @@ #include "syscfg/syscfg.h" #include "stats/stats.h" #include "host/ble_hs.h" -#include "host/ble_audio_broadcast_source.h" +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) +#include "audio/ble_audio_broadcast_source.h" +#endif #include "ble_hs_priv.h" #include "ble_iso_priv.h" #include "nimble/nimble_npl.h" diff --git a/nimble/host/src/ble_iso.c b/nimble/host/src/ble_iso.c index 90bd613d05..503cdd0d03 100644 --- a/nimble/host/src/ble_iso.c +++ b/nimble/host/src/ble_iso.c @@ -87,10 +87,10 @@ static SLIST_HEAD(, ble_iso_big) ble_iso_bigs; static SLIST_HEAD(, ble_iso_conn) ble_iso_conns; static struct os_mempool ble_iso_big_pool; static os_membuf_t ble_iso_big_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIG), sizeof (struct ble_iso_big))]; + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BIGS), sizeof (struct ble_iso_big))]; static struct os_mempool ble_iso_bis_pool; static os_membuf_t ble_iso_bis_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_MAX_BIS), sizeof (struct ble_iso_bis))]; + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BISES), sizeof (struct ble_iso_bis))]; static void ble_iso_conn_append(struct ble_iso_conn *conn) @@ -234,7 +234,7 @@ ble_iso_create_big(const struct ble_iso_create_big_params *create_params, struct ble_iso_big *big; cp.adv_handle = create_params->adv_handle; - if (create_params->bis_cnt > MYNEWT_VAL(BLE_MAX_BIS)) { + if (create_params->bis_cnt > MYNEWT_VAL(BLE_ISO_MAX_BISES)) { return BLE_HS_EINVAL; } @@ -498,7 +498,7 @@ ble_iso_big_sync_create(const struct ble_iso_big_sync_create_params *param, uint8_t *big_handle) { struct ble_hci_le_big_create_sync_cp *cp; - uint8_t buf[sizeof(*cp) + MYNEWT_VAL(BLE_MAX_BIS)]; + uint8_t buf[sizeof(*cp) + MYNEWT_VAL(BLE_ISO_MAX_BISES)]; struct ble_iso_big *big; int rc; @@ -922,13 +922,13 @@ ble_iso_init(void) SLIST_INIT(&ble_iso_bigs); rc = os_mempool_init(&ble_iso_big_pool, - MYNEWT_VAL(BLE_MAX_BIG), + MYNEWT_VAL(BLE_ISO_MAX_BIGS), sizeof (struct ble_iso_big), ble_iso_big_mem, "ble_iso_big_pool"); SYSINIT_PANIC_ASSERT(rc == 0); rc = os_mempool_init(&ble_iso_bis_pool, - MYNEWT_VAL(BLE_MAX_BIS), + MYNEWT_VAL(BLE_ISO_MAX_BISES), sizeof (struct ble_iso_bis), ble_iso_bis_mem, "ble_iso_bis_pool"); SYSINIT_PANIC_ASSERT(rc == 0); diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index faaaa0052d..2848b648d1 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -440,6 +440,11 @@ syscfg.defs: that have been enabled in the stack, such as GATT support. value: 0 + BLE_AUDIO: + description: 'This option enables Bluetooth LE Audio support' + value: 0 + experimental: 1 + # Flow control settings. BLE_HS_FLOW_CTRL: description: > @@ -493,20 +498,6 @@ syscfg.defs: supported by host. value: 0 - BLE_MAX_BIG: - desciptrion: > - Number of available BIGs - value: 'MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES' - restrictions: - - 'BLE_ISO_BROADCAST_SOURCE if 0' - - BLE_MAX_BIS: - description: > - Number of supported BISes - value: 4 - restrictions: - - 'BLE_ISO_BROADCAST_SOURCE if 0' - ### Log settings. BLE_HS_LOG_MOD: @@ -523,6 +514,20 @@ syscfg.defs: description: 'Minimum level for the BLE EATT log.' value: 1 + BLE_ISO_MAX_BIGS: + desciptrion: > + Number of available BIGs + value: 'MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES' + restrictions: + - 'BLE_ISO_BROADCAST_SOURCE if 0' + + BLE_ISO_MAX_BISES: + description: > + Number of supported BISes + value: 4 + restrictions: + - 'BLE_ISO_BROADCAST_SOURCE if 0' + syscfg.logs: BLE_HS_LOG: module: MYNEWT_VAL(BLE_HS_LOG_MOD) diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index 86da373817..6571329582 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -803,12 +803,12 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif -#ifndef MYNEWT_VAL_BLE_MAX_BIG -#define MYNEWT_VAL_BLE_MAX_BIG (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS +#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) #endif -#ifndef MYNEWT_VAL_BLE_MAX_BIS -#define MYNEWT_VAL_BLE_MAX_BIS (4) +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES +#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) #endif #ifndef MYNEWT_VAL_BLE_MESH diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index c44af9c58d..8321199654 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -804,12 +804,12 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif -#ifndef MYNEWT_VAL_BLE_MAX_BIG -#define MYNEWT_VAL_BLE_MAX_BIG (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS +#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) #endif -#ifndef MYNEWT_VAL_BLE_MAX_BIS -#define MYNEWT_VAL_BLE_MAX_BIS (4) +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES +#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) #endif /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host) */ diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index d087c57451..af7f7992cb 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -803,12 +803,12 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif -#ifndef MYNEWT_VAL_BLE_MAX_BIG -#define MYNEWT_VAL_BLE_MAX_BIG (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS +#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) #endif -#ifndef MYNEWT_VAL_BLE_MAX_BIS -#define MYNEWT_VAL_BLE_MAX_BIS (4) +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES +#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) #endif #ifndef MYNEWT_VAL_BLE_MESH diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index 4910e54e68..c62bb02c50 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -802,12 +802,12 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif -#ifndef MYNEWT_VAL_BLE_MAX_BIG -#define MYNEWT_VAL_BLE_MAX_BIG (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS +#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) #endif -#ifndef MYNEWT_VAL_BLE_MAX_BIS -#define MYNEWT_VAL_BLE_MAX_BIS (4) +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES +#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) #endif #ifndef MYNEWT_VAL_BLE_MESH diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index b70ba2b992..27047feb56 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1719,12 +1719,12 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif -#ifndef MYNEWT_VAL_BLE_MAX_BIG -#define MYNEWT_VAL_BLE_MAX_BIG (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS +#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) #endif -#ifndef MYNEWT_VAL_BLE_MAX_BIS -#define MYNEWT_VAL_BLE_MAX_BIS (4) +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES +#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) #endif #ifndef MYNEWT_VAL_BLE_MESH diff --git a/targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml b/targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml index d3255ff1c6..b86d58872c 100644 --- a/targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml +++ b/targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml @@ -43,5 +43,5 @@ syscfg.vals: BLE_VERSION: 54 BLE_ISO: 1 BLE_ISO_BROADCAST_SOURCE: 1 - BLE_MAX_BIG: 1 - BLE_MAX_BIS: 2 + BLE_ISO_MAX_BIGS: 1 + BLE_ISO_MAX_BISES: 2 From 49912bbd5b9d9d80b031910aa19f8b9ab094c92c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 1 Mar 2024 14:22:37 +0100 Subject: [PATCH 0927/1333] host/ble_hs: call ble_iso_rx_data if BLE_ISO_BROADCAST_SINK BLE_ISO defines ISO as whole, but we RX iso data only when device is broadcast sink. --- nimble/host/src/ble_hs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index 147837d9f3..7983cca187 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -818,7 +818,7 @@ ble_transport_to_hs_acl_impl(struct os_mbuf *om) int ble_transport_to_hs_iso_impl(struct os_mbuf *om) { -#if MYNEWT_VAL(BLE_ISO) +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK) return ble_iso_rx_data(om, NULL); #else os_mbuf_free_chain(om); From b4eb3bbdd5cbe535d23b2b4d276e043a9fd76bec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 4 Jun 2021 15:01:20 +0200 Subject: [PATCH 0928/1333] apps: blestress: fix test 6 Disable filtering of advertising reports, as we check the same data N times, and only first time is registered with filtering enabled. --- apps/blestress/src/tx_stress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/blestress/src/tx_stress.c b/apps/blestress/src/tx_stress.c index 1711f9fbf8..5d5f22703f 100644 --- a/apps/blestress/src/tx_stress.c +++ b/apps/blestress/src/tx_stress.c @@ -73,7 +73,7 @@ tx_stress_simple_scan(ble_gap_event_fn *cb, uint16_t duration) params.passive = 1; params.window = BLE_GAP_SCAN_FAST_WINDOW; - rc = ble_gap_ext_disc(own_addr_type, duration, 0, 1, 0, 0, ¶ms, NULL, + rc = ble_gap_ext_disc(own_addr_type, duration, 0, 0, 0, 0, ¶ms, NULL, cb, NULL); if (rc != 0) { From 7cf4b883d48316d7402c68220fb281328d52a309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 9 Jun 2021 11:21:55 +0200 Subject: [PATCH 0929/1333] apps/blestress: set BLE_ACL_BUF_SIZE to proper value With current (default) CoC MPS setting we were trying to send more than HCI packet could hold. This patch increases its size to sufficient value. --- apps/blestress/syscfg.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/blestress/syscfg.yml b/apps/blestress/syscfg.yml index 4f7fa4daca..b24280436b 100644 --- a/apps/blestress/syscfg.yml +++ b/apps/blestress/syscfg.yml @@ -82,3 +82,6 @@ syscfg.vals: # Whether to save data to sys/config, or just keep it in RAM. BLE_STORE_CONFIG_PERSIST: 0 + + # ACL buf size must be able to contain CoC MPS plus ACL header + BLE_TRANSPORT_ACL_SIZE: MYNEWT_VAL_BLE_L2CAP_COC_MPS + 4 From 339f1d8b5a481cc4a97f8dddc6865515bb4f411d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 10 Jun 2021 13:38:35 +0200 Subject: [PATCH 0930/1333] apps/blestress: fix test 9 - add connection params By adding connection params with increased supervision timeout we are able to make more connections before previous are closed. Supervision timeout is set to its maximum value of 32s (0x0C80 in 10ms units).This allows to achieve number of connections declared to be supported by NimBLE: 32+. --- apps/blestress/src/tx_stress.c | 52 ++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/apps/blestress/src/tx_stress.c b/apps/blestress/src/tx_stress.c index 5d5f22703f..18296e52f9 100644 --- a/apps/blestress/src/tx_stress.c +++ b/apps/blestress/src/tx_stress.c @@ -83,7 +83,7 @@ tx_stress_simple_scan(ble_gap_event_fn *cb, uint16_t duration) } static int -tx_stress_simple_connect(ble_gap_event_fn *cb, int test_num) +tx_stress_simple_connect(ble_gap_event_fn *cb, int test_num, struct ble_gap_conn_params *params) { uint8_t own_addr_type; int rc; @@ -105,7 +105,7 @@ tx_stress_simple_connect(ble_gap_event_fn *cb, int test_num) rc = ble_gap_ext_connect(own_addr_type, &tx_stress_ctx->dev_addr, 10000, BLE_GAP_LE_PHY_1M_MASK | BLE_GAP_LE_PHY_2M_MASK, - NULL, NULL, NULL, cb, NULL); + params, params, NULL, cb, NULL); if (rc != 0) { MODLOG_DFLT(INFO, "\033[0;31mError during connection; rc=%d\033[0m\n", @@ -175,7 +175,7 @@ tx_stress_switcher_gap_event(struct ble_gap_event *event, void *arg) } /* Connect to rx device just to give it a signal to switch test. */ tx_stress_simple_connect(tx_stress_switcher_gap_event, - tx_stress_ctx->cur_test_id); + tx_stress_ctx->cur_test_id, NULL); return 0; case BLE_GAP_EVENT_DISCONNECT: @@ -212,7 +212,7 @@ tx_stress_switch_test() tx_stress_simple_scan(tx_stress_switcher_gap_event, 0); os_sem_pend(&tx_stress_main_sem, OS_TIMEOUT_NEVER); - tx_stress_simple_connect(tx_stress_switcher_gap_event, 0); + tx_stress_simple_connect(tx_stress_switcher_gap_event, 0, NULL); } static int @@ -363,7 +363,7 @@ tx_stress_2_gap_event(struct ble_gap_event *event, void *arg) return 0; } tx_stress_simple_connect(tx_stress_2_gap_event, - tx_stress_ctx->cur_test_id); + tx_stress_ctx->cur_test_id, NULL); return 0; default: @@ -405,7 +405,7 @@ tx_stress_3_gap_event(struct ble_gap_event *event, void *arg) return 0; } tx_stress_simple_connect(tx_stress_3_gap_event, - tx_stress_ctx->cur_test_id); + tx_stress_ctx->cur_test_id, NULL); return 0; default: @@ -848,6 +848,16 @@ tx_stress_9_gap_event(struct ble_gap_event *event, void *arg) { ble_addr_t addr; int test; + struct ble_gap_conn_params conn_params = { + .scan_itvl = 0x0010, + .scan_window = 0x0010, + .itvl_min = BLE_GAP_INITIAL_CONN_ITVL_MIN, + .itvl_max = BLE_GAP_INITIAL_CONN_ITVL_MAX, + .latency = 0, + .supervision_timeout = 0x0C80, + .min_ce_len = 0x0010, + .max_ce_len = 0x0300, + }; switch (event->type) { case BLE_GAP_EVENT_EXT_DISC: @@ -860,7 +870,7 @@ tx_stress_9_gap_event(struct ble_gap_event *event, void *arg) ble_gap_disc_cancel(); tx_stress_ctx->dev_addr = event->ext_disc.addr; tx_stress_simple_connect(tx_stress_9_gap_event, - tx_stress_ctx->cur_test_id); + tx_stress_ctx->cur_test_id, &conn_params); } return 0; @@ -1169,7 +1179,7 @@ tx_stress_11_gap_event(struct ble_gap_event *event, void *arg) ble_gap_disc_cancel(); tx_stress_ctx->dev_addr = event->ext_disc.addr; tx_stress_simple_connect(tx_stress_11_gap_event, - tx_stress_ctx->cur_test_id); + tx_stress_ctx->cur_test_id, NULL); } return 0; @@ -1467,7 +1477,7 @@ tx_stress_15_gap_event(struct ble_gap_event *event, void *arg) return 0; } /* Reconnect */ - tx_stress_simple_connect(tx_stress_15_gap_event, 15); + tx_stress_simple_connect(tx_stress_15_gap_event, 15, NULL); return 0; default: @@ -1537,19 +1547,19 @@ tx_stress_test_perform(int test_num) break; case 2: console_printf("Stress Connect/Disconnect legacy\033[0m\n"); - tx_stress_simple_connect(&tx_stress_2_gap_event, 2); + tx_stress_simple_connect(&tx_stress_2_gap_event, 2, NULL); break; case 3: console_printf("Stress Connect/Disconnect ext adv\033[0m\n"); - tx_stress_simple_connect(&tx_stress_3_gap_event, 3); + tx_stress_simple_connect(&tx_stress_3_gap_event, 3, NULL); break; case 4: console_printf("Stress connection params update (TX)\033[0m\n"); - tx_stress_simple_connect(&tx_stress_4_gap_event, 4); + tx_stress_simple_connect(&tx_stress_4_gap_event, 4, NULL); break; case 5: console_printf("Stress connection params update (RX)\033[0m\n"); - tx_stress_simple_connect(&tx_stress_5_gap_event, 5); + tx_stress_simple_connect(&tx_stress_5_gap_event, 5, NULL); break; case 6: console_printf("Stress Scan\033[0m\n"); @@ -1557,11 +1567,11 @@ tx_stress_test_perform(int test_num) break; case 7: console_printf("Stress PHY Update (TX)\033[0m\n"); - tx_stress_simple_connect(&tx_stress_7_gap_event, 7); + tx_stress_simple_connect(&tx_stress_7_gap_event, 7, NULL); break; case 8: console_printf("Stress PHY Update (RX)\033[0m\n"); - tx_stress_simple_connect(&tx_stress_8_gap_event, 8); + tx_stress_simple_connect(&tx_stress_8_gap_event, 8, NULL); break; case 9: console_printf("Stress multi connection\033[0m\n"); @@ -1569,27 +1579,27 @@ tx_stress_test_perform(int test_num) break; case 10: console_printf("Stress L2CAP send\033[0m\n"); - tx_stress_simple_connect(&tx_stress_10_gap_event, 10); + tx_stress_simple_connect(&tx_stress_10_gap_event, 10, NULL); break; case 11: console_printf("Stress Advertise/Connect/Disconnect\033[0m\n"); - tx_stress_simple_connect(&tx_stress_11_gap_event, 11); + tx_stress_simple_connect(&tx_stress_11_gap_event, 11, NULL); break; case 12: console_printf("Stress GATT indication\033[0m\n"); - tx_stress_simple_connect(&tx_stress_12_gap_event, 12); + tx_stress_simple_connect(&tx_stress_12_gap_event, 12, NULL); break; case 13: console_printf("Stress GATT notification\033[0m\n"); - tx_stress_simple_connect(&tx_stress_13_gap_event, 13); + tx_stress_simple_connect(&tx_stress_13_gap_event, 13, NULL); break; case 14: console_printf("Stress GATT Subscribe/Notify/Unsubscribe\033[0m\n"); - tx_stress_simple_connect(&tx_stress_14_gap_event, 14); + tx_stress_simple_connect(&tx_stress_14_gap_event, 14, NULL); break; case 15: console_printf("Stress Connect/Send/Disconnect\033[0m\n"); - tx_stress_simple_connect(&tx_stress_15_gap_event, 15); + tx_stress_simple_connect(&tx_stress_15_gap_event, 15, NULL); break; default: console_printf("\033[0;31mFound test, but do not know how to perform." From 8debcf0c46dfc6a7f8e21d86ff9715a2d522766b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 11 Jun 2021 14:46:45 +0200 Subject: [PATCH 0931/1333] apps/blestress: run all tests All implemented tests are working now - run all of them. --- apps/blestress/src/rx_stress.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/apps/blestress/src/rx_stress.c b/apps/blestress/src/rx_stress.c index 2761196ca9..95b7082185 100644 --- a/apps/blestress/src/rx_stress.c +++ b/apps/blestress/src/rx_stress.c @@ -1456,12 +1456,6 @@ rx_stress_main_task_fn(void *arg) /* Standard tests perform */ for (i = 11; i < STRESS_UUIDS_NUM; ++i) { - if (i == 7 || i == 8 || i == 13) { - /* 7,8: PHY update tests cause that the device during the next test - * will stuck somewhere and will reset. Skip them for now. - * 13: Should work after fixing ble_gatts_notify_custom (nimble issue on GitHub)*/ - continue; - } /* Start test. */ rx_stress_start(i); } From e55baf9843442c5342a467e8050f025ec193df7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 22 Jan 2024 13:35:47 +0100 Subject: [PATCH 0932/1333] nimble/services: add PACS This commit adds Published Audio Capabilities Service/Prifile. In pair ble_audio_codec module is added, that supports registering supported codecs with their corresponding configurations. --- .github/test_build_apps_syscfg.yml | 1 + nimble/host/audio/include/audio/ble_audio.h | 256 +++++++++- .../audio/include/audio/ble_audio_codec.h | 146 ++++++ .../services/pacs/ble_audio_svc_pacs.h | 95 ++++ .../services/pacs/ble_audio_svc_pacs_lc3.h | 63 +++ nimble/host/audio/services/pacs/lc3/pkg.yml | 34 ++ .../pacs/lc3/src/ble_audio_svc_pacs_lc3.c | 153 ++++++ .../host/audio/services/pacs/lc3/syscfg.yml | 131 +++++ nimble/host/audio/services/pacs/pkg.yml | 33 ++ .../services/pacs/src/ble_audio_svc_pacs.c | 479 ++++++++++++++++++ nimble/host/audio/services/pacs/syscfg.yml | 69 +++ nimble/host/audio/src/ble_audio_codec.c | 138 +++++ nimble/host/audio/syscfg.yml | 4 + nimble/host/src/ble_audio_codec_priv.h | 25 + nimble/host/src/ble_hs.c | 5 + nimble/host/src/ble_hs_priv.h | 1 + .../examples/linux/include/syscfg/syscfg.h | 4 + .../linux_blemesh/include/syscfg/syscfg.h | 4 + .../examples/nuttx/include/syscfg/syscfg.h | 4 + porting/nimble/include/syscfg/syscfg.h | 4 + porting/npl/riot/include/syscfg/syscfg.h | 4 + 21 files changed, 1643 insertions(+), 10 deletions(-) create mode 100644 nimble/host/audio/include/audio/ble_audio_codec.h create mode 100644 nimble/host/audio/services/pacs/include/services/pacs/ble_audio_svc_pacs.h create mode 100644 nimble/host/audio/services/pacs/lc3/include/services/pacs/ble_audio_svc_pacs_lc3.h create mode 100644 nimble/host/audio/services/pacs/lc3/pkg.yml create mode 100644 nimble/host/audio/services/pacs/lc3/src/ble_audio_svc_pacs_lc3.c create mode 100644 nimble/host/audio/services/pacs/lc3/syscfg.yml create mode 100644 nimble/host/audio/services/pacs/pkg.yml create mode 100644 nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c create mode 100644 nimble/host/audio/services/pacs/syscfg.yml create mode 100644 nimble/host/audio/src/ble_audio_codec.c create mode 100644 nimble/host/src/ble_audio_codec_priv.h diff --git a/.github/test_build_apps_syscfg.yml b/.github/test_build_apps_syscfg.yml index aabcc2979d..9887918b43 100644 --- a/.github/test_build_apps_syscfg.yml +++ b/.github/test_build_apps_syscfg.yml @@ -54,6 +54,7 @@ syscfg.vals: BLE_EATT_CHAN_NUM: 2 BLE_PHY_2M: 1 BLE_PHY_CODED: 1 + BLE_AUDIO_MAX_CODEC_RECORDS: 2 # controller BLE_LL_CFG_FEAT_LL_PRIVACY: 1 diff --git a/nimble/host/audio/include/audio/ble_audio.h b/nimble/host/audio/include/audio/ble_audio.h index c1ce1dc9c8..288f13ee50 100644 --- a/nimble/host/audio/include/audio/ble_audio.h +++ b/nimble/host/audio/include/audio/ble_audio.h @@ -208,19 +208,184 @@ */ /** LE Audio Codec Config Type: Sampling Frequency. */ -#define BLE_AUDIO_CODEC_SAMPLING_FREQ_TYPE 0x01 +#define BLE_AUDIO_CODEC_CONF_SAMPLING_FREQ_TYPE 0x01 /** LE Audio Codec Config Type: Frame Duration. */ -#define BLE_AUDIO_CODEC_FRAME_DURATION_TYPE 0x02 +#define BLE_AUDIO_CODEC_CONF_FRAME_DURATION_TYPE 0x02 /** LE Audio Codec Config Type: Channel Allocation. */ -#define BLE_AUDIO_CODEC_AUDIO_CHANNEL_ALLOCATION_TYPE 0x03 +#define BLE_AUDIO_CODEC_CONF_AUDIO_CHANNEL_ALLOCATION_TYPE 0x03 /** LE Audio Codec Config Type: Octets Per Codec Frame. */ -#define BLE_AUDIO_CODEC_OCTETS_PER_CODEC_FRAME_TYPE 0x04 +#define BLE_AUDIO_CODEC_CONF_OCTETS_PER_CODEC_FRAME_TYPE 0x04 /** LE Audio Codec Config Type: Frame Blocks Per SDU. */ -#define BLE_AUDIO_CODEC_FRAME_BLOCKS_PER_SDU_TYPE 0x05 +#define BLE_AUDIO_CODEC_CONF_FRAME_BLOCKS_PER_SDU_TYPE 0x05 + +/** @} */ + +/** + * @defgroup ble_audio_codec_config Bluetooth Low Energy Audio Codec Specific Capabilities + * @{ + */ + + +/** LE Audio Codec Specific Capability: Supported Sampling Frequencies. */ +#define BLE_AUDIO_CODEC_CAPS_SAMPLING_FREQ_TYPE 0x01 + +/** LE Audio Codec Specific Capability: Supported Frame Durations. */ +#define BLE_AUDIO_CODEC_CAPS_FRAME_DURATION_TYPE 0x02 + +/** LE Audio Codec Specific Capability: Supported Audio Channel Counts. */ +#define BLE_AUDIO_CODEC_CAPS_SUP_AUDIO_CHANNEL_COUNTS_TYPE 0x03 + +/** LE Audio Codec Specific Capability: Supported Octets Per Codec Frame. */ +#define BLE_AUDIO_CODEC_CAPS_OCTETS_PER_CODEC_FRAME_TYPE 0x04 + +/** LE Audio Codec Specific Capability: Supported Codec Frames Per SDU. */ +#define BLE_AUDIO_CODEC_CAPS_FRAMES_PER_SDU_TYPE 0x05 + +/** @} */ + +/** + * @defgroup ble_audio_contexts Bluetooth Low Energy Audio Context Types + * @{ + */ + +/** LE Audio Codec Context Type: Prohibited. */ +#define BLE_AUDIO_CONTEXT_TYPE_PROHIBITED 0x0000 + +/** LE Audio Codec Context Type: Unspecified. */ +#define BLE_AUDIO_CONTEXT_TYPE_UNSPECIFIED 0x0001 + +/** LE Audio Codec Context Type: Conversational. */ +#define BLE_AUDIO_CONTEXT_TYPE_CONVERSATIONAL 0x0002 + +/** LE Audio Codec Context Type: Media. */ +#define BLE_AUDIO_CONTEXT_TYPE_MEDIA 0x0004 + +/** LE Audio Codec Context Type: Game. */ +#define BLE_AUDIO_CONTEXT_TYPE_GAME 0x0008 + +/** LE Audio Codec Context Type: Instructional. */ +#define BLE_AUDIO_CONTEXT_TYPE_INSTRUCTIONAL 0x0010 + +/** LE Audio Codec Context Type: Voice Assistants. */ +#define BLE_AUDIO_CONTEXT_TYPE_VOICE_ASSISTANTS 0x0020 + +/** LE Audio Codec Context Type: Live. */ +#define BLE_AUDIO_CONTEXT_TYPE_LIVE 0x0040 + +/** LE Audio Codec Context Type: Sound Effects. */ +#define BLE_AUDIO_CONTEXT_TYPE_SOUND_EFFECTS 0x0080 + +/** LE Audio Codec Context Type: Notifications. */ +#define BLE_AUDIO_CONTEXT_TYPE_NOTIFICATIONS 0x0100 + +/** LE Audio Codec Context Type: Ringtone. */ +#define BLE_AUDIO_CONTEXT_TYPE_RINGTONE 0x0200 + +/** LE Audio Codec Context Type: Alerts. */ +#define BLE_AUDIO_CONTEXT_TYPE_ALERTS 0x0400 + +/** LE Audio Codec Context Type: EmergencyAlarm. */ +#define BLE_AUDIO_CONTEXT_TYPE_EMERGENCY_ALARM 0x0800 + +/** @} */ + +/** + * @defgroup ble_audio_contexts Bluetooth Low Energy Audio Supported Frame Durations + * @{ + */ + +/** LE Audio Codec Supported Frame Duration: 7.5 ms frame duration. */ +#define BLE_AUDIO_CODEC_SUPPORTED_FRAME_DURATION_7_5_MS 0x0001 + +/** LE Audio Codec Supported Frame Duration: 10 ms frame duration. */ +#define BLE_AUDIO_CODEC_SUPPORTED_FRAME_DURATION_10_MS 0x0002 + +/** LE Audio Codec Supported Frame Duration: 7.5 ms preferred. */ +#define BLE_AUDIO_CODEC_PREFERED_FRAME_DURATION_7_5_MS 0x0010 + +/** LE Audio Codec Supported Frame Duration: 10 ms preferred. */ +#define BLE_AUDIO_CODEC_PREFERED_FRAME_DURATION_10_MS 0x0020 + +/** @} */ + +/** + * @defgroup ble_audio_contexts Bluetooth Low Energy Audio Supported Sampling Frequencies + * @{ + */ + +/** LE Audio Codec Supported Sampling Frequency: 8000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_8000_HZ (1ULL << 0) + +/** LE Audio Codec Supported Sampling Frequency: 11025 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_11025_HZ (1ULL << 1) + +/** LE Audio Codec Supported Sampling Frequency: 16000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_16000_HZ (1ULL << 2) + +/** LE Audio Codec Supported Sampling Frequency: 22050 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_22050_HZ (1ULL << 3) + +/** LE Audio Codec Supported Sampling Frequency: 24000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_24000_HZ (1ULL << 4) + +/** LE Audio Codec Supported Sampling Frequency: 32000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_32000_HZ (1ULL << 5) + +/** LE Audio Codec Supported Sampling Frequency: 44100 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_44100_HZ (1ULL << 6) + +/** LE Audio Codec Supported Sampling Frequency: 48000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_48000_HZ (1ULL << 7) + +/** LE Audio Codec Supported Sampling Frequency: 88200 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_88200_HZ (1ULL << 8) + +/** LE Audio Codec Supported Sampling Frequency: 96000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_96000_HZ (1ULL << 9) + +/** LE Audio Codec Supported Sampling Frequency: 176400 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_176400_HZ (1ULL << 10) + +/** LE Audio Codec Supported Sampling Frequency: 192000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_192000_HZ (1ULL << 11) + +/** LE Audio Codec Supported Sampling Frequency: 384000 Hz. */ +#define BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_384000_HZ (1ULL << 12) + +/** @} */ + +/** + * @defgroup ble_audio_contexts Bluetooth Low Energy Audio Supported Channel Counts + * @{ + */ + +/** LE Audio Codec Supported Channel Count: 1. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_1 0x0001 + +/** LE Audio Codec Supported Channel Count: 2. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_2 0x0002 + +/** LE Audio Codec Supported Channel Count: 3. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_3 0x0004 + +/** LE Audio Codec Supported Channel Count: 4. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_4 0x0008 + +/** LE Audio Codec Supported Channel Count: 5. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_5 0x0010 + +/** LE Audio Codec Supported Channel Count: 6. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_6 0x0020 + +/** LE Audio Codec Supported Channel Count: 7. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_7 0x0040 + +/** LE Audio Codec Supported Channel Count: 8. */ +#define BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_8 0x0080 /** @} */ @@ -244,16 +409,55 @@ _octets_per_codec_frame, \ _codec_frame_blocks_per_sdu) \ { \ - 2, BLE_AUDIO_CODEC_SAMPLING_FREQ_TYPE, _sampling_freq, \ - 2, BLE_AUDIO_CODEC_FRAME_DURATION_TYPE, _frame_duration, \ - OPTIONAL_FIELD(5, BLE_AUDIO_CODEC_AUDIO_CHANNEL_ALLOCATION_TYPE, \ + 2, BLE_AUDIO_CODEC_CONF_SAMPLING_FREQ_TYPE, _sampling_freq, \ + 2, BLE_AUDIO_CODEC_CONF_FRAME_DURATION_TYPE, _frame_duration, \ + OPTIONAL_FIELD(5, BLE_AUDIO_CODEC_CONF_AUDIO_CHANNEL_ALLOCATION_TYPE, \ _audio_channel_alloc) \ - 3, BLE_AUDIO_CODEC_OCTETS_PER_CODEC_FRAME_TYPE, \ + 3, BLE_AUDIO_CODEC_CONF_OCTETS_PER_CODEC_FRAME_TYPE, \ (_octets_per_codec_frame), ((_octets_per_codec_frame) >> 8), \ - OPTIONAL_FIELD(2, BLE_AUDIO_CODEC_FRAME_BLOCKS_PER_SDU_TYPE, \ + OPTIONAL_FIELD(2, BLE_AUDIO_CODEC_CONF_FRAME_BLOCKS_PER_SDU_TYPE, \ _codec_frame_blocks_per_sdu) \ } +/** + * @brief Helper macro used to build LTV array of Codec_Specific_Capabilities. + * + * @param _sampling_freq Supported_Sampling_Frequencies - + * two octet value + * @param _frame_duration Supported_Frame_Durations - single + * octet value + * @param _audio_channel_counts Supported_Audio_Channel_Counts - + * single octet value + * @param _min_octets_per_codec_frame minimum value of + * Supported_Octets_Per_Codec_Frame - + * two octet value + * @param _max_octets_per_codec_frame maximum value of + * Supported_Octets_Per_Codec_Frame - + * two octet value + * @param _codec_frames_per_sdu Supported_Max_Codec_Frames_Per_SDU - + * single octet value + * + * @return Pointer to a `ble_uuid16_t` structure. + */ +#define BLE_AUDIO_BUILD_CODEC_CAPS(_sampling_freq, \ + _frame_duration, \ + _audio_channel_counts, \ + _min_octets_per_codec_frame, \ + _max_octets_per_codec_frame, \ + _codec_frames_per_sdu) \ + { \ + 3, BLE_AUDIO_CODEC_CAPS_SAMPLING_FREQ_TYPE, \ + (_sampling_freq), ((_sampling_freq) >> 8), \ + 2, BLE_AUDIO_CODEC_CAPS_FRAME_DURATION_TYPE, _frame_duration, \ + OPTIONAL_FIELD(2, BLE_AUDIO_CODEC_CAPS_SUP_AUDIO_CHANNEL_COUNTS_TYPE, \ + _audio_channel_counts) \ + 5, BLE_AUDIO_CODEC_CAPS_OCTETS_PER_CODEC_FRAME_TYPE, \ + (_min_octets_per_codec_frame), ((_min_octets_per_codec_frame) >> 8), \ + (_max_octets_per_codec_frame), ((_max_octets_per_codec_frame) >> 8), \ + OPTIONAL_FIELD(2, BLE_AUDIO_CODEC_CAPS_FRAMES_PER_SDU_TYPE, \ + _codec_frames_per_sdu) \ + } + /** Codec Information */ struct ble_audio_codec_id { /** Coding Format */ @@ -306,6 +510,12 @@ struct ble_audio_broadcast_name { /** BLE Audio event: Broadcast Announcement */ #define BLE_AUDIO_EVENT_BROADCAST_ANNOUNCEMENT 0 +/** BLE Audio event: Codec Registered */ +#define BLE_AUDIO_EVENT_CODEC_REGISTERED 1 + +/** BLE Audio event: Codec Unregistered */ +#define BLE_AUDIO_EVENT_CODEC_UNREGISTERED 2 + /** @} */ /** @brief Broadcast Announcement */ @@ -329,6 +539,18 @@ struct ble_audio_event_broadcast_announcement { struct ble_audio_broadcast_name *name; }; +/** @brief Codec Registered */ +struct ble_audio_event_codec_registered { + /** Codec Record */ + const struct ble_audio_codec_record *record; +}; + +/** @brief Codec Unregistered */ +struct ble_audio_event_codec_unregistered { + /** Codec Record */ + const struct ble_audio_codec_record *record; +}; + /** * Represents a BLE Audio related event. When such an event occurs, the host * notifies the application by passing an instance of this structure to an @@ -352,6 +574,20 @@ struct ble_audio_event { * Represents a received Broadcast Announcement. */ struct ble_audio_event_broadcast_announcement broadcast_announcement; + + /** + * @ref BLE_AUDIO_EVENT_CODEC_REGISTERED + * + * Represents a codec registration. + */ + struct ble_audio_event_codec_registered codec_registered; + + /** + * @ref BLE_AUDIO_EVENT_CODEC_UNREGISTERED + * + * Represents a codec registration. + */ + struct ble_audio_event_codec_unregistered codec_unregistered; }; }; diff --git a/nimble/host/audio/include/audio/ble_audio_codec.h b/nimble/host/audio/include/audio/ble_audio_codec.h new file mode 100644 index 0000000000..dcb1df9d34 --- /dev/null +++ b/nimble/host/audio/include/audio/ble_audio_codec.h @@ -0,0 +1,146 @@ +/* + * 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_BLE_AUDIO_CODEC_ +#define H_BLE_AUDIO_CODEC_ + +/** + * @file ble_audio_codec.h + * + * @brief Bluetooth LE Audio Codec + * + * This header file provides the public API for managing LE Audio Codecs + * + * @defgroup ble_audio_codec Bluetooth LE Audio Codec + * @ingroup bt_host + * @{ + * + * This API allows to create and manage list of LE Audio codecs with their capabilities and + * metadata. This list can be used by higher level services, like PACS. Memory management of + * codec entries is left to application and neither static nor dynamic allocation is enforced. + * + */ + +#include "stdint.h" +#include "ble_audio.h" + +/** Bit describing direction of codec configuration - source */ +#define BLE_AUDIO_CODEC_DIR_SOURCE_BIT (1 << 0) +/** Bit describing direction of codec configuration - sink */ +#define BLE_AUDIO_CODEC_DIR_SINK_BIT (1 << 1) + +/** Codec list entry */ +struct ble_audio_codec_record { + /* Pointer to next codec list entry */ + STAILQ_ENTRY(ble_audio_codec_record) next; + + /* Codec ID */ + struct ble_audio_codec_id codec_id; + + /* Length of Codec Specific Capabilities */ + uint8_t codec_spec_caps_len; + + /* Codec Specific Capabilities data */ + const uint8_t *codec_spec_caps; + + /* Metadata length */ + uint8_t metadata_len; + + /* Metadata */ + const uint8_t *metadata; + + /* Bitfield describing direction that codec is acting on. It is a logical OR of: + * - BLE_AUDIO_CODEC_DIR_SOURCE_BIT + * - BLE_AUDIO_CODEC_DIR_SINK_BIT + */ + uint8_t direction; +}; + +/** Type definition codec iteration callback function. */ +typedef int ble_audio_codec_foreach_fn(const struct ble_audio_codec_record *record, void *arg); + +struct ble_audio_codec_register_params { + /* Codec ID structure */ + struct ble_audio_codec_id codec_id; + + /* Codec Specific Capabilities length */ + uint8_t codec_spec_caps_len; + + /* Codec Specific Capabilities data */ + uint8_t *codec_spec_caps; + + /* Metadata length */ + uint8_t metadata_len; + + /* Metadata */ + uint8_t *metadata; + + /* Bitfield describing direction that codec is acting on. It is a logical OR of: + * - BLE_AUDIO_CODEC_DIR_SOURCE_BIT + * - BLE_AUDIO_CODEC_DIR_SINK_BIT + */ + uint8_t direction; +}; + +/** + * @brief Register codec entry + * + * @param[in] params Pointer to a `ble_audio_codec_register_params` + * structure that defines Codec Specific Capabilities + * @param[out] out_record Pointer to registered codec entry. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_codec_register(const struct ble_audio_codec_register_params + *params, + struct ble_audio_codec_record *out_record); +/** + * @brief Remove codec entry from register + * + * @param[in] codec_record Pointer to registered codec entry. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_codec_unregister(struct ble_audio_codec_record *codec_record); + +/** + * @brief Iterate through all registered codecs and call function on every + * one of them. + * + * @param[in] direction Codec entry direction. It is any + * combination of following bits: + * - BLE_AUDIO_CODEC_DIR_SOURCE_BIT + * - BLE_AUDIO_CODEC_DIR_SINK_BIT + * This filters entries so the callback is called + * only on these have matching direction bit set. + * @param[in] cb Callback to be called on codec entries. + * @param[in] arg Optional callback argument. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_codec_foreach(uint8_t direction, ble_audio_codec_foreach_fn *cb, void *arg); + +/** + * @} + */ + +#endif /* H_BLE_AUDIO_CODEC_ */ diff --git a/nimble/host/audio/services/pacs/include/services/pacs/ble_audio_svc_pacs.h b/nimble/host/audio/services/pacs/include/services/pacs/ble_audio_svc_pacs.h new file mode 100644 index 0000000000..fdbcbeef9f --- /dev/null +++ b/nimble/host/audio/services/pacs/include/services/pacs/ble_audio_svc_pacs.h @@ -0,0 +1,95 @@ +/* + * 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_BLE_AUDIO_SVC_PACS_ +#define H_BLE_AUDIO_SVC_PACS_ + +/** + * @file ble_audio_svc_pacs.h + * + * @brief Bluetooth LE Audio PAC Service + * + * This header file provides the public API for interacting with the PACS package. + * + * @defgroup ble_audio_svc_pacs Bluetooth LE Audio PACS package + * @ingroup bt_host + * @{ + * + * This package is used to setup PACS for codecs registered with @ref ble_audio_codec. + * To register a codec create it's definition as `ble_audio_codec_record` structure and register it + * using `ble_audio_codec_register()`. Up to BLE_AUDIO_MAX_CODEC_RECORDS entries may be registered. + * Registering and unregistering codecs, as well as setting PACS parameters will trigger sending + * notifications, if their support is enabled (see pacs/syscfg.yml). + * + */ + +#define BLE_SVC_AUDIO_PACS_UUID16 0x1850 +#define BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_PAC 0x2BC9 +#define BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_AUDIO_LOCATIONS 0x2BCA +#define BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_PAC 0x2BCB +#define BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_AUDIO_LOCATIONS 0x2BCC +#define BLE_SVC_AUDIO_PACS_CHR_UUID16_AVAILABLE_AUDIO_CONTEXTS 0x2BCD +#define BLE_SVC_AUDIO_PACS_CHR_UUID16_SUPPORTED_AUDIO_CONTEXTS 0x2BCE + + +struct ble_svc_audio_pacs_set_param { + /* Supported Audio Locations */ + uint32_t audio_locations; + + /* Supported Contexts */ + uint16_t supported_contexts; +}; + +/** + * @brief Set PACS params. + * + * Set device capabilities reported in Published Audio Capabilities Service. + * + * @param[in] flags Flags that define if capabilities being set are for + * Sink or Source. Valid values are either + * `BLE_AUDIO_CODEC_FLAG_SOURCE` or `BLE_AUDIO_CODEC_FLAG_SINK` + * @param[in] param Pointer to a `ble_svc_audio_pacs_set_param` + * structure that defines capabilities supported by + * device. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_svc_audio_pacs_set(uint8_t flags, struct ble_svc_audio_pacs_set_param *param); + +/** + * @brief Set available context types. + * + * @param[in] conn_handle Connection handle identifying connection for which contexts + * being set + * @param[in] sink_contexts Available Sink Contexts + * @param[in] source_contexts Available Source Contexts + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_svc_audio_pacs_avail_contexts_set(uint16_t conn_handle, + uint16_t sink_contexts, + uint16_t source_contexts); + +/** + * @} + */ + +#endif /* H_BLE_AUDIO_SVC_PACS_ */ diff --git a/nimble/host/audio/services/pacs/lc3/include/services/pacs/ble_audio_svc_pacs_lc3.h b/nimble/host/audio/services/pacs/lc3/include/services/pacs/ble_audio_svc_pacs_lc3.h new file mode 100644 index 0000000000..ddd6f546c2 --- /dev/null +++ b/nimble/host/audio/services/pacs/lc3/include/services/pacs/ble_audio_svc_pacs_lc3.h @@ -0,0 +1,63 @@ +/* + * 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_BLE_AUDIO_SVC_PACS_LC3_ +#define H_BLE_AUDIO_SVC_PACS_LC3_ + + +/** + * @file ble_audio_svc_pacs_lc3.h + * + * @brief Bluetooth PAC Service for LC3 Codec + * + * This header file provides the public API for interacting with the PACS LC3 package, that + * registers PAC entry for LC3 codec with configurations contained in system configuration file + * + * @defgroup ble_audio_svc_pacs_lc3 Bluetooth LE Audio PACS LC3 package + * @ingroup ble_audio_svc_pacs + * @{ + * + * This package is an example how to register codec entry that PACS can use to construct its entries + * for GATT database. This is high level package that can be used to construct basic PACS setup for + * LC3 codec. This package creates only single PAC entry per source and sink. If more PAC entries + * need to be created, with more advanced setup, @ref ble_audio_svc_pacs service shall be used in + * combination with @ref ble_audio_codec API. + * + */ + +/** + * @brief Set available context types. + * + * @param[in] conn_handle Connection handle identifying connection for which contexts + * being set + * @param[in] sink_contexts Available Sink Contexts + * @param[in] source_contexts Available Source Contexts + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_svc_audio_pacs_lc3_set_avail_contexts(uint16_t conn_handle, + uint16_t sink_contexts, + uint16_t source_contexts); + +/** + * @} + */ + +#endif /* H_BLE_AUDIO_SVC_PACS_LC3_ */ diff --git a/nimble/host/audio/services/pacs/lc3/pkg.yml b/nimble/host/audio/services/pacs/lc3/pkg.yml new file mode 100644 index 0000000000..eb8f6b67ed --- /dev/null +++ b/nimble/host/audio/services/pacs/lc3/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: nimble/host/audio/services/pacs/lc3 +pkg.description: LC3 codec entry for Published Audio Capabilities Service +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" +pkg.keywords: + - ble + - bluetooth + - pacs + - nimble + +pkg.deps: + - nimble/host/audio/services/pacs + - nimble/host + +pkg.init: + ble_svc_audio_pacs_lc3_init: + - $after:ble_svc_audio_pacs_init diff --git a/nimble/host/audio/services/pacs/lc3/src/ble_audio_svc_pacs_lc3.c b/nimble/host/audio/services/pacs/lc3/src/ble_audio_svc_pacs_lc3.c new file mode 100644 index 0000000000..61c703629c --- /dev/null +++ b/nimble/host/audio/services/pacs/lc3/src/ble_audio_svc_pacs_lc3.c @@ -0,0 +1,153 @@ +/* + * 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. + */ + +#include "audio/ble_audio_codec.h" +#include "services/pacs/ble_audio_svc_pacs.h" +#include "syscfg/syscfg.h" +#include "host/ble_hs.h" + +/* Below is to unmangle comma separated Metadata octets from MYNEWT_VAL */ +#define _Args(...) __VA_ARGS__ +#define STRIP_PARENS(X) X +#define UNMANGLE_MYNEWT_VAL(X) STRIP_PARENS(_Args X) + +#define BLE_SVC_AUDIO_PACS_LC3_CODEC_ID 0x06 + +static uint8_t ble_svc_audio_pacs_lc3_src_codec_spec_caps[] = BLE_AUDIO_BUILD_CODEC_CAPS( + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_SAMPLING_FREQUENCIES), + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_FRAME_DURATIONS), +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_CHANNEL_COUNTS + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_CHANNEL_COUNTS), +#else + , +#endif + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_MIN_OCTETS_PER_CODEC_FRAME), + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_OCTETS_PER_CODEC_FRAME), +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_CODEC_FRAMES_PER_SDU + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_CODEC_FRAMES_PER_SDU), +#endif +); + +static uint8_t ble_svc_audio_pacs_lc3_snk_codec_spec_caps[] = BLE_AUDIO_BUILD_CODEC_CAPS( + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_SAMPLING_FREQUENCIES), + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_FRAME_DURATIONS), + #ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_CHANNEL_COUNTS + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_AUDIO_CHANNEL_COUNTS), + #else + , + #endif + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_MIN_OCTETS_PER_CODEC_FRAME), + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_OCTETS_PER_CODEC_FRAME), + #ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_CODEC_FRAMES_PER_SDU + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_MAX_CODEC_FRAMES_PER_SDU), + #endif +); + +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_METADATA +static uint8_t ble_svc_audio_pacs_lc3_src_metadata[] = +{ UNMANGLE_MYNEWT_VAL(MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_METADATA)) }; +#endif + +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SNK_METADATA +static uint8_t ble_svc_audio_pacs_lc3_snk_metadata[] = +{ UNMANGLE_MYNEWT_VAL(MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_METADATA)) }; +#endif + +static struct ble_audio_codec_register_params src_codec_params = { + .codec_id = { + .format = BLE_SVC_AUDIO_PACS_LC3_CODEC_ID, + .company_id = 0x00, + .vendor_specific = 0x00 + }, + .codec_spec_caps_len = sizeof(ble_svc_audio_pacs_lc3_src_codec_spec_caps), + .codec_spec_caps = ble_svc_audio_pacs_lc3_src_codec_spec_caps, +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_METADATA + .metadata_len = sizeof(ble_svc_audio_pacs_lc3_src_metadata), + .metadata = ble_svc_audio_pacs_lc3_src_metadata, +#else + .metadata_len = 0, +#endif + .direction = BLE_AUDIO_CODEC_DIR_SOURCE_BIT +}; + +static struct ble_audio_codec_register_params snk_codec_params = { + .codec_id = { + .format = BLE_SVC_AUDIO_PACS_LC3_CODEC_ID, + .company_id = 0x00, + .vendor_specific = 0x00 + }, + .codec_spec_caps_len = sizeof(ble_svc_audio_pacs_lc3_snk_codec_spec_caps), + .codec_spec_caps = ble_svc_audio_pacs_lc3_snk_codec_spec_caps, +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SNK_METADATA + .metadata_len = sizeof(ble_svc_audio_pacs_lc3_snk_metadata), + .metadata = ble_svc_audio_pacs_lc3_snk_metadata, +#else + .metadata_len = 0, +#endif + + .direction = BLE_AUDIO_CODEC_DIR_SINK_BIT +}; + +static int +codec_register(void) +{ + int rc; + + rc = ble_audio_codec_register(&src_codec_params, NULL); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_audio_codec_register(&snk_codec_params, NULL); + SYSINIT_PANIC_ASSERT(rc == 0); + + return 0; +} + +int +ble_svc_audio_pacs_lc3_set_avail_contexts(uint16_t conn_handle, + uint16_t sink_contexts, + uint16_t source_contexts) +{ + return ble_svc_audio_pacs_avail_contexts_set(conn_handle, sink_contexts, + source_contexts); +} + +void +ble_svc_audio_pacs_lc3_init(void) +{ + struct ble_svc_audio_pacs_set_param src_params = { + .audio_locations = MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_LOCATIONS), + .supported_contexts = MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_SUP_CONTEXTS) + }; + struct ble_svc_audio_pacs_set_param snk_params = { + .audio_locations = MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_SUP_AUDIO_LOCATIONS), + .supported_contexts = MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_SUP_CONTEXTS) + }; + int rc; + + rc = codec_register(); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_svc_audio_pacs_set(BLE_AUDIO_CODEC_DIR_SOURCE_BIT, &src_params); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_svc_audio_pacs_set(BLE_AUDIO_CODEC_DIR_SINK_BIT, &snk_params); + SYSINIT_PANIC_ASSERT(rc == 0); + + (void)rc; +} diff --git a/nimble/host/audio/services/pacs/lc3/syscfg.yml b/nimble/host/audio/services/pacs/lc3/syscfg.yml new file mode 100644 index 0000000000..f2a2ff0685 --- /dev/null +++ b/nimble/host/audio/services/pacs/lc3/syscfg.yml @@ -0,0 +1,131 @@ +# 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. + +syscfg.defs: + BLE_SVC_AUDIO_PACS_LC3_SRC_SAMPLING_FREQUENCIES: + description: > + Sampling frequencies supported by LC3 codec, as source. This setting is mandatory. + Accepts any combination of values defined in Bluetooth Assigned Numbers 6.12.4.1. + Default value: 48000Hz + value: 0x80 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SRC_FRAME_DURATIONS: + description: > + Frame Durations supported by LC3 codec, as source. This setting is mandatory. + Accepts any combination of values defined in Bluetooth Assigned Numbers 6.12.4.2. + Default value: 7.5ms and 10ms supported, 10ms preferred. + value: 0x23 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_CHANNEL_COUNTS: + description: > + Audio Channel Counts supported by LC3 codec, as source. This setting is optional. + Accepts any combination of values defined in Bluetooth Assigned Numbers 6.12.4.3. + value: + BLE_SVC_AUDIO_PACS_LC3_SRC_MIN_OCTETS_PER_CODEC_FRAME: + description: > + Minimum number of Octets Per Codec Frame supported by LC3 codec, as source. + This setting is mandatory. Default value: 80 + value: 80 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_OCTETS_PER_CODEC_FRAME: + description: > + Maximum number of Octets Per Codec Frame supported by LC3 codec, as source. + This setting is mandatory. Default value: 120 + value: 120 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_CODEC_FRAMES_PER_SDU: + description: > + Maximum number of Codec Frames Per SDU supported by LC3 codec, as source. + This setting is optional. + value: + BLE_SVC_AUDIO_PACS_LC3_SRC_METADATA: + description: > + Optional Metadata to be attached to source codec capabilities. This value shall be in + form of bytes forming LTVs of Metadata. Example: '0x03, 0x01, 0x00, 0x08' + (lenght = 3, type = 0x01 (Preferred_Audio_Contexts), 0x00, 0x04 (Media)) + value: + BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_LOCATIONS: + description: > + Audio Locations supported by source codec. Value is an any combination of values defined + in Bluetooth Assigned Numbers 6.12.1. Default: Front Left and Front Right + value: 0x00000003 + BLE_SVC_AUDIO_PACS_LC3_SRC_SUP_CONTEXTS: + description: > + Audio Locations supported by source codec. Value is an any combination of values defined + in Bluetooth Assigned Numbers 6.12.3. Default: Media + value: 0x0004 + + BLE_SVC_AUDIO_PACS_LC3_SNK_SAMPLING_FREQUENCIES: + description: > + Sampling frequencies supported by LC3 codec, as sink. This setting is mandatory. + Accepts any combination of values defined in Bluetooth Assigned Numbers 6.12.4.1. + Default value: 48000Hz + value: 0x80 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SNK_FRAME_DURATIONS: + description: > + Frame Durations supported by LC3 codec, as sink. This setting is mandatory. + Accepts any combination of values defined in Bluetooth Assigned Numbers 6.12.4.2. + Default value: 7.5ms and 10ms supported, 10ms preferred. + value: 0x23 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SNK_AUDIO_CHANNEL_COUNTS: + description: > + Audio Channel Counts supported by LC3 codec, as sink. This setting is optional. + Accepts any combination of values defined in Bluetooth Assigned Numbers 6.12.4.3. + value: + BLE_SVC_AUDIO_PACS_LC3_SNK_MIN_OCTETS_PER_CODEC_FRAME: + description: > + Minimum number of Octets Per Codec Frame supported by LC3 codec, as source. + This setting is mandatory. Default value: 80 + value: 80 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SNK_MAX_OCTETS_PER_CODEC_FRAME: + description: > + Maximum number of Octets Per Codec Frame supported by LC3 codec, as sink. + This setting is mandatory. Default value: 120 + value: 120 + restrictions: + - $notnull + BLE_SVC_AUDIO_PACS_LC3_SNK_MAX_CODEC_FRAMES_PER_SDU: + description: > + Maximum number of Codec Frames Per SDU supported by LC3 codec, as sink. + This setting is optional. + value: + BLE_SVC_AUDIO_PACS_LC3_SNK_METADATA: + description: > + Optional Metadata to be attached to sink codec capabilities. This value shall be in + form of bytes forming LTVs of Metadata. Example: '0x03, 0x01, 0x00, 0x08' + (lenght = 3, type = 0x01 (Preferred_Audio_Contexts), 0x00, 0x04 (Media)) + value: + BLE_SVC_AUDIO_PACS_LC3_SNK_SUP_AUDIO_LOCATIONS: + description: > + Audio Locations supported by sink codec. Value is an any combination of values defined + in Bluetooth Assigned Numbers 6.12.1. Default: Front Left and Front Right + value: 0x00000003 + BLE_SVC_AUDIO_PACS_LC3_SNK_SUP_CONTEXTS: + description: > + Audio Locations supported by sink codec. Value is an any combination of values defined + in Bluetooth Assigned Numbers 6.12.3. Default: Media + value: 0x0004 diff --git a/nimble/host/audio/services/pacs/pkg.yml b/nimble/host/audio/services/pacs/pkg.yml new file mode 100644 index 0000000000..799378d7e7 --- /dev/null +++ b/nimble/host/audio/services/pacs/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: nimble/host/audio/services/pacs +pkg.description: Published Audio Capabilities Service +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" +pkg.keywords: + - ble + - bluetooth + - pacs + - nimble + +pkg.deps: + - nimble/host + - nimble/host/services/gatt + +pkg.init: + ble_svc_audio_pacs_init: 'MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SYSINIT_STAGE)' diff --git a/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c b/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c new file mode 100644 index 0000000000..9b124a5a97 --- /dev/null +++ b/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c @@ -0,0 +1,479 @@ +/* + * 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. + */ + +#include "audio/ble_audio.h" +#include "host/ble_hs.h" +#include "host/ble_gatt.h" +#include "audio/ble_audio_codec.h" +#include "services/pacs/ble_audio_svc_pacs.h" + +static uint32_t ble_svc_audio_pacs_sink_audio_locations; +static uint32_t ble_svc_audio_pacs_source_audio_locations; +static struct available_ctx { + uint16_t conn_handle; + uint16_t ble_svc_audio_pacs_avail_sink_contexts; + uint16_t ble_svc_audio_pacs_avail_source_contexts; +} ble_svc_audio_pacs_avail_contexts[MYNEWT_VAL(BLE_MAX_CONNECTIONS)] = { + [0 ... MYNEWT_VAL(BLE_MAX_CONNECTIONS) - 1] = { + .conn_handle = BLE_HS_CONN_HANDLE_NONE, + .ble_svc_audio_pacs_avail_sink_contexts = 0, + .ble_svc_audio_pacs_avail_source_contexts = 0 + } +}; +static uint16_t ble_svc_audio_pacs_sup_sink_contexts; +static uint16_t ble_svc_audio_pacs_sup_source_contexts; + +static struct ble_gap_event_listener ble_pacs_listener; +static struct ble_audio_event_listener ble_audio_listener; + +struct pac_read_cb_arg { + struct os_mbuf *om; + uint8_t pac_count; +}; + +static int +ble_svc_audio_pacs_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); + +static const struct ble_gatt_svc_def ble_svc_audio_pacs_defs[] = { + { /*** Service: Published Audio Capabilities Service (PACS) */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BLE_SVC_AUDIO_PACS_UUID16), + .characteristics = (struct ble_gatt_chr_def[]) { +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SINK_PAC) + { + .uuid = BLE_UUID16_DECLARE(BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_PAC), + .access_cb = ble_svc_audio_pacs_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SINK_PAC_NOTIFY) + | BLE_GATT_CHR_F_NOTIFY +#endif + }, +#endif +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SINK_AUDIO_LOCATIONS) + { + .uuid = BLE_UUID16_DECLARE( + BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_AUDIO_LOCATIONS), + .access_cb = ble_svc_audio_pacs_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SINK_AUDIO_LOCATIONS_NOTIFY) + | BLE_GATT_CHR_F_NOTIFY +#endif + }, +#endif +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SOURCE_PAC) + { + .uuid = BLE_UUID16_DECLARE( + BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_PAC), + .access_cb = ble_svc_audio_pacs_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SOURCE_PAC_NOTIFY) + | BLE_GATT_CHR_F_NOTIFY +#endif + }, +#endif +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SOURCE_AUDIO_LOCATIONS) + { + .uuid = BLE_UUID16_DECLARE( + BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_AUDIO_LOCATIONS), + .access_cb = ble_svc_audio_pacs_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SOURCE_AUDIO_LOCATIONS_NOTIFY) + | BLE_GATT_CHR_F_NOTIFY +#endif + }, +#endif + { + .uuid = BLE_UUID16_DECLARE( + BLE_SVC_AUDIO_PACS_CHR_UUID16_AVAILABLE_AUDIO_CONTEXTS), + .access_cb = ble_svc_audio_pacs_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_NOTIFY, + }, { + .uuid = BLE_UUID16_DECLARE( + BLE_SVC_AUDIO_PACS_CHR_UUID16_SUPPORTED_AUDIO_CONTEXTS), + .access_cb = ble_svc_audio_pacs_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC +#if MYNEWT_VAL(BLE_SVC_AUDIO_PACS_SUP_AUDIO_CTX_NOTIFY) + | BLE_GATT_CHR_F_NOTIFY +#endif + }, { + 0, /* No more characteristics in this service */ + } + } + }, + { + 0, /* No more services. */ + }, +}; + +static int +codec_record_to_pacs_entry(const struct ble_audio_codec_record *record, void *arg) +{ + struct pac_read_cb_arg *cb_arg = (struct pac_read_cb_arg *)arg; + uint8_t *buf; + int rc; + + rc = os_mbuf_append(cb_arg->om, &record->codec_id.format, sizeof(uint8_t)); + if (rc) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + buf = os_mbuf_extend(cb_arg->om, 4); + if (buf == NULL) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + put_le16(buf + 0, record->codec_id.company_id); + put_le16(buf + 2, record->codec_id.vendor_specific); + + rc = os_mbuf_append(cb_arg->om, &record->codec_spec_caps_len, sizeof(uint8_t)); + if (rc) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + rc = os_mbuf_append(cb_arg->om, record->codec_spec_caps, record->codec_spec_caps_len); + if (rc) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + rc = os_mbuf_append(cb_arg->om, &record->metadata_len, sizeof(uint8_t)); + if (rc) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + rc = os_mbuf_append(cb_arg->om, record->metadata, record->metadata_len); + if (rc) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + cb_arg->pac_count++; + + return 0; +} + +static int +ble_svc_audio_pacs_sink_pac_read_access(struct ble_gatt_access_ctxt *ctxt) +{ + struct pac_read_cb_arg cb_arg = { + .om = ctxt->om, + .pac_count = 0 + }; + int rc; + uint8_t *pac_count; + + pac_count = os_mbuf_extend(ctxt->om, sizeof(uint8_t)); + rc = ble_audio_codec_foreach(BLE_AUDIO_CODEC_DIR_SINK_BIT, + codec_record_to_pacs_entry, (void *)&cb_arg); + + *pac_count = cb_arg.pac_count; + + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; +} + +static int +ble_svc_audio_pacs_source_pac_read_access(struct ble_gatt_access_ctxt *ctxt) +{ + struct pac_read_cb_arg cb_arg = { + .om = ctxt->om, + .pac_count = 0 + }; + int rc; + uint8_t *pac_count; + + pac_count = os_mbuf_extend(ctxt->om, sizeof(uint8_t)); + rc = ble_audio_codec_foreach(BLE_AUDIO_CODEC_DIR_SOURCE_BIT, + codec_record_to_pacs_entry, (void *)&cb_arg); + + *pac_count = cb_arg.pac_count; + + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; +} + +static int +ble_svc_audio_pacs_sink_audio_loc_read_access(struct ble_gatt_access_ctxt * + ctxt) +{ + uint8_t *buf; + + buf = os_mbuf_extend(ctxt->om, 4); + if (buf == NULL) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + put_le32(buf + 0, ble_svc_audio_pacs_sink_audio_locations); + + return 0; +} + +static int +ble_svc_audio_pacs_source_audio_loc_read_access(struct ble_gatt_access_ctxt * + ctxt) +{ + uint8_t *buf; + + buf = os_mbuf_extend(ctxt->om, 4); + if (buf == NULL) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + put_le32(buf + 0, ble_svc_audio_pacs_source_audio_locations); + + return 0; +} + +static struct available_ctx * +ble_svc_audio_pacs_find_avail_ctx(uint16_t conn_handle) +{ + int i; + + for (i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); i++) { + if (ble_svc_audio_pacs_avail_contexts[i].conn_handle == conn_handle) { + return &ble_svc_audio_pacs_avail_contexts[i]; + } + } + return NULL; +} + +static int +ble_svc_audio_pacs_avail_audio_ctx_read_access(uint16_t conn_handle, + struct ble_gatt_access_ctxt *ctxt) +{ + struct available_ctx *avail_ctx; + uint8_t *buf; + + avail_ctx = ble_svc_audio_pacs_find_avail_ctx(conn_handle); + + buf = os_mbuf_extend(ctxt->om, 4); + if (buf == NULL) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + put_le16(buf + 0, avail_ctx->ble_svc_audio_pacs_avail_sink_contexts); + put_le16(buf + 2, avail_ctx->ble_svc_audio_pacs_avail_source_contexts); + + return 0; +} + +static int +ble_svc_audio_pacs_sup_audio_ctx_read_access(struct ble_gatt_access_ctxt + *ctxt) +{ + uint8_t *buf; + + buf = os_mbuf_extend(ctxt->om, 4); + if (buf == NULL) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + put_le16(buf + 0, ble_svc_audio_pacs_sup_sink_contexts); + put_le16(buf + 2, ble_svc_audio_pacs_sup_source_contexts); + + return 0; +} + +static int +ble_svc_audio_pacs_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + uint16_t uuid16 = ble_uuid_u16(ctxt->chr->uuid); + int rc; + + switch (uuid16) { + case BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_PAC: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = ble_svc_audio_pacs_sink_pac_read_access(ctxt); + } else { + assert(0); + rc = BLE_ATT_ERR_UNLIKELY; + } + return rc; + case BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_AUDIO_LOCATIONS: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = ble_svc_audio_pacs_sink_audio_loc_read_access(ctxt); + } else { + rc = BLE_ATT_ERR_REQ_NOT_SUPPORTED; + } + return rc; + case BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_PAC: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = ble_svc_audio_pacs_source_pac_read_access(ctxt); + } else { + assert(0); + rc = BLE_ATT_ERR_UNLIKELY; + } + return rc; + case BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_AUDIO_LOCATIONS: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = ble_svc_audio_pacs_source_audio_loc_read_access(ctxt); + } else { + rc = BLE_ATT_ERR_REQ_NOT_SUPPORTED; + } + return rc; + case BLE_SVC_AUDIO_PACS_CHR_UUID16_AVAILABLE_AUDIO_CONTEXTS: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = ble_svc_audio_pacs_avail_audio_ctx_read_access(conn_handle, + ctxt); + } else { + assert(0); + rc = BLE_ATT_ERR_UNLIKELY; + } + return rc; + case BLE_SVC_AUDIO_PACS_CHR_UUID16_SUPPORTED_AUDIO_CONTEXTS: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = ble_svc_audio_pacs_sup_audio_ctx_read_access(ctxt); + } else { + assert(0); + rc = BLE_ATT_ERR_UNLIKELY; + } + return rc; + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } +} + +static int +pac_notify(uint16_t chrc_uuid) +{ + uint16_t chr_val_handle; + int rc; + + if (!ble_hs_is_enabled()) { + /* Do not notify if host has not started yet */ + return 0; + } + + rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BLE_SVC_AUDIO_PACS_UUID16), + BLE_UUID16_DECLARE(chrc_uuid), NULL, &chr_val_handle); + + if (!rc) { + ble_gatts_chr_updated(chr_val_handle); + } + + return rc; +} + +int +ble_svc_audio_pacs_set(uint8_t flags, struct ble_svc_audio_pacs_set_param *param) +{ + int rc; + + if (flags & BLE_AUDIO_CODEC_DIR_SOURCE_BIT) { + ble_svc_audio_pacs_source_audio_locations = param->audio_locations; + ble_svc_audio_pacs_sup_source_contexts = param->supported_contexts; + rc = pac_notify(BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_AUDIO_LOCATIONS); + if (rc != 0) { + return rc; + } + } + + if (flags & BLE_AUDIO_CODEC_DIR_SINK_BIT) { + ble_svc_audio_pacs_sink_audio_locations = param->audio_locations; + ble_svc_audio_pacs_sup_sink_contexts = param->supported_contexts; + rc = pac_notify(BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_AUDIO_LOCATIONS); + if (rc != 0) { + return rc; + } + } + + return pac_notify(BLE_SVC_AUDIO_PACS_CHR_UUID16_SUPPORTED_AUDIO_CONTEXTS); +} + +int +ble_svc_audio_pacs_avail_contexts_set(uint16_t conn_handle, + uint16_t sink_contexts, + uint16_t source_contexts) +{ + struct available_ctx *avail_ctx = ble_svc_audio_pacs_find_avail_ctx(conn_handle); + + avail_ctx->ble_svc_audio_pacs_avail_sink_contexts = sink_contexts; + avail_ctx->ble_svc_audio_pacs_avail_source_contexts = source_contexts; + + return pac_notify(BLE_SVC_AUDIO_PACS_CHR_UUID16_AVAILABLE_AUDIO_CONTEXTS); +} + +static int +ble_pacs_audio_event(struct ble_audio_event *event, void *arg) +{ + uint8_t codec_dir; + + if (event->type == BLE_AUDIO_EVENT_CODEC_REGISTERED || + event->type == BLE_AUDIO_EVENT_CODEC_UNREGISTERED) { + codec_dir = event->type == BLE_AUDIO_EVENT_CODEC_REGISTERED ? + event->codec_registered.record->direction : + event->codec_unregistered.record->direction; + + if (codec_dir & BLE_AUDIO_CODEC_DIR_SOURCE_BIT) { + pac_notify(BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_PAC); + } + + if (codec_dir & BLE_AUDIO_CODEC_DIR_SINK_BIT) { + pac_notify(BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_PAC); + } + } + + return 0; +} + +static int +ble_pacs_gap_event(struct ble_gap_event *event, void *arg) +{ + struct available_ctx *avail_ctx; + + switch (event->type) { + case BLE_GAP_EVENT_CONNECT: + if (event->connect.status != 0) { + break; + } + avail_ctx = ble_svc_audio_pacs_find_avail_ctx(BLE_HS_CONN_HANDLE_NONE); + avail_ctx->conn_handle = event->connect.conn_handle; + break; + case BLE_GAP_EVENT_DISCONNECT: + avail_ctx = ble_svc_audio_pacs_find_avail_ctx(event->disconnect.conn.conn_handle); + if (avail_ctx >= 0) { + avail_ctx->conn_handle = BLE_HS_CONN_HANDLE_NONE; + } + break; + default: + break; + } + return 0; +} + +void +ble_svc_audio_pacs_init(void) +{ + int rc; + + /* Ensure this function only gets called by sysinit. */ + SYSINIT_ASSERT_ACTIVE(); + + rc = ble_gatts_count_cfg(ble_svc_audio_pacs_defs); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_gatts_add_svcs(ble_svc_audio_pacs_defs); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_gap_event_listener_register(&ble_pacs_listener, + ble_pacs_gap_event, NULL); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_audio_event_listener_register(&ble_audio_listener, ble_pacs_audio_event, NULL); + SYSINIT_PANIC_ASSERT(rc == 0); + (void)rc; +} diff --git a/nimble/host/audio/services/pacs/syscfg.yml b/nimble/host/audio/services/pacs/syscfg.yml new file mode 100644 index 0000000000..01481c0cee --- /dev/null +++ b/nimble/host/audio/services/pacs/syscfg.yml @@ -0,0 +1,69 @@ +# 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. + +syscfg.defs: + BLE_SVC_AUDIO_PACS_SYSINIT_STAGE: + description: > + Sysinit stage for Published Audio Capabilities Service. + value: 303 + BLE_SVC_AUDIO_PACS_SINK_PAC: + description: > + Enable Sink PAC characteristic. + If disabled, BLE_SVC_AUDIO_PACS_SOURCE_PAC must be enabled. + value: 1 + BLE_SVC_AUDIO_PACS_SINK_PAC_NOTIFY: + description: > + Enable Sink PAC characteristic notifications. + value: 1 + restrictions: BLE_SVC_AUDIO_PACS_SINK_PAC + BLE_SVC_AUDIO_PACS_SINK_AUDIO_LOCATIONS: + description: > + Enable SOURCE Sink Audio Locations characteristic. + value: 1 + restrictions: BLE_SVC_AUDIO_PACS_SINK_PAC + BLE_SVC_AUDIO_PACS_SINK_AUDIO_LOCATIONS_NOTIFY: + description: > + Enable SOURCE Sink Audio Locations characteristic notifications. + value: 1 + restrictions: BLE_SVC_AUDIO_PACS_SINK_AUDIO_LOCATIONS + BLE_SVC_AUDIO_PACS_SOURCE_PAC: + description: > + Enable Source PAC characteristic. + If disabled, BLE_SVC_AUDIO_PACS_SINK_PAC must be enabled. + value: 1 + BLE_SVC_AUDIO_PACS_SOURCE_PAC_NOTIFY: + description: > + Enable Source PAC characteristic notifications. + value: 1 + restrictions: BLE_SVC_AUDIO_PACS_SOURCE_PAC + BLE_SVC_AUDIO_PACS_SOURCE_AUDIO_LOCATIONS: + description: > + Enable Source Audio Locations characteristic. + value: 1 + restrictions: BLE_SVC_AUDIO_PACS_SOURCE_PAC + BLE_SVC_AUDIO_PACS_SOURCE_AUDIO_LOCATIONS_NOTIFY: + description: > + Enable Source Audio Locations characteristic notifications. + value: 1 + restrictions: BLE_SVC_AUDIO_PACS_SOURCE_AUDIO_LOCATIONS + BLE_SVC_AUDIO_PACS_SUP_AUDIO_CTX_NOTIFY: + description: > + Enable Supported Audio Contexts characteristic notifications. + value: 1 + +syscfg.restrictions: + - 'BLE_SVC_AUDIO_PACS_SINK_PAC == 1 || BLE_SVC_AUDIO_PACS_SOURCE_PAC == 1' diff --git a/nimble/host/audio/src/ble_audio_codec.c b/nimble/host/audio/src/ble_audio_codec.c new file mode 100644 index 0000000000..df244f96ff --- /dev/null +++ b/nimble/host/audio/src/ble_audio_codec.c @@ -0,0 +1,138 @@ +/* + * 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. + */ + +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(BLE_AUDIO_MAX_CODEC_RECORDS) +#include "os/os.h" +#include "audio/ble_audio.h" +#include "audio/ble_audio_codec.h" +#include "ble_audio_priv.h" +#include "host/ble_hs.h" +#include "sysinit/sysinit.h" + +static STAILQ_HEAD(, ble_audio_codec_record) ble_audio_codec_records; +static struct os_mempool ble_audio_codec_pool; + +static os_membuf_t ble_audio_svc_pacs_pac_elem_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_AUDIO_MAX_CODEC_RECORDS), + sizeof (struct ble_audio_codec_record)) +]; + +int +ble_audio_codec_register(const struct ble_audio_codec_register_params *params, + struct ble_audio_codec_record *out_record) +{ + struct ble_audio_event codec_event = { + .type = BLE_AUDIO_EVENT_CODEC_REGISTERED + }; + + struct ble_audio_codec_record *record = + os_memblock_get(&ble_audio_codec_pool); + if (!record) { + return BLE_HS_ENOMEM; + } + + record->codec_id = params->codec_id; + record->codec_spec_caps_len = params->codec_spec_caps_len; + record->codec_spec_caps = params->codec_spec_caps; + record->metadata_len = params->metadata_len; + record->metadata = params->metadata; + record->direction = params->direction; + + if (STAILQ_EMPTY(&ble_audio_codec_records)) { + STAILQ_INSERT_HEAD(&ble_audio_codec_records, record, next); + } else { + STAILQ_INSERT_TAIL(&ble_audio_codec_records, record, next); + } + + out_record = record; + + codec_event.codec_registered.record = record; + (void)ble_audio_event_listener_call(&codec_event); + + return 0; +} + +int +ble_audio_codec_unregister(struct ble_audio_codec_record *codec_record) +{ + struct ble_audio_event codec_event = { + .type = BLE_AUDIO_EVENT_CODEC_UNREGISTERED + }; + + STAILQ_REMOVE(&ble_audio_codec_records, codec_record, + ble_audio_codec_record, next); + + codec_event.codec_unregistered.record = codec_record; + (void)ble_audio_event_listener_call(&codec_event); + + return 0; +} + +int +ble_audio_codec_foreach(uint8_t flags, ble_audio_codec_foreach_fn *cb, void *arg) +{ + struct ble_audio_codec_record *record; + int rc; + + STAILQ_FOREACH(record, &ble_audio_codec_records, next) { + if (record->direction & flags) { + rc = cb(record, arg); + if (rc != 0) { + return rc; + } + } + } + return 0; +} + +struct ble_audio_codec_record * +ble_audio_codec_find(struct ble_audio_codec_id codec_id, uint8_t flag) +{ + struct ble_audio_codec_record *record; + + STAILQ_FOREACH(record, &ble_audio_codec_records, next) { + if (!memcmp(&record->codec_id, &codec_id, + sizeof(struct ble_audio_codec_id)) && + (flag ? (record->direction & flag) : 1)) { + return record; + } + } + + return NULL; +} + +int +ble_audio_codec_init(void) +{ + int rc; + + STAILQ_INIT(&ble_audio_codec_records); + + rc = os_mempool_init(&ble_audio_codec_pool, + MYNEWT_VAL(BLE_AUDIO_MAX_CODEC_RECORDS), + sizeof(struct ble_audio_codec_record), + ble_audio_svc_pacs_pac_elem_mem, + "ble_audio_codec_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); + + return 0; +} +#endif diff --git a/nimble/host/audio/syscfg.yml b/nimble/host/audio/syscfg.yml index d7af13d1a0..5f0269e0ab 100644 --- a/nimble/host/audio/syscfg.yml +++ b/nimble/host/audio/syscfg.yml @@ -17,5 +17,9 @@ # syscfg.defs: + BLE_AUDIO_MAX_CODEC_RECORDS: + description: > + Maximum number of registered audio codecs. + value: 0 syscfg.logs: diff --git a/nimble/host/src/ble_audio_codec_priv.h b/nimble/host/src/ble_audio_codec_priv.h new file mode 100644 index 0000000000..64e999efeb --- /dev/null +++ b/nimble/host/src/ble_audio_codec_priv.h @@ -0,0 +1,25 @@ +/* + * 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_BLE_AUDIO_CODEC_PRIV_ +#define H_BLE_AUDIO_CODEC_PRIV_ + +int ble_audio_codec_init(void); + +#endif /* H_BLE_AUDIO_CODEC_PRIV_ */ diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index 7983cca187..bac7f02e6a 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -765,6 +765,11 @@ ble_hs_init(void) #endif #endif +#if MYNEWT_VAL(BLE_AUDIO_MAX_CODEC_RECORDS) + rc = ble_audio_codec_init(); + SYSINIT_PANIC_ASSERT(rc == 0); +#endif + ble_hs_stop_init(); ble_mqueue_init(&ble_hs_rx_q, ble_hs_event_rx_data, NULL); diff --git a/nimble/host/src/ble_hs_priv.h b/nimble/host/src/ble_hs_priv.h index 393b4d4323..49022b17b7 100644 --- a/nimble/host/src/ble_hs_priv.h +++ b/nimble/host/src/ble_hs_priv.h @@ -26,6 +26,7 @@ #include "ble_att_priv.h" #include "ble_eatt_priv.h" #include "ble_gap_priv.h" +#include "ble_audio_codec_priv.h" #include "ble_gatt_priv.h" #include "ble_hs_hci_priv.h" #include "ble_hs_atomic_priv.h" diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index 6571329582..e4d2d3a46f 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -599,6 +599,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS +#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#endif + #ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM #define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) #endif diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 8321199654..3919eb1eb0 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -600,6 +600,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS +#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#endif + #ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM #define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) #endif diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index af7f7992cb..16cdc6c005 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -599,6 +599,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS +#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#endif + #ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM #define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) #endif diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index c62bb02c50..4054f14403 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -598,6 +598,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS +#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#endif + #ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM #define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) #endif diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 27047feb56..1c46e12a63 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1515,6 +1515,10 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif +#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS +#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#endif + #ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM #define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) #endif From 59ce2f441010a5d572fa5ca16fc28240cc2601fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 27 Feb 2024 10:07:44 +0100 Subject: [PATCH 0933/1333] ext: add libsamplerate library Adds libsamplerate library that allows to resample audio streams to different samplerate. --- ext/libsamplerate/include/config.h | 44 +++++++++++++++++++++++ ext/libsamplerate/pkg.yml | 57 ++++++++++++++++++++++++++++++ ext/libsamplerate/syscfg.yml | 30 ++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 ext/libsamplerate/include/config.h create mode 100644 ext/libsamplerate/pkg.yml create mode 100644 ext/libsamplerate/syscfg.yml diff --git a/ext/libsamplerate/include/config.h b/ext/libsamplerate/include/config.h new file mode 100644 index 0000000000..756c57d18f --- /dev/null +++ b/ext/libsamplerate/include/config.h @@ -0,0 +1,44 @@ +/* + * 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_LIBSAMPLERATE_CONFIG_ +#define H_LIBSAMPLERATE_CONFIG_ + +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(ENABLE_SINC_BEST_CONVERTER) +#define ENABLE_SINC_BEST_CONVERTER 1 +#endif + +#if MYNEWT_VAL(ENABLE_SINC_MEDIUM_CONVERTER) +#define ENABLE_SINC_MEDIUM_CONVERTER 1 +#endif + +#if MYNEWT_VAL(ENABLE_SINC_FAST_CONVERTER) +#define ENABLE_SINC_FAST_CONVERTER 1 +#endif + +#if MYNEWT_VAL(LIBSAMPLER_NDEBUG) +#define LIBSAMPLER_NDEBUG 1 +#endif + +#define PACKAGE "libsamplerate" +#define VERSION "0.2.2" + +#endif /* H_LIBSAMPLERATE_CONFIG_ */ diff --git a/ext/libsamplerate/pkg.yml b/ext/libsamplerate/pkg.yml new file mode 100644 index 0000000000..a42d0ea6c7 --- /dev/null +++ b/ext/libsamplerate/pkg.yml @@ -0,0 +1,57 @@ +# +# 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: ext/libsamplerate +pkg.description: samplerate library +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - samplerate + +pkg.type: sdk + +pkg.cflags: -DHAVE_STDBOOL_H -fsingle-precision-constant -DHAVE_CONFIG_H +pkg.cflags.ENABLE_SINC_BEST_CONVERTER: -DENABLE_SINC_BEST_CONVERTER +pkg.cflags.ENABLE_SINC_MEDIUM_CONVERTER: -DENABLE_SINC_MEDIUM_CONVERTER +pkg.cflags.ENABLE_SINC_FAST_CONVERTER: -DENABLE_SINC_FAST_CONVERTER +pkg.cflags.LIBSAMPLER_NDEBUG: -DNDEBUG +pkg.lflags: -lm + +pkg.ign_dirs: + - "@libsamplerate/Octave" + - "@libsamplerate/Win32" + - "@libsamplerate/cmake" + - "@libsamplerate/docs" + - "@libsamplerate/examples" + - "@libsamplerate/include" + - "@libsamplerate/m4" + - "@libsamplerate/tests" + +pkg.src_dirs: + - "@libsamplerate/src" + +pkg.include_dirs: + - "@libsamplerate/include" + +repository.libsamplerate: + type: github + vers: 0.2.2-commit + branch: release-0.2.2 + user: libsndfile + repo: libsamplerate diff --git a/ext/libsamplerate/syscfg.yml b/ext/libsamplerate/syscfg.yml new file mode 100644 index 0000000000..11232a69bb --- /dev/null +++ b/ext/libsamplerate/syscfg.yml @@ -0,0 +1,30 @@ +# 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. + +syscfg.defs: + ENABLE_SINC_BEST_CONVERTER: + description: Enable SINC best converter + value: 1 + ENABLE_SINC_MEDIUM_CONVERTER: + description: Enable SINC medium converter + value: 1 + ENABLE_SINC_FAST_CONVERTER: + description: Enable SINC fastest converter + value: 1 + LIBSAMPLER_NDEBUG: + description: Define NDEBUG for resampler code (turns off asserts) + value: 0 From 8b7eda2a561df50004fb507fbfa4451b72398d78 Mon Sep 17 00:00:00 2001 From: taks <857tn859@gmail.com> Date: Mon, 4 Mar 2024 09:01:06 +0900 Subject: [PATCH 0934/1333] nimble/host: Fix ble_gap_adv_set_data return code --- nimble/host/src/ble_gap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 8c63610c68..8e83b2d85f 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -2772,7 +2772,7 @@ ble_gap_adv_set_data(const uint8_t *data, int data_len) /* Check for valid parameters */ if (((data == NULL) && (data_len != 0)) || (data_len > BLE_HCI_MAX_ADV_DATA_LEN)) { - return BLE_ERR_INV_HCI_CMD_PARMS; + return BLE_HS_EINVAL; } memcpy(cmd.adv_data, data, data_len); From f901dfa0c2fec668e277ae4546dffdd15f320962 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 5 Mar 2024 11:43:58 +0100 Subject: [PATCH 0935/1333] nimble/iso: Fix missing big_handle return parameter This fixes ble_iso_create_big to return the BIG handle created to the API user. Signed-off-by: Mariusz Skamra --- apps/btshell/src/cmd_iso.c | 5 ++++- nimble/host/audio/src/ble_audio_broadcast_source.c | 6 ++++-- nimble/host/include/host/ble_iso.h | 4 +++- nimble/host/src/ble_iso.c | 5 ++++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/apps/btshell/src/cmd_iso.c b/apps/btshell/src/cmd_iso.c index 284f02111e..27a9bc9d44 100644 --- a/apps/btshell/src/cmd_iso.c +++ b/apps/btshell/src/cmd_iso.c @@ -164,6 +164,7 @@ cmd_iso_big_create(int argc, char **argv) { struct ble_iso_create_big_params params = { 0 }; struct ble_iso_big_params big_params = { 0 }; + uint8_t big_handle; int rc; rc = parse_arg_init(argc - 1, argv + 1); @@ -235,12 +236,14 @@ cmd_iso_big_create(int argc, char **argv) big_params.broadcast_code = parse_arg_extract("broadcast_code"); big_params.encryption = big_params.broadcast_code ? 1 : 0; - rc = ble_iso_create_big(¶ms, &big_params); + rc = ble_iso_create_big(¶ms, &big_params, &big_handle); if (rc != 0) { console_printf("BIG create failed (%d)\n", rc); return rc; } + console_printf("New big_handle %u created\n", big_handle); + return 0; } diff --git a/nimble/host/audio/src/ble_audio_broadcast_source.c b/nimble/host/audio/src/ble_audio_broadcast_source.c index d243a5f197..20edcceab1 100644 --- a/nimble/host/audio/src/ble_audio_broadcast_source.c +++ b/nimble/host/audio/src/ble_audio_broadcast_source.c @@ -25,6 +25,7 @@ #if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) struct ble_audio_broadcast { SLIST_ENTRY(ble_audio_broadcast) next; + uint8_t big_handle; uint8_t adv_instance; struct ble_audio_base *base; struct ble_iso_big_params *big_params; @@ -332,7 +333,8 @@ ble_audio_broadcast_start(uint8_t adv_instance, return rc; } - rc = ble_iso_create_big(&create_big_params, broadcast->big_params); + rc = ble_iso_create_big(&create_big_params, broadcast->big_params, + &broadcast->big_handle); if (rc) { BLE_HS_LOG_ERROR("Failed to create BIG (rc=%d)\n", rc); return rc; @@ -378,7 +380,7 @@ ble_audio_broadcast_destroy(uint8_t adv_instance) return rc; } - rc = ble_iso_terminate_big(adv_instance); + rc = ble_iso_terminate_big(broadcast->big_handle); if (rc) { BLE_HS_LOG_ERROR("Failed to terminate BIG\n"); return rc; diff --git a/nimble/host/include/host/ble_iso.h b/nimble/host/include/host/ble_iso.h index 1bae3366d4..ee99b962bd 100644 --- a/nimble/host/include/host/ble_iso.h +++ b/nimble/host/include/host/ble_iso.h @@ -307,6 +307,7 @@ struct ble_iso_create_big_params { * the BIG. These parameters include settings * such as SDU interval, maximum SDU size, * transport latency, etc. + * @param[out] big_handle BIG instance handle * * @return 0 on success; * an error code on failure. @@ -315,7 +316,8 @@ struct ble_iso_create_big_params { * function specified in @p create_params. */ int ble_iso_create_big(const struct ble_iso_create_big_params *create_params, - const struct ble_iso_big_params *big_params); + const struct ble_iso_big_params *big_params, + uint8_t *big_handle); /** * Terminates an existing Broadcast Isochronous Group (BIG). diff --git a/nimble/host/src/ble_iso.c b/nimble/host/src/ble_iso.c index 503cdd0d03..76bc948038 100644 --- a/nimble/host/src/ble_iso.c +++ b/nimble/host/src/ble_iso.c @@ -228,7 +228,8 @@ ble_iso_big_free(struct ble_iso_big *big) #if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) int ble_iso_create_big(const struct ble_iso_create_big_params *create_params, - const struct ble_iso_big_params *big_params) + const struct ble_iso_big_params *big_params, + uint8_t *big_handle) { struct ble_hci_le_create_big_cp cp = { 0 }; struct ble_iso_big *big; @@ -271,6 +272,8 @@ ble_iso_create_big(const struct ble_iso_create_big_params *create_params, memcpy(cp.broadcast_code, big_params->broadcast_code, 16); } + *big_handle = big->handle; + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_CREATE_BIG), &cp, sizeof(cp),NULL, 0); From 75b35adb697c263d3e8f85be80ac5a39a45e15bd Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 5 Mar 2024 11:57:55 +0100 Subject: [PATCH 0936/1333] nimble/iso: Fix potential memory leak This fixes potential BIG memory leak in case ble_hs_hci_cmd_tx returned an error. If the error is returned, the code will free the allocated BIG and BISes. --- nimble/host/src/ble_iso.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/nimble/host/src/ble_iso.c b/nimble/host/src/ble_iso.c index 76bc948038..004b1fc474 100644 --- a/nimble/host/src/ble_iso.c +++ b/nimble/host/src/ble_iso.c @@ -233,6 +233,7 @@ ble_iso_create_big(const struct ble_iso_create_big_params *create_params, { struct ble_hci_le_create_big_cp cp = { 0 }; struct ble_iso_big *big; + int rc; cp.adv_handle = create_params->adv_handle; if (create_params->bis_cnt > MYNEWT_VAL(BLE_ISO_MAX_BISES)) { @@ -272,11 +273,16 @@ ble_iso_create_big(const struct ble_iso_create_big_params *create_params, memcpy(cp.broadcast_code, big_params->broadcast_code, 16); } - *big_handle = big->handle; + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CREATE_BIG), + &cp, sizeof(cp),NULL, 0); + if (rc != 0) { + ble_iso_big_free(big); + } else { + *big_handle = big->handle; + } - return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_CREATE_BIG), - &cp, sizeof(cp),NULL, 0); + return rc; } int From 65fcd4245e31f5e1d3fd4fb7d1a7536a8ddbe6a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 5 Mar 2024 06:39:51 +0100 Subject: [PATCH 0937/1333] ext/libsamplerate: adjust config.h to be package exclusive `config.h` being in `include` directory meant that it was included globally. It may cause it being indluded into other package (as global include) Added prefixes to libsamplerate syscfg settings. --- ext/libsamplerate/{include => src}/config.h | 8 ++++---- ext/libsamplerate/syscfg.yml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) rename ext/libsamplerate/{include => src}/config.h (84%) diff --git a/ext/libsamplerate/include/config.h b/ext/libsamplerate/src/config.h similarity index 84% rename from ext/libsamplerate/include/config.h rename to ext/libsamplerate/src/config.h index 756c57d18f..9c77c58e4f 100644 --- a/ext/libsamplerate/include/config.h +++ b/ext/libsamplerate/src/config.h @@ -22,19 +22,19 @@ #include "syscfg/syscfg.h" -#if MYNEWT_VAL(ENABLE_SINC_BEST_CONVERTER) +#if MYNEWT_VAL(LIBSAMPLERATE_ENABLE_SINC_BEST_CONVERTER) #define ENABLE_SINC_BEST_CONVERTER 1 #endif -#if MYNEWT_VAL(ENABLE_SINC_MEDIUM_CONVERTER) +#if MYNEWT_VAL(LIBSAMPLERATE_ENABLE_SINC_MEDIUM_CONVERTER) #define ENABLE_SINC_MEDIUM_CONVERTER 1 #endif -#if MYNEWT_VAL(ENABLE_SINC_FAST_CONVERTER) +#if MYNEWT_VAL(LIBSAMPLERATE_ENABLE_SINC_FAST_CONVERTER) #define ENABLE_SINC_FAST_CONVERTER 1 #endif -#if MYNEWT_VAL(LIBSAMPLER_NDEBUG) +#if MYNEWT_VAL(LIBSAMPLERATE_LIBSAMPLER_NDEBUG) #define LIBSAMPLER_NDEBUG 1 #endif diff --git a/ext/libsamplerate/syscfg.yml b/ext/libsamplerate/syscfg.yml index 11232a69bb..285820045f 100644 --- a/ext/libsamplerate/syscfg.yml +++ b/ext/libsamplerate/syscfg.yml @@ -16,15 +16,15 @@ # under the License. syscfg.defs: - ENABLE_SINC_BEST_CONVERTER: + LIBSAMPLERATE_ENABLE_SINC_BEST_CONVERTER: description: Enable SINC best converter value: 1 - ENABLE_SINC_MEDIUM_CONVERTER: + LIBSAMPLERATE_ENABLE_SINC_MEDIUM_CONVERTER: description: Enable SINC medium converter value: 1 - ENABLE_SINC_FAST_CONVERTER: + LIBSAMPLERATE_ENABLE_SINC_FAST_CONVERTER: description: Enable SINC fastest converter value: 1 - LIBSAMPLER_NDEBUG: + LIBSAMPLERATE_LIBSAMPLER_NDEBUG: description: Define NDEBUG for resampler code (turns off asserts) value: 0 From 253f5901b64cede3b0eef8f31345452f14f65f1c Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Thu, 7 Mar 2024 14:24:31 +0100 Subject: [PATCH 0938/1333] nimble/host: Fix invalid response for mtu exchange request This commit applies valid response (Request Not Supported) when mtu exchange is requested over EATT. --- nimble/host/src/ble_att_svr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index aad64f687d..145318f09d 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -727,7 +727,7 @@ ble_att_svr_rx_mtu(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) if (cid != BLE_L2CAP_CID_ATT) { /*TODO */ - return BLE_ATT_ERR_INVALID_PDU; + return BLE_HS_ENOTSUP; } rc = ble_att_svr_pullup_req_base(rxom, sizeof(*cmd), &att_err); From 0ccd12212b37ff9743d40b9fb902561b3e810373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Mar 2024 07:29:01 +0100 Subject: [PATCH 0939/1333] ext/libsamplerate: always build with DNDEBUG flag Debug build pulls assert.h and nrfx, in which PACKAGE define isi pulled from libsamplerate/serc/config.h. This is not correct behavior and these defines are not correlated. Library should be always build without asserts, circumventing the issue. Cleaned up duplicated cflags in pkg.yml. --- ext/libsamplerate/pkg.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ext/libsamplerate/pkg.yml b/ext/libsamplerate/pkg.yml index a42d0ea6c7..a8164ac1bd 100644 --- a/ext/libsamplerate/pkg.yml +++ b/ext/libsamplerate/pkg.yml @@ -26,11 +26,7 @@ pkg.keywords: pkg.type: sdk -pkg.cflags: -DHAVE_STDBOOL_H -fsingle-precision-constant -DHAVE_CONFIG_H -pkg.cflags.ENABLE_SINC_BEST_CONVERTER: -DENABLE_SINC_BEST_CONVERTER -pkg.cflags.ENABLE_SINC_MEDIUM_CONVERTER: -DENABLE_SINC_MEDIUM_CONVERTER -pkg.cflags.ENABLE_SINC_FAST_CONVERTER: -DENABLE_SINC_FAST_CONVERTER -pkg.cflags.LIBSAMPLER_NDEBUG: -DNDEBUG +pkg.cflags: -DHAVE_STDBOOL_H -fsingle-precision-constant -DHAVE_CONFIG_H -DNDEBUG pkg.lflags: -lm pkg.ign_dirs: From f9472d5748cba7706567d323ea1aa56493a4227b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 8 Mar 2024 11:03:13 +0100 Subject: [PATCH 0940/1333] ext/libsamplerate: remove unneeded ign_dirs src_dirs and include_dirs fully describes what to compile and what not. --- ext/libsamplerate/pkg.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/ext/libsamplerate/pkg.yml b/ext/libsamplerate/pkg.yml index a8164ac1bd..4bb8089027 100644 --- a/ext/libsamplerate/pkg.yml +++ b/ext/libsamplerate/pkg.yml @@ -29,16 +29,6 @@ pkg.type: sdk pkg.cflags: -DHAVE_STDBOOL_H -fsingle-precision-constant -DHAVE_CONFIG_H -DNDEBUG pkg.lflags: -lm -pkg.ign_dirs: - - "@libsamplerate/Octave" - - "@libsamplerate/Win32" - - "@libsamplerate/cmake" - - "@libsamplerate/docs" - - "@libsamplerate/examples" - - "@libsamplerate/include" - - "@libsamplerate/m4" - - "@libsamplerate/tests" - pkg.src_dirs: - "@libsamplerate/src" From cdf2520550d2cab7b6914150cc514216c37a3828 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Fri, 8 Mar 2024 15:05:45 +0100 Subject: [PATCH 0941/1333] apps: blestress: Perform all tests Edit for loop to run all tests. --- apps/blestress/src/rx_stress.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/blestress/src/rx_stress.c b/apps/blestress/src/rx_stress.c index 95b7082185..d684ab40b4 100644 --- a/apps/blestress/src/rx_stress.c +++ b/apps/blestress/src/rx_stress.c @@ -1208,7 +1208,7 @@ static struct rx_stress_adv_set rx_stress_adv_sets[] = { }, { .instance = SWITCHER_INSTANCE, - .instance_uuid128 = rx_stress_uuid128[0], + .instance_uuid128 = rx_stress_uuid128[1], .legacy_pdu = LEGACY_ADVERT, .cb = rx_stress_0_gap_event, .pattern_data = NULL, @@ -1340,6 +1340,12 @@ rx_stress_start(int test_num) /* Start test. */ switch (test_num) { + case 0: + return; + case 1: + console_printf("Nothing to do"); + rx_stress_simple_adv(&rx_stress_adv_sets[1]); + return; case 2: console_printf("Stress Connect/Disconnect legacy\033[0m\n"); rx_stress_simple_adv(&rx_stress_adv_sets[2]); @@ -1455,7 +1461,7 @@ rx_stress_main_task_fn(void *arg) os_sem_pend(&rx_stress_main_sem, OS_TIMEOUT_NEVER); /* Standard tests perform */ - for (i = 11; i < STRESS_UUIDS_NUM; ++i) { + for (i = 1; i < STRESS_UUIDS_NUM; ++i) { /* Start test. */ rx_stress_start(i); } From a830ac364550eaf53d80b7c68e25abdc09e00b02 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Fri, 26 Jan 2024 10:40:48 +0100 Subject: [PATCH 0942/1333] host/sm: Add doxygen comments to the header file Adds missing macros, functions and structures documentation. --- nimble/host/include/host/ble_sm.h | 221 +++++++++++++++++++++++++++++- 1 file changed, 218 insertions(+), 3 deletions(-) diff --git a/nimble/host/include/host/ble_sm.h b/nimble/host/include/host/ble_sm.h index 51e745f36c..503e1310a4 100644 --- a/nimble/host/include/host/ble_sm.h +++ b/nimble/host/include/host/ble_sm.h @@ -20,6 +20,13 @@ #ifndef H_BLE_SM_ #define H_BLE_SM_ +/** + * @brief Bluetooth Security Manager (SM) + * @defgroup bt_sm Bluetooth Security Manager (SM) + * @ingroup bt_host + * @{ + */ + #include #include "syscfg/syscfg.h" #include @@ -29,68 +36,213 @@ extern "C" { #endif +/** + * @defgroup ble_sm_err Security Manager (SM) Error Codes + * @{ + */ + +/** SM Error Code: Success */ #define BLE_SM_ERR_SUCCESS 0x00 + +/** SM Error Code: Passkey entry failed */ #define BLE_SM_ERR_PASSKEY 0x01 + +/** SM Error Code: Out Of Band (OOB) not available */ #define BLE_SM_ERR_OOB 0x02 + +/** SM Error Code: Authentication Requirements */ #define BLE_SM_ERR_AUTHREQ 0x03 + +/** SM Error Code: Confirm Value failed */ #define BLE_SM_ERR_CONFIRM_MISMATCH 0x04 + +/** SM Error Code: Pairing Not Supported */ #define BLE_SM_ERR_PAIR_NOT_SUPP 0x05 + +/** SM Error Code: Encryption Key Size */ #define BLE_SM_ERR_ENC_KEY_SZ 0x06 + +/** SM Error Code: Command Not Supported */ #define BLE_SM_ERR_CMD_NOT_SUPP 0x07 + +/** SM Error Code: Unspecified Reason */ #define BLE_SM_ERR_UNSPECIFIED 0x08 + +/** SM Error Code: Repeated Attempts */ #define BLE_SM_ERR_REPEATED 0x09 + +/** SM Error Code: Invalid Parameters */ #define BLE_SM_ERR_INVAL 0x0a + +/** SM Error Code: DHKey Check failed */ #define BLE_SM_ERR_DHKEY 0x0b + +/** SM Error Code: Numeric Comparison failed */ #define BLE_SM_ERR_NUMCMP 0x0c + +/** SM Error Code: Pairing in progress */ #define BLE_SM_ERR_ALREADY 0x0d + +/** SM Error Code: Cross-transport Key Derivation/Generation not allowed */ #define BLE_SM_ERR_CROSS_TRANS 0x0e + +/** SM Error Code: Key Rejected */ #define BLE_SM_ERR_KEY_REJ 0x0f + +/** SM Error Code: Out Of Boundary Code Value */ #define BLE_SM_ERR_MAX_PLUS_1 0x10 +/** @} */ + +/** + * @defgroup ble_sm_pair_alg Security Manager (SM) Pairing Algorithms + * @{ + */ + +/** SM Pairing Algorithm: Just Works */ #define BLE_SM_PAIR_ALG_JW 0 + +/** SM Pairing Algorithm: Passkey Entry */ #define BLE_SM_PAIR_ALG_PASSKEY 1 + +/** SM Pairing Algorithm: Out Of Band */ #define BLE_SM_PAIR_ALG_OOB 2 + +/** SM Pairing Algorithm: Numeric Comparison */ #define BLE_SM_PAIR_ALG_NUMCMP 3 +/** @} */ + +/** + * @defgroup ble_sm_pair_key_dist Security Manager (SM) Key Distribution Flags + * @{ + */ + +/** SM Key Distribution: Distribute Long Term Key (LTK) */ #define BLE_SM_PAIR_KEY_DIST_ENC 0x01 + +/** SM Key Distribution: Distribute Identity Resolving Key (IRK) */ #define BLE_SM_PAIR_KEY_DIST_ID 0x02 + +/** SM Key Distribution: Distribute Connection Signature Resolving Key (CSRK) */ #define BLE_SM_PAIR_KEY_DIST_SIGN 0x04 + +/** SM Key Distribution: Derive the Link Key from the LTK */ #define BLE_SM_PAIR_KEY_DIST_LINK 0x08 + +/** SM Key Distribution: Reserved For Future Use */ #define BLE_SM_PAIR_KEY_DIST_RESERVED 0xf0 +/** @} */ + +/** + * @defgroup ble_sm_io_cap Security Manager (SM) Input/Output Capabilities + * @{ + */ + +/** SM IO Capabilities: Display Only */ #define BLE_SM_IO_CAP_DISP_ONLY 0x00 + +/** SM IO Capabilities: Display Yes No */ #define BLE_SM_IO_CAP_DISP_YES_NO 0x01 + +/** SM IO Capabilities: Keyboard Only */ #define BLE_SM_IO_CAP_KEYBOARD_ONLY 0x02 + +/** SM IO Capabilities: No Input No Output */ #define BLE_SM_IO_CAP_NO_IO 0x03 + +/** SM IO Capabilities: Keyboard Display */ #define BLE_SM_IO_CAP_KEYBOARD_DISP 0x04 + +/** SM IO Capabilities: Reserved For Future Use */ #define BLE_SM_IO_CAP_RESERVED 0x05 +/** @} */ + +/** + * @defgroup ble_sm_pair_oob Security Manager (SM) Out Of Band Data (OOB) Flags + * @{ + */ + +/** SM OOB: Out Of Band Data Not Available */ #define BLE_SM_PAIR_OOB_NO 0x00 + +/** SM OOB: Out Of Band Data Available */ #define BLE_SM_PAIR_OOB_YES 0x01 + +/** SM OOB: Reserved For Future Use */ #define BLE_SM_PAIR_OOB_RESERVED 0x02 +/** @} */ + +/** + * @defgroup ble_sm_authreq Security Manager (SM) Authentication Requirements Flags + * @{ + */ + +/** SM Authentication Requirement: Bonding */ #define BLE_SM_PAIR_AUTHREQ_BOND 0x01 + +/** SM Authentication Requirement: MITM protection */ #define BLE_SM_PAIR_AUTHREQ_MITM 0x04 + +/** SM Authentication Requirement: Secure Connections */ #define BLE_SM_PAIR_AUTHREQ_SC 0x08 + +/** SM Authentication Requirement: Keypress notifications */ #define BLE_SM_PAIR_AUTHREQ_KEYPRESS 0x10 + +/** SM Authentication Requirement: Reserved For Future Use */ #define BLE_SM_PAIR_AUTHREQ_RESERVED 0xe2 +/** @} */ + +/** + * @defgroup ble_sm_pair_key_sz Security Manager (SM) Key Sizes + * @{ + */ + +/** SM Key Size: Minimum supported encryption key size in octets */ #define BLE_SM_PAIR_KEY_SZ_MIN 7 + +/** SM Key Size: Maximum supported encryption key size in octets */ #define BLE_SM_PAIR_KEY_SZ_MAX 16 -/* +/** @} */ + +/** + * @defgroup ble_sm_ioact Security Manager (SM) Key Generation Action + * @{ * The security manager asks the application to perform a key generation * action. The application passes the passkey back to SM via * ble_sm_inject_io(). */ + +/** SM IO Action: None (Just Works pairing) */ #define BLE_SM_IOACT_NONE 0 + +/** SM IO Action: Out Of Band (OOB) */ #define BLE_SM_IOACT_OOB 1 + +/** SM IO Action: Input (Passkey Entry) */ #define BLE_SM_IOACT_INPUT 2 + +/** SM IO Action: Passkey Display */ #define BLE_SM_IOACT_DISP 3 + +/** SM IO Action: Numeric Comparison */ #define BLE_SM_IOACT_NUMCMP 4 + +/** SM IO Action: Out Of Band (OOB) Secure Connections */ #define BLE_SM_IOACT_OOB_SC 5 + +/** SM IO Action: Out Of Boundary Code Value */ #define BLE_SM_IOACT_MAX_PLUS_ONE 6 +/** @} */ + +/** Represents Out Of Band (OOB) data used in Secure Connections pairing */ struct ble_sm_sc_oob_data { /** Random Number. */ uint8_t r[16]; @@ -99,19 +251,64 @@ struct ble_sm_sc_oob_data { uint8_t c[16]; }; +/** Represents Input/Output data for Security Manager used during pairing process */ struct ble_sm_io { + /** Pairing action, indicating the type of pairing method. Can be one of the + * following: + * o BLE_SM_IOACT_NONE + * o BLE_SM_IOACT_OOB + * o BLE_SM_IOACT_INPUT + * o BLE_SM_IOACT_DISP + * o BLE_SM_IOACT_NUMCMP + * o BLE_SM_IOACT_OOB_SC + */ uint8_t action; + + /** Union holding different types of pairing data. The valid field is inferred + * from the action field. */ union { + /** Passkey value between 000000 and 999999. + * Valid for the following actions: + * o BLE_SM_IOACT_INPUT + * o BLE_SM_IOACT_DISP + */ uint32_t passkey; + + /** Temporary Key random value used in Legacy Pairing. + * Valid for the following actions: + * o BLE_SM_IOACT_OOB + */ uint8_t oob[16]; + + /** Numeric Comparison acceptance indicator. + * Valid for the following actions: + * o BLE_SM_IOACT_NUMCMP + */ uint8_t numcmp_accept; + + /** Out Of Band (OOB) data used in Secure Connections. + * Valid for the following actions: + * o BLE_SM_IOACT_OOB_SC + */ struct { - struct ble_sm_sc_oob_data *local; + /** Remote Secure Connections Out Of Band (OOB) data */ struct ble_sm_sc_oob_data *remote; + /** Local Secure Connections Out Of Band (OOB) data */ + struct ble_sm_sc_oob_data *local; } oob_sc_data; }; }; +/** + * Generates Out of Band (OOB) data used during the authentication process. + * The data consists of 128-bit Random Number and 128-bit Confirm Value. + * + * @param oob_data A pointer to the structure where the generated + * OOB data will be stored. + * + * @return 0 on success; + * Non-zero on failure. + */ int ble_sm_sc_oob_generate_data(struct ble_sm_sc_oob_data *oob_data); #if MYNEWT_VAL(BLE_SM_CSIS_SIRK) @@ -132,8 +329,22 @@ int ble_sm_csis_resolve_rsi(const uint8_t *rsi, const uint8_t *sirk, #endif #if NIMBLE_BLE_SM +/** + * @brief Passes the IO data from an application to the Security Manager during the pairing + * process. + * + * It should be used after a pairing method has been established for given connection + * and once the appropriate key generation information (e.g. passkey) has been obtained. + * + * @param conn_handle The connection handle of the relevant connection. + * @param pkey A pointer to the structure where IO data is stored. + * + * @return 0 on success; + * Non-zero on failure. + */ int ble_sm_inject_io(uint16_t conn_handle, struct ble_sm_io *pkey); #else +/** This macro replaces the function to return BLE_HS_ENOTSUP when SM is disabled. */ #define ble_sm_inject_io(conn_handle, pkey) \ ((void)(conn_handle), BLE_HS_ENOTSUP) #endif @@ -142,4 +353,8 @@ int ble_sm_inject_io(uint16_t conn_handle, struct ble_sm_io *pkey); } #endif -#endif +/** + * @} + */ + +#endif /* H_BLE_SM_ */ From e33099a190739b8df6689f808d4053fc51b37c1c Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 12 Mar 2024 17:17:17 +0100 Subject: [PATCH 0943/1333] nimble/host: Fix possible deadlock in ble_att_tx If ble_hs_misc_conn_chan_find_reqd() failed function would exit with HS lock locked. --- nimble/host/src/ble_att_cmd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/host/src/ble_att_cmd.c b/nimble/host/src/ble_att_cmd.c index 4106cd0609..4760ff60da 100644 --- a/nimble/host/src/ble_att_cmd.c +++ b/nimble/host/src/ble_att_cmd.c @@ -114,6 +114,7 @@ ble_att_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom) rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT, &conn, &chan); if (rc != 0) { + ble_hs_unlock(); os_mbuf_free_chain(txom); return rc; } From 1c91062dbcf47ec7b746b2c478affd447493c12f Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Tue, 27 Feb 2024 16:05:33 +0100 Subject: [PATCH 0944/1333] ci: Add Doxygen Check workflow This commit adds a new workflow for Doxygen Check to ensure documentation integrity. The workflow verifies if the Doxygen output contains any warnings. --- .github/check_doxygen.py | 115 +++++++++++++++++++++++++ .github/workflows/compliance_check.yml | 19 +++- .rat-excludes | 1 + Doxyfile | 7 ++ 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100755 .github/check_doxygen.py create mode 100644 Doxyfile diff --git a/.github/check_doxygen.py b/.github/check_doxygen.py new file mode 100755 index 0000000000..0f47a10bc0 --- /dev/null +++ b/.github/check_doxygen.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 + +# +# 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. +# + +import os +import re +import subprocess +import sys +from pathlib import Path + +TMP_FOLDER = "/tmp/doxygen_check" +WARN_FILE_NAME = "warnings.log" +allowed_files = [ + "nimble/include/nimble/ble.h", +] + + +def run_cmd(cmd: str) -> list[str]: + out = subprocess.check_output(cmd, text=True, shell=True) + return out.splitlines() + + +def run_cmd_no_check(cmd: str) -> list[str]: + out = subprocess.run(cmd, text=True, shell=True, stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL).stdout + return out.splitlines() + + +def is_ignored(filename: str, allowed: list[str]) -> bool: + if Path(filename).suffix != ".h" or "priv" in filename: + return True + if filename in allowed: + return False + if re.search(r"nimble/host.*include.*", filename): + return False + + return True + + +def main() -> bool: + if len(sys.argv) > 1: + commit = sys.argv[1] + else: + commit = "HEAD" + if len(sys.argv) > 2: + upstream = sys.argv[2] + else: + upstream = "origin/master" + + mb = run_cmd(f"git merge-base {upstream} {commit}") + upstream = mb[0] + + results_ok = [] + results_fail = [] + results_ign = [] + + os.makedirs(Path(TMP_FOLDER, WARN_FILE_NAME).parent, mode=0o755, + exist_ok=True) + + files = run_cmd(f"git diff --diff-filter=AM --name-only {upstream} {commit}") + for fname in files: + if is_ignored(fname, allowed_files): + results_ign.append(fname) + continue + + os.environ['DOXYGEN_INPUT'] = fname + try: + run_cmd_no_check("doxygen") + + except subprocess.CalledProcessError as e: + print(f"\033[31m[FAIL] {e.returncode}\033[0m") + return False + + with open(os.path.join(TMP_FOLDER, WARN_FILE_NAME)) as warn_log: + warnings = warn_log.read() + if len(warnings) == 0: + results_ok.append(fname) + else: + results_fail.append((fname, warnings)) + + for fname in results_ign: + print(f"\033[90m[ NA ] {fname}\033[0m") + for fname in results_ok: + print(f"\033[32m[ OK ] {fname}\033[0m") + for fname, warnings in results_fail: + print(f"\033[31m[FAIL] {fname}\033[0m") + print(warnings) + + if len(results_fail) > 0: + print(f"\033[31mYour code has documentation style problems, see the logs " + f"for details.\033[0m") + + return len(results_fail) == 0 + + +if __name__ == "__main__": + if not main(): + sys.exit(1) diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index 9b2ee76315..ade32b220a 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -56,7 +56,24 @@ jobs: wget https://dlcdn.apache.org//creadur/apache-rat-0.16.1/apache-rat-0.16.1-bin.tar.gz tar zxf apache-rat-0.16.1-bin.tar.gz apache-rat-0.16.1/apache-rat-0.16.1.jar mv apache-rat-0.16.1/apache-rat-0.16.1.jar apache-rat.jar - - name: check licensing + - name: Check licensing shell: bash run: | ./repos/apache-mynewt-core/.github/check_license.py + + style_doxygen: + name: Doxygen Style + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Install Dependencies + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y doxygen + - name: Check Doxygen + shell: bash + run: | + .github/check_doxygen.py diff --git a/.rat-excludes b/.rat-excludes index f29a97eb1d..b0bf3e0977 100644 --- a/.rat-excludes +++ b/.rat-excludes @@ -18,6 +18,7 @@ uncrustify.cfg .style_ignored_dirs .mailmap requirements.txt +Doxyfile # tinycrypt - BSD License. tinycrypt diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000000..35909d5383 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,7 @@ +WARN_NO_PARAMDOC = YES +WARN_LOGFILE = /tmp/doxygen_check/warnings.log +INPUT = $(DOXYGEN_INPUT) +GENERATE_HTML = NO +GENERATE_LATEX = NO +MACRO_EXPANSION = YES +WARN_FORMAT = $line: $text From 10c2ae801809c08d6b0677c06712d7aad9b03ec0 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 12 Mar 2024 14:19:48 +0100 Subject: [PATCH 0945/1333] nimble/eatt: Fix NULL deref in ble_eatt_alloc If ble_eatt_conn_pool was empty we would end up in writing NULL address. --- nimble/host/src/ble_eatt.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c index de1c0d7153..f9f7d924f9 100644 --- a/nimble/host/src/ble_eatt.c +++ b/nimble/host/src/ble_eatt.c @@ -177,10 +177,13 @@ ble_eatt_alloc(void) struct ble_eatt *eatt; eatt = os_memblock_get(&ble_eatt_conn_pool); - if (eatt) { - SLIST_INSERT_HEAD(&g_ble_eatt_list, eatt, next); + if (!eatt) { + BLE_EATT_LOG_WARN("eatt: Failed to allocate new eatt context\n"); + return NULL; } + SLIST_INSERT_HEAD(&g_ble_eatt_list, eatt, next); + eatt->conn_handle = BLE_HS_CONN_HANDLE_NONE; eatt->chan = NULL; eatt->client_op = 0; From 826682d3ce20224830f22e75e1fb4bb0fa1ca4fc Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 12 Mar 2024 14:20:27 +0100 Subject: [PATCH 0946/1333] nimble/hs: Make ble_eatt_start static and void It is not used outside of ble_eatt.c --- nimble/host/src/ble_eatt.c | 10 ++++------ nimble/host/src/ble_eatt_priv.h | 7 ------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c index f9f7d924f9..9fad2a862e 100644 --- a/nimble/host/src/ble_eatt.c +++ b/nimble/host/src/ble_eatt.c @@ -76,6 +76,7 @@ static struct ble_npl_event g_read_sup_cl_feat_ev; static struct ble_npl_event g_read_sup_srv_feat_ev; static void ble_eatt_setup_cb(struct ble_npl_event *ev); +static void ble_eatt_start(uint16_t conn_handle); static struct ble_eatt * ble_eatt_find_not_busy(uint16_t conn_handle) @@ -520,7 +521,7 @@ ble_eatt_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom) return rc; } -int +static void ble_eatt_start(uint16_t conn_handle) { struct ble_gap_conn_desc desc; @@ -533,21 +534,18 @@ ble_eatt_start(uint16_t conn_handle) /* Let master to create ecoc. * TODO: Slave could setup after some timeout */ - return 0; + return; } eatt = ble_eatt_alloc(); if (!eatt) { - BLE_EATT_LOG_ERROR("eatt: no available eatt resources\n"); - return 0; + return; } eatt->conn_handle = conn_handle; /* Setup EATT */ ble_npl_eventq_put(ble_hs_evq_get(), &eatt->setup_ev); - - return 0; } void diff --git a/nimble/host/src/ble_eatt_priv.h b/nimble/host/src/ble_eatt_priv.h index d5d01bd0ee..d3c9877672 100644 --- a/nimble/host/src/ble_eatt_priv.h +++ b/nimble/host/src/ble_eatt_priv.h @@ -36,7 +36,6 @@ void ble_eatt_init(ble_eatt_att_rx_fn att_rx_fn); uint16_t ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op); void ble_eatt_release_chan(uint16_t conn_handle, uint8_t op); int ble_eatt_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom); -int ble_eatt_start(uint16_t conn_handle); #else static inline void ble_eatt_init(ble_eatt_att_rx_fn att_rx_fn) @@ -54,11 +53,5 @@ ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op) { return BLE_L2CAP_CID_ATT; } - -static inline int -ble_eatt_start(uint16_t conn_handle) -{ - return 0; -} #endif #endif From b74b97fd7da4aa308f8da48b45e11c2dda86731c Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 12 Mar 2024 14:57:04 +0100 Subject: [PATCH 0947/1333] nimble/eatt: Fix no resource handling on accept Return error code instead of asserting on low resources. --- nimble/host/src/ble_eatt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c index 9fad2a862e..721c94608d 100644 --- a/nimble/host/src/ble_eatt.c +++ b/nimble/host/src/ble_eatt.c @@ -244,15 +244,17 @@ ble_eatt_l2cap_event_fn(struct ble_l2cap_event *event, void *arg) if (!eatt) { return BLE_HS_ENOMEM; } + eatt->conn_handle = event->accept.conn_handle; event->accept.chan->cb_arg = eatt; rc = ble_eatt_prepare_rx_sdu(event->accept.chan); if (rc) { ble_eatt_free(eatt); + return rc; } - assert(rc == 0); - return 0; + + break; case BLE_L2CAP_EVENT_COC_TX_UNSTALLED: ble_npl_eventq_put(ble_hs_evq_get(), &eatt->wakeup_ev); break; From 3d6bfda185a6574c19652a3ab0ca998abdfaa85f Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 15 Mar 2024 09:01:19 +0100 Subject: [PATCH 0948/1333] nimble/host: Fix EATT restrictions in syscfg EATT requires Enhanced COC and number of available channels should be at least that of supported EATT channels. --- nimble/host/syscfg.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index 2848b648d1..69db7dfd35 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -310,18 +310,22 @@ syscfg.defs: due to memory exhaustion. (0/1) Units are milliseconds. (0/1) value: 1000 - # Supported server ATT commands. (0/1) + # Enhanced ATT bearer options BLE_EATT_CHAN_NUM: description: > - Number of CoC channels allocated to EATT + Maximum number of supported EATT channels (in total). If set to 0 + EATT support it disabled. value: 0 - restrictions: BLE_GATT_NOTIFY_MULTIPLE - + restrictions: + - BLE_GATT_NOTIFY_MULTIPLE + - BLE_L2CAP_ENHANCED_COC + - 'BLE_L2CAP_COC_MAX_NUM >= BLE_EATT_CHAN_NUM' BLE_EATT_MTU: description: > MTU used for EATT channels. value: 128 + # Supported server ATT commands. (0/1) BLE_ATT_SVR_FIND_INFO: description: > Enables processing of incoming Find Information Request ATT From a41b4570d6f22636ec65bbb94907bf5861765673 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 15 Mar 2024 10:44:50 +0100 Subject: [PATCH 0949/1333] nimble/host: Fix possible memory leak in ble_eatt_prepare_rx_sdu ble_l2cap_recv_ready consumes om buffer only on success. --- nimble/host/src/ble_eatt.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c index 721c94608d..2ef62a80ab 100644 --- a/nimble/host/src/ble_eatt.c +++ b/nimble/host/src/ble_eatt.c @@ -148,6 +148,12 @@ ble_eatt_prepare_rx_sdu(struct ble_l2cap_chan *chan) } rc = ble_l2cap_recv_ready(chan, om); + if (rc) { + BLE_EATT_LOG_ERROR("eatt: Failed to supply RX SDU conn_handle 0x%04x (status=%d)\n", + chan->conn_handle, rc); + os_mbuf_free_chain(om); + } + return rc; } From a6e47b687bf316a2bfd456a455ca904a9903884d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 15 Mar 2024 10:45:45 +0100 Subject: [PATCH 0950/1333] nimble/host: Fix leak on EATT connection If EATT COC connection failed we need to clean up allocated memory. --- nimble/host/src/ble_eatt.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c index 2ef62a80ab..93ff0f5d45 100644 --- a/nimble/host/src/ble_eatt.c +++ b/nimble/host/src/ble_eatt.c @@ -320,6 +320,7 @@ ble_eatt_setup_cb(struct ble_npl_event *ev) { struct ble_eatt *eatt; struct os_mbuf *om; + int rc; eatt = ble_npl_event_get_arg(ev); assert(eatt); @@ -332,8 +333,16 @@ ble_eatt_setup_cb(struct ble_npl_event *ev) } BLE_EATT_LOG_DEBUG("eatt: connecting eatt on conn_handle 0x%04x\n", eatt->conn_handle); - ble_l2cap_enhanced_connect(eatt->conn_handle, BLE_EATT_PSM, - MYNEWT_VAL(BLE_EATT_MTU), 1, &om, ble_eatt_l2cap_event_fn, eatt); + + rc = ble_l2cap_enhanced_connect(eatt->conn_handle, BLE_EATT_PSM, + MYNEWT_VAL(BLE_EATT_MTU), 1, &om, + ble_eatt_l2cap_event_fn, eatt); + if (rc) { + BLE_EATT_LOG_ERROR("eatt: Failed to connect EATT on conn_handle 0x%04x (status=%d)\n", + eatt->conn_handle, rc); + os_mbuf_free_chain(om); + ble_eatt_free(eatt); + } } static int From 6f8f2572e3d4101f5abae4a05a820e0672994de5 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 20 Mar 2024 13:25:25 +0100 Subject: [PATCH 0951/1333] nimble/host: Connect EATT when encryption is enabled Some peers reject connection to EATT PSM if encryption is not enabled. Since EATT requires any PDUs to be sent only on encrypted link we can postpone initiating EATT connection until encryption with no real drawbacks. --- nimble/host/src/ble_eatt.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c index 93ff0f5d45..21732b0910 100644 --- a/nimble/host/src/ble_eatt.c +++ b/nimble/host/src/ble_eatt.c @@ -450,15 +450,20 @@ ble_eatt_gap_event(struct ble_gap_event *event, void *arg) struct ble_eatt *eatt; switch (event->type) { - case BLE_GAP_EVENT_CONNECT: - if (event->connect.status != 0) { + case BLE_GAP_EVENT_ENC_CHANGE: + if (event->enc_change.status != 0) { return 0; } - BLE_EATT_LOG_DEBUG("eatt: Device connected, waiting to write into " - "client supported features\n"); + /* don't try to connect if already connected */ + if (ble_eatt_find_by_conn_handle(event->enc_change.conn_handle)) { + return 0; + } + + BLE_EATT_LOG_DEBUG("eatt: Encryption enabled, connecting EATT (conn_handle=0x%04x)\n", + event->enc_change.conn_handle); - ble_npl_event_set_arg(&g_read_sup_srv_feat_ev, UINT_TO_POINTER(event->connect.conn_handle)); + ble_npl_event_set_arg(&g_read_sup_srv_feat_ev, UINT_TO_POINTER(event->enc_change.conn_handle)); ble_npl_eventq_put(ble_hs_evq_get(), &g_read_sup_srv_feat_ev); break; From f12fbcdb19a8ca29b15ec3b939ce2f522be03428 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Thu, 21 Mar 2024 09:22:08 +0100 Subject: [PATCH 0952/1333] apps/bttester: change device name max len in syscfg This is needed for upper tester, test case GATT/SR/GAW/BI-32-C Signed-off-by: Piotr Narajowski --- apps/bttester/syscfg.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 68a60f6a24..83eea8cef6 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -116,6 +116,7 @@ syscfg.vals: BLE_SVC_GAP_PPCP_SUPERVISION_TMO: 2000 BLE_SVC_GAP_APPEARANCE_WRITE_PERM: 0 BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM: 0 + BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH: 6 BLE_STORE_CONFIG_PERSIST: 0 BLE_MESH: 1 From 074710e667369cfde0c855246f588c3c50c36af6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 20 Mar 2024 02:19:12 +0100 Subject: [PATCH 0953/1333] nimble/ll: Reschedule preempted adv event if possible Currently we simply drop adv event if it was preempted, but instead we can try to reschedule it as longs as new start time does not exceed adv_delay limit. Note that we only reschedule if no PDU was sent in that event, otherwise we could not guarantee that aux is properly scheduled relative to exts. --- .../include/controller/ble_ll_adv.h | 2 +- nimble/controller/src/ble_ll_adv.c | 61 ++++++++++++------- nimble/controller/src/ble_ll_sched.c | 6 +- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_adv.h b/nimble/controller/include/controller/ble_ll_adv.h index b861d19dba..db35209dc1 100644 --- a/nimble/controller/include/controller/ble_ll_adv.h +++ b/nimble/controller/include/controller/ble_ll_adv.h @@ -168,7 +168,7 @@ int ble_ll_adv_can_chg_whitelist(void); * Called when an advertising event has been removed from the scheduler * without being run. */ -void ble_ll_adv_event_rmvd_from_sched(struct ble_ll_adv_sm *advsm); +void ble_ll_adv_preempted(struct ble_ll_adv_sm *advsm); /* * Called when a periodic event has been removed from the scheduler diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 52606f93e6..8dc4444775 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -110,6 +110,7 @@ struct ble_ll_adv_sm uint8_t own_addr_type; uint8_t peer_addr_type; uint8_t adv_chan; + uint8_t retry_event; uint8_t adv_pdu_len; int8_t adv_rpa_index; int8_t tx_power; @@ -227,7 +228,7 @@ struct ble_ll_adv_sm struct ble_ll_adv_sm g_ble_ll_adv_sm[BLE_ADV_INSTANCES]; struct ble_ll_adv_sm *g_ble_ll_cur_adv_sm; -static void ble_ll_adv_drop_event(struct ble_ll_adv_sm *advsm); +static void ble_ll_adv_drop_event(struct ble_ll_adv_sm *advsm, bool preempted); static struct ble_ll_adv_sm * ble_ll_adv_sm_find_configured(uint8_t instance) @@ -1068,14 +1069,10 @@ ble_ll_adv_tx_done(void *arg) g_ble_ll_cur_adv_sm = NULL; } -/* - * Called when an advertising event has been removed from the scheduler - * without being run. - */ void -ble_ll_adv_event_rmvd_from_sched(struct ble_ll_adv_sm *advsm) +ble_ll_adv_preempted(struct ble_ll_adv_sm *advsm) { - ble_ll_adv_drop_event(advsm); + ble_ll_adv_drop_event(advsm, 1); } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) @@ -4742,8 +4739,10 @@ ble_ll_adv_rx_isr_start(uint8_t pdu_type) } static void -ble_ll_adv_drop_event(struct ble_ll_adv_sm *advsm) +ble_ll_adv_drop_event(struct ble_ll_adv_sm *advsm, bool preempted) { + os_sr_t sr; + STATS_INC(ble_ll_stats, adv_drop_event); ble_ll_sched_rmv_elem(&advsm->adv_sch); @@ -4755,6 +4754,12 @@ ble_ll_adv_drop_event(struct ble_ll_adv_sm *advsm) advsm->aux_active = 0; #endif + if (preempted) { + OS_ENTER_CRITICAL(sr); + advsm->retry_event = !(advsm->flags & BLE_LL_ADV_SM_FLAG_ACTIVE_CHANSET_MASK); + OS_EXIT_CRITICAL(sr); + } + advsm->adv_chan = ble_ll_adv_final_chan(advsm); ble_ll_event_add(&advsm->adv_txdone_ev); } @@ -4779,7 +4784,7 @@ ble_ll_adv_reschedule_event(struct ble_ll_adv_sm *advsm) rc = ble_ll_sched_adv_reschedule(sch, max_delay_ticks); if (rc) { - ble_ll_adv_drop_event(advsm); + ble_ll_adv_drop_event(advsm, 0); return; } @@ -4845,25 +4850,35 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) final_adv_chan = ble_ll_adv_final_chan(advsm); if (advsm->adv_chan == final_adv_chan) { -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - if (advsm->events_max) { - advsm->events++; - } -#endif - ble_ll_scan_chk_resume(); /* This event is over. Set adv channel to first one */ advsm->adv_chan = ble_ll_adv_first_chan(advsm); - /* - * Calculate start time of next advertising event. NOTE: we do not - * add the random advDelay as the scheduling code will do that. - */ itvl = advsm->adv_itvl_usecs; tick_itvl = ble_ll_tmr_u2t(itvl); - advsm->adv_event_start_time += tick_itvl; - advsm->adv_pdu_start_time = advsm->adv_event_start_time; + + /* do not calculate new event time if current event should be retried; + * this happens if event was preempted, so we just try to schedule one + * more time with the same start time + */ + + if (!advsm->retry_event) { +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + if (advsm->events_max) { + advsm->events++; + } +#endif + + /* + * Calculate start time of next advertising event. NOTE: we do not + * add the random advDelay as the scheduling code will do that. + */ + advsm->adv_event_start_time += tick_itvl; + advsm->adv_pdu_start_time = advsm->adv_event_start_time; + } else { + advsm->retry_event = 0; + } /* * The scheduled time better be in the future! If it is not, we will @@ -4909,7 +4924,7 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm) advsm->aux_active && LL_TMR_GT(advsm->adv_pdu_start_time, AUX_CURRENT(advsm)->start_time)) { - ble_ll_adv_drop_event(advsm); + ble_ll_adv_drop_event(advsm, 0); return; } #endif @@ -5009,7 +5024,7 @@ ble_ll_adv_sec_done(struct ble_ll_adv_sm *advsm) ble_ll_rfmgmt_release(); if (advsm->aux_dropped) { - ble_ll_adv_drop_event(advsm); + ble_ll_adv_drop_event(advsm, 0); return; } diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index bfec620d01..f2987dfdf0 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -151,9 +151,9 @@ ble_ll_sched_preempt(struct ble_ll_sched_item *sch, break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) - case BLE_LL_SCHED_TYPE_ADV: - ble_ll_adv_event_rmvd_from_sched(entry->cb_arg); - break; + case BLE_LL_SCHED_TYPE_ADV: + ble_ll_adv_preempted(entry->cb_arg); + break; #endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER) case BLE_LL_SCHED_TYPE_SCAN_AUX: From 6d5fe383efc6ebbe8f6b93fc5d6d9c6e6d9c1158 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 20 Mar 2024 17:34:22 +0100 Subject: [PATCH 0954/1333] nimble/ll: Remove periodic adv min/max interval in sm We only need current interval, no need to store min and max (and min was never used anyway). --- nimble/controller/src/ble_ll_adv.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 8dc4444775..0ce13a6da8 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -159,8 +159,6 @@ struct ble_ll_adv_sm struct os_mbuf *periodic_new_data; uint32_t periodic_crcinit; /* only 3 bytes are used */ uint32_t periodic_access_addr; - uint16_t periodic_adv_itvl_min; - uint16_t periodic_adv_itvl_max; uint16_t periodic_adv_props; uint16_t periodic_channel_id; uint16_t periodic_event_cntr; @@ -171,8 +169,9 @@ struct ble_ll_adv_sm uint8_t periodic_sync_index : 1; uint8_t periodic_num_used_chans; uint8_t periodic_chanmap[BLE_LL_CHAN_MAP_LEN]; + uint16_t periodic_adv_itvl; uint32_t periodic_adv_itvl_ticks; - uint8_t periodic_adv_itvl_rem_usec; + uint8_t periodic_adv_itvl_rem_us; uint8_t periodic_adv_event_start_time_remainder; uint32_t periodic_adv_event_start_time; struct ble_ll_adv_sync periodic_sync[2]; @@ -665,7 +664,7 @@ ble_ll_adv_put_syncinfo(struct ble_ll_adv_sm *advsm, offset = ble_ll_tmr_t2u(anchor - AUX_CURRENT(advsm)->start_time); offset += advsm->periodic_adv_event_start_time_remainder; - offset += advsm->periodic_adv_itvl_rem_usec; + offset += advsm->periodic_adv_itvl_rem_us; } /* Sync Packet Offset (13 bits), Offset Units (1 bit), Offset Adjust (1 bit), @@ -696,7 +695,7 @@ ble_ll_adv_put_syncinfo(struct ble_ll_adv_sm *advsm, dptr[1] = ((offset >> 8) & 0x0000001f) | units; /* Interval (2 bytes) */ - put_le16(&dptr[2], advsm->periodic_adv_itvl_max); + put_le16(&dptr[2], advsm->periodic_adv_itvl); /* Channels Mask (37 bits) */ dptr[4] = advsm->periodic_chanmap[0]; @@ -2432,7 +2431,7 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm, ble_ll_tmr_add_u(&advsm->periodic_adv_event_start_time, &advsm->periodic_adv_event_start_time_remainder, - advsm->periodic_adv_itvl_rem_usec); + advsm->periodic_adv_itvl_rem_us); sch->start_time = advsm->periodic_adv_event_start_time; sch->remainder = advsm->periodic_adv_event_start_time_remainder; @@ -2658,10 +2657,9 @@ ble_ll_adv_sm_start_periodic(struct ble_ll_adv_sm *advsm) (advsm->periodic_access_addr & 0x0000ffff); advsm->periodic_crcinit = ble_ll_rand() & 0xffffff; - usecs = (uint32_t)advsm->periodic_adv_itvl_max * BLE_LL_ADV_PERIODIC_ITVL; - + usecs = (uint32_t)advsm->periodic_adv_itvl * BLE_LL_ADV_PERIODIC_ITVL; advsm->periodic_adv_itvl_ticks = ble_ll_tmr_u2t_r(usecs, - &advsm->periodic_adv_itvl_rem_usec); + &advsm->periodic_adv_itvl_rem_us); /* There is no point in starting periodic advertising until next advertising * event since SyncInfo is needed for synchronization @@ -3975,8 +3973,7 @@ ble_ll_adv_periodic_set_param(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_PACKET_TOO_LONG; } - advsm->periodic_adv_itvl_min = adv_itvl_min; - advsm->periodic_adv_itvl_max = adv_itvl_max; + advsm->periodic_adv_itvl = adv_itvl_max; advsm->periodic_adv_props = props; ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_CONFIGURED); @@ -4056,7 +4053,7 @@ ble_ll_adv_periodic_set_data(const uint8_t *cmdbuf, uint8_t len) */ if (!ble_ll_adv_periodic_check_data_itvl(payload_total_len, advsm->periodic_adv_props, - advsm->periodic_adv_itvl_max, + advsm->periodic_adv_itvl, advsm->sec_phy)) { return BLE_ERR_PACKET_TOO_LONG; } @@ -4149,7 +4146,7 @@ ble_ll_adv_periodic_enable(const uint8_t *cmdbuf, uint8_t len) */ if (!ble_ll_adv_periodic_check_data_itvl(SYNC_DATA_LEN(advsm), advsm->periodic_adv_props, - advsm->periodic_adv_itvl_max, + advsm->periodic_adv_itvl, advsm->sec_phy)) { return BLE_ERR_PACKET_TOO_LONG; } From 55045567920eb9da57b7788d9b0010ea614a6c97 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 20 Mar 2024 17:35:01 +0100 Subject: [PATCH 0955/1333] nimble/ll: Fix sync packet offset in syncinfo We need to move periodic advertising event start time by full interval (not only ticks) as otherwise any calculation of start time in the future event will not be accurate. --- nimble/controller/src/ble_ll_adv.c | 31 ++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 0ce13a6da8..f194ec21c9 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -623,48 +623,51 @@ ble_ll_adv_put_syncinfo(struct ble_ll_adv_sm *advsm, uint8_t *dptr) { #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) - uint8_t anchor_usecs; uint16_t conn_cnt; #endif unsigned int event_cnt_off = 0; uint32_t offset = 0; - uint32_t anchor; + uint32_t itvl_us; + uint32_t anchor_ticks; + uint8_t anchor_rem_us; uint8_t units; if (connsm) { #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) - anchor = connsm->anchor_point; - anchor_usecs = connsm->anchor_point_usecs; + anchor_ticks = connsm->anchor_point; + anchor_rem_us = connsm->anchor_point_usecs; conn_cnt = connsm->event_cntr; /* get anchor for conn event that is before periodic_adv_event_start_time */ - while (LL_TMR_GT(anchor, advsm->periodic_adv_event_start_time)) { - ble_ll_conn_get_anchor(connsm, --conn_cnt, &anchor, &anchor_usecs); + while (LL_TMR_GT(anchor_ticks, advsm->periodic_adv_event_start_time)) { + ble_ll_conn_get_anchor(connsm, --conn_cnt, &anchor_ticks, &anchor_rem_us); } - offset = ble_ll_tmr_t2u(advsm->periodic_adv_event_start_time - anchor); - offset -= anchor_usecs; + offset = ble_ll_tmr_t2u(advsm->periodic_adv_event_start_time - anchor_ticks); + offset -= anchor_rem_us; offset += advsm->periodic_adv_event_start_time_remainder; /* connEventCount */ put_le16(conn_event_cnt, conn_cnt); #endif } else { - anchor = advsm->periodic_adv_event_start_time; + anchor_ticks = advsm->periodic_adv_event_start_time; + anchor_rem_us = advsm->periodic_adv_event_start_time_remainder; + itvl_us = advsm->periodic_adv_itvl * BLE_LL_ADV_PERIODIC_ITVL; /* Get periodic event that is past AUX start time (so that we always * provide valid offset if it is not too far in future). This can * happen if advertising event is interleaved with periodic advertising * event (when chaining). */ - while (LL_TMR_GT(AUX_CURRENT(advsm)->start_time, anchor)) { - anchor += advsm->periodic_adv_itvl_ticks; + while (LL_TMR_GEQ(AUX_CURRENT(advsm)->start_time, anchor_ticks)) { + ble_ll_tmr_add(&anchor_ticks, &anchor_rem_us, itvl_us); event_cnt_off++; } - offset = ble_ll_tmr_t2u(anchor - AUX_CURRENT(advsm)->start_time); - offset += advsm->periodic_adv_event_start_time_remainder; - offset += advsm->periodic_adv_itvl_rem_us; + /* We always schedule aux with 0 rem_us so no need to include it here */ + offset = ble_ll_tmr_t2u(anchor_ticks - AUX_CURRENT(advsm)->start_time); + offset += anchor_rem_us; } /* Sync Packet Offset (13 bits), Offset Units (1 bit), Offset Adjust (1 bit), From 3aa35d7a3f0bbec68901c88d40487950b59fae81 Mon Sep 17 00:00:00 2001 From: sc Date: Wed, 6 Mar 2024 16:36:10 +0100 Subject: [PATCH 0956/1333] apps/bttester: Add support for BAP autopts tests This commit introduces environment for BAP testing with autopts. --- apps/bttester/src/btp/btp.h | 4 +- apps/bttester/src/btp/btp_bap.h | 114 +++++++++ apps/bttester/src/btp/bttester.h | 11 +- apps/bttester/src/btp_bap.c | 426 +++++++++++++++++++++++++++++++ apps/bttester/src/btp_core.c | 10 + apps/bttester/syscfg.yml | 23 +- 6 files changed, 582 insertions(+), 6 deletions(-) create mode 100644 apps/bttester/src/btp/btp_bap.h create mode 100644 apps/bttester/src/btp_bap.c diff --git a/apps/bttester/src/btp/btp.h b/apps/bttester/src/btp/btp.h index 5e1a172e9f..4403a16038 100644 --- a/apps/bttester/src/btp/btp.h +++ b/apps/bttester/src/btp/btp.h @@ -33,6 +33,7 @@ #include "btp_gattc.h" #include "btp_l2cap.h" #include "btp_mesh.h" +#include "btp_bap.h" #define BTP_MTU MYNEWT_VAL(BTTESTER_BTP_DATA_SIZE_MAX) #define BTP_DATA_MAX_SIZE (BTP_MTU - sizeof(struct btp_hdr)) @@ -46,8 +47,9 @@ #define BTP_SERVICE_ID_L2CAP 3 #define BTP_SERVICE_ID_MESH 4 #define BTP_SERVICE_ID_GATTC 6 +#define BTP_SERVICE_ID_BAP 14 -#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_GATTC +#define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_BAP #define BTP_STATUS_SUCCESS 0x00 #define BTP_STATUS_FAILED 0x01 diff --git a/apps/bttester/src/btp/btp_bap.h b/apps/bttester/src/btp/btp_bap.h new file mode 100644 index 0000000000..f25ab14748 --- /dev/null +++ b/apps/bttester/src/btp/btp_bap.h @@ -0,0 +1,114 @@ +/* + * 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_BTP_BAP_ +#define H_BTP_BAP_ + +#include "nimble/ble.h" +#include + +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif + +/* BAP Service */ +/* commands */ +#define BTP_BAP_READ_SUPPORTED_COMMANDS 0x01 +struct btp_bap_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define BTP_BAP_DISCOVER 0x02 +#define BTP_BAP_SEND 0x03 +#define BTP_BAP_BROADCAST_SOURCE_SETUP 0x04 +struct bap_broadcast_source_setup_cmd { + uint8_t streams_per_subgroup; + uint8_t subgroups; + uint8_t sdu_interval[3]; + uint8_t framing; + uint16_t max_sdu; + uint8_t rtn; + uint16_t max_transport_lat; + uint8_t presentation_delay[3]; + uint8_t coding_fmt; + uint16_t vid; + uint16_t cid; + uint8_t cc_ltvs_len; + uint8_t cc_ltvs[]; +} __packed; + +struct bap_broadcast_source_setup_rp { + uint32_t gap_settings; + uint8_t broadcast_id[3]; +} __packed; + +#define BTP_BAP_BROADCAST_SOURCE_RELEASE 0x05 +struct bap_bap_broadcast_source_release_cmd { + uint8_t broadcast_id[3]; +} __packed; + +#define BTP_BAP_BROADCAST_ADV_START 0x06 +struct bap_bap_broadcast_adv_start_cmd { + uint8_t broadcast_id[3]; +} __packed; + +#define BTP_BAP_BROADCAST_ADV_STOP 0x07 +struct bap_bap_broadcast_adv_stop_cmd { + uint8_t broadcast_id[3]; +} __packed; + +#define BTP_BAP_BROADCAST_SOURCE_START 0x08 +struct bap_bap_broadcast_source_start_cmd { + uint8_t broadcast_id[3]; +} __packed; + +#define BTP_BAP_BROADCAST_SOURCE_STOP 0x09 +struct bap_bap_broadcast_source_stop_cmd { + uint8_t broadcast_id[3]; +} __packed; + +#define BTP_BAP_BROADCAST_SINK_SETUP 0x0a +#define BTP_BAP_BROADCAST_SINK_RELEASE 0x0b +#define BTP_BAP_BROADCAST_SCAN_START 0x0c +#define BTP_BAP_BROADCAST_SCAN_STOP 0x0d +#define BTP_BAP_BROADCAST_SINK_SYNC 0x0e +#define BTP_BAP_BROADCAST_SINK_STOP 0x0f +#define BTP_BAP_BROADCAST_SINK_BIS_SYNC 0x10 +#define BTP_BAP_DISCOVER_SCAN_DELEGATOR 0x11 +#define BTP_BAP_BROADCAST_ASSISTANT_SCAN_START 0x12 +#define BTP_BAP_BROADCAST_ASSISTANT_SCAN_STOP 0x13 +#define BTP_BAP_ADD_BROADCAST_SRC 0x14 +#define BTP_BAP_REMOVE_BROADCAST_SRC 0x15 +#define BTP_BAP_MODIFY_BROADCAST_SRC 0x16 +#define BTP_BAP_SET_BROADCAST_CODE 0x17 +#define BTP_BAP_SEND_PAST 0x18 + +#define BTP_BAP_EV_DISCOVERY_COMPLETED 0x80 +#define BTP_BAP_EV_CODEC_CAP_FOUND 0x81 +#define BTP_BAP_EV_ASE_FOUND 0x82 +#define BTP_BAP_EV_STREAM_RECEIVED 0x83 +#define BTP_BAP_EV_BAA_FOUND 0x84 +#define BTP_BAP_EV_BIS_FOUND 0x85 +#define BTP_BAP_EV_BIS_SYNCED 0x86 +#define BTP_BAP_EV_BIS_STREAM_RECEIVED 0x87 +#define BTP_BAP_EV_SCAN_DELEGATOR_FOUND 0x88 +#define BTP_BAP_EV_BROADCAST_RECEIVE_STATE 0x89 +#define BTP_BAP_EV_PA_SYNC_REQ 0x8a + +#endif /* H_BTP_BAP_ */ diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h index 8e8b98b5ad..5d7e1219d2 100644 --- a/apps/bttester/src/btp/bttester.h +++ b/apps/bttester/src/btp/bttester.h @@ -141,4 +141,13 @@ gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); int gatt_svr_init(void); -#endif /* __BTTESTER_H__ */ \ No newline at end of file + +#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +uint8_t +tester_init_bap(void); +uint8_t +tester_unregister_bap(void); +#endif /* MYNEWT_VAL(BLE_ISO_BROADCASTER) */ + +#endif /* __BTTESTER_H__ */ + diff --git a/apps/bttester/src/btp_bap.c b/apps/bttester/src/btp_bap.c new file mode 100644 index 0000000000..b6a92ac623 --- /dev/null +++ b/apps/bttester/src/btp_bap.c @@ -0,0 +1,426 @@ +/* + * 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. + */ + +/* btp_bap.c - Bluetooth Basic Audio Profile Tester */ + +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(BLE_ISO_BROADCASTER) + +#include "btp/btp_bap.h" + + +#include "btp/btp.h" +#include "console/console.h" + +#include "nimble/ble.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "math.h" + +#include "audio/ble_audio_broadcast_source.h" +#include "audio/ble_audio.h" +#include "host/ble_iso.h" + +#include "bsp/bsp.h" + + +#define BROADCAST_ADV_INSTANCE 1 + +static struct ble_audio_big_subgroup big_subgroup; + +static uint8_t id_addr_type; +static uint8_t audio_data[155]; +static uint16_t max_sdu; +static uint32_t sdu_interval; + +static struct ble_audio_base tester_base; + +static os_membuf_t bis_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BISES), + sizeof(struct ble_audio_bis)) +]; +static struct os_mempool bis_pool; + +static os_membuf_t codec_spec_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BISES) * 2, 19) +]; +static struct os_mempool codec_spec_pool; + +static uint16_t bis_handles[MYNEWT_VAL(BLE_ISO_MAX_BISES)]; +/* The timer callout */ +static struct os_callout audio_broadcast_callout; + +struct ble_iso_big_params big_params; + +static int audio_data_offset; + +static void +audio_broadcast_event_cb(struct os_event *ev) +{ + assert(ev != NULL); + uint32_t ev_start_time = os_cputime_ticks_to_usecs(os_cputime_get32()); + + if (audio_data_offset + 2 * max_sdu >= sizeof(audio_data)) { + audio_data_offset = 0; + } + + uint8_t lr_payload[max_sdu * 2]; + memcpy(lr_payload, audio_data + audio_data_offset, max_sdu); + memcpy(lr_payload + max_sdu, audio_data + audio_data_offset, + max_sdu); + ble_iso_tx(bis_handles[0], (void *)(lr_payload), + max_sdu * 2); + + audio_data_offset += max_sdu; + + /** Use cputime to time BROADCAST_SDU_INTVL, as these ticks are more + * accurate than os_time ones. This assures that we do not push + * LC3 data to ISO before interval, which could lead to + * controller running out of buffers. This is only needed because + * we already have data in an array - in real world application + * we usually wait for new audio to arrive, and lose time to code it too. + */ + while (os_cputime_ticks_to_usecs(os_cputime_get32()) - ev_start_time < + (sdu_interval)); + + os_callout_reset(&audio_broadcast_callout, 0); +} + +static int +iso_event(struct ble_iso_event *event, void *arg) +{ + int i; + + switch (event->type) { + case BLE_ISO_EVENT_BIG_CREATE_COMPLETE: + console_printf("BIG created\n"); + if (event->big_created.desc.num_bis > + MYNEWT_VAL(BROADCASTER_CHAN_NUM)) { + return BLE_HS_EINVAL; + } + for (i = 0; i < MYNEWT_VAL(BROADCASTER_CHAN_NUM); i++) { + bis_handles[i] = event->big_created.desc.conn_handle[i]; + } + return 0; + case BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE: + console_printf("BIG terminated\n"); + return 0; + default: + return BLE_HS_ENOTSUP; + } +} + +static uint8_t +supported_commands(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct btp_bap_read_supported_commands_rp *rp = rsp; + + /* octet 0 */ + tester_set_bit(rp->data, BTP_BAP_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_BAP_BROADCAST_SOURCE_SETUP); + tester_set_bit(rp->data, BTP_BAP_BROADCAST_SOURCE_RELEASE); + tester_set_bit(rp->data, BTP_BAP_BROADCAST_ADV_START); + tester_set_bit(rp->data, BTP_BAP_BROADCAST_ADV_STOP); + + /* octet 1 */ + tester_set_bit(rp->data, BTP_BAP_BROADCAST_SOURCE_START); + tester_set_bit(rp->data, BTP_BAP_BROADCAST_SOURCE_STOP); + + *rsp_len = sizeof(*rp) + 2; + + return BTP_STATUS_SUCCESS; +} + +static int +base_create(const struct bap_broadcast_source_setup_cmd *cmd) +{ + struct ble_audio_bis *bis; + uint8_t sampling_freq = cmd->cc_ltvs[2]; + uint8_t frame_duration = cmd->cc_ltvs[5]; + uint16_t chan_loc = BLE_AUDIO_LOCATION_FRONT_LEFT | + BLE_AUDIO_LOCATION_FRONT_RIGHT; + + + uint8_t codec_spec_config[] = + BLE_AUDIO_BUILD_CODEC_CONFIG(sampling_freq, frame_duration, chan_loc, + max_sdu, ); + + tester_base.broadcast_id = sampling_freq; + tester_base.presentation_delay = sampling_freq * 10000; + + big_subgroup.bis_cnt = MYNEWT_VAL(BROADCASTER_CHAN_NUM); + + /** LC3 */ + big_subgroup.codec_id.format = 0x06; + + big_subgroup.codec_spec_config_len = sizeof(codec_spec_config); + + big_subgroup.codec_spec_config_len = os_memblock_get(&codec_spec_pool); + + memcpy(big_subgroup.codec_spec_config, + codec_spec_config, + sizeof(codec_spec_config)); + + bis = os_memblock_get(&bis_pool); + if (!bis) { + return BLE_HS_ENOMEM + } + + bis->codec_spec_config_len = 0; + + STAILQ_INSERT_HEAD(&big_subgroup.bises, bis, next); + STAILQ_INSERT_HEAD(&tester_base.subs, &big_subgroup, next); + + tester_base.num_subgroups++; + + return 0; +} + +static int +broadcast_destroy_fn(struct ble_audio_base *base, void *args) +{ + struct ble_audio_bis *bis; + + STAILQ_FOREACH(bis, &big_subgroup.bises, next) { + os_memblock_put(&codec_spec_pool, bis->codec_spec_config); + os_memblock_put(&bis_pool, bis); + } + + memset(&big_subgroup, 0, sizeof(big_subgroup)); + + return 0; +} + +static uint8_t +broadcast_source_setup(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + int rc; + + const struct bap_broadcast_source_setup_cmd *source_config = cmd; + max_sdu = source_config->max_sdu; + sdu_interval = get_le24(source_config->sdu_interval); + + base_create(source_config); + + struct ble_gap_periodic_adv_params periodic_params = { + .itvl_min = 30, + .itvl_max = 30, + }; + + struct ble_gap_ext_adv_params extended_params = { + .itvl_min = 50, + .itvl_max = 50, + .scannable = 0, + .connectable = 0, + .primary_phy = BLE_HCI_LE_PHY_1M, + .secondary_phy = BLE_HCI_LE_PHY_2M, + .own_addr_type = id_addr_type, + .sid = BROADCAST_ADV_INSTANCE, + }; + + big_params.sdu_interval = sdu_interval; + big_params.max_sdu = max_sdu; + big_params.max_transport_latency = 8; + big_params.rtn = source_config->rtn; + big_params.phy = BLE_HCI_LE_PHY_2M; + big_params.packing = 0; + big_params.framing = source_config->framing; + big_params.encryption = 0; + + struct ble_broadcast_create_params create_params = { + .base = &tester_base, + .extended_params = &extended_params, + .periodic_params = &periodic_params, + .name = MYNEWT_VAL(BROADCASTER_BROADCAST_NAME), + .adv_instance = BROADCAST_ADV_INSTANCE, + .big_params = &big_params, + .svc_data = NULL, + .svc_data_len = 0, + }; + + rc = ble_audio_broadcast_create(&create_params, + broadcast_destroy_fn, + NULL, + NULL); + if (rc) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +broadcast_source_release(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + int rc; + + rc = ble_audio_broadcast_destroy(BROADCAST_ADV_INSTANCE); + if (rc) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +broadcast_adv_start(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + int rc; + + rc = ble_audio_broadcast_start(BROADCAST_ADV_INSTANCE, iso_event, NULL); + if (rc) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +broadcast_adv_stop(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + int rc; + + rc = ble_audio_broadcast_stop(BROADCAST_ADV_INSTANCE); + if (rc) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +broadcast_source_start(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + int rc; + + rc = os_callout_reset(&audio_broadcast_callout, 0); + if (rc) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +broadcast_source_stop(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + os_callout_stop(&audio_broadcast_callout); + + return BTP_STATUS_SUCCESS; +} + +static const struct btp_handler handlers[] = { + { + .opcode = BTP_BAP_READ_SUPPORTED_COMMANDS, + .index = BTP_INDEX_NONE, + .expect_len = 0, + .func = supported_commands, + }, + { + .opcode = BTP_BAP_BROADCAST_SOURCE_SETUP, + .index = BTP_INDEX, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = broadcast_source_setup, + }, + { + .opcode = BTP_BAP_BROADCAST_SOURCE_RELEASE, + .index = BTP_INDEX, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = broadcast_source_release, + }, + { + .opcode = BTP_BAP_BROADCAST_ADV_START, + .index = BTP_INDEX, + .expect_len = sizeof(struct bap_bap_broadcast_adv_start_cmd), + .func = broadcast_adv_start, + }, + { + .opcode = BTP_BAP_BROADCAST_ADV_STOP, + .index = BTP_INDEX, + .expect_len = sizeof(struct bap_bap_broadcast_adv_stop_cmd), + .func = broadcast_adv_stop, + }, + { + .opcode = BTP_BAP_BROADCAST_SOURCE_START, + .index = BTP_INDEX, + .expect_len = sizeof(struct bap_bap_broadcast_source_start_cmd), + .func = broadcast_source_start, + }, + { + .opcode = BTP_BAP_BROADCAST_SOURCE_STOP, + .index = BTP_INDEX, + .expect_len = sizeof(struct bap_bap_broadcast_source_stop_cmd), + .func = broadcast_source_stop, + }, +}; + +uint8_t +tester_init_bap(void) +{ + int rc; + + /* Make sure we have proper identity address set (public preferred) */ + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* configure global address */ + rc = ble_hs_id_infer_auto(0, &id_addr_type); + assert(rc == 0); + + memset(audio_data, 36, sizeof(char)*155); + + os_callout_init(&audio_broadcast_callout, os_eventq_dflt_get(), + audio_broadcast_event_cb, NULL); + + rc = os_mempool_init(&bis_pool, MYNEWT_VAL(BLE_ISO_MAX_BISES), + sizeof(struct ble_audio_bis), bis_mem, + "bis_pool"); + if (rc) { + return BTP_STATUS_FAILED; + } + + rc = os_mempool_init(&codec_spec_pool, + MYNEWT_VAL(BLE_ISO_MAX_BISES) * 2, 19, + codec_spec_mem, "codec_spec_pool"); + if (rc) { + return BTP_STATUS_FAILED; + } + + tester_register_command_handlers(BTP_SERVICE_ID_BAP, handlers, + ARRAY_SIZE(handlers)); + + return BTP_STATUS_SUCCESS; +} + +uint8_t +tester_unregister_bap(void) +{ + return BTP_STATUS_SUCCESS; +} + +#endif /* MYNEWT_VAL(BLE_ISO_BROADCASTER) */ + diff --git a/apps/bttester/src/btp_core.c b/apps/bttester/src/btp_core.c index 5ab290d937..f7a4bc4f92 100644 --- a/apps/bttester/src/btp_core.c +++ b/apps/bttester/src/btp_core.c @@ -102,6 +102,11 @@ register_service(const void *cmd, uint16_t cmd_len, status = tester_init_mesh(); break; #endif /* MYNEWT_VAL(BLE_MESH) */ +#if MYNEWT_VAL(BLE_ISO_BROADCASTER) + case BTP_SERVICE_ID_BAP: + status = tester_init_bap(); + break; +#endif /* MYNEWT_VAL(BLE_ISO_BROADCASTER) */ case BTP_SERVICE_ID_GATTC: status = tester_init_gatt_cl(); break; @@ -154,6 +159,11 @@ unregister_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_GATTC: status = tester_unregister_gatt_cl(); break; +#if MYNEWT_VAL(BLE_ISO_BROADCASTER) + case BTP_SERVICE_ID_BAP: + status = tester_unregister_bap(); + break; +#endif /* MYNEWT_VAL(BLE_ISO_BROADCASTER) */ default: status = BTP_STATUS_FAILED; break; diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 83eea8cef6..f3352b8943 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -79,11 +79,28 @@ syscfg.defs: description: NRPA rotation timeout in seconds value: 5 + BROADCASTER_CHAN_NUM: + description: Number of channels used for broadcast + value: 1 + BROADCASTER_BROADCAST_NAME: + description: Broadcast name + value: '"test_broadcast"' + syscfg.vals: CONSOLE_IMPLEMENTATION: full LOG_IMPLEMENTATION: full STATS_IMPLEMENTATION: full + BLE_ISO: 1 + BLE_AUDIO: 1 + BLE_ROLE_BROADCASTER: 1 + BLE_ISO_MAX_BISES: 1 + BLE_ISO_MAX_BIGS: 1 + BLE_EXT_ADV: 1 + BLE_PERIODIC_ADV: 1 + BLE_ISO_BROADCAST_SOURCE: 1 + BLE_MULTI_ADV_INSTANCES: 1 + OS_MAIN_STACK_SIZE: 512 SHELL_TASK: 0 SHELL_NEWTMGR: 0 @@ -101,7 +118,7 @@ syscfg.vals: BLE_L2CAP_SIG_MAX_PROCS: 2 BLE_L2CAP_ENHANCED_COC: 1 BLE_EATT_CHAN_NUM: 5 - BLE_VERSION: 53 + BLE_VERSION: 54 # Some testcases require MPS < MTU BLE_L2CAP_COC_MPS: 100 BLE_RPA_TIMEOUT: 30 @@ -144,7 +161,5 @@ syscfg.vals: BLE_MESH_TX_SEG_MSG_COUNT: 2 BLE_MAX_CONNECTIONS: 8 - BLE_MESH_ADV_BUF_COUNT: 20 - BLE_MESH_TX_SEG_MAX: 6 - BLE_EATT_CHAN_NUM: 2 + From b1ecc2da6ab319018479095a275b55669545dfa7 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 21 Mar 2024 15:35:10 +0100 Subject: [PATCH 0957/1333] apps/bttester: Fix build with EATT enabled EATT support requires at least same number of COC channels. --- apps/bttester/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index f3352b8943..bb4d6f775f 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -114,7 +114,7 @@ syscfg.vals: RTT_NUM_BUFFERS_UP: 0 RTT_NUM_BUFFERS_DOWN: 0 - BLE_L2CAP_COC_MAX_NUM: 3 + BLE_L2CAP_COC_MAX_NUM: 5 BLE_L2CAP_SIG_MAX_PROCS: 2 BLE_L2CAP_ENHANCED_COC: 1 BLE_EATT_CHAN_NUM: 5 From 3681562cd3e7d19fcbea666be2aadf6277be3540 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 22 Mar 2024 12:20:10 +0100 Subject: [PATCH 0958/1333] apps/bttester: Fix use of extended advertising interface This shoudl allow to run GAP and GATT tests with BLE_EXT_ADV enabled. --- apps/bttester/src/btp_gap.c | 105 ++++++++++++++++++++++++++---------- 1 file changed, 76 insertions(+), 29 deletions(-) diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 79ec5152fc..d0aa7ce06e 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -264,7 +264,6 @@ controller_info(const void *cmd, uint16_t cmd_len, } #if MYNEWT_VAL(BLE_EXT_ADV) -int adv_duration = 0; static struct ble_gap_ext_adv_params adv_params = { .primary_phy = BLE_HCI_LE_PHY_1M, .secondary_phy = BLE_HCI_LE_PHY_1M, @@ -278,6 +277,8 @@ static struct ble_gap_adv_params adv_params = { }; #endif +static uint8_t ad_flags = BLE_HS_ADV_F_BREDR_UNSUP; + #if MYNEWT_VAL(BTTESTER_PRIVACY_MODE) && MYNEWT_VAL(BTTESTER_USE_NRPA) static void rotate_nrpa_cb(struct os_event *ev) { @@ -287,18 +288,29 @@ static void rotate_nrpa_cb(struct os_event *ev) int32_t remaining_time; os_time_t remaining_ticks; - if (adv_params.disc_mode == BLE_GAP_DISC_MODE_LTD) { - duration_ms = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); + if (current_settings & BIT(BTP_GAP_SETTINGS_DISCOVERABLE)) { + if (ad_flags & BLE_HS_ADV_F_DISC_LTD) { + duration_ms = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); + } } +#if MYNEWT_VAL(BLE_EXT_ADV) + ble_gap_ext_adv_stop(0); +#else ble_gap_adv_stop(); +#endif + rc = ble_hs_id_gen_rnd(1, &addr); assert(rc == 0); rc = ble_hs_id_set_rnd(addr.val); assert(rc == 0); +#if MYNEWT_VAL(BLE_EXT_ADV) + ble_gap_ext_adv_start(0, duration_ms / 10, 0); +#else ble_gap_adv_start(own_addr_type, NULL, duration_ms, - &adv_params, gap_event_cb, NULL); + &adv_params, gap_event_cb, NULL); +#endif remaining_time = os_get_uptime_usec() - advertising_start; if (remaining_time > 0) { @@ -344,13 +356,10 @@ set_connectable(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } -static uint8_t ad_flags = BLE_HS_ADV_F_BREDR_UNSUP; - static uint8_t set_discoverable(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { -#if !MYNEWT_VAL(BLE_EXT_ADV) const struct btp_gap_set_discoverable_cmd *cp = cmd; struct btp_gap_set_discoverable_rp *rp = rsp; @@ -359,19 +368,25 @@ set_discoverable(const void *cmd, uint16_t cmd_len, switch (cp->discoverable) { case BTP_GAP_NON_DISCOVERABLE: ad_flags &= ~(BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_DISC_LTD); +#if !MYNEWT_VAL(BLE_EXT_ADV) adv_params.disc_mode = BLE_GAP_DISC_MODE_NON; +#endif current_settings &= ~BIT(BTP_GAP_SETTINGS_DISCOVERABLE); break; case BTP_GAP_GENERAL_DISCOVERABLE: ad_flags &= ~BLE_HS_ADV_F_DISC_LTD; ad_flags |= BLE_HS_ADV_F_DISC_GEN; +#if !MYNEWT_VAL(BLE_EXT_ADV) adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; +#endif current_settings |= BIT(BTP_GAP_SETTINGS_DISCOVERABLE); break; case BTP_GAP_LIMITED_DISCOVERABLE: ad_flags &= ~BLE_HS_ADV_F_DISC_GEN; ad_flags |= BLE_HS_ADV_F_DISC_LTD; +#if !MYNEWT_VAL(BLE_EXT_ADV) adv_params.disc_mode = BLE_GAP_DISC_MODE_LTD; +#endif current_settings |= BIT(BTP_GAP_SETTINGS_DISCOVERABLE); break; default: @@ -383,9 +398,6 @@ set_discoverable(const void *cmd, uint16_t cmd_len, *rsp_len = sizeof(*rp); return BTP_STATUS_SUCCESS; -#else - return BTP_STATUS_FAILED; -#endif } static uint8_t @@ -438,16 +450,19 @@ start_advertising(const void *cmd, uint16_t cmd_len, { const struct btp_gap_start_advertising_cmd *cp = cmd; struct btp_gap_start_advertising_rp *rp = rsp; - int32_t duration_ms = BLE_HS_FOREVER; uint8_t buf[BLE_HS_ADV_MAX_SZ]; uint8_t buf_len = 0; uint8_t adv_len, sd_len; uint8_t addr_type; uint32_t duration; - int err; - int i; +#if MYNEWT_VAL(BLE_EXT_ADV) + struct os_mbuf *ad_buf; + int duration_ms = 0; +#else + int32_t duration_ms = BLE_HS_FOREVER; +#endif SYS_LOG_DBG(""); @@ -498,8 +513,6 @@ start_advertising(const void *cmd, uint16_t cmd_len, } #if MYNEWT_VAL(BLE_EXT_ADV) - struct os_mbuf *ad_buf; - adv_params.own_addr_type = own_addr_type; err = ble_gap_ext_adv_configure(0, &adv_params, NULL, gap_event_cb, NULL); if (err) { @@ -513,7 +526,6 @@ start_advertising(const void *cmd, uint16_t cmd_len, os_mbuf_free_chain(ad_buf); return BTP_STATUS_FAILED; } - err = ble_gap_ext_adv_set_data(0, ad_buf); #else err = ble_gap_adv_set_data(buf, buf_len); @@ -528,20 +540,28 @@ start_advertising(const void *cmd, uint16_t cmd_len, return BTP_STATUS_FAILED; } +#if MYNEWT_VAL(BLE_EXT_ADV) + ad_buf = os_msys_get_pkthdr(BLE_HS_ADV_MAX_SZ, 0); + + if (os_mbuf_append(ad_buf, buf, buf_len)) { + os_mbuf_free_chain(ad_buf); + return BTP_STATUS_FAILED; + } + err = ble_gap_ext_adv_rsp_set_data(0, ad_buf); +#else err = ble_gap_adv_rsp_set_data(buf, buf_len); +#endif if (err != 0) { SYS_LOG_ERR("Advertising failed: err %d", err); return BTP_STATUS_FAILED; } } -#if !MYNEWT_VAL(BLE_EXT_ADV) - if (adv_params.disc_mode == BLE_GAP_DISC_MODE_LTD) { - duration_ms = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); + if (current_settings & BIT(BTP_GAP_SETTINGS_DISCOVERABLE)) { + if (ad_flags & BLE_HS_ADV_F_DISC_LTD) { + duration_ms = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); + } } -#else - adv_duration = MYNEWT_VAL(BTTESTER_LTD_ADV_TIMEOUT); -#endif /* In NimBLE, own_addr_type is configured in `controller_info` function. * Let's just verify restrictions for Privacy options. @@ -576,10 +596,10 @@ start_advertising(const void *cmd, uint16_t cmd_len, #endif #if MYNEWT_VAL(BLE_EXT_ADV) - err = ble_gap_ext_adv_start(0, duration_ms, 0); + err = ble_gap_ext_adv_start(0, duration_ms / 10, 0); #else err = ble_gap_adv_start(own_addr_type, NULL, duration_ms, - &adv_params, gap_event_cb, NULL); + &adv_params, gap_event_cb, NULL); #endif if (err) { SYS_LOG_ERR("Advertising failed: err %d", err); @@ -1751,24 +1771,51 @@ passkey_confirm(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +#if MYNEWT_VAL(BLE_EXT_ADV) +static struct ble_gap_ext_adv_params dir_adv_params = { + .primary_phy = BLE_HCI_LE_PHY_1M, + .secondary_phy = BLE_HCI_LE_PHY_1M, + .sid = 1, + .legacy_pdu = 1, + .directed = 1, + .connectable = 1, +}; +#else +static struct ble_gap_adv_params dir_adv_params = { + .conn_mode = BLE_GAP_CONN_MODE_DIR, +}; +#endif + static uint8_t start_direct_adv(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { const struct btp_gap_start_direct_adv_cmd *cp = cmd; struct btp_gap_start_advertising_rp *rp = rsp; - static struct ble_gap_adv_params adv_params = { - .conn_mode = BLE_GAP_CONN_MODE_DIR, - }; int err; SYS_LOG_DBG(""); - adv_params.high_duty_cycle = cp->options & BIT(1); +#if MYNEWT_VAL(BLE_EXT_ADV) + dir_adv_params.high_duty_directed = cp->options & BIT(1); + dir_adv_params.own_addr_type = own_addr_type; + memcpy(&dir_adv_params.peer, &cp->address, sizeof(dir_adv_params.peer)); + + err = ble_gap_ext_adv_configure(0, &dir_adv_params, NULL, gap_event_cb, NULL); + if (err) { + SYS_LOG_ERR("Failed to configure extended advertiser; rc=%d", err); + return BTP_STATUS_FAILED; + } + + err = ble_gap_ext_adv_start(0, 128, 0); +#else + dir_adv_params.high_duty_cycle = cp->options & BIT(1); err = ble_gap_adv_start(own_addr_type, &cp->address, - BLE_HS_FOREVER, &adv_params, + BLE_HS_FOREVER, &dir_adv_params, gap_event_cb, NULL); +#endif + if (err) { SYS_LOG_ERR("Advertising failed: err %d", err); return BTP_STATUS_FAILED; From d1ad7b29c9fb83247dc982d23fc1a4c16624db92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 22 Mar 2024 14:32:45 +0100 Subject: [PATCH 0959/1333] audio/ble_audio.h: fix duplicated defgroups Couple defgroups had same title. --- nimble/host/audio/include/audio/ble_audio.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nimble/host/audio/include/audio/ble_audio.h b/nimble/host/audio/include/audio/ble_audio.h index 288f13ee50..f555cacdde 100644 --- a/nimble/host/audio/include/audio/ble_audio.h +++ b/nimble/host/audio/include/audio/ble_audio.h @@ -225,7 +225,7 @@ /** @} */ /** - * @defgroup ble_audio_codec_config Bluetooth Low Energy Audio Codec Specific Capabilities + * @defgroup ble_audio_codec_caps Bluetooth Low Energy Audio Codec Specific Capabilities * @{ */ @@ -294,7 +294,7 @@ /** @} */ /** - * @defgroup ble_audio_contexts Bluetooth Low Energy Audio Supported Frame Durations + * @defgroup ble_audio_sup_frame_durations Bluetooth Low Energy Audio Supported Frame Durations * @{ */ @@ -313,7 +313,7 @@ /** @} */ /** - * @defgroup ble_audio_contexts Bluetooth Low Energy Audio Supported Sampling Frequencies + * @defgroup ble_audio_sup_sampling_freqs Bluetooth Low Energy Audio Supported Sampling Frequencies * @{ */ @@ -359,7 +359,7 @@ /** @} */ /** - * @defgroup ble_audio_contexts Bluetooth Low Energy Audio Supported Channel Counts + * @defgroup ble_audio_sup_chan_counts Bluetooth Low Energy Audio Supported Channel Counts * @{ */ From 8abef5532631652b8bf0f6959810aadfccb68d75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 22 Mar 2024 14:38:33 +0100 Subject: [PATCH 0960/1333] audio/ble_audio.h: add missing doxygen for ble_audio_broadcast_name `ble_audio_broadcast_name` was not documented. --- nimble/host/audio/include/audio/ble_audio.h | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/host/audio/include/audio/ble_audio.h b/nimble/host/audio/include/audio/ble_audio.h index f555cacdde..080318dbea 100644 --- a/nimble/host/audio/include/audio/ble_audio.h +++ b/nimble/host/audio/include/audio/ble_audio.h @@ -494,6 +494,7 @@ struct ble_audio_pub_broadcast_announcement { const uint8_t *metadata; }; +/** Broadcast Name */ struct ble_audio_broadcast_name { /** Broadcast Name length */ uint8_t name_len; From bba23c8ec6c1e919150bbc536c06d27dc30ea484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 25 Mar 2024 07:12:39 +0100 Subject: [PATCH 0961/1333] audio/ble_audio.h: fix doxygen reference for ble_audio_base_bis_iter @ref was missing, and to make all file visible to doxygen defgroup bt_le_audio was added. --- nimble/host/audio/include/audio/ble_audio.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/nimble/host/audio/include/audio/ble_audio.h b/nimble/host/audio/include/audio/ble_audio.h index 080318dbea..ca70876412 100644 --- a/nimble/host/audio/include/audio/ble_audio.h +++ b/nimble/host/audio/include/audio/ble_audio.h @@ -23,6 +23,16 @@ #include #include +/** + * @file ble_audio.h + * + * @brief Bluetooth Low Energy Audio API + * + * @defgroup bt_le_audio Bluetooth LE Audio + * @ingroup bt_host + * @{ + */ + /** * @cond * Helper macros for BLE_AUDIO_BUILD_CODEC_CONFIG @@ -644,7 +654,7 @@ int ble_audio_event_listener_unregister(struct ble_audio_event_listener *listene * BASE iterator * * The iterator structure used by @ref ble_audio_base_subgroup_iter and - * @ble_audio_base_bis_iter functions to iterate the BASE Level 2 and 3 elements + * @ref ble_audio_base_bis_iter functions to iterate the BASE Level 2 and 3 elements * (Subgroups and BISes). * This should be used as an opaque structure and not modified manually. * @@ -825,4 +835,6 @@ struct ble_audio_base { STAILQ_HEAD(, ble_audio_big_subgroup) subs; }; +/** @} */ + #endif /* H_BLE_AUDIO_ */ From 0bffd7a2a2c2700a2d6ac6d35e271e9b1db65044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 25 Mar 2024 07:17:59 +0100 Subject: [PATCH 0962/1333] audio/ble_audio.h: remove unused argument description in ble_audio_event_listener_register This looks like leftover and is not used. --- nimble/host/audio/include/audio/ble_audio.h | 1 - 1 file changed, 1 deletion(-) diff --git a/nimble/host/audio/include/audio/ble_audio.h b/nimble/host/audio/include/audio/ble_audio.h index ca70876412..59122cfa8f 100644 --- a/nimble/host/audio/include/audio/ble_audio.h +++ b/nimble/host/audio/include/audio/ble_audio.h @@ -629,7 +629,6 @@ struct ble_audio_event_listener { * and/or argument unregister listener first and register it again. * * @param[in] listener Listener structure - * @param[in] event_mask Optional event mask * @param[in] fn Callback function * @param[in] arg Optional callback argument * From 53bae66f71b5ee24e3dc2ada9dd46bb540e33ac8 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 26 Mar 2024 12:59:14 +0100 Subject: [PATCH 0963/1333] nimble/host: Fix reports when using legacy scan with EXT_ADV enabled ble_gap_disc() should always results in BLE_GAP_EVENT_DISC and legacy PDUs only. --- nimble/host/src/ble_gap.c | 55 ++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 8e83b2d85f..b935eface0 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -121,6 +121,10 @@ static const struct ble_gap_conn_params ble_gap_conn_params_dflt = { struct ble_gap_master_state { uint8_t op; +#if MYNEWT_VAL(BLE_EXT_ADV) + /* indicates if discovery was started with legacy API */ + uint8_t legacy_discovery; +#endif uint8_t exp_set:1; ble_npl_time_t exp_os_ticks; @@ -979,13 +983,45 @@ ble_gap_disc_report(void *desc) struct ble_gap_event event; memset(&event, 0, sizeof event); + event.type = BLE_GAP_EVENT_DISC; + event.disc = *((struct ble_gap_disc_desc *)desc); + + ble_gap_master_extract_state(&state, 0); + if (ble_gap_has_client(&state)) { + state.cb(&event, state.cb_arg); + } + + ble_gap_event_listener_call(&event); +} + #if MYNEWT_VAL(BLE_EXT_ADV) +static void +ble_gap_ext_disc_report(void *desc) +{ + struct ble_gap_ext_disc_desc *ext_desc = desc; + struct ble_gap_disc_desc legacy_desc; + struct ble_gap_master_state state; + struct ble_gap_event event; + + if (ble_gap_master.legacy_discovery) { + /* ignore non-legacy events */ + if (!(ext_desc->props & BLE_HCI_ADV_LEGACY_MASK)) { + return; + } + + legacy_desc.event_type = ext_desc->legacy_event_type; + legacy_desc.length_data = ext_desc->length_data; + legacy_desc.addr = ext_desc->addr; + legacy_desc.rssi = ext_desc->rssi; + legacy_desc.data = ext_desc->data; + legacy_desc.direct_addr = ext_desc->direct_addr; + ble_gap_disc_report(&legacy_desc); + return; + } + + memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_EXT_DISC; event.ext_disc = *((struct ble_gap_ext_disc_desc *)desc); -#else - event.type = BLE_GAP_EVENT_DISC; - event.disc = *((struct ble_gap_disc_desc *)desc); -#endif ble_gap_master_extract_state(&state, 0); if (ble_gap_has_client(&state)) { @@ -994,6 +1030,7 @@ ble_gap_disc_report(void *desc) ble_gap_event_listener_call(&event); } +#endif static void ble_gap_disc_complete(void) @@ -1557,7 +1594,7 @@ ble_gap_rx_ext_adv_report(struct ble_gap_ext_disc_desc *desc) return; } - ble_gap_disc_report(desc); + ble_gap_ext_disc_report(desc); } #endif @@ -4822,6 +4859,7 @@ ble_gap_ext_disc(uint8_t own_addr_type, uint16_t duration, uint16_t period, } ble_gap_master.op = BLE_GAP_OP_M_DISC; + ble_gap_master.legacy_discovery = 0; rc = ble_gap_ext_disc_enable_tx(1, filter_duplicates, duration, period); if (rc != 0) { @@ -4898,6 +4936,7 @@ ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms, #if NIMBLE_BLE_SCAN #if MYNEWT_VAL(BLE_EXT_ADV) struct ble_gap_ext_disc_params p = {0}; + int rc; if (!ble_hs_is_enabled()) { return BLE_HS_EDISABLED; @@ -4913,10 +4952,14 @@ ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms, duration_ms = BLE_GAP_DISC_DUR_DFLT; } - return ble_gap_ext_disc(own_addr_type, duration_ms/10, 0, + rc = ble_gap_ext_disc(own_addr_type, duration_ms/10, 0, disc_params->filter_duplicates, disc_params->filter_policy, disc_params->limited, &p, NULL, cb, cb_arg); + + ble_gap_master.legacy_discovery = 1; + + return rc; #else struct ble_gap_disc_params params; uint32_t duration_ticks = 0; From 89e7090c59a0dd2fa1a556f83dbf7dee81f9df68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 27 Mar 2024 08:46:43 +0100 Subject: [PATCH 0964/1333] controller/ble_ll_sync.c: acad_len potentially uninitialised acad_len in ble_ll_sync_rx_pkt_in is filled in ble_ll_sync_parse_ext_hdr and later accessed in ble_ll_sync_check_acad. There is a possibility that extended advertising header is missing data containing acad, and it will not get filled, leaving it uninitialised. --- nimble/controller/src/ble_ll_sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 31c8ec04d8..d15f1df007 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -1136,7 +1136,7 @@ ble_ll_sync_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) int8_t tx_power = 127; /* defaults to not available */ uint8_t *aux = NULL; uint8_t *acad = NULL; - uint8_t acad_len; + uint8_t acad_len = 0; const uint8_t *biginfo = NULL; uint8_t biginfo_len = 0; int datalen; From 675452b62822efd3e3fd28ac55eb166baf8461f4 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 27 Mar 2024 09:10:48 +0100 Subject: [PATCH 0965/1333] Prepare for NimBLE 1.7.0 release --- NOTICE | 2 +- RELEASE_NOTES.md | 11 +++++------ repository.yml | 4 ++++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/NOTICE b/NOTICE index 7e95f43482..740162388b 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ Apache Mynewt NimBLE -Copyright 2015-2023 The Apache Software Foundation +Copyright 2015-2024 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index afd5e92a85..a34cd87526 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,6 +1,6 @@ # RELEASE NOTES -09 August 2023 - Apache NimBLE v1.6.0 +27 March 2024 - Apache NimBLE v1.7.0 For full release notes, please visit the [Apache Mynewt Wiki](https://cwiki.apache.org/confluence/display/MYNEWT/Release+Notes). @@ -10,11 +10,10 @@ replaces the proprietary SoftDevice on Nordic chipsets. New features in this version of NimBLE include: -* Initial support for ISO broacaster -* Support for Bluetooth Core Specification 5.4 -* FEM antenna control -* nRF PHY driver unification -* IPC HCI transport improvements +* Initial support for Enhanced ATT bearer +* Initial support for Broadcast Source and Auracast +* GATT host API additions +* Doxygen API comments overhaul If working on next-generation RTOS and Bluetooth protocol stack sounds exciting to you, get in touch, by sending a mail to the Apache Mynewt diff --git a/repository.yml b/repository.yml index 2dc50fb8ac..b50dc7b9bc 100644 --- a/repository.yml +++ b/repository.yml @@ -32,6 +32,7 @@ repo.versions: "1.4.0": "nimble_1_4_0_tag" "1.5.0": "nimble_1_5_0_tag" "1.6.0": "nimble_1_6_0_tag" + "1.7.0": "nimble_1_7_0_tag" "1.0-latest": "1.0.0" "1.1-latest": "1.1.0" @@ -40,6 +41,7 @@ repo.versions: "1.4-latest": "1.4.0" "1.5-latest": "1.5.0" "1.6-latest": "1.6.0" + "1.7-latest": "1.7.0" repo.newt_compatibility: 0.0.0: @@ -58,3 +60,5 @@ repo.newt_compatibility: 1.10.0: good 1.6.0: 1.11.0: good + 1.7.0: + 1.12.0: good From 0c6f2fe6b78c3b6ad2a125dc5aa378f122655541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 4 Apr 2024 12:38:24 +0200 Subject: [PATCH 0966/1333] host/ble_audio.c: fix ble_audio_adv_parse_broadcast_announcement data->success was set to false at every entry to the funcion. That made the valid advertising payload fail after parsing BLE_BROADCAST_PUB_ANNOUNCEMENT_SVC_UUID - final break in block was reached but the success set in parsing BLE_BROADCAST_AUDIO_ANNOUNCEMENT_SVC_UUID was cleared. --- nimble/host/audio/src/ble_audio.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/nimble/host/audio/src/ble_audio.c b/nimble/host/audio/src/ble_audio.c index f7597aaf72..4253347816 100644 --- a/nimble/host/audio/src/ble_audio.c +++ b/nimble/host/audio/src/ble_audio.c @@ -47,8 +47,6 @@ ble_audio_adv_parse_broadcast_announcement(const struct ble_hs_adv_field *field, event = &data->event.broadcast_announcement; - data->success = false; - switch (field->type) { case BLE_HS_ADV_TYPE_SVC_DATA_UUID16: if (value_len < 2) { From 1d809b1201c24dc28e86119ea0006fa4946c0b3d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 4 Apr 2024 13:38:16 +0200 Subject: [PATCH 0967/1333] Apache NimBLE 1.7.0 release --- repository.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/repository.yml b/repository.yml index b50dc7b9bc..8098429783 100644 --- a/repository.yml +++ b/repository.yml @@ -22,8 +22,8 @@ repo.versions: "0.0.0": "master" "0-dev": "0.0.0" - "0-latest": "1.6.0" - "1-latest": "1.6.0" + "0-latest": "1.7.0" + "1-latest": "1.7.0" "1.0.0": "nimble_1_0_0_tag" "1.1.0": "nimble_1_1_0_tag" From e56389af216450721aaab7731f18679db0042a2f Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 5 Apr 2024 15:02:37 +0200 Subject: [PATCH 0968/1333] nimble/porting: Remove not needed sysflash Ports do not use sysflash. --- .../examples/linux/include/syscfg/syscfg.h | 23 +++++---- .../linux/include/sysflash/sysflash.h | 51 ------------------- .../linux_blemesh/include/syscfg/syscfg.h | 25 ++++----- .../linux_blemesh/include/sysflash/sysflash.h | 51 ------------------- .../examples/nuttx/include/syscfg/syscfg.h | 23 +++++---- .../nuttx/include/sysflash/sysflash.h | 51 ------------------- porting/nimble/include/syscfg/syscfg.h | 23 +++++---- porting/nimble/include/sysflash/sysflash.h | 51 ------------------- porting/npl/riot/include/syscfg/syscfg.h | 24 ++++----- porting/npl/riot/include/sysflash/sysflash.h | 51 ------------------- porting/update_generated_files.sh | 3 +- 11 files changed, 63 insertions(+), 313 deletions(-) delete mode 100644 porting/examples/linux/include/sysflash/sysflash.h delete mode 100644 porting/examples/linux_blemesh/include/sysflash/sysflash.h delete mode 100644 porting/examples/nuttx/include/sysflash/sysflash.h delete mode 100644 porting/nimble/include/sysflash/sysflash.h delete mode 100644 porting/npl/riot/include/sysflash/sysflash.h diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index e4d2d3a46f..c7230e4164 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.12.0-dev + * This file was generated by Apache newt version: 1.12.0 */ #ifndef H_MYNEWT_SYSCFG_ @@ -15,6 +15,7 @@ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val +/*** @apache-mynewt-core/crypto/tinycrypt */ #ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE #define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) #endif @@ -599,8 +600,8 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif -#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS -#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#ifndef MYNEWT_VAL_BLE_AUDIO +#define MYNEWT_VAL_BLE_AUDIO (0) #endif #ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM @@ -775,6 +776,14 @@ #define MYNEWT_VAL_BLE_HS_SYSINIT_STAGE (200) #endif +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS +#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES +#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM #define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (0) #endif @@ -807,14 +816,6 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif -#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS -#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) -#endif - -#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES -#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) -#endif - #ifndef MYNEWT_VAL_BLE_MESH #define MYNEWT_VAL_BLE_MESH (0) #endif diff --git a/porting/examples/linux/include/sysflash/sysflash.h b/porting/examples/linux/include/sysflash/sysflash.h deleted file mode 100644 index 2f4d843f4c..0000000000 --- a/porting/examples/linux/include/sysflash/sysflash.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * This file was generated by Apache newt version: 1.12.0-dev - */ - -#ifndef H_MYNEWT_SYSFLASH_ -#define H_MYNEWT_SYSFLASH_ - -#include "flash_map/flash_map.h" - -#define FLASH_AREA_COUNT 6 - -/** - * This flash map definition is used for two purposes: - * 1. To locate the meta area, which contains the true flash map definition. - * 2. As a fallback in case the meta area cannot be read from flash. - */ -extern const struct flash_area sysflash_map_dflt[FLASH_AREA_COUNT]; - -/* Flash map was defined in @apache-mynewt-core/hw/bsp/native */ - -#define FLASH_AREA_BOOTLOADER 0 -#define FLASH_AREA_BOOTLOADER_DEVICE 0 -#define FLASH_AREA_BOOTLOADER_OFFSET 0x00000000 -#define FLASH_AREA_BOOTLOADER_SIZE 16384 - -#define FLASH_AREA_IMAGE_0 1 -#define FLASH_AREA_IMAGE_0_DEVICE 0 -#define FLASH_AREA_IMAGE_0_OFFSET 0x00020000 -#define FLASH_AREA_IMAGE_0_SIZE 393216 - -#define FLASH_AREA_IMAGE_1 2 -#define FLASH_AREA_IMAGE_1_DEVICE 0 -#define FLASH_AREA_IMAGE_1_OFFSET 0x00080000 -#define FLASH_AREA_IMAGE_1_SIZE 393216 - -#define FLASH_AREA_IMAGE_SCRATCH 3 -#define FLASH_AREA_IMAGE_SCRATCH_DEVICE 0 -#define FLASH_AREA_IMAGE_SCRATCH_OFFSET 0x000e0000 -#define FLASH_AREA_IMAGE_SCRATCH_SIZE 131072 - -#define FLASH_AREA_REBOOT_LOG 16 -#define FLASH_AREA_REBOOT_LOG_DEVICE 0 -#define FLASH_AREA_REBOOT_LOG_OFFSET 0x00004000 -#define FLASH_AREA_REBOOT_LOG_SIZE 16384 - -#define FLASH_AREA_NFFS 17 -#define FLASH_AREA_NFFS_DEVICE 0 -#define FLASH_AREA_NFFS_OFFSET 0x00008000 -#define FLASH_AREA_NFFS_SIZE 32768 - -#endif diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 3919eb1eb0..ee1db3c94e 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.12.0-dev + * This file was generated by Apache newt version: 1.12.0 */ #ifndef H_MYNEWT_SYSCFG_ @@ -15,6 +15,7 @@ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val +/*** @apache-mynewt-core/crypto/tinycrypt */ #ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE #define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) #endif @@ -600,8 +601,8 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif -#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS -#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#ifndef MYNEWT_VAL_BLE_AUDIO +#define MYNEWT_VAL_BLE_AUDIO (0) #endif #ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM @@ -776,6 +777,14 @@ #define MYNEWT_VAL_BLE_HS_SYSINIT_STAGE (200) #endif +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS +#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES +#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM #define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (0) #endif @@ -808,14 +817,6 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif -#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS -#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) -#endif - -#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES -#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) -#endif - /* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host) */ #ifndef MYNEWT_VAL_BLE_MESH #define MYNEWT_VAL_BLE_MESH (1) @@ -1328,7 +1329,7 @@ /* Overridden by @apache-mynewt-nimble/nimble/host/mesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN -#define MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN (33) +#define MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN (66) #endif #ifndef MYNEWT_VAL_BLE_MESH_PROXY_USE_DEVICE_NAME diff --git a/porting/examples/linux_blemesh/include/sysflash/sysflash.h b/porting/examples/linux_blemesh/include/sysflash/sysflash.h deleted file mode 100644 index 2f4d843f4c..0000000000 --- a/porting/examples/linux_blemesh/include/sysflash/sysflash.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * This file was generated by Apache newt version: 1.12.0-dev - */ - -#ifndef H_MYNEWT_SYSFLASH_ -#define H_MYNEWT_SYSFLASH_ - -#include "flash_map/flash_map.h" - -#define FLASH_AREA_COUNT 6 - -/** - * This flash map definition is used for two purposes: - * 1. To locate the meta area, which contains the true flash map definition. - * 2. As a fallback in case the meta area cannot be read from flash. - */ -extern const struct flash_area sysflash_map_dflt[FLASH_AREA_COUNT]; - -/* Flash map was defined in @apache-mynewt-core/hw/bsp/native */ - -#define FLASH_AREA_BOOTLOADER 0 -#define FLASH_AREA_BOOTLOADER_DEVICE 0 -#define FLASH_AREA_BOOTLOADER_OFFSET 0x00000000 -#define FLASH_AREA_BOOTLOADER_SIZE 16384 - -#define FLASH_AREA_IMAGE_0 1 -#define FLASH_AREA_IMAGE_0_DEVICE 0 -#define FLASH_AREA_IMAGE_0_OFFSET 0x00020000 -#define FLASH_AREA_IMAGE_0_SIZE 393216 - -#define FLASH_AREA_IMAGE_1 2 -#define FLASH_AREA_IMAGE_1_DEVICE 0 -#define FLASH_AREA_IMAGE_1_OFFSET 0x00080000 -#define FLASH_AREA_IMAGE_1_SIZE 393216 - -#define FLASH_AREA_IMAGE_SCRATCH 3 -#define FLASH_AREA_IMAGE_SCRATCH_DEVICE 0 -#define FLASH_AREA_IMAGE_SCRATCH_OFFSET 0x000e0000 -#define FLASH_AREA_IMAGE_SCRATCH_SIZE 131072 - -#define FLASH_AREA_REBOOT_LOG 16 -#define FLASH_AREA_REBOOT_LOG_DEVICE 0 -#define FLASH_AREA_REBOOT_LOG_OFFSET 0x00004000 -#define FLASH_AREA_REBOOT_LOG_SIZE 16384 - -#define FLASH_AREA_NFFS 17 -#define FLASH_AREA_NFFS_DEVICE 0 -#define FLASH_AREA_NFFS_OFFSET 0x00008000 -#define FLASH_AREA_NFFS_SIZE 32768 - -#endif diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index 16cdc6c005..48a830a60d 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.12.0-dev + * This file was generated by Apache newt version: 1.12.0 */ #ifndef H_MYNEWT_SYSCFG_ @@ -15,6 +15,7 @@ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val +/*** @apache-mynewt-core/crypto/tinycrypt */ #ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE #define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) #endif @@ -599,8 +600,8 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif -#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS -#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#ifndef MYNEWT_VAL_BLE_AUDIO +#define MYNEWT_VAL_BLE_AUDIO (0) #endif #ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM @@ -775,6 +776,14 @@ #define MYNEWT_VAL_BLE_HS_SYSINIT_STAGE (200) #endif +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS +#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES +#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM #define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (0) #endif @@ -807,14 +816,6 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif -#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS -#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) -#endif - -#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES -#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) -#endif - #ifndef MYNEWT_VAL_BLE_MESH #define MYNEWT_VAL_BLE_MESH (0) #endif diff --git a/porting/examples/nuttx/include/sysflash/sysflash.h b/porting/examples/nuttx/include/sysflash/sysflash.h deleted file mode 100644 index 2f4d843f4c..0000000000 --- a/porting/examples/nuttx/include/sysflash/sysflash.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * This file was generated by Apache newt version: 1.12.0-dev - */ - -#ifndef H_MYNEWT_SYSFLASH_ -#define H_MYNEWT_SYSFLASH_ - -#include "flash_map/flash_map.h" - -#define FLASH_AREA_COUNT 6 - -/** - * This flash map definition is used for two purposes: - * 1. To locate the meta area, which contains the true flash map definition. - * 2. As a fallback in case the meta area cannot be read from flash. - */ -extern const struct flash_area sysflash_map_dflt[FLASH_AREA_COUNT]; - -/* Flash map was defined in @apache-mynewt-core/hw/bsp/native */ - -#define FLASH_AREA_BOOTLOADER 0 -#define FLASH_AREA_BOOTLOADER_DEVICE 0 -#define FLASH_AREA_BOOTLOADER_OFFSET 0x00000000 -#define FLASH_AREA_BOOTLOADER_SIZE 16384 - -#define FLASH_AREA_IMAGE_0 1 -#define FLASH_AREA_IMAGE_0_DEVICE 0 -#define FLASH_AREA_IMAGE_0_OFFSET 0x00020000 -#define FLASH_AREA_IMAGE_0_SIZE 393216 - -#define FLASH_AREA_IMAGE_1 2 -#define FLASH_AREA_IMAGE_1_DEVICE 0 -#define FLASH_AREA_IMAGE_1_OFFSET 0x00080000 -#define FLASH_AREA_IMAGE_1_SIZE 393216 - -#define FLASH_AREA_IMAGE_SCRATCH 3 -#define FLASH_AREA_IMAGE_SCRATCH_DEVICE 0 -#define FLASH_AREA_IMAGE_SCRATCH_OFFSET 0x000e0000 -#define FLASH_AREA_IMAGE_SCRATCH_SIZE 131072 - -#define FLASH_AREA_REBOOT_LOG 16 -#define FLASH_AREA_REBOOT_LOG_DEVICE 0 -#define FLASH_AREA_REBOOT_LOG_OFFSET 0x00004000 -#define FLASH_AREA_REBOOT_LOG_SIZE 16384 - -#define FLASH_AREA_NFFS 17 -#define FLASH_AREA_NFFS_DEVICE 0 -#define FLASH_AREA_NFFS_OFFSET 0x00008000 -#define FLASH_AREA_NFFS_SIZE 32768 - -#endif diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index 4054f14403..37fe32dd87 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.12.0-dev + * This file was generated by Apache newt version: 1.12.0 */ #ifndef H_MYNEWT_SYSCFG_ @@ -15,6 +15,7 @@ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val +/*** @apache-mynewt-core/crypto/tinycrypt */ #ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE #define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) #endif @@ -598,8 +599,8 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif -#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS -#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#ifndef MYNEWT_VAL_BLE_AUDIO +#define MYNEWT_VAL_BLE_AUDIO (0) #endif #ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM @@ -774,6 +775,14 @@ #define MYNEWT_VAL_BLE_HS_SYSINIT_STAGE (200) #endif +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS +#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES +#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM #define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (0) #endif @@ -806,14 +815,6 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif -#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS -#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) -#endif - -#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES -#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) -#endif - #ifndef MYNEWT_VAL_BLE_MESH #define MYNEWT_VAL_BLE_MESH (0) #endif diff --git a/porting/nimble/include/sysflash/sysflash.h b/porting/nimble/include/sysflash/sysflash.h deleted file mode 100644 index 2f4d843f4c..0000000000 --- a/porting/nimble/include/sysflash/sysflash.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * This file was generated by Apache newt version: 1.12.0-dev - */ - -#ifndef H_MYNEWT_SYSFLASH_ -#define H_MYNEWT_SYSFLASH_ - -#include "flash_map/flash_map.h" - -#define FLASH_AREA_COUNT 6 - -/** - * This flash map definition is used for two purposes: - * 1. To locate the meta area, which contains the true flash map definition. - * 2. As a fallback in case the meta area cannot be read from flash. - */ -extern const struct flash_area sysflash_map_dflt[FLASH_AREA_COUNT]; - -/* Flash map was defined in @apache-mynewt-core/hw/bsp/native */ - -#define FLASH_AREA_BOOTLOADER 0 -#define FLASH_AREA_BOOTLOADER_DEVICE 0 -#define FLASH_AREA_BOOTLOADER_OFFSET 0x00000000 -#define FLASH_AREA_BOOTLOADER_SIZE 16384 - -#define FLASH_AREA_IMAGE_0 1 -#define FLASH_AREA_IMAGE_0_DEVICE 0 -#define FLASH_AREA_IMAGE_0_OFFSET 0x00020000 -#define FLASH_AREA_IMAGE_0_SIZE 393216 - -#define FLASH_AREA_IMAGE_1 2 -#define FLASH_AREA_IMAGE_1_DEVICE 0 -#define FLASH_AREA_IMAGE_1_OFFSET 0x00080000 -#define FLASH_AREA_IMAGE_1_SIZE 393216 - -#define FLASH_AREA_IMAGE_SCRATCH 3 -#define FLASH_AREA_IMAGE_SCRATCH_DEVICE 0 -#define FLASH_AREA_IMAGE_SCRATCH_OFFSET 0x000e0000 -#define FLASH_AREA_IMAGE_SCRATCH_SIZE 131072 - -#define FLASH_AREA_REBOOT_LOG 16 -#define FLASH_AREA_REBOOT_LOG_DEVICE 0 -#define FLASH_AREA_REBOOT_LOG_OFFSET 0x00004000 -#define FLASH_AREA_REBOOT_LOG_SIZE 16384 - -#define FLASH_AREA_NFFS 17 -#define FLASH_AREA_NFFS_DEVICE 0 -#define FLASH_AREA_NFFS_OFFSET 0x00008000 -#define FLASH_AREA_NFFS_SIZE 32768 - -#endif diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 1c46e12a63..236e8cfe40 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1,5 +1,5 @@ /** - * This file was generated by Apache newt version: 1.12.0-dev + * This file was generated by Apache newt version: 1.12.0 */ #ifndef H_MYNEWT_SYSCFG_ @@ -15,6 +15,7 @@ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val +/*** @apache-mynewt-core/compiler/arm-none-eabi-m4 */ #ifndef MYNEWT_VAL_HARDFLOAT #define MYNEWT_VAL_HARDFLOAT (0) #endif @@ -1205,7 +1206,6 @@ #define MYNEWT_VAL_BLE_LL_ISO (0) #endif -/* Value copied from BLE_LL_ISO_BROADCASTER */ #ifndef MYNEWT_VAL_BLE_LL_ISO_BROADCASTER #define MYNEWT_VAL_BLE_LL_ISO_BROADCASTER (0) #endif @@ -1515,8 +1515,8 @@ #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #endif -#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS -#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#ifndef MYNEWT_VAL_BLE_AUDIO +#define MYNEWT_VAL_BLE_AUDIO (0) #endif #ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM @@ -1691,6 +1691,14 @@ #define MYNEWT_VAL_BLE_HS_SYSINIT_STAGE (200) #endif +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS +#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES +#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) +#endif + #ifndef MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM #define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (0) #endif @@ -1723,14 +1731,6 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif -#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS -#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) -#endif - -#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES -#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) -#endif - #ifndef MYNEWT_VAL_BLE_MESH #define MYNEWT_VAL_BLE_MESH (0) #endif diff --git a/porting/npl/riot/include/sysflash/sysflash.h b/porting/npl/riot/include/sysflash/sysflash.h deleted file mode 100644 index 0194dc49a8..0000000000 --- a/porting/npl/riot/include/sysflash/sysflash.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * This file was generated by Apache newt version: 1.12.0-dev - */ - -#ifndef H_MYNEWT_SYSFLASH_ -#define H_MYNEWT_SYSFLASH_ - -#include "flash_map/flash_map.h" - -#define FLASH_AREA_COUNT 6 - -/** - * This flash map definition is used for two purposes: - * 1. To locate the meta area, which contains the true flash map definition. - * 2. As a fallback in case the meta area cannot be read from flash. - */ -extern const struct flash_area sysflash_map_dflt[FLASH_AREA_COUNT]; - -/* Flash map was defined in @apache-mynewt-core/hw/bsp/nordic_pca10056 */ - -#define FLASH_AREA_BOOTLOADER 0 -#define FLASH_AREA_BOOTLOADER_DEVICE 0 -#define FLASH_AREA_BOOTLOADER_OFFSET 0x00000000 -#define FLASH_AREA_BOOTLOADER_SIZE 32768 - -#define FLASH_AREA_IMAGE_0 1 -#define FLASH_AREA_IMAGE_0_DEVICE 0 -#define FLASH_AREA_IMAGE_0_OFFSET 0x0000c000 -#define FLASH_AREA_IMAGE_0_SIZE 483328 - -#define FLASH_AREA_IMAGE_1 2 -#define FLASH_AREA_IMAGE_1_DEVICE 0 -#define FLASH_AREA_IMAGE_1_OFFSET 0x00082000 -#define FLASH_AREA_IMAGE_1_SIZE 483328 - -#define FLASH_AREA_IMAGE_SCRATCH 3 -#define FLASH_AREA_IMAGE_SCRATCH_DEVICE 0 -#define FLASH_AREA_IMAGE_SCRATCH_OFFSET 0x000f8000 -#define FLASH_AREA_IMAGE_SCRATCH_SIZE 16384 - -#define FLASH_AREA_REBOOT_LOG 16 -#define FLASH_AREA_REBOOT_LOG_DEVICE 0 -#define FLASH_AREA_REBOOT_LOG_OFFSET 0x00008000 -#define FLASH_AREA_REBOOT_LOG_SIZE 16384 - -#define FLASH_AREA_NFFS 17 -#define FLASH_AREA_NFFS_DEVICE 0 -#define FLASH_AREA_NFFS_OFFSET 0x000fc000 -#define FLASH_AREA_NFFS_SIZE 16384 - -#endif diff --git a/porting/update_generated_files.sh b/porting/update_generated_files.sh index 006498e2fe..7365bc3ed6 100755 --- a/porting/update_generated_files.sh +++ b/porting/update_generated_files.sh @@ -33,8 +33,9 @@ declare -A targets=( for target in "${!targets[@]}"; do echo "Updating target $target" newt build "@apache-mynewt-nimble/porting/targets/$target" > /dev/null 2>&1 - # logcfg is not used in ports + # logcfg and sysflash is not used in ports rm -rf "bin/@apache-mynewt-nimble/porting/targets/${target}/generated/include/logcfg" + rm -rf "bin/@apache-mynewt-nimble/porting/targets/${target}/generated/include/sysflash" cp "bin/@apache-mynewt-nimble/porting/targets/${target}/generated/include" "${targets[$target]}" -r # Remove repo version and hash MYNEWT_VALS as it doesn't make much sense to commit them and they # defeat the purpose of this script. From 795264b3dbcd0951fd9681cf15e39badd41ce5b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 5 Apr 2024 09:27:27 +0200 Subject: [PATCH 0969/1333] host/ble_gap.h: Extend description of ble_gap_periodic_adv_sync_create Added to the description condition when the Periodic Sync actually happens. --- nimble/host/include/host/ble_gap.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index 271933963c..86e589c189 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -1826,7 +1826,10 @@ int ble_gap_periodic_adv_set_data(uint8_t instance, const struct ble_gap_periodic_adv_set_data_params *params); /** - * Performs the Synchronization procedure with periodic advertiser. + * Schedule the Synchronization procedure with periodic advertiser. + * Procedure is performed as soon as Extended Discovery procedure is started. + * If Extended Discovery is already active when issuing this procedure, + * it will be performed immediately. It is up to application to start Extended Discovery. * * @param addr Peer address to synchronize with. If NULL than * peers from periodic list are used. From bc1f354ea4c646be5035b9ebdec11b7306c42c18 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 5 Apr 2024 14:36:17 +0200 Subject: [PATCH 0970/1333] nimble/host: Wrap extended advertising with legacy API This allows to use extended advertising along legacy GAP API. This will make it easier for applications to port to using EXT ADV. --- nimble/host/src/ble_gap.c | 138 +++++++++++++++++- nimble/host/syscfg.yml | 7 + .../examples/linux/include/syscfg/syscfg.h | 4 + .../linux_blemesh/include/syscfg/syscfg.h | 6 +- .../examples/nuttx/include/syscfg/syscfg.h | 4 + porting/nimble/include/syscfg/syscfg.h | 4 + porting/npl/riot/include/syscfg/syscfg.h | 7 +- 7 files changed, 161 insertions(+), 9 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index b935eface0..b264efd5c9 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -2514,7 +2514,17 @@ ble_gap_adv_stop_no_lock(void) int ble_gap_adv_stop(void) { -#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) +#if NIMBLE_BLE_ADVERTISE +#if MYNEWT_VAL(BLE_EXT_ADV) + int rc; + + rc = ble_gap_ext_adv_stop(MYNEWT_VAL(BLE_HS_EXT_ADV_LEGACY_INSTANCE)); + if (rc) { + return rc; + } + + return ble_gap_ext_adv_remove(MYNEWT_VAL(BLE_HS_EXT_ADV_LEGACY_INSTANCE)); +#else int rc; if (!ble_hs_is_enabled()) { @@ -2526,6 +2536,7 @@ ble_gap_adv_stop(void) ble_hs_unlock(); return rc; +#endif #else return BLE_HS_ENOTSUP; #endif @@ -2712,7 +2723,73 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, const struct ble_gap_adv_params *adv_params, ble_gap_event_fn *cb, void *cb_arg) { -#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) +#if NIMBLE_BLE_ADVERTISE +#if MYNEWT_VAL(BLE_EXT_ADV) + struct ble_gap_ext_adv_params ext_params; + int duration; + int rc; + + STATS_INC(ble_gap_stats, adv_start); + + if (!ble_hs_is_enabled()) { + return BLE_HS_EDISABLED; + } + + memset(&ext_params, 0, sizeof(ext_params)); + + ext_params.own_addr_type = own_addr_type; + ext_params.primary_phy = BLE_HCI_LE_PHY_1M; + ext_params.secondary_phy = BLE_HCI_LE_PHY_1M; + ext_params.tx_power = 127; + ext_params.sid = 0; + ext_params.legacy_pdu = 1; + + switch (adv_params->conn_mode) { + case BLE_GAP_CONN_MODE_NON: + if (adv_params->disc_mode != BLE_GAP_DISC_MODE_NON) { + ext_params.scannable = 1; + } + break; + case BLE_GAP_CONN_MODE_DIR: + if (!direct_addr) { + return BLE_HS_EINVAL; + } + + ext_params.peer = *direct_addr; + ext_params.directed = 1; + if (adv_params->high_duty_cycle) { + ext_params.high_duty_directed = 1; + } + break; + case BLE_GAP_CONN_MODE_UND: + ext_params.connectable = 1; + ext_params.scannable = 1; + break; + default: + return BLE_HS_EINVAL; + } + + ext_params.itvl_min = adv_params->itvl_min; + ext_params.itvl_max = adv_params->itvl_max; + ext_params.channel_map = adv_params->channel_map; + ext_params.filter_policy = adv_params->filter_policy; + ext_params.high_duty_directed = adv_params->high_duty_cycle; + + /* configure instance 0 */ + rc = ble_gap_ext_adv_configure(MYNEWT_VAL(BLE_HS_EXT_ADV_LEGACY_INSTANCE), + &ext_params, NULL, cb, cb_arg); + if (rc) { + return rc; + } + + if (duration_ms == BLE_HS_FOREVER) { + duration = 0; + } else { + duration = duration_ms / 10; + } + + return ble_gap_ext_adv_start(MYNEWT_VAL(BLE_HS_EXT_ADV_LEGACY_INSTANCE), duration, 0); +#else uint32_t duration_ticks; int rc; @@ -2788,6 +2865,7 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, STATS_INC(ble_gap_stats, adv_start_fail); } return rc; +#endif #else return BLE_HS_ENOTSUP; #endif @@ -2796,7 +2874,29 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, int ble_gap_adv_set_data(const uint8_t *data, int data_len) { -#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) +#if NIMBLE_BLE_ADVERTISE +#if MYNEWT_VAL(BLE_EXT_ADV) + struct os_mbuf *mbuf; + int rc; + + if (((data == NULL) && (data_len != 0)) || + (data_len > BLE_HCI_MAX_ADV_DATA_LEN)) { + return BLE_HS_EINVAL; + } + + mbuf = os_msys_get_pkthdr(data_len, 0); + if (!mbuf) { + return BLE_HS_ENOMEM; + } + + rc = os_mbuf_append(mbuf, data, data_len); + if (rc) { + os_mbuf_free_chain(mbuf); + return BLE_HS_ENOMEM; + } + + return ble_gap_ext_adv_set_data(MYNEWT_VAL(BLE_HS_EXT_ADV_LEGACY_INSTANCE), mbuf); +#else struct ble_hci_le_set_adv_data_cp cmd; uint16_t opcode; @@ -2818,6 +2918,7 @@ ble_gap_adv_set_data(const uint8_t *data, int data_len) opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADV_DATA); return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); +#endif #else return BLE_HS_ENOTSUP; #endif @@ -2826,7 +2927,29 @@ ble_gap_adv_set_data(const uint8_t *data, int data_len) int ble_gap_adv_rsp_set_data(const uint8_t *data, int data_len) { -#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) +#if NIMBLE_BLE_ADVERTISE +#if MYNEWT_VAL(BLE_EXT_ADV) + struct os_mbuf *mbuf; + int rc; + + if (((data == NULL) && (data_len != 0)) || + (data_len > BLE_HCI_MAX_ADV_DATA_LEN)) { + return BLE_HS_EINVAL; + } + + mbuf = os_msys_get_pkthdr(data_len, 0); + if (!mbuf) { + return BLE_HS_ENOMEM; + } + + rc = os_mbuf_append(mbuf, data, data_len); + if (rc) { + os_mbuf_free_chain(mbuf); + return BLE_HS_ENOMEM; + } + + return ble_gap_ext_adv_rsp_set_data(MYNEWT_VAL(BLE_HS_EXT_ADV_LEGACY_INSTANCE), mbuf); +#else struct ble_hci_le_set_scan_rsp_data_cp cmd; uint16_t opcode; @@ -2846,6 +2969,7 @@ ble_gap_adv_rsp_set_data(const uint8_t *data, int data_len) opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA); return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0); +#endif #else return BLE_HS_ENOTSUP; #endif @@ -2854,7 +2978,7 @@ ble_gap_adv_rsp_set_data(const uint8_t *data, int data_len) int ble_gap_adv_set_fields(const struct ble_hs_adv_fields *adv_fields) { -#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) +#if NIMBLE_BLE_ADVERTISE uint8_t buf[BLE_HS_ADV_MAX_SZ]; uint8_t buf_sz; int rc; @@ -2882,7 +3006,7 @@ ble_gap_adv_set_fields(const struct ble_hs_adv_fields *adv_fields) int ble_gap_adv_rsp_set_fields(const struct ble_hs_adv_fields *rsp_fields) { -#if NIMBLE_BLE_ADVERTISE && !MYNEWT_VAL(BLE_EXT_ADV) +#if NIMBLE_BLE_ADVERTISE uint8_t buf[BLE_HS_ADV_MAX_SZ]; uint8_t buf_sz; int rc; @@ -2907,7 +3031,7 @@ int ble_gap_adv_active(void) { #if NIMBLE_BLE_ADVERTISE - return ble_gap_adv_active_instance(0); + return ble_gap_adv_active_instance(MYNEWT_VAL(BLE_HS_EXT_ADV_LEGACY_INSTANCE)); #else return 0; #endif diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index 69db7dfd35..93dbcd2ed9 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -27,6 +27,13 @@ syscfg.defs: initialization. value: 1 + BLE_HS_EXT_ADV_LEGACY_INSTANCE: + description: > + Advertising instance that is used when extended advertising + support is enabled but legacy GAP API is used. + range: 0..BLE_MULTI_ADV_INSTANCES + value: 0 + # Debug settings. BLE_HS_DEBUG: description: 'Enables extra runtime assertions.' diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index c7230e4164..3c62cc3ca4 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -728,6 +728,10 @@ #define MYNEWT_VAL_BLE_HS_DEBUG (0) #endif +#ifndef MYNEWT_VAL_BLE_HS_EXT_ADV_LEGACY_INSTANCE +#define MYNEWT_VAL_BLE_HS_EXT_ADV_LEGACY_INSTANCE (0) +#endif + #ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL #define MYNEWT_VAL_BLE_HS_FLOW_CTRL (0) #endif diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index ee1db3c94e..e16ecb5b14 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -729,6 +729,10 @@ #define MYNEWT_VAL_BLE_HS_DEBUG (0) #endif +#ifndef MYNEWT_VAL_BLE_HS_EXT_ADV_LEGACY_INSTANCE +#define MYNEWT_VAL_BLE_HS_EXT_ADV_LEGACY_INSTANCE (0) +#endif + #ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL #define MYNEWT_VAL_BLE_HS_FLOW_CTRL (0) #endif @@ -1329,7 +1333,7 @@ /* Overridden by @apache-mynewt-nimble/nimble/host/mesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN -#define MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN (66) +#define MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN (33) #endif #ifndef MYNEWT_VAL_BLE_MESH_PROXY_USE_DEVICE_NAME diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index 48a830a60d..4740c348c3 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -728,6 +728,10 @@ #define MYNEWT_VAL_BLE_HS_DEBUG (0) #endif +#ifndef MYNEWT_VAL_BLE_HS_EXT_ADV_LEGACY_INSTANCE +#define MYNEWT_VAL_BLE_HS_EXT_ADV_LEGACY_INSTANCE (0) +#endif + #ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL #define MYNEWT_VAL_BLE_HS_FLOW_CTRL (0) #endif diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index 37fe32dd87..766a5e46e6 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -727,6 +727,10 @@ #define MYNEWT_VAL_BLE_HS_DEBUG (0) #endif +#ifndef MYNEWT_VAL_BLE_HS_EXT_ADV_LEGACY_INSTANCE +#define MYNEWT_VAL_BLE_HS_EXT_ADV_LEGACY_INSTANCE (0) +#endif + #ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL #define MYNEWT_VAL_BLE_HS_FLOW_CTRL (0) #endif diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 236e8cfe40..d07ca8a179 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -84,8 +84,9 @@ #define MYNEWT_VAL_CRYPTO (0) #endif +/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_GPIO_AS_PIN_RESET -#define MYNEWT_VAL_GPIO_AS_PIN_RESET (0) +#define MYNEWT_VAL_GPIO_AS_PIN_RESET (1) #endif #ifndef MYNEWT_VAL_I2C_0 @@ -1643,6 +1644,10 @@ #define MYNEWT_VAL_BLE_HS_DEBUG (0) #endif +#ifndef MYNEWT_VAL_BLE_HS_EXT_ADV_LEGACY_INSTANCE +#define MYNEWT_VAL_BLE_HS_EXT_ADV_LEGACY_INSTANCE (0) +#endif + #ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL #define MYNEWT_VAL_BLE_HS_FLOW_CTRL (0) #endif From 6d153f934af134bcf69436335d29be3e2dba5b79 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Tue, 9 Apr 2024 15:08:10 +0200 Subject: [PATCH 0971/1333] apps: Fix x64 native btshell build --- apps/btshell/src/cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index 4c00d7ba35..50aac79400 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -2447,7 +2447,7 @@ cmd_keystore_iterator(int obj_type, console_printf("Key: "); if (ble_addr_cmp(&val->sec.peer_addr, BLE_ADDR_ANY) == 0) { console_printf("ediv=%u ", val->sec.ediv); - console_printf("ediv=%llu ", val->sec.rand_num); + console_printf("rand=%" PRIu64, val->sec.rand_num); } else { console_printf("addr_type=%u ", val->sec.peer_addr.type); print_addr(val->sec.peer_addr.val); From 58eb4082535d8ca9df62af54de02236b0144622e Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Mon, 5 Feb 2024 16:49:27 +0100 Subject: [PATCH 0972/1333] nimble: host: Add initial support for CS HCI --- nimble/host/include/host/ble_cs.h | 57 +++ nimble/host/src/ble_cs.c | 731 +++++++++++++++++++++++++++++ nimble/host/src/ble_cs_priv.h | 31 ++ nimble/host/src/ble_hs_hci_evt.c | 13 + nimble/host/src/ble_hs_startup.c | 17 + nimble/include/nimble/hci_common.h | 302 ++++++++++++ nimble/syscfg.yml | 5 + nimble/transport/syscfg.yml | 4 + 8 files changed, 1160 insertions(+) create mode 100644 nimble/host/include/host/ble_cs.h create mode 100644 nimble/host/src/ble_cs.c create mode 100644 nimble/host/src/ble_cs_priv.h diff --git a/nimble/host/include/host/ble_cs.h b/nimble/host/include/host/ble_cs.h new file mode 100644 index 0000000000..3abbd11e65 --- /dev/null +++ b/nimble/host/include/host/ble_cs.h @@ -0,0 +1,57 @@ +/* + * 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. + */ + +/* All Channel Sounding APIs are experimental and subject to change at any time */ + +#ifndef H_BLE_CS_ +#define H_BLE_CS_ +#include "syscfg/syscfg.h" + +#define BLE_CS_EVENT_CS_PROCEDURE_COMPLETE (0) + +struct ble_cs_event { + uint8_t type; + union + { + struct + { + uint16_t conn_handle; + uint8_t status; + } procedure_complete; + }; + +}; + +typedef int ble_cs_event_fn(struct ble_cs_event *event, void *arg); + +struct ble_cs_initiator_procedure_start_params { + uint16_t conn_handle; + ble_cs_event_fn *cb; + void *cb_arg; +}; + +struct ble_cs_reflector_setup_params { + ble_cs_event_fn *cb; + void *cb_arg; +}; + +int ble_cs_initiator_procedure_start(const struct ble_cs_initiator_procedure_start_params *params); +int ble_cs_initiator_procedure_terminate(uint16_t conn_handle); +int ble_cs_reflector_setup(struct ble_cs_reflector_setup_params *params); +#endif diff --git a/nimble/host/src/ble_cs.c b/nimble/host/src/ble_cs.c new file mode 100644 index 0000000000..cef622206b --- /dev/null +++ b/nimble/host/src/ble_cs.c @@ -0,0 +1,731 @@ +/* + * 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. + */ + +#include +#include "syscfg/syscfg.h" +#include "ble_hs_mbuf_priv.h" + +#if MYNEWT_VAL(BLE_CHANNEL_SOUNDING) + +#include "os/os_mbuf.h" +#include "host/ble_hs_log.h" +#include "host/ble_hs.h" +#include "host/ble_cs.h" +#include "nimble/hci_common.h" +#include "sys/queue.h" +#include "ble_hs_hci_priv.h" + +struct ble_cs_rd_rem_supp_cap_cp { + uint16_t conn_handle; +} __attribute__((packed)); + +struct ble_cs_wr_cached_rem_supp_cap_cp { + uint16_t conn_handle; + uint8_t num_config_supported; + uint16_t max_consecutive_procedures_supported; + uint8_t num_antennas_supported; + uint8_t max_antenna_paths_supported; + uint8_t roles_supported; + uint8_t optional_modes_supported; + uint8_t rtt_capability; + uint8_t rtt_aa_only_n; + uint8_t rtt_sounding_n; + uint8_t rtt_random_payload_n; + uint16_t optional_nadm_sounding_capability; + uint16_t optional_nadm_random_capability; + uint8_t optional_cs_sync_phys_supported; + uint16_t optional_subfeatures_supported; + uint16_t optional_t_ip1_times_supported; + uint16_t optional_t_ip2_times_supported; + uint16_t optional_t_fcs_times_supported; + uint16_t optional_t_pm_times_supported; + uint8_t t_sw_time_supported; +} __attribute__((packed)); +struct ble_cs_wr_cached_rem_supp_cap_rp { + uint16_t conn_handle; +} __attribute__((packed)); + +struct ble_cs_sec_enable_cp { + uint16_t conn_handle; +} __attribute__((packed)); + +struct ble_cs_set_def_settings_cp { + uint16_t conn_handle; + uint8_t role_enable; + uint8_t cs_sync_antenna_selection; + uint8_t max_tx_power; +} __attribute__((packed)); +struct ble_cs_set_def_settings_rp { + uint16_t conn_handle; +} __attribute__((packed)); + +struct ble_cs_rd_rem_fae_cp { + uint16_t conn_handle; +} __attribute__((packed)); + +struct ble_cs_wr_cached_rem_fae_cp { + uint16_t conn_handle; + uint8_t remote_fae_table[72]; +} __attribute__((packed)); +struct ble_cs_wr_cached_rem_fae_rp { + uint16_t conn_handle; +} __attribute__((packed)); + +struct ble_cs_create_config_cp { + uint16_t conn_handle; + uint8_t config_id; + /* If the config should be created on the remote controller too */ + uint8_t create_context; + /* The main mode to be used in the CS procedures */ + uint8_t main_mode_type; + /* The sub mode to be used in the CS procedures */ + uint8_t sub_mode_type; + /* Minimum/maximum number of CS main mode steps to be executed before + * a submode step. + */ + uint8_t min_main_mode_steps; + uint8_t max_main_mode_steps; + /* The number of main mode steps taken from the end of the last + * CS subevent to be repeated at the beginning of the current CS subevent + * directly after the last mode 0 step of that event + */ + uint8_t main_mode_repetition; + uint8_t mode_0_steps; + uint8_t role; + uint8_t rtt_type; + uint8_t cs_sync_phy; + uint8_t channel_map[10]; + uint8_t channel_map_repetition; + uint8_t channel_selection_type; + uint8_t ch3c_shape; + uint8_t ch3c_jump; + uint8_t companion_signal_enable; +} __attribute__((packed)); + +struct ble_cs_remove_config_cp { + uint16_t conn_handle; + uint8_t config_id; +} __attribute__((packed)); + +struct ble_cs_set_chan_class_cp { + uint8_t channel_classification[10]; +} __attribute__((packed)); + +struct ble_cs_set_proc_params_cp { + uint16_t conn_handle; + uint8_t config_id; + /* The maximum duration of each CS procedure (time = N × 0.625 ms) */ + uint16_t max_procedure_len; + /* The minimum and maximum number of connection events between + * consecutive CS procedures. Ignored if only one CS procedure. */ + uint16_t min_procedure_interval; + uint16_t max_procedure_interval; + /* The maximum number of consecutive CS procedures to be scheduled */ + uint16_t max_procedure_count; + /* Minimum/maximum suggested durations for each CS subevent in microseconds. + * Only 3 bytes meaningful. */ + uint32_t min_subevent_len; + uint32_t max_subevent_len; + /* Antenna Configuration Index (ACI) for swithing during phase measuement */ + uint8_t tone_antenna_config_selection; + /* The remote device’s Tx PHY. A 4 bits bitmap. */ + uint8_t phy; + /* How many more or fewer of transmit power levels should the remote device’s + * Tx PHY use during the CS tones and RTT transmission */ + uint8_t tx_power_delta; + /* Preferred peer-ordered antenna elements to be used by the peer for + * the selected antenna configuration (ACI). A 4 bits bitmap. */ + uint8_t preferred_peer_antenna; + /* SNR Output Index (SOI) for SNR control adjustment. */ + uint8_t snr_control_initiator; + uint8_t snr_control_reflector; +} __attribute__((packed)); +struct ble_cs_set_proc_params_rp { + uint16_t conn_handle; +} __attribute__((packed)); + +struct ble_cs_proc_enable_cp { + uint16_t conn_handle; + uint8_t config_id; + uint8_t enable; +} __attribute__((packed)); + +struct ble_cs_state { + uint8_t op; + ble_cs_event_fn *cb; + void *cb_arg; +}; + +static struct ble_cs_state cs_state; + +static int +ble_cs_call_event_cb(struct ble_cs_event *event) +{ + int rc; + + if (cs_state.cb != NULL) { + rc = cs_state.cb(event, cs_state.cb_arg); + } else { + rc = 0; + } + + return rc; +} + +static void +ble_cs_call_procedure_complete_cb(uint16_t conn_handle, uint8_t status) +{ + struct ble_cs_event event; + + memset(&event, 0, sizeof event); + event.type = BLE_CS_EVENT_CS_PROCEDURE_COMPLETE; + event.procedure_complete.conn_handle = conn_handle; + event.procedure_complete.status = status; + ble_cs_call_event_cb(&event); +} + +static int +ble_cs_rd_loc_supp_cap(void) +{ + int rc; + struct ble_hci_le_cs_rd_loc_supp_cap_rp rp; + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CS_RD_LOC_SUPP_CAP), + NULL, 0, &rp, sizeof(rp)); + + rp.max_consecutive_procedures_supported = le16toh(rp.max_consecutive_procedures_supported); + rp.optional_nadm_sounding_capability = le16toh(rp.optional_nadm_sounding_capability); + rp.optional_nadm_random_capability = le16toh(rp.optional_nadm_random_capability); + rp.optional_subfeatures_supported = le16toh(rp.optional_subfeatures_supported); + rp.optional_t_ip1_times_supported = le16toh(rp.optional_t_ip1_times_supported); + rp.optional_t_ip2_times_supported = le16toh(rp.optional_t_ip2_times_supported); + rp.optional_t_fcs_times_supported = le16toh(rp.optional_t_fcs_times_supported); + rp.optional_t_pm_times_supported = le16toh(rp.optional_t_pm_times_supported); + (void) rp; + + return rc; +} + +static int +ble_cs_rd_rem_supp_cap(const struct ble_cs_rd_rem_supp_cap_cp *cmd) +{ + struct ble_hci_le_cs_rd_rem_supp_cap_cp cp; + + cp.conn_handle = htole16(cmd->conn_handle); + + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CS_RD_REM_SUPP_CAP), + &cp, sizeof(cp), NULL, 0); +} + +static int +ble_cs_wr_cached_rem_supp_cap(const struct ble_cs_wr_cached_rem_supp_cap_cp *cmd, + struct ble_cs_wr_cached_rem_supp_cap_rp *rsp) +{ + struct ble_hci_le_cs_wr_cached_rem_supp_cap_cp cp; + struct ble_hci_le_cs_wr_cached_rem_supp_cap_rp rp; + int rc; + + cp.conn_handle = htole16(cmd->conn_handle); + cp.num_config_supported = cmd->num_config_supported; + cp.max_consecutive_procedures_supported = htole16(cmd->max_consecutive_procedures_supported); + cp.num_antennas_supported = cmd->num_antennas_supported; + cp.max_antenna_paths_supported = cmd->max_antenna_paths_supported; + cp.roles_supported = cmd->roles_supported; + cp.optional_modes_supported = cmd->optional_modes_supported; + cp.rtt_capability = cmd->rtt_capability; + cp.rtt_aa_only_n = cmd->rtt_aa_only_n; + cp.rtt_sounding_n = cmd->rtt_sounding_n; + cp.rtt_random_payload_n = cmd->rtt_random_payload_n; + cp.optional_nadm_sounding_capability = htole16(cmd->optional_nadm_sounding_capability); + cp.optional_nadm_random_capability = htole16(cmd->optional_nadm_random_capability); + cp.optional_cs_sync_phys_supported = cmd->optional_cs_sync_phys_supported; + cp.optional_subfeatures_supported = htole16(cmd->optional_subfeatures_supported); + cp.optional_t_ip1_times_supported = htole16(cmd->optional_t_ip1_times_supported); + cp.optional_t_ip2_times_supported = htole16(cmd->optional_t_ip2_times_supported); + cp.optional_t_fcs_times_supported = htole16(cmd->optional_t_fcs_times_supported); + cp.optional_t_pm_times_supported = htole16(cmd->optional_t_pm_times_supported); + cp.t_sw_time_supported = cmd->t_sw_time_supported; + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CS_WR_CACHED_REM_SUPP_CAP), + &cp, sizeof(cp), &rp, sizeof(rp)); + + rsp->conn_handle = le16toh(rp.conn_handle); + + return rc; +} + +static int +ble_cs_sec_enable(const struct ble_cs_sec_enable_cp *cmd) +{ + struct ble_hci_le_cs_sec_enable_cp cp; + + cp.conn_handle = htole16(cmd->conn_handle); + + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CS_SEC_ENABLE), + &cp, sizeof(cp), NULL, 0); +} + +static int +ble_cs_set_def_settings(const struct ble_cs_set_def_settings_cp *cmd, + struct ble_cs_set_def_settings_rp *rsp) +{ + struct ble_hci_le_cs_set_def_settings_cp cp; + struct ble_hci_le_cs_set_def_settings_rp rp; + int rc; + + cp.conn_handle = htole16(cmd->conn_handle); + cp.role_enable = cmd->role_enable; + cp.cs_sync_antenna_selection = cmd->cs_sync_antenna_selection; + cp.max_tx_power = cmd->max_tx_power; + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CS_SET_DEF_SETTINGS), + &cp, sizeof(cp), &rp, sizeof(rp)); + + rsp->conn_handle = le16toh(rp.conn_handle); + + return rc; +} + +static int +ble_cs_rd_rem_fae(const struct ble_cs_rd_rem_fae_cp *cmd) +{ + struct ble_hci_le_cs_rd_rem_fae_cp cp; + + cp.conn_handle = htole16(cmd->conn_handle); + + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CS_RD_REM_FAE), + &cp, sizeof(cp), NULL, 0); +} + +static int +ble_cs_wr_cached_rem_fae(const struct ble_cs_wr_cached_rem_fae_cp *cmd, + struct ble_cs_wr_cached_rem_fae_rp *rsp) +{ + struct ble_hci_le_cs_wr_cached_rem_fae_cp cp; + struct ble_hci_le_cs_wr_cached_rem_fae_rp rp; + int rc; + + cp.conn_handle = htole16(cmd->conn_handle); + memcpy(cp.remote_fae_table, cmd->remote_fae_table, 72); + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CS_WR_CACHED_REM_FAE), + &cp, sizeof(cp), &rp, sizeof(rp)); + + rsp->conn_handle = le16toh(rp.conn_handle); + + return rc; +} + +static int +ble_cs_create_config(const struct ble_cs_create_config_cp *cmd) +{ + struct ble_hci_le_cs_create_config_cp cp; + + cp.conn_handle = htole16(cmd->conn_handle); + cp.config_id = cmd->config_id; + cp.create_context = cmd->create_context; + cp.main_mode_type = cmd->main_mode_type; + cp.sub_mode_type = cmd->sub_mode_type; + cp.min_main_mode_steps = cmd->min_main_mode_steps; + cp.max_main_mode_steps = cmd->max_main_mode_steps; + cp.main_mode_repetition = cmd->main_mode_repetition; + cp.mode_0_steps = cmd->mode_0_steps; + cp.role = cmd->role; + cp.rtt_type = cmd->rtt_type; + cp.cs_sync_phy = cmd->cs_sync_phy; + memcpy(cp.channel_map, cmd->channel_map, 10); + cp.channel_map_repetition = cmd->channel_map_repetition; + cp.channel_selection_type = cmd->channel_selection_type; + cp.ch3c_shape = cmd->ch3c_shape; + cp.ch3c_jump = cmd->ch3c_jump; + cp.companion_signal_enable = cmd->companion_signal_enable; + + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CS_CREATE_CONFIG), + &cp, sizeof(cp), NULL, 0); +} + +static int +ble_cs_remove_config(const struct ble_cs_remove_config_cp *cmd) +{ + struct ble_hci_le_cs_remove_config_cp cp; + + cp.conn_handle = htole16(cmd->conn_handle); + cp.config_id = cmd->config_id; + + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CS_REMOVE_CONFIG), + &cp, sizeof(cp), NULL, 0); +} + +static int +ble_cs_set_chan_class(const struct ble_cs_set_chan_class_cp *cmd) +{ + struct ble_hci_le_cs_set_chan_class_cp cp; + int rc; + + memcpy(cp.channel_classification, cmd->channel_classification, 10); + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CS_SET_CHAN_CLASS), + &cp, sizeof(cp), NULL, 0); + + return rc; +} + +static int +ble_cs_set_proc_params(const struct ble_cs_set_proc_params_cp *cmd, + struct ble_cs_set_proc_params_rp *rsp) +{ + struct ble_hci_le_cs_set_proc_params_cp cp; + struct ble_hci_le_cs_set_proc_params_rp rp; + int rc; + + cp.conn_handle = htole16(cmd->conn_handle); + cp.config_id = cmd->config_id; + cp.max_procedure_len = htole16(cmd->max_procedure_len); + cp.min_procedure_interval = htole16(cmd->min_procedure_interval); + cp.max_procedure_interval = htole16(cmd->max_procedure_interval); + cp.max_procedure_count = htole16(cmd->max_procedure_count); + put_le24(cp.min_subevent_len, cmd->min_subevent_len); + put_le24(cp.max_subevent_len, cmd->max_subevent_len); + cp.tone_antenna_config_selection = cmd->tone_antenna_config_selection; + cp.phy = cmd->phy; + cp.tx_power_delta = cmd->tx_power_delta; + cp.preferred_peer_antenna = cmd->preferred_peer_antenna; + cp.snr_control_initiator = cmd->snr_control_initiator; + cp.snr_control_reflector = cmd->snr_control_reflector; + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CS_SET_PROC_PARAMS), + &cp, sizeof(cp), &rp, sizeof(rp)); + + rsp->conn_handle = le16toh(rp.conn_handle); + + return rc; +} + +static int +ble_cs_proc_enable(const struct ble_cs_proc_enable_cp *cmd) +{ + struct ble_hci_le_cs_proc_enable_cp cp; + + cp.conn_handle = htole16(cmd->conn_handle); + cp.config_id = cmd->config_id; + cp.enable = cmd->enable; + + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CS_PROC_ENABLE), + &cp, sizeof(cp), NULL, 0); +} + +int +ble_hs_hci_evt_le_cs_rd_rem_supp_cap_complete(uint8_t subevent, const void *data, + unsigned int len) +{ + int rc; + const struct ble_hci_ev_le_subev_cs_rd_rem_supp_cap_complete *ev = data; + struct ble_cs_set_def_settings_cp set_cmd; + struct ble_cs_set_def_settings_rp set_rsp; + struct ble_cs_rd_rem_fae_cp fae_cmd; + + if (len != sizeof(*ev) || ev->status) { + return BLE_HS_ECONTROLLER; + } + + BLE_HS_LOG(DEBUG, "CS capabilities exchanged"); + + /* TODO: Save the remote capabilities somewhere */ + + set_cmd.conn_handle = le16toh(ev->conn_handle); + /* Only initiator role is enabled */ + set_cmd.role_enable = 0x01; + /* Use antenna with ID 0x01 */ + set_cmd.cs_sync_antenna_selection = 0x01; + /* Set max TX power to the max supported */ + set_cmd.max_tx_power = 0x7F; + + rc = ble_cs_set_def_settings(&set_cmd, &set_rsp); + if (rc) { + BLE_HS_LOG(DEBUG, "Failed to set the default CS settings, err %dt", rc); + + return rc; + } + + /* Read the mode 0 Frequency Actuation Error table */ + fae_cmd.conn_handle = le16toh(ev->conn_handle); + rc = ble_cs_rd_rem_fae(&fae_cmd); + if (rc) { + BLE_HS_LOG(DEBUG, "Failed to read FAE table"); + } + + return rc; +} + +int +ble_hs_hci_evt_le_cs_rd_rem_fae_complete(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_cs_rd_rem_fae_complete *ev = data; + struct ble_cs_create_config_cp cmd; + int rc; + + if (len != sizeof(*ev) || ev->status) { + return BLE_HS_ECONTROLLER; + } + + cmd.conn_handle = le16toh(ev->conn_handle); + /* The config will use ID 0x00 */ + cmd.config_id = 0x00; + /* Create the config on the remote controller too */ + cmd.create_context = 0x01; + /* Measure phase rotations in main mode */ + cmd.main_mode_type = 0x01; + /* Do not use sub mode for now. */ + cmd.sub_mode_type = 0xFF; + /* Range from which the number of CS main mode steps to execute + * will be randomly selected. + */ + cmd.min_main_mode_steps = 0x02; + cmd.max_main_mode_steps = 0x06; + /* The number of main mode steps to be repeated at the beginning of + * the current CS, irrespectively if there are some overlapping main + * mode steps from previous CS subevent or not. + */ + cmd.main_mode_repetition = 0x00; + /* Number of CS mode 0 steps to be included at the beginning of + * each CS subevent + */ + cmd.mode_0_steps = 0x03; + /* Take the Initiator role */ + cmd.role = 0x00; + cmd.rtt_type = 0x01; + cmd.cs_sync_phy = 0x01; + memcpy(cmd.channel_map, (uint8_t[10]) {0x0a, 0xfa, 0xcf, 0xac, 0xfa, 0xc0}, 10); + cmd.channel_map_repetition = 0x01; + /* Use Channel Selection Algorithm #3b */ + cmd.channel_selection_type = 0x00; + /* Ignore these as used only with #3c algorithm */ + cmd.ch3c_shape = 0x00; + cmd.ch3c_jump = 0x00; + /* EDLC/ECLD attack protection not supported */ + cmd.companion_signal_enable = 0x00; + + /* Create CS config */ + rc = ble_cs_create_config(&cmd); + if (rc) { + BLE_HS_LOG(DEBUG, "Failed to create CS config"); + } + + return rc; +} + +int +ble_hs_hci_evt_le_cs_sec_enable_complete(uint8_t subevent, const void *data, + unsigned int len) +{ + int rc; + struct ble_cs_set_proc_params_cp cmd; + struct ble_cs_set_proc_params_rp rsp; + struct ble_cs_proc_enable_cp enable_cmd; + const struct ble_hci_ev_le_subev_cs_sec_enable_complete *ev = data; + + if (len != sizeof(*ev)) { + BLE_HS_LOG(DEBUG, "Failed to enable CS security"); + + return BLE_HS_ECONTROLLER; + } + + BLE_HS_LOG(DEBUG, "CS setup phase completed"); + + cmd.conn_handle = le16toh(ev->conn_handle); + cmd.config_id = 0x00; + /* The maximum duration of each CS procedure (time = N × 0.625 ms) */ + cmd.max_procedure_len = 8; + /* The maximum number of consecutive CS procedures to be scheduled + * as part of this measurement + */ + cmd.max_procedure_count = 0x0001; + /* The minimum and maximum number of connection events between + * consecutive CS procedures. Ignored if only one CS procedure. + */ + cmd.min_procedure_interval = 0x0000; + cmd.max_procedure_interval = 0x0000; + /* Minimum/maximum suggested durations for each CS subevent in microseconds. + * 1250us and 5000us selected. + */ + cmd.min_subevent_len = 1250; + cmd.max_subevent_len = 5000; + /* Use ACI 0 as we have only one antenna on each side */ + cmd.tone_antenna_config_selection = 0x00; + /* Use LE 1M PHY for CS procedures */ + cmd.phy = 0x01; + /* Transmit power delta set to 0x80 means Host does not have a recommendation. */ + cmd.tx_power_delta = 0x80; + /* Preferred antenna array elements to use. We have only a single antenna here. */ + cmd.preferred_peer_antenna = 0x01; + /* SNR Output Index (SOI) for SNR control adjustment. 0xFF means SNR control + * is not to be applied. + */ + cmd.snr_control_initiator = 0xff; + cmd.snr_control_reflector = 0xff; + + rc = ble_cs_set_proc_params(&cmd, &rsp); + if (rc) { + BLE_HS_LOG(DEBUG, "Failed to set CS procedure parameters"); + } + + enable_cmd.conn_handle = le16toh(ev->conn_handle); + enable_cmd.config_id = 0x00; + enable_cmd.enable = 0x01; + + rc = ble_cs_proc_enable(&enable_cmd); + if (rc) { + BLE_HS_LOG(DEBUG, "Failed to enable CS procedure"); + } + + return rc; +} + +int +ble_hs_hci_evt_le_cs_config_complete(uint8_t subevent, const void *data, + unsigned int len) +{ + int rc; + const struct ble_hci_ev_le_subev_cs_config_complete *ev = data; + struct ble_cs_sec_enable_cp cmd; + + if (len != sizeof(*ev) || ev->status) { + return BLE_HS_ECONTROLLER; + } + + cmd.conn_handle = le16toh(ev->conn_handle); + + /* Exchange CS security keys */ + rc = ble_cs_sec_enable(&cmd); + if (rc) { + BLE_HS_LOG(DEBUG, "Failed to enable CS security"); + ble_cs_call_procedure_complete_cb(le16toh(ev->conn_handle), ev->status); + } + + return 0; +} + +int +ble_hs_hci_evt_le_cs_proc_enable_complete(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_cs_proc_enable_complete *ev = data; + + if (len != sizeof(*ev) || ev->status) { + return BLE_HS_ECONTROLLER; + } + + return 0; +} + +int +ble_hs_hci_evt_le_cs_subevent_result(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_cs_subevent_result *ev = data; + + if (len != sizeof(*ev)) { + return BLE_HS_ECONTROLLER; + } + + return 0; +} + +int +ble_hs_hci_evt_le_cs_subevent_result_continue(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_cs_subevent_result_continue *ev = data; + + if (len != sizeof(*ev)) { + return BLE_HS_ECONTROLLER; + } + + return 0; +} + +int +ble_hs_hci_evt_le_cs_test_end_complete(uint8_t subevent, const void *data, + unsigned int len) +{ + const struct ble_hci_ev_le_subev_cs_test_end_complete *ev = data; + + if (len != sizeof(*ev)) { + return BLE_HS_ECONTROLLER; + } + + return 0; +} + +int +ble_cs_initiator_procedure_start(const struct ble_cs_initiator_procedure_start_params *params) +{ + struct ble_hci_le_cs_rd_loc_supp_cap_rp rsp; + struct ble_cs_rd_rem_supp_cap_cp cmd; + int rc; + + /* Channel Sounding setup phase: + * 1. Set local default CS settings + * 2. Exchange CS capabilities with the remote + * 3. Read or write the mode 0 Frequency Actuation Error table + * 4. Create CS configurations + * 5. Start the CS Security Start procedure + */ + + cs_state.cb = params->cb; + cs_state.cb_arg = params->cb_arg; + + cmd.conn_handle = params->conn_handle; + rc = ble_cs_rd_rem_supp_cap(&cmd); + if (rc) { + BLE_HS_LOG(DEBUG, "Failed to read local supported CS capabilities," + "err %dt", rc); + } + + return rc; +} + +int +ble_cs_initiator_procedure_terminate(uint16_t conn_handle) +{ + return 0; +} + +int +ble_cs_reflector_setup(struct ble_cs_reflector_setup_params *params) +{ + cs_state.cb = params->cb; + cs_state.cb_arg = params->cb_arg; + + return 0; +} +#endif diff --git a/nimble/host/src/ble_cs_priv.h b/nimble/host/src/ble_cs_priv.h new file mode 100644 index 0000000000..f02565852d --- /dev/null +++ b/nimble/host/src/ble_cs_priv.h @@ -0,0 +1,31 @@ +/* + * 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_BLE_CS_PRIV_ +#define H_BLE_CS_PRIV_ + +int ble_hs_hci_evt_le_cs_rd_rem_supp_cap_complete(uint8_t subevent, const void *data, unsigned int len); +int ble_hs_hci_evt_le_cs_rd_rem_fae_complete(uint8_t subevent, const void *data, unsigned int len); +int ble_hs_hci_evt_le_cs_sec_enable_complete(uint8_t subevent, const void *data, unsigned int len); +int ble_hs_hci_evt_le_cs_config_complete(uint8_t subevent, const void *data, unsigned int len); +int ble_hs_hci_evt_le_cs_proc_enable_complete(uint8_t subevent, const void *data, unsigned int len); +int ble_hs_hci_evt_le_cs_subevent_result(uint8_t subevent, const void *data, unsigned int len); +int ble_hs_hci_evt_le_cs_subevent_result_continue(uint8_t subevent, const void *data, unsigned int len); +int ble_hs_hci_evt_le_cs_test_end_complete(uint8_t subevent, const void *data, unsigned int len); +#endif diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index cc88bfd838..48012f3b47 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -26,6 +26,9 @@ #include "host/ble_iso.h" #include "ble_hs_priv.h" #include "ble_iso_priv.h" +#if MYNEWT_VAL(BLE_CHANNEL_SOUNDING) +#include "ble_cs_priv.h" +#endif _Static_assert(sizeof (struct hci_data_hdr) == BLE_HCI_DATA_HDR_SZ, "struct hci_data_hdr must be 4 bytes"); @@ -163,6 +166,16 @@ static ble_hs_hci_evt_le_fn * const ble_hs_hci_evt_le_dispatch[] = { #if MYNEWT_VAL(BLE_CONN_SUBRATING) [BLE_HCI_LE_SUBEV_SUBRATE_CHANGE] = ble_hs_hci_evt_le_subrate_change, #endif +#if MYNEWT_VAL(BLE_CHANNEL_SOUNDING) + [BLE_HCI_LE_SUBEV_CS_RD_REM_SUPP_CAP_COMPLETE] = ble_hs_hci_evt_le_cs_rd_rem_supp_cap_complete, + [BLE_HCI_LE_SUBEV_CS_RD_REM_FAE_COMPLETE] = ble_hs_hci_evt_le_cs_rd_rem_fae_complete, + [BLE_HCI_LE_SUBEV_CS_SEC_ENABLE_COMPLETE] = ble_hs_hci_evt_le_cs_sec_enable_complete, + [BLE_HCI_LE_SUBEV_CS_CONFIG_COMPLETE] = ble_hs_hci_evt_le_cs_config_complete, + [BLE_HCI_LE_SUBEV_CS_PROC_ENABLE_COMPLETE] = ble_hs_hci_evt_le_cs_proc_enable_complete, + [BLE_HCI_LE_SUBEV_CS_SUBEVENT_RESULT] = ble_hs_hci_evt_le_cs_subevent_result, + [BLE_HCI_LE_SUBEV_CS_SUBEVENT_RESULT_CONTINUE] = ble_hs_hci_evt_le_cs_subevent_result_continue, + [BLE_HCI_LE_SUBEV_CS_TEST_END_COMPLETE] = ble_hs_hci_evt_le_cs_test_end_complete, +#endif }; #define BLE_HS_HCI_EVT_LE_DISPATCH_SZ \ diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c index 827c00d2a1..c23579547c 100644 --- a/nimble/host/src/ble_hs_startup.c +++ b/nimble/host/src/ble_hs_startup.c @@ -314,6 +314,23 @@ ble_hs_startup_le_set_evmask_tx(void) } #endif +#if MYNEWT_VAL(BLE_CHANNEL_SOUNDING) + if (version >= BLE_HCI_VER_BCS_5_4) { + /** + * Enable the following LE events: + * 0x0000080000000000 LE CS Read Remote Supported Capabilities Complete event + * 0x0000100000000000 LE CS Read Remote FAE Table Complete event + * 0x0000200000000000 LE CS Security Enable Complete event + * 0x0000400000000000 LE CS Config Complete event + * 0x0000800000000000 LE CS Procedure Enable Complete event + * 0x0001000000000000 LE CS Subevent Result event + * 0x0002000000000000 LE CS Subevent Result Continue event + * 0x0004000000000000 LE CS Test End Complete event + */ + mask |= 0x0007f80000000000; + } +#endif + cmd.event_mask = htole64(mask); rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index fb74c24aa2..aadfa37b58 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1149,6 +1149,180 @@ struct ble_hci_le_subrate_req_cp { uint16_t supervision_tmo; } __attribute__((packed)); +#define BLE_HCI_OCF_LE_CS_RD_LOC_SUPP_CAP (0x0089) +struct ble_hci_le_cs_rd_loc_supp_cap_rp { + uint8_t num_config_supported; + uint16_t max_consecutive_procedures_supported; + uint8_t num_antennas_supported; + uint8_t max_antenna_paths_supported; + uint8_t roles_supported; + uint8_t optional_modes_supported; + uint8_t rtt_capability; + uint8_t rtt_aa_only_n; + uint8_t rtt_sounding_n; + uint8_t rtt_random_payload_n; + uint16_t optional_nadm_sounding_capability; + uint16_t optional_nadm_random_capability; + uint8_t optional_cs_sync_phys_supported; + uint16_t optional_subfeatures_supported; + uint16_t optional_t_ip1_times_supported; + uint16_t optional_t_ip2_times_supported; + uint16_t optional_t_fcs_times_supported; + uint16_t optional_t_pm_times_supported; + uint8_t t_sw_time_supported; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_CS_RD_REM_SUPP_CAP (0x008A) +struct ble_hci_le_cs_rd_rem_supp_cap_cp { + uint16_t conn_handle; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_CS_WR_CACHED_REM_SUPP_CAP (0x008B) +struct ble_hci_le_cs_wr_cached_rem_supp_cap_cp { + uint16_t conn_handle; + uint8_t num_config_supported; + uint16_t max_consecutive_procedures_supported; + uint8_t num_antennas_supported; + uint8_t max_antenna_paths_supported; + uint8_t roles_supported; + uint8_t optional_modes_supported; + uint8_t rtt_capability; + uint8_t rtt_aa_only_n; + uint8_t rtt_sounding_n; + uint8_t rtt_random_payload_n; + uint16_t optional_nadm_sounding_capability; + uint16_t optional_nadm_random_capability; + uint8_t optional_cs_sync_phys_supported; + uint16_t optional_subfeatures_supported; + uint16_t optional_t_ip1_times_supported; + uint16_t optional_t_ip2_times_supported; + uint16_t optional_t_fcs_times_supported; + uint16_t optional_t_pm_times_supported; + uint8_t t_sw_time_supported; +} __attribute__((packed)); +struct ble_hci_le_cs_wr_cached_rem_supp_cap_rp { + uint16_t conn_handle; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_CS_SEC_ENABLE (0x008C) +struct ble_hci_le_cs_sec_enable_cp { + uint16_t conn_handle; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_CS_SET_DEF_SETTINGS (0x008D) +struct ble_hci_le_cs_set_def_settings_cp { + uint16_t conn_handle; + uint8_t role_enable; + uint8_t cs_sync_antenna_selection; + uint8_t max_tx_power; +} __attribute__((packed)); +struct ble_hci_le_cs_set_def_settings_rp { + uint16_t conn_handle; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_CS_RD_REM_FAE (0x008E) +struct ble_hci_le_cs_rd_rem_fae_cp { + uint16_t conn_handle; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_CS_WR_CACHED_REM_FAE (0x008F) +struct ble_hci_le_cs_wr_cached_rem_fae_cp { + uint16_t conn_handle; + uint8_t remote_fae_table[72]; +} __attribute__((packed)); +struct ble_hci_le_cs_wr_cached_rem_fae_rp { + uint16_t conn_handle; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_CS_CREATE_CONFIG (0x0090) +struct ble_hci_le_cs_create_config_cp { + uint16_t conn_handle; + uint8_t config_id; + uint8_t create_context; + uint8_t main_mode_type; + uint8_t sub_mode_type; + uint8_t min_main_mode_steps; + uint8_t max_main_mode_steps; + uint8_t main_mode_repetition; + uint8_t mode_0_steps; + uint8_t role; + uint8_t rtt_type; + uint8_t cs_sync_phy; + uint8_t channel_map[10]; + uint8_t channel_map_repetition; + uint8_t channel_selection_type; + uint8_t ch3c_shape; + uint8_t ch3c_jump; + uint8_t companion_signal_enable; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_CS_REMOVE_CONFIG (0x0091) +struct ble_hci_le_cs_remove_config_cp { + uint16_t conn_handle; + uint8_t config_id; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_CS_SET_CHAN_CLASS (0x0092) +struct ble_hci_le_cs_set_chan_class_cp { + uint8_t channel_classification[10]; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_CS_SET_PROC_PARAMS (0x0093) +struct ble_hci_le_cs_set_proc_params_cp { + uint16_t conn_handle; + uint8_t config_id; + uint16_t max_procedure_len; + uint16_t min_procedure_interval; + uint16_t max_procedure_interval; + uint16_t max_procedure_count; + uint8_t min_subevent_len[3]; + uint8_t max_subevent_len[3]; + uint8_t tone_antenna_config_selection; + uint8_t phy; + uint8_t tx_power_delta; + uint8_t preferred_peer_antenna; + uint8_t snr_control_initiator; + uint8_t snr_control_reflector; +} __attribute__((packed)); +struct ble_hci_le_cs_set_proc_params_rp { + uint16_t conn_handle; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_CS_PROC_ENABLE (0x0094) +struct ble_hci_le_cs_proc_enable_cp { + uint16_t conn_handle; + uint8_t config_id; + uint8_t enable; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_CS_TEST (0x0095) +struct ble_hci_le_cs_test_cp { + uint8_t main_mode_type; + uint8_t sub_mode_type; + uint8_t main_mode_repetition; + uint8_t mode_0_steps; + uint8_t role; + uint8_t rtt_type; + uint8_t cs_sync_phy; + uint8_t cs_sync_antenna_selection; + uint8_t subevent_len[3]; + uint16_t subevent_interval; + uint8_t transmit_power_level; + uint8_t t_ip1_time; + uint8_t t_ip2_time; + uint8_t t_fcs_time; + uint8_t t_pm_time; + uint8_t t_sw_time; + uint8_t tone_antenna_config_selection; + uint8_t companion_signal_enable; + uint16_t drbg_nonce; + uint16_t override_config; + uint8_t override_parameters_length; + uint8_t override_parameters_data[]; +} __attribute__((packed)); + +#define BLE_HCI_OCF_LE_CS_TEST_END (0x0096) + /* --- Vendor specific commands (OGF 0x003F) */ /* Read Random Static Address */ #define BLE_HCI_OCF_VS_RD_STATIC_ADDR (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0001)) @@ -1993,6 +2167,134 @@ struct ble_hci_ev_le_subev_subrate_change { uint16_t supervision_tmo; } __attribute__((packed)); +#define BLE_HCI_LE_SUBEV_CS_RD_REM_SUPP_CAP_COMPLETE (0x2C) +struct ble_hci_ev_le_subev_cs_rd_rem_supp_cap_complete { + uint8_t subev_code; + uint8_t status; + uint16_t conn_handle; + uint8_t num_config_supported; + uint16_t max_consecutive_procedures_supported; + uint8_t num_antennas_supported; + uint8_t max_antenna_paths_supported; + uint8_t roles_supported; + uint8_t optional_modes_supported; + uint8_t rtt_capability; + uint8_t rtt_aa_only_n; + uint8_t rtt_sounding_n; + uint8_t rtt_random_payload_n; + uint16_t optional_nadm_sounding_capability; + uint16_t optional_nadm_random_capability; + uint8_t optional_cs_sync_phys_supported; + uint16_t optional_subfeatures_supported; + uint16_t optional_t_ip1_times_supported; + uint16_t optional_t_ip2_times_supported; + uint16_t optional_t_fcs_times_supported; + uint16_t optional_t_pm_times_supported; + uint8_t t_sw_time_supported; +} __attribute__((packed)); + +#define BLE_HCI_LE_SUBEV_CS_RD_REM_FAE_COMPLETE (0x2D) +struct ble_hci_ev_le_subev_cs_rd_rem_fae_complete { + uint8_t subev_code; + uint8_t status; + uint16_t conn_handle; + uint8_t remote_fae_table[72]; +} __attribute__((packed)); + +#define BLE_HCI_LE_SUBEV_CS_SEC_ENABLE_COMPLETE (0x2E) +struct ble_hci_ev_le_subev_cs_sec_enable_complete { + uint8_t subev_code; + uint8_t status; + uint16_t conn_handle; +} __attribute__((packed)); + +#define BLE_HCI_LE_SUBEV_CS_CONFIG_COMPLETE (0x2F) +struct ble_hci_ev_le_subev_cs_config_complete { + uint8_t subev_code; + uint8_t status; + uint16_t conn_handle; + uint8_t config_id; + uint8_t action; + uint8_t main_mode_type; + uint8_t sub_mode_type; + uint8_t min_main_mode_steps; + uint8_t max_main_mode_steps; + uint8_t main_mode_repetition; + uint8_t mode_0_steps; + uint8_t role; + uint8_t rtt_type; + uint8_t cs_sync_phy; + uint8_t channel_map[10]; + uint8_t channel_map_repetition; + uint8_t channel_selection_type; + uint8_t ch3c_shape; + uint8_t ch3c_jump; + uint8_t companion_signal_enable; + uint8_t t_ip1_time; + uint8_t t_ip2_time; + uint8_t t_fcs_time; + uint8_t t_pm_time; +} __attribute__((packed)); + +#define BLE_HCI_LE_SUBEV_CS_PROC_ENABLE_COMPLETE (0x30) +struct ble_hci_ev_le_subev_cs_proc_enable_complete { + uint8_t subev_code; + uint8_t status; + uint16_t conn_handle; + uint8_t config_id; + uint8_t state; + uint8_t tone_antenna_config_selection; + uint8_t selected_tx_power; + uint8_t subevent_len[3]; + uint8_t subevents_per_event; + uint16_t subevent_interval; + uint16_t event_interval; + uint16_t procedure_interval; + uint16_t procedure_count; +} __attribute__((packed)); + +#define BLE_HCI_LE_SUBEV_CS_SUBEVENT_RESULT (0x31) +struct cs_steps_data { + uint8_t mode; + uint8_t channel; + uint8_t data_len; + uint8_t data[]; +} __attribute__((packed)); +struct ble_hci_ev_le_subev_cs_subevent_result { + uint8_t subev_code; + uint16_t conn_handle; + uint8_t config_id; + uint16_t start_acl_conn_event_counter; + uint16_t procedure_counter; + uint16_t frequency_compensation; + uint8_t reference_power_level; + uint8_t procedure_done_status; + uint8_t subevent_done_status; + uint8_t abort_reason; + uint8_t num_antenna_paths; + uint8_t num_steps_reported; + struct cs_steps_data steps[]; +} __attribute__((packed)); + +#define BLE_HCI_LE_SUBEV_CS_SUBEVENT_RESULT_CONTINUE (0x32) +struct ble_hci_ev_le_subev_cs_subevent_result_continue { + uint8_t subev_code; + uint16_t conn_handle; + uint8_t config_id; + uint8_t procedure_done_status; + uint8_t subevent_done_status; + uint8_t abort_reason; + uint8_t num_antenna_paths; + uint8_t num_steps_reported; + struct cs_steps_data steps[]; +} __attribute__((packed)); + +#define BLE_HCI_LE_SUBEV_CS_TEST_END_COMPLETE (0x33) +struct ble_hci_ev_le_subev_cs_test_end_complete { + uint8_t subev_code; + uint8_t status; +} __attribute__((packed)); + /* Data buffer overflow event */ #define BLE_HCI_EVENT_ACL_BUF_OVERFLOW (0x01) diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index 6264d0bc2b..d19702790f 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -115,6 +115,11 @@ syscfg.defs: restrictions: - 'BLE_ISO if 1' + BLE_CHANNEL_SOUNDING: + description: > + This enables Channel Sounding feature + value: 0 + BLE_HCI_VS: description: > Enables support for NimBLE specific vendor HCI commands diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml index febe09d401..7e8ea9357d 100644 --- a/nimble/transport/syscfg.yml +++ b/nimble/transport/syscfg.yml @@ -117,3 +117,7 @@ $import: syscfg.vals.'BLE_EXT_ADV || BLE_LL_CFG_FEAT_LL_EXT_ADV': BLE_TRANSPORT_EVT_SIZE: 257 + +syscfg.vals.'BLE_CHANNEL_SOUNDING && !(BLE_EXT_ADV || BLE_LL_CFG_FEAT_LL_EXT_ADV)': + # A larger buffer is needed to sent the FAE table. + BLE_TRANSPORT_EVT_SIZE: 78 From f639326653bad3be44eeeaddf2b0fe77d2022419 Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Thu, 29 Feb 2024 10:41:06 +0100 Subject: [PATCH 0973/1333] nimble: controller: Add initial support for CS HCI Add stubs for Channel Sounding. --- nimble/controller/include/controller/ble_ll.h | 83 ++++++------ .../controller/include/controller/ble_ll_cs.h | 51 ++++++++ nimble/controller/src/ble_ll.c | 5 + nimble/controller/src/ble_ll_cs.c | 119 ++++++++++++++++++ nimble/controller/src/ble_ll_hci.c | 47 +++++++ nimble/controller/syscfg.yml | 8 ++ 6 files changed, 273 insertions(+), 40 deletions(-) create mode 100644 nimble/controller/include/controller/ble_ll_cs.h create mode 100644 nimble/controller/src/ble_ll_cs.c diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 0b5e1d52cb..752ca43e97 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -245,46 +245,49 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats; #endif /* LL Features */ -#define BLE_LL_FEAT_LE_ENCRYPTION (0x0000000001) -#define BLE_LL_FEAT_CONN_PARM_REQ (0x0000000002) -#define BLE_LL_FEAT_EXTENDED_REJ (0x0000000004) -#define BLE_LL_FEAT_PERIPH_INIT (0x0000000008) -#define BLE_LL_FEAT_LE_PING (0x0000000010) -#define BLE_LL_FEAT_DATA_LEN_EXT (0x0000000020) -#define BLE_LL_FEAT_LL_PRIVACY (0x0000000040) -#define BLE_LL_FEAT_EXT_SCAN_FILT (0x0000000080) -#define BLE_LL_FEAT_LE_2M_PHY (0x0000000100) -#define BLE_LL_FEAT_STABLE_MOD_ID_TX (0x0000000200) -#define BLE_LL_FEAT_STABLE_MOD_ID_RX (0x0000000400) -#define BLE_LL_FEAT_LE_CODED_PHY (0x0000000800) -#define BLE_LL_FEAT_EXT_ADV (0x0000001000) -#define BLE_LL_FEAT_PERIODIC_ADV (0x0000002000) -#define BLE_LL_FEAT_CSA2 (0x0000004000) -#define BLE_LL_FEAT_LE_POWER_CLASS_1 (0x0000008000) -#define BLE_LL_FEAT_MIN_USED_CHAN (0x0000010000) -#define BLE_LL_FEAT_CTE_REQ (0x0000020000) -#define BLE_LL_FEAT_CTE_RSP (0x0000040000) -#define BLE_LL_FEAT_CTE_TX (0x0000080000) -#define BLE_LL_FEAT_CTE_RX (0x0000100000) -#define BLE_LL_FEAT_CTE_AOD (0x0000200000) -#define BLE_LL_FEAT_CTE_AOA (0x0000400000) -#define BLE_LL_FEAT_CTE_RECV (0x0000800000) -#define BLE_LL_FEAT_SYNC_TRANS_SEND (0x0001000000) -#define BLE_LL_FEAT_SYNC_TRANS_RECV (0x0002000000) -#define BLE_LL_FEAT_SCA_UPDATE (0x0004000000) -#define BLE_LL_FEAT_REM_PKEY (0x0008000000) -#define BLE_LL_FEAT_CIS_CENTRAL (0x0010000000) -#define BLE_LL_FEAT_CIS_PERIPH (0x0020000000) -#define BLE_LL_FEAT_ISO_BROADCASTER (0x0040000000) -#define BLE_LL_FEAT_SYNC_RECV (0x0080000000) -#define BLE_LL_FEAT_CIS_HOST (0x0100000000) -#define BLE_LL_FEAT_POWER_CTRL_REQ (0x0200000000) -#define BLE_LL_FEAT_POWER_CHANGE_IND (0x0400000000) -#define BLE_LL_FEAT_PATH_LOSS_MON (0x0800000000) -#define BLE_LL_FEAT_PERIODIC_ADV_ADI (0x1000000000) -#define BLE_LL_FEAT_CONN_SUBRATING (0x2000000000) -#define BLE_LL_FEAT_CONN_SUBRATING_HOST (0x4000000000) -#define BLE_LL_FEAT_CHANNEL_CLASS (0x8000000000) +#define BLE_LL_FEAT_LE_ENCRYPTION (0x0000000000001) +#define BLE_LL_FEAT_CONN_PARM_REQ (0x0000000000002) +#define BLE_LL_FEAT_EXTENDED_REJ (0x0000000000004) +#define BLE_LL_FEAT_PERIPH_INIT (0x0000000000008) +#define BLE_LL_FEAT_LE_PING (0x0000000000010) +#define BLE_LL_FEAT_DATA_LEN_EXT (0x0000000000020) +#define BLE_LL_FEAT_LL_PRIVACY (0x0000000000040) +#define BLE_LL_FEAT_EXT_SCAN_FILT (0x0000000000080) +#define BLE_LL_FEAT_LE_2M_PHY (0x0000000000100) +#define BLE_LL_FEAT_STABLE_MOD_ID_TX (0x0000000000200) +#define BLE_LL_FEAT_STABLE_MOD_ID_RX (0x0000000000400) +#define BLE_LL_FEAT_LE_CODED_PHY (0x0000000000800) +#define BLE_LL_FEAT_EXT_ADV (0x0000000001000) +#define BLE_LL_FEAT_PERIODIC_ADV (0x0000000002000) +#define BLE_LL_FEAT_CSA2 (0x0000000004000) +#define BLE_LL_FEAT_LE_POWER_CLASS_1 (0x0000000008000) +#define BLE_LL_FEAT_MIN_USED_CHAN (0x0000000010000) +#define BLE_LL_FEAT_CTE_REQ (0x0000000020000) +#define BLE_LL_FEAT_CTE_RSP (0x0000000040000) +#define BLE_LL_FEAT_CTE_TX (0x0000000080000) +#define BLE_LL_FEAT_CTE_RX (0x0000000100000) +#define BLE_LL_FEAT_CTE_AOD (0x0000000200000) +#define BLE_LL_FEAT_CTE_AOA (0x0000000400000) +#define BLE_LL_FEAT_CTE_RECV (0x0000000800000) +#define BLE_LL_FEAT_SYNC_TRANS_SEND (0x0000001000000) +#define BLE_LL_FEAT_SYNC_TRANS_RECV (0x0000002000000) +#define BLE_LL_FEAT_SCA_UPDATE (0x0000004000000) +#define BLE_LL_FEAT_REM_PKEY (0x0000008000000) +#define BLE_LL_FEAT_CIS_CENTRAL (0x0000010000000) +#define BLE_LL_FEAT_CIS_PERIPH (0x0000020000000) +#define BLE_LL_FEAT_ISO_BROADCASTER (0x0000040000000) +#define BLE_LL_FEAT_SYNC_RECV (0x0000080000000) +#define BLE_LL_FEAT_CIS_HOST (0x0000100000000) +#define BLE_LL_FEAT_POWER_CTRL_REQ (0x0000200000000) +#define BLE_LL_FEAT_POWER_CHANGE_IND (0x0000400000000) +#define BLE_LL_FEAT_PATH_LOSS_MON (0x0000800000000) +#define BLE_LL_FEAT_PERIODIC_ADV_ADI (0x0001000000000) +#define BLE_LL_FEAT_CONN_SUBRATING (0x0002000000000) +#define BLE_LL_FEAT_CONN_SUBRATING_HOST (0x0004000000000) +#define BLE_LL_FEAT_CHANNEL_CLASS (0x0008000000000) +#define BLE_LL_FEAT_CS (0x0400000000000) +#define BLE_LL_FEAT_CS_HOST_SUPPORT (0x0800000000000) +#define BLE_LL_FEAT_CS_PCT_QUALITY_IND (0x1000000000000) /* This is initial mask, so if feature exchange will not happen, * but host will want to use this procedure, we will try. If not diff --git a/nimble/controller/include/controller/ble_ll_cs.h b/nimble/controller/include/controller/ble_ll_cs.h new file mode 100644 index 0000000000..fb7cb4a59b --- /dev/null +++ b/nimble/controller/include/controller/ble_ll_cs.h @@ -0,0 +1,51 @@ +/* + * 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. + */ + +/* All Channel Sounding APIs are experimental and subject to change at any time */ + +#ifndef H_BLE_LL_CS +#define H_BLE_LL_CS + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* HCI handlers */ +int ble_ll_cs_hci_rd_loc_supp_cap(uint8_t *rspbuf, uint8_t *rsplen); +int ble_ll_cs_hci_rd_rem_supp_cap(const uint8_t *cmdbuf, uint8_t cmdlen); +int ble_ll_cs_hci_wr_cached_rem_supp_cap(const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen); +int ble_ll_cs_hci_sec_enable(const uint8_t *cmdbuf, uint8_t cmdlen); +int ble_ll_cs_hci_set_def_settings(const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen); +int ble_ll_cs_hci_rd_rem_fae(const uint8_t *cmdbuf, uint8_t cmdlen); +int ble_ll_cs_hci_wr_cached_rem_fae(const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen); +int ble_ll_cs_hci_create_config(const uint8_t *cmdbuf, uint8_t cmdlen); +int ble_ll_cs_hci_remove_config(const uint8_t *cmdbuf, uint8_t cmdlen); +int ble_ll_cs_hci_set_chan_class(const uint8_t *cmdbuf, uint8_t cmdlen); +int ble_ll_cs_hci_set_proc_params(const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen); +int ble_ll_cs_hci_proc_enable(const uint8_t *cmdbuf, uint8_t cmdlen); +int ble_ll_cs_hci_test(const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen); +int ble_ll_cs_hci_test_end(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 998f8d4f03..7e87891ab5 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1930,6 +1930,11 @@ ble_ll_init(void) features |= BLE_LL_FEAT_CONN_SUBRATING; #endif +#if MYNEWT_VAL(BLE_LL_CHANNEL_SOUNDING) + features |= BLE_LL_FEAT_CS; + features |= BLE_LL_FEAT_CS_PCT_QUALITY_IND; +#endif + lldata->ll_supp_features = features; /* Initialize random number generation */ diff --git a/nimble/controller/src/ble_ll_cs.c b/nimble/controller/src/ble_ll_cs.c new file mode 100644 index 0000000000..a9a181a849 --- /dev/null +++ b/nimble/controller/src/ble_ll_cs.c @@ -0,0 +1,119 @@ +/* + * 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. + */ + +#include +#if MYNEWT_VAL(BLE_LL_CHANNEL_SOUNDING) +#include +#include "nimble/hci_common.h" +#include "controller/ble_ll_utils.h" +#include "controller/ble_ll.h" +#include "controller/ble_ll_conn.h" +#include "controller/ble_ll_hci.h" +#include "controller/ble_ll_cs.h" + +int +ble_ll_cs_hci_rd_loc_supp_cap(uint8_t *rspbuf, uint8_t *rsplen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_cs_hci_rd_rem_supp_cap(const uint8_t *cmdbuf, uint8_t cmdlen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_cs_hci_wr_cached_rem_supp_cap(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_cs_hci_sec_enable(const uint8_t *cmdbuf, uint8_t cmdlen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_cs_hci_set_def_settings(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_cs_hci_rd_rem_fae(const uint8_t *cmdbuf, uint8_t cmdlen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_cs_hci_wr_cached_rem_fae(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_cs_hci_create_config(const uint8_t *cmdbuf, uint8_t cmdlen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_cs_hci_remove_config(const uint8_t *cmdbuf, uint8_t cmdlen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_cs_hci_set_chan_class(const uint8_t *cmdbuf, uint8_t cmdlen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_cs_hci_set_proc_params(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_cs_hci_proc_enable(const uint8_t *cmdbuf, uint8_t cmdlen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_cs_hci_test(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + return BLE_ERR_UNSUPPORTED; +} + +int +ble_ll_cs_hci_test_end(void) +{ + return BLE_ERR_UNSUPPORTED; +} + +#endif /* BLE_LL_CHANNEL_SOUNDING */ diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 6e5f46891a..f75e4ddbaa 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -37,6 +37,7 @@ #include "controller/ble_ll_isoal.h" #include "controller/ble_ll_iso.h" #include "controller/ble_ll_iso_big.h" +#include "controller/ble_ll_cs.h" #include "ble_ll_priv.h" #include "ble_ll_conn_priv.h" #include "ble_ll_hci_priv.h" @@ -1315,6 +1316,52 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, case BLE_HCI_OCF_LE_SUBRATE_REQ: rc = ble_ll_conn_hci_subrate_req(cmdbuf, len, rspbuf, rsplen); break; +#endif +#if MYNEWT_VAL(BLE_LL_CHANNEL_SOUNDING) + case BLE_HCI_OCF_LE_CS_RD_LOC_SUPP_CAP: + rc = ble_ll_cs_hci_rd_loc_supp_cap(rspbuf, rsplen); + break; + case BLE_HCI_OCF_LE_CS_RD_REM_SUPP_CAP: + rc = ble_ll_cs_hci_rd_rem_supp_cap(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_CS_WR_CACHED_REM_SUPP_CAP: + rc = ble_ll_cs_hci_wr_cached_rem_supp_cap(cmdbuf, len, rspbuf, rsplen); + break; +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_HCI_OCF_LE_CS_SEC_ENABLE: + rc = ble_ll_cs_hci_sec_enable(cmdbuf, len); + break; +#endif + case BLE_HCI_OCF_LE_CS_SET_DEF_SETTINGS: + rc = ble_ll_cs_hci_set_def_settings(cmdbuf, len, rspbuf, rsplen); + break; + case BLE_HCI_OCF_LE_CS_RD_REM_FAE: + rc = ble_ll_cs_hci_rd_rem_fae(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_CS_WR_CACHED_REM_FAE: + rc = ble_ll_cs_hci_wr_cached_rem_fae(cmdbuf, len, rspbuf, rsplen); + break; + case BLE_HCI_OCF_LE_CS_CREATE_CONFIG: + rc = ble_ll_cs_hci_create_config(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_CS_REMOVE_CONFIG: + rc = ble_ll_cs_hci_remove_config(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_CS_SET_CHAN_CLASS: + rc = ble_ll_cs_hci_set_chan_class(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_CS_SET_PROC_PARAMS: + rc = ble_ll_cs_hci_set_proc_params(cmdbuf, len, rspbuf, rsplen); + break; + case BLE_HCI_OCF_LE_CS_PROC_ENABLE: + rc = ble_ll_cs_hci_proc_enable(cmdbuf, len); + break; + case BLE_HCI_OCF_LE_CS_TEST: + rc = ble_ll_cs_hci_test(cmdbuf, len, rspbuf, rsplen); + break; + case BLE_HCI_OCF_LE_CS_TEST_END: + rc = ble_ll_cs_hci_test_end(); + break; #endif default: rc = BLE_ERR_UNKNOWN_HCI_CMD; diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 8a32e2e028..ce8fad1e9a 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -516,6 +516,14 @@ syscfg.defs: value: 0 experimental: 1 + BLE_LL_CHANNEL_SOUNDING: + description: > + Enable support for Channel Sounding feature. + restrictions: + - (BLE_VERSION >= 54) if 1 + value: MYNEWT_VAL(BLE_CHANNEL_SOUNDING) + state: experimental + BLE_LL_SYSINIT_STAGE: description: > Sysinit stage for the NimBLE controller. From b02b39bfb193a6bd9ffef3d6cab6b71712abd803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 9 Apr 2024 11:21:55 +0200 Subject: [PATCH 0974/1333] host/audio/ble_iso.c: fix deallocation of BIS Freeing memory back to BIS pool in loop while changing removing ISO connections from list lead to memory leak. Now, memory is freed in separate loop. --- nimble/host/src/ble_iso.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_iso.c b/nimble/host/src/ble_iso.c index 004b1fc474..af728d135c 100644 --- a/nimble/host/src/ble_iso.c +++ b/nimble/host/src/ble_iso.c @@ -205,6 +205,10 @@ static int ble_iso_big_free(struct ble_iso_big *big) { struct ble_iso_conn *conn; + struct ble_iso_bis *rem_bis[MYNEWT_VAL(BLE_ISO_MAX_BISES)] = { + [0 ... MYNEWT_VAL(BLE_ISO_MAX_BISES) - 1] = NULL + }; + uint8_t i = 0; SLIST_FOREACH(conn, &ble_iso_conns, next) { struct ble_iso_bis *bis; @@ -216,10 +220,14 @@ ble_iso_big_free(struct ble_iso_big *big) bis = CONTAINER_OF(conn, struct ble_iso_bis, conn); if (bis->big == big) { SLIST_REMOVE(&ble_iso_conns, conn, ble_iso_conn, next); - os_memblock_put(&ble_iso_bis_pool, bis); + rem_bis[i++] = bis; } } + while (i > 0) { + os_memblock_put(&ble_iso_bis_pool, rem_bis[--i]); + } + SLIST_REMOVE(&ble_iso_bigs, big, ble_iso_big, next); os_memblock_put(&ble_iso_big_pool, big); return 0; From 66147e7c811f1eec4acb41d524c2bf9484fa7b67 Mon Sep 17 00:00:00 2001 From: Guy Mishol Date: Wed, 10 Apr 2024 10:24:31 +0300 Subject: [PATCH 0975/1333] nimble/transport: Fix mempool alignment Change transport pool buffers type from uint8_t to os_membuf_t to ensure the required address OS alignment. --- nimble/transport/src/transport.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nimble/transport/src/transport.c b/nimble/transport/src/transport.c index c9b37a7e94..99c11c266a 100644 --- a/nimble/transport/src/transport.c +++ b/nimble/transport/src/transport.c @@ -70,23 +70,23 @@ BLE_MBUF_MEMBLOCK_OVERHEAD + \ BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT)) -static uint8_t pool_cmd_buf[ OS_MEMPOOL_BYTES(POOL_CMD_COUNT, POOL_CMD_SIZE) ]; +static os_membuf_t pool_cmd_buf[ OS_MEMPOOL_SIZE(POOL_CMD_COUNT, POOL_CMD_SIZE) ]; static struct os_mempool pool_cmd; -static uint8_t pool_evt_buf[ OS_MEMPOOL_BYTES(POOL_EVT_COUNT, POOL_EVT_SIZE) ]; +static os_membuf_t pool_evt_buf[ OS_MEMPOOL_SIZE(POOL_EVT_COUNT, POOL_EVT_SIZE) ]; static struct os_mempool pool_evt; -static uint8_t pool_evt_lo_buf[ OS_MEMPOOL_BYTES(POOL_EVT_LO_COUNT, POOL_EVT_SIZE) ]; +static os_membuf_t pool_evt_lo_buf[ OS_MEMPOOL_SIZE(POOL_EVT_LO_COUNT, POOL_EVT_SIZE) ]; static struct os_mempool pool_evt_lo; #if POOL_ACL_COUNT > 0 -static uint8_t pool_acl_buf[ OS_MEMPOOL_BYTES(POOL_ACL_COUNT, POOL_ACL_SIZE) ]; +static os_membuf_t pool_acl_buf[ OS_MEMPOOL_SIZE(POOL_ACL_COUNT, POOL_ACL_SIZE) ]; static struct os_mempool_ext pool_acl; static struct os_mbuf_pool mpool_acl; #endif #if POOL_ISO_COUNT > 0 -static uint8_t pool_iso_buf[ OS_MEMPOOL_BYTES(POOL_ISO_COUNT, POOL_ISO_SIZE) ]; +static os_membuf_t pool_iso_buf[ OS_MEMPOOL_SIZE(POOL_ISO_COUNT, POOL_ISO_SIZE) ]; static struct os_mempool_ext pool_iso; static struct os_mbuf_pool mpool_iso; #endif From 533c122b10b22be9ecbaae79efc78a7f113eaa09 Mon Sep 17 00:00:00 2001 From: Guy Mishol Date: Wed, 10 Apr 2024 10:45:32 +0300 Subject: [PATCH 0976/1333] nimble/ble_gap: remove extraneous parentheses Fix build warning generated with llvm based compilers on equality comparison with extraneous parentheses. --- nimble/host/src/ble_gap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index b264efd5c9..44d57707ad 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -3720,7 +3720,7 @@ ble_gap_ext_adv_clear(void) /* If there is an active instance or periodic adv instance, * Don't send the command * */ - if ((ble_gap_slave[instance].op == BLE_GAP_OP_S_ADV)) { + if (ble_gap_slave[instance].op == BLE_GAP_OP_S_ADV) { ble_hs_unlock(); return BLE_HS_EBUSY; } From d38ca0a1c629b6f0b429152ffa34e3dd26be8df0 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 9 Apr 2024 13:42:48 +0200 Subject: [PATCH 0977/1333] nimble/porting: Fix Linux MESH sample Sample was missing call bt_mesh_prov_enable() and thus was not handling provisioning. --- porting/examples/linux_blemesh/ble.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/porting/examples/linux_blemesh/ble.c b/porting/examples/linux_blemesh/ble.c index 277481d21c..381c6299a8 100644 --- a/porting/examples/linux_blemesh/ble.c +++ b/porting/examples/linux_blemesh/ble.c @@ -426,6 +426,8 @@ blemesh_on_sync(void) if (bt_mesh_is_provisioned()) { printk("Mesh network restored from flash\n"); } + + bt_mesh_prov_enable(BT_MESH_PROV_GATT | BT_MESH_PROV_ADV); } void From c433982091da1811d13d4df12478548ccebf5ade Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 9 Apr 2024 13:43:39 +0200 Subject: [PATCH 0978/1333] nimble/mesh: Fix handling of connection handle value Connection handle is not guaranteed to start from 0. --- nimble/host/mesh/src/proxy_msg.c | 45 +++++++++++++++++++++++++++++--- nimble/host/mesh/src/proxy_msg.h | 6 ++++- nimble/host/mesh/src/proxy_srv.c | 9 +++++-- 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/nimble/host/mesh/src/proxy_msg.c b/nimble/host/mesh/src/proxy_msg.c index e3aff56274..ef03b7d7cf 100644 --- a/nimble/host/mesh/src/proxy_msg.c +++ b/nimble/host/mesh/src/proxy_msg.c @@ -61,7 +61,7 @@ static void proxy_sar_timeout(struct ble_npl_event *work) BT_WARN("Proxy SAR timeout"); - if (role->conn_handle) { + if (role->conn_handle != BLE_HS_CONN_HANDLE_NONE) { rc = ble_gap_terminate(role->conn_handle, BLE_ERR_REM_USER_CONN_TERM); assert(rc == 0); @@ -194,7 +194,7 @@ static void proxy_msg_init(struct bt_mesh_proxy_role *role) role->buf = NET_BUF_SIMPLE(CONFIG_BT_MESH_PROXY_MSG_LEN); net_buf_simple_init_with_data(role->buf, - &bufs[role->conn_handle * + &bufs[role->index * CONFIG_BT_MESH_PROXY_MSG_LEN], CONFIG_BT_MESH_PROXY_MSG_LEN); @@ -204,15 +204,42 @@ static void proxy_msg_init(struct bt_mesh_proxy_role *role) k_work_add_arg_delayable(&role->sar_timer, role); } +struct bt_mesh_proxy_role *bt_mesh_proxy_role_find_with_buf(const struct os_mbuf *buf) +{ + unsigned int i; + + for (i = 0; i < CONFIG_BT_MAX_CONN; i++) { + if (roles[i].buf == buf) { + return &roles[i]; + } + } + + return NULL; +} + +struct bt_mesh_proxy_role *get_role(uint16_t conn_handle) +{ + unsigned int i; + + for (i = 0; i < CONFIG_BT_MAX_CONN; i++) { + if (roles[i].conn_handle == BLE_HS_CONN_HANDLE_NONE) { + roles[i].conn_handle = conn_handle; + return &roles[i]; + } + } + + return NULL; +} + struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(uint16_t conn_handle, proxy_send_cb_t send, proxy_recv_cb_t recv) { struct bt_mesh_proxy_role *role; - role = &roles[conn_handle]; + role = get_role(conn_handle); + assert(role); - role->conn_handle = conn_handle; proxy_msg_init(role); role->cb.recv = recv; @@ -234,4 +261,14 @@ void bt_mesh_proxy_role_cleanup(struct bt_mesh_proxy_role *role) bt_mesh_adv_update(); } +void bt_mesh_proxy_msg_init(void) +{ + unsigned int i; + + for (i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); i++) { + roles[i].index = i; + roles[i].conn_handle = 0xffff; + } +} + #endif /* MYNEWT_VAL(BLE_MESH_PROXY) */ diff --git a/nimble/host/mesh/src/proxy_msg.h b/nimble/host/mesh/src/proxy_msg.h index dabe7e80ce..447224bcd0 100644 --- a/nimble/host/mesh/src/proxy_msg.h +++ b/nimble/host/mesh/src/proxy_msg.h @@ -31,6 +31,7 @@ typedef int (*proxy_send_cb_t)(uint16_t conn_handle, typedef void (*proxy_recv_cb_t)(struct bt_mesh_proxy_role *role); struct bt_mesh_proxy_role { + unsigned int index; uint16_t conn_handle; uint8_t msg_type; @@ -58,10 +59,13 @@ struct bt_mesh_proxy_client { int bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, const void *buf, uint16_t len); int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, struct os_mbuf *msg); -void bt_mesh_proxy_msg_init(struct bt_mesh_proxy_role *role); void bt_mesh_proxy_role_cleanup(struct bt_mesh_proxy_role *role); struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(uint16_t conn_handle, proxy_send_cb_t send, proxy_recv_cb_t recv); struct bt_mesh_proxy_client *find_client(uint16_t conn_handle); + +struct bt_mesh_proxy_role *bt_mesh_proxy_role_find_with_buf(const struct os_mbuf *buf); + +void bt_mesh_proxy_msg_init(void); #endif /* ZEPHYR_SUBSYS_BLUETOOTH_MESH_PROXY_MSG_H_ */ diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index 15939cfea6..22d9082cd1 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -720,10 +720,13 @@ int bt_mesh_proxy_gatt_disable(void) void bt_mesh_proxy_addr_add(struct os_mbuf *buf, uint16_t addr) { struct bt_mesh_proxy_client *client; - struct bt_mesh_proxy_role *cli = - CONTAINER_OF(buf, struct bt_mesh_proxy_role, buf); + struct bt_mesh_proxy_role *cli; + + cli = bt_mesh_proxy_role_find_with_buf(buf); + assert(cli); client = find_client(cli->conn_handle); + assert(client); BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr); @@ -997,6 +1000,8 @@ int bt_mesh_proxy_init(void) clients[i].conn_handle = 0xffff; } + bt_mesh_proxy_msg_init(); + resolve_svc_handles(); ble_gatts_svc_set_visibility(svc_handles.proxy_h, 0); From c753751dddd249a0036a6b7b6529f5a3904c2ed8 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Wed, 10 Apr 2024 11:20:55 +0200 Subject: [PATCH 0979/1333] nimble/services: Fix incorrect PACS characteristic notification This commit provides fix for incorrect PACS characteristic sending notification after changing it's state. --- nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c b/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c index 9b124a5a97..d91722fc8d 100644 --- a/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c +++ b/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c @@ -385,7 +385,7 @@ ble_svc_audio_pacs_set(uint8_t flags, struct ble_svc_audio_pacs_set_param *param if (flags & BLE_AUDIO_CODEC_DIR_SINK_BIT) { ble_svc_audio_pacs_sink_audio_locations = param->audio_locations; ble_svc_audio_pacs_sup_sink_contexts = param->supported_contexts; - rc = pac_notify(BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_AUDIO_LOCATIONS); + rc = pac_notify(BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_AUDIO_LOCATIONS); if (rc != 0) { return rc; } From c315860ba6ef2c5e8ea03eddfeebc6bd87226091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 10 Apr 2024 12:30:36 +0200 Subject: [PATCH 0980/1333] host/audio/pacs: fix possible NULL dereference avail_ctx may be null. --- .../audio/services/pacs/src/ble_audio_svc_pacs.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c b/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c index d91722fc8d..25b2e04900 100644 --- a/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c +++ b/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c @@ -257,6 +257,9 @@ ble_svc_audio_pacs_avail_audio_ctx_read_access(uint16_t conn_handle, uint8_t *buf; avail_ctx = ble_svc_audio_pacs_find_avail_ctx(conn_handle); + if (!avail_ctx) { + return BLE_HS_ENOENT; + } buf = os_mbuf_extend(ctxt->om, 4); if (buf == NULL) { @@ -400,6 +403,9 @@ ble_svc_audio_pacs_avail_contexts_set(uint16_t conn_handle, uint16_t source_contexts) { struct available_ctx *avail_ctx = ble_svc_audio_pacs_find_avail_ctx(conn_handle); + if (!avail_ctx) { + return BLE_HS_ENOENT; + } avail_ctx->ble_svc_audio_pacs_avail_sink_contexts = sink_contexts; avail_ctx->ble_svc_audio_pacs_avail_source_contexts = source_contexts; @@ -441,10 +447,18 @@ ble_pacs_gap_event(struct ble_gap_event *event, void *arg) break; } avail_ctx = ble_svc_audio_pacs_find_avail_ctx(BLE_HS_CONN_HANDLE_NONE); + if (!avail_ctx) { + return BLE_HS_ENOENT; + } + avail_ctx->conn_handle = event->connect.conn_handle; break; case BLE_GAP_EVENT_DISCONNECT: avail_ctx = ble_svc_audio_pacs_find_avail_ctx(event->disconnect.conn.conn_handle); + if (!avail_ctx) { + return BLE_HS_ENOENT; + } + if (avail_ctx >= 0) { avail_ctx->conn_handle = BLE_HS_CONN_HANDLE_NONE; } From 1e9ba4655421a3e3322d497124c17c0222abc865 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Thu, 11 Apr 2024 09:54:54 +0200 Subject: [PATCH 0981/1333] syscfg: fix typo --- nimble/host/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index 93dbcd2ed9..873dcae4bf 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -526,7 +526,7 @@ syscfg.defs: value: 1 BLE_ISO_MAX_BIGS: - desciptrion: > + description: > Number of available BIGs value: 'MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES' restrictions: From 5599a15369c294b916eba093889b0a9960f7b05c Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Thu, 11 Apr 2024 11:53:37 +0200 Subject: [PATCH 0982/1333] nimble/ll: fix ifdef ble_ll_ctrl_phy_update_ind_instant() is called from another function inside #if MYNEWT_VAL(BLE_LL_PHY), but it was defined only if ROLE_CENTRAL was enabled --- nimble/controller/src/ble_ll_ctrl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 6eb883c82f..d2b8a31b7b 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -856,7 +856,9 @@ ble_ll_ctrl_phy_update_ind_make(struct ble_ll_conn_sm *connsm, uint8_t *dptr, ctrdata[0] = m_to_s; ctrdata[1] = s_to_m; } +#endif +#if MYNEWT_VAL(BLE_LL_PHY) static bool ble_ll_ctrl_phy_update_ind_instant(struct ble_ll_conn_sm *connsm, uint8_t *ctrdata) { From 7b0a2d7d3044a06e4f03a5dd652e07c34054c61f Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Mon, 25 Mar 2024 16:05:29 +0100 Subject: [PATCH 0983/1333] nimble/host: Fix compilation error in ble_store_config.c This should fix compilation error when -O2 optimization is enabled. GCC incorrectly detects problem. This change adds asserts that convinces GCC that pre-condition will not result in accessing memory out-of-bounds. This also changes one condition that also contributes to make GCC convinced that pre-condition are met. Error: In function 'ble_store_config_delete_obj', inlined from 'ble_store_config_delete_cccd' at repos/apache-mynewt-nimble/nimble/host/store/config/src/ble_store_config.c:380:10, inlined from 'ble_store_config_delete' at repos/apache-mynewt-nimble/nimble/host/store/config/src/ble_store_config.c:542:14: repos/apache-mynewt-nimble/nimble/host/store/config/src/ble_store_config.c:193:9: error: 'memmove' offset [16, 31] is out of the bounds [0, 16] of object 'ble_store_config_cccds' with type 'struct ble_store_value_cccd[1]' [-Werror=array-bounds] 193 | memmove(dst, src, move_count * value_size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ repos/apache-mynewt-nimble/nimble/host/store/config/src/ble_store_config.c: In function 'ble_store_config_delete': repos/apache-mynewt-nimble/nimble/host/store/config/src/ble_store_config.c:45:5: note: 'ble_store_config_cccds' declared here 45 | ble_store_config_cccds[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)]; Signed-off-by: Jerzy Kasenberg --- nimble/host/store/config/src/ble_store_config.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nimble/host/store/config/src/ble_store_config.c b/nimble/host/store/config/src/ble_store_config.c index 0ee8906c69..664b8768bf 100644 --- a/nimble/host/store/config/src/ble_store_config.c +++ b/nimble/host/store/config/src/ble_store_config.c @@ -225,6 +225,7 @@ ble_store_config_delete_our_sec(const struct ble_store_key_sec *key_sec) #if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int rc; + assert(ble_store_config_num_our_secs <= ARRAY_SIZE(ble_store_config_our_secs)); rc = ble_store_config_delete_sec(key_sec, ble_store_config_our_secs, &ble_store_config_num_our_secs); if (rc != 0) { @@ -248,6 +249,7 @@ ble_store_config_delete_peer_sec(const struct ble_store_key_sec *key_sec) #if MYNEWT_VAL(BLE_STORE_MAX_BONDS) int rc; + assert(ble_store_config_num_peer_secs <= ARRAY_SIZE(ble_store_config_peer_secs)); rc = ble_store_config_delete_sec(key_sec, ble_store_config_peer_secs, &ble_store_config_num_peer_secs); if (rc != 0) { @@ -369,10 +371,11 @@ ble_store_config_delete_cccd(const struct ble_store_key_cccd *key_cccd) int rc; idx = ble_store_config_find_cccd(key_cccd); - if (idx == -1) { + if (idx < 0) { return BLE_HS_ENOENT; } + assert(ble_store_config_num_cccds < ARRAY_SIZE(ble_store_config_cccds)); rc = ble_store_config_delete_obj(ble_store_config_cccds, sizeof *ble_store_config_cccds, idx, From 301cc998b6ca5c51cafd2f39bc5843c07a1002ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Thu, 11 Apr 2024 10:24:16 +0200 Subject: [PATCH 0984/1333] host/audio/pacs: fix notifications for available contexts Available contexts values are per connection. When value is changed, read access for notification gives BLE_HS_CONN_HANDLE_NONE as conn handle. This was making impossible to fetch the right value. Now, flag was introduced, for marking the changed value. --- .../services/pacs/src/ble_audio_svc_pacs.c | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c b/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c index 25b2e04900..eb3a9244ed 100644 --- a/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c +++ b/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c @@ -29,6 +29,7 @@ static struct available_ctx { uint16_t conn_handle; uint16_t ble_svc_audio_pacs_avail_sink_contexts; uint16_t ble_svc_audio_pacs_avail_source_contexts; + uint8_t val_changed; } ble_svc_audio_pacs_avail_contexts[MYNEWT_VAL(BLE_MAX_CONNECTIONS)] = { [0 ... MYNEWT_VAL(BLE_MAX_CONNECTIONS) - 1] = { .conn_handle = BLE_HS_CONN_HANDLE_NONE, @@ -253,12 +254,20 @@ static int ble_svc_audio_pacs_avail_audio_ctx_read_access(uint16_t conn_handle, struct ble_gatt_access_ctxt *ctxt) { - struct available_ctx *avail_ctx; + struct available_ctx *avail_ctx = NULL; uint8_t *buf; + int i; - avail_ctx = ble_svc_audio_pacs_find_avail_ctx(conn_handle); - if (!avail_ctx) { - return BLE_HS_ENOENT; + if (conn_handle == BLE_HS_CONN_HANDLE_NONE) { + for (i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); i++) { + if (ble_svc_audio_pacs_avail_contexts[i].val_changed) { + avail_ctx = &ble_svc_audio_pacs_avail_contexts[i]; + avail_ctx->val_changed = false; + break; + } + } + } else { + avail_ctx = ble_svc_audio_pacs_find_avail_ctx(conn_handle); } buf = os_mbuf_extend(ctxt->om, 4); @@ -266,6 +275,11 @@ ble_svc_audio_pacs_avail_audio_ctx_read_access(uint16_t conn_handle, return BLE_ATT_ERR_INSUFFICIENT_RES; } + if (!avail_ctx) { + put_le32(buf + 0, 0); + return 0; + } + put_le16(buf + 0, avail_ctx->ble_svc_audio_pacs_avail_sink_contexts); put_le16(buf + 2, avail_ctx->ble_svc_audio_pacs_avail_source_contexts); @@ -409,6 +423,7 @@ ble_svc_audio_pacs_avail_contexts_set(uint16_t conn_handle, avail_ctx->ble_svc_audio_pacs_avail_sink_contexts = sink_contexts; avail_ctx->ble_svc_audio_pacs_avail_source_contexts = source_contexts; + avail_ctx->val_changed = true; return pac_notify(BLE_SVC_AUDIO_PACS_CHR_UUID16_AVAILABLE_AUDIO_CONTEXTS); } From 364b720d6210e5a23314254ca9beaa8857abbedf Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Mon, 8 Apr 2024 12:08:36 +0200 Subject: [PATCH 0985/1333] nimble/bttester: Various fixes in BAP bttester part MYNEWT_VAL is corrected in multiple places for an up-to-date name. Missing semicolon and invalid function name are fixed in btp_bap.c Codec configuration is now set on BIS level, as setting it on subgroup level caused tests to fail. --- apps/bttester/src/btp/bttester.h | 4 +-- apps/bttester/src/btp_bap.c | 45 ++++++++++++++------------------ apps/bttester/src/btp_core.c | 8 +++--- apps/bttester/syscfg.yml | 2 ++ 4 files changed, 28 insertions(+), 31 deletions(-) diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h index 5d7e1219d2..7cb82b5c92 100644 --- a/apps/bttester/src/btp/bttester.h +++ b/apps/bttester/src/btp/bttester.h @@ -142,12 +142,12 @@ gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); int gatt_svr_init(void); -#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) uint8_t tester_init_bap(void); uint8_t tester_unregister_bap(void); -#endif /* MYNEWT_VAL(BLE_ISO_BROADCASTER) */ +#endif /* MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) */ #endif /* __BTTESTER_H__ */ diff --git a/apps/bttester/src/btp_bap.c b/apps/bttester/src/btp_bap.c index b6a92ac623..5a2d06c811 100644 --- a/apps/bttester/src/btp_bap.c +++ b/apps/bttester/src/btp_bap.c @@ -21,7 +21,7 @@ #include "syscfg/syscfg.h" -#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) #include "btp/btp_bap.h" @@ -38,9 +38,6 @@ #include "audio/ble_audio.h" #include "host/ble_iso.h" -#include "bsp/bsp.h" - - #define BROADCAST_ADV_INSTANCE 1 static struct ble_audio_big_subgroup big_subgroup; @@ -158,7 +155,6 @@ base_create(const struct bap_broadcast_source_setup_cmd *cmd) uint16_t chan_loc = BLE_AUDIO_LOCATION_FRONT_LEFT | BLE_AUDIO_LOCATION_FRONT_RIGHT; - uint8_t codec_spec_config[] = BLE_AUDIO_BUILD_CODEC_CONFIG(sampling_freq, frame_duration, chan_loc, max_sdu, ); @@ -166,25 +162,24 @@ base_create(const struct bap_broadcast_source_setup_cmd *cmd) tester_base.broadcast_id = sampling_freq; tester_base.presentation_delay = sampling_freq * 10000; - big_subgroup.bis_cnt = MYNEWT_VAL(BROADCASTER_CHAN_NUM); + big_subgroup.bis_cnt = MYNEWT_VAL(BLE_ISO_MAX_BISES); /** LC3 */ big_subgroup.codec_id.format = 0x06; - big_subgroup.codec_spec_config_len = sizeof(codec_spec_config); - - big_subgroup.codec_spec_config_len = os_memblock_get(&codec_spec_pool); - - memcpy(big_subgroup.codec_spec_config, - codec_spec_config, - sizeof(codec_spec_config)); + big_subgroup.codec_spec_config_len = 0; bis = os_memblock_get(&bis_pool); if (!bis) { - return BLE_HS_ENOMEM + return BLE_HS_ENOMEM; } - bis->codec_spec_config_len = 0; + bis->codec_spec_config = os_memblock_get(&codec_spec_pool); + memcpy(bis->codec_spec_config, + codec_spec_config, + sizeof(codec_spec_config)); + bis->codec_spec_config_len = sizeof(codec_spec_config); + bis->idx = 1; STAILQ_INSERT_HEAD(&big_subgroup.bises, bis, next); STAILQ_INSERT_HEAD(&tester_base.subs, &big_subgroup, next); @@ -221,6 +216,15 @@ broadcast_source_setup(const void *cmd, uint16_t cmd_len, void *rsp, base_create(source_config); + big_params.sdu_interval = sdu_interval; + big_params.max_sdu = max_sdu; + big_params.max_transport_latency = 8; + big_params.rtn = source_config->rtn; + big_params.phy = BLE_HCI_LE_PHY_2M; + big_params.packing = 0; + big_params.framing = source_config->framing; + big_params.encryption = 0; + struct ble_gap_periodic_adv_params periodic_params = { .itvl_min = 30, .itvl_max = 30, @@ -237,15 +241,6 @@ broadcast_source_setup(const void *cmd, uint16_t cmd_len, void *rsp, .sid = BROADCAST_ADV_INSTANCE, }; - big_params.sdu_interval = sdu_interval; - big_params.max_sdu = max_sdu; - big_params.max_transport_latency = 8; - big_params.rtn = source_config->rtn; - big_params.phy = BLE_HCI_LE_PHY_2M; - big_params.packing = 0; - big_params.framing = source_config->framing; - big_params.encryption = 0; - struct ble_broadcast_create_params create_params = { .base = &tester_base, .extended_params = &extended_params, @@ -422,5 +417,5 @@ tester_unregister_bap(void) return BTP_STATUS_SUCCESS; } -#endif /* MYNEWT_VAL(BLE_ISO_BROADCASTER) */ +#endif /* MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) */ diff --git a/apps/bttester/src/btp_core.c b/apps/bttester/src/btp_core.c index f7a4bc4f92..a7b1878322 100644 --- a/apps/bttester/src/btp_core.c +++ b/apps/bttester/src/btp_core.c @@ -102,11 +102,11 @@ register_service(const void *cmd, uint16_t cmd_len, status = tester_init_mesh(); break; #endif /* MYNEWT_VAL(BLE_MESH) */ -#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) case BTP_SERVICE_ID_BAP: status = tester_init_bap(); break; -#endif /* MYNEWT_VAL(BLE_ISO_BROADCASTER) */ +#endif /* MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) */ case BTP_SERVICE_ID_GATTC: status = tester_init_gatt_cl(); break; @@ -159,11 +159,11 @@ unregister_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_GATTC: status = tester_unregister_gatt_cl(); break; -#if MYNEWT_VAL(BLE_ISO_BROADCASTER) +#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) case BTP_SERVICE_ID_BAP: status = tester_unregister_bap(); break; -#endif /* MYNEWT_VAL(BLE_ISO_BROADCASTER) */ +#endif /* MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) */ default: status = BTP_STATUS_FAILED; break; diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index bb4d6f775f..80c377a7c1 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -97,6 +97,8 @@ syscfg.vals: BLE_ISO_MAX_BISES: 1 BLE_ISO_MAX_BIGS: 1 BLE_EXT_ADV: 1 + BLE_PHY_2M: 1 + BLE_EXT_ADV_MAX_SIZE: 40 BLE_PERIODIC_ADV: 1 BLE_ISO_BROADCAST_SOURCE: 1 BLE_MULTI_ADV_INSTANCES: 1 From 25bf03e1fab0c96a996a3d2dc8e6e14520edc874 Mon Sep 17 00:00:00 2001 From: Donatien Garnier Date: Fri, 12 Apr 2024 16:52:08 +0100 Subject: [PATCH 0986/1333] nimble/porting: Fix OS_MEMPOOL_SIZE() macro The OS_MEMPOOL_SIZE() macro returns an invalid size when guards are used (an additional 4 bytes must be reserved for each block, which is not done at the moment). Correct this in line with the macro defined in mynewt core. --- porting/nimble/include/os/os_mempool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porting/nimble/include/os/os_mempool.h b/porting/nimble/include/os/os_mempool.h index 71d77065ae..74bc43fe0d 100644 --- a/porting/nimble/include/os/os_mempool.h +++ b/porting/nimble/include/os/os_mempool.h @@ -164,7 +164,7 @@ typedef __uint128_t os_membuf_t; #else #error "Unhandled `OS_ALIGNMENT` for `os_membuf_t`" #endif /* OS_ALIGNMENT == * */ -#define OS_MEMPOOL_SIZE(n,blksize) ((((blksize) + ((OS_ALIGNMENT)-1)) / (OS_ALIGNMENT)) * (n)) +#define OS_MEMPOOL_SIZE(n,blksize) (((OS_MEMPOOL_BLOCK_SZ(blksize) + ((OS_ALIGNMENT)-1)) / (OS_ALIGNMENT)) * (n)) /** Calculates the number of bytes required to initialize a memory pool. */ #define OS_MEMPOOL_BYTES(n,blksize) \ From 1cf220fd12b49e92733a16831653329d6a34eb2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 15 Apr 2024 07:02:37 +0200 Subject: [PATCH 0987/1333] host/audio/pacs: verify if set available contexts are supported We shouldn't allow to set available contexts that are not set to be supported. --- nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c b/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c index eb3a9244ed..92155f41e4 100644 --- a/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c +++ b/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c @@ -421,6 +421,11 @@ ble_svc_audio_pacs_avail_contexts_set(uint16_t conn_handle, return BLE_HS_ENOENT; } + if ((sink_contexts & ble_svc_audio_pacs_sup_sink_contexts) != sink_contexts || + (source_contexts & ble_svc_audio_pacs_sup_source_contexts) != source_contexts) { + return BLE_HS_ENOTSUP; + } + avail_ctx->ble_svc_audio_pacs_avail_sink_contexts = sink_contexts; avail_ctx->ble_svc_audio_pacs_avail_source_contexts = source_contexts; avail_ctx->val_changed = true; From c42d6a8cfc1d7d2797af35e0f8839cdab917033e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 15 Apr 2024 07:06:41 +0200 Subject: [PATCH 0988/1333] host/audio/pacs: allow ble_svc_audio_pacs_set params to be static const This allows to params to be static const without any casting. --- .../services/pacs/include/services/pacs/ble_audio_svc_pacs.h | 2 +- nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/host/audio/services/pacs/include/services/pacs/ble_audio_svc_pacs.h b/nimble/host/audio/services/pacs/include/services/pacs/ble_audio_svc_pacs.h index fdbcbeef9f..9410c7b0f7 100644 --- a/nimble/host/audio/services/pacs/include/services/pacs/ble_audio_svc_pacs.h +++ b/nimble/host/audio/services/pacs/include/services/pacs/ble_audio_svc_pacs.h @@ -71,7 +71,7 @@ struct ble_svc_audio_pacs_set_param { * @return 0 on success; * A non-zero value on failure. */ -int ble_svc_audio_pacs_set(uint8_t flags, struct ble_svc_audio_pacs_set_param *param); +int ble_svc_audio_pacs_set(uint8_t flags, const struct ble_svc_audio_pacs_set_param *param); /** * @brief Set available context types. diff --git a/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c b/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c index 92155f41e4..ef53f94ac5 100644 --- a/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c +++ b/nimble/host/audio/services/pacs/src/ble_audio_svc_pacs.c @@ -386,7 +386,7 @@ pac_notify(uint16_t chrc_uuid) } int -ble_svc_audio_pacs_set(uint8_t flags, struct ble_svc_audio_pacs_set_param *param) +ble_svc_audio_pacs_set(uint8_t flags, const struct ble_svc_audio_pacs_set_param *param) { int rc; From 2e20f9957592e53d5ac74556a795445bdd65c774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Mon, 15 Apr 2024 07:18:55 +0200 Subject: [PATCH 0989/1333] host/audio/pacs: fix doxygen - Added descriptions for UUIDs - removed /ref to function in different file - added description for ble_svc_audio_pacs_set_param --- .../services/pacs/ble_audio_svc_pacs.h | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/nimble/host/audio/services/pacs/include/services/pacs/ble_audio_svc_pacs.h b/nimble/host/audio/services/pacs/include/services/pacs/ble_audio_svc_pacs.h index 9410c7b0f7..1949297d84 100644 --- a/nimble/host/audio/services/pacs/include/services/pacs/ble_audio_svc_pacs.h +++ b/nimble/host/audio/services/pacs/include/services/pacs/ble_audio_svc_pacs.h @@ -31,7 +31,7 @@ * @ingroup bt_host * @{ * - * This package is used to setup PACS for codecs registered with @ref ble_audio_codec. + * This package is used to setup PACS for codecs registered with ble_audio_codec. * To register a codec create it's definition as `ble_audio_codec_record` structure and register it * using `ble_audio_codec_register()`. Up to BLE_AUDIO_MAX_CODEC_RECORDS entries may be registered. * Registering and unregistering codecs, as well as setting PACS parameters will trigger sending @@ -39,20 +39,33 @@ * */ +/** BLE Audio Published Audio Capabilities Service UUID */ #define BLE_SVC_AUDIO_PACS_UUID16 0x1850 + +/** BLE Audio Published Audio Capabilities Service Sink PAC characteristic UUID */ #define BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_PAC 0x2BC9 + +/** BLE Audio Published Audio Capabilities Service Sink Audio Locations characteristic UUID */ #define BLE_SVC_AUDIO_PACS_CHR_UUID16_SINK_AUDIO_LOCATIONS 0x2BCA + +/** BLE Audio Published Audio Capabilities Service Source PAC characteristic UUID */ #define BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_PAC 0x2BCB + +/** BLE Audio Published Audio Capabilities Service Source Audio Locations characteristic UUID */ #define BLE_SVC_AUDIO_PACS_CHR_UUID16_SOURCE_AUDIO_LOCATIONS 0x2BCC + +/** BLE Audio Published Audio Capabilities Service Available Audio Contexts characteristic UUID */ #define BLE_SVC_AUDIO_PACS_CHR_UUID16_AVAILABLE_AUDIO_CONTEXTS 0x2BCD -#define BLE_SVC_AUDIO_PACS_CHR_UUID16_SUPPORTED_AUDIO_CONTEXTS 0x2BCE +/** BLE Audio Published Audio Capabilities Service Supported Audio Contexts characteristic UUID */ +#define BLE_SVC_AUDIO_PACS_CHR_UUID16_SUPPORTED_AUDIO_CONTEXTS 0x2BCE +/** Parameters used for setting supported Audio Locations and Contexts. */ struct ble_svc_audio_pacs_set_param { - /* Supported Audio Locations */ + /** Supported Audio Locations */ uint32_t audio_locations; - /* Supported Contexts */ + /** Supported Contexts */ uint16_t supported_contexts; }; From 0d047ce25fd262fda149f84dc52fe80592c933be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 27 Feb 2024 10:08:50 +0100 Subject: [PATCH 0990/1333] apps: add Auracast USB sample with LC3 codec This adds sample that acts as USB sound device. Audio signal is coded using LC3 and broadacasted using Auracast package. --- apps/auracast_usb/include/tusb_config.h | 445 ++++++++++++++++++++++++ apps/auracast_usb/include/usb_audio.h | 30 ++ apps/auracast_usb/pkg.yml | 46 +++ apps/auracast_usb/src/app_priv.h | 45 +++ apps/auracast_usb/src/audio_usb.c | 278 +++++++++++++++ apps/auracast_usb/src/main.c | 325 +++++++++++++++++ apps/auracast_usb/src/usb_desc.c | 395 +++++++++++++++++++++ apps/auracast_usb/syscfg.usb.yml | 174 +++++++++ apps/auracast_usb/syscfg.yml | 132 +++++++ 9 files changed, 1870 insertions(+) create mode 100644 apps/auracast_usb/include/tusb_config.h create mode 100644 apps/auracast_usb/include/usb_audio.h create mode 100644 apps/auracast_usb/pkg.yml create mode 100644 apps/auracast_usb/src/app_priv.h create mode 100644 apps/auracast_usb/src/audio_usb.c create mode 100644 apps/auracast_usb/src/main.c create mode 100644 apps/auracast_usb/src/usb_desc.c create mode 100644 apps/auracast_usb/syscfg.usb.yml create mode 100644 apps/auracast_usb/syscfg.yml diff --git a/apps/auracast_usb/include/tusb_config.h b/apps/auracast_usb/include/tusb_config.h new file mode 100644 index 0000000000..053ed762c8 --- /dev/null +++ b/apps/auracast_usb/include/tusb_config.h @@ -0,0 +1,445 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#include "syscfg/syscfg.h" + +#ifdef __cplusplus +extern "C" { +#endif +/** + * COMMON CONFIGURATION + */ + +#include + +/* defined by compiler flags for flexibility */ +#ifndef CFG_TUSB_MCU +#error CFG_TUSB_MCU must be defined +#endif + +#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE + +#define CFG_TUSB_OS OPT_OS_MYNEWT +#define CFG_TUSB_DEBUG 1 + +#define CFG_TUD_EP_MAX 9 + +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +/** + * DEVICE CONFIGURATION + */ +#define CFG_TUD_ENDPOINT0_SIZE MYNEWT_VAL(USBD_EP0_SIZE) + +/* ------------- CLASS ------------- */ +#define CFG_TUD_CDC MYNEWT_VAL(USBD_CDC) +#define CFG_TUD_HID MYNEWT_VAL(USBD_HID) +#define CFG_TUD_MSC 0 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_VENDOR 0 +#define CFG_TUD_USBTMC 0 +#define CFG_TUD_DFU_RT 0 +#define CFG_TUD_ECM_RNDIS 0 +#define CFG_TUD_BTH MYNEWT_VAL(USBD_BTH) +#define CFG_TUD_AUDIO_IN MYNEWT_VAL(USBD_AUDIO_IN) +#define CFG_TUD_AUDIO_OUT MYNEWT_VAL(USBD_AUDIO_OUT) +#define CFG_TUD_AUDIO_IN_OUT MYNEWT_VAL(USBD_AUDIO_IN_OUT) +#define CFG_TUD_AUDIO (MYNEWT_VAL(USBD_AUDIO_IN) || MYNEWT_VAL(USBD_AUDIO_OUT) || \ + MYNEWT_VAL(USBD_AUDIO_IN_OUT)) + +/* Audio format type */ +#define CFG_TUD_AUDIO_FORMAT_TYPE_TX AUDIO_FORMAT_TYPE_I +#define CFG_TUD_AUDIO_FORMAT_TYPE_RX AUDIO_FORMAT_TYPE_I + +/* Audio format type I specifications */ +#define CFG_TUD_AUDIO_FORMAT_TYPE_I_TX AUDIO_DATA_FORMAT_TYPE_I_PCM +#define CFG_TUD_AUDIO_FORMAT_TYPE_I_RX AUDIO_DATA_FORMAT_TYPE_I_PCM +#define CFG_TUD_AUDIO_N_CHANNELS_TX 2 +#define CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX 2 +#define CFG_TUD_AUDIO_N_CHANNELS_RX MYNEWT_VAL(USB_AUDIO_OUT_CHANNELS) +#define CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX 2 +#define CFG_TUD_AUDIO_RX_ITEMSIZE 2 +#define CFG_TUD_AUDIO_SAMPLE_RATE MYNEWT_VAL(USB_AUDIO_OUT_SAMPLE_RATE) +#define SAMPLES_PER_PACKET ((((CFG_TUD_AUDIO_SAMPLE_RATE) -1) / 1000) + 1) + +/* EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) */ +#define CFG_TUD_AUDIO_EPSIZE_IN (CFG_TUD_AUDIO_IN * SAMPLES_PER_PACKET * \ + (CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX) *(CFG_TUD_AUDIO_N_CHANNELS_TX)) /* 48 Samples (48 kHz) x 2 Bytes/Sample x n Channels */ +#define CFG_TUD_AUDIO_TX_FIFO_COUNT (CFG_TUD_AUDIO_IN * 1) +#define CFG_TUD_AUDIO_TX_FIFO_SIZE (CFG_TUD_AUDIO_IN ? ((CFG_TUD_AUDIO_EPSIZE_IN)) : 0) + +/* EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) */ +#define CFG_TUD_AUDIO_ENABLE_EP_OUT 1 +#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 0 +#define CFG_TUD_AUDIO_EPSIZE_OUT (CFG_TUD_AUDIO_OUT * \ + ((SAMPLES_PER_PACKET + 1) * \ + (CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX) *(CFG_TUD_AUDIO_N_CHANNELS_RX))) /* N Samples (N kHz) x 2 Bytes/Sample x n Channels */ +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX CFG_TUD_AUDIO_EPSIZE_OUT +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ (CFG_TUD_AUDIO_EPSIZE_OUT * 40) +#define CFG_TUD_AUDIO_RX_FIFO_COUNT (CFG_TUD_AUDIO_OUT * 1) +#define CFG_TUD_AUDIO_RX_FIFO_SIZE (CFG_TUD_AUDIO_OUT ? (3 * \ + (CFG_TUD_AUDIO_EPSIZE_OUT / \ + CFG_TUD_AUDIO_RX_FIFO_COUNT)) : 0) + +/* Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes) */ +#define CFG_TUD_AUDIO_N_AS_INT 1 + +/* Size of control request buffer */ +#define CFG_TUD_AUDIO_CTRL_BUF_SIZE 64 + +/* Minimal number for alternative interfaces that is recognized by Windows as Bluetooth radio controller */ +#define CFG_TUD_BTH_ISO_ALT_COUNT 2 + +/* CDC FIFO size of TX and RX */ +#define CFG_TUD_CDC_RX_BUFSIZE 64 +#define CFG_TUD_CDC_TX_BUFSIZE 64 + +/* HID buffer size Should be sufficient to hold ID (if any) + Data */ +#define CFG_TUD_HID_BUFSIZE 16 + +#define TUD_AUDIO_SPEAKER_MONO_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN \ + + TUD_AUDIO_DESC_STD_AC_LEN \ + + TUD_AUDIO_DESC_CS_AC_LEN \ + + TUD_AUDIO_DESC_CLK_SRC_LEN \ + + TUD_AUDIO_DESC_INPUT_TERM_LEN \ + + TUD_AUDIO_DESC_OUTPUT_TERM_LEN \ + + TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN \ + + TUD_AUDIO_DESC_STD_AS_INT_LEN \ + + TUD_AUDIO_DESC_STD_AS_INT_LEN \ + + TUD_AUDIO_DESC_CS_AS_INT_LEN \ + + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN \ + + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN \ + + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN) + +#define TUD_AUDIO_SPEAKER_MONO_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epsize) \ + /* Standard Interface Association Descriptor (IAD) */ \ + TUD_AUDIO_DESC_IAD(/*_firstitfs*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00), \ + /* Standard AC Interface Descriptor(4.7.1) */ \ + TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx), \ + /* Class-Specific AC Interface Header Descriptor(4.7.2) */ \ + TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO_FUNC_DESKTOP_SPEAKER, \ + /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+ \ + TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL_LEN, \ + /*_ctrl*/ AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS), \ + /* Clock Source Descriptor(4.7.2.1) */ \ + TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO_CLOCK_SOURCE_ATT_INT_FIX_CLK, \ + /*_ctrl*/ (AUDIO_CTRL_R << AUDIO_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x00, \ + /*_stridx*/ 0x00), \ + /* Input Terminal Descriptor(4.7.2.4) */ \ + TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, \ + /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x01, \ + /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, \ + /*_ctrl*/ 0 * (AUDIO_CTRL_R << AUDIO_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00), \ + /* Output Terminal Descriptor(4.7.2.5) */ \ + TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, \ + /*_assocTerm*/ 0x00, /*_srcid*/ 0x02, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, \ + /*_stridx*/ 0x00), \ + /* Feature Unit Descriptor(4.7.2.8) */ \ + TUD_AUDIO_DESC_FEATURE_UNIT_ONE_CHANNEL(/*_unitid*/ 0x02, /*_srcid*/ 0x01, \ + /*_ctrlch0master*/ 0 * (AUDIO_CTRL_RW << \ + AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | \ + AUDIO_CTRL_RW << \ + AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS), \ + /*_ctrlch1*/ 0 * (AUDIO_CTRL_RW << \ + AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << \ + AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS), \ + /*_stridx*/ 0x00), \ + /* Standard AS Interface Descriptor(4.9.1) */ \ + /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */ \ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, \ + /*_stridx*/ 0x00), \ + /* Standard AS Interface Descriptor(4.9.1) */ \ + /* Interface 1, Alternate 1 - alternate interface for data streaming */ \ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, \ + /*_stridx*/ 0x00), \ + /* Class-Specific AS Interface Descriptor(4.9.2) */ \ + TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, \ + /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, \ + /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00), \ + /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */ \ + TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample), \ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */ \ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, \ + /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_SYNCHRONOUS | \ + TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, \ + /*_interval*/ (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 0x04 : 0x01), \ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */ \ + TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, \ + /*_ctrl*/ AUDIO_CTRL_NONE, \ + /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, \ + /*_lockdelay*/ 0x0000) \ + +/* XXXXX + * 3 iso endpoint alternative for 16,32,48 kHz does not work on windows, works on Linux, on MAC reported freq is 48kHz and mac sends data for 16kHz + * MAC does not change clock selection like Linux does + */ + +#define TUD_AUDIO_SPEAKER3_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epsize1, \ + _epsize2, _epsize3) \ + /* Standard Interface Association Descriptor (IAD) */ \ + TUD_AUDIO_DESC_IAD(/*_firstitfs*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00), \ + /* Standard AC Interface Descriptor(4.7.1) */ \ + TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx), \ + /* Class-Specific AC Interface Header Descriptor(4.7.2) */ \ + TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO_FUNC_DESKTOP_SPEAKER, \ + /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+ \ + TUD_AUDIO_DESC_OUTPUT_TERM_LEN+0*TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN, \ + /*_ctrl*/ AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS), \ + /* Clock Source Descriptor(4.7.2.1) */ \ + TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO_CLOCK_SOURCE_ATT_INT_FIX_CLK, \ + /*_ctrl*/ (AUDIO_CTRL_RW << AUDIO_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x00, \ + /*_stridx*/ 0x00), \ + /* Input Terminal Descriptor(4.7.2.4) */ \ + TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, \ + /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x02, \ + /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_FRONT_LEFT | AUDIO_CHANNEL_CONFIG_FRONT_RIGHT, \ + /*_idxchannelnames*/ 0x00, \ + /*_ctrl*/ 0 * (AUDIO_CTRL_R << AUDIO_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00), \ + /* Output Terminal Descriptor(4.7.2.5) */ \ + TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, \ + /*_assocTerm*/ 0x00, /*_srcid*/ 0x01, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, \ + /*_stridx*/ 0x00), \ + /* Standard AS Interface Descriptor(4.9.1) */ \ + /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */ \ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, \ + /*_stridx*/ 0x00), \ + /* Standard AS Interface Descriptor(4.9.1) */ \ + \ + /* Interface 1, Alternate 1 - alternate interface for data streaming */ \ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, \ + /*_stridx*/ 0x00), \ + /* Class-Specific AS Interface Descriptor(4.9.2) */ \ + TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, \ + /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x02, \ + /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_FRONT_LEFT | AUDIO_CHANNEL_CONFIG_FRONT_RIGHT, \ + /*_stridx*/ 0x00), \ + /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */ \ + TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample), \ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */ \ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, \ + /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_SYNCHRONOUS | \ + TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize1, \ + /*_interval*/ (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 0x04 : 0x01), \ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */ \ + TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, \ + /*_ctrl*/ AUDIO_CTRL_NONE, \ + /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, \ + /*_lockdelay*/ 0x0000), \ + \ + /* Interface 1, Alternate 2 - alternate interface for data streaming */ \ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x02, /*_nEPs*/ 0x01, \ + /*_stridx*/ 0x00), \ + /* Class-Specific AS Interface Descriptor(4.9.2) */ \ + TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, \ + /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x02, \ + /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_FRONT_LEFT | AUDIO_CHANNEL_CONFIG_FRONT_RIGHT, \ + /*_stridx*/ 0x00), \ + /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */ \ + TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample), \ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */ \ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, \ + /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_SYNCHRONOUS | \ + TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize2, \ + /*_interval*/ (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 0x04 : 0x01), \ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */ \ + TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, \ + /*_ctrl*/ AUDIO_CTRL_NONE, \ + /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, \ + /*_lockdelay*/ 0x0000), \ + \ + /* Interface 1, Alternate 1 - alternate interface for data streaming */ \ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x03, /*_nEPs*/ 0x01, \ + /*_stridx*/ 0x00), \ + /* Class-Specific AS Interface Descriptor(4.9.2) */ \ + TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, \ + /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x02, \ + /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_FRONT_LEFT | AUDIO_CHANNEL_CONFIG_FRONT_RIGHT, \ + /*_stridx*/ 0x00), \ + /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */ \ + TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample), \ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */ \ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, \ + /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_SYNCHRONOUS | \ + TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize3, \ + /*_interval*/ (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 0x04 : 0x01), \ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */ \ + TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, \ + /*_ctrl*/ AUDIO_CTRL_NONE, \ + /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, \ + /*_lockdelay*/ 0x0000) \ + +#define TUD_AUDIO_SPK3_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN \ + + TUD_AUDIO_DESC_STD_AC_LEN \ + + TUD_AUDIO_DESC_CS_AC_LEN \ + + TUD_AUDIO_DESC_CLK_SRC_LEN \ + + TUD_AUDIO_DESC_INPUT_TERM_LEN \ + + TUD_AUDIO_DESC_OUTPUT_TERM_LEN \ + + 0 * TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN \ + + TUD_AUDIO_DESC_STD_AS_INT_LEN \ + + (TUD_AUDIO_DESC_STD_AS_INT_LEN \ + + TUD_AUDIO_DESC_CS_AS_INT_LEN \ + + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN \ + + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN \ + + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN) * 3) + + +#define TUD_AUDIO_SPEAKER_DESCRIPTOR_FLOAT(_itfnum, _stridx, _epout, _epsize) \ + /* Standard Interface Association Descriptor (IAD) */ \ + TUD_AUDIO_DESC_IAD(/*_firstitfs*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00), \ + /* Standard AC Interface Descriptor(4.7.1) */ \ + TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx), \ + /* Class-Specific AC Interface Header Descriptor(4.7.2) */ \ + TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO_FUNC_DESKTOP_SPEAKER, \ + /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+ \ + TUD_AUDIO_DESC_OUTPUT_TERM_LEN+0*TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN, \ + /*_ctrl*/ AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS), \ + /* Clock Source Descriptor(4.7.2.1) */ \ + TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO_CLOCK_SOURCE_ATT_INT_FIX_CLK, \ + /*_ctrl*/ (AUDIO_CTRL_RW << AUDIO_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x00, \ + /*_stridx*/ 0x00), \ + /* Input Terminal Descriptor(4.7.2.4) */ \ + TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, \ + /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x02, \ + /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_FRONT_LEFT | AUDIO_CHANNEL_CONFIG_FRONT_RIGHT, \ + /*_idxchannelnames*/ 0x00, \ + /*_ctrl*/ 0 * (AUDIO_CTRL_R << AUDIO_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00), \ + /* Output Terminal Descriptor(4.7.2.5) */ \ + TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, \ + /*_assocTerm*/ 0x00, /*_srcid*/ 0x01, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, \ + /*_stridx*/ 0x00), \ + /* Standard AS Interface Descriptor(4.9.1) */ \ + /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */ \ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, \ + /*_stridx*/ 0x00), \ + /* Standard AS Interface Descriptor(4.9.1) */ \ + /* Interface 1, Alternate 1 - alternate interface for data streaming */ \ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, \ + /*_stridx*/ 0x00), \ + /* Class-Specific AS Interface Descriptor(4.9.2) */ \ + TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, \ + /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT, /*_nchannelsphysical*/ 0x02, \ + /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_FRONT_LEFT | AUDIO_CHANNEL_CONFIG_FRONT_RIGHT, \ + /*_stridx*/ 0x00), \ + /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */ \ + TUD_AUDIO_DESC_TYPE_I_FORMAT(4, 32), \ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */ \ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, \ + /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_SYNCHRONOUS | \ + TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, \ + /*_interval*/ (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 0x04 : 0x01), \ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */ \ + TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, \ + /*_ctrl*/ AUDIO_CTRL_NONE, \ + /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, \ + /*_lockdelay*/ 0x0000) \ + +#define TUD_AUDIO_SPEAKER_STEREO_DESC_LEN (TUD_AUDIO_DESC_IAD_LEN \ + + TUD_AUDIO_DESC_STD_AC_LEN \ + + TUD_AUDIO_DESC_CS_AC_LEN \ + + TUD_AUDIO_DESC_CLK_SRC_LEN \ + + TUD_AUDIO_DESC_INPUT_TERM_LEN \ + + TUD_AUDIO_DESC_OUTPUT_TERM_LEN \ + + 0 * TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN \ + + TUD_AUDIO_DESC_STD_AS_INT_LEN \ + + (TUD_AUDIO_DESC_STD_AS_INT_LEN \ + + TUD_AUDIO_DESC_CS_AS_INT_LEN \ + + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN \ + + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN \ + + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN) * 1) + +#define TUD_AUDIO_SPEAKER_STEREO_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epsize) \ + /* Standard Interface Association Descriptor (IAD) */ \ + TUD_AUDIO_DESC_IAD(/*_firstitfs*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00), \ + /* Standard AC Interface Descriptor(4.7.1) */ \ + TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx), \ + /* Class-Specific AC Interface Header Descriptor(4.7.2) */ \ + TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO_FUNC_DESKTOP_SPEAKER, \ + /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+ \ + TUD_AUDIO_DESC_OUTPUT_TERM_LEN+0*TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN, \ + /*_ctrl*/ AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS), \ + /* Clock Source Descriptor(4.7.2.1) */ \ + TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ 0x04, /*_attr*/ AUDIO_CLOCK_SOURCE_ATT_INT_FIX_CLK, \ + /*_ctrl*/ (AUDIO_CTRL_RW << AUDIO_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x00, \ + /*_stridx*/ 0x00), \ + /* Input Terminal Descriptor(4.7.2.4) */ \ + TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ 0x01, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, \ + /*_clkid*/ 0x04, /*_nchannelslogical*/ 0x02, \ + /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_FRONT_LEFT | AUDIO_CHANNEL_CONFIG_FRONT_RIGHT, \ + /*_idxchannelnames*/ 0x00, \ + /*_ctrl*/ 0 * (AUDIO_CTRL_R << AUDIO_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00), \ + /* Output Terminal Descriptor(4.7.2.5) */ \ + TUD_AUDIO_DESC_OUTPUT_TERM(/*_termid*/ 0x03, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, \ + /*_assocTerm*/ 0x00, /*_srcid*/ 0x01, /*_clkid*/ 0x04, /*_ctrl*/ 0x0000, \ + /*_stridx*/ 0x00), \ + /* Standard AS Interface Descriptor(4.9.1) */ \ + /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */ \ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, \ + /*_stridx*/ 0x00), \ + /* Standard AS Interface Descriptor(4.9.1) */ \ + /* Interface 1, Alternate 1 - alternate interface for data streaming */ \ + TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, \ + /*_stridx*/ 0x00), \ + /* Class-Specific AS Interface Descriptor(4.9.2) */ \ + TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ 0x01, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, \ + /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x02, \ + /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_FRONT_LEFT | AUDIO_CHANNEL_CONFIG_FRONT_RIGHT, \ + /*_stridx*/ 0x00), \ + /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */ \ + TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample), \ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */ \ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, \ + /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_SYNCHRONOUS | \ + TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, \ + /*_interval*/ (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 0x04 : 0x01), \ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */ \ + TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, \ + /*_ctrl*/ AUDIO_CTRL_NONE, \ + /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, \ + /*_lockdelay*/ 0x0000) \ + +#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN ( \ + (1 - CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP) * CFG_TUD_AUDIO_OUT * \ + (TUD_AUDIO_SPEAKER_MONO_DESC_LEN * (CFG_TUD_AUDIO_N_CHANNELS_RX == 1 ? 1 : 0)) + \ + (0 + CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP) * CFG_TUD_AUDIO_OUT * \ + (TUD_AUDIO_SPEAKER_MONO_FB_DESC_LEN * (CFG_TUD_AUDIO_N_CHANNELS_RX == 1 ? 1 : 0)) + \ + (1 - CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP) * CFG_TUD_AUDIO_OUT * \ + (TUD_AUDIO_SPEAKER_STEREO_DESC_LEN * (CFG_TUD_AUDIO_N_CHANNELS_RX == 2 ? 1 : 0))) +#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 +#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/apps/auracast_usb/include/usb_audio.h b/apps/auracast_usb/include/usb_audio.h new file mode 100644 index 0000000000..ea93b9fc5b --- /dev/null +++ b/apps/auracast_usb/include/usb_audio.h @@ -0,0 +1,30 @@ +/* + * 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_USB_AUDIO_ +#define H_USB_AUDIO_ + +#include + +typedef void (* usb_audio_sample_rate_cb_t)(uint32_t); + +/* Set default sample rate, should only be used before USB is initialized */ +void usb_desc_sample_rate_set(uint32_t sample_rate); + +#endif /* H_USB_AUDIO_ */ diff --git a/apps/auracast_usb/pkg.yml b/apps/auracast_usb/pkg.yml new file mode 100644 index 0000000000..96c56f2ca2 --- /dev/null +++ b/apps/auracast_usb/pkg.yml @@ -0,0 +1,46 @@ +# 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: apps/auracast_usb +pkg.type: app +pkg.description: Auracast sample application. + +pkg.author: "Krzysztof Kopyściński" +pkg.email: "krzysztof.kopyscinski@codecoup.pl" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - "@apache-mynewt-core/sys/config" + - nimble/host + - nimble/host/util + - nimble/host/services/gap + - nimble/host/store/config + - "@apache-mynewt-core/kernel/os" + - "@apache-mynewt-core/sys/console" + - "@apache-mynewt-core/sys/log" + - "@apache-mynewt-core/sys/stats" + - "@apache-mynewt-core/sys/sysinit" + - "@apache-mynewt-core/sys/id" + - "@apache-mynewt-core/hw/usb/tinyusb" + - "@apache-mynewt-nimble/nimble/host/audio/services/auracast" + - "@apache-mynewt-nimble/ext/liblc3" + - "@apache-mynewt-nimble/ext/libsamplerate" + +pkg.init: + audio_usb_init: 402 diff --git a/apps/auracast_usb/src/app_priv.h b/apps/auracast_usb/src/app_priv.h new file mode 100644 index 0000000000..87a901a71b --- /dev/null +++ b/apps/auracast_usb/src/app_priv.h @@ -0,0 +1,45 @@ +/* + * 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_APP_PRIV_ +#define H_APP_PRIV_ + +#include + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#define AUDIO_CHANNELS MYNEWT_VAL(AURACAST_CHAN_NUM) +#define AUDIO_SAMPLE_SIZE sizeof(int16_t) +#define AUDIO_PCM_SAMPLE_RATE MYNEWT_VAL(USB_AUDIO_OUT_SAMPLE_RATE) + +#define LC3_FRAME_DURATION (MYNEWT_VAL(LC3_FRAME_DURATION)) +#define LC3_SAMPLING_FREQ (MYNEWT_VAL(LC3_SAMPLING_FREQ)) +#define LC3_BITRATE (MYNEWT_VAL(LC3_BITRATE)) +#define LC3_FPDT (LC3_SAMPLING_FREQ * LC3_FRAME_DURATION / 1000000) +#define BIG_NUM_BIS (MIN(AUDIO_CHANNELS, MYNEWT_VAL(BIG_NUM_BIS))) + +struct chan { + void *encoder; + uint16_t handle; +}; + +extern struct chan chans[AUDIO_CHANNELS]; +#endif /* H_APP_PRIV_ */ diff --git a/apps/auracast_usb/src/audio_usb.c b/apps/auracast_usb/src/audio_usb.c new file mode 100644 index 0000000000..c63f688ce0 --- /dev/null +++ b/apps/auracast_usb/src/audio_usb.c @@ -0,0 +1,278 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "console/console.h" + +#include +#include +#include + +#include "host/ble_gap.h" +#include "os/os_cputime.h" + +#include "app_priv.h" + +#define AUDIO_BUF_SIZE 1024 + +static uint8_t g_usb_enabled; + +static void usb_data_func(struct os_event *ev); + +struct chan chans[AUDIO_CHANNELS]; + +static struct os_event usb_data_ev = { + .ev_cb = usb_data_func, +}; + +static uint32_t frame_bytes_lc3; +static uint16_t big_sdu; + +static int16_t out_buf[AUDIO_BUF_SIZE]; +/* Reserve twice the size of input, so we'll always have space for resampler output */ +static uint8_t encoded_frame[155]; +static int out_idx = 0; +#if MYNEWT_VAL(ISO_HCI_FEEDBACK) +static int samples_idx = 0; +static int16_t samples_read[AUDIO_BUF_SIZE]; +/* 155 is maximum value Octets Per Codec Frame described in Table 3.5 of BAP specification */ +static float samples_read_float[AUDIO_BUF_SIZE]; +static float resampled_float[AUDIO_BUF_SIZE]; +double resampler_in_rate = AUDIO_PCM_SAMPLE_RATE; +double resampler_out_rate = LC3_SAMPLING_FREQ; +double resampler_ratio; +SRC_STATE *resampler_state; +static struct ble_gap_event_listener feedback_listener; +#endif +static uint32_t pkt_counter = 0; + + +#if MYNEWT_VAL(ISO_HCI_FEEDBACK) +static int +ble_hs_gap_event_handler(struct ble_gap_event *event, void *arg) +{ + struct ble_hci_vs_subev_iso_hci_feedback *feedback_pkt; + double adjust = 0; + + if (event->type == BLE_GAP_EVENT_UNHANDLED_HCI_EVENT && + event->unhandled_hci.is_le_meta == false && + event->unhandled_hci.is_vs == true) { + const struct ble_hci_ev_vs *ev = event->unhandled_hci.ev; + + if (ev->id == BLE_HCI_VS_SUBEV_ISO_HCI_FEEDBACK) { + feedback_pkt = (struct ble_hci_vs_subev_iso_hci_feedback *) ev->data; + assert(feedback_pkt->count == MYNEWT_VAL(BLE_ISO_MAX_BIGS)); + /* There is only one BIG in this sample */ + if (feedback_pkt->feedback[0].diff > 0) { + adjust += 10; + } else if (feedback_pkt->feedback[0].diff < 0) { + adjust -= 10; + } + resampler_ratio = (resampler_out_rate + adjust) / resampler_in_rate; + } + } + + return 0; +} + +static void +resample(void) +{ + static int resampled_len; + int samples_consumed; + int samples_left; + SRC_DATA sd; + int resample_avail = ARRAY_SIZE(out_buf) - out_idx; + int rc; + + src_short_to_float_array(samples_read, samples_read_float, samples_idx); + + sd.data_in = samples_read_float; + sd.data_out = resampled_float; + sd.input_frames = samples_idx / AUDIO_CHANNELS; + sd.output_frames = resample_avail / AUDIO_CHANNELS; + sd.end_of_input = 0; + sd.input_frames_used = 0; + sd.output_frames_gen = 0; + sd.src_ratio = resampler_ratio; + + rc = src_process(resampler_state, &sd); + assert(rc == 0); + + resampled_len = sd.output_frames_gen * AUDIO_CHANNELS; + + assert(resampled_len <= resample_avail); + + src_float_to_short_array(resampled_float, + &out_buf[out_idx], + resampled_len); + + out_idx += resampled_len; + + samples_consumed = sd.input_frames_used * AUDIO_CHANNELS; + samples_left = samples_idx - samples_consumed; + memmove(samples_read, &samples_read[samples_consumed], samples_left); + samples_idx -= samples_consumed; +} +#endif + +static void +usb_data_func(struct os_event *ev) +{ + int ch_idx; + unsigned int num_bytes; + unsigned int num_samples; + unsigned int num_frames; + int read; + int skip; + + if (!g_usb_enabled) { + tud_audio_clear_ep_out_ff(); + return; + } + + while ((num_bytes = tud_audio_available()) > 0) { + num_samples = num_bytes / AUDIO_SAMPLE_SIZE; + num_frames = num_samples / AUDIO_CHANNELS; + num_bytes = num_frames * AUDIO_SAMPLE_SIZE * AUDIO_CHANNELS; + +#if MYNEWT_VAL(ISO_HCI_FEEDBACK) + assert(samples_idx + num_samples < ARRAY_SIZE(samples_read)); + read = tud_audio_read(&samples_read[samples_idx], num_bytes); + samples_idx += num_samples; + resample(); +#else + assert(out_idx + num_samples < ARRAY_SIZE(out_buf)); + read = tud_audio_read(&out_buf[out_idx], num_bytes); + out_idx += num_samples; +#endif + assert(read == num_bytes); + + assert((out_idx & 0x80000000) == 0); + if (out_idx / AUDIO_CHANNELS >= LC3_FPDT) { + pkt_counter++; + skip = 0; + + for (ch_idx = 0; ch_idx < AUDIO_CHANNELS; ch_idx++) { + if (chans[ch_idx].handle == 0) { + skip = 1; + continue; + } + } + + if (!skip) { + memset(encoded_frame, 0, sizeof(encoded_frame)); + lc3_encode(chans[0].encoder, LC3_PCM_FORMAT_S16, out_buf + 0, + AUDIO_CHANNELS, (int) frame_bytes_lc3, + encoded_frame); + if (AUDIO_CHANNELS == 2) { + if (MYNEWT_VAL(BIG_NUM_BIS) == 1) { + lc3_encode(chans[0].encoder, LC3_PCM_FORMAT_S16, + out_buf + 1, AUDIO_CHANNELS, + (int) frame_bytes_lc3, encoded_frame + big_sdu / 2); + ble_iso_tx(chans[0].handle, encoded_frame, big_sdu); + } else { + ble_iso_tx(chans[0].handle, encoded_frame, big_sdu); + memset(encoded_frame, 0, sizeof(encoded_frame)); + lc3_encode(chans[1].encoder, LC3_PCM_FORMAT_S16, out_buf + 1, + AUDIO_CHANNELS, (int) frame_bytes_lc3, + encoded_frame); + ble_iso_tx(chans[1].handle, encoded_frame, big_sdu); + } + } else { + ble_iso_tx(chans[0].handle, encoded_frame, big_sdu); + } + + if (out_idx / AUDIO_CHANNELS >= LC3_FPDT) { + out_idx -= LC3_FPDT * AUDIO_CHANNELS; + memmove(out_buf, &out_buf[LC3_FPDT * AUDIO_CHANNELS], + out_idx * AUDIO_SAMPLE_SIZE); + } else { + out_idx = 0; + } + } + } + } +} + +bool +tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_bytes_received, + uint8_t func_id, uint8_t ep_out, + uint8_t cur_alt_setting) +{ + (void)rhport; + (void)n_bytes_received; + (void)func_id; + (void)ep_out; + (void)cur_alt_setting; + + if (!usb_data_ev.ev_queued) { + os_eventq_put(os_eventq_dflt_get(), &usb_data_ev); + } + + return true; +} + +void +audio_usb_init(void) +{ + /* Need to reference those explicitly, so they are always pulled by linker + * instead of weak symbols in tinyusb. + */ + (void)tud_audio_rx_done_post_read_cb; + + usb_desc_sample_rate_set(AUDIO_PCM_SAMPLE_RATE); + + assert(LC3_FPDT == lc3_frame_samples(LC3_FRAME_DURATION, + LC3_SAMPLING_FREQ)); + + unsigned esize = lc3_encoder_size(LC3_FRAME_DURATION, + LC3_SAMPLING_FREQ); + for (int i = 0; i < AUDIO_CHANNELS; i++) { + chans[i].encoder = calloc(1, esize); + lc3_setup_encoder(LC3_FRAME_DURATION, LC3_SAMPLING_FREQ, + 0, chans[i].encoder); + } + + g_usb_enabled = 1; + + frame_bytes_lc3 = lc3_frame_bytes(LC3_FRAME_DURATION, LC3_BITRATE); + big_sdu = frame_bytes_lc3 * + (1 + ((AUDIO_CHANNELS == 2) && (BIG_NUM_BIS == 1))); + +#if MYNEWT_VAL(ISO_HCI_FEEDBACK) + int rc; + + assert(resampler_state == NULL); + resampler_state = src_new(SRC_ZERO_ORDER_HOLD, AUDIO_CHANNELS, NULL); + assert(resampler_state != NULL); + + rc = ble_gap_event_listener_register(&feedback_listener, + ble_hs_gap_event_handler, NULL); + assert(rc == 0); + + resampler_ratio = resampler_out_rate / resampler_in_rate; +#endif +} diff --git a/apps/auracast_usb/src/main.c b/apps/auracast_usb/src/main.c new file mode 100644 index 0000000000..fcf4fd397d --- /dev/null +++ b/apps/auracast_usb/src/main.c @@ -0,0 +1,325 @@ +/* + * 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. + */ + +#include "console/console.h" +#include "config/config.h" + +#include "nimble/ble.h" +#include "host/ble_hs.h" +#include "host/util/util.h" + +#include "services/auracast/ble_svc_auracast.h" + +#include "hal/hal_gpio.h" +#include "bsp/bsp.h" +#include "app_priv.h" + +#define BROADCAST_SID 1 +#define BROADCAST_SDU_INTVL MYNEWT_VAL(LC3_FRAME_DURATION) +#if (MYNEWT_VAL(LC3_BITRATE) == 24000) +#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_24000_HZ +#elif (MYNEWT_VAL(LC3_BITRATE) == 48000) +#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_48000_HZ +#elif (MYNEWT_VAL(LC3_BITRATE) == 96000) +#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_96000_HZ +#else +BUILD_ASSERT(0, "Only 24kHz and 48kHz supported"); +#endif +#define BROADCAST_MAX_SDU (BROADCAST_SDU_INTVL * \ + MYNEWT_VAL(LC3_BITRATE) / \ + (1000 * 1000 * 8) * \ + MYNEWT_VAL(AURACAST_CHAN_NUM) / \ + MYNEWT_VAL(BIG_NUM_BIS)) + +#define BROADCASTER_INTERRUPT_TASK_PRIO 4 +#define BROADCASTER_INTERRUPT_TASK_STACK_SZ 512 + +static uint8_t id_addr_type; + +static struct ble_audio_base auracast_base; +static struct ble_audio_big_subgroup big_subgroup; + +static os_membuf_t bis_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BIG_NUM_BIS), + sizeof(struct ble_audio_bis)) +]; +static struct os_mempool bis_pool; + +static os_membuf_t codec_spec_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BIG_NUM_BIS) * 2, 19) +]; +static struct os_mempool codec_spec_pool; + +static uint8_t auracast_adv_instance; + +static void +auracast_init(void) +{ + int rc; + + assert(MYNEWT_VAL(AURACAST_CHAN_NUM) > 0); + + rc = os_mempool_init(&bis_pool, MYNEWT_VAL(BIG_NUM_BIS), + sizeof(struct ble_audio_bis), bis_mem, + "bis_pool"); + assert(rc == 0); + + rc = os_mempool_init(&codec_spec_pool, + MYNEWT_VAL(BIG_NUM_BIS) * 2, 19, + codec_spec_mem, "codec_spec_pool"); + assert(rc == 0); +} + +static int +base_create(void) +{ +#if MYNEWT_VAL(BIG_NUM_BIS) > 1 + struct ble_audio_bis *bis_left; + struct ble_audio_bis *bis_right; + uint8_t codec_spec_config_left_chan[] = + BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, + MYNEWT_VAL(LC3_FRAME_DURATION) == 10000 ? + BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS : + BLE_AUDIO_SELECTED_FRAME_DURATION_7_5_MS, + BLE_AUDIO_LOCATION_FRONT_LEFT, + BROADCAST_MAX_SDU, ); + uint8_t codec_spec_config_right_chan[] = + BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, + MYNEWT_VAL(LC3_FRAME_DURATION) == 10000 ? + BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS : + BLE_AUDIO_SELECTED_FRAME_DURATION_7_5_MS, + BLE_AUDIO_LOCATION_FRONT_RIGHT, + BROADCAST_MAX_SDU, ); +#else + uint16_t chan_loc = BLE_AUDIO_LOCATION_FRONT_LEFT | + BLE_AUDIO_LOCATION_FRONT_RIGHT; + uint8_t codec_spec_config[] = + BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, + MYNEWT_VAL(LC3_FRAME_DURATION) == 10000 ? + BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS : + BLE_AUDIO_SELECTED_FRAME_DURATION_7_5_MS, + chan_loc, + BROADCAST_MAX_SDU * 2, ); + + struct ble_audio_bis *bis; +#endif + if (MYNEWT_VAL(BROADCAST_ID) != 0) { + auracast_base.broadcast_id = MYNEWT_VAL(BROADCAST_ID); + } else { + ble_hs_hci_rand(&auracast_base.broadcast_id, 3); + } + auracast_base.presentation_delay = 20000; + + big_subgroup.bis_cnt = MYNEWT_VAL(BIG_NUM_BIS); + + /** LC3 */ + big_subgroup.codec_id.format = 0x06; + + big_subgroup.codec_spec_config_len = 0; +#if MYNEWT_VAL(BIG_NUM_BIS) > 1 + bis_left = os_memblock_get(&bis_pool); + if (!bis_left) { + return BLE_HS_ENOMEM; + } + + bis_left->codec_spec_config = os_memblock_get(&codec_spec_pool); + memcpy(bis_left->codec_spec_config, + codec_spec_config_left_chan, + sizeof(codec_spec_config_left_chan)); + bis_left->codec_spec_config_len = sizeof(codec_spec_config_left_chan); + bis_left->idx = 1; + + bis_right = os_memblock_get(&bis_pool); + if (!bis_right) { + return BLE_HS_ENOMEM; + } + + bis_right->codec_spec_config = os_memblock_get(&codec_spec_pool); + memcpy(bis_right->codec_spec_config, + codec_spec_config_right_chan, + sizeof(codec_spec_config_right_chan)); + bis_right->codec_spec_config_len = sizeof(codec_spec_config_right_chan); + bis_right->idx = 2; + + STAILQ_INSERT_HEAD(&big_subgroup.bises, bis_left, next); + STAILQ_INSERT_TAIL(&big_subgroup.bises, bis_right, next); +#else + bis = os_memblock_get(&bis_pool); + if (!bis) { + return BLE_HS_ENOMEM; + } + + bis->codec_spec_config = os_memblock_get(&codec_spec_pool); + memcpy(bis->codec_spec_config, + codec_spec_config, + sizeof(codec_spec_config)); + bis->codec_spec_config_len = sizeof(codec_spec_config); + STAILQ_INSERT_HEAD(&big_subgroup.bises, bis, next); +#endif + + STAILQ_INSERT_HEAD(&auracast_base.subs, &big_subgroup, next); + auracast_base.num_subgroups++; + return 0; +} + +static int +auracast_destroy_fn(struct ble_audio_base *base, void *args) +{ + struct ble_audio_bis *bis; + int i; + + STAILQ_FOREACH(bis, &big_subgroup.bises, next) { + os_memblock_put(&codec_spec_pool, bis->codec_spec_config); + os_memblock_put(&bis_pool, bis); + } + + memset(&big_subgroup, 0, sizeof(big_subgroup)); + + for (i = 0; i < MYNEWT_VAL(AURACAST_CHAN_NUM); i++) { + chans[i].handle = 0; + } + + return 0; +} + +static int +iso_event(struct ble_iso_event *event, void *arg) +{ + int i; + + switch (event->type) { + case BLE_ISO_EVENT_BIG_CREATE_COMPLETE: + console_printf("BIG created\n"); + if (event->big_created.desc.num_bis > + MYNEWT_VAL(AURACAST_CHAN_NUM)) { + return BLE_HS_EINVAL; + } + if (MYNEWT_VAL(AURACAST_CHAN_NUM) == event->big_created.desc.num_bis) { + for (i = 0; i < MYNEWT_VAL(AURACAST_CHAN_NUM); i++) { + chans[i].handle = event->big_created.desc.conn_handle[i]; + } + } else { + for (i = 0; i < MYNEWT_VAL(AURACAST_CHAN_NUM); i++) { + chans[i].handle = event->big_created.desc.conn_handle[0]; + } + } + return 0; + case BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE: + console_printf("BIG terminated\n"); + return 0; + default: + return BLE_HS_ENOTSUP; + } +} + +static int +auracast_create(void) +{ + const char *program_info = "NimBLE Auracast Test"; + static struct ble_iso_big_params big_params = { + .sdu_interval = MYNEWT_VAL(LC3_FRAME_DURATION), + .max_sdu = BROADCAST_MAX_SDU, + .max_transport_latency = MYNEWT_VAL(LC3_FRAME_DURATION) / 1000, + .rtn = MYNEWT_VAL(BIG_RTN), + .phy = MYNEWT_VAL(BIG_PHY), + .packing = MYNEWT_VAL(BIG_PACKING), + .framing = MYNEWT_VAL(BIG_FRAMING), + .encryption = MYNEWT_VAL(BIG_ENCRYPTION), + .broadcast_code = MYNEWT_VAL(BROADCAST_CODE), + }; + + struct ble_svc_auracast_create_params create_params = { + .base = &auracast_base, + .big_params = &big_params, + .name = MYNEWT_VAL(BROADCAST_NAME), + .program_info = program_info, + .own_addr_type = id_addr_type, + .secondary_phy = BLE_HCI_LE_PHY_2M, + .sid = BROADCAST_SID, + .frame_duration = MYNEWT_VAL(LC3_FRAME_DURATION), + .sampling_frequency = MYNEWT_VAL(LC3_SAMPLING_FREQ), + .bitrate = MYNEWT_VAL(LC3_BITRATE), + }; + + return ble_svc_auracast_create(&create_params, + &auracast_adv_instance, + auracast_destroy_fn, + NULL, + NULL); +} + +static int +auracast_start(void) +{ + return ble_svc_auracast_start(auracast_adv_instance, iso_event, NULL); +} + +static void +on_sync(void) +{ + int rc; + + console_printf("Bluetooth initialized\n"); + + /* Make sure we have proper identity address set (public preferred) */ + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* configure global address */ + rc = ble_hs_id_infer_auto(0, &id_addr_type); + assert(rc == 0); + + auracast_init(); + + rc = base_create(); + assert(rc == 0); + + rc = auracast_create(); + assert(rc == 0); + + rc = auracast_start(); + assert(rc == 0); +} + +/* + * main + * + * The main task for the project. This function initializes the packages, + * then starts serving events from default event queue. + * + * @return int NOTE: this function should never return! + */ +int +mynewt_main(int argc, char **argv) +{ + /* Initialize OS */ + sysinit(); + + console_printf("LE Audio Broadcast sample application\n"); + + /* Set sync callback */ + ble_hs_cfg.sync_cb = on_sync; + + /* As the last thing, process events from default event queue */ + while (1) { + os_eventq_run(os_eventq_dflt_get()); + } + + return 0; +} diff --git a/apps/auracast_usb/src/usb_desc.c b/apps/auracast_usb/src/usb_desc.c new file mode 100644 index 0000000000..681ad7cea7 --- /dev/null +++ b/apps/auracast_usb/src/usb_desc.c @@ -0,0 +1,395 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USBD_PRODUCT_RELEASE_NUMBER MYNEWT_VAL(USBD_PRODUCT_RELEASE_NUMBER) + +#ifndef CONFIG_NUM +#define CONFIG_NUM 1 +#endif + +typedef enum { + USB_STRING_DESCRIPTOR_LANG = 0, + USB_STRING_DESCRIPTOR_MANUFACTURER = 1, + USB_STRING_DESCRIPTOR_PRODUCT = 2, + USB_STRING_DESCRIPTOR_INTERFACE = 3, + USB_STRING_DESCRIPTOR_CDC = 4, + USB_STRING_DESCRIPTOR_SERIAL = 16, + USB_STRING_DESCRIPTOR_MICROSOFT_OS = 0xEE, +} usb_string_descriptor_ix_t; + +#define CDC_IF_STR_IX (MYNEWT_VAL(USBD_CDC_DESCRIPTOR_STRING) == NULL ? 0 : 4) + +const tusb_desc_device_t desc_device = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + + .bDeviceClass = 0x00, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = MYNEWT_VAL(USBD_VID), + .idProduct = MYNEWT_VAL(USBD_PID), + .bcdDevice = USBD_PRODUCT_RELEASE_NUMBER, + + .iManufacturer = USB_STRING_DESCRIPTOR_MANUFACTURER, + .iProduct = USB_STRING_DESCRIPTOR_PRODUCT, + .iSerialNumber = USB_STRING_DESCRIPTOR_SERIAL, + + .bNumConfigurations = 0x01 +}; + +/* + * Invoked when received GET DEVICE DESCRIPTOR + * Application return pointer to descriptor + */ +const uint8_t * +tud_descriptor_device_cb(void) +{ + return (const uint8_t *)&desc_device; +} + +#if MYNEWT_VAL_CHOICE(MCU_TARGET, nRF5340_APP) || MYNEWT_VAL_CHOICE(MCU_TARGET, nRF52840) +#define ISO_EP 8 +#else +#error MCU not supported +#endif + +/* + * Configuration Descriptor + */ + +enum { +#if CFG_TUD_BTH + ITF_NUM_BTH, +#if CFG_TUD_BTH_ISO_ALT_COUNT > 0 + ITF_NUM_BTH_VOICE, +#endif +#endif + +#if CFG_TUD_CDC + ITF_NUM_CDC, + ITF_NUM_CDC_DATA, +#endif + +#if CFG_TUD_MSC + ITF_NUM_MSC, +#endif + +#if CFG_TUD_HID + ITF_NUM_HID, +#endif + +#if CFG_TUD_AUDIO_IN + ITF_NUM_AUDIO_AC, + ITF_NUM_AUDIO_AS_IN, +#elif CFG_TUD_AUDIO_OUT + ITF_NUM_AUDIO_AC, + ITF_NUM_AUDIO_AS_OUT, +#elif CFG_TUD_AUDIO_IN_OUT + ITF_NUM_AUDIO_AC, + ITF_NUM_AUDIO_AS_IN, + ITF_NUM_AUDIO_AS_OUT, +#endif + + ITF_NUM_TOTAL +}; + +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + \ + CFG_TUD_CDC * TUD_CDC_DESC_LEN + \ + CFG_TUD_MSC * TUD_MSC_DESC_LEN + \ + CFG_TUD_HID * TUD_HID_DESC_LEN + \ + CFG_TUD_BTH * TUD_BTH_DESC_LEN + \ + CFG_TUD_AUDIO_IN * TUD_AUDIO_MIC_ONE_CH_DESC_LEN + \ + (1 + CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP) * CFG_TUD_AUDIO_OUT * \ + (TUD_AUDIO_SPEAKER_MONO_DESC_LEN * (CFG_TUD_AUDIO_N_CHANNELS_RX == 1 ? 1 : 0)) + \ + (1 - CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP) * CFG_TUD_AUDIO_OUT * \ + (TUD_AUDIO_SPEAKER_STEREO_DESC_LEN * (CFG_TUD_AUDIO_N_CHANNELS_RX == 2 ? 1 : 0)) + \ + 0) + +const uint8_t desc_configuration[] = { + TUD_CONFIG_DESCRIPTOR(CONFIG_NUM, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, + MYNEWT_VAL(USBD_CONFIGURATION_MAX_POWER)), + +#if CFG_TUD_BTH + TUD_BTH_DESCRIPTOR(ITF_NUM_BTH, BTH_IF_STR_IX, USBD_BTH_EVENT_EP, USBD_BTH_EVENT_EP_SIZE, + USBD_BTH_EVENT_EP_INTERVAL, USBD_BTH_DATA_IN_EP, USBD_BTH_DATA_OUT_EP, USBD_BTH_DATA_EP_SIZE, + 0, 9, 17, 25, 33, 49), +#endif + + +#if CFG_TUD_CDC + TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, CDC_IF_STR_IX, USBD_CDC_NOTIFY_EP, USBD_CDC_NOTIFY_EP_SIZE, + USBD_CDC_DATA_OUT_EP, USBD_CDC_DATA_IN_EP, USBD_CDC_DATA_EP_SIZE), +#endif + +#if CFG_TUD_MSC + /* TODO: MSC not handled yet */ + TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, MSC_IF_STR_IX, EPNUM_MSC_OUT, EPNUM_MSC_IN, + (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 512 : 64), +#endif + +#if CFG_TUD_HID + TUD_HID_DESCRIPTOR(ITF_NUM_HID, HID_IF_STR_IX, HID_PROTOCOL_NONE, sizeof(desc_hid_report), + USBD_HID_REPORT_EP, USBD_HID_REPORT_EP_SIZE, USBD_HID_REPORT_EP_INTERVAL), +#endif + +#if CFG_TUD_AUDIO_IN_OUT +#elif CFG_TUD_AUDIO_IN + TUD_AUDIO_MIC2_DESCRIPTOR(ITF_NUM_AUDIO_AC_IN, 0, 2, 16, 0x80 | ISO_EP, 192), +#elif CFG_TUD_AUDIO_OUT && CFG_TUD_AUDIO_N_CHANNELS_RX == 2 +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP == 1 + TUD_AUDIO_SPEAKER_STEREO_FB_DESCRIPTOR(ITF_NUM_AUDIO_AC, 0, CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX, + 8 * CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX, ISO_EP, CFG_TUD_AUDIO_EPSIZE_OUT, 0x80 | ISO_EP, 1), +#else + TUD_AUDIO_SPEAKER_STEREO_DESCRIPTOR(ITF_NUM_AUDIO_AC, 0, CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX, + 8 * CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX, ISO_EP, CFG_TUD_AUDIO_EPSIZE_OUT), +#endif +#elif CFG_TUD_AUDIO_OUT && CFG_TUD_AUDIO_N_CHANNELS_RX == 1 + #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + TUD_AUDIO_SPEAKER_MONO_FB_DESCRIPTOR(ITF_NUM_AUDIO_AC, 0, 2, 16, ISO_EP, 100, 0x80 | ISO_EP), +#else + TUD_AUDIO_SPEAKER_MONO_DESCRIPTOR(ITF_NUM_AUDIO_AC, 0, CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX, + 8 * CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX, ISO_EP, CFG_TUD_AUDIO_EPSIZE_OUT), +#endif +#endif +}; + +/** + * Invoked when received GET CONFIGURATION DESCRIPTOR + * Application return pointer to descriptor + * Descriptor contents must exist long enough for transfer to complete + */ +const uint8_t * +tud_descriptor_configuration_cb(uint8_t index) +{ + (void)index; + + return desc_configuration; +} + +static uint16_t desc_string[MYNEWT_VAL(USBD_STRING_DESCRIPTOR_MAX_LENGTH) + 1]; + +#if CFG_TUD_AUDIO + +#if CFG_TUD_AUDIO_IN +const uint16_t tud_audio_desc_lengths[] = {TUD_AUDIO_MIC2_DESC_LEN}; +#elif CFG_TUD_AUDIO_OUT && CFG_TUD_AUDIO_N_CHANNELS_RX == 1 +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +const uint16_t tud_audio_desc_lengths[] = {TUD_AUDIO_SPEAKER_MONO_FB_DESC_LEN}; +#else +const uint16_t tud_audio_desc_lengths[] = {TUD_AUDIO_SPEAKER_MONO_DESC_LEN}; +#endif +#elif CFG_TUD_AUDIO_OUT && CFG_TUD_AUDIO_N_CHANNELS_RX == 2 +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP +const uint16_t tud_audio_desc_lengths[] = {TUD_AUDIO_SPEAKER_STEREO_FB_DESC_LEN}; +#else +const uint16_t tud_audio_desc_lengths[] = {TUD_AUDIO_SPEAKER_STEREO_DESC_LEN}; +#endif +#endif + +static uint32_t g_sample_rate = CFG_TUD_AUDIO_SAMPLE_RATE; +static usb_audio_sample_rate_cb_t sample_rate_cb; + +/* Invoked when audio class specific set request received for an entity */ +bool +tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff) +{ + uint32_t new_sample_rate; + + (void) rhport; + audio_control_request_t *request = (audio_control_request_t *) p_request; + + if (request->bEntityID == 2 && request->bControlSelector == AUDIO_FU_CTRL_VOLUME && + request->bRequest == AUDIO_CS_REQ_CUR) { + /* Ignore value but accept request */ + return true; + } else if (request->bEntityID == 4 && request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ && + request->bRequest == AUDIO_CS_REQ_CUR) { + /* Ignore value but accept request */ + new_sample_rate = ((audio_control_cur_4_t *)(pBuff))->bCur; + if (new_sample_rate != g_sample_rate) { + g_sample_rate = new_sample_rate; + if (sample_rate_cb) { + sample_rate_cb(g_sample_rate); + } + } + return true; + } else { + __BKPT(1); + } + return false; +} + +bool +tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request) +{ + (void) rhport; + audio_control_request_t *request = (audio_control_request_t *) p_request; + if (request->bEntityID == 4 && request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) { + if (request->bRequest == AUDIO_CS_REQ_CUR) { + audio_control_cur_4_t curf = {g_sample_rate}; + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &curf, sizeof(curf)); + } else if (request->bRequest == AUDIO_CS_REQ_RANGE) { +#if 1 + audio_control_range_4_n_t(1) rangef = { + .wNumSubRanges = 1, + .subrange[0] = {g_sample_rate, g_sample_rate, 0}, + }; +#else + audio_control_range_4_n_t(2) rangef = { + .wNumSubRanges = 2, + .subrange[0] = {16000, 16000, 0}, + .subrange[1] = {48000, 48000, 0}, + }; +#endif + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &rangef, sizeof(rangef)); + } + } else if (request->bEntityID == 5 && request->bControlSelector == AUDIO_CX_CTRL_CONTROL) { + if (request->bRequest == AUDIO_CS_REQ_CUR) { + audio_control_cur_1_t cur_clk = {1}; + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &cur_clk, sizeof(cur_clk)); + } + } else if (request->bEntityID == 4 && request->bControlSelector == AUDIO_CS_CTRL_CLK_VALID && + request->bRequest == AUDIO_CS_REQ_CUR) { + audio_control_cur_1_t cur_valid = {.bCur = 1}; + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &cur_valid, sizeof(cur_valid)); + } else if (request->bEntityID == 2 && request->bControlSelector == AUDIO_FU_CTRL_MUTE && + request->bRequest == AUDIO_CS_REQ_CUR) { + audio_control_cur_1_t mute = {.bCur = 0}; + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute, sizeof(mute)); + } else if (request->bEntityID == 2 && request->bControlSelector == AUDIO_FU_CTRL_VOLUME) { + if (request->bRequest == AUDIO_CS_REQ_RANGE) { + audio_control_range_2_n_t(1) range_vol = { + .wNumSubRanges = 1, + .subrange[0] = {0, 1000, 10} + }; + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &range_vol, sizeof(range_vol)); + } else if (request->bRequest == AUDIO_CS_REQ_CUR) { + audio_control_cur_2_t cur_vol = {.bCur = 1280}; + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &cur_vol, sizeof(cur_vol)); + } + } else { + __BKPT(1); + } + return false; +} + +#endif + +/* Function converts ASCII string to USB descriptor format */ +static uint16_t * +string_to_usb_desc_string(const char *str, uint16_t *desc, uint8_t desc_size) +{ + int i; + int char_num = strlen(str); + + assert(char_num < desc_size); + if (char_num >= desc_size) { + char_num = desc_size - 1; + } + + /* Encode length in first byte, type in second byte */ + desc[0] = tu_htole16(tu_u16(TUSB_DESC_STRING, 2 * (char_num + 1))); + + /* Copy characters 8bit to 16 bits */ + for (i = 0; i < char_num; ++i) { + desc[1 + i] = tu_htole16(str[i]); + } + + return desc; +} + +/* LANGID string descriptors */ +static const uint16_t usbd_lang_id[2] = { + (TUSB_DESC_STRING << 8) + 4, /* Size of this descriptor */ + tu_htole16(MYNEWT_VAL(USBD_LANGID)) +}; + +static struct { + uint16_t major; + uint16_t minor; + uint16_t revision; + uint32_t build; +} img_version = { + 1, 0, 0, 1 +}; + +static char serial_number[11]; + +static uint16_t * +serial_to_usb_desc_string(uint16_t *desc, size_t size) +{ + if (serial_number[0] == 0) { + uint64_t serial = MYNEWT_VAL(USBD_SERIAL_ID); + + snprintf(serial_number, 11, "%010" PRIu64, serial); + } + + return string_to_usb_desc_string(serial_number, desc, size); +} + +/* + * Invoked when received GET STRING DESCRIPTOR request + * Application return pointer to descriptor, whose contents must exist long enough for transfer to complete + */ +const uint16_t * +tud_descriptor_string_cb(uint8_t index, uint16_t langid) +{ + const uint16_t *ret = NULL; + char interface[100]; + +#if MYNEWT_VAL(USBD_WINDOWS_COMP_ID) + if (index == USB_STRING_DESCRIPTOR_MICROSOFT_OS) { + ret = (const uint16_t *)microsoft_os_string_descriptor; + } +#endif + if (index == USB_STRING_DESCRIPTOR_LANG) { + ret = usbd_lang_id; + } else if (index == USB_STRING_DESCRIPTOR_SERIAL) { + ret = serial_to_usb_desc_string(desc_string, ARRAY_SIZE(desc_string)); + } else if (index == USB_STRING_DESCRIPTOR_MANUFACTURER) { + ret = string_to_usb_desc_string(MYNEWT_VAL(USBD_VENDOR_STRING), desc_string, ARRAY_SIZE(desc_string)); + } else if (index == USB_STRING_DESCRIPTOR_PRODUCT) { + ret = string_to_usb_desc_string(MYNEWT_VAL(USBD_PRODUCT_STRING), desc_string, ARRAY_SIZE(desc_string)); + } else if (index == USB_STRING_DESCRIPTOR_INTERFACE) { + snprintf(interface, sizeof(interface), "%s, (%u.%u.%u.%lu)", MYNEWT_VAL(USBD_PRODUCT_STRING), + img_version.major, img_version.minor, img_version.revision, img_version.build); + ret = string_to_usb_desc_string(interface, desc_string, ARRAY_SIZE(desc_string)); + } + return ret; +} + +void +usb_desc_sample_rate_set(uint32_t sample_rate) +{ + g_sample_rate = sample_rate; +} diff --git a/apps/auracast_usb/syscfg.usb.yml b/apps/auracast_usb/syscfg.usb.yml new file mode 100644 index 0000000000..d9967b5128 --- /dev/null +++ b/apps/auracast_usb/syscfg.usb.yml @@ -0,0 +1,174 @@ +# 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. + +syscfg.defs.TINYUSB: + USBD_STRING_DESCRIPTOR_MAX_LENGTH: + description: Maximum length of string descriptor in characters + value: 31 + USBD_EP0_SIZE: + description: > + Endpoint 0 size + value: 64 + USBD_SERIAL_ID: + description: Serial ID + value: 1 + restrictions: + - $notnull + USBD_VID: + description: Vendor ID + value: + restrictions: + - $notnull + USBD_PID: + description: Product ID + value: + restrictions: + - $notnull + USBD_PRODUCT_RELEASE_NUMBER: + description: Product release number needed for USB descriptor + value: 0x100 + USBD_CONFIGURATION_MAX_POWER: + description: > + Maximum power consumption of the USB device from the bus in this specific + configuration when the device is fully operational. Expressed in 2 mA units + (i.e., 50 = 100 mA). + value: 100 + USBD_LANGID: + description: Language ID as specified by usb.org + value: 0x0409 + USBD_VENDOR_STRING: + description: Manufacturer identification string + value: '"Apache Software Foundation"' + USBD_PRODUCT_STRING: + description: Device friendly name + value: '"NimBLE Auracast"' + USBD_CDC: + description: Enable CDC device + value: 0 + USBD_CDC_CONSOLE: + description: Enable CDC device function for console in TinyUSB stack. + value: + USBD_HID: + description: Enable HID device + value: 0 + USBD_MSC: + description: Enable MSC device + value: 0 + USBD_BTH: + description: Enable BT HCI device + value: 0 + USBD_AUDIO: + description: Enable Audio device + value: 0 + USBD_AUDIO_IN: + description: Enable Audio device + value: 0 + USBD_AUDIO_OUT: + description: Enable Audio device + value: 1 + USBD_AUDIO_IN_OUT: + description: Enable Audio device + value: 0 + USB_AUDIO_OUT_CHANNELS: + description: Number of audio channels on USB stream + value: MYNEWT_VAL(AURACAST_CHAN_NUM) + USB_AUDIO_OUT_SAMPLE_RATE: + description: USB sample rate + value: 48000 + + USBD_CDC_DATA_OUT_EP: + description: CDC data out endpoint number + value: + USBD_CDC_DATA_IN_EP: + description: CDC data out endpoint number + value: + USBD_CDC_DATA_EP_SIZE: + description: CDC data endpoint size + value: + USBD_CDC_NOTIFY_EP: + description: CDC notify endpoint number + value: + USBD_CDC_NOTIFY_EP_SIZE: + description: CDC notify endpoint size + value: + + USBD_CDC_DESCRIPTOR_STRING: + description: String for CDC interface + value: NULL + + USBD_MSC_DESCRIPTOR_STRING: + description: String for MSC interface + value: NULL + + USBD_HID_DESCRIPTOR_STRING: + description: String for HID interface + value: NULL + + USBD_BTH_DESCRIPTOR_STRING: + description: String for BT descriptor + value: NULL + + USBD_HID_REPORT_EP: + description: HID report endpoint number + value: + USBD_HID_REPORT_EP_SIZE: + description: HID report endpoint size + value: + USBD_HID_REPORT_EP_INTERVAL: + description: HID report endpoint interval + value: + + USBD_HID_REPORT_ID_KEYBOARD: + description: HID keyboard report ID + value: + USBD_HID_CAPS_LOCK_LED_PIN: + description: Caps Lock LED + value: -1 + USBD_HID_CAPS_LOCK_LED_ON_VALUE: + description: Value to set to pin to turn led on + value: 0 + USBD_HID_NUM_LOCK_LED_PIN: + description: Num Lock LED + value: -1 + USBD_HID_NUM_LOCK_LED_ON_VALUE: + description: Value to set to pin to turn led on + value: 0 + USBD_HID_REPORT_ID_MOUSE: + description: HID keyboard report ID + value: + + USBD_BTH_EVENT_EP: + description: BTH event endpoint number + value: + USBD_BTH_EVENT_EP_SIZE: + description: BTH event endpoint size + value: + USBD_BTH_EVENT_EP_INTERVAL: + description: BTH event endpoint interval + value: + USBD_BTH_DATA_IN_EP: + description: BTH data in endpoint number + value: + USBD_BTH_DATA_OUT_EP: + description: BTH data out endpoint number + value: + USBD_BTH_DATA_EP_SIZE: + description: BTH data endpoints size + value: + +syscfg.restrictions: + - '!USBD_STD_DESCRIPTORS' diff --git a/apps/auracast_usb/syscfg.yml b/apps/auracast_usb/syscfg.yml new file mode 100644 index 0000000000..1cad13b557 --- /dev/null +++ b/apps/auracast_usb/syscfg.yml @@ -0,0 +1,132 @@ +# 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. + +syscfg.defs: + ISO_HCI_FEEDBACK: + description: Enable HCI feedback for resampler. This reduces jitter between USB and ISO. + value: 1 + + AURACAST_CHAN_NUM: 2 + + BROADCAST_ID: + description: Broadcast ID value, will use random number if 0 + value: 0x000000 + BROADCAST_NAME: + description: Broadcast name + value: '"NimBLE Auracast"' + BROADCAST_CODE: + description: Broadcast code used for encrpytion + value: '"listen2nimble"' + + LC3_FRAME_DURATION: + description: LC3 frame duration + value: 10000 + LC3_SAMPLING_FREQ: + description: LC3 sampling frequency + value: 24000 + LC3_BITRATE: + description: LC3 bitrate + value: 24000 + + BIG_PHY: + description: + value: 3 + BIG_NUM_BIS: + description: Max number of BISes used + value: 2 + BIG_RTN: + description: BIG RTN (number of retransmissions) + value: 0 + BIG_PACKING: + description: Arrangement of BIS subevents (0 = sequential, 1 = interleaved) + value: 0 + BIG_FRAMING: + description: + value: 0 + BIG_ENCRYPTION: + description: BIS encryption + value: 0 + +syscfg.vals: + CONSOLE_IMPLEMENTATION: full + LOG_IMPLEMENTATION: full + STATS_IMPLEMENTATION: full + + # Disable not used GAP roles (we only do non-connectable + # advertising here) + BLE_ROLE_BROADCASTER: 1 + BLE_ROLE_CENTRAL: 0 + BLE_ROLE_OBSERVER: 0 + BLE_ROLE_PERIPHERAL: 0 + + # Enable Extended Advertising + BLE_EXT_ADV: 1 + + # Enable Periodic Advertising + BLE_PERIODIC_ADV: 1 + + # Max advertising data size + BLE_EXT_ADV_MAX_SIZE: 261 + + # Number of multi-advertising instances. Note that due + # to historical reasonds total number of advertising + # instances is BLE_MULTI_ADV_INSTANCES + 1 as instance + # 0 is always available + BLE_MULTI_ADV_INSTANCES: 1 + + # Controller uses msys pool for storing advertising data and scan responses. + # Since we advertise a lot of data (~6k in total) at the same time we need + # to increase block count. + MSYS_1_BLOCK_COUNT: 32 + + BLE_PHY_2M: 1 + + BLE_VERSION: 54 + BLE_ISO: 1 + BLE_ISO_BROADCAST_SOURCE: 1 + BLE_ISO_MAX_BIGS: 1 + BLE_ISO_MAX_BISES: 2 + + USBD_VID: 0xFFFF + USBD_PID: 0x0001 + USBD_VENDOR_STRING: '"Apache Software Foundation"' + USBD_PRODUCT_STRING: '"NimBLE Auracast"' + USBD_AUDIO_OUT: 1 + USB_AUDIO_OUT_CHANNELS: MYNEWT_VAL(AURACAST_CHAN_NUM) + + # resampler + encoder + LIBSAMPLERATE_ENABLE_SINC_BEST_CONVERTER: 0 + LIBSAMPLERATE_ENABLE_SINC_MEDIUM_CONVERTER: 0 + LIBSAMPLERATE_ENABLE_SINC_FAST_CONVERTER: 1 + LIBSAMPLERATE_LIBSAMPLER_NDEBUG: 1 + + MCU_HFCLK_DIV: 1 + HARDFLOAT: 1 + +syscfg.vals.TINYUSB: + USBD_STACK_SIZE: 500 + USBD_STD_DESCRIPTORS: 0 + +syscfg.vals.ISO_HCI_FEEDBACK: + BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS: 1000 + BLE_HS_GAP_UNHANDLED_HCI_EVENT: 1 + +syscfg.vals.BSP_NRF52: + BLE_PHY_NRF52_HEADERMASK_WORKAROUND: 1 + +$import: + - "@apache-mynewt-nimble/apps/auracast_usb/syscfg.usb.yml" \ No newline at end of file From 0c401ebb0c966cdab59b71e7bd5609519227b303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 27 Feb 2024 10:09:26 +0100 Subject: [PATCH 0991/1333] targets: add target for auracast_usb app Adds build target for auracast_usb application. --- targets/auracast_usb/nrf5340-mcu.ld | 220 ++++++++++++++++++++++++++++ targets/auracast_usb/nrf5340.ld | 26 ++++ targets/auracast_usb/pkg.yml | 24 +++ targets/auracast_usb/syscfg.yml | 25 ++++ targets/auracast_usb/target.yml | 27 ++++ 5 files changed, 322 insertions(+) create mode 100644 targets/auracast_usb/nrf5340-mcu.ld create mode 100644 targets/auracast_usb/nrf5340.ld create mode 100755 targets/auracast_usb/pkg.yml create mode 100755 targets/auracast_usb/syscfg.yml create mode 100755 targets/auracast_usb/target.yml diff --git a/targets/auracast_usb/nrf5340-mcu.ld b/targets/auracast_usb/nrf5340-mcu.ld new file mode 100644 index 0000000000..2e2e4f1679 --- /dev/null +++ b/targets/auracast_usb/nrf5340-mcu.ld @@ -0,0 +1,220 @@ +/* Linker script for Nordic Semiconductor nRF5 devices + * + * Version: Sourcery G++ 4.5-1 + * Support: https://support.codesourcery.com/GNUToolchain/ + * + * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __bssnz_start__ + * __bssnz_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .imghdr (NOLOAD): + { + . = . + _imghdr_size; + } > FLASH + + __text = .; + + .text : + { + __isr_vector_start = .; + KEEP(*(.isr_vector)) + __isr_vector_end = .; + EXCLUDE_FILE(*liblc3.a: *libm.a: *libsamplerate.a: *audio_usb.o) *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + EXCLUDE_FILE(*liblc3.a: *libsamplerate.a:) *(.rodata*) + + *(.eh_frame*) + PROVIDE(mynewt_main = main); + . = ALIGN(4); + } > FLASH + + + .net_core_img : + { + PROVIDE(net_core_img_start = .); + KEEP(*(.net_core_img)); + PROVIDE(net_core_img_end = .); + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + . = ALIGN(4); + } > FLASH + __exidx_end = .; + + __etext = .; + + .vector_relocation : + { + . = ALIGN(4); + __vector_tbl_reloc__ = .; + . = . + (__isr_vector_end - __isr_vector_start); + . = ALIGN(4); + } > RAM + + /* Section for app-net cores IPC */ + .ipc 0x20000400 (NOLOAD): + { + . = ALIGN(4); + *(.ipc) + . = ALIGN(4); + } > RAM + + /* This section will be zeroed by RTT package init */ + .rtt (NOLOAD): + { + . = ALIGN(4); + *(.rtt) + . = ALIGN(4); + } > RAM + + .data : + { + __data_start__ = .; + *(vtable) + *(.data*) + + *(.jcr) + *liblc3.a:(.text* .rodata*) + *libsamplerate.a:(.text* .rodata*) + *audio_usb.o(.text*) + *libm.a:(.text*) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > RAM AT > FLASH + + /* Non-zeroed BSS. This section is similar to BSS, but does not get zeroed at init-time. + */ + .bssnz : + { + . = ALIGN(4); + __bssnz_start__ = .; + *(.bss.core.nz*) + . = ALIGN(4); + __bssnz_end__ = .; + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + /* Heap starts after BSS */ + . = ALIGN(8); + __HeapBase = .; + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + _ram_start = ORIGIN(RAM); + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Top of head is the bottom of the stack */ + __HeapLimit = __StackLimit; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") +} + diff --git a/targets/auracast_usb/nrf5340.ld b/targets/auracast_usb/nrf5340.ld new file mode 100644 index 0000000000..6ee5122a54 --- /dev/null +++ b/targets/auracast_usb/nrf5340.ld @@ -0,0 +1,26 @@ +/* + * 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. + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x0000c000, LENGTH = 0x76000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x80000 +} + +/* This linker script is used for images and thus contains an image header */ +_imghdr_size = 0x20; diff --git a/targets/auracast_usb/pkg.yml b/targets/auracast_usb/pkg.yml new file mode 100755 index 0000000000..379a8ac882 --- /dev/null +++ b/targets/auracast_usb/pkg.yml @@ -0,0 +1,24 @@ +# +# 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: targets/auracast_usb +pkg.type: target +pkg.description: +pkg.author: +pkg.homepage: diff --git a/targets/auracast_usb/syscfg.yml b/targets/auracast_usb/syscfg.yml new file mode 100755 index 0000000000..2e58b5cbac --- /dev/null +++ b/targets/auracast_usb/syscfg.yml @@ -0,0 +1,25 @@ +# +# 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. +# + +syscfg.vals.BSP_NRF5340: + MCU_MPU_ENABLE: 0 + MCU_CACHE_ENABLED: 1 + BSP_NRF5340_NET_ENABLE: 1 + NRF5340_EMBED_NET_CORE: 1 + NET_CORE_IMAGE_TARGET_NAME: "@apache-mynewt-nimble/targets/nordic_pca10095_net-blehci_broadcaster" diff --git a/targets/auracast_usb/target.yml b/targets/auracast_usb/target.yml new file mode 100755 index 0000000000..3aa75b5248 --- /dev/null +++ b/targets/auracast_usb/target.yml @@ -0,0 +1,27 @@ +# +# 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. +# + +target.app: "@apache-mynewt-nimble/apps/auracast_usb" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10121" +target.build_profile: speed + +# linkerscrupt that moves audio processing to RAM, for better performance +bsp.linkerscript: + - "@apache-mynewt-nimble/targets/auracast_usb/nrf5340.ld" + - "@apache-mynewt-nimble/targets/auracast_usb/nrf5340-mcu.ld" From 2c1b130cf0f27f91acd2c0d7f7693a8b8c914dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 15 Mar 2024 08:24:59 +0100 Subject: [PATCH 0992/1333] apps/auracast_usb: use float instead of double Cortex M-33 FPU doesn't support double precision arithmetic. Use float instead of double so the performance can be improved. This allows to use better interpolator in resampler. --- apps/auracast_usb/src/audio_usb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/auracast_usb/src/audio_usb.c b/apps/auracast_usb/src/audio_usb.c index c63f688ce0..d0c5fee411 100644 --- a/apps/auracast_usb/src/audio_usb.c +++ b/apps/auracast_usb/src/audio_usb.c @@ -60,9 +60,9 @@ static int16_t samples_read[AUDIO_BUF_SIZE]; /* 155 is maximum value Octets Per Codec Frame described in Table 3.5 of BAP specification */ static float samples_read_float[AUDIO_BUF_SIZE]; static float resampled_float[AUDIO_BUF_SIZE]; -double resampler_in_rate = AUDIO_PCM_SAMPLE_RATE; -double resampler_out_rate = LC3_SAMPLING_FREQ; -double resampler_ratio; +float resampler_in_rate = AUDIO_PCM_SAMPLE_RATE; +float resampler_out_rate = LC3_SAMPLING_FREQ; +float resampler_ratio; SRC_STATE *resampler_state; static struct ble_gap_event_listener feedback_listener; #endif @@ -74,7 +74,7 @@ static int ble_hs_gap_event_handler(struct ble_gap_event *event, void *arg) { struct ble_hci_vs_subev_iso_hci_feedback *feedback_pkt; - double adjust = 0; + float adjust = 0; if (event->type == BLE_GAP_EVENT_UNHANDLED_HCI_EVENT && event->unhandled_hci.is_le_meta == false && @@ -266,7 +266,7 @@ audio_usb_init(void) int rc; assert(resampler_state == NULL); - resampler_state = src_new(SRC_ZERO_ORDER_HOLD, AUDIO_CHANNELS, NULL); + resampler_state = src_new(SRC_SINC_FASTEST, AUDIO_CHANNELS, NULL); assert(resampler_state != NULL); rc = ble_gap_event_listener_register(&feedback_listener, From 61021c15754056d44d0485e8da01262bb1bd1c02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 15 Mar 2024 08:27:44 +0100 Subject: [PATCH 0993/1333] ext/libsamplerate: compile using single precision floating point numbers Compile using floats instead of doubles, so the FPUs that don't support double-precision arithmetic can be used. --- ext/libsamplerate/pkg.yml | 5 ++++- ext/libsamplerate/src/config.h | 4 ---- ext/libsamplerate/syscfg.yml | 3 --- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/ext/libsamplerate/pkg.yml b/ext/libsamplerate/pkg.yml index 4bb8089027..94a950261d 100644 --- a/ext/libsamplerate/pkg.yml +++ b/ext/libsamplerate/pkg.yml @@ -26,9 +26,12 @@ pkg.keywords: pkg.type: sdk -pkg.cflags: -DHAVE_STDBOOL_H -fsingle-precision-constant -DHAVE_CONFIG_H -DNDEBUG +pkg.cflags: -O3 -DHAVE_STDBOOL_H -fsingle-precision-constant -DHAVE_CONFIG_H -DNDEBUG -DLIBSAMPLERATE_SINGLE_PRECISION pkg.lflags: -lm +app.cflags: + - -DLIBSAMPLERATE_SINGLE_PRECISION + pkg.src_dirs: - "@libsamplerate/src" diff --git a/ext/libsamplerate/src/config.h b/ext/libsamplerate/src/config.h index 9c77c58e4f..dca00b2b89 100644 --- a/ext/libsamplerate/src/config.h +++ b/ext/libsamplerate/src/config.h @@ -34,10 +34,6 @@ #define ENABLE_SINC_FAST_CONVERTER 1 #endif -#if MYNEWT_VAL(LIBSAMPLERATE_LIBSAMPLER_NDEBUG) -#define LIBSAMPLER_NDEBUG 1 -#endif - #define PACKAGE "libsamplerate" #define VERSION "0.2.2" diff --git a/ext/libsamplerate/syscfg.yml b/ext/libsamplerate/syscfg.yml index 285820045f..730d84d1d1 100644 --- a/ext/libsamplerate/syscfg.yml +++ b/ext/libsamplerate/syscfg.yml @@ -25,6 +25,3 @@ syscfg.defs: LIBSAMPLERATE_ENABLE_SINC_FAST_CONVERTER: description: Enable SINC fastest converter value: 1 - LIBSAMPLERATE_LIBSAMPLER_NDEBUG: - description: Define NDEBUG for resampler code (turns off asserts) - value: 0 From 1543982424d3c5ef7d4c4dbae2203f8e3c020f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Wed, 17 Apr 2024 14:41:40 +0200 Subject: [PATCH 0994/1333] host/ble_l2cap_coc: fix possible race condition in L2CAP COC Two functions: `ble_l2cap_coc_continue_tx` and `ble_l2cap_coc_recv_ready` can be reached from other task than host, for example separate thread running in application, by calling `ble_l2cap_recv_ready` or `ble_l2cap_send`. Because pointer to chan passed into these functions may be outdated (connection is being terminated by host) this will lead to either: - triggering BLE_HS_DBG_ASSERT(conn != NULL) in ble_hs_conn_find_assert - dereferencing NULL pointer to conn, after ble_hs_conn_find_assert returns NULL (case with disabled BLE_HS_DEBUG) These two cases shall not cause assert, and should be prepared for chan not existing anymore. Now, BLE_HS_ENOTCONN is returned if connection no longer exists. --- nimble/host/src/ble_l2cap_coc.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c index 25727ee19c..a3d1b1c22d 100644 --- a/nimble/host/src/ble_l2cap_coc.c +++ b/nimble/host/src/ble_l2cap_coc.c @@ -506,7 +506,12 @@ ble_l2cap_coc_continue_tx(struct ble_l2cap_chan *chan) goto failed; } - conn = ble_hs_conn_find_assert(chan->conn_handle); + conn = ble_hs_conn_find(chan->conn_handle); + if (!conn) { + rc = BLE_HS_ENOTCONN; + BLE_HS_LOG(DEBUG, "Connection does not exist"); + goto failed; + } rc = ble_l2cap_tx(conn, chan, txom); if (rc) { @@ -619,7 +624,13 @@ ble_l2cap_coc_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx) (chan->coc_rx.next_sdu_alloc_idx + 1) % BLE_L2CAP_SDU_BUFF_CNT; ble_hs_lock(); - conn = ble_hs_conn_find_assert(chan->conn_handle); + conn = ble_hs_conn_find(chan->conn_handle); + if (!conn) { + BLE_HS_LOG(DEBUG, "Connection does not exist"); + ble_hs_unlock(); + return BLE_HS_ENOTCONN; + } + c = ble_hs_conn_chan_find_by_scid(conn, chan->scid); if (!c) { ble_hs_unlock(); From 6ce56a4fa009c8b9cb469279f53d3a0e38c1e845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 26 Apr 2024 09:18:27 +0200 Subject: [PATCH 0995/1333] host/audio: add defines for Codec Formats Adds Codec Formats from Assigned Numbers. --- nimble/host/audio/include/audio/ble_audio.h | 34 +++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/nimble/host/audio/include/audio/ble_audio.h b/nimble/host/audio/include/audio/ble_audio.h index 59122cfa8f..05a583be22 100644 --- a/nimble/host/audio/include/audio/ble_audio.h +++ b/nimble/host/audio/include/audio/ble_audio.h @@ -71,6 +71,40 @@ /** Public Broadcast Announcement Service UUID. */ #define BLE_BROADCAST_PUB_ANNOUNCEMENT_SVC_UUID 0x1856 +/** + * @defgroup ble_audio_codec_formats Bluetooth Low Energy Audio Codec Formats + * @{ + */ + +/** BLE Audio codec format - μ-law log */ +#define BLE_AUDIO_CODEC_FORMAT_MU_LAW_LOG 0x00 + +/** BLE Audio codec format - A-law log */ +#define BLE_AUDIO_CODEC_FORMAT_A_LAW_LOG 0x01 + +/** BLE Audio codec format - CVSD */ +#define BLE_AUDIO_CODEC_FORMAT_CVSD 0x02 + +/** BLE Audio codec format - Transparent */ +#define BLE_AUDIO_CODEC_FORMAT_TRANSPARENT 0x03 + +/** BLE Audio codec format - Linear PCM */ +#define BLE_AUDIO_CODEC_FORMAT_LINEAR_PCM 0x04 + +/** BLE Audio codec format - mSBC */ +#define BLE_AUDIO_CODEC_FORMAT_MSBC 0x05 + +/** BLE Audio codec format - LC3 */ +#define BLE_AUDIO_CODEC_FORMAT_LC3 0x06 + +/** BLE Audio codec format - G.729A */ +#define BLE_AUDIO_CODEC_FORMAT_G_729A 0x07 + +/** BLE Audio codec format - Vendor Specific */ +#define BLE_AUDIO_CODEC_FORMAT_VENDOR_SPECIFIC 0xFF + +/** @} */ + /** * @defgroup ble_audio_sampling_rates Bluetooth Low Energy Audio Sampling Rates * @{ From 4ebbbf287b85f019e988a66d45c6d6f7f72a83e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 9 Feb 2024 14:55:20 +0100 Subject: [PATCH 0996/1333] nimble/host: Add Broadcast Audio Scan Service BASS initial implementation --- nimble/host/audio/include/audio/ble_audio.h | 82 ++ .../services/bass/ble_audio_svc_bass.h | 466 +++++++++ nimble/host/audio/services/bass/pkg.yml | 33 + .../services/bass/src/ble_audio_svc_bass.c | 890 ++++++++++++++++++ nimble/host/audio/services/bass/syscfg.yml | 38 + nimble/host/include/host/ble_att.h | 12 + 6 files changed, 1521 insertions(+) create mode 100644 nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h create mode 100644 nimble/host/audio/services/bass/pkg.yml create mode 100644 nimble/host/audio/services/bass/src/ble_audio_svc_bass.c create mode 100644 nimble/host/audio/services/bass/syscfg.yml diff --git a/nimble/host/audio/include/audio/ble_audio.h b/nimble/host/audio/include/audio/ble_audio.h index 05a583be22..836a1ab532 100644 --- a/nimble/host/audio/include/audio/ble_audio.h +++ b/nimble/host/audio/include/audio/ble_audio.h @@ -65,6 +65,9 @@ * @endcond */ +/** Broadcast Audio Broadcast Code Size. */ +#define BLE_AUDIO_BROADCAST_CODE_SIZE 16 + /** Broadcast Audio Announcement Service UUID. */ #define BLE_BROADCAST_AUDIO_ANNOUNCEMENT_SVC_UUID 0x1852 @@ -561,6 +564,18 @@ struct ble_audio_broadcast_name { /** BLE Audio event: Codec Unregistered */ #define BLE_AUDIO_EVENT_CODEC_UNREGISTERED 2 +/** BLE Audio event: BASS - Remote Scan Stopped */ +#define BLE_AUDIO_EVENT_BASS_REMOTE_SCAN_STOPPED 3 + +/** BLE Audio event: BASS - Remote Scan Started */ +#define BLE_AUDIO_EVENT_BASS_REMOTE_SCAN_STARTED 4 + +/** BLE Audio event: BASS - Operation status */ +#define BLE_AUDIO_EVENT_BASS_OPERATION_STATUS 5 + +/** BLE Audio event: BASS - Set Broadcast Code */ +#define BLE_AUDIO_EVENT_BASS_BROADCAST_CODE_SET 6 + /** @} */ /** @brief Broadcast Announcement */ @@ -596,6 +611,45 @@ struct ble_audio_event_codec_unregistered { const struct ble_audio_codec_record *record; }; +/** @brief BASS Source Removed */ +struct ble_audio_event_bass_remote_scan { + /** Connection Handle of Broadcast Assistant that is performing Scan procedure for us */ + uint16_t conn_handle; +}; + +/** BASS Operation status OP code */ +enum ble_audio_event_bass_operation_statu_op { + /** BLE Audio event: BASS - Add Source */ + BLE_AUDIO_EVENT_BASS_SOURCE_ADDED, + + /** BLE Audio event: BASS - Modify Source */ + BLE_AUDIO_EVENT_BASS_SOURCE_MODIFIED, + + /** BLE Audio event: BASS - Remove Source */ + BLE_AUDIO_EVENT_BASS_SOURCE_REMOVED, +}; + +/** @brief BASS operation status */ +struct ble_audio_event_bass_op_status { + /** Source ID */ + uint8_t source_id; + + /** Operation */ + enum ble_audio_event_bass_operation_statu_op op; + + /** Event status. 0 on success, BLE_HS Error code otherwise */ + uint8_t status; +}; + +/** @brief BASS Set Broadcast Code */ +struct ble_audio_event_bass_set_broadcast_code { + /** Source ID */ + uint8_t source_id; + + /** Source ID */ + uint8_t broadcast_code[BLE_AUDIO_BROADCAST_CODE_SIZE]; +}; + /** * Represents a BLE Audio related event. When such an event occurs, the host * notifies the application by passing an instance of this structure to an @@ -633,6 +687,34 @@ struct ble_audio_event { * Represents a codec registration. */ struct ble_audio_event_codec_unregistered codec_unregistered; + + /** + * @ref BLE_AUDIO_EVENT_BASS_REMOTE_SCAN_STOPPED + * + * Represents a Scan procedure termination by Broadcast Assistant. + */ + struct ble_audio_event_bass_remote_scan remote_scan_stopped; + + /** + * @ref BLE_AUDIO_EVENT_BASS_REMOTE_SCAN_STARTED + * + * Represents a Scan procedure start by Broadcast Assistant. + */ + struct ble_audio_event_bass_remote_scan remote_scan_started; + + /** + * @ref BLE_AUDIO_EVENT_BASS_SOURCE_ADDED + * + * Represents a Broadcast Source being added to BASS. + */ + struct ble_audio_event_bass_op_status bass_operation_status; + + /** + * @ref BLE_AUDIO_EVENT_BASS_BROADCAST_CODE_SET + * + * Represents a Broadcast Code baing set in BASS. + */ + struct ble_audio_event_bass_set_broadcast_code bass_set_broadcast_code; }; }; diff --git a/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h b/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h new file mode 100644 index 0000000000..431ecb968c --- /dev/null +++ b/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h @@ -0,0 +1,466 @@ +/** + * 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_BLE_AUDIO_SVC_BASS_ +#define H_BLE_AUDIO_SVC_BASS_ + +#include +#include "audio/ble_audio.h" +#include "syscfg/syscfg.h" + +/** + * @file ble_audio_svc_bass.h + * + * @brief Bluetooth LE Audio BAS Service + * + * This header file provides the public API for interacting with the BASS package. + * + * @defgroup ble_audio_svc_bass Bluetooth LE Audio BASS package + * @ingroup bt_host + * @{ + * + * This package implements BASS service. Receiver states can be modified with setter functions + * or GATT writes to Control Point characteristic. Operations on Control Point like Add Source or + * Modify Source can be accepted or rejected by application by registering accept function callback. + * Accessing Control Point characteristic, or Successful modification or Receiver State will lead to + * emission of one of BLE_SVC_AUDIO_BASS events. + * + */ + +/** BLE AUDIO BASS Maximum Subgroup Number */ +#define BLE_SVC_AUDIO_BASS_SUB_NUM_MAX \ + MYNEWT_VAL(BLE_SVC_AUDIO_BASS_SUB_NUM_MAX) + +/** BLE AUDIO BASS characteristic UUID */ +#define BLE_SVC_AUDIO_BASS_UUID16 0x184F + +/** BLE AUDIO BASS Control Point characteristic UUID */ +#define BLE_SVC_AUDIO_BASS_CHR_UUID16_BASS_CP 0x2BC7 + +/** BLE AUDIO BASS Broadcast Receiver State characteristic UUID */ +#define BLE_SVC_AUDIO_BASS_CHR_UUID16_BROADCAST_RECEIVE_STATE 0x2BC8 + +/** BLE AUDIO BASS Add Source operation OP code */ +#define BLE_SVC_AUDIO_BASS_OPERATION_ADD_SOURCE 0x01 + +/** BLE AUDIO BASS Modify Source operation OP code */ +#define BLE_SVC_AUDIO_BASS_OPERATION_MODIFY_SOURCE 0x02 + +/** BLE AUDIO BASS Remove Source operation OP code */ +#define BLE_SVC_AUDIO_BASS_OPERATION_REMOVE_SOURCE 0x03 + +/** BLE AUDIO BASS Error: OP Code not supported */ +#define BLE_SVC_AUDIO_BASS_ERR_OPCODE_NOT_SUPPORTED 0x80 + +/** BLE AUDIO BASS Error: Invalid Source ID */ +#define BLE_SVC_AUDIO_BASS_ERR_INVALID_SOURCE_ID 0x81 + +/** BLE AUDIO BASS Encryption States */ +enum ble_svc_audio_bass_big_enc { + /** BLE AUDIO BASS BIG Encryption: Not Encrypted */ + BLE_SVC_AUDIO_BASS_BIG_ENC_NOT_ENCRYPTED, + + /** BLE AUDIO BASS BIG Encryption: Broadcast Code Required */ + BLE_SVC_AUDIO_BASS_BIG_ENC_BROADCAST_CODE_REQ, + + /** BLE AUDIO BASS BIG Encryption: Decrypting */ + BLE_SVC_AUDIO_BASS_BIG_ENC_DECRYPTING, + + /** BLE AUDIO BASS BIG Encryption: Bad Code */ + BLE_SVC_AUDIO_BASS_BIG_ENC_BAD_CODE +}; + +/** BLE AUDIO BASS PA Sync parameters, valid fo Modify Source operation */ +enum ble_svc_audio_bass_pa_sync { + /** BLE AUDIO BASS PA Sync: Do not synchronize to PA */ + BLE_SVC_AUDIO_BASS_PA_SYNC_DO_NOT_SYNC, + + /** BLE AUDIO BASS PA Sync: Synchronize to PA – PAST available */ + BLE_SVC_AUDIO_BASS_PA_SYNC_SYNC_PAST_AVAILABLE, + + /** BLE AUDIO BASS PA Sync: Synchronize to PA – PAST not available */ + BLE_SVC_AUDIO_BASS_PA_SYNC_SYNC_PAST_NOT_AVAILABLE, + + /** + * BLE AUDIO BASS PA Sync: reserved for future use. + * This shall be always last value in this enum + */ + BLE_SVC_AUDIO_BASS_PA_SYNC_RFU +}; + +/** BLE AUDIO BASS Broadcast Receiver: PA Sync States */ +enum ble_svc_audio_bass_pa_sync_state { + /** BLE AUDIO BASS PA Sync State: Not synchronized to PA */ + BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_NOT_SYNCED, + + /** BLE AUDIO BASS PA Sync State: SyncInfo Request */ + BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_SYNC_INFO_REQ, + + /** BLE AUDIO BASS PA Sync State: Synchronized to PA */ + BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_SYNCED, + + /** BLE AUDIO BASS PA Sync State: Failed to synchronize to PAA */ + BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_SYNCED_FAILED, + + /** BLE AUDIO BASS PA Sync State: No PAST */ + BLE_SVC_AUDIO_BASS_PA_SYNC_STATE_NO_PAST +}; + +/** BLE AUDIO BASS Broadcast Receiver State: Subgroup entry */ +struct ble_svc_audio_bass_subgroup { + /** BLE AUDIO BASS Subgroup entry: Bis Synchronization State */ + uint32_t bis_sync_state; + + /** BLE AUDIO BASS Subgroup entry: Metadata length */ + uint8_t metadata_length; + + /** BLE AUDIO BASS Subgroup entry: Metadata */ + uint8_t *metadata; +}; + +/** BLE AUDIO BASS Broadcast Receiver State */ +struct ble_svc_audio_bass_receiver_state { + /** BLE AUDIO BASS Broadcast Receiver State: Source ID */ + uint8_t source_id; + + /** BLE AUDIO BASS Broadcast Receiver State: Source BLE Address */ + ble_addr_t source_addr; + + /** BLE AUDIO BASS Broadcast Receiver State: Source Advertising SID */ + uint8_t source_adv_sid; + + /** BLE AUDIO BASS Broadcast Receiver State: Broadcast ID */ + uint32_t broadcast_id; + + /** BLE AUDIO BASS Broadcast Receiver State: PA Sync state */ + enum ble_svc_audio_bass_pa_sync_state pa_sync_state; + + /** BLE AUDIO BASS Broadcast Receiver State: BIG Encryption */ + enum ble_svc_audio_bass_big_enc big_encryption; + + /** + * BLE AUDIO BASS Broadcast Receiver State: Bad Code. + * On GATT Read access, this value is ignored if big_encryption + * is not set to BLE_SVC_AUDIO_BASS_BIG_ENC_BAD_CODE + */ + uint8_t bad_code[BLE_AUDIO_BROADCAST_CODE_SIZE]; + + /** BLE AUDIO BASS Broadcast Receiver State: Number of subgroups */ + uint8_t num_subgroups; + + /** BLE AUDIO BASS Broadcast Receiver State: subgroup entries */ + struct ble_svc_audio_bass_subgroup + subgroups[BLE_SVC_AUDIO_BASS_SUB_NUM_MAX]; +}; + +/** BLE AUDIO BASS Broadcast Receiver State add parameters */ +struct ble_svc_audio_bass_receiver_state_add_params { + /** BLE AUDIO BASS Broadcast Receiver State: Source BLE Address */ + ble_addr_t source_addr; + + /** BLE AUDIO BASS Broadcast Receiver State: Source Advertising SID */ + uint8_t source_adv_sid; + + /** BLE AUDIO BASS Broadcast Receiver State: Broadcast ID */ + uint32_t broadcast_id; + + /** BLE AUDIO BASS Broadcast Receiver State: PA Sync state */ + enum ble_svc_audio_bass_pa_sync_state pa_sync_state; + + /** BLE AUDIO BASS Broadcast Receiver State: BIG Encryption */ + enum ble_svc_audio_bass_big_enc big_encryption; + + /** + * BLE AUDIO BASS Broadcast Receiver State: Bad Code. + * On GATT Read access, this value is ignored if big_encryption + * is not set to BLE_SVC_AUDIO_BASS_BIG_ENC_BAD_CODE + */ + const uint8_t *bad_code; + + /** BLE AUDIO BASS Broadcast Receiver State: Number of subgroups */ + uint8_t num_subgroups; + + /** BLE AUDIO BASS Broadcast Receiver State: subgroup entries */ + struct ble_svc_audio_bass_subgroup + subgroups[BLE_SVC_AUDIO_BASS_SUB_NUM_MAX]; +}; + +/** Parameters used for updating Metadata in Receiver State. */ +struct ble_svc_audio_bass_metadata_params { + /** Subgroup index */ + uint8_t subgroup_idx; + + /** Metadata length */ + uint8_t metadata_length; + + /** Metadata */ + const uint8_t *metadata; +}; + +/** Parameters used for updating Receiver State. */ +struct ble_svc_audio_bass_update_params { + /** PA Sync state */ + enum ble_svc_audio_bass_pa_sync_state pa_sync_state; + + /** BIG encryption state */ + enum ble_svc_audio_bass_big_enc big_encryption; + + /** Incorrect Bad Broadcast Code. Valid for BLE_SVC_AUDIO_BASS_BIG_ENC_BAD_CODE */ + const uint8_t *bad_code; + + /** BLE AUDIO BASS Broadcast Receiver State: Number of subgroups */ + uint8_t num_subgroups; + + /** BLE AUDIO BASS Broadcast Receiver State: subgroup entries */ + struct ble_svc_audio_bass_subgroup + subgroups[BLE_SVC_AUDIO_BASS_SUB_NUM_MAX]; +}; + +/** + * Structure describing operation attempted by write on + * BASS Control Point characteristic + */ +struct ble_svc_audio_bass_operation { + /** + * Indicates the type of BASS operation that occurred. This is one of the + * ble_svc_audio_bass_operation codes. + */ + uint8_t op; + + /** Connection handle for which the operation was performed */ + uint16_t conn_handle; + + /** + * A discriminated union containing additional details concerning the BASS Control Point + * event. The 'type' field indicates which member of the union is valid. + */ + union { + /** + * Represents Add Source operation. Valid for the following event + * types: + * o BLE_SVC_AUDIO_BASS_OPERATION_ADD_SOURCE + * Application can accept or reject Add Source operation. If no application callback is set + * and free Receive State characteristic exists operation is automatically accepted. + * If application callback exists and returns 0 operation is accepted. + * Otherwise, operation is rejected. + * If operation is accepted by application, it may select receiver state to be filled. + * If application doesnt select characteristic, BASS Server falls back + * to searching free one. If none is found, operation is rejected. + * After Add Source operation is accepted, BLE_AUDIO_EVENT is emitted. + */ + struct { + /** Source ID */ + uint8_t source_id; + + /** Advertiser Address */ + ble_addr_t adv_addr; + + /** Advertising SID */ + uint8_t adv_sid; + + /** Broadcast ID */ + uint32_t broadcast_id : 24; + + /** PA Sync */ + enum ble_svc_audio_bass_pa_sync pa_sync; + + /** PA Interval */ + uint16_t pa_interval; + + /** Number of subgroups */ + uint8_t num_subgroups; + + /** Subgroup entries */ + struct ble_svc_audio_bass_subgroup + subgroups[BLE_SVC_AUDIO_BASS_SUB_NUM_MAX]; + + /** + * Pointer to provide source ID to be swapped or NULL. + * + * Valid only if all other receive states are used. + * + * If there are insufficient resources to handle the operation, + * the application is requested to provide source ID to be + * removed once accepted. + */ + uint8_t *out_source_id_to_swap; + } add_source; + + /** + * Represents Modify Source operation. Valid for the following event + * types: + * o BLE_SVC_AUDIO_BASS_OPERATION_MODIFY_SOURCE + * Application can accept or reject Add Source operation. + * If no application callback is set + * or application callback returns 0 operation is automatically accepted. + * If application callback returns non-zero value operation is rejected. + */ + struct { + /** Source ID */ + uint8_t source_id; + + /** PA Sync */ + enum ble_svc_audio_bass_pa_sync pa_sync; + + /** PA Interval */ + uint16_t pa_interval; + + /** Number of subgroups */ + uint16_t num_subgroups; + + /** BIS Synchronisation of subgroups */ + uint32_t bis_sync[BLE_SVC_AUDIO_BASS_SUB_NUM_MAX]; + } modify_source; + + /** + * Represents Remove Source operation. Valid for the following event + * types: + * o BLE_SVC_AUDIO_BASS_OPERATION_REMOVE_SOURCE + */ + struct { + /** Source ID */ + uint8_t source_id; + } remove_source; + }; +}; + +/** + * Prototype of Accept Function callback for BASS Control Point operations. + * This function shall return 0 if operation is accepted, + * and error code if rejected. + */ +typedef int ble_svc_audio_bass_accept_fn(struct ble_svc_audio_bass_operation + *operation, void *arg); + +/** + * @brief Set Accept Function callback. + * + * Set Accept Function callback that will be used to accept or reject + * operations queried on BASS Control Point characteristic. If no function + * is registered, operations are accepted by default. Only one Accept + * Function can be registered at once. + * + * @param[in] fn ble_svc_audio_bass_accept_fn + * to be registered. + * @param[in] arg Optional ble_svc_audio_bass_accept_fn + * argument. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int +ble_svc_audio_bass_accept_fn_set(ble_svc_audio_bass_accept_fn *fn, void *arg); + +/** + * @brief Add Broadcast Receive State. + * + * Add new Broadcast Receive State to BASS. + * + * @param[in] params Parameters of new + * Broadcast Receive State. + * @param[out] source_id Source ID assigned by BASS to new + * Broadcast Receive State + * + * @return 0 on success; + * A non-zero value on failure. + */ +int +ble_svc_audio_bass_receive_state_add(const struct ble_svc_audio_bass_receiver_state_add_params *params, + uint8_t *source_id); + +/** + * @brief Remove Broadcast Receive State. + * + * Remove Broadcast Receive State from BASS. + * + * @param[in] source_id Source ID of Broadcast Receive State + * to be removed + * + * @return 0 on success; + * A non-zero value on failure. + */ +int +ble_svc_audio_bass_receive_state_remove(uint8_t source_id); + +/** + * @brief Update Broadcast Receive State metadata. + * + * Set Broadcast Receive State metadata to new value. + * + * @param[in] params Parameter structure with new metadata. + * @param[in] source_id Source ID of Broadcast Receive State + * + * @return 0 on success; + * A non-zero value on failure. + */ +int +ble_svc_audio_bass_update_metadata(const struct ble_svc_audio_bass_metadata_params *params, + uint8_t source_id); + +/** + * @brief Update Broadcast Receive State. + * + * Set Broadcast Receive State to new value. + * + * @param[in] params Parameter structure with new + * Receive State. + * @param[in] source_id Source ID of Broadcast Receive State + * + * @return 0 on success; + * A non-zero value on failure. + */ +int +ble_svc_audio_bass_receive_state_update(const struct + ble_svc_audio_bass_update_params *params, + uint8_t source_id); + +/** + * @brief Find Broadcast Receive State by Source ID. + * + * Get Broadcast Receive State characteristic value by Source ID. + * + * @param[in] source_id Source ID of Broadcast Receive State + * @param[out] state Pointer to Broadcast Receive State + * characteristic value + * + * @return 0 on success; + * A non-zero value on failure. + */ +int +ble_svc_audio_bass_receiver_state_get(uint8_t source_id, + struct ble_svc_audio_bass_receiver_state **state); + +/** + * @brief Get the source ID for given Receive State index. + * + * @param[in] index Receive State index. + * @param[in,out] source_id Pointer to the variable where the + * Source ID will be stored. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int +ble_svc_audio_bass_source_id_get(uint8_t index, uint8_t *source_id); + +/** + * @} + */ + +#endif /* H_BLE_AUDIO_SVC_BASS_ */ diff --git a/nimble/host/audio/services/bass/pkg.yml b/nimble/host/audio/services/bass/pkg.yml new file mode 100644 index 0000000000..e92ab6dd04 --- /dev/null +++ b/nimble/host/audio/services/bass/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: nimble/host/audio/services/bass +pkg.description: Broadcast Audio Scan Service +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - ble + - bluetooth + - pacs + - nimble + +pkg.deps: + - nimble/host + - nimble/host/services/gatt + +pkg.init: + ble_svc_audio_bass_init: 'MYNEWT_VAL(BLE_SVC_AUDIO_BASS_SYSINIT_STAGE)' diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c new file mode 100644 index 0000000000..6a40c17a84 --- /dev/null +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -0,0 +1,890 @@ +/* + * 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. + */ + +#include "host/ble_hs.h" +#include "host/ble_gatt.h" +#include "../../host/src/ble_gatt_priv.h" +#include "../../host/src/ble_att_priv.h" +#include "services/bass/ble_audio_svc_bass.h" +#include "../../../src/ble_audio_priv.h" + +#define BLE_SVC_AUDIO_BASS_CHR_LEN_UNLIMITED (-1) +#define BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE 0xFF + +const ble_uuid_t * bass_receive_state_uuid = + BLE_UUID16_DECLARE(BLE_SVC_AUDIO_BASS_CHR_UUID16_BROADCAST_RECEIVE_STATE); +const ble_uuid_t * bass_cp_uuid = + BLE_UUID16_DECLARE(BLE_SVC_AUDIO_BASS_CHR_UUID16_BASS_CP); + +enum ble_svc_audio_bass_ctrl_point_op_code { + BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED, + BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED, + BLE_AUDIO_SVC_BASS_ADD_SOURCE, + BLE_AUDIO_SVC_BASS_MODIFY_SOURCE, + BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE, + BLE_AUDIO_SVC_BASS_REMOVE_SOURCE +}; + +typedef int ble_svc_audio_bass_ctrl_point_handler_cb(uint8_t *data, + uint16_t data_len, + uint16_t conn_handle); + +static struct ble_svc_audio_bass_ctrl_point_ev { + ble_svc_audio_bass_accept_fn *ctrl_point_ev_fn; + void *arg; +} accept_fn; + +struct ble_svc_audio_bass_rcv_state_entry { + uint8_t source_id; + uint16_t chr_val; + struct ble_svc_audio_bass_receiver_state state; +}; + +static struct ble_svc_audio_bass_rcv_state_entry + receiver_states[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX)] = { + [0 ... MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) - 1] = { + .source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE + } +}; + +static struct os_mempool ble_audio_svc_bass_metadata_pool; +static os_membuf_t ble_audio_svc_bass_metadata_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) * + BLE_SVC_AUDIO_BASS_SUB_NUM_MAX, + MYNEWT_VAL(BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ))]; + +static int +ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, uint16_t data_len, uint16_t conn_handle); +static int +ble_svc_audio_bass_remote_scan_started(uint8_t *data, uint16_t data_len, uint16_t conn_handle); +static int +ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle); +static int +ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle); +static int +ble_svc_audio_bass_set_broadcast_code(uint8_t *data, uint16_t data_len, uint16_t conn_handle); +static int +ble_svc_audio_bass_remove_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle); + +static int +ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt, uint16_t conn_handle); +static int +ble_svc_audio_bass_rcv_state_read_access(struct ble_gatt_access_ctxt *ctxt, void *arg); + +static struct ble_svc_audio_bass_ctrl_point_handler { + uint8_t op_code; + uint8_t length_min; + uint8_t length_max; + ble_svc_audio_bass_ctrl_point_handler_cb *handler_cb; +} ble_svc_audio_bass_ctrl_point_handlers[] = { + { + .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STOPPED, + .length_min = 0, + .length_max = 0, + .handler_cb = ble_svc_audio_bass_remote_scan_stopped + }, { + .op_code = BLE_AUDIO_SVC_BASS_REMOTE_SCAN_STARTED, + .length_min = 0, + .length_max = 0, + .handler_cb = ble_svc_audio_bass_remote_scan_started + }, { + .op_code = BLE_AUDIO_SVC_BASS_ADD_SOURCE, + .length_min = 15, + .length_max = BLE_SVC_AUDIO_BASS_CHR_LEN_UNLIMITED, + .handler_cb = ble_svc_audio_bass_add_source + }, { + .op_code = BLE_AUDIO_SVC_BASS_MODIFY_SOURCE, + .length_min = 5, + .length_max = BLE_SVC_AUDIO_BASS_CHR_LEN_UNLIMITED, + .handler_cb = ble_svc_audio_bass_modify_source + }, { + .op_code = BLE_AUDIO_SVC_BASS_SET_BROADCAST_CODE, + .length_min = 17, + .length_max = 17, + .handler_cb = ble_svc_audio_bass_set_broadcast_code + }, { + .op_code = BLE_AUDIO_SVC_BASS_REMOVE_SOURCE, + .length_min = 1, + .length_max = 1, + .handler_cb = ble_svc_audio_bass_remove_source + } +}; + +static struct ble_gatt_chr_def ble_svc_audio_bass_chrs[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) + 2]; + +static const struct ble_gatt_svc_def ble_svc_audio_bass_defs[MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) + 2] = { + { /*** Service: Published Audio Capabilities Service (bass) */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BLE_SVC_AUDIO_BASS_UUID16), + .characteristics = ble_svc_audio_bass_chrs, + }, + { + 0, /* No more services. */ + }, +}; + +static uint8_t free_source_id = 0; + +static int +ble_svc_audio_bass_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + uint16_t uuid16 = ble_uuid_u16(ctxt->chr->uuid); + int rc; + + switch (uuid16) { + case BLE_SVC_AUDIO_BASS_CHR_UUID16_BASS_CP: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = ble_svc_audio_bass_ctrl_point_write_access(ctxt, conn_handle); + } else { + assert(0); + } + return rc; + case BLE_SVC_AUDIO_BASS_CHR_UUID16_BROADCAST_RECEIVE_STATE: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = ble_svc_audio_bass_rcv_state_read_access(ctxt, arg); + } else { + assert(0); + } + return rc; + default: + assert(0); + } +} + +static bool +ble_svc_audio_bass_source_id_free(uint8_t source_id) +{ + int i; + for (i = 0; i < MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX); i++) { + if (receiver_states[i].source_id == source_id) { + return false; + } + } + + return true; +}; + +static uint8_t +ble_svc_audio_bass_get_new_source_id(void) +{ + /** Wrap around after all Source IDs were used */ + if (free_source_id == BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE) { + free_source_id = 0; + } + + while (!ble_svc_audio_bass_source_id_free(free_source_id)) { + free_source_id++; + } + + return free_source_id; +} + +static int +ble_svc_audio_bass_receive_state_notify(struct ble_svc_audio_bass_rcv_state_entry *state) +{ + int i; + + for (i = 0; i < sizeof(ble_svc_audio_bass_chrs); i++) { + if (ble_svc_audio_bass_chrs[i].arg == state) { + ble_gatts_chr_updated(*ble_svc_audio_bass_chrs[i].val_handle); + return 0; + } + } + + return BLE_HS_ENOENT; +} + +static int +ble_svc_audio_bass_receive_state_find_by_source_id(struct ble_svc_audio_bass_rcv_state_entry **out_state, + uint8_t source_id) +{ + int i; + + for (i = 0; i < sizeof(receiver_states); i++) { + if (receiver_states[i].source_id == source_id) { + *out_state = &receiver_states[i]; + return 0; + } + } + + return BLE_HS_ENOMEM; +} + +int +ble_svc_audio_bass_receive_state_find_free(struct ble_svc_audio_bass_rcv_state_entry **out_state) +{ + int i; + + for (i = 0; i < sizeof(receiver_states); i++) { + if (receiver_states[i].source_id == BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE) { + *out_state = &receiver_states[i]; + return 0; + } + } + + return BLE_HS_ENOMEM; +} + +static void +ble_svc_audio_bass_receive_state_free(struct ble_svc_audio_bass_rcv_state_entry *state) +{ + state->source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE; +} + +static int +ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, uint16_t data_len, uint16_t conn_handle) +{ + struct ble_audio_event ev = { + .type = BLE_AUDIO_EVENT_BASS_REMOTE_SCAN_STOPPED + }; + + ev.remote_scan_stopped.conn_handle = conn_handle; + ble_audio_event_listener_call(&ev); + + return 0; +} + +static int +ble_svc_audio_bass_remote_scan_started(uint8_t *data, uint16_t data_len, uint16_t conn_handle) +{ + struct ble_audio_event ev = { + .type = BLE_AUDIO_EVENT_BASS_REMOTE_SCAN_STARTED + }; + + ev.remote_scan_started.conn_handle = conn_handle; + ble_audio_event_listener_call(&ev); + + return 0; +} + +static int +ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle) +{ + struct ble_audio_event ev = { + .type = BLE_AUDIO_EVENT_BASS_OPERATION_STATUS, + .bass_operation_status = { + .op = BLE_AUDIO_EVENT_BASS_SOURCE_ADDED, + .status = 0 + } + }; + struct ble_svc_audio_bass_operation operation; + struct ble_svc_audio_bass_rcv_state_entry *rcv_state = NULL; + uint8_t offset = 0; + uint8_t *metadata_ptr; + uint8_t source_id_new; + uint8_t source_id_to_remove = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE; + int rc = 0; + int i; + + memset(&operation, 0, sizeof(operation)); + + operation.op = BLE_SVC_AUDIO_BASS_OPERATION_ADD_SOURCE; + operation.conn_handle = conn_handle; + + operation.add_source.adv_addr.type = data[offset++]; + memcpy(operation.add_source.adv_addr.val, &data[offset], 6); + offset += 6; + operation.add_source.adv_sid = data[offset++]; + operation.add_source.broadcast_id = get_le24(&data[offset]); + offset += 3; + operation.add_source.pa_sync = data[offset++]; + if (operation.add_source.pa_sync >= BLE_SVC_AUDIO_BASS_PA_SYNC_RFU) { + rc = BLE_HS_EINVAL; + ev.bass_operation_status.status = BLE_HS_EINVAL; + goto done; + } + + operation.add_source.pa_interval = get_le16(&data[offset]); + offset += 2; + operation.add_source.num_subgroups = data[offset++]; + + /** + * Previous data was checked for it's size in `ble_svc_audio_bass_ctrl_point_write_access`. + * As bis_sync_state array may be of variable length, we need to check it separately + */ + data_len -= offset; + for (i = 0; i < operation.add_source.num_subgroups; i++) { + if (data_len < sizeof(uint32_t)) { + rc = BLE_ATT_ERR_WRITE_REQ_REJECTED; + ev.bass_operation_status.status = BLE_HS_EREJECT; + goto done; + } + operation.add_source.subgroups[i].bis_sync_state = get_le32(&data[offset]); + offset += 4; + operation.add_source.subgroups[i].metadata_length = data[offset++]; + data_len -= 5; + if (data_len < operation.add_source.subgroups[i].metadata_length) { + rc = BLE_ATT_ERR_WRITE_REQ_REJECTED; + ev.bass_operation_status.status = BLE_HS_EREJECT; + goto done; + } + operation.add_source.subgroups[i].metadata = &data[offset]; + offset += operation.add_source.subgroups[i].metadata_length; + data_len -= operation.add_source.subgroups[i].metadata_length; + } + + source_id_new = ble_svc_audio_bass_get_new_source_id(); + operation.add_source.source_id = source_id_new; + + ble_svc_audio_bass_receive_state_find_free(&rcv_state); + if (rcv_state == NULL) { + operation.add_source.out_source_id_to_swap = &source_id_to_remove; + } else { + operation.add_source.out_source_id_to_swap = NULL; + rcv_state->source_id = operation.add_source.source_id; + } + + if (accept_fn.ctrl_point_ev_fn) { + rc = accept_fn.ctrl_point_ev_fn(&operation, accept_fn.arg); + if (rc != 0) { + if (rcv_state != NULL) { + ble_svc_audio_bass_receive_state_free(rcv_state); + } + rc = BLE_ATT_ERR_WRITE_REQ_REJECTED; + ev.bass_operation_status.status = BLE_HS_EREJECT; + goto done; + } + } + + if (rcv_state == NULL) { + if (source_id_to_remove != BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE) { + ble_svc_audio_bass_receive_state_find_by_source_id(&rcv_state, source_id_to_remove); + if (rcv_state == NULL) { + rc = BLE_HS_EAPP; + ev.bass_operation_status.status = BLE_HS_EAPP; + goto done; + } + + /* Swap Source ID */ + rcv_state->source_id = operation.add_source.source_id; + } else { + rc = BLE_HS_ENOMEM; + ev.bass_operation_status.status = BLE_HS_ENOMEM; + goto done; + } + } else { + rcv_state->source_id = operation.add_source.source_id; + } + + ev.bass_operation_status.source_id = rcv_state->source_id; + rcv_state->state.source_addr.type = operation.add_source.adv_addr.type; + memcpy(&rcv_state->state.source_addr.type, operation.add_source.adv_addr.val, 6); + rcv_state->state.source_adv_sid = operation.add_source.adv_sid; + rcv_state->state.broadcast_id = operation.add_source.broadcast_id; + + for (i = 0; i < operation.add_source.num_subgroups; i++) { + metadata_ptr = os_memblock_get(&ble_audio_svc_bass_metadata_pool); + if (!metadata_ptr) { + rc = BLE_HS_ENOMEM; + ev.bass_operation_status.status = BLE_HS_ENOMEM; + goto done; + } + rcv_state->state.subgroups[i].metadata_length = operation.add_source.subgroups[i].metadata_length; + memcpy(metadata_ptr, operation.add_source.subgroups[i].metadata, + min(operation.add_source.subgroups[i].metadata_length, + MYNEWT_VAL(BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ))); + + rcv_state->state.subgroups[i].metadata = metadata_ptr; + } + +done: + if (!rc) { + rc = ble_svc_audio_bass_receive_state_notify(rcv_state); + ev.bass_operation_status.status = rc; + goto done; + } + + ble_audio_event_listener_call(&ev); + + return rc; +} + +static int +check_bis_sync(uint16_t num_subgroups, const uint32_t *bis_sync_list) +{ + uint32_t bis_sync_mask = 0; + int i; + int j; + + for (i = 0; i < num_subgroups; i++) { + if (bis_sync_list[i] != 0xFFFFFFFF) { + for (j = 0; j < num_subgroups; j++) { + if (bis_sync_list[i] & bis_sync_mask) { + return BLE_HS_EINVAL; + } + + bis_sync_mask |= bis_sync_list[i]; + } + } + } + + return 0; +} + +static int +ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle) +{ + struct ble_svc_audio_bass_operation operation; + struct ble_svc_audio_bass_rcv_state_entry *rcv_state = NULL; + struct ble_audio_event ev = { + .type = BLE_AUDIO_EVENT_BASS_OPERATION_STATUS, + .bass_operation_status = { + .op = BLE_AUDIO_EVENT_BASS_SOURCE_MODIFIED, + .status = 0 + } + }; + uint8_t offset = 0; + int rc = 0; + int i; + + memset(&operation, 0, sizeof(operation)); + + operation.op = BLE_SVC_AUDIO_BASS_OPERATION_MODIFY_SOURCE; + operation.conn_handle = conn_handle; + + operation.modify_source.source_id = data[offset++]; + + ble_svc_audio_bass_receive_state_find_by_source_id(&rcv_state, + operation.modify_source.source_id); + if (rcv_state == NULL) { + rc = BLE_SVC_AUDIO_BASS_ERR_INVALID_SOURCE_ID; + ev.bass_operation_status.status = BLE_HS_EINVAL; + goto done; + } + + operation.modify_source.pa_sync = data[offset++]; + if (operation.modify_source.pa_sync >= BLE_SVC_AUDIO_BASS_PA_SYNC_RFU) { + rc = BLE_HS_EINVAL; + ev.bass_operation_status.status = BLE_HS_EREJECT; + goto done; + } + + operation.modify_source.pa_interval = get_le16(&data[offset]); + offset += 2; + operation.modify_source.num_subgroups = get_le16(&data[offset]); + offset += 2; + + data_len -= offset; + if (data_len < operation.modify_source.num_subgroups * sizeof(uint32_t)) { + rc = BLE_ATT_ERR_WRITE_REQ_REJECTED; + ev.bass_operation_status.status = BLE_HS_EREJECT; + goto done; + } + + for (i = 0; i < operation.modify_source.num_subgroups; i++) { + operation.modify_source.bis_sync[i] = get_le32(&data[offset]); + offset += 4; + } + + if (check_bis_sync(operation.modify_source.num_subgroups, + operation.modify_source.bis_sync)) { + rc = BLE_HS_EINVAL; + ev.bass_operation_status.status = BLE_HS_EREJECT; + goto done; + } + + if (accept_fn.ctrl_point_ev_fn) { + rc = accept_fn.ctrl_point_ev_fn(&operation, accept_fn.arg); + if (rc != 0) { + rc = BLE_ATT_ERR_WRITE_REQ_REJECTED; + ev.bass_operation_status.status = BLE_HS_EREJECT; + goto done; + } + } + + ev.bass_operation_status.source_id = operation.modify_source.source_id; + +done: + if (!rc) { + rc = ble_svc_audio_bass_receive_state_notify(rcv_state); + ev.bass_operation_status.status = rc; + goto done; + } + + ble_audio_event_listener_call(&ev); + + return rc; +} + +static int +ble_svc_audio_bass_set_broadcast_code(uint8_t *data, uint16_t data_len, uint16_t conn_handle) +{ + struct ble_svc_audio_bass_rcv_state_entry *rcv_state = NULL; + struct ble_audio_event ev = { + .type = BLE_AUDIO_EVENT_BASS_BROADCAST_CODE_SET, + }; + + ev.bass_set_broadcast_code.source_id = data[0]; + + ble_svc_audio_bass_receive_state_find_by_source_id(&rcv_state, + ev.bass_set_broadcast_code.source_id); + if (rcv_state == NULL) { + return BLE_SVC_AUDIO_BASS_ERR_INVALID_SOURCE_ID; + } + + memcpy(ev.bass_set_broadcast_code.broadcast_code, &data[1], BLE_AUDIO_BROADCAST_CODE_SIZE); + + ble_audio_event_listener_call(&ev); + + return 0; +} + +static int +ble_svc_audio_bass_remove_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle) +{ + struct ble_audio_event ev = { + .type = BLE_AUDIO_EVENT_BASS_BROADCAST_CODE_SET, + .bass_operation_status = { + .op = BLE_AUDIO_EVENT_BASS_SOURCE_REMOVED, + .status = 0 + } + }; + struct ble_svc_audio_bass_rcv_state_entry *rcv_state = NULL; + struct ble_svc_audio_bass_operation operation; + int rc = 0; + int i; + + ev.bass_set_broadcast_code.source_id = data[0]; + + ble_svc_audio_bass_receive_state_find_by_source_id(&rcv_state, + ev.bass_operation_status.source_id); + if (rcv_state == NULL) { + rc = BLE_SVC_AUDIO_BASS_ERR_INVALID_SOURCE_ID; + ev.bass_operation_status.status = BLE_HS_ENOENT; + goto done; + } + + operation.remove_source.source_id = ev.bass_operation_status.source_id; + operation.conn_handle = conn_handle; + if (accept_fn.ctrl_point_ev_fn) { + rc = accept_fn.ctrl_point_ev_fn(&operation, accept_fn.arg); + if (rc != 0) { + rc = BLE_HS_EREJECT; + ev.bass_operation_status.status = BLE_HS_EREJECT; + goto done; + } + } + + for (i = 0; i < rcv_state->state.num_subgroups; i++) { + os_memblock_put(&ble_audio_svc_bass_metadata_pool, rcv_state->state.subgroups[i].metadata); + } + + memset(rcv_state, 0, sizeof(*rcv_state)); + rcv_state->source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE; + +done: + if (!rc) { + rc = ble_svc_audio_bass_receive_state_notify(rcv_state); + ev.bass_operation_status.status = rc; + goto done; + } + + ble_audio_event_listener_call(&ev); + + return rc; +} + +static struct ble_svc_audio_bass_ctrl_point_handler * +ble_svc_audio_bass_find_handler(uint8_t opcode) +{ + int i; + + for (i = 0; i < sizeof(ble_svc_audio_bass_ctrl_point_handlers); i++) { + if (ble_svc_audio_bass_ctrl_point_handlers[i].op_code == opcode) { + return &ble_svc_audio_bass_ctrl_point_handlers[i]; + } + } + + return NULL; +} + +static int +ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt, uint16_t conn_handle) +{ + struct ble_svc_audio_bass_ctrl_point_handler *handler; + + uint8_t opcode = ctxt->om->om_data[0]; + + handler = ble_svc_audio_bass_find_handler(opcode); + + if (!handler) { + return BLE_SVC_AUDIO_BASS_ERR_OPCODE_NOT_SUPPORTED; + } + + if (ctxt->om->om_len - 1 < handler->length_min && + handler->length_max >= 0 ? + ctxt->om->om_len > handler->length_max : 0) { + return BLE_ATT_ERR_WRITE_REQ_REJECTED; + } + + return handler->handler_cb(&ctxt->om->om_data[1], ctxt->om->om_len - 1, conn_handle); +} + +static int +ble_svc_audio_bass_rcv_state_read_access(struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + struct ble_svc_audio_bass_rcv_state_entry *state = arg; + uint8_t *buf; + int i; + + /* Nothing set, return empty buffer */ + if (state->source_id == BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE) { + return 0; + } + + os_mbuf_append(ctxt->om, &state->source_id, 1); + os_mbuf_append(ctxt->om, &state->state.source_addr.type, 1); + os_mbuf_append(ctxt->om, &state->state.source_addr.val, 6); + os_mbuf_append(ctxt->om, &state->state.source_adv_sid, 1); + buf = os_mbuf_extend(ctxt->om, 3); + if (buf == NULL) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + put_le24(buf, state->state.broadcast_id); + os_mbuf_append(ctxt->om, &state->state.pa_sync_state, 1); + os_mbuf_append(ctxt->om, &state->state.big_encryption, 1); + + if (state->state.big_encryption == BLE_SVC_AUDIO_BASS_BIG_ENC_BAD_CODE) { + os_mbuf_append(ctxt->om, &state->state.bad_code, BLE_AUDIO_BROADCAST_CODE_SIZE); + } + + os_mbuf_append(ctxt->om, &state->state.num_subgroups, 1); + + for (i = 0; i < state->state.num_subgroups; i++) { + buf = os_mbuf_extend(ctxt->om, 4); + if (buf == NULL) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + + put_le32(buf, state->state.subgroups[i].bis_sync_state); + os_mbuf_append(ctxt->om, &state->state.subgroups[i].metadata_length, 1); + os_mbuf_append(ctxt->om, state->state.subgroups[i].metadata, + state->state.subgroups[i].metadata_length); + } + + return 0; +} + +int +ble_svc_audio_bass_accept_fn_set(ble_svc_audio_bass_accept_fn *fn, void *arg) +{ + if (accept_fn.ctrl_point_ev_fn) { + return BLE_HS_EALREADY; + } + + accept_fn.ctrl_point_ev_fn = fn; + accept_fn.arg = arg; + return 0; +} + +int +ble_svc_audio_bass_receive_state_add(const struct ble_svc_audio_bass_receiver_state_add_params *params, + uint8_t *source_id) +{ + struct ble_svc_audio_bass_rcv_state_entry *rcv_state; + int i; + int rc; + + rc = ble_svc_audio_bass_receive_state_find_free(&rcv_state); + if (rc) { + return rc; + } + + rcv_state->source_id = ble_svc_audio_bass_get_new_source_id(); + rcv_state->state.source_addr = params->source_addr; + rcv_state->state.source_adv_sid = params->source_adv_sid; + rcv_state->state.broadcast_id = params->broadcast_id; + rcv_state->state.pa_sync_state = params->pa_sync_state; + rcv_state->state.big_encryption = params->big_encryption; + if (rcv_state->state.big_encryption == + BLE_SVC_AUDIO_BASS_BIG_ENC_BAD_CODE) { + memcpy(&rcv_state->state.bad_code, params->bad_code, + BLE_AUDIO_BROADCAST_CODE_SIZE); + } + rcv_state->state.num_subgroups = params->num_subgroups; + + for (i = 0; i < rcv_state->state.num_subgroups; i++) { + rcv_state->state.subgroups[i].metadata = + os_memblock_get(&ble_audio_svc_bass_metadata_pool); + + if (!rcv_state->state.subgroups[i].metadata) { + return 0; + } + + rcv_state->state.subgroups[i].metadata_length = + min(params->subgroups[i].metadata_length, + ble_audio_svc_bass_metadata_pool.mp_block_size); + memcpy(rcv_state->state.subgroups[i].metadata, params->subgroups[i].metadata, + rcv_state->state.subgroups[i].metadata_length); + } + + *source_id = rcv_state->source_id; + + return ble_svc_audio_bass_receive_state_notify(rcv_state); +} + +int +ble_svc_audio_bass_receive_state_remove(uint8_t source_id) +{ + struct ble_svc_audio_bass_rcv_state_entry *rcv_state = NULL; + int rc, i; + + rc = ble_svc_audio_bass_receive_state_find_by_source_id(&rcv_state, source_id); + if (rc) { + return rc; + } + + memset(&rcv_state->state, 0, sizeof(rcv_state->state)); + rcv_state->source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE; + + for (i = 0; i < rcv_state->state.num_subgroups; i++) { + os_memblock_put(&ble_audio_svc_bass_metadata_pool, rcv_state->state.subgroups[i].metadata); + } + + return ble_svc_audio_bass_receive_state_notify(rcv_state); +} + +int +ble_svc_audio_bass_update_metadata(const struct ble_svc_audio_bass_metadata_params *params, + uint8_t source_id) +{ + struct ble_svc_audio_bass_rcv_state_entry *rcv_state = NULL; + int rc; + + rc = ble_svc_audio_bass_receive_state_find_by_source_id(&rcv_state, source_id); + if (rc) { + return rc; + } + + rcv_state->state.subgroups[params->subgroup_idx].metadata_length = params->metadata_length; + memcpy(rcv_state->state.subgroups[params->subgroup_idx].metadata, + params->metadata, params->metadata_length); + + return ble_svc_audio_bass_receive_state_notify(rcv_state); +} + +int +ble_svc_audio_bass_receive_state_update(const struct + ble_svc_audio_bass_update_params *params, + uint8_t source_id) +{ + struct ble_svc_audio_bass_rcv_state_entry *rcv_state = NULL; + int rc; + + rc = ble_svc_audio_bass_receive_state_find_by_source_id(&rcv_state, + source_id); + if (rc) { + return rc; + } + + if (rcv_state->state.num_subgroups < params->num_subgroups) { + return BLE_HS_ENOMEM; + } + + rcv_state->state.pa_sync_state = params->pa_sync_state; + rcv_state->state.big_encryption = params->big_encryption; + if (params->bad_code) { + memcpy(rcv_state->state.bad_code, + params->bad_code, + BLE_AUDIO_BROADCAST_CODE_SIZE); + } + + int i; + for (i = 0; i < params->num_subgroups; i++) { + rcv_state->state.subgroups[i].bis_sync_state = + params->subgroups[i].bis_sync_state; + memcpy(rcv_state->state.subgroups[i].metadata, + params->subgroups[i].metadata, + params->subgroups[i].metadata_length); + } + + return ble_svc_audio_bass_receive_state_notify(rcv_state); +} + +int +ble_svc_audio_bass_receiver_state_get(uint8_t source_id, + struct ble_svc_audio_bass_receiver_state **state) +{ + struct ble_svc_audio_bass_rcv_state_entry *rcv_state = NULL; + + ble_svc_audio_bass_receive_state_find_by_source_id(&rcv_state, source_id); + + if (!rcv_state) { + return BLE_HS_ENOENT; + } + + *state = &rcv_state->state; + + return 0; +} + +int +ble_svc_audio_bass_source_id_get(uint8_t index, uint8_t *source_id) +{ + if (index >= ARRAY_SIZE(receiver_states) || + receiver_states[index].source_id == + BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE) { + return BLE_HS_ENOENT; + } + + *source_id = receiver_states[index].source_id; + + return 0; +} + +void +ble_svc_audio_bass_init(void) +{ + int rc; + int i; + + /* Ensure this function only gets called by sysinit. */ + SYSINIT_ASSERT_ACTIVE(); + + ble_svc_audio_bass_chrs[0].uuid = bass_cp_uuid; + ble_svc_audio_bass_chrs[0].access_cb = ble_svc_audio_bass_access; + ble_svc_audio_bass_chrs[0].flags = BLE_GATT_CHR_F_WRITE_NO_RSP | BLE_GATT_CHR_F_WRITE_ENC; + + for (i = 1; i <= MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX); i++) { + ble_svc_audio_bass_chrs[i].uuid = bass_receive_state_uuid; + ble_svc_audio_bass_chrs[i].access_cb = ble_svc_audio_bass_access; + ble_svc_audio_bass_chrs[i].arg = &receiver_states[i-1]; + ble_svc_audio_bass_chrs[i].val_handle = &receiver_states[i-1].chr_val; + ble_svc_audio_bass_chrs[i].flags = BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_READ_ENC | + BLE_GATT_CHR_F_NOTIFY; + } + + rc = ble_gatts_count_cfg(ble_svc_audio_bass_defs); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_gatts_add_svcs(ble_svc_audio_bass_defs); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = os_mempool_init(&ble_audio_svc_bass_metadata_pool, + MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) * + BLE_SVC_AUDIO_BASS_SUB_NUM_MAX, + MYNEWT_VAL(BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ), + ble_audio_svc_bass_metadata_mem, "ble_audio_svc_bass_metadata_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); + + (void)rc; +} diff --git a/nimble/host/audio/services/bass/syscfg.yml b/nimble/host/audio/services/bass/syscfg.yml new file mode 100644 index 0000000000..2be3f497c3 --- /dev/null +++ b/nimble/host/audio/services/bass/syscfg.yml @@ -0,0 +1,38 @@ +# 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. + +syscfg.defs: + BLE_SVC_AUDIO_BASS_SYSINIT_STAGE: + description: > + Sysinit stage for Published Audio Capabilities Service. + value: 303 + BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX: + description: > + Maximum number of Broadcast Receive State characteristics. + value: 2 + BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ: + description: > + Maximum size of metadata that can be saved for subgroup. If set to 0 metadata is + not being saved. + value: 32 + BLE_SVC_AUDIO_BASS_SUB_NUM_MAX: + description: > + Maximum number of Subgroups supported per Receive State. + value: 3 + +syscfg.restrictions: + - 'BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX < 0xFE' diff --git a/nimble/host/include/host/ble_att.h b/nimble/host/include/host/ble_att.h index bfd7adf10f..8323c9d764 100644 --- a/nimble/host/include/host/ble_att.h +++ b/nimble/host/include/host/ble_att.h @@ -113,6 +113,18 @@ struct os_mbuf; /**Requested value is not allowed. */ #define BLE_ATT_ERR_VALUE_NOT_ALLOWED 0x13 +/**Write Request Rejected. */ +#define BLE_ATT_ERR_WRITE_REQ_REJECTED 0xFC + +/**Client Characteristic Configuration Descriptor Improperly Configured. */ +#define BLE_ATT_ERR_CCCD_IMPORER_CONF 0xFD + +/**Procedure Already in Progress. */ +#define BLE_ATT_ERR_PROC_IN_PROGRESS 0xFE + +/**Out of Range. */ +#define BLE_ATT_ERR_OUT_OF_RANGE 0xFF + /** @} */ /** From 862159340f54beec98ba2a89a42ed613a02c7537 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 29 Apr 2024 10:52:21 +0200 Subject: [PATCH 0997/1333] nimble: iso: Move Rx callback param to Setup ISO Data Path command This moves the ISO Rx callback to be provided by application as Setup ISO Data Path function parameter, as the callback will be used only for HCI data path, thus there is no point to require the callback when the broadcast sync is created. --- apps/btshell/src/cmd_iso.c | 70 +++++++++++++++++++++++++----- nimble/host/include/host/ble_iso.h | 17 ++++---- nimble/host/src/ble_iso.c | 56 ++++++++++++++++-------- nimble/include/nimble/hci_common.h | 2 + 4 files changed, 108 insertions(+), 37 deletions(-) diff --git a/apps/btshell/src/cmd_iso.c b/apps/btshell/src/cmd_iso.c index 27a9bc9d44..3383c379f3 100644 --- a/apps/btshell/src/cmd_iso.c +++ b/apps/btshell/src/cmd_iso.c @@ -17,6 +17,7 @@ * under the License. */ +#include "host/ble_hs.h" #include "host/ble_iso.h" #include "cmd_iso.h" @@ -26,7 +27,7 @@ #if (MYNEWT_VAL(BLE_ISO)) static struct iso_rx_stats { - uint8_t bis_index; + uint16_t conn_handle; bool ts_valid; uint32_t ts; uint16_t seq_num; @@ -34,12 +35,60 @@ static struct iso_rx_stats { uint64_t valid_cnt; uint64_t error_cnt; uint64_t lost_cnt; -} rx_stats_pool[MYNEWT_VAL(BLE_ISO_MAX_BISES)]; +} rx_stats_pool[MYNEWT_VAL(BLE_ISO_MAX_BISES)] = { + [0 ... MYNEWT_VAL(BLE_ISO_MAX_BISES) - 1] = { + .conn_handle = BLE_HS_CONN_HANDLE_NONE + } +}; + +static struct iso_rx_stats * +iso_rx_stats_lookup_conn_handle(uint16_t conn_handle) +{ + for (size_t i = 0; i < ARRAY_SIZE(rx_stats_pool); i++) { + if (rx_stats_pool[i].conn_handle == conn_handle) { + return &rx_stats_pool[i]; + } + } + + return NULL; +} + +static struct iso_rx_stats * +iso_rx_stats_get_or_new(uint16_t conn_handle) +{ + struct iso_rx_stats *rx_stats; + + rx_stats = iso_rx_stats_lookup_conn_handle(conn_handle); + if (rx_stats == NULL) { + rx_stats = iso_rx_stats_lookup_conn_handle(BLE_HS_CONN_HANDLE_NONE); + if (rx_stats == NULL) { + return NULL; + } + } + + rx_stats->conn_handle = conn_handle; + + return rx_stats; +} + +static void +iso_rx_stats_reset(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(rx_stats_pool); i++) { + memset(&rx_stats_pool[i], 0, sizeof(rx_stats_pool[i])); + rx_stats_pool[i].conn_handle = BLE_HS_CONN_HANDLE_NONE; + } +} static void -iso_rx_stats_update(uint16_t conn_handle, const struct ble_iso_rx_data_info *info, - struct iso_rx_stats *stats) +iso_rx_stats_update(uint16_t conn_handle, const struct ble_iso_rx_data_info *info, void *arg) { + struct iso_rx_stats *stats = arg; + + if (!stats) { + return; + } + stats->ts_valid = info->ts_valid; if (stats->ts_valid) { stats->ts = info->ts; @@ -58,9 +107,9 @@ iso_rx_stats_update(uint16_t conn_handle, const struct ble_iso_rx_data_info *inf stats->total_cnt++; if ((stats->total_cnt % 100) == 0) { - console_printf("BIS=%d, seq_num=%d, num_rx=%lld, " + console_printf("conn_handle=0x%04x, seq_num=%d, num_rx=%lld, " "(valid=%lld, error=%lld, lost=%lld) ", - stats->bis_index, stats->seq_num, + stats->conn_handle, stats->seq_num, stats->total_cnt, stats->valid_cnt, stats->error_cnt, stats->lost_cnt); @@ -122,6 +171,7 @@ ble_iso_event_handler(struct ble_iso_event *event, void *arg) console_printf("BIG Sync Terminated handle=0x%02x reason: %u\n", event->big_terminated.big_handle, event->big_terminated.reason); + iso_rx_stats_reset(); break; case BLE_ISO_EVENT_ISO_RX: @@ -349,12 +399,6 @@ cmd_iso_big_sync_create(int argc, char **argv) for (uint8_t i = 0; i < params.bis_cnt; i++) { bis_params[i].bis_index = bis_idxs[i]; - bis_params[i].cb = ble_iso_event_handler; - bis_params[i].cb_arg = &rx_stats_pool[i]; - - /* Reset stats */ - memset(&rx_stats_pool[i], 0, sizeof(rx_stats_pool[i])); - rx_stats_pool[i].bis_index = bis_idxs[i]; } params.bis_params = bis_params; @@ -457,6 +501,8 @@ cmd_iso_data_path_setup(int argc, char **argv) } /* For now, the Data Path ID is set to HCI by default */ + params.cb = ble_iso_event_handler; + params.cb_arg = iso_rx_stats_get_or_new(params.conn_handle); rc = ble_iso_data_path_setup(¶ms); if (rc != 0) { diff --git a/nimble/host/include/host/ble_iso.h b/nimble/host/include/host/ble_iso.h index ee99b962bd..ad1d0ed9a8 100644 --- a/nimble/host/include/host/ble_iso.h +++ b/nimble/host/include/host/ble_iso.h @@ -333,14 +333,6 @@ int ble_iso_terminate_big(uint8_t big_handle); struct ble_iso_bis_params { /** BIS index */ uint8_t bis_index; - - /** The callback to associate with the BIS. - * Received ISO data is reported through this callback. - */ - ble_iso_event_fn *cb; - - /** The optional argument to pass to the callback function */ - void *cb_arg; }; /** @brief BIG Sync parameters for @ref ble_iso_big_sync_create */ @@ -443,6 +435,15 @@ struct ble_iso_data_path_setup_params { /** Codec Configuration */ const uint8_t *codec_config; + + /** + * The ISO Data callback. Must be set if @p data_path_id is HCI. + * Received ISO data is reported through this callback. + */ + ble_iso_event_fn *cb; + + /** The optional argument to pass to the callback function */ + void *cb_arg; }; /** diff --git a/nimble/host/src/ble_iso.c b/nimble/host/src/ble_iso.c index af728d135c..7e78cc9607 100644 --- a/nimble/host/src/ble_iso.c +++ b/nimble/host/src/ble_iso.c @@ -233,6 +233,20 @@ ble_iso_big_free(struct ble_iso_big *big) return 0; } +static struct ble_iso_conn * +ble_iso_conn_lookup_handle(uint16_t handle) +{ + struct ble_iso_conn *conn; + + SLIST_FOREACH(conn, &ble_iso_conns, next) { + if (conn->handle == handle) { + return conn; + } + } + + return NULL; +} + #if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) int ble_iso_create_big(const struct ble_iso_create_big_params *create_params, @@ -496,20 +510,6 @@ ble_iso_tx(uint16_t conn_handle, void *data, uint16_t data_len) #endif /* BLE_ISO_BROADCAST_SOURCE */ #if MYNEWT_VAL(BLE_ISO_BROADCAST_SINK) -static struct ble_iso_conn * -ble_iso_conn_lookup_handle(uint16_t handle) -{ - struct ble_iso_conn *conn; - - SLIST_FOREACH(conn, &ble_iso_conns, next) { - if (conn->handle == handle) { - return conn; - } - } - - return NULL; -} - int ble_iso_big_sync_create(const struct ble_iso_big_sync_create_params *param, uint8_t *big_handle) @@ -553,9 +553,6 @@ ble_iso_big_sync_create(const struct ble_iso_big_sync_create_params *param, return BLE_HS_ENOMEM; } - bis->conn.cb = param->bis_params[i].cb; - bis->conn.cb_arg = param->bis_params[i].cb_arg; - cp->bis[i] = param->bis_params[i].bis_index; } @@ -867,8 +864,15 @@ ble_iso_data_path_setup(const struct ble_iso_data_path_setup_params *param) struct ble_hci_le_setup_iso_data_path_rp rp; struct ble_hci_le_setup_iso_data_path_cp *cp; uint8_t buf[sizeof(*cp) + UINT8_MAX]; + struct ble_iso_conn *conn; int rc; + conn = ble_iso_conn_lookup_handle(param->conn_handle); + if (conn == NULL) { + BLE_HS_LOG_ERROR("invalid conn_handle\n"); + return BLE_HS_ENOTCONN; + } + if (param->codec_config_len > 0 && param->codec_config == NULL) { BLE_HS_LOG_ERROR("Missing codec_config\n"); return BLE_HS_EINVAL; @@ -886,6 +890,14 @@ ble_iso_data_path_setup(const struct ble_iso_data_path_setup_params *param) if (param->data_path_dir & BLE_ISO_DATA_DIR_RX) { /* Output (Controller to Host) */ cp->data_path_dir |= BLE_HCI_ISO_DATA_PATH_DIR_OUTPUT; + + if (cp->data_path_id == BLE_HCI_ISO_DATA_PATH_ID_HCI && param->cb == NULL) { + BLE_HS_LOG_ERROR("param->cb is NULL\n"); + return BLE_HS_EINVAL; + } + + conn->cb = param->cb; + conn->cb_arg = param->cb_arg; } cp->data_path_id = param->data_path_id; @@ -910,8 +922,15 @@ ble_iso_data_path_remove(const struct ble_iso_data_path_remove_params *param) { struct ble_hci_le_remove_iso_data_path_rp rp; struct ble_hci_le_remove_iso_data_path_cp cp = { 0 }; + struct ble_iso_conn *conn; int rc; + conn = ble_iso_conn_lookup_handle(param->conn_handle); + if (conn == NULL) { + BLE_HS_LOG_ERROR("invalid conn_handle\n"); + return BLE_HS_ENOTCONN; + } + put_le16(&cp.conn_handle, param->conn_handle); if (param->data_path_dir & BLE_ISO_DATA_DIR_TX) { @@ -922,6 +941,9 @@ ble_iso_data_path_remove(const struct ble_iso_data_path_remove_params *param) if (param->data_path_dir & BLE_ISO_DATA_DIR_RX) { /* Output (Controller to Host) */ cp.data_path_dir |= BLE_HCI_ISO_DATA_PATH_DIR_OUTPUT; + + conn->cb = NULL; + conn->cb_arg = NULL; } rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index aadfa37b58..80c4f2b3fc 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -2423,6 +2423,8 @@ struct hci_data_hdr #define BLE_HCI_ISO_DATA_PATH_DIR_INPUT 0x00 #define BLE_HCI_ISO_DATA_PATH_DIR_OUTPUT 0x01 +#define BLE_HCI_ISO_DATA_PATH_ID_HCI 0x00 + struct ble_hci_iso { uint16_t handle; uint16_t length; From 4a994636ede6d48ac664462e4de70107920bc81d Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Mon, 6 May 2024 15:59:10 +0530 Subject: [PATCH 0998/1333] nimble/host: Add API to retrieve the size of the controller's white list --- nimble/host/include/host/ble_gap.h | 9 +++++++++ nimble/host/src/ble_gap.c | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index 86e589c189..e842ae29a7 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -2239,6 +2239,15 @@ int ble_gap_terminate(uint16_t conn_handle, uint8_t hci_reason); */ int ble_gap_wl_set(const ble_addr_t *addrs, uint8_t white_list_count); +/** + * Retrieves the size of whitelist supported by controller + * + * @param size On success, this holds the size of controller accept list + * + * @return 0 on success; nonzero on failure + */ +int ble_gap_wl_read_size(uint8_t *size); + /** * Initiates a connection parameter update procedure. * diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 44d57707ad..fe54fca8b2 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -2398,6 +2398,23 @@ ble_gap_wl_tx_clear(void) BLE_HCI_OCF_LE_CLEAR_WHITE_LIST), NULL, 0, NULL, 0 ); } + +int +ble_gap_wl_read_size(uint8_t *size) +{ + struct ble_hci_le_rd_white_list_rp rsp; + int rc; + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_RD_WHITE_LIST_SIZE), + NULL, 0, &rsp, sizeof(rsp)); + + if (rc == 0) { + *size = rsp.size; + } + + return rc; +} #endif int From 175029cd1606e639efc630a53cf99cf3be51a9c4 Mon Sep 17 00:00:00 2001 From: Taras Zaporozhets Date: Mon, 22 Apr 2024 15:07:11 +0200 Subject: [PATCH 0999/1333] nimble/transport: Fix compilation with TCP socket transport --- nimble/transport/socket/src/ble_hci_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/transport/socket/src/ble_hci_socket.c b/nimble/transport/socket/src/ble_hci_socket.c index 0d52ec584f..41975cacc6 100644 --- a/nimble/transport/socket/src/ble_hci_socket.c +++ b/nimble/transport/socket/src/ble_hci_socket.c @@ -178,7 +178,7 @@ static int s_ble_hci_device = MYNEWT_VAL(BLE_SOCK_LINUX_DEV); static int s_ble_hci_device = 0; #endif -#if MYNEWT_VAL(BLE_SOCK_USE_LINUX_BLUE) +#if MYNEWT_VAL(BLE_SOCK_USE_LINUX_BLUE) || MYNEWT_VAL(BLE_SOCK_USE_TCP) static int ble_hci_sock_acl_tx(struct os_mbuf *om) { @@ -275,7 +275,7 @@ ble_hci_sock_acl_tx(struct os_mbuf *om) } #endif -#if MYNEWT_VAL(BLE_SOCK_USE_LINUX_BLUE) +#if MYNEWT_VAL(BLE_SOCK_USE_LINUX_BLUE) || MYNEWT_VAL(BLE_SOCK_USE_TCP) static int ble_hci_sock_cmdevt_tx(uint8_t *hci_ev, uint8_t h4_type) { From f3afc1715bded0b339491db410ea2e753a32a48b Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Mon, 6 May 2024 17:56:08 +0530 Subject: [PATCH 1000/1333] nimble/host: Avoid slave instance reset inside extract_cb --- nimble/host/src/ble_gap.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index fe54fca8b2..733d6f1f33 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -1617,6 +1617,18 @@ ble_gap_rx_adv_set_terminated(const struct ble_hci_ev_le_subev_adv_set_terminate ble_gap_adv_finished(ev->adv_handle, reason, conn_handle, ev->num_events); } +static void +ble_gap_slave_get_cb(uint8_t instance, + ble_gap_event_fn **out_cb, void **out_cb_arg) +{ + ble_hs_lock(); + + *out_cb = ble_gap_slave[instance].cb; + *out_cb_arg = ble_gap_slave[instance].cb_arg; + + ble_hs_unlock(); +} + void ble_gap_rx_scan_req_rcvd(const struct ble_hci_ev_le_subev_scan_req_rcvd *ev) { @@ -1624,7 +1636,7 @@ ble_gap_rx_scan_req_rcvd(const struct ble_hci_ev_le_subev_scan_req_rcvd *ev) ble_gap_event_fn *cb; void *cb_arg; - ble_gap_slave_extract_cb(ev->adv_handle, &cb, &cb_arg); + ble_gap_slave_get_cb(ev->adv_handle, &cb, &cb_arg); if (cb != NULL) { memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_SCAN_REQ_RCVD; From 5f2aa282a85b209719e6ee36df44b1307fc118fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bojan=20Poto=C4=8Dnik?= Date: Mon, 13 May 2024 19:02:07 +0200 Subject: [PATCH 1001/1333] nimble/transport: Fix syscfg definition names for uart_ll transport Change BLE_TRANSPORT_UART_* in hci_uart.c to BLE_TRANSPORT_UART_LL_* to match definitions in syscfg.yml. uart_ll was added by 80ef459c48dd2e938789013da1222438ffa2bf92 as a copy of existing "uart" transport. "_LL" was added to "BLE_TRANSPORT_UART_*" definitions in syscfg.yml, but not in the hci_uart.c file. --- nimble/transport/uart_ll/src/hci_uart.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/nimble/transport/uart_ll/src/hci_uart.c b/nimble/transport/uart_ll/src/hci_uart.c index 95eae3f4b3..692b415c6d 100644 --- a/nimble/transport/uart_ll/src/hci_uart.c +++ b/nimble/transport/uart_ll/src/hci_uart.c @@ -136,31 +136,31 @@ hci_uart_configure(void) enum hal_uart_flow_ctl flowctl; int rc; - rc = hal_uart_init_cbs(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT), + rc = hal_uart_init_cbs(MYNEWT_VAL(BLE_TRANSPORT_UART_LL_PORT), hci_uart_tx_char, NULL, hci_uart_rx_char, NULL); if (rc != 0) { return -1; } - if (MYNEWT_VAL_CHOICE(BLE_TRANSPORT_UART_PARITY, odd)) { + if (MYNEWT_VAL_CHOICE(BLE_TRANSPORT_UART_LL_PARITY, odd)) { parity = HAL_UART_PARITY_ODD; - } else if (MYNEWT_VAL_CHOICE(BLE_TRANSPORT_UART_PARITY, even)) { + } else if (MYNEWT_VAL_CHOICE(BLE_TRANSPORT_UART_LL_PARITY, even)) { parity = HAL_UART_PARITY_EVEN; } else { parity = HAL_UART_PARITY_NONE; } - if (MYNEWT_VAL_CHOICE(BLE_TRANSPORT_UART_FLOW_CONTROL, rtscts)) { + if (MYNEWT_VAL_CHOICE(BLE_TRANSPORT_UART_LL_FLOW_CONTROL, rtscts)) { flowctl = HAL_UART_FLOW_CTL_RTS_CTS; } else { flowctl = HAL_UART_FLOW_CTL_NONE; } - rc = hal_uart_config(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT), - MYNEWT_VAL(BLE_TRANSPORT_UART_BAUDRATE), - MYNEWT_VAL(BLE_TRANSPORT_UART_DATA_BITS), - MYNEWT_VAL(BLE_TRANSPORT_UART_STOP_BITS), + rc = hal_uart_config(MYNEWT_VAL(BLE_TRANSPORT_UART_LL_PORT), + MYNEWT_VAL(BLE_TRANSPORT_UART_LL_BAUDRATE), + MYNEWT_VAL(BLE_TRANSPORT_UART_LL_DATA_BITS), + MYNEWT_VAL(BLE_TRANSPORT_UART_LL_STOP_BITS), parity, flowctl); if (rc != 0) { return -1; @@ -192,7 +192,7 @@ ble_transport_to_ll_cmd_impl(void *buf) STAILQ_INSERT_TAIL(&tx_q, txe, tx_q_next); OS_EXIT_CRITICAL(sr); - hal_uart_start_tx(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT)); + hal_uart_start_tx(MYNEWT_VAL(BLE_TRANSPORT_UART_LL_PORT)); return 0; } @@ -220,7 +220,7 @@ ble_transport_to_ll_acl_impl(struct os_mbuf *om) STAILQ_INSERT_TAIL(&tx_q, txe, tx_q_next); OS_EXIT_CRITICAL(sr); - hal_uart_start_tx(MYNEWT_VAL(BLE_TRANSPORT_UART_PORT)); + hal_uart_start_tx(MYNEWT_VAL(BLE_TRANSPORT_UART_LL_PORT)); return 0; } From 8bdd23e2ce0cb3074ddf860eb8bea8da06ea210d Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Wed, 15 May 2024 17:00:43 +0200 Subject: [PATCH 1002/1333] nimble/host: Fix invalid connection handle check in SM This fixes invalid conn handle check in SM. The handle 0 is valid connection handle. --- nimble/host/src/ble_sm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index 0b7c28db59..bb1dfe0842 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -2873,7 +2873,7 @@ ble_sm_rx(struct ble_l2cap_chan *chan) int rc; handle = ble_l2cap_get_conn_handle(chan); - if (!handle) { + if (handle == BLE_HS_CONN_HANDLE_NONE) { return BLE_HS_ENOTCONN; } From d40479fce96091e685ea1e088de80c8ae88c984b Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Tue, 14 May 2024 16:48:34 +0200 Subject: [PATCH 1003/1333] nimble/host: Modify BASS characteristics properties This commit changes BASS audio scan control point and BASS broadcast receive state characteristics properties. Previous properties were not correct with specification. --- nimble/host/audio/services/bass/src/ble_audio_svc_bass.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index 6a40c17a84..97f8afd937 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -861,7 +861,9 @@ ble_svc_audio_bass_init(void) ble_svc_audio_bass_chrs[0].uuid = bass_cp_uuid; ble_svc_audio_bass_chrs[0].access_cb = ble_svc_audio_bass_access; - ble_svc_audio_bass_chrs[0].flags = BLE_GATT_CHR_F_WRITE_NO_RSP | BLE_GATT_CHR_F_WRITE_ENC; + ble_svc_audio_bass_chrs[0].flags = BLE_GATT_CHR_F_WRITE_NO_RSP | + BLE_GATT_CHR_F_WRITE | + BLE_GATT_CHR_F_WRITE_ENC; for (i = 1; i <= MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX); i++) { ble_svc_audio_bass_chrs[i].uuid = bass_receive_state_uuid; From d18ab26959eba920801092120980dc0f719e40e8 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Tue, 14 May 2024 16:49:51 +0200 Subject: [PATCH 1004/1333] nimble/host: Fix incorrect naming in BASS Change keyword and description from PACS to BASS. --- nimble/host/audio/services/bass/pkg.yml | 2 +- nimble/host/audio/services/bass/syscfg.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/host/audio/services/bass/pkg.yml b/nimble/host/audio/services/bass/pkg.yml index e92ab6dd04..1546b2640e 100644 --- a/nimble/host/audio/services/bass/pkg.yml +++ b/nimble/host/audio/services/bass/pkg.yml @@ -22,7 +22,7 @@ pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: - ble - bluetooth - - pacs + - bass - nimble pkg.deps: diff --git a/nimble/host/audio/services/bass/syscfg.yml b/nimble/host/audio/services/bass/syscfg.yml index 2be3f497c3..f125115e1f 100644 --- a/nimble/host/audio/services/bass/syscfg.yml +++ b/nimble/host/audio/services/bass/syscfg.yml @@ -18,7 +18,7 @@ syscfg.defs: BLE_SVC_AUDIO_BASS_SYSINIT_STAGE: description: > - Sysinit stage for Published Audio Capabilities Service. + Sysinit stage for Broadcast Audio Scan Service. value: 303 BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX: description: > From a36ed34174909570e6ea592fe5fa2e621046408f Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Wed, 15 May 2024 12:53:41 +0200 Subject: [PATCH 1005/1333] nimble/host: Modify GATT flags descriptions This commit changes GATT flags descriptions, making them more readable regarding permissions and properties. --- nimble/host/include/host/ble_gatt.h | 30 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index 1492b1aad6..2532e4d2f1 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -121,49 +121,49 @@ struct ble_hs_cfg; * @{ */ -/** GATT Characteristic Flag: Broadcast. */ +/** GATT Characteristic Flag: Broadcast property. */ #define BLE_GATT_CHR_F_BROADCAST 0x0001 -/** GATT Characteristic Flag: Read. */ +/** GATT Characteristic Flag: Read property. */ #define BLE_GATT_CHR_F_READ 0x0002 -/** GATT Characteristic Flag: Write without Response. */ +/** GATT Characteristic Flag: Write without Response property. */ #define BLE_GATT_CHR_F_WRITE_NO_RSP 0x0004 -/** GATT Characteristic Flag: Write. */ +/** GATT Characteristic Flag: Write property. */ #define BLE_GATT_CHR_F_WRITE 0x0008 -/** GATT Characteristic Flag: Notify. */ +/** GATT Characteristic Flag: Notify property. */ #define BLE_GATT_CHR_F_NOTIFY 0x0010 -/** GATT Characteristic Flag: Indicate. */ +/** GATT Characteristic Flag: Indicate property. */ #define BLE_GATT_CHR_F_INDICATE 0x0020 -/** GATT Characteristic Flag: Authenticated Signed Writes. */ +/** GATT Characteristic Flag: Authenticated Signed Writes property. */ #define BLE_GATT_CHR_F_AUTH_SIGN_WRITE 0x0040 -/** GATT Characteristic Flag: Reliable Writes. */ +/** GATT Characteristic Flag: Reliable Writes property. */ #define BLE_GATT_CHR_F_RELIABLE_WRITE 0x0080 -/** GATT Characteristic Flag: Auxiliary Writes. */ +/** GATT Characteristic Flag: Auxiliary Writes permission. */ #define BLE_GATT_CHR_F_AUX_WRITE 0x0100 -/** GATT Characteristic Flag: Read Encrypted. */ +/** GATT Characteristic Flag: Read Encrypted permission. */ #define BLE_GATT_CHR_F_READ_ENC 0x0200 -/** GATT Characteristic Flag: Read Authenticated. */ +/** GATT Characteristic Flag: Read Authenticated permission. */ #define BLE_GATT_CHR_F_READ_AUTHEN 0x0400 -/** GATT Characteristic Flag: Read Authorized. */ +/** GATT Characteristic Flag: Read Authorized permission. */ #define BLE_GATT_CHR_F_READ_AUTHOR 0x0800 -/** GATT Characteristic Flag: Write Encrypted. */ +/** GATT Characteristic Flag: Write Encrypted permission. */ #define BLE_GATT_CHR_F_WRITE_ENC 0x1000 -/** GATT Characteristic Flag: Write Authenticated. */ +/** GATT Characteristic Flag: Write Authenticated permission. */ #define BLE_GATT_CHR_F_WRITE_AUTHEN 0x2000 -/** GATT Characteristic Flag: Write Authorized. */ +/** GATT Characteristic Flag: Write Authorized permission. */ #define BLE_GATT_CHR_F_WRITE_AUTHOR 0x4000 From 9190dcc9e9cbf1b099213ccac447aeb7ff3d8474 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Wed, 15 May 2024 14:56:50 +0200 Subject: [PATCH 1006/1333] Update GATT function descriptions This commit modifies GATT functions description to get them up to speed with current doxygen rules. --- nimble/host/include/host/ble_gatt.h | 45 +++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index 2532e4d2f1..5a268c0c9c 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -334,6 +334,8 @@ int ble_gattc_exchange_mtu(uint16_t conn_handle, * updates; null for no callback. * @param cb_arg The optional argument to pass to the callback * function. + * + * @return 0 on success; nonzero on failure. */ int ble_gattc_disc_all_svcs(uint16_t conn_handle, ble_gatt_disc_svc_fn *cb, void *cb_arg); @@ -637,6 +639,8 @@ int ble_gattc_write_long(uint16_t conn_handle, uint16_t attr_handle, * updates; null for no callback. * @param cb_arg The optional argument to pass to the callback * function. + * + * @return 0 on success; nonzero on failure. */ int ble_gattc_write_reliable(uint16_t conn_handle, struct ble_gatt_attr *attrs, @@ -686,7 +690,15 @@ int ble_gatts_notify_multiple_custom(uint16_t conn_handle, struct ble_gatt_notif *tuples); /** - * Deprecated. Should not be used. Use ble_gatts_notify_custom instead. + * @deprecated Should not be used. Use ble_gatts_notify_custom instead. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param att_handle The attribute handle to indicate in the + * outgoing notification. + * @param om The value to write to the characteristic. + * + * @return 0 on success; nonzero on failure. */ int ble_gattc_notify_custom(uint16_t conn_handle, uint16_t att_handle, struct os_mbuf *om); @@ -706,7 +718,15 @@ int ble_gattc_notify_custom(uint16_t conn_handle, uint16_t att_handle, int ble_gatts_notify(uint16_t conn_handle, uint16_t chr_val_handle); /** - * Deprecated. Should not be used. Use ble_gatts_notify instead. + * @deprecated Should not be used. Use ble_gatts_notify instead. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param chr_val_handle The value attribute handle of the + * characteristic to include in the outgoing + * notification. + * + * @return 0 on success; nonzero on failure. */ int ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle); @@ -752,8 +772,18 @@ int ble_gatts_notify_multiple(uint16_t conn_handle, */ int ble_gatts_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, struct os_mbuf *txom); + /** - * Deprecated. Should not be used. Use ble_gatts_indicate_custom instead. + * @deprecated Should not be used. Use ble_gatts_indicate_custom instead. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param chr_val_handle The value attribute handle of the + * characteristic to include in the outgoing + * indication. + * @param txom The data to include in the indication. + * + * @return 0 on success; nonzero on failure. */ int ble_gattc_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, struct os_mbuf *txom); @@ -773,11 +803,16 @@ int ble_gattc_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, int ble_gatts_indicate(uint16_t conn_handle, uint16_t chr_val_handle); /** - * Deprecated. Should not be used. Use ble_gatts_indicate instead. + * @deprecated Should not be used. Use ble_gatts_indicate instead. + * @copydoc ble_gatts_indicate */ int ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle); -/** Initialize the BLE GATT client. */ +/** + * Initialize the BLE GATT client + * + * @return 0 on success; nonzero on failure. + */ int ble_gattc_init(void); /*** @server. */ From 7ec17b684d818ca6367cefc94c6b51daa299c8d4 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 16 May 2024 14:26:51 +0200 Subject: [PATCH 1007/1333] nimble/audio/bass: Fix infinite loop This fixes infinite loop while sending BASS Receive state notifications. --- nimble/host/audio/services/bass/src/ble_audio_svc_bass.c | 1 - 1 file changed, 1 deletion(-) diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index 97f8afd937..1c4ff639e1 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -408,7 +408,6 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha if (!rc) { rc = ble_svc_audio_bass_receive_state_notify(rcv_state); ev.bass_operation_status.status = rc; - goto done; } ble_audio_event_listener_call(&ev); From 04fea98258cc814ca826e9f0fdacd1c5fb9d3965 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 8 May 2024 11:58:21 +0200 Subject: [PATCH 1008/1333] nimble/host: Fix legacy advertising API with EXT_ADV enabled Configured advertisign instance is required in order to set advertising data when extended advertising HCI is used. Since when legacy PDU are in use we can set both AD and SCAN_RSP we can easily pre-configure selected instance just for this purpose and re-configure it before starting advertising without affecting set AD/SCAN_RSP. --- nimble/host/src/ble_gap.c | 60 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 733d6f1f33..38da71200b 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -202,6 +202,10 @@ struct ble_gap_slave_state { static bssnz_t struct ble_gap_slave_state ble_gap_slave[BLE_ADV_INSTANCES]; +#if MYNEWT_VAL(BLE_EXT_ADV) +static bool ext_adv_legacy_configured = false; +#endif + struct ble_gap_update_entry { SLIST_ENTRY(ble_gap_update_entry) next; struct ble_gap_upd_params params; @@ -1471,6 +1475,8 @@ ble_gap_reset_state(int reason) ble_gap_adv_finished(i, reason, 0, 0); } } + + ext_adv_legacy_configured = false; #else if (ble_gap_adv_active_instance(0)) { /* Indicate to application that advertising has stopped. */ @@ -2552,7 +2558,13 @@ ble_gap_adv_stop(void) return rc; } - return ble_gap_ext_adv_remove(MYNEWT_VAL(BLE_HS_EXT_ADV_LEGACY_INSTANCE)); + rc = ble_gap_ext_adv_remove(MYNEWT_VAL(BLE_HS_EXT_ADV_LEGACY_INSTANCE)); + if (rc) { + return rc; + } + + ext_adv_legacy_configured = false; + return 0; #else int rc; @@ -2804,13 +2816,15 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, ext_params.filter_policy = adv_params->filter_policy; ext_params.high_duty_directed = adv_params->high_duty_cycle; - /* configure instance 0 */ + /* configure legacy instance */ rc = ble_gap_ext_adv_configure(MYNEWT_VAL(BLE_HS_EXT_ADV_LEGACY_INSTANCE), &ext_params, NULL, cb, cb_arg); if (rc) { return rc; } + ext_adv_legacy_configured = true; + if (duration_ms == BLE_HS_FOREVER) { duration = 0; } else { @@ -2900,6 +2914,38 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, #endif } +#if MYNEWT_VAL(BLE_EXT_ADV) +static int +ble_gap_ext_adv_legacy_preconfigure(void) +{ + struct ble_gap_ext_adv_params ext_params; + int rc; + + if (ext_adv_legacy_configured) { + return 0; + } + + memset(&ext_params, 0, sizeof(ext_params)); + ext_params.own_addr_type = BLE_ADDR_RANDOM; + ext_params.primary_phy = BLE_HCI_LE_PHY_1M; + ext_params.secondary_phy = BLE_HCI_LE_PHY_1M; + ext_params.tx_power = 127; + ext_params.sid = 0; + ext_params.legacy_pdu = 1; + ext_params.scannable = 1; + ext_params.connectable = 1; + + rc = ble_gap_ext_adv_configure(MYNEWT_VAL(BLE_HS_EXT_ADV_LEGACY_INSTANCE), + &ext_params, NULL, NULL, NULL); + if (rc) { + return rc; + } + + ext_adv_legacy_configured = true; + return 0; +} +#endif + int ble_gap_adv_set_data(const uint8_t *data, int data_len) { @@ -2913,6 +2959,11 @@ ble_gap_adv_set_data(const uint8_t *data, int data_len) return BLE_HS_EINVAL; } + rc = ble_gap_ext_adv_legacy_preconfigure(); + if (rc) { + return rc; + } + mbuf = os_msys_get_pkthdr(data_len, 0); if (!mbuf) { return BLE_HS_ENOMEM; @@ -2966,6 +3017,11 @@ ble_gap_adv_rsp_set_data(const uint8_t *data, int data_len) return BLE_HS_EINVAL; } + rc = ble_gap_ext_adv_legacy_preconfigure(); + if (rc) { + return rc; + } + mbuf = os_msys_get_pkthdr(data_len, 0); if (!mbuf) { return BLE_HS_ENOMEM; From 89d6fd6c474e3273abe33d18794d69968a145366 Mon Sep 17 00:00:00 2001 From: Guy Mishol Date: Mon, 20 May 2024 13:55:12 +0300 Subject: [PATCH 1009/1333] nimble/transport: Fix undeclared function 'min' warning Fix build warning generated with llvm based compilers on a call to undeclared function 'min'. --- nimble/transport/common/hci_ipc/src/hci_ipc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nimble/transport/common/hci_ipc/src/hci_ipc.c b/nimble/transport/common/hci_ipc/src/hci_ipc.c index 613c9ce153..f1ebbd8953 100644 --- a/nimble/transport/common/hci_ipc/src/hci_ipc.c +++ b/nimble/transport/common/hci_ipc/src/hci_ipc.c @@ -26,6 +26,14 @@ #include #include +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef max +#define max(a, b) ((a) > (b) ? (a) : (b)) +#endif + volatile struct hci_ipc_shm *g_ipc_shm; static void From 07ac1903c5717eec5921f4e50cbe7579b202db9f Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Mon, 3 Jun 2024 13:59:03 +0200 Subject: [PATCH 1010/1333] nimble/host: Fix invalid memset in ble_gattc_read_mult_cb_var This commit applies correct value when using memset to fill attr array. Fixes GATT/CL/GAR/BI-13-C, GATT/CL/GAR/BI-36-C, GATT/CL/GAR/BI-38-C, GATT/CL/GAR/BI-42-C, GATT/CL/GAR/BI-44-C, GATT/CL/GAR/BV-05-C --- nimble/host/src/ble_gattc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index be19f2dc9d..4507317ced 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -3345,7 +3345,7 @@ ble_gattc_read_mult_cb_var(struct ble_gattc_proc *proc, int status, return 0; } - memset(attr, 0, sizeof(*attr)); + memset(attr, 0, sizeof(attr)); for (i = 0; i < proc->read_mult.num_handles; i++) { attr[i].handle = proc->read_mult.handles[i]; From 9f845c47c99d48f6b0469f77e540dd2719330cca Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Mon, 3 Jun 2024 14:10:21 +0200 Subject: [PATCH 1011/1333] nimble/bttester: Add early exit in read_var_cb This commit applies early exit if status != 0. --- apps/bttester/src/btp_gatt_cl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/bttester/src/btp_gatt_cl.c b/apps/bttester/src/btp_gatt_cl.c index 609d7e504c..e4da8a3eaa 100644 --- a/apps/bttester/src/btp_gatt_cl.c +++ b/apps/bttester/src/btp_gatt_cl.c @@ -1392,6 +1392,7 @@ read_var_cb(uint16_t conn_handle, rp->data_length = 0; tester_event(BTP_SERVICE_ID_GATTC, BTP_GATTC_READ_MULTIPLE_VAR_RP, rp, sizeof(*rp)); + return 0; } for (int i = 0; i < num_attrs; i++) { From 554e063421f07fe2a9028ea2b389a503e1d24ee0 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 13 Jun 2024 18:32:24 +0200 Subject: [PATCH 1012/1333] nimble/ll: Fix encryption pause/restart procedure This fixes 2 issues in encrpytion pause/restart procedure (i.e. key refresh) initiated in central role: 1. We transition to "paused" encryption state when LL_PAUSE_ENC_RSP is txd, but that is done after we try to enqueue LL_ENC_REQ. This means LL_ENC_REQ is put at the end of tx queue. By conicidence this makes order of PDUs correct when there's only LL_PAUSE_ENC_RSP on tx queue, but it fails if there was an ACL packet already queued. In such case LL_ENC_REQ is queued after that ACL packet which means neither will be sent - ACL packet cannot be sent because we have no encryption, LL_ENC_REQ cannot be sent because there's ACL packet in front. 2. We do not check if LL_ENC_REQ was properly queued (i.e. if mbuf was allocated for PDU) so it may happen that LL_ENC_REQ will never be queued. In both scenarios the connection will timeout eventually since encryption restart procedure cannot be completed. This fix ensures that LL_ENC_REQ is queued properly by using a "pending" flag that is evaluated when checking for pending procedures. --- .../include/controller/ble_ll_conn.h | 1 + nimble/controller/src/ble_ll_ctrl.c | 38 ++++++++++--------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 88e7934b1f..7d6af874dd 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -108,6 +108,7 @@ struct ble_ll_conn_sm_flags { uint32_t encrypted : 1; uint32_t encrypt_ltk_req : 1; uint32_t encrypt_event_sent : 1; + uint32_t pending_encrypt_restart : 1; uint32_t version_ind_txd : 1; uint32_t version_ind_rxd : 1; uint32_t features_rxd : 1; diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index d2b8a31b7b..da12a5f313 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -2684,6 +2684,9 @@ ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc, void ble_ll_ctrl_chk_proc_start(struct ble_ll_conn_sm *connsm) { +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) + struct os_mbuf *om; +#endif int i; /* XXX: TODO new rules! Cannot start certain control procedures if other @@ -2706,6 +2709,22 @@ ble_ll_ctrl_chk_proc_start(struct ble_ll_conn_sm *connsm) return; } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) + if (connsm->flags.pending_encrypt_restart) { + /* This flag should only be set after LL_PAUSE_ENC_RSP was txd from + * central and there should be already active encryption procedure + * ongoing. We need to restart encryption to complete key refresh. + */ + BLE_LL_ASSERT(connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_ENCRYPT); + BLE_LL_ASSERT(IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_ENCRYPT)); + + om = ble_ll_ctrl_proc_init(connsm, BLE_LL_CTRL_PROC_ENCRYPT, NULL); + if (om) { + connsm->flags.pending_encrypt_restart = 0; + } + } +#endif + /* If there is a running procedure or no pending, do nothing */ if ((connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_IDLE) && (connsm->pending_ctrl_procs != 0)) { @@ -2755,9 +2774,6 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) uint8_t *dptr; uint8_t *rspbuf; uint8_t *rspdata; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - int restart_encryption; -#endif int rc = 0; uint8_t rsp_opcode = 0; @@ -2802,10 +2818,6 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) ble_ll_trace_u32x2(BLE_LL_TRACE_ID_CTRL_RX, opcode, len); -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - restart_encryption = 0; -#endif - /* If opcode comes from reserved value or CtrlData fields is invalid * we shall respond with LL_UNKNOWN_RSP */ @@ -2956,9 +2968,6 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) break; case BLE_LL_CTRL_PAUSE_ENC_RSP: rsp_opcode = ble_ll_ctrl_rx_pause_enc_rsp(connsm); - if (rsp_opcode == BLE_LL_CTRL_PAUSE_ENC_RSP) { - restart_encryption = 1; - } break; #endif case BLE_LL_CTRL_PING_REQ: @@ -3032,13 +3041,6 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) } len = g_ble_ll_ctrl_pkt_lengths[rsp_opcode] + 1; ble_ll_conn_enqueue_pkt(connsm, om, BLE_LL_LLID_CTRL, len); -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) - if (restart_encryption) { - /* XXX: what happens if this fails? Meaning we cant allocate - mbuf? */ - ble_ll_ctrl_proc_init(connsm, BLE_LL_CTRL_PROC_ENCRYPT, NULL); - } -#endif } #if MYNEWT_VAL(BLE_LL_CONN_INIT_AUTO_DLE) @@ -3206,6 +3208,8 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) case BLE_LL_CTRL_PAUSE_ENC_RSP: if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { connsm->enc_data.enc_state = CONN_ENC_S_PAUSE_ENC_RSP_WAIT; + } else { + connsm->flags.pending_encrypt_restart = 1; } break; #endif From 4973bfcc797873152bfd579fbfedac4a2547ed8a Mon Sep 17 00:00:00 2001 From: Mateusz Szafoni Date: Mon, 17 Jun 2024 10:35:56 +0200 Subject: [PATCH 1013/1333] porting/npl/nuttx: Fix building with GCC 414 error: implicit declaration of function 'vprintf' [-Wimplicit-function-declaration] 32 | vprintf(fmt, args); --- porting/npl/nuttx/include/nimble/nimble_npl_os_log.h | 1 + 1 file changed, 1 insertion(+) diff --git a/porting/npl/nuttx/include/nimble/nimble_npl_os_log.h b/porting/npl/nuttx/include/nimble/nimble_npl_os_log.h index 5fcce6aeec..24315a21a7 100644 --- a/porting/npl/nuttx/include/nimble/nimble_npl_os_log.h +++ b/porting/npl/nuttx/include/nimble/nimble_npl_os_log.h @@ -21,6 +21,7 @@ #define _NIMBLE_NPL_OS_LOG_H_ #include +#include /* Example on how to use macro to generate module logging functions */ #define BLE_NPL_LOG_IMPL(lvl) \ From fb15c844542e812ceb49ab5ac8502dc93c167b90 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Fri, 24 May 2024 15:38:55 +0200 Subject: [PATCH 1014/1333] nimble/host: remove check srv supported features According to Core Specification Version 5.4, Vol 3, Part G, section 6.2.1, it is not necesarry to check the Server Supported Features characteristic before attempting to esablish an EATT bearer. --- nimble/host/src/ble_eatt.c | 49 ++------------------------------------ 1 file changed, 2 insertions(+), 47 deletions(-) diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c index 21732b0910..c15f545b6d 100644 --- a/nimble/host/src/ble_eatt.c +++ b/nimble/host/src/ble_eatt.c @@ -73,7 +73,6 @@ static struct os_mempool ble_eatt_sdu_mbuf_mempool; static struct ble_gap_event_listener ble_eatt_listener; static struct ble_npl_event g_read_sup_cl_feat_ev; -static struct ble_npl_event g_read_sup_srv_feat_ev; static void ble_eatt_setup_cb(struct ble_npl_event *ev); static void ble_eatt_start(uint16_t conn_handle); @@ -389,49 +388,6 @@ ble_gatt_eatt_read_cl_uuid_cb(uint16_t conn_handle, return BLE_HS_EDONE; } -static int -ble_gatt_eatt_read_uuid_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, void *arg) -{ - uint8_t supported_features; - int rc; - - if (error == NULL || (error->status != 0 && error->status != BLE_HS_EDONE)) { - BLE_EATT_LOG_DEBUG("eatt: Cannot find Server Supported features on peer device\n"); - return BLE_HS_EDONE; - } - - if (attr == NULL) { - BLE_EATT_LOG_ERROR("eatt: Invalid attribute \n"); - return BLE_HS_EDONE; - } - - rc = os_mbuf_copydata(attr->om, 0, 1, &supported_features); - if (rc) { - BLE_EATT_LOG_ERROR("eatt: Cannot read srv supported features \n"); - return BLE_HS_EDONE; - } - - if (supported_features & 0x01) { - ble_npl_event_set_arg(&g_read_sup_cl_feat_ev, UINT_TO_POINTER(conn_handle)); - ble_npl_eventq_put(ble_hs_evq_get(), &g_read_sup_cl_feat_ev); - } - return BLE_HS_EDONE; -} - -static void -ble_gatt_eatt_read_svr_uuid(struct ble_npl_event *ev) -{ - uint16_t conn_handle; - - conn_handle = POINTER_TO_UINT(ble_npl_event_get_arg(ev)); - - ble_gattc_read_by_uuid(conn_handle, 1, 0xffff, - BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_SERVER_SUPPORTED_FEAT_UUID16), - ble_gatt_eatt_read_uuid_cb, NULL); -} - static void ble_gatt_eatt_read_cl_uuid(struct ble_npl_event *ev) { @@ -463,8 +419,8 @@ ble_eatt_gap_event(struct ble_gap_event *event, void *arg) BLE_EATT_LOG_DEBUG("eatt: Encryption enabled, connecting EATT (conn_handle=0x%04x)\n", event->enc_change.conn_handle); - ble_npl_event_set_arg(&g_read_sup_srv_feat_ev, UINT_TO_POINTER(event->enc_change.conn_handle)); - ble_npl_eventq_put(ble_hs_evq_get(), &g_read_sup_srv_feat_ev); + ble_npl_event_set_arg(&g_read_sup_cl_feat_ev, UINT_TO_POINTER(event->enc_change.conn_handle)); + ble_npl_eventq_put(ble_hs_evq_get(), &g_read_sup_cl_feat_ev); break; case BLE_GAP_EVENT_DISCONNECT: @@ -591,7 +547,6 @@ ble_eatt_init(ble_eatt_att_rx_fn att_rx_cb) ble_gap_event_listener_register(&ble_eatt_listener, ble_eatt_gap_event, NULL); ble_l2cap_create_server(BLE_EATT_PSM, MYNEWT_VAL(BLE_EATT_MTU), ble_eatt_l2cap_event_fn, NULL); - ble_npl_event_init(&g_read_sup_srv_feat_ev, ble_gatt_eatt_read_svr_uuid, NULL); ble_npl_event_init(&g_read_sup_cl_feat_ev, ble_gatt_eatt_read_cl_uuid, NULL); ble_eatt_att_rx_cb = att_rx_cb; From f65f61acdbc427d11b5c7fb1b8213cedc1410766 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Tue, 4 Jun 2024 14:10:10 +0200 Subject: [PATCH 1015/1333] nimble/ble: Add doxygen comments to the header file Adds missing macros and structures documentation. --- nimble/include/nimble/ble.h | 120 ++++++++++++++++++++++++++++++++++-- 1 file changed, 115 insertions(+), 5 deletions(-) diff --git a/nimble/include/nimble/ble.h b/nimble/include/nimble/ble.h index 6979e945bf..c42d5c5ba4 100644 --- a/nimble/include/nimble/ble.h +++ b/nimble/include/nimble/ble.h @@ -20,6 +20,11 @@ #ifndef H_BLE_ #define H_BLE_ +/** + * @defgroup bt_low_energy Bluetooth Low Energy + * @{ + */ + #include #include #include "syscfg/syscfg.h" @@ -29,15 +34,18 @@ extern "C" { #endif -/* The number of advertising instances */ +/** The number of advertising instances */ #define BLE_ADV_INSTANCES (MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) + 1) -/* BLE encryption block definitions */ +/** BLE encryption block definitions */ #define BLE_ENC_BLOCK_SIZE (16) -/* 4 byte header + 251 byte payload. */ +/** 4 byte header + 251 byte payload. */ #define BLE_ACL_MAX_PKT_SIZE 255 +/** + * @cond INTERNAL_DOCS + */ struct ble_encryption_block { uint8_t key[BLE_ENC_BLOCK_SIZE]; @@ -122,17 +130,34 @@ struct ble_mbuf_hdr_txiso { uint16_t packet_seq_num; }; +/** + * @endcond + */ + +/** Structure representing a BLE mbuf header. */ struct ble_mbuf_hdr { union { + /** RX info for received packets. */ struct ble_mbuf_hdr_rxinfo rxinfo; + + /** TX info for transmitted packets. */ struct ble_mbuf_hdr_txinfo txinfo; + + /** TX ISO info for transmitted isochronous packets. */ struct ble_mbuf_hdr_txiso txiso; }; + + /** CPU time when the packet processing began. */ uint32_t beg_cputime; + + /** Remaining microseconds for packet processing. */ uint32_t rem_usecs; }; +/** + * @cond INTERNAL_DOCS + */ #define BLE_MBUF_HDR_IGNORED(hdr) \ (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_IGNORED)) @@ -186,7 +211,16 @@ struct ble_mbuf_hdr /* Length of host user header. Only contains the peer's connection handle. */ #define BLE_MBUF_HS_HDR_LEN (2) +/** + * @endcond + */ + +/** Length of a Bluetooth Device Address. */ #define BLE_DEV_ADDR_LEN (6) + +/** + * @cond INTERNAL_DOCS + */ extern uint8_t g_dev_addr[BLE_DEV_ADDR_LEN]; extern uint8_t g_random_addr[BLE_DEV_ADDR_LEN]; @@ -271,29 +305,103 @@ enum ble_error_codes #define BLE_HW_ERR_DO_NOT_USE (0) /* XXX: reserve this one for now */ #define BLE_HW_ERR_HCI_SYNC_LOSS (1) -/* Own Bluetooth Device address type */ +/** + * @endcond + */ + +/** + * @defgroup ble_own_address_types Bluetooth Device Own Address Types + * @{ + */ + +/** Bluetooth Device Own Address Type: Public. */ #define BLE_OWN_ADDR_PUBLIC (0x00) + +/** Bluetooth Device Own Address Type: Random. */ #define BLE_OWN_ADDR_RANDOM (0x01) + +/** + * Bluetooth Device Own Address Type: Resolvable Private Address (RPA) + * with Public fallback. + */ #define BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT (0x02) + +/** + * Bluetooth Device Own Address Type: Resolvable Private Address (RPA) + * with Random fallback. + */ #define BLE_OWN_ADDR_RPA_RANDOM_DEFAULT (0x03) -/* Bluetooth Device address type */ +/** @} */ + +/** + * @defgroup ble_address_types Bluetooth Device Address Types + * @{ + */ + +/** Bluetooth Device Address Type: Public. */ #define BLE_ADDR_PUBLIC (0x00) + +/** Bluetooth Device Address Type: Random. */ #define BLE_ADDR_RANDOM (0x01) + +/** + * Bluetooth Device Address Type: Public Identity Address + * (Corresponds to Resolved Private Address). + */ #define BLE_ADDR_PUBLIC_ID (0x02) + +/** + * Bluetooth Device Address Type: Random (Static) Identity Address + * (Corresponds to Resolved Private Address). + */ #define BLE_ADDR_RANDOM_ID (0x03) +/** @} */ + +/** + * @brief A macro representing any BLE address. + * + * This macro initializes a `ble_addr_t` structure to all zeros. + */ #define BLE_ADDR_ANY (&(ble_addr_t) { 0, {0, 0, 0, 0, 0, 0} }) +/** + * Checks if the given address is a Resolvable Private Address (RPA). + * + * @param addr Pointer to the `ble_addr_t` structure. + * @return Non-zero if the address is an RPA, + * zero otherwise. + */ #define BLE_ADDR_IS_RPA(addr) (((addr)->type == BLE_ADDR_RANDOM) && \ ((addr)->val[5] & 0xc0) == 0x40) + +/** + * Checks if the given address is a Non-Resolvable Private Address (NRPA). + * + * @param addr Pointer to the `ble_addr_t` structure. + * @return Non-zero if the address is an NRPA, + * zero otherwise. + */ #define BLE_ADDR_IS_NRPA(addr) (((addr)->type == BLE_ADDR_RANDOM) && \ ((addr)->val[5] & 0xc0) == 0x00) + +/** + * @brief Checks if the given address is a Static Random Address. + * + * @param addr Pointer to the `ble_addr_t` structure. + * @return Non-zero if the address is a Static Random Address, + * zero otherwise. + */ #define BLE_ADDR_IS_STATIC(addr) (((addr)->type == BLE_ADDR_RANDOM) && \ ((addr)->val[5] & 0xc0) == 0xc0) +/** Structure representing a BLE address. */ typedef struct { + /** The type of the address. */ uint8_t type; + + /** The value of the address as an array of 6 bytes. */ uint8_t val[6]; } ble_addr_t; @@ -314,4 +422,6 @@ static inline int ble_addr_cmp(const ble_addr_t *a, const ble_addr_t *b) } #endif +/** @} **/ + #endif /* H_BLE_ */ From c478d6eaecf4120de4a741da9794908d59316618 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Wed, 19 Jun 2024 10:18:23 +0200 Subject: [PATCH 1016/1333] targets: remove deprecated settings from various syscfgs This commit replaces deprecated setting BLE_LL_VND_EVENT_ON_ASSERT with BLE_LL_HCI_VS_EVENT_ON_ASSERT. --- .github/targets/nordic_pca10095_blehci/syscfg.yml | 2 +- targets/nordic_pca10095_net-blehci/syscfg.yml | 2 +- targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/targets/nordic_pca10095_blehci/syscfg.yml b/.github/targets/nordic_pca10095_blehci/syscfg.yml index aae8d12769..4c16ba61c6 100644 --- a/.github/targets/nordic_pca10095_blehci/syscfg.yml +++ b/.github/targets/nordic_pca10095_blehci/syscfg.yml @@ -29,7 +29,7 @@ syscfg.vals: BLE_LL_CONN_INIT_SLOTS: 4 BLE_LL_DTM: 1 BLE_LL_DTM_EXTENSIONS: 1 - BLE_LL_VND_EVENT_ON_ASSERT: 1 + BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 BLE_MAX_CONNECTIONS: 5 BLE_MAX_PERIODIC_SYNCS: 5 BLE_MULTI_ADV_INSTANCES: 5 diff --git a/targets/nordic_pca10095_net-blehci/syscfg.yml b/targets/nordic_pca10095_net-blehci/syscfg.yml index f20f40e69f..30f9bcc985 100644 --- a/targets/nordic_pca10095_net-blehci/syscfg.yml +++ b/targets/nordic_pca10095_net-blehci/syscfg.yml @@ -31,7 +31,7 @@ syscfg.vals: BLE_LL_CONN_INIT_SLOTS: 4 BLE_LL_DTM: 1 BLE_LL_DTM_EXTENSIONS: 1 - BLE_LL_VND_EVENT_ON_ASSERT: 1 + BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 BLE_MAX_CONNECTIONS: 5 BLE_EXT_ADV: 1 BLE_EXT_ADV_MAX_SIZE: 1650 diff --git a/targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml b/targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml index b86d58872c..ba780d33cd 100644 --- a/targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml +++ b/targets/nordic_pca10095_net-blehci_broadcaster/syscfg.yml @@ -31,7 +31,7 @@ syscfg.vals: BLE_LL_CONN_INIT_SLOTS: 4 BLE_LL_DTM: 1 BLE_LL_DTM_EXTENSIONS: 1 - BLE_LL_VND_EVENT_ON_ASSERT: 1 + BLE_LL_HCI_VS_EVENT_ON_ASSERT: 1 BLE_MAX_CONNECTIONS: 5 BLE_EXT_ADV: 1 BLE_EXT_ADV_MAX_SIZE: 1650 From cc1015756ba20ab0cb26c7fafdb2437aa2f92dbf Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Tue, 11 Jun 2024 17:52:55 +0200 Subject: [PATCH 1017/1333] ci: Build Nuttx port Adds a step to the CI workflow for checking the build of Nuttx master branch. --- .github/workflows/build_ports.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_ports.yml b/.github/workflows/build_ports.yml index 8c49d1f513..fc508aa3a3 100644 --- a/.github/workflows/build_ports.yml +++ b/.github/workflows/build_ports.yml @@ -34,7 +34,7 @@ jobs: shell: bash run: | sudo apt-get update - sudo apt-get install -y make ccache gcc-multilib g++-multilib + sudo apt-get install -y make ccache gcc-multilib g++-multilib kconfig-frontends - name: Build example ports shell: bash run: | @@ -52,3 +52,14 @@ jobs: sed -i 's|PKG_URL.*|PKG_URL = '$(pwd)'|' RIOT/pkg/nimble/Makefile sed -i 's|PKG_VERSION.*|PKG_VERSION = '${{ github.sha }}'|' RIOT/pkg/nimble/Makefile make -C RIOT/examples/nimble_gatt + - name: Build Nuttx port + shell: bash + if: success() || failure() + continue-on-error: true + run: | + mkdir nuttx-build + git clone --depth=1 https://github.com/apache/nuttx.git nuttx-build/nuttx + git clone --depth=1 https://github.com/apache/nuttx-apps nuttx-build/apps + ./nuttx-build/nuttx/tools/configure.sh -l nrf52840-dk:sdc_nimble + sed -i 's|CONFIG_NIMBLE_REF :=.*|CONFIG_NIMBLE_REF := ${{ github.sha }}|' nuttx-build/apps/wireless/bluetooth/nimble/Makefile + make -C nuttx-build/nuttx From 09ae1c44275de9275e4a6412b132d34daa99c243 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Wed, 22 May 2024 13:16:54 +0200 Subject: [PATCH 1018/1333] porting/update_generated_files: Add comments stripping and prepend license header The script modifying 'syscfg.h' files for ports will now remove all block comments and add the license header --- .github/LICENSE_TEMPLATE | 18 ++++++++++++++++++ porting/update_generated_files.sh | 7 ++++--- 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 .github/LICENSE_TEMPLATE diff --git a/.github/LICENSE_TEMPLATE b/.github/LICENSE_TEMPLATE new file mode 100644 index 0000000000..80b586513c --- /dev/null +++ b/.github/LICENSE_TEMPLATE @@ -0,0 +1,18 @@ +/* + * 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. + */ diff --git a/porting/update_generated_files.sh b/porting/update_generated_files.sh index 7365bc3ed6..94f1808a41 100755 --- a/porting/update_generated_files.sh +++ b/porting/update_generated_files.sh @@ -37,9 +37,10 @@ for target in "${!targets[@]}"; do rm -rf "bin/@apache-mynewt-nimble/porting/targets/${target}/generated/include/logcfg" rm -rf "bin/@apache-mynewt-nimble/porting/targets/${target}/generated/include/sysflash" cp "bin/@apache-mynewt-nimble/porting/targets/${target}/generated/include" "${targets[$target]}" -r - # Remove repo version and hash MYNEWT_VALS as it doesn't make much sense to commit them and they - # defeat the purpose of this script. + # Remove all comments and hash MYNEWT_VALS as it doesn't make much sense to commit them and they + # defeat the purpose of this script. Prepend the license header. find "${targets[$target]}/include" -type f -name 'syscfg.h' -exec sed -i '/MYNEWT_VAL_REPO_*/,/#endif/d' {} \; - find "${targets[$target]}/include" -type f -name 'syscfg.h' -exec sed -i '/\/\*\*\* Repository/,/\*\//d' {} \; + find "${targets[$target]}/include" -type f -name 'syscfg.h' -exec sed -i -E ':a;N;$!ba;s:/\*([^*]|(\*+([^*/])))*\*+/::g' {} \; find "${targets[$target]}/include" -type f -name 'syscfg.h' -exec sed -i '$!N;/^\n$/{$q;D;};P;D;' {} \; + find "${targets[$target]}/include" -type f -name 'syscfg.h' -exec sh -c 'cat "$0" "$1" > "$1.tmp" && mv "$1.tmp" "$1"' "../.github/LICENSE_TEMPLATE" {} \; done From 2096f12513b344a3673abf08e9d3edc624b94d94 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Wed, 22 May 2024 13:30:34 +0200 Subject: [PATCH 1019/1333] ci: Submit PR updating ports syscfg files on merge Adds new step to the CI that creates a Pull Request with each 'syscfg.h' file if changes are detected. --- .github/workflows/ports_syscfg_check.yml | 47 ++++++++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ports_syscfg_check.yml b/.github/workflows/ports_syscfg_check.yml index 66d47a2350..89ccd82e45 100644 --- a/.github/workflows/ports_syscfg_check.yml +++ b/.github/workflows/ports_syscfg_check.yml @@ -19,12 +19,20 @@ name: Check ports syscfg update -on: [pull_request] +on: + push: + branches: + - 'master' + paths: + - '*/syscfg.h' jobs: targets: name: Check ports syscfg update runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 @@ -52,23 +60,46 @@ jobs: newt upgrade --shallow=1 rm -rf repos/apache-mynewt-nimble git clone .. repos/apache-mynewt-nimble - cd .. - name: Build ports tests targets shell: bash run: | cd build ./repos/apache-mynewt-nimble/porting/update_generated_files.sh - cd repos/apache-mynewt-nimble - name: Check ports syscfg (debug) shell: bash if: runner.debug == '1' run: | + cd build/repos/apache-mynewt-nimble git diff - name: Check ports syscfg shell: bash run: | - git diff --quiet || (\ - echo -e "\033[0;31mChanges in system configration files detected."; - echo -e "\033[0;31mRun ./repos/apache-mynewt-nimble/porting/update_generated_files.sh" \ - "to update NimBLE ports configurations."; - exit 1) + cd build/repos/apache-mynewt-nimble + if ! git diff --quiet; then + echo -e "\033[0;31mChanges in system configuration files detected:" + git diff --name-only + cp porting/examples/linux/include/syscfg/syscfg.h ../../../porting/examples/linux/include/syscfg/syscfg.h + cp porting/examples/linux_blemesh/include/syscfg/syscfg.h ../../../porting/examples/linux_blemesh/include/syscfg/syscfg.h + cp porting/examples/nuttx/include/syscfg/syscfg.h ../../../porting/examples/nuttx/include/syscfg/syscfg.h + cp porting/nimble/include/syscfg/syscfg.h ../../../porting/nimble/include/syscfg/syscfg.h + cp porting/npl/riot/include/syscfg/syscfg.h ../../../porting/npl/riot/include/syscfg/syscfg.h + else + echo "No changes detected in system configuration files." + fi + cd ../../.. + rm -rf build + - name: Create Pull Request + uses: peter-evans/create-pull-request@v6 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: | + porting: Update ports syscfg + branch: update-ports-syscfg + title: "Update ports syscfg" + body: | + Update NimBLE ports configurations: + - Removes all /* */ comments from `syscfg.h` files. + - Adds the license header to each `syscfg.h` file. + - Auto-generated by [create-pull-request][1] + + [1]: https://github.com/peter-evans/create-pull-request From 263e5d4d40f548292a1e3263a9bf7a19ca01e681 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 26 Apr 2024 15:22:23 +0200 Subject: [PATCH 1020/1333] nimble/transport/socket: Add ISO Tx transport support Add support for sending ISO data on native. --- nimble/transport/socket/src/ble_hci_socket.c | 50 ++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/nimble/transport/socket/src/ble_hci_socket.c b/nimble/transport/socket/src/ble_hci_socket.c index 41975cacc6..c0581c6359 100644 --- a/nimble/transport/socket/src/ble_hci_socket.c +++ b/nimble/transport/socket/src/ble_hci_socket.c @@ -277,6 +277,50 @@ ble_hci_sock_acl_tx(struct os_mbuf *om) #if MYNEWT_VAL(BLE_SOCK_USE_LINUX_BLUE) || MYNEWT_VAL(BLE_SOCK_USE_TCP) static int +ble_hci_sock_iso_tx(struct os_mbuf *om) +{ + struct msghdr msg; + struct iovec iov[8]; + int i; + struct os_mbuf *m; + uint8_t ch; + + memset(&msg, 0, sizeof(msg)); + memset(iov, 0, sizeof(iov)); + + msg.msg_iov = iov; + + ch = BLE_HCI_UART_H4_ISO; + iov[0].iov_len = 1; + iov[0].iov_base = &ch; + i = 1; + for (m = om; m; m = SLIST_NEXT(m, om_next)) { + iov[i].iov_base = m->om_data; + iov[i].iov_len = m->om_len; + i++; + } + msg.msg_iovlen = i; + + STATS_INC(hci_sock_stats, omsg); + STATS_INC(hci_sock_stats, oiso); + STATS_INCN(hci_sock_stats, obytes, OS_MBUF_PKTLEN(om) + 1); + i = sendmsg(ble_hci_sock_state.sock, &msg, 0); + os_mbuf_free_chain(om); + if (i != OS_MBUF_PKTLEN(om) + 1) { + if (i < 0) { + dprintf(1, "sendmsg() failed : %d\n", errno); + } else { + dprintf(1, "sendmsg() partial write: %d\n", i); + } + STATS_INC(hci_sock_stats, oerr); + return BLE_ERR_MEM_CAPACITY; + } + return 0; +} +#endif /* BLE_SOCK_USE_LINUX_BLUE */ + +#if MYNEWT_VAL(BLE_SOCK_USE_LINUX_BLUE) +static int ble_hci_sock_cmdevt_tx(uint8_t *hci_ev, uint8_t h4_type) { struct msghdr msg; @@ -871,6 +915,12 @@ ble_hci_sock_init(void) SYSINIT_PANIC_ASSERT(rc == 0); } +int +ble_transport_to_ll_iso_impl(struct os_mbuf *om) +{ + return ble_hci_sock_iso_tx(om); +} + void ble_transport_ll_init(void) { From dba496900b2dc6bade7f859e21d9aba050fc4554 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Fri, 21 Jun 2024 10:35:42 +0200 Subject: [PATCH 1021/1333] ci: Fix `Check ports syscfg update` workflow Updates run conditions, so that the action will be triggered on every PR merge. Additionally, adds a scheduled run once a day. --- .github/workflows/ports_syscfg_check.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ports_syscfg_check.yml b/.github/workflows/ports_syscfg_check.yml index 89ccd82e45..e49dedc30b 100644 --- a/.github/workflows/ports_syscfg_check.yml +++ b/.github/workflows/ports_syscfg_check.yml @@ -23,8 +23,8 @@ on: push: branches: - 'master' - paths: - - '*/syscfg.h' + schedule: + - cron: '0 0 * * *' jobs: targets: From cbe729b00a1913020ae4cbe6700046ee1813f91d Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Thu, 27 Jun 2024 15:18:05 +0200 Subject: [PATCH 1022/1333] ci: Update `Check ports syscfg update` workflow Updates run conditions, so that the action will not be triggered on forks. Changes cron schedule to avoid conflicts with other jobs. --- .github/workflows/ports_syscfg_check.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ports_syscfg_check.yml b/.github/workflows/ports_syscfg_check.yml index e49dedc30b..0b8c6aa6a3 100644 --- a/.github/workflows/ports_syscfg_check.yml +++ b/.github/workflows/ports_syscfg_check.yml @@ -24,7 +24,7 @@ on: branches: - 'master' schedule: - - cron: '0 0 * * *' + - cron: '37 21 * * *' jobs: targets: @@ -33,6 +33,7 @@ jobs: permissions: contents: write pull-requests: write + if: github.event.repository.fork == false steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 From cf42d74a7041d284892cb717e1a37efa247af2d4 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 25 Jan 2024 13:30:12 +0100 Subject: [PATCH 1023/1333] nimble/audio: Add initial audio broadcast sink implementation This adds initial implementation of audio broadcast sink. --- nimble/host/audio/include/audio/ble_audio.h | 98 + .../include/audio/ble_audio_broadcast_sink.h | 281 +++ .../include/audio/ble_audio_scan_delegator.h | 393 ++++ nimble/host/audio/pkg.yml | 9 + nimble/host/audio/src/ble_audio.c | 4 +- .../host/audio/src/ble_audio_broadcast_sink.c | 1647 +++++++++++++++++ .../audio/src/ble_audio_broadcast_sink_priv.h | 34 + nimble/host/audio/src/ble_audio_priv.h | 11 + .../host/audio/src/ble_audio_scan_delegator.c | 460 +++++ .../audio/src/ble_audio_scan_delegator_priv.h | 33 + nimble/host/audio/syscfg.yml | 79 +- 11 files changed, 3047 insertions(+), 2 deletions(-) create mode 100644 nimble/host/audio/include/audio/ble_audio_broadcast_sink.h create mode 100644 nimble/host/audio/include/audio/ble_audio_scan_delegator.h create mode 100644 nimble/host/audio/src/ble_audio_broadcast_sink.c create mode 100644 nimble/host/audio/src/ble_audio_broadcast_sink_priv.h create mode 100644 nimble/host/audio/src/ble_audio_scan_delegator.c create mode 100644 nimble/host/audio/src/ble_audio_scan_delegator_priv.h diff --git a/nimble/host/audio/include/audio/ble_audio.h b/nimble/host/audio/include/audio/ble_audio.h index 836a1ab532..6fb5f295ed 100644 --- a/nimble/host/audio/include/audio/ble_audio.h +++ b/nimble/host/audio/include/audio/ble_audio.h @@ -68,6 +68,9 @@ /** Broadcast Audio Broadcast Code Size. */ #define BLE_AUDIO_BROADCAST_CODE_SIZE 16 +/** Basic Audio Announcement Service UUID. */ +#define BLE_BASIC_AUDIO_ANNOUNCEMENT_SVC_UUID 0x1851 + /** Broadcast Audio Announcement Service UUID. */ #define BLE_BROADCAST_AUDIO_ANNOUNCEMENT_SVC_UUID 0x1852 @@ -576,6 +579,15 @@ struct ble_audio_broadcast_name { /** BLE Audio event: BASS - Set Broadcast Code */ #define BLE_AUDIO_EVENT_BASS_BROADCAST_CODE_SET 6 +/** BLE Audio event: Broadcast Sink - PA Sync state */ +#define BLE_AUDIO_EVENT_BROADCAST_SINK_PA_SYNC_STATE 7 + +/** BLE Audio event: Broadcast Sink - BIS Sync state */ +#define BLE_AUDIO_EVENT_BROADCAST_SINK_BIS_SYNC_STATE 8 + +/** BLE Audio event: Broadcast Sink - Metadata Updated */ +#define BLE_AUDIO_EVENT_BROADCAST_SINK_METADATA 9 + /** @} */ /** @brief Broadcast Announcement */ @@ -650,6 +662,56 @@ struct ble_audio_event_bass_set_broadcast_code { uint8_t broadcast_code[BLE_AUDIO_BROADCAST_CODE_SIZE]; }; +enum ble_audio_broadcast_sink_sync_state { + /** Broadcast Sink Sync State: Not Synced */ + BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_NOT_SYNCED, + + /** Broadcast Sink Sync State: Sync initiated */ + BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_INITIATED, + + /** Broadcast Sink Sync State: Sync established */ + BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_ESTABLISHED, +}; + +/** @brief PA Synchronization state */ +struct ble_audio_event_broadcast_sink_pa_sync_state { + /** Source ID */ + uint8_t source_id; + + /** Sync state */ + enum ble_audio_broadcast_sink_sync_state state; +}; + +/** @brief BIS Synchronization state */ +struct ble_audio_event_broadcast_sink_bis_sync_state { + /** Source ID */ + uint8_t source_id; + + /** BIS Index */ + uint8_t bis_index; + + /** Sync state */ + enum ble_audio_broadcast_sink_sync_state state; + + /** Connection Handle. Valid if `state` is @ref BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_ESTABLISHED */ + uint16_t conn_handle; +}; + +/** @brief Broadcast Sink Metadata changed */ +struct ble_audio_event_broadcast_sink_metadata { + /** Source ID */ + uint8_t source_id; + + /** BIS Index Mask */ + uint8_t bis_sync; + + /** Scan Delegator Subgroup: Metadata */ + const uint8_t *metadata; + + /** Scan Delegator Subgroup: Metadata length */ + uint8_t metadata_length; +}; + /** * Represents a BLE Audio related event. When such an event occurs, the host * notifies the application by passing an instance of this structure to an @@ -715,6 +777,27 @@ struct ble_audio_event { * Represents a Broadcast Code baing set in BASS. */ struct ble_audio_event_bass_set_broadcast_code bass_set_broadcast_code; + + /** + * @ref BLE_AUDIO_EVENT_BROADCAST_SINK_PA_SYNC_STATE + * + * Represents a update of Broadcast Sink PA sync state. + */ + struct ble_audio_event_broadcast_sink_pa_sync_state broadcast_sink_pa_sync_state; + + /** + * @ref BLE_AUDIO_EVENT_BROADCAST_SINK_BIS_SYNC_STATE + * + * Represents an update of Broadcast Sink BIS sync state. + */ + struct ble_audio_event_broadcast_sink_bis_sync_state broadcast_sink_bis_sync_state; + + /** + * @ref BLE_AUDIO_EVENT_BROADCAST_SINK_METADATA + * + * Represents an update in Broadcast Sink Metadata. + */ + struct ble_audio_event_broadcast_sink_metadata broadcast_sink_metadata; }; }; @@ -950,6 +1033,21 @@ struct ble_audio_base { STAILQ_HEAD(, ble_audio_big_subgroup) subs; }; +static inline const char * +ble_audio_broadcast_sink_sync_state_str(enum ble_audio_broadcast_sink_sync_state state) +{ + switch (state) { + case BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_NOT_SYNCED: + return "not synced"; + case BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_INITIATED: + return "initiated"; + case BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_ESTABLISHED: + return "established"; + default: + return "invalid"; + } +} + /** @} */ #endif /* H_BLE_AUDIO_ */ diff --git a/nimble/host/audio/include/audio/ble_audio_broadcast_sink.h b/nimble/host/audio/include/audio/ble_audio_broadcast_sink.h new file mode 100644 index 0000000000..36da4e6c10 --- /dev/null +++ b/nimble/host/audio/include/audio/ble_audio_broadcast_sink.h @@ -0,0 +1,281 @@ +/* + * 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_BLE_AUDIO_BROADCAST_SINK_ +#define H_BLE_AUDIO_BROADCAST_SINK_ + +/** + * @file ble_audio_broadcast_sink.h + * + * @brief Bluetooth LE Audio BAP Broadcast Sink API + * + * @defgroup ble_audio_broadcast_sink Bluetooth LE Audio BAP Broadcast Sink + * @ingroup bt_host + * @{ + * + */ + +#include +#include "host/ble_gap.h" +#include "host/ble_iso.h" +#include "audio/ble_audio.h" +#include "audio/ble_audio_scan_delegator.h" +#include "nimble/ble.h" + +enum ble_audio_broadcast_sink_action_type { + /** Broadcast Sink Action Type: PA sync */ + BLE_AUDIO_BROADCAST_SINK_ACTION_PA_SYNC, + + /** Broadcast Sink Action Type: BIG sync */ + BLE_AUDIO_BROADCAST_SINK_ACTION_BIG_SYNC, + + /** Broadcast Sink Action Type: BIS sync */ + BLE_AUDIO_BROADCAST_SINK_ACTION_BIS_SYNC, + + /** Broadcast Sink Action Type: Start discovery (scan) */ + BLE_AUDIO_BROADCAST_SINK_ACTION_DISC_START, + + /** Broadcast Sink Action Type: Start discovery (scan) */ + BLE_AUDIO_BROADCAST_SINK_ACTION_DISC_STOP, +}; + +struct ble_audio_broadcast_sink_action { + /** + * Indicates the type of action that is requested. + */ + enum ble_audio_broadcast_sink_action_type type; + + /** + * A discriminated union containing additional details concerning the action. + * The 'type' field indicates which member of the union is valid. + */ + union { + /** + * Represents PA Sync parameters request. + * + * The action triggered on locally or remotely initiated PA synchronization request. + * The application should initialize the `out_parameters`, or abort the process. + * + * Valid for the following action types: + * o BLE_AUDIO_BROADCAST_SINK_ACTION_PA_SYNC + * + * Return: + * o 0 on success; + * o A non-zero value to abort. + */ + struct { + /** Pointer to Periodic Sync parameters to initialize. */ + struct ble_gap_periodic_sync_params *out_params; + } pa_sync; + + /** + * Represents BIG Sync request. + * + * The action triggered on locally or remotely initiated BIG synchronization request. + * The application should provide the `out_mse` and `out_sync_timeout`, + * or reject the request. + * + * Valid for the following action types: + * o BLE_AUDIO_BROADCAST_SINK_ACTION_BIG_SYNC + * + * Return: + * o 0 on success; + * o A non-zero value to abort. + */ + struct { + /** Source ID. */ + uint8_t source_id; + + /** ISO Interval. */ + uint16_t iso_interval; + + /** Presentation delay. */ + uint32_t presentation_delay; + + /** Number of SubEvents. The total number of subevents that are used to transmit BIS Data. */ + uint8_t nse; + + /** Burst Number. The number of new payloads for each BIS in a BIS event. */ + uint8_t bn; + + /** + * Pointer to Maximum subevents value to initialize. + * Range: 0x00 to 0x1F. + * Default: 0x00, meaning the Controller can schedule reception of any number of subevents up to NSE. + */ + uint8_t *out_mse; + + /** + * Pointer to Sync Timeout value to initialize. + * Range: 0x000A to 0x4000. + * Default: @ref iso_interval * 6. + */ + uint16_t *out_sync_timeout; + } big_sync; + + /** + * Represents BIS Sync request. + * + * The action triggered on locally or remotely initiated BIS synchronization request. + * The application should provide the `out_cb` and optionally `out_cb_arg`, + * or reject the request. + * + * @note The `subgroup` object as well as it's `base` object, + * therefore must be copied to in order to cache its information. + * + * Valid for the following action types: + * o BLE_AUDIO_BROADCAST_SINK_ACTION_BIS_SYNC + * + * Return: + * o 0 on success; + * o A non-zero value to abort. + */ + struct { + /** Source ID. */ + uint8_t source_id; + + /** Subgroup index. */ + uint8_t subgroup_index; + + /** Broadcast Audio Source Endpoint BIS. */ + const struct ble_audio_base_bis *bis; + + /** Broadcast Audio Source Endpoint Subgroup. */ + const struct ble_audio_base_subgroup *subgroup; + } bis_sync; + + /** + * Represents discovery start request. + * + * The action triggered on locally as part of PA synchronization process. + * + * Valid for the following action types: + * o BLE_AUDIO_BROADCAST_SINK_ACTION_SCAN_START + * + * Return: + * o 0 on success; + * o A non-zero value to abort. + */ + struct { + /** Preferred extended discovery parameters. */ + const struct ble_gap_ext_disc_params *params_preferred; + } disc_start; + }; +}; + +/** + * Prototype of Broadcast Sink action callback. + * This function shall return 0 if operation is accepted, and error code if rejected. + */ +typedef int ble_audio_broadcast_sink_action_fn(struct ble_audio_broadcast_sink_action *action, + void *arg); + +/** + * @brief Sets the application callback function. + * + * This function sets the callback function and its argument that will be called + * when a Broadcast Sink action is triggered. + * + * @param cb Pointer to the callback function of type ble_audio_scan_delegator_ev_cb. + * @param arg Pointer to the argument to be passed to the callback function. + * + * @return Returns 0 on success, or a non-zero error code otherwise. + */ +int ble_audio_broadcast_sink_cb_set(ble_audio_broadcast_sink_action_fn *cb, void *arg); + +/** Sink Add function parameters */ +struct ble_audio_broadcast_sink_add_params { + /** Broadcast Code */ + uint8_t broadcast_code[BLE_AUDIO_BROADCAST_CODE_SIZE]; + + /** Broadcast Code parameter is valid */ + uint8_t broadcast_code_is_valid : 1; +}; + +/** + * @brief Start audio broadcast sink synchronization with the source. + * + * This function synchronizes the audio broadcast sink with the source + * identified by the given source ID. + * The source can be added locally using @ref ble_svc_audio_bass_receive_state_add function + * or requested by remote device. + * + * @param source_id Source ID of Broadcast Source to synchronize to. + * @param params Parameters to be used. + * + * @return 0 on success; + * BLE_HS_ENOENT if the source ID is invalid; + * BLE_HS_EDONE if synced already; + * BLE_HS_EALREADY if the synchronization is in progress; + * BLE_HS_ENOMEM if memory allocation fails; + * Any other non-zero value on failure. + */ +int ble_audio_broadcast_sink_start(uint8_t source_id, + const struct ble_audio_broadcast_sink_add_params *params); + +/** + * @brief Stop audio broadcast sink synchronization. + * + * This function terminates or aborts the pending synchronization with the source + * identified by the given source ID. + * + * @param source_id Source ID of Broadcast Source to synchronize to. + * + * @return 0 on success; + * BLE_HS_ENOENT if the source ID is invalid; + * Any other non-zero value on failure. + */ +int ble_audio_broadcast_sink_stop(uint8_t source_id); + +/** Metadata Update function parameters */ +struct ble_audio_broadcast_sink_metadata_update_params { + /** Subgroup index */ + uint8_t subgroup_index; + + /** Scan Delegator Subgroup: Metadata */ + uint8_t *metadata; + + /** Scan Delegator Subgroup: Metadata length */ + uint8_t metadata_length; +}; + +/** + * @brief Sets audio broadcast sink metadata. + * + * This function updates the broadcast sink metadata identified by the given source ID. + * + * @param source_id Source ID of Broadcast Source. + * @param params Parameters to be used. + * + * @return 0 on success; + * BLE_HS_ENOENT if the source ID is invalid; + * Any other non-zero value on failure. + */ +int ble_audio_broadcast_sink_metadata_update(uint8_t source_id, + const struct ble_audio_broadcast_sink_metadata_update_params *params); + +/** + * @brief Initialize Broadcast Sink + * + * This function is restricted to be called by sysinit. + * + * @return Returns 0 on success, or a non-zero error code otherwise. + */ +int ble_audio_broadcast_sink_init(void); +#endif /* H_BLE_AUDIO_BROADCAST_SINK_ */ diff --git a/nimble/host/audio/include/audio/ble_audio_scan_delegator.h b/nimble/host/audio/include/audio/ble_audio_scan_delegator.h new file mode 100644 index 0000000000..5c9aa66053 --- /dev/null +++ b/nimble/host/audio/include/audio/ble_audio_scan_delegator.h @@ -0,0 +1,393 @@ +/* + * 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_BLE_AUDIO_SCAN_DELEGATOR_ +#define H_BLE_AUDIO_SCAN_DELEGATOR_ + +/** + * @file ble_audio_scan_delegator.h + * + * @brief Bluetooth LE Audio BAP Scan Delegator API + * + * @defgroup ble_audio_scan_delegator Bluetooth LE Audio BAP Scan Delegator + * @ingroup bt_host + * @{ + * + */ + +#include +#include "audio/ble_audio.h" +#include "nimble/ble.h" + +#if MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR) +#define BLE_AUDIO_SCAN_DELEGATOR_SUBGROUP_MAX \ + MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR_SUBGROUP_MAX) +#else +#define BLE_AUDIO_SCAN_DELEGATOR_SUBGROUP_MAX 0 +#endif /* BLE_AUDIO_SCAN_DELEGATOR */ + +/** No preferred BIS Synchronization. Decision is left to application. */ +#define BLE_AUDIO_SCAN_DELEGATOR_BIS_SYNC_ANY 0xFFFFFFFF + +/** Unknown PA Interval */ +#define BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_UNKNOWN 0xFFFF + +/** Scan Delegator Source descriptor */ +struct ble_audio_scan_delegator_source_desc { + /** Scan Delegator Source: BLE Address */ + ble_addr_t addr; + + /** Scan Delegator Source: Advertising SID */ + uint8_t adv_sid; + + /** Scan Delegator Source: Broadcast ID */ + uint32_t broadcast_id; +}; + +/** Scan Delegator Broadcast Encryption States */ +enum ble_audio_scan_delegator_big_enc { + /** Scan Delegator BIG Encryption: Not Encrypted */ + BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_NONE, + + /** Scan Delegator BIG Encryption: Broadcast Code Required */ + BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_BROADCAST_CODE_MISSING, + + /** Scan Delegator BIG Encryption: Decrypting */ + BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_DECRYPTING, + + /** Scan Delegator BIG Encryption: Bad Code */ + BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_BROADCAST_CODE_INVALID +}; + +/** Scan Delegator PA Sync States */ +enum ble_audio_scan_delegator_pa_sync_state { + /** Scan Delegator PA Sync State: Not synchronized to PA */ + BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_NOT_SYNCED, + + /** Scan Delegator PA Sync State: SyncInfo Request */ + BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_SYNC_INFO_REQ, + + /** Scan Delegator PA Sync State: Synchronized to PA */ + BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_SYNCED, + + /** Scan Delegator PA Sync State: Failed to synchronize to PAA */ + BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_ERROR, + + /** Scan Delegator PA Sync State: No PAST */ + BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_NO_PAST +}; + +/** Scan Delegator Subgroup definition */ +struct ble_audio_scan_delegator_subgroup { + /** Scan Delegator Subgroup: BIS Synchronization */ + uint32_t bis_sync; + + /** Scan Delegator Subgroup: Metadata */ + uint8_t *metadata; + + /** Scan Delegator Subgroup: Metadata length */ + uint8_t metadata_length; +}; + +/** Scan Delegator PA Sync option */ +enum ble_audio_scan_delegator_pa_sync { + /** Scan Delegator PA Sync: Do not synchronize to PA */ + BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_DO_NOT_SYNC, + + /** Scan Delegator PA Sync: Synchronize to PA – PAST available */ + BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_PAST_AVAILABLE, + + /** Scan Delegator PA Sync: Synchronize to PA – PAST not available */ + BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_PAST_NOT_AVAILABLE, +}; + +/** Scan Delegator Broadcast Source Synchronization option */ +struct ble_audio_scan_delegator_sync_opt { + /** PA Sync option */ + enum ble_audio_scan_delegator_pa_sync pa_sync; + + /** PA Sync interval */ + uint16_t pa_interval; + + /** Number of Subgroups */ + uint8_t num_subgroups; + + /** Subgroup sync option */ + struct ble_audio_scan_delegator_subgroup subgroups[ + BLE_AUDIO_SCAN_DELEGATOR_SUBGROUP_MAX]; +}; + +enum ble_audio_scan_delegator_action_type { + /** Scan Delegator Action Type: Add Source */ + BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_ADD, + + /** Scan Delegator Action Type: Modify Source */ + BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_MODIFY, + + /** Scan Delegator Action Type: Remove Source */ + BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_REMOVE, +}; + +struct ble_audio_scan_delegator_action { + /** + * Indicates the type of action that is requested. + */ + enum ble_audio_scan_delegator_action_type type; + + /** + * A union containing additional details concerning the action. + * The 'type' field indicates which member of the union is valid. + */ + union { + /** + * Represents remote Add Source operation request. + * + * Valid for the following action types: + * o BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_ADD + * + * @note The @ref ble_audio_scan_delegator_subgroup.metadata object is temporary, therefore must be copied to in + * order to cache its information. + * + * Return: + * o 0 on success; + * o A non-zero value to reject. + */ + struct { + /** Source ID */ + uint8_t source_id; + + /** Broadcast Source descriptor */ + struct ble_audio_scan_delegator_source_desc source_desc; + + /** Broadcast synchronization option */ + struct ble_audio_scan_delegator_sync_opt sync_opt; + + /** + * Valid pointer to provide source ID to be swapped or NULL. + * + * If there are insufficient resources to handle the operation, the application is requested to provide + * source ID to be removed once accepted. + */ + uint8_t *out_source_id_to_swap; + } source_add; + + /** + * Represents remote Modify Source operation request. + * + * Valid for the following action types: + * o BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_MODIFY + * + * @note The @ref ble_audio_scan_delegator_subgroup.metadata object is temporary, therefore must be copied to in + * order to cache its information. + * + * Return: + * o 0 on success; + * o A non-zero value to reject. + */ + struct { + /** Source ID */ + uint8_t source_id; + + /** Broadcast synchronization option */ + struct ble_audio_scan_delegator_sync_opt sync_opt; + } source_modify; + + /** + * Represents remote Remove Source operation request. + * + * Valid for the following action types: + * o BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_REMOVE + * + * Return: + * o 0 on success; + * o A non-zero value to reject. + */ + struct { + /** Source ID */ + uint8_t source_id; + } source_remove; + + /** + * Represents remote Broadcast Code Set operation request. + * + * Valid for the following action types: + * o BLE_AUDIO_SCAN_DELEGATOR_ACTION_BROADCAST_CODE + * + * Return: + * o 0 on success; + * o A non-zero value on failure. + */ + struct { + /** Source ID */ + uint8_t source_id; + + /** Broadcast Code value to be stored. */ + const uint8_t value[BLE_AUDIO_BROADCAST_CODE_SIZE]; + } broadcast_code; + }; +}; + +/** + * Prototype of Scan Delegator action callback. + * This function shall return 0 if operation is accepted, and error code if rejected. + */ +typedef int ble_audio_scan_delegator_action_fn( + struct ble_audio_scan_delegator_action *action, void *arg); + +/** + * @brief Sets the application callback function. + * + * This function sets the callback function that will be called on remote device request. + * + * @param[in] cb Pointer to the callback function. + * @param[in] arg Pointer to any additional arguments that need to + * be passed to the callback function. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_scan_delegator_action_fn_set(ble_audio_scan_delegator_action_fn *cb, void *arg); + +/** Scan Delegator Receive State definition */ +struct ble_audio_scan_delegator_receive_state { + /** Scan Delegator Receive State: PA Sync state */ + enum ble_audio_scan_delegator_pa_sync_state pa_sync_state; + + /** Scan Delegator Receive State: BIG Encryption */ + enum ble_audio_scan_delegator_big_enc big_enc; + + /** + * Incorrect Bad Broadcast Code. + * Valid for @ref BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_BROADCAST_CODE_INVALID. + */ + uint8_t bad_code[BLE_AUDIO_BROADCAST_CODE_SIZE]; + + /** Scan Delegator Receive State: Number of subgroups */ + uint8_t num_subgroups; + + /** Scan Delegator Receive State: subgroup entries */ + struct ble_audio_scan_delegator_subgroup subgroups[ + MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR_SUBGROUP_MAX)]; +}; + +/** Receive State Add function parameters */ +struct ble_audio_scan_delegator_receive_state_add_params { + /** Broadcast Source descriptor */ + struct ble_audio_scan_delegator_source_desc source_desc; + + /** Receive state */ + struct ble_audio_scan_delegator_receive_state state; +}; + +/** + * @brief Adds the receive state. + * + * This function allocates receive state and returns it's source ID. + * + * @param[in] params Parameters to be used. + * @param[in,out] source_id Unique source ID of receive state added. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_scan_delegator_receive_state_add(const struct ble_audio_scan_delegator_receive_state_add_params *params, + uint8_t *source_id); + +/** + * @brief Removes the receive state. + * + * This function removes the specific receive state identified by source ID. + * + * @param[in] source_id Source ID of receive state to be removed. + * @param[in] params Parameters to be used. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_scan_delegator_receive_state_remove(uint8_t source_id); + +/** + * @brief Set the receive state. + * + * This function updates the specific receive state identified by source ID. + * + * @param[in] source_id Source ID of receive state to be updated. + * @param[in] state Receive state to be set. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_scan_delegator_receive_state_set(uint8_t source_id, + const struct ble_audio_scan_delegator_receive_state *state); + +/** + * @brief get the receive state. + * + * This function returns the specific receive state identified by source ID. + * + * @param[in] source_id Source ID of receive state to be updated. + * @param[in,out] state Pointer to receive state to be populate. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_scan_delegator_receive_state_get(uint8_t source_id, + struct ble_audio_scan_delegator_receive_state *state); + +/** Scan Delegator Receive State entry definition */ +struct ble_audio_scan_delegator_receive_state_entry { + /** Source ID */ + uint8_t source_id; + + /** Broadcast Source descriptor */ + struct ble_audio_scan_delegator_source_desc source_desc; + + /** Receive state */ + struct ble_audio_scan_delegator_receive_state state; +}; + +/** + * Type definition Receive State iteration callback function. + * + * @note Return 0 to continue, or a non-zero to abort foreach loop. + */ +typedef int ble_audio_scan_delegator_receive_state_foreach_fn( + struct ble_audio_scan_delegator_receive_state_entry *entry, void *arg); + +/** + * @brief Iterate receive states. + * + * @param[in] cb Callback to be called on codec entries. + * @param[in] arg Optional callback argument. + * + * @return 0 on success; + * A non-zero value on failure. + */ +void ble_audio_scan_delegator_receive_state_foreach(ble_audio_scan_delegator_receive_state_foreach_fn *cb, void *arg); + +/** + * @brief Initialize Scan Delegator + * + * This function is restricted to be called by sysinit. + * + * @return 0 on success; + * A non-zero value on failure. + */ +int ble_audio_scan_delegator_init(void); +#endif /* H_BLE_AUDIO_SCAN_DELEGATOR_ */ diff --git a/nimble/host/audio/pkg.yml b/nimble/host/audio/pkg.yml index 66d418d311..5dd146166a 100644 --- a/nimble/host/audio/pkg.yml +++ b/nimble/host/audio/pkg.yml @@ -30,3 +30,12 @@ pkg.keywords: pkg.deps: - nimble - nimble/host + +pkg.deps.BLE_AUDIO_SCAN_DELEGATOR: + - nimble/host/audio/services/bass + +pkg.init.BLE_AUDIO_BROADCAST_SINK: + ble_audio_broadcast_sink_init: 'MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK_SYSINIT_STAGE)' + +pkg.init.BLE_AUDIO_SCAN_DELEGATOR: + ble_audio_scan_delegator_init: 'MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR_SYSINIT_STAGE)' diff --git a/nimble/host/audio/src/ble_audio.c b/nimble/host/audio/src/ble_audio.c index 4253347816..f601a07fb4 100644 --- a/nimble/host/audio/src/ble_audio.c +++ b/nimble/host/audio/src/ble_audio.c @@ -136,7 +136,9 @@ ble_audio_gap_event(struct ble_gap_event *gap_event, void *arg) { switch (gap_event->type) { case BLE_GAP_EVENT_EXT_DISC: { - struct ble_audio_adv_parse_broadcast_announcement_data data = { 0 }; + struct ble_audio_adv_parse_broadcast_announcement_data data = { + .success = false, + }; int rc; rc = ble_hs_adv_parse(gap_event->ext_disc.data, diff --git a/nimble/host/audio/src/ble_audio_broadcast_sink.c b/nimble/host/audio/src/ble_audio_broadcast_sink.c new file mode 100644 index 0000000000..8c2f05451d --- /dev/null +++ b/nimble/host/audio/src/ble_audio_broadcast_sink.c @@ -0,0 +1,1647 @@ +/* + * 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. + */ + +#include "sysinit/sysinit.h" + +#if MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK) +#include "stdlib.h" + +#include "audio/ble_audio.h" +#include "audio/ble_audio_broadcast_sink.h" +#include "audio/ble_audio_scan_delegator.h" +#include "host/ble_gap.h" +#include "host/ble_hs.h" +#include "host/ble_iso.h" +#include "host/ble_uuid.h" + +#include "ble_audio_priv.h" +#include "ble_audio_scan_delegator_priv.h" + +#define CLAMP(_n, _min, _max) (MAX(_min, MIN(_n, _max))) +#define BROADCAST_ID_INVALID 0xFFFFFFFF +#define BIS_INDEX_TEST(_bis_sync, _index) (((_bis_sync) & (1 << ((_index) - 1))) > 0) +#define BIS_INDEX_SET(_bis_sync, _index) ((_bis_sync) |= (1 << ((_index) - 1))) +#define BIS_INDEX_CLEAR(_bis_sync, _index) ((_bis_sync) &= ~(1 << ((_index) - 1))) + +static struct { + ble_audio_broadcast_sink_action_fn *fn; + void *arg; +} action_cb; + +enum pa_sync_state_internal { + PA_SYNC_STATE_IDLE, + PA_SYNC_STATE_PENDING_DISC, + PA_SYNC_STATE_PENDING_PAST, + PA_SYNC_STATE_PENDING_SYNC, + PA_SYNC_STATE_ACTIVE, + PA_SYNC_STATE_ERROR, + PA_SYNC_STATE_TIMEOUT, +}; + +enum big_sync_state_internal { + BIG_SYNC_STATE_IDLE, + BIG_SYNC_STATE_PENDING_BIG_INFO, + BIG_SYNC_STATE_PENDING_CODE, + BIG_SYNC_STATE_PENDING_BASE, + BIG_SYNC_STATE_PENDING_SYNC, + BIG_SYNC_STATE_FAILED, + BIG_SYNC_STATE_ACTIVE, +}; + +struct ble_audio_broadcast_sink { + /** Instance ID, same as BASS Source ID */ + uint8_t source_id; + + /** Internal PA sync state */ + enum pa_sync_state_internal pa_sync_state; + + /** Internal BIG sync state */ + enum big_sync_state_internal big_sync_state; + + /** Periodic sync handle */ + uint16_t pa_sync_handle; + + /** Connection handle or @ref BLE_HS_CONN_HANDLE_NONE */ + uint16_t past_conn_handle; + + /** BIG Handle */ + uint8_t big_handle; + + /** ISO Interval */ + uint16_t iso_interval; + + /** Burst Number */ + uint8_t bn; + + /** Number of SubEvents */ + uint8_t nse; + + /** Callback function */ + ble_audio_event_fn *cb; + + /** Broadcast code */ + uint8_t broadcast_code[BLE_AUDIO_BROADCAST_CODE_SIZE]; + + /** The optional argument to pass to the callback function. */ + void *cb_arg; + + /** BIG Sync Parameters */ + struct ble_audio_broadcast_sink_big_sync_params *big_sync_params; + + /** If true, the broadcast is encrypted and requires broadcast_code */ + uint8_t is_encrypted : 1; + /** If true, the broadcast_code value is valid */ + uint8_t broadcast_code_is_valid : 1; + + /** Internal subgroups state */ + uint8_t num_subgroups; + struct { + uint32_t bis_sync; + } subgroups[MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR_SUBGROUP_MAX)]; + + /** Singly-linked list entry. */ + SLIST_ENTRY(ble_audio_broadcast_sink) next; +}; + +static SLIST_HEAD(, ble_audio_broadcast_sink) ble_audio_broadcast_sink_list; +static struct os_mempool ble_audio_broadcast_sink_pool; +static os_membuf_t ble_audio_broadcast_sink_mem[ + OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK_MAX), + sizeof(struct ble_audio_broadcast_sink))]; + +/** If true, the discovery was started by us, otherwise by someone else */ +static bool disc_self_initiated; + +/** If true, the Periodic Advertising Sync is pending */ +static bool periodic_adv_sync_in_progress; + +static int gap_event_handler(struct ble_gap_event *event, void *arg); +static int iso_event_handler(struct ble_iso_event *event, void *arg); +static void big_sync_state_set(struct ble_audio_broadcast_sink *sink, enum big_sync_state_internal state_internal); +static void pa_sync_state_set(struct ble_audio_broadcast_sink *sink, enum pa_sync_state_internal state_internal); + +static struct ble_audio_broadcast_sink * +broadcast_sink_get(uint8_t source_id) +{ + struct ble_audio_broadcast_sink *sink; + + SLIST_FOREACH(sink, &ble_audio_broadcast_sink_list, next) { + if (source_id == sink->source_id) { + return sink; + } + } + + return NULL; +} + +static struct ble_audio_broadcast_sink * +broadcast_lookup_pa_sync_handle(uint16_t pa_sync_handle) +{ + struct ble_audio_broadcast_sink *sink; + + SLIST_FOREACH(sink, &ble_audio_broadcast_sink_list, next) { + if (pa_sync_handle == sink->pa_sync_handle) { + return sink; + } + } + + return NULL; +} + +static struct ble_audio_broadcast_sink * +broadcast_sink_lookup_adv_sid_broadcast_id_pair(uint8_t adv_sid, uint32_t broadcast_id) +{ + struct ble_audio_scan_delegator_source_desc source_desc; + struct ble_audio_broadcast_sink *sink; + int rc; + + SLIST_FOREACH(sink, &ble_audio_broadcast_sink_list, next) { + rc = ble_audio_scan_delegator_source_desc_get(sink->source_id, &source_desc); + if (rc != 0) { + BLE_HS_LOG_ERROR("source desc get failed (%d)\n", rc); + continue; + } + + if (source_desc.adv_sid == adv_sid && source_desc.broadcast_id == broadcast_id) { + return sink; + } + } + + return NULL; +} + +static struct ble_audio_broadcast_sink * +broadcast_sink_lookup_addr_adv_sid_pair(const ble_addr_t *addr, uint8_t adv_sid) +{ + struct ble_audio_scan_delegator_source_desc source_desc; + struct ble_audio_broadcast_sink *sink; + int rc; + + SLIST_FOREACH(sink, &ble_audio_broadcast_sink_list, next) { + rc = ble_audio_scan_delegator_source_desc_get(sink->source_id, &source_desc); + if (rc != 0) { + BLE_HS_LOG_ERROR("source desc get failed (%d)\n", rc); + continue; + } + + if (source_desc.adv_sid == adv_sid && ble_addr_cmp(&source_desc.addr, addr) == 0) { + return sink; + } + } + + return NULL; +} + +static struct ble_audio_broadcast_sink * +broadcast_sink_lookup_pa_sync_state(enum pa_sync_state_internal state_internal) +{ + struct ble_audio_broadcast_sink *sink; + + SLIST_FOREACH(sink, &ble_audio_broadcast_sink_list, next) { + if (sink->pa_sync_state == state_internal) { + return sink; + } + } + + return NULL; +} + +static int +disc_start(void) +{ + struct ble_audio_broadcast_sink_action action; + struct ble_gap_ext_disc_params disc_params; + int rc; + + if (ble_gap_disc_active()) { + return 0; + } + + disc_params.itvl = BLE_GAP_SCAN_FAST_INTERVAL_MIN; + disc_params.window = BLE_GAP_SCAN_FAST_WINDOW; + disc_params.passive = true; + + action.type = BLE_AUDIO_BROADCAST_SINK_ACTION_DISC_START; + action.disc_start.params_preferred = &disc_params; + + rc = action_cb.fn(&action, action_cb.arg); + if (rc != 0) { + BLE_HS_LOG_WARN("disc start rejected by user (%d)\n", rc); + } else { + disc_self_initiated = true; + } + + return rc; +} + +static void +disc_stop(void) +{ + struct ble_audio_broadcast_sink_action action; + int rc; + + if (!disc_self_initiated || !ble_gap_disc_active()) { + return; + } + + action.type = BLE_AUDIO_BROADCAST_SINK_ACTION_DISC_STOP; + + rc = action_cb.fn(&action, action_cb.arg); + if (rc != 0) { + BLE_HS_LOG_WARN("disc stop rejected by user (%d)\n", rc); + } + + disc_self_initiated = false; +} + +struct basic_audio_announcement_svc_data { + /** BASE length */ + uint8_t length; + + /** BASE */ + const uint8_t *base; +}; + +struct service_data_uuid16 { + struct basic_audio_announcement_svc_data basic_audio_announcement; +}; + +static void +service_data_uuid16_parse(const uint16_t uuid16, const uint8_t * const value, const uint8_t value_len, + void *user_data) +{ + struct service_data_uuid16 *data = user_data; + + if (uuid16 == BLE_BASIC_AUDIO_ANNOUNCEMENT_SVC_UUID) { + data->basic_audio_announcement.base = value; + data->basic_audio_announcement.length = value_len; + } +} + +struct periodic_report { + struct service_data_uuid16 uuid16; +}; + +static int +periodic_report_parse(const struct ble_hs_adv_field *field, void *user_data) +{ + struct periodic_report *report = user_data; + const uint8_t value_len = field->length - sizeof(field->length); + ble_uuid16_t uuid16 = BLE_UUID16_INIT(0); + uint8_t offset = 0; + + switch (field->type) { + case BLE_HS_ADV_TYPE_SVC_DATA_UUID16: + if (value_len < 2) { + break; + } + + uuid16.value = get_le16(&field->value[offset]); + offset += 2; + + service_data_uuid16_parse(uuid16.value, &field->value[offset], value_len - offset, &report->uuid16); + break; + + default: + /* Continue */ + return BLE_HS_ENOENT; + } + + /* Stop */ + return 0; +} + +static uint32_t +subgroup_bis_sync_get(struct ble_audio_broadcast_sink *sink, uint8_t subgroup_index) +{ + if (subgroup_index > sink->num_subgroups) { + return 0; + } + + return sink->subgroups[subgroup_index].bis_sync; +} + +static void +bass_big_state_update(struct ble_audio_broadcast_sink *sink, enum big_sync_state_internal from, + enum big_sync_state_internal to) +{ + struct ble_audio_scan_delegator_receive_state receive_state = {0}; + int rc; + + rc = ble_audio_scan_delegator_receive_state_get(sink->source_id, &receive_state); + if (rc != 0) { + BLE_HS_LOG_ERROR("receive state get failed (%d)\n", rc); + return; + } + + switch (to) { + case BIG_SYNC_STATE_PENDING_CODE: + receive_state.big_enc = BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_BROADCAST_CODE_MISSING; + break; + + case BIG_SYNC_STATE_IDLE: + if (from == BIG_SYNC_STATE_PENDING_CODE) { + /* FIXME: this does not seem to be right */ + receive_state.big_enc = BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_BROADCAST_CODE_INVALID; + memcpy(receive_state.bad_code, sink->broadcast_code, sizeof(receive_state.bad_code)); + } else if (from == BIG_SYNC_STATE_ACTIVE || from == BIG_SYNC_STATE_FAILED) { + /* Iterate subgroup indexes to update the BIS Sync state */ + for (uint8_t index = 0; index < receive_state.num_subgroups; index++) { + receive_state.subgroups[index].bis_sync = 0; + } + } + /* fallthrough */ + + case BIG_SYNC_STATE_PENDING_BIG_INFO: + case BIG_SYNC_STATE_PENDING_BASE: + case BIG_SYNC_STATE_PENDING_SYNC: + receive_state.big_enc = BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_NONE; + break; + + case BIG_SYNC_STATE_FAILED: + receive_state.big_enc = BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_NONE; + + /* BASS v1.0 3.1.1.4 Add Source operation + * "(...) if the server fails to synchronize to the BIG, the server shall write a value of + * 0xFFFFFFFF (Failed to synchronize to BIG) to the BIS_Sync_State field + */ + for (uint8_t index = 0; index < receive_state.num_subgroups; index++) { + receive_state.subgroups[index].bis_sync = BLE_AUDIO_SCAN_DELEGATOR_BIS_SYNC_ANY; + } + break; + + case BIG_SYNC_STATE_ACTIVE: + if (sink->is_encrypted) { + receive_state.big_enc = BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_DECRYPTING; + } else { + receive_state.big_enc = BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_NONE; + } + + /* Iterate subgroup indexes to update the BIS Sync state */ + for (uint8_t index = 0; index < receive_state.num_subgroups; index++) { + receive_state.subgroups[index].bis_sync = subgroup_bis_sync_get(sink, index); + } + break; + } + + rc = ble_audio_scan_delegator_receive_state_set(sink->source_id, &receive_state); + if (rc != 0) { + BLE_HS_LOG_ERROR("receive state update failed (%d)\n", rc); + } +} + +static enum ble_audio_broadcast_sink_sync_state +big_state_internal_to_api(enum big_sync_state_internal state_internal) +{ + switch (state_internal) { + case BIG_SYNC_STATE_PENDING_CODE: + case BIG_SYNC_STATE_PENDING_BIG_INFO: + case BIG_SYNC_STATE_PENDING_BASE: + case BIG_SYNC_STATE_PENDING_SYNC: + return BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_INITIATED; + + case BIG_SYNC_STATE_ACTIVE: + return BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_ESTABLISHED; + + default: + return BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_NOT_SYNCED; + } +} + +static void +api_bis_state_update(struct ble_audio_broadcast_sink *sink, enum big_sync_state_internal from, + enum big_sync_state_internal to) +{ + struct ble_audio_event event; + + if (to == BIG_SYNC_STATE_ACTIVE) { + /* special case. event already sent from big_sync_established_handler() */ + return; + } + + event.type = BLE_AUDIO_EVENT_BROADCAST_SINK_BIS_SYNC_STATE; + event.broadcast_sink_bis_sync_state.source_id = sink->source_id; + event.broadcast_sink_bis_sync_state.state = big_state_internal_to_api(to); + event.broadcast_sink_bis_sync_state.conn_handle = BLE_HS_CONN_HANDLE_NONE; + + for (uint8_t subgroup_index = 0; subgroup_index < sink->num_subgroups; subgroup_index++) { + uint32_t bis_sync = sink->subgroups[subgroup_index].bis_sync; + + if (bis_sync != BLE_AUDIO_SCAN_DELEGATOR_BIS_SYNC_ANY) { + for (uint8_t bis_index = 0; bis_sync > 0; bis_index++) { + if (BIS_INDEX_TEST(bis_sync, bis_index)) { + event.broadcast_sink_bis_sync_state.bis_index = bis_index; + ble_audio_event_listener_call(&event); + BIS_INDEX_CLEAR(bis_sync, bis_index); + } + } + } + } +} + +static void +big_sync_state_set(struct ble_audio_broadcast_sink *sink, enum big_sync_state_internal state_internal) +{ + enum big_sync_state_internal state_internal_old = sink->big_sync_state; + + if (state_internal == state_internal_old) { + return; + } + + sink->big_sync_state = state_internal; + + api_bis_state_update(sink, state_internal_old, state_internal); + bass_big_state_update(sink, state_internal_old, state_internal); +} + +static void +bass_pa_state_update(struct ble_audio_broadcast_sink *sink, enum pa_sync_state_internal from, + enum pa_sync_state_internal to) +{ + struct ble_audio_scan_delegator_receive_state receive_state; + int rc; + + rc = ble_audio_scan_delegator_receive_state_get(sink->source_id, &receive_state); + if (rc != 0) { + BLE_HS_LOG_ERROR("receive state get failed (%d)\n", rc); + return; + } + + switch (to) { + case PA_SYNC_STATE_IDLE: + case PA_SYNC_STATE_PENDING_DISC: + case PA_SYNC_STATE_PENDING_SYNC: + receive_state.pa_sync_state = BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_NOT_SYNCED; + break; + + case PA_SYNC_STATE_PENDING_PAST: + receive_state.pa_sync_state = BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_SYNC_INFO_REQ; + break; + + case PA_SYNC_STATE_ACTIVE: + receive_state.pa_sync_state = BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_SYNCED; + break; + + case PA_SYNC_STATE_ERROR: + receive_state.pa_sync_state = BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_ERROR; + break; + + case PA_SYNC_STATE_TIMEOUT: + if (from == PA_SYNC_STATE_PENDING_PAST) { + receive_state.pa_sync_state = BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_NO_PAST; + } else { + receive_state.pa_sync_state = BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_ERROR; + } + break; + } + + rc = ble_audio_scan_delegator_receive_state_set(sink->source_id, &receive_state); + if (rc != 0) { + BLE_HS_LOG_ERROR("receive state set failed (%d)\n", rc); + } +} + +static enum ble_audio_broadcast_sink_sync_state +pa_state_internal_to_api(enum pa_sync_state_internal state_internal) +{ + switch (state_internal) { + case PA_SYNC_STATE_PENDING_DISC: + case PA_SYNC_STATE_PENDING_SYNC: + case PA_SYNC_STATE_PENDING_PAST: + return BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_INITIATED; + + case PA_SYNC_STATE_ACTIVE: + return BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_ESTABLISHED; + + default: + return BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_NOT_SYNCED; + } +} + +static void +api_pa_state_update(struct ble_audio_broadcast_sink *sink, enum pa_sync_state_internal from, + enum pa_sync_state_internal to) +{ + struct ble_audio_event event; + + event.type = BLE_AUDIO_EVENT_BROADCAST_SINK_PA_SYNC_STATE; + event.broadcast_sink_pa_sync_state.source_id = sink->source_id; + event.broadcast_sink_pa_sync_state.state = pa_state_internal_to_api(to); + + if (event.broadcast_sink_pa_sync_state.state != pa_state_internal_to_api(from)) { + ble_audio_event_listener_call(&event); + } +} + +static void +pa_sync_state_set(struct ble_audio_broadcast_sink *sink, enum pa_sync_state_internal state_internal) +{ + enum pa_sync_state_internal state_internal_old = sink->pa_sync_state; + + if (state_internal == state_internal_old) { + return; + } + + sink->pa_sync_state = state_internal; + api_pa_state_update(sink, state_internal_old, state_internal); + bass_pa_state_update(sink, state_internal_old, state_internal); +} + +static uint32_t +group_bis_sync_get(struct ble_audio_broadcast_sink *sink) +{ + uint32_t bis_sync_flat = 0; + + for (uint8_t subgroup_index = 0; subgroup_index < sink->num_subgroups; subgroup_index++) { + bis_sync_flat |= sink->subgroups[subgroup_index].bis_sync; + } + + return bis_sync_flat; +} + +static void +pa_sync_create(void) +{ + struct ble_gap_periodic_sync_params periodic_sync_params = {0}; + struct ble_audio_broadcast_sink_action action; + int rc; + + if (periodic_adv_sync_in_progress) { + return; + } + + action.type = BLE_AUDIO_BROADCAST_SINK_ACTION_PA_SYNC; + action.pa_sync.out_params = &periodic_sync_params; + + rc = action_cb.fn(&action, action_cb.arg); + if (rc != 0) { + BLE_HS_LOG_WARN("rejected by user (%d)\n", rc); + return; + } + + rc = ble_gap_periodic_adv_sync_create(NULL, 0, &periodic_sync_params, + gap_event_handler, NULL); + if (rc != 0) { + BLE_HS_LOG_ERROR("adv sync create failed (%d)\n", rc); + } else { + periodic_adv_sync_in_progress = true; + } +} + +static void +big_sync_established_handler(uint8_t source_id, uint8_t status, const struct ble_iso_big_desc *desc) +{ + struct ble_audio_broadcast_sink *sink; + uint32_t bis_sync_state = 0; + uint32_t group_bis_sync; + uint8_t bis_index; + + /* Restart scan if needed */ + if (broadcast_sink_lookup_pa_sync_state(PA_SYNC_STATE_PENDING_SYNC) != NULL) { + pa_sync_create(); + disc_start(); + } else if (broadcast_sink_lookup_pa_sync_state(PA_SYNC_STATE_PENDING_DISC) != NULL) { + disc_start(); + } + + sink = broadcast_sink_get(source_id); + if (sink == NULL) { + BLE_HS_LOG_DEBUG("Unknown source_id %u\n", source_id); + return; + } + + if (status != 0) { + big_sync_state_set(sink, BIG_SYNC_STATE_FAILED); + return; + } + + bis_index = 0; + group_bis_sync = group_bis_sync_get(sink); + + for (uint8_t i = 0; i < desc->num_bis; i++) { + uint16_t conn_handle = desc->conn_handle[i]; + + for (; group_bis_sync > 0; bis_index++) { + if (BIS_INDEX_TEST(group_bis_sync, bis_index)) { + struct ble_audio_event event; + + event.type = BLE_AUDIO_EVENT_BROADCAST_SINK_BIS_SYNC_STATE; + event.broadcast_sink_bis_sync_state.source_id = sink->source_id; + event.broadcast_sink_bis_sync_state.bis_index = bis_index; + event.broadcast_sink_bis_sync_state.state = BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_ESTABLISHED; + event.broadcast_sink_bis_sync_state.conn_handle = conn_handle; + + ble_audio_event_listener_call(&event); + + BIS_INDEX_SET(bis_sync_state, bis_index); + BIS_INDEX_CLEAR(group_bis_sync, bis_index); + break; + } + } + } + + /* Check whether all BISes got conn handle */ + group_bis_sync = group_bis_sync_get(sink); + if (bis_sync_state != group_bis_sync) { + BLE_HS_LOG_WARN("not all BISes synced"); + + for (uint8_t subgroup_index = 0; subgroup_index < sink->num_subgroups; subgroup_index++) { + uint32_t bis_sync_missing; + + bis_sync_missing = sink->subgroups[subgroup_index].bis_sync & ~bis_sync_state; + if (bis_sync_missing == 0) { + continue; + } + + for (bis_index = 0; bis_sync_missing > 0; bis_index++) { + if (BIS_INDEX_TEST(bis_sync_missing, bis_index)) { + struct ble_audio_event event; + + event.type = BLE_AUDIO_EVENT_BROADCAST_SINK_BIS_SYNC_STATE; + event.broadcast_sink_bis_sync_state.source_id = sink->source_id; + event.broadcast_sink_bis_sync_state.bis_index = bis_index; + event.broadcast_sink_bis_sync_state.state = BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_NOT_SYNCED; + event.broadcast_sink_bis_sync_state.conn_handle = BLE_HS_CONN_HANDLE_NONE; + + ble_audio_event_listener_call(&event); + + BIS_INDEX_CLEAR(bis_sync_missing, bis_index); + } + } + + sink->subgroups[subgroup_index].bis_sync &= bis_sync_state; + } + } + + big_sync_state_set(sink, BIG_SYNC_STATE_ACTIVE); +} + +static void +big_sync_terminated_handler(uint8_t source_id, uint8_t reason) +{ + struct ble_audio_broadcast_sink *sink; + + sink = broadcast_sink_get(source_id); + if (sink == NULL) { + BLE_HS_LOG_DEBUG("Unknown source_id %u\n", source_id); + return; + } + + big_sync_state_set(sink, BIG_SYNC_STATE_IDLE); +} + +static int +iso_event_handler(struct ble_iso_event *event, void *arg) +{ + switch (event->type) { + case BLE_ISO_EVENT_BIG_SYNC_ESTABLISHED: + big_sync_established_handler(POINTER_TO_UINT(arg), event->big_sync_established.status, + &event->big_sync_established.desc); + break; + + case BLE_ISO_EVENT_BIG_SYNC_TERMINATED: + big_sync_terminated_handler(POINTER_TO_UINT(arg), event->big_terminated.reason); + break; + + default: + break; + } + + return 0; +} + +static int +pa_sync_create_cancel(void) +{ + int rc; + + if (!periodic_adv_sync_in_progress) { + return 0; + } + + rc = ble_gap_periodic_adv_sync_create_cancel(); + if (rc != 0) { + BLE_HS_LOG_ERROR("adv sync create cancel failed (%d)\n", rc); + } else { + periodic_adv_sync_in_progress = false; + } + + return rc; +} + +static int +pa_sync_add(const ble_addr_t *addr, uint8_t adv_sid) +{ + int rc; + + if (periodic_adv_sync_in_progress) { + rc = pa_sync_create_cancel(); + if (rc != 0) { + return rc; + } + } + + rc = ble_gap_add_dev_to_periodic_adv_list(addr, adv_sid); + if (rc != 0) { + BLE_HS_LOG_ERROR("add dev to periodic adv list failed (%d)\n", rc); + /* TODO: destroy sink */ + return rc; + } + + (void)pa_sync_create(); + + return rc; +} + +static int +pa_sync_remove(const ble_addr_t *addr, uint8_t adv_sid) +{ + int rc; + + if (periodic_adv_sync_in_progress) { + rc = pa_sync_create_cancel(); + if (rc != 0) { + return rc; + } + } + + rc = ble_gap_rem_dev_from_periodic_adv_list(addr, adv_sid); + if (rc != 0) { + BLE_HS_LOG_ERROR("rem dev from periodic adv list failed (%d)\n", rc); + } + + return rc; +} + +static void +periodic_sync_handler(const ble_addr_t *addr, uint8_t adv_sid, uint8_t status, uint16_t pa_sync_handle) +{ + struct ble_audio_broadcast_sink *sink; + + periodic_adv_sync_in_progress = false; + + sink = broadcast_sink_lookup_addr_adv_sid_pair(addr, adv_sid); + if (sink == NULL) { + BLE_HS_LOG_DEBUG("sink not found\n"); + } else { + (void)pa_sync_remove(addr, adv_sid); + + if (status == BLE_ERR_SUCCESS) { + sink->pa_sync_handle = pa_sync_handle; + pa_sync_state_set(sink, PA_SYNC_STATE_ACTIVE); + } else if (status == BLE_ERR_OPERATION_CANCELLED) { + pa_sync_state_set(sink, PA_SYNC_STATE_IDLE); + } else if (status == BLE_ERR_CONN_ESTABLISHMENT) { + pa_sync_state_set(sink, PA_SYNC_STATE_TIMEOUT); + } else { + pa_sync_state_set(sink, PA_SYNC_STATE_ERROR); + } + } + + sink = broadcast_sink_lookup_pa_sync_state(PA_SYNC_STATE_PENDING_SYNC); + if (sink != NULL) { + pa_sync_create(); + disc_start(); + } else { + disc_stop(); + } +} + +static void +periodic_sync_lost_handler(uint16_t sync_handle, int reason) +{ + struct ble_audio_broadcast_sink *sink; + + sink = broadcast_lookup_pa_sync_handle(sync_handle); + if (sink == NULL) { + BLE_HS_LOG_DEBUG("Unknown sync_handle %u\n", sync_handle); + return; + } + + if (reason == BLE_HS_EDONE) { + pa_sync_state_set(sink, PA_SYNC_STATE_IDLE); + } else if (reason == BLE_HS_ETIMEOUT) { + pa_sync_state_set(sink, PA_SYNC_STATE_TIMEOUT); + } else { + pa_sync_state_set(sink, PA_SYNC_STATE_ERROR); + } +} + +static void +biginfo_report_handler(uint16_t pa_sync_handle, uint16_t iso_interval, uint8_t nse, uint8_t bn, uint8_t encryption) +{ + struct ble_audio_broadcast_sink *sink; + + sink = broadcast_lookup_pa_sync_handle(pa_sync_handle); + if (sink == NULL) { + BLE_HS_LOG_DEBUG("Unknown pa_sync_handle %u\n", pa_sync_handle); + return; + } + + if (sink->big_sync_state == BIG_SYNC_STATE_PENDING_BIG_INFO) { + sink->is_encrypted = encryption; + sink->iso_interval = iso_interval; + sink->nse = nse; + sink->bn = bn; + + if (sink->is_encrypted && !sink->broadcast_code_is_valid) { + big_sync_state_set(sink, BIG_SYNC_STATE_PENDING_CODE); + } else { + big_sync_state_set(sink, BIG_SYNC_STATE_PENDING_BASE); + } + } +} + +static int +bis_params_get(struct ble_audio_broadcast_sink *sink, struct ble_audio_base_group *group, + struct ble_audio_base_iter *subgroup_iter, + struct ble_iso_bis_params bis_params[MYNEWT_VAL(BLE_ISO_MAX_BISES)], uint8_t *out_bis_cnt) +{ + uint8_t subgroup_index; + uint32_t group_bis_sync = 0; + uint8_t bis_cnt = 0; + int rc = 0; + + if (action_cb.fn == NULL) { + BLE_HS_LOG_ERROR("action_cb.fn is NULL\n"); + return BLE_HS_EAPP; + } + + for (subgroup_index = 0; subgroup_index < group->num_subgroups; subgroup_index++) { + struct ble_audio_base_subgroup subgroup; + struct ble_audio_base_iter bis_iter; + uint32_t subgroup_bis_sync_req; + + rc = ble_audio_base_subgroup_iter(subgroup_iter, &subgroup, &bis_iter); + if (rc != 0) { + break; + } + + subgroup_bis_sync_req = subgroup_bis_sync_get(sink, subgroup_index); + if (subgroup_bis_sync_req == 0) { + /* No BISes requested for this subgroup */ + continue; + } + + sink->subgroups[subgroup_index].bis_sync = 0; + + for (uint8_t i = 0; i < subgroup.num_bis && bis_cnt < MYNEWT_VAL(BLE_ISO_MAX_BISES); i++) { + struct ble_audio_broadcast_sink_action action = {0}; + struct ble_audio_base_bis bis; + + rc = ble_audio_base_bis_iter(&bis_iter, &bis); + if (rc != 0) { + break; + } + + /* Core 5.4 | Vol 4, Part E; 7.8.106 LE BIG Create Sync command + * BIS[i]: 0x01 to 0x1F + */ + if (bis.index < 0x01 || bis.index > 0x7F) { + continue; + } + + if (BIS_INDEX_TEST(group_bis_sync, bis.index)) { + /* BAP_v1.0.1; 3.7.2.2 Basic Audio Announcements + * + * Rule 3: Every BIS in the BIG, denoted by its BIS_index value, + * shall only be present in one subgroup. + */ + BLE_HS_LOG_WARN("duplicated bis index 0x%02x", bis.index); + continue; + } + + if (!BIS_INDEX_TEST(subgroup_bis_sync_req, bis.index)) { + continue; + } + + action.type = BLE_AUDIO_BROADCAST_SINK_ACTION_BIS_SYNC; + action.bis_sync.source_id = sink->source_id; + action.bis_sync.subgroup_index = subgroup_index; + action.bis_sync.bis = &bis; + action.bis_sync.subgroup = &subgroup; + + rc = action_cb.fn(&action, action_cb.arg); + if (rc != 0) { + BLE_HS_LOG_WARN("bis sync rejected by user (%d)\n", rc); + } else { + BIS_INDEX_SET(sink->subgroups[subgroup_index].bis_sync, bis.index); + bis_params[bis_cnt].bis_index = bis.index; + bis_cnt++; + } + } + + group_bis_sync |= sink->subgroups[subgroup_index].bis_sync; + } + + sink->num_subgroups = subgroup_index; + + *out_bis_cnt = bis_cnt; + return rc; +} + +static int +bis_params_bis_index_cmp(const void *p1, const void *p2) +{ + const struct ble_iso_bis_params *bis_params_1 = p1; + const struct ble_iso_bis_params *bis_params_2 = p2; + + return bis_params_1->bis_index - bis_params_2->bis_index; +} + +static void +big_sync(struct ble_audio_broadcast_sink *sink, const uint8_t *base, uint8_t base_len) +{ + struct ble_audio_broadcast_sink_action action; + struct ble_audio_base_group group; + struct ble_audio_base_iter subgroup_iter; + struct ble_iso_big_sync_create_params big_sync_create_params; + struct ble_iso_bis_params bis_params[MYNEWT_VAL(BLE_ISO_MAX_BISES)]; + char broadcast_code[BLE_AUDIO_BROADCAST_CODE_SIZE + 1]; + uint8_t bis_cnt = 0; + int rc; + + rc = ble_audio_base_parse(base, base_len, &group, &subgroup_iter); + if (rc != 0) { + BLE_HS_LOG_ERROR("base parse failed (%d)\n", rc); + ble_audio_broadcast_sink_stop(sink->source_id); + return; + } + + /* By default, the controller can schedule reception of any number of subevents up to NSE */ + big_sync_create_params.mse = 0x00; + + /* By default, (6 * ISO_Interval * 1.25) / 10 = 3/4 * ISO_Interval */ + big_sync_create_params.sync_timeout = (uint16_t)((3.0 * sink->iso_interval) / 4.0); + big_sync_create_params.sync_timeout = CLAMP(big_sync_create_params.sync_timeout, 0x000A, 0x4000); + + action.type = BLE_AUDIO_BROADCAST_SINK_ACTION_BIG_SYNC; + action.big_sync.source_id = sink->source_id; + action.big_sync.iso_interval = sink->iso_interval; + action.big_sync.nse = sink->nse; + action.big_sync.bn = sink->bn; + action.big_sync.presentation_delay = group.presentation_delay; + action.big_sync.out_mse = &big_sync_create_params.mse; + action.big_sync.out_sync_timeout = &big_sync_create_params.sync_timeout; + + if (action_cb.fn == NULL) { + BLE_HS_LOG_ERROR("action_cb.fn is NULL\n"); + ble_audio_broadcast_sink_stop(sink->source_id); + return; + } + + rc = action_cb.fn(&action, action_cb.arg); + if (rc != 0) { + BLE_HS_LOG_WARN("big sync rejected by user (%d)\n", rc); + ble_audio_broadcast_sink_stop(sink->source_id); + return; + } + + if (sink->broadcast_code_is_valid) { + memcpy(broadcast_code, sink->broadcast_code, BLE_AUDIO_BROADCAST_CODE_SIZE); + broadcast_code[BLE_AUDIO_BROADCAST_CODE_SIZE] = '\0'; + big_sync_create_params.broadcast_code = broadcast_code; + } else { + big_sync_create_params.broadcast_code = NULL; + } + + big_sync_create_params.sync_handle = sink->pa_sync_handle; + big_sync_create_params.cb = iso_event_handler; + big_sync_create_params.cb_arg = UINT_TO_POINTER(sink->source_id); + big_sync_create_params.bis_params = bis_params; + + rc = bis_params_get(sink, &group, &subgroup_iter, bis_params, &bis_cnt); + if (rc != 0 || bis_cnt == 0) { + ble_audio_broadcast_sink_stop(sink->source_id); + return; + } + + /* Sort the parameters by BIS index in ascending order. It is required to properly match the + * BIS index with conn handle in BIG Sync Established event handler. + */ + qsort(bis_params, bis_cnt, sizeof(*bis_params), bis_params_bis_index_cmp); + + big_sync_create_params.bis_cnt = bis_cnt; + + /* Stop scan first */ + disc_stop(); + + rc = ble_iso_big_sync_create(&big_sync_create_params, &sink->big_handle); + if (rc != 0) { + BLE_HS_LOG_ERROR("big sync failed (%d)\n", rc); + return; + } + + big_sync_state_set(sink, BIG_SYNC_STATE_PENDING_SYNC); +} + +static void +metadata_update(struct ble_audio_broadcast_sink *sink, const uint8_t *base, uint8_t base_len) +{ + struct ble_audio_event event; + struct ble_audio_base_group group; + struct ble_audio_base_iter subgroup_iter; + int rc = 0; + + rc = ble_audio_base_parse(base, base_len, &group, &subgroup_iter); + if (rc != 0) { + BLE_HS_LOG_WARN("base parse failed (%d)\n", rc); + return; + } + + for (uint8_t subgroup_index = 0; subgroup_index < group.num_subgroups; subgroup_index++) { + struct ble_audio_base_subgroup subgroup; + uint32_t bis_sync_state; + + rc = ble_audio_base_subgroup_iter(&subgroup_iter, &subgroup, NULL); + if (rc != 0) { + break; + } + + bis_sync_state = subgroup_bis_sync_get(sink, subgroup_index); + if (bis_sync_state == 0) { + /* No BISes synced for this subgroup */ + continue; + } + + event.type = BLE_AUDIO_EVENT_BROADCAST_SINK_METADATA; + event.broadcast_sink_metadata.source_id = sink->source_id; + event.broadcast_sink_metadata.bis_sync = bis_sync_state; + event.broadcast_sink_metadata.metadata = subgroup.metadata; + event.broadcast_sink_metadata.metadata_length = subgroup.metadata_len; + + /* TODO: filter duplicates */ + + ble_audio_event_listener_call(&event); + } +} + +static void +periodic_report_handler(uint16_t pa_sync_handle, const uint8_t *data, uint8_t data_length, uint8_t data_status, + int8_t rssi, int8_t tx_power) +{ + struct ble_audio_broadcast_sink *sink; + struct periodic_report report = {0}; + int rc; + + if (data_status != BLE_HCI_PERIODIC_DATA_STATUS_COMPLETE) { + return; + } + + sink = broadcast_lookup_pa_sync_handle(pa_sync_handle); + if (sink == NULL) { + BLE_HS_LOG_DEBUG("Unknown pa_sync_handle %u\n", pa_sync_handle); + return; + } + + if (sink->big_sync_state == BIG_SYNC_STATE_PENDING_BASE) { + rc = ble_hs_adv_parse(data, data_length, periodic_report_parse, &report); + if (rc != 0 || report.uuid16.basic_audio_announcement.length == 0) { + BLE_HS_LOG_WARN("source_id %u incorrectly formatted BASE\n", sink->source_id); + ble_audio_broadcast_sink_stop(sink->source_id); + return; + } + + big_sync(sink, report.uuid16.basic_audio_announcement.base, report.uuid16.basic_audio_announcement.length); + } else if (sink->big_sync_state == BIG_SYNC_STATE_ACTIVE) { + rc = ble_hs_adv_parse(data, data_length, periodic_report_parse, &report); + if (rc != 0 || report.uuid16.basic_audio_announcement.length == 0) { + BLE_HS_LOG_WARN("source_id %u incorrectly formatted BASE\n", sink->source_id); + return; + } + + metadata_update(sink, report.uuid16.basic_audio_announcement.base, + report.uuid16.basic_audio_announcement.length); + } +} + +static int +broadcast_id_parse_from_adv(const struct ble_hs_adv_field *field, void *user_data) +{ + const uint8_t value_len = field->length - sizeof(field->length); + uint32_t *broadcast_id = user_data; + + if (field->type == BLE_HS_ADV_TYPE_SVC_DATA_UUID16) { + ble_uuid16_t uuid16 = BLE_UUID16_INIT(0); + uint8_t offset = 0; + + if (value_len < 2) { + /* Continue parsing */ + return BLE_HS_ENOENT; + } + + uuid16.value = get_le16(&field->value[offset]); + offset += 2; + + if (uuid16.value == BLE_BROADCAST_AUDIO_ANNOUNCEMENT_SVC_UUID) { + if ((value_len - offset) >= 3) { + *broadcast_id = get_le24(&field->value[offset]); + } + + /* stop parsing */ + return 0; + } + } + + /* continue parsing */ + return BLE_HS_ENOENT; +} + +static void +ext_disc_handler(const ble_addr_t *addr, uint8_t adv_sid, const uint8_t *data, uint8_t data_length) +{ + uint32_t broadcast_id = BROADCAST_ID_INVALID; + struct ble_audio_broadcast_sink *sink; + int rc; + + if (broadcast_sink_lookup_pa_sync_state(PA_SYNC_STATE_PENDING_DISC) == NULL) { + return; + } + + rc = ble_hs_adv_parse(data, data_length, broadcast_id_parse_from_adv, &broadcast_id); + if (rc != 0 || broadcast_id == BROADCAST_ID_INVALID) { + return; + } + + sink = broadcast_sink_lookup_adv_sid_broadcast_id_pair(adv_sid, broadcast_id); + if (sink == NULL) { + return; + } + + if (sink->pa_sync_state == PA_SYNC_STATE_PENDING_DISC) { + rc = pa_sync_add(addr, adv_sid); + if (rc != 0) { + /* TODO: */ + } else { + pa_sync_state_set(sink, PA_SYNC_STATE_PENDING_SYNC); + } + } +} + +static int +gap_event_handler(struct ble_gap_event *event, void *arg) +{ + switch (event->type) { + case BLE_GAP_EVENT_PERIODIC_SYNC: + periodic_sync_handler(&event->periodic_sync.adv_addr, event->periodic_sync.sid, + event->periodic_sync.status, event->periodic_sync.sync_handle); + break; + + case BLE_GAP_EVENT_PERIODIC_SYNC_LOST: + periodic_sync_lost_handler(event->periodic_sync_lost.sync_handle, event->periodic_sync_lost.reason); + break; + + case BLE_GAP_EVENT_PERIODIC_TRANSFER: + periodic_sync_handler(&event->periodic_transfer.adv_addr, event->periodic_transfer.sid, + event->periodic_transfer.status, event->periodic_transfer.sync_handle); + break; + + case BLE_GAP_EVENT_BIGINFO_REPORT: + biginfo_report_handler(event->biginfo_report.sync_handle, event->biginfo_report.iso_interval, + event->biginfo_report.nse, event->biginfo_report.bn, event->biginfo_report.encryption); + + break; + + case BLE_GAP_EVENT_PERIODIC_REPORT: + periodic_report_handler(event->periodic_report.sync_handle, event->periodic_report.data, + event->periodic_report.data_length, + event->periodic_report.data_status, event->periodic_report.rssi, + event->periodic_report.tx_power); + break; + + case BLE_GAP_EVENT_EXT_DISC: + ext_disc_handler(&event->ext_disc.addr, event->ext_disc.sid, event->ext_disc.data, + event->ext_disc.length_data); + break; + + default: + break; + } + + return 0; +} + +int +ble_audio_broadcast_sink_cb_set(ble_audio_broadcast_sink_action_fn *cb, void *arg) +{ + if (action_cb.fn != NULL) { + return BLE_HS_EALREADY; + } + + action_cb.fn = cb; + action_cb.arg = arg; + + return 0; +} + +void +ble_audio_broadcast_sink_code_set(uint8_t source_id, const uint8_t broadcast_code[BLE_AUDIO_BROADCAST_CODE_SIZE]) +{ + struct ble_audio_broadcast_sink *sink; + + BLE_AUDIO_DBG_ASSERT(broadcast_code != NULL); + + sink = broadcast_sink_get(source_id); + if (sink == NULL) { + BLE_HS_LOG_DEBUG("Unknown source_id %u\n", source_id); + return; + } + + if (sink->big_sync_state == BIG_SYNC_STATE_PENDING_CODE) { + memcpy(sink->broadcast_code, broadcast_code, BLE_AUDIO_BROADCAST_CODE_SIZE); + + big_sync_state_set(sink, BIG_SYNC_STATE_PENDING_BASE); + } +} + +static struct ble_audio_broadcast_sink * +broadcast_sink_new(uint8_t source_id) +{ + struct ble_audio_broadcast_sink *sink; + + sink = os_memblock_get(&ble_audio_broadcast_sink_pool); + if (sink == NULL) { + BLE_HS_LOG_WARN("Out of memory\n"); + return NULL; + } + + memset(sink, 0, sizeof(*sink)); + + sink->source_id = source_id; + + SLIST_INSERT_HEAD(&ble_audio_broadcast_sink_list, sink, next); + + return sink; +} + +static int +pa_sync_receive(struct ble_audio_broadcast_sink *sink, const uint16_t *conn_handle) +{ + struct ble_audio_broadcast_sink_action action; + struct ble_audio_scan_delegator_source_desc source_desc; + struct ble_gap_periodic_sync_params periodic_sync_params = {0}; + int rc; + + rc = ble_audio_scan_delegator_source_desc_get(sink->source_id, &source_desc); + if (rc != 0) { + BLE_HS_LOG_ERROR("source desc get failed (%d)\n", rc); + return rc; + } + + if (action_cb.fn == NULL) { + BLE_HS_LOG_ERROR("action_cb.fn is NULL\n"); + return BLE_HS_EAPP; + } + + action.type = BLE_AUDIO_BROADCAST_SINK_ACTION_PA_SYNC; + action.pa_sync.out_params = &periodic_sync_params; + + rc = action_cb.fn(&action, action_cb.arg); + if (rc != 0) { + BLE_HS_LOG_WARN("pa sync rejected by user (%d)\n", rc); + return rc; + } + + rc = ble_gap_periodic_adv_sync_receive( + *conn_handle, &periodic_sync_params, gap_event_handler, NULL); + if (rc != 0) { + BLE_HS_LOG_ERROR("sync receive failed (%d)\n", rc); + return rc; + } + + return 0; +} + +static int +broadcast_sink_start(uint8_t source_id, const uint8_t *broadcast_code, uint16_t *conn_handle) +{ + struct ble_audio_scan_delegator_source_desc source_desc; + struct ble_audio_broadcast_sink *sink; + int rc; + + rc = ble_audio_scan_delegator_source_desc_get(source_id, &source_desc); + if (rc != 0) { + BLE_HS_LOG_ERROR("source desc get failed (%d)\n", rc); + return rc; + } + + sink = broadcast_sink_get(source_id); + if (sink == NULL) { + sink = broadcast_sink_new(source_id); + if (sink == NULL) { + return BLE_HS_ENOMEM; + } + } + + if (broadcast_code != NULL) { + memcpy(sink->broadcast_code, broadcast_code, BLE_AUDIO_BROADCAST_CODE_SIZE); + sink->broadcast_code_is_valid = true; + } + + /* If not previously set, let the application decide which BISes to sync */ + if (sink->num_subgroups == 0) { + sink->num_subgroups = ARRAY_SIZE(sink->subgroups); + for (uint8_t i = 0; i < sink->num_subgroups; i++) { + sink->subgroups[i].bis_sync = BLE_AUDIO_SCAN_DELEGATOR_BIS_SYNC_ANY; + } + } + + switch (sink->pa_sync_state) { + case PA_SYNC_STATE_PENDING_PAST: + case PA_SYNC_STATE_PENDING_DISC: + case PA_SYNC_STATE_PENDING_SYNC: + case PA_SYNC_STATE_ACTIVE: + break; + + case PA_SYNC_STATE_IDLE: + case PA_SYNC_STATE_ERROR: + case PA_SYNC_STATE_TIMEOUT: + if (conn_handle != NULL) { + /* sync using PAST procedure */ + rc = pa_sync_receive(sink, conn_handle); + if (rc != 0) { + return rc; + } + pa_sync_state_set(sink, PA_SYNC_STATE_PENDING_PAST); + } else if (source_desc.addr.type == BLE_ADDR_PUBLIC) { + /* sync to public address (we don't need to scan, as the address won't change) */ + rc = pa_sync_add(&source_desc.addr, source_desc.adv_sid); + if (rc != 0) { + return rc; + } + pa_sync_state_set(sink, PA_SYNC_STATE_PENDING_SYNC); + } else { + /* scan to find broadcaster using Adv SID and Broadcast ID */ + rc = disc_start(); + if (rc != 0) { + return rc; + } + pa_sync_state_set(sink, PA_SYNC_STATE_PENDING_DISC); + } + break; + + default: + BLE_AUDIO_DBG_ASSERT(false); + ble_audio_broadcast_sink_stop(source_id); + return BLE_HS_EAGAIN; + } + + switch (sink->big_sync_state) { + case BIG_SYNC_STATE_ACTIVE: + case BIG_SYNC_STATE_PENDING_BIG_INFO: + case BIG_SYNC_STATE_PENDING_SYNC: + case BIG_SYNC_STATE_PENDING_BASE: + break; + + case BIG_SYNC_STATE_PENDING_CODE: + if (broadcast_code != NULL) { + big_sync_state_set(sink, BIG_SYNC_STATE_PENDING_BASE); + } + break; + + case BIG_SYNC_STATE_FAILED: + case BIG_SYNC_STATE_IDLE: + big_sync_state_set(sink, BIG_SYNC_STATE_PENDING_BIG_INFO); + break; + + default: + BLE_AUDIO_DBG_ASSERT(false); + ble_audio_broadcast_sink_stop(source_id); + return BLE_HS_EAGAIN; + } + + if (sink->pa_sync_state == PA_SYNC_STATE_ACTIVE && + sink->big_sync_state == BIG_SYNC_STATE_ACTIVE) { + return BLE_HS_EDONE; + } + + return 0; +} + +int +ble_audio_broadcast_sink_start(uint8_t source_id, const struct ble_audio_broadcast_sink_add_params *params) +{ + return broadcast_sink_start(source_id, + params->broadcast_code_is_valid ? params->broadcast_code : NULL, + NULL); +} + +static void +ble_audio_broadcast_sink_destroy(struct ble_audio_broadcast_sink *sink) +{ + os_error_t os_error; + + os_error = os_memblock_put(&ble_audio_broadcast_sink_pool, sink); + if (os_error != OS_OK) { + BLE_HS_LOG_ERROR("Failed to put memory block (os_error %d)\n", os_error); + return; + } + + SLIST_REMOVE(&ble_audio_broadcast_sink_list, sink, ble_audio_broadcast_sink, next); +} + +static int +pa_sync_term(struct ble_audio_broadcast_sink *sink) +{ + int rc; + + switch (sink->pa_sync_state) { + case PA_SYNC_STATE_ACTIVE: + rc = ble_gap_periodic_adv_sync_terminate(sink->pa_sync_handle); + if (rc != 0) { + BLE_HS_LOG_ERROR("adv sync terminate failed (%d)\n", rc); + return rc; + } + break; + + case PA_SYNC_STATE_PENDING_PAST: + rc = ble_gap_periodic_adv_sync_receive(sink->past_conn_handle, NULL, gap_event_handler, NULL); + if (rc != 0) { + BLE_HS_LOG_ERROR("adv sync receive cancel failed (%d)\n", rc); + return rc; + } + break; + + case PA_SYNC_STATE_PENDING_SYNC: { + struct ble_audio_scan_delegator_source_desc source_desc; + + rc = ble_audio_scan_delegator_source_desc_get(sink->source_id, &source_desc); + if (rc != 0) { + BLE_HS_LOG_ERROR("source desc get failed (%d)\n", rc); + return rc; + } + + rc = pa_sync_remove(&source_desc.addr, source_desc.adv_sid); + if (rc != 0) { + return rc; + } + break; + } + + default: + break; + } + + pa_sync_state_set(sink, PA_SYNC_STATE_IDLE); + + return 0; +} + +static int +big_sync_term(struct ble_audio_broadcast_sink *sink) +{ + int rc; + + switch (sink->big_sync_state) { + case BIG_SYNC_STATE_ACTIVE: + case BIG_SYNC_STATE_PENDING_SYNC: + rc = ble_iso_big_sync_terminate(sink->big_handle); + if (rc != 0) { + BLE_HS_LOG_ERROR("big sync terminate failed (%d)\n", rc); + return rc; + } + break; + + case BIG_SYNC_STATE_IDLE: + case BIG_SYNC_STATE_FAILED: + case BIG_SYNC_STATE_PENDING_CODE: + case BIG_SYNC_STATE_PENDING_BASE: + case BIG_SYNC_STATE_PENDING_BIG_INFO: + break; + } + + big_sync_state_set(sink, BIG_SYNC_STATE_IDLE); + + return 0; +} + +int +ble_audio_broadcast_sink_stop(uint8_t source_id) +{ + struct ble_audio_broadcast_sink *sink; + int rc; + + sink = broadcast_sink_get(source_id); + if (sink == NULL) { + BLE_HS_LOG_WARN("no sink with source_id=0x%02x\n", source_id); + return 0; + } + + rc = pa_sync_term(sink); + if (rc != 0) { + return rc; + } + + rc = big_sync_term(sink); + if (rc != 0) { + return rc; + } + + ble_audio_broadcast_sink_destroy(sink); + + return 0; +} + +int +ble_audio_broadcast_sink_metadata_update(uint8_t source_id, + const struct ble_audio_broadcast_sink_metadata_update_params *params) +{ + struct ble_audio_broadcast_sink *sink; + + sink = broadcast_sink_get(source_id); + if (sink == NULL) { + BLE_HS_LOG_WARN("no sink with source_id=0x%02x\n", source_id); + return 0; + } + + return ble_audio_scan_delegator_metadata_update(sink->source_id, params->subgroup_index, params->metadata, + params->metadata_length); +} + +int +ble_audio_broadcast_sink_config(uint8_t source_id, uint16_t conn_handle, + const struct ble_audio_scan_delegator_sync_opt *sync_opt) +{ + struct ble_audio_broadcast_sink *sink; + int rc; + + BLE_AUDIO_DBG_ASSERT(sync_opt != NULL); + + sink = broadcast_sink_get(source_id); + if (sink == NULL) { + if (sync_opt->pa_sync != BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_DO_NOT_SYNC) { + sink = broadcast_sink_new(source_id); + if (sink == NULL) { + return BLE_HS_ENOMEM; + } + } else { + /* nothing to do */ + return 0; + } + } + + if (sync_opt->pa_sync != BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_DO_NOT_SYNC) { + /* TODO: Skip if the BIS Sync is same */ + if (sink->num_subgroups != 0) { + rc = big_sync_term(sink); + if (rc != 0) { + return rc; + } + } + + sink->num_subgroups = sync_opt->num_subgroups; + + for (uint8_t subgroup_index = 0; subgroup_index < sink->num_subgroups; subgroup_index++) { + sink->subgroups[subgroup_index].bis_sync = sync_opt->subgroups[subgroup_index].bis_sync; + } + + if (sync_opt->pa_sync == BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_PAST_NOT_AVAILABLE) { + rc = broadcast_sink_start(source_id, NULL, NULL); + } else { + rc = broadcast_sink_start(source_id, NULL, &conn_handle); + } + } else { + rc = pa_sync_term(sink); + } + + return rc; +} + +int +ble_audio_broadcast_sink_init(void) +{ + static struct ble_gap_event_listener gap_event_listener; + int rc; + + /* Ensure this function only gets called by sysinit. */ + SYSINIT_ASSERT_ACTIVE(); + + rc = os_mempool_init(&ble_audio_broadcast_sink_pool, + MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK_MAX), + sizeof(struct ble_audio_broadcast_sink), + ble_audio_broadcast_sink_mem, + "ble_audio_broadcast_sink_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_gap_event_listener_register(&gap_event_listener, gap_event_handler, NULL); + SYSINIT_PANIC_ASSERT(rc == 0); + + return 0; +} +#endif /* BLE_AUDIO_BROADCAST_SINK */ diff --git a/nimble/host/audio/src/ble_audio_broadcast_sink_priv.h b/nimble/host/audio/src/ble_audio_broadcast_sink_priv.h new file mode 100644 index 0000000000..ad7990144d --- /dev/null +++ b/nimble/host/audio/src/ble_audio_broadcast_sink_priv.h @@ -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. + */ + +#ifndef H_BLE_AUDIO_BROADCAST_SINK_PRIV_ +#define H_BLE_AUDIO_BROADCAST_SINK_PRIV_ + +#include +#include "audio/ble_audio.h" +#include "audio/ble_audio_broadcast_sink.h" +#include "audio/ble_audio_scan_delegator.h" + +int ble_audio_broadcast_sink_config( + uint8_t source_id, uint16_t conn_handle, + const struct ble_audio_scan_delegator_sync_opt *sync_opt); +void ble_audio_broadcast_sink_code_set( + uint8_t source_id, const uint8_t broadcast_code[16]); + +#endif /* H_BLE_AUDIO_BROADCAST_SINK_PRIV_ */ diff --git a/nimble/host/audio/src/ble_audio_priv.h b/nimble/host/audio/src/ble_audio_priv.h index 10f0109ddc..d575c54969 100644 --- a/nimble/host/audio/src/ble_audio_priv.h +++ b/nimble/host/audio/src/ble_audio_priv.h @@ -22,6 +22,17 @@ #include "audio/ble_audio.h" +#define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) +#define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b)) + +#if MYNEWT_VAL(BLE_HS_DEBUG) +#define BLE_AUDIO_DBG_ASSERT(x) assert(x) +#define BLE_AUDIO_DBG_ASSERT_EVAL(x) assert(x) +#else +#define BLE_AUDIO_DBG_ASSERT(x) +#define BLE_AUDIO_DBG_ASSERT_EVAL(x) ((void)(x)) +#endif + int ble_audio_event_listener_call(struct ble_audio_event *event); #endif /* H_BLE_AUDIO_PRIV_ */ diff --git a/nimble/host/audio/src/ble_audio_scan_delegator.c b/nimble/host/audio/src/ble_audio_scan_delegator.c new file mode 100644 index 0000000000..db580c6398 --- /dev/null +++ b/nimble/host/audio/src/ble_audio_scan_delegator.c @@ -0,0 +1,460 @@ +/* + * 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. + */ + +#include "sysinit/sysinit.h" + +#if MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR) +#include "audio/ble_audio.h" +#include "audio/ble_audio_broadcast_sink.h" +#include "audio/ble_audio_scan_delegator.h" +#include "host/ble_hs.h" +#include "host/ble_uuid.h" + +#include "../services/bass/include/services/bass/ble_audio_svc_bass.h" + +#include "ble_audio_priv.h" +#include "ble_audio_broadcast_sink_priv.h" + +static ble_audio_scan_delegator_action_fn *action_cb; + +int +ble_audio_scan_delegator_source_desc_get(uint8_t source_id, struct ble_audio_scan_delegator_source_desc *source_desc) +{ + struct ble_svc_audio_bass_receiver_state *state; + int rc; + + rc = ble_svc_audio_bass_receiver_state_get(source_id, &state); + if (rc != 0) { + BLE_HS_LOG_ERROR("bass receiver state get failed (%d)\n", rc); + return rc; + } + + source_desc->addr = state->source_addr; + source_desc->adv_sid = state->source_adv_sid; + source_desc->broadcast_id = state->broadcast_id; + + return 0; +} + +int +ble_audio_scan_delegator_receive_state_get(uint8_t source_id, struct ble_audio_scan_delegator_receive_state *out_state) +{ + struct ble_svc_audio_bass_receiver_state *state; + int rc; + + rc = ble_svc_audio_bass_receiver_state_get(source_id, &state); + if (rc != 0) { + BLE_HS_LOG_ERROR("bass receiver state get failed (%d)\n", rc); + return rc; + } + + out_state->pa_sync_state = (uint8_t)state->pa_sync_state; + out_state->big_enc = (uint8_t)state->big_encryption; + if (out_state->big_enc == BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_BROADCAST_CODE_INVALID) { + memcpy(out_state->bad_code, state->bad_code, sizeof(out_state->bad_code)); + } + out_state->num_subgroups = state->num_subgroups; + for (uint8_t i = 0; i < out_state->num_subgroups; i++) { + out_state->subgroups[i].bis_sync = state->subgroups[i].bis_sync_state; + out_state->subgroups[i].metadata = state->subgroups[i].metadata; + out_state->subgroups[i].metadata_length = state->subgroups[i].metadata_length; + } + + return 0; +} + +int +ble_audio_scan_delegator_metadata_update(uint8_t source_id, uint8_t subgroup_index, const uint8_t *metadata, + uint8_t metadata_length) +{ + struct ble_svc_audio_bass_metadata_params params; + + params.subgroup_idx = subgroup_index; + params.metadata = metadata; + params.metadata_length = metadata_length; + + return ble_svc_audio_bass_update_metadata(¶ms, source_id); +} + +static int +action_call(struct ble_audio_scan_delegator_action *action, void *arg) +{ + int rc; + + if (action_cb == NULL) { + BLE_HS_LOG_ERROR("callback is NULL\n"); + return BLE_HS_EAPP; + } + + rc = action_cb(action, arg); + if (rc != 0) { + return rc; + } + + return 0; +} + +static void +source_desc_init(struct ble_audio_scan_delegator_source_desc *source_desc, const ble_addr_t *addr, uint8_t adv_sid, + uint32_t broadcast_id) +{ + source_desc->addr = *addr; + source_desc->adv_sid = adv_sid; + source_desc->broadcast_id = broadcast_id; +} + +static void +subgroups_init(struct ble_audio_scan_delegator_subgroup *subgroups, + const struct ble_svc_audio_bass_subgroup *bass_subgroups, uint8_t num_subgroups) +{ + BLE_AUDIO_DBG_ASSERT(num_subgroups < MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR_SUBGROUP_MAX)); + + for (uint8_t i = 0; i < num_subgroups; i++) { + subgroups[i].bis_sync = bass_subgroups[i].bis_sync_state; + subgroups[i].metadata_length = bass_subgroups[i].metadata_length; + subgroups[i].metadata = bass_subgroups[i].metadata; + } +} + +static void +sync_opt_init(struct ble_audio_scan_delegator_sync_opt *sync_opt, enum ble_svc_audio_bass_pa_sync pa_sync, + uint16_t pa_interval, const struct ble_svc_audio_bass_subgroup *bass_subgroups, uint8_t num_subgroups) +{ + sync_opt->pa_sync = (uint8_t)pa_sync; + sync_opt->pa_interval = pa_interval; + sync_opt->num_subgroups = num_subgroups; + if (sync_opt->num_subgroups > 0) { + subgroups_init(sync_opt->subgroups, bass_subgroups, num_subgroups); + } +} + +static int +bass_add_source_op_handler(struct ble_svc_audio_bass_operation *op, void *arg) +{ + struct ble_audio_scan_delegator_action action = {0}; + const uint8_t source_id = op->add_source.source_id; + int rc; + + source_desc_init(&action.source_add.source_desc, &op->add_source.adv_addr, + op->add_source.adv_sid, op->add_source.broadcast_id); + sync_opt_init(&action.source_add.sync_opt, op->add_source.pa_sync, op->add_source.pa_interval, + op->add_source.subgroups, op->add_source.num_subgroups); + + action.type = BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_ADD; + action.source_add.source_id = source_id; + action.source_add.out_source_id_to_swap = op->add_source.out_source_id_to_swap; + + rc = action_call(&action, arg); + if (rc != 0) { + BLE_HS_LOG_DEBUG("API callback (%d)\n", rc); + return rc; + } + +#if MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK) + if (op->add_source.out_source_id_to_swap != NULL) { + rc = ble_audio_broadcast_sink_stop(*op->add_source.out_source_id_to_swap); + if (rc != 0) { + BLE_HS_LOG_WARN("sink stop failed (%d)\n", rc); + } + } + + rc = ble_audio_broadcast_sink_config(source_id, op->conn_handle, &action.source_add.sync_opt); + if (rc != 0) { + BLE_HS_LOG_WARN("sink config failed (%d)\n", rc); + } +#endif /* BLE_AUDIO_BROADCAST_SINK */ + + return 0; +} + +static int +bass_modify_source_op_handler(struct ble_svc_audio_bass_operation *op, void *arg) +{ + struct ble_audio_scan_delegator_action action = {0}; + struct ble_audio_scan_delegator_sync_opt *sync_opt; + const uint8_t source_id = op->modify_source.source_id; + int rc; + + sync_opt = &action.source_modify.sync_opt; + sync_opt_init(sync_opt, op->modify_source.pa_sync, op->modify_source.pa_interval, NULL, 0); + + BLE_AUDIO_DBG_ASSERT(sync_opt->num_subgroups < ARRAY_SIZE(subgroups)); + + for (uint8_t i = 0; i < sync_opt->num_subgroups; i++) { + sync_opt->subgroups[i].bis_sync = op->modify_source.bis_sync[i]; + /* FIXME: Missing metadata in Modify Source */ + } + + action.type = BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_MODIFY; + action.source_modify.source_id = source_id; + + rc = action_call(&action, arg); + if (rc != 0) { + return rc; + } + +#if MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK) + rc = ble_audio_broadcast_sink_config(source_id, op->conn_handle, sync_opt); + if (rc != 0) { + BLE_HS_LOG_WARN("sink config failed (%d)\n", rc); + } +#endif /* BLE_AUDIO_BROADCAST_SINK */ + + return 0; +} + +static int +bass_remove_source_op_handler(struct ble_svc_audio_bass_operation *op, void *arg) +{ + struct ble_audio_scan_delegator_action action; + const uint8_t source_id = op->remove_source.source_id; + int rc; + + action.type = BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_REMOVE; + action.source_remove.source_id = source_id; + + rc = action_call(&action, arg); + if (rc != 0) { + return rc; + } + +#if MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK) + rc = ble_audio_broadcast_sink_stop(source_id); + if (rc != 0) { + BLE_HS_LOG_WARN("sink stop failed (%d)\n", rc); + } +#endif /* BLE_AUDIO_BROADCAST_SINK */ + + return 0; +} + +static int +bass_accept_fn(struct ble_svc_audio_bass_operation *op, void *arg) +{ + switch (op->op) { + case BLE_SVC_AUDIO_BASS_OPERATION_ADD_SOURCE: + return bass_add_source_op_handler(op, arg); + + case BLE_SVC_AUDIO_BASS_OPERATION_MODIFY_SOURCE: + return bass_modify_source_op_handler(op, arg); + + case BLE_SVC_AUDIO_BASS_OPERATION_REMOVE_SOURCE: + return bass_remove_source_op_handler(op, arg); + + default: + return BLE_HS_ENOTSUP; + } +} + +int +ble_audio_scan_delegator_action_fn_set(ble_audio_scan_delegator_action_fn *fn, void *arg) +{ + int rc; + + if (fn == NULL) { + BLE_HS_LOG_ERROR("callback is NULL\n"); + return BLE_HS_EINVAL; + } + + if (action_cb != NULL) { + return BLE_HS_EALREADY; + } + + action_cb = fn; + + rc = ble_svc_audio_bass_accept_fn_set(bass_accept_fn, arg); + if (rc != 0) { + action_cb = NULL; + } + + return 0; +} + +int +ble_audio_scan_delegator_receive_state_add(const struct ble_audio_scan_delegator_receive_state_add_params *params, + uint8_t *source_id) +{ + struct ble_svc_audio_bass_receiver_state_add_params bass_params = {0}; + + if (params == NULL) { + BLE_HS_LOG_ERROR("NULL params\n"); + return BLE_HS_EINVAL; + } + + if (source_id == NULL) { + BLE_HS_LOG_ERROR("NULL source_id\n"); + return BLE_HS_EINVAL; + } + + bass_params.source_addr = params->source_desc.addr; + bass_params.source_adv_sid = params->source_desc.adv_sid; + bass_params.broadcast_id = params->source_desc.broadcast_id; + bass_params.pa_sync_state = (uint8_t)params->state.pa_sync_state; + bass_params.big_encryption = (uint8_t)params->state.big_enc; + + if (params->state.big_enc == BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_BROADCAST_CODE_INVALID) { + bass_params.bad_code = params->state.bad_code; + } else { + bass_params.bad_code = NULL; + } + + bass_params.num_subgroups = params->state.num_subgroups; + if (bass_params.num_subgroups > BLE_SVC_AUDIO_BASS_SUB_NUM_MAX) { + BLE_HS_LOG_ERROR("num_subgroups above the limit\n"); + return BLE_HS_ENOMEM; + } + + for (uint8_t i = 0; i < bass_params.num_subgroups; i++) { + bass_params.subgroups[i].bis_sync_state = params->state.subgroups->bis_sync; + bass_params.subgroups[i].metadata_length = params->state.subgroups->metadata_length; + bass_params.subgroups[i].metadata = params->state.subgroups->metadata; + } + + return ble_svc_audio_bass_receive_state_add(&bass_params, source_id); +} + +int +ble_audio_scan_delegator_receive_state_remove(uint8_t source_id) +{ + int rc; + +#if MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK) + rc = ble_audio_broadcast_sink_stop(source_id); + if (rc != 0) { + BLE_HS_LOG_WARN("sink stop failed (%d)\n", rc); + } +#endif /* BLE_AUDIO_BROADCAST_SINK */ + + return ble_svc_audio_bass_receive_state_remove(source_id); +} + +int +ble_audio_scan_delegator_receive_state_set(uint8_t source_id, + const struct ble_audio_scan_delegator_receive_state *state) +{ + struct ble_svc_audio_bass_update_params bass_params; + int rc; + + if (state == NULL) { + BLE_HS_LOG_ERROR("NULL state\n"); + return BLE_HS_EINVAL; + } + + bass_params.pa_sync_state = (uint8_t)state->pa_sync_state; + bass_params.big_encryption = (uint8_t)state->big_enc; + + if (state->big_enc == BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_BROADCAST_CODE_INVALID) { + bass_params.bad_code = state->bad_code; + } else { + bass_params.bad_code = NULL; + } + + bass_params.num_subgroups = state->num_subgroups; + if (bass_params.num_subgroups > BLE_SVC_AUDIO_BASS_SUB_NUM_MAX) { + BLE_HS_LOG_ERROR("num_subgroups above the limit\n"); + return BLE_HS_ENOMEM; + } + + for (uint8_t i = 0; i < bass_params.num_subgroups; i++) { + bass_params.subgroups[i].bis_sync_state = state->subgroups[i].bis_sync; + bass_params.subgroups[i].metadata_length = state->subgroups[i].metadata_length; + bass_params.subgroups[i].metadata = state->subgroups[i].metadata; + } + + rc = ble_svc_audio_bass_receive_state_update(&bass_params, source_id); + if (rc != 0) { + BLE_HS_LOG_ERROR("Failed to update receive state (rc %d)\n", rc); + } + + return 0; +} + +void +ble_audio_scan_delegator_receive_state_foreach(ble_audio_scan_delegator_receive_state_foreach_fn *fn, void *arg) +{ + struct ble_audio_scan_delegator_receive_state_entry entry; + int rc; + + if (fn == NULL) { + BLE_HS_LOG_ERROR("callback is NULL\n"); + return; + } + + for (int i = 0; i < MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR_RECEIVE_STATE_MAX); i++) { + struct ble_svc_audio_bass_receiver_state *state; + uint8_t source_id; + + rc = ble_svc_audio_bass_source_id_get(i, &source_id); + if (rc != 0) { + continue; + } + + rc = ble_svc_audio_bass_receiver_state_get(source_id, &state); + if (rc != 0) { + BLE_HS_LOG_ERROR("Failed to get receiver state (rc %d)\n", rc); + continue; + } + + entry.source_id = source_id; + source_desc_init(&entry.source_desc, &state->source_addr, state->source_adv_sid, state->source_adv_sid); + entry.state.pa_sync_state = (uint8_t)state->pa_sync_state; + entry.state.big_enc = (uint8_t)state->big_encryption; + if (entry.state.big_enc == BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_BROADCAST_CODE_INVALID) { + memcpy(entry.state.bad_code, state->bad_code, sizeof(entry.state.bad_code)); + } + entry.state.num_subgroups = state->num_subgroups; + subgroups_init(entry.state.subgroups, state->subgroups, state->num_subgroups); + + if (fn(&entry, arg) != 0) { + break; + } + } +} + +#if MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK) +static int +audio_event_handler(struct ble_audio_event *event, void *arg) +{ + if (event->type == BLE_AUDIO_EVENT_BASS_BROADCAST_CODE_SET) { + ble_audio_broadcast_sink_code_set(event->bass_set_broadcast_code.source_id, + event->bass_set_broadcast_code.broadcast_code); + } + + return 0; +} +#endif /* BLE_AUDIO_BROADCAST_SINK */ + +int +ble_audio_scan_delegator_init(void) +{ + int rc; + + /* Ensure this function only gets called by sysinit. */ + SYSINIT_ASSERT_ACTIVE(); + +#if MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK) + static struct ble_audio_event_listener listener; + + rc = ble_audio_event_listener_register(&listener, audio_event_handler, NULL); + SYSINIT_PANIC_ASSERT(rc == 0); +#endif /* BLE_AUDIO_BROADCAST_SINK */ + + return rc; +} +#endif /* BLE_AUDIO_SCAN_DELEGATOR */ diff --git a/nimble/host/audio/src/ble_audio_scan_delegator_priv.h b/nimble/host/audio/src/ble_audio_scan_delegator_priv.h new file mode 100644 index 0000000000..ae5fc6510d --- /dev/null +++ b/nimble/host/audio/src/ble_audio_scan_delegator_priv.h @@ -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. + */ + +#ifndef H_BLE_AUDIO_SCAN_DELEGATOR_PRIV_ +#define H_BLE_AUDIO_SCAN_DELEGATOR_PRIV_ + +#include +#include "audio/ble_audio.h" +#include "audio/ble_audio_scan_delegator.h" + +int ble_audio_scan_delegator_source_desc_get( + uint8_t source_id, struct ble_audio_scan_delegator_source_desc *source_desc); +int ble_audio_scan_delegator_metadata_update( + uint8_t source_id, uint8_t subgroup_index, const uint8_t *metadata, + uint8_t metadata_length); + +#endif /* H_BLE_AUDIO_SCAN_DELEGATOR_PRIV_ */ diff --git a/nimble/host/audio/syscfg.yml b/nimble/host/audio/syscfg.yml index 5f0269e0ab..5368e503e7 100644 --- a/nimble/host/audio/syscfg.yml +++ b/nimble/host/audio/syscfg.yml @@ -16,10 +16,87 @@ # under the License. # +# syscfg.defs section syscfg.defs: BLE_AUDIO_MAX_CODEC_RECORDS: description: > Maximum number of registered audio codecs. value: 0 -syscfg.logs: + BLE_AUDIO_BROADCAST_SINK: + description: > + This option enables BLE Audio Sink support. + value: 0 + restrictions: + - '(BLE_ISO_BROADCAST_SINK > 0) if 1' + + BLE_AUDIO_SCAN_DELEGATOR: + description: > + This option enables BLE Audio Scan Delegator support. + value: 0 + +syscfg.defs.BLE_AUDIO_BROADCAST_SINK: + BLE_AUDIO_BROADCAST_SINK_SYSINIT_STAGE: + description: > + Primary sysinit stage for BLE Audio Broadcast Sink. + value: 500 + + BLE_AUDIO_BROADCAST_SINK_LOG_MOD: + description: 'Numeric module ID to use for BLE Audio Broadcast Sink log messages.' + value: 28 + + BLE_AUDIO_BROADCAST_SINK_LOG_LVL: + description: 'Minimum level for the BLE Audio Broadcast Sink log log.' + value: 1 + + BLE_AUDIO_BROADCAST_SINK_MAX: + description: > + Maximum umber of Audio Broadcast Sink instances. + value: 'MYNEWT_VAL_BLE_ISO_MAX_BIGS' + +syscfg.defs.BLE_AUDIO_SCAN_DELEGATOR: + BLE_AUDIO_SCAN_DELEGATOR_SYSINIT_STAGE: + description: > + Primary sysinit stage for BLE Audio Scan Delegator. + value: 499 + + BLE_AUDIO_SCAN_DELEGATOR_LOG_MOD: + description: 'Numeric module ID to use for BLE Audio Scan Delegator log messages.' + value: 29 + + BLE_AUDIO_SCAN_DELEGATOR_LOG_LVL: + description: 'Minimum level for the BLE Audio Scan Delegator log log.' + value: 1 + + BLE_AUDIO_SCAN_DELEGATOR_RECEIVE_STATE_MAX: + description: > + Maximum number of Receive State instances. + value: MYNEWT_VAL(BLE_SVC_AUDIO_BASS_RECEIVE_STATE_MAX) + + BLE_AUDIO_SCAN_DELEGATOR_SUBGROUP_MAX: + description: > + Maximum number of Subgroups per Receive State. + value: MYNEWT_VAL(BLE_SVC_AUDIO_BASS_SUB_NUM_MAX) + + BLE_AUDIO_SCAN_DELEGATOR_STANDALONE: + description: > + This option enables the BLE Audio Scan Delegator as standalone device. + value: 1 + restrictions: + - '(BLE_AUDIO_BROADCAST_SINK == 0) if 1' + +# syscfg.logs section +syscfg.logs.BLE_AUDIO_BROADCAST_SINK: + BLE_AUDIO_BROADCAST_SINK_LOG: + module: MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK_LOG_MOD) + level: MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK_LOG_LVL) + +syscfg.logs.BLE_AUDIO_SCAN_DELEGATOR: + BLE_AUDIO_SCAN_DELEGATOR_LOG: + module: MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR_LOG_MOD) + level: MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR_LOG_LVL) + +# syscfg.vals section +syscfg.vals.BLE_AUDIO_BROADCAST_SINK: + BLE_AUDIO_SCAN_DELEGATOR: 1 + BLE_AUDIO_SCAN_DELEGATOR_STANDALONE: 0 From 868ecb0bdbec073aa6e4830f1cab9da323740193 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 25 Jan 2024 13:28:54 +0100 Subject: [PATCH 1024/1333] apps/btshell: Add Audio Broadcast Sink to shell application this extends the btshell application with Audio Broadcast Sink functionality. --- apps/btshell/src/btshell.h | 2 + apps/btshell/src/cmd.c | 86 ++- apps/btshell/src/cmd.h | 7 + apps/btshell/src/cmd_leaudio.c | 705 +++++++++++++++++- apps/btshell/src/cmd_leaudio.h | 20 + apps/btshell/src/main.c | 6 + apps/btshell/syscfg.yml | 3 + .../host/audio/targets/btshell_native/pkg.yml | 1 + .../audio/targets/btshell_native/syscfg.yml | 5 +- 9 files changed, 830 insertions(+), 5 deletions(-) diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h index c2a2eb3e29..3d94c21204 100644 --- a/apps/btshell/src/btshell.h +++ b/apps/btshell/src/btshell.h @@ -222,6 +222,8 @@ int btshell_broadcast_start(uint8_t adv_instance); int btshell_broadcast_stop(uint8_t adv_instance); #endif +void btshell_leaudio_init(void); + int btshell_gap_event(struct ble_gap_event *event, void *arg); void btshell_sync_stats(uint16_t handle); uint8_t btshell_get_default_own_addr_type(void); diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index 50aac79400..a9758e14b2 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -87,14 +87,28 @@ static const struct parse_arg_kv_pair cmd_peer_addr_types[] = { { NULL } }; -static const struct parse_arg_kv_pair cmd_addr_type[] = { +const struct parse_arg_kv_pair cmd_addr_type[] = { { "public", BLE_ADDR_PUBLIC }, { "random", BLE_ADDR_RANDOM }, { NULL } }; +const char * +cmd_addr_type_str(uint8_t type) +{ + const struct parse_arg_kv_pair *kvs = cmd_addr_type; + int i; -static int + for (i = 0; kvs[i].key != NULL; i++) { + if (type == kvs[i].val) { + return kvs[i].key; + } + } + + return "unknown"; +} + +int parse_dev_addr(const char *prefix, const struct parse_arg_kv_pair *addr_types, ble_addr_t *addr) { @@ -152,6 +166,12 @@ parse_dev_addr(const char *prefix, const struct parse_arg_kv_pair *addr_types, return 0; } +int +cmd_parse_addr(const char *prefix, ble_addr_t *addr) +{ + return parse_dev_addr(prefix, cmd_addr_type, addr); +} + /***************************************************************************** * $advertise * *****************************************************************************/ @@ -4924,7 +4944,67 @@ static const struct shell_cmd btshell_commands[] = { .help = &leaudio_broadcast_stop_help, #endif }, -#endif /* BLE_ISO_BROADCAST_SOURCE */ +#endif +#if MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK) + { + .sc_cmd = "broadcast-sink-start", + .sc_cmd_func = cmd_leaudio_broadcast_sink_start, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &cmd_leaudio_broadcast_sink_start_help, +#endif + }, + { + .sc_cmd = "broadcast-sink-stop", + .sc_cmd_func = cmd_leaudio_broadcast_sink_stop, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &cmd_leaudio_broadcast_sink_stop_help, +#endif + }, + { + .sc_cmd = "broadcast-sink-metadata", + .sc_cmd_func = cmd_leaudio_broadcast_sink_metadata_update, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &cmd_leaudio_broadcast_sink_metadata_update_help, +#endif + }, +#endif /* BLE_AUDIO_BROADCAST_SINK */ +#if MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR) + { + .sc_cmd = "scan-delegator-add", + .sc_cmd_func = cmd_leaudio_scan_delegator_receive_state_add, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &cmd_leaudio_scan_delegator_receive_state_add_help, +#endif + }, + { + .sc_cmd = "scan-delegator-remove", + .sc_cmd_func = cmd_leaudio_scan_delegator_receive_state_remove, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &cmd_leaudio_scan_delegator_receive_state_remove_help, +#endif + }, + { + .sc_cmd = "scan-delegator-set", + .sc_cmd_func = cmd_leaudio_scan_delegator_receive_state_set, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &cmd_leaudio_scan_delegator_receive_state_set_help, +#endif + }, + { + .sc_cmd = "scan-delegator-get", + .sc_cmd_func = cmd_leaudio_scan_delegator_receive_state_get, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &cmd_leaudio_scan_delegator_receive_state_get_help, +#endif + }, + { + .sc_cmd = "scan-delegator-show", + .sc_cmd_func = cmd_leaudio_scan_delegator_receive_state_show, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &cmd_leaudio_scan_delegator_receive_state_show_help, +#endif + }, +#endif /* BLE_AUDIO_SCAN_DELEGATOR */ #if MYNEWT_VAL(BLE_ISO) #if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) { diff --git a/apps/btshell/src/cmd.h b/apps/btshell/src/cmd.h index 1477ea85c7..c5532f34ff 100644 --- a/apps/btshell/src/cmd.h +++ b/apps/btshell/src/cmd.h @@ -30,6 +30,13 @@ int parse_eddystone_url(char *full_url, uint8_t *out_scheme, char *out_body, int cmd_parse_conn_start_end(uint16_t *out_conn, uint16_t *out_start, uint16_t *out_end); +int parse_dev_addr(const char *prefix, const struct parse_arg_kv_pair *addr_types, + ble_addr_t *addr); + +int cmd_parse_addr(const char *prefix, ble_addr_t *addr); + +const char *cmd_addr_type_str(uint8_t type); + void cmd_init(void); #endif diff --git a/apps/btshell/src/cmd_leaudio.c b/apps/btshell/src/cmd_leaudio.c index 2f31246cf8..cea206b6e0 100644 --- a/apps/btshell/src/cmd_leaudio.c +++ b/apps/btshell/src/cmd_leaudio.c @@ -20,9 +20,13 @@ #include "cmd_leaudio.h" #include "btshell.h" #include "console/console.h" +#include "shell/shell.h" +#include "bsp/bsp.h" #include "errno.h" -#if (MYNEWT_VAL(BLE_AUDIO)) +#define STR_NULL "null" + +#if (MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)) #include "audio/ble_audio_broadcast_source.h" int cmd_leaudio_base_add(int argc, char **argv) @@ -382,4 +386,703 @@ cmd_leaudio_broadcast_stop(int argc, char **argv) return btshell_broadcast_stop(adv_instance); } +#endif /* BLE_ISO_BROADCAST_SOURCE */ + +#if (MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK)) +#include "audio/ble_audio_broadcast_sink.h" + +#define BROADCAST_SINK_PA_SYNC_TIMEOUT_DEFAULT 0x07D0 + +static int +broadcast_sink_pa_sync_params_get(struct ble_gap_periodic_sync_params *params) +{ + params->skip = 0; + params->sync_timeout = BROADCAST_SINK_PA_SYNC_TIMEOUT_DEFAULT; + params->reports_disabled = false; + + return 0; +} + +static void +codec_specific_config_printf(const struct ble_audio_codec_id *unused, const uint8_t *data, + uint8_t len) +{ + console_printf("data=%p len=%u\n", data, len); +} + +static void +base_bis_printf(const struct ble_audio_codec_id *codec_id, const struct ble_audio_base_bis *bis) +{ + console_printf("BISCodecConfig:\n\t"); + codec_specific_config_printf(codec_id,bis->codec_spec_config, bis->codec_spec_config_len); +} + +static void +metadata_printf(const uint8_t *data, uint8_t len) +{ + console_printf("data=%p len=%u\n", data, len); +} + +static void +base_subgroup_printf(uint8_t subgroup_index, const struct ble_audio_base_subgroup *subgroup) +{ + console_printf("subgroup_index=%u\n", subgroup_index); + console_printf("Codec ID:\n\tformat=0x%02x company_id=0x%04x vendor_specific=0x%02x\n", + subgroup->codec_id.format, subgroup->codec_id.company_id, + subgroup->codec_id.vendor_specific); + console_printf("SubgroupCodecConfig:\n\t"); + codec_specific_config_printf(&subgroup->codec_id, + subgroup->codec_spec_config, + subgroup->codec_spec_config_len); + console_printf("Metadata:\n\t"); + metadata_printf(subgroup->metadata, subgroup->metadata_len); +} + +static int +broadcast_sink_disc_start(const struct ble_gap_ext_disc_params *params) +{ + uint8_t own_addr_type; + int rc; + + /* Figure out address to use while scanning. */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + console_printf("determining own address type failed (%d)", rc); + assert(0); + } + + rc = ble_gap_ext_disc(own_addr_type, 0, 0, 0, 0, 0, params, NULL, NULL, NULL); + if (rc != 0) { + console_printf("ext disc failed (%d)", rc); + } + + return rc; +} + +static int +broadcast_sink_disc_stop(void) +{ + int rc; + + rc = ble_gap_disc_cancel(); + if (rc != 0) { + console_printf("disc cancel failed (%d)", rc); + } + + return rc; +} + +static int +broadcast_sink_action_fn(struct ble_audio_broadcast_sink_action *action, void *arg) +{ + switch (action->type) { + case BLE_AUDIO_BROADCAST_SINK_ACTION_PA_SYNC: + console_printf("PA Sync:\n"); + return broadcast_sink_pa_sync_params_get(action->pa_sync.out_params); + case BLE_AUDIO_BROADCAST_SINK_ACTION_BIG_SYNC: + console_printf("BIG Sync:\nsource_id=0x%02x iso_interval=0x%04x" + " presentation_delay=%u[us]\n", + action->big_sync.source_id, action->big_sync.iso_interval, + action->big_sync.presentation_delay); + break; + case BLE_AUDIO_BROADCAST_SINK_ACTION_BIS_SYNC: + console_printf("BIS Sync:\n\tsource_id=0x%02x bis_index=0x%02x\n", + action->bis_sync.source_id, action->bis_sync.bis->index); + base_subgroup_printf(action->bis_sync.subgroup_index, action->bis_sync.subgroup); + base_bis_printf(&action->bis_sync.subgroup->codec_id, action->bis_sync.bis); + return 0; + case BLE_AUDIO_BROADCAST_SINK_ACTION_DISC_START: + return broadcast_sink_disc_start(action->disc_start.params_preferred); + case BLE_AUDIO_BROADCAST_SINK_ACTION_DISC_STOP: + return broadcast_sink_disc_stop(); + default: + assert(false); + return ENOTSUP; + } + + return 0; +} + + +static const struct shell_param cmd_leaudio_broadcast_sink_start_params[] = { + {"source_id", "usage: ="}, + {"broadcast_code", "usage: =[string], default: NULL"}, + {NULL, NULL} +}; + +#if MYNEWT_VAL(SHELL_CMD_HELP) +const struct shell_cmd_help cmd_leaudio_broadcast_sink_start_help = { + .summary = "Start audio Broadcast Sink", + .usage = NULL, + .params = cmd_leaudio_broadcast_sink_start_params +}; +#endif + +int +cmd_leaudio_broadcast_sink_start(int argc, char **argv) +{ + struct ble_audio_broadcast_sink_add_params params = {0}; + char *broadcast_code; + uint8_t source_id; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + source_id = parse_arg_uint8("source_id", &rc); + if (rc != 0) { + console_printf("invalid 'source_id' parameter\n"); + return rc; + } + + broadcast_code = parse_arg_extract("broadcast_code"); + if (broadcast_code != NULL) { + strncpy((char *)params.broadcast_code, broadcast_code, BLE_AUDIO_BROADCAST_CODE_SIZE); + params.broadcast_code_is_valid = true; + } + + rc = ble_audio_broadcast_sink_start(source_id, ¶ms); + if (rc != 0) { + console_printf("start failed (%d)\n", rc); + } + + return rc; +} + +static const struct shell_param cmd_leaudio_broadcast_sink_stop_params[] = { + {"source_id", "usage: ="}, + {NULL, NULL} +}; + +#if MYNEWT_VAL(SHELL_CMD_HELP) +const struct shell_cmd_help cmd_leaudio_broadcast_sink_stop_help = { + .summary = "Stop audio Broadcast Sink", + .usage = NULL, + .params = cmd_leaudio_broadcast_sink_stop_params +}; +#endif + +int +cmd_leaudio_broadcast_sink_stop(int argc, char **argv) +{ + uint8_t source_id; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + source_id = parse_arg_uint8("source_id", &rc); + if (rc != 0) { + console_printf("invalid 'source_id' parameter\n"); + return rc; + } + + rc = ble_audio_broadcast_sink_stop(source_id); + if (rc != 0) { + console_printf("stop failed (%d)\n", rc); + } + + return rc; +} + +static const struct shell_param cmd_leaudio_broadcast_sink_metadata_update_params[] = { + {"source_id", "usage: ="}, + {"subgroup_index", "usage: ="}, + {"metadata", "usage: =[XX:XX...]"}, + {NULL, NULL} +}; + +#if MYNEWT_VAL(SHELL_CMD_HELP) +const struct shell_cmd_help cmd_leaudio_broadcast_sink_metadata_update_help = { + .summary = "Update Broadcast Sink metadata", + .usage = NULL, + .params = cmd_leaudio_broadcast_sink_metadata_update_params +}; #endif + +int +cmd_leaudio_broadcast_sink_metadata_update(int argc, char **argv) +{ + struct ble_audio_broadcast_sink_metadata_update_params params = {0}; + static bssnz_t uint8_t metadata[UINT8_MAX]; + unsigned int metadata_len; + uint8_t source_id; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + source_id = parse_arg_uint8("source_id", &rc); + if (rc != 0) { + console_printf("invalid 'source_id' parameter\n"); + return rc; + } + + params.subgroup_index = parse_arg_uint8("subgroup_index", &rc); + if (rc != 0) { + console_printf("invalid 'subgroup_index' parameter\n"); + return rc; + } + + rc = parse_arg_byte_stream("metadata", UINT8_MAX, metadata, &metadata_len); + if (rc == 0) { + params.metadata = metadata; + params.metadata_length = metadata_len; + } else if (rc != ENOENT) { + console_printf("invalid 'metadata' parameter\n"); + return rc; + } + + rc = ble_audio_broadcast_sink_metadata_update(source_id, ¶ms); + if (rc != 0) { + console_printf("metadata update failed (%d)\n", rc); + } + + return rc; +} + +static int +broadcast_sink_audio_event_handler(struct ble_audio_event *event, void *arg) +{ + switch (event->type) { + case BLE_AUDIO_EVENT_BROADCAST_SINK_PA_SYNC_STATE: + console_printf("source_id=0x%02x PA sync: %s\n", + event->broadcast_sink_pa_sync_state.source_id, + ble_audio_broadcast_sink_sync_state_str( + event->broadcast_sink_pa_sync_state.state)); + break; + case BLE_AUDIO_EVENT_BROADCAST_SINK_BIS_SYNC_STATE: + console_printf("source_id=0x%02x bis_index=0x%02x BIS sync: %s\n", + event->broadcast_sink_bis_sync_state.source_id, + event->broadcast_sink_bis_sync_state.bis_index, + ble_audio_broadcast_sink_sync_state_str( + event->broadcast_sink_bis_sync_state.state)); + if (event->broadcast_sink_bis_sync_state.state == + BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_ESTABLISHED) { + console_printf("conn_handle=0x%04x\n", + event->broadcast_sink_bis_sync_state.conn_handle); + } + break; + default: + break; + } + + return 0; +} +#endif /* BLE_AUDIO_BROADCAST_SINK */ + +#if MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR) +#include "audio/ble_audio_scan_delegator.h" + +static void +scan_delegator_source_desc_printf(const struct ble_audio_scan_delegator_source_desc *source_desc) +{ + console_printf("broadcast_id=0x%6x adv_sid=%d adv_addr_type=%s adv_addr=", + source_desc->broadcast_id, source_desc->adv_sid, + cmd_addr_type_str(source_desc->addr.type)); + print_addr(source_desc->addr.val); + console_printf("\n"); +} + +static void +scan_delegator_sync_opt_printf(const struct ble_audio_scan_delegator_sync_opt *sync_opt) +{ + console_printf("pa_sync=%d pa_interval=0x%04x num_subgroups=%d", + sync_opt->pa_sync, sync_opt->pa_interval, sync_opt->num_subgroups); + for (uint8_t i = 0; i < sync_opt->num_subgroups; i++) { + console_printf("\n\tbis_sync=0x%04x metadata_length=%d metadata=", + sync_opt->subgroups[i].bis_sync, sync_opt->subgroups[i].metadata_length); + print_bytes(sync_opt->subgroups[i].metadata, sync_opt->subgroups[i].metadata_length); + } + console_printf("\n"); +} + +static int +scan_delegator_pick_source_id_to_swap(uint8_t *out_source_id_to_swap) +{ + /* TODO: Add some logic here */ + *out_source_id_to_swap = 0; + + return 0; +} + +static int +scan_delegator_action_fn(struct ble_audio_scan_delegator_action *action, void *arg) +{ + switch (action->type) { + case BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_ADD: + console_printf("Source Add:\nsource_id=%u\n", action->source_add.source_id); + scan_delegator_source_desc_printf(&action->source_add.source_desc); + scan_delegator_sync_opt_printf(&action->source_add.sync_opt); + if (action->source_add.out_source_id_to_swap == NULL) { + return 0; + } else { + return scan_delegator_pick_source_id_to_swap(action->source_add.out_source_id_to_swap); + } + case BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_MODIFY: + console_printf("Source Modify:\nsource_id=%u\n", action->source_modify.source_id); + scan_delegator_sync_opt_printf(&action->source_modify.sync_opt); + break; + case BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_REMOVE: + console_printf("Source Remove:\nsource_id=%u\n", action->source_remove.source_id); + break; + default: + assert(false); + return ENOTSUP; + } + + return 0; +} + +static const struct shell_param cmd_leaudio_scan_delegator_receive_state_add_params[] = { + {"addr_type", "usage: =[public|random], default: public"}, + {"addr", "usage: =[XX:XX:XX:XX:XX:XX]"}, + {"broadcast_id", "usage: =[0-0xFFFFFF]"}, + {"adv_sid", "usage: =[UINT8], default: 0"}, + {NULL, NULL} +}; + +#if MYNEWT_VAL(SHELL_CMD_HELP) +const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_add_help = { + .summary = "Add receive state", + .usage = NULL, + .params = cmd_leaudio_scan_delegator_receive_state_add_params +}; +#endif /* SHELL_CMD_HELP */ + +int +cmd_leaudio_scan_delegator_receive_state_add(int argc, char **argv) +{ + struct ble_audio_scan_delegator_receive_state_add_params params = {0}; + uint8_t source_id; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + rc = cmd_parse_addr(NULL, ¶ms.source_desc.addr); + if (rc != 0) { + console_printf("invalid 'adv_addr' parameter\n"); + return rc; + } + + params.source_desc.broadcast_id = parse_arg_uint32("broadcast_id", &rc); + if (rc != 0) { + console_printf("invalid 'broadcast_id' parameter\n"); + return rc; + } + + params.source_desc.adv_sid = parse_arg_uint8_dflt("adv_sid", 0, &rc); + if (rc != 0) { + console_printf("invalid 'adv_sid' parameter\n"); + return rc; + } + + rc = ble_audio_scan_delegator_receive_state_add(¶ms, &source_id); + if (rc != 0) { + console_printf("Failed to add receive state (%d)\n", rc); + } else { + console_printf("New source_id=%u created\n", source_id); + } + + return rc; +} + +static const struct shell_param cmd_leaudio_scan_delegator_receive_state_remove_params[] = { + {"source_id", "usage: ="}, + {NULL, NULL} +}; + +#if MYNEWT_VAL(SHELL_CMD_HELP) +const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_remove_help = { + .summary = "Remove receive state", + .usage = NULL, + .params = cmd_leaudio_scan_delegator_receive_state_remove_params +}; +#endif /* SHELL_CMD_HELP */ + +int +cmd_leaudio_scan_delegator_receive_state_remove(int argc, char **argv) +{ + uint8_t source_id; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + source_id = parse_arg_uint8("source_id", &rc); + if (rc != 0) { + console_printf("invalid 'source_id' parameter\n"); + return rc; + } + + rc = ble_audio_scan_delegator_receive_state_remove(source_id); + if (rc != 0) { + console_printf("remove failed (%d)\n", rc); + } + + return rc; +} + +const struct parse_arg_kv_pair cmd_pa_sync_type[] = { + { "not_synced", BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_NOT_SYNCED }, + { "sync_info_req", BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_SYNC_INFO_REQ }, + { "synced", BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_SYNCED }, + { "failed", BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_ERROR }, + { "no_past", BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_NO_PAST }, + { NULL } +}; + +const struct parse_arg_kv_pair cmd_big_enc_type[] = { + { "not_encrypted", BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_NONE }, + { "code_req", BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_BROADCAST_CODE_MISSING }, + { "decrypting", BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_DECRYPTING }, + { "bad_code", BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_BROADCAST_CODE_INVALID }, + { NULL } +}; + +static const struct shell_param cmd_leaudio_scan_delegator_receive_state_set_params[] = { + {"source_id", "usage: ="}, + {"pa_sync_state", "usage: =[not_synced|sync_info_req|synced|failed|no_past]," + " default: not_synced"}, + {"big_enc", "usage: =[not_encrypted|code_req|decrypting|bad_code]," + " default: not_encrypted"}, + {"bad_code", "usage: =[string], default: NULL"}, + {NULL, NULL} +}; + +#if MYNEWT_VAL(SHELL_CMD_HELP) +const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_set_help = { + .summary = "Set receive state", + .usage = NULL, + .params = cmd_leaudio_scan_delegator_receive_state_set_params +}; +#endif /* SHELL_CMD_HELP */ + +int +cmd_leaudio_scan_delegator_receive_state_set(int argc, char **argv) +{ + struct ble_audio_scan_delegator_receive_state state = {0}; + char *bad_code; + uint8_t source_id; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + source_id = parse_arg_uint8("source_id", &rc); + if (rc != 0) { + console_printf("invalid 'source_id' parameter\n"); + return rc; + } + + state.pa_sync_state = parse_arg_kv_dflt("pa_sync_state", cmd_pa_sync_type, + BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_STATE_NOT_SYNCED, &rc); + if (rc != 0) { + console_printf("invalid 'pa_sync_state' parameter\n"); + return rc; + } + + state.big_enc = parse_arg_kv_dflt("big_enc", cmd_big_enc_type, + BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_NONE, &rc); + if (rc != 0) { + console_printf("invalid 'big_enc' parameter\n"); + return rc; + } + + bad_code = parse_arg_extract("bad_code"); + if (bad_code != NULL) { + strncpy((char *)state.bad_code, bad_code, BLE_AUDIO_BROADCAST_CODE_SIZE); + } + + /* TODO: initialize state.subgroups */ + state.num_subgroups = 0; + + rc = ble_audio_scan_delegator_receive_state_set(source_id, &state); + if (rc != 0) { + console_printf("set failed (%d)\n", rc); + } + + return rc; +} + +static const char * +pa_sync_type_str(enum ble_audio_scan_delegator_pa_sync_state pa_sync_state) +{ + for (size_t i = 0; i < ARRAY_SIZE(cmd_pa_sync_type); i++) { + if (cmd_pa_sync_type[i].val == pa_sync_state) { + return cmd_pa_sync_type[i].key; + } + } + + return STR_NULL; +} + +static const char * +big_enc_type_str(enum ble_audio_scan_delegator_big_enc big_enc) +{ + for (size_t i = 0; i < ARRAY_SIZE(cmd_big_enc_type); i++) { + if (cmd_big_enc_type[i].val == big_enc) { + return cmd_big_enc_type[i].key; + } + } + + return STR_NULL; +} + +static void +scan_delegator_receive_state_printf(const struct ble_audio_scan_delegator_receive_state *state) +{ + console_printf("pa_sync_state=%s big_enc=%s num_subgroups=%d", + pa_sync_type_str(state->pa_sync_state), big_enc_type_str(state->big_enc), + state->num_subgroups); + + if (state->big_enc == BLE_AUDIO_SCAN_DELEGATOR_BIG_ENC_BROADCAST_CODE_INVALID) { + console_printf("bad_code="); + print_bytes(state->bad_code, sizeof(state->bad_code)); + console_printf("\n"); + } + + for (uint8_t i = 0; i < state->num_subgroups; i++) { + console_printf("\n\tbis_sync=0x%04x metadata_length=%d metadata=", + state->subgroups[i].bis_sync, state->subgroups[i].metadata_length); + print_bytes(state->subgroups[i].metadata, state->subgroups[i].metadata_length); + console_printf("\n"); + } +} + +static const struct shell_param cmd_leaudio_scan_delegator_receive_state_get_params[] = { + {"source_id", "usage: ="}, + {NULL, NULL} +}; + +#if MYNEWT_VAL(SHELL_CMD_HELP) +const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_get_help = { + .summary = "Get receive state", + .usage = NULL, + .params = cmd_leaudio_scan_delegator_receive_state_get_params +}; +#endif /* SHELL_CMD_HELP */ + +int +cmd_leaudio_scan_delegator_receive_state_get(int argc, char **argv) +{ + struct ble_audio_scan_delegator_receive_state state = {0}; + uint8_t source_id; + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + source_id = parse_arg_uint8("source_id", &rc); + if (rc != 0) { + console_printf("invalid 'source_id' parameter\n"); + return rc; + } + + rc = ble_audio_scan_delegator_receive_state_get(source_id, &state); + if (rc != 0) { + console_printf("get failed (%d)\n", rc); + } else { + console_printf("source_id=%u\n", source_id); + scan_delegator_receive_state_printf(&state); + } + + return rc; +} + +static int +scan_delegator_receive_state_foreach_fn(struct ble_audio_scan_delegator_receive_state_entry *entry, + void *arg) +{ + console_printf("source_id=%u\n", entry->source_id); + scan_delegator_source_desc_printf(&entry->source_desc); + scan_delegator_receive_state_printf(&entry->state); + + return 0; +} + +#if MYNEWT_VAL(SHELL_CMD_HELP) +const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_show_help = { + .summary = "List receive states", + .usage = NULL, + .params = NULL +}; +#endif /* SHELL_CMD_HELP */ + +int +cmd_leaudio_scan_delegator_receive_state_show(int argc, char **argv) +{ + uint8_t num_entries = 0; + + ble_audio_scan_delegator_receive_state_foreach(scan_delegator_receive_state_foreach_fn, + &num_entries); + if (num_entries == 0) { + console_printf("No receive state\n"); + } + + return 0; +} + +static int +scan_delegator_audio_event_handler(struct ble_audio_event *event, void *arg) +{ + switch (event->type) { + case BLE_AUDIO_EVENT_BROADCAST_ANNOUNCEMENT: + console_printf("Broadcast Announcement\n"); + console_printf("broadcast_id=0x%6x adv_sid=%d addr_type=%s addr=", + event->broadcast_announcement.broadcast_id, + event->broadcast_announcement.ext_disc->sid, + cmd_addr_type_str(event->broadcast_announcement.ext_disc->addr.type)); + print_addr(event->broadcast_announcement.ext_disc->addr.val); + console_printf("\n"); + break; + default: + break; + } + + return 0; +} +#endif /* BLE_AUDIO_SCAN_DELEGATOR */ + +void +btshell_leaudio_init(void) +{ + int rc = 0; + +#if (MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR)) + static struct ble_audio_event_listener scan_delegator_listener; + + rc = ble_audio_scan_delegator_action_fn_set(scan_delegator_action_fn, NULL); + assert(rc == 0); + + rc = ble_audio_event_listener_register(&scan_delegator_listener, + scan_delegator_audio_event_handler, NULL); + assert(rc == 0); +#endif /* BLE_AUDIO_SCAN_DELEGATOR */ + +#if (MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK)) + static struct ble_audio_event_listener broadcast_sink_listener; + + rc = ble_audio_broadcast_sink_cb_set(broadcast_sink_action_fn, NULL); + assert(rc == 0); + + rc = ble_audio_event_listener_register(&broadcast_sink_listener, + broadcast_sink_audio_event_handler, NULL); +#endif /* BLE_AUDIO_BROADCAST_SINK */ + assert(rc == 0); +} diff --git a/apps/btshell/src/cmd_leaudio.h b/apps/btshell/src/cmd_leaudio.h index 84fc458626..477b33a21f 100644 --- a/apps/btshell/src/cmd_leaudio.h +++ b/apps/btshell/src/cmd_leaudio.h @@ -43,4 +43,24 @@ int cmd_leaudio_broadcast_update(int argc, char **argv); int cmd_leaudio_broadcast_start(int argc, char **argv); int cmd_leaudio_broadcast_stop(int argc, char **argv); +extern const struct shell_cmd_help cmd_leaudio_broadcast_sink_start_help; +extern const struct shell_cmd_help cmd_leaudio_broadcast_sink_stop_help; +extern const struct shell_cmd_help cmd_leaudio_broadcast_sink_metadata_update_help; + +int cmd_leaudio_broadcast_sink_start(int argc, char **argv); +int cmd_leaudio_broadcast_sink_stop(int argc, char **argv); +int cmd_leaudio_broadcast_sink_metadata_update(int argc, char **argv); + +extern const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_add_help; +extern const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_remove_help; +extern const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_set_help; +extern const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_get_help; +extern const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_show_help; + +int cmd_leaudio_scan_delegator_receive_state_add(int argc, char **argv); +int cmd_leaudio_scan_delegator_receive_state_remove(int argc, char **argv); +int cmd_leaudio_scan_delegator_receive_state_set(int argc, char **argv); +int cmd_leaudio_scan_delegator_receive_state_get(int argc, char **argv); +int cmd_leaudio_scan_delegator_receive_state_show(int argc, char **argv); + #endif /* H_CMD_LEAUDIO_ */ diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index 0ba90ff131..7292927654 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -2078,6 +2078,10 @@ btshell_ext_scan(uint8_t own_addr_type, uint16_t duration, uint16_t period, const struct ble_gap_ext_disc_params *coded_params, void *cb_args) { + struct btshell_scan_opts *scan_opts = cb_args; + + console_printf("silent %d.", scan_opts->silent); + #if !MYNEWT_VAL(BLE_EXT_ADV) console_printf("BLE extended advertising not supported."); console_printf(" Configure nimble host to enable it\n"); @@ -3143,6 +3147,8 @@ mynewt_main(int argc, char **argv) btshell_init_ext_adv_restart(); + btshell_leaudio_init(); + while (1) { os_eventq_run(os_eventq_dflt_get()); } diff --git a/apps/btshell/syscfg.yml b/apps/btshell/syscfg.yml index 091a2df0c1..3bdfb34ac6 100644 --- a/apps/btshell/syscfg.yml +++ b/apps/btshell/syscfg.yml @@ -50,3 +50,6 @@ syscfg.vals: syscfg.vals.BLE_MESH: MSYS_1_BLOCK_COUNT: 16 + +syscfg.vals.BLE_AUDIO_BROADCAST_SINK: + BLE_AUDIO_BROADCAST_SINK_MAX: 1 diff --git a/nimble/host/audio/targets/btshell_native/pkg.yml b/nimble/host/audio/targets/btshell_native/pkg.yml index 67eb2d6fe5..7c129c62ff 100644 --- a/nimble/host/audio/targets/btshell_native/pkg.yml +++ b/nimble/host/audio/targets/btshell_native/pkg.yml @@ -24,3 +24,4 @@ pkg.description: Target for native btshell application with LE Audio pkg.author: "Apache Mynewt " pkg.homepage: "http://mynewt.apache.org/" pkg.deps: + - nimble/host/audio diff --git a/nimble/host/audio/targets/btshell_native/syscfg.yml b/nimble/host/audio/targets/btshell_native/syscfg.yml index e9db007074..3c04c0c12e 100644 --- a/nimble/host/audio/targets/btshell_native/syscfg.yml +++ b/nimble/host/audio/targets/btshell_native/syscfg.yml @@ -30,7 +30,7 @@ syscfg.vals: # Disable security manager (pairing and bonding). BLE_SM_LEGACY: 0 - BLE_SM_SC: 0 + BLE_SM_SC: 1 # Default task settings OS_MAIN_STACK_SIZE: 512 @@ -64,6 +64,9 @@ syscfg.vals: BLE_ISO_MAX_BIGS: 1 BLE_ISO_MAX_BISES: 2 + BLE_AUDIO_BROADCAST_SINK: 1 + BLE_AUDIO_SCAN_DELEGATOR: 1 + CONSOLE_UART: 1 CONSOLE_UART_BAUD: 1000000 CONSOLE_STICKY_PROMPT: 1 From 060266094e2af884f4487fccba391c3e2a96ff23 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 30 Apr 2024 09:46:10 +0200 Subject: [PATCH 1025/1333] nimble/audio: Add PACS to Broadcast Sink This enables PACS when Broadcast Sink role is enabled. By default the 16_2 and 24_2 mandatory settings are supported as per spec. --- nimble/host/audio/pkg.yml | 3 +++ nimble/host/audio/services/pacs/lc3/syscfg.yml | 9 +++++++++ nimble/host/audio/syscfg.yml | 1 + 3 files changed, 13 insertions(+) diff --git a/nimble/host/audio/pkg.yml b/nimble/host/audio/pkg.yml index 5dd146166a..43385d2718 100644 --- a/nimble/host/audio/pkg.yml +++ b/nimble/host/audio/pkg.yml @@ -31,6 +31,9 @@ pkg.deps: - nimble - nimble/host +pkg.deps.BLE_AUDIO_BROADCAST_SINK: + - nimble/host/audio/services/pacs/lc3 + pkg.deps.BLE_AUDIO_SCAN_DELEGATOR: - nimble/host/audio/services/bass diff --git a/nimble/host/audio/services/pacs/lc3/syscfg.yml b/nimble/host/audio/services/pacs/lc3/syscfg.yml index f2a2ff0685..2a12d89b50 100644 --- a/nimble/host/audio/services/pacs/lc3/syscfg.yml +++ b/nimble/host/audio/services/pacs/lc3/syscfg.yml @@ -129,3 +129,12 @@ syscfg.defs: Audio Locations supported by sink codec. Value is an any combination of values defined in Bluetooth Assigned Numbers 6.12.3. Default: Media value: 0x0004 + +syscfg.vals.BLE_AUDIO_BROADCAST_SINK: + BLE_SVC_AUDIO_PACS_LC3_SNK_SAMPLING_FREQUENCIES: > + BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_16000_HZ || BLE_AUDIO_CODEC_SUPPORTED_SAMPLING_RATE_24000_HZ + BLE_SVC_AUDIO_PACS_LC3_SNK_FRAME_DURATIONS: BLE_AUDIO_CODEC_SUPPORTED_FRAME_DURATION_10_MS + BLE_SVC_AUDIO_PACS_LC3_SNK_AUDIO_CHANNEL_COUNTS: BLE_AUDIO_CODEC_SUPPORTED_CHANNEL_COUNT_1 + BLE_SVC_AUDIO_PACS_LC3_SNK_MIN_OCTETS_PER_CODEC_FRAME: 40 + BLE_SVC_AUDIO_PACS_LC3_SNK_MAX_OCTETS_PER_CODEC_FRAME: 60 + BLE_SVC_AUDIO_PACS_LC3_SNK_MAX_CODEC_FRAMES_PER_SDU: 1 diff --git a/nimble/host/audio/syscfg.yml b/nimble/host/audio/syscfg.yml index 5368e503e7..a5c8907f69 100644 --- a/nimble/host/audio/syscfg.yml +++ b/nimble/host/audio/syscfg.yml @@ -100,3 +100,4 @@ syscfg.logs.BLE_AUDIO_SCAN_DELEGATOR: syscfg.vals.BLE_AUDIO_BROADCAST_SINK: BLE_AUDIO_SCAN_DELEGATOR: 1 BLE_AUDIO_SCAN_DELEGATOR_STANDALONE: 0 + BLE_AUDIO_MAX_CODEC_RECORDS: 2 From 779ab041468d6be92ce14bdb65a3deb0eef4707e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 10 May 2024 08:20:03 +0200 Subject: [PATCH 1026/1333] apps/auracast_usb: fix crash on to much/corrupted data on USB If USB pushes more data then it should, handle it more gracefully. --- apps/auracast_usb/src/audio_usb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/auracast_usb/src/audio_usb.c b/apps/auracast_usb/src/audio_usb.c index d0c5fee411..3d51be5197 100644 --- a/apps/auracast_usb/src/audio_usb.c +++ b/apps/auracast_usb/src/audio_usb.c @@ -154,7 +154,11 @@ usb_data_func(struct os_event *ev) } while ((num_bytes = tud_audio_available()) > 0) { - num_samples = num_bytes / AUDIO_SAMPLE_SIZE; + num_frames = num_bytes / (AUDIO_CHANNELS * AUDIO_SAMPLE_SIZE); + num_samples = num_frames * AUDIO_CHANNELS; + if (out_idx + num_samples >= ARRAY_SIZE(out_buf)) { + num_samples = ARRAY_SIZE(out_buf) - out_idx - 1; + } num_frames = num_samples / AUDIO_CHANNELS; num_bytes = num_frames * AUDIO_SAMPLE_SIZE * AUDIO_CHANNELS; From 79605be9a089dc70102ca0cf5494a41c7145bc10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 10 May 2024 08:22:05 +0200 Subject: [PATCH 1027/1333] apps/auracast_usb: adds support for all LC3 samplerates Only 44.1 is unsupported, rest should be configurable. --- apps/auracast_usb/src/main.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/auracast_usb/src/main.c b/apps/auracast_usb/src/main.c index fcf4fd397d..c64fca90f7 100644 --- a/apps/auracast_usb/src/main.c +++ b/apps/auracast_usb/src/main.c @@ -32,15 +32,21 @@ #define BROADCAST_SID 1 #define BROADCAST_SDU_INTVL MYNEWT_VAL(LC3_FRAME_DURATION) -#if (MYNEWT_VAL(LC3_BITRATE) == 24000) + +#if (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 8000) +#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_8000_HZ +#elif (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 16000) +#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_16000_HZ +#elif (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 24000) #define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_24000_HZ -#elif (MYNEWT_VAL(LC3_BITRATE) == 48000) +#elif (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 32000) +#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_32000_HZ +#elif (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 48000) #define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_48000_HZ -#elif (MYNEWT_VAL(LC3_BITRATE) == 96000) -#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_96000_HZ #else -BUILD_ASSERT(0, "Only 24kHz and 48kHz supported"); +BUILD_ASSERT(0, "Sample frequency not supported"); #endif + #define BROADCAST_MAX_SDU (BROADCAST_SDU_INTVL * \ MYNEWT_VAL(LC3_BITRATE) / \ (1000 * 1000 * 8) * \ From 18970d976a15eda90ae0ecf629d4edf5c33d2b8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 10 May 2024 08:42:47 +0200 Subject: [PATCH 1028/1333] apps/auracast_usb: fix broadcast with HCI feedback disabled When HCI feedback is disabled, we shall use LC3 internal resampler. Adjusted samplerate on LC3 input to accomodate this. --- apps/auracast_usb/src/app_priv.h | 6 +++++- apps/auracast_usb/src/audio_usb.c | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/auracast_usb/src/app_priv.h b/apps/auracast_usb/src/app_priv.h index 87a901a71b..5304e08241 100644 --- a/apps/auracast_usb/src/app_priv.h +++ b/apps/auracast_usb/src/app_priv.h @@ -28,12 +28,16 @@ #define AUDIO_CHANNELS MYNEWT_VAL(AURACAST_CHAN_NUM) #define AUDIO_SAMPLE_SIZE sizeof(int16_t) +#if MYNEWT_VAL(ISO_HCI_FEEDBACK) +#define AUDIO_PCM_SAMPLE_RATE LC3_SAMPLING_FREQ +#else #define AUDIO_PCM_SAMPLE_RATE MYNEWT_VAL(USB_AUDIO_OUT_SAMPLE_RATE) +#endif #define LC3_FRAME_DURATION (MYNEWT_VAL(LC3_FRAME_DURATION)) #define LC3_SAMPLING_FREQ (MYNEWT_VAL(LC3_SAMPLING_FREQ)) #define LC3_BITRATE (MYNEWT_VAL(LC3_BITRATE)) -#define LC3_FPDT (LC3_SAMPLING_FREQ * LC3_FRAME_DURATION / 1000000) +#define LC3_FPDT (AUDIO_PCM_SAMPLE_RATE * LC3_FRAME_DURATION / 1000000) #define BIG_NUM_BIS (MIN(AUDIO_CHANNELS, MYNEWT_VAL(BIG_NUM_BIS))) struct chan { diff --git a/apps/auracast_usb/src/audio_usb.c b/apps/auracast_usb/src/audio_usb.c index 3d51be5197..933a04d872 100644 --- a/apps/auracast_usb/src/audio_usb.c +++ b/apps/auracast_usb/src/audio_usb.c @@ -60,7 +60,7 @@ static int16_t samples_read[AUDIO_BUF_SIZE]; /* 155 is maximum value Octets Per Codec Frame described in Table 3.5 of BAP specification */ static float samples_read_float[AUDIO_BUF_SIZE]; static float resampled_float[AUDIO_BUF_SIZE]; -float resampler_in_rate = AUDIO_PCM_SAMPLE_RATE; +float resampler_in_rate = MYNEWT_VAL(USB_AUDIO_OUT_SAMPLE_RATE); float resampler_out_rate = LC3_SAMPLING_FREQ; float resampler_ratio; SRC_STATE *resampler_state; @@ -250,14 +250,14 @@ audio_usb_init(void) usb_desc_sample_rate_set(AUDIO_PCM_SAMPLE_RATE); assert(LC3_FPDT == lc3_frame_samples(LC3_FRAME_DURATION, - LC3_SAMPLING_FREQ)); + AUDIO_PCM_SAMPLE_RATE)); unsigned esize = lc3_encoder_size(LC3_FRAME_DURATION, - LC3_SAMPLING_FREQ); + AUDIO_PCM_SAMPLE_RATE); for (int i = 0; i < AUDIO_CHANNELS; i++) { chans[i].encoder = calloc(1, esize); lc3_setup_encoder(LC3_FRAME_DURATION, LC3_SAMPLING_FREQ, - 0, chans[i].encoder); + AUDIO_PCM_SAMPLE_RATE, chans[i].encoder); } g_usb_enabled = 1; From debd4738ba0ec6e6645959a900a3dbce15710281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 10 May 2024 08:44:22 +0200 Subject: [PATCH 1029/1333] apps/auracast_usb: adjust config for disabled resampler Resampler only works fast enough for low output samplerates. Set higher quality as default, and disable resampler - use one from LC3. --- apps/auracast_usb/syscfg.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/auracast_usb/syscfg.yml b/apps/auracast_usb/syscfg.yml index 1cad13b557..0796128343 100644 --- a/apps/auracast_usb/syscfg.yml +++ b/apps/auracast_usb/syscfg.yml @@ -18,7 +18,7 @@ syscfg.defs: ISO_HCI_FEEDBACK: description: Enable HCI feedback for resampler. This reduces jitter between USB and ISO. - value: 1 + value: 0 AURACAST_CHAN_NUM: 2 @@ -37,10 +37,10 @@ syscfg.defs: value: 10000 LC3_SAMPLING_FREQ: description: LC3 sampling frequency - value: 24000 + value: 48000 LC3_BITRATE: description: LC3 bitrate - value: 24000 + value: 96000 BIG_PHY: description: From 8561044141fcbfcf56375c3c2f5aa25a9c9ad47a Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Thu, 4 Jul 2024 15:06:52 +0200 Subject: [PATCH 1030/1333] ci: Add PR labeler Adds a new workflow for adding labels to Pull Requests. The labels are based on the paths of changed files. --- .github/labeler_cfg.yml | 26 ++++++++++++++++++++++++ .github/workflows/labeler.yml | 38 +++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 .github/labeler_cfg.yml create mode 100644 .github/workflows/labeler.yml diff --git a/.github/labeler_cfg.yml b/.github/labeler_cfg.yml new file mode 100644 index 0000000000..cc4f6abb21 --- /dev/null +++ b/.github/labeler_cfg.yml @@ -0,0 +1,26 @@ +# +# 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. +# + +host: + - changed-files: + - any-glob-to-any-file: nimble/host/** + +controller: + - changed-files: + - any-glob-to-any-file: nimble/controller/** diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 0000000000..7c2d296d19 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,38 @@ +# +# 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. +# + +name: "Pull Request Labeler" +on: + - pull_request + +jobs: + labeler: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Assign labels based on paths + uses: actions/labeler@v5 + with: + sync-labels: true + configuration-path: .github/labeler_cfg.yml From 9b8368b5807b8101b1380c1605f77d6e56832381 Mon Sep 17 00:00:00 2001 From: sjanc <10303625+sjanc@users.noreply.github.com> Date: Mon, 22 Jul 2024 14:10:55 +0000 Subject: [PATCH 1031/1333] porting: Update ports syscfg --- .../examples/linux/include/syscfg/syscfg.h | 82 +-- .../linux_blemesh/include/syscfg/syscfg.h | 109 +--- .../examples/nuttx/include/syscfg/syscfg.h | 84 +-- porting/nimble/include/syscfg/syscfg.h | 79 +-- porting/npl/riot/include/syscfg/syscfg.h | 554 ++++++++++++++---- 5 files changed, 522 insertions(+), 386 deletions(-) diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index 3c62cc3ca4..07d3945cda 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -1,21 +1,28 @@ -/** - * This file was generated by Apache newt version: 1.12.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_MYNEWT_SYSCFG_ #define H_MYNEWT_SYSCFG_ -/** - * This macro exists to ensure code includes this header when needed. If code - * checks the existence of a setting directly via ifdef without including this - * header, the setting macro will silently evaluate to 0. In contrast, an - * attempt to use these macros without including this header will result in a - * compiler error. - */ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val -/*** @apache-mynewt-core/crypto/tinycrypt */ #ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE #define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) #endif @@ -28,12 +35,10 @@ #define MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG (0) #endif -/*** @apache-mynewt-core/hw/bsp/native */ #ifndef MYNEWT_VAL_BSP_SIMULATED #define MYNEWT_VAL_BSP_SIMULATED (1) #endif -/*** @apache-mynewt-core/hw/hal */ #ifndef MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS #define MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS (1) #endif @@ -62,7 +67,6 @@ #define MYNEWT_VAL_HAL_SYSTEM_RESET_CB (0) #endif -/*** @apache-mynewt-core/hw/mcu/native */ #ifndef MYNEWT_VAL_I2C_0 #define MYNEWT_VAL_I2C_0 (0) #endif @@ -95,7 +99,6 @@ #define MYNEWT_VAL_MCU_UART_POLLER_PRIO (1) #endif -/*** @apache-mynewt-core/kernel/os */ #ifndef MYNEWT_VAL_FLOAT_USER #define MYNEWT_VAL_FLOAT_USER (0) #endif @@ -152,7 +155,6 @@ #define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (0) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_CRASH_FILE_LINE #define MYNEWT_VAL_OS_CRASH_FILE_LINE (1) #endif @@ -197,7 +199,6 @@ #define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX (600000) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN #define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (1) #endif @@ -266,7 +267,6 @@ #define MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME (0) #endif -/* Overridden by @apache-mynewt-core/hw/mcu/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_TICKS_PER_SEC #define MYNEWT_VAL_OS_TICKS_PER_SEC (100) #endif @@ -287,7 +287,6 @@ #define MYNEWT_VAL_WATCHDOG_INTERVAL (30000) #endif -/*** @apache-mynewt-core/net/ip/native_sockets */ #ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX #define MYNEWT_VAL_NATIVE_SOCKETS_MAX (8) #endif @@ -314,7 +313,6 @@ #define MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE (200) #endif -/*** @apache-mynewt-core/sys/console/stub */ #ifndef MYNEWT_VAL_CONSOLE_UART_BAUD #define MYNEWT_VAL_CONSOLE_UART_BAUD (115200) #endif @@ -327,7 +325,6 @@ #define MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL (UART_FLOW_CTL_NONE) #endif -/*** @apache-mynewt-core/sys/flash_map */ #ifndef MYNEWT_VAL_FLASH_MAP_MAX_AREAS #define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10) #endif @@ -340,7 +337,6 @@ #define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (9) #endif -/*** @apache-mynewt-core/sys/log/common */ #ifndef MYNEWT_VAL_DFLT_LOG_LVL #define MYNEWT_VAL_DFLT_LOG_LVL (1) #endif @@ -353,7 +349,6 @@ #define MYNEWT_VAL_LOG_GLOBAL_IDX (1) #endif -/*** @apache-mynewt-core/sys/log/modlog */ #ifndef MYNEWT_VAL_MODLOG_CONSOLE_DFLT #define MYNEWT_VAL_MODLOG_CONSOLE_DFLT (1) #endif @@ -374,7 +369,6 @@ #define MYNEWT_VAL_MODLOG_SYSINIT_STAGE (100) #endif -/*** @apache-mynewt-core/sys/log/stub */ #ifndef MYNEWT_VAL_LOG_CONSOLE #define MYNEWT_VAL_LOG_CONSOLE (1) #endif @@ -387,17 +381,14 @@ #define MYNEWT_VAL_LOG_FCB_SLOT1 (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux (defined by @apache-mynewt-core/sys/log/stub) */ #ifndef MYNEWT_VAL_LOG_LEVEL #define MYNEWT_VAL_LOG_LEVEL (0) #endif -/*** @apache-mynewt-core/sys/sys */ #ifndef MYNEWT_VAL_DEBUG_PANIC_ENABLED #define MYNEWT_VAL_DEBUG_PANIC_ENABLED (1) #endif -/*** @apache-mynewt-core/sys/sysdown */ #ifndef MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN #define MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN (1) #endif @@ -414,27 +405,26 @@ #define MYNEWT_VAL_SYSDOWN_TIMEOUT_MS (10000) #endif -/*** @apache-mynewt-core/sys/sysinit */ #ifndef MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT #define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE #define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (1) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_MESSAGE #define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (1) #endif -/*** @apache-mynewt-core/util/rwlock */ #ifndef MYNEWT_VAL_RWLOCK_DEBUG #define MYNEWT_VAL_RWLOCK_DEBUG (0) #endif -/*** @apache-mynewt-nimble/nimble */ +#ifndef MYNEWT_VAL_BLE_CHANNEL_SOUNDING +#define MYNEWT_VAL_BLE_CHANNEL_SOUNDING (0) +#endif + #ifndef MYNEWT_VAL_BLE_CONN_SUBRATING #define MYNEWT_VAL_BLE_CONN_SUBRATING (0) #endif @@ -531,7 +521,6 @@ #define MYNEWT_VAL_BLE_WHITELIST (1) #endif -/*** @apache-mynewt-nimble/nimble/host */ #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) #endif @@ -892,7 +881,6 @@ #define MYNEWT_VAL_BLE_STORE_MAX_CCCDS (8) #endif -/*** @apache-mynewt-nimble/nimble/host/services/ans */ #ifndef MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT #define MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT (0) #endif @@ -905,7 +893,6 @@ #define MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT (0) #endif -/*** @apache-mynewt-nimble/nimble/host/services/bas */ #ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE #define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE (1) #endif @@ -918,7 +905,6 @@ #define MYNEWT_VAL_BLE_SVC_BAS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/dis */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM (-1) #endif @@ -927,7 +913,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM (-1) #endif @@ -936,7 +921,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM (-1) #endif @@ -945,7 +929,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM (-1) #endif @@ -962,7 +945,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM (-1) #endif @@ -971,7 +953,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM (-1) #endif @@ -984,12 +965,10 @@ #define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM (-1) #endif -/*** @apache-mynewt-nimble/nimble/host/services/gap */ #ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE #define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE (0) #endif @@ -1034,32 +1013,26 @@ #define MYNEWT_VAL_BLE_SVC_GAP_SYSINIT_STAGE (301) #endif -/*** @apache-mynewt-nimble/nimble/host/services/gatt */ #ifndef MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE (302) #endif -/*** @apache-mynewt-nimble/nimble/host/services/ias */ #ifndef MYNEWT_VAL_BLE_SVC_IAS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_IAS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/ipss */ #ifndef MYNEWT_VAL_BLE_SVC_IPSS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_IPSS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/lls */ #ifndef MYNEWT_VAL_BLE_SVC_LLS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_LLS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/tps */ #ifndef MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/transport */ #undef MYNEWT_VAL_BLE_ACL_BUF_COUNT #undef MYNEWT_VAL_BLE_ACL_BUF_SIZE @@ -1118,12 +1091,10 @@ #define MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ACL_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ACL_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT (10) #endif @@ -1173,12 +1144,10 @@ #define MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ISO_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ISO_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT (10) #endif @@ -1187,7 +1156,6 @@ #define MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE (300) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 #define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) #endif @@ -1216,7 +1184,6 @@ #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif -/*** @apache-mynewt-nimble/nimble/transport/socket */ #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif @@ -1225,12 +1192,10 @@ #define MYNEWT_VAL_BLE_SOCK_LINUX_DEV (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_STACK_SIZE #define MYNEWT_VAL_BLE_SOCK_STACK_SIZE (1028) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_TASK_PRIO #define MYNEWT_VAL_BLE_SOCK_TASK_PRIO (3) #endif @@ -1239,7 +1204,6 @@ #define MYNEWT_VAL_BLE_SOCK_TCP_PORT (14433) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE #define MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE (1) #endif @@ -1248,12 +1212,10 @@ #define MYNEWT_VAL_BLE_SOCK_USE_NUTTX (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_TCP #define MYNEWT_VAL_BLE_SOCK_USE_TCP (0) #endif -/*** newt */ #ifndef MYNEWT_VAL_APP_NAME #define MYNEWT_VAL_APP_NAME "dummy_app" #endif @@ -1294,7 +1256,6 @@ #define MYNEWT_VAL_TARGET_linux (1) #endif -/*** Included packages */ #define MYNEWT_PKG_apache_mynewt_core__compiler_sim 1 #define MYNEWT_PKG_apache_mynewt_core__crypto_tinycrypt 1 #define MYNEWT_PKG_apache_mynewt_core__hw_bsp_native 1 @@ -1339,7 +1300,6 @@ #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_linux 1 -/*** Included APIs */ #define MYNEWT_API_TRNG_HW_IMPL 1 #define MYNEWT_API_ble_transport 1 #define MYNEWT_API_console 1 diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index e16ecb5b14..a5ab87a6bd 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -1,21 +1,28 @@ -/** - * This file was generated by Apache newt version: 1.12.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_MYNEWT_SYSCFG_ #define H_MYNEWT_SYSCFG_ -/** - * This macro exists to ensure code includes this header when needed. If code - * checks the existence of a setting directly via ifdef without including this - * header, the setting macro will silently evaluate to 0. In contrast, an - * attempt to use these macros without including this header will result in a - * compiler error. - */ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val -/*** @apache-mynewt-core/crypto/tinycrypt */ #ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE #define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) #endif @@ -28,12 +35,10 @@ #define MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG (0) #endif -/*** @apache-mynewt-core/hw/bsp/native */ #ifndef MYNEWT_VAL_BSP_SIMULATED #define MYNEWT_VAL_BSP_SIMULATED (1) #endif -/*** @apache-mynewt-core/hw/hal */ #ifndef MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS #define MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS (1) #endif @@ -62,7 +67,6 @@ #define MYNEWT_VAL_HAL_SYSTEM_RESET_CB (0) #endif -/*** @apache-mynewt-core/hw/mcu/native */ #ifndef MYNEWT_VAL_I2C_0 #define MYNEWT_VAL_I2C_0 (0) #endif @@ -95,12 +99,10 @@ #define MYNEWT_VAL_MCU_UART_POLLER_PRIO (1) #endif -/*** @apache-mynewt-core/kernel/os */ #ifndef MYNEWT_VAL_FLOAT_USER #define MYNEWT_VAL_FLOAT_USER (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_MSYS_1_BLOCK_COUNT #define MYNEWT_VAL_MSYS_1_BLOCK_COUNT (80) #endif @@ -153,7 +155,6 @@ #define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (0) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_CRASH_FILE_LINE #define MYNEWT_VAL_OS_CRASH_FILE_LINE (1) #endif @@ -198,7 +199,6 @@ #define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX (600000) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN #define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (1) #endif @@ -267,7 +267,6 @@ #define MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME (0) #endif -/* Overridden by @apache-mynewt-core/hw/mcu/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_TICKS_PER_SEC #define MYNEWT_VAL_OS_TICKS_PER_SEC (100) #endif @@ -288,7 +287,6 @@ #define MYNEWT_VAL_WATCHDOG_INTERVAL (30000) #endif -/*** @apache-mynewt-core/net/ip/native_sockets */ #ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX #define MYNEWT_VAL_NATIVE_SOCKETS_MAX (8) #endif @@ -315,7 +313,6 @@ #define MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE (200) #endif -/*** @apache-mynewt-core/sys/console/stub */ #ifndef MYNEWT_VAL_CONSOLE_UART_BAUD #define MYNEWT_VAL_CONSOLE_UART_BAUD (115200) #endif @@ -328,7 +325,6 @@ #define MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL (UART_FLOW_CTL_NONE) #endif -/*** @apache-mynewt-core/sys/flash_map */ #ifndef MYNEWT_VAL_FLASH_MAP_MAX_AREAS #define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10) #endif @@ -341,7 +337,6 @@ #define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (9) #endif -/*** @apache-mynewt-core/sys/log/common */ #ifndef MYNEWT_VAL_DFLT_LOG_LVL #define MYNEWT_VAL_DFLT_LOG_LVL (1) #endif @@ -354,7 +349,6 @@ #define MYNEWT_VAL_LOG_GLOBAL_IDX (1) #endif -/*** @apache-mynewt-core/sys/log/modlog */ #ifndef MYNEWT_VAL_MODLOG_CONSOLE_DFLT #define MYNEWT_VAL_MODLOG_CONSOLE_DFLT (1) #endif @@ -375,7 +369,6 @@ #define MYNEWT_VAL_MODLOG_SYSINIT_STAGE (100) #endif -/*** @apache-mynewt-core/sys/log/stub */ #ifndef MYNEWT_VAL_LOG_CONSOLE #define MYNEWT_VAL_LOG_CONSOLE (1) #endif @@ -388,17 +381,14 @@ #define MYNEWT_VAL_LOG_FCB_SLOT1 (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-core/sys/log/stub) */ #ifndef MYNEWT_VAL_LOG_LEVEL #define MYNEWT_VAL_LOG_LEVEL (0) #endif -/*** @apache-mynewt-core/sys/sys */ #ifndef MYNEWT_VAL_DEBUG_PANIC_ENABLED #define MYNEWT_VAL_DEBUG_PANIC_ENABLED (1) #endif -/*** @apache-mynewt-core/sys/sysdown */ #ifndef MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN #define MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN (1) #endif @@ -415,27 +405,26 @@ #define MYNEWT_VAL_SYSDOWN_TIMEOUT_MS (10000) #endif -/*** @apache-mynewt-core/sys/sysinit */ #ifndef MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT #define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE #define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (1) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_MESSAGE #define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (1) #endif -/*** @apache-mynewt-core/util/rwlock */ #ifndef MYNEWT_VAL_RWLOCK_DEBUG #define MYNEWT_VAL_RWLOCK_DEBUG (0) #endif -/*** @apache-mynewt-nimble/nimble */ +#ifndef MYNEWT_VAL_BLE_CHANNEL_SOUNDING +#define MYNEWT_VAL_BLE_CHANNEL_SOUNDING (0) +#endif + #ifndef MYNEWT_VAL_BLE_CONN_SUBRATING #define MYNEWT_VAL_BLE_CONN_SUBRATING (0) #endif @@ -532,7 +521,6 @@ #define MYNEWT_VAL_BLE_WHITELIST (1) #endif -/*** @apache-mynewt-nimble/nimble/host */ #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) #endif @@ -821,7 +809,6 @@ #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host) */ #ifndef MYNEWT_VAL_BLE_MESH #define MYNEWT_VAL_BLE_MESH (1) #endif @@ -870,7 +857,6 @@ #define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (0) #endif -/* Overridden by @apache-mynewt-nimble/nimble/host (defined by @apache-mynewt-nimble/nimble/host) */ #ifndef MYNEWT_VAL_BLE_SM_SC #define MYNEWT_VAL_BLE_SM_SC (1) #endif @@ -895,7 +881,6 @@ #define MYNEWT_VAL_BLE_STORE_MAX_CCCDS (8) #endif -/*** @apache-mynewt-nimble/nimble/host/mesh */ #ifndef MYNEWT_VAL_BLE_MESH_ACCESS_LAYER_MSG #define MYNEWT_VAL_BLE_MESH_ACCESS_LAYER_MSG (1) #endif @@ -912,7 +897,6 @@ #define MYNEWT_VAL_BLE_MESH_ADV (1) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT #define MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT (20) #endif @@ -941,7 +925,6 @@ #define MYNEWT_VAL_BLE_MESH_ADV_TASK_PRIO (9) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_APP_KEY_COUNT #define MYNEWT_VAL_BLE_MESH_APP_KEY_COUNT (4) #endif @@ -974,7 +957,6 @@ #define MYNEWT_VAL_BLE_MESH_CDB_SUBNET_COUNT (1) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_CFG_CLI #define MYNEWT_VAL_BLE_MESH_CFG_CLI (1) #endif @@ -1015,7 +997,6 @@ #define MYNEWT_VAL_BLE_MESH_DEV_UUID (((uint8_t[16]){0x11, 0x22, 0})) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_FRIEND #define MYNEWT_VAL_BLE_MESH_FRIEND (1) #endif @@ -1056,7 +1037,6 @@ #define MYNEWT_VAL_BLE_MESH_GATT (1) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_GATT_PROXY #define MYNEWT_VAL_BLE_MESH_GATT_PROXY (1) #endif @@ -1089,12 +1069,10 @@ #define MYNEWT_VAL_BLE_MESH_IV_UPDATE_SEQ_LIMIT (0x800000) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_IV_UPDATE_TEST #define MYNEWT_VAL_BLE_MESH_IV_UPDATE_TEST (1) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_LABEL_COUNT #define MYNEWT_VAL_BLE_MESH_LABEL_COUNT (2) #endif @@ -1111,7 +1089,6 @@ #define MYNEWT_VAL_BLE_MESH_LOOPBACK_BUFS (3) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_LOW_POWER #define MYNEWT_VAL_BLE_MESH_LOW_POWER (1) #endif @@ -1124,7 +1101,6 @@ #define MYNEWT_VAL_BLE_MESH_LOW_POWER_LOG_MOD (15) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_LPN_AUTO #define MYNEWT_VAL_BLE_MESH_LPN_AUTO (0) #endif @@ -1181,7 +1157,6 @@ #define MYNEWT_VAL_BLE_MESH_MODEL_EXTENSIONS (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_MODEL_GROUP_COUNT #define MYNEWT_VAL_BLE_MESH_MODEL_GROUP_COUNT (2) #endif @@ -1198,7 +1173,6 @@ #define MYNEWT_VAL_BLE_MESH_MODEL_LOG_MOD (16) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_MODEL_VND_MSG_CID_FORCE #define MYNEWT_VAL_BLE_MESH_MODEL_VND_MSG_CID_FORCE (1) #endif @@ -1255,7 +1229,6 @@ #define MYNEWT_VAL_BLE_MESH_OOB_OUTPUT_SIZE (4) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_PB_ADV #define MYNEWT_VAL_BLE_MESH_PB_ADV (1) #endif @@ -1264,7 +1237,6 @@ #define MYNEWT_VAL_BLE_MESH_PB_ADV_RETRANS_TIMEOUT (500) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_PB_GATT #define MYNEWT_VAL_BLE_MESH_PB_GATT (1) #endif @@ -1273,7 +1245,6 @@ #define MYNEWT_VAL_BLE_MESH_PB_GATT_USE_DEVICE_NAME (1) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_PROV #define MYNEWT_VAL_BLE_MESH_PROV (1) #endif @@ -1314,7 +1285,6 @@ #define MYNEWT_VAL_BLE_MESH_PROV_OOB_PUBLIC_KEY (0) #endif -/* Overridden by @apache-mynewt-nimble/nimble/host/mesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_PROXY #define MYNEWT_VAL_BLE_MESH_PROXY (1) #endif @@ -1331,7 +1301,6 @@ #define MYNEWT_VAL_BLE_MESH_PROXY_LOG_MOD (19) #endif -/* Overridden by @apache-mynewt-nimble/nimble/host/mesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN #define MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN (33) #endif @@ -1340,12 +1309,10 @@ #define MYNEWT_VAL_BLE_MESH_PROXY_USE_DEVICE_NAME (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_RELAY #define MYNEWT_VAL_BLE_MESH_RELAY (1) #endif -/* Value copied from BLE_MESH_RELAY */ #ifndef MYNEWT_VAL_BLE_MESH_RELAY_ENABLED #define MYNEWT_VAL_BLE_MESH_RELAY_ENABLED (1) #endif @@ -1390,7 +1357,6 @@ #define MYNEWT_VAL_BLE_MESH_SEQ_STORE_RATE (128) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_SETTINGS #define MYNEWT_VAL_BLE_MESH_SETTINGS (0) #endif @@ -1403,7 +1369,6 @@ #define MYNEWT_VAL_BLE_MESH_SETTINGS_LOG_MOD (20) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_SHELL #define MYNEWT_VAL_BLE_MESH_SHELL (0) #endif @@ -1416,7 +1381,6 @@ #define MYNEWT_VAL_BLE_MESH_STORE_TIMEOUT (2) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_SUBNET_COUNT #define MYNEWT_VAL_BLE_MESH_SUBNET_COUNT (2) #endif @@ -1429,7 +1393,6 @@ #define MYNEWT_VAL_BLE_MESH_SYSINIT_STAGE_SHELL (1000) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_TESTING #define MYNEWT_VAL_BLE_MESH_TESTING (1) #endif @@ -1442,7 +1405,6 @@ #define MYNEWT_VAL_BLE_MESH_TRANS_LOG_MOD (21) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ #ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_MAX #define MYNEWT_VAL_BLE_MESH_TX_SEG_MAX (6) #endif @@ -1467,7 +1429,6 @@ #define MYNEWT_VAL_BLE_MESH_UNPROV_BEACON_INT (5) #endif -/*** @apache-mynewt-nimble/nimble/host/services/ans */ #ifndef MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT #define MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT (0) #endif @@ -1480,7 +1441,6 @@ #define MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT (0) #endif -/*** @apache-mynewt-nimble/nimble/host/services/bas */ #ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE #define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE (1) #endif @@ -1493,7 +1453,6 @@ #define MYNEWT_VAL_BLE_SVC_BAS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/dis */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM (-1) #endif @@ -1502,7 +1461,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM (-1) #endif @@ -1511,7 +1469,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM (-1) #endif @@ -1520,7 +1477,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM (-1) #endif @@ -1537,7 +1493,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM (-1) #endif @@ -1546,7 +1501,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM (-1) #endif @@ -1559,12 +1513,10 @@ #define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM (-1) #endif -/*** @apache-mynewt-nimble/nimble/host/services/gap */ #ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE #define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE (0) #endif @@ -1609,32 +1561,26 @@ #define MYNEWT_VAL_BLE_SVC_GAP_SYSINIT_STAGE (301) #endif -/*** @apache-mynewt-nimble/nimble/host/services/gatt */ #ifndef MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE (302) #endif -/*** @apache-mynewt-nimble/nimble/host/services/ias */ #ifndef MYNEWT_VAL_BLE_SVC_IAS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_IAS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/ipss */ #ifndef MYNEWT_VAL_BLE_SVC_IPSS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_IPSS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/lls */ #ifndef MYNEWT_VAL_BLE_SVC_LLS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_LLS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/tps */ #ifndef MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/transport */ #undef MYNEWT_VAL_BLE_ACL_BUF_COUNT #undef MYNEWT_VAL_BLE_ACL_BUF_SIZE @@ -1693,12 +1639,10 @@ #define MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ACL_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ACL_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT (10) #endif @@ -1748,12 +1692,10 @@ #define MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ISO_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ISO_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT (10) #endif @@ -1762,7 +1704,6 @@ #define MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE (300) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 #define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) #endif @@ -1791,7 +1732,6 @@ #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif -/*** @apache-mynewt-nimble/nimble/transport/socket */ #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif @@ -1800,12 +1740,10 @@ #define MYNEWT_VAL_BLE_SOCK_LINUX_DEV (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_STACK_SIZE #define MYNEWT_VAL_BLE_SOCK_STACK_SIZE (1028) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_TASK_PRIO #define MYNEWT_VAL_BLE_SOCK_TASK_PRIO (3) #endif @@ -1814,7 +1752,6 @@ #define MYNEWT_VAL_BLE_SOCK_TCP_PORT (14433) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE #define MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE (1) #endif @@ -1823,12 +1760,10 @@ #define MYNEWT_VAL_BLE_SOCK_USE_NUTTX (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_TCP #define MYNEWT_VAL_BLE_SOCK_USE_TCP (0) #endif -/*** newt */ #ifndef MYNEWT_VAL_APP_NAME #define MYNEWT_VAL_APP_NAME "dummy_app" #endif @@ -1869,7 +1804,6 @@ #define MYNEWT_VAL_TARGET_linux_blemesh (1) #endif -/*** Included packages */ #define MYNEWT_PKG_apache_mynewt_core__compiler_sim 1 #define MYNEWT_PKG_apache_mynewt_core__crypto_tinycrypt 1 #define MYNEWT_PKG_apache_mynewt_core__hw_bsp_native 1 @@ -1915,7 +1849,6 @@ #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_linux_blemesh 1 -/*** Included APIs */ #define MYNEWT_API_TRNG_HW_IMPL 1 #define MYNEWT_API_ble_transport 1 #define MYNEWT_API_console 1 diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index 4740c348c3..c116f586aa 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -1,21 +1,28 @@ -/** - * This file was generated by Apache newt version: 1.12.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_MYNEWT_SYSCFG_ #define H_MYNEWT_SYSCFG_ -/** - * This macro exists to ensure code includes this header when needed. If code - * checks the existence of a setting directly via ifdef without including this - * header, the setting macro will silently evaluate to 0. In contrast, an - * attempt to use these macros without including this header will result in a - * compiler error. - */ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val -/*** @apache-mynewt-core/crypto/tinycrypt */ #ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE #define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) #endif @@ -28,12 +35,10 @@ #define MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG (0) #endif -/*** @apache-mynewt-core/hw/bsp/native */ #ifndef MYNEWT_VAL_BSP_SIMULATED #define MYNEWT_VAL_BSP_SIMULATED (1) #endif -/*** @apache-mynewt-core/hw/hal */ #ifndef MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS #define MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS (1) #endif @@ -62,7 +67,6 @@ #define MYNEWT_VAL_HAL_SYSTEM_RESET_CB (0) #endif -/*** @apache-mynewt-core/hw/mcu/native */ #ifndef MYNEWT_VAL_I2C_0 #define MYNEWT_VAL_I2C_0 (0) #endif @@ -95,7 +99,6 @@ #define MYNEWT_VAL_MCU_UART_POLLER_PRIO (1) #endif -/*** @apache-mynewt-core/kernel/os */ #ifndef MYNEWT_VAL_FLOAT_USER #define MYNEWT_VAL_FLOAT_USER (0) #endif @@ -152,7 +155,6 @@ #define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (0) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_CRASH_FILE_LINE #define MYNEWT_VAL_OS_CRASH_FILE_LINE (1) #endif @@ -197,7 +199,6 @@ #define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX (600000) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN #define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (1) #endif @@ -266,7 +267,6 @@ #define MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME (0) #endif -/* Overridden by @apache-mynewt-core/hw/mcu/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_TICKS_PER_SEC #define MYNEWT_VAL_OS_TICKS_PER_SEC (100) #endif @@ -287,7 +287,6 @@ #define MYNEWT_VAL_WATCHDOG_INTERVAL (30000) #endif -/*** @apache-mynewt-core/net/ip/native_sockets */ #ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX #define MYNEWT_VAL_NATIVE_SOCKETS_MAX (8) #endif @@ -314,7 +313,6 @@ #define MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE (200) #endif -/*** @apache-mynewt-core/sys/console/stub */ #ifndef MYNEWT_VAL_CONSOLE_UART_BAUD #define MYNEWT_VAL_CONSOLE_UART_BAUD (115200) #endif @@ -327,7 +325,6 @@ #define MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL (UART_FLOW_CTL_NONE) #endif -/*** @apache-mynewt-core/sys/flash_map */ #ifndef MYNEWT_VAL_FLASH_MAP_MAX_AREAS #define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10) #endif @@ -340,7 +337,6 @@ #define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (9) #endif -/*** @apache-mynewt-core/sys/log/common */ #ifndef MYNEWT_VAL_DFLT_LOG_LVL #define MYNEWT_VAL_DFLT_LOG_LVL (1) #endif @@ -353,7 +349,6 @@ #define MYNEWT_VAL_LOG_GLOBAL_IDX (1) #endif -/*** @apache-mynewt-core/sys/log/modlog */ #ifndef MYNEWT_VAL_MODLOG_CONSOLE_DFLT #define MYNEWT_VAL_MODLOG_CONSOLE_DFLT (1) #endif @@ -374,7 +369,6 @@ #define MYNEWT_VAL_MODLOG_SYSINIT_STAGE (100) #endif -/*** @apache-mynewt-core/sys/log/stub */ #ifndef MYNEWT_VAL_LOG_CONSOLE #define MYNEWT_VAL_LOG_CONSOLE (1) #endif @@ -387,17 +381,14 @@ #define MYNEWT_VAL_LOG_FCB_SLOT1 (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-core/sys/log/stub) */ #ifndef MYNEWT_VAL_LOG_LEVEL #define MYNEWT_VAL_LOG_LEVEL (2) #endif -/*** @apache-mynewt-core/sys/sys */ #ifndef MYNEWT_VAL_DEBUG_PANIC_ENABLED #define MYNEWT_VAL_DEBUG_PANIC_ENABLED (1) #endif -/*** @apache-mynewt-core/sys/sysdown */ #ifndef MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN #define MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN (1) #endif @@ -414,27 +405,26 @@ #define MYNEWT_VAL_SYSDOWN_TIMEOUT_MS (10000) #endif -/*** @apache-mynewt-core/sys/sysinit */ #ifndef MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT #define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE #define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (1) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_MESSAGE #define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (1) #endif -/*** @apache-mynewt-core/util/rwlock */ #ifndef MYNEWT_VAL_RWLOCK_DEBUG #define MYNEWT_VAL_RWLOCK_DEBUG (0) #endif -/*** @apache-mynewt-nimble/nimble */ +#ifndef MYNEWT_VAL_BLE_CHANNEL_SOUNDING +#define MYNEWT_VAL_BLE_CHANNEL_SOUNDING (0) +#endif + #ifndef MYNEWT_VAL_BLE_CONN_SUBRATING #define MYNEWT_VAL_BLE_CONN_SUBRATING (0) #endif @@ -531,7 +521,6 @@ #define MYNEWT_VAL_BLE_WHITELIST (1) #endif -/*** @apache-mynewt-nimble/nimble/host */ #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) #endif @@ -844,7 +833,6 @@ #define MYNEWT_VAL_BLE_SM_KEYPRESS (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/host) */ #ifndef MYNEWT_VAL_BLE_SM_LEGACY #define MYNEWT_VAL_BLE_SM_LEGACY (1) #endif @@ -869,7 +857,6 @@ #define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/host) */ #ifndef MYNEWT_VAL_BLE_SM_SC #define MYNEWT_VAL_BLE_SM_SC (1) #endif @@ -894,7 +881,6 @@ #define MYNEWT_VAL_BLE_STORE_MAX_CCCDS (8) #endif -/*** @apache-mynewt-nimble/nimble/host/services/ans */ #ifndef MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT #define MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT (0) #endif @@ -907,7 +893,6 @@ #define MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT (0) #endif -/*** @apache-mynewt-nimble/nimble/host/services/bas */ #ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE #define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE (1) #endif @@ -920,7 +905,6 @@ #define MYNEWT_VAL_BLE_SVC_BAS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/dis */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM (-1) #endif @@ -929,7 +913,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM (-1) #endif @@ -938,7 +921,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM (-1) #endif @@ -947,7 +929,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM (-1) #endif @@ -964,7 +945,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM (-1) #endif @@ -973,7 +953,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM (-1) #endif @@ -986,12 +965,10 @@ #define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM (-1) #endif -/*** @apache-mynewt-nimble/nimble/host/services/gap */ #ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE #define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE (0) #endif @@ -1036,32 +1013,26 @@ #define MYNEWT_VAL_BLE_SVC_GAP_SYSINIT_STAGE (301) #endif -/*** @apache-mynewt-nimble/nimble/host/services/gatt */ #ifndef MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE (302) #endif -/*** @apache-mynewt-nimble/nimble/host/services/ias */ #ifndef MYNEWT_VAL_BLE_SVC_IAS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_IAS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/ipss */ #ifndef MYNEWT_VAL_BLE_SVC_IPSS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_IPSS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/lls */ #ifndef MYNEWT_VAL_BLE_SVC_LLS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_LLS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/tps */ #ifndef MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/transport */ #undef MYNEWT_VAL_BLE_ACL_BUF_COUNT #undef MYNEWT_VAL_BLE_ACL_BUF_SIZE @@ -1120,12 +1091,10 @@ #define MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ACL_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ACL_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT (10) #endif @@ -1175,12 +1144,10 @@ #define MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ISO_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ISO_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT (10) #endif @@ -1189,7 +1156,6 @@ #define MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE (300) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 #define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) #endif @@ -1218,7 +1184,6 @@ #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif -/*** @apache-mynewt-nimble/nimble/transport/socket */ #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif @@ -1227,12 +1192,10 @@ #define MYNEWT_VAL_BLE_SOCK_LINUX_DEV (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_STACK_SIZE #define MYNEWT_VAL_BLE_SOCK_STACK_SIZE (1028) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_TASK_PRIO #define MYNEWT_VAL_BLE_SOCK_TASK_PRIO (3) #endif @@ -1245,17 +1208,14 @@ #define MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_NUTTX #define MYNEWT_VAL_BLE_SOCK_USE_NUTTX (1) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/nuttx (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_TCP #define MYNEWT_VAL_BLE_SOCK_USE_TCP (0) #endif -/*** newt */ #ifndef MYNEWT_VAL_APP_NAME #define MYNEWT_VAL_APP_NAME "dummy_app" #endif @@ -1296,7 +1256,6 @@ #define MYNEWT_VAL_TARGET_nuttx (1) #endif -/*** Included packages */ #define MYNEWT_PKG_apache_mynewt_core__compiler_sim 1 #define MYNEWT_PKG_apache_mynewt_core__crypto_tinycrypt 1 #define MYNEWT_PKG_apache_mynewt_core__hw_bsp_native 1 @@ -1341,7 +1300,6 @@ #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_nuttx 1 -/*** Included APIs */ #define MYNEWT_API_TRNG_HW_IMPL 1 #define MYNEWT_API_ble_transport 1 #define MYNEWT_API_console 1 diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index 766a5e46e6..926b7756c1 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -1,21 +1,28 @@ -/** - * This file was generated by Apache newt version: 1.12.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_MYNEWT_SYSCFG_ #define H_MYNEWT_SYSCFG_ -/** - * This macro exists to ensure code includes this header when needed. If code - * checks the existence of a setting directly via ifdef without including this - * header, the setting macro will silently evaluate to 0. In contrast, an - * attempt to use these macros without including this header will result in a - * compiler error. - */ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val -/*** @apache-mynewt-core/crypto/tinycrypt */ #ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE #define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) #endif @@ -28,12 +35,10 @@ #define MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG (0) #endif -/*** @apache-mynewt-core/hw/bsp/native */ #ifndef MYNEWT_VAL_BSP_SIMULATED #define MYNEWT_VAL_BSP_SIMULATED (1) #endif -/*** @apache-mynewt-core/hw/hal */ #ifndef MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS #define MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS (1) #endif @@ -62,7 +67,6 @@ #define MYNEWT_VAL_HAL_SYSTEM_RESET_CB (0) #endif -/*** @apache-mynewt-core/hw/mcu/native */ #ifndef MYNEWT_VAL_I2C_0 #define MYNEWT_VAL_I2C_0 (0) #endif @@ -95,7 +99,6 @@ #define MYNEWT_VAL_MCU_UART_POLLER_PRIO (1) #endif -/*** @apache-mynewt-core/kernel/os */ #ifndef MYNEWT_VAL_FLOAT_USER #define MYNEWT_VAL_FLOAT_USER (0) #endif @@ -152,7 +155,6 @@ #define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (0) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_CRASH_FILE_LINE #define MYNEWT_VAL_OS_CRASH_FILE_LINE (1) #endif @@ -197,7 +199,6 @@ #define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX (600000) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN #define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (1) #endif @@ -266,7 +267,6 @@ #define MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME (0) #endif -/* Overridden by @apache-mynewt-core/hw/mcu/native (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_TICKS_PER_SEC #define MYNEWT_VAL_OS_TICKS_PER_SEC (100) #endif @@ -287,7 +287,6 @@ #define MYNEWT_VAL_WATCHDOG_INTERVAL (30000) #endif -/*** @apache-mynewt-core/net/ip/native_sockets */ #ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX #define MYNEWT_VAL_NATIVE_SOCKETS_MAX (8) #endif @@ -314,7 +313,6 @@ #define MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE (200) #endif -/*** @apache-mynewt-core/sys/console/stub */ #ifndef MYNEWT_VAL_CONSOLE_UART_BAUD #define MYNEWT_VAL_CONSOLE_UART_BAUD (115200) #endif @@ -327,7 +325,6 @@ #define MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL (UART_FLOW_CTL_NONE) #endif -/*** @apache-mynewt-core/sys/flash_map */ #ifndef MYNEWT_VAL_FLASH_MAP_MAX_AREAS #define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10) #endif @@ -340,7 +337,6 @@ #define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (9) #endif -/*** @apache-mynewt-core/sys/log/common */ #ifndef MYNEWT_VAL_DFLT_LOG_LVL #define MYNEWT_VAL_DFLT_LOG_LVL (1) #endif @@ -353,7 +349,6 @@ #define MYNEWT_VAL_LOG_GLOBAL_IDX (1) #endif -/*** @apache-mynewt-core/sys/log/modlog */ #ifndef MYNEWT_VAL_MODLOG_CONSOLE_DFLT #define MYNEWT_VAL_MODLOG_CONSOLE_DFLT (1) #endif @@ -374,7 +369,6 @@ #define MYNEWT_VAL_MODLOG_SYSINIT_STAGE (100) #endif -/*** @apache-mynewt-core/sys/log/stub */ #ifndef MYNEWT_VAL_LOG_CONSOLE #define MYNEWT_VAL_LOG_CONSOLE (1) #endif @@ -391,12 +385,10 @@ #define MYNEWT_VAL_LOG_LEVEL (255) #endif -/*** @apache-mynewt-core/sys/sys */ #ifndef MYNEWT_VAL_DEBUG_PANIC_ENABLED #define MYNEWT_VAL_DEBUG_PANIC_ENABLED (1) #endif -/*** @apache-mynewt-core/sys/sysdown */ #ifndef MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN #define MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN (1) #endif @@ -413,27 +405,26 @@ #define MYNEWT_VAL_SYSDOWN_TIMEOUT_MS (10000) #endif -/*** @apache-mynewt-core/sys/sysinit */ #ifndef MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT #define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE #define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (1) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ #ifndef MYNEWT_VAL_SYSINIT_PANIC_MESSAGE #define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (1) #endif -/*** @apache-mynewt-core/util/rwlock */ #ifndef MYNEWT_VAL_RWLOCK_DEBUG #define MYNEWT_VAL_RWLOCK_DEBUG (0) #endif -/*** @apache-mynewt-nimble/nimble */ +#ifndef MYNEWT_VAL_BLE_CHANNEL_SOUNDING +#define MYNEWT_VAL_BLE_CHANNEL_SOUNDING (0) +#endif + #ifndef MYNEWT_VAL_BLE_CONN_SUBRATING #define MYNEWT_VAL_BLE_CONN_SUBRATING (0) #endif @@ -530,7 +521,6 @@ #define MYNEWT_VAL_BLE_WHITELIST (1) #endif -/*** @apache-mynewt-nimble/nimble/host */ #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) #endif @@ -891,7 +881,6 @@ #define MYNEWT_VAL_BLE_STORE_MAX_CCCDS (8) #endif -/*** @apache-mynewt-nimble/nimble/host/services/ans */ #ifndef MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT #define MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT (0) #endif @@ -904,7 +893,6 @@ #define MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT (0) #endif -/*** @apache-mynewt-nimble/nimble/host/services/bas */ #ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE #define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE (1) #endif @@ -917,7 +905,6 @@ #define MYNEWT_VAL_BLE_SVC_BAS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/dis */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM (-1) #endif @@ -926,7 +913,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM (-1) #endif @@ -935,7 +921,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM (-1) #endif @@ -944,7 +929,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM (-1) #endif @@ -961,7 +945,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM (-1) #endif @@ -970,7 +953,6 @@ #define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM (-1) #endif @@ -983,12 +965,10 @@ #define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_DEFAULT (NULL) #endif -/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ #ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM #define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM (-1) #endif -/*** @apache-mynewt-nimble/nimble/host/services/gap */ #ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE #define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE (0) #endif @@ -1033,32 +1013,26 @@ #define MYNEWT_VAL_BLE_SVC_GAP_SYSINIT_STAGE (301) #endif -/*** @apache-mynewt-nimble/nimble/host/services/gatt */ #ifndef MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE (302) #endif -/*** @apache-mynewt-nimble/nimble/host/services/ias */ #ifndef MYNEWT_VAL_BLE_SVC_IAS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_IAS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/ipss */ #ifndef MYNEWT_VAL_BLE_SVC_IPSS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_IPSS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/lls */ #ifndef MYNEWT_VAL_BLE_SVC_LLS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_LLS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/host/services/tps */ #ifndef MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE (303) #endif -/*** @apache-mynewt-nimble/nimble/transport */ #undef MYNEWT_VAL_BLE_ACL_BUF_COUNT #undef MYNEWT_VAL_BLE_ACL_BUF_SIZE @@ -1117,12 +1091,10 @@ #define MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ACL_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ACL_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT (10) #endif @@ -1172,12 +1144,10 @@ #define MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ISO_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ISO_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT (10) #endif @@ -1186,7 +1156,6 @@ #define MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE (300) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/porting_default (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 #define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) #endif @@ -1215,7 +1184,6 @@ #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif -/*** @apache-mynewt-nimble/nimble/transport/socket */ #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif @@ -1236,7 +1204,6 @@ #define MYNEWT_VAL_BLE_SOCK_TCP_PORT (14433) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/porting_default (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE #define MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE (1) #endif @@ -1245,12 +1212,10 @@ #define MYNEWT_VAL_BLE_SOCK_USE_NUTTX (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/porting_default (defined by @apache-mynewt-nimble/nimble/transport/socket) */ #ifndef MYNEWT_VAL_BLE_SOCK_USE_TCP #define MYNEWT_VAL_BLE_SOCK_USE_TCP (0) #endif -/*** newt */ #ifndef MYNEWT_VAL_APP_NAME #define MYNEWT_VAL_APP_NAME "dummy_app" #endif @@ -1291,7 +1256,6 @@ #define MYNEWT_VAL_TARGET_porting_default (1) #endif -/*** Included packages */ #define MYNEWT_PKG_apache_mynewt_core__compiler_sim 1 #define MYNEWT_PKG_apache_mynewt_core__crypto_tinycrypt 1 #define MYNEWT_PKG_apache_mynewt_core__hw_bsp_native 1 @@ -1336,7 +1300,6 @@ #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_porting_default 1 -/*** Included APIs */ #define MYNEWT_API_TRNG_HW_IMPL 1 #define MYNEWT_API_ble_transport 1 #define MYNEWT_API_console 1 diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index d07ca8a179..06080e272b 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1,26 +1,310 @@ -/** - * This file was generated by Apache newt version: 1.12.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_MYNEWT_SYSCFG_ #define H_MYNEWT_SYSCFG_ -/** - * This macro exists to ensure code includes this header when needed. If code - * checks the existence of a setting directly via ifdef without including this - * header, the setting macro will silently evaluate to 0. In contrast, an - * attempt to use these macros without including this header will result in a - * compiler error. - */ #define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name #define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val -/*** @apache-mynewt-core/compiler/arm-none-eabi-m4 */ +#ifndef MYNEWT_VAL_INCLUDE_IMAGE_HEADER +#define MYNEWT_VAL_INCLUDE_IMAGE_HEADER (1) +#endif + +#undef MYNEWT_VAL_LINK_TEMPLATE + +#ifndef MYNEWT_VAL_MAIN_STACK_SIZE +#define MYNEWT_VAL_MAIN_STACK_SIZE (768) +#endif + +#ifndef MYNEWT_VAL_MCU_RAM_SIZE +#define MYNEWT_VAL_MCU_RAM_SIZE (0x40000) +#endif + +#ifndef MYNEWT_VAL_MCU_RAM_START +#define MYNEWT_VAL_MCU_RAM_START (0x20000000) +#endif + #ifndef MYNEWT_VAL_HARDFLOAT #define MYNEWT_VAL_HARDFLOAT (0) #endif -/*** @apache-mynewt-core/crypto/tinycrypt */ +#ifndef MYNEWT_VAL_MBEDTLS_AES_ALT +#define MYNEWT_VAL_MBEDTLS_AES_ALT (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_AES_C +#define MYNEWT_VAL_MBEDTLS_AES_C (1) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_AES_FEWER_TABLES +#define MYNEWT_VAL_MBEDTLS_AES_FEWER_TABLES (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_AES_ROM_TABLES +#define MYNEWT_VAL_MBEDTLS_AES_ROM_TABLES (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ARC4_C +#define MYNEWT_VAL_MBEDTLS_ARC4_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ARIA_C +#define MYNEWT_VAL_MBEDTLS_ARIA_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_BASE64_C +#define MYNEWT_VAL_MBEDTLS_BASE64_C (1) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_BIGNUM_ALT +#define MYNEWT_VAL_MBEDTLS_BIGNUM_ALT (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_BLOWFISH_C +#define MYNEWT_VAL_MBEDTLS_BLOWFISH_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_CAMELLIA_C +#define MYNEWT_VAL_MBEDTLS_CAMELLIA_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_CCM_C +#define MYNEWT_VAL_MBEDTLS_CCM_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_CHACHA20_C +#define MYNEWT_VAL_MBEDTLS_CHACHA20_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_CHACHAPOLY_C +#define MYNEWT_VAL_MBEDTLS_CHACHAPOLY_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_CIPHER_MODE_CBC +#define MYNEWT_VAL_MBEDTLS_CIPHER_MODE_CBC (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_CIPHER_MODE_CFB +#define MYNEWT_VAL_MBEDTLS_CIPHER_MODE_CFB (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_CIPHER_MODE_CTR +#define MYNEWT_VAL_MBEDTLS_CIPHER_MODE_CTR (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_CIPHER_MODE_OFB +#define MYNEWT_VAL_MBEDTLS_CIPHER_MODE_OFB (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_CIPHER_MODE_XTS +#define MYNEWT_VAL_MBEDTLS_CIPHER_MODE_XTS (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_CMAC_C +#define MYNEWT_VAL_MBEDTLS_CMAC_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_CTR_DRBG_C +#define MYNEWT_VAL_MBEDTLS_CTR_DRBG_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_DES_C +#define MYNEWT_VAL_MBEDTLS_DES_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECDH_COMPUTE_SHARED_ALT +#define MYNEWT_VAL_MBEDTLS_ECDH_COMPUTE_SHARED_ALT (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECDH_GEN_PUBLIC_ALT +#define MYNEWT_VAL_MBEDTLS_ECDH_GEN_PUBLIC_ALT (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECDSA_GENKEY_ALT +#define MYNEWT_VAL_MBEDTLS_ECDSA_GENKEY_ALT (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECDSA_SIGN_ALT +#define MYNEWT_VAL_MBEDTLS_ECDSA_SIGN_ALT (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECDSA_VERIFY_ALT +#define MYNEWT_VAL_MBEDTLS_ECDSA_VERIFY_ALT (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECJPAKE_C +#define MYNEWT_VAL_MBEDTLS_ECJPAKE_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECP_ALT +#define MYNEWT_VAL_MBEDTLS_ECP_ALT (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECP_DP_BP256R1 +#define MYNEWT_VAL_MBEDTLS_ECP_DP_BP256R1 (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECP_DP_BP384R1 +#define MYNEWT_VAL_MBEDTLS_ECP_DP_BP384R1 (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECP_DP_BP512R1 +#define MYNEWT_VAL_MBEDTLS_ECP_DP_BP512R1 (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECP_DP_CURVE25519 +#define MYNEWT_VAL_MBEDTLS_ECP_DP_CURVE25519 (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECP_DP_CURVE448 +#define MYNEWT_VAL_MBEDTLS_ECP_DP_CURVE448 (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECP_DP_SECP192K1 +#define MYNEWT_VAL_MBEDTLS_ECP_DP_SECP192K1 (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECP_DP_SECP192R1 +#define MYNEWT_VAL_MBEDTLS_ECP_DP_SECP192R1 (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECP_DP_SECP224K1 +#define MYNEWT_VAL_MBEDTLS_ECP_DP_SECP224K1 (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECP_DP_SECP224R1 +#define MYNEWT_VAL_MBEDTLS_ECP_DP_SECP224R1 (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECP_DP_SECP256K1 +#define MYNEWT_VAL_MBEDTLS_ECP_DP_SECP256K1 (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECP_DP_SECP256R1 +#define MYNEWT_VAL_MBEDTLS_ECP_DP_SECP256R1 (1) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECP_DP_SECP384R1 +#define MYNEWT_VAL_MBEDTLS_ECP_DP_SECP384R1 (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECP_DP_SECP521R1 +#define MYNEWT_VAL_MBEDTLS_ECP_DP_SECP521R1 (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ECP_RESTARTABLE +#define MYNEWT_VAL_MBEDTLS_ECP_RESTARTABLE (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ENTROPY_C +#define MYNEWT_VAL_MBEDTLS_ENTROPY_C (1) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_ENTROPY_HARDWARE_ALT +#define MYNEWT_VAL_MBEDTLS_ENTROPY_HARDWARE_ALT (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_GENPRIME +#define MYNEWT_VAL_MBEDTLS_GENPRIME (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_HKDF_C +#define MYNEWT_VAL_MBEDTLS_HKDF_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED +#define MYNEWT_VAL_MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED +#define MYNEWT_VAL_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED +#define MYNEWT_VAL_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED +#define MYNEWT_VAL_MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_MD2_C +#define MYNEWT_VAL_MBEDTLS_MD2_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_MD4_C +#define MYNEWT_VAL_MBEDTLS_MD4_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_MD5_C +#define MYNEWT_VAL_MBEDTLS_MD5_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_MPI_MAX_SIZE +#define MYNEWT_VAL_MBEDTLS_MPI_MAX_SIZE (1024) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_NIST_KW_C +#define MYNEWT_VAL_MBEDTLS_NIST_KW_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_PKCS1_V15 +#define MYNEWT_VAL_MBEDTLS_PKCS1_V15 (1) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_PKCS1_V21 +#define MYNEWT_VAL_MBEDTLS_PKCS1_V21 (1) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_POLY1305_C +#define MYNEWT_VAL_MBEDTLS_POLY1305_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_RIPEMD160_C +#define MYNEWT_VAL_MBEDTLS_RIPEMD160_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_SHA1_C +#define MYNEWT_VAL_MBEDTLS_SHA1_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_SHA256_ALT +#define MYNEWT_VAL_MBEDTLS_SHA256_ALT (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_SHA256_C +#define MYNEWT_VAL_MBEDTLS_SHA256_C (1) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_SHA512_C +#define MYNEWT_VAL_MBEDTLS_SHA512_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_SSL_TLS_C +#define MYNEWT_VAL_MBEDTLS_SSL_TLS_C (0) +#endif + +#ifndef MYNEWT_VAL_MBEDTLS_TIMING_C +#define MYNEWT_VAL_MBEDTLS_TIMING_C (0) +#endif + #ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE #define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) #endif @@ -33,7 +317,6 @@ #define MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG (0) #endif -/*** @apache-mynewt-core/hw/bsp/nordic_pca10056 */ #ifndef MYNEWT_VAL_BSP_NRF52840 #define MYNEWT_VAL_BSP_NRF52840 (1) #endif @@ -42,7 +325,6 @@ #define MYNEWT_VAL_SOFT_PWM (0) #endif -/*** @apache-mynewt-core/hw/hal */ #ifndef MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS #define MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS (1) #endif @@ -71,7 +353,6 @@ #define MYNEWT_VAL_HAL_SYSTEM_RESET_CB (0) #endif -/*** @apache-mynewt-core/hw/mcu/nordic/nrf52xxx */ #ifndef MYNEWT_VAL_ADC_0 #define MYNEWT_VAL_ADC_0 (0) #endif @@ -84,7 +365,6 @@ #define MYNEWT_VAL_CRYPTO (0) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_GPIO_AS_PIN_RESET #define MYNEWT_VAL_GPIO_AS_PIN_RESET (1) #endif @@ -97,12 +377,10 @@ #define MYNEWT_VAL_I2C_0_FREQ_KHZ (100) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_I2C_0_PIN_SCL #define MYNEWT_VAL_I2C_0_PIN_SCL (27) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_I2C_0_PIN_SDA #define MYNEWT_VAL_I2C_0_PIN_SDA (26) #endif @@ -119,7 +397,6 @@ #undef MYNEWT_VAL_I2C_1_PIN_SDA -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_MCU_ACCESS_PORT_PROTECTION__default #define MYNEWT_VAL_MCU_ACCESS_PORT_PROTECTION__default (0) #endif @@ -137,12 +414,10 @@ #define MYNEWT_VAL_MCU_BUS_DRIVER_I2C_USE_TWIM (0) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_MCU_COMMON_STARTUP #define MYNEWT_VAL_MCU_COMMON_STARTUP (1) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_MCU_DCDC_ENABLED #define MYNEWT_VAL_MCU_DCDC_ENABLED (1) #endif @@ -173,12 +448,10 @@ #define MYNEWT_VAL_MCU_I2C_RECOVERY_DELAY_USEC (100) #endif -/* Overridden by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_MCU_ICACHE_ENABLED #define MYNEWT_VAL_MCU_ICACHE_ENABLED (1) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_MCU_LFCLK_SOURCE__LFRC #define MYNEWT_VAL_MCU_LFCLK_SOURCE__LFRC (0) #endif @@ -200,7 +473,6 @@ #define MYNEWT_VAL_MCU_NRF52840 (0) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_MCU_TARGET__nRF52810 #define MYNEWT_VAL_MCU_TARGET__nRF52810 (0) #endif @@ -249,47 +521,38 @@ #define MYNEWT_VAL_QSPI_ENABLE (0) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_QSPI_FLASH_PAGE_SIZE #define MYNEWT_VAL_QSPI_FLASH_PAGE_SIZE (256) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_QSPI_FLASH_SECTOR_COUNT #define MYNEWT_VAL_QSPI_FLASH_SECTOR_COUNT (4096) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_QSPI_FLASH_SECTOR_SIZE #define MYNEWT_VAL_QSPI_FLASH_SECTOR_SIZE (4096) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_QSPI_PIN_CS #define MYNEWT_VAL_QSPI_PIN_CS (17) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_QSPI_PIN_DIO0 #define MYNEWT_VAL_QSPI_PIN_DIO0 (20) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_QSPI_PIN_DIO1 #define MYNEWT_VAL_QSPI_PIN_DIO1 (21) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_QSPI_PIN_DIO2 #define MYNEWT_VAL_QSPI_PIN_DIO2 (22) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_QSPI_PIN_DIO3 #define MYNEWT_VAL_QSPI_PIN_DIO3 (23) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_QSPI_PIN_SCK #define MYNEWT_VAL_QSPI_PIN_SCK (19) #endif @@ -318,17 +581,14 @@ #define MYNEWT_VAL_SPI_0_MASTER (0) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_SPI_0_MASTER_PIN_MISO #define MYNEWT_VAL_SPI_0_MASTER_PIN_MISO (46) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_SPI_0_MASTER_PIN_MOSI #define MYNEWT_VAL_SPI_0_MASTER_PIN_MOSI (45) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_SPI_0_MASTER_PIN_SCK #define MYNEWT_VAL_SPI_0_MASTER_PIN_SCK (47) #endif @@ -337,22 +597,18 @@ #define MYNEWT_VAL_SPI_0_SLAVE (0) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_SPI_0_SLAVE_PIN_MISO #define MYNEWT_VAL_SPI_0_SLAVE_PIN_MISO (46) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_SPI_0_SLAVE_PIN_MOSI #define MYNEWT_VAL_SPI_0_SLAVE_PIN_MOSI (45) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_SPI_0_SLAVE_PIN_SCK #define MYNEWT_VAL_SPI_0_SLAVE_PIN_SCK (47) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_SPI_0_SLAVE_PIN_SS #define MYNEWT_VAL_SPI_0_SLAVE_PIN_SS (44) #endif @@ -415,7 +671,6 @@ #define MYNEWT_VAL_TEMP (0) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_TIMER_0 #define MYNEWT_VAL_TIMER_0 (0) #endif @@ -436,7 +691,6 @@ #define MYNEWT_VAL_TIMER_4 (0) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_TIMER_5 #define MYNEWT_VAL_TIMER_5 (1) #endif @@ -449,22 +703,18 @@ #define MYNEWT_VAL_UART_0 (1) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_UART_0_PIN_CTS #define MYNEWT_VAL_UART_0_PIN_CTS (7) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_UART_0_PIN_RTS #define MYNEWT_VAL_UART_0_PIN_RTS (5) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_UART_0_PIN_RX #define MYNEWT_VAL_UART_0_PIN_RX (8) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx) */ #ifndef MYNEWT_VAL_UART_0_PIN_TX #define MYNEWT_VAL_UART_0_PIN_TX (6) #endif @@ -497,17 +747,14 @@ #define MYNEWT_VAL_XTAL_RC (0) #endif -/*** @apache-mynewt-core/kernel/os */ #ifndef MYNEWT_VAL_FLOAT_USER #define MYNEWT_VAL_FLOAT_USER (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_MSYS_1_BLOCK_COUNT #define MYNEWT_VAL_MSYS_1_BLOCK_COUNT (5) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_MSYS_1_BLOCK_SIZE #define MYNEWT_VAL_MSYS_1_BLOCK_SIZE (88) #endif @@ -548,12 +795,10 @@ #define MYNEWT_VAL_OS_COREDUMP_CB (0) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_CPUTIME_FREQ #define MYNEWT_VAL_OS_CPUTIME_FREQ (32768) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_CPUTIME_TIMER_NUM #define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (5) #endif @@ -670,7 +915,6 @@ #define MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME (0) #endif -/* Overridden by @apache-mynewt-core/hw/mcu/nordic/nrf52xxx (defined by @apache-mynewt-core/kernel/os) */ #ifndef MYNEWT_VAL_OS_TICKS_PER_SEC #define MYNEWT_VAL_OS_TICKS_PER_SEC (128) #endif @@ -691,7 +935,6 @@ #define MYNEWT_VAL_WATCHDOG_INTERVAL (30000) #endif -/*** @apache-mynewt-core/libc */ #ifndef MYNEWT_VAL_LIBC__baselibc #define MYNEWT_VAL_LIBC__baselibc (1) #endif @@ -702,7 +945,6 @@ #define MYNEWT_VAL_LIBC (1) #endif -/*** @apache-mynewt-core/libc/baselibc */ #ifndef MYNEWT_VAL_BASELIBC_ASSERT_FILE_LINE #define MYNEWT_VAL_BASELIBC_ASSERT_FILE_LINE (0) #endif @@ -719,7 +961,6 @@ #define MYNEWT_VAL_BASELIBC_THREAD_SAFE_HEAP_ALLOCATION (0) #endif -/*** @apache-mynewt-core/sys/console/stub */ #ifndef MYNEWT_VAL_CONSOLE_UART_BAUD #define MYNEWT_VAL_CONSOLE_UART_BAUD (115200) #endif @@ -732,7 +973,6 @@ #define MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL (UART_FLOW_CTL_NONE) #endif -/*** @apache-mynewt-core/sys/flash_map */ #ifndef MYNEWT_VAL_FLASH_MAP_MAX_AREAS #define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10) #endif @@ -745,7 +985,6 @@ #define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (9) #endif -/*** @apache-mynewt-core/sys/log/common */ #ifndef MYNEWT_VAL_DFLT_LOG_LVL #define MYNEWT_VAL_DFLT_LOG_LVL (1) #endif @@ -758,7 +997,6 @@ #define MYNEWT_VAL_LOG_GLOBAL_IDX (1) #endif -/*** @apache-mynewt-core/sys/log/modlog */ #ifndef MYNEWT_VAL_MODLOG_CONSOLE_DFLT #define MYNEWT_VAL_MODLOG_CONSOLE_DFLT (1) #endif @@ -779,7 +1017,6 @@ #define MYNEWT_VAL_MODLOG_SYSINIT_STAGE (100) #endif -/*** @apache-mynewt-core/sys/log/stub */ #ifndef MYNEWT_VAL_LOG_CONSOLE #define MYNEWT_VAL_LOG_CONSOLE (1) #endif @@ -796,12 +1033,10 @@ #define MYNEWT_VAL_LOG_LEVEL (255) #endif -/*** @apache-mynewt-core/sys/sys */ #ifndef MYNEWT_VAL_DEBUG_PANIC_ENABLED #define MYNEWT_VAL_DEBUG_PANIC_ENABLED (1) #endif -/*** @apache-mynewt-core/sys/sysdown */ #ifndef MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN #define MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN (1) #endif @@ -818,7 +1053,6 @@ #define MYNEWT_VAL_SYSDOWN_TIMEOUT_MS (10000) #endif -/*** @apache-mynewt-core/sys/sysinit */ #ifndef MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT #define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1) #endif @@ -831,12 +1065,14 @@ #define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (0) #endif -/*** @apache-mynewt-core/util/rwlock */ #ifndef MYNEWT_VAL_RWLOCK_DEBUG #define MYNEWT_VAL_RWLOCK_DEBUG (0) #endif -/*** @apache-mynewt-nimble/nimble */ +#ifndef MYNEWT_VAL_BLE_CHANNEL_SOUNDING +#define MYNEWT_VAL_BLE_CHANNEL_SOUNDING (0) +#endif + #ifndef MYNEWT_VAL_BLE_CONN_SUBRATING #define MYNEWT_VAL_BLE_CONN_SUBRATING (0) #endif @@ -849,7 +1085,6 @@ #define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (31) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble) */ #ifndef MYNEWT_VAL_BLE_HCI_VS #define MYNEWT_VAL_BLE_HCI_VS (1) #endif @@ -878,7 +1113,6 @@ #define MYNEWT_VAL_BLE_MAX_CONNECTIONS (1) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble) */ #ifndef MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS #define MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS (0) #endif @@ -935,7 +1169,6 @@ #define MYNEWT_VAL_BLE_WHITELIST (1) #endif -/*** @apache-mynewt-nimble/nimble/controller */ #ifndef MYNEWT_VAL_BLE_CONTROLLER #define MYNEWT_VAL_BLE_CONTROLLER (1) #endif @@ -948,7 +1181,6 @@ #define MYNEWT_VAL_BLE_FEM_ANTENNA (0) #endif -/* Value copied from BLE_LL_LNA */ #ifndef MYNEWT_VAL_BLE_FEM_LNA #define MYNEWT_VAL_BLE_FEM_LNA (0) #endif @@ -961,17 +1193,14 @@ #define MYNEWT_VAL_BLE_FEM_LNA_GAIN_TUNABLE (0) #endif -/* Value copied from BLE_LL_LNA_GPIO */ #ifndef MYNEWT_VAL_BLE_FEM_LNA_GPIO #define MYNEWT_VAL_BLE_FEM_LNA_GPIO (-1) #endif -/* Value copied from BLE_LL_LNA_TURN_ON_US */ #ifndef MYNEWT_VAL_BLE_FEM_LNA_TURN_ON_US #define MYNEWT_VAL_BLE_FEM_LNA_TURN_ON_US (1) #endif -/* Value copied from BLE_LL_PA */ #ifndef MYNEWT_VAL_BLE_FEM_PA #define MYNEWT_VAL_BLE_FEM_PA (0) #endif @@ -984,17 +1213,14 @@ #define MYNEWT_VAL_BLE_FEM_PA_GAIN_TUNABLE (0) #endif -/* Value copied from BLE_LL_PA_GPIO */ #ifndef MYNEWT_VAL_BLE_FEM_PA_GPIO #define MYNEWT_VAL_BLE_FEM_PA_GPIO (-1) #endif -/* Value copied from BLE_LL_PA_TURN_ON_US */ #ifndef MYNEWT_VAL_BLE_FEM_PA_TURN_ON_US #define MYNEWT_VAL_BLE_FEM_PA_TURN_ON_US (1) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ #ifndef MYNEWT_VAL_BLE_HW_WHITELIST_ENABLE #define MYNEWT_VAL_BLE_HW_WHITELIST_ENABLE (0) #endif @@ -1011,27 +1237,22 @@ #define MYNEWT_VAL_BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_DATA_LEN_EXT #define MYNEWT_VAL_BLE_LL_CFG_FEAT_DATA_LEN_EXT (0) #endif -/* Value copied from BLE_PHY_2M */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_2M_PHY #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_2M_PHY (0) #endif -/* Value copied from BLE_PHY_CODED */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CODED_PHY #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CODED_PHY (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CSA2 #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CSA2 (1) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION (0) #endif @@ -1044,32 +1265,26 @@ #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE (0) #endif -/* Value copied from BLE_EXT_ADV */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV (0) #endif -/* Value copied from BLE_PERIODIC_ADV */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV (0) #endif -/* Value copied from BLE_MAX_PERIODIC_SYNCS */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_CNT #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_CNT (0) #endif -/* Value copied from BLE_MAX_PERIODIC_SYNCS */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_LIST_CNT #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_LIST_CNT (0) #endif -/* Value copied from BLE_PERIODIC_ADV_SYNC_TRANSFER */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY (0) #endif @@ -1086,6 +1301,10 @@ #define MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_CHANNEL_SOUNDING +#define MYNEWT_VAL_BLE_LL_CHANNEL_SOUNDING (0) +#endif + #ifndef MYNEWT_VAL_BLE_LL_CONN_EVENT_END_MARGIN #define MYNEWT_VAL_BLE_LL_CONN_EVENT_END_MARGIN (0) #endif @@ -1094,7 +1313,6 @@ #define MYNEWT_VAL_BLE_LL_CONN_INIT_AUTO_DLE (1) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ #ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_MAX_TX_BYTES #define MYNEWT_VAL_BLE_LL_CONN_INIT_MAX_TX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE) #endif @@ -1159,7 +1377,6 @@ #define MYNEWT_VAL_BLE_LL_DIRECT_TEST_MODE (0) #endif -/* Value copied from BLE_LL_DIRECT_TEST_MODE */ #ifndef MYNEWT_VAL_BLE_LL_DTM #define MYNEWT_VAL_BLE_LL_DTM (0) #endif @@ -1184,7 +1401,6 @@ #define MYNEWT_VAL_BLE_LL_HCI_LLCP_TRACE (0) #endif -/* Value copied from BLE_HCI_VS */ #ifndef MYNEWT_VAL_BLE_LL_HCI_VS #define MYNEWT_VAL_BLE_LL_HCI_VS (1) #endif @@ -1193,7 +1409,6 @@ #define MYNEWT_VAL_BLE_LL_HCI_VS_CONN_STRICT_SCHED (0) #endif -/* Value copied from BLE_LL_VND_EVENT_ON_ASSERT */ #ifndef MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_ON_ASSERT #define MYNEWT_VAL_BLE_LL_HCI_VS_EVENT_ON_ASSERT (0) #endif @@ -1202,7 +1417,6 @@ #define MYNEWT_VAL_BLE_LL_HCI_VS_LOCAL_IRK (0) #endif -/* Value copied from BLE_ISO */ #ifndef MYNEWT_VAL_BLE_LL_ISO #define MYNEWT_VAL_BLE_LL_ISO (0) #endif @@ -1231,7 +1445,6 @@ #define MYNEWT_VAL_BLE_LL_LNA_TURN_ON_US (1) #endif -/* Value copied from BLE_LL_MFRG_ID */ #ifndef MYNEWT_VAL_BLE_LL_MANUFACTURER_ID #define MYNEWT_VAL_BLE_LL_MANUFACTURER_ID (0x0B65) #endif @@ -1276,7 +1489,6 @@ #define MYNEWT_VAL_BLE_LL_PA_TURN_ON_US (1) #endif -/* Value copied from BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS */ #ifndef MYNEWT_VAL_BLE_LL_PERIODIC_ADV_SYNC_BIGINFO_REPORTS #define MYNEWT_VAL_BLE_LL_PERIODIC_ADV_SYNC_BIGINFO_REPORTS (0) #endif @@ -1293,7 +1505,6 @@ #define MYNEWT_VAL_BLE_LL_RESOLV_LIST_SIZE (4) #endif -/* Overridden by @apache-mynewt-core/hw/bsp/nordic_pca10056 (defined by @apache-mynewt-nimble/nimble/controller) */ #ifndef MYNEWT_VAL_BLE_LL_RFMGMT_ENABLE_TIME #define MYNEWT_VAL_BLE_LL_RFMGMT_ENABLE_TIME (1500) #endif @@ -1302,32 +1513,26 @@ #define MYNEWT_VAL_BLE_LL_RNG_BUFSIZE (32) #endif -/* Value copied from BLE_ROLE_BROADCASTER */ #ifndef MYNEWT_VAL_BLE_LL_ROLE_BROADCASTER #define MYNEWT_VAL_BLE_LL_ROLE_BROADCASTER (1) #endif -/* Value copied from BLE_ROLE_CENTRAL */ #ifndef MYNEWT_VAL_BLE_LL_ROLE_CENTRAL #define MYNEWT_VAL_BLE_LL_ROLE_CENTRAL (1) #endif -/* Value copied from BLE_ROLE_OBSERVER */ #ifndef MYNEWT_VAL_BLE_LL_ROLE_OBSERVER #define MYNEWT_VAL_BLE_LL_ROLE_OBSERVER (1) #endif -/* Value copied from BLE_ROLE_PERIPHERAL */ #ifndef MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL #define MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL (1) #endif -/* Value copied from BLE_LL_OUR_SCA */ #ifndef MYNEWT_VAL_BLE_LL_SCA #define MYNEWT_VAL_BLE_LL_SCA (60) #endif -/* Value copied from BLE_LL_EXT_ADV_AUX_PTR_CNT */ #ifndef MYNEWT_VAL_BLE_LL_SCAN_AUX_SEGMENT_CNT #define MYNEWT_VAL_BLE_LL_SCAN_AUX_SEGMENT_CNT (0) #endif @@ -1356,12 +1561,10 @@ #define MYNEWT_VAL_BLE_LL_STRICT_CONN_SCHEDULING (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ #ifndef MYNEWT_VAL_BLE_LL_SUPP_MAX_RX_BYTES #define MYNEWT_VAL_BLE_LL_SUPP_MAX_RX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/controller) */ #ifndef MYNEWT_VAL_BLE_LL_SUPP_MAX_TX_BYTES #define MYNEWT_VAL_BLE_LL_SUPP_MAX_TX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE) #endif @@ -1410,7 +1613,6 @@ #define MYNEWT_VAL_BLE_XTAL_SETTLE_TIME (0) #endif -/*** @apache-mynewt-nimble/nimble/drivers/nrf5x */ #ifndef MYNEWT_VAL_BLE_PHY_DBG_TIME_ADDRESS_END_PIN #define MYNEWT_VAL_BLE_PHY_DBG_TIME_ADDRESS_END_PIN (-1) #endif @@ -1447,7 +1649,6 @@ #define MYNEWT_VAL_BLE_PHY_VARIABLE_TIFS (0) #endif -/*** @apache-mynewt-nimble/nimble/host */ #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) #endif @@ -1760,7 +1961,6 @@ #define MYNEWT_VAL_BLE_SM_KEYPRESS (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/host) */ #ifndef MYNEWT_VAL_BLE_SM_LEGACY #define MYNEWT_VAL_BLE_SM_LEGACY (0) #endif @@ -1785,7 +1985,6 @@ #define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (0) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/host) */ #ifndef MYNEWT_VAL_BLE_SM_SC #define MYNEWT_VAL_BLE_SM_SC (0) #endif @@ -1810,7 +2009,6 @@ #define MYNEWT_VAL_BLE_STORE_MAX_CCCDS (8) #endif -/*** @apache-mynewt-nimble/nimble/host/services/gap */ #ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE #define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE (0) #endif @@ -1855,12 +2053,10 @@ #define MYNEWT_VAL_BLE_SVC_GAP_SYSINIT_STAGE (301) #endif -/*** @apache-mynewt-nimble/nimble/host/services/gatt */ #ifndef MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE (302) #endif -/*** @apache-mynewt-nimble/nimble/transport */ #undef MYNEWT_VAL_BLE_ACL_BUF_COUNT #undef MYNEWT_VAL_BLE_ACL_BUF_SIZE @@ -1915,17 +2111,14 @@ #define MYNEWT_VAL_BLE_TRANSPORT (1) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT (24) #endif -/* Value copied from BLE_TRANSPORT_ACL_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT (24) #endif -/* Value copied from BLE_TRANSPORT_ACL_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT (24) #endif @@ -1934,7 +2127,6 @@ #define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (251) #endif -/* Overridden by @apache-mynewt-nimble/porting/targets/riot (defined by @apache-mynewt-nimble/nimble/transport) */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT (2) #endif @@ -1976,12 +2168,10 @@ #define MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ISO_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT (10) #endif -/* Value copied from BLE_TRANSPORT_ISO_COUNT */ #ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT #define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT (10) #endif @@ -2018,7 +2208,133 @@ #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif -/*** newt */ +#ifndef MYNEWT_VAL_BOOTUTIL_BOOTSTRAP +#define MYNEWT_VAL_BOOTUTIL_BOOTSTRAP (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_DOWNGRADE_PREVENTION__none +#define MYNEWT_VAL_BOOTUTIL_DOWNGRADE_PREVENTION__none (1) +#endif +#ifndef MYNEWT_VAL_BOOTUTIL_DOWNGRADE_PREVENTION__security_counter +#define MYNEWT_VAL_BOOTUTIL_DOWNGRADE_PREVENTION__security_counter (0) +#endif +#ifndef MYNEWT_VAL_BOOTUTIL_DOWNGRADE_PREVENTION__version +#define MYNEWT_VAL_BOOTUTIL_DOWNGRADE_PREVENTION__version (0) +#endif +#ifndef MYNEWT_VAL_BOOTUTIL_DOWNGRADE_PREVENTION +#define MYNEWT_VAL_BOOTUTIL_DOWNGRADE_PREVENTION (1) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_ENCRYPT_EC256 +#define MYNEWT_VAL_BOOTUTIL_ENCRYPT_EC256 (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_ENCRYPT_KW +#define MYNEWT_VAL_BOOTUTIL_ENCRYPT_KW (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_ENCRYPT_RSA +#define MYNEWT_VAL_BOOTUTIL_ENCRYPT_RSA (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_ENCRYPT_X25519 +#define MYNEWT_VAL_BOOTUTIL_ENCRYPT_X25519 (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_FEED_WATCHDOG +#define MYNEWT_VAL_BOOTUTIL_FEED_WATCHDOG (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_HAVE_LOGGING +#define MYNEWT_VAL_BOOTUTIL_HAVE_LOGGING (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_HW_ROLLBACK_PROT +#define MYNEWT_VAL_BOOTUTIL_HW_ROLLBACK_PROT (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_IMAGE_FORMAT_V2 +#define MYNEWT_VAL_BOOTUTIL_IMAGE_FORMAT_V2 (1) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_IMAGE_NUMBER +#define MYNEWT_VAL_BOOTUTIL_IMAGE_NUMBER (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_LOG_LEVEL +#define MYNEWT_VAL_BOOTUTIL_LOG_LEVEL (BOOTUTIL_LOG_LEVEL_INFO) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_MAX_IMG_SECTORS +#define MYNEWT_VAL_BOOTUTIL_MAX_IMG_SECTORS (128) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_NO_LOGGING +#define MYNEWT_VAL_BOOTUTIL_NO_LOGGING (1) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_OVERWRITE_ONLY +#define MYNEWT_VAL_BOOTUTIL_OVERWRITE_ONLY (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_OVERWRITE_ONLY_FAST +#define MYNEWT_VAL_BOOTUTIL_OVERWRITE_ONLY_FAST (1) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_SIGN_EC256 +#define MYNEWT_VAL_BOOTUTIL_SIGN_EC256 (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_SIGN_ED25519 +#define MYNEWT_VAL_BOOTUTIL_SIGN_ED25519 (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_SIGN_RSA +#define MYNEWT_VAL_BOOTUTIL_SIGN_RSA (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_SIGN_RSA_LEN +#define MYNEWT_VAL_BOOTUTIL_SIGN_RSA_LEN (2048) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_SINGLE_APPLICATION_SLOT +#define MYNEWT_VAL_BOOTUTIL_SINGLE_APPLICATION_SLOT (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_SWAP_SAVE_ENCTLV +#define MYNEWT_VAL_BOOTUTIL_SWAP_SAVE_ENCTLV (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_SWAP_USING_MOVE +#define MYNEWT_VAL_BOOTUTIL_SWAP_USING_MOVE (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_USE_MBED_TLS +#define MYNEWT_VAL_BOOTUTIL_USE_MBED_TLS (1) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_USE_TINYCRYPT +#define MYNEWT_VAL_BOOTUTIL_USE_TINYCRYPT (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_VALIDATE_SLOT0 +#define MYNEWT_VAL_BOOTUTIL_VALIDATE_SLOT0 (0) +#endif + +#ifndef MYNEWT_VAL_BOOTUTIL_VERSION_CMP_USE_BUILD_NUMBER +#define MYNEWT_VAL_BOOTUTIL_VERSION_CMP_USE_BUILD_NUMBER (0) +#endif + +#undef MYNEWT_VAL_MCUBOOT_DATA_SHARING + +#undef MYNEWT_VAL_MCUBOOT_MEASURED_BOOT + +#undef MYNEWT_VAL_MCUBOOT_MEASURED_BOOT_MAX_RECORD_SZ + +#undef MYNEWT_VAL_MCUBOOT_SHARED_DATA_BASE + +#undef MYNEWT_VAL_MCUBOOT_SHARED_DATA_SIZE + #ifndef MYNEWT_VAL_APP_NAME #define MYNEWT_VAL_APP_NAME "dummy_app" #endif @@ -2059,8 +2375,9 @@ #define MYNEWT_VAL_TARGET_riot (1) #endif -/*** Included packages */ +#define MYNEWT_PKG_apache_mynewt_core__boot_startup 1 #define MYNEWT_PKG_apache_mynewt_core__compiler_arm_none_eabi_m4 1 +#define MYNEWT_PKG_apache_mynewt_core__crypto_mbedtls 1 #define MYNEWT_PKG_apache_mynewt_core__crypto_tinycrypt 1 #define MYNEWT_PKG_apache_mynewt_core__hw_bsp_nordic_pca10056 1 #define MYNEWT_PKG_apache_mynewt_core__hw_cmsis_core 1 @@ -2069,9 +2386,11 @@ #define MYNEWT_PKG_apache_mynewt_core__hw_hal 1 #define MYNEWT_PKG_apache_mynewt_core__hw_mcu_nordic 1 #define MYNEWT_PKG_apache_mynewt_core__hw_mcu_nordic_nrf52xxx 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_mcu_nordic_nrf_common 1 #define MYNEWT_PKG_apache_mynewt_core__kernel_os 1 #define MYNEWT_PKG_apache_mynewt_core__libc 1 #define MYNEWT_PKG_apache_mynewt_core__libc_baselibc 1 +#define MYNEWT_PKG_apache_mynewt_core__mgmt_image_header 1 #define MYNEWT_PKG_apache_mynewt_core__sys_console_stub 1 #define MYNEWT_PKG_apache_mynewt_core__sys_defs 1 #define MYNEWT_PKG_apache_mynewt_core__sys_flash_map 1 @@ -2094,10 +2413,13 @@ #define MYNEWT_PKG_apache_mynewt_nimble__porting_npl_mynewt 1 #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 #define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_riot 1 +#define MYNEWT_PKG_mcuboot__boot_bootutil 1 +#define MYNEWT_PKG_mcuboot__boot_mynewt_flash_map_backend 1 +#define MYNEWT_PKG_mcuboot__boot_mynewt_mcuboot_config 1 -/*** Included APIs */ #define MYNEWT_API_ble_driver 1 #define MYNEWT_API_ble_transport 1 +#define MYNEWT_API_bootloader 1 #define MYNEWT_API_console 1 #define MYNEWT_API_log 1 #define MYNEWT_API_stats 1 From a9400d707b04c3cc8ae5d526d8b9f76c57c9408b Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Mon, 22 Jul 2024 17:29:56 +0200 Subject: [PATCH 1032/1333] ci: Fix `Check ports syscfg update` workflow Amends incorrect relative path to the LICENSE_TEMPLATE file. --- porting/update_generated_files.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porting/update_generated_files.sh b/porting/update_generated_files.sh index 94f1808a41..e5104b63f8 100755 --- a/porting/update_generated_files.sh +++ b/porting/update_generated_files.sh @@ -42,5 +42,5 @@ for target in "${!targets[@]}"; do find "${targets[$target]}/include" -type f -name 'syscfg.h' -exec sed -i '/MYNEWT_VAL_REPO_*/,/#endif/d' {} \; find "${targets[$target]}/include" -type f -name 'syscfg.h' -exec sed -i -E ':a;N;$!ba;s:/\*([^*]|(\*+([^*/])))*\*+/::g' {} \; find "${targets[$target]}/include" -type f -name 'syscfg.h' -exec sed -i '$!N;/^\n$/{$q;D;};P;D;' {} \; - find "${targets[$target]}/include" -type f -name 'syscfg.h' -exec sh -c 'cat "$0" "$1" > "$1.tmp" && mv "$1.tmp" "$1"' "../.github/LICENSE_TEMPLATE" {} \; + find "${targets[$target]}/include" -type f -name 'syscfg.h' -exec sh -c 'cat "$0" "$1" > "$1.tmp" && mv "$1.tmp" "$1"' "repos/apache-mynewt-nimble/.github/LICENSE_TEMPLATE" {} \; done From e4af62122fe07f8d4bbee3d412cb026807900efb Mon Sep 17 00:00:00 2001 From: sjanc <10303625+sjanc@users.noreply.github.com> Date: Tue, 30 Jul 2024 21:45:21 +0000 Subject: [PATCH 1033/1333] porting: Update ports syscfg --- porting/examples/linux_blemesh/include/syscfg/syscfg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index a5ab87a6bd..a476d88917 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -1302,7 +1302,7 @@ #endif #ifndef MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN -#define MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN (33) +#define MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN (66) #endif #ifndef MYNEWT_VAL_BLE_MESH_PROXY_USE_DEVICE_NAME From 1f187b8ec595d59e31bdd434c48957dc9d673a24 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Tue, 30 Jul 2024 17:41:14 +0530 Subject: [PATCH 1034/1333] nimble/host: Modify Advertising Tx power levels Spec ver 5.4 , Vol 4, Part E, section 7.8.6 mentions the range value for Tx power level. Different BLE spec version have modified the range values that Tx Power level can have. Update the min / max macros to reflect the same --- nimble/include/nimble/hci_common.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 80c4f2b3fc..b1f6261266 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1428,8 +1428,17 @@ struct ble_hci_vs_set_local_irk_cp { #define BLE_HCI_ADV_PEER_ADDR_MAX (1) /* --- LE advertising channel tx power (OCF 0x0007) */ -#define BLE_HCI_ADV_CHAN_TXPWR_MIN (-20) -#define BLE_HCI_ADV_CHAN_TXPWR_MAX (10) +#if MYNEWT_VAL(BLE_VERSION) == 50 +#define BLE_HCI_ADV_CHAN_TXPWR_MIN (-20) +#define BLE_HCI_ADV_CHAN_TXPWR_MAX (10) +#elif MYNEWT_VAL(BLE_VERSION) == 51 +#define BLE_HCI_ADV_CHAN_TXPWR_MIN (-20) +#define BLE_HCI_ADV_CHAN_TXPWR_MAX (20) +#elif MYNEWT_VAL(BLE_VERSION) >= 52 +#define BLE_HCI_ADV_CHAN_TXPWR_MIN (-127) +#define BLE_HCI_ADV_CHAN_TXPWR_MAX (20) +#endif + /* --- LE set scan enable (OCF 0x000c) */ From 97651a1ac477ed920332f93c0ff1dd0096e68c8e Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Mon, 22 Jul 2024 16:26:07 +0200 Subject: [PATCH 1035/1333] ci: Upgrade PR labeler Adds a new label's category for Pull Request size. The labels are based on the number of altered lines. --- .github/labeler_cfg.yml | 4 ++++ .github/workflows/labeler.yml | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/labeler_cfg.yml b/.github/labeler_cfg.yml index cc4f6abb21..45e245cf58 100644 --- a/.github/labeler_cfg.yml +++ b/.github/labeler_cfg.yml @@ -24,3 +24,7 @@ host: controller: - changed-files: - any-glob-to-any-file: nimble/controller/** + +CI: + - changed-files: + - any-glob-to-any-file: .github/workflows/** diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 7c2d296d19..c084f29d81 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -19,13 +19,14 @@ name: "Pull Request Labeler" on: - - pull_request + - pull_request_target jobs: labeler: permissions: contents: read pull-requests: write + issues: write runs-on: ubuntu-latest steps: - name: Checkout repository @@ -36,3 +37,9 @@ jobs: with: sync-labels: true configuration-path: .github/labeler_cfg.yml + + - name: Assign labels based on the PR's size + uses: codelytv/pr-size-labeler@v1.10.0 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ignore_file_deletions: true From 609f6a2ece8728664a6cdf45514957c431d04ee3 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 30 Jul 2024 08:58:09 +0200 Subject: [PATCH 1036/1333] Add initial asf.yaml configuration This sets ininitial configuration for email notifications. --- .asf.yaml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .asf.yaml diff --git a/.asf.yaml b/.asf.yaml new file mode 100644 index 0000000000..c43fe91b7f --- /dev/null +++ b/.asf.yaml @@ -0,0 +1,23 @@ +# +# 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. +# + +notifications: + commits: commits@mynewt.apache.org + issues: notifications@mynewt.apache.org + pullrequests: notifications@mynewt.apache.org From b84191aca22abde7a980dc56bad5162ca467763c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 1 Aug 2024 15:45:52 +0200 Subject: [PATCH 1037/1333] apps/auracast_usb: Fix calculation for octets_per_frame and max_sdu --- apps/auracast_usb/src/main.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/apps/auracast_usb/src/main.c b/apps/auracast_usb/src/main.c index c64fca90f7..4ddb0b8608 100644 --- a/apps/auracast_usb/src/main.c +++ b/apps/auracast_usb/src/main.c @@ -31,7 +31,6 @@ #include "app_priv.h" #define BROADCAST_SID 1 -#define BROADCAST_SDU_INTVL MYNEWT_VAL(LC3_FRAME_DURATION) #if (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 8000) #define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_8000_HZ @@ -47,11 +46,17 @@ BUILD_ASSERT(0, "Sample frequency not supported"); #endif -#define BROADCAST_MAX_SDU (BROADCAST_SDU_INTVL * \ - MYNEWT_VAL(LC3_BITRATE) / \ - (1000 * 1000 * 8) * \ - MYNEWT_VAL(AURACAST_CHAN_NUM) / \ - MYNEWT_VAL(BIG_NUM_BIS)) +/* Note: values need to be adjusted if sampling frequency is 44100 (currently + * not supported by app) or SDU interval is different from LC3 frame + * length + */ +#define OCTETS_PER_CODEC_FRAME (MYNEWT_VAL(LC3_BITRATE) / \ + 8 * MYNEWT_VAL(LC3_FRAME_DURATION) / \ + 1000000) +#define BIG_SDU_INTERVAL (MYNEWT_VAL(LC3_FRAME_DURATION)) +#define BIG_MAX_SDU (OCTETS_PER_CODEC_FRAME * \ + MYNEWT_VAL(AURACAST_CHAN_NUM) / \ + MYNEWT_VAL(BIG_NUM_BIS)) #define BROADCASTER_INTERRUPT_TASK_PRIO 4 #define BROADCASTER_INTERRUPT_TASK_STACK_SZ 512 @@ -104,14 +109,14 @@ base_create(void) BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS : BLE_AUDIO_SELECTED_FRAME_DURATION_7_5_MS, BLE_AUDIO_LOCATION_FRONT_LEFT, - BROADCAST_MAX_SDU, ); + OCTETS_PER_CODEC_FRAME, ); uint8_t codec_spec_config_right_chan[] = BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, MYNEWT_VAL(LC3_FRAME_DURATION) == 10000 ? BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS : BLE_AUDIO_SELECTED_FRAME_DURATION_7_5_MS, BLE_AUDIO_LOCATION_FRONT_RIGHT, - BROADCAST_MAX_SDU, ); + OCTETS_PER_CODEC_FRAME, ); #else uint16_t chan_loc = BLE_AUDIO_LOCATION_FRONT_LEFT | BLE_AUDIO_LOCATION_FRONT_RIGHT; @@ -121,7 +126,7 @@ base_create(void) BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS : BLE_AUDIO_SELECTED_FRAME_DURATION_7_5_MS, chan_loc, - BROADCAST_MAX_SDU * 2, ); + OCTETS_PER_CODEC_FRAME, ); struct ble_audio_bis *bis; #endif @@ -239,8 +244,8 @@ auracast_create(void) { const char *program_info = "NimBLE Auracast Test"; static struct ble_iso_big_params big_params = { - .sdu_interval = MYNEWT_VAL(LC3_FRAME_DURATION), - .max_sdu = BROADCAST_MAX_SDU, + .sdu_interval = BIG_SDU_INTERVAL, + .max_sdu = BIG_MAX_SDU, .max_transport_latency = MYNEWT_VAL(LC3_FRAME_DURATION) / 1000, .rtn = MYNEWT_VAL(BIG_RTN), .phy = MYNEWT_VAL(BIG_PHY), From fdb4eda254215bf183874bab930b0ca88eba2392 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 1 Aug 2024 12:03:45 +0200 Subject: [PATCH 1038/1333] nimble/mesh: Fix syscfg restrictions for BLE_MESH_PROXY_MSG_LEN Make sure BLE_MESH_PROXY_MSG_LEN is properly set when both BLE_MESH_PB_GATT and BLE_MESH_GATT_PROXY are set. --- nimble/host/mesh/syscfg.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/nimble/host/mesh/syscfg.yml b/nimble/host/mesh/syscfg.yml index c75828d243..73bef03aac 100644 --- a/nimble/host/mesh/syscfg.yml +++ b/nimble/host/mesh/syscfg.yml @@ -977,11 +977,10 @@ syscfg.vals.BLE_MESH_GATT_PROXY: syscfg.vals.BLE_MESH_PB_GATT: BLE_MESH_PROXY: 1 BLE_MESH_PROV: 1 + BLE_MESH_PROXY_MSG_LEN: 66 syscfg.vals.BLE_MESH_PB_ADV: BLE_MESH_PROV: 1 -syscfg.vals.'BLE_MESH_PB_GATT': - BLE_MESH_PROXY_MSG_LEN: 66 -syscfg.vals.'BLE_MESH_GATT_PROXY': +syscfg.vals.'BLE_MESH_GATT_PROXY && !BLE_MESH_PB_GATT': BLE_MESH_PROXY_MSG_LEN: 33 From f4702af0a1423062a2692addcc0b7f3ac9b06277 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 1 Aug 2024 15:46:19 +0200 Subject: [PATCH 1039/1333] nimble/ll: Use retransmissions for BIG Create Controller now uses RTN parameter to include retransmissions in BIG event. This applies only to IRC for now, pretransmissions are not included. --- nimble/controller/src/ble_ll_iso_big.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index e41f3f94c8..0645ed44ef 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -1270,9 +1270,12 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len) bp.encrypted = cmd->encryption; memcpy(bp.broadcast_code, cmd->broadcast_code, 16); - bp.nse = 1; + /* FIXME for now we only care about retransmissions, so set both NSE and IRC + * to RTN + */ + bp.nse = MIN(cmd->rtn, 0x0f);; bp.bn = 1; - bp.irc = 1; + bp.irc = MIN(cmd->rtn, 0x0f); bp.pto = 0; bp.iso_interval = bp.sdu_interval / 1250; bp.max_pdu = bp.max_sdu; From c8de4cc348d3f865017d151759d38156b4449715 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 31 Jul 2024 11:05:22 +0200 Subject: [PATCH 1040/1333] nimble/ll: Update ticks conversions for MCUs with idiv support We can use simple calculations for MCUs that support idiv. This has also larger range of allowed values on uint32_t values. --- nimble/controller/include/controller/ble_ll_tmr.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nimble/controller/include/controller/ble_ll_tmr.h b/nimble/controller/include/controller/ble_ll_tmr.h index 2d79427b63..bf62503824 100644 --- a/nimble/controller/include/controller/ble_ll_tmr.h +++ b/nimble/controller/include/controller/ble_ll_tmr.h @@ -64,9 +64,17 @@ ble_ll_tmr_u2t(uint32_t usecs) return usecs / 32; #endif #if MYNEWT_VAL(OS_CPUTIME_FREQ) == 32768 +#if __ARM_FEATURE_IDIV + if (usecs < 131072) { + return (usecs * 32768) / 1000000; + } else { + return ((uint64_t)usecs * 32768) / 1000000; + } +#else if (usecs <= 31249) { return (usecs * 137439) / 4194304; } +#endif #endif return os_cputime_usecs_to_ticks(usecs); From 5e9dad22da8b255883276489fc2b86f6a2b20811 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 31 Jul 2024 11:32:54 +0200 Subject: [PATCH 1041/1333] nimble/ll: Fix event drift in event start time calculations Updating BIG event start time by adding interval on every event introduces additional clock drift due to rouding errors on conversion from usecs to ticks. This fixes the problem by using some event time as constant base and timing for subsqeuent events is calculated relative to that event. This eliminates drift due to calculations. To prevent overflows in calculations, base event is changed every 30mins. --- nimble/controller/src/ble_ll_iso_big.c | 51 ++++++++++++++++++++------ 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 0645ed44ef..53bc415d74 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -134,6 +134,9 @@ struct ble_ll_iso_big { uint32_t sync_delay; uint32_t event_start; uint8_t event_start_us; + uint32_t anchor_base_ticks; + uint8_t anchor_base_rem_us; + uint16_t anchor_offset; struct ble_ll_sched_item sch; struct ble_npl_event event_done; @@ -168,6 +171,35 @@ static uint8_t bis_pool_free = BIS_POOL_SIZE; static struct ble_ll_iso_big *big_pending; static struct ble_ll_iso_big *big_active; +static void +big_sched_set(struct ble_ll_iso_big *big) +{ + uint32_t offset_us; + + big->sch.start_time = big->anchor_base_ticks; + big->sch.remainder = big->anchor_base_rem_us; + + offset_us = big->anchor_offset * big->iso_interval * 1250; + + ble_ll_tmr_add(&big->sch.start_time, &big->sch.remainder, offset_us); + + /* Reset anchor base every 30mins to avoid overflows in calculations later. */ + if (offset_us >= 30 * 60 * 1000000) { + big->anchor_base_ticks = big->sch.start_time; + big->anchor_base_rem_us = big->sch.remainder; + big->anchor_offset = 0; + } + + big->sch.end_time = big->sch.start_time + + ble_ll_tmr_u2t_up(big->sync_delay) + 1; + big->sch.start_time -= g_ble_ll_sched_offset_ticks; + + if (big->control_active) { + /* XXX calculate proper time */ + big->sch.end_time += 10; + } +} + struct ble_ll_iso_bis * ble_ll_iso_big_find_bis_by_handle(uint16_t conn_handle) { @@ -536,19 +568,13 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) } } - /* XXX precalculate some data here? */ + big->anchor_offset++; + big_sched_set(big); - ble_ll_tmr_add(&big->sch.start_time, &big->sch.remainder, - big->iso_interval * 1250); big->sch.end_time = big->sch.start_time + ble_ll_tmr_u2t_up(big->sync_delay) + 1; big->sch.start_time -= g_ble_ll_sched_offset_ticks; - if (big->control_active) { - /* XXX fixme */ - big->sch.end_time += 10; - } - /* XXX this should always succeed since we preempt anything for now */ rc = ble_ll_sched_iso_big(&big->sch, 0, 0); assert(rc == 0); @@ -1107,10 +1133,11 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, big_event_fixed = 1; } - big->sch.start_time = big_time; - big->sch.remainder = 0; - big->sch.end_time = big->sch.start_time + sync_delay_ticks + 1; - big->sch.start_time -= g_ble_ll_sched_offset_ticks; + big->anchor_base_ticks = big_time; + big->anchor_base_rem_us = 0; + big->anchor_offset = 0; + + big_sched_set(big); rc = ble_ll_sched_iso_big(&big->sch, 1, big_event_fixed); if (rc < 0) { From 7c4fb32a8b1c581143e0ded6fc16eb3b579ebb70 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 1 Aug 2024 16:22:52 +0200 Subject: [PATCH 1042/1333] nimble/phy: Adjust timings for nRF5x phy Measured on nRF52 and nRF53 to have consistent results for all supported transitions. Due to rounding errors we're not able to achieve perfect 150us on all transitions, but we should be +/- 1us which is perfectly fine. --- nimble/drivers/nrf5x/src/ble_phy.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index ec5507c9fa..a6fff1f901 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -222,15 +222,15 @@ static const uint8_t g_ble_phy_t_rxenddelay[BLE_PHY_NUM_MODE] = { #else /* delay between EVENTS_READY and start of tx */ static const uint8_t g_ble_phy_t_txdelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 4, - [BLE_PHY_MODE_2M] = 3, + [BLE_PHY_MODE_1M] = 6, + [BLE_PHY_MODE_2M] = 5, [BLE_PHY_MODE_CODED_125KBPS] = 5, [BLE_PHY_MODE_CODED_500KBPS] = 5 }; /* delay between EVENTS_END and end of txd packet */ static const uint8_t g_ble_phy_t_txenddelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 4, - [BLE_PHY_MODE_2M] = 3, + [BLE_PHY_MODE_1M] = 6, + [BLE_PHY_MODE_2M] = 4, [BLE_PHY_MODE_CODED_125KBPS] = 9, [BLE_PHY_MODE_CODED_500KBPS] = 3 }; @@ -243,8 +243,8 @@ static const uint8_t g_ble_phy_t_rxaddrdelay[BLE_PHY_NUM_MODE] = { }; /* delay between end of rxd packet and EVENTS_END */ static const uint8_t g_ble_phy_t_rxenddelay[BLE_PHY_NUM_MODE] = { - [BLE_PHY_MODE_1M] = 6, - [BLE_PHY_MODE_2M] = 2, + [BLE_PHY_MODE_1M] = 4, + [BLE_PHY_MODE_2M] = 1, [BLE_PHY_MODE_CODED_125KBPS] = 27, [BLE_PHY_MODE_CODED_500KBPS] = 22 }; From a9384f8b99c08c7bb07929e3fe5dbc12298c04c8 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 1 Aug 2024 15:48:29 +0200 Subject: [PATCH 1043/1333] nimble/phy: Fix tx-tx transition timing Delay for event END was always included in tx-tx transition calculations which resulted in invalid calculations for tx-tx transition anchored at packet start. This fixes the issue and also fixes timing for event ADDRESS since it seems to be different that the one for END event. --- nimble/drivers/nrf5x/src/ble_phy.c | 38 +++++++++++++++++------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index a6fff1f901..f556f65024 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -227,6 +227,13 @@ static const uint8_t g_ble_phy_t_txdelay[BLE_PHY_NUM_MODE] = { [BLE_PHY_MODE_CODED_125KBPS] = 5, [BLE_PHY_MODE_CODED_500KBPS] = 5 }; +/* delay between EVENTS_ADDRESS and txd access address */ +static const uint8_t g_ble_phy_t_txaddrdelay[BLE_PHY_NUM_MODE] = { + [BLE_PHY_MODE_1M] = 7, + [BLE_PHY_MODE_2M] = 5, + [BLE_PHY_MODE_CODED_125KBPS] = 17, + [BLE_PHY_MODE_CODED_500KBPS] = 17 +}; /* delay between EVENTS_END and end of txd packet */ static const uint8_t g_ble_phy_t_txenddelay[BLE_PHY_NUM_MODE] = { [BLE_PHY_MODE_1M] = 6, @@ -1104,25 +1111,24 @@ ble_phy_tx_end_isr(void) */ } else if (transition == BLE_PHY_TRANSITION_TX_TX) { if (g_ble_phy_data.txtx_time_anchor) { - /* Schedule next TX relative to current TX end. TX end timestamp is - * captured in CC[2]. - */ - tx_time = NRF_TIMER0->CC[2] + g_ble_phy_data.txtx_time_us; - } else { - /* Schedule next TX relative to current TX start. AA timestamp is - * captured in CC[1], we need to adjust for sync word to get TX - * start. - */ - tx_time = NRF_TIMER0->CC[1] - ble_ll_pdu_syncword_us(tx_phy_mode) + - g_ble_phy_data.txtx_time_us; - /* Adjust for delay between EVENT_ADDRESS and actual address TX time */ - /* FIXME assume this is the same as EVENT_END to end, but we should - * measure this to be sure */ + /* Calculate TX anchor relative to current TX end */ + + /* TX end timestamp is captured in CC[2] */ + tx_time = NRF_TIMER0->CC[2]; + /* Adjust for delay between EVENT_END and actual TX end time */ tx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; + } else { + /* Calculate TX anchor relative to current TX start */ + + /* AA timestamp is captured in CC[1] */ + tx_time = NRF_TIMER0->CC[1]; + /* Adjust for delay between EVENT_ADDRESS and actual AA time ota */ + tx_time += g_ble_phy_t_txaddrdelay[tx_phy_mode]; + /* Adjust by sync word length to get TX start time */ + tx_time -= ble_ll_pdu_syncword_us(tx_phy_mode); } - /* Adjust for delay between EVENT_END and actual TX end time */ - tx_time += g_ble_phy_t_txenddelay[tx_phy_mode]; + tx_time += g_ble_phy_data.txtx_time_us; #if PHY_USE_FEM_PA fem_time = tx_time - MYNEWT_VAL(BLE_FEM_PA_TURN_ON_US); From f8994e1406f9a9e243f0a17518ca73bc40d04691 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 7 Aug 2024 01:00:46 +0200 Subject: [PATCH 1044/1333] nimble/ll: Fix LLID for empty BIS PDUs LLID=1 should be only used for empty PDUs that are sent as padding for SDUs that are too short. --- nimble/controller/src/ble_ll_isoal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_isoal.c b/nimble/controller/src/ble_ll_isoal.c index fd9d205fe5..0ae6d6b780 100644 --- a/nimble/controller/src/ble_ll_isoal.c +++ b/nimble/controller/src/ble_ll_isoal.c @@ -205,7 +205,7 @@ ble_ll_isoal_mux_unframed_get(struct ble_ll_isoal_mux *mux, uint8_t idx, pdu_idx = idx - sdu_idx * mux->pdu_per_sdu; if (sdu_idx >= mux->sdu_in_event) { - *llid = 1; + *llid = 0; return 0; } @@ -215,7 +215,7 @@ ble_ll_isoal_mux_unframed_get(struct ble_ll_isoal_mux *mux, uint8_t idx, } if (!pkthdr) { - *llid = 1; + *llid = 0; return 0; } From f06f9363b7a8e65f882bb6a6d9c18291b373a689 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 8 Aug 2024 16:19:24 +0200 Subject: [PATCH 1045/1333] nimble/host: Fix matching responses to ATT procedures If we sent the same request to two different peers at exactly the same time, it was possible that responses could be matched with invalid procedures. --- nimble/host/src/ble_gattc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index 4507317ced..45ee869c85 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -961,10 +961,12 @@ ble_gattc_proc_matches_conn_rx_entry(struct ble_gattc_proc *proc, void *arg) criteria = arg; - if (criteria->conn_handle != BLE_HS_CONN_HANDLE_NONE && - criteria->conn_handle != proc->conn_handle && - criteria->cid != proc->cid) { + if ((criteria->conn_handle != BLE_HS_CONN_HANDLE_NONE) && + (criteria->conn_handle != proc->conn_handle)) { + return 0; + } + if (criteria->cid != proc->cid) { return 0; } From 746e5ff5d958e8606e181f3c830e80813ed9feaf Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 6 Aug 2024 21:51:26 +0200 Subject: [PATCH 1046/1333] nimble/ll: Fix BIG anchor offset overflow The anchor base for BIG events was reset every 30mins to avoid overflow in offset calculations which could happen after more than 60mins of streaming. However, as it turns out anchor offset wraps-around much earlier than that after just ~10m55s (at 10ms iso interval) so we should better take care of anchor offset instead of offset_us. --- nimble/controller/src/ble_ll_iso_big.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 53bc415d74..d4a492b296 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -183,8 +183,10 @@ big_sched_set(struct ble_ll_iso_big *big) ble_ll_tmr_add(&big->sch.start_time, &big->sch.remainder, offset_us); - /* Reset anchor base every 30mins to avoid overflows in calculations later. */ - if (offset_us >= 30 * 60 * 1000000) { + /* Reset anchor base before anchor offset wraps-around. + * This happens much earlier than possible overflow in calculations. + */ + if (big->anchor_offset == UINT16_MAX) { big->anchor_base_ticks = big->sch.start_time; big->anchor_base_rem_us = big->sch.remainder; big->anchor_offset = 0; From 5a8d0e3a7f0f9d6ca8cc2ac18613c231092e6e73 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 7 Aug 2024 00:56:48 +0200 Subject: [PATCH 1047/1333] nimble/ll: Add option to prefill isoal mux This adds option to queue initial SDUs in mux until there are enough data to fill entire ISO event. This makes it easier to handle pre-transmissions since we don't care if host is aware that it should send more data for the 1st event to fill pre-transmission subevents - we will simply not "release" data from mux until there are enough SDUs to fill complete event (i.e. initial ISO events may contain only empty packets). --- .../include/controller/ble_ll_isoal.h | 4 ++++ nimble/controller/src/ble_ll_isoal.c | 18 ++++++++++++++++++ nimble/controller/syscfg.yml | 9 +++++++++ 3 files changed, 31 insertions(+) diff --git a/nimble/controller/include/controller/ble_ll_isoal.h b/nimble/controller/include/controller/ble_ll_isoal.h index 73ceaf76d6..4ad8d858bd 100644 --- a/nimble/controller/include/controller/ble_ll_isoal.h +++ b/nimble/controller/include/controller/ble_ll_isoal.h @@ -27,6 +27,10 @@ extern "C" { #if MYNEWT_VAL(BLE_LL_ISO) struct ble_ll_isoal_mux { +#if MYNEWT_VAL(BLE_LL_ISOAL_MUX_PREFILL) + uint8_t active; +#endif + /* Max PDU length */ uint8_t max_pdu; /* Number of expected SDUs per ISO interval */ diff --git a/nimble/controller/src/ble_ll_isoal.c b/nimble/controller/src/ble_ll_isoal.c index 0ae6d6b780..bed974bb3e 100644 --- a/nimble/controller/src/ble_ll_isoal.c +++ b/nimble/controller/src/ble_ll_isoal.c @@ -119,13 +119,31 @@ ble_ll_isoal_mux_tx_pkt_in(struct ble_ll_isoal_mux *mux, struct os_mbuf *om, pkthdr = OS_MBUF_PKTHDR(om); STAILQ_INSERT_TAIL(&mux->sdu_q, pkthdr, omp_next); mux->sdu_q_len++; +#if MYNEWT_VAL(BLE_LL_ISOAL_MUX_PREFILL) + if (mux->sdu_q_len == mux->sdu_per_event) { + mux->active = 1; + } +#endif OS_EXIT_CRITICAL(sr); } int ble_ll_isoal_mux_event_start(struct ble_ll_isoal_mux *mux, uint32_t timestamp) { +#if MYNEWT_VAL(BLE_LL_ISOAL_MUX_PREFILL) + /* If prefill is enabled, we always expect to have required number of SDUs + * in queue, otherwise we disable mux until enough SDUs are queued again. + */ + mux->sdu_in_event = mux->sdu_per_event; + if (mux->sdu_in_event > mux->sdu_q_len) { + mux->active = 0; + } + if (!mux->active) { + mux->sdu_in_event = 0; + } +#else mux->sdu_in_event = min(mux->sdu_q_len, mux->sdu_per_event); +#endif mux->event_tx_timestamp = timestamp; return mux->sdu_in_event; diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index ce8fad1e9a..e77a1de44b 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -516,6 +516,15 @@ syscfg.defs: value: 0 experimental: 1 + BLE_LL_ISOAL_MUX_PREFILL: + description: > + Waits until number of SDUs enqueued in mux is enough to fill complete + ISO event before providing data to ISO. + This is useful for pre-transmissions as it ensures that all subevents + in 1st ISO event are non-empty. + value: 0 + experimental: 1 + BLE_LL_CHANNEL_SOUNDING: description: > Enable support for Channel Sounding feature. From 4150a609400dbf11fe83348395d6ce930d581eb7 Mon Sep 17 00:00:00 2001 From: rymanluk <2675599+rymanluk@users.noreply.github.com> Date: Thu, 8 Aug 2024 17:45:25 +0000 Subject: [PATCH 1048/1333] porting: Update ports syscfg --- porting/npl/riot/include/syscfg/syscfg.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 06080e272b..68203ad47c 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1421,6 +1421,10 @@ #define MYNEWT_VAL_BLE_LL_ISO (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_ISOAL_MUX_PREFILL +#define MYNEWT_VAL_BLE_LL_ISOAL_MUX_PREFILL (0) +#endif + #ifndef MYNEWT_VAL_BLE_LL_ISO_BROADCASTER #define MYNEWT_VAL_BLE_LL_ISO_BROADCASTER (0) #endif From afe0272d72e812dd2cb446a9ca962e171918e0c6 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 24 Oct 2023 10:32:59 +0200 Subject: [PATCH 1049/1333] nimble/transport: Add auto syscfg for monitor This adds common syscfg that is defined when monitor is used. --- nimble/transport/syscfg.monitor.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/transport/syscfg.monitor.yml b/nimble/transport/syscfg.monitor.yml index 7cfbc416fd..4defd910bc 100644 --- a/nimble/transport/syscfg.monitor.yml +++ b/nimble/transport/syscfg.monitor.yml @@ -54,5 +54,8 @@ syscfg.defs: length value will be split. value: 128 +syscfg.defs.'BLE_MONITOR_UART || BLE_MONITOR_RTT': + BLE_MONITOR: 1 + syscfg.restrictions: - '!(BLE_MONITOR_UART && BLE_MONITOR_RTT)' From 6ef9cc4fb2671f3421c5d862e6574b6c50ac038d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 20 Oct 2023 17:20:26 +0200 Subject: [PATCH 1050/1333] nimble/transport: Add common HCI RX task This adds common task for implementing HCI RX. Any transport can simply register its own function for RX that will be run in separate task whenever triggered by dedicated API. This for example allows to easily implement handling HCI RX in a task instead of in an interrupt since handling RX in an interrupt doesn't work well with monitor enabled. If selected transport doesn't register its function, all rx_task code will be compiled out since there won't be any references to that code. --- nimble/transport/include/nimble/transport.h | 5 ++ nimble/transport/src/rx_task.c | 84 +++++++++++++++++++++ nimble/transport/syscfg.yml | 8 ++ 3 files changed, 97 insertions(+) create mode 100644 nimble/transport/src/rx_task.c diff --git a/nimble/transport/include/nimble/transport.h b/nimble/transport/include/nimble/transport.h index fcb3297cf7..f5a30780b6 100644 --- a/nimble/transport/include/nimble/transport.h +++ b/nimble/transport/include/nimble/transport.h @@ -35,6 +35,11 @@ struct os_mbuf; /* Initialization */ void ble_transport_init(void); +/* Common HCI RX task functions */ +typedef void ble_transport_rx_func_t(void *arg); +void ble_transport_rx_register(ble_transport_rx_func_t *func, void *arg); +void ble_transport_rx(void); + /* Allocators for supported data types */ void *ble_transport_alloc_cmd(void); void *ble_transport_alloc_evt(int discardable); diff --git a/nimble/transport/src/rx_task.c b/nimble/transport/src/rx_task.c new file mode 100644 index 0000000000..076990cdd3 --- /dev/null +++ b/nimble/transport/src/rx_task.c @@ -0,0 +1,84 @@ +/* + * 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. + */ + +#include +#include +#if MYNEWT +#include +#endif +#include +#include +#include + +#if !defined(MYNEWT) || MYNEWT_VAL(BLE_TRANSPORT_RX_STACK_SIZE) > 0 + +static ble_transport_rx_func_t *rx_func; +static void *rx_func_arg; + +#if MYNEWT +OS_TASK_STACK_DEFINE(rx_stack, MYNEWT_VAL(BLE_TRANSPORT_RX_STACK_SIZE)); +static struct os_task rx_task; +#endif + +static struct ble_npl_eventq rx_eventq; +static struct ble_npl_event rx_event; + +static void +rx_event_func(struct ble_npl_event *ev) +{ + rx_func(rx_func_arg); +} + +static void +rx_task_func(void *arg) +{ + struct ble_npl_event *ev; + + ble_npl_eventq_init(&rx_eventq); + + while (1) { + ev = ble_npl_eventq_get(&rx_eventq, BLE_NPL_TIME_FOREVER); + ble_npl_event_run(ev); + } +} + +void +ble_transport_rx_register(ble_transport_rx_func_t *func, void *arg) +{ + assert(func && !rx_func); + + rx_func = func; + rx_func_arg = arg; + + ble_npl_event_init(&rx_event, rx_event_func, NULL); + +#ifdef MYNEWT + os_task_init(&rx_task, "hci_rx_task", rx_task_func, NULL, + MYNEWT_VAL(BLE_TRANSPORT_RX_PRIO), OS_WAIT_FOREVER, rx_stack, + MYNEWT_VAL(BLE_TRANSPORT_RX_STACK_SIZE)); +#endif +} + +void +ble_transport_rx(void) +{ + ble_npl_eventq_put(&rx_eventq, &rx_event); +} + +#endif diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml index 7e8ea9357d..877c3db24c 100644 --- a/nimble/transport/syscfg.yml +++ b/nimble/transport/syscfg.yml @@ -110,6 +110,14 @@ syscfg.defs: of ISO buffers available for controller. value: MYNEWT_VAL(BLE_TRANSPORT_ISO_COUNT) + BLE_TRANSPORT_RX_PRIO: + description: Priority of RX task + type: task_priority + value: 126 + BLE_TRANSPORT_RX_STACK_SIZE: + description: Stack size of RX task + value: + # import monitor and defunct settings from separate file to reduce clutter in main file $import: - "@apache-mynewt-nimble/nimble/transport/syscfg.monitor.yml" From c6dc666b8a5697118692216246cdc5b781f88ee2 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 20 Oct 2023 17:23:08 +0200 Subject: [PATCH 1051/1333] nimble/transport/nrf53: Move RX from interrupt to task This adds option to move RX from interrupt to task. This is enforced if monitor is used since montor code cannot be used from interrupts. --- .../transport/nrf5340/src/nrf5340_ble_hci.c | 31 ++++++++++++++----- nimble/transport/nrf5340/syscfg.yml | 28 +++++++++++++++++ 2 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 nimble/transport/nrf5340/syscfg.yml diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index 7f3c5efe27..c6e69f4062 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -36,6 +36,20 @@ static struct hci_ipc_sm g_hci_ipc_sm; +static void +rx_func(void *arg) +{ + uint8_t *buf; + int len; + + len = ipc_nrf5340_available_buf(IPC_RX_CHANNEL, (void **)&buf); + while (len > 0) { + len = hci_ipc_rx(&g_hci_ipc_sm, buf, len); + ipc_nrf5340_consume(IPC_RX_CHANNEL, len); + len = ipc_nrf5340_available_buf(IPC_RX_CHANNEL, (void **)&buf); + } +} + static int nrf5340_ble_hci_acl_tx(struct os_mbuf *om) { @@ -95,15 +109,13 @@ nrf5340_ble_hci_iso_tx(struct os_mbuf *om) static void nrf5340_ble_hci_trans_rx(int channel, void *user_data) { - uint8_t *buf; - int len; + assert(channel == IPC_RX_CHANNEL); - len = ipc_nrf5340_available_buf(channel, (void **)&buf); - while (len > 0) { - len = hci_ipc_rx(&g_hci_ipc_sm, buf, len); - ipc_nrf5340_consume(channel, len); - len = ipc_nrf5340_available_buf(channel, (void **)&buf); - } +#if MYNEWT_VAL(BLE_TRANSPORT_NRF5340_RX_TASK) + ble_transport_rx(); +#else + rx_func(NULL); +#endif } static void @@ -111,6 +123,9 @@ nrf5340_ble_hci_init(void) { SYSINIT_ASSERT_ACTIVE(); +#if MYNEWT_VAL(BLE_TRANSPORT_NRF5340_RX_TASK) + ble_transport_rx_register(rx_func, NULL); +#endif ipc_nrf5340_recv(IPC_RX_CHANNEL, nrf5340_ble_hci_trans_rx, NULL); } diff --git a/nimble/transport/nrf5340/syscfg.yml b/nimble/transport/nrf5340/syscfg.yml new file mode 100644 index 0000000000..2b05734078 --- /dev/null +++ b/nimble/transport/nrf5340/syscfg.yml @@ -0,0 +1,28 @@ +# 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. + +syscfg.defs: + BLE_TRANSPORT_NRF5340_RX_TASK: + description: > + Use separate task for RX. This is required and enabled by default + if monitor is used, optional otherwise. + value: 0 + +syscfg.vals.BLE_MONITOR: + BLE_TRANSPORT_NRF5340_RX_TASK: 1 + BLE_TRANSPORT_RX_PRIO: 1 + BLE_TRANSPORT_RX_STACK_SIZE: 120 From c5881fa5783adad9fcaabc10c74bfae42aa954b3 Mon Sep 17 00:00:00 2001 From: andrzej-kaczmarek <9692685+andrzej-kaczmarek@users.noreply.github.com> Date: Fri, 9 Aug 2024 10:28:40 +0000 Subject: [PATCH 1052/1333] porting: Update ports syscfg --- porting/examples/linux/include/syscfg/syscfg.h | 6 ++++++ porting/examples/linux_blemesh/include/syscfg/syscfg.h | 6 ++++++ porting/examples/nuttx/include/syscfg/syscfg.h | 6 ++++++ porting/nimble/include/syscfg/syscfg.h | 6 ++++++ porting/npl/riot/include/syscfg/syscfg.h | 6 ++++++ 5 files changed, 30 insertions(+) diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index 07d3945cda..9c3680da4b 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -1184,6 +1184,12 @@ #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO +#define MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO (126) +#endif + +#undef MYNEWT_VAL_BLE_TRANSPORT_RX_STACK_SIZE + #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index a476d88917..1bd9f42710 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -1732,6 +1732,12 @@ #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO +#define MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO (126) +#endif + +#undef MYNEWT_VAL_BLE_TRANSPORT_RX_STACK_SIZE + #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index c116f586aa..f9a75854ca 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -1184,6 +1184,12 @@ #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO +#define MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO (126) +#endif + +#undef MYNEWT_VAL_BLE_TRANSPORT_RX_STACK_SIZE + #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index 926b7756c1..4b32ec556b 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -1184,6 +1184,12 @@ #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO +#define MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO (126) +#endif + +#undef MYNEWT_VAL_BLE_TRANSPORT_RX_STACK_SIZE + #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) #endif diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 68203ad47c..de90aae2b4 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -2212,6 +2212,12 @@ #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO +#define MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO (126) +#endif + +#undef MYNEWT_VAL_BLE_TRANSPORT_RX_STACK_SIZE + #ifndef MYNEWT_VAL_BOOTUTIL_BOOTSTRAP #define MYNEWT_VAL_BOOTUTIL_BOOTSTRAP (0) #endif From a908b5e8db3868d197daa14c83ace137090caefe Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 9 Aug 2024 16:08:59 +0200 Subject: [PATCH 1053/1333] nimble/transport: Fix build with RX task Remove separate syscfg to enable RX task from nrf5340 transport package. RX task is now enabled if RX task stack size is set to a valid value. RX task priority should not be set to default value to avoid conflicts with other task priorities if RX task is not used (this is always verified by newt). Since empty value is not a valid priority we should better only define that setting if RX task is enabled. --- nimble/transport/nrf5340/src/nrf5340_ble_hci.c | 4 ++-- nimble/transport/nrf5340/syscfg.yml | 12 ++---------- nimble/transport/src/rx_task.c | 8 ++++---- nimble/transport/syscfg.yml | 14 ++++++++++---- 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index c6e69f4062..5da5398a04 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -111,7 +111,7 @@ nrf5340_ble_hci_trans_rx(int channel, void *user_data) { assert(channel == IPC_RX_CHANNEL); -#if MYNEWT_VAL(BLE_TRANSPORT_NRF5340_RX_TASK) +#if MYNEWT_VAL(BLE_TRANSPORT_RX_TASK) ble_transport_rx(); #else rx_func(NULL); @@ -123,7 +123,7 @@ nrf5340_ble_hci_init(void) { SYSINIT_ASSERT_ACTIVE(); -#if MYNEWT_VAL(BLE_TRANSPORT_NRF5340_RX_TASK) +#if MYNEWT_VAL(BLE_TRANSPORT_RX_TASK) ble_transport_rx_register(rx_func, NULL); #endif ipc_nrf5340_recv(IPC_RX_CHANNEL, nrf5340_ble_hci_trans_rx, NULL); diff --git a/nimble/transport/nrf5340/syscfg.yml b/nimble/transport/nrf5340/syscfg.yml index 2b05734078..a784a79299 100644 --- a/nimble/transport/nrf5340/syscfg.yml +++ b/nimble/transport/nrf5340/syscfg.yml @@ -15,14 +15,6 @@ # specific language governing permissions and limitations # under the License. -syscfg.defs: - BLE_TRANSPORT_NRF5340_RX_TASK: - description: > - Use separate task for RX. This is required and enabled by default - if monitor is used, optional otherwise. - value: 0 - syscfg.vals.BLE_MONITOR: - BLE_TRANSPORT_NRF5340_RX_TASK: 1 - BLE_TRANSPORT_RX_PRIO: 1 - BLE_TRANSPORT_RX_STACK_SIZE: 120 + BLE_TRANSPORT_RX_TASK_STACK_SIZE: 120 + BLE_TRANSPORT_RX_TASK_PRIO: 1 diff --git a/nimble/transport/src/rx_task.c b/nimble/transport/src/rx_task.c index 076990cdd3..4e7d7196a9 100644 --- a/nimble/transport/src/rx_task.c +++ b/nimble/transport/src/rx_task.c @@ -26,13 +26,13 @@ #include #include -#if !defined(MYNEWT) || MYNEWT_VAL(BLE_TRANSPORT_RX_STACK_SIZE) > 0 +#if !defined(MYNEWT) || MYNEWT_VAL(BLE_TRANSPORT_RX_TASK_STACK_SIZE) static ble_transport_rx_func_t *rx_func; static void *rx_func_arg; #if MYNEWT -OS_TASK_STACK_DEFINE(rx_stack, MYNEWT_VAL(BLE_TRANSPORT_RX_STACK_SIZE)); +OS_TASK_STACK_DEFINE(rx_stack, MYNEWT_VAL(BLE_TRANSPORT_RX_TASK_STACK_SIZE)); static struct os_task rx_task; #endif @@ -70,8 +70,8 @@ ble_transport_rx_register(ble_transport_rx_func_t *func, void *arg) #ifdef MYNEWT os_task_init(&rx_task, "hci_rx_task", rx_task_func, NULL, - MYNEWT_VAL(BLE_TRANSPORT_RX_PRIO), OS_WAIT_FOREVER, rx_stack, - MYNEWT_VAL(BLE_TRANSPORT_RX_STACK_SIZE)); + MYNEWT_VAL(BLE_TRANSPORT_RX_TASK_PRIO), OS_WAIT_FOREVER, + rx_stack, MYNEWT_VAL(BLE_TRANSPORT_RX_TASK_STACK_SIZE)); #endif } diff --git a/nimble/transport/syscfg.yml b/nimble/transport/syscfg.yml index 877c3db24c..c2b9ec1e91 100644 --- a/nimble/transport/syscfg.yml +++ b/nimble/transport/syscfg.yml @@ -110,12 +110,18 @@ syscfg.defs: of ISO buffers available for controller. value: MYNEWT_VAL(BLE_TRANSPORT_ISO_COUNT) - BLE_TRANSPORT_RX_PRIO: + BLE_TRANSPORT_RX_TASK_STACK_SIZE: + description: > + Stack size of RX task. + RX task is started if stack size is set to a valid value. + value: + +syscfg.defs.BLE_TRANSPORT_RX_TASK_STACK_SIZE: + BLE_TRANSPORT_RX_TASK: 1 + BLE_TRANSPORT_RX_TASK_PRIO: description: Priority of RX task type: task_priority - value: 126 - BLE_TRANSPORT_RX_STACK_SIZE: - description: Stack size of RX task + restrictions: $notnull value: # import monitor and defunct settings from separate file to reduce clutter in main file From 49db78462cf6267496a5d1efd81e9d522716243b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 9 Aug 2024 10:25:09 +0200 Subject: [PATCH 1054/1333] nimble/phy/cmac: Fix setting TX power level TX power is now configured using ble_ll_tx_power_set (instead of ble_phy_tx_power_set) which uses ble_phy_tx_power_round to calculate proper TX power level. This adds missing implementation for that function in CMAC PHY driver so power level can be properly set. --- nimble/drivers/dialog_cmac/src/ble_phy.c | 32 +++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index 4c0e4c942a..434aaa969e 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -1655,26 +1655,46 @@ ble_phy_encrypt_disable(void) } #endif +static int8_t +phy_txpower_round(int8_t dbm) +{ + static const int8_t supported_pwr_levels[] = {-18, -12, -8, -6, -3, -2, + -1, 0, 1, 2, 3, 4, 5, 6 }; + int i; + + for (i = 0; i < ARRAY_SIZE(supported_pwr_levels); i++) { + if (dbm <= supported_pwr_levels[i]) { + dbm = supported_pwr_levels[i]; + break; + } + } + + if (i == ARRAY_SIZE(supported_pwr_levels)) { + dbm = supported_pwr_levels[ARRAY_SIZE(supported_pwr_levels) - 1]; + } + + return dbm; +} + int ble_phy_tx_power_set(int dbm) { #if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE) if (g_cmac_shm_debugdata.tx_power_ovr_enable) { - ble_rf_set_tx_power(g_cmac_shm_debugdata.tx_power_ovr); - } else { - ble_rf_set_tx_power(dbm); + dbm = g_cmac_shm_debugdata.tx_power_ovr; } -#else - ble_rf_set_tx_power(dbm); #endif + dbm = phy_txpower_round(dbm); + ble_rf_set_tx_power(dbm); + return 0; } int ble_phy_tx_power_round(int dbm) { - return 0; + return phy_txpower_round(dbm); } int From f5e945ced363adc259b63250da959d1e6da83645 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 8 Aug 2024 15:24:29 +0200 Subject: [PATCH 1055/1333] nimble/audio: Change sizeof to ARRAY_SIZE This commit modifes loop expressions to use ARRAY_SIZE macro instead of sizeof. --- nimble/host/audio/services/bass/src/ble_audio_svc_bass.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index 1c4ff639e1..48a7a76b40 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -201,7 +201,7 @@ ble_svc_audio_bass_receive_state_notify(struct ble_svc_audio_bass_rcv_state_entr { int i; - for (i = 0; i < sizeof(ble_svc_audio_bass_chrs); i++) { + for (i = 0; i < ARRAY_SIZE(ble_svc_audio_bass_chrs); i++) { if (ble_svc_audio_bass_chrs[i].arg == state) { ble_gatts_chr_updated(*ble_svc_audio_bass_chrs[i].val_handle); return 0; @@ -217,7 +217,7 @@ ble_svc_audio_bass_receive_state_find_by_source_id(struct ble_svc_audio_bass_rcv { int i; - for (i = 0; i < sizeof(receiver_states); i++) { + for (i = 0; i < ARRAY_SIZE(receiver_states); i++) { if (receiver_states[i].source_id == source_id) { *out_state = &receiver_states[i]; return 0; @@ -232,7 +232,7 @@ ble_svc_audio_bass_receive_state_find_free(struct ble_svc_audio_bass_rcv_state_e { int i; - for (i = 0; i < sizeof(receiver_states); i++) { + for (i = 0; i < ARRAY_SIZE(receiver_states); i++) { if (receiver_states[i].source_id == BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE) { *out_state = &receiver_states[i]; return 0; From 14c049fd9afa49937092da0ebda054da21294cf2 Mon Sep 17 00:00:00 2001 From: rymanluk <2675599+rymanluk@users.noreply.github.com> Date: Mon, 19 Aug 2024 06:57:01 +0000 Subject: [PATCH 1056/1333] porting: Update ports syscfg --- porting/examples/linux/include/syscfg/syscfg.h | 6 +----- porting/examples/linux_blemesh/include/syscfg/syscfg.h | 6 +----- porting/examples/nuttx/include/syscfg/syscfg.h | 6 +----- porting/nimble/include/syscfg/syscfg.h | 6 +----- porting/npl/riot/include/syscfg/syscfg.h | 6 +----- 5 files changed, 5 insertions(+), 25 deletions(-) diff --git a/porting/examples/linux/include/syscfg/syscfg.h b/porting/examples/linux/include/syscfg/syscfg.h index 9c3680da4b..25dcac4786 100644 --- a/porting/examples/linux/include/syscfg/syscfg.h +++ b/porting/examples/linux/include/syscfg/syscfg.h @@ -1184,11 +1184,7 @@ #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif -#ifndef MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO -#define MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO (126) -#endif - -#undef MYNEWT_VAL_BLE_TRANSPORT_RX_STACK_SIZE +#undef MYNEWT_VAL_BLE_TRANSPORT_RX_TASK_STACK_SIZE #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h b/porting/examples/linux_blemesh/include/syscfg/syscfg.h index 1bd9f42710..ac89b3ba53 100644 --- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h +++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h @@ -1732,11 +1732,7 @@ #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif -#ifndef MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO -#define MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO (126) -#endif - -#undef MYNEWT_VAL_BLE_TRANSPORT_RX_STACK_SIZE +#undef MYNEWT_VAL_BLE_TRANSPORT_RX_TASK_STACK_SIZE #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h b/porting/examples/nuttx/include/syscfg/syscfg.h index f9a75854ca..d751e85677 100644 --- a/porting/examples/nuttx/include/syscfg/syscfg.h +++ b/porting/examples/nuttx/include/syscfg/syscfg.h @@ -1184,11 +1184,7 @@ #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif -#ifndef MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO -#define MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO (126) -#endif - -#undef MYNEWT_VAL_BLE_TRANSPORT_RX_STACK_SIZE +#undef MYNEWT_VAL_BLE_TRANSPORT_RX_TASK_STACK_SIZE #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) diff --git a/porting/nimble/include/syscfg/syscfg.h b/porting/nimble/include/syscfg/syscfg.h index 4b32ec556b..35d18efe70 100644 --- a/porting/nimble/include/syscfg/syscfg.h +++ b/porting/nimble/include/syscfg/syscfg.h @@ -1184,11 +1184,7 @@ #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif -#ifndef MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO -#define MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO (126) -#endif - -#undef MYNEWT_VAL_BLE_TRANSPORT_RX_STACK_SIZE +#undef MYNEWT_VAL_BLE_TRANSPORT_RX_TASK_STACK_SIZE #ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE #define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index de90aae2b4..c6d948e67a 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -2212,11 +2212,7 @@ #define MYNEWT_VAL_BLE_TRANSPORT_LL (1) #endif -#ifndef MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO -#define MYNEWT_VAL_BLE_TRANSPORT_RX_PRIO (126) -#endif - -#undef MYNEWT_VAL_BLE_TRANSPORT_RX_STACK_SIZE +#undef MYNEWT_VAL_BLE_TRANSPORT_RX_TASK_STACK_SIZE #ifndef MYNEWT_VAL_BOOTUTIL_BOOTSTRAP #define MYNEWT_VAL_BOOTUTIL_BOOTSTRAP (0) From cc1ddb64d2e483f04d7b486e8fe3cf6b43c2fb2e Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Mon, 12 Aug 2024 11:37:49 +0200 Subject: [PATCH 1057/1333] ci: Update `Check ports syscfg update` workflow Changes the author of commits to bot account. --- .github/workflows/ports_syscfg_check.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ports_syscfg_check.yml b/.github/workflows/ports_syscfg_check.yml index 0b8c6aa6a3..5755a490e9 100644 --- a/.github/workflows/ports_syscfg_check.yml +++ b/.github/workflows/ports_syscfg_check.yml @@ -92,6 +92,7 @@ jobs: - name: Create Pull Request uses: peter-evans/create-pull-request@v6 with: + author: Mynewt Bot token: ${{ secrets.GITHUB_TOKEN }} commit-message: | porting: Update ports syscfg From dff71a2888e4e46fef60c3e0c72cd95acdf4f7dd Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 9 Aug 2024 11:53:29 +0200 Subject: [PATCH 1058/1333] nimble/audio/bass: Modify remove source operation Fix event type in ble_audio_event structure. Add characteristic value in receive state. Remove goto pointing to goto itself. --- nimble/host/audio/services/bass/src/ble_audio_svc_bass.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index 48a7a76b40..87e4da2112 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -549,7 +549,7 @@ static int ble_svc_audio_bass_remove_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle) { struct ble_audio_event ev = { - .type = BLE_AUDIO_EVENT_BASS_BROADCAST_CODE_SET, + .type = BLE_AUDIO_EVENT_BASS_OPERATION_STATUS, .bass_operation_status = { .op = BLE_AUDIO_EVENT_BASS_SOURCE_REMOVED, .status = 0 @@ -557,10 +557,12 @@ ble_svc_audio_bass_remove_source(uint8_t *data, uint16_t data_len, uint16_t conn }; struct ble_svc_audio_bass_rcv_state_entry *rcv_state = NULL; struct ble_svc_audio_bass_operation operation; + uint16_t chr_val; int rc = 0; int i; ev.bass_set_broadcast_code.source_id = data[0]; + operation.op = BLE_SVC_AUDIO_BASS_OPERATION_REMOVE_SOURCE; ble_svc_audio_bass_receive_state_find_by_source_id(&rcv_state, ev.bass_operation_status.source_id); @@ -587,12 +589,12 @@ ble_svc_audio_bass_remove_source(uint8_t *data, uint16_t data_len, uint16_t conn memset(rcv_state, 0, sizeof(*rcv_state)); rcv_state->source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE; + rcv_state->chr_val = chr_val; done: if (!rc) { rc = ble_svc_audio_bass_receive_state_notify(rcv_state); ev.bass_operation_status.status = rc; - goto done; } ble_audio_event_listener_call(&ev); From 6f5b33ca0c33fd2c1421ffde61e096cff54c112e Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 8 Aug 2024 15:39:06 +0200 Subject: [PATCH 1059/1333] nimble/audio/bass: Add data length check in BASS remote scan This commit adds data length checks to remote scan operations. Now any data coming with remote scan start/stop will result in instant ATT error. --- nimble/host/audio/services/bass/src/ble_audio_svc_bass.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index 87e4da2112..dfad886bbe 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -251,6 +251,10 @@ ble_svc_audio_bass_receive_state_free(struct ble_svc_audio_bass_rcv_state_entry static int ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, uint16_t data_len, uint16_t conn_handle) { + if (data_len > 1) { + return BLE_ATT_ERR_WRITE_REQ_REJECTED; + } + struct ble_audio_event ev = { .type = BLE_AUDIO_EVENT_BASS_REMOTE_SCAN_STOPPED }; @@ -264,6 +268,10 @@ ble_svc_audio_bass_remote_scan_stopped(uint8_t *data, uint16_t data_len, uint16_ static int ble_svc_audio_bass_remote_scan_started(uint8_t *data, uint16_t data_len, uint16_t conn_handle) { + if (data_len > 1) { + return BLE_ATT_ERR_WRITE_REQ_REJECTED; + } + struct ble_audio_event ev = { .type = BLE_AUDIO_EVENT_BASS_REMOTE_SCAN_STARTED }; From cda8b20993a38e411fdfc10616bea9a0811d981a Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 8 Aug 2024 15:34:08 +0200 Subject: [PATCH 1060/1333] nimble/audio: Modify BASS control point write access Modify BASS control point write access in a way that it would use flattened mbuf to pass data to handler. Previous solution was prone to errors due to chained mbufs. Fix handler check from simple bool comparison to ensuring that it's not NULL. Add opcode variable to hold proper operation id in write access. This is helpful during debugging operations. --- .../audio/services/bass/src/ble_audio_svc_bass.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index dfad886bbe..451b766ddc 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -627,13 +627,16 @@ ble_svc_audio_bass_find_handler(uint8_t opcode) static int ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt, uint16_t conn_handle) { + uint8_t opcode; + struct os_mbuf *om; + uint16_t mbuf_len = OS_MBUF_PKTLEN(ctxt->om); struct ble_svc_audio_bass_ctrl_point_handler *handler; - uint8_t opcode = ctxt->om->om_data[0]; + opcode = ctxt->om->om_data[0]; handler = ble_svc_audio_bass_find_handler(opcode); - if (!handler) { + if (handler == NULL) { return BLE_SVC_AUDIO_BASS_ERR_OPCODE_NOT_SUPPORTED; } @@ -643,7 +646,12 @@ ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt, ui return BLE_ATT_ERR_WRITE_REQ_REJECTED; } - return handler->handler_cb(&ctxt->om->om_data[1], ctxt->om->om_len - 1, conn_handle); + ctxt->om = os_mbuf_pullup(ctxt->om, mbuf_len); + if (!ctxt->om) { + return BLE_ATT_ERR_UNLIKELY; + } + + return handler->handler_cb(&om->om_data[1], mbuf_len - 1, conn_handle); } static int From d007e11cbd9fb2064452a1fb654285ad8a0ba07c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 30 Aug 2024 16:27:06 +0200 Subject: [PATCH 1061/1333] nimble/transport: Fix race in nrf5340 IPC transport The HCI transport is initialized after LL task is initialized, but the IPC itself is initialized before LL task. If host on appcore starts before HCI transport is initialized on netcore, it can put HCI Reset in IPC shm before we can receive it and handle. This causes host to send 2nd HCI Reset which triggers handling of data in IPC shm and will fail because we cannot handle 2 HCI commands at the same time (i.e. 2x HCI Reset). This fixes the problem by triggering read from IPC shm just after HCI transport is initialized so we can handle command that was sent there before we were ready to receive it. --- nimble/transport/nrf5340/src/nrf5340_ble_hci.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index 5da5398a04..679cfb1241 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -121,12 +121,18 @@ nrf5340_ble_hci_trans_rx(int channel, void *user_data) static void nrf5340_ble_hci_init(void) { + os_sr_t sr; + SYSINIT_ASSERT_ACTIVE(); #if MYNEWT_VAL(BLE_TRANSPORT_RX_TASK) ble_transport_rx_register(rx_func, NULL); #endif ipc_nrf5340_recv(IPC_RX_CHANNEL, nrf5340_ble_hci_trans_rx, NULL); + + OS_ENTER_CRITICAL(sr); + nrf5340_ble_hci_trans_rx(IPC_RX_CHANNEL, NULL); + OS_EXIT_CRITICAL(sr); } #if MYNEWT_VAL(BLE_CONTROLLER) From 05cef9b1fa166828666da9fafc3d32d41f6a18ee Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 26 Apr 2024 15:25:23 +0200 Subject: [PATCH 1062/1333] apps/auracast: Make the code compile on native target This fixes auracast native build by disabling GPIO button functionality. --- apps/auracast/src/main.c | 15 +++++++++------ apps/auracast/syscfg.yml | 5 +++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/apps/auracast/src/main.c b/apps/auracast/src/main.c index 977d643cd0..ec4c86700f 100644 --- a/apps/auracast/src/main.c +++ b/apps/auracast/src/main.c @@ -60,12 +60,12 @@ static uint16_t bis_handles[MYNEWT_VAL(BROADCASTER_CHAN_NUM)]; static struct os_callout audio_broadcast_callout; static int audio_data_offset; +static uint8_t auracast_adv_instance; + +#if MYNEWT_VAL(BROADCASTER_STOP_BUTTON) >= 0 static struct os_task auracast_interrupt_task_str; static struct os_eventq auracast_interrupt_eventq; static os_stack_t auracast_interrupt_task_stack[BROADCASTER_INTERRUPT_TASK_STACK_SZ]; - -static uint8_t auracast_adv_instance; - static void auracast_interrupt_task(void *arg) { @@ -90,6 +90,7 @@ auracast_gpio_irq(void *arg) { os_eventq_put(&auracast_interrupt_eventq, &broadcast_stop_ev); } +#endif /* MYNEWT_VAL(BROADCASTER_STOP_BUTTON) >= 0 */ static void audio_broadcast_event_cb(struct os_event *ev) @@ -373,6 +374,7 @@ mynewt_main(int argc, char **argv) /* Set sync callback */ ble_hs_cfg.sync_cb = on_sync; +#if MYNEWT_VAL(BROADCASTER_STOP_BUTTON) >= 0 os_eventq_init(&auracast_interrupt_eventq); os_task_init(&auracast_interrupt_task_str, "auracast_interrupt_task", auracast_interrupt_task, NULL, @@ -380,9 +382,10 @@ mynewt_main(int argc, char **argv) auracast_interrupt_task_stack, BROADCASTER_INTERRUPT_TASK_STACK_SZ); - hal_gpio_irq_init(BUTTON_3, auracast_gpio_irq, NULL, - HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_UP); - hal_gpio_irq_enable(BUTTON_3); + hal_gpio_irq_init(MYNEWT_VAL(BROADCASTER_STOP_BUTTON), auracast_gpio_irq, + NULL, HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_UP); + hal_gpio_irq_enable(MYNEWT_VAL(BROADCASTER_STOP_BUTTON)); +#endif /* MYNEWT_VAL(BROADCASTER_STOP_BUTTON) >= 0 */ /* As the last thing, process events from default event queue */ while (1) { diff --git a/apps/auracast/syscfg.yml b/apps/auracast/syscfg.yml index f22b92d0b9..dc1b1a5b1d 100644 --- a/apps/auracast/syscfg.yml +++ b/apps/auracast/syscfg.yml @@ -18,6 +18,11 @@ syscfg.defs: BROADCASTER_CHAN_NUM: 2 BROADCASTER_BROADCAST_NAME: '"NimBLE Auracast"' + BROADCASTER_STOP_BUTTON: + description: > + Button number for Broadcast Stop action. + Negative value if disabled. + value: BUTTON_3 syscfg.vals: CONSOLE_IMPLEMENTATION: full From 22d5e0e042cacce4e6bd7f4a1463637c307bed96 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Thu, 1 Aug 2024 16:47:03 +0200 Subject: [PATCH 1063/1333] host: sm: ignore security request We should ignore second security request pairing has already started --- nimble/host/src/ble_sm.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index bb1dfe0842..eed5e3638b 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -2007,6 +2007,14 @@ ble_sm_sec_req_rx(uint16_t conn_handle, struct os_mbuf **om, ble_hs_lock(); conn = ble_hs_conn_find_assert(conn_handle); + + /* Check if pairing procedure is already in progress */ + if (ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_PAIR, 1, NULL)) { + ble_hs_unlock(); + res->app_status = 0; + return; + } + if (!(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CMD_NOT_SUPP); res->sm_err = BLE_SM_ERR_CMD_NOT_SUPP; From 2ed13eb7f4de575c70357a855784db109e16b296 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Thu, 8 Aug 2024 09:50:37 +0200 Subject: [PATCH 1064/1333] host: test: fix SM test case This test case should check if security request from peer sent after pairing request was ignored. --- nimble/host/test/src/ble_sm_test.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nimble/host/test/src/ble_sm_test.c b/nimble/host/test/src/ble_sm_test.c index 2ba1678d7b..7a2994be75 100644 --- a/nimble/host/test/src/ble_sm_test.c +++ b/nimble/host/test/src/ble_sm_test.c @@ -415,13 +415,14 @@ TEST_CASE_SELF(ble_sm_test_case_peer_sec_req_inval) fail.reason = BLE_SM_ERR_CMD_NOT_SUPP; ble_sm_test_util_verify_tx_pair_fail(&fail); - /*** Pairing already in progress; ignore security request. */ + /*** Pairing already in progress; ignore security request before pairing + * response was received. */ ble_hs_atomic_conn_set_flags(2, BLE_HS_CONN_F_MASTER, 1); rc = ble_sm_pair_initiate(2); TEST_ASSERT_FATAL(rc == 0); ble_hs_test_util_prev_tx_queue_clear(); - ble_sm_test_util_rx_sec_req(2, &sec_req, BLE_HS_EALREADY); + ble_sm_test_util_rx_sec_req(2, &sec_req, 0); TEST_ASSERT(ble_hs_test_util_prev_tx_queue_sz() == 0); ble_hs_test_util_assert_mbufs_freed(NULL); From baf2930d32c21222b77086181d842301bff9721f Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Fri, 23 Aug 2024 16:11:31 +0200 Subject: [PATCH 1065/1333] host: tests: add SM test case This covers the case where security request sent from peer should be rejected after pairing response was received. Move ble_sm_test_util_rx_pair_rsp() declaration. --- nimble/host/test/src/ble_sm_test.c | 31 +++++++++++++++++++++++++ nimble/host/test/src/ble_sm_test_util.c | 2 +- nimble/host/test/src/ble_sm_test_util.h | 3 +++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/nimble/host/test/src/ble_sm_test.c b/nimble/host/test/src/ble_sm_test.c index 7a2994be75..dcdbaf01ed 100644 --- a/nimble/host/test/src/ble_sm_test.c +++ b/nimble/host/test/src/ble_sm_test.c @@ -428,6 +428,36 @@ TEST_CASE_SELF(ble_sm_test_case_peer_sec_req_inval) ble_hs_test_util_assert_mbufs_freed(NULL); } +TEST_CASE_SELF(ble_sm_test_case_peer_sec_req_reject) +{ + struct ble_sm_sec_req sec_req; + int rc; + + struct ble_sm_pair_cmd pair_rsp = {0x04, 0, 0x0D, 10, 0x02, 0x02}; + + ble_sm_test_util_init(); + + ble_sm_dbg_set_next_pair_rand(((uint8_t[16]) {0})); + + ble_hs_test_util_create_conn(2, ((uint8_t[6]) {1,2,3,5,6,7}), + ble_sm_test_util_conn_cb, + NULL); + + /*** Pairing already in progress; reject security request after pairing + * response was received. */ + + ble_hs_atomic_conn_set_flags(2, BLE_HS_CONN_F_MASTER, 1); + rc = ble_sm_pair_initiate(2); + TEST_ASSERT_FATAL(rc == 0); + ble_hs_test_util_prev_tx_queue_clear(); + + ble_sm_test_util_rx_pair_rsp(2, &pair_rsp, 0); + ble_sm_test_util_rx_sec_req(2, &sec_req, BLE_HS_EALREADY); + TEST_ASSERT(ble_hs_test_util_prev_tx_queue_sz() != 0); + + ble_hs_test_util_assert_mbufs_freed(NULL); +} + /***************************************************************************** * $us * *****************************************************************************/ @@ -509,5 +539,6 @@ TEST_SUITE(ble_sm_gen_test_suite) ble_sm_test_case_peer_bonding_bad(); ble_sm_test_case_conn_broken(); ble_sm_test_case_peer_sec_req_inval(); + ble_sm_test_case_peer_sec_req_reject(); } #endif diff --git a/nimble/host/test/src/ble_sm_test_util.c b/nimble/host/test/src/ble_sm_test_util.c index e3becdf866..74d40e8b53 100644 --- a/nimble/host/test/src/ble_sm_test_util.c +++ b/nimble/host/test/src/ble_sm_test_util.c @@ -717,7 +717,7 @@ ble_sm_test_util_rx_pair_req(uint16_t conn_handle, req, rx_status); } -static void +void ble_sm_test_util_rx_pair_rsp(uint16_t conn_handle, struct ble_sm_pair_cmd *rsp, int rx_status) { diff --git a/nimble/host/test/src/ble_sm_test_util.h b/nimble/host/test/src/ble_sm_test_util.h index d9aa3805c7..3ddc86c1f1 100644 --- a/nimble/host/test/src/ble_sm_test_util.h +++ b/nimble/host/test/src/ble_sm_test_util.h @@ -96,6 +96,9 @@ void ble_sm_test_util_io_check_post( void ble_sm_test_util_rx_sec_req(uint16_t conn_handle, struct ble_sm_sec_req *cmd, int exp_status); +void ble_sm_test_util_rx_pair_rsp(uint16_t conn_handle, + struct ble_sm_pair_cmd *rsp, + int rx_status); void ble_sm_test_util_verify_tx_pair_fail(struct ble_sm_pair_fail *exp_cmd); void ble_sm_test_util_us_lgcy_good(struct ble_sm_test_params *params); void ble_sm_test_util_peer_fail_inval(int we_are_master, From f8d60614b7df21db77f0ff75e30ee104c71fa649 Mon Sep 17 00:00:00 2001 From: Deomid rojer Ryabkov Date: Mon, 2 Sep 2024 22:48:34 +0300 Subject: [PATCH 1066/1333] porting/npl/linux: Fix stuck callouts `ble_npl_callout.c_active` is not reset after callout is executed, so only the first callout fires and subsequent are not scheduled at all. Fixes https://github.com/apache/mynewt-nimble/issues/1771 --- porting/npl/linux/src/os_callout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porting/npl/linux/src/os_callout.c b/porting/npl/linux/src/os_callout.c index d3091fa9c8..76c8b2eefd 100644 --- a/porting/npl/linux/src/os_callout.c +++ b/porting/npl/linux/src/os_callout.c @@ -32,7 +32,7 @@ ble_npl_callout_timer_cb(union sigval sv) { struct ble_npl_callout *c = (struct ble_npl_callout *)sv.sival_ptr; assert(c); - + c->c_active = false; if (c->c_evq) { ble_npl_eventq_put(c->c_evq, &c->c_ev); } else { From 42e5a2816d0d3df397f69b63bf7420542e4cd7c2 Mon Sep 17 00:00:00 2001 From: Deomid rojer Ryabkov Date: Mon, 2 Sep 2024 22:42:41 +0300 Subject: [PATCH 1067/1333] porting/npl/linux: Handle EINTR from sem_timedwait It's been observed that `sem_timedwait()` can return `EINTR` even if `sigaction()` specified `SA_RESTART`. Not sure what the deal with that is but handling it is simple enough. --- porting/npl/linux/src/os_sem.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/porting/npl/linux/src/os_sem.c b/porting/npl/linux/src/os_sem.c index e3434af5a1..be43c64991 100644 --- a/porting/npl/linux/src/os_sem.c +++ b/porting/npl/linux/src/os_sem.c @@ -71,9 +71,14 @@ ble_npl_sem_pend(struct ble_npl_sem *sem, uint32_t timeout) wait.tv_sec += timeout / 1000; wait.tv_nsec += (timeout % 1000) * 1000000; - err = sem_timedwait(&sem->lock, &wait); - if (err && errno == ETIMEDOUT) { - return BLE_NPL_TIMEOUT; + while ((err = sem_timedwait(&sem->lock, &wait)) != 0) { + switch (errno) { + case EINTR: + continue; + case ETIMEDOUT: + return BLE_NPL_TIMEOUT; + } + break; } } From 7af0b740abda96635939bb25a6f07d0b162674ea Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 14 Aug 2024 15:05:37 +0530 Subject: [PATCH 1068/1333] nimble/host: Add support for ext adv param v2 HCI command --- nimble/host/include/host/ble_gap.h | 6 ++ nimble/host/src/ble_gap.c | 152 +++++++++++++++++++++-------- nimble/host/src/ble_hs_hci_priv.h | 2 +- nimble/host/src/ble_hs_startup.c | 5 +- nimble/include/nimble/hci_common.h | 8 ++ 5 files changed, 131 insertions(+), 42 deletions(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index e842ae29a7..33c56d76db 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -1582,6 +1582,12 @@ struct ble_gap_ext_adv_params { /** Advertising Set ID */ uint8_t sid; + + /** Primary phy options */ + uint8_t pri_phy_opt; + + /** Secondary phy options */ + uint8_t sec_phy_opt; }; /** diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 38da71200b..e0ddb88593 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -3124,45 +3124,38 @@ ble_gap_adv_active(void) #if MYNEWT_VAL(BLE_EXT_ADV) static int -ble_gap_ext_adv_params_tx(uint8_t instance, - const struct ble_gap_ext_adv_params *params, - int8_t *selected_tx_power) - +ble_gap_set_ext_adv_params(struct ble_hci_le_set_ext_adv_params_cp *cmd, + uint8_t instance, const struct ble_gap_ext_adv_params *params, + int8_t *selected_tx_power) { - struct ble_hci_le_set_ext_adv_params_cp cmd; - struct ble_hci_le_set_ext_adv_params_rp rsp; - int rc; - - memset(&cmd, 0, sizeof(cmd)); - - cmd.adv_handle = instance; + cmd->adv_handle = instance; if (params->connectable) { - cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE; + cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE; } if (params->scannable) { - cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE; + cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE; } if (params->directed) { - cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED; - cmd.peer_addr_type = params->peer.type; - memcpy(cmd.peer_addr, params->peer.val, BLE_DEV_ADDR_LEN); + cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED; + cmd->peer_addr_type = params->peer.type; + memcpy(cmd->peer_addr, params->peer.val, BLE_DEV_ADDR_LEN); } if (params->high_duty_directed) { - cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED; + cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED; } if (params->anonymous) { - cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV; + cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV; } if (params->include_tx_power) { - cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR; + cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR; } if (params->legacy_pdu) { - cmd.props |= BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY; + cmd->props |= BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY; /* check right away if the applied configuration is valid before handing * the command to the controller to improve error reporting */ - switch (cmd.props) { + switch (cmd->props) { case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_IND: case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_LD_DIR: case BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_HD_DIR: @@ -3177,38 +3170,58 @@ ble_gap_ext_adv_params_tx(uint8_t instance, /* Fill optional fields if application did not specify them. */ if (params->itvl_min == 0 && params->itvl_max == 0) { /* TODO for now limited to legacy values*/ - put_le24(cmd.pri_itvl_min, BLE_GAP_ADV_FAST_INTERVAL1_MIN); - put_le24(cmd.pri_itvl_max, BLE_GAP_ADV_FAST_INTERVAL2_MAX); + put_le24(cmd->pri_itvl_min, BLE_GAP_ADV_FAST_INTERVAL1_MIN); + put_le24(cmd->pri_itvl_max, BLE_GAP_ADV_FAST_INTERVAL2_MAX); } else { - put_le24(cmd.pri_itvl_min, params->itvl_min); - put_le24(cmd.pri_itvl_max, params->itvl_max); + put_le24(cmd->pri_itvl_min, params->itvl_min); + put_le24(cmd->pri_itvl_max, params->itvl_max); } if (params->channel_map == 0) { - cmd.pri_chan_map = BLE_GAP_ADV_DFLT_CHANNEL_MAP; + cmd->pri_chan_map = BLE_GAP_ADV_DFLT_CHANNEL_MAP; } else { - cmd.pri_chan_map = params->channel_map; + cmd->pri_chan_map = params->channel_map; } /* Zero is the default value for filter policy and high duty cycle */ - cmd.filter_policy = params->filter_policy; - cmd.tx_power = params->tx_power; + cmd->filter_policy = params->filter_policy; + cmd->tx_power = params->tx_power; if (params->legacy_pdu) { - cmd.pri_phy = BLE_HCI_LE_PHY_1M; - cmd.sec_phy = BLE_HCI_LE_PHY_1M; + cmd->pri_phy = BLE_HCI_LE_PHY_1M; + cmd->sec_phy = BLE_HCI_LE_PHY_1M; } else { - cmd.pri_phy = params->primary_phy; - cmd.sec_phy = params->secondary_phy; + cmd->pri_phy = params->primary_phy; + cmd->sec_phy = params->secondary_phy; } - cmd.own_addr_type = params->own_addr_type; - cmd.sec_max_skip = 0; - cmd.sid = params->sid; - cmd.scan_req_notif = params->scan_req_notif; + cmd->own_addr_type = params->own_addr_type; + cmd->sec_max_skip = 0; + cmd->sid = params->sid; + cmd->scan_req_notif = params->scan_req_notif; + + return 0; +} + +static int +ble_gap_ext_adv_params_tx_v1(uint8_t instance, + const struct ble_gap_ext_adv_params *params, + int8_t *selected_tx_power) +{ + struct ble_hci_le_set_ext_adv_params_cp cmd; + struct ble_hci_le_set_ext_adv_params_rp rsp; + int rc; + + memset(&cmd, 0, sizeof(cmd)); + + rc = ble_gap_set_ext_adv_params(&cmd, instance, params, selected_tx_power); + + if (rc != 0) { + return rc; + } rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, - BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM), + BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM), &cmd, sizeof(cmd), &rsp, sizeof(rsp)); if (rc != 0) { @@ -3220,6 +3233,69 @@ ble_gap_ext_adv_params_tx(uint8_t instance, } return 0; + +} + +static int +ble_gap_ext_adv_params_tx_v2(uint8_t instance, + const struct ble_gap_ext_adv_params *params, + int8_t *selected_tx_power) +{ + + struct ble_hci_le_set_ext_adv_params_v2_cp cmd; + struct ble_hci_le_set_ext_adv_params_rp rsp; + int rc; + + memset(&cmd, 0, sizeof(cmd)); + + rc = ble_gap_set_ext_adv_params(&(cmd.cmd), instance, params, selected_tx_power); + + if (rc != 0) { + return rc; + } + + cmd.pri_phy_opt = params->pri_phy_opt; + cmd.sec_phy_opt = params->sec_phy_opt; + + rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM_V2), + &cmd, sizeof(cmd), &rsp, sizeof(rsp)); + + if (rc != 0) { + return rc; + } + + if (selected_tx_power) { + *selected_tx_power = rsp.tx_power; + } + + return 0; +} + +static int +ble_gap_ext_adv_params_tx(uint8_t instance, + const struct ble_gap_ext_adv_params *params, + int8_t *selected_tx_power) +{ + struct ble_hs_hci_sup_cmd sup_cmd; + int rc = 0; + + sup_cmd = ble_hs_hci_get_hci_supported_cmd(); + + /* Return Error if phy is non-zero and controller doesn't support V2 */ + if (!((sup_cmd.commands[46] & 0x04) != 0) && + (params->primary_phy || params->secondary_phy)) { + return BLE_HS_EINVAL; + } + + if ((sup_cmd.commands[46] & 0x04) != 0) { + rc = ble_gap_ext_adv_params_tx_v2(instance, params, selected_tx_power); + return rc; + } + + rc = ble_gap_ext_adv_params_tx_v1(instance, params, selected_tx_power); + + return rc; } static int diff --git a/nimble/host/src/ble_hs_hci_priv.h b/nimble/host/src/ble_hs_hci_priv.h index 78621e046a..211f3f931c 100644 --- a/nimble/host/src/ble_hs_hci_priv.h +++ b/nimble/host/src/ble_hs_hci_priv.h @@ -80,7 +80,7 @@ struct hci_periodic_adv_params #endif struct ble_hs_hci_sup_cmd { - unsigned event_mask2 : 1; /** Indicates whether the controller supports the set event mask page 2 command */ + uint8_t commands[64]; }; extern uint16_t ble_hs_hci_avail_pkts; diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c index c23579547c..2f95880be9 100644 --- a/nimble/host/src/ble_hs_startup.c +++ b/nimble/host/src/ble_hs_startup.c @@ -82,8 +82,7 @@ ble_hs_startup_read_sup_cmd_tx(void) return rc; } - /* Only check support for Set Event ­Mask ­Page ­2 command */ - sup_cmd.event_mask2 = (rsp.commands[22] & 0x04) != 0; + memcpy(&sup_cmd.commands, &rsp.commands, sizeof(sup_cmd)); ble_hs_hci_set_hci_supported_cmd(sup_cmd); return 0; @@ -373,7 +372,7 @@ ble_hs_startup_set_evmask_tx(void) return rc; } - if ((version >= BLE_HCI_VER_BCS_4_1) && sup_cmd.event_mask2) { + if ((version >= BLE_HCI_VER_BCS_4_1) && ((sup_cmd.commands[22] & 0x04) != 0)) { /** * Enable the following events: * 0x0000000000800000 Authenticated Payload Timeout Event diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index b1f6261266..68f1538826 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -593,6 +593,7 @@ struct ble_hci_le_set_ext_adv_params_cp { uint8_t sid; uint8_t scan_req_notif; } __attribute__((packed)); + struct ble_hci_le_set_ext_adv_params_rp { int8_t tx_power; } __attribute__((packed)); @@ -1149,6 +1150,13 @@ struct ble_hci_le_subrate_req_cp { uint16_t supervision_tmo; } __attribute__((packed)); +#define BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM_V2 (0x007F) +struct ble_hci_le_set_ext_adv_params_v2_cp { + struct ble_hci_le_set_ext_adv_params_cp cmd; + uint8_t pri_phy_opt; + uint8_t sec_phy_opt; +} __attribute__((packed)); + #define BLE_HCI_OCF_LE_CS_RD_LOC_SUPP_CAP (0x0089) struct ble_hci_le_cs_rd_loc_supp_cap_rp { uint8_t num_config_supported; From dd1d28b07a159a65fc82e9be6321565475a97b7a Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Mon, 9 Sep 2024 14:38:34 +0200 Subject: [PATCH 1069/1333] nimble/host: Fix build for extended scan This eliminates "declared but not used" warnings. --- nimble/host/src/ble_gap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index e0ddb88593..39b6ace798 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -202,9 +202,11 @@ struct ble_gap_slave_state { static bssnz_t struct ble_gap_slave_state ble_gap_slave[BLE_ADV_INSTANCES]; +#if NIMBLE_BLE_ADVERTISE #if MYNEWT_VAL(BLE_EXT_ADV) static bool ext_adv_legacy_configured = false; #endif +#endif struct ble_gap_update_entry { SLIST_ENTRY(ble_gap_update_entry) next; @@ -2914,6 +2916,7 @@ ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, #endif } +#if NIMBLE_BLE_ADVERTISE #if MYNEWT_VAL(BLE_EXT_ADV) static int ble_gap_ext_adv_legacy_preconfigure(void) @@ -2945,6 +2948,7 @@ ble_gap_ext_adv_legacy_preconfigure(void) return 0; } #endif +#endif int ble_gap_adv_set_data(const uint8_t *data, int data_len) From 2fa42c38bc8b34a02a39cae44a179f3322b95dee Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 30 Aug 2024 16:26:52 +0200 Subject: [PATCH 1070/1333] nimble/drivers: Add driver for SKY66405 FEM This adds driver for SKY66405 FEM. The bypass function is only supported using dedicated pin (CPS). Enabling bypass by setting both CTX and CRX to high state is not supported due to limitation in FEM API. --- .../fem/sky66405/include/sky66405/sky66405.h | 37 ++++++ nimble/drivers/fem/sky66405/pkg.yml | 31 +++++ nimble/drivers/fem/sky66405/src/sky66405.c | 118 ++++++++++++++++++ nimble/drivers/fem/sky66405/syscfg.yml | 43 +++++++ 4 files changed, 229 insertions(+) create mode 100644 nimble/drivers/fem/sky66405/include/sky66405/sky66405.h create mode 100644 nimble/drivers/fem/sky66405/pkg.yml create mode 100644 nimble/drivers/fem/sky66405/src/sky66405.c create mode 100644 nimble/drivers/fem/sky66405/syscfg.yml diff --git a/nimble/drivers/fem/sky66405/include/sky66405/sky66405.h b/nimble/drivers/fem/sky66405/include/sky66405/sky66405.h new file mode 100644 index 0000000000..8a8edb0ed3 --- /dev/null +++ b/nimble/drivers/fem/sky66405/include/sky66405/sky66405.h @@ -0,0 +1,37 @@ +/* + * 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 _SKY66405_H +#define _SKY66405_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void sky66405_rx_bypass(uint8_t enabled); +void sky66405_tx_bypass(uint8_t enabled); + +#ifdef __cplusplus +} +#endif + +#endif /* _SKY66405_H */ diff --git a/nimble/drivers/fem/sky66405/pkg.yml b/nimble/drivers/fem/sky66405/pkg.yml new file mode 100644 index 0000000000..459c232048 --- /dev/null +++ b/nimble/drivers/fem/sky66405/pkg.yml @@ -0,0 +1,31 @@ +# +# 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: nimble/drivers/fem/sky66405 +pkg.description: Driver for SKY66405 front-end module +pkg.author: "Apache Mynewt " +pkg.homepage: "https://mynewt.apache.org/" +pkg.apis: + - ble_fem_pa + - ble_fem_lna +pkg.deps: + - nimble/controller + +pkg.init: + sky66405_init: 999 diff --git a/nimble/drivers/fem/sky66405/src/sky66405.c b/nimble/drivers/fem/sky66405/src/sky66405.c new file mode 100644 index 0000000000..c4eb7c24a4 --- /dev/null +++ b/nimble/drivers/fem/sky66405/src/sky66405.c @@ -0,0 +1,118 @@ +/* + * 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. + */ + +#include +#include +#include +#include + +static struct { + uint8_t rx_bypass : 1; + uint8_t tx_bypass : 1; +} sky66405_config = { + .rx_bypass = MYNEWT_VAL(SKY66405_RX_BYPASS), + .tx_bypass = MYNEWT_VAL(SKY66405_TX_BYPASS), +}; + +static void +sky66405_bypass(uint8_t enabled) +{ + /* this is called only if bypass is enabled which means CPS PIN is + * correctly set and there is no need to check it here. + */ + hal_gpio_write(MYNEWT_VAL(SKY66405_PIN_CPS), enabled); +} + +void +ble_fem_pa_init(void) +{ + sky66405_tx_bypass(0); +} + +void +ble_fem_pa_enable(void) +{ + if (sky66405_config.tx_bypass) { + sky66405_bypass(1); + } +} + +void +ble_fem_pa_disable(void) +{ + if (sky66405_config.tx_bypass) { + sky66405_bypass(0); + } +} + +void +ble_fem_lna_init(void) +{ + sky66405_rx_bypass(0); +} + +void +ble_fem_lna_enable(void) +{ + if (sky66405_config.rx_bypass) { + sky66405_bypass(1); + } +} + +void +ble_fem_lna_disable(void) +{ + if (sky66405_config.rx_bypass) { + sky66405_bypass(0); + } +} + +void +sky66405_rx_bypass(uint8_t enabled) +{ + int pin = MYNEWT_VAL(SKY66405_PIN_CPS); + + if (pin >= 0) { + sky66405_config.rx_bypass = enabled; + sky66405_bypass(enabled); + } +} + +void +sky66405_tx_bypass(uint8_t enabled) +{ + int pin = MYNEWT_VAL(SKY66405_PIN_CPS); + + if (pin >= 0) { + sky66405_config.tx_bypass = enabled; + sky66405_bypass(enabled); + } +} + +void +sky66405_init(void) +{ + int pin; + + /* Disable bypass, we'll enable it when needed */ + pin = MYNEWT_VAL(SKY66405_PIN_CPS); + if (pin >= 0) { + hal_gpio_init_out(pin, 0); + } +} diff --git a/nimble/drivers/fem/sky66405/syscfg.yml b/nimble/drivers/fem/sky66405/syscfg.yml new file mode 100644 index 0000000000..b961bd44de --- /dev/null +++ b/nimble/drivers/fem/sky66405/syscfg.yml @@ -0,0 +1,43 @@ +# 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. +# + +syscfg.defs: + SKY66405_PIN_CPS: + description: > + GPIO pin number to control CPS signal. + When set to '-1', pin state will not be changed and it should be + driven externally. + value: -1 + SKY66405_TX_BYPASS: + description: > + Enables bypass for TX which effectively disables operation as PA. + Only valid if CPS signal is controller by driver. + value: 0 + SKY66405_RX_BYPASS: + description: > + Enables bypass for RX which effectively disables operation as PA. + Only valid if CPS signal is controller by driver. + value: 0 + +syscfg.vals.!BLE_FEM_PA: + # Enable TX bypass by default if PA is disabled + SKY66405_TX_BYPASS: 1 + +syscfg.vals.!BLE_FEM_LNA: + # Enable RX bypass by default if LNA is disabled + SKY66405_RX_BYPASS: 1 From 5effa1d3a1fb924c0440c8474e8edbc3586ef4e5 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Tue, 10 Sep 2024 10:56:56 +0200 Subject: [PATCH 1071/1333] nimble/host: Fix ble_gap_ext_adv_params_tx and rename variables ble_gap_ext_adv_params_tx should check if PHY options != 0 Also rename variables for consistency. --- nimble/host/include/host/ble_gap.h | 8 ++++---- nimble/host/src/ble_gap.c | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h index 33c56d76db..9a1ead0049 100644 --- a/nimble/host/include/host/ble_gap.h +++ b/nimble/host/include/host/ble_gap.h @@ -1583,11 +1583,11 @@ struct ble_gap_ext_adv_params { /** Advertising Set ID */ uint8_t sid; - /** Primary phy options */ - uint8_t pri_phy_opt; + /** Primary PHY options */ + uint8_t primary_phy_opt; - /** Secondary phy options */ - uint8_t sec_phy_opt; + /** Secondary PHY options */ + uint8_t secondary_phy_opt; }; /** diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 39b6ace798..0beb39ee3e 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -3258,8 +3258,8 @@ ble_gap_ext_adv_params_tx_v2(uint8_t instance, return rc; } - cmd.pri_phy_opt = params->pri_phy_opt; - cmd.sec_phy_opt = params->sec_phy_opt; + cmd.pri_phy_opt = params->primary_phy_opt; + cmd.sec_phy_opt = params->secondary_phy_opt; rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM_V2), @@ -3288,7 +3288,7 @@ ble_gap_ext_adv_params_tx(uint8_t instance, /* Return Error if phy is non-zero and controller doesn't support V2 */ if (!((sup_cmd.commands[46] & 0x04) != 0) && - (params->primary_phy || params->secondary_phy)) { + (params->primary_phy_opt || params->secondary_phy_opt)) { return BLE_HS_EINVAL; } From deb78222b50588bf3a5b5b21d4c1d1a8b90522f7 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sun, 15 Sep 2024 17:02:47 +0200 Subject: [PATCH 1072/1333] nimble/ll: Fix non-connectable PDUs handling for initiator We should not reply on ADV_NONCONN_IND and SCAN_IND as initiator - those are not connectable so we'll just get connection failed to be established error. --- nimble/controller/src/ble_ll_scan.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 5530eabb26..670f6b38cb 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -1621,8 +1621,16 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok) switch (pdu_type) { case BLE_ADV_PDU_TYPE_ADV_IND: case BLE_ADV_PDU_TYPE_ADV_DIRECT_IND: + rc = ble_ll_scan_rx_isr_end_on_adv(pdu_type, rxbuf, hdr, &addrd); + break; case BLE_ADV_PDU_TYPE_ADV_NONCONN_IND: case BLE_ADV_PDU_TYPE_ADV_SCAN_IND: +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + if (scansm->scanp->scan_type == BLE_SCAN_TYPE_INITIATE) { + rc = -1; + break; + } +#endif rc = ble_ll_scan_rx_isr_end_on_adv(pdu_type, rxbuf, hdr, &addrd); break; case BLE_ADV_PDU_TYPE_SCAN_RSP: From 16e1bfc67966ba531d1c313f443ced7f66a2e15e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sun, 15 Sep 2024 17:02:23 +0200 Subject: [PATCH 1073/1333] nimble/host: Fix L2CAP update request event This fixes L2CAP update request event handling to be the same a connection update request as described in documentation. The copy of requested parameters is passed as peer_params while the original param struct is passed as self_params so application can update these if needed. --- nimble/host/src/ble_gap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 0beb39ee3e..b0ce6ff47b 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -2175,13 +2175,17 @@ ble_gap_rx_l2cap_update_req(uint16_t conn_handle, struct ble_gap_upd_params *params) { #if NIMBLE_BLE_CONNECT + struct ble_gap_upd_params peer_params; struct ble_gap_event event; int rc; + peer_params = *params; + memset(&event, 0, sizeof event); event.type = BLE_GAP_EVENT_L2CAP_UPDATE_REQ; event.conn_update_req.conn_handle = conn_handle; - event.conn_update_req.peer_params = params; + event.conn_update_req.peer_params = &peer_params; + event.conn_update_req.self_params = params; rc = ble_gap_call_conn_event_cb(&event, conn_handle); return rc; From 67f7e979f09fc72e4a5cf2c307af694594ecfefd Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Tue, 17 Sep 2024 11:21:03 +0200 Subject: [PATCH 1074/1333] documentation/sphinx: Fix formatting errors in `.rst` files Fixes broken references to other documents/sections. Adds `Host Identity` to the API reference. --- docs/README.rst | 6 +++--- docs/ble_hs/ble_hs_id.rst | 7 +++++++ docs/ble_setup/ble_addr.rst | 6 +++--- docs/btshell/btshell_GAP.rst | 2 +- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/README.rst b/docs/README.rst index ef2871c636..a05534a578 100644 --- a/docs/README.rst +++ b/docs/README.rst @@ -1,5 +1,5 @@ NimBLE Bluetooth Stack Documentation -################################# +#################################### This folder holds the documentation for the NimBLE Bluetooth stack from the `Apache Mynewt`_ project. It is built using `Sphinx`_. @@ -19,8 +19,8 @@ Previewing Changes ========================== In order to preview any changes you make you must first install a Sphinx -toolchain as described at https://github.com/apache/mynewt-documentation#id3. - Then: +toolchain as described at https://github.com/apache/mynewt-documentation. +Then: .. code-block:: bash diff --git a/docs/ble_hs/ble_hs_id.rst b/docs/ble_hs/ble_hs_id.rst index dbb47c9411..6e257e10a8 100644 --- a/docs/ble_hs/ble_hs_id.rst +++ b/docs/ble_hs/ble_hs_id.rst @@ -43,3 +43,10 @@ Header .. code-block:: cpp #include "host/ble_hs.h" + +API +~~~ + +.. doxygengroup:: bt_host_id + :content-only: + :members: diff --git a/docs/ble_setup/ble_addr.rst b/docs/ble_setup/ble_addr.rst index 0a67a5f774..bfd49923b8 100644 --- a/docs/ble_setup/ble_addr.rst +++ b/docs/ble_setup/ble_addr.rst @@ -52,12 +52,12 @@ Method 3: Configure a random address at runtime Random addresses get configured through the NimBLE host. The following two functions are used in random address configuration: -- :doc:`ble_hs_id_gen_rnd <../ble_hs/ble_hs_id/functions/ble_hs_id_gen_rnd>`: +- :c:func:`ble_hs_id_gen_rnd`: Generates a new random address. -- :doc:`ble_hs_id_set_rnd <../ble_hs/ble_hs_id/functions/ble_hs_id_set_rnd>`: +- :c:func:`ble_hs_id_set_rnd`: Sets the device's random address. -For an example of how this is done, see the :doc:`<../../../os/tutorials/ibeacon>`. +For an example of how this is done, see the :doc:`../../../tutorials/ble/ibeacon`. *Note:* A NimBLE device can be configured with multiple addresses; at most one of each address type. diff --git a/docs/btshell/btshell_GAP.rst b/docs/btshell/btshell_GAP.rst index 738d146c5b..2d52a16e1e 100644 --- a/docs/btshell/btshell_GAP.rst +++ b/docs/btshell/btshell_GAP.rst @@ -411,7 +411,7 @@ Advertising with Extended Advertising enabled +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ | | scan\_req\_notif | [``0``-1] | Enable SCAN\_REQ notifications | +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| **advertise-set-addr** | | | Configure *random* address for instance | +| **advertise-set-addr** | | | Configure *random* address for instance | +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ | | instance | [``0``-UINT8\_MAX] | Advertising instance | +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ From 1962ba172647002782b8879e6e10772efb79857c Mon Sep 17 00:00:00 2001 From: dmainz Date: Sat, 14 Sep 2024 13:00:13 -0500 Subject: [PATCH 1075/1333] nimble/host/src/ble_gap.c - undefined SET_BIT before defining it. The STM32 port also has a SET_BIT. --- nimble/host/src/ble_gap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index b0ce6ff47b..5a161a2763 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -41,6 +41,7 @@ #define bssnz_t #endif +#undef SET_BIT #define SET_BIT(t, n) (t |= 1UL << (n)) /** From caecb2c6283cc612551ef6a980ff1b5b9e51beb6 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 17 Sep 2024 16:32:30 +0200 Subject: [PATCH 1076/1333] porting/nuttx: Remove not used wqueue.h This looks like copy-and-paste from Linux port. --- porting/npl/nuttx/src/wqueue.h | 104 --------------------------------- 1 file changed, 104 deletions(-) delete mode 100644 porting/npl/nuttx/src/wqueue.h diff --git a/porting/npl/nuttx/src/wqueue.h b/porting/npl/nuttx/src/wqueue.h deleted file mode 100644 index 7821eacda6..0000000000 --- a/porting/npl/nuttx/src/wqueue.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - wqueue.h - Worker thread queue based on the Standard C++ library list - template class. - ------------------------------------------ - Copyright (c) 2013 Vic Hargrave - Licensed 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. -*/ - -// https://vichargrave.github.io/articles/2013-01/multithreaded-work-queue-in-cpp -// https://github.com/vichargrave/wqueue/blob/master/wqueue.h - - -#ifndef __wqueue_h__ -#define __wqueue_h__ - -#include -#include -#include - -struct wqueue_s -{ - dq_queue_s m_queue; - pthread_mutex_t m_mutex; - pthread_mutexattr_t m_mutex_attr; - pthread_cond_t m_condv; -}; - -using namespace std; - -template class wqueue -{ - dq_queue_s m_queue; - pthread_mutex_t m_mutex; - pthread_mutexattr_t m_mutex_attr; - pthread_cond_t m_condv; - -public: - wqueue() - { - dq_init(m_queue); - pthread_mutexattr_init(&m_mutex_attr); - pthread_mutexattr_settype(&m_mutex_attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&m_mutex, &m_mutex_attr); - pthread_cond_init(&m_condv, NULL); - } - - ~wqueue() { - pthread_mutex_destroy(&m_mutex); - pthread_cond_destroy(&m_condv); - } - - void put(T item) { - dq_entry_t* entry = malloc(sizeof(T)); - - pthread_mutex_lock(&m_mutex); - dq_addlast(entry, &m_queue); - m_queue.push_back(item); - pthread_cond_signal(&m_condv); - pthread_mutex_unlock(&m_mutex); - } - - T get(uint32_t tmo) { - pthread_mutex_lock(&m_mutex); - if (tmo) { - while (m_queue.size() == 0) { - pthread_cond_wait(&m_condv, &m_mutex); - } - } - - T item = NULL; - - if (m_queue.size() != 0) { - item = m_queue.front(); - m_queue.pop_front(); - } - - pthread_mutex_unlock(&m_mutex); - return item; - } - - void remove(T item) { - pthread_mutex_lock(&m_mutex); - m_queue.remove(item); - pthread_mutex_unlock(&m_mutex); - } - - int size() { - pthread_mutex_lock(&m_mutex); - int size = m_queue.size(); - pthread_mutex_unlock(&m_mutex); - return size; - } -}; - -#endif From a6331691e855ed5c5de66fcba3ba1133929e45ad Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Wed, 18 Sep 2024 11:21:35 +0200 Subject: [PATCH 1077/1333] nimble/host: Truncate data in ble_eatt_tx Data packets sent over eatt chan weren't correctly truncated. Data packet is now adjusted to peer device's MTU for the channel. Fixes various GATT/SR test cases that verify support for Read Long Characteristic Value Requests, Multiple Read Characteristic Value Requests etc. --- nimble/host/src/ble_eatt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c index c15f545b6d..96666c9d0f 100644 --- a/nimble/host/src/ble_eatt.c +++ b/nimble/host/src/ble_eatt.c @@ -476,6 +476,8 @@ ble_eatt_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom) goto error; } + ble_att_truncate_to_mtu(eatt->chan, txom); + rc = ble_l2cap_send(eatt->chan, txom); if (rc == 0) { goto done; From 519c14b34bd247bebc8177128e50a018f028f160 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Mon, 23 Sep 2024 13:51:03 +0200 Subject: [PATCH 1078/1333] nimble/audio: Use proper variable within scan delegator assert This commit changes subgroups filed in assert used in operation handler in scan delegator. Now proper defined array size is used. --- nimble/host/audio/src/ble_audio_scan_delegator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/audio/src/ble_audio_scan_delegator.c b/nimble/host/audio/src/ble_audio_scan_delegator.c index db580c6398..60e04adc36 100644 --- a/nimble/host/audio/src/ble_audio_scan_delegator.c +++ b/nimble/host/audio/src/ble_audio_scan_delegator.c @@ -194,7 +194,7 @@ bass_modify_source_op_handler(struct ble_svc_audio_bass_operation *op, void *arg sync_opt = &action.source_modify.sync_opt; sync_opt_init(sync_opt, op->modify_source.pa_sync, op->modify_source.pa_interval, NULL, 0); - BLE_AUDIO_DBG_ASSERT(sync_opt->num_subgroups < ARRAY_SIZE(subgroups)); + BLE_AUDIO_DBG_ASSERT(sync_opt->num_subgroups < ARRAY_SIZE(sync_opt->subgroups)); for (uint8_t i = 0; i < sync_opt->num_subgroups; i++) { sync_opt->subgroups[i].bis_sync = op->modify_source.bis_sync[i]; From 4f75c0b3b466186beff40e8489870c6cee076aaa Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 23 Sep 2024 14:20:15 +0200 Subject: [PATCH 1079/1333] nimble/mesh: Add check for rx buffer in PB ADV Validate if Transaction Continuation PDU can fit into buffer before copying data. --- nimble/host/mesh/src/pb_adv.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/nimble/host/mesh/src/pb_adv.c b/nimble/host/mesh/src/pb_adv.c index 19d179c850..76b96ae365 100644 --- a/nimble/host/mesh/src/pb_adv.c +++ b/nimble/host/mesh/src/pb_adv.c @@ -32,6 +32,7 @@ #define START_PAYLOAD_MAX 20 #define CONT_PAYLOAD_MAX 23 +#define RX_BUFFER_MAX 65 #define START_LAST_SEG(gpc) (gpc >> 2) #define CONT_SEG_INDEX(gpc) (gpc >> 2) @@ -41,7 +42,8 @@ #define LINK_ACK 0x01 #define LINK_CLOSE 0x02 -#define XACT_SEG_DATA(_seg) (&link.rx.buf->om_data[20 + ((_seg - 1) * 23)]) +#define XACT_SEG_OFFSET(_seg) (20 + ((_seg - 1) * 23)) +#define XACT_SEG_DATA(_seg) (&link.rx.buf->om_data[XACT_SEG_OFFSET(_seg)]) #define XACT_SEG_RECV(_seg) (link.rx.seg &= ~(1 << (_seg))) #define XACT_ID_MAX 0x7f @@ -224,7 +226,7 @@ static void reset_adv_link(void) } link.tx.pending_ack = XACT_ID_NVAL; if (!rx_buf) { - rx_buf = NET_BUF_SIMPLE(65); + rx_buf = NET_BUF_SIMPLE(RX_BUFFER_MAX); } link.rx.buf = rx_buf; net_buf_simple_reset(link.rx.buf); @@ -388,6 +390,11 @@ static void gen_prov_cont(struct prov_rx *rx, struct os_mbuf *buf) return; } + if (XACT_SEG_OFFSET(seg) + buf->om_len > RX_BUFFER_MAX) { + BT_WARN("Rx buffer overflow. Malformed generic prov frame?"); + return; + } + memcpy(XACT_SEG_DATA(seg), buf->om_data, buf->om_len); XACT_SEG_RECV(seg); @@ -892,7 +899,7 @@ void pb_adv_init(void) k_work_init_delayable(&link.tx.retransmit, prov_retransmit); if (!rx_buf) { - rx_buf = NET_BUF_SIMPLE(65); + rx_buf = NET_BUF_SIMPLE(RX_BUFFER_MAX); } link.rx.buf = rx_buf; net_buf_simple_reset(link.rx.buf); From bd739129210b6c6b3653dd058271ed3f831eeb3e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 18 Sep 2024 00:36:37 +0200 Subject: [PATCH 1080/1333] nimble/host: Preempt GAP operations before removing entry from RL --- nimble/host/src/ble_hs_pvcy.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_hs_pvcy.c b/nimble/host/src/ble_hs_pvcy.c index dc09b51ba8..f7cf090c09 100644 --- a/nimble/host/src/ble_hs_pvcy.c +++ b/nimble/host/src/ble_hs_pvcy.c @@ -59,8 +59,8 @@ ble_hs_pvcy_set_resolve_enabled(int enable) &cmd, sizeof(cmd), NULL, 0); } -int -ble_hs_pvcy_remove_entry(uint8_t addr_type, const uint8_t *addr) +static int +ble_hs_pvcy_remove_entry_hci(uint8_t addr_type, const uint8_t *addr) { struct ble_hci_le_rmv_resolve_list_cp cmd; @@ -76,6 +76,21 @@ ble_hs_pvcy_remove_entry(uint8_t addr_type, const uint8_t *addr) &cmd, sizeof(cmd), NULL, 0); } +int +ble_hs_pvcy_remove_entry(uint8_t addr_type, const uint8_t *addr) +{ + int rc; + + /* Need to preempt all GAP procedures (advertising, pending connections) + * before modifying resolving list in the controller + */ + ble_gap_preempt(); + rc = ble_hs_pvcy_remove_entry_hci(addr_type, addr); + ble_gap_preempt_done(); + + return rc; +} + static int ble_hs_pvcy_clear_entries(void) { From 845ea65aca8c341b104e17999ff0a45b22c9e673 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 23 Sep 2024 17:34:57 +0200 Subject: [PATCH 1081/1333] apps/auracast_usb: Fix default value for BIG PHY Should be 2M. --- apps/auracast_usb/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/auracast_usb/syscfg.yml b/apps/auracast_usb/syscfg.yml index 0796128343..9c44c9d438 100644 --- a/apps/auracast_usb/syscfg.yml +++ b/apps/auracast_usb/syscfg.yml @@ -44,7 +44,7 @@ syscfg.defs: BIG_PHY: description: - value: 3 + value: 2 BIG_NUM_BIS: description: Max number of BISes used value: 2 From f39330866a85fa4de49246e9d21334bc8d14f0a1 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 23 Sep 2024 15:10:28 +0200 Subject: [PATCH 1082/1333] nimble/host: Validate advertising instance before parsing event Advertising instance is used for indexing slave state array. Since instance is provided by host invalid handle in event means there is bug in controller. --- nimble/host/src/ble_hs_hci_evt.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 48012f3b47..3cb5f9858f 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -879,6 +879,13 @@ ble_hs_hci_evt_le_adv_set_terminated(uint8_t subevent, const void *data, return BLE_HS_ECONTROLLER; } + /* this indicates bug in controller as host uses instances from + * 0-BLE_ADV_INSTANCES range only + */ + if (ev->adv_handle >= BLE_ADV_INSTANCES) { + return BLE_HS_ECONTROLLER; + } + if (ev->status == 0) { /* ignore return code as we need to terminate advertising set anyway */ ble_gap_rx_conn_complete(&pend_conn_complete, ev->adv_handle); @@ -900,6 +907,13 @@ ble_hs_hci_evt_le_scan_req_rcvd(uint8_t subevent, const void *data, return BLE_HS_ECONTROLLER; } + /* this indicates bug in controller as host uses instances from + * 0-BLE_ADV_INSTANCES range only + */ + if (ev->adv_handle >= BLE_ADV_INSTANCES) { + return BLE_HS_ECONTROLLER; + } + ble_gap_rx_scan_req_rcvd(ev); #endif From 3b7a32ea09a3bffaab831ee0ab193a2375fc4df6 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 23 Sep 2024 15:57:46 +0200 Subject: [PATCH 1083/1333] nimble/host: Fix legacy advertising report event validation If event contained more than one report it would likely failed validation due to invalid data comparison. --- nimble/host/src/ble_hs_hci_evt.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 3cb5f9858f..181a2fb487 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -479,15 +479,13 @@ ble_hs_hci_evt_le_adv_rpt_first_pass(const void *data, unsigned int len) rpt = data; - len -= sizeof(*rpt) + 1; - data += sizeof(rpt) + 1; - if (rpt->data_len > len) { return BLE_HS_ECONTROLLER; } - len -= rpt->data_len; - data += rpt->data_len; + /* extra byte for RSSI after adv data */ + len -= sizeof(*rpt) + 1 + rpt->data_len; + data += sizeof(*rpt) + 1 + rpt->data_len; } /* Make sure length was correct */ From 23d61150ddae4bc8356356d7ef09d816fb89da45 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 23 Sep 2024 15:59:46 +0200 Subject: [PATCH 1084/1333] nimble/host: Add extended advertising report event validation Validate if HCI event received from controller has proper sizes before passing it to GAP event. --- nimble/host/src/ble_hs_hci_evt.c | 53 +++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 181a2fb487..37265c016c 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -597,29 +597,66 @@ ble_hs_hci_decode_legacy_type(uint16_t evt_type) return -1; } } -#endif static int -ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, const void *data, - unsigned int len) +ble_hs_hci_evt_le_ext_adv_rpt_first_pass(const void *data, unsigned int len) { -#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN const struct ble_hci_ev_le_subev_ext_adv_rpt *ev = data; const struct ext_adv_report *report; - struct ble_gap_ext_disc_desc desc; int i; - int legacy_event_type; if (len < sizeof(*ev)) { - return BLE_HS_EBADDATA; + return BLE_HS_ECONTROLLER; } + len -= sizeof(*ev); + data += sizeof(*ev); + if (ev->num_reports < BLE_HCI_LE_ADV_RPT_NUM_RPTS_MIN || ev->num_reports > BLE_HCI_LE_ADV_RPT_NUM_RPTS_MAX) { return BLE_HS_EBADDATA; } - /* TODO properly validate len of the event */ + for (i = 0; i < ev->num_reports; i++) { + if (len < sizeof(*report)) { + return BLE_HS_ECONTROLLER; + } + + report = data; + + if (report->data_len > len) { + return BLE_HS_ECONTROLLER; + } + + len -= sizeof(*report) + report->data_len; + data += sizeof(*report) + report->data_len; + } + + /* Make sure length was correct */ + if (len) { + return BLE_HS_ECONTROLLER; + } + + return 0; +} +#endif + +static int +ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, const void *data, + unsigned int len) +{ +#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN + const struct ble_hci_ev_le_subev_ext_adv_rpt *ev = data; + const struct ext_adv_report *report; + struct ble_gap_ext_disc_desc desc; + int legacy_event_type; + int rc; + int i; + + rc = ble_hs_hci_evt_le_ext_adv_rpt_first_pass(data, len); + if (rc != 0) { + return rc; + } report = &ev->reports[0]; for (i = 0; i < ev->num_reports; i++) { From 363d97a5aeee22799938bb9cf0b7ba00a912639b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 23 Sep 2024 16:29:48 +0200 Subject: [PATCH 1085/1333] nimble/host: Don't assert on unknown data status Just skip advertising report if it has been reported with reserved data status. --- nimble/host/src/ble_hs_hci_evt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 37265c016c..a8b95108b5 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -683,7 +683,8 @@ ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, const void *data, desc.data_status = BLE_GAP_EXT_ADV_DATA_STATUS_TRUNCATED; break; default: - assert(false); + report = (const void *) &report->data[report->data_len]; + continue; } } desc.addr.type = report->addr_type; From 1cdbbe8a79e4592db5d439f2b4ec8bce936287d2 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 23 Sep 2024 17:35:09 +0200 Subject: [PATCH 1086/1333] nimble/ll: Fix RTN handling in HCI BIG Create RTN is number of retransmissions onlt so IRC=RTN+1. --- nimble/controller/src/ble_ll_iso_big.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index d4a492b296..b07e5c1d86 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -1302,9 +1302,9 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len) /* FIXME for now we only care about retransmissions, so set both NSE and IRC * to RTN */ - bp.nse = MIN(cmd->rtn, 0x0f);; + bp.nse = MIN(cmd->rtn + 1, 0x0f);; bp.bn = 1; - bp.irc = MIN(cmd->rtn, 0x0f); + bp.irc = MIN(cmd->rtn + 1, 0x0f); bp.pto = 0; bp.iso_interval = bp.sdu_interval / 1250; bp.max_pdu = bp.max_sdu; From 5baa3f4ba09654e837ab9ed0c1880a67f6a3fbd5 Mon Sep 17 00:00:00 2001 From: Wojciech Pietraszewski Date: Thu, 26 Sep 2024 14:38:54 +0200 Subject: [PATCH 1087/1333] docs: Fix the layout in multiple .rst files for the PDF output Fixes formatting issues in the following categories: - BLE HS - btshell - mesh --- docs/ble_hs/ble_hs_return_codes.rst | 606 ++++++------- docs/btshell/btshell_GAP.rst | 1213 ++++++++++++++------------- docs/btshell/btshell_GATT.rst | 193 ++--- docs/btshell/btshell_advdata.rst | 82 +- docs/mesh/index.rst | 1 + 5 files changed, 1069 insertions(+), 1026 deletions(-) diff --git a/docs/ble_hs/ble_hs_return_codes.rst b/docs/ble_hs/ble_hs_return_codes.rst index c69cc4f8d4..5cce93d60e 100644 --- a/docs/ble_hs/ble_hs_return_codes.rst +++ b/docs/ble_hs/ble_hs_return_codes.rst @@ -121,317 +121,335 @@ Return codes - Core The precise meaning of each of these error codes depends on the function that returns it. The API reference for a particular function indicates the conditions under which each of these codes are returned. -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| Value | Name | Condition | -+=========+==============================+=============================================================================================+ -| 0x00 | *N/A* | Success | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x01 | BLE\_HS\_EAGAIN | Temporary failure; try again. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x02 | BLE\_HS\_EALREADY | Operation already in progress or completed. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x03 | BLE\_HS\_EINVAL | One or more arguments are invalid. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x04 | BLE\_HS\_EMSGSIZE | The provided buffer is too small. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x05 | BLE\_HS\_ENOENT | No entry matching the specified criteria. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x06 | BLE\_HS\_ENOMEM | Operation failed due to resource exhaustion. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x07 | BLE\_HS\_ENOTCONN | No open connection with the specified handle. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x08 | BLE\_HS\_ENOTSUP | Operation disabled at compile time. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x09 | BLE\_HS\_EAPP | Application callback behaved unexpectedly. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x0a | BLE\_HS\_EBADDATA | Command from peer is invalid. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x0b | BLE\_HS\_EOS | Mynewt OS error. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x0c | BLE\_HS\_ECONTROLLER | Event from controller is invalid. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x0d | BLE\_HS\_ETIMEOUT | Operation timed out. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x0e | BLE\_HS\_EDONE | Operation completed successfully. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x0f | BLE\_HS\_EBUSY | Operation cannot be performed until procedure completes. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x10 | BLE\_HS\_EREJECT | Peer rejected a connection parameter update request. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x11 | BLE\_HS\_EUNKNOWN | Unexpected failure; catch all. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x12 | BLE\_HS\_EROLE | Operation requires different role (e.g., central vs. peripheral). | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x13 | BLE\_HS\_ETIMEOUT\_HCI | HCI request timed out; controller unresponsive. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x14 | BLE\_HS\_ENOMEM\_EVT | Controller failed to send event due to memory exhaustion (combined host-controller only). | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x15 | BLE\_HS\_ENOADDR | Operation requires an identity address but none configured. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x16 | BLE\_HS\_ENOTSYNCED | Attempt to use the host before it is synced with controller. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x17 | BLE\_HS\_EAUTHEN | Insufficient authentication. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x18 | BLE\_HS\_EAUTHOR | Insufficient authorization. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x19 | BLE\_HS\_EENCRYPT | Insufficient encryption level. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x1a | BLE\_HS\_EENCRYPT\_KEY\_SZ | Insufficient key size. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x1b | BLE\_HS\_ESTORE\_CAP | Storage at capacity. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ -| 0x1c | BLE\_HS\_ESTORE\_FAIL | Storage IO error. | -+---------+------------------------------+---------------------------------------------------------------------------------------------+ +.. table:: Return codes - Core + :widths: 10 30 60 + + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | Value | Name | Condition | + +=========+==============================+=============================================================================================+ + | 0x00 | *N/A* | Success | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x01 | BLE\_HS\_EAGAIN | Temporary failure; try again. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x02 | BLE\_HS\_EALREADY | Operation already in progress or completed. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x03 | BLE\_HS\_EINVAL | One or more arguments are invalid. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x04 | BLE\_HS\_EMSGSIZE | The provided buffer is too small. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x05 | BLE\_HS\_ENOENT | No entry matching the specified criteria. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x06 | BLE\_HS\_ENOMEM | Operation failed due to resource exhaustion. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x07 | BLE\_HS\_ENOTCONN | No open connection with the specified handle. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x08 | BLE\_HS\_ENOTSUP | Operation disabled at compile time. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x09 | BLE\_HS\_EAPP | Application callback behaved unexpectedly. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x0a | BLE\_HS\_EBADDATA | Command from peer is invalid. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x0b | BLE\_HS\_EOS | Mynewt OS error. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x0c | BLE\_HS\_ECONTROLLER | Event from controller is invalid. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x0d | BLE\_HS\_ETIMEOUT | Operation timed out. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x0e | BLE\_HS\_EDONE | Operation completed successfully. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x0f | BLE\_HS\_EBUSY | Operation cannot be performed until procedure completes. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x10 | BLE\_HS\_EREJECT | Peer rejected a connection parameter update request. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x11 | BLE\_HS\_EUNKNOWN | Unexpected failure; catch all. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x12 | BLE\_HS\_EROLE | Operation requires different role (e.g., central vs. peripheral). | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x13 | BLE\_HS\_ETIMEOUT\_HCI | HCI request timed out; controller unresponsive. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x14 | BLE\_HS\_ENOMEM\_EVT | Controller failed to send event due to memory exhaustion (combined host-controller only). | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x15 | BLE\_HS\_ENOADDR | Operation requires an identity address but none configured. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x16 | BLE\_HS\_ENOTSYNCED | Attempt to use the host before it is synced with controller. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x17 | BLE\_HS\_EAUTHEN | Insufficient authentication. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x18 | BLE\_HS\_EAUTHOR | Insufficient authorization. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x19 | BLE\_HS\_EENCRYPT | Insufficient encryption level. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x1a | BLE\_HS\_EENCRYPT\_KEY\_SZ | Insufficient key size. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x1b | BLE\_HS\_ESTORE\_CAP | Storage at capacity. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ + | 0x1c | BLE\_HS\_ESTORE\_FAIL | Storage IO error. | + +---------+------------------------------+---------------------------------------------------------------------------------------------+ Return codes - ATT ^^^^^^^^^^^^^^^^^^ -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| NimBLE Value | Formal Value | Name | Condition | -+================+================+============================================+===========================================================================================================================================+ -| 0x0101 | 0x01 | BLE\_ATT\_ERR\_INVALID\_HANDLE | The attribute handle given was not valid on this server. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0102 | 0x02 | BLE\_ATT\_ERR\_READ\_NOT\_PERMITTED | The attribute cannot be read. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0103 | 0x03 | BLE\_ATT\_ERR\_WRITE\_NOT\_PERMITTED | The attribute cannot be written. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0104 | 0x04 | BLE\_ATT\_ERR\_INVALID\_PDU | The attribute PDU was invalid. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0105 | 0x05 | BLE\_ATT\_ERR\_INSUFFICIENT\_AUTHEN | The attribute requires authentication before it can be read or written. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0106 | 0x06 | BLE\_ATT\_ERR\_REQ\_NOT\_SUPPORTED | Attribute server does not support the request received from the client. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0107 | 0x07 | BLE\_ATT\_ERR\_INVALID\_OFFSET | Offset specified was past the end of the attribute. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0108 | 0x08 | BLE\_ATT\_ERR\_INSUFFICIENT\_AUTHOR | The attribute requires authorization before it can be read or written. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0109 | 0x09 | BLE\_ATT\_ERR\_PREPARE\_QUEUE\_FULL | Too many prepare writes have been queued. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x010a | 0x0a | BLE\_ATT\_ERR\_ATTR\_NOT\_FOUND | No attribute found within the given attribute handle range. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x010b | 0x0b | BLE\_ATT\_ERR\_ATTR\_NOT\_LONG | The attribute cannot be read or written using the Read Blob Request. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x010c | 0x0c | BLE\_ATT\_ERR\_INSUFFICIENT\_KEY\_SZ | The Encryption Key Size used for encrypting this link is insufficient. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x010d | 0x0d | BLE\_ATT\_ERR\_INVALID\_ATTR\_VALUE\_LEN | The attribute value length is invalid for the operation. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x010e | 0x0e | BLE\_ATT\_ERR\_UNLIKELY | The attribute request that was requested has encountered an error that was unlikely, and therefore could not be completed as requested. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x010f | 0x0f | BLE\_ATT\_ERR\_INSUFFICIENT\_ENC | The attribute requires encryption before it can be read or written. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0110 | 0x10 | BLE\_ATT\_ERR\_UNSUPPORTED\_GROUP | The attribute type is not a supported grouping attribute as defined by a higher layer specification. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0111 | 0x11 | BLE\_ATT\_ERR\_INSUFFICIENT\_RES | Insufficient Resources to complete the request. | -+----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +.. table:: Return codes - ATT + :widths: 11 10 45 34 + + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | NimBLE Value | Formal Value | Name | Condition | + +================+================+============================================+===========================================================================================================================================+ + | 0x0101 | 0x01 | BLE\_ATT\_ERR\_INVALID\_HANDLE | The attribute handle given was not valid on this server. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0102 | 0x02 | BLE\_ATT\_ERR\_READ\_NOT\_PERMITTED | The attribute cannot be read. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0103 | 0x03 | BLE\_ATT\_ERR\_WRITE\_NOT\_PERMITTED | The attribute cannot be written. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0104 | 0x04 | BLE\_ATT\_ERR\_INVALID\_PDU | The attribute PDU was invalid. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0105 | 0x05 | BLE\_ATT\_ERR\_INSUFFICIENT\_AUTHEN | The attribute requires authentication before it can be read or written. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0106 | 0x06 | BLE\_ATT\_ERR\_REQ\_NOT\_SUPPORTED | Attribute server does not support the request received from the client. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0107 | 0x07 | BLE\_ATT\_ERR\_INVALID\_OFFSET | Offset specified was past the end of the attribute. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0108 | 0x08 | BLE\_ATT\_ERR\_INSUFFICIENT\_AUTHOR | The attribute requires authorization before it can be read or written. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0109 | 0x09 | BLE\_ATT\_ERR\_PREPARE\_QUEUE\_FULL | Too many prepare writes have been queued. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x010a | 0x0a | BLE\_ATT\_ERR\_ATTR\_NOT\_FOUND | No attribute found within the given attribute handle range. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x010b | 0x0b | BLE\_ATT\_ERR\_ATTR\_NOT\_LONG | The attribute cannot be read or written using the Read Blob Request. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x010c | 0x0c | BLE\_ATT\_ERR\_INSUFFICIENT\_KEY\_SZ | The Encryption Key Size used for encrypting this link is insufficient. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x010d | 0x0d | BLE\_ATT\_ERR\_INVALID\_ATTR\_VALUE\_LEN | The attribute value length is invalid for the operation. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x010e | 0x0e | BLE\_ATT\_ERR\_UNLIKELY | The attribute request that was requested has encountered an error that was unlikely, and therefore could not be completed as requested. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x010f | 0x0f | BLE\_ATT\_ERR\_INSUFFICIENT\_ENC | The attribute requires encryption before it can be read or written. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0110 | 0x10 | BLE\_ATT\_ERR\_UNSUPPORTED\_GROUP | The attribute type is not a supported grouping attribute as defined by a higher layer specification. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0111 | 0x11 | BLE\_ATT\_ERR\_INSUFFICIENT\_RES | Insufficient Resources to complete the request. | + +----------------+----------------+--------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ Return codes - HCI ^^^^^^^^^^^^^^^^^^ -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| NimBLE Value | Formal Value | Name | Condition | -+================+================+====================================+================================================================================+ -| 0x0201 | 0x01 | BLE\_ERR\_UNKNOWN\_HCI\_CMD | Unknown HCI Command | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0202 | 0x02 | BLE\_ERR\_UNK\_CONN\_ID | Unknown Connection Identifier | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0203 | 0x03 | BLE\_ERR\_HW\_FAIL | Hardware Failure | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0204 | 0x04 | BLE\_ERR\_PAGE\_TMO | Page Timeout | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0205 | 0x05 | BLE\_ERR\_AUTH\_FAIL | Authentication Failure | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0206 | 0x06 | BLE\_ERR\_PINKEY\_MISSING | PIN or Key Missing | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0207 | 0x07 | BLE\_ERR\_MEM\_CAPACITY | Memory Capacity Exceeded | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0208 | 0x08 | BLE\_ERR\_CONN\_SPVN\_TMO | Connection Timeout | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0209 | 0x09 | BLE\_ERR\_CONN\_LIMIT | Connection Limit Exceeded | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x020a | 0x0a | BLE\_ERR\_SYNCH\_CONN\_LIMIT | Synchronous Connection Limit To A Device Exceeded | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x020b | 0x0b | BLE\_ERR\_ACL\_CONN\_EXISTS | ACL Connection Already Exists | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x020c | 0x0c | BLE\_ERR\_CMD\_DISALLOWED | Command Disallowed | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x020d | 0x0d | BLE\_ERR\_CONN\_REJ\_RESOURCES | Connection Rejected due to Limited Resources | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x020e | 0x0e | BLE\_ERR\_CONN\_REJ\_SECURITY | Connection Rejected Due To Security Reasons | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x020f | 0x0f | BLE\_ERR\_CONN\_REJ\_BD\_ADDR | Connection Rejected due to Unacceptable BD\_ADDR | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0210 | 0x10 | BLE\_ERR\_CONN\_ACCEPT\_TMO | Connection Accept Timeout Exceeded | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0211 | 0x11 | BLE\_ERR\_UNSUPPORTED | Unsupported Feature or Parameter Value | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0212 | 0x12 | BLE\_ERR\_INV\_HCI\_CMD\_PARMS | Invalid HCI Command Parameters | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0213 | 0x13 | BLE\_ERR\_REM\_USER\_CONN\_TERM | Remote User Terminated Connection | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0214 | 0x14 | BLE\_ERR\_RD\_CONN\_TERM\_RESRCS | Remote Device Terminated Connection due to Low Resources | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0215 | 0x15 | BLE\_ERR\_RD\_CONN\_TERM\_PWROFF | Remote Device Terminated Connection due to Power Off | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0216 | 0x16 | BLE\_ERR\_CONN\_TERM\_LOCAL | Connection Terminated By Local Host | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0217 | 0x17 | BLE\_ERR\_REPEATED\_ATTEMPTS | Repeated Attempts | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0218 | 0x18 | BLE\_ERR\_NO\_PAIRING | Pairing Not Allowed | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0219 | 0x19 | BLE\_ERR\_UNK\_LMP | Unknown LMP PDU | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x021a | 0x1a | BLE\_ERR\_UNSUPP\_REM\_FEATURE | Unsupported Remote Feature / Unsupported LMP Feature | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x021b | 0x1b | BLE\_ERR\_SCO\_OFFSET | SCO Offset Rejected | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x021c | 0x1c | BLE\_ERR\_SCO\_ITVL | SCO Interval Rejected | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x021d | 0x1d | BLE\_ERR\_SCO\_AIR\_MODE | SCO Air Mode Rejected | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x021e | 0x1e | BLE\_ERR\_INV\_LMP\_LL\_PARM | Invalid LMP Parameters / Invalid LL Parameters | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x021f | 0x1f | BLE\_ERR\_UNSPECIFIED | Unspecified Error | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0220 | 0x20 | BLE\_ERR\_UNSUPP\_LMP\_LL\_PARM | Unsupported LMP Parameter Value / Unsupported LL Parameter Value | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0221 | 0x21 | BLE\_ERR\_NO\_ROLE\_CHANGE | Role Change Not Allowed | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0222 | 0x22 | BLE\_ERR\_LMP\_LL\_RSP\_TMO | LMP Response Timeout / LL Response Timeout | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0223 | 0x23 | BLE\_ERR\_LMP\_COLLISION | LMP Error Transaction Collision | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0224 | 0x24 | BLE\_ERR\_LMP\_PDU | LMP PDU Not Allowed | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0225 | 0x25 | BLE\_ERR\_ENCRYPTION\_MODE | Encryption Mode Not Acceptable | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0226 | 0x26 | BLE\_ERR\_LINK\_KEY\_CHANGE | Link Key cannot be Changed | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0227 | 0x27 | BLE\_ERR\_UNSUPP\_QOS | Requested QoS Not Supported | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0228 | 0x28 | BLE\_ERR\_INSTANT\_PASSED | Instant Passed | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0229 | 0x29 | BLE\_ERR\_UNIT\_KEY\_PAIRING | Pairing With Unit Key Not Supported | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x022a | 0x2a | BLE\_ERR\_DIFF\_TRANS\_COLL | Different Transaction Collision | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x022c | 0x2c | BLE\_ERR\_QOS\_PARM | QoS Unacceptable Parameter | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x022d | 0x2d | BLE\_ERR\_QOS\_REJECTED | QoS Rejected | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x022e | 0x2e | BLE\_ERR\_CHAN\_CLASS | Channel Classification Not Supported | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x022f | 0x2f | BLE\_ERR\_INSUFFICIENT\_SEC | Insufficient Security | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0230 | 0x30 | BLE\_ERR\_PARM\_OUT\_OF\_RANGE | Parameter Out Of Mandatory Range | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0232 | 0x32 | BLE\_ERR\_PENDING\_ROLE\_SW | Role Switch Pending | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0234 | 0x34 | BLE\_ERR\_RESERVED\_SLOT | Reserved Slot Violation | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0235 | 0x35 | BLE\_ERR\_ROLE\_SW\_FAIL | Role Switch Failed | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0236 | 0x36 | BLE\_ERR\_INQ\_RSP\_TOO\_BIG | Extended Inquiry Response Too Large | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0237 | 0x37 | BLE\_ERR\_SEC\_SIMPLE\_PAIR | Secure Simple Pairing Not Supported By Host | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0238 | 0x38 | BLE\_ERR\_HOST\_BUSY\_PAIR | Host Busy - Pairing | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0239 | 0x39 | BLE\_ERR\_CONN\_REJ\_CHANNEL | Connection Rejected due to No Suitable Channel Found | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x023a | 0x3a | BLE\_ERR\_CTLR\_BUSY | Controller Busy | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x023b | 0x3b | BLE\_ERR\_CONN\_PARMS | Unacceptable Connection Parameters | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x023c | 0x3c | BLE\_ERR\_DIR\_ADV\_TMO | Directed Advertising Timeout | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x023d | 0x3d | BLE\_ERR\_CONN\_TERM\_MIC | Connection Terminated due to MIC Failure | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x023e | 0x3e | BLE\_ERR\_CONN\_ESTABLISHMENT | Connection Failed to be Established | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x023f | 0x3f | BLE\_ERR\_MAC\_CONN\_FAIL | MAC Connection Failed | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ -| 0x0240 | 0x40 | BLE\_ERR\_COARSE\_CLK\_ADJ | Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock Dragging | -+----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ +.. table:: Return codes - HCI + :widths: 11 10 39 40 + + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | NimBLE Value | Formal Value | Name | Condition | + +================+================+====================================+================================================================================+ + | 0x0201 | 0x01 | BLE\_ERR\_UNKNOWN\_HCI\_CMD | Unknown HCI Command | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0202 | 0x02 | BLE\_ERR\_UNK\_CONN\_ID | Unknown Connection Identifier | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0203 | 0x03 | BLE\_ERR\_HW\_FAIL | Hardware Failure | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0204 | 0x04 | BLE\_ERR\_PAGE\_TMO | Page Timeout | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0205 | 0x05 | BLE\_ERR\_AUTH\_FAIL | Authentication Failure | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0206 | 0x06 | BLE\_ERR\_PINKEY\_MISSING | PIN or Key Missing | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0207 | 0x07 | BLE\_ERR\_MEM\_CAPACITY | Memory Capacity Exceeded | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0208 | 0x08 | BLE\_ERR\_CONN\_SPVN\_TMO | Connection Timeout | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0209 | 0x09 | BLE\_ERR\_CONN\_LIMIT | Connection Limit Exceeded | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x020a | 0x0a | BLE\_ERR\_SYNCH\_CONN\_LIMIT | Synchronous Connection Limit To A Device Exceeded | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x020b | 0x0b | BLE\_ERR\_ACL\_CONN\_EXISTS | ACL Connection Already Exists | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x020c | 0x0c | BLE\_ERR\_CMD\_DISALLOWED | Command Disallowed | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x020d | 0x0d | BLE\_ERR\_CONN\_REJ\_RESOURCES | Connection Rejected due to Limited Resources | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x020e | 0x0e | BLE\_ERR\_CONN\_REJ\_SECURITY | Connection Rejected Due To Security Reasons | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x020f | 0x0f | BLE\_ERR\_CONN\_REJ\_BD\_ADDR | Connection Rejected due to Unacceptable BD\_ADDR | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0210 | 0x10 | BLE\_ERR\_CONN\_ACCEPT\_TMO | Connection Accept Timeout Exceeded | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0211 | 0x11 | BLE\_ERR\_UNSUPPORTED | Unsupported Feature or Parameter Value | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0212 | 0x12 | BLE\_ERR\_INV\_HCI\_CMD\_PARMS | Invalid HCI Command Parameters | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0213 | 0x13 | BLE\_ERR\_REM\_USER\_CONN\_TERM | Remote User Terminated Connection | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0214 | 0x14 | BLE\_ERR\_RD\_CONN\_TERM\_RESRCS | Remote Device Terminated Connection due to Low Resources | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0215 | 0x15 | BLE\_ERR\_RD\_CONN\_TERM\_PWROFF | Remote Device Terminated Connection due to Power Off | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0216 | 0x16 | BLE\_ERR\_CONN\_TERM\_LOCAL | Connection Terminated By Local Host | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0217 | 0x17 | BLE\_ERR\_REPEATED\_ATTEMPTS | Repeated Attempts | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0218 | 0x18 | BLE\_ERR\_NO\_PAIRING | Pairing Not Allowed | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0219 | 0x19 | BLE\_ERR\_UNK\_LMP | Unknown LMP PDU | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x021a | 0x1a | BLE\_ERR\_UNSUPP\_REM\_FEATURE | Unsupported Remote Feature / Unsupported LMP Feature | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x021b | 0x1b | BLE\_ERR\_SCO\_OFFSET | SCO Offset Rejected | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x021c | 0x1c | BLE\_ERR\_SCO\_ITVL | SCO Interval Rejected | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x021d | 0x1d | BLE\_ERR\_SCO\_AIR\_MODE | SCO Air Mode Rejected | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x021e | 0x1e | BLE\_ERR\_INV\_LMP\_LL\_PARM | Invalid LMP Parameters / Invalid LL Parameters | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x021f | 0x1f | BLE\_ERR\_UNSPECIFIED | Unspecified Error | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0220 | 0x20 | BLE\_ERR\_UNSUPP\_LMP\_LL\_PARM | Unsupported LMP Parameter Value / Unsupported LL Parameter Value | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0221 | 0x21 | BLE\_ERR\_NO\_ROLE\_CHANGE | Role Change Not Allowed | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0222 | 0x22 | BLE\_ERR\_LMP\_LL\_RSP\_TMO | LMP Response Timeout / LL Response Timeout | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0223 | 0x23 | BLE\_ERR\_LMP\_COLLISION | LMP Error Transaction Collision | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0224 | 0x24 | BLE\_ERR\_LMP\_PDU | LMP PDU Not Allowed | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0225 | 0x25 | BLE\_ERR\_ENCRYPTION\_MODE | Encryption Mode Not Acceptable | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0226 | 0x26 | BLE\_ERR\_LINK\_KEY\_CHANGE | Link Key cannot be Changed | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0227 | 0x27 | BLE\_ERR\_UNSUPP\_QOS | Requested QoS Not Supported | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0228 | 0x28 | BLE\_ERR\_INSTANT\_PASSED | Instant Passed | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0229 | 0x29 | BLE\_ERR\_UNIT\_KEY\_PAIRING | Pairing With Unit Key Not Supported | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x022a | 0x2a | BLE\_ERR\_DIFF\_TRANS\_COLL | Different Transaction Collision | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x022c | 0x2c | BLE\_ERR\_QOS\_PARM | QoS Unacceptable Parameter | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x022d | 0x2d | BLE\_ERR\_QOS\_REJECTED | QoS Rejected | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x022e | 0x2e | BLE\_ERR\_CHAN\_CLASS | Channel Classification Not Supported | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x022f | 0x2f | BLE\_ERR\_INSUFFICIENT\_SEC | Insufficient Security | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0230 | 0x30 | BLE\_ERR\_PARM\_OUT\_OF\_RANGE | Parameter Out Of Mandatory Range | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0232 | 0x32 | BLE\_ERR\_PENDING\_ROLE\_SW | Role Switch Pending | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0234 | 0x34 | BLE\_ERR\_RESERVED\_SLOT | Reserved Slot Violation | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0235 | 0x35 | BLE\_ERR\_ROLE\_SW\_FAIL | Role Switch Failed | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0236 | 0x36 | BLE\_ERR\_INQ\_RSP\_TOO\_BIG | Extended Inquiry Response Too Large | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0237 | 0x37 | BLE\_ERR\_SEC\_SIMPLE\_PAIR | Secure Simple Pairing Not Supported By Host | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0238 | 0x38 | BLE\_ERR\_HOST\_BUSY\_PAIR | Host Busy - Pairing | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0239 | 0x39 | BLE\_ERR\_CONN\_REJ\_CHANNEL | Connection Rejected due to No Suitable Channel Found | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x023a | 0x3a | BLE\_ERR\_CTLR\_BUSY | Controller Busy | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x023b | 0x3b | BLE\_ERR\_CONN\_PARMS | Unacceptable Connection Parameters | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x023c | 0x3c | BLE\_ERR\_DIR\_ADV\_TMO | Directed Advertising Timeout | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x023d | 0x3d | BLE\_ERR\_CONN\_TERM\_MIC | Connection Terminated due to MIC Failure | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x023e | 0x3e | BLE\_ERR\_CONN\_ESTABLISHMENT | Connection Failed to be Established | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x023f | 0x3f | BLE\_ERR\_MAC\_CONN\_FAIL | MAC Connection Failed | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ + | 0x0240 | 0x40 | BLE\_ERR\_COARSE\_CLK\_ADJ | Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock Dragging | + +----------------+----------------+------------------------------------+--------------------------------------------------------------------------------+ Return codes - L2CAP ^^^^^^^^^^^^^^^^^^^^ -+----------------+----------------+----------------------------------------------+------------------------------------------------------+ -| NimBLE Value | Formal Value | Name | Condition | -+================+================+==============================================+======================================================+ -| 0x0300 | 0x00 | BLE\_L2CAP\_SIG\_ERR\_CMD\_NOT\_UNDERSTOOD | Invalid or unsupported incoming L2CAP sig command. | -+----------------+----------------+----------------------------------------------+------------------------------------------------------+ -| 0x0301 | 0x01 | BLE\_L2CAP\_SIG\_ERR\_MTU\_EXCEEDED | Incoming packet too large. | -+----------------+----------------+----------------------------------------------+------------------------------------------------------+ -| 0x0302 | 0x02 | BLE\_L2CAP\_SIG\_ERR\_INVALID\_CID | No channel with specified ID. | -+----------------+----------------+----------------------------------------------+------------------------------------------------------+ +.. table:: Return codes - L2CAP + :widths: 11 10 50 29 + + +----------------+----------------+----------------------------------------------+------------------------------------------------------+ + | NimBLE Value | Formal Value | Name | Condition | + +================+================+==============================================+======================================================+ + | 0x0300 | 0x00 | BLE\_L2CAP\_SIG\_ERR\_CMD\_NOT\_UNDERSTOOD | Invalid or unsupported incoming L2CAP sig command. | + +----------------+----------------+----------------------------------------------+------------------------------------------------------+ + | 0x0301 | 0x01 | BLE\_L2CAP\_SIG\_ERR\_MTU\_EXCEEDED | Incoming packet too large. | + +----------------+----------------+----------------------------------------------+------------------------------------------------------+ + | 0x0302 | 0x02 | BLE\_L2CAP\_SIG\_ERR\_INVALID\_CID | No channel with specified ID. | + +----------------+----------------+----------------------------------------------+------------------------------------------------------+ Return codes - Security manager (us) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| NimBLE Value | Formal Value | Name | Condition | -+================+================+===================================+===========================================================================================================================================+ -| 0x0401 | 0x01 | BLE\_SM\_ERR\_PASSKEY | The user input of passkey failed, for example, the user cancelled the operation. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0402 | 0x02 | BLE\_SM\_ERR\_OOB | The OOB data is not available. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0403 | 0x03 | BLE\_SM\_ERR\_AUTHREQ | The pairing procedure cannot be performed as authentication requirements cannot be met due to IO capabilities of one or both devices. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0404 | 0x04 | BLE\_SM\_ERR\_CONFIRM\_MISMATCH | The confirm value does not match the calculated compare value. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0405 | 0x05 | BLE\_SM\_ERR\_PAIR\_NOT\_SUPP | Pairing is not supported by the device. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0406 | 0x06 | BLE\_SM\_ERR\_ENC\_KEY\_SZ | The resultant encryption key size is insufficient for the security requirements of this device. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0407 | 0x07 | BLE\_SM\_ERR\_CMD\_NOT\_SUPP | The SMP command received is not supported on this device. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0408 | 0x08 | BLE\_SM\_ERR\_UNSPECIFIED | Pairing failed due to an unspecified reason. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0409 | 0x09 | BLE\_SM\_ERR\_REPEATED | Pairing or authentication procedure is disallowed because too little time has elapsed since last pairing request or security request. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x040a | 0x0a | BLE\_SM\_ERR\_INVAL | The Invalid Parameters error code indicates that the command length is invalid or that a parameter is outside of the specified range. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x040b | 0x0b | BLE\_SM\_ERR\_DHKEY | Indicates to the remote device that the DHKey Check value received doesn’t match the one calculated by the local device. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x040c | 0x0c | BLE\_SM\_ERR\_NUMCMP | Indicates that the confirm values in the numeric comparison protocol do not match. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x040d | 0x0d | BLE\_SM\_ERR\_ALREADY | Indicates that the pairing over the LE transport failed due to a Pairing Request sent over the BR/EDR transport in process. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x040e | 0x0e | BLE\_SM\_ERR\_CROSS\_TRANS | Indicates that the BR/EDR Link Key generated on the BR/EDR transport cannot be used to derive and distribute keys for the LE transport. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +.. table:: Return codes - Security manager (us) + :widths: 11 10 39 40 + + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | NimBLE Value | Formal Value | Name | Condition | + +================+================+===================================+===========================================================================================================================================+ + | 0x0401 | 0x01 | BLE\_SM\_ERR\_PASSKEY | The user input of passkey failed, for example, the user cancelled the operation. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0402 | 0x02 | BLE\_SM\_ERR\_OOB | The OOB data is not available. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0403 | 0x03 | BLE\_SM\_ERR\_AUTHREQ | The pairing procedure cannot be performed as authentication requirements cannot be met due to IO capabilities of one or both devices. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0404 | 0x04 | BLE\_SM\_ERR\_CONFIRM\_MISMATCH | The confirm value does not match the calculated compare value. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0405 | 0x05 | BLE\_SM\_ERR\_PAIR\_NOT\_SUPP | Pairing is not supported by the device. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0406 | 0x06 | BLE\_SM\_ERR\_ENC\_KEY\_SZ | The resultant encryption key size is insufficient for the security requirements of this device. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0407 | 0x07 | BLE\_SM\_ERR\_CMD\_NOT\_SUPP | The SMP command received is not supported on this device. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0408 | 0x08 | BLE\_SM\_ERR\_UNSPECIFIED | Pairing failed due to an unspecified reason. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0409 | 0x09 | BLE\_SM\_ERR\_REPEATED | Pairing or authentication procedure is disallowed because too little time has elapsed since last pairing request or security request. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x040a | 0x0a | BLE\_SM\_ERR\_INVAL | The Invalid Parameters error code indicates that the command length is invalid or that a parameter is outside of the specified range. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x040b | 0x0b | BLE\_SM\_ERR\_DHKEY | Indicates to the remote device that the DHKey Check value received doesn’t match the one calculated by the local device. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x040c | 0x0c | BLE\_SM\_ERR\_NUMCMP | Indicates that the confirm values in the numeric comparison protocol do not match. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x040d | 0x0d | BLE\_SM\_ERR\_ALREADY | Indicates that the pairing over the LE transport failed due to a Pairing Request sent over the BR/EDR transport in process. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x040e | 0x0e | BLE\_SM\_ERR\_CROSS\_TRANS | Indicates that the BR/EDR Link Key generated on the BR/EDR transport cannot be used to derive and distribute keys for the LE transport. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ Return codes - Security manager (peer) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| NimBLE Value | Formal Value | Name | Condition | -+================+================+===================================+===========================================================================================================================================+ -| 0x0501 | 0x01 | BLE\_SM\_ERR\_PASSKEY | The user input of passkey failed, for example, the user cancelled the operation. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0502 | 0x02 | BLE\_SM\_ERR\_OOB | The OOB data is not available. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0503 | 0x03 | BLE\_SM\_ERR\_AUTHREQ | The pairing procedure cannot be performed as authentication requirements cannot be met due to IO capabilities of one or both devices. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0504 | 0x04 | BLE\_SM\_ERR\_CONFIRM\_MISMATCH | The confirm value does not match the calculated compare value. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0505 | 0x05 | BLE\_SM\_ERR\_PAIR\_NOT\_SUPP | Pairing is not supported by the device. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0506 | 0x06 | BLE\_SM\_ERR\_ENC\_KEY\_SZ | The resultant encryption key size is insufficient for the security requirements of this device. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0507 | 0x07 | BLE\_SM\_ERR\_CMD\_NOT\_SUPP | The SMP command received is not supported on this device. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0508 | 0x08 | BLE\_SM\_ERR\_UNSPECIFIED | Pairing failed due to an unspecified reason. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x0509 | 0x09 | BLE\_SM\_ERR\_REPEATED | Pairing or authentication procedure is disallowed because too little time has elapsed since last pairing request or security request. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x050a | 0x0a | BLE\_SM\_ERR\_INVAL | The Invalid Parameters error code indicates that the command length is invalid or that a parameter is outside of the specified range. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x050b | 0x0b | BLE\_SM\_ERR\_DHKEY | Indicates to the remote device that the DHKey Check value received doesn’t match the one calculated by the local device. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x050c | 0x0c | BLE\_SM\_ERR\_NUMCMP | Indicates that the confirm values in the numeric comparison protocol do not match. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x050d | 0x0d | BLE\_SM\_ERR\_ALREADY | Indicates that the pairing over the LE transport failed due to a Pairing Request sent over the BR/EDR transport in process. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| 0x050e | 0x0e | BLE\_SM\_ERR\_CROSS\_TRANS | Indicates that the BR/EDR Link Key generated on the BR/EDR transport cannot be used to derive and distribute keys for the LE transport. | -+----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +.. table:: Return codes - Security manager (peer) + :widths: 11 10 39 40 + + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | NimBLE Value | Formal Value | Name | Condition | + +================+================+===================================+===========================================================================================================================================+ + | 0x0501 | 0x01 | BLE\_SM\_ERR\_PASSKEY | The user input of passkey failed, for example, the user cancelled the operation. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0502 | 0x02 | BLE\_SM\_ERR\_OOB | The OOB data is not available. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0503 | 0x03 | BLE\_SM\_ERR\_AUTHREQ | The pairing procedure cannot be performed as authentication requirements cannot be met due to IO capabilities of one or both devices. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0504 | 0x04 | BLE\_SM\_ERR\_CONFIRM\_MISMATCH | The confirm value does not match the calculated compare value. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0505 | 0x05 | BLE\_SM\_ERR\_PAIR\_NOT\_SUPP | Pairing is not supported by the device. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0506 | 0x06 | BLE\_SM\_ERR\_ENC\_KEY\_SZ | The resultant encryption key size is insufficient for the security requirements of this device. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0507 | 0x07 | BLE\_SM\_ERR\_CMD\_NOT\_SUPP | The SMP command received is not supported on this device. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0508 | 0x08 | BLE\_SM\_ERR\_UNSPECIFIED | Pairing failed due to an unspecified reason. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x0509 | 0x09 | BLE\_SM\_ERR\_REPEATED | Pairing or authentication procedure is disallowed because too little time has elapsed since last pairing request or security request. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x050a | 0x0a | BLE\_SM\_ERR\_INVAL | The Invalid Parameters error code indicates that the command length is invalid or that a parameter is outside of the specified range. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x050b | 0x0b | BLE\_SM\_ERR\_DHKEY | Indicates to the remote device that the DHKey Check value received doesn’t match the one calculated by the local device. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x050c | 0x0c | BLE\_SM\_ERR\_NUMCMP | Indicates that the confirm values in the numeric comparison protocol do not match. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x050d | 0x0d | BLE\_SM\_ERR\_ALREADY | Indicates that the pairing over the LE transport failed due to a Pairing Request sent over the BR/EDR transport in process. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + | 0x050e | 0x0e | BLE\_SM\_ERR\_CROSS\_TRANS | Indicates that the BR/EDR Link Key generated on the BR/EDR transport cannot be used to derive and distribute keys for the LE transport. | + +----------------+----------------+-----------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/docs/btshell/btshell_GAP.rst b/docs/btshell/btshell_GAP.rst index 2d52a16e1e..149c4c02c2 100644 --- a/docs/btshell/btshell_GAP.rst +++ b/docs/btshell/btshell_GAP.rst @@ -34,627 +34,646 @@ modes and procedures are defined for use over an LE physical transport: Available commands ~~~~~~~~~~~~~~~~~~ -Parameters default values are marked red. - Configuration ------------- -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ -| **Command** | **Parmeters** | \*\* Possible values\*\* | **Description** | -+=====================+=================+============================+=========================================================================================================+ -| **set** | | | Set configuration options | -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ -| | addr | XX:XX:XX:XX:XX:XX | Local device address | -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ -| | addr\_type | ``public`` | Local device address type | -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ -| | | random | Use random address for scan requests | -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ -| | mtu | [23-UINT16\_MAX] | GATT Maximum Transmission Unit (MTU) | -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ -| | irk | XX:XX:XX... | Local Identity Resolving Key (16 byte | -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ -| **set-priv-mode** | | | Set privacy mode for device | -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ -| | addr | XX:XX:XX:XX:XX:XX | Remote device address | -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ -| | addr\_type | ``public`` | Remote device public address type | -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ -| | | random | Remote device random address type | -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ -| | mode | [``0``-1] | 0 - use network privacy, 1 - use device privacy | -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ -| **white-list** | | | Add devices to white list (this command accepts multiple instances of addr and addr\_type parameters) | -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ -| | addr | XX:XX:XX:XX:XX:XX | Remote device address | -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ -| | addr\_type | ``public`` | Remote device public address type | -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ -| | | random | Remote device random address type | -+---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ +.. table:: Configuration + :widths: 20 15 25 40 + + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ + | **Command** | **Parameters** | **Possible values** | **Description** | + +=====================+=================+============================+=========================================================================================================+ + | **set** | | | Set configuration options | + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ + | | addr | XX:XX:XX:XX:XX:XX | Local device address | + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ + | | addr\_type | ``public`` | Local device address type | + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ + | | | random | Use random address for scan requests | + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ + | | mtu | [23-UINT16\_MAX] | GATT Maximum Transmission Unit (MTU) | + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ + | | irk | XX:XX:XX... | Local Identity Resolving Key (16 byte | + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ + | **set-priv-mode** | | | Set privacy mode for device | + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ + | | addr | XX:XX:XX:XX:XX:XX | Remote device address | + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ + | | addr\_type | ``public`` | Remote device public address type | + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ + | | | random | Remote device random address type | + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ + | | mode | [``0``-1] | 0 - use network privacy, 1 - use device privacy | + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ + | **white-list** | | | Add devices to white list (this command accepts multiple instances of addr and addr\_type parameters) | + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ + | | addr | XX:XX:XX:XX:XX:XX | Remote device address | + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ + | | addr\_type | ``public`` | Remote device public address type | + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ + | | | random | Remote device random address type | + +---------------------+-----------------+----------------------------+---------------------------------------------------------------------------------------------------------+ Device discovery and connection ------------------------------- -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| **Command** | **Parmeters** | \*\* Possible values\*\* | **Description** | -+==========================+================================+============================+============================================================================================================+ -| **scan** | | | Discover remote devices | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | cancel | | cancel ongoing scan procedure | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | extended | ``none`` | Start legacy scan | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | 1M | Start extended scan on 1M PHY | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | coded | Start extended scan on Coded PHY | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | both | Start extended scan on both PHYs | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | duration | [1-``INT32_MAX``], | Duration of scan in milliseconds | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | limited | [``0``-1] | Use limited discovery procedure | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | passive | [``0``-1] | Use passive scan | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | interval | [``0``-UINT16\_MAX] | Scan interval, if 0 use stack's default | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | window | [``0``-UINT16\_MAX] | Scan window, if 0 use stack's default | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | filter | ``no_wl`` | Scan filter policy - Accept all advertising packets | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | use\_wl | Accept only advertising packets from devices on White List | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | no\_wl\_inita | Accept all advertising packets (including directed RPA) | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | use\_wl\_inita | Accept only advertising packets from devices on White List (including directed RPA) | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | nodups | [``0``-1] | Disable duplicates filtering | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | own\_addr\_type | ``public`` | Use public address for scan requests | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | random | Use random address for scan requests | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | rpa\_pub | Use RPA address for scan requests (fallback to public if no IRK) | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | rpa\_rnd | Use RPA address for scan requests (fallback to random if no IRK) | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | extended\_duration | [``0``-UINT16\_MAX] | Duration of extended scan in 10 milliseconds | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | extended\_period | [``0``-UINT16\_MAX] | Periodic scan interval in 1.28 seconds (0 disabled) | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | longrange\_interval | [``0``-UINT16\_MAX] | Scan interval for Coded Scan , if 0 use stack's default | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | longrange\_window | [``0``-UINT16\_MAX] | Scan window for Coded Scan , if 0 use stack's default | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | longrange\_passive | [``0``-1] | Use passive scan for Coded Scan | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| **connect** | | | Initiate connection to remote device | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | cancel | | Cancel ongoing connection procedure | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | extended | ``none`` | Use legacy connection procedure | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | 1M | Extended connect using 1M PHY scan parameters | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | coded | Extended connect using Coded PHY scan parameters | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | both | Extended connect using 1M and Coded PHYs scan parameters | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | all | Extended connect using 1M and Coded PHYs scan parameters (Provide also connection parameters for 2M PHY) | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | peer\_addr\_type | ``public`` | Remote device public address type | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | random | Remote device random address type | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | public\_id | Remote device public address type (Identity) | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | random\_id | Remote device random address type (Identity) | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | peer\_addr | XX:XX:XX:XX:XX:XX | Remote device address | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | own\_addr\_type | ``public`` | Use public address for scan requests | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | random | Use random address for scan requests | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | rpa\_pub | Use RPA address for scan requests (fallback to public if no IRK) | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | | rpa\_rnd | Use RPA address for scan requests (fallback to random if no IRK) | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | duration | [``0``-INT32\_MAX] | Connection attempt duration, if 0 use stack's default | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | scan\_interval | [0-UINT16\_MAX] | Scan interval, default: 0x0010 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | scan\_window | [0-UINT16\_MAX] | Scan window, default: 0x0010 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | interval\_min | [0-UINT16\_MAX] | Minimum connection interval, default: 30 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | interval\_max | [0-UINT16\_MAX] | Maximum connection interval, default: 50 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | latency | [UINT16] | Connection latency, default: 0 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | timeout | [UINT16] | Connection timeout, default: 0x0100 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | min\_conn\_event\_len | [UINT16] | Minimum length of connection event, default: 0x0010 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | max\_conn\_event\_len | [UINT16] | Maximum length of connection event, default: 0x0300 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | coded\_scan\_interval | [0-UINT16\_MAX] | Coded PHY Scan interval, default: 0x0010 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | coded\_scan\_window | [0-UINT16\_MAX] | Coded PHY Scan window, default: 0x0010 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | coded\_interval\_min | [0-UINT16\_MAX] | Coded PHY Minimum connection interval, default: 30 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | coded\_interval\_max | [0-UINT16\_MAX] | Coded PHY Maximum connection interval, default: 50 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | coded\_latency | [UINT16] | Coded PHY Connection latency, default: 0 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | coded\_timeout | [UINT16] | Coded PHY Connection timeout, default: 0x0100 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | coded\_min\_conn\_event\_len | [UINT16] | Coded PHY Minimum length of connection event, default: 0x0010 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | coded\_max\_conn\_event\_len | [UINT16] | Coded PHY Maximum length of connection event, default: 0x0300 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | 2M\_scan\_interval | [0-UINT16\_MAX] | 2M PHY Scan interval, default: 0x0010 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | 2M\_scan\_window | [0-UINT16\_MAX] | 2M PHY Scan window, default: 0x0010 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | 2M\_interval\_min | [0-UINT16\_MAX] | 2M PHY Minimum connection interval, default: 30 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | 2M\_interval\_max | [0-UINT16\_MAX] | 2M PHY Maximum connection interval, default: 50 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | 2M\_latency | [UINT16] | 2M PHY Connection latency, default: 0 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | 2M\_timeout | [UINT16] | 2M PHY Connection timeout, default: 0x0100 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | 2M\_min\_conn\_event\_len | [UINT16] | 2M PHY Minimum length of connection event, default: 0x0010 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | 2M\_max\_conn\_event\_len | [UINT16] | 2M PHY Maximum length of connection event, default: 0x0300 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| **disconnect** | | | Disconnect exisiting connection | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | reason | [UINT8] | Disconnect reason | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| **show-addr** | | | Show local public and random identity addresses | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| **show-conn** | | | Show current connections | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| **conn-rssi** | | | Obtain RSSI of specified connection | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| **conn-update-params** | | | Update parameters of specified connection | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | interval\_min | [0-UINT16\_MAX] | Minimum connection interval, default: 30 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | interval\_max | [0-UINT16\_MAX] | Maximum connection interval, default: 50 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | latency | [UINT16] | Connection latency, default: 0 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | timeout | [UINT16] | Connection timeout, default: 0x0100 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | min\_conn\_event\_len | [UINT16] | Minimum length of connection event, default: 0x0010 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | max\_conn\_event\_len | [UINT16] | Maximum length of connection event, default: 0x0300 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| **conn-datalen** | | | Set DLE parmaeters for connection | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | octets | [UINT16] | Maximum transmission packet size | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | time | [UINT16] | Maximum transmission packet time | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| **phy-set** | | | Set prefered PHYs used for connection | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | tx\_phys\_mask | [UINT8] | Prefered PHYs on TX is mask of following bits0x00 - no preference0x01 - 1M, 0x02 - 2M, 0x04 - Coded | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | rx\_phys\_mask | [UINT8] | Prefered PHYs on RX is mask of following bits0x00 - no preference0x01 - 1M, 0x02 - 2M, 0x04 - Coded | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | phy\_opts | [UINT16] | Options for Coded PHY 0 - any coding, 1 - prefer S2, 2 - prefer S8 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| **phy-set-default** | | | Set default prefered PHYs used for new connection | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | tx\_phys\_mask | [UINT8] | Prefered PHYs on TX is mask of following bits0x00 - no preference0x01 - 1M, 0x02 - 2M, 0x04 - Coded | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | rx\_phys\_mask | [UINT8] | Prefered PHYs on RX is mask of following bits0x00 - no preference0x01 - 1M, 0x02 - 2M, 0x04 - Coded | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| **phy-read** | | | Read connection current PHY | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| **l2cap-update** | | | Update connection parameters | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | interval\_min | [0-UINT16\_MAX] | Minimum connection interval, default: 30 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | interval\_max | [0-UINT16\_MAX] | Maximum connection interval, default: 50 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | latency | [UINT16] | Connection latency, default: 0 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ -| | timeout | [UINT16] | Connection timeout, default: 0x0100 | -+--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ +.. table:: Device discovery and connection + :widths: 15 25 20 40 + + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | **Command** | **Parameters** | **Possible values** | **Description** | + +==========================+================================+============================+============================================================================================================+ + | **scan** | | | Discover remote devices | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | cancel | | cancel ongoing scan procedure | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | extended | ``none`` | Start legacy scan | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | 1M | Start extended scan on 1M PHY | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | coded | Start extended scan on Coded PHY | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | both | Start extended scan on both PHYs | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | duration | [1-``INT32_MAX``], | Duration of scan in milliseconds | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | limited | [``0``-1] | Use limited discovery procedure | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | passive | [``0``-1] | Use passive scan | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | interval | [``0``-UINT16\_MAX] | Scan interval, if 0 use stack's default | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | window | [``0``-UINT16\_MAX] | Scan window, if 0 use stack's default | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | filter | ``no_wl`` | Scan filter policy - Accept all advertising packets | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | use\_wl | Accept only advertising packets from devices on White List | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | no\_wl\_inita | Accept all advertising packets (including directed RPA) | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | use\_wl\_inita | Accept only advertising packets from devices on White List (including directed RPA) | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | nodups | [``0``-1] | Disable duplicates filtering | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | own\_addr\_type | ``public`` | Use public address for scan requests | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | random | Use random address for scan requests | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | rpa\_pub | Use RPA address for scan requests (fallback to public if no IRK) | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | rpa\_rnd | Use RPA address for scan requests (fallback to random if no IRK) | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | extended\_duration | [``0``-UINT16\_MAX] | Duration of extended scan in 10 milliseconds | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | extended\_period | [``0``-UINT16\_MAX] | Periodic scan interval in 1.28 seconds (0 disabled) | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | longrange\_interval | [``0``-UINT16\_MAX] | Scan interval for Coded Scan , if 0 use stack's default | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | longrange\_window | [``0``-UINT16\_MAX] | Scan window for Coded Scan , if 0 use stack's default | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | longrange\_passive | [``0``-1] | Use passive scan for Coded Scan | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | **connect** | | | Initiate connection to remote device | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | cancel | | Cancel ongoing connection procedure | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | extended | ``none`` | Use legacy connection procedure | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | 1M | Extended connect using 1M PHY scan parameters | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | coded | Extended connect using Coded PHY scan parameters | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | both | Extended connect using 1M and Coded PHYs scan parameters | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | all | Extended connect using 1M and Coded PHYs scan parameters (Provide also connection parameters for 2M PHY) | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | peer\_addr\_type | ``public`` | Remote device public address type | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | random | Remote device random address type | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | public\_id | Remote device public address type (Identity) | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | random\_id | Remote device random address type (Identity) | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | peer\_addr | XX:XX:XX:XX:XX:XX | Remote device address | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | own\_addr\_type | ``public`` | Use public address for scan requests | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | random | Use random address for scan requests | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | rpa\_pub | Use RPA address for scan requests (fallback to public if no IRK) | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | | rpa\_rnd | Use RPA address for scan requests (fallback to random if no IRK) | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | duration | [``0``-INT32\_MAX] | Connection attempt duration, if 0 use stack's default | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | scan\_interval | [0-UINT16\_MAX] | Scan interval, default: 0x0010 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | scan\_window | [0-UINT16\_MAX] | Scan window, default: 0x0010 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | interval\_min | [0-UINT16\_MAX] | Minimum connection interval, default: 30 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | interval\_max | [0-UINT16\_MAX] | Maximum connection interval, default: 50 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | latency | [UINT16] | Connection latency, default: 0 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | timeout | [UINT16] | Connection timeout, default: 0x0100 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | min\_conn\_event\_len | [UINT16] | Minimum length of connection event, default: 0x0010 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | max\_conn\_event\_len | [UINT16] | Maximum length of connection event, default: 0x0300 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | coded\_scan\_interval | [0-UINT16\_MAX] | Coded PHY Scan interval, default: 0x0010 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | coded\_scan\_window | [0-UINT16\_MAX] | Coded PHY Scan window, default: 0x0010 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | coded\_interval\_min | [0-UINT16\_MAX] | Coded PHY Minimum connection interval, default: 30 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | coded\_interval\_max | [0-UINT16\_MAX] | Coded PHY Maximum connection interval, default: 50 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | coded\_latency | [UINT16] | Coded PHY Connection latency, default: 0 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | coded\_timeout | [UINT16] | Coded PHY Connection timeout, default: 0x0100 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | coded\_min\_conn\_event\_len | [UINT16] | Coded PHY Minimum length of connection event, default: 0x0010 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | coded\_max\_conn\_event\_len | [UINT16] | Coded PHY Maximum length of connection event, default: 0x0300 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | 2M\_scan\_interval | [0-UINT16\_MAX] | 2M PHY Scan interval, default: 0x0010 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | 2M\_scan\_window | [0-UINT16\_MAX] | 2M PHY Scan window, default: 0x0010 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | 2M\_interval\_min | [0-UINT16\_MAX] | 2M PHY Minimum connection interval, default: 30 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | 2M\_interval\_max | [0-UINT16\_MAX] | 2M PHY Maximum connection interval, default: 50 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | 2M\_latency | [UINT16] | 2M PHY Connection latency, default: 0 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | 2M\_timeout | [UINT16] | 2M PHY Connection timeout, default: 0x0100 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | 2M\_min\_conn\_event\_len | [UINT16] | 2M PHY Minimum length of connection event, default: 0x0010 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | 2M\_max\_conn\_event\_len | [UINT16] | 2M PHY Maximum length of connection event, default: 0x0300 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | **disconnect** | | | Disconnect exisiting connection | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | reason | [UINT8] | Disconnect reason | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | **show-addr** | | | Show local public and random identity addresses | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | **show-conn** | | | Show current connections | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | **conn-rssi** | | | Obtain RSSI of specified connection | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | **conn-update-params** | | | Update parameters of specified connection | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | interval\_min | [0-UINT16\_MAX] | Minimum connection interval, default: 30 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | interval\_max | [0-UINT16\_MAX] | Maximum connection interval, default: 50 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | latency | [UINT16] | Connection latency, default: 0 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | timeout | [UINT16] | Connection timeout, default: 0x0100 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | min\_conn\_event\_len | [UINT16] | Minimum length of connection event, default: 0x0010 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | max\_conn\_event\_len | [UINT16] | Maximum length of connection event, default: 0x0300 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | **conn-datalen** | | | Set DLE parmaeters for connection | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | octets | [UINT16] | Maximum transmission packet size | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | time | [UINT16] | Maximum transmission packet time | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | **phy-set** | | | Set prefered PHYs used for connection | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | tx\_phys\_mask | [UINT8] | Prefered PHYs on TX is mask of following bits0x00 - no preference0x01 - 1M, 0x02 - 2M, 0x04 - Coded | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | rx\_phys\_mask | [UINT8] | Prefered PHYs on RX is mask of following bits0x00 - no preference0x01 - 1M, 0x02 - 2M, 0x04 - Coded | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | phy\_opts | [UINT16] | Options for Coded PHY 0 - any coding, 1 - prefer S2, 2 - prefer S8 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | **phy-set-default** | | | Set default prefered PHYs used for new connection | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | tx\_phys\_mask | [UINT8] | Prefered PHYs on TX is mask of following bits0x00 - no preference0x01 - 1M, 0x02 - 2M, 0x04 - Coded | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | rx\_phys\_mask | [UINT8] | Prefered PHYs on RX is mask of following bits0x00 - no preference0x01 - 1M, 0x02 - 2M, 0x04 - Coded | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | **phy-read** | | | Read connection current PHY | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | **l2cap-update** | | | Update connection parameters | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | interval\_min | [0-UINT16\_MAX] | Minimum connection interval, default: 30 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | interval\_max | [0-UINT16\_MAX] | Maximum connection interval, default: 50 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | latency | [UINT16] | Connection latency, default: 0 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ + | | timeout | [UINT16] | Connection timeout, default: 0x0100 | + +--------------------------+--------------------------------+----------------------------+------------------------------------------------------------------------------------------------------------+ Security -------- -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| **Command** | **Parmeters** | \*\* Possible values\*\* | **Description** | -+===========================+====================+============================+============================================================================================================================+ -| **security-set-data** | | | Set security configuration | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | oob-flag | [``0``-1] | Set Out-Of-Band (OOB) flag in Security Manager | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | mitm-flag | [``0``-1] | Set Man-In-The-Middle (MITM) flag in Security Manager | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | io\_capabilities | 0 | Set Input-Output Capabilities to "DisplayOnly" | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | | 1 | Set Input-Output Capabilities to "DisplayYesNo" | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | | 2 | Set Input-Output Capabilities to "KeyboardOnly" | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | | 3 | Set Input-Output Capabilities to "NoInputNoOutput" | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | | 4 | Set Input-Output Capabilities to "KeyboardDisplay" | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | our\_key\_dist | [UINT8] | Set Local Keys Distribution, this is a bit field of possible values: LTK (0x01), IRK (0x02), CSRK (0x04), LTK\_SC(0x08) | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | their\_key\_dist | [UINT8] | Set Remote Keys Distribution, this is a bit field of possible values: LTK (0x01), IRK (0x02), CSRK (0x04), LTK\_SC(0x08) | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | bonding-flag | [``0``-1] | Set Bonding flag in Security Manager | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | sc-flag | [``0``-1] | Set Secure Connections flag in Security Manager | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| **security-pair** | | | Start pairing procedure | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| **security-encryption** | | | Start encryption procedure | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | ediv | [UINT16] | EDIV for LTK to use (use storage if not provided) | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | rand | [UINT64] | Rand for LTK | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | ltk | XX:XX:XX... | LTK (16 bytes) | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| **security-start** | | | Start security procedure (This starts either pairing or encryption depending if keys are stored) | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| **auth-passkey** | | | Reply to Passkey request | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | action | [UINT16] | Action to reply (as received in event) | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | key | [0-999999] | Passkey to reply (Input or Display action) | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | oob | XX:XX:XX:... | Out-Of-Band secret (16 bytes) (OOB action) | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| | yesno | Yy-Ny | Confirm passkey (for Passkey Confirm action) | -+---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ +.. table:: Security + :widths: 15 15 15 55 + + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | **Command** | **Parameters** | **Possible values** | **Description** | + +===========================+====================+============================+============================================================================================================================+ + | **security-set-data** | | | Set security configuration | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | oob-flag | [``0``-1] | Set Out-Of-Band (OOB) flag in Security Manager | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | mitm-flag | [``0``-1] | Set Man-In-The-Middle (MITM) flag in Security Manager | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | io\_capabilities | 0 | Set Input-Output Capabilities to "DisplayOnly" | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | | 1 | Set Input-Output Capabilities to "DisplayYesNo" | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | | 2 | Set Input-Output Capabilities to "KeyboardOnly" | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | | 3 | Set Input-Output Capabilities to "NoInputNoOutput" | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | | 4 | Set Input-Output Capabilities to "KeyboardDisplay" | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | our\_key\_dist | [UINT8] | Set Local Keys Distribution, this is a bit field of possible values: LTK (0x01), IRK (0x02), CSRK (0x04), LTK\_SC(0x08) | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | their\_key\_dist | [UINT8] | Set Remote Keys Distribution, this is a bit field of possible values: LTK (0x01), IRK (0x02), CSRK (0x04), LTK\_SC(0x08) | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | bonding-flag | [``0``-1] | Set Bonding flag in Security Manager | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | sc-flag | [``0``-1] | Set Secure Connections flag in Security Manager | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | **security-pair** | | | Start pairing procedure | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | **security-encryption** | | | Start encryption procedure | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | ediv | [UINT16] | EDIV for LTK to use (use storage if not provided) | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | rand | [UINT64] | Rand for LTK | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | ltk | XX:XX:XX... | LTK (16 bytes) | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | **security-start** | | | Start security procedure (This starts either pairing or encryption depending if keys are stored) | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | **auth-passkey** | | | Reply to Passkey request | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | action | [UINT16] | Action to reply (as received in event) | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | key | [0-999999] | Passkey to reply (Input or Display action) | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | oob | XX:XX:XX:... | Out-Of-Band secret (16 bytes) (OOB action) | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ + | | yesno | Yy-Ny | Confirm passkey (for Passkey Confirm action) | + +---------------------------+--------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------------+ Advertising with Extended Advertising enabled --------------------------------------------- -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| **Command** | **Parmeters** | \*\* Possible values\*\* | **Description** | -+==============================+==========================+============================+=====================================================================================+ -| **advertise-configure** | | | Configure new advertising instance | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | instance | [``0``-UINT8\_MAX] | Advertising instance | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | connectable | [``0``-1] | Use connectable advertising | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | scannable | [``0``-1] | Use scannable advertising | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | peer\_addr\_type | ``public`` | Remote device public address type | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | random | Remote device random address type | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | public\_id | Remote device public address type (Identity) | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | random\_id | Remote device random address type (Identity) | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | peer\_addr | XX:XX:XX:XX:XX:XX | Remote device address - if provided perform directed advertising | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | own\_addr\_type | ``public`` | Use public address for scan requests | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | random | Use random address for scan requests | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | rpa\_pub | Use RPA address for scan requests (fallback to public if no IRK) | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | rpa\_rnd | Use RPA address for scan requests (fallback to random if no IRK) | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | channel\_map | [``0``-UINT8\_MAX} | Primary advertising channels map. If 0 use all channels. | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | filter | ``none`` | Advertising filter policy - no filtering, no whitelist used | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | scan | process all connection requests but only scans from white list | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | conn | process all scan request but only connection requests from white list | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | both | ignore all scan and connection requests unless in white list | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | interval\_min | [``0``-UINT32\_MAX] | Minimum advertising interval in 0.625 miliseconds If 0 use stack default. | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | interval\_max | [``0``-UINT32\_MAX] | Maximum advertising interval in 0.625 miliseconds If 0 use stack default. | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | rx\_power | [-127 - ``127``] | Advertising TX power in dBm | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | primary\_phy | ``1M`` | Use 1M PHY on primary advertising channels | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | ``coded`` | Use Coded PHY on primary advertising channels | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | secondary\_phy | ``1M`` | Use 1M PHY on secondary advertising channels | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | ``coded`` | Use coded PHY on primary advertising channels | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | ``2M`` | Use 2M PHY on primary advertising channels | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | sid | [``0``-16] | Adsertising instance SID | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | high\_duty | [``0``-1] | Use high\_duty advertising | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | anonymous | [``0``-1] | Use anonymous advertising | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | legacy | [``0``-1] | Use legacy PDUs for advertising | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | include\_tx\_power | [``0``-1] | Include TX power information in advertising PDUs | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | scan\_req\_notif | [``0``-1] | Enable SCAN\_REQ notifications | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| **advertise-set-addr** | | | Configure *random* address for instance | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | instance | [``0``-UINT8\_MAX] | Advertising instance | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | addr | XX:XX:XX:XX:XX:XX | Random address | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| **advertise-set-adv-data** | | | Configure advertising instance ADV\_DATA. This allow to configure following TLVs: | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| **advertise-set-scan-rsp** | | | Configure advertising instance SCAN\_RSP. This allow to configure following TLVs: | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | instance | [``0``-UINT8\_MAX] | Advertising instance | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | flags | [``0``-UINT8\_MAX] | Flags value | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | uuid16 | [UINT16] | 16-bit UUID value (can be passed multiple times) | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | uuid16\_is\_complete | [``0``-1] | I 16-bit UUID list is complete | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | uuid32 | [UINT32] | 32-bit UUID value (can be passed multiple times) | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | uuid32\_is\_complete | [``0``-1] | I 32-bit UUID list is complete | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | uuid128 | XX:XX:XX:... | 128-bit UUID value (16 bytes) (can be passed multiple times) | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | uuid128\_is\_complete | [``0``-1] | I 128-bit UUID list is complete | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | tx\_power\_level | [-127 - 127] | TX Power level to include | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | appearance | [UINT16] | Appearance | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | name | string | Name | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | advertising\_interval | [UINT16] | Advertising interval | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | service\_data\_uuid32 | XX:XX:XX:... | 32-bit UUID service data | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | service\_data\_uuid128 | XX:XX:XX:... | 128-bit UUID service data | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | uri | XX:XX:XX:... | URI | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | msg\_data | XX:XX:XX:... | Manufacturer data | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | eddystone\_url | string | Eddystone with specified URL | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| **advertise-start** | | | Start advertising with configured instance | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | instance | [``0``-UINT8\_MAX] | Advertising instance | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | duration | [``0``-UINT16\_MAX] | Advertising duration in 10ms units. 0 - forver | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | max\_events | [``0``-UINT8\_MAX] | Maximum number of advertising events. 0 - no limit | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| **advertise-stop** | | | Stop advertising | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | instance | [``0``-UINT8\_MAX] | Advertising instance | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| **advertise-remove** | | | Remove configured advertising instance | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | instance | [``0``-UINT8\_MAX] | Advertising instance | -+------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ +.. table:: Advertising with Extended Advertising enabled + :widths: 15 20 20 45 + + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | **Command** | **Parameters** | **Possible values** | **Description** | + +==============================+==========================+============================+=====================================================================================+ + | **advertise-configure** | | | Configure new advertising instance | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | instance | [``0``-UINT8\_MAX] | Advertising instance | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | connectable | [``0``-1] | Use connectable advertising | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | scannable | [``0``-1] | Use scannable advertising | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | peer\_addr\_type | ``public`` | Remote device public address type | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | random | Remote device random address type | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | public\_id | Remote device public address type (Identity) | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | random\_id | Remote device random address type (Identity) | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | peer\_addr | XX:XX:XX:XX:XX:XX | Remote device address - if provided perform directed advertising | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | own\_addr\_type | ``public`` | Use public address for scan requests | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | random | Use random address for scan requests | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | rpa\_pub | Use RPA address for scan requests (fallback to public if no IRK) | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | rpa\_rnd | Use RPA address for scan requests (fallback to random if no IRK) | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | channel\_map | [``0``-UINT8\_MAX} | Primary advertising channels map. If 0 use all channels. | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | filter | ``none`` | Advertising filter policy - no filtering, no whitelist used | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | scan | process all connection requests but only scans from white list | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | conn | process all scan request but only connection requests from white list | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | both | ignore all scan and connection requests unless in white list | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | interval\_min | [``0``-UINT32\_MAX] | Minimum advertising interval in 0.625 miliseconds If 0 use stack default. | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | interval\_max | [``0``-UINT32\_MAX] | Maximum advertising interval in 0.625 miliseconds If 0 use stack default. | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | rx\_power | [-127 - ``127``] | Advertising TX power in dBm | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | primary\_phy | ``1M`` | Use 1M PHY on primary advertising channels | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | ``coded`` | Use Coded PHY on primary advertising channels | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | secondary\_phy | ``1M`` | Use 1M PHY on secondary advertising channels | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | ``coded`` | Use coded PHY on primary advertising channels | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | ``2M`` | Use 2M PHY on primary advertising channels | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | sid | [``0``-16] | Adsertising instance SID | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | high\_duty | [``0``-1] | Use high\_duty advertising | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | anonymous | [``0``-1] | Use anonymous advertising | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | legacy | [``0``-1] | Use legacy PDUs for advertising | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | include\_tx\_power | [``0``-1] | Include TX power information in advertising PDUs | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | scan\_req\_notif | [``0``-1] | Enable SCAN\_REQ notifications | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | **advertise-set-addr** | | | Configure *random* address for instance | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | instance | [``0``-UINT8\_MAX] | Advertising instance | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | addr | XX:XX:XX:XX:XX:XX | Random address | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | **advertise-set-adv-data** | | | Configure advertising instance ADV\_DATA. This allow to configure following TLVs: | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | **advertise-set-scan-rsp** | | | Configure advertising instance SCAN\_RSP. This allow to configure following TLVs: | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | instance | [``0``-UINT8\_MAX] | Advertising instance | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | flags | [``0``-UINT8\_MAX] | Flags value | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | uuid16 | [UINT16] | 16-bit UUID value (can be passed multiple times) | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | uuid16\_is\_complete | [``0``-1] | I 16-bit UUID list is complete | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | uuid32 | [UINT32] | 32-bit UUID value (can be passed multiple times) | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | uuid32\_is\_complete | [``0``-1] | I 32-bit UUID list is complete | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | uuid128 | XX:XX:XX:... | 128-bit UUID value (16 bytes) (can be passed multiple times) | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | uuid128\_is\_complete | [``0``-1] | I 128-bit UUID list is complete | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | tx\_power\_level | [-127 - 127] | TX Power level to include | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | appearance | [UINT16] | Appearance | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | name | string | Name | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | advertising\_interval | [UINT16] | Advertising interval | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | service\_data\_uuid32 | XX:XX:XX:... | 32-bit UUID service data | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | service\_data\_uuid128 | XX:XX:XX:... | 128-bit UUID service data | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | uri | XX:XX:XX:... | URI | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | msg\_data | XX:XX:XX:... | Manufacturer data | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | eddystone\_url | string | Eddystone with specified URL | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | **advertise-start** | | | Start advertising with configured instance | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | instance | [``0``-UINT8\_MAX] | Advertising instance | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | duration | [``0``-UINT16\_MAX] | Advertising duration in 10ms units. 0 - forver | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | max\_events | [``0``-UINT8\_MAX] | Maximum number of advertising events. 0 - no limit | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | **advertise-stop** | | | Stop advertising | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | instance | [``0``-UINT8\_MAX] | Advertising instance | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | **advertise-remove** | | | Remove configured advertising instance | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | instance | [``0``-UINT8\_MAX] | Advertising instance | + +------------------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ Legacy Advertising with Extended Advertising disabled ----------------------------------------------------- -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| **Command** | **Parmeters** | \*\* Possible values\*\* | **Description** | -+====================+==========================+============================+=====================================================================================+ -| **advertise** | | | Enable advertising | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | stop | | Stop enabled advertising | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | conn | ``und`` | Connectable mode: undirected | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | non | non-connectable | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | dir | directed | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | discov | ``gen`` | Discoverable mode: general discoverable | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | ltd | limited discoverable | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | non | non-discoverable | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | scannable | [``0``-1] | Use scannable advertising | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | peer\_addr\_type | ``public`` | Remote device public address type | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | random | Remote device random address type | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | public\_id | Remote device public address type (Identity) | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | random\_id | Remote device random address type (Identity) | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | peer\_addr | XX:XX:XX:XX:XX:XX | Remote device address - if provided perform directed advertising | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | own\_addr\_type | ``public`` | Use public address for scan requests | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | random | Use random address for scan requests | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | rpa\_pub | Use RPA address for scan requests (fallback to public if no IRK) | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | rpa\_rnd | Use RPA address for scan requests (fallback to random if no IRK) | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | channel\_map | [``0``-UINT8\_MAX} | Primary advertising channels map. If 0 use all channels. | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | filter | ``none`` | Advertising filter policy - no filtering, no whitelist used | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | scan | process all connection requests but only scans from white list | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | conn | process all scan request but only connection requests from white list | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | | both | ignore all scan and connection requests unless in white list | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | interval\_min | [``0``-UINT32\_MAX] | Minimum advertising interval in 0.625 miliseconds If 0 use stack default. | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | interval\_max | [``0``-UINT32\_MAX] | Maximum advertising interval in 0.625 miliseconds If 0 use stack default. | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | high\_duty | [``0``-1] | Use high\_duty advertising | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | duration | [``1``-INT32\_MAX] | Advertising duration in ms | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| **set-adv-data** | | | Configure advertising instance ADV\_DATA. This allow to configure following TLVs: | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| **set-scan-rsp** | | | Configure advertising instance SCAN\_RSP. This allow to configure following TLVs: | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | flags | [``0``-UINT8\_MAX] | Flags value | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | uuid16 | [UINT16] | 16-bit UUID value (can be passed multiple times) | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | uuid16\_is\_complete | [``0``-1] | I 16-bit UUID list is complete | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | uuid32 | [UINT32] | 32-bit UUID value (can be passed multiple times) | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | uuid32\_is\_complete | [``0``-1] | I 32-bit UUID list is complete | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | uuid128 | XX:XX:XX:... | 128-bit UUID value (16 bytes) (can be passed multiple times) | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | uuid128\_is\_complete | [``0``-1] | I 128-bit UUID list is complete | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | tx\_power\_level | [-127 - 127] | TX Power level to include | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | appearance | [UINT16] | Appearance | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | name | string | Name | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | advertising\_interval | [UINT16] | Advertising interval | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | service\_data\_uuid32 | XX:XX:XX:... | 32-bit UUID service data | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | service\_data\_uuid128 | XX:XX:XX:... | 128-bit UUID service data | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | uri | XX:XX:XX:... | URI | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | msg\_data | XX:XX:XX:... | Manufacturer data | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ -| | eddystone\_url | string | Eddystone with specified URL | -+--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ +.. table:: Legacy Advertising with Extended Advertising disabled + :widths: 15 20 20 45 + + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | **Command** | **Parameters** | **Possible values** | **Description** | + +====================+==========================+============================+=====================================================================================+ + | **advertise** | | | Enable advertising | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | stop | | Stop enabled advertising | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | conn | ``und`` | Connectable mode: undirected | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | non | non-connectable | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | dir | directed | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | discov | ``gen`` | Discoverable mode: general discoverable | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | ltd | limited discoverable | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | non | non-discoverable | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | scannable | [``0``-1] | Use scannable advertising | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | peer\_addr\_type | ``public`` | Remote device public address type | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | random | Remote device random address type | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | public\_id | Remote device public address type (Identity) | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | random\_id | Remote device random address type (Identity) | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | peer\_addr | XX:XX:XX:XX:XX:XX | Remote device address - if provided perform directed advertising | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | own\_addr\_type | ``public`` | Use public address for scan requests | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | random | Use random address for scan requests | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | rpa\_pub | Use RPA address for scan requests (fallback to public if no IRK) | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | rpa\_rnd | Use RPA address for scan requests (fallback to random if no IRK) | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | channel\_map | [``0``-UINT8\_MAX} | Primary advertising channels map. If 0 use all channels. | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | filter | ``none`` | Advertising filter policy - no filtering, no whitelist used | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | scan | process all connection requests but only scans from white list | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | conn | process all scan request but only connection requests from white list | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | | both | ignore all scan and connection requests unless in white list | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | interval\_min | [``0``-UINT32\_MAX] | Minimum advertising interval in 0.625 miliseconds If 0 use stack default. | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | interval\_max | [``0``-UINT32\_MAX] | Maximum advertising interval in 0.625 miliseconds If 0 use stack default. | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | high\_duty | [``0``-1] | Use high\_duty advertising | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | duration | [``1``-INT32\_MAX] | Advertising duration in ms | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | **set-adv-data** | | | Configure advertising instance ADV\_DATA. This allow to configure following TLVs: | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | **set-scan-rsp** | | | Configure advertising instance SCAN\_RSP. This allow to configure following TLVs: | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | flags | [``0``-UINT8\_MAX] | Flags value | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | uuid16 | [UINT16] | 16-bit UUID value (can be passed multiple times) | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | uuid16\_is\_complete | [``0``-1] | I 16-bit UUID list is complete | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | uuid32 | [UINT32] | 32-bit UUID value (can be passed multiple times) | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | uuid32\_is\_complete | [``0``-1] | I 32-bit UUID list is complete | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | uuid128 | XX:XX:XX:... | 128-bit UUID value (16 bytes) (can be passed multiple times) | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | uuid128\_is\_complete | [``0``-1] | I 128-bit UUID list is complete | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | tx\_power\_level | [-127 - 127] | TX Power level to include | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | appearance | [UINT16] | Appearance | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | name | string | Name | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | advertising\_interval | [UINT16] | Advertising interval | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | service\_data\_uuid32 | XX:XX:XX:... | 32-bit UUID service data | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | service\_data\_uuid128 | XX:XX:XX:... | 128-bit UUID service data | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | uri | XX:XX:XX:... | URI | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | msg\_data | XX:XX:XX:... | Manufacturer data | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ + | | eddystone\_url | string | Eddystone with specified URL | + +--------------------+--------------------------+----------------------------+-------------------------------------------------------------------------------------+ L2CAP Connection Oriented Channels ---------------------------------- -+---------------------------+-----------------+----------------------------+----------------------------------------------------+ -| **Command** | **Parmeters** | \*\* Possible values\*\* | **Description** | -+===========================+=================+============================+====================================================+ -| **l2cap-create-server** | | | Create L2CAP server | -+---------------------------+-----------------+----------------------------+----------------------------------------------------+ -| | psm | [UINT16] | PSM | -+---------------------------+-----------------+----------------------------+----------------------------------------------------+ -| **l2cap-connect** | | | Connect to remote L2CAP server | -+---------------------------+-----------------+----------------------------+----------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+---------------------------+-----------------+----------------------------+----------------------------------------------------+ -| | psm | [UINT16] | PSM | -+---------------------------+-----------------+----------------------------+----------------------------------------------------+ -| **l2cap-disconnect** | | | Disconnec from L2CAP server | -+---------------------------+-----------------+----------------------------+----------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+---------------------------+-----------------+----------------------------+----------------------------------------------------+ -| | idx | [UINT16] | L2CAP connection oriented channel identifier | -+---------------------------+-----------------+----------------------------+----------------------------------------------------+ -| **l2cap-send** | | | Send data over connected L2CAP channel | -+---------------------------+-----------------+----------------------------+----------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+---------------------------+-----------------+----------------------------+----------------------------------------------------+ -| | idx | [UINT16] | L2CAP connection oriented channel identifier | -+---------------------------+-----------------+----------------------------+----------------------------------------------------+ -| | bytes | [UINT16] | Number of bytes to send (hardcoded data pattern) | -+---------------------------+-----------------+----------------------------+----------------------------------------------------+ -| **l2cap-show-coc** | | | Show connected L2CAP channels | -+---------------------------+-----------------+----------------------------+----------------------------------------------------+ +.. table:: L2CAP Connection Oriented Channels + :widths: 25 15 15 45 + + +---------------------------+-----------------+----------------------------+----------------------------------------------------+ + | **Command** | **Parameters** | **Possible values** | **Description** | + +===========================+=================+============================+====================================================+ + | **l2cap-create-server** | | | Create L2CAP server | + +---------------------------+-----------------+----------------------------+----------------------------------------------------+ + | | psm | [UINT16] | PSM | + +---------------------------+-----------------+----------------------------+----------------------------------------------------+ + | **l2cap-connect** | | | Connect to remote L2CAP server | + +---------------------------+-----------------+----------------------------+----------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +---------------------------+-----------------+----------------------------+----------------------------------------------------+ + | | psm | [UINT16] | PSM | + +---------------------------+-----------------+----------------------------+----------------------------------------------------+ + | **l2cap-disconnect** | | | Disconnec from L2CAP server | + +---------------------------+-----------------+----------------------------+----------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +---------------------------+-----------------+----------------------------+----------------------------------------------------+ + | | idx | [UINT16] | L2CAP connection oriented channel identifier | + +---------------------------+-----------------+----------------------------+----------------------------------------------------+ + | **l2cap-send** | | | Send data over connected L2CAP channel | + +---------------------------+-----------------+----------------------------+----------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +---------------------------+-----------------+----------------------------+----------------------------------------------------+ + | | idx | [UINT16] | L2CAP connection oriented channel identifier | + +---------------------------+-----------------+----------------------------+----------------------------------------------------+ + | | bytes | [UINT16] | Number of bytes to send (hardcoded data pattern) | + +---------------------------+-----------------+----------------------------+----------------------------------------------------+ + | **l2cap-show-coc** | | | Show connected L2CAP channels | + +---------------------------+-----------------+----------------------------+----------------------------------------------------+ Keys storage ------------ -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| **Command** | **Parmeters** | \*\* Possible values\*\* | **Description** | -+=====================+=================+============================+====================================================+ -| **keystore-add** | | | Add keys to storage | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | type | msec | Master Key | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | | ssec | Slave Key | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | | cccd | Client Characteristic Configuration Descriptor | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | addr | XX:XX:XX:XX:XX:XX | Device address | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | addr\_type | ``public`` | Device address type | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | | random | Use random address for scan requests | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | ediv | [UINT16] | EDIV for LTK to add | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | rand | [UINT64] | Rand for LTK | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | ltk | XX:XX:XX... | LTK (16 bytes) | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | irk | XX:XX:XX... | Identity Resolving Key (16 bytes) | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | csrk | XX:XX:XX... | Connection Signature Resolving Key (16 bytes) | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| **keystore-del** | | | Delete keys from storage | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | type | msec | Master Key | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | | ssec | Slave Key | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | | cccd | Client Characteristic Configuration Descriptor | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | addr | XX:XX:XX:XX:XX:XX | Device address | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | addr\_type | ``public`` | Device address type | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | | random | Use random address for scan requests | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | ediv | [UINT16] | EDIV for LTK to remove | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | rand | [UINT64] | Rand for LTK | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| **keystore-show** | | | Show stored keys | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | type | msec | Master Keys | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | | ssec | Slave Keys | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ -| | | cccd | Client Characteristic Configuration Descriptor s | -+---------------------+-----------------+----------------------------+----------------------------------------------------+ +.. table:: Keys storage + :widths: 20 15 20 45 + + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | **Command** | **Parameters** | **Possible values** | **Description** | + +=====================+=================+============================+====================================================+ + | **keystore-add** | | | Add keys to storage | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | type | msec | Master Key | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | | ssec | Slave Key | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | | cccd | Client Characteristic Configuration Descriptor | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | addr | XX:XX:XX:XX:XX:XX | Device address | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | addr\_type | ``public`` | Device address type | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | | random | Use random address for scan requests | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | ediv | [UINT16] | EDIV for LTK to add | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | rand | [UINT64] | Rand for LTK | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | ltk | XX:XX:XX... | LTK (16 bytes) | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | irk | XX:XX:XX... | Identity Resolving Key (16 bytes) | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | csrk | XX:XX:XX... | Connection Signature Resolving Key (16 bytes) | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | **keystore-del** | | | Delete keys from storage | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | type | msec | Master Key | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | | ssec | Slave Key | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | | cccd | Client Characteristic Configuration Descriptor | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | addr | XX:XX:XX:XX:XX:XX | Device address | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | addr\_type | ``public`` | Device address type | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | | random | Use random address for scan requests | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | ediv | [UINT16] | EDIV for LTK to remove | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | rand | [UINT64] | Rand for LTK | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | **keystore-show** | | | Show stored keys | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | type | msec | Master Keys | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | | ssec | Slave Keys | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ + | | | cccd | Client Characteristic Configuration Descriptors | + +---------------------+-----------------+----------------------------+----------------------------------------------------+ diff --git a/docs/btshell/btshell_GATT.rst b/docs/btshell/btshell_GATT.rst index 0fe465fe5b..5468e49c4f 100644 --- a/docs/btshell/btshell_GATT.rst +++ b/docs/btshell/btshell_GATT.rst @@ -1,108 +1,109 @@ GATT feature API for btshell ============================ -GATT(GENERIC ATTRIBUTE PROFILE) describes a service framework using the Attribute Protocol for discovering services, +Generic Attribute Profile (GATT) describes a service framework using the Attribute Protocol for discovering services, and for reading and writing characteristic values on a peer device. There are 11 features defined in the GATT Profile, and each of the features is mapped to procedures and sub-procedures: Available commands ~~~~~~~~~~~~~~~~~~ -Parameters default values (if applicable) are marked red. - Configuration ------------- -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| **Command** | **Parmeters** | \*\* Possible values\*\* | **Description** | -+====================================+=================+============================+===========================================================+ -| **gatt-discover-characteristic** | | | Discover GATT characteristics | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | uuid | [UINT16] | Characteristic UUID | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | start | [UINT16] | Discovery start handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | end | [UINT16] | Discovery end handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| **gatt-discover-descriptor** | | | Discover GATT descriptors | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | start | [UINT16] | Discovery start handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | end | [UINT16] | Discovery end handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| **gatt-discover-service** | | | Discover services | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | uuid16 | [UINT16] | Service UUID | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| **gatt-discover-full** | | | Discover services, characteristic and descriptors | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| **gatt-find-included-services** | | | Find included services | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | start | [UINT16] | Discovery start handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | end | [UINT16] | Discovery end handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| **gatt-exchange-mtu** | | | Initiate ATT MTU exchange procedure | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| **gatt-read** | | | Read attribute | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | long | [``0``-1] | Long read | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | attr | [UINT16] | Attribute handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | offset | [UINT16] | Long read offset value | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | uuid | [UINT16] | Characteristic UUID | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | start | [UINT16] | Discovery start handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | end | [UINT16] | Discovery end handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| **gatt-notify** | | | Send notification or indication to all subscribed peers | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | attr | [UINT16] | Attribute handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| **gatt-service-changed** | | | Send Services Changed notification | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | start | [UINT16] | Start handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | end | [UINT16] | End handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| **gatt-service-visibility** | | | Set service visibility | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | handle | [UINT16] | Service handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | visibility | [``0``-1] | Service visibility | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| **gatt-show** | | | Show remote devices discovered databases structure | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| **gatt-show-local** | | | Show local database structure | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| **gatt-write** | | | Write attribute | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | conn | [UINT16] | Connection handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | no\_rsp | [``0``-1] | Use Write Without Response | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | long | [``0``-1] | Use Long Write procedure | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | attr | [UINT16] | Attribute handle | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | offset | [UINT16] | Long write offset value | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ -| | value | XX:XX:XX... | Data to write | -+------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ +.. table:: Configuration + :widths: 20 15 20 45 + + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | **Command** | **Parmeters** | **Possible values** | **Description** | + +====================================+=================+============================+===========================================================+ + | **gatt-discover-characteristic** | | | Discover GATT characteristics | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | uuid | [UINT16] | Characteristic UUID | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | start | [UINT16] | Discovery start handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | end | [UINT16] | Discovery end handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | **gatt-discover-descriptor** | | | Discover GATT descriptors | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | start | [UINT16] | Discovery start handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | end | [UINT16] | Discovery end handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | **gatt-discover-service** | | | Discover services | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | uuid16 | [UINT16] | Service UUID | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | **gatt-discover-full** | | | Discover services, characteristic and descriptors | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | **gatt-find-included-services** | | | Find included services | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | start | [UINT16] | Discovery start handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | end | [UINT16] | Discovery end handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | **gatt-exchange-mtu** | | | Initiate ATT MTU exchange procedure | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | **gatt-read** | | | Read attribute | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | long | [``0``-1] | Long read | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | attr | [UINT16] | Attribute handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | offset | [UINT16] | Long read offset value | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | uuid | [UINT16] | Characteristic UUID | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | start | [UINT16] | Discovery start handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | end | [UINT16] | Discovery end handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | **gatt-notify** | | | Send notification or indication to all subscribed peers | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | attr | [UINT16] | Attribute handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | **gatt-service-changed** | | | Send Services Changed notification | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | start | [UINT16] | Start handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | end | [UINT16] | End handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | **gatt-service-visibility** | | | Set service visibility | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | handle | [UINT16] | Service handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | visibility | [``0``-1] | Service visibility | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | **gatt-show** | | | Show remote devices discovered databases structure | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | **gatt-show-local** | | | Show local database structure | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | **gatt-write** | | | Write attribute | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | conn | [UINT16] | Connection handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | no\_rsp | [``0``-1] | Use Write Without Response | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | long | [``0``-1] | Use Long Write procedure | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | attr | [UINT16] | Attribute handle | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | offset | [UINT16] | Long write offset value | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ + | | value | XX:XX:XX... | Data to write | + +------------------------------------+-----------------+----------------------------+-----------------------------------------------------------+ diff --git a/docs/btshell/btshell_advdata.rst b/docs/btshell/btshell_advdata.rst index eabfcb3b84..b533cb069b 100644 --- a/docs/btshell/btshell_advdata.rst +++ b/docs/btshell/btshell_advdata.rst @@ -6,42 +6,46 @@ formats used for Extended Inquiry Response (EIR), Advertising Data (AD), and OOB to the Bluetooth Core Specification, CSSv6, available for download `here `__. -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| **Name** | **Definition** | **Details** | **btshell Notes** | -+===========================+=====================================================+===========================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================+==============================================+ -| flags | Indicates basic information about the advertiser. | Flags used over the LE physical channel are: \* Limited Discoverable Mode \* General Discoverable Mode \* BR/EDR Not Supported \* Simultaneous LE and BR/EDR to Same Device Capable (Controller) \* Simultaneous LE and BR/EDR to Same Device Capable (Host) | NimBLE will auto-calculate if set to 0. | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| uuid16 | 16-bit Bluetooth Service UUIDs | Indicates the Service UUID list is incomplete i.e. more 16-bit Service UUIDs available. 16 bit UUIDs shall only be used if they are assigned by the Bluetooth SIG. | Set repeatedly for multiple service UUIDs. | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| uuid16\_is\_complete | 16-bit Bluetooth Service UUIDs | Indicates the Service UUID list is complete. 16 bit UUIDs shall only be used if they are assigned by the Bluetooth SIG. | | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| uuid32 | 32-bit Bluetooth Service UUIDs | Indicates the Service UUID list is incomplete i.e. more 32-bit Service UUIDs available. 32 bit UUIDs shall only be used if they are assigned by the Bluetooth SIG. | Set repeatedly for multiple service UUIDs. | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| uuid32\_is\_complete | 32-bit Bluetooth Service UUIDs | Indicates the Service UUID list is complete. 32 bit UUIDs shall only be used if they are assigned by the Bluetooth SIG. | | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| uuid128 | Global 128-bit Service UUIDs | More 128-bit Service UUIDs available. | Set repeatedly for multiple service UUIDs. | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| uuid128\_is\_complete | Global 128-bit Service UUIDs | Complete list of 128-bit Service UUIDs | | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| tx\_power\_level | TX Power Level | Indicates the transmitted power level of the packet containing the data type. The TX Power Level data type may be used to calculate path loss on a received packet using the following equation: pathloss = Tx Power Level – RSSI where “RSSI” is the received signal strength, in dBm, of the packet received. | NimBLE will auto-calculate if set to -128. | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| slave\_interval\_range | Slave Connection Interval Range | Contains the Peripheral’s preferred connection interval range, for all logical connections. Size: 4 Octets . The first 2 octets defines the minimum value for the connection interval in the following manner: connIntervalmin = Conn\_Interval\_Min \* 1.25 ms Conn\_Interval\_Min range: 0x0006 to 0x0C80 Value of 0xFFFF indicates no specific minimum. The other 2 octets defines the maximum value for the connection interval in the following manner: connIntervalmax = Conn\_Interval\_Max \* 1.25 ms Conn\_Interval\_Max range: 0x0006 to 0x0C80 Conn\_Interval\_Max shall be equal to or greater than the Conn\_Interval\_Min. Value of 0xFFFF indicates no specific maximum. | | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| service\_data\_uuid16 | Service Data - 16 bit UUID | Size: 2 or more octets The first 2 octets contain the 16 bit Service UUID followed by additional service data | | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| public\_target\_address | Public Target Address | Defines the address of one or more intended recipients of an advertisement when one or more devices were bonded using a public address. This data type shall exist only once. It may be sent in either the Advertising or Scan Response data, but not both. | | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| appearance | Appearance | Defines the external appearance of the device. The Appearance data type shall exist only once. It may be sent in either the Advertising or Scan Response data, but not both. | | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| advertising\_interval | Advertising Interval | Contains the advInterval value as defined in the Core specification, Volume 6, Part B, Section 4.4.2.2. | | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| service\_data\_uuid32 | Service Data - 32 bit UUID | Size: 4 or more octets The first 4 octets contain the 32 bit Service UUID followed by additional service data | | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| service\_data\_uuid128 | Service Data - 128 bit UUID | Size: 16 or more octets The first 16 octets contain the 128 bit Service UUID followed by additional service data | | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| uri | Uniform Resource Identifier (URI) | Scheme name string and URI as a UTF-8 string | | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| mfg\_data | Manufacturer Specific data | Size: 2 or more octets The first 2 octets contain the Company Identifier Code followed by additional manufacturer specific data | | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ -| eddystone\_url | | | | -+---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ +.. table:: Advertisement Data Fields + :class: longtable + :widths: 20 20 45 15 + + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | **Name** | **Definition** | **Details** | **btshell Notes** | + +===========================+=====================================================+===========================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================+==============================================+ + | flags | Indicates basic information about the advertiser. | Flags used over the LE physical channel are: \* Limited Discoverable Mode \* General Discoverable Mode \* BR/EDR Not Supported \* Simultaneous LE and BR/EDR to Same Device Capable (Controller) \* Simultaneous LE and BR/EDR to Same Device Capable (Host) | NimBLE will auto-calculate if set to 0. | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | uuid16 | 16-bit Bluetooth Service UUIDs | Indicates the Service UUID list is incomplete i.e. more 16-bit Service UUIDs available. 16 bit UUIDs shall only be used if they are assigned by the Bluetooth SIG. | Set repeatedly for multiple service UUIDs. | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | uuid16\_is\_complete | 16-bit Bluetooth Service UUIDs | Indicates the Service UUID list is complete. 16 bit UUIDs shall only be used if they are assigned by the Bluetooth SIG. | | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | uuid32 | 32-bit Bluetooth Service UUIDs | Indicates the Service UUID list is incomplete i.e. more 32-bit Service UUIDs available. 32 bit UUIDs shall only be used if they are assigned by the Bluetooth SIG. | Set repeatedly for multiple service UUIDs. | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | uuid32\_is\_complete | 32-bit Bluetooth Service UUIDs | Indicates the Service UUID list is complete. 32 bit UUIDs shall only be used if they are assigned by the Bluetooth SIG. | | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | uuid128 | Global 128-bit Service UUIDs | More 128-bit Service UUIDs available. | Set repeatedly for multiple service UUIDs. | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | uuid128\_is\_complete | Global 128-bit Service UUIDs | Complete list of 128-bit Service UUIDs | | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | tx\_power\_level | TX Power Level | Indicates the transmitted power level of the packet containing the data type. The TX Power Level data type may be used to calculate path loss on a received packet using the following equation: pathloss = Tx Power Level – RSSI where “RSSI” is the received signal strength, in dBm, of the packet received. | NimBLE will auto-calculate if set to -128. | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | slave\_interval\_range | Slave Connection Interval Range | Contains the Peripheral’s preferred connection interval range, for all logical connections. Size: 4 Octets . The first 2 octets defines the minimum value for the connection interval in the following manner: connIntervalmin = Conn\_Interval\_Min \* 1.25 ms Conn\_Interval\_Min range: 0x0006 to 0x0C80 Value of 0xFFFF indicates no specific minimum. The other 2 octets defines the maximum value for the connection interval in the following manner: connIntervalmax = Conn\_Interval\_Max \* 1.25 ms Conn\_Interval\_Max range: 0x0006 to 0x0C80 Conn\_Interval\_Max shall be equal to or greater than the Conn\_Interval\_Min. Value of 0xFFFF indicates no specific maximum. | | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | service\_data\_uuid16 | Service Data - 16 bit UUID | Size: 2 or more octets The first 2 octets contain the 16 bit Service UUID followed by additional service data | | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | public\_target\_address | Public Target Address | Defines the address of one or more intended recipients of an advertisement when one or more devices were bonded using a public address. This data type shall exist only once. It may be sent in either the Advertising or Scan Response data, but not both. | | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | appearance | Appearance | Defines the external appearance of the device. The Appearance data type shall exist only once. It may be sent in either the Advertising or Scan Response data, but not both. | | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | advertising\_interval | Advertising Interval | Contains the advInterval value as defined in the Core specification, Volume 6, Part B, Section 4.4.2.2. | | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | service\_data\_uuid32 | Service Data - 32 bit UUID | Size: 4 or more octets The first 4 octets contain the 32 bit Service UUID followed by additional service data | | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | service\_data\_uuid128 | Service Data - 128 bit UUID | Size: 16 or more octets The first 16 octets contain the 128 bit Service UUID followed by additional service data | | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | uri | Uniform Resource Identifier (URI) | Scheme name string and URI as a UTF-8 string | | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | mfg\_data | Manufacturer Specific data | Size: 2 or more octets The first 2 octets contain the Company Identifier Code followed by additional manufacturer specific data | | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + | eddystone\_url | | | | + +---------------------------+-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+ diff --git a/docs/mesh/index.rst b/docs/mesh/index.rst index 6ad75363f0..bab9d883ae 100644 --- a/docs/mesh/index.rst +++ b/docs/mesh/index.rst @@ -84,6 +84,7 @@ Lightness Server Model. .. figure:: mesh_lightning_model.jpg :alt: Light Lightness Server model (source: Mesh Model Specification 1.0) + :width: 450 Mesh Node features supported by Apache Mynewt ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 64d5000f7257c774e17235c1f96d85eda28c0971 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 23 Sep 2024 15:03:21 +0200 Subject: [PATCH 1088/1333] nimble/ll: Fix periodic advertising event timing This modifies padv event start time calculations to use single event start time as anchor and calculate subsequent event start times as an offset from that event. This virtually removes drift due to rounding errors and avoids relative drift of padv vs. BIG events. --- nimble/controller/src/ble_ll_adv.c | 80 +++++++++++++++++------------- 1 file changed, 45 insertions(+), 35 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index f194ec21c9..d8eaaaf3ab 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -170,10 +170,16 @@ struct ble_ll_adv_sm uint8_t periodic_num_used_chans; uint8_t periodic_chanmap[BLE_LL_CHAN_MAP_LEN]; uint16_t periodic_adv_itvl; - uint32_t periodic_adv_itvl_ticks; - uint8_t periodic_adv_itvl_rem_us; - uint8_t periodic_adv_event_start_time_remainder; - uint32_t periodic_adv_event_start_time; + + uint32_t padv_itvl_us; + + uint16_t padv_anchor_offset; + uint32_t padv_anchor; + uint8_t padv_anchor_rem_us; + + uint32_t padv_event_start; + uint8_t padv_event_start_rem_us; + struct ble_ll_adv_sync periodic_sync[2]; struct ble_npl_event adv_periodic_txdone_ev; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) @@ -639,20 +645,20 @@ ble_ll_adv_put_syncinfo(struct ble_ll_adv_sm *advsm, conn_cnt = connsm->event_cntr; /* get anchor for conn event that is before periodic_adv_event_start_time */ - while (LL_TMR_GT(anchor_ticks, advsm->periodic_adv_event_start_time)) { + while (LL_TMR_GT(anchor_ticks, advsm->padv_event_start)) { ble_ll_conn_get_anchor(connsm, --conn_cnt, &anchor_ticks, &anchor_rem_us); } - offset = ble_ll_tmr_t2u(advsm->periodic_adv_event_start_time - anchor_ticks); + offset = ble_ll_tmr_t2u(advsm->padv_event_start - anchor_ticks); offset -= anchor_rem_us; - offset += advsm->periodic_adv_event_start_time_remainder; + offset += advsm->padv_event_start_rem_us; /* connEventCount */ put_le16(conn_event_cnt, conn_cnt); #endif } else { - anchor_ticks = advsm->periodic_adv_event_start_time; - anchor_rem_us = advsm->periodic_adv_event_start_time_remainder; + anchor_ticks = advsm->padv_event_start; + anchor_rem_us = advsm->padv_event_start_rem_us; itvl_us = advsm->periodic_adv_itvl * BLE_LL_ADV_PERIODIC_ITVL; /* Get periodic event that is past AUX start time (so that we always @@ -2420,7 +2426,7 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm, * Preincrement event counter as we later send this in PDU so make sure * same values are used */ - chan = ble_ll_utils_dci_csa2(++advsm->periodic_event_cntr, + chan = ble_ll_utils_dci_csa2(advsm->periodic_event_cntr, advsm->periodic_channel_id, advsm->periodic_num_used_chans, advsm->periodic_chanmap); @@ -2432,14 +2438,20 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm, sch = &sync->sch; - ble_ll_tmr_add_u(&advsm->periodic_adv_event_start_time, - &advsm->periodic_adv_event_start_time_remainder, - advsm->periodic_adv_itvl_rem_us); + advsm->padv_event_start = advsm->padv_anchor; + advsm->padv_event_start_rem_us = advsm->padv_anchor_rem_us; + ble_ll_tmr_add(&advsm->padv_event_start, &advsm->padv_event_start_rem_us, + advsm->padv_itvl_us * advsm->padv_anchor_offset); + + if (advsm->padv_anchor_offset == UINT16_MAX) { + advsm->padv_anchor_offset = 0; + advsm->padv_anchor = advsm->padv_event_start; + advsm->padv_anchor_rem_us = advsm->padv_event_start_rem_us; + } - sch->start_time = advsm->periodic_adv_event_start_time; - sch->remainder = advsm->periodic_adv_event_start_time_remainder; - sch->end_time = sch->start_time + ble_ll_tmr_u2t_up(max_usecs); - sch->start_time -= g_ble_ll_sched_offset_ticks; + sch->start_time = advsm->padv_event_start - g_ble_ll_sched_offset_ticks; + sch->remainder = advsm->padv_event_start_rem_us; + sch->end_time = advsm->padv_event_start + ble_ll_tmr_u2t_up(max_usecs); rc = ble_ll_sched_periodic_adv(sch, first_pdu); if (rc) { @@ -2451,10 +2463,14 @@ ble_ll_adv_periodic_schedule_first(struct ble_ll_adv_sm *advsm, sync->start_time = sch->start_time + g_ble_ll_sched_offset_ticks; assert(first_pdu || - (sync->start_time == advsm->periodic_adv_event_start_time)); + (sync->start_time == advsm->padv_event_start)); - /* The event start time is when we start transmission of the SYNC PDU */ - advsm->periodic_adv_event_start_time = sync->start_time; + if (first_pdu) { + /* Need to update anchor on 1st PDU since it's start time can be changed + * while scheduling */ + advsm->padv_anchor = sync->start_time; + advsm->padv_event_start = sync->start_time; + } } static void @@ -2535,8 +2551,8 @@ ble_ll_adv_periodic_schedule_next(struct ble_ll_adv_sm *advsm) * is scheduled past advertising interval. */ if (sync->auxptr_zero || - (LL_TMR_GT(sch->end_time, advsm->periodic_adv_event_start_time + - advsm->periodic_adv_itvl_ticks))) { + (LL_TMR_GT(sch->end_time, advsm->padv_event_start + + advsm->periodic_adv_itvl))) { STATS_INC(ble_ll_stats, periodic_chain_drop_event); ble_ll_sched_rmv_elem(&sync->sch); } @@ -2560,7 +2576,9 @@ ble_ll_adv_sync_schedule(struct ble_ll_adv_sm *advsm, bool first_pdu) static void ble_ll_adv_reschedule_periodic_event(struct ble_ll_adv_sm *advsm) { - advsm->periodic_adv_event_start_time += advsm->periodic_adv_itvl_ticks; + advsm->periodic_event_cntr++; + advsm->padv_anchor_offset++; + ble_ll_adv_sync_schedule(advsm, false); } @@ -2634,8 +2652,6 @@ ble_ll_adv_periodic_event_done(struct ble_npl_event *ev) static void ble_ll_adv_sm_start_periodic(struct ble_ll_adv_sm *advsm) { - uint32_t usecs; - /* * The Advertising DID is not required to change when a SyncInfo field is * added to or removed from an advertising set. However, if it does not @@ -2660,16 +2676,9 @@ ble_ll_adv_sm_start_periodic(struct ble_ll_adv_sm *advsm) (advsm->periodic_access_addr & 0x0000ffff); advsm->periodic_crcinit = ble_ll_rand() & 0xffffff; - usecs = (uint32_t)advsm->periodic_adv_itvl * BLE_LL_ADV_PERIODIC_ITVL; - advsm->periodic_adv_itvl_ticks = ble_ll_tmr_u2t_r(usecs, - &advsm->periodic_adv_itvl_rem_us); - - /* There is no point in starting periodic advertising until next advertising - * event since SyncInfo is needed for synchronization - */ - advsm->periodic_adv_event_start_time_remainder = 0; - advsm->periodic_adv_event_start_time = advsm->adv_pdu_start_time + - ble_ll_tmr_u2t(advsm->adv_itvl_usecs + 5000); + advsm->padv_anchor_offset = 1; + advsm->padv_anchor = ble_ll_tmr_get(); + advsm->padv_anchor_rem_us = 0; ble_ll_adv_sync_schedule(advsm, true); } @@ -3977,6 +3986,7 @@ ble_ll_adv_periodic_set_param(const uint8_t *cmdbuf, uint8_t len) } advsm->periodic_adv_itvl = adv_itvl_max; + advsm->padv_itvl_us = adv_itvl_max * BLE_LL_ADV_PERIODIC_ITVL; advsm->periodic_adv_props = props; ble_ll_adv_flags_set(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_CONFIGURED); From b6d7261d75028226ea01decab0fa5281c0eecbe8 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 23 Sep 2024 17:34:41 +0200 Subject: [PATCH 1089/1333] nimble/ll: Fix BIG event scheduling relative to padv This fixes scheduling of BIG events relative to padv. The start time of a BIG event should be relative to padv event start, not padv sched start time which in theory may be different if that's not for the 1st AUX_SYNC_IND. Also if padv event start time is in the past, we still need to schedule BIG event in the future instead of just failing. --- .../include/controller/ble_ll_adv.h | 6 ++-- nimble/controller/src/ble_ll_adv.c | 17 +++++---- nimble/controller/src/ble_ll_iso_big.c | 35 +++++++++---------- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_adv.h b/nimble/controller/include/controller/ble_ll_adv.h index db35209dc1..6c332faf3c 100644 --- a/nimble/controller/include/controller/ble_ll_adv.h +++ b/nimble/controller/include/controller/ble_ll_adv.h @@ -201,9 +201,9 @@ int ble_ll_adv_periodic_set_info_transfer(const uint8_t *cmdbuf, uint8_t len, /* Get advertising instance with periodic advertising configured */ struct ble_ll_adv_sm *ble_ll_adv_sync_get(uint8_t handle); -/* Get periodic advertising event scheduled time */ -int ble_ll_adv_sync_sched_get(struct ble_ll_adv_sm *advsm, - uint32_t *start_time, uint32_t *end_time); +int ble_ll_adv_padv_event_start_get(struct ble_ll_adv_sm *advsm, + uint32_t *event_start, + uint8_t *event_start_rem_us); #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) struct ble_ll_iso_big; diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index d8eaaaf3ab..809a887765 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -5337,19 +5337,18 @@ ble_ll_adv_sync_get(uint8_t handle) } int -ble_ll_adv_sync_sched_get(struct ble_ll_adv_sm *advsm, uint32_t *start_time, - uint32_t *end_time) +ble_ll_adv_padv_event_start_get(struct ble_ll_adv_sm *advsm, + uint32_t *event_start, + uint8_t *event_start_rem_us) { - struct ble_ll_adv_sync *sync; - if (!advsm || !advsm->periodic_adv_active) { - return -EIO; + return -EINVAL; } - sync = SYNC_CURRENT(advsm); - - *start_time = sync->sch.start_time + g_ble_ll_sched_offset_ticks; - *end_time = sync->sch.end_time; + *event_start = advsm->padv_event_start; + if (event_start_rem_us) { + *event_start_rem_us = advsm->padv_event_start_rem_us; + } return 0; } diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index b07e5c1d86..19af3e61fd 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -1111,41 +1111,40 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, * not enough for some phys to run scheduler item. */ - uint32_t start_time, end_time, big_time; + uint32_t padv_start_time, big_start_time; uint32_t sync_delay_ticks = ble_ll_tmr_u2t_up(big->sync_delay); - uint32_t iso_interval_ticks = ble_ll_tmr_u2t_up(big->iso_interval * 1250); int big_event_fixed; - rc = ble_ll_adv_sync_sched_get(big->advsm, &start_time, &end_time); + rc = ble_ll_adv_padv_event_start_get(big->advsm, &padv_start_time, NULL); if (rc) { - /* Set 1st BIG one interval after "now", this ensures it's always - * scheduled in the future. - */ - big_time = ble_ll_tmr_get() + iso_interval_ticks; + /* 1st event will be moved by 1 interval before scheduling so this will + * be always in the future */ + big_start_time = ble_ll_tmr_get(); big_event_fixed = 0; } else { /* Set 1st BIG event directly before periodic advertising event, this * way it will not overlap it even if periodic advertising data changes. * Make sure it's in the future. */ - big_time = start_time - g_ble_ll_sched_offset_ticks - sync_delay_ticks - 1; - while (big_time - g_ble_ll_sched_offset_ticks < ble_ll_tmr_get()) { - big_time += iso_interval_ticks; - } + big_start_time = padv_start_time - g_ble_ll_sched_offset_ticks - + sync_delay_ticks - 1; big_event_fixed = 1; } - big->anchor_base_ticks = big_time; + big->anchor_base_ticks = big_start_time; big->anchor_base_rem_us = 0; big->anchor_offset = 0; - big_sched_set(big); + do { + big->anchor_offset++; + big_sched_set(big); - rc = ble_ll_sched_iso_big(&big->sch, 1, big_event_fixed); - if (rc < 0) { - ble_ll_iso_big_free(big); - return -EFAULT; - } + if (LL_TMR_LEQ(big->sch.start_time, ble_ll_tmr_get())) { + rc = -1; + } else { + rc = ble_ll_sched_iso_big(&big->sch, 1, big_event_fixed); + } + } while (rc < 0); ble_ll_iso_big_update_event_start(big); From 881dc67914dd869dc3a6dea0685383211a94eeaf Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Fri, 13 Sep 2024 14:38:53 +0200 Subject: [PATCH 1090/1333] nimble/ll: Change ext_adv_params field name This changes name of field containing parameters from first version of SET_EXT_ADV_PARAMS in ble_hci_le_set_ext_adv_params_v2_cp structure. New name enhances clarity by more accurately describing its contents. --- nimble/host/src/ble_gap.c | 2 +- nimble/include/nimble/hci_common.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 5a161a2763..7d8cf39263 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -3257,7 +3257,7 @@ ble_gap_ext_adv_params_tx_v2(uint8_t instance, memset(&cmd, 0, sizeof(cmd)); - rc = ble_gap_set_ext_adv_params(&(cmd.cmd), instance, params, selected_tx_power); + rc = ble_gap_set_ext_adv_params(&(cmd.params_v1), instance, params, selected_tx_power); if (rc != 0) { return rc; diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 68f1538826..7e983c6c8b 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1152,7 +1152,7 @@ struct ble_hci_le_subrate_req_cp { #define BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM_V2 (0x007F) struct ble_hci_le_set_ext_adv_params_v2_cp { - struct ble_hci_le_set_ext_adv_params_cp cmd; + struct ble_hci_le_set_ext_adv_params_cp params_v1; uint8_t pri_phy_opt; uint8_t sec_phy_opt; } __attribute__((packed)); From 92754368952e499182ac2243b40a1f8ed375d043 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Wed, 18 Sep 2024 11:51:43 +0200 Subject: [PATCH 1091/1333] nimble/ll: Add set ext adv params v2 command This adds second version of Set Extended Advertising Parameters command (7.8.53) Introduced in Core Specification v5.4. --- .../include/controller/ble_ll_adv.h | 5 ++ nimble/controller/src/ble_ll_adv.c | 51 +++++++++++++++++++ nimble/controller/src/ble_ll_hci.c | 7 +++ nimble/controller/src/ble_ll_hci_supp_cmd.c | 3 ++ nimble/include/nimble/hci_common.h | 7 +++ 5 files changed, 73 insertions(+) diff --git a/nimble/controller/include/controller/ble_ll_adv.h b/nimble/controller/include/controller/ble_ll_adv.h index 6c332faf3c..6290c9f456 100644 --- a/nimble/controller/include/controller/ble_ll_adv.h +++ b/nimble/controller/include/controller/ble_ll_adv.h @@ -216,6 +216,11 @@ int ble_ll_adv_sync_big_remove(struct ble_ll_adv_sm *advsm, struct ble_ll_iso_big *big); #endif /* BLE_LL_ISO_BROADCASTER */ +#if MYNEWT_VAL(BLE_VERSION) >= 54 +int ble_ll_adv_ext_set_param_v2(const uint8_t *cmdbuf, uint8_t len, + uint8_t *rspbuf, uint8_t *rsplen); +#endif + /* Called to notify adv code about RPA rotation */ void ble_ll_adv_rpa_timeout(void); diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 809a887765..fb7aee633e 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -3622,6 +3622,57 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, return rc; } +#if MYNEWT_VAL(BLE_VERSION) >= 54 +static uint8_t +ble_ll_adv_ext_phy_mode_get(uint8_t phy, uint8_t phy_opt) +{ + if (phy != BLE_HCI_LE_PHY_CODED) { + return phy; + } + + switch (phy_opt) { + case BLE_HCI_ADVERTISING_PHY_OPT_S2_PREF: + case BLE_HCI_ADVERTISING_PHY_OPT_S2_REQ: + return BLE_PHY_MODE_CODED_500KBPS; + case BLE_HCI_ADVERTISING_PHY_OPT_NO_PREF: + case BLE_HCI_ADVERTISING_PHY_OPT_S8_PREF: + case BLE_HCI_ADVERTISING_PHY_OPT_S8_REQ: + return BLE_PHY_MODE_CODED_125KBPS; + default: + BLE_LL_ASSERT(0); + } +} + +int +ble_ll_adv_ext_set_param_v2(const uint8_t *cmdbuf, uint8_t len, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_le_set_ext_adv_params_v2_cp *cmd = (const void *) cmdbuf; + struct ble_ll_adv_sm *advsm; + int rc; + + if (len != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if ((cmd->pri_phy_opt > 4) || (cmd->sec_phy_opt > 4)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + rc = ble_ll_adv_ext_set_param(cmdbuf, len - 2, rspbuf, rsplen); + if (rc != 0) { + return rc; + } + + advsm = ble_ll_adv_sm_get(cmd->params_v1.adv_handle); + + advsm->pri_phy = ble_ll_adv_ext_phy_mode_get(cmd->params_v1.pri_phy, cmd->pri_phy_opt); + advsm->sec_phy = ble_ll_adv_ext_phy_mode_get(cmd->params_v1.pri_phy, cmd->sec_phy_opt); + + return rc; +} +#endif + int ble_ll_adv_ext_set_adv_data(const uint8_t *cmdbuf, uint8_t cmdlen) { diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index f75e4ddbaa..7e2d707bd8 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1317,6 +1317,13 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, rc = ble_ll_conn_hci_subrate_req(cmdbuf, len, rspbuf, rsplen); break; #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +#if MYNEWT_VAL(BLE_VERSION) >= 54 + case BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM_V2: + rc = ble_ll_adv_ext_set_param_v2(cmdbuf, len, rspbuf, rsplen); + break; +#endif +#endif #if MYNEWT_VAL(BLE_LL_CHANNEL_SOUNDING) case BLE_HCI_OCF_LE_CS_RD_LOC_SUPP_CAP: rc = ble_ll_cs_hci_rd_loc_supp_cap(rspbuf, rsplen); diff --git a/nimble/controller/src/ble_ll_hci_supp_cmd.c b/nimble/controller/src/ble_ll_hci_supp_cmd.c index 40b1e947ca..732381ea20 100644 --- a/nimble/controller/src/ble_ll_hci_supp_cmd.c +++ b/nimble/controller/src/ble_ll_hci_supp_cmd.c @@ -286,6 +286,9 @@ static const uint8_t octet_46 = OCTET( BIT(0) /* HCI LE Set Default Subrate */ BIT(1) /* HCI LE Subrate Request */ #endif +#if MYNEWT_VAL(BLE_VERSION) >= 54 && MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + BIT(2) /* HCI LE Set Extended Advertising Parameters [v2] */ +#endif ); static const uint8_t g_ble_ll_hci_supp_cmds[64] = { diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 7e983c6c8b..252b033973 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1637,6 +1637,13 @@ struct ble_hci_vs_set_local_irk_cp { #define BLE_HCI_PRIVACY_NETWORK (0) #define BLE_HCI_PRIVACY_DEVICE (1) +/* --- LE set advertising coded PHY options (OCF 0x007F) */ +#define BLE_HCI_ADVERTISING_PHY_OPT_NO_PREF 0x0 +#define BLE_HCI_ADVERTISING_PHY_OPT_S2_PREF 0x1 +#define BLE_HCI_ADVERTISING_PHY_OPT_S8_PREF 0x2 +#define BLE_HCI_ADVERTISING_PHY_OPT_S2_REQ 0x3 +#define BLE_HCI_ADVERTISING_PHY_OPT_S8_REQ 0x4 + /* Event Codes */ #define BLE_HCI_EVCODE_INQUIRY_CMP (0x01) #define BLE_HCI_EVCODE_INQUIRY_RESULT (0x02) From 1d866e41afa67eecf059a0e39c529370a78ef231 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 9 Oct 2024 15:40:29 +0200 Subject: [PATCH 1092/1333] nimble/host: Optimize characteristics discovery We can stop characteristics discovery as soon as there are less than 2 attributes left. This means if last characteristic has descriptor (e.g. CCC) we will save single ATT_READ_BY_TYPE_REQ/RSP transaction. As a side-effect we also resume discovery starting from the next handle after last characteristic value handle instead of characteristic declaration handle, but this is ok since there cannot be any atrtibutes (so also characteristic declarations) between characteristic declaration and characteristic value. --- nimble/host/src/ble_gattc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index 45ee869c85..b3c8e04e12 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -2299,7 +2299,9 @@ ble_gattc_disc_all_chrs_rx_adata(struct ble_gattc_proc *proc, rc = BLE_HS_EBADDATA; goto done; } - proc->disc_all_chrs.prev_handle = adata->att_handle; + + /* We'll resume after characteristic value */ + proc->disc_all_chrs.prev_handle = chr.val_handle; rc = 0; @@ -2328,7 +2330,10 @@ ble_gattc_disc_all_chrs_rx_complete(struct ble_gattc_proc *proc, int status) return BLE_HS_EDONE; } - if (proc->disc_all_chrs.prev_handle == proc->disc_all_chrs.end_handle) { + /* We can stop discovery if there are less than 2 attributes left since + * complete characteristic requires at least 2 handles. + */ + if (proc->disc_all_chrs.prev_handle + 1 >= proc->disc_all_chrs.end_handle - 1) { /* Characteristic discovery complete. */ ble_gattc_disc_all_chrs_cb(proc, BLE_HS_EDONE, 0, NULL); return BLE_HS_EDONE; From bda4b0c67d2cc66254e9d097aa9e499ba21b2dd8 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 16 Oct 2024 02:36:43 +0200 Subject: [PATCH 1093/1333] nimble/host: Clear ATT queue on conn_free We need to free all mbufs enqueued on ATT queue when connection is freed, otherwise we may leak mbufs. --- nimble/host/src/ble_hs_conn.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimble/host/src/ble_hs_conn.c b/nimble/host/src/ble_hs_conn.c index 57ba16af87..1e83d33de2 100644 --- a/nimble/host/src/ble_hs_conn.c +++ b/nimble/host/src/ble_hs_conn.c @@ -255,6 +255,11 @@ ble_hs_conn_free(struct ble_hs_conn *conn) os_mbuf_free_chain(OS_MBUF_PKTHDR_TO_MBUF(omp)); } + while ((omp = STAILQ_FIRST(&conn->att_tx_q)) != NULL) { + STAILQ_REMOVE_HEAD(&conn->att_tx_q, omp_next); + os_mbuf_free_chain(OS_MBUF_PKTHDR_TO_MBUF(omp)); + } + #if MYNEWT_VAL(BLE_HS_DEBUG) memset(conn, 0xff, sizeof *conn); #endif From 5191a4eeeaac45941384f2e75149f355f52f53a1 Mon Sep 17 00:00:00 2001 From: Mynewt Bot Date: Wed, 16 Oct 2024 21:46:41 +0000 Subject: [PATCH 1094/1333] porting: Update ports syscfg --- porting/npl/riot/include/syscfg/syscfg.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index c6d948e67a..c4e8383e44 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -949,6 +949,10 @@ #define MYNEWT_VAL_BASELIBC_ASSERT_FILE_LINE (0) #endif +#ifndef MYNEWT_VAL_BASELIBC_DEBUG_MALLOC +#define MYNEWT_VAL_BASELIBC_DEBUG_MALLOC (0) +#endif + #ifndef MYNEWT_VAL_BASELIBC_EXECUTE_GLOBAL_CONSTRUCTORS #define MYNEWT_VAL_BASELIBC_EXECUTE_GLOBAL_CONSTRUCTORS (1) #endif From 7ae1910cdca5f713e2ecd369b0f5fc46db325d7a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 17 Oct 2024 20:45:39 +0200 Subject: [PATCH 1095/1333] nimble/ll: Null-terminate string in vs_printf HCI event This allows app on host to simply print the contents of event. --- nimble/controller/src/ble_ll_hci_ev.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index 06d3706875..8d088d9da8 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -618,6 +618,7 @@ ble_ll_hci_ev_send_vs_printf(uint8_t id, const char *fmt, ...) struct ble_hci_ev_vs *ev; struct ble_hci_ev *hci_ev; va_list ap; + int len; hci_ev = ble_transport_alloc_evt(1); if (!hci_ev) { @@ -631,10 +632,12 @@ ble_ll_hci_ev_send_vs_printf(uint8_t id, const char *fmt, ...) ev->id = id; va_start(ap, fmt); - hci_ev->length += vsnprintf((void *)ev->data, - BLE_HCI_MAX_DATA_LEN - sizeof(*ev), fmt, ap); + len = vsnprintf((void *)ev->data, BLE_HCI_MAX_DATA_LEN - sizeof(*ev), fmt, ap); va_end(ap); + ev->data[len] = 0; + hci_ev->length += len + 1; + ble_ll_hci_event_send(hci_ev); } From 38d08c938547e3d76bb7b1ff6ac294813aaeeb2b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 17 Oct 2024 00:55:15 +0200 Subject: [PATCH 1096/1333] nimble/ll: Fix calculating BIG scheduler start time The same code is executed already in big_sched_set resulting in sched offset being subtracted twice. --- nimble/controller/src/ble_ll_iso_big.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 19af3e61fd..5109a6b6b4 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -573,10 +573,6 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) big->anchor_offset++; big_sched_set(big); - big->sch.end_time = big->sch.start_time + - ble_ll_tmr_u2t_up(big->sync_delay) + 1; - big->sch.start_time -= g_ble_ll_sched_offset_ticks; - /* XXX this should always succeed since we preempt anything for now */ rc = ble_ll_sched_iso_big(&big->sch, 0, 0); assert(rc == 0); From d3bf5ec7c2b639f497d81811bf1920fb2112eaf0 Mon Sep 17 00:00:00 2001 From: Roman Sukhorukov Date: Sat, 10 Aug 2024 09:25:44 +0300 Subject: [PATCH 1097/1333] nimble/host: Add offset in GATT server long read context This allows application to easily determine if client is performing GATT Long Read operation. --- nimble/host/include/host/ble_gatt.h | 6 ++++++ nimble/host/src/ble_gatts.c | 1 + 2 files changed, 7 insertions(+) diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index 5a268c0c9c..229d99dda3 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -960,6 +960,12 @@ struct ble_gatt_access_ctxt { */ const struct ble_gatt_dsc_def *dsc; }; + + /** + * An offset in case of BLE_ATT_OP_READ_BLOB_REQ. + * If the value is greater than zero it's an indication of a long attribute read. + */ + uint16_t offset; }; /** diff --git a/nimble/host/src/ble_gatts.c b/nimble/host/src/ble_gatts.c index bf50305f4f..c77e561b73 100644 --- a/nimble/host/src/ble_gatts.c +++ b/nimble/host/src/ble_gatts.c @@ -416,6 +416,7 @@ ble_gatts_chr_val_access(uint16_t conn_handle, uint16_t attr_handle, gatt_ctxt.op = ble_gatts_chr_op(att_op); gatt_ctxt.chr = chr_def; + gatt_ctxt.offset = offset; ble_gatts_chr_inc_val_stat(gatt_ctxt.op); rc = ble_gatts_val_access(conn_handle, attr_handle, offset, &gatt_ctxt, om, From caad037667b1ff00421bb8211efddb94f9f0d82d Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 18 Oct 2024 17:17:27 +0200 Subject: [PATCH 1098/1333] nimble/ll: Allow anonymous adv on non-scan/conn/legacy only --- nimble/controller/src/ble_ll_adv.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index fb7aee633e..64884376a5 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -3427,6 +3427,32 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, goto done; } + /* Anonymous advertising only makes sense for non-connectable, non-scannable + * and non-legacy. This is not explicitly stated anywhere in HCI/LL part of + * the spec, but Vol 3, Part C, 9.1.1.2 (GAP) states: + * "A device in the Broadcast mode may send non-connectable and non- + * scannable undirected or non-connectable and non-scannable directed + * advertising events anonymously by excluding the Broadcaster's address." + * And Vol 4, Part E, 7.8.53 (HCI) states: + * "If the Advertising_Event_Properties parameter does not describe an + * event type supported by the Controller, contains an invalid bit + * combination, or specifies a type that does not support advertising + * data when the advertising set already contains some, the Controller + * shall return the error code Invalid HCI Command Parameters (0x12)." + * + * So let's just assume anonymous on connectable/scannable/legacy is an + * invalid bit combination. + */ + if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV) { + if (props & (BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE | + BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE | + BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED | + BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY)) { + rc = BLE_ERR_INV_HCI_CMD_PARMS; + goto done; + } + } + if (props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) { if (ADV_DATA_LEN(advsm) > BLE_ADV_LEGACY_DATA_MAX_LEN || SCAN_RSP_DATA_LEN(advsm) > BLE_SCAN_RSP_LEGACY_DATA_MAX_LEN) { From a5fa9d1e841ed4f160502cff43a4f57d1a0fe2f5 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Sun, 6 Oct 2024 21:43:38 +0200 Subject: [PATCH 1099/1333] nimble/ll: Add option to select location of AdvA in ext adv This adds syscfg to select location of AdvA in extended advertising PDUs. If enabled, AdvA is put in AUX_ADV_IND instead of ADV_EXT_IND. This is enabled by default to retain current behavior. --- nimble/controller/src/ble_ll_adv.c | 33 ++++++++++++++++++++++++++---- nimble/controller/syscfg.yml | 5 +++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 64884376a5..98ddfbfcc6 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -570,6 +570,7 @@ ble_ll_adv_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) uint8_t ext_hdr_len; uint8_t ext_hdr_flags; uint32_t offset; + bool has_adva; advsm = pducb_arg; @@ -581,8 +582,6 @@ ble_ll_adv_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) /* only ADV_EXT_IND goes on primary advertising channels */ pdu_type = BLE_ADV_PDU_TYPE_ADV_EXT_IND; - *hdr_byte = pdu_type; - adv_mode = 0; if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE) { adv_mode |= BLE_LL_EXT_ADV_MODE_CONN; @@ -591,11 +590,19 @@ ble_ll_adv_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) adv_mode |= BLE_LL_EXT_ADV_MODE_SCAN; } + has_adva = !MYNEWT_VAL(BLE_LL_EXT_ADV_ADVA_IN_AUX) && + !(advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV); + ext_hdr_len = BLE_LL_EXT_ADV_FLAGS_SIZE + BLE_LL_EXT_ADV_DATA_INFO_SIZE + BLE_LL_EXT_ADV_AUX_PTR_SIZE; ext_hdr_flags = (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT) | (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT); + if (has_adva) { + ext_hdr_len += BLE_LL_EXT_ADV_ADVA_SIZE; + ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_ADVA_BIT); + } + /* ext hdr len and adv mode */ dptr[0] = ext_hdr_len | (adv_mode << 6); dptr += 1; @@ -604,6 +611,15 @@ ble_ll_adv_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) dptr[0] = ext_hdr_flags; dptr += 1; + if (has_adva) { + /* AdvA */ + if (advsm->flags & BLE_LL_ADV_SM_FLAG_TX_ADD) { + pdu_type |= BLE_ADV_PDU_HDR_TXADD_RAND; + } + memcpy(dptr, advsm->adva, BLE_LL_EXT_ADV_ADVA_SIZE); + dptr += BLE_LL_EXT_ADV_ADVA_SIZE; + } + /* ADI */ dptr[0] = advsm->adi & 0x00ff; dptr[1] = advsm->adi >> 8; @@ -619,6 +635,8 @@ ble_ll_adv_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) ble_ll_adv_put_aux_ptr(AUX_CURRENT(advsm)->chan, advsm->sec_phy, offset, dptr); + *hdr_byte = pdu_type; + return BLE_LL_EXT_ADV_HDR_LEN + ext_hdr_len; } @@ -1407,9 +1425,16 @@ ble_ll_adv_aux_calculate_payload(struct ble_ll_adv_sm *advsm, uint16_t props, ext_hdr_len += BLE_LL_EXT_ADV_DATA_INFO_SIZE; } - /* AdvA in 1st PDU, except for anonymous */ + /* AdvA if: + * - 1st PDU + * - not anonymous + * - scannable/connectable or ADVA_IN_AUX selected + */ if (first_pdu && - !(props & BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV)) { + !(props & BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV) && + ((props & (BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE | + BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE)) || + MYNEWT_VAL(BLE_LL_EXT_ADV_ADVA_IN_AUX))) { ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_ADVA_BIT); ext_hdr_len += BLE_LL_EXT_ADV_ADVA_SIZE; } diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index e77a1de44b..fc9a93293b 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -618,6 +618,11 @@ syscfg.defs: like build optimisation, cache, clock speed etc. value: 0 + BLE_LL_EXT_ADV_ADVA_IN_AUX: + description: > + Put AdvA in AUX_ADV_IND instead of ADV_EXT_IND. + value: 1 + BLE_LL_STACK_SIZE: description: > This is the stack size for LL task. From 80056c481af33e68d1ee0755cc62168f26203a71 Mon Sep 17 00:00:00 2001 From: Mynewt Bot Date: Mon, 21 Oct 2024 15:05:14 +0000 Subject: [PATCH 1100/1333] porting: Update ports syscfg --- porting/npl/riot/include/syscfg/syscfg.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index c4e8383e44..c25160bf29 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1393,6 +1393,10 @@ #define MYNEWT_VAL_BLE_LL_EXT (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_EXT_ADV_ADVA_IN_AUX +#define MYNEWT_VAL_BLE_LL_EXT_ADV_ADVA_IN_AUX (1) +#endif + #ifndef MYNEWT_VAL_BLE_LL_EXT_ADV_AUX_PTR_CNT #define MYNEWT_VAL_BLE_LL_EXT_ADV_AUX_PTR_CNT (0) #endif From fd8d1b472f24625c644e8cf3e02ba389c833e7ae Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 17 Oct 2024 20:21:08 +0200 Subject: [PATCH 1101/1333] nimble/ll: Fix offset calculation in BIGInfo Offset calculation in BIGInfo assumes BIG event start time is always after AUX_SYNC_IND since BIG should be advanced to next event by the time AUX_SYNC_IND is sent. However, if AUX_SYNC_IND is scheduled close to BIG event this may not happend and thus calculated offset is invalid. This makes sure that we always use BIG event after AUX_SYNC_IND to calculate offset. --- nimble/controller/src/ble_ll_adv.c | 1 - nimble/controller/src/ble_ll_iso_big.c | 30 ++++++++++++++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 98ddfbfcc6..e474998ee4 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -2216,7 +2216,6 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) sync->sch.start_time + g_ble_ll_sched_offset_ticks, sync->sch.remainder); - BLE_LL_ASSERT(biginfo_len > 0); dptr += biginfo_len; } diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 5109a6b6b4..5aee5de123 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -307,20 +307,38 @@ ble_ll_iso_big_biginfo_copy(struct ble_ll_iso_big *big, uint8_t *dptr, uint32_t base_ticks, uint8_t base_rem_us) { uint8_t *dptr_start; + uint32_t event_start; + uint8_t event_start_us; uint64_t counter; uint32_t offset_us; uint32_t offset; - uint32_t d_ticks; - uint8_t d_rem_us; dptr_start = dptr; counter = big->bis_counter; - d_ticks = big->event_start - base_ticks; - d_rem_us = big->event_start_us; - ble_ll_tmr_sub(&d_ticks, &d_rem_us, base_rem_us); + event_start = big->event_start; + event_start_us = big->event_start_us; + + /* Use next BIG event in case current one is before AUX_SYNC_IND. This can + * happen if AUX_SYNC_IND is scheduled right after BIG event and the BIG + * was not yet advanced to next event. + */ + if (event_start <= base_ticks) { + ble_ll_tmr_add(&event_start, &event_start_us, big->iso_interval * 1250); + counter++; + } + + /* Drop BIGInfo if BIG event is still before AUX_SYNC_IND. This should not + * happen but better not send invalid offset. + */ + if (event_start <= base_ticks) { + return 0; + } + + offset_us = ble_ll_tmr_t2u(event_start - base_ticks); + offset_us += event_start_us; + offset_us -= base_rem_us; - offset_us = ble_ll_tmr_t2u(d_ticks) + d_rem_us; if (offset_us <= 600) { counter += big->bn; offset_us += big->iso_interval * 1250; From 37143bed9bff2395c60732ea1e5eeb4669eafa0f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 17 Oct 2024 20:40:51 +0200 Subject: [PATCH 1102/1333] nimble/ll: Simplify SyncInfo calculation This simplifies calculation of SyncInfo used in AUX_ADV_IND and LL_PERIODIC_SYNC_IND to use the same code in both cases. In case of LL Control PDU we do not "rewind" connsm to find proper connection event but instead "advance" padv event the same way as it was done for AUX_ADV_IND PDU. --- .../include/controller/ble_ll_conn.h | 9 +- nimble/controller/src/ble_ll_adv.c | 90 +++++++++---------- nimble/controller/src/ble_ll_conn.c | 20 +++-- nimble/controller/src/ble_ll_sync.c | 10 +-- 4 files changed, 67 insertions(+), 62 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 7d6af874dd..1d29063bf8 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -448,10 +448,15 @@ void ble_ll_conn_chan_map_update(void); /* required for unit testing */ uint8_t ble_ll_conn_calc_dci(struct ble_ll_conn_sm *conn, uint16_t latency); -/* used to get anchor point for connection event specified */ -void ble_ll_conn_get_anchor(struct ble_ll_conn_sm *connsm, uint16_t conn_event, +/* get current event counter and anchor point */ +void ble_ll_conn_anchor_get(struct ble_ll_conn_sm *connsm, uint16_t *event_cntr, uint32_t *anchor, uint8_t *anchor_usecs); +/* get anchor point for specified connection event */ +void ble_ll_conn_anchor_event_cntr_get(struct ble_ll_conn_sm *connsm, + uint16_t event_cntr, uint32_t *anchor, + uint8_t *anchor_usecs); + #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) int ble_ll_conn_move_anchor(struct ble_ll_conn_sm *connsm, uint16_t offset); #endif diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index e474998ee4..056df4f60d 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -643,83 +643,73 @@ ble_ll_adv_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) static void ble_ll_adv_put_syncinfo(struct ble_ll_adv_sm *advsm, - struct ble_ll_conn_sm *connsm, uint8_t *conn_event_cnt, + struct ble_ll_conn_sm *connsm, uint8_t *conn_event_cntr, uint8_t *dptr) { -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) - uint16_t conn_cnt; -#endif - unsigned int event_cnt_off = 0; - uint32_t offset = 0; - uint32_t itvl_us; + uint32_t offset_us; + uint32_t offset; uint32_t anchor_ticks; uint8_t anchor_rem_us; - uint8_t units; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) + uint16_t anchor_event_cntr; +#endif + uint32_t event_start; + uint8_t event_start_us; + uint32_t event_cntr_offset = 0; if (connsm) { #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) - anchor_ticks = connsm->anchor_point; - anchor_rem_us = connsm->anchor_point_usecs; - conn_cnt = connsm->event_cntr; - - /* get anchor for conn event that is before periodic_adv_event_start_time */ - while (LL_TMR_GT(anchor_ticks, advsm->padv_event_start)) { - ble_ll_conn_get_anchor(connsm, --conn_cnt, &anchor_ticks, &anchor_rem_us); - } - - offset = ble_ll_tmr_t2u(advsm->padv_event_start - anchor_ticks); - offset -= anchor_rem_us; - offset += advsm->padv_event_start_rem_us; + ble_ll_conn_anchor_get(connsm, &anchor_event_cntr, + &anchor_ticks, &anchor_rem_us); /* connEventCount */ - put_le16(conn_event_cnt, conn_cnt); + put_le16(conn_event_cntr, anchor_event_cntr); +#else + BLE_LL_ASSERT(0); #endif } else { - anchor_ticks = advsm->padv_event_start; - anchor_rem_us = advsm->padv_event_start_rem_us; - itvl_us = advsm->periodic_adv_itvl * BLE_LL_ADV_PERIODIC_ITVL; - - /* Get periodic event that is past AUX start time (so that we always - * provide valid offset if it is not too far in future). This can - * happen if advertising event is interleaved with periodic advertising - * event (when chaining). - */ - while (LL_TMR_GEQ(AUX_CURRENT(advsm)->start_time, anchor_ticks)) { - ble_ll_tmr_add(&anchor_ticks, &anchor_rem_us, itvl_us); - event_cnt_off++; - } + anchor_ticks = AUX_CURRENT(advsm)->start_time; + anchor_rem_us = 0; + } - /* We always schedule aux with 0 rem_us so no need to include it here */ - offset = ble_ll_tmr_t2u(anchor_ticks - AUX_CURRENT(advsm)->start_time); - offset += anchor_rem_us; + event_start = advsm->padv_event_start; + event_start_us = advsm->padv_event_start_rem_us; + + /* Find padv event that is past anchor item */ + while (LL_TMR_LEQ(event_start, anchor_ticks)) { + ble_ll_tmr_add(&event_start, &event_start_us, advsm->padv_itvl_us); + event_cntr_offset++; } + offset_us = ble_ll_tmr_t2u(event_start - anchor_ticks); + offset_us += event_start_us; + offset_us -= anchor_rem_us; + /* Sync Packet Offset (13 bits), Offset Units (1 bit), Offset Adjust (1 bit), * RFU (1 bit) */ - if (offset > 245700) { - units = 0x20; - offset = offset / 300; - + if (offset_us > 245700) { + offset = offset_us / 300; if (offset >= 0x2000) { if (connsm) { offset -= 0x2000; - units |= 0x40; + /* Offset Units = 1, Offset Adjust = 1 */ + offset |= 0x6000; } else { - /* not able to represent time in offset */ offset = 0; - units = 0x00; - event_cnt_off = 0; + event_cntr_offset = 0; } + } else { + /* Offset Units = 1, Offset Adjust = 0 */ + offset |= 0x2000; } } else { - units = 0x00; - offset = offset / 30; + offset = offset_us / 30; + /* Offset Units = 0, Offset Adjust = 0 */ } - dptr[0] = (offset & 0x000000ff); - dptr[1] = ((offset >> 8) & 0x0000001f) | units; + put_le16(&dptr[0], offset); /* Interval (2 bytes) */ put_le16(&dptr[2], advsm->periodic_adv_itvl); @@ -743,7 +733,7 @@ ble_ll_adv_put_syncinfo(struct ble_ll_adv_sm *advsm, dptr[15] = (uint8_t)(advsm->periodic_crcinit >> 16); /* Event Counter (2 bytes) */ - put_le16(&dptr[16], advsm->periodic_event_cntr + event_cnt_off); + put_le16(&dptr[16], advsm->periodic_event_cntr + event_cntr_offset); } #endif diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index cee6f976b2..789b948aad 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2275,10 +2275,20 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err) connsm->event_cntr, (uint32_t)ble_err); } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) void -ble_ll_conn_get_anchor(struct ble_ll_conn_sm *connsm, uint16_t conn_event, +ble_ll_conn_anchor_get(struct ble_ll_conn_sm *connsm, uint16_t *event_cntr, uint32_t *anchor, uint8_t *anchor_usecs) +{ + *event_cntr = connsm->event_cntr; + *anchor = connsm->anchor_point; + *anchor_usecs = connsm->anchor_point_usecs; +} + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) +void +ble_ll_conn_anchor_event_cntr_get(struct ble_ll_conn_sm *connsm, + uint16_t event_cntr, uint32_t *anchor, + uint8_t *anchor_usecs) { uint32_t itvl; @@ -2287,11 +2297,11 @@ ble_ll_conn_get_anchor(struct ble_ll_conn_sm *connsm, uint16_t conn_event, *anchor = connsm->anchor_point; *anchor_usecs = connsm->anchor_point_usecs; - if ((int16_t)(conn_event - connsm->event_cntr) < 0) { - itvl *= connsm->event_cntr - conn_event; + if ((int16_t)(event_cntr - connsm->event_cntr) < 0) { + itvl *= connsm->event_cntr - event_cntr; ble_ll_tmr_sub(anchor, anchor_usecs, itvl); } else { - itvl *= conn_event - connsm->event_cntr; + itvl *= event_cntr - connsm->event_cntr; ble_ll_tmr_add(anchor, anchor_usecs, itvl); } } diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index d15f1df007..846ca73a71 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -2094,8 +2094,8 @@ ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, /* get anchor for specified conn event */ conn_event_count = get_le16(sync_ind + 20); - ble_ll_conn_get_anchor(connsm, conn_event_count, &sm->anchor_point, - &sm->anchor_point_usecs); + ble_ll_conn_anchor_event_cntr_get(connsm, conn_event_count, &sm->anchor_point, + &sm->anchor_point_usecs); /* Set last anchor point */ sm->last_anchor_point = sm->anchor_point - (last_pa_diff * sm->itvl_ticks); @@ -2103,8 +2103,8 @@ ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, /* calculate extra window widening */ sync_conn_event_count = get_le16(sync_ind + 32); sca = sync_ind[24] >> 5; - ble_ll_conn_get_anchor(connsm, sync_conn_event_count, &sync_anchor, - &sync_anchor_usecs); + ble_ll_conn_anchor_event_cntr_get(connsm, sync_conn_event_count, &sync_anchor, + &sync_anchor_usecs); ww_adjust = ble_ll_utils_calc_window_widening(connsm->anchor_point, sync_anchor, sca); @@ -2155,7 +2155,7 @@ ble_ll_sync_put_syncinfo(struct ble_ll_sync_sm *syncsm, /* get anchor for conn event that is before periodic_adv_event_start_time */ while (LL_TMR_GT(anchor, syncsm->anchor_point)) { - ble_ll_conn_get_anchor(connsm, --conn_cnt, &anchor, &anchor_usecs); + ble_ll_conn_anchor_event_cntr_get(connsm, --conn_cnt, &anchor, &anchor_usecs); } offset = ble_ll_tmr_t2u(syncsm->anchor_point - anchor); From 80d95d0d0b19b4b6b26c0edcd53ad04f43328eb7 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 9 Aug 2024 15:44:16 +0200 Subject: [PATCH 1103/1333] nimble/audio/bass: Modify add source operation in BASS Fix memcpy wrong field format from address. Move check_bis_sync up, so add source can use it. Add checks for address type. Add checks for advertising sid. Add pa_sync_state and num of subgroups to receive state. --- .../services/bass/ble_audio_svc_bass.h | 3 + .../services/bass/src/ble_audio_svc_bass.c | 66 ++++++++++++------- 2 files changed, 46 insertions(+), 23 deletions(-) diff --git a/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h b/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h index 431ecb968c..155df24a52 100644 --- a/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h +++ b/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h @@ -71,6 +71,9 @@ /** BLE AUDIO BASS Error: Invalid Source ID */ #define BLE_SVC_AUDIO_BASS_ERR_INVALID_SOURCE_ID 0x81 +/** BLE AUDIO BASS ADVERTISING SID MAX VALUE */ +#define BLE_SVC_AUDIO_BASS_ADV_SID_MAX_VAL 0x0F + /** BLE AUDIO BASS Encryption States */ enum ble_svc_audio_bass_big_enc { /** BLE AUDIO BASS BIG Encryption: Not Encrypted */ diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index 451b766ddc..c18a276b3c 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -282,6 +282,28 @@ ble_svc_audio_bass_remote_scan_started(uint8_t *data, uint16_t data_len, uint16_ return 0; } +static int +check_bis_sync(uint16_t num_subgroups, const uint32_t *bis_sync_list) +{ + uint32_t bis_sync_mask = 0; + int i; + int j; + + for (i = 0; i < num_subgroups; i++) { + if (bis_sync_list[i] != 0xFFFFFFFF) { + for (j = 0; j < num_subgroups; j++) { + if (bis_sync_list[i] & bis_sync_mask) { + return BLE_HS_EINVAL; + } + + bis_sync_mask |= bis_sync_list[i]; + } + } + } + + return 0; +} + static int ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle) { @@ -307,9 +329,21 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha operation.conn_handle = conn_handle; operation.add_source.adv_addr.type = data[offset++]; + if (operation.add_source.adv_addr.type != BLE_ADDR_PUBLIC || + operation.add_source.adv_addr.type != BLE_ADDR_RANDOM) { + rc = BLE_HS_EINVAL; + ev.bass_operation_status.status = BLE_HS_EINVAL; + goto done; + } memcpy(operation.add_source.adv_addr.val, &data[offset], 6); offset += 6; operation.add_source.adv_sid = data[offset++]; + if (operation.add_source.adv_sid > BLE_SVC_AUDIO_BASS_ADV_SID_MAX_VAL) { + rc = BLE_HS_EINVAL; + ev.bass_operation_status.status = BLE_HS_EINVAL; + goto done; + } + operation.add_source.broadcast_id = get_le24(&data[offset]); offset += 3; operation.add_source.pa_sync = data[offset++]; @@ -346,6 +380,13 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha operation.add_source.subgroups[i].metadata = &data[offset]; offset += operation.add_source.subgroups[i].metadata_length; data_len -= operation.add_source.subgroups[i].metadata_length; + + if (check_bis_sync(operation.add_source.num_subgroups, + operation.add_source.bis_sync)) { + rc = BLE_HS_EINVAL; + ev.bass_operation_status.status = BLE_HS_EREJECT; + goto done; + } } source_id_new = ble_svc_audio_bass_get_new_source_id(); @@ -393,9 +434,10 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha ev.bass_operation_status.source_id = rcv_state->source_id; rcv_state->state.source_addr.type = operation.add_source.adv_addr.type; - memcpy(&rcv_state->state.source_addr.type, operation.add_source.adv_addr.val, 6); + memcpy(&rcv_state->state.source_addr.val, operation.add_source.adv_addr.val, 6); rcv_state->state.source_adv_sid = operation.add_source.adv_sid; rcv_state->state.broadcast_id = operation.add_source.broadcast_id; + rcv_state->state.num_subgroups = operation.add_source.num_subgroups; for (i = 0; i < operation.add_source.num_subgroups; i++) { metadata_ptr = os_memblock_get(&ble_audio_svc_bass_metadata_pool); @@ -423,28 +465,6 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha return rc; } -static int -check_bis_sync(uint16_t num_subgroups, const uint32_t *bis_sync_list) -{ - uint32_t bis_sync_mask = 0; - int i; - int j; - - for (i = 0; i < num_subgroups; i++) { - if (bis_sync_list[i] != 0xFFFFFFFF) { - for (j = 0; j < num_subgroups; j++) { - if (bis_sync_list[i] & bis_sync_mask) { - return BLE_HS_EINVAL; - } - - bis_sync_mask |= bis_sync_list[i]; - } - } - } - - return 0; -} - static int ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle) { From aafa677d835078cd1064452dd3916c394fcb320b Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 8 Aug 2024 16:52:27 +0200 Subject: [PATCH 1104/1333] nimble/audio/bass: BASS modify source update Handling for proper receive state fields is added. Fix a never-ending goto statement returning to goto itself. Fixed offset "jump" from two-bytes to one-byte. --- .../services/bass/ble_audio_svc_bass.h | 3 +++ .../services/bass/src/ble_audio_svc_bass.c | 24 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h b/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h index 155df24a52..48f1a53232 100644 --- a/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h +++ b/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h @@ -329,6 +329,9 @@ struct ble_svc_audio_bass_operation { /** BIS Synchronisation of subgroups */ uint32_t bis_sync[BLE_SVC_AUDIO_BASS_SUB_NUM_MAX]; + /** Subgroup entries */ + struct ble_svc_audio_bass_subgroup + subgroups[BLE_SVC_AUDIO_BASS_SUB_NUM_MAX]; } modify_source; /** diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index c18a276b3c..cc4805f951 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -477,6 +477,7 @@ ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn .status = 0 } }; + uint8_t *metadata_ptr; uint8_t offset = 0; int rc = 0; int i; @@ -518,6 +519,16 @@ ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn for (i = 0; i < operation.modify_source.num_subgroups; i++) { operation.modify_source.bis_sync[i] = get_le32(&data[offset]); offset += 4; + operation.modify_source.subgroups[i].metadata_length = data[offset++]; + data_len -= 5; + if (data_len < operation.modify_source.subgroups[i].metadata_length) { + rc = BLE_ATT_ERR_WRITE_REQ_REJECTED; + ev.bass_operation_status.status = BLE_HS_ERJECT; + goto done; + } + operation.modify_source.subgroups[i].metadata = &data[offset]; + offset += operation_modify_source.subgroups[i].metadata_length; + data_len -= operation.modify_source.subgroups[i].metadata_length; } if (check_bis_sync(operation.modify_source.num_subgroups, @@ -527,6 +538,18 @@ ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn goto done; } + for (i = 0; i < operation.modify_source.num_subgroups; i++) { + metadata_ptr = os_memblock_get(&ble_audio_svc_bass_metadata_pool); + if (metadata_ptr == NULL) { + rc = BLE_HS_ENOMEM; + ev.bass_operation_status.status = BLE_HS_ENOMEM; + goto done; + } + memcpy(metadata_ptr, operation.modify_source.subgroups[i].metadata, + min(operation.modify_source.subgroups[i].metadata_length, + MYNEWT_VAL(BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ))); + } + if (accept_fn.ctrl_point_ev_fn) { rc = accept_fn.ctrl_point_ev_fn(&operation, accept_fn.arg); if (rc != 0) { @@ -542,7 +565,6 @@ ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn if (!rc) { rc = ble_svc_audio_bass_receive_state_notify(rcv_state); ev.bass_operation_status.status = rc; - goto done; } ble_audio_event_listener_call(&ev); From 77902be94314fb6de8707de40083a3087feb8e77 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Mon, 16 Sep 2024 12:32:50 +0200 Subject: [PATCH 1105/1333] nimble/ll: Refactor DID update Now we can universally update DID with the same function, also for periodic advertising. --- nimble/controller/src/ble_ll_adv.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 056df4f60d..b50422517c 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -1931,10 +1931,10 @@ ble_ll_adv_set_adv_params(const uint8_t *cmdbuf, uint8_t len) } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) -static void -ble_ll_adv_update_did(struct ble_ll_adv_sm *advsm) +static uint16_t +ble_ll_adv_update_did(uint16_t old_adi) { - uint16_t old_adi = advsm->adi; + uint16_t new_adi; /* * The Advertising DID for a given advertising set shall be initialized @@ -1945,8 +1945,10 @@ ble_ll_adv_update_did(struct ble_ll_adv_sm *advsm) * the previously used value. */ do { - advsm->adi = (advsm->adi & 0xf000) | (ble_ll_rand() & 0x0fff); - } while (old_adi == advsm->adi); + new_adi = (old_adi & 0xf000) | (ble_ll_rand() & 0x0fff); + } while (old_adi == new_adi); + + return new_adi; } #endif @@ -1980,7 +1982,7 @@ ble_ll_adv_update_adv_scan_rsp_data(struct ble_ll_adv_sm *advsm) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) /* DID shall be updated when host provides new advertising data */ - ble_ll_adv_update_did(advsm); + advsm->adi = ble_ll_adv_update_did(advsm->adi); #endif } @@ -2675,7 +2677,7 @@ ble_ll_adv_sm_start_periodic(struct ble_ll_adv_sm *advsm) * advertisers should update the Advertising DID when a periodic advertising * train is enabled. */ - ble_ll_adv_update_did(advsm); + advsm->adi = ble_ll_adv_update_did(advsm->adi); advsm->periodic_adv_active = 1; @@ -2718,7 +2720,7 @@ ble_ll_adv_sm_stop_periodic(struct ble_ll_adv_sm *advsm) * advertisers should update the Advertising DID when a periodic advertising * train is disabled. */ - ble_ll_adv_update_did(advsm); + advsm->adi = ble_ll_adv_update_did(advsm->adi); /* Remove any scheduled advertising items */ advsm->periodic_adv_active = 0; @@ -3140,7 +3142,7 @@ ble_ll_adv_set_scan_rsp_data(const uint8_t *data, uint8_t datalen, } /* DID shall be updated when host provides new scan response data */ - ble_ll_adv_update_did(advsm); + advsm->adi = ble_ll_adv_update_did(advsm->adi); #endif } @@ -3215,7 +3217,7 @@ ble_ll_adv_set_adv_data(const uint8_t *data, uint8_t datalen, uint8_t instance, } /* update DID only */ - ble_ll_adv_update_did(advsm); + advsm->adi = ble_ll_adv_update_did(advsm->adi); return BLE_ERR_SUCCESS; case BLE_HCI_LE_SET_DATA_OPER_LAST: ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_ADV_DATA_INCOMPLETE); @@ -3303,7 +3305,7 @@ ble_ll_adv_set_adv_data(const uint8_t *data, uint8_t datalen, uint8_t instance, } /* DID shall be updated when host provides new advertising data */ - ble_ll_adv_update_did(advsm); + advsm->adi = ble_ll_adv_update_did(advsm->adi); #endif } From dae0e40cffe96bbb2085c3364ea5d796a0b4c1ed Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Mon, 16 Sep 2024 12:39:38 +0200 Subject: [PATCH 1106/1333] nimble/ll: Add PA ADI support This adds ADI support for Periodic Advertising in controller. --- .../include/controller/ble_ll_sync.h | 2 +- nimble/controller/src/ble_ll.c | 4 ++ nimble/controller/src/ble_ll_adv.c | 64 +++++++++++++++++-- nimble/controller/src/ble_ll_conn_hci.c | 34 +++++++--- nimble/controller/src/ble_ll_ctrl.c | 8 +-- nimble/controller/src/ble_ll_sync.c | 60 ++++++++++++++--- nimble/controller/syscfg.yml | 11 +++- 7 files changed, 153 insertions(+), 30 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_sync.h b/nimble/controller/include/controller/ble_ll_sync.h index b4f9e944d2..5d7ef7a864 100644 --- a/nimble/controller/include/controller/ble_ll_sync.h +++ b/nimble/controller/include/controller/ble_ll_sync.h @@ -45,7 +45,7 @@ int ble_ll_sync_transfer(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); void ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, - const uint8_t *sync_ind, bool reports_disabled, + const uint8_t *sync_ind, uint8_t mode, uint16_t max_skip, uint32_t sync_timeout); void ble_ll_sync_transfer_disconnected(struct ble_ll_conn_sm *connsm); diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 7e87891ab5..f2fc37d6d1 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1935,6 +1935,10 @@ ble_ll_init(void) features |= BLE_LL_FEAT_CS_PCT_QUALITY_IND; #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT) + features |= BLE_LL_FEAT_PERIODIC_ADV_ADI; +#endif + lldata->ll_supp_features = features; /* Initialize random number generation */ diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index b50422517c..1e56a8d454 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -167,6 +167,10 @@ struct ble_ll_adv_sm uint8_t periodic_adv_active : 1; uint8_t periodic_sync_active : 1; uint8_t periodic_sync_index : 1; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT) + uint8_t periodic_include_adi : 1; + uint16_t periodic_adv_adi; +#endif uint8_t periodic_num_used_chans; uint8_t periodic_chanmap[BLE_LL_CHAN_MAP_LEN]; uint16_t periodic_adv_itvl; @@ -2175,6 +2179,12 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte) dptr += 1; } #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT) + if (sync->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) { + put_le16(dptr, advsm->periodic_adv_adi); + dptr += BLE_LL_EXT_ADV_DATA_INFO_SIZE; + } +#endif if (sync->ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { if (!SYNC_NEXT(advsm)->sch.enqueued) { @@ -2356,6 +2366,13 @@ ble_ll_adv_sync_calculate(struct ble_ll_adv_sm *advsm, ext_hdr_len = BLE_LL_EXT_ADV_HDR_LEN; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT) + if (advsm->periodic_include_adi) { + sync->ext_hdr_flags |= (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT); + ext_hdr_len += BLE_LL_EXT_ADV_DATA_INFO_SIZE; + } +#endif + /* TxPower if configured * Note: TxPower shall not be present in chain PDU for SYNC */ @@ -2613,6 +2630,9 @@ ble_ll_adv_update_periodic_data(struct ble_ll_adv_sm *advsm) os_mbuf_free_chain(advsm->periodic_adv_data); advsm->periodic_adv_data = advsm->periodic_new_data; advsm->periodic_new_data = NULL; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT) + advsm->periodic_adv_adi = ble_ll_adv_update_did(advsm->periodic_adv_adi); +#endif } ble_ll_adv_flags_clear(advsm, BLE_LL_ADV_SM_FLAG_PERIODIC_NEW_DATA); @@ -2679,6 +2699,14 @@ ble_ll_adv_sm_start_periodic(struct ble_ll_adv_sm *advsm) */ advsm->adi = ble_ll_adv_update_did(advsm->adi); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT) + /* + * Since periodic advertising can be started without data we initialize DID here + * instead of after setting periodic advertising data. + */ + advsm->periodic_adv_adi = ble_ll_adv_update_did(advsm->periodic_adv_adi); +#endif + advsm->periodic_adv_active = 1; /* keep channel map since we cannot change it later on */ @@ -3636,6 +3664,9 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, advsm->sec_phy = cmd->sec_phy; /* Update SID only */ advsm->adi = (advsm->adi & 0x0fff) | ((cmd->sid << 12)); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT) + advsm->periodic_adv_adi = (advsm->periodic_adv_adi & 0x0fff) | ((cmd->sid << 12)); +#endif advsm->props = props; @@ -4141,6 +4172,23 @@ ble_ll_adv_periodic_set_data(const uint8_t *cmdbuf, uint8_t len) case BLE_HCI_LE_SET_DATA_OPER_COMPLETE: new_data = true; break; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT) + case BLE_HCI_LE_SET_DATA_OPER_UNCHANGED: + if (!advsm->periodic_adv_enabled) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (advsm->periodic_adv_data->om_len == 0) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (cmd->adv_data_len != 0) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + advsm->periodic_adv_adi = ble_ll_adv_update_did(advsm->periodic_adv_adi); + return BLE_ERR_SUCCESS; +#endif default: return BLE_ERR_INV_HCI_CMD_PARMS; } @@ -4217,10 +4265,14 @@ ble_ll_adv_periodic_enable(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_UNK_ADV_INDENT; } -#if MYNEWT_VAL(BLE_VERSION) >= 53 +#if !MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT) if (cmd->enable & 0x02) { return BLE_ERR_UNSUPPORTED; - } else if (cmd->enable & 0xfc) { + } +#endif + +#if MYNEWT_VAL(BLE_VERSION) >= 53 + if (cmd->enable & 0xfc) { return BLE_ERR_INV_HCI_CMD_PARMS; } #else @@ -4229,7 +4281,7 @@ ble_ll_adv_periodic_enable(const uint8_t *cmdbuf, uint8_t len) } #endif - if (cmd->enable) { + if (cmd->enable & 0x1) { if (advsm->props & (BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV | BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE | BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE | @@ -4247,7 +4299,7 @@ ble_ll_adv_periodic_enable(const uint8_t *cmdbuf, uint8_t len) /* If Enable is set to 0x01 and the length of the periodic advertising * data is greater than the maximum that the Controller can transmit - * within the chosen periodicadvertising interval, the Controller shall + * within the chosen periodic advertising interval, the Controller shall * return the error code Packet Too Long (0x45). */ if (!ble_ll_adv_periodic_check_data_itvl(SYNC_DATA_LEN(advsm), @@ -4257,6 +4309,10 @@ ble_ll_adv_periodic_enable(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_PACKET_TOO_LONG; } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT) + advsm->periodic_include_adi = !!(cmd->enable & 0x2); +#endif + /* If the advertising set is not currently enabled (see the * LE_Set_Extended_Advertising_Enable command), the periodic advertising * is not started until the advertising set is enabled. diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index dd32da565f..e1b2689b79 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -2069,11 +2069,18 @@ ble_ll_set_sync_transfer_params(const uint8_t *cmdbuf, uint8_t len, goto done; } - if ((MYNEWT_VAL(BLE_VERSION) >= 53 ) && (cmd->mode == 0x03)) { - /* We do not support ADI in periodic advertising thus cannot enable - * duplicate filtering. - */ - return BLE_ERR_UNSUPPORTED; + if (MYNEWT_VAL(BLE_VERSION) >= 53) { + if (cmd->mode > 0x03) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if ((cmd->mode == 0x03) && + !MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT)) { + /* We do not support ADI in periodic advertising thus cannot enable + * duplicate filtering. + */ + return BLE_ERR_UNSUPPORTED; + } } else if (cmd->mode > 0x02) { return BLE_ERR_INV_HCI_CMD_PARMS; } @@ -2126,11 +2133,18 @@ ble_ll_set_default_sync_transfer_params(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } - if ((MYNEWT_VAL(BLE_VERSION) >= 53 ) && (cmd->mode == 0x03)) { - /* We do not support ADI in periodic advertising thus cannot enable - * duplicate filtering. - */ - return BLE_ERR_UNSUPPORTED; + if (MYNEWT_VAL(BLE_VERSION) >= 53) { + if (cmd->mode > 0x03) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if ((cmd->mode == 0x03) && + !MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT)) { + /* We do not support ADI in periodic advertising thus cannot enable + * duplicate filtering. + */ + return BLE_ERR_UNSUPPORTED; + } } else if (cmd->mode > 0x02) { return BLE_ERR_INV_HCI_CMD_PARMS; } diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index da12a5f313..6902ba4958 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1135,11 +1135,9 @@ ble_ll_ctrl_rx_phy_update_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr) static uint8_t ble_ll_ctrl_rx_periodic_sync_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr) { - if (connsm->sync_transfer_mode) { - ble_ll_sync_periodic_ind(connsm, dptr, connsm->sync_transfer_mode == 1, - connsm->sync_transfer_skip, - connsm->sync_transfer_sync_timeout); - } + ble_ll_sync_periodic_ind(connsm, dptr, connsm->sync_transfer_mode, + connsm->sync_transfer_skip, + connsm->sync_transfer_sync_timeout); return BLE_ERR_MAX; } #endif diff --git a/nimble/controller/src/ble_ll_sync.c b/nimble/controller/src/ble_ll_sync.c index 846ca73a71..f1a709fb9e 100644 --- a/nimble/controller/src/ble_ll_sync.c +++ b/nimble/controller/src/ble_ll_sync.c @@ -64,6 +64,7 @@ #define BLE_LL_SYNC_SM_FLAG_HCI_TRUNCATED 0x0100 #define BLE_LL_SYNC_SM_FLAG_NEW_CHANMAP 0x0200 #define BLE_LL_SYNC_SM_FLAG_CHAIN 0x0400 +#define BLE_LL_SYNC_SM_FLAG_DUPLICATES 0x0800 #define BLE_LL_SYNC_ITVL_USECS 1250 @@ -121,6 +122,10 @@ struct ble_ll_sync_sm { uint16_t event_cntr_last_received; uint8_t adv_addr_rpa[6]; #endif + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT) + uint16_t prev_adi; +#endif }; static struct ble_ll_sync_sm g_ble_ll_sync_sm[BLE_LL_SYNC_CNT]; @@ -548,7 +553,7 @@ ble_ll_sync_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *rxhdr) static int ble_ll_sync_parse_ext_hdr(struct os_mbuf *om, uint8_t **aux, int8_t *tx_power, - uint8_t **acad, uint8_t *acad_len) + uint8_t **acad, uint8_t *acad_len, uint16_t **adi) { uint8_t *rxbuf = om->om_data; uint8_t ext_hdr_flags; @@ -587,8 +592,10 @@ ble_ll_sync_parse_ext_hdr(struct os_mbuf *om, uint8_t **aux, int8_t *tx_power, i += BLE_LL_EXT_ADV_CTE_INFO_SIZE; } - /* there should be no ADI in Sync or chain, skip it */ if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) { + if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT) { + *adi = (uint16_t *) ext_hdr + i; + } i += BLE_LL_EXT_ADV_DATA_INFO_SIZE; } @@ -1137,10 +1144,12 @@ ble_ll_sync_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) uint8_t *aux = NULL; uint8_t *acad = NULL; uint8_t acad_len = 0; + uint16_t *adi = NULL; const uint8_t *biginfo = NULL; uint8_t biginfo_len = 0; int datalen; bool reports_enabled; + bool is_duplicate = false; BLE_LL_ASSERT(sm); @@ -1186,14 +1195,22 @@ ble_ll_sync_rx_pkt_in(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) } /* get ext header data */ - datalen = ble_ll_sync_parse_ext_hdr(rxpdu, &aux, &tx_power, &acad, &acad_len); + datalen = ble_ll_sync_parse_ext_hdr(rxpdu, &aux, &tx_power, &acad, &acad_len, &adi); if (datalen < 0) { /* we got bad packet, end event */ goto end_event; } +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT) + if (adi != NULL) { + is_duplicate = (sm->flags & BLE_LL_SYNC_SM_FLAG_DUPLICATES) && (*adi == sm->prev_adi); + sm->prev_adi = *adi; + } +#endif + reports_enabled = ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT) && - !(sm->flags & BLE_LL_SYNC_SM_FLAG_DISABLED); + !(sm->flags & BLE_LL_SYNC_SM_FLAG_DISABLED) && + !is_duplicate; /* no need to schedule for chain if reporting is disabled */ if (reports_enabled) { @@ -1539,6 +1556,12 @@ ble_ll_sync_info_event(struct ble_ll_scan_addr_data *addrd, } #endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT) + if (g_ble_ll_sync_create_params.options & BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_DUPLICATES) { + sm->flags |= BLE_LL_SYNC_SM_FLAG_DUPLICATES; + } +#endif + sm->flags &= ~BLE_LL_SYNC_SM_FLAG_RESERVED; sm->flags |= BLE_LL_SYNC_SM_FLAG_ESTABLISHING; sm->flags |= BLE_LL_SYNC_SM_FLAG_SYNC_INFO; @@ -1583,7 +1606,8 @@ ble_ll_sync_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } if (!(cmd->options & BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_DISABLED) && - (cmd->options & BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_DUPLICATES)) { + (cmd->options & BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_DUPLICATES) && + !MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT)) { /* We do not support ADI in periodic advertising thus cannot enable * duplicate filtering. */ @@ -1870,7 +1894,8 @@ ble_ll_sync_receive_enable(const uint8_t *cmdbuf, uint8_t len) if (MYNEWT_VAL(BLE_VERSION) >= 53) { if (cmd->enable > 0x03) { return BLE_ERR_INV_HCI_CMD_PARMS; - } else if (cmd->enable == 0x03) { + } else if ((cmd->enable == 0x03) && + !MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT)) { /* We do not support ADI in periodic advertising thus cannot enable * duplicate filtering. */ @@ -1898,8 +1923,14 @@ ble_ll_sync_receive_enable(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_UNK_ADV_INDENT; } - if (cmd->enable) { + if (cmd->enable & 0x1) { sm->flags &= ~BLE_LL_SYNC_SM_FLAG_DISABLED; + + if (cmd->enable & 0x2) { + sm->flags |= BLE_LL_SYNC_SM_FLAG_DUPLICATES; + } else { + sm->flags &= ~BLE_LL_SYNC_SM_FLAG_DUPLICATES; + } } else { sm->flags |= BLE_LL_SYNC_SM_FLAG_DISABLED; } @@ -1940,7 +1971,7 @@ ble_ll_sync_transfer_get(const uint8_t *addr, uint8_t addr_type, uint8_t sid) void ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, - const uint8_t *sync_ind, bool reports_disabled, + const uint8_t *sync_ind, uint8_t mode, uint16_t max_skip, uint32_t sync_timeout) { const uint8_t *syncinfo = sync_ind + 2; @@ -1966,6 +1997,10 @@ ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, uint8_t sca; os_sr_t sr; + if (!mode) { + return; + } + phy_mode = ble_ll_ctrl_phy_from_phy_mask(sync_ind[25]); itvl = get_le16(syncinfo + 2); /* ignore if sync params are not valid */ @@ -2133,8 +2168,15 @@ ble_ll_sync_periodic_ind(struct ble_ll_conn_sm *connsm, sm->anchor_point = sm->sch.start_time + g_ble_ll_sched_offset_ticks; sm->anchor_point_usecs = sm->sch.remainder; - if (reports_disabled) { + switch (mode) { + case 0x1: sm->flags |= BLE_LL_SYNC_SM_FLAG_DISABLED; + break; + case 0x3: + sm->flags |= BLE_LL_SYNC_SM_FLAG_DUPLICATES; + break; + default: + break; } } diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index fc9a93293b..862a36a523 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -319,10 +319,19 @@ syscfg.defs: BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER: description: > - This option is use to enable/disable support for Periodic + This option is used to enable/disable support for Periodic Advertising Sync Transfer Feature. value: MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) + BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT: + description: > + This option is used to enable/disable support for Periodic + Advertising ADI. + value: 0 + restrictions: + - '(BLE_VERSION >= 53) if 1' + - '(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV == 1)' + BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL: description: > Enable controller-to-host flow control support. This allows host to From b0c3e4a085f1a2ed1b4439c04eec423cc7f79661 Mon Sep 17 00:00:00 2001 From: Mynewt Bot Date: Thu, 24 Oct 2024 10:03:05 +0000 Subject: [PATCH 1107/1333] porting: Update ports syscfg --- porting/npl/riot/include/syscfg/syscfg.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index c25160bf29..4ec768e8ae 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1277,6 +1277,10 @@ #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_ADI_SUPPORT (0) +#endif + #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_CNT #define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_CNT (0) #endif From 1fa9dfd3c02602748b3b0e7edf05aeec2f24a92b Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Mon, 23 Sep 2024 14:29:45 +0200 Subject: [PATCH 1108/1333] nimble/audio: Add subgroups information for modify operation This commit adds subgroups info for modify source operation. Now metadata field can be handled in scan delegator during modify procedure. --- .../services/bass/ble_audio_svc_bass.h | 2 - .../services/bass/src/ble_audio_svc_bass.c | 49 +++++++++---------- .../host/audio/src/ble_audio_scan_delegator.c | 5 +- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h b/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h index 48f1a53232..873ac7ae62 100644 --- a/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h +++ b/nimble/host/audio/services/bass/include/services/bass/ble_audio_svc_bass.h @@ -327,8 +327,6 @@ struct ble_svc_audio_bass_operation { /** Number of subgroups */ uint16_t num_subgroups; - /** BIS Synchronisation of subgroups */ - uint32_t bis_sync[BLE_SVC_AUDIO_BASS_SUB_NUM_MAX]; /** Subgroup entries */ struct ble_svc_audio_bass_subgroup subgroups[BLE_SVC_AUDIO_BASS_SUB_NUM_MAX]; diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index cc4805f951..e3cecb060e 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -282,28 +282,6 @@ ble_svc_audio_bass_remote_scan_started(uint8_t *data, uint16_t data_len, uint16_ return 0; } -static int -check_bis_sync(uint16_t num_subgroups, const uint32_t *bis_sync_list) -{ - uint32_t bis_sync_mask = 0; - int i; - int j; - - for (i = 0; i < num_subgroups; i++) { - if (bis_sync_list[i] != 0xFFFFFFFF) { - for (j = 0; j < num_subgroups; j++) { - if (bis_sync_list[i] & bis_sync_mask) { - return BLE_HS_EINVAL; - } - - bis_sync_mask |= bis_sync_list[i]; - } - } - } - - return 0; -} - static int ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle) { @@ -382,7 +360,7 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha data_len -= operation.add_source.subgroups[i].metadata_length; if (check_bis_sync(operation.add_source.num_subgroups, - operation.add_source.bis_sync)) { + operation.add_source.subgroups)) { rc = BLE_HS_EINVAL; ev.bass_operation_status.status = BLE_HS_EREJECT; goto done; @@ -466,6 +444,27 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha } static int +check_bis_sync(uint16_t num_subgroups, struct ble_svc_audio_bass_subgroup *subgroups) +{ + uint32_t bis_sync_mask = 0; + int i; + int j; + + for (i = 0; i < num_subgroups; i++) { + if (subgroups[i].bis_sync != 0xFFFFFFFF) { + for (j = 0; j < num_subgroups; j++) { + if (subgroups[i].bis_sync & bis_sync_mask) { + return BLE_HS_EINVAL; + } + + bis_sync_mask |= subgroups[i].bis_sync; + } + } + } + + return 0; +} + ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle) { struct ble_svc_audio_bass_operation operation; @@ -517,7 +516,7 @@ ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn } for (i = 0; i < operation.modify_source.num_subgroups; i++) { - operation.modify_source.bis_sync[i] = get_le32(&data[offset]); + operation.modify_source.subgroups.bis_sync[i] = get_le32(&data[offset]); offset += 4; operation.modify_source.subgroups[i].metadata_length = data[offset++]; data_len -= 5; @@ -532,7 +531,7 @@ ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn } if (check_bis_sync(operation.modify_source.num_subgroups, - operation.modify_source.bis_sync)) { + operation.modify_source.subgroups)) { rc = BLE_HS_EINVAL; ev.bass_operation_status.status = BLE_HS_EREJECT; goto done; diff --git a/nimble/host/audio/src/ble_audio_scan_delegator.c b/nimble/host/audio/src/ble_audio_scan_delegator.c index 60e04adc36..08a5ac645d 100644 --- a/nimble/host/audio/src/ble_audio_scan_delegator.c +++ b/nimble/host/audio/src/ble_audio_scan_delegator.c @@ -197,8 +197,9 @@ bass_modify_source_op_handler(struct ble_svc_audio_bass_operation *op, void *arg BLE_AUDIO_DBG_ASSERT(sync_opt->num_subgroups < ARRAY_SIZE(sync_opt->subgroups)); for (uint8_t i = 0; i < sync_opt->num_subgroups; i++) { - sync_opt->subgroups[i].bis_sync = op->modify_source.bis_sync[i]; - /* FIXME: Missing metadata in Modify Source */ + sync_opt->subgroups[i].bis_sync = op->modify_source.subgroups[i].bis_sync_state; + sync_opt->subgroups[i].metadata_length = op->modify_source.subgroups[i].metadata_length; + sync_opt->subgroups[i].metadata = op->modify_source.subgroups[i].metadata; } action.type = BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_MODIFY; From 027a56d46ed88f63482394cf8d1b8862a29e4a06 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Wed, 25 Sep 2024 13:56:09 +0200 Subject: [PATCH 1109/1333] nimble/host: move att_truncate_to_mtu to ble_att_svr_tx_rsp Move att_truncate_to_mtu from ble_eatt_tx to ble_att_svr_tx_rsp. This could cause some issues when used by client. --- nimble/host/src/ble_att_svr.c | 21 +++++++++++++++++++++ nimble/host/src/ble_eatt.c | 2 -- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 145318f09d..783999d991 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -625,6 +625,8 @@ static int ble_att_svr_tx_rsp(uint16_t conn_handle, uint16_t cid, int hs_status, struct os_mbuf *om, uint8_t att_op, uint8_t err_status, uint16_t err_handle) { + struct ble_l2cap_chan *chan; + struct ble_hs_conn *conn; int do_tx; if (hs_status != 0 && err_status == 0) { @@ -636,6 +638,24 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, uint16_t cid, int hs_status, struct os_ if (do_tx) { if (hs_status == 0) { + ble_hs_lock(); + conn = ble_hs_conn_find(conn_handle); + if (conn == NULL) { + hs_status = BLE_HS_ENOTCONN; + ble_hs_unlock(); + goto done; + } + + chan = ble_hs_conn_chan_find_by_scid(conn, cid); + if (chan == NULL) { + hs_status = BLE_HS_ENOENT; + ble_hs_unlock(); + goto done; + } + + ble_att_truncate_to_mtu(chan, om); + ble_hs_unlock(); + hs_status = ble_att_tx(conn_handle, cid, om); om = NULL; if (hs_status) { @@ -643,6 +663,7 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, uint16_t cid, int hs_status, struct os_ } } +done: if (hs_status != 0) { STATS_INC(ble_att_stats, error_rsp_tx); diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c index 96666c9d0f..c15f545b6d 100644 --- a/nimble/host/src/ble_eatt.c +++ b/nimble/host/src/ble_eatt.c @@ -476,8 +476,6 @@ ble_eatt_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom) goto error; } - ble_att_truncate_to_mtu(eatt->chan, txom); - rc = ble_l2cap_send(eatt->chan, txom); if (rc == 0) { goto done; From ae401ab5cde6f056717407e18d6abb6c44767855 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Mon, 23 Sep 2024 16:19:11 +0200 Subject: [PATCH 1110/1333] nimble/host: ble_gap.c don't use tabs as indentation --- nimble/host/src/ble_gap.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 7d8cf39263..6369b44788 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -7129,7 +7129,7 @@ ble_gap_init(void) int ble_gap_enh_read_transmit_power_level(uint16_t conn_handle, uint8_t phy, uint8_t *out_status, uint8_t *out_phy , - uint8_t *out_curr_tx_power_level, uint8_t *out_max_tx_power_level) + uint8_t *out_curr_tx_power_level, uint8_t *out_max_tx_power_level) { #if MYNEWT_VAL(BLE_POWER_CONTROL) @@ -7162,7 +7162,7 @@ ble_gap_enh_read_transmit_power_level(uint16_t conn_handle, uint8_t phy, uint8_t int ble_gap_read_remote_transmit_power_level(uint16_t conn_handle, - uint8_t phy) + uint8_t phy) { #if MYNEWT_VAL(BLE_POWER_CONTROL) struct ble_hci_le_read_remote_transmit_power_level_cp cmd; @@ -7181,11 +7181,11 @@ ble_gap_read_remote_transmit_power_level(uint16_t conn_handle, int ble_gap_set_path_loss_reporting_param(uint16_t conn_handle, - uint8_t high_threshold, - uint8_t high_hysteresis, - uint8_t low_threshold, - uint8_t low_hysteresis, - uint16_t min_time_spent) + uint8_t high_threshold, + uint8_t high_hysteresis, + uint8_t low_threshold, + uint8_t low_hysteresis, + uint16_t min_time_spent) { #if MYNEWT_VAL(BLE_POWER_CONTROL) struct ble_hci_le_set_path_loss_report_param_cp cmd; @@ -7208,7 +7208,7 @@ ble_gap_set_path_loss_reporting_param(uint16_t conn_handle, int ble_gap_set_path_loss_reporting_enable(uint16_t conn_handle, - uint8_t enable) + uint8_t enable) { #if MYNEWT_VAL(BLE_POWER_CONTROL) struct ble_hci_le_set_path_loss_report_enable_cp cmd; @@ -7227,8 +7227,8 @@ ble_gap_set_path_loss_reporting_enable(uint16_t conn_handle, int ble_gap_set_transmit_power_reporting_enable(uint16_t conn_handle, - uint8_t local_enable, - uint8_t remote_enable) + uint8_t local_enable, + uint8_t remote_enable) { #if MYNEWT_VAL(BLE_POWER_CONTROL) struct ble_hci_le_set_transmit_power_report_enable_cp cmd; From b73cbab1f1f04049132106d8d8fd0b548350303b Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Tue, 29 Oct 2024 14:08:42 +0100 Subject: [PATCH 1111/1333] nimble/ll: Set handle in cmd_resp before return Minor fix. We should set conn_handle in the command response buffer before returning. --- nimble/controller/src/ble_ll_conn_hci.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index e1b2689b79..a7bb136f70 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1514,7 +1514,8 @@ ble_ll_conn_hci_set_data_len(const uint8_t *cmdbuf, uint8_t len, tx_time = le16toh(cmd->tx_time); if (!ble_ll_hci_check_dle(tx_octets, tx_time)) { - return BLE_ERR_INV_HCI_CMD_PARMS; + rc = BLE_ERR_INV_HCI_CMD_PARMS; + goto done; } rc = ble_ll_conn_set_data_len(connsm, tx_octets, tx_time, 0, 0); @@ -2071,7 +2072,8 @@ ble_ll_set_sync_transfer_params(const uint8_t *cmdbuf, uint8_t len, if (MYNEWT_VAL(BLE_VERSION) >= 53) { if (cmd->mode > 0x03) { - return BLE_ERR_INV_HCI_CMD_PARMS; + rc = BLE_ERR_INV_HCI_CMD_PARMS; + goto done; } if ((cmd->mode == 0x03) && @@ -2079,10 +2081,12 @@ ble_ll_set_sync_transfer_params(const uint8_t *cmdbuf, uint8_t len, /* We do not support ADI in periodic advertising thus cannot enable * duplicate filtering. */ - return BLE_ERR_UNSUPPORTED; + rc = BLE_ERR_UNSUPPORTED; + goto done; } } else if (cmd->mode > 0x02) { - return BLE_ERR_INV_HCI_CMD_PARMS; + rc = BLE_ERR_INV_HCI_CMD_PARMS; + goto done; } skip = le16toh(cmd->skip); From 530f8b98dafca5589f5c6c5524a316bf41dd3c18 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Fri, 20 Sep 2024 15:10:09 +0200 Subject: [PATCH 1112/1333] nimble/host: add eatt opcode check in ble_eatt_l2cap_event_fn Att opcode check caused l2cap disconnection when opcode included in received data was write command which is supported and can be used on eatt. Also, the comment seemed irrelevant. Fixes GATT/SR/GAW/BV-01-C --- nimble/host/src/ble_att.c | 45 ++++++++++++++++++++++++++++++ nimble/host/src/ble_att_cmd_priv.h | 2 ++ nimble/host/src/ble_eatt.c | 17 +++++------ 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index 5e221824c3..4a867639c4 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -635,6 +635,51 @@ ble_att_create_chan(uint16_t conn_handle) return chan; } +bool +ble_eatt_supported_req(uint8_t opcode) +{ + switch (opcode) { + case BLE_ATT_OP_WRITE_CMD: + case BLE_ATT_OP_FIND_INFO_REQ: + case BLE_ATT_OP_FIND_TYPE_VALUE_REQ: + case BLE_ATT_OP_READ_TYPE_REQ: + case BLE_ATT_OP_READ_REQ: + case BLE_ATT_OP_READ_BLOB_REQ: + case BLE_ATT_OP_READ_MULT_REQ: + case BLE_ATT_OP_READ_GROUP_TYPE_REQ: + case BLE_ATT_OP_WRITE_REQ: + case BLE_ATT_OP_PREP_WRITE_REQ: + case BLE_ATT_OP_EXEC_WRITE_REQ: + case BLE_ATT_OP_INDICATE_REQ: + case BLE_ATT_OP_READ_MULT_VAR_REQ: + case BLE_ATT_OP_NOTIFY_MULTI_REQ: + return true; + } + return false; +} + +bool +ble_eatt_supported_rsp(uint8_t opcode) +{ + switch (opcode) { + case BLE_ATT_OP_ERROR_RSP: + case BLE_ATT_OP_FIND_INFO_RSP: + case BLE_ATT_OP_FIND_TYPE_VALUE_RSP: + case BLE_ATT_OP_READ_TYPE_RSP: + case BLE_ATT_OP_INDICATE_RSP: + case BLE_ATT_OP_READ_RSP: + case BLE_ATT_OP_READ_BLOB_RSP: + case BLE_ATT_OP_READ_MULT_RSP: + case BLE_ATT_OP_READ_GROUP_TYPE_RSP: + case BLE_ATT_OP_WRITE_RSP: + case BLE_ATT_OP_PREP_WRITE_RSP: + case BLE_ATT_OP_EXEC_WRITE_RSP: + case BLE_ATT_OP_READ_MULT_VAR_RSP: + return true; + } + return false; +} + bool ble_att_is_request_op(uint8_t opcode) { diff --git a/nimble/host/src/ble_att_cmd_priv.h b/nimble/host/src/ble_att_cmd_priv.h index 78c60d5ef4..ab407ca9a2 100644 --- a/nimble/host/src/ble_att_cmd_priv.h +++ b/nimble/host/src/ble_att_cmd_priv.h @@ -462,6 +462,8 @@ int ble_att_tx_with_conn(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, struct os_mbuf *txom); bool ble_att_is_response_op(uint8_t opcode); bool ble_att_is_request_op(uint8_t opcode); +bool ble_eatt_supported_req(uint8_t opcode); +bool ble_eatt_supported_rsp(uint8_t opcode); #ifdef __cplusplus } #endif diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c index c15f545b6d..3ec9bd3b8e 100644 --- a/nimble/host/src/ble_eatt.c +++ b/nimble/host/src/ble_eatt.c @@ -266,15 +266,16 @@ ble_eatt_l2cap_event_fn(struct ble_l2cap_event *event, void *arg) case BLE_L2CAP_EVENT_COC_DATA_RECEIVED: assert(eatt->chan == event->receive.chan); opcode = event->receive.sdu_rx->om_data[0]; - if (ble_att_is_response_op(opcode)) { + if (ble_eatt_supported_rsp(opcode)) { ble_npl_eventq_put(ble_hs_evq_get(), &eatt->wakeup_ev); - } else if (!ble_att_is_request_op(opcode)) { - /* As per BLE 5.4 Standard, Vol. 3, Part F, section 5.3.2 - * (ENHANCED ATT BEARER L2CAP INTEROPERABILITY REQUIREMENTS: - * Channel Requirements): - * All packets sent on this L2CAP channel shall be Attribute PDUs. - * - * Disconnect peer with invalid behavior. + } else if (!ble_eatt_supported_req(opcode)) { + /* If an ATT PDU is supported on any ATT bearer, then it shall be + * supported on all supported ATT bearers with the following + * exceptions: + * • The Exchange MTU sub-procedure shall only be supported on the + * LE Fixed Channel Unenhanced ATT bearer. + * • The Signed Write Without Response sub-procedure shall only be + * supported on the LE Fixed Channel Unenhanced ATT bearer. */ ble_l2cap_disconnect(eatt->chan); return BLE_HS_EREJECT; From b1ec600f7582ea603bb5c581e7c2bbf27bdd39ba Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 29 Oct 2024 16:21:48 +0100 Subject: [PATCH 1113/1333] nimble/ll: Fix build with clang 11 on mac Looks like clang is not able to track relation between max_delay and calc_sch which are involve two separate if-else blocks. This is false positive. repos/apache-mynewt-nimble/nimble/controller/src/ble_ll_sched.c:568:9: error: variable 'max_delay' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized] if (calc_sch) { ^~~~~~~~ repos/apache-mynewt-nimble/nimble/controller/src/ble_ll_sched.c:586:35: note: uninitialized use occurs here rc = ble_ll_sched_insert(sch, max_delay, preempt_none); ^~~~~~~~~ repos/apache-mynewt-nimble/nimble/controller/src/ble_ll_sched.c:568:5: note: remove the 'if' if its condition is always true if (calc_sch) { ^~~~~~~~~~~~~~ repos/apache-mynewt-nimble/nimble/controller/src/ble_ll_sched.c:431:23: note: initialize the variable 'max_delay' to silence this warning uint32_t max_delay; ^ = 0 --- nimble/controller/src/ble_ll_sched.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index f2987dfdf0..8f4599bdf3 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -428,7 +428,7 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, uint32_t orig_start_time; uint32_t earliest_start = 0; uint32_t min_win_offset; - uint32_t max_delay; + uint32_t max_delay = 0; uint32_t adv_rxend; bool calc_sch = true; os_sr_t sr; @@ -536,7 +536,6 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, } else { connsm->css_period_idx = css->period_anchor_idx; } - max_delay = 0; } /* Calculate anchor point and move to next period if scheduled too From 84429c43ed03d0e0dddb3c8f4b2bb28237924b44 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 30 Oct 2024 10:18:34 +0100 Subject: [PATCH 1114/1333] ci: Enable newt test on Mac We properly support 64bit in native target now so those can be re-enabled. --- .github/workflows/newt_test_all.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/newt_test_all.yml b/.github/workflows/newt_test_all.yml index 8299b54d5e..c557b92a57 100644 --- a/.github/workflows/newt_test_all.yml +++ b/.github/workflows/newt_test_all.yml @@ -24,13 +24,18 @@ on: [push, pull_request] jobs: newt_test: name: Run newt test all - runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-13] + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: go-version: 'stable' - name: Install Dependencies + if: matrix.os == 'ubuntu-latest' shell: bash run: | sudo apt-get update From 8f6b9df15a0ea6d39d5b1e54fda61fd3c2535b5c Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 31 Oct 2024 08:58:06 +0100 Subject: [PATCH 1115/1333] ci: Only download required repositories This should speed up CI a bit. --- .github/project.yml | 4 +++ .github/project_newt_test_all.yml | 39 +++++++++++++++++++++++++++++ .github/workflows/newt_test_all.yml | 2 +- 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 .github/project_newt_test_all.yml diff --git a/.github/project.yml b/.github/project.yml index 4d81374169..c030061996 100644 --- a/.github/project.yml +++ b/.github/project.yml @@ -30,3 +30,7 @@ repository.apache-mynewt-core: vers: 0.0.0 user: apache repo: mynewt-core + +project.repositories.ignored: + - stm-* + - atmel-samd21xx diff --git a/.github/project_newt_test_all.yml b/.github/project_newt_test_all.yml new file mode 100644 index 0000000000..960c844bad --- /dev/null +++ b/.github/project_newt_test_all.yml @@ -0,0 +1,39 @@ +# +# 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. +# + +project.name: "my_project" + +project.repositories: + - apache-mynewt-core + +# Use github's distribution mechanism for core ASF libraries. +# This provides mirroring automatically for us. +# +repository.apache-mynewt-core: + type: github + vers: 0.0.0 + user: apache + repo: mynewt-core + +project.repositories.allowed: + - apache-mynewt-core + - apache-mynewt-nimble + - apache-mynewt-mcumgr + - mcuboot + - mbedtls diff --git a/.github/workflows/newt_test_all.yml b/.github/workflows/newt_test_all.yml index c557b92a57..04299bdbec 100644 --- a/.github/workflows/newt_test_all.yml +++ b/.github/workflows/newt_test_all.yml @@ -49,7 +49,7 @@ jobs: shell: bash run: | newt new build - cp -f .github/project.yml build/project.yml + cp -f .github/project_newt_test_all.yml build/project.yml cd build newt upgrade --shallow=1 rm -rf repos/apache-mynewt-nimble From 1d65368c7a05a958378e9a71026f05abbd3115b7 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 31 Oct 2024 14:53:43 +0100 Subject: [PATCH 1116/1333] nimble/audio/bass: Control point buffer fix Remove unnecessary buffer from operation. Pass proper buffer to handler. --- nimble/host/audio/services/bass/src/ble_audio_svc_bass.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index e3cecb060e..bc04631b9f 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -669,7 +669,6 @@ static int ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt, uint16_t conn_handle) { uint8_t opcode; - struct os_mbuf *om; uint16_t mbuf_len = OS_MBUF_PKTLEN(ctxt->om); struct ble_svc_audio_bass_ctrl_point_handler *handler; @@ -692,7 +691,7 @@ ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt, ui return BLE_ATT_ERR_UNLIKELY; } - return handler->handler_cb(&om->om_data[1], mbuf_len - 1, conn_handle); + return handler->handler_cb(&ctxt->om->om_data[1], mbuf_len - 1, conn_handle); } static int From 73536338e41d459ca4d8b096e8df4d104304f752 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 31 Oct 2024 14:39:05 +0100 Subject: [PATCH 1117/1333] nimble/audio/bass: Remove unnecessary variable Remove uncnecessary variable representing characterisic value in remove source operation --- nimble/host/audio/services/bass/src/ble_audio_svc_bass.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index bc04631b9f..8bf6ca88c5 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -606,7 +606,6 @@ ble_svc_audio_bass_remove_source(uint8_t *data, uint16_t data_len, uint16_t conn }; struct ble_svc_audio_bass_rcv_state_entry *rcv_state = NULL; struct ble_svc_audio_bass_operation operation; - uint16_t chr_val; int rc = 0; int i; @@ -638,7 +637,6 @@ ble_svc_audio_bass_remove_source(uint8_t *data, uint16_t data_len, uint16_t conn memset(rcv_state, 0, sizeof(*rcv_state)); rcv_state->source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE; - rcv_state->chr_val = chr_val; done: if (!rc) { From 71585bb528457fa148d8f495cd5b22234f022f6d Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 31 Oct 2024 14:36:29 +0100 Subject: [PATCH 1118/1333] nimble/audio/bass: Fix typos in modify source Fixes typo errors in modify source operation --- nimble/host/audio/services/bass/src/ble_audio_svc_bass.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index 8bf6ca88c5..a1c7da82c3 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -516,17 +516,17 @@ ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn } for (i = 0; i < operation.modify_source.num_subgroups; i++) { - operation.modify_source.subgroups.bis_sync[i] = get_le32(&data[offset]); + operation.modify_source.subgroups[i].bis_sync_state = get_le32(&data[offset]); offset += 4; operation.modify_source.subgroups[i].metadata_length = data[offset++]; data_len -= 5; if (data_len < operation.modify_source.subgroups[i].metadata_length) { rc = BLE_ATT_ERR_WRITE_REQ_REJECTED; - ev.bass_operation_status.status = BLE_HS_ERJECT; + ev.bass_operation_status.status = BLE_HS_EREJECT; goto done; } operation.modify_source.subgroups[i].metadata = &data[offset]; - offset += operation_modify_source.subgroups[i].metadata_length; + offset += operation.modify_source.subgroups[i].metadata_length; data_len -= operation.modify_source.subgroups[i].metadata_length; } From 8378e697eb6d6c7fa7917435defe73b57401aea1 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 31 Oct 2024 14:32:12 +0100 Subject: [PATCH 1119/1333] nimble/audio/bass: Move check_bis_sync function Move location of check_bis_sync function so calling it would not result in build error --- .../services/bass/src/ble_audio_svc_bass.c | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index a1c7da82c3..8b5daf98c6 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -282,6 +282,28 @@ ble_svc_audio_bass_remote_scan_started(uint8_t *data, uint16_t data_len, uint16_ return 0; } +static int +check_bis_sync(uint16_t num_subgroups, struct ble_svc_audio_bass_subgroup *subgroups) +{ + uint32_t bis_sync_mask = 0; + int i; + int j; + + for (i = 0; i < num_subgroups; i++) { + if (subgroups[i].bis_sync_state != 0xFFFFFFFF) { + for (j = 0; j < num_subgroups; j++) { + if (subgroups[i].bis_sync_state & bis_sync_mask) { + return BLE_HS_EINVAL; + } + + bis_sync_mask |= subgroups[i].bis_sync_state; + } + } + } + + return 0; +} + static int ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle) { @@ -444,27 +466,6 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha } static int -check_bis_sync(uint16_t num_subgroups, struct ble_svc_audio_bass_subgroup *subgroups) -{ - uint32_t bis_sync_mask = 0; - int i; - int j; - - for (i = 0; i < num_subgroups; i++) { - if (subgroups[i].bis_sync != 0xFFFFFFFF) { - for (j = 0; j < num_subgroups; j++) { - if (subgroups[i].bis_sync & bis_sync_mask) { - return BLE_HS_EINVAL; - } - - bis_sync_mask |= subgroups[i].bis_sync; - } - } - } - - return 0; -} - ble_svc_audio_bass_modify_source(uint8_t *data, uint16_t data_len, uint16_t conn_handle) { struct ble_svc_audio_bass_operation operation; From 1b0b46d8910acb851fd6315d630cc9ea8d45f6f7 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 31 Oct 2024 13:54:51 +0100 Subject: [PATCH 1120/1333] porting: Sync mbuf with latest core This fix msys allocation with multiple mpools. From upstream commit: " When msys was configured with several mpools and one of the pools run out of buffers, os_mbuf_get() returned NULL even though other mpool did have buffers available. Now search for suitable buffer checks if suitable pool is empty and if not search continues." --- porting/nimble/src/os_mbuf.c | 45 +++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/porting/nimble/src/os_mbuf.c b/porting/nimble/src/os_mbuf.c index f659070328..796a853759 100644 --- a/porting/nimble/src/os_mbuf.c +++ b/porting/nimble/src/os_mbuf.c @@ -153,24 +153,30 @@ os_msys_reset(void) } static struct os_mbuf_pool * -_os_msys_find_pool(uint16_t dsize) +os_msys_find_pool(uint16_t dsize) { struct os_mbuf_pool *pool; + struct os_mbuf_pool *pool_with_free_blocks = NULL; + uint16_t pool_free_blocks; - pool = NULL; STAILQ_FOREACH(pool, &g_msys_pool_list, omp_next) { - if (dsize <= pool->omp_databuf_len) { - break; + pool_free_blocks = pool->omp_pool->mp_num_free; + if (pool_free_blocks != 0) { + pool_with_free_blocks = pool; + if (dsize <= pool->omp_databuf_len) { + break; + } } } - if (!pool) { - pool = STAILQ_LAST(&g_msys_pool_list, os_mbuf_pool, omp_next); - } - - return (pool); + return pool_with_free_blocks; } +static struct os_mbuf_pool * +os_msys_find_biggest_pool(void) +{ + return os_msys_find_pool(0xFFFF); +} struct os_mbuf * os_msys_get(uint16_t dsize, uint16_t leadingspace) @@ -178,7 +184,15 @@ os_msys_get(uint16_t dsize, uint16_t leadingspace) struct os_mbuf *m; struct os_mbuf_pool *pool; - pool = _os_msys_find_pool(dsize); + /* If dsize = 0 that means user has no idea how big block size is needed, + * therefore lets find for him the biggest one + */ + if (dsize == 0) { + pool = os_msys_find_biggest_pool(); + } else { + pool = os_msys_find_pool(dsize); + } + if (!pool) { goto err; } @@ -197,7 +211,16 @@ os_msys_get_pkthdr(uint16_t dsize, uint16_t user_hdr_len) struct os_mbuf_pool *pool; total_pkthdr_len = user_hdr_len + sizeof(struct os_mbuf_pkthdr); - pool = _os_msys_find_pool(dsize + total_pkthdr_len); + + /* If dsize = 0 that means user has no idea how big block size is needed, + * therefore lets find for him the biggest one + */ + if (dsize == 0) { + pool = os_msys_find_biggest_pool(); + } else { + pool = os_msys_find_pool(dsize + total_pkthdr_len); + } + if (!pool) { goto err; } From 718129445d3886943688d8c7020b00bd4d2a65d6 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Mon, 15 Apr 2024 14:56:19 +0200 Subject: [PATCH 1121/1333] Initial commit adding BASS in bttester Adding BASS support in bttester --- apps/bttester/pkg.yml | 2 + apps/bttester/src/btp/btp_bap.h | 15 +- apps/bttester/src/btp/btp_gap.h | 10 ++ apps/bttester/src/btp/bttester.h | 4 +- apps/bttester/src/btp_bap.c | 266 ++++++++++++++++++++++++++++++- apps/bttester/src/btp_core.c | 2 +- apps/bttester/src/btp_gap.c | 38 +++++ apps/bttester/syscfg.yml | 16 +- 8 files changed, 340 insertions(+), 13 deletions(-) diff --git a/apps/bttester/pkg.yml b/apps/bttester/pkg.yml index e763185fe5..0972cb7a2b 100644 --- a/apps/bttester/pkg.yml +++ b/apps/bttester/pkg.yml @@ -32,10 +32,12 @@ pkg.deps: - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/shell" - "@apache-mynewt-nimble/nimble/host" + - "@apache-mynewt-nimble/nimble/host/audio" - "@apache-mynewt-nimble/nimble/host/util" - "@apache-mynewt-nimble/nimble/host/services/gap" - "@apache-mynewt-nimble/nimble/host/services/gatt" - "@apache-mynewt-nimble/nimble/host/services/dis" + - "@apache-mynewt-nimble/nimble/host/audio/services/bass" - "@apache-mynewt-nimble/nimble/host/store/config" - "@apache-mynewt-core/hw/drivers/uart" - "@apache-mynewt-core/hw/drivers/rtt" diff --git a/apps/bttester/src/btp/btp_bap.h b/apps/bttester/src/btp/btp_bap.h index f25ab14748..804c9d4c87 100644 --- a/apps/bttester/src/btp/btp_bap.h +++ b/apps/bttester/src/btp/btp_bap.h @@ -84,11 +84,24 @@ struct bap_bap_broadcast_source_stop_cmd { } __packed; #define BTP_BAP_BROADCAST_SINK_SETUP 0x0a + +#define BTP_BAP_BROADCAST_SINK_STOP 0x0f +struct btp_bap_broadcast_sink_stop_cmd { + ble_addr_t address; + uint8_t broadcast_id[3]; +} __packed; + +#define BTP_BAP_SET_BROADCAST_CODE 0x17 +struct btp_bap_set_broadcast_code_cmd { + ble_addr_t addr; + uint8_t source_id; + uint8_t broadcast_code[16]; +} __packed; + #define BTP_BAP_BROADCAST_SINK_RELEASE 0x0b #define BTP_BAP_BROADCAST_SCAN_START 0x0c #define BTP_BAP_BROADCAST_SCAN_STOP 0x0d #define BTP_BAP_BROADCAST_SINK_SYNC 0x0e -#define BTP_BAP_BROADCAST_SINK_STOP 0x0f #define BTP_BAP_BROADCAST_SINK_BIS_SYNC 0x10 #define BTP_BAP_DISCOVER_SCAN_DELEGATOR 0x11 #define BTP_BAP_BROADCAST_ASSISTANT_SCAN_START 0x12 diff --git a/apps/bttester/src/btp/btp_gap.h b/apps/bttester/src/btp/btp_gap.h index 2a87b12930..9c691878f2 100644 --- a/apps/bttester/src/btp/btp_gap.h +++ b/apps/bttester/src/btp/btp_gap.h @@ -70,6 +70,7 @@ struct btp_gap_read_controller_index_list_rp { #define BTP_GAP_SETTINGS_PRIVACY 13 #define BTP_GAP_SETTINGS_CONTROLLER_CONFIG 14 #define BTP_GAP_SETTINGS_STATIC_ADDRESS 15 +#define BTP_GAP_SETTINGS_EXTENDED_ADVERTISING 17 #define BTP_GAP_SETTINGS_PERIODIC_ADVERTISING 18 #define BTP_GAP_READ_CONTROLLER_INFO 0x03 @@ -258,6 +259,15 @@ struct btp_gap_set_filter_accept_list_cmd { ble_addr_t addrs[]; } __packed; +#define GAP_SET_EXT_ADV 0x21 +struct btp_gap_set_ext_advertising_cmd { + uint8_t setting; +} __packed; + +struct btp_gap_set_ext_advertising_rp { + uint32_t current_settings; +} __packed; + #define GAP_PADV_CONFIGURE 0x22 struct gap_periodic_adv_configure_cmd { uint8_t flags; diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h index 7cb82b5c92..87068d2a78 100644 --- a/apps/bttester/src/btp/bttester.h +++ b/apps/bttester/src/btp/bttester.h @@ -142,12 +142,12 @@ gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); int gatt_svr_init(void); -#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) +#if MYNEWT_VAL(BLE_AUDIO) uint8_t tester_init_bap(void); uint8_t tester_unregister_bap(void); -#endif /* MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) */ +#endif /* MYNEWT_VAL(BLE_AUDIO) */ #endif /* __BTTESTER_H__ */ diff --git a/apps/bttester/src/btp_bap.c b/apps/bttester/src/btp_bap.c index 5a2d06c811..37ecedb0e4 100644 --- a/apps/bttester/src/btp_bap.c +++ b/apps/bttester/src/btp_bap.c @@ -19,22 +19,24 @@ /* btp_bap.c - Bluetooth Basic Audio Profile Tester */ +#include "btp/bttester.h" #include "syscfg/syscfg.h" +#include + #if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) #include "btp/btp_bap.h" - #include "btp/btp.h" #include "console/console.h" -#include "nimble/ble.h" #include "host/ble_hs.h" #include "host/util/util.h" #include "math.h" #include "audio/ble_audio_broadcast_source.h" +#include "audio/ble_audio_broadcast_sink.h" #include "audio/ble_audio.h" #include "host/ble_iso.h" @@ -42,6 +44,13 @@ static struct ble_audio_big_subgroup big_subgroup; +static struct broadcast_sink { + ble_addr_t addr; + uint8_t source_id; + uint8_t broadcast_code[BLE_AUDIO_BROADCAST_CODE_SIZE]; +} sinks[MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK_MAX)]; + +static uint8_t sink_num = 0; static uint8_t id_addr_type; static uint8_t audio_data[155]; static uint16_t max_sdu; @@ -107,7 +116,7 @@ iso_event(struct ble_iso_event *event, void *arg) switch (event->type) { case BLE_ISO_EVENT_BIG_CREATE_COMPLETE: - console_printf("BIG created\n"); + console_printf("%s: BIG created\n", __func__); if (event->big_created.desc.num_bis > MYNEWT_VAL(BROADCASTER_CHAN_NUM)) { return BLE_HS_EINVAL; @@ -117,7 +126,7 @@ iso_event(struct ble_iso_event *event, void *arg) } return 0; case BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE: - console_printf("BIG terminated\n"); + console_printf("%s: BIG terminated\n", __func__); return 0; default: return BLE_HS_ENOTSUP; @@ -319,6 +328,74 @@ broadcast_source_start(const void *cmd, uint16_t cmd_len, void *rsp, return BTP_STATUS_SUCCESS; } +static uint8_t +broadcast_code_set(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + const struct btp_bap_set_broadcast_code_cmd *cp = cmd; + + if (sink_num > MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK_MAX)) { + return BTP_STATUS_FAILED; + } + + sinks[sink_num].addr = cp->addr; + sinks[sink_num].addr.type = cp->addr.type; + sinks[sink_num].source_id = cp->source_id; + + memcpy(sinks[sink_num].broadcast_code, cp->broadcast_code, + BLE_AUDIO_BROADCAST_CODE_SIZE); + + sink_num++; + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +broadcast_sink_setup(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + int rc, i; + struct ble_audio_broadcast_sink_add_params params = {0}; + + for (i = 0; i < sink_num; i++) { + memcpy(params.broadcast_code, sinks[i].broadcast_code, + BLE_AUDIO_BROADCAST_CODE_SIZE); + params.broadcast_code_is_valid = true; + rc = ble_audio_broadcast_sink_start(sinks[i].source_id, ¶ms); + if (rc) { + return BTP_STATUS_FAILED; + } + } + + return BTP_STATUS_SUCCESS; +} + +static int +scan_delegator_receive_state_foreach_fn(struct ble_audio_scan_delegator_receive_state_entry *entry, + void *addr) +{ + if (ble_addr_cmp(addr, &entry->source_desc.addr)) { + ble_audio_broadcast_sink_stop(entry->source_id); + } + + return 0; +} + +static uint8_t +broadcast_sink_stop(const void *cmd, uint16_t cmd_len, void *rsp, + uint16_t *rsp_len) +{ + ble_addr_t addr; + const struct btp_bap_broadcast_sink_stop_cmd *cp = cmd; + + addr = cp->address; + + ble_audio_scan_delegator_receive_state_foreach(scan_delegator_receive_state_foreach_fn, + &addr); + + return BTP_STATUS_SUCCESS; +} + static uint8_t broadcast_source_stop(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) @@ -371,8 +448,172 @@ static const struct btp_handler handlers[] = { .expect_len = sizeof(struct bap_bap_broadcast_source_stop_cmd), .func = broadcast_source_stop, }, + { + .opcode = BTP_BAP_SET_BROADCAST_CODE, + .index = BTP_INDEX, + .expect_len = sizeof(struct btp_bap_set_broadcast_code_cmd), + .func = broadcast_code_set, + }, + { + .opcode = BTP_BAP_BROADCAST_SINK_SETUP, + .index = BTP_INDEX, + .expect_len = 0, + .func = broadcast_sink_setup, + }, + { + .opcode = BTP_BAP_BROADCAST_SINK_STOP, + .index = BTP_INDEX, + .expect_len = sizeof(struct btp_bap_broadcast_sink_stop_cmd), + .func = broadcast_sink_stop, + }, }; +#define BROADCAST_SINK_PA_SYNC_TIMEOUT_DEFAULT 0x07D0 + +static int +broadcast_sink_pa_sync_params_get(struct ble_gap_periodic_sync_params *params) +{ + params->skip = 0; + params->sync_timeout = BROADCAST_SINK_PA_SYNC_TIMEOUT_DEFAULT; + params->reports_disabled = false; + + return 0; +} + +static int +broadcast_sink_disc_start(const struct ble_gap_ext_disc_params *params) +{ + uint8_t own_addr_type; + int rc; + + /* Figure out address to use while scanning. */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + console_printf("%s: determining own address type failed (%d)", __func__, rc); + assert(0); + } + + rc = ble_gap_ext_disc(own_addr_type, 0, 0, 0, 0, 0, params, NULL, NULL, NULL); + if (rc != 0) { + console_printf("%s: ext disc failed (%d)", __func__, rc); + } + + return rc; +} + +static int +broadcast_sink_disc_stop(void) +{ + int rc; + + rc = ble_gap_disc_cancel(); + if (rc != 0) { + console_printf("%s: disc cancel failed (%d)", __func__, rc); + } + + return rc; +} + +static int +broadcast_sink_action_fn(struct ble_audio_broadcast_sink_action *action, void *arg) +{ + switch (action->type) { + case BLE_AUDIO_BROADCAST_SINK_ACTION_PA_SYNC: + return broadcast_sink_pa_sync_params_get(action->pa_sync.out_params); + case BLE_AUDIO_BROADCAST_SINK_ACTION_BIG_SYNC: + break; + case BLE_AUDIO_BROADCAST_SINK_ACTION_BIS_SYNC: + return 0; + case BLE_AUDIO_BROADCAST_SINK_ACTION_DISC_START: + return broadcast_sink_disc_start(action->disc_start.params_preferred); + case BLE_AUDIO_BROADCAST_SINK_ACTION_DISC_STOP: + return broadcast_sink_disc_stop(); + default: + assert(false); + return BLE_HS_ENOTSUP; + } + + return 0; +} + +static int +broadcast_sink_audio_event_handler(struct ble_audio_event *event, void *arg) +{ + switch (event->type) { + case BLE_AUDIO_EVENT_BROADCAST_SINK_PA_SYNC_STATE: + console_printf("%s: source_id=0x%02x PA sync: %s\n", __func__, + event->broadcast_sink_pa_sync_state.source_id, + ble_audio_broadcast_sink_sync_state_str( + event->broadcast_sink_pa_sync_state.state)); + break; + case BLE_AUDIO_EVENT_BROADCAST_SINK_BIS_SYNC_STATE: + console_printf("%s: source_id=0x%02x bis_index=0x%02x BIS sync: %s\n", + __func__, event->broadcast_sink_bis_sync_state.source_id, + event->broadcast_sink_bis_sync_state.bis_index, + ble_audio_broadcast_sink_sync_state_str( + event->broadcast_sink_bis_sync_state.state)); + if (event->broadcast_sink_bis_sync_state.state == + BLE_AUDIO_BROADCAST_SINK_SYNC_STATE_ESTABLISHED) { + console_printf("%s: conn_handle=0x%04x\n", __func__, + event->broadcast_sink_bis_sync_state.conn_handle); + } + break; + default: + break; + } + + return 0; +} + +static int +scan_delegator_pick_source_id_to_swap(uint8_t *out_source_id_to_swap) +{ + /* TODO: Add some logic here */ + *out_source_id_to_swap = 0; + + return 0; +} + +static int +scan_delegator_action_fn(struct ble_audio_scan_delegator_action *action, void *arg) +{ + switch (action->type) { + case BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_ADD: + console_printf("%s: Source Add:\nsource_id=%u\n", __func__, + action->source_add.source_id); + if (action->source_add.out_source_id_to_swap == NULL) { + return 0; + } + return scan_delegator_pick_source_id_to_swap(action->source_add.out_source_id_to_swap); + case BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_MODIFY: + console_printf("%s: Source Modify:\nsource_id=%u\n", __func__, + action->source_modify.source_id); + break; + case BLE_AUDIO_SCAN_DELEGATOR_ACTION_SOURCE_REMOVE: + console_printf("%s: Source Remove:\nsource_id=%u\n", __func__, + action->source_remove.source_id); + break; + default: + assert(false); + return BLE_HS_ENOTSUP; + } + + return 0; +} + +static int +scan_delegator_audio_event_handler(struct ble_audio_event *event, void *arg) +{ + switch (event->type) { + case BLE_AUDIO_EVENT_BROADCAST_ANNOUNCEMENT: + break; + default: + break; + } + + return 0; +} + uint8_t tester_init_bap(void) { @@ -405,6 +646,23 @@ tester_init_bap(void) return BTP_STATUS_FAILED; } + static struct ble_audio_event_listener broadcast_sink_listener; + + rc = ble_audio_broadcast_sink_cb_set(broadcast_sink_action_fn, NULL); + assert(rc == 0); + + rc = ble_audio_event_listener_register(&broadcast_sink_listener, + broadcast_sink_audio_event_handler, NULL); + + static struct ble_audio_event_listener scan_delegator_listener; + + rc = ble_audio_scan_delegator_action_fn_set(scan_delegator_action_fn, NULL); + assert(rc == 0); + + rc = ble_audio_event_listener_register(&scan_delegator_listener, + scan_delegator_audio_event_handler, NULL); + assert(rc == 0); + tester_register_command_handlers(BTP_SERVICE_ID_BAP, handlers, ARRAY_SIZE(handlers)); diff --git a/apps/bttester/src/btp_core.c b/apps/bttester/src/btp_core.c index a7b1878322..eeae816a9e 100644 --- a/apps/bttester/src/btp_core.c +++ b/apps/bttester/src/btp_core.c @@ -106,7 +106,7 @@ register_service(const void *cmd, uint16_t cmd_len, case BTP_SERVICE_ID_BAP: status = tester_init_bap(); break; -#endif /* MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) */ +#endif /* MYNEWT_VAL(BLE_ISO_BROADCASTER) */ case BTP_SERVICE_ID_GATTC: status = tester_init_gatt_cl(); break; diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index d0aa7ce06e..f6747b0f49 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -160,6 +160,7 @@ supported_commands(const void *cmd, uint16_t cmd_len, /* octet 4 */ #if MYNEWT_VAL(BLE_PERIODIC_ADV) + tester_set_bit(rp->data, GAP_SET_EXT_ADV); tester_set_bit(rp->data, GAP_PADV_CONFIGURE); tester_set_bit(rp->data, GAP_PADV_START); tester_set_bit(rp->data, GAP_PADV_SET_DATA); @@ -2000,6 +2001,36 @@ set_filter_accept_list(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +#if MYNEWT_VAL(BLE_EXT_ADV) +static uint8_t +set_ext_advertising(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct btp_gap_set_ext_advertising_rp *rp = rsp; + const struct btp_gap_set_ext_advertising_cmd *cp = cmd; + + if (current_settings & BIT(BTP_GAP_SETTINGS_ADVERTISING)) { + return BTP_STATUS_FAILED; + } + + if (cp->setting) { + current_settings |= BIT(BTP_GAP_SETTINGS_EXTENDED_ADVERTISING); + adv_params.legacy_pdu = 0; + /* TODO: This is temporary until auto-pts nonscannable implementation */ + adv_params.scannable = 0; + } else { + current_settings &= ~BIT(BTP_GAP_SETTINGS_EXTENDED_ADVERTISING); + adv_params.legacy_pdu = 1; + } + + rp->current_settings = htole32(current_settings); + *rsp_len = sizeof(*rp); + + return BTP_STATUS_SUCCESS; +} + +#endif + #if MYNEWT_VAL(BLE_PERIODIC_ADV) static uint8_t periodic_adv_configure(const void *cmd, uint16_t cmd_len, @@ -2330,6 +2361,13 @@ static const struct btp_handler handlers[] = { .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = set_filter_accept_list, }, +#if MYNEWT_VAL(BLE_EXT_ADV) + { + .opcode = GAP_SET_EXT_ADV, + .expect_len = sizeof(struct btp_gap_set_ext_advertising_cmd), + .func = set_ext_advertising, + }, +#endif /* BLE_EXT_ADV*/ #if MYNEWT_VAL(BLE_PERIODIC_ADV) { .opcode = GAP_PADV_CONFIGURE, diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 80c377a7c1..fea32fccd6 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -93,15 +93,23 @@ syscfg.vals: BLE_ISO: 1 BLE_AUDIO: 1 + BLE_AUDIO_BROADCAST_SINK: 1 + BLE_AUDIO_BROADCAST_SINK_MAX: 2 + BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 + BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: 1 BLE_ROLE_BROADCASTER: 1 - BLE_ISO_MAX_BISES: 1 - BLE_ISO_MAX_BIGS: 1 + BLE_ISO_BROADCAST_SOURCE: 1 + BLE_ISO_BROADCAST_SINK: 1 + BLE_ISO_MAX_BISES: 3 + BLE_ISO_MAX_BIGS: 3 BLE_EXT_ADV: 1 BLE_PHY_2M: 1 BLE_EXT_ADV_MAX_SIZE: 40 BLE_PERIODIC_ADV: 1 BLE_ISO_BROADCAST_SOURCE: 1 - BLE_MULTI_ADV_INSTANCES: 1 + BLE_MULTI_ADV_INSTANCES: 3 + BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ: 256 + BLE_SVC_AUDIO_BASS_SUB_NUM_MAX: 10 OS_MAIN_STACK_SIZE: 512 SHELL_TASK: 0 @@ -163,5 +171,3 @@ syscfg.vals: BLE_MESH_TX_SEG_MSG_COUNT: 2 BLE_MAX_CONNECTIONS: 8 - - From a45a15c1c95237929d251134d4dababf14f658aa Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 31 Oct 2024 13:51:37 +0100 Subject: [PATCH 1122/1333] porting/linux: Fix warning about __USE_GNU redefinition Simply define this before including any systema headers. g -D_GNU_SOURCE -o ../../../porting/npl/linux/src/os_atomic.o ../../ ../porting/npl/linux/src/os_atomic.c ../../../porting/npl/linux/src/os_atomic.c:21:9: warning: "__USE_GNU" redefined 21 | #define __USE_GNU | ^~~~~~~~~ In file included from /usr/include/bits/libc-header-start.h:33, from /usr/include/stdint.h:26, from /usr/lib/gcc/x86_64-redhat-linux/14/include/stdint.h:9, from ../../../porting/npl/linux/src/os_atomic.c:20: /usr/include/features.h:409:10: note: this is the location of the previous definition 409 | # define __USE_GNU 1 | ^~~~~~~~~ --- porting/npl/linux/src/os_atomic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/porting/npl/linux/src/os_atomic.c b/porting/npl/linux/src/os_atomic.c index 743a8470e2..531c4a2749 100644 --- a/porting/npl/linux/src/os_atomic.c +++ b/porting/npl/linux/src/os_atomic.c @@ -17,8 +17,9 @@ * under the License. */ -#include #define __USE_GNU + +#include #include #include "nimble/nimble_npl.h" From c41feda76b810cf52651f4bc53f2edcf78a0e103 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 5 Apr 2024 14:48:45 +0200 Subject: [PATCH 1123/1333] apps/bttester: Add initial support for PACS autopts tests This commit adds support for Published Audio Capabilities Service in bttester application. --- apps/bttester/pkg.yml | 2 + apps/bttester/src/btp/btp.h | 2 + apps/bttester/src/btp/btp_pacs.h | 59 ++++++ apps/bttester/src/btp/bttester.h | 7 + apps/bttester/src/btp_core.c | 10 + apps/bttester/src/btp_pacs.c | 333 +++++++++++++++++++++++++++++++ apps/bttester/syscfg.yml | 1 + 7 files changed, 414 insertions(+) create mode 100644 apps/bttester/src/btp/btp_pacs.h create mode 100644 apps/bttester/src/btp_pacs.c diff --git a/apps/bttester/pkg.yml b/apps/bttester/pkg.yml index 0972cb7a2b..8511195452 100644 --- a/apps/bttester/pkg.yml +++ b/apps/bttester/pkg.yml @@ -38,6 +38,8 @@ pkg.deps: - "@apache-mynewt-nimble/nimble/host/services/gatt" - "@apache-mynewt-nimble/nimble/host/services/dis" - "@apache-mynewt-nimble/nimble/host/audio/services/bass" + - "@apache-mynewt-nimble/nimble/host/audio/services/pacs" + - "@apache-mynewt-nimble/nimble/host/audio/services/pacs/lc3" - "@apache-mynewt-nimble/nimble/host/store/config" - "@apache-mynewt-core/hw/drivers/uart" - "@apache-mynewt-core/hw/drivers/rtt" diff --git a/apps/bttester/src/btp/btp.h b/apps/bttester/src/btp/btp.h index 4403a16038..17fe388767 100644 --- a/apps/bttester/src/btp/btp.h +++ b/apps/bttester/src/btp/btp.h @@ -33,6 +33,7 @@ #include "btp_gattc.h" #include "btp_l2cap.h" #include "btp_mesh.h" +#include "btp_pacs.h" #include "btp_bap.h" #define BTP_MTU MYNEWT_VAL(BTTESTER_BTP_DATA_SIZE_MAX) @@ -47,6 +48,7 @@ #define BTP_SERVICE_ID_L2CAP 3 #define BTP_SERVICE_ID_MESH 4 #define BTP_SERVICE_ID_GATTC 6 +#define BTP_SERVICE_ID_PACS 12 #define BTP_SERVICE_ID_BAP 14 #define BTP_SERVICE_ID_MAX BTP_SERVICE_ID_BAP diff --git a/apps/bttester/src/btp/btp_pacs.h b/apps/bttester/src/btp/btp_pacs.h new file mode 100644 index 0000000000..3b9b5b06ce --- /dev/null +++ b/apps/bttester/src/btp/btp_pacs.h @@ -0,0 +1,59 @@ +/* + * 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 BTP_PACS_H +#define BTP_PACS_H + +#include + +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif + +#define BTP_PACS_READ_SUPPORTED_COMMANDS 0x01 +struct btp_pacs_read_supported_commands_rp { + uint8_t data[0]; +} __packed; + +#define BTP_PACS_UPDATE_CHARACTERISTIC 0x02 +struct btp_pacs_update_characteristic_cmd { + uint8_t char_id; +} __packed; + +#define BTP_PACS_SET_LOCATION 0x03 + +#define BTP_PACS_SET_AVAILABLE_CONTEXTS 0x04 +struct btp_pacs_set_available_contexts_cmd { + uint16_t sink_contexts; + uint16_t source_contexts; +} __packed; + +#define BTP_PACS_SET_SUPPORTED_CONTEXTS 0x05 +struct btp_pacs_set_supported_contexts_cmd { + uint16_t sink_contexts; + uint16_t source_contexts; +} __packed; + +#define BTP_PACS_CHARACTERISTIC_SINK_PAC 0x01 +#define BTP_PACS_CHARACTERISTIC_SOURCE_PAC 0x02 +#define BTP_PACS_CHARACTERISTIC_SINK_AUDIO_LOCATIONS 0x03 +#define BTP_PACS_CHARACTERISTIC_SOURCE_AUDIO_LOCATIONS 0x04 +#define BTP_PACS_CHARACTERISTIC_AVAILABLE_AUDIO_CONTEXTS 0x05 + +#endif /* BTP_PACS_H*/ diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h index 87068d2a78..6e1fb3a87b 100644 --- a/apps/bttester/src/btp/bttester.h +++ b/apps/bttester/src/btp/bttester.h @@ -149,5 +149,12 @@ uint8_t tester_unregister_bap(void); #endif /* MYNEWT_VAL(BLE_AUDIO) */ +#if MYNEWT_VAL(BLE_AUDIO) +uint8_t +tester_init_pacs(void); +uint8_t +tester_unregister_pacs(void); +#endif /* MYNEWT_VAL(BLE_AUDIO) */ + #endif /* __BTTESTER_H__ */ diff --git a/apps/bttester/src/btp_core.c b/apps/bttester/src/btp_core.c index eeae816a9e..a1eafb300c 100644 --- a/apps/bttester/src/btp_core.c +++ b/apps/bttester/src/btp_core.c @@ -107,6 +107,11 @@ register_service(const void *cmd, uint16_t cmd_len, status = tester_init_bap(); break; #endif /* MYNEWT_VAL(BLE_ISO_BROADCASTER) */ +#if MYNEWT_VAL(BLE_AUDIO) + case BTP_SERVICE_ID_PACS: + status = tester_init_pacs(); + break; +#endif /* MYNEWT(BLE_AUDIO) */ case BTP_SERVICE_ID_GATTC: status = tester_init_gatt_cl(); break; @@ -164,6 +169,11 @@ unregister_service(const void *cmd, uint16_t cmd_len, status = tester_unregister_bap(); break; #endif /* MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) */ +#if MYNEWT_VAL(BLE_AUDIO) + case BTP_SERVICE_ID_PACS: + status = tester_unregister_pacs(); + break; +#endif /* MYNEWT_VAL (BLE_AUDIO) */ default: status = BTP_STATUS_FAILED; break; diff --git a/apps/bttester/src/btp_pacs.c b/apps/bttester/src/btp_pacs.c new file mode 100644 index 0000000000..217d44df2f --- /dev/null +++ b/apps/bttester/src/btp_pacs.c @@ -0,0 +1,333 @@ +/* + * 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. + */ + +/* btp_pacs.c - Bluetooth Published Audio Capacity Service Tester */ + +#include "audio/ble_audio.h" +#include "audio/ble_audio_codec.h" +#include "btp/bttester.h" +#include "host/ble_gap.h" +#include "os/util.h" +#include "syscfg/syscfg.h" +#include + +#if MYNEWT_VAL(BLE_AUDIO) + +#include "btp/btp.h" +#include "btp/btp_pacs.h" +#include "services/pacs/ble_audio_svc_pacs.h" +#include "services/pacs/ble_audio_svc_pacs_lc3.h" + +#define BLE_SVC_AUDIO_PACS_LC3_CODEC_ID 0x06 +#define BTTESTER_SUPPORTED_CTXTS 0x07 + +struct set_avail_cb_data { + uint16_t src_ctxts; + uint16_t snk_ctxts; +}; + +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SNK_METADATA +static uint8_t ble_svc_audio_pacs_lc3_snk_metadata[] = +{ UNMANGLE_MYNEWT_VAL(MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_METADATA)) }; +#endif + +static uint8_t ble_svc_audio_pacs_lc3_snk_codec_spec_caps[] = BLE_AUDIO_BUILD_CODEC_CAPS( + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_SAMPLING_FREQUENCIES), + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_FRAME_DURATIONS), + #ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_CHANNEL_COUNTS + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_AUDIO_CHANNEL_COUNTS), + #else + , + #endif + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_MIN_OCTETS_PER_CODEC_FRAME), + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_OCTETS_PER_CODEC_FRAME), + #ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_CODEC_FRAMES_PER_SDU + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_MAX_CODEC_FRAMES_PER_SDU), + #endif +); + +static uint8_t ble_svc_audio_pacs_lc3_src_codec_spec_caps[] = BLE_AUDIO_BUILD_CODEC_CAPS( + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_SAMPLING_FREQUENCIES), + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_FRAME_DURATIONS), +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_CHANNEL_COUNTS + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_CHANNEL_COUNTS), +#else + , +#endif + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_MIN_OCTETS_PER_CODEC_FRAME), + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_OCTETS_PER_CODEC_FRAME), +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_CODEC_FRAMES_PER_SDU + MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_MAX_CODEC_FRAMES_PER_SDU), +#endif +); + +static struct ble_audio_codec_register_params snk_codec_params = { + .codec_id = { + .format = BLE_SVC_AUDIO_PACS_LC3_CODEC_ID, + .company_id = 0x00, + .vendor_specific = 0x00 + }, + .codec_spec_caps_len = sizeof(ble_svc_audio_pacs_lc3_snk_codec_spec_caps), + .codec_spec_caps = ble_svc_audio_pacs_lc3_snk_codec_spec_caps, +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SNK_METADATA + .metadata_len = sizeof(ble_svc_audio_pacs_lc3_snk_metadata), + .metadata = ble_svc_audio_pacs_lc3_snk_metadata, +#else + .metadata_len = 0, +#endif + + .direction = BLE_AUDIO_CODEC_DIR_SINK_BIT +}; + +static struct ble_audio_codec_register_params src_codec_params = { + .codec_id = { + .format = BLE_SVC_AUDIO_PACS_LC3_CODEC_ID, + .company_id = 0x00, + .vendor_specific = 0x00 + }, + .codec_spec_caps_len = sizeof(ble_svc_audio_pacs_lc3_src_codec_spec_caps), + .codec_spec_caps = ble_svc_audio_pacs_lc3_src_codec_spec_caps, +#ifdef MYNEWT_VAL_BLE_SVC_AUDIO_PACS_LC3_SRC_METADATA + .metadata_len = sizeof(ble_svc_audio_pacs_lc3_src_metadata), + .metadata = ble_svc_audio_pacs_lc3_src_metadata, +#else + .metadata_len = 0, +#endif + .direction = BLE_AUDIO_CODEC_DIR_SOURCE_BIT +}; + +int +set_available(uint16_t conn_handle, void *arg) +{ + int rc; + struct set_avail_cb_data *avail_data = arg; + + rc = ble_svc_audio_pacs_avail_contexts_set(conn_handle, + avail_data->snk_ctxts, + avail_data->src_ctxts); + if (rc) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +pacs_set_available_contexts(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_pacs_set_available_contexts_cmd *cp = cmd; + uint16_t source_contexts = le16toh(cp->source_contexts); + uint16_t sink_conexts = le16toh(cp->sink_contexts); + struct set_avail_cb_data cb_data; + + /* If this originated from pacs_update_characteristic - we update with unspecified */ + if (sink_conexts == BTP_PACS_CHARACTERISTIC_AVAILABLE_AUDIO_CONTEXTS) { + cb_data.snk_ctxts = BLE_AUDIO_CONTEXT_TYPE_UNSPECIFIED; + cb_data.src_ctxts = BLE_AUDIO_CONTEXT_TYPE_UNSPECIFIED; + } else { + cb_data.snk_ctxts = sink_conexts; + cb_data.src_ctxts = source_contexts; + } + + ble_gap_conn_foreach_handle(set_available, &cb_data); + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +pacs_set_snk_location(void) +{ + int rc; + struct ble_svc_audio_pacs_set_param snk_params = { + .audio_locations = 0, + .supported_contexts = MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SNK_SUP_CONTEXTS) + }; + + rc = ble_svc_audio_pacs_set(BLE_AUDIO_CODEC_DIR_SINK_BIT, &snk_params); + if (rc) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +pacs_set_src_location(void) +{ + int rc; + struct ble_svc_audio_pacs_set_param src_params = { + .audio_locations = 0, + .supported_contexts = MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_SUP_CONTEXTS) + }; + + rc = ble_svc_audio_pacs_set(BLE_AUDIO_CODEC_DIR_SOURCE_BIT, &src_params); + if (rc) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +pacs_update_characteristic(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int rc; + const struct btp_pacs_update_characteristic_cmd *cp = cmd; + + switch (cp->char_id) { + case BTP_PACS_CHARACTERISTIC_SINK_PAC: + rc = ble_audio_codec_register(&snk_codec_params, NULL); + if (rc) { + return BTP_STATUS_FAILED; + } + break; + case BTP_PACS_CHARACTERISTIC_SOURCE_PAC: + rc = ble_audio_codec_register(&src_codec_params, NULL); + if (rc) { + return BTP_STATUS_FAILED; + } + break; + case BTP_PACS_CHARACTERISTIC_SINK_AUDIO_LOCATIONS: + rc = pacs_set_snk_location(); + if (rc) { + return BTP_STATUS_FAILED; + } + break; + case BTP_PACS_CHARACTERISTIC_SOURCE_AUDIO_LOCATIONS: + rc = pacs_set_src_location(); + if (rc) { + return BTP_STATUS_FAILED; + } + break; + case BTP_PACS_CHARACTERISTIC_AVAILABLE_AUDIO_CONTEXTS: + rc = pacs_set_available_contexts(cmd, cmd_len, rsp, rsp_len); + if (rc) { + return BTP_STATUS_FAILED; + } + break; + default: + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +pacs_set_supported_contexts(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + int rc; + const struct btp_pacs_set_supported_contexts_cmd *sup_ctxts = cmd; + + struct ble_svc_audio_pacs_set_param src_params = { + .audio_locations = 0, + .supported_contexts = sup_ctxts->source_contexts, + }; + struct ble_svc_audio_pacs_set_param snk_params = { + .audio_locations = 0, + .supported_contexts = sup_ctxts->sink_contexts, + }; + + rc = ble_svc_audio_pacs_set(BLE_AUDIO_CODEC_DIR_SOURCE_BIT, &src_params); + if (rc) { + return BTP_STATUS_FAILED; + } + + rc = ble_svc_audio_pacs_set(BLE_AUDIO_CODEC_DIR_SINK_BIT, &snk_params); + if (rc) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + +static uint8_t +supported_commands(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + struct btp_pacs_read_supported_commands_rp *rp = rsp; + + /* octet 0 */ + tester_set_bit(rp->data, BTP_PACS_READ_SUPPORTED_COMMANDS); + tester_set_bit(rp->data, BTP_PACS_UPDATE_CHARACTERISTIC); + tester_set_bit(rp->data, BTP_PACS_SET_AVAILABLE_CONTEXTS); + tester_set_bit(rp->data, BTP_PACS_SET_SUPPORTED_CONTEXTS); + + *rsp_len = sizeof(*rp) + 1; + + return BTP_STATUS_SUCCESS; +} + +static const struct btp_handler handlers[] = { + { + .opcode = BTP_PACS_READ_SUPPORTED_COMMANDS, + .expect_len = 0, + .func = supported_commands, + }, + { + .opcode = BTP_PACS_UPDATE_CHARACTERISTIC, + .expect_len = sizeof(struct btp_pacs_update_characteristic_cmd), + .func = pacs_update_characteristic, + }, + { + .opcode = BTP_PACS_SET_AVAILABLE_CONTEXTS, + .expect_len = sizeof(struct btp_pacs_set_available_contexts_cmd), + .func = pacs_set_available_contexts, + }, + { + .opcode = BTP_PACS_SET_SUPPORTED_CONTEXTS, + .expect_len = sizeof(struct btp_pacs_set_supported_contexts_cmd), + .func = pacs_set_supported_contexts, + }, +}; + +uint8_t +tester_init_pacs(void) +{ + int rc; + struct ble_svc_audio_pacs_set_param src_params = { + .audio_locations = MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_LOCATIONS), + .supported_contexts = BTTESTER_SUPPORTED_CTXTS + }; + struct ble_svc_audio_pacs_set_param snk_params = { + .audio_locations = MYNEWT_VAL(BLE_SVC_AUDIO_PACS_LC3_SRC_AUDIO_LOCATIONS), + .supported_contexts = BTTESTER_SUPPORTED_CTXTS + }; + + rc = ble_svc_audio_pacs_set(BLE_AUDIO_CODEC_DIR_SOURCE_BIT, &src_params); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_svc_audio_pacs_set(BLE_AUDIO_CODEC_DIR_SINK_BIT, &snk_params); + SYSINIT_PANIC_ASSERT(rc == 0); + + tester_register_command_handlers(BTP_SERVICE_ID_PACS, handlers, + ARRAY_SIZE(handlers)); + + return BTP_STATUS_SUCCESS; +} + +uint8_t +tester_unregister_pacs(void) +{ + return BTP_STATUS_SUCCESS; +} + +#endif /* MYNEWT_VAL(BLE_AUDIO)*/ diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index fea32fccd6..140b664e72 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -87,6 +87,7 @@ syscfg.defs: value: '"test_broadcast"' syscfg.vals: + BLE_AUDIO_MAX_CODEC_RECORDS: 3 CONSOLE_IMPLEMENTATION: full LOG_IMPLEMENTATION: full STATS_IMPLEMENTATION: full From 4e3ac5b6e7c7df63a594c4ff6839e266b4ccfed9 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 7 Nov 2024 09:44:30 +0100 Subject: [PATCH 1124/1333] nimble/host: Add Number Complete Packets event validation Validate if HCI event received from controller has proper sizes before passing it to GAP event --- nimble/host/src/ble_hs_hci_evt.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index a8b95108b5..47430423be 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -292,6 +292,10 @@ ble_hs_hci_evt_num_completed_pkts(uint8_t event_code, const void *data, uint16_t num_pkts; int i; + if (len < sizeof(*ev)) { + return BLE_HS_ECONTROLLER; + } + if (len != sizeof(*ev) + (ev->count * sizeof(ev->completed[0]))) { return BLE_HS_ECONTROLLER; } From 12b877e9d3ea4b83841fa18596c77938fa797be2 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 31 Oct 2024 14:27:46 +0100 Subject: [PATCH 1125/1333] nimble/audio/bass: Fix condition in address recognition This commit fixes logic for address recognition in add_source operation --- nimble/host/audio/services/bass/src/ble_audio_svc_bass.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index 8b5daf98c6..8dea91a505 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -329,7 +329,8 @@ ble_svc_audio_bass_add_source(uint8_t *data, uint16_t data_len, uint16_t conn_ha operation.conn_handle = conn_handle; operation.add_source.adv_addr.type = data[offset++]; - if (operation.add_source.adv_addr.type != BLE_ADDR_PUBLIC || + + if (operation.add_source.adv_addr.type != BLE_ADDR_PUBLIC && operation.add_source.adv_addr.type != BLE_ADDR_RANDOM) { rc = BLE_HS_EINVAL; ev.bass_operation_status.status = BLE_HS_EINVAL; From cdbd44d3612dc5d478d2491491cf05c11860e38b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 12 Nov 2024 14:07:23 +0100 Subject: [PATCH 1126/1333] Update missing licenses and rat excludes --- .rat-excludes | 3 +++ LICENSE | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.rat-excludes b/.rat-excludes index b0bf3e0977..0bd74f7249 100644 --- a/.rat-excludes +++ b/.rat-excludes @@ -34,3 +34,6 @@ system_nrf52.c # CMSIS-CORE - BSD License. cmsis_nvic.h + +# Linker scripts for Nordics nRF5X - TCL license +nrf5340-mcu.ld diff --git a/LICENSE b/LICENSE index 960e8257e9..ca697aee3f 100644 --- a/LICENSE +++ b/LICENSE @@ -225,3 +225,6 @@ missing licensing information. The BSD license was subsequently added to these files in later releases. These files are: * babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/cmsis_nvic.h +This product bundles part of linker scripts from Nordic Semiconductor, +which is available under the "modified Tcl/Tk" license. Bundled files are: + * targets/auracast_usb/nrf5340-mcu.ld From ca67e3015eec30eb97c853112441082d709e43ba Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 13 Nov 2024 13:12:42 +0100 Subject: [PATCH 1127/1333] Prepare for Apache NimBLE 1.8.0 release --- RELEASE_NOTES.md | 8 +++----- repository.yml | 4 ++++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index a34cd87526..3a83f16832 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,6 +1,6 @@ # RELEASE NOTES -27 March 2024 - Apache NimBLE v1.7.0 +13 November 2024 - Apache NimBLE v1.8.0 For full release notes, please visit the [Apache Mynewt Wiki](https://cwiki.apache.org/confluence/display/MYNEWT/Release+Notes). @@ -10,10 +10,8 @@ replaces the proprietary SoftDevice on Nordic chipsets. New features in this version of NimBLE include: -* Initial support for Enhanced ATT bearer -* Initial support for Broadcast Source and Auracast -* GATT host API additions -* Doxygen API comments overhaul +* Initial support for Channel Sounding (host) +* Support for SKY66405 FEM If working on next-generation RTOS and Bluetooth protocol stack sounds exciting to you, get in touch, by sending a mail to the Apache Mynewt diff --git a/repository.yml b/repository.yml index 8098429783..e8c6c655e6 100644 --- a/repository.yml +++ b/repository.yml @@ -33,6 +33,7 @@ repo.versions: "1.5.0": "nimble_1_5_0_tag" "1.6.0": "nimble_1_6_0_tag" "1.7.0": "nimble_1_7_0_tag" + "1.8.0": "nimble_1_8_0_tag" "1.0-latest": "1.0.0" "1.1-latest": "1.1.0" @@ -42,6 +43,7 @@ repo.versions: "1.5-latest": "1.5.0" "1.6-latest": "1.6.0" "1.7-latest": "1.7.0" + "1.8-latest": "1.8.0" repo.newt_compatibility: 0.0.0: @@ -62,3 +64,5 @@ repo.newt_compatibility: 1.11.0: good 1.7.0: 1.12.0: good + 1.8.0: + 1.13.0: good From 49d7a08ec58ef1b37d3f7f81aff20befcb14d930 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 25 Nov 2024 10:55:12 +0100 Subject: [PATCH 1128/1333] Apache NimBLE 1.8.0 release --- repository.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/repository.yml b/repository.yml index e8c6c655e6..8261ae866a 100644 --- a/repository.yml +++ b/repository.yml @@ -22,8 +22,8 @@ repo.versions: "0.0.0": "master" "0-dev": "0.0.0" - "0-latest": "1.7.0" - "1-latest": "1.7.0" + "0-latest": "1.8.0" + "1-latest": "1.8.0" "1.0.0": "nimble_1_0_0_tag" "1.1.0": "nimble_1_1_0_tag" From ca6a764dd792b02f277b4aec4233f4871d30d53c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 20 Nov 2024 01:40:16 +0100 Subject: [PATCH 1129/1333] nimble/host: Fix SMP command allocation os_mbuf_extend can allocate new mbuf if there's not enough space in txom for complete SMP command. In such case we write SMP command data to the original mbuf which doesn't have om_len updated instead to newly created mbuf. This can happen especially for SMP Public Key if block size is not large enough to fit pkthdr and 65 bytes of command data. We should use pointer returned from os_mbuf_extend as a SMP command data pointer as this always points to added space. --- nimble/host/src/ble_sm_cmd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_sm_cmd.c b/nimble/host/src/ble_sm_cmd.c index b84df1ec75..a740dc3ac2 100644 --- a/nimble/host/src/ble_sm_cmd.c +++ b/nimble/host/src/ble_sm_cmd.c @@ -29,18 +29,20 @@ void * ble_sm_cmd_get(uint8_t opcode, size_t len, struct os_mbuf **txom) { struct ble_sm_hdr *hdr; + void *data; *txom = ble_hs_mbuf_l2cap_pkt(); if (*txom == NULL) { return NULL; } - if (os_mbuf_extend(*txom, sizeof(*hdr) + len) == NULL) { + data = os_mbuf_extend(*txom, sizeof(*hdr) + len); + if (data == NULL) { os_mbuf_free_chain(*txom); return NULL; } - hdr = (struct ble_sm_hdr *)(*txom)->om_data; + hdr = (struct ble_sm_hdr *)data; hdr->opcode = opcode; From 9715855b54f278cdbf336b8f1e87ef642b243bf9 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Fri, 22 Nov 2024 15:05:19 +0100 Subject: [PATCH 1130/1333] nimble/ll: Set ext adv params v2 command bug fixes --- nimble/controller/src/ble_ll_adv.c | 2 +- nimble/controller/src/ble_ll_hci.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 1e56a8d454..3b36c87a53 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -3740,7 +3740,7 @@ ble_ll_adv_ext_set_param_v2(const uint8_t *cmdbuf, uint8_t len, advsm = ble_ll_adv_sm_get(cmd->params_v1.adv_handle); advsm->pri_phy = ble_ll_adv_ext_phy_mode_get(cmd->params_v1.pri_phy, cmd->pri_phy_opt); - advsm->sec_phy = ble_ll_adv_ext_phy_mode_get(cmd->params_v1.pri_phy, cmd->sec_phy_opt); + advsm->sec_phy = ble_ll_adv_ext_phy_mode_get(cmd->params_v1.sec_phy, cmd->sec_phy_opt); return rc; } diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 7e2d707bd8..b3e61ca2ef 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -779,6 +779,9 @@ ble_ll_is_valid_adv_mode(uint8_t ocf) #if MYNEWT_VAL(BLE_VERSION) >= 51 case BLE_HCI_OCF_LE_PERIODIC_ADV_RECEIVE_ENABLE: #endif +#if MYNEWT_VAL(BLE_VERSION) >= 54 + case BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM_V2: +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER) case BLE_HCI_OCF_LE_PERIODIC_ADV_SYNC_TRANSFER: case BLE_HCI_OCF_LE_PERIODIC_ADV_SET_INFO_TRANSFER: From 8a92ed1bf5e0b092055382b8150f92057d1c0479 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 18 Nov 2024 10:19:38 +0100 Subject: [PATCH 1131/1333] apps/bleprph: Adjust OS main stack Mcumgr image upload may require a bit more stack than current default. Make sure we are on safe side with default. --- apps/bleprph/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bleprph/syscfg.yml b/apps/bleprph/syscfg.yml index 0800f213ba..5f417d7cd7 100644 --- a/apps/bleprph/syscfg.yml +++ b/apps/bleprph/syscfg.yml @@ -62,7 +62,7 @@ syscfg.vals: CONFIG_MGMT: 1 # OS main/default task - OS_MAIN_STACK_SIZE: 512 + OS_MAIN_STACK_SIZE: 768 # Lots of smaller mbufs are required for smp using typical BLE ATT MTU # values. From 284b78443fae64c2b8535f1eb73c97681a35c01a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 25 Nov 2024 13:57:36 +0100 Subject: [PATCH 1132/1333] nimble/ll: Fix extended features for fake dual mode We do not have extended features pages so remove bit from standard features and make HCI Read Extended Featuers fail on page>0. --- nimble/controller/src/ble_ll_hci.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index b3e61ca2ef..4446f8a9b0 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1738,16 +1738,21 @@ ble_ll_hci_cmd_fake_dual_mode(uint16_t opcode, uint8_t *cmdbuf, uint8_t len, rc = 0; break; case BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT): - put_le64(rspbuf, 0x877bffdbfe0ffebf); + put_le64(rspbuf, 0x077bffdbfe0ffebf); *rsplen = 8; rc = 0; break; case BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, 0x04): /* Read Local Extended Features */ - rspbuf[0] = 0; + rspbuf[0] = cmdbuf[0]; rspbuf[1] = 0; - put_le64(&rspbuf[2], 0x877bffdbfe0ffebf); + if (rspbuf[0] == 0) { + put_le64(&rspbuf[2], 0x077bffdbfe0ffebf); + rc = 0; + } else { + put_le64(&rspbuf[2], 0); + rc = BLE_ERR_INV_HCI_CMD_PARMS; + } *rsplen = 10; - rc = 0; break; case BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_BUF_SIZE): put_le16(rspbuf, 255); From 1edcf65e19f6b8aba26f7f53840a57cebe74c66f Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Fri, 22 Nov 2024 14:50:20 +0100 Subject: [PATCH 1133/1333] nimble/ll: Add connection update support for CSS Now we only reject connection update requests if host or peripheral tries to change connection interval --- nimble/controller/src/ble_ll_conn_hci.c | 17 +++++++++--- nimble/controller/src/ble_ll_ctrl.c | 37 +++++++++++++++++-------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index a7bb136f70..f3ac72380f 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1029,11 +1029,11 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) } #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - /* Do not allow connection update if css in enabled, we only allow to move - * anchor point (i.e. change slot) via dedicated HCI command. - */ + /* We only allow to change connection parameters if conn_itvl can stay unchanged */ if (ble_ll_sched_css_is_enabled() && - connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { + connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL && + (connsm->conn_itvl < le16toh(cmd->conn_itvl_min) || + connsm->conn_itvl > le16toh(cmd->conn_itvl_max))) { return BLE_ERR_CMD_DISALLOWED; } #endif @@ -1098,8 +1098,13 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) /* Retrieve command data */ hcu = &connsm->conn_param_req; +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + hcu->conn_itvl_max = connsm->conn_itvl; + hcu->conn_itvl_min = connsm->conn_itvl; +#else hcu->conn_itvl_min = le16toh(cmd->conn_itvl_min); hcu->conn_itvl_max = le16toh(cmd->conn_itvl_max); +#endif hcu->conn_latency = le16toh(cmd->conn_latency); hcu->supervision_timeout = le16toh(cmd->supervision_timeout); hcu->min_ce_len = le16toh(cmd->min_ce_len); @@ -1116,6 +1121,10 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) if (!rc) { hcu->handle = handle; +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + connsm->css_slot_idx_pending = connsm->css_slot_idx; +#endif + /* Start the control procedure */ ble_ll_ctrl_proc_start(connsm, ctrl_proc, NULL); } diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 6902ba4958..85f98417a8 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -291,8 +291,25 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr, req->offset4 = get_le16(dptr + 19); req->offset5 = get_le16(dptr + 21); - /* Check if parameters are valid */ ble_err = BLE_ERR_SUCCESS; + +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + /* Allow to change connection parameters only if conn_itvl can stay unchanged + * and anchor point change is not requested */ + if (ble_ll_sched_css_is_enabled() && + connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL && + ((connsm->conn_itvl < le16toh(req->interval_min)) || + (connsm->conn_itvl > le16toh(req->interval_max)) || + (le16toh(req->offset0) != 0xffff))) { + ble_err = BLE_ERR_INV_LMP_LL_PARM; + goto conn_param_pdu_exit; + } + + req->interval_min = connsm->conn_itvl; + req->interval_max = connsm->conn_itvl; +#endif + + /* Check if parameters are valid */ rc = ble_ll_conn_hci_chk_conn_params(req->interval_min, req->interval_max, req->latency, @@ -380,6 +397,13 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr, rspbuf[1] = opcode; rspbuf[2] = ble_err; } + +#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) + if (!ble_err) { + connsm->css_slot_idx_pending = connsm->css_slot_idx; + } +#endif + return rsp_opcode; } @@ -2259,17 +2283,6 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr, return BLE_ERR_MAX; } -#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - /* Reject any attempts to change connection parameters by peripheral */ - if (ble_ll_sched_css_is_enabled() && - connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { - rsp_opcode = BLE_LL_CTRL_REJECT_IND_EXT; - rspbuf[1] = BLE_LL_CTRL_CONN_PARM_REQ; - rspbuf[2] = BLE_ERR_UNSUPPORTED; - return rsp_opcode; - } -#endif - /* XXX: remember to deal with this on the central: if the peripheral has * initiated a procedure we may have received its connection parameter * update request and have signaled the host with an event. If that From dc3ab0be3aa1aac8be9a7702a571df28e141464a Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 15 Nov 2024 15:09:31 +0100 Subject: [PATCH 1134/1333] btshell: Fix missing audio functionality inclusion This fixes audio shell functionality not being compiled. --- apps/btshell/pkg.yml | 3 +++ apps/btshell/src/btshell.h | 4 ++++ apps/btshell/src/cmd_leaudio.c | 2 ++ nimble/host/audio/targets/btshell_native/syscfg.yml | 1 + 4 files changed, 10 insertions(+) diff --git a/apps/btshell/pkg.yml b/apps/btshell/pkg.yml index d98f541f06..79b0dcfa3e 100644 --- a/apps/btshell/pkg.yml +++ b/apps/btshell/pkg.yml @@ -38,3 +38,6 @@ pkg.deps: pkg.deps.BTSHELL_ANS: - nimble/host/services/ans + +pkg.deps.BLE_AUDIO: + - nimble/host/audio diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h index 3d94c21204..f035f6b023 100644 --- a/apps/btshell/src/btshell.h +++ b/apps/btshell/src/btshell.h @@ -222,7 +222,11 @@ int btshell_broadcast_start(uint8_t adv_instance); int btshell_broadcast_stop(uint8_t adv_instance); #endif +#if MYNEWT_VAL(BLE_AUDIO) void btshell_leaudio_init(void); +#else +#define btshell_leaudio_init() +#endif /* BLE_AUDIO */ int btshell_gap_event(struct ble_gap_event *event, void *arg); void btshell_sync_stats(uint16_t handle); diff --git a/apps/btshell/src/cmd_leaudio.c b/apps/btshell/src/cmd_leaudio.c index cea206b6e0..bd243dfd4f 100644 --- a/apps/btshell/src/cmd_leaudio.c +++ b/apps/btshell/src/cmd_leaudio.c @@ -26,6 +26,7 @@ #define STR_NULL "null" +#if (MYNEWT_VAL(BLE_AUDIO)) #if (MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)) #include "audio/ble_audio_broadcast_source.h" int @@ -1086,3 +1087,4 @@ btshell_leaudio_init(void) #endif /* BLE_AUDIO_BROADCAST_SINK */ assert(rc == 0); } +#endif /* BLE_AUDIO */ diff --git a/nimble/host/audio/targets/btshell_native/syscfg.yml b/nimble/host/audio/targets/btshell_native/syscfg.yml index 3c04c0c12e..cf2d410487 100644 --- a/nimble/host/audio/targets/btshell_native/syscfg.yml +++ b/nimble/host/audio/targets/btshell_native/syscfg.yml @@ -64,6 +64,7 @@ syscfg.vals: BLE_ISO_MAX_BIGS: 1 BLE_ISO_MAX_BISES: 2 + BLE_AUDIO: 1 BLE_AUDIO_BROADCAST_SINK: 1 BLE_AUDIO_SCAN_DELEGATOR: 1 From 9660042277834ef684b6187bb6fd7b8c3d47a249 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 15 Nov 2024 15:14:03 +0100 Subject: [PATCH 1135/1333] btshell: Fix print format specifiers This fixes various compilation issues related to usage of invalid format specifiers. Tested on native and nrf5340. repos/apache-mynewt-nimble/apps/btshell/src/cmd_leaudio.c:724:39: error: format '%x' expects argument of type 'unsigned int', but argument 2 has type 'uint32_t' {aka 'long unsigned int'} [-Werror=format=] 724 | console_printf("broadcast_id=0x%06x adv_sid=%d adv_addr_type=%s adv_addr=", | ~~~^ | | | unsigned int | %06lx 725 | source_desc->broadcast_id, source_desc->adv_sid, | ~~~~~~~~~~~~~~~~~~~~~~~~~ | | | uint32_t {aka long unsigned int} cc1: all warnings being treated as errors --- apps/btshell/src/cmd_iso.c | 4 ++-- apps/btshell/src/cmd_leaudio.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/btshell/src/cmd_iso.c b/apps/btshell/src/cmd_iso.c index 3383c379f3..cd6046082c 100644 --- a/apps/btshell/src/cmd_iso.c +++ b/apps/btshell/src/cmd_iso.c @@ -107,8 +107,8 @@ iso_rx_stats_update(uint16_t conn_handle, const struct ble_iso_rx_data_info *inf stats->total_cnt++; if ((stats->total_cnt % 100) == 0) { - console_printf("conn_handle=0x%04x, seq_num=%d, num_rx=%lld, " - "(valid=%lld, error=%lld, lost=%lld) ", + console_printf("conn_handle=0x%04x, seq_num=%d, num_rx=%" PRIu64 ", " + "(valid=%" PRIu64 ", error=%" PRIu64 ", lost=%" PRIu64 ") ", stats->conn_handle, stats->seq_num, stats->total_cnt, stats->valid_cnt, stats->error_cnt, stats->lost_cnt); diff --git a/apps/btshell/src/cmd_leaudio.c b/apps/btshell/src/cmd_leaudio.c index bd243dfd4f..8cc3e5457a 100644 --- a/apps/btshell/src/cmd_leaudio.c +++ b/apps/btshell/src/cmd_leaudio.c @@ -482,7 +482,7 @@ broadcast_sink_action_fn(struct ble_audio_broadcast_sink_action *action, void *a return broadcast_sink_pa_sync_params_get(action->pa_sync.out_params); case BLE_AUDIO_BROADCAST_SINK_ACTION_BIG_SYNC: console_printf("BIG Sync:\nsource_id=0x%02x iso_interval=0x%04x" - " presentation_delay=%u[us]\n", + " presentation_delay=%" PRIu32 "[us]\n", action->big_sync.source_id, action->big_sync.iso_interval, action->big_sync.presentation_delay); break; @@ -684,7 +684,7 @@ broadcast_sink_audio_event_handler(struct ble_audio_event *event, void *arg) static void scan_delegator_source_desc_printf(const struct ble_audio_scan_delegator_source_desc *source_desc) { - console_printf("broadcast_id=0x%6x adv_sid=%d adv_addr_type=%s adv_addr=", + console_printf("broadcast_id=0x%06" PRIx32 " adv_sid=%d adv_addr_type=%s adv_addr=", source_desc->broadcast_id, source_desc->adv_sid, cmd_addr_type_str(source_desc->addr.type)); print_addr(source_desc->addr.val); @@ -697,7 +697,7 @@ scan_delegator_sync_opt_printf(const struct ble_audio_scan_delegator_sync_opt *s console_printf("pa_sync=%d pa_interval=0x%04x num_subgroups=%d", sync_opt->pa_sync, sync_opt->pa_interval, sync_opt->num_subgroups); for (uint8_t i = 0; i < sync_opt->num_subgroups; i++) { - console_printf("\n\tbis_sync=0x%04x metadata_length=%d metadata=", + console_printf("\n\tbis_sync=0x%04" PRIx32 " metadata_length=%d metadata=", sync_opt->subgroups[i].bis_sync, sync_opt->subgroups[i].metadata_length); print_bytes(sync_opt->subgroups[i].metadata, sync_opt->subgroups[i].metadata_length); } @@ -957,7 +957,7 @@ scan_delegator_receive_state_printf(const struct ble_audio_scan_delegator_receiv } for (uint8_t i = 0; i < state->num_subgroups; i++) { - console_printf("\n\tbis_sync=0x%04x metadata_length=%d metadata=", + console_printf("\n\tbis_sync=0x%04" PRIu32 " metadata_length=%d metadata=", state->subgroups[i].bis_sync, state->subgroups[i].metadata_length); print_bytes(state->subgroups[i].metadata, state->subgroups[i].metadata_length); console_printf("\n"); @@ -1045,7 +1045,7 @@ scan_delegator_audio_event_handler(struct ble_audio_event *event, void *arg) switch (event->type) { case BLE_AUDIO_EVENT_BROADCAST_ANNOUNCEMENT: console_printf("Broadcast Announcement\n"); - console_printf("broadcast_id=0x%6x adv_sid=%d addr_type=%s addr=", + console_printf("broadcast_id=0x%06" PRIx32 " adv_sid=%d addr_type=%s addr=", event->broadcast_announcement.broadcast_id, event->broadcast_announcement.ext_disc->sid, cmd_addr_type_str(event->broadcast_announcement.ext_disc->addr.type)); From 02161763f12869b11a4670f06ba8cc7f89eb79f3 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 15 Nov 2024 15:15:57 +0100 Subject: [PATCH 1136/1333] bass: Fix duplicated code This fixes duplicated code by using ble_svc_audio_bass_receive_state_free function when Receive State instance is cleared. --- nimble/host/audio/services/bass/src/ble_audio_svc_bass.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index 8dea91a505..516e202855 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -245,7 +245,9 @@ ble_svc_audio_bass_receive_state_find_free(struct ble_svc_audio_bass_rcv_state_e static void ble_svc_audio_bass_receive_state_free(struct ble_svc_audio_bass_rcv_state_entry *state) { + memset(&state->state, 0, sizeof(state->state)); state->source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE; + /* state->chr_val shall not be cleared */ } static int @@ -637,8 +639,7 @@ ble_svc_audio_bass_remove_source(uint8_t *data, uint16_t data_len, uint16_t conn os_memblock_put(&ble_audio_svc_bass_metadata_pool, rcv_state->state.subgroups[i].metadata); } - memset(rcv_state, 0, sizeof(*rcv_state)); - rcv_state->source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE; + ble_svc_audio_bass_receive_state_free(rcv_state); done: if (!rc) { @@ -809,8 +810,7 @@ ble_svc_audio_bass_receive_state_remove(uint8_t source_id) return rc; } - memset(&rcv_state->state, 0, sizeof(rcv_state->state)); - rcv_state->source_id = BLE_SVC_AUDIO_BASS_RECEIVE_STATE_SRC_ID_NONE; + ble_svc_audio_bass_receive_state_free(rcv_state); for (i = 0; i < rcv_state->state.num_subgroups; i++) { os_memblock_put(&ble_audio_svc_bass_metadata_pool, rcv_state->state.subgroups[i].metadata); From 5f3a3678696acf36943d0835fa1538c9109a0b56 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 18 Nov 2024 11:15:25 +0100 Subject: [PATCH 1137/1333] bass: Fix control point parameters lenght check This fixes the parameters length check and simplifies the buffer operations a bit. --- .../services/bass/src/ble_audio_svc_bass.c | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c index 516e202855..61c03f8c36 100644 --- a/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c +++ b/nimble/host/audio/services/bass/src/ble_audio_svc_bass.c @@ -89,8 +89,8 @@ ble_svc_audio_bass_rcv_state_read_access(struct ble_gatt_access_ctxt *ctxt, void static struct ble_svc_audio_bass_ctrl_point_handler { uint8_t op_code; - uint8_t length_min; - uint8_t length_max; + int16_t length_min; + int16_t length_max; ble_svc_audio_bass_ctrl_point_handler_cb *handler_cb; } ble_svc_audio_bass_ctrl_point_handlers[] = { { @@ -670,10 +670,15 @@ static int ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt, uint16_t conn_handle) { uint8_t opcode; - uint16_t mbuf_len = OS_MBUF_PKTLEN(ctxt->om); struct ble_svc_audio_bass_ctrl_point_handler *handler; + ctxt->om = os_mbuf_pullup(ctxt->om, OS_MBUF_PKTLEN(ctxt->om)); + if (!ctxt->om) { + return BLE_ATT_ERR_UNLIKELY; + } + opcode = ctxt->om->om_data[0]; + os_mbuf_adj(ctxt->om, sizeof(opcode)); handler = ble_svc_audio_bass_find_handler(opcode); @@ -681,18 +686,12 @@ ble_svc_audio_bass_ctrl_point_write_access(struct ble_gatt_access_ctxt *ctxt, ui return BLE_SVC_AUDIO_BASS_ERR_OPCODE_NOT_SUPPORTED; } - if (ctxt->om->om_len - 1 < handler->length_min && - handler->length_max >= 0 ? - ctxt->om->om_len > handler->length_max : 0) { + if ((handler->length_min != BLE_SVC_AUDIO_BASS_CHR_LEN_UNLIMITED && (ctxt->om->om_len < handler->length_min)) || + (handler->length_max != BLE_SVC_AUDIO_BASS_CHR_LEN_UNLIMITED && (ctxt->om->om_len > handler->length_max))) { return BLE_ATT_ERR_WRITE_REQ_REJECTED; } - ctxt->om = os_mbuf_pullup(ctxt->om, mbuf_len); - if (!ctxt->om) { - return BLE_ATT_ERR_UNLIKELY; - } - - return handler->handler_cb(&ctxt->om->om_data[1], mbuf_len - 1, conn_handle); + return handler->handler_cb(ctxt->om->om_data, OS_MBUF_PKTLEN(ctxt->om), conn_handle); } static int From aff2ce3da2984567c6114bc55e8428ffb0aaedae Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 15 Nov 2024 15:23:25 +0100 Subject: [PATCH 1138/1333] btshell: Remove unused header include This removes unused header include. --- apps/btshell/src/btshell.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/btshell/src/btshell.h b/apps/btshell/src/btshell.h index f035f6b023..d8bf83d2ff 100644 --- a/apps/btshell/src/btshell.h +++ b/apps/btshell/src/btshell.h @@ -28,9 +28,6 @@ #include "host/ble_gatt.h" #include "host/ble_gap.h" -#if (MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)) -#include "audio/ble_audio_broadcast_source.h" -#endif #ifdef __cplusplus extern "C" { From a8a4c327da263115ea1e6bc80cea2fe4046e5f14 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Fri, 15 Nov 2024 15:26:01 +0100 Subject: [PATCH 1139/1333] btshell: Fix ISO Broadcast Source build without BLE Audio This fixes building ISO Broadcast Source enabled target with BLE Audio functionality disabled. --- apps/btshell/src/cmd.c | 8 ++++---- apps/btshell/src/main.c | 16 ++++++++-------- nimble/host/src/ble_hs.c | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index a9758e14b2..aad564a1a6 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -4235,7 +4235,7 @@ static const struct shell_cmd_help sync_stats_help = { #endif #endif -#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) +#if MYNEWT_VAL(BLE_AUDIO) && MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) #if MYNEWT_VAL(SHELL_CMD_HELP) static const struct shell_param leaudio_base_add_params[] = { {"adv_instance", "Advertising instance, usage: ="}, @@ -4367,7 +4367,7 @@ static const struct shell_cmd_help leaudio_broadcast_stop_help = { .params = leaudio_broadcast_stop_params, }; #endif -#endif +#endif /* BLE_AUDIO && BLE_ISO_BROADCAST_SOURCE */ static const struct shell_cmd btshell_commands[] = { #if MYNEWT_VAL(BLE_EXT_ADV) @@ -4887,7 +4887,7 @@ static const struct shell_cmd btshell_commands[] = { }, #endif #endif -#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) +#if MYNEWT_VAL(BLE_AUDIO) && MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) { .sc_cmd = "base_add", .sc_cmd_func = cmd_leaudio_base_add, @@ -4944,7 +4944,7 @@ static const struct shell_cmd btshell_commands[] = { .help = &leaudio_broadcast_stop_help, #endif }, -#endif +#endif /* BLE_AUDIO && BLE_ISO_BROADCAST_SOURCE */ #if MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK) { .sc_cmd = "broadcast-sink-start", diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index 7292927654..410fb5a453 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -41,10 +41,10 @@ #include "host/ble_gatt.h" #include "host/ble_store.h" #include "host/ble_sm.h" -#if MYNEWT_VAL(BLE_AUDIO) +#if MYNEWT_VAL(BLE_AUDIO) && MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) #include "audio/ble_audio_broadcast_source.h" #include "audio/ble_audio.h" -#endif +#endif /* BLE_AUDIO && BLE_ISO_BROADCAST_SOURCE */ #include "host/util/util.h" /* Mandatory services. */ @@ -132,7 +132,7 @@ int btshell_full_disc_prev_chr_val; struct ble_sm_sc_oob_data oob_data_local; struct ble_sm_sc_oob_data oob_data_remote; -#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) +#if MYNEWT_VAL(BLE_AUDIO) && MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) static struct {struct ble_audio_base *base; uint8_t adv_instance;} btshell_base_list[MYNEWT_VAL(BLE_ISO_MAX_BIGS)]; @@ -181,7 +181,7 @@ static os_membuf_t btshell_big_params_mem[ OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BIGS), sizeof(struct ble_iso_big_params)) ]; static struct os_mempool btshell_big_params_pool; -#endif +#endif /* BLE_AUDIO && BLE_ISO_BROADCAST_SOURCE */ #define XSTR(s) STR(s) #ifndef STR @@ -2768,7 +2768,7 @@ btshell_get_default_own_addr_type(void) return default_own_addr_type; } -#if (MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)) +#if MYNEWT_VAL(BLE_AUDIO) && MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) static int btshell_base_find_free(void) { @@ -3036,7 +3036,7 @@ btshell_broadcast_stop(uint8_t adv_instance) { return ble_audio_broadcast_stop(adv_instance); } -#endif +#endif /* BLE_AUDIO && BLE_ISO_BROADCAST_SOURCE */ /** * main @@ -3087,7 +3087,7 @@ mynewt_main(int argc, char **argv) "btshell_coc_conn_pool"); assert(rc == 0); #endif -#if (MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE)) +#if MYNEWT_VAL(BLE_AUDIO) && MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) rc = os_mempool_init(&btshell_base_pool, MYNEWT_VAL(BLE_ISO_MAX_BIGS), sizeof(struct ble_audio_base), btshell_base_mem, @@ -3123,7 +3123,7 @@ mynewt_main(int argc, char **argv) sizeof(struct ble_iso_big_params), btshell_big_params_mem, "btshell_big_params_pool"); assert(rc == 0); -#endif +#endif /* BLE_AUDIO && BLE_ISO_BROADCAST_SOURCE */ /* Initialize the NimBLE host configuration. */ ble_hs_cfg.reset_cb = btshell_on_reset; ble_hs_cfg.sync_cb = btshell_on_sync; diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index bac7f02e6a..70a4aa6c9d 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -24,9 +24,9 @@ #include "syscfg/syscfg.h" #include "stats/stats.h" #include "host/ble_hs.h" -#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) +#if MYNEWT_VAL(BLE_AUDIO) && MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) #include "audio/ble_audio_broadcast_source.h" -#endif +#endif /* BLE_AUDIO && BLE_ISO_BROADCAST_SOURCE */ #include "ble_hs_priv.h" #include "ble_iso_priv.h" #include "nimble/nimble_npl.h" @@ -759,10 +759,10 @@ ble_hs_init(void) #if MYNEWT_VAL(BLE_ISO) rc = ble_iso_init(); SYSINIT_PANIC_ASSERT(rc == 0); -#if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) +#if MYNEWT_VAL(BLE_AUDIO) && MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) rc = ble_audio_broadcast_init(); SYSINIT_PANIC_ASSERT(rc == 0); -#endif +#endif /* BLE_AUDIO && BLE_ISO_BROADCAST_SOURCE */ #endif #if MYNEWT_VAL(BLE_AUDIO_MAX_CODEC_RECORDS) From ef6afc456f3acd952f3206830c94424fa1378723 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 18 Nov 2024 09:29:22 +0100 Subject: [PATCH 1140/1333] btshell: Add 'broadcast-sink-set-sync-params' command This adds 'broadcast-sink-set-sync-params' commands to be used to set the PA Sync parameters to be used. --- apps/btshell/src/cmd.c | 7 ++++ apps/btshell/src/cmd_leaudio.c | 60 +++++++++++++++++++++++++++------- apps/btshell/src/cmd_leaudio.h | 2 ++ 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index aad564a1a6..87f5d9f1de 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -4965,6 +4965,13 @@ static const struct shell_cmd btshell_commands[] = { .sc_cmd_func = cmd_leaudio_broadcast_sink_metadata_update, #if MYNEWT_VAL(SHELL_CMD_HELP) .help = &cmd_leaudio_broadcast_sink_metadata_update_help, +#endif + }, + { + .sc_cmd = "broadcast-sink-set-sync-params", + .sc_cmd_func = cmd_leaudio_broadcast_sink_sync_params_set, +#if MYNEWT_VAL(SHELL_CMD_HELP) + .help = &cmd_leaudio_broadcast_sink_sync_params_set_help, #endif }, #endif /* BLE_AUDIO_BROADCAST_SINK */ diff --git a/apps/btshell/src/cmd_leaudio.c b/apps/btshell/src/cmd_leaudio.c index 8cc3e5457a..3e3a685e02 100644 --- a/apps/btshell/src/cmd_leaudio.c +++ b/apps/btshell/src/cmd_leaudio.c @@ -392,17 +392,14 @@ cmd_leaudio_broadcast_stop(int argc, char **argv) #if (MYNEWT_VAL(BLE_AUDIO_BROADCAST_SINK)) #include "audio/ble_audio_broadcast_sink.h" -#define BROADCAST_SINK_PA_SYNC_TIMEOUT_DEFAULT 0x07D0 +#define BROADCAST_SINK_PA_SYNC_SKIP_DFLT 0x0000 +#define BROADCAST_SINK_PA_SYNC_TIMEOUT_DFLT 0x07D0 -static int -broadcast_sink_pa_sync_params_get(struct ble_gap_periodic_sync_params *params) -{ - params->skip = 0; - params->sync_timeout = BROADCAST_SINK_PA_SYNC_TIMEOUT_DEFAULT; - params->reports_disabled = false; - - return 0; -} +static struct ble_gap_periodic_sync_params broadcast_sink_periodic_sync_params = { + .skip = BROADCAST_SINK_PA_SYNC_SKIP_DFLT, + .sync_timeout = BROADCAST_SINK_PA_SYNC_TIMEOUT_DFLT, + .reports_disabled = false +}; static void codec_specific_config_printf(const struct ble_audio_codec_id *unused, const uint8_t *data, @@ -479,7 +476,8 @@ broadcast_sink_action_fn(struct ble_audio_broadcast_sink_action *action, void *a switch (action->type) { case BLE_AUDIO_BROADCAST_SINK_ACTION_PA_SYNC: console_printf("PA Sync:\n"); - return broadcast_sink_pa_sync_params_get(action->pa_sync.out_params); + *action->pa_sync.out_params = broadcast_sink_periodic_sync_params; + break; case BLE_AUDIO_BROADCAST_SINK_ACTION_BIG_SYNC: console_printf("BIG Sync:\nsource_id=0x%02x iso_interval=0x%04x" " presentation_delay=%" PRIu32 "[us]\n", @@ -648,6 +646,46 @@ cmd_leaudio_broadcast_sink_metadata_update(int argc, char **argv) return rc; } +#if MYNEWT_VAL(SHELL_CMD_HELP) +static const struct shell_param cmd_leaudio_broadcast_sink_sync_params_set_params[] = { + {"skip", "usage: =[0x0000-0x01F3], default: 0x0000"}, + {"sync_timeout", "usage: =[0x000A-0x4000], default: 0x07D0"}, + {NULL, NULL} +}; + +const struct shell_cmd_help cmd_leaudio_broadcast_sink_sync_params_set_help = { + .summary = "Set Broadcast Sink sync parameters", + .usage = NULL, + .params = cmd_leaudio_broadcast_sink_sync_params_set_params +}; +#endif /* SHELL_CMD_HELP */ + +int +cmd_leaudio_broadcast_sink_sync_params_set(int argc, char **argv) +{ + int rc; + + rc = parse_arg_init(argc - 1, argv + 1); + if (rc != 0) { + return rc; + } + + broadcast_sink_periodic_sync_params.skip = parse_arg_uint16_dflt("skip", BROADCAST_SINK_PA_SYNC_SKIP_DFLT, &rc); + if (rc != 0) { + console_printf("invalid 'skip' parameter\n"); + return rc; + } + + broadcast_sink_periodic_sync_params.sync_timeout = parse_arg_time_dflt("sync_timeout", 10000, + BROADCAST_SINK_PA_SYNC_TIMEOUT_DFLT, &rc); + if (rc != 0) { + console_printf("invalid 'sync_timeout' parameter\n"); + return rc; + } + + return rc; +} + static int broadcast_sink_audio_event_handler(struct ble_audio_event *event, void *arg) { diff --git a/apps/btshell/src/cmd_leaudio.h b/apps/btshell/src/cmd_leaudio.h index 477b33a21f..1704c6f4da 100644 --- a/apps/btshell/src/cmd_leaudio.h +++ b/apps/btshell/src/cmd_leaudio.h @@ -46,10 +46,12 @@ int cmd_leaudio_broadcast_stop(int argc, char **argv); extern const struct shell_cmd_help cmd_leaudio_broadcast_sink_start_help; extern const struct shell_cmd_help cmd_leaudio_broadcast_sink_stop_help; extern const struct shell_cmd_help cmd_leaudio_broadcast_sink_metadata_update_help; +extern const struct shell_cmd_help cmd_leaudio_broadcast_sink_sync_params_set_help; int cmd_leaudio_broadcast_sink_start(int argc, char **argv); int cmd_leaudio_broadcast_sink_stop(int argc, char **argv); int cmd_leaudio_broadcast_sink_metadata_update(int argc, char **argv); +int cmd_leaudio_broadcast_sink_sync_params_set(int argc, char **argv); extern const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_add_help; extern const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_remove_help; From 9c0dee60d2e11e4ab8ba8979d8bb54486f6f78b4 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 18 Nov 2024 10:39:54 +0100 Subject: [PATCH 1141/1333] btshell: Fix build with SHELL_CMD_HELP option disabled This fixes btshell application compilation errors with SHELL_CMD_HELP option disabled. --- apps/btshell/src/cmd.c | 2 +- apps/btshell/src/cmd_leaudio.c | 27 ++++++++++++--------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index 87f5d9f1de..ba47ee7456 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -4152,13 +4152,13 @@ static const struct shell_param sync_transfer_receive_params[] = { {"reports_disabled", "disable reports, usage: =[0-1], default: 0"}, {NULL, NULL} }; -#endif static const struct shell_cmd_help sync_transfer_receive_help = { .summary = "start/stop periodic sync reception with specific parameters", .usage = NULL, .params = sync_transfer_receive_params, }; +#endif /* SHELL_CMD_HELP */ #endif static int diff --git a/apps/btshell/src/cmd_leaudio.c b/apps/btshell/src/cmd_leaudio.c index 3e3a685e02..84545d06dc 100644 --- a/apps/btshell/src/cmd_leaudio.c +++ b/apps/btshell/src/cmd_leaudio.c @@ -502,20 +502,19 @@ broadcast_sink_action_fn(struct ble_audio_broadcast_sink_action *action, void *a return 0; } - +#if MYNEWT_VAL(SHELL_CMD_HELP) static const struct shell_param cmd_leaudio_broadcast_sink_start_params[] = { {"source_id", "usage: ="}, {"broadcast_code", "usage: =[string], default: NULL"}, {NULL, NULL} }; -#if MYNEWT_VAL(SHELL_CMD_HELP) const struct shell_cmd_help cmd_leaudio_broadcast_sink_start_help = { .summary = "Start audio Broadcast Sink", .usage = NULL, .params = cmd_leaudio_broadcast_sink_start_params }; -#endif +#endif /* SHELL_CMD_HELP */ int cmd_leaudio_broadcast_sink_start(int argc, char **argv) @@ -550,18 +549,18 @@ cmd_leaudio_broadcast_sink_start(int argc, char **argv) return rc; } +#if MYNEWT_VAL(SHELL_CMD_HELP) static const struct shell_param cmd_leaudio_broadcast_sink_stop_params[] = { {"source_id", "usage: ="}, {NULL, NULL} }; -#if MYNEWT_VAL(SHELL_CMD_HELP) const struct shell_cmd_help cmd_leaudio_broadcast_sink_stop_help = { .summary = "Stop audio Broadcast Sink", .usage = NULL, .params = cmd_leaudio_broadcast_sink_stop_params }; -#endif +#endif /* SHELL_CMD_HELP */ int cmd_leaudio_broadcast_sink_stop(int argc, char **argv) @@ -588,6 +587,7 @@ cmd_leaudio_broadcast_sink_stop(int argc, char **argv) return rc; } +#if MYNEWT_VAL(SHELL_CMD_HELP) static const struct shell_param cmd_leaudio_broadcast_sink_metadata_update_params[] = { {"source_id", "usage: ="}, {"subgroup_index", "usage: ="}, @@ -595,13 +595,12 @@ static const struct shell_param cmd_leaudio_broadcast_sink_metadata_update_param {NULL, NULL} }; -#if MYNEWT_VAL(SHELL_CMD_HELP) const struct shell_cmd_help cmd_leaudio_broadcast_sink_metadata_update_help = { .summary = "Update Broadcast Sink metadata", .usage = NULL, .params = cmd_leaudio_broadcast_sink_metadata_update_params }; -#endif +#endif /* SHELL_CMD_HELP */ int cmd_leaudio_broadcast_sink_metadata_update(int argc, char **argv) @@ -779,6 +778,7 @@ scan_delegator_action_fn(struct ble_audio_scan_delegator_action *action, void *a return 0; } +#if MYNEWT_VAL(SHELL_CMD_HELP) static const struct shell_param cmd_leaudio_scan_delegator_receive_state_add_params[] = { {"addr_type", "usage: =[public|random], default: public"}, {"addr", "usage: =[XX:XX:XX:XX:XX:XX]"}, @@ -787,7 +787,6 @@ static const struct shell_param cmd_leaudio_scan_delegator_receive_state_add_par {NULL, NULL} }; -#if MYNEWT_VAL(SHELL_CMD_HELP) const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_add_help = { .summary = "Add receive state", .usage = NULL, @@ -835,12 +834,12 @@ cmd_leaudio_scan_delegator_receive_state_add(int argc, char **argv) return rc; } +#if MYNEWT_VAL(SHELL_CMD_HELP) static const struct shell_param cmd_leaudio_scan_delegator_receive_state_remove_params[] = { {"source_id", "usage: ="}, {NULL, NULL} }; -#if MYNEWT_VAL(SHELL_CMD_HELP) const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_remove_help = { .summary = "Remove receive state", .usage = NULL, @@ -890,17 +889,15 @@ const struct parse_arg_kv_pair cmd_big_enc_type[] = { { NULL } }; +#if MYNEWT_VAL(SHELL_CMD_HELP) static const struct shell_param cmd_leaudio_scan_delegator_receive_state_set_params[] = { {"source_id", "usage: ="}, - {"pa_sync_state", "usage: =[not_synced|sync_info_req|synced|failed|no_past]," - " default: not_synced"}, - {"big_enc", "usage: =[not_encrypted|code_req|decrypting|bad_code]," - " default: not_encrypted"}, + {"pa_sync_state", "usage: =[not_synced|sync_info_req|synced|failed|no_past], default: not_synced"}, + {"big_enc", "usage: =[not_encrypted|code_req|decrypting|bad_code], default: not_encrypted"}, {"bad_code", "usage: =[string], default: NULL"}, {NULL, NULL} }; -#if MYNEWT_VAL(SHELL_CMD_HELP) const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_set_help = { .summary = "Set receive state", .usage = NULL, @@ -1002,12 +999,12 @@ scan_delegator_receive_state_printf(const struct ble_audio_scan_delegator_receiv } } +#if MYNEWT_VAL(SHELL_CMD_HELP) static const struct shell_param cmd_leaudio_scan_delegator_receive_state_get_params[] = { {"source_id", "usage: ="}, {NULL, NULL} }; -#if MYNEWT_VAL(SHELL_CMD_HELP) const struct shell_cmd_help cmd_leaudio_scan_delegator_receive_state_get_help = { .summary = "Get receive state", .usage = NULL, From 4752ca35faf1f05ddbbb47084dba1b716e606bf2 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 25 Nov 2024 12:58:27 +0100 Subject: [PATCH 1142/1333] ci: Build with Broadcast Sink and Scan Delegator enabled This adds Broadcast Sink and Scan Delegator to CI syscfg to build all applications with those options enabled. --- .github/test_build_apps_syscfg.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/test_build_apps_syscfg.yml b/.github/test_build_apps_syscfg.yml index 9887918b43..a83a5c3d87 100644 --- a/.github/test_build_apps_syscfg.yml +++ b/.github/test_build_apps_syscfg.yml @@ -28,6 +28,9 @@ syscfg.vals: BLE_ISO: 1 BLE_ISO_TEST: 1 BLE_AUDIO: 1 + BLE_AUDIO_BROADCAST_SINK: 1 + BLE_AUDIO_SCAN_DELEGATOR: 1 + BLE_ISO_BROADCAST_SINK: 1 BLE_ISO_BROADCAST_SOURCE: 1 BLE_HCI_VS: 1 BLE_POWER_CONTROL: 1 From bc190e4f1c00ae05201359c29c5c2bf94d9c0c59 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 26 Nov 2024 09:01:43 +0100 Subject: [PATCH 1143/1333] ci: Update CodeQL actions V2 are being deprecated. --- .github/workflows/codeql.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 816492278e..cc4b6c74b3 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -51,7 +51,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -66,7 +66,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). # If this step fails, then you should remove it and run the build manually (see below) #- name: Autobuild - # uses: github/codeql-action/autobuild@v2 + # uses: github/codeql-action/autobuild@v3 # ℹ️ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -78,7 +78,7 @@ jobs: ./.github/workflows/codeql-buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" upload: false @@ -107,14 +107,14 @@ jobs: output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif - name: Upload CodeQL results to code scanning - uses: github/codeql-action/upload-sarif@v2 + uses: github/codeql-action/upload-sarif@v3 with: sarif_file: ${{ steps.step1.outputs.sarif-output }} category: "/language:${{matrix.language}}" - name: Upload CodeQL results as an artifact if: success() || failure() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: codeql-results path: ${{ steps.step1.outputs.sarif-output }} From 0a605c9425fb562a28105fa8e0bd6376de6ef46a Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Wed, 27 Nov 2024 08:48:12 +0100 Subject: [PATCH 1144/1333] nimble/ll: make includes config dependent The call to ble_ll_isoal_reset() is behind define, but include was not. Same for iso_big. --- nimble/controller/src/ble_ll.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index f2fc37d6d1..4e0a74c537 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -46,8 +46,12 @@ #include "controller/ble_ll_trace.h" #include "controller/ble_ll_sync.h" #include "controller/ble_fem.h" +#if MYNEWT_VAL(BLE_LL_ISO) #include "controller/ble_ll_isoal.h" +#endif +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) #include "controller/ble_ll_iso_big.h" +#endif #if MYNEWT_VAL(BLE_LL_EXT) #include "controller/ble_ll_ext.h" #endif From a220f6679461ec25f280e3ba818ee924a0692ee7 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 12 Nov 2024 12:49:56 +0100 Subject: [PATCH 1145/1333] nimble/ll: Check scheduler before sending connection request We should not attempt to initiate connection if there's not enough time left for connection req/rsp before next scheduling item, otherwise it may be corrupted since scheduler will forcibly disable phy before executing new item. --- nimble/controller/src/ble_ll_conn.c | 34 ++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 789b948aad..c671a39969 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3221,24 +3221,46 @@ ble_ll_conn_send_connect_req(struct os_mbuf *rxpdu, { struct ble_ll_conn_sm *connsm; struct ble_mbuf_hdr *rxhdr; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) uint8_t phy; -#endif + uint8_t phy_mode; + uint32_t sch_next; + uint32_t conn_req_us; + uint32_t conn_req_end; int rc; connsm = g_ble_ll_conn_create_sm.connsm; rxhdr = BLE_MBUF_HDR_PTR(rxpdu); -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - if (ext) { #if MYNEWT_VAL(BLE_LL_PHY) - phy = rxhdr->rxinfo.phy; + phy = rxhdr->rxinfo.phy; + phy_mode = rxhdr->rxinfo.phy_mode; #else - phy = BLE_PHY_1M; + phy = BLE_PHY_1M; + phy_mode = BLE_PHY_MODE_1M; #endif + +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + if (ext) { ble_ll_conn_create_set_params(connsm, phy); } +#else + (void)phy; +#endif + + rc = ble_ll_sched_next_time(&sch_next); + if (rc) { + conn_req_us = rxhdr->rem_usecs + ble_ll_pdu_us(34, phy_mode); +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + if (ext) { + conn_req_us += BLE_LL_IFS + ble_ll_pdu_us(14, phy_mode); + } #endif + conn_req_end = rxhdr->beg_cputime + ble_ll_tmr_u2t_up(conn_req_us); + + if (LL_TMR_LEQ(sch_next, conn_req_end)) { + return -1; + } + } if (ble_ll_sched_conn_central_new(connsm, rxhdr, 0)) { return -1; From e0fb600b8a857a354a66e384537fc03c784ae7d1 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Fri, 19 Jul 2024 13:37:54 +0200 Subject: [PATCH 1146/1333] apps/blestress: logging refactor This commit removes console_printf usage, adjust log levels to match it's actual content, remove colors etc. --- apps/blestress/src/rx_stress.c | 232 +++++++++++----------- apps/blestress/src/stress.c | 181 ++++++++--------- apps/blestress/src/stress_gatt.c | 10 +- apps/blestress/src/tx_stress.c | 325 +++++++++++++++---------------- 4 files changed, 375 insertions(+), 373 deletions(-) diff --git a/apps/blestress/src/rx_stress.c b/apps/blestress/src/rx_stress.c index d684ab40b4..32b9ab60bd 100644 --- a/apps/blestress/src/rx_stress.c +++ b/apps/blestress/src/rx_stress.c @@ -60,7 +60,7 @@ static struct os_sem rx_stress_main_sem; static void rx_stress_on_test_finish(int test_num) { - console_printf("\033[0;32m\nStress test %d completed\033[0m\n", test_num); + MODLOG_DFLT(INFO, "\nStress test %d completed\n", test_num); os_sem_release(&rx_stress_main_sem); } @@ -72,7 +72,8 @@ rx_stress_adv_start(uint8_t instance) /* Resume advertising earlier configured instance */ rc = ble_gap_ext_adv_start(instance, 0, 0); assert (rc == 0 || rc == 2); - MODLOG_DFLT(INFO, "Instance %d started; rc: %d\n", instance, rc); + MODLOG_DFLT(DEBUG, "Ext Adv - Test Instance %d started; rc: %d\n", + instance, rc); return rc; } @@ -109,8 +110,7 @@ rx_stress_simple_adv(struct rx_stress_adv_set *adv_set) /* Determine own address type */ rc = ble_hs_id_infer_auto(0, &own_addr_type); if (rc != 0) { - MODLOG_DFLT(ERROR, "\033[0;31mError determining own address type; " - "rc=%d\033[0m\n", rc); + MODLOG_DFLT(ERROR, "Error determining own address type; rc=%d\n", rc); return; } @@ -209,7 +209,7 @@ rx_stress_0_gap_event(struct ble_gap_event *event, void *arg) if (event->connect.status == 0) { MODLOG_DFLT(INFO, "\nConnection established; status=%d; num=%d\n", event->connect.status, - ++rx_stress_ctx->con_stat[0].num); + ++rx_stress_ctx->con_stat[1].num); /* Stop test advert */ ble_gap_ext_adv_stop(TEST_INSTANCE); @@ -222,9 +222,9 @@ rx_stress_0_gap_event(struct ble_gap_event *event, void *arg) } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); - console_printf("\033[0;32mReceived signal to switch test\033[0m\n"); + MODLOG_DFLT(INFO, "Received signal to switch test\n"); /* Add token to semaphore. Main task will start next test. */ os_sem_release(&rx_stress_main_sem); @@ -243,22 +243,24 @@ rx_stress_2_gap_event(struct ble_gap_event *event, void *arg) ++rx_stress_ctx->con_stat[2].attempts_num; /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { - MODLOG_DFLT(INFO, "\nConnection established; status=%d; num=%d\n", + MODLOG_DFLT(INFO, "\nConnection established; " + "status=%d; num=%d; conn handle=%d;\n", event->connect.status, - ++rx_stress_ctx->con_stat[2].num); + ++rx_stress_ctx->con_stat[2].num, + event->connect.conn_handle); } else { /* Connection failed; resume advertising. */ - MODLOG_DFLT(INFO, "Connection failed; status=%d ", - event->connect.status); + MODLOG_DFLT(WARN, "Connection failed; status=%d; conn handle=%d;" + "\n ", + event->connect.status, event->connect.conn_handle); rx_stress_adv_start(TEST_INSTANCE); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); - console_printf("\033[0;32m>\033[0m"); if (rx_stress_ctx->con_stat[2].num >= MYNEWT_VAL(BLE_STRESS_REPEAT)) { rx_stress_on_test_finish(2); } else { @@ -268,7 +270,7 @@ rx_stress_2_gap_event(struct ble_gap_event *event, void *arg) return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -281,19 +283,24 @@ rx_stress_3_gap_event(struct ble_gap_event *event, void *arg) ++rx_stress_ctx->con_stat[3].attempts_num; /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { - MODLOG_DFLT(INFO, "\nConnection established; status=%d; num=%d\n", + MODLOG_DFLT(INFO, "\nConnection established; status=%d; num=%d;" + " handle=%d;\n", event->connect.status, - ++rx_stress_ctx->con_stat[3].num); + ++rx_stress_ctx->con_stat[3].num, + event->connect.conn_handle); } else { /* Connection failed; resume advertising. */ + MODLOG_DFLT(WARN, "Connection failed; status=%d; conn handle=%d;" + "\n ", + event->connect.status, event->connect.conn_handle); + rx_stress_adv_start(TEST_INSTANCE); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); - console_printf("\033[0;32m>\033[0m"); if (rx_stress_ctx->con_stat[3].num >= MYNEWT_VAL(BLE_STRESS_REPEAT)) { rx_stress_on_test_finish(3); } else { @@ -303,7 +310,7 @@ rx_stress_3_gap_event(struct ble_gap_event *event, void *arg) return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -319,7 +326,7 @@ rx_stress_4_gap_event(struct ble_gap_event *event, void *arg) ++rx_stress_ctx->con_stat[4].attempts_num; /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { - MODLOG_DFLT(INFO, "Connection established; status=%d; num=%d", + MODLOG_DFLT(DEBUG, "Connection established; status=%d; num=%d", event->connect.status, ++rx_stress_ctx->con_stat[4].num); @@ -329,14 +336,14 @@ rx_stress_4_gap_event(struct ble_gap_event *event, void *arg) rx_stress_ctx->conn_handle = event->connect.conn_handle; } else { /* Connection failed; resume advertising. */ - MODLOG_DFLT(INFO, "Connection failed; status=%d ", - event->connect.status); + MODLOG_DFLT(WARN, "Connection failed; status=%d; conn handle=%d", + event->connect.status, event->connect.conn_handle); rx_stress_adv_start(TEST_INSTANCE); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d ", event->disconnect.reason); + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d ", event->disconnect.reason); if (rx_stress_ctx->con_stat[4].prms_upd_num >= MYNEWT_VAL(BLE_STRESS_REPEAT)) { rx_stress_on_test_finish(4); @@ -348,11 +355,11 @@ rx_stress_4_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_CONN_UPDATE: if (event->conn_update.status != 0) { - MODLOG_DFLT(INFO, "Connection update failed\n"); + MODLOG_DFLT(WARN, "Connection update failed\n; conn handle=%d", + event->connect.conn_handle); } else { MODLOG_DFLT(INFO, "Connection updated; num=%d\n", ++rx_stress_ctx->con_stat[4].prms_upd_num); - console_printf("\033[0;32m>\033[0m"); } if (rx_stress_ctx->con_stat[4].prms_upd_num >= @@ -364,7 +371,7 @@ rx_stress_4_gap_event(struct ble_gap_event *event, void *arg) return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -393,13 +400,12 @@ rx_stress_5_con_update(void) rc = ble_gap_update_params(rx_stress_ctx->conn_handle, ¶ms); if (rc == BLE_HS_ENOTCONN) { - MODLOG_DFLT(INFO, "Device disconnected. Connection update failed\n"); + MODLOG_DFLT(ERROR, "Device disconnected. Connection update failed\n"); assert(0); } if (rc != 0) { - MODLOG_DFLT(ERROR, "\033[0;31mError during connection update; " - "rc=%d\033[0m\n", rc); + MODLOG_DFLT(ERROR, "Error during connection update; rc=%d\n", rc); assert(0); } @@ -418,7 +424,7 @@ rx_stress_5_gap_event(struct ble_gap_event *event, void *arg) /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { - MODLOG_DFLT(INFO, "Connection established; status=%d; num=%d", + MODLOG_DFLT(DEBUG, "Connection established; status=%d; num=%d", event->connect.status, ++rx_stress_ctx->con_stat[5].num); @@ -432,14 +438,14 @@ rx_stress_5_gap_event(struct ble_gap_event *event, void *arg) assert(rc == 0); } else { /* Connection failed; resume advertising. */ - MODLOG_DFLT(INFO, "Connection failed; status=%d ", - event->connect.status); + MODLOG_DFLT(WARN, "Connection failed; status=%d; conn handle=%d", + event->connect.status, event->connect.conn_handle); rx_stress_adv_start(TEST_INSTANCE); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d ", event->disconnect.reason); + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d ", event->disconnect.reason); if (rx_stress_ctx->con_stat[5].prms_upd_num >= MYNEWT_VAL(BLE_STRESS_REPEAT)) { rx_stress_on_test_finish(5); @@ -451,11 +457,10 @@ rx_stress_5_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_CONN_UPDATE: if (event->conn_update.status != 0) { - MODLOG_DFLT(INFO, "Connection update failed\n"); + MODLOG_DFLT(DEBUG, "Connection update failed\n"); } else { MODLOG_DFLT(INFO, "Connection updated; num=%d\n", ++rx_stress_ctx->con_stat[5].prms_upd_num); - console_printf("\033[0;32m>\033[0m"); } if (rx_stress_ctx->con_stat[5].prms_upd_num >= @@ -495,7 +500,7 @@ rx_stress_7_gap_event(struct ble_gap_event *event, void *arg) /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { - MODLOG_DFLT(INFO, "Connection established; status=%d; num=%d", + MODLOG_DFLT(DEBUG, "Connection established; status=%d; num=%d", event->connect.status, ++rx_stress_ctx->con_stat[7].num); @@ -505,14 +510,14 @@ rx_stress_7_gap_event(struct ble_gap_event *event, void *arg) rx_stress_ctx->conn_handle = event->connect.conn_handle; } else { /* Connection failed; resume advertising. */ - MODLOG_DFLT(INFO, "Connection failed; status=%d ", + MODLOG_DFLT(DEBUG, "Connection failed; status=%d ", event->connect.status); rx_stress_adv_start(TEST_INSTANCE); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d ", event->disconnect.reason); + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d ", event->disconnect.reason); if (rx_stress_ctx->con_stat[7].phy_upd_num >= MYNEWT_VAL(BLE_STRESS_REPEAT)) { rx_stress_on_test_finish(7); @@ -524,11 +529,11 @@ rx_stress_7_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_PHY_UPDATE_COMPLETE: if (event->phy_updated.status != 0) { - MODLOG_DFLT(INFO, "PHY update failed\n"); + MODLOG_DFLT(WARN, "PHY update failed\n"); } else { - MODLOG_DFLT(INFO, "PHY updated; num=%d\n", - ++rx_stress_ctx->con_stat[7].phy_upd_num); - console_printf("\033[0;32m>\033[0m"); + MODLOG_DFLT(INFO, "PHY updated; num=%d; rx:%d, tx:%d\n", + ++rx_stress_ctx->con_stat[7].phy_upd_num, + event->phy_updated.rx_phy, event->phy_updated.tx_phy); } if (rx_stress_ctx->con_stat[7].phy_upd_num >= @@ -593,14 +598,16 @@ rx_stress_8_con_update(void) rc = ble_gap_set_prefered_le_phy(rx_stress_ctx->conn_handle, tx_phys_mask, rx_phys_mask, 0); + MODLOG_DFLT(INFO, "Set PHY params: tx_phys_mask=%d; rx_phys_mask=%d\n", + tx_phys_mask, rx_phys_mask); + if (rc == BLE_HS_ENOTCONN) { MODLOG_DFLT(INFO, "Device disconnected. Connection update failed\n"); return rc; } if (rc != 0) { - MODLOG_DFLT(ERROR, "\033[0;31mError during PHY update; " - "rc=%d\033[0m\n", rc); + MODLOG_DFLT(ERROR, "Error during PHY update; rc=%d\n", rc); } return rc; @@ -618,7 +625,7 @@ rx_stress_8_gap_event(struct ble_gap_event *event, void *arg) /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { - MODLOG_DFLT(INFO, "Connection established; status=%d; num=%d", + MODLOG_DFLT(DEBUG, "Connection established; status=%d; num=%d", event->connect.status, ++rx_stress_ctx->con_stat[8].num); @@ -632,14 +639,14 @@ rx_stress_8_gap_event(struct ble_gap_event *event, void *arg) assert(rc == 0); } else { /* Connection failed; resume advertising. */ - MODLOG_DFLT(INFO, "Connection failed; status=%d ", + MODLOG_DFLT(DEBUG, "Connection failed; status=%d ", event->connect.status); rx_stress_adv_start(TEST_INSTANCE); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d ", event->disconnect.reason); + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d ", event->disconnect.reason); if (rx_stress_ctx->con_stat[8].phy_upd_num >= MYNEWT_VAL(BLE_STRESS_REPEAT)) { rx_stress_on_test_finish(8); @@ -651,12 +658,11 @@ rx_stress_8_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_PHY_UPDATE_COMPLETE: if (event->phy_updated.status != 0) { - MODLOG_DFLT(INFO, "PHY update failed\n"); + MODLOG_DFLT(WARN, "PHY update failed\n"); } else { MODLOG_DFLT(INFO, "PHY updated; num=%d; rx:%d, tx:%d\n", ++rx_stress_ctx->con_stat[8].phy_upd_num, event->phy_updated.rx_phy, event->phy_updated.tx_phy); - console_printf("\033[0;32m>\033[0m"); } if (rx_stress_ctx->con_stat[8].phy_upd_num >= @@ -686,10 +692,9 @@ rx_stress_9_gap_event(struct ble_gap_event *event, void *arg) /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { - MODLOG_DFLT(INFO, "Connection established; status=%d; num=%d", + MODLOG_DFLT(INFO, "Connection established; status=%d; num=%d\n", event->connect.status, ++rx_stress_ctx->con_stat[9].num); - console_printf("\033[0;32m>\033[0m"); /* Remember max number of established connections */ if (rx_stress_ctx->con_stat[9].num > @@ -698,14 +703,14 @@ rx_stress_9_gap_event(struct ble_gap_event *event, void *arg) } } else { /* Connection failed; resume advertising. */ - MODLOG_DFLT(INFO, "Connection failed; status=%d ", + MODLOG_DFLT(INFO, "Connection failed; status=%d\n", event->connect.status); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d ", event->disconnect.reason); - console_printf("\033[0;31mX\033[0m"); + MODLOG_DFLT(INFO, "Disconnect; reason=%d; conn handle=%d\n", + event->disconnect.reason, event->connect.conn_handle); MODLOG_DFLT(INFO, "Connections num: %d\n", --rx_stress_ctx->con_stat[9].num); @@ -731,7 +736,7 @@ rx_stress_9_gap_event(struct ble_gap_event *event, void *arg) return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); } return 0; } @@ -740,9 +745,11 @@ static void tx_stress_10_l2cap_update_event(uint16_t conn_handle, int status, void *arg) { if (status == 0) { - MODLOG_DFLT(INFO, "L2CAP params updated\n"); + MODLOG_DFLT(INFO, "L2CAP params updated; conn handle=%d\n", + conn_handle); } else { - MODLOG_DFLT(INFO, "L2CAP params update failed; rc=%d\n", status); + MODLOG_DFLT(ERROR, "L2CAP params update failed; rc=%d; conn " + "handle=%d\n", status, conn_handle); assert(0); } } @@ -760,7 +767,7 @@ rx_stress_10_l2cap_event(struct ble_l2cap_event *event, void *arg) switch (event->type) { case BLE_L2CAP_EVENT_COC_CONNECTED: if (event->connect.status) { - MODLOG_DFLT(INFO, "LE COC error: %d\n", event->connect.status); + MODLOG_DFLT(ERROR, "LE COC error: %d\n", event->connect.status); return 0; } @@ -801,7 +808,7 @@ rx_stress_10_l2cap_event(struct ble_l2cap_event *event, void *arg) case BLE_L2CAP_EVENT_COC_DATA_RECEIVED: stress_l2cap_coc_recv(event->receive.chan, event->receive.sdu_rx); - MODLOG_DFLT(INFO, "L2CAP server received data; num=%d\n", + MODLOG_DFLT(DEBUG, "L2CAP server received data; num=%d\n", ++rx_stress_ctx->rcv_num); rx_stress_ctx->chan = event->receive.chan; @@ -835,7 +842,7 @@ rx_stress_10_l2cap_event(struct ble_l2cap_event *event, void *arg) /* Get mbuf for adv data */ data_buf = os_msys_get_pkthdr(data_len, 0); - MODLOG_DFLT(INFO, "Data buf %s\n", data_buf ? "OK" : "NOK"); + MODLOG_DFLT(DEBUG, "Data buf %s\n", data_buf ? "OK" : "NOK"); assert(data_buf != NULL); /* Fill mbuf with the pattern */ @@ -843,13 +850,13 @@ rx_stress_10_l2cap_event(struct ble_l2cap_event *event, void *arg) /* Send data */ rc = ble_l2cap_send(rx_stress_ctx->chan, data_buf); - MODLOG_DFLT(INFO, "Return code=%d\n", rc); + MODLOG_DFLT(DEBUG, "Return code=%d\n", rc); if (rc) { if (rc == BLE_HS_ESTALLED) { - MODLOG_DFLT(INFO, "L2CAP stalled - waiting\n"); + MODLOG_DFLT(ERROR, "L2CAP stalled - waiting\n"); stalled = true; } else { - MODLOG_DFLT(INFO, "Sending data via L2CAP failed with error " + MODLOG_DFLT(ERROR, "Sending data via L2CAP failed with error " "code %d\n", rc); } } @@ -905,12 +912,13 @@ rx_stress_11_gap_event(struct ble_gap_event *event, void *arg) ++rx_stress_ctx->con_stat[11].attempts_num; /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { - MODLOG_DFLT(INFO, "\nConnection established; status=%d; num=%d\n", - event->connect.status, - ++rx_stress_ctx->con_stat[11].num); + MODLOG_DFLT(INFO, "\nConnection established; status=%d; num=%d; " + "conn handle=%d\n", event->connect.status, + ++rx_stress_ctx->con_stat[11].num, + event->connect.conn_handle); } else { - MODLOG_DFLT(INFO, "\033[0;31mError: connection attempt failed; " - "status=%d\033[0m\n", event->connect.status); + MODLOG_DFLT(ERROR, "Error: connection attempt failed; status=%d\n", + event->connect.status); } ble_gap_terminate(event->connect.conn_handle, @@ -918,9 +926,8 @@ rx_stress_11_gap_event(struct ble_gap_event *event, void *arg) return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); - console_printf("\033[0;32m>\033[0m"); if (rx_stress_ctx->con_stat[11].num >= MYNEWT_VAL(BLE_STRESS_REPEAT)) { rx_stress_on_test_finish(11); } else { @@ -930,7 +937,7 @@ rx_stress_11_gap_event(struct ble_gap_event *event, void *arg) return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -955,19 +962,19 @@ rx_stress_12_gap_event(struct ble_gap_event *event, void *arg) break; } else { /* Connection failed; resume advertising */ - MODLOG_DFLT(INFO, "Connection failed; status=%d ", + MODLOG_DFLT(DEBUG, "Connection failed; status=%d ", event->connect.status); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); rx_stress_ctx->s12_notif_time = rx_stress_ctx->time_sum / rx_stress_ctx->send_num; - MODLOG_DFLT(INFO, "Average time: %d us\n", + MODLOG_DFLT(DEBUG, "Average time: %d us\n", rx_stress_ctx->s12_notif_time); rx_stress_on_test_finish(12); @@ -975,7 +982,7 @@ rx_stress_12_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_NOTIFY_TX: rx_stress_ctx->end_us = os_get_uptime_usec(); - MODLOG_DFLT(INFO, "Notify TX event\n"); + MODLOG_DFLT(DEBUG, "Notify TX event\n"); if (!event->notify_tx.status) { /* Send next only after previous indication is done */ @@ -991,13 +998,12 @@ rx_stress_12_gap_event(struct ble_gap_event *event, void *arg) /* Time of data sending */ us = rx_stress_ctx->end_us - rx_stress_ctx->begin_us; - console_printf("Indication time: %lld\n", us); + MODLOG_DFLT(DEBUG, "Indication time: %lld\n", us); rx_stress_ctx->time_sum += us; - console_printf("\033[0;32m>\033[0m"); break; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } @@ -1107,35 +1113,35 @@ rx_stress_14_gap_event(struct ble_gap_event *event, void *arg) rx_stress_ctx->conn_handle = event->connect.conn_handle; } else { /* Connection failed; resume advertising */ - MODLOG_DFLT(INFO, "Connection failed; status=%d ", + MODLOG_DFLT(DEBUG, "Connection failed; status=%d ", event->connect.status); assert(0); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); rx_stress_ctx->s14_notif_time = rx_stress_ctx->time_sum / rx_stress_ctx->send_num; - MODLOG_DFLT(INFO, "Average time: %d us\n", + MODLOG_DFLT(DEBUG, "Average time: %d us\n", rx_stress_ctx->s14_notif_time); rx_stress_on_test_finish(14); return 0; case BLE_GAP_EVENT_NOTIFY_TX: - MODLOG_DFLT(INFO, "Notify TX event\n"); + MODLOG_DFLT(DEBUG, "Notify TX event\n"); assert(event->notify_tx.status == 0); return 0; case BLE_GAP_EVENT_SUBSCRIBE: - MODLOG_DFLT(INFO, "Subscribe event\n"); + MODLOG_DFLT(DEBUG, "Subscribe event\n"); if (event->subscribe.cur_notify) { - MODLOG_DFLT(INFO, "Notification subscribed\n"); + MODLOG_DFLT(DEBUG, "Notification subscribed\n"); ++rx_stress_ctx->send_num; @@ -1145,17 +1151,15 @@ rx_stress_14_gap_event(struct ble_gap_event *event, void *arg) rc = ble_gatts_notify_custom(rx_stress_ctx->conn_handle, hrs_hrm_handle, om); assert(rc == 0); - - console_printf("\033[0;32m>\033[0m"); } else if (event->subscribe.prev_notify) { - MODLOG_DFLT(INFO, "Notification unsubscribed\n"); + MODLOG_DFLT(DEBUG, "Notification unsubscribed\n"); } else { - MODLOG_DFLT(INFO, "Other subscription\n"); + MODLOG_DFLT(DEBUG, "Other subscription\n"); } return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -1172,16 +1176,15 @@ rx_stress_15_gap_event(struct ble_gap_event *event, void *arg) event->connect.status, ++rx_stress_ctx->con_stat[15].num); } else { - MODLOG_DFLT(INFO, "\033[0;31mError: connection attempt failed; " - "status=%d\033[0m\n", event->connect.status); + MODLOG_DFLT(DEBUG, "Error: connection attempt failed; " + "status=%d\n", event->connect.status); assert(0); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); - console_printf("\033[0;32m>\033[0m"); if (rx_stress_ctx->con_stat[15].num >= MYNEWT_VAL(BLE_STRESS_REPEAT)) { rx_stress_on_test_finish(15); } else { @@ -1191,7 +1194,7 @@ rx_stress_15_gap_event(struct ble_gap_event *event, void *arg) return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -1336,83 +1339,82 @@ rx_stress_start(int test_num) /* Init semaphore with 0 tokens. */ os_sem_init(&rx_stress_main_sem, 0); - console_printf("\033[1;36mStart test num %d - ", test_num); + MODLOG_DFLT(INFO, "Start test num %d - ", test_num); /* Start test. */ switch (test_num) { case 0: return; case 1: - console_printf("Nothing to do"); + MODLOG_DFLT(INFO, "Nothing to do\n"); rx_stress_simple_adv(&rx_stress_adv_sets[1]); return; case 2: - console_printf("Stress Connect/Disconnect legacy\033[0m\n"); + MODLOG_DFLT(INFO, "Stress Connect/Disconnect legacy\n"); rx_stress_simple_adv(&rx_stress_adv_sets[2]); break; case 3: - console_printf("Stress Connect/Disconnect ext adv\033[0m\n"); + MODLOG_DFLT(INFO, "Stress Connect/Disconnect ext adv\n"); rx_stress_simple_adv(&rx_stress_adv_sets[3]); break; case 4: - console_printf("Stress connection params update (TX)\033[0m\n"); + MODLOG_DFLT(INFO, "Stress connection params update (TX)\n"); rx_stress_simple_adv(&rx_stress_adv_sets[4]); break; case 5: - console_printf("Stress connection params update (RX)\033[0m\n"); + MODLOG_DFLT(INFO, "Stress connection params update (RX)\n"); rx_stress_simple_adv(&rx_stress_adv_sets[5]); break; case 6: /* Start SWITCHER advert that gives possibility to remotely start * next test advert */ - console_printf("Stress Scan\033[0m\n"); + MODLOG_DFLT(INFO, "Stress Scan\n"); rx_stress_simple_adv(&rx_stress_adv_sets[0]); rx_stress_simple_adv(&rx_stress_adv_sets[6]); break; case 7: - console_printf("Stress PHY Update (TX)\033[0m\n"); + MODLOG_DFLT(INFO, "Stress PHY Update (TX)\n"); rx_stress_simple_adv(&rx_stress_adv_sets[7]); break; case 8: - console_printf("Stress PHY Update (RX)\033[0m\n"); + MODLOG_DFLT(INFO, "Stress PHY Update (RX)\n"); rx_stress_simple_adv(&rx_stress_adv_sets[8]); break; case 9: - console_printf("Stress multi connection\033[0m\n"); + MODLOG_DFLT(INFO, "Stress multi connection\n"); rx_stress_simple_adv(&rx_stress_adv_sets[9]); break; case 10: - console_printf("Stress L2CAP send\033[0m\n"); + MODLOG_DFLT(INFO, "Stress L2CAP send\n"); rc = ble_l2cap_create_server(TEST_PSM, STRESS_COC_MTU, rx_stress_10_l2cap_event, NULL); assert(rc == 0); rx_stress_simple_adv(&rx_stress_adv_sets[10]); break; case 11: - console_printf("Stress Advertise/Connect/Disconnect\033[0m\n"); + MODLOG_DFLT(INFO, "Stress Advertise/Connect/Disconnect\n"); rx_stress_simple_adv(&rx_stress_adv_sets[11]); break; case 12: - console_printf("Stress GATT indication\033[0m\n"); + MODLOG_DFLT(INFO, "Stress GATT indication\n"); rx_stress_simple_adv(&rx_stress_adv_sets[12]); break; case 13: - console_printf("Stress GATT notification\033[0m\n"); + MODLOG_DFLT(INFO, "Stress GATT notification\n"); ble_npl_event_init(&rx_stress_13_notify_ev, rx_stress_13_notify_ev_func, NULL); rx_stress_simple_adv(&rx_stress_adv_sets[13]); break; case 14: - console_printf("Stress GATT Subscribe/Notify/Unsubscribe\033[0m\n"); + MODLOG_DFLT(INFO, "Stress GATT Subscribe/Notify/Unsubscribe\n"); rx_stress_simple_adv(&rx_stress_adv_sets[14]); break; case 15: - console_printf("Stress Connect/Send/Disconnect\033[0m\n"); + MODLOG_DFLT(INFO, "Stress Connect/Send/Disconnect\n"); rx_stress_simple_adv(&rx_stress_adv_sets[15]); break; default: - console_printf("\033[0;31mFound test, but do not know how to perform." - "\033[0m\n"); + MODLOG_DFLT(ERROR, "Found test, but do not know how to perform.\n"); assert(0); } @@ -1442,7 +1444,7 @@ stress_uuid_init() static void rx_stress_read_command_cb(void) { - console_printf("Start testing\n"); + MODLOG_DFLT(INFO, "Start testing\n"); os_sem_release(&rx_stress_main_sem); } @@ -1453,8 +1455,8 @@ rx_stress_main_task_fn(void *arg) stress_uuid_init(); - console_printf("\033[1;36mRX device\033[0m\n"); - console_printf("Press ENTER to start: \n"); + MODLOG_DFLT(INFO, "RX device\n"); + MODLOG_DFLT(INFO, "Press ENTER to start: \n"); console_init(&rx_stress_read_command_cb); /* Waite for pressing ENTER in console */ diff --git a/apps/blestress/src/stress.c b/apps/blestress/src/stress.c index 1a9cb0c0d9..85f103cb2a 100644 --- a/apps/blestress/src/stress.c +++ b/apps/blestress/src/stress.c @@ -24,73 +24,80 @@ static struct os_callout stress_timer_callout; void com_stress_print_report(const struct com_stress_test_ctx *test_ctxs) { - console_printf("\033[0;32mAll tests completed\033[0m\n"); - console_printf("Tests results:\n"); - - console_printf( - "\033[0;33mUse case 1 - Stress Connect -> Connect Cancel: \n\033[0m"); - console_printf("Con attempts = %d\n", test_ctxs->con_stat[1].attempts_num); - console_printf("Con success = %d\n", test_ctxs->con_stat[1].num); - - console_printf( - "\033[0;33mUse case 2 - Stress Connect/Disconnect legacy: \n\033[0m"); - console_printf("Con attempts = %d\n", test_ctxs->con_stat[2].attempts_num); - console_printf("Con success = %d\n", test_ctxs->con_stat[2].num); - - console_printf( - "\033[0;33mUse case 3 - Stress Connect/Disconnect ext adv: \n\033[0m"); - console_printf("Con attempts = %d\n", test_ctxs->con_stat[3].attempts_num); - console_printf("Con success = %d\n", test_ctxs->con_stat[3].num); - - console_printf( - "\033[0;33mUse case 4 - Stress connection params update (TX): \n\033[0m"); - console_printf("Params updates = %d\n", - test_ctxs->con_stat[4].prms_upd_num); - - console_printf( - "\033[0;33mUse case 5 - Stress connection params update (RX): \n\033[0m"); - console_printf("Params updates = %d\n", - test_ctxs->con_stat[5].prms_upd_num); - - console_printf("\033[0;33mUse case 6 - Stress Scan: \n\033[0m"); - console_printf("Received first packets = %d\n", - test_ctxs->s6_rcv_adv_first); - console_printf("Received all packets = %d\n", test_ctxs->s6_rcv_adv_suc); - - console_printf("\033[0;33mUse case 7 - Stress PHY Update (TX): \n\033[0m"); - console_printf("PHY updates = %d\n", test_ctxs->con_stat[7].phy_upd_num); - - console_printf("\033[0;33mUse case 8 - Stress PHY Update (RX): \n\033[0m"); - console_printf("PHY updates = %d\n", test_ctxs->con_stat[8].phy_upd_num); - - console_printf( - "\033[0;33mUse case 9 - Stress multi connection: \n\033[0m"); - console_printf("Max reached num of connections = %d\n", - test_ctxs->con_stat[9].max_num); - - console_printf("\033[0;33mUse case 10 - Stress L2CAP send: \n\033[0m"); - console_printf("Average bit rate = %d\n", test_ctxs->s10_bit_rate); - console_printf("Max received MTU = %lld\n", test_ctxs->s10_max_mtu); - - console_printf("\033[0;33mUse case 11 - " - "Stress Advertise/Connect/Continue adv \n\033[0m"); -// console_printf(" = %d\n",); - - console_printf("\033[0;33mUse case 12 - " - "Stress GATT indication: \n\033[0m"); - console_printf("Average bit rate = %d\n", test_ctxs->s12_notif_time); - - console_printf("\033[0;33mUse case 13 - " - "Stress GATT notification: \n\033[0m"); - console_printf("Average time = %d\n", test_ctxs->s13_notif_time); - - console_printf("\033[0;33mUse case 14 - " - "Stress GATT Subscribe/Notify/Unsubscribe: \n\033[0m"); - console_printf("Average time = %d\n", test_ctxs->s14_notif_time); - - console_printf("\033[0;33mUse case 15 - " - "Stress Connect/Send/Disconnect: \n\033[0m"); - console_printf("Con num = %d\n", test_ctxs->con_stat[15].num); + MODLOG_DFLT(INFO, "All tests completed\n"); + MODLOG_DFLT(INFO, "Tests results:\n"); + + MODLOG_DFLT(INFO, "Use case 1 - " + "Stress Connect -> Connect Cancel: \n"); + MODLOG_DFLT(INFO, "Con attempts = %d\n", + test_ctxs->con_stat[1].attempts_num); + MODLOG_DFLT(INFO, "Con success = %d\n", test_ctxs->con_stat[1].num); + + MODLOG_DFLT(INFO, "Use case 2 - " + "Stress Connect/Disconnect legacy: \n"); + MODLOG_DFLT(INFO, "Con attempts = %d\n", + test_ctxs->con_stat[2].attempts_num); + MODLOG_DFLT(INFO, "Con success = %d\n", test_ctxs->con_stat[2].num); + + MODLOG_DFLT(INFO, "Use case 3 - " + "Stress Connect/Disconnect ext adv: \n"); + MODLOG_DFLT(INFO, "Con attempts = %d\n", + test_ctxs->con_stat[3].attempts_num); + MODLOG_DFLT(INFO, "Con success = %d\n", test_ctxs->con_stat[3].num); + + MODLOG_DFLT(INFO, "Use case 4 - " + "Stress connection params update (TX): \n"); + MODLOG_DFLT(INFO, "Params updates = %d\n", + test_ctxs->con_stat[4].prms_upd_num); + + MODLOG_DFLT(INFO, "Use case 5 - " + "Stress connection params update (RX): \n"); + MODLOG_DFLT(INFO, "Params updates = %d\n", + test_ctxs->con_stat[5].prms_upd_num); + + MODLOG_DFLT(INFO, "Use case 6 - Stress Scan: \n"); + MODLOG_DFLT(INFO, "Received first packets = %d\n", + test_ctxs->s6_rcv_adv_first); + MODLOG_DFLT(INFO, "Received all packets = %d\n", + test_ctxs->s6_rcv_adv_suc); + + MODLOG_DFLT(INFO, "Use case 7 - " + "Stress PHY Update (TX): \n"); + MODLOG_DFLT(INFO, "PHY updates = %d\n", + test_ctxs->con_stat[7].phy_upd_num); + + MODLOG_DFLT(INFO, "Use case 8 - " + "Stress PHY Update (RX): \n"); + MODLOG_DFLT(INFO, "PHY updates = %d\n", + test_ctxs->con_stat[8].phy_upd_num); + + MODLOG_DFLT(INFO, "Use case 9 - " + "Stress multi connection: \n"); + MODLOG_DFLT(INFO, "Max reached num of connections = %d\n", + test_ctxs->con_stat[9].max_num); + + MODLOG_DFLT(INFO, "Use case 10 - Stress L2CAP send: \n"); + MODLOG_DFLT(INFO, "Average bit rate = %d\n", test_ctxs->s10_bit_rate); + MODLOG_DFLT(INFO, "Max received MTU = %lld\n", test_ctxs->s10_max_mtu); + + MODLOG_DFLT(INFO, "Use case 11 - " + "Stress Advertise/Connect/Continue adv \n"); + + MODLOG_DFLT(INFO, "Use case 12 - " + "Stress GATT indication: \n"); + MODLOG_DFLT(INFO, "Average bit rate = %d\n", test_ctxs->s12_notif_time); + + MODLOG_DFLT(INFO, "Use case 13 - " + "Stress GATT notification: \n"); + MODLOG_DFLT(INFO, "Average time = %d\n", test_ctxs->s13_notif_time); + + MODLOG_DFLT(INFO, "Use case 14 - " + "Stress GATT Subscribe/Notify/Unsubscribe: \n"); + MODLOG_DFLT(INFO, "Average time = %d\n", test_ctxs->s14_notif_time); + + MODLOG_DFLT(INFO, "Use case 15 - " + "Stress Connect/Send/Disconnect: \n"); + MODLOG_DFLT(INFO, "Con num = %d\n", test_ctxs->con_stat[15].num); } void @@ -143,8 +150,8 @@ void stress_l2cap_coc_recv(struct ble_l2cap_chan *chan, struct os_mbuf *sdu) { int rc; - console_printf("LE CoC SDU received, chan: 0x%08lx, data len %d\n", - (uint32_t) chan, OS_MBUF_PKTLEN(sdu)); + MODLOG_DFLT(DEBUG, "LE CoC SDU received, chan: 0x%08lx, data len %d\n", + (uint32_t) chan, OS_MBUF_PKTLEN(sdu)); rc = os_mbuf_free_chain(sdu); assert(rc == 0); @@ -164,8 +171,8 @@ stress_l2cap_coc_accept(uint16_t peer_mtu, struct ble_l2cap_chan *chan) struct os_mbuf *sdu_rx; int rc; - console_printf("LE CoC accepting, chan: 0x%08lx, peer_mtu %d\n", - (uint32_t) chan, peer_mtu); + MODLOG_DFLT(DEBUG, "LE CoC accepting, chan: 0x%08lx, peer_mtu %d\n", + (uint32_t) chan, peer_mtu); for (int i = 0; i < MYNEWT_VAL(BLE_L2CAP_COC_SDU_BUFF_COUNT); i++) { sdu_rx = os_msys_get_pkthdr(STRESS_COC_MTU, 0); @@ -216,9 +223,9 @@ stress_disc_dsc_fn(uint16_t conn_handle, if (error->status == 0) { if (!ble_uuid_cmp(&dsc->uuid.u, &search_ctx->dsc_uuid.u) && !found) { - MODLOG_DFLT(INFO, "Found chr descriptor\n"); + MODLOG_DFLT(DEBUG, "Found chr descriptor\n"); search_ctx->dsc_handle = dsc->handle; - MODLOG_DFLT(INFO, "uuid=%#06x; handle=%#06x", dsc->uuid.u16.value, + MODLOG_DFLT(DEBUG, "uuid=%#06x; handle=%#06x", dsc->uuid.u16.value, dsc->handle); found = true; } @@ -226,7 +233,7 @@ stress_disc_dsc_fn(uint16_t conn_handle, } if (error->status == BLE_HS_EDONE) { - MODLOG_DFLT(INFO, "Done descriptor discovery\n"); + MODLOG_DFLT(DEBUG, "Done descriptor discovery\n"); if (found) { found = false; @@ -234,13 +241,11 @@ stress_disc_dsc_fn(uint16_t conn_handle, return 0; } - MODLOG_DFLT(ERROR, "\033[0;31mDid not find particular descriptor" - "\033[0m\n"); + MODLOG_DFLT(ERROR, "Did not find particular descriptor\n"); return 0; } - MODLOG_DFLT(ERROR, "\033[0;31mError during descriptor discovery" - "\033[0m\n"); + MODLOG_DFLT(ERROR, "Error during descriptor discovery\n"); assert(0); return 0; } @@ -257,14 +262,14 @@ stress_disc_chr_fn(uint16_t conn_handle, search_ctx = (struct stress_gatt_search_ctx *) arg; if (error->status == 0) { - MODLOG_DFLT(INFO, "Found characteristic\n"); + MODLOG_DFLT(DEBUG, "Found characteristic\n"); search_ctx->chr_start_handle = chr->val_handle; found = true; return 0; } if (error->status == BLE_HS_EDONE) { - MODLOG_DFLT(INFO, "Done characteristic discovery\n"); + MODLOG_DFLT(DEBUG, "Done characteristic discovery\n"); if (found) { found = false; @@ -282,13 +287,11 @@ stress_disc_chr_fn(uint16_t conn_handle, return 0; } - MODLOG_DFLT(ERROR, "\033[0;31mDid not find particular " - "characteristic\033[0m\n"); + MODLOG_DFLT(ERROR, "Did not find particular characteristic\n"); return 0; } - MODLOG_DFLT(ERROR, - "\033[0;31mError during characteristic discovery\033[0m\n"); + MODLOG_DFLT(ERROR, "Error during characteristic discovery\n"); assert(0); return 0; } @@ -304,7 +307,7 @@ stress_disc_svc_fn(uint16_t conn_handle, const struct ble_gatt_error *error, search_ctx = (struct stress_gatt_search_ctx *) arg; if (error->status == 0) { - MODLOG_DFLT(INFO, "Found service\n"); + MODLOG_DFLT(DEBUG, "Found service\n"); search_ctx->srv_start_handle = service->start_handle; search_ctx->srv_end_handle = service->end_handle; found = true; @@ -312,7 +315,7 @@ stress_disc_svc_fn(uint16_t conn_handle, const struct ble_gatt_error *error, } if (error->status == BLE_HS_EDONE) { - MODLOG_DFLT(INFO, "Done service discovery\n"); + MODLOG_DFLT(DEBUG, "Done service discovery\n"); if (found) { found = false; @@ -327,17 +330,17 @@ stress_disc_svc_fn(uint16_t conn_handle, const struct ble_gatt_error *error, &search_ctx->chr_uuid.u, &stress_disc_chr_fn, search_ctx); - MODLOG_DFLT(INFO, "rc=%d\n", rc); + MODLOG_DFLT(DEBUG, "rc=%d\n", rc); assert(rc == 0); return 0; } MODLOG_DFLT(ERROR, - "\033[0;31mDid not find particular service\033[0m\n"); + "Did not find particular service\n"); return 0; } - MODLOG_DFLT(ERROR, "\033[0;31mError during service discovery\033[0m\n"); + MODLOG_DFLT(ERROR, "Error during service discovery\n"); assert(0); return 0; } diff --git a/apps/blestress/src/stress_gatt.c b/apps/blestress/src/stress_gatt.c index a6d845c5d0..a076132752 100644 --- a/apps/blestress/src/stress_gatt.c +++ b/apps/blestress/src/stress_gatt.c @@ -82,23 +82,23 @@ stress_gatt_access_cb(uint16_t conn_handle, uint16_t attr_handle, switch(uuid){ case STRESS_GATT_READ_UUID: - MODLOG_DFLT(INFO, "GATT Read event\n"); + MODLOG_DFLT(DEBUG, "GATT Read event\n"); rc = os_mbuf_append(ctxt->om, &chr_value, sizeof(chr_value)); assert(rc == 0); //return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; return 0; case STRESS_GATT_WRITE_UUID: - MODLOG_DFLT(INFO, "GATT Write event\n"); + MODLOG_DFLT(DEBUG, "GATT Write event\n"); print_mbuf(ctxt->om); return 0; case STRESS_GATT_NOTIFY_UUID: - MODLOG_DFLT(INFO, "GATT Notify event\n"); + MODLOG_DFLT(DEBUG, "GATT Notify event\n"); return 0; case STRESS_GATT_INDICATE_UUID: - MODLOG_DFLT(INFO, "GATT Indicate event\n"); + MODLOG_DFLT(DEBUG, "GATT Indicate event\n"); return 0; default: - MODLOG_DFLT(ERROR, "GATT UUID does not exist\n"); + MODLOG_DFLT(DEBUG, "GATT UUID does not exist\n"); assert(0); return BLE_ATT_ERR_UNLIKELY; } diff --git a/apps/blestress/src/tx_stress.c b/apps/blestress/src/tx_stress.c index 18296e52f9..20333f1faa 100644 --- a/apps/blestress/src/tx_stress.c +++ b/apps/blestress/src/tx_stress.c @@ -19,6 +19,7 @@ #include #include +#include "inttypes.h" #include #include #include "tx_stress.h" @@ -48,7 +49,8 @@ static int completed_tests = 0; static void tx_stress_on_test_finish(int test_num) { - console_printf("\033[0;32m\nStress test %d completed\033[0m\n", test_num); + MODLOG_DFLT(INFO, "\nStress test %d completed\n", + test_num); ++completed_tests; tx_stress_ctx->completed[test_num] = true; os_sem_release(&tx_stress_main_sem); @@ -64,8 +66,7 @@ tx_stress_simple_scan(ble_gap_event_fn *cb, uint16_t duration) /* Figure out address to use while scanning. */ rc = ble_hs_id_infer_auto(0, &own_addr_type); if (rc != 0) { - console_printf("\033[0;31mError determining own address type; " - "rc=%d\033[0m\n", rc); + MODLOG_DFLT(ERROR, "Error determining own address type; rc=%d\n", rc); assert(0); } @@ -77,8 +78,8 @@ tx_stress_simple_scan(ble_gap_event_fn *cb, uint16_t duration) cb, NULL); if (rc != 0) { - console_printf("\033[0;31mError initiating GAP discovery procedure" - "; rc=%d\033[0m\n", rc); + MODLOG_DFLT(WARN, "Error initiating GAP discovery procedure" + "; rc=%d\n", rc); } } @@ -94,12 +95,12 @@ tx_stress_simple_connect(ble_gap_event_fn *cb, int test_num, struct ble_gap_conn /* Figure out address to use while connecting. */ rc = ble_hs_id_infer_auto(0, &own_addr_type); if (rc != 0) { - MODLOG_DFLT(INFO, "\033[0;31mError determining own address type; " - "rc=%d\033[0m\n", rc); + MODLOG_DFLT(ERROR, "Error determining own address type; " + "rc=%d\n", rc); return rc; } - MODLOG_DFLT(INFO, "Connection attempt: %d\n", + MODLOG_DFLT(DEBUG, "Connection attempt: %d\n", ++tx_stress_ctx->con_stat[test_num].attempts_num); rc = ble_gap_ext_connect(own_addr_type, &tx_stress_ctx->dev_addr, @@ -108,7 +109,7 @@ tx_stress_simple_connect(ble_gap_event_fn *cb, int test_num, struct ble_gap_conn params, params, NULL, cb, NULL); if (rc != 0) { - MODLOG_DFLT(INFO, "\033[0;31mError during connection; rc=%d\033[0m\n", + MODLOG_DFLT(ERROR, "Error during connection; rc=%d\n", rc); } @@ -165,12 +166,12 @@ tx_stress_switcher_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_CONNECT: /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { - MODLOG_DFLT(INFO, "Success to connect to device\n"); + MODLOG_DFLT(DEBUG, "Success to connect to device\n"); return 0; } else if (event->connect.status == BLE_HS_ETIMEOUT_HCI) { - MODLOG_DFLT(INFO, "Connection timeout\n"); + MODLOG_DFLT(WARN, "Connection timeout\n"); } else { - MODLOG_DFLT(INFO, "Error: connection attempt failed; status=%d\n", + MODLOG_DFLT(WARN, "Error: connection attempt failed; status=%d\n", event->connect.status); } /* Connect to rx device just to give it a signal to switch test. */ @@ -196,7 +197,7 @@ tx_stress_switcher_gap_event(struct ble_gap_event *event, void *arg) return 0; case BLE_GAP_EVENT_DISC_COMPLETE: - MODLOG_DFLT(INFO, "Discovery complete; reason=%d\n", + MODLOG_DFLT(DEBUG, "Discovery complete; reason=%d\n", event->disc_complete.reason); return 0; @@ -228,7 +229,7 @@ tx_stress_1_gap_event(struct ble_gap_event *event, void *arg) if (event->connect.status == 0) { /* Connection successfully established. In this use case * it is error of 'Connect cancel'. Stress test failed. */ - MODLOG_DFLT(INFO, "Success to connect to device\n"); + MODLOG_DFLT(DEBUG, "Success to connect to device\n"); ++tx_stress_ctx->con_stat[1].num; ble_gap_terminate(event->connect.conn_handle, BLE_ERR_NO_PAIRING); @@ -236,7 +237,7 @@ tx_stress_1_gap_event(struct ble_gap_event *event, void *arg) return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d ", event->disconnect.reason); + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d ", event->disconnect.reason); return 0; default: @@ -259,8 +260,7 @@ tx_stress_1_test() /* Figure out address to use while advertising. */ rc = ble_hs_id_infer_auto(0, &own_addr_type); if (rc != 0) { - MODLOG_DFLT(INFO, "\033[0;31mError determining own address type; " - "rc=%d\033[0m\n", rc); + MODLOG_DFLT(ERROR, "Error determining own address type; rc=%d\n", rc); os_sem_release(&tx_stress_main_sem); return; } @@ -271,27 +271,25 @@ tx_stress_1_test() rc = ble_hs_id_gen_rnd(1, &rnd_rx_addr); assert (rc == 0); - MODLOG_DFLT(INFO, "Connection attempt; num=%d\n", + MODLOG_DFLT(DEBUG, "Connection attempt; num=%d\n", ++tx_stress_ctx->con_stat[1].attempts_num); rc = ble_gap_connect(own_addr_type, &rnd_rx_addr, 10000, NULL, tx_stress_1_gap_event, NULL); if (rc != 0) { - MODLOG_DFLT(INFO, "\033[0;31mConnection error; rc=%d\033[0m\n", + MODLOG_DFLT(ERROR, "Connection error; rc=%d\n", rc); os_sem_release(&tx_stress_main_sem); return; } - MODLOG_DFLT(INFO, "Connect cancel\n"); + MODLOG_DFLT(DEBUG, "Connect cancel\n"); ble_gap_conn_cancel(); - console_printf("\033[0;32m>\033[0m"); } - console_printf( - "\033[0;32m\nFirst part of test completed\nStart second part: " - "Connect->random delay->cancel\n\033[0m"); + MODLOG_DFLT(INFO, "\nFirst part of test completed\nStart second part: " + "Connect->random delay->cancel\n"); while (tx_stress_ctx->con_stat[1].attempts_num < 2 * MYNEWT_VAL(BLE_STRESS_REPEAT)) { @@ -299,7 +297,7 @@ tx_stress_1_test() rc = ble_hs_id_gen_rnd(1, &rnd_rx_addr); assert (rc == 0); - MODLOG_DFLT(INFO, "Connection attempt; num=%d\n", + MODLOG_DFLT(DEBUG, "Connection attempt; num=%d\n", ++tx_stress_ctx->con_stat[1].attempts_num); delay_time = rand() % 1000; @@ -310,7 +308,7 @@ tx_stress_1_test() tx_stress_1_gap_event, NULL); if (rc != 0) { - MODLOG_DFLT(INFO, "\033[0;31mConnection error; rc=%d\033[0m\n", + MODLOG_DFLT(ERROR, "Connection error; rc=%d\n", rc); os_sem_release(&tx_stress_main_sem); return; @@ -318,9 +316,8 @@ tx_stress_1_test() os_time_delay(os_time_ms_to_ticks32(delay_time)); - MODLOG_DFLT(INFO, "Connect cancel\n"); + MODLOG_DFLT(DEBUG, "Connect cancel\n"); ble_gap_conn_cancel(); - console_printf("\033[0;32m>\033[0m"); } tx_stress_on_test_finish(1); @@ -336,7 +333,9 @@ tx_stress_2_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_CONNECT: /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { - MODLOG_DFLT(INFO, "Success to connect to device\n"); + MODLOG_DFLT(INFO, "Success to connect to device, conn " + "handle=%d\n", + event->connect.conn_handle); ++tx_stress_ctx->con_stat[2].num; rc = ble_gap_conn_find(event->connect.conn_handle, &desc); @@ -344,19 +343,23 @@ tx_stress_2_gap_event(struct ble_gap_event *event, void *arg) tx_stress_ctx->conn_handle = desc.conn_handle; - ble_gap_terminate(event->connect.conn_handle, + rc = ble_gap_terminate(event->connect.conn_handle, BLE_ERR_REM_USER_CONN_TERM); + + MODLOG_DFLT(INFO, "Connection terminated; conn handle=%d, rc=%d\n", + event->connect.conn_handle, rc); } else { - MODLOG_DFLT(INFO, "\033[0;31mError: connection attempt failed; " - "status=%d\033[0m\n", event->connect.status); + MODLOG_DFLT(ERROR, "Error: connection attempt failed; " + "status=%d; conn handle=%d;\n", + event->connect.status, + event->connect.conn_handle); os_sem_release(&tx_stress_main_sem); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); - console_printf("\033[0;32m>\033[0m"); if (tx_stress_ctx->con_stat[2].num >= MYNEWT_VAL(BLE_STRESS_REPEAT)) { tx_stress_on_test_finish(2); @@ -382,23 +385,23 @@ tx_stress_3_gap_event(struct ble_gap_event *event, void *arg) /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { ++tx_stress_ctx->con_stat[3].num; - MODLOG_DFLT(INFO, "Success to connect to device\n"); + MODLOG_DFLT(INFO, "Success to connect to device; conn " + "handle=%d\n", event->connect.conn_handle); rc = ble_gap_terminate(event->connect.conn_handle, BLE_ERR_REM_USER_CONN_TERM); - MODLOG_DFLT(INFO, "rc=%d\n", rc); + MODLOG_DFLT(DEBUG, "rc=%d\n", rc); } else { - MODLOG_DFLT(INFO, "\033[0;31mError: connection attempt failed; " - "status=%d\033[0m\n", event->connect.status); + MODLOG_DFLT(ERROR, "Error: connection attempt failed; " + "status=%d\n", event->connect.status); os_sem_release(&tx_stress_main_sem); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); - console_printf("\033[0;32m>\033[0m"); if (tx_stress_ctx->con_stat[3].num >= MYNEWT_VAL(BLE_STRESS_REPEAT)) { tx_stress_on_test_finish(3); @@ -409,7 +412,7 @@ tx_stress_3_gap_event(struct ble_gap_event *event, void *arg) return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -438,13 +441,12 @@ tx_stress_4_con_update(void) rc = ble_gap_update_params(tx_stress_ctx->conn_handle, ¶ms); if (rc == BLE_HS_ENOTCONN) { - MODLOG_DFLT(INFO, "Device disconnected. Connection update failed\n"); + MODLOG_DFLT(ERROR, "Device disconnected. Connection update failed\n"); assert(0); } if (rc != 0) { - MODLOG_DFLT(ERROR, "\033[0;31mError during connection update; " - "rc=%d\033[0m\n", rc); + MODLOG_DFLT(ERROR, "Error during connection update; rc=%d\n", rc); assert(0); } @@ -468,25 +470,24 @@ tx_stress_4_gap_event(struct ble_gap_event *event, void *arg) tx_stress_4_con_update(); } else { - MODLOG_DFLT(INFO, "\033[0;31mError: connection attempt failed; " - "status=%d\033[0m\n", event->connect.status); + MODLOG_DFLT(ERROR, "Error: connection attempt failed; " + "status=%d\n", event->connect.status); os_sem_release(&tx_stress_main_sem); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); tx_stress_on_test_finish(4); return 0; case BLE_GAP_EVENT_CONN_UPDATE: if (event->conn_update.status != 0) { - MODLOG_DFLT(INFO, "Connection update failed\n"); + MODLOG_DFLT(WARN, "Connection update failed\n"); } else { MODLOG_DFLT(INFO, "Connection updated; num=%d\n", ++tx_stress_ctx->con_stat[4].prms_upd_num); - console_printf("\033[0;32m>\033[0m"); } if (tx_stress_ctx->con_stat[4].prms_upd_num >= @@ -498,19 +499,18 @@ tx_stress_4_gap_event(struct ble_gap_event *event, void *arg) rc = tx_stress_4_con_update(); if (rc != 0) { - MODLOG_DFLT(INFO, "\033[0;31mError: update fail; " - "rc=%d\033[0m\n", rc); + MODLOG_DFLT(ERROR, "Error: update fail; rc=%d\n", rc); os_sem_release(&tx_stress_main_sem); } } return 0; case BLE_GAP_EVENT_CONN_UPDATE_REQ: - MODLOG_DFLT(INFO, "Connection update request\n"); + MODLOG_DFLT(DEBUG, "Connection update request\n"); return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -527,25 +527,24 @@ tx_stress_5_gap_event(struct ble_gap_event *event, void *arg) ++tx_stress_ctx->con_stat[5].num; tx_stress_ctx->conn_handle = event->connect.conn_handle; } else { - console_printf("\033[0;31mError: Update fail; " - "status=%d\033[0m\n", event->connect.status); + MODLOG_DFLT(ERROR, "Error: Update fail; status=%d\n", + event->connect.status); os_sem_release(&tx_stress_main_sem); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); tx_stress_on_test_finish(5); return 0; case BLE_GAP_EVENT_CONN_UPDATE: if (event->conn_update.status != 0) { - MODLOG_DFLT(INFO, "Connection update failed\n"); + MODLOG_DFLT(DEBUG, "Connection update failed\n"); } else { MODLOG_DFLT(INFO, "Connection updated; num=%d\n", ++tx_stress_ctx->con_stat[5].prms_upd_num); - console_printf("\033[0;32m>\033[0m"); } if (tx_stress_ctx->con_stat[5].prms_upd_num >= @@ -556,11 +555,11 @@ tx_stress_5_gap_event(struct ble_gap_event *event, void *arg) return 0; case BLE_GAP_EVENT_CONN_UPDATE_REQ: - MODLOG_DFLT(INFO, "Connection update request\n"); + MODLOG_DFLT(DEBUG, "Connection update request\n"); return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -622,9 +621,9 @@ tx_stress_6_gap_event(struct ble_gap_event *event, void *arg) BLE_GAP_EXT_ADV_DATA_STATUS_COMPLETE) { /* Got all packets of advert. */ ++tx_stress_ctx->s6_rcv_adv_suc; + MODLOG_DFLT(INFO, "Adv data=%" PRIu8 "\n", *(event->ext_disc.data)); MODLOG_DFLT(INFO, "Got all packets of advert. num=%d\n", tx_stress_ctx->s6_rcv_adv_suc); - console_printf("\033[0;32m>\033[0m"); start_id = 0; if (tx_stress_ctx->s6_rcv_adv_suc >= @@ -637,12 +636,12 @@ tx_stress_6_gap_event(struct ble_gap_event *event, void *arg) return 0; case BLE_GAP_EVENT_DISC_COMPLETE: - MODLOG_DFLT(INFO, "Discovery complete; reason=%d\n", + MODLOG_DFLT(DEBUG, "Discovery complete; reason=%d\n", event->disc_complete.reason); return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -704,14 +703,17 @@ tx_stress_7_phy_update(void) rc = ble_gap_set_prefered_le_phy(tx_stress_ctx->conn_handle, tx_phys_mask, rx_phys_mask, 0); + MODLOG_DFLT(INFO, "Set PHY params: tx_phys_mask=%d; rx_phys_mask=%d\n", + tx_phys_mask, rx_phys_mask); + if (rc == BLE_HS_ENOTCONN) { - MODLOG_DFLT(INFO, "Device disconnected. Connection update failed\n"); + MODLOG_DFLT(WARN, "Device disconnected. Connection update failed\n"); return rc; } if (rc != 0) { - MODLOG_DFLT(ERROR, "\033[0;31mError during PHY update; " - "rc=%d\033[0m\n", rc); + MODLOG_DFLT(ERROR, "Error during PHY update; " + "rc=%d\n", rc); } return rc; @@ -726,41 +728,40 @@ tx_stress_7_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_CONNECT: /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { - MODLOG_DFLT(INFO, "Success to connect to device\n"); + MODLOG_DFLT(DEBUG, "Success to connect to device\n"); ++tx_stress_ctx->con_stat[7].num; tx_stress_ctx->conn_handle = event->connect.conn_handle; tx_stress_7_phy_update(); } else { - console_printf("\033[0;31mError: Update fail; " - "status=%d\033[0m\n", event->connect.status); + MODLOG_DFLT(ERROR, "Error: Update fail; " + "status=%d\n", event->connect.status); os_sem_release(&tx_stress_main_sem); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); tx_stress_on_test_finish(7); return 0; case BLE_GAP_EVENT_CONN_UPDATE: - MODLOG_DFLT(INFO, "Connection updated\n"); + MODLOG_DFLT(DEBUG, "Connection updated\n"); return 0; case BLE_GAP_EVENT_CONN_UPDATE_REQ: - MODLOG_DFLT(INFO, "Connection update request\n"); + MODLOG_DFLT(DEBUG, "Connection update request\n"); return 0; case BLE_GAP_EVENT_PHY_UPDATE_COMPLETE: if (event->phy_updated.status != 0) { - MODLOG_DFLT(INFO, "PHY update failed\n"); + MODLOG_DFLT(WARN, "PHY update failed\n"); } else { MODLOG_DFLT(INFO, "PHY updated; num=%d; rx:%d, tx:%d\n", ++tx_stress_ctx->con_stat[7].phy_upd_num, event->phy_updated.rx_phy, event->phy_updated.tx_phy); - console_printf("\033[0;32m>\033[0m"); } if (tx_stress_ctx->con_stat[7].phy_upd_num >= @@ -771,8 +772,9 @@ tx_stress_7_gap_event(struct ble_gap_event *event, void *arg) /* Update connection. */ rc = tx_stress_7_phy_update(); if (rc != 0) { - console_printf("\033[0;31mError: PHPY update fail; " - "rc=%d\033[0m\n", event->phy_updated.status); + MODLOG_DFLT(ERROR, "Error: PHPY update fail; " + "rc=%d\n", + event->phy_updated.status); assert(0); } } @@ -791,43 +793,43 @@ tx_stress_8_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_CONNECT: /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { - MODLOG_DFLT(INFO, "Success to connect to device\n"); + MODLOG_DFLT(DEBUG, "Success to connect to device\n"); ++tx_stress_ctx->con_stat[8].num; tx_stress_ctx->conn_handle = event->connect.conn_handle; } else { - MODLOG_DFLT(INFO, "\033[0;31mError: connection attempt failed; " - "status=%d\033[0m\n", event->connect.status); + MODLOG_DFLT(ERROR, "Error: connection attempt failed; " + "status=%d\n", event->connect.status); os_sem_release(&tx_stress_main_sem); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); tx_stress_on_test_finish(8); return 0; case BLE_GAP_EVENT_CONN_UPDATE: if (event->conn_update.status != 0) { - MODLOG_DFLT(INFO, "Connection update failed\n"); + MODLOG_DFLT(DEBUG, "Connection update failed\n"); } else { - MODLOG_DFLT(INFO, "Connection updated; num=%d\n", + MODLOG_DFLT(DEBUG, "Connection updated; num=%d\n", ++tx_stress_ctx->con_stat[8].prms_upd_num); } return 0; case BLE_GAP_EVENT_CONN_UPDATE_REQ: - MODLOG_DFLT(INFO, "Connection update request\n"); + MODLOG_DFLT(DEBUG, "Connection update request\n"); return 0; case BLE_GAP_EVENT_PHY_UPDATE_COMPLETE: if (event->phy_updated.status != 0) { - MODLOG_DFLT(INFO, "PHY update failed\n"); + MODLOG_DFLT(WARN, "PHY update failed\n"); } else { - MODLOG_DFLT(INFO, "PHY updated; num=%d\n", - ++tx_stress_ctx->con_stat[8].phy_upd_num); - console_printf("\033[0;32m>\033[0m"); + MODLOG_DFLT(INFO, "PHY updated; num=%d; rx:%d, tx:%d\n", + ++tx_stress_ctx->con_stat[8].phy_upd_num, + event->phy_updated.rx_phy, event->phy_updated.tx_phy); } if (tx_stress_ctx->con_stat[8].phy_upd_num >= @@ -876,7 +878,7 @@ tx_stress_9_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_DISC_COMPLETE: if (event->disc_complete.reason == 0 && !tx_stress_ctx->completed[9]) { - console_printf("\033[0;31mScanning timeout\033[0m"); + MODLOG_DFLT(ERROR, "Scanning timeout"); tx_stress_ctx->completed[9] = true; os_sem_release(&tx_stress_main_sem); return 0; @@ -886,24 +888,24 @@ tx_stress_9_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_CONNECT: /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { - MODLOG_DFLT(INFO, "Success to connect to device\n"); + MODLOG_DFLT(INFO, "Success to connect to device, conn " + "handle=%d\n", event->connect.conn_handle); MODLOG_DFLT(INFO, "Connections num: %d\n", ++tx_stress_ctx->con_stat[9].num); - console_printf("\033[0;32m>\033[0m"); /* Remember max number of handled connections */ if (tx_stress_ctx->con_stat[9].num > tx_stress_ctx->con_stat[9].max_num) { tx_stress_ctx->con_stat[9].max_num = tx_stress_ctx->con_stat[9].num; } } else { - MODLOG_DFLT(INFO, "\033[0;31mError: connection attempt failed; " - "status=%d\033[0m\n", event->connect.status); + MODLOG_DFLT(ERROR, "Error: connection attempt failed; " + "status=%d\n", event->connect.status); } break; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d ", event->disconnect.reason); - console_printf("\033[0;31mX\033[0m"); + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d; conn handle=%d", + event->disconnect.reason); MODLOG_DFLT(INFO, "Connections num: %d\n", --tx_stress_ctx->con_stat[9].num); @@ -914,7 +916,7 @@ tx_stress_9_gap_event(struct ble_gap_event *event, void *arg) break; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } @@ -956,7 +958,7 @@ tx_stress_9_perform() for (i = 0; i <= MYNEWT_VAL(BLE_MAX_CONNECTIONS); ++i) { rc = ble_gap_conn_find(i, NULL); if (rc == 0) { - MODLOG_DFLT(INFO, "Terminating...\n"); + MODLOG_DFLT(DEBUG, "Terminating...\n"); ble_gap_terminate(i, BLE_ERR_REM_USER_CONN_TERM); } } @@ -1081,19 +1083,19 @@ tx_stress_10_l2cap_event(struct ble_l2cap_event *event, void *arg) /* Time of data sending */ us = tx_stress_ctx->end_us - tx_stress_ctx->begin_us; - MODLOG_DFLT(INFO, "Time of receiving L2CAP data: %ld \n", + MODLOG_DFLT(DEBUG, "Time of receiving L2CAP data: %ld \n", tx_stress_ctx->end_us); /* Remember size of entire mbuf chain */ tx_stress_ctx->rcv_data_bytes = OS_MBUF_PKTLEN( event->receive.sdu_rx); - MODLOG_DFLT(INFO, "Num of received bytes: %lld\n", + MODLOG_DFLT(DEBUG, "Num of received bytes: %lld\n", tx_stress_ctx->rcv_data_bytes); /* Calculate the bit rate of this send */ tx_stress_ctx->s10_bit_rate = stress_calc_bit_rate(us, tx_stress_ctx->rcv_data_bytes); - MODLOG_DFLT(INFO, "Bit rate: %d B/s\n", tx_stress_ctx->s10_bit_rate); + MODLOG_DFLT(DEBUG, "Bit rate: %d B/s\n", tx_stress_ctx->s10_bit_rate); /* Remember the sum of bytes and the time to calculate the average * bit rate. */ @@ -1104,7 +1106,6 @@ tx_stress_10_l2cap_event(struct ble_l2cap_event *event, void *arg) if (tx_stress_ctx->s10_max_mtu < tx_stress_ctx->rcv_data_bytes) { tx_stress_ctx->s10_max_mtu = tx_stress_ctx->rcv_data_bytes; } - console_printf("\033[0;32m>\033[0m"); MODLOG_DFLT(INFO, "Loop nr: %d\n", ++i); tx_stress_10_l2cap_send_req(); @@ -1142,8 +1143,8 @@ tx_stress_10_gap_event(struct ble_gap_event *event, void *arg) tx_stress_10_l2cap_event, NULL); assert(rc == 0); } else { - MODLOG_DFLT(INFO, "\033[0;31mError: connection attempt failed; " - "status=%d\033[0m\n", event->connect.status); + MODLOG_DFLT(ERROR, "Error: connection attempt failed; " + "status=%d\n", event->connect.status); } return 0; @@ -1151,13 +1152,13 @@ tx_stress_10_gap_event(struct ble_gap_event *event, void *arg) tx_stress_ctx->s10_bit_rate = 1000000 * tx_stress_ctx->bytes_sum / tx_stress_ctx->time_sum; - MODLOG_DFLT(INFO, "Average bit rate: %d B/s\n", + MODLOG_DFLT(DEBUG, "Average bit rate: %d B/s\n", tx_stress_ctx->s10_bit_rate); tx_stress_on_test_finish(10); return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -1187,18 +1188,18 @@ tx_stress_11_gap_event(struct ble_gap_event *event, void *arg) /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { ++tx_stress_ctx->con_stat[11].num; - MODLOG_DFLT(INFO, "Success to connect to device\n"); + MODLOG_DFLT(INFO, "Success to connect to device; conn " + "handle=%d\n", event->connect.conn_handle); } else { - MODLOG_DFLT(INFO, "\033[0;31mError: connection attempt failed; " - "status=%d\033[0m\n", event->connect.status); + MODLOG_DFLT(ERROR, "Error: connection attempt failed; " + "status=%d\n", event->connect.status); break; } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); - console_printf("\033[0;32m>\033[0m"); if (tx_stress_ctx->con_stat[11].num >= MYNEWT_VAL(BLE_STRESS_REPEAT)) { tx_stress_on_test_finish(11); @@ -1207,7 +1208,7 @@ tx_stress_11_gap_event(struct ble_gap_event *event, void *arg) break; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } @@ -1227,16 +1228,16 @@ tx_stress_12_gap_event(struct ble_gap_event *event, void *arg) /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { ++tx_stress_ctx->con_stat[12].num; - MODLOG_DFLT(INFO, "Success to connect to device\n"); + MODLOG_DFLT(DEBUG, "Success to connect to device\n"); tx_stress_ctx->conn_handle = event->connect.conn_handle; } else { - MODLOG_DFLT(INFO, "\033[0;31mError: connection attempt failed; " - "status=%d\033[0m\n", event->connect.status); + MODLOG_DFLT(ERROR, "Error: connection attempt failed; " + "status=%d\n", event->connect.status); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); /* Finish test after first disconnection */ tx_stress_on_test_finish(12); @@ -1244,12 +1245,11 @@ tx_stress_12_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_NOTIFY_RX: /* Received indication */ - MODLOG_DFLT(INFO, "Notify RX event\n"); - console_printf("\033[0;32m>\033[0m"); + MODLOG_DFLT(INFO, "Received indication\n"); return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -1262,30 +1262,30 @@ tx_stress_13_gap_event(struct ble_gap_event *event, void *arg) /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { ++tx_stress_ctx->con_stat[13].num; - MODLOG_DFLT(INFO, "Success to connect to device\n"); + MODLOG_DFLT(DEBUG, "Success to connect to device\n"); tx_stress_ctx->conn_handle = event->connect.conn_handle; } else { - MODLOG_DFLT(INFO, "\033[0;31mError: connection attempt failed; " - "status=%d\033[0m\n", event->connect.status); + MODLOG_DFLT(ERROR, "Error: connection attempt failed; " + "status=%d\n", event->connect.status); assert(0); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); /* Finish test after disconnection */ tx_stress_on_test_finish(13); return 0; case BLE_GAP_EVENT_NOTIFY_RX: - MODLOG_DFLT(INFO, "Notify RX event\n"); - console_printf("\033[0;32m>\033[0m"); ++tx_stress_ctx->rcv_num; + MODLOG_DFLT(INFO, "Received notification; count=%d\n", + tx_stress_ctx->rcv_num); return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -1354,7 +1354,7 @@ tx_stress_14_gap_event(struct ble_gap_event *event, void *arg) /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { ++tx_stress_ctx->con_stat[14].num; - MODLOG_DFLT(INFO, "Success to connect to device\n"); + MODLOG_DFLT(DEBUG, "Success to connect to device\n"); tx_stress_ctx->conn_handle = event->connect.conn_handle; /* Find CCCD handle (with default UUID16 = 0x2902) */ @@ -1364,21 +1364,21 @@ tx_stress_14_gap_event(struct ble_gap_event *event, void *arg) BLE_UUID16_DECLARE(0x2902), &tx_stress_14_disc_cccd_fn); } else { - MODLOG_DFLT(INFO, "\033[0;31mError: connection attempt failed; " - "status=%d\033[0m\n", event->connect.status); + MODLOG_DFLT(ERROR, "Error: connection attempt failed; " + "status=%d\n", event->connect.status); assert(0); } return 0; case BLE_GAP_EVENT_DISCONNECT: - MODLOG_DFLT(INFO, "Disconnect; reason=%d \n", + MODLOG_DFLT(DEBUG, "Disconnect; reason=%d \n", event->disconnect.reason); /* Calc average notifying time */ if (tx_stress_ctx->rcv_num > 0) { tx_stress_ctx->s14_notif_time = tx_stress_ctx->time_sum / tx_stress_ctx->rcv_num; } - MODLOG_DFLT(INFO, "Average notification time: %d\n", + MODLOG_DFLT(DEBUG, "Average notification time: %d\n", tx_stress_ctx->s14_notif_time); /* Finish test after first disconnection */ tx_stress_on_test_finish(14); @@ -1386,20 +1386,19 @@ tx_stress_14_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_NOTIFY_RX: tx_stress_ctx->end_us = os_get_uptime_usec(); - MODLOG_DFLT(INFO, "Notify RX event\n"); + MODLOG_DFLT(DEBUG, "Notify RX event\n"); /* Time of data sending */ us = tx_stress_ctx->end_us - tx_stress_ctx->begin_us; - MODLOG_DFLT(INFO, "Notification time: %lld\n us", us); + MODLOG_DFLT(DEBUG, "Notification time: %lld\n us", us); tx_stress_ctx->time_sum += us; - console_printf("\033[0;32m>\033[0m"); /* Perform use case specified number of times */ if (++tx_stress_ctx->rcv_num >= MYNEWT_VAL(BLE_STRESS_REPEAT)) { rc = ble_gap_terminate(event->notify_rx.conn_handle, BLE_ERR_REM_USER_CONN_TERM); - MODLOG_DFLT(INFO, "rc=%d\n", rc); + MODLOG_DFLT(DEBUG, "rc=%d\n", rc); assert(rc == 0); return 0; } @@ -1416,7 +1415,7 @@ tx_stress_14_gap_event(struct ble_gap_event *event, void *arg) return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -1427,7 +1426,6 @@ tx_stress_15_write_cb(uint16_t conn_handle, const struct ble_gatt_error *error, { /* Disconnect */ ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM); - console_printf("\033[0;32m>\033[0m"); return 0; } @@ -1438,7 +1436,7 @@ tx_stress_15_disc_chr_fn(struct stress_gatt_search_ctx *search_ctx) struct os_mbuf *om; /* Send some data */ - MODLOG_DFLT(INFO, "Write to chr\n"); + MODLOG_DFLT(DEBUG, "Write to chr\n"); om = ble_hs_mbuf_from_flat(test_6_pattern, 20); rc = ble_gattc_write(tx_stress_ctx->conn_handle, @@ -1454,7 +1452,7 @@ tx_stress_15_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_CONNECT: /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { - MODLOG_DFLT(INFO, "Success to connect to device; num: %d\n", + MODLOG_DFLT(DEBUG, "Success to connect to device; num: %d\n", ++tx_stress_ctx->con_stat[15].num); tx_stress_ctx->conn_handle = event->connect.conn_handle; @@ -1464,8 +1462,8 @@ tx_stress_15_gap_event(struct ble_gap_event *event, void *arg) BLE_UUID16_DECLARE(STRESS_GATT_WRITE_UUID), &tx_stress_15_disc_chr_fn); } else { - MODLOG_DFLT(INFO, "\033[0;31mError: connection attempt failed; " - "status=%d\033[0m\n", event->connect.status); + MODLOG_DFLT(ERROR, "Error: connection attempt failed; " + "status=%d\n", event->connect.status); assert(0); } return 0; @@ -1481,7 +1479,7 @@ tx_stress_15_gap_event(struct ble_gap_event *event, void *arg) return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -1513,12 +1511,12 @@ scan_for_test_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_DISC_COMPLETE: /* On timeout */ tx_stress_ctx->scan_timeout = true; - console_printf("\033[1;36mDiscover complete\033[0m\n"); + MODLOG_DFLT(DEBUG, "Discover complete\n"); os_sem_release(&tx_stress_main_sem); return 0; default: - MODLOG_DFLT(INFO, "Other event occurs=%d\n", event->type); + MODLOG_DFLT(DEBUG, "Other event occurs=%d\n", event->type); return 0; } } @@ -1535,75 +1533,74 @@ tx_stress_test_perform(int test_num) tx_stress_ctx->completed[test_num] = false; tx_stress_ctx->conn_handle = 0xffff; - console_printf("\033[1;36mStart test num %d - ", test_num); + MODLOG_DFLT(INFO, "Start test num %d - ", test_num); /* Start test */ switch (test_num) { case 0: return; case 1: - console_printf("Stress Connect -> Connect Cancel\033[0m\n"); + MODLOG_DFLT(INFO, "Stress Connect -> Connect Cancel\n"); tx_stress_1_test(); break; case 2: - console_printf("Stress Connect/Disconnect legacy\033[0m\n"); + MODLOG_DFLT(INFO, "Stress Connect/Disconnect legacy\n"); tx_stress_simple_connect(&tx_stress_2_gap_event, 2, NULL); break; case 3: - console_printf("Stress Connect/Disconnect ext adv\033[0m\n"); + MODLOG_DFLT(INFO, "Stress Connect/Disconnect ext adv\n"); tx_stress_simple_connect(&tx_stress_3_gap_event, 3, NULL); break; case 4: - console_printf("Stress connection params update (TX)\033[0m\n"); + MODLOG_DFLT(INFO, "Stress connection params update (TX)\n"); tx_stress_simple_connect(&tx_stress_4_gap_event, 4, NULL); break; case 5: - console_printf("Stress connection params update (RX)\033[0m\n"); + MODLOG_DFLT(INFO, "Stress connection params update (RX)\n"); tx_stress_simple_connect(&tx_stress_5_gap_event, 5, NULL); break; case 6: - console_printf("Stress Scan\033[0m\n"); + MODLOG_DFLT(INFO, "Stress Scan\n"); tx_stress_6_perform(); break; case 7: - console_printf("Stress PHY Update (TX)\033[0m\n"); + MODLOG_DFLT(INFO, "Stress PHY Update (TX)\n"); tx_stress_simple_connect(&tx_stress_7_gap_event, 7, NULL); break; case 8: - console_printf("Stress PHY Update (RX)\033[0m\n"); + MODLOG_DFLT(INFO, "Stress PHY Update (RX)\n"); tx_stress_simple_connect(&tx_stress_8_gap_event, 8, NULL); break; case 9: - console_printf("Stress multi connection\033[0m\n"); + MODLOG_DFLT(INFO, "Stress multi connection\n"); tx_stress_9_perform(); break; case 10: - console_printf("Stress L2CAP send\033[0m\n"); + MODLOG_DFLT(INFO, "Stress L2CAP send\n"); tx_stress_simple_connect(&tx_stress_10_gap_event, 10, NULL); break; case 11: - console_printf("Stress Advertise/Connect/Disconnect\033[0m\n"); + MODLOG_DFLT(INFO, "Stress Advertise/Connect/Disconnect\n"); tx_stress_simple_connect(&tx_stress_11_gap_event, 11, NULL); break; case 12: - console_printf("Stress GATT indication\033[0m\n"); + MODLOG_DFLT(INFO, "Stress GATT indication\n"); tx_stress_simple_connect(&tx_stress_12_gap_event, 12, NULL); break; case 13: - console_printf("Stress GATT notification\033[0m\n"); + MODLOG_DFLT(INFO, "Stress GATT notification\n"); tx_stress_simple_connect(&tx_stress_13_gap_event, 13, NULL); break; case 14: - console_printf("Stress GATT Subscribe/Notify/Unsubscribe\033[0m\n"); + MODLOG_DFLT(INFO, "Stress GATT Subscribe/Notify/Unsubscribe\n"); tx_stress_simple_connect(&tx_stress_14_gap_event, 14, NULL); break; case 15: - console_printf("Stress Connect/Send/Disconnect\033[0m\n"); + MODLOG_DFLT(INFO, "Stress Connect/Send/Disconnect\n"); tx_stress_simple_connect(&tx_stress_15_gap_event, 15, NULL); break; default: - console_printf("\033[0;31mFound test, but do not know how to perform." - "\033[0m\n"); + MODLOG_DFLT(ERROR, "Found test, but do not know how to perform.\n"); assert(0); } @@ -1617,7 +1614,7 @@ tx_stress_test_perform(int test_num) static void tx_stress_read_command_cb(void) { - console_printf("Start testing\n"); + MODLOG_DFLT(INFO, "Start testing\n"); os_sem_release(&tx_stress_main_sem); } @@ -1628,8 +1625,8 @@ tx_stress_main_task_fn(void *arg) tx_stress_ctx = &tx_stress_ctxD; - console_printf("\033[1;36mTX device\033[0m\n"); - console_printf("Press ENTER to start: \n"); + MODLOG_DFLT(INFO, "TX device\n"); + MODLOG_DFLT(INFO, "Press ENTER to start: \n"); console_init(&tx_stress_read_command_cb); /* Waite for pressing ENTER in console */ @@ -1643,7 +1640,7 @@ tx_stress_main_task_fn(void *arg) //tx_stress_test_perform(1); while (1) { - console_printf("\033[0;36mStart scan for test\033[0m\n"); + MODLOG_DFLT(INFO, "Start scan for test\n"); /* Scan for known UUID128 of one of the stress tests. */ tx_stress_simple_scan(scan_for_test_gap_event, 2000); From 24a0f7e22c7ebca6c3621590ad07fcbca86af3e7 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 26 Nov 2024 09:52:22 +0100 Subject: [PATCH 1147/1333] apps: Remove leaudio_broadcaster application This removes apps/leaudio_broadcaster application as it duplicates the apps/auracast application functionality. --- apps/leaudio_broadcaster/pkg.yml | 39 - apps/leaudio_broadcaster/src/audio_data.h | 4412 --------------------- apps/leaudio_broadcaster/src/main.c | 404 -- apps/leaudio_broadcaster/syscfg.yml | 66 - 4 files changed, 4921 deletions(-) delete mode 100644 apps/leaudio_broadcaster/pkg.yml delete mode 100644 apps/leaudio_broadcaster/src/audio_data.h delete mode 100644 apps/leaudio_broadcaster/src/main.c delete mode 100644 apps/leaudio_broadcaster/syscfg.yml diff --git a/apps/leaudio_broadcaster/pkg.yml b/apps/leaudio_broadcaster/pkg.yml deleted file mode 100644 index 95439284c7..0000000000 --- a/apps/leaudio_broadcaster/pkg.yml +++ /dev/null @@ -1,39 +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. -# - -pkg.name: apps/leaudio_broadcaster -pkg.type: app -pkg.description: LE Audio Broadcast sample application. - -pkg.author: "Krzysztof Kopyściński" -pkg.email: "krzysztof.kopyscinski@codecoup.pl" -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - -pkg.deps: - - nimble/host - - nimble/host/util - - nimble/host/services/gap - - nimble/host/store/config - - nimble/host/audio - - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console" - - "@apache-mynewt-core/sys/log" - - "@apache-mynewt-core/sys/stats" - - "@apache-mynewt-core/sys/sysinit" - - "@apache-mynewt-core/sys/id" diff --git a/apps/leaudio_broadcaster/src/audio_data.h b/apps/leaudio_broadcaster/src/audio_data.h deleted file mode 100644 index 0bb90a4a1f..0000000000 --- a/apps/leaudio_broadcaster/src/audio_data.h +++ /dev/null @@ -1,4412 +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. - */ - -/** LC3 coded audio data, with 48kHz sample rate. - * Audio signal coded here is 100Hz-20kHz sweep signal, in sinus form - */ -const uint8_t audio_data[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x33, 0x99, 0xb9, 0x51, 0x64, 0x62, 0x1d, 0x6c, 0x3c, 0xf8, 0xae, 0xb5, 0xbd, 0x64, 0xba, 0x9e, - 0xe2, 0x0c, 0x72, 0x7a, 0x4c, 0xdc, 0xed, 0x84, 0x9d, 0x8a, 0x75, 0x28, 0x61, 0x88, 0xcc, 0x11, - 0xef, 0x66, 0x35, 0x9e, 0xbf, 0x34, 0xdd, 0x56, 0xcb, 0x39, 0x9a, 0xed, 0x53, 0xe7, 0xc6, 0x6e, - 0x73, 0x53, 0x29, 0x4e, 0x02, 0x2f, 0xb2, 0x65, 0x81, 0xe9, 0xb6, 0xee, 0xf5, 0x35, 0x20, 0xfc, - 0xc1, 0x31, 0x7e, 0x63, 0x28, 0x9f, 0x03, 0xe0, 0x7e, 0x07, 0xe0, 0x7e, 0x07, 0xe0, 0x3d, 0xe0, - 0xf9, 0x11, 0xcf, 0x5d, 0xab, 0x9c, 0xc4, 0x78, 0xed, 0x64, 0xbd, 0x3e, 0x4c, 0x6b, 0x06, 0x27, - 0x1a, 0x80, 0xf1, 0xb0, 0xec, 0x96, 0x4a, 0x21, 0x07, 0xb2, 0x13, 0xf0, 0x3f, 0x03, 0xf3, 0x02, - 0x38, 0x26, 0x1e, 0x8b, 0x82, 0x6a, 0x63, 0x34, 0x33, 0x9e, 0x72, 0xd8, 0xa9, 0x96, 0xbe, 0x10, - 0x87, 0xca, 0x68, 0x69, 0x81, 0xa0, 0x5e, 0x6d, 0xeb, 0xbb, 0x09, 0x50, 0x8c, 0x3c, 0xda, 0xbd, - 0x5b, 0x20, 0x77, 0xae, 0xa8, 0x4f, 0x74, 0xde, 0x0a, 0xa7, 0xe4, 0x2f, 0x0a, 0x8c, 0x91, 0x84, - 0xb5, 0x97, 0x9e, 0xdf, 0x04, 0x86, 0xce, 0x02, 0xdc, 0xa2, 0xf2, 0x33, 0x0c, 0xe5, 0x0d, 0x2a, - 0x36, 0x59, 0xd7, 0x03, 0x0c, 0xb7, 0xb3, 0xa1, 0xe3, 0x7f, 0x21, 0x58, 0xd1, 0x5d, 0xb8, 0x3f, - 0x03, 0xf0, 0x3f, 0x01, 0xfc, 0x07, 0xf0, 0x0f, 0xe0, 0x5f, 0x83, 0xb8, 0x07, 0x8b, 0x04, 0xe4, - 0x32, 0x08, 0x21, 0x4a, 0x97, 0x4a, 0x76, 0x4a, 0x06, 0x71, 0xba, 0x1b, 0xb9, 0x6f, 0x05, 0xb4, - 0x67, 0xf1, 0x0b, 0xee, 0x03, 0xf0, 0x1f, 0x18, 0x38, 0x26, 0x1e, 0x8f, 0x82, 0x6a, 0x63, 0x34, - 0x33, 0x99, 0xb9, 0x7c, 0x0f, 0xda, 0x8d, 0xcf, 0x8f, 0x01, 0xff, 0x62, 0x63, 0xf0, 0x32, 0x2f, - 0xd1, 0x7f, 0xc9, 0x4a, 0xe1, 0x4f, 0x8c, 0x0f, 0xf3, 0x9b, 0x09, 0xb7, 0xad, 0xdd, 0xe8, 0xba, - 0xd5, 0x9c, 0xf1, 0x88, 0x8d, 0x7f, 0x56, 0x46, 0x8b, 0x8d, 0x5a, 0x1e, 0xd1, 0xe7, 0xdf, 0x70, - 0xf5, 0x06, 0x80, 0x58, 0xb7, 0xe1, 0x9d, 0x60, 0x1e, 0xcf, 0x07, 0x7c, 0xfb, 0xdf, 0x3a, 0x26, - 0x27, 0x53, 0x54, 0xe3, 0x33, 0x8f, 0x42, 0x0f, 0x0f, 0x87, 0x81, 0xf8, 0x0f, 0xc0, 0xfe, 0x07, - 0xe0, 0x7b, 0xad, 0x59, 0x8a, 0xea, 0x1f, 0xaa, 0x87, 0x79, 0x6b, 0x6e, 0x60, 0x0c, 0x81, 0xf0, - 0x60, 0x2d, 0x62, 0x78, 0xc8, 0x1d, 0x27, 0x28, 0x0f, 0xc0, 0x3d, 0x98, 0x07, 0xe0, 0x1f, 0x10, - 0x38, 0xed, 0x92, 0x2b, 0x82, 0x6a, 0x73, 0x2c, 0xaf, 0xdd, 0x4d, 0x39, 0x00, 0xfc, 0x8e, 0x80, - 0x31, 0x4b, 0xdc, 0x52, 0x82, 0x9c, 0x16, 0x03, 0x87, 0xd5, 0xca, 0x62, 0xe5, 0xd4, 0xb3, 0x0b, - 0xe2, 0xae, 0x6c, 0x4f, 0xfe, 0x46, 0xf7, 0x90, 0xdd, 0x29, 0xf5, 0xb6, 0x42, 0x3f, 0xd1, 0x5a, - 0xa1, 0xdf, 0x46, 0x4c, 0x20, 0x4a, 0x86, 0x72, 0x5f, 0x5b, 0xc6, 0xff, 0x0d, 0x44, 0x35, 0x91, - 0xf7, 0x3d, 0xbe, 0x78, 0x7c, 0xb7, 0x03, 0x0e, 0x7d, 0x91, 0x24, 0xf2, 0xe8, 0x78, 0x1f, 0x03, - 0xf8, 0x0f, 0xe0, 0x7f, 0x03, 0xf0, 0x3e, 0x1f, 0x64, 0x1b, 0x84, 0x67, 0x94, 0x12, 0x20, 0x78, - 0xf3, 0x20, 0x26, 0x56, 0x7f, 0xd7, 0x1c, 0xf3, 0xfd, 0xf0, 0xe8, 0x29, 0xf0, 0x7c, 0xf2, 0x82, - 0x6f, 0x81, 0x07, 0x90, 0x3f, 0x03, 0xe2, 0x88, 0x31, 0x2b, 0xc8, 0x3d, 0xd2, 0x6a, 0x03, 0xcc, - 0x63, 0xc0, 0x39, 0xbf, 0x1b, 0x8d, 0x08, 0xa5, 0xfd, 0xdd, 0x32, 0x8e, 0x3c, 0x8e, 0x4c, 0x58, - 0xd8, 0x33, 0x7f, 0xa7, 0xb8, 0xbf, 0x8a, 0xbb, 0xe2, 0xd8, 0x12, 0xc5, 0x52, 0x1a, 0xe1, 0xb1, - 0x42, 0x07, 0xcc, 0x22, 0x76, 0x3e, 0x90, 0xb3, 0x00, 0xa6, 0x41, 0xb2, 0xa1, 0xd6, 0xfb, 0x57, - 0x00, 0x5b, 0xd3, 0x1e, 0x83, 0x1c, 0xab, 0x1d, 0x13, 0x25, 0x0b, 0xac, 0xff, 0x98, 0xd4, 0x57, - 0x9b, 0x0c, 0xb8, 0x0f, 0x0f, 0x87, 0xe0, 0x7e, 0x07, 0xf0, 0x1f, 0xc0, 0xf8, 0x05, 0xff, 0x9e, - 0x3b, 0x45, 0xc0, 0xfc, 0x69, 0xfc, 0x75, 0x6b, 0x4b, 0x2c, 0xc7, 0xf6, 0xbf, 0x22, 0x2c, 0xea, - 0x17, 0x89, 0xc3, 0x7f, 0x08, 0xee, 0x38, 0x22, 0x67, 0x74, 0x65, 0x0f, 0x7f, 0x00, 0xf7, 0x04, - 0x27, 0x38, 0xa9, 0xbf, 0xd2, 0x6a, 0x23, 0x1c, 0x63, 0xc6, 0xc2, 0x42, 0xcd, 0x56, 0x9d, 0x10, - 0x13, 0xbe, 0xdb, 0x5f, 0x7c, 0x58, 0x95, 0x42, 0xb0, 0xf7, 0x0c, 0xe7, 0xa2, 0x41, 0x72, 0x06, - 0xd0, 0xa2, 0x50, 0xd7, 0x6e, 0x9b, 0xd3, 0x91, 0xf9, 0x36, 0xea, 0x12, 0x6b, 0x10, 0xdc, 0x17, - 0xd5, 0x1d, 0xab, 0x1a, 0xea, 0x55, 0xe8, 0xba, 0xf4, 0x3d, 0x68, 0x0a, 0x46, 0x18, 0xc7, 0xef, - 0xfe, 0x94, 0x1f, 0x80, 0x52, 0x23, 0x36, 0x0e, 0x7a, 0xf4, 0xb7, 0x03, 0xf0, 0x7e, 0x07, 0xe0, - 0x7e, 0x07, 0xe0, 0x3f, 0x03, 0xe0, 0xeb, 0xed, 0xd1, 0x6a, 0xb9, 0xd0, 0xaa, 0x93, 0x61, 0xe7, - 0x00, 0xea, 0x7a, 0x34, 0x0e, 0x80, 0x04, 0x20, 0x86, 0x8f, 0xd7, 0x96, 0x22, 0xff, 0x64, 0x45, - 0xed, 0xc0, 0x44, 0xf7, 0x30, 0x44, 0xf2, 0x92, 0x27, 0x50, 0x01, 0x3f, 0xd2, 0x6a, 0x23, 0x5c, - 0xa7, 0x93, 0x9c, 0x4e, 0x56, 0x0f, 0xc9, 0x0e, 0x09, 0x8f, 0x16, 0x16, 0x67, 0x00, 0xc3, 0x9c, - 0x78, 0x02, 0xca, 0xb1, 0x24, 0x26, 0x40, 0x37, 0xce, 0xd5, 0x00, 0xee, 0x86, 0x26, 0x76, 0x6b, - 0xb0, 0xb3, 0x97, 0x5f, 0x92, 0x10, 0x13, 0x95, 0xcf, 0xf6, 0x49, 0x33, 0x7b, 0x85, 0xf6, 0x01, - 0x26, 0x4e, 0x12, 0xe2, 0xc6, 0xa5, 0x19, 0x1d, 0x63, 0x97, 0xd1, 0x60, 0xfa, 0x44, 0xf8, 0x75, - 0x8f, 0x50, 0xb2, 0x2a, 0x9f, 0x07, 0xe0, 0xfc, 0x0f, 0x80, 0xfe, 0x07, 0xf0, 0x3e, 0x0f, 0xb1, - 0x05, 0x05, 0x19, 0x2c, 0x20, 0x39, 0xaf, 0x8a, 0x48, 0xe9, 0xfb, 0x4e, 0xed, 0xc7, 0xbe, 0x6f, - 0x5b, 0xac, 0x58, 0x02, 0x3c, 0x84, 0xc6, 0xf6, 0xc0, 0x40, 0xf7, 0x78, 0x4d, 0xdd, 0x8b, 0x0d, - 0xe7, 0x50, 0x01, 0x3f, 0xd2, 0x6a, 0x43, 0x2c, 0xaf, 0xdd, 0xed, 0xea, 0x51, 0x7d, 0x91, 0x2c, - 0x07, 0x57, 0x30, 0x76, 0x1d, 0xd0, 0xe8, 0x5e, 0xf5, 0x2e, 0x02, 0xa0, 0xf5, 0x04, 0x52, 0x9d, - 0x22, 0xbf, 0xda, 0x21, 0x3b, 0x04, 0x96, 0x7e, 0x4f, 0xea, 0x2d, 0x0f, 0x69, 0xf0, 0xc3, 0xc2, - 0xea, 0x8e, 0x0f, 0xd9, 0xed, 0x9f, 0x91, 0x6a, 0x71, 0x7a, 0x1b, 0x5d, 0x3f, 0xc4, 0x5b, 0x93, - 0x64, 0xfb, 0x08, 0x49, 0x96, 0xd1, 0xd5, 0xf3, 0x2e, 0x38, 0x9f, 0x96, 0xd7, 0x43, 0xc3, 0xe0, - 0xf0, 0x7c, 0x1f, 0x81, 0xf8, 0x1f, 0x83, 0xd6, 0xb7, 0x69, 0x60, 0x02, 0xec, 0x37, 0xb8, 0x28, - 0x6f, 0x34, 0x37, 0xf5, 0x1d, 0x4b, 0x4b, 0x9f, 0x97, 0xb5, 0xfa, 0x5a, 0x50, 0xa6, 0xec, 0x01, - 0x3f, 0xb0, 0x07, 0x9a, 0x42, 0x7f, 0xc3, 0x09, 0xe7, 0x50, 0x01, 0x3f, 0xd2, 0x6a, 0x14, 0x34, - 0x33, 0xd3, 0xb2, 0xb7, 0x84, 0x00, 0x6e, 0x91, 0xe1, 0x20, 0x56, 0xef, 0x8b, 0x8e, 0x44, 0x6e, - 0xe5, 0xa7, 0x44, 0x89, 0x53, 0x82, 0xb6, 0xb2, 0xa1, 0xef, 0xa8, 0x9d, 0x42, 0x98, 0xa5, 0xde, - 0x26, 0xe5, 0xf2, 0xe6, 0x33, 0x76, 0x66, 0x58, 0x45, 0xeb, 0x40, 0x57, 0xc6, 0x91, 0x06, 0x8b, - 0x1c, 0xcf, 0x58, 0x89, 0xd9, 0x41, 0x93, 0x51, 0x18, 0xfe, 0x08, 0x86, 0x4f, 0x68, 0xbf, 0x21, - 0x65, 0x19, 0x76, 0xa6, 0x87, 0xe0, 0x7e, 0x0f, 0xc0, 0xfc, 0x0f, 0xe0, 0x3f, 0x81, 0xf8, 0x73, - 0x82, 0xc4, 0x87, 0x41, 0xe7, 0x37, 0x70, 0xf0, 0x0a, 0x9e, 0xeb, 0xa3, 0x02, 0x7c, 0x17, 0x81, - 0x2c, 0x26, 0xab, 0xa3, 0xa4, 0x84, 0xe0, 0x07, 0xf3, 0x00, 0x1f, 0x6e, 0x10, 0xf3, 0xc3, 0x06, - 0x27, 0x50, 0x01, 0x3f, 0xd2, 0x6a, 0x43, 0x34, 0xaf, 0xdd, 0x47, 0x5c, 0xd0, 0x54, 0x05, 0x05, - 0xec, 0x4a, 0x53, 0xf8, 0x78, 0x29, 0xbc, 0x82, 0x18, 0x56, 0x38, 0xd4, 0xcd, 0x63, 0xde, 0x94, - 0x75, 0xba, 0xcc, 0xd3, 0xaa, 0xcb, 0xce, 0x4e, 0x27, 0x05, 0x71, 0x74, 0xa6, 0xba, 0xa7, 0xae, - 0xe2, 0x30, 0x16, 0x21, 0x1f, 0x59, 0x51, 0x74, 0xac, 0x13, 0x24, 0xd8, 0x89, 0x5b, 0x7a, 0x61, - 0xa4, 0x49, 0x3e, 0xac, 0x0e, 0xe1, 0xa1, 0xf0, 0x10, 0x78, 0x17, 0xcd, 0x04, 0xf9, 0xb7, 0xac, - 0x9f, 0x0f, 0x83, 0xe0, 0xf8, 0x1f, 0x81, 0xf8, 0x1f, 0x83, 0xc0, 0x0e, 0x9f, 0x5b, 0xda, 0x2f, - 0xdc, 0x72, 0x49, 0x73, 0x02, 0xcf, 0x94, 0x18, 0xa7, 0x16, 0x1b, 0x52, 0x14, 0x1f, 0x1b, 0x7a, - 0xfd, 0x04, 0xcf, 0xc0, 0xfc, 0x07, 0xc6, 0x82, 0x67, 0x52, 0xfc, 0x3f, 0xd2, 0x6a, 0x23, 0x44, - 0x69, 0xd4, 0x3e, 0xe9, 0x79, 0x25, 0x1d, 0x3f, 0xe3, 0x88, 0x05, 0x0b, 0x8c, 0x76, 0x29, 0x7e, - 0xe7, 0xd5, 0x8a, 0xb6, 0x5f, 0x02, 0x85, 0x0e, 0x92, 0x70, 0xb8, 0x44, 0xff, 0x73, 0x7e, 0x47, - 0xe4, 0x30, 0xa4, 0x7f, 0x8a, 0x52, 0x2d, 0x18, 0xa6, 0x28, 0xa1, 0x43, 0x41, 0x2f, 0xaa, 0x69, - 0xba, 0xdb, 0x82, 0xd2, 0xc7, 0x8b, 0xa4, 0x31, 0x85, 0x9b, 0x87, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x73, 0xec, 0x31, 0x42, 0xd2, 0xa7, 0xf9, 0x71, 0x47, 0xc3, 0xe1, 0xf8, 0x1f, 0x81, 0xf8, 0x3e, - 0x0f, 0x11, 0xe9, 0xd3, 0x35, 0xef, 0x37, 0xd6, 0xe4, 0x1a, 0xed, 0x15, 0x73, 0xa7, 0xf3, 0x93, - 0x76, 0xb1, 0x56, 0x5f, 0x78, 0xdc, 0x92, 0x39, 0xbb, 0x90, 0x03, 0xf8, 0x1f, 0x83, 0xf3, 0x05, - 0x67, 0xe7, 0xfa, 0x3f, 0xd2, 0x6a, 0x26, 0x34, 0x35, 0x15, 0x69, 0xd5, 0x3a, 0xa2, 0xc3, 0x59, - 0x46, 0x4c, 0x85, 0x96, 0xaa, 0xc2, 0x9f, 0x34, 0x4c, 0x72, 0x21, 0x98, 0xa7, 0xea, 0xfb, 0xce, - 0xf8, 0xec, 0xce, 0x01, 0x02, 0xa1, 0x70, 0x16, 0x25, 0x1b, 0x7c, 0xb2, 0x38, 0x91, 0x9c, 0xbf, - 0xb8, 0x0a, 0xd4, 0x06, 0xf7, 0x30, 0xcb, 0x51, 0xbf, 0x76, 0x56, 0x2e, 0x9a, 0xeb, 0xb5, 0x8f, - 0x2d, 0x97, 0x6c, 0xc2, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x76, 0x62, 0xab, 0xeb, 0x7d, - 0x4f, 0x07, 0xc1, 0xf0, 0x7e, 0x07, 0xe0, 0x7e, 0x0f, 0x83, 0x9c, 0x10, 0x6d, 0x2a, 0x41, 0x2c, - 0x62, 0x51, 0xc2, 0x35, 0x2d, 0xb3, 0x88, 0x9e, 0x77, 0xc1, 0xe7, 0xad, 0x83, 0xe6, 0x48, 0x80, - 0xde, 0x80, 0x0f, 0xb2, 0x03, 0xf0, 0x3e, 0x88, 0x27, 0xe7, 0xfa, 0x3f, 0xd2, 0x6a, 0x36, 0x3c, - 0xa7, 0x91, 0xec, 0x56, 0xe1, 0x98, 0x95, 0xe9, 0x1d, 0xbc, 0xc2, 0x4a, 0x52, 0x0b, 0x1c, 0x89, - 0x27, 0x28, 0x9b, 0x34, 0x2c, 0x75, 0xb2, 0x56, 0x2f, 0x2c, 0x3f, 0x02, 0x00, 0xc6, 0x99, 0xff, - 0x88, 0x4e, 0x09, 0xde, 0xde, 0x4f, 0xec, 0xe1, 0xdf, 0x4d, 0x20, 0x62, 0x10, 0x56, 0x83, 0x17, - 0x96, 0x25, 0x37, 0x43, 0xc4, 0x8b, 0x9b, 0xaf, 0xd1, 0x13, 0x84, 0x3c, 0x08, 0x4a, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x76, 0x0f, 0xdb, 0xda, 0x39, 0xd6, 0xf0, 0x7c, 0x1e, 0x07, 0xc1, 0xf8, - 0x1f, 0x83, 0xc3, 0xdc, 0x81, 0x20, 0x60, 0x23, 0x26, 0x5c, 0x10, 0x75, 0xc4, 0x4b, 0x4e, 0xa8, - 0x84, 0x8c, 0x3b, 0x5c, 0xc4, 0xdc, 0x28, 0x39, 0x91, 0x01, 0xe7, 0x03, 0xf8, 0x0f, 0xc3, 0x0b, - 0x27, 0xe7, 0xfa, 0x3f, 0xd2, 0x6a, 0x66, 0x1c, 0xaf, 0xdd, 0xe6, 0x14, 0x51, 0x1d, 0x3e, 0x4d, - 0xf9, 0x6e, 0xb8, 0x18, 0x1f, 0x89, 0x35, 0xa4, 0xc6, 0x79, 0x15, 0x60, 0xeb, 0x82, 0xb7, 0xae, - 0x98, 0x7c, 0x70, 0x5c, 0x5d, 0xab, 0x99, 0x44, 0xd0, 0x4d, 0x7d, 0xb2, 0xb2, 0x18, 0x15, 0x99, - 0x4b, 0x1d, 0x06, 0xad, 0x85, 0x51, 0xd7, 0x4f, 0xe8, 0x3b, 0xbf, 0x3b, 0x20, 0x5d, 0xb5, 0x9e, - 0xec, 0x2b, 0x9d, 0xa1, 0xd8, 0x8b, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xb5, 0x43, 0xbf, - 0xbc, 0x78, 0x3e, 0x0f, 0x83, 0xf0, 0x1f, 0x83, 0xc3, 0x9a, 0x3c, 0xc6, 0x22, 0x02, 0x31, 0x0d, - 0x74, 0xd6, 0x10, 0xb1, 0x8a, 0x37, 0xab, 0x8d, 0xdb, 0xa0, 0xc8, 0x26, 0x8d, 0x8e, 0x44, 0x5f, - 0x60, 0xbc, 0xe0, 0x3f, 0x01, 0xf8, 0x1f, 0x04, 0x27, 0xe7, 0xfa, 0x3f, 0xd2, 0x6a, 0x45, 0xa4, - 0x3f, 0xa9, 0x40, 0x35, 0xdd, 0x67, 0x11, 0x0b, 0xa4, 0x4d, 0x3c, 0xc4, 0xc1, 0x33, 0x8d, 0xe7, - 0xcc, 0x54, 0xe6, 0xf9, 0x68, 0x49, 0xa7, 0x13, 0x19, 0x19, 0xe1, 0x34, 0x9e, 0xc9, 0xcc, 0x42, - 0x08, 0x36, 0xb6, 0x53, 0x01, 0xc2, 0x13, 0x36, 0x48, 0xe5, 0x05, 0x1c, 0xa1, 0x51, 0xa7, 0x17, - 0x43, 0x1e, 0x4e, 0xe4, 0x2c, 0x56, 0xbe, 0x00, 0x00, 0x00, 0x0a, 0x96, 0x82, 0xdd, 0x7b, 0xa1, - 0xdc, 0x9b, 0xc7, 0xae, 0xce, 0xd3, 0x6a, 0x04, 0x8a, 0x5c, 0x0c, 0xf8, 0x70, 0x0f, 0xbf, 0x57, - 0x5a, 0xdc, 0x3a, 0x27, 0xd0, 0x9f, 0x66, 0xda, 0x2c, 0xbd, 0x47, 0x2f, 0xbe, 0x1a, 0x91, 0x47, - 0xe8, 0x8e, 0x27, 0x8b, 0x9a, 0xcb, 0xf2, 0x48, 0x7e, 0x07, 0xc1, 0xf8, 0x1e, 0xf6, 0x0a, 0x87, - 0x27, 0xe7, 0xfa, 0x3f, 0xd2, 0x79, 0xf6, 0x3c, 0x33, 0x99, 0xb9, 0xa2, 0xb8, 0x20, 0xa8, 0xd0, - 0x14, 0xc3, 0xc7, 0xbd, 0x56, 0x64, 0x68, 0x11, 0x39, 0x6c, 0xd6, 0x71, 0x8f, 0xca, 0x73, 0x0f, - 0x39, 0xce, 0xf3, 0x2d, 0xd2, 0xb6, 0xc2, 0x0d, 0x00, 0x0d, 0xd7, 0xda, 0xb7, 0xa8, 0xa7, 0x2f, - 0x64, 0xdd, 0x61, 0x33, 0x6a, 0xe5, 0x01, 0x56, 0xdb, 0x57, 0xc8, 0xd0, 0x99, 0x25, 0xa3, 0xbf, - 0xe8, 0x99, 0xad, 0x1b, 0x14, 0xe5, 0x19, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf1, - 0xff, 0xe3, 0xc0, 0xfc, 0x0f, 0xc0, 0xfc, 0x07, 0xe0, 0x78, 0x0f, 0x66, 0x77, 0xb9, 0xf7, 0xfc, - 0x8e, 0xa8, 0x45, 0xe2, 0xed, 0xcc, 0xa3, 0xbc, 0x63, 0x25, 0xe0, 0x8c, 0xdb, 0xf1, 0x03, 0x99, - 0x03, 0xf6, 0x00, 0x9f, 0xe0, 0x1f, 0xc3, 0x0d, 0x27, 0xe7, 0x96, 0x3f, 0xd2, 0x6a, 0x55, 0xbc, - 0x69, 0xac, 0x33, 0x2a, 0x32, 0xd6, 0x00, 0xf5, 0x23, 0x68, 0xb5, 0x0a, 0x0d, 0x7a, 0xcf, 0x1f, - 0xf7, 0xa3, 0x8e, 0xf6, 0x01, 0x61, 0x3c, 0x7d, 0x41, 0x95, 0x21, 0xce, 0x2f, 0xe9, 0x70, 0xb3, - 0xc3, 0x30, 0x21, 0xc6, 0xe5, 0x8a, 0x27, 0x72, 0x7f, 0x0f, 0xcc, 0x0a, 0x90, 0x9f, 0xbd, 0xcd, - 0x5a, 0x8c, 0xf5, 0x59, 0xcb, 0x29, 0xff, 0xc5, 0x58, 0x00, 0x79, 0x88, 0xdc, 0xf3, 0x8a, 0x19, - 0x7f, 0x5f, 0x1d, 0x73, 0x4b, 0x32, 0xa4, 0xdb, 0x74, 0xe1, 0xac, 0x3e, 0x0f, 0xc0, 0x00, 0xd0, - 0xe2, 0x5e, 0xa2, 0x12, 0x93, 0x5b, 0x2f, 0x83, 0x88, 0x00, 0x52, 0xdd, 0x2a, 0xd0, 0x12, 0x31, - 0x85, 0x4f, 0x62, 0x18, 0x7f, 0xae, 0x3e, 0x90, 0x3c, 0x3e, 0x0f, 0xc1, 0xf1, 0x91, 0x3a, 0x16, - 0x27, 0xe7, 0x96, 0x3b, 0xd2, 0x7a, 0x06, 0x3c, 0xaf, 0xdc, 0xb8, 0x33, 0x53, 0x0e, 0x82, 0xd0, - 0x2d, 0x35, 0x02, 0x56, 0x8b, 0xa3, 0x75, 0x19, 0xce, 0x1d, 0xd0, 0x3f, 0x25, 0x19, 0x13, 0xc6, - 0x96, 0xc5, 0x1d, 0x4a, 0x0f, 0x06, 0xae, 0x07, 0x3e, 0xf1, 0x0d, 0x05, 0x99, 0x16, 0xce, 0x7d, - 0x6e, 0x50, 0xed, 0xdb, 0x6e, 0x7e, 0x7d, 0x90, 0xb4, 0xd0, 0x78, 0x5a, 0x98, 0x33, 0xa1, 0x7f, - 0xfc, 0x43, 0x27, 0x4b, 0x2a, 0xe3, 0x8c, 0xd0, 0x90, 0x1f, 0xae, 0x5f, 0x26, 0x1e, 0x1e, 0x0f, - 0xc0, 0xfc, 0x0f, 0xc1, 0xf0, 0x3f, 0x8e, 0x2a, 0x7b, 0xdc, 0x96, 0x1f, 0x9b, 0x7c, 0x27, 0x8f, - 0x6e, 0x0d, 0x0c, 0xd8, 0xa4, 0xf8, 0xd6, 0x9e, 0x3b, 0xf1, 0x4f, 0x01, 0xc0, 0x86, 0x63, 0xb6, - 0x01, 0xf8, 0x23, 0xee, 0x07, 0xe0, 0x3e, 0x9f, 0x26, 0x4c, 0x20, 0xfb, 0xd2, 0x6a, 0x03, 0xec, - 0x17, 0x53, 0xd0, 0x86, 0xa5, 0xe8, 0x6d, 0x4d, 0xbe, 0x39, 0xb9, 0xa5, 0x84, 0xc6, 0x65, 0x73, - 0x7c, 0x85, 0x03, 0x8b, 0xa7, 0xda, 0x83, 0x20, 0x7d, 0x0b, 0x4d, 0xcf, 0x76, 0xcb, 0x5c, 0x2e, - 0x2c, 0x4a, 0x51, 0xfc, 0xed, 0xf5, 0xb2, 0x0b, 0x0f, 0x0f, 0xe5, 0xe1, 0x2d, 0x10, 0x1a, 0xa3, - 0xcb, 0x72, 0x90, 0xab, 0xda, 0x00, 0xda, 0xcf, 0x45, 0xcc, 0x92, 0xb1, 0x56, 0x88, 0xae, 0x86, - 0x27, 0x58, 0x70, 0x80, 0x20, 0x0f, 0xe0, 0x3e, 0x07, 0xf0, 0x1f, 0x80, 0xfe, 0x07, 0x8f, 0xb0, - 0x83, 0xb1, 0xc0, 0x27, 0x20, 0x70, 0xa1, 0xc8, 0x62, 0x2a, 0xdc, 0xae, 0x70, 0xe8, 0xd5, 0xec, - 0x9e, 0xfb, 0xfe, 0xcd, 0x42, 0x2f, 0x80, 0x0f, 0xb8, 0x0f, 0xf0, 0x0f, 0xb7, 0x00, 0xfa, 0x95, - 0x27, 0xce, 0x0d, 0xbb, 0xd2, 0x6a, 0x43, 0xdc, 0x35, 0x7f, 0x0d, 0x4c, 0x15, 0xef, 0xff, 0x79, - 0x66, 0x85, 0x1c, 0x28, 0xef, 0x72, 0x31, 0xf1, 0x4a, 0x76, 0x45, 0x5a, 0xd5, 0xf2, 0xed, 0xb9, - 0x36, 0xad, 0x63, 0x9c, 0x43, 0x33, 0xc0, 0xf2, 0x26, 0xad, 0x99, 0x18, 0xb7, 0xdf, 0x09, 0x9e, - 0xd2, 0xc1, 0x55, 0x5b, 0x95, 0xa5, 0xba, 0x98, 0xec, 0x96, 0x3b, 0x93, 0x0d, 0x94, 0x6d, 0xc9, - 0x0e, 0xae, 0x65, 0xcc, 0x9b, 0x1a, 0xd8, 0x54, 0x18, 0xe1, 0x80, 0x0a, 0xe0, 0x1c, 0xe4, 0xf3, - 0xe0, 0x7c, 0x1f, 0x83, 0xf0, 0x1f, 0xc0, 0xf8, 0x3c, 0x1f, 0xab, 0xa9, 0xe8, 0xee, 0x30, 0x5d, - 0x8f, 0x19, 0x57, 0xf5, 0xaa, 0x78, 0xe5, 0x69, 0xf4, 0x11, 0x13, 0x73, 0x17, 0x47, 0xfd, 0xc0, - 0x3d, 0xc8, 0x1f, 0xc0, 0xfc, 0x07, 0xe2, 0xa0, 0xc6, 0x3d, 0xab, 0x3b, 0xd2, 0x6a, 0x24, 0x5c, - 0xb7, 0xcc, 0x62, 0xe4, 0x68, 0xfe, 0x89, 0x40, 0x8a, 0x0a, 0xc0, 0x0e, 0xf8, 0x35, 0x2d, 0xc7, - 0x90, 0xc0, 0x07, 0xbf, 0x4e, 0x32, 0xd5, 0x0a, 0xb2, 0x89, 0xe3, 0xa5, 0x6c, 0x0f, 0xe7, 0x49, - 0x27, 0xe3, 0xa8, 0xf5, 0xb5, 0x51, 0x96, 0x00, 0x4b, 0x3a, 0x4a, 0xbd, 0x2f, 0xd8, 0x45, 0x20, - 0x14, 0x82, 0xd8, 0xaf, 0xd5, 0x17, 0x3d, 0xf5, 0x1b, 0xd9, 0x37, 0x8a, 0x56, 0xf6, 0x19, 0x16, - 0xd3, 0x02, 0x37, 0xb5, 0xc0, 0xf1, 0x7e, 0xf3, 0x87, 0xc3, 0xf0, 0xfc, 0x3e, 0x1f, 0x03, 0xa6, - 0xa6, 0xbd, 0x86, 0x87, 0x7f, 0xee, 0xef, 0x69, 0x80, 0x7c, 0xee, 0x8b, 0x3f, 0xf2, 0x04, 0x82, - 0xc1, 0xad, 0xe9, 0x10, 0x56, 0x98, 0xa9, 0x4c, 0xb2, 0xa3, 0x9d, 0xf0, 0x3c, 0xf8, 0x7a, 0x17, - 0x07, 0xcb, 0x15, 0xbb, 0xd2, 0x79, 0xf5, 0x7c, 0xaf, 0xdd, 0x5d, 0x70, 0x6c, 0xfd, 0x44, 0x6a, - 0x11, 0x28, 0x28, 0x00, 0x01, 0x20, 0x77, 0x41, 0xb0, 0x01, 0xde, 0x49, 0x2e, 0x48, 0x76, 0xa1, - 0x4b, 0x17, 0xe0, 0x0e, 0x04, 0x23, 0xca, 0x32, 0x74, 0x27, 0x50, 0x02, 0xcc, 0x4d, 0xc6, 0x49, - 0x5b, 0xbb, 0x7e, 0xa4, 0xbf, 0xa0, 0x6c, 0x12, 0x85, 0xa8, 0x0f, 0x26, 0xfe, 0x97, 0x52, 0x68, - 0xc7, 0xfc, 0x0f, 0x5d, 0x9c, 0xbb, 0x6c, 0x13, 0xf9, 0xd1, 0x86, 0x83, 0x58, 0x79, 0xef, 0x61, - 0x87, 0x8d, 0x06, 0x30, 0xe3, 0xf8, 0x49, 0x11, 0x76, 0x45, 0x21, 0x2a, 0x4f, 0x46, 0x57, 0xf6, - 0x38, 0xce, 0xb4, 0x2b, 0x2f, 0xe7, 0x74, 0x68, 0x49, 0x5e, 0x64, 0x62, 0x5f, 0x1d, 0xe6, 0x3e, - 0x50, 0x78, 0x7c, 0x18, 0x0f, 0xe0, 0x3e, 0x35, 0x07, 0xcb, 0x15, 0xbb, 0xd2, 0x79, 0xe4, 0xf4, - 0x69, 0xd4, 0x53, 0xa1, 0xf3, 0x0e, 0xec, 0xe2, 0xa2, 0x7e, 0xde, 0xe0, 0x5d, 0x49, 0x92, 0x4e, - 0xd9, 0xca, 0x6c, 0x1f, 0x60, 0x07, 0x32, 0x68, 0xab, 0x6d, 0xb7, 0x0d, 0x45, 0xa5, 0x93, 0x71, - 0xd3, 0x2c, 0x11, 0x24, 0xfc, 0xbb, 0x5e, 0x0f, 0xea, 0xdd, 0x33, 0x13, 0xcd, 0x83, 0x46, 0x14, - 0x3d, 0x11, 0xcc, 0x97, 0x03, 0x18, 0x90, 0x2e, 0x52, 0x83, 0xae, 0xff, 0xa8, 0x79, 0x15, 0x2a, - 0x2f, 0xac, 0x3b, 0x0b, 0x4c, 0xea, 0xa0, 0x63, 0x38, 0xf0, 0x7f, 0xfd, 0xa7, 0xfb, 0xa3, 0xca, - 0x5f, 0x79, 0xeb, 0x67, 0x49, 0x51, 0x09, 0x44, 0x02, 0x41, 0x2d, 0xa0, 0xc2, 0x1c, 0x9f, 0x99, - 0x3b, 0xab, 0xdb, 0x09, 0x59, 0xca, 0xb4, 0xd0, 0xc7, 0xc0, 0xfc, 0x1f, 0xb0, 0x88, 0xfe, 0xab, - 0x06, 0x3d, 0xab, 0x3b, 0xd2, 0x79, 0xc4, 0x34, 0xb0, 0xdc, 0x62, 0xbe, 0x61, 0x09, 0x75, 0x38, - 0x4f, 0x05, 0x02, 0xd7, 0xea, 0xbb, 0x0b, 0x1e, 0xb9, 0x2f, 0x21, 0x73, 0x59, 0x34, 0x24, 0x53, - 0x10, 0x1f, 0xa4, 0x1c, 0xc2, 0xf3, 0x7c, 0x46, 0x5a, 0x20, 0x6b, 0x6f, 0x0a, 0x76, 0xc7, 0x10, - 0xeb, 0x21, 0x8c, 0x46, 0x57, 0xf9, 0x2d, 0xd9, 0x54, 0x4c, 0x51, 0x7a, 0xf0, 0xdd, 0x77, 0xae, - 0x94, 0xe3, 0x9e, 0xaa, 0xb4, 0x01, 0xc6, 0x7a, 0x00, 0x00, 0x00, 0x02, 0x37, 0xed, 0x8b, 0x51, - 0x48, 0xc7, 0x0f, 0x0e, 0x0f, 0x07, 0xf9, 0x1a, 0x0a, 0x06, 0xa0, 0x83, 0x00, 0x52, 0x9e, 0xf9, - 0xee, 0xbe, 0xc2, 0x1d, 0xab, 0x26, 0xa6, 0x5c, 0x95, 0x51, 0x0b, 0x55, 0xee, 0x4f, 0x8b, 0x19, - 0x8f, 0x33, 0x01, 0x07, 0xe1, 0x83, 0xc6, 0x39, 0x47, 0xcb, 0x15, 0xbf, 0xd2, 0x79, 0xf5, 0x84, - 0x69, 0xd5, 0x7f, 0x4f, 0xd0, 0xba, 0xd5, 0xf0, 0xca, 0xf9, 0x55, 0x53, 0x2d, 0x5d, 0xdd, 0x68, - 0x17, 0x3c, 0xa0, 0x7f, 0x91, 0xde, 0xfe, 0x79, 0x26, 0x2c, 0x56, 0x0d, 0x6d, 0xbc, 0x41, 0x2c, - 0xb6, 0x6e, 0xdf, 0x46, 0x8f, 0x3a, 0xbd, 0x82, 0x4b, 0xd1, 0x64, 0xb2, 0x65, 0xb6, 0x5c, 0x11, - 0x7a, 0xb1, 0xfc, 0x37, 0xda, 0x1d, 0x15, 0x9c, 0x73, 0x2f, 0x39, 0x0e, 0xc8, 0xf9, 0x00, 0x00, - 0x00, 0x00, 0x32, 0x44, 0x6c, 0x0c, 0xb5, 0x36, 0x6e, 0xe1, 0xf0, 0x1e, 0x9f, 0x1d, 0x73, 0xab, - 0x16, 0x46, 0x7e, 0xfb, 0x8e, 0x41, 0xd1, 0xb6, 0x4e, 0xa6, 0x92, 0xe3, 0x5b, 0x6b, 0xd7, 0x28, - 0xfc, 0x56, 0x60, 0x6d, 0x8b, 0x11, 0x2f, 0x38, 0x37, 0xe7, 0x1f, 0x1e, 0x1f, 0x80, 0xf2, 0x95, - 0x06, 0x3d, 0x3d, 0x3f, 0xd2, 0x79, 0xe5, 0x64, 0x69, 0x36, 0x3a, 0x20, 0x8b, 0xb3, 0x05, 0xc1, - 0x8d, 0xe6, 0x37, 0xe2, 0xef, 0xf6, 0xf5, 0xee, 0x37, 0x32, 0xb7, 0x81, 0xc1, 0x18, 0xe6, 0x32, - 0xf3, 0x50, 0x34, 0x2a, 0x5c, 0xba, 0x54, 0xab, 0x34, 0x15, 0x96, 0xb0, 0x9e, 0xb2, 0x8e, 0xe8, - 0x28, 0xac, 0x26, 0xd9, 0xf5, 0x46, 0xbd, 0x94, 0x28, 0x3f, 0x7a, 0x32, 0x28, 0xe7, 0x60, 0x20, - 0x9c, 0xe7, 0x1b, 0x88, 0xfa, 0x7b, 0x18, 0x45, 0xfc, 0xdd, 0x20, 0xd0, 0xe3, 0x4e, 0xe6, 0x62, - 0xc3, 0x87, 0x07, 0xc1, 0xfb, 0x2e, 0xec, 0xbe, 0xe6, 0xb2, 0x98, 0xa8, 0x8d, 0x00, 0x8e, 0x64, - 0xa3, 0xb4, 0x36, 0xc0, 0x9c, 0x87, 0x14, 0xc4, 0x14, 0x72, 0xd8, 0xa3, 0x34, 0x13, 0x0b, 0x41, - 0x7e, 0x71, 0x81, 0xe1, 0xf8, 0x80, 0xf6, 0x88, 0xe7, 0xcc, 0x07, 0xbf, 0xd2, 0x79, 0xe6, 0x2c, - 0x69, 0xf1, 0xf5, 0x5a, 0x22, 0xc4, 0xa2, 0x02, 0x0f, 0x0f, 0xb1, 0xc4, 0x35, 0xad, 0x7d, 0x21, - 0x7b, 0x26, 0xb6, 0x63, 0xe4, 0xa4, 0xe7, 0xc7, 0x26, 0xcc, 0xf7, 0x6d, 0x7e, 0x33, 0x1a, 0xd2, - 0x9d, 0xd7, 0xb4, 0xca, 0x97, 0x5b, 0x15, 0xc0, 0x99, 0xb4, 0xe8, 0x3e, 0xad, 0xcb, 0x14, 0x87, - 0xc4, 0x96, 0x1e, 0x78, 0xad, 0x9d, 0x40, 0x31, 0x51, 0x02, 0xdb, 0x18, 0x33, 0x50, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x81, 0x64, 0xdb, 0xf1, 0xe1, 0xf0, 0x7c, 0x1f, 0x03, 0xfb, 0x93, 0x0c, - 0x33, 0x50, 0x84, 0x93, 0xc8, 0x54, 0xed, 0x60, 0xe6, 0x1a, 0x78, 0xc4, 0x78, 0x91, 0x96, 0xaa, - 0x6c, 0x7d, 0x77, 0xd8, 0x3e, 0x1d, 0x19, 0x3b, 0xf3, 0x01, 0xc1, 0xf8, 0x7e, 0x07, 0xe2, 0x97, - 0x26, 0x3d, 0x3d, 0x3f, 0xd2, 0x79, 0xd6, 0x14, 0x69, 0xd4, 0x53, 0xa3, 0xe8, 0x70, 0x4a, 0x81, - 0xf6, 0xd3, 0x9c, 0x63, 0xec, 0x68, 0x9c, 0x8e, 0x6f, 0x1f, 0xde, 0xce, 0x4c, 0xcf, 0xa4, 0x67, - 0x8a, 0x6b, 0x6e, 0x1e, 0x80, 0x26, 0x85, 0x95, 0xe8, 0x72, 0x78, 0x6f, 0xca, 0xb7, 0x41, 0xe1, - 0x34, 0x8f, 0xdb, 0x72, 0x39, 0xd0, 0xc8, 0x29, 0xf9, 0x57, 0xd3, 0x74, 0x8c, 0x2d, 0xcb, 0xf0, - 0x33, 0x50, 0x09, 0x12, 0x31, 0xea, 0x1f, 0xc0, 0xe4, 0x6d, 0x7f, 0x00, 0x00, 0x0e, 0x50, 0xd9, - 0x0a, 0x23, 0xe1, 0xc0, 0xf8, 0x3e, 0x07, 0x96, 0x4e, 0x4f, 0x83, 0x5c, 0xef, 0xea, 0xf2, 0xd9, - 0x5c, 0xf9, 0x62, 0x0b, 0x5b, 0xf5, 0xb0, 0xaa, 0xd0, 0x38, 0x17, 0x16, 0x93, 0x6f, 0x0f, 0xc0, - 0xce, 0x72, 0x30, 0xf8, 0xfc, 0x20, 0xfa, 0x8b, 0x27, 0xcc, 0x07, 0xbf, 0xd2, 0x79, 0xf6, 0x14, - 0x69, 0xd4, 0x8e, 0x07, 0x5e, 0x1e, 0xb3, 0x98, 0x6c, 0x51, 0x60, 0xba, 0xd9, 0x89, 0xde, 0xb9, - 0x2a, 0x19, 0xcf, 0x18, 0xd0, 0x53, 0x46, 0x8a, 0x36, 0xe6, 0xf6, 0x48, 0x89, 0xb4, 0x96, 0x8b, - 0x86, 0xe9, 0xb4, 0x36, 0xec, 0x19, 0x7e, 0x88, 0x8f, 0x0d, 0xd3, 0xd6, 0x6a, 0xd0, 0xc8, 0x3e, - 0xf7, 0xe7, 0x03, 0xac, 0xb8, 0xaa, 0x0f, 0xd1, 0x66, 0x30, 0x13, 0x44, 0x12, 0x98, 0xc3, 0x64, - 0x5b, 0x90, 0x08, 0x4d, 0xb5, 0x4d, 0xde, 0x6f, 0x20, 0x2d, 0xf8, 0x7d, 0xb9, 0x57, 0x8f, 0x0f, - 0x83, 0xfc, 0xd4, 0x10, 0xcd, 0xe5, 0x65, 0xd7, 0xb8, 0x54, 0x7c, 0x78, 0xe6, 0xb4, 0xe0, 0xc3, - 0x74, 0x04, 0xf9, 0x0e, 0xdd, 0xf2, 0x69, 0xc1, 0x69, 0xcc, 0x82, 0x67, 0x8c, 0x0f, 0xe2, 0x96, - 0x27, 0xcc, 0x07, 0xbf, 0xd2, 0x79, 0xc6, 0x3c, 0xaa, 0xf5, 0xee, 0xed, 0x94, 0x04, 0x6b, 0x57, - 0x87, 0xef, 0xe1, 0xd8, 0x8b, 0x2f, 0x73, 0x7e, 0xbf, 0xbe, 0x65, 0x4a, 0x47, 0xe4, 0xea, 0x59, - 0x02, 0xde, 0xdd, 0x6e, 0xd0, 0xf6, 0x07, 0x3f, 0x8d, 0x19, 0x4b, 0x8e, 0xa0, 0x35, 0xb7, 0x93, - 0xe2, 0x6a, 0xd8, 0x58, 0xbb, 0x32, 0xa9, 0xcc, 0xe4, 0xa4, 0xbf, 0x73, 0xfe, 0xfd, 0xf8, 0x34, - 0x45, 0x00, 0x00, 0xdd, 0xf7, 0x80, 0x28, 0x98, 0x95, 0x80, 0x28, 0xd1, 0x78, 0x30, 0x55, 0x82, - 0x70, 0xe1, 0xe0, 0x7e, 0x03, 0x1d, 0xfe, 0xd3, 0xf1, 0xe0, 0x7c, 0x17, 0x3f, 0x46, 0x0b, 0x04, - 0xbb, 0xc4, 0x24, 0x0c, 0x0b, 0xa2, 0xb3, 0x08, 0xa4, 0x97, 0xa2, 0x2b, 0x8d, 0xe9, 0xd1, 0xaf, - 0xf8, 0x61, 0xc1, 0xe7, 0xf0, 0x08, 0xfa, 0x9e, 0x27, 0xcc, 0x07, 0xbf, 0xd2, 0x79, 0xd5, 0x44, - 0x69, 0xd4, 0x54, 0x54, 0x30, 0x36, 0x69, 0x18, 0x07, 0xe4, 0xba, 0x8e, 0xd5, 0x08, 0xe6, 0x1b, - 0xf4, 0x6f, 0x93, 0xe0, 0xb0, 0xf5, 0xa7, 0x30, 0x34, 0x47, 0x53, 0x4f, 0xde, 0xbb, 0x83, 0xd9, - 0x24, 0x1e, 0xa3, 0xd5, 0x8a, 0x63, 0xda, 0x21, 0xf5, 0xfe, 0xe2, 0x61, 0x05, 0x10, 0xc2, 0x95, - 0xe7, 0xc4, 0x35, 0xcb, 0xa9, 0xe5, 0xe4, 0xe8, 0xde, 0x10, 0xc7, 0xcd, 0x16, 0x15, 0x03, 0xa3, - 0xa7, 0x00, 0x00, 0x42, 0xcc, 0x9c, 0x39, 0x31, 0xcc, 0x66, 0x8f, 0x0f, 0x0f, 0x83, 0xf0, 0x42, - 0xff, 0xee, 0xd0, 0x26, 0x62, 0x0b, 0x80, 0xd0, 0x86, 0xee, 0x19, 0x19, 0x41, 0xcf, 0x8d, 0xfa, - 0x7e, 0x51, 0xd4, 0x46, 0x81, 0x84, 0x45, 0x84, 0x7b, 0x87, 0x87, 0xc7, 0xf0, 0x00, 0xf2, 0x95, - 0x27, 0xcc, 0x07, 0xbf, 0xd2, 0x79, 0xe6, 0x2c, 0xaf, 0xdd, 0x74, 0x2e, 0x0e, 0x76, 0xa9, 0x35, - 0xf5, 0xa3, 0x37, 0xa7, 0x42, 0xd0, 0x54, 0x22, 0x66, 0xf7, 0xb4, 0x42, 0x4f, 0x70, 0x9f, 0x2c, - 0x9b, 0xf8, 0x69, 0x44, 0x94, 0xae, 0xf8, 0x40, 0xd0, 0x67, 0x52, 0x53, 0xdd, 0x46, 0xf5, 0xc8, - 0xa4, 0x08, 0xfc, 0x4f, 0xcb, 0xc5, 0x31, 0x69, 0xc2, 0x4b, 0x60, 0x1d, 0x6a, 0x4a, 0xba, 0x46, - 0x7b, 0xc8, 0xad, 0x97, 0x83, 0x3b, 0x38, 0x02, 0xdd, 0xf9, 0x49, 0x76, 0xfa, 0xbf, 0xc2, 0xf6, - 0xcf, 0x98, 0xfe, 0x02, 0xcf, 0xc7, 0x43, 0xaa, 0xc8, 0x0f, 0xe3, 0xcc, 0x2d, 0x32, 0x58, 0x75, - 0x93, 0x36, 0x08, 0x3f, 0x70, 0x55, 0xda, 0x2f, 0x68, 0x67, 0x6b, 0x97, 0x3b, 0x69, 0xd4, 0xf1, - 0x3d, 0x2c, 0x03, 0x97, 0xc0, 0x77, 0xe2, 0x0f, 0x27, 0xd4, 0x8f, 0x3f, 0xd2, 0x79, 0xc5, 0x8c, - 0xaf, 0xae, 0x9d, 0x0f, 0x5d, 0x27, 0xcd, 0xc5, 0x34, 0x0d, 0xe2, 0x2b, 0x3e, 0xcf, 0x3b, 0x14, - 0xa2, 0xc5, 0x5f, 0x8b, 0x51, 0x2f, 0x5e, 0x93, 0x79, 0x92, 0xbc, 0x5f, 0x61, 0xb2, 0xfe, 0xa1, - 0x69, 0xc9, 0x22, 0x6c, 0xb3, 0xfc, 0xd2, 0x19, 0xbe, 0x36, 0x6e, 0x50, 0x24, 0xbe, 0xc8, 0x78, - 0xc6, 0xfc, 0x9a, 0xe2, 0xa0, 0x78, 0x53, 0x05, 0xef, 0x1d, 0xe9, 0x97, 0x11, 0x45, 0xa6, 0x3a, - 0xf5, 0x5e, 0x00, 0x02, 0x5a, 0x27, 0x4e, 0x69, 0x44, 0x36, 0x47, 0x0f, 0xc0, 0x7c, 0xb8, 0xad, - 0x43, 0xea, 0xe3, 0x81, 0x07, 0x0a, 0xd3, 0x5b, 0x09, 0x4f, 0x08, 0x3d, 0x95, 0xca, 0x49, 0xed, - 0x56, 0x4e, 0xe9, 0x1a, 0xec, 0xc1, 0x61, 0x1f, 0x08, 0x84, 0xef, 0x8c, 0x71, 0xf0, 0x3e, 0x0c, - 0x27, 0xd4, 0x8f, 0x3f, 0xd2, 0x79, 0xd5, 0x5c, 0xaf, 0x08, 0x0c, 0xb0, 0xd5, 0x02, 0xc9, 0xe1, - 0xde, 0x81, 0xec, 0xbf, 0x8e, 0x50, 0x01, 0x65, 0x64, 0x09, 0xc1, 0xd9, 0x1e, 0x6f, 0x1c, 0x05, - 0x0f, 0xde, 0x11, 0xa3, 0x05, 0xc8, 0xc8, 0xda, 0x48, 0xae, 0x1d, 0x18, 0xfb, 0xd6, 0x3b, 0xe7, - 0x8a, 0x3c, 0xb9, 0xe8, 0x5a, 0x45, 0xa1, 0x58, 0xd0, 0xfe, 0xf7, 0xde, 0x8e, 0x43, 0x1c, 0xd2, - 0xbc, 0x63, 0x48, 0xde, 0xce, 0x7a, 0x52, 0xa2, 0x83, 0x2a, 0x7f, 0x10, 0x52, 0x1c, 0x1f, 0x95, - 0x11, 0x5c, 0x7e, 0x01, 0xfb, 0x0c, 0x2b, 0x1c, 0xc0, 0x77, 0xaf, 0x0f, 0xf5, 0xff, 0x1f, 0xa8, - 0x56, 0x40, 0xcb, 0x7a, 0xfc, 0xa9, 0x5d, 0x05, 0x1c, 0x96, 0x95, 0x49, 0x6b, 0x85, 0xc5, 0x5c, - 0x59, 0x95, 0xfe, 0x18, 0xe0, 0x7b, 0x22, 0x06, 0x27, 0xd4, 0x8f, 0x3f, 0xd2, 0x79, 0xd4, 0x7c, - 0x69, 0xd5, 0x83, 0x56, 0xab, 0xe8, 0xbe, 0xf6, 0x6b, 0x41, 0x7a, 0x2c, 0xf4, 0x58, 0x26, 0xfc, - 0x33, 0x23, 0xd2, 0x32, 0x34, 0x7a, 0x01, 0xaa, 0x66, 0xe1, 0x6c, 0x54, 0x0a, 0xe0, 0xae, 0x92, - 0x63, 0xea, 0x1b, 0x40, 0x05, 0xd6, 0x19, 0xfe, 0xe8, 0x56, 0x4a, 0xd7, 0x4c, 0xee, 0xd4, 0x3f, - 0x99, 0xd5, 0x56, 0x57, 0x34, 0xb1, 0x9b, 0x5a, 0x00, 0x00, 0x00, 0x06, 0x1f, 0x5f, 0x00, 0x10, - 0xc4, 0x91, 0x33, 0xea, 0xbb, 0x2f, 0x2a, 0xee, 0x87, 0xa0, 0x00, 0x06, 0xe1, 0xd8, 0xb4, 0x92, - 0xfd, 0xc1, 0xab, 0x6a, 0x1b, 0x2a, 0x32, 0x9c, 0x9f, 0xf6, 0xf5, 0xb7, 0x4c, 0x73, 0x16, 0xca, - 0x42, 0xc7, 0xd0, 0x0d, 0x7e, 0x5d, 0x41, 0x4a, 0x0f, 0x33, 0xe1, 0xe3, 0xf1, 0x19, 0x36, 0x0e, - 0x3b, 0xc6, 0x06, 0x9e, 0xe2, 0x79, 0xd6, 0x3c, 0x69, 0xd4, 0x53, 0xa1, 0xf3, 0x6d, 0xc1, 0x0c, - 0x7b, 0xab, 0xe2, 0xf3, 0xe0, 0xb6, 0x7c, 0x32, 0xe5, 0xe4, 0x15, 0x1f, 0x09, 0x5d, 0xf6, 0x30, - 0x93, 0x8e, 0xb2, 0x70, 0x09, 0x55, 0x78, 0xb4, 0x7c, 0x12, 0xe8, 0x38, 0x3b, 0x9d, 0x4a, 0x4e, - 0x4c, 0xa1, 0xc7, 0x46, 0xad, 0x6f, 0xb0, 0xbf, 0x9f, 0x98, 0x64, 0xb6, 0x4b, 0x25, 0x6d, 0xd1, - 0xf4, 0xbd, 0xc8, 0x9f, 0xfe, 0x15, 0x1b, 0xe0, 0xe2, 0xb3, 0x57, 0xc2, 0x94, 0xb9, 0x81, 0xfc, - 0x28, 0xd4, 0x74, 0x28, 0x22, 0x92, 0x0b, 0xd8, 0x40, 0x9c, 0x66, 0x95, 0x4c, 0xa1, 0x0b, 0x5f, - 0x0f, 0xfc, 0xf7, 0x83, 0x4a, 0x3b, 0x87, 0x8c, 0xe7, 0xd6, 0x19, 0xe8, 0x57, 0x03, 0x8f, 0x1e, - 0x0f, 0xc1, 0xf0, 0x7f, 0x00, 0x4c, 0xee, 0x88, 0x3b, 0xc6, 0x06, 0x9e, 0xe2, 0x79, 0xc5, 0x44, - 0xaf, 0xdd, 0x90, 0x4e, 0xf2, 0x1c, 0xb4, 0x53, 0xed, 0x62, 0x62, 0x07, 0xe8, 0xff, 0x8b, 0x75, - 0x9a, 0xae, 0xca, 0x1b, 0x89, 0xd0, 0x3c, 0x5f, 0x68, 0x9e, 0xe5, 0x46, 0xdd, 0x74, 0x5a, 0x7d, - 0x73, 0xbc, 0xe4, 0x94, 0xa5, 0x14, 0xd6, 0x53, 0x83, 0x2c, 0x3d, 0x6f, 0x3c, 0xa1, 0x3d, 0x39, - 0x79, 0xe6, 0xa7, 0xb3, 0x24, 0x00, 0x1d, 0x36, 0x16, 0x00, 0x02, 0x64, 0xed, 0x01, 0x6d, 0x15, - 0x57, 0x89, 0xa3, 0x29, 0x10, 0x6d, 0xbe, 0x03, 0x79, 0xdb, 0xcf, 0xad, 0xa1, 0x86, 0x77, 0x75, - 0x19, 0x3c, 0x19, 0x58, 0x6a, 0xf2, 0x3a, 0xd9, 0x3e, 0xbb, 0x24, 0x75, 0xd5, 0x42, 0xf0, 0x54, - 0x26, 0xe6, 0x98, 0x19, 0x1d, 0x36, 0xaf, 0x70, 0xc3, 0x83, 0xc7, 0x80, 0xf6, 0x42, 0x22, 0x05, - 0x7b, 0xc6, 0x06, 0x9e, 0xe2, 0x79, 0xc5, 0xd4, 0x69, 0xd5, 0x83, 0x27, 0xa4, 0x2f, 0xb1, 0xee, - 0xfe, 0xfb, 0x55, 0x90, 0x7c, 0xf9, 0xa6, 0x08, 0x7d, 0x96, 0x78, 0x1f, 0x8d, 0x21, 0xb7, 0xb5, - 0x9b, 0x23, 0x0a, 0x25, 0x6d, 0x7d, 0xc1, 0x06, 0x3d, 0xb8, 0x45, 0x5b, 0x4e, 0x03, 0x91, 0x2d, - 0xef, 0x07, 0x89, 0xd7, 0xb2, 0xe3, 0xd8, 0xe1, 0xf2, 0x31, 0xe7, 0xd8, 0xf1, 0x94, 0x9a, 0x4d, - 0xe5, 0xb4, 0x00, 0x00, 0x00, 0xe5, 0x49, 0xfe, 0x76, 0x9f, 0x61, 0x2e, 0x22, 0xf2, 0x08, 0xd6, - 0xc7, 0xe0, 0x02, 0x62, 0xf1, 0x1c, 0xa0, 0x8b, 0x85, 0x28, 0x14, 0x91, 0xf2, 0x0a, 0xc8, 0xeb, - 0x51, 0x64, 0xc0, 0x1d, 0xaa, 0x64, 0x4d, 0xdd, 0x6d, 0x71, 0xd5, 0x49, 0x87, 0x76, 0x05, 0xcc, - 0x64, 0x96, 0xf0, 0xe1, 0xc7, 0x38, 0x1e, 0x0a, 0x3b, 0xc6, 0x06, 0x9e, 0xe2, 0x79, 0xc6, 0x3c, - 0x37, 0xca, 0x9f, 0xb8, 0x92, 0xad, 0xf0, 0xa9, 0xc0, 0x45, 0x97, 0x26, 0x99, 0xa0, 0x58, 0xa5, - 0xfb, 0x57, 0x8f, 0x72, 0x42, 0x94, 0xed, 0xc2, 0x7b, 0xa6, 0x49, 0xb0, 0x16, 0x71, 0x54, 0xb1, - 0x8c, 0xa8, 0x65, 0xc6, 0x68, 0xbc, 0xcd, 0xc5, 0xf5, 0x0d, 0xe2, 0x12, 0x21, 0xf5, 0xfd, 0xd1, - 0x6b, 0xe9, 0xe2, 0x1f, 0x68, 0x9c, 0xb8, 0xe6, 0x5c, 0x41, 0xd7, 0xb2, 0x4d, 0xba, 0xaf, 0xf4, - 0x61, 0x7e, 0x02, 0xcd, 0x05, 0x32, 0xa0, 0xc3, 0x1f, 0x18, 0x70, 0xe0, 0xf9, 0x1e, 0x09, 0xc1, - 0x9d, 0x3e, 0x4d, 0x35, 0x21, 0x84, 0x3d, 0x75, 0xe1, 0xac, 0x52, 0x20, 0xaa, 0xa9, 0x85, 0xe8, - 0x93, 0x8a, 0x0d, 0xe1, 0x6a, 0x63, 0x9c, 0xa1, 0x5b, 0xa1, 0xc7, 0x07, 0x38, 0x3f, 0x83, 0x01, - 0x1d, 0xe3, 0x03, 0x4f, 0x71, 0x3a, 0x05, 0xe9, 0x69, 0xd4, 0x53, 0x77, 0xbb, 0xff, 0x67, 0x70, - 0x39, 0x68, 0x91, 0x89, 0x3c, 0xd1, 0x1f, 0x23, 0x75, 0x50, 0xae, 0x4b, 0x77, 0xa2, 0xe3, 0x76, - 0x5c, 0xf4, 0x72, 0x1d, 0xa8, 0x0f, 0x55, 0x7a, 0x73, 0x45, 0xbe, 0xd4, 0xe0, 0xe8, 0x99, 0x95, - 0x9a, 0xc9, 0x98, 0xb8, 0x34, 0x03, 0xd1, 0xee, 0x2a, 0x96, 0xde, 0x05, 0xd5, 0xe3, 0x3a, 0x64, - 0xa7, 0x23, 0xdd, 0xe4, 0x00, 0x00, 0x00, 0x0b, 0xd8, 0x35, 0xfd, 0x8c, 0x47, 0x0d, 0xe9, 0xba, - 0xd0, 0xfd, 0xf0, 0x38, 0xf3, 0xe0, 0xf8, 0x33, 0xfa, 0x08, 0x77, 0x0a, 0xc3, 0xca, 0x7b, 0x9f, - 0x25, 0xa7, 0x0c, 0x84, 0xbd, 0x28, 0xa1, 0x72, 0x6c, 0x95, 0x59, 0xb7, 0x35, 0x31, 0xda, 0x8b, - 0xe3, 0xe2, 0x80, 0xdb, 0x8d, 0xf0, 0x3b, 0x06, 0x1d, 0xe3, 0x03, 0x4f, 0x71, 0x3a, 0x35, 0xf1, - 0x69, 0xd4, 0x53, 0x7a, 0xa6, 0x57, 0xdf, 0xe0, 0xec, 0xd6, 0x52, 0x4c, 0x37, 0x16, 0xbc, 0x17, - 0xd6, 0x92, 0x5e, 0xf8, 0x71, 0xa2, 0xb3, 0x49, 0xf2, 0x3b, 0x94, 0xb1, 0x4d, 0xe9, 0x39, 0x1e, - 0xb7, 0x3c, 0x2d, 0xdd, 0x5f, 0xfe, 0x9c, 0x89, 0x26, 0x7b, 0xfd, 0x7c, 0x1f, 0xcc, 0xbd, 0x6f, - 0x35, 0x7f, 0x6f, 0x2d, 0x5b, 0xe3, 0x53, 0x1c, 0x7c, 0x04, 0x77, 0x08, 0x30, 0xc1, 0xa1, 0xa2, - 0xed, 0x99, 0x8a, 0x91, 0x26, 0x61, 0xb2, 0x72, 0x99, 0x92, 0xce, 0x1e, 0x0e, 0x1e, 0x0c, 0x3f, - 0xea, 0x80, 0xde, 0x29, 0xef, 0x60, 0xd3, 0xf3, 0xac, 0xa5, 0x09, 0x18, 0x42, 0x0b, 0x6e, 0x63, - 0xe1, 0x31, 0xdb, 0x8d, 0x6b, 0xe7, 0x84, 0xac, 0xc7, 0x18, 0x19, 0x98, 0x6f, 0x80, 0x78, 0xc2, - 0x1d, 0xe3, 0x03, 0x4f, 0x71, 0x3a, 0x26, 0x39, 0x05, 0xc2, 0xd1, 0x02, 0xeb, 0x04, 0x30, 0x1f, - 0xcf, 0x8f, 0x99, 0x5a, 0x19, 0xa7, 0x82, 0xcb, 0x70, 0xf0, 0xf2, 0xa9, 0xc3, 0xfe, 0x36, 0x90, - 0xd7, 0x19, 0xda, 0xce, 0x16, 0xf6, 0xcc, 0x85, 0xe9, 0x73, 0x15, 0x2a, 0xeb, 0x53, 0xdf, 0x4b, - 0xec, 0x7f, 0x01, 0x5b, 0x50, 0x75, 0xcc, 0x9d, 0x62, 0xfd, 0x8b, 0x11, 0x7e, 0x07, 0xfb, 0x79, - 0x22, 0xdb, 0xdc, 0x15, 0x2c, 0xc9, 0xc9, 0x54, 0xd3, 0x39, 0x61, 0xf6, 0xe1, 0x6c, 0x48, 0x06, - 0x70, 0xf8, 0xe7, 0x73, 0xc1, 0xf8, 0x3b, 0x72, 0x45, 0x80, 0x23, 0x87, 0x34, 0x28, 0xed, 0x10, - 0x70, 0x70, 0x48, 0xec, 0x62, 0x03, 0xe2, 0x5b, 0x33, 0x9a, 0xea, 0x72, 0xa1, 0x20, 0x5f, 0x60, - 0x7e, 0x0f, 0xc0, 0xf8, 0x3f, 0x03, 0xf0, 0x03, 0x3c, 0xa4, 0x87, 0x67, 0x71, 0x2a, 0x25, 0x21, - 0x00, 0x01, 0x61, 0xb5, 0x61, 0x7c, 0x6c, 0x47, 0xba, 0x3d, 0xba, 0x3b, 0x5c, 0x42, 0xd7, 0x8e, - 0x8c, 0xe2, 0xb3, 0x20, 0x0d, 0x14, 0x0b, 0x6b, 0x95, 0x91, 0x80, 0x4d, 0x74, 0x86, 0x41, 0x97, - 0x14, 0xb9, 0x72, 0xeb, 0x77, 0xd4, 0x8e, 0x6e, 0xe5, 0xba, 0x3b, 0xe6, 0x83, 0x28, 0xa4, 0xd0, - 0x57, 0x9f, 0xc9, 0x04, 0x3a, 0x71, 0xf3, 0xa4, 0x1b, 0xf5, 0x32, 0xfd, 0x20, 0x36, 0x0d, 0x48, - 0xd3, 0x76, 0x46, 0x67, 0x17, 0xed, 0x1c, 0x1c, 0x38, 0x3c, 0x1e, 0x0f, 0x87, 0x87, 0x87, 0x83, - 0xe1, 0xe5, 0xce, 0x1e, 0x07, 0xae, 0x46, 0xc6, 0x79, 0x46, 0x26, 0xaa, 0x9e, 0x61, 0x4a, 0xef, - 0x81, 0xa6, 0x18, 0xc3, 0xa3, 0x6b, 0xb8, 0x09, 0xf0, 0x3f, 0x01, 0xfc, 0x0f, 0x87, 0xc2, 0x03, - 0x1c, 0xa4, 0x87, 0x67, 0x71, 0x2a, 0x55, 0x79, 0x05, 0xc2, 0x3c, 0xe5, 0x45, 0x6c, 0xe7, 0x10, - 0x4e, 0xd9, 0xe5, 0x84, 0x46, 0x9c, 0x3f, 0x9c, 0x5b, 0x14, 0xe8, 0x9d, 0xd7, 0xf5, 0x7f, 0xd1, - 0x0d, 0x54, 0x3f, 0xca, 0x46, 0x33, 0xf2, 0xc0, 0x0c, 0xfc, 0x2c, 0x7b, 0xd0, 0xb0, 0xf0, 0xa6, - 0xad, 0x21, 0x47, 0x74, 0x16, 0xb2, 0xa6, 0x37, 0x18, 0xfc, 0x2b, 0x65, 0x57, 0x2e, 0xec, 0x69, - 0x08, 0x72, 0x41, 0x29, 0xcf, 0x2c, 0xf1, 0x5d, 0x9d, 0x78, 0x02, 0xe2, 0x7d, 0x86, 0x83, 0x19, - 0x0e, 0xc3, 0x8c, 0x87, 0x83, 0xc3, 0xdd, 0x0d, 0x0c, 0x40, 0xb6, 0x0f, 0xdc, 0x82, 0x5c, 0x09, - 0x6a, 0x42, 0x75, 0x02, 0x0e, 0x47, 0x6b, 0x00, 0xe6, 0x26, 0x13, 0xa8, 0xe2, 0xfa, 0x1a, 0x0f, - 0x0f, 0xc0, 0xf8, 0x3f, 0x07, 0x83, 0xf0, 0x84, 0x1c, 0xa4, 0x87, 0x67, 0x71, 0x2a, 0x45, 0x01, - 0x19, 0xad, 0x36, 0xf5, 0xc8, 0x09, 0xde, 0x74, 0x71, 0x9e, 0xf3, 0x33, 0x31, 0x6a, 0x35, 0xad, - 0x7c, 0xdd, 0xea, 0xa3, 0x79, 0x54, 0x4f, 0xdb, 0x1b, 0x15, 0x41, 0xb0, 0xf9, 0xf6, 0x07, 0xfd, - 0xe7, 0xcb, 0xe2, 0x24, 0x4f, 0xf1, 0x53, 0x0f, 0x0a, 0xd8, 0xc1, 0xdf, 0xdc, 0x0f, 0x47, 0x2a, - 0x18, 0x0d, 0x2b, 0x0b, 0x78, 0x34, 0x82, 0x11, 0xd7, 0x4d, 0x35, 0x03, 0xeb, 0xce, 0x70, 0x1a, - 0xf5, 0xfd, 0x70, 0x71, 0xf5, 0x2e, 0x3c, 0x3c, 0x3f, 0x03, 0xc3, 0xc3, 0xe1, 0xf0, 0xf8, 0x1d, - 0x6c, 0x9d, 0x2b, 0x22, 0x3c, 0x18, 0x0d, 0x2a, 0x8c, 0xe8, 0x06, 0x16, 0xd6, 0x9c, 0x15, 0x40, - 0x16, 0x06, 0xad, 0xea, 0x9d, 0x0b, 0x8a, 0x83, 0xf3, 0x83, 0xf0, 0x7e, 0x30, 0x7c, 0x0e, 0xc3, - 0xfc, 0xa0, 0x37, 0x47, 0x71, 0x3a, 0x15, 0x01, 0x05, 0xc2, 0x3f, 0x59, 0xce, 0x7c, 0x6c, 0x44, - 0xf7, 0x52, 0xb7, 0x2b, 0x89, 0x80, 0x09, 0x61, 0xd7, 0x77, 0x57, 0x63, 0x87, 0x7b, 0x88, 0xc8, - 0xa5, 0x72, 0xed, 0x94, 0x0c, 0x84, 0x47, 0xdc, 0xc7, 0x89, 0x7d, 0xef, 0x8d, 0x2a, 0xf4, 0x06, - 0xbd, 0x21, 0x6e, 0x3c, 0x50, 0x9b, 0xcc, 0x01, 0x93, 0xa0, 0xac, 0x4a, 0x38, 0xb6, 0x58, 0xdd, - 0x62, 0x84, 0x87, 0x22, 0x90, 0xb1, 0xa6, 0xa9, 0x91, 0xaf, 0xd8, 0x90, 0xcc, 0x0b, 0xb1, 0x20, - 0xf0, 0xe1, 0x86, 0x66, 0x1c, 0x3c, 0x78, 0xe1, 0x1e, 0x76, 0xd8, 0xf5, 0xe4, 0x57, 0xbd, 0xee, - 0xe6, 0x9f, 0x95, 0x13, 0x10, 0x35, 0xcb, 0x1e, 0x84, 0x14, 0x69, 0x8c, 0x06, 0xa6, 0x7c, 0x3e, - 0x0f, 0xc0, 0xfc, 0x0f, 0xc0, 0xfc, 0x0e, 0x05, 0x1c, 0xa0, 0x37, 0x47, 0x71, 0x2a, 0x64, 0xc9, - 0x05, 0xc2, 0x2d, 0xbf, 0x94, 0x18, 0x2b, 0x9e, 0x1e, 0xff, 0x82, 0x28, 0x5f, 0x6c, 0x46, 0x76, - 0x50, 0x29, 0x5e, 0x59, 0x73, 0xfd, 0x6b, 0x8e, 0x64, 0x33, 0xf6, 0xf6, 0x84, 0x2e, 0x95, 0xba, - 0xb2, 0x8d, 0x72, 0xbb, 0x17, 0x71, 0x91, 0x96, 0xae, 0xab, 0x89, 0xa5, 0xa4, 0xad, 0xaa, 0x48, - 0xe9, 0xdc, 0x69, 0xba, 0x16, 0x99, 0xde, 0x56, 0x69, 0x30, 0xfe, 0xe6, 0xab, 0x1c, 0xe4, 0x50, - 0x71, 0x75, 0x5d, 0xd3, 0x09, 0xa2, 0x13, 0xdc, 0x67, 0x3c, 0x3e, 0x3c, 0x3c, 0x3c, 0x1e, 0x1e, - 0x1d, 0xe7, 0x09, 0x3a, 0x24, 0x66, 0xe1, 0xbe, 0x1b, 0x4f, 0x2a, 0xd3, 0x0b, 0xed, 0xd4, 0xbf, - 0x54, 0xf5, 0x4e, 0x5b, 0x71, 0x7a, 0xe8, 0x0f, 0x07, 0xe0, 0x3e, 0x0f, 0x81, 0xe1, 0xf0, 0x06, - 0x1c, 0xa0, 0x37, 0x47, 0x71, 0x2a, 0x24, 0xd9, 0x19, 0xa1, 0x2c, 0x66, 0x90, 0xb6, 0x0a, 0x0d, - 0x39, 0xb6, 0x11, 0x69, 0x65, 0x6e, 0x92, 0x1c, 0x0d, 0xaf, 0x1a, 0x82, 0x29, 0x7f, 0xbb, 0x9c, - 0x8b, 0x12, 0x8b, 0x66, 0x8d, 0xd7, 0x61, 0xad, 0xa1, 0x5c, 0x47, 0x2d, 0x62, 0x01, 0x0f, 0xe3, - 0xb6, 0xdd, 0x68, 0xee, 0x2b, 0x8c, 0xed, 0xf9, 0xea, 0x43, 0x61, 0x65, 0x57, 0xa3, 0xfd, 0xd9, - 0xcb, 0x10, 0xf9, 0x3a, 0xcc, 0x87, 0x09, 0x8f, 0x10, 0xfe, 0xb1, 0x7f, 0x4f, 0xa2, 0xc7, 0xfc, - 0x1c, 0x38, 0x7e, 0x07, 0xe0, 0x7e, 0x07, 0xe0, 0x3f, 0x81, 0x7e, 0x3f, 0xd1, 0xee, 0xb8, 0xad, - 0xf8, 0x0f, 0x28, 0x0f, 0x58, 0x84, 0x12, 0xac, 0x21, 0x96, 0x78, 0x7a, 0xbb, 0x76, 0x06, 0x26, - 0x38, 0x63, 0x3b, 0xc0, 0xe4, 0x1c, 0x0e, 0xc5, 0xfc, 0xa0, 0x0e, 0x47, 0x71, 0x3a, 0x46, 0x29, - 0x00, 0x00, 0x0f, 0x6f, 0xb2, 0x94, 0x5d, 0x10, 0x2f, 0xca, 0x99, 0xc5, 0xc6, 0x84, 0xa9, 0xd4, - 0xe0, 0x81, 0x3e, 0xbf, 0x51, 0x7a, 0x44, 0xdb, 0xc4, 0xf9, 0x33, 0xa3, 0x59, 0xae, 0x80, 0x5b, - 0x47, 0xee, 0x2d, 0xe4, 0xf8, 0xec, 0xcf, 0x46, 0xc5, 0x9f, 0xb2, 0xa4, 0xb2, 0x11, 0xee, 0xaf, - 0x77, 0xbe, 0x76, 0xf4, 0xac, 0xd8, 0x28, 0xe9, 0xf3, 0x5b, 0x93, 0x59, 0x1f, 0xb5, 0x29, 0xf6, - 0xb7, 0xe5, 0xc5, 0x6f, 0xa2, 0x51, 0xe1, 0xf8, 0x7e, 0x0f, 0xc0, 0x7e, 0x07, 0xe0, 0x7c, 0x38, - 0x1d, 0xeb, 0xc8, 0xea, 0xc6, 0x3e, 0x6b, 0xa1, 0xac, 0xfa, 0xdf, 0xa8, 0xf8, 0xc2, 0x6f, 0x1d, - 0x39, 0xa2, 0x89, 0x2a, 0xb0, 0x6b, 0x2e, 0x3d, 0x40, 0x7c, 0x0f, 0xe0, 0x7c, 0x1f, 0x98, 0x07, - 0x1a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x04, 0x79, 0x04, 0x80, 0xfc, 0x37, 0x46, 0x6c, 0xbf, 0xeb, - 0x78, 0xa1, 0xbc, 0x1e, 0x54, 0x0c, 0x33, 0x62, 0x9f, 0x55, 0x6e, 0x5b, 0x00, 0xb2, 0x38, 0x41, - 0x97, 0x66, 0xc6, 0x45, 0x8b, 0xa7, 0x2c, 0xb9, 0xe7, 0x90, 0x7f, 0x40, 0x99, 0x1a, 0x55, 0x84, - 0xc9, 0x0b, 0x80, 0xe8, 0xea, 0xe0, 0x5d, 0x84, 0xc0, 0x56, 0x70, 0xb8, 0x1b, 0x23, 0x82, 0xe7, - 0xff, 0x70, 0xe6, 0x3c, 0xef, 0xb8, 0x9c, 0x87, 0x7b, 0x35, 0xc9, 0x38, 0xd0, 0xec, 0xeb, 0x0f, - 0x0f, 0xc1, 0xf0, 0x3f, 0x03, 0xf0, 0x78, 0xf8, 0xe2, 0xe2, 0x14, 0x96, 0xc0, 0x57, 0x68, 0x89, - 0x74, 0xb7, 0xc1, 0xb2, 0xd6, 0xa9, 0x7e, 0x26, 0xde, 0x28, 0xf0, 0x13, 0xce, 0x07, 0x0f, 0xc3, - 0xe0, 0x7e, 0x07, 0xe0, 0x7e, 0x07, 0xc2, 0x08, 0x1a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x05, 0x21, - 0x00, 0x00, 0x60, 0xee, 0x8d, 0x54, 0xb8, 0xbc, 0x11, 0xe4, 0x59, 0xa0, 0xac, 0xee, 0x13, 0x3d, - 0x28, 0xb3, 0xa0, 0x3b, 0x69, 0x42, 0xe1, 0xb9, 0xe0, 0x71, 0xdf, 0x4f, 0x17, 0xfc, 0x0c, 0xd5, - 0x79, 0x28, 0x28, 0xfe, 0x04, 0xf9, 0x79, 0xa7, 0x6f, 0xea, 0x6f, 0xdd, 0x6a, 0x46, 0x72, 0xc4, - 0x13, 0x8c, 0x1e, 0x91, 0x34, 0x09, 0xc3, 0xb1, 0x61, 0x48, 0xbc, 0xe6, 0x1c, 0x69, 0x51, 0xff, - 0xd2, 0xb7, 0xf5, 0xc4, 0x0c, 0x21, 0x98, 0x7c, 0x0f, 0x83, 0xc0, 0xfc, 0x0f, 0x87, 0xc7, 0xe8, - 0xec, 0x7e, 0x23, 0xa1, 0x7d, 0x07, 0x0c, 0x40, 0xbf, 0x0c, 0x50, 0xf4, 0x95, 0xce, 0xe2, 0x97, - 0x1a, 0x49, 0x1b, 0x38, 0x14, 0xc0, 0x4b, 0x37, 0xe0, 0xfc, 0x0f, 0x81, 0xf0, 0x78, 0xf0, 0x09, - 0x1a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x14, 0xf9, 0x00, 0x00, 0x62, 0x61, 0xf7, 0x2f, 0x30, 0xbc, - 0x28, 0xbc, 0x28, 0x65, 0x7a, 0x47, 0xd7, 0x8f, 0x22, 0xf4, 0xb5, 0x5f, 0x97, 0xcf, 0x28, 0x51, - 0x42, 0x1f, 0x9b, 0x83, 0x7e, 0x50, 0xbb, 0xf0, 0x6d, 0x6a, 0x62, 0x59, 0x3d, 0x99, 0x05, 0x14, - 0xeb, 0x3a, 0xb1, 0x88, 0xf8, 0xdb, 0x8b, 0x3e, 0xb1, 0x24, 0x58, 0xd6, 0x1f, 0xd0, 0x56, 0xa1, - 0x8c, 0x7a, 0x37, 0xd4, 0x03, 0xd8, 0x0e, 0x9d, 0x8b, 0xe2, 0xf1, 0x53, 0x90, 0x31, 0x87, 0x87, - 0xc1, 0xf0, 0x7c, 0x07, 0xe0, 0x7e, 0x07, 0x86, 0x06, 0xfb, 0x6d, 0xf6, 0x0b, 0x19, 0x9c, 0x5a, - 0x65, 0xfb, 0x3c, 0xf5, 0xd8, 0x15, 0xa1, 0xc3, 0xbd, 0x01, 0x8d, 0x64, 0xd1, 0x51, 0xaf, 0xc3, - 0xf0, 0x3f, 0x81, 0xf8, 0x1f, 0x87, 0xe0, 0x0a, 0x1a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x44, 0x59, - 0x05, 0xc0, 0x9d, 0xa7, 0x4c, 0x88, 0x55, 0x01, 0xc8, 0x85, 0xaa, 0xbb, 0x7c, 0xb5, 0x2c, 0x5d, - 0xce, 0x53, 0x94, 0x4f, 0x0d, 0xa6, 0x09, 0x22, 0x42, 0x9e, 0xef, 0xff, 0xfb, 0xcb, 0x4f, 0xa2, - 0xe8, 0xc7, 0xc9, 0x5c, 0xa1, 0x27, 0x9f, 0xfc, 0x47, 0xcb, 0x4d, 0x52, 0xfe, 0x6d, 0x37, 0xc9, - 0x55, 0x15, 0xba, 0xb4, 0xf4, 0xf0, 0xc8, 0xef, 0x07, 0x52, 0xc6, 0xe9, 0x3f, 0xcc, 0xf4, 0xff, - 0x99, 0x32, 0x60, 0x89, 0x07, 0x4d, 0xe3, 0x1e, 0x07, 0x81, 0xf8, 0x1f, 0x07, 0x8f, 0xc1, 0x19, - 0x10, 0x21, 0x44, 0x9a, 0x82, 0x82, 0xb8, 0x65, 0x94, 0xc8, 0x13, 0x9d, 0x8e, 0xdd, 0x32, 0xc4, - 0xd2, 0x4c, 0xa9, 0xc2, 0xa0, 0x43, 0xe1, 0xf8, 0x0f, 0xc0, 0xfc, 0x0f, 0xc0, 0x7e, 0x06, 0x0b, - 0x1a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x24, 0x71, 0x05, 0xc0, 0x29, 0x32, 0x84, 0x40, 0x4b, 0xb4, - 0xb8, 0xf8, 0xd6, 0xa6, 0xec, 0x18, 0xb0, 0xaa, 0x08, 0xbf, 0x29, 0x3f, 0x51, 0xbe, 0xe3, 0x8c, - 0x18, 0xb9, 0x76, 0xe0, 0xe8, 0x18, 0x4d, 0x1f, 0x99, 0x41, 0x25, 0x1c, 0x65, 0x5c, 0x2c, 0x0e, - 0x44, 0x04, 0x9f, 0x4d, 0x70, 0x89, 0x16, 0xf1, 0xe6, 0xc9, 0xc4, 0x51, 0x0a, 0x40, 0x90, 0x0a, - 0xa8, 0x00, 0x5f, 0x3a, 0xca, 0x1f, 0x42, 0xdc, 0x31, 0xd5, 0x47, 0x16, 0x1f, 0x8d, 0xcf, 0x0f, - 0x07, 0x81, 0xf0, 0x3e, 0x07, 0xe0, 0x78, 0x78, 0x89, 0x16, 0xf6, 0xbb, 0x98, 0x92, 0x3d, 0x56, - 0xa6, 0xb5, 0xff, 0x76, 0x03, 0x89, 0x04, 0xcf, 0x1e, 0xfc, 0x72, 0x3b, 0x80, 0x54, 0xf8, 0x7c, - 0x07, 0xf0, 0x3f, 0x03, 0xf0, 0x3f, 0x06, 0x0c, 0x0a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x34, 0xd9, - 0x00, 0x00, 0x17, 0xa1, 0xff, 0x37, 0x32, 0x54, 0xf2, 0x35, 0xaa, 0xbc, 0x3d, 0x44, 0x8c, 0x73, - 0xeb, 0xa4, 0x59, 0x99, 0xa1, 0xcf, 0x35, 0x8b, 0x40, 0xc4, 0xb5, 0x6c, 0xa2, 0x1f, 0x25, 0x4e, - 0x8f, 0x2f, 0xca, 0x57, 0x8c, 0x06, 0xae, 0xce, 0xcc, 0x52, 0x45, 0x6b, 0x6b, 0xe6, 0x72, 0x66, - 0x4d, 0x58, 0x5d, 0x70, 0xb4, 0x7c, 0xbf, 0xeb, 0x84, 0x5e, 0x17, 0x42, 0x4a, 0x37, 0x1a, 0x27, - 0x66, 0x74, 0x80, 0xf2, 0x2f, 0x53, 0xb7, 0x06, 0x79, 0xc3, 0xc1, 0xf0, 0x3e, 0x0f, 0xc0, 0xf8, - 0x3f, 0x0e, 0x1e, 0xfb, 0xa4, 0x49, 0xea, 0x48, 0x10, 0x32, 0x23, 0x18, 0xd7, 0xa7, 0x29, 0xb3, - 0x7c, 0xf1, 0xc4, 0xab, 0x9c, 0xdb, 0xcf, 0x9c, 0x1e, 0x0f, 0xc0, 0xfc, 0x0f, 0x83, 0x82, 0x0e, - 0x0a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x34, 0xd9, 0x05, 0xc0, 0x28, 0xf5, 0x8d, 0xd8, 0x07, 0x04, - 0xd3, 0x2e, 0x17, 0x79, 0x42, 0x9b, 0x5b, 0x69, 0x9b, 0xb8, 0xee, 0xe0, 0x97, 0xdb, 0x2a, 0x6b, - 0x94, 0xbe, 0xca, 0x5d, 0x74, 0x7a, 0x45, 0x21, 0xc5, 0x46, 0x9c, 0x7a, 0x6f, 0x80, 0xf6, 0x6c, - 0x26, 0xcb, 0xa9, 0xee, 0x25, 0xd1, 0xd5, 0x23, 0xb5, 0x01, 0x13, 0xae, 0x47, 0xb3, 0xb7, 0x76, - 0x88, 0x52, 0x40, 0x18, 0xa4, 0xf9, 0xa1, 0x11, 0xc1, 0x39, 0xed, 0x9f, 0xf6, 0x33, 0xc7, 0x87, - 0x80, 0xfc, 0x1f, 0x81, 0xf8, 0x1f, 0x0f, 0x0f, 0xf7, 0xbf, 0x33, 0xec, 0xe9, 0x9f, 0x66, 0x64, - 0xd1, 0xe7, 0xe5, 0xd3, 0x27, 0x20, 0x57, 0xe2, 0x08, 0x36, 0x1d, 0xaa, 0x4d, 0x4e, 0x60, 0xf0, - 0x7e, 0x07, 0xe0, 0x7e, 0x07, 0xc0, 0xf8, 0x0f, 0x0a, 0x68, 0xc9, 0xf7, 0x71, 0x2a, 0x34, 0x99, - 0x05, 0xc2, 0x3c, 0xe5, 0x45, 0xc1, 0x14, 0xf5, 0x9f, 0x92, 0x87, 0x2b, 0x4f, 0x8f, 0x46, 0xf7, - 0x90, 0x7f, 0x33, 0x60, 0xf1, 0xa6, 0xbc, 0xd0, 0x0e, 0xbb, 0x47, 0xdb, 0xbe, 0xb2, 0xe5, 0x2a, - 0x2c, 0x90, 0xc3, 0x1f, 0x2c, 0xa6, 0xbd, 0x4f, 0x10, 0x7a, 0x4f, 0x0e, 0xe6, 0xdc, 0xfa, 0xef, - 0x51, 0x99, 0xeb, 0x94, 0x13, 0x73, 0xaa, 0xdc, 0x4c, 0xc9, 0xa7, 0x35, 0x7d, 0xd7, 0x00, 0x00, - 0x02, 0x65, 0xd2, 0x97, 0xea, 0x16, 0x68, 0x32, 0x97, 0x29, 0xe1, 0xf1, 0xf0, 0x7c, 0x3c, 0x1e, - 0x28, 0xf8, 0x3f, 0x2a, 0x64, 0xb1, 0x82, 0xe4, 0x95, 0xab, 0xb6, 0xb8, 0xcb, 0x1c, 0xba, 0x03, - 0x6e, 0x9d, 0xf4, 0x0b, 0x15, 0xa8, 0x63, 0xf0, 0x3f, 0x80, 0xfc, 0x0f, 0xc0, 0xfc, 0x0e, 0x11, - 0x0a, 0x28, 0x8c, 0x57, 0x71, 0x2a, 0x66, 0x29, 0x00, 0x00, 0x20, 0x84, 0xdc, 0x03, 0x04, 0xeb, - 0x4f, 0xb6, 0x88, 0x4a, 0xe0, 0x3f, 0x33, 0x8e, 0xdc, 0x7d, 0x6f, 0xee, 0xf6, 0x84, 0xeb, 0xbf, - 0x91, 0x69, 0x4b, 0xce, 0x33, 0xfb, 0x0a, 0x66, 0x8e, 0x79, 0xd6, 0x11, 0x63, 0x25, 0x95, 0xcd, - 0x58, 0x73, 0x02, 0xa7, 0xb6, 0x01, 0x06, 0xc4, 0xd3, 0xfa, 0xbf, 0x4c, 0xc1, 0xc3, 0xb6, 0xd3, - 0xc4, 0x33, 0x99, 0x3f, 0xb1, 0x72, 0xe8, 0xd1, 0xed, 0xd5, 0xad, 0x20, 0x95, 0x84, 0x9c, 0x39, - 0xf0, 0x7e, 0x07, 0xe0, 0x7f, 0x07, 0xe0, 0xf0, 0x7e, 0x9b, 0xb9, 0x9d, 0x29, 0xca, 0x3b, 0x35, - 0xd9, 0xc6, 0x3a, 0xf0, 0x09, 0x69, 0xcd, 0xbd, 0xd6, 0xda, 0xf0, 0x91, 0x3d, 0xcd, 0xb3, 0x73, - 0x81, 0xe0, 0x7e, 0x07, 0xe0, 0x7c, 0x4c, 0x12, 0x0a, 0x68, 0xcf, 0xf7, 0x71, 0x2a, 0x04, 0xf1, - 0x07, 0x82, 0x14, 0xfc, 0x2b, 0x0d, 0x9f, 0xbe, 0xb2, 0xbe, 0x70, 0x4e, 0x05, 0x14, 0x2f, 0x36, - 0xc4, 0x7a, 0x3e, 0xe7, 0xd9, 0xf8, 0x64, 0xde, 0xce, 0x4a, 0x9c, 0x6a, 0xbd, 0xd1, 0x46, 0x78, - 0x18, 0x7a, 0xd8, 0x4c, 0x5f, 0x4d, 0x16, 0xfe, 0xca, 0xee, 0x57, 0x0d, 0x32, 0x27, 0xe9, 0x70, - 0x3b, 0x6a, 0xb4, 0xce, 0xc5, 0x67, 0x35, 0x00, 0xbf, 0x31, 0x34, 0xb6, 0xf1, 0xff, 0x92, 0x83, - 0x10, 0x69, 0x98, 0x04, 0xed, 0x5c, 0x3e, 0x1f, 0x83, 0xf0, 0x7e, 0x07, 0xc1, 0xe1, 0xf7, 0x01, - 0x89, 0x86, 0x9a, 0xec, 0x1a, 0xcc, 0x2a, 0xa6, 0xdf, 0x0a, 0x77, 0x4d, 0x19, 0x7b, 0xdf, 0xd0, - 0xdd, 0xf3, 0xbd, 0x78, 0x71, 0x87, 0x07, 0xe0, 0x3f, 0x03, 0xf0, 0x1f, 0x81, 0xfc, 0x0e, 0x14, - 0x0a, 0x68, 0xcf, 0xf7, 0x71, 0x2a, 0x33, 0xc1, 0x07, 0x82, 0x13, 0x5b, 0xf5, 0x2d, 0xee, 0xfd, - 0x7f, 0xfb, 0x76, 0x44, 0x85, 0x6c, 0xdd, 0x4c, 0xa6, 0x95, 0xa9, 0x01, 0x31, 0x90, 0x49, 0xc4, - 0x3d, 0x4b, 0x96, 0xce, 0x4b, 0x00, 0xc9, 0x69, 0x94, 0xca, 0xd2, 0x72, 0xc6, 0xe5, 0xa5, 0x12, - 0x69, 0x52, 0x37, 0x74, 0x64, 0x8f, 0x89, 0x5a, 0x1e, 0x97, 0x9a, 0x00, 0x55, 0x45, 0x78, 0x0a, - 0x72, 0xff, 0x94, 0x26, 0x4e, 0xcd, 0x20, 0x36, 0xb5, 0x7f, 0x77, 0x3a, 0x3d, 0x38, 0x4a, 0x75, - 0x2e, 0x7c, 0x3e, 0x07, 0xc1, 0xf0, 0x78, 0x71, 0xc0, 0xa6, 0x75, 0x7f, 0xe9, 0x8a, 0x8b, 0xd1, - 0x33, 0x41, 0x0d, 0xcc, 0xd1, 0x18, 0x5d, 0x23, 0x57, 0x1b, 0x09, 0x38, 0x8c, 0x1f, 0x9c, 0x0f, - 0xc0, 0x7e, 0x07, 0xf0, 0x3f, 0x03, 0xf0, 0x16, 0x0a, 0x28, 0x8c, 0x57, 0x71, 0x2a, 0x56, 0x11, - 0x05, 0xc0, 0x9b, 0x63, 0x39, 0x73, 0x53, 0x95, 0x15, 0xe7, 0x15, 0xe0, 0x44, 0x4d, 0x15, 0xbf, - 0xde, 0x98, 0x1a, 0x4b, 0xb0, 0x85, 0x5f, 0x68, 0xb2, 0x5b, 0x4d, 0x6a, 0x3d, 0x83, 0xd4, 0xd4, - 0xe4, 0xd8, 0x47, 0x67, 0x80, 0x3b, 0xe3, 0xad, 0xfe, 0x78, 0xba, 0x10, 0x3c, 0x9f, 0x82, 0x30, - 0xf6, 0x8a, 0xbc, 0x1b, 0xf6, 0xab, 0x50, 0x0a, 0x6a, 0x96, 0xf5, 0x29, 0x24, 0xde, 0x06, 0x3b, - 0xf7, 0x9f, 0x93, 0xcf, 0x66, 0x29, 0xec, 0x7c, 0x3c, 0x0f, 0xc0, 0xfc, 0x1f, 0x0f, 0x91, 0xc3, - 0x1f, 0xad, 0x34, 0xc0, 0x86, 0xc4, 0x44, 0xcb, 0xae, 0xc7, 0x9d, 0xc9, 0x21, 0xf0, 0xa1, 0x6b, - 0xb0, 0x94, 0x45, 0x63, 0x08, 0x8f, 0x9e, 0x07, 0xe0, 0x7e, 0x03, 0xe0, 0x7f, 0x01, 0xf8, 0x19, - 0x0a, 0x68, 0xcf, 0xf7, 0x71, 0x2a, 0x34, 0x51, 0x00, 0x00, 0x00, 0x37, 0x6e, 0x5c, 0x01, 0x8c, - 0x3f, 0xff, 0x62, 0x2d, 0x0d, 0x9e, 0x43, 0x75, 0x69, 0xb0, 0x78, 0x55, 0x7e, 0x0f, 0x78, 0x26, - 0x7c, 0xd5, 0xb4, 0x5c, 0x1a, 0x30, 0x27, 0x9d, 0x48, 0x73, 0x70, 0x77, 0x0f, 0xf5, 0x30, 0x53, - 0xbc, 0x63, 0x38, 0x99, 0x77, 0x69, 0x3d, 0xd1, 0xa6, 0xad, 0x22, 0xf7, 0xc2, 0x6b, 0x53, 0x45, - 0xe5, 0x19, 0x13, 0x44, 0x4f, 0x02, 0x32, 0xfd, 0x03, 0x6f, 0x29, 0xac, 0x78, 0xae, 0x20, 0x62, - 0x9c, 0xf8, 0x3e, 0x0f, 0x81, 0xf8, 0x3f, 0x07, 0xc7, 0x07, 0x5d, 0x8f, 0x14, 0x34, 0xdc, 0xee, - 0xd5, 0xd4, 0x64, 0xbd, 0x7f, 0x9d, 0x45, 0x5f, 0xa1, 0x9c, 0xa3, 0x05, 0xe9, 0x23, 0xa2, 0x05, - 0x1b, 0x38, 0x7e, 0x07, 0xe0, 0x7c, 0x0c, 0x1b, 0x0a, 0x28, 0x8c, 0x57, 0x71, 0x2a, 0x36, 0x39, - 0x05, 0xc2, 0x2d, 0xb6, 0x06, 0x49, 0x18, 0xb9, 0xe1, 0x64, 0xf4, 0x2a, 0x15, 0xeb, 0xac, 0x33, - 0xea, 0xcb, 0x6d, 0x69, 0x4f, 0x5c, 0x10, 0x44, 0xbd, 0x31, 0xce, 0x3c, 0xba, 0xb9, 0xf0, 0x83, - 0x0b, 0x3e, 0x14, 0x7a, 0x56, 0x51, 0x5e, 0xcb, 0x95, 0x39, 0x71, 0xed, 0xd3, 0x33, 0x9a, 0x4d, - 0xa3, 0x8b, 0x9b, 0xcd, 0x16, 0xa3, 0x25, 0xae, 0x6c, 0x9f, 0x00, 0x00, 0x00, 0x91, 0xba, 0xd0, - 0x02, 0x44, 0x89, 0xfa, 0xbf, 0xa2, 0xf1, 0x11, 0x1d, 0x4e, 0x0f, 0x81, 0xf8, 0x1f, 0x03, 0xe1, - 0xe1, 0x35, 0x2d, 0x5d, 0x61, 0xc5, 0x78, 0xe4, 0xea, 0x5c, 0x86, 0x9b, 0x8e, 0x92, 0x54, 0xce, - 0x63, 0x30, 0xc1, 0xce, 0xd1, 0x4f, 0x87, 0xc1, 0xf0, 0x3f, 0x03, 0xf0, 0x3f, 0x81, 0xf0, 0x1f, - 0x0a, 0x70, 0xbc, 0x77, 0x71, 0x2a, 0x56, 0x11, 0x00, 0x00, 0x02, 0x46, 0x64, 0x63, 0x12, 0xa4, - 0x19, 0xda, 0x38, 0xd9, 0x99, 0xf8, 0xc7, 0xd6, 0x5a, 0xaf, 0x79, 0x14, 0x40, 0xbf, 0xda, 0xcc, - 0x59, 0xed, 0xff, 0xc4, 0x6e, 0x25, 0xa8, 0x83, 0x2f, 0x91, 0xbf, 0xf4, 0xb5, 0x60, 0x1f, 0x44, - 0x1c, 0x53, 0x27, 0x71, 0x4c, 0x3a, 0x84, 0x6d, 0x59, 0xfd, 0x68, 0x72, 0x16, 0x24, 0xc8, 0x22, - 0x04, 0xfd, 0x9d, 0xc3, 0x00, 0x0f, 0xc3, 0x4f, 0xf6, 0x9b, 0x99, 0x66, 0xe5, 0xe8, 0x9c, 0x13, - 0x63, 0x83, 0xe0, 0xf8, 0x1f, 0x81, 0xf0, 0x7e, 0x1c, 0x00, 0xdc, 0x6e, 0x2b, 0xe7, 0x9b, 0xa9, - 0xaa, 0x33, 0xb6, 0x37, 0xea, 0xdc, 0x11, 0xbb, 0xf4, 0xeb, 0x30, 0xd2, 0xf1, 0x65, 0x11, 0x5b, - 0xf0, 0xf8, 0x3e, 0x07, 0x83, 0xc7, 0xe0, 0x22, 0x0a, 0x70, 0xbc, 0x77, 0x71, 0x2a, 0x46, 0x31, - 0x00, 0x00, 0x00, 0x05, 0xc7, 0x20, 0x0c, 0x68, 0x5d, 0xb4, 0xd7, 0x65, 0xe2, 0x7e, 0x64, 0x69, - 0xc0, 0x79, 0x17, 0x8c, 0x04, 0xa0, 0xcd, 0xc7, 0x6c, 0x20, 0x96, 0x7c, 0x1a, 0x70, 0x8c, 0xdc, - 0x26, 0x89, 0x28, 0xfa, 0xca, 0x49, 0x17, 0xe8, 0x28, 0xa2, 0x5f, 0xa2, 0xfb, 0xd5, 0xc1, 0x91, - 0x6a, 0x18, 0x89, 0xe7, 0x92, 0x05, 0x50, 0x0f, 0xef, 0x5a, 0x5a, 0xdd, 0x0f, 0x6b, 0x9a, 0xd7, - 0x27, 0x98, 0x13, 0x4f, 0x94, 0x5e, 0xe4, 0xd0, 0xf0, 0xf0, 0xfc, 0x0f, 0xc1, 0xf8, 0x1f, 0x81, - 0xf0, 0x78, 0x7c, 0x93, 0x14, 0x0e, 0x50, 0xbd, 0x13, 0x0f, 0x7f, 0x25, 0x3c, 0x11, 0x04, 0x81, - 0x1c, 0x7f, 0xe7, 0x25, 0x7d, 0xe6, 0xe3, 0x8c, 0x61, 0x27, 0xc1, 0xf8, 0x3c, 0x70, 0xf0, 0x26, - 0x0a, 0x6f, 0x43, 0x77, 0x71, 0x2a, 0x25, 0x19, 0x05, 0xc0, 0x26, 0x36, 0xf3, 0x8a, 0xec, 0x1c, - 0xd5, 0x9c, 0x29, 0xf5, 0xb1, 0xb9, 0xc8, 0xb0, 0x3b, 0xa8, 0xc3, 0xe3, 0x2d, 0xca, 0x7b, 0x90, - 0xe6, 0x7d, 0x9a, 0xa6, 0x40, 0xd2, 0xd8, 0xda, 0x56, 0xf7, 0xfe, 0x56, 0xad, 0xfc, 0x3b, 0xae, - 0xd3, 0x95, 0x6d, 0xba, 0xde, 0x8c, 0x0b, 0x76, 0x9d, 0xe7, 0x56, 0xe3, 0x97, 0x14, 0x2c, 0x3c, - 0xb8, 0xa7, 0x7c, 0x9e, 0x00, 0xfc, 0x43, 0xaa, 0xed, 0x58, 0x9b, 0xc5, 0xf2, 0x01, 0xd6, 0x3c, - 0x7c, 0x1f, 0x03, 0xe0, 0x7e, 0x07, 0x87, 0x87, 0x86, 0x3c, 0xd1, 0xf4, 0xb5, 0x4a, 0x29, 0x93, - 0xad, 0x53, 0x30, 0x85, 0x95, 0x26, 0x4f, 0x45, 0xb5, 0xc3, 0x51, 0x31, 0xa5, 0x7a, 0x18, 0xc1, - 0xf0, 0x7e, 0x07, 0xe1, 0xf0, 0x3c, 0x06, 0x0e, 0x0a, 0xde, 0x40, 0xa7, 0x71, 0x2a, 0x24, 0x71, - 0x0d, 0xc1, 0xee, 0xba, 0xbd, 0x82, 0x50, 0xa0, 0x25, 0x0a, 0xed, 0x97, 0xce, 0x60, 0x2d, 0xf9, - 0xa6, 0x97, 0x2f, 0xe8, 0x05, 0xda, 0x37, 0x2b, 0x0e, 0xd5, 0x67, 0x48, 0x29, 0xb1, 0x94, 0x6f, - 0x1a, 0x31, 0xb4, 0x72, 0xba, 0xeb, 0x59, 0x91, 0xb7, 0xbc, 0x5e, 0xeb, 0xb1, 0xae, 0xa8, 0xd5, - 0x1c, 0xf8, 0x47, 0x27, 0x9c, 0x73, 0xb9, 0x80, 0xc9, 0xcd, 0x77, 0x0a, 0x99, 0x00, 0xa9, 0x04, - 0x4f, 0xe6, 0xb3, 0x10, 0x46, 0x70, 0xf0, 0x7e, 0x07, 0xe0, 0xfc, 0x1e, 0x0e, 0x3c, 0x26, 0x00, - 0xa0, 0xe7, 0x02, 0x0e, 0x19, 0x0b, 0x90, 0xa8, 0xbb, 0x24, 0x11, 0xb4, 0x13, 0xe2, 0x6d, 0xb9, - 0xec, 0x1f, 0x38, 0xd7, 0x64, 0xf0, 0x7e, 0x03, 0xf8, 0x1f, 0x81, 0xf8, 0x1f, 0x83, 0xf0, 0x11, - 0x0a, 0xde, 0x40, 0xa7, 0x71, 0x2a, 0x44, 0x31, 0x00, 0x00, 0x00, 0x5c, 0x89, 0x73, 0x30, 0x0e, - 0xb1, 0x92, 0xb9, 0x1e, 0xb0, 0x56, 0x34, 0x72, 0x4f, 0x7d, 0x1b, 0xca, 0x05, 0x95, 0xd5, 0xc5, - 0x98, 0xee, 0x37, 0x97, 0xa8, 0xfb, 0xb8, 0x61, 0xb1, 0x99, 0x00, 0x90, 0x96, 0xee, 0x1a, 0x6a, - 0x24, 0x6e, 0xeb, 0x9f, 0x53, 0xdc, 0x09, 0xaa, 0xfb, 0xc3, 0x8d, 0x1d, 0xa1, 0xee, 0x48, 0x97, - 0x60, 0xd2, 0xdd, 0x3c, 0x7f, 0xf4, 0xee, 0x11, 0x12, 0x9c, 0xdc, 0xa6, 0xba, 0x61, 0xc3, 0xe0, - 0x7e, 0x0f, 0xc0, 0xfc, 0x0f, 0x81, 0xe0, 0x99, 0x7d, 0xa2, 0xcc, 0x85, 0x43, 0xc5, 0xe5, 0xd6, - 0x64, 0xb5, 0x78, 0x70, 0xd0, 0xe9, 0x70, 0xe6, 0x75, 0x84, 0x3f, 0x0a, 0x7c, 0x86, 0x39, 0x88, - 0x88, 0x7f, 0x03, 0xe0, 0xf8, 0xf8, 0xf2, 0x15, 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x2a, 0x04, 0xb9, - 0x05, 0xc2, 0x71, 0x5c, 0x02, 0x99, 0xdc, 0x5e, 0xb9, 0x6c, 0x6f, 0xdf, 0x52, 0x9e, 0x2d, 0x5b, - 0x67, 0x0e, 0xb4, 0x18, 0x43, 0x89, 0x6a, 0x8f, 0xa6, 0xe6, 0xbc, 0x96, 0xf0, 0x9f, 0x9d, 0x79, - 0x3d, 0x03, 0x25, 0xfe, 0x2b, 0xa3, 0xf9, 0xca, 0x64, 0x77, 0xe7, 0x2c, 0x96, 0x69, 0x99, 0xa6, - 0xbe, 0x13, 0xcb, 0xa2, 0x0a, 0x6f, 0xa1, 0xc7, 0x36, 0xcc, 0xae, 0xd1, 0xba, 0x39, 0x05, 0xd0, - 0x9c, 0x17, 0xa2, 0xec, 0xff, 0x1c, 0x3e, 0x1f, 0x03, 0xf0, 0x3f, 0x07, 0xc0, 0xf0, 0xeb, 0xd0, - 0x52, 0x02, 0xe5, 0x4b, 0x24, 0x82, 0x0e, 0x6f, 0x8b, 0x2a, 0x88, 0x86, 0xb2, 0xaf, 0x77, 0x56, - 0xc3, 0xaf, 0xbe, 0x54, 0x80, 0x4f, 0x81, 0xf0, 0x7e, 0x0f, 0xc1, 0xf8, 0x1f, 0x03, 0xf0, 0x19, - 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x2a, 0x23, 0xc9, 0x37, 0xe7, 0x14, 0xf3, 0xd2, 0xc0, 0xce, 0x02, - 0x93, 0x8f, 0x9b, 0x1a, 0x50, 0x5a, 0x47, 0x8c, 0xdc, 0x53, 0x4d, 0x5c, 0xb4, 0xb1, 0x18, 0x31, - 0x8b, 0xad, 0x6f, 0xe6, 0x94, 0xbf, 0x01, 0x34, 0x04, 0x61, 0x26, 0xd3, 0xe1, 0xdb, 0x07, 0xf9, - 0xfd, 0x7f, 0x33, 0xf4, 0x54, 0x09, 0xfa, 0x10, 0x08, 0x85, 0x92, 0xb6, 0xe1, 0x32, 0x49, 0x94, - 0xa8, 0xd2, 0xb9, 0x34, 0x33, 0x34, 0x18, 0x72, 0x56, 0xdd, 0x19, 0x80, 0x50, 0xc0, 0x9c, 0x3e, - 0x0f, 0x87, 0xe0, 0x7e, 0x03, 0xf8, 0x1c, 0x01, 0x4b, 0x4b, 0xe6, 0x6c, 0x9d, 0x29, 0x01, 0xf6, - 0x9c, 0x38, 0x1d, 0x4c, 0x42, 0xaf, 0x61, 0xda, 0x8a, 0xe2, 0x6f, 0xb4, 0x32, 0x38, 0x4a, 0x44, - 0x03, 0x1b, 0xc6, 0x33, 0x03, 0xbc, 0x0e, 0xc8, 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x39, 0xf4, 0x31, - 0x05, 0xc7, 0xf5, 0x2a, 0x9f, 0x0e, 0x68, 0x80, 0x79, 0xe7, 0x0f, 0xd5, 0x1c, 0xbc, 0x9a, 0x6d, - 0xd6, 0x2a, 0x2e, 0xc9, 0x11, 0x80, 0xc7, 0xba, 0x44, 0x31, 0x0e, 0xf3, 0x02, 0xe4, 0x5b, 0x80, - 0x77, 0x70, 0x52, 0x7e, 0x49, 0x7e, 0xa1, 0xad, 0xff, 0xbe, 0xa0, 0x1b, 0x3b, 0xf6, 0x72, 0x30, - 0x1d, 0xdd, 0x5b, 0xe8, 0x64, 0xd4, 0x65, 0x2e, 0x94, 0xa3, 0xae, 0xb2, 0x67, 0xff, 0x16, 0x70, - 0x52, 0xc5, 0x0c, 0x7f, 0x70, 0x78, 0x1f, 0x81, 0xf8, 0x0f, 0xe0, 0x7c, 0x3f, 0x00, 0x41, 0xc3, - 0x29, 0x1b, 0x12, 0xb0, 0xe8, 0xe8, 0x03, 0xa2, 0x09, 0x02, 0x2e, 0xa9, 0x2c, 0xa9, 0x81, 0x6a, - 0xce, 0xe1, 0xe2, 0x51, 0xd9, 0xfd, 0xc0, 0x7c, 0x0f, 0xc0, 0xf0, 0x7c, 0x1f, 0x0f, 0x0e, 0x0d, - 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x2a, 0x14, 0x21, 0xb0, 0xd1, 0xfe, 0x02, 0x0c, 0xb3, 0xb6, 0x83, - 0x75, 0x81, 0xa0, 0x4b, 0x9d, 0x3a, 0x23, 0x6f, 0x51, 0x41, 0x4d, 0x7f, 0x12, 0x44, 0xf4, 0x60, - 0x50, 0x45, 0x95, 0x2f, 0x88, 0x02, 0xda, 0x5f, 0x55, 0x46, 0xe4, 0xcd, 0x0d, 0x60, 0xd7, 0xd5, - 0x8e, 0x46, 0xc2, 0x3b, 0x89, 0xe0, 0x4b, 0xd0, 0xe4, 0x97, 0x98, 0x58, 0xae, 0x7a, 0xca, 0x3e, - 0x36, 0xc8, 0x83, 0x54, 0xd5, 0x46, 0x39, 0xc6, 0xd6, 0xca, 0x29, 0x4a, 0x4e, 0x58, 0xf1, 0xe0, - 0xfc, 0x07, 0xf0, 0x1f, 0x81, 0xf8, 0x0f, 0xc3, 0xfe, 0xb0, 0x8d, 0xff, 0xed, 0xd6, 0xf0, 0xe5, - 0xc7, 0x8e, 0x3d, 0x4a, 0xa6, 0xb3, 0xe9, 0x92, 0xa1, 0xd3, 0xc6, 0x95, 0x0b, 0x66, 0xcf, 0xa4, - 0x2b, 0xe0, 0x7d, 0xe4, 0xfb, 0x9a, 0x73, 0x12, 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x3a, 0x34, 0x51, - 0x69, 0xf1, 0xe5, 0x5c, 0x4a, 0x49, 0xd5, 0xe9, 0xe1, 0x77, 0xd2, 0xa7, 0x0f, 0xaa, 0x5a, 0x24, - 0xe2, 0x43, 0xa0, 0xa7, 0xdb, 0x58, 0xfe, 0xeb, 0xe8, 0x14, 0x7d, 0x48, 0xda, 0x99, 0x7a, 0x03, - 0x9b, 0x72, 0x29, 0x8d, 0x06, 0xc2, 0x06, 0x3b, 0x4f, 0xa9, 0xc1, 0xc5, 0x40, 0x92, 0x93, 0xed, - 0xe8, 0x14, 0x4d, 0x2e, 0x89, 0x73, 0x03, 0x83, 0xdb, 0xee, 0xe3, 0xe2, 0x4b, 0x59, 0xef, 0xcb, - 0x0e, 0x14, 0xe8, 0x91, 0xc2, 0xb8, 0xf8, 0x3e, 0x07, 0xc1, 0xf0, 0x3f, 0x03, 0xf1, 0x10, 0x04, - 0xe0, 0x02, 0x43, 0x60, 0xa3, 0x65, 0xb9, 0xe2, 0x7e, 0xbe, 0x52, 0x1f, 0xcc, 0x0f, 0x33, 0x44, - 0x9c, 0xfa, 0x8a, 0x58, 0xf2, 0x60, 0xb9, 0x5a, 0x51, 0xbd, 0xe2, 0x1a, 0xf8, 0x6e, 0x06, 0xda, - 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x3a, 0x04, 0xf1, 0x69, 0xd4, 0x41, 0x0b, 0x57, 0xdc, 0xd0, 0x46, - 0x81, 0xf4, 0xba, 0xa0, 0x3b, 0x8a, 0xd5, 0x3f, 0x15, 0x89, 0x23, 0x10, 0x82, 0xcb, 0x6a, 0xe6, - 0x2a, 0x95, 0x3f, 0xfa, 0x5b, 0x0b, 0x07, 0x41, 0xd6, 0x3d, 0x40, 0x29, 0x99, 0x8a, 0x79, 0x56, - 0x9b, 0xb3, 0x6c, 0x58, 0x21, 0x02, 0x01, 0x3b, 0xf1, 0x7c, 0x62, 0x56, 0x94, 0xdb, 0x3a, 0x3b, - 0x02, 0xae, 0x17, 0xb0, 0xea, 0xe7, 0xc2, 0x8d, 0x71, 0x0f, 0x54, 0xa3, 0x99, 0xa3, 0x8f, 0x87, - 0xc1, 0xf8, 0x1f, 0x81, 0xf8, 0x1f, 0x81, 0xfe, 0x08, 0xe2, 0x50, 0x52, 0xe4, 0x31, 0xa3, 0x20, - 0x0c, 0x49, 0xd7, 0xc6, 0x46, 0x60, 0xf2, 0xe1, 0xa2, 0x10, 0x96, 0xfe, 0x6a, 0xba, 0x1c, 0x2a, - 0x41, 0x03, 0x3e, 0x3a, 0xbf, 0x7c, 0x1e, 0xe6, 0x0b, 0x58, 0xca, 0xf7, 0x71, 0x3a, 0x04, 0xe9, - 0xaa, 0xf6, 0x07, 0x75, 0x88, 0x63, 0x97, 0x76, 0xb2, 0x9f, 0x74, 0x03, 0x59, 0x45, 0x41, 0x64, - 0x44, 0xea, 0x56, 0xdd, 0x86, 0x5a, 0x08, 0x90, 0x09, 0xc2, 0xb0, 0x32, 0x2b, 0x21, 0x2d, 0xcd, - 0x6a, 0x7b, 0x10, 0x67, 0x57, 0xd0, 0x81, 0x62, 0x51, 0x53, 0x3e, 0x3b, 0x8c, 0x66, 0x1d, 0xe1, - 0xff, 0x9b, 0x9d, 0x50, 0xfe, 0x4b, 0x58, 0xc7, 0xe7, 0x69, 0xb9, 0xda, 0x2d, 0x04, 0x00, 0xaa, - 0xd7, 0xd5, 0x32, 0x17, 0x09, 0x87, 0x87, 0xc3, 0xe0, 0x7e, 0x07, 0xe0, 0xfc, 0x0f, 0x83, 0xec, - 0x3c, 0x60, 0x68, 0x2e, 0x87, 0x02, 0x42, 0x92, 0xf6, 0xb0, 0xe6, 0xab, 0x37, 0x16, 0xdc, 0x6d, - 0xdb, 0x1c, 0x9c, 0xc9, 0x39, 0x92, 0x09, 0xe9, 0x46, 0x9f, 0xc9, 0xb1, 0x69, 0x83, 0xf1, 0x35, - 0x4a, 0xde, 0x40, 0xa7, 0x71, 0x3a, 0x15, 0x49, 0xaa, 0xf5, 0xa7, 0x07, 0x1a, 0x24, 0xd7, 0x61, - 0x47, 0x97, 0x6d, 0xc7, 0xc2, 0xc0, 0x26, 0xe0, 0x2c, 0x82, 0x92, 0x48, 0x4b, 0x73, 0x2b, 0x20, - 0x89, 0x48, 0xd6, 0x5f, 0x35, 0x8e, 0xa8, 0xe1, 0xb9, 0x2f, 0x76, 0xc1, 0x24, 0x1f, 0xaf, 0xea, - 0x46, 0x96, 0x6c, 0x6f, 0xa1, 0x60, 0x3d, 0xb2, 0x9e, 0x5d, 0xe4, 0xdb, 0xe3, 0x20, 0x66, 0x06, - 0x79, 0x24, 0xa9, 0xfa, 0x90, 0x59, 0x7d, 0x95, 0x7e, 0x56, 0x56, 0x60, 0x00, 0x4f, 0xb7, 0xf0, - 0xf0, 0xf0, 0x3f, 0x07, 0xe0, 0x7c, 0x0f, 0xc0, 0xf1, 0xc2, 0xd4, 0x7e, 0x7f, 0x1f, 0x15, 0x02, - 0x91, 0x30, 0xa8, 0xcf, 0xe1, 0xd3, 0xbe, 0x39, 0x18, 0xa7, 0xd8, 0x27, 0x07, 0xe0, 0x8e, 0xba, - 0x64, 0x2c, 0xe3, 0x4e, 0x38, 0x93, 0xf1, 0x00, 0x0a, 0xde, 0x40, 0xa7, 0x71, 0x3a, 0x25, 0x49, - 0xaf, 0xdd, 0x49, 0xd0, 0x00, 0x2f, 0x1f, 0x73, 0x84, 0xbf, 0xb1, 0x1c, 0xd3, 0x01, 0xac, 0x45, - 0x65, 0xbf, 0xc2, 0xf9, 0x94, 0x70, 0xbd, 0x72, 0x2f, 0xeb, 0x2f, 0xed, 0xff, 0x1d, 0x00, 0x29, - 0x63, 0xa9, 0xa4, 0x2a, 0x32, 0x19, 0xc5, 0x17, 0xb8, 0x44, 0x9d, 0x35, 0x26, 0x80, 0x22, 0xc2, - 0xbd, 0x0f, 0x41, 0xea, 0x16, 0x51, 0x4d, 0x03, 0xcc, 0xaf, 0xb2, 0x4f, 0xe9, 0xa9, 0x48, 0xf9, - 0xed, 0x8f, 0xbd, 0xeb, 0xb8, 0x70, 0x7c, 0x0f, 0xe0, 0x7e, 0x03, 0xf0, 0x1f, 0x20, 0x3f, 0xc7, - 0x17, 0x44, 0x2c, 0x38, 0x3b, 0x6e, 0xa3, 0xbb, 0x95, 0xe6, 0x5a, 0xb0, 0x4a, 0xdb, 0xf1, 0xeb, - 0x06, 0x37, 0x12, 0x64, 0x90, 0xac, 0x4d, 0xef, 0x41, 0x0c, 0xb3, 0x81, 0xcc, 0x97, 0x87, 0x40, - 0x1b, 0x58, 0xca, 0xf7, 0x71, 0x39, 0xf4, 0x61, 0x69, 0xd4, 0x41, 0xd9, 0xdd, 0xe2, 0xaa, 0xbb, - 0x30, 0x4b, 0x61, 0x43, 0x0d, 0xcd, 0x67, 0x0a, 0x07, 0x99, 0x18, 0xa5, 0xf7, 0x78, 0x7d, 0x2a, - 0xaf, 0x8d, 0xda, 0xae, 0x4c, 0x0e, 0x07, 0x2b, 0x45, 0x54, 0x80, 0x0f, 0xd4, 0x4b, 0x87, 0x78, - 0x0b, 0x91, 0xb1, 0x2e, 0x37, 0x35, 0x62, 0xd7, 0xc6, 0x3f, 0xcf, 0x54, 0x66, 0xbc, 0xe8, 0x38, - 0xe6, 0xf9, 0xab, 0x8e, 0xda, 0x31, 0x2b, 0x01, 0x9b, 0x8b, 0x4e, 0x50, 0x91, 0x71, 0xe4, 0x61, - 0x4b, 0x87, 0x83, 0xe0, 0xfc, 0x1f, 0x81, 0xf8, 0x3f, 0x01, 0xff, 0xd5, 0x67, 0xbe, 0x3a, 0x6e, - 0xa3, 0xd6, 0x25, 0x10, 0xe6, 0x36, 0xca, 0xc3, 0xb4, 0xcd, 0xfd, 0xe9, 0xf0, 0xdd, 0xed, 0x7c, - 0xbd, 0xb9, 0x58, 0x95, 0xa7, 0xf3, 0xc8, 0xfc, 0x4a, 0xde, 0x40, 0xa7, 0x71, 0x1a, 0x35, 0xb1, - 0x69, 0x22, 0x08, 0x97, 0x59, 0xc6, 0xef, 0xda, 0x00, 0x19, 0xde, 0x54, 0x54, 0xea, 0xcd, 0xb9, - 0x7e, 0x65, 0x42, 0x94, 0x20, 0x3f, 0x4b, 0xa9, 0xfb, 0x31, 0xd5, 0x9e, 0x68, 0xa0, 0xc5, 0x27, - 0x24, 0xa4, 0x5e, 0x36, 0xd5, 0xe1, 0x64, 0x88, 0x08, 0xd4, 0xe5, 0xae, 0x1e, 0x3f, 0x37, 0x3d, - 0xcf, 0x5d, 0x03, 0x9a, 0x4e, 0xa2, 0x2e, 0xb6, 0xf5, 0x47, 0x01, 0x46, 0xb4, 0x3b, 0x84, 0x66, - 0x4c, 0x87, 0xfb, 0x3b, 0x01, 0xd9, 0x87, 0x87, 0x87, 0xe0, 0xf8, 0x1f, 0x81, 0xf8, 0x03, 0xfd, - 0xb2, 0x4c, 0x82, 0xd6, 0xce, 0x40, 0x2d, 0x5e, 0xfc, 0x72, 0x70, 0x29, 0x92, 0xc9, 0xe7, 0xd0, - 0x2d, 0xd9, 0x44, 0x87, 0x97, 0x1c, 0xf4, 0xe7, 0x59, 0x1c, 0xfc, 0xf0, 0xcc, 0x73, 0xe1, 0x77, - 0xec, 0xac, 0xa7, 0x07, 0x59, 0x3a, 0x34, 0xd1, 0x33, 0xd7, 0xfa, 0x76, 0x00, 0xee, 0xf2, 0xed, - 0xf8, 0x94, 0x94, 0xc0, 0xb9, 0xa4, 0x3d, 0x73, 0x2e, 0xd2, 0x6c, 0x0a, 0xbe, 0x1d, 0xb1, 0x2d, - 0xee, 0xa3, 0x3e, 0x04, 0x14, 0xc0, 0xfa, 0xd6, 0xc1, 0xad, 0x3a, 0xd5, 0x3a, 0x08, 0x3a, 0x82, - 0xed, 0xeb, 0x60, 0xab, 0x90, 0xb0, 0x5c, 0xd0, 0x9e, 0xec, 0xe7, 0xf3, 0x32, 0x70, 0x21, 0x8e, - 0xb4, 0xe7, 0x55, 0x09, 0xc3, 0x7a, 0xb9, 0x51, 0x5c, 0xe4, 0x03, 0x68, 0x1f, 0x80, 0xfe, 0x07, - 0xc1, 0xf6, 0x33, 0x12, 0x00, 0x69, 0xc8, 0xe7, 0x7c, 0x01, 0xd8, 0x78, 0x52, 0xef, 0x20, 0xde, - 0xd5, 0x6c, 0xfc, 0x67, 0xaf, 0x12, 0x8d, 0x3c, 0x17, 0x6d, 0x00, 0x3e, 0x0f, 0x90, 0x0f, 0xe0, - 0x1f, 0xc0, 0xfc, 0x1f, 0x81, 0xfc, 0x0f, 0x44, 0x19, 0x59, 0x4e, 0x0e, 0xb2, 0x6a, 0x13, 0x2c, - 0xa8, 0x0b, 0x9b, 0x86, 0xe8, 0xe9, 0x76, 0x98, 0xdc, 0xb9, 0x70, 0x9c, 0xac, 0xe8, 0xb2, 0xe0, - 0x03, 0x3c, 0xf9, 0xe9, 0x7e, 0xdc, 0x5f, 0x5b, 0x4e, 0x7c, 0xe8, 0x5c, 0xfc, 0xff, 0x23, 0x5e, - 0x64, 0x01, 0x67, 0x29, 0x2e, 0x85, 0x07, 0xf0, 0x11, 0x30, 0xc3, 0xc1, 0xa4, 0xfa, 0x3b, 0x7f, - 0x15, 0xa9, 0x98, 0x19, 0x76, 0x6c, 0x77, 0x61, 0x5f, 0x64, 0x7c, 0x7c, 0x74, 0x82, 0xbe, 0x76, - 0xb3, 0x6c, 0xcf, 0xca, 0xf1, 0xc0, 0xfe, 0x03, 0xf8, 0x1f, 0x0e, 0xf3, 0x21, 0x46, 0x9e, 0x63, - 0x18, 0x71, 0x2a, 0x07, 0x74, 0x18, 0x38, 0x57, 0x8a, 0x15, 0x1b, 0xdf, 0xb5, 0x4a, 0x5d, 0xad, - 0xe8, 0x07, 0xbe, 0x00, 0xf0, 0x7e, 0x07, 0xf0, 0x1f, 0xc0, 0x7e, 0x0f, 0xc1, 0xfc, 0x0f, 0x2a, - 0x19, 0x59, 0x4e, 0x0e, 0xb2, 0x6a, 0x43, 0x34, 0x69, 0xd5, 0x7a, 0xea, 0x8d, 0xa6, 0x94, 0x80, - 0xd3, 0x10, 0x5b, 0x5b, 0x86, 0xad, 0x0d, 0x0b, 0x31, 0xee, 0x21, 0xef, 0x0c, 0xd5, 0x0e, 0xf2, - 0x6d, 0x34, 0xd6, 0x6a, 0x11, 0xaf, 0x64, 0x96, 0xff, 0x14, 0x50, 0x9d, 0xd5, 0xe2, 0x07, 0xf4, - 0x00, 0x63, 0x2e, 0x2c, 0x94, 0xfc, 0xc5, 0x87, 0xfb, 0x73, 0x2e, 0xe3, 0xfd, 0xfe, 0xfe, 0xea, - 0x88, 0xc9, 0xb3, 0x3f, 0x38, 0xb7, 0x65, 0xc2, 0x48, 0xb1, 0xf2, 0x57, 0x78, 0xf0, 0x3e, 0x0f, - 0xc0, 0x7f, 0x03, 0xfe, 0x38, 0xbc, 0x78, 0x67, 0x36, 0xb0, 0xbf, 0x00, 0xa1, 0x93, 0x04, 0xfa, - 0x55, 0x44, 0xb8, 0xfb, 0xc8, 0xc3, 0xf7, 0x42, 0x67, 0x50, 0x79, 0x6a, 0x4e, 0x80, 0xbe, 0xc5, - 0xeb, 0xa2, 0x8c, 0xc3, 0x87, 0x21, 0xf9, 0x0f, 0x0c, 0xac, 0xa7, 0x07, 0x59, 0x3a, 0x04, 0x69, - 0x69, 0xd4, 0x3e, 0x17, 0xb0, 0x98, 0x04, 0x05, 0x75, 0x62, 0x2f, 0x8f, 0x3f, 0x5e, 0x54, 0x3e, - 0x5a, 0x21, 0x5e, 0xcb, 0xd7, 0x50, 0x7b, 0x89, 0x50, 0x16, 0xdb, 0x47, 0x9f, 0x8a, 0xf0, 0xa3, - 0x12, 0xe8, 0x0e, 0xf3, 0x32, 0x6b, 0xf4, 0x10, 0x12, 0xa8, 0x3d, 0x2b, 0x69, 0x26, 0xe1, 0x02, - 0x3f, 0x22, 0xd7, 0x13, 0x22, 0x67, 0x8b, 0x5d, 0x8f, 0x1c, 0x8c, 0x56, 0x22, 0x0c, 0x93, 0x19, - 0xb0, 0x83, 0xff, 0x31, 0x2b, 0x3c, 0x36, 0x31, 0xc6, 0x3e, 0x0f, 0xc0, 0xfc, 0x0f, 0xc0, 0x7c, - 0x0f, 0xfe, 0xd4, 0xc0, 0xa2, 0x0d, 0xa1, 0x10, 0xf3, 0xaf, 0xae, 0x98, 0x30, 0xe0, 0x4d, 0xb0, - 0xc3, 0x08, 0x7d, 0x39, 0x00, 0x47, 0xac, 0xaa, 0xfd, 0xe1, 0xc8, 0x3b, 0x8c, 0x7c, 0x0e, 0xc9, - 0x1c, 0xac, 0xa7, 0x07, 0x59, 0x3a, 0x25, 0xc9, 0xb0, 0xd2, 0xbf, 0x90, 0x45, 0xba, 0xcf, 0x4f, - 0x87, 0x7e, 0x31, 0x8d, 0xf2, 0xc5, 0x31, 0x44, 0x7f, 0x49, 0x8b, 0x3f, 0xd4, 0xde, 0xf5, 0x31, - 0x66, 0x82, 0xe2, 0xbf, 0x2d, 0x87, 0xbd, 0x21, 0xb4, 0xb1, 0x56, 0x42, 0x74, 0xfd, 0x5a, 0x44, - 0x03, 0x98, 0x1a, 0x22, 0x91, 0x2d, 0x63, 0x2a, 0xac, 0x87, 0x61, 0x2d, 0x26, 0xe9, 0x1a, 0xa5, - 0xff, 0xdf, 0x65, 0xe6, 0xfb, 0x97, 0x16, 0x3d, 0xcb, 0x01, 0xe3, 0x46, 0x4b, 0x26, 0xe7, 0x87, - 0xc0, 0xfc, 0x0f, 0xc0, 0xfc, 0x1f, 0x81, 0xff, 0x01, 0x0e, 0x43, 0xa4, 0x08, 0x8e, 0x02, 0xe1, - 0xf9, 0x47, 0x77, 0xd6, 0xe0, 0x31, 0x67, 0x40, 0x2f, 0xf9, 0xe0, 0x93, 0x68, 0xb8, 0x61, 0xea, - 0xb1, 0xc0, 0x9e, 0x49, 0x85, 0x83, 0x89, 0x06, 0x1c, 0x32, 0x1c, 0xb7, 0x59, 0x3a, 0x25, 0x71, - 0x69, 0xd5, 0x7a, 0x69, 0x7a, 0x00, 0x00, 0x00, 0x5e, 0xcd, 0x5d, 0x5d, 0x9f, 0xe1, 0x34, 0x7f, - 0x41, 0x1f, 0x3e, 0x58, 0x11, 0xd7, 0x0b, 0xc5, 0xff, 0x81, 0x59, 0x5d, 0x18, 0x0f, 0x3a, 0xc4, - 0x1d, 0x36, 0x73, 0x5a, 0x43, 0x92, 0xf7, 0x4c, 0x58, 0x75, 0xba, 0x19, 0x39, 0xeb, 0x22, 0x49, - 0x03, 0xd5, 0x9a, 0xa0, 0xec, 0x9a, 0x77, 0xd4, 0x59, 0x8a, 0x8a, 0x86, 0x6e, 0x73, 0x42, 0x25, - 0x5f, 0xe9, 0x15, 0x7e, 0x51, 0x3c, 0x07, 0xc7, 0x91, 0xc7, 0x87, 0x83, 0xf0, 0x3e, 0x07, 0xe0, - 0x78, 0x00, 0x2b, 0x98, 0xf9, 0x3e, 0xe7, 0x5d, 0x8b, 0xe1, 0x46, 0x29, 0x6d, 0xb1, 0x9c, 0xaf, - 0x4c, 0x0e, 0x49, 0x7c, 0xe9, 0xc1, 0x22, 0x17, 0x17, 0xa4, 0x60, 0x47, 0x09, 0xef, 0x85, 0x03, - 0x1c, 0x32, 0x1c, 0xb7, 0x59, 0x3a, 0x15, 0xb1, 0x66, 0x56, 0xfc, 0x34, 0x6c, 0x0a, 0x7c, 0x00, - 0x31, 0xe7, 0x9b, 0x3e, 0x8b, 0xe6, 0x8e, 0x9b, 0x9f, 0x19, 0x61, 0x3a, 0xd0, 0x2d, 0xca, 0xba, - 0x73, 0xc6, 0xf2, 0x04, 0x09, 0x48, 0x28, 0x24, 0x67, 0xbe, 0x51, 0xf8, 0xc4, 0x8c, 0xdc, 0x81, - 0x46, 0x13, 0x86, 0x85, 0x4d, 0x25, 0x2b, 0xb4, 0x64, 0x23, 0x77, 0x62, 0x64, 0xf0, 0x52, 0x6e, - 0xd6, 0x59, 0x17, 0xdc, 0xd7, 0x44, 0x07, 0xd7, 0x05, 0x6f, 0x6e, 0x66, 0x81, 0x15, 0x11, 0x60, - 0x67, 0x8f, 0x83, 0xf0, 0x3f, 0x01, 0xf0, 0x78, 0x3e, 0x00, 0x1c, 0x54, 0x4e, 0x17, 0x85, 0x28, - 0x30, 0x08, 0xc8, 0xa3, 0x18, 0xab, 0x25, 0x2a, 0x03, 0x7d, 0x4d, 0xc4, 0x73, 0x7a, 0xdb, 0xdc, - 0xdc, 0x39, 0x15, 0x4b, 0x45, 0x31, 0xf1, 0x01, 0x1c, 0x32, 0x8b, 0xb7, 0x59, 0x3a, 0x36, 0x29, - 0xb0, 0xdc, 0x58, 0x9c, 0x3d, 0xf8, 0x63, 0x7f, 0xcc, 0xc6, 0x86, 0xb4, 0x12, 0xbb, 0xc1, 0xa6, - 0x45, 0x22, 0x34, 0xe9, 0xcb, 0x2d, 0xf6, 0x45, 0x0a, 0x74, 0x9a, 0x04, 0xaa, 0x90, 0xfa, 0xfe, - 0x2e, 0xc2, 0xb7, 0x5b, 0x04, 0x95, 0x5b, 0x1c, 0xbb, 0x27, 0x4c, 0x23, 0x74, 0x29, 0x65, 0xb3, - 0x29, 0x83, 0x0c, 0xff, 0xca, 0x2c, 0x9b, 0x02, 0x71, 0x97, 0x97, 0xfc, 0x2a, 0x5e, 0xe8, 0xa5, - 0xcb, 0x5b, 0xf4, 0xf5, 0x3e, 0x3e, 0x1f, 0x1f, 0x0f, 0xc1, 0xf0, 0xf8, 0x38, 0x39, 0xf7, 0xed, - 0xfd, 0xb5, 0xbf, 0x3d, 0xc6, 0xe4, 0x97, 0x53, 0xd5, 0xdb, 0x24, 0x1a, 0x2d, 0x59, 0x46, 0xd2, - 0x78, 0xcf, 0x44, 0x64, 0xc8, 0x97, 0x87, 0x00, 0x00, 0x5b, 0x76, 0x23, 0x1e, 0x3e, 0x0f, 0x40, - 0x1c, 0x31, 0xa2, 0xb7, 0x59, 0x3a, 0x44, 0xc1, 0x33, 0xd3, 0x8d, 0x2f, 0x14, 0xf2, 0x6a, 0x70, - 0xdb, 0x8e, 0x7a, 0xb3, 0x95, 0xcb, 0x81, 0x5c, 0xf8, 0x5c, 0xb0, 0x30, 0xb8, 0x50, 0xb8, 0xcd, - 0x5f, 0x61, 0xe5, 0xfc, 0x54, 0xd0, 0xcc, 0xb0, 0x32, 0xa3, 0x79, 0x23, 0x30, 0xbf, 0xa6, 0x60, - 0xb0, 0x91, 0x48, 0x28, 0xdb, 0xa6, 0x6d, 0x06, 0x7d, 0x8c, 0x41, 0x4d, 0x9d, 0x79, 0xec, 0xde, - 0x45, 0xf9, 0xb2, 0x3b, 0x8c, 0x84, 0x4f, 0x89, 0xca, 0x2f, 0xa9, 0xfb, 0x6a, 0x83, 0xf0, 0x3e, - 0x1c, 0x7c, 0x68, 0x4e, 0x04, 0x06, 0x2e, 0x0b, 0xf1, 0x9b, 0x10, 0x41, 0x34, 0xde, 0x34, 0x46, - 0xc1, 0x25, 0x43, 0x02, 0xe8, 0xaa, 0x72, 0x89, 0xa2, 0xb8, 0x99, 0xe1, 0xf8, 0x1f, 0xc0, 0x7e, - 0x03, 0xf8, 0x07, 0xe0, 0x7e, 0x07, 0xe2, 0x98, 0x38, 0x63, 0x2d, 0x6e, 0xb2, 0x6a, 0x13, 0x7c, - 0xa7, 0x93, 0xab, 0x53, 0x7c, 0x44, 0xa6, 0xa3, 0x5c, 0x6e, 0x15, 0x16, 0xc0, 0x70, 0x24, 0x37, - 0x5e, 0xed, 0x86, 0x81, 0x07, 0x22, 0x6d, 0xfa, 0x2b, 0xb4, 0xbc, 0x96, 0x97, 0x5d, 0xf1, 0x41, - 0x46, 0x6b, 0x74, 0x19, 0x83, 0x62, 0xb5, 0xf6, 0x5a, 0x82, 0x66, 0x62, 0x21, 0x40, 0x53, 0xb6, - 0x3e, 0x02, 0xf0, 0xe1, 0x78, 0x1d, 0x7d, 0x09, 0x1d, 0x32, 0x2c, 0x03, 0xac, 0x48, 0x36, 0xfd, - 0x00, 0x00, 0x62, 0x87, 0x11, 0x9d, 0xee, 0x1f, 0x81, 0xf8, 0xe3, 0x98, 0x09, 0x2a, 0x02, 0xf1, - 0x43, 0xba, 0xc3, 0x0f, 0xe8, 0x3a, 0xb6, 0x16, 0x3e, 0x19, 0xd3, 0xca, 0x0d, 0xac, 0x66, 0x44, - 0x29, 0x66, 0x02, 0x11, 0xc3, 0xe1, 0xf8, 0x0f, 0xe0, 0x3f, 0x81, 0xfc, 0x0f, 0x8c, 0xe2, 0x94, - 0x38, 0x63, 0x2d, 0x6e, 0xb2, 0x6a, 0x04, 0xfc, 0x33, 0x99, 0x90, 0x39, 0x20, 0x30, 0xff, 0xb4, - 0x30, 0xb8, 0xc4, 0x12, 0xb1, 0xe9, 0x0f, 0x96, 0xdb, 0x03, 0xcd, 0x52, 0xe2, 0x14, 0x56, 0xf6, - 0x04, 0x3c, 0x4a, 0x5e, 0x8f, 0x15, 0xee, 0xc2, 0x67, 0x8b, 0x94, 0xf7, 0xdc, 0x90, 0x0b, 0xf3, - 0x4e, 0x58, 0xf1, 0x50, 0x5c, 0xa2, 0x6f, 0xa7, 0xa2, 0x7e, 0xb3, 0xf3, 0x5f, 0x90, 0x15, 0x67, - 0xd4, 0xeb, 0xa4, 0x7f, 0x2b, 0x1c, 0xb9, 0x0c, 0x41, 0xc5, 0x02, 0x16, 0xa8, 0xf1, 0xe0, 0xfc, - 0x0f, 0x87, 0x82, 0x1b, 0xdf, 0x89, 0x5e, 0x36, 0x79, 0xbe, 0x67, 0xef, 0xfc, 0x10, 0x3b, 0x67, - 0x30, 0x8e, 0xc5, 0x3f, 0x39, 0x00, 0x2c, 0x4f, 0xf8, 0xe4, 0x46, 0x5d, 0x83, 0xf0, 0x3f, 0x03, - 0xf0, 0x3f, 0x03, 0xf0, 0x3c, 0x3c, 0x1e, 0x90, 0x38, 0x63, 0x2d, 0x6e, 0xb2, 0x69, 0xf3, 0xd4, - 0x33, 0xd8, 0x0e, 0xc2, 0x9f, 0x37, 0x79, 0x60, 0x9a, 0xfc, 0xf2, 0x74, 0xf3, 0x6f, 0x3a, 0x72, - 0x71, 0x2d, 0xb0, 0xd3, 0xf7, 0x25, 0x57, 0x4a, 0x2f, 0xeb, 0xcf, 0x94, 0xce, 0x06, 0x4e, 0x2c, - 0x72, 0xbc, 0xf8, 0xf4, 0x26, 0xde, 0xb9, 0x51, 0xea, 0xba, 0xe8, 0x09, 0x79, 0x57, 0xa0, 0x97, - 0xbf, 0xf5, 0x41, 0xfb, 0x9b, 0x94, 0x77, 0x67, 0x5e, 0xfc, 0xb8, 0xc1, 0xe8, 0x27, 0x86, 0x12, - 0x09, 0x3c, 0xf9, 0xba, 0x0f, 0x4c, 0xe0, 0x7e, 0x0e, 0x1c, 0x42, 0x9e, 0x7d, 0x1d, 0xfa, 0x47, - 0x21, 0xa5, 0xa7, 0x83, 0xdb, 0x4b, 0x22, 0x0f, 0xda, 0x11, 0x07, 0x36, 0x97, 0x0d, 0x1a, 0x4a, - 0x3e, 0x42, 0x58, 0xfc, 0x70, 0x3f, 0x03, 0xf8, 0x1f, 0x81, 0xfc, 0x0f, 0xc1, 0xf0, 0x3e, 0x8c, - 0x38, 0x63, 0x2d, 0x6e, 0xb2, 0x6a, 0x23, 0x6c, 0x69, 0xd4, 0x3e, 0x17, 0xac, 0x21, 0x55, 0x93, - 0x90, 0xdc, 0x64, 0xe3, 0x94, 0x46, 0x58, 0x16, 0x64, 0x08, 0x07, 0x57, 0xea, 0xe7, 0x8d, 0xe6, - 0x3c, 0xff, 0x72, 0xe9, 0xee, 0x44, 0xa1, 0x91, 0xe0, 0xa5, 0x8d, 0xf8, 0x00, 0x42, 0xf4, 0x4f, - 0x12, 0xaa, 0x8d, 0x53, 0xe5, 0x04, 0x23, 0x9a, 0xb0, 0xdf, 0x36, 0x57, 0x8d, 0x80, 0xce, 0x61, - 0x42, 0x79, 0x4e, 0x9a, 0x98, 0x80, 0x36, 0x76, 0xb1, 0x12, 0x52, 0x09, 0x04, 0x3b, 0xc3, 0x07, - 0x83, 0xc3, 0xc1, 0xce, 0xe7, 0x38, 0xd9, 0x76, 0x6f, 0x6f, 0x4d, 0xf7, 0xca, 0xf3, 0x15, 0x07, - 0xf4, 0xa4, 0x45, 0x43, 0xe6, 0x1e, 0x2b, 0x38, 0x95, 0x22, 0x62, 0x7e, 0x09, 0x2a, 0x75, 0x4d, - 0xbe, 0x8a, 0xb3, 0xf8, 0xe7, 0x28, 0xf1, 0x45, 0x15, 0x36, 0xf0, 0xaa, 0x59, 0x3a, 0x05, 0x61, - 0x17, 0x53, 0xba, 0x39, 0x92, 0x10, 0x28, 0x29, 0x42, 0x01, 0x0d, 0x63, 0x30, 0xf6, 0xa2, 0x2e, - 0x2e, 0x94, 0x22, 0x45, 0x69, 0x24, 0x9c, 0xed, 0xc9, 0x03, 0xbb, 0xfa, 0x1b, 0x87, 0x07, 0x18, - 0x7b, 0x1c, 0x81, 0xcc, 0x46, 0x10, 0x0c, 0x05, 0x37, 0xa8, 0xc9, 0xf0, 0x54, 0x77, 0x46, 0xbb, - 0x32, 0x7e, 0xad, 0x89, 0x17, 0xdb, 0x80, 0x3b, 0xcb, 0x56, 0x1c, 0xc4, 0x60, 0x62, 0x11, 0x1b, - 0x0d, 0x2b, 0x8a, 0xfa, 0x5f, 0x9b, 0x03, 0xe3, 0xc3, 0xe3, 0x08, 0x19, 0x41, 0xf9, 0xb0, 0x75, - 0x90, 0x35, 0xf1, 0x6b, 0xde, 0x52, 0x86, 0xb0, 0xa8, 0x45, 0xf5, 0x31, 0x38, 0xbc, 0x42, 0x74, - 0x11, 0x0e, 0x67, 0x07, 0xc0, 0xfc, 0x07, 0xf0, 0x1f, 0xc0, 0x7e, 0x07, 0xc0, 0xf8, 0x1e, 0x88, - 0x2a, 0x6d, 0xe1, 0x54, 0xb2, 0x69, 0xf4, 0x84, 0x33, 0x99, 0x90, 0x14, 0xce, 0x01, 0x5d, 0xb0, - 0x5e, 0x96, 0x0e, 0x6e, 0xab, 0x5c, 0xe5, 0x6d, 0xbb, 0x37, 0x38, 0xb9, 0xb2, 0x1b, 0x05, 0x8c, - 0x78, 0x2c, 0x60, 0xcb, 0xf6, 0x63, 0xc2, 0xaa, 0xcf, 0x45, 0xe3, 0xe7, 0x83, 0xfc, 0x3b, 0xd6, - 0x02, 0x76, 0x96, 0x16, 0x4c, 0xf2, 0xdb, 0x01, 0x14, 0xee, 0x3d, 0x4f, 0xfa, 0x79, 0xe6, 0xee, - 0xcf, 0x2e, 0x8b, 0x05, 0x95, 0xce, 0x11, 0xdd, 0x00, 0x06, 0x76, 0xa4, 0xd0, 0x72, 0xe6, 0x0f, - 0x83, 0xcf, 0x01, 0x37, 0xba, 0xad, 0xa4, 0x76, 0x0e, 0xf2, 0x49, 0xa9, 0xf3, 0xf3, 0xdf, 0xa4, - 0x60, 0x91, 0x77, 0xd7, 0x02, 0x6d, 0x81, 0x16, 0xc1, 0x6a, 0x3f, 0x11, 0xdc, 0x78, 0x1f, 0x81, - 0xfc, 0x07, 0xf0, 0x3f, 0x07, 0x87, 0x86, 0x84, 0x2a, 0x6d, 0xe1, 0x54, 0xb2, 0x69, 0xf5, 0x2c, - 0x33, 0xd3, 0x8c, 0x58, 0xe1, 0x9c, 0xb2, 0x59, 0xfc, 0xdc, 0xd0, 0xc0, 0xf3, 0xe2, 0x7b, 0x0d, - 0x82, 0x03, 0x79, 0xc8, 0x02, 0x05, 0xa5, 0xc0, 0xa3, 0x32, 0x5e, 0xa7, 0x59, 0x35, 0x90, 0x72, - 0xba, 0x77, 0x62, 0x47, 0x75, 0xe5, 0xe7, 0x87, 0xff, 0x6f, 0xf6, 0x54, 0x3c, 0x3c, 0x04, 0xa5, - 0x61, 0x6b, 0x51, 0xb2, 0xef, 0x43, 0xfc, 0xe5, 0x5a, 0x49, 0xd8, 0xa2, 0x90, 0x2d, 0xf4, 0xc9, - 0x92, 0x34, 0x04, 0x4d, 0xbc, 0x44, 0x1b, 0x3c, 0x1f, 0x0f, 0x07, 0xe7, 0x1e, 0x4c, 0x8e, 0x93, - 0x84, 0xc3, 0x84, 0xf0, 0x53, 0xdf, 0x8f, 0x39, 0x31, 0xeb, 0x80, 0xfb, 0x07, 0xa7, 0xc4, 0x62, - 0xdb, 0xe9, 0xe8, 0x64, 0x1e, 0x0f, 0x80, 0xfc, 0x07, 0xe0, 0x7e, 0x07, 0x83, 0x81, 0xe2, 0x82, - 0x2a, 0x6d, 0xe1, 0x54, 0xb2, 0x69, 0xd5, 0x14, 0xa7, 0x9c, 0xd9, 0x8f, 0xdd, 0x6b, 0x3d, 0x76, - 0xf7, 0xc3, 0x0e, 0x97, 0x50, 0x17, 0x2a, 0xf3, 0xb1, 0xc9, 0x00, 0x11, 0x47, 0x58, 0xb6, 0x37, - 0x42, 0x00, 0x82, 0x81, 0xef, 0x39, 0xd7, 0x5c, 0xd4, 0x53, 0xa8, 0x2e, 0xf6, 0xbf, 0x6b, 0x6b, - 0xed, 0xbb, 0x79, 0x5f, 0x4e, 0x7f, 0x5c, 0x9c, 0x36, 0xde, 0xd0, 0xc3, 0xe0, 0xa2, 0x2e, 0xf6, - 0xdc, 0x8b, 0x53, 0x7a, 0x9c, 0xb5, 0xd2, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x86, 0xe7, 0xe0, 0xe7, - 0x03, 0xae, 0x3b, 0xcf, 0xdc, 0xa2, 0x6e, 0x9d, 0x9c, 0x27, 0xe3, 0x71, 0x00, 0x53, 0xcf, 0x51, - 0x41, 0xab, 0x75, 0x93, 0x63, 0x0f, 0x17, 0x53, 0x8f, 0x43, 0xc1, 0xf9, 0x01, 0xfb, 0x08, 0x3f, - 0xc0, 0xfc, 0x07, 0xc0, 0xfc, 0x07, 0xe2, 0x82, 0x38, 0x37, 0x7f, 0xee, 0xb2, 0x6a, 0x05, 0x04, - 0xaf, 0xdd, 0x47, 0xae, 0x91, 0xb9, 0x15, 0x00, 0x00, 0x35, 0x1c, 0x0e, 0xf4, 0x88, 0x7b, 0x3b, - 0x20, 0x11, 0x45, 0xff, 0x9b, 0xc9, 0x49, 0x92, 0x5c, 0xa8, 0x15, 0xc6, 0x2f, 0x00, 0x65, 0xd9, - 0x0c, 0xa6, 0xc1, 0x57, 0x59, 0xfe, 0x6c, 0xa8, 0xb9, 0xca, 0x85, 0x17, 0x43, 0x10, 0x50, 0x89, - 0x2a, 0x32, 0xf0, 0xe9, 0x21, 0xb0, 0x76, 0x84, 0xd6, 0x2c, 0x02, 0x2d, 0xca, 0x00, 0xe4, 0xe7, - 0x70, 0xfc, 0x0d, 0x62, 0x61, 0x29, 0x9b, 0x87, 0x1f, 0x0f, 0xc1, 0xf8, 0x1f, 0x83, 0xe0, 0xe3, - 0x86, 0x05, 0x8b, 0x60, 0x65, 0xfa, 0x56, 0x07, 0xe6, 0x3c, 0x06, 0x1a, 0x85, 0xda, 0x16, 0xa8, - 0xe5, 0x5d, 0x56, 0x66, 0x21, 0xce, 0x99, 0xa2, 0xd4, 0xeb, 0x17, 0x0b, 0xe6, 0x20, 0x53, 0x48, - 0x15, 0xa9, 0xc6, 0x9a, 0x59, 0x3a, 0x15, 0x19, 0xa8, 0x0a, 0xd8, 0xfb, 0x8e, 0x91, 0xcf, 0x81, - 0xf5, 0x95, 0x4a, 0x3c, 0xbf, 0x7b, 0x07, 0x47, 0x4c, 0x06, 0xfb, 0xb8, 0x8e, 0x89, 0x7a, 0xe4, - 0x77, 0xd5, 0xfe, 0xa2, 0x5d, 0x91, 0x3b, 0x3a, 0x4e, 0x73, 0x87, 0x6e, 0x9e, 0xb1, 0x18, 0x3f, - 0x20, 0x0f, 0x97, 0xc7, 0x92, 0xbd, 0x38, 0xa4, 0x5a, 0xdf, 0x04, 0x0d, 0xd6, 0xee, 0xe5, 0x37, - 0x91, 0x4d, 0xd6, 0xf1, 0x39, 0x0a, 0x77, 0xf4, 0x28, 0x18, 0xd6, 0x4e, 0x1b, 0x1f, 0x07, 0x30, - 0x0d, 0x89, 0xf3, 0xe2, 0xa3, 0x96, 0x01, 0xfa, 0x00, 0x69, 0x46, 0x83, 0x58, 0xf8, 0x7d, 0x50, - 0xe5, 0x1c, 0x72, 0x20, 0x12, 0x0a, 0x40, 0x31, 0x94, 0x3f, 0xe1, 0xe0, 0x7e, 0x07, 0xf0, 0x1f, - 0xc0, 0x7e, 0x07, 0xe0, 0x7e, 0x07, 0xe2, 0x8e, 0x31, 0x44, 0x9f, 0x94, 0xb2, 0x6a, 0x04, 0x14, - 0x62, 0xa1, 0x41, 0x6d, 0x58, 0xb3, 0xd6, 0x54, 0x5d, 0x8e, 0x1b, 0xf9, 0xf7, 0xe1, 0xdc, 0xb2, - 0x0a, 0x45, 0xcd, 0xfa, 0x6e, 0x8d, 0x63, 0x73, 0x21, 0x99, 0x55, 0x5c, 0x2c, 0x3a, 0xbf, 0x9c, - 0xe7, 0xad, 0xb0, 0xa9, 0x88, 0xcb, 0x00, 0xd0, 0x1b, 0x3b, 0x87, 0xe4, 0x34, 0x74, 0xd6, 0x41, - 0x01, 0x5a, 0x90, 0x50, 0xd8, 0x61, 0x22, 0xb8, 0xdf, 0xbe, 0xab, 0xa6, 0xf9, 0xd2, 0x05, 0x81, - 0xe6, 0x82, 0x20, 0x7c, 0x3c, 0x60, 0x18, 0x64, 0x7d, 0x2c, 0x7c, 0xc3, 0xf1, 0xfb, 0xbb, 0x77, - 0x59, 0xf4, 0x7b, 0xf2, 0x06, 0x8d, 0x50, 0x8d, 0x9f, 0x4c, 0xc1, 0xa1, 0x0f, 0x69, 0x56, 0x91, - 0xee, 0x6c, 0x3c, 0x0f, 0xc0, 0x7f, 0x01, 0xfc, 0x07, 0xf0, 0x3f, 0x00, 0xfe, 0x03, 0xe2, 0x8c, - 0x31, 0x44, 0x9f, 0x94, 0xb2, 0x6a, 0x04, 0x2c, 0x33, 0xd7, 0xfb, 0x2c, 0x1a, 0x47, 0x41, 0x14, - 0xaa, 0xbb, 0x2f, 0x89, 0x27, 0x2c, 0x14, 0x19, 0x47, 0x2c, 0x09, 0x2b, 0xb7, 0x86, 0x2a, 0x41, - 0xcd, 0xea, 0x0a, 0xc0, 0x62, 0x0d, 0x1a, 0xfd, 0xf2, 0x27, 0x4f, 0x87, 0xfa, 0x66, 0x41, 0x22, - 0xf0, 0xc0, 0x7d, 0x12, 0x3c, 0xff, 0xd8, 0x37, 0x5b, 0x53, 0x07, 0x9b, 0x31, 0x48, 0x1e, 0x74, - 0xa3, 0xf6, 0x2c, 0x3f, 0x81, 0xf5, 0x8a, 0xaa, 0xa1, 0xdc, 0x84, 0x92, 0x7d, 0x56, 0x0f, 0x83, - 0x8f, 0xf0, 0x45, 0x63, 0x5e, 0x0b, 0x34, 0x10, 0x60, 0xc9, 0x8b, 0xf9, 0x00, 0x0b, 0x35, 0xf6, - 0x63, 0xf4, 0x00, 0xc7, 0x64, 0x11, 0xef, 0x57, 0xa0, 0x76, 0x84, 0xe1, 0xf0, 0x1f, 0x81, 0xf8, - 0x1f, 0x80, 0xfc, 0x0f, 0xc0, 0xfc, 0x1e, 0x8a, 0x31, 0x44, 0x9f, 0x94, 0xb2, 0x69, 0xf4, 0x24, - 0x37, 0xdf, 0x74, 0xd5, 0xec, 0x89, 0x25, 0xf8, 0x06, 0x62, 0xdb, 0x69, 0xec, 0x25, 0xdc, 0x0f, - 0x00, 0xff, 0x4e, 0x2f, 0xa4, 0xfa, 0x75, 0x06, 0x49, 0x05, 0xde, 0xc4, 0x47, 0x9a, 0x70, 0x2d, - 0xa8, 0xbf, 0x43, 0xb5, 0x73, 0xb5, 0x6b, 0xbd, 0x7f, 0xd3, 0x51, 0xd3, 0x4a, 0xd9, 0x29, 0xfc, - 0x69, 0xd6, 0xdc, 0x20, 0xa8, 0x28, 0x3f, 0xa6, 0x59, 0x57, 0x81, 0xa7, 0x2f, 0x3e, 0x61, 0xaf, - 0x9f, 0xa5, 0x61, 0x1f, 0xb9, 0x0d, 0x44, 0xf7, 0xee, 0x5e, 0xd9, 0xd7, 0x0a, 0x59, 0xe6, 0x09, - 0x6d, 0xc8, 0xd8, 0xe2, 0x42, 0x98, 0xa5, 0x7b, 0x7e, 0xcc, 0xcc, 0xe9, 0x1b, 0x0b, 0xc5, 0x35, - 0x31, 0x73, 0xa5, 0x75, 0x96, 0xa6, 0x00, 0x1c, 0x3e, 0x1e, 0x07, 0x1c, 0xf1, 0xe0, 0x3e, 0x08, - 0x31, 0x44, 0x9f, 0x94, 0xb2, 0x79, 0x95, 0xcc, 0x33, 0x9e, 0x5d, 0x41, 0x8f, 0x8a, 0x96, 0xc7, - 0xe1, 0x70, 0x65, 0xe7, 0xdb, 0x04, 0xd5, 0xd1, 0x32, 0xef, 0x93, 0xc9, 0x18, 0x8f, 0xe0, 0xe1, - 0x65, 0x45, 0x99, 0x6e, 0x1c, 0x2b, 0xc9, 0x31, 0x1c, 0x79, 0x1b, 0x83, 0x4e, 0xff, 0xda, 0x66, - 0x7e, 0x8c, 0xe7, 0x4e, 0x49, 0x2a, 0x1d, 0x4f, 0x7a, 0x6a, 0xb4, 0xe7, 0xa0, 0x05, 0x0c, 0xc2, - 0x46, 0xd2, 0x31, 0x87, 0xa6, 0x36, 0x6c, 0x25, 0x7e, 0x12, 0xfb, 0x1c, 0x24, 0xc3, 0xe0, 0xf1, - 0xee, 0x58, 0x4a, 0x5e, 0xa5, 0x27, 0x85, 0xc0, 0x61, 0xcd, 0xf2, 0xbc, 0xb1, 0x17, 0xc3, 0xd6, - 0xd6, 0x54, 0xc7, 0xff, 0xa1, 0xe7, 0xc1, 0x0f, 0xbf, 0xf9, 0x4a, 0x23, 0xc3, 0xf0, 0x3f, 0x03, - 0xf8, 0x0f, 0xe0, 0x78, 0x7c, 0x0e, 0x1e, 0x86, 0x31, 0x44, 0x9f, 0x94, 0xb2, 0x69, 0xe4, 0x34, - 0x37, 0xdf, 0x74, 0x6e, 0x24, 0x93, 0x69, 0xca, 0xf0, 0x42, 0x18, 0xc9, 0x65, 0x85, 0x6f, 0x58, - 0x9b, 0xba, 0x9a, 0x97, 0xd0, 0x62, 0xc1, 0xac, 0x90, 0xd2, 0x42, 0x31, 0x2d, 0x7c, 0xc0, 0x2b, - 0xa1, 0x0b, 0xc8, 0x50, 0xf9, 0xbb, 0xa5, 0x7d, 0x4b, 0x87, 0xe8, 0x2f, 0xd0, 0xbb, 0x82, 0xfd, - 0x16, 0x10, 0x19, 0x1f, 0x93, 0x96, 0xb8, 0x62, 0x32, 0xd6, 0x75, 0xbb, 0x2d, 0x8c, 0x48, 0x20, - 0xcc, 0xa6, 0xef, 0x97, 0x6d, 0x51, 0xe5, 0x73, 0x65, 0x9c, 0xdd, 0x79, 0x7c, 0xee, 0x7b, 0xc3, - 0xb7, 0xbf, 0xe4, 0x8f, 0x24, 0xf3, 0x6a, 0x48, 0x7a, 0x33, 0x35, 0x97, 0x37, 0x57, 0x7f, 0x5e, - 0x61, 0x75, 0x1c, 0x3e, 0xdb, 0x57, 0xc4, 0x85, 0x0d, 0xc3, 0xe1, 0x87, 0x81, 0xc6, 0x7d, 0x07, - 0x91, 0x44, 0x9f, 0x94, 0xb2, 0x39, 0xa5, 0xdc, 0x69, 0xd4, 0x53, 0xa1, 0xf2, 0xb1, 0x90, 0x83, - 0xe6, 0x47, 0x9c, 0xb0, 0x39, 0x1c, 0xa0, 0x8e, 0xd1, 0x26, 0xbe, 0xaa, 0x8e, 0xab, 0xad, 0x5b, - 0x71, 0x66, 0xc4, 0xf1, 0xd4, 0x0b, 0x50, 0x92, 0xb0, 0xd3, 0x44, 0xe3, 0x56, 0x3f, 0xb0, 0x84, - 0xc8, 0xdf, 0x80, 0xf9, 0x66, 0xd9, 0x19, 0x17, 0xe0, 0xe2, 0x12, 0x84, 0x1c, 0xcf, 0x57, 0xa9, - 0x56, 0x79, 0x70, 0x7f, 0xb9, 0xa7, 0x58, 0x53, 0xea, 0x65, 0xe9, 0x91, 0x5c, 0x3b, 0x1c, 0xe7, - 0xa4, 0xff, 0xac, 0xa9, 0xfb, 0xde, 0xf9, 0xfc, 0x3c, 0x45, 0x36, 0x2d, 0x7c, 0xdc, 0x83, 0x69, - 0x12, 0x6a, 0xb1, 0x6a, 0x29, 0x02, 0x12, 0xd0, 0x00, 0x93, 0x93, 0xe8, 0x90, 0xbb, 0x5c, 0xa5, - 0x8c, 0xf6, 0x08, 0x7c, 0x37, 0x86, 0x3e, 0x07, 0x98, 0x44, 0x69, 0x6e, 0xb2, 0x39, 0xc6, 0x3c, - 0x69, 0xd4, 0x53, 0xa1, 0xf2, 0xa1, 0xf1, 0xaa, 0xf4, 0x4c, 0x39, 0xb2, 0xc2, 0xa4, 0xa6, 0xf1, - 0xcf, 0x85, 0xb4, 0xd3, 0xc9, 0xc7, 0xa3, 0x33, 0xf3, 0x5a, 0x04, 0xbb, 0x04, 0x8f, 0x8f, 0x80, - 0x7a, 0x24, 0x12, 0x88, 0x2b, 0xb9, 0x56, 0xbe, 0x39, 0x92, 0xf1, 0xb4, 0x80, 0x4b, 0xc1, 0xb3, - 0x7b, 0x23, 0xfc, 0x48, 0x7e, 0x7f, 0xea, 0x3d, 0x49, 0xc4, 0x32, 0x04, 0x69, 0x36, 0xed, 0x68, - 0x03, 0x75, 0x5d, 0x79, 0xc1, 0xcc, 0xa3, 0x21, 0x3d, 0x84, 0xd4, 0x23, 0x16, 0x48, 0x67, 0x80, - 0x3c, 0x76, 0x4e, 0x57, 0x39, 0x4f, 0x1a, 0xbf, 0x6e, 0xf7, 0x2a, 0xac, 0xb9, 0x3d, 0x1c, 0xf1, - 0x72, 0x6b, 0xff, 0x78, 0xec, 0xff, 0x15, 0xe1, 0x35, 0x44, 0x5e, 0x07, 0xc1, 0xfc, 0x61, 0xf8, - 0x98, 0x44, 0x69, 0x6e, 0xb2, 0x39, 0xc6, 0x3c, 0x37, 0xe7, 0x3d, 0xc9, 0x8e, 0xff, 0xc4, 0x6e, - 0x98, 0x6d, 0x0c, 0xe7, 0x5b, 0xa2, 0x9d, 0x70, 0xf9, 0x49, 0x65, 0x08, 0x3c, 0x9d, 0x4c, 0xbe, - 0xab, 0x06, 0x7f, 0x44, 0xcd, 0x5c, 0x3c, 0x0f, 0x45, 0x11, 0x44, 0xa6, 0x5c, 0x39, 0x10, 0xe4, - 0x5e, 0xaa, 0xff, 0x83, 0x97, 0xbb, 0x26, 0x41, 0x9f, 0x65, 0xc0, 0x70, 0x59, 0xea, 0x44, 0xd1, - 0x9d, 0x60, 0x8b, 0x95, 0xdc, 0xee, 0xa5, 0x97, 0x57, 0xb9, 0xc8, 0x53, 0x6b, 0x50, 0x93, 0xef, - 0x46, 0x29, 0xd1, 0x37, 0x23, 0xc8, 0xb8, 0x72, 0x83, 0xd8, 0x10, 0xde, 0xe4, 0x5d, 0xde, 0xc5, - 0xb0, 0x95, 0x28, 0x52, 0xe5, 0x78, 0xea, 0x33, 0xff, 0x45, 0x02, 0x67, 0x5e, 0x1d, 0x80, 0x1e, - 0x2a, 0x64, 0xe0, 0x17, 0x1f, 0x0d, 0x81, 0xf5, 0x98, 0x44, 0x69, 0x6e, 0xb2, 0x39, 0xb6, 0x34, - 0xaf, 0xdd, 0x5d, 0x72, 0x51, 0x9c, 0xbc, 0x0c, 0xcc, 0x10, 0xab, 0x8c, 0xc2, 0x7d, 0x59, 0x42, - 0x30, 0xe9, 0x9d, 0x1a, 0x5c, 0x84, 0x23, 0x4e, 0x22, 0xd6, 0x5f, 0x48, 0x7b, 0x28, 0x9c, 0x30, - 0x8e, 0x91, 0x70, 0xc9, 0x7a, 0x47, 0x8e, 0x19, 0xee, 0xbf, 0x26, 0xbe, 0x14, 0x32, 0xda, 0x90, - 0xa9, 0xb1, 0x01, 0x31, 0x7b, 0x70, 0x6f, 0x7a, 0x92, 0xb9, 0x20, 0x11, 0x61, 0x36, 0xf1, 0x68, - 0x3b, 0x55, 0x89, 0xbc, 0x57, 0x9b, 0xa1, 0x25, 0xf6, 0x2a, 0x0d, 0xbf, 0x06, 0x3c, 0x04, 0x81, - 0x70, 0xc1, 0xc2, 0xc1, 0x75, 0x90, 0xfe, 0x28, 0x0e, 0xf3, 0x46, 0x00, 0xd2, 0xc0, 0xb0, 0x25, - 0xa9, 0x95, 0xba, 0x98, 0x32, 0xc6, 0x64, 0xa8, 0x42, 0xac, 0x6c, 0x1e, 0x6c, 0x3c, 0x91, 0xf8, - 0x98, 0x44, 0xa5, 0x6e, 0xb2, 0x39, 0xf6, 0x2c, 0xaf, 0xdd, 0x5d, 0x70, 0x12, 0x34, 0x02, 0x21, - 0x2e, 0x2a, 0xa5, 0x29, 0x16, 0x21, 0x2b, 0x6b, 0xa6, 0x00, 0x62, 0x1a, 0x85, 0x11, 0xfe, 0x27, - 0x96, 0xc0, 0xe3, 0xca, 0xf9, 0x46, 0xdf, 0x0f, 0x6e, 0x7b, 0x04, 0xb5, 0x60, 0x0b, 0xd7, 0x23, - 0x62, 0x79, 0xd6, 0x0c, 0x1a, 0xd2, 0xed, 0x99, 0xc4, 0x11, 0x6a, 0x80, 0x3a, 0x1f, 0x6c, 0x4a, - 0x47, 0xa4, 0xc2, 0x1c, 0x5b, 0x94, 0x64, 0x8c, 0x26, 0x04, 0xfb, 0xfd, 0x16, 0xc5, 0x1f, 0x97, - 0x58, 0xcd, 0x2c, 0xec, 0xa5, 0xe7, 0x78, 0x58, 0xa7, 0x88, 0x7e, 0xb5, 0xaa, 0x2c, 0xbf, 0x1d, - 0x7d, 0xf1, 0xe0, 0x41, 0x8e, 0x4d, 0x3a, 0x58, 0x34, 0x6e, 0x28, 0x41, 0x75, 0x15, 0xeb, 0xc8, - 0xf2, 0x43, 0xc7, 0x21, 0x6d, 0xe3, 0x9e, 0x07, 0x78, 0x44, 0xa5, 0x6e, 0xb2, 0x39, 0xc6, 0x3c, - 0xb0, 0xdc, 0x12, 0xcc, 0x4c, 0xcc, 0x48, 0xed, 0x80, 0x64, 0xa3, 0x51, 0xff, 0x3d, 0xf0, 0x22, - 0xd1, 0x9b, 0xd6, 0xd3, 0x68, 0x90, 0x43, 0x3f, 0x1b, 0x71, 0x66, 0xd9, 0xa2, 0xbf, 0xc9, 0xe5, - 0xeb, 0x73, 0x46, 0xc1, 0xad, 0x24, 0xfd, 0xf3, 0x39, 0x11, 0x8f, 0xaa, 0x4c, 0x5e, 0xb6, 0x4e, - 0x11, 0xa1, 0xb4, 0xdb, 0x1a, 0xe4, 0xa5, 0xe5, 0xc5, 0xb7, 0xec, 0x9c, 0x1d, 0x17, 0xb7, 0x75, - 0xc5, 0x7e, 0x7d, 0xf1, 0x28, 0xa2, 0x14, 0x9f, 0x10, 0xde, 0x56, 0xb4, 0xe1, 0x83, 0xef, 0x57, - 0x87, 0xda, 0x25, 0x28, 0x35, 0x38, 0x90, 0x50, 0xa4, 0xb5, 0x5d, 0x7d, 0x94, 0xc3, 0xda, 0x73, - 0xdb, 0xe7, 0x28, 0x29, 0xbb, 0x59, 0x5c, 0xb5, 0x83, 0x72, 0x3b, 0x45, 0xc2, 0x56, 0xc7, 0x79, - 0x98, 0x44, 0xa5, 0x6e, 0xb2, 0x39, 0xc6, 0x1c, 0xb0, 0xdc, 0x62, 0x63, 0x93, 0x7b, 0xc3, 0x48, - 0xe7, 0x95, 0x2c, 0x81, 0x44, 0x14, 0xd3, 0xad, 0xf5, 0x39, 0x80, 0x5e, 0xee, 0x45, 0xc0, 0xbd, - 0x79, 0xc3, 0x00, 0x4b, 0x0a, 0xe2, 0x40, 0x24, 0xbc, 0xc5, 0xf6, 0x61, 0x16, 0xa6, 0x76, 0xa2, - 0x59, 0xaa, 0x1c, 0xe5, 0x07, 0x22, 0x89, 0x27, 0xce, 0x4a, 0x3d, 0xd3, 0x95, 0x29, 0x8f, 0xd4, - 0xc9, 0xa4, 0x9c, 0xfd, 0x00, 0x8f, 0x51, 0x80, 0x2a, 0xc8, 0xaa, 0xed, 0xf5, 0xb1, 0x54, 0xf3, - 0x42, 0xd4, 0x2b, 0xa0, 0x34, 0xd0, 0x01, 0x44, 0xf8, 0x28, 0x78, 0x1f, 0x77, 0xf4, 0xf1, 0x9a, - 0xc7, 0x75, 0x42, 0xbd, 0x06, 0xf8, 0x0c, 0xba, 0x99, 0xc7, 0xd4, 0xa9, 0xdd, 0x9b, 0xb6, 0xd0, - 0x86, 0x02, 0x31, 0xe3, 0x18, 0x7c, 0x00, 0xfc, 0x78, 0x44, 0xa5, 0x6e, 0xb2, 0x39, 0xc6, 0x24, - 0x69, 0xd5, 0x7e, 0xf4, 0x56, 0xff, 0xd6, 0xb8, 0x39, 0x42, 0xb8, 0xea, 0x1e, 0x44, 0x7d, 0xdb, - 0x3a, 0xb6, 0x27, 0xe9, 0xc5, 0xe9, 0xce, 0x0b, 0x27, 0x53, 0x53, 0x03, 0x18, 0x9b, 0x40, 0xa5, - 0xd1, 0x72, 0x39, 0x94, 0x3c, 0xb2, 0x50, 0x91, 0x4f, 0x84, 0xa1, 0xa4, 0x88, 0x6e, 0x7b, 0x48, - 0x4a, 0x99, 0x55, 0x38, 0xab, 0x70, 0x69, 0x53, 0x6f, 0xe9, 0x2d, 0xec, 0x15, 0xc8, 0x2f, 0xf6, - 0x1f, 0x48, 0x7d, 0xdf, 0x34, 0x16, 0xc3, 0x6f, 0x06, 0x64, 0x26, 0x9c, 0x20, 0xd0, 0x1c, 0xb0, - 0x6c, 0x57, 0x24, 0xc7, 0xa9, 0x5d, 0xea, 0x8e, 0xd1, 0xeb, 0x56, 0xfc, 0x10, 0x4d, 0xbd, 0xa4, - 0xe4, 0xa0, 0xac, 0xe2, 0xcc, 0x79, 0xb0, 0x7f, 0xae, 0x41, 0xcf, 0x9a, 0x1e, 0x61, 0x81, 0xfc, - 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xd5, 0x34, 0xae, 0xec, 0x1e, 0xe4, 0xe0, 0xd5, 0xb6, 0x00, - 0x00, 0xa5, 0x9f, 0x96, 0xcd, 0x72, 0xe7, 0x6b, 0xbd, 0x30, 0xbc, 0x87, 0x98, 0xed, 0xa5, 0x60, - 0x96, 0x46, 0x0e, 0xdb, 0xda, 0x89, 0x3e, 0x73, 0xed, 0xb8, 0x31, 0x33, 0x96, 0xfc, 0x5f, 0xe5, - 0x7f, 0xe9, 0xad, 0x25, 0x07, 0x2c, 0xec, 0x4c, 0xc4, 0x0f, 0x9c, 0x76, 0xe8, 0xaf, 0x0b, 0x62, - 0x23, 0xd7, 0xb2, 0x23, 0xaf, 0x62, 0x5c, 0xb4, 0xdd, 0x13, 0x51, 0x25, 0x86, 0x0c, 0xec, 0x91, - 0x22, 0x56, 0xaf, 0x7b, 0xe0, 0x30, 0x4c, 0x66, 0x14, 0x01, 0xfa, 0x42, 0x04, 0x4b, 0x91, 0xf9, - 0x65, 0xf4, 0x63, 0xd8, 0x58, 0xfb, 0xbb, 0xbe, 0x96, 0xe2, 0xdc, 0x0a, 0x9e, 0x43, 0xba, 0xd2, - 0xe4, 0xa9, 0x23, 0x01, 0xe7, 0x33, 0xb1, 0xe4, 0x78, 0x44, 0xa5, 0x6e, 0xb2, 0x39, 0xc6, 0x34, - 0x69, 0xd5, 0x7e, 0xef, 0x47, 0x1d, 0x1a, 0x06, 0x63, 0xd2, 0xd7, 0x56, 0x12, 0x77, 0x40, 0x88, - 0x00, 0xfd, 0x53, 0xa5, 0x52, 0x98, 0xd9, 0xf7, 0xd4, 0x97, 0xa1, 0x06, 0x7e, 0xc6, 0x9d, 0x5f, - 0x2c, 0x45, 0x27, 0x10, 0xee, 0x32, 0x36, 0xeb, 0x5e, 0x8a, 0x42, 0x23, 0x8b, 0x9c, 0x4b, 0x5d, - 0x14, 0x0a, 0x16, 0x2c, 0xfa, 0x6d, 0x9a, 0x64, 0xe8, 0xc2, 0xeb, 0x23, 0x51, 0x74, 0xe2, 0xbe, - 0x86, 0x3e, 0x9e, 0x4e, 0x3d, 0xf4, 0x10, 0xea, 0xb8, 0xc8, 0x0f, 0x35, 0xee, 0xba, 0x1f, 0x85, - 0xed, 0x2b, 0x5c, 0xe0, 0x65, 0xfc, 0x7f, 0xe3, 0xb5, 0x4c, 0xa2, 0x16, 0x68, 0xfc, 0xf0, 0x41, - 0x22, 0x2a, 0xea, 0x8e, 0x3f, 0xb2, 0x73, 0x66, 0x9e, 0xfe, 0x60, 0x66, 0x29, 0x86, 0x81, 0xf8, - 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xb6, 0x3c, 0x66, 0x3c, 0x02, 0x2d, 0xef, 0xe3, 0x94, 0xd8, - 0x80, 0x92, 0x4a, 0x95, 0x73, 0x76, 0x38, 0xc1, 0x72, 0x0b, 0xdd, 0xdd, 0x56, 0x98, 0x8c, 0xc6, - 0x13, 0x03, 0xdd, 0x3a, 0xd6, 0x0f, 0x63, 0xbb, 0xde, 0x18, 0x3a, 0x07, 0x21, 0xf8, 0x9d, 0xe8, - 0xb6, 0xca, 0x75, 0x31, 0x2e, 0x28, 0x6b, 0x1b, 0xd9, 0x19, 0x49, 0xe6, 0xf0, 0x1c, 0x54, 0xa8, - 0x10, 0xeb, 0xc2, 0x27, 0x50, 0x22, 0x03, 0x7a, 0x64, 0xbd, 0xf9, 0x0e, 0xdf, 0x80, 0xec, 0xd4, - 0xa3, 0xac, 0x4c, 0x0f, 0xb6, 0xc0, 0xe4, 0xb0, 0x8b, 0x74, 0x6c, 0xf0, 0x14, 0x5a, 0xa7, 0x55, - 0xb6, 0x2e, 0xdd, 0xdb, 0x0e, 0x29, 0xed, 0x6f, 0x93, 0x9c, 0x51, 0x14, 0x41, 0x34, 0xa8, 0x4f, - 0x62, 0x0e, 0x31, 0xb1, 0x71, 0x64, 0x87, 0xf0, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa5, 0xfc, - 0xb0, 0xdc, 0x62, 0x57, 0xd3, 0x36, 0xf2, 0xac, 0x75, 0xf7, 0xe4, 0x7e, 0xad, 0xe3, 0x52, 0x9d, - 0x36, 0x68, 0xd7, 0xde, 0xa5, 0xd5, 0x2e, 0xbd, 0x2a, 0x54, 0x3c, 0xe7, 0x64, 0xec, 0x4f, 0xb8, - 0x89, 0xba, 0x8e, 0xf0, 0x3d, 0x8f, 0x1c, 0xc5, 0x36, 0xec, 0x31, 0x31, 0x1c, 0x18, 0x72, 0x55, - 0xb0, 0x48, 0x18, 0x4a, 0xef, 0xb9, 0xe6, 0xc9, 0xdc, 0xe9, 0x60, 0x61, 0x64, 0x90, 0x85, 0x22, - 0x55, 0x9f, 0x06, 0x3c, 0xd1, 0xde, 0x8f, 0x2a, 0xa2, 0xbf, 0x80, 0x84, 0x58, 0x33, 0x0f, 0x28, - 0x57, 0x88, 0x40, 0x90, 0x88, 0x22, 0xf2, 0xf8, 0xfc, 0x27, 0x10, 0x78, 0x52, 0x79, 0xb5, 0x27, - 0x9a, 0x79, 0xcb, 0x0e, 0x23, 0xfe, 0x8f, 0x80, 0x53, 0x20, 0x61, 0xf3, 0xc1, 0x9d, 0xfe, 0x07, - 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xd6, 0x2c, 0x69, 0xd4, 0x6a, 0x42, 0x75, 0xb2, 0x56, 0x45, - 0xdb, 0x97, 0x98, 0x7c, 0xf8, 0x26, 0x81, 0xdd, 0x03, 0x6f, 0xd2, 0x5b, 0x85, 0x92, 0xb5, 0x9c, - 0x5b, 0x60, 0x4d, 0xaf, 0x25, 0x78, 0xce, 0xfd, 0x38, 0xc0, 0xd1, 0xf1, 0x1e, 0x99, 0xa7, 0xb2, - 0xf1, 0xae, 0x19, 0x59, 0x9a, 0xba, 0x97, 0x57, 0xcf, 0x6b, 0xee, 0x95, 0xdf, 0xa5, 0x95, 0xc3, - 0xa3, 0xa5, 0x93, 0xc3, 0x19, 0xd3, 0x48, 0x1a, 0x2a, 0x82, 0xe7, 0x5e, 0xdd, 0xff, 0x66, 0xd6, - 0xc1, 0xae, 0xa2, 0xcf, 0xff, 0x86, 0x08, 0x85, 0x94, 0x41, 0xc5, 0x17, 0xf6, 0xfa, 0x02, 0x3b, - 0x16, 0xe1, 0xa5, 0x38, 0x0d, 0x9c, 0x86, 0xef, 0x05, 0x9b, 0x96, 0x9c, 0x24, 0x07, 0x9c, 0xff, - 0x82, 0xf7, 0x07, 0x13, 0x38, 0xec, 0xf2, 0xda, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa5, 0xe4, - 0x69, 0xd4, 0x53, 0xbf, 0x32, 0xf9, 0xec, 0x78, 0xf3, 0x36, 0xd1, 0xaa, 0xac, 0x07, 0x21, 0xd3, - 0x6c, 0x15, 0x8f, 0xbc, 0x88, 0xa1, 0x7e, 0x52, 0xef, 0xd6, 0xf4, 0x15, 0xf5, 0x35, 0x93, 0xb7, - 0xd8, 0x36, 0x6f, 0xa5, 0xbe, 0xe0, 0x06, 0xf8, 0x9d, 0x49, 0x5a, 0x27, 0x40, 0x03, 0x09, 0xdf, - 0x34, 0x47, 0x3d, 0x32, 0xab, 0x10, 0x19, 0x0c, 0x43, 0x54, 0x2e, 0xda, 0xe5, 0x7b, 0xcd, 0x02, - 0xb8, 0x46, 0x14, 0x10, 0x05, 0xc7, 0x6b, 0xac, 0x48, 0x9d, 0x1c, 0x1f, 0xc4, 0x49, 0x78, 0x0c, - 0x63, 0xbf, 0x0a, 0x4e, 0xcf, 0x04, 0x3c, 0x65, 0x64, 0x7a, 0x89, 0xe6, 0xd3, 0x77, 0xd6, 0x1f, - 0xcf, 0x43, 0x9c, 0xe5, 0x75, 0xde, 0x16, 0x71, 0x37, 0x61, 0x4c, 0xf6, 0x87, 0x2b, 0xfc, 0x07, - 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xd6, 0x2c, 0xaf, 0xdd, 0x8e, 0xee, 0x15, 0xf5, 0x46, 0xb7, - 0xde, 0xd7, 0xa3, 0x50, 0xac, 0x8e, 0xc2, 0x34, 0x02, 0xd2, 0x2a, 0xdd, 0xff, 0xdc, 0xf0, 0xba, - 0x8a, 0x5a, 0x96, 0x77, 0xca, 0x80, 0xa6, 0x60, 0x0a, 0x2a, 0x5b, 0x73, 0x5d, 0x0e, 0xeb, 0x52, - 0x76, 0x6b, 0x67, 0x3b, 0x59, 0x81, 0xc9, 0xfa, 0x8d, 0x82, 0x01, 0x76, 0x2c, 0x29, 0x9a, 0xa6, - 0xbf, 0xd2, 0x9a, 0x8a, 0x0b, 0x0d, 0xfb, 0x29, 0xb9, 0x7b, 0x37, 0x42, 0xa6, 0xe0, 0xbc, 0x13, - 0x45, 0x57, 0x37, 0x60, 0x3f, 0xe0, 0xeb, 0xb5, 0xbf, 0x39, 0x9f, 0x1d, 0xdc, 0x4c, 0xee, 0xea, - 0xb4, 0xb5, 0x1f, 0x80, 0xe6, 0x12, 0xf0, 0x85, 0x54, 0x3d, 0x58, 0x8b, 0x21, 0x8a, 0x8e, 0xdb, - 0xab, 0xf3, 0xf8, 0x26, 0x63, 0x19, 0x61, 0xf8, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xb6, 0x34, - 0xaf, 0xdd, 0x5d, 0x70, 0x77, 0xc6, 0x5b, 0x81, 0x61, 0x35, 0x4d, 0x00, 0x3e, 0x7e, 0x5e, 0x7e, - 0xe4, 0x20, 0x03, 0xc2, 0x6e, 0x06, 0xd4, 0x13, 0x02, 0x05, 0xc9, 0x34, 0xcd, 0x9a, 0x72, 0xaa, - 0x2c, 0x54, 0x83, 0xdc, 0x30, 0x1b, 0xc1, 0xa6, 0x5e, 0xd7, 0x94, 0xae, 0x1a, 0x55, 0xba, 0x28, - 0xa3, 0x28, 0xde, 0xb6, 0x34, 0xa6, 0x34, 0xbb, 0xd1, 0xa1, 0xd2, 0x0d, 0x5f, 0xcd, 0xe2, 0xe8, - 0x5b, 0xb3, 0xe7, 0x07, 0x0b, 0xbf, 0x07, 0xd9, 0x03, 0x10, 0x6b, 0xde, 0x07, 0xbb, 0xc2, 0x30, - 0x5b, 0x34, 0x7f, 0xd6, 0xbe, 0x0e, 0x2f, 0xe9, 0x33, 0xbe, 0x7c, 0x86, 0x1f, 0x5f, 0xae, 0x34, - 0xe0, 0xad, 0x7e, 0xa2, 0x02, 0x7e, 0x10, 0x2f, 0x91, 0x19, 0x94, 0xc3, 0x3c, 0xe6, 0x0f, 0x1e, - 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa5, 0xfc, 0xaf, 0xdd, 0x5d, 0x72, 0x40, 0x99, 0x6f, 0xc2, - 0x1b, 0xde, 0x55, 0x98, 0xc8, 0xd0, 0x3c, 0x25, 0xd4, 0xe3, 0x93, 0x2c, 0x6e, 0x62, 0xaf, 0xb2, - 0xdb, 0xab, 0xd4, 0xaf, 0x14, 0x09, 0x1e, 0x1a, 0xde, 0x12, 0xba, 0xc8, 0x63, 0x9d, 0xa2, 0x67, - 0x75, 0xd8, 0x3e, 0xe6, 0xe2, 0x8c, 0xf7, 0xd2, 0xcd, 0x83, 0x33, 0x09, 0x95, 0xea, 0x42, 0x51, - 0x17, 0xad, 0x45, 0xbe, 0x80, 0xd2, 0x64, 0x18, 0x00, 0x7f, 0x59, 0x56, 0xd6, 0xb8, 0x0d, 0x43, - 0x0a, 0x8e, 0xad, 0xa4, 0x7f, 0x11, 0xc7, 0x8b, 0x90, 0x83, 0x43, 0xed, 0xf1, 0x88, 0x74, 0xd1, - 0x1d, 0x0d, 0x3c, 0xeb, 0xfb, 0x10, 0x0c, 0xed, 0xa0, 0xa5, 0x98, 0xec, 0xa7, 0xdd, 0xab, 0x5c, - 0xd4, 0x63, 0xa2, 0x19, 0x09, 0x4e, 0x7f, 0x03, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc6, 0x3c, - 0x69, 0x22, 0xe8, 0x73, 0x20, 0x58, 0x38, 0x1d, 0xfd, 0x9e, 0xa2, 0xb7, 0x7b, 0x72, 0x36, 0xfa, - 0x26, 0x3e, 0xc4, 0x03, 0xe2, 0x8f, 0x86, 0x5b, 0xdf, 0xa9, 0x39, 0xcb, 0xac, 0xd4, 0x2e, 0xbd, - 0xeb, 0x4b, 0x27, 0x06, 0xf9, 0xff, 0x26, 0x50, 0xe8, 0x4e, 0xeb, 0xae, 0x9f, 0x93, 0x95, 0xf2, - 0x68, 0xb7, 0xba, 0x84, 0x0d, 0x9c, 0xbe, 0x08, 0x7a, 0x70, 0x62, 0x51, 0x22, 0x27, 0x43, 0x23, - 0xd7, 0x8b, 0x2a, 0x7c, 0xac, 0xe0, 0xa4, 0x6e, 0x1f, 0xde, 0x6b, 0x65, 0x8c, 0x7f, 0xfd, 0x87, - 0x36, 0x40, 0xa8, 0xd5, 0xbb, 0x86, 0xed, 0xf3, 0xd8, 0x0c, 0x1d, 0x0b, 0x8b, 0x5a, 0x80, 0xd4, - 0xca, 0xcb, 0x72, 0x52, 0x95, 0xa7, 0xea, 0xa9, 0xe4, 0xec, 0xed, 0x06, 0xd8, 0xcc, 0x3e, 0x07, - 0x79, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xb6, 0x2c, 0xb0, 0xd2, 0xdb, 0xe7, 0x6a, 0xb8, 0xa5, 0x31, - 0x37, 0xee, 0x2f, 0x89, 0x78, 0x18, 0xf9, 0x03, 0xd4, 0xab, 0xfb, 0x14, 0x26, 0xf8, 0xe2, 0x1c, - 0x20, 0x4c, 0x35, 0xe8, 0x8c, 0x56, 0x17, 0xaa, 0xb4, 0x68, 0xda, 0xb9, 0x19, 0x39, 0xd2, 0x13, - 0x8d, 0xa6, 0x21, 0xc4, 0xec, 0xd6, 0xcb, 0xa1, 0xb6, 0xc2, 0x06, 0xc1, 0x96, 0xed, 0x18, 0x46, - 0x09, 0x1e, 0x39, 0x1c, 0xeb, 0x36, 0xa1, 0x99, 0x8a, 0xfd, 0x14, 0x33, 0x80, 0x35, 0x31, 0xf1, - 0x24, 0x85, 0x80, 0x1f, 0x90, 0x84, 0x82, 0xa9, 0x32, 0xc3, 0x01, 0xc1, 0xda, 0x1d, 0x43, 0x8f, - 0xed, 0x8b, 0x3e, 0xe9, 0x57, 0xd8, 0x56, 0x0c, 0xc6, 0x77, 0x7d, 0x4b, 0xd0, 0x83, 0x14, 0xf4, - 0x5a, 0x4a, 0x21, 0x05, 0x86, 0x41, 0xa7, 0xc1, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc5, 0xfc, - 0xae, 0xed, 0x1b, 0x9f, 0x80, 0x9b, 0x46, 0xc9, 0xee, 0xe6, 0xaa, 0x41, 0xa7, 0x40, 0x48, 0xa1, - 0x08, 0x99, 0x82, 0x48, 0x0a, 0xc8, 0x52, 0x66, 0x58, 0x96, 0x70, 0x6e, 0x50, 0xe3, 0x43, 0xa5, - 0x74, 0x31, 0xc7, 0x0c, 0x15, 0x94, 0x74, 0x02, 0xd2, 0x96, 0x3a, 0x15, 0x4a, 0xd3, 0x28, 0x07, - 0x6a, 0x8d, 0x97, 0x21, 0x33, 0xbf, 0xe8, 0x80, 0xaf, 0xec, 0x35, 0xb4, 0x2b, 0xba, 0xad, 0xec, - 0xc8, 0xe4, 0x80, 0x3e, 0x90, 0x19, 0x02, 0x5d, 0x48, 0x47, 0x90, 0xf3, 0xbe, 0x0f, 0x7f, 0xde, - 0x13, 0xbd, 0x72, 0x97, 0xf0, 0x87, 0xbc, 0x4f, 0x1d, 0x7a, 0xa8, 0xd2, 0x06, 0x19, 0xbb, 0xe4, - 0xbe, 0x5d, 0x4d, 0x24, 0x54, 0xaa, 0xa1, 0x4b, 0x27, 0x2f, 0x1b, 0x4b, 0x7c, 0x26, 0x59, 0x58, - 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc6, 0x34, 0xaf, 0xdd, 0x5d, 0x57, 0xcc, 0xa3, 0x86, 0x1d, - 0x6d, 0xdd, 0x40, 0xe6, 0x3a, 0x6c, 0xca, 0x2d, 0xb9, 0xbd, 0xaf, 0xf4, 0x89, 0x12, 0x83, 0x82, - 0xcd, 0x72, 0x04, 0x91, 0xdd, 0xe4, 0x9c, 0xdd, 0x5f, 0x2d, 0x77, 0xf9, 0x7c, 0xa7, 0x5c, 0x9a, - 0xf4, 0x20, 0x33, 0x6b, 0x59, 0x3d, 0xe1, 0xb7, 0x91, 0xa1, 0xac, 0xc3, 0xad, 0x4c, 0xea, 0xec, - 0x6a, 0x06, 0xe4, 0xfa, 0xf2, 0x9a, 0x33, 0xea, 0x18, 0x12, 0xa0, 0xdc, 0xfc, 0x37, 0xd9, 0x4c, - 0xaa, 0x11, 0xe7, 0x03, 0x39, 0x72, 0xbf, 0x1c, 0xca, 0xd3, 0x5f, 0x1b, 0x02, 0xff, 0xa7, 0x67, - 0x7c, 0x14, 0x4f, 0xed, 0x54, 0x77, 0x73, 0x2c, 0x48, 0x48, 0x0f, 0xa6, 0x47, 0x87, 0x08, 0x1f, - 0x41, 0xb2, 0x4f, 0xfc, 0x39, 0x0f, 0x77, 0xc1, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa6, 0x3c, - 0x69, 0xd4, 0x6a, 0x42, 0x63, 0xb5, 0x97, 0x25, 0xe0, 0xa6, 0x00, 0x93, 0xdc, 0x9c, 0x68, 0xb5, - 0x58, 0x2e, 0x3c, 0x24, 0x05, 0xf7, 0xa7, 0x33, 0xc6, 0x48, 0x94, 0x63, 0xdd, 0x8e, 0xd1, 0xe2, - 0x14, 0x7e, 0x33, 0xfc, 0xec, 0x43, 0x1b, 0x78, 0x02, 0x1b, 0x5a, 0x78, 0xae, 0x2e, 0x2d, 0x95, - 0x7f, 0x41, 0x2f, 0x90, 0x46, 0x57, 0xc0, 0xf0, 0xd3, 0xde, 0x1d, 0xa9, 0x86, 0x4d, 0x5d, 0x76, - 0x58, 0x44, 0x76, 0x1f, 0x47, 0x26, 0x38, 0xf8, 0xc4, 0x9a, 0x02, 0xb7, 0x1c, 0xfc, 0x39, 0xe6, - 0x72, 0x94, 0x78, 0x70, 0x2e, 0x51, 0xfc, 0xf4, 0xba, 0x5c, 0x17, 0xcf, 0x14, 0xc0, 0x2d, 0x7b, - 0xb6, 0x5c, 0x49, 0x72, 0x92, 0xdc, 0x83, 0xa7, 0x90, 0x3b, 0x96, 0xc9, 0x07, 0x8e, 0x7c, 0x63, - 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa6, 0x34, 0xaf, 0xdd, 0x72, 0x00, 0xd7, 0xcf, 0x22, 0x79, - 0xce, 0xce, 0x21, 0xcf, 0x85, 0xd9, 0x2a, 0xd8, 0xd4, 0x1d, 0x00, 0x49, 0xae, 0x4e, 0x01, 0x08, - 0xf8, 0x7e, 0xc2, 0x91, 0x69, 0x68, 0x1d, 0x04, 0xf9, 0x06, 0x30, 0xf3, 0x15, 0x53, 0xd6, 0x08, - 0xf3, 0x0f, 0x96, 0xac, 0x17, 0x9d, 0x42, 0xc5, 0xdb, 0xa2, 0x15, 0xbb, 0x2e, 0xd1, 0x6e, 0x9e, - 0xed, 0x97, 0xd1, 0xb0, 0x2e, 0x89, 0xa8, 0x8e, 0x89, 0x27, 0x2c, 0xfd, 0x9a, 0x22, 0x84, 0x21, - 0x91, 0x6b, 0x64, 0x96, 0x00, 0xfe, 0x5d, 0x07, 0x0b, 0xa2, 0x7e, 0xab, 0xd0, 0xee, 0xeb, 0xb7, - 0x8e, 0xbb, 0x85, 0x78, 0x9f, 0xa0, 0x5e, 0x6c, 0x62, 0x47, 0x5d, 0xe1, 0x65, 0x0e, 0x0e, 0xc7, - 0x1d, 0x00, 0x75, 0x9b, 0x4a, 0x42, 0x5f, 0x01, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc5, 0xbc, - 0xb0, 0xdc, 0x62, 0x56, 0xd4, 0x50, 0x19, 0x30, 0x62, 0x00, 0x93, 0x48, 0x23, 0xd8, 0x8a, 0x44, - 0xe5, 0xdb, 0x09, 0x9c, 0x08, 0x8d, 0x74, 0xbf, 0x33, 0x1a, 0x33, 0x3e, 0xe3, 0xc0, 0x4c, 0x79, - 0x28, 0x9c, 0x4a, 0x19, 0x27, 0x97, 0x7f, 0x42, 0x74, 0x3f, 0xa5, 0x7c, 0xe0, 0x3e, 0xf4, 0x39, - 0x22, 0xa0, 0x05, 0x2e, 0x0a, 0x83, 0xa0, 0x55, 0x47, 0xc2, 0xed, 0xb1, 0x14, 0x20, 0x5f, 0xff, - 0x7a, 0x32, 0x19, 0x50, 0xdb, 0x16, 0x80, 0x7d, 0x1f, 0x6a, 0x9b, 0xc2, 0x8e, 0xfc, 0x70, 0x40, - 0x1a, 0x91, 0xb0, 0x87, 0xad, 0x8b, 0xb7, 0x8e, 0x44, 0xad, 0x0d, 0x70, 0x7b, 0x7a, 0x40, 0xae, - 0x15, 0x3f, 0x73, 0x02, 0xe0, 0xbe, 0x9f, 0xcf, 0x6d, 0xbf, 0x4a, 0x3a, 0x0c, 0x92, 0x76, 0x1e, - 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xb6, 0x3c, 0x69, 0xd4, 0x53, 0xbd, 0x32, 0xc2, 0x82, 0x19, - 0xbf, 0x3c, 0x5c, 0x7a, 0xac, 0x01, 0xfc, 0x94, 0x76, 0xf9, 0x6b, 0x28, 0x39, 0x72, 0xce, 0x1c, - 0x1a, 0x3a, 0x81, 0x04, 0xc8, 0x07, 0x55, 0xca, 0x05, 0x2c, 0x0b, 0xb8, 0x64, 0x65, 0xf5, 0x38, - 0xa7, 0x01, 0x29, 0xd5, 0x6a, 0x00, 0xef, 0x4a, 0xcf, 0x97, 0x8c, 0x1b, 0xd5, 0x27, 0x32, 0x9a, - 0xf3, 0x93, 0x58, 0x30, 0x5c, 0x7e, 0xfb, 0xed, 0x58, 0x6e, 0x8a, 0x96, 0xd0, 0xc6, 0x72, 0x01, - 0xc3, 0x8a, 0x5a, 0x69, 0x19, 0x01, 0xe5, 0xa7, 0xfc, 0x1e, 0x78, 0x3f, 0x98, 0xec, 0xae, 0xe3, - 0x9a, 0x88, 0x1a, 0xea, 0x9e, 0xda, 0x15, 0xf6, 0x85, 0x6c, 0x04, 0x94, 0x57, 0x8e, 0xd7, 0x3f, - 0xca, 0x5c, 0x39, 0xde, 0xe0, 0x63, 0xbc, 0x07, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc6, 0x2c, - 0x69, 0xd4, 0x8a, 0x58, 0x8e, 0xc0, 0x35, 0x85, 0x61, 0x67, 0xd5, 0x84, 0x18, 0x61, 0xee, 0xc4, - 0xc5, 0x01, 0xe4, 0xca, 0xbb, 0xea, 0xa2, 0x35, 0x61, 0xbb, 0x6b, 0x86, 0x9c, 0x9f, 0xba, 0x0f, - 0x85, 0x76, 0xe5, 0x87, 0x82, 0x79, 0xf5, 0x53, 0x72, 0x58, 0x77, 0x5c, 0xb9, 0x81, 0x0a, 0xe3, - 0xbe, 0xae, 0xd5, 0x6b, 0xe8, 0x4d, 0xdb, 0x08, 0xf6, 0x94, 0xed, 0x5a, 0xe9, 0x55, 0x2d, 0x0f, - 0x54, 0xcd, 0x6f, 0x9f, 0xaa, 0x98, 0x47, 0x84, 0xfb, 0xb8, 0xd9, 0x99, 0x08, 0x0f, 0xe1, 0x1f, - 0x35, 0xad, 0xf7, 0x64, 0x04, 0xf2, 0xb6, 0x5d, 0x90, 0x62, 0x6f, 0xee, 0x7e, 0x62, 0x89, 0xfc, - 0x4e, 0xef, 0x82, 0x8f, 0x03, 0x5a, 0x58, 0x28, 0x22, 0x0d, 0xa3, 0xcc, 0x23, 0xc6, 0x3c, 0x0f, - 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xc5, 0xd4, 0x69, 0xd4, 0x53, 0x87, 0x0f, 0xf2, 0x3d, 0xef, - 0xd0, 0x40, 0x99, 0x3c, 0xe2, 0xcc, 0x21, 0x07, 0x34, 0x09, 0x82, 0x32, 0x55, 0x25, 0xd8, 0xe5, - 0xc8, 0xc4, 0x4f, 0x97, 0x27, 0xd0, 0x14, 0x1c, 0x54, 0x88, 0x92, 0xa1, 0x2c, 0xc6, 0xd6, 0xf3, - 0xe3, 0x18, 0x39, 0xa8, 0x79, 0x9f, 0x85, 0x36, 0xb1, 0xa2, 0x66, 0xf2, 0x35, 0xf0, 0xb1, 0x05, - 0x4e, 0xcf, 0x61, 0x4f, 0x7f, 0x77, 0xe8, 0xf5, 0x74, 0xd9, 0x1f, 0x75, 0x7e, 0x12, 0x8e, 0xf7, - 0xd5, 0x65, 0x34, 0xd4, 0x7e, 0x27, 0xbc, 0x6f, 0xe2, 0xb2, 0xf5, 0x2a, 0x7c, 0x36, 0xb0, 0x46, - 0x74, 0x8d, 0x03, 0x3e, 0x50, 0x6b, 0x2e, 0xed, 0xa6, 0xa6, 0x90, 0xee, 0x6b, 0xac, 0xe1, 0x30, - 0x72, 0x6b, 0xff, 0x04, 0xda, 0x9e, 0x38, 0x3e, 0x99, 0x23, 0x32, 0x8e, 0xb2, 0x39, 0xa6, 0x3c, - 0xb0, 0xdc, 0x62, 0x6f, 0xa5, 0x3a, 0x56, 0xe6, 0x06, 0xa8, 0x75, 0x42, 0x00, 0x27, 0x19, 0xf9, - 0xb6, 0xf4, 0x19, 0x6e, 0xb3, 0x73, 0x5b, 0x69, 0x18, 0xc3, 0x23, 0x2d, 0x6c, 0xf2, 0x40, 0x80, - 0xef, 0x26, 0xe6, 0x53, 0xfd, 0xce, 0xbb, 0x47, 0xe5, 0xda, 0x38, 0x82, 0xc0, 0x19, 0x69, 0x0b, - 0xa2, 0xcc, 0x9a, 0x6a, 0x38, 0xb9, 0x18, 0xab, 0x9b, 0xd9, 0x5e, 0x19, 0xec, 0x35, 0x01, 0x9c, - 0x4b, 0x55, 0x2d, 0xec, 0xaa, 0x84, 0x98, 0x2a, 0xe6, 0xb8, 0x03, 0x8e, 0xd9, 0xe5, 0x1b, 0x92, - 0xec, 0x43, 0xf6, 0x50, 0xbf, 0x7f, 0xe9, 0xee, 0x9b, 0x0a, 0x36, 0x68, 0xd4, 0xda, 0xd4, 0x69, - 0x22, 0x56, 0xdb, 0x6c, 0xd7, 0x09, 0x85, 0x10, 0x01, 0xaf, 0xf0, 0x63, 0xc3, 0xe1, 0x9f, 0x07, - 0x9b, 0xc5, 0x37, 0xee, 0xb2, 0x39, 0xc5, 0xe4, 0x00, 0xc0, 0x5f, 0xba, 0x85, 0x0b, 0x4f, 0x32, - 0x77, 0xe0, 0x1b, 0xc9, 0xdf, 0x64, 0x30, 0x0c, 0x39, 0x0f, 0xdd, 0xce, 0x93, 0xfc, 0x85, 0xb9, - 0x62, 0xc4, 0x1b, 0x32, 0x49, 0x0e, 0x04, 0x6d, 0x42, 0x78, 0xfb, 0x7a, 0x3d, 0x7b, 0x26, 0x17, - 0x12, 0xab, 0x24, 0x49, 0x7f, 0xbd, 0xf5, 0x32, 0xa2, 0x24, 0xd7, 0x1e, 0x6f, 0xe0, 0xc2, 0xda, - 0x85, 0xdc, 0x78, 0x1a, 0xf2, 0x76, 0xea, 0x90, 0xa1, 0x32, 0x6d, 0x72, 0x10, 0x2b, 0x20, 0x6c, - 0x1b, 0x91, 0xcf, 0x38, 0x3e, 0x0f, 0x87, 0x86, 0x67, 0xb1, 0xc2, 0xe8, 0xb6, 0x78, 0xe8, 0x36, - 0x1a, 0x2e, 0xa3, 0xb9, 0xdb, 0xe9, 0x02, 0xee, 0x8d, 0xaa, 0xa1, 0x72, 0xbc, 0xb1, 0x32, 0x03, - 0xe0, 0x7e, 0x07, 0xf0, 0x3f, 0x01, 0xe5, 0x83, 0x3d, 0xe2, 0x9b, 0xf7, 0x59, 0x0a, 0x25, 0xca, - 0x37, 0xc7, 0xc2, 0xa2, 0x56, 0x44, 0xb6, 0x00, 0x00, 0x1a, 0x32, 0xe9, 0xbc, 0x47, 0xbe, 0x1c, - 0x9f, 0x82, 0xf7, 0xda, 0xa5, 0x58, 0xa9, 0x04, 0x3c, 0x68, 0xed, 0x36, 0x07, 0x81, 0xe4, 0xc1, - 0x33, 0xbe, 0x92, 0x8b, 0x82, 0xe2, 0x48, 0xc7, 0x44, 0xf2, 0x0f, 0x25, 0xb1, 0x2d, 0xde, 0xbe, - 0xc1, 0x73, 0x0c, 0xb4, 0x8e, 0xe3, 0xcc, 0x70, 0x91, 0xfc, 0xc6, 0x35, 0x94, 0xb3, 0x5c, 0x4b, - 0xd3, 0x99, 0x5b, 0x44, 0xed, 0xf2, 0x94, 0x7f, 0x7c, 0x58, 0x63, 0x1b, 0x93, 0x9e, 0x3c, 0x38, - 0xf8, 0x16, 0x70, 0x29, 0xab, 0xba, 0xfb, 0x2d, 0x5b, 0xa8, 0x10, 0x62, 0xe9, 0xe6, 0x8c, 0xe2, - 0xc0, 0xe8, 0x56, 0xb0, 0x13, 0xc7, 0x73, 0x38, 0x20, 0xf0, 0xd3, 0x67, 0x1c, 0xf0, 0xf8, 0x43, - 0xcd, 0xe2, 0x9b, 0xf7, 0x59, 0x1a, 0x06, 0x32, 0x37, 0xca, 0x74, 0x3f, 0xcb, 0x5e, 0xc6, 0xaa, - 0x00, 0x01, 0xa0, 0xea, 0xed, 0x68, 0x7c, 0x8c, 0x51, 0x4d, 0x94, 0x12, 0x69, 0x2c, 0x00, 0x69, - 0x75, 0xcf, 0x95, 0x54, 0xb5, 0x2d, 0x63, 0x60, 0x5e, 0x9b, 0xbc, 0x51, 0xc0, 0x07, 0xba, 0x61, - 0x87, 0x08, 0xba, 0xe6, 0xfd, 0x98, 0xf2, 0x06, 0x80, 0x0d, 0x20, 0x7c, 0x48, 0x23, 0x3a, 0xb9, - 0x74, 0x59, 0x6f, 0xec, 0x9d, 0x2f, 0xb1, 0x4a, 0xd4, 0xb3, 0x4e, 0xfc, 0x7a, 0x33, 0xb0, 0x9a, - 0x0b, 0xa4, 0xce, 0x61, 0x8c, 0xf1, 0x83, 0xc1, 0xe0, 0xa7, 0x06, 0x41, 0x65, 0xb0, 0xee, 0x18, - 0x34, 0x8f, 0x8a, 0x15, 0x42, 0x71, 0x1d, 0xf7, 0x99, 0xe6, 0x2d, 0x7d, 0x86, 0xf9, 0x5e, 0x3a, - 0x64, 0x8a, 0xe6, 0x32, 0x58, 0xc7, 0x11, 0xc3, 0xdd, 0xe2, 0x9b, 0xf7, 0x59, 0x1a, 0x06, 0x32, - 0xaf, 0xdd, 0x47, 0xaf, 0xed, 0xa3, 0xde, 0x00, 0x00, 0x01, 0x43, 0x12, 0x7e, 0x61, 0xbb, 0x2b, - 0x1d, 0x25, 0xb9, 0x7d, 0x8e, 0x56, 0x64, 0x31, 0xdb, 0x3a, 0xf8, 0x23, 0x8b, 0x55, 0x1c, 0xdd, - 0x2d, 0x44, 0x75, 0x2f, 0xc4, 0x86, 0x11, 0x96, 0x4c, 0xf5, 0xc0, 0x8c, 0x1d, 0xc0, 0x70, 0x85, - 0x01, 0x36, 0x29, 0x4b, 0x30, 0xf9, 0x0c, 0x2e, 0x2e, 0xab, 0x75, 0xca, 0x0f, 0xb5, 0x98, 0x2d, - 0x85, 0x23, 0x95, 0x15, 0xd9, 0x3a, 0xd1, 0x47, 0x38, 0xc1, 0xcf, 0x0e, 0x07, 0xc0, 0xf8, 0x1c, - 0x39, 0x7b, 0xbd, 0x31, 0xda, 0xb7, 0x54, 0xc7, 0xce, 0x1a, 0xf3, 0x62, 0x6d, 0xf2, 0x33, 0x4e, - 0x0c, 0x84, 0x04, 0x14, 0xd1, 0x3b, 0x42, 0xb2, 0x11, 0x3a, 0x3a, 0x48, 0x95, 0xc1, 0x29, 0xfe, - 0x5d, 0xd7, 0x8e, 0xf7, 0x59, 0x1a, 0x16, 0x2a, 0x00, 0x00, 0x00, 0x5c, 0x28, 0x11, 0x53, 0x00, - 0x8c, 0xdc, 0x43, 0x04, 0x31, 0x3f, 0x9d, 0x4a, 0x0b, 0xf6, 0x08, 0xd3, 0x72, 0x9c, 0x3f, 0x79, - 0x25, 0x35, 0x5f, 0x40, 0xdb, 0xae, 0x90, 0xbe, 0x35, 0xf4, 0x76, 0xaa, 0x39, 0xba, 0x07, 0x23, - 0xc6, 0x4c, 0x83, 0xbc, 0xee, 0x94, 0x25, 0x80, 0x2a, 0x8d, 0x1a, 0x7f, 0x80, 0xa7, 0x24, 0x50, - 0x17, 0x5b, 0x24, 0x09, 0xe7, 0x28, 0xf6, 0x9b, 0xcd, 0x57, 0x4f, 0x9c, 0x60, 0xef, 0x16, 0xcc, - 0x16, 0x16, 0x7b, 0x34, 0xc8, 0xe1, 0xf0, 0x88, 0x30, 0xb4, 0xb2, 0xcb, 0x30, 0xc9, 0x44, 0x28, - 0xfa, 0xb3, 0xe0, 0x21, 0x20, 0x00, 0xc0, 0x5a, 0xcb, 0x01, 0x0f, 0x06, 0x34, 0x67, 0x8e, 0xf8, - 0x7c, 0x1f, 0x80, 0xfe, 0x07, 0xc0, 0xf8, 0x32, 0xcb, 0x21, 0x8b, 0x97, 0x59, 0x0a, 0x06, 0x3a, - 0xb0, 0xd2, 0xc2, 0xb5, 0xa3, 0xc7, 0x39, 0x0e, 0x03, 0xf4, 0xb2, 0xef, 0x07, 0xda, 0xb6, 0xfd, - 0xfa, 0x68, 0xc1, 0x01, 0xe1, 0x5a, 0x65, 0xe7, 0x5b, 0x3a, 0xf3, 0x1a, 0xe7, 0x68, 0xda, 0xb9, - 0x19, 0x4d, 0xb4, 0xd8, 0x9f, 0x2d, 0x49, 0xba, 0x8c, 0x34, 0x95, 0x40, 0x35, 0x86, 0xfc, 0xd1, - 0x25, 0x6c, 0x90, 0x81, 0xd5, 0x1c, 0xb9, 0xb7, 0xfa, 0x6e, 0x47, 0xd5, 0xbc, 0x83, 0xcf, 0xdb, - 0x58, 0x54, 0x41, 0xf5, 0x28, 0xe2, 0x40, 0x72, 0x7c, 0x19, 0x98, 0x54, 0xe7, 0x07, 0x9c, 0xfe, - 0x10, 0xe5, 0xd3, 0x45, 0xaf, 0x2c, 0x05, 0x07, 0xe7, 0xca, 0x90, 0x28, 0xe4, 0xb0, 0x44, 0x99, - 0x7a, 0x8a, 0xf2, 0x71, 0x8e, 0x64, 0x8a, 0xf4, 0x21, 0xc0, 0x90, 0x53, 0x7e, 0x78, 0x12, 0x1c, - 0x5b, 0x21, 0x8b, 0x97, 0x59, 0x1a, 0x16, 0x2a, 0xaf, 0xde, 0xcb, 0xf9, 0xc9, 0x12, 0x54, 0xc3, - 0xb6, 0xbf, 0xc6, 0xdd, 0x33, 0xef, 0x43, 0xbb, 0x3f, 0x61, 0x00, 0xdf, 0x78, 0x66, 0x7c, 0x52, - 0x78, 0x22, 0x5a, 0x11, 0x2f, 0xa6, 0x2d, 0x29, 0xd3, 0xf5, 0x2b, 0x54, 0x7d, 0x23, 0xc3, 0x14, - 0x17, 0x5c, 0x47, 0x14, 0x3e, 0x40, 0xf9, 0x87, 0x56, 0x0b, 0x97, 0x3a, 0xa9, 0x71, 0x0f, 0x84, - 0xee, 0xa0, 0xa0, 0xc2, 0xc3, 0xf3, 0x10, 0xbc, 0xa1, 0x1b, 0x7b, 0xcd, 0x21, 0x87, 0x66, 0x05, - 0x87, 0x9e, 0x18, 0x7b, 0x33, 0x26, 0x7c, 0xc5, 0x42, 0xe2, 0x04, 0x2c, 0xfc, 0xd2, 0xcc, 0x09, - 0x39, 0xa3, 0x8c, 0x74, 0xda, 0xc6, 0x4b, 0xa6, 0x53, 0xda, 0xc2, 0x51, 0x5f, 0x77, 0x6a, 0x14, - 0x75, 0x95, 0xe7, 0x9c, 0x0a, 0x26, 0x59, 0x81, 0xdb, 0x21, 0x8b, 0x97, 0x59, 0x1a, 0x26, 0x32, - 0xaf, 0xde, 0xcb, 0xf9, 0xd9, 0x8b, 0x32, 0x47, 0x46, 0x01, 0xfe, 0xdc, 0xee, 0xca, 0xbb, 0x21, - 0xe2, 0x27, 0xf6, 0xc0, 0x74, 0x81, 0xd9, 0xaa, 0xab, 0xf8, 0x70, 0x9d, 0x8d, 0x88, 0xd7, 0x08, - 0x4b, 0x17, 0x2f, 0xd9, 0xa6, 0xe0, 0x2f, 0x93, 0x48, 0xf7, 0x33, 0xb2, 0xb3, 0x2d, 0x19, 0x18, - 0x12, 0xfd, 0x31, 0xb8, 0xcc, 0xfe, 0x64, 0x87, 0x69, 0xdc, 0xe4, 0x5c, 0x65, 0xe5, 0x77, 0xb0, - 0x68, 0xb0, 0x06, 0xb4, 0x3b, 0x59, 0x19, 0x83, 0x3c, 0x38, 0x3c, 0x3c, 0x38, 0x78, 0x83, 0x61, - 0xd0, 0x31, 0x81, 0x97, 0x03, 0xb8, 0xef, 0x01, 0x15, 0x40, 0x82, 0xed, 0x8b, 0x08, 0x4f, 0x71, - 0x32, 0xf5, 0xc9, 0x29, 0x1b, 0x2b, 0xac, 0x4c, 0x10, 0x70, 0xa7, 0x97, 0x07, 0x0e, 0x49, 0xe3, - 0xdb, 0x21, 0x4b, 0x97, 0x59, 0x1a, 0x26, 0x12, 0xae, 0xec, 0x11, 0x26, 0xe8, 0x37, 0x92, 0x31, - 0xe5, 0x7f, 0x28, 0xd9, 0x53, 0x25, 0xa2, 0x66, 0x43, 0xcd, 0x52, 0x54, 0x1d, 0x5b, 0xc6, 0x8a, - 0x80, 0xb8, 0x1c, 0x95, 0x07, 0xbc, 0xd0, 0x16, 0xe2, 0x9d, 0x9e, 0x69, 0x70, 0x19, 0xe3, 0x82, - 0x2c, 0xb5, 0x68, 0xe8, 0x7d, 0x89, 0x1a, 0xcd, 0x5a, 0x2e, 0x31, 0x6a, 0x09, 0x5b, 0xb5, 0x65, - 0x8b, 0xd3, 0x84, 0x69, 0xae, 0xaa, 0xd1, 0xbf, 0x98, 0x54, 0x1f, 0xbe, 0x56, 0xfe, 0x6c, 0x38, - 0x47, 0x8f, 0x73, 0x0c, 0xc7, 0xe0, 0x43, 0x58, 0x7e, 0xba, 0xbf, 0x42, 0x48, 0xe0, 0x02, 0xaa, - 0x07, 0x30, 0xfe, 0x2f, 0xcb, 0xc4, 0xd0, 0xd8, 0x90, 0xf7, 0xab, 0x12, 0xee, 0x44, 0x87, 0x70, - 0x74, 0xa0, 0x63, 0xfb, 0xc1, 0xe2, 0x6c, 0x9e, 0x5b, 0x21, 0x8b, 0x97, 0x59, 0x19, 0xf6, 0x2a, - 0xaf, 0xa6, 0xc8, 0x17, 0x83, 0x85, 0xb2, 0x00, 0x04, 0x26, 0x17, 0x1b, 0xb0, 0x82, 0x3d, 0x92, - 0x55, 0x92, 0x2c, 0xcb, 0x67, 0x59, 0x5d, 0xa4, 0x57, 0xb5, 0xf4, 0x0b, 0xcd, 0x2d, 0x28, 0x50, - 0x40, 0x15, 0x90, 0x80, 0x09, 0xb6, 0x09, 0x0b, 0x90, 0x65, 0xdb, 0xc6, 0xf1, 0x86, 0xd9, 0x38, - 0xd8, 0xa2, 0x03, 0x25, 0xc0, 0x97, 0x38, 0x86, 0xfd, 0x86, 0x46, 0x1a, 0xb9, 0xce, 0xa9, 0x5e, - 0xb6, 0xa4, 0x22, 0x2f, 0x9a, 0x86, 0x38, 0xc2, 0x7b, 0x9e, 0x78, 0x3c, 0x1e, 0x1c, 0x1f, 0x07, - 0x1a, 0x08, 0x32, 0x5b, 0x03, 0x89, 0x1d, 0x5b, 0x9f, 0x94, 0x9e, 0x97, 0xde, 0x51, 0xf2, 0x0d, - 0x17, 0xe9, 0x94, 0xa7, 0xfd, 0x5e, 0xea, 0x1d, 0xe2, 0xa8, 0x0b, 0xc0, 0xc2, 0x00, 0xc1, 0xec, - 0x4b, 0x21, 0x4b, 0x97, 0x59, 0x1a, 0x06, 0x1a, 0xaf, 0xde, 0xcb, 0xf9, 0xbd, 0x13, 0x73, 0x0c, - 0x76, 0x0e, 0x78, 0x17, 0x02, 0x17, 0xd2, 0xd1, 0x02, 0xfc, 0x16, 0xa1, 0x3f, 0x01, 0x7d, 0x07, - 0x4a, 0xc9, 0x36, 0x24, 0x45, 0xff, 0xd4, 0x75, 0x8f, 0x51, 0x98, 0xd1, 0x81, 0x98, 0x2a, 0x87, - 0xdc, 0x6f, 0xb8, 0x72, 0xcc, 0x0f, 0x1f, 0xd1, 0x7b, 0x47, 0x57, 0xe5, 0xd0, 0x37, 0xa1, 0x06, - 0x28, 0x7d, 0x54, 0xeb, 0xca, 0x35, 0xc5, 0x77, 0x08, 0x7a, 0x5b, 0x8e, 0x13, 0x60, 0x93, 0x27, - 0x12, 0x38, 0x61, 0xe7, 0x8f, 0xe2, 0x86, 0x8d, 0x73, 0x04, 0x06, 0xf8, 0xb1, 0x98, 0xe6, 0x3a, - 0x4c, 0x2f, 0x31, 0x97, 0x5d, 0x3d, 0xda, 0xb8, 0xc3, 0x38, 0x03, 0xc6, 0xe1, 0x67, 0x68, 0x23, - 0x75, 0x64, 0x4a, 0x24, 0x80, 0x0c, 0x38, 0x26, 0x5b, 0x21, 0x4b, 0x97, 0x59, 0x19, 0xe6, 0x12, - 0xb0, 0xdc, 0x58, 0x39, 0x3d, 0x8b, 0x23, 0x72, 0x96, 0x1a, 0x93, 0x6a, 0x4f, 0xce, 0x7c, 0x61, - 0x4b, 0xec, 0xc2, 0xd4, 0x2b, 0xbc, 0xbe, 0x07, 0xc6, 0xe1, 0x67, 0x09, 0xbc, 0x3f, 0x3a, 0x43, - 0x0e, 0xc1, 0x55, 0x4e, 0xe1, 0x45, 0xf2, 0x9d, 0x7a, 0x6c, 0x8a, 0x15, 0x85, 0x68, 0xb5, 0x9e, - 0xe4, 0x21, 0xc2, 0x5c, 0x9a, 0x7f, 0xfd, 0x12, 0x4d, 0xdb, 0x57, 0x4a, 0x82, 0x57, 0xf1, 0x15, - 0x9e, 0x9b, 0xa3, 0xeb, 0xf2, 0x9a, 0x16, 0xc3, 0x65, 0x38, 0xe7, 0x38, 0x60, 0xe0, 0xff, 0x5e, - 0xdd, 0x32, 0xfb, 0x28, 0x6a, 0xf7, 0x4e, 0x4c, 0x5e, 0x78, 0x82, 0x5a, 0x6e, 0x9f, 0x99, 0xbf, - 0x21, 0x3f, 0x87, 0x94, 0xf0, 0x70, 0x7c, 0xc9, 0x0e, 0x2b, 0x4c, 0x63, 0x83, 0xce, 0x97, 0xc3, - 0xdb, 0x21, 0x4b, 0x97, 0x59, 0x1a, 0x06, 0x32, 0xb0, 0xdc, 0xac, 0xc2, 0x74, 0xa1, 0x3d, 0x48, - 0x3a, 0x03, 0x09, 0x80, 0x9b, 0x70, 0x44, 0x4f, 0xeb, 0x7d, 0xc6, 0xa5, 0x9f, 0xd8, 0xad, 0x96, - 0x2b, 0xbf, 0x90, 0x15, 0x58, 0x86, 0x2c, 0xec, 0xd1, 0x0a, 0xa1, 0xe6, 0x4e, 0x6a, 0xf4, 0x93, - 0x3e, 0x8c, 0xf0, 0x79, 0x70, 0x49, 0xa2, 0x36, 0x54, 0x72, 0xaf, 0x3f, 0xcd, 0x73, 0xf0, 0x0e, - 0x8c, 0x0f, 0xf0, 0xbc, 0xfe, 0xcf, 0x1e, 0xc7, 0x10, 0xf2, 0x8a, 0x7d, 0xf0, 0xe5, 0x4b, 0x27, - 0x1e, 0x0e, 0x18, 0x0f, 0xea, 0xd8, 0xb6, 0x07, 0x4a, 0x5f, 0xdf, 0x0c, 0x9b, 0x3d, 0xc2, 0x1a, - 0x6f, 0x80, 0xe1, 0x9e, 0xea, 0x44, 0xe5, 0x60, 0x48, 0xb2, 0x83, 0xa4, 0x3c, 0xd6, 0xce, 0xc0, - 0xe6, 0x64, 0xef, 0x11, 0xcf, 0x07, 0x98, 0x63, 0xd3, 0xbf, 0xd0, 0x17, 0x59, 0x19, 0xe6, 0x0a, - 0xaf, 0xa6, 0xca, 0x13, 0xf8, 0x16, 0xcc, 0x00, 0x2e, 0x16, 0x74, 0x2c, 0x96, 0x75, 0x81, 0xc1, - 0x54, 0x0f, 0xd8, 0x5f, 0x66, 0x50, 0xed, 0x38, 0xbc, 0x76, 0xb2, 0x05, 0x47, 0x58, 0xa7, 0xdc, - 0x28, 0x22, 0x37, 0xba, 0x80, 0xc1, 0xce, 0xfc, 0xc3, 0x01, 0xf5, 0xa7, 0x48, 0x74, 0x2b, 0x7a, - 0xf6, 0x3c, 0xed, 0xd3, 0x7a, 0xf7, 0xcf, 0xcd, 0x5a, 0x3a, 0xe2, 0xe7, 0x4a, 0x9e, 0xb8, 0x20, - 0x26, 0x3c, 0xc9, 0x42, 0x4f, 0x84, 0xde, 0x70, 0xe3, 0xe1, 0xf0, 0x7c, 0x1f, 0xf0, 0x08, 0x2b, - 0x86, 0x18, 0x8d, 0x41, 0x97, 0x22, 0x64, 0xd0, 0xe4, 0xf9, 0x77, 0xcc, 0x4d, 0x27, 0x79, 0x60, - 0x8d, 0x40, 0x8f, 0x8e, 0x03, 0x73, 0xd1, 0xe6, 0x27, 0x1f, 0x34, 0xfc, 0x58, 0x09, 0x9e, 0x33, - 0x53, 0xbf, 0xd0, 0x17, 0x59, 0x19, 0xd6, 0x0a, 0xae, 0xec, 0x11, 0x26, 0xb9, 0x70, 0xd6, 0x00, - 0x1d, 0xb3, 0x75, 0x85, 0x2c, 0xf6, 0x85, 0xce, 0x68, 0x9f, 0xd0, 0x02, 0xde, 0x6d, 0xd0, 0xae, - 0x0f, 0x3a, 0x8d, 0x29, 0xf0, 0x62, 0x61, 0x80, 0x25, 0x49, 0x49, 0xcd, 0xa5, 0xad, 0x6e, 0xdb, - 0xb5, 0x0f, 0x50, 0x45, 0x12, 0xb1, 0xae, 0x86, 0xe6, 0xe5, 0x5f, 0x0c, 0x95, 0x17, 0x24, 0xd3, - 0xd6, 0x45, 0x8e, 0x4c, 0x28, 0x38, 0x20, 0xfc, 0x96, 0xea, 0x05, 0xe4, 0x13, 0xd8, 0x90, 0xdc, - 0x31, 0xc3, 0x83, 0xc1, 0xf0, 0xf0, 0xbf, 0x1b, 0x6a, 0x44, 0x76, 0xe5, 0xfd, 0xdf, 0x14, 0xcf, - 0xe3, 0x43, 0x50, 0xa4, 0xe2, 0x8e, 0x4c, 0x46, 0x7a, 0x15, 0xb5, 0xc8, 0x1c, 0xd3, 0x39, 0x23, - 0x21, 0x67, 0x9a, 0xae, 0xf4, 0x0e, 0x19, 0x99, 0xd3, 0xbf, 0xd0, 0x17, 0x59, 0x19, 0xc6, 0x1a, - 0xb0, 0xd3, 0x95, 0x9c, 0x58, 0x00, 0x00, 0x00, 0xf5, 0x3c, 0x01, 0xbc, 0x50, 0x4b, 0x8a, 0x3b, - 0xbe, 0xb0, 0x2c, 0xd8, 0x89, 0x14, 0x24, 0xd0, 0xeb, 0x2b, 0x46, 0x10, 0x67, 0x88, 0xd3, 0xd3, - 0xda, 0x0f, 0x5c, 0x59, 0x59, 0x2c, 0x25, 0x0f, 0x4c, 0x65, 0x0a, 0x9b, 0x0a, 0x21, 0xef, 0xdc, - 0x43, 0xe3, 0x91, 0xf6, 0x38, 0x2d, 0x60, 0xfe, 0x48, 0xec, 0xff, 0x1b, 0xac, 0x69, 0x69, 0x14, - 0x84, 0x18, 0x2d, 0xfb, 0x0d, 0xe8, 0x64, 0xaa, 0x27, 0x87, 0xc7, 0x87, 0xc7, 0xfc, 0x93, 0x00, - 0x84, 0x46, 0xae, 0xd8, 0xb5, 0x8d, 0x59, 0x05, 0xca, 0xd3, 0x74, 0xc9, 0xc5, 0xfb, 0x9c, 0x69, - 0x49, 0xcc, 0xb9, 0xa2, 0x46, 0xca, 0x20, 0xd8, 0xdb, 0xfa, 0xf7, 0xe1, 0x84, 0x8e, 0x35, 0x40, - 0x03, 0xbf, 0xd0, 0x17, 0x59, 0x39, 0xc6, 0x3a, 0xaf, 0xdd, 0x49, 0xd0, 0x58, 0x01, 0x68, 0x7b, - 0x15, 0x25, 0xbc, 0xbd, 0x68, 0xca, 0x4a, 0xaa, 0x1e, 0x7c, 0xca, 0x07, 0xf0, 0x8b, 0xe2, 0x53, - 0xa1, 0xba, 0xcf, 0x90, 0xae, 0xec, 0x67, 0xd5, 0x18, 0xc8, 0xe7, 0xcf, 0xdf, 0x2a, 0x54, 0xef, - 0x84, 0x3c, 0x94, 0x02, 0xc3, 0xc2, 0x71, 0x3b, 0x0e, 0xc5, 0xa1, 0x6d, 0x0a, 0xb9, 0x20, 0xad, - 0xfa, 0xff, 0x3f, 0x40, 0xcf, 0x3a, 0x78, 0x7f, 0x3c, 0xd9, 0x35, 0x70, 0xe3, 0x33, 0xb3, 0x83, - 0xe0, 0xfc, 0x0f, 0xc0, 0xfc, 0x1f, 0x00, 0x73, 0x1f, 0x5f, 0xd1, 0xc7, 0x12, 0x2f, 0xa6, 0x64, - 0x53, 0xbe, 0xe4, 0x8c, 0x0d, 0x97, 0x0f, 0xcd, 0xb3, 0xd2, 0x58, 0xb6, 0xba, 0x18, 0xb8, 0x62, - 0x78, 0x32, 0x88, 0x44, 0x2a, 0xf3, 0x33, 0x33, 0xdb, 0x21, 0x37, 0x97, 0x59, 0x19, 0xf5, 0xca, - 0xaf, 0xdd, 0x49, 0xcf, 0xc5, 0x1e, 0x8a, 0xa2, 0x00, 0xf6, 0x9a, 0xa4, 0x8c, 0x5f, 0xa2, 0x92, - 0x0a, 0x8c, 0x05, 0x2a, 0x5b, 0x3d, 0x0c, 0x7a, 0x22, 0xeb, 0xb9, 0x07, 0xe0, 0x57, 0xc1, 0xd5, - 0x2e, 0x6a, 0x68, 0x8d, 0xcb, 0xd0, 0x32, 0xc8, 0x4a, 0x3f, 0x86, 0x21, 0xc9, 0x08, 0x97, 0x21, - 0x27, 0xa9, 0xb0, 0x38, 0xa1, 0xf3, 0xdd, 0xf5, 0xca, 0x95, 0xab, 0xe6, 0xa9, 0xed, 0x72, 0x36, - 0x30, 0xd1, 0x6f, 0x53, 0xdb, 0xb4, 0x39, 0x64, 0xcc, 0xe3, 0xe0, 0xf8, 0x3c, 0x1e, 0x00, 0x5c, - 0xec, 0xbe, 0xee, 0x62, 0xee, 0x30, 0x47, 0x27, 0x12, 0x4c, 0x50, 0xb1, 0x4b, 0xee, 0xe4, 0x74, - 0x51, 0xf6, 0x91, 0x68, 0xee, 0x17, 0x12, 0xa6, 0xed, 0xdb, 0x20, 0xe8, 0x25, 0xec, 0x72, 0xc9, - 0xdb, 0x21, 0x37, 0x97, 0x59, 0x19, 0xf5, 0x8a, 0xaf, 0xa6, 0xc8, 0x17, 0x7f, 0x81, 0x39, 0x12, - 0x00, 0x8c, 0x3f, 0xc9, 0x35, 0x8a, 0x38, 0x56, 0xa2, 0xee, 0xa0, 0x6a, 0x00, 0x15, 0xde, 0x4d, - 0xd3, 0xca, 0xd3, 0x0a, 0x6e, 0xcd, 0x17, 0xcf, 0x7e, 0x26, 0xde, 0x16, 0x06, 0xdf, 0x37, 0x99, - 0x56, 0xf8, 0x09, 0xf0, 0x77, 0x96, 0xe7, 0xd9, 0x35, 0xf0, 0x67, 0xfa, 0x28, 0x1f, 0x04, 0xa7, - 0x80, 0x95, 0x55, 0xfa, 0xd0, 0x3f, 0x07, 0x1c, 0x82, 0x18, 0x34, 0x74, 0x9c, 0x1e, 0x3c, 0x1f, - 0x07, 0xc0, 0xfe, 0x07, 0xe0, 0xe7, 0x99, 0xdc, 0x6f, 0x24, 0xe4, 0x59, 0xd0, 0x63, 0x86, 0xe2, - 0x7a, 0xa0, 0xa2, 0x48, 0x62, 0x54, 0xff, 0x81, 0x25, 0x64, 0xb8, 0x1f, 0xa0, 0xd6, 0x5c, 0x0b, - 0x23, 0xee, 0xbe, 0x8f, 0x2e, 0xdb, 0x86, 0x41, 0xdb, 0x21, 0x37, 0x97, 0x59, 0x19, 0xe5, 0x7a, - 0xaf, 0xa6, 0xca, 0xa1, 0x55, 0xbe, 0xff, 0xdc, 0x00, 0x04, 0xf7, 0x23, 0x29, 0x46, 0xf6, 0xb4, - 0x53, 0x22, 0x0a, 0x40, 0x7e, 0x6f, 0x58, 0xb9, 0x8c, 0xdb, 0xa1, 0x3c, 0x7b, 0xa5, 0x37, 0xc7, - 0xb3, 0x99, 0xc5, 0x50, 0x17, 0x39, 0x75, 0x8e, 0xb7, 0xfb, 0x7c, 0x3a, 0xd5, 0xa4, 0x7e, 0xd0, - 0x3f, 0xff, 0xe7, 0xb1, 0x37, 0x20, 0x50, 0xf1, 0xb3, 0xef, 0x1b, 0x2f, 0x41, 0x11, 0x82, 0xc1, - 0xa0, 0x6e, 0xdb, 0x4b, 0x76, 0x92, 0x4b, 0x06, 0xb1, 0xc1, 0xf0, 0x7c, 0x0f, 0x83, 0x80, 0x0f, - 0x3f, 0xdd, 0xeb, 0xe5, 0xf6, 0x76, 0x84, 0x46, 0x89, 0x97, 0x5a, 0x4a, 0xa7, 0x01, 0x83, 0xff, - 0x30, 0x0d, 0x1a, 0x37, 0x65, 0xdd, 0x88, 0xa6, 0x32, 0x01, 0x36, 0x2d, 0x96, 0xfb, 0x25, 0xb3, - 0xdb, 0x21, 0x37, 0x97, 0x59, 0x1a, 0x15, 0x6a, 0xaf, 0xdd, 0x47, 0xae, 0x87, 0xb3, 0x6e, 0x00, - 0x2d, 0xd4, 0x97, 0x7a, 0xa6, 0xdf, 0x22, 0x80, 0x85, 0x1b, 0x4f, 0xc2, 0x1f, 0x2c, 0x3c, 0x0b, - 0x5d, 0xbf, 0xc4, 0x84, 0x2b, 0xff, 0x91, 0x11, 0x42, 0x6c, 0xb4, 0xec, 0x24, 0xb7, 0xd3, 0x15, - 0x41, 0xb1, 0x42, 0x15, 0xf2, 0x76, 0x8d, 0x3a, 0x20, 0x9d, 0x6f, 0x84, 0x9f, 0x75, 0x54, 0xe3, - 0x17, 0xbf, 0x03, 0x0f, 0xcb, 0x00, 0xdf, 0x7d, 0x83, 0xeb, 0xa5, 0x5b, 0x09, 0x1c, 0xe3, 0xe0, - 0xf8, 0x0f, 0xc0, 0x7e, 0x07, 0xe1, 0x87, 0x8c, 0x27, 0xc1, 0xfd, 0x79, 0xea, 0xde, 0xdd, 0xa3, - 0x4f, 0xb8, 0x14, 0x51, 0x14, 0xd3, 0x9f, 0x0c, 0x07, 0xa2, 0xaf, 0xcf, 0xb0, 0x5d, 0x13, 0x5a, - 0xa6, 0x97, 0x1a, 0x4c, 0x96, 0x3f, 0xe4, 0x48, 0xdb, 0x21, 0x37, 0x97, 0x59, 0x19, 0xf5, 0x7a, - 0xae, 0xed, 0x18, 0xc3, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x21, 0x1a, 0x23, 0x22, 0x82, - 0xde, 0x56, 0x00, 0x03, 0x39, 0xab, 0x1a, 0x5e, 0x2d, 0x76, 0x3a, 0x8a, 0x3b, 0x7a, 0x9f, 0x90, - 0x8a, 0xba, 0x2c, 0xc0, 0x57, 0xf6, 0x52, 0xbf, 0xc5, 0x90, 0xe2, 0x46, 0x3b, 0x94, 0xfd, 0x1b, - 0x68, 0x50, 0xf6, 0x8c, 0x81, 0x5f, 0x61, 0xa9, 0x06, 0x0a, 0x0b, 0x42, 0x58, 0x0c, 0x8c, 0xfe, - 0x0b, 0xb1, 0x94, 0x78, 0xa0, 0x7e, 0x0f, 0x3c, 0x7c, 0x0f, 0x81, 0xfc, 0x0f, 0xe0, 0xf8, 0xf2, - 0x26, 0x1d, 0x88, 0x44, 0xb8, 0xd3, 0x1d, 0xb4, 0x2b, 0xe8, 0x64, 0x42, 0xb7, 0x2c, 0x72, 0x7d, - 0x93, 0x77, 0xa6, 0xc5, 0x1e, 0x26, 0xfb, 0x7e, 0x40, 0xdf, 0xd0, 0xd5, 0xf4, 0xe7, 0x80, 0xe0, - 0x5b, 0x21, 0x37, 0x97, 0x59, 0x19, 0xf5, 0xd2, 0xae, 0xed, 0x18, 0xc3, 0x34, 0x00, 0x00, 0x00, - 0x0e, 0xd4, 0xbc, 0x15, 0xaa, 0xb6, 0x06, 0x47, 0x8d, 0x6e, 0x00, 0x57, 0x6b, 0xa6, 0xed, 0xff, - 0xdf, 0xc2, 0x48, 0x94, 0x1a, 0xbb, 0xb6, 0xb7, 0x18, 0xd1, 0x28, 0xac, 0x2e, 0x52, 0x81, 0xc1, - 0xa9, 0xa0, 0x62, 0x11, 0xeb, 0xf2, 0xdf, 0xb5, 0xb9, 0x5e, 0xd4, 0x85, 0x94, 0x5a, 0x46, 0xe4, - 0xde, 0x7e, 0xdb, 0x7b, 0xe1, 0x37, 0x57, 0x31, 0x46, 0xd4, 0x02, 0xca, 0x34, 0xe1, 0xfc, 0x70, - 0xf0, 0x3f, 0x01, 0xf0, 0x3e, 0x07, 0x9f, 0x21, 0xd3, 0x9c, 0x19, 0xb1, 0x91, 0x52, 0xbf, 0xf7, - 0xbb, 0x6e, 0xf1, 0x68, 0x99, 0xec, 0x8c, 0x3a, 0x2d, 0x5f, 0x1a, 0x16, 0xaa, 0x97, 0xa7, 0xad, - 0xfd, 0x72, 0x17, 0x32, 0x6f, 0x42, 0xd4, 0x0f, 0xcb, 0x21, 0x37, 0x97, 0x59, 0x19, 0xf5, 0xda, - 0xae, 0xec, 0x0f, 0xb3, 0x42, 0x12, 0xd3, 0x00, 0x00, 0x00, 0xdc, 0x94, 0x9d, 0x84, 0xb1, 0xa5, - 0x70, 0x6a, 0xdb, 0xef, 0x0a, 0xe3, 0xcb, 0x15, 0x2e, 0xb4, 0x56, 0x8f, 0xbd, 0x51, 0xc2, 0x83, - 0x91, 0xa7, 0x98, 0xc0, 0xf5, 0xee, 0xdb, 0x79, 0x1d, 0xb2, 0x13, 0x9d, 0x23, 0x3c, 0xaa, 0x66, - 0x7e, 0x45, 0x17, 0xf3, 0x2c, 0x5f, 0x2c, 0x3b, 0x5d, 0xa5, 0x8a, 0x1c, 0x37, 0x62, 0x8c, 0xaa, - 0x8f, 0x52, 0xa3, 0x35, 0x94, 0x57, 0x34, 0xcd, 0xa6, 0xe4, 0xe1, 0xc3, 0xc3, 0xf8, 0x1f, 0x07, - 0x00, 0x08, 0xe5, 0x13, 0x34, 0x5a, 0x6e, 0x33, 0x24, 0xe6, 0xc1, 0x17, 0xab, 0xfa, 0x52, 0x10, - 0x78, 0x33, 0x95, 0xa6, 0xec, 0x53, 0x1e, 0x72, 0xe2, 0x91, 0x85, 0x51, 0x96, 0x6f, 0x99, 0xa4, - 0xdb, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x06, 0x3a, 0xb0, 0xdc, 0xac, 0x99, 0xfc, 0xa7, 0x25, 0x91, - 0xff, 0x02, 0x20, 0x74, 0x42, 0x2a, 0x7a, 0x0c, 0x09, 0x7f, 0xbf, 0x91, 0x04, 0x4f, 0x0d, 0xe0, - 0xe9, 0xc9, 0xf2, 0x79, 0x05, 0xbc, 0x3c, 0xb1, 0x5d, 0x4b, 0x07, 0xfc, 0xc4, 0xa6, 0x05, 0x94, - 0x12, 0xf3, 0x70, 0xf6, 0x4a, 0xf1, 0x4c, 0x1f, 0x04, 0xe3, 0x43, 0x14, 0xed, 0x08, 0xaa, 0x75, - 0xe0, 0x9d, 0xb4, 0xe2, 0x3b, 0x03, 0xeb, 0x98, 0x58, 0xd1, 0xf1, 0xc0, 0xf6, 0x1a, 0x1e, 0x71, - 0xc1, 0xf0, 0x7f, 0x03, 0xc1, 0xc3, 0x82, 0xb1, 0xdc, 0x01, 0xc1, 0xd3, 0x82, 0x68, 0x7e, 0x1f, - 0xa1, 0xd1, 0x19, 0xa8, 0x64, 0xc8, 0x03, 0x1b, 0x0f, 0x1d, 0x3b, 0x85, 0xf2, 0x4a, 0x1f, 0xc4, - 0x77, 0x35, 0xc2, 0x0e, 0x3e, 0x44, 0x1b, 0xc9, 0x5b, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x06, 0x0a, - 0xaf, 0xde, 0xcb, 0x94, 0xe0, 0xe7, 0x7a, 0x12, 0x00, 0x00, 0x3b, 0xd0, 0x3d, 0xc1, 0x34, 0x00, - 0x00, 0x25, 0xbc, 0xbe, 0x5e, 0x36, 0xae, 0xc3, 0xf9, 0xb2, 0xec, 0x2f, 0x96, 0x83, 0xd5, 0xaf, - 0xce, 0x9f, 0x73, 0xd2, 0xc1, 0xc4, 0x36, 0x12, 0x01, 0x35, 0xe4, 0x0f, 0x7f, 0x74, 0x91, 0xeb, - 0xec, 0x1c, 0x6e, 0x7d, 0x17, 0x17, 0xd1, 0x8a, 0x02, 0xb0, 0xbb, 0x49, 0x62, 0x7f, 0x96, 0xfd, - 0x74, 0xd9, 0xcf, 0x5b, 0x74, 0x84, 0xc1, 0xb3, 0x3c, 0x70, 0x7c, 0x0f, 0x81, 0xf8, 0x1c, 0x20, - 0xc5, 0xa2, 0x58, 0x94, 0xe3, 0xd8, 0xe3, 0x14, 0xd8, 0x70, 0x08, 0xda, 0x59, 0x77, 0x30, 0x9c, - 0x39, 0x8a, 0x54, 0xce, 0xb1, 0x23, 0x5d, 0x90, 0xbc, 0xe5, 0x2c, 0xb7, 0x25, 0x0f, 0x08, 0x40, - 0xdb, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x16, 0x12, 0xaf, 0xde, 0xcb, 0xe0, 0x87, 0x0d, 0x93, 0x07, - 0x00, 0x04, 0x00, 0x29, 0x9b, 0x99, 0x97, 0x35, 0x52, 0x0d, 0x40, 0x00, 0x00, 0x10, 0x0d, 0x7a, - 0x70, 0x35, 0x2f, 0x80, 0x3c, 0x14, 0xca, 0x10, 0x3f, 0x6a, 0x18, 0x6d, 0x29, 0xa9, 0x72, 0xf6, - 0xbe, 0xd4, 0x19, 0xd1, 0xc4, 0x29, 0x16, 0x24, 0xb3, 0x02, 0xa9, 0x72, 0x9b, 0xe3, 0xe8, 0xdd, - 0x71, 0x5d, 0xb6, 0x83, 0xae, 0x26, 0x28, 0x23, 0xb5, 0x52, 0xad, 0x16, 0x29, 0x84, 0xbf, 0x6a, - 0x3c, 0xae, 0x51, 0x03, 0xe3, 0xe0, 0xf8, 0x3f, 0x07, 0xe1, 0xe6, 0x67, 0xad, 0xc4, 0x79, 0x2e, - 0xfe, 0xc0, 0x72, 0x34, 0xde, 0x5c, 0xc6, 0x5b, 0xc1, 0xcb, 0xb0, 0x38, 0x50, 0x02, 0x89, 0xd4, - 0x18, 0xdf, 0x30, 0x71, 0x56, 0x27, 0xfe, 0x57, 0x5b, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x15, 0xf2, - 0xaf, 0xdd, 0x49, 0xcf, 0xcc, 0xa4, 0x07, 0x3f, 0x00, 0x08, 0xba, 0xea, 0x33, 0x83, 0xf2, 0x1d, - 0x4a, 0xe8, 0x2b, 0x00, 0x26, 0x46, 0xff, 0xc5, 0x59, 0xdc, 0x04, 0x76, 0xc7, 0x1a, 0x70, 0x6c, - 0xb1, 0x71, 0xe6, 0xd7, 0xc3, 0x71, 0xb8, 0x85, 0x8e, 0xf7, 0x24, 0x6f, 0x6d, 0x8b, 0xde, 0x37, - 0xc9, 0x4c, 0x48, 0xd6, 0x0e, 0x2a, 0x29, 0x33, 0x56, 0x9b, 0xcd, 0x28, 0xb4, 0x62, 0x82, 0x9e, - 0x70, 0x2a, 0x16, 0x0e, 0xfb, 0x6c, 0x82, 0x8b, 0x30, 0x71, 0xe1, 0xf8, 0x3f, 0x07, 0xc1, 0xf8, - 0x3b, 0xb8, 0x9b, 0x2f, 0x22, 0x79, 0x7d, 0x71, 0x14, 0x41, 0x6d, 0x70, 0x84, 0x45, 0x44, 0x06, - 0xa4, 0x86, 0xc9, 0x36, 0x7d, 0x80, 0xda, 0xcc, 0xf2, 0xc1, 0x2d, 0x16, 0x31, 0x2e, 0x7a, 0x8e, - 0x5b, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x15, 0xaa, 0xae, 0xec, 0x11, 0x26, 0xb7, 0x2f, 0x3f, 0xb4, - 0xb4, 0x00, 0x6e, 0x1a, 0x2b, 0xc2, 0xbc, 0x22, 0x6e, 0xf3, 0xf2, 0x6b, 0x3d, 0xec, 0x29, 0x95, - 0x53, 0xdd, 0xaa, 0x8c, 0x3d, 0xce, 0x81, 0x97, 0x61, 0x19, 0x2f, 0x5e, 0x13, 0xf1, 0x9c, 0xb6, - 0x3f, 0xcd, 0x77, 0x53, 0xf5, 0x90, 0x47, 0x07, 0xda, 0x9b, 0x63, 0x02, 0x4a, 0x30, 0xff, 0x3a, - 0x76, 0xe8, 0x42, 0x96, 0x6d, 0x1a, 0x64, 0xe4, 0xee, 0x86, 0x6d, 0xeb, 0x05, 0x66, 0x6c, 0xc3, - 0x8f, 0x81, 0xf8, 0x1f, 0x80, 0xfc, 0x1e, 0x07, 0xfe, 0x22, 0xc0, 0x2b, 0x82, 0x22, 0xa5, 0x60, - 0x5e, 0x4f, 0xef, 0x5c, 0x4a, 0xd8, 0x42, 0x5b, 0xca, 0xbc, 0xf0, 0x6b, 0xaa, 0xc3, 0x69, 0x6f, - 0x6b, 0xbe, 0xc8, 0x18, 0x3f, 0x00, 0x19, 0x8d, 0xcb, 0x22, 0x97, 0x17, 0x59, 0x19, 0xd5, 0x8a, - 0xaf, 0xa6, 0xc8, 0x6c, 0x5a, 0x28, 0x8f, 0x78, 0xe5, 0x00, 0x52, 0x7c, 0x34, 0x94, 0xa7, 0x12, - 0x1d, 0x1d, 0x0f, 0x27, 0x84, 0x09, 0xab, 0xd8, 0xc5, 0xf7, 0x69, 0xde, 0xcd, 0xf0, 0xbd, 0x50, - 0xdc, 0x4a, 0x32, 0xc3, 0x92, 0x6c, 0xb5, 0xa8, 0xd2, 0x87, 0x56, 0x5d, 0x57, 0x63, 0x68, 0x13, - 0x24, 0x2f, 0xdd, 0x92, 0x9a, 0xc8, 0x90, 0x83, 0x70, 0x09, 0x77, 0x16, 0xc2, 0x76, 0xb3, 0xe1, - 0xc5, 0xc0, 0x9a, 0x5c, 0x63, 0xe3, 0x9c, 0x3e, 0x1f, 0x07, 0xf0, 0x1f, 0x80, 0xfc, 0x1f, 0x0e, - 0xed, 0x87, 0xf2, 0x17, 0xaf, 0x9d, 0xdc, 0x64, 0x12, 0x56, 0x3e, 0x2c, 0x56, 0xd0, 0xe0, 0x92, - 0x09, 0xd3, 0xc4, 0x6d, 0xca, 0x42, 0x7c, 0x72, 0x29, 0x02, 0xc0, 0x40, 0x04, 0x3f, 0xf6, 0x5f, - 0x5b, 0x22, 0x97, 0x17, 0x59, 0x1a, 0x05, 0x9a, 0xae, 0xec, 0x0f, 0x7b, 0x69, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x41, 0xaf, 0xfc, 0x8a, 0xb4, 0xa6, 0x16, 0xf1, 0x30, 0x4a, 0x32, 0x65, 0x7b, 0xb8, - 0x15, 0x84, 0xe4, 0x15, 0x21, 0x24, 0x8e, 0xdc, 0xbd, 0x52, 0xbf, 0x4d, 0x97, 0x48, 0xff, 0xf2, - 0x35, 0x2f, 0xfc, 0x4c, 0xe2, 0x4b, 0x34, 0x66, 0x4b, 0x5b, 0xcf, 0xbc, 0xa3, 0x22, 0x7b, 0xd7, - 0x8b, 0x5e, 0xc5, 0x3b, 0x1d, 0xca, 0x9b, 0x63, 0x47, 0x36, 0x0c, 0x80, 0x64, 0xec, 0x6d, 0x26, - 0xb8, 0xe3, 0xe3, 0xf0, 0x0f, 0x81, 0xf8, 0x1e, 0x03, 0xbd, 0xe3, 0xe9, 0x7c, 0x73, 0xd5, 0xff, - 0xed, 0x9b, 0xb6, 0xa5, 0xdd, 0x0a, 0xa0, 0x88, 0xf8, 0xad, 0x8f, 0x0a, 0xc5, 0x85, 0x2f, 0x57, - 0x52, 0x60, 0xd9, 0x9f, 0x66, 0xd3, 0x7b, 0xa6, 0xdb, 0x22, 0x97, 0x17, 0x59, 0x19, 0xf5, 0xc2, - 0xaf, 0xde, 0xcb, 0x85, 0xa7, 0x00, 0x00, 0x00, 0x01, 0x55, 0xe8, 0x5f, 0x8a, 0x56, 0xbc, 0x0c, - 0x12, 0x0a, 0x2a, 0x1e, 0xa9, 0xdc, 0x71, 0xef, 0x73, 0xb5, 0x83, 0x0c, 0x00, 0x5a, 0x54, 0xc1, - 0xe2, 0x96, 0x5a, 0xfe, 0xd4, 0x70, 0xb8, 0x8d, 0x0f, 0x9e, 0xdd, 0xad, 0x2d, 0x24, 0x27, 0x8e, - 0xba, 0xe4, 0xfe, 0x43, 0xab, 0x43, 0x7a, 0x80, 0x27, 0x7e, 0x02, 0x55, 0x17, 0x88, 0x51, 0xcb, - 0x8e, 0x29, 0x97, 0x2f, 0x25, 0x2d, 0xd3, 0x54, 0x9e, 0x3c, 0x3e, 0x0f, 0xc0, 0xf8, 0x1f, 0x07, - 0xfc, 0x61, 0x65, 0xc8, 0x2a, 0x81, 0xda, 0x49, 0x4e, 0x23, 0xec, 0x61, 0xb4, 0xb1, 0xb2, 0xf1, - 0x65, 0x61, 0xad, 0x53, 0x22, 0xda, 0x54, 0x33, 0x9b, 0x86, 0xbe, 0x86, 0xb6, 0xa0, 0x06, 0x55, - 0x5b, 0x22, 0x97, 0x17, 0x59, 0x19, 0xe5, 0x9a, 0x69, 0xd4, 0x3b, 0x63, 0x50, 0x77, 0xfb, 0x38, - 0x00, 0x00, 0x14, 0x4a, 0x4e, 0xe5, 0x7e, 0x3d, 0x1b, 0x13, 0x1f, 0x00, 0x28, 0x86, 0x0d, 0x5c, - 0x8f, 0xf8, 0x26, 0xd1, 0x0c, 0xc6, 0x10, 0x54, 0x78, 0xb4, 0xc4, 0xc9, 0x7a, 0xe7, 0xb0, 0xf1, - 0x91, 0xc8, 0x4e, 0x69, 0x0f, 0x4d, 0xd6, 0x43, 0x2b, 0x58, 0x3c, 0x66, 0x06, 0x07, 0x9c, 0x09, - 0xed, 0x1c, 0x1d, 0x0a, 0x74, 0x0d, 0xb6, 0xcf, 0x0e, 0x81, 0x13, 0xdd, 0x35, 0x6b, 0x34, 0x0f, - 0x97, 0xc7, 0x1e, 0x1e, 0x1f, 0x81, 0xf8, 0x3f, 0x07, 0xe1, 0x04, 0xa5, 0xd0, 0xff, 0x03, 0x33, - 0xab, 0xe3, 0xbe, 0xaa, 0x3f, 0xf1, 0x26, 0x29, 0x16, 0x61, 0xf8, 0x67, 0x5e, 0x48, 0x9d, 0x6a, - 0x57, 0x3d, 0xd8, 0xcd, 0x89, 0xe1, 0x97, 0x45, 0xeb, 0x22, 0x97, 0x17, 0x59, 0x39, 0xf5, 0xc2, - 0xae, 0xed, 0x18, 0xc3, 0x35, 0x47, 0xf3, 0x82, 0x00, 0x00, 0x0a, 0x8d, 0xee, 0x0c, 0x3f, 0x00, - 0x00, 0x00, 0x02, 0x78, 0xdb, 0x9b, 0xa0, 0xe1, 0xe2, 0x22, 0xb6, 0x06, 0x3f, 0xbe, 0xc7, 0x5f, - 0x62, 0xb0, 0x15, 0x12, 0xec, 0xcf, 0x7c, 0xf8, 0x92, 0x96, 0x5a, 0x4a, 0xbd, 0xf4, 0xb6, 0xc0, - 0xcd, 0xd6, 0x83, 0x6d, 0xbf, 0x39, 0xae, 0x56, 0x6c, 0xf6, 0x06, 0x1e, 0xe0, 0xe8, 0x78, 0xa1, - 0x50, 0x9b, 0x7f, 0xba, 0xa0, 0xc7, 0xed, 0xfa, 0x03, 0xa9, 0x0c, 0x7c, 0xf8, 0x7c, 0x1f, 0x03, - 0xf0, 0x7e, 0x1e, 0x03, 0x0b, 0x87, 0xe4, 0x16, 0x30, 0x8f, 0x2f, 0xf4, 0x6d, 0x82, 0xd1, 0x5e, - 0xd9, 0x3a, 0xe5, 0x38, 0x99, 0x56, 0xe7, 0x76, 0x89, 0x6c, 0x8c, 0x0a, 0x4c, 0xf1, 0x9f, 0x8e, - 0xcb, 0x23, 0x63, 0x97, 0x59, 0x19, 0xe6, 0x32, 0xaf, 0xe4, 0xc5, 0x79, 0xc2, 0x5a, 0xff, 0x30, - 0x6b, 0x09, 0x2f, 0xdb, 0x49, 0x80, 0xa7, 0xdc, 0xb8, 0x00, 0x00, 0x00, 0x0a, 0xb2, 0x5f, 0x67, - 0x82, 0x1a, 0x72, 0xdf, 0xfc, 0x95, 0xe3, 0xa4, 0xcf, 0xa3, 0x4e, 0x2b, 0x05, 0x71, 0x98, 0x3b, - 0x08, 0xcc, 0xd8, 0xe0, 0xa3, 0x34, 0xf9, 0xa9, 0xfd, 0xeb, 0xea, 0xfc, 0x18, 0xb7, 0x98, 0x1a, - 0x74, 0x61, 0xb8, 0xc6, 0xf9, 0x99, 0x25, 0x7d, 0x6b, 0xfd, 0xbf, 0x91, 0x58, 0xef, 0x0d, 0x14, - 0xce, 0x61, 0xc0, 0xfe, 0x07, 0xc0, 0xf8, 0x3e, 0x1f, 0xc8, 0xa0, 0x38, 0x93, 0x48, 0x9e, 0x2f, - 0x32, 0x57, 0x4f, 0x26, 0x9f, 0x8e, 0x99, 0xe5, 0x02, 0xa4, 0x48, 0x5a, 0x3d, 0xf7, 0xe5, 0x54, - 0x79, 0x3b, 0xae, 0xcf, 0x6c, 0x5d, 0x20, 0x8a, 0x5b, 0x23, 0x63, 0x97, 0x59, 0x1a, 0x06, 0x0a, - 0xaf, 0x07, 0x59, 0x7c, 0x19, 0x03, 0xa9, 0x3c, 0x00, 0x14, 0x24, 0x32, 0xde, 0x23, 0x1e, 0x64, - 0x00, 0x00, 0x00, 0x02, 0x78, 0x2b, 0x20, 0xce, 0x2f, 0x68, 0xf5, 0xbf, 0x05, 0xeb, 0x26, 0x55, - 0x29, 0x53, 0x4c, 0x7e, 0x61, 0xf9, 0xad, 0x8f, 0xc2, 0x8a, 0x41, 0x34, 0x8d, 0xc9, 0x28, 0xc6, - 0xf8, 0x8b, 0x08, 0xa3, 0xd4, 0x35, 0x7a, 0x7e, 0x53, 0xa0, 0x52, 0x5d, 0x56, 0xd6, 0xd1, 0xdf, - 0xc9, 0xc4, 0x58, 0x68, 0x78, 0x86, 0xf0, 0xa8, 0x62, 0x31, 0x98, 0xf0, 0xe0, 0xf8, 0x3c, 0x1f, - 0x87, 0x8f, 0x00, 0x18, 0x31, 0x02, 0x8c, 0x85, 0xa0, 0xa6, 0x11, 0x2b, 0x61, 0x36, 0xdf, 0x97, - 0xc1, 0x2b, 0x02, 0xba, 0xad, 0xc2, 0x2b, 0xd3, 0x85, 0xe4, 0x28, 0x75, 0xaa, 0xa9, 0x20, 0x72, - 0x5b, 0x23, 0x63, 0x97, 0x59, 0x1a, 0x16, 0x32, 0xaf, 0xde, 0xcb, 0xe0, 0xab, 0x2b, 0xe8, 0xed, - 0x50, 0xe3, 0x86, 0x47, 0xe5, 0x26, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x4f, 0xb5, 0xa6, - 0x0f, 0x22, 0x99, 0x27, 0x10, 0x6e, 0x3f, 0x2c, 0x8c, 0xa3, 0x70, 0xa0, 0x31, 0x5f, 0xec, 0xd2, - 0x6b, 0x19, 0x59, 0x24, 0x59, 0x31, 0xe6, 0x5c, 0x7b, 0x58, 0x91, 0xf2, 0x1f, 0xe5, 0xef, 0xe1, - 0x69, 0x7c, 0x89, 0x15, 0xd6, 0xf0, 0x90, 0x04, 0xf1, 0x1f, 0x4b, 0x6f, 0xd6, 0x20, 0x0e, 0x9b, - 0xf5, 0xb2, 0x26, 0xce, 0x3c, 0x78, 0xf0, 0x7c, 0x1f, 0x81, 0xf8, 0x1e, 0x0c, 0xc3, 0xb7, 0xec, - 0xcd, 0x3f, 0xa9, 0x4d, 0x80, 0x23, 0x7a, 0x9c, 0x52, 0xec, 0x07, 0xb9, 0xcf, 0x14, 0xfe, 0x1d, - 0x31, 0xaf, 0x97, 0xd8, 0x3c, 0xb4, 0xfc, 0x09, 0xdb, 0x23, 0x63, 0x97, 0x59, 0x1a, 0x16, 0x0a, - 0xaf, 0xde, 0xcb, 0xe0, 0x85, 0xa8, 0x27, 0x59, 0x00, 0x01, 0xbf, 0x14, 0x21, 0x94, 0xb6, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x4a, 0xbe, 0xff, 0x68, 0x3f, 0x33, 0x88, 0xc8, 0xea, 0x78, 0x68, 0x02, - 0x5d, 0x09, 0x28, 0x00, 0x6d, 0x52, 0x33, 0xaf, 0x64, 0x95, 0x5e, 0xa3, 0xed, 0x4c, 0x68, 0x8f, - 0xef, 0x24, 0x88, 0x45, 0xa1, 0x68, 0x3a, 0x1f, 0x25, 0x2d, 0xe7, 0x52, 0x34, 0xd4, 0x24, 0x55, - 0x52, 0x60, 0x48, 0x63, 0xe2, 0x23, 0x1a, 0xca, 0xce, 0x20, 0xc3, 0x87, 0xc1, 0xf8, 0x7c, 0x0f, - 0x06, 0x07, 0x73, 0x81, 0xec, 0x4e, 0x4d, 0x9d, 0x5d, 0x11, 0xfe, 0xf0, 0x4f, 0x32, 0xa4, 0x6e, - 0xc9, 0xf9, 0x47, 0x2a, 0x54, 0x86, 0x1b, 0xa0, 0xa8, 0x64, 0x9e, 0x07, 0x08, 0x36, 0x1b, 0x8c, - 0xdb, 0x23, 0x63, 0x97, 0x59, 0x1a, 0x26, 0x32, 0xae, 0xec, 0x0f, 0x7b, 0x69, 0x00, 0x00, 0x00, - 0x0b, 0x2e, 0x68, 0x94, 0x87, 0x37, 0x64, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xa8, 0xb0, 0x06, - 0x83, 0x1b, 0x2d, 0x62, 0x14, 0xb3, 0x22, 0xb6, 0x22, 0xa3, 0xf7, 0xbe, 0xd0, 0x7c, 0x75, 0xff, - 0x33, 0xcb, 0x97, 0x1d, 0xd4, 0x6e, 0x8d, 0x22, 0xfc, 0xe0, 0x98, 0xba, 0x9a, 0x65, 0x82, 0x5c, - 0x37, 0xe7, 0xd3, 0xa9, 0xdf, 0x0d, 0x69, 0xaa, 0x27, 0xfa, 0x1d, 0x2c, 0x08, 0x75, 0x0c, 0x7b, - 0x01, 0xee, 0x19, 0xe7, 0x0f, 0x87, 0xc1, 0xf8, 0x1f, 0x0f, 0xe6, 0x7d, 0xeb, 0x69, 0xbb, 0xa6, - 0x5f, 0x9f, 0x6a, 0xb2, 0xba, 0xac, 0x84, 0x14, 0xde, 0xe9, 0x6e, 0xd4, 0x31, 0x9a, 0xf3, 0x32, - 0x22, 0xa5, 0xe2, 0xf6, 0x3e, 0x75, 0xe8, 0x4d, 0x4b, 0x23, 0x63, 0x97, 0x59, 0x19, 0xe5, 0xa2, - 0xb0, 0xdc, 0xac, 0x9f, 0x4f, 0x3a, 0xa2, 0xc7, 0x00, 0x02, 0x30, 0x4e, 0x88, 0x25, 0x1c, 0x25, - 0xa7, 0x3a, 0x72, 0xc3, 0xf3, 0x65, 0xb3, 0x05, 0x32, 0x8d, 0x45, 0x6f, 0xba, 0x21, 0x22, 0xb1, - 0x50, 0xd3, 0xf2, 0x53, 0x0e, 0xba, 0xd5, 0x99, 0x07, 0xfb, 0x5b, 0x93, 0x74, 0x90, 0x08, 0xcc, - 0xd2, 0xd9, 0xd4, 0x91, 0x5f, 0x96, 0xef, 0xcd, 0x06, 0xcf, 0x04, 0x0e, 0xa1, 0x73, 0x54, 0xa3, - 0xdc, 0x55, 0xd4, 0xe3, 0xc8, 0xb9, 0xab, 0xb7, 0xf3, 0x38, 0x1d, 0xb3, 0x34, 0x63, 0xe1, 0xf0, - 0x7c, 0x18, 0x3f, 0x6f, 0xe2, 0xc6, 0x1c, 0xbc, 0xca, 0xbb, 0x19, 0x8e, 0x89, 0x8a, 0x83, 0xfa, - 0x2b, 0xac, 0x1e, 0x7f, 0xc1, 0x06, 0x99, 0x54, 0x84, 0x06, 0x90, 0x3e, 0x9e, 0x17, 0xfe, 0x07, - 0xcb, 0x59, 0x68, 0x27, 0x59, 0x1a, 0x26, 0x3a, 0xaf, 0xdd, 0x47, 0xaf, 0x45, 0x72, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xa8, 0x00, 0x00, 0x84, 0xa0, 0x2f, 0xbe, 0x6a, 0xff, - 0x0b, 0xd8, 0xf2, 0x6f, 0x0a, 0x4d, 0x8b, 0xd4, 0xce, 0x90, 0xa5, 0xbe, 0xcd, 0x84, 0x89, 0xc6, - 0xaa, 0xc2, 0xd7, 0xe0, 0xfc, 0xf4, 0x44, 0xb5, 0x78, 0x7e, 0xd7, 0xdb, 0x9e, 0x7e, 0x18, 0x40, - 0xcf, 0x2a, 0xa8, 0x93, 0xa4, 0x57, 0xc8, 0x26, 0xec, 0x8a, 0x1e, 0xb2, 0x61, 0x89, 0xf2, 0xca, - 0xef, 0xdc, 0x63, 0xc3, 0xe1, 0xf8, 0x0f, 0xc1, 0xe3, 0xe1, 0xbd, 0xd3, 0xfc, 0xee, 0x01, 0x57, - 0xce, 0xa2, 0x20, 0x72, 0xac, 0x90, 0xd7, 0xa3, 0xef, 0x4d, 0x93, 0x3d, 0x65, 0xaa, 0x03, 0xb8, - 0xbd, 0x28, 0x81, 0xa4, 0xcd, 0x81, 0x22, 0x7f, 0xdb, 0x59, 0x68, 0x27, 0x59, 0x1a, 0x06, 0x1a, - 0xb6, 0xaf, 0xa6, 0xa4, 0x0f, 0xc8, 0x00, 0x00, 0x00, 0x8e, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x1f, - 0x89, 0x3f, 0x1e, 0xe4, 0xbd, 0x9e, 0x69, 0xe4, 0xc8, 0x3f, 0xa1, 0x01, 0x8b, 0x3c, 0xd4, 0x7b, - 0xa3, 0x0a, 0x2b, 0xac, 0x9c, 0x76, 0x1a, 0x93, 0x9f, 0x3e, 0xe8, 0x3a, 0x5c, 0x1c, 0x61, 0x84, - 0xe2, 0xe5, 0x2a, 0xb2, 0x1c, 0x19, 0x45, 0x8c, 0xe1, 0x2b, 0x4f, 0xde, 0xc3, 0xfd, 0x59, 0x25, - 0x92, 0x59, 0xc8, 0xef, 0x02, 0xff, 0x86, 0xd5, 0x7e, 0x61, 0x71, 0x9c, 0x3e, 0x1f, 0x07, 0xe0, - 0x7e, 0x1c, 0x61, 0xc4, 0xe7, 0xf9, 0x13, 0xe5, 0x97, 0x8c, 0x19, 0xcf, 0x4b, 0xdd, 0xca, 0xa0, - 0x45, 0xc7, 0x42, 0x81, 0x85, 0xdb, 0x2c, 0x7b, 0x2c, 0x93, 0x4d, 0xbe, 0x0f, 0xab, 0x60, 0x66, - 0x5b, 0x59, 0x68, 0x27, 0x59, 0x1a, 0x05, 0xfa, 0x69, 0x22, 0xde, 0xdd, 0xd2, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0xcd, 0x03, 0xa3, 0x66, 0x74, 0x51, 0x0c, 0xfd, - 0x96, 0x0e, 0xc4, 0xa1, 0xa5, 0x02, 0x16, 0x3e, 0x54, 0xdc, 0x7b, 0xbf, 0xd1, 0x7f, 0x34, 0xe2, - 0xfc, 0x41, 0x33, 0xf9, 0xe8, 0x4c, 0x0a, 0x66, 0xfb, 0x40, 0x24, 0xd7, 0x1a, 0x5e, 0x80, 0xa4, - 0xa8, 0x60, 0x8b, 0x47, 0x99, 0xd3, 0xa4, 0x7c, 0x01, 0x58, 0x1a, 0x51, 0x8b, 0x43, 0xba, 0xb4, - 0x0a, 0x01, 0x31, 0x8f, 0x0f, 0x0f, 0xc0, 0xf8, 0x1f, 0x87, 0x9f, 0x0e, 0x62, 0x3d, 0xe5, 0x1b, - 0x23, 0x29, 0x1b, 0x32, 0x0d, 0x49, 0xc9, 0x8c, 0x2a, 0x31, 0x17, 0x14, 0x1d, 0x7b, 0x26, 0x54, - 0x07, 0x46, 0xb5, 0x00, 0x2f, 0x97, 0x96, 0x00, 0x5b, 0x59, 0x68, 0x27, 0x59, 0x19, 0xf6, 0x32, - 0xaf, 0xdd, 0x4a, 0x8e, 0x8a, 0x00, 0x00, 0x04, 0x16, 0x72, 0x00, 0x00, 0x00, 0x01, 0x3c, 0x65, - 0x00, 0x00, 0x06, 0xc2, 0x8d, 0x61, 0x32, 0xec, 0x63, 0x9f, 0xd5, 0x3b, 0x41, 0x19, 0x48, 0x92, - 0x5b, 0x79, 0xdf, 0x4e, 0xe0, 0x56, 0xab, 0x10, 0xad, 0xb6, 0x70, 0x26, 0xd8, 0x3b, 0x04, 0x1a, - 0x26, 0x3f, 0x1e, 0xfb, 0x61, 0x9b, 0x2c, 0xcd, 0xc3, 0x1a, 0x45, 0xbe, 0x86, 0xb5, 0x80, 0xbf, - 0x58, 0xe5, 0xf1, 0xc4, 0xfa, 0x70, 0xc3, 0x28, 0xe1, 0x66, 0xe6, 0x3e, 0x1f, 0x1f, 0x1f, 0x07, - 0xc1, 0x86, 0x07, 0x3f, 0x01, 0x4a, 0x24, 0x08, 0xb1, 0x9d, 0x34, 0x0f, 0xd4, 0x9a, 0x67, 0xa5, - 0x2c, 0x41, 0xcc, 0xd6, 0xb1, 0x4d, 0xb6, 0x30, 0x9e, 0x87, 0x1b, 0x81, 0x9b, 0x8a, 0x1b, 0x1f, - 0xdb, 0x59, 0x68, 0x27, 0x59, 0x1a, 0x06, 0x2a, 0x69, 0xab, 0xe1, 0x95, 0x02, 0xf7, 0x56, 0xf1, - 0x00, 0x00, 0x6f, 0x0a, 0x1d, 0x00, 0x00, 0x00, 0x85, 0x49, 0x3a, 0xc8, 0xa2, 0xa7, 0xd2, 0x5a, - 0xa9, 0xdf, 0xe8, 0x8c, 0x63, 0x9f, 0xa4, 0x30, 0xad, 0x60, 0xc9, 0xeb, 0x68, 0x08, 0x85, 0xc7, - 0x58, 0x80, 0x08, 0xa1, 0xb6, 0x36, 0xd8, 0xe9, 0x6a, 0x7b, 0x0b, 0xc1, 0xd6, 0x5e, 0x3f, 0x82, - 0x55, 0x55, 0x9c, 0x24, 0x89, 0x0d, 0x17, 0xf5, 0x4e, 0xf7, 0x62, 0x1a, 0x50, 0xb6, 0x11, 0xe5, - 0x96, 0xa1, 0xea, 0xc7, 0xf3, 0xc7, 0x87, 0xc3, 0xe0, 0xf8, 0x3e, 0x0f, 0x1f, 0x71, 0x01, 0x0a, - 0x69, 0x82, 0xa7, 0xe9, 0x15, 0xa2, 0xb7, 0xd0, 0x26, 0x0c, 0x4d, 0x9f, 0xd9, 0x37, 0x1f, 0x09, - 0x3f, 0x68, 0x19, 0xcc, 0xf5, 0xec, 0x70, 0x2b, 0x4b, 0x59, 0x68, 0x27, 0x59, 0x19, 0xe6, 0x3a, - 0xaf, 0xa6, 0xc8, 0x17, 0x7f, 0x00, 0x00, 0x00, 0x17, 0x06, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x90, 0x4d, 0x7e, 0x2d, 0x3b, 0x28, 0x83, 0xe1, 0x07, 0x76, 0x76, 0xcf, 0xba, 0x15, 0x34, - 0xb2, 0x39, 0x94, 0xdb, 0x89, 0xe9, 0x6d, 0x1a, 0xaf, 0xd6, 0x16, 0xa8, 0x64, 0x82, 0xb0, 0x29, - 0x5e, 0x24, 0xdd, 0x6b, 0x36, 0x83, 0xba, 0x3a, 0xf6, 0x36, 0x7a, 0x39, 0xd7, 0x81, 0xb2, 0x27, - 0xaf, 0x4c, 0x76, 0xc9, 0x2d, 0x17, 0x4c, 0x66, 0x99, 0x8d, 0x36, 0x38, 0xf0, 0xf8, 0x1f, 0x83, - 0xe1, 0xe0, 0xf8, 0x50, 0x30, 0xfe, 0x6c, 0x6f, 0x1c, 0x5a, 0x7b, 0x2e, 0x88, 0x59, 0x3b, 0xec, - 0xca, 0xde, 0x54, 0x84, 0xc2, 0x74, 0xc8, 0xa9, 0x40, 0x21, 0x70, 0x1d, 0x4f, 0xb4, 0xea, 0x06, - 0xcb, 0x59, 0x68, 0x27, 0x59, 0x19, 0xf6, 0x0a, 0xaf, 0xdd, 0x47, 0xae, 0x79, 0x00, 0x1f, 0x83, - 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0xdb, 0x11, 0x71, 0xcf, 0xbd, - 0x91, 0x1c, 0x8e, 0xc5, 0x83, 0xc4, 0xe6, 0x94, 0xef, 0x6e, 0x0e, 0x9e, 0x6a, 0x42, 0xa9, 0x2a, - 0x2a, 0xd0, 0x12, 0xae, 0x29, 0x75, 0xa5, 0xbf, 0xd1, 0xa3, 0x08, 0x7e, 0xee, 0xfc, 0xaa, 0x6b, - 0x9e, 0xfa, 0x66, 0x0f, 0x9d, 0xef, 0x40, 0x26, 0xe0, 0x10, 0x37, 0x20, 0x7b, 0x47, 0x23, 0xa4, - 0x2a, 0xb7, 0x61, 0xc7, 0x0f, 0x0f, 0x83, 0xe0, 0x7c, 0x0f, 0x83, 0xc0, 0xfd, 0xbe, 0xb6, 0xff, - 0xfa, 0x50, 0x5b, 0x22, 0x16, 0xc5, 0x40, 0x94, 0x44, 0x34, 0x24, 0x3b, 0xc8, 0xa3, 0x46, 0x42, - 0xa9, 0xf3, 0xb0, 0x22, 0x4b, 0xa8, 0x02, 0x1d, 0x4b, 0x59, 0x68, 0x27, 0x59, 0x19, 0xe6, 0x22, - 0xaf, 0xdd, 0x47, 0x5c, 0xb0, 0x00, 0x00, 0x00, 0x09, 0xa7, 0x33, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x51, 0x3a, 0x47, 0x73, 0x14, 0xdc, 0x14, 0x55, 0x01, 0xad, 0xc9, 0x84, 0xf5, 0x04, 0xca, - 0x57, 0xf3, 0x4d, 0xa5, 0x4e, 0x52, 0x7c, 0x3c, 0xb4, 0xac, 0x71, 0xe4, 0x05, 0x1f, 0x32, 0xd5, - 0x66, 0xee, 0x2e, 0x65, 0x11, 0x2b, 0xf8, 0x17, 0x9f, 0x1c, 0x31, 0xc1, 0x45, 0x92, 0xf7, 0xec, - 0x52, 0x11, 0xaf, 0xf8, 0x38, 0xe2, 0x4f, 0x46, 0x0e, 0xa7, 0x7d, 0x8c, 0x61, 0xe0, 0xf0, 0x1e, - 0x1f, 0x1f, 0x80, 0x20, 0x74, 0x20, 0x33, 0xd0, 0x97, 0xf4, 0x65, 0xe5, 0x0f, 0x72, 0x9a, 0xf8, - 0x6a, 0x30, 0x93, 0x48, 0x44, 0x87, 0x45, 0x57, 0x15, 0x89, 0x56, 0xf2, 0x61, 0x92, 0xcb, 0x2f, - 0x5b, 0x59, 0x68, 0x27, 0x59, 0x19, 0xe6, 0x3a, 0xb0, 0xdc, 0x57, 0x1e, 0x7c, 0x00, 0x00, 0x3f, - 0x74, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x39, 0xc0, 0xa6, 0x1f, 0xdd, 0xdd, 0xf7, - 0x8b, 0x46, 0x51, 0xe9, 0xbf, 0x18, 0x60, 0x29, 0x50, 0x4f, 0x93, 0x93, 0xcd, 0x14, 0x7b, 0x2a, - 0x53, 0x8f, 0xca, 0x5a, 0xa7, 0xe9, 0xb6, 0xb2, 0xa0, 0x81, 0x52, 0x7a, 0x5d, 0x89, 0xfd, 0xde, - 0x59, 0x8a, 0x16, 0xa5, 0xe5, 0x2c, 0x17, 0xb3, 0x89, 0xde, 0x88, 0x0c, 0xd6, 0xbe, 0x89, 0x47, - 0xdd, 0x4d, 0x03, 0xe0, 0x70, 0xf8, 0xf8, 0x7c, 0x3c, 0x78, 0xf7, 0x83, 0xda, 0x69, 0x3e, 0x11, - 0xbc, 0x3f, 0x2e, 0x0e, 0x4e, 0x55, 0x11, 0xdd, 0x4a, 0xd8, 0xd2, 0xbc, 0xe0, 0x9e, 0x70, 0xf9, - 0x06, 0x5c, 0x0d, 0xe9, 0x1a, 0x5c, 0x8a, 0xfd, 0x5b, 0x53, 0xe8, 0xa7, 0x59, 0x1a, 0x36, 0x3a, - 0xb6, 0xae, 0x86, 0x8b, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xaf, 0x71, 0xb2, 0x01, 0x10, 0x2f, 0x58, 0xa8, 0xda, 0xb2, 0x6b, 0xea, 0x17, 0x82, 0x2a, 0xbc, - 0x17, 0x6c, 0xb8, 0xd7, 0x60, 0xec, 0xac, 0x27, 0x51, 0x63, 0xbd, 0x84, 0xe8, 0x16, 0x96, 0xd8, - 0x10, 0x67, 0xce, 0x90, 0xe4, 0x82, 0x54, 0x9c, 0xab, 0x44, 0x53, 0x78, 0x5c, 0xb3, 0x3e, 0x1f, - 0xf6, 0x95, 0x2a, 0x8a, 0x8f, 0xed, 0x7d, 0x66, 0x2a, 0xf5, 0xb8, 0xe3, 0xe1, 0xc7, 0xc7, 0x1f, - 0x1e, 0x1e, 0x38, 0xfe, 0x01, 0x07, 0x40, 0x10, 0x17, 0x93, 0xba, 0x8e, 0x86, 0xb0, 0x0f, 0x29, - 0x1f, 0xd8, 0x67, 0x5b, 0x07, 0xb3, 0x8b, 0x89, 0x4e, 0xbe, 0xde, 0xc6, 0xad, 0xf3, 0x18, 0x25, - 0xdb, 0x53, 0xe8, 0xa7, 0x59, 0x19, 0xf6, 0x3a, 0x69, 0xd4, 0x3d, 0x80, 0x5f, 0x44, 0xf0, 0x1b, - 0x03, 0x78, 0x03, 0xdd, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x9c, 0x1f, 0xba, 0x9f, 0x49, 0x68, - 0x95, 0xbb, 0xa2, 0x6e, 0x80, 0xcc, 0x35, 0xdc, 0xff, 0xc9, 0x1f, 0x10, 0x2c, 0xdc, 0x79, 0x16, - 0x99, 0xef, 0xf3, 0xd4, 0x9a, 0x9a, 0x00, 0x44, 0x82, 0x10, 0x10, 0x24, 0x3a, 0xd1, 0x86, 0x0e, - 0x4b, 0xa7, 0xb0, 0x31, 0x0d, 0xbb, 0x79, 0xd0, 0xc0, 0xe9, 0x30, 0xf2, 0x9f, 0xcc, 0x2a, 0x67, - 0xad, 0xec, 0x1e, 0x0f, 0x81, 0xf1, 0xf8, 0x7c, 0x1c, 0x3c, 0x1e, 0x1f, 0x1c, 0x00, 0x02, 0x87, - 0x80, 0xd1, 0x3c, 0xd8, 0x47, 0xbf, 0xc9, 0xec, 0x76, 0x76, 0xe5, 0xcd, 0x14, 0x99, 0x89, 0xe5, - 0x7a, 0xd2, 0x9b, 0x22, 0xc2, 0xc2, 0x13, 0xc3, 0x4b, 0x53, 0xe8, 0xa7, 0x59, 0x19, 0xe6, 0x32, - 0xaf, 0xa6, 0xca, 0x13, 0x93, 0x00, 0xeb, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, 0x80, 0x9d, 0xf7, 0xc3, 0x46, 0x0b, 0x53, 0x53, 0x73, 0x89, 0xc2, 0x97, 0x55, - 0x72, 0x5c, 0xff, 0x9a, 0xdc, 0x02, 0xf7, 0xf0, 0xcf, 0x21, 0x75, 0x66, 0xe6, 0x6c, 0x3b, 0xba, - 0x79, 0x7c, 0xcc, 0x09, 0x13, 0xba, 0xb1, 0x7e, 0x92, 0x48, 0x08, 0xfb, 0xcc, 0x16, 0xb3, 0xbf, - 0x95, 0x42, 0x12, 0x23, 0x7b, 0x8b, 0xc4, 0xa1, 0xe7, 0x05, 0x3f, 0xc7, 0x86, 0x1c, 0x3c, 0x7e, - 0x1f, 0x0f, 0x0f, 0x0c, 0x0f, 0x37, 0xcb, 0xcd, 0x3b, 0x4b, 0x74, 0x4e, 0xa6, 0x1f, 0x4b, 0x8a, - 0x9e, 0xfb, 0x19, 0x56, 0xfd, 0xc8, 0x31, 0x86, 0x38, 0xf0, 0x61, 0xef, 0x30, 0x56, 0x57, 0xb9, - 0xcb, 0x53, 0xe8, 0xa7, 0x59, 0x19, 0xf6, 0x3a, 0xaf, 0xa6, 0xc8, 0x17, 0x7f, 0x00, 0x00, 0x00, - 0x00, 0x05, 0x62, 0x75, 0x00, 0x00, 0x69, 0x8c, 0xb5, 0x9f, 0x6d, 0x91, 0x16, 0xec, 0x45, 0x2d, - 0xd7, 0x21, 0x0a, 0xd3, 0x74, 0x15, 0x95, 0x67, 0x89, 0x8f, 0xb7, 0x07, 0x97, 0xb4, 0x98, 0x68, - 0x61, 0xec, 0x05, 0xc5, 0x91, 0x0b, 0x6f, 0x0f, 0xd6, 0x08, 0xbf, 0x6d, 0x57, 0x68, 0xb3, 0x3e, - 0xd6, 0x22, 0x91, 0x89, 0x3d, 0xd3, 0xcf, 0x0f, 0x02, 0x68, 0x0c, 0xc5, 0xd9, 0x61, 0xb5, 0x6c, - 0xa3, 0x68, 0x38, 0xc3, 0xc3, 0x83, 0xe7, 0x83, 0xc3, 0x8c, 0x1d, 0xc9, 0xc7, 0x32, 0x2b, 0x70, - 0x8e, 0x87, 0x12, 0x53, 0x43, 0x41, 0x24, 0xe9, 0x59, 0x03, 0xa3, 0xc4, 0x4b, 0xf9, 0x63, 0xd3, - 0x86, 0x6f, 0x28, 0x60, 0xe1, 0x17, 0xdb, 0x42, 0x0b, 0x53, 0xe8, 0xa7, 0x59, 0x3a, 0x16, 0x0a, - 0xae, 0xec, 0x11, 0x26, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x40, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0xbc, 0x19, 0x14, 0x6e, 0x12, 0xa1, 0x3a, 0xba, 0x04, 0x5e, 0xea, 0x69, 0x8d, - 0xb1, 0x09, 0xf8, 0xfb, 0x64, 0x6a, 0x78, 0x8d, 0x47, 0x40, 0x96, 0x40, 0xa1, 0x65, 0x8c, 0x09, - 0x2a, 0xa1, 0x36, 0x57, 0x11, 0x6e, 0x99, 0x4b, 0x31, 0x58, 0x23, 0x85, 0x8e, 0x38, 0x0f, 0x57, - 0x47, 0xee, 0x44, 0x32, 0x6f, 0x04, 0x5c, 0xbf, 0xd2, 0xf1, 0xf8, 0x3e, 0x1f, 0x03, 0x87, 0x1e, - 0x1f, 0x07, 0x83, 0x8e, 0x1f, 0xfe, 0xe2, 0x0b, 0xe9, 0x36, 0x03, 0xae, 0x74, 0xa7, 0x7f, 0x11, - 0x66, 0xc6, 0x9a, 0xe9, 0xdc, 0x9c, 0x99, 0xba, 0xd6, 0x42, 0xb8, 0x3a, 0x9e, 0x95, 0xee, 0x41, - 0xcb, 0x53, 0xe8, 0xa7, 0x59, 0x19, 0xf6, 0x3a, 0xb0, 0xd2, 0xbf, 0x90, 0x28, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x01, 0x4f, 0x00, 0x03, 0x1f, 0x9c, 0x00, 0x00, 0x00, 0x24, 0x0d, 0x60, 0x8b, 0x80, - 0x3b, 0x7a, 0x02, 0x8e, 0xea, 0x5e, 0xa6, 0xc9, 0x36, 0x07, 0xac, 0xae, 0x7e, 0x91, 0xd7, 0x6e, - 0xdc, 0xa1, 0x54, 0xc9, 0x75, 0x9c, 0xce, 0x7d, 0x7d, 0x04, 0xc1, 0xd1, 0x71, 0x1c, 0xbf, 0x8c, - 0x27, 0xb8, 0x20, 0xc9, 0xba, 0xa3, 0x8f, 0xfa, 0x44, 0xc3, 0x2f, 0x0a, 0xb3, 0x56, 0xa0, 0xab, - 0x6e, 0x1f, 0xc7, 0x8e, 0x3e, 0x1e, 0xf8, 0xf0, 0xf8, 0x78, 0x70, 0x0f, 0xfe, 0x78, 0x15, 0xb8, - 0xcf, 0x1d, 0xb9, 0x69, 0x24, 0x7a, 0x50, 0x85, 0x62, 0x26, 0xf7, 0x93, 0x2b, 0x00, 0x75, 0x4f, - 0x16, 0xdc, 0x23, 0x06, 0x99, 0xb0, 0x06, 0x1f, 0xdb, 0x53, 0xe8, 0xa7, 0x59, 0x1a, 0x06, 0x32, - 0xaf, 0xde, 0xcb, 0x94, 0xcb, 0x00, 0x12, 0x26, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x28, 0xc0, 0x55, 0xea, 0xd5, 0x22, 0xd8, 0x60, 0xe5, 0xa1, 0xab, 0x14, 0x67, - 0x2f, 0x34, 0x1c, 0x63, 0x68, 0xe1, 0x58, 0x09, 0x83, 0x4d, 0x6d, 0x27, 0xaa, 0xa9, 0x2a, 0x23, - 0x93, 0xea, 0x4e, 0x52, 0x55, 0xd3, 0x9e, 0x04, 0xf0, 0x69, 0xa2, 0x55, 0xa1, 0x20, 0x84, 0xe8, - 0xed, 0x95, 0x73, 0x9a, 0x67, 0x25, 0x84, 0xc8, 0x8e, 0x7e, 0x0f, 0x83, 0xf0, 0x78, 0xf0, 0xf3, - 0xc3, 0xc7, 0x04, 0x1d, 0x3a, 0xbf, 0xfe, 0xcd, 0xd6, 0x67, 0xb0, 0xfb, 0x4b, 0x60, 0x83, 0x17, - 0x32, 0x8f, 0x84, 0xcb, 0xf4, 0xe2, 0xec, 0x57, 0xe9, 0xf4, 0xd9, 0x00, 0x50, 0x34, 0xc4, 0x8f, - 0xeb, 0x53, 0xe8, 0xa7, 0x59, 0x1a, 0x26, 0x32, 0xae, 0xec, 0x11, 0x27, 0x19, 0xd0, 0x62, 0x4b, - 0x9f, 0x92, 0x14, 0xbc, 0x07, 0x1c, 0xcd, 0x60, 0x00, 0x3f, 0x57, 0x72, 0x78, 0xb6, 0x2b, 0xb9, - 0x23, 0xf9, 0xf4, 0x88, 0x94, 0xe5, 0xdd, 0x61, 0xef, 0x21, 0x28, 0x38, 0x79, 0x91, 0x0a, 0xcb, - 0x97, 0xa2, 0x5d, 0xa7, 0x18, 0x3b, 0x3a, 0x52, 0xac, 0xfe, 0xc5, 0x69, 0x48, 0x07, 0xf0, 0xa5, - 0xf4, 0x06, 0xed, 0xbb, 0x6c, 0x5a, 0xae, 0x56, 0x4b, 0x1e, 0xf1, 0x21, 0xc2, 0xf6, 0xb5, 0xc8, - 0xfa, 0x2f, 0xa3, 0x9c, 0xe1, 0xe3, 0xe7, 0xb0, 0xb1, 0x50, 0xdc, 0xe2, 0x49, 0x0b, 0x91, 0x08, - 0xdc, 0x4d, 0x8b, 0xf2, 0xb8, 0x83, 0xcc, 0x45, 0x26, 0xb3, 0xc9, 0x08, 0x1c, 0x71, 0xe9, 0x75, - 0xff, 0x16, 0x10, 0x2e, 0x83, 0x32, 0x45, 0xc4, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0xa5, 0xca, - 0x69, 0x22, 0x06, 0xbe, 0xb8, 0x00, 0x00, 0x55, 0x5b, 0xef, 0x00, 0x00, 0x00, 0x65, 0x5b, 0x53, - 0x00, 0x00, 0x00, 0x01, 0xe4, 0x3c, 0x66, 0x44, 0xb7, 0x31, 0x12, 0x8e, 0xf8, 0x46, 0x36, 0x48, - 0xa3, 0x84, 0xae, 0x9a, 0xde, 0xcf, 0xbe, 0x67, 0xa1, 0x24, 0x81, 0xa9, 0x4c, 0xfd, 0x11, 0x1a, - 0xca, 0xbb, 0x75, 0x5e, 0x95, 0x2b, 0xda, 0xc3, 0xd6, 0x2e, 0x7c, 0xc1, 0x9a, 0x98, 0x7a, 0xf9, - 0xe6, 0xb3, 0x4d, 0x7e, 0x50, 0xd3, 0x9c, 0x0e, 0x8d, 0xa1, 0xe2, 0x87, 0xcf, 0xc7, 0xc3, 0xc3, - 0xc0, 0xf0, 0x79, 0xff, 0x33, 0xfa, 0x2b, 0xe2, 0x2e, 0x7c, 0xcd, 0xee, 0x04, 0xd5, 0xae, 0xd3, - 0x49, 0x0a, 0x97, 0x36, 0x42, 0x31, 0xd5, 0xcc, 0xa3, 0xe5, 0x35, 0xcc, 0x6a, 0xe0, 0xfb, 0x61, - 0x5b, 0x53, 0xe8, 0xa7, 0x59, 0x19, 0xe6, 0x22, 0xb0, 0xd2, 0xc2, 0xb5, 0x9b, 0x5e, 0x0d, 0x49, - 0xbb, 0x31, 0x14, 0xd0, 0x16, 0x61, 0xd1, 0x9a, 0x00, 0x16, 0x0e, 0x09, 0x69, 0x56, 0xae, 0x13, - 0x2b, 0x91, 0x7b, 0xe0, 0x64, 0x29, 0xff, 0xfd, 0xdc, 0x02, 0x5e, 0xde, 0xc4, 0x61, 0x77, 0x7b, - 0xe0, 0xe9, 0xcf, 0xeb, 0x5e, 0x2d, 0x46, 0x50, 0x6c, 0xd3, 0x95, 0xd8, 0x14, 0x31, 0xc5, 0x72, - 0xce, 0xc4, 0xde, 0x03, 0x51, 0xb6, 0xd0, 0xd5, 0xc2, 0x7f, 0x5d, 0xa8, 0xcc, 0x34, 0x3c, 0xad, - 0x33, 0x75, 0x5a, 0x65, 0x96, 0x22, 0x18, 0x78, 0xf1, 0x80, 0x42, 0x04, 0xf5, 0x2f, 0x00, 0xda, - 0x4e, 0x5f, 0x29, 0xbb, 0xeb, 0x49, 0x53, 0x4c, 0x90, 0x29, 0x99, 0x37, 0xe0, 0x2c, 0xe3, 0xdc, - 0x40, 0x0a, 0x29, 0xc4, 0x2b, 0x81, 0x1a, 0x64, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0xb6, 0x32, - 0x00, 0x00, 0x7b, 0x8a, 0x4f, 0xb1, 0xcd, 0x72, 0xeb, 0x2f, 0x0c, 0x8d, 0x21, 0x4d, 0xce, 0xba, - 0xa1, 0x37, 0x98, 0x35, 0xd6, 0x85, 0xed, 0x39, 0x22, 0x9c, 0x85, 0x49, 0x87, 0x8a, 0xcf, 0x4c, - 0xab, 0x48, 0x69, 0x6b, 0xbc, 0x6a, 0x38, 0x4e, 0xe0, 0x93, 0x9b, 0xe2, 0x8d, 0x23, 0x54, 0x0e, - 0x4b, 0x6f, 0x17, 0x7d, 0x05, 0x5a, 0xc2, 0x02, 0x5a, 0x10, 0x0f, 0x6e, 0xf2, 0x94, 0x81, 0x7a, - 0x99, 0xc7, 0x9b, 0xe5, 0xff, 0xf9, 0xc7, 0x27, 0x37, 0x80, 0x2a, 0x98, 0x98, 0x71, 0xce, 0x07, - 0x0d, 0x5d, 0x01, 0xdf, 0x03, 0x24, 0xc2, 0xd0, 0x47, 0xab, 0x5c, 0xb6, 0x57, 0x2f, 0x08, 0xb8, - 0x6c, 0xbf, 0xef, 0x56, 0x4d, 0x98, 0xc7, 0x1c, 0x78, 0x1f, 0x03, 0xf8, 0x38, 0x3e, 0x11, 0x2a, - 0xc8, 0x34, 0x8f, 0xe7, 0x79, 0x09, 0x95, 0x9a, 0xaf, 0xa6, 0xca, 0xa0, 0xc4, 0x9c, 0x8d, 0xe3, - 0xce, 0xbf, 0xbc, 0x6a, 0x2e, 0xe0, 0xbe, 0xbd, 0xa2, 0x3a, 0x6d, 0x84, 0x19, 0x2d, 0x7e, 0xe4, - 0x7a, 0x69, 0x85, 0x11, 0xc4, 0x7e, 0x27, 0x96, 0x4a, 0x91, 0x96, 0x58, 0x21, 0xa8, 0x30, 0xe8, - 0xd4, 0x07, 0xe5, 0x04, 0x9c, 0x80, 0x4d, 0x07, 0x26, 0x1f, 0xcf, 0x74, 0xc9, 0x1e, 0x0a, 0xf9, - 0xe9, 0x4f, 0x23, 0xd1, 0x6f, 0x46, 0x7f, 0x5a, 0x5a, 0x27, 0x9e, 0x9b, 0x72, 0xca, 0xea, 0x6f, - 0x38, 0x4b, 0x43, 0x70, 0xc3, 0xc3, 0x83, 0xc3, 0x9b, 0x60, 0x7e, 0x06, 0xb3, 0xc4, 0x53, 0x16, - 0x70, 0xf3, 0xb0, 0x8d, 0x02, 0x50, 0x97, 0x83, 0x55, 0x2d, 0x4c, 0xbc, 0xc8, 0x1b, 0x25, 0xb6, - 0xdc, 0x79, 0x75, 0xfc, 0xf3, 0x32, 0xcb, 0x1a, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x75, 0xaa, - 0xb0, 0xd2, 0xbf, 0x90, 0x50, 0xd0, 0xf0, 0x42, 0x44, 0x70, 0x24, 0x60, 0x1a, 0x2c, 0xbd, 0x2a, - 0x5f, 0x4b, 0x37, 0x70, 0x95, 0x79, 0xff, 0x07, 0xad, 0x00, 0x68, 0x44, 0xfe, 0xde, 0x89, 0x98, - 0x3c, 0x3d, 0x96, 0x3c, 0x08, 0x2d, 0x2f, 0xfc, 0xa9, 0xe7, 0xce, 0x1d, 0x91, 0x3e, 0xb1, 0x89, - 0xdc, 0x7d, 0xbd, 0x2f, 0x0d, 0x56, 0x15, 0x6c, 0xde, 0x0e, 0x57, 0x29, 0x67, 0x78, 0x41, 0xfb, - 0xf7, 0x2d, 0xea, 0xab, 0x5f, 0x85, 0xce, 0x39, 0xd1, 0x9d, 0xfb, 0x96, 0xec, 0x70, 0xf8, 0x61, - 0xe1, 0x9d, 0x87, 0xa3, 0x56, 0x63, 0x78, 0x7b, 0x40, 0x6b, 0x5f, 0x1e, 0x7e, 0x33, 0x23, 0x0c, - 0xd9, 0xc4, 0x2d, 0xf2, 0x0d, 0x32, 0x15, 0x7c, 0x10, 0xef, 0xd1, 0x52, 0xd8, 0x22, 0x2b, 0xd7, - 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x86, 0x02, 0x00, 0x00, 0x00, 0x5c, 0x4f, 0x5c, 0x9d, 0xdd, - 0x23, 0xea, 0x8f, 0x47, 0xb9, 0xed, 0xc2, 0x20, 0x63, 0x74, 0x8e, 0x6e, 0x88, 0x0f, 0xdf, 0x76, - 0x0a, 0xac, 0x64, 0xc4, 0x55, 0x19, 0x4a, 0xb7, 0x7a, 0xeb, 0xf9, 0xa0, 0xcf, 0x58, 0x59, 0xd6, - 0xe8, 0xc0, 0xee, 0x3b, 0x7e, 0xb1, 0x30, 0x26, 0x9b, 0x33, 0x1a, 0x56, 0xc7, 0x15, 0xe5, 0xa2, - 0x7c, 0xf3, 0x54, 0xff, 0x8f, 0x7a, 0xd6, 0xf0, 0x84, 0x6c, 0xeb, 0xcd, 0xe1, 0x80, 0x5e, 0x45, - 0x8b, 0x8c, 0x2e, 0x9e, 0x71, 0xe3, 0xc3, 0x1f, 0xb2, 0x18, 0x0e, 0x45, 0x1a, 0x22, 0x77, 0xcf, - 0x03, 0x41, 0xd7, 0x84, 0x37, 0x88, 0x4f, 0xf3, 0x87, 0xec, 0x9b, 0xd1, 0x0d, 0x1b, 0xab, 0x01, - 0x8f, 0x81, 0xf8, 0x3f, 0x03, 0xe1, 0xe7, 0x17, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x09, 0xb5, 0x9a, - 0xae, 0xed, 0x19, 0x12, 0xa7, 0xec, 0xb5, 0x78, 0xea, 0x3c, 0x5f, 0x3c, 0x65, 0x32, 0xc1, 0x96, - 0x17, 0x53, 0xb5, 0x8a, 0xc8, 0xa4, 0xbc, 0x00, 0x16, 0xff, 0x66, 0xad, 0x27, 0x95, 0x20, 0x99, - 0xe4, 0x92, 0x8e, 0x0d, 0x73, 0x94, 0xbe, 0xed, 0x8b, 0xb9, 0x83, 0xa8, 0x30, 0xc6, 0xc3, 0x6e, - 0xb3, 0xa6, 0xe5, 0x1b, 0x7a, 0xd0, 0x90, 0x5a, 0x70, 0x05, 0x7e, 0x13, 0xb0, 0xb5, 0xf4, 0x50, - 0xa3, 0xb3, 0x42, 0x45, 0x57, 0x1f, 0x3c, 0x4d, 0x1b, 0xbd, 0xa8, 0x8c, 0x65, 0xb7, 0x27, 0x07, - 0x07, 0x8f, 0x85, 0x0f, 0x51, 0x5c, 0x2d, 0x32, 0x33, 0x61, 0x39, 0x8b, 0x92, 0x23, 0x9e, 0x2f, - 0xa2, 0x19, 0x4c, 0x65, 0xb1, 0xc5, 0xdb, 0x79, 0x58, 0x18, 0x2a, 0x26, 0x3e, 0x81, 0x44, 0x63, - 0xc8, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x96, 0x0a, 0x00, 0x00, 0x00, 0x5c, 0x4f, 0x57, 0xe1, 0xe3, - 0xbc, 0x37, 0x2a, 0xaf, 0x44, 0x7a, 0xf6, 0x6e, 0x08, 0x0a, 0x68, 0xf8, 0xea, 0x64, 0x83, 0x2c, - 0xd9, 0xce, 0x39, 0xce, 0xa9, 0x4e, 0xd4, 0xae, 0x45, 0xe9, 0x30, 0xab, 0x44, 0xb3, 0x4e, 0xa0, - 0xde, 0x8c, 0x5b, 0x17, 0x8d, 0xd0, 0xb8, 0xcf, 0x93, 0xd4, 0xa8, 0x7e, 0xbc, 0x40, 0x1c, 0x52, - 0x3b, 0x05, 0x69, 0x0a, 0x0f, 0xba, 0x99, 0xc6, 0x07, 0xce, 0x7a, 0xc5, 0x00, 0x49, 0x8c, 0xf9, - 0x57, 0xce, 0x01, 0x47, 0x1e, 0x38, 0x78, 0xf0, 0x3d, 0xd5, 0x46, 0x8b, 0x19, 0x01, 0xd8, 0xdd, - 0xe5, 0x1a, 0xac, 0x3b, 0xff, 0x51, 0xb2, 0x89, 0x2e, 0x41, 0xfc, 0x4f, 0xdd, 0x9b, 0x88, 0x1c, - 0x3f, 0x01, 0xf8, 0x1e, 0x0f, 0x87, 0x8e, 0x11, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x09, 0x95, 0xda, - 0xb0, 0xd2, 0xc2, 0xb4, 0xcd, 0x00, 0x67, 0xfa, 0x11, 0xab, 0x00, 0x06, 0x12, 0x0c, 0xca, 0x82, - 0x9f, 0xb2, 0x61, 0x98, 0x46, 0x1f, 0xb7, 0x04, 0x6c, 0x91, 0x49, 0xa9, 0xd4, 0xbe, 0x87, 0xf6, - 0xdd, 0xf6, 0x4c, 0x82, 0x4f, 0x2b, 0xea, 0xbf, 0x67, 0x6b, 0x86, 0x96, 0x4e, 0x33, 0x2a, 0xbb, - 0x52, 0x29, 0x73, 0x7d, 0x2b, 0x2d, 0x15, 0xb3, 0x84, 0x68, 0x93, 0x06, 0x94, 0x0a, 0x05, 0x5f, - 0x8f, 0x9c, 0xd1, 0x77, 0xa1, 0x4f, 0x5c, 0x1d, 0xfd, 0xaf, 0xec, 0x3e, 0x3c, 0x1e, 0x1e, 0x0f, - 0x0d, 0x22, 0xc0, 0x41, 0x0b, 0x7c, 0x0a, 0xc3, 0x3e, 0x29, 0x3e, 0x1b, 0x8e, 0xf8, 0xc0, 0xb0, - 0x66, 0x2e, 0x45, 0xea, 0xea, 0xa3, 0x0a, 0x1a, 0x6b, 0xa3, 0x9b, 0x40, 0x78, 0x48, 0x7a, 0xd7, - 0xd8, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x85, 0xe2, 0xaf, 0xa6, 0xc8, 0x17, 0x7f, 0x07, 0xd7, 0x80, - 0x85, 0x13, 0x00, 0x01, 0xd1, 0x39, 0x98, 0xdf, 0x2f, 0x6d, 0x9a, 0x18, 0x38, 0xbd, 0xfd, 0x90, - 0xc0, 0xd5, 0x26, 0x43, 0x07, 0x65, 0x0a, 0x21, 0x38, 0x54, 0xe0, 0x51, 0x55, 0x53, 0x11, 0xe7, - 0x46, 0x6c, 0x32, 0x98, 0x69, 0xe2, 0x99, 0x27, 0x20, 0x1d, 0xab, 0x1e, 0x3b, 0x0d, 0x20, 0x08, - 0xaf, 0x40, 0xa3, 0x69, 0x19, 0xb5, 0xa4, 0x97, 0x85, 0xd3, 0xb9, 0x10, 0x45, 0x45, 0x95, 0x76, - 0x55, 0x2d, 0x20, 0xc5, 0x1e, 0x8e, 0x3c, 0x3c, 0x1e, 0x1f, 0x2e, 0xf4, 0x8f, 0x52, 0xf3, 0x11, - 0x12, 0x09, 0x55, 0x8d, 0x65, 0x73, 0x76, 0x12, 0x0a, 0x31, 0x30, 0x99, 0x63, 0x6a, 0x70, 0x82, - 0xda, 0x1b, 0xca, 0xa0, 0xc6, 0x1f, 0x48, 0x30, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x76, 0x3a, - 0xb0, 0xd2, 0xc2, 0xb4, 0xe8, 0x03, 0xc5, 0x58, 0xf9, 0x16, 0x0c, 0x7d, 0x98, 0xd8, 0xc6, 0x8b, - 0x15, 0x7a, 0x10, 0x1e, 0xd9, 0xf5, 0xda, 0x2e, 0x55, 0x0e, 0x00, 0x1e, 0xf8, 0x72, 0x0c, 0xa5, - 0xe0, 0xe7, 0x31, 0x5b, 0xf7, 0xe7, 0x17, 0x85, 0x0f, 0x3c, 0x37, 0x27, 0xff, 0xef, 0x9f, 0xee, - 0xd9, 0xba, 0x49, 0xac, 0xb8, 0xaf, 0x82, 0xc8, 0x3c, 0x3a, 0x40, 0x41, 0xfb, 0x93, 0x48, 0x9a, - 0x75, 0x8c, 0x74, 0x6f, 0xaf, 0xbc, 0x29, 0x1d, 0x0d, 0xa2, 0x17, 0xc2, 0x78, 0xf4, 0xe8, 0x4c, - 0x71, 0xf8, 0x08, 0x01, 0x4b, 0x48, 0x10, 0xb8, 0x82, 0x41, 0xc9, 0x98, 0xca, 0xb5, 0x20, 0x00, - 0x4f, 0x46, 0xed, 0x59, 0x64, 0xfc, 0x57, 0x0a, 0x50, 0xb5, 0x52, 0x7d, 0x46, 0xd1, 0xe2, 0x79, - 0xc9, 0x18, 0x7f, 0xb7, 0x79, 0x19, 0x86, 0x3a, 0xaf, 0xdd, 0x47, 0xaf, 0xd9, 0x97, 0xb6, 0x49, - 0x9c, 0xea, 0x94, 0x11, 0x6e, 0x68, 0xd4, 0xbc, 0x72, 0xbe, 0xc1, 0xe3, 0xbe, 0xfe, 0x53, 0x05, - 0x2b, 0x0f, 0x14, 0x1f, 0xa1, 0xcd, 0x19, 0xfd, 0x44, 0x78, 0x5d, 0x0e, 0xb6, 0x7a, 0x0b, 0x07, - 0xbf, 0xae, 0x97, 0x1c, 0x4f, 0x97, 0xa1, 0x92, 0xcb, 0x5a, 0xea, 0x36, 0xc3, 0xdf, 0x33, 0x5c, - 0x12, 0xc9, 0x14, 0x25, 0x7b, 0x9a, 0x35, 0xea, 0x63, 0x00, 0xa4, 0x6e, 0x9d, 0x7c, 0x14, 0x25, - 0xe2, 0x9e, 0x43, 0x5f, 0xca, 0x8c, 0x78, 0x7c, 0x3e, 0x3e, 0x1e, 0x62, 0x7f, 0x36, 0x1b, 0xb5, - 0x3e, 0x9e, 0x03, 0xce, 0x27, 0x63, 0xca, 0x5a, 0xd5, 0x4d, 0x72, 0x6b, 0x4f, 0xfb, 0xa1, 0xf2, - 0xc2, 0x65, 0x11, 0x02, 0x41, 0x87, 0x90, 0xc6, 0x48, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x96, 0x12, - 0xaf, 0xa6, 0xca, 0xa0, 0xd1, 0x87, 0xbe, 0x89, 0xd0, 0xce, 0x85, 0x59, 0x7a, 0x65, 0x23, 0x50, - 0xc8, 0x53, 0x5c, 0xd8, 0x14, 0x4f, 0x2e, 0xb5, 0x66, 0x49, 0x0f, 0x52, 0x12, 0x21, 0xfb, 0x7f, - 0x6d, 0xa6, 0x80, 0x20, 0x95, 0x30, 0xdc, 0xfc, 0xee, 0x23, 0xd5, 0x30, 0xa7, 0x9e, 0x11, 0x2b, - 0x52, 0xf2, 0x3e, 0x5b, 0x9e, 0xeb, 0x6b, 0xa0, 0x5f, 0x15, 0x68, 0x8e, 0xe9, 0x78, 0x59, 0xd9, - 0xe6, 0xc9, 0x05, 0x0d, 0x73, 0x26, 0xf8, 0x3b, 0x34, 0x2f, 0x1f, 0x91, 0x9e, 0x99, 0x63, 0x8c, - 0x33, 0xf4, 0x84, 0x0e, 0x27, 0x25, 0xb6, 0x1b, 0x98, 0x0e, 0xee, 0xcf, 0xd8, 0x15, 0xd5, 0xaa, - 0xd9, 0xbf, 0x82, 0xfb, 0x5a, 0x91, 0x4c, 0xa3, 0x6b, 0x4a, 0x17, 0x07, 0x99, 0xcc, 0x7a, 0x01, - 0xd9, 0x18, 0x7f, 0xb7, 0x79, 0x19, 0x96, 0x2a, 0xb6, 0xba, 0x94, 0x47, 0x96, 0x0a, 0x24, 0x0e, - 0x1d, 0x13, 0x4c, 0xd0, 0x98, 0x46, 0x8e, 0xe9, 0x00, 0x09, 0xa0, 0x5f, 0x54, 0x00, 0x0a, 0x27, - 0xd9, 0x45, 0xcf, 0xcf, 0x1a, 0xb1, 0xb9, 0x23, 0xd3, 0x8f, 0x2b, 0xa0, 0x6c, 0xf0, 0x94, 0xc5, - 0xec, 0xa0, 0x25, 0x4c, 0x03, 0x95, 0x9a, 0xb0, 0xe8, 0x17, 0x31, 0xcc, 0x58, 0xae, 0x26, 0xd5, - 0x19, 0x74, 0xd0, 0x5d, 0x2a, 0xcf, 0x73, 0xb2, 0xd0, 0xf2, 0x0e, 0x6e, 0x20, 0xef, 0xb2, 0x5d, - 0x74, 0xc2, 0x33, 0x9d, 0x8c, 0xe3, 0x8f, 0x1e, 0x0f, 0x0f, 0x87, 0x9c, 0x5a, 0x72, 0x8c, 0x3d, - 0x84, 0x9d, 0x8c, 0xf9, 0x92, 0x6a, 0x27, 0x11, 0xb6, 0x7c, 0x1f, 0x5c, 0x20, 0xa5, 0x31, 0x10, - 0x53, 0xfa, 0x70, 0xc1, 0x57, 0x77, 0x41, 0x9c, 0xd8, 0x34, 0x8f, 0xe7, 0x79, 0x19, 0x95, 0xf2, - 0xae, 0xec, 0x0f, 0xb3, 0x25, 0xd2, 0x48, 0x45, 0xcc, 0x96, 0x18, 0x73, 0x3f, 0x05, 0xf8, 0xf1, - 0x77, 0x06, 0xb8, 0x84, 0x9f, 0x94, 0x3a, 0x01, 0x59, 0xef, 0x5e, 0x07, 0xb8, 0x44, 0x7c, 0xb5, - 0x08, 0xdd, 0xae, 0x57, 0x5b, 0x81, 0x1a, 0xc7, 0x62, 0x6c, 0xf9, 0x0a, 0x4a, 0xb6, 0xf3, 0x44, - 0x11, 0x93, 0xb8, 0x1e, 0xb8, 0xa9, 0x4f, 0xbc, 0x79, 0xf6, 0x95, 0xfd, 0xfb, 0xf3, 0x57, 0x4b, - 0xb9, 0xe9, 0xb5, 0xcd, 0x8d, 0xd4, 0x39, 0x21, 0x88, 0x43, 0xda, 0x37, 0xb8, 0x78, 0xfc, 0x1e, - 0x0f, 0x87, 0x04, 0x2d, 0x7e, 0xf0, 0xad, 0x32, 0xd2, 0xef, 0x5c, 0xa7, 0xd6, 0x56, 0x84, 0xcc, - 0xbc, 0x3b, 0x95, 0x32, 0x8b, 0xaa, 0x20, 0xb2, 0x89, 0x90, 0x61, 0x00, 0xc9, 0xe9, 0xe9, 0x42, - 0xc8, 0x34, 0x8f, 0xe7, 0x79, 0x39, 0x86, 0x0a, 0xaf, 0xdd, 0x49, 0x47, 0x93, 0x57, 0xb2, 0x73, - 0x98, 0x0a, 0x4a, 0x00, 0x02, 0xdc, 0x10, 0x12, 0x0d, 0xa8, 0x69, 0xb4, 0xff, 0xbb, 0xd4, 0x79, - 0x00, 0x10, 0x9a, 0xd9, 0x29, 0x03, 0x07, 0x8d, 0xe2, 0xeb, 0x51, 0x78, 0xff, 0x8f, 0xde, 0x43, - 0xb8, 0x6b, 0x59, 0xf8, 0xa5, 0x52, 0x56, 0x92, 0xa2, 0x86, 0xb2, 0x2d, 0x49, 0xf6, 0x12, 0x4b, - 0x9a, 0xf3, 0x65, 0x5c, 0xb3, 0x2c, 0xc1, 0x2f, 0x02, 0x43, 0x35, 0xe5, 0xab, 0x9b, 0xa6, 0x19, - 0xf3, 0xd4, 0x73, 0xc1, 0x83, 0x07, 0x1c, 0xc5, 0xb7, 0x8f, 0x20, 0xc2, 0xa4, 0x18, 0x21, 0x83, - 0xc0, 0x58, 0xea, 0xb3, 0xcf, 0x90, 0x80, 0x92, 0x34, 0xd0, 0xc6, 0x2f, 0x39, 0x13, 0xbf, 0x92, - 0xbd, 0x02, 0x92, 0x14, 0x88, 0x75, 0x17, 0x8f, 0x58, 0x31, 0x9e, 0xe7, 0x79, 0x19, 0x96, 0x32, - 0x00, 0x00, 0x00, 0x17, 0xce, 0xd6, 0x4b, 0x99, 0x74, 0x49, 0x5b, 0xfd, 0x44, 0xe4, 0xd0, 0xf0, - 0x28, 0x47, 0x5e, 0xff, 0x1b, 0xc0, 0xe7, 0x04, 0x71, 0x3d, 0x0d, 0xd6, 0xca, 0x4c, 0x60, 0xc4, - 0x25, 0xe3, 0xef, 0x6b, 0xc8, 0x44, 0xdf, 0x67, 0xf4, 0xa2, 0x3c, 0x99, 0xf2, 0xeb, 0x63, 0x2b, - 0x4f, 0x57, 0xb0, 0xb4, 0xd3, 0x15, 0x11, 0xd9, 0x4a, 0x4d, 0xe0, 0xfc, 0x8d, 0x7e, 0xbb, 0xdf, - 0x51, 0x9b, 0xd6, 0x78, 0x46, 0x08, 0x84, 0x21, 0x19, 0x9a, 0x9e, 0x1c, 0x26, 0x98, 0x45, 0xfa, - 0x96, 0xd6, 0xe3, 0xe3, 0x86, 0x79, 0x95, 0xa4, 0x90, 0x73, 0xe5, 0x0c, 0x93, 0xed, 0x60, 0x04, - 0x16, 0x48, 0x1c, 0x2d, 0xe0, 0xf3, 0x18, 0x2f, 0xc9, 0x87, 0x8f, 0x0f, 0x0e, 0x0e, 0x35, 0x04, - 0x0a, 0xa2, 0x25, 0xbe, 0x79, 0x29, 0xd6, 0x22, 0xaf, 0xdd, 0x49, 0xd0, 0x01, 0x07, 0x26, 0x24, - 0x1a, 0x30, 0xf7, 0x6a, 0x7c, 0x6d, 0x9b, 0x33, 0x48, 0x02, 0x8d, 0x03, 0x92, 0x80, 0x00, 0x00, - 0x00, 0x9b, 0x5f, 0x92, 0xdf, 0x60, 0x50, 0x67, 0x44, 0xa0, 0xed, 0xb2, 0xaa, 0xdf, 0x6f, 0xfc, - 0x8d, 0x08, 0xfb, 0xb1, 0x55, 0x21, 0x9c, 0x5d, 0x89, 0xc5, 0x0f, 0x69, 0x54, 0xaa, 0x9b, 0x7c, - 0x6e, 0x86, 0x21, 0x29, 0xb8, 0x84, 0xa3, 0xd5, 0x82, 0x0b, 0xdc, 0xe0, 0x0f, 0xa8, 0x5e, 0x5d, - 0x77, 0xdb, 0x0f, 0x83, 0x83, 0xc3, 0x8c, 0x27, 0x38, 0x79, 0x87, 0x31, 0x4c, 0xcc, 0xa5, 0x12, - 0x52, 0x98, 0x6b, 0x9b, 0x18, 0x09, 0x51, 0x91, 0x73, 0x8f, 0x76, 0xe2, 0x04, 0x4c, 0x4c, 0x19, - 0xc5, 0x7b, 0xd6, 0x24, 0x31, 0x97, 0xf9, 0x53, 0x4a, 0xa2, 0x25, 0xbe, 0x79, 0x39, 0xb6, 0x22, - 0xaf, 0xdd, 0x47, 0x5c, 0xd4, 0x87, 0xe9, 0x38, 0x67, 0x02, 0xb6, 0xd5, 0x9e, 0x32, 0x3e, 0x50, - 0x4e, 0x41, 0x80, 0xeb, 0x01, 0x11, 0x93, 0x00, 0x00, 0xc1, 0x6f, 0x39, 0x60, 0x40, 0xe1, 0x8f, - 0xe0, 0xde, 0x4a, 0x1c, 0x46, 0x43, 0x6c, 0xd0, 0x4d, 0x6f, 0x87, 0xfd, 0x26, 0xc9, 0xac, 0xef, - 0x65, 0x1f, 0x08, 0xd4, 0x2d, 0xe3, 0xbb, 0x95, 0x06, 0x98, 0x02, 0x6f, 0xc3, 0x4b, 0x70, 0xb5, - 0xd4, 0x1d, 0xcc, 0x12, 0x9e, 0xd0, 0x4b, 0xc0, 0x83, 0x5e, 0x5c, 0x43, 0xe0, 0x61, 0xfc, 0x70, - 0x85, 0xb9, 0xe1, 0xce, 0x81, 0x81, 0x74, 0x0f, 0x71, 0x24, 0x04, 0xe7, 0x0b, 0x3d, 0x89, 0x87, - 0x1f, 0x22, 0x73, 0xef, 0x71, 0xca, 0x0e, 0xac, 0x13, 0x9a, 0xab, 0x6f, 0x08, 0x10, 0x58, 0x63, - 0xda, 0xa2, 0x25, 0xbe, 0x79, 0x19, 0xb6, 0x2a, 0xaf, 0xde, 0xcb, 0xf9, 0xda, 0x75, 0x22, 0xeb, - 0x42, 0x79, 0x4d, 0xf9, 0x26, 0x61, 0xa1, 0xde, 0x6f, 0x04, 0x69, 0x01, 0x56, 0x71, 0x00, 0x00, - 0x00, 0xc9, 0x21, 0xc5, 0x11, 0x2d, 0x68, 0xb3, 0x00, 0x0d, 0x1b, 0x31, 0x17, 0xa5, 0x05, 0x0b, - 0x0c, 0x4a, 0x5e, 0x20, 0xbf, 0x2c, 0x0d, 0x5c, 0x6c, 0x89, 0x64, 0x68, 0xe2, 0xcd, 0x31, 0xb3, - 0x25, 0x74, 0x83, 0x25, 0x47, 0x80, 0xba, 0x98, 0xa2, 0xaa, 0x5c, 0x20, 0x84, 0x5d, 0x84, 0x77, - 0xa6, 0x57, 0x5f, 0xc0, 0x7e, 0x0f, 0xc0, 0xf0, 0xf1, 0xf9, 0x1c, 0x78, 0x25, 0xe7, 0xf6, 0xbe, - 0x41, 0x60, 0x4b, 0x07, 0xd9, 0x03, 0x1a, 0x7a, 0xfa, 0xc9, 0x8c, 0x49, 0x67, 0x61, 0x68, 0xbe, - 0x6b, 0x94, 0x67, 0xce, 0x01, 0x7f, 0xbd, 0x03, 0xda, 0xa2, 0x25, 0xbe, 0x79, 0x19, 0xb6, 0x32, - 0xb6, 0xae, 0x86, 0x8b, 0xf6, 0x97, 0xbd, 0x1d, 0x21, 0x8d, 0xd3, 0xc1, 0x14, 0xa5, 0xb4, 0x74, - 0xcb, 0x2c, 0x68, 0x95, 0x58, 0x6e, 0x9d, 0xd8, 0x67, 0xd7, 0x00, 0x28, 0x59, 0xe1, 0x22, 0x0f, - 0x08, 0x16, 0x8c, 0xbc, 0x39, 0x08, 0xc8, 0xf2, 0xd5, 0x63, 0x96, 0x2a, 0x4d, 0xe4, 0xb8, 0x45, - 0x8d, 0xe0, 0xe6, 0x7e, 0x09, 0xe7, 0xba, 0xdb, 0x8c, 0x84, 0x06, 0xd1, 0xa0, 0xcf, 0x15, 0xd8, - 0xe6, 0x6e, 0x30, 0x2c, 0xf3, 0x92, 0xe8, 0x69, 0xbf, 0xdb, 0xe0, 0xe2, 0x18, 0xe5, 0x38, 0x7c, - 0x70, 0x58, 0xab, 0x5a, 0xb3, 0x41, 0xa2, 0x39, 0x1d, 0xe8, 0x60, 0x13, 0x37, 0xa0, 0xea, 0x94, - 0xa9, 0x3f, 0xc2, 0xa8, 0x02, 0xa8, 0xc9, 0xc9, 0x5b, 0x82, 0x58, 0xa0, 0x7e, 0x58, 0xc0, 0xbc, - 0xda, 0xa2, 0x25, 0xbe, 0x79, 0x19, 0x85, 0xe2, 0x33, 0xd8, 0x04, 0x09, 0x22, 0xac, 0x4b, 0x30, - 0x26, 0xa5, 0xce, 0x2b, 0x8b, 0xe4, 0xdd, 0x49, 0xde, 0xf3, 0x71, 0xdb, 0x41, 0x0b, 0x9c, 0x9e, - 0x37, 0x87, 0x37, 0x00, 0x30, 0x51, 0x30, 0xf8, 0x07, 0x9d, 0xd5, 0xaf, 0x2d, 0xa0, 0x72, 0x91, - 0xf5, 0xf6, 0xff, 0x28, 0xe7, 0x8c, 0x19, 0x61, 0xc9, 0x90, 0x69, 0xd0, 0xb6, 0x18, 0x57, 0x2b, - 0xbb, 0x7d, 0x94, 0xbd, 0xbb, 0x1b, 0xd1, 0xf3, 0xe2, 0x7b, 0x00, 0x00, 0x00, 0x5e, 0xb5, 0x7d, - 0x88, 0x13, 0x70, 0x37, 0xc7, 0x09, 0xf1, 0xff, 0x00, 0xf4, 0xda, 0xfd, 0xf8, 0xc8, 0xeb, 0x4e, - 0x20, 0x64, 0x24, 0xe8, 0x83, 0x33, 0xdd, 0x21, 0xf1, 0x98, 0xa9, 0x4a, 0x2a, 0x22, 0x38, 0xd0, - 0x50, 0x44, 0x3e, 0x12, 0x97, 0xf5, 0x0a, 0x4f, 0xb5, 0x45, 0x00, 0xbc, 0xf2, 0x39, 0x96, 0x24, - 0xb6, 0xaf, 0xa6, 0xf9, 0xcd, 0x37, 0xd5, 0x1c, 0x78, 0xf8, 0x77, 0x78, 0xdd, 0x48, 0x14, 0x86, - 0x42, 0xb8, 0xa5, 0x3f, 0x61, 0x53, 0x26, 0x14, 0x48, 0x00, 0x3a, 0x99, 0xa8, 0xc0, 0x35, 0x0d, - 0x65, 0x76, 0x0d, 0x54, 0x20, 0x78, 0x1f, 0xf5, 0x28, 0xdd, 0x90, 0x38, 0xb0, 0xae, 0x63, 0xe6, - 0x31, 0x7b, 0xd9, 0x68, 0x06, 0x49, 0x53, 0xda, 0x75, 0x93, 0x00, 0x15, 0x70, 0x7f, 0xa1, 0x2f, - 0x4d, 0xf6, 0xb4, 0x42, 0x29, 0xfd, 0xfd, 0xa7, 0x50, 0xf9, 0x4e, 0xb1, 0x67, 0x06, 0x3c, 0xc0, - 0x6f, 0x38, 0x79, 0x0b, 0x3e, 0x0e, 0x94, 0x82, 0x42, 0x70, 0x9a, 0xc5, 0x1b, 0x63, 0x61, 0x3e, - 0x4b, 0xb3, 0x17, 0xbb, 0x40, 0x09, 0x2a, 0xff, 0x7e, 0xe5, 0x44, 0xdf, 0x48, 0x4a, 0x75, 0x8b, - 0x5a, 0xa2, 0x80, 0x5e, 0x79, 0x19, 0x96, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6d, 0x73, 0x7c, - 0x9f, 0x67, 0xa0, 0xef, 0xa0, 0xa7, 0xeb, 0xe2, 0xe1, 0x85, 0x96, 0x6a, 0xe4, 0x5b, 0xa3, 0xc6, - 0x67, 0x86, 0xd3, 0x74, 0x6c, 0x13, 0xb2, 0x27, 0x47, 0x70, 0x4c, 0x11, 0x7f, 0x31, 0xa6, 0xc0, - 0x2d, 0x9f, 0xc1, 0x91, 0x91, 0x1b, 0xa9, 0xb6, 0xee, 0x29, 0x8d, 0x51, 0xbf, 0xab, 0xad, 0xed, - 0x28, 0x95, 0xf9, 0x44, 0x3d, 0x92, 0x01, 0x45, 0x09, 0x32, 0xb3, 0x82, 0x55, 0xf4, 0x7b, 0x46, - 0x43, 0x48, 0xac, 0x84, 0xd9, 0x86, 0xd3, 0x0f, 0xc2, 0xa5, 0x42, 0x20, 0x89, 0x96, 0x99, 0xba, - 0xe6, 0x22, 0x7b, 0x43, 0x99, 0xa0, 0x7a, 0xce, 0x14, 0x67, 0x08, 0x47, 0x76, 0xe0, 0xf9, 0x4d, - 0xd4, 0x42, 0xd1, 0xe0, 0xf0, 0x78, 0x71, 0xb6, 0x3a, 0xa2, 0x80, 0x5e, 0x79, 0x09, 0xc6, 0x22, - 0x35, 0x16, 0xd8, 0x03, 0xc2, 0xd2, 0x32, 0x65, 0x0f, 0x49, 0xb5, 0x22, 0x2f, 0x98, 0x3e, 0x96, - 0x6b, 0x25, 0xef, 0xf6, 0x08, 0x01, 0xc4, 0xf3, 0xf1, 0xf2, 0x31, 0xf1, 0xa5, 0x00, 0x3b, 0x24, - 0x7d, 0x52, 0x00, 0xe5, 0x7e, 0xbe, 0xb5, 0x73, 0xf3, 0xe8, 0x4b, 0xbf, 0x91, 0xf5, 0x54, 0x7f, - 0x21, 0x72, 0x51, 0xd8, 0xe1, 0x31, 0xa6, 0x40, 0x8a, 0xcc, 0x5f, 0xfb, 0x40, 0x94, 0x61, 0x54, - 0x7d, 0x74, 0x71, 0x5e, 0xc4, 0x00, 0x10, 0x92, 0x02, 0x93, 0x30, 0x37, 0x6f, 0xac, 0xf4, 0xad, - 0xe6, 0x90, 0xc0, 0x9c, 0x32, 0xc4, 0x42, 0x2b, 0x38, 0x99, 0x1c, 0x60, 0xa8, 0x5e, 0x49, 0xb0, - 0x0f, 0x27, 0xab, 0x4c, 0x98, 0x81, 0x8e, 0x77, 0x3b, 0xd3, 0x1c, 0xb4, 0xfd, 0x1f, 0x3a, 0xa7, - 0x95, 0x45, 0x00, 0xbc, 0xf2, 0x39, 0x65, 0x94, 0x33, 0x99, 0xa3, 0x6b, 0xc6, 0x11, 0xc8, 0xea, - 0xb8, 0x61, 0x56, 0x62, 0x54, 0xef, 0x09, 0xac, 0xa7, 0x9c, 0xad, 0x88, 0x72, 0xaf, 0xf2, 0xa8, - 0x81, 0x9f, 0x94, 0x00, 0x00, 0x02, 0xf0, 0xb9, 0xf9, 0xc6, 0xf8, 0x3d, 0x1a, 0x27, 0x3f, 0xf5, - 0xb9, 0xac, 0x99, 0xf8, 0x85, 0x99, 0xcf, 0x49, 0x9f, 0xaf, 0x12, 0x30, 0x09, 0xfe, 0xd0, 0xbd, - 0x86, 0x1a, 0xac, 0xfa, 0xbb, 0x6a, 0x66, 0x24, 0xed, 0x00, 0x00, 0x03, 0x54, 0xca, 0x7c, 0x4a, - 0xfa, 0xe6, 0xc8, 0x40, 0x26, 0x05, 0x34, 0x56, 0x3b, 0x79, 0x50, 0xcf, 0x27, 0x43, 0x18, 0xb1, - 0xc0, 0x8a, 0xf1, 0x82, 0x94, 0x12, 0x71, 0xba, 0x16, 0x61, 0x76, 0x5c, 0x54, 0x36, 0x73, 0xc6, - 0x31, 0x89, 0x38, 0x20, 0x3f, 0x47, 0x1b, 0xb1, 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x76, 0x2c, - 0xa7, 0x93, 0xb3, 0x3a, 0x0e, 0xd7, 0x1c, 0x1f, 0xf4, 0x4b, 0x21, 0xd0, 0xc4, 0xe0, 0xcc, 0xef, - 0x91, 0x75, 0x3d, 0xa5, 0xb0, 0x40, 0xb3, 0xb9, 0x31, 0x00, 0x6e, 0x00, 0x00, 0x0d, 0x11, 0x8c, - 0xe6, 0x15, 0x6c, 0xb2, 0x90, 0x0e, 0xe8, 0xdc, 0xce, 0xd0, 0x62, 0xb0, 0x91, 0xbe, 0x4b, 0xbd, - 0x94, 0x45, 0x10, 0xa5, 0x09, 0x1f, 0x7f, 0x18, 0xbe, 0xf9, 0xc8, 0x0d, 0x8d, 0xd5, 0xf1, 0x5d, - 0x99, 0x2b, 0xb7, 0xa7, 0x00, 0x00, 0x00, 0xd8, 0x5e, 0x54, 0x19, 0xb5, 0xff, 0x6d, 0x16, 0xdd, - 0xfa, 0xf5, 0x7d, 0x1d, 0xbe, 0x3e, 0x7d, 0x91, 0xd9, 0xaa, 0x2a, 0xcd, 0xe0, 0x6a, 0x90, 0x8b, - 0xc8, 0x0c, 0xad, 0x60, 0xde, 0x00, 0xfd, 0xb4, 0x1c, 0x57, 0xe0, 0x1b, 0x7f, 0x56, 0x68, 0xd6, - 0x87, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x85, 0xcc, 0x33, 0xd3, 0x9e, 0x22, 0x68, 0x6b, 0xaf, 0xd6, - 0xa4, 0x58, 0xc7, 0xa3, 0xf3, 0x00, 0xe2, 0x5c, 0xf3, 0xf6, 0xdb, 0x75, 0xba, 0x17, 0xd3, 0xc1, - 0xaf, 0x7f, 0x00, 0x00, 0x00, 0x43, 0x84, 0xe7, 0xfc, 0x20, 0xd6, 0xee, 0xb0, 0xb9, 0xed, 0x0a, - 0xf0, 0xde, 0x63, 0x4a, 0xa1, 0x5a, 0x58, 0x07, 0xb1, 0x38, 0x42, 0x56, 0x56, 0xf7, 0xaa, 0x64, - 0x84, 0xab, 0x74, 0xc9, 0xc4, 0xa0, 0x09, 0xdd, 0x00, 0x00, 0x00, 0x03, 0x0d, 0x63, 0x4e, 0xbe, - 0xce, 0x98, 0xb5, 0x50, 0xae, 0x78, 0xc0, 0xb0, 0x5c, 0x0f, 0xca, 0x14, 0x15, 0x68, 0x01, 0x1f, - 0xc6, 0x0d, 0x51, 0x5f, 0x40, 0xe1, 0x48, 0xed, 0x2d, 0xe4, 0x64, 0xd2, 0x7e, 0x16, 0x99, 0x89, - 0x75, 0x25, 0x63, 0x66, 0x12, 0x08, 0xb4, 0x51, 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0xa6, 0x24, - 0x33, 0x99, 0xa3, 0x6b, 0xc6, 0x40, 0x4e, 0xf2, 0x28, 0x89, 0x9e, 0x2b, 0x8a, 0x6f, 0xe1, 0x1e, - 0x33, 0x5a, 0x70, 0x73, 0xb0, 0x05, 0xc7, 0xcc, 0xb7, 0x27, 0x00, 0x00, 0x00, 0x0b, 0x3f, 0x43, - 0x7c, 0xa0, 0x5d, 0x2e, 0x1f, 0x82, 0x46, 0x80, 0x39, 0xe0, 0xf3, 0x1a, 0x5f, 0x44, 0xc2, 0x81, - 0x92, 0xb1, 0xa3, 0xf6, 0x56, 0x71, 0x57, 0xf5, 0x30, 0xa1, 0x39, 0x74, 0xbb, 0x23, 0xd9, 0x1d, - 0x5c, 0x49, 0x00, 0x4b, 0xee, 0x8c, 0x85, 0xe2, 0x4c, 0x03, 0x1d, 0x7c, 0xc1, 0x88, 0x32, 0x63, - 0x36, 0xec, 0x9a, 0x8c, 0x20, 0xdc, 0xe8, 0x9c, 0x7d, 0x11, 0x80, 0xda, 0x23, 0xe6, 0x41, 0xfa, - 0x0c, 0x27, 0xa9, 0xb4, 0x8a, 0x26, 0xa9, 0x3c, 0x0b, 0x78, 0x4b, 0xc4, 0x84, 0xa2, 0x32, 0x83, - 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x96, 0x14, 0xa8, 0x0a, 0x97, 0xaf, 0xfe, 0xac, 0xa6, 0x0a, - 0xe1, 0x39, 0xca, 0xb8, 0x3a, 0x4f, 0x2b, 0xe3, 0x36, 0x00, 0x10, 0xcb, 0x27, 0xd9, 0xe2, 0x7c, - 0x79, 0xd0, 0x00, 0x00, 0x04, 0x7c, 0xe0, 0x82, 0xcc, 0x6e, 0x97, 0x2d, 0x88, 0x6e, 0x5b, 0xbd, - 0x20, 0x79, 0x51, 0xc5, 0x6f, 0xff, 0xad, 0xde, 0x5f, 0x02, 0x72, 0x31, 0x96, 0x2a, 0x7c, 0xaa, - 0x94, 0x32, 0x5c, 0xae, 0xa5, 0x49, 0x0b, 0x84, 0x0a, 0x00, 0x1d, 0xbc, 0x9d, 0x0f, 0x9e, 0xa3, - 0x1a, 0xe5, 0xe6, 0x00, 0xc0, 0xf2, 0xb6, 0x6e, 0x9e, 0xf5, 0x6b, 0x0c, 0xfd, 0x92, 0x6c, 0x01, - 0x87, 0xc8, 0x1f, 0xb3, 0x10, 0x81, 0x64, 0xb9, 0xb3, 0x71, 0xa5, 0x36, 0x42, 0x27, 0xdb, 0x79, - 0x41, 0x84, 0x07, 0x08, 0x49, 0xf5, 0x38, 0xae, 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x96, 0x3c, - 0xae, 0xf1, 0x98, 0x15, 0x69, 0xd4, 0x07, 0x00, 0x00, 0x29, 0xde, 0xff, 0x8b, 0xc6, 0x7b, 0x35, - 0xf8, 0x26, 0x07, 0x42, 0xe9, 0x0e, 0xf2, 0x5a, 0xdb, 0x75, 0xd8, 0xbd, 0x00, 0x21, 0xce, 0x65, - 0x8f, 0x1a, 0x4c, 0xfb, 0xcf, 0xaf, 0xba, 0x6d, 0xc4, 0x98, 0x48, 0xd8, 0xa8, 0xf5, 0x3a, 0xbe, - 0x01, 0xb6, 0x93, 0x98, 0x34, 0xae, 0x75, 0x79, 0x26, 0xa4, 0x44, 0xf1, 0x17, 0x4a, 0x2c, 0x6e, - 0x05, 0x29, 0x36, 0x4d, 0xe5, 0x23, 0xb9, 0xff, 0x5b, 0xa2, 0xcc, 0xfe, 0x06, 0x71, 0x48, 0x46, - 0x66, 0xae, 0x88, 0x67, 0x87, 0xa3, 0xd0, 0xb8, 0x67, 0xfa, 0x6f, 0x3a, 0xa2, 0x85, 0xa5, 0xa3, - 0xd5, 0xa5, 0x28, 0x10, 0xe3, 0xed, 0x5b, 0x11, 0x63, 0xa0, 0xb8, 0x1f, 0x1f, 0xdb, 0x47, 0x2c, - 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x66, 0x3c, 0x33, 0xd3, 0xb5, 0xb8, 0x9d, 0xe5, 0x92, 0xaa, - 0x00, 0x2a, 0x00, 0x06, 0x30, 0x9a, 0x3d, 0x97, 0xe8, 0x11, 0x6f, 0x8f, 0xeb, 0x98, 0xa1, 0xc5, - 0x00, 0x00, 0x00, 0xcc, 0x4d, 0x31, 0x19, 0xf2, 0x0a, 0x32, 0x12, 0x5e, 0xce, 0x61, 0xb6, 0x12, - 0xbd, 0xb0, 0xf3, 0xc6, 0xd2, 0xe9, 0x3c, 0xa0, 0x40, 0x98, 0x33, 0x39, 0x4f, 0xf4, 0x5c, 0xdd, - 0x5b, 0x17, 0x1e, 0x26, 0xe1, 0x15, 0xb2, 0xff, 0x2c, 0x00, 0x46, 0xe4, 0xc4, 0xe2, 0x07, 0x2e, - 0x4e, 0xbf, 0x0d, 0xc0, 0x7f, 0xde, 0x73, 0xc6, 0xb4, 0xb8, 0x04, 0xde, 0xb8, 0x16, 0xdb, 0x9e, - 0xa1, 0xa5, 0xd1, 0x25, 0x5b, 0x50, 0x0d, 0xf1, 0x4f, 0xc2, 0xd6, 0xc9, 0x83, 0x58, 0x18, 0x4d, - 0x26, 0x19, 0x1c, 0xa8, 0x0e, 0xd7, 0xcd, 0x38, 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x96, 0x1c, - 0x33, 0xd2, 0xc1, 0x91, 0x36, 0x06, 0x73, 0x74, 0x55, 0x63, 0x0f, 0x0d, 0xc6, 0xc5, 0x37, 0x32, - 0x23, 0x57, 0xa2, 0x52, 0x26, 0xe6, 0x0e, 0x44, 0xbd, 0xf7, 0xe2, 0x00, 0x01, 0x2f, 0x59, 0xed, - 0xea, 0x0b, 0xd5, 0xe1, 0x8c, 0x48, 0x5c, 0x76, 0xc5, 0x26, 0xcf, 0x00, 0x6a, 0x14, 0x55, 0xa5, - 0x7e, 0xef, 0xd8, 0xb0, 0xc1, 0x4a, 0xc1, 0x8f, 0x43, 0x7d, 0xb1, 0xef, 0x32, 0x78, 0x04, 0xfd, - 0x6a, 0xa2, 0x01, 0x16, 0xaf, 0x74, 0x19, 0xe8, 0xc1, 0xce, 0x9f, 0xe0, 0x43, 0xc8, 0x9c, 0xa9, - 0xd0, 0x6e, 0xb0, 0x29, 0xbb, 0x78, 0x31, 0xcc, 0x45, 0xb7, 0x4a, 0xff, 0x80, 0x53, 0xb9, 0x57, - 0x97, 0xe9, 0x60, 0xce, 0x5d, 0x26, 0x0c, 0xd6, 0xe3, 0xd2, 0xd1, 0x59, 0x68, 0x82, 0xd4, 0xc3, - 0xa7, 0x98, 0x05, 0x3c, 0xf2, 0x39, 0x86, 0x14, 0xaa, 0x72, 0x28, 0x1c, 0x23, 0xca, 0x8d, 0x54, - 0x31, 0x9f, 0x7a, 0x0c, 0x0b, 0xf9, 0x00, 0x00, 0x13, 0x8d, 0x44, 0xaa, 0x44, 0x4a, 0x06, 0x00, - 0x00, 0x00, 0x02, 0x62, 0xc7, 0xf0, 0xf8, 0x6a, 0xbd, 0x1d, 0x75, 0x02, 0x11, 0x50, 0xcf, 0x51, - 0x7d, 0x12, 0xa8, 0xfe, 0x93, 0xad, 0x29, 0x0a, 0xbf, 0xbb, 0x3b, 0xf3, 0x63, 0x98, 0x6e, 0x85, - 0x73, 0xc1, 0x02, 0x41, 0x87, 0x9c, 0x53, 0xc7, 0x00, 0x57, 0x04, 0x4a, 0x78, 0xda, 0xcb, 0xe0, - 0xed, 0xe5, 0x3f, 0x3f, 0x8d, 0x1c, 0xc9, 0x28, 0xf5, 0x12, 0xcb, 0x34, 0x68, 0x30, 0x7c, 0xe6, - 0x86, 0xbd, 0xe0, 0x48, 0x40, 0x3f, 0xb5, 0x1f, 0x35, 0x6b, 0x32, 0x3b, 0x61, 0x6c, 0xe4, 0xde, - 0x81, 0x3a, 0x96, 0xc4, 0x20, 0xa9, 0xee, 0x87, 0x87, 0x98, 0x05, 0x3c, 0xf2, 0x79, 0x96, 0x3c, - 0x35, 0x1d, 0x6f, 0xd0, 0x0b, 0xbd, 0x6c, 0x0e, 0x54, 0x6a, 0xbe, 0xdd, 0x5b, 0x56, 0x75, 0x13, - 0xc7, 0x42, 0x28, 0x79, 0xc3, 0xfa, 0x0b, 0xc3, 0xaa, 0x5d, 0x99, 0x23, 0xe8, 0xdb, 0x04, 0x7a, - 0xd8, 0x78, 0x50, 0xab, 0x97, 0x12, 0xff, 0xa6, 0xf5, 0x85, 0xa9, 0xae, 0xd4, 0x57, 0xc2, 0x05, - 0x19, 0x3b, 0x6a, 0xac, 0x1b, 0x78, 0x10, 0xad, 0xde, 0x20, 0xc1, 0xa3, 0xdf, 0x57, 0xc4, 0x8f, - 0x2a, 0x00, 0x00, 0x02, 0x96, 0x4e, 0x79, 0x2b, 0xda, 0x72, 0x78, 0xdc, 0x3b, 0x03, 0x55, 0xd0, - 0xa3, 0xc1, 0xf2, 0x22, 0xee, 0x09, 0xf6, 0x72, 0x47, 0xf1, 0x57, 0x46, 0xd9, 0xc9, 0x0b, 0xa0, - 0xb9, 0x66, 0xaa, 0x7b, 0xea, 0x13, 0xc2, 0x08, 0x01, 0x66, 0x8f, 0xb3, 0x55, 0xe3, 0xe2, 0x89, - 0x85, 0xa6, 0xf0, 0xfe, 0xf2, 0x79, 0x86, 0x24, 0x33, 0x99, 0x9b, 0x83, 0xf8, 0x2a, 0x63, 0x47, - 0xa8, 0x98, 0xe4, 0x80, 0xf9, 0x98, 0x38, 0x29, 0x1a, 0xaf, 0x7e, 0xc1, 0x84, 0xfd, 0xc7, 0x07, - 0x8d, 0xc8, 0x92, 0x14, 0x00, 0x03, 0x50, 0xdf, 0xdd, 0x23, 0xc8, 0xd1, 0xa6, 0xb0, 0xa3, 0x10, - 0xd3, 0xe2, 0xdc, 0x57, 0x83, 0xd5, 0x84, 0xb3, 0x47, 0x04, 0x5b, 0xd2, 0xa9, 0xd1, 0xe3, 0xee, - 0xd3, 0x1c, 0x9c, 0xb1, 0x4f, 0xa0, 0x00, 0x00, 0x39, 0x21, 0xe6, 0x8b, 0xa3, 0xd9, 0xbf, 0x1c, - 0x03, 0x7e, 0x78, 0x7c, 0x39, 0x00, 0xe1, 0x70, 0x03, 0x34, 0x10, 0x6e, 0x42, 0xac, 0x8c, 0x40, - 0x4d, 0xe0, 0x71, 0x80, 0x54, 0x1d, 0x67, 0x43, 0x69, 0x34, 0x8a, 0x16, 0x78, 0x56, 0x85, 0xdd, - 0x91, 0x36, 0x51, 0x79, 0x6b, 0x6f, 0x7e, 0x8c, 0x85, 0xa6, 0xf0, 0xfe, 0xf2, 0x79, 0x96, 0x3c, - 0x35, 0x15, 0x1c, 0x7a, 0xf9, 0xb9, 0x15, 0xe0, 0xbb, 0xd6, 0x30, 0xcd, 0x56, 0x50, 0x2b, 0xc4, - 0x80, 0x2b, 0x4e, 0xa8, 0xd5, 0xf6, 0x54, 0x89, 0xbc, 0xbb, 0xc8, 0xfe, 0xa5, 0xd1, 0x00, 0x2d, - 0xcd, 0xb7, 0x7f, 0xd2, 0x26, 0x62, 0xff, 0xc4, 0x7e, 0xf3, 0x6f, 0xfe, 0x5c, 0x06, 0x09, 0xc2, - 0xf6, 0x16, 0x14, 0x4b, 0xaf, 0x70, 0xc8, 0x3b, 0xca, 0xed, 0x32, 0xb6, 0xff, 0x62, 0x16, 0x0b, - 0x57, 0x57, 0x01, 0x38, 0x00, 0x00, 0x9e, 0x5f, 0xc7, 0xf1, 0x08, 0x01, 0xb6, 0x9e, 0x5f, 0xfb, - 0x2e, 0xbf, 0x72, 0xd3, 0x6c, 0x14, 0x21, 0xfb, 0xa6, 0x0c, 0xa3, 0x7a, 0xa0, 0xe9, 0x91, 0xe7, - 0xa7, 0x90, 0xb3, 0x59, 0x84, 0x67, 0x0b, 0x94, 0x88, 0xce, 0x52, 0xd3, 0xfe, 0x67, 0x95, 0x92, - 0xa7, 0x96, 0x3c, 0xfc, 0xf2, 0x39, 0x76, 0x14, 0x65, 0xdb, 0x77, 0x74, 0x9b, 0xd1, 0x69, 0x04, - 0xa5, 0xab, 0x66, 0x61, 0x14, 0x5a, 0xc4, 0xc2, 0x97, 0x58, 0xb2, 0x79, 0x19, 0xe3, 0x67, 0xad, - 0x01, 0x95, 0x51, 0x52, 0x00, 0x01, 0x1a, 0x75, 0xd4, 0xa2, 0x96, 0x59, 0x20, 0x64, 0x25, 0x05, - 0x13, 0xdb, 0x41, 0xe0, 0x85, 0xa5, 0xb0, 0x6d, 0x5b, 0x3c, 0x6a, 0x4c, 0x6c, 0xa4, 0x4a, 0x66, - 0x37, 0x36, 0xa8, 0x1d, 0x4b, 0x1b, 0x17, 0x3c, 0x43, 0x00, 0x00, 0x0f, 0xf6, 0xf6, 0xb0, 0x3a, - 0xff, 0x2d, 0xc1, 0x2b, 0x8c, 0xf8, 0x20, 0x38, 0xb7, 0x83, 0x49, 0x13, 0x72, 0x58, 0xa3, 0xff, - 0x96, 0x2d, 0xd7, 0x2c, 0x60, 0xe6, 0x23, 0x13, 0xe9, 0x12, 0xdc, 0xc7, 0x29, 0x52, 0x97, 0x61, - 0x27, 0x07, 0x8d, 0xb7, 0x10, 0x12, 0x47, 0x34, 0xa5, 0xa6, 0xf0, 0xfe, 0xf2, 0x39, 0x86, 0x34, - 0x33, 0x99, 0xad, 0xf5, 0xb8, 0x20, 0x69, 0x36, 0xc3, 0x36, 0x38, 0x69, 0x6c, 0x55, 0x45, 0x82, - 0xc1, 0x47, 0xb5, 0x00, 0xe6, 0x9e, 0xec, 0x9f, 0xee, 0x9d, 0xda, 0xd3, 0x2b, 0x6e, 0xd8, 0x0b, - 0xa7, 0xab, 0xca, 0xf5, 0xe8, 0xd6, 0x02, 0xfb, 0xfe, 0xa3, 0x2b, 0x5f, 0x27, 0xa7, 0xd3, 0x6a, - 0x26, 0xfb, 0x88, 0x1c, 0xc5, 0xa4, 0xfa, 0x7f, 0x29, 0xfa, 0xd3, 0x67, 0x91, 0x97, 0xae, 0x84, - 0x47, 0x28, 0x00, 0x01, 0x0c, 0x1c, 0x69, 0x6f, 0xde, 0x2c, 0x8b, 0x31, 0x90, 0x4a, 0x1f, 0x06, - 0x39, 0x85, 0x14, 0x2f, 0xf2, 0x66, 0x4e, 0xff, 0x8a, 0xef, 0x13, 0x03, 0x84, 0xc1, 0x09, 0xb8, - 0x35, 0xd2, 0x8b, 0x54, 0xb9, 0x92, 0x86, 0xbe, 0xa8, 0xa5, 0x7c, 0x1c, 0x42, 0xcd, 0x35, 0x91, - 0xa5, 0xa6, 0xf0, 0xfe, 0xf2, 0x39, 0x86, 0x34, 0xaf, 0xde, 0xd3, 0xde, 0x29, 0xed, 0x28, 0x0d, - 0x99, 0xdd, 0xfa, 0x24, 0x1f, 0x60, 0x23, 0x8f, 0x5b, 0x2b, 0x71, 0x00, 0x00, 0x00, 0x18, 0xb9, - 0xe5, 0xc0, 0x40, 0x00, 0x04, 0x38, 0x27, 0x36, 0x94, 0xd7, 0x17, 0x8b, 0x70, 0x4c, 0x86, 0x34, - 0x7b, 0xef, 0x53, 0x59, 0x91, 0x66, 0x04, 0x41, 0xa7, 0x00, 0xcf, 0x10, 0x27, 0xf0, 0xdf, 0x0b, - 0xe1, 0xdb, 0xf8, 0x57, 0x3b, 0x2b, 0x02, 0x49, 0x2b, 0x98, 0x1f, 0x79, 0x70, 0x42, 0x2b, 0xac, - 0x12, 0x63, 0x0f, 0x91, 0x9c, 0xc0, 0x65, 0x85, 0xa5, 0x63, 0x2c, 0xb0, 0x4c, 0x3b, 0x98, 0x88, - 0x18, 0x71, 0x64, 0x0d, 0xdb, 0x8c, 0xeb, 0x07, 0xd4, 0x36, 0x0f, 0xd4, 0x30, 0x84, 0x61, 0x5c, - 0x1f, 0xd1, 0x8c, 0x7e, 0x0f, 0xdf, 0xb0, 0x9c, 0xa4, 0xa7, 0x0a, 0x7e, 0xf2, 0x39, 0x76, 0x34, - 0x33, 0xd7, 0x8c, 0x35, 0x71, 0x03, 0x71, 0x5c, 0x0e, 0x58, 0xb3, 0xc3, 0x3c, 0x24, 0x94, 0x53, - 0x0f, 0x65, 0x75, 0xd3, 0xbc, 0xae, 0x3c, 0x84, 0xde, 0x62, 0x00, 0x21, 0x7b, 0x79, 0x01, 0x6f, - 0xce, 0x47, 0x16, 0xd8, 0x82, 0x42, 0xe2, 0x1c, 0x52, 0x2e, 0xaf, 0x3b, 0xf7, 0xb5, 0x7f, 0xb9, - 0xd6, 0xe7, 0x8f, 0x84, 0x3f, 0xd2, 0x99, 0x4e, 0x15, 0xe1, 0x00, 0xcf, 0x2d, 0x30, 0x00, 0x1b, - 0x38, 0xa2, 0xc8, 0xeb, 0x02, 0x91, 0xdf, 0xfa, 0x7e, 0x00, 0x09, 0x17, 0x86, 0x70, 0x64, 0x95, - 0xa6, 0xb0, 0x5a, 0x5c, 0x18, 0xf1, 0x52, 0xa9, 0x09, 0x1e, 0xb5, 0x79, 0x35, 0x49, 0xe9, 0xb4, - 0xf5, 0xc7, 0x76, 0xea, 0x2c, 0x8f, 0x8e, 0x58, 0x17, 0xaa, 0x5e, 0xa8, 0x80, 0x7a, 0xdb, 0xf8, - 0xa5, 0xaf, 0x06, 0xfe, 0xf2, 0x39, 0x96, 0x34, 0x69, 0xad, 0x39, 0xda, 0x09, 0x4e, 0x4d, 0x05, - 0x63, 0x35, 0x94, 0xf7, 0x7d, 0xae, 0xdc, 0x29, 0x81, 0xb0, 0xdc, 0xae, 0x0f, 0x94, 0x17, 0x00, - 0xce, 0x1e, 0x72, 0x1b, 0x3d, 0x8b, 0xc9, 0x6a, 0x45, 0x35, 0x59, 0x23, 0x13, 0xf9, 0x28, 0x7b, - 0x2a, 0xb1, 0x88, 0xf3, 0x75, 0x67, 0x46, 0xe3, 0xb2, 0x07, 0x9e, 0xc9, 0x85, 0x55, 0x29, 0x05, - 0x2f, 0x7a, 0x1f, 0xe9, 0xed, 0x67, 0x1d, 0x0f, 0xbe, 0x00, 0x29, 0x71, 0xfc, 0xdb, 0xe3, 0x50, - 0x81, 0x10, 0x8d, 0x27, 0x30, 0x00, 0xcc, 0x63, 0x84, 0x3e, 0xd3, 0xd0, 0x61, 0xbd, 0xe2, 0x5b, - 0x5c, 0x0f, 0x9d, 0xd4, 0x69, 0x7e, 0x1f, 0x78, 0xf7, 0xaa, 0xad, 0xfb, 0x56, 0x92, 0xfe, 0x76, - 0x02, 0x38, 0xf6, 0x61, 0x13, 0x95, 0x07, 0x28, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x39, 0x76, 0x14, - 0x35, 0x16, 0xeb, 0x64, 0x8e, 0x38, 0x4c, 0x9d, 0xa2, 0x33, 0x03, 0x67, 0x77, 0x01, 0x8b, 0x94, - 0xda, 0x0d, 0xba, 0x85, 0xab, 0xbb, 0xa7, 0xcd, 0x52, 0xd2, 0x28, 0x48, 0xfd, 0x6a, 0x9e, 0xb3, - 0x97, 0x2a, 0x67, 0x7f, 0x61, 0x7a, 0xd3, 0xc2, 0x95, 0xbc, 0xf3, 0x13, 0xbb, 0x38, 0x2c, 0x5e, - 0xf5, 0x25, 0xd5, 0x35, 0xdd, 0x30, 0xbd, 0x47, 0x6d, 0x7a, 0xdf, 0xbe, 0xe5, 0xf8, 0x87, 0xaa, - 0x00, 0x05, 0x76, 0x4e, 0x2c, 0xfc, 0x61, 0x4a, 0x0a, 0xea, 0xa0, 0xef, 0xe0, 0xce, 0xfd, 0xb2, - 0xca, 0x73, 0xa2, 0x79, 0x6c, 0x79, 0x6b, 0x05, 0xb3, 0x26, 0xd0, 0x6e, 0x98, 0xac, 0x3f, 0x08, - 0xed, 0x75, 0x09, 0xeb, 0xd5, 0xb9, 0xee, 0xd7, 0xca, 0xbe, 0x37, 0xa8, 0x31, 0x09, 0x26, 0xc6, - 0xa5, 0xaf, 0x06, 0xfe, 0xf2, 0x39, 0x76, 0x24, 0x35, 0x7f, 0x23, 0xcf, 0x33, 0x12, 0xde, 0x3c, - 0x10, 0xbc, 0xd5, 0xab, 0xb5, 0x31, 0xde, 0x73, 0xa5, 0xcf, 0xe9, 0xcd, 0xd6, 0xd8, 0xf5, 0x87, - 0x44, 0x23, 0x15, 0x25, 0x51, 0x9e, 0xb2, 0x1f, 0xa3, 0x37, 0xe5, 0x08, 0x12, 0x97, 0xf7, 0x2f, - 0x22, 0x63, 0x53, 0x76, 0x8b, 0x95, 0x50, 0x02, 0x42, 0x2f, 0x94, 0xd5, 0x56, 0x61, 0xa7, 0xde, - 0xa8, 0xcd, 0x25, 0x49, 0x6b, 0xa8, 0x93, 0x33, 0xbd, 0x25, 0x79, 0x9a, 0x79, 0xb9, 0x97, 0xe4, - 0x09, 0xd1, 0x1f, 0xfa, 0x2f, 0xb0, 0x1f, 0x03, 0xc0, 0x79, 0xe0, 0x07, 0x2c, 0xaf, 0x7b, 0xb3, - 0xbf, 0x09, 0x0d, 0x0e, 0x57, 0x8f, 0x5d, 0xa7, 0x79, 0x52, 0x13, 0xf7, 0x24, 0x90, 0x26, 0x9e, - 0x6b, 0xb3, 0x9e, 0x06, 0x3c, 0x1f, 0xd1, 0x2c, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0x96, 0x3c, - 0xaf, 0xdd, 0xec, 0xcd, 0x0b, 0x42, 0x00, 0x00, 0x2e, 0x7a, 0x81, 0xcb, 0x68, 0x5f, 0x8b, 0x27, - 0x5a, 0x66, 0x42, 0x8b, 0xcb, 0xa7, 0xf2, 0x55, 0x8c, 0xf1, 0xbd, 0xff, 0xed, 0x97, 0x68, 0x26, - 0x8d, 0xdc, 0x19, 0x36, 0xc2, 0x4a, 0xa6, 0x3a, 0x55, 0xf0, 0x04, 0x2c, 0xa2, 0x72, 0xac, 0x64, - 0xe9, 0xf3, 0x1c, 0x9d, 0x2d, 0x41, 0xb7, 0x04, 0x2a, 0x28, 0x81, 0x41, 0x4b, 0xf5, 0xc6, 0x12, - 0x71, 0xb9, 0x3a, 0x2b, 0x7d, 0xaf, 0x12, 0xa3, 0xf1, 0xbc, 0x37, 0xb5, 0x78, 0xfe, 0x0f, 0x07, - 0xe1, 0xf1, 0x7f, 0x8d, 0x2e, 0x47, 0x5c, 0x3a, 0x11, 0xa8, 0x02, 0x8a, 0x1f, 0x6b, 0xa3, 0x1e, - 0xa5, 0xb3, 0x7b, 0x04, 0xcc, 0xf9, 0x05, 0xf6, 0xad, 0xe2, 0xe2, 0x27, 0x0f, 0x0f, 0xe5, 0xdc, - 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0x96, 0x3c, 0x64, 0x11, 0x5d, 0x4e, 0x5b, 0x2d, 0x0d, 0x23, - 0xf3, 0x0c, 0x6d, 0x9b, 0x66, 0x35, 0x84, 0xb9, 0x6e, 0x3d, 0x59, 0x00, 0x52, 0xfb, 0x2f, 0x5a, - 0x0d, 0x4e, 0x83, 0x36, 0xdb, 0x38, 0xa4, 0x8f, 0x17, 0x70, 0x3f, 0x1c, 0xd9, 0xba, 0xb5, 0x08, - 0x23, 0x42, 0xe0, 0xae, 0x6b, 0xb7, 0xcc, 0x59, 0xc4, 0xdb, 0xeb, 0xc6, 0x06, 0x8c, 0x3e, 0xfc, - 0xf5, 0x86, 0x6d, 0xf7, 0xc9, 0x28, 0xba, 0x5f, 0xee, 0x8f, 0x52, 0xb4, 0x9b, 0xa7, 0xe7, 0xdb, - 0x94, 0x55, 0x09, 0xbf, 0x72, 0x00, 0x7f, 0x00, 0x7e, 0x07, 0xe1, 0xc0, 0x9f, 0xd2, 0x34, 0xad, - 0x0c, 0xcc, 0xc5, 0x71, 0x48, 0x37, 0xfc, 0xaa, 0x0d, 0x1c, 0x8d, 0xf7, 0x4c, 0x98, 0x79, 0x3a, - 0xe7, 0xba, 0x6b, 0x21, 0xc7, 0x87, 0xf7, 0x2c, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0xa6, 0x3c, - 0x37, 0x6c, 0x53, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x4b, 0x8b, 0xf6, 0x32, 0x39, 0x48, 0x5b, 0x22, - 0x4f, 0x00, 0x00, 0x00, 0xff, 0x87, 0x00, 0x75, 0x5c, 0xf4, 0x0c, 0xd0, 0xec, 0x07, 0x73, 0x83, - 0x31, 0x29, 0xdd, 0x09, 0x57, 0xd3, 0x3c, 0xda, 0xa2, 0x04, 0xb9, 0xad, 0x13, 0xa8, 0x88, 0x84, - 0x87, 0x00, 0x7a, 0xbf, 0x83, 0x33, 0x15, 0xb1, 0xb0, 0xfd, 0x78, 0x12, 0x21, 0x3f, 0x1d, 0x6f, - 0x63, 0x17, 0x1f, 0xac, 0x1c, 0xec, 0x49, 0xfd, 0xa9, 0x85, 0x4f, 0x0d, 0x3d, 0x4f, 0xc0, 0xfc, - 0x3c, 0x0f, 0x0b, 0xf2, 0x04, 0x02, 0x90, 0xff, 0x07, 0x0a, 0x8b, 0x80, 0x71, 0x85, 0xc6, 0x69, - 0xb3, 0x10, 0xa1, 0xd2, 0xdb, 0x27, 0x48, 0xc5, 0x5b, 0xbb, 0xf1, 0xe8, 0x87, 0x3c, 0x3c, 0xd5, - 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0xa6, 0x3c, 0x35, 0x16, 0xad, 0x1b, 0x11, 0x11, 0x2c, 0x31, - 0x9b, 0x11, 0xa4, 0xb4, 0x21, 0x9f, 0x58, 0xa7, 0x69, 0x72, 0x41, 0xff, 0x6d, 0xd2, 0x08, 0x82, - 0x05, 0x1f, 0x5f, 0x56, 0xb5, 0x4f, 0x9c, 0xe6, 0x63, 0xf0, 0x5f, 0xf3, 0x59, 0x48, 0xba, 0x0f, - 0xba, 0x84, 0x33, 0x25, 0x9a, 0x6a, 0x3d, 0x78, 0x05, 0xbc, 0x2f, 0x04, 0xb7, 0x68, 0xac, 0x54, - 0x2b, 0x74, 0xed, 0x1f, 0xef, 0x85, 0x94, 0xd6, 0x82, 0x33, 0xae, 0xc1, 0x19, 0x5b, 0xed, 0x5d, - 0x93, 0x50, 0xac, 0xba, 0xcf, 0xc1, 0x1f, 0xe0, 0x3f, 0x03, 0xe3, 0xc4, 0x01, 0xd7, 0x00, 0xf6, - 0xdf, 0xa6, 0xb8, 0x30, 0x7a, 0xee, 0x1a, 0x36, 0x7f, 0x38, 0x94, 0xc2, 0x6c, 0xc5, 0xab, 0xbe, - 0xc7, 0x82, 0x6b, 0xc8, 0x61, 0xc5, 0xd6, 0xfe, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0xa6, 0x34, - 0xa7, 0x93, 0xab, 0x17, 0xbc, 0xeb, 0xc1, 0x81, 0x22, 0x09, 0x43, 0x88, 0x90, 0x6f, 0x57, 0xec, - 0x00, 0x00, 0x43, 0x7c, 0x81, 0xea, 0x88, 0x05, 0xb7, 0x66, 0xc1, 0x19, 0xc7, 0xb0, 0xbd, 0x0e, - 0x1f, 0x14, 0xc9, 0x40, 0x05, 0xab, 0x02, 0xdf, 0x36, 0x96, 0xec, 0x3c, 0x43, 0xe9, 0x48, 0xba, - 0x41, 0x77, 0x10, 0x1c, 0xc9, 0xa3, 0x68, 0xa4, 0x3c, 0xf0, 0xcd, 0x87, 0x12, 0xb2, 0xc4, 0xef, - 0xd0, 0x2d, 0x71, 0xe5, 0xe6, 0x4d, 0xbf, 0x17, 0xe1, 0x98, 0xc1, 0x4f, 0x60, 0x1f, 0xc0, 0x7e, - 0x07, 0xe0, 0xf8, 0x80, 0xba, 0xbc, 0x7d, 0xe4, 0x47, 0x11, 0xde, 0xe4, 0x65, 0xe1, 0x9b, 0xc0, - 0x7a, 0x3e, 0x40, 0x76, 0x3c, 0x94, 0xe3, 0x1d, 0x5e, 0x5a, 0x40, 0xdb, 0xe8, 0x18, 0x29, 0x7c, - 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0xb6, 0x34, 0x65, 0xca, 0x46, 0xb9, 0x0b, 0x52, 0x79, 0x41, - 0x19, 0xc3, 0x73, 0x41, 0x1c, 0x52, 0xc7, 0x42, 0xc6, 0xcc, 0x7f, 0xb4, 0xf0, 0x18, 0x20, 0x04, - 0x05, 0xc7, 0x3d, 0x84, 0x7a, 0x66, 0xbf, 0x9e, 0xb3, 0x80, 0xf8, 0x8c, 0xb8, 0x90, 0x9a, 0xc0, - 0x59, 0x00, 0x50, 0xa7, 0xf1, 0x3b, 0xf6, 0xbe, 0x59, 0xf8, 0x13, 0xae, 0x02, 0x45, 0xe9, 0xb5, - 0x3c, 0x3d, 0xa3, 0x50, 0xab, 0x50, 0x84, 0x22, 0xfa, 0xc3, 0xc7, 0x70, 0x15, 0x5a, 0x18, 0x73, - 0xae, 0xb3, 0xdb, 0x73, 0x9f, 0x71, 0x55, 0xfc, 0x03, 0xf0, 0x1f, 0x81, 0xc1, 0x4f, 0x75, 0xd8, - 0x5a, 0x3d, 0x42, 0xfc, 0xc3, 0x81, 0x58, 0x1a, 0xb3, 0x61, 0xf4, 0xa5, 0x5d, 0xbd, 0x1c, 0xd3, - 0x7e, 0xfe, 0xbc, 0xf4, 0x1c, 0xe7, 0xda, 0x55, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0x96, 0x3c, - 0x63, 0xc0, 0x39, 0x41, 0x09, 0x13, 0x33, 0xb4, 0x49, 0x82, 0x56, 0xb8, 0x0c, 0xaf, 0x54, 0x24, - 0x61, 0x6b, 0x00, 0x02, 0x55, 0xf8, 0x02, 0x36, 0x24, 0x97, 0x94, 0x17, 0x16, 0xff, 0xc5, 0x5a, - 0x22, 0x7c, 0x45, 0x25, 0xe0, 0x41, 0xe4, 0x40, 0xf9, 0x20, 0x3c, 0xe0, 0x48, 0xbe, 0xa1, 0x54, - 0xef, 0x5d, 0x3a, 0xfb, 0x00, 0xf2, 0x43, 0xda, 0x97, 0x91, 0x47, 0xeb, 0xaf, 0x0a, 0x51, 0x4e, - 0x1c, 0x1d, 0xe5, 0x97, 0x28, 0x4b, 0xa7, 0x23, 0xf4, 0x01, 0xac, 0x53, 0x22, 0x1c, 0xff, 0x07, - 0xf8, 0x0f, 0xc0, 0xfc, 0x1e, 0x02, 0x1d, 0xa7, 0xa3, 0x6b, 0x16, 0x58, 0x99, 0xd1, 0xd9, 0xd7, - 0x5a, 0x5c, 0x25, 0x4f, 0x1b, 0x83, 0x10, 0x9b, 0x65, 0x52, 0xc8, 0xaf, 0x76, 0x22, 0x1c, 0xde, - 0xa5, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0xb6, 0x3c, 0x65, 0xc6, 0xcd, 0x55, 0x50, 0x3d, 0x97, 0x82, - 0x9f, 0x19, 0x08, 0xd8, 0x1e, 0x75, 0xd2, 0x61, 0xc1, 0x35, 0x05, 0xfb, 0x13, 0xa6, 0x14, 0x63, - 0x87, 0x4d, 0x51, 0x0e, 0x16, 0x3b, 0x43, 0xaa, 0xc2, 0x72, 0xbf, 0x1f, 0x9c, 0xf5, 0xc1, 0x07, - 0xc2, 0xc5, 0xd2, 0x77, 0xe1, 0x39, 0xff, 0x43, 0x15, 0x29, 0x64, 0x5b, 0xa3, 0x44, 0x78, 0x93, - 0x88, 0xc1, 0x82, 0x3a, 0x25, 0x6d, 0x0c, 0xbc, 0x4b, 0xba, 0xca, 0xbe, 0xbb, 0x19, 0xe4, 0x8e, - 0x76, 0x0c, 0xe5, 0x8c, 0x8d, 0xcf, 0xe0, 0x7c, 0x3c, 0xc6, 0x0c, 0xfb, 0xdb, 0x2e, 0x16, 0x35, - 0x91, 0x51, 0x29, 0x18, 0x54, 0xad, 0x0b, 0x07, 0x76, 0x42, 0xd7, 0x55, 0x12, 0x6d, 0xce, 0x2f, - 0x7f, 0xe0, 0x78, 0xe0, 0xfe, 0xe6, 0xb2, 0x27, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x46, 0x3c, - 0xa7, 0x93, 0xab, 0x44, 0xbe, 0xa7, 0x80, 0x9c, 0xd3, 0xf8, 0xe1, 0x27, 0x07, 0x73, 0x64, 0x42, - 0xc1, 0x1d, 0x6c, 0x8b, 0xe3, 0xc5, 0x99, 0x2d, 0xf9, 0x62, 0x2e, 0xda, 0xf6, 0xb7, 0x19, 0x5a, - 0x06, 0x49, 0x62, 0x8f, 0x30, 0xe9, 0xb1, 0xc4, 0xd1, 0x09, 0x46, 0x15, 0xc2, 0xd6, 0x7e, 0x50, - 0xf7, 0xef, 0x31, 0x82, 0xef, 0xfb, 0xe2, 0xee, 0xd2, 0x20, 0xcb, 0xe4, 0x73, 0x7b, 0x49, 0x44, - 0x67, 0x23, 0x2e, 0xb8, 0x22, 0xa0, 0xd8, 0xe9, 0xbd, 0x30, 0x34, 0x65, 0x51, 0x6c, 0x01, 0xf7, - 0x80, 0x7e, 0x0f, 0x87, 0xc6, 0x78, 0xcf, 0x07, 0x77, 0x6c, 0x92, 0x63, 0xd6, 0xab, 0x53, 0xbd, - 0x59, 0x26, 0x10, 0xd2, 0xbe, 0xc8, 0x61, 0x41, 0xf0, 0x34, 0x63, 0xf1, 0x10, 0x4c, 0xaa, 0x2c, - 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0x86, 0x3c, 0xaa, 0x5a, 0xbb, 0xd7, 0xf8, 0xbb, 0x6f, 0xc4, - 0xc0, 0x30, 0x3e, 0x19, 0xe0, 0xf5, 0x55, 0x89, 0x37, 0x28, 0xd4, 0x29, 0x0d, 0x1f, 0xfa, 0xc2, - 0x00, 0x12, 0xad, 0x18, 0xd3, 0x85, 0x03, 0xd1, 0x26, 0xba, 0xc3, 0x95, 0x73, 0x0a, 0xff, 0x05, - 0x55, 0xee, 0x12, 0x41, 0x6d, 0x0c, 0x06, 0xf7, 0x01, 0x63, 0x20, 0xf6, 0xf5, 0x75, 0xcb, 0xf4, - 0x34, 0xf4, 0x0d, 0x55, 0x2e, 0x64, 0x61, 0x96, 0xc1, 0x14, 0x18, 0xf0, 0x06, 0xc1, 0x36, 0xa1, - 0xcb, 0xd5, 0x81, 0x08, 0xa3, 0x8a, 0xc0, 0x7f, 0x01, 0xf8, 0x3e, 0x0e, 0x47, 0x81, 0xc7, 0x8c, - 0xa3, 0xf0, 0x44, 0x41, 0x97, 0x61, 0xbd, 0x28, 0x73, 0x24, 0xa1, 0xfc, 0x76, 0x76, 0x57, 0x68, - 0x00, 0x00, 0x08, 0xc3, 0xc1, 0x08, 0xa3, 0x8e, 0x85, 0xaf, 0x06, 0xfe, 0xf2, 0x19, 0x96, 0x3c, - 0x69, 0xb1, 0xb3, 0x14, 0xc6, 0x0a, 0xef, 0xfa, 0x49, 0x55, 0xc7, 0xd6, 0xd6, 0x6f, 0xca, 0x4d, - 0x80, 0x0c, 0x07, 0x98, 0xef, 0xb9, 0xdd, 0xf0, 0x2c, 0x72, 0xfb, 0x82, 0x00, 0xc4, 0xf9, 0x7a, - 0x77, 0x18, 0xf7, 0x13, 0xcd, 0x32, 0x82, 0x84, 0xf3, 0xde, 0x5d, 0xee, 0xec, 0x4a, 0x5a, 0xca, - 0xcd, 0xe0, 0xbe, 0x24, 0xd0, 0xcf, 0xfa, 0xa2, 0x60, 0x8a, 0x57, 0xa1, 0x74, 0x0e, 0xe1, 0xf9, - 0xc5, 0xe7, 0x75, 0x25, 0xe2, 0x19, 0xb8, 0xab, 0x49, 0xea, 0xe3, 0x48, 0x22, 0x98, 0x7e, 0x0f, - 0x81, 0xf1, 0xc1, 0x70, 0xe7, 0xc4, 0xea, 0x0e, 0x16, 0xd8, 0xfb, 0xb9, 0x93, 0x5c, 0x6d, 0x54, - 0x08, 0x7e, 0xc7, 0x90, 0xb6, 0xe5, 0xa7, 0x1f, 0xf1, 0xea, 0xcf, 0xc7, 0xf1, 0xea, 0x71, 0x4c, - 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, 0x66, 0x71, 0x12, 0xfb, 0xfc, 0xc3, 0xd6, 0xee, - 0x81, 0x60, 0xf5, 0x11, 0x13, 0x17, 0xd4, 0xe0, 0x47, 0x5f, 0x2b, 0x34, 0x69, 0x01, 0x01, 0xfa, - 0xe3, 0x71, 0x62, 0xd5, 0xfd, 0xc6, 0xad, 0xa8, 0xa1, 0x71, 0x0d, 0x50, 0x8b, 0x5f, 0x94, 0xa9, - 0xc6, 0x7b, 0xea, 0x99, 0x12, 0x7b, 0xcf, 0x33, 0xe1, 0x70, 0x52, 0x96, 0x14, 0xb9, 0xb6, 0x56, - 0x20, 0xcf, 0x88, 0x7a, 0x3c, 0x00, 0xf5, 0x8d, 0x82, 0xdc, 0x0c, 0xc0, 0x57, 0xfd, 0xb5, 0xb5, - 0x59, 0x4f, 0xd7, 0xde, 0xa0, 0x3e, 0x03, 0xf0, 0x7c, 0x38, 0x2f, 0x82, 0x4a, 0x02, 0x18, 0xcf, - 0xca, 0xe8, 0xd2, 0x49, 0xee, 0x11, 0x96, 0x2e, 0x8a, 0x02, 0xf1, 0x62, 0x10, 0x78, 0x87, 0x8e, - 0x41, 0x1f, 0x08, 0xc1, 0xa7, 0x11, 0xc5, 0xfc, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, - 0xaf, 0xa6, 0xc8, 0x17, 0xa3, 0x84, 0xdd, 0xa9, 0x0a, 0x0e, 0x89, 0xbc, 0x1f, 0xf0, 0x65, 0x09, - 0x6a, 0x1d, 0x56, 0x2f, 0xf0, 0xcd, 0xa6, 0xba, 0xcb, 0xa2, 0x5d, 0xcf, 0xe8, 0x89, 0x91, 0x7d, - 0x62, 0x41, 0x4e, 0xf4, 0x85, 0xf9, 0x49, 0xeb, 0xaa, 0x66, 0xb7, 0xd9, 0x79, 0x47, 0xfd, 0x78, - 0x49, 0x3b, 0x68, 0x11, 0xfb, 0xee, 0x8a, 0x55, 0x05, 0x04, 0x35, 0xb7, 0x0d, 0x1a, 0xe3, 0xdd, - 0x59, 0xbe, 0xf7, 0xfc, 0x1a, 0xac, 0x1c, 0x3d, 0x70, 0xce, 0xfe, 0x98, 0x40, 0xd7, 0x0f, 0xd0, - 0x7e, 0x1f, 0x0c, 0x1c, 0x32, 0xbe, 0x5f, 0x1a, 0xc2, 0xab, 0xfc, 0xb0, 0xbd, 0x6c, 0x64, 0xf5, - 0x7f, 0x9b, 0xd3, 0x42, 0x77, 0x73, 0xe2, 0x04, 0xdc, 0xf5, 0x7f, 0x9e, 0x3e, 0xdc, 0x61, 0xd7, - 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, 0x66, 0x6e, 0xc7, 0xba, 0x0b, 0x00, 0x5e, 0x7e, - 0x17, 0x39, 0xe6, 0x76, 0xdb, 0x13, 0xa6, 0x5b, 0x1a, 0x16, 0x1c, 0x88, 0x6f, 0x59, 0x98, 0xe0, - 0x7e, 0x5d, 0xe7, 0xd0, 0xb9, 0x93, 0xdd, 0xf9, 0x87, 0xc2, 0x84, 0xf1, 0xab, 0x86, 0x07, 0x37, - 0x72, 0x2b, 0xcb, 0xb4, 0xe6, 0x9b, 0x62, 0x26, 0x81, 0xde, 0xae, 0xf2, 0x4a, 0x5d, 0xf8, 0xb8, - 0xaa, 0xfa, 0x96, 0x1c, 0x54, 0x35, 0x43, 0xfe, 0xda, 0xeb, 0xc7, 0x9d, 0x8f, 0xbf, 0xc6, 0xb5, - 0x87, 0x7a, 0xc3, 0x90, 0x02, 0x4e, 0xb0, 0x3f, 0x03, 0xf0, 0x78, 0x79, 0x1f, 0x8e, 0x15, 0x14, - 0xa1, 0xae, 0x84, 0x3b, 0x09, 0x62, 0x15, 0x7c, 0x50, 0xf7, 0x78, 0xed, 0x72, 0x41, 0x63, 0xcf, - 0xb3, 0xf0, 0xb0, 0x08, 0x70, 0x26, 0x49, 0xd6, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x2c, - 0x69, 0xd5, 0x7a, 0x69, 0x80, 0x89, 0x16, 0x0e, 0x00, 0x8e, 0xdd, 0xe8, 0xba, 0x4a, 0xb8, 0xd4, - 0x9f, 0x71, 0xd7, 0x2a, 0xd2, 0xf5, 0x0c, 0xc3, 0x4f, 0xfb, 0x22, 0x11, 0x30, 0xb1, 0x93, 0x21, - 0x19, 0x9a, 0xb8, 0x73, 0x51, 0x9e, 0x2a, 0x77, 0x0f, 0x61, 0xbb, 0x18, 0x26, 0x3a, 0x10, 0x35, - 0x4a, 0xa3, 0x35, 0x10, 0x92, 0x56, 0xf5, 0xf5, 0x6e, 0xb8, 0x73, 0x7f, 0xf7, 0x78, 0xd2, 0x36, - 0x2e, 0x72, 0xfa, 0x9d, 0x7a, 0xdd, 0xe3, 0x6a, 0x0e, 0x47, 0x06, 0xa3, 0x23, 0x9f, 0x60, 0x7c, - 0x0f, 0x87, 0x99, 0x1e, 0x63, 0x8f, 0x66, 0xc4, 0x31, 0x76, 0x2d, 0x6a, 0x06, 0xc4, 0xd0, 0x4d, - 0x39, 0x53, 0x65, 0x85, 0x6c, 0xd7, 0x65, 0xdd, 0xf9, 0xa6, 0xf2, 0x18, 0x18, 0x9c, 0x8a, 0xd5, - 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, 0xaf, 0xae, 0x7f, 0x37, 0x7c, 0x7e, 0xc8, 0x66, - 0x0c, 0xdb, 0xf9, 0x2a, 0xd1, 0xdc, 0x4b, 0xd9, 0xa3, 0x2d, 0xb4, 0x03, 0xae, 0x50, 0x54, 0x60, - 0xdb, 0xbe, 0x75, 0xe2, 0xb8, 0x20, 0xee, 0x0d, 0x6f, 0x53, 0xaf, 0xce, 0x03, 0x41, 0xc2, 0xc2, - 0xbb, 0xd5, 0x1f, 0xb8, 0x7f, 0x2c, 0xad, 0x56, 0x3b, 0x9b, 0xd7, 0xc9, 0xfc, 0xaf, 0x0a, 0x43, - 0x4c, 0xa2, 0xde, 0x6d, 0xf0, 0x57, 0x61, 0x8a, 0x55, 0x0b, 0x3c, 0x37, 0xbc, 0xf5, 0x9f, 0xda, - 0x35, 0xf9, 0x86, 0x34, 0xd4, 0x57, 0x30, 0x7f, 0x07, 0x83, 0xe1, 0xc0, 0x3e, 0x44, 0x81, 0x64, - 0x89, 0x31, 0xd2, 0xa8, 0x04, 0xe1, 0x52, 0x99, 0x84, 0x7b, 0x8b, 0x4d, 0x00, 0x92, 0x95, 0x49, - 0x52, 0x69, 0x84, 0xf8, 0xc7, 0x9a, 0x89, 0xe7, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x56, 0x3c, - 0x33, 0xd2, 0xb4, 0x9f, 0x05, 0xe1, 0xfa, 0x45, 0x00, 0x6f, 0x0a, 0x22, 0x3e, 0x60, 0xae, 0xcf, - 0xa0, 0x2f, 0xfc, 0xb6, 0xa8, 0x52, 0x88, 0x72, 0x12, 0xbe, 0xe9, 0xf3, 0xdc, 0xca, 0xa7, 0xe4, - 0xdd, 0x5a, 0x49, 0x6b, 0x42, 0x48, 0xc7, 0xde, 0x5b, 0x86, 0xf8, 0xd1, 0xc3, 0x56, 0x13, 0x97, - 0x12, 0x80, 0x6b, 0xab, 0x24, 0x24, 0x85, 0xb5, 0x76, 0x41, 0x3a, 0xeb, 0xa4, 0x51, 0xfd, 0x78, - 0x00, 0xd0, 0xa4, 0x3c, 0x79, 0xce, 0x54, 0xc2, 0x36, 0x15, 0x99, 0x46, 0xe7, 0x23, 0x00, 0x7f, - 0x01, 0xe0, 0xf8, 0x78, 0x37, 0xe3, 0x44, 0xf0, 0xc0, 0x24, 0xd0, 0xc9, 0x9c, 0x03, 0xe4, 0x7f, - 0x96, 0x92, 0x05, 0x40, 0xdf, 0xdf, 0x5c, 0xe6, 0xd3, 0xb9, 0xb8, 0x09, 0x04, 0x3b, 0x9c, 0x8c, - 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x76, 0x3c, 0xaa, 0x72, 0x73, 0xe5, 0x5b, 0x51, 0x7c, 0xb3, - 0x87, 0x46, 0x40, 0x43, 0xe4, 0x19, 0x48, 0x8a, 0xe9, 0x8c, 0x51, 0x10, 0x86, 0x49, 0x47, 0x2b, - 0xdc, 0x88, 0x66, 0xe1, 0x44, 0x5c, 0x6e, 0x7b, 0xcd, 0x5d, 0xb6, 0x3b, 0xb2, 0xd5, 0x9f, 0x93, - 0xd0, 0x94, 0xef, 0xe0, 0x13, 0x33, 0x83, 0xa1, 0x37, 0xb6, 0xc8, 0xc7, 0x15, 0xdb, 0xbf, 0xac, - 0x97, 0xaa, 0x34, 0xe2, 0x45, 0x35, 0xaf, 0x75, 0x67, 0xf1, 0x7a, 0x71, 0xa6, 0xd1, 0x73, 0xdf, - 0x9f, 0x72, 0x46, 0xf8, 0x20, 0xfe, 0x07, 0xc1, 0xf8, 0x3c, 0x1f, 0xc7, 0x06, 0xc5, 0xe4, 0x52, - 0xd2, 0x6f, 0x92, 0x73, 0x58, 0x22, 0xbb, 0xda, 0x8d, 0xc1, 0xa4, 0xf4, 0xa8, 0x4f, 0x5a, 0xb1, - 0x90, 0x29, 0x48, 0x66, 0x47, 0x8d, 0x3a, 0x0c, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x2c, - 0xaf, 0xdd, 0x47, 0x5c, 0xbe, 0xa2, 0xfd, 0xbc, 0xa0, 0x77, 0xc9, 0x9e, 0x7b, 0xc3, 0x7e, 0x20, - 0xd5, 0x15, 0x36, 0xfd, 0x0d, 0xbd, 0xf2, 0x45, 0xb9, 0x05, 0x4f, 0x58, 0xe0, 0xe6, 0x09, 0x9a, - 0x6a, 0xf0, 0xdc, 0x35, 0x0d, 0xe7, 0x80, 0x71, 0xff, 0x81, 0x7f, 0x77, 0xc4, 0xd4, 0x30, 0x13, - 0xdc, 0x3a, 0x2f, 0x79, 0x06, 0x88, 0x87, 0xe1, 0xb9, 0x0c, 0x54, 0xb7, 0xa9, 0xf8, 0x38, 0xed, - 0xa1, 0x82, 0xdd, 0x87, 0xfd, 0x51, 0x3b, 0xe4, 0x1b, 0xb1, 0x30, 0x4e, 0xb7, 0x9e, 0x03, 0xfc, - 0x3e, 0x07, 0xc3, 0xec, 0x43, 0xb8, 0xb3, 0x8d, 0x19, 0xc6, 0x43, 0x27, 0x8f, 0x09, 0x63, 0xe5, - 0xc4, 0x07, 0x41, 0x6f, 0x13, 0x00, 0x79, 0xdd, 0x09, 0x27, 0xde, 0xc4, 0x71, 0x4b, 0xf7, 0xbc, - 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x56, 0x3c, 0xaa, 0x55, 0xb7, 0x24, 0x58, 0x31, 0x2f, 0x97, - 0x1f, 0x7f, 0x50, 0x76, 0x2c, 0x74, 0x2d, 0xf6, 0xd9, 0xdb, 0xbd, 0x07, 0x39, 0xb5, 0x5a, 0xed, - 0x8d, 0xdc, 0x64, 0x0c, 0x5b, 0x27, 0xc7, 0x96, 0xf2, 0xfc, 0x31, 0x3d, 0x42, 0x39, 0x15, 0x6a, - 0x6b, 0x9d, 0x6e, 0xaf, 0x1e, 0x9a, 0x9c, 0x38, 0x0f, 0xe3, 0x9e, 0xec, 0xd5, 0xed, 0x41, 0x3c, - 0xf8, 0x11, 0xb0, 0x5e, 0x42, 0x46, 0x77, 0xde, 0xb3, 0x5c, 0xd0, 0xba, 0x83, 0xa8, 0xf0, 0x34, - 0x96, 0x44, 0x95, 0xee, 0xfc, 0x07, 0xf0, 0x1f, 0x81, 0xf0, 0xfc, 0x41, 0xfb, 0x1f, 0x47, 0xf8, - 0xcf, 0xef, 0xce, 0xef, 0xaf, 0x96, 0xdf, 0x00, 0x58, 0x72, 0x83, 0xdb, 0x24, 0x20, 0x01, 0xef, - 0x9f, 0x44, 0xb9, 0xa4, 0xe2, 0x91, 0x94, 0xec, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, - 0x66, 0x6e, 0xc7, 0xe6, 0x2e, 0x32, 0x8e, 0x22, 0x9e, 0x55, 0x80, 0x61, 0xe0, 0x8a, 0xa5, 0x3f, - 0x95, 0xe0, 0x55, 0x60, 0x2e, 0xba, 0xaa, 0x4e, 0xd2, 0xfa, 0x76, 0x7c, 0x31, 0xcd, 0x9a, 0xd4, - 0xfc, 0x7d, 0xd3, 0xd3, 0x8c, 0x33, 0x03, 0x2d, 0x76, 0x18, 0xfb, 0x43, 0x89, 0x31, 0xd6, 0x02, - 0xa0, 0x6d, 0x55, 0x10, 0xe8, 0xae, 0x37, 0xe5, 0x60, 0x47, 0xcf, 0xf7, 0x22, 0x25, 0xe6, 0xf7, - 0xcb, 0x99, 0x6d, 0x2d, 0xdb, 0x02, 0x69, 0x16, 0x15, 0x56, 0x6b, 0x07, 0xb1, 0x69, 0xf3, 0x80, - 0xfc, 0x07, 0xf0, 0x7c, 0x70, 0xe6, 0xfd, 0x75, 0x86, 0x94, 0x6b, 0xf8, 0x28, 0x5b, 0x49, 0xf8, - 0x74, 0xc2, 0xba, 0x58, 0xc7, 0x55, 0xb8, 0xc9, 0x9e, 0x2f, 0xfc, 0x03, 0x0f, 0xe2, 0xd3, 0xce, - 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, 0xaa, 0x6f, 0x07, 0xbb, 0x3f, 0xd8, 0x79, 0x25, - 0x03, 0x41, 0x4e, 0x0b, 0x33, 0x5a, 0x0b, 0x82, 0x3d, 0xae, 0xe8, 0x10, 0x72, 0xb5, 0x7b, 0x96, - 0xe7, 0xd0, 0xc0, 0x40, 0x2f, 0x17, 0x6a, 0x9e, 0xbd, 0xe2, 0x7f, 0xbb, 0x36, 0x3a, 0xb9, 0x0f, - 0x7f, 0x96, 0xf2, 0xfe, 0x0b, 0x12, 0xe9, 0xca, 0xe8, 0x2f, 0x0f, 0x1e, 0x27, 0xf6, 0x80, 0x27, - 0x01, 0x37, 0x81, 0xfe, 0x86, 0x2a, 0x0e, 0x79, 0x90, 0x70, 0xf5, 0xe4, 0xe9, 0x8e, 0x3c, 0x79, - 0xff, 0x3f, 0xf1, 0xc9, 0x02, 0x0b, 0xf1, 0x1f, 0x81, 0xf0, 0x3e, 0xc1, 0xe1, 0x72, 0x33, 0xaf, - 0x29, 0xd5, 0x37, 0x5e, 0x2b, 0x97, 0xdc, 0x9a, 0x12, 0x5c, 0xaf, 0x19, 0x79, 0x9f, 0xa0, 0xef, - 0x02, 0x66, 0xbf, 0x03, 0x82, 0x96, 0x5a, 0xf1, 0x71, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x56, 0x2c, - 0x66, 0x71, 0x55, 0x28, 0xc7, 0xcb, 0x12, 0xbc, 0x67, 0x7c, 0x14, 0xa5, 0xed, 0x35, 0x49, 0x59, - 0x92, 0xd0, 0x51, 0x5d, 0xf1, 0x08, 0x93, 0x64, 0x87, 0xe2, 0x37, 0xe7, 0x02, 0xb8, 0x39, 0xd9, - 0xef, 0xb3, 0x82, 0xd5, 0x1b, 0x32, 0xaa, 0xc6, 0x89, 0x03, 0x80, 0x1c, 0xd4, 0x95, 0x85, 0xc5, - 0xeb, 0x0e, 0x7a, 0x53, 0x7b, 0xfb, 0x24, 0xed, 0x64, 0x1a, 0xe0, 0x87, 0xb8, 0xe5, 0xcf, 0xbe, - 0x6c, 0x17, 0xf2, 0xd6, 0x02, 0x6e, 0x78, 0xa0, 0xc9, 0xfd, 0x8e, 0xd0, 0x00, 0x3f, 0x80, 0xf8, - 0x7e, 0x1f, 0x01, 0x83, 0xe7, 0x04, 0xf8, 0x8c, 0xf0, 0xb5, 0x6f, 0x92, 0xff, 0x8c, 0x32, 0xf8, - 0x12, 0xba, 0xad, 0x59, 0x59, 0x9d, 0x25, 0x6a, 0x6c, 0x4c, 0x81, 0x04, 0xf7, 0x9e, 0xce, 0x80, - 0x71, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x34, 0x65, 0xc9, 0xf7, 0x20, 0x2d, 0xee, 0x82, 0xd8, - 0x1b, 0xb4, 0x62, 0x09, 0x60, 0x29, 0xa1, 0xe1, 0x0d, 0xa7, 0x29, 0xab, 0x31, 0x41, 0x5d, 0x5b, - 0x6c, 0xdf, 0x28, 0xd1, 0x8f, 0x35, 0xa7, 0x24, 0x46, 0xaf, 0x3d, 0xf8, 0xb1, 0xc8, 0x97, 0x1b, - 0x15, 0xae, 0xc8, 0x97, 0x73, 0x95, 0x1d, 0x45, 0x8b, 0xc9, 0x51, 0xeb, 0x9e, 0x15, 0x5d, 0xc4, - 0x20, 0x6b, 0x11, 0x03, 0x23, 0xb9, 0x7d, 0x95, 0xe5, 0x4a, 0x8b, 0x03, 0x69, 0x3c, 0x1f, 0xbe, - 0x8e, 0xf6, 0xe8, 0x93, 0xb3, 0x07, 0xe0, 0x7e, 0x07, 0x81, 0xe0, 0xf1, 0xc7, 0xcc, 0xc3, 0xb1, - 0x6f, 0x14, 0x01, 0x4d, 0xd9, 0x3c, 0xf1, 0x06, 0x1f, 0x35, 0x98, 0x90, 0xaf, 0x1f, 0x19, 0x61, - 0x82, 0x33, 0xfd, 0xe0, 0xa1, 0x0a, 0x62, 0x63, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x56, 0x3c, - 0x63, 0xbe, 0x62, 0x88, 0xda, 0xfc, 0x1e, 0x11, 0x29, 0x0c, 0xe5, 0x1b, 0xe5, 0x41, 0xba, 0xb3, - 0xcf, 0x4a, 0xda, 0xa2, 0x7e, 0x6d, 0x8b, 0xf8, 0xfc, 0xf1, 0x9e, 0x17, 0x6c, 0x9d, 0x19, 0xdd, - 0x81, 0x15, 0xa4, 0x32, 0x73, 0x7e, 0xba, 0xc3, 0x7d, 0x0b, 0xbc, 0x10, 0x11, 0x2f, 0x5f, 0xed, - 0xad, 0xc7, 0x7c, 0x0a, 0xc1, 0xb3, 0xef, 0x0a, 0xec, 0x13, 0x08, 0x9e, 0x12, 0x64, 0xce, 0xf8, - 0xe8, 0x23, 0xf6, 0x67, 0xac, 0x53, 0x50, 0xdc, 0x4a, 0xfc, 0xc3, 0xc0, 0x92, 0x0b, 0x2b, 0xf8, - 0x1f, 0xc1, 0xfc, 0x0f, 0x0f, 0x38, 0xf8, 0x91, 0xa0, 0x10, 0x29, 0x4c, 0xb2, 0xd0, 0x3d, 0x2a, - 0x06, 0xbc, 0x8b, 0x82, 0x18, 0x90, 0x62, 0x7f, 0x67, 0x7e, 0x75, 0xc1, 0xf5, 0x2c, 0x82, 0xc3, - 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x76, 0x3c, 0x65, 0xdb, 0x69, 0x4c, 0x00, 0x13, 0x80, 0x00, - 0xa5, 0x3d, 0x13, 0x89, 0x11, 0xac, 0x4b, 0x54, 0xdf, 0x73, 0xd1, 0x09, 0x20, 0xc5, 0xd0, 0xd5, - 0x16, 0x47, 0xd8, 0x32, 0x19, 0x4c, 0xa9, 0x7b, 0xb5, 0x42, 0x72, 0x3c, 0x77, 0x89, 0xad, 0xbc, - 0xc0, 0x34, 0xdd, 0xb3, 0x24, 0x80, 0x12, 0x92, 0x8b, 0x8c, 0x31, 0xe9, 0x75, 0x5d, 0x72, 0xc9, - 0x27, 0x0f, 0x5c, 0xc0, 0xb4, 0xbe, 0x67, 0xa3, 0xcc, 0x0f, 0x48, 0x47, 0xbd, 0x9b, 0x05, 0x1c, - 0xbc, 0xa6, 0x41, 0x21, 0x8c, 0x51, 0x78, 0x0f, 0xc0, 0xfc, 0x3f, 0x87, 0xe3, 0x0e, 0x0e, 0xba, - 0xad, 0x50, 0x32, 0xf1, 0x76, 0xa4, 0xf9, 0x0c, 0x36, 0xc1, 0xdd, 0xbc, 0xbf, 0x68, 0x70, 0x01, - 0xc4, 0xe4, 0x17, 0xe2, 0x12, 0x28, 0xc5, 0x9f, 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, - 0x35, 0x0a, 0x9e, 0x71, 0xc2, 0xab, 0x24, 0xaf, 0x16, 0xa5, 0x65, 0x01, 0x3c, 0x0e, 0x39, 0x42, - 0x75, 0xf5, 0x02, 0xf0, 0x1a, 0xf6, 0xec, 0xa3, 0x9d, 0xda, 0x93, 0x3d, 0x5f, 0xa8, 0x95, 0xa8, - 0xd0, 0xc3, 0x2c, 0xa8, 0x3a, 0x02, 0x84, 0x45, 0x79, 0x0a, 0x6f, 0x0f, 0x3c, 0xae, 0x11, 0x18, - 0xd9, 0xfe, 0xf6, 0x1c, 0xb0, 0xe0, 0x09, 0x42, 0xd7, 0xe4, 0xec, 0xd2, 0x47, 0xd4, 0xf6, 0xd7, - 0x6e, 0xe3, 0xdf, 0x4e, 0xa0, 0xd7, 0xb3, 0xaa, 0xf6, 0x28, 0x1a, 0xbb, 0x01, 0xc3, 0xaf, 0xc0, - 0xfe, 0x03, 0xf0, 0x7e, 0x3e, 0x70, 0x7c, 0x66, 0x21, 0xe9, 0x30, 0x96, 0xae, 0x2e, 0x1c, 0x3c, - 0xcc, 0x68, 0xec, 0xb1, 0x25, 0x1f, 0xed, 0xaf, 0xeb, 0xd8, 0x89, 0x3c, 0x27, 0x62, 0x38, 0xb1, - 0x91, 0x6a, 0xd2, 0xce, 0xf2, 0x19, 0x66, 0x3c, 0xaf, 0xd8, 0x66, 0x50, 0x91, 0xce, 0x6e, 0x00, - 0x93, 0x92, 0xf8, 0x3f, 0x41, 0xce, 0x85, 0xf2, 0xea, 0x59, 0x43, 0x74, 0x9f, 0x02, 0x89, 0x7c, - 0xae, 0xc0, 0x18, 0x11, 0x3d, 0x87, 0x63, 0xe9, 0x07, 0xe0, 0xe7, 0x0b, 0x24, 0x7b, 0x46, 0xb2, - 0x3b, 0x4b, 0x21, 0xa9, 0x3e, 0x9b, 0xaa, 0x34, 0x12, 0xa5, 0xbb, 0x35, 0x52, 0xcc, 0x1f, 0xf2, - 0x15, 0x35, 0x3d, 0xa9, 0x0b, 0xd4, 0xbc, 0xbc, 0x06, 0x48, 0x40, 0x53, 0x29, 0x4d, 0x96, 0x1f, - 0xdc, 0x41, 0x94, 0xd4, 0x06, 0x0f, 0xc1, 0xf1, 0xe1, 0xc4, 0x47, 0xc0, 0xf2, 0xb8, 0x9c, 0xc0, - 0x18, 0x92, 0xe2, 0x92, 0x79, 0x25, 0x6a, 0x4e, 0x5c, 0xa5, 0x43, 0x03, 0x9d, 0x56, 0x9e, 0x04, - 0x0c, 0x47, 0xc3, 0x07, 0x86, 0x7d, 0x51, 0xb0, 0x71, 0x72, 0x90, 0x4e, 0xf2, 0x19, 0x36, 0x3c, - 0xaf, 0xde, 0xd9, 0x76, 0xbf, 0xd7, 0xe9, 0x42, 0x20, 0x1c, 0xba, 0xc5, 0xd2, 0x84, 0x1a, 0xc9, - 0xfe, 0xe0, 0xa4, 0x27, 0x91, 0x41, 0x2c, 0x90, 0x21, 0x2f, 0x13, 0xa4, 0x90, 0x44, 0x9c, 0xe3, - 0x21, 0x0b, 0x2f, 0x1b, 0x7a, 0x7c, 0x3d, 0x4b, 0xf1, 0x4d, 0x92, 0x96, 0xea, 0xbe, 0x8b, 0xa2, - 0x21, 0xad, 0x9a, 0x4f, 0x38, 0xb1, 0xe6, 0x7b, 0x70, 0xe0, 0x53, 0xf4, 0xbb, 0x30, 0xf4, 0xa4, - 0xc8, 0x9c, 0x64, 0x84, 0xb5, 0x79, 0xb3, 0x29, 0x8a, 0x99, 0xc4, 0x2c, 0x0e, 0xb8, 0x70, 0xfe, - 0x0f, 0xfc, 0x42, 0x32, 0x6f, 0x4b, 0x8d, 0x8a, 0x00, 0xc9, 0x86, 0x90, 0xbf, 0x0d, 0x82, 0xc1, - 0x3c, 0xc6, 0x77, 0xaa, 0xcc, 0x84, 0xeb, 0xb7, 0xe3, 0x4b, 0xf7, 0x93, 0x88, 0x32, 0x99, 0xf8, - 0x91, 0x72, 0x90, 0x4e, 0xf2, 0x39, 0x26, 0x24, 0x69, 0xd4, 0x3b, 0x66, 0x16, 0x03, 0x00, 0x90, - 0x22, 0x40, 0xfa, 0x1a, 0x04, 0x41, 0xa5, 0xc1, 0xf6, 0xa7, 0x21, 0xd0, 0x0c, 0x43, 0x97, 0x96, - 0x55, 0x0d, 0x1c, 0x01, 0xb6, 0x85, 0x74, 0x0a, 0x78, 0xf3, 0x9b, 0x7c, 0x18, 0x8f, 0x6a, 0x0f, - 0x08, 0x89, 0xbe, 0x3b, 0x7e, 0xe1, 0x0e, 0x27, 0xa2, 0xea, 0xad, 0x9c, 0xcf, 0xd9, 0x4b, 0x40, - 0x73, 0x35, 0x6b, 0xcb, 0x5e, 0x0e, 0xff, 0x17, 0x3c, 0x44, 0x6d, 0xdc, 0x26, 0xbf, 0x28, 0x96, - 0xb2, 0x8d, 0x8d, 0x9e, 0x7d, 0xca, 0x82, 0x51, 0xf0, 0x79, 0xf0, 0xf9, 0x3e, 0x07, 0xff, 0x6c, - 0x30, 0xe9, 0xaf, 0xab, 0x1f, 0x91, 0x02, 0xd7, 0x94, 0xbe, 0x82, 0x8a, 0x58, 0xb6, 0x2c, 0x06, - 0x09, 0x88, 0xfb, 0x99, 0xe3, 0xfd, 0x96, 0xa5, 0x91, 0x72, 0x90, 0x4e, 0xf2, 0x19, 0x56, 0x3c, - 0xaa, 0x55, 0xb7, 0x24, 0x66, 0x3c, 0xcb, 0xe6, 0x01, 0x0d, 0x56, 0xf4, 0x3f, 0x74, 0xbf, 0xfb, - 0x3b, 0x05, 0xdf, 0xcd, 0x00, 0x00, 0x00, 0x00, 0xdd, 0xd3, 0x47, 0x59, 0x30, 0x43, 0xb7, 0x3c, - 0xb8, 0x17, 0xd4, 0x51, 0xe1, 0xa4, 0xb0, 0x52, 0xa9, 0x13, 0xd9, 0xf3, 0x04, 0x48, 0xe2, 0x65, - 0xa7, 0xbb, 0xa8, 0x3c, 0xe1, 0xe7, 0x72, 0x3e, 0x8f, 0x0d, 0xc2, 0x88, 0x6b, 0x25, 0x07, 0x6a, - 0x3c, 0x9b, 0xb7, 0x4e, 0xd7, 0x40, 0x21, 0x03, 0xa6, 0xbb, 0x01, 0x14, 0x4d, 0x59, 0xaf, 0x07, - 0xf0, 0x78, 0x3e, 0x0f, 0xb0, 0x3f, 0x07, 0x2e, 0xca, 0xe0, 0x35, 0xb8, 0x63, 0x37, 0x46, 0xce, - 0x97, 0xb8, 0xcb, 0x3a, 0xce, 0x3e, 0x5b, 0xf9, 0xb6, 0xb2, 0x83, 0x30, 0x70, 0x45, 0x4d, 0xb8, - 0x91, 0x72, 0x90, 0x4e, 0xf2, 0x19, 0x66, 0x3c, 0x69, 0xd4, 0xd7, 0x0f, 0x56, 0xb8, 0x0a, 0x16, - 0xd2, 0xa2, 0x0a, 0xd6, 0x86, 0x63, 0x1d, 0xf5, 0x79, 0x28, 0x93, 0x0f, 0x2e, 0x60, 0x7a, 0x0b, - 0x85, 0x00, 0x03, 0x59, 0x79, 0x93, 0xfb, 0xa4, 0x95, 0xbe, 0xd3, 0x99, 0x09, 0x31, 0x6d, 0xb1, - 0x92, 0xa6, 0x2e, 0x08, 0x89, 0x6a, 0xd8, 0x42, 0x39, 0x62, 0x22, 0x42, 0x9e, 0xb7, 0x0b, 0xbf, - 0xdf, 0xf9, 0xa7, 0x55, 0x5a, 0x0e, 0x93, 0xbe, 0x39, 0x71, 0xb0, 0x97, 0x5d, 0x4f, 0x8e, 0x97, - 0x98, 0xae, 0xd8, 0x3e, 0x94, 0xea, 0x7e, 0x0f, 0x87, 0xe0, 0xe1, 0x8f, 0xe0, 0xff, 0x8e, 0x7d, - 0xc7, 0x5d, 0x99, 0xec, 0x13, 0xf8, 0x27, 0x05, 0x8a, 0x01, 0xb1, 0xd8, 0x84, 0xa4, 0xbd, 0x59, - 0xc6, 0xf6, 0xfe, 0xf7, 0x0e, 0x4d, 0xb4, 0xa8, 0x71, 0x72, 0x90, 0x4e, 0xf2, 0x19, 0x56, 0x3c, - 0xaa, 0x6f, 0xa2, 0xf5, 0xd8, 0xb5, 0x5e, 0xbd, 0x40, 0x81, 0xb1, 0x5e, 0x70, 0x21, 0xab, 0x00, - 0x00, 0x00, 0x00, 0xcd, 0xb9, 0xa5, 0x00, 0xed, 0xc7, 0xf5, 0xf3, 0x79, 0xa1, 0x72, 0xa6, 0xf4, - 0x97, 0x3a, 0x66, 0xf0, 0x06, 0x52, 0xce, 0x4d, 0x40, 0xb0, 0xd7, 0x56, 0x11, 0x36, 0xeb, 0x5f, - 0x76, 0x0e, 0x27, 0x89, 0x4f, 0x90, 0x4e, 0x5f, 0xa4, 0xbb, 0x65, 0x18, 0x7f, 0xbe, 0x5d, 0x33, - 0x3b, 0xf0, 0xee, 0xf3, 0x0c, 0xab, 0x98, 0x21, 0x4f, 0x7f, 0xa8, 0xbd, 0x67, 0xfe, 0x03, 0xf8, - 0x1f, 0xe0, 0x3e, 0x1c, 0x78, 0xc0, 0xfd, 0x3f, 0x79, 0x8b, 0x5c, 0xd1, 0xc2, 0x51, 0x43, 0x45, - 0x1b, 0x0e, 0xeb, 0x9c, 0xc7, 0x1d, 0x54, 0x4d, 0x75, 0x75, 0x30, 0xe8, 0xfc, 0x3c, 0x52, 0xb3, - 0x96, 0xeb, 0x66, 0xaf, 0x72, 0x19, 0x96, 0x3c, 0xaa, 0x6f, 0x27, 0x9f, 0x71, 0x1f, 0xaf, 0xb1, - 0xb2, 0xaa, 0x21, 0x2b, 0x65, 0x0b, 0xb4, 0x98, 0x0f, 0xad, 0x8e, 0x7b, 0xa1, 0xa9, 0x01, 0xf6, - 0x5c, 0x20, 0xcb, 0x10, 0x89, 0x09, 0xdc, 0x57, 0xb2, 0x77, 0x20, 0xc5, 0xa8, 0xd1, 0x2d, 0xa8, - 0xee, 0x9f, 0x47, 0xeb, 0x5e, 0x25, 0x31, 0x90, 0x6b, 0x53, 0x5e, 0x40, 0xda, 0xce, 0x70, 0xc5, - 0x6c, 0xb2, 0xee, 0x9e, 0xfa, 0x48, 0x07, 0x91, 0xdf, 0x85, 0x52, 0x46, 0xc9, 0xd0, 0x4f, 0xb7, - 0xb4, 0xe8, 0x1a, 0x4e, 0xab, 0x03, 0x9e, 0x3e, 0x00, 0x1c, 0x08, 0x5d, 0x0d, 0xa9, 0x97, 0xe4, - 0x32, 0x30, 0x6f, 0x4a, 0xab, 0x3d, 0x4a, 0x09, 0x0a, 0x98, 0xc3, 0x60, 0x4f, 0xb8, 0x7d, 0x0e, - 0x88, 0xb4, 0x68, 0x82, 0xa0, 0x03, 0x5d, 0x9c, 0x96, 0xeb, 0x66, 0xaf, 0x72, 0x39, 0x56, 0x2c, - 0x65, 0xd9, 0x97, 0x01, 0xee, 0x4a, 0x66, 0x11, 0x45, 0x5b, 0xde, 0x86, 0xac, 0xba, 0x65, 0xf1, - 0x3f, 0x56, 0x54, 0x05, 0x5a, 0x39, 0x00, 0x3e, 0x79, 0x2f, 0xbb, 0xcd, 0x63, 0x69, 0xa5, 0x45, - 0x64, 0xab, 0xfe, 0xc9, 0x8f, 0xf9, 0x25, 0xb1, 0x69, 0x21, 0x4b, 0x7f, 0xbb, 0x5c, 0x6b, 0x30, - 0x21, 0xdb, 0x98, 0x32, 0x9e, 0x9f, 0xe5, 0xf3, 0x11, 0x60, 0xeb, 0xc6, 0xcb, 0x74, 0x72, 0xd0, - 0x1c, 0x94, 0xd4, 0xe6, 0xf0, 0x05, 0x5b, 0x02, 0xa4, 0x9f, 0xea, 0x44, 0xb8, 0x0d, 0xf4, 0x73, - 0x08, 0x3c, 0xce, 0x29, 0xf0, 0xb5, 0xe0, 0x48, 0x13, 0xab, 0x4a, 0x47, 0x89, 0xb1, 0x33, 0x8a, - 0xc7, 0xae, 0x39, 0xee, 0xbb, 0x65, 0xb9, 0xe2, 0xa0, 0x72, 0x6e, 0x3e, 0xa0, 0x33, 0x56, 0xa6, - 0x96, 0xeb, 0x66, 0xaf, 0x72, 0x39, 0x76, 0x34, 0x65, 0x57, 0x24, 0xfc, 0x7e, 0x20, 0x8e, 0xb5, - 0x9b, 0x37, 0x73, 0x06, 0x19, 0x9a, 0x84, 0x40, 0x00, 0xeb, 0x19, 0x30, 0xd1, 0x54, 0xd5, 0x11, - 0x6d, 0xaa, 0xac, 0xd6, 0xb9, 0x08, 0xd7, 0x79, 0x4f, 0x4d, 0xe8, 0x27, 0x5b, 0xe1, 0xe6, 0x41, - 0x7b, 0xd4, 0x30, 0x66, 0xc3, 0x67, 0x28, 0x70, 0xaf, 0x1b, 0xcc, 0x6b, 0x7b, 0x12, 0x2a, 0xe6, - 0xfa, 0x7e, 0x23, 0xb9, 0x24, 0x56, 0x92, 0x3b, 0x42, 0xc3, 0xb4, 0x2a, 0x22, 0x3d, 0xae, 0xfb, - 0x8d, 0x73, 0xb5, 0x20, 0x18, 0x5f, 0x63, 0x02, 0x75, 0x91, 0x7d, 0x16, 0xa5, 0xfd, 0x20, 0xe9, - 0x27, 0x80, 0x13, 0xdc, 0xaa, 0xc1, 0x4d, 0xcc, 0x99, 0x00, 0xf8, 0x48, 0x30, 0x2c, 0xb0, 0xa4, - 0x3c, 0x0b, 0x08, 0xbf, 0x63, 0x3d, 0x61, 0xa8, 0xb6, 0xeb, 0x66, 0xaf, 0x72, 0x39, 0x66, 0x34, - 0x63, 0xb3, 0xbd, 0x96, 0xb3, 0x4d, 0xd2, 0xf2, 0xee, 0xa4, 0x40, 0x95, 0x46, 0x7d, 0x46, 0x9e, - 0xa5, 0x6f, 0x5c, 0xe2, 0xfc, 0x70, 0xcf, 0xe0, 0x25, 0xe2, 0x44, 0x10, 0x05, 0x8a, 0xe9, 0xe9, - 0x43, 0xcc, 0x0d, 0x4c, 0x47, 0x14, 0x97, 0xac, 0xf5, 0x79, 0x36, 0x9d, 0xb7, 0xfd, 0xbe, 0xda, - 0x64, 0xa2, 0x70, 0x09, 0x52, 0x83, 0xf9, 0x91, 0xfa, 0x8b, 0x47, 0xd1, 0x2d, 0xee, 0xf4, 0xd9, - 0x41, 0xd9, 0xb2, 0x99, 0xf0, 0x0a, 0x93, 0x8c, 0x30, 0x27, 0xb0, 0x05, 0xfc, 0x58, 0x30, 0x5a, - 0x3f, 0x46, 0x13, 0x90, 0x9a, 0x29, 0x53, 0x60, 0xae, 0x82, 0xad, 0xc1, 0x2b, 0x27, 0x6a, 0x4f, - 0x3e, 0xeb, 0x9b, 0x6e, 0x34, 0x6a, 0x48, 0xf1, 0xb7, 0x33, 0x5a, 0x00, 0x3a, 0x11, 0x4e, 0xea, - 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x66, 0x3c, 0xb6, 0x91, 0xd0, 0xbc, 0x85, 0xad, 0x1c, 0xc1, - 0xc5, 0x74, 0xa3, 0x65, 0x58, 0x79, 0x04, 0x76, 0x1a, 0xba, 0x32, 0xcd, 0xc3, 0xbc, 0x10, 0x62, - 0x17, 0x92, 0x1a, 0x73, 0xac, 0x21, 0xa4, 0xc1, 0x08, 0xc1, 0xfd, 0x0e, 0x4a, 0x33, 0xf2, 0xe8, - 0xfd, 0xab, 0x37, 0x23, 0x66, 0x9d, 0x84, 0xad, 0xa6, 0xc3, 0xf7, 0x8c, 0x0e, 0x73, 0x01, 0x0e, - 0x23, 0xb8, 0x6d, 0x19, 0x5c, 0xed, 0xaf, 0x76, 0xf7, 0x83, 0x0d, 0x7e, 0x89, 0x98, 0x1c, 0x5b, - 0x99, 0x95, 0xb7, 0xe0, 0x48, 0xcf, 0xa0, 0xc6, 0x10, 0x44, 0x89, 0x24, 0xb5, 0x79, 0xc4, 0xfc, - 0xa1, 0xc2, 0x3b, 0x41, 0x53, 0x89, 0xad, 0xce, 0x3e, 0x39, 0xb2, 0x92, 0xea, 0x36, 0xda, 0x4a, - 0xc9, 0x52, 0xc0, 0x19, 0xd9, 0x2a, 0x7d, 0x1e, 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x45, 0xe4, - 0x6e, 0xba, 0xba, 0xbc, 0xf5, 0x92, 0xd9, 0x00, 0x2d, 0x18, 0x51, 0x21, 0x42, 0x93, 0x43, 0xce, - 0x38, 0xfb, 0x80, 0x6f, 0x6f, 0x0d, 0x0b, 0x9f, 0xdc, 0x9e, 0x09, 0xb4, 0x68, 0x96, 0xbb, 0x25, - 0x36, 0xe6, 0x05, 0x3b, 0x83, 0xc4, 0x7c, 0x97, 0x04, 0xf0, 0xf0, 0x31, 0x12, 0x53, 0x28, 0xf5, - 0x3a, 0xb3, 0x4b, 0x50, 0xbc, 0xf6, 0x58, 0x53, 0xe1, 0x94, 0xe2, 0xe0, 0xec, 0x61, 0x35, 0x73, - 0x6c, 0xc2, 0xb6, 0x4b, 0xa6, 0x12, 0x7d, 0x28, 0xbc, 0x29, 0x02, 0x74, 0x71, 0x41, 0xeb, 0xe1, - 0xa5, 0x68, 0xbe, 0xac, 0xde, 0xcf, 0x1a, 0x25, 0x79, 0x66, 0x4f, 0x68, 0xdb, 0xb0, 0x67, 0x7f, - 0xc2, 0xfa, 0x52, 0x88, 0xf8, 0x11, 0x75, 0x0c, 0x37, 0x9b, 0x3c, 0x4d, 0xe2, 0x48, 0x17, 0xa6, - 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x56, 0x3c, 0xaf, 0xe4, 0xa2, 0x89, 0x12, 0x82, 0x0c, 0x29, - 0xbf, 0x24, 0x3d, 0xce, 0x5e, 0x00, 0x0c, 0xb4, 0xea, 0xf0, 0x83, 0x87, 0x99, 0xd9, 0xda, 0xbb, - 0xe1, 0x31, 0xa9, 0x85, 0xd1, 0xdc, 0x6e, 0xff, 0xba, 0xb1, 0xfd, 0x54, 0x95, 0x64, 0xbb, 0x8f, - 0x9e, 0x6f, 0x2a, 0x8a, 0x85, 0xd5, 0xef, 0x6f, 0x2a, 0xdb, 0xb9, 0x1e, 0x90, 0xd0, 0x3d, 0xb3, - 0xb4, 0xd5, 0x21, 0xf7, 0xcc, 0xa0, 0x56, 0x37, 0xd2, 0x04, 0xac, 0xa6, 0xba, 0x35, 0x9b, 0xf8, - 0x54, 0x4f, 0x56, 0x8e, 0x03, 0xba, 0xb7, 0xbe, 0x42, 0xc4, 0x8b, 0xf1, 0x3b, 0x97, 0x91, 0x6e, - 0xa9, 0x3b, 0x56, 0x63, 0x21, 0xe4, 0x32, 0x00, 0x40, 0x49, 0x96, 0x2d, 0x2f, 0x42, 0x1f, 0xce, - 0x9e, 0x2b, 0x45, 0x5f, 0xba, 0x22, 0x4f, 0x66, 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x66, 0x2c, - 0x65, 0xca, 0x4a, 0x9e, 0x20, 0x90, 0xd5, 0xeb, 0xdf, 0xb8, 0x17, 0x31, 0xd9, 0x80, 0x30, 0x3b, - 0x26, 0xd8, 0xa2, 0xbd, 0x5b, 0x02, 0x22, 0x53, 0x50, 0x98, 0xa5, 0x6a, 0x9b, 0x17, 0xd8, 0x89, - 0x3e, 0xf7, 0x00, 0x3d, 0x93, 0xeb, 0x5c, 0x37, 0x12, 0x20, 0x94, 0x6d, 0x2c, 0x0d, 0xcc, 0x20, - 0x04, 0x55, 0xa2, 0x73, 0xbb, 0xc0, 0xaa, 0x95, 0xa2, 0x02, 0x52, 0x9c, 0xf6, 0xb2, 0xd0, 0xc9, - 0xd4, 0x8d, 0xcf, 0xfe, 0xee, 0xa6, 0xc9, 0xf4, 0xd2, 0xd3, 0xca, 0xf8, 0x88, 0x0d, 0xf3, 0xcd, - 0x90, 0xff, 0x03, 0x3e, 0xb9, 0x22, 0x9f, 0x5b, 0x67, 0x40, 0xc7, 0x86, 0x67, 0xba, 0xf2, 0x10, - 0x6a, 0x38, 0xbc, 0x8f, 0x6a, 0x35, 0x69, 0xbf, 0xda, 0xeb, 0xbf, 0x41, 0x56, 0x71, 0x55, 0x4f, - 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x56, 0x34, 0xb6, 0x90, 0xce, 0x2f, 0x9f, 0xa6, 0x39, 0xdb, - 0x76, 0xc2, 0x48, 0x94, 0x8c, 0xd3, 0xc2, 0xc0, 0xde, 0xa3, 0x37, 0xc0, 0x1c, 0x11, 0x2c, 0x9b, - 0x06, 0x3a, 0xbf, 0x47, 0x64, 0x38, 0x2c, 0x56, 0x2b, 0x5d, 0x1d, 0xf6, 0x6e, 0xd3, 0x62, 0x89, - 0x10, 0x2b, 0x5d, 0x15, 0x48, 0x2f, 0x03, 0xa8, 0x07, 0xf3, 0x78, 0xcd, 0xb9, 0xb8, 0xce, 0xe7, - 0x69, 0x39, 0x3c, 0x13, 0x14, 0xd6, 0xb8, 0x8c, 0xe0, 0xcd, 0x8a, 0x23, 0x15, 0x89, 0x83, 0x31, - 0x3a, 0x0c, 0x95, 0xc0, 0xe9, 0xbf, 0x9f, 0xbd, 0x05, 0x61, 0x67, 0xe3, 0x3f, 0x10, 0x9a, 0x29, - 0x72, 0x3c, 0x5a, 0x38, 0xe0, 0xf4, 0x9a, 0x59, 0x9f, 0xd5, 0x44, 0x62, 0xcd, 0xed, 0x00, 0x78, - 0xc2, 0x1c, 0x7c, 0x47, 0xf4, 0xb3, 0x55, 0x13, 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x56, 0x0c, - 0xaf, 0xe5, 0x67, 0xb2, 0x9d, 0xfd, 0x91, 0xaf, 0x74, 0xcd, 0xd3, 0x13, 0x5c, 0xa8, 0x96, 0x7b, - 0x63, 0x82, 0xa3, 0x3f, 0x19, 0xa9, 0xd5, 0xc7, 0x7c, 0x3c, 0x64, 0x11, 0x80, 0x9b, 0xbc, 0x11, - 0x43, 0xf3, 0x6a, 0x02, 0xb4, 0x70, 0x52, 0x0f, 0xeb, 0xf0, 0x41, 0x9f, 0x15, 0x9e, 0xf5, 0xd7, - 0x72, 0x98, 0x4b, 0x06, 0x1a, 0x74, 0x8f, 0x29, 0x1f, 0x0d, 0x38, 0xf7, 0xea, 0xd8, 0xa4, 0x3e, - 0x37, 0xba, 0x03, 0xa9, 0xef, 0x6d, 0x0b, 0x1b, 0x48, 0x97, 0xd7, 0x76, 0x06, 0x66, 0xf0, 0x7d, - 0x2b, 0xe4, 0x56, 0x38, 0x87, 0x5d, 0xb6, 0x00, 0x64, 0x55, 0xe5, 0x31, 0x11, 0xa1, 0xac, 0x9c, - 0x88, 0x28, 0x04, 0xae, 0x9d, 0x14, 0xc5, 0x61, 0x9d, 0x11, 0x54, 0x3e, 0xb3, 0x46, 0x61, 0x0d, - 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x76, 0x34, 0x66, 0x57, 0xfe, 0x3a, 0x35, 0x14, 0xf0, 0x24, - 0x07, 0x8c, 0x8c, 0x9b, 0xdb, 0x06, 0xd7, 0x4c, 0x45, 0xf2, 0x1e, 0x75, 0x12, 0x9a, 0x0e, 0x66, - 0xbe, 0xb8, 0x15, 0x6c, 0x4c, 0xfc, 0x8a, 0x98, 0xac, 0xc0, 0xb0, 0x9c, 0x9a, 0x68, 0xd2, 0xab, - 0x41, 0x7d, 0xb4, 0x82, 0x2c, 0x8f, 0x0f, 0x93, 0xf4, 0xfa, 0x4d, 0x87, 0x76, 0xea, 0x45, 0xe6, - 0x66, 0x05, 0xe3, 0x09, 0x0e, 0x56, 0xf8, 0x16, 0xd6, 0x7e, 0x8f, 0xde, 0x9a, 0x61, 0x67, 0xbd, - 0xe3, 0x77, 0xb9, 0x73, 0x7b, 0xf2, 0x3f, 0x38, 0x88, 0x29, 0x36, 0x88, 0x84, 0x0c, 0x10, 0xd8, - 0x80, 0x6d, 0xbc, 0x26, 0xc8, 0x2c, 0xdd, 0x68, 0xfe, 0x2b, 0x23, 0x73, 0xd2, 0x38, 0x54, 0x63, - 0xc6, 0x57, 0xc7, 0xfe, 0x7e, 0xf7, 0xac, 0xab, 0xb1, 0x2d, 0x5a, 0x8e, 0xf2, 0x39, 0x35, 0x84, - 0xaf, 0xa7, 0x15, 0x3e, 0x78, 0xcd, 0x36, 0xc0, 0x19, 0x4c, 0x1d, 0x8d, 0x0b, 0xc6, 0x83, 0x8e, - 0xcc, 0xc7, 0xb7, 0x14, 0x15, 0x87, 0x95, 0x8b, 0xfb, 0xac, 0x9b, 0xdd, 0x72, 0xdf, 0xef, 0xfe, - 0x15, 0xc7, 0xce, 0xcc, 0xb4, 0x51, 0x23, 0xea, 0x70, 0x2e, 0x1b, 0x60, 0x3e, 0x70, 0x01, 0xb6, - 0xa4, 0xe9, 0xb7, 0x1c, 0x32, 0x64, 0xe3, 0xea, 0x57, 0x1c, 0x65, 0x7f, 0xfd, 0x05, 0x8c, 0xae, - 0x96, 0x79, 0x53, 0x17, 0x42, 0xbf, 0xfd, 0x35, 0x27, 0x6e, 0x3b, 0xd0, 0xb3, 0x3f, 0x90, 0x03, - 0xc4, 0x4a, 0xf3, 0x5a, 0x0f, 0x39, 0xb2, 0x65, 0x8e, 0x4f, 0x0a, 0xb8, 0xfb, 0x03, 0x3e, 0x4f, - 0x8d, 0xf1, 0xa6, 0x2d, 0x8d, 0x85, 0x25, 0x72, 0xe2, 0xcb, 0xec, 0xf7, 0xe1, 0x98, 0xef, 0xe6, - 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x76, 0x2c, 0xaf, 0xde, 0xd3, 0xde, 0x29, 0xec, 0xcb, 0xa8, - 0xa4, 0xa7, 0xdb, 0x9f, 0x13, 0xaa, 0x7c, 0xff, 0x2e, 0x7d, 0x26, 0x00, 0xb7, 0xa0, 0x49, 0x04, - 0x6b, 0x78, 0x0b, 0xfe, 0x7c, 0x8c, 0x2c, 0x86, 0x78, 0x04, 0x92, 0xa5, 0x06, 0x05, 0x40, 0xe5, - 0x5f, 0xe8, 0x5e, 0x1b, 0x4b, 0x53, 0x6e, 0xe4, 0x52, 0xeb, 0x96, 0x18, 0x33, 0xa7, 0x3a, 0xf5, - 0x59, 0xa8, 0xb3, 0x81, 0x20, 0xd7, 0x88, 0x92, 0x6a, 0xdb, 0x6e, 0x81, 0xe5, 0x47, 0xda, 0x84, - 0x83, 0x9a, 0x9e, 0x5e, 0x78, 0x8c, 0x12, 0xf0, 0xc0, 0x35, 0x03, 0x58, 0x3f, 0xec, 0x8f, 0xb7, - 0xe8, 0x74, 0xa6, 0xfb, 0xd1, 0xa2, 0xe2, 0x20, 0x18, 0x86, 0x03, 0x22, 0x43, 0x46, 0x23, 0x76, - 0x22, 0x2f, 0x38, 0x83, 0xdb, 0x90, 0xd3, 0x13, 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x56, 0x3c, - 0x69, 0x22, 0xe4, 0xca, 0x53, 0x96, 0xc7, 0x1b, 0xed, 0xf3, 0x0a, 0xc8, 0xfc, 0x00, 0x5d, 0xa2, - 0x8c, 0x2b, 0x14, 0x70, 0x6d, 0x84, 0x76, 0x1e, 0x00, 0xcc, 0x13, 0xdb, 0xf3, 0x48, 0xbd, 0x79, - 0x77, 0x56, 0x2e, 0x91, 0x75, 0x37, 0x14, 0x9f, 0x29, 0x9a, 0x4f, 0xb9, 0x0e, 0x77, 0x77, 0x5a, - 0x7a, 0x3d, 0xe3, 0x76, 0x36, 0x61, 0xd5, 0xa9, 0xda, 0x5e, 0x27, 0xa5, 0xb8, 0xc9, 0x27, 0xc8, - 0x4f, 0x50, 0x77, 0x0f, 0x14, 0x1e, 0x80, 0x1b, 0xbf, 0xb1, 0xc5, 0x39, 0xaf, 0xe6, 0x82, 0x60, - 0xb0, 0x5e, 0x32, 0xc1, 0xdf, 0xa8, 0x33, 0x70, 0xaf, 0x78, 0x08, 0x1f, 0xce, 0x63, 0x45, 0xbb, - 0xf0, 0xf9, 0x90, 0x3e, 0x11, 0xf3, 0x7e, 0x5d, 0x44, 0x61, 0xe3, 0xa8, 0xbc, 0xaa, 0x71, 0x33, - 0xb1, 0x2d, 0x5a, 0x8e, 0xf2, 0x39, 0x16, 0x2c, 0x65, 0xc7, 0x3e, 0xca, 0xc3, 0x81, 0xb0, 0xa1, - 0x95, 0xf1, 0x83, 0xb4, 0x2a, 0x9f, 0xd9, 0xed, 0xb6, 0x66, 0x25, 0xcd, 0x41, 0x1d, 0x06, 0x01, - 0x57, 0x3c, 0xb7, 0x75, 0xee, 0x9a, 0x64, 0xd7, 0x83, 0x2c, 0x34, 0x42, 0xae, 0x59, 0x21, 0x9c, - 0xaa, 0xc8, 0xfa, 0xfc, 0x6e, 0xb5, 0x4d, 0x14, 0x8d, 0xe4, 0x5a, 0x85, 0xe9, 0xb7, 0xa1, 0x76, - 0x4b, 0x57, 0x1b, 0x8b, 0xa5, 0x91, 0x48, 0xdd, 0x76, 0x47, 0x3d, 0xdf, 0xe3, 0xbd, 0x5f, 0x54, - 0x14, 0x25, 0x9f, 0x11, 0x81, 0xcc, 0x62, 0x83, 0x8f, 0x20, 0x5c, 0xa7, 0x39, 0x37, 0xcd, 0x5f, - 0xb2, 0x30, 0x10, 0x9e, 0x2c, 0xec, 0xb6, 0x65, 0x45, 0xd2, 0x0c, 0x5b, 0xa2, 0x4f, 0x8b, 0xb6, - 0xa1, 0x0b, 0xc2, 0xbb, 0x8c, 0xa5, 0x15, 0x87, 0xb1, 0x2d, 0x5a, 0x8e, 0xf2, 0x39, 0x25, 0xe4, - 0x65, 0xc6, 0xd3, 0xa6, 0x52, 0x43, 0x2a, 0xef, 0x33, 0x6c, 0x87, 0xeb, 0x3a, 0xcf, 0x5d, 0xf0, - 0xc0, 0x08, 0x10, 0x7e, 0x05, 0xb0, 0x45, 0x65, 0x24, 0xd9, 0xe8, 0xb5, 0xf1, 0x9a, 0xbf, 0xc8, - 0xbf, 0x69, 0x46, 0x6a, 0x23, 0xb9, 0x2e, 0x01, 0xea, 0x4d, 0xdf, 0x67, 0xfa, 0x07, 0x84, 0x2e, - 0x59, 0xa2, 0x09, 0x20, 0xdd, 0xf6, 0x02, 0x98, 0xbd, 0xc7, 0x57, 0x85, 0x72, 0x36, 0x1a, 0x2a, - 0x4f, 0x84, 0x15, 0xa8, 0x47, 0x57, 0x9f, 0x57, 0x23, 0xd6, 0xc0, 0x7c, 0x3e, 0xf6, 0x02, 0x3a, - 0xc4, 0x97, 0x5c, 0xc0, 0x52, 0x4c, 0x05, 0x1f, 0x1a, 0xfb, 0x4c, 0x4f, 0x31, 0x4c, 0xc8, 0x02, - 0xfd, 0x73, 0xed, 0x7b, 0x24, 0xe0, 0xc1, 0x61, 0xb8, 0x52, 0x8d, 0x2c, 0x8a, 0xb3, 0x7e, 0xf8, - 0xb1, 0x2d, 0x5a, 0x8e, 0xf2, 0x39, 0x25, 0x84, 0xaf, 0xdd, 0x74, 0x71, 0x44, 0x68, 0xff, 0x2b, - 0x57, 0x71, 0x24, 0x5c, 0x55, 0xa5, 0x54, 0x83, 0x19, 0xf7, 0x1a, 0xc2, 0xe7, 0xdc, 0x46, 0xf0, - 0x09, 0x8b, 0xf5, 0xf3, 0x91, 0x04, 0x22, 0xa1, 0x27, 0x34, 0x0f, 0x64, 0xeb, 0x1f, 0xe5, 0x9b, - 0xcb, 0x22, 0x0f, 0xc3, 0x54, 0x10, 0x78, 0x8c, 0x61, 0xf9, 0xf4, 0x6f, 0xc9, 0xbb, 0x88, 0x86, - 0x73, 0x8a, 0x4c, 0xff, 0x4e, 0x44, 0xc9, 0x5d, 0x96, 0x9f, 0x80, 0x19, 0xe6, 0x78, 0x1f, 0x6b, - 0x00, 0x0c, 0x9f, 0x04, 0x24, 0x74, 0xf0, 0x3c, 0x53, 0x08, 0x2b, 0x3b, 0x50, 0xa9, 0xe8, 0x65, - 0x87, 0x69, 0xf7, 0xd4, 0x59, 0x0e, 0x0b, 0x9d, 0x1e, 0x11, 0x0a, 0xe6, 0x57, 0x11, 0x78, 0x08, - 0xd0, 0x64, 0x47, 0x05, 0xae, 0x94, 0x89, 0xbc, 0xb1, 0x31, 0xa7, 0x0e, 0xf2, 0x39, 0x15, 0xfc, - 0xb6, 0x85, 0x63, 0x1f, 0x20, 0xc0, 0x06, 0x36, 0xe0, 0xa7, 0x4a, 0xc5, 0xad, 0x13, 0x1f, 0xa7, - 0x8a, 0xd5, 0x1a, 0xab, 0xdc, 0xc1, 0x6b, 0xa9, 0x50, 0xfb, 0x62, 0xc5, 0x48, 0xf1, 0x9b, 0x9b, - 0x2c, 0xe8, 0x56, 0xcf, 0x2a, 0x04, 0xa4, 0x0b, 0xd5, 0x36, 0xda, 0x6a, 0xa8, 0xa7, 0xa9, 0x58, - 0xef, 0xa2, 0x35, 0x74, 0x48, 0xc9, 0xa2, 0xb5, 0x48, 0xeb, 0x2f, 0x99, 0x26, 0x75, 0xf9, 0xeb, - 0x35, 0xc1, 0x92, 0xec, 0xda, 0x01, 0xee, 0x4e, 0xef, 0x15, 0xe6, 0x87, 0x03, 0xf7, 0x73, 0xc5, - 0x6f, 0x02, 0xf5, 0xbe, 0x1f, 0x49, 0x0f, 0x88, 0x0b, 0xe3, 0x24, 0x06, 0xed, 0xe1, 0xa1, 0xe3, - 0x33, 0x5b, 0xbb, 0xae, 0x10, 0x01, 0xd0, 0xd8, 0x63, 0xe2, 0x15, 0x44, 0xdf, 0xd3, 0x7b, 0x5b, - 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x76, 0x0c, 0x69, 0x22, 0x72, 0xe4, 0x98, 0xd5, 0x8a, 0x89, - 0x1c, 0x65, 0xc4, 0x6e, 0x00, 0x17, 0x29, 0x54, 0x3d, 0xd5, 0x58, 0x43, 0xc0, 0x33, 0x85, 0x15, - 0x9d, 0xf1, 0x19, 0x3f, 0x72, 0x51, 0xcf, 0x81, 0xb7, 0x6b, 0xd7, 0x35, 0x69, 0x08, 0xe1, 0x13, - 0x3b, 0x78, 0x0a, 0xe1, 0x1b, 0xa7, 0xe8, 0x72, 0x10, 0x55, 0xb9, 0x20, 0x11, 0x50, 0xa4, 0x17, - 0x87, 0x12, 0xfa, 0xf9, 0xf4, 0x1d, 0x4f, 0x08, 0x95, 0x82, 0x72, 0x9e, 0xc9, 0x0f, 0xe9, 0x01, - 0x21, 0x7f, 0xde, 0xf8, 0x10, 0x38, 0x56, 0x3b, 0x20, 0xa7, 0x02, 0x3f, 0x16, 0x3c, 0x36, 0x81, - 0x69, 0xa6, 0x1a, 0xcc, 0x51, 0xac, 0x6d, 0x79, 0x9a, 0xda, 0x1c, 0xca, 0xa7, 0x96, 0x95, 0x6b, - 0x00, 0xb0, 0x61, 0x1c, 0xce, 0xc3, 0x6f, 0xb7, 0x95, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x55, 0x84, - 0xaa, 0x56, 0xbf, 0xa9, 0xda, 0x3c, 0x9d, 0xc3, 0xf5, 0xac, 0x60, 0x1e, 0x1a, 0xd8, 0x19, 0xdf, - 0x0a, 0x71, 0x4a, 0xfc, 0xe5, 0xc4, 0x08, 0x23, 0xec, 0x2f, 0x4c, 0x6c, 0xa6, 0x7c, 0x21, 0x4a, - 0xdd, 0xb3, 0xca, 0x0f, 0xbb, 0x13, 0x27, 0x92, 0x69, 0xde, 0x0e, 0xe7, 0x16, 0xd4, 0x62, 0x1a, - 0x7c, 0xd8, 0xef, 0xcd, 0xcd, 0xdd, 0x83, 0xbd, 0x7f, 0xaa, 0x22, 0xc3, 0x04, 0xe2, 0x4d, 0x2b, - 0xe4, 0x6f, 0xd2, 0x4e, 0xb8, 0x46, 0x41, 0x47, 0xbe, 0x19, 0x09, 0xfc, 0x60, 0x43, 0x60, 0x39, - 0x1d, 0xda, 0x13, 0x3e, 0x0d, 0x1d, 0xc8, 0x68, 0xbc, 0x05, 0x49, 0xa7, 0xc1, 0x3b, 0x2a, 0x03, - 0x60, 0x25, 0xba, 0xac, 0xd5, 0x4b, 0x2c, 0x64, 0x83, 0x96, 0x80, 0x4d, 0xa0, 0x66, 0xab, 0x1e, - 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x55, 0xf4, 0xaa, 0x56, 0x81, 0x76, 0xd9, 0xc8, 0x2c, 0x73, - 0x36, 0x0f, 0xea, 0x62, 0xe2, 0x2c, 0x3b, 0x4b, 0x43, 0xdc, 0x2e, 0x7a, 0x64, 0xf5, 0xc9, 0xb4, - 0xd3, 0x00, 0x02, 0x38, 0xc4, 0x99, 0x45, 0x1a, 0x98, 0x04, 0x95, 0xd5, 0xbe, 0x36, 0xa9, 0xd1, - 0x88, 0xf0, 0xc3, 0x1f, 0xe5, 0x6a, 0x61, 0xac, 0x5d, 0x5e, 0x7d, 0xf0, 0xc3, 0x0a, 0x06, 0x20, - 0xde, 0xe4, 0xe3, 0x4a, 0x50, 0xae, 0xea, 0xbd, 0x97, 0xb0, 0xe4, 0xe6, 0x13, 0x25, 0x13, 0x3c, - 0x9d, 0xd1, 0x00, 0xfb, 0x94, 0xff, 0xb8, 0x13, 0x63, 0x79, 0x7c, 0x38, 0xbf, 0x96, 0x4e, 0xec, - 0x8b, 0x24, 0xd3, 0x67, 0xf1, 0x6a, 0x56, 0x7b, 0xca, 0xf1, 0xee, 0x32, 0x3b, 0x01, 0x12, 0x00, - 0x37, 0xa9, 0x23, 0xe6, 0xf7, 0x12, 0x74, 0xe1, 0x95, 0xed, 0xae, 0xab, 0x72, 0x39, 0x65, 0xbc, - 0x65, 0xc7, 0x3e, 0xba, 0x36, 0x09, 0x27, 0x54, 0x8f, 0xf1, 0xe9, 0x4f, 0x64, 0x30, 0xaa, 0x29, - 0x9f, 0x5d, 0x65, 0x00, 0x00, 0x53, 0x82, 0x0f, 0xdd, 0x1c, 0x37, 0x3a, 0xbf, 0xb6, 0xba, 0xf1, - 0xbe, 0x00, 0xc8, 0x58, 0x9b, 0xbf, 0x78, 0xc5, 0xbe, 0x78, 0x7f, 0xd3, 0xb0, 0xdc, 0x2f, 0xd4, - 0xbd, 0x16, 0x7f, 0xbb, 0x36, 0xd3, 0x5f, 0x75, 0x99, 0x27, 0x3c, 0xd8, 0x44, 0xed, 0xbd, 0xb7, - 0xc1, 0xe7, 0x56, 0x27, 0x63, 0x3c, 0xa2, 0x25, 0x5b, 0xc6, 0x93, 0x9d, 0x03, 0x96, 0x19, 0xa4, - 0xd9, 0x58, 0xeb, 0xf9, 0xf4, 0xcb, 0x05, 0xa2, 0x20, 0xac, 0xf4, 0xed, 0x1a, 0xc8, 0x32, 0xa8, - 0x88, 0xc3, 0xad, 0x15, 0xcc, 0x10, 0x65, 0xd1, 0x83, 0xe4, 0x99, 0xf9, 0xfe, 0xaa, 0x44, 0xd0, - 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x76, 0x1c, 0x69, 0x22, 0x06, 0xbe, 0xcf, 0xbb, 0x90, 0x18, - 0x52, 0x80, 0x9a, 0xbc, 0x72, 0x5b, 0x82, 0xed, 0x4f, 0x22, 0x04, 0xca, 0xe6, 0xf0, 0x1d, 0x3e, - 0x19, 0x9d, 0xcc, 0xb2, 0x6a, 0x37, 0x5a, 0xa8, 0x24, 0x0d, 0x27, 0x00, 0xeb, 0x99, 0xa9, 0x6c, - 0x96, 0xd9, 0x30, 0x39, 0x3f, 0xcb, 0x4d, 0x9f, 0x97, 0x8d, 0x5a, 0xd6, 0x71, 0x42, 0x8b, 0x1d, - 0xf5, 0x72, 0x87, 0x7d, 0x4c, 0x2c, 0x80, 0x01, 0x8a, 0x1a, 0x30, 0x68, 0x6f, 0xfb, 0x6c, 0x5b, - 0xc0, 0xe8, 0x73, 0x0f, 0x77, 0xae, 0x69, 0xa2, 0xba, 0x3b, 0x86, 0xf3, 0x22, 0x1e, 0xda, 0x7b, - 0xc8, 0x50, 0xc9, 0x12, 0x89, 0xff, 0xe6, 0x57, 0xe2, 0x50, 0xef, 0x1e, 0x37, 0xda, 0xc5, 0x1d, - 0xcf, 0x63, 0xcf, 0x1c, 0x79, 0x8e, 0xf8, 0xb8, 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x29, 0x56, 0x2c, - 0x65, 0xca, 0x0c, 0x46, 0xc6, 0x0f, 0x6d, 0xc2, 0xc1, 0x9d, 0x46, 0x6b, 0x63, 0x2f, 0x24, 0x80, - 0xf9, 0x0e, 0x34, 0xbf, 0x1b, 0x00, 0x23, 0x4d, 0xef, 0x2f, 0x3f, 0x36, 0xfc, 0x5e, 0x98, 0x6d, - 0x00, 0xf5, 0x32, 0x7b, 0x17, 0x4e, 0xb7, 0xc8, 0x7f, 0x4f, 0xcb, 0x75, 0x42, 0x94, 0x8f, 0x1c, - 0x77, 0x91, 0x21, 0x58, 0x0a, 0x9f, 0xe2, 0xf0, 0x24, 0x82, 0x60, 0x38, 0x15, 0x9c, 0x66, 0xa4, - 0x0c, 0xce, 0xd7, 0x98, 0x92, 0x21, 0x82, 0xad, 0x64, 0x05, 0x9f, 0x1c, 0x81, 0x78, 0x31, 0x2e, - 0xb3, 0x35, 0xd8, 0x39, 0x26, 0xa0, 0xae, 0x18, 0xdf, 0x9b, 0x15, 0xc8, 0x54, 0x3f, 0x72, 0x73, - 0xaa, 0x6c, 0x99, 0xf3, 0x01, 0x82, 0x3f, 0x06, 0xf9, 0x22, 0x80, 0x50, 0x3f, 0xb4, 0x5d, 0x64, - 0xb5, 0xe9, 0x62, 0x2f, 0x72, 0x39, 0x76, 0x34, 0x65, 0xc7, 0x3e, 0xbd, 0x54, 0x3b, 0x16, 0x90, - 0xdc, 0x7d, 0x82, 0x5b, 0x33, 0x8a, 0xc1, 0x6a, 0x59, 0x44, 0x23, 0x87, 0x50, 0xa1, 0xc5, 0x00, - 0x00, 0x6c, 0xf6, 0x1e, 0x90, 0xfc, 0x00, 0x04, 0x36, 0x8c, 0x59, 0x9a, 0x9d, 0x6a, 0x98, 0x8f, - 0x31, 0xb2, 0x25, 0xe6, 0xca, 0x2c, 0x83, 0x26, 0x7b, 0x52, 0xdc, 0x27, 0x9f, 0xda, 0x74, 0x90, - 0xba, 0xc2, 0x2e, 0x09, 0x02, 0xec, 0xe6, 0xf4, 0x1a, 0x97, 0xc7, 0x82, 0xcf, 0x75, 0x6a, 0x2c, - 0x26, 0x04, 0x81, 0xd3, 0x70, 0xd0, 0x9c, 0x6a, 0x4e, 0x50, 0x87, 0x3f, 0x15, 0x8e, 0x6f, 0x20, - 0x50, 0xa9, 0x84, 0xea, 0xfd, 0xdf, 0x55, 0xd9, 0xb3, 0x49, 0x67, 0xc0, 0x43, 0xd2, 0xf5, 0x68, - 0x0a, 0x65, 0x54, 0x12, 0xcb, 0x7a, 0x6d, 0x50, 0xb5, 0xe9, 0x62, 0x2b, 0x72, 0x39, 0x75, 0xec, - 0xaa, 0x72, 0x28, 0x1c, 0x23, 0xca, 0x8c, 0x31, 0x24, 0xa3, 0x04, 0x8f, 0x88, 0xe2, 0xd0, 0x51, - 0x97, 0x8f, 0x00, 0xee, 0xb9, 0x2c, 0x03, 0xa3, 0x1a, 0x73, 0xd9, 0x42, 0xbc, 0x46, 0x13, 0x46, - 0x00, 0x00, 0xee, 0xc8, 0xb4, 0xc5, 0x3c, 0xe6, 0xa4, 0xe8, 0x67, 0x45, 0xf7, 0xcc, 0x7d, 0xdd, - 0x15, 0x48, 0xcf, 0xc1, 0x49, 0x8c, 0xef, 0x61, 0x96, 0xd6, 0xd9, 0x36, 0x6d, 0xb5, 0x2d, 0x39, - 0x73, 0x56, 0x21, 0xa7, 0x00, 0xf6, 0xe3, 0x6e, 0xc2, 0xf8, 0x82, 0xf9, 0x01, 0x70, 0xd3, 0x0a, - 0x44, 0xed, 0xe6, 0x74, 0xfe, 0xbe, 0xbd, 0xc4, 0xff, 0x43, 0x28, 0x18, 0xa1, 0xa4, 0x95, 0xde, - 0x49, 0x6c, 0x24, 0xc7, 0xcb, 0x7c, 0x5e, 0x71, 0xc1, 0xf9, 0x37, 0xcb, 0x11, 0xc9, 0x4a, 0xa4, - 0x95, 0xe9, 0x62, 0x2b, 0x72, 0x39, 0x65, 0x8c, 0xaf, 0xdd, 0x47, 0x5c, 0xb0, 0x00, 0x49, 0x93, - 0x33, 0x62, 0x33, 0xea, 0x01, 0x96, 0x10, 0xe9, 0xad, 0x31, 0x60, 0x63, 0xf9, 0x70, 0xb5, 0x05, - 0x93, 0x21, 0x00, 0x00, 0x00, 0x1b, 0xf0, 0xb4, 0x11, 0x74, 0xb8, 0x13, 0x3f, 0xe9, 0xa0, 0x87, - 0xa9, 0xeb, 0xf4, 0x90, 0xcd, 0xf1, 0xd5, 0x98, 0xa1, 0xc7, 0xc4, 0xf3, 0x2d, 0xe2, 0x38, 0x12, - 0x1b, 0x59, 0x0c, 0xa0, 0x6f, 0x2d, 0x00, 0xd6, 0xfb, 0xfd, 0x1f, 0x4f, 0xac, 0x83, 0x66, 0xe6, - 0x30, 0xf0, 0xe1, 0xe6, 0x5f, 0xfe, 0x37, 0x82, 0xde, 0x01, 0xe0, 0x63, 0x6f, 0x7a, 0x5b, 0x81, - 0x01, 0xf1, 0x7c, 0x58, 0x9f, 0x4a, 0x7d, 0x11, 0xd2, 0xd3, 0x20, 0x4e, 0xb5, 0xfc, 0xe3, 0x28, - 0xd9, 0x0b, 0xf6, 0x5d, 0x8e, 0x1c, 0x1c, 0xec, 0xb5, 0xed, 0xae, 0xab, 0x72, 0x29, 0x85, 0xcb, - 0xb0, 0xdc, 0x57, 0x20, 0xf0, 0xa7, 0x97, 0x09, 0x74, 0xb4, 0x8e, 0xbb, 0x8a, 0x26, 0x54, 0xe4, - 0xcd, 0x48, 0x58, 0xcc, 0xea, 0xe0, 0x6f, 0x98, 0xb6, 0x00, 0xa4, 0x1b, 0x6d, 0x00, 0x2b, 0x3a, - 0xcf, 0x5b, 0xb7, 0x5e, 0xc5, 0x12, 0x68, 0xd3, 0xaf, 0x2c, 0x53, 0x43, 0x57, 0x1f, 0xe2, 0xb6, - 0x6e, 0xb0, 0xe1, 0x95, 0x7e, 0x6d, 0x63, 0x04, 0x32, 0x58, 0x9d, 0x3a, 0xe8, 0xe2, 0x21, 0xc5, - 0x2e, 0x45, 0x56, 0xec, 0x38, 0x53, 0xe1, 0x0c, 0x98, 0xcd, 0x8f, 0x00, 0xc0, 0x58, 0x8f, 0x80, - 0x4e, 0x14, 0x9d, 0x44, 0x39, 0x0f, 0xa9, 0x8f, 0x67, 0xc8, 0xed, 0xf4, 0x69, 0x45, 0x64, 0x76, - 0x98, 0x5f, 0x96, 0xa1, 0x88, 0x8c, 0xdf, 0x5f, 0x19, 0x7e, 0xc7, 0x26, 0xc1, 0x18, 0x78, 0xdc, - 0xb4, 0x71, 0x61, 0x8b, 0x72, 0x29, 0x85, 0xf3, 0xaf, 0xdd, 0x47, 0x5c, 0xf8, 0xf7, 0x5d, 0x32, - 0xb2, 0x35, 0x24, 0x6f, 0x38, 0xf4, 0x7c, 0x9b, 0x23, 0x39, 0xdd, 0xd4, 0x86, 0x97, 0xff, 0xc8, - 0x61, 0x9b, 0xf3, 0xf2, 0xad, 0x9b, 0xb1, 0x5d, 0x07, 0x94, 0x64, 0x06, 0x3a, 0x87, 0xec, 0x50, - 0x74, 0x21, 0x00, 0xc6, 0x46, 0x09, 0xba, 0xd1, 0x31, 0x47, 0xa6, 0xeb, 0x5f, 0x5a, 0xd6, 0x49, - 0x18, 0xeb, 0x1b, 0x99, 0xf5, 0x21, 0x5a, 0xe8, 0xb0, 0xa7, 0x38, 0xc6, 0xc7, 0xf9, 0x21, 0x4a, - 0x13, 0x0a, 0xf8, 0xe6, 0xae, 0xf9, 0x9f, 0x9f, 0x40, 0x68, 0x50, 0xb8, 0x9f, 0x0c, 0xe8, 0x70, - 0xc4, 0x70, 0x33, 0x08, 0xdd, 0x46, 0x76, 0x76, 0x55, 0x74, 0x43, 0x17, 0xc9, 0xcc, 0xbb, 0x6b, - 0x50, 0x86, 0xda, 0x12, 0x79, 0x9f, 0x04, 0xaf, 0xb4, 0x4d, 0x18, 0x0b, 0x72, 0x29, 0x75, 0x83, - 0x37, 0xe8, 0x78, 0x4c, 0xdd, 0x28, 0xd1, 0xf1, 0xa5, 0x1f, 0xea, 0x9c, 0x2d, 0x1f, 0xfc, 0x29, - 0x3b, 0xca, 0x42, 0xdd, 0x56, 0x2f, 0x55, 0xaa, 0x11, 0x41, 0x23, 0x4b, 0xe0, 0x8a, 0xfe, 0x4d, - 0x49, 0x93, 0x7e, 0xd0, 0x3a, 0x26, 0x94, 0xcf, 0x54, 0xd2, 0x73, 0x43, 0xa5, 0x86, 0x08, 0x3b, - 0xdb, 0x9c, 0x33, 0x0b, 0xde, 0xd1, 0x22, 0x51, 0xa9, 0xff, 0x73, 0xe3, 0xe2, 0x0d, 0x78, 0x3b, - 0xc0, 0x66, 0xc1, 0x2b, 0x3f, 0x97, 0x7e, 0x13, 0xc7, 0x4a, 0x5b, 0x87, 0x8f, 0x43, 0xa4, 0xc2, - 0x3c, 0xad, 0xf1, 0x1a, 0x7c, 0x94, 0xfa, 0x33, 0x6a, 0xa2, 0x0c, 0x5c, 0x62, 0x75, 0x00, 0x42, - 0xab, 0xed, 0x05, 0x25, 0x58, 0x69, 0x4e, 0xc1, 0xcc, 0x53, 0xc6, 0x54, 0xc6, 0x1c, 0xce, 0x94, - 0xb4, 0x4d, 0x18, 0x0b, 0x72, 0x39, 0x55, 0xab, 0xaf, 0xa7, 0x15, 0xa8, 0xfa, 0xa5, 0x34, 0x80, - 0x03, 0xb3, 0x75, 0xe8, 0x13, 0x94, 0x18, 0xdc, 0xd8, 0x42, 0xea, 0x90, 0x95, 0x6b, 0x37, 0x53, - 0x2e, 0x0f, 0xc1, 0x0f, 0xa9, 0x55, 0x71, 0xa2, 0xbe, 0xee, 0xe2, 0x16, 0xb0, 0x47, 0x82, 0x1f, - 0x91, 0x53, 0xc1, 0xa2, 0x19, 0xc8, 0x5e, 0x37, 0x98, 0x7f, 0x20, 0x33, 0x91, 0x1b, 0x8a, 0x12, - 0xc1, 0x67, 0xa5, 0xbf, 0x6a, 0xa6, 0xc2, 0xe9, 0xf2, 0xe6, 0x21, 0x4a, 0xf0, 0xba, 0xed, 0xa3, - 0x9f, 0x8d, 0xe3, 0xc3, 0x54, 0xac, 0x01, 0x62, 0x53, 0x20, 0x7c, 0x7c, 0x53, 0x59, 0x5b, 0xd3, - 0x8a, 0x6d, 0x86, 0x32, 0x50, 0x58, 0xc5, 0xe8, 0xe3, 0xf8, 0xff, 0xc4, 0x91, 0x89, 0x75, 0x2e, - 0x8a, 0xe4, 0x9e, 0x73, 0xda, 0x64, 0x27, 0x83, 0x94, 0x3c, 0x71, 0x0b, 0x72, 0x39, 0x55, 0x6b, - 0xaf, 0xdd, 0x47, 0x5c, 0xc7, 0x48, 0xbf, 0x31, 0x23, 0xf9, 0x44, 0x19, 0xad, 0x87, 0xee, 0x99, - 0xce, 0xdd, 0xbe, 0xba, 0x25, 0x83, 0x36, 0x59, 0x62, 0x45, 0x2f, 0xcc, 0xb3, 0x56, 0xae, 0x24, - 0xc9, 0xf1, 0x9d, 0x05, 0x11, 0x5d, 0x68, 0x98, 0x71, 0xd4, 0xef, 0xa6, 0xc2, 0x21, 0x6e, 0x39, - 0x11, 0x0b, 0x96, 0x04, 0xc0, 0xfc, 0x74, 0xa4, 0xe5, 0x0e, 0xef, 0x05, 0x1a, 0x4d, 0x1e, 0x83, - 0xa8, 0xdd, 0x5f, 0xcd, 0x23, 0x89, 0x26, 0xad, 0x27, 0x0f, 0x14, 0xa0, 0xba, 0x22, 0x87, 0x05, - 0x98, 0xab, 0x84, 0x4e, 0x9f, 0x7d, 0x8e, 0x28, 0x09, 0x8f, 0xf2, 0xe1, 0xe6, 0xbe, 0xa3, 0x9e, - 0xf4, 0xb4, 0xd3, 0x2d, 0x93, 0xb5, 0x8c, 0xe6, 0x3b, 0x7e, 0x27, 0x17, 0x9c, 0x31, 0x26, 0x42, - 0xb4, 0x3c, 0x71, 0x0b, 0x72, 0x29, 0x65, 0x4b, 0xaf, 0xdc, 0xf2, 0xe1, 0x37, 0x69, 0x8f, 0x62, - 0x94, 0xaa, 0x2e, 0x8f, 0x4c, 0x13, 0x76, 0x24, 0xa7, 0xc5, 0x6a, 0xeb, 0xcd, 0xe4, 0x11, 0x6e, - 0xaa, 0x4d, 0x5a, 0xbc, 0x30, 0x81, 0xcb, 0xaf, 0x22, 0x20, 0x00, 0x55, 0x45, 0x25, 0x83, 0xf9, - 0xb2, 0x42, 0x42, 0x5c, 0x7f, 0x20, 0x1c, 0x45, 0x7d, 0x12, 0xa8, 0xfe, 0x93, 0xad, 0x29, 0x9e, - 0xb1, 0xdc, 0xc6, 0xaa, 0xc1, 0xb5, 0x4d, 0xae, 0xe6, 0xe2, 0x50, 0x62, 0x66, 0xb7, 0x13, 0x9e, - 0x84, 0xe3, 0xed, 0x02, 0x90, 0x01, 0x84, 0x09, 0x8e, 0x18, 0x12, 0xe0, 0xf9, 0x0f, 0x38, 0x35, - 0xb1, 0x62, 0x99, 0x3a, 0xc5, 0x21, 0x65, 0xa1, 0x4e, 0xe5, 0x63, 0x3f, 0x9c, 0x43, 0x63, 0xb4, - 0xae, 0xc8, 0x52, 0x31, 0xa2, 0x2a, 0xf5, 0xf3, 0x94, 0x3c, 0x71, 0x0b, 0x72, 0x39, 0x55, 0x53, - 0xaf, 0xa6, 0xca, 0x13, 0x95, 0x17, 0x6c, 0x2d, 0x47, 0x4e, 0xf4, 0x3a, 0xb8, 0xf0, 0x27, 0x55, - 0xf9, 0x78, 0x67, 0x4e, 0x50, 0x6a, 0xc0, 0x2b, 0x9f, 0xe5, 0xda, 0x28, 0xcc, 0x23, 0xae, 0x95, - 0xd0, 0xc0, 0xff, 0x90, 0xcf, 0xf1, 0x89, 0x7e, 0xc9, 0x79, 0x70, 0x48, 0xc4, 0x47, 0x85, 0x26, - 0x37, 0x26, 0xc4, 0x55, 0x42, 0xd7, 0xd3, 0x69, 0x9f, 0x2f, 0xe7, 0xf4, 0x2c, 0x5d, 0x96, 0x37, - 0xb0, 0xb7, 0x47, 0x3d, 0x1e, 0x3d, 0xf3, 0x39, 0xe5, 0xdc, 0xe7, 0x81, 0xf1, 0x7d, 0x22, 0xd7, - 0x09, 0xee, 0x56, 0x19, 0xe7, 0xc6, 0x53, 0x43, 0x0c, 0x8b, 0x37, 0x62, 0x68, 0x9e, 0x90, 0xa8, - 0x88, 0x9b, 0x14, 0x5d, 0x29, 0xdf, 0xaf, 0xfa, 0x7d, 0x7e, 0x0f, 0x63, 0xb3, 0xc7, 0x2e, 0xbf, - 0x94, 0x3c, 0x71, 0x0b, 0x72, 0x29, 0x45, 0x4b, 0x69, 0xab, 0xe4, 0x62, 0x9f, 0xb0, 0x4e, 0xd3, - 0x48, 0xa7, 0xb8, 0xa8, 0x6b, 0x21, 0xd6, 0x1a, 0x0d, 0xcc, 0xe5, 0x36, 0xc5, 0x24, 0xba, 0xad, - 0xdf, 0x35, 0xe1, 0x45, 0xa8, 0xd4, 0x8c, 0x4e, 0x88, 0x37, 0x5f, 0x09, 0x05, 0x0d, 0x8d, 0x14, - 0x44, 0xd7, 0x7e, 0x17, 0x13, 0xa4, 0xd4, 0x74, 0x9d, 0x64, 0x6d, 0x60, 0xd0, 0x4c, 0x82, 0x4e, - 0x3a, 0xb4, 0x3b, 0xd6, 0xe3, 0xa9, 0xe3, 0xda, 0x0b, 0x97, 0xec, 0xc4, 0x1a, 0x65, 0x64, 0x4a, - 0x00, 0x38, 0xf2, 0x3c, 0x3f, 0x09, 0x9e, 0x22, 0x2b, 0x00, 0xaf, 0x4c, 0xac, 0x3b, 0x00, 0x1d, - 0x25, 0xab, 0x0b, 0x1a, 0x56, 0xe1, 0x7b, 0x8e, 0xc8, 0x80, 0x4e, 0x68, 0xcf, 0x18, 0x74, 0x19, - 0x10, 0x2c, 0xa0, 0x8c, 0x42, 0x04, 0x38, 0xf7, 0xb4, 0x4d, 0x18, 0x0b, 0x72, 0x29, 0x65, 0x4b, - 0xb0, 0xd2, 0xbf, 0xfa, 0x22, 0x62, 0xa0, 0x3a, 0xbe, 0x16, 0x43, 0x4e, 0xd1, 0x9e, 0x40, 0x98, - 0x3c, 0x1c, 0x26, 0xe8, 0x69, 0xae, 0x0e, 0x13, 0xa9, 0x1e, 0x42, 0x47, 0x9e, 0x7a, 0x56, 0xf6, - 0xc0, 0xb6, 0xbb, 0x80, 0x00, 0x34, 0xd4, 0x27, 0x3b, 0x31, 0x20, 0xa2, 0xdb, 0x0e, 0x81, 0xe9, - 0x23, 0x27, 0x8c, 0xd2, 0x20, 0xf6, 0x1a, 0x79, 0xe7, 0x23, 0x51, 0xec, 0x6f, 0x15, 0x7c, 0x7f, - 0x7b, 0xce, 0xa9, 0x30, 0xf9, 0xb4, 0x4a, 0x1e, 0x27, 0x3e, 0xc3, 0xe1, 0x10, 0x60, 0xfa, 0xc1, - 0x62, 0x6a, 0x67, 0x43, 0x62, 0xe1, 0x9d, 0x30, 0x75, 0x2a, 0x19, 0xf1, 0x5e, 0xd6, 0x06, 0xaf, - 0x46, 0xb7, 0x1c, 0x47, 0x0d, 0xc8, 0xd3, 0xc3, 0x65, 0xf0, 0x66, 0x83, 0xc5, 0x9e, 0xe3, 0x1c, - 0xb4, 0x3c, 0x71, 0x0b, 0x72, 0x29, 0x45, 0x63, 0xb0, 0xd2, 0xc2, 0x06, 0xf4, 0x6c, 0xfb, 0xc1, - 0x8f, 0x89, 0x8a, 0x74, 0x0a, 0xd2, 0x5f, 0x4a, 0xf9, 0x7c, 0x3c, 0x51, 0xcf, 0x28, 0x07, 0x36, - 0xca, 0xbd, 0x7a, 0xcd, 0xd0, 0x57, 0x1f, 0x54, 0x01, 0x19, 0x8c, 0xd0, 0x8b, 0x1e, 0x40, 0xa5, - 0x76, 0x7f, 0xb0, 0x25, 0x79, 0x3c, 0xa4, 0x51, 0x74, 0xa3, 0x6a, 0x53, 0x44, 0xbb, 0x9a, 0x39, - 0xa7, 0x8b, 0xd4, 0x66, 0xe5, 0x8e, 0x52, 0xc9, 0xbb, 0x9e, 0x2a, 0x19, 0x31, 0x12, 0x15, 0x5d, - 0x4b, 0x8f, 0xfc, 0x08, 0xb2, 0xd3, 0x0a, 0xb8, 0xad, 0xa7, 0x38, 0xba, 0xd6, 0x83, 0xb3, 0xe8, - 0x74, 0x04, 0xd4, 0x19, 0x01, 0xc4, 0xc3, 0x96, 0xe5, 0x8a, 0xe1, 0x17, 0x09, 0xf0, 0xd4, 0x40, - 0x9a, 0xce, 0x1b, 0x1e, 0x1c, 0x9c, 0x3d, 0x0b, 0xb2, 0xfc, 0xd5, 0xcb, 0x72, 0x29, 0x55, 0x43, - 0xaf, 0xdd, 0x92, 0x47, 0xe0, 0x4e, 0xf8, 0xd3, 0x44, 0x79, 0xec, 0x05, 0x38, 0xd5, 0x9d, 0xfe, - 0xec, 0x81, 0xc0, 0xd3, 0x3d, 0xcd, 0x5c, 0x3b, 0x04, 0x92, 0x44, 0x6b, 0x60, 0x15, 0xc9, 0x08, - 0xc9, 0x19, 0xe7, 0xc3, 0x95, 0x00, 0x06, 0xf0, 0x63, 0x39, 0x2f, 0x9d, 0xca, 0xe7, 0xdd, 0x5e, - 0xe8, 0x42, 0x60, 0xae, 0xf7, 0x3d, 0x54, 0x97, 0xc8, 0xf0, 0xae, 0xe7, 0xc9, 0x19, 0xc0, 0xba, - 0xeb, 0xff, 0x21, 0xa9, 0xe4, 0xbd, 0x3f, 0xfb, 0xb8, 0x4a, 0x9c, 0x3e, 0x48, 0x8c, 0x19, 0xc2, - 0x61, 0xcf, 0x94, 0xd6, 0x20, 0x58, 0x2e, 0x7f, 0x00, 0x95, 0x6f, 0x65, 0x5d, 0x45, 0xc6, 0x76, - 0x59, 0x54, 0x9c, 0xa5, 0x52, 0x15, 0x68, 0x05, 0x92, 0x9e, 0xd3, 0x98, 0x75, 0xdc, 0x37, 0x6e, - 0xb2, 0xfc, 0xd5, 0xcb, 0x72, 0x39, 0x45, 0x3b, 0xaf, 0xa6, 0xc8, 0x6c, 0x71, 0xa7, 0x64, 0xc8, - 0x03, 0xf6, 0x41, 0x91, 0xe2, 0xaa, 0x0d, 0x16, 0x53, 0xcc, 0x0b, 0xaf, 0xcf, 0x29, 0x88, 0x88, - 0xc5, 0x52, 0x40, 0x05, 0x03, 0x49, 0xbe, 0xcf, 0x29, 0x47, 0xdf, 0x86, 0x00, 0x00, 0x0d, 0xa8, - 0x9a, 0x70, 0xe5, 0x7d, 0xbc, 0x39, 0xd0, 0xee, 0x27, 0x3b, 0xea, 0xfa, 0xaa, 0xb5, 0x90, 0x9d, - 0xfc, 0xb9, 0x2d, 0x43, 0xa0, 0xb7, 0xc5, 0xb3, 0xb4, 0x38, 0xfa, 0x6c, 0xe8, 0x55, 0x2e, 0xba, - 0xd9, 0xe1, 0xdc, 0xe1, 0x38, 0x0e, 0xf7, 0xe6, 0x8b, 0x29, 0xbc, 0xe9, 0x93, 0x90, 0x6a, 0x66, - 0x5b, 0x06, 0x91, 0x5d, 0x4c, 0xfe, 0x15, 0x15, 0x8f, 0xd5, 0xd3, 0x82, 0xfd, 0x0b, 0xc9, 0x02, - 0x71, 0x31, 0x8d, 0xc7, 0x03, 0x0e, 0x1e, 0x33, 0xb2, 0xfc, 0xd5, 0xcb, 0x72, 0x29, 0x45, 0x43, - 0xaf, 0xdd, 0x49, 0x48, 0xd3, 0x75, 0x5e, 0xb0, 0xd0, 0xb0, 0x73, 0x72, 0x7d, 0x02, 0x7b, 0x87, - 0x8e, 0x21, 0xd1, 0xd1, 0xac, 0x4a, 0xb8, 0x7d, 0x1a, 0x56, 0x42, 0x43, 0x9a, 0x3b, 0xfe, 0xda, - 0x43, 0xb4, 0x11, 0x0a, 0x88, 0x0e, 0x16, 0xf1, 0xfe, 0x0c, 0x9b, 0x62, 0x20, 0x22, 0x25, 0x69, - 0xb6, 0x6d, 0x50, 0x93, 0x3e, 0xa7, 0x40, 0x85, 0x5a, 0xd0, 0x9d, 0x33, 0x8c, 0x92, 0xf5, 0x19, - 0xdd, 0xef, 0x2b, 0x3e, 0xb3, 0xdb, 0xf7, 0x91, 0xd6, 0x0d, 0xd3, 0x21, 0x10, 0xc0, 0xaf, 0x56, - 0x95, 0xac, 0x9e, 0x9c, 0xde, 0xb4, 0x81, 0x1f, 0x47, 0xf9, 0x0f, 0xdd, 0xbe, 0x03, 0xab, 0x3a, - 0x4c, 0x2e, 0x80, 0x3a, 0xc2, 0x27, 0x1c, 0x68, 0x60, 0x65, 0xce, 0x31, 0x43, 0x9d, 0x32, 0x63, - 0xb2, 0xfc, 0xd5, 0xcb, 0x72, 0x29, 0x35, 0x43, 0xaf, 0xdd, 0x47, 0x5c, 0xf9, 0x00, 0xce, 0xda, - 0x72, 0x75, 0xe5, 0xce, 0x0f, 0xda, 0x63, 0xf1, 0xbb, 0x2f, 0x6e, 0x27, 0xaf, 0xc9, 0xf9, 0x05, - 0x2f, 0x3b, 0x77, 0x81, 0x72, 0xfe, 0x1c, 0x01, 0xb7, 0x00, 0xf3, 0x32, 0x27, 0x6c, 0xfa, 0x1e, - 0xeb, 0x80, 0x00, 0x1b, 0xe5, 0x20, 0x2d, 0x53, 0x50, 0xe1, 0x92, 0x72, 0x7d, 0x1d, 0x9b, 0x6f, - 0xaa, 0x9d, 0x8a, 0x3c, 0x5a, 0xa6, 0xa0, 0x19, 0xf7, 0x4b, 0x4f, 0x1a, 0xc7, 0x13, 0xae, 0xcf, - 0xa1, 0x80, 0x05, 0x8a, 0x1b, 0x78, 0x51, 0xe3, 0x70, 0x5e, 0x7f, 0x7a, 0x5b, 0x7b, 0x03, 0x67, - 0x5c, 0x30, 0xb4, 0xbe, 0xc5, 0xf1, 0x4d, 0x2b, 0x9d, 0x95, 0xf2, 0xe0, 0x68, 0x3f, 0x9c, 0x71, - 0xe0, 0x3c, 0x0f, 0x82, 0x06, 0xc1, 0xb1, 0xdc, 0xb2, 0xf7, 0x96, 0xcf, 0x72, 0x29, 0x25, 0x1b, - 0xaf, 0xa7, 0x16, 0x19, 0x40, 0xf1, 0x9c, 0x25, 0x92, 0x3f, 0x33, 0xb2, 0xbf, 0x20, 0xb3, 0xa0, - 0x2d, 0x5d, 0xae, 0x21, 0xf2, 0xc5, 0xb8, 0x11, 0x55, 0x11, 0x4b, 0x02, 0xc7, 0x79, 0x44, 0x5f, - 0x48, 0xb5, 0x1e, 0x16, 0x00, 0x07, 0x9a, 0xbe, 0xf0, 0x4d, 0x7d, 0x00, 0x20, 0x8a, 0x54, 0xf4, - 0x21, 0xf3, 0x81, 0x1d, 0x49, 0x66, 0x9c, 0xb5, 0xf2, 0x32, 0xa6, 0xcb, 0x96, 0xd0, 0x2c, 0xd0, - 0x20, 0x1c, 0xfa, 0xce, 0xa2, 0x43, 0x4a, 0x0f, 0xf1, 0x51, 0x82, 0x6f, 0x87, 0xde, 0x9d, 0x20, - 0x17, 0x72, 0x69, 0x02, 0xe2, 0x8d, 0x0c, 0x3f, 0x68, 0x87, 0x07, 0xaa, 0xf2, 0xd7, 0xec, 0xd4, - 0x8c, 0x01, 0xc2, 0x79, 0x02, 0xbf, 0xfb, 0xc6, 0x29, 0xa4, 0x65, 0x31, 0xdb, 0x5a, 0x65, 0xbc, - 0xb2, 0xf7, 0x96, 0xcb, 0x72, 0x39, 0x55, 0x34, 0xaf, 0xa6, 0xc8, 0x17, 0xb7, 0x7d, 0xd5, 0xca, - 0x74, 0xc2, 0x5c, 0x37, 0x77, 0xf3, 0xf9, 0x9b, 0x22, 0xa2, 0x30, 0x43, 0x24, 0x9d, 0x13, 0xb0, - 0x8c, 0x2c, 0xb4, 0x26, 0x5b, 0x91, 0xcb, 0xd0, 0x02, 0xe9, 0xea, 0x3e, 0xb9, 0xbd, 0xc7, 0xd3, - 0x12, 0x4c, 0x44, 0xcf, 0xfe, 0xee, 0xb3, 0xfc, 0xf8, 0x7d, 0xd0, 0x28, 0xd0, 0xc9, 0x5e, 0xbc, - 0x0a, 0xd6, 0xf6, 0xa7, 0x19, 0x4a, 0x53, 0x3b, 0x45, 0xfb, 0x17, 0x90, 0x9b, 0xd2, 0xf2, 0x03, - 0xea, 0x1f, 0x0f, 0x0a, 0x3d, 0x82, 0xd0, 0x92, 0x50, 0x3c, 0xaa, 0x8f, 0x0c, 0x9c, 0x2a, 0x03, - 0xb0, 0x76, 0x51, 0xab, 0x45, 0x27, 0xa8, 0x00, 0x0e, 0x31, 0xf1, 0x68, 0x25, 0x0d, 0x5f, 0x8a, - 0xf2, 0x87, 0xf8, 0x7c, 0x38, 0xdf, 0x67, 0x04, 0x92, 0xf7, 0x96, 0xcb, 0x72, 0x29, 0x25, 0x4b, - 0x69, 0xd4, 0x6d, 0x1c, 0xb8, 0xb2, 0x19, 0x82, 0x7a, 0xc5, 0x7e, 0x26, 0xbd, 0x0c, 0x51, 0xe1, - 0xb3, 0x8e, 0xe9, 0xf5, 0x0e, 0xec, 0x92, 0x79, 0x9c, 0x5d, 0x5a, 0xec, 0x4d, 0x1f, 0x9d, 0x03, - 0x5e, 0xcf, 0x10, 0x00, 0x00, 0x55, 0xb2, 0xb3, 0x23, 0xfd, 0xa2, 0x86, 0x58, 0xeb, 0xdd, 0xe8, - 0x29, 0xc3, 0x02, 0x4a, 0x66, 0x04, 0x41, 0xa8, 0x85, 0x6d, 0xc4, 0x07, 0xd7, 0x1f, 0xec, 0x46, - 0x3d, 0xbf, 0x8b, 0xf1, 0x3d, 0xb8, 0xf0, 0x7d, 0x6c, 0xd3, 0xaf, 0x80, 0x5a, 0x1b, 0x43, 0xd9, - 0x89, 0xd4, 0x91, 0xbd, 0x3c, 0xf1, 0x53, 0x86, 0x1c, 0x31, 0x38, 0x7f, 0x08, 0x17, 0x77, 0x73, - 0x60, 0x20, 0x4f, 0x4b, 0x66, 0x09, 0x76, 0x38, 0xdf, 0x8e, 0x00, 0x20, 0x19, 0xfb, 0x36, 0xe8, - 0xd2, 0xf7, 0x96, 0xcb, 0x72, 0x39, 0x55, 0x44, 0x69, 0xd5, 0x83, 0xaf, 0xc3, 0x79, 0x09, 0x0e, - 0x52, 0xd2, 0x55, 0x8d, 0x78, 0xcc, 0x3a, 0x6c, 0x65, 0xc1, 0xcc, 0x02, 0xac, 0x02, 0x40, 0x73, - 0x29, 0x63, 0x1f, 0x13, 0x45, 0x67, 0x03, 0xf9, 0x08, 0xa2, 0x20, 0x00, 0x00, 0x91, 0x15, 0xe4, - 0x27, 0x74, 0xe0, 0xf0, 0x90, 0x05, 0x2f, 0xda, 0x12, 0xdd, 0xaa, 0x2d, 0x00, 0x25, 0xf0, 0xd5, - 0xaa, 0x72, 0xa6, 0x30, 0xc6, 0x7f, 0x9d, 0x33, 0xce, 0x22, 0xcd, 0x65, 0x84, 0x35, 0xe8, 0xe2, - 0xb8, 0x0d, 0xf0, 0xa5, 0x40, 0x79, 0x01, 0x28, 0x6b, 0x0c, 0x32, 0x89, 0x4e, 0xc0, 0xe7, 0xef, - 0xb6, 0x85, 0xd9, 0x63, 0x91, 0x85, 0xee, 0x0c, 0xa5, 0x7d, 0x71, 0xf3, 0x29, 0x01, 0xbd, 0x52, - 0x57, 0xd7, 0x48, 0x13, 0x63, 0xb8, 0xb0, 0x09, 0xb2, 0xf7, 0x96, 0xcb, 0x72, 0x39, 0x55, 0x44, - 0x69, 0xd9, 0xef, 0x6c, 0xb2, 0x38, 0xbe, 0x9e, 0x51, 0xd0, 0xd9, 0x42, 0xfd, 0xf2, 0xa0, 0x1d, - 0x83, 0x0d, 0xb8, 0xeb, 0xbe, 0xfd, 0xdd, 0xc4, 0x1b, 0x86, 0xb7, 0xa3, 0x2d, 0x79, 0x91, 0xc5, - 0x58, 0x6c, 0x47, 0x20, 0x4f, 0xe9, 0x53, 0xab, 0x16, 0x22, 0x45, 0x5c, 0xa5, 0xce, 0x7c, 0x0f, - 0xd6, 0xd0, 0xd1, 0x15, 0x95, 0x10, 0xb9, 0xb1, 0x25, 0x79, 0x74, 0x07, 0x2e, 0xb8, 0x2a, 0x55, - 0x42, 0x4f, 0xd6, 0x45, 0x3d, 0x5e, 0x19, 0x86, 0x0a, 0x28, 0xc1, 0x36, 0xf7, 0xeb, 0x9e, 0x8e, - 0xe0, 0x34, 0x21, 0x87, 0x47, 0xdb, 0x03, 0x3f, 0x4a, 0x88, 0x12, 0x43, 0x86, 0x68, 0x7a, 0x1c, - 0x55, 0x66, 0x1d, 0x6b, 0x0a, 0xb3, 0x03, 0x12, 0x7e, 0x30, 0xd2, 0xc4, 0x89, 0x6a, 0xc8, 0x71, - 0xb2, 0xf7, 0x96, 0xcb, 0x72, 0x39, 0x35, 0x2c, 0x04, 0x80, 0xcf, 0x6e, 0xba, 0x53, 0x7e, 0xfc, - 0x48, 0x13, 0xb0, 0xb2, 0xe0, 0x4a, 0x27, 0x0a, 0x77, 0x12, 0x5e, 0x41, 0x52, 0xd7, 0xe2, 0x25, - 0x8a, 0x30, 0x0a, 0x64, 0x05, 0x9b, 0x60, 0x62, 0x7f, 0x5a, 0x06, 0x2a, 0x60, 0x8f, 0x2d, 0xbd, - 0x03, 0xc8, 0xaf, 0xcb, 0x2b, 0x0c, 0x6e, 0x17, 0x2d, 0x8b, 0x4d, 0xf9, 0x2d, 0x9f, 0x50, 0x28, - 0x0e, 0x87, 0x60, 0xa5, 0x32, 0x00, 0x1c, 0x80, 0x4a, 0x6b, 0x1a, 0xf1, 0x7b, 0xe5, 0x0c, 0x36, - 0x6f, 0x09, 0xe1, 0xf1, 0x39, 0x0c, 0x14, 0x43, 0xa0, 0x85, 0x69, 0x0c, 0x4d, 0x63, 0xcc, 0x13, - 0x2e, 0x06, 0x29, 0x29, 0x3e, 0x62, 0xeb, 0xea, 0xf9, 0xb3, 0x6d, 0x39, 0x82, 0x04, 0xf8, 0xe3, - 0xdc, 0xe0, 0xf8, 0x7c, 0x67, 0x13, 0x84, 0xf2, 0xab, 0x26, 0x2d, 0xe5, 0x72, 0x09, 0x55, 0x3c, - 0x00, 0x02, 0x0b, 0xfd, 0x34, 0x96, 0xcd, 0x2c, 0x13, 0xf5, 0x15, 0x62, 0xb3, 0x0c, 0xbc, 0xb0, - 0xf2, 0x55, 0x65, 0x77, 0x8a, 0x88, 0x33, 0xde, 0x29, 0xdc, 0xa7, 0xaa, 0xf1, 0x3b, 0xb7, 0xe1, - 0xf0, 0x3f, 0x7e, 0x0b, 0xd3, 0xc2, 0xca, 0x1c, 0x82, 0x29, 0x75, 0xd3, 0x40, 0x44, 0x2c, 0x35, - 0x60, 0x0b, 0xe3, 0x7c, 0xf0, 0x8d, 0x92, 0x6b, 0xa1, 0xad, 0x23, 0x83, 0x51, 0x37, 0xe4, 0x7e, - 0xdf, 0x43, 0xf8, 0xb0, 0xac, 0x3a, 0x03, 0x9d, 0xad, 0xcd, 0x2f, 0x0c, 0xc0, 0xca, 0x10, 0x80, - 0xb6, 0x78, 0x9d, 0x02, 0x39, 0xd5, 0x1b, 0xa6, 0x4b, 0x1c, 0x4b, 0x13, 0xf0, 0xf2, 0xf0, 0x3e, - 0x83, 0xc4, 0x95, 0x57, 0xc3, 0x9a, 0x38, 0xf0, 0x7c, 0x1f, 0x1c, 0x1e, 0x73, 0x25, 0x99, 0xe1, - 0xcb, 0x26, 0x2d, 0xe5, 0x72, 0x09, 0x65, 0x44, 0x00, 0x00, 0x5c, 0x72, 0x41, 0xbd, 0xd3, 0x72, - 0xc5, 0x97, 0xa1, 0x09, 0x85, 0xb7, 0xb5, 0xcd, 0x87, 0xb2, 0x14, 0xf7, 0xe4, 0xa2, 0x56, 0xf3, - 0x24, 0xd9, 0x78, 0xeb, 0x77, 0x74, 0x15, 0x2d, 0x80, 0xee, 0xd7, 0xd1, 0x9b, 0x8f, 0xd9, 0x48, - 0xcf, 0x65, 0x14, 0x8b, 0xd3, 0xed, 0x61, 0x71, 0xd3, 0x58, 0x6d, 0x8f, 0xb9, 0x3a, 0x12, 0xb8, - 0x11, 0xf0, 0x7f, 0x98, 0x0f, 0xf7, 0x0d, 0xf0, 0x6a, 0x30, 0x63, 0xc4, 0xa3, 0xf7, 0x6f, 0x30, - 0x1e, 0x7a, 0x8f, 0x5f, 0x02, 0x0a, 0xa1, 0x76, 0x95, 0x11, 0x0e, 0xb3, 0x25, 0xc1, 0x24, 0xed, - 0x84, 0x1a, 0xa0, 0x02, 0x74, 0x91, 0x93, 0xe5, 0x53, 0x6a, 0x01, 0xdb, 0x68, 0x00, 0x70, 0xec, - 0xc7, 0x0f, 0x8f, 0x3f, 0x87, 0x33, 0xd4, 0x3b, 0xab, 0x26, 0x2d, 0xe5, 0x72, 0x09, 0x65, 0x3c, - 0x00, 0x00, 0xa8, 0xe7, 0x3f, 0x87, 0x15, 0x13, 0x4d, 0x2e, 0xb6, 0x5d, 0x73, 0x44, 0x5c, 0x0f, - 0x96, 0xbd, 0x9a, 0x07, 0xe4, 0xe8, 0x25, 0x9e, 0x4e, 0xb8, 0xec, 0x83, 0xac, 0xd8, 0x21, 0x8c, - 0x49, 0xb6, 0x03, 0xf8, 0x10, 0x7d, 0x94, 0x7c, 0x00, 0xb2, 0xad, 0x2c, 0xfa, 0x1e, 0xd2, 0x5a, - 0x4d, 0xa3, 0x3e, 0x84, 0x85, 0x6e, 0x6a, 0x75, 0x12, 0x86, 0x12, 0xed, 0xfe, 0x12, 0xb6, 0x7f, - 0x44, 0x20, 0x88, 0x9f, 0x74, 0xcc, 0x4b, 0x8f, 0x8c, 0xed, 0xf2, 0x1e, 0x2e, 0xd2, 0x25, 0x93, - 0x1f, 0x5c, 0xd2, 0x6c, 0xcb, 0x4e, 0x4a, 0x01, 0xd7, 0xe0, 0xb9, 0x6d, 0x4a, 0x95, 0xcb, 0x98, - 0x5b, 0x12, 0x7c, 0x7e, 0xa4, 0x37, 0x87, 0x99, 0xc7, 0x87, 0x87, 0xc3, 0xc1, 0x87, 0x1b, 0x3b, - 0xab, 0x26, 0x2d, 0xe5, 0x72, 0x09, 0x65, 0x4c, 0x00, 0x00, 0x49, 0x66, 0xcd, 0x0f, 0xe2, 0x90, - 0x44, 0x22, 0xa7, 0xe4, 0x98, 0x09, 0x9e, 0xc8, 0x8e, 0x98, 0xff, 0x70, 0x84, 0xb0, 0x2b, 0xaf, - 0xd0, 0x13, 0xb2, 0xa3, 0xc1, 0xd0, 0xe2, 0x9a, 0xac, 0xf5, 0xeb, 0x1e, 0xa4, 0x99, 0x49, 0x97, - 0x16, 0x6d, 0x1f, 0xcc, 0x78, 0x57, 0xec, 0x44, 0x2a, 0x18, 0x86, 0x60, 0x85, 0x9d, 0x9e, 0x14, - 0x7b, 0x1b, 0x42, 0xa8, 0x40, 0x17, 0xa1, 0x89, 0xc8, 0xe9, 0xd8, 0x98, 0x78, 0x56, 0x8a, 0x32, - 0x00, 0x46, 0x03, 0x4d, 0x13, 0x13, 0x5f, 0x7c, 0x7f, 0xb6, 0x03, 0x8f, 0x67, 0x95, 0x59, 0xcf, - 0xf4, 0xc6, 0x21, 0x57, 0x38, 0x2b, 0x78, 0x77, 0x88, 0x07, 0x66, 0x1c, 0x38, 0x60, 0x39, 0xf1, - 0xf0, 0xf0, 0xf0, 0x7d, 0xe1, 0xeb, 0x5c, 0x48, 0xb2, 0xf7, 0x8a, 0xcb, 0x72, 0x09, 0x35, 0x3c, - 0xb6, 0xba, 0x95, 0xeb, 0x8c, 0xcb, 0x32, 0x16, 0x68, 0x08, 0xe8, 0xf3, 0x54, 0xed, 0xd0, 0x23, - 0xb8, 0xd8, 0xfe, 0x83, 0x49, 0x8a, 0x2c, 0xed, 0x74, 0x11, 0x5a, 0xe3, 0xe9, 0x3a, 0x74, 0x01, - 0x6f, 0x93, 0xa5, 0x68, 0xf6, 0xc2, 0xb0, 0x27, 0xab, 0xed, 0x83, 0xfe, 0x73, 0x59, 0x33, 0xf2, - 0x9a, 0xa0, 0x43, 0xd5, 0xce, 0x9d, 0xbc, 0xe6, 0x06, 0x13, 0x52, 0x2e, 0xaf, 0x50, 0x10, 0x02, - 0xb8, 0xf8, 0x78, 0x81, 0xf8, 0x21, 0xb2, 0xe7, 0xbd, 0x7c, 0x79, 0x56, 0x1d, 0xc1, 0x9f, 0x98, - 0xd9, 0x81, 0xd6, 0x38, 0x54, 0x41, 0x32, 0xa1, 0x1c, 0x62, 0x3e, 0x1e, 0x25, 0x7f, 0xb8, 0xbd, - 0x34, 0x93, 0x90, 0x08, 0x27, 0xc1, 0xe0, 0xf8, 0xf0, 0x7e, 0x1e, 0x1e, 0x1f, 0xb3, 0x62, 0x33, - 0xa6, 0x97, 0x6d, 0x65, 0x72, 0x19, 0x55, 0x4c, 0x00, 0x00, 0xad, 0xf5, 0xb8, 0x70, 0x1c, 0x3d, - 0x42, 0x6e, 0x7f, 0x08, 0x9a, 0x82, 0x46, 0x2b, 0x81, 0x4c, 0xbe, 0xaa, 0x01, 0xdb, 0x75, 0x89, - 0x79, 0x95, 0xc3, 0xbc, 0x16, 0x20, 0x87, 0x3c, 0xca, 0x15, 0xee, 0x26, 0xcf, 0x22, 0xce, 0x43, - 0xc0, 0xd3, 0x55, 0xd6, 0xac, 0x9c, 0x24, 0x66, 0xb5, 0xb0, 0x59, 0x76, 0x60, 0x23, 0xd4, 0xc8, - 0x62, 0xa3, 0x10, 0xe4, 0x25, 0x8e, 0x35, 0x1a, 0xd1, 0x49, 0x59, 0x1b, 0x8a, 0x54, 0xfc, 0x01, - 0x1a, 0xa8, 0xdf, 0x01, 0x51, 0x54, 0x5f, 0x58, 0x65, 0x22, 0xcc, 0xca, 0x31, 0xcd, 0x5f, 0xd2, - 0x6e, 0x5c, 0xbe, 0x4f, 0xc7, 0x6c, 0x0a, 0x6d, 0xc4, 0x26, 0x42, 0x1e, 0xbd, 0x86, 0x20, 0x8e, - 0x18, 0x73, 0x9e, 0x7b, 0xc0, 0x31, 0xa2, 0x2d, 0xb2, 0xf7, 0x8a, 0xcb, 0x72, 0x09, 0x45, 0x54, - 0xb7, 0x90, 0x1e, 0x6d, 0xf4, 0xf7, 0xba, 0x1c, 0x9d, 0x28, 0xa9, 0x49, 0xa0, 0xd4, 0x89, 0xa5, - 0xbb, 0x2d, 0xb1, 0xe6, 0xb5, 0x6f, 0x41, 0x76, 0x40, 0x59, 0x6b, 0x67, 0x1f, 0x5d, 0xae, 0x4c, - 0xbf, 0x68, 0x0c, 0xdc, 0x06, 0xa1, 0x0c, 0xf6, 0x02, 0xf9, 0xc2, 0x57, 0xe0, 0x02, 0xb6, 0x81, - 0x80, 0xac, 0x8b, 0x94, 0x6b, 0x89, 0xb2, 0x6d, 0x54, 0xa3, 0xf1, 0xb7, 0x49, 0x0f, 0x12, 0xc7, - 0xf2, 0x84, 0x97, 0x89, 0xf2, 0x63, 0x9f, 0x11, 0xcb, 0xbe, 0x0f, 0x91, 0x12, 0x80, 0x8a, 0x40, - 0xde, 0x5e, 0x9a, 0x92, 0xb6, 0x7b, 0xd1, 0x42, 0xf6, 0xa5, 0xef, 0x98, 0xc2, 0x4b, 0x74, 0x4e, - 0xe2, 0x39, 0x84, 0x78, 0x86, 0x3e, 0x0f, 0x1e, 0x3c, 0x38, 0xf8, 0x39, 0xd6, 0x7a, 0xf1, 0xf8, - 0xb2, 0xf7, 0x8a, 0xcb, 0x72, 0x19, 0x45, 0x5c, 0xb7, 0x8e, 0x57, 0xf0, 0x5a, 0xe1, 0xbe, 0x1d, - 0xde, 0x3a, 0xfc, 0x59, 0x2f, 0x95, 0x9a, 0x2e, 0xa3, 0x5a, 0xc6, 0xed, 0x24, 0x61, 0x10, 0xc8, - 0xff, 0x18, 0xef, 0xaa, 0x5b, 0xbc, 0xd9, 0x6e, 0xd7, 0x71, 0xb8, 0x95, 0x91, 0x0f, 0x74, 0xf3, - 0xa9, 0x87, 0x80, 0x37, 0xff, 0x65, 0xef, 0x3a, 0x46, 0x7e, 0xa1, 0x15, 0xd4, 0x23, 0x3e, 0xa5, - 0xb4, 0x7a, 0x13, 0x60, 0x61, 0xb8, 0x5d, 0xb5, 0x2b, 0xf5, 0x73, 0xb0, 0xd0, 0x20, 0x38, 0x0a, - 0x37, 0xce, 0xad, 0x7b, 0xc6, 0x3c, 0x15, 0x9e, 0x16, 0xfd, 0x0b, 0x97, 0x2f, 0x26, 0xbd, 0x18, - 0x98, 0xb9, 0xc9, 0x30, 0x13, 0x5c, 0x35, 0xf2, 0x58, 0xf2, 0x1d, 0xfa, 0xc0, 0x00, 0xf8, 0x7c, - 0x3c, 0x7c, 0x3c, 0x3e, 0x0f, 0xd7, 0x8e, 0xa9, 0xa6, 0x97, 0x6d, 0x65, 0x72, 0x19, 0x55, 0x5c, - 0x00, 0x00, 0x4a, 0xaa, 0xdf, 0xc3, 0xea, 0xc1, 0x91, 0xcc, 0x7b, 0x65, 0x32, 0xc1, 0xdf, 0x7c, - 0x26, 0xcf, 0xc7, 0xcc, 0x1c, 0x96, 0x4c, 0x19, 0xaa, 0x8e, 0x4b, 0xed, 0x33, 0xf8, 0x71, 0xfe, - 0xe8, 0x69, 0xbf, 0x44, 0x25, 0x77, 0x34, 0xe9, 0x85, 0xfc, 0xa4, 0xfb, 0xef, 0xd2, 0xaf, 0xe5, - 0x2e, 0xcb, 0xe8, 0x6f, 0x56, 0x61, 0xa8, 0x92, 0xa7, 0x6d, 0x0f, 0xd5, 0x4b, 0xc9, 0x7b, 0x9a, - 0x1d, 0x09, 0x73, 0x8f, 0x2f, 0x3d, 0xed, 0x1f, 0xf2, 0xad, 0xfc, 0x4a, 0x1e, 0x13, 0x00, 0x3a, - 0x92, 0x23, 0xce, 0x82, 0xa6, 0xca, 0xce, 0xef, 0x49, 0xb9, 0x0c, 0x13, 0x96, 0x63, 0x95, 0x58, - 0xf8, 0x90, 0xde, 0xc3, 0xc1, 0xe1, 0xe1, 0xc0, 0xf8, 0x78, 0x39, 0xde, 0x61, 0xf3, 0xcc, 0x93, - 0xc6, 0x97, 0x6d, 0x65, 0x72, 0x09, 0x55, 0x5c, 0x00, 0x00, 0x04, 0x64, 0xc2, 0x65, 0xa5, 0x9b, - 0x1b, 0xf5, 0x1e, 0x7c, 0x69, 0x02, 0x66, 0x02, 0xf5, 0x67, 0x3d, 0x74, 0xc1, 0x94, 0x28, 0x45, - 0xee, 0xf2, 0x61, 0xd7, 0x6c, 0x4f, 0xc3, 0xf7, 0xf6, 0x7c, 0x0a, 0xf2, 0xe1, 0xad, 0x80, 0xab, - 0x29, 0xb5, 0xb6, 0x0e, 0x9c, 0xc8, 0xb9, 0x73, 0xa3, 0xa4, 0x9b, 0x08, 0x78, 0x46, 0x33, 0x05, - 0x59, 0x73, 0x38, 0x7e, 0x53, 0x82, 0xab, 0xb4, 0xd8, 0x3e, 0xc0, 0xd0, 0xf4, 0x6f, 0xf1, 0x37, - 0xbc, 0x62, 0xfb, 0xf8, 0x14, 0x2f, 0x8f, 0xc0, 0xf5, 0xdc, 0xb0, 0x69, 0x43, 0x1e, 0x1f, 0x70, - 0x33, 0xad, 0xd1, 0x5e, 0xd1, 0x5a, 0x2b, 0xfb, 0xff, 0x2c, 0x90, 0x03, 0x8f, 0x31, 0xce, 0x1f, - 0x07, 0xc1, 0xf8, 0x70, 0xee, 0x79, 0xe1, 0x77, 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x55, 0x5c, - 0x00, 0x00, 0x51, 0xd6, 0xd8, 0xe3, 0xc4, 0x8c, 0x8e, 0x67, 0xea, 0x5f, 0xa8, 0xf3, 0x29, 0x5f, - 0x08, 0x8d, 0x93, 0x99, 0x5e, 0x36, 0xe5, 0x76, 0x06, 0x6a, 0x30, 0xa4, 0x32, 0x32, 0xfc, 0xce, - 0xab, 0x13, 0x89, 0xa5, 0xe1, 0x82, 0xfb, 0xd5, 0x65, 0x45, 0xa6, 0x17, 0x87, 0x51, 0xbc, 0x8a, - 0xce, 0x5a, 0xf2, 0x1a, 0xba, 0x33, 0xf1, 0x3c, 0x75, 0x96, 0x66, 0xe7, 0x9c, 0x47, 0xa8, 0x75, - 0xc4, 0xb0, 0x6c, 0x56, 0x50, 0xcf, 0xe9, 0xa7, 0xdf, 0x0d, 0xf0, 0xf8, 0x41, 0x91, 0xfe, 0x21, - 0x76, 0x2c, 0xb4, 0x59, 0x22, 0x27, 0x1f, 0x33, 0x15, 0xdd, 0x33, 0xb4, 0xf6, 0x0d, 0xb1, 0x1f, - 0x64, 0x94, 0x6f, 0x8c, 0x63, 0x87, 0x0f, 0x0f, 0x87, 0xc1, 0xe0, 0x61, 0x85, 0xde, 0x1b, 0x23, - 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x55, 0x64, 0xaf, 0xde, 0xaf, 0x87, 0x46, 0xfd, 0x1e, 0xf4, - 0xe9, 0x93, 0x89, 0xda, 0x9f, 0xac, 0x1b, 0x3a, 0x4c, 0x26, 0x6c, 0x39, 0x5b, 0x6d, 0xe6, 0x29, - 0xdb, 0x44, 0x8c, 0xe6, 0x6c, 0x78, 0x88, 0xac, 0x59, 0xea, 0xdf, 0x09, 0xef, 0x2a, 0x0c, 0x2f, - 0x2e, 0x58, 0x29, 0x55, 0xbf, 0xa4, 0xa5, 0xdc, 0xc4, 0x26, 0xde, 0x68, 0xa1, 0x2c, 0x20, 0x26, - 0xa9, 0xa6, 0xe2, 0x39, 0x2c, 0xd9, 0x0e, 0xfb, 0xb4, 0x3e, 0x3d, 0x57, 0xb4, 0xb4, 0xd7, 0xcc, - 0x19, 0x89, 0x27, 0x7d, 0xfb, 0xaa, 0x2e, 0x9c, 0x63, 0x57, 0x49, 0x39, 0x88, 0xcb, 0xb4, 0xca, - 0x52, 0x0e, 0x56, 0xea, 0xfc, 0x78, 0xfe, 0x6b, 0x73, 0xff, 0x04, 0xf1, 0xc3, 0x8f, 0x87, 0xc3, - 0xe0, 0xfb, 0x46, 0x92, 0xf0, 0x9d, 0xc8, 0xec, 0xa4, 0x4f, 0xee, 0x21, 0x72, 0x19, 0x25, 0x54, - 0x38, 0x63, 0x03, 0x45, 0x3f, 0x0d, 0x4f, 0x28, 0xdb, 0x46, 0xb1, 0x7d, 0xf8, 0x2a, 0xbb, 0xb6, - 0x9f, 0xa9, 0x15, 0xb0, 0xb3, 0x12, 0x6b, 0xe8, 0xe5, 0x1e, 0x74, 0x70, 0x91, 0x13, 0x34, 0x4d, - 0x4a, 0xb8, 0x7b, 0xe6, 0x6d, 0xfe, 0x85, 0x4e, 0xba, 0xac, 0x12, 0xff, 0x58, 0x16, 0x10, 0xc1, - 0x70, 0x7e, 0x89, 0xb4, 0x84, 0x21, 0xc7, 0x7a, 0x35, 0x56, 0x2e, 0x6a, 0x02, 0xb0, 0xa0, 0x10, - 0x49, 0x33, 0xd6, 0x57, 0x4b, 0x4a, 0x66, 0xcb, 0x3b, 0x00, 0xdc, 0xeb, 0x5f, 0x41, 0xdc, 0x40, - 0x3b, 0x3f, 0xa4, 0xf9, 0x56, 0x0c, 0x33, 0xa2, 0x2f, 0x1c, 0x8a, 0x42, 0x54, 0xae, 0xf7, 0xbb, - 0xf1, 0x2b, 0xcb, 0x91, 0x95, 0xa0, 0xf4, 0x1e, 0x19, 0xc2, 0x10, 0xe7, 0x18, 0x70, 0xfb, 0x88, - 0xa6, 0x97, 0x6d, 0x65, 0x72, 0x29, 0x35, 0x64, 0xaf, 0xdd, 0x47, 0x5d, 0x46, 0xc5, 0xfd, 0x81, - 0x82, 0x41, 0x59, 0xad, 0x3b, 0x24, 0x2f, 0x86, 0x49, 0x9b, 0xfb, 0x82, 0xb6, 0xdf, 0xf1, 0x54, - 0x52, 0xca, 0x10, 0xfd, 0x91, 0x73, 0x58, 0xbc, 0xb4, 0x47, 0x3f, 0xb9, 0x2f, 0xe5, 0x54, 0x1f, - 0xcf, 0x61, 0x2e, 0xba, 0xd3, 0x78, 0x64, 0x12, 0xb2, 0xdc, 0x19, 0xa7, 0x89, 0xd3, 0x00, 0x56, - 0x61, 0x09, 0x75, 0x8b, 0x0f, 0xa7, 0xa1, 0xdc, 0xd0, 0x15, 0xe5, 0xf5, 0x8c, 0x75, 0x21, 0x41, - 0x82, 0x9e, 0x49, 0xf0, 0xb2, 0xd8, 0xf3, 0x28, 0xf0, 0x5e, 0x11, 0x39, 0x88, 0x2e, 0xfe, 0x2f, - 0xb7, 0x8e, 0xd2, 0x1e, 0x93, 0xf1, 0x00, 0x27, 0x3a, 0x98, 0x72, 0x3e, 0x1c, 0x70, 0xc7, 0xc7, - 0x83, 0x81, 0xc8, 0xd3, 0x62, 0x23, 0x32, 0x26, 0xa4, 0x4f, 0xee, 0x21, 0x72, 0x19, 0x35, 0x6c, - 0x00, 0x06, 0x98, 0x1d, 0x78, 0x1c, 0x4f, 0xae, 0x3c, 0x0b, 0xfd, 0x61, 0x38, 0x3e, 0x2f, 0x10, - 0x1b, 0x48, 0x6c, 0x3e, 0x43, 0x08, 0x25, 0x07, 0xa7, 0xb0, 0x4f, 0x1b, 0xa4, 0xca, 0x9d, 0x68, - 0xd0, 0x2a, 0x22, 0x3e, 0x04, 0xd4, 0xe6, 0x76, 0x8c, 0xac, 0x74, 0xdb, 0x71, 0x53, 0xe8, 0x71, - 0xc9, 0x0d, 0x24, 0xb5, 0x27, 0xe4, 0xaa, 0xb5, 0xc3, 0x7f, 0xf6, 0x52, 0x81, 0xaf, 0x30, 0xf0, - 0xe6, 0x88, 0x65, 0xa9, 0xf4, 0x6a, 0x7d, 0xb6, 0x06, 0x87, 0xc4, 0x6c, 0x1a, 0x71, 0x0b, 0x20, - 0x60, 0x82, 0x24, 0xe2, 0x57, 0x3d, 0x6d, 0x5e, 0xbe, 0x37, 0xab, 0xa1, 0xa7, 0x37, 0xf7, 0x3d, - 0x5e, 0x80, 0x1c, 0xc6, 0x0c, 0x1c, 0x1c, 0x3e, 0x07, 0xc3, 0xe1, 0xe1, 0xe7, 0x36, 0xa6, 0x50, - 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x45, 0x64, 0xb0, 0xd2, 0xbf, 0xf9, 0x4d, 0xc8, 0xe1, 0x95, - 0x22, 0x86, 0x89, 0x6c, 0x3a, 0xdb, 0x05, 0x25, 0xcd, 0x73, 0x92, 0xe3, 0x20, 0xdd, 0x46, 0xff, - 0x1b, 0xb2, 0x0b, 0xc3, 0x29, 0x0b, 0xf2, 0x78, 0x08, 0xca, 0x9b, 0xfe, 0xd5, 0x80, 0xc4, 0xfc, - 0x56, 0xb7, 0xcf, 0x1e, 0x15, 0xd5, 0xab, 0x9b, 0x18, 0x7a, 0xa8, 0xcb, 0x92, 0x08, 0x39, 0x55, - 0xc6, 0x5b, 0xa6, 0xa4, 0x23, 0x76, 0x1f, 0xaa, 0xdf, 0x5c, 0xe6, 0x90, 0x38, 0xbc, 0x65, 0x6d, - 0xe8, 0x92, 0x37, 0x8c, 0x0c, 0x04, 0xec, 0x5b, 0x52, 0xce, 0x90, 0x10, 0x84, 0x3a, 0x32, 0x7a, - 0x2d, 0xdd, 0x6a, 0xed, 0x0d, 0xe2, 0xf7, 0xba, 0xbc, 0xe3, 0xce, 0x48, 0x8e, 0x38, 0x70, 0xf0, - 0xf8, 0xf0, 0x78, 0x3e, 0x65, 0x58, 0x92, 0x1e, 0xa4, 0x4f, 0xee, 0x21, 0x72, 0x19, 0x45, 0x6c, - 0x04, 0x80, 0xe4, 0x10, 0x35, 0x6d, 0x65, 0x13, 0x4b, 0xc1, 0x05, 0x47, 0x8f, 0x67, 0xa9, 0x43, - 0x6e, 0x6a, 0x3f, 0x3b, 0xa7, 0x8f, 0x82, 0xad, 0x0e, 0x6b, 0x96, 0xfe, 0xb4, 0xe7, 0x35, 0x3a, - 0x23, 0x38, 0xbf, 0x16, 0x7a, 0xea, 0x0d, 0x55, 0x7d, 0x79, 0x89, 0x69, 0xb4, 0xd4, 0x93, 0xae, - 0xfe, 0xb4, 0xed, 0x25, 0xcc, 0x22, 0xd7, 0x89, 0xf6, 0xbf, 0xff, 0x87, 0x81, 0xf5, 0xf3, 0xe3, - 0xca, 0x90, 0xb8, 0xf0, 0xc8, 0xcc, 0x49, 0x36, 0x60, 0x54, 0x98, 0x6f, 0x16, 0xeb, 0xc7, 0x5e, - 0xc1, 0x49, 0x30, 0xea, 0x12, 0xdd, 0xfa, 0x44, 0x78, 0xa4, 0xe0, 0x42, 0xc3, 0xd7, 0xcb, 0x7b, - 0x55, 0x86, 0x43, 0xb8, 0xe3, 0xcc, 0x78, 0xf0, 0x3e, 0x1e, 0x63, 0x8c, 0x78, 0xe0, 0x8a, 0x73, - 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x35, 0x74, 0x00, 0x00, 0x24, 0x08, 0x30, 0xb0, 0xd7, 0x30, - 0xa7, 0x09, 0xff, 0xd2, 0x36, 0x01, 0x9a, 0x80, 0xe8, 0x35, 0x7b, 0xa9, 0x39, 0xe9, 0x64, 0x79, - 0x72, 0x11, 0xe1, 0xc1, 0x58, 0x57, 0xc1, 0x5a, 0x8d, 0xe9, 0x3e, 0x51, 0x42, 0x9a, 0x7a, 0x76, - 0x1f, 0x1b, 0xbb, 0x9f, 0xd4, 0xa3, 0x80, 0x9d, 0xc9, 0x76, 0x9f, 0xef, 0x19, 0x52, 0xd6, 0xd9, - 0x65, 0x25, 0x59, 0x40, 0x8c, 0x26, 0x72, 0x99, 0x0b, 0xb4, 0x85, 0x4f, 0xa1, 0xd9, 0x98, 0x08, - 0x9d, 0xb0, 0xf7, 0x9d, 0xd1, 0x7c, 0x16, 0xf2, 0x54, 0x61, 0xab, 0x18, 0xf9, 0xbe, 0x9f, 0xa6, - 0x64, 0x3d, 0x79, 0x71, 0x20, 0xf1, 0x9d, 0x2f, 0xfb, 0x1f, 0xd1, 0xe7, 0x83, 0xe1, 0xfc, 0x0e, - 0x3e, 0x38, 0xdf, 0x46, 0x78, 0x7e, 0x34, 0x98, 0xc2, 0x08, 0x6e, 0xe5, 0x72, 0x09, 0x25, 0x74, - 0x00, 0x00, 0x28, 0x94, 0x58, 0x2b, 0x0d, 0xc2, 0x12, 0xc0, 0x7b, 0x14, 0x6d, 0xe5, 0x12, 0xfc, - 0x91, 0xd4, 0x8e, 0xe4, 0x6f, 0x2b, 0x95, 0xe0, 0xc6, 0xa3, 0x98, 0xee, 0x3a, 0x76, 0x26, 0x2b, - 0xaa, 0xea, 0x23, 0x52, 0xc9, 0xab, 0xb5, 0x86, 0x09, 0xf3, 0xbc, 0x38, 0x9e, 0xef, 0x63, 0x58, - 0xbc, 0x23, 0xbf, 0x52, 0xa0, 0x5c, 0x8f, 0x69, 0x25, 0x1b, 0x8f, 0x66, 0xa2, 0xb1, 0x27, 0x91, - 0x74, 0x3c, 0x6f, 0xf6, 0x7a, 0x8c, 0x50, 0x78, 0x6e, 0x13, 0xc6, 0x9c, 0xf9, 0x15, 0x1f, 0x44, - 0x22, 0x20, 0x60, 0x7a, 0xdd, 0xa0, 0x61, 0xc5, 0xe2, 0x41, 0x59, 0x0f, 0xbd, 0xb3, 0xf1, 0xe6, - 0xfe, 0x90, 0x70, 0x1f, 0x38, 0xf8, 0xfc, 0x0e, 0x07, 0x87, 0x9e, 0x7c, 0x58, 0x27, 0x8f, 0x33, - 0xa2, 0x08, 0x6e, 0xe5, 0x72, 0x09, 0x45, 0x74, 0x00, 0x00, 0x38, 0x24, 0x7a, 0xaa, 0xf1, 0xb5, - 0x93, 0x2d, 0x8b, 0xb4, 0xcd, 0x51, 0xd9, 0xd4, 0xdc, 0xad, 0x05, 0x18, 0x07, 0x9a, 0xf3, 0xe7, - 0x1a, 0x15, 0x02, 0xa7, 0x1d, 0xbf, 0x22, 0xb7, 0xc3, 0xee, 0x54, 0x97, 0x93, 0x2c, 0x33, 0x01, - 0x4c, 0xcb, 0x7d, 0x8c, 0xc7, 0x38, 0xdd, 0xbe, 0x57, 0xe4, 0x12, 0x88, 0xe7, 0x6b, 0x2c, 0x3f, - 0xbf, 0x56, 0x90, 0x87, 0x0c, 0x6f, 0x2e, 0xd4, 0xf5, 0x59, 0xfc, 0xcd, 0xb0, 0x1f, 0xdc, 0x58, - 0xfa, 0xba, 0x30, 0x0f, 0xf7, 0x99, 0x1e, 0x42, 0xed, 0xd7, 0xde, 0x15, 0x5c, 0xc1, 0x82, 0xc5, - 0xd2, 0x2d, 0x18, 0x12, 0xda, 0x95, 0x58, 0xfd, 0xf6, 0xda, 0x0d, 0x24, 0x30, 0xf8, 0x1f, 0x07, - 0xf0, 0x71, 0xce, 0x2b, 0x10, 0x77, 0xe9, 0x61, 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x45, 0x7c, - 0x00, 0xc0, 0x4e, 0x5d, 0x55, 0x18, 0x8a, 0x1b, 0xf9, 0x01, 0xef, 0x8a, 0x03, 0xaf, 0x2f, 0xd8, - 0x1d, 0x02, 0xe6, 0xea, 0xa5, 0xf5, 0xca, 0x93, 0xcd, 0x94, 0xbe, 0x68, 0xd0, 0xc2, 0x1f, 0x14, - 0x83, 0x9c, 0x9d, 0xb4, 0x54, 0xa8, 0x9e, 0x0f, 0x85, 0x55, 0x2a, 0x75, 0x8f, 0x2b, 0x9f, 0x82, - 0xbd, 0xcc, 0x06, 0xf2, 0x15, 0x20, 0x9e, 0xe7, 0xc5, 0x36, 0xc4, 0x95, 0x17, 0x24, 0xdf, 0x79, - 0x82, 0x8f, 0x97, 0xcf, 0xff, 0xf0, 0xc2, 0x26, 0x8c, 0x44, 0xb7, 0xe0, 0x90, 0x9c, 0xd9, 0xd4, - 0xa3, 0x46, 0x12, 0x28, 0x35, 0x50, 0xaf, 0x87, 0x54, 0x78, 0x46, 0x68, 0x96, 0x47, 0x5d, 0x61, - 0xc9, 0x60, 0x3c, 0x31, 0x3c, 0x2f, 0x83, 0xe1, 0xf0, 0x65, 0xe1, 0xec, 0x6d, 0xfd, 0xcc, 0x16, - 0xa4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x35, 0x74, 0x00, 0x00, 0x52, 0x04, 0x91, 0x6d, 0x5c, 0xf3, - 0x05, 0x5a, 0x7a, 0xa2, 0xe9, 0x6b, 0xde, 0x98, 0xb1, 0x08, 0xe1, 0x5c, 0x6d, 0xa1, 0xd8, 0x20, - 0xeb, 0x51, 0xe3, 0x8d, 0x00, 0x0d, 0xcd, 0x57, 0x77, 0x2a, 0x3d, 0xe2, 0x05, 0x92, 0x5e, 0xce, - 0x33, 0x58, 0x77, 0x06, 0x6c, 0x72, 0x3e, 0xbb, 0xbd, 0x8f, 0x57, 0x06, 0x05, 0x05, 0xe4, 0x54, - 0xed, 0x6a, 0x8b, 0xc1, 0x08, 0x90, 0x16, 0x09, 0xfa, 0xd0, 0x4f, 0xa6, 0x17, 0xcf, 0x43, 0x1f, - 0xa4, 0xf4, 0x91, 0xff, 0x43, 0x30, 0x3f, 0x55, 0xce, 0x77, 0xe1, 0xed, 0x08, 0xeb, 0xa6, 0xfa, - 0xd0, 0xea, 0x8f, 0x4b, 0xe1, 0x85, 0x08, 0x35, 0x3c, 0x00, 0xfc, 0x73, 0xb8, 0x87, 0x87, 0x03, - 0x83, 0xc7, 0x3c, 0xe7, 0xe5, 0x39, 0x13, 0x9a, 0xa4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x25, 0x74, - 0x00, 0x01, 0x69, 0x46, 0xb4, 0x9f, 0x19, 0x25, 0xfe, 0x51, 0x09, 0xe7, 0x36, 0x89, 0x73, 0xd8, - 0x2c, 0x7a, 0xee, 0x1e, 0xe9, 0xb5, 0x26, 0x4f, 0x67, 0x8d, 0xdb, 0xc3, 0x40, 0xe2, 0x4c, 0x9e, - 0x4d, 0x52, 0x0e, 0xfb, 0xae, 0x34, 0x4a, 0xbf, 0x58, 0xe6, 0xf5, 0xb4, 0x4c, 0xc2, 0xca, 0xd1, - 0xd9, 0xb9, 0x98, 0x6b, 0x5f, 0x35, 0x68, 0x2d, 0xc7, 0x4a, 0x92, 0xf3, 0x4b, 0x3f, 0x36, 0x3f, - 0x49, 0xfa, 0x0d, 0xff, 0x91, 0xb6, 0x06, 0x18, 0xa6, 0xea, 0x41, 0xdf, 0x3d, 0xc2, 0x2f, 0xa8, - 0x36, 0x52, 0xb9, 0xc0, 0x73, 0x29, 0x0c, 0xc8, 0xef, 0x3c, 0x32, 0x65, 0xb0, 0x1d, 0x02, 0x03, - 0xb0, 0xca, 0x8f, 0xbe, 0x83, 0x07, 0x87, 0x8e, 0x0f, 0x87, 0xe7, 0x19, 0x8d, 0x9b, 0x52, 0xe3, - 0xc4, 0x4f, 0xee, 0x21, 0x72, 0x09, 0x35, 0x7c, 0x04, 0x81, 0xd0, 0x1a, 0x52, 0x2c, 0x52, 0x15, - 0x28, 0x18, 0x3e, 0xd7, 0x70, 0x05, 0x04, 0xa9, 0xc1, 0x9b, 0xb0, 0xac, 0xd4, 0xab, 0x23, 0xda, - 0xa1, 0xbf, 0x91, 0x8a, 0xc0, 0x58, 0x6f, 0x58, 0x08, 0x9c, 0x0f, 0x00, 0xb7, 0xba, 0xd9, 0x54, - 0x84, 0x13, 0x18, 0xa9, 0xfc, 0x95, 0x18, 0x31, 0x7e, 0x3e, 0xb6, 0xdd, 0x4d, 0xac, 0xac, 0x07, - 0x61, 0xb3, 0x5f, 0x30, 0x24, 0x40, 0x83, 0x77, 0xf7, 0x94, 0x7d, 0x0b, 0xbb, 0x57, 0x86, 0xf5, - 0x0a, 0x83, 0xd3, 0x34, 0xe2, 0xcf, 0xd3, 0x8d, 0xe0, 0x66, 0x8f, 0x79, 0xc9, 0xfa, 0x5e, 0x51, - 0x59, 0x50, 0xda, 0x57, 0xcb, 0x54, 0x04, 0xf3, 0x2b, 0x01, 0xd1, 0x9c, 0x63, 0xc1, 0xe0, 0x7c, - 0x3e, 0x10, 0x32, 0x14, 0x1f, 0x1e, 0x60, 0xe4, 0xc4, 0x50, 0x05, 0x21, 0x72, 0x09, 0x15, 0x74, - 0x00, 0x00, 0x02, 0x2c, 0x30, 0x2e, 0x0d, 0x66, 0x68, 0xc2, 0xbc, 0x54, 0x27, 0x50, 0xab, 0x11, - 0x04, 0x84, 0x49, 0x68, 0xc5, 0x34, 0xb3, 0x54, 0x0e, 0x16, 0x86, 0xe7, 0x6c, 0xfb, 0x63, 0x9d, - 0xc3, 0xdc, 0x24, 0x10, 0x63, 0xce, 0xe9, 0x24, 0x92, 0x48, 0xf3, 0x98, 0x79, 0x67, 0x8a, 0xe4, - 0x9f, 0x97, 0x0b, 0x0f, 0xce, 0x76, 0x31, 0x14, 0x68, 0xed, 0xe7, 0xd9, 0xe6, 0x48, 0xbb, 0x56, - 0x45, 0x9e, 0x5a, 0xd6, 0x6e, 0xea, 0xa5, 0xdf, 0x8e, 0x6a, 0x49, 0xcd, 0xe9, 0xf3, 0x27, 0x5d, - 0xdd, 0xe3, 0x56, 0x6d, 0xa0, 0xc1, 0xa8, 0xcb, 0xcb, 0xdb, 0xb1, 0xec, 0x15, 0x06, 0x00, 0x27, - 0x33, 0xe1, 0x87, 0x87, 0x87, 0xc0, 0xf8, 0x7c, 0x1c, 0x3e, 0x1e, 0x38, 0x7c, 0x78, 0xf5, 0x9c, - 0xc4, 0x50, 0x05, 0x21, 0x72, 0x09, 0x45, 0x7c, 0x00, 0xc0, 0x5f, 0xe9, 0x53, 0x55, 0x61, 0x1d, - 0x48, 0xa7, 0xe6, 0xdf, 0xa3, 0x82, 0xa9, 0x07, 0x81, 0x70, 0x8f, 0x20, 0x75, 0xa6, 0x79, 0x46, - 0xe0, 0x77, 0x1c, 0x5f, 0x7e, 0xee, 0x1d, 0x9f, 0x64, 0x15, 0x34, 0x3e, 0xc5, 0xb1, 0x96, 0x5e, - 0x00, 0x9d, 0x21, 0xb2, 0x6d, 0x52, 0x2d, 0x5a, 0xdc, 0xb9, 0x9d, 0x1d, 0x10, 0xe3, 0x49, 0x5f, - 0xe1, 0xec, 0x9b, 0x12, 0x17, 0x55, 0x03, 0x26, 0x94, 0x27, 0xfb, 0xfd, 0x20, 0x50, 0xba, 0x96, - 0x12, 0x45, 0x19, 0x36, 0xcf, 0xdf, 0xfe, 0xc1, 0xcb, 0xc7, 0x4d, 0x49, 0x20, 0x18, 0xc8, 0x89, - 0xa4, 0x28, 0xbe, 0x84, 0xf4, 0xa5, 0x1d, 0x85, 0x1d, 0x92, 0x05, 0xb2, 0x10, 0x66, 0x70, 0xf8, - 0xf8, 0x7e, 0x3e, 0x39, 0xb2, 0x3b, 0xc9, 0xee, 0xa4, 0x65, 0x4a, 0x41, 0x72, 0x09, 0x45, 0x8c, - 0x00, 0x00, 0x4e, 0x3f, 0xf7, 0x13, 0x0a, 0x6b, 0x85, 0xc9, 0x41, 0x44, 0x68, 0x48, 0xe7, 0xbc, - 0xe6, 0x89, 0xc2, 0x30, 0xef, 0x98, 0x65, 0x30, 0x2b, 0xbb, 0x35, 0x35, 0xe5, 0xa5, 0xa6, 0xe6, - 0x74, 0xc2, 0xa8, 0x66, 0xbe, 0x85, 0x22, 0x64, 0x7f, 0xcb, 0x2d, 0xf8, 0xbb, 0xa2, 0x14, 0x8a, - 0x19, 0x37, 0x4d, 0x10, 0x0e, 0x00, 0x01, 0x79, 0x71, 0x7f, 0x48, 0x69, 0x7c, 0x3e, 0x92, 0xe6, - 0xca, 0x0b, 0x90, 0x93, 0xab, 0x94, 0x3e, 0xec, 0x3f, 0xe1, 0x78, 0xec, 0x89, 0x28, 0x05, 0xb2, - 0x58, 0x45, 0x56, 0x43, 0xe9, 0x03, 0xfa, 0x01, 0x24, 0xc2, 0xf7, 0xc4, 0x85, 0x52, 0x15, 0xcc, - 0x86, 0x2f, 0x39, 0x8e, 0x60, 0x83, 0xc7, 0xc3, 0xc7, 0xc1, 0xdf, 0x4b, 0x5a, 0x28, 0xdf, 0xac, - 0xc4, 0x65, 0x4a, 0x41, 0x72, 0x09, 0x15, 0x94, 0x00, 0x00, 0x03, 0x61, 0x03, 0x38, 0x9c, 0x15, - 0xe6, 0xba, 0x02, 0x23, 0x84, 0x2e, 0x4f, 0xb2, 0x5d, 0xd6, 0xa6, 0x86, 0xfa, 0x03, 0xdf, 0xe8, - 0xcf, 0x2a, 0x3f, 0x94, 0x7e, 0xd1, 0x30, 0x53, 0x7f, 0x9d, 0x03, 0x54, 0x70, 0x77, 0xa7, 0x48, - 0xa3, 0x59, 0xb1, 0xd3, 0xea, 0x06, 0x82, 0x64, 0x53, 0x05, 0x0e, 0x81, 0xff, 0xd4, 0x57, 0x4c, - 0xd4, 0x0e, 0x2c, 0xfb, 0xd6, 0x8f, 0x35, 0x01, 0x01, 0x6b, 0x12, 0x21, 0xe7, 0x18, 0x15, 0x88, - 0xdd, 0xe2, 0x91, 0x24, 0x7e, 0x0f, 0xa2, 0x11, 0x45, 0x01, 0xfa, 0xa1, 0x45, 0xf9, 0xb4, 0x6f, - 0x70, 0xd1, 0x7b, 0x94, 0xc2, 0xf3, 0x9a, 0xc0, 0x04, 0x27, 0xc3, 0xe1, 0x8e, 0x0f, 0x0f, 0x80, - 0xe1, 0xc1, 0xc7, 0x0f, 0x18, 0xe5, 0xa2, 0x6d, 0xa6, 0xac, 0xc9, 0x85, 0x72, 0x09, 0x25, 0x94, - 0x00, 0x00, 0x5e, 0x8d, 0x23, 0xf9, 0xfa, 0x0d, 0xf3, 0xfe, 0xe5, 0xec, 0xbb, 0x2a, 0xe6, 0x25, - 0x70, 0x55, 0x07, 0x29, 0x79, 0xeb, 0x07, 0x66, 0x63, 0x76, 0xd7, 0xcc, 0x2d, 0x82, 0xaf, 0x89, - 0xaf, 0x90, 0xd2, 0x22, 0x2f, 0x35, 0x23, 0x84, 0x07, 0x33, 0x70, 0x32, 0x04, 0x75, 0xd5, 0x24, - 0xe6, 0x5d, 0xa8, 0xfa, 0x74, 0x9e, 0x23, 0x77, 0xf0, 0xff, 0xc4, 0xfc, 0xe0, 0x94, 0x37, 0x38, - 0x93, 0x3a, 0xeb, 0xdb, 0x66, 0x7d, 0xe5, 0x69, 0xda, 0x7f, 0x6e, 0x8e, 0xe9, 0xfe, 0xb6, 0x76, - 0xe0, 0x84, 0xe3, 0xc6, 0xe0, 0x0e, 0x10, 0x20, 0xcc, 0x53, 0x94, 0x20, 0xe4, 0x04, 0xf2, 0x9c, - 0xb6, 0xcd, 0x21, 0x86, 0x0f, 0x07, 0xc1, 0xe3, 0xc1, 0xc1, 0xc3, 0x85, 0xb6, 0x64, 0xfa, 0xd7, - 0xc4, 0x65, 0x4a, 0x41, 0x72, 0x09, 0x35, 0x8c, 0x00, 0xc3, 0x2e, 0x07, 0x4d, 0xcf, 0x40, 0xe3, - 0xc4, 0x6a, 0xbd, 0x87, 0xa0, 0x32, 0xc2, 0xf7, 0x32, 0xa2, 0x74, 0xf4, 0x62, 0xeb, 0x64, 0xac, - 0x75, 0x6d, 0x4c, 0xa0, 0x2f, 0xa5, 0xe7, 0x48, 0x75, 0x1b, 0x28, 0x84, 0x57, 0x6f, 0x72, 0x54, - 0x6b, 0xb6, 0x9e, 0xda, 0x48, 0xe3, 0xa9, 0xd6, 0x41, 0xe8, 0xc3, 0x12, 0x16, 0x20, 0x2c, 0x64, - 0xee, 0xad, 0x6c, 0xbb, 0x3e, 0x84, 0xff, 0x19, 0x5e, 0x42, 0xf1, 0x29, 0xc9, 0x67, 0x6d, 0x28, - 0x00, 0x73, 0x62, 0x00, 0x42, 0xdc, 0xc5, 0x6b, 0x46, 0x21, 0x2f, 0x22, 0x4f, 0xf0, 0x2d, 0x7e, - 0x52, 0x78, 0x76, 0x5a, 0x61, 0x99, 0x0f, 0xcf, 0x0f, 0xfa, 0x38, 0x38, 0x3e, 0x1f, 0x03, 0xc3, - 0xf0, 0xfc, 0x0c, 0x1e, 0x13, 0x46, 0x22, 0x8c, 0xc4, 0x65, 0x4a, 0x41, 0x72, 0x09, 0x25, 0x94, - 0x00, 0x00, 0x90, 0x17, 0x7a, 0x70, 0x6b, 0x33, 0xce, 0x57, 0x32, 0x9d, 0x05, 0x11, 0x10, 0xf2, - 0xef, 0x31, 0xe9, 0xcb, 0x2d, 0x86, 0x68, 0xdf, 0xcc, 0x6a, 0x7b, 0x59, 0x33, 0x52, 0x51, 0x0d, - 0xb0, 0xb8, 0x03, 0xe7, 0x91, 0x37, 0xc8, 0xe4, 0xa8, 0xf5, 0x3d, 0x36, 0x19, 0x72, 0xf3, 0xb9, - 0xa8, 0x79, 0xa5, 0x47, 0x52, 0x9a, 0xfd, 0x65, 0x0a, 0x75, 0x49, 0xc3, 0x3c, 0x15, 0xc4, 0x5f, - 0x88, 0x89, 0x96, 0x84, 0xf7, 0x6e, 0xa6, 0xb3, 0x40, 0x8c, 0xb2, 0x90, 0xc1, 0xfc, 0x19, 0x01, - 0xbb, 0xaf, 0xd4, 0xb5, 0x32, 0x48, 0xcf, 0x00, 0x43, 0x21, 0xb6, 0x04, 0xe9, 0x90, 0xc8, 0x60, - 0x4e, 0xdf, 0xd1, 0x8f, 0x07, 0x83, 0xc0, 0x7f, 0x07, 0xe7, 0xf0, 0x7c, 0xe2, 0x26, 0xc3, 0x4f, - 0xa4, 0x65, 0x4a, 0x41, 0x72, 0x09, 0x35, 0x94, 0x04, 0x84, 0x22, 0x81, 0x1a, 0xea, 0x9f, 0x75, - 0xa9, 0x1c, 0xcd, 0x73, 0xa5, 0xe9, 0x4c, 0xf7, 0x7f, 0x57, 0x3a, 0xb0, 0x97, 0xb6, 0x50, 0xf2, - 0x2b, 0x83, 0x69, 0x79, 0xc0, 0xe4, 0x32, 0x57, 0x55, 0xc8, 0x42, 0x07, 0xdf, 0xdd, 0xbc, 0x12, - 0xae, 0x05, 0xac, 0xe3, 0x3c, 0x81, 0x8f, 0x42, 0x43, 0x06, 0xf3, 0x21, 0xcf, 0x0e, 0x95, 0x01, - 0x67, 0x41, 0xb2, 0x9a, 0x64, 0x4a, 0x4b, 0xd7, 0xb1, 0x74, 0xbb, 0x65, 0xde, 0xcf, 0x7c, 0x02, - 0x16, 0x4a, 0x5d, 0xa7, 0xc8, 0xf0, 0x09, 0x9b, 0xac, 0x34, 0xc2, 0x4a, 0x04, 0x0a, 0x3a, 0x0e, - 0x0b, 0x86, 0x92, 0x8e, 0x2f, 0x21, 0xbb, 0xd6, 0x1d, 0x26, 0x61, 0x1f, 0xce, 0x38, 0x7c, 0x1e, - 0x1e, 0x03, 0xe0, 0xe4, 0xab, 0x52, 0x07, 0xcb, 0xa6, 0xac, 0xc9, 0x85, 0x72, 0x09, 0x35, 0x9c, - 0x00, 0x01, 0xf1, 0x6d, 0x83, 0xa1, 0xd4, 0xf4, 0xb9, 0xa8, 0xd9, 0xf0, 0xc3, 0x81, 0x40, 0xa0, - 0x6b, 0x6f, 0x26, 0x29, 0x64, 0x9f, 0x81, 0x6c, 0x01, 0x6c, 0xf4, 0x39, 0xf2, 0x67, 0xdd, 0x4c, - 0xba, 0x3a, 0x89, 0xc6, 0xc3, 0x4d, 0x4b, 0xa5, 0xeb, 0x7e, 0x67, 0xa9, 0x33, 0x30, 0xd9, 0x02, - 0xdc, 0x2a, 0x20, 0x82, 0x64, 0x54, 0x31, 0x43, 0x09, 0x71, 0x50, 0xdb, 0x3e, 0xf8, 0xb5, 0x68, - 0x2c, 0xcc, 0xb6, 0x95, 0xf6, 0x5e, 0x3c, 0x45, 0xea, 0x9c, 0x87, 0xf4, 0x3a, 0x3d, 0x82, 0xdf, - 0x62, 0xd5, 0x42, 0x60, 0x77, 0x0f, 0x85, 0x0d, 0x6d, 0x3a, 0x14, 0xdb, 0xaf, 0x35, 0x39, 0xdd, - 0xf2, 0x67, 0x42, 0x77, 0x38, 0x67, 0x0f, 0x0e, 0x0f, 0x1f, 0x0f, 0x51, 0xcc, 0xb1, 0xe7, 0x60, - 0xa6, 0xac, 0xc9, 0x85, 0x72, 0x09, 0x25, 0x9c, 0x00, 0xc0, 0xb8, 0x4b, 0x99, 0xf0, 0xf2, 0x0c, - 0x2d, 0xf0, 0x4c, 0xc3, 0xaf, 0x13, 0x4e, 0x1f, 0x8c, 0x8a, 0x9a, 0x24, 0xc5, 0x99, 0x9a, 0x91, - 0x95, 0xe2, 0x8f, 0x32, 0x01, 0x82, 0x23, 0x68, 0x4d, 0x79, 0xdf, 0x56, 0x6a, 0xf2, 0xfe, 0x02, - 0xb9, 0x73, 0xf2, 0xb3, 0x30, 0x7e, 0xab, 0xf5, 0x2f, 0x3a, 0x05, 0xdd, 0x4b, 0xae, 0x9b, 0xeb, - 0xd4, 0x5d, 0x97, 0x8f, 0xbd, 0x60, 0xcf, 0xa5, 0x6c, 0x17, 0x1a, 0x06, 0x98, 0x13, 0x12, 0x53, - 0xd3, 0x05, 0x5e, 0xb6, 0x98, 0x44, 0x83, 0x81, 0xef, 0x1c, 0xf6, 0x2a, 0x7c, 0x1d, 0xef, 0x4c, - 0x8e, 0x59, 0xd4, 0x7d, 0x74, 0x40, 0x57, 0x4c, 0x39, 0x04, 0xfc, 0x8f, 0x0f, 0x0c, 0x1e, 0x1f, - 0x08, 0x06, 0x18, 0x7d, 0x7d, 0xe3, 0x23, 0x7c, 0xb4, 0x39, 0x63, 0x0f, 0x72, 0x09, 0x25, 0xa4, - 0x00, 0x08, 0xa1, 0xf9, 0x79, 0xc3, 0x62, 0x17, 0x8c, 0xe5, 0xf8, 0xe3, 0x83, 0x33, 0x49, 0x18, - 0x31, 0x50, 0x6e, 0x27, 0x7f, 0x64, 0x22, 0x71, 0x6f, 0x98, 0x01, 0x0c, 0xb3, 0x86, 0x92, 0xa1, - 0x6b, 0xa3, 0x38, 0x9d, 0xce, 0x85, 0x71, 0x8e, 0x9a, 0x57, 0x44, 0x64, 0x5f, 0x29, 0x86, 0x05, - 0x0b, 0xe7, 0x26, 0x83, 0xb3, 0x90, 0x09, 0x08, 0x08, 0xe4, 0x61, 0xb2, 0x83, 0xd4, 0xda, 0xaf, - 0x82, 0x14, 0xdc, 0xf4, 0x26, 0x77, 0x61, 0xab, 0x7e, 0x3c, 0xed, 0xe6, 0x7c, 0x1c, 0x13, 0x78, - 0x9c, 0xc3, 0xcf, 0x08, 0x0d, 0x37, 0x7c, 0x63, 0x60, 0x33, 0xf1, 0xbd, 0x6b, 0x61, 0x53, 0xf5, - 0x68, 0x70, 0x07, 0xe8, 0x70, 0x78, 0x38, 0x70, 0x7c, 0x31, 0xdd, 0x9e, 0x4b, 0x33, 0xa4, 0x99, - 0xd4, 0x39, 0x63, 0x0f, 0x72, 0x09, 0x35, 0xa4, 0x04, 0x80, 0xd6, 0x01, 0x56, 0x1c, 0x09, 0x80, - 0xce, 0x23, 0x84, 0xbb, 0x48, 0x63, 0x43, 0xdc, 0x0a, 0x0c, 0xfe, 0xc3, 0xdc, 0xd9, 0x96, 0x4e, - 0x52, 0x80, 0x51, 0x35, 0x32, 0xd5, 0x63, 0x95, 0xbb, 0x1a, 0xf1, 0xce, 0xf9, 0x06, 0xa0, 0x19, - 0xb4, 0xf1, 0x24, 0x17, 0xe0, 0x13, 0x36, 0x9f, 0x71, 0x62, 0x96, 0x35, 0x84, 0x6d, 0x6d, 0x53, - 0x54, 0x69, 0xeb, 0x1a, 0x82, 0x11, 0x98, 0x10, 0xce, 0x8c, 0x8f, 0x66, 0xee, 0x30, 0xb6, 0x35, - 0x9b, 0x46, 0x72, 0xb9, 0x0d, 0x30, 0x34, 0xc2, 0x4a, 0xa2, 0x39, 0x5c, 0x0e, 0x3e, 0xe0, 0xe4, - 0x0c, 0x9a, 0xaa, 0xe0, 0xe8, 0x7a, 0x26, 0x2c, 0xc0, 0x41, 0x87, 0x0f, 0x03, 0xf0, 0x3f, 0x83, - 0xd0, 0x7e, 0x0e, 0x39, 0xd2, 0x1e, 0x2d, 0x14, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x35, 0xa4, - 0x3c, 0x03, 0xc7, 0xd2, 0x58, 0x84, 0xd2, 0x42, 0xee, 0x0e, 0xb8, 0x99, 0xe2, 0x91, 0xa5, 0x83, - 0x5e, 0x05, 0x58, 0x22, 0x32, 0xa1, 0x26, 0x54, 0xca, 0x12, 0x19, 0xaa, 0xab, 0xa7, 0xce, 0x8c, - 0x15, 0xdc, 0x68, 0xf3, 0x5b, 0x40, 0x81, 0xa1, 0x68, 0x60, 0x50, 0x52, 0x39, 0x70, 0x02, 0x11, - 0xe9, 0xef, 0x7c, 0x23, 0x6e, 0xdf, 0xf5, 0xea, 0x08, 0x19, 0x4e, 0x87, 0xd7, 0x68, 0x6f, 0x49, - 0xc6, 0xb6, 0x43, 0x9b, 0xa1, 0x66, 0xfd, 0x04, 0x96, 0x38, 0x6d, 0xba, 0xdf, 0xb4, 0xc4, 0x39, - 0xab, 0xbf, 0x6f, 0xa7, 0x12, 0x9d, 0xb9, 0xba, 0x39, 0x9e, 0xba, 0x45, 0x24, 0x22, 0x64, 0xe8, - 0xe2, 0x5e, 0x7f, 0xf0, 0xf1, 0xa1, 0xe1, 0xf4, 0x7a, 0x1e, 0x8e, 0x1c, 0xc7, 0x3c, 0x13, 0xc3, - 0xc2, 0x1d, 0xcb, 0x05, 0x72, 0x29, 0x15, 0xac, 0x00, 0x01, 0x2e, 0x19, 0xf0, 0x63, 0x1c, 0x64, - 0xa4, 0x1a, 0x45, 0xa2, 0x1c, 0xb8, 0x58, 0xab, 0x02, 0x4d, 0xd4, 0xb0, 0x01, 0xd3, 0xd3, 0x49, - 0x3d, 0xbc, 0xcc, 0x10, 0xad, 0xf4, 0xb7, 0xd9, 0x0e, 0xde, 0x14, 0x13, 0x3b, 0xa2, 0x5b, 0xdf, - 0xe7, 0x6a, 0x8a, 0x55, 0x20, 0xf9, 0x25, 0x46, 0x31, 0xd0, 0xbf, 0x71, 0x24, 0x72, 0xcf, 0xc3, - 0x50, 0xa1, 0x1f, 0xff, 0x40, 0x7b, 0x49, 0xc5, 0xea, 0x4f, 0xea, 0x59, 0x34, 0x44, 0x00, 0x5e, - 0x16, 0x0c, 0xa6, 0xa5, 0x7b, 0xc7, 0xd5, 0x39, 0x09, 0xb5, 0xfa, 0x9c, 0x9b, 0x81, 0x04, 0xcd, - 0xda, 0x35, 0xb6, 0x04, 0x44, 0x76, 0x66, 0x10, 0x3b, 0xec, 0xe1, 0xe0, 0x78, 0xf8, 0x1f, 0x81, - 0xe0, 0xfc, 0x33, 0xc4, 0x35, 0x18, 0xc3, 0x35, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x25, 0xac, - 0x69, 0xd4, 0x3b, 0xc2, 0x6e, 0x3b, 0x8f, 0xa9, 0x9b, 0x85, 0x62, 0x7b, 0xa2, 0x8b, 0xf5, 0xb3, - 0x17, 0x37, 0xfa, 0x96, 0x46, 0xb5, 0xfc, 0x72, 0xf6, 0x6c, 0x85, 0xe6, 0xfa, 0x79, 0xb8, 0x97, - 0xab, 0xc6, 0xc8, 0xe1, 0xcc, 0xb6, 0x29, 0x6d, 0x0f, 0xb9, 0x1c, 0xb1, 0xa1, 0xf4, 0x84, 0xe4, - 0x4f, 0x41, 0x17, 0x6b, 0xe7, 0x81, 0xbe, 0x7c, 0x03, 0xed, 0xee, 0xb9, 0xa9, 0xf9, 0xaa, 0x8b, - 0x8b, 0x15, 0x6d, 0x75, 0xe9, 0x03, 0x57, 0x45, 0x2b, 0x8f, 0x8a, 0xf5, 0xa8, 0xa0, 0x32, 0x11, - 0x77, 0x82, 0x15, 0x9f, 0x9a, 0x12, 0x75, 0x2c, 0x79, 0xd6, 0x8f, 0xd8, 0xe4, 0xfa, 0xd4, 0x13, - 0x54, 0xe9, 0x9c, 0x2d, 0x2c, 0x1b, 0x0f, 0xe0, 0xf8, 0x38, 0xd6, 0x66, 0x61, 0x8f, 0xc4, 0x6e, - 0xc2, 0x1d, 0xcb, 0x05, 0x72, 0x29, 0x15, 0xb4, 0x00, 0xc0, 0x66, 0x40, 0x7f, 0x3a, 0x68, 0x22, - 0x23, 0x2d, 0x81, 0xe6, 0x6f, 0x70, 0xf4, 0x3d, 0x5a, 0x5e, 0x8f, 0xd3, 0x0c, 0x36, 0x37, 0xd5, - 0xb5, 0x4f, 0xd7, 0x30, 0x19, 0x34, 0xaf, 0x2d, 0x85, 0xac, 0xf0, 0x7b, 0x7f, 0xd8, 0x91, 0x6b, - 0x11, 0xac, 0x64, 0x61, 0x16, 0x67, 0x73, 0x1b, 0x3e, 0xac, 0x10, 0xc7, 0xef, 0xb0, 0x43, 0xf6, - 0xe5, 0xc4, 0x98, 0x56, 0x21, 0xf7, 0xe8, 0x18, 0xd5, 0x36, 0xa1, 0xff, 0xcd, 0xac, 0xc6, 0xdc, - 0xee, 0xb2, 0xe9, 0xc4, 0xf7, 0xf1, 0xfc, 0x63, 0xce, 0x3e, 0xf6, 0x56, 0x33, 0x17, 0x13, 0x6e, - 0x45, 0x36, 0x95, 0x4e, 0x27, 0x32, 0x34, 0x13, 0x79, 0x8c, 0x38, 0x3c, 0x3e, 0x07, 0xe0, 0xfc, - 0x1c, 0x78, 0xe7, 0xfe, 0xc6, 0x07, 0x7c, 0x03, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x05, 0xb4, - 0x05, 0xc0, 0x97, 0x65, 0xaa, 0xb1, 0xdb, 0x33, 0x1d, 0x8f, 0x3e, 0xde, 0x42, 0x98, 0x77, 0xbf, - 0xd4, 0xf9, 0x31, 0x08, 0x0c, 0x22, 0x12, 0xef, 0x7b, 0xe4, 0x87, 0x47, 0xf9, 0xda, 0x34, 0x83, - 0x46, 0x0c, 0x01, 0x06, 0xd9, 0x6d, 0xdd, 0xe9, 0x38, 0xb9, 0xd1, 0xf4, 0xcf, 0xb6, 0xa7, 0xdb, - 0xd7, 0x4b, 0x67, 0x23, 0xad, 0xb8, 0x45, 0x03, 0x3c, 0xd2, 0xf6, 0x6b, 0xc8, 0x25, 0x8d, 0x1e, - 0xca, 0x4e, 0x48, 0x15, 0xa5, 0x4d, 0xa6, 0x00, 0xf5, 0xd3, 0x5d, 0xa0, 0xfe, 0x05, 0xde, 0x77, - 0x7c, 0xfc, 0x60, 0xd6, 0x42, 0x5c, 0xf0, 0xa0, 0x41, 0x14, 0x95, 0x5a, 0x5d, 0x0e, 0xa6, 0xb1, - 0xc4, 0xe0, 0x07, 0x07, 0x80, 0xf8, 0x78, 0x1f, 0x07, 0x03, 0x81, 0xe7, 0xa4, 0x6e, 0x3b, 0x16, - 0x82, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x15, 0xac, 0x04, 0x8e, 0x7b, 0x4b, 0x56, 0xca, 0x47, 0xa0, - 0x1d, 0xcf, 0x25, 0x47, 0x3c, 0xe5, 0x19, 0x82, 0x38, 0xb7, 0xdb, 0x0f, 0x0d, 0xb5, 0x0e, 0xd5, - 0x16, 0x2a, 0x45, 0xd5, 0xcc, 0xa2, 0xee, 0xa8, 0xf6, 0xad, 0xc8, 0xbc, 0x52, 0x85, 0x3c, 0x3e, - 0x63, 0x9a, 0x3d, 0xe8, 0xf3, 0x33, 0x53, 0xe7, 0x84, 0xa8, 0x16, 0x3b, 0x22, 0xf5, 0x94, 0xd1, - 0x4c, 0xf7, 0x03, 0x0d, 0xd4, 0xb4, 0x32, 0x59, 0xc9, 0xdb, 0x48, 0x6b, 0xdd, 0x03, 0xd4, 0xcc, - 0xff, 0xb7, 0xa7, 0x97, 0x1d, 0x83, 0x14, 0x3c, 0x0c, 0x4a, 0xc6, 0x1c, 0xa0, 0x3a, 0xd4, 0xbb, - 0x13, 0xa7, 0xd6, 0xd6, 0x44, 0x48, 0x4f, 0x79, 0xf8, 0xf0, 0x7c, 0x1f, 0xa0, 0x79, 0x01, 0xfc, - 0x83, 0xe3, 0x62, 0x37, 0x13, 0x8c, 0x90, 0x47, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x05, 0xac, - 0x00, 0x01, 0x26, 0xf7, 0x02, 0x45, 0xe6, 0xe1, 0xc8, 0xab, 0xbc, 0x2d, 0x72, 0xbb, 0x90, 0xb5, - 0xde, 0x32, 0xbe, 0x60, 0x37, 0x82, 0x31, 0x31, 0x2a, 0x9b, 0x18, 0xca, 0x48, 0xf0, 0xb5, 0xa7, - 0x46, 0x73, 0x53, 0x97, 0x83, 0xc4, 0x73, 0xaf, 0xf6, 0xd0, 0x9a, 0x01, 0xf1, 0x90, 0x4a, 0xb0, - 0x29, 0x00, 0x0f, 0x84, 0xc0, 0x91, 0x07, 0x0f, 0x66, 0x06, 0x55, 0x79, 0x81, 0x03, 0xd8, 0x2b, - 0xbf, 0xce, 0xaf, 0x58, 0x00, 0x5d, 0xa3, 0x51, 0x10, 0x01, 0x67, 0x83, 0x8c, 0xc8, 0x52, 0x71, - 0x2c, 0x72, 0x07, 0x0e, 0xc5, 0xb4, 0x70, 0xf2, 0x3a, 0x97, 0x84, 0x7e, 0xd7, 0xd6, 0xae, 0xf0, - 0x5b, 0xe3, 0xe3, 0xe0, 0x1f, 0xc0, 0xfd, 0x07, 0xc3, 0xf1, 0xcb, 0x31, 0x93, 0x9d, 0xc3, 0x7d, - 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x15, 0xbc, 0x04, 0x80, 0x27, 0x96, 0xe5, 0x9f, 0x1d, 0x98, - 0x7f, 0xde, 0xa9, 0x06, 0x6d, 0xc7, 0xd7, 0xc3, 0xd7, 0x0d, 0xbe, 0xbc, 0xfe, 0xc4, 0xbb, 0x57, - 0x49, 0x0e, 0x1b, 0x73, 0x4e, 0x9e, 0xe9, 0xbd, 0x85, 0xb6, 0xb8, 0x53, 0x7b, 0x9d, 0x8f, 0x2c, - 0x36, 0x77, 0xcc, 0x79, 0x69, 0x4a, 0xd0, 0x70, 0x5a, 0x7a, 0x48, 0x88, 0xe5, 0x54, 0x6b, 0x83, - 0xad, 0x36, 0x6a, 0x20, 0xeb, 0x58, 0x8d, 0x8f, 0x2b, 0x0e, 0xd7, 0xfd, 0x28, 0x0d, 0xb4, 0x3e, - 0x8d, 0xa3, 0x0f, 0x85, 0xb9, 0xde, 0xbe, 0x06, 0x1a, 0x1a, 0x00, 0x55, 0x89, 0xa8, 0x1f, 0xec, - 0x45, 0x8a, 0x42, 0x58, 0x88, 0x64, 0xa0, 0x3e, 0xc4, 0x1f, 0x07, 0xc0, 0xf0, 0x70, 0x1f, 0x85, - 0xf0, 0x5c, 0x1f, 0xc6, 0x79, 0x30, 0x2b, 0x5c, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xf5, 0xa4, - 0x00, 0xc0, 0x1a, 0x82, 0xb9, 0xa8, 0x96, 0x29, 0xa5, 0x81, 0x9f, 0x39, 0x3b, 0x70, 0x23, 0x39, - 0x35, 0x0a, 0x95, 0x81, 0x24, 0xb3, 0xa0, 0x58, 0x6c, 0xf3, 0x5d, 0xd1, 0x39, 0xc1, 0x71, 0x21, - 0x10, 0xc2, 0x4b, 0x28, 0x89, 0x97, 0x94, 0x06, 0x7c, 0x8a, 0x5d, 0xaa, 0xba, 0x73, 0xaa, 0x37, - 0x76, 0x1c, 0x58, 0x7b, 0x78, 0x53, 0x13, 0xd9, 0x1d, 0xcc, 0x11, 0x3d, 0x87, 0xc9, 0x70, 0x9c, - 0x4a, 0xe5, 0x84, 0x26, 0x63, 0x1c, 0x21, 0xbb, 0x4e, 0x17, 0xb0, 0x80, 0x04, 0xbc, 0x61, 0x90, - 0x93, 0xc2, 0x90, 0x33, 0xf4, 0xbd, 0xe4, 0x6e, 0x57, 0xaa, 0xf0, 0xb6, 0x4b, 0x4e, 0x1f, 0xc3, - 0xe0, 0xf8, 0x3f, 0x04, 0xf5, 0x9a, 0x7e, 0xa7, 0xe0, 0x68, 0xe2, 0xe3, 0xc0, 0xf2, 0x01, 0xb3, - 0xa4, 0x65, 0x4a, 0x45, 0x72, 0x09, 0x05, 0xb4, 0x00, 0x01, 0xf0, 0xd7, 0x1b, 0x3d, 0x12, 0xfe, - 0x87, 0xbc, 0xf1, 0x46, 0x7f, 0xaf, 0xe8, 0x8e, 0xd8, 0xa8, 0x0f, 0x35, 0x81, 0xf6, 0xf3, 0x53, - 0xa1, 0xee, 0x9e, 0x47, 0x32, 0x60, 0x41, 0x56, 0x19, 0x5e, 0xcd, 0x91, 0x93, 0x3c, 0xd2, 0xb0, - 0xef, 0x03, 0x36, 0x91, 0xaa, 0x9a, 0x8f, 0x06, 0x90, 0xfe, 0x02, 0xce, 0x1f, 0xbc, 0x5f, 0x43, - 0x9e, 0x0d, 0xbf, 0x81, 0x52, 0xb4, 0xb0, 0xcf, 0x9f, 0xd6, 0xf4, 0x80, 0xe1, 0x9c, 0xa3, 0x54, - 0xa7, 0xcb, 0xae, 0x65, 0xa0, 0xbb, 0x60, 0x04, 0x5f, 0x2b, 0x58, 0x25, 0xd7, 0x1c, 0x18, 0x8c, - 0x6b, 0x87, 0x21, 0x29, 0x51, 0x92, 0xc2, 0x46, 0x2e, 0xbc, 0x38, 0x60, 0xfc, 0x0e, 0xc7, 0x87, - 0x0e, 0x0c, 0x3e, 0xde, 0x3d, 0x31, 0x45, 0x11, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xe5, 0xbc, - 0x00, 0x00, 0x40, 0x70, 0xf1, 0xc9, 0x87, 0xe9, 0x1b, 0x2a, 0x08, 0xfb, 0x57, 0x88, 0xb6, 0x0a, - 0x8e, 0x86, 0x71, 0x2b, 0x11, 0x1c, 0x02, 0x56, 0xbf, 0xbd, 0x5f, 0x02, 0xca, 0x76, 0x93, 0x36, - 0x6e, 0x68, 0xfd, 0xfe, 0x4d, 0xb0, 0x70, 0xfb, 0xfe, 0x93, 0xab, 0x7e, 0xe2, 0xdd, 0x26, 0x32, - 0x82, 0x73, 0x95, 0x17, 0x35, 0x0a, 0x59, 0x2c, 0xe7, 0x31, 0x16, 0xe6, 0xd2, 0xc5, 0x4a, 0x94, - 0x1c, 0xa5, 0xfb, 0x30, 0x7e, 0xec, 0x23, 0x7a, 0xf2, 0x1d, 0x92, 0x4f, 0xe2, 0xcf, 0xbf, 0x9a, - 0xec, 0xc2, 0x31, 0x03, 0x61, 0x81, 0x9a, 0x2b, 0xcc, 0xd6, 0xe7, 0x3f, 0x9c, 0x6e, 0x6f, 0x8f, - 0xf0, 0x5e, 0x7f, 0x21, 0xe6, 0x5f, 0xf0, 0x68, 0xfa, 0xa7, 0x28, 0x7a, 0xee, 0x4b, 0x56, 0xde, - 0xa4, 0x65, 0x4a, 0x45, 0x72, 0x08, 0xe5, 0xbc, 0x00, 0xc3, 0x1c, 0xbf, 0x03, 0xf7, 0xa9, 0x45, - 0xe6, 0xe9, 0x53, 0x2c, 0xa3, 0x3e, 0xd3, 0x05, 0x55, 0xc8, 0x9e, 0xf4, 0xf3, 0xa5, 0x9c, 0x17, - 0x7d, 0x48, 0x7e, 0x0b, 0x90, 0xe1, 0xd4, 0xae, 0x28, 0xb7, 0xfc, 0x5f, 0x7f, 0x3f, 0x84, 0x86, - 0xcc, 0x56, 0x0a, 0x75, 0x23, 0x72, 0x68, 0x0e, 0x1b, 0x59, 0xd5, 0x06, 0xfb, 0x2e, 0xaa, 0x30, - 0x5a, 0x37, 0x88, 0x6d, 0x75, 0xf8, 0x3a, 0x91, 0xbb, 0x72, 0x21, 0xfa, 0xad, 0x9a, 0x92, 0x6c, - 0x8e, 0xd5, 0xa2, 0xda, 0x89, 0x7d, 0x64, 0xf5, 0x9d, 0x55, 0xc8, 0x86, 0x06, 0x9e, 0xc1, 0x99, - 0xf2, 0x33, 0xd7, 0x89, 0xd4, 0xf2, 0x27, 0x87, 0x03, 0xf0, 0x0f, 0xe8, 0x0e, 0xe0, 0x0f, 0x03, - 0xfa, 0x38, 0x7f, 0x0f, 0x04, 0xa8, 0x31, 0x79, 0xa4, 0x65, 0x4a, 0x45, 0x72, 0x08, 0xe5, 0xbc, - 0x04, 0x82, 0x1b, 0xa4, 0x01, 0xe0, 0x13, 0x37, 0x59, 0xe0, 0xd9, 0x2b, 0x95, 0x47, 0x1c, 0x57, - 0xac, 0xdd, 0x50, 0x7d, 0xfb, 0xb2, 0x1b, 0xb9, 0xcb, 0xd5, 0xac, 0x55, 0x76, 0xde, 0x79, 0x88, - 0xff, 0xcd, 0x3f, 0xa9, 0x7c, 0x2c, 0x75, 0x4a, 0x1a, 0x26, 0xd2, 0xe1, 0x26, 0x94, 0x79, 0x08, - 0x5e, 0x25, 0x2d, 0x71, 0xa9, 0x95, 0xb9, 0x2a, 0xcf, 0x78, 0x15, 0x88, 0x84, 0x5b, 0xc3, 0xf2, - 0xca, 0x49, 0x1c, 0x54, 0xda, 0xf5, 0x9f, 0x94, 0xff, 0x8f, 0x98, 0x4a, 0x83, 0x1e, 0x01, 0x90, - 0x58, 0x53, 0x67, 0x24, 0x68, 0x8a, 0x6f, 0xc7, 0x15, 0xfc, 0x0d, 0xf5, 0x61, 0xe3, 0xfd, 0xfc, - 0x1d, 0xc3, 0xf0, 0x3f, 0x01, 0xe1, 0xd8, 0x1f, 0x07, 0xc0, 0xc6, 0xf1, 0xe7, 0x31, 0x8f, 0x73, - 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x05, 0xcc, 0x05, 0xbf, 0xeb, 0x69, 0x94, 0x99, 0xa8, 0xf1, - 0x0e, 0x92, 0x78, 0xaf, 0x01, 0xdc, 0x41, 0x3e, 0xd9, 0x4d, 0xb5, 0xc3, 0xe6, 0x5e, 0x56, 0x0e, - 0xdb, 0x69, 0x6b, 0x2a, 0x17, 0xbe, 0xd8, 0x2a, 0x71, 0xec, 0x70, 0x96, 0x8e, 0xda, 0xf1, 0x2e, - 0xeb, 0x40, 0x3f, 0x94, 0x3d, 0x1c, 0x7b, 0x73, 0x92, 0x4f, 0x25, 0x3d, 0x4a, 0x1a, 0x00, 0x96, - 0xa1, 0xee, 0xad, 0xdc, 0xf5, 0x98, 0xea, 0x1c, 0x29, 0x20, 0x01, 0x5e, 0x7b, 0x38, 0x3b, 0x43, - 0x0e, 0x27, 0xcb, 0x30, 0x93, 0xe7, 0x9e, 0xbe, 0x6f, 0xb3, 0xdf, 0x0e, 0xec, 0xc8, 0x54, 0x02, - 0x9f, 0x24, 0xdb, 0x5c, 0x4f, 0x1a, 0xd2, 0x52, 0x1d, 0xe3, 0xcf, 0x8f, 0xe0, 0xf8, 0x07, 0xf1, - 0x3a, 0x8f, 0x08, 0x82, 0x63, 0x92, 0x07, 0x32, 0x82, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xe5, 0xd4, - 0x00, 0x06, 0x94, 0xa8, 0xb5, 0xb8, 0x7f, 0xec, 0x80, 0x29, 0x5d, 0xd8, 0xc1, 0x32, 0xdd, 0xd1, - 0x05, 0x53, 0x33, 0x6b, 0x58, 0x00, 0xcf, 0x48, 0xa4, 0xd6, 0xce, 0x18, 0x6a, 0xbe, 0xec, 0x08, - 0xa1, 0x16, 0x39, 0xd6, 0xcd, 0x75, 0x06, 0x8e, 0xdc, 0x22, 0x03, 0x83, 0x24, 0xd1, 0x5e, 0x0c, - 0x6c, 0xa1, 0xa4, 0x36, 0x06, 0xb8, 0xc8, 0x16, 0x32, 0xbe, 0x8c, 0x78, 0x04, 0xbe, 0x84, 0xf2, - 0x4a, 0xed, 0x94, 0x75, 0xde, 0xb4, 0xdc, 0x91, 0x8d, 0xb5, 0x96, 0x61, 0x43, 0xee, 0x3e, 0x69, - 0x03, 0x84, 0xb5, 0x43, 0xad, 0xa5, 0x35, 0x42, 0x75, 0x08, 0x3d, 0x0a, 0x27, 0x76, 0x6c, 0x7b, - 0xc3, 0x07, 0x81, 0xf9, 0x81, 0xf8, 0x7c, 0x07, 0xe8, 0xf1, 0xa2, 0x5e, 0x3c, 0xf4, 0x29, 0x51, - 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xf5, 0xcc, 0x04, 0x8e, 0x04, 0x00, 0xff, 0x7a, 0x54, 0x6b, - 0x4a, 0x61, 0x23, 0x36, 0xd4, 0x6b, 0x8f, 0x20, 0x5c, 0xa3, 0xfb, 0x43, 0xde, 0x27, 0x6a, 0x30, - 0x65, 0xd6, 0x6f, 0x2c, 0x6b, 0xa1, 0x25, 0xbc, 0xa3, 0x4e, 0xbf, 0x32, 0x9b, 0xf0, 0x68, 0x3d, - 0xf9, 0xe8, 0x10, 0x34, 0xfa, 0xb4, 0x5d, 0x40, 0x02, 0x97, 0xa7, 0x90, 0x0c, 0xf9, 0xdf, 0x6c, - 0x21, 0xad, 0x56, 0xcc, 0xe4, 0xb6, 0xc0, 0x7b, 0x8f, 0x5b, 0x15, 0xe2, 0x34, 0xc8, 0x47, 0x2b, - 0x32, 0xc7, 0x48, 0x70, 0x23, 0xd9, 0x08, 0x31, 0x02, 0xa4, 0x99, 0x10, 0xf0, 0x20, 0x72, 0x89, - 0x11, 0xe2, 0x4b, 0x9a, 0x0b, 0x0a, 0x13, 0x04, 0xe1, 0xe0, 0x3c, 0x2e, 0x60, 0x7e, 0x1f, 0xc0, - 0x78, 0x7c, 0x78, 0xce, 0x37, 0x58, 0x68, 0xd8, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xe5, 0xcc, - 0x04, 0x90, 0x07, 0x33, 0x07, 0x60, 0xfd, 0xe3, 0xec, 0x7e, 0x9b, 0xe3, 0xd1, 0x30, 0x29, 0x22, - 0x2a, 0x23, 0x7b, 0x65, 0x26, 0x4d, 0xba, 0xfc, 0xd2, 0xfa, 0xe0, 0xf9, 0x20, 0x2f, 0x01, 0x72, - 0x86, 0xaf, 0x5b, 0x7f, 0x49, 0xaf, 0xbc, 0xbb, 0x31, 0x35, 0x9b, 0xda, 0xbf, 0x63, 0x88, 0xd5, - 0x5e, 0x2c, 0xbf, 0xb7, 0x44, 0xc1, 0xf9, 0x23, 0xde, 0x5a, 0x01, 0x4a, 0x44, 0x41, 0x2c, 0x32, - 0x34, 0x86, 0xac, 0x49, 0x62, 0xef, 0xb7, 0x8b, 0xfe, 0xfa, 0xf2, 0x66, 0x0e, 0x88, 0x72, 0x90, - 0x88, 0x7b, 0x83, 0x9b, 0x05, 0xd1, 0x51, 0x8f, 0xbf, 0x79, 0xc1, 0x79, 0xf2, 0x78, 0x40, 0x8c, - 0x3c, 0x3e, 0x03, 0xfc, 0x2d, 0xc1, 0xf8, 0x0f, 0x0f, 0xba, 0x8c, 0x86, 0x98, 0x47, 0x5c, 0xf2, - 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xf5, 0xcc, 0x00, 0xcc, 0x0f, 0x92, 0x03, 0x75, 0x12, 0xdb, - 0x72, 0x37, 0x8b, 0x66, 0xc9, 0xe9, 0x64, 0xa3, 0x17, 0x5f, 0xa0, 0x2e, 0x6e, 0x60, 0xc1, 0xa6, - 0x8c, 0xfd, 0x02, 0x3b, 0xa7, 0x98, 0xa7, 0xda, 0x9e, 0x16, 0xcb, 0x8d, 0x65, 0x7a, 0x7e, 0xb7, - 0xc4, 0xf5, 0x37, 0x88, 0x71, 0x38, 0x2c, 0x32, 0x52, 0x17, 0x70, 0x3f, 0xd1, 0x6a, 0x6d, 0x8d, - 0xed, 0x5f, 0xa4, 0xed, 0x42, 0x06, 0x4b, 0xa8, 0x5e, 0x62, 0x4e, 0x4b, 0x02, 0xe7, 0xfe, 0x54, - 0xde, 0x88, 0xf7, 0xfd, 0xd3, 0x3d, 0x6f, 0x1b, 0xc9, 0x94, 0x74, 0x57, 0xc4, 0x3d, 0xdc, 0x54, - 0x91, 0xd5, 0xe7, 0x36, 0x17, 0x11, 0xac, 0x28, 0x2b, 0xe6, 0x1c, 0x1f, 0x03, 0xe4, 0xfc, 0x1f, - 0x85, 0x78, 0xe3, 0x32, 0x78, 0x57, 0x69, 0x2d, 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x08, 0xf5, 0xdc, - 0x00, 0x06, 0xa0, 0x3e, 0xa9, 0x76, 0x09, 0x2a, 0x4e, 0xa0, 0xcb, 0xdc, 0xf0, 0x30, 0x4d, 0xdf, - 0x8d, 0xd3, 0x19, 0x7b, 0x2c, 0x79, 0x1e, 0x6a, 0x23, 0xc5, 0xf9, 0x46, 0x91, 0xd0, 0x26, 0x1b, - 0xf8, 0x46, 0x50, 0x56, 0x83, 0x98, 0x27, 0x1a, 0xa7, 0x7c, 0xeb, 0x90, 0x9b, 0x94, 0x6f, 0x17, - 0x54, 0x89, 0x21, 0x94, 0xd2, 0x04, 0x00, 0x45, 0x98, 0x30, 0xb4, 0xcf, 0x4a, 0x90, 0xed, 0x77, - 0x51, 0x67, 0xe4, 0xf1, 0xd3, 0xaf, 0xec, 0x3c, 0x03, 0x0a, 0xf3, 0x83, 0xf5, 0x40, 0x49, 0x3f, - 0x15, 0x21, 0xf4, 0x41, 0x6f, 0xd7, 0x58, 0xc5, 0x6e, 0xcd, 0x4a, 0xbd, 0x91, 0x6f, 0x64, 0x08, - 0xf0, 0xf8, 0x7e, 0x1f, 0x80, 0xfe, 0x1f, 0xc7, 0x97, 0xb8, 0x63, 0x70, 0x0c, 0x18, 0x3f, 0xc8, - 0xa2, 0x1d, 0xcb, 0x05, 0x72, 0x09, 0x05, 0xd4, 0x00, 0x00, 0xf2, 0xb4, 0x00, 0x7b, 0xf6, 0x30, - 0x4b, 0xd2, 0x57, 0xae, 0x2e, 0xf3, 0x08, 0x05, 0x34, 0x38, 0x6e, 0xac, 0xfd, 0x94, 0xb9, 0xf9, - 0xd8, 0x5b, 0xef, 0x7c, 0x81, 0x95, 0xe9, 0xe0, 0x6b, 0x7d, 0x8a, 0xb8, 0x6f, 0x66, 0x82, 0x11, - 0xb7, 0x6a, 0x63, 0x28, 0xf7, 0x91, 0x58, 0x38, 0xce, 0xc8, 0x53, 0xb2, 0x9a, 0xb4, 0x07, 0x3c, - 0x81, 0x27, 0x4a, 0x88, 0x33, 0x6d, 0x37, 0xb1, 0xa7, 0xcb, 0x6e, 0xdd, 0xc7, 0x9a, 0x6e, 0xdc, - 0xb5, 0x21, 0x7f, 0xd3, 0x02, 0x0a, 0x79, 0x83, 0xb4, 0xaf, 0x74, 0x1b, 0xb4, 0x0f, 0xe2, 0xaf, - 0x15, 0x6d, 0x0d, 0x01, 0xc7, 0x02, 0x06, 0x33, 0xeb, 0xd8, 0x33, 0xe6, 0xe5, 0xe3, 0x2e, 0xf0, - 0x5f, 0x0f, 0x21, 0xcb, 0x6d, 0x86, 0x06, 0xb9, 0xb4, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd5, 0xdc, - 0x00, 0xc3, 0xf5, 0xf9, 0xd6, 0xe4, 0x55, 0xeb, 0x8c, 0xb5, 0x6c, 0xc9, 0xe2, 0x92, 0x54, 0xcb, - 0x36, 0x2d, 0x90, 0x55, 0x22, 0x29, 0x91, 0xbe, 0xfd, 0xd4, 0xba, 0x06, 0xcb, 0x7d, 0x5a, 0x1e, - 0x5a, 0xef, 0xb4, 0x5e, 0x44, 0xee, 0xd9, 0x9d, 0xae, 0x61, 0xfc, 0x66, 0x66, 0x1d, 0x2d, 0xd8, - 0x88, 0xd4, 0x4b, 0xf5, 0x0f, 0xcc, 0x70, 0xc7, 0x5e, 0xa4, 0x1b, 0xa0, 0xcc, 0x6f, 0x14, 0xa2, - 0x28, 0x84, 0x56, 0xdf, 0x9b, 0x9b, 0x1d, 0x31, 0x77, 0x7b, 0xbc, 0x6f, 0x3d, 0xae, 0x37, 0x24, - 0xe4, 0xef, 0xab, 0xb6, 0xc0, 0x00, 0xad, 0x44, 0xf1, 0x9e, 0x98, 0x19, 0x0b, 0xfd, 0x70, 0x67, - 0x9f, 0x9e, 0x1e, 0x87, 0xa1, 0xa0, 0xd0, 0x1c, 0x9d, 0x1a, 0x3d, 0x1b, 0xf6, 0x2c, 0xd9, 0xd3, - 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xc5, 0xdc, 0x04, 0x8c, 0x0a, 0xd0, 0x8b, 0x08, 0x59, 0xea, - 0x37, 0x08, 0xa4, 0x24, 0x01, 0x0c, 0xa3, 0xaa, 0xb6, 0x2b, 0xca, 0x29, 0x89, 0x31, 0x5d, 0xa3, - 0xf5, 0xdc, 0xd1, 0x78, 0x34, 0xda, 0xce, 0xbe, 0x18, 0xff, 0x18, 0xd4, 0x8a, 0xf4, 0x80, 0x40, - 0x8e, 0xe5, 0x8f, 0x26, 0x02, 0xa1, 0x19, 0x3a, 0xa7, 0x4a, 0x85, 0x8b, 0xc8, 0xe2, 0xed, 0xfa, - 0xd3, 0x58, 0x19, 0xea, 0xe5, 0x7d, 0x86, 0xe8, 0x1b, 0x59, 0x73, 0x0f, 0x92, 0xfd, 0x6e, 0xb9, - 0x05, 0xb2, 0x21, 0x1d, 0xdd, 0xbc, 0xea, 0xfe, 0x15, 0xf9, 0x96, 0x7e, 0x39, 0x45, 0xa1, 0xfa, - 0xf9, 0x77, 0xca, 0x50, 0x47, 0x81, 0xa3, 0x4d, 0xf3, 0xc3, 0xc1, 0xce, 0x1d, 0x03, 0x9c, 0x9d, - 0x0b, 0x02, 0x9f, 0x43, 0x9d, 0x67, 0x93, 0xab, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xe5, 0xdc, - 0x00, 0x08, 0xa3, 0xf4, 0x59, 0x6e, 0x0b, 0x46, 0xee, 0xce, 0x77, 0xfe, 0x27, 0x55, 0xf6, 0xd6, - 0xf4, 0xf7, 0x2b, 0xab, 0xb3, 0x99, 0x0c, 0x42, 0xe4, 0x05, 0x9d, 0x21, 0x3b, 0x34, 0x6d, 0x0c, - 0x33, 0xf2, 0xee, 0x72, 0x2e, 0xd1, 0x1e, 0xeb, 0x70, 0x36, 0xd9, 0x45, 0x08, 0xd7, 0x3c, 0x79, - 0x05, 0x63, 0x41, 0x7c, 0x78, 0xc3, 0xaa, 0x76, 0x14, 0x22, 0xdf, 0xc4, 0x5b, 0x1b, 0x23, 0x88, - 0xac, 0xd9, 0x38, 0x7e, 0x84, 0x1c, 0x81, 0x80, 0x3c, 0x57, 0xa7, 0x2c, 0xe8, 0xf2, 0x59, 0xb4, - 0x9c, 0x8a, 0x56, 0xb3, 0xd0, 0x29, 0x1a, 0x0e, 0x3f, 0x19, 0x29, 0xbb, 0x8a, 0xf3, 0xfb, 0x03, - 0x31, 0xcf, 0xc1, 0xe0, 0x70, 0x70, 0xc6, 0x1f, 0x0d, 0x8e, 0x43, 0xf0, 0x73, 0xc1, 0x44, 0xfc, - 0xb4, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xf5, 0xe4, 0x00, 0x04, 0x6e, 0x94, 0x9d, 0xaa, 0x6b, 0x43, - 0x9d, 0x6b, 0x8f, 0x14, 0x3b, 0xb0, 0x78, 0xb0, 0x33, 0x31, 0xc1, 0x8e, 0xf3, 0x75, 0x71, 0xbe, - 0xb9, 0x84, 0x5c, 0xfb, 0x3d, 0x2c, 0x0c, 0x32, 0x6a, 0xef, 0x90, 0x51, 0xdf, 0x6f, 0x43, 0x7b, - 0x96, 0x17, 0xd9, 0x81, 0x2c, 0xb6, 0x12, 0xd9, 0x8f, 0x4f, 0xbf, 0x44, 0xcc, 0x46, 0xab, 0xef, - 0xf3, 0xd1, 0xa1, 0x10, 0x28, 0xa4, 0x6d, 0xcc, 0x77, 0xd3, 0xf8, 0xd5, 0xd5, 0x95, 0xcf, 0xde, - 0xb4, 0x9e, 0xeb, 0xb2, 0x3f, 0x7d, 0xef, 0xbd, 0x2d, 0x86, 0x29, 0xfe, 0xd9, 0x70, 0x7a, 0x3d, - 0x48, 0xcd, 0xf0, 0x03, 0xe4, 0x04, 0x18, 0x8a, 0xce, 0x76, 0x66, 0x0c, 0x3c, 0x1c, 0x27, 0x33, - 0x81, 0x0e, 0x97, 0xd0, 0x77, 0xa3, 0x52, 0xe1, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd5, 0xf4, - 0x04, 0x80, 0xb9, 0xd1, 0xea, 0x0b, 0x6d, 0x5b, 0x0a, 0xd6, 0xda, 0xe7, 0xa9, 0xe7, 0x58, 0x40, - 0x74, 0xdb, 0x35, 0xf6, 0x73, 0xc7, 0x81, 0x7c, 0xc1, 0x6e, 0xd3, 0xa8, 0xaa, 0xef, 0xe2, 0xf7, - 0x20, 0x16, 0xbc, 0x3e, 0x32, 0x32, 0x17, 0x5d, 0xfc, 0x7b, 0x2b, 0x95, 0x6c, 0x89, 0x9a, 0xd0, - 0xe4, 0xe9, 0x63, 0x5b, 0x56, 0x4f, 0x74, 0x16, 0x51, 0x96, 0x07, 0xe2, 0x2b, 0x78, 0xb7, 0x22, - 0x11, 0x0b, 0x86, 0x06, 0xa7, 0xa1, 0x93, 0xb8, 0xc4, 0x8a, 0x3f, 0x17, 0xb6, 0xef, 0x2c, 0x0f, - 0xa1, 0x7c, 0x56, 0x44, 0x22, 0x73, 0x7b, 0x4e, 0x3f, 0xbd, 0x5e, 0x9d, 0x79, 0xad, 0xbc, 0x57, - 0x4c, 0xe6, 0x07, 0x83, 0x18, 0x4f, 0x1f, 0x26, 0x8e, 0x1f, 0x1d, 0x8f, 0x84, 0x73, 0x97, 0x93, - 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xf5, 0xe4, 0x05, 0xc0, 0xee, 0xc4, 0xb6, 0xf1, 0x78, 0x1c, - 0x92, 0xa3, 0x44, 0xa6, 0x8e, 0x34, 0x54, 0x3c, 0xf9, 0x70, 0x11, 0x72, 0xf7, 0xc3, 0xf8, 0xad, - 0x77, 0x05, 0x7e, 0x9c, 0x87, 0x4e, 0x37, 0xfe, 0x70, 0x58, 0x3e, 0x56, 0xb0, 0x6c, 0xca, 0xfc, - 0x7e, 0x7c, 0x9f, 0x2c, 0xf0, 0x7f, 0x0a, 0x88, 0xec, 0x6f, 0x83, 0xfd, 0xe8, 0xd4, 0x8a, 0x04, - 0x1f, 0xd5, 0x6c, 0x5e, 0x75, 0xdb, 0x2f, 0x2b, 0x44, 0x69, 0xbf, 0xdc, 0xeb, 0x71, 0xe6, 0xd0, - 0x53, 0xf1, 0xfa, 0x6d, 0x0f, 0xe1, 0x1e, 0x1f, 0x47, 0xe4, 0xbc, 0x23, 0x78, 0x89, 0xe5, 0x78, - 0x8c, 0x68, 0xc7, 0x3b, 0x54, 0x4e, 0xf7, 0x80, 0xbe, 0x3c, 0x78, 0x7c, 0x3e, 0x78, 0x78, 0xe3, - 0x17, 0x81, 0x1a, 0x4a, 0x1d, 0xec, 0x1a, 0xe3, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd5, 0xf4, - 0x00, 0x07, 0xf9, 0xc9, 0xf0, 0xe6, 0x4c, 0x15, 0x5e, 0x3d, 0x52, 0x3a, 0xa8, 0x4a, 0x61, 0xe0, - 0x03, 0x4e, 0x61, 0x7a, 0xef, 0x54, 0x60, 0x34, 0x45, 0x5c, 0xd9, 0x41, 0xfc, 0x6e, 0x6c, 0x25, - 0xf6, 0xab, 0x6e, 0x7a, 0x2c, 0x3f, 0x2a, 0x6b, 0x3c, 0x46, 0x44, 0x43, 0x08, 0x95, 0xcd, 0xda, - 0xc3, 0x53, 0x0a, 0xac, 0x72, 0x02, 0x3e, 0xd6, 0x8c, 0xcc, 0x32, 0x1c, 0x4d, 0x64, 0x94, 0xc5, - 0xfb, 0xb0, 0x68, 0xe7, 0xaf, 0x6e, 0xbc, 0x9e, 0xbf, 0x27, 0xe0, 0x0a, 0x84, 0x6b, 0x28, 0x53, - 0xa7, 0xc1, 0xf3, 0xf1, 0xad, 0x27, 0xf2, 0xd6, 0xad, 0x45, 0x33, 0x0f, 0xde, 0x9d, 0x6b, 0x43, - 0x01, 0xe1, 0xf1, 0xe0, 0x78, 0x68, 0x2c, 0x12, 0x73, 0x05, 0x4b, 0x4c, 0xd9, 0x79, 0xa3, 0x4c, - 0xb4, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xe5, 0xfc, 0x04, 0x83, 0xf2, 0x43, 0x5c, 0x3b, 0xb7, 0x22, - 0xf4, 0x83, 0x1a, 0x13, 0xf1, 0x44, 0x26, 0x9c, 0x93, 0xed, 0xf4, 0xfd, 0xc0, 0xb6, 0xef, 0xcb, - 0x43, 0x5d, 0xde, 0xf0, 0xeb, 0x01, 0x1b, 0x76, 0x82, 0xbb, 0x78, 0xa2, 0x26, 0x9b, 0x63, 0xb0, - 0x91, 0xa5, 0xd2, 0xd7, 0xc5, 0x54, 0xd9, 0x20, 0x51, 0x6e, 0xb0, 0x0b, 0x7d, 0x13, 0x46, 0x39, - 0xbd, 0xf9, 0x45, 0xeb, 0x7d, 0x41, 0xb4, 0x37, 0x3e, 0x09, 0xb5, 0xd2, 0xec, 0x67, 0x93, 0xcf, - 0x6d, 0xa9, 0xd0, 0x67, 0x10, 0x80, 0x08, 0x13, 0x66, 0x42, 0xe1, 0x77, 0x38, 0x4c, 0x54, 0xb4, - 0x87, 0xe5, 0xff, 0x95, 0x61, 0x25, 0x4d, 0x18, 0xff, 0x47, 0xbe, 0x3e, 0x1c, 0x16, 0xea, 0x1c, - 0x5e, 0x0f, 0x0f, 0x2b, 0x4f, 0x45, 0xce, 0x0b, 0xb4, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd5, 0xf4, - 0x04, 0x80, 0x89, 0x37, 0xc9, 0xab, 0x0b, 0x9d, 0xb6, 0x8a, 0xd4, 0x9b, 0x41, 0x45, 0x5a, 0xba, - 0xc7, 0xa5, 0x1b, 0x4e, 0xe8, 0xe3, 0x3f, 0xbf, 0x5d, 0x32, 0x99, 0xb8, 0x18, 0xb0, 0x4c, 0x0b, - 0x7a, 0xf4, 0x78, 0xe5, 0xb0, 0x90, 0x99, 0xaa, 0xf0, 0xb4, 0xc5, 0xec, 0xc4, 0x4f, 0xae, 0x75, - 0x57, 0x9f, 0x7b, 0x46, 0x7c, 0x0a, 0xee, 0xf1, 0x41, 0xc1, 0x74, 0x4d, 0x0b, 0xe1, 0xa3, 0x75, - 0xeb, 0x64, 0xc8, 0xbc, 0x29, 0x00, 0x21, 0x91, 0x9d, 0x0c, 0x29, 0x1f, 0xcd, 0xc2, 0x19, 0xc7, - 0x70, 0x7f, 0x12, 0x30, 0x3d, 0x9a, 0x37, 0xa6, 0x83, 0x08, 0x2c, 0x75, 0xf2, 0x65, 0x9f, 0x60, - 0x73, 0xe3, 0xf1, 0xc0, 0x7c, 0x3c, 0x7e, 0x1e, 0x78, 0xe1, 0xf5, 0xe8, 0xee, 0x3e, 0x7d, 0xb9, - 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xe5, 0xfc, 0x04, 0x80, 0x29, 0xc1, 0xc4, 0x2f, 0x9d, 0x30, - 0x83, 0x82, 0x73, 0x6c, 0x33, 0xb6, 0x37, 0xcf, 0xec, 0xb3, 0xe8, 0x48, 0x24, 0xd6, 0x82, 0xab, - 0x23, 0xcb, 0x9d, 0xcb, 0x6b, 0x1a, 0xad, 0x96, 0x32, 0x3a, 0xed, 0x43, 0xf1, 0xdf, 0x02, 0xde, - 0x66, 0x4a, 0x8b, 0x5c, 0x1a, 0x8f, 0x70, 0x0a, 0xf2, 0xaa, 0x04, 0x2d, 0xa6, 0x23, 0x35, 0x8a, - 0x7f, 0x1e, 0xf9, 0x24, 0xec, 0x67, 0x7e, 0x7f, 0x1e, 0x7d, 0x4c, 0x99, 0x43, 0x3d, 0xb8, 0xed, - 0xef, 0xea, 0xb6, 0x25, 0x06, 0x20, 0x69, 0x25, 0xe4, 0x97, 0xd0, 0x9d, 0x0c, 0xb5, 0x3d, 0x3d, - 0x08, 0xe2, 0x54, 0x9d, 0xc2, 0xf8, 0x5f, 0x70, 0x78, 0xf1, 0xf8, 0x3e, 0x3c, 0x2e, 0x0f, 0xc4, - 0x20, 0x9f, 0x80, 0x42, 0x6e, 0xe7, 0xc6, 0x17, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x09, 0x05, 0xf4, - 0x04, 0x80, 0x62, 0xdf, 0x2f, 0x51, 0xcc, 0x97, 0x7e, 0x59, 0xa8, 0x2a, 0xd7, 0x36, 0x6c, 0x58, - 0x4a, 0x4b, 0x7b, 0x51, 0x19, 0x51, 0x3d, 0xb2, 0x05, 0xfc, 0xe0, 0xcc, 0x89, 0xa9, 0xc6, 0xc7, - 0x24, 0xdd, 0x06, 0x2d, 0x74, 0xb4, 0x72, 0xc4, 0xbe, 0x2b, 0x17, 0xb5, 0x87, 0x6e, 0x3f, 0x6a, - 0x84, 0x9c, 0x59, 0x7a, 0x07, 0x64, 0xf0, 0x8a, 0x54, 0x2c, 0x1a, 0x5e, 0x8a, 0x5d, 0xd3, 0x8b, - 0xe0, 0x6f, 0x06, 0x0d, 0x7a, 0xc8, 0x6d, 0x9f, 0x0e, 0x15, 0x6b, 0x8f, 0xa7, 0xdf, 0x39, 0x2f, - 0x45, 0x1a, 0xdb, 0xc4, 0x36, 0xfc, 0xa2, 0xa5, 0xb1, 0x93, 0xd4, 0xea, 0x73, 0x91, 0x1f, 0x83, - 0x03, 0xc3, 0x81, 0xe0, 0x70, 0xf0, 0xf1, 0x87, 0x0b, 0x18, 0xfe, 0x55, 0xc4, 0xfc, 0x70, 0xde, - 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xe6, 0x04, 0x00, 0x10, 0xbe, 0xbf, 0xc1, 0x4c, 0x3c, 0x03, - 0xe8, 0xeb, 0x0a, 0x6c, 0x91, 0xcb, 0xa3, 0xf1, 0xe3, 0xd5, 0x64, 0x95, 0x46, 0x53, 0xe1, 0x02, - 0x5f, 0x30, 0x79, 0x44, 0xd0, 0x69, 0x4d, 0xa1, 0xeb, 0x7f, 0x6f, 0x76, 0x59, 0x9b, 0xd4, 0x88, - 0x22, 0x14, 0x38, 0x7f, 0xaa, 0x4e, 0x5f, 0x90, 0xb9, 0x20, 0xf6, 0x8e, 0x58, 0x89, 0x05, 0x85, - 0xbf, 0x3f, 0xbc, 0x8b, 0xb2, 0x6c, 0xaa, 0x18, 0x66, 0xd8, 0xdf, 0x29, 0xea, 0x75, 0xf3, 0xb3, - 0x33, 0x17, 0x3a, 0x15, 0x63, 0xe0, 0x66, 0x04, 0x1d, 0xd6, 0x2b, 0x29, 0x01, 0x11, 0x48, 0x86, - 0xfa, 0x15, 0x8a, 0xd2, 0x06, 0x01, 0x4c, 0xcf, 0xe3, 0x8f, 0x1c, 0x61, 0xf3, 0xf4, 0x1e, 0xd8, - 0x1d, 0x3f, 0x7d, 0x1e, 0x5a, 0x85, 0xc3, 0x1e, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd6, 0x04, - 0x00, 0xd0, 0x76, 0xf2, 0x7f, 0x99, 0x06, 0x42, 0xba, 0x96, 0xa4, 0x66, 0xa1, 0x65, 0x02, 0x8e, - 0x0b, 0x06, 0xb9, 0x14, 0x5b, 0xf5, 0x89, 0x5b, 0x66, 0xf4, 0x69, 0x54, 0x4e, 0x58, 0x4d, 0xd9, - 0xd3, 0xab, 0xd2, 0x53, 0x92, 0xc5, 0x77, 0x20, 0x12, 0x1c, 0xe8, 0xa6, 0x3e, 0xb7, 0x9f, 0x88, - 0xff, 0x50, 0x5b, 0xeb, 0x68, 0xb2, 0xe8, 0x7a, 0xbb, 0x9c, 0x05, 0x5f, 0x10, 0x4c, 0xc4, 0x8f, - 0x55, 0xd9, 0x6c, 0xf6, 0xb3, 0xbc, 0x53, 0x99, 0xa9, 0xfb, 0x82, 0x3f, 0xee, 0xcf, 0x37, 0x72, - 0xfa, 0x8b, 0xe5, 0x63, 0x9b, 0x43, 0xde, 0x64, 0x3d, 0x37, 0xbe, 0x00, 0xdd, 0x9a, 0x4d, 0x4e, - 0xa7, 0x8e, 0x0c, 0xf8, 0x7c, 0x2c, 0x3a, 0x69, 0x38, 0x94, 0x89, 0x6b, 0x31, 0xdc, 0xa7, 0x30, - 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xc6, 0x0c, 0x04, 0x92, 0xbc, 0x03, 0x7e, 0xd0, 0xea, 0xb9, - 0x7b, 0xd3, 0x5f, 0xcb, 0xdf, 0x36, 0x51, 0x32, 0x20, 0x0f, 0x25, 0x93, 0xce, 0x92, 0xdc, 0x67, - 0x85, 0xf8, 0xa7, 0x11, 0x0b, 0x52, 0x1c, 0x67, 0x7f, 0x11, 0xf7, 0xbd, 0x73, 0x99, 0x32, 0xb3, - 0x85, 0x2b, 0x47, 0x6d, 0x06, 0x3c, 0xa6, 0x12, 0x4b, 0xa7, 0x65, 0x2f, 0x5a, 0xb9, 0xb9, 0xb8, - 0xf9, 0x0e, 0x07, 0x38, 0xf8, 0x16, 0x00, 0x16, 0x29, 0xee, 0xc0, 0xf6, 0x7a, 0x70, 0x17, 0x7a, - 0x0b, 0x6b, 0xb6, 0xba, 0x81, 0x15, 0x7d, 0xe9, 0x72, 0x05, 0x3d, 0xb0, 0x2c, 0xe9, 0xe0, 0x6d, - 0x72, 0x06, 0xfc, 0x3e, 0x1a, 0x23, 0x83, 0xe0, 0xc1, 0xf3, 0xe0, 0xf1, 0xe0, 0xff, 0xce, 0xfe, - 0x3c, 0x4c, 0x5f, 0x5c, 0x0c, 0xd4, 0x72, 0xf2, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xc6, 0x0c, - 0x00, 0x07, 0x36, 0x63, 0xdb, 0xdc, 0xae, 0x38, 0x21, 0x1b, 0xe5, 0xf8, 0x09, 0x1f, 0xd9, 0x49, - 0xb5, 0x70, 0xc3, 0x04, 0x20, 0xc7, 0x91, 0x5f, 0x41, 0x67, 0x58, 0x9e, 0xcc, 0x6f, 0x19, 0x17, - 0xba, 0xbb, 0x8f, 0x6b, 0x96, 0xea, 0xae, 0x01, 0x48, 0xac, 0xd3, 0x00, 0xa6, 0x22, 0xed, 0xbf, - 0x9c, 0x95, 0x21, 0x51, 0xe7, 0xf7, 0xda, 0x00, 0x14, 0xc1, 0x6e, 0xc5, 0x6d, 0xb5, 0x37, 0x0f, - 0xa0, 0xa2, 0xae, 0x80, 0x0b, 0x8d, 0x03, 0x1e, 0x8b, 0x0f, 0x81, 0x19, 0x1b, 0xaf, 0x80, 0x06, - 0xdc, 0xb0, 0x9d, 0x32, 0xaf, 0x09, 0x59, 0xbc, 0xfe, 0xc0, 0x0f, 0xe9, 0x14, 0x22, 0x16, 0xbc, - 0x78, 0xf1, 0xc7, 0x82, 0xa0, 0xd3, 0x3a, 0x79, 0x63, 0x61, 0xd0, 0xb8, 0x24, 0xc4, 0x7b, 0xc5, - 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd6, 0x0c, 0x02, 0x0e, 0x25, 0x72, 0x42, 0xbd, 0xb4, 0xc0, - 0xf2, 0x6f, 0x60, 0x06, 0x8a, 0x98, 0xa8, 0xef, 0xe8, 0x44, 0x26, 0x84, 0xe7, 0x86, 0xfb, 0x51, - 0x3c, 0x8c, 0x19, 0x84, 0x2a, 0x50, 0x74, 0x24, 0xf3, 0xd0, 0x37, 0xa4, 0x5c, 0x0d, 0x54, 0xf1, - 0xaf, 0x99, 0xb6, 0x5d, 0xf4, 0x72, 0x41, 0x06, 0x61, 0xec, 0xd2, 0x2d, 0xe5, 0xe6, 0xa1, 0x56, - 0xb3, 0x00, 0x09, 0xef, 0x3b, 0x48, 0xda, 0xee, 0xce, 0x68, 0x4c, 0x27, 0x5d, 0x7e, 0x0a, 0x03, - 0xfa, 0x7d, 0xf0, 0x29, 0x30, 0xa8, 0xbc, 0xff, 0x66, 0x26, 0xc7, 0x9a, 0xf1, 0xe3, 0x8e, 0xc2, - 0xae, 0xa9, 0x3f, 0x26, 0xd8, 0x9f, 0xdd, 0x8e, 0x61, 0xe1, 0xc7, 0x87, 0x07, 0x4e, 0x38, 0x03, - 0xc3, 0xc1, 0xfe, 0x0a, 0x30, 0x95, 0x41, 0x31, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xc6, 0x0c, - 0x00, 0x09, 0x4a, 0xba, 0x20, 0x0e, 0xdd, 0xb5, 0x71, 0x59, 0x9b, 0x48, 0xf7, 0xbd, 0x32, 0x2e, - 0x70, 0xf2, 0xb3, 0x61, 0x13, 0xd1, 0x27, 0xa7, 0xc3, 0xa3, 0xce, 0x3a, 0xbf, 0x7e, 0xc9, 0x87, - 0x8d, 0x2d, 0xa7, 0xa4, 0x10, 0x1d, 0x84, 0x94, 0xcd, 0x82, 0x0b, 0xa6, 0x3e, 0x87, 0x40, 0x2a, - 0x96, 0x04, 0x81, 0x4f, 0x3a, 0x8a, 0xe7, 0x15, 0x54, 0xaf, 0xb8, 0xb8, 0x55, 0x9b, 0x5c, 0x03, - 0x6d, 0xc1, 0x8e, 0x8c, 0xfd, 0x91, 0xb2, 0x44, 0xae, 0xc8, 0x8e, 0x54, 0xb2, 0x24, 0xf8, 0xe7, - 0x63, 0x79, 0x1d, 0x8a, 0x26, 0x04, 0xcc, 0x36, 0x28, 0xf5, 0x18, 0x11, 0x50, 0xa3, 0xf1, 0xfc, - 0xc6, 0x38, 0x63, 0xf0, 0x38, 0x68, 0x9e, 0xf7, 0x8e, 0x16, 0x77, 0xf0, 0x77, 0xf6, 0x59, 0x59, - 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xd6, 0x0c, 0x02, 0x00, 0x42, 0x97, 0xbb, 0x39, 0xe8, 0x03, - 0xce, 0xd5, 0x36, 0x74, 0xc7, 0x31, 0x63, 0x1b, 0x4f, 0x59, 0xd8, 0x86, 0x4a, 0xe7, 0x5b, 0x0e, - 0xb9, 0x07, 0x66, 0xc9, 0xee, 0x38, 0x38, 0x0c, 0x07, 0xf7, 0x3b, 0xa5, 0x2b, 0x3c, 0x23, 0x3f, - 0x0c, 0x7b, 0x3a, 0x77, 0x87, 0xb3, 0x31, 0x7b, 0xcb, 0x2a, 0xf2, 0x27, 0x40, 0x3c, 0x49, 0x00, - 0x7b, 0x02, 0x97, 0xea, 0x0b, 0x68, 0x92, 0x64, 0x40, 0x87, 0x84, 0x16, 0x5d, 0xaa, 0xd6, 0x04, - 0xe2, 0xf8, 0x1b, 0x6c, 0xd0, 0x5b, 0xc0, 0x47, 0x96, 0xa3, 0x43, 0xa0, 0x76, 0x34, 0x63, 0xac, - 0x35, 0xff, 0x87, 0xf5, 0x7e, 0x5f, 0x6f, 0x81, 0x83, 0xcf, 0x83, 0x83, 0xc1, 0xae, 0xee, 0x31, - 0x3a, 0xd9, 0x39, 0xc1, 0xec, 0x58, 0xcd, 0xaa, 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xb6, 0x1c, - 0x04, 0x84, 0x23, 0xaf, 0x99, 0xd5, 0x0c, 0x08, 0x4e, 0xf2, 0x00, 0xf3, 0x8d, 0x76, 0x65, 0xd4, - 0x95, 0x1a, 0x35, 0xb3, 0x28, 0xa2, 0x5d, 0xa3, 0xe6, 0x91, 0x75, 0xa9, 0x55, 0x61, 0xbd, 0x18, - 0xd9, 0xc3, 0xff, 0x69, 0xb2, 0x01, 0xba, 0xfa, 0x42, 0xa0, 0x53, 0xa2, 0xb1, 0x54, 0x2d, 0xd1, - 0x09, 0xf1, 0xbb, 0xc2, 0xe6, 0xa1, 0x5e, 0x01, 0xe9, 0x59, 0x8b, 0x23, 0x84, 0x74, 0x70, 0x47, - 0x6a, 0x6c, 0x2d, 0xee, 0x29, 0x86, 0x24, 0xdd, 0x90, 0x93, 0x8b, 0xfa, 0x89, 0x54, 0xbb, 0xbf, - 0x5e, 0xc9, 0xcf, 0xfd, 0x99, 0x85, 0xf1, 0xad, 0x54, 0xe8, 0x16, 0x48, 0x02, 0x10, 0x40, 0x07, - 0xfc, 0x3c, 0x30, 0x78, 0x7f, 0x03, 0xe6, 0xe2, 0x25, 0x38, 0xc1, 0x6d, 0xc7, 0x2e, 0x33, 0xa0, - 0x94, 0x39, 0x63, 0x0f, 0x72, 0x08, 0xe6, 0x1c, 0x00, 0xcd, 0xe3, 0x69, 0xf7, 0x40, 0x1e, 0x74, - 0x25, 0x44, 0x00, 0x92, 0x99, 0xed, 0x26, 0x50, 0x0b, 0x9f, 0x30, 0x0d, 0x8f, 0x1b, 0xe6, 0xa7, - 0x41, 0x36, 0xd5, 0x43, 0x3a, 0x1d, 0x24, 0x88, 0xc3, 0x28, 0x8f, 0x79, 0x70, 0x2f, 0xe3, 0x70, - 0x9b, 0x91, 0x93, 0xd8, 0xcc, 0x13, 0x9a, 0x15, 0xa1, 0xea, 0xb0, 0x07, 0xbc, 0x69, 0x82, 0x01, - 0xd4, 0xff, 0xc9, 0xbc, 0x58, 0x50, 0xc1, 0x69, 0xa8, 0x88, 0xd9, 0x8f, 0x05, 0x5d, 0xb5, 0xf8, - 0xbd, 0x17, 0x23, 0x9e, 0xae, 0x9f, 0x4c, 0xcd, 0x03, 0x29, 0xcc, 0x77, 0x3e, 0x15, 0x09, 0x15, - 0xc1, 0x5b, 0x8a, 0x59, 0xfe, 0x22, 0x66, 0x54, 0xff, 0x78, 0x3e, 0x3c, 0x3f, 0x07, 0x98, 0x7a, - 0x1f, 0x1f, 0x37, 0x20, 0xca, 0x39, 0xb9, 0x39, 0x95, 0x7a, 0xef, 0x6f, 0x72, 0x08, 0xd6, 0x14, - 0x04, 0x80, 0x10, 0x7b, 0xd8, 0x54, 0xad, 0xc6, 0x86, 0x84, 0x25, 0x8a, 0x23, 0x50, 0x2e, 0x21, - 0x07, 0x97, 0x1a, 0xab, 0xff, 0x1b, 0x4a, 0xab, 0x59, 0xea, 0x72, 0x68, 0x69, 0x76, 0xf3, 0x72, - 0x33, 0x74, 0x9c, 0xd9, 0xe1, 0x98, 0x96, 0x73, 0x92, 0xc6, 0x1f, 0xa1, 0xc7, 0x77, 0x6d, 0xf1, - 0x59, 0xdf, 0x86, 0xbd, 0x2e, 0xcf, 0x61, 0x42, 0x19, 0x0c, 0x08, 0xd5, 0x79, 0xdb, 0x9d, 0xe4, - 0xb5, 0x7a, 0x8e, 0xa7, 0xf2, 0xd8, 0xdd, 0x3b, 0xb0, 0xf3, 0x9f, 0x8c, 0xe8, 0xaa, 0x10, 0x01, - 0x41, 0xd8, 0xf9, 0x89, 0x06, 0xdb, 0xa6, 0x9c, 0x90, 0x2d, 0xa9, 0x50, 0x6b, 0x00, 0xce, 0x24, - 0x3c, 0x0f, 0xe3, 0xf8, 0x9e, 0x0f, 0xc0, 0xf8, 0x46, 0x66, 0xcb, 0xd7, 0x2a, 0xc0, 0x15, 0xd2, - 0x95, 0x7a, 0xef, 0x6f, 0x72, 0x08, 0xd6, 0x14, 0x00, 0xc0, 0x18, 0x52, 0x09, 0x56, 0x62, 0x26, - 0x69, 0x3e, 0x1e, 0xbf, 0x78, 0x75, 0xe9, 0x11, 0x95, 0x8d, 0x93, 0xa2, 0xc4, 0xf5, 0x83, 0x96, - 0xf7, 0x2c, 0x50, 0x79, 0x1c, 0x60, 0xb2, 0x28, 0x3a, 0x71, 0x84, 0x2c, 0xe8, 0xa6, 0x4c, 0xfd, - 0xdd, 0x61, 0x94, 0xaa, 0x41, 0xb8, 0xea, 0x9a, 0x9d, 0x51, 0xe4, 0x0a, 0x7d, 0x14, 0x4c, 0x06, - 0x05, 0x3a, 0xc6, 0x89, 0xad, 0x6e, 0xc1, 0x00, 0x88, 0x30, 0xa5, 0x60, 0x6a, 0x83, 0x5f, 0xc5, - 0xc6, 0x5a, 0xa8, 0xbd, 0x53, 0xcf, 0xe2, 0x15, 0x13, 0x28, 0x72, 0xc6, 0x94, 0x38, 0xe0, 0x02, - 0xb5, 0x98, 0x49, 0xbe, 0x65, 0xf8, 0xbc, 0x74, 0x4c, 0xe0, 0xf0, 0x78, 0x0f, 0xf0, 0xf0, 0x7f, - 0x94, 0xc0, 0x7c, 0xfa, 0xa5, 0x9f, 0x2b, 0x06, 0x95, 0x7a, 0xef, 0x6f, 0x72, 0x08, 0xd6, 0x24, - 0x07, 0x80, 0x4e, 0xc1, 0x89, 0x46, 0x26, 0xc4, 0x5e, 0xaa, 0x70, 0x30, 0xa7, 0xfb, 0x1f, 0x76, - 0xe7, 0xba, 0x40, 0xdf, 0xc2, 0x8b, 0x3a, 0x34, 0xbd, 0xae, 0xb2, 0x0c, 0x47, 0x4d, 0x75, 0xfa, - 0xca, 0x74, 0xf3, 0x9a, 0x93, 0x77, 0xe5, 0x6c, 0x8f, 0x18, 0x15, 0x8e, 0x78, 0xa5, 0xf6, 0xce, - 0x35, 0xd3, 0xc3, 0x92, 0x90, 0xe1, 0x57, 0xb8, 0x00, 0x4f, 0x2b, 0xf1, 0xcd, 0x8c, 0x6f, 0x32, - 0x9f, 0x1c, 0xc8, 0x4d, 0xd9, 0x6e, 0x64, 0xe5, 0xc1, 0xc6, 0x34, 0xad, 0x22, 0x74, 0x01, 0x2f, - 0x38, 0xc7, 0x1c, 0xac, 0x61, 0x21, 0x7a, 0xce, 0x4e, 0x8c, 0x8d, 0x8e, 0x1e, 0xe7, 0x9d, 0x92, - 0xf9, 0xe1, 0xf0, 0xf1, 0x1e, 0x0d, 0x6b, 0xd5, 0x3a, 0x37, 0x88, 0x71, 0xea, 0x38, 0x2e, 0x5e, - 0x95, 0x7a, 0xef, 0x6f, 0x72, 0x08, 0xb6, 0x1c, 0x0c, 0x08, 0x67, 0x4c, 0x0e, 0xad, 0xf1, 0x49, - 0x37, 0xa9, 0x04, 0xaa, 0xff, 0x81, 0xfb, 0xcd, 0xd6, 0xc4, 0x36, 0xcb, 0x0d, 0x4e, 0x54, 0x00, - 0x94, 0xa0, 0x08, 0x2d, 0x8a, 0x3b, 0xbc, 0x48, 0x14, 0x1c, 0x9a, 0x2a, 0x28, 0xa4, 0xb8, 0x44, - 0xfa, 0xa1, 0x5c, 0xc6, 0x38, 0x3b, 0x38, 0x56, 0xa6, 0xbd, 0xa4, 0x23, 0x0d, 0x51, 0x13, 0xd8, - 0x82, 0xb7, 0xd6, 0xb2, 0x0c, 0xb1, 0xbb, 0xee, 0x3c, 0xe9, 0xae, 0x8f, 0xa1, 0x58, 0xd3, 0xa4, - 0xf0, 0xb0, 0xd2, 0x1a, 0x47, 0xdc, 0x23, 0xa9, 0xeb, 0xd6, 0xed, 0x4b, 0xf8, 0x54, 0xd2, 0x6a, - 0x9a, 0xbd, 0xa9, 0xf3, 0x78, 0xd4, 0xec, 0x6c, 0x71, 0xe3, 0xf0, 0xfc, 0x0f, 0x07, 0x0f, 0x1a, - 0x41, 0xd3, 0x83, 0xed, 0x4d, 0x9b, 0x39, 0xb9, 0x86, 0xac, 0xc9, 0x85, 0x72, 0x08, 0xc6, 0x34, - 0x00, 0xc0, 0x50, 0x63, 0x0a, 0xf2, 0xb2, 0x04, 0xfb, 0xa2, 0xad, 0x2c, 0x66, 0x3c, 0x75, 0x78, - 0x71, 0x49, 0x83, 0x23, 0x56, 0x1d, 0x76, 0xf9, 0xfb, 0xdf, 0x6c, 0xf3, 0x8e, 0x7d, 0x79, 0x75, - 0x49, 0xa0, 0xea, 0xbc, 0xd4, 0x64, 0x06, 0x01, 0x4b, 0xae, 0x65, 0x0a, 0xe6, 0xa1, 0x4a, 0xea, - 0x4d, 0x7c, 0xa9, 0x87, 0xb2, 0x00, 0xed, 0xb8, 0xb8, 0x1d, 0x91, 0x66, 0x60, 0xbe, 0x75, 0x8c, - 0x8a, 0xec, 0x52, 0x3b, 0xcd, 0x11, 0x00, 0x86, 0x6b, 0x85, 0xc9, 0xbb, 0xbd, 0x7f, 0x8e, 0x6b, - 0x0d, 0x3c, 0x88, 0xc9, 0x5e, 0x5d, 0x7e, 0x50, 0x49, 0xdb, 0x5e, 0x21, 0x6f, 0x27, 0x47, 0xc7, - 0x88, 0x27, 0x1c, 0x3e, 0x18, 0x3d, 0x43, 0xe1, 0xf1, 0xc1, 0x64, 0xa7, 0x3b, 0x8c, 0x63, 0xd6, - 0x66, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x2c, 0x00, 0x00, 0xd6, 0xba, 0x0a, 0xde, 0x0d, 0x61, - 0x67, 0xd8, 0xe3, 0x78, 0x6a, 0xff, 0x7d, 0x19, 0x94, 0xee, 0x63, 0x36, 0x3a, 0xe5, 0xad, 0xbe, - 0xd7, 0xa9, 0xa6, 0x9e, 0x01, 0x5a, 0x9e, 0x43, 0x1c, 0xa9, 0x0b, 0x96, 0xf7, 0xb7, 0x0d, 0x9e, - 0xfd, 0xfd, 0x1d, 0x8c, 0xe9, 0xdf, 0xe5, 0x75, 0x92, 0x38, 0x51, 0x8b, 0x11, 0x3a, 0x98, 0x91, - 0x48, 0x8d, 0xce, 0xdf, 0xf7, 0xf3, 0x36, 0x84, 0x06, 0x51, 0x0c, 0xa4, 0x04, 0xbb, 0x0e, 0xaa, - 0x3a, 0x32, 0xe6, 0x76, 0x90, 0x6e, 0xcc, 0x32, 0x22, 0xc0, 0x50, 0x53, 0x5a, 0xe4, 0xef, 0x68, - 0xe5, 0x5e, 0x42, 0x3a, 0x92, 0x48, 0xa2, 0x42, 0x92, 0x7f, 0x61, 0xf0, 0xf1, 0xf0, 0x1e, 0x0e, - 0x1e, 0x0c, 0x78, 0xe8, 0x7a, 0x19, 0x83, 0xa0, 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xe6, 0x3c, - 0x00, 0x00, 0x0a, 0xff, 0x7b, 0xe7, 0x5b, 0x83, 0xba, 0x0c, 0x69, 0xdf, 0x15, 0x0f, 0x07, 0xbf, - 0xb0, 0x1d, 0xbc, 0xf4, 0x00, 0xec, 0x08, 0x89, 0x68, 0x80, 0x04, 0xdf, 0x2f, 0x2a, 0xb8, 0xbd, - 0x5b, 0x65, 0x6c, 0x7b, 0x32, 0xf3, 0x9d, 0x55, 0x70, 0xc5, 0xfb, 0xf8, 0xe3, 0x87, 0x28, 0xe7, - 0x71, 0xe7, 0x54, 0xd0, 0x2f, 0xec, 0xb5, 0x75, 0x2b, 0x46, 0xf4, 0x56, 0xac, 0xf6, 0xb6, 0xa0, - 0x28, 0xac, 0x21, 0x0f, 0x7e, 0x13, 0xe1, 0xe8, 0x80, 0x6c, 0x48, 0xd2, 0xb1, 0xcc, 0x2e, 0x65, - 0x01, 0xa8, 0x98, 0x0c, 0x68, 0x7f, 0xb2, 0x05, 0x2e, 0x9e, 0xb1, 0xff, 0x26, 0x55, 0xf0, 0x66, - 0xe7, 0xa1, 0x82, 0x16, 0x60, 0x1c, 0x7c, 0xf8, 0x70, 0x75, 0xa3, 0x84, 0xcd, 0x2b, 0x0a, 0x9d, - 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xf6, 0x3c, 0x00, 0x02, 0x0e, 0x27, 0x82, 0x99, 0xe0, 0xe8, - 0x31, 0xb9, 0xde, 0x8e, 0x62, 0xa3, 0x93, 0x5b, 0x5a, 0x38, 0x66, 0x19, 0x54, 0xb2, 0x40, 0x91, - 0xbc, 0xbb, 0x17, 0x7f, 0x83, 0x0a, 0x3d, 0xe4, 0xc2, 0xbd, 0x75, 0xd3, 0x37, 0x22, 0x13, 0x41, - 0x28, 0xe4, 0x4c, 0x72, 0x8f, 0x26, 0x2e, 0xd9, 0x8f, 0x06, 0xc9, 0x7f, 0xbb, 0x7c, 0x31, 0xb2, - 0xb0, 0x7c, 0xd8, 0xa4, 0xa0, 0x33, 0x0d, 0x11, 0xfe, 0xb7, 0x75, 0xf2, 0x5a, 0x36, 0x1d, 0x1d, - 0x51, 0x78, 0xb5, 0x63, 0x7d, 0xd8, 0x11, 0xf5, 0x11, 0x15, 0x86, 0xde, 0xd6, 0xc7, 0x3d, 0xd2, - 0x3d, 0xd8, 0x50, 0x25, 0x2e, 0x10, 0x8b, 0xf0, 0xc7, 0xfa, 0x66, 0xa7, 0x1f, 0xce, 0x10, 0x53, - 0xb6, 0x41, 0xe6, 0xac, 0xd2, 0xe6, 0x7c, 0x52, 0xa6, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x34, - 0x00, 0x02, 0x11, 0xd1, 0xf6, 0x74, 0xac, 0x18, 0x97, 0x32, 0x76, 0x76, 0x5a, 0x4b, 0x29, 0x5e, - 0xb0, 0xd3, 0x25, 0xb8, 0x55, 0x79, 0x84, 0x50, 0xce, 0x82, 0x68, 0xd1, 0x82, 0xd2, 0x01, 0x50, - 0x2d, 0xb7, 0x83, 0xfd, 0x1d, 0x6b, 0x00, 0x7f, 0x39, 0xc3, 0x51, 0x18, 0x64, 0x87, 0x42, 0xf2, - 0xa3, 0x6d, 0x4c, 0x76, 0x43, 0xe4, 0x04, 0x59, 0xc7, 0x6b, 0xad, 0x01, 0x9d, 0x8c, 0xdc, 0x4e, - 0x88, 0x3e, 0x0b, 0x06, 0xe2, 0xbd, 0xb6, 0x04, 0x77, 0x0b, 0x7a, 0x57, 0x9f, 0x00, 0x64, 0x18, - 0xbe, 0x03, 0x4d, 0x87, 0x13, 0x3f, 0x07, 0x0c, 0x48, 0xf5, 0x42, 0x31, 0x78, 0x67, 0xae, 0xf6, - 0xf8, 0x1e, 0x70, 0xe8, 0x78, 0x1e, 0x1e, 0x07, 0xc0, 0x47, 0xc5, 0x1a, 0xe8, 0xf4, 0x15, 0x45, - 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xf6, 0x3c, 0x00, 0x00, 0x11, 0xb5, 0xe6, 0xc1, 0x00, 0x51, - 0x31, 0x12, 0xd9, 0x99, 0xfb, 0x0a, 0x15, 0x55, 0x1a, 0x94, 0xb5, 0x00, 0x76, 0xe2, 0x1a, 0xcf, - 0xe5, 0x93, 0xfc, 0xe1, 0x09, 0xcf, 0x27, 0xca, 0xd2, 0x88, 0xf5, 0x05, 0xa0, 0xb5, 0x9a, 0x72, - 0xf3, 0xcc, 0x46, 0xdd, 0x6e, 0xd2, 0xd6, 0x21, 0x3a, 0xb0, 0xa4, 0x22, 0x0c, 0xfc, 0xee, 0xc0, - 0x06, 0xba, 0x1c, 0xe5, 0x9f, 0x15, 0xac, 0x63, 0xa5, 0x14, 0xa5, 0x62, 0x4a, 0xbf, 0x0b, 0x74, - 0xde, 0x60, 0x22, 0x2b, 0xb7, 0x1b, 0x70, 0x45, 0xb8, 0xa8, 0x9d, 0xb0, 0x76, 0xf4, 0x51, 0x2c, - 0xc5, 0x2e, 0xeb, 0x1b, 0x76, 0x44, 0x3b, 0x63, 0x2f, 0x69, 0xa5, 0x20, 0x3b, 0x87, 0x8e, 0x78, - 0x7c, 0x3c, 0x1e, 0x86, 0xb8, 0xe6, 0x98, 0x5d, 0x66, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xf6, 0x3c, - 0x0a, 0xff, 0xf1, 0x47, 0xd8, 0x22, 0x24, 0x56, 0xcc, 0x72, 0xf5, 0x72, 0x9c, 0xd8, 0x45, 0xb2, - 0x33, 0x94, 0xc7, 0xba, 0x3c, 0xb2, 0x1d, 0x7b, 0xf6, 0x6c, 0xc3, 0x5b, 0xe3, 0xeb, 0x71, 0xc8, - 0x62, 0xa5, 0xe9, 0x65, 0xd9, 0x67, 0x96, 0x6b, 0xd3, 0x77, 0xbf, 0xb0, 0x69, 0xce, 0xf3, 0xb2, - 0x95, 0xfc, 0x9d, 0xf5, 0xc1, 0x94, 0x33, 0xd7, 0x83, 0x10, 0x17, 0xbb, 0xb8, 0x58, 0x78, 0x0e, - 0x9f, 0xd0, 0xa8, 0xaf, 0x06, 0xfb, 0xb7, 0x4f, 0xad, 0x46, 0x84, 0x45, 0x11, 0xf0, 0x07, 0xe7, - 0xee, 0x1e, 0x3a, 0x7b, 0xe5, 0x53, 0xcf, 0x81, 0xd2, 0x55, 0x55, 0xfb, 0xf2, 0x72, 0x47, 0x04, - 0xc6, 0xfb, 0x38, 0xf1, 0xe0, 0x39, 0x3c, 0x0f, 0x8f, 0xc5, 0x18, 0x69, 0x17, 0x18, 0x51, 0x84, - 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xe6, 0x3c, 0x00, 0x00, 0x4e, 0x9e, 0xb3, 0x62, 0xa1, 0x80, - 0x3c, 0xee, 0x6e, 0xcf, 0x55, 0xf6, 0xa5, 0xc3, 0x08, 0x2e, 0x79, 0xd4, 0xc2, 0x36, 0x30, 0x02, - 0xe4, 0xd9, 0x0e, 0x73, 0xd6, 0x03, 0x44, 0x6b, 0x47, 0x7c, 0x0c, 0xac, 0x1a, 0xa0, 0xe6, 0xf8, - 0xf7, 0x2e, 0xc9, 0x30, 0xa4, 0xe2, 0x16, 0x07, 0x6f, 0x02, 0x83, 0x3f, 0xba, 0x00, 0x96, 0xe4, - 0x5a, 0xca, 0x2e, 0xde, 0x08, 0xee, 0x91, 0xcd, 0x96, 0x84, 0x6f, 0xd0, 0xb9, 0xf7, 0x7b, 0x9d, - 0xa6, 0x07, 0x18, 0x93, 0x43, 0x80, 0x02, 0x30, 0xd9, 0x23, 0x47, 0xc8, 0x18, 0x3d, 0xb6, 0x1c, - 0x69, 0x9b, 0x04, 0x58, 0xe0, 0x7b, 0xd4, 0x33, 0xc6, 0x36, 0x3c, 0x11, 0xd0, 0x37, 0x0d, 0x82, - 0xe3, 0xcd, 0x62, 0xb6, 0x42, 0x8c, 0x5d, 0x3c, 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x3c, - 0x00, 0x06, 0xa8, 0xec, 0x30, 0xf8, 0x02, 0xa1, 0x07, 0xfa, 0x5b, 0x5c, 0x8c, 0xc3, 0x42, 0x0c, - 0xe1, 0x29, 0xa5, 0x53, 0x1e, 0x51, 0x10, 0x26, 0x71, 0x87, 0x44, 0xaf, 0xee, 0x39, 0xaf, 0x5f, - 0x3f, 0xdd, 0x78, 0xec, 0xc0, 0x1c, 0xad, 0xf2, 0xb9, 0x85, 0x42, 0x67, 0x5d, 0x89, 0x9a, 0x09, - 0x80, 0x84, 0xb0, 0x18, 0xd6, 0x31, 0x00, 0x32, 0x0b, 0x3d, 0x09, 0x81, 0x4c, 0x0e, 0xcf, 0x17, - 0x6f, 0xaa, 0x1b, 0x05, 0x81, 0x33, 0xa8, 0x98, 0x2f, 0x59, 0xbc, 0xf7, 0x3b, 0x6f, 0x65, 0x0f, - 0x88, 0x3f, 0xeb, 0x50, 0x44, 0xc0, 0x9c, 0xe7, 0xa5, 0xf0, 0x80, 0xa0, 0x8e, 0x27, 0xe1, 0xb7, - 0xd1, 0x1e, 0xf0, 0x6e, 0x83, 0xf0, 0xdf, 0xbe, 0x1d, 0x1c, 0xf2, 0xdc, 0x10, 0x2e, 0xb1, 0x6e, - 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x3c, 0x00, 0xc3, 0x46, 0xcc, 0xea, 0x31, 0xbc, 0xda, - 0x50, 0xd5, 0xd8, 0x31, 0xdb, 0xd6, 0xfa, 0x60, 0x5b, 0xf3, 0x68, 0x9c, 0xd3, 0x1c, 0x21, 0x39, - 0x8d, 0x20, 0x7e, 0x2b, 0x5e, 0xbb, 0x55, 0x62, 0x37, 0x9d, 0xbc, 0x96, 0xd7, 0x08, 0x18, 0x69, - 0x94, 0x6c, 0x3b, 0xed, 0x7a, 0xb9, 0xe4, 0xb4, 0x31, 0x38, 0x6b, 0x80, 0x00, 0x32, 0x83, 0x71, - 0x2e, 0x4c, 0xc4, 0xa8, 0x50, 0xf0, 0xce, 0xe8, 0xc6, 0xcc, 0x22, 0x79, 0x6b, 0x89, 0xed, 0x9a, - 0x3d, 0x81, 0x9e, 0x42, 0x0f, 0x88, 0x28, 0x35, 0xcb, 0x2c, 0x24, 0xf8, 0x09, 0x28, 0x1a, 0x43, - 0x8b, 0x4f, 0xb3, 0x90, 0x55, 0x1f, 0x16, 0x22, 0xf0, 0x09, 0xcc, 0x3d, 0xa7, 0x0e, 0xca, 0x71, - 0xe9, 0x0a, 0x27, 0x0e, 0x72, 0x79, 0x8b, 0x76, 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x3c, - 0x00, 0x07, 0x5f, 0xc8, 0xe3, 0xa6, 0xd0, 0x3b, 0x8e, 0x82, 0x7a, 0xd8, 0x1a, 0x9f, 0x9f, 0x8a, - 0x9c, 0x91, 0x57, 0x5c, 0x78, 0x55, 0x30, 0x77, 0x38, 0xe1, 0x3a, 0x34, 0x48, 0x9b, 0x71, 0xdf, - 0x4f, 0xcf, 0x6b, 0x8a, 0xbe, 0xd6, 0x3e, 0x4c, 0x70, 0xc5, 0x75, 0x1c, 0x66, 0x3a, 0xa7, 0x49, - 0x24, 0x92, 0xb3, 0x00, 0x12, 0xda, 0xab, 0x09, 0x82, 0x4d, 0x33, 0x74, 0x8c, 0xe7, 0x7c, 0x3e, - 0x90, 0xf2, 0x88, 0x96, 0xa9, 0xeb, 0x40, 0x7a, 0x77, 0x28, 0xad, 0x6c, 0xf5, 0xb8, 0x80, 0x34, - 0x5f, 0x81, 0x47, 0xa2, 0x42, 0xc8, 0x70, 0xf4, 0x7f, 0x85, 0xd5, 0x93, 0x45, 0x1f, 0x47, 0x19, - 0xc4, 0xc8, 0x00, 0x71, 0x13, 0xec, 0xb2, 0xe2, 0x60, 0x70, 0xce, 0xb4, 0x41, 0xb5, 0x92, 0xe1, - 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xe6, 0x3c, 0x00, 0x00, 0x84, 0xbd, 0x00, 0xfc, 0x0a, 0xf7, - 0xb4, 0x15, 0x10, 0xe4, 0xe0, 0xad, 0x2d, 0x1f, 0x1c, 0x7c, 0x1f, 0xeb, 0xa9, 0x43, 0x10, 0x58, - 0x41, 0x1e, 0x99, 0x52, 0x0d, 0x41, 0xf3, 0x1d, 0xec, 0x63, 0xc2, 0xcc, 0xe2, 0x8b, 0xc1, 0x09, - 0xc6, 0x3f, 0xd8, 0xbf, 0x3e, 0x08, 0x5e, 0x2e, 0x7a, 0x5a, 0x23, 0xe3, 0xb7, 0x53, 0x1c, 0x9e, - 0x27, 0xe5, 0x3d, 0x04, 0x5a, 0xdc, 0xa3, 0xc5, 0x94, 0x6b, 0xcb, 0x09, 0x1e, 0x71, 0x29, 0x47, - 0xd3, 0xbe, 0x4f, 0x08, 0xbe, 0x07, 0xf5, 0xbf, 0x98, 0xa7, 0xbc, 0xc5, 0x25, 0x51, 0xb7, 0x24, - 0x29, 0x21, 0x45, 0x41, 0x11, 0x0d, 0x40, 0x0f, 0x87, 0x78, 0xf4, 0xfc, 0x9f, 0x03, 0xc0, 0x25, - 0xd6, 0xb3, 0xe6, 0x8e, 0x2b, 0xcd, 0xc5, 0x59, 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xd6, 0x3c, - 0x00, 0x01, 0x96, 0x93, 0x10, 0xac, 0x08, 0xb7, 0x3e, 0xc4, 0x99, 0x57, 0x08, 0x27, 0x1c, 0x8c, - 0x85, 0x3b, 0xb2, 0x7a, 0x65, 0x12, 0x36, 0x02, 0x13, 0x5a, 0x4b, 0x74, 0x08, 0xd4, 0x2f, 0xcb, - 0xe7, 0x6d, 0x1f, 0xe0, 0xa7, 0x35, 0x71, 0x09, 0x4b, 0x1e, 0xe5, 0x46, 0xc4, 0xd1, 0x23, 0x69, - 0xa8, 0x36, 0xa6, 0xaa, 0x17, 0x9d, 0x00, 0x03, 0xc5, 0x6e, 0xc2, 0x22, 0x2c, 0x97, 0xbe, 0x22, - 0xa2, 0x28, 0xb7, 0xfe, 0xd3, 0xdb, 0x97, 0x85, 0x75, 0x8f, 0x11, 0x55, 0xef, 0x2c, 0xa9, 0xd1, - 0xbe, 0x97, 0x3d, 0x3b, 0x27, 0x66, 0xcc, 0xb7, 0x2e, 0x2f, 0xe8, 0x13, 0x87, 0x02, 0x60, 0xfd, - 0x39, 0x3c, 0x9b, 0x9f, 0xd1, 0xd8, 0xde, 0x51, 0x7e, 0xb8, 0xc6, 0x15, 0xc2, 0xf3, 0x49, 0xce, - 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xb6, 0x3c, 0x00, 0xc0, 0xea, 0xe4, 0x95, 0x80, 0x8d, 0x68, - 0xa0, 0x21, 0xd3, 0xb5, 0xc1, 0xda, 0x11, 0x65, 0x6e, 0xb6, 0xe1, 0xbf, 0x2d, 0xb8, 0x05, 0x78, - 0x44, 0x1f, 0xcf, 0x65, 0xce, 0x0f, 0x1e, 0x00, 0x61, 0x6d, 0xa4, 0x8f, 0x06, 0x03, 0xfb, 0x8d, - 0x7d, 0x9a, 0xbc, 0xf1, 0xf4, 0x24, 0x49, 0xfb, 0x12, 0x82, 0x12, 0xae, 0x1f, 0x5f, 0x00, 0xe8, - 0x79, 0x1a, 0xc1, 0x95, 0x79, 0x91, 0xec, 0x22, 0x15, 0xea, 0x8e, 0xb8, 0x41, 0x8e, 0xd2, 0xd4, - 0xac, 0x90, 0x3a, 0xfe, 0xad, 0xc8, 0x1e, 0x7f, 0x54, 0x7f, 0x5c, 0xe6, 0x78, 0xef, 0xdd, 0xe6, - 0x7d, 0x53, 0x46, 0x8b, 0x8b, 0xf4, 0x38, 0xce, 0x13, 0xd3, 0x78, 0xf0, 0x3c, 0x3f, 0x81, 0xb2, - 0x70, 0x98, 0x73, 0x85, 0xab, 0xf3, 0xc0, 0x41, 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xe6, 0x3c, - 0x04, 0x80, 0xaa, 0x12, 0x97, 0xdc, 0xaa, 0x03, 0xa0, 0x77, 0xb1, 0x92, 0x08, 0x81, 0x46, 0x0c, - 0x6a, 0xd0, 0x59, 0x2f, 0x45, 0x77, 0xcc, 0xea, 0x25, 0x2a, 0xe3, 0xc4, 0xef, 0x93, 0x94, 0x07, - 0x04, 0xa9, 0x83, 0xbf, 0x71, 0x40, 0xa0, 0x0e, 0xbf, 0x89, 0x20, 0xe4, 0x0c, 0x33, 0xd5, 0x46, - 0xce, 0xb3, 0x82, 0xe6, 0xf5, 0x70, 0x4e, 0x30, 0x84, 0xb0, 0xd5, 0x7f, 0x41, 0x7c, 0x37, 0x6a, - 0x6e, 0xab, 0xf3, 0x46, 0x8d, 0xa8, 0x50, 0x4e, 0x42, 0xb8, 0xaa, 0xa7, 0x51, 0x60, 0x73, 0x64, - 0x89, 0xd0, 0xac, 0x08, 0x59, 0x36, 0xce, 0x12, 0x3f, 0xb5, 0x5c, 0x1a, 0x63, 0xf5, 0xb6, 0x41, - 0x19, 0x98, 0xf8, 0x71, 0xe1, 0x9c, 0xe8, 0xf0, 0x71, 0x56, 0x0e, 0x24, 0x34, 0xbd, 0xdd, 0x24, - 0x86, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xc6, 0x3c, 0x04, 0x80, 0x8a, 0xc7, 0x95, 0x58, 0x0d, 0x38, - 0xb6, 0xc4, 0xc1, 0xd1, 0x23, 0x9a, 0x65, 0x8e, 0x7a, 0xd0, 0xcc, 0xdf, 0x30, 0xd4, 0x93, 0xd5, - 0x99, 0xf4, 0xa3, 0x34, 0xd7, 0xae, 0x5c, 0xb9, 0x4e, 0xf5, 0x3d, 0x85, 0x58, 0xff, 0x24, 0x04, - 0xba, 0xd7, 0x3e, 0xf8, 0xba, 0x43, 0x83, 0x08, 0x4d, 0xaa, 0x8d, 0x8a, 0x95, 0x0b, 0x1c, 0x00, - 0x00, 0x24, 0x0e, 0xfe, 0x14, 0xa3, 0xd9, 0x89, 0x57, 0x8c, 0xa6, 0x0a, 0x5a, 0x93, 0xaa, 0x9f, - 0xc0, 0xf7, 0x0f, 0x2e, 0xfa, 0xb1, 0xff, 0x22, 0x93, 0x32, 0xce, 0x42, 0x13, 0x17, 0x06, 0x0f, - 0xd1, 0xa0, 0xdb, 0xcb, 0x87, 0xe0, 0xe0, 0x84, 0x81, 0xc2, 0xc3, 0xe1, 0xe0, 0xf0, 0x3e, 0x7b, - 0x83, 0x9a, 0xb8, 0xf2, 0x76, 0x2f, 0x0c, 0x52, 0xa6, 0x62, 0x7e, 0x65, 0x72, 0x08, 0xc6, 0x3c, - 0x0d, 0xd9, 0x17, 0x1d, 0x9a, 0xd5, 0x20, 0xac, 0xd6, 0x8e, 0xd8, 0x3a, 0x75, 0x82, 0x41, 0x18, - 0x7d, 0xa2, 0x7d, 0x11, 0xd0, 0x21, 0x95, 0xe5, 0x11, 0x3a, 0x54, 0xb2, 0xda, 0x82, 0x94, 0xe1, - 0x2b, 0xb7, 0x6a, 0xca, 0xed, 0x38, 0x57, 0x99, 0x72, 0x64, 0x07, 0x03, 0x34, 0xb1, 0x34, 0x8b, - 0x0a, 0xe1, 0xce, 0xa2, 0x38, 0x53, 0xfe, 0x0c, 0x37, 0x99, 0x2e, 0x27, 0xa1, 0xc5, 0x3c, 0x04, - 0x28, 0xf1, 0xaa, 0x54, 0x63, 0x4b, 0x82, 0x25, 0x19, 0xab, 0xa0, 0x5d, 0x32, 0x65, 0x56, 0x64, - 0xc7, 0x3b, 0x65, 0x53, 0x33, 0x35, 0x55, 0x52, 0xaa, 0xaa, 0xa6, 0x66, 0xaa, 0xaa, 0xa6, 0x66, - 0x65, 0x55, 0x54, 0xcc, 0xcc, 0xcc, 0xca, 0xaa, 0x99, 0x99, 0x99, 0x99, 0x95, 0x56, 0x66, 0x66, - 0x45, 0xcf, 0xee, 0x5c, 0xf2, 0x0b, 0xa6, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0x93, 0xe5, 0x28, 0x34, 0x00, 0x00, 0x04, -}; diff --git a/apps/leaudio_broadcaster/src/main.c b/apps/leaudio_broadcaster/src/main.c deleted file mode 100644 index 52033250e1..0000000000 --- a/apps/leaudio_broadcaster/src/main.c +++ /dev/null @@ -1,404 +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. - */ - -#include "console/console.h" -#include "config/config.h" - -#include "nimble/ble.h" -#include "host/ble_hs.h" -#include "host/util/util.h" - -#include "audio/ble_audio_broadcast_source.h" -#include "audio/ble_audio.h" -#include "host/ble_iso.h" - -#include "hal/hal_gpio.h" -#include "bsp/bsp.h" - -#include "audio_data.h" - -#define BROADCAST_ADV_INSTANCE 1 -#define BROADCAST_MAX_SDU 120 -#define BROADCAST_SDU_INTVL 10000 -#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_48000_HZ - -#define BROADCASTER_INTERRUPT_TASK_PRIO 4 -#define BROADCASTER_INTERRUPT_TASK_STACK_SZ 512 - -static uint8_t id_addr_type; - -static struct ble_audio_base broadcaster_base; -static struct ble_audio_big_subgroup big_subgroup; - -static os_membuf_t bis_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BROADCASTER_CHAN_NUM), - sizeof(struct ble_audio_bis)) -]; -static struct os_mempool bis_pool; - -static os_membuf_t codec_spec_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BISES) * 2, 19) -]; -static struct os_mempool codec_spec_pool; - -static uint16_t bis_handles[MYNEWT_VAL(BROADCASTER_CHAN_NUM)]; -/* The timer callout */ -static struct os_callout audio_broadcast_callout; - -static int audio_data_offset; -static struct os_task broadcaster_interrupt_task_str; -static struct os_eventq broadcaster_interrupt_eventq; -static os_stack_t broadcaster_interrupt_task_stack[BROADCASTER_INTERRUPT_TASK_STACK_SZ]; - -static void -broadcaster_interrupt_task(void *arg) -{ - while (1) { - os_eventq_run(&broadcaster_interrupt_eventq); - } -} - -static void -broadcast_stop_ev_cb(struct os_event *ev) -{ - ble_audio_broadcast_stop(BROADCAST_ADV_INSTANCE); - ble_audio_broadcast_destroy(BROADCAST_ADV_INSTANCE); -} - -static struct os_event broadcast_stop_ev = { - .ev_cb = broadcast_stop_ev_cb, -}; - -static void -broadcaster_gpio_irq(void *arg) -{ - os_eventq_put(&broadcaster_interrupt_eventq, &broadcast_stop_ev); -} - -static void -audio_broadcast_event_cb(struct os_event *ev) -{ - assert(ev != NULL); - uint32_t ev_start_time = os_cputime_ticks_to_usecs(os_cputime_get32()); - - -#if MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 - if (audio_data_offset + BROADCAST_MAX_SDU >= sizeof(audio_data)) { - audio_data_offset = 0; - } - - ble_iso_tx(bis_handles[0], (void *)(audio_data + audio_data_offset), - BROADCAST_MAX_SDU); - ble_iso_tx(bis_handles[1], (void *)(audio_data + audio_data_offset), - BROADCAST_MAX_SDU); -#else - if (audio_data_offset + 2 * BROADCAST_MAX_SDU >= sizeof(audio_data)) { - audio_data_offset = 0; - } - - uint8_t lr_payload[BROADCAST_MAX_SDU * 2]; - memcpy(lr_payload, audio_data + audio_data_offset, BROADCAST_MAX_SDU); - memcpy(lr_payload + BROADCAST_MAX_SDU, audio_data + audio_data_offset, - BROADCAST_MAX_SDU); - ble_iso_tx(bis_handles[0], (void *)(lr_payload), - BROADCAST_MAX_SDU * 2); -#endif - audio_data_offset += BROADCAST_MAX_SDU; - - /** Use cputime to time BROADCAST_SDU_INTVL, as these ticks are more - * accurate than os_time ones. This assures that we do not push - * LC3 data to ISO before interval, which could lead to - * controller running out of buffers. This is only needed because - * we already have coded data in an array - in real world application - * we usually wait for new audio to arrive, and lose time to code it too. - */ - while (os_cputime_ticks_to_usecs(os_cputime_get32()) - ev_start_time < - (BROADCAST_SDU_INTVL)); - - os_callout_reset(&audio_broadcast_callout, 0); -} -static int -broadcast_audio() -{ - os_callout_reset(&audio_broadcast_callout, 0); - - return 0; -} - -static int -iso_event(struct ble_iso_event *event, void *arg) -{ - int i; - - switch (event->type) { - case BLE_ISO_EVENT_BIG_CREATE_COMPLETE: - console_printf("BIG created\n"); - if (event->big_created.desc.num_bis > - MYNEWT_VAL(BROADCASTER_CHAN_NUM)) { - return BLE_HS_EINVAL; - } - for (i = 0; i < MYNEWT_VAL(BROADCASTER_CHAN_NUM); i++) { - bis_handles[i] = event->big_created.desc.conn_handle[i]; - } - broadcast_audio(); - return 0; - case BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE: - console_printf("BIG terminated\n"); - return 0; - default: - return BLE_HS_ENOTSUP; - } -} - -static void -broadcaster_init() -{ - int rc; - - os_callout_init(&audio_broadcast_callout, os_eventq_dflt_get(), - audio_broadcast_event_cb, NULL); - - assert(MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 0); - - rc = os_mempool_init(&bis_pool, MYNEWT_VAL(BROADCASTER_CHAN_NUM), - sizeof(struct ble_audio_bis), bis_mem, - "bis_pool"); - assert(rc == 0); - - rc = os_mempool_init(&codec_spec_pool, - MYNEWT_VAL(BLE_ISO_MAX_BISES) * 2, 19, - codec_spec_mem, "codec_spec_pool"); - assert(rc == 0); -} - -static int -base_create() -{ -#if MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 - struct ble_audio_bis *bis_left; - struct ble_audio_bis *bis_right; - uint8_t codec_spec_config_left_chan[] = - BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, - BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS, - BLE_AUDIO_LOCATION_FRONT_LEFT, - BROADCAST_MAX_SDU, ); - uint8_t codec_spec_config_right_chan[] = - BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, - BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS, - BLE_AUDIO_LOCATION_FRONT_RIGHT, - BROADCAST_MAX_SDU, ); -#else - uint16_t chan_loc = BLE_AUDIO_LOCATION_FRONT_LEFT | - BLE_AUDIO_LOCATION_FRONT_RIGHT; - uint8_t codec_spec_config[] = - BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, - BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS, - chan_loc, - BROADCAST_MAX_SDU * 2, ); - - struct ble_audio_bis *bis; -#endif - broadcaster_base.broadcast_id = 0x42; - broadcaster_base.presentation_delay = 20000; - - big_subgroup.bis_cnt = MYNEWT_VAL(BROADCASTER_CHAN_NUM); - - /** LC3 */ - big_subgroup.codec_id.format = 0x06; - - big_subgroup.codec_spec_config_len = 0; -#if MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 - bis_left = os_memblock_get(&bis_pool); - if (!bis_left) { - return BLE_HS_ENOMEM; - } - - bis_left->codec_spec_config = os_memblock_get(&codec_spec_pool); - memcpy(bis_left->codec_spec_config, - codec_spec_config_left_chan, - sizeof(codec_spec_config_left_chan)); - bis_left->codec_spec_config_len = sizeof(codec_spec_config_left_chan); - bis_left->idx = 1; - - bis_right = os_memblock_get(&bis_pool); - if (!bis_right) { - return BLE_HS_ENOMEM; - } - - bis_right->codec_spec_config = os_memblock_get(&codec_spec_pool); - memcpy(bis_right->codec_spec_config, - codec_spec_config_right_chan, - sizeof(codec_spec_config_right_chan)); - bis_right->codec_spec_config_len = sizeof(codec_spec_config_right_chan); - bis_right->idx = 2; - - STAILQ_INSERT_HEAD(&big_subgroup.bises, bis_left, next); - STAILQ_INSERT_TAIL(&big_subgroup.bises, bis_right, next); -#else - bis = os_memblock_get(&bis_pool); - if (!bis) { - return BLE_HS_ENOMEM; - } - - bis->codec_spec_config = os_memblock_get(&codec_spec_pool); - memcpy(bis->codec_spec_config, - codec_spec_config, - sizeof(codec_spec_config)); - bis->codec_spec_config_len = sizeof(codec_spec_config); - STAILQ_INSERT_HEAD(&big_subgroup.bises, bis, next); -#endif - - STAILQ_INSERT_HEAD(&broadcaster_base.subs, &big_subgroup, next); - broadcaster_base.num_subgroups++; - return 0; -} - -static int -broadcast_destroy_fn(struct ble_audio_base *base, void *args) -{ - struct ble_audio_bis *bis; - - STAILQ_FOREACH(bis, &big_subgroup.bises, next) { - os_memblock_put(&codec_spec_pool, bis->codec_spec_config); - os_memblock_put(&bis_pool, bis); - } - - memset(&big_subgroup, 0, sizeof(big_subgroup)); - - return 0; -} - -static int -broadcast_create() -{ - struct ble_gap_periodic_adv_params periodic_params = { - .itvl_min = 30, - .itvl_max = 30, - }; - - struct ble_gap_ext_adv_params extended_params = { - .itvl_min = 50, - .itvl_max = 50, - .scannable = 0, - .connectable = 0, - .primary_phy = BLE_HCI_LE_PHY_1M, - .secondary_phy = BLE_HCI_LE_PHY_2M, - .own_addr_type = id_addr_type, - .sid = BROADCAST_ADV_INSTANCE, - }; - - static struct ble_iso_big_params big_params = { - .sdu_interval = BROADCAST_SDU_INTVL, - .max_sdu = MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 ? - BROADCAST_MAX_SDU : BROADCAST_MAX_SDU * 2, - .max_transport_latency = BROADCAST_SDU_INTVL / 1000, - .rtn = 0, - .phy = BLE_HCI_LE_PHY_2M, - .packing = 0, - .framing = 0, - .encryption = 0, - }; - - struct ble_broadcast_create_params create_params = { - .base = &broadcaster_base, - .extended_params = &extended_params, - .periodic_params = &periodic_params, - .name = MYNEWT_VAL(BROADCASTER_BROADCAST_NAME), - .adv_instance = BROADCAST_ADV_INSTANCE, - .big_params = &big_params, - .svc_data = NULL, - .svc_data_len = 0, - }; - - return ble_audio_broadcast_create(&create_params, - broadcast_destroy_fn, - NULL, - NULL); -} - -static int -broadcast_start() -{ - return ble_audio_broadcast_start(BROADCAST_ADV_INSTANCE, iso_event, NULL); -} - -static void -on_sync(void) -{ - int rc; - - console_printf("Bluetooth initialized\n"); - - /* Make sure we have proper identity address set (public preferred) */ - rc = ble_hs_util_ensure_addr(0); - assert(rc == 0); - - /* configure global address */ - rc = ble_hs_id_infer_auto(0, &id_addr_type); - assert(rc == 0); - - broadcaster_init(); - - rc = base_create(); - assert(rc == 0); - - rc = broadcast_create(); - assert(rc == 0); - - rc = broadcast_start(); - assert(rc == 0); -} - -/* - * main - * - * The main task for the project. This function initializes the packages, - * then starts serving events from default event queue. - * - * @return int NOTE: this function should never return! - */ -int -mynewt_main(int argc, char **argv) -{ - /* Initialize OS */ - sysinit(); - - console_printf("LE Audio Broadcast sample application\n"); - - /* Set sync callback */ - ble_hs_cfg.sync_cb = on_sync; - - os_eventq_init(&broadcaster_interrupt_eventq); - os_task_init(&broadcaster_interrupt_task_str, "broadcaster_interrupt_task", - broadcaster_interrupt_task, NULL, - BROADCASTER_INTERRUPT_TASK_PRIO, OS_WAIT_FOREVER, - broadcaster_interrupt_task_stack, - BROADCASTER_INTERRUPT_TASK_STACK_SZ); - - hal_gpio_irq_init(BUTTON_3, broadcaster_gpio_irq, NULL, - HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_UP); - hal_gpio_irq_enable(BUTTON_3); - - /* As the last thing, process events from default event queue */ - while (1) { - os_eventq_run(os_eventq_dflt_get()); - } - - return 0; -} diff --git a/apps/leaudio_broadcaster/syscfg.yml b/apps/leaudio_broadcaster/syscfg.yml deleted file mode 100644 index cffb828ed3..0000000000 --- a/apps/leaudio_broadcaster/syscfg.yml +++ /dev/null @@ -1,66 +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. - -syscfg.defs: - BROADCASTER_CHAN_NUM: 2 - BROADCASTER_BROADCAST_NAME: '"NimBLE Broadcast"' - -syscfg.vals: - CONSOLE_IMPLEMENTATION: full - LOG_IMPLEMENTATION: full - STATS_IMPLEMENTATION: full - - # Disable not used GAP roles (we only do non-connectable - # advertising here) - BLE_ROLE_BROADCASTER: 1 - BLE_ROLE_CENTRAL: 0 - BLE_ROLE_OBSERVER: 0 - BLE_ROLE_PERIPHERAL: 0 - - # Enable Extended Advertising - BLE_EXT_ADV: 1 - - # Enable Periodic Advertising - BLE_PERIODIC_ADV: 1 - - # Max advertising data size - BLE_EXT_ADV_MAX_SIZE: 261 - - # Number of multi-advertising instances. Note that due - # to historical reasonds total number of advertising - # instances is BLE_MULTI_ADV_INSTANCES + 1 as instance - # 0 is always available - BLE_MULTI_ADV_INSTANCES: 1 - - # Controller uses msys pool for storing advertising data and scan responses. - # Since we advertise a lot of data (~6k in total) at the same time we need - # to increase block count. - MSYS_1_BLOCK_COUNT: 32 - - BLE_VERSION: 54 - BLE_AUDIO: 1 - BLE_ISO: 1 - BLE_ISO_BROADCAST_SOURCE: 1 - BLE_ISO_MAX_BIGS: 1 - BLE_ISO_MAX_BISES: 2 - -syscfg.vals.BSP_NRF5340: - MCU_MPU_ENABLE: 1 - MCU_CACHE_ENABLED: 1 - BSP_NRF5340_NET_ENABLE: 1 - NRF5340_EMBED_NET_CORE: 1 - NET_CORE_IMAGE_TARGET_NAME: "@apache-mynewt-nimble/targets/nordic_pca10095_net-blehci_broadcaster" From 61a947a5d566a30d47e3f662ad85d23942b3fc21 Mon Sep 17 00:00:00 2001 From: Piotr Date: Thu, 28 Nov 2024 10:10:15 +0100 Subject: [PATCH 1148/1333] apps: bttester: fix uart settings uart_pipe.c from bttester app was using values copied directly from uart_console.c e.g. CONSOLE_UART_DEV, CONSOLE_UART_BAUD. This caused BTP malfunction when trying to receive logs over UART from bttester. BTTESTER_UART variables are now added to syscfg and applied in uart_pipe.c --- apps/bttester/src/uart_pipe.c | 8 ++++---- apps/bttester/syscfg.yml | 12 ++++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/apps/bttester/src/uart_pipe.c b/apps/bttester/src/uart_pipe.c index 223a78975f..ac7f11d6dd 100644 --- a/apps/bttester/src/uart_pipe.c +++ b/apps/bttester/src/uart_pipe.c @@ -48,7 +48,7 @@ static struct uart_pipe_ring cr_rx; static uint8_t cr_rx_buf[MYNEWT_VAL(BTTESTER_BTP_DATA_SIZE_MAX)]; static volatile bool uart_console_rx_stalled; -struct os_event rx_ev; +static struct os_event rx_ev; static inline int inc_and_wrap(int i, int max) @@ -243,11 +243,11 @@ int bttester_pipe_init(void) { struct uart_conf uc = { - .uc_speed = MYNEWT_VAL(CONSOLE_UART_BAUD), + .uc_speed = MYNEWT_VAL(BTTESTER_UART_BAUD), .uc_databits = 8, .uc_stopbits = 1, .uc_parity = UART_PARITY_NONE, - .uc_flow_ctl = MYNEWT_VAL(CONSOLE_UART_FLOW_CONTROL), + .uc_flow_ctl = MYNEWT_VAL(BTTESTER_UART_FLOW_CONTROL), .uc_tx_char = uart_console_tx_char, .uc_rx_char = uart_console_rx_char, }; @@ -263,7 +263,7 @@ bttester_pipe_init(void) if (!uart_dev) { uart_dev = - (struct uart_dev *) os_dev_open(MYNEWT_VAL(CONSOLE_UART_DEV), + (struct uart_dev *) os_dev_open(MYNEWT_VAL(BTTESTER_UART_DEV), OS_TIMEOUT_NEVER, &uc); if (!uart_dev) { return -1; diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 140b664e72..11daaae8db 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -19,6 +19,18 @@ # Package: apps/blemesh syscfg.defs: + BTTESTER_UART_BAUD: + description: 'Console UART baud rate.' + value: '115200' + + BTTESTER_UART_FLOW_CONTROL: + description: 'Console UART flow control.' + value: 'UART_FLOW_CTL_RTS_CTS' + + BTTESTER_UART_DEV: + description: 'Console UART device.' + value: '"uart0"' + BTTESTER_PIPE_UART: description: 'Set communication pipe to UART' value: 1 From a04e52e610bcf0cf791c6e2df75ce347d679501b Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 26 Nov 2024 12:04:12 +0100 Subject: [PATCH 1149/1333] apps: auracast_usb: Fix missing BLE_AUDIO option enabled This fixes missing BLE_AUDIO option that has to be enabled to use ble_audio_broadcast_source functionality. --- apps/auracast_usb/syscfg.yml | 2 ++ nimble/host/audio/src/ble_audio_broadcast_source.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/auracast_usb/syscfg.yml b/apps/auracast_usb/syscfg.yml index 9c44c9d438..56ada080db 100644 --- a/apps/auracast_usb/syscfg.yml +++ b/apps/auracast_usb/syscfg.yml @@ -101,6 +101,8 @@ syscfg.vals: BLE_ISO_MAX_BIGS: 1 BLE_ISO_MAX_BISES: 2 + BLE_AUDIO: 1 + USBD_VID: 0xFFFF USBD_PID: 0x0001 USBD_VENDOR_STRING: '"Apache Software Foundation"' diff --git a/nimble/host/audio/src/ble_audio_broadcast_source.c b/nimble/host/audio/src/ble_audio_broadcast_source.c index 20edcceab1..210536f7ee 100644 --- a/nimble/host/audio/src/ble_audio_broadcast_source.c +++ b/nimble/host/audio/src/ble_audio_broadcast_source.c @@ -22,6 +22,7 @@ #include "os/util.h" +#if MYNEWT_VAL(BLE_AUDIO) #if MYNEWT_VAL(BLE_ISO_BROADCAST_SOURCE) struct ble_audio_broadcast { SLIST_ENTRY(ble_audio_broadcast) next; @@ -492,4 +493,5 @@ ble_audio_broadcast_init(void) return 0; } -#endif +#endif /* BLE_ISO_BROADCAST_SOURCE */ +#endif /* BLE_AUDIO */ From 5a94d71784d8e9b4d747d008082bcf92c85cbc8c Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 26 Nov 2024 15:24:07 +0100 Subject: [PATCH 1150/1333] apps: Merge auracast and auracast_usb applications This adds new AUDIO_USB syscfg option to disable the USB audio support in auracast_usb application. This fixes code duplication, so that auracast_usb has been renamed to auracast, where previous auracast application has been removed. --- .../include/tusb_config.h | 0 .../include/usb_audio.h | 0 apps/auracast/pkg.yml | 9 + .../{auracast_usb => auracast}/src/app_priv.h | 8 +- .../src/audio_usb.c => auracast/src/audio.c} | 110 +++++- apps/auracast/src/main.c | 257 +++++++------- .../{auracast_usb => auracast}/src/usb_desc.c | 5 +- .../{auracast_usb => auracast}/syscfg.usb.yml | 0 apps/auracast/syscfg.yml | 90 ++++- apps/auracast_usb/pkg.yml | 46 --- apps/auracast_usb/src/main.c | 336 ------------------ apps/auracast_usb/syscfg.yml | 134 ------- 12 files changed, 327 insertions(+), 668 deletions(-) rename apps/{auracast_usb => auracast}/include/tusb_config.h (100%) rename apps/{auracast_usb => auracast}/include/usb_audio.h (100%) rename apps/{auracast_usb => auracast}/src/app_priv.h (94%) rename apps/{auracast_usb/src/audio_usb.c => auracast/src/audio.c} (76%) rename apps/{auracast_usb => auracast}/src/usb_desc.c (99%) rename apps/{auracast_usb => auracast}/syscfg.usb.yml (100%) delete mode 100644 apps/auracast_usb/pkg.yml delete mode 100644 apps/auracast_usb/src/main.c delete mode 100644 apps/auracast_usb/syscfg.yml diff --git a/apps/auracast_usb/include/tusb_config.h b/apps/auracast/include/tusb_config.h similarity index 100% rename from apps/auracast_usb/include/tusb_config.h rename to apps/auracast/include/tusb_config.h diff --git a/apps/auracast_usb/include/usb_audio.h b/apps/auracast/include/usb_audio.h similarity index 100% rename from apps/auracast_usb/include/usb_audio.h rename to apps/auracast/include/usb_audio.h diff --git a/apps/auracast/pkg.yml b/apps/auracast/pkg.yml index fa33aa31f5..902c38028e 100644 --- a/apps/auracast/pkg.yml +++ b/apps/auracast/pkg.yml @@ -32,8 +32,17 @@ pkg.deps: - nimble/host/store/config - nimble/host/audio/services/auracast - "@apache-mynewt-core/kernel/os" + - "@apache-mynewt-core/sys/config" - "@apache-mynewt-core/sys/console" - "@apache-mynewt-core/sys/log" - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/sysinit" - "@apache-mynewt-core/sys/id" + +pkg.deps.AUDIO_USB: + - ext/liblc3 + - ext/libsamplerate + - "@apache-mynewt-core/hw/usb/tinyusb" + +pkg.init: + audio_init: 402 diff --git a/apps/auracast_usb/src/app_priv.h b/apps/auracast/src/app_priv.h similarity index 94% rename from apps/auracast_usb/src/app_priv.h rename to apps/auracast/src/app_priv.h index 5304e08241..87b0f97685 100644 --- a/apps/auracast_usb/src/app_priv.h +++ b/apps/auracast/src/app_priv.h @@ -21,6 +21,7 @@ #define H_APP_PRIV_ #include +#include #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -40,10 +41,5 @@ #define LC3_FPDT (AUDIO_PCM_SAMPLE_RATE * LC3_FRAME_DURATION / 1000000) #define BIG_NUM_BIS (MIN(AUDIO_CHANNELS, MYNEWT_VAL(BIG_NUM_BIS))) -struct chan { - void *encoder; - uint16_t handle; -}; - -extern struct chan chans[AUDIO_CHANNELS]; +void audio_chan_set_conn_handle(uint8_t chan_idx, uint16_t conn_handle); #endif /* H_APP_PRIV_ */ diff --git a/apps/auracast_usb/src/audio_usb.c b/apps/auracast/src/audio.c similarity index 76% rename from apps/auracast_usb/src/audio_usb.c rename to apps/auracast/src/audio.c index 933a04d872..15c64511a9 100644 --- a/apps/auracast_usb/src/audio_usb.c +++ b/apps/auracast/src/audio.c @@ -18,13 +18,26 @@ */ #include +#include +#include #include #include -#include + +#include "console/console.h" +#include "host/ble_hs.h" +#include "host/ble_iso.h" + +#include "app_priv.h" + +struct chan { + void *encoder; + uint16_t handle; +} chans[AUDIO_CHANNELS]; + +#if MYNEWT_VAL(AUDIO_USB) #include #include #include -#include "console/console.h" #include #include @@ -33,16 +46,12 @@ #include "host/ble_gap.h" #include "os/os_cputime.h" -#include "app_priv.h" - #define AUDIO_BUF_SIZE 1024 static uint8_t g_usb_enabled; static void usb_data_func(struct os_event *ev); -struct chan chans[AUDIO_CHANNELS]; - static struct os_event usb_data_ev = { .ev_cb = usb_data_func, }; @@ -239,7 +248,7 @@ tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_bytes_received, return true; } -void +static void audio_usb_init(void) { /* Need to reference those explicitly, so they are always pulled by linker @@ -280,3 +289,90 @@ audio_usb_init(void) resampler_ratio = resampler_out_rate / resampler_in_rate; #endif } +#else +#include "audio_data.h" + +#define BROADCAST_MAX_SDU 120 + +static int audio_data_offset; +static struct os_callout audio_broadcast_callout; + +static void +audio_broadcast_event_cb(struct os_event *ev) +{ + assert(ev != NULL); + uint32_t ev_start_time = os_cputime_ticks_to_usecs(os_cputime_get32()); + +#if MYNEWT_VAL(AURACAST_CHAN_NUM) > 1 + if (audio_data_offset + BROADCAST_MAX_SDU >= sizeof(audio_data)) { + audio_data_offset = 0; + } + + if (chans[0].handle != BLE_HS_CONN_HANDLE_NONE) { + ble_iso_tx(chans[0].handle, (void *) (audio_data + audio_data_offset), + BROADCAST_MAX_SDU); + } + if (chans[1].handle != BLE_HS_CONN_HANDLE_NONE) { + ble_iso_tx(chans[1].handle, (void *) (audio_data + audio_data_offset), + BROADCAST_MAX_SDU); + } +#else + if (audio_data_offset + 2 * BROADCAST_MAX_SDU >= sizeof(audio_data)) { + audio_data_offset = 0; + } + + uint8_t lr_payload[BROADCAST_MAX_SDU * 2]; + memcpy(lr_payload, audio_data + audio_data_offset, BROADCAST_MAX_SDU); + memcpy(lr_payload + BROADCAST_MAX_SDU, audio_data + audio_data_offset, + BROADCAST_MAX_SDU); + + if (chans[0].handle != BLE_HS_CONN_HANDLE_NONE) { + ble_iso_tx(chans[0].handle, (void *) (lr_payload), + BROADCAST_MAX_SDU * 2); + } +#endif + audio_data_offset += BROADCAST_MAX_SDU; + + /** Use cputime to time LC3_FRAME_DURATION, as these ticks are more + * accurate than os_time ones. This assures that we do not push + * LC3 data to ISO before interval, which could lead to + * controller running out of buffers. This is only needed because + * we already have coded data in an array - in real world application + * we usually wait for new audio to arrive, and lose time to code it too. + */ + while (os_cputime_ticks_to_usecs(os_cputime_get32()) - ev_start_time < + (MYNEWT_VAL(LC3_FRAME_DURATION))); + + os_callout_reset(&audio_broadcast_callout, 0); +} + +static void +audio_dummy_init(void) +{ + os_callout_init(&audio_broadcast_callout, os_eventq_dflt_get(), + audio_broadcast_event_cb, NULL); + + os_callout_reset(&audio_broadcast_callout, 0); +} +#endif /* AUDIO_USB */ + +void +audio_init(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(chans); i++) { + chans[i].handle = BLE_HS_CONN_HANDLE_NONE; + } + +#if MYNEWT_VAL(AUDIO_USB) + audio_usb_init(); +#else + audio_dummy_init(); +#endif /* AUDIO_USB */ +} + +void +audio_chan_set_conn_handle(uint8_t chan_idx, uint16_t conn_handle) +{ + assert(chan_idx < ARRAY_SIZE(chans)); + chans[chan_idx].handle = conn_handle; +} diff --git a/apps/auracast/src/main.c b/apps/auracast/src/main.c index ec4c86700f..bee05e8920 100644 --- a/apps/auracast/src/main.c +++ b/apps/auracast/src/main.c @@ -28,13 +28,35 @@ #include "hal/hal_gpio.h" #include "bsp/bsp.h" - -#include "audio_data.h" +#include "app_priv.h" #define BROADCAST_SID 1 -#define BROADCAST_MAX_SDU 120 -#define BROADCAST_SDU_INTVL 10000 + +#if (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 8000) +#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_8000_HZ +#elif (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 16000) +#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_16000_HZ +#elif (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 24000) +#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_24000_HZ +#elif (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 32000) +#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_32000_HZ +#elif (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 48000) #define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_48000_HZ +#else +BUILD_ASSERT(0, "Sample frequency not supported"); +#endif + +/* Note: values need to be adjusted if sampling frequency is 44100 (currently + * not supported by app) or SDU interval is different from LC3 frame + * length + */ +#define OCTETS_PER_CODEC_FRAME (MYNEWT_VAL(LC3_BITRATE) / \ + 8 * MYNEWT_VAL(LC3_FRAME_DURATION) / \ + 1000000) +#define BIG_SDU_INTERVAL (MYNEWT_VAL(LC3_FRAME_DURATION)) +#define BIG_MAX_SDU (OCTETS_PER_CODEC_FRAME * \ + MYNEWT_VAL(AURACAST_CHAN_NUM) / \ + MYNEWT_VAL(BIG_NUM_BIS)) #define BROADCASTER_INTERRUPT_TASK_PRIO 4 #define BROADCASTER_INTERRUPT_TASK_STACK_SZ 512 @@ -45,160 +67,83 @@ static struct ble_audio_base auracast_base; static struct ble_audio_big_subgroup big_subgroup; static os_membuf_t bis_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BROADCASTER_CHAN_NUM), + OS_MEMPOOL_SIZE(MYNEWT_VAL(BIG_NUM_BIS), sizeof(struct ble_audio_bis)) ]; static struct os_mempool bis_pool; static os_membuf_t codec_spec_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ISO_MAX_BISES) * 2, 19) + OS_MEMPOOL_SIZE(MYNEWT_VAL(BIG_NUM_BIS) * 2, 19) ]; static struct os_mempool codec_spec_pool; -static uint16_t bis_handles[MYNEWT_VAL(BROADCASTER_CHAN_NUM)]; -/* The timer callout */ -static struct os_callout audio_broadcast_callout; - -static int audio_data_offset; static uint8_t auracast_adv_instance; -#if MYNEWT_VAL(BROADCASTER_STOP_BUTTON) >= 0 -static struct os_task auracast_interrupt_task_str; -static struct os_eventq auracast_interrupt_eventq; -static os_stack_t auracast_interrupt_task_stack[BROADCASTER_INTERRUPT_TASK_STACK_SZ]; -static void -auracast_interrupt_task(void *arg) -{ - while (1) { - os_eventq_run(&auracast_interrupt_eventq); - } -} - static void -broadcast_stop_ev_cb(struct os_event *ev) -{ - ble_svc_auracast_stop(auracast_adv_instance); - ble_svc_auracast_terminate(auracast_adv_instance); -} - -static struct os_event broadcast_stop_ev = { - .ev_cb = broadcast_stop_ev_cb, -}; - -static void -auracast_gpio_irq(void *arg) -{ - os_eventq_put(&auracast_interrupt_eventq, &broadcast_stop_ev); -} -#endif /* MYNEWT_VAL(BROADCASTER_STOP_BUTTON) >= 0 */ - -static void -audio_broadcast_event_cb(struct os_event *ev) -{ - assert(ev != NULL); - uint32_t ev_start_time = os_cputime_ticks_to_usecs(os_cputime_get32()); - -#if MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 - if (audio_data_offset + BROADCAST_MAX_SDU >= sizeof(audio_data)) { - audio_data_offset = 0; - } - - ble_iso_tx(bis_handles[0], (void *)(audio_data + audio_data_offset), - BROADCAST_MAX_SDU); - ble_iso_tx(bis_handles[1], (void *)(audio_data + audio_data_offset), - BROADCAST_MAX_SDU); -#else - if (audio_data_offset + 2 * BROADCAST_MAX_SDU >= sizeof(audio_data)) { - audio_data_offset = 0; - } - - uint8_t lr_payload[BROADCAST_MAX_SDU * 2]; - memcpy(lr_payload, audio_data + audio_data_offset, BROADCAST_MAX_SDU); - memcpy(lr_payload + BROADCAST_MAX_SDU, audio_data + audio_data_offset, - BROADCAST_MAX_SDU); - ble_iso_tx(bis_handles[0], (void *)(lr_payload), - BROADCAST_MAX_SDU * 2); -#endif - audio_data_offset += BROADCAST_MAX_SDU; - - /** Use cputime to time BROADCAST_SDU_INTVL, as these ticks are more - * accurate than os_time ones. This assures that we do not push - * LC3 data to ISO before interval, which could lead to - * controller running out of buffers. This is only needed because - * we already have coded data in an array - in real world application - * we usually wait for new audio to arrive, and lose time to code it too. - */ - while (os_cputime_ticks_to_usecs(os_cputime_get32()) - ev_start_time < - (BROADCAST_SDU_INTVL)); - - os_callout_reset(&audio_broadcast_callout, 0); -} -static int -broadcast_audio() -{ - os_callout_reset(&audio_broadcast_callout, 0); - - return 0; -} - -static void -auracast_init() +auracast_init(void) { int rc; - os_callout_init(&audio_broadcast_callout, os_eventq_dflt_get(), - audio_broadcast_event_cb, NULL); - - assert(MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 0); + assert(MYNEWT_VAL(AURACAST_CHAN_NUM) > 0); - rc = os_mempool_init(&bis_pool, MYNEWT_VAL(BROADCASTER_CHAN_NUM), + rc = os_mempool_init(&bis_pool, MYNEWT_VAL(BIG_NUM_BIS), sizeof(struct ble_audio_bis), bis_mem, "bis_pool"); assert(rc == 0); rc = os_mempool_init(&codec_spec_pool, - MYNEWT_VAL(BLE_ISO_MAX_BISES) * 2, 19, + MYNEWT_VAL(BIG_NUM_BIS) * 2, 19, codec_spec_mem, "codec_spec_pool"); assert(rc == 0); } static int -base_create() +base_create(void) { -#if MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 +#if MYNEWT_VAL(BIG_NUM_BIS) > 1 struct ble_audio_bis *bis_left; struct ble_audio_bis *bis_right; uint8_t codec_spec_config_left_chan[] = BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, - BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS, + MYNEWT_VAL(LC3_FRAME_DURATION) == 10000 ? + BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS : + BLE_AUDIO_SELECTED_FRAME_DURATION_7_5_MS, BLE_AUDIO_LOCATION_FRONT_LEFT, - BROADCAST_MAX_SDU, ); + OCTETS_PER_CODEC_FRAME, ); uint8_t codec_spec_config_right_chan[] = BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, - BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS, + MYNEWT_VAL(LC3_FRAME_DURATION) == 10000 ? + BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS : + BLE_AUDIO_SELECTED_FRAME_DURATION_7_5_MS, BLE_AUDIO_LOCATION_FRONT_RIGHT, - BROADCAST_MAX_SDU, ); + OCTETS_PER_CODEC_FRAME, ); #else uint16_t chan_loc = BLE_AUDIO_LOCATION_FRONT_LEFT | BLE_AUDIO_LOCATION_FRONT_RIGHT; uint8_t codec_spec_config[] = BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, - BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS, + MYNEWT_VAL(LC3_FRAME_DURATION) == 10000 ? + BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS : + BLE_AUDIO_SELECTED_FRAME_DURATION_7_5_MS, chan_loc, - BROADCAST_MAX_SDU * 2, ); + OCTETS_PER_CODEC_FRAME, ); struct ble_audio_bis *bis; #endif - auracast_base.broadcast_id = 0x42; + if (MYNEWT_VAL(BROADCAST_ID) != 0) { + auracast_base.broadcast_id = MYNEWT_VAL(BROADCAST_ID); + } else { + ble_hs_hci_rand(&auracast_base.broadcast_id, 3); + } auracast_base.presentation_delay = 20000; - big_subgroup.bis_cnt = MYNEWT_VAL(BROADCASTER_CHAN_NUM); + big_subgroup.bis_cnt = MYNEWT_VAL(BIG_NUM_BIS); /** LC3 */ big_subgroup.codec_id.format = 0x06; big_subgroup.codec_spec_config_len = 0; -#if MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 +#if MYNEWT_VAL(BIG_NUM_BIS) > 1 bis_left = os_memblock_get(&bis_pool); if (!bis_left) { return BLE_HS_ENOMEM; @@ -248,6 +193,7 @@ static int auracast_destroy_fn(struct ble_audio_base *base, void *args) { struct ble_audio_bis *bis; + int i; STAILQ_FOREACH(bis, &big_subgroup.bises, next) { os_memblock_put(&codec_spec_pool, bis->codec_spec_config); @@ -256,6 +202,10 @@ auracast_destroy_fn(struct ble_audio_base *base, void *args) memset(&big_subgroup, 0, sizeof(big_subgroup)); + for (i = 0; i < MYNEWT_VAL(AURACAST_CHAN_NUM); i++) { + audio_chan_set_conn_handle(i, BLE_HS_CONN_HANDLE_NONE); + } + return 0; } @@ -268,13 +218,18 @@ iso_event(struct ble_iso_event *event, void *arg) case BLE_ISO_EVENT_BIG_CREATE_COMPLETE: console_printf("BIG created\n"); if (event->big_created.desc.num_bis > - MYNEWT_VAL(BROADCASTER_CHAN_NUM)) { + MYNEWT_VAL(AURACAST_CHAN_NUM)) { return BLE_HS_EINVAL; } - for (i = 0; i < MYNEWT_VAL(BROADCASTER_CHAN_NUM); i++) { - bis_handles[i] = event->big_created.desc.conn_handle[i]; + if (MYNEWT_VAL(AURACAST_CHAN_NUM) == event->big_created.desc.num_bis) { + for (i = 0; i < MYNEWT_VAL(AURACAST_CHAN_NUM); i++) { + audio_chan_set_conn_handle(i, event->big_created.desc.conn_handle[i]); + } + } else { + for (i = 0; i < MYNEWT_VAL(AURACAST_CHAN_NUM); i++) { + audio_chan_set_conn_handle(i, event->big_created.desc.conn_handle[0]); + } } - broadcast_audio(); return 0; case BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE: console_printf("BIG terminated\n"); @@ -285,32 +240,32 @@ iso_event(struct ble_iso_event *event, void *arg) } static int -auracast_create() +auracast_create(void) { const char *program_info = "NimBLE Auracast Test"; static struct ble_iso_big_params big_params = { - .sdu_interval = BROADCAST_SDU_INTVL, - .max_sdu = MYNEWT_VAL(BROADCASTER_CHAN_NUM) > 1 ? - BROADCAST_MAX_SDU : BROADCAST_MAX_SDU * 2, - .max_transport_latency = BROADCAST_SDU_INTVL / 1000, - .rtn = 0, - .phy = BLE_HCI_LE_PHY_2M, - .packing = 0, - .framing = 0, - .encryption = 0, + .sdu_interval = BIG_SDU_INTERVAL, + .max_sdu = BIG_MAX_SDU, + .max_transport_latency = MYNEWT_VAL(LC3_FRAME_DURATION) / 1000, + .rtn = MYNEWT_VAL(BIG_RTN), + .phy = MYNEWT_VAL(BIG_PHY), + .packing = MYNEWT_VAL(BIG_PACKING), + .framing = MYNEWT_VAL(BIG_FRAMING), + .encryption = MYNEWT_VAL(BIG_ENCRYPTION), + .broadcast_code = MYNEWT_VAL(BROADCAST_CODE), }; struct ble_svc_auracast_create_params create_params = { .base = &auracast_base, .big_params = &big_params, - .name = MYNEWT_VAL(BROADCASTER_BROADCAST_NAME), + .name = MYNEWT_VAL(BROADCAST_NAME), .program_info = program_info, .own_addr_type = id_addr_type, .secondary_phy = BLE_HCI_LE_PHY_2M, .sid = BROADCAST_SID, - .frame_duration = 10000, - .sampling_frequency = 48000, - .bitrate = 48000, + .frame_duration = MYNEWT_VAL(LC3_FRAME_DURATION), + .sampling_frequency = MYNEWT_VAL(LC3_SAMPLING_FREQ), + .bitrate = MYNEWT_VAL(LC3_BITRATE), }; return ble_svc_auracast_create(&create_params, @@ -321,7 +276,7 @@ auracast_create() } static int -auracast_start() +auracast_start(void) { return ble_svc_auracast_start(auracast_adv_instance, iso_event, NULL); } @@ -351,9 +306,43 @@ on_sync(void) rc = auracast_start(); assert(rc == 0); +} + +#if MYNEWT_VAL(AURACAST_STOP_BUTTON) >= 0 +#include "hal/hal_gpio.h" +#include "bsp/bsp.h" + +#define AURACAST_INTERRUPT_TASK_PRIO 4 +#define AURACAST_INTERRUPT_TASK_STACK_SZ 512 + +static struct os_task auracast_interrupt_task_str; +static struct os_eventq auracast_interrupt_eventq; +static os_stack_t auracast_interrupt_task_stack[AURACAST_INTERRUPT_TASK_STACK_SZ]; +static void +auracast_interrupt_task(void *arg) +{ + while (1) { + os_eventq_run(&auracast_interrupt_eventq); + } +} - broadcast_audio(); +static void +broadcast_stop_ev_cb(struct os_event *ev) +{ + ble_svc_auracast_stop(auracast_adv_instance); + ble_svc_auracast_terminate(auracast_adv_instance); +} + +static struct os_event broadcast_stop_ev = { + .ev_cb = broadcast_stop_ev_cb, +}; + +static void +auracast_gpio_irq(void *arg) +{ + os_eventq_put(&auracast_interrupt_eventq, &broadcast_stop_ev); } +#endif /* MYNEWT_VAL(AURACAST_STOP_BUTTON) >= 0 */ /* * main @@ -374,18 +363,18 @@ mynewt_main(int argc, char **argv) /* Set sync callback */ ble_hs_cfg.sync_cb = on_sync; -#if MYNEWT_VAL(BROADCASTER_STOP_BUTTON) >= 0 +#if MYNEWT_VAL(AURACAST_STOP_BUTTON) >= 0 os_eventq_init(&auracast_interrupt_eventq); os_task_init(&auracast_interrupt_task_str, "auracast_interrupt_task", auracast_interrupt_task, NULL, - BROADCASTER_INTERRUPT_TASK_PRIO, OS_WAIT_FOREVER, + AURACAST_INTERRUPT_TASK_PRIO, OS_WAIT_FOREVER, auracast_interrupt_task_stack, - BROADCASTER_INTERRUPT_TASK_STACK_SZ); + AURACAST_INTERRUPT_TASK_STACK_SZ); - hal_gpio_irq_init(MYNEWT_VAL(BROADCASTER_STOP_BUTTON), auracast_gpio_irq, + hal_gpio_irq_init(MYNEWT_VAL(AURACAST_STOP_BUTTON), auracast_gpio_irq, NULL, HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_UP); - hal_gpio_irq_enable(MYNEWT_VAL(BROADCASTER_STOP_BUTTON)); -#endif /* MYNEWT_VAL(BROADCASTER_STOP_BUTTON) >= 0 */ + hal_gpio_irq_enable(MYNEWT_VAL(AURACAST_STOP_BUTTON)); +#endif /* MYNEWT_VAL(AURACAST_STOP_BUTTON) >= 0 */ /* As the last thing, process events from default event queue */ while (1) { diff --git a/apps/auracast_usb/src/usb_desc.c b/apps/auracast/src/usb_desc.c similarity index 99% rename from apps/auracast_usb/src/usb_desc.c rename to apps/auracast/src/usb_desc.c index 681ad7cea7..4738b47e9a 100644 --- a/apps/auracast_usb/src/usb_desc.c +++ b/apps/auracast/src/usb_desc.c @@ -17,8 +17,10 @@ * under the License. */ -#include #include + +#if MYNEWT_VAL(AUDIO_USB) +#include #include #include #include @@ -393,3 +395,4 @@ usb_desc_sample_rate_set(uint32_t sample_rate) { g_sample_rate = sample_rate; } +#endif /* AUDIO_USB */ diff --git a/apps/auracast_usb/syscfg.usb.yml b/apps/auracast/syscfg.usb.yml similarity index 100% rename from apps/auracast_usb/syscfg.usb.yml rename to apps/auracast/syscfg.usb.yml diff --git a/apps/auracast/syscfg.yml b/apps/auracast/syscfg.yml index dc1b1a5b1d..e243f690e7 100644 --- a/apps/auracast/syscfg.yml +++ b/apps/auracast/syscfg.yml @@ -16,14 +16,65 @@ # under the License. syscfg.defs: - BROADCASTER_CHAN_NUM: 2 - BROADCASTER_BROADCAST_NAME: '"NimBLE Auracast"' - BROADCASTER_STOP_BUTTON: + AUDIO_USB: + description: Enable USB audio output device driver. + value: 1 + restrictions: + # For now, LC3 encoded audio data, with 48kHz sample rate is supported only. + - '(LC3_SAMPLING_FREQ == 48000) if 0' + - '(LC3_FRAME_DURATION == 10000) is 0' + + ISO_HCI_FEEDBACK: + description: Enable HCI feedback for resampler. This reduces jitter between USB and ISO. + value: 0 + + AURACAST_CHAN_NUM: 2 + + AURACAST_STOP_BUTTON: description: > - Button number for Broadcast Stop action. + Button number for Auracast Stop action. Negative value if disabled. value: BUTTON_3 + BROADCAST_ID: + description: Broadcast ID value, will use random number if 0 + value: 0x000000 + BROADCAST_NAME: + description: Broadcast name + value: '"NimBLE Auracast"' + BROADCAST_CODE: + description: Broadcast code used for encrpytion + value: '"listen2nimble"' + + LC3_FRAME_DURATION: + description: LC3 frame duration + value: 10000 + LC3_SAMPLING_FREQ: + description: LC3 sampling frequency + value: 48000 + LC3_BITRATE: + description: LC3 bitrate + value: 96000 + + BIG_PHY: + description: + value: 2 + BIG_NUM_BIS: + description: Max number of BISes used + value: 2 + BIG_RTN: + description: BIG RTN (number of retransmissions) + value: 0 + BIG_PACKING: + description: Arrangement of BIS subevents (0 = sequential, 1 = interleaved) + value: 0 + BIG_FRAMING: + description: + value: 0 + BIG_ENCRYPTION: + description: BIS encryption + value: 0 + syscfg.vals: CONSOLE_IMPLEMENTATION: full LOG_IMPLEMENTATION: full @@ -65,3 +116,34 @@ syscfg.vals: BLE_ISO_MAX_BISES: 2 BLE_AUDIO: 1 + + MCU_HFCLK_DIV: 1 + HARDFLOAT: 1 + +syscfg.vals.AUDIO_USB: + # TinyUSB + USBD_VID: 0xFFFF + USBD_PID: 0x0001 + USBD_VENDOR_STRING: '"Apache Software Foundation"' + USBD_PRODUCT_STRING: '"NimBLE Auracast"' + USBD_AUDIO_OUT: 1 + USBD_STACK_SIZE: 500 + USBD_STD_DESCRIPTORS: 0 + + USB_AUDIO_OUT_CHANNELS: MYNEWT_VAL(AURACAST_CHAN_NUM) + + # Resampler + LIBSAMPLERATE_ENABLE_SINC_BEST_CONVERTER: 0 + LIBSAMPLERATE_ENABLE_SINC_MEDIUM_CONVERTER: 0 + LIBSAMPLERATE_ENABLE_SINC_FAST_CONVERTER: 1 + LIBSAMPLERATE_LIBSAMPLER_NDEBUG: 1 + +syscfg.vals.ISO_HCI_FEEDBACK: + BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS: 1000 + BLE_HS_GAP_UNHANDLED_HCI_EVENT: 1 + +syscfg.vals.BSP_NRF52: + BLE_PHY_NRF52_HEADERMASK_WORKAROUND: 1 + +$import: + - "@apache-mynewt-nimble/apps/auracast/syscfg.usb.yml" \ No newline at end of file diff --git a/apps/auracast_usb/pkg.yml b/apps/auracast_usb/pkg.yml deleted file mode 100644 index 96c56f2ca2..0000000000 --- a/apps/auracast_usb/pkg.yml +++ /dev/null @@ -1,46 +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. -# - -pkg.name: apps/auracast_usb -pkg.type: app -pkg.description: Auracast sample application. - -pkg.author: "Krzysztof Kopyściński" -pkg.email: "krzysztof.kopyscinski@codecoup.pl" -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - -pkg.deps: - - "@apache-mynewt-core/sys/config" - - nimble/host - - nimble/host/util - - nimble/host/services/gap - - nimble/host/store/config - - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/sys/console" - - "@apache-mynewt-core/sys/log" - - "@apache-mynewt-core/sys/stats" - - "@apache-mynewt-core/sys/sysinit" - - "@apache-mynewt-core/sys/id" - - "@apache-mynewt-core/hw/usb/tinyusb" - - "@apache-mynewt-nimble/nimble/host/audio/services/auracast" - - "@apache-mynewt-nimble/ext/liblc3" - - "@apache-mynewt-nimble/ext/libsamplerate" - -pkg.init: - audio_usb_init: 402 diff --git a/apps/auracast_usb/src/main.c b/apps/auracast_usb/src/main.c deleted file mode 100644 index 4ddb0b8608..0000000000 --- a/apps/auracast_usb/src/main.c +++ /dev/null @@ -1,336 +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. - */ - -#include "console/console.h" -#include "config/config.h" - -#include "nimble/ble.h" -#include "host/ble_hs.h" -#include "host/util/util.h" - -#include "services/auracast/ble_svc_auracast.h" - -#include "hal/hal_gpio.h" -#include "bsp/bsp.h" -#include "app_priv.h" - -#define BROADCAST_SID 1 - -#if (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 8000) -#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_8000_HZ -#elif (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 16000) -#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_16000_HZ -#elif (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 24000) -#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_24000_HZ -#elif (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 32000) -#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_32000_HZ -#elif (MYNEWT_VAL(LC3_SAMPLING_FREQ) == 48000) -#define BROADCAST_SAMPLE_RATE BLE_AUDIO_SAMPLING_RATE_48000_HZ -#else -BUILD_ASSERT(0, "Sample frequency not supported"); -#endif - -/* Note: values need to be adjusted if sampling frequency is 44100 (currently - * not supported by app) or SDU interval is different from LC3 frame - * length - */ -#define OCTETS_PER_CODEC_FRAME (MYNEWT_VAL(LC3_BITRATE) / \ - 8 * MYNEWT_VAL(LC3_FRAME_DURATION) / \ - 1000000) -#define BIG_SDU_INTERVAL (MYNEWT_VAL(LC3_FRAME_DURATION)) -#define BIG_MAX_SDU (OCTETS_PER_CODEC_FRAME * \ - MYNEWT_VAL(AURACAST_CHAN_NUM) / \ - MYNEWT_VAL(BIG_NUM_BIS)) - -#define BROADCASTER_INTERRUPT_TASK_PRIO 4 -#define BROADCASTER_INTERRUPT_TASK_STACK_SZ 512 - -static uint8_t id_addr_type; - -static struct ble_audio_base auracast_base; -static struct ble_audio_big_subgroup big_subgroup; - -static os_membuf_t bis_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BIG_NUM_BIS), - sizeof(struct ble_audio_bis)) -]; -static struct os_mempool bis_pool; - -static os_membuf_t codec_spec_mem[ - OS_MEMPOOL_SIZE(MYNEWT_VAL(BIG_NUM_BIS) * 2, 19) -]; -static struct os_mempool codec_spec_pool; - -static uint8_t auracast_adv_instance; - -static void -auracast_init(void) -{ - int rc; - - assert(MYNEWT_VAL(AURACAST_CHAN_NUM) > 0); - - rc = os_mempool_init(&bis_pool, MYNEWT_VAL(BIG_NUM_BIS), - sizeof(struct ble_audio_bis), bis_mem, - "bis_pool"); - assert(rc == 0); - - rc = os_mempool_init(&codec_spec_pool, - MYNEWT_VAL(BIG_NUM_BIS) * 2, 19, - codec_spec_mem, "codec_spec_pool"); - assert(rc == 0); -} - -static int -base_create(void) -{ -#if MYNEWT_VAL(BIG_NUM_BIS) > 1 - struct ble_audio_bis *bis_left; - struct ble_audio_bis *bis_right; - uint8_t codec_spec_config_left_chan[] = - BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, - MYNEWT_VAL(LC3_FRAME_DURATION) == 10000 ? - BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS : - BLE_AUDIO_SELECTED_FRAME_DURATION_7_5_MS, - BLE_AUDIO_LOCATION_FRONT_LEFT, - OCTETS_PER_CODEC_FRAME, ); - uint8_t codec_spec_config_right_chan[] = - BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, - MYNEWT_VAL(LC3_FRAME_DURATION) == 10000 ? - BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS : - BLE_AUDIO_SELECTED_FRAME_DURATION_7_5_MS, - BLE_AUDIO_LOCATION_FRONT_RIGHT, - OCTETS_PER_CODEC_FRAME, ); -#else - uint16_t chan_loc = BLE_AUDIO_LOCATION_FRONT_LEFT | - BLE_AUDIO_LOCATION_FRONT_RIGHT; - uint8_t codec_spec_config[] = - BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE, - MYNEWT_VAL(LC3_FRAME_DURATION) == 10000 ? - BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS : - BLE_AUDIO_SELECTED_FRAME_DURATION_7_5_MS, - chan_loc, - OCTETS_PER_CODEC_FRAME, ); - - struct ble_audio_bis *bis; -#endif - if (MYNEWT_VAL(BROADCAST_ID) != 0) { - auracast_base.broadcast_id = MYNEWT_VAL(BROADCAST_ID); - } else { - ble_hs_hci_rand(&auracast_base.broadcast_id, 3); - } - auracast_base.presentation_delay = 20000; - - big_subgroup.bis_cnt = MYNEWT_VAL(BIG_NUM_BIS); - - /** LC3 */ - big_subgroup.codec_id.format = 0x06; - - big_subgroup.codec_spec_config_len = 0; -#if MYNEWT_VAL(BIG_NUM_BIS) > 1 - bis_left = os_memblock_get(&bis_pool); - if (!bis_left) { - return BLE_HS_ENOMEM; - } - - bis_left->codec_spec_config = os_memblock_get(&codec_spec_pool); - memcpy(bis_left->codec_spec_config, - codec_spec_config_left_chan, - sizeof(codec_spec_config_left_chan)); - bis_left->codec_spec_config_len = sizeof(codec_spec_config_left_chan); - bis_left->idx = 1; - - bis_right = os_memblock_get(&bis_pool); - if (!bis_right) { - return BLE_HS_ENOMEM; - } - - bis_right->codec_spec_config = os_memblock_get(&codec_spec_pool); - memcpy(bis_right->codec_spec_config, - codec_spec_config_right_chan, - sizeof(codec_spec_config_right_chan)); - bis_right->codec_spec_config_len = sizeof(codec_spec_config_right_chan); - bis_right->idx = 2; - - STAILQ_INSERT_HEAD(&big_subgroup.bises, bis_left, next); - STAILQ_INSERT_TAIL(&big_subgroup.bises, bis_right, next); -#else - bis = os_memblock_get(&bis_pool); - if (!bis) { - return BLE_HS_ENOMEM; - } - - bis->codec_spec_config = os_memblock_get(&codec_spec_pool); - memcpy(bis->codec_spec_config, - codec_spec_config, - sizeof(codec_spec_config)); - bis->codec_spec_config_len = sizeof(codec_spec_config); - STAILQ_INSERT_HEAD(&big_subgroup.bises, bis, next); -#endif - - STAILQ_INSERT_HEAD(&auracast_base.subs, &big_subgroup, next); - auracast_base.num_subgroups++; - return 0; -} - -static int -auracast_destroy_fn(struct ble_audio_base *base, void *args) -{ - struct ble_audio_bis *bis; - int i; - - STAILQ_FOREACH(bis, &big_subgroup.bises, next) { - os_memblock_put(&codec_spec_pool, bis->codec_spec_config); - os_memblock_put(&bis_pool, bis); - } - - memset(&big_subgroup, 0, sizeof(big_subgroup)); - - for (i = 0; i < MYNEWT_VAL(AURACAST_CHAN_NUM); i++) { - chans[i].handle = 0; - } - - return 0; -} - -static int -iso_event(struct ble_iso_event *event, void *arg) -{ - int i; - - switch (event->type) { - case BLE_ISO_EVENT_BIG_CREATE_COMPLETE: - console_printf("BIG created\n"); - if (event->big_created.desc.num_bis > - MYNEWT_VAL(AURACAST_CHAN_NUM)) { - return BLE_HS_EINVAL; - } - if (MYNEWT_VAL(AURACAST_CHAN_NUM) == event->big_created.desc.num_bis) { - for (i = 0; i < MYNEWT_VAL(AURACAST_CHAN_NUM); i++) { - chans[i].handle = event->big_created.desc.conn_handle[i]; - } - } else { - for (i = 0; i < MYNEWT_VAL(AURACAST_CHAN_NUM); i++) { - chans[i].handle = event->big_created.desc.conn_handle[0]; - } - } - return 0; - case BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE: - console_printf("BIG terminated\n"); - return 0; - default: - return BLE_HS_ENOTSUP; - } -} - -static int -auracast_create(void) -{ - const char *program_info = "NimBLE Auracast Test"; - static struct ble_iso_big_params big_params = { - .sdu_interval = BIG_SDU_INTERVAL, - .max_sdu = BIG_MAX_SDU, - .max_transport_latency = MYNEWT_VAL(LC3_FRAME_DURATION) / 1000, - .rtn = MYNEWT_VAL(BIG_RTN), - .phy = MYNEWT_VAL(BIG_PHY), - .packing = MYNEWT_VAL(BIG_PACKING), - .framing = MYNEWT_VAL(BIG_FRAMING), - .encryption = MYNEWT_VAL(BIG_ENCRYPTION), - .broadcast_code = MYNEWT_VAL(BROADCAST_CODE), - }; - - struct ble_svc_auracast_create_params create_params = { - .base = &auracast_base, - .big_params = &big_params, - .name = MYNEWT_VAL(BROADCAST_NAME), - .program_info = program_info, - .own_addr_type = id_addr_type, - .secondary_phy = BLE_HCI_LE_PHY_2M, - .sid = BROADCAST_SID, - .frame_duration = MYNEWT_VAL(LC3_FRAME_DURATION), - .sampling_frequency = MYNEWT_VAL(LC3_SAMPLING_FREQ), - .bitrate = MYNEWT_VAL(LC3_BITRATE), - }; - - return ble_svc_auracast_create(&create_params, - &auracast_adv_instance, - auracast_destroy_fn, - NULL, - NULL); -} - -static int -auracast_start(void) -{ - return ble_svc_auracast_start(auracast_adv_instance, iso_event, NULL); -} - -static void -on_sync(void) -{ - int rc; - - console_printf("Bluetooth initialized\n"); - - /* Make sure we have proper identity address set (public preferred) */ - rc = ble_hs_util_ensure_addr(0); - assert(rc == 0); - - /* configure global address */ - rc = ble_hs_id_infer_auto(0, &id_addr_type); - assert(rc == 0); - - auracast_init(); - - rc = base_create(); - assert(rc == 0); - - rc = auracast_create(); - assert(rc == 0); - - rc = auracast_start(); - assert(rc == 0); -} - -/* - * main - * - * The main task for the project. This function initializes the packages, - * then starts serving events from default event queue. - * - * @return int NOTE: this function should never return! - */ -int -mynewt_main(int argc, char **argv) -{ - /* Initialize OS */ - sysinit(); - - console_printf("LE Audio Broadcast sample application\n"); - - /* Set sync callback */ - ble_hs_cfg.sync_cb = on_sync; - - /* As the last thing, process events from default event queue */ - while (1) { - os_eventq_run(os_eventq_dflt_get()); - } - - return 0; -} diff --git a/apps/auracast_usb/syscfg.yml b/apps/auracast_usb/syscfg.yml deleted file mode 100644 index 56ada080db..0000000000 --- a/apps/auracast_usb/syscfg.yml +++ /dev/null @@ -1,134 +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. - -syscfg.defs: - ISO_HCI_FEEDBACK: - description: Enable HCI feedback for resampler. This reduces jitter between USB and ISO. - value: 0 - - AURACAST_CHAN_NUM: 2 - - BROADCAST_ID: - description: Broadcast ID value, will use random number if 0 - value: 0x000000 - BROADCAST_NAME: - description: Broadcast name - value: '"NimBLE Auracast"' - BROADCAST_CODE: - description: Broadcast code used for encrpytion - value: '"listen2nimble"' - - LC3_FRAME_DURATION: - description: LC3 frame duration - value: 10000 - LC3_SAMPLING_FREQ: - description: LC3 sampling frequency - value: 48000 - LC3_BITRATE: - description: LC3 bitrate - value: 96000 - - BIG_PHY: - description: - value: 2 - BIG_NUM_BIS: - description: Max number of BISes used - value: 2 - BIG_RTN: - description: BIG RTN (number of retransmissions) - value: 0 - BIG_PACKING: - description: Arrangement of BIS subevents (0 = sequential, 1 = interleaved) - value: 0 - BIG_FRAMING: - description: - value: 0 - BIG_ENCRYPTION: - description: BIS encryption - value: 0 - -syscfg.vals: - CONSOLE_IMPLEMENTATION: full - LOG_IMPLEMENTATION: full - STATS_IMPLEMENTATION: full - - # Disable not used GAP roles (we only do non-connectable - # advertising here) - BLE_ROLE_BROADCASTER: 1 - BLE_ROLE_CENTRAL: 0 - BLE_ROLE_OBSERVER: 0 - BLE_ROLE_PERIPHERAL: 0 - - # Enable Extended Advertising - BLE_EXT_ADV: 1 - - # Enable Periodic Advertising - BLE_PERIODIC_ADV: 1 - - # Max advertising data size - BLE_EXT_ADV_MAX_SIZE: 261 - - # Number of multi-advertising instances. Note that due - # to historical reasonds total number of advertising - # instances is BLE_MULTI_ADV_INSTANCES + 1 as instance - # 0 is always available - BLE_MULTI_ADV_INSTANCES: 1 - - # Controller uses msys pool for storing advertising data and scan responses. - # Since we advertise a lot of data (~6k in total) at the same time we need - # to increase block count. - MSYS_1_BLOCK_COUNT: 32 - - BLE_PHY_2M: 1 - - BLE_VERSION: 54 - BLE_ISO: 1 - BLE_ISO_BROADCAST_SOURCE: 1 - BLE_ISO_MAX_BIGS: 1 - BLE_ISO_MAX_BISES: 2 - - BLE_AUDIO: 1 - - USBD_VID: 0xFFFF - USBD_PID: 0x0001 - USBD_VENDOR_STRING: '"Apache Software Foundation"' - USBD_PRODUCT_STRING: '"NimBLE Auracast"' - USBD_AUDIO_OUT: 1 - USB_AUDIO_OUT_CHANNELS: MYNEWT_VAL(AURACAST_CHAN_NUM) - - # resampler + encoder - LIBSAMPLERATE_ENABLE_SINC_BEST_CONVERTER: 0 - LIBSAMPLERATE_ENABLE_SINC_MEDIUM_CONVERTER: 0 - LIBSAMPLERATE_ENABLE_SINC_FAST_CONVERTER: 1 - LIBSAMPLERATE_LIBSAMPLER_NDEBUG: 1 - - MCU_HFCLK_DIV: 1 - HARDFLOAT: 1 - -syscfg.vals.TINYUSB: - USBD_STACK_SIZE: 500 - USBD_STD_DESCRIPTORS: 0 - -syscfg.vals.ISO_HCI_FEEDBACK: - BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS: 1000 - BLE_HS_GAP_UNHANDLED_HCI_EVENT: 1 - -syscfg.vals.BSP_NRF52: - BLE_PHY_NRF52_HEADERMASK_WORKAROUND: 1 - -$import: - - "@apache-mynewt-nimble/apps/auracast_usb/syscfg.usb.yml" \ No newline at end of file From e4f97e24a1c5844bae9fa45ad846324008cf14e0 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 25 Nov 2024 15:27:12 +0100 Subject: [PATCH 1151/1333] nimble/ll: Fix closing connection event on CRC error If single CRC error is received we should always reply to allow other side to retransmit the packet. If two consecutive CRC errors are received, we will close the connection event. --- nimble/controller/src/ble_ll_conn.c | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index c671a39969..65ff4cb0d9 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3750,30 +3750,15 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) */ if (!BLE_MBUF_HDR_CRC_OK(rxhdr)) { /* - * Increment # of consecutively received CRC errors. If more than - * one we will end the connection event. + * Increment # of consecutively received CRC errors. + * + * If more than one, we will end the connection event and no reply is needed. + * If less or equal to one, we always reply: + * - peripheral always replies + * - central replies to allow peripheral retransmit the packet */ ++connsm->cons_rxd_bad_crc; - if (connsm->cons_rxd_bad_crc >= 2) { - reply = 0; - } else { - switch (connsm->conn_role) { -#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - case BLE_LL_CONN_ROLE_CENTRAL: - reply = connsm->flags.last_txd_md; - break; -#endif -#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) - case BLE_LL_CONN_ROLE_PERIPHERAL: - /* A peripheral always responds with a packet */ - reply = 1; - break; -#endif - default: - BLE_LL_ASSERT(0); - break; - } - } + reply = connsm->cons_rxd_bad_crc < 2; } else { /* Reset consecutively received bad crcs (since this one was good!) */ connsm->cons_rxd_bad_crc = 0; From 93af9e7ab340428b2c306768461c38b4e32052c0 Mon Sep 17 00:00:00 2001 From: Mynewt Bot Date: Mon, 2 Dec 2024 21:45:57 +0000 Subject: [PATCH 1152/1333] porting: Update ports syscfg --- porting/npl/riot/include/syscfg/syscfg.h | 68 ++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 4ec768e8ae..6aa3cdd1ae 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -747,6 +747,73 @@ #define MYNEWT_VAL_XTAL_RC (0) #endif +#ifndef MYNEWT_VAL_JLINK_TARGET +#define MYNEWT_VAL_JLINK_TARGET (NRF52) +#endif + +#ifndef MYNEWT_VAL_MYNEWT_DEBUGGER__jlink +#define MYNEWT_VAL_MYNEWT_DEBUGGER__jlink (0) +#endif +#ifndef MYNEWT_VAL_MYNEWT_DEBUGGER__openocd +#define MYNEWT_VAL_MYNEWT_DEBUGGER__openocd (0) +#endif +#ifndef MYNEWT_VAL_MYNEWT_DEBUGGER__pyocd +#define MYNEWT_VAL_MYNEWT_DEBUGGER__pyocd (0) +#endif +#ifndef MYNEWT_VAL_MYNEWT_DEBUGGER__st_link_gdbserver +#define MYNEWT_VAL_MYNEWT_DEBUGGER__st_link_gdbserver (0) +#endif +#ifndef MYNEWT_VAL_MYNEWT_DEBUGGER__stutil +#define MYNEWT_VAL_MYNEWT_DEBUGGER__stutil (0) +#endif +#undef MYNEWT_VAL_MYNEWT_DEBUGGER + +#ifndef MYNEWT_VAL_MYNEWT_DOWNLOADER__ezflashcli +#define MYNEWT_VAL_MYNEWT_DOWNLOADER__ezflashcli (0) +#endif +#ifndef MYNEWT_VAL_MYNEWT_DOWNLOADER__jlink +#define MYNEWT_VAL_MYNEWT_DOWNLOADER__jlink (0) +#endif +#ifndef MYNEWT_VAL_MYNEWT_DOWNLOADER__nrfjprog +#define MYNEWT_VAL_MYNEWT_DOWNLOADER__nrfjprog (0) +#endif +#ifndef MYNEWT_VAL_MYNEWT_DOWNLOADER__nrfutil +#define MYNEWT_VAL_MYNEWT_DOWNLOADER__nrfutil (1) +#endif +#ifndef MYNEWT_VAL_MYNEWT_DOWNLOADER__openocd +#define MYNEWT_VAL_MYNEWT_DOWNLOADER__openocd (0) +#endif +#ifndef MYNEWT_VAL_MYNEWT_DOWNLOADER__pyocd +#define MYNEWT_VAL_MYNEWT_DOWNLOADER__pyocd (0) +#endif +#ifndef MYNEWT_VAL_MYNEWT_DOWNLOADER__stflash +#define MYNEWT_VAL_MYNEWT_DOWNLOADER__stflash (0) +#endif +#ifndef MYNEWT_VAL_MYNEWT_DOWNLOADER__stm32_programmer_cli +#define MYNEWT_VAL_MYNEWT_DOWNLOADER__stm32_programmer_cli (0) +#endif +#ifndef MYNEWT_VAL_MYNEWT_DOWNLOADER +#define MYNEWT_VAL_MYNEWT_DOWNLOADER (1) +#endif + +#ifndef MYNEWT_VAL_MYNEWT_DOWNLOADER_MFG_IMAGE_FLASH_OFFSET +#define MYNEWT_VAL_MYNEWT_DOWNLOADER_MFG_IMAGE_FLASH_OFFSET (0x0) +#endif + +#undef MYNEWT_VAL_MYNEWT_DOWNLOADER_OPENOCD_BOARD + +#undef MYNEWT_VAL_MYNEWT_DOWNLOADER_OPENOCD_CFG + +#undef MYNEWT_VAL_MYNEWT_DOWNLOADER_OPENOCD_INTERFACE + +#undef MYNEWT_VAL_NRFJPROG_COPROCESSOR + +#undef MYNEWT_VAL_NRFUTIL_TRAITS + +#ifndef MYNEWT_VAL_PYOCD_TARGET +#define MYNEWT_VAL_PYOCD_TARGET (nrf52840) +#endif + #ifndef MYNEWT_VAL_FLOAT_USER #define MYNEWT_VAL_FLOAT_USER (0) #endif @@ -2405,6 +2472,7 @@ #define MYNEWT_PKG_apache_mynewt_core__hw_mcu_nordic 1 #define MYNEWT_PKG_apache_mynewt_core__hw_mcu_nordic_nrf52xxx 1 #define MYNEWT_PKG_apache_mynewt_core__hw_mcu_nordic_nrf_common 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_scripts 1 #define MYNEWT_PKG_apache_mynewt_core__kernel_os 1 #define MYNEWT_PKG_apache_mynewt_core__libc 1 #define MYNEWT_PKG_apache_mynewt_core__libc_baselibc 1 From 125db54d921ac95a819c9f6b811461e3def27580 Mon Sep 17 00:00:00 2001 From: Mynewt Bot Date: Thu, 5 Dec 2024 21:46:06 +0000 Subject: [PATCH 1153/1333] porting: Update ports syscfg --- porting/npl/riot/include/syscfg/syscfg.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 6aa3cdd1ae..de1f33f670 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -577,6 +577,10 @@ #define MYNEWT_VAL_QSPI_WRITEOC (0) #endif +#ifndef MYNEWT_VAL_QSPI_XIP_OFFSET +#define MYNEWT_VAL_QSPI_XIP_OFFSET (0x10000000) +#endif + #ifndef MYNEWT_VAL_SPI_0_MASTER #define MYNEWT_VAL_SPI_0_MASTER (0) #endif From 3a30f01342b6da933478466ef0cffd48d45f7023 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 6 Dec 2024 14:15:33 +0100 Subject: [PATCH 1154/1333] nimble/ll: Fix connection parameters update with CSS build in Interval should be clipped only if CSS is runtime enabled and not just compiled in. --- nimble/controller/src/ble_ll_conn_hci.c | 9 +++++++-- nimble/controller/src/ble_ll_ctrl.c | 21 +++++++++++---------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index f3ac72380f..394db6f6b1 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1099,8 +1099,13 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) /* Retrieve command data */ hcu = &connsm->conn_param_req; #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) - hcu->conn_itvl_max = connsm->conn_itvl; - hcu->conn_itvl_min = connsm->conn_itvl; + if (ble_ll_sched_css_is_enabled()) { + hcu->conn_itvl_max = connsm->conn_itvl; + hcu->conn_itvl_min = connsm->conn_itvl; + } else { + hcu->conn_itvl_min = le16toh(cmd->conn_itvl_min); + hcu->conn_itvl_max = le16toh(cmd->conn_itvl_max); + } #else hcu->conn_itvl_min = le16toh(cmd->conn_itvl_min); hcu->conn_itvl_max = le16toh(cmd->conn_itvl_max); diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 85f98417a8..6562766d31 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -296,17 +296,18 @@ ble_ll_ctrl_conn_param_pdu_proc(struct ble_ll_conn_sm *connsm, uint8_t *dptr, #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) /* Allow to change connection parameters only if conn_itvl can stay unchanged * and anchor point change is not requested */ - if (ble_ll_sched_css_is_enabled() && - connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL && - ((connsm->conn_itvl < le16toh(req->interval_min)) || - (connsm->conn_itvl > le16toh(req->interval_max)) || - (le16toh(req->offset0) != 0xffff))) { - ble_err = BLE_ERR_INV_LMP_LL_PARM; - goto conn_param_pdu_exit; - } + if (ble_ll_sched_css_is_enabled()) { + if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL && + ((connsm->conn_itvl < le16toh(req->interval_min)) || + (connsm->conn_itvl > le16toh(req->interval_max)) || + (le16toh(req->offset0) != 0xffff))) { + ble_err = BLE_ERR_INV_LMP_LL_PARM; + goto conn_param_pdu_exit; + } - req->interval_min = connsm->conn_itvl; - req->interval_max = connsm->conn_itvl; + req->interval_min = connsm->conn_itvl; + req->interval_max = connsm->conn_itvl; + } #endif /* Check if parameters are valid */ From 70d1ab7000bd5189febdaa7ab2da59eb7c74d5bb Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 29 Nov 2024 10:42:38 +0100 Subject: [PATCH 1155/1333] Remove incubator leftovers Apparently couple leftovers were present in tree. --- porting/nimble/pkg.yml | 4 ++-- porting/npl/mynewt/pkg.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/porting/nimble/pkg.yml b/porting/nimble/pkg.yml index d56c90dbed..c538bc4c6a 100644 --- a/porting/nimble/pkg.yml +++ b/porting/nimble/pkg.yml @@ -20,7 +20,7 @@ pkg.name: porting/nimble pkg.type: app pkg.description: Stub for NimBLE porting -pkg.author: "Apache Mynewt " +pkg.author: "Apache Mynewt " pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: @@ -40,4 +40,4 @@ pkg.deps: # No need to build files from this package pkg.ign_files: - - ".*\\.c" \ No newline at end of file + - ".*\\.c" diff --git a/porting/npl/mynewt/pkg.yml b/porting/npl/mynewt/pkg.yml index b6a790f049..7bb94c6255 100644 --- a/porting/npl/mynewt/pkg.yml +++ b/porting/npl/mynewt/pkg.yml @@ -19,7 +19,7 @@ pkg.name: porting/npl/mynewt pkg.description: NimBLE porting layer for Apache Mynewt -pkg.author: "Apache Mynewt " +pkg.author: "Apache Mynewt " pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: From faf2f77424542ff28c49ea6e6341a9974aeef95d Mon Sep 17 00:00:00 2001 From: yyy Date: Mon, 2 Dec 2024 10:47:14 +0800 Subject: [PATCH 1156/1333] provisioner remove dependency of marco BLE_MESH_CDB --- nimble/host/mesh/src/provisioner.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/provisioner.c b/nimble/host/mesh/src/provisioner.c index 36a20a0cfd..2c9fab313e 100644 --- a/nimble/host/mesh/src/provisioner.c +++ b/nimble/host/mesh/src/provisioner.c @@ -33,6 +33,10 @@ static struct { uint8_t uuid[16]; } prov_device; +#if !MYNEWT_VAL(BLE_MESH_CDB) +static struct bt_mesh_cdb_node prov_node; +#endif + static void send_pub_key(void); static void prov_dh_key_gen(void); static void pub_key_ready(const uint8_t *pkey); @@ -234,6 +238,14 @@ static void prov_capabilities(const uint8_t *data) prov_fail(PROV_ERR_RESOURCES); return; } +#else + prov_device.node = &prov_node; + memset(&prov_node, 0, sizeof(struct bt_mesh_cdb_node)); + memcpy(prov_node.uuid, prov_device.uuid, 16); + prov_node.addr = prov_device.addr; + prov_node.num_elem = data[0]; + prov_node.net_idx = prov_device.net_idx; + atomic_set(prov_node.flags, 0); #endif memcpy(bt_mesh_prov_link.conf_inputs.capabilities, data, PDU_LEN_CAPABILITIES); @@ -454,7 +466,9 @@ static void send_prov_data(void) { struct os_mbuf *pdu = PROV_BUF(PDU_LEN_DATA); #if MYNEWT_VAL(BLE_MESH_CDB) - struct bt_mesh_cdb_subnet *sub; + struct bt_mesh_cdb_subnet *sub; +#else + struct bt_mesh_subnet *sub; #endif uint8_t session_key[16]; uint8_t nonce[13]; @@ -497,6 +511,14 @@ static void send_prov_data(void) prov_fail(PROV_ERR_UNEXP_ERR); return; } +#else + sub = bt_mesh_subnet_get(prov_device.node->net_idx); + if (sub == NULL) { + BT_ERR("No subnet with net_idx %u", + prov_device.node->net_idx); + prov_fail(PROV_ERR_UNEXP_ERR); + return; + } #endif bt_mesh_prov_buf_init(pdu, PROV_DATA); #if MYNEWT_VAL(BLE_MESH_CDB) @@ -504,6 +526,11 @@ static void send_prov_data(void) net_buf_simple_add_be16(pdu, prov_device.node->net_idx); net_buf_simple_add_u8(pdu, bt_mesh_cdb_subnet_flags(sub)); net_buf_simple_add_be32(pdu, bt_mesh_cdb.iv_index); +#else + net_buf_simple_add_mem(pdu, sub->keys[SUBNET_KEY_TX_IDX(sub)].net, 16); + net_buf_simple_add_be16(pdu, prov_device.node->net_idx); + net_buf_simple_add_u8(pdu, bt_mesh_net_flags(sub)); + net_buf_simple_add_be32(pdu, bt_mesh.iv_index); #endif net_buf_simple_add_be16(pdu, prov_device.node->addr); net_buf_simple_add(pdu, 8); /* For MIC */ From 1815c9cd627852d055edeedf86d6348d9b923956 Mon Sep 17 00:00:00 2001 From: yyy Date: Mon, 9 Dec 2024 19:30:14 +0800 Subject: [PATCH 1157/1333] add blemesh_shell demo for linux --- nimble/host/mesh/src/testing.c | 18 +- porting/examples/linux_blemesh_shell/Makefile | 110 + .../examples/linux_blemesh_shell/README.md | 76 + .../include/console/console_port.h | 40 + .../linux_blemesh_shell/include/shell/shell.h | 220 ++ .../include/syscfg/syscfg.h | 1934 +++++++++++++++++ .../include/sysflash/sysflash.h | 51 + .../linux_blemesh_shell/shell/console_port.c | 88 + .../linux_blemesh_shell/shell/shell_port.c | 230 ++ .../examples/linux_blemesh_shell/src/ble.c | 503 +++++ .../examples/linux_blemesh_shell/src/main.c | 106 + 11 files changed, 3370 insertions(+), 6 deletions(-) create mode 100644 porting/examples/linux_blemesh_shell/Makefile create mode 100644 porting/examples/linux_blemesh_shell/README.md create mode 100644 porting/examples/linux_blemesh_shell/include/console/console_port.h create mode 100644 porting/examples/linux_blemesh_shell/include/shell/shell.h create mode 100644 porting/examples/linux_blemesh_shell/include/syscfg/syscfg.h create mode 100644 porting/examples/linux_blemesh_shell/include/sysflash/sysflash.h create mode 100644 porting/examples/linux_blemesh_shell/shell/console_port.c create mode 100644 porting/examples/linux_blemesh_shell/shell/shell_port.c create mode 100644 porting/examples/linux_blemesh_shell/src/ble.c create mode 100644 porting/examples/linux_blemesh_shell/src/main.c diff --git a/nimble/host/mesh/src/testing.c b/nimble/host/mesh/src/testing.c index 7ee11a1373..b8e46366b1 100644 --- a/nimble/host/mesh/src/testing.c +++ b/nimble/host/mesh/src/testing.c @@ -94,16 +94,22 @@ void bt_test_mesh_trans_incomp_timer_exp(void) int bt_test_mesh_lpn_group_add(uint16_t group) { - bt_mesh_lpn_group_add(group); - - return 0; +#if MYNEWT_VAL(BLE_MESH_LOW_POWER) + bt_mesh_lpn_group_add(group); + return 0; +#else + return -ENOTSUP; +#endif } int bt_test_mesh_lpn_group_remove(uint16_t *groups, size_t groups_count) { - bt_mesh_lpn_group_del(groups, groups_count); - - return 0; +#if MYNEWT_VAL(BLE_MESH_LOW_POWER) + bt_mesh_lpn_group_del(groups, groups_count); + return 0; +#else + return -ENOTSUP; +#endif } int bt_test_mesh_rpl_clear(void) diff --git a/porting/examples/linux_blemesh_shell/Makefile b/porting/examples/linux_blemesh_shell/Makefile new file mode 100644 index 0000000000..c90f87781f --- /dev/null +++ b/porting/examples/linux_blemesh_shell/Makefile @@ -0,0 +1,110 @@ +# +# 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. +# + +# Toolchain commands +CROSS_COMPILE ?= +CC := ccache $(CROSS_COMPILE)gcc +CXX := ccache $(CROSS_COMPILE)g++ +LD := $(CROSS_COMPILE)gcc +AR := $(CROSS_COMPILE)ar +AS := $(CROSS_COMPILE)as +NM := $(CROSS_COMPILE)nm +OBJDUMP := $(CROSS_COMPILE)objdump +OBJCOPY := $(CROSS_COMPILE)objcopy +SIZE := $(CROSS_COMPILE)size + +# Configure NimBLE variables +NIMBLE_ROOT := ../../.. +NIMBLE_CFG_TINYCRYPT := 1 + +# Skip files that don't build for this port +NIMBLE_IGNORE := $(NIMBLE_ROOT)/porting/nimble/src/hal_timer.c \ + $(NIMBLE_ROOT)/porting/nimble/src/os_cputime.c \ + $(NIMBLE_ROOT)/porting/nimble/src/os_cputime_pwr2.c \ + $(NULL) + +include $(NIMBLE_ROOT)/porting/nimble/Makefile.defs +include $(NIMBLE_ROOT)/porting/nimble/Makefile.mesh + +SRC := $(NIMBLE_SRC) + +# Source files for NPL OSAL +SRC += \ + $(wildcard $(NIMBLE_ROOT)/porting/npl/linux/src/*.c) \ + $(wildcard $(NIMBLE_ROOT)/porting/npl/linux/src/*.cc) \ + $(wildcard $(NIMBLE_ROOT)/nimble/transport/socket/src/*.c) \ + $(TINYCRYPT_SRC) \ + $(wildcard $(NIMBLE_ROOT)/nimble/host/mesh/src/*.c) \ + $(NULL) + +# Source files for demo app +SRC += \ + ./src/main.c \ + ./src/ble.c \ + ./shell/shell_port.c \ + ./shell/console_port.c \ + $(NULL) + +# Add NPL and all NimBLE directories to include paths +INC = \ + ./include \ + $(NIMBLE_ROOT)/porting/npl/linux/include \ + $(NIMBLE_ROOT)/porting/npl/linux/src \ + $(NIMBLE_ROOT)/nimble/transport/socket/include \ + $(NIMBLE_INCLUDE) \ + $(TINYCRYPT_INCLUDE) \ + $(NULL) + +INCLUDES := $(addprefix -I, $(INC)) + +SRC_C = $(filter %.c, $(SRC)) +SRC_CC = $(filter %.cc, $(SRC)) + +OBJ := $(SRC_C:.c=.o) +OBJ += $(SRC_CC:.cc=.o) + +TINYCRYPT_OBJ := $(TINYCRYPT_SRC:.c=.o) + +CFLAGS = \ + $(NIMBLE_CFLAGS) \ + $(INCLUDES) \ + -g \ + -D_GNU_SOURCE \ + $(NULL) + +LIBS := $(NIMBLE_LDFLAGS) -lrt -lpthread -lstdc++ + +.PHONY: all clean +.DEFAULT: all + +all: nimble-linux-blemesh-shell + +clean: + rm $(OBJ) -f + rm nimble-linux-blemesh-shell -f + +$(TINYCRYPT_OBJ): CFLAGS+=$(TINYCRYPT_CFLAGS) + +%.o: %.c + $(CC) -c $(INCLUDES) $(CFLAGS) -o $@ $< + +%.o: %.cc + $(CXX) -c $(INCLUDES) $(CFLAGS) -o $@ $< + +nimble-linux-blemesh-shell: $(OBJ) $(TINYCRYPT_OBJ) + $(LD) -o $@ $^ $(LIBS) + $(SIZE) $@ diff --git a/porting/examples/linux_blemesh_shell/README.md b/porting/examples/linux_blemesh_shell/README.md new file mode 100644 index 0000000000..414fc7c2d6 --- /dev/null +++ b/porting/examples/linux_blemesh_shell/README.md @@ -0,0 +1,76 @@ + + +# Apache Mynewt NimBLE + +## Overview + +See https://mynewt.apache.org/latest/network + +## Building + +NimBLE is usually built as a part of Apache Mynewt OS, but ports for +other RTOS-es are also available. + +### Linux + +1. Build the sample application + +```no-highlight + cd porting/examples/linux_blemesh_shell + make +``` + +2. Run the sample application + +First insert a USB Bluetooth dongle. These are typically BLE 4.0 capable. + +Verify the dongle is connected with hciconfig: + +```no-highlight + $ hciconfig +hci0: Type: BR/EDR Bus: USB + BD Address: 00:1B:DC:06:62:5E ACL MTU: 310:10 SCO MTU: 64:8 + DOWN + RX bytes:5470 acl:0 sco:0 events:40 errors:0 + TX bytes:5537 acl:176 sco:0 commands:139 errors:1 +``` + +Then run the application built in step one. The application is configured +in sysconfig.h to use hci0. + +```no-highlight + cd porting/examples/linux_blemesh_shell + sudo ./nimble-linux-blemesh-shell +``` + +3. Run shell commands + +This example reads input form console, then execute all commands supported by nimble/host/mesh/src/shell.c + + +some example commands: + +```no-highlight + mesh>help + mesh>provision 0 1 0 + mesh>provision-adv c70512201872a85c9046a3e67ef1c55e 0 2 0 +``` diff --git a/porting/examples/linux_blemesh_shell/include/console/console_port.h b/porting/examples/linux_blemesh_shell/include/console/console_port.h new file mode 100644 index 0000000000..439ac9f3e6 --- /dev/null +++ b/porting/examples/linux_blemesh_shell/include/console/console_port.h @@ -0,0 +1,40 @@ +/* + * 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 __CONSOLE_PORT_H__ +#define __CONSOLE_PORT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nimble/nimble_npl.h" +struct os_eventq; + +void console_set_queues(struct os_eventq *avail, struct os_eventq *lines); + +void console_set_event_cb(ble_npl_event_fn *cb); + +int console_init(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/porting/examples/linux_blemesh_shell/include/shell/shell.h b/porting/examples/linux_blemesh_shell/include/shell/shell.h new file mode 100644 index 0000000000..75130487d5 --- /dev/null +++ b/porting/examples/linux_blemesh_shell/include/shell/shell.h @@ -0,0 +1,220 @@ +/* + * 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 __SHELL_H__ +#define __SHELL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "syscfg/syscfg.h" + +/** + * porting for linux platform, modification of shell.c is not needed + */ +#include "nimble/nimble_npl.h" +#define TASK_DEFAULT_PRIORITY 1 +#define TASK_DEFAULT_STACK NULL +#define TASK_DEFAULT_STACK_SIZE 768 + +#define OS_TASK_STACK_DEFINE(g_blemesh_shell_stack, BLE_MESH_SHELL_STACK_SIZE) \ + unsigned g_blemesh_shell_stack = BLE_MESH_SHELL_STACK_SIZE; + +#define os_task ble_npl_task +#define os_eventq ble_npl_eventq +#define os_event ble_npl_event +#define OS_WAIT_FOREVER (-1) + +void ble_npl_eventq_run(struct ble_npl_eventq *evq); + +#define os_eventq_init(q) ble_npl_eventq_init(q) +#define os_eventq_run(q) ble_npl_eventq_run(q) +#define os_task_init(task, name, func, arg, prio, sanity_itvl, stack_bottom, stack_size) \ + ble_npl_task_init(task, name, (ble_npl_task_func_t)func, arg, TASK_DEFAULT_PRIORITY, sanity_itvl, NULL, stack_size) + +void handle_shell_evt(struct os_event *ev); + +int cmd_mesh_init(int argc, char *argv[]); + +void ble_mesh_shell_init(void); + +#ifndef MYNEWT_VAL_SHELL_CMD_ARGC_MAX +#define MYNEWT_VAL_SHELL_CMD_ARGC_MAX (16) +#endif + +/* + * The shell.h below is copied from mynewt core + */ +struct os_eventq; +struct shell_cmd; +struct streamer; + +/** Command IDs in the "shell" newtmgr group. */ +#define SHELL_NMGR_OP_EXEC 0 + +/** @brief Callback called when command is entered. + * + * @param argc Number of parameters passed. + * @param argv Array of option strings. First option is always command name. + * + * @return 0 in case of success or negative value in case of error. + */ +typedef int (*shell_cmd_func_t)(int argc, char *argv[]); + +/** + * @brief Callback for "extended" shell commands. + * + * @param cmd The shell command being executed. + * @param argc Number of arguments passed. + * @param argv Array of option strings. First option is always + * command name. + * @param streamer The streamer to write shell output to. + * + * @return 0 on success; SYS_E[...] on failure. + */ +typedef int (*shell_cmd_ext_func_t)(const struct shell_cmd *cmd, + int argc, char *argv[], + struct streamer *streamer); + +struct shell_param { + const char *param_name; + const char *help; +}; + +struct shell_cmd_help { + const char *summary; + const char *usage; + const struct shell_param *params; +}; + +struct shell_cmd { + uint8_t sc_ext : 1; /* 1 if this is an extended shell comand. */ + union { + shell_cmd_func_t sc_cmd_func; + shell_cmd_ext_func_t sc_cmd_ext_func; + }; + + const char *sc_cmd; + const struct shell_cmd_help *help; +}; + +struct shell_module { + const char *name; + const struct shell_cmd *commands; +}; + +#if MYNEWT_VAL(SHELL_CMD_HELP) +#define SHELL_HELP_(help_) (help_) +#else +#define SHELL_HELP_(help_) NULL +#endif + +/** + * @brief constructs a legacy shell command. + */ +#define SHELL_CMD(cmd_, func_, help_) { \ + .sc_ext = 0, \ + .sc_cmd_func = func_, \ + .sc_cmd = cmd_, \ + .help = SHELL_HELP_(help_), \ +} + +/** + * @brief constructs an extended shell command. + */ +#define SHELL_CMD_EXT(cmd_, func_, help_) { \ + .sc_ext = 1, \ + .sc_cmd_ext_func = func_, \ + .sc_cmd = cmd_, \ + .help = SHELL_HELP_(help_), \ +} + +/** @brief Register a shell_module object + * + * @param shell_name Module name to be entered in shell console. + * + * @param shell_commands Array of commands to register. + * The array should be terminated with an empty element. + */ +int shell_register(const char *shell_name, + const struct shell_cmd *shell_commands); + +/** @brief Optionally register an app default cmd handler. + * + * @param handler To be called if no cmd found in cmds registered with + * shell_init. + */ +void shell_register_app_cmd_handler(shell_cmd_func_t handler); + +/** @brief Callback to get the current prompt. + * + * @returns Current prompt string. + */ +typedef const char *(*shell_prompt_function_t)(void); + +/** @brief Optionally register a custom prompt callback. + * + * @param handler To be called to get the current prompt. + */ +void shell_register_prompt_handler(shell_prompt_function_t handler); + +/** @brief Optionally register a default module, to avoid typing it in + * shell console. + * + * @param name Module name. + */ +void shell_register_default_module(const char *name); + +/** @brief Optionally set event queue to process shell command events + * + * @param evq Event queue to be used in shell + */ +void shell_evq_set(struct os_eventq *evq); + +/** + * @brief Processes a set of arguments and executes their corresponding shell + * command. + * + * @param argc The argument count (including command name). + * @param argv The argument list ([0] is command name). + * @param streamer The streamer to send output to. + * + * @return 0 on success; SYS_E[...] on failure. + */ +int shell_exec(int argc, char **argv, struct streamer *streamer); + +#if MYNEWT_VAL(SHELL_MGMT) +struct os_mbuf; +typedef int (*shell_nlip_input_func_t)(struct os_mbuf *, void *arg); +int shell_nlip_input_register(shell_nlip_input_func_t nf, void *arg); +int shell_nlip_output(struct os_mbuf *m); +#endif + +#if MYNEWT_VAL(SHELL_COMPAT) +int shell_cmd_register(const struct shell_cmd *sc); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* __SHELL_H__ */ diff --git a/porting/examples/linux_blemesh_shell/include/syscfg/syscfg.h b/porting/examples/linux_blemesh_shell/include/syscfg/syscfg.h new file mode 100644 index 0000000000..deaded7db0 --- /dev/null +++ b/porting/examples/linux_blemesh_shell/include/syscfg/syscfg.h @@ -0,0 +1,1934 @@ +/* + * 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_MYNEWT_SYSCFG_ +#define H_MYNEWT_SYSCFG_ + +#define MYNEWT_VAL(_name) MYNEWT_VAL_ ## _name +#define MYNEWT_VAL_CHOICE(_name, _val) MYNEWT_VAL_ ## _name ## __ ## _val + +#ifndef MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE +#define MYNEWT_VAL_TINYCRYPT_SYSINIT_STAGE (200) +#endif + +#ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME +#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_TRNG_DEV_NAME "trng" +#endif + +#ifndef MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG +#define MYNEWT_VAL_TINYCRYPT_UECC_RNG_USE_TRNG (0) +#endif + +/*** @apache-mynewt-core/hw/bsp/native */ +#ifndef MYNEWT_VAL_BSP_SIMULATED +#define MYNEWT_VAL_BSP_SIMULATED (1) +#endif + +/*** @apache-mynewt-core/hw/hal */ +#ifndef MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS +#define MYNEWT_VAL_HAL_ENABLE_SOFTWARE_BREAKPOINTS (1) +#endif + +#ifndef MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT +#define MYNEWT_VAL_HAL_FLASH_MAX_DEVICE_COUNT (0) +#endif + +#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ +#define MYNEWT_VAL_HAL_FLASH_VERIFY_BUF_SZ (16) +#endif + +#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_ERASES +#define MYNEWT_VAL_HAL_FLASH_VERIFY_ERASES (0) +#endif + +#ifndef MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES +#define MYNEWT_VAL_HAL_FLASH_VERIFY_WRITES (0) +#endif + +#ifndef MYNEWT_VAL_HAL_SBRK +#define MYNEWT_VAL_HAL_SBRK (1) +#endif + +#ifndef MYNEWT_VAL_HAL_SYSTEM_RESET_CB +#define MYNEWT_VAL_HAL_SYSTEM_RESET_CB (0) +#endif + +/*** @apache-mynewt-core/hw/mcu/native */ +#ifndef MYNEWT_VAL_I2C_0 +#define MYNEWT_VAL_I2C_0 (0) +#endif + +#ifndef MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE +#define MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE (1) +#endif + +#ifndef MYNEWT_VAL_MCU_FLASH_STYLE_NORDIC +#define MYNEWT_VAL_MCU_FLASH_STYLE_NORDIC (0) +#endif + +#ifndef MYNEWT_VAL_MCU_FLASH_STYLE_ST +#define MYNEWT_VAL_MCU_FLASH_STYLE_ST (1) +#endif + +#ifndef MYNEWT_VAL_MCU_NATIVE +#define MYNEWT_VAL_MCU_NATIVE (1) +#endif + +#ifndef MYNEWT_VAL_MCU_NATIVE_USE_SIGNALS +#define MYNEWT_VAL_MCU_NATIVE_USE_SIGNALS (1) +#endif + +#ifndef MYNEWT_VAL_MCU_TIMER_POLLER_PRIO +#define MYNEWT_VAL_MCU_TIMER_POLLER_PRIO (0) +#endif + +#ifndef MYNEWT_VAL_MCU_UART_POLLER_PRIO +#define MYNEWT_VAL_MCU_UART_POLLER_PRIO (1) +#endif + +/*** @apache-mynewt-core/kernel/os */ +#ifndef MYNEWT_VAL_FLOAT_USER +#define MYNEWT_VAL_FLOAT_USER (0) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-core/kernel/os) */ +#ifndef MYNEWT_VAL_MSYS_1_BLOCK_COUNT +#define MYNEWT_VAL_MSYS_1_BLOCK_COUNT (80) +#endif + +#ifndef MYNEWT_VAL_MSYS_1_BLOCK_SIZE +#define MYNEWT_VAL_MSYS_1_BLOCK_SIZE (292) +#endif + +#ifndef MYNEWT_VAL_MSYS_1_SANITY_MIN_COUNT +#define MYNEWT_VAL_MSYS_1_SANITY_MIN_COUNT (0) +#endif + +#ifndef MYNEWT_VAL_MSYS_2_BLOCK_COUNT +#define MYNEWT_VAL_MSYS_2_BLOCK_COUNT (0) +#endif + +#ifndef MYNEWT_VAL_MSYS_2_BLOCK_SIZE +#define MYNEWT_VAL_MSYS_2_BLOCK_SIZE (0) +#endif + +#ifndef MYNEWT_VAL_MSYS_2_SANITY_MIN_COUNT +#define MYNEWT_VAL_MSYS_2_SANITY_MIN_COUNT (0) +#endif + +#ifndef MYNEWT_VAL_MSYS_SANITY_TIMEOUT +#define MYNEWT_VAL_MSYS_SANITY_TIMEOUT (60000) +#endif + +#ifndef MYNEWT_VAL_OS_ASSERT_CB +#define MYNEWT_VAL_OS_ASSERT_CB (0) +#endif + +#ifndef MYNEWT_VAL_OS_CLI +#define MYNEWT_VAL_OS_CLI (0) +#endif + +#ifndef MYNEWT_VAL_OS_COREDUMP +#define MYNEWT_VAL_OS_COREDUMP (0) +#endif + +#ifndef MYNEWT_VAL_OS_COREDUMP_CB +#define MYNEWT_VAL_OS_COREDUMP_CB (0) +#endif + +#ifndef MYNEWT_VAL_OS_CPUTIME_FREQ +#define MYNEWT_VAL_OS_CPUTIME_FREQ (1000000) +#endif + +#ifndef MYNEWT_VAL_OS_CPUTIME_TIMER_NUM +#define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (0) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ +#ifndef MYNEWT_VAL_OS_CRASH_FILE_LINE +#define MYNEWT_VAL_OS_CRASH_FILE_LINE (1) +#endif + +#ifndef MYNEWT_VAL_OS_CRASH_LOG +#define MYNEWT_VAL_OS_CRASH_LOG (0) +#endif + +#ifndef MYNEWT_VAL_OS_CRASH_RESTORE_REGS +#define MYNEWT_VAL_OS_CRASH_RESTORE_REGS (0) +#endif + +#ifndef MYNEWT_VAL_OS_CRASH_STACKTRACE +#define MYNEWT_VAL_OS_CRASH_STACKTRACE (0) +#endif + +#ifndef MYNEWT_VAL_OS_CTX_SW_STACK_CHECK +#define MYNEWT_VAL_OS_CTX_SW_STACK_CHECK (0) +#endif + +#ifndef MYNEWT_VAL_OS_CTX_SW_STACK_GUARD +#define MYNEWT_VAL_OS_CTX_SW_STACK_GUARD (4) +#endif + +#ifndef MYNEWT_VAL_OS_DEBUG_MODE +#define MYNEWT_VAL_OS_DEBUG_MODE (0) +#endif + +#ifndef MYNEWT_VAL_OS_DEFAULT_IRQ_CB +#define MYNEWT_VAL_OS_DEFAULT_IRQ_CB (0) +#endif + +#ifndef MYNEWT_VAL_OS_EVENTQ_DEBUG +#define MYNEWT_VAL_OS_EVENTQ_DEBUG (0) +#endif + +#ifndef MYNEWT_VAL_OS_EVENTQ_MONITOR +#define MYNEWT_VAL_OS_EVENTQ_MONITOR (0) +#endif + +#ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX +#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MAX (600000) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/kernel/os) */ +#ifndef MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN +#define MYNEWT_VAL_OS_IDLE_TICKLESS_MS_MIN (1) +#endif + +#ifndef MYNEWT_VAL_OS_MAIN_STACK_SIZE +#define MYNEWT_VAL_OS_MAIN_STACK_SIZE (1024) +#endif + +#ifndef MYNEWT_VAL_OS_MAIN_TASK_PRIO +#define MYNEWT_VAL_OS_MAIN_TASK_PRIO (127) +#endif + +#ifndef MYNEWT_VAL_OS_MAIN_TASK_SANITY_ITVL_MS +#define MYNEWT_VAL_OS_MAIN_TASK_SANITY_ITVL_MS (0) +#endif + +#ifndef MYNEWT_VAL_OS_MEMPOOL_CHECK +#define MYNEWT_VAL_OS_MEMPOOL_CHECK (0) +#endif + +#ifndef MYNEWT_VAL_OS_MEMPOOL_GUARD +#define MYNEWT_VAL_OS_MEMPOOL_GUARD (0) +#endif + +#ifndef MYNEWT_VAL_OS_MEMPOOL_POISON +#define MYNEWT_VAL_OS_MEMPOOL_POISON (0) +#endif + +#ifndef MYNEWT_VAL_OS_SCHEDULING +#define MYNEWT_VAL_OS_SCHEDULING (1) +#endif + +#ifndef MYNEWT_VAL_OS_SYSINIT_STAGE +#define MYNEWT_VAL_OS_SYSINIT_STAGE (0) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW +#define MYNEWT_VAL_OS_SYSVIEW (0) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_CALLOUT +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_CALLOUT (1) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_EVENTQ +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_EVENTQ (1) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_MBUF +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_MBUF (0) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_MEMPOOL +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_MEMPOOL (0) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_MUTEX +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_MUTEX (1) +#endif + +#ifndef MYNEWT_VAL_OS_SYSVIEW_TRACE_SEM +#define MYNEWT_VAL_OS_SYSVIEW_TRACE_SEM (1) +#endif + +#ifndef MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME +#define MYNEWT_VAL_OS_TASK_RUN_TIME_CPUTIME (0) +#endif + +/* Overridden by @apache-mynewt-core/hw/mcu/native (defined by @apache-mynewt-core/kernel/os) */ +#ifndef MYNEWT_VAL_OS_TICKS_PER_SEC +#define MYNEWT_VAL_OS_TICKS_PER_SEC (100) +#endif + +#ifndef MYNEWT_VAL_OS_TIME_DEBUG +#define MYNEWT_VAL_OS_TIME_DEBUG (0) +#endif + +#ifndef MYNEWT_VAL_OS_WATCHDOG_MONITOR +#define MYNEWT_VAL_OS_WATCHDOG_MONITOR (0) +#endif + +#ifndef MYNEWT_VAL_SANITY_INTERVAL +#define MYNEWT_VAL_SANITY_INTERVAL (15000) +#endif + +#ifndef MYNEWT_VAL_WATCHDOG_INTERVAL +#define MYNEWT_VAL_WATCHDOG_INTERVAL (30000) +#endif + +/*** @apache-mynewt-core/net/ip/native_sockets */ +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX +#define MYNEWT_VAL_NATIVE_SOCKETS_MAX (8) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_MAX_UDP +#define MYNEWT_VAL_NATIVE_SOCKETS_MAX_UDP (2048) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_POLL_INTERVAL_MS +#define MYNEWT_VAL_NATIVE_SOCKETS_POLL_INTERVAL_MS (200) +#endif + +#undef MYNEWT_VAL_NATIVE_SOCKETS_POLL_ITVL + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_PRIO +#define MYNEWT_VAL_NATIVE_SOCKETS_PRIO (2) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_STACK_SZ +#define MYNEWT_VAL_NATIVE_SOCKETS_STACK_SZ (4096) +#endif + +#ifndef MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE +#define MYNEWT_VAL_NATIVE_SOCKETS_SYSINIT_STAGE (200) +#endif + +/*** @apache-mynewt-core/sys/console/stub */ +/* + #ifndef MYNEWT_VAL_CONSOLE_UART_BAUD + #define MYNEWT_VAL_CONSOLE_UART_BAUD (115200) + #endif + + #ifndef MYNEWT_VAL_CONSOLE_UART_DEV + #define MYNEWT_VAL_CONSOLE_UART_DEV "uart0" + #endif + + #ifndef MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL + #define MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL (UART_FLOW_CTL_NONE) + #endif + */ + +/*** @apache-mynewt-core/sys/flash_map */ +#ifndef MYNEWT_VAL_FLASH_MAP_MAX_AREAS +#define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10) +#endif + +#ifndef MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG +#define MYNEWT_VAL_FLASH_MAP_SUPPORT_MFG (0) +#endif + +#ifndef MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE +#define MYNEWT_VAL_FLASH_MAP_SYSINIT_STAGE (9) +#endif + +/*** @apache-mynewt-core/sys/log/common */ +#ifndef MYNEWT_VAL_DFLT_LOG_LVL +#define MYNEWT_VAL_DFLT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_DFLT_LOG_MOD +#define MYNEWT_VAL_DFLT_LOG_MOD (0) +#endif + +#ifndef MYNEWT_VAL_LOG_GLOBAL_IDX +#define MYNEWT_VAL_LOG_GLOBAL_IDX (1) +#endif + +/*** @apache-mynewt-core/sys/log/modlog */ +#ifndef MYNEWT_VAL_MODLOG_CONSOLE_DFLT +#define MYNEWT_VAL_MODLOG_CONSOLE_DFLT (1) +#endif + +#ifndef MYNEWT_VAL_MODLOG_LOG_MACROS +#define MYNEWT_VAL_MODLOG_LOG_MACROS (0) +#endif + +#ifndef MYNEWT_VAL_MODLOG_MAX_MAPPINGS +#define MYNEWT_VAL_MODLOG_MAX_MAPPINGS (16) +#endif + +#ifndef MYNEWT_VAL_MODLOG_MAX_PRINTF_LEN +#define MYNEWT_VAL_MODLOG_MAX_PRINTF_LEN (128) +#endif + +#ifndef MYNEWT_VAL_MODLOG_SYSINIT_STAGE +#define MYNEWT_VAL_MODLOG_SYSINIT_STAGE (100) +#endif + +/*** @apache-mynewt-core/sys/log/stub */ +#ifndef MYNEWT_VAL_LOG_CONSOLE +#define MYNEWT_VAL_LOG_CONSOLE (1) +#endif + +#ifndef MYNEWT_VAL_LOG_FCB +#define MYNEWT_VAL_LOG_FCB (0) +#endif + +#ifndef MYNEWT_VAL_LOG_FCB_SLOT1 +#define MYNEWT_VAL_LOG_FCB_SLOT1 (0) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-core/sys/log/stub) */ +#ifndef MYNEWT_VAL_LOG_LEVEL +#define MYNEWT_VAL_LOG_LEVEL (0) +#endif + +/*** @apache-mynewt-core/sys/sys */ +#ifndef MYNEWT_VAL_DEBUG_PANIC_ENABLED +#define MYNEWT_VAL_DEBUG_PANIC_ENABLED (1) +#endif + +/*** @apache-mynewt-core/sys/sysdown */ +#ifndef MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN +#define MYNEWT_VAL_SYSDOWN_CONSTRAIN_DOWN (1) +#endif + +#ifndef MYNEWT_VAL_SYSDOWN_PANIC_FILE_LINE +#define MYNEWT_VAL_SYSDOWN_PANIC_FILE_LINE (0) +#endif + +#ifndef MYNEWT_VAL_SYSDOWN_PANIC_MESSAGE +#define MYNEWT_VAL_SYSDOWN_PANIC_MESSAGE (0) +#endif + +#ifndef MYNEWT_VAL_SYSDOWN_TIMEOUT_MS +#define MYNEWT_VAL_SYSDOWN_TIMEOUT_MS (10000) +#endif + +/*** @apache-mynewt-core/sys/sysinit */ +#ifndef MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT +#define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ +#ifndef MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE +#define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (1) +#endif + +/* Overridden by @apache-mynewt-core/hw/bsp/native (defined by @apache-mynewt-core/sys/sysinit) */ +#ifndef MYNEWT_VAL_SYSINIT_PANIC_MESSAGE +#define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (1) +#endif + +/*** @apache-mynewt-core/util/rwlock */ +#ifndef MYNEWT_VAL_RWLOCK_DEBUG +#define MYNEWT_VAL_RWLOCK_DEBUG (0) +#endif + +/*** @apache-mynewt-nimble/nimble */ +#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING +#define MYNEWT_VAL_BLE_CONN_SUBRATING (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EXT_ADV +#define MYNEWT_VAL_BLE_EXT_ADV (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE +#define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (31) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_VS +#define MYNEWT_VAL_BLE_HCI_VS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET +#define MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET (0) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO +#define MYNEWT_VAL_BLE_ISO (0) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_BROADCAST_SINK +#define MYNEWT_VAL_BLE_ISO_BROADCAST_SINK (0) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_BROADCAST_SOURCE +#define MYNEWT_VAL_BLE_ISO_BROADCAST_SOURCE (0) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_TEST +#define MYNEWT_VAL_BLE_ISO_TEST (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MAX_CONNECTIONS +#define MYNEWT_VAL_BLE_MAX_CONNECTIONS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS +#define MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES +#define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV +#define MYNEWT_VAL_BLE_PERIODIC_ADV (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS +#define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER +#define MYNEWT_VAL_BLE_PERIODIC_ADV_SYNC_TRANSFER (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PHY_2M +#define MYNEWT_VAL_BLE_PHY_2M (0) +#endif + +#ifndef MYNEWT_VAL_BLE_PHY_CODED +#define MYNEWT_VAL_BLE_PHY_CODED (0) +#endif + +#ifndef MYNEWT_VAL_BLE_POWER_CONTROL +#define MYNEWT_VAL_BLE_POWER_CONTROL (0) +#endif + +#ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER +#define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ROLE_CENTRAL +#define MYNEWT_VAL_BLE_ROLE_CENTRAL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ROLE_OBSERVER +#define MYNEWT_VAL_BLE_ROLE_OBSERVER (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ROLE_PERIPHERAL +#define MYNEWT_VAL_BLE_ROLE_PERIPHERAL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_VERSION +#define MYNEWT_VAL_BLE_VERSION (50) +#endif + +#ifndef MYNEWT_VAL_BLE_WHITELIST +#define MYNEWT_VAL_BLE_WHITELIST (1) +#endif + +/*** @apache-mynewt-nimble/nimble/host */ +#ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU +#define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO +#define MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_TYPE +#define MYNEWT_VAL_BLE_ATT_SVR_FIND_TYPE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_INDICATE +#define MYNEWT_VAL_BLE_ATT_SVR_INDICATE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES +#define MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES (64) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY +#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI +#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI (MYNEWT_VAL_BLE_ATT_SVR_NOTIFY && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE +#define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE_TMO +#define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE_TMO (30000) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ +#define MYNEWT_VAL_BLE_ATT_SVR_READ (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_BLOB +#define MYNEWT_VAL_BLE_ATT_SVR_READ_BLOB (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_GROUP_TYPE +#define MYNEWT_VAL_BLE_ATT_SVR_READ_GROUP_TYPE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_MULT +#define MYNEWT_VAL_BLE_ATT_SVR_READ_MULT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE +#define MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_SIGNED_WRITE +#define MYNEWT_VAL_BLE_ATT_SVR_SIGNED_WRITE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_WRITE +#define MYNEWT_VAL_BLE_ATT_SVR_WRITE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP +#define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) +#endif + +#ifndef MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS +#define MYNEWT_VAL_BLE_AUDIO_MAX_CODEC_RECORDS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM +#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL +#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD +#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27) +#endif + +#ifndef MYNEWT_VAL_BLE_EATT_MTU +#define MYNEWT_VAL_BLE_EATT_MTU (128) +#endif + +#ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE +#define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_CHRS +#define MYNEWT_VAL_BLE_GATT_DISC_ALL_CHRS (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_DSCS +#define MYNEWT_VAL_BLE_GATT_DISC_ALL_DSCS (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_SVCS +#define MYNEWT_VAL_BLE_GATT_DISC_ALL_SVCS (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_DISC_CHR_UUID +#define MYNEWT_VAL_BLE_GATT_DISC_CHR_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_DISC_SVC_UUID +#define MYNEWT_VAL_BLE_GATT_DISC_SVC_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_FIND_INC_SVCS +#define MYNEWT_VAL_BLE_GATT_FIND_INC_SVCS (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_INDICATE +#define MYNEWT_VAL_BLE_GATT_INDICATE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_MAX_PROCS +#define MYNEWT_VAL_BLE_GATT_MAX_PROCS (4) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY +#define MYNEWT_VAL_BLE_GATT_NOTIFY (1) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE +#define MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE ((MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ +#define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ_LONG +#define MYNEWT_VAL_BLE_GATT_READ_LONG (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ_MAX_ATTRS +#define MYNEWT_VAL_BLE_GATT_READ_MAX_ATTRS (8) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ_MULT +#define MYNEWT_VAL_BLE_GATT_READ_MULT (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ_MULT_VAR +#define MYNEWT_VAL_BLE_GATT_READ_MULT_VAR (MYNEWT_VAL_BLE_ROLE_CENTRAL && (MYNEWT_VAL_BLE_VERSION >= 52)) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ_UUID +#define MYNEWT_VAL_BLE_GATT_READ_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_RESUME_RATE +#define MYNEWT_VAL_BLE_GATT_RESUME_RATE (1000) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_SIGNED_WRITE +#define MYNEWT_VAL_BLE_GATT_SIGNED_WRITE (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_WRITE +#define MYNEWT_VAL_BLE_GATT_WRITE (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_WRITE_LONG +#define MYNEWT_VAL_BLE_GATT_WRITE_LONG (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_WRITE_MAX_ATTRS +#define MYNEWT_VAL_BLE_GATT_WRITE_MAX_ATTRS (4) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_WRITE_NO_RSP +#define MYNEWT_VAL_BLE_GATT_WRITE_NO_RSP (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_WRITE_RELIABLE +#define MYNEWT_VAL_BLE_GATT_WRITE_RELIABLE (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_HOST +#define MYNEWT_VAL_BLE_HOST (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_AUTO_START +#define MYNEWT_VAL_BLE_HS_AUTO_START (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_DEBUG +#define MYNEWT_VAL_BLE_HS_DEBUG (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_EXT_ADV_LEGACY_INSTANCE +#define MYNEWT_VAL_BLE_HS_EXT_ADV_LEGACY_INSTANCE (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL +#define MYNEWT_VAL_BLE_HS_FLOW_CTRL (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL_ITVL +#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_ITVL (1000) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL_THRESH +#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_THRESH (2) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT +#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT +#define MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_LOG_LVL +#define MYNEWT_VAL_BLE_HS_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_LOG_MOD +#define MYNEWT_VAL_BLE_HS_LOG_MOD (4) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS +#define MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_REQUIRE_OS +#define MYNEWT_VAL_BLE_HS_REQUIRE_OS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN +#define MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN_TIMEOUT +#define MYNEWT_VAL_BLE_HS_STOP_ON_SHUTDOWN_TIMEOUT (2000) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_HS_SYSINIT_STAGE (200) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM +#define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_COC_MPS +#define MYNEWT_VAL_BLE_L2CAP_COC_MPS (MYNEWT_VAL_MSYS_1_BLOCK_SIZE-8) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT +#define MYNEWT_VAL_BLE_L2CAP_COC_SDU_BUFF_COUNT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC +#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS +#define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_MAX_CHANS +#define MYNEWT_VAL_BLE_L2CAP_MAX_CHANS (3*MYNEWT_VAL_BLE_MAX_CONNECTIONS) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_RX_FRAG_TIMEOUT +#define MYNEWT_VAL_BLE_L2CAP_RX_FRAG_TIMEOUT (30000) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS +#define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BIGS +#define MYNEWT_VAL_BLE_ISO_MAX_BIGS (MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES) +#endif + +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES +#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host) */ +#ifndef MYNEWT_VAL_BLE_MESH +#define MYNEWT_VAL_BLE_MESH (1) +#endif + +#ifndef MYNEWT_VAL_BLE_RPA_TIMEOUT +#define MYNEWT_VAL_BLE_RPA_TIMEOUT (300) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_BONDING +#define MYNEWT_VAL_BLE_SM_BONDING (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_CSIS_SIRK +#define MYNEWT_VAL_BLE_SM_CSIS_SIRK (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_IO_CAP +#define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_NO_INPUT_OUTPUT) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_KEYPRESS +#define MYNEWT_VAL_BLE_SM_KEYPRESS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_LEGACY +#define MYNEWT_VAL_BLE_SM_LEGACY (1) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_LVL +#define MYNEWT_VAL_BLE_SM_LVL (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_MAX_PROCS +#define MYNEWT_VAL_BLE_SM_MAX_PROCS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_MITM +#define MYNEWT_VAL_BLE_SM_MITM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG +#define MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_OUR_KEY_DIST +#define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (0) +#endif + +/* Overridden by @apache-mynewt-nimble/nimble/host (defined by @apache-mynewt-nimble/nimble/host) */ +#ifndef MYNEWT_VAL_BLE_SM_SC +#define MYNEWT_VAL_BLE_SM_SC (1) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS +#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_SC_ONLY +#define MYNEWT_VAL_BLE_SM_SC_ONLY (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST +#define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (0) +#endif + +#ifndef MYNEWT_VAL_BLE_STORE_MAX_BONDS +#define MYNEWT_VAL_BLE_STORE_MAX_BONDS (3) +#endif + +#ifndef MYNEWT_VAL_BLE_STORE_MAX_CCCDS +#define MYNEWT_VAL_BLE_STORE_MAX_CCCDS (8) +#endif + +/*** @apache-mynewt-nimble/nimble/host/mesh */ +#ifndef MYNEWT_VAL_BLE_MESH_ACCESS_LAYER_MSG +#define MYNEWT_VAL_BLE_MESH_ACCESS_LAYER_MSG (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ACCESS_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_ACCESS_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ACCESS_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_ACCESS_LOG_MOD (10) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ADV +#define MYNEWT_VAL_BLE_MESH_ADV (1) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT +#define MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT (20) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ADV_EXT +#define MYNEWT_VAL_BLE_MESH_ADV_EXT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ADV_LEGACY +#define MYNEWT_VAL_BLE_MESH_ADV_LEGACY (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ADV_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_ADV_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ADV_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_ADV_LOG_MOD (11) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ADV_STACK_SIZE +#define MYNEWT_VAL_BLE_MESH_ADV_STACK_SIZE (768) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_ADV_TASK_PRIO +#define MYNEWT_VAL_BLE_MESH_ADV_TASK_PRIO (9) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_APP_KEY_COUNT +#define MYNEWT_VAL_BLE_MESH_APP_KEY_COUNT (4) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_BEACON_ENABLED +#define MYNEWT_VAL_BLE_MESH_BEACON_ENABLED (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_BEACON_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_BEACON_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_BEACON_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_BEACON_LOG_MOD (12) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_CDB +#define MYNEWT_VAL_BLE_MESH_CDB (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_CDB_APP_KEY_COUNT +#define MYNEWT_VAL_BLE_MESH_CDB_APP_KEY_COUNT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_CDB_NODE_COUNT +#define MYNEWT_VAL_BLE_MESH_CDB_NODE_COUNT (8) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_CDB_SUBNET_COUNT +#define MYNEWT_VAL_BLE_MESH_CDB_SUBNET_COUNT (1) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_CFG_CLI +#define MYNEWT_VAL_BLE_MESH_CFG_CLI (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_CRPL +#define MYNEWT_VAL_BLE_MESH_CRPL (10) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_CRYPTO_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_CRYPTO_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_CRYPTO_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_CRYPTO_LOG_MOD (13) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_CDB +#define MYNEWT_VAL_BLE_MESH_DEBUG_CDB (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_CFG +#define MYNEWT_VAL_BLE_MESH_DEBUG_CFG (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_USE_ID_ADDR +#define MYNEWT_VAL_BLE_MESH_DEBUG_USE_ID_ADDR (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_DEFAULT_TTL +#define MYNEWT_VAL_BLE_MESH_DEFAULT_TTL (7) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_DEVICE_NAME +#define MYNEWT_VAL_BLE_MESH_DEVICE_NAME "nimble-mesh-node" +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_DEV_UUID +#define MYNEWT_VAL_BLE_MESH_DEV_UUID (((uint8_t[16]) {0x11, 0x22, 0})) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND +#define MYNEWT_VAL_BLE_MESH_FRIEND (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_ENABLED +#define MYNEWT_VAL_BLE_MESH_FRIEND_ENABLED (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_FRIEND_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_FRIEND_LOG_MOD (14) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_LPN_COUNT +#define MYNEWT_VAL_BLE_MESH_FRIEND_LPN_COUNT (2) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_QUEUE_SIZE +#define MYNEWT_VAL_BLE_MESH_FRIEND_QUEUE_SIZE (16) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_RECV_WIN +#define MYNEWT_VAL_BLE_MESH_FRIEND_RECV_WIN (255) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_SEG_RX +#define MYNEWT_VAL_BLE_MESH_FRIEND_SEG_RX (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_SUB_LIST_SIZE +#define MYNEWT_VAL_BLE_MESH_FRIEND_SUB_LIST_SIZE (3) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_GATT +#define MYNEWT_VAL_BLE_MESH_GATT (1) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_GATT_PROXY +#define MYNEWT_VAL_BLE_MESH_GATT_PROXY (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_GATT_PROXY_ENABLED +#define MYNEWT_VAL_BLE_MESH_GATT_PROXY_ENABLED (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_GATT_SERVER +#define MYNEWT_VAL_BLE_MESH_GATT_SERVER (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_HEALTH_CLI +#define MYNEWT_VAL_BLE_MESH_HEALTH_CLI (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_HEARTBEAT_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_HEARTBEAT_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_HEARTBEAT_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_HEARTBEAT_LOG_MOD (26) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_IVU_DIVIDER +#define MYNEWT_VAL_BLE_MESH_IVU_DIVIDER (4) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_IV_UPDATE_SEQ_LIMIT +#define MYNEWT_VAL_BLE_MESH_IV_UPDATE_SEQ_LIMIT (0x800000) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_IV_UPDATE_TEST +#define MYNEWT_VAL_BLE_MESH_IV_UPDATE_TEST (1) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_LABEL_COUNT +#define MYNEWT_VAL_BLE_MESH_LABEL_COUNT (2) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_LOG_MOD (9) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LOOPBACK_BUFS +#define MYNEWT_VAL_BLE_MESH_LOOPBACK_BUFS (3) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_LOW_POWER +#define MYNEWT_VAL_BLE_MESH_LOW_POWER (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LOW_POWER_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_LOW_POWER_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LOW_POWER_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_LOW_POWER_LOG_MOD (15) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_LPN_AUTO +#define MYNEWT_VAL_BLE_MESH_LPN_AUTO (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_AUTO_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_LPN_AUTO_TIMEOUT (15) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_ESTABLISHMENT +#define MYNEWT_VAL_BLE_MESH_LPN_ESTABLISHMENT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_GROUPS +#define MYNEWT_VAL_BLE_MESH_LPN_GROUPS (10) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_INIT_POLL_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_LPN_INIT_POLL_TIMEOUT (MYNEWT_VAL_BLE_MESH_LPN_POLL_TIMEOUT) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_MIN_QUEUE_SIZE +#define MYNEWT_VAL_BLE_MESH_LPN_MIN_QUEUE_SIZE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_POLL_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_LPN_POLL_TIMEOUT (300) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_RECV_DELAY +#define MYNEWT_VAL_BLE_MESH_LPN_RECV_DELAY (100) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_RECV_WIN_FACTOR +#define MYNEWT_VAL_BLE_MESH_LPN_RECV_WIN_FACTOR (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_RETRY_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_LPN_RETRY_TIMEOUT (8) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_RSSI_FACTOR +#define MYNEWT_VAL_BLE_MESH_LPN_RSSI_FACTOR (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_SCAN_LATENCY +#define MYNEWT_VAL_BLE_MESH_LPN_SCAN_LATENCY (10) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_SUB_ALL_NODES_ADDR +#define MYNEWT_VAL_BLE_MESH_LPN_SUB_ALL_NODES_ADDR (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_MODEL_EXTENSIONS +#define MYNEWT_VAL_BLE_MESH_MODEL_EXTENSIONS (0) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_MODEL_GROUP_COUNT +#define MYNEWT_VAL_BLE_MESH_MODEL_GROUP_COUNT (2) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_MODEL_KEY_COUNT +#define MYNEWT_VAL_BLE_MESH_MODEL_KEY_COUNT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_MODEL_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_MODEL_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_MODEL_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_MODEL_LOG_MOD (16) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_MODEL_VND_MSG_CID_FORCE +#define MYNEWT_VAL_BLE_MESH_MODEL_VND_MSG_CID_FORCE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_MSG_CACHE_SIZE +#define MYNEWT_VAL_BLE_MESH_MSG_CACHE_SIZE (10) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_NETWORK_TRANSMIT_COUNT +#define MYNEWT_VAL_BLE_MESH_NETWORK_TRANSMIT_COUNT (2) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_NETWORK_TRANSMIT_INTERVAL +#define MYNEWT_VAL_BLE_MESH_NETWORK_TRANSMIT_INTERVAL (20) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_NET_BUF_USER_DATA_SIZE +#define MYNEWT_VAL_BLE_MESH_NET_BUF_USER_DATA_SIZE (4) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_NET_KEYS_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_NET_KEYS_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_NET_KEYS_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_NET_KEYS_LOG_MOD (23) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_NET_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_NET_LOG_LVL (2) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_NET_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_NET_LOG_MOD (17) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_NODE_ID_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_NODE_ID_TIMEOUT (60) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_OOB_INPUT_ACTIONS +#define MYNEWT_VAL_BLE_MESH_OOB_INPUT_ACTIONS (((BT_MESH_NO_INPUT))) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_OOB_INPUT_SIZE +#define MYNEWT_VAL_BLE_MESH_OOB_INPUT_SIZE (4) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_OOB_OUTPUT_ACTIONS +#define MYNEWT_VAL_BLE_MESH_OOB_OUTPUT_ACTIONS (((BT_MESH_DISPLAY_NUMBER))) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_OOB_OUTPUT_SIZE +#define MYNEWT_VAL_BLE_MESH_OOB_OUTPUT_SIZE (4) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_PB_ADV +#define MYNEWT_VAL_BLE_MESH_PB_ADV (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PB_ADV_RETRANS_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_PB_ADV_RETRANS_TIMEOUT (500) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_PB_GATT +#define MYNEWT_VAL_BLE_MESH_PB_GATT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PB_GATT_USE_DEVICE_NAME +#define MYNEWT_VAL_BLE_MESH_PB_GATT_USE_DEVICE_NAME (1) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_PROV +#define MYNEWT_VAL_BLE_MESH_PROV (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROVISIONER +#define MYNEWT_VAL_BLE_MESH_PROVISIONER (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROVISIONER_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_PROVISIONER_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROVISIONER_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_PROVISIONER_LOG_MOD (25) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROV_DEVICE +#define MYNEWT_VAL_BLE_MESH_PROV_DEVICE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROV_DEVICE_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_PROV_DEVICE_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROV_DEVICE_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_PROV_DEVICE_LOG_MOD (24) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROV_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_PROV_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROV_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_PROV_LOG_MOD (18) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROV_OOB_PUBLIC_KEY +#define MYNEWT_VAL_BLE_MESH_PROV_OOB_PUBLIC_KEY (0) +#endif + +/* Overridden by @apache-mynewt-nimble/nimble/host/mesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_PROXY +#define MYNEWT_VAL_BLE_MESH_PROXY (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROXY_FILTER_SIZE +#define MYNEWT_VAL_BLE_MESH_PROXY_FILTER_SIZE (3) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROXY_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_PROXY_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROXY_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_PROXY_LOG_MOD (19) +#endif + +/* Overridden by @apache-mynewt-nimble/nimble/host/mesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN +#define MYNEWT_VAL_BLE_MESH_PROXY_MSG_LEN (33) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROXY_USE_DEVICE_NAME +#define MYNEWT_VAL_BLE_MESH_PROXY_USE_DEVICE_NAME (0) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_RELAY +#define MYNEWT_VAL_BLE_MESH_RELAY (1) +#endif + +/* Value copied from BLE_MESH_RELAY */ +#ifndef MYNEWT_VAL_BLE_MESH_RELAY_ENABLED +#define MYNEWT_VAL_BLE_MESH_RELAY_ENABLED (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_RELAY_RETRANSMIT_COUNT +#define MYNEWT_VAL_BLE_MESH_RELAY_RETRANSMIT_COUNT (2) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_RELAY_RETRANSMIT_INTERVAL +#define MYNEWT_VAL_BLE_MESH_RELAY_RETRANSMIT_INTERVAL (20) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_RPL_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_RPL_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_RPL_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_RPL_LOG_MOD (22) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_RPL_STORE_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_RPL_STORE_TIMEOUT (5) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_RX_SEG_MAX +#define MYNEWT_VAL_BLE_MESH_RX_SEG_MAX (3) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_RX_SEG_MSG_COUNT +#define MYNEWT_VAL_BLE_MESH_RX_SEG_MSG_COUNT (2) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_SEG_BUFS +#define MYNEWT_VAL_BLE_MESH_SEG_BUFS (64) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_SEG_RETRANSMIT_ATTEMPTS +#define MYNEWT_VAL_BLE_MESH_SEG_RETRANSMIT_ATTEMPTS (4) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_SEQ_STORE_RATE +#define MYNEWT_VAL_BLE_MESH_SEQ_STORE_RATE (128) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_SETTINGS +#define MYNEWT_VAL_BLE_MESH_SETTINGS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_SETTINGS_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_SETTINGS_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_SETTINGS_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_SETTINGS_LOG_MOD (20) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_SHELL +#define MYNEWT_VAL_BLE_MESH_SHELL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_SHELL_MODELS +#define MYNEWT_VAL_BLE_MESH_SHELL_MODELS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_STORE_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_STORE_TIMEOUT (2) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_SUBNET_COUNT +#define MYNEWT_VAL_BLE_MESH_SUBNET_COUNT (2) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_MESH_SYSINIT_STAGE (500) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_SYSINIT_STAGE_SHELL +#define MYNEWT_VAL_BLE_MESH_SYSINIT_STAGE_SHELL (1000) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_TESTING +#define MYNEWT_VAL_BLE_MESH_TESTING (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_TRANS_LOG_LVL +#define MYNEWT_VAL_BLE_MESH_TRANS_LOG_LVL (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_TRANS_LOG_MOD +#define MYNEWT_VAL_BLE_MESH_TRANS_LOG_MOD (21) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_MAX +#define MYNEWT_VAL_BLE_MESH_TX_SEG_MAX (6) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_MSG_COUNT +#define MYNEWT_VAL_BLE_MESH_TX_SEG_MSG_COUNT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_RETRANS_COUNT +#define MYNEWT_VAL_BLE_MESH_TX_SEG_RETRANS_COUNT (4) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_RETRANS_TIMEOUT_GROUP +#define MYNEWT_VAL_BLE_MESH_TX_SEG_RETRANS_TIMEOUT_GROUP (50) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_RETRANS_TIMEOUT_UNICAST +#define MYNEWT_VAL_BLE_MESH_TX_SEG_RETRANS_TIMEOUT_UNICAST (400) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_UNPROV_BEACON_INT +#define MYNEWT_VAL_BLE_MESH_UNPROV_BEACON_INT (5) +#endif + +/*** @apache-mynewt-nimble/nimble/host/services/ans */ +#ifndef MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT +#define MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_ANS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_ANS_SYSINIT_STAGE (303) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT +#define MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT (0) +#endif + +/*** @apache-mynewt-nimble/nimble/host/services/bas */ +#ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE +#define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_READ_PERM +#define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_READ_PERM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_BAS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_BAS_SYSINIT_STAGE (303) +#endif + +/*** @apache-mynewt-nimble/nimble/host/services/dis */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_DEFAULT_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_FIRMWARE_REVISION_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_HARDWARE_REVISION_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_MANUFACTURER_NAME_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_DEFAULT "Apache Mynewt NimBLE" +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_MODEL_NUMBER_READ_PERM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_SERIAL_NUMBER_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_SOFTWARE_REVISION_READ_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_DIS_SYSINIT_STAGE (303) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM (-1) +#endif + +/*** @apache-mynewt-nimble/nimble/host/services/gap */ +#ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE +#define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE_WRITE_PERM +#define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE_WRITE_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION +#define MYNEWT_VAL_BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME +#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME "nimble" +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH +#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH (31) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM +#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_SLAVE_LATENCY +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SLAVE_LATENCY (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_SUPERVISION_TMO +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SUPERVISION_TMO (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_GAP_SYSINIT_STAGE (301) +#endif + +/*** @apache-mynewt-nimble/nimble/host/services/gatt */ +#ifndef MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_GATT_SYSINIT_STAGE (302) +#endif + +/*** @apache-mynewt-nimble/nimble/host/services/ias */ +#ifndef MYNEWT_VAL_BLE_SVC_IAS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_IAS_SYSINIT_STAGE (303) +#endif + +/*** @apache-mynewt-nimble/nimble/host/services/ipss */ +#ifndef MYNEWT_VAL_BLE_SVC_IPSS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_IPSS_SYSINIT_STAGE (303) +#endif + +/*** @apache-mynewt-nimble/nimble/host/services/lls */ +#ifndef MYNEWT_VAL_BLE_SVC_LLS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_LLS_SYSINIT_STAGE (303) +#endif + +/*** @apache-mynewt-nimble/nimble/host/services/tps */ +#ifndef MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SVC_TPS_SYSINIT_STAGE (303) +#endif + +/*** @apache-mynewt-nimble/nimble/transport */ +#undef MYNEWT_VAL_BLE_ACL_BUF_COUNT + +#undef MYNEWT_VAL_BLE_ACL_BUF_SIZE + +#undef MYNEWT_VAL_BLE_HCI_BRIDGE + +#undef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE + +#undef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT + +#undef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT + +#undef MYNEWT_VAL_BLE_HCI_TRANSPORT + +#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT +#define MYNEWT_VAL_BLE_MONITOR_RTT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME "btmonitor" +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART +#define MYNEWT_VAL_BLE_MONITOR_UART (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE +#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV +#define MYNEWT_VAL_BLE_MONITOR_UART_DEV "uart0" +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT +#define MYNEWT_VAL_BLE_TRANSPORT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_COUNT (10) +#endif + +/* Value copied from BLE_TRANSPORT_ACL_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_HS_COUNT (10) +#endif + +/* Value copied from BLE_TRANSPORT_ACL_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_FROM_LL_COUNT (10) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_ACL_SIZE (251) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_COUNT (4) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_DISCARDABLE_COUNT (16) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_EVT_SIZE (70) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__cdc +#define MYNEWT_VAL_BLE_TRANSPORT_HS__cdc (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__custom +#define MYNEWT_VAL_BLE_TRANSPORT_HS__custom (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac +#define MYNEWT_VAL_BLE_TRANSPORT_HS__dialog_cmac (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__native +#define MYNEWT_VAL_BLE_TRANSPORT_HS__native (1) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340 +#define MYNEWT_VAL_BLE_TRANSPORT_HS__nrf5340 (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__uart +#define MYNEWT_VAL_BLE_TRANSPORT_HS__uart (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS__usb +#define MYNEWT_VAL_BLE_TRANSPORT_HS__usb (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_HS +#define MYNEWT_VAL_BLE_TRANSPORT_HS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_COUNT (10) +#endif + +/* Value copied from BLE_TRANSPORT_ISO_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_HS_COUNT (10) +#endif + +/* Value copied from BLE_TRANSPORT_ISO_COUNT */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_FROM_LL_COUNT (10) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE +#define MYNEWT_VAL_BLE_TRANSPORT_ISO_SIZE (300) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 +#define MYNEWT_VAL_BLE_TRANSPORT_LL__apollo3 (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__custom +#define MYNEWT_VAL_BLE_TRANSPORT_LL__custom (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac +#define MYNEWT_VAL_BLE_TRANSPORT_LL__dialog_cmac (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__emspi +#define MYNEWT_VAL_BLE_TRANSPORT_LL__emspi (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__native +#define MYNEWT_VAL_BLE_TRANSPORT_LL__native (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340 +#define MYNEWT_VAL_BLE_TRANSPORT_LL__nrf5340 (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__socket +#define MYNEWT_VAL_BLE_TRANSPORT_LL__socket (1) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL__uart_ll +#define MYNEWT_VAL_BLE_TRANSPORT_LL__uart_ll (0) +#endif +#ifndef MYNEWT_VAL_BLE_TRANSPORT_LL +#define MYNEWT_VAL_BLE_TRANSPORT_LL (1) +#endif + +/*** @apache-mynewt-nimble/nimble/transport/socket */ +#ifndef MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE +#define MYNEWT_VAL_BLE_SOCK_CLI_SYSINIT_STAGE (500) +#endif + +#ifndef MYNEWT_VAL_BLE_SOCK_LINUX_DEV +#define MYNEWT_VAL_BLE_SOCK_LINUX_DEV (0) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport/socket) */ +#ifndef MYNEWT_VAL_BLE_SOCK_STACK_SIZE +#define MYNEWT_VAL_BLE_SOCK_STACK_SIZE (1028) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport/socket) */ +#ifndef MYNEWT_VAL_BLE_SOCK_TASK_PRIO +#define MYNEWT_VAL_BLE_SOCK_TASK_PRIO (3) +#endif + +#ifndef MYNEWT_VAL_BLE_SOCK_TCP_PORT +#define MYNEWT_VAL_BLE_SOCK_TCP_PORT (14433) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport/socket) */ +#ifndef MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE +#define MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_SOCK_USE_NUTTX +#define MYNEWT_VAL_BLE_SOCK_USE_NUTTX (0) +#endif + +/* Overridden by @apache-mynewt-nimble/porting/targets/linux_blemesh (defined by @apache-mynewt-nimble/nimble/transport/socket) */ +#ifndef MYNEWT_VAL_BLE_SOCK_USE_TCP +#define MYNEWT_VAL_BLE_SOCK_USE_TCP (0) +#endif + +/*** newt */ +#ifndef MYNEWT_VAL_APP_NAME +#define MYNEWT_VAL_APP_NAME "dummy_app" +#endif + +#ifndef MYNEWT_VAL_APP_dummy_app +#define MYNEWT_VAL_APP_dummy_app (1) +#endif + +#ifndef MYNEWT_VAL_ARCH_NAME +#define MYNEWT_VAL_ARCH_NAME "sim" +#endif + +#ifndef MYNEWT_VAL_ARCH_sim +#define MYNEWT_VAL_ARCH_sim (1) +#endif + +#ifndef MYNEWT_VAL_BSP_NAME +#define MYNEWT_VAL_BSP_NAME "native" +#endif + +#ifndef MYNEWT_VAL_BSP_native +#define MYNEWT_VAL_BSP_native (1) +#endif + +#ifndef MYNEWT_VAL_NEWT_FEATURE_LOGCFG +#define MYNEWT_VAL_NEWT_FEATURE_LOGCFG (1) +#endif + +#ifndef MYNEWT_VAL_NEWT_FEATURE_SYSDOWN +#define MYNEWT_VAL_NEWT_FEATURE_SYSDOWN (1) +#endif + +#ifndef MYNEWT_VAL_TARGET_NAME +#define MYNEWT_VAL_TARGET_NAME "linux_blemesh" +#endif + +#ifndef MYNEWT_VAL_TARGET_linux_blemesh +#define MYNEWT_VAL_TARGET_linux_blemesh (1) +#endif + +/*** Included packages */ +#define MYNEWT_PKG_apache_mynewt_core__compiler_sim 1 +#define MYNEWT_PKG_apache_mynewt_core__crypto_tinycrypt 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_bsp_native 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_flash_enc_flash 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_flash_enc_flash_ef_tinycrypt 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_trng 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_trng_trng_sw 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_drivers_uart_uart_hal 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_hal 1 +#define MYNEWT_PKG_apache_mynewt_core__hw_mcu_native 1 +#define MYNEWT_PKG_apache_mynewt_core__kernel_os 1 +#define MYNEWT_PKG_apache_mynewt_core__kernel_sim 1 +#define MYNEWT_PKG_apache_mynewt_core__net_ip_mn_socket 1 +#define MYNEWT_PKG_apache_mynewt_core__net_ip_native_sockets 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_console_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_defs 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_flash_map 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_common 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_modlog 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_log_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_stats_stub 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sys 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sysdown 1 +#define MYNEWT_PKG_apache_mynewt_core__sys_sysinit 1 +#define MYNEWT_PKG_apache_mynewt_core__util_mem 1 +#define MYNEWT_PKG_apache_mynewt_core__util_rwlock 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_mesh 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ans 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_bas 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_dis 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gap 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_gatt 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ias 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_ipss 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_lls 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_host_services_tps 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_transport 1 +#define MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_socket 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_npl_mynewt 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_dummy_app 1 +#define MYNEWT_PKG_apache_mynewt_nimble__porting_targets_linux_blemesh 1 + +/*** Included APIs */ +#define MYNEWT_API_TRNG_HW_IMPL 1 +#define MYNEWT_API_ble_transport 1 +#define MYNEWT_API_console 1 +#define MYNEWT_API_log 1 +#define MYNEWT_API_stats 1 + +#endif diff --git a/porting/examples/linux_blemesh_shell/include/sysflash/sysflash.h b/porting/examples/linux_blemesh_shell/include/sysflash/sysflash.h new file mode 100644 index 0000000000..2f4d843f4c --- /dev/null +++ b/porting/examples/linux_blemesh_shell/include/sysflash/sysflash.h @@ -0,0 +1,51 @@ +/** + * This file was generated by Apache newt version: 1.12.0-dev + */ + +#ifndef H_MYNEWT_SYSFLASH_ +#define H_MYNEWT_SYSFLASH_ + +#include "flash_map/flash_map.h" + +#define FLASH_AREA_COUNT 6 + +/** + * This flash map definition is used for two purposes: + * 1. To locate the meta area, which contains the true flash map definition. + * 2. As a fallback in case the meta area cannot be read from flash. + */ +extern const struct flash_area sysflash_map_dflt[FLASH_AREA_COUNT]; + +/* Flash map was defined in @apache-mynewt-core/hw/bsp/native */ + +#define FLASH_AREA_BOOTLOADER 0 +#define FLASH_AREA_BOOTLOADER_DEVICE 0 +#define FLASH_AREA_BOOTLOADER_OFFSET 0x00000000 +#define FLASH_AREA_BOOTLOADER_SIZE 16384 + +#define FLASH_AREA_IMAGE_0 1 +#define FLASH_AREA_IMAGE_0_DEVICE 0 +#define FLASH_AREA_IMAGE_0_OFFSET 0x00020000 +#define FLASH_AREA_IMAGE_0_SIZE 393216 + +#define FLASH_AREA_IMAGE_1 2 +#define FLASH_AREA_IMAGE_1_DEVICE 0 +#define FLASH_AREA_IMAGE_1_OFFSET 0x00080000 +#define FLASH_AREA_IMAGE_1_SIZE 393216 + +#define FLASH_AREA_IMAGE_SCRATCH 3 +#define FLASH_AREA_IMAGE_SCRATCH_DEVICE 0 +#define FLASH_AREA_IMAGE_SCRATCH_OFFSET 0x000e0000 +#define FLASH_AREA_IMAGE_SCRATCH_SIZE 131072 + +#define FLASH_AREA_REBOOT_LOG 16 +#define FLASH_AREA_REBOOT_LOG_DEVICE 0 +#define FLASH_AREA_REBOOT_LOG_OFFSET 0x00004000 +#define FLASH_AREA_REBOOT_LOG_SIZE 16384 + +#define FLASH_AREA_NFFS 17 +#define FLASH_AREA_NFFS_DEVICE 0 +#define FLASH_AREA_NFFS_OFFSET 0x00008000 +#define FLASH_AREA_NFFS_SIZE 32768 + +#endif diff --git a/porting/examples/linux_blemesh_shell/shell/console_port.c b/porting/examples/linux_blemesh_shell/shell/console_port.c new file mode 100644 index 0000000000..3ed21ba2b1 --- /dev/null +++ b/porting/examples/linux_blemesh_shell/shell/console_port.c @@ -0,0 +1,88 @@ +/* + * 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. + */ +#include +#include "nimble/nimble_npl.h" +#include "shell/shell.h" + +static struct ble_npl_task mesh_input_task; +static struct ble_npl_event shell_evt; + +struct os_eventq * avail_queue; +static ble_npl_event_fn *shell_ev_cb; + +void +console_set_queues(struct os_eventq *avail, struct os_eventq *lines) +{ + avail_queue = avail; +} + +void +console_set_event_cb(ble_npl_event_fn *cb) +{ + shell_ev_cb = cb; +} + +static void +mesh_shell_evt_add(char *cmd) +{ + struct ble_npl_event *ev = &shell_evt; + + if (ev->ev_queued) { + printf("Wait last cmd be handled...\n"); + return; + } + + ble_npl_event_init(ev, shell_ev_cb, cmd); + + ble_npl_eventq_put(avail_queue, ev); +} + +static void * +console_input_thread(void *args) +{ + char line[128]; + + while (1) { + printf("\n\nmesh>"); + fgets(line, sizeof(line), stdin); + int len = strlen(line); + if (len > 0 && (line[len-1] == '\n')) { + line[len-1] = '\0'; + --len; + } + + if (len > 0) { + mesh_shell_evt_add(line); + } + } + + return NULL; +} + +int +console_init() +{ + int i; + + ble_npl_task_init(&mesh_input_task, "mesh_input", console_input_thread, + NULL, TASK_DEFAULT_PRIORITY, BLE_NPL_TIME_FOREVER, + TASK_DEFAULT_STACK, TASK_DEFAULT_STACK_SIZE); + + return 0; +} diff --git a/porting/examples/linux_blemesh_shell/shell/shell_port.c b/porting/examples/linux_blemesh_shell/shell/shell_port.c new file mode 100644 index 0000000000..bd9af6d3b9 --- /dev/null +++ b/porting/examples/linux_blemesh_shell/shell/shell_port.c @@ -0,0 +1,230 @@ +/* + * 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. + */ +#include +#include +#include "nimble/nimble_npl.h" +#include "shell/shell.h" +#include "console/console.h" +#include "console/console_port.h" + +static const struct shell_cmd *def_commands; + +int +shell_register(const char *module_name, const struct shell_cmd *commands) +{ + def_commands = commands; + return 0; +} + +void +shell_register_app_cmd_handler(shell_cmd_func_t handler) +{ +} + +void +shell_register_prompt_handler(shell_prompt_function_t handler) +{ +} + +void +shell_register_default_module(const char *name) +{ +} + +void +shell_evq_set(struct os_eventq *evq) +{ + console_set_queues(evq, NULL); + console_set_event_cb(handle_shell_evt); +} + +void +print_prompt(struct streamer *streamer) +{ + console_printf(">mesh\n"); +} + +static size_t +line2argv(char *str, char *argv[], size_t size, struct streamer *streamer) +{ + size_t argc = 0; + + if (!strlen(str)) { + return 0; + } + + while (*str && *str == ' ') { + str++; + } + + if (!*str) { + return 0; + } + + argv[argc++] = str; + + while ((str = strchr(str, ' '))) { + *str++ = '\0'; + + while (*str && *str == ' ') { + str++; + } + + if (!*str) { + break; + } + + argv[argc++] = str; + + if (argc == size) { + fprintf(stderr, "Too many parameters (max %zu)\n", size - 1); + return 0; + } + } + + /* keep it POSIX style where argv[argc] is required to be NULL */ + argv[argc] = NULL; + + return argc; +} + +int +show_cmd_help(char *cmd, struct streamer *streamer) +{ + const struct shell_cmd *command; + + for (int i = 0; def_commands[i].sc_cmd; i++) { + if (!cmd) { + command = &def_commands[i]; + } else if (!strcmp(cmd, def_commands[i].sc_cmd)) { + command = &def_commands[i]; + } else { + continue; + } + + if (command->help) { + console_printf("%s: %s\n", command->sc_cmd, command->help->usage ?: ""); + } else { + console_printf("%s\n", command->sc_cmd); + } + } + + return 0; +} + +int +shell_exec(int argc, char **argv, struct streamer *streamer) +{ + const struct shell_cmd *cmd = NULL; + const char *command = argv[0]; + size_t argc_offset = 0; + int rc; + + if (!strcmp(command, "help")) { + if (argc >= 2) { + return show_cmd_help(argv[1], NULL); + } else { + return show_cmd_help(NULL, NULL); + } + } + + for (int i = 0; def_commands[i].sc_cmd; i++) { + if (!strcmp(command, def_commands[i].sc_cmd)) { + cmd = &def_commands[i]; + } + } + + if (!cmd) { + console_printf("Unrecognized command: %s\n", argv[0]); + console_printf("Type 'help' for list of available commands\n"); + print_prompt(streamer); + return BLE_NPL_ENOENT; + } + + /* Execute callback with arguments */ + if (!cmd->sc_ext) { + rc = cmd->sc_cmd_func(argc - argc_offset, &argv[argc_offset]); + } else { + rc = cmd->sc_cmd_ext_func(cmd, argc - argc_offset, &argv[argc_offset], streamer); + } + if (rc < 0) { + show_cmd_help(argv[0], streamer); + } + + print_prompt(streamer); + + return rc; +} + +static void +shell_process_command(char *line, struct streamer *streamer) +{ + char *argv[MYNEWT_VAL(SHELL_CMD_ARGC_MAX) + 1]; + size_t argc; + + argc = line2argv(line, argv, MYNEWT_VAL(SHELL_CMD_ARGC_MAX) + 1, streamer); + if (!argc) { + print_prompt(streamer); + return; + } + + shell_exec(argc, argv, streamer); +} + +void +handle_shell_evt(struct os_event *ev) +{ + char *line; + + if (!ev) { + print_prompt(NULL); + return; + } + + line = ev->ev_arg; + if (!line) { + print_prompt(NULL); + return; + } + + shell_process_command(line, NULL); + + ev->ev_queued = 0; +} + +#if MYNEWT_VAL(SHELL_MGMT) +int +shell_nlip_input_register(shell_nlip_input_func_t nf, void *arg) +{ + return 0; +} +int +shell_nlip_output(struct os_mbuf *m) +{ + return 0; +} +#endif + +#if MYNEWT_VAL(SHELL_COMPAT) +int +shell_cmd_register(const struct shell_cmd *sc) +{ + return 0; +} +#endif diff --git a/porting/examples/linux_blemesh_shell/src/ble.c b/porting/examples/linux_blemesh_shell/src/ble.c new file mode 100644 index 0000000000..c380ac88d5 --- /dev/null +++ b/porting/examples/linux_blemesh_shell/src/ble.c @@ -0,0 +1,503 @@ +/* + * 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. + */ + +#include +#include "mesh/mesh.h" +#include "console/console.h" + +/* BLE */ +#include "nimble/nimble_port.h" +#include "nimble/ble.h" +#include "host/ble_hs.h" +#include "services/gap/ble_svc_gap.h" +#include "mesh/glue.h" +#include "shell/shell.h" +#include "console/console_port.h" + +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG)) + +/* Company ID */ +#define CID_VENDOR 0x05C3 +#define STANDARD_TEST_ID 0x00 +#define TEST_ID 0x01 +static int recent_test_id = STANDARD_TEST_ID; + +#define FAULT_ARR_SIZE 2 + +static bool has_reg_fault = true; + +static int +fault_get_cur(struct bt_mesh_model *model, + uint8_t *test_id, + uint16_t *company_id, + uint8_t *faults, + uint8_t *fault_count) +{ + uint8_t reg_faults[FAULT_ARR_SIZE] = { [0 ... FAULT_ARR_SIZE-1] = 0xff }; + + console_printf("fault_get_cur() has_reg_fault %u\n", has_reg_fault); + + *test_id = recent_test_id; + *company_id = CID_VENDOR; + + *fault_count = MIN(*fault_count, sizeof(reg_faults)); + memcpy(faults, reg_faults, *fault_count); + + return 0; +} + +static int +fault_get_reg(struct bt_mesh_model *model, + uint16_t company_id, + uint8_t *test_id, + uint8_t *faults, + uint8_t *fault_count) +{ + if (company_id != CID_VENDOR) { + return -BLE_HS_EINVAL; + } + + console_printf("fault_get_reg() has_reg_fault %u\n", has_reg_fault); + + *test_id = recent_test_id; + + if (has_reg_fault) { + uint8_t reg_faults[FAULT_ARR_SIZE] = { [0 ... FAULT_ARR_SIZE-1] = 0xff }; + + *fault_count = MIN(*fault_count, sizeof(reg_faults)); + memcpy(faults, reg_faults, *fault_count); + } else { + *fault_count = 0; + } + + return 0; +} + +static int +fault_clear(struct bt_mesh_model *model, uint16_t company_id) +{ + if (company_id != CID_VENDOR) { + return -BLE_HS_EINVAL; + } + + has_reg_fault = false; + + return 0; +} + +static int +fault_test(struct bt_mesh_model *model, uint8_t test_id, uint16_t company_id) +{ + if (company_id != CID_VENDOR) { + return -BLE_HS_EINVAL; + } + + if (test_id != STANDARD_TEST_ID && test_id != TEST_ID) { + return -BLE_HS_EINVAL; + } + + recent_test_id = test_id; + has_reg_fault = true; + bt_mesh_fault_update(bt_mesh_model_elem(model)); + + return 0; +} + +static const struct bt_mesh_health_srv_cb health_srv_cb = { + .fault_get_cur = &fault_get_cur, + .fault_get_reg = &fault_get_reg, + .fault_clear = &fault_clear, + .fault_test = &fault_test, +}; + +static struct bt_mesh_health_srv health_srv = { + .cb = &health_srv_cb, +}; + +static struct bt_mesh_model_pub health_pub; + +static void +health_pub_init(void) +{ + health_pub.msg = BT_MESH_HEALTH_FAULT_MSG(0); +} + +static struct bt_mesh_model_pub gen_level_pub; +static struct bt_mesh_model_pub gen_onoff_pub; + +static uint8_t gen_on_off_state; +static int16_t gen_level_state; + +static int +gen_onoff_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(3); + uint8_t *status; + int rc; + + console_printf("#mesh-onoff STATUS\n"); + + bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x04)); + status = net_buf_simple_add(msg, 1); + *status = gen_on_off_state; + + rc = bt_mesh_model_send(model, ctx, msg, NULL, NULL); + if (rc) { + console_printf("#mesh-onoff STATUS: send status failed\n"); + } + + os_mbuf_free_chain(msg); + return rc; +} + +static int +gen_onoff_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + console_printf("#mesh-onoff GET\n"); + + return gen_onoff_status(model, ctx); +} + +static int +gen_onoff_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + console_printf("#mesh-onoff SET\n"); + + gen_on_off_state = buf->om_data[0]; + + return gen_onoff_status(model, ctx); +} + +static int +gen_onoff_set_unack(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + console_printf("#mesh-onoff SET-UNACK\n"); + + gen_on_off_state = buf->om_data[0]; + return 0; +} + +static const struct bt_mesh_model_op gen_onoff_op[] = { + { BT_MESH_MODEL_OP_2(0x82, 0x01), 0, gen_onoff_get }, + { BT_MESH_MODEL_OP_2(0x82, 0x02), 2, gen_onoff_set }, + { BT_MESH_MODEL_OP_2(0x82, 0x03), 2, gen_onoff_set_unack }, + BT_MESH_MODEL_OP_END, +}; + +static void +gen_level_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(4); + + console_printf("#mesh-level STATUS\n"); + + bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_2(0x82, 0x08)); + net_buf_simple_add_le16(msg, gen_level_state); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + console_printf("#mesh-level STATUS: send status failed\n"); + } + + os_mbuf_free_chain(msg); +} + +static int +gen_level_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + console_printf("#mesh-level GET\n"); + + gen_level_status(model, ctx); + return 0; +} + +static int +gen_level_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + int16_t level; + + level = (int16_t) net_buf_simple_pull_le16(buf); + console_printf("#mesh-level SET: level=%d\n", level); + + gen_level_status(model, ctx); + + gen_level_state = level; + console_printf("#mesh-level: level=%d\n", gen_level_state); + return 0; +} + +static int +gen_level_set_unack(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + int16_t level; + + level = (int16_t) net_buf_simple_pull_le16(buf); + console_printf("#mesh-level SET-UNACK: level=%d\n", level); + + gen_level_state = level; + console_printf("#mesh-level: level=%d\n", gen_level_state); + return 0; +} + +static int +gen_delta_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + int16_t delta_level; + + delta_level = (int16_t) net_buf_simple_pull_le16(buf); + console_printf("#mesh-level DELTA-SET: delta_level=%d\n", delta_level); + + gen_level_status(model, ctx); + + gen_level_state += delta_level; + console_printf("#mesh-level: level=%d\n", gen_level_state); + return 0; +} + +static int +gen_delta_set_unack(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + int16_t delta_level; + + delta_level = (int16_t) net_buf_simple_pull_le16(buf); + console_printf("#mesh-level DELTA-SET: delta_level=%d\n", delta_level); + + gen_level_state += delta_level; + console_printf("#mesh-level: level=%d\n", gen_level_state); + return 0; +} + +static int +gen_move_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + return 0; +} + +static int +gen_move_set_unack(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + return 0; +} + +static const struct bt_mesh_model_op gen_level_op[] = { + { BT_MESH_MODEL_OP_2(0x82, 0x05), 0, gen_level_get }, + { BT_MESH_MODEL_OP_2(0x82, 0x06), 3, gen_level_set }, + { BT_MESH_MODEL_OP_2(0x82, 0x07), 3, gen_level_set_unack }, + { BT_MESH_MODEL_OP_2(0x82, 0x09), 5, gen_delta_set }, + { BT_MESH_MODEL_OP_2(0x82, 0x0a), 5, gen_delta_set_unack }, + { BT_MESH_MODEL_OP_2(0x82, 0x0b), 3, gen_move_set }, + { BT_MESH_MODEL_OP_2(0x82, 0x0c), 3, gen_move_set_unack }, + BT_MESH_MODEL_OP_END, +}; + +static struct bt_mesh_model root_models[] = { + BT_MESH_MODEL_CFG_SRV, + BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), + BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_op, + &gen_onoff_pub, NULL), + BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_SRV, gen_level_op, + &gen_level_pub, NULL), +}; + +static struct bt_mesh_model_pub vnd_model_pub; + +static int +vnd_model_recv(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(3); + int rc; + + console_printf("#vendor-model-recv\n"); + + console_printf("data:%s len:%d\n", bt_hex(buf->om_data, buf->om_len), + buf->om_len); + + bt_mesh_model_msg_init(msg, BT_MESH_MODEL_OP_3(0x01, CID_VENDOR)); + os_mbuf_append(msg, buf->om_data, buf->om_len); + + rc = bt_mesh_model_send(model, ctx, msg, NULL, NULL); + if (rc) { + console_printf("#vendor-model-recv: send rsp failed\n"); + } + + os_mbuf_free_chain(msg); + return rc; +} + +static const struct bt_mesh_model_op vnd_model_op[] = { + { BT_MESH_MODEL_OP_3(0x01, CID_VENDOR), 0, vnd_model_recv }, + BT_MESH_MODEL_OP_END, +}; + +static struct bt_mesh_model vnd_models[] = { + BT_MESH_MODEL_VND(CID_VENDOR, BT_MESH_MODEL_ID_GEN_ONOFF_SRV, vnd_model_op, + &vnd_model_pub, NULL), +}; + +static struct bt_mesh_elem elements[] = { + BT_MESH_ELEM(0, root_models, vnd_models), +}; + +static const struct bt_mesh_comp comp = { + .cid = CID_VENDOR, + .elem = elements, + .elem_count = ARRAY_SIZE(elements), +}; + +static int +output_number(bt_mesh_output_action_t action, uint32_t number) +{ + console_printf("!!! app laer: output OOB Number: %u\n", number); + + return 0; +} + +static void +prov_complete(uint16_t net_idx, uint16_t addr) +{ + console_printf("Local node provisioned, primary address 0x%04x\n", addr); +} + +static const uint8_t dev_uuid[16] = MYNEWT_VAL(BLE_MESH_DEV_UUID); + +static const struct bt_mesh_prov prov = { + .uuid = dev_uuid, + .output_size = 0, + .output_actions = 0, + .output_number = output_number, + .complete = prov_complete, +}; + +static void +blemesh_on_reset(int reason) +{ + BLE_HS_LOG(ERROR, "Resetting state; reason=%d\n", reason); +} + +void mesh_initialized(void); + + +#include "mesh/glue.h" +#include "mesh/testing.h" + + +void +net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, + const void *payload, size_t payload_len) +{ + console_printf("Received net packet: ttl 0x%02x ctl 0x%02x src 0x%04x " + "dst 0x%04x " "payload_len %d\n", ttl, ctl, src, dst, + payload_len); +} + +static void +model_bound_cb(uint16_t addr, struct bt_mesh_model *model, + uint16_t key_idx) +{ + console_printf("Model bound: remote addr 0x%04x key_idx 0x%04x model %p\n", + addr, key_idx, model); +} + +static void +model_unbound_cb(uint16_t addr, struct bt_mesh_model *model, + uint16_t key_idx) +{ + console_printf("Model unbound: remote addr 0x%04x key_idx 0x%04x " + "model %p\n", addr, key_idx, model); +} + +static void +invalid_bearer_cb(uint8_t opcode) +{ + console_printf("Invalid bearer: opcode 0x%02x\n", opcode); +} + +static void +incomp_timer_exp_cb(void) +{ + console_printf("Incomplete timer expired\n"); +} + +static struct bt_test_cb bt_test_cb = { + .mesh_net_recv = net_recv_ev, + .mesh_model_bound = model_bound_cb, + .mesh_model_unbound = model_unbound_cb, + .mesh_prov_invalid_bearer = invalid_bearer_cb, + .mesh_trans_incomp_timer_exp = incomp_timer_exp_cb, +}; + + +static void +blemesh_on_sync(void) +{ + int err; + + console_printf("Bluetooth initialized\n"); + + console_printf("Init mesh and shell task now.\n"); + ble_mesh_shell_init(); + + /* init mesh node. it call bt_mesh_init. */ + cmd_mesh_init(0, NULL); + + console_printf("Start mesh adv task.\n"); + mesh_initialized(); + + if (IS_ENABLED(CONFIG_BT_TESTING)) { + bt_test_cb_register(&bt_test_cb); + } + + console_init(); +} + +void +nimble_host_task(void *param) +{ + health_pub_init(); + + /* Initialize the NimBLE host configuration. */ + ble_hs_cfg.reset_cb = blemesh_on_reset; + ble_hs_cfg.sync_cb = blemesh_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + nimble_port_run(); +} diff --git a/porting/examples/linux_blemesh_shell/src/main.c b/porting/examples/linux_blemesh_shell/src/main.c new file mode 100644 index 0000000000..734f716ba6 --- /dev/null +++ b/porting/examples/linux_blemesh_shell/src/main.c @@ -0,0 +1,106 @@ +/* + * 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. + */ + +#include +#include +#include + +#include +#include "nimble/nimble_npl.h" +#include "nimble/nimble_port.h" + +#include "mesh/glue.h" +#include "mesh/porting.h" + +#include "services/gap/ble_svc_gap.h" +#include "services/gatt/ble_svc_gatt.h" + +static struct ble_npl_task s_task_host; +static struct ble_npl_task s_task_hci; +static struct ble_npl_task s_task_mesh_adv; + +void nimble_host_task(void *param); +void ble_hci_sock_ack_handler(void *param); +void ble_hci_sock_init(void); +void ble_hci_sock_set_device(int dev); +void ble_store_ram_init(void); + +#define TASK_DEFAULT_PRIORITY 1 +#define TASK_DEFAULT_STACK NULL +#define TASK_DEFAULT_STACK_SIZE 400 + +void * +ble_hci_sock_task(void *param) +{ + ble_hci_sock_ack_handler(param); + return NULL; +} + +void * +ble_host_task(void *param) +{ + nimble_host_task(param); + return NULL; +} + +void * +ble_mesh_adv_task(void *param) +{ + mesh_adv_thread(param); + return NULL; +} + +void +mesh_initialized(void) +{ + ble_npl_task_init(&s_task_mesh_adv, "ble_mesh_adv", ble_mesh_adv_task, + NULL, TASK_DEFAULT_PRIORITY, BLE_NPL_TIME_FOREVER, + TASK_DEFAULT_STACK, TASK_DEFAULT_STACK_SIZE); +} + +int +main(int argc, char *argv[]) +{ + int ret = 0; + + /* allow to specify custom hci */ + if (argc > 1) { + ble_hci_sock_set_device(atoi(argv[1])); + } + + nimble_port_init(); + + ble_svc_gap_init(); + ble_svc_gatt_init(); + bt_mesh_register_gatt(); + + /* XXX Need to have template for store */ + ble_store_ram_init(); + + ble_npl_task_init(&s_task_hci, "hci_sock", ble_hci_sock_task, + NULL, TASK_DEFAULT_PRIORITY, BLE_NPL_TIME_FOREVER, + TASK_DEFAULT_STACK, TASK_DEFAULT_STACK_SIZE); + + /* Create task which handles default event queue for host stack. */ + ble_npl_task_init(&s_task_host, "ble_host", ble_host_task, + NULL, TASK_DEFAULT_PRIORITY, BLE_NPL_TIME_FOREVER, + TASK_DEFAULT_STACK, TASK_DEFAULT_STACK_SIZE); + + pthread_exit(&ret); +} From 85f95592f715ac8d4a584261876572f457c39386 Mon Sep 17 00:00:00 2001 From: yyy Date: Fri, 20 Dec 2024 10:46:54 +0800 Subject: [PATCH 1158/1333] fix coding style --- .../linux_blemesh_shell/include/shell/shell.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/porting/examples/linux_blemesh_shell/include/shell/shell.h b/porting/examples/linux_blemesh_shell/include/shell/shell.h index 75130487d5..4135010f79 100644 --- a/porting/examples/linux_blemesh_shell/include/shell/shell.h +++ b/porting/examples/linux_blemesh_shell/include/shell/shell.h @@ -131,20 +131,20 @@ struct shell_module { * @brief constructs a legacy shell command. */ #define SHELL_CMD(cmd_, func_, help_) { \ - .sc_ext = 0, \ - .sc_cmd_func = func_, \ - .sc_cmd = cmd_, \ - .help = SHELL_HELP_(help_), \ + .sc_ext = 0, \ + .sc_cmd_func = func_, \ + .sc_cmd = cmd_, \ + .help = SHELL_HELP_(help_), \ } /** * @brief constructs an extended shell command. */ #define SHELL_CMD_EXT(cmd_, func_, help_) { \ - .sc_ext = 1, \ - .sc_cmd_ext_func = func_, \ - .sc_cmd = cmd_, \ - .help = SHELL_HELP_(help_), \ + .sc_ext = 1, \ + .sc_cmd_ext_func = func_, \ + .sc_cmd = cmd_, \ + .help = SHELL_HELP_(help_), \ } /** @brief Register a shell_module object From 895ed28b99080cef86828c3629fe53b4f80004e3 Mon Sep 17 00:00:00 2001 From: yyy Date: Mon, 23 Dec 2024 16:23:37 +0800 Subject: [PATCH 1159/1333] revert coding style change --- .../linux_blemesh_shell/include/shell/shell.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/porting/examples/linux_blemesh_shell/include/shell/shell.h b/porting/examples/linux_blemesh_shell/include/shell/shell.h index 4135010f79..75130487d5 100644 --- a/porting/examples/linux_blemesh_shell/include/shell/shell.h +++ b/porting/examples/linux_blemesh_shell/include/shell/shell.h @@ -131,20 +131,20 @@ struct shell_module { * @brief constructs a legacy shell command. */ #define SHELL_CMD(cmd_, func_, help_) { \ - .sc_ext = 0, \ - .sc_cmd_func = func_, \ - .sc_cmd = cmd_, \ - .help = SHELL_HELP_(help_), \ + .sc_ext = 0, \ + .sc_cmd_func = func_, \ + .sc_cmd = cmd_, \ + .help = SHELL_HELP_(help_), \ } /** * @brief constructs an extended shell command. */ #define SHELL_CMD_EXT(cmd_, func_, help_) { \ - .sc_ext = 1, \ - .sc_cmd_ext_func = func_, \ - .sc_cmd = cmd_, \ - .help = SHELL_HELP_(help_), \ + .sc_ext = 1, \ + .sc_cmd_ext_func = func_, \ + .sc_cmd = cmd_, \ + .help = SHELL_HELP_(help_), \ } /** @brief Register a shell_module object From 939cff9b31516397c1aa467452e055a46938f3e4 Mon Sep 17 00:00:00 2001 From: Guy Mishol Date: Fri, 3 Jan 2025 16:53:35 +0200 Subject: [PATCH 1160/1333] nimble/host: Fix wrong Host Error Code used in GATT client code A wrong Host Error Code was used in ble_gattc.c file cause compilation error. Fix it by replacing with the correct Host Error Code. --- nimble/host/src/ble_gattc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index b3c8e04e12..0ff4ec28e6 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -4444,7 +4444,7 @@ ble_gatts_notify_multiple_custom(uint16_t conn_handle, conn = ble_hs_conn_find(conn_handle); if (conn == NULL) { - return ENOTCONN; + return BLE_HS_ENOTCONN; } /* Read missing values */ @@ -4527,7 +4527,7 @@ ble_gatts_notify_multiple(uint16_t conn_handle, BLE_HS_LOG_DEBUG("conn_handle %d\n", conn_handle); conn = ble_hs_conn_find(conn_handle); if (conn == NULL) { - return ENOTCONN; + return BLE_HS_ENOTCONN; } /** Skip sending to client that doesn't support this feature */ From 734a53dccc1593134a2edf7aa05b7e23e4082395 Mon Sep 17 00:00:00 2001 From: chrysn Date: Mon, 30 Dec 2024 23:38:40 +0100 Subject: [PATCH 1161/1333] debug: Declare as printf-style, remove empty statement This resolves the -Wformat-nonliteral warning by (which complains about non-literals used as printf formatters, unless the containing function itself is also printf style), and a stray leftover empty debug statement discovered by that warning: -Wformat-nonliteral is a bit of a false postive here because due to the level prefix, the empty printf is not *really* empty, but it is accurate enough in that it does not provide any valuable details. --- nimble/host/src/ble_gatts.c | 2 -- porting/npl/riot/include/nimble/nimble_npl_os_log.h | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/nimble/host/src/ble_gatts.c b/nimble/host/src/ble_gatts.c index c77e561b73..ee6a8a3c65 100644 --- a/nimble/host/src/ble_gatts.c +++ b/nimble/host/src/ble_gatts.c @@ -1619,8 +1619,6 @@ ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, struct os_mbuf *om) int rc = 0; int i; - BLE_HS_LOG(DEBUG, ""); - if (!om) { return BLE_ATT_ERR_INSUFFICIENT_RES; } diff --git a/porting/npl/riot/include/nimble/nimble_npl_os_log.h b/porting/npl/riot/include/nimble/nimble_npl_os_log.h index 5fcce6aeec..91c8047547 100644 --- a/porting/npl/riot/include/nimble/nimble_npl_os_log.h +++ b/porting/npl/riot/include/nimble/nimble_npl_os_log.h @@ -24,6 +24,7 @@ /* Example on how to use macro to generate module logging functions */ #define BLE_NPL_LOG_IMPL(lvl) \ + __attribute__((__format__ (__printf__, 1, 0))) \ static inline void _BLE_NPL_LOG_CAT(BLE_NPL_LOG_MODULE, \ _BLE_NPL_LOG_CAT(_, lvl))(const char *fmt, ...)\ { \ From 2a14c85d5a6124b8835b89a40da7afb68446c39e Mon Sep 17 00:00:00 2001 From: Guy Mishol Date: Fri, 3 Jan 2025 17:05:29 +0200 Subject: [PATCH 1162/1333] nimble/host: Fix a build warning caused by using undeclared min function Use of undeclared min function causes build warning. Declare the min and max function in file ble_l2cap_coc.c --- nimble/host/src/ble_l2cap_coc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c index a3d1b1c22d..d4cb15f971 100644 --- a/nimble/host/src/ble_l2cap_coc.c +++ b/nimble/host/src/ble_l2cap_coc.c @@ -27,6 +27,14 @@ #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 && NIMBLE_BLE_CONNECT +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef max +#define max(a, b) ((a) > (b) ? (a) : (b)) +#endif + #define BLE_L2CAP_SDU_SIZE 2 STAILQ_HEAD(ble_l2cap_coc_srv_list, ble_l2cap_coc_srv); From 2fcb7812d765adc6f167c2c6a5c56e2bfaf2c6e9 Mon Sep 17 00:00:00 2001 From: Guy Mishol Date: Fri, 3 Jan 2025 17:09:32 +0200 Subject: [PATCH 1163/1333] nimble/host: Fix a build warning caused by undeclared ARRAY_SIZE macro Use of undeclared ARRAY_SIZE macro causes build warning. Add include to "os/util.h" in ble_store_config.c file. --- nimble/host/store/config/src/ble_store_config.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/host/store/config/src/ble_store_config.c b/nimble/host/store/config/src/ble_store_config.c index 664b8768bf..b800a4ee58 100644 --- a/nimble/host/store/config/src/ble_store_config.c +++ b/nimble/host/store/config/src/ble_store_config.c @@ -24,6 +24,7 @@ #include "syscfg/syscfg.h" #include "host/ble_hs.h" #include "base64/base64.h" +#include "os/util.h" #include "store/config/ble_store_config.h" #include "ble_store_config_priv.h" From 3eacaf5624b40384993075d367a19f46a2c449b4 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 18 Dec 2024 17:23:51 +0100 Subject: [PATCH 1164/1333] nimble/ll: Use RPA from global local IRK on active scan Local IRK, if set, is used to generate local RPA in use cases where own address type was set to 0x02 or 0x03 but peer address is not added to resolving list. If no IRK is set (or set to all-zero), the controller uses NRPA. --- nimble/controller/src/ble_ll_scan_aux.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 7b3b0a168f..b61f729db1 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -1150,11 +1150,12 @@ ble_ll_scan_aux_scan_req_tx_pdu_cb(uint8_t *dptr, void *arg, uint8_t *hdr_byte) uint8_t rpa[BLE_DEV_ADDR_LEN]; #endif uint8_t hb; + uint8_t own_addr_type = ble_ll_scan_get_own_addr_type(); hb = BLE_ADV_PDU_TYPE_SCAN_REQ; /* ScanA */ - if (ble_ll_scan_get_own_addr_type() & 0x01) { + if (own_addr_type & 0x01) { hb |= BLE_ADV_PDU_HDR_TXADD_RAND; scana = g_random_addr; } else { @@ -1162,7 +1163,7 @@ ble_ll_scan_aux_scan_req_tx_pdu_cb(uint8_t *dptr, void *arg, uint8_t *hdr_byte) } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - if (ble_ll_scan_get_own_addr_type() & 0x02) { + if (own_addr_type & 0x02) { if (aux->rpa_index >=0) { rl = &g_ble_ll_resolv_list[aux->rpa_index]; } else { @@ -1171,15 +1172,20 @@ ble_ll_scan_aux_scan_req_tx_pdu_cb(uint8_t *dptr, void *arg, uint8_t *hdr_byte) /* * If device is on RL and we have local IRK, we use RPA generated using - * that IRK as ScanA. Otherwise we use NRPA as ScanA to prevent our - * device from being tracked when doing an active scan + * that IRK as ScanA. Otherwise we use NRPA or RPA from global local IRK + * as ScanA to prevent our device from being tracked when doing + * an active scan * ref: Core 5.2, Vol 6, Part B, section 6.3) */ if (rl && rl->rl_has_local) { ble_ll_resolv_get_priv_addr(rl, 1, rpa); scana = rpa; } else { - scana = ble_ll_get_scan_nrpa(); + if (ble_ll_resolv_local_rpa_get(own_addr_type & 0x01, rpa) == 0) { + scana = rpa; + } else { + scana = ble_ll_get_scan_nrpa(); + } } hb |= BLE_ADV_PDU_HDR_TXADD_RAND; From 39b367f0033f852eabf34d44304bea106db86a5b Mon Sep 17 00:00:00 2001 From: chrysn Date: Tue, 24 Dec 2024 02:53:56 +0100 Subject: [PATCH 1165/1333] porting: Add missing include --- porting/npl/riot/include/nimble/nimble_npl_os_log.h | 1 + 1 file changed, 1 insertion(+) diff --git a/porting/npl/riot/include/nimble/nimble_npl_os_log.h b/porting/npl/riot/include/nimble/nimble_npl_os_log.h index 91c8047547..f585070dad 100644 --- a/porting/npl/riot/include/nimble/nimble_npl_os_log.h +++ b/porting/npl/riot/include/nimble/nimble_npl_os_log.h @@ -21,6 +21,7 @@ #define _NIMBLE_NPL_OS_LOG_H_ #include +#include /* Example on how to use macro to generate module logging functions */ #define BLE_NPL_LOG_IMPL(lvl) \ From cf947cd5ae3fcab858f6adcc288dd3f2630fb9db Mon Sep 17 00:00:00 2001 From: chrysn Date: Fri, 27 Dec 2024 22:48:57 +0100 Subject: [PATCH 1166/1333] Consistently declare min() macro before using it --- apps/blemesh/src/main.c | 4 ++++ apps/blestress/src/rx_stress.c | 4 ++++ apps/btshell/src/cmd.c | 4 ++++ apps/btshell/src/main.c | 4 ++++ apps/bttester/src/btp_mesh.c | 4 ++++ apps/bttester/src/bttester.c | 4 ++++ apps/bttester/src/rtt_pipe.c | 4 ++++ apps/mesh_badge/src/mesh.c | 4 ++++ apps/mesh_badge/src/reel_board.c | 4 ++++ nimble/controller/src/ble_ll_isoal.c | 4 ++++ nimble/drivers/dialog_cmac/src/ble_phy.c | 4 ++++ nimble/drivers/native/src/ble_phy.c | 4 ++++ nimble/drivers/nrf51/src/ble_phy.c | 4 ++++ nimble/drivers/nrf5x/src/ble_phy.c | 4 ++++ nimble/host/src/ble_iso.c | 4 ++++ nimble/host/src/ble_l2cap_coc.c | 4 ++++ nimble/host/test/src/ble_att_svr_test.c | 4 ++++ porting/nimble/src/os_mbuf.c | 2 +- 18 files changed, 69 insertions(+), 1 deletion(-) diff --git a/apps/blemesh/src/main.c b/apps/blemesh/src/main.c index e11ceb8f5c..1636bdcf19 100644 --- a/apps/blemesh/src/main.c +++ b/apps/blemesh/src/main.c @@ -32,6 +32,10 @@ #include "services/gap/ble_svc_gap.h" #include "mesh/glue.h" +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + /* Company ID */ #define CID_VENDOR 0x05C3 #define STANDARD_TEST_ID 0x00 diff --git a/apps/blestress/src/rx_stress.c b/apps/blestress/src/rx_stress.c index 32b9ab60bd..5e086733cb 100644 --- a/apps/blestress/src/rx_stress.c +++ b/apps/blestress/src/rx_stress.c @@ -20,6 +20,10 @@ #include #include "rx_stress.h" +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + /* UUID128 of stress test use cases*/ static uint8_t rx_stress_uuid128[STRESS_UUIDS_NUM][16]; diff --git a/apps/btshell/src/cmd.c b/apps/btshell/src/cmd.c index ba47ee7456..3380de7547 100644 --- a/apps/btshell/src/cmd.c +++ b/apps/btshell/src/cmd.c @@ -45,6 +45,10 @@ #include "cmd_l2cap.h" #include "cmd_leaudio.h" +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + #define BTSHELL_MODULE "btshell" int diff --git a/apps/btshell/src/main.c b/apps/btshell/src/main.c index 410fb5a453..0db012e98c 100644 --- a/apps/btshell/src/main.c +++ b/apps/btshell/src/main.c @@ -58,6 +58,10 @@ #include "../src/ble_hs_atomic_priv.h" #include "../src/ble_hs_priv.h" +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + #if MYNEWT_VAL(BLE_ROLE_CENTRAL) #define BTSHELL_MAX_SVCS 32 #define BTSHELL_MAX_CHRS 64 diff --git a/apps/bttester/src/btp_mesh.c b/apps/bttester/src/btp_mesh.c index 2825329aa6..aad7eb4ada 100644 --- a/apps/bttester/src/btp_mesh.c +++ b/apps/bttester/src/btp_mesh.c @@ -38,6 +38,10 @@ #include "btp/btp.h" +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + extern uint8_t own_addr_type; #define CONTROLLER_INDEX 0 diff --git a/apps/bttester/src/bttester.c b/apps/bttester/src/bttester.c index d5e0399a49..fa4a82bb6f 100644 --- a/apps/bttester/src/bttester.c +++ b/apps/bttester/src/bttester.c @@ -35,6 +35,10 @@ #include "bttester_pipe.h" #include "btp/btp.h" +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + #define CMD_QUEUED 2 static struct os_eventq avail_queue; diff --git a/apps/bttester/src/rtt_pipe.c b/apps/bttester/src/rtt_pipe.c index 4e66770926..d1a8bd4a46 100644 --- a/apps/bttester/src/rtt_pipe.c +++ b/apps/bttester/src/rtt_pipe.c @@ -19,6 +19,10 @@ #include "syscfg/syscfg.h" +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + #if MYNEWT_VAL(BTTESTER_PIPE_RTT) #include "os/mynewt.h" diff --git a/apps/mesh_badge/src/mesh.c b/apps/mesh_badge/src/mesh.c index ee999172b7..8137ab9217 100644 --- a/apps/mesh_badge/src/mesh.c +++ b/apps/mesh_badge/src/mesh.c @@ -11,6 +11,10 @@ #include "mesh.h" #include "board.h" +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + #define BT_COMP_ID_LF 0x05f1 #define MOD_LF 0x0000 diff --git a/apps/mesh_badge/src/reel_board.c b/apps/mesh_badge/src/reel_board.c index 5e5f6b4088..3cf527b9e6 100644 --- a/apps/mesh_badge/src/reel_board.c +++ b/apps/mesh_badge/src/reel_board.c @@ -20,6 +20,10 @@ #define printk console_printf +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + enum font_size { FONT_BIG = 0, FONT_MEDIUM = 1, diff --git a/nimble/controller/src/ble_ll_isoal.c b/nimble/controller/src/ble_ll_isoal.c index bed974bb3e..d23382c966 100644 --- a/nimble/controller/src/ble_ll_isoal.c +++ b/nimble/controller/src/ble_ll_isoal.c @@ -24,6 +24,10 @@ #include #include +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + #if MYNEWT_VAL(BLE_LL_ISO) STAILQ_HEAD(ble_ll_iso_tx_q, os_mbuf_pkthdr); diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index 434aaa969e..c077f25ff3 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -39,6 +39,10 @@ #error LE Coded PHY cannot be enabled on DA1469x #endif +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + /* Statistics */ STATS_SECT_START(ble_phy_stats) STATS_SECT_ENTRY(phy_isrs) diff --git a/nimble/drivers/native/src/ble_phy.c b/nimble/drivers/native/src/ble_phy.c index 5969dff1b6..e1d2e4aa73 100644 --- a/nimble/drivers/native/src/ble_phy.c +++ b/nimble/drivers/native/src/ble_phy.c @@ -28,6 +28,10 @@ #include "controller/ble_phy.h" #include "controller/ble_ll.h" +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + /* BLE PHY data structure */ struct ble_phy_obj { diff --git a/nimble/drivers/nrf51/src/ble_phy.c b/nimble/drivers/nrf51/src/ble_phy.c index c3a523dce1..955db6351f 100644 --- a/nimble/drivers/nrf51/src/ble_phy.c +++ b/nimble/drivers/nrf51/src/ble_phy.c @@ -47,6 +47,10 @@ #error LE Coded PHY cannot be enabled on nRF51 #endif +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + static uint32_t ble_phy_mode_pdu_start_off(int phy_mode) { diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index f556f65024..3deec7dd63 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -56,6 +56,10 @@ #include #include "phy_priv.h" +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) #if !MYNEWT_VAL_CHOICE(MCU_TARGET, nRF52840) && \ !MYNEWT_VAL_CHOICE(MCU_TARGET, nRF52811) && \ diff --git a/nimble/host/src/ble_iso.c b/nimble/host/src/ble_iso.c index 7e78cc9607..600e7ed5bf 100644 --- a/nimble/host/src/ble_iso.c +++ b/nimble/host/src/ble_iso.c @@ -30,6 +30,10 @@ #include "ble_hs_hci_priv.h" #include "ble_hs_mbuf_priv.h" +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + #define ble_iso_big_conn_handles_init(_big, _handles, _num_handles) \ do { \ struct ble_iso_conn *conn = SLIST_FIRST(&ble_iso_conns); \ diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c index d4cb15f971..3a483c7510 100644 --- a/nimble/host/src/ble_l2cap_coc.c +++ b/nimble/host/src/ble_l2cap_coc.c @@ -25,6 +25,10 @@ #include "ble_l2cap_coc_priv.h" #include "ble_l2cap_sig_priv.h" +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 && NIMBLE_BLE_CONNECT #ifndef min diff --git a/nimble/host/test/src/ble_att_svr_test.c b/nimble/host/test/src/ble_att_svr_test.c index 84394d6a56..95b5eec67c 100644 --- a/nimble/host/test/src/ble_att_svr_test.c +++ b/nimble/host/test/src/ble_att_svr_test.c @@ -27,6 +27,10 @@ #include "host/ble_l2cap.h" #include "ble_hs_test_util.h" +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + static uint8_t *ble_att_svr_test_attr_r_1; static uint16_t ble_att_svr_test_attr_r_1_len; static uint8_t *ble_att_svr_test_attr_r_2; diff --git a/porting/nimble/src/os_mbuf.c b/porting/nimble/src/os_mbuf.c index 796a853759..6d84be1f4b 100644 --- a/porting/nimble/src/os_mbuf.c +++ b/porting/nimble/src/os_mbuf.c @@ -1273,4 +1273,4 @@ os_mbuf_pack_chains(struct os_mbuf *m1, struct os_mbuf *m2) } return m1; -} \ No newline at end of file +} From 63db05e991af2279e1c2b956f6975e8164741e0d Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Wed, 27 Nov 2024 20:02:14 +0100 Subject: [PATCH 1167/1333] nimble/eatt: Handle MTU request over enhanced bearer Handle ATT MTU request over enhanced bearer. This request shall return Request Not Supported error (0x06) This is required for GATT/CL/GAC/BV-01-C test. --- nimble/host/src/ble_att.c | 4 ++++ nimble/host/src/ble_att_svr.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index 4a867639c4..471f6cab97 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -639,6 +639,10 @@ bool ble_eatt_supported_req(uint8_t opcode) { switch (opcode) { + /* EATT does not support MTU request, + * but we must handle this request with proper error response. + */ + case BLE_ATT_OP_MTU_REQ: case BLE_ATT_OP_WRITE_CMD: case BLE_ATT_OP_FIND_INFO_REQ: case BLE_ATT_OP_FIND_TYPE_VALUE_REQ: diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 783999d991..e584cae32d 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -747,7 +747,7 @@ ble_att_svr_rx_mtu(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rxom) mtu = 0; if (cid != BLE_L2CAP_CID_ATT) { - /*TODO */ + /* This operation is not supported over enhanced ATT bearer */ return BLE_HS_ENOTSUP; } From 207b1074fab736a381e06e22e58f30d2908e87c2 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Mon, 18 Nov 2024 11:14:19 +0100 Subject: [PATCH 1168/1333] nimble/ll: Add vs hci cmd with additional scan cfg This allows to configure scanner to: - ignore either legacy or extended packets, - set minimal RSSI filter on primary channel. If scan is enabled command returns command disallowed error. --- .../include/controller/ble_ll_scan.h | 16 +++++++ nimble/controller/src/ble_ll_hci_vs.c | 35 ++++++++++++++ nimble/controller/src/ble_ll_scan.c | 46 ++++++++++++++++++- nimble/controller/syscfg.yml | 11 +++++ nimble/include/nimble/hci_common.h | 10 ++++ 5 files changed, 116 insertions(+), 2 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index 07e4c9208a..19d9cdd9c6 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -99,6 +99,14 @@ struct ble_ll_scan_pdu_data { uint8_t adva[BLE_DEV_ADDR_LEN]; }; +struct ble_ll_scan_vs_config { + uint8_t ignore_legacy : 1; + uint8_t ignore_ext : 1; + uint8_t rssi_filter : 1; + + int8_t rssi_threshold; +}; + struct ble_ll_scan_addr_data { uint8_t *adva; uint8_t *targeta; @@ -156,6 +164,10 @@ struct ble_ll_scan_sm /* Connection sm for initiator scan */ struct ble_ll_conn_sm *connsm; #endif + +#if MYNEWT_VAL(BLE_LL_HCI_VS_SET_SCAN_CFG) + struct ble_ll_scan_vs_config vs_config; +#endif }; /* Scan types */ @@ -259,6 +271,10 @@ ble_ll_scan_rx_filter(uint8_t own_addr_type, uint8_t scan_filt_policy, struct ble_ll_scan_addr_data *addrd, uint8_t *scan_ok); int ble_ll_scan_rx_check_init(struct ble_ll_scan_addr_data *addrd); +#if MYNEWT_VAL(BLE_LL_HCI_VS_SET_SCAN_CFG) +int ble_ll_scan_set_vs_config(uint32_t flags, int8_t rssi_threshold); +#endif + #ifdef __cplusplus } #endif diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index 1710e456fe..df8b688697 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -356,6 +356,37 @@ ble_ll_hci_vs_set_local_irk(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, } #endif +#if MYNEWT_VAL(BLE_LL_HCI_VS_SET_SCAN_CFG) +static int +ble_ll_hci_vs_set_scan_cfg(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_vs_set_scan_cfg_cp *cmd = (const void *)cmdbuf; + uint32_t flags; + int rc; + + if (cmdlen != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + flags = le32toh(cmd->flags); + + if ((flags & BLE_HCI_VS_SET_SCAN_CFG_FLAG_NO_LEGACY) && + (flags & BLE_HCI_VS_SET_SCAN_CFG_FLAG_NO_EXT)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + rc = ble_ll_scan_set_vs_config(flags, cmd->rssi_threshold); + if (rc != 0) { + return BLE_ERR_CMD_DISALLOWED; + } + + *rsplen = 0; + + return 0; +} +#endif + static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_RD_STATIC_ADDR, ble_ll_hci_vs_rd_static_addr), @@ -386,6 +417,10 @@ static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = { BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_LOCAL_IRK, ble_ll_hci_vs_set_local_irk), #endif +#if MYNEWT_VAL(BLE_LL_HCI_VS_SET_SCAN_CFG) + BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_SCAN_CFG, + ble_ll_hci_vs_set_scan_cfg) +#endif }; static struct ble_ll_hci_vs_cmd * diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 670f6b38cb..157ba94c1b 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -2000,8 +2000,10 @@ ble_ll_scan_rx_pkt_in_on_legacy(uint8_t pdu_type, struct os_mbuf *om, void ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hdr) { +#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_HCI_VS_SET_SCAN_CFG) + struct ble_mbuf_hdr_rxinfo *rxinfo = &hdr->rxinfo; +#endif #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) - struct ble_mbuf_hdr_rxinfo *rxinfo; uint8_t *targeta; #endif struct ble_ll_scan_sm *scansm; @@ -2023,6 +2025,26 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd return; } +#if MYNEWT_VAL(BLE_LL_HCI_VS_SET_SCAN_CFG) + if ((scansm->vs_config.ignore_ext) && + (ptype == BLE_ADV_PDU_TYPE_ADV_EXT_IND)) { + ble_ll_scan_chk_resume(); + return; + } + + if ((scansm->vs_config.ignore_legacy) && + (ptype != BLE_ADV_PDU_TYPE_ADV_EXT_IND)) { + ble_ll_scan_chk_resume(); + return; + } + + if ((scansm->vs_config.rssi_filter) && + (rxinfo->rssi < scansm->vs_config.rssi_threshold)) { + ble_ll_scan_chk_resume(); + return; + } +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (ptype == BLE_ADV_PDU_TYPE_ADV_EXT_IND) { ble_ll_scan_aux_pkt_in_on_ext(om, hdr); @@ -2034,7 +2056,6 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd switch (scansm->scanp->scan_type) { #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) case BLE_SCAN_TYPE_INITIATE: - rxinfo = &hdr->rxinfo; if (rxinfo->flags & BLE_MBUF_HDR_F_CONNECT_IND_TXD) { /* We need to keep original TargetA in case it was resolved, so rl * can be updated properly. @@ -2258,6 +2279,27 @@ ble_ll_scan_hci_set_ext_params(const uint8_t *cmdbuf, uint8_t len) #endif +#if MYNEWT_VAL(BLE_LL_HCI_VS_SET_SCAN_CFG) +int +ble_ll_scan_set_vs_config(uint32_t flags, int8_t rssi_threshold) +{ + struct ble_ll_scan_sm *scansm; + + scansm = &g_ble_ll_scan_sm; + + if (scansm->scan_enabled || scansm->connsm) { + return 1; + } + + scansm->vs_config.ignore_legacy = !!(flags & BLE_HCI_VS_SET_SCAN_CFG_FLAG_NO_LEGACY); + scansm->vs_config.ignore_ext = !!(flags & BLE_HCI_VS_SET_SCAN_CFG_FLAG_NO_EXT); + scansm->vs_config.rssi_filter = !!(flags & BLE_HCI_VS_SET_SCAN_CFG_FLAG_RSSI_FILTER); + scansm->vs_config.rssi_threshold = rssi_threshold; + + return 0; +} +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) static void ble_ll_scan_duration_period_timers_restart(struct ble_ll_scan_sm *scansm) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 862a36a523..bc4860c1bd 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -422,6 +422,17 @@ syscfg.defs: value: 0 restrictions: - BLE_LL_HCI_VS if 1 + BLE_LL_HCI_VS_SET_SCAN_CFG: + description: > + Enables HCI command to set global PDU filter for scanner. + It allows: + - ignoring extended or legacy PDUs while scanning, + - setting minimal RSSI filter on primary channel + value: 0 + restrictions: + - BLE_LL_HCI_VS if 1 + - BLE_LL_CFG_FEAT_LL_EXT_ADV if 1 + - BLE_LL_ROLE_OBSERVER if 1 BLE_LL_HCI_VS_EVENT_ON_ASSERT: diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 252b033973..6d9ba85db5 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1396,6 +1396,16 @@ struct ble_hci_vs_set_local_irk_cp { uint8_t irk[16]; } __attribute__((packed)); +#define BLE_HCI_VS_SET_SCAN_CFG_FLAG_NO_LEGACY (0x00000001) +#define BLE_HCI_VS_SET_SCAN_CFG_FLAG_NO_EXT (0x00000002) +#define BLE_HCI_VS_SET_SCAN_CFG_FLAG_RSSI_FILTER (0x00000004) + +#define BLE_HCI_OCF_VS_SET_SCAN_CFG (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x000B)) +struct ble_hci_vs_set_scan_cfg_cp { + uint32_t flags; + int8_t rssi_threshold; +} __attribute__((packed)); + /* Command Specific Definitions */ /* --- Set controller to host flow control (OGF 0x03, OCF 0x0031) --- */ #define BLE_HCI_CTLR_TO_HOST_FC_OFF (0) From 0f09bcfb99b6aa6fe91b6e11122fe4d3833d24d7 Mon Sep 17 00:00:00 2001 From: Mynewt Bot Date: Tue, 28 Jan 2025 10:11:13 +0000 Subject: [PATCH 1169/1333] porting: Update ports syscfg --- porting/npl/riot/include/syscfg/syscfg.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index de1f33f670..e6155c7b62 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1500,6 +1500,10 @@ #define MYNEWT_VAL_BLE_LL_HCI_VS_LOCAL_IRK (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_HCI_VS_SET_SCAN_CFG +#define MYNEWT_VAL_BLE_LL_HCI_VS_SET_SCAN_CFG (0) +#endif + #ifndef MYNEWT_VAL_BLE_LL_ISO #define MYNEWT_VAL_BLE_LL_ISO (0) #endif From c29b277c18f6de67dcae80688d66b0d9df3cc515 Mon Sep 17 00:00:00 2001 From: Guy Mishol Date: Wed, 22 Jan 2025 13:16:02 +0200 Subject: [PATCH 1170/1333] host: sm: secure connection only pairing might fail with no reason When BLE_SM_SC_ONLY is on during pairing request, the process might fail even though both SC is supported by the peer and the key size meet the requirements. --- nimble/host/src/ble_sm.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index eed5e3638b..a83b9ff287 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -1849,18 +1849,18 @@ ble_sm_pair_req_rx(uint16_t conn_handle, struct os_mbuf **om, } else if (req->max_enc_key_size > BLE_SM_PAIR_KEY_SZ_MAX) { res->sm_err = BLE_SM_ERR_INVAL; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_INVAL); - } else if (MYNEWT_VAL(BLE_SM_SC_ONLY)) { - /* Fail if Secure Connections Only mode is on and remote does not - * meet key size requirements - MITM was checked in last step. - * Fail if SC is not supported by peer or key size is too small + } else if (MYNEWT_VAL(BLE_SM_SC_ONLY) && !(req->authreq & BLE_SM_PAIR_AUTHREQ_SC)) { + /* Fail if Secure Connections Only mode is on and SC is not supported by peer */ - if (!(req->authreq & BLE_SM_PAIR_AUTHREQ_SC)) { - res->sm_err = BLE_SM_ERR_AUTHREQ; - res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_AUTHREQ); - } else if (req->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX) { - res->sm_err = BLE_SM_ERR_ENC_KEY_SZ; - res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_ENC_KEY_SZ); - } + res->sm_err = BLE_SM_ERR_AUTHREQ; + res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_AUTHREQ); + res->enc_cb = 1; + } else if (MYNEWT_VAL(BLE_SM_SC_ONLY) && (req->max_enc_key_size != BLE_SM_PAIR_KEY_SZ_MAX)) { + /* Fail if Secure Connections Only mode is on and key size is too small + */ + res->sm_err = BLE_SM_ERR_ENC_KEY_SZ; + res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_ENC_KEY_SZ); + res->enc_cb = 1; } else if (!ble_sm_verify_auth_requirements(req->authreq)) { res->sm_err = BLE_SM_ERR_AUTHREQ; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_AUTHREQ); From efec1cdafd084ea68a19e1d04d17b69fa129fdbe Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 10 Feb 2025 12:44:08 +0100 Subject: [PATCH 1171/1333] apps/bttester: Add option to disable default NimBLE configuration in app --- apps/bttester/pkg.yml | 9 +++--- apps/bttester/src/btp_pacs.c | 7 +++-- apps/bttester/syscfg.yml | 56 +++++++++++++++++++----------------- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/apps/bttester/pkg.yml b/apps/bttester/pkg.yml index 8511195452..ae05f1c9de 100644 --- a/apps/bttester/pkg.yml +++ b/apps/bttester/pkg.yml @@ -32,15 +32,16 @@ pkg.deps: - "@apache-mynewt-core/sys/stats" - "@apache-mynewt-core/sys/shell" - "@apache-mynewt-nimble/nimble/host" - - "@apache-mynewt-nimble/nimble/host/audio" - "@apache-mynewt-nimble/nimble/host/util" - "@apache-mynewt-nimble/nimble/host/services/gap" - "@apache-mynewt-nimble/nimble/host/services/gatt" - "@apache-mynewt-nimble/nimble/host/services/dis" - - "@apache-mynewt-nimble/nimble/host/audio/services/bass" - - "@apache-mynewt-nimble/nimble/host/audio/services/pacs" - - "@apache-mynewt-nimble/nimble/host/audio/services/pacs/lc3" - "@apache-mynewt-nimble/nimble/host/store/config" - "@apache-mynewt-core/hw/drivers/uart" - "@apache-mynewt-core/hw/drivers/rtt" +pkg.deps.BLE_AUDIO: + - "@apache-mynewt-nimble/nimble/host/audio" + - "@apache-mynewt-nimble/nimble/host/audio/services/bass" + - "@apache-mynewt-nimble/nimble/host/audio/services/pacs" + - "@apache-mynewt-nimble/nimble/host/audio/services/pacs/lc3" diff --git a/apps/bttester/src/btp_pacs.c b/apps/bttester/src/btp_pacs.c index 217d44df2f..9404cd946e 100644 --- a/apps/bttester/src/btp_pacs.c +++ b/apps/bttester/src/btp_pacs.c @@ -19,16 +19,17 @@ /* btp_pacs.c - Bluetooth Published Audio Capacity Service Tester */ +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(BLE_AUDIO) + #include "audio/ble_audio.h" #include "audio/ble_audio_codec.h" #include "btp/bttester.h" #include "host/ble_gap.h" #include "os/util.h" -#include "syscfg/syscfg.h" #include -#if MYNEWT_VAL(BLE_AUDIO) - #include "btp/btp.h" #include "btp/btp_pacs.h" #include "services/pacs/ble_audio_svc_pacs.h" diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 11daaae8db..0bab8b101e 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -16,9 +16,12 @@ # under the License. # -# Package: apps/blemesh - syscfg.defs: + BTTESTER_NODEFAULT: + description: > + Disable any NimBLE configuration in bttester app. + This is useful for building bttester apps with custom configuration. + value: 0 BTTESTER_UART_BAUD: description: 'Console UART baud rate.' value: '115200' @@ -99,31 +102,10 @@ syscfg.defs: value: '"test_broadcast"' syscfg.vals: - BLE_AUDIO_MAX_CODEC_RECORDS: 3 CONSOLE_IMPLEMENTATION: full LOG_IMPLEMENTATION: full STATS_IMPLEMENTATION: full - BLE_ISO: 1 - BLE_AUDIO: 1 - BLE_AUDIO_BROADCAST_SINK: 1 - BLE_AUDIO_BROADCAST_SINK_MAX: 2 - BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 - BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: 1 - BLE_ROLE_BROADCASTER: 1 - BLE_ISO_BROADCAST_SOURCE: 1 - BLE_ISO_BROADCAST_SINK: 1 - BLE_ISO_MAX_BISES: 3 - BLE_ISO_MAX_BIGS: 3 - BLE_EXT_ADV: 1 - BLE_PHY_2M: 1 - BLE_EXT_ADV_MAX_SIZE: 40 - BLE_PERIODIC_ADV: 1 - BLE_ISO_BROADCAST_SOURCE: 1 - BLE_MULTI_ADV_INSTANCES: 3 - BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ: 256 - BLE_SVC_AUDIO_BASS_SUB_NUM_MAX: 10 - OS_MAIN_STACK_SIZE: 512 SHELL_TASK: 0 SHELL_NEWTMGR: 0 @@ -137,11 +119,15 @@ syscfg.vals: RTT_NUM_BUFFERS_UP: 0 RTT_NUM_BUFFERS_DOWN: 0 + BLE_STORE_CONFIG_PERSIST: 0 + +syscfg.vals.!BTTESTER_NODEFAULT: + BLE_VERSION: 54 + BLE_L2CAP_COC_MAX_NUM: 5 BLE_L2CAP_SIG_MAX_PROCS: 2 BLE_L2CAP_ENHANCED_COC: 1 BLE_EATT_CHAN_NUM: 5 - BLE_VERSION: 54 # Some testcases require MPS < MTU BLE_L2CAP_COC_MPS: 100 BLE_RPA_TIMEOUT: 30 @@ -157,7 +143,26 @@ syscfg.vals: BLE_SVC_GAP_APPEARANCE_WRITE_PERM: 0 BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM: 0 BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH: 6 - BLE_STORE_CONFIG_PERSIST: 0 + + BLE_ISO: 1 + BLE_AUDIO: 1 + BLE_AUDIO_BROADCAST_SINK: 1 + BLE_AUDIO_BROADCAST_SINK_MAX: 2 + BLE_AUDIO_MAX_CODEC_RECORDS: 3 + BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 + BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: 1 + BLE_ROLE_BROADCASTER: 1 + BLE_ISO_BROADCAST_SOURCE: 1 + BLE_ISO_BROADCAST_SINK: 1 + BLE_ISO_MAX_BISES: 3 + BLE_ISO_MAX_BIGS: 3 + BLE_EXT_ADV: 1 + BLE_PHY_2M: 1 + BLE_EXT_ADV_MAX_SIZE: 40 + BLE_PERIODIC_ADV: 1 + BLE_MULTI_ADV_INSTANCES: 3 + BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ: 256 + BLE_SVC_AUDIO_BASS_SUB_NUM_MAX: 10 BLE_MESH: 1 BLE_MESH_SHELL: 0 @@ -183,4 +188,3 @@ syscfg.vals: BLE_MESH_RX_SEG_MAX: 13 BLE_MESH_TX_SEG_MSG_COUNT: 2 BLE_MAX_CONNECTIONS: 8 - From c3d13057414613430bd4cbea639ca1b00fa36656 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 10 Feb 2025 12:45:09 +0100 Subject: [PATCH 1172/1333] nimble: Add option to select Core 6.0 --- nimble/include/nimble/hci_common.h | 7 +++++++ nimble/syscfg.yml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 6d9ba85db5..395856f21b 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -2373,6 +2373,7 @@ struct ble_hci_ev_le_subev_cs_test_end_complete { #define BLE_HCI_VER_BCS_5_2 (11) #define BLE_HCI_VER_BCS_5_3 (12) #define BLE_HCI_VER_BCS_5_4 (13) +#define BLE_HCI_VER_BCS_6_0 (14) #define BLE_LMP_VER_BCS_1_0b (0) #define BLE_LMP_VER_BCS_1_1 (1) @@ -2388,6 +2389,7 @@ struct ble_hci_ev_le_subev_cs_test_end_complete { #define BLE_LMP_VER_BCS_5_2 (11) #define BLE_LMP_VER_BCS_5_3 (12) #define BLE_LMP_VER_BCS_5_4 (13) +#define BLE_LMP_VER_BCS_6_0 (14) /* selected HCI and LMP version */ #if MYNEWT_VAL(BLE_VERSION) == 50 @@ -2405,6 +2407,11 @@ struct ble_hci_ev_le_subev_cs_test_end_complete { #elif MYNEWT_VAL(BLE_VERSION) == 54 #define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_5_4 #define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_5_4 +#elif MYNEWT_VAL(BLE_VERSION) == 60 +#define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_6_0 +#define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_6_0 +#else +#error Unsupported BLE_VERSION selected #endif #define BLE_HCI_DATA_HDR_SZ 4 diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index d19702790f..638a40832c 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -87,7 +87,7 @@ syscfg.defs: This allows to configure supported Bluetooth Core version. Some features may not be available if version is too low. Version is integer for easy comparison. - range: 50, 51, 52, 53, 54 + range: 50, 51, 52, 53, 54, 60 value: 50 BLE_ISO: description: > From c9d6f5c5969a7fdfc1d05f6070ef00f7b3b02c6a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 3 Feb 2025 18:52:31 +0100 Subject: [PATCH 1173/1333] nimble/transport: Fix ISO HCI length parsing Length in ISO HCI packets is 14 bits. --- nimble/include/nimble/hci_common.h | 2 +- nimble/transport/common/hci_h4/src/hci_h4.c | 2 +- nimble/transport/nrf5340/src/nrf5340_ble_hci.c | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 395856f21b..f4fe5a7f81 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -2433,7 +2433,7 @@ struct hci_data_hdr #define BLE_HCI_ISO_CONN_HANDLE_MASK (0x07ff) #define BLE_HCI_ISO_PB_FLAG_MASK (0x3000) #define BLE_HCI_ISO_TS_FLAG_MASK (0x4000) -#define BLE_HCI_ISO_LENGTH_MASK (0x7fff) +#define BLE_HCI_ISO_LENGTH_MASK (0x3fff) #define BLE_HCI_ISO_SDU_LENGTH_MASK (0x0fff) #define BLE_HCI_ISO_PKT_STATUS_FLAG_MASK (0xC000) diff --git a/nimble/transport/common/hci_h4/src/hci_h4.c b/nimble/transport/common/hci_h4/src/hci_h4.c index e787bf5ef2..9af046ab63 100644 --- a/nimble/transport/common/hci_h4/src/hci_h4.c +++ b/nimble/transport/common/hci_h4/src/hci_h4.c @@ -177,7 +177,7 @@ hci_h4_sm_w4_header(struct hci_h4_sm *h4sm, struct hci_h4_input_buffer *ib) } os_mbuf_append(h4sm->om, h4sm->hdr, h4sm->len); - h4sm->exp_len = (get_le16(&h4sm->hdr[2]) & 0x7fff) + 4; + h4sm->exp_len = BLE_HCI_ISO_LENGTH(get_le16(&h4sm->hdr[2])) + 4; break; default: assert(0); diff --git a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c index 679cfb1241..f73be05522 100644 --- a/nimble/transport/nrf5340/src/nrf5340_ble_hci.c +++ b/nimble/transport/nrf5340/src/nrf5340_ble_hci.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -86,7 +87,7 @@ nrf5340_ble_hci_iso_tx(struct os_mbuf *om) int rc; hdr.type = HCI_IPC_TYPE_ISO; - hdr.length = 4 + get_le16(&om->om_data[2]); + hdr.length = 4 + BLE_HCI_ISO_LENGTH(get_le16(&om->om_data[2])); rc = ipc_nrf5340_write(IPC_TX_CHANNEL, &hdr, sizeof(hdr), false); if (rc == 0) { From be31782bd4d6aa524bc9d17d6e3e412ea063a314 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 31 Jan 2025 12:14:01 +0100 Subject: [PATCH 1174/1333] nimble/ll: Use RPA from global local IRK on active scan for legacy PDU Local IRK, if set, is used to generate local RPA in use cases where own address type was set to 0x02 or 0x03 but peer address is not added to resolving list. If no IRK is set (or set to all-zero), the controller uses NRPA. This is already done for AUX_SCAN_REQ and legacy PDU was accidentally omitted in previous PR. --- nimble/controller/src/ble_ll_scan.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 157ba94c1b..f2c52f19e3 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -288,8 +288,12 @@ ble_ll_scan_req_pdu_prepare(struct ble_ll_scan_sm *scansm, ble_ll_resolv_get_priv_addr(rl, 1, rpa); scana = rpa; } else { - ble_ll_scan_refresh_nrpa(scansm); - scana = scansm->scan_nrpa; + if (ble_ll_resolv_local_rpa_get(scansm->own_addr_type & 0x01, rpa) == 0) { + scana = rpa; + } else { + ble_ll_scan_refresh_nrpa(scansm); + scana = scansm->scan_nrpa; + } } hdr_byte |= BLE_ADV_PDU_HDR_TXADD_RAND; From 3c108d364f3c899c56969aedc54de25111876c37 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 4 Feb 2025 10:17:48 +0100 Subject: [PATCH 1175/1333] nimble/ll: Use helper to read 24-bit values --- nimble/controller/src/ble_ll_adv.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 3b36c87a53..646e8b12a8 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -3461,10 +3461,8 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, } #endif - adv_itvl_min = cmd->pri_itvl_min[2] << 16 | cmd->pri_itvl_min[1] << 8 | - cmd->pri_itvl_min[0]; - adv_itvl_max = cmd->pri_itvl_max[2] << 16 | cmd->pri_itvl_max[1] << 8 | - cmd->pri_itvl_max[0]; + adv_itvl_min = get_le24(cmd->pri_itvl_min); + adv_itvl_max = get_le24(cmd->pri_itvl_max); if (props & ~BLE_HCI_LE_SET_EXT_ADV_PROP_MASK) { rc = BLE_ERR_INV_HCI_CMD_PARMS; From 019e14ce7cd2993c34490cd924d5457878fed959 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 4 Feb 2025 10:18:05 +0100 Subject: [PATCH 1176/1333] nimble/ll: Validate PHY in HCI LE BIG Create This adds validation of phy parameter in HCI LE BIG Create to make sure we don't accept phy that we do not support. --- nimble/controller/src/ble_ll_iso_big.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 5aee5de123..3b5cbf5ce0 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -1280,6 +1280,7 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len) { const struct ble_hci_le_create_big_cp *cmd = (void *)cmdbuf; struct big_params bp; + uint8_t valid_phys; int rc; if (len != sizeof(*cmd)) { @@ -1297,6 +1298,18 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } + valid_phys = BLE_HCI_LE_PHY_1M_PREF_MASK; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY) + valid_phys |= BLE_HCI_LE_PHY_2M_PREF_MASK; +#endif +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY) + valid_phys |= BLE_HCI_LE_PHY_CODED_PREF_MASK; +#endif + + if (cmd->phy & ~valid_phys) { + return BLE_ERR_UNSUPPORTED; + } + bp.sdu_interval = get_le24(cmd->sdu_interval); bp.max_transport_latency = le16toh(cmd->max_transport_latency); bp.max_sdu = le16toh(cmd->max_sdu); From 0fde9712f25957461a26c9695e4eb399c3ebc9ab Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 4 Feb 2025 11:23:44 +0100 Subject: [PATCH 1177/1333] nimble/ll: Update LE supported commands bitmask Add HCI commands related to ISO Data Path to commands bitmask - we already support them. --- nimble/controller/src/ble_ll_hci_supp_cmd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/controller/src/ble_ll_hci_supp_cmd.c b/nimble/controller/src/ble_ll_hci_supp_cmd.c index 732381ea20..eb4182ed6b 100644 --- a/nimble/controller/src/ble_ll_hci_supp_cmd.c +++ b/nimble/controller/src/ble_ll_hci_supp_cmd.c @@ -273,6 +273,10 @@ static const uint8_t octet_43 = OCTET( #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE) BIT(2) /* HCI LE Request Peer SCA */ #endif +#if MYNEWT_VAL(BLE_LL_ISO) + BIT(3) /* HCI LE Setup ISO Data Path */ + BIT(4) /* HCI LE Remove ISO Data Path */ +#endif ); static const uint8_t octet_44 = OCTET( From 0ae94f81b5c5736ad5397290c2463139df06e9ad Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 4 Feb 2025 13:54:26 +0100 Subject: [PATCH 1178/1333] nimble/ll: Fix PHY validation for PAST phy parameter in PAST HCI command shall have only single bit set. --- nimble/controller/src/ble_ll_ctrl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 6562766d31..a71ccdbd1d 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -650,6 +650,11 @@ ble_ll_ctrl_phy_from_phy_mask(uint8_t phy_mask) { uint8_t phy; + /* One and only one bit shall be set */ + if (__builtin_popcount(phy_mask) != 1) { + return 0; + } + /* * NOTE: wipe out unsupported PHYs. There should not be an unsupported * in this mask if the other side is working correctly. From cb6a375b5fdf17dff05b9059ce2786dfdf584a66 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 4 Feb 2025 15:12:41 +0100 Subject: [PATCH 1179/1333] nimble/ll: Handle max_transport_latency violation on BIG create This adds validation of max_transport_latency parameter for HCI LE BIG Create command. The calculations are done as per Core 6.0, Vol 6, Part G, 3.2.1 and 3.2.2. --- nimble/controller/src/ble_ll_iso_big.c | 90 ++++++++++++++++---------- 1 file changed, 56 insertions(+), 34 deletions(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 3b5cbf5ce0..97829e70c1 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -84,7 +84,7 @@ struct big_params { uint8_t pto; /* 0-15, mandatory 0 */ uint32_t sdu_interval; uint16_t iso_interval; - uint16_t max_transport_latency; + uint16_t max_transport_latency_ms; uint16_t max_sdu; uint8_t max_pdu; uint8_t phy; @@ -132,6 +132,7 @@ struct ble_ll_iso_big { uint64_t bis_counter; uint32_t sync_delay; + uint32_t transport_latency_us; uint32_t event_start; uint8_t event_start_us; uint32_t anchor_base_ticks; @@ -986,12 +987,16 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, BLE_LL_ASSERT(big); + big_pool_free--; + advsm = ble_ll_adv_sync_get(adv_handle); if (!advsm) { + ble_ll_iso_big_free(big); return -ENOENT; } if (ble_ll_adv_sync_big_add(advsm, big) < 0) { + ble_ll_iso_big_free(big); return -ENOENT; } @@ -1044,34 +1049,8 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, bp->sdu_interval, bp->bn, pte); } - big_pool_free--; bis_pool_free -= num_bis; - /* Calculate AA for each BIS and BIG Control. We have to repeat this process - * until all AAs are valid. - */ - do { - rc = 0; - - seed_aa = ble_ll_utils_calc_seed_aa(); - big->ctrl_aa = ble_ll_utils_calc_big_aa(seed_aa, 0); - - if (!ble_ll_utils_verify_aa(big->ctrl_aa)) { - continue; - } - - rc = 1; - - STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) { - bis->aa = ble_ll_utils_calc_big_aa(seed_aa, bis->num); - if (!ble_ll_utils_verify_aa(bis->aa)) { - rc = 0; - break; - } - bis->chan_id = bis->aa ^ (bis->aa >> 16); - } - } while (rc == 0); - big->bn = bp->bn; big->pto = bp->pto; big->irc = bp->irc; @@ -1107,13 +1086,54 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, big->pto = 0; } + /* Core 6.0, Vol 6, Part G, 3.2.1 and 3.2.2 */ + if (big->framed) { + big->transport_latency_us = big->sync_delay + + (big->pto * (big->nse / big->bn - big->irc) + 1) * + big->iso_interval * 1250 + big->sdu_interval; + } else { + big->transport_latency_us = big->sync_delay + + (big->pto * (big->nse / big->bn - big->irc) + 1) * + big->iso_interval * 1250 - big->sdu_interval; + } + + if (big->transport_latency_us > bp->max_transport_latency_ms * 1000) { + ble_ll_iso_big_free(big); + return -ERANGE; + } + + /* Calculate AA for each BIS and BIG Control. We have to repeat this process + * until all AAs are valid. + */ + do { + rc = 0; + + seed_aa = ble_ll_utils_calc_seed_aa(); + big->ctrl_aa = ble_ll_utils_calc_big_aa(seed_aa, 0); + + if (!ble_ll_utils_verify_aa(big->ctrl_aa)) { + continue; + } + + rc = 1; + + STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) { + bis->aa = ble_ll_utils_calc_big_aa(seed_aa, bis->num); + if (!ble_ll_utils_verify_aa(bis->aa)) { + rc = 0; + break; + } + bis->chan_id = bis->aa ^ (bis->aa >> 16); + } + } while (rc == 0); + + ble_ll_iso_big_biginfo_calc(big, seed_aa); + if (big->encrypted) { ble_ll_iso_big_calculate_gsk(big, bp->broadcast_code); ble_ll_iso_big_calculate_iv(big); } - ble_ll_iso_big_biginfo_calc(big, seed_aa); - /* For now we will schedule complete event as single item. This allows for * shortest possible subevent space (150us) but can create sequence of long * events that will block scheduler from other activities. To mitigate this @@ -1253,10 +1273,7 @@ ble_ll_iso_big_hci_evt_complete(void) evt->big_handle = big->handle; put_le24(evt->big_sync_delay, big->sync_delay); /* Core 5.3, Vol 6, Part G, 3.2.2 */ - put_le24(evt->transport_latency_big, - big->sync_delay + - (big->pto * (big->nse / big->bn - big->irc) + 1) * big->iso_interval * 1250 - - big->sdu_interval); + put_le24(evt->transport_latency_big, big->transport_latency_us); evt->phy = big->phy; evt->nse = big->nse; evt->bn = big->bn; @@ -1311,7 +1328,7 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len) } bp.sdu_interval = get_le24(cmd->sdu_interval); - bp.max_transport_latency = le16toh(cmd->max_transport_latency); + bp.max_transport_latency_ms = le16toh(cmd->max_transport_latency); bp.max_sdu = le16toh(cmd->max_sdu); if (cmd->phy & BLE_HCI_LE_PHY_2M_PREF_MASK) { bp.phy = BLE_PHY_2M; @@ -1346,6 +1363,8 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_CONN_REJ_RESOURCES; case -ENOENT: return BLE_ERR_UNK_ADV_INDENT; + case -ERANGE: + return BLE_ERR_UNSUPPORTED; default: return BLE_ERR_UNSPECIFIED; } @@ -1388,6 +1407,7 @@ ble_ll_iso_big_hci_create_test(const uint8_t *cmdbuf, uint8_t len) bp.pto = cmd->pto; bp.sdu_interval = get_le24(cmd->sdu_interval); bp.iso_interval = le16toh(cmd->iso_interval); + bp.max_transport_latency_ms = 0x0fa0; /* max_transport_latency for HCI LE Create BIG */ bp.max_sdu = le16toh(cmd->max_sdu); bp.max_pdu = le16toh(cmd->max_pdu); /* TODO verify phy */ @@ -1432,6 +1452,8 @@ ble_ll_iso_big_hci_create_test(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_CONN_REJ_RESOURCES; case -ENOENT: return BLE_ERR_UNK_ADV_INDENT; + case -ERANGE: + return BLE_ERR_UNSUPPORTED; default: return BLE_ERR_UNSPECIFIED; } From 93394c249eb54cbd1c03f7081e2f76e8c202d927 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 4 Feb 2025 15:13:12 +0100 Subject: [PATCH 1180/1333] nimble/ll: Handle duplicated BIG on BIG create Trying to create BIG with the same handle as existing one should return command disallowed status. --- nimble/controller/src/ble_ll_iso_big.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 97829e70c1..8f52dfedd7 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -1357,6 +1357,8 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len) switch (rc) { case 0: break; + case -EALREADY: + return BLE_ERR_CMD_DISALLOWED; case -EINVAL: return BLE_ERR_INV_HCI_CMD_PARMS; case -ENOMEM: @@ -1446,6 +1448,8 @@ ble_ll_iso_big_hci_create_test(const uint8_t *cmdbuf, uint8_t len) switch (rc) { case 0: break; + case -EALREADY: + return BLE_ERR_CMD_DISALLOWED; case -EINVAL: return BLE_ERR_INV_HCI_CMD_PARMS; case -ENOMEM: From 7e60f76001ddc8e3387dd43e2ce7d818b784c64a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 5 Feb 2025 10:23:39 +0100 Subject: [PATCH 1181/1333] nimble/ll: Fix encryption key refresh with central role disabled If peripheral role is disabled, we still need to handle LL_PAUSE_ENC_RSP whic is used for encryption key refresh procedure. --- nimble/controller/src/ble_ll_ctrl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index a71ccdbd1d..a05b5c9d8b 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -3229,6 +3229,11 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) connsm->flags.pending_encrypt_restart = 1; } break; +#else + case BLE_LL_CTRL_PAUSE_ENC_RSP: + BLE_LL_ASSERT(connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL); + connsm->flags.pending_encrypt_restart = 1; + break; #endif #endif #if MYNEWT_VAL(BLE_LL_PHY) From f9e8571a473d77d1e1134cce94d12cd611d441b5 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 6 Feb 2025 12:59:57 +0100 Subject: [PATCH 1182/1333] nimble/ll: Update BIG data for BIGinfo atomically We need to make sure that counters and event start time are updated atomically so they are in sync when BIGInfo is calculated. --- nimble/controller/src/ble_ll_iso_big.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 8f52dfedd7..de895b1eac 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -326,7 +326,7 @@ ble_ll_iso_big_biginfo_copy(struct ble_ll_iso_big *big, uint8_t *dptr, */ if (event_start <= base_ticks) { ble_ll_tmr_add(&event_start, &event_start_us, big->iso_interval * 1250); - counter++; + counter += big->bn; } /* Drop BIGInfo if BIG event is still before AUX_SYNC_IND. This should not @@ -440,13 +440,17 @@ ble_ll_iso_big_chan_map_update_complete(struct ble_ll_iso_big *big) } static void -ble_ll_iso_big_update_event_start(struct ble_ll_iso_big *big) +ble_ll_iso_big_update_event_start(struct ble_ll_iso_big *big, + uint64_t new_big_counter) { os_sr_t sr; OS_ENTER_CRITICAL(sr); + /* This has to be updated atomically to avoid races when copying to BIGInfo */ big->event_start = big->sch.start_time + g_ble_ll_sched_offset_ticks; big->event_start_us = big->sch.remainder; + big->bis_counter += (new_big_counter - big->big_counter) * big->bn; + big->big_counter = new_big_counter; OS_EXIT_CRITICAL(sr); } @@ -462,6 +466,7 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) uint16_t exp; uint32_t now; #endif + uint64_t big_counter; struct ble_hci_ev_num_comp_pkts *hci_ev_ncp = NULL; int num_completed_pkt; int idx; @@ -548,13 +553,13 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) big->sch.start_time = big->event_start; big->sch.remainder = big->event_start_us; + big_counter = big->big_counter; do { - big->big_counter++; - big->bis_counter += big->bn; + big_counter++; if (big->control_active && - (big->control_instant == (uint16_t)big->big_counter)) { + (big->control_instant == (uint16_t)big_counter)) { switch (big->control_active) { case BIG_CONTROL_ACTIVE_TERM: ble_ll_iso_big_terminate_complete(big); @@ -583,7 +588,7 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) } if (big->control_active) { - big->control_instant = big->big_counter + 6; + big->control_instant = big_counter + 6; big->cstf = 1; big->cssn += 1; } @@ -597,7 +602,7 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) assert(rc == 0); } while (rc < 0); - ble_ll_iso_big_update_event_start(big); + ble_ll_iso_big_update_event_start(big, big_counter); } static void @@ -1180,7 +1185,7 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, } } while (rc < 0); - ble_ll_iso_big_update_event_start(big); + ble_ll_iso_big_update_event_start(big, big->big_counter); big_pending = big; From bea72800c64000e9c06836e49de741ca6d318fa6 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 29 Jan 2025 11:00:08 +0100 Subject: [PATCH 1183/1333] ci: Update uncrustify configuration to 0.78 Also park GHA image to specific ubuntu version (24.04). --- .github/workflows/compliance_check.yml | 6 +- uncrustify.cfg | 4475 ++++++++++++++++-------- 2 files changed, 3115 insertions(+), 1366 deletions(-) diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index ade32b220a..1311335873 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -24,7 +24,7 @@ on: [pull_request] jobs: style_check: name: Coding style - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v3 with: @@ -43,7 +43,7 @@ jobs: style_license: name: Licensing - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v3 with: @@ -63,7 +63,7 @@ jobs: style_doxygen: name: Doxygen Style - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v3 with: diff --git a/uncrustify.cfg b/uncrustify.cfg index 1735f339ad..43dee3b91c 100644 --- a/uncrustify.cfg +++ b/uncrustify.cfg @@ -1,1959 +1,3708 @@ +# Uncrustify_d-0.78.1_f + # # General options # -# The type of line endings. Default=Auto -newlines = lf # auto/lf/crlf/cr +# The type of line endings. +# +# Default: auto +newlines = lf # lf/crlf/cr/auto -# The original size of tabs in the input. Default=8 -input_tab_size = 4 # number +# The original size of tabs in the input. +# +# Default: 8 +input_tab_size = 4 # unsigned number -# The size of tabs in the output (only used if align_with_tabs=true). Default=8 -output_tab_size = 4 # number +# The size of tabs in the output (only used if align_with_tabs=true). +# +# Default: 8 +output_tab_size = 4 # unsigned number -# The ASCII value of the string escape char, usually 92 (\) or 94 (^). (Pawn) -string_escape_char = 92 # number +# The ASCII value of the string escape char, usually 92 (\) or (Pawn) 94 (^). +# +# Default: 92 +string_escape_char = 92 # unsigned number -# Alternate string escape char for Pawn. Only works right before the quote char. -string_escape_char2 = 0 # number +# Alternate string escape char (usually only used for Pawn). +# Only works right before the quote char. +string_escape_char2 = 0 # unsigned number -# Replace tab characters found in string literals with the escape sequence \t instead. -string_replace_tab_chars = false # false/true +# Replace tab characters found in string literals with the escape sequence \t +# instead. +string_replace_tab_chars = false # true/false -# Allow interpreting '>=' and '>>=' as part of a template in 'void f(list>=val);'. -# If true, 'assert(x<0 && y>=3)' will be broken. Default=False +# Allow interpreting '>=' and '>>=' as part of a template in code like +# 'void f(list>=val);'. If true, 'assert(x<0 && y>=3)' will be broken. # Improvements to template detection may make this option obsolete. -tok_split_gte = false # false/true +tok_split_gte = false # true/false + +# Disable formatting of NL_CONT ('\\n') ended lines (e.g. multi-line macros). +disable_processing_nl_cont = false # true/false -# Override the default ' *INDENT-OFF*' in comments for disabling processing of part of the file. +# Specify the marker used in comments to disable processing of part of the +# file. +# +# Default: *INDENT-OFF* disable_processing_cmt = "" # string -# Override the default ' *INDENT-ON*' in comments for enabling processing of part of the file. +# Specify the marker used in comments to (re)enable processing in a file. +# +# Default: *INDENT-ON* enable_processing_cmt = "" # string -# Enable parsing of digraphs. Default=False -enable_digraphs = false # false/true +# Enable parsing of digraphs. +enable_digraphs = false # true/false -# Control what to do with the UTF-8 BOM (recommend 'remove') -utf8_bom = ignore # ignore/add/remove/force +# Option to allow both disable_processing_cmt and enable_processing_cmt +# strings, if specified, to be interpreted as ECMAScript regular expressions. +# If true, a regex search will be performed within comments according to the +# specified patterns in order to disable/enable processing. +processing_cmt_as_regex = false # true/false -# If the file contains bytes with values between 128 and 255, but is not UTF-8, then output as UTF-8 -utf8_byte = false # false/true +# Add or remove the UTF-8 BOM (recommend 'remove'). +utf8_bom = ignore # ignore/add/remove/force/not_defined -# Force the output encoding to UTF-8 -utf8_force = false # false/true +# If the file contains bytes with values between 128 and 255, but is not +# UTF-8, then output as UTF-8. +utf8_byte = false # true/false + +# Force the output encoding to UTF-8. +utf8_force = false # true/false # -# Indenting +# Spacing options # -# The number of columns to indent per level. -# Usually 2, 3, 4, or 8. Default=8 -indent_columns = 4 # number +# Add or remove space around non-assignment symbolic operators ('+', '/', '%', +# '<<', and so forth). +sp_arith = force # ignore/add/remove/force/not_defined -# The continuation indent. If non-zero, this overrides the indent of '(' and '=' continuation indents. -# For FreeBSD, this is set to 4. Negative value is absolute and not increased for each ( level -indent_continue = 0 # number +# Add or remove space around arithmetic operators '+' and '-'. +# +# Overrides sp_arith. +sp_arith_additive = ignore # ignore/add/remove/force/not_defined -# How to use tabs when indenting code -# 0=spaces only -# 1=indent with tabs to brace level, align with spaces (default) -# 2=indent and align with tabs, using spaces when not on a tabstop -indent_with_tabs = 0 # number +# Add or remove space around assignment operator '=', '+=', etc. +sp_assign = force # ignore/add/remove/force/not_defined -# Comments that are not a brace level are indented with tabs on a tabstop. -# Requires indent_with_tabs=2. If false, will use spaces. -indent_cmt_with_tabs = false # false/true +# Add or remove space around '=' in C++11 lambda capture specifications. +# +# Overrides sp_assign. +sp_cpp_lambda_assign = ignore # ignore/add/remove/force/not_defined -# Whether to indent strings broken by '\' so that they line up -indent_align_string = false # false/true +# Add or remove space after the capture specification of a C++11 lambda when +# an argument list is present, as in '[] (int x){ ... }'. +sp_cpp_lambda_square_paren = ignore # ignore/add/remove/force/not_defined -# The number of spaces to indent multi-line XML strings. -# Requires indent_align_string=True -indent_xml_string = 0 # number +# Add or remove space after the capture specification of a C++11 lambda with +# no argument list is present, as in '[] { ... }'. +sp_cpp_lambda_square_brace = ignore # ignore/add/remove/force/not_defined -# Spaces to indent '{' from level -indent_brace = 0 # number +# Add or remove space after the opening parenthesis and before the closing +# parenthesis of a argument list of a C++11 lambda, as in +# '[]( ){ ... }' +# with an empty list. +sp_cpp_lambda_argument_list_empty = ignore # ignore/add/remove/force/not_defined -# Whether braces are indented to the body level -indent_braces = false # false/true +# Add or remove space after the opening parenthesis and before the closing +# parenthesis of a argument list of a C++11 lambda, as in +# '[]( int x ){ ... }'. +sp_cpp_lambda_argument_list = ignore # ignore/add/remove/force/not_defined -# Disabled indenting function braces if indent_braces is true -indent_braces_no_func = false # false/true +# Add or remove space after the argument list of a C++11 lambda, as in +# '[](int x) { ... }'. +sp_cpp_lambda_paren_brace = ignore # ignore/add/remove/force/not_defined -# Disabled indenting class braces if indent_braces is true -indent_braces_no_class = false # false/true +# Add or remove space between a lambda body and its call operator of an +# immediately invoked lambda, as in '[]( ... ){ ... } ( ... )'. +sp_cpp_lambda_fparen = ignore # ignore/add/remove/force/not_defined -# Disabled indenting struct braces if indent_braces is true -indent_braces_no_struct = false # false/true +# Add or remove space around assignment operator '=' in a prototype. +# +# If set to ignore, use sp_assign. +sp_assign_default = ignore # ignore/add/remove/force/not_defined -# Indent based on the size of the brace parent, i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc. -indent_brace_parent = false # false/true +# Add or remove space before assignment operator '=', '+=', etc. +# +# Overrides sp_assign. +sp_before_assign = ignore # ignore/add/remove/force/not_defined -# Indent based on the paren open instead of the brace open in '({\n', default is to indent by brace. -indent_paren_open_brace = false # false/true +# Add or remove space after assignment operator '=', '+=', etc. +# +# Overrides sp_assign. +sp_after_assign = ignore # ignore/add/remove/force/not_defined -# indent a C# delegate by another level, default is to not indent by another level. -indent_cs_delegate_brace = false # false/true +# Add or remove space in 'enum {'. +# +# Default: add +sp_enum_brace = add # ignore/add/remove/force/not_defined -# Whether the 'namespace' body is indented -indent_namespace = false # false/true +# Add or remove space in 'NS_ENUM ('. +sp_enum_paren = ignore # ignore/add/remove/force/not_defined -# Only indent one namespace and no sub-namespaces. -# Requires indent_namespace=true. -indent_namespace_single_indent = false # false/true +# Add or remove space around assignment '=' in enum. +sp_enum_assign = ignore # ignore/add/remove/force/not_defined -# The number of spaces to indent a namespace block -indent_namespace_level = 0 # number +# Add or remove space before assignment '=' in enum. +# +# Overrides sp_enum_assign. +sp_enum_before_assign = ignore # ignore/add/remove/force/not_defined -# If the body of the namespace is longer than this number, it won't be indented. -# Requires indent_namespace=true. Default=0 (no limit) -indent_namespace_limit = 0 # number +# Add or remove space after assignment '=' in enum. +# +# Overrides sp_enum_assign. +sp_enum_after_assign = ignore # ignore/add/remove/force/not_defined -# Whether the 'extern "C"' body is indented -indent_extern = false # false/true +# Add or remove space around assignment ':' in enum. +sp_enum_colon = ignore # ignore/add/remove/force/not_defined -# Whether the 'class' body is indented -indent_class = true # false/true +# Add or remove space around preprocessor '##' concatenation operator. +# +# Default: add +sp_pp_concat = add # ignore/add/remove/force/not_defined -# Whether to indent the stuff after a leading base class colon -indent_class_colon = true # false/true +# Add or remove space after preprocessor '#' stringify operator. +# Also affects the '#@' charizing operator. +sp_pp_stringify = ignore # ignore/add/remove/force/not_defined -# Indent based on a class colon instead of the stuff after the colon. -# Requires indent_class_colon=true. Default=False -indent_class_on_colon = false # false/true +# Add or remove space before preprocessor '#' stringify operator +# as in '#define x(y) L#y'. +sp_before_pp_stringify = ignore # ignore/add/remove/force/not_defined -# Whether to indent the stuff after a leading class initializer colon -indent_constr_colon = false # false/true +# Add or remove space around boolean operators '&&' and '||'. +sp_bool = force # ignore/add/remove/force/not_defined -# Virtual indent from the ':' for member initializers. Default=2 -indent_ctor_init_leading = 2 # number +# Add or remove space around compare operator '<', '>', '==', etc. +sp_compare = force # ignore/add/remove/force/not_defined -# Additional indenting for constructor initializer list -indent_ctor_init = 0 # number +# Add or remove space inside '(' and ')'. +sp_inside_paren = remove # ignore/add/remove/force/not_defined -# False=treat 'else\nif' as 'else if' for indenting purposes -# True=indent the 'if' one level -indent_else_if = false # false/true +# Add or remove space between nested parentheses, i.e. '((' vs. ') )'. +sp_paren_paren = remove # ignore/add/remove/force/not_defined -# Amount to indent variable declarations after a open brace. neg=relative, pos=absolute -indent_var_def_blk = 0 # number +# Add or remove space between back-to-back parentheses, i.e. ')(' vs. ') ('. +sp_cparen_oparen = ignore # ignore/add/remove/force/not_defined -# Indent continued variable declarations instead of aligning. -indent_var_def_cont = false # false/true +# Whether to balance spaces inside nested parentheses. +sp_balance_nested_parens = false # true/false -# Indent continued shift expressions ('<<' and '>>') instead of aligning. -# Turn align_left_shift off when enabling this. -indent_shift = false # false/true +# Add or remove space between ')' and '{'. +sp_paren_brace = force # ignore/add/remove/force/not_defined -# True: force indentation of function definition to start in column 1 -# False: use the default behavior -indent_func_def_force_col1 = false # false/true +# Add or remove space between nested braces, i.e. '{{' vs. '{ {'. +sp_brace_brace = ignore # ignore/add/remove/force/not_defined -# True: indent continued function call parameters one indent level -# False: align parameters under the open paren -indent_func_call_param = false # false/true +# Add or remove space before pointer star '*'. +sp_before_ptr_star = force # ignore/add/remove/force/not_defined -# Same as indent_func_call_param, but for function defs -indent_func_def_param = false # false/true +# Add or remove space before pointer star '*' that isn't followed by a +# variable name. If set to ignore, sp_before_ptr_star is used instead. +sp_before_unnamed_ptr_star = ignore # ignore/add/remove/force/not_defined -# Same as indent_func_call_param, but for function protos -indent_func_proto_param = false # false/true +# Add or remove space before pointer star '*' that is followed by a qualifier. +# If set to ignore, sp_before_unnamed_ptr_star is used instead. +sp_before_qualifier_ptr_star = ignore # ignore/add/remove/force/not_defined -# Same as indent_func_call_param, but for class declarations -indent_func_class_param = false # false/true +# Add or remove space before pointer star '*' that is followed by 'operator' keyword. +# If set to ignore, sp_before_unnamed_ptr_star is used instead. +sp_before_operator_ptr_star = ignore # ignore/add/remove/force/not_defined -# Same as indent_func_call_param, but for class variable constructors -indent_func_ctor_var_param = false # false/true +# Add or remove space before pointer star '*' that is followed by +# a class scope (as in 'int *MyClass::method()') or namespace scope +# (as in 'int *my_ns::func()'). +# If set to ignore, sp_before_unnamed_ptr_star is used instead. +sp_before_scope_ptr_star = ignore # ignore/add/remove/force/not_defined -# Same as indent_func_call_param, but for templates -indent_template_param = false # false/true +# Add or remove space before pointer star '*' that is followed by '::', +# as in 'int *::func()'. +# If set to ignore, sp_before_unnamed_ptr_star is used instead. +sp_before_global_scope_ptr_star = ignore # ignore/add/remove/force/not_defined -# Double the indent for indent_func_xxx_param options -indent_func_param_double = false # false/true +# Add or remove space between a qualifier and a pointer star '*' that isn't +# followed by a variable name, as in '(char const *)'. If set to ignore, +# sp_before_ptr_star is used instead. +sp_qualifier_unnamed_ptr_star = ignore # ignore/add/remove/force/not_defined -# Indentation column for standalone 'const' function decl/proto qualifier -indent_func_const = 0 # number +# Add or remove space between pointer stars '*', as in 'int ***a;'. +sp_between_ptr_star = remove # ignore/add/remove/force/not_defined -# Indentation column for standalone 'throw' function decl/proto qualifier -indent_func_throw = 0 # number +# Add or remove space between pointer star '*' and reference '&', as in 'int *& a;'. +sp_between_ptr_ref = ignore # ignore/add/remove/force/not_defined -# The number of spaces to indent a continued '->' or '.' -# Usually set to 0, 1, or indent_columns. -indent_member = 0 # number +# Add or remove space after pointer star '*', if followed by a word. +# +# Overrides sp_type_func. +sp_after_ptr_star = ignore # ignore/add/remove/force/not_defined -# Spaces to indent single line ('//') comments on lines before code -indent_sing_line_comments = 0 # number +# Add or remove space after pointer caret '^', if followed by a word. +sp_after_ptr_block_caret = ignore # ignore/add/remove/force/not_defined -# If set, will indent trailing single line ('//') comments relative -# to the code instead of trying to keep the same absolute column -indent_relative_single_line_comments = false # false/true +# Add or remove space after pointer star '*', if followed by a qualifier. +sp_after_ptr_star_qualifier = ignore # ignore/add/remove/force/not_defined -# Spaces to indent 'case' from 'switch' -# Usually 0 or indent_columns. -indent_switch_case = 0 # number +# Add or remove space after a pointer star '*', if followed by a function +# prototype or function definition. +# +# Overrides sp_after_ptr_star and sp_type_func. +sp_after_ptr_star_func = ignore # ignore/add/remove/force/not_defined -# Spaces to shift the 'case' line, without affecting any other lines -# Usually 0. -indent_case_shift = 0 # number +# Add or remove space after a pointer star '*' in the trailing return of a +# function prototype or function definition. +sp_after_ptr_star_trailing = ignore # ignore/add/remove/force/not_defined -# Spaces to indent '{' from 'case'. -# By default, the brace will appear under the 'c' in case. -# Usually set to 0 or indent_columns. -indent_case_brace = 0 # number +# Add or remove space between the pointer star '*' and the name of the variable +# in a function pointer definition. +sp_ptr_star_func_var = ignore # ignore/add/remove/force/not_defined -# Whether to indent comments found in first column -indent_col1_comment = false # false/true +# Add or remove space between the pointer star '*' and the name of the type +# in a function pointer type definition. +sp_ptr_star_func_type = ignore # ignore/add/remove/force/not_defined -# How to indent goto labels -# >0: absolute column where 1 is the leftmost column -# <=0: subtract from brace indent -# Default=1 -indent_label = 1 # number +# Add or remove space after a pointer star '*', if followed by an open +# parenthesis, as in 'void* (*)()'. +sp_ptr_star_paren = ignore # ignore/add/remove/force/not_defined -# Same as indent_label, but for access specifiers that are followed by a colon. Default=1 -indent_access_spec = 1 # number +# Add or remove space before a pointer star '*', if followed by a function +# prototype or function definition. If set to ignore, sp_before_ptr_star is +# used instead. +sp_before_ptr_star_func = ignore # ignore/add/remove/force/not_defined -# Indent the code after an access specifier by one level. -# If set, this option forces 'indent_access_spec=0' -indent_access_spec_body = false # false/true +# Add or remove space between a qualifier and a pointer star '*' followed by +# the name of the function in a function prototype or definition, as in +# 'char const *foo()`. If set to ignore, sp_before_ptr_star is used instead. +sp_qualifier_ptr_star_func = ignore # ignore/add/remove/force/not_defined -# If an open paren is followed by a newline, indent the next line so that it lines up after the open paren (not recommended) -indent_paren_nl = false # false/true +# Add or remove space before a pointer star '*' in the trailing return of a +# function prototype or function definition. +sp_before_ptr_star_trailing = ignore # ignore/add/remove/force/not_defined -# Controls the indent of a close paren after a newline. -# 0: Indent to body level -# 1: Align under the open paren -# 2: Indent to the brace level -indent_paren_close = 2 # number +# Add or remove space between a qualifier and a pointer star '*' in the +# trailing return of a function prototype or function definition, as in +# 'auto foo() -> char const *'. +sp_qualifier_ptr_star_trailing = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before a reference sign '&'. +sp_before_byref = ignore # ignore/add/remove/force/not_defined + +# Add or remove space before a reference sign '&' that isn't followed by a +# variable name. If set to ignore, sp_before_byref is used instead. +sp_before_unnamed_byref = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after reference sign '&', if followed by a word. +# +# Overrides sp_type_func. +sp_after_byref = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after a reference sign '&', if followed by a function +# prototype or function definition. +# +# Overrides sp_after_byref and sp_type_func. +sp_after_byref_func = ignore # ignore/add/remove/force/not_defined -# Controls the indent of a comma when inside a paren.If TRUE, aligns under the open paren -indent_comma_paren = false # false/true +# Add or remove space before a reference sign '&', if followed by a function +# prototype or function definition. +sp_before_byref_func = ignore # ignore/add/remove/force/not_defined -# Controls the indent of a BOOL operator when inside a paren.If TRUE, aligns under the open paren -indent_bool_paren = false # false/true +# Add or remove space after a reference sign '&', if followed by an open +# parenthesis, as in 'char& (*)()'. +sp_byref_paren = ignore # ignore/add/remove/force/not_defined -# If 'indent_bool_paren' is true, controls the indent of the first expression. If TRUE, aligns the first expression to the following ones -indent_first_bool_expr = false # false/true +# Add or remove space between type and word. In cases where total removal of +# whitespace would be a syntax error, a value of 'remove' is treated the same +# as 'force'. +# +# This also affects some other instances of space following a type that are +# not covered by other options; for example, between the return type and +# parenthesis of a function type template argument, between the type and +# parenthesis of an array parameter, or between 'decltype(...)' and the +# following word. +# +# Default: force +sp_after_type = force # ignore/add/remove/force/not_defined -# If an open square is followed by a newline, indent the next line so that it lines up after the open square (not recommended) -indent_square_nl = false # false/true +# Add or remove space between 'decltype(...)' and word, +# brace or function call. +sp_after_decltype = ignore # ignore/add/remove/force/not_defined -# Don't change the relative indent of ESQL/C 'EXEC SQL' bodies -indent_preserve_sql = false # false/true +# (D) Add or remove space before the parenthesis in the D constructs +# 'template Foo(' and 'class Foo('. +sp_before_template_paren = ignore # ignore/add/remove/force/not_defined -# Align continued statements at the '='. Default=True -# If FALSE or the '=' is followed by a newline, the next line is indent one tab. -indent_align_assign = true # false/true +# Add or remove space between 'template' and '<'. +# If set to ignore, sp_before_angle is used. +sp_template_angle = ignore # ignore/add/remove/force/not_defined -# Indent OC blocks at brace level instead of usual rules. -indent_oc_block = false # false/true +# Add or remove space before '<'. +sp_before_angle = ignore # ignore/add/remove/force/not_defined -# Indent OC blocks in a message relative to the parameter name. -# 0=use indent_oc_block rules, 1+=spaces to indent -indent_oc_block_msg = 0 # number +# Add or remove space inside '<' and '>'. +sp_inside_angle = ignore # ignore/add/remove/force/not_defined -# Minimum indent for subsequent parameters -indent_oc_msg_colon = 0 # number +# Add or remove space inside '<>'. +# if empty. +sp_inside_angle_empty = ignore # ignore/add/remove/force/not_defined -# If true, prioritize aligning with initial colon (and stripping spaces from lines, if necessary). -# Default=True. -indent_oc_msg_prioritize_first_colon = true # false/true +# Add or remove space between '>' and ':'. +sp_angle_colon = ignore # ignore/add/remove/force/not_defined -# If indent_oc_block_msg and this option are on, blocks will be indented the way that Xcode does by default (from keyword if the parameter is on its own line; otherwise, from the previous indentation level). -indent_oc_block_msg_xcode_style = false # false/true +# Add or remove space after '>'. +sp_after_angle = ignore # ignore/add/remove/force/not_defined -# If indent_oc_block_msg and this option are on, blocks will be indented from where the brace is relative to a msg keyword. -indent_oc_block_msg_from_keyword = false # false/true +# Add or remove space between '>' and '(' as found in 'new List(foo);'. +sp_angle_paren = ignore # ignore/add/remove/force/not_defined -# If indent_oc_block_msg and this option are on, blocks will be indented from where the brace is relative to a msg colon. -indent_oc_block_msg_from_colon = false # false/true +# Add or remove space between '>' and '()' as found in 'new List();'. +sp_angle_paren_empty = ignore # ignore/add/remove/force/not_defined -# If indent_oc_block_msg and this option are on, blocks will be indented from where the block caret is. -indent_oc_block_msg_from_caret = false # false/true +# Add or remove space between '>' and a word as in 'List m;' or +# 'template static ...'. +sp_angle_word = ignore # ignore/add/remove/force/not_defined -# If indent_oc_block_msg and this option are on, blocks will be indented from where the brace is. -indent_oc_block_msg_from_brace = false # false/true +# Add or remove space between '>' and '>' in '>>' (template stuff). +# +# Default: add +sp_angle_shift = add # ignore/add/remove/force/not_defined -# When identing after virtual brace open and newline add further spaces to reach this min. indent. -indent_min_vbrace_open = 0 # number +# (C++11) Permit removal of the space between '>>' in 'foo >'. Note +# that sp_angle_shift cannot remove the space without this option. +sp_permit_cpp11_shift = false # true/false -# TRUE: When identing after virtual brace open and newline add further spaces after regular indent to reach next tabstop. -indent_vbrace_open_on_tabstop = false # false/true +# Add or remove space before '(' of control statements ('if', 'for', 'switch', +# 'while', etc.). +sp_before_sparen = add # ignore/add/remove/force/not_defined -# If true, a brace followed by another token (not a newline) will indent all contained lines to match the token.Default=True. -indent_token_after_brace = true # false/true +# Add or remove space inside '(' and ')' of control statements other than +# 'for'. +sp_inside_sparen = remove # ignore/add/remove/force/not_defined -# If true, cpp lambda body will be indentedDefault=False. -indent_cpp_lambda_body = false # false/true +# Add or remove space after '(' of control statements other than 'for'. +# +# Overrides sp_inside_sparen. +sp_inside_sparen_open = ignore # ignore/add/remove/force/not_defined +# Add or remove space before ')' of control statements other than 'for'. # -# Spacing options +# Overrides sp_inside_sparen. +sp_inside_sparen_close = ignore # ignore/add/remove/force/not_defined + +# Add or remove space inside '(' and ')' of 'for' statements. +sp_inside_for = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after '(' of 'for' statements. # +# Overrides sp_inside_for. +sp_inside_for_open = ignore # ignore/add/remove/force/not_defined -# Add or remove space around arithmetic operator '+', '-', '/', '*', etc -# also '>>>' '<<' '>>' '%' '|' -sp_arith = ignore # ignore/add/remove/force +# Add or remove space before ')' of 'for' statements. +# +# Overrides sp_inside_for. +sp_inside_for_close = ignore # ignore/add/remove/force/not_defined -# Add or remove space around assignment operator '=', '+=', etc -sp_assign = force # ignore/add/remove/force +# Add or remove space between '((' or '))' of control statements. +sp_sparen_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space around '=' in C++11 lambda capture specifications. Overrides sp_assign -sp_cpp_lambda_assign = ignore # ignore/add/remove/force +# Add or remove space after ')' of control statements. +sp_after_sparen = ignore # ignore/add/remove/force/not_defined -# Add or remove space after the capture specification in C++11 lambda. -sp_cpp_lambda_square_paren = ignore # ignore/add/remove/force +# Add or remove space between ')' and '{' of control statements. +sp_sparen_brace = add # ignore/add/remove/force/not_defined -# Add or remove space around assignment operator '=' in a prototype -sp_assign_default = ignore # ignore/add/remove/force +# Add or remove space between 'do' and '{'. +sp_do_brace_open = ignore # ignore/add/remove/force/not_defined -# Add or remove space before assignment operator '=', '+=', etc. Overrides sp_assign. -sp_before_assign = ignore # ignore/add/remove/force +# Add or remove space between '}' and 'while'. +sp_brace_close_while = ignore # ignore/add/remove/force/not_defined -# Add or remove space after assignment operator '=', '+=', etc. Overrides sp_assign. -sp_after_assign = ignore # ignore/add/remove/force +# Add or remove space between 'while' and '('. Overrides sp_before_sparen. +sp_while_paren_open = ignore # ignore/add/remove/force/not_defined -# Add or remove space in 'NS_ENUM (' -sp_enum_paren = ignore # ignore/add/remove/force +# (D) Add or remove space between 'invariant' and '('. +sp_invariant_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space around assignment '=' in enum -sp_enum_assign = ignore # ignore/add/remove/force +# (D) Add or remove space after the ')' in 'invariant (C) c'. +sp_after_invariant_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space before assignment '=' in enum. Overrides sp_enum_assign. -sp_enum_before_assign = ignore # ignore/add/remove/force +# Add or remove space before empty statement ';' on 'if', 'for' and 'while'. +sp_special_semi = ignore # ignore/add/remove/force/not_defined -# Add or remove space after assignment '=' in enum. Overrides sp_enum_assign. -sp_enum_after_assign = ignore # ignore/add/remove/force +# Add or remove space before ';'. +# +# Default: remove +sp_before_semi = remove # ignore/add/remove/force/not_defined -# Add or remove space around preprocessor '##' concatenation operator. Default=Add -sp_pp_concat = add # ignore/add/remove/force +# Add or remove space before ';' in non-empty 'for' statements. +sp_before_semi_for = ignore # ignore/add/remove/force/not_defined -# Add or remove space after preprocessor '#' stringify operator. Also affects the '#@' charizing operator. -sp_pp_stringify = ignore # ignore/add/remove/force +# Add or remove space before a semicolon of an empty left part of a for +# statement, as in 'for ( ; ; )'. +sp_before_semi_for_empty = ignore # ignore/add/remove/force/not_defined -# Add or remove space before preprocessor '#' stringify operator as in '#define x(y) L#y'. -sp_before_pp_stringify = ignore # ignore/add/remove/force +# Add or remove space between the semicolons of an empty middle part of a for +# statement, as in 'for ( ; ; )'. +sp_between_semi_for_empty = ignore # ignore/add/remove/force/not_defined -# Add or remove space around boolean operators '&&' and '||' -sp_bool = force # ignore/add/remove/force +# Add or remove space after ';', except when followed by a comment. +# +# Default: add +sp_after_semi = add # ignore/add/remove/force/not_defined -# Add or remove space around compare operator '<', '>', '==', etc -sp_compare = force # ignore/add/remove/force +# Add or remove space after ';' in non-empty 'for' statements. +# +# Default: force +sp_after_semi_for = force # ignore/add/remove/force/not_defined -# Add or remove space inside '(' and ')' -sp_inside_paren = remove # ignore/add/remove/force +# Add or remove space after the final semicolon of an empty part of a for +# statement, as in 'for ( ; ; )'. +sp_after_semi_for_empty = remove # ignore/add/remove/force/not_defined -# Add or remove space between nested parens: '((' vs ') )' -sp_paren_paren = remove # ignore/add/remove/force +# Add or remove space before '[' (except '[]'). +sp_before_square = ignore # ignore/add/remove/force/not_defined -# Add or remove space between back-to-back parens: ')(' vs ') (' -sp_cparen_oparen = ignore # ignore/add/remove/force +# Add or remove space before '[' for a variable definition. +# +# Default: remove +sp_before_vardef_square = remove # ignore/add/remove/force/not_defined -# Whether to balance spaces inside nested parens -sp_balance_nested_parens = false # false/true +# Add or remove space before '[' for asm block. +sp_before_square_asm_block = ignore # ignore/add/remove/force/not_defined -# Add or remove space between ')' and '{' -sp_paren_brace = force # ignore/add/remove/force +# Add or remove space before '[]'. +sp_before_squares = ignore # ignore/add/remove/force/not_defined -# Add or remove space before pointer star '*' -sp_before_ptr_star = force # ignore/add/remove/force +# Add or remove space before C++17 structured bindings. +sp_cpp_before_struct_binding = ignore # ignore/add/remove/force/not_defined -# Add or remove space before pointer star '*' that isn't followed by a variable name -# If set to 'ignore', sp_before_ptr_star is used instead. -sp_before_unnamed_ptr_star = ignore # ignore/add/remove/force +# Add or remove space inside a non-empty '[' and ']'. +sp_inside_square = ignore # ignore/add/remove/force/not_defined -# Add or remove space between pointer stars '*' -sp_between_ptr_star = remove # ignore/add/remove/force +# Add or remove space inside '[]'. +# if empty. +sp_inside_square_empty = ignore # ignore/add/remove/force/not_defined -# Add or remove space after pointer star '*', if followed by a word. -sp_after_ptr_star = ignore # ignore/add/remove/force +# (OC) Add or remove space inside a non-empty Objective-C boxed array '@[' and +# ']'. If set to ignore, sp_inside_square is used. +sp_inside_square_oc_array = ignore # ignore/add/remove/force/not_defined -# Add or remove space after pointer star '*', if followed by a qualifier. -sp_after_ptr_star_qualifier = ignore # ignore/add/remove/force +# Add or remove space after ',', i.e. 'a,b' vs. 'a, b'. +sp_after_comma = force # ignore/add/remove/force/not_defined -# Add or remove space after a pointer star '*', if followed by a func proto/def. -sp_after_ptr_star_func = ignore # ignore/add/remove/force +# Add or remove space before ',', i.e. 'a,b' vs. 'a ,b'. +# +# Default: remove +sp_before_comma = remove # ignore/add/remove/force/not_defined -# Add or remove space after a pointer star '*', if followed by an open paren (function types). -sp_ptr_star_paren = ignore # ignore/add/remove/force +# (C#, Vala) Add or remove space between ',' and ']' in multidimensional array type +# like 'int[,,]'. +sp_after_mdatype_commas = ignore # ignore/add/remove/force/not_defined -# Add or remove space before a pointer star '*', if followed by a func proto/def. -sp_before_ptr_star_func = ignore # ignore/add/remove/force +# (C#, Vala) Add or remove space between '[' and ',' in multidimensional array type +# like 'int[,,]'. +sp_before_mdatype_commas = ignore # ignore/add/remove/force/not_defined -# Add or remove space before a reference sign '&' -sp_before_byref = ignore # ignore/add/remove/force +# (C#, Vala) Add or remove space between ',' in multidimensional array type +# like 'int[,,]'. +sp_between_mdatype_commas = ignore # ignore/add/remove/force/not_defined -# Add or remove space before a reference sign '&' that isn't followed by a variable name -# If set to 'ignore', sp_before_byref is used instead. -sp_before_unnamed_byref = ignore # ignore/add/remove/force +# Add or remove space between an open parenthesis and comma, +# i.e. '(,' vs. '( ,'. +# +# Default: force +sp_paren_comma = force # ignore/add/remove/force/not_defined -# Add or remove space after reference sign '&', if followed by a word. -sp_after_byref = ignore # ignore/add/remove/force +# Add or remove space between a type and ':'. +sp_type_colon = ignore # ignore/add/remove/force/not_defined -# Add or remove space after a reference sign '&', if followed by a func proto/def. -sp_after_byref_func = ignore # ignore/add/remove/force +# Add or remove space after the variadic '...' when preceded by a +# non-punctuator. +# The value REMOVE will be overridden with FORCE +sp_after_ellipsis = ignore # ignore/add/remove/force/not_defined -# Add or remove space before a reference sign '&', if followed by a func proto/def. -sp_before_byref_func = ignore # ignore/add/remove/force +# Add or remove space before the variadic '...' when preceded by a +# non-punctuator. +# The value REMOVE will be overridden with FORCE +sp_before_ellipsis = ignore # ignore/add/remove/force/not_defined -# Add or remove space between type and word. Default=Force -sp_after_type = force # ignore/add/remove/force +# Add or remove space between a type and '...'. +sp_type_ellipsis = ignore # ignore/add/remove/force/not_defined -# Add or remove space before the paren in the D constructs 'template Foo(' and 'class Foo('. -sp_before_template_paren = ignore # ignore/add/remove/force +# Add or remove space between a '*' and '...'. +sp_ptr_type_ellipsis = ignore # ignore/add/remove/force/not_defined -# Add or remove space in 'template <' vs 'template<'. -# If set to ignore, sp_before_angle is used. -sp_template_angle = ignore # ignore/add/remove/force +# Add or remove space between ')' and '...'. +sp_paren_ellipsis = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between '&&' and '...'. +sp_byref_ellipsis = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between ')' and a qualifier such as 'const'. +sp_paren_qualifier = ignore # ignore/add/remove/force/not_defined + +# Add or remove space between ')' and 'noexcept'. +sp_paren_noexcept = ignore # ignore/add/remove/force/not_defined + +# Add or remove space after class ':'. +sp_after_class_colon = ignore # ignore/add/remove/force/not_defined -# Add or remove space before '<>' -sp_before_angle = ignore # ignore/add/remove/force +# Add or remove space before class ':'. +sp_before_class_colon = ignore # ignore/add/remove/force/not_defined -# Add or remove space inside '<' and '>' -sp_inside_angle = ignore # ignore/add/remove/force +# Add or remove space after class constructor ':'. +# +# Default: add +sp_after_constr_colon = ignore # ignore/add/remove/force/not_defined -# Add or remove space after '<>' -sp_after_angle = ignore # ignore/add/remove/force +# Add or remove space before class constructor ':'. +# +# Default: add +sp_before_constr_colon = ignore # ignore/add/remove/force/not_defined -# Add or remove space between '<>' and '(' as found in 'new List(foo);' -sp_angle_paren = ignore # ignore/add/remove/force +# Add or remove space before case ':'. +# +# Default: remove +sp_before_case_colon = remove # ignore/add/remove/force/not_defined -# Add or remove space between '<>' and '()' as found in 'new List();' -sp_angle_paren_empty = ignore # ignore/add/remove/force +# Add or remove space between 'operator' and operator sign. +sp_after_operator = ignore # ignore/add/remove/force/not_defined -# Add or remove space between '<>' and a word as in 'List m;' or 'template static ...' -sp_angle_word = ignore # ignore/add/remove/force +# Add or remove space between the operator symbol and the open parenthesis, as +# in 'operator ++('. +sp_after_operator_sym = ignore # ignore/add/remove/force/not_defined -# Add or remove space between '>' and '>' in '>>' (template stuff C++/C# only). Default=Add -sp_angle_shift = add # ignore/add/remove/force +# Overrides sp_after_operator_sym when the operator has no arguments, as in +# 'operator *()'. +sp_after_operator_sym_empty = ignore # ignore/add/remove/force/not_defined -# Permit removal of the space between '>>' in 'foo >' (C++11 only). Default=False -# sp_angle_shift cannot remove the space without this option. -sp_permit_cpp11_shift = false # false/true +# Add or remove space after C/D cast, i.e. 'cast(int)a' vs. 'cast(int) a' or +# '(int)a' vs. '(int) a'. +sp_after_cast = ignore # ignore/add/remove/force/not_defined -# Add or remove space before '(' of 'if', 'for', 'switch', 'while', etc. -sp_before_sparen = add # ignore/add/remove/force +# Add or remove spaces inside cast parentheses. +sp_inside_paren_cast = ignore # ignore/add/remove/force/not_defined -# Add or remove space inside if-condition '(' and ')' -sp_inside_sparen = remove # ignore/add/remove/force +# Add or remove space between the type and open parenthesis in a C++ cast, +# i.e. 'int(exp)' vs. 'int (exp)'. +sp_cpp_cast_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space before if-condition ')'. Overrides sp_inside_sparen. -sp_inside_sparen_close = ignore # ignore/add/remove/force +# Add or remove space between 'sizeof' and '('. +sp_sizeof_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space after if-condition '('. Overrides sp_inside_sparen. -sp_inside_sparen_open = ignore # ignore/add/remove/force +# Add or remove space between 'sizeof' and '...'. +sp_sizeof_ellipsis = ignore # ignore/add/remove/force/not_defined -# Add or remove space after ')' of 'if', 'for', 'switch', and 'while', etc. -sp_after_sparen = ignore # ignore/add/remove/force +# Add or remove space between 'sizeof...' and '('. +sp_sizeof_ellipsis_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space between ')' and '{' of 'if', 'for', 'switch', and 'while', etc. -sp_sparen_brace = add # ignore/add/remove/force +# Add or remove space between '...' and a parameter pack. +sp_ellipsis_parameter_pack = ignore # ignore/add/remove/force/not_defined -# Add or remove space between 'invariant' and '(' in the D language. -sp_invariant_paren = ignore # ignore/add/remove/force +# Add or remove space between a parameter pack and '...'. +sp_parameter_pack_ellipsis = ignore # ignore/add/remove/force/not_defined -# Add or remove space after the ')' in 'invariant (C) c' in the D language. -sp_after_invariant_paren = ignore # ignore/add/remove/force +# Add or remove space between 'decltype' and '('. +sp_decltype_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space before empty statement ';' on 'if', 'for' and 'while' -sp_special_semi = ignore # ignore/add/remove/force +# (Pawn) Add or remove space after the tag keyword. +sp_after_tag = ignore # ignore/add/remove/force/not_defined -# Add or remove space before ';'. Default=Remove -sp_before_semi = remove # ignore/add/remove/force +# Add or remove space inside enum '{' and '}'. +sp_inside_braces_enum = ignore # ignore/add/remove/force/not_defined -# Add or remove space before ';' in non-empty 'for' statements -sp_before_semi_for = ignore # ignore/add/remove/force +# Add or remove space inside struct/union '{' and '}'. +sp_inside_braces_struct = ignore # ignore/add/remove/force/not_defined -# Add or remove space before a semicolon of an empty part of a for statement. -sp_before_semi_for_empty = ignore # ignore/add/remove/force +# (OC) Add or remove space inside Objective-C boxed dictionary '{' and '}' +sp_inside_braces_oc_dict = ignore # ignore/add/remove/force/not_defined -# Add or remove space after ';', except when followed by a comment. Default=Add -sp_after_semi = add # ignore/add/remove/force +# Add or remove space after open brace in an unnamed temporary +# direct-list-initialization +# if statement is a brace_init_lst +# works only if sp_brace_brace is set to ignore. +sp_after_type_brace_init_lst_open = ignore # ignore/add/remove/force/not_defined -# Add or remove space after ';' in non-empty 'for' statements. Default=Force -sp_after_semi_for = force # ignore/add/remove/force +# Add or remove space before close brace in an unnamed temporary +# direct-list-initialization +# if statement is a brace_init_lst +# works only if sp_brace_brace is set to ignore. +sp_before_type_brace_init_lst_close = ignore # ignore/add/remove/force/not_defined -# Add or remove space after the final semicolon of an empty part of a for statement: for ( ; ; ). -sp_after_semi_for_empty = remove # ignore/add/remove/force +# Add or remove space inside an unnamed temporary direct-list-initialization +# if statement is a brace_init_lst +# works only if sp_brace_brace is set to ignore +# works only if sp_before_type_brace_init_lst_close is set to ignore. +sp_inside_type_brace_init_lst = ignore # ignore/add/remove/force/not_defined -# Add or remove space before '[' (except '[]') -sp_before_square = ignore # ignore/add/remove/force +# Add or remove space inside '{' and '}'. +sp_inside_braces = ignore # ignore/add/remove/force/not_defined -# Add or remove space before '[]' -sp_before_squares = ignore # ignore/add/remove/force +# Add or remove space inside '{}'. +# if empty. +sp_inside_braces_empty = ignore # ignore/add/remove/force/not_defined -# Add or remove space inside a non-empty '[' and ']' -sp_inside_square = ignore # ignore/add/remove/force +# Add or remove space around trailing return operator '->'. +sp_trailing_return = ignore # ignore/add/remove/force/not_defined -# Add or remove space after ',' -sp_after_comma = ignore # ignore/add/remove/force +# Add or remove space between return type and function name. A minimum of 1 +# is forced except for pointer return types. +sp_type_func = ignore # ignore/add/remove/force/not_defined -# Add or remove space before ','. Default=Remove -sp_before_comma = remove # ignore/add/remove/force +# Add or remove space between type and open brace of an unnamed temporary +# direct-list-initialization. +sp_type_brace_init_lst = ignore # ignore/add/remove/force/not_defined -# Add or remove space between ',' and ']' in multidimensional array type 'int[,,]' -sp_after_mdatype_commas = ignore # ignore/add/remove/force +# Add or remove space between function name and '(' on function declaration. +sp_func_proto_paren = remove # ignore/add/remove/force/not_defined -# Add or remove space between '[' and ',' in multidimensional array type 'int[,,]' -sp_before_mdatype_commas = ignore # ignore/add/remove/force +# Add or remove space between function name and '()' on function declaration +# if empty. +sp_func_proto_paren_empty = remove # ignore/add/remove/force/not_defined -# Add or remove space between ',' in multidimensional array type 'int[,,]' -sp_between_mdatype_commas = ignore # ignore/add/remove/force +# Add or remove space between function name and '(' with a typedef specifier. +sp_func_type_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space between an open paren and comma: '(,' vs '( ,'. Default=Force -sp_paren_comma = force # ignore/add/remove/force +# Add or remove space between alias name and '(' of a non-pointer function type typedef. +sp_func_def_paren = remove # ignore/add/remove/force/not_defined -# Add or remove space before the variadic '...' when preceded by a non-punctuator -sp_before_ellipsis = ignore # ignore/add/remove/force +# Add or remove space between function name and '()' on function definition +# if empty. +sp_func_def_paren_empty = ignore # ignore/add/remove/force/not_defined -# Add or remove space after class ':' -sp_after_class_colon = ignore # ignore/add/remove/force +# Add or remove space inside empty function '()'. +# Overrides sp_after_angle unless use_sp_after_angle_always is set to true. +sp_inside_fparens = ignore # ignore/add/remove/force/not_defined -# Add or remove space before class ':' -sp_before_class_colon = ignore # ignore/add/remove/force +# Add or remove space inside function '(' and ')'. +sp_inside_fparen = remove # ignore/add/remove/force/not_defined -# Add or remove space after class constructor ':' -sp_after_constr_colon = ignore # ignore/add/remove/force +# Add or remove space inside user functor '(' and ')'. +sp_func_call_user_inside_rparen = ignore # ignore/add/remove/force/not_defined -# Add or remove space before class constructor ':' -sp_before_constr_colon = ignore # ignore/add/remove/force +# Add or remove space inside empty functor '()'. +# Overrides sp_after_angle unless use_sp_after_angle_always is set to true. +sp_inside_rparens = ignore # ignore/add/remove/force/not_defined -# Add or remove space before case ':'. Default=Remove -sp_before_case_colon = remove # ignore/add/remove/force +# Add or remove space inside functor '(' and ')'. +sp_inside_rparen = ignore # ignore/add/remove/force/not_defined -# Add or remove space between 'operator' and operator sign -sp_after_operator = ignore # ignore/add/remove/force +# Add or remove space inside the first parentheses in a function type, as in +# 'void (*x)(...)'. +sp_inside_tparen = ignore # ignore/add/remove/force/not_defined -# Add or remove space between the operator symbol and the open paren, as in 'operator ++(' -sp_after_operator_sym = ignore # ignore/add/remove/force +# Add or remove space between the ')' and '(' in a function type, as in +# 'void (*x)(...)'. +sp_after_tparen_close = ignore # ignore/add/remove/force/not_defined -# Add or remove space between the operator symbol and the open paren when the operator has no arguments, as in 'operator *()' -sp_after_operator_sym_empty = ignore # ignore/add/remove/force +# Add or remove space between ']' and '(' when part of a function call. +sp_square_fparen = ignore # ignore/add/remove/force/not_defined -# Add or remove space after C/D cast, i.e. 'cast(int)a' vs 'cast(int) a' or '(int)a' vs '(int) a' -sp_after_cast = ignore # ignore/add/remove/force +# Add or remove space between ')' and '{' of function. +sp_fparen_brace = add # ignore/add/remove/force/not_defined -# Add or remove spaces inside cast parens -sp_inside_paren_cast = ignore # ignore/add/remove/force +# Add or remove space between ')' and '{' of a function call in object +# initialization. +# +# Overrides sp_fparen_brace. +sp_fparen_brace_initializer = ignore # ignore/add/remove/force/not_defined -# Add or remove space between the type and open paren in a C++ cast, i.e. 'int(exp)' vs 'int (exp)' -sp_cpp_cast_paren = ignore # ignore/add/remove/force +# (Java) Add or remove space between ')' and '{{' of double brace initializer. +sp_fparen_dbrace = ignore # ignore/add/remove/force/not_defined -# Add or remove space between 'sizeof' and '(' -sp_sizeof_paren = ignore # ignore/add/remove/force +# Add or remove space between function name and '(' on function calls. +sp_func_call_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space after the tag keyword (Pawn) -sp_after_tag = ignore # ignore/add/remove/force +# Add or remove space between function name and '()' on function calls without +# parameters. If set to ignore (the default), sp_func_call_paren is used. +sp_func_call_paren_empty = ignore # ignore/add/remove/force/not_defined -# Add or remove space inside enum '{' and '}' -sp_inside_braces_enum = ignore # ignore/add/remove/force +# Add or remove space between the user function name and '(' on function +# calls. You need to set a keyword to be a user function in the config file, +# like: +# set func_call_user tr _ i18n +sp_func_call_user_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space inside struct/union '{' and '}' -sp_inside_braces_struct = ignore # ignore/add/remove/force +# Add or remove space inside user function '(' and ')'. +sp_func_call_user_inside_fparen = ignore # ignore/add/remove/force/not_defined -# Add or remove space inside '{' and '}' -sp_inside_braces = ignore # ignore/add/remove/force +# Add or remove space between nested parentheses with user functions, +# i.e. '((' vs. '( ('. +sp_func_call_user_paren_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space inside '{}' -sp_inside_braces_empty = ignore # ignore/add/remove/force +# Add or remove space between a constructor/destructor and the open +# parenthesis. +sp_func_class_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space between return type and function name -# A minimum of 1 is forced except for pointer return types. -sp_type_func = ignore # ignore/add/remove/force +# Add or remove space between a constructor without parameters or destructor +# and '()'. +sp_func_class_paren_empty = ignore # ignore/add/remove/force/not_defined -# Add or remove space between function name and '(' on function declaration -sp_func_proto_paren = remove # ignore/add/remove/force +# Add or remove space after 'return'. +# +# Default: force +sp_return = force # ignore/add/remove/force/not_defined -# Add or remove space between function name and '()' on function declaration without parameters -sp_func_proto_paren_empty = remove # ignore/add/remove/force +# Add or remove space between 'return' and '('. +sp_return_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space between function name and '(' on function definition -sp_func_def_paren = remove # ignore/add/remove/force +# Add or remove space between 'return' and '{'. +sp_return_brace = ignore # ignore/add/remove/force/not_defined -# Add or remove space between function name and '()' on function definition without parameters -sp_func_def_paren_empty = ignore # ignore/add/remove/force +# Add or remove space between '__attribute__' and '('. +sp_attribute_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space inside empty function '()' -sp_inside_fparens = ignore # ignore/add/remove/force +# Add or remove space between 'defined' and '(' in '#if defined (FOO)'. +sp_defined_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space inside function '(' and ')' -sp_inside_fparen = remove # ignore/add/remove/force +# Add or remove space between 'throw' and '(' in 'throw (something)'. +sp_throw_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space inside the first parens in the function type: 'void (*x)(...)' -sp_inside_tparen = ignore # ignore/add/remove/force +# Add or remove space between 'throw' and anything other than '(' as in +# '@throw [...];'. +sp_after_throw = ignore # ignore/add/remove/force/not_defined -# Add or remove between the parens in the function type: 'void (*x)(...)' -sp_after_tparen_close = ignore # ignore/add/remove/force +# Add or remove space between 'catch' and '(' in 'catch (something) { }'. +# If set to ignore, sp_before_sparen is used. +sp_catch_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space between ']' and '(' when part of a function call. -sp_square_fparen = ignore # ignore/add/remove/force +# (OC) Add or remove space between '@catch' and '(' +# in '@catch (something) { }'. If set to ignore, sp_catch_paren is used. +sp_oc_catch_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space between ')' and '{' of function -sp_fparen_brace = add # ignore/add/remove/force +# (OC) Add or remove space before Objective-C protocol list +# as in '@protocol Protocol' or '@interface MyClass : NSObject'. +sp_before_oc_proto_list = ignore # ignore/add/remove/force/not_defined -# Java: Add or remove space between ')' and '{{' of double brace initializer. -sp_fparen_dbrace = ignore # ignore/add/remove/force +# (OC) Add or remove space between class name and '(' +# in '@interface className(categoryName):BaseClass' +sp_oc_classname_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space between function name and '(' on function calls -sp_func_call_paren = ignore # ignore/add/remove/force +# (D) Add or remove space between 'version' and '(' +# in 'version (something) { }'. If set to ignore, sp_before_sparen is used. +sp_version_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space between function name and '()' on function calls without parameters. -# If set to 'ignore' (the default), sp_func_call_paren is used. -sp_func_call_paren_empty = ignore # ignore/add/remove/force +# (D) Add or remove space between 'scope' and '(' +# in 'scope (something) { }'. If set to ignore, sp_before_sparen is used. +sp_scope_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space between the user function name and '(' on function calls -# You need to set a keyword to be a user function, like this: 'set func_call_user _' in the config file. -sp_func_call_user_paren = ignore # ignore/add/remove/force +# Add or remove space between 'super' and '(' in 'super (something)'. +# +# Default: remove +sp_super_paren = remove # ignore/add/remove/force/not_defined -# Add or remove space between a constructor/destructor and the open paren -sp_func_class_paren = ignore # ignore/add/remove/force +# Add or remove space between 'this' and '(' in 'this (something)'. +# +# Default: remove +sp_this_paren = remove # ignore/add/remove/force/not_defined -# Add or remove space between a constructor without parameters or destructor and '()' -sp_func_class_paren_empty = ignore # ignore/add/remove/force +# Add or remove space between a macro name and its definition. +sp_macro = ignore # ignore/add/remove/force/not_defined -# Add or remove space between 'return' and '(' -sp_return_paren = ignore # ignore/add/remove/force +# Add or remove space between a macro function ')' and its definition. +sp_macro_func = ignore # ignore/add/remove/force/not_defined -# Add or remove space between '__attribute__' and '(' -sp_attribute_paren = ignore # ignore/add/remove/force +# Add or remove space between 'else' and '{' if on the same line. +sp_else_brace = add # ignore/add/remove/force/not_defined -# Add or remove space between 'defined' and '(' in '#if defined (FOO)' -sp_defined_paren = ignore # ignore/add/remove/force +# Add or remove space between '}' and 'else' if on the same line. +sp_brace_else = add # ignore/add/remove/force/not_defined -# Add or remove space between 'throw' and '(' in 'throw (something)' -sp_throw_paren = ignore # ignore/add/remove/force +# Add or remove space between '}' and the name of a typedef on the same line. +sp_brace_typedef = add # ignore/add/remove/force/not_defined -# Add or remove space between 'throw' and anything other than '(' as in '@throw [...];' -sp_after_throw = ignore # ignore/add/remove/force +# Add or remove space before the '{' of a 'catch' statement, if the '{' and +# 'catch' are on the same line, as in 'catch (decl) {'. +sp_catch_brace = ignore # ignore/add/remove/force/not_defined -# Add or remove space between 'catch' and '(' in 'catch (something) { }' -# If set to ignore, sp_before_sparen is used. -sp_catch_paren = ignore # ignore/add/remove/force +# (OC) Add or remove space before the '{' of a '@catch' statement, if the '{' +# and '@catch' are on the same line, as in '@catch (decl) {'. +# If set to ignore, sp_catch_brace is used. +sp_oc_catch_brace = ignore # ignore/add/remove/force/not_defined -# Add or remove space between 'version' and '(' in 'version (something) { }' (D language) -# If set to ignore, sp_before_sparen is used. -sp_version_paren = ignore # ignore/add/remove/force +# Add or remove space between '}' and 'catch' if on the same line. +sp_brace_catch = ignore # ignore/add/remove/force/not_defined -# Add or remove space between 'scope' and '(' in 'scope (something) { }' (D language) -# If set to ignore, sp_before_sparen is used. -sp_scope_paren = ignore # ignore/add/remove/force +# (OC) Add or remove space between '}' and '@catch' if on the same line. +# If set to ignore, sp_brace_catch is used. +sp_oc_brace_catch = ignore # ignore/add/remove/force/not_defined -# Add or remove space between 'super' and '(' in 'super (something)'. Default=Remove -sp_super_paren = remove # ignore/add/remove/force +# Add or remove space between 'finally' and '{' if on the same line. +sp_finally_brace = ignore # ignore/add/remove/force/not_defined -# Add or remove space between 'this' and '(' in 'this (something)'. Default=Remove -sp_this_paren = remove # ignore/add/remove/force +# Add or remove space between '}' and 'finally' if on the same line. +sp_brace_finally = ignore # ignore/add/remove/force/not_defined -# Add or remove space between macro and value -sp_macro = ignore # ignore/add/remove/force +# Add or remove space between 'try' and '{' if on the same line. +sp_try_brace = ignore # ignore/add/remove/force/not_defined -# Add or remove space between macro function ')' and value -sp_macro_func = ignore # ignore/add/remove/force +# Add or remove space between get/set and '{' if on the same line. +sp_getset_brace = ignore # ignore/add/remove/force/not_defined -# Add or remove space between 'else' and '{' if on the same line -sp_else_brace = add # ignore/add/remove/force +# Add or remove space between a variable and '{' for C++ uniform +# initialization. +sp_word_brace_init_lst = add # ignore/add/remove/force/not_defined -# Add or remove space between '}' and 'else' if on the same line -sp_brace_else = add # ignore/add/remove/force +# Add or remove space between a variable and '{' for a namespace. +# +# Default: add +sp_word_brace_ns = add # ignore/add/remove/force/not_defined -# Add or remove space between '}' and the name of a typedef on the same line -sp_brace_typedef = add # ignore/add/remove/force +# Add or remove space before the '::' operator. +sp_before_dc = ignore # ignore/add/remove/force/not_defined -# Add or remove space between 'catch' and '{' if on the same line -sp_catch_brace = ignore # ignore/add/remove/force +# Add or remove space after the '::' operator. +sp_after_dc = ignore # ignore/add/remove/force/not_defined -# Add or remove space between '}' and 'catch' if on the same line -sp_brace_catch = ignore # ignore/add/remove/force +# (D) Add or remove around the D named array initializer ':' operator. +sp_d_array_colon = ignore # ignore/add/remove/force/not_defined -# Add or remove space between 'finally' and '{' if on the same line -sp_finally_brace = ignore # ignore/add/remove/force +# Add or remove space after the '!' (not) unary operator. +# +# Default: remove +sp_not = remove # ignore/add/remove/force/not_defined -# Add or remove space between '}' and 'finally' if on the same line -sp_brace_finally = ignore # ignore/add/remove/force +# Add or remove space between two '!' (not) unary operators. +# If set to ignore, sp_not will be used. +sp_not_not = ignore # ignore/add/remove/force/not_defined -# Add or remove space between 'try' and '{' if on the same line -sp_try_brace = ignore # ignore/add/remove/force +# Add or remove space after the '~' (invert) unary operator. +# +# Default: remove +sp_inv = remove # ignore/add/remove/force/not_defined -# Add or remove space between get/set and '{' if on the same line -sp_getset_brace = ignore # ignore/add/remove/force +# Add or remove space after the '&' (address-of) unary operator. This does not +# affect the spacing after a '&' that is part of a type. +# +# Default: remove +sp_addr = remove # ignore/add/remove/force/not_defined -# Add or remove space between a variable and '{' for C++ uniform initialization. Default=Add -sp_word_brace_init_lst = add # ignore/add/remove/force +# Add or remove space around the '.' or '->' operators. +# +# Default: remove +sp_member = remove # ignore/add/remove/force/not_defined -# Add or remove space between a variable and '{' for a namespace. Default=Add -sp_word_brace_ns = add # ignore/add/remove/force +# Add or remove space after the '*' (dereference) unary operator. This does +# not affect the spacing after a '*' that is part of a type. +# +# Default: remove +sp_deref = remove # ignore/add/remove/force/not_defined -# Add or remove space before the '::' operator -sp_before_dc = ignore # ignore/add/remove/force +# Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. +# +# Default: remove +sp_sign = remove # ignore/add/remove/force/not_defined -# Add or remove space after the '::' operator -sp_after_dc = ignore # ignore/add/remove/force +# Add or remove space between '++' and '--' the word to which it is being +# applied, as in '(--x)' or 'y++;'. +# +# Default: remove +sp_incdec = remove # ignore/add/remove/force/not_defined -# Add or remove around the D named array initializer ':' operator -sp_d_array_colon = ignore # ignore/add/remove/force +# Add or remove space before a backslash-newline at the end of a line. +# +# Default: add +sp_before_nl_cont = add # ignore/add/remove/force/not_defined -# Add or remove space after the '!' (not) operator. Default=Remove -sp_not = remove # ignore/add/remove/force +# (OC) Add or remove space after the scope '+' or '-', as in '-(void) foo;' +# or '+(int) bar;'. +sp_after_oc_scope = ignore # ignore/add/remove/force/not_defined -# Add or remove space after the '~' (invert) operator. Default=Remove -sp_inv = remove # ignore/add/remove/force +# (OC) Add or remove space after the colon in message specs, +# i.e. '-(int) f:(int) x;' vs. '-(int) f: (int) x;'. +sp_after_oc_colon = ignore # ignore/add/remove/force/not_defined -# Add or remove space after the '&' (address-of) operator. Default=Remove -# This does not affect the spacing after a '&' that is part of a type. -sp_addr = remove # ignore/add/remove/force +# (OC) Add or remove space before the colon in message specs, +# i.e. '-(int) f: (int) x;' vs. '-(int) f : (int) x;'. +sp_before_oc_colon = ignore # ignore/add/remove/force/not_defined -# Add or remove space around the '.' or '->' operators. Default=Remove -sp_member = remove # ignore/add/remove/force +# (OC) Add or remove space after the colon in immutable dictionary expression +# 'NSDictionary *test = @{@"foo" :@"bar"};'. +sp_after_oc_dict_colon = ignore # ignore/add/remove/force/not_defined -# Add or remove space after the '*' (dereference) operator. Default=Remove -# This does not affect the spacing after a '*' that is part of a type. -sp_deref = remove # ignore/add/remove/force +# (OC) Add or remove space before the colon in immutable dictionary expression +# 'NSDictionary *test = @{@"foo" :@"bar"};'. +sp_before_oc_dict_colon = ignore # ignore/add/remove/force/not_defined -# Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. Default=Remove -sp_sign = remove # ignore/add/remove/force +# (OC) Add or remove space after the colon in message specs, +# i.e. '[object setValue:1];' vs. '[object setValue: 1];'. +sp_after_send_oc_colon = ignore # ignore/add/remove/force/not_defined -# Add or remove space before or after '++' and '--', as in '(--x)' or 'y++;'. Default=Remove -sp_incdec = remove # ignore/add/remove/force +# (OC) Add or remove space before the colon in message specs, +# i.e. '[object setValue:1];' vs. '[object setValue :1];'. +sp_before_send_oc_colon = ignore # ignore/add/remove/force/not_defined -# Add or remove space before a backslash-newline at the end of a line. Default=Add -sp_before_nl_cont = add # ignore/add/remove/force +# (OC) Add or remove space after the (type) in message specs, +# i.e. '-(int)f: (int) x;' vs. '-(int)f: (int)x;'. +sp_after_oc_type = ignore # ignore/add/remove/force/not_defined -# Add or remove space after the scope '+' or '-', as in '-(void) foo;' or '+(int) bar;' -sp_after_oc_scope = ignore # ignore/add/remove/force +# (OC) Add or remove space after the first (type) in message specs, +# i.e. '-(int) f:(int)x;' vs. '-(int)f:(int)x;'. +sp_after_oc_return_type = ignore # ignore/add/remove/force/not_defined -# Add or remove space after the colon in message specs -# '-(int) f:(int) x;' vs '-(int) f: (int) x;' -sp_after_oc_colon = ignore # ignore/add/remove/force +# (OC) Add or remove space between '@selector' and '(', +# i.e. '@selector(msgName)' vs. '@selector (msgName)'. +# Also applies to '@protocol()' constructs. +sp_after_oc_at_sel = ignore # ignore/add/remove/force/not_defined -# Add or remove space before the colon in message specs -# '-(int) f: (int) x;' vs '-(int) f : (int) x;' -sp_before_oc_colon = ignore # ignore/add/remove/force +# (OC) Add or remove space between '@selector(x)' and the following word, +# i.e. '@selector(foo) a:' vs. '@selector(foo)a:'. +sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force/not_defined -# Add or remove space after the colon in immutable dictionary expression -# 'NSDictionary *test = @{@"foo" :@"bar"};' -sp_after_oc_dict_colon = ignore # ignore/add/remove/force +# (OC) Add or remove space inside '@selector' parentheses, +# i.e. '@selector(foo)' vs. '@selector( foo )'. +# Also applies to '@protocol()' constructs. +sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force/not_defined -# Add or remove space before the colon in immutable dictionary expression -# 'NSDictionary *test = @{@"foo" :@"bar"};' -sp_before_oc_dict_colon = ignore # ignore/add/remove/force +# (OC) Add or remove space before a block pointer caret, +# i.e. '^int (int arg){...}' vs. ' ^int (int arg){...}'. +sp_before_oc_block_caret = ignore # ignore/add/remove/force/not_defined -# Add or remove space after the colon in message specs -# '[object setValue:1];' vs '[object setValue: 1];' -sp_after_send_oc_colon = ignore # ignore/add/remove/force +# (OC) Add or remove space after a block pointer caret, +# i.e. '^int (int arg){...}' vs. '^ int (int arg){...}'. +sp_after_oc_block_caret = ignore # ignore/add/remove/force/not_defined -# Add or remove space before the colon in message specs -# '[object setValue:1];' vs '[object setValue :1];' -sp_before_send_oc_colon = ignore # ignore/add/remove/force +# (OC) Add or remove space between the receiver and selector in a message, +# as in '[receiver selector ...]'. +sp_after_oc_msg_receiver = ignore # ignore/add/remove/force/not_defined -# Add or remove space after the (type) in message specs -# '-(int)f: (int) x;' vs '-(int)f: (int)x;' -sp_after_oc_type = ignore # ignore/add/remove/force +# (OC) Add or remove space after '@property'. +sp_after_oc_property = ignore # ignore/add/remove/force/not_defined -# Add or remove space after the first (type) in message specs -# '-(int) f:(int)x;' vs '-(int)f:(int)x;' -sp_after_oc_return_type = ignore # ignore/add/remove/force +# (OC) Add or remove space between '@synchronized' and the open parenthesis, +# i.e. '@synchronized(foo)' vs. '@synchronized (foo)'. +sp_after_oc_synchronized = ignore # ignore/add/remove/force/not_defined -# Add or remove space between '@selector' and '(' -# '@selector(msgName)' vs '@selector (msgName)' -# Also applies to @protocol() constructs -sp_after_oc_at_sel = ignore # ignore/add/remove/force +# Add or remove space around the ':' in 'b ? t : f'. +sp_cond_colon = ignore # ignore/add/remove/force/not_defined -# Add or remove space between '@selector(x)' and the following word -# '@selector(foo) a:' vs '@selector(foo)a:' -sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force +# Add or remove space before the ':' in 'b ? t : f'. +# +# Overrides sp_cond_colon. +sp_cond_colon_before = ignore # ignore/add/remove/force/not_defined -# Add or remove space inside '@selector' parens -# '@selector(foo)' vs '@selector( foo )' -# Also applies to @protocol() constructs -sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force +# Add or remove space after the ':' in 'b ? t : f'. +# +# Overrides sp_cond_colon. +sp_cond_colon_after = ignore # ignore/add/remove/force/not_defined -# Add or remove space before a block pointer caret -# '^int (int arg){...}' vs. ' ^int (int arg){...}' -sp_before_oc_block_caret = ignore # ignore/add/remove/force +# Add or remove space around the '?' in 'b ? t : f'. +sp_cond_question = ignore # ignore/add/remove/force/not_defined -# Add or remove space after a block pointer caret -# '^int (int arg){...}' vs. '^ int (int arg){...}' -sp_after_oc_block_caret = ignore # ignore/add/remove/force +# Add or remove space before the '?' in 'b ? t : f'. +# +# Overrides sp_cond_question. +sp_cond_question_before = ignore # ignore/add/remove/force/not_defined -# Add or remove space between the receiver and selector in a message. -# '[receiver selector ...]' -sp_after_oc_msg_receiver = ignore # ignore/add/remove/force +# Add or remove space after the '?' in 'b ? t : f'. +# +# Overrides sp_cond_question. +sp_cond_question_after = ignore # ignore/add/remove/force/not_defined -# Add or remove space after @property. -sp_after_oc_property = ignore # ignore/add/remove/force +# In the abbreviated ternary form '(a ?: b)', add or remove space between '?' +# and ':'. +# +# Overrides all other sp_cond_* options. +sp_cond_ternary_short = ignore # ignore/add/remove/force/not_defined -# Add or remove space around the ':' in 'b ? t : f' -sp_cond_colon = ignore # ignore/add/remove/force +# Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make +# sense here. +sp_case_label = ignore # ignore/add/remove/force/not_defined -# Add or remove space before the ':' in 'b ? t : f'. Overrides sp_cond_colon. -sp_cond_colon_before = ignore # ignore/add/remove/force +# (D) Add or remove space around the D '..' operator. +sp_range = ignore # ignore/add/remove/force/not_defined -# Add or remove space after the ':' in 'b ? t : f'. Overrides sp_cond_colon. -sp_cond_colon_after = ignore # ignore/add/remove/force +# Add or remove space after ':' in a Java/C++11 range-based 'for', +# as in 'for (Type var : expr)'. +sp_after_for_colon = ignore # ignore/add/remove/force/not_defined -# Add or remove space around the '?' in 'b ? t : f' -sp_cond_question = ignore # ignore/add/remove/force +# Add or remove space before ':' in a Java/C++11 range-based 'for', +# as in 'for (Type var : expr)'. +sp_before_for_colon = ignore # ignore/add/remove/force/not_defined -# Add or remove space before the '?' in 'b ? t : f'. Overrides sp_cond_question. -sp_cond_question_before = ignore # ignore/add/remove/force +# (D) Add or remove space between 'extern' and '(' as in 'extern (C)'. +sp_extern_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove space after the '?' in 'b ? t : f'. Overrides sp_cond_question. -sp_cond_question_after = ignore # ignore/add/remove/force +# Add or remove space after the opening of a C++ comment, as in '// A'. +sp_cmt_cpp_start = ignore # ignore/add/remove/force/not_defined -# In the abbreviated ternary form (a ?: b), add/remove space between ? and :.'. Overrides all other sp_cond_* options. -sp_cond_ternary_short = ignore # ignore/add/remove/force +# remove space after the '//' and the pvs command '-V1234', +# only works with sp_cmt_cpp_start set to add or force. +sp_cmt_cpp_pvs = false # true/false -# Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make sense here. -sp_case_label = ignore # ignore/add/remove/force +# remove space after the '//' and the command 'lint', +# only works with sp_cmt_cpp_start set to add or force. +sp_cmt_cpp_lint = false # true/false -# Control the space around the D '..' operator. -sp_range = ignore # ignore/add/remove/force +# Add or remove space in a C++ region marker comment, as in '// BEGIN'. +# A region marker is defined as a comment which is not preceded by other text +# (i.e. the comment is the first non-whitespace on the line), and which starts +# with either 'BEGIN' or 'END'. +# +# Overrides sp_cmt_cpp_start. +sp_cmt_cpp_region = ignore # ignore/add/remove/force/not_defined -# Control the spacing after ':' in 'for (TYPE VAR : EXPR)' -sp_after_for_colon = ignore # ignore/add/remove/force +# If true, space added with sp_cmt_cpp_start will be added after Doxygen +# sequences like '///', '///<', '//!' and '//!<'. +sp_cmt_cpp_doxygen = false # true/false -# Control the spacing before ':' in 'for (TYPE VAR : EXPR)' -sp_before_for_colon = ignore # ignore/add/remove/force +# If true, space added with sp_cmt_cpp_start will be added after Qt translator +# or meta-data comments like '//:', '//=', and '//~'. +sp_cmt_cpp_qttr = false # true/false -# Control the spacing in 'extern (C)' (D) -sp_extern_paren = ignore # ignore/add/remove/force +# Add or remove space between #else or #endif and a trailing comment. +sp_endif_cmt = ignore # ignore/add/remove/force/not_defined -# Control the space after the opening of a C++ comment '// A' vs '//A' -sp_cmt_cpp_start = ignore # ignore/add/remove/force +# Add or remove space after 'new', 'delete' and 'delete[]'. +sp_after_new = ignore # ignore/add/remove/force/not_defined -# TRUE: If space is added with sp_cmt_cpp_start, do it after doxygen sequences like '///', '///<', '//!' and '//!<'. -sp_cmt_cpp_doxygen = false # false/true +# Add or remove space between 'new' and '(' in 'new()'. +sp_between_new_paren = ignore # ignore/add/remove/force/not_defined -# TRUE: If space is added with sp_cmt_cpp_start, do it after Qt translator or meta-data comments like '//:', '//=', and '//~'. -sp_cmt_cpp_qttr = false # false/true +# Add or remove space between ')' and type in 'new(foo) BAR'. +sp_after_newop_paren = ignore # ignore/add/remove/force/not_defined -# Controls the spaces between #else or #endif and a trailing comment -sp_endif_cmt = ignore # ignore/add/remove/force +# Add or remove space inside parentheses of the new operator +# as in 'new(foo) BAR'. +sp_inside_newop_paren = ignore # ignore/add/remove/force/not_defined -# Controls the spaces after 'new', 'delete' and 'delete[]' -sp_after_new = ignore # ignore/add/remove/force +# Add or remove space after the open parenthesis of the new operator, +# as in 'new(foo) BAR'. +# +# Overrides sp_inside_newop_paren. +sp_inside_newop_paren_open = ignore # ignore/add/remove/force/not_defined -# Controls the spaces between new and '(' in 'new()' -sp_between_new_paren = ignore # ignore/add/remove/force +# Add or remove space before the close parenthesis of the new operator, +# as in 'new(foo) BAR'. +# +# Overrides sp_inside_newop_paren. +sp_inside_newop_paren_close = ignore # ignore/add/remove/force/not_defined -# Controls the spaces before a trailing or embedded comment -sp_before_tr_emb_cmt = ignore # ignore/add/remove/force +# Add or remove space before a trailing comment. +sp_before_tr_cmt = ignore # ignore/add/remove/force/not_defined -# Number of spaces before a trailing or embedded comment -sp_num_before_tr_emb_cmt = 0 # number +# Number of spaces before a trailing comment. +sp_num_before_tr_cmt = 0 # unsigned number -# Control space between a Java annotation and the open paren. -sp_annotation_paren = ignore # ignore/add/remove/force +# Add or remove space before an embedded comment. +# +# Default: force +sp_before_emb_cmt = force # ignore/add/remove/force/not_defined -# If true, vbrace tokens are dropped to the previous token and skipped. -sp_skip_vbrace_tokens = false # false/true +# Number of spaces before an embedded comment. +# +# Default: 1 +sp_num_before_emb_cmt = 1 # unsigned number +# Add or remove space after an embedded comment. # -# Code alignment (not left column spaces/tabs) +# Default: force +sp_after_emb_cmt = force # ignore/add/remove/force/not_defined + +# Number of spaces after an embedded comment. # +# Default: 1 +sp_num_after_emb_cmt = 1 # unsigned number -# Whether to keep non-indenting tabs -align_keep_tabs = false # false/true +# (Java) Add or remove space between an annotation and the open parenthesis. +sp_annotation_paren = ignore # ignore/add/remove/force/not_defined -# Whether to use tabs for aligning -align_with_tabs = false # false/true +# If true, vbrace tokens are dropped to the previous token and skipped. +sp_skip_vbrace_tokens = false # true/false -# Whether to bump out to the next tab when aligning -align_on_tabstop = false # false/true +# Add or remove space after 'noexcept'. +sp_after_noexcept = ignore # ignore/add/remove/force/not_defined -# Whether to left-align numbers -#align_number_left = false # false/true +# Add or remove space after '_'. +sp_vala_after_translation = ignore # ignore/add/remove/force/not_defined -# Whether to keep whitespace not required for alignment. -align_keep_extra_space = false # false/true +# Add or remove space before a bit colon ':'. +sp_before_bit_colon = ignore # ignore/add/remove/force/not_defined -# Align variable definitions in prototypes and functions -align_func_params = false # false/true +# Add or remove space after a bit colon ':'. +sp_after_bit_colon = ignore # ignore/add/remove/force/not_defined -# Align parameters in single-line functions that have the same name. -# The function names must already be aligned with each other. -align_same_func_call_params = false # false/true +# If true, a is inserted after #define. +force_tab_after_define = false # true/false -# The span for aligning variable definitions (0=don't align) -align_var_def_span = 0 # number +# +# Indenting options +# -# How to align the star in variable definitions. -# 0=Part of the type 'void * foo;' -# 1=Part of the variable 'void *foo;' -# 2=Dangling 'void *foo;' -align_var_def_star_style = 1 # number +# The number of columns to indent per level. Usually 2, 3, 4, or 8. +# +# Default: 8 +indent_columns = 4 # unsigned number -# How to align the '&' in variable definitions. -# 0=Part of the type -# 1=Part of the variable -# 2=Dangling -align_var_def_amp_style = 0 # number +# Whether to ignore indent for the first continuation line. Subsequent +# continuation lines will still be indented to match the first. +indent_ignore_first_continue = false # true/false -# The threshold for aligning variable definitions (0=no limit) -align_var_def_thresh = 0 # number +# The continuation indent. If non-zero, this overrides the indent of '(', '[' +# and '=' continuation indents. Negative values are OK; negative value is +# absolute and not increased for each '(' or '[' level. +# +# For FreeBSD, this is set to 4. +# Requires indent_ignore_first_continue=false. +indent_continue = 0 # number -# The gap for aligning variable definitions -align_var_def_gap = 0 # number +# The continuation indent, only for class header line(s). If non-zero, this +# overrides the indent of 'class' continuation indents. +# Requires indent_ignore_first_continue=false. +indent_continue_class_head = 0 # unsigned number -# Whether to align the colon in struct bit fields -align_var_def_colon = false # false/true +# Whether to indent empty lines (i.e. lines which contain only spaces before +# the newline character). +indent_single_newlines = false # true/false -# Whether to align any attribute after the variable name -align_var_def_attribute = false # false/true +# The continuation indent for func_*_param if they are true. If non-zero, this +# overrides the indent. +indent_param = 0 # unsigned number -# Whether to align inline struct/enum/union variable definitions -align_var_def_inline = true # false/true +# How to use tabs when indenting code. +# +# 0: Spaces only +# 1: Indent with tabs to brace level, align with spaces (default) +# 2: Indent and align with tabs, using spaces when not on a tabstop +# +# Default: 1 +indent_with_tabs = 0 # unsigned number -# The span for aligning on '=' in assignments (0=don't align) -align_assign_span = 0 # number +# Whether to indent comments that are not at a brace level with tabs on a +# tabstop. Requires indent_with_tabs=2. If false, will use spaces. +indent_cmt_with_tabs = false # true/false -# The threshold for aligning on '=' in assignments (0=no limit) -align_assign_thresh = 0 # number +# Whether to indent strings broken by '\' so that they line up. +indent_align_string = false # true/false -# The span for aligning on '=' in enums (0=don't align) -align_enum_equ_span = 0 # number +# The number of spaces to indent multi-line XML strings. +# Requires indent_align_string=true. +indent_xml_string = 0 # unsigned number -# The threshold for aligning on '=' in enums (0=no limit) -align_enum_equ_thresh = 0 # number +# Spaces to indent '{' from level. +indent_brace = 0 # unsigned number -# The span for aligning class (0=don't align) -align_var_class_span = 0 # number +# Whether braces are indented to the body level. +indent_braces = false # true/false -# The threshold for aligning class member definitions (0=no limit) -align_var_class_thresh = 0 # number +# Whether to disable indenting function braces if indent_braces=true. +indent_braces_no_func = false # true/false -# The gap for aligning class member definitions -align_var_class_gap = 0 # number +# Whether to disable indenting class braces if indent_braces=true. +indent_braces_no_class = false # true/false -# The span for aligning struct/union (0=don't align) -align_var_struct_span = 0 # number +# Whether to disable indenting struct braces if indent_braces=true. +indent_braces_no_struct = false # true/false -# The threshold for aligning struct/union member definitions (0=no limit) -align_var_struct_thresh = 0 # number +# Whether to indent based on the size of the brace parent, +# i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc. +indent_brace_parent = false # true/false -# The gap for aligning struct/union member definitions -align_var_struct_gap = 0 # number +# Whether to indent based on the open parenthesis instead of the open brace +# in '({\n'. +indent_paren_open_brace = false # true/false -# The span for aligning struct initializer values (0=don't align) -align_struct_init_span = 0 # number +# (C#) Whether to indent the brace of a C# delegate by another level. +indent_cs_delegate_brace = false # true/false -# The minimum space between the type and the synonym of a typedef -align_typedef_gap = 0 # number +# (C#) Whether to indent a C# delegate (to handle delegates with no brace) by +# another level. +indent_cs_delegate_body = false # true/false -# The span for aligning single-line typedefs (0=don't align) -align_typedef_span = 0 # number +# Whether to indent the body of a 'namespace'. +indent_namespace = false # true/false -# How to align typedef'd functions with other typedefs -# 0: Don't mix them at all -# 1: align the open paren with the types -# 2: align the function type name with the other type names -align_typedef_func = 0 # number +# Whether to indent only the first namespace, and not any nested namespaces. +# Requires indent_namespace=true. +indent_namespace_single_indent = false # true/false -# Controls the positioning of the '*' in typedefs. Just try it. -# 0: Align on typedef type, ignore '*' -# 1: The '*' is part of type name: typedef int *pint; -# 2: The '*' is part of the type, but dangling: typedef int *pint; -align_typedef_star_style = 1 # number +# The number of spaces to indent a namespace block. +# If set to zero, use the value indent_columns +indent_namespace_level = 0 # unsigned number -# Controls the positioning of the '&' in typedefs. Just try it. -# 0: Align on typedef type, ignore '&' -# 1: The '&' is part of type name: typedef int &pint; -# 2: The '&' is part of the type, but dangling: typedef int &pint; -align_typedef_amp_style = 0 # number +# If the body of the namespace is longer than this number, it won't be +# indented. Requires indent_namespace=true. 0 means no limit. +indent_namespace_limit = 0 # unsigned number -# The span for aligning comments that end lines (0=don't align) -align_right_cmt_span = 0 # number +# Whether to indent only in inner namespaces (nested in other namespaces). +# Requires indent_namespace=true. +indent_namespace_inner_only = false # true/false -# If aligning comments, mix with comments after '}' and #endif with less than 3 spaces before the comment -align_right_cmt_mix = false # false/true +# Whether the 'extern "C"' body is indented. +indent_extern = false # true/false -# If a trailing comment is more than this number of columns away from the text it follows, -# it will qualify for being aligned. This has to be > 0 to do anything. -align_right_cmt_gap = 0 # number +# Whether the 'class' body is indented. +indent_class = true # true/false -# Align trailing comment at or beyond column N; 'pulls in' comments as a bonus side effect (0=ignore) -align_right_cmt_at_col = 0 # number +# Whether to ignore indent for the leading base class colon. +indent_ignore_before_class_colon = false # true/false -# The span for aligning function prototypes (0=don't align) -align_func_proto_span = 0 # number +# Additional indent before the leading base class colon. +# Negative values decrease indent down to the first column. +# Requires indent_ignore_before_class_colon=false and a newline break before +# the colon (see pos_class_colon and nl_class_colon) +indent_before_class_colon = 0 # number -# Minimum gap between the return type and the function name. -align_func_proto_gap = 0 # number +# Whether to indent the stuff after a leading base class colon. +indent_class_colon = true # true/false -# Align function protos on the 'operator' keyword instead of what follows -align_on_operator = false # false/true +# Whether to indent based on a class colon instead of the stuff after the +# colon. Requires indent_class_colon=true. +indent_class_on_colon = false # true/false -# Whether to mix aligning prototype and variable declarations. -# If true, align_var_def_XXX options are used instead of align_func_proto_XXX options. -align_mix_var_proto = false # false/true +# Whether to ignore indent for a leading class initializer colon. +indent_ignore_before_constr_colon = false # true/false -# Align single-line functions with function prototypes, uses align_func_proto_span -align_single_line_func = false # false/true +# Whether to indent the stuff after a leading class initializer colon. +indent_constr_colon = false # true/false -# Aligning the open brace of single-line functions. -# Requires align_single_line_func=true, uses align_func_proto_span -align_single_line_brace = false # false/true +# Virtual indent from the ':' for leading member initializers. +# +# Default: 2 +indent_ctor_init_leading = 2 # unsigned number -# Gap for align_single_line_brace. -align_single_line_brace_gap = 0 # number +# Virtual indent from the ':' for following member initializers. +# +# Default: 2 +indent_ctor_init_following = 2 # unsigned number + +# Additional indent for constructor initializer list. +# Negative values decrease indent down to the first column. +indent_ctor_init = 0 # number -# The span for aligning ObjC msg spec (0=don't align) -align_oc_msg_spec_span = 0 # number +# Whether to indent 'if' following 'else' as a new block under the 'else'. +# If false, 'else\nif' is treated as 'else if' for indenting purposes. +indent_else_if = false # true/false -# Whether to align macros wrapped with a backslash and a newline. -# This will not work right if the macro contains a multi-line comment. -align_nl_cont = false # false/true +# Amount to indent variable declarations after a open brace. +# +# <0: Relative +# >=0: Absolute +indent_var_def_blk = 0 # number -# # Align macro functions and variables together -align_pp_define_together = false # false/true +# Whether to indent continued variable declarations instead of aligning. +indent_var_def_cont = false # true/false -# The minimum space between label and value of a preprocessor define -align_pp_define_gap = 0 # number +# How to indent continued shift expressions ('<<' and '>>'). +# Set align_left_shift=false when using this. +# 0: Align shift operators instead of indenting them (default) +# 1: Indent by one level +# -1: Preserve original indentation +indent_shift = 0 # number -# The span for aligning on '#define' bodies (0=don't align, other=number of lines including comments between blocks) -align_pp_define_span = 0 # number +# Whether to force indentation of function definitions to start in column 1. +indent_func_def_force_col1 = false # true/false -# Align lines that start with '<<' with previous '<<'. Default=True -align_left_shift = true # false/true +# Whether to indent continued function call parameters one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_call_param = false # true/false -# Align text after asm volatile () colons. -align_asm_colon = false # false/true +# Whether to indent continued function definition parameters one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_def_param = false # true/false -# Span for aligning parameters in an Obj-C message call on the ':' (0=don't align) -align_oc_msg_colon_span = 0 # number +# for function definitions, only if indent_func_def_param is false +# Allows to align params when appropriate and indent them when not +# behave as if it was true if paren position is more than this value +# if paren position is more than the option value +indent_func_def_param_paren_pos_threshold = 0 # unsigned number -# If true, always align with the first parameter, even if it is too short. -align_oc_msg_colon_first = false # false/true +# Whether to indent continued function call prototype one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_proto_param = false # true/false -# Aligning parameters in an Obj-C '+' or '-' declaration on the ':' -align_oc_decl_colon = false # false/true +# Whether to indent continued function call declaration one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_class_param = false # true/false -# -# Newline adding and removing options -# +# Whether to indent continued class variable constructors one indent level, +# rather than aligning parameters under the open parenthesis. +indent_func_ctor_var_param = false # true/false + +# Whether to indent continued template parameter list one indent level, +# rather than aligning parameters under the open parenthesis. +indent_template_param = false # true/false -# Whether to collapse empty blocks between '{' and '}' -nl_collapse_empty_body = false # false/true +# Double the indent for indent_func_xxx_param options. +# Use both values of the options indent_columns and indent_param. +indent_func_param_double = false # true/false -# Don't split one-line braced assignments - 'foo_t f = { 1, 2 };' -nl_assign_leave_one_liners = true # false/true +# Indentation column for standalone 'const' qualifier on a function +# prototype. +indent_func_const = 0 # unsigned number -# Don't split one-line braced statements inside a class xx { } body -nl_class_leave_one_liners = false # false/true +# Indentation column for standalone 'throw' qualifier on a function +# prototype. +indent_func_throw = 0 # unsigned number -# Don't split one-line enums: 'enum foo { BAR = 15 };' -nl_enum_leave_one_liners = false # false/true +# How to indent within a macro followed by a brace on the same line +# This allows reducing the indent in macros that have (for example) +# `do { ... } while (0)` blocks bracketing them. +# +# true: add an indent for the brace on the same line as the macro +# false: do not add an indent for the brace on the same line as the macro +# +# Default: true +indent_macro_brace = true # true/false -# Don't split one-line get or set functions -nl_getset_leave_one_liners = false # false/true +# The number of spaces to indent a continued '->' or '.'. +# Usually set to 0, 1, or indent_columns. +indent_member = 0 # unsigned number -# Don't split one-line function definitions - 'int foo() { return 0; }' -nl_func_leave_one_liners = false # false/true +# Whether lines broken at '.' or '->' should be indented by a single indent. +# The indent_member option will not be effective if this is set to true. +indent_member_single = false # true/false -# Don't split one-line C++11 lambdas - '[]() { return 0; }' -nl_cpp_lambda_leave_one_liners = false # false/true +# Spaces to indent single line ('//') comments on lines before code. +indent_single_line_comments_before = 0 # unsigned number -# Don't split one-line if/else statements - 'if(a) b++;' -nl_if_leave_one_liners = false # false/true +# Spaces to indent single line ('//') comments on lines after code. +indent_single_line_comments_after = 0 # unsigned number -# Don't split one-line while statements - 'while(a) b++;' -nl_while_leave_one_liners = true # false/true +# When opening a paren for a control statement (if, for, while, etc), increase +# the indent level by this value. Negative values decrease the indent level. +indent_sparen_extra = 0 # number -# Don't split one-line OC messages -nl_oc_msg_leave_one_liner = false # false/true +# Whether to indent trailing single line ('//') comments relative to the code +# instead of trying to keep the same absolute column. +indent_relative_single_line_comments = false # true/false -# Add or remove newline between Objective-C block signature and '{' -nl_oc_block_brace = ignore # ignore/add/remove/force +# Spaces to indent 'case' from 'switch'. Usually 0 or indent_columns. +# It might be wise to choose the same value for the option indent_case_brace. +indent_switch_case = 0 # unsigned number -# Add or remove newlines at the start of the file -nl_start_of_file = remove # ignore/add/remove/force +# Spaces to indent the body of a 'switch' before any 'case'. +# Usually the same as indent_columns or indent_switch_case. +indent_switch_body = 0 # unsigned number -# The number of newlines at the start of the file (only used if nl_start_of_file is 'add' or 'force' -nl_start_of_file_min = 0 # number +# Whether to ignore indent for '{' following 'case'. +indent_ignore_case_brace = false # true/false -# Add or remove newline at the end of the file -nl_end_of_file = ignore # ignore/add/remove/force +# Spaces to indent '{' from 'case'. By default, the brace will appear under +# the 'c' in case. Usually set to 0 or indent_columns. Negative values are OK. +# It might be wise to choose the same value for the option indent_switch_case. +indent_case_brace = 0 # number -# The number of newlines at the end of the file (only used if nl_end_of_file is 'add' or 'force') -nl_end_of_file_min = 0 # number +# indent 'break' with 'case' from 'switch'. +indent_switch_break_with_case = false # true/false -# Add or remove newline between '=' and '{' -nl_assign_brace = remove # ignore/add/remove/force +# Whether to indent preprocessor statements inside of switch statements. +# +# Default: true +indent_switch_pp = true # true/false -# Add or remove newline between '=' and '[' (D only) -nl_assign_square = ignore # ignore/add/remove/force +# Spaces to shift the 'case' line, without affecting any other lines. +# Usually 0. +indent_case_shift = 0 # unsigned number -# Add or remove newline after '= [' (D only). Will also affect the newline before the ']' -nl_after_square_assign = ignore # ignore/add/remove/force +# Whether to align comments before 'case' with the 'case'. +# +# Default: true +indent_case_comment = true # true/false -# The number of blank lines after a block of variable definitions at the top of a function body -# 0 = No change (default) -nl_func_var_def_blk = 0 # number +# Whether to indent comments not found in first column. +# +# Default: true +indent_comment = true # true/false -# The number of newlines before a block of typedefs -# 0 = No change (default) -# the option 'nl_after_access_spec' takes preference over 'nl_typedef_blk_start' -nl_typedef_blk_start = 0 # number +# Whether to indent comments found in first column. +indent_col1_comment = false # true/false -# The number of newlines after a block of typedefs -# 0 = No change (default) -nl_typedef_blk_end = 0 # number +# Whether to indent multi string literal in first column. +indent_col1_multi_string_literal = false # true/false -# The maximum consecutive newlines within a block of typedefs -# 0 = No change (default) -nl_typedef_blk_in = 0 # number +# Align comments on adjacent lines that are this many columns apart or less. +# +# Default: 3 +indent_comment_align_thresh = 3 # unsigned number -# The number of newlines before a block of variable definitions not at the top of a function body -# 0 = No change (default) -# the option 'nl_after_access_spec' takes preference over 'nl_var_def_blk_start' -nl_var_def_blk_start = 0 # number +# Whether to ignore indent for goto labels. +indent_ignore_label = false # true/false -# The number of newlines after a block of variable definitions not at the top of a function body -# 0 = No change (default) -nl_var_def_blk_end = 0 # number +# How to indent goto labels. Requires indent_ignore_label=false. +# +# >0: Absolute column where 1 is the leftmost column +# <=0: Subtract from brace indent +# +# Default: 1 +indent_label = 1 # number -# The maximum consecutive newlines within a block of variable definitions -# 0 = No change (default) -nl_var_def_blk_in = 0 # number +# How to indent access specifiers that are followed by a +# colon. +# +# >0: Absolute column where 1 is the leftmost column +# <=0: Subtract from brace indent +# +# Default: 1 +indent_access_spec = 1 # number -# Add or remove newline between a function call's ')' and '{', as in: -# list_for_each(item, &list) { } -nl_fcall_brace = remove # ignore/add/remove/force +# Whether to indent the code after an access specifier by one level. +# If true, this option forces 'indent_access_spec=0'. +indent_access_spec_body = false # true/false -# Add or remove newline between 'enum' and '{' -nl_enum_brace = ignore # ignore/add/remove/force +# If an open parenthesis is followed by a newline, whether to indent the next +# line so that it lines up after the open parenthesis (not recommended). +indent_paren_nl = false # true/false -# Add or remove newline between 'struct and '{' -nl_struct_brace = remove # ignore/add/remove/force +# How to indent a close parenthesis after a newline. +# +# 0: Indent to body level (default) +# 1: Align under the open parenthesis +# 2: Indent to the brace level +# -1: Preserve original indentation +indent_paren_close = 2 # number -# Add or remove newline between 'union' and '{' -nl_union_brace = remove # ignore/add/remove/force +# Whether to indent the open parenthesis of a function definition, +# if the parenthesis is on its own line. +indent_paren_after_func_def = false # true/false -# Add or remove newline between 'if' and '{' -nl_if_brace = remove # ignore/add/remove/force +# Whether to indent the open parenthesis of a function declaration, +# if the parenthesis is on its own line. +indent_paren_after_func_decl = false # true/false -# Add or remove newline between '}' and 'else' -nl_brace_else = remove # ignore/add/remove/force +# Whether to indent the open parenthesis of a function call, +# if the parenthesis is on its own line. +indent_paren_after_func_call = false # true/false -# Add or remove newline between 'else if' and '{' -# If set to ignore, nl_if_brace is used instead -nl_elseif_brace = remove # ignore/add/remove/force +# How to indent a comma when inside braces. +# 0: Indent by one level (default) +# 1: Align under the open brace +# -1: Preserve original indentation +indent_comma_brace = 0 # number -# Add or remove newline between 'else' and '{' -nl_else_brace = remove # ignore/add/remove/force +# How to indent a comma when inside parentheses. +# 0: Indent by one level (default) +# 1: Align under the open parenthesis +# -1: Preserve original indentation +indent_comma_paren = 0 # number -# Add or remove newline between 'else' and 'if' -nl_else_if = remove # ignore/add/remove/force +# How to indent a Boolean operator when inside parentheses. +# 0: Indent by one level (default) +# 1: Align under the open parenthesis +# -1: Preserve original indentation +indent_bool_paren = 0 # number -# Add or remove newline between '}' and 'finally' -nl_brace_finally = ignore # ignore/add/remove/force +# Whether to ignore the indentation of a Boolean operator when outside +# parentheses. +indent_ignore_bool = false # true/false -# Add or remove newline between 'finally' and '{' -nl_finally_brace = ignore # ignore/add/remove/force +# Whether to ignore the indentation of an arithmetic operator. +indent_ignore_arith = false # true/false -# Add or remove newline between 'try' and '{' -nl_try_brace = ignore # ignore/add/remove/force +# Whether to indent a semicolon when inside a for parenthesis. +# If true, aligns under the open for parenthesis. +indent_semicolon_for_paren = false # true/false -# Add or remove newline between get/set and '{' -nl_getset_brace = ignore # ignore/add/remove/force +# Whether to ignore the indentation of a semicolon outside of a 'for' +# statement. +indent_ignore_semicolon = false # true/false -# Add or remove newline between 'for' and '{' -nl_for_brace = remove # ignore/add/remove/force +# Whether to align the first expression to following ones +# if indent_bool_paren=1. +indent_first_bool_expr = false # true/false -# Add or remove newline between 'catch' and '{' -nl_catch_brace = ignore # ignore/add/remove/force +# Whether to align the first expression to following ones +# if indent_semicolon_for_paren=true. +indent_first_for_expr = false # true/false -# Add or remove newline between '}' and 'catch' -nl_brace_catch = ignore # ignore/add/remove/force +# If an open square is followed by a newline, whether to indent the next line +# so that it lines up after the open square (not recommended). +indent_square_nl = false # true/false -# Add or remove newline between '}' and ']' -nl_brace_square = ignore # ignore/add/remove/force +# (ESQL/C) Whether to preserve the relative indent of 'EXEC SQL' bodies. +indent_preserve_sql = false # true/false -# Add or remove newline between '}' and ')' in a function invocation -nl_brace_fparen = ignore # ignore/add/remove/force +# Whether to ignore the indentation of an assignment operator. +indent_ignore_assign = false # true/false -# Add or remove newline between 'while' and '{' -nl_while_brace = remove # ignore/add/remove/force +# Whether to align continued statements at the '='. If false or if the '=' is +# followed by a newline, the next line is indent one tab. +# +# Default: true +indent_align_assign = true # true/false -# Add or remove newline between 'scope (x)' and '{' (D) -nl_scope_brace = ignore # ignore/add/remove/force +# If true, the indentation of the chunks after a '=' sequence will be set at +# LHS token indentation column before '='. +indent_off_after_assign = false # true/false -# Add or remove newline between 'unittest' and '{' (D) -nl_unittest_brace = ignore # ignore/add/remove/force +# Whether to align continued statements at the '('. If false or the '(' is +# followed by a newline, the next line indent is one tab. +# +# Default: true +indent_align_paren = true # true/false -# Add or remove newline between 'version (x)' and '{' (D) -nl_version_brace = ignore # ignore/add/remove/force +# (OC) Whether to indent Objective-C code inside message selectors. +indent_oc_inside_msg_sel = false # true/false -# Add or remove newline between 'using' and '{' -nl_using_brace = ignore # ignore/add/remove/force +# (OC) Whether to indent Objective-C blocks at brace level instead of usual +# rules. +indent_oc_block = false # true/false -# Add or remove newline between two open or close braces. -# Due to general newline/brace handling, REMOVE may not work. -nl_brace_brace = ignore # ignore/add/remove/force +# (OC) Indent for Objective-C blocks in a message relative to the parameter +# name. +# +# =0: Use indent_oc_block rules +# >0: Use specified number of spaces to indent +indent_oc_block_msg = 0 # unsigned number -# Add or remove newline between 'do' and '{' -nl_do_brace = remove # ignore/add/remove/force +# (OC) Minimum indent for subsequent parameters +indent_oc_msg_colon = 0 # unsigned number -# Add or remove newline between '}' and 'while' of 'do' statement -nl_brace_while = remove # ignore/add/remove/force +# (OC) Whether to prioritize aligning with initial colon (and stripping spaces +# from lines, if necessary). +# +# Default: true +indent_oc_msg_prioritize_first_colon = true # true/false -# Add or remove newline between 'switch' and '{' -nl_switch_brace = remove # ignore/add/remove/force +# (OC) Whether to indent blocks the way that Xcode does by default +# (from the keyword if the parameter is on its own line; otherwise, from the +# previous indentation level). Requires indent_oc_block_msg=true. +indent_oc_block_msg_xcode_style = false # true/false -# Add or remove newline between 'synchronized' and '{' -nl_synchronized_brace = ignore # ignore/add/remove/force +# (OC) Whether to indent blocks from where the brace is, relative to a +# message keyword. Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_keyword = false # true/false -# Add a newline between ')' and '{' if the ')' is on a different line than the if/for/etc. -# Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch and nl_catch_brace. -nl_multi_line_cond = false # false/true +# (OC) Whether to indent blocks from where the brace is, relative to a message +# colon. Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_colon = false # true/false -# Force a newline in a define after the macro name for multi-line defines. -nl_multi_line_define = false # false/true +# (OC) Whether to indent blocks from where the block caret is. +# Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_caret = false # true/false -# Whether to put a newline before 'case' statement, not after the first 'case' -nl_before_case = false # false/true +# (OC) Whether to indent blocks from where the brace caret is. +# Requires indent_oc_block_msg=true. +indent_oc_block_msg_from_brace = false # true/false -# Add or remove newline between ')' and 'throw' -nl_before_throw = ignore # ignore/add/remove/force +# When indenting after virtual brace open and newline add further spaces to +# reach this minimum indent. +indent_min_vbrace_open = 0 # unsigned number -# Whether to put a newline after 'case' statement -nl_after_case = false # false/true +# Whether to add further spaces after regular indent to reach next tabstop +# when indenting after virtual brace open and newline. +indent_vbrace_open_on_tabstop = false # true/false -# Add or remove a newline between a case ':' and '{'. Overrides nl_after_case. -nl_case_colon_brace = ignore # ignore/add/remove/force +# How to indent after a brace followed by another token (not a newline). +# true: indent all contained lines to match the token +# false: indent all contained lines to match the brace +# +# Default: true +indent_token_after_brace = true # true/false -# Newline between namespace and { -nl_namespace_brace = ignore # ignore/add/remove/force +# Whether to indent the body of a C++11 lambda. +indent_cpp_lambda_body = false # true/false -# Add or remove newline between 'template<>' and whatever follows. -nl_template_class = ignore # ignore/add/remove/force +# How to indent compound literals that are being returned. +# true: add both the indent from return & the compound literal open brace +# (i.e. 2 indent levels) +# false: only indent 1 level, don't add the indent for the open brace, only +# add the indent for the return. +# +# Default: true +indent_compound_literal_return = true # true/false -# Add or remove newline between 'class' and '{' -nl_class_brace = ignore # ignore/add/remove/force +# (C#) Whether to indent a 'using' block if no braces are used. +# +# Default: true +indent_using_block = true # true/false -# Add or remove newline before/after each ',' in the base class list, -# (tied to pos_class_comma). -nl_class_init_args = ignore # ignore/add/remove/force +# How to indent the continuation of ternary operator. +# +# 0: Off (default) +# 1: When the `if_false` is a continuation, indent it under the `if_true` branch +# 2: When the `:` is a continuation, indent it under `?` +indent_ternary_operator = 0 # unsigned number -# Add or remove newline after each ',' in the constructor member initialization. -# Related to nl_constr_colon, pos_constr_colon and pos_constr_comma. -nl_constr_init_args = ignore # ignore/add/remove/force +# Whether to indent the statements inside ternary operator. +indent_inside_ternary_operator = false # true/false -# Add or remove newline before first element, after comma, and after last element in enum -nl_enum_own_lines = ignore # ignore/add/remove/force +# If true, the indentation of the chunks after a `return` sequence will be set at return indentation column. +indent_off_after_return = false # true/false -# Add or remove newline between return type and function name in a function definition -nl_func_type_name = add # ignore/add/remove/force +# If true, the indentation of the chunks after a `return new` sequence will be set at return indentation column. +indent_off_after_return_new = false # true/false -# Add or remove newline between return type and function name inside a class {} -# Uses nl_func_type_name or nl_func_proto_type_name if set to ignore. -nl_func_type_name_class = ignore # ignore/add/remove/force +# If true, the tokens after return are indented with regular single indentation. By default (false) the indentation is after the return token. +indent_single_after_return = false # true/false -# Add or remove newline between class specification and '::' in 'void A::f() { }' -# Only appears in separate member implementation (does not appear with in-line implmementation) -nl_func_class_scope = ignore # ignore/add/remove/force +# Whether to ignore indent and alignment for 'asm' blocks (i.e. assume they +# have their own indentation). +indent_ignore_asm_block = false # true/false -# Add or remove newline between function scope and name -# Controls the newline after '::' in 'void A::f() { }' -nl_func_scope_name = ignore # ignore/add/remove/force +# Don't indent the close parenthesis of a function definition, +# if the parenthesis is on its own line. +donot_indent_func_def_close_paren = false # true/false -# Add or remove newline between return type and function name in a prototype -nl_func_proto_type_name = ignore # ignore/add/remove/force +# +# Newline adding and removing options +# -# Add or remove newline between a function name and the opening '(' in the declaration -nl_func_paren = remove # ignore/add/remove/force +# Whether to collapse empty blocks between '{' and '}' except for functions. +# Use nl_collapse_empty_body_functions to specify how empty function braces +# should be formatted. +nl_collapse_empty_body = false # true/false -# Add or remove newline between a function name and the opening '(' in the definition -nl_func_def_paren = remove # ignore/add/remove/force +# Whether to collapse empty blocks between '{' and '}' for functions only. +# If true, overrides nl_inside_empty_func. +nl_collapse_empty_body_functions = false # true/false -# Add or remove newline after '(' in a function declaration -nl_func_decl_start = remove # ignore/add/remove/force +# Don't split one-line braced assignments, as in 'foo_t f = { 1, 2 };'. +nl_assign_leave_one_liners = true # true/false -# Add or remove newline after '(' in a function definition -nl_func_def_start = remove # ignore/add/remove/force +# Don't split one-line braced statements inside a 'class xx { }' body. +nl_class_leave_one_liners = false # true/false -# Overrides nl_func_decl_start when there is only one parameter. -nl_func_decl_start_single = ignore # ignore/add/remove/force +# Don't split one-line enums, as in 'enum foo { BAR = 15 };' +nl_enum_leave_one_liners = false # true/false -# Overrides nl_func_def_start when there is only one parameter. -nl_func_def_start_single = ignore # ignore/add/remove/force +# Don't split one-line get or set functions. +nl_getset_leave_one_liners = false # true/false -# Whether to add newline after '(' in a function declaration if '(' and ')' are in different lines. -nl_func_decl_start_multi_line = false # false/true +# (C#) Don't split one-line property get or set functions. +nl_cs_property_leave_one_liners = false # true/false -# Whether to add newline after '(' in a function definition if '(' and ')' are in different lines. -nl_func_def_start_multi_line = false # false/true +# Don't split one-line function definitions, as in 'int foo() { return 0; }'. +# might modify nl_func_type_name +nl_func_leave_one_liners = false # true/false -# Add or remove newline after each ',' in a function declaration -nl_func_decl_args = ignore # ignore/add/remove/force +# Don't split one-line C++11 lambdas, as in '[]() { return 0; }'. +nl_cpp_lambda_leave_one_liners = false # true/false -# Add or remove newline after each ',' in a function definition -nl_func_def_args = ignore # ignore/add/remove/force +# Don't split one-line if/else statements, as in 'if(...) b++;'. +nl_if_leave_one_liners = false # true/false -# Whether to add newline after each ',' in a function declaration if '(' and ')' are in different lines. -nl_func_decl_args_multi_line = false # false/true +# Don't split one-line while statements, as in 'while(...) b++;'. +nl_while_leave_one_liners = true # true/false -# Whether to add newline after each ',' in a function definition if '(' and ')' are in different lines. -nl_func_def_args_multi_line = false # false/true +# Don't split one-line do statements, as in 'do { b++; } while(...);'. +nl_do_leave_one_liners = false # true/false -# Add or remove newline before the ')' in a function declaration -nl_func_decl_end = remove # ignore/add/remove/force +# Don't split one-line for statements, as in 'for(...) b++;'. +nl_for_leave_one_liners = false # true/false -# Add or remove newline before the ')' in a function definition -nl_func_def_end = remove # ignore/add/remove/force +# (OC) Don't split one-line Objective-C messages. +nl_oc_msg_leave_one_liner = false # true/false -# Overrides nl_func_decl_end when there is only one parameter. -nl_func_decl_end_single = ignore # ignore/add/remove/force +# (OC) Add or remove newline between method declaration and '{'. +nl_oc_mdef_brace = ignore # ignore/add/remove/force/not_defined -# Overrides nl_func_def_end when there is only one parameter. -nl_func_def_end_single = ignore # ignore/add/remove/force +# (OC) Add or remove newline between Objective-C block signature and '{'. +nl_oc_block_brace = ignore # ignore/add/remove/force/not_defined -# Whether to add newline before ')' in a function declaration if '(' and ')' are in different lines. -nl_func_decl_end_multi_line = false # false/true +# (OC) Add or remove blank line before '@interface' statement. +nl_oc_before_interface = ignore # ignore/add/remove/force/not_defined -# Whether to add newline before ')' in a function definition if '(' and ')' are in different lines. -nl_func_def_end_multi_line = false # false/true +# (OC) Add or remove blank line before '@implementation' statement. +nl_oc_before_implementation = ignore # ignore/add/remove/force/not_defined -# Add or remove newline between '()' in a function declaration. -nl_func_decl_empty = ignore # ignore/add/remove/force +# (OC) Add or remove blank line before '@end' statement. +nl_oc_before_end = ignore # ignore/add/remove/force/not_defined -# Add or remove newline between '()' in a function definition. -nl_func_def_empty = ignore # ignore/add/remove/force +# (OC) Add or remove newline between '@interface' and '{'. +nl_oc_interface_brace = ignore # ignore/add/remove/force/not_defined -# Whether to add newline after '(' in a function call if '(' and ')' are in different lines. -nl_func_call_start_multi_line = false # false/true +# (OC) Add or remove newline between '@implementation' and '{'. +nl_oc_implementation_brace = ignore # ignore/add/remove/force/not_defined -# Whether to add newline after each ',' in a function call if '(' and ')' are in different lines. -nl_func_call_args_multi_line = false # false/true +# Add or remove newlines at the start of the file. +nl_start_of_file = remove # ignore/add/remove/force/not_defined -# Whether to add newline before ')' in a function call if '(' and ')' are in different lines. -nl_func_call_end_multi_line = false # false/true +# The minimum number of newlines at the start of the file (only used if +# nl_start_of_file is 'add' or 'force'). +nl_start_of_file_min = 0 # unsigned number -# Whether to put each OC message parameter on a separate line -# See nl_oc_msg_leave_one_liner -nl_oc_msg_args = false # false/true +# Add or remove newline at the end of the file. +nl_end_of_file = force # ignore/add/remove/force/not_defined -# Add or remove newline between function signature and '{' -nl_fdef_brace = add # ignore/add/remove/force +# The minimum number of newlines at the end of the file (only used if +# nl_end_of_file is 'add' or 'force'). +nl_end_of_file_min = 1 # unsigned number -# Add or remove newline between C++11 lambda signature and '{' -nl_cpp_ldef_brace = ignore # ignore/add/remove/force +# Add or remove newline between '=' and '{'. +nl_assign_brace = remove # ignore/add/remove/force/not_defined -# Add or remove a newline between the return keyword and return expression. -nl_return_expr = ignore # ignore/add/remove/force +# (D) Add or remove newline between '=' and '['. +nl_assign_square = ignore # ignore/add/remove/force/not_defined -# Whether to put a newline after semicolons, except in 'for' statements -nl_after_semicolon = false # false/true +# Add or remove newline between '[]' and '{'. +nl_tsquare_brace = ignore # ignore/add/remove/force/not_defined -# Java: Control the newline between the ')' and '{{' of the double brace initializer. -nl_paren_dbrace_open = ignore # ignore/add/remove/force +# (D) Add or remove newline after '= ['. Will also affect the newline before +# the ']'. +nl_after_square_assign = ignore # ignore/add/remove/force/not_defined -# Whether to put a newline after brace open. -# This also adds a newline before the matching brace close. -nl_after_brace_open = false # false/true +# Add or remove newline between a function call's ')' and '{', as in +# 'list_for_each(item, &list) { }'. +nl_fcall_brace = remove # ignore/add/remove/force/not_defined -# If nl_after_brace_open and nl_after_brace_open_cmt are true, a newline is -# placed between the open brace and a trailing single-line comment. -nl_after_brace_open_cmt = false # false/true +# Add or remove newline between 'enum' and '{'. +nl_enum_brace = ignore # ignore/add/remove/force/not_defined -# Whether to put a newline after a virtual brace open with a non-empty body. -# These occur in un-braced if/while/do/for statement bodies. -nl_after_vbrace_open = false # false/true +# Add or remove newline between 'enum' and 'class'. +nl_enum_class = ignore # ignore/add/remove/force/not_defined -# Whether to put a newline after a virtual brace open with an empty body. -# These occur in un-braced if/while/do/for statement bodies. -nl_after_vbrace_open_empty = false # false/true +# Add or remove newline between 'enum class' and the identifier. +nl_enum_class_identifier = ignore # ignore/add/remove/force/not_defined -# Whether to put a newline after a brace close. -# Does not apply if followed by a necessary ';'. -nl_after_brace_close = false # false/true +# Add or remove newline between 'enum class' type and ':'. +nl_enum_identifier_colon = ignore # ignore/add/remove/force/not_defined -# Whether to put a newline after a virtual brace close. -# Would add a newline before return in: 'if (foo) a++; return;' -nl_after_vbrace_close = false # false/true +# Add or remove newline between 'enum class identifier :' and type. +nl_enum_colon_type = ignore # ignore/add/remove/force/not_defined -# Control the newline between the close brace and 'b' in: 'struct { int a; } b;' -# Affects enums, unions and structures. If set to ignore, uses nl_after_brace_close -nl_brace_struct_var = ignore # ignore/add/remove/force +# Add or remove newline between 'struct and '{'. +nl_struct_brace = remove # ignore/add/remove/force/not_defined -# Whether to alter newlines in '#define' macros -nl_define_macro = false # false/true +# Add or remove newline between 'union' and '{'. +nl_union_brace = remove # ignore/add/remove/force/not_defined -# Whether to remove blanks after '#ifxx' and '#elxx', or before '#elxx' and '#endif'. Does not affect top-level #ifdefs. -nl_squeeze_ifdef = false # false/true +# Add or remove newline between 'if' and '{'. +nl_if_brace = remove # ignore/add/remove/force/not_defined -# Makes the nl_squeeze_ifdef option affect the top-level #ifdefs as well. -nl_squeeze_ifdef_top_level = false # false/true +# Add or remove newline between '}' and 'else'. +nl_brace_else = remove # ignore/add/remove/force/not_defined -# Add or remove blank line before 'if' -nl_before_if = ignore # ignore/add/remove/force +# Add or remove newline between 'else if' and '{'. If set to ignore, +# nl_if_brace is used instead. +nl_elseif_brace = remove # ignore/add/remove/force/not_defined -# Add or remove blank line after 'if' statement -nl_after_if = ignore # ignore/add/remove/force +# Add or remove newline between 'else' and '{'. +nl_else_brace = remove # ignore/add/remove/force/not_defined -# Add or remove blank line before 'for' -nl_before_for = ignore # ignore/add/remove/force +# Add or remove newline between 'else' and 'if'. +nl_else_if = remove # ignore/add/remove/force/not_defined -# Add or remove blank line after 'for' statement -nl_after_for = ignore # ignore/add/remove/force +# Add or remove newline before '{' opening brace +nl_before_opening_brace_func_class_def = ignore # ignore/add/remove/force/not_defined -# Add or remove blank line before 'while' -nl_before_while = ignore # ignore/add/remove/force +# Add or remove newline before 'if'/'else if' closing parenthesis. +nl_before_if_closing_paren = ignore # ignore/add/remove/force/not_defined -# Add or remove blank line after 'while' statement -nl_after_while = ignore # ignore/add/remove/force +# Add or remove newline between '}' and 'finally'. +nl_brace_finally = ignore # ignore/add/remove/force/not_defined -# Add or remove blank line before 'switch' -nl_before_switch = ignore # ignore/add/remove/force +# Add or remove newline between 'finally' and '{'. +nl_finally_brace = ignore # ignore/add/remove/force/not_defined -# Add or remove blank line after 'switch' statement -nl_after_switch = ignore # ignore/add/remove/force +# Add or remove newline between 'try' and '{'. +nl_try_brace = ignore # ignore/add/remove/force/not_defined -# Add or remove blank line before 'synchronized' -nl_before_synchronized = ignore # ignore/add/remove/force +# Add or remove newline between get/set and '{'. +nl_getset_brace = ignore # ignore/add/remove/force/not_defined -# Add or remove blank line after 'synchronized' statement -nl_after_synchronized = ignore # ignore/add/remove/force +# Add or remove newline between 'for' and '{'. +nl_for_brace = remove # ignore/add/remove/force/not_defined -# Add or remove blank line before 'do' -nl_before_do = ignore # ignore/add/remove/force +# Add or remove newline before the '{' of a 'catch' statement, as in +# 'catch (decl) {'. +nl_catch_brace = ignore # ignore/add/remove/force/not_defined -# Add or remove blank line after 'do/while' statement -nl_after_do = ignore # ignore/add/remove/force +# (OC) Add or remove newline before the '{' of a '@catch' statement, as in +# '@catch (decl) {'. If set to ignore, nl_catch_brace is used. +nl_oc_catch_brace = ignore # ignore/add/remove/force/not_defined -# Whether to double-space commented-entries in struct/union/enum -nl_ds_struct_enum_cmt = false # false/true +# Add or remove newline between '}' and 'catch'. +nl_brace_catch = ignore # ignore/add/remove/force/not_defined -# force nl before } of a struct/union/enum -# (lower priority than 'eat_blanks_before_close_brace') -nl_ds_struct_enum_close_brace = false # false/true +# (OC) Add or remove newline between '}' and '@catch'. If set to ignore, +# nl_brace_catch is used. +nl_oc_brace_catch = ignore # ignore/add/remove/force/not_defined -# Add or remove blank line before 'func_class_def' -nl_before_func_class_def = 0 # number +# Add or remove newline between '}' and ']'. +nl_brace_square = ignore # ignore/add/remove/force/not_defined -# Add or remove blank line before 'func_class_proto' -nl_before_func_class_proto = 0 # number +# Add or remove newline between '}' and ')' in a function invocation. +nl_brace_fparen = ignore # ignore/add/remove/force/not_defined -# Add or remove a newline before/after a class colon, -# (tied to pos_class_colon). -nl_class_colon = ignore # ignore/add/remove/force +# Add or remove newline between 'while' and '{'. +nl_while_brace = remove # ignore/add/remove/force/not_defined -# Add or remove a newline around a class constructor colon. -# Related to nl_constr_init_args, pos_constr_colon and pos_constr_comma. -nl_constr_colon = ignore # ignore/add/remove/force +# (D) Add or remove newline between 'scope (x)' and '{'. +nl_scope_brace = ignore # ignore/add/remove/force/not_defined -# Change simple unbraced if statements into a one-liner -# 'if(b)\n i++;' => 'if(b) i++;' -nl_create_if_one_liner = false # false/true +# (D) Add or remove newline between 'unittest' and '{'. +nl_unittest_brace = ignore # ignore/add/remove/force/not_defined -# Change simple unbraced for statements into a one-liner -# 'for (i=0;i<5;i++)\n foo(i);' => 'for (i=0;i<5;i++) foo(i);' -nl_create_for_one_liner = false # false/true +# (D) Add or remove newline between 'version (x)' and '{'. +nl_version_brace = ignore # ignore/add/remove/force/not_defined -# Change simple unbraced while statements into a one-liner -# 'while (i<5)\n foo(i++);' => 'while (i<5) foo(i++);' -nl_create_while_one_liner = false # false/true +# (C#) Add or remove newline between 'using' and '{'. +nl_using_brace = ignore # ignore/add/remove/force/not_defined -# Change a one-liner if statement into simple unbraced if -# 'if(b) i++;' => 'if(b) i++;' -nl_split_if_one_liner = false # false/true +# Add or remove newline between two open or close braces. Due to general +# newline/brace handling, REMOVE may not work. +nl_brace_brace = ignore # ignore/add/remove/force/not_defined -# Change a one-liner for statement into simple unbraced for -# 'for (i=0;<5;i++) foo(i);' => 'for (i=0;<5;i++) foo(i);' -nl_split_for_one_liner = false # false/true +# Add or remove newline between 'do' and '{'. +nl_do_brace = remove # ignore/add/remove/force/not_defined -# Change simple unbraced while statements into a one-liner while -# 'while (i<5)\n foo(i++);' => 'while (i<5) foo(i++);' -nl_split_while_one_liner = false # false/true +# Add or remove newline between '}' and 'while' of 'do' statement. +nl_brace_while = remove # ignore/add/remove/force/not_defined -# -# Positioning options -# +# Add or remove newline between 'switch' and '{'. +nl_switch_brace = remove # ignore/add/remove/force/not_defined + +# Add or remove newline between 'synchronized' and '{'. +nl_synchronized_brace = ignore # ignore/add/remove/force/not_defined -# The position of arithmetic operators in wrapped expressions -pos_arith = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +# Add a newline between ')' and '{' if the ')' is on a different line than the +# if/for/etc. +# +# Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch and +# nl_catch_brace. +nl_multi_line_cond = false # true/false -# The position of assignment in wrapped expressions. -# Do not affect '=' followed by '{' -pos_assign = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +# Add a newline after '(' if an if/for/while/switch condition spans multiple +# lines +nl_multi_line_sparen_open = ignore # ignore/add/remove/force/not_defined -# The position of boolean operators in wrapped expressions -pos_bool = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +# Add a newline before ')' if an if/for/while/switch condition spans multiple +# lines. Overrides nl_before_if_closing_paren if both are specified. +nl_multi_line_sparen_close = ignore # ignore/add/remove/force/not_defined -# The position of comparison operators in wrapped expressions -pos_compare = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +# Force a newline in a define after the macro name for multi-line defines. +nl_multi_line_define = false # true/false -# The position of conditional (b ? t : f) operators in wrapped expressions -pos_conditional = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +# Whether to add a newline before 'case', and a blank line before a 'case' +# statement that follows a ';' or '}'. +nl_before_case = false # true/false -# The position of the comma in wrapped expressions -pos_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +# Whether to add a newline after a 'case' statement. +nl_after_case = false # true/false -# The position of the comma in enum entries -pos_enum_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +# Add or remove newline between a case ':' and '{'. +# +# Overrides nl_after_case. +nl_case_colon_brace = ignore # ignore/add/remove/force/not_defined -# The position of the comma in the base class list if there are more than one line, -# (tied to nl_class_init_args). -pos_class_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +# Add or remove newline between ')' and 'throw'. +nl_before_throw = ignore # ignore/add/remove/force/not_defined -# The position of the comma in the constructor initialization list. -# Related to nl_constr_colon, nl_constr_init_args and pos_constr_colon. -pos_constr_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +# Add or remove newline between 'namespace' and '{'. +nl_namespace_brace = ignore # ignore/add/remove/force/not_defined -# The position of trailing/leading class colon, between class and base class list -# (tied to nl_class_colon). -pos_class_colon = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +# Add or remove newline after 'template<...>' of a template class. +nl_template_class = ignore # ignore/add/remove/force/not_defined -# The position of colons between constructor and member initialization, -# (tied to UO_nl_constr_colon). -# Related to nl_constr_colon, nl_constr_init_args and pos_constr_comma. -pos_constr_colon = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force +# Add or remove newline after 'template<...>' of a template class declaration. +# +# Overrides nl_template_class. +nl_template_class_decl = ignore # ignore/add/remove/force/not_defined +# Add or remove newline after 'template<>' of a specialized class declaration. # -# Line Splitting options +# Overrides nl_template_class_decl. +nl_template_class_decl_special = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after 'template<...>' of a template class definition. # +# Overrides nl_template_class. +nl_template_class_def = ignore # ignore/add/remove/force/not_defined -# Try to limit code width to N number of columns -code_width = 119 # number +# Add or remove newline after 'template<>' of a specialized class definition. +# +# Overrides nl_template_class_def. +nl_template_class_def_special = ignore # ignore/add/remove/force/not_defined -# Whether to fully split long 'for' statements at semi-colons -ls_for_split_full = false # false/true +# Add or remove newline after 'template<...>' of a template function. +nl_template_func = ignore # ignore/add/remove/force/not_defined -# Whether to fully split long function protos/calls at commas -ls_func_split_full = false # false/true +# Add or remove newline after 'template<...>' of a template function +# declaration. +# +# Overrides nl_template_func. +nl_template_func_decl = ignore # ignore/add/remove/force/not_defined -# Whether to split lines as close to code_width as possible and ignore some groupings -ls_code_width = false # false/true +# Add or remove newline after 'template<>' of a specialized function +# declaration. +# +# Overrides nl_template_func_decl. +nl_template_func_decl_special = ignore # ignore/add/remove/force/not_defined +# Add or remove newline after 'template<...>' of a template function +# definition. # -# Blank line options +# Overrides nl_template_func. +nl_template_func_def = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline after 'template<>' of a specialized function +# definition. # +# Overrides nl_template_func_def. +nl_template_func_def_special = ignore # ignore/add/remove/force/not_defined -# The maximum consecutive newlines (3 = 2 blank lines) -nl_max = 0 # number +# Add or remove newline after 'template<...>' of a template variable. +nl_template_var = ignore # ignore/add/remove/force/not_defined -# The number of newlines after a function prototype, if followed by another function prototype -nl_after_func_proto = 0 # number +# Add or remove newline between 'template<...>' and 'using' of a templated +# type alias. +nl_template_using = ignore # ignore/add/remove/force/not_defined -# The number of newlines after a function prototype, if not followed by another function prototype -nl_after_func_proto_group = 0 # number +# Add or remove newline between 'class' and '{'. +nl_class_brace = ignore # ignore/add/remove/force/not_defined -# The number of newlines after a function class prototype, if followed by another function class prototype -nl_after_func_class_proto = 0 # number +# Add or remove newline before or after (depending on pos_class_comma, +# may not be IGNORE) each',' in the base class list. +nl_class_init_args = ignore # ignore/add/remove/force/not_defined -# The number of newlines after a function class prototype, if not followed by another function class prototype -nl_after_func_class_proto_group = 0 # number +# Add or remove newline after each ',' in the constructor member +# initialization. Related to nl_constr_colon, pos_constr_colon and +# pos_constr_comma. +nl_constr_init_args = ignore # ignore/add/remove/force/not_defined -# The number of newlines before a multi-line function def body -nl_before_func_body_def = 0 # number +# Add or remove newline before first element, after comma, and after last +# element, in 'enum'. +nl_enum_own_lines = ignore # ignore/add/remove/force/not_defined -# The number of newlines before a multi-line function prototype body -nl_before_func_body_proto = 0 # number +# Add or remove newline between return type and function name in a function +# definition. +# might be modified by nl_func_leave_one_liners +nl_func_type_name = add # ignore/add/remove/force/not_defined -# The number of newlines after '}' of a multi-line function body -nl_after_func_body = 0 # number +# Add or remove newline between return type and function name inside a class +# definition. If set to ignore, nl_func_type_name or nl_func_proto_type_name +# is used instead. +nl_func_type_name_class = ignore # ignore/add/remove/force/not_defined -# The number of newlines after '}' of a multi-line function body in a class declaration -nl_after_func_body_class = 0 # number +# Add or remove newline between class specification and '::' +# in 'void A::f() { }'. Only appears in separate member implementation (does +# not appear with in-line implementation). +nl_func_class_scope = ignore # ignore/add/remove/force/not_defined -# The number of newlines after '}' of a single line function body -nl_after_func_body_one_liner = 0 # number +# Add or remove newline between function scope and name, as in +# 'void A :: f() { }'. +nl_func_scope_name = ignore # ignore/add/remove/force/not_defined -# The minimum number of newlines before a multi-line comment. -# Doesn't apply if after a brace open or another multi-line comment. -nl_before_block_comment = 0 # number +# Add or remove newline between return type and function name in a prototype. +nl_func_proto_type_name = ignore # ignore/add/remove/force/not_defined -# The minimum number of newlines before a single-line C comment. -# Doesn't apply if after a brace open or other single-line C comments. -nl_before_c_comment = 0 # number +# Add or remove newline between a function name and the opening '(' in the +# declaration. +nl_func_paren = remove # ignore/add/remove/force/not_defined -# The minimum number of newlines before a CPP comment. -# Doesn't apply if after a brace open or other CPP comments. -nl_before_cpp_comment = 0 # number +# Overrides nl_func_paren for functions with no parameters. +nl_func_paren_empty = ignore # ignore/add/remove/force/not_defined -# Whether to force a newline after a multi-line comment. -nl_after_multiline_comment = false # false/true +# Add or remove newline between a function name and the opening '(' in the +# definition. +nl_func_def_paren = remove # ignore/add/remove/force/not_defined -# Whether to force a newline after a label's colon. -nl_after_label_colon = false # false/true +# Overrides nl_func_def_paren for functions with no parameters. +nl_func_def_paren_empty = ignore # ignore/add/remove/force/not_defined + +# Add or remove newline between a function name and the opening '(' in the +# call. +nl_func_call_paren = ignore # ignore/add/remove/force/not_defined -# The number of newlines after '}' or ';' of a struct/enum/union definition -nl_after_struct = 0 # number +# Overrides nl_func_call_paren for functions with no parameters. +nl_func_call_paren_empty = ignore # ignore/add/remove/force/not_defined -# The number of newlines before a class definition -nl_before_class = 0 # number +# Add or remove newline after '(' in a function declaration. +nl_func_decl_start = remove # ignore/add/remove/force/not_defined -# The number of newlines after '}' or ';' of a class definition -nl_after_class = 0 # number +# Add or remove newline after '(' in a function definition. +nl_func_def_start = remove # ignore/add/remove/force/not_defined -# The number of newlines before a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. -# Will not change the newline count if after a brace open. -# 0 = No change. -nl_before_access_spec = 0 # number +# Overrides nl_func_decl_start when there is only one parameter. +nl_func_decl_start_single = ignore # ignore/add/remove/force/not_defined -# The number of newlines after a 'private:', 'public:', 'protected:', 'signals:' or 'slots:' label. -# 0 = No change. -# the option 'nl_after_access_spec' takes preference over 'nl_typedef_blk_start' and 'nl_var_def_blk_start' -nl_after_access_spec = 0 # number +# Overrides nl_func_def_start when there is only one parameter. +nl_func_def_start_single = ignore # ignore/add/remove/force/not_defined -# The number of newlines between a function def and the function comment. -# 0 = No change. -nl_comment_func_def = 0 # number +# Whether to add a newline after '(' in a function declaration if '(' and ')' +# are in different lines. If false, nl_func_decl_start is used instead. +nl_func_decl_start_multi_line = false # true/false -# The number of newlines after a try-catch-finally block that isn't followed by a brace close. -# 0 = No change. -nl_after_try_catch_finally = 0 # number +# Whether to add a newline after '(' in a function definition if '(' and ')' +# are in different lines. If false, nl_func_def_start is used instead. +nl_func_def_start_multi_line = false # true/false -# The number of newlines before and after a property, indexer or event decl. -# 0 = No change. -nl_around_cs_property = 0 # number +# Add or remove newline after each ',' in a function declaration. +nl_func_decl_args = ignore # ignore/add/remove/force/not_defined -# The number of newlines between the get/set/add/remove handlers in C#. -# 0 = No change. -nl_between_get_set = 0 # number +# Add or remove newline after each ',' in a function definition. +nl_func_def_args = ignore # ignore/add/remove/force/not_defined -# Add or remove newline between C# property and the '{' -nl_property_brace = ignore # ignore/add/remove/force +# Add or remove newline after each ',' in a function call. +nl_func_call_args = ignore # ignore/add/remove/force/not_defined -# Whether to remove blank lines after '{' -eat_blanks_after_open_brace = false # false/true +# Whether to add a newline after each ',' in a function declaration if '(' +# and ')' are in different lines. If false, nl_func_decl_args is used instead. +nl_func_decl_args_multi_line = false # true/false -# Whether to remove blank lines before '}' -eat_blanks_before_close_brace = false # false/true +# Whether to add a newline after each ',' in a function definition if '(' +# and ')' are in different lines. If false, nl_func_def_args is used instead. +nl_func_def_args_multi_line = false # true/false -# How aggressively to remove extra newlines not in preproc. -# 0: No change -# 1: Remove most newlines not handled by other config -# 2: Remove all newlines and reformat completely by config -nl_remove_extra_newlines = 0 # number +# Add or remove newline before the ')' in a function declaration. +nl_func_decl_end = remove # ignore/add/remove/force/not_defined -# Whether to put a blank line before 'return' statements, unless after an open brace. -nl_before_return = false # false/true +# Add or remove newline before the ')' in a function definition. +nl_func_def_end = remove # ignore/add/remove/force/not_defined -# Whether to put a blank line after 'return' statements, unless followed by a close brace. -nl_after_return = false # false/true +# Overrides nl_func_decl_end when there is only one parameter. +nl_func_decl_end_single = ignore # ignore/add/remove/force/not_defined -# Whether to put a newline after a Java annotation statement. -# Only affects annotations that are after a newline. -nl_after_annotation = ignore # ignore/add/remove/force +# Overrides nl_func_def_end when there is only one parameter. +nl_func_def_end_single = ignore # ignore/add/remove/force/not_defined -# Controls the newline between two annotations. -nl_between_annotation = ignore # ignore/add/remove/force +# Whether to add a newline before ')' in a function declaration if '(' and ')' +# are in different lines. If false, nl_func_decl_end is used instead. +nl_func_decl_end_multi_line = false # true/false -# -# Code modifying options (non-whitespace) -# +# Whether to add a newline before ')' in a function definition if '(' and ')' +# are in different lines. If false, nl_func_def_end is used instead. +nl_func_def_end_multi_line = false # true/false -# Add or remove braces on single-line 'do' statement -mod_full_brace_do = add # ignore/add/remove/force +# Add or remove newline between '()' in a function declaration. +nl_func_decl_empty = ignore # ignore/add/remove/force/not_defined -# Add or remove braces on single-line 'for' statement -mod_full_brace_for = add # ignore/add/remove/force +# Add or remove newline between '()' in a function definition. +nl_func_def_empty = ignore # ignore/add/remove/force/not_defined -# Add or remove braces on single-line function definitions. (Pawn) -mod_full_brace_function = ignore # ignore/add/remove/force +# Add or remove newline between '()' in a function call. +nl_func_call_empty = ignore # ignore/add/remove/force/not_defined -# Add or remove braces on single-line 'if' statement. Will not remove the braces if they contain an 'else'. -mod_full_brace_if = add # ignore/add/remove/force +# Whether to add a newline after '(' in a function call, +# has preference over nl_func_call_start_multi_line. +nl_func_call_start = ignore # ignore/add/remove/force/not_defined -# Make all if/elseif/else statements in a chain be braced or not. Overrides mod_full_brace_if. -# If any must be braced, they are all braced. If all can be unbraced, then the braces are removed. -mod_full_brace_if_chain = false # false/true +# Whether to add a newline before ')' in a function call. +nl_func_call_end = ignore # ignore/add/remove/force/not_defined -# Make all if/elseif/else statements with at least one 'else' or 'else if' fully braced. -# If mod_full_brace_if_chain is used together with this option, all if-else chains will get braces, -# and simple 'if' statements will lose them (if possible). -mod_full_brace_if_chain_only = false # false/true +# Whether to add a newline after '(' in a function call if '(' and ')' are in +# different lines. +nl_func_call_start_multi_line = false # true/false -# Don't remove braces around statements that span N newlines -mod_full_brace_nl = 0 # number +# Whether to add a newline after each ',' in a function call if '(' and ')' +# are in different lines. +nl_func_call_args_multi_line = false # true/false -# Add or remove braces on single-line 'while' statement -mod_full_brace_while = ignore # ignore/add/remove/force +# Whether to add a newline before ')' in a function call if '(' and ')' are in +# different lines. +nl_func_call_end_multi_line = false # true/false -# Add or remove braces on single-line 'using ()' statement -mod_full_brace_using = ignore # ignore/add/remove/force +# Whether to respect nl_func_call_XXX option in case of closure args. +nl_func_call_args_multi_line_ignore_closures = false # true/false -# Add or remove unnecessary paren on 'return' statement -mod_paren_on_return = ignore # ignore/add/remove/force +# Whether to add a newline after '<' of a template parameter list. +nl_template_start = false # true/false -# Whether to change optional semicolons to real semicolons -mod_pawn_semicolon = false # false/true +# Whether to add a newline after each ',' in a template parameter list. +nl_template_args = false # true/false -# Add parens on 'while' and 'if' statement around bools -mod_full_paren_if_bool = false # false/true +# Whether to add a newline before '>' of a template parameter list. +nl_template_end = false # true/false -# Whether to remove superfluous semicolons -mod_remove_extra_semicolon = false # false/true +# (OC) Whether to put each Objective-C message parameter on a separate line. +# See nl_oc_msg_leave_one_liner. +nl_oc_msg_args = false # true/false -# If a function body exceeds the specified number of newlines and doesn't have a comment after -# the close brace, a comment will be added. -mod_add_long_function_closebrace_comment = 0 # number +# (OC) Minimum number of Objective-C message parameters before applying nl_oc_msg_args. +nl_oc_msg_args_min_params = 0 # unsigned number -# If a namespace body exceeds the specified number of newlines and doesn't have a comment after -# the close brace, a comment will be added. -mod_add_long_namespace_closebrace_comment = 0 # number +# (OC) Max code width of Objective-C message before applying nl_oc_msg_args. +nl_oc_msg_args_max_code_width = 0 # unsigned number -# If a class body exceeds the specified number of newlines and doesn't have a comment after -# the close brace, a comment will be added. -mod_add_long_class_closebrace_comment = 0 # number +# Add or remove newline between function signature and '{'. +nl_fdef_brace = add # ignore/add/remove/force/not_defined -# If a switch body exceeds the specified number of newlines and doesn't have a comment after -# the close brace, a comment will be added. -mod_add_long_switch_closebrace_comment = 0 # number +# Add or remove newline between function signature and '{', +# if signature ends with ')'. Overrides nl_fdef_brace. +nl_fdef_brace_cond = ignore # ignore/add/remove/force/not_defined -# If an #ifdef body exceeds the specified number of newlines and doesn't have a comment after -# the #endif, a comment will be added. -mod_add_long_ifdef_endif_comment = 0 # number +# Add or remove newline between C++11 lambda signature and '{'. +nl_cpp_ldef_brace = ignore # ignore/add/remove/force/not_defined -# If an #ifdef or #else body exceeds the specified number of newlines and doesn't have a comment after -# the #else, a comment will be added. -mod_add_long_ifdef_else_comment = 0 # number +# Add or remove newline between 'return' and the return expression. +nl_return_expr = ignore # ignore/add/remove/force/not_defined -# If TRUE, will sort consecutive single-line 'import' statements [Java, D] -mod_sort_import = false # false/true +# Add or remove newline between 'throw' and the throw expression. +nl_throw_expr = ignore # ignore/add/remove/force/not_defined -# If TRUE, will sort consecutive single-line 'using' statements [C#] -mod_sort_using = false # false/true +# Whether to add a newline after semicolons, except in 'for' statements. +nl_after_semicolon = false # true/false -# If TRUE, will sort consecutive single-line '#include' statements [C/C++] and '#import' statements [Obj-C] -# This is generally a bad idea, as it may break your code. -mod_sort_include = false # false/true +# (Java) Add or remove newline between the ')' and '{{' of the double brace +# initializer. +nl_paren_dbrace_open = ignore # ignore/add/remove/force/not_defined -# If TRUE, it will move a 'break' that appears after a fully braced 'case' before the close brace. -mod_move_case_break = false # false/true +# Whether to add a newline after the type in an unnamed temporary +# direct-list-initialization, better: +# before a direct-list-initialization. +nl_type_brace_init_lst = ignore # ignore/add/remove/force/not_defined -# Will add or remove the braces around a fully braced case statement. -# Will only remove the braces if there are no variable declarations in the block. -mod_case_brace = ignore # ignore/add/remove/force +# Whether to add a newline after the open brace in an unnamed temporary +# direct-list-initialization. +nl_type_brace_init_lst_open = ignore # ignore/add/remove/force/not_defined -# If TRUE, it will remove a void 'return;' that appears as the last statement in a function. -mod_remove_empty_return = false # false/true +# Whether to add a newline before the close brace in an unnamed temporary +# direct-list-initialization. +nl_type_brace_init_lst_close = ignore # ignore/add/remove/force/not_defined -# If TRUE, it will organize the properties (Obj-C) -mod_sort_oc_properties = false # false/true +# Whether to add a newline before '{'. +nl_before_brace_open = false # true/false -# Determines weight of atomic/nonatomic (Obj-C) -mod_sort_oc_property_thread_safe_weight = 0 # number +# Whether to add a newline after '{'. +nl_after_brace_open = false # true/false -# Determines weight of readwrite (Obj-C) -mod_sort_oc_property_readwrite_weight = 0 # number +# Whether to add a newline between the open brace and a trailing single-line +# comment. Requires nl_after_brace_open=true. +nl_after_brace_open_cmt = false # true/false -# Determines weight of reference type (retain, copy, assign, weak, strong) (Obj-C) -mod_sort_oc_property_reference_weight = 0 # number +# Whether to add a newline after a virtual brace open with a non-empty body. +# These occur in un-braced if/while/do/for statement bodies. +nl_after_vbrace_open = false # true/false -# Determines weight of getter type (getter=) (Obj-C) -mod_sort_oc_property_getter_weight = 0 # number +# Whether to add a newline after a virtual brace open with an empty body. +# These occur in un-braced if/while/do/for statement bodies. +nl_after_vbrace_open_empty = false # true/false -# Determines weight of setter type (setter=) (Obj-C) -mod_sort_oc_property_setter_weight = 0 # number +# Whether to add a newline after '}'. Does not apply if followed by a +# necessary ';'. +nl_after_brace_close = false # true/false -# Determines weight of nullability type (nullable/nonnull) (Obj-C) -mod_sort_oc_property_nullability_weight = 0 # number +# Whether to add a newline after a virtual brace close, +# as in 'if (foo) a++; return;'. +nl_after_vbrace_close = false # true/false -# -# Comment modifications -# +# Add or remove newline between the close brace and identifier, +# as in 'struct { int a; } b;'. Affects enumerations, unions and +# structures. If set to ignore, uses nl_after_brace_close. +nl_brace_struct_var = ignore # ignore/add/remove/force/not_defined -# Try to wrap comments at cmt_width columns -cmt_width = 0 # number +# Whether to alter newlines in '#define' macros. +nl_define_macro = false # true/false -# Set the comment reflow mode (default: 0) -# 0: no reflowing (apart from the line wrapping due to cmt_width) -# 1: no touching at all -# 2: full reflow -cmt_reflow_mode = 0 # number +# Whether to alter newlines between consecutive parenthesis closes. The number +# of closing parentheses in a line will depend on respective open parenthesis +# lines. +nl_squeeze_paren_close = false # true/false -# Whether to convert all tabs to spaces in comments. Default is to leave tabs inside comments alone, unless used for indenting. -cmt_convert_tab_to_spaces = true # false/true +# Whether to remove blanks after '#ifxx' and '#elxx', or before '#elxx' and +# '#endif'. Does not affect top-level #ifdefs. +nl_squeeze_ifdef = false # true/false -# If false, disable all multi-line comment changes, including cmt_width. keyword substitution and leading chars. -# Default=True. -cmt_indent_multi = true # false/true +# Makes the nl_squeeze_ifdef option affect the top-level #ifdefs as well. +nl_squeeze_ifdef_top_level = false # true/false -# Whether to group c-comments that look like they are in a block -cmt_c_group = false # false/true +# Add or remove blank line before 'if'. +nl_before_if = ignore # ignore/add/remove/force/not_defined -# Whether to put an empty '/*' on the first line of the combined c-comment -cmt_c_nl_start = false # false/true +# Add or remove blank line after 'if' statement. Add/Force work only if the +# next token is not a closing brace. +nl_after_if = ignore # ignore/add/remove/force/not_defined -# Whether to put a newline before the closing '*/' of the combined c-comment -cmt_c_nl_end = false # false/true +# Add or remove blank line before 'for'. +nl_before_for = ignore # ignore/add/remove/force/not_defined -# Whether to group cpp-comments that look like they are in a block -cmt_cpp_group = true # false/true +# Add or remove blank line after 'for' statement. +nl_after_for = ignore # ignore/add/remove/force/not_defined -# Whether to put an empty '/*' on the first line of the combined cpp-comment -cmt_cpp_nl_start = true # false/true +# Add or remove blank line before 'while'. +nl_before_while = ignore # ignore/add/remove/force/not_defined -# Whether to put a newline before the closing '*/' of the combined cpp-comment -cmt_cpp_nl_end = true # false/true +# Add or remove blank line after 'while' statement. +nl_after_while = ignore # ignore/add/remove/force/not_defined -# Whether to change cpp-comments into c-comments -cmt_cpp_to_c = true # false/true +# Add or remove blank line before 'switch'. +nl_before_switch = ignore # ignore/add/remove/force/not_defined -# Whether to put a star on subsequent comment lines -cmt_star_cont = false # false/true +# Add or remove blank line after 'switch' statement. +nl_after_switch = ignore # ignore/add/remove/force/not_defined -# The number of spaces to insert at the start of subsequent comment lines -cmt_sp_before_star_cont = 0 # number +# Add or remove blank line before 'synchronized'. +nl_before_synchronized = ignore # ignore/add/remove/force/not_defined -# The number of spaces to insert after the star on subsequent comment lines -cmt_sp_after_star_cont = 0 # number +# Add or remove blank line after 'synchronized' statement. +nl_after_synchronized = ignore # ignore/add/remove/force/not_defined -# For multi-line comments with a '*' lead, remove leading spaces if the first and last lines of -# the comment are the same length. Default=True -cmt_multi_check_last = true # false/true +# Add or remove blank line before 'do'. +nl_before_do = ignore # ignore/add/remove/force/not_defined -# For multi-line comments with a '*' lead, remove leading spaces if the first and last lines of -# the comment are the same length AND if the length is bigger as the first_len minimum. Default=4 -cmt_multi_first_len_minimum = 4 # number +# Add or remove blank line after 'do/while' statement. +nl_after_do = ignore # ignore/add/remove/force/not_defined -# The filename that contains text to insert at the head of a file if the file doesn't start with a C/C++ comment. -# Will substitute $(filename) with the current file's name. -cmt_insert_file_header = "" # string +# Ignore nl_before_{if,for,switch,do,synchronized} if the control +# statement is immediately after a case statement. +# if nl_before_{if,for,switch,do} is set to remove, this option +# does nothing. +nl_before_ignore_after_case = false # true/false -# The filename that contains text to insert at the end of a file if the file doesn't end with a C/C++ comment. -# Will substitute $(filename) with the current file's name. -cmt_insert_file_footer = "" # string +# Whether to put a blank line before 'return' statements, unless after an open +# brace. +nl_before_return = false # true/false -# The filename that contains text to insert before a function implementation if the function isn't preceded with a C/C++ comment. -# Will substitute $(function) with the function name and $(javaparam) with the javadoc @param and @return stuff. -# Will also substitute $(fclass) with the class name: void CFoo::Bar() { ... } -cmt_insert_func_header = "" # string +# Whether to put a blank line after 'return' statements, unless followed by a +# close brace. +nl_after_return = false # true/false -# The filename that contains text to insert before a class if the class isn't preceded with a C/C++ comment. -# Will substitute $(class) with the class name. -cmt_insert_class_header = "" # string +# Whether to put a blank line before a member '.' or '->' operators. +nl_before_member = ignore # ignore/add/remove/force/not_defined -# The filename that contains text to insert before a Obj-C message specification if the method isn't preceded with a C/C++ comment. -# Will substitute $(message) with the function name and $(javaparam) with the javadoc @param and @return stuff. -cmt_insert_oc_msg_header = "" # string +# (Java) Whether to put a blank line after a member '.' or '->' operators. +nl_after_member = ignore # ignore/add/remove/force/not_defined + +# Whether to double-space commented-entries in 'struct'/'union'/'enum'. +nl_ds_struct_enum_cmt = false # true/false + +# Whether to force a newline before '}' of a 'struct'/'union'/'enum'. +# (Lower priority than eat_blanks_before_close_brace.) +nl_ds_struct_enum_close_brace = false # true/false + +# Add or remove newline before or after (depending on pos_class_colon) a class +# colon, as in 'class Foo : public Bar'. +nl_class_colon = ignore # ignore/add/remove/force/not_defined -# If a preprocessor is encountered when stepping backwards from a function name, then -# this option decides whether the comment should be inserted. -# Affects cmt_insert_oc_msg_header, cmt_insert_func_header and cmt_insert_class_header. -cmt_insert_before_preproc = false # false/true +# Add or remove newline around a class constructor colon. The exact position +# depends on nl_constr_init_args, pos_constr_colon and pos_constr_comma. +nl_constr_colon = ignore # ignore/add/remove/force/not_defined -# If a function is declared inline to a class definition, then -# this option decides whether the comment should be inserted. -# Affects cmt_insert_func_header. -cmt_insert_before_inlines = true # false/true +# Whether to collapse a two-line namespace, like 'namespace foo\n{ decl; }' +# into a single line. If true, prevents other brace newline rules from turning +# such code into four lines. If true, it also preserves one-liner namespaces. +nl_namespace_two_to_one_liner = false # true/false -# If the function is a constructor/destructor, then -# this option decides whether the comment should be inserted. -# Affects cmt_insert_func_header. -cmt_insert_before_ctor_dtor = false # false/true +# Whether to remove a newline in simple unbraced if statements, turning them +# into one-liners, as in 'if(b)\n i++;' => 'if(b) i++;'. +nl_create_if_one_liner = false # true/false + +# Whether to remove a newline in simple unbraced for statements, turning them +# into one-liners, as in 'for (...)\n stmt;' => 'for (...) stmt;'. +nl_create_for_one_liner = false # true/false + +# Whether to remove a newline in simple unbraced while statements, turning +# them into one-liners, as in 'while (expr)\n stmt;' => 'while (expr) stmt;'. +nl_create_while_one_liner = false # true/false + +# Whether to collapse a function definition whose body (not counting braces) +# is only one line so that the entire definition (prototype, braces, body) is +# a single line. +nl_create_func_def_one_liner = false # true/false + +# Whether to split one-line simple list definitions into three lines by +# adding newlines, as in 'int a[12] = { 0 };'. +nl_create_list_one_liner = false # true/false + +# Whether to split one-line simple unbraced if statements into two lines by +# adding a newline, as in 'if(b) i++;'. +nl_split_if_one_liner = false # true/false + +# Whether to split one-line simple unbraced for statements into two lines by +# adding a newline, as in 'for (...) stmt;'. +nl_split_for_one_liner = false # true/false + +# Whether to split one-line simple unbraced while statements into two lines by +# adding a newline, as in 'while (expr) stmt;'. +nl_split_while_one_liner = false # true/false + +# Don't add a newline before a cpp-comment in a parameter list of a function +# call. +donot_add_nl_before_cpp_comment = false # true/false # -# Preprocessor options +# Blank line options # -# Control indent of preprocessors inside #if blocks at brace level 0 (file-level) -pp_indent = ignore # ignore/add/remove/force +# The maximum number of consecutive newlines (3 = 2 blank lines). +nl_max = 0 # unsigned number -# Whether to indent #if/#else/#endif at the brace level (true) or from column 1 (false) -pp_indent_at_level = false # false/true +# The maximum number of consecutive newlines in a function. +nl_max_blank_in_func = 0 # unsigned number -# Specifies the number of columns to indent preprocessors per level at brace level 0 (file-level). -# If pp_indent_at_level=false, specifies the number of columns to indent preprocessors per level at brace level > 0 (function-level). -# Default=1. -pp_indent_count = 1 # number +# The number of newlines inside an empty function body. +# This option overrides eat_blanks_after_open_brace and +# eat_blanks_before_close_brace, but is ignored when +# nl_collapse_empty_body_functions=true +nl_inside_empty_func = 0 # unsigned number -# Add or remove space after # based on pp_level of #if blocks -pp_space = ignore # ignore/add/remove/force +# The number of newlines before a function prototype. +nl_before_func_body_proto = 0 # unsigned number -# Sets the number of spaces added with pp_space -pp_space_count = 0 # number +# The number of newlines before a multi-line function definition. Where +# applicable, this option is overridden with eat_blanks_after_open_brace=true +nl_before_func_body_def = 0 # unsigned number -# The indent for #region and #endregion in C# and '#pragma region' in C/C++ -pp_indent_region = 0 # number +# The number of newlines before a class constructor/destructor prototype. +nl_before_func_class_proto = 0 # unsigned number -# Whether to indent the code between #region and #endregion -pp_region_indent_code = false # false/true +# The number of newlines before a class constructor/destructor definition. +nl_before_func_class_def = 0 # unsigned number -# If pp_indent_at_level=true, sets the indent for #if, #else and #endif when not at file-level. -# 0: indent preprocessors using output_tab_size. -# >0: column at which all preprocessors will be indented. -pp_indent_if = 0 # number +# The number of newlines after a function prototype. +nl_after_func_proto = 0 # unsigned number -# Control whether to indent the code between #if, #else and #endif. -pp_if_indent_code = false # false/true +# The number of newlines after a function prototype, if not followed by +# another function prototype. +nl_after_func_proto_group = 0 # unsigned number -# Whether to indent '#define' at the brace level (true) or from column 1 (false) -pp_define_at_level = false # false/true +# The number of newlines after a class constructor/destructor prototype. +nl_after_func_class_proto = 0 # unsigned number +# The number of newlines after a class constructor/destructor prototype, +# if not followed by another constructor/destructor prototype. +nl_after_func_class_proto_group = 0 # unsigned number + +# Whether one-line method definitions inside a class body should be treated +# as if they were prototypes for the purposes of adding newlines. # -# Use or Do not Use options +# Requires nl_class_leave_one_liners=true. Overrides nl_before_func_body_def +# and nl_before_func_class_def for one-liners. +nl_class_leave_one_liner_groups = false # true/false + +# The number of newlines after '}' of a multi-line function body. +# +# Overrides nl_min_after_func_body and nl_max_after_func_body. +nl_after_func_body = 0 # unsigned number + +# The minimum number of newlines after '}' of a multi-line function body. +# +# Only works when nl_after_func_body is 0. +nl_min_after_func_body = 0 # unsigned number + +# The maximum number of newlines after '}' of a multi-line function body. # +# Only works when nl_after_func_body is 0. +# Takes precedence over nl_min_after_func_body. +nl_max_after_func_body = 0 # unsigned number -# True: indent_func_call_param will be used (default) -# False: indent_func_call_param will NOT be used -use_indent_func_call_param = false # false/true +# The number of newlines after '}' of a multi-line function body in a class +# declaration. Also affects class constructors/destructors. +# +# Overrides nl_after_func_body. +nl_after_func_body_class = 0 # unsigned number -# The value of the indentation for a continuation line is calculate differently if the line is: -# a declaration :your case with QString fileName ... -# an assigment :your case with pSettings = new QSettings( ... -# At the second case the option value might be used twice: -# at the assigment -# at the function call (if present) -# To prevent the double use of the option value, use this option with the value 'true'. -# True: indent_continue will be used only once -# False: indent_continue will be used every time (default) -use_indent_continue_only_once = false # false/true +# The number of newlines after '}' of a single line function body. Also +# affects class constructors/destructors. +# +# Overrides nl_after_func_body and nl_after_func_body_class. +nl_after_func_body_one_liner = 0 # unsigned number -# SIGNAL/SLOT Qt macros have special formatting options. See options_for_QT.cpp for details. -# Default=True. -use_options_overriding_for_qt_macros = true # false/true +# The number of newlines before a block of typedefs. If nl_after_access_spec +# is non-zero, that option takes precedence. +# +# 0: No change (default). +nl_typedef_blk_start = 0 # unsigned number +# The number of newlines after a block of typedefs. # -# Warn levels - 1: error, 2: warning (default), 3: note +# 0: No change (default). +nl_typedef_blk_end = 0 # unsigned number + +# The maximum number of consecutive newlines within a block of typedefs. # +# 0: No change (default). +nl_typedef_blk_in = 0 # unsigned number + +# The minimum number of blank lines after a block of variable definitions +# at the top of a function body. If any preprocessor directives appear +# between the opening brace of the function and the variable block, then +# it is considered as not at the top of the function.Newlines are added +# before trailing preprocessor directives, if any exist. +# +# 0: No change (default). +nl_var_def_blk_end_func_top = 1 # unsigned number + +# The minimum number of empty newlines before a block of variable definitions +# not at the top of a function body. If nl_after_access_spec is non-zero, +# that option takes precedence. Newlines are not added at the top of the +# file or just after an opening brace. Newlines are added above any +# preprocessor directives before the block. +# +# 0: No change (default). +nl_var_def_blk_start = 1 # unsigned number + +# The minimum number of empty newlines after a block of variable definitions +# not at the top of a function body. Newlines are not added if the block +# is at the bottom of the file or just before a preprocessor directive. +# +# 0: No change (default). +nl_var_def_blk_end = 1 # unsigned number -# Warning is given if doing tab-to-\t replacement and we have found one in a C# verbatim string literal. -warn_level_tabs_found_in_verbatim_string_literals = 2 # number - -# You can force a token to be a type with the 'type' option. -# Example: -# type myfoo1 myfoo2 -# -# You can create custom macro-based indentation using macro-open, -# macro-else and macro-close. -# Example: -# macro-open BEGIN_TEMPLATE_MESSAGE_MAP -# macro-open BEGIN_MESSAGE_MAP -# macro-close END_MESSAGE_MAP -# -# You can assign any keyword to any type with the set option. -# set func_call_user _ N_ -# -# The full syntax description of all custom definition config entries -# is shown below: -# -# define custom tokens as: -# - embed whitespace in token using '' escape character, or -# put token in quotes -# - these: ' " and ` are recognized as quote delimiters -# -# type token1 token2 token3 ... -# ^ optionally specify multiple tokens on a single line -# define def_token output_token -# ^ output_token is optional, then NULL is assumed -# macro-open token -# macro-close token -# macro-else token -# set id token1 token2 ... -# ^ optionally specify multiple tokens on a single line -# ^ id is one of the names in token_enum.h sans the CT_ prefix, -# e.g. PP_PRAGMA -# -# all tokens are separated by any mix of ',' commas, '=' equal signs -# and whitespace (space, tab) -# -# You can add support for other file extensions using the 'file_ext' command. -# The first arg is the language name used with the '-l' option. -# The remaining args are file extensions, matched with 'endswith'. -# file_ext CPP .ch .cxx .cpp.in -# -# option(s) with 'not default' value: 0 +# The maximum number of consecutive newlines within a block of variable +# definitions. +# +# 0: No change (default). +nl_var_def_blk_in = 1 # unsigned number + +# The minimum number of newlines before a multi-line comment. +# Doesn't apply if after a brace open or another multi-line comment. +nl_before_block_comment = 0 # unsigned number + +# The minimum number of newlines before a single-line C comment. +# Doesn't apply if after a brace open or other single-line C comments. +nl_before_c_comment = 0 # unsigned number + +# The minimum number of newlines before a CPP comment. +# Doesn't apply if after a brace open or other CPP comments. +nl_before_cpp_comment = 0 # unsigned number + +# Whether to force a newline after a multi-line comment. +nl_after_multiline_comment = false # true/false + +# Whether to force a newline after a label's colon. +nl_after_label_colon = false # true/false + +# The number of newlines before a struct definition. +nl_before_struct = 0 # unsigned number + +# The number of newlines after '}' or ';' of a struct/enum/union definition. +nl_after_struct = 0 # unsigned number + +# The number of newlines before a class definition. +nl_before_class = 0 # unsigned number + +# The number of newlines after '}' or ';' of a class definition. +nl_after_class = 0 # unsigned number + +# The number of newlines before a namespace. +nl_before_namespace = 0 # unsigned number + +# The number of newlines after '{' of a namespace. This also adds newlines +# before the matching '}'. +# +# 0: Apply eat_blanks_after_open_brace or eat_blanks_before_close_brace if +# applicable, otherwise no change. +# +# Overrides eat_blanks_after_open_brace and eat_blanks_before_close_brace. +nl_inside_namespace = 0 # unsigned number + +# The number of newlines after '}' of a namespace. +nl_after_namespace = 0 # unsigned number + +# The number of newlines before an access specifier label. This also includes +# the Qt-specific 'signals:' and 'slots:'. Will not change the newline count +# if after a brace open. +# +# 0: No change (default). +nl_before_access_spec = 0 # unsigned number + +# The number of newlines after an access specifier label. This also includes +# the Qt-specific 'signals:' and 'slots:'. Will not change the newline count +# if after a brace open. +# +# 0: No change (default). +# +# Overrides nl_typedef_blk_start and nl_var_def_blk_start. +nl_after_access_spec = 0 # unsigned number + +# The number of newlines between a function definition and the function +# comment, as in '// comment\n void foo() {...}'. +# +# 0: No change (default). +nl_comment_func_def = 0 # unsigned number + +# The number of newlines after a try-catch-finally block that isn't followed +# by a brace close. +# +# 0: No change (default). +nl_after_try_catch_finally = 0 # unsigned number + +# (C#) The number of newlines before and after a property, indexer or event +# declaration. +# +# 0: No change (default). +nl_around_cs_property = 0 # unsigned number + +# (C#) The number of newlines between the get/set/add/remove handlers. +# +# 0: No change (default). +nl_between_get_set = 0 # unsigned number + +# (C#) Add or remove newline between property and the '{'. +nl_property_brace = ignore # ignore/add/remove/force/not_defined + +# Whether to remove blank lines after '{'. +eat_blanks_after_open_brace = true # true/false + +# Whether to remove blank lines before '}'. +eat_blanks_before_close_brace = true # true/false + +# How aggressively to remove extra newlines not in preprocessor. +# +# 0: No change (default) +# 1: Remove most newlines not handled by other config +# 2: Remove all newlines and reformat completely by config +nl_remove_extra_newlines = 0 # unsigned number + +# (Java) Add or remove newline after an annotation statement. Only affects +# annotations that are after a newline. +nl_after_annotation = ignore # ignore/add/remove/force/not_defined + +# (Java) Add or remove newline between two annotations. +nl_between_annotation = ignore # ignore/add/remove/force/not_defined + +# The number of newlines before a whole-file #ifdef. +# +# 0: No change (default). +nl_before_whole_file_ifdef = 0 # unsigned number + +# The number of newlines after a whole-file #ifdef. +# +# 0: No change (default). +nl_after_whole_file_ifdef = 0 # unsigned number + +# The number of newlines before a whole-file #endif. +# +# 0: No change (default). +nl_before_whole_file_endif = 0 # unsigned number + +# The number of newlines after a whole-file #endif. +# +# 0: No change (default). +nl_after_whole_file_endif = 0 # unsigned number + +# +# Positioning options +# + +# The position of arithmetic operators in wrapped expressions. +pos_arith = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of assignment in wrapped expressions. Do not affect '=' +# followed by '{'. +pos_assign = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of Boolean operators in wrapped expressions. +pos_bool = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of comparison operators in wrapped expressions. +pos_compare = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of conditional operators, as in the '?' and ':' of +# 'expr ? stmt : stmt', in wrapped expressions. +pos_conditional = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in wrapped expressions. +pos_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in enum entries. +pos_enum_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in the base class list if there is more than one +# line. Affects nl_class_init_args. +pos_class_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of the comma in the constructor initialization list. +# Related to nl_constr_colon, nl_constr_init_args and pos_constr_colon. +pos_constr_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of trailing/leading class colon, between class and base class +# list. Affects nl_class_colon. +pos_class_colon = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of colons between constructor and member initialization. +# Related to nl_constr_colon, nl_constr_init_args and pos_constr_comma. +pos_constr_colon = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# The position of shift operators in wrapped expressions. +pos_shift = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force + +# +# Line splitting options +# + +# Try to limit code width to N columns. +code_width = 119 # unsigned number + +# Whether to fully split long 'for' statements at semi-colons. +ls_for_split_full = false # true/false + +# Whether to fully split long function prototypes/calls at commas. +# The option ls_code_width has priority over the option ls_func_split_full. +ls_func_split_full = false # true/false + +# Whether to split lines as close to code_width as possible and ignore some +# groupings. +# The option ls_code_width has priority over the option ls_func_split_full. +ls_code_width = false # true/false + +# +# Code alignment options (not left column spaces/tabs) +# + +# Whether to keep non-indenting tabs. +align_keep_tabs = false # true/false + +# Whether to use tabs for aligning. +align_with_tabs = false # true/false + +# Whether to bump out to the next tab when aligning. +align_on_tabstop = false # true/false + +# Whether to right-align numbers. +align_number_right = false # true/false + +# Whether to keep whitespace not required for alignment. +align_keep_extra_space = false # true/false + +# Whether to align variable definitions in prototypes and functions. +align_func_params = false # true/false + +# The span for aligning parameter definitions in function on parameter name. +# +# 0: Don't align (default). +align_func_params_span = 0 # unsigned number + +# The threshold for aligning function parameter definitions. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_func_params_thresh = 0 # number + +# The gap for aligning function parameter definitions. +align_func_params_gap = 0 # unsigned number + +# The span for aligning constructor value. +# +# 0: Don't align (default). +align_constr_value_span = 0 # unsigned number + +# The threshold for aligning constructor value. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_constr_value_thresh = 0 # number + +# The gap for aligning constructor value. +align_constr_value_gap = 0 # unsigned number + +# Whether to align parameters in single-line functions that have the same +# name. The function names must already be aligned with each other. +align_same_func_call_params = false # true/false + +# The span for aligning function-call parameters for single line functions. +# +# 0: Don't align (default). +align_same_func_call_params_span = 0 # unsigned number + +# The threshold for aligning function-call parameters for single line +# functions. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_same_func_call_params_thresh = 0 # number + +# The span for aligning variable definitions. +# +# 0: Don't align (default). +align_var_def_span = 0 # unsigned number + +# How to consider (or treat) the '*' in the alignment of variable definitions. +# +# 0: Part of the type 'void * foo;' (default) +# 1: Part of the variable 'void *foo;' +# 2: Dangling 'void *foo;' +# Dangling: the '*' will not be taken into account when aligning. +align_var_def_star_style = 1 # unsigned number + +# How to consider (or treat) the '&' in the alignment of variable definitions. +# +# 0: Part of the type 'long & foo;' (default) +# 1: Part of the variable 'long &foo;' +# 2: Dangling 'long &foo;' +# Dangling: the '&' will not be taken into account when aligning. +align_var_def_amp_style = 0 # unsigned number + +# The threshold for aligning variable definitions. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_var_def_thresh = 0 # number + +# The gap for aligning variable definitions. +align_var_def_gap = 0 # unsigned number + +# Whether to align the colon in struct bit fields. +align_var_def_colon = false # true/false + +# The gap for aligning the colon in struct bit fields. +align_var_def_colon_gap = 0 # unsigned number + +# Whether to align any attribute after the variable name. +align_var_def_attribute = false # true/false + +# Whether to align inline struct/enum/union variable definitions. +align_var_def_inline = true # true/false + +# The span for aligning on '=' in assignments. +# +# 0: Don't align (default). +align_assign_span = 0 # unsigned number + +# The span for aligning on '=' in function prototype modifier. +# +# 0: Don't align (default). +align_assign_func_proto_span = 0 # unsigned number + +# The threshold for aligning on '=' in assignments. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_assign_thresh = 0 # number + +# Whether to align on the left most assignment when multiple +# definitions are found on the same line. +# Depends on 'align_assign_span' and 'align_assign_thresh' settings. +align_assign_on_multi_var_defs = false # true/false + +# The span for aligning on '{' in braced init list. +# +# 0: Don't align (default). +align_braced_init_list_span = 0 # unsigned number + +# The threshold for aligning on '{' in braced init list. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_braced_init_list_thresh = 0 # number + +# How to apply align_assign_span to function declaration "assignments", i.e. +# 'virtual void foo() = 0' or '~foo() = {default|delete}'. +# +# 0: Align with other assignments (default) +# 1: Align with each other, ignoring regular assignments +# 2: Don't align +align_assign_decl_func = 0 # unsigned number + +# The span for aligning on '=' in enums. +# +# 0: Don't align (default). +align_enum_equ_span = 0 # unsigned number + +# The threshold for aligning on '=' in enums. +# Use a negative number for absolute thresholds. +# +# 0: no limit (default). +align_enum_equ_thresh = 0 # number + +# The span for aligning class member definitions. +# +# 0: Don't align (default). +align_var_class_span = 0 # unsigned number + +# The threshold for aligning class member definitions. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_var_class_thresh = 0 # number + +# The gap for aligning class member definitions. +align_var_class_gap = 0 # unsigned number + +# The span for aligning struct/union member definitions. +# +# 0: Don't align (default). +align_var_struct_span = 0 # unsigned number + +# The threshold for aligning struct/union member definitions. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_var_struct_thresh = 0 # number + +# The gap for aligning struct/union member definitions. +align_var_struct_gap = 0 # unsigned number + +# The span for aligning struct initializer values. +# +# 0: Don't align (default). +align_struct_init_span = 0 # unsigned number + +# The span for aligning single-line typedefs. +# +# 0: Don't align (default). +align_typedef_span = 0 # unsigned number + +# The minimum space between the type and the synonym of a typedef. +align_typedef_gap = 0 # unsigned number + +# How to align typedef'd functions with other typedefs. +# +# 0: Don't mix them at all (default) +# 1: Align the open parenthesis with the types +# 2: Align the function type name with the other type names +align_typedef_func = 0 # unsigned number + +# How to consider (or treat) the '*' in the alignment of typedefs. +# +# 0: Part of the typedef type, 'typedef int * pint;' (default) +# 1: Part of type name: 'typedef int *pint;' +# 2: Dangling: 'typedef int *pint;' +# Dangling: the '*' will not be taken into account when aligning. +align_typedef_star_style = 1 # unsigned number + +# How to consider (or treat) the '&' in the alignment of typedefs. +# +# 0: Part of the typedef type, 'typedef int & intref;' (default) +# 1: Part of type name: 'typedef int &intref;' +# 2: Dangling: 'typedef int &intref;' +# Dangling: the '&' will not be taken into account when aligning. +align_typedef_amp_style = 0 # unsigned number + +# The span for aligning comments that end lines. +# +# 0: Don't align (default). +align_right_cmt_span = 0 # unsigned number + +# Minimum number of columns between preceding text and a trailing comment in +# order for the comment to qualify for being aligned. Must be non-zero to have +# an effect. +align_right_cmt_gap = 0 # unsigned number + +# If aligning comments, whether to mix with comments after '}' and #endif with +# less than three spaces before the comment. +align_right_cmt_mix = false # true/false + +# Whether to only align trailing comments that are at the same brace level. +align_right_cmt_same_level = false # true/false + +# Minimum column at which to align trailing comments. Comments which are +# aligned beyond this column, but which can be aligned in a lesser column, +# may be "pulled in". +# +# 0: Ignore (default). +align_right_cmt_at_col = 0 # unsigned number + +# The span for aligning function prototypes. +# +# 0: Don't align (default). +align_func_proto_span = 0 # unsigned number + +# Whether to ignore continuation lines when evaluating the number of +# new lines for the function prototype alignment's span. +# +# false: continuation lines are part of the newlines count +# true: continuation lines are not counted +align_func_proto_span_ignore_cont_lines = false # true/false + +# How to consider (or treat) the '*' in the alignment of function prototypes. +# +# 0: Part of the type 'void * foo();' (default) +# 1: Part of the function 'void *foo();' +# 2: Dangling 'void *foo();' +# Dangling: the '*' will not be taken into account when aligning. +align_func_proto_star_style = 0 # unsigned number + +# How to consider (or treat) the '&' in the alignment of function prototypes. +# +# 0: Part of the type 'long & foo();' (default) +# 1: Part of the function 'long &foo();' +# 2: Dangling 'long &foo();' +# Dangling: the '&' will not be taken into account when aligning. +align_func_proto_amp_style = 0 # unsigned number + +# The threshold for aligning function prototypes. +# Use a negative number for absolute thresholds. +# +# 0: No limit (default). +align_func_proto_thresh = 0 # number + +# Minimum gap between the return type and the function name. +align_func_proto_gap = 0 # unsigned number + +# Whether to align function prototypes on the 'operator' keyword instead of +# what follows. +align_on_operator = false # true/false + +# Whether to mix aligning prototype and variable declarations. If true, +# align_var_def_XXX options are used instead of align_func_proto_XXX options. +align_mix_var_proto = false # true/false + +# Whether to align single-line functions with function prototypes. +# Uses align_func_proto_span. +align_single_line_func = false # true/false + +# Whether to align the open brace of single-line functions. +# Requires align_single_line_func=true. Uses align_func_proto_span. +align_single_line_brace = false # true/false + +# Gap for align_single_line_brace. +align_single_line_brace_gap = 0 # unsigned number + +# (OC) The span for aligning Objective-C message specifications. +# +# 0: Don't align (default). +align_oc_msg_spec_span = 0 # unsigned number + +# Whether and how to align backslashes that split a macro onto multiple lines. +# This will not work right if the macro contains a multi-line comment. +# +# 0: Do nothing (default) +# 1: Align the backslashes in the column at the end of the longest line +# 2: Align with the backslash that is farthest to the left, or, if that +# backslash is farther left than the end of the longest line, at the end of +# the longest line +# 3: Align with the backslash that is farthest to the right +align_nl_cont = 0 # unsigned number + +# The minimum number of spaces between the end of a line and its continuation +# backslash. Requires align_nl_cont. +# +# Default: 1 +align_nl_cont_spaces = 1 # unsigned number + +# Whether to align macro functions and variables together. +align_pp_define_together = false # true/false + +# The span for aligning on '#define' bodies. +# +# =0: Don't align (default) +# >0: Number of lines (including comments) between blocks +align_pp_define_span = 0 # unsigned number + +# The minimum space between label and value of a preprocessor define. +align_pp_define_gap = 0 # unsigned number + +# Whether to align lines that start with '<<' with previous '<<'. +# +# Default: true +align_left_shift = true # true/false + +# Whether to align comma-separated statements following '<<' (as used to +# initialize Eigen matrices). +align_eigen_comma_init = false # true/false + +# Whether to align text after 'asm volatile ()' colons. +align_asm_colon = false # true/false + +# (OC) Span for aligning parameters in an Objective-C message call +# on the ':'. +# +# 0: Don't align. +align_oc_msg_colon_span = 0 # unsigned number + +# (OC) Whether to always align with the first parameter, even if it is too +# short. +align_oc_msg_colon_first = false # true/false + +# (OC) Whether to align parameters in an Objective-C '+' or '-' declaration +# on the ':'. +align_oc_decl_colon = false # true/false + +# (OC) Whether to not align parameters in an Objectve-C message call if first +# colon is not on next line of the message call (the same way Xcode does +# alignment) +align_oc_msg_colon_xcode_like = false # true/false + +# +# Comment modification options +# + +# Try to wrap comments at N columns. +cmt_width = 0 # unsigned number + +# How to reflow comments. +# +# 0: No reflowing (apart from the line wrapping due to cmt_width) (default) +# 1: No touching at all +# 2: Full reflow (enable cmt_indent_multi for indent with line wrapping due to cmt_width) +cmt_reflow_mode = 0 # unsigned number + +# Path to a file that contains regular expressions describing patterns for +# which the end of one line and the beginning of the next will be folded into +# the same sentence or paragraph during full comment reflow. The regular +# expressions are described using ECMAScript syntax. The syntax for this +# specification is as follows, where "..." indicates the custom regular +# expression and "n" indicates the nth end_of_prev_line_regex and +# beg_of_next_line_regex regular expression pair: +# +# end_of_prev_line_regex[1] = "...$" +# beg_of_next_line_regex[1] = "^..." +# end_of_prev_line_regex[2] = "...$" +# beg_of_next_line_regex[2] = "^..." +# . +# . +# . +# end_of_prev_line_regex[n] = "...$" +# beg_of_next_line_regex[n] = "^..." +# +# Note that use of this option overrides the default reflow fold regular +# expressions, which are internally defined as follows: +# +# end_of_prev_line_regex[1] = "[\w,\]\)]$" +# beg_of_next_line_regex[1] = "^[\w,\[\(]" +# end_of_prev_line_regex[2] = "\.$" +# beg_of_next_line_regex[2] = "^[A-Z]" +cmt_reflow_fold_regex_file = "" # string + +# Whether to indent wrapped lines to the start of the encompassing paragraph +# during full comment reflow (cmt_reflow_mode = 2). Overrides the value +# specified by cmt_sp_after_star_cont. +# +# Note that cmt_align_doxygen_javadoc_tags overrides this option for +# paragraphs associated with javadoc tags +cmt_reflow_indent_to_paragraph_start = false # true/false + +# Whether to convert all tabs to spaces in comments. If false, tabs in +# comments are left alone, unless used for indenting. +cmt_convert_tab_to_spaces = true # true/false + +# Whether to apply changes to multi-line comments, including cmt_width, +# keyword substitution and leading chars. +# +# Default: true +cmt_indent_multi = true # true/false + +# Whether to align doxygen javadoc-style tags ('@param', '@return', etc.) +# and corresponding fields such that groups of consecutive block tags, +# parameter names, and descriptions align with one another. Overrides that +# which is specified by the cmt_sp_after_star_cont. If cmt_width > 0, it may +# be necessary to enable cmt_indent_multi and set cmt_reflow_mode = 2 +# in order to achieve the desired alignment for line-wrapping. +cmt_align_doxygen_javadoc_tags = false # true/false + +# The number of spaces to insert after the star and before doxygen +# javadoc-style tags (@param, @return, etc). Requires enabling +# cmt_align_doxygen_javadoc_tags. Overrides that which is specified by the +# cmt_sp_after_star_cont. +# +# Default: 1 +cmt_sp_before_doxygen_javadoc_tags = 1 # unsigned number + +# Whether to change trailing, single-line c-comments into cpp-comments. +cmt_trailing_single_line_c_to_cpp = false # true/false + +# Whether to group c-comments that look like they are in a block. +cmt_c_group = false # true/false + +# Whether to put an empty '/*' on the first line of the combined c-comment. +cmt_c_nl_start = false # true/false + +# Whether to add a newline before the closing '*/' of the combined c-comment. +cmt_c_nl_end = false # true/false + +# Whether to change cpp-comments into c-comments. +cmt_cpp_to_c = true # true/false + +# Whether to group cpp-comments that look like they are in a block. Only +# meaningful if cmt_cpp_to_c=true. +cmt_cpp_group = true # true/false + +# Whether to put an empty '/*' on the first line of the combined cpp-comment +# when converting to a c-comment. +# +# Requires cmt_cpp_to_c=true and cmt_cpp_group=true. +cmt_cpp_nl_start = true # true/false + +# Whether to add a newline before the closing '*/' of the combined cpp-comment +# when converting to a c-comment. +# +# Requires cmt_cpp_to_c=true and cmt_cpp_group=true. +cmt_cpp_nl_end = true # true/false + +# Whether to put a star on subsequent comment lines. +cmt_star_cont = false # true/false + +# The number of spaces to insert at the start of subsequent comment lines. +cmt_sp_before_star_cont = 0 # unsigned number + +# The number of spaces to insert after the star on subsequent comment lines. +cmt_sp_after_star_cont = 0 # unsigned number + +# For multi-line comments with a '*' lead, remove leading spaces if the first +# and last lines of the comment are the same length. +# +# Default: true +cmt_multi_check_last = true # true/false + +# For multi-line comments with a '*' lead, remove leading spaces if the first +# and last lines of the comment are the same length AND if the length is +# bigger as the first_len minimum. +# +# Default: 4 +cmt_multi_first_len_minimum = 4 # unsigned number + +# Path to a file that contains text to insert at the beginning of a file if +# the file doesn't start with a C/C++ comment. If the inserted text contains +# '$(filename)', that will be replaced with the current file's name. +cmt_insert_file_header = "" # string + +# Path to a file that contains text to insert at the end of a file if the +# file doesn't end with a C/C++ comment. If the inserted text contains +# '$(filename)', that will be replaced with the current file's name. +cmt_insert_file_footer = "" # string + +# Path to a file that contains text to insert before a function definition if +# the function isn't preceded by a C/C++ comment. If the inserted text +# contains '$(function)', '$(javaparam)' or '$(fclass)', these will be +# replaced with, respectively, the name of the function, the javadoc '@param' +# and '@return' stuff, or the name of the class to which the member function +# belongs. +cmt_insert_func_header = "" # string + +# Path to a file that contains text to insert before a class if the class +# isn't preceded by a C/C++ comment. If the inserted text contains '$(class)', +# that will be replaced with the class name. +cmt_insert_class_header = "" # string + +# Path to a file that contains text to insert before an Objective-C message +# specification, if the method isn't preceded by a C/C++ comment. If the +# inserted text contains '$(message)' or '$(javaparam)', these will be +# replaced with, respectively, the name of the function, or the javadoc +# '@param' and '@return' stuff. +cmt_insert_oc_msg_header = "" # string + +# Whether a comment should be inserted if a preprocessor is encountered when +# stepping backwards from a function name. +# +# Applies to cmt_insert_oc_msg_header, cmt_insert_func_header and +# cmt_insert_class_header. +cmt_insert_before_preproc = false # true/false + +# Whether a comment should be inserted if a function is declared inline to a +# class definition. +# +# Applies to cmt_insert_func_header. +# +# Default: true +cmt_insert_before_inlines = true # true/false + +# Whether a comment should be inserted if the function is a class constructor +# or destructor. +# +# Applies to cmt_insert_func_header. +cmt_insert_before_ctor_dtor = false # true/false + +# +# Code modifying options (non-whitespace) +# + +# Add or remove braces on a single-line 'do' statement. +mod_full_brace_do = add # ignore/add/remove/force/not_defined + +# Add or remove braces on a single-line 'for' statement. +mod_full_brace_for = add # ignore/add/remove/force/not_defined + +# (Pawn) Add or remove braces on a single-line function definition. +mod_full_brace_function = ignore # ignore/add/remove/force/not_defined + +# Add or remove braces on a single-line 'if' statement. Braces will not be +# removed if the braced statement contains an 'else'. +mod_full_brace_if = add # ignore/add/remove/force/not_defined + +# Whether to enforce that all blocks of an 'if'/'else if'/'else' chain either +# have, or do not have, braces. Overrides mod_full_brace_if. +# +# 0: Don't override mod_full_brace_if +# 1: Add braces to all blocks if any block needs braces and remove braces if +# they can be removed from all blocks +# 2: Add braces to all blocks if any block already has braces, regardless of +# whether it needs them +# 3: Add braces to all blocks if any block needs braces and remove braces if +# they can be removed from all blocks, except if all blocks have braces +# despite none needing them +mod_full_brace_if_chain = 0 # unsigned number + +# Whether to add braces to all blocks of an 'if'/'else if'/'else' chain. +# If true, mod_full_brace_if_chain will only remove braces from an 'if' that +# does not have an 'else if' or 'else'. +mod_full_brace_if_chain_only = false # true/false + +# Add or remove braces on single-line 'while' statement. +mod_full_brace_while = ignore # ignore/add/remove/force/not_defined + +# Add or remove braces on single-line 'using ()' statement. +mod_full_brace_using = ignore # ignore/add/remove/force/not_defined + +# Don't remove braces around statements that span N newlines +mod_full_brace_nl = 0 # unsigned number + +# Whether to prevent removal of braces from 'if'/'for'/'while'/etc. blocks +# which span multiple lines. +# +# Affects: +# mod_full_brace_for +# mod_full_brace_if +# mod_full_brace_if_chain +# mod_full_brace_if_chain_only +# mod_full_brace_while +# mod_full_brace_using +# +# Does not affect: +# mod_full_brace_do +# mod_full_brace_function +mod_full_brace_nl_block_rem_mlcond = false # true/false + +# Add or remove unnecessary parentheses on 'return' statement. +mod_paren_on_return = ignore # ignore/add/remove/force/not_defined + +# Add or remove unnecessary parentheses on 'throw' statement. +mod_paren_on_throw = ignore # ignore/add/remove/force/not_defined + +# (Pawn) Whether to change optional semicolons to real semicolons. +mod_pawn_semicolon = false # true/false + +# Whether to fully parenthesize Boolean expressions in 'while' and 'if' +# statement, as in 'if (a && b > c)' => 'if (a && (b > c))'. +mod_full_paren_if_bool = false # true/false + +# Whether to fully parenthesize Boolean expressions after '=' +# statement, as in 'x = a && b > c;' => 'x = (a && (b > c));'. +mod_full_paren_assign_bool = false # true/false + +# Whether to fully parenthesize Boolean expressions after '=' +# statement, as in 'return a && b > c;' => 'return (a && (b > c));'. +mod_full_paren_return_bool = false # true/false + +# Whether to remove superfluous semicolons. +mod_remove_extra_semicolon = false # true/false + +# Whether to remove duplicate include. +mod_remove_duplicate_include = false # true/false + +# the following options (mod_XX_closebrace_comment) use different comment, +# depending of the setting of the next option. +# false: Use the c comment (default) +# true : Use the cpp comment +mod_add_force_c_closebrace_comment = false # true/false + +# If a function body exceeds the specified number of newlines and doesn't have +# a comment after the close brace, a comment will be added. +mod_add_long_function_closebrace_comment = 0 # unsigned number + +# If a namespace body exceeds the specified number of newlines and doesn't +# have a comment after the close brace, a comment will be added. +mod_add_long_namespace_closebrace_comment = 0 # unsigned number + +# If a class body exceeds the specified number of newlines and doesn't have a +# comment after the close brace, a comment will be added. +mod_add_long_class_closebrace_comment = 0 # unsigned number + +# If a switch body exceeds the specified number of newlines and doesn't have a +# comment after the close brace, a comment will be added. +mod_add_long_switch_closebrace_comment = 0 # unsigned number + +# If an #ifdef body exceeds the specified number of newlines and doesn't have +# a comment after the #endif, a comment will be added. +mod_add_long_ifdef_endif_comment = 0 # unsigned number + +# If an #ifdef or #else body exceeds the specified number of newlines and +# doesn't have a comment after the #else, a comment will be added. +mod_add_long_ifdef_else_comment = 0 # unsigned number + +# Whether to take care of the case by the mod_sort_xx options. +mod_sort_case_sensitive = false # true/false + +# Whether to sort consecutive single-line 'import' statements. +mod_sort_import = false # true/false + +# (C#) Whether to sort consecutive single-line 'using' statements. +mod_sort_using = false # true/false + +# Whether to sort consecutive single-line '#include' statements (C/C++) and +# '#import' statements (Objective-C). Be aware that this has the potential to +# break your code if your includes/imports have ordering dependencies. +mod_sort_include = false # true/false + +# Whether to prioritize '#include' and '#import' statements that contain +# filename without extension when sorting is enabled. +mod_sort_incl_import_prioritize_filename = false # true/false + +# Whether to prioritize '#include' and '#import' statements that does not +# contain extensions when sorting is enabled. +mod_sort_incl_import_prioritize_extensionless = false # true/false + +# Whether to prioritize '#include' and '#import' statements that contain +# angle over quotes when sorting is enabled. +mod_sort_incl_import_prioritize_angle_over_quotes = false # true/false + +# Whether to ignore file extension in '#include' and '#import' statements +# for sorting comparison. +mod_sort_incl_import_ignore_extension = false # true/false + +# Whether to group '#include' and '#import' statements when sorting is enabled. +mod_sort_incl_import_grouping_enabled = false # true/false + +# Whether to move a 'break' that appears after a fully braced 'case' before +# the close brace, as in 'case X: { ... } break;' => 'case X: { ... break; }'. +mod_move_case_break = false # true/false + +# Whether to move a 'return' that appears after a fully braced 'case' before +# the close brace, as in 'case X: { ... } return;' => 'case X: { ... return; }'. +mod_move_case_return = false # true/false + +# Add or remove braces around a fully braced case statement. Will only remove +# braces if there are no variable declarations in the block. +mod_case_brace = ignore # ignore/add/remove/force/not_defined + +# Whether to remove a void 'return;' that appears as the last statement in a +# function. +mod_remove_empty_return = false # true/false + +# Add or remove the comma after the last value of an enumeration. +mod_enum_last_comma = ignore # ignore/add/remove/force/not_defined + +# Syntax to use for infinite loops. +# +# 0: Leave syntax alone (default) +# 1: Rewrite as `for(;;)` +# 2: Rewrite as `while(true)` +# 3: Rewrite as `do`...`while(true);` +# 4: Rewrite as `while(1)` +# 5: Rewrite as `do`...`while(1);` +# +# Infinite loops that do not already match one of these syntaxes are ignored. +# Other options that affect loop formatting will be applied after transforming +# the syntax. +mod_infinite_loop = 0 # unsigned number + +# Add or remove the 'int' keyword in 'int short'. +mod_int_short = ignore # ignore/add/remove/force/not_defined + +# Add or remove the 'int' keyword in 'short int'. +mod_short_int = ignore # ignore/add/remove/force/not_defined + +# Add or remove the 'int' keyword in 'int long'. +mod_int_long = ignore # ignore/add/remove/force/not_defined + +# Add or remove the 'int' keyword in 'long int'. +mod_long_int = ignore # ignore/add/remove/force/not_defined + +# Add or remove the 'int' keyword in 'int signed'. +mod_int_signed = ignore # ignore/add/remove/force/not_defined + +# Add or remove the 'int' keyword in 'signed int'. +mod_signed_int = ignore # ignore/add/remove/force/not_defined + +# Add or remove the 'int' keyword in 'int unsigned'. +mod_int_unsigned = ignore # ignore/add/remove/force/not_defined + +# Add or remove the 'int' keyword in 'unsigned int'. +mod_unsigned_int = ignore # ignore/add/remove/force/not_defined + +# If there is a situation where mod_int_* and mod_*_int would result in +# multiple int keywords, whether to keep the rightmost int (the default) or the +# leftmost int. +mod_int_prefer_int_on_left = false # true/false + +# (OC) Whether to organize the properties. If true, properties will be +# rearranged according to the mod_sort_oc_property_*_weight factors. +mod_sort_oc_properties = false # true/false + +# (OC) Weight of a class property modifier. +mod_sort_oc_property_class_weight = 0 # number + +# (OC) Weight of 'atomic' and 'nonatomic'. +mod_sort_oc_property_thread_safe_weight = 0 # number + +# (OC) Weight of 'readwrite' when organizing properties. +mod_sort_oc_property_readwrite_weight = 0 # number + +# (OC) Weight of a reference type specifier ('retain', 'copy', 'assign', +# 'weak', 'strong') when organizing properties. +mod_sort_oc_property_reference_weight = 0 # number + +# (OC) Weight of getter type ('getter=') when organizing properties. +mod_sort_oc_property_getter_weight = 0 # number + +# (OC) Weight of setter type ('setter=') when organizing properties. +mod_sort_oc_property_setter_weight = 0 # number + +# (OC) Weight of nullability type ('nullable', 'nonnull', 'null_unspecified', +# 'null_resettable') when organizing properties. +mod_sort_oc_property_nullability_weight = 0 # number + +# +# Preprocessor options +# + +# How to use tabs when indenting preprocessor code. +# +# -1: Use 'indent_with_tabs' setting (default) +# 0: Spaces only +# 1: Indent with tabs to brace level, align with spaces +# 2: Indent and align with tabs, using spaces when not on a tabstop +# +# Default: -1 +pp_indent_with_tabs = -1 # number + +# Add or remove indentation of preprocessor directives inside #if blocks +# at brace level 0 (file-level). +pp_indent = ignore # ignore/add/remove/force/not_defined + +# Whether to indent #if/#else/#endif at the brace level. If false, these are +# indented from column 1. +pp_indent_at_level = false # true/false + +# Whether to indent #if/#else/#endif at the parenthesis level if the brace +# level is 0. If false, these are indented from column 1. +pp_indent_at_level0 = false # true/false + +# Specifies the number of columns to indent preprocessors per level +# at brace level 0 (file-level). If pp_indent_at_level=false, also specifies +# the number of columns to indent preprocessors per level +# at brace level > 0 (function-level). +# +# Default: 1 +pp_indent_count = 1 # unsigned number + +# Add or remove space after # based on pp level of #if blocks. +pp_space_after = ignore # ignore/add/remove/force/not_defined + +# Sets the number of spaces per level added with pp_space_after. +pp_space_count = 0 # unsigned number + +# The indent for '#region' and '#endregion' in C# and '#pragma region' in +# C/C++. Negative values decrease indent down to the first column. +pp_indent_region = 0 # number + +# Whether to indent the code between #region and #endregion. +pp_region_indent_code = false # true/false + +# If pp_indent_at_level=true, sets the indent for #if, #else and #endif when +# not at file-level. Negative values decrease indent down to the first column. +# +# =0: Indent preprocessors using output_tab_size +# >0: Column at which all preprocessors will be indented +pp_indent_if = 0 # number + +# Whether to indent the code between #if, #else and #endif. +pp_if_indent_code = false # true/false + +# Whether to indent the body of an #if that encompasses all the code in the file. +pp_indent_in_guard = false # true/false + +# Whether to indent '#define' at the brace level. If false, these are +# indented from column 1. +pp_define_at_level = false # true/false + +# Whether to indent '#include' at the brace level. +pp_include_at_level = false # true/false + +# Whether to ignore the '#define' body while formatting. +pp_ignore_define_body = false # true/false + +# An offset value that controls the indentation of the body of a multiline #define. +# 'body' refers to all the lines of a multiline #define except the first line. +# Requires 'pp_ignore_define_body = false'. +# +# <0: Absolute column: the body indentation starts off at the specified column +# (ex. -3 ==> the body is indented starting from column 3) +# >=0: Relative to the column of the '#' of '#define' +# (ex. 3 ==> the body is indented starting 3 columns at the right of '#') +# +# Default: 8 +pp_multiline_define_body_indent = 8 # number + +# Whether to indent case statements between #if, #else, and #endif. +# Only applies to the indent of the preprocessor that the case statements +# directly inside of. +# +# Default: true +pp_indent_case = true # true/false + +# Whether to indent whole function definitions between #if, #else, and #endif. +# Only applies to the indent of the preprocessor that the function definition +# is directly inside of. +# +# Default: true +pp_indent_func_def = true # true/false + +# Whether to indent extern C blocks between #if, #else, and #endif. +# Only applies to the indent of the preprocessor that the extern block is +# directly inside of. +# +# Default: true +pp_indent_extern = true # true/false + +# How to indent braces directly inside #if, #else, and #endif. +# Requires pp_if_indent_code=true and only applies to the indent of the +# preprocessor that the braces are directly inside of. +# 0: No extra indent +# 1: Indent by one level +# -1: Preserve original indentation +# +# Default: 1 +pp_indent_brace = 1 # number + +# Whether to print warning messages for unbalanced #if and #else blocks. +# This will print a message in the following cases: +# - if an #ifdef block ends on a different indent level than +# where it started from. Example: +# +# #ifdef TEST +# int i; +# { +# int j; +# #endif +# +# - an #elif/#else block ends on a different indent level than +# the corresponding #ifdef block. Example: +# +# #ifdef TEST +# int i; +# #else +# } +# int j; +# #endif +pp_warn_unbalanced_if = false # true/false + +# +# Sort includes options +# + +# The regex for include category with priority 0. +include_category_0 = "" # string + +# The regex for include category with priority 1. +include_category_1 = "" # string + +# The regex for include category with priority 2. +include_category_2 = "" # string + +# +# Use or Do not Use options +# + +# true: indent_func_call_param will be used (default) +# false: indent_func_call_param will NOT be used +# +# Default: true +use_indent_func_call_param = true # true/false + +# The value of the indentation for a continuation line is calculated +# differently if the statement is: +# - a declaration: your case with QString fileName ... +# - an assignment: your case with pSettings = new QSettings( ... +# +# At the second case the indentation value might be used twice: +# - at the assignment +# - at the function call (if present) +# +# To prevent the double use of the indentation value, use this option with the +# value 'true'. +# +# true: indent_continue will be used only once +# false: indent_continue will be used every time (default) +# +# Requires indent_ignore_first_continue=false. +use_indent_continue_only_once = false # true/false + +# The indentation can be: +# - after the assignment, at the '[' character +# - at the beginning of the lambda body +# +# true: indentation will be at the beginning of the lambda body +# false: indentation will be after the assignment (default) +indent_cpp_lambda_only_once = false # true/false + +# Whether sp_after_angle takes precedence over sp_inside_fparen. This was the +# historic behavior, but is probably not the desired behavior, so this is off +# by default. +use_sp_after_angle_always = false # true/false + +# Whether to apply special formatting for Qt SIGNAL/SLOT macros. Essentially, +# this tries to format these so that they match Qt's normalized form (i.e. the +# result of QMetaObject::normalizedSignature), which can slightly improve the +# performance of the QObject::connect call, rather than how they would +# otherwise be formatted. +# +# See options_for_QT.cpp for details. +# +# Default: true +use_options_overriding_for_qt_macros = true # true/false + +# If true: the form feed character is removed from the list of whitespace +# characters. See https://en.cppreference.com/w/cpp/string/byte/isspace. +use_form_feed_no_more_as_whitespace_character = false # true/false + +# +# Warn levels - 1: error, 2: warning (default), 3: note +# + +# (C#) Warning is given if doing tab-to-\t replacement and we have found one +# in a C# verbatim string literal. +# +# Default: 2 +warn_level_tabs_found_in_verbatim_string_literals = 2 # unsigned number + +# Limit the number of loops. +# Used by uncrustify.cpp to exit from infinite loop. +# 0: no limit. +debug_max_number_of_loops = 0 # number + +# Set the number of the line to protocol; +# Used in the function prot_the_line if the 2. parameter is zero. +# 0: nothing protocol. +debug_line_number_to_protocol = 0 # number + +# Set the number of second(s) before terminating formatting the current file, +# 0: no timeout. +# only for linux +debug_timeout = 0 # number + +# Set the number of characters to be printed if the text is too long, +# 0: do not truncate. +debug_truncate = 0 # unsigned number + +# sort (or not) the tracking info. +# +# Default: true +debug_sort_the_tracks = true # true/false + +# decode (or not) the flags as a new line. +# only if the -p option is set. +debug_decode_the_flags = false # true/false + +# use (or not) the exit(EX_SOFTWARE) function. +# +# Default: true +debug_use_the_exit_function_pop = true # true/false + +# insert the number of the line at the beginning of each line +set_numbering_for_html_output = false # true/false + +# Meaning of the settings: +# Ignore - do not do any changes +# Add - makes sure there is 1 or more space/brace/newline/etc +# Force - makes sure there is exactly 1 space/brace/newline/etc, +# behaves like Add in some contexts +# Remove - removes space/brace/newline/etc +# +# +# - Token(s) can be treated as specific type(s) with the 'set' option: +# `set tokenType tokenString [tokenString...]` +# +# Example: +# `set BOOL __AND__ __OR__` +# +# tokenTypes are defined in src/token_enum.h, use them without the +# 'CT_' prefix: 'CT_BOOL' => 'BOOL' +# +# +# - Token(s) can be treated as type(s) with the 'type' option. +# `type tokenString [tokenString...]` +# +# Example: +# `type int c_uint_8 Rectangle` +# +# This can also be achieved with `set TYPE int c_uint_8 Rectangle` +# +# +# To embed whitespace in tokenStrings use the '\' escape character, or quote +# the tokenStrings. These quotes are supported: "'` +# +# +# - Support for the auto detection of languages through the file ending can be +# added using the 'file_ext' command. +# `file_ext langType langString [langString..]` +# +# Example: +# `file_ext CPP .ch .cxx .cpp.in` +# +# langTypes are defined in uncrusify_types.h in the lang_flag_e enum, use +# them without the 'LANG_' prefix: 'LANG_CPP' => 'CPP' +# +# +# - Custom macro-based indentation can be set up using 'macro-open', +# 'macro-else' and 'macro-close'. +# `(macro-open | macro-else | macro-close) tokenString` +# +# Example: +# `macro-open BEGIN_TEMPLATE_MESSAGE_MAP` +# `macro-open BEGIN_MESSAGE_MAP` +# `macro-close END_MESSAGE_MAP` +# +# +# option(s) with 'not default' value: 75 # From aeee5e6a6723e284bdac5b5fb02a01f0401df1f7 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 20 Feb 2025 19:55:57 +0100 Subject: [PATCH 1184/1333] nimble/ll: Fix padv interval check for scheduling We should use padv interval value in ticks for calculations, not in HCI units... --- nimble/controller/src/ble_ll_adv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 646e8b12a8..401fe2747e 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -2585,7 +2585,7 @@ ble_ll_adv_periodic_schedule_next(struct ble_ll_adv_sm *advsm) */ if (sync->auxptr_zero || (LL_TMR_GT(sch->end_time, advsm->padv_event_start + - advsm->periodic_adv_itvl))) { + ble_ll_tmr_u2t(advsm->padv_itvl_us)))) { STATS_INC(ble_ll_stats, periodic_chain_drop_event); ble_ll_sched_rmv_elem(&sync->sch); } From 25e54af0a26d6183516d6c6c0eb6be1246b6a02f Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 20 Feb 2025 13:51:01 +0100 Subject: [PATCH 1185/1333] nimble/ll: Make NRPA generation in active scan optional This adds a syscfg to disable NRPA generation by LL in active scan. This allows host to specify own NRPA as a random address and use it instead of the one generated by LL. Also this moves code to make SCAN_REQ/AUX_SCAN_REQ to common helper so we don't duplicate code. --- .../include/controller/ble_ll_scan.h | 9 ++- nimble/controller/src/ble_ll_scan.c | 68 ++++++++++--------- nimble/controller/src/ble_ll_scan_aux.c | 57 +--------------- nimble/controller/syscfg.yml | 10 +++ 4 files changed, 54 insertions(+), 90 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index 19d9cdd9c6..47c7437414 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -132,7 +132,7 @@ struct ble_ll_scan_sm uint8_t scan_rsp_cons_fails; uint8_t scan_rsp_cons_ok; uint8_t scan_peer_rpa[BLE_DEV_ADDR_LEN]; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) +#if MYNEWT_VAL(BLE_LL_SCAN_ACTIVE_SCAN_NRPA) ble_npl_time_t scan_nrpa_timer; uint8_t scan_nrpa[BLE_DEV_ADDR_LEN]; #endif @@ -250,7 +250,6 @@ void ble_ll_scan_interrupted(struct ble_ll_scan_sm *scansm); /* Called to halt currently running scan */ void ble_ll_scan_halt(void); -uint8_t *ble_ll_get_scan_nrpa(void); uint8_t ble_ll_scan_get_own_addr_type(void); uint8_t ble_ll_scan_get_filt_policy(void); uint8_t ble_ll_scan_get_filt_dups(void); @@ -266,6 +265,12 @@ int ble_ll_scan_have_rxd_scan_rsp(uint8_t *addr, uint8_t txadd, uint8_t ext_adv, void ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t txadd, uint8_t ext_adv, uint16_t adi); +struct ble_ll_scan_sm *ble_ll_scan_sm_get(void); + +void ble_ll_scan_make_req_pdu(struct ble_ll_scan_sm *scansm, uint8_t *pdu, + uint8_t *hdr_byte, uint8_t adva_type, + const uint8_t *adva, int rpa_index); + int ble_ll_scan_rx_filter(uint8_t own_addr_type, uint8_t scan_filt_policy, struct ble_ll_scan_addr_data *addrd, uint8_t *scan_ok); diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index f2c52f19e3..d758d899f1 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -175,7 +175,7 @@ ble_ll_scan_req_backoff(struct ble_ll_scan_sm *scansm, int success) BLE_LL_ASSERT(scansm->backoff_count <= 256); } -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) +#if MYNEWT_VAL(BLE_LL_SCAN_ACTIVE_SCAN_NRPA) static void ble_ll_scan_refresh_nrpa(struct ble_ll_scan_sm *scansm) { @@ -191,17 +191,13 @@ ble_ll_scan_refresh_nrpa(struct ble_ll_scan_sm *scansm) scansm->scan_nrpa_timer = now + ble_ll_resolv_get_rpa_tmo(); } } +#endif -uint8_t * -ble_ll_get_scan_nrpa(void) +struct ble_ll_scan_sm * +ble_ll_scan_sm_get(void) { - struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm; - - ble_ll_scan_refresh_nrpa(scansm); - - return scansm->scan_nrpa; + return &g_ble_ll_scan_sm; } -#endif uint8_t ble_ll_scan_get_own_addr_type(void) @@ -241,30 +237,26 @@ ble_ll_scan_backoff_update(int success) ble_ll_scan_req_backoff(scansm, success); } -static void -ble_ll_scan_req_pdu_prepare(struct ble_ll_scan_sm *scansm, - const uint8_t *adv_addr, uint8_t adv_addr_type, - int8_t rpa_index) +void +ble_ll_scan_make_req_pdu(struct ble_ll_scan_sm *scansm, uint8_t *pdu, + uint8_t *hdr_byte, uint8_t adva_type, + const uint8_t *adva, int rpa_index) { - uint8_t hdr_byte; - struct ble_ll_scan_pdu_data *pdu_data; uint8_t *scana; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) struct ble_ll_resolv_entry *rl; uint8_t rpa[BLE_DEV_ADDR_LEN]; #endif - pdu_data = &scansm->pdu_data; - /* Construct first PDU header byte */ - hdr_byte = BLE_ADV_PDU_TYPE_SCAN_REQ; - if (adv_addr_type) { - hdr_byte |= BLE_ADV_PDU_HDR_RXADD_RAND; + *hdr_byte = BLE_ADV_PDU_TYPE_SCAN_REQ; + if (adva_type) { + *hdr_byte |= BLE_ADV_PDU_HDR_RXADD_RAND; } /* Determine ScanA */ if (scansm->own_addr_type & 0x01) { - hdr_byte |= BLE_ADV_PDU_HDR_TXADD_RAND; + *hdr_byte |= BLE_ADV_PDU_HDR_TXADD_RAND; scana = g_random_addr; } else { scana = g_dev_addr; @@ -278,12 +270,12 @@ ble_ll_scan_req_pdu_prepare(struct ble_ll_scan_sm *scansm, rl = NULL; } - /* - * If device is on RL and we have local IRK, we use RPA generated using - * that IRK as ScanA. Otherwise we use NRPA as ScanA to prevent our - * device from being tracked when doing an active scan (Core 5.1, Vol 6, - * Part B, section 6.3) - */ + /* Check if we should use RPA/NRPA instead of public/random address: + * - use RPA if device is on RL and has local IRK set + * - use RPA generated from local IRK if set + * - use NRPA if allowed by configuration + * */ + if (rl && rl->rl_has_local) { ble_ll_resolv_get_priv_addr(rl, 1, rpa); scana = rpa; @@ -291,19 +283,29 @@ ble_ll_scan_req_pdu_prepare(struct ble_ll_scan_sm *scansm, if (ble_ll_resolv_local_rpa_get(scansm->own_addr_type & 0x01, rpa) == 0) { scana = rpa; } else { +#if MYNEWT_VAL(BLE_LL_SCAN_ACTIVE_SCAN_NRPA) ble_ll_scan_refresh_nrpa(scansm); scana = scansm->scan_nrpa; +#endif } } - hdr_byte |= BLE_ADV_PDU_HDR_TXADD_RAND; + *hdr_byte |= BLE_ADV_PDU_HDR_TXADD_RAND; } #endif - /* Save scan request data */ - pdu_data->hdr_byte = hdr_byte; - memcpy(pdu_data->scana, scana, BLE_DEV_ADDR_LEN); - memcpy(pdu_data->adva, adv_addr, BLE_DEV_ADDR_LEN); + memcpy(pdu, scana, BLE_DEV_ADDR_LEN); + memcpy(pdu + 6, adva, BLE_DEV_ADDR_LEN); +} + +static void +ble_ll_scan_req_pdu_prepare(struct ble_ll_scan_sm *scansm, + const uint8_t *adv_addr, uint8_t adv_addr_type, + int8_t rpa_index) +{ + ble_ll_scan_make_req_pdu(scansm, scansm->pdu_data.scana, + &scansm->pdu_data.hdr_byte, adv_addr_type, adv_addr, + rpa_index); } static uint8_t @@ -2751,7 +2753,7 @@ ble_ll_scan_common_init(void) scansm->scan_phys[PHY_CODED].phy = BLE_PHY_CODED; #endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) +#if MYNEWT_VAL(BLE_LL_SCAN_ACTIVE_SCAN_NRPA) /* Make sure we'll generate new NRPA if necessary */ scansm->scan_nrpa_timer = ble_npl_time_get(); #endif diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index b61f729db1..0596cd6f93 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -1144,62 +1144,9 @@ static uint8_t ble_ll_scan_aux_scan_req_tx_pdu_cb(uint8_t *dptr, void *arg, uint8_t *hdr_byte) { struct ble_ll_scan_aux_data *aux = arg; - uint8_t *scana; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - struct ble_ll_resolv_entry *rl; - uint8_t rpa[BLE_DEV_ADDR_LEN]; -#endif - uint8_t hb; - uint8_t own_addr_type = ble_ll_scan_get_own_addr_type(); - - hb = BLE_ADV_PDU_TYPE_SCAN_REQ; - - /* ScanA */ - if (own_addr_type & 0x01) { - hb |= BLE_ADV_PDU_HDR_TXADD_RAND; - scana = g_random_addr; - } else { - scana = g_dev_addr; - } - -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - if (own_addr_type & 0x02) { - if (aux->rpa_index >=0) { - rl = &g_ble_ll_resolv_list[aux->rpa_index]; - } else { - rl = NULL; - } - - /* - * If device is on RL and we have local IRK, we use RPA generated using - * that IRK as ScanA. Otherwise we use NRPA or RPA from global local IRK - * as ScanA to prevent our device from being tracked when doing - * an active scan - * ref: Core 5.2, Vol 6, Part B, section 6.3) - */ - if (rl && rl->rl_has_local) { - ble_ll_resolv_get_priv_addr(rl, 1, rpa); - scana = rpa; - } else { - if (ble_ll_resolv_local_rpa_get(own_addr_type & 0x01, rpa) == 0) { - scana = rpa; - } else { - scana = ble_ll_get_scan_nrpa(); - } - } - - hb |= BLE_ADV_PDU_HDR_TXADD_RAND; - } -#endif - memcpy(dptr, scana, BLE_DEV_ADDR_LEN); - - /* AdvA */ - if (aux->adva_type) { - hb |= BLE_ADV_PDU_HDR_RXADD_RAND; - } - memcpy(dptr + BLE_DEV_ADDR_LEN, aux->adva, BLE_DEV_ADDR_LEN); - *hdr_byte = hb; + ble_ll_scan_make_req_pdu(ble_ll_scan_sm_get(), dptr, hdr_byte, + aux->adva_type, aux->adva, aux->rpa_index); return BLE_DEV_ADDR_LEN * 2; } diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index bc4860c1bd..d26f7006e4 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -370,6 +370,16 @@ syscfg.defs: concurrently (Core 5.2, Vol 6, Part B, 4.4.2.2.2). value: MYNEWT_VAL(BLE_LL_EXT_ADV_AUX_PTR_CNT) + BLE_LL_SCAN_ACTIVE_SCAN_NRPA: + description: > + The controller will automatically generate NRPA for scan requests + if host requested to use privacy (i.e. 0x02 or 0x03 own address + type) but the peer is not on the resolving list. + If disabled, public or random address will be used. + value: 1 + restrictions: + - BLE_LL_CFG_FEAT_LL_PRIVACY if 1 + BLE_LL_PUBLIC_DEV_ADDR: description: > Set public device address. Address is specified as 48-bit number. From e6f0aa1243f6dbce21977f37203138efc01f1ae4 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 20 Feb 2025 18:04:30 +0100 Subject: [PATCH 1186/1333] nimble/ll: Fix transmitting fragmented HCI ACL data For whatever reason HCI ACL packets with empty payload are allowed, but at the same time we are not allowed to send and empty fragment with LLID=0b00 over the air. We need to wait for the 1st non-empty payload and "recombine" it with the empty payload(s) to form a proper payload with LLID=0b00. We don't really need to recombine payloads, instead we can just count and then discard initial empty payloads and the update non-empty payload accordingly. See Core 6.0, Vol 6, Part B, 2.4.1. --- .../include/controller/ble_ll_conn.h | 1 + nimble/controller/src/ble_ll.c | 4 +- nimble/controller/src/ble_ll_conn.c | 37 +++++++++++++++++-- nimble/controller/src/ble_ll_dtm.c | 2 +- nimble/include/nimble/ble.h | 2 +- 5 files changed, 39 insertions(+), 7 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 1d29063bf8..c0ba84afad 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -344,6 +344,7 @@ struct ble_ll_conn_sm /* Packet transmit queue */ struct os_mbuf *cur_tx_pdu; STAILQ_HEAD(conn_txq_head, os_mbuf_pkthdr) conn_txq; + uint8_t conn_txq_num_zero_pkt; /* List entry for active/free connection pools */ union { diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 4e0a74c537..8c22c89fb5 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -847,7 +847,7 @@ ble_ll_tx_pkt_in(void) /* Do some basic error checking */ pb = handle & 0x3000; - if ((pkthdr->omp_len != length) || (pb > 0x1000) || (length == 0)) { + if ((pkthdr->omp_len != length) || (pb > 0x1000)) { /* This is a bad ACL packet. Count a stat and free it */ STATS_INC(ble_ll_stats, bad_acl_hdr); os_mbuf_free_chain(om); @@ -1548,7 +1548,7 @@ ble_ll_mbuf_init(struct os_mbuf *m, uint8_t pdulen, uint8_t hdr) /* Set BLE transmit header */ ble_hdr = BLE_MBUF_HDR_PTR(m); - ble_hdr->txinfo.flags = 0; + ble_hdr->txinfo.num_data_pkt = 0; ble_hdr->txinfo.offset = 0; ble_hdr->txinfo.pyld_len = pdulen; ble_hdr->txinfo.hdr_byte = hdr; diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 65ff4cb0d9..dcaa3aae5f 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1301,7 +1301,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) m->om_data = (uint8_t *)&empty_pdu; m->om_data += BLE_MBUF_MEMBLOCK_OVERHEAD; ble_hdr = &empty_pdu.ble_hdr; - ble_hdr->txinfo.flags = 0; + ble_hdr->txinfo.num_data_pkt = 0; ble_hdr->txinfo.offset = 0; ble_hdr->txinfo.pyld_len = 0; } @@ -2034,6 +2034,7 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) /* Initialize transmit queue and ack/flow control elements */ STAILQ_INIT(&connsm->conn_txq); + connsm->conn_txq_num_zero_pkt = 0; connsm->cur_tx_pdu = NULL; connsm->tx_seqnum = 0; connsm->next_exp_seqnum = 0; @@ -3845,7 +3846,8 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) #if (BLETEST_THROUGHPUT_TEST == 1) bletest_completed_pkt(connsm->conn_handle); #endif - ++connsm->completed_pkts; + BLE_LL_ASSERT(txhdr->txinfo.num_data_pkt >= 1); + connsm->completed_pkts += txhdr->txinfo.num_data_pkt; if (connsm->completed_pkts > 2) { ble_ll_event_add(&g_ble_ll_data.ll_comp_pkt_ev); } @@ -3946,17 +3948,46 @@ ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm *connsm, struct os_mbuf *om, os_sr_t sr; struct os_mbuf_pkthdr *pkthdr; struct ble_mbuf_hdr *ble_hdr; + uint8_t num_pkt; int lifo; + /* We cannot send empty payload with LLID=0b10. Instead, we need to wait for + * non-empty payload and combine it together. Since we don't really recombine + * fragments we just count number of consecutive empty payloads and use 1st + * non-empty as a start packet. Empty payloads can be freed immediately as + * we don't need to enqueue them. + * + * Reference: Core 6.0, Vol 6, Part B, 2.4.1 + */ + if ((length == 0) && + ((hdr_byte == BLE_LL_LLID_DATA_START) || (connsm->conn_txq_num_zero_pkt > 0))) { + connsm->conn_txq_num_zero_pkt++; + os_mbuf_free_chain(om); + return; + } + /* Set mbuf length and packet length if a control PDU */ if (hdr_byte == BLE_LL_LLID_CTRL) { om->om_len = length; OS_MBUF_PKTHDR(om)->omp_len = length; + num_pkt = 0; + } else { + num_pkt = 1; + + /* This is the 1st non-empty data fragment so adjust LLID accordingly. + * num_pkt is updated to make sure we send back proper numbber of + * completed packets back to host. + */ + if (connsm->conn_txq_num_zero_pkt) { + hdr_byte = BLE_LL_LLID_DATA_START; + num_pkt += connsm->conn_txq_num_zero_pkt; + connsm->conn_txq_num_zero_pkt = 0; + } } /* Set BLE transmit header */ ble_hdr = BLE_MBUF_HDR_PTR(om); - ble_hdr->txinfo.flags = 0; + ble_hdr->txinfo.num_data_pkt = num_pkt; ble_hdr->txinfo.offset = 0; ble_hdr->txinfo.hdr_byte = hdr_byte; diff --git a/nimble/controller/src/ble_ll_dtm.c b/nimble/controller/src/ble_ll_dtm.c index c57a1357a1..c7823e0f1a 100644 --- a/nimble/controller/src/ble_ll_dtm.c +++ b/nimble/controller/src/ble_ll_dtm.c @@ -308,7 +308,7 @@ ble_ll_dtm_tx_create_ctx(uint8_t packet_payload, uint8_t len, /* Set BLE transmit header */ ble_hdr = BLE_MBUF_HDR_PTR(m); - ble_hdr->txinfo.flags = 0; + ble_hdr->txinfo.num_data_pkt = 0; ble_hdr->txinfo.offset = 0; ble_hdr->txinfo.pyld_len = len; ble_hdr->txinfo.hdr_byte = packet_payload; diff --git a/nimble/include/nimble/ble.h b/nimble/include/nimble/ble.h index c42d5c5ba4..a2add5d79a 100644 --- a/nimble/include/nimble/ble.h +++ b/nimble/include/nimble/ble.h @@ -120,7 +120,7 @@ struct ble_mbuf_hdr_rxinfo /* Transmit info. NOTE: no flags defined */ struct ble_mbuf_hdr_txinfo { - uint8_t flags; + uint8_t num_data_pkt; uint8_t hdr_byte; uint16_t offset; uint16_t pyld_len; From f1379c78a3829c9360f3e5d38906c4db7389df0e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 21 Feb 2025 12:32:29 +0100 Subject: [PATCH 1187/1333] nimble/ll: Fix HCI Number Of Completed Packets event We can (and shall) keep sending nocp event with ncp=0 periodically but *only* if we have HCI data packets enqueued. Currently we check if txq is empty but that doesn't take into account that the only queued PDUs may be LL Control. This adds extra counter to track number of data PDUs queued in conn. --- nimble/controller/include/controller/ble_ll_conn.h | 1 + nimble/controller/src/ble_ll_conn.c | 2 ++ nimble/controller/src/ble_ll_conn_hci.c | 6 +++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index c0ba84afad..347f4653ee 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -344,6 +344,7 @@ struct ble_ll_conn_sm /* Packet transmit queue */ struct os_mbuf *cur_tx_pdu; STAILQ_HEAD(conn_txq_head, os_mbuf_pkthdr) conn_txq; + uint8_t conn_txq_num_data_pkt; uint8_t conn_txq_num_zero_pkt; /* List entry for active/free connection pools */ diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index dcaa3aae5f..90d5a8cac5 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2034,6 +2034,7 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm) /* Initialize transmit queue and ack/flow control elements */ STAILQ_INIT(&connsm->conn_txq); + connsm->conn_txq_num_data_pkt = 0; connsm->conn_txq_num_zero_pkt = 0; connsm->cur_tx_pdu = NULL; connsm->tx_seqnum = 0; @@ -4046,6 +4047,7 @@ ble_ll_conn_enqueue_pkt(struct ble_ll_conn_sm *connsm, struct os_mbuf *om, } else { STAILQ_INSERT_TAIL(&connsm->conn_txq, pkthdr, omp_next); } + connsm->conn_txq_num_data_pkt += num_pkt; OS_EXIT_CRITICAL(sr); } diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 394db6f6b1..fae4b31a9e 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -310,6 +310,8 @@ ble_ll_conn_num_comp_pkts_event_send(struct ble_ll_conn_sm *connsm) ev->completed[0].packets = htole16(connsm->completed_pkts); hci_ev->length += sizeof(ev->completed[0]); + BLE_LL_ASSERT(connsm->conn_txq_num_data_pkt >= connsm->completed_pkts); + connsm->conn_txq_num_data_pkt -= connsm->completed_pkts; connsm->completed_pkts = 0; ble_ll_hci_event_send(hci_ev); @@ -330,7 +332,7 @@ ble_ll_conn_num_comp_pkts_event_send(struct ble_ll_conn_sm *connsm) * event and that either has packets enqueued or has completed packets. */ if ((connsm->conn_state != BLE_LL_CONN_STATE_IDLE) && - (connsm->completed_pkts || !STAILQ_EMPTY(&connsm->conn_txq))) { + (connsm->completed_pkts || connsm->conn_txq_num_data_pkt)) { /* If no buffer, get one, If cant get one, leave. */ if (!hci_ev) { hci_ev = ble_transport_alloc_evt(0); @@ -351,6 +353,8 @@ ble_ll_conn_num_comp_pkts_event_send(struct ble_ll_conn_sm *connsm) hci_ev->length += sizeof(ev->completed[ev->count]); ev->count++; + BLE_LL_ASSERT(connsm->conn_txq_num_data_pkt >= connsm->completed_pkts); + connsm->conn_txq_num_data_pkt -= connsm->completed_pkts; connsm->completed_pkts = 0; /* Send now if the buffer is full. */ From c6b1ea9efb7220341e415d2277a2629fbe0a8b39 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 17 Feb 2025 18:36:40 +0100 Subject: [PATCH 1188/1333] nimble/ll: Fix DLE without coded phy Requested max time should be limited to 2120us if LL doesn't support coded phy. --- nimble/controller/src/ble_ll_conn.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 90d5a8cac5..1864f8f369 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1838,6 +1838,9 @@ ble_ll_conn_set_data_len(struct ble_ll_conn_sm *connsm, tx_time = MIN(tx_time, BLE_LL_CONN_SUPP_TIME_MAX_UNCODED); rx_time = MIN(rx_time, BLE_LL_CONN_SUPP_TIME_MAX_UNCODED); } +#else + tx_time = MIN(tx_time, BLE_LL_CONN_SUPP_TIME_MAX_UNCODED); + rx_time = MIN(rx_time, BLE_LL_CONN_SUPP_TIME_MAX_UNCODED); #endif if (connsm->max_tx_time != tx_time) { From f9161f375565c44df7362f8ed53b0b74ab0d9813 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 17 Feb 2025 19:06:33 +0100 Subject: [PATCH 1189/1333] nimble/ll: Fix connection update HCI event HCI LE Connection Update Complete event shall only be sent if this is a result of request issued by host or if any connection parameter has changed. We should not send the event if this was just an anchor move requested by peripheral. --- nimble/controller/include/controller/ble_ll_conn.h | 1 + nimble/controller/src/ble_ll_conn.c | 9 +++++---- nimble/controller/src/ble_ll_conn_hci.c | 3 +++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 347f4653ee..2b0c606dd6 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -119,6 +119,7 @@ struct ble_ll_conn_sm_flags { uint32_t terminate_ind_rxd_acked : 1; uint32_t conn_update_sched : 1; uint32_t conn_update_use_cp : 1; + uint32_t conn_update_host_initd : 1; uint32_t conn_update_host_w4reply : 1; uint32_t conn_update_host_w4event : 1; uint32_t chanmap_update_sched : 1; diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 1864f8f369..52446b6471 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -2542,15 +2542,16 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm) if (connsm->flags.conn_update_sched && (connsm->event_cntr == connsm->conn_update_req.instant)) { - /* Set flag so we send connection update event */ + /* Set flag to send event to host if request was issued by host or + * any of parameters changed (i.e. skip on anchor moves) + */ upd = &connsm->conn_update_req; - if (CONN_IS_CENTRAL(connsm) || - (CONN_IS_PERIPHERAL(connsm) && - IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_CONN_PARAM_REQ)) || + if (connsm->flags.conn_update_host_initd || (connsm->conn_itvl != upd->interval) || (connsm->periph_latency != upd->latency) || (connsm->supervision_tmo != upd->timeout)) { connsm->flags.conn_update_host_w4event = 1; + connsm->flags.conn_update_host_initd = 0; } #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index fae4b31a9e..158464ed53 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1134,6 +1134,9 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) connsm->css_slot_idx_pending = connsm->css_slot_idx; #endif + /* Mark procedure as host initiated */ + connsm->flags.conn_update_host_initd = 1; + /* Start the control procedure */ ble_ll_ctrl_proc_start(connsm, ctrl_proc, NULL); } From 890be280a318b6e447acaa929ff22a2c713044e4 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 20 Feb 2025 14:00:28 +0100 Subject: [PATCH 1190/1333] nimble/ll: Update chanmap in BIGInfo after completed chanmap update Channel map needs to be update in BIGInfo after change since BIGInfo is precalculated and not generated before each tx. --- nimble/controller/src/ble_ll_iso_big.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index de895b1eac..1b4e50d363 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -255,6 +255,18 @@ ble_ll_iso_big_last_tx_timestamp_get(struct ble_ll_iso_bis *bis, return 0; } +static void +ble_ll_iso_big_biginfo_chanmap_update(struct ble_ll_iso_big *big) +{ + uint8_t *buf; + + buf = &big->biginfo[23]; + + /* chm, phy */ + memcpy(buf, big->chan_map, 5); + buf[4] |= (big->phy - 1) << 5; +} + static void ble_ll_iso_big_biginfo_calc(struct ble_ll_iso_big *big, uint32_t seed_aa) { @@ -296,8 +308,7 @@ ble_ll_iso_big_biginfo_calc(struct ble_ll_iso_big *big, uint32_t seed_aa) /* chm, phy */ memcpy(buf, big->chan_map, 5); - buf[4] |= (big->phy - 1) << 5; - buf += 5; + ble_ll_iso_big_biginfo_chanmap_update(big); /* bis_payload_cnt, framing */ memset(buf, 0x00, 5); @@ -437,6 +448,8 @@ ble_ll_iso_big_chan_map_update_complete(struct ble_ll_iso_big *big) { memcpy(big->chan_map, big->chan_map_new, BLE_LL_CHAN_MAP_LEN); big->chan_map_used = ble_ll_utils_chan_map_used_get(big->chan_map); + + ble_ll_iso_big_biginfo_chanmap_update(big); } static void From 0ef41fe1c9dedafc766d7a4635df2ee84e0880df Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 26 Feb 2025 09:13:06 +0100 Subject: [PATCH 1191/1333] nimble/ll: Fix default value for BLE_LL_SCAN_ACTIVE_SCAN_NRPA Intention was to default to 1 if privacy is enabled, not forcing privacy. --- nimble/controller/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index d26f7006e4..b6770f0879 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -376,7 +376,7 @@ syscfg.defs: if host requested to use privacy (i.e. 0x02 or 0x03 own address type) but the peer is not on the resolving list. If disabled, public or random address will be used. - value: 1 + value: MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) restrictions: - BLE_LL_CFG_FEAT_LL_PRIVACY if 1 From 7df6d20409a60a0369c1db852dd79f2cbe3d56cd Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 26 Feb 2025 01:50:41 +0100 Subject: [PATCH 1192/1333] nimble/ll: Fix sync check in aux This fixes condition to check if AUX_ADV_IND has both ADI and SyncInfo before passing it to sync code. Invalid condition allowed that either ADI *or* SyncInfo is present in whch case the offset to SyncInfo in PDU was calculated incorrectly and the resulting sync sm used random data and thus failed. --- nimble/controller/src/ble_ll_scan_aux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 0596cd6f93..ceb094c027 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -1412,8 +1412,8 @@ ble_ll_scan_aux_sync_check(struct os_mbuf *rxpdu, eh_data = &rxbuf[4]; /* Need ADI and SyncInfo */ - if (!(eh_flags & ((1 << BLE_LL_EXT_ADV_SYNC_INFO_BIT) | - (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)))) { + if (!(eh_flags & (1 << BLE_LL_EXT_ADV_DATA_INFO_BIT)) || + !(eh_flags & (1 << BLE_LL_EXT_ADV_SYNC_INFO_BIT))) { return; } From d1b788578e433f1ab6c271acb861392a3b035b10 Mon Sep 17 00:00:00 2001 From: Mynewt Bot Date: Wed, 26 Feb 2025 08:48:14 +0000 Subject: [PATCH 1193/1333] porting: Update ports syscfg --- porting/npl/riot/include/syscfg/syscfg.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index e6155c7b62..35d448cc7a 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1624,6 +1624,10 @@ #define MYNEWT_VAL_BLE_LL_SCA (60) #endif +#ifndef MYNEWT_VAL_BLE_LL_SCAN_ACTIVE_SCAN_NRPA +#define MYNEWT_VAL_BLE_LL_SCAN_ACTIVE_SCAN_NRPA (0) +#endif + #ifndef MYNEWT_VAL_BLE_LL_SCAN_AUX_SEGMENT_CNT #define MYNEWT_VAL_BLE_LL_SCAN_AUX_SEGMENT_CNT (0) #endif From caaf8e4678839f37750b130ce52f1163ea96ee52 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 20 Feb 2025 14:10:02 +0100 Subject: [PATCH 1194/1333] nimble/ll: Disable HCI LE Set Host Feat if no controllable features We don't need to support this command if there are no host-controllable features present in LL. --- nimble/controller/src/ble_ll.c | 3 +++ nimble/controller/src/ble_ll_hci.c | 2 +- nimble/controller/src/ble_ll_hci_supp_cmd.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 8c22c89fb5..238bfad1d3 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -1464,6 +1464,7 @@ ble_ll_read_supp_features(void) return g_ble_ll_data.ll_supp_features; } +#if BLE_LL_HOST_CONTROLLED_FEATURES /** * Sets the features controlled by the host. * @@ -1502,6 +1503,8 @@ ble_ll_set_host_feat(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_SUCCESS; } +#endif + /** * Flush a link layer packet queue. * diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 4446f8a9b0..d074733019 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1301,7 +1301,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, } break; #endif /* BLE_LL_ISO */ -#if MYNEWT_VAL(BLE_VERSION) >= 52 +#if BLE_LL_HOST_CONTROLLED_FEATURES case BLE_HCI_OCF_LE_SET_HOST_FEATURE: rc = ble_ll_set_host_feat(cmdbuf, len); break; diff --git a/nimble/controller/src/ble_ll_hci_supp_cmd.c b/nimble/controller/src/ble_ll_hci_supp_cmd.c index eb4182ed6b..75155060fc 100644 --- a/nimble/controller/src/ble_ll_hci_supp_cmd.c +++ b/nimble/controller/src/ble_ll_hci_supp_cmd.c @@ -280,7 +280,7 @@ static const uint8_t octet_43 = OCTET( ); static const uint8_t octet_44 = OCTET( -#if MYNEWT_VAL(BLE_VERSION) >= 52 +#if BLE_LL_HOST_CONTROLLED_FEATURES BIT(1) /* HCI LE Set Host Feature */ #endif ); From 486d43caaf2ea73ad9fdf559922969e8d37f5c5b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 20 Feb 2025 18:19:31 +0100 Subject: [PATCH 1195/1333] nimble/ll: Update HCI supported commands bitmask --- nimble/controller/src/ble_ll_hci_supp_cmd.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_hci_supp_cmd.c b/nimble/controller/src/ble_ll_hci_supp_cmd.c index 75155060fc..abf292222b 100644 --- a/nimble/controller/src/ble_ll_hci_supp_cmd.c +++ b/nimble/controller/src/ble_ll_hci_supp_cmd.c @@ -132,6 +132,14 @@ static const uint8_t octet_28 = OCTET( #endif ); +static const uint8_t octet_32 = OCTET( +#if (MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL)) && \ + MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) + BIT(4) /* HCI Read Authenticated Payload Timeout */ + BIT(5) /* HCI Write Authenticated Payload Timeout */ +#endif +); + static const uint8_t octet_33 = OCTET( #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) BIT(4) /* HCI LE Remote Connection Parameter Request Reply */ @@ -328,7 +336,7 @@ static const uint8_t g_ble_ll_hci_supp_cmds[64] = { 0, 0, 0, - 0, + octet_32, octet_33, octet_34, octet_35, From ded0999a47eb62d6c23dd0d4fc8c1957c973c11a Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 20 Feb 2025 18:30:18 +0100 Subject: [PATCH 1196/1333] nimble/ll: Add HCI Read Transmit Power Level command support This command is mandatory if central or peripheral roles are supported. --- nimble/controller/src/ble_ll_conn_hci.c | 34 +++++++++++++++++++++ nimble/controller/src/ble_ll_conn_priv.h | 3 ++ nimble/controller/src/ble_ll_hci.c | 5 +++ nimble/controller/src/ble_ll_hci_supp_cmd.c | 3 ++ 4 files changed, 45 insertions(+) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 158464ed53..20ad4c1b8c 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -32,6 +32,7 @@ #include "controller/ble_ll_ctrl.h" #include "controller/ble_ll_scan.h" #include "controller/ble_ll_adv.h" +#include "ble_ll_priv.h" #include "ble_ll_conn_priv.h" #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) @@ -1939,6 +1940,39 @@ ble_ll_conn_hci_wr_auth_pyld_tmo(const uint8_t *cmdbuf, uint8_t len, } #endif +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) +int +ble_ll_conn_hci_cb_read_tx_pwr(const uint8_t *cmdbuf, uint8_t len, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_cb_read_tx_pwr_cp *cmd = (const void *)cmdbuf; + struct ble_hci_cb_read_tx_pwr_rp *rsp = (void *)rspbuf; + struct ble_ll_conn_sm *connsm; + uint16_t handle; + + if (len != sizeof(*cmd)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + if (cmd->type != 0x01) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + handle = le16toh(cmd->conn_handle); + connsm = ble_ll_conn_find_by_handle(handle); + if (!connsm) { + return BLE_ERR_UNK_CONN_ID; + } + + rsp->conn_handle = cmd->conn_handle; + rsp->tx_level = g_ble_ll_tx_power; + + *rsplen = sizeof(*rsp); + + return BLE_ERR_SUCCESS; +} +#endif + #if MYNEWT_VAL(BLE_LL_PHY) /** * Read current phy for connection (OGF=8, OCF==0x0030) diff --git a/nimble/controller/src/ble_ll_conn_priv.h b/nimble/controller/src/ble_ll_conn_priv.h index 954a27663a..460a836ff0 100644 --- a/nimble/controller/src/ble_ll_conn_priv.h +++ b/nimble/controller/src/ble_ll_conn_priv.h @@ -227,6 +227,9 @@ int ble_ll_conn_hci_wr_auth_pyld_tmo(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); int ble_ll_conn_hci_rd_auth_pyld_tmo(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); +int ble_ll_conn_hci_cb_read_tx_pwr(const uint8_t *cmdbuf, uint8_t len, + uint8_t *rspbuf, uint8_t *rsplen); + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE) int ble_ll_conn_req_peer_sca(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index d074733019..93fac9d604 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1541,6 +1541,11 @@ ble_ll_hci_ctlr_bb_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, rc = ble_ll_reset(); } break; +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + case BLE_HCI_OCF_CB_READ_TX_PWR: + rc = ble_ll_conn_hci_cb_read_tx_pwr(cmdbuf, len, rspbuf, rsplen); + break; +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) case BLE_HCI_OCF_CB_SET_CTLR_TO_HOST_FC: rc = ble_ll_hci_cb_set_ctrlr_to_host_fc(cmdbuf, len); diff --git a/nimble/controller/src/ble_ll_hci_supp_cmd.c b/nimble/controller/src/ble_ll_hci_supp_cmd.c index abf292222b..d9d6bd6045 100644 --- a/nimble/controller/src/ble_ll_hci_supp_cmd.c +++ b/nimble/controller/src/ble_ll_hci_supp_cmd.c @@ -45,6 +45,9 @@ static const uint8_t octet_5 = OCTET( ); static const uint8_t octet_10 = OCTET( +#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) + BIT(2) /* HCI Read Transmit Power Level */ +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL) BIT(5) /* HCI Set Controller To Host Flow Control */ BIT(6) /* HCI Host Buffer Size */ From 61d554190740367263cb6b7192e504eb1cf61ad8 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 20 Feb 2025 11:06:25 +0100 Subject: [PATCH 1197/1333] nimble/host: Remove outdated PTS tests results Those are greatly outdated and PTS is now mainly tested via automated tools like AutoPTS. --- .rat-excludes | 6 - nimble/host/pts/README.txt | 8 - nimble/host/pts/pts-gap.txt | 367 ------ nimble/host/pts/pts-gatt.txt | 508 -------- nimble/host/pts/pts-l2cap.txt | 304 ----- nimble/host/pts/pts-sm.txt | 310 ----- .../host/pts/tpg/94654-20170317-085122560.tpg | 1026 ----------------- .../host/pts/tpg/94654-20170317-085441153.pts | 289 ----- qualification/README.txt | 33 + 9 files changed, 33 insertions(+), 2818 deletions(-) delete mode 100644 nimble/host/pts/README.txt delete mode 100644 nimble/host/pts/pts-gap.txt delete mode 100644 nimble/host/pts/pts-gatt.txt delete mode 100644 nimble/host/pts/pts-l2cap.txt delete mode 100644 nimble/host/pts/pts-sm.txt delete mode 100644 nimble/host/pts/tpg/94654-20170317-085122560.tpg delete mode 100644 nimble/host/pts/tpg/94654-20170317-085441153.pts create mode 100644 qualification/README.txt diff --git a/.rat-excludes b/.rat-excludes index 0bd74f7249..d465abc867 100644 --- a/.rat-excludes +++ b/.rat-excludes @@ -8,12 +8,6 @@ docs RELEASE_NOTES.md .gitignore README.md -pts-gap.txt -pts-gatt.txt -pts-l2cap.txt -pts-sm.txt -94654-20170317-085122560.tpg -94654-20170317-085441153.pts uncrustify.cfg .style_ignored_dirs .mailmap diff --git a/nimble/host/pts/README.txt b/nimble/host/pts/README.txt deleted file mode 100644 index bb03b18caf..0000000000 --- a/nimble/host/pts/README.txt +++ /dev/null @@ -1,8 +0,0 @@ -This folder contains qualification tests results against BT SIG Profile Test -Suite. - -pts-FOO.txt files contain result for specific profiles or protocols. This -includes PTS version, test date, enabled tests, results etc. - -In addition to tests results 'tpg' folder constains Test Plang Generator -configuration files that can be imported by PTS for tests configuration. diff --git a/nimble/host/pts/pts-gap.txt b/nimble/host/pts/pts-gap.txt deleted file mode 100644 index 29ed2446ea..0000000000 --- a/nimble/host/pts/pts-gap.txt +++ /dev/null @@ -1,367 +0,0 @@ -PTS test results for GAP - -PTS version: 7.5.0 -Tested: 27-Sept-2019 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- - -GAP/BROB/BCST/BV-01-C PASS advertise-configure legacy=1 connectable=0 scannable=0 -GAP/BROB/BCST/BV-02-C PASS advertise-configure legacy=1 connectable=0 scannable=0 - -GAP/BROB/BCST/BV-03-C PASS set irk= e.g: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:11 - Note: in PTS IXIT please set: - TSPX_iut_device_IRK_for_resolvable_privacy_address_generation_procedure=11000000000000000000000000000000 - set advertise-set-adv-data name= flags=4 - advertise-configure connectable=0 scannable=0 own_addr_type=rpa_pub -GAP/BROB/BCST/BV-04-C PASS TSPX_advertising_data=07086E696D626C65 - advertise-set-adv-data name=nimble - set addr_type=random addr=01:3e:56:f7:46:21 - advertise-configure connectable=0 scannable=0 own_addr_type=random -GAP/BROB/BCST/BV-05-C N/A -GAP/BROB/OBSV/BV-01-C PASS scan passive -GAP/BROB/OBSV/BV-02-C PASS scan -GAP/BROB/OBSV/BV-03-C PASS scan -GAP/BROB/OBSV/BV-04-C PASS connect peer_addr= - security-set-data bonding=1 - security-pair conn= - - -GAP/BROB/OBSV/BV-05-C PASS scan own_addr_type=rpa_pub -GAP/BROB/OBSV/BV-06-C PASS scan own_addr_type=rpa_pub -------------------------------------------------------------------------------- - -GAP/DISC/NONM/BV-01-C PASS advertise-configure connectable=0 legacy=1 adverdise=non -GAP/DISC/NONM/BV-02-C PASS advertise-configure connectable=0 - -GAP/DISC/LIMM/BV-01-C N/A -GAP/DISC/LIMM/BV-02-C N/A -GAP/DISC/LIMM/BV-03-C PASS advertise-configure legacy=1 connectable=0 - advertise-set-adv-data flags=5 - advertise-start duration= e.g.3000 -GAP/DISC/LIMM/BV-04-C PASS advertise-configure legacy=1 connectable=0 - advertise-set-adv-data flags=5 - advertising-start duration= -GAP/DISC/GENM/BV-01-C N/A -GAP/DISC/GENM/BV-02-C N/A -GAP/DISC/GENM/BV-03-C PASS advertise-configure legacy=1 connectable=0 - advertise-set-adv-data flags=6 - advertise-start -GAP/DISC/GENM/BV-04-C PASS advertise-configure legacy=1 connectable=0 - advertise-set-adv-data flags=6 - advertising-start - -GAP/DISC/LIMP/BV-01-C PASS scan limited=1 nodups=1 -GAP/DISC/LIMP/BV-02-C PASS scan limited=1 nodups=1 -GAP/DISC/LIMP/BV-03-C PASS scan limited=1 nodups=1 -GAP/DISC/LIMP/BV-04-C PASS scan limited=1 nodups=1 -GAP/DISC/LIMP/BV-05-C PASS scan limited=1 nodups=1 - -GAP/DISC/GENP/BV-01-C PASS scan nodups=1 -GAP/DISC/GENP/BV-02-C PASS scan nodups=1 -GAP/DISC/GENP/BV-03-C PASS scan nodups=1 - -GAP/DISC/GENP/BV-04-C PASS scan nodups=1 - -GAP/DISC/GENP/BV-05-C PASS scan nodups=1 - -GAP/DISC/RPA/BV-01-C N/A scan nodups=1 -------------------------------------------------------------------------------- - -GAP/IDLE/GIN/BV-01-C N/A -GAP/IDLE/GIN/BV-02-C N/A -GAP/IDLE/NAMP/BV-01-C PASS advertise-configure connectable=1 legacy=1 - advertising-start - gatt-discover-full conn= - gatt-show - - gatt-read conn= uuid=0x2a00 start= end= - disconnect conn= -GAP/IDLE/NAMP/BV-02-C PASS - advertise-configure connectable=1 legacy=1 - advertising-start -GAP/IDLE/DED/BV-01-C N/A -GAP/IDLE/DED/BV-02-C N/A -------------------------------------------------------------------------------- - -GAP/CONN/NCON/BV-01-C PASS advertise-configure connectable=0 legacy=1 - advertising-start -GAP/CONN/NCON/BV-02-C PASS advertise-configure connectable=0 legacy=1 - advertise-set-adv-data flags=6 - advertise-start -GAP/CONN/NCON/BV-03-C PASS advertise-configure connectable=0 legacy=1 - advertise-set-adv-data flags=5 - advertise-start - -GAP/CONN/DCON/BV-01-C PASS advertise-configure connectable=0 directed=1 peer_addr= - advertise-start -GAP/CONN/DCON/BV-02-C N/A -GAP/CONN/DCON/BV-03-C N/A - -GAP/CONN/UCON/BV-01-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=4 - advertise-start -GAP/CONN/UCON/BV-02_C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=5 - advertise-start -GAP/CONN/UCON/BV-03_C PASS adbertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 -GAP/CONN/UCON/BV-04_C N/A -GAP/CONN/UCON/BV-05_C N/A -GAP/CONN/UCON/BV-06_C N/A - -GAP/CONN/ACEP/BV-01-C PASS white-list addr_type=public addr= - connect - disconnect conn= -GAP/CONN/ACEP/BV-02-C N/A - -GAP/CONN/GCEP/BV-01-C PASS connect peer_addr= - disconnect conn= -GAP/CONN/GCEP/BV-02-C PASS connect peer_addr= -GAP/CONN/GCEP/BV-03-C PASS set irk= - connect peer_addr= own_addr_type=rpa_pub - security-set-data bonding=1 our_key_dist=7 their_key_dist=7 - security-pair conn= - connect peer_addr= - disconnect conn=1 -GAP/CONN/GCEP/BV-04-C N/A -GAP/CONN/SCEP/BV-01-C PASS white-list addr_type=public addr= - connect - disconnect conn= -GAP/CONN/SCEP/BV-02-C INC -GAP/CONN/DCEP/BV-01-C PASS connect peer_addr= - disconnect conn= -GAP/CONN/DCEP/BV-02-C INC -GAP/CONN/DCEP/BV-03-C PASS connect peer_addr= - disconnect conn= -GAP/CONN/DCEP/BV-04-C PASS connect peer_addr= - disconnect conn= - -GAP/CONN/CPUP/BV-01-C PASS advertise-start - conn-update-params conn= -GAP/CONN/CPUP/BV-02-C PASS advertise-start - conn-update-params conn= -GAP/CONN/CPUP/BV-03-C PASS advertise-start - conn-update-params conn= -GAP/CONN/CPUP/BV-04-C PASS connect peer_addr= - disconnect conn= -GAP/CONN/CPUP/BV-05-C PASS connect peer_addr= - disconnect conn= -GAP/CONN/CPUP/BV-06-C PASS conect peer_addr= - conn-update-params conn= eg.latency=20 - disconnect conn= -GAP/CONN/CPUP/BV-08-C PASS advertise-configure legacy=1 connectable=1 - advertise-set-data name= - advertise-start - -GAP/CONN/TERM/BV-01-C PASS connect peer_addr= - disconnect conn= -GAP/CONN/PRDA/BV-01-C N/A -GAP/CONN/PRDA/BV-02-C N/A -------------------------------------------------------------------------------- -GAP/BOND/NBON/BV-01-C PASS security-set-data bonding=0 - connect peer_addr= - - connect peer_addr= - -GAP/BOND/NBON/BV-02-C PASS security-set-data bonding=0 - connect peer_addr= - security-pair conn= - - connect peer_addr= - security-pair conn= - -GAP/BOND/NBON/BV-03-C PASS security-set-data bonding=0 - advertise-configure legacy=1 connectable=1 - advertise-set-data name= - advertise-start - - -GAP/BOND/BON/BV-01-C PASS security-set-data bonding=1 sc=1 our_key_dist=7 their_key_dist=7 - advertise-configure legacy=1 connectable=1 - advertise-start - security-start conn= - - advertise-start - -GAP/BOND/BON/BV-02-C PASS security-set-data bonding=1 - connect peer_addr= - security-pair conn= - - connect peer_addr= - seccurity-pair conn= - -GAP/BOND/BON/BV-03-C PASS security-set-sm-data bonding=1 our_key_dist=7 their_key_dist=7 - advertise-configure legacy=1 connectable=1 - advertise-start - - advertise-start - -GAP/BOND/BON/BV-04-C PASS security-set-data bonding=1 - connect-peer_addr= - disconnect conn= - connect peer_addr= - security-pair conn= - disconnect conn= -------------------------------------------------------------------------------- - -GAP/SEC/AUT/BV-11-C PASS security-set-data io_capabilities=1 sc=1 - advertise-configure legacy=1 connectable=1 - advertising-start - Note: in PTS enter handle for characteristics - value which requires encryption for read (gatt-show-local) - auth-passkey conn= action=3 key=123456 - Note: enter '123456' passkey in PTS -GAP/SEC/AUT/BV-12-C PASS security-set-data io_capabilities=1 bonding=1 mitm_flag=1 sc=1 our_key_dist=7 their_key_dist=7 - connect peer_addr= - gatt-show-local - Note: in PTS enter handle for characteristics - value which requires encryption for read - auth-passkey conn= action=3 key=123456 - Note: enter '123456' passkey in PTS -GAP/SEC/AUT/BV-13-C PASS Note: in PTS confirm that IUT supports GATT Server - security-set-data io_capabilities=1 bonding=1 mitm_flag=1 sc=1 our_key_dist=7 their_key_dist=7 - connect peer_addr= - gatt-show-local - Note: in PTS enter handle for characteristics - value which requires authenticated pairing for read - auth-passkey conn= action=3 key=123456 - Note: enter '123456' passkey in PTS -GAP/SEC/AUT/BV-14-C PASS security-set-data io_capabilities=1 - advertise-configure legacy=1 connectable=1 - advertise-start - gatt-show-local - Note: in PTS enter handle for characteristics - value which requires authenticated pairing for read - auth-passkey conn= action=3 key=123456 - Note: enter '123456' passkey in PTS -GAP/SEC/AUT/BV-15-C N/A security-set-data bonding=1 io_capabilities=4 mitm_flag=1 sc=1 our_key_dist=7 their_key_dist=7 - advertise-configure legacy=1 connectable=1 - advertise-start - auth-passkey conn= action=2 key= - advertise-start - gatt-show-local - Note: in PTS enter handle for characteristics - value which requires authenticated pairing for read -GAP/SEC/AUT/BV-16-C N/A security-set-data io_capabilities=1 bonding=1 mitm_flag=1 sc=1 our_key_dist=7 their_key_dist=7 - connect peer_addr= - auth-passkey conn= action=3 key=123456 - Note: enter '123456' passkey in PTS - connect peer_addr= - gatt-show-local - Note: in PTS enter handle for characteristics - value which requires authenticated pairing for read -GAP/SEC/AUT/BV-17-C N/A -GAP/SEC/AUT/BV-18-C N/A -GAP/SEC/AUT/BV-19-C N/A -GAP/SEC/AUT/BV-20-C N/A -GAP/SEC/AUT/BV-21-C N/A -GAP/SEC/AUT/BV-22-C N/A -GAP/SEC/AUT/BV-23-C N/A -GAP/SEC/AUT/BV-24-C N/A - -GAP/SEC/CSIGN/BV-01-C N/A -GAP/SEC/CSIGN/BV-02-C N/A - -GAP/SEC/CSIGN/BI-01-C N/A -GAP/SEC/CSIGN/BI-02-C N/A -GAP/SEC/CSIGN/BI-03-C N/A -GAP/SEC/CSIGN/BI-04-C N/A -------------------------------------------------------------------------------- - -GAP/PRIV/CONN/BV-01-C N/A -GAP/PRIV/CONN/BV-02-C N/A -GAP/PRIV/CONN/BV-03-C N/A -GAP/PRIV/CONN/BV-04-C INC -GAP/PRIV/CONN/BV-05-C N/A -GAP/PRIV/CONN/BV-06-C N/A -GAP/PRIV/CONN/BV-07-C N/A -GAP/PRIV/CONN/BV-08-C N/A -GAP/PRIV/CONN/BV-09-C N/A -GAP/PRIV/CONN/BV-10-C N/A -GAP/PRIV/CONN/BV-11-C N/A -------------------------------------------------------------------------------- - -GAP/ADV/BV-01-C PASS advertise-set-adv_data uuid16=0x1802 - advertise-start - advertise-stop -GAP/ADV/BV-02-C PASS advertise-set-adv_data name= - advertise-start - advertise-stop -GAP/ADV/BV-03-C PASS advertise-set-adv_data flags=6 - advertise-start - advertise-stop -GAP/ADV/BV-04-C PASS advertise-set-adv_data mfg_data=ff:ff - advertise-start - advertise-stop -GAP/ADV/BV-05-C PASS advertise-set-adv_data tx_pwr_lvl=10 - advertise-start - advertise-stop -GAP/ADV/BV-08-C N/A -GAP/ADV/BV-09-C N/A -GAP/ADV/BV-10-C PASS advetrise-set-adv_data service_data_uuid16=18:02:ff:ff - advertise-start - advertise-stop -GAP/ADV/BV-11-C PASS advertise-set -dv_data appearance=12 - advertise-start - advertise-stop -GAP/ADV/BV-12-C N/A -GAP/ADV/BV-13-C N/A -GAP/ADV/BV-14-C N/A -GAP/ADV/BV-15-C N/A -GAP/ADV/BV-16-C N/A -GAP/ADV/BV-17-C PASS In PTS: TSPX_URI= - set-adv-data uri= - advertise-start - advertise-stop -------------------------------------------------------------------------------- - -GAP/GAT/BV-01-C PASS - advertising-start - - connect peer_addr= -GAP/GAT/BV-02-C N/A -GAP/GAT/BV-03-C N/A -GAP/GAT/BV-04-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GAP/GAT/BV-05-C N/A -GAP/GAT/BV-06-C N/A -GAP/GAT/BV-07-C N/A -GAP/GAT/BV-08-C N/A ----------------------------------------------------------------------------- - -GAP/DM/NCON/BV-01-C N/A -GAP/DM/CON/BV-01-C N/A -GAP/DM/NBON/BV-01-C N/A -GAP/DM/BON/BV-01-C N/A -GAP/DM/GIN/BV-01-C N/A -GAP/DM/LIN/BV-01-C N/A -GAP/DM/NAD/BV-01-C N/A -GAP/DM/NAD/BV-02-C N/A -GAP/DM/LEP/BV-01-C N/A -GAP/DM/LEP/BV-02-C N/A -GAP/DM/LEP/BV-04-C N/A -GAP/DM/LEP/BV-05-C N/A -GAP/DM/LEP/BV-06-C N/A -GAP/DM/LEP/BV-07-C N/A -GAP/DM/LEP/BV-08-C N/A -GAP/DM/LEP/BV-09-C N/A -GAP/DM/LEP/BV-10-C N/A -GAP/DM/LEP/BV-11-C N/A -------------------------------------------------------------------------------- - -GAP/MOD/NDIS/BV-01-C N/A -GAP/MOD/LDIS/BV-01-C N/A -GAP/MOD/LDIS/BV-02-C N/A -GAP/MOD/LDIS/BV-03-C N/A -GAP/MOD/GDIS/BV-01-C N/A -GAP/MOD/GDIS/BV-02-C N/A -GAP/MOD/NCON/BV-01-C N/A -GAP/MOD/CON/BV-01-C N/A \ No newline at end of file diff --git a/nimble/host/pts/pts-gatt.txt b/nimble/host/pts/pts-gatt.txt deleted file mode 100644 index 74c0a2e016..0000000000 --- a/nimble/host/pts/pts-gatt.txt +++ /dev/null @@ -1,508 +0,0 @@ -PTS test results for GATT - -PTS version: 7.5.0 -Tested: 27-Sept-2019 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -GATT/CL/GAC/BV-01-C PASS connect peer_addr= - gatt-exchanche-mtu conn= - gatt-write conn= long=1 attr= value= - disconnect conn= -------------------------------------------------------------------------------- - -GATT/CL/GAD/BV-01-C PASS connect peer_addr= - gatt-discover-service conn= - gatt-show - - disconnect conn= - -GATT/CL/GAD/BV-02-C PASS connect peer_addr= - gatt-discover-service conn= uuid= - gatt-show - - disconnect conn= - -GATT/CL/GAD/BV-03-C PASS connect peer_addr= - gatt-find-included-services conn= start=1 end=0xffff - - disconnect conn= - -GATT/CL/GAD/BV-04-C PASS connect peer_addr= - gatt-discover-service conn= uuid= - gatt-discover-characteristic conn= start= end= - gatt-show - - disconnect conn= - -GATT/CL/GAD/BV-05-C PASS connect peer_addr= - gatt-discover-service conn= - gatt-discover-characteristic conn= uuid= start= end= - gatt-show - - disconnect conn= - -GATT/CL/GAD/BV-06-C PASS connect peer_addr= - gatt-discover-service conn= - gatt-discover-characteristic conn= start= end= - gatt-discover-descriptor conn= start= end= - - disconnect conn= - -GATT/CL/GAD/BV-07-C N/A -GATT/CL/GAD/BV-08-C N/A -------------------------------------------------------------------------------- - -GATT/CL/GAR/BV-01-C PASS connect peer_addr= - gatt-read conn= attr= - - disconnect conn= -GATT/CL/GAR/BI-01-C PASS connect peer_addr= - gatt-read conn= attr= - - disconnect conn= -GATT/CL/GAR/BI-02-C PASS connect peer_addr= - gatt-read conn= attr= - - disconnect conn= -GATT/CL/GAR/BI-03-C N/A - -GATT/CL/GAR/BI-04-C PASS connect peer_addr= - gatt-read conn= attr= - disconnect conn= - -GATT/CL/GAR/BI-05-C PASS connect peer_addr= - gatt-read conn= attr= - - disconnect conn= -GATT/CL/GAR/BV-03-C PASS connect peer_addr= - gatt-read conn= uuid= start=1 end=0xffff - - - disconnect conn= -GATT/CL/GAR/BI-06-C PASS connect peer_addr= - gatt-read conn= uuid= start= end= - disconnect conn= - -GATT/CL/GAR/BI-07-C PASS connect peer_addr= - gatt-read conn= uuid= start= end= - disconnect conn= - -GATT/CL/GAR/BI-09-C N/A -GATT/CL/GAR/BI-10-C PASS connect peer_addr= - gatt-read conn= uuid= start= end= - disconnect conn= - -GATT/CL/GAR/BI-11-C PASS connect perr_addr= - gatt-read conn= start= end= - disconnect conn= - -GATT/CL/GAR/BV-04-C PASS connect peer_addr= - gatt-read conn= long=1 attr= - - - disconnect conn= -GATT/CL/GAR/BI-12-C PASS connect peer_addr= - gatt-read conn= long=1 attr= - - disconnect conn= -GATT/CL/GAR/BI-13-C PASS connect peer_addr= - gatt-read conn= long=1 attr= offset= - - disconnect conn= -GATT/CL/GAR/BI-14-C PASS connect peer_addr= - gatt-read conn= long=1 attr= - disconnect conn= - -GATT/CL/GAR/BI-15-C N/A - -GATT/CL/GAR/BI-16-C PASS connect peer_addr= - gatt-read conn= long=1 attr= - disconnect conn= - -GATT/CL/GAR/BI-17-C PASS connect peer_addr= - gatt-read conn= long=1 attr= - - disconnect conn= -GATT/CL/GAR/BV-05-C PASS connect peer_addr= - gatt-read conn= attr= attr= - disconnect conn= -GATT/CL/GAR/BI-18-C PASS connect peer_addr= - gatt-read conn= attr= attr= - - disconnect conn= -GATT/CL/GAR/BI-19-C PASS connect peer_addr= - gatt-read conn= attr= attr= - disconnect conn= - -GATT/CL/GAR/BI-20-C N/A - -GATT/CL/GAR/BI-21-C PASS connect peer_addr= - gatt-read conn= attr= attr= - disconnect conn= - -GATT/CL/GAR/BI-22-C PASS connect peer_addr= - gatt-read conn= attr= attr= - - disconnect conn= -GATT/CL/GAR/BV-06-C PASS connect peer_addr= - gatt-read conn= attr= - - disconnect conn= -GATT/CL/GAR/BV-07-C PASS connect peer_addr= - gatt-read conn= long=1 attr= - - - disconnect conn= -GATT/CL/GAR/BI-34-C N/A -GATT/CL/GAR/BI-35-C PASS connect peer_addr= - gatt-read conn= long=1 attr= - - disconnect conn= -------------------------------------------------------------------------------- - -GATT/CL/GAW/BV-01-C PASS connect peer_addr= - gatt-write no_rsp=1 conn= attr= value= - disconnect conn= -GATT/CL/GAW/BV-02-C N/A - -GATT/CL/GAW/BV-03-C PASS connect peer_addr= - gatt-write conn= attr= value= - disconnect conn= -GATT/CL/GAW/BI-02-C PASS connect peer_addr= - gatt-write conn= attr= value= - disconnect conn= -GATT/CL/GAW/BI-03-C PASS connect peer_addr= - gatt-write conn= attr= value= - disconnect conn= -GATT/CL/GAW/BI-04-C N/A - -GATT/CL/GAW/BI-05-C PASS connect peer_addr= - gatt-write conn= attr= value= - disconnect conn= -GATT/CL/GAW/BI-06-C PASS connect peer_addr= - gatt-write conn= attr= value= - disconnect conn= -GATT/CL/GAW/BV-05-C PASS connect peer_addr= - gatt-write long=1 conn= attr= value= - disconnect conn= -GATT/CL/GAW/BI-07-C PASS connect peer_addr= - gatt-write long=1 conn= attr= value= - disocnnect conn= -GATT/CL/GAW/BI-08-C PASS connect peer_addr= - gatt-write long=1 conn= attr= value= - diconnect conn= -GATT/CL/GAW/BI-09-C PASS connect peer_addr= - gatt-write long=1 conn= attr= value= offset= - diconnect conn=1 -GATT/CL/GAW/BI-11-C N/A - -GATT/CL/GAW/BI-12-C PASS connect peer_addr= - gatt-write long=1 conn= attr= value= - disconnect conn= -GATT/CL/GAW/BI-13-C PASS connect peer_addr= - gatt-write long=1 conn= attr= value= - diconnect conn= -GATT/CL/GAW/BV-06-C PASS connect peer_addr= - gatt-write long=1 conn= attr= value= - -GAAT/CL/GAW/BV-08-C PASS connect peer_addr= - gat-write conn= attr= value= - -GATT/CL/GAW/BV-09-C PASS connect peer_addr= - gatt-write long=1 conn= attr= value= - -GATT/CL/GAW/BI-32-C PASS connect peer_addr= - gatt-write conn= attr= value= attr= value= - disconnect conn= -GATT/CL/GAW/BI-33-C PASS connect peer_addr= - gatt-write conn= attr= value= - disconnect conn= -GATT/CL/GAW/BI-34-C PASS connect peer_addr= - gatt-write long=1 conn= attr= value= - disconnect conn= - -------------------------------------------------------------------------------- - -GATT/CL/GAN/BV-01-C PASS connect peer_addr= - gatt-write conn= attr= value=01:00 - Note: verify that the notification was received - disconnect conn= -------------------------------------------------------------------------------- - -GATT/CL/GAI/BV-01-C PASS connect peer_addr= - gatt-write conn= attr= value=01:00 - Note: verify that the notification was received - disconnect conn= -------------------------------------------------------------------------------- - -GATT/CL/GAS/BV-01-C PASS connect peer_addr= - disconnect conn= -------------------------------------------------------------------------------- - -GATT/CL/GAT/BV-01-C PASS connect peer_addr= - gatt-read conn= attr= -GATT/CL/GAT/BV-02-C PASS connect peer_addr= - gatt-write conn= attr= value= -------------------------------------------------------------------------------- - -GATT/CL/GPA/BV-01-C N/A -GATT/CL/GPA/BV-02-C N/A -GATT/CL/GPA/BV-03-C N/A -GATT/CL/GPA/BV-04-C N/A -GATT/CL/GPA/BV-05-C N/A -GATT/CL/GPA/BV-06-C N/A -GATT/CL/GPA/BV-07-C N/A -GATT/CL/GPA/BV-08-C N/A -GATT/CL/GPA/BV-11-C N/A -GATT/CL/GPA/BV-12-C N/A -------------------------------------------------------------------------------- - -GATT/SR/GAC/BV-01-C PASS set mtu=25 - advertise-configure connectable=1 legacy=1 - advertise-start - advertise-start -------------------------------------------------------------------------------- - -GATT/SR/GAD/BV-01-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - gatt-show-local - -GATT/SR/GAD/BV-02-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - gatt-show-local - -GATT/SR/GAD/BV-03-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - gatt-show-local - -GATT/SR/GAD/BV-04-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAD/BV-05-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAD/BV-06-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAD/BV-07-C N/A -GATT/SR/GAD/BV-08-C N/A -------------------------------------------------------------------------------- - -GATT/SR/GAR/BV-01-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BI-01-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BI-02-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAR/BI-03-C N/A -GATT/SR/GAR/BI-04-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BI-05-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BV-03-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BI-06-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - gatt-show-local - - -GATT/SR/GAR/BI-07-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAR/BI-08-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BI-09-C N/A -GATT/SR/GAR/BI-10-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BI-11-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAR/BV-04-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BI-12-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAR/BI-13-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BI-14-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAR/BI-15-C N/A -GATT/SR/GAR/BI-16-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BI-17-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BV-05-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BI-18-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAR/BI-19-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAR/BI-20-C N/A -GATT/SR/GAR/BI-21-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BI-22-C PASS advertise-configure connectable=1 legacy=1 - advertise-startt -GATT/SR/GAR/BV-06-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BI-23-C N/A -GATT/SR/GAR/BI-24-C N/A -GATT/SR/GAR/BI-25-C N/A -GATT/SR/GAR/BI-26-C N/A -GATT/SR/GAR/BI-27-C N/A -GATT/SR/GAR/BV-07-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BV-08-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAR/BI-28-C N/A -GATT/SR/GAR/BI-29-C N/A -GATT/SR/GAR/BI-30-C N/A -GATT/SR/GAR/BI-31-C N/A -GATT/SR/GAR/BI-32-C N/A -GATT/SR/GAR/BI-33-C N/A -GATT/SR/GAR/BI-34-C N/A -GATT/SR/GAR/BI-35-C N/A -------------------------------------------------------------------------------- - -GATT/SR/GAW/BV-01-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BV-02-C N/A -GATT/SR/GAW/BI-01-C N/A -GATT/SR/GAW/BV-03-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-02-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAW/BI-03-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-04-C N/A -GATT/SR/GAW/BI-05-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-06-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BV-05-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-07-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAW/BI-08-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAW/BI-09-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-11-C N/A -GATT/SR/GAW/BI-12-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-13-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BV-06-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BV-10-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-14-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAW/BI-15-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAW/BI-17-C N/A -GATT/SR/GAW/BI-18-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-19-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BV-11-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BV-07-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BV-08-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-20-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAW/BI-21-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAW/BI-22-C N/A -GATT/SR/GAW/BI-23-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-24-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BV-09-C PASS advertise-configure connectable=1 legacy=1q - advertise-start -GATT/SR/GAW/BI-25-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAW/BI-26-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -GATT/SR/GAW/BI-27-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-29-C N/A -GATT/SR/GAW/BI-30-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-31-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-32-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-33-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-34-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/GAW/BI-35-C PASS advertise-configure connectable=1 legacy=1 - advertise-start ------------------------------------------------------------------------------- - -GATT/SR/GAN/BV-01-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - gatt-notify attr= ------------------------------------------------------------------------------- - -GATT/SR/GAI/BV-01-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - gatt-notify attr= -------------------------------------------------------------------------------- - -GATT/SR/GAS/BV-01-C PASS Note: set TSPX_security_enabled to TRUE - security-set-data bonding=1 our_key_dist=7 their_key_dist=7 - advertise-configure connectable=1 legacy=1 - advertise-start - - gatt-service-changed start=1 end=0xffff - advertise-start - security-start conn= -------------------------------------------------------------------------------- - -GATT/SR/GAT/BV-01-C PASS advertise-start - gatt-notify attr=0x0008 ------------------------------------------------------------------------------- - -GATT/SR/GPA/BV-01-C N/A -GATT/SR/GPA/BV-02-C N/A -GATT/SR/GPA/BV-03-C N/A -GATT/SR/GPA/BV-04-C N/A -GATT/SR/GPA/BV-05-C N/A -GATT/SR/GPA/BV-06-C N/A -GATT/SR/GPA/BV-07-C N/A -GATT/SR/GPA/BV-08-C N/A -GATT/SR/GPA/BV-11-C N/A -GATT/SR/GPA/BV-12-C N/A -------------------------------------------------------------------------------- - -GATT/SR/UNS/BI-01-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -GATT/SR/UNS/BI-02-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - --------------------------------------------------------------------------------- - -GATT/SR/GPM/BV-01-C N/A - diff --git a/nimble/host/pts/pts-l2cap.txt b/nimble/host/pts/pts-l2cap.txt deleted file mode 100644 index c09add9168..0000000000 --- a/nimble/host/pts/pts-l2cap.txt +++ /dev/null @@ -1,304 +0,0 @@ -PTS test results for L2CAP - -PTS version: 7.5.0 -Tested: 07-Oct-2019 - -syscfg.vals: - BLE_EXT_ADV: 1 - BLE_PUBLIC_DEV_ADDR: "((uint8_t[6]){0x01, 0xff, 0xff, 0xc0, 0xde, 0xc0})" - BLE_SM_LEGACY: 1 - BLE_SM_SC: 1 - BLE_L2CAP_COC_MAX_NUM: 5 - BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL: 9 - BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL: 30 - BLE_SVC_GAP_PPCP_SUPERVISION_TMO: 2000 - CONSOLE_HISTORY_SIZE: 10 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- - -L2CAP/COS/CED/BV-01-C N/A -L2CAP/COS/CED/BV-03-C N/A -L2CAP/COS/CED/BV-04-C N/A -L2CAP/COS/CED/BV-05-C N/A -L2CAP/COS/CED/BV-07-C N/A -L2CAP/COS/CED/BV-08-C N/A -L2CAP/COS/CED/BV-09-C N/A -L2CAP/COS/CED/BV-10-C N/A -L2CAP/COS/CED/BV-11-C N/A -L2CAP/COS/CED/BI-01-C N/A -------------------------------------------------------------------------------- - -L2CAP/COS/CFD/BV-01-C N/A -L2CAP/COS/CFD/BV-02-C N/A -L2CAP/COS/CFD/BV-03-C N/A -L2CAP/COS/CFD/BV-08-C N/A -L2CAP/COS/CFD/BV-09-C N/A -L2CAP/COS/CFD/BV-10-C N/A -L2CAP/COS/CFD/BV-11-C N/A -L2CAP/COS/CFD/BV-12-C N/A -L2CAP/COS/CFD/BV-13-C N/A -------------------------------------------------------------------------------- - -L2CAP/COS/IEX/BV-01-C N/A -L2CAP/COS/IEX/BV-02-C N/A -------------------------------------------------------------------------------- - -L2CAP/COS/ECH/BV-01-C N/A -L2CAP/COS/ECH/BV-02-C N/A -------------------------------------------------------------------------------- - -L2CAP/COS/CFC/BV-01-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - l2cap-create-server psm= - advertise-start - l2cap-send conn= idx=0 bytes=15 - -L2CAP/COS/CFC/BV-02-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - l2cap-create-server psm= - advertise-start - l2cap-send conn= idx=0 bytes=15 - -L2CAP/COS/CFC/BV-03-C PASS NOTE: #define BTSHELL_COC_MTU = 512 - advertise-configure connectable=1 legacy=1 - l2cap-create-server psm= - advertise-start -L2CAP/COS/CFC/BV-04-C PASS advertise-configure connectable=1 legacy=1 - l2cap-create-server psm= - advertise-start -L2CAP/COS/CFC/BV-05-C PASS advertise-configure connectable=1 legacy=1 - l2cap-create-server psm= - advertise-start - l2cap-connect conn= psm= - l2cap-connect conn= psm=<2nd psm> -------------------------------------------------------------------------------- - -L2CAP/CLS/CLR/BV-01-C N/A -------------------------------------------------------------------------------- - -L2CAP/CLS/UCD/BV-01-C N/A -L2CAP/CLS/UCD/BV-02-C N/A -L2CAP/CLS/UCD/BV-03-C N/A -------------------------------------------------------------------------------- - -L2CAP/EXF/BV-01-C N/A -L2CAP/EXF/BV-02-C N/A -L2CAP/EXF/BV-03-C N/A -L2CAP/EXF/BV-04-C N/A -L2CAP/EXF/BV-05-C N/A -L2CAP/EXF/BV-06-C N/A -------------------------------------------------------------------------------- - -L2CAP/CMC/BV-01-C N/A -L2CAP/CMC/BV-02-C N/A -L2CAP/CMC/BV-03-C N/A -L2CAP/CMC/BV-04-C N/A -L2CAP/CMC/BV-05-C N/A -L2CAP/CMC/BV-06-C N/A -L2CAP/CMC/BV-07-C N/A -L2CAP/CMC/BV-08-C N/A -L2CAP/CMC/BV-09-C N/A -L2CAP/CMC/BV-10-C N/A -L2CAP/CMC/BV-11-C N/A -L2CAP/CMC/BV-12-C N/A -L2CAP/CMC/BV-13-C N/A -L2CAP/CMC/BV-14-C N/A -L2CAP/CMC/BV-15-C N/A -L2CAP/CMC/BI-01-C N/A -L2CAP/CMC/BI-02-C N/A -L2CAP/CMC/BI-03-C N/A -L2CAP/CMC/BI-04-C N/A -L2CAP/CMC/BI-05-C N/A -L2CAP/CMC/BI-06-C N/A -------------------------------------------------------------------------------- - -L2CAP/FOC/BV-01-C N/A -L2CAP/FOC/BV-02-C N/A -L2CAP/FOC/BV-03-C N/A -------------------------------------------------------------------------------- - -L2CAP/OFS/BV-01-C N/A -L2CAP/OFS/BV-02-C N/A -L2CAP/OFS/BV-03-C N/A -L2CAP/OFS/BV-04-C N/A -L2CAP/OFS/BV-05-C N/A -L2CAP/OFS/BV-06-C N/A -L2CAP/OFS/BV-07-C N/A -L2CAP/OFS/BV-08-C N/A -------------------------------------------------------------------------------- - -L2CAP/ERM/BV-01-C N/A -L2CAP/ERM/BV-02-C N/A -L2CAP/ERM/BV-03-C N/A -L2CAP/ERM/BV-05-C N/A -L2CAP/ERM/BV-06-C N/A -L2CAP/ERM/BV-07-C N/A -L2CAP/ERM/BV-08-C N/A -L2CAP/ERM/BV-09-C N/A -L2CAP/ERM/BV-10-C N/A -L2CAP/ERM/BV-11-C N/A -L2CAP/ERM/BV-12-C N/A -L2CAP/ERM/BV-13-C N/A -L2CAP/ERM/BV-14-C N/A -L2CAP/ERM/BV-15-C N/A -L2CAP/ERM/BV-16-C N/A -L2CAP/ERM/BV-17-C N/A -L2CAP/ERM/BV-18-C N/A -L2CAP/ERM/BV-19-C N/A -L2CAP/ERM/BV-20-C N/A -L2CAP/ERM/BV-21-C N/A -L2CAP/ERM/BV-22-C N/A -L2CAP/ERM/BV-23-C N/A -L2CAP/ERM/BI-01-C N/A -L2CAP/ERM/BI-02-C N/A -L2CAP/ERM/BI-03-C N/A -L2CAP/ERM/BI-04-C N/A -L2CAP/ERM/BI-05-C N/A -------------------------------------------------------------------------------- - -L2CAP/STM/BV-01-C N/A -L2CAP/STM/BV-02-C N/A -L2CAP/STM/BV-03-C N/A -L2CAP/STM/BV-11-C N/A -L2CAP/STM/BV-12-C N/A -L2CAP/STM/BV-13-C N/A -------------------------------------------------------------------------------- - -L2CAP/FIX/BV-01-C N/A -L2CAP/FIX/BV-02-C N/A -------------------------------------------------------------------------------- - -L2CAP/EWC/BV-01-C N/A -L2CAP/EWC/BV-02-C N/A -L2CAP/EWC/BV-03-C N/A -------------------------------------------------------------------------------- - -L2CAP/LSC/BV-01-C N/A -L2CAP/LSC/BV-02-C N/A -L2CAP/LSC/BV-03-C N/A -L2CAP/LSC/BI-04-C N/A -L2CAP/LSC/BI-05-C N/A -L2CAP/LSC/BV-06-C N/A -L2CAP/LSC/BV-07-C N/A -L2CAP/LSC/BV-08-C N/A -L2CAP/LSC/BV-09-C N/A -L2CAP/LSC/BI-10-C N/A -L2CAP/LSC/BI-11-C N/A -L2CAP/LSC/BV-12-C N/A -------------------------------------------------------------------------------- - -L2CAP/CCH/BV-01-C N/A -L2CAP/CCH/BV-02-C N/A -L2CAP/CCH/BV-03-C N/A -L2CAP/CCH/BV-04-C N/A -------------------------------------------------------------------------------- - -L2CAP/ECF/BV-01-C N/A -L2CAP/ECF/BV-02-C N/A -L2CAP/ECF/BV-03-C N/A -L2CAP/ECF/BV-04-C N/A -L2CAP/ECF/BV-05-C N/A -L2CAP/ECF/BV-06-C N/A -L2CAP/ECF/BV-07-C N/A -L2CAP/ECF/BV-08-C N/A -------------------------------------------------------------------------------- - -L2CAP/LE/CPU/BV-01-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - advertise-start - l2cap-update conn= -L2CAP/LE/CPU/BV-02-C PASS connect peer_addr= - disconnect conn= -L2CAP/LE/CPU/BI-01-C PASS connect peer_addr= - disconnect conn= -L2CAP/LE/CPU/BI-02-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - advertise-start -------------------------------------------------------------------------------- - -L2CAP/LE/REJ/BI-01-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - advertise-start -L2CAP/LE/REJ/BI-02-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - advertise-start - disconnect conn= -------------------------------------------------------------------------------- - -L2CAP/LE/CFC/BV-01-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - advertise-start -L2CAP/LE/CFC/BV-02-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - advertise-start - l2cap-connect conn= psm=90 -L2CAP/LE/CFC/BV-03-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - l2cap-create-server psm= - advertise-start - l2cap-send conn= idx=0 bytes=15 - -L2CAP/LE/CFC/BV-04-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - advertise-start - l2cap-connect conn= psm= -L2CAP/LE/CFC/BV-05-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - advertise-start -L2CAP/LE/CFC/BV-06-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - l2cap-create-server psm= - advertise-start - l2cap-send conn= idx=0 bytes=15 -L2CAP/LE/CFC/BV-07-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - l2cap-create-server psm= - advertise-start -L2CAP/LE/CFC/BI-01-C PASS advertise-configure connectable=1 legacy=1 - l2cap-create-server psm= - advertise-start -L2CAP/LE/CFC/BV-08-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - l2cap-create-server psm= - advertise-start - l2cap-disconnect conn= idx=0 -L2CAP/LE/CFC/BV-09-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - l2cap-create-server psm= - advertise-start -L2CAP/LE/CFC/BV-16-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - advertise-start - l2cap-connect conn= psm=90 -L2CAP/LE/CFC/BV-17-C N/A -L2CAP/LE/CFC/BV-18-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - advertise-start - l2cap-connect conn= psm=90 -L2CAP/LE/CFC/BV-19-C PASS NOTE: TSPC_L2CAP_3_16 (multiple channel support) must be checked - advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - advertise-start - l2cap-connect conn= psm=90 -L2CAP/LE/CFC/BV-20-C PASS NOTE: TSPC_L2CAP_3_16 (multiple channel support) must be checked - advertise-configure connectable=1 legacy=1 - l2cap-create-server psm= - advertise-start -L2CAP/LE/CFC/BV-21-C PASS advertise-configure connectable=1 legacy=1 - advertise-set-adv-data flags=6 - advertise-start - l2cap-connect conn= psm=90 -------------------------------------------------------------------------------- - -L2CAP/LE/CID/BV-01-C N/A -L2CAP/LE/CID/BV-02-C N/A -------------------------------------------------------------------------------- - diff --git a/nimble/host/pts/pts-sm.txt b/nimble/host/pts/pts-sm.txt deleted file mode 100644 index ac26db712e..0000000000 --- a/nimble/host/pts/pts-sm.txt +++ /dev/null @@ -1,310 +0,0 @@ -PTS test results for SM - -PTS version: 7.5.0 -Tested: 07-Oct-2019 - -syscfg.vals: - BLE_EXT_ADV: 1 - BLE_PUBLIC_DEV_ADDR: "((uint8_t[6]){0x01, 0xff, 0xff, 0xc0, 0xde, 0xc0})" - BLE_SM_LEGACY: 1 - BLE_SM_SC: 1 - BLE_L2CAP_COC_MAX_NUM: 5 - BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL: 9 - BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL: 30 - BLE_SVC_GAP_PPCP_SUPERVISION_TMO: 2000 - CONSOLE_HISTORY_SIZE: 10 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup -NONE test result is none - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- - -SM/MAS/PROT/BV-01-C PASS connect peer_addr= - security-set-data bonding=1 sc=1 our_key_dist=7 their_key_dist=7 - security-pair conn= -------------------------------------------------------------------------------- - -SM/MAS/JW/BV-01-C N/A -SM/MAS/JW/BV-05-C PASS connect peer_addr= - security-pair conn= - disconnect conn= - -SM/MAS/JW/BI-01-C PASS connect peer_addr= - security-pair conn= -SM/MAS/JW/BI-04-C PASS connect peer_addr= - security-set-data bonding=1 sc=1 - security-pair conn= -------------------------------------------------------------------------------- - -SM/MAS/PKE/BV-01-C PASS security-set-data io_capabilities=1 - connect peer_addr= - b sec pair conn= - b passkey conn= action=3 key=123456 - Note: enter '123456' passkey in PTS -SM/MAS/PKE/BV-04-C PASS security-set-data bonding=1 oob_flag=0 - connect peer_addr= - security-pair conn= - disconnect conn= -SM/MAS/PKE/BI-01-C PASS ecurity-set-data io_capabilities=1 oob_flag=0 - connect peer_addr= - security-pair conn= - auth-passkey conn= action=3 key=123456 - Note: enter invalid passkey -SM/MAS/PKE/BI-02-C PASS security-set-data io_capabilities=1 oob_flag=0 - connect peer_addr= - security-pair conn= - auth-passkey conn= action=3 key=123456 - Note: enter '123456' passkey in PTS -------------------------------------------------------------------------------- - -SM/MAS/OOB/BV-01-C N/A -SM/MAS/OOB/BV-03-C N/A -SM/MAS/OOB/BV-05-C PASS security-set-data io_capabilities=1 oob_flag=0 - connect-peer_addr= - security-pair conn= - auth-passkey conn= action=3 key=123456 - Note: enter '123456' passkey in PTS - disconnect conn=1 -SM/MAS/OOB/BV-07-C PASS ecurity-set-data io_capabilities=1 oob_flag=0 - connect-peer_addr= - security-pair conn= - disconnect conn=1 -SM/MAS/OOB/BV-09-C N/A -SM/MAS/OOB/BI-01-C N/A -------------------------------------------------------------------------------- - -SM/MAS/EKS/BV-01-C PASS connect peer_addr= - security-pair conn= - disconnect conn=1 -SM/MAS/EKS/BI-01-C PASS connect peer_addr= - security-pair conn= - disconnect conn=1 -------------------------------------------------------------------------------- - -SM/MAS/SIGN/BV-01-C N/A -SM/MAS/SIGN/BV-03-C N/A -SM/MAS/SIGN/BI-01-C N/A -------------------------------------------------------------------------------- - -SM/MAS/KDU/BV-04-C PASS security-set-data our_key_dist=4 - connect peer_addr= - security-pair conn= - disconnect conn=1 -SM/MAS/KDU/BV-05-C PASS security-set-data our_key_dist=2 - connect peer_addr= - security-pair conn= - disconnect conn=1 -SM/MAS/KDU/BV-06-C PASS security-set-data our_key_dist=1 - connect peer_addr= - security-pair conn= - disconnect conn=1 -SM/MAS/KDU/BV-10-C PASS security-set-data our_key_dist=2 sc=1 - connect peer_addr= - security-pair conn= - disconnect conn=1 -SM/MAS/KDU/BV-11-C PASS security-set-data our_key_dist=2 sc=1 - connect peer_addr= - security-pair conn= - disconnect conn=1 -SM/MAS/KDU/BI-01-C PASS connect peer_addr= - disconnect conn=1 - reset device - - -------------------------------------------------------------------------------- - -SM/MAS/SIP/BV-02-C PASS security-set-data io_capabilities=4 - connect peer_addr= - disconnect conn=1 -------------------------------------------------------------------------------- -SM/MAS/SCJW/BV-01-C PASS security-set-data sc=1 - connect peer_addr= - security-pair conn= - disconnect conn=1 -SM/MAS/SCJW/BV-04-C PASS security-set-data sc=1 io_capabilities=1 our_key_dist=1 - connect peer_addr= - security-pair conn= - disconnect conn=1 -SM/MAS/SCJW/BI-01-C PASS security-set-data sc=1 io_capabilities=4 - connect peer_addr= - security-pair conn= - disconnect conn=1 - - -------------------------------------------------------------------------------- - -SM/MAS/SCPK/BV-01-C PASS security-set-data sc=1 io_capabilities=2 - connect peer_addr= - security-pair conn= - auth_passkey conn=1 action=2 key=123456 - Note: enter '123456' passkey in PTS - disconnect conn=1 -SM/MAS/SCPK/BV-04-C PASS security-set-data io_capabilities=4 oob_flag=0 our_key_dist=1 their_key_dist=1 - connect peer_addr= - security-pair conn= - auth_passkey conn=1 action=2 key=123456 - Note: enter '123456' passkey in PTS - disconnect conn=1 -SM/MAS/SCPK/BI-01-C PASS security-set-data io_capabilities=4 oob_flag=0 sc=1 - connect peer_addr= - security-pair conn= - disconnect conn=1 - - auth_passkey conn=1 action=2 key=123456 - Note: enter '123456' passkey in PTS - disconnect conn=1 -SM/MAS/SCPK/BI-02-C PASS security-set-data io_capabilities=2 oob_flag=0 bonding=1 sc=1 - connect peer_addr= - security-pair conn= - auth_passkey conn=1 action=2 key=123456 - Note: enter '123456' passkey in PTS - disconnect conn=1 -------------------------------------------------------------------------------- - -SM/MAS/SCOB/BV-01-C N/A -SM/MAS/SCOB/BI-04-C N/A -SM/MAS/SCOB/BV-01-C N/A -SM/MAS/SCOB/BI-04-C N/A -------------------------------------------------------------------------------- - -SM/MAS/SCCT/BV-01-C N/A -SM/MAS/SCCT/BV-03-C N/A -SM/MAS/SCCT/BV-05-C N/A -SM/MAS/SCCT/BV-07-C N/A -SM/MAS/SCCT/BV-09-C N/A -------------------------------------------------------------------------------- - -SM/SLA/PROT/BV-02-C PASS advertise-configure connectable=1 legacy=1 - advertise-start - -------------------------------------------------------------------------------- - -SM/MAS/JW/BV-02-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -SM/SLA/JW/BI-02-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -SM/SLA/JW/BI-03-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -------------------------------------------------------------------------------- - -SM/SLA/PKE/BV-02-C PASS security-set-data io_capabilities=4 - advertise-configure connectable=1 legacy=1 - advertise-start - auth-passkey conn= action=2 key= - -SM/SLA/PKE/BV-05-C PASS security-set-data io_capabilities=4 - advertise-configure connectable=1 legacy=1 - advertise-start -SM/SLA/PKE/BI-03-C PASS security-set-data io_capabilities=4 - advertise-configure connectable=1 legacy=1 - advertise-start - auth-passkey conn= action=3 key=123456 - Note: enter invalid passkey -------------------------------------------------------------------------------- - -SM/SLA/OOB/BV-02-C N/A -SM/SLA/OOB/BV-04-C N/A -SM/SLA/OOB/BV-06-C PASS security-set-data io_capabilities=1 - advertise-configure connectable=1 legacy=1 - advertise-start - auth-passkey conn= action=3 key= -SM/SLA/OOB/BV-08-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -SM/SLA/OOB/BV-10-C N/A -SM/SLA/OOB/BI-02-C N/A -------------------------------------------------------------------------------- - -SM/SLA/EKS/BV-02-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -SM/SLA/EKS/BI-02-C PASS advertise-configure connectable=1 legacy=1 - advertise-start -------------------------------------------------------------------------------- - -SM/SLA/KDU/BV-01-C PASS security-set-data io_capabilities=1 - advertise-configure connectable=1 legacy=1 - advertise-start -SM/SLA/KDU/BV-02-C PASS security-set-data io_capabilities=2 - advertise-configure connectable=1 legacy=1 - advertise-start -SM/SLA/KDU/BV-03-C PASS security-set-data io_capabilities=4 - advertise-configure connectable=1 legacy=1 - advertise-start -SM/SLA/KDU/BV-07-C PASS security-set-data our_key_dist=1 bonding=1 - advertise-configure connectable=1 legacy=1 - advertise-start -SM/SLA/KDU/BV-08-C PASS security-set-data our_key_dist=2 sc=1 - advertise-configure connectable=1 legacy=1 - advertise-start -SM/SLA/KDU/BV-09-C PASS security-set-data our_key_dist=4 bonding=0 - advertise-configure connectable=1 legacy=1 - advertise-start -SM/SLA/KDU/BI-01-C PASS advertise-configure connectable=1 legacy=1 - security-set-data sc=1 - advertise-start - - -------------------------------------------------------------------------------- - -SM/SLA/SIP/BV-01-C PASS security-set-data io_capabilities=4 - advertise-configure connectable=1 legacy=1 - advertise-start - security-start conn= -------------------------------------------------------------------------------- - -SM/SLA/SIE/BV-01-C PASS security-set-data io_capabilities=3 bonding=1 our_key_dist=1 their_key_dist=1 - advertise-configure connectable=1 legacy=1 - advertise-start - advertise-start - security-start conn= -------------------------------------------------------------------------------- - -SM/SLA/SCJW/BV-02-C PASS security-set-data io_capabilities=4 oob_flag=0 bonding=0 mitm_flag=0 sc=1 our_key_dist=1 - advertise-configure connectable=1 legacy=1 - advertise-start -SM/SLA/SCJW/BV-03-C PASS security-set-data io_capabilities=1 our_key_dist=1 oob_flag=0 - advertise-configure connectable=1 legacy=1 - advertise-start -SM/SLA/SCJW/BI-02-C PASS security-set-data io_capabilities=1 oob_flag=0 bonding=1 sc=1 - advertise-configure connectable=1 legacy=1 - advertise-start -------------------------------------------------------------------------------- - -SM/SLA/SCPK/BV-02-C PASS security-set-data io_capabilities=1 oob_flag=0 sc=1 - advertise-configure connectable=1 legacy=1 - advertise-start - auth-passkey conn=1 action=4 key=186900 yesno=yy -SM/SLA/SCPK/BV-03-C PASS security-set-data io_capabilities=2 oob_flag=0 our_key_dist=1 their_key_dist=1 sc=1 - advertise-configure connectable=1 legacy=1 - advertise-start - auth-passkey conn=1 action=2 key=123456 - Note: enter '123456' passkey in PTS -SM/SLA/SCPK/BI-03-C PASS security-set-data io_capabilities=2 oob_flag=0 sc=1 - advertise-configure connectable=1 legacy=1 - advertise-start - auth-passkey conn=1 action=2 key=123456 oob= - Note: enter '123456' passkey in PTS -SM/SLA/SCPK/BI-04-C PASS security-set-data io_capabilities=2 oob_flag=0 mitm_flag=1 sc=1 - advertise-configure connectable=1 legacy=1 - advertise-start - - auth-passkey conn=1 action=2 key=123456 - Note: enter '123456' passkey in PTS -------------------------------------------------------------------------------- - -SM/SLA/SCOB/BV-02-C N/A -SM/SLA/SCOB/BI-03-C N/A -SM/SLA/SCOB/BV-02-C N/A -SM/SLA/SCOB/BI-03-C N/A -------------------------------------------------------------------------------- - -SM/SLA/SCCT/BV-02-C N/A -SM/SLA/SCCT/BV-04-C N/A -SM/SLA/SCCT/BV-06-C N/A -SM/SLA/SCCT/BV-08-C N/A -SM/SLA/SCCT/BV-10-C N/A \ No newline at end of file diff --git a/nimble/host/pts/tpg/94654-20170317-085122560.tpg b/nimble/host/pts/tpg/94654-20170317-085122560.tpg deleted file mode 100644 index f5bb0ce99c..0000000000 --- a/nimble/host/pts/tpg/94654-20170317-085122560.tpg +++ /dev/null @@ -1,1026 +0,0 @@ - -M'&/JP\$+#X83?)"[ M2E=\N*7*U 5)JSKT(5#=>@^/#]IP*[GTZ0%0]$F(/$ -MEK[V7>349??;!JZJNFZ CK=QGD^FOYV^FU>"DK<@0U*##HV\H9&_%["5IK@1 -MA9F,FJO2P^3:4_]04%-0T%9=^XCMWKF"L$[)%)G>_I 0Q?@:H)&1HX)7VY&. -M3 *!JH;^YUJ1[_*7JN2'Z5^*0I&NP+[LAE:>S92BP^T:3+B>IKFJJ8A,4Y^L -MUX+P_C'Z#VN20)A!ANN2@J#!AYY4"KQ\5):1]+[B\TN+BI"AB8NJH ,NZ(() -MG>K?^A\-B,<@/IVC+$#XFXJ<65V*OE'"L]7*OEJ*C]CS^."A/) (K_@0 -ME"&)D)^IP]?+')Q(%NM&7:VL@*6#D!-TU,7.WG SERP(@*R+DH"MPH;@X:Y) -M]X6NG8^EC)N?AH+3[\3SG''R3(?WRGF0NZ#,_4%*E)&>&9R)5[F0OM$A0Y.; -MA8R7%EGBS&\IDPYNR%4ZV$FK^(F[P B/[TU86=H%S^ -MH[H^EYQB:MZ)A:2@IV)4O=//SXNP#%F]5N&<3KZL>(#6'H"D4\DST(O!(![@ -MUYZX#+:1G:V5BE&TGHK]+;@:^JF;;2-&@WD;Z8I9*SB5D+7 &/J8NI6GYGMDGK2(U+_)K!,I$6Q4R% -MAIE9AK#]!JAFCWWD:A8K.9O/I(;D(F2G*6A0YUCMIOQ5M*VD#1: -MG9^)MMZ GIK7,^R0^M"/\%^_B9Y7TLQ/^N?S1 DEF 6XUJU"V_3_U\44H9.; -M6C/PV(36QT(9B9^.C)*YUP?BN>#F%4ST/JM>\*Y;K)J:S+4[O%?G[S[L"^FPVC9/W+).O23U=;?;2EV+G5"5%KG(EED8SLB#Q["2.9YW6IB4DKT QL7P\,%# -MAY^ (+Y+V8GD:B'!S H%G*;=[-\ -M 0+QQ3;G\H21FY_P4-)38+ =K,/38[24B[6W\(N-L/(9[/_LY.X/OLZ%S;A> -MO0TN'._"@/.)DDZ*AGY.V1XW%G7:O+R67U"C@:L%+T\24!11KH^]@[UR\Y\T -M'G.5D/)=H)R"J6R470%+AO24DHF5L -2OV(60>3Z]/#0\HE4<(V%GXBM% 0- -M3X-@G;H%E[2$DL$P-?W&"JI0-EV0AUP(\>] XIW!BI6DO7I9T33VE._FJ(*_ -MKQ6$@E,QFO?! P_#OYFAJ_:"JEF6?]O2PM3:)3"+BYBAK :/H:SLBX.NPOA_3S>U9*&PG[SAU:$=KQR\M>?\!X3 -MZYZ?J;\8N0V1]JOBJ@3;9=L01YQ<:%>>U)-!GAL!T^"]VF8KB/^$EH.ENI:4 -M[(80V,)1T>^'[@;!KIZ5T4.RQW)2M,X;#;8LTO_GV8V[OD6F@JNK JO G$2Q -MH(=0E:GW!3:0E_/T4ZF!M!D-F1F7NI*^QP;A%%V8M*U:R59]QE^+$NONY](% -M28E"K!J#K5N5E8#B_OU9L819J(CL]20ZBF"L4*4D#JV,*& -MYJV<6(JKEZZ4+^NI?%8D<$.P^*4 Z#=7K>XM. -MU3'S/BX/AP [V4*K!EY0C-/CE//ME"./3?_H5OQM$R!7NN&@21#()=Q)MEIG -MU_Y)N7IZ .'V51 ]]L:;LEZ+DI"H^K R=CO:@D2&#^H,PQ!"EDZ>@'"*JK)I -MM9<-XF7"=^(HC+:D156UME\ U?+P=G >A(^3=EW1ZB[7^C_1CZ&R#Y!"F:FH -MHO_0SL+1D%1$55K!?)*MLC?(]!3G_A,(AXY&\M.G+@>5;>6Z]?^Z&KBV:9N< -MBRWP0KI!\#7P]MOC;Y)<5(NN%8*2GEL9'\7/SMD 1Q6PCZ]6;0T*&KK)-^4N -M-OV!3U6TE8(,B;9"K*0WH=?J*<_9J=-(NK)0LY:FO5R)P'*3V.;%;^Z6() 2 -MWEB>F*H-#0RERD0TG[]6I4)#T_26M/[GQ8V5MO]RIY&RN%W_S1G/L829DMR2 -M]('/K/92XJKUML7OR!,>P)J*"H>&-Q0-\]("+'L^-EO>=(036Y>P%.:V&"8V-7ZT139&:(YNN@Z VJQCV=M VOMJ:E/XOE(L[GZ4;QT"H -M$!AY7Y>2^:N K"-$'B0L[FEJN#[Q19:D[2;=9F*>)!$@X/4']#" -M!1&2G)8;"$M&=?M B=+DQ^YQ"-!FB)9'T\^32NDK[68N]-J[6Y^IR:Z(A[.. -M6RG95?0:6^K'2FAK[7\O>>+_9#G(I4O*2=3,_<+@R)UM-9DW*NL+I?DJA^ -M:X8+&-[1=O9MX:R#BIVVVL*?&,-#U928LBR6DI:OR/OQV_;Z"H13GEZ <)J[ -M^8(-)]\+U9V24@V?@HK_A'3=YS&MN]3U&:<&)%JJPHZ6H4 --!,T\L,(ICBY -M$XOXI)]-\^"U_CHZ!52.^"'OK$V=K;>;@,34R_HCW U3FB1#KKV/@Z#_S.'% -M9M 26;U3E76LAFN3DZG5@QO8R.G+!?N(V9N<2;,*E9E2@K&$0L$X+707X.^\ -MT*.^GE""6H$?\19Z=D.11X"6D]CR\RWCD_%?L8JF/FV$&X]!:4**[ -MIJ&85T .P5K[]>8?Q92+TN#S6X[[MHCH"/&KV'J%?' -MDXN2D@L"PEG3X\S?#I9!&(61@+:/6K0YEXK-.ODV/_?'<;&3^)J!2E##A^,3 -M^E;>K7N=]K<"P^$PWC05A%.T7+ 72YJ2?GKS[_#*?9/+D5I=DGF1MKNMU-:; -MTA'SN[>Q@KJ'7 >7QXCJY?#F JZBH%J*TH7WD[S#-.W&]"["KX^N/$.2E8- -M\'OI3>S9)=OP3U7$O"FNK.\J5(+0IC!.XWY;M$\. -M=$Z/KD^-C/1_0?_L_+W"8^N=B7="A8V64I)?G0DOR_KWS/WPQFUSE4C6DDBH -MPJ(PFL.YN.[W]D+^>+I&EEF\EPW'VQA<& I.AD"V5P+ .6_&1:%>-O&=E8%* -M4Z0_F\3GXHI]D-*1FG<:^(&&FQ$__=_Z\-!-I[N#]"^O-VP$ U1GN0\!K]*A/C9:4F99SFM+[ -M[/?CV\*/O(Z#ME:'OC&&?BVA3B31],CN[TF*EE6"FYY(_IXY];+QIY%OQ/?P -MO'*3\1.ABJKLSL+ 7[&CG)>!3%[%>BSWMCX#>%VV+I"SC'*XM%O%*Q$\F$3R -MFPZ16JEA@IM"\L/P^B,0TK:X6KG'%9"W[*C0N>76+Q%7H<_>PHYZHI3A)I%T -M'CJE1J;\5+\;VP%IFYWG(<')6(D;XR:/K)56#*O 5YC#VK;WD_H'2JC>IQI2 -M#Q)4X? :TPVM[5T "L<4HRZ>IZZGK_N#H)Z#!2#PQ>W&P5H#TE6?DII]0?_U -M&*Q64E:.A]I>Y.KMN_K%\W60 9M4G7>#89>?AQ=WP<6$M/BPF(@#DXY8H>HV -M_98"]E%UHB\\ASAPD.K1\^:UE\.K'Z!]6YL*DABNQ='FFM8U\J>$N;^)5E:; -M)HY7P\"EFN02YN[;E$Z.O[U&K 1"I3*7,,8PB6.?)NNE%"<+^?)R\BZB9Z6IC<;N)4W -MEY_GY\JLE%.13J-^"6Q2BLC7\M ,DGJQ)(E!VJ2>JL$T&>X]XL(MD$C9 KM8 -M%Y>>1_Z3H)?PNK"UEQY;MXY:G%GHQVX4[8_K5(P&CO(G'D&LVCKQRXG#YNWUT]23B'FSNANK -M@Z20C[BBQL4UU=+ND/(1D56Y OC->0^5A'RAD:0)&OZ$T.+\%E=K2E)F21L'SG5?CVIO&C8Z+K@7F\3[O\+J% -MK ,6OHYV"U3WZ=%^O_I*[+2LOFNZ'JB&3Z[%X$%9K\/(9II5A+\>CLV44)DG -MY"7V/;KFB)A=4].7@ZASJ'":Q?OL=UEIJBM)BH:'DOQRDJGTL!*[0>HY??Y= -MFH1(OYRWAUJ2T4S+"ZR@FZZRN4&HP\;T]IH2Q9F!DZV225N_C9);$_T!Y9J6 -MB?F&05X*DJ"#A3HS)L?'&@E>::Z$F&OD%;D[>K$/HNT2&C7!VF$ _$SYEG(;VM@7+&[?+^VI-.F;>X -M4$N*I)"B-MC^$ ;YV2@#T;JXA(JZ$ N3WQ-JL"%2M&J##F86WT/BL'P -MY.VZ(+&==J "\H:'QX.LP/#E[>8/BUZF'QI-5Y"0G*"V[S?D9O%'18Y.OQY. -MBN.WELSHV]K#\>(NUEP8;K>_4;:W^HE8]=?]M-" G)V?4[6AJYZ2EEO(SYH. -MTTO,P0*3G@V)GMG/YD6U,L<2Y XGUX) -M5_*33$# Y3?& [B;I:JP:89:E>KG^_6:7=8*G*!8[&^$;(Z@1KQ02XQR>D^[0?W8I/O-HL#UDI)0DZAU -MB0)0^(Z7S,)\T"?Z U#6N@25I]B*U0;.UH2"=%]>6:ZX\2'U/M(5U716I!UU -MAU>VX _/V?RJT)V2DA"&F9I3<(VJ\_9U\.#3L9.F9)JHII.?H+_E_M'N.AC' -MLJ26B+DMEGL&T.?A\O3"2VZZG P?TXM@[/:MS>W.P<\+W$D$U;_/>$NY>I>X -M@7(U+^;^3T^$B;-_E[M7GA&.60E*V?<3XZ;8V;L]]0J6EIF<%& -J5L2]SOF -M)..<4(JK6EB.FR?/*Y/*3^&/#W\G-)F'B? -M_I^'2E1MGHKG[)A4BPP,6SO'#EU2L@8-FX'XNKJJMD?P]A#56)N3GJ:]0(]# -MKQOCD)&4K4(9#][#/G_6O= #>+!255^7FJLR<%C8RX_1K[:$A7N@B;OC]X-8 -MD<#T'M<6O7NCD]Z'?G!;B/,JPSIMY8V7L!]:YYA>@(CT]#ETYC7;3**MC$LL -MGITZ!Y[MV@],Q_+DGQ6>J,^3K(EMA+=-(OW7L//1@8:QI5G:JH(>;!2"QRXJ -M+R[F!=L=DUCVD5J60+I_Q%R+1_*UQG;UV46@EY],D=";@:GC\)J8F)M;W8R; -M*.+3[O8_Q?!5A-&;R((_DEJ? LG"R$Q\%E20$:^YD96)27[S\]/WG8,";9:< -MB\;UOXW--C77[].KC!/_VJ;VMZ.4P+KM^M R]8]67@PGA[R'HA)=V0W=!13! -MY%:R5&I>GJT_;)R Q5/7[);$"[J:>U7SEY&\5B95RW<.4*_2T\;"V(-3OI]Y -M\@__\X:4/1J3QT3^-=.JL]O[I3=Q1GB=J]ISE]AB"MH2U.UFE?U7^,8K))8C=:WBEBA$ISUM_JO# !"7X>:K!ML#X,"_.J= -MG!R4+TY!FAEF5YO2PO$U[*- [4:L7U8]CA>_O)CFP<7;TQ"2IKGZN5>GGPAS -M.;5>5A ;3I:$O*=[#2@N0NZU'H$O7!BZB==5R7@K:4D->IP,'V\CHW@)Z40(>&U;>7 -M1P/+%KBF6Y]?D)!6\L'U->V;]1S=])[\45:#HI67Q LF:<'M@% 1!+V?BN4)3P"-F-18@GM^ -MB*CJ)3+6X,]04)Y;!?R;@V&PFM7.UT&$4!&III5*O9)WV=L2=^YN&LJ[%^V> -M^8,L'!J(D2(FN_1!#SIX%YN/5E^Q;BS"YO_$/\M-5H2=KYR&T+"@GN#,(?G! -M#\A+NYR\%)V%/7N.>R3Q[._&\]JK7Y"+2Y>*JA>IIZE)7I@*XWH6T32[6]6: -MDE";E_',D)?HU"T:YM[A4""1K*)S\ED S^+T6 O:>(>5&_W',OEWT#[C78"> -M&9/2N;T(C;VI#ML)O9.24?.8_!ULCY#%%\3&^]DT8IN UZJHKOWRJB$S^58O -MVTM:L8-\#__SHTK3:?&_L/#V[).5W*:>.9*3O%L"P*T-[H-"IR>MSFR?C*V, -M7@BBPF?DU' *@?*UWU>:HT);D=H.\9>.2TT$P_?4:TX,\+NFJZ@";%6XXS;N -M\O"]VI6&I%N&,+:S)2L3YC&CGJ]R")Y[PR@P[;/_R7I0,$)*=0Y7SNZ"6D_%]Q="M%!&:FJS7 -MEMDR]?W +_V8I>";BHB]UK.,S/(QE??CBZ9@20F__):6I('^/,;W]=B/6Y^, -M@IA>B[!3FPDMXWV\C 9CG6)O96G H-MEHO!3L#FE)82CY>(F8FACI^'F^\P\%K0YJ>( -ML\Z3DHZWO$DPP>+ TPT@28J,F+R&64#!QNR0/]!8CU::O8^>O6>AH$+!S/[- -MY]/4CY#_N8\NCTN@6[?1:OF6]?7%!U>?7UKPC5)"XY*;\,82 ^\%R\-)ZJR9 -M7UK0FZJFL%>MTR9W-<75I9A0@EOP6)^=4-4#Y@^CDZTT45I;R?XY9__P Y!2 -M7D2 ,)(7HJ8:T<,*_863^XETD)J;8I92Y_(E]B_3U(>2X)WV2]:"AIS''MS^ -M-/*(EZQ:@^W7PK6*(.)9Y/8PXI:"! Z?BZMI1I;91/[)R.7"MNN:D Q'^KU<\5$<:<8!WC4$,SLT-V_Z M$U=GJ"^3D?;FF.T@2?V -M/K0[HE"0G'@_UI2;]]COX1F<%%&5CISZ>\3'Y-_Z-/.JEI.MH-,7JJ9VE_%= -M,@YVK@V2V6]?*7-+JUMJ/6I"5IY^5"W.R$^'S^486[]%* -MKI$C6Z9.F*)@GKB'B %&2#&U3&8K:U9&J81DY*05ADDPG'6X$8+D/:8<+Z) -MN-DM1\'<6@O>?07UF%C),M,P]/X*^GR3AU99G .AEBG-[=NPF9+?A(Q=2]N$ -M3Y\"DKTZQN49B(YX&HF'3K:*FG,;O3KG\ZU6A/.I@RV&4(KP^C<\^\>E#*1% -MZ!F/CKJYCIO#QX&,RV;0CZ)=J :>#8N")MLI<]7V+._BGI)]FQ>WD5H(:))7 -M8*(+U0L(Y^-8N0X9$+RF0*I?K,Y7S=0YU/Y$\3CVHKREH,*!P0,*T;BFHXV. -M7;B-1='8T/OGR+F6O@Z65ZFWJ'^;052%R)&@$5_ 9[CIPQ1=7FHV9>NE*HH6="LC/ -M2-'6V$:D7!^]AX]O>HW]\3@9I^;U\Z:8G)M7LHJ*T'"@4L$-^E[3AL[ \8K= -MN;>LF@^KLZF0>MCPEI/0N\=:=C>(EEU*5N4,HN"4G(H=I8D2C -MMJ"?DX&;MP6R*N#-PW:/]WPO6PQ)%,%VJ:ZJ. -MJ*"2@0+#]^_N]@^JAX:?0J:-O'&1SE>@COOE".;#]^9)FKGW"?9##K:3L'JL -M].TPY]##+%);A/H'0EL'W(\0CY&TMU"G^KG"XG3:M";)+'G_E:!=@JNX7)F) -M3T4QOG0#F*7WDZED%C="PC/[_?%4KH^64UAKV%*U0=G'[/04B:N2N,F+GIA& -MB97"X^[TU_971:1]B:=6N)U&NMCPSXOY#\[9O:.=@$,.0:B25[L'/O;%TE+/ -M2:H9@YY7C2QT08^0S2VJQ\<*U4?B/]2=I5NEKPN2\+:+(O+'-^X^YWF@DYN/ -MHKR7)KXL-1;176O#6D!?FKJN&QW^?C\J;DNQV -MBZ'6$*'/'ACJTYYK!F]%LOM)X9&@F;F0,'![/]D:.- -M6@C^ N/$\2PMFL.8!!'UEA&8GN2FGL'#0<05D)X=FJ*[F(&6]PWST-7$\+2K -MCJ2=>EE?E=*\Z?IMU#)+2IK* IQMAX!:O\JJ=<3\]M"+1I'JJYZ]"*2:G5C< -MR*5C0/&/5I")E(RNJ_B5VLT^.6(ZED^'NX]3G_(MC'NZMIG,S_C5_2?9HM&> -MG'BS>O!FBY.LEYW6(OR_.$QA8H!T494B8K,]'35DI1& -MN@@1A)^2_@VAI9E2XLL05! 4W9(U69*P7E+1\/3[E]+@FX6AL]>-#8*!O**Z -M/:S$SS^ZQ!JKC87[B[@)X_R@QOP%N?>IO(*&A<\1LYLA#$S[(<=1CO8-K8,: -M;(J0]XCG'_F@8L2:HKQ]V7J<9T*4:%9;04[J"^.+T<, @5^[HIX7N[N4N_!V -MQ-[O$/_D<)R"D+VDR9Z7 -: AA"$B"R5G9A+!_#@_%;F3PJ<4XZ0E5>KL!(J -M],+:DH_"0]^D=((*H)I?V.@U;<9ET8%0HI>H@Y1T YCU_F?P\@-)L)!6UDM. -M#XLMI\ 3]]HP U[WA)Q/.$'/*%"!]]3!:I[U!@<2^@J$F V0ED19VOXSUN;V -MXKBMJWZLEAN:6*P6F<+"R ,/Q^'W2(C2"4N:$+N"@[B0F_+;Y28:,L"\H)I? -M]ET;B_7,YQVOL91TGE%:FU+K^>YOUE.?D_ %LY/^FTQ3FLW_J39\\EX4S**Z -MF:(&]MGKP/?5Q=C*G*B76&C=IEL:HL(NFB?AJ51RJQKO5C!)O '7T_?@[\*B -MCKR<0UQOBV"F \OL?)D/Y1:#Q/W.@]X.O9)7B4B0+MYR=1DYL)P\??[<[2 -MRU*47U>'#*6@O&5B$?I\V+^3H%=:4K9:GX0!5CCZ\_X/:S9<@:^&5I-PM_O9 -MBERO2_; 1PY?A(,/AJMKG?DG,?]^U"?3XY)5$*S/BOF!IC.XR,C0(J+DR\"< -MQ[(UDU>'AZGX(%:7YSYCYN;>SQ"0B]TV 8NHP0[ \_&6(ATF79>O 3#SKL9O -MSYJ;M/$>]UG^L%Y;&?KS')ZQMJ^FM)):AD87"JOC+/H+,D>4$9J?DUW&4HHG -MX#3:-\F-J0>LSC -ME\";IG1["//YML:23[M=KU5ZSN\6"&6VLR$,Z O'!\S9$"*V>YL C:J=K^=5G>?]\E6\S!0\Y2?DEV" PDYEM?E]CS]_#7391&JIG+ -M4E^5'<<4+3+N;O*.@ER>%(V^@I./NHG$Q,S5P/!'M]P=B_^!;SA63Q+K^3OE -MO\\^EIT?2I:/&DFF#[C!#,"G^\_^Q39JNERS6Y:;@Y^QAE>9__B;_=IK49CS -MK821OX*1 O;1F)&1O7*0F%# T^3"=L"C'8@)M8:S4M/&>YK:R0_!CIB;E7*@ -MJ;:ZD'L(U#EZ1L,1F2:@2UJ-6$WPC$CJ_3KURHN_AJNL1Y)&$HSRPM2ZUBS' -M#I2(3L=:;XUFXC -M.HNR(@->1T^:D(JBY_62- -#6C@!EIM/E:6*23IM?]>20:D&#>F,AI2[#$9^ -MZ,_@^,4#X ]V48P6EX\8H 9:Q_1#-/+N#P*-A8**1D">5BF&@0D"B<\##JW9 -M-=BN!+M65;CYDJ&.ET<^*$X.>LK.*'ZBB+2#*T(95U%2=#(&:@+*@>_,T.?;0(+!+%$&;K&J/CY#* -MHM+QTI(/1_ [O9Q(A)):NL#$^1)GYL6,GK&,5H>/:Q!>6SV/2725PU=[ U>MOEX]2N/^BCG(,M%:DSM'B^X);Q]:]F"RRDI>KL()C -MIE<#,KVWF^XB_[*7KH+QKE?E:X-ACY:1]+ZW6+/9(L7G[+_S"K*FG,>\G'*6 -M<#G'W<>05).VA)^%KE."EACQ/N;UQ"?;O5^P"5@;OY!35='"=O746TJ5E+%3 -MA_;F(" 6>WO#^1'T'((FMD6&\.WL_3B..1& -MQU:MGF&KFDM\3[*GR3+G\!K!8)9F*9F3?9J;O_&S[.6UQ -?5X> C-N>HJV. -M6/' I0"3T>96:O[58O*>HJEN5I)[!OD:2=N G'!!>=(*9KXW5Z0,0CM!SE4^9OI,*]\,Z -M=&?/AG&4G?69 %>QM_O7'JO;K?R^O:;97JFL'?L-T.$_^B+P2:>&.1/95X>B -MH%GT./;BZ9?;OV-D<)]E#M3YRU$YBY61 -M[$^.F)BAI(MQU/4WY_32HH^[VJ/; -MJ:-R_Z4 1;EVI#V&6.S_92M2&V;I'9*R-S!T,;VTYU>K,1)EI];N$>3))'5 -M$!3[\+TLFW*6I:B<0:.20N?B3@\K!F6OT^L/J8B#MX]+>,2/./%T.ZN -M6*1Q'I&^FL?<]M"?H)1WMH&:OUG^_)?F]<"=@#9>II%+^JRFOL46PY;^O<&- -M3I>;O6I:&_<3[=+FPQ"#A$KXEDN;E_&*&SIU^C7/$[:&>YPG)GH.EQEO,Y,$?POKPG-9QO(Z)UXNHPMKC -MK***N194FK<"Z#/ZW^;;K8N7K/>7XKM^^?F -MWB$269JXK1.14E;Q <#^9I+2:U*,AE^;FY)7@L?:PM,>^FS2O_"8A)^^/KF0 -M4AE#1<_(]=5T3(Y_KY2O60O(M%^9M-D2)U*!-/;RT)+C-?(;L9%2L-*;AS^4 -M=8?:P_E[YA6;=+3_$BC=C8#J31.19G#028S_OXY"N%RHI)0+0MZ7XMAS=_\^L;%;Q)( -M>IRG5Y>5O@3CDS[F/I""D%6*CMR52JSUEMD<1OT5V1Q&O[F4:7Z6BZ#RDM/B -M\3;RU\"2GBB3K%YOMYJLGI_-5@OO^0C$4D-7!@T8CUEI.#DT_>BKQ,\.S2 -MNCO6B;JMA>]R:X*J6DT(S\O3]L\1S[11J!:+X8-@1/W3\O/0+OK7 QZ>H9*$ -MSJFGH*>=#5?HP$:CY_]@JA,C992@Y>MV_#PY_ EVU06<+E?E8)3!WVE -M *W3H-"F2KI;9]'YOU -MQOH*UJM.1D.)C01P2.B-_M?FY<,^AFA0JZL&MJ<4<<34T#?6(QE2VFCOAFZ -ML(W]+?H,[UR@Y)>$C8J_FXNGP9I(TQ;WT[ L#Y&8G-JJI(B>T^!6^-'"49\K -MS(KE18J5D2$#CH,(LF!=PU'>U,+:]<-4$YN\D@$"EPS*T[65B8N4AAFJ&1?K -M[)?RP@MY]I:MCZ% DJ&,DJ?)SM*%G(.;F@*^5L)?U^5[T2?&SU1*G^V;@X>] -MU9;%P7)C>CHE2)9!NP&'6YO3*O$S_6XU^O+"A'Y 0JI;:4765Q',R0\' U6' -MEH6437W%1J"6K0=I[7OW]L-*CH2*WE(+F?&H5E*:[M *^(?1Q0B+5)Z@G!:[ -MNH)@7%^A4!6^)B+G** +E-")N9K+!M+DK_K+W7!0@H_G]C3P\K(%_Y&>L?+% -M4[T-NH+EZ440G)12*QH9FIJ5CK<5\O?W\\#)CY:A^U.-J%"EC,#Z-MSR6(>6 -MI:U6RUJ2 X_ UM$F-/?SAQZ,+>^S6@R#J&$;)APO!9DNOKW"?CJNJ6[JEW>CY^77P, "X49I;IZ"3BL#% -M)O11HDN$Q*5:K\+2K?#&QMM<5(.8LB&V2X9PJ2G_ZU&?H(&>GY._@J)/F8+ -M[3HW\N"ZC\&8\8]=OX.^(>'%GJ:A0!DC\^8WU\-71CC825X! -M*J8 D,3J>,7NSMQ)C\Z,'+X50)0WBN^+G*(DJ5VW@H/!V2.)CG 8"L0#T^P,:N+ -MAZ17B<"KM=8N*(G7H/NN37^"7Z#8\<,Z,'K*@XY=X(M22T>26K:CP-7?WI,8 -MBS>L'&FH;4\FLM-,WC?$/!?S!UAVDK86KU>#D*:QR,=J]+,)4PI(6"ZZ1\YFZ2(NHJ' -MF).=8Y>:R.+:P8^;D;ZPD5)W!8RXT/;Q)O;U0ZE>.%S]]!NI^Z&]DRQ -M=IJZBH&B#(W)@@7+QJY;ZT.[MZE;"*)=7Z+CUDNM(N?^P-3BA" 6NQITMBT* -MBO"+_B*0'8R'G'O@]O3N>OKS3$G2^0^(NE<#GGK#S\M02D/Q_W:4RGNBMXG! -M,C#V[%#EPY1F0UKKGJ;?3B7W]?0UD6-WIJN;AQ[%F*7A]#Z:\._5BY><3*O[ -MG3NMEDL- <;HR\?PEH!<5,3RGK^UH(M13\M"4&KJ8@I[[\6/!\^0GF%O[MH.2 -MB+WPLL#W]_4P-!L:D$Q=NX=6!KM!T=XY.G#OVIF:K(V#!ZD9N%K#PQWDR-[% -MY ^F#$SLM[MJN%ZHP4/TYA8P6LB_EK*"?E*:"^@PEV36 G4*_[GW-8 -MCY."H[G4^$BKB, -M5P#4V=/E[E.#>'M56@"Y5X*J@7(/PTF<6 -M[N6FC NQN/>0^9[$PJ75WJ6>65J=BA$A:[E3T/W%6EB G9>5JECAC%?!_0]) -M\* ZA9:AFD*!GYO8\O;V<]K0FI:4B*NY5I1'C%#V=3:V Y*[DML*N)>4DVH( -M].W&-,;PCU8)[9J%Z[BAUBW*S.L%3R+8EW:=C$M5A)"I^I[ NN$0XOK'S;^+ -MH:HFYJNQPEK#$L9)Q*OL!P\VAK);4*Z@K_;1H8X?<,/3.C_@(X1V?H>ZD+J3 -ME2IA^,:IRG\JP'GK;:Y!"#7FQ LY/=EEZ64O(]W^62SX^V>&W/ -M6XV I%^IX,:)R4]#FF,?J8Q##:4T1.FJW"+);'V]R*D$:K -MNJ:6\)<(D_GWQ'XBIIKBB1:=.O(0JJC$)-_V9D^GED3EC(9?3<"0O]G_J,D5 -M6]8I1@^-AYB.B[F0?77^"$HT<:+_=&' -M?@Y+G['&GXD*F<'W]<8*O)""B1X'DIO"_]J9S-02F[>BFA#C\O,_[N;)7[R2 -M'02(GHJFE[K(P_#=J$B;JZ8E>_M,%_T16_#"?O(FL1(FT<%+)S=;+(=B63WN.CXF:F;F0 -M5HL2N^3F)?S(DP>$IK>WDI8@99^;Q>QYT\'_C<\":7^9PRF6NX)0A* )\<#W -M1G'. -M03CN]L8W\X=>7#VO5:UOS .:S-P.S>O'X@J&1-1&CI2;,/#ZS/8M[AW^!Z], -M%5,;\JZV7B , QD(J,>*K#?><\)*;DI 4NO?B>>#WV]5-ED914*'Z -M"\SNP_91D]&-IEU:D\/6N-65_L\=O88?4]2:7;"0EW$'04F9D,I$IYTJ6_AV -M@PW &4?ORV2-6BR:DJJ*IM*IX=0LWI)/ Y*DDHI8BEN53?$Q_Q8N5\6LFE&Z -MAUH%4T9-S2' ZP#2AM"?SYV?BPMEGN%T3S%JO%I>IMHO: -MPX'$V'S)\]P;FK2%EZ9-ED.@6EOB]C]^W_Y!=8F*CO67OG/A(],5K]A*5))3 -M7X.)*B#N0!*+,!S;G*1QEY*CW#U)_X+<&-"6/(ZE_X%[EIW2T?ST=\/+A_PU -MU_N(OH^E;,&X93+0(PN4H9U!FWQVD4QEXY;5YO*!E[I0"9S^H2C!I9+2S(TI -MZ_'+KH2LOX:/O*J4$%/Q,><:WC7' SA0BKHW[KN"#):=T5[!XNH-S:[8D5Z% -M0YN60IBBK8^;I?;DQ=3OHZV6&'B:HJN=$_ZC&;&:4?R7^).1PI(L_>;$*5BQ -MF_"%\5J7::6^@7SQPIQ1HIZ.B/);\HZ9#/#@^A^GUKB'PI] CXN?ATX(PM5& -M-_.Y3A 76X?XU9>7T,'E+9HD"I]4#X'IEXWMQ89]PLP!Q5U%V[NPF!6-/D[- -MJ >8S9(Y,#J[Y6&(3-> GDN;FJP/N>+B"-[1W*7;=(AKLJOI9WJ/7_ -M[3?N%\^>E*>KFDB#D2W4RN"5D'Z,FM"9T,%^P<7$/E,?EEY>FA&(NN&V6Q3# -MP-NX64[FD0H/D^=?PS]!"AFJ/J-M2EE.X4.)LM!7#6Z:ZCZF0K%;7 -M:M+"+5/U]]57''F5BQ>=2[I^KRB**P_CQ]SNM%H-F1:EH(@WJT+P)NX6[/61 -M?:T1 "*"BX)IA*O P_H!Z^A= ]1(F@L@VD:K@@2!AIK'PD7[U]/CM=PCE=*7 -M I<9QO,54R@DBCB1Y'E^4]D'? WJ>9=IJF -MM9TKE^/N-_*;HI.@4H&/N)9)E$/S^,9V!]E08%&SBKW.G^_%T,5_\L/V@U1Z -M:FU&:VF@I+_3^-:OWO/9GU>6KHJ=CQJV_XE2\?F:U\8GXYK.OZARJH)0K Z> -MZ1@M]/Q_S.,3RYZ?MT*ZJ)J2IG")\Y \]O8T 4>\0I66D*B!P4TCT9GX4I". -M49H)V.+T_Y VP)2QDX^6<9Y0DHR=V>?/^:PCE%L0\:GY1!^# L#35A?BLDJ, -M-E/9NI)4'[R-ZM,7N]6? NC_6ZM.)J"_\.@1-_!NYHU/F=6;6%6[(Y>3R_[) -M+0L32@R&6KA#7 5*I%I!*/B3N]KMTXN.6P";CD&:0&RRN^S\V,;("A^CX:N- -MGH&*6H;^D('^7UDQ^4;%Q-NZ2%^6AE*?^L+_#[8&B9:[$'<*N -M_I &V5;(&=.9LI>3KZ4?\304]B>*ICWNOL:N@Y*GK5B,#H3! +0Y39Q.29H; -MBZ&7U^[U'"W>!M#+J#V74Z(;&%.@5OT! -M]"5N1B;BG*!QL3)S@8G#6L,:1Z&+C573EINHXFSWP-> K)*7D:9=2XM@!JC3 -M%P+ESI3T!O9\BIBF6@/-_NUN\"71BPY$]IZ-TA11J!":_)8UVU*^)I>2DP^/ -MH(^-*;SL[; #2869B$6'G;ESFHKPU FM!L/EA7>_P#F:P8^X%?DAXFSZQ>_U -MJ0Z(EKBZ@4NAH%>3".SIALF):P-"H[ROMUIR ZX?DG>"C>K6Q_ILP-_\N@Z% -MI8*ZS=G1UEP1LG:U\*F*S?G&YM(OVKI=MJM[MXG[>)>"T<\@M'Q6DY^46?#Q -M((*HP78W=C?/X$K=Z8/\CH7<%:C%(#/']L6Y>^Y\4&>KT]M26)\S6 -MCXP_+>^M+*:? ^K/$,%8\,*T18^+?HNK@IVZV6@5)\?@((QQ"0($FO -M5H-9D\W^->;U^]5<=O.=1HJ*F*@, _#,UU&_MI&;<'%7F+A>J]4R?; _HMP/ -MI&)"D[J&P%75PN+_[]+6D[7SDU:M59*:O\?$/T;Z)B:.FE2,EXALDRQ4N]C -MUH55#V OCE@4AIP/2*/;_V$0U/Y YL5*F];95Y"]G+.REILBABFBZ?G-PYV( -MK+V F):;7K>@7@O!8D:R[M)GO)*TG(^8BJU!!-O@4/9R_I90UD,G,_,_]^Y& -MD<@+E7+0@=V$A:_K+2\;D=Q4F170BA>[L%GPZGG;[@*6OP>,2*A*A+7>B 'Q -M^,?0 \]6H"J1BIH<0X[T^C:U[/7#1:1VR>/_G;O$G?_(B$]:Z\76B9Q*G$>& -MNY"[IH-U<'FTPD3.ZT>LH-&PQ[I3K(VWP>KZ"L>M_//3D7+57YY>F)HVIE6K -M0O#4]C3EX71TI%$&H[(MD-;;V+FXWE^PT5(ID/INVC)6H*V(?[M6FIF2N!XK -MQ8DI:-B:RI,\;%E_*''8!=5NN2 -M&O\!Q\ W/L>OSHO]D.V-3KZG,/ S"0[>H\OE$%Z?AYR'K$R#,[!XD>G5-#IF -MSQ":A0B,=>J6,[JCF0-*_/4H M_RP9%'C<.,I$:P0OA0BP*D]?XZ.Z:7\!*? -M4@F;JT+OPOR0D+"YMY&L>M?_[,>L=J*P")Z?=H&IDZ8U^^/%X4C\5J*HMG>H -M6*V,347V7)?_YU"=5G*9M@E_EY"\X4'Y.F[78H>0^HAM&J>#+S7!^",7D"\#!VQI)S@^EEUH4FX6'MP$4$SH>E\*[EI674G*XDY8L -M%YT(Q='2QBGJ#U&Z])]>L\:JG+ZLAIOS-CD^-# #F$&P'J" JYN'+0&P.G(* -MFUI94ZCQU/GPX"^#]YA?G/J")PM?G/:]^?9IHY*5^FNE5.&C[K! -MP'U2RR+8XQ:4Z)RR%-BDD%$H\O;%Y?8 JS*=TKF5Y[H>H$8 \0X$2OC+ .76 -MDJZONUKZ2]Q:;81XB>+%0/OR<:Z4AE$2U]J]\*W1BH9)B?T:6)>"Y_OU]?H^ -MUY>A@IU?DI)8ECV[S>L'29&PD)U:HP.;:/:= 7YS?C3OUKM/L%U2'0Y6(0K8 -MP!'D]^>;H&R:ELM?A(- 09^L\C 0VT,0C(KM7^2Y089+]/KNR.=:V$V41DJK -M3;ZYJI29\RO1]K*T0J^>'4#7GXV2DX"&F6<'[,7JK[);=EUV=V&D -MD^C' +)<"%^9#KU#N)*$2-$^9/8^)I!"C$!^F@ZY&-1?00JBWZ-7?GP.V0I%:0AJWP\HG ]#;Z]!): -MGK2'[:_8;-]L]X+8W.'JI\$)AI_>X%Z>K:JYL(,*]^W$V_7PS9*57ZI64)R^ -M,_6N]0+ITOZ'XL$QG8@>M7GTBU9&B*6S8*K&QM#GY7J+H)6F4I/SS,M2X?V( -M.H6UTT#S"1[4QCI]PP0R6_R>5UZXY9Q*]R+2U86BNE6,D8G#>*3]X\+Q_^X% -M$D+R(%/QQKA3GTP PC7V']*)5[.^FH*L3Z&< >+VT/;%B,>-G)Q/CHF-D(V_ -MP/S$S5S VZ_:F$B'TA[J[!?_$_?]PNXTSXJ,51]^!A-RE'(0<.W-Q!;.R\/" -MU$;:!:&7HHU>D\&:NP#S[S8R/>:X@Y^\E%BZGLD-HQ)0E).TP%R6"N?P-9WV -M\@%=D9J-=I*KEY;<7TC/ZH6%G!.,L)":FS > O?R)?;GVLIH]:.#FBV*\+%- -MK3+%DL8!0(>@&];FTX)2E@V6Q-;VE@.6FK:$H'(54W'&MB7D%0: -MZ9R!.L"F"QD2T]?0]"6O"(4UJ@^/0Z1%E9=Q&"A.TLI"6\!+7<6CFG^(D]ZY -MCM+!,>SNOA037(JD?50#O%DMPUNT#(*:$9_53KU%D&;BE:W/79F)K9V$@KBQ -MI)C([VO*=8F6E)H)7JB@A:M(^=DUK\/\3\3$F+N*GX!S'Z7VE1KSVYJ7I B" -M T2$,Z !WD&O]):BB7*$GIZZ#+K&FO?11>WJW=$9BJ7]BD,]ELJYCI*B\Z'Z -ME^7 IU(P0T>K!8ASI_SV8G0;I_+9)BP2!YCP -MD9":$0.(PRK#"9I4@!^.F8+3#70Y,#SZ2KIP6OBU]XB#:;>#!\U%/"^B I2B -M7+*]0):3V?+')G;%&HN%D+U:B(>:DT_9DO4[_ .&FGJ"FI/ZII68U\*L[B[O -MX8=%G[Y4OXNM1C>9)\P$S4OKG!>.E$0\OX22EK*0T.JPD3]?+V+G&X0_>=7IERJ,'?S^"5 -MB!X=A)D%)4M!-3K:.V6Q$)BN @_9SFB[1D/%P,F_:G8J;KYYWJYO1+L_6AZ&V!9."O$-SZ_7& -ML#)"A+&BKYW7?JB3GX]PW=#B7IQ2O( WUYE(LI+AZ\;^==D(JI;AUP(GEGI? -MJ-GT-3>2YTM0^)-[NUPR]I7LZF-F.D:G@Q8NK(*8J\^DO9+,U:L?)O+6NU^6 -MC(<854> #'K!WB[Z-"[BO9B>@SN$DUJFLD2J]_P*)T;2R?;)TH>8@(&0@WI* -M29* S93'5?_T6ZW<5(W?\JN7$8;NX8BV/JE679IXS3)4_<#VCK^D4GR/B8*= -MI9""Y,.EU%^ ]JV. JJJJEY102O?$,7IUCF.N+.^BIB2_[Z'_K;'YHJ=O_A6 -MN9*6=]"\R/'Y;AO$TS\4>DQ9C8U&L#JK@LK\R43S$\] %F@7NKR=0X:SQ\(P -MD#?%K[J<>(%:IXM>"Z&6JZH #J^#NT]2_B)8% -M==SZ@L9?NO>[U>;6Q=2 EZ&ZNH:'GE%, NHU\)X(Y]*2-PF*]EJ11>7R=3?5 -M\,-OE[V=EJYAB6"DN2S*CL%&U1Q?IX?!C*P-2Z&5_\%ZM-;EYD$9N/R1C%R3 -MJYF3IK;8POS1!@J+S_9C?+V;@9N2J'.20YT@YL;V?O8BF+96&9I=&G\55PMF -MA(B3D)>8J[,-]#UT']?.NJ**1[:*LOZT1X,!6<#6C)!>1*0=RD%@FO_:^^;G -M]<+VS="MLO*OCOH I:/R,1?N0XJRI$E+GIZ5FX##/GGVX-#'3X:$/(FLSH>Y -MDC_+ 8Z3SLNV382'BKM,2;MSCE^-<>'BF^?CU>"T#B; -MDL&DD,JS].[2YB&T4G);AAR#J4WCBT6828H%D$JH?W&6],?W]@N>B9.1-X"" -MD+0V4LD#KL#^$ JLH_T;F6RV0N*:]71FKO!GGJ K7$*3IA6DQ]Y6DM?50J:6 -M>]ZM6EZ:G&N4)T=^$ %JKA 10+7ER/YJR\AKFB5P'" -M]II0K *3WDVSK)2IC(.AAIW9Z'HA@X7^P)F3GJM;J ^;_%*DGJT!$'&6^C6% -ME'04J=ZS_ZC@S/"3VHO[KYN(^9[2U/74NM!'^*/2A-I7@EZ"IGOA^0[=WZ8Q -MK=ZQ0EVAI9_A(KG /J"?GIVMOIB S@-8XC,VFN8*KYH$B[F$ -M@MATJ:>HV-7KURX2_J+42\AY\MNPGKN*N).W3<;!;_/WPHFQFGW4L7Z7PJM; -M3Q+8[!;!S[S -M[?8%-HB/D%J#CY00N(6@X!$W]>]+592I5HB'GZ-8$_XU%CI_P,T>?YB7L@EH -MJ W6R0_NVO3U&<*6A[_75>V+HI>;\_[U\#9&X(B^G:""=M#>TJ $6(T-RXJJ -MR\%!F*O^F5&[OD&80LIV8E]3#Y].1D$&M5:?^LT?J -M)SK%L]JNAE^0LA=[NTV&DL<,RM:\T%.-4%RSJ7A'JJC!M?3'RQ.+5J!7";BK -MOI,\P7+U]/?+B\:@@)Q''J23C.6S]2_N]N4>M;S,3YR$@SBRB,'5Q(3U ,&) -MEE^!EYY+4,9^@(CT]V;U]@.M7HUSB)^*LE'!IIW0PO@G RP_(D72$I:N7F1FQH8Z):?[YU#K^ -M IQ3T[E&43.1PHL'T[CP6AZ 0O:0\,;%0KOV HB((927D7RMPMN2Q://M'HV -M%+BD01H]MI8.P?OMQCX#YDJ6K*JHN5^>=X^%*FRR[\5#5B1:NJC\OO4*67OQ -M1Y)RH)Z@1\"&FYZHS%*:]]W/R-_Q,)?R.M2_'8F-+)!8R)O$U_HFVUF.L??9 -M_NM#F9#W^(E&:N7&>M[G5D<$^WM^5A**"I2-F.$PQJ_^%=*L4Y_[5O2^0O+[ -M!V94PS(S8/K:C79DGJJ3J(^5K=KSRRB_\#V-.77W@5M1ICUEH2=*HJHC_J@R@A% -M2%&M\N)M7X6+6(_/?$*B]X+K:J:VML0:^I"PGI(0FH/ JL58?8B7G195+ZK- -M\>W@^CWCE;P1\5>PFJO@IEL#*V?;D9/47T:=EE= 5%W9TMU<$Z;V6- A@IJ" -MDA7RBG$R_336B,. 8)*#V1N&!:P!PO3ZU?(2O[Z<5\KX[5,ACIW*S=?Y7=J8 -MBQ>,[ZD5CHJH3ZK1,\3S\% #1])&9SXIUW3,ZA+W]CXP)52\VJN5 -MB/;SP%.+!=T#286<-E4]B;F)1O"/I_0M/C_#";J&)*FR"+6@(*?E>=-P5L.* -MI[F*_D"6EJ*4V//D\#;_\HR&5^#/Q$$)Z/?3.:JLA(*V,I"*@ZQ=U\,Z,2[M -MVJ:<$%).IO";LL?\RN"%HZ(=18"[@=J2Q)7P1>54MHJVAB":G_I:"PSM#]&* -MG%&[]J>2F:R.2UO^$78OTK@/AY/#>@*2%;J]Y?F5(."@BPX@>HH[+":BE=K@ -M.;0VYO5FGAI,9KB) ZP]JT7.%2CO@]1&MEV 'Q6,B,*Z_P+FE_OR) <-A?M* -MV@Q;DXI&%:O9!, E+@K* P*;>E"2C%O/JDHIFH$A_F3$Q;_&E+#+L:60K'D9 -M*\_D7HBB]7"A?(K7%[SRQ^Q+<;"3^3!;>@\AEI,;#\7P7[!+G7:;0G]LGJN1 -M^I>OP,5<2;9P HB*C]1!3=#RQ>P0 ,MUDD":0W[P@Z'!<>TF[F7+KZ)059]% -MG*DAFYL*W LA%L4^( -M)LH(#HG("H?=@:R>F4""N+>31-+LUA#MY5!85%&02(H#P<*O\9F+H=26F8(" -M\O+Y]BZET=>0E%VTUUA:H/*6VP,*V%2;WI&5V('_0*:JX1*=[Y9B^ K7D%B6 -MJ)H&5:GPT#"0.H"=0*9>D(MR&_.\\L)%-N[MSXT$""J&ADE+,II7 ,[[!*7: -M\LRWF@9/K;FG.;(O*1+EQG;@P6FJCIE*A8V\0::'FT$#JA?1CBLNVKL._55: -MGFJ GI/0>/';N47D8-'5M(J=!=&V?\W9PM.=AK*[U9""K\UB;/3 +\*$6!'\ -MFD&"KKFD5LT% -)_D)@&MA2OQ@*ZD$>7B89-TJR:&QD.?Q'+RO&'=':-B7V%7KI7 -MFR?3[\06/MNYFM"#.)^1B98PFO\E!^[A+@O$]WQ"KHF? B>+J8+#E)[,TOG -M=9/!6 &25I"Q7/T91,'!A;!;N9!;BG+8\_/V0C$^8 ;JV6YO8\G[2/?[!BIB= -M2)J<:ZF7[(Y[P\:IP\S-Z\,!ZHNQBI[&"8RAIE*^Y[CY;CYRCTI1@JR7@+XI -MP8VB]EJ+AJVR1/JW#;;'-]KURX>E^85:5YY8P!:74,M3580 DY\WE5>)<%:_ -M()Y=GNV"UEJ08X-;C9A:N(1(Z]$>)@'/6XB:W$B,L[&, >HYD!#DP5>5K*&I -MFX5JHYY[",0&VM[ FX6D#$&)5YR+$;N8@[&7+]8[PH=]MU$:=&>Z7C1:G2?+ -MZ:\*S^_OX$B5K94<6J]<-( 6 L>K[/00[,56 ";4J"^J\3,X0A4"G9=CG"_ -M@ZE8W78@+L??\%3TDI*:5S*T00+YT=:=HJ*579FKEJ 7M\ -MRM&KGG:EI9(!JR('J\>V.=Y4K<]+E_:?7%7"D[>HDOD+S]C7!LL0\P&(JYRQ -M^E92J+)CH C8\C%_QBX(G$A3\;*!7EK PJ'D+H9^6;"(^D'AWO:B,/K@M+:> -MCUH509.0?ZMBSZ?$6%R:?H^7NAZKMZT4].;>)-KE -MQ8JGJ8W9B(V0Q:H JD5$QA_/3([$%%2M@9*L) -3)@9N0 -MFECQ,?7OT/W"DU71$I.:NUP+L]:7TPV!ZL'+BPOQJX7=FI:T1ZJ4@-Y7:1OG -M\# 663R"DYU0=;J=QX]S/9 (,G7 <7F[<2HVYG9OZKKVH%[P2Y97H'!"YPRC -MV%P001;^O>$&YIIZ9P4#)!=70V8^#C$&NB*R'HY36QV'LU=WWT]*< -MK8>NGJG8^>&GBQC=G)'#K]^NV%N8&;::E::"GI&.>L'JXS?MP-"^$(N5CE%2 -MJ-'#H+&^<(I;@A%_C>?4UMOMU\>?LE1Q=I.NUZ1.*Q/.K_A=N%I_CI6)J4.< -MB/$J9:#G ZS3\T0N4:5^\5E_%7N -M29. DTR0>\35Z_K%!<@/GDQ%S*_%7J"@%^%ITQ8F[N-0LKV@EH^(V)"3E$"M -M"JP+XP''QT/O#G^?2OZ-FI[H!AW9$A'WOE0/+D:QG5?36D/%70/)O8A>K9Q1 -M6:[C*]#PYCY1F%":4;Y5>Y=@FXMQ:H];A\B"4+11G%U!EX'%-O4R/O#82)HP -MG5.]^(6%Q<+P[/(L&U-:D$M^:I:7HI0E.F5MD\;+9J.>6$.>[,?LFJO-SBS/ -M ^'' =\GD%^>7=6ZQ+MZBZ& 4L?V -M/,;2YF".O9^5^C58_H4*[MR0&?J/MX>?^P5 Y.)#\@?%DXN$II*OJ/BV4-C# -MP=)>@J)%&Y+ZJJQ:4?*K\^8UIO&K6CB_%Y&^I:-,0_1TT.WU4J9H0UZ3WY:3 -M;<3IV.S [\.ZH+B8Z:R]DZ6.N(NGSHDD\>9LWYJ 3RBOKTQ:6(KZUJ(P9 J3 -ME'];@?"C@[BH#GL!'<#!X>N@*_9C1I<75\?HC%.RM;O#/YW4T^R@G!N0B3*= -M6%=QXT_#_(*!G1ZTDKM8GA4^)? *_!&@DK+[3^CRE93F6UF:J)<9KOA3GT#3_I&:]Y3NGU". -M1==>0)BL!:[9S?O,U]+0AY>42(*%C8Q-JK -MX2S%YO71$:=2#OI="ZG>BIS0I:>30/(G$&_F*-85D)WUM9J#26_"XM>2/[R: -MD1^?P_.C=9*SPTRPBHTE_5F788Z)UP_*R# 448R5D).:LGY"Y/OU+F[NT>N/ -MJ!T#N890DIA+$N,_Y!NBE ?FU+"U6>D[O"XB(I1=;%3EZT,XPNWL9Z[4L.J]\S7UQ+$.X=] -MG!>^E:4;J,0G@=*NP-&=M;2-5;>V_Z:BCNTSU]3Z&MR.IGFNS!,J-J-$P>0Q -M^_Z3&Y>M@HA)JX23+\36X2;Z]_"NEEB(BQZA2H::/^G]S,KG(=1LC$2_E+B4 -MD*W;K=DW]-;']O-MA?N?JD1+G':3@%;8PM##XOE8[]9OB)BCC%^:GHI!D(K! -M.^?%[\)RV8:>D(V1<@-0R0+:_-0&U)I35@''(\3F$"_;JHAP6)^1"8-B=_F- -M6J,2!;:@NS>AG)UFE@,-^_G\E^_)F Y'UN,:_586&[F.(3TV? -MES_%EC4@-! /.O2IA9V;C8LD#K?HR*S/\?+ "[N,C$Z25)UR>IC!P-CV\'78 -MBI@EZ, 6,+U/O8R)TRD -MGX2/-YWHNZ:=4\PLWXKBT8F7O$ /KY43:+23@-[%;^Y:6H"6]K[3ODMR7D&F -M&\&H"NZA38[#R)E648B9EIVN%ZB/C\'^Q_)SY_$ND*![CX-<6RS/!4*>UIZ% -ME:">GIB3E-9_QHOY?J^!WVZ -MGC""J!C8EE]%A>/%_[;;B5YL6)N'FY92@*CQN7?Z\D;7%Y =HOX B,;/K^T -MU (!\P/.MA7L5?KLN*Q5NLCYYIY +87"EZNPV[:);NAN@SY<#PBT[[=:!4!6AO(81VBG'#O$V>I&QD8Y16H/PX.%%U[;7 -M][:^!9JCG(J@7XK'')/F5=#0"521JENHL%[''O4N5M#P.H[@$I:#]&J;JFE9OQ#M8#].$23WYX5&^> -MO^BLD@O,LNS3[]9W3_Z?2YN>6?ZZJ!8I6:9YQ0ZFJ0[<$TR,L9^2D7):;"13 -M25#VE_ON\)6)H(D0BJF3 M2CPH0+DZMR18*)]W#FEO7MT4J!@964(JJ=^8^X -MH)IZ?C^1,KJS)["6;&NW/XO;:T*^0GF"?K&&3LI1:PN2UE]8R -MTIV-K5Z7MZTKMC'46MGZ$-7)0JO6\IM:F3BIQKBJ=/OV3\'BE/X^U-N<"%ZW -M2OA45R==D(#T"Z(Q%CN6 -MN99V0]FR=J_M\UP FB9:FKJ'O8M H/Z=]<+%480V+WJ-FI"0[,%I]K/T=>., -MDM_HEWQ9B3JZ#4T%_(XA!3 7LIJ!C+CAJ+@&J8WJD1)21:<(N]4BD):*GD*$ -M>X,!SY#?P1;2P].#4JMRG(Z+C+^YG]E(\NT>D"W;3"&2A(8)D__RQ0/(BG61 -MFU^7&9C@\_CR\'"KW[:3A(13L[JEMGK,@]K$FEF4N;I14?JDGGU$\/D^>]?+ -MJH^VNPQM?X8?)N=^126O@-#62'^+GYA6LT_9=!$^-G[UO7()G(*.7NJL5IK! -M#HPMKL/1[HX%O!R2+8JL$%L#U//V;:Q+O08K5II6BOZB1I 7VLY-]P'GKN#0 -M*9)1,K:.4MNV+ Z6Q2OT\&80V_VCLEZUB)ROB-W2X89SN'M0$:NS&S/M]^?T -M+Y63@YU?@5B*JEVKV/]'7%&\4KU66JH#JA>#I^O6L/330$\5L=.,P[6D2I^D -M\.5F?L*8]K&XOD:'EO/L$NOVUM;LSHZ0?KV$F+R3,L) @MP &G4%0X^:1:B/ -MG\T+ME92P>/Q-L8V08N'](N,^EJJE*9SBR"L0O? #T\*X$-2MYM\=B^R0GCW -MO5#S\=1P,.6LH]0;6Z"KJ4T7HP!,G8FH4JFZ -M@D"6%Y.;DHCR/J)OP./'I:.8FHJ.F_<-\,+U'<8"K8_&FY:' -M4HZ#.HUR5VXR!/@%KJ7YY?TZR&0L7S[N8Z -MW?# '/C']ND_^G4(Q13K?F_DE>'2E:LIYD8P>W5K,0E=-!; -ML;N0GIK+QJ,VA'8"AK>:JE,BEO'F0_OG!_&FL82PG)NVGX+-!_48G';_B5N@ -MNGNJ?YO!>]'O]@,PB]N@ UIOBI;S3!L;\77ZP+L&()?(27)66IH!8?;&EM/* -MAX:L1*NN7IF[C;\2W8#B7L\9OX1QG$-2@*Z1TJO2\C3V$MI)BH91=9XF&QIT -M$%.7S*SX$]S6JX\4POI"7@6^<8*XQWG#'+V@ -M"G%:H5I]'C+J:.J^5BL_U%/?@W\5MAZ(3DY+_AG*J ^O%M]7B"QV3NIV^EZF.H9Z* -MU:G4UJ3K8;NZFJA"B)?-@Y[72/*]4E03T)E*?55:WHJV4GF?@P%"S-=-P]H@ -MF8BN!3*IMXF[D+AT4<<6QR[>4"E_]H*QD(*ZGT<74MA0-/*%3EW#OP'@-9W% -M[<*JE(*%I?2[G[C.5]?OQ1B&N &%7%%:$W %JQ,BR'/:AEY;)!O,3D9!PC*!4@E*%TB=OEKX77%W"O9*RNXNL -MWH':C,[*F$.2NW8"B=^039U2XC\4$/&02I )J_R"F$X*KL3B-\1U\UJ I),P -M/ZY;E4W#%[7_W9>!J[.:C$^5OU,2=/_-3(XNH<5$#(ZIE,V&F4UJAE+7(E3G -M]?_+O9_;BHX&8HFC@!(-]>C\T0'9"AL1IH>-F9:.1UZ)QEN;!2HG\!+^Q9&] -MGE_279I7H6M:X$6(D;"0B*Z7 )KXMG_6 IJ@%)5:H7HZLG(=)4;:G/K4$OO. -M 4)#>E"7&+34^M+8\+BGQ +3PI*.$HY;\O,N.B_:G+B;BF*OM?J'X?(YEY?N -M"X,4G,FYNF%(N#:>H:14 DJ(R(>F6@&"GD"+.'*H\-'M%I9WR)F'AWZ#D$T7 -MMF+0&^+8[/3>%NO#"9"5D?::L&N"FZQ: M'Q^>#R$,-YD:&M4L7ZE_%&VS10 -MH8N>W/21M]-VQ9>UM>/\4DH%#8JK@X1.60=+!THOG/ZTDJ/8OZ);@<<>,.^: -MX]*1L*0;@ZN'GDBDA?#Q[C/3CUIXG7F[5:*SED/[L7?E]--7!86J;Z@%4L.@ -MB<%(WE^BJM1O1%B(0IV^V, =@N$T-O[VUX_MEBZ9%Y:M&!I,5=T"S,!"G$G1 -M\/ 2K$6+3X/MJEN@=[W!\GSB,O 'E)"@#Y!9UZCQQR_RA%Q3V98@OZ\8\>3D -M\) +CY*+KO90J).FIZ_'_<>P3*._GY7#K(*LMYO3,_]5L!KUBT+&$XCCGE"% -M1 SC[/;EYPBF8D*RNMV^BQY"PI4E__YU1Q#:;$Z.2+N#I;[BU]1X!T*TCKR' -MX(NZO6NCEE?-Z]3\VO7S3861F,O4C?N_K,2[I]WX$JS4H,5@31R%EZK2Z,H7 -MDY./TIZ3%COFXPBRD'U0EY"_ Q4 PE 6"D7>E5.]Q\&_U>; Q^CMH[[HIR3 -MJ9J?T<[*])1"E%B6N)X3;9"K43+ETMQ%MN<0,+?<2QAZ7Z" _^SP\@^!IX)? -M*I]E,"U64$ ,CI7)MK"8ZK)E -M5<*OCX\NO5"KMAN*4*N/^*/=R@% OS)X^U3GX".^CB6>J.%^O#J[._>=NJ5 -MG;.=VY"6'O+^X]RLMO1'\J**@M?J1?_ZE8_>&$2MM?=3G89UMT=LJ]*)EA)? -MAA*;@JSWFO<3T7WWQ<92M*F:^XJ&7)+ X^I#M<9#D_!JKQ/'?::@G^&6[700 -M%.*O%X67OQ^KO3@GJ5G=W(YG"N OMX6 O)>!AJR?G?,6'T77_]M)+)"3B[*3 -M-HNPT)LG2-)![ @#P_ !7,2PJ99)4Z+F!H#-Y.TFQ\#;7XNCCUI8D[J- Z;# -MO;83CQN0BIC9XZ42QN?#4%B^&[6EMDNP\(+E5_,0';!+O/J7_'^(4+OEZO$N -M[\4V;49&PZI*C%Z3'ZOK[1HV\XD.NDBKDI^FD(C-_^[ZQ_1.@I67K\LHKKJL -M<$L(JBP+Y/$::XR/E+U?G8MFMA$)$+7P+9XIII)&PY:7NZF7H+: P8I: ^SB -MR^,".Y(I4UR"0_JB8!6NR>/%Q>WV#_RED:Z.L+N7K0[ X+I=@$4"LKG](OXP -M]#3%A5QV<9&F77NHJY[["R3O";@2BZN,L9J;)EI#663U]]+ P"L6H)B6GPCW -MLXS:VL7EK@.+7ZA_DH"NEG\%]^K9U_;RRHUZ5;_/F$N[8EN!B4RMAX2GT9\ -MGD2)6BVZD*:+030QY;(ZYQL,K*-8RGN]FCROVX\\FIG-*_9H2=NPW$ -M??;[M/-#7XZ3BO7/0\NX5)N-'=/'UZ_KQ?:&AIZ:G)7'5O^@VGCI_L5O@?V-^^P1P]>^IVL0]8/GX"A-Y75 -MT& FOJ.07$S(;8MXA9<)+-3.(>#:1590C%5:0+MX]GK!LCGPU_)&TY^%BUFC -MIU^2(9Y]"8[+X=K=Y\#FC_.1=Y["NY'2>:!7V.)!\N_VQ[^CFHW>0JJ= OS. -M\GZ)DYVUH5[RI7KL]\74"KF3MENF=SI^N9*]9?GSR(29T;N7U(NX@IRHX39S -MY="+6I.[D8#V1OA;FV0#%C7%]^.O3FJ[6X>'D)#MB<;3/\601\F:^*RCE)ZO -M:9VI&P_\0ES#R8^4^D#FG8U/H82=0_0TW_;6(T=2U5-:I9&II[I%@L<."Z3L -M^LS/&,==OI,2VA"\5K2[GIFA]>P2VH>,49*%\%V[]M*#]='0DCZ1UXD:>5G" -M%1_&$ ^0(%0;6IVL7Y#0?_#90+C]B?!1C#U8BI664R/R-Q 7DU*;6G"H^^J$ -MNE\-P]/E+,7##IN3ETFHKY.# />>_16N%?5E<+KL%JV)8J"7@NG\P.3#PYF, -MG9YDKJZ DJWWD^3J-9?<_]JHQKD2O(>/7A8LI[?JB/OTJ@W[\=:[MZZ@NB93 -MJ[B 7I>BT.Z6>_3S4+944)2*JA=GZ4=1M!)(GOVPJM<(T.4V+!_;7:#?GU07 -MFLBQAM^I#0,P<:6CR()=>K^0E'OMY#74+L7@S89A][J13G^C/?#PV?+UVY*= -MK%=7FP:,6Y7PTY:^>C?0K72/E+E[OH:XCY+RE9W.UL\23Y95C)J_H*J@FHO1 -MP/<2]]!#.WR6DZ^=V/E#R)RB&E%6H:Z;1<8S;L+'PT1&GER2UT.;+!>*R^L)TII" -M]@2PP9:6K/H+P12TQ00[#RIB\G5]8=HG"=$16EPS^M<60%O.Z<$@]5C";@R%? -MP<.YH!YQO%"KJ(G"7)66E@5Z4X>=#A"+K:.0?]'7<,F$UE"[&Z%V2?&,70TQ -M\3?<\/:.D^V"]I.VI@L,&>/%L.V*N*:X75.-!XZ3G C#]S_UPL,75E6$KU^- -MQK!WRUD$),@+T32#\EY*@X9!27GR4J#>^31NY,B+>@U0@Y"3").IFM+W_^X* -M^ASXE1"2^IV?^Z:KNG*@1%WQP?CT%O3%1;.+D=*1]MOG U4*-)2SW;:1FYL5 -M(G,6]O9CO(.PO9:7VX.FG_=!SR=AF+12O9;QOC_B6I[!Z?'T;]-8CZ80@Y)' -MLEJ2I=#V-)HZSXB7EKB"4W^.F8_8U!DUY!3S:8"\A[R:.)*6A@#!_.W.+]CT -MKXV%J*Z:E1.X&I?7(\3 U9)EAUR8@H!TBPA^D"!S -W('/C5 4,UA[Z-L+*V -M"7[^B+)=\O1YTGXPRPJBOXS\6)./0/D/4GA0GXZ2<9(; >)1)!;$$TR;T F2 -ME9.?J/*7F:GJQ%^AFO%UB5R;;'V_HSXNG:;%"DN]P)N6CYR7DHS"T^W"NO6+ -MDI&=JX]65I5J&M;'+]/ $XZ6F$R/GXV8H+6;P1S.[L[7T(G7JDR#F(V(S9J= -MPQ/%\O2Z][B.7;^L=8-X"&VVE_#*! K5S<[%2:,>_9%:UKE:GZ!TDL'JE>XV -MQ>L,G!F>Q)6ZY=J45@!1IA>+@7IR4\,K[P0% -MH))=CKU6FJ"06W%WQ? VPL#M<"Q#G,N+I$N>S?O9]/O/A].BF9P)AEJA0%D4 -M\W?F9>>\E?F 2[N4BK&5F0KY[.Z!'[UKNJZ64N-D_W-+WY!5GM9V9 -M6H_M&K:XE(NAWOA3S=4OR=6.LA6?TY"JJE+VCZKRO\4@<#8"K%B249H=KE;S -MU\?@68+:ET22R/;%(=4V%M8KKHH>7(;9?+Z05ZK#WL<]J)S+E-!]5[\AE?,, -MZBWV_L\4D)20&[:#1YX2UA'PET8]CZN5H+] DIY;DT3-_CCNL/I#%Z!<;:Z& -MZ4>1DJL2U(;7"?C2 -M"_C\J]C82-QTF_Y2XIX)S!J1!>A%P/8L6_QUHKE6L)H9 -M\=/6FI_&YS>=FX6PG9[#N86]=^G%$ZA1GEV5^KN_M!I*P<+C(]?.U%N-K)O# -M@UJ&]^3"]Z,0I@JO%^2;J)L>3:>OF?(W8_KWP1^VAFKD6NKMD9N >0QY/YV^9.E**VDPF2>?07K,%45@G[D+.>JQK^V^ %W!!17HO87\/")-+OP@%$E@'8 -MD+NL<^*7@TSO!=;PF9.0_J*\6H@:6)'!T_)WCN9ID*Q#6^UXEJ:%R>ID]D3" -MB5N!LH.;7H*RO%GF[,6U[>=-I[Y47I>]IWF@@ W1Q6 R$B+N>/)MFEK;1\>;$+_;S.)YY -M7RB2B+Z*I)N;14W%]MP$P<\6FZN;58O[Z(.+D9"Y*3YU(#?"[H664)&>\*J2 -MQ]3%, Q %IDE]Q.2R. L^O??D*_[PIOPD7J;H->_0(_#RY"$$ZV6D1RS)H7+ -MP?/FT)SO4&N5H'V#KQAVDVK'UAG5^L/ID#F-7+]%]I*J!_+L[_;6\Y:VO.R9 -MG;W+('*"P43=V-W W$F?JI86AY6XQEWZP33U+BRVT,KSFZ>3IHF"4L&R%_'* -M @^JW0P+&(>ZK55V]I*^<0U^Z&?F! MIZ%8.QC\A=Q%G".;IHJ( -M6/+^=*XGQ@:><%9\D%U>K6S0]PM[A3.UEEN.H)&7LTB>6\?RU:_U]5"CE&." -MJ(.?D)*?[<'5+OQSP7+DDQZ-CA8>H"T_MS>S]?&)5I0*OKR%JKB:/2<:_Z_F -MVV.O%IIMK7^MJSB6NL4;[/ PUL,=3=E7"E6]=I&@L('U5L##3,7MXM!;OYR* -MO$20F**-MGK1P?S%L/3%7["T5(V1 9C@QH[6G( 4NU^16%O%-!; /O+6E)Q -M'16Q&[VD3D, J>+@&+!*#YYQY):C%I#V7PL!?GHS\J00H>M2HB06QI219*:P7'X -M]9:6=ZZ9AY2:M:I[ ^DC":I8&]BP)U.+P6NTQ[;OU5RJ&3OC:2II>I)S^3C'.M>!8Q#6HD:AO>HQSOFOL(P6J]& -M!9-8NJ>;G[F6LJ#$T,,$RLP#'>JRA5%ZG(>)ENQ'@Z?!\;WZPAJJE"&OHXN\ -M0R7+0L.LF9.$E]N8F<5PQS+Z[<5=H_1-4A26^9&46,U6VV/Z.@J[A?% ?R"6 -MW1LR,_8VP]F3G[I[B8N?GJ=,0/;UT.#32/>SVY['7?>C $RV7O>+EE95DR* -MIXB^B^@7BM$ #LPBV=Q4L+I/UYB-NHB06PF2.?0F-N*JA(5SNXR-=\9QHDL0 -M@BG'S" 3H;2BUIU36\Q/&A*L$E_!*!W0]_X Q(B:K)8+?[L"CQ,<++">JZ>2 -M@YG+\C_B/.Q%F!:BC5Z(D[F67Y]-#U,3L9.0JWN8J?-@%XB-]M7P)A/R#9N& -MFQF9K%#?O-':;R(WYT]&<-*:DQY=WQ12ZO30%_?JEH^>7+_<3HNX59T#($ . -MW*?DOIKX'H^^U0;,6MOG$O%WY!K"N9;=5;>7BWN!J96RH,_XH^:H^\#\K[V] -M7ZG/BJFV; 73!7+%%\;LR,?4@(>GD7N#PJ/3"8>\BZ]&EY8"U?#M]G8O]X:@ -M]@6:4I.=N' =R:V768IQBY\2"+I(P)K_3=/Y\A8"PX\$;;>^1X2:@8S),\4T -MHV5%DV[C)":B87^SZ;;W8F2O(2^AZ4' -MAO +TNG%_A OVHV6/)#VD&"6H;.UB=FN"&'IS=L%]*V$E=B\IKBNP8&0>,,9 -MU/RZ8 5Z@*.%C@E"B,?[QP&:7+9B,AJ-%V?;LG^#/ PV2G7R-1[3( -M[-%IE77<$,^"FCQ)C9Y+:>R/MP5,ZJCA3_9/3;^,!+NM0I!5D/%K]?JV?]F# -MOY&8K)_+"8F,1EK-K_JOP$CDZO)ME[U>B:>-%D.YAXC'%$;&T#>9D9.*GJ77 -M@HK9%0/CW:(R>W)#EIG)$L;VYJ[1NER?NY;=5JK %9K!"U"24%147+8+F@.5 -MC[GQ=M7G^J4 '0_#W5N8N'*73-C^-Y;Z$P>7K!U!NYV0P4RJX/3R<];3[K2> -M#9N.'4=F<+K8[OJ,]M=<9/JJ5%3-U9J,DEL9\?;%\N^2NYA5BTH635.29%H! -MT(P8!Q[%PJM/$R[0PEYYEAV2!UF?YC2#P/YVFA +$FUZ -MN:J*6]>0EXK'(&SP\G.8G;B9<;J,ME6N&?KY,E R#J*5FFQ%C9N+XZ>K94AN -MS@[8]8>Z3^_CDI2+:9Z:X//6YI8_PP-/ELB,](:IUI/V^,C^:$>!K\7N\$== -MW)&NMH,7RB95TTCSV-:@Q=NV4Y:;GO=(5X'Y3Q&Z&))PEYB>N(X -M5%:>];?06I!$O\/KV-F$%E^%I'*(CHQ$6RO"P3ID\]!(D[A;F;V>ODL-U?'E -M]+_ONW:KDII&NK.9@%DR=Q3&&B*[7Y^\"4?/T;BZVLKZS_Q#"T&<^IJ*C):7 -M4H&V6*#JQI#N\@K-_*^52I)8W@@2?;K)U$FGS,76IG8^=NT7_;PG(V13D+8]&\VQG[K5!B0GO6PN(JJ6AL1 -M+O,!NG8@G1I;5ET@FH'G%C<]YL"P!U:2J?Q+DG>UK!/E$V<3V_ $)#E"$[MQ.?X0]:T2::X@1*L!H+;WBS_MWY//' BVK8,;NOO:59S)).RV\!KND$*"J.NNGM% :9_W-NWOXS]W -MFH /&XRHC:776LX [^JJT[Z&A+WC'I4'*'IRP/+^Y&&!2?E9*>D_G/^PE?\>**@)"_M8B"?WN5J*3$/27"+["[ -MEK:]@8=.L).<22(\Q_X#AUN6?IH0A;*3#,KJ%K?VIL=K5=KL7X8-1R.G@//H -MSZ(&XN/OCZ^NBZV4H( 6TYT%5QL#V)0^%0Z)7E\#.M7_P+N. -MFE0>KYZG2HVRC],"CP,06 /".[2GEAUH-@/LZ!$Z-G'&6I;YJ4 /=::?/-GR -M8S?@\TM&H!^[AU.4@X^A.\SN"M/3O5OP;9V& -MGHMZEK=)0<;Z-_#"C7N>^JKPYYFB8/:+R,( Y*K]RL"YNJB4@WF>1X*VL9"_ -M$V@Y9N7@<*^0EYN/^IFK <\E2'R8HY%6DJF"\=[99.[V UZ 7YU?D8#2LAN] -MPLO%XI;XI![UT/R#D$X3\NO],]0EM;B?DEDKZ)>?E0Q1GCSZU\N2E+F2D&:' -MA9E Y-9M?O;Z0VZ6D>@/G>E(QG:?Q\S Q@?"D9^0$:J&GYR#J9J# _OO[<#R -M&KF'JUM:>KM:GD"05^/"# ?ITL<'' ]WG)-:!ZV?WGF?G0/:Q=96%-M07!I5 -M1AVV*.*?U/;5@Q"?G&!7N8E^MY>4V-8]U_8FNUI&GP*/*Y21;DT2%2WWY<]# -M6ZJZA[_=#6@V@>3WI8 78^)T_*L%9K![I=4HY3 $R;=80!6UWZ9"YDIB0IC(,(ZVUF<_+ -MS P>W\.]A96\3XR.A:F $*[@EG;'K[I:[9B-O<^G 6+IBV(OV@V5*+=(V.; \'SQ@:UWD0)[>(R#V4 U/#_2PZ^@89^:457&"\XB -MTL7VQ]CI7X.96H#>)DKI\3;UE^X^T(FCA(A&FZ^-YDZ7Q50DX]_U$8L4+;V? -M5H'C)/93$I8V]^7Z4.<8B9DIE8U:GGJ.B]%]&?\_KD%\^:5(IQVA>#@:RE -M^.D7&L15B+>;4AB<'4.^6>/0%/*RHA_13<,;V ]6H=:8BS?S)E04HX23UER$"OP;.+?VY1<;U+Z#TH=:01I#=!Y[0-03[BZ0 -MV8:4[)*NJU^'BTI9$YW$,%M"HX2!.X?R?=.*H30NYD;ZP[JF4$P6_82+(K8? -MQWQ S_8.X<:5EE6/$FW8AH2[\3X\QC)[\)"^/I,7I&NIFK)ZF2W]Q/;8_ K! -MUI-3AP&V]$J^)B060PSC_6;DUD5&G$N'AH=)NM++H\/>D%Z,HY$8_\+;W18V -M1_?<$]F]1XB3VN& ER4<\M+>]EI$O[#WN,9/BUB2\\;_PQ2'D'236N\&I9*- -MQ2GU->7%2J2DGI^2J)H?/LSQ[/8T):B+4L6^;[A-NW.[^]'4_-@FPM!>M?R\ -M3XV,AX(.DL3S[;I%OEB#5ER N)>HCE>0=KTAR.F/J,)8 - Y>HRPK(8ZJJ*Q -MC$B%/C,T\!:E?).R57)2JAW YL+CCZ99KI80@[CQP<;NXM/%5?"P7PZA')*@ -M5'W;RQ""M=#!E]6EF]BLI%V8D_40_<]A[59B6W?/1J>2BA%Q]KOZB.LGIGVV -MFZQRGTG0Z^TZEG!Q;J2^1KZ_E(JXI%/JB/WXPY'2EX(%G8F3G5-LAI^2L_;^ -M5^_#IQ>9VTP&4JN3I9 !U\VH%,7"#X\QNUX50*F:HIQ9K!W7 3O\EA?UIIQP -M4:T 2:H]PPM%X;B4]@:F6X/_"7 9[/J0(1S4&JRGHIQZH-^=)^*F\!6&D9:? -MD99.P%8#2/3TTO?8X:UP1E.Q7DD"KK)6*V,[-SG;Q'"T"A8I.DKV"I/+8VSNU%^^2$U%XD0/\7DN7 -MDF*EVL+]RJ?H$\#GR*J*'Z62>@]^0F!: P50+,+7L!OWU/*QP'.[D\EJRS20 -M!!XKG;&[K8#R53+F.D+00+.;7*48N62_^L"*XN):I9:1-X>)F6V44Z/9[6[F -MVS&/4$R"L=L^1%2LFIL*V\0YB@DZVEDMOFM.WV=D*3J*\5@J22F8*1CGCC+>KDZ=U' -M:L@15;BSUHQOJ*&@DHK9XF;6]E/E#;1+J9;4FEW"_Z/2=! !K9Y4FHM:\_?0 -M+-;1O9/R+I>BFXCKCA<(SL#9A*3&"492V;^Y@)N$X[,^+?#8B/K[OQ^*C982 -ME-CC_[?R0[Q[HNC!=,/7X/?C;YI01$,2A9*IEJO-#'K8W"<4G)"M -MC:(_AH[WBQ\7FQ\(!BU0(*^ -ME/"?QW_/&'RF2YR.TX*]899:V5/$D.:ORYU/DXB/AQ>22Y7,]#<7[_&G$JP" -MJ*BNI*%M\\3&K[K^4ZV0$8RBF#BI=/.+V?W,U\?NU$.3JF2+KXD/K Z3TSHE -MNKH?SY"8GK&O_[J#BZJ. ('X^<,'^_\/W*EW^Y*)IDM2N*1>D]"0U/[F-I,% -MB8NTC9*KJP.O4]P:H;.'7_*"G:5KQ.W&^^4<7%*$E9.>NJ >J,+O]YRTB=ZM -M$(GY@S.:G2B08]OL4KSMFJV;*HM.-8642/*1O"X#$5!-FW^]#MVS:L7V]/?P -M9\6#2<4# -MG:!;FZ2)?Y?1$!5ME]/:AE&@10.7>H"H=%KS+LM06'7:488T]IZ-EZB1%#7F -M-B.P@U>@O;*"E91^AL>^Q930VY".E9:+DH>%V8@7L]5&]BXA'UN8:.^2H5M# -MDC[J[-@.)";(CYZ4E-:?E(NVG:V ^G7G[E(2NMA=GP./J7NCDG*=Q,H.]2HJ -MF_72:FWLI8#"7_XP#;&VMY:^I64<8.) 5\"L*^4GE^&71N3\RHE -M?(X#T0/'% J(M%O_B?Q];8Y)S3_Y5/9:XF?6:*BJAU;> -MBI1:P^7Z^DE>ZT\Q^!O#+$K]6 -M7,:?'"LFJ9?:P-03QO9ORPU6FU^:MY_V2,Q4B\3^Y,2MRP8#$[J?E7]<58\3 -MN[CSJ.34;91VM<+=H%&TEB5;@Z+"V[9\$%.'=;R[@Z#"+1:0]^]46%H4MAV< -M.I&@20FL\1*0H;*56Y.\TVQ:FQCB.,3 UQ"K=&2_]D.^SD=J!^CNK?I"HU[L -M2*J.CD#70-/JT)3_[_"[5X^\1IAKJZ&;@R??UD[""\)K5=>43YR!9J.FC0SR -MX1_PU,>'5IN(ED^^D-YPOY+2U<@75@K%]1RXKE[S7@6[BY@F<-MMGF_B6L3) -M?HF>7(:=J@/M"R\V1Y/^1KYPK%;2\.7WP-9SC:(2GZ 56XJMII['UV;!Q89R -MD:.*^OZ0A9/:L;;P].#:A[>DMU*9N ^+'@L^<._MPS]48)U867)7DKW!Z]7O -MM9?*KX^-C8F\JVJBI'LE*%>"WZ, 3(^$C9M7GVJP3Y_!'G-@$I#KGIY?HYZU -MJ=F3[ ^:\OS[[LI*[LOPK9X%"/B;CQCR+$2-4\/A;L VY9GYWD5V4IB-$0_" -MXYGVMMVEH9B?X6HF_N;V6U6P&9Z:%1JZX'7_36D!TGJ!VD:F65"3.X[=Q30W -M^_#%&%*V>8]7AP>WTH3-*,$F/\_(I&!:JKJ2,@.\$93Y;_KT#[G4NF0,\KT3 -M.;^:I\#4H@H/$)Z.3%6*GLTZP\Y*YW[A\,+>&UN+G[,HC+J6"L&=M_$'K@M& -M#02KRFJ;G=NN7KM;H8&7DP3^.:XV/\#1M!A%1[6*^<'6PK)=@Z:OEAW\ Q?: -M.38;[F=1H%[[LY$9VH"GEP,.SQ*L5+0ISYU>_K1: L$^&3_@%="-1H/[?HO> -ME9>ET;'T[O6BJ)W"=IF;FJ2)2-+T[L+$,\;NAM6-B9>4BKHUEQG:@ P=HM 4 -MIEKHZ5*+8[".32BS]/3P-"N CX7!7@:[N_Y$M%T3%.#JRB*@<1")%EN#FI^' -MFA>Z4']!ZFSV(/(#?)G6D;97DYM"W?6'UN3A)W* -MZN7^!>+ OX8#OSIK1=&ZIBMUMQ7JTQ)QE?ZP,#L_O;N -M)40<2D2Z49H"TL2EPYS0FIZ.@*J2P3[\T/I%]Y"@D8VV5YJ[>E:RTPU0T800 -M5IM:45I=;*)7YQ03__(3XIVWDIJKNWQSL3K9]&% >_.'5B69FKV8E+"_S2+Y -M;.(N R2VF:>>G$5*LY6:\P0,:M?#'(N5CYQNVXF[A)^JZ233U[WN(VK?C5M# -MCKBWB+&.4H$/R_=Z! %0M,L]O:*ZEIC27F)^6\'CYL9EU^>8S[L%45EZ=7@B>F*6^B\E_(LB&T9X<^E2"6JQ.LL7J -MK,8?]M*3H&P#BXU>&XJ\[<'5(##S4)83@MN3D@QWA*%!E/_%^L"CLMP9C)(, -MOVQZ6L+ _'XI.4FEZ5RH9=3N3WC>$Z)Q(E]:BC4["@F[9-FX)XCH,'!,A= -M7LOJ%>"KKHE*F9I+3J&CT)FJ_N5ZTCO"KI6+^UPW2'K1+<[;G))V>Z1 EY?! -MD]-T/_ KG)V4K[912GN@4$F3AZ#;G/92/*8=*'F@59WCE&WR.LK=D*)MDY:3 -MDEI[C #1L3?EVIND@JJYA]9,D>IE:.S2>L#3UI:5C"*8GX/@D(O-W^BH0 /= -MF8"\'FU8B:V1]YT#'O__K]H%2).9L=J06+Y#NKH/0?[!X=7\$\?3ZI^5RQHF -M[?:+DYI!P\/G/C[E\8QT6AT$>7Q:U0SWV)!1B?[RB?NK\SIF]9?\C[V<@9&D -MPH""RK[9VN+9R8>06YLD$9S>N(YQ03+36D+0\+ORIIJ"ZI*/EVP9ZC-EX-*" -M\K@8_&^4A%D, SOM[I1V KF?O$!6AH]-J%>7)\HJS>I/0NM?K8ZI -M)2/QM#6UAPM/AK;VI)&^/J:/B<#?[$<-V^G3RBNFFG=#]'+'O% -M?IN9%IX@E%KRULOCU"C/HM([CO]U>J!#4E;Q@)C%^>;$%,73^HF4\:)TJA;0 -MR_,"OMR41II(T'\!/C\TUA##E%"!WO97FIUYEOL0RQ?0E)B;E5^Q&IBG4*<9 ?2 -MK(# IHB:B!A7P,]3HY.&C9F-CY.XAI$%U!D^;A+(B).IE5Y2JI)0.)JY QN: -M8?Q\V\ZT2YZ? 9[UZTH2H)*7*)[1K_;V&XX0VZ\0D9.7\>_0D)!#H8>%DW)[ -MT?!Y/N9MPKR!BZ]&21*70:*:S5VKY;Q1DM%?G5S;:X29P/;#.C7U] M>N:EZ -MF)I?H^[)\?3B>IO-):N96XJX:F%J>G<&M1EY_@3OGQF(VX)K_G2%:=H4\4,@L!JU'I($40+'5%O?S -MG79FKTO+DG>5EAKT%_> 1&6GEA O8>[N.RFW:LFY)2OKFPPD7]U. 4]F9"4)Q3DXFE\9:8 -M\P_C1!264YR3MUA#S3/%+K RHQ!&@YG22)./;':I"WL+YG2#G_R6D=R?D?>2 -MP??L]9>GXFVFH9L>6P>V18SSY].7]\N[D.:95^J+@I%&#?[U/OOFVXF;G$&? -M$E6_H_+[(0HD_\K/ [LF^81&AZU&H$^7T,3UE>;ZY5*($9E\H(*ZM+&F^_?M -MSL\(5L/:R:]&>*>.$@**EFRVER+6;_#TQ Z?W%:?@H4:6L#YPL*-@*"'IE%; -MJ/?&^3HT,D#^D8I96J-^F6+ -MFZJJCJ".2.KS[C?&C86(&K.9NE(!*-+-W _B -MHLF_%GC@O_VNAI(7O1#@V7NZ],N'2(^ E@:]KIZF58-)3='#U<34U0GG\K>^ -MDZ7+FEIXC+;E>O7^9CKRG*/RGW"W<\+9RW,0A(:2A9+TFZK9\E5O]_90U9!6 -MOW"#CYJ@^X$IZ='(BI22U/HU'*NYEGUG\\;\/J+0:YJX,IN2AY7SF-K2<);7 -MRZVFP;^*0W>R7M0MU\4G[_ CBQI03BQH-*S@">OH.N%ZOS -MI9< P\3[[N;W1K9[5T(0AKQ2>Z1:\M? =5Z:\E6#TL;%;N;/-D.VQ$M:;Y.VLIP(]\4P^J-=M+ 9K$=7T)Z> -M6RIL]]0P&P]PF8CM6X;KD%6#&6K8!J80ME2GO;Y5$D6=H#6"\?XXU^[_]IB. -MOQ"3CXE*F^)>?U'?R\\4Y>90(N! -MJH<# -S1EO&5\+V?LMF0;._2%$^\EH0=E:27WV" 6L',QM)>B%>=^K"3O[.% -M^L$4GQ(FA;R=%!8;DB\/FH,-P?G%\D/O4Z"AF9R)59YRC!#JX<7'[]574E1* -MI(J'B+GT?MM<' W*]MP/D#ZAHTRORY!?@\,Z$.06VO.KEE&0F+N&F]Y@1E<# -MJM'C7-]")IQ3BYT0J R^FO;AI9OR\?:BGN7OFH)2732'>AMRJ^- >DF:!?:' -M6(KR]K[OUM?U=YA?D*)2WIMD!@O-'L[PNA9#BU>2\8N0)E?'UL7EUA+_3605XM/IKB^2)X6D(G3/OC&^_;5SYY>BK^=GLOX7E,L_-A( -MS^*6GU9?E8U604+H-D+E?NS\]^?%O[7$AUN/D4^+H'NJF0[(H0'!S4#&B_[? -M$((,NYHR<9_1 L#U-?X_UUV DD'G' -M]O"9EFA7*%N83;6.VO+E_O7"P6O6JHH)F(Z->(X8S=_@U\K3"ZU]C!^6QEWK -MAI!0S69EGFWPHHM2G)=7I*U\H:S6")&CZ!\%UMPAN^\@B+JTU=P+&LECZO<)>+DL$3[>8:^]DUEG.1C**"FT.UJ0TB -MD1"*H\F38VE -MTEORSQ'P6E9031"7LY$'._$@=93'6EP;KYJ=T+F0)ZD#Q.;<,%V+O873LJB@ -MFY-SJ]3?UL+"1X^AJ*J[E%)*B,GJ9?7PXL=:,'VXAQI$LY_)-\=PQ?!SETVX -M#+[&#H>-EKL3V@H"2M/\GU"6N+L7C4-Y\ZKQ8MF64$6BPJB$GJF66IB+N:6H -MQ5[84Z#+7L+8ZL^\BON6./^:+%_941(\Q-HOPQC3LX2?D5N)(PL'" 1P"AR' -MN+R]96H\QC VTIR3FZT025J];).ZQU=:T9P05DF.%?*_N8^K IYX__Y/<$ZF -MN8U64,Y;GS_%P^7V+ME#I9&/VHL/E9CO@V+VNYZB]TOVD(^_6F] -MG56HIJN6I"0647%D__02[]-<0!2M4+-*.P>"]4NN>Y11AIGXF<6I3?F,%'0-R$@Y95D$>I@I.:7P4J-/8GHYS I")2JX*N=!.?R^ M -M._OBB_!&JJ@-&!1#G-JJU.?^-<4+CM6F0PQO:+&WJ<'-B@/)OEKYLA7NM -M"Z"%W<#RL3;TY$#KQY&3EYY(@K/$EGKE)E&&_ ?.]U62F(T%K)>/N%K$#Y<) -MY-C:Q<7"A$2CA9.72JE5PRC(C9R*K9K;EBN,W^/2\#X'A%"?E[255X,UEJB@ -MIRMTG_!3AHV5%XMFCY?5M-%R,_?QD(YYL)!3+J !;_+2\3>0RXKWH-.KOZJ0 -MT0WG$9V:ME %GW90E&SRO4*RWAWD_M1>IO&SHPZ>U8.HBYZ GIUQ(''@-A;8 -MC[J8L)R:2():>AZ](O_:%(?"I-#Z.9W^E7.ZKIK2PZ#;46OL]IKEX712BI#W -M@)R*VNL/\%A#ODMTD5X2X=[Q9OIN$/24<962BI&+AGY(\>'YDD*4PH^/ -MNKY.J%VOH_J Q=S4_D8AP82$F9YCBFM2EKY8T_#SDO8G]]FOOJ6ZFMLJ2(&U -MM\,&0<'6=]PC4E[2.YJWC(=2DKI4FJ/7[?:4TM,QMJ* -MHG&L7_'6,S8W[\&7M!Z']@"6MV!P>LT7(1FO@[.6I+R+BL97FH?T[>?_PQ.Z -MCX&/6B:ZI'+!P^KD]F7;XYY%V*AK6%I5@=%^^>)T)8&#\$S5E*V/.L.4^5C( -M5,+=R+!BQKV E?WM1Z 25TSJ$48UG\:;A*M[OZ:36 J1UAK'PD1WK:KJXO&3 -M5YZW6?Y/7O1J]XG1,:/3P#9PK )T_YDH'$QO7A_HFV_:8=MM#"#9"H\&:\FL\0!Y20FP)-KD!3'@' -M9QS&TPJ6.YUZOIAT4JS9T>7&.L"BOT>N0$D5ZT$Y@(,IS?W^R@/&0Q8&K$F> -M36U@6A" P96FL/KO@UY]5U9'DUF ?9)+:)1X7_%VDO2#5@=BZ^%P)B@M!9W -M\?/Y.F?0PHA0E%F^68(!\<[)6;V#GHZVI5^-I.H8_\9URI!0>G']G)Q^I-93 -M)]\%@*V)@\Z]]*^"@ 690?(M\"? UJN6DYV(3PVRDZ?QP=4N5J.(E[)]JBV3 -ME@-6"<0Y),?WVT]5G>VS [L[S]E;PE9:-$DRGHHY7\<)D[C8Z -M\4Z^1)\L4XB(GB:&T]KOX$\J*@# Q@V;AP"Z\$*?BLF&FL?S_>XR;L%_L%N% -M0%>6F-K>PO"YB9(KCZ-;JZ#B=/ P%H%R: -ME[:Z7\TBY?0R\,6#]I.;JB:65]M4HO.=TC_+K87TGY:3F >>ZL7 W-9R/\"& -MGDP\#-:!HV9P4MC]^DP Y32"G)!%B:^[2V!0>,GVP3WT_\J3._U>FY!#=HN@ -M6KMQ" 76P, 1SM*Y/JLA4E93>::0MI,1,=_&1E;"SLF4CHXA&GLD_P*!B8)0 -M?I6GN@/3_N^?@IJ$T2OW-/3F!UZ,FI1+'[\O.9H9TP %Q\I#XYR@G*6I -M6HT=.*:=PV+C-C 6\(J/<"H#WXD>XE4B#\[M"H8&E -MNJG ]1YN/ML:LY.4I%5: N#6V3!7D#0,E]&"@Z#RDQ8R]AM4"+25C@BZ66)T -M^DBVBS!0"<&6/3/EKQF'E*))LYNJ7Z>)PO)E[G?3"W+&E_I" -MKE6*CZS">+YV>_%ICII 3K96BVP"D]&L!(_& T 76K!$'\;ANJRZ\\U^,]6] -MQ9M:F([&_'"+EE1H7YO-2LG3^,/(@)"&K*Z@FEN_&Y_&7%W%]$7DQO;8O=!6 -MKOJ0G*K"[*"(K)P6.4^1*Z\BDH.4 -MDYHJ\L@)RP%&U-LXJ(?%E5P%DQ;T>DZ[YQ+&Q;O&PU@1AA^6E9A*\03:T)!0 -MHDL'E)*:S?O5_X:P@8/H+-W*[8>* -MO8F\F7JWD&NKL997O\#A]6S0^J,DE6L=XW'Q?0/\9._DE&QB1G6-] T -MQ@%=E*.QQ?F^$Y/^2I;>9_3"=VTE$\<;NQ=Q!#L&ZJH=?VEN/ -MTOY$\.X%:Q>3@K:XVZ7:@)F1E,?&]ZZ>\(V439X,DK)?^.MV4^// 0-L]-G_M2@IJ-"%J CKZ [MC#QLT/QQ_DY"MX"D -M)%%QP/3L+L CG;VBD9"PFITEP\K0,8F2K773NAMB\BT:,- ++%.TF[#W0%ML -M5 . YU/3GKP*VW2%JH*MMMTEN^UO]D\02H6KGKZ3A_>9O(73]O_ZY1-?I:E_ -MDXQ42TW9YO7^-Y>K2;2>+4FTE*K1^_:= -MTO6:ZIX$@IHZAY?RP,R?T0+,SY/O*@L(3XBU&W:_AUP&)J)RTV'0U^; )?22 -M%EU&4)99P-WS\:B$H[7;@WGS)]/1Y_07VZV*6;U45UY?*8Z:]PE%2:X*KR7OM-O0JU9U%LAN6@MR@DJP!^_'^4.-/?J&="D*=\HBJ1?''\#9Z -M\HZRFJ^'=_(ZPH*8<)5>AX\H -ME*2/@NTHZ>,C@P4'$DB7E0&[M@-#B^VGD0C#[J#@]8%0$(&[EZ"9@P%/HU&( -M5D&K@)*Z?0OO=EPJ'R].\D*"=$A$6FZ&.GLCS[,;V -M=M*O1:2+GIM25K%,6? 55/K.J8>ADQ^3!A/^H,R4)^_ZQ=..E9R5A4^^BT:@ -MFPK@U)A=;QX95L[_8EG9:>A8>)BYL(ZP44#Z:1])"*D8]A]/W5 -MFL2GKX">6W>BB(GH!9G2[L<6#YN1E+?$CDF&VOTGX/3&^EK=IWVX'_JJCXZ@ -MB?5\*VR@+NFF+F-K8+:M82(7[> M:Y*A3GUQ-_7VWVFEIZ B,&? -M;%Z_07SOUH_PH]'V$WR=$9 #K/OM9?K/XX>:D$J#JJRR!TIST<77PHOCHJ8O -MNE&5I+=, 3YYY\0Z$4*W_8VYA;MKH)03&,^,3<_B_$S&6HIOGE^-8;H+"?+M -ME_HV15">F5:#H%O\^7UZ.Z -MO#9$E%22B/+_VK2H&%H&DI6*P^23Y=6V18*5DE;VAG264O*'KT%^+1N':Q;I? -MNN:/U*BX7Q]Y6SQP3AZVCUO^'&Y20\)?UZFWEPL#Q^8@+N5(R_BB9@U/8 -M>9Q4?867FG[(WK6Z9CK'C%P!K;:@DL,YLE?9YZKZK:"+K-^=F:ZLFJ[1.9,N -M\,*XGQ8PDY.#&(ZPC-/ T1O4 -V:P?U**T9.FX ,TKFW_.93[Z:,.$*2/)D@ -M6J[##:Q4YMOQ@Z2]@$^3SU*( "TG/B7^IO)#BZZ0HIN.BYO4N\":U,[;XLK& -MUL/<0-^="H)>BY::2+>ZV7+P]:_P)8_)@)U4B;^Z\9><@UA_ -MB6RA:_<67Z.-GZ*_>(F=U8*4), O_/?P%6=.G,V7C V2J)7_4L#$R:E#\9^T -M?DS%CHBHJZ7XQ;05QKWN\*&J^QO6$Y*!EZF7K:-OPB]/G_SJU$=^SK> -MT[.2FM'[Y.V4^BN$$%&],J*J6Q5.TO0=EA.IAE*RG>TVE3__K=/P78G/O8D: -M]S!RFU%58S %G/*%59%8$\PPGN<^\7YEV_#+FL&]>^^<=B.EZ?XU=>X%CW"L -MET.G2"!?G_#DU1+0]MM-< YL2Q*-0)&0>T5O_\U/%<.&]]^,5W^!/6:.70$6 -MQ^_FTE#M?9DFD9"0JI>YE]WRSCB9C0_PLTO?P)SKHP@@ML_^SWMN^)6!!1GY"AJI'CO9U'(T#PK=S3 -MF4;7@KUAH(CJZL<0$,7!C;:YJIJO7;!Q1\7$-;_DQHJ:*/NJ.QS5H)G2]GFE -MY!#BF51_G#L83+TAM[;GR$C5U_=XCI!)GDD.BXULEXM(U/-W[Y;;4HA?BUI/ -MB9PRK+(-40V+Q#*O!)&\UB^?V*^"ADM.L(+2H4OQ -MT(P"HYU7@M.;\L*C.N_NVORP5ID$45F8P25*.WD(Z:4'A%@PSZ->_7UZ?XL_Y-M'B!DN4#PM94=DH,M_>87XGF -M+,?NU@5.?9:<\'U6J,!>BUG#QMQ?H90\E;$(@VP 5]*2967E]=&=ID7RF -M5$MH0,#$]'/'DI*X]H.#';)1O:"V\5 UDNZ]&Y>\KY>/JZP:&,*T?%G>/G)K!LX+(_ YUSPH'X\N(KMO!6)9M -MGO)*3E,BDC[&)&;/4=A6A10)@ZODV=CX_9(B'YN5JHKRPC5M[_Y0N(NCA5H) -M\C&CIJW7QO+"FI19K(^ASEVTAD+8H9;UT-'&F\:KJ]@0TM10K$6C]1 ?T6>R -M;%\*FX>/DT 1'K3NUL;E8Q"]B@V'[1LAVD$)"@ 6!-K(AY;0/)RX9:MLEY_- -M]-$P]B?;[YQY?H.62*BPI(^:P*I2*M$.2?. NYZ<@U9 FI&2H(_-Q^NN[O;^ -MRY!6K.18**7H:Z#Q+RC -MG_F<69ZY0 _#R//F]\6K$HF/D[J2CPA7@HA8T]76U\J[TBP?LI&H=8FO\.'D -M]^SZ)KM/C> ]<@%3EI(70.W>"N;"Q!22N)P4JX"3N*0^P-;U1L:N0ZB&F?#8 -MC[N6)NR<0LW]J8JHC8J:%^+5@M&C\S?O]'51H%I&FO"+F]D= -M$_6X0GY=D%F"6\-R-?+FQ8^=G*2M,(M""V/7FR+V -M-,6:_ZK^>6IMV_OUHK -MAK&2TT$/ZLCF5SF5=GF4N:C,ZI!T@N+DQS"^,E6_%?&UEC!B@')P3H+9#LCW -M6LC?&4"+3[=>J?J#FJ)LEI['\#7P;C;2EYRRD9HQEX+Q2O72?IB6G(Q0F8*C -M,A/P]/( J(.*O)^8B+MIH(+S[84<+_)X6U8(O\.CUE<@\OGW^LBUJ/:D6_'/ -MG[>3O<+V'>0^Q1*2(_*;N(:&G[ZA0/U]_?ONNQ*0+]Z:JXNML B@Z ?H!LN( -MJ:><@(SZ3IUSEI]!-^<;[O[#:9O=DIO6CU86@))?\?[KYNO(@&_5ARP1D7Q^ -MRISSD86:P/C&NB7D\_2)EM64>KFY@,+:X+PV4;BD=Y?;)_;S-OWPSZQ6RAF> -M5WFY0]HXRP.NN'JCF)TSE5JIQHR#X1 \]C!7-8U6:9J;HU):GTJ@QL%]XB5& -M_8R)K@_7L%.-US_NI]8VPI:6OHV]AXV3X%NZVJK4SXH"TKL5K]2)N)5'ME>= -MPO1%)'_^"KNRK4.)H$U2LF.?B6Y1%#9/;G?&)X-2N,_!6DEO,>0+QLS8R_\+^7-N]?;$*W2*$77##\1@J -M@8&;=Z>06^R"0^#1\;?_T^ 2I&P)2CBJ.J%,R/&VUO("BZ>D0WJA%);U9%+_ -MQ>;\QO.&E!BHETV.JR10\P/^#,%+43VILDF.HWN^BZQ6BQ?6]_;ZUO#K+ASS -MB;J-J9G!CIW)HAQ?(M_!0N&"GM\+GI)#5X.B-YCQOCE"_\8C68 6G8ZRB:CC -M52G0/AP+A;"0G/?EP>?6_/IS+!:)KL*7NAEF0#O SN=45""6G0ZALD#CEE/) -M%#3O]_'3DX!I@U&#OX1WG.S3P20ZP)*7H!.HK[.<%;C:GCSO_G/S ]91G\FH -M0;ML(%?-R@\:QHK0EUX1CXN+C:]F_XJ#%L7^P&Z(AU97]Y>>J)^F\+Y[2._D -M0]31 G$(N9/]&H!^F8A8L%.KP/XS.OXZY1J1^["0E*H+@O_STLQ0 Y$WEUJ> -M\JOLGN64X[Q<@;6>4*^+S');(-L'W*Y;^Y"0DU:"J::9XT(W\,+CP^<7J8BO -M@T:2D9H$P?COQNNFGY.#6AV2$HL:VI?V^A)'X3T:'$_M1HL.H8Y;%^0)_^?B -MXH./E$1>4X",V3;%=J+: -MDY>V5S9;K@Y3K,#0[])OUE.-O97MOU^)BL:$5_$*'N/' ,B4M%14G_8@CY:. -M4Q$V-7OE^EJYAY"UJ:>]=A*[LX.E!EC/S\@LSO&KJ)[SL?62B?*2AYK#*A7N -MTE?U?G >5:#1]I\%Z8'(#Y."T2 PO(#(T\"VKNB5Y+0L;/O]O-29YHJTI9+C%^5ZB#"/-#^R4:")9?ZJKX5HX!, -MH?37^BY/G19>FF2N()MMAL*IR$VHWO,<3I:L3;D&[U-F=K;A,A#OYF6A@Y+Y -MFP+R@7N*:80?AP)*S,\*5,J#JIN,B*FFDII3Q+!WPSKD]N7N\)J3E(MR@,.K -M$7\5V*YR7@Z:\-B6\^GJJDJ&"':%6;%SO%]L7_\,N&G:.>]XJ:,J16T*XV;).IO7\'T3)V^(:M?8[1YRL -MJR22D?0N=>M%EHN+Q -M4].#G@9@KYJ(G:P&EW'V-.+'^O/*EM%:T+Z?RJ'YDAOWB*ZG1) OTN6C2O&; -MC'^/ I!ACA+1X_?UTM.%4));FU:E3$/EUX-AD)#0^Q(3U@W',;\5L+O VI ? -MG+18F*DXA /'_,\+L+!3JX19J%OD$%W-,!&7]:L<&;V$@JGIE;K;X$F>EWK$ -MVP^>>8-3NHN=I5;EL";WYMK#UU^,; >]C4UCOG?HU"D9Q5LREIN?S R7N4TY -MI9,%,\3V5A &DH^,VX.5AIX&:;>0D0*LU\>-QL661T^-DT.=JH!*IEZ:PI#E -MEM>:P7^(0%U.2H*X[1G/\Y0+GBV7E192UZO\^O/N"YIQB\5&M+9;XM:M\1O/ -M'(6V,@2GDIZZH+>"QSO7+/J^/>"T>(JNCDB\ -MCZ5*X;6:Q_4>1T[_#QO"C_!6 -ME\4B-.X[RW#GIG1= X:MCHM/A^ 3];9PCJ7L0QB37Y33Z*USESO[^]B/4*Q( -MZ9N;CX7<\7$/VMT6P\F/W+F:2_I-K::"@,SD^?ODTH_HEJRS>O>'4[8%MZV@ -M_H1QR\_$CL&'GYV0J;6)3A& EYKG_O/D]NW%A$B(J5J1'*GKWZ<07)7[D1QS -M29+ ]G&6/I/+?(N3L0^=_)*4$-L(SP]D.)Q?A5>2FH%AI)<94;7FU@+(4H^@ -M5T.[#Z971@TPY^__SI*,H(M3@HCPA83 T_;2,!0!G)99KY:HJYUCAJ[#5I1\ -MK*4(OW2:1YFXC(:*5[_HU#WMM=;S0K95LUO5COI*;+9#$-@ X_]BRR>T4U>; -M1Q&0II821I.;)Z%%'"@%*^R6))6PYN_A"MY^@NVJ_08HFF&8R]GI]!1D^7P,#.;<\HYH] '8B/7LVK -M8$1;F9KL\C?Z3XJ2A7=U[6LR3C$]MY"PYH0>0F+?XRC -M3<#^;>[P9AJ)5 9-@IRE( !D,STJ>@(YJ75YHNKG[FM'S[/3P,@-) -MOME;5J1(G[N OXF% ONCRX_"CKR!E'V%J//GDY3!EY[-,A9G_:*3_>(DXLH -MAX#;:&SN,O<84)6 FM.I=HR5JL'B_/+D]5*VDIJYNPI&DHW17\=V=C[15W:( -MO#^&#HZXCDC-#?^O#=/27B_'RI6MPPI&NH.QEIJ* -M\,9" 5+,Q]K)F7@YFI9:+?R?H)^-I.(]%>[WCSV T;$Z,9:9!=SE$)B2$ECW -MD1J0P])O^[;$PKP*7H22H)NM0I/=*,-*_)"[FJF5]UH>IHY33>)6_;XK.X*C -MK;BS@OI&=8X TB&6VD^[GD&7^CV8SZ:M]-XNQ?Y@PVR6GZJ\VH]=H+79V\[* -MS0;2RK^RNHRL^Z6BK!X;K7*YQ].ZX^>!&)7O1KSG<;POB.\B()UL'2^6]+*V?*4D9.%4%37@<'F[,)O[\.. -M\(.;EG>"@SF7MJ7)V1 .B+*MFB%<@TR^B,/3D3!4TM!'Q[*=%\<(C[<&X./U -M^I;6DIV%@MJ2UH9(K:'P_ZEYX%EY_ -MU-SN>O+:])R$FP!QB8/1^87 A(A?FU2C?%+"PCCR$.6CNHBSK5H$KH/!WD'9 -M(P/R7"2&B38128FR]YK,\_E %^5)IX_#FKB-?I91@:+D%6[WU4_2;).L;Y^7 -MVK[-UM5VFL8;KJ2. 8FOKI,$L(K)5EP; L7REH_PK+V>1-*[EBG)$N\5R+E9:*T->.QAJ5L*5TRJO$O 6X4^0 -ME)2'7EZ;I8"!TJ * ]G?*\B>0M(- -M6MF1FM+ ?,?3[N*1EI"$AXF#@6P-FU/4\QF?O!&%CE5*6J2'@QDYV?_04-O) -M7Z 6N;C7E_4 diff --git a/nimble/host/pts/tpg/94654-20170317-085441153.pts b/nimble/host/pts/tpg/94654-20170317-085441153.pts deleted file mode 100644 index 92507b139c..0000000000 --- a/nimble/host/pts/tpg/94654-20170317-085441153.pts +++ /dev/null @@ -1,289 +0,0 @@ - -94654mynewt-Updated - - - L2CAP - 0
2
- 1
3
- 1
4
- 1
5
- 1
6
- 2
40
- 2
41
- 2
42
- 2
43
- 2
45
- 2
46
- 2
47
- 3
1
- 3
12
- 3
16
-
- - GAP - 0
2
- 0a
4
- 10
1
- 12
1
- 13
1
- 13
2
- 14
1
- 15
1
- 16
1
- 18
1
- 18
2
- 19
1
- 19
2
- 19
3
- 20
1
- 20
2
- 20
3
- 20
4
- 20A
1
- 20A
10
- 20A
11
- 20A
12
- 20A
13
- 20A
14
- 20A
15
- 20A
16
- 20A
17
- 20A
2
- 20A
3
- 20A
4
- 20A
5
- 20A
7
- 20A
8
- 20A
9
- 21
1
- 21
2
- 21
3
- 21
4
- 21
5
- 21
6
- 21
7
- 21
8
- 21
9
- 22
1
- 22
2
- 22
3
- 22
4
- 23
1
- 23
2
- 23
3
- 23
4
- 23
5
- 24
1
- 24
2
- 24
3
- 24
4
- 25
1
- 25
2
- 25
3
- 25
4
- 25
7
- 25
8
- 25
9
- 26
1
- 26
2
- 26
3
- 26
4
- 27
1
- 27
2
- 28
1
- 28
2
- 29
1
- 29
2
- 29
3
- 29
4
- 30
1
- 30
2
- 31
1
- 31
2
- 31
3
- 31
4
- 31
5
- 31
6
- 31
7
- 31
8
- 31
9
- 32
1
- 32
2
- 32
3
- 33
1
- 33
2
- 33
3
- 33
4
- 33
5
- 33
6
- 34
1
- 34
2
- 34
3
- 35
1
- 35
2
- 35
3
- 35
4
- 35
5
- 35
7
- 35
8
- 35
9
- 37
1
- 37
2
- 37
3
- 5
1
- 5
2
- 5
3
- 5
4
- 6
1
- 7
1
- 7
2
- 8
1
- 8
2
- 8a
3
- 9
1
-
- - SUM ICS - - - PROD - - - GATT - 1
1
- 1
2
- 2
2
- 3
1
- 3
10
- 3
11
- 3
12
- 3
14
- 3
15
- 3
16
- 3
17
- 3
18
- 3
19
- 3
2
- 3
20
- 3
21
- 3
22
- 3
23
- 3
3
- 3
4
- 3
5
- 3
6
- 3
7
- 3
8
- 3
9
- 4
1
- 4
10
- 4
11
- 4
12
- 4
14
- 4
15
- 4
16
- 4
17
- 4
18
- 4
19
- 4
2
- 4
20
- 4
21
- 4
22
- 4
23
- 4
3
- 4
4
- 4
5
- 4
6
- 4
7
- 4
8
- 4
9
- 7
2
- 7
3
- 7
4
-
- - ATT - 1
1
- 1
2
- 2
2
- 3
1
- 3
10
- 3
11
- 3
12
- 3
13
- 3
14
- 3
15
- 3
16
- 3
17
- 3
18
- 3
19
- 3
2
- 3
20
- 3
22
- 3
23
- 3
24
- 3
25
- 3
26
- 3
27
- 3
28
- 3
29
- 3
3
- 3
4
- 3
5
- 3
6
- 3
7
- 3
8
- 3
9
- 4
1
- 4
10
- 4
11
- 4
12
- 4
13
- 4
14
- 4
15
- 4
16
- 4
17
- 4
18
- 4
19
- 4
2
- 4
20
- 4
22
- 4
23
- 4
24
- 4
25
- 4
26
- 4
27
- 4
28
- 4
29
- 4
3
- 4
4
- 4
5
- 4
6
- 4
7
- 4
8
- 4
9
- 5
2
- 5
3
- 5
4
-
- - SM - 1
1
- 1
2
- 2
1
- 2
2
- 2
3
- 2
5
- 3
1
- 4
1
- 4
2
- 5
1
- 5
2
- 5
3
- 5
4
- 7
1
- 7
2
- 7
3
-
-
-
diff --git a/qualification/README.txt b/qualification/README.txt new file mode 100644 index 0000000000..f4f76ae39c --- /dev/null +++ b/qualification/README.txt @@ -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. +# + +This folder contains informations related to NimBLE qualification. + + +NimBLE Host: + +Currently PTS tests are done with AutoPTS [1] environment and qualification +related files (Qualification Workspace draft and PTS workspace) are stored +within NimBLE's AutoPTS workspace [2]. + +[1] https://github.com/auto-pts/auto-pts +[2] https://github.com/auto-pts/auto-pts/tree/master/autopts/workspaces/nimble-master + + +NimBLE Controller: TBD From b191f72a32320ecdcf1a9283d09a5ac452369706 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 12 Feb 2025 15:28:31 +0100 Subject: [PATCH 1198/1333] apps/bttester: Set default log level to sane value --- apps/bttester/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 0bab8b101e..0fe4727e46 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -109,7 +109,7 @@ syscfg.vals: OS_MAIN_STACK_SIZE: 512 SHELL_TASK: 0 SHELL_NEWTMGR: 0 - LOG_LEVEL: 12 + LOG_LEVEL: 1 MSYS_1_BLOCK_COUNT: 100 BLE_MONITOR_RTT: 1 From 90be7f86d0db5701292b67905e841be4cd0b4a1d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 26 Feb 2025 13:07:53 +0100 Subject: [PATCH 1199/1333] ci: Fix doxygen checks It looks like newer version of Doxygen has issues if no output is generated. Specify to generate HTML output in tmp folder. --- Doxyfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doxyfile b/Doxyfile index 35909d5383..91870efd74 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1,7 +1,8 @@ WARN_NO_PARAMDOC = YES WARN_LOGFILE = /tmp/doxygen_check/warnings.log INPUT = $(DOXYGEN_INPUT) -GENERATE_HTML = NO +GENERATE_HTML = YES +HTML_OUTPUT = /tmp/doxygen_check/html GENERATE_LATEX = NO MACRO_EXPANSION = YES WARN_FORMAT = $line: $text From a6541c4997b0d50673be91cb003958a8a240739b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 26 Feb 2025 13:56:54 +0100 Subject: [PATCH 1200/1333] ci: Add missing doxygen dependency graphviz is now required. --- .github/workflows/compliance_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index 1311335873..a0eef08bba 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -72,7 +72,7 @@ jobs: shell: bash run: | sudo apt-get update - sudo apt-get install -y doxygen + sudo apt-get install -y doxygen graphviz - name: Check Doxygen shell: bash run: | From ef1838a4db513d53db681aa4c8aef5e87762eeb3 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 26 Feb 2025 11:52:00 +0100 Subject: [PATCH 1201/1333] nimble/host: Don't used magic CID numbers in L2CAP code Use defines for specifying allowed COC CID range. --- nimble/host/include/host/ble_l2cap.h | 6 ++++++ nimble/host/src/ble_l2cap.c | 4 +++- nimble/host/src/ble_l2cap_coc_priv.h | 3 --- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/nimble/host/include/host/ble_l2cap.h b/nimble/host/include/host/ble_l2cap.h index f836e97c6c..d6532cf3e8 100644 --- a/nimble/host/include/host/ble_l2cap.h +++ b/nimble/host/include/host/ble_l2cap.h @@ -66,6 +66,12 @@ struct ble_hs_conn; /** Security Manager (SM) CID. */ #define BLE_L2CAP_CID_SM 6 +/** Start range for connection oriented channel CID. */ +#define BLE_L2CAP_COC_CID_START 0x0040 + +/** End range for connection oriented channel CID. */ +#define BLE_L2CAP_COC_CID_END 0x007F + /** @} */ /** diff --git a/nimble/host/src/ble_l2cap.c b/nimble/host/src/ble_l2cap.c index 50fe18c651..2b979e9181 100644 --- a/nimble/host/src/ble_l2cap.c +++ b/nimble/host/src/ble_l2cap.c @@ -385,7 +385,9 @@ ble_l2cap_rx(struct ble_hs_conn *conn, } /* For CIDs from dynamic range we check if SDU size isn't larger than MPS */ - if (chan->dcid >= 0x0040 && chan->dcid <= 0x007F && l2cap_hdr.len > chan->my_coc_mps) { + if (chan->dcid >= BLE_L2CAP_COC_CID_START && + chan->dcid <= BLE_L2CAP_COC_CID_END && + l2cap_hdr.len > chan->my_coc_mps) { /* Data exceeds MPS */ BLE_HS_LOG(ERROR, "error: sdu_len > chan->my_coc_mps (%d>%d)\n", l2cap_hdr.len, chan->my_coc_mps); diff --git a/nimble/host/src/ble_l2cap_coc_priv.h b/nimble/host/src/ble_l2cap_coc_priv.h index 37a95b31ec..8a87303fb7 100644 --- a/nimble/host/src/ble_l2cap_coc_priv.h +++ b/nimble/host/src/ble_l2cap_coc_priv.h @@ -30,9 +30,6 @@ extern "C" { #endif -#define BLE_L2CAP_COC_CID_START 0x0040 -#define BLE_L2CAP_COC_CID_END 0x007F - struct ble_l2cap_chan; #define BLE_L2CAP_COC_FLAG_STALLED 0x01 From 4d967a34b7367195cadc797eff14fc422854574e Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 26 Feb 2025 11:53:30 +0100 Subject: [PATCH 1202/1333] nimble/host: Allow L2CAP disconnect request only on COC channels Disconnecting fixed CID channel (like SMP, ATT or control) could lead to hard to debug issues. It is also invalid (at least for ATT CID behavior is clarified in spec) to use this to disconnect fixed channel. --- nimble/host/include/host/ble_l2cap.h | 2 +- nimble/host/src/ble_l2cap_sig.c | 33 +++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/nimble/host/include/host/ble_l2cap.h b/nimble/host/include/host/ble_l2cap.h index d6532cf3e8..32bd41bc8d 100644 --- a/nimble/host/include/host/ble_l2cap.h +++ b/nimble/host/include/host/ble_l2cap.h @@ -571,7 +571,7 @@ int ble_l2cap_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, /** * @brief Disconnect an L2CAP channel. * - * This function disconnects the specified L2CAP channel by sending a disconnect signal. + * This function disconnects the specified L2CAP connection oriented channel by sending a disconnect signal. * * @param chan Pointer to the L2CAP channel structure representing the channel to disconnect. * diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index 029e855383..8cb5e07821 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -1574,6 +1574,8 @@ ble_l2cap_sig_disc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, struct ble_l2cap_chan *chan; struct ble_hs_conn *conn; int rc; + uint16_t scid; + uint16_t dcid; rc = ble_hs_mbuf_pullup_base(om, sizeof(*req)); if (rc != 0) { @@ -1593,18 +1595,34 @@ ble_l2cap_sig_disc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, conn = ble_hs_conn_find_assert(conn_handle); req = (struct ble_l2cap_sig_disc_req *) (*om)->om_data; + scid = le16toh(req->scid); + dcid = le16toh(req->dcid); + + if (scid < BLE_L2CAP_COC_CID_START || scid > BLE_L2CAP_COC_CID_END || + dcid < BLE_L2CAP_COC_CID_START || dcid > BLE_L2CAP_COC_CID_END) { + /* Don't bother with look-up if it is not for connection oriented + * channel + */ + chan = NULL; + } else { + /* Let's find matching channel. Note that destination CID in the request + * is from peer perspective. It is source CID from nimble perspective + */ + chan = ble_hs_conn_chan_find_by_scid(conn, dcid); + } - /* Let's find matching channel. Note that destination CID in the request - * is from peer perspective. It is source CID from nimble perspective - */ - chan = ble_hs_conn_chan_find_by_scid(conn, le16toh(req->dcid)); if (!chan) { os_mbuf_free_chain(txom); ble_hs_unlock(); ble_l2cap_sig_reject_invalid_cid_tx(conn_handle, hdr->identifier, req->dcid, req->scid); return 0; } - if (le16toh(req->scid) != chan->dcid) { + + /* Core Spec 6.0 Vol3 PartA 4.6 + * If the receiver finds a DCID match but the SCID fails to find the same + * match, the request should be silently discarded. + */ + if (scid != chan->dcid) { os_mbuf_free_chain(txom); ble_hs_unlock(); return 0; @@ -1704,6 +1722,11 @@ ble_l2cap_sig_disconnect(struct ble_l2cap_chan *chan) struct ble_l2cap_sig_proc *proc; int rc; + /* this is allowed only for connection oriented channels */ + if (chan->scid < BLE_L2CAP_COC_CID_START || chan->scid > BLE_L2CAP_COC_CID_END) { + return BLE_HS_EREJECT; + } + if (chan->flags & BLE_L2CAP_CHAN_F_DISCONNECTING) { return 0; } From 5506aebe58517cfa824d66f97f3ae683a510248b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 17 Feb 2025 17:57:09 +0100 Subject: [PATCH 1203/1333] nimble/ll: Fix update chanmap in BIGInfo This fix merged in 890be280a3 was broken during rebase. --- nimble/controller/src/ble_ll_iso_big.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 1b4e50d363..2b84e98070 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -307,8 +307,8 @@ ble_ll_iso_big_biginfo_calc(struct ble_ll_iso_big *big, uint32_t seed_aa) buf += 2; /* chm, phy */ - memcpy(buf, big->chan_map, 5); ble_ll_iso_big_biginfo_chanmap_update(big); + buf += 5; /* bis_payload_cnt, framing */ memset(buf, 0x00, 5); From 6dbb0854f2901f515fdd95688f94c31155595b2e Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 26 Feb 2025 16:06:34 +0100 Subject: [PATCH 1204/1333] nimble/host: Fix invalid pullup in L2CAP connection request There was a typo which resulted in pulling up pointer size instead of request size. --- nimble/host/src/ble_l2cap_sig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index 8cb5e07821..2188b5913d 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -1181,7 +1181,7 @@ ble_l2cap_sig_coc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, struct ble_hs_conn *conn; uint16_t scid; - rc = ble_hs_mbuf_pullup_base(om, sizeof(req)); + rc = ble_hs_mbuf_pullup_base(om, sizeof(*req)); if (rc != 0) { return rc; } From 138b42be52c0917f93f44f9629a1ddfd43ec9d63 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 25 Feb 2025 16:25:40 +0100 Subject: [PATCH 1205/1333] nimble/ll: Fix allocating BIG BIG handle has to be assigned before other checks that may fail as it's used to check if BIG is allocated. If not assigned properly, the BIG may not be freed in case of an error. --- nimble/controller/src/ble_ll_iso_big.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 2b84e98070..570bf01a70 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -1006,6 +1006,7 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, BLE_LL_ASSERT(big); big_pool_free--; + big->handle = big_handle; advsm = ble_ll_adv_sync_get(adv_handle); if (!advsm) { @@ -1019,7 +1020,6 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, } big->advsm = advsm; - big->handle = big_handle; big->crc_init = ble_ll_rand(); memcpy(big->chan_map, g_ble_ll_data.chan_map, BLE_LL_CHAN_MAP_LEN); From af04f5c418f838b8fc7092cd0ff084e876b0c91b Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 19 Feb 2025 23:05:55 +0100 Subject: [PATCH 1206/1333] nimble/ll: Fix command status for HCI LE Ext Create Connection Status should be 'unsupported feature or parameter value' if specified phy is not supported. --- nimble/controller/src/ble_ll_conn_hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 20ad4c1b8c..877a100386 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -457,7 +457,7 @@ ble_ll_conn_hci_create_check_scan(struct ble_ll_conn_create_scan *p) #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) if (p->init_phy_mask & ~ble_ll_conn_create_valid_phy_mask) { - return BLE_ERR_INV_HCI_CMD_PARMS; + return BLE_ERR_UNSUPPORTED; } if (!(p->init_phy_mask & ble_ll_conn_create_required_phy_mask)) { From d508a854cb7539dfa07e2b148462dc2f17d4f262 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Wed, 19 Feb 2025 23:05:55 +0100 Subject: [PATCH 1207/1333] nimble/ll: Fix command status for HCI LE Set Ext Scan Parameters Status should be 'unsupported feature or parameter value' if specified phy is not supported. --- nimble/controller/src/ble_ll_scan.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index d758d899f1..0f73fd2e8c 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -2208,11 +2208,13 @@ ble_ll_scan_hci_set_ext_params(const uint8_t *cmdbuf, uint8_t len) return BLE_ERR_INV_HCI_CMD_PARMS; } - /* Check if no reserved bits in PHYS are set and that at least one valid PHY - * is set. - */ - if (!(cmd->phys & SCAN_VALID_PHY_MASK) || - (cmd->phys & ~SCAN_VALID_PHY_MASK)) { + /* Check if valid phy is specified */ + if (cmd->phys & ~SCAN_VALID_PHY_MASK) { + return BLE_ERR_UNSUPPORTED; + } + + /* Check if at least one valid phy is specified */ + if (!(cmd->phys & SCAN_VALID_PHY_MASK)) { return BLE_ERR_INV_HCI_CMD_PARMS; } From 62bb1b148917b4b40596c6582482a12e970239f2 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 20 Feb 2025 12:35:15 +0100 Subject: [PATCH 1208/1333] nimble/ll: Fix addr type in adv reports We should always use flag for checking if InitA was resolved since rpa index can be set to RL entry index even if it was not used for resolving (e.g. peer advertised with identity address). --- nimble/controller/src/ble_ll_scan_aux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index ceb094c027..b9d5141581 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -425,7 +425,7 @@ ble_ll_hci_ev_update_ext_adv_report_from_ext(struct ble_hci_ev *hci_ev, if (eh_flags & (1 << BLE_LL_EXT_ADV_ADVA_BIT)) { #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - if (rxinfo->rpa_index >= 0) { + if (rxinfo->flags & BLE_MBUF_HDR_F_RESOLVED) { rl = &g_ble_ll_resolv_list[rxinfo->rpa_index]; report->addr_type = rl->rl_addr_type + 2; memcpy(report->addr, rl->rl_identity_addr, 6); From cb21d6c187b106dc6a108a7b2ccd0bcd6a17a188 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Thu, 20 Feb 2025 17:01:02 +0100 Subject: [PATCH 1209/1333] nimble/ll: Ignore RFU fields in CEAP format Fields that are RFU in CEAP format should be ignored. --- nimble/controller/src/ble_ll_scan_aux.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index b9d5141581..535c9c6470 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -388,7 +388,6 @@ ble_ll_hci_ev_update_ext_adv_report_from_ext(struct ble_hci_ev *hci_ev, #endif uint8_t pdu_hdr; uint8_t adv_mode; - uint8_t eh_len; uint8_t eh_flags; uint8_t *eh_data; uint8_t *rxbuf; @@ -397,7 +396,6 @@ ble_ll_hci_ev_update_ext_adv_report_from_ext(struct ble_hci_ev *hci_ev, pdu_hdr = rxbuf[0]; adv_mode = rxbuf[2] >> 6; - eh_len = rxbuf[2] & 0x3f; eh_flags = rxbuf[3]; eh_data = &rxbuf[4]; @@ -484,8 +482,10 @@ ble_ll_hci_ev_update_ext_adv_report_from_ext(struct ble_hci_ev *hci_ev, report->tx_power = 0x7f; } - /* Strip PDU header and ext header, leave only AD */ - os_mbuf_adj(rxpdu, 3 + eh_len); + /* AdvData in ADV_EXT_IND is RFU so we should ignore it, i.e. we can just + * remove any data left in mbuf + */ + os_mbuf_adj(rxpdu, os_mbuf_len(rxpdu)); } @@ -851,9 +851,10 @@ ble_ll_scan_aux_parse_to_aux_data(struct ble_ll_scan_aux_data *aux, /* Now parse extended header... */ - /* AdvA is only valid in 1st PDU, ignore in AUX_CHAIN_IND */ + /* AdvA is only valid in AUX_ADV_IND if not already present in ADV_EXT_IND */ if (eh_flags & (1 << BLE_LL_EXT_ADV_ADVA_BIT)) { - if (!(aux->flags & BLE_LL_SCAN_AUX_F_AUX_CHAIN)) { + if (!(aux->flags & BLE_LL_SCAN_AUX_F_HAS_ADVA) && + !(aux->flags & BLE_LL_SCAN_AUX_F_AUX_CHAIN)) { memcpy(aux->adva, eh_data, 6); aux->adva_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_TXADD_MASK); aux->flags |= BLE_LL_SCAN_AUX_F_HAS_ADVA; @@ -864,9 +865,10 @@ ble_ll_scan_aux_parse_to_aux_data(struct ble_ll_scan_aux_data *aux, eh_data += BLE_LL_EXT_ADV_ADVA_SIZE; } - /* TargetA is only valid in 1st PDU, ignore in AUX_CHAIN_IND */ + /* TargetA is only valid in AUX_ADV_IND if not already present in ADV_EXT_IND */ if (eh_flags & (1 << BLE_LL_EXT_ADV_TARGETA_BIT)) { - if (!(aux->flags & BLE_LL_SCAN_AUX_F_AUX_CHAIN)) { + if (!(aux->flags & BLE_LL_SCAN_AUX_F_HAS_TARGETA) && + !(aux->flags & BLE_LL_SCAN_AUX_F_AUX_CHAIN)) { memcpy(aux->targeta, eh_data, 6); aux->targeta_type = !!(pdu_hdr & BLE_ADV_PDU_HDR_RXADD_MASK); aux->flags |= BLE_LL_SCAN_AUX_F_HAS_TARGETA; @@ -901,7 +903,8 @@ ble_ll_scan_aux_parse_to_aux_data(struct ble_ll_scan_aux_data *aux, } } - if (eh_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) { + /* AuxPtr is RFU if AdvMode!=0 so ignore in such case */ + if ((adv_mode == 0) && (eh_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT))) { aux->aux_ptr = get_le24(eh_data); rxhdr->rxinfo.flags |= BLE_MBUF_HDR_F_AUX_PTR_WAIT; } From 35f589e8a7aa4a96809793b966916ee2d8f1182d Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Mon, 3 Mar 2025 11:10:04 +0100 Subject: [PATCH 1210/1333] apps: bttester: fix compilation error Fixes compilation error: Error: repos/apache-mynewt-nimble/nimble/host/mesh/src/cfg_cli.c: In function 'mod_member_list_handle': repos/apache-mynewt-nimble/nimble/host/mesh/src/cfg_cli.c:486:18: error: 'cid' may be used uninitialized [-Werror=maybe-uninitialized] 486 | (vnd && param->cid != cid)) { | ~~~~~^~~~~~~~~~~~~~~~~~~~~ repos/apache-mynewt-nimble/nimble/host/mesh/src/cfg_cli.c:468:37: note: 'cid' was declared here 468 | uint16_t elem_addr, mod_id, cid; | ^~~ --- nimble/host/mesh/src/cfg_cli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/mesh/src/cfg_cli.c b/nimble/host/mesh/src/cfg_cli.c index 6195f2ac29..f4a1ad1574 100644 --- a/nimble/host/mesh/src/cfg_cli.c +++ b/nimble/host/mesh/src/cfg_cli.c @@ -465,7 +465,7 @@ static int mod_member_list_handle(struct bt_mesh_msg_ctx *ctx, struct os_mbuf *buf, bool vnd, struct mod_member_list_param *param) { - uint16_t elem_addr, mod_id, cid; + uint16_t elem_addr, mod_id, cid = 0; uint8_t status; int i; From d0412020cb017378d8e95029ae0a24500faaefd3 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Thu, 6 Feb 2025 14:44:54 +0100 Subject: [PATCH 1211/1333] nimble: bttester: add variable to properly initialize characteristics New variable that stores value handle of chrc is introduced. It's needed to properly register predefined characteristics. Previously, two characteristics were using same variable to store value handle, so registering both of them resulted in overwriting handle of the former one --- apps/bttester/src/btp_gatt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/bttester/src/btp_gatt.c b/apps/bttester/src/btp_gatt.c index 496779ebb6..7275460d6d 100644 --- a/apps/bttester/src/btp_gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -82,6 +82,7 @@ static uint8_t indicate_state; static uint16_t myconn_handle; static struct os_callout notify_tx_timer; uint16_t notify_handle; +uint16_t notify_handle_alt; uint8_t notify_value = 90; struct find_attr_data { @@ -243,7 +244,7 @@ static const struct ble_gatt_svc_def gatt_svr_svcs[] = { }, { .uuid = PTS_UUID_DECLARE(PTS_CHR_NOTIFY_ALT), .access_cb = gatt_svr_read_write_test, - .val_handle = ¬ify_handle, + .val_handle = ¬ify_handle_alt, .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_NOTIFY | From aafed638a844aa1477647f547a2dadcabd6a6d9d Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 4 Mar 2025 13:54:37 +0100 Subject: [PATCH 1212/1333] apps/bttester: Remove not used syscfg value BTTESTER_CONN_PARAM_UPDATE is leftover and is no longer used in code. --- apps/bttester/syscfg.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 0fe4727e46..1be2945575 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -74,10 +74,6 @@ syscfg.defs: description: Maximum BTP payload value: 2048 - BTTESTER_CONN_PARAM_UPDATE: - description: Trigger conn param update after connection establish - value: 0 - BTTESTER_DEBUG: description: Enable debug logging value: 0 From 1f65494e22312b145ed74f45a573572ca5470856 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 4 Mar 2025 11:50:13 +0100 Subject: [PATCH 1213/1333] nimble/host: Refactor L2CAP signaling PDU parsing Add helper that validates if PDU size is valid. This fixes L2CAP/COS/CED/BI-11-C qualification test. --- nimble/host/src/ble_l2cap_sig.c | 87 ++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 33 deletions(-) diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index 2188b5913d..f360ad708b 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -407,6 +407,38 @@ ble_l2cap_sig_check_conn_params(const struct ble_gap_upd_params *params) return 0; } +/* This helper does validation of sizes and (if requested) CIDs sizes */ +static int +ble_l2cap_sig_mbuf_pullup_base(struct os_mbuf **om, int base_len, unsigned int *cids_count) +{ + if (cids_count) { + if (OS_MBUF_PKTLEN(*om) < base_len) { + return BLE_HS_EBADDATA; + } + + if ((OS_MBUF_PKTLEN(*om) - base_len) % sizeof(uint16_t)) { + return BLE_HS_EBADDATA; + } + + *cids_count = (OS_MBUF_PKTLEN(*om) - base_len) / sizeof(uint16_t); + if (*cids_count == 0 || *cids_count > BLE_L2CAP_MAX_COC_CONN_REQ) { + return BLE_HS_EBADDATA; + } + } else { + if (OS_MBUF_PKTLEN(*om) != base_len) { + return BLE_HS_EBADDATA; + } + } + + /* data sizes validated, just pullup all */ + *om = os_mbuf_pullup(*om, OS_MBUF_PKTLEN(*om)); + if (*om == NULL) { + return BLE_HS_ENOMEM; + } + + return 0; +} + int ble_l2cap_sig_update_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, @@ -423,7 +455,7 @@ ble_l2cap_sig_update_req_rx(uint16_t conn_handle, l2cap_result = 0; /* Silence spurious gcc warning. */ - rc = ble_hs_mbuf_pullup_base(om, BLE_L2CAP_SIG_UPDATE_REQ_SZ); + rc = ble_l2cap_sig_mbuf_pullup_base(om, sizeof(*req), NULL); if (rc != 0) { return rc; } @@ -500,7 +532,7 @@ ble_l2cap_sig_update_rsp_rx(uint16_t conn_handle, return 0; } - rc = ble_hs_mbuf_pullup_base(om, BLE_L2CAP_SIG_UPDATE_RSP_SZ); + rc = ble_l2cap_sig_mbuf_pullup_base(om, sizeof(*rsp), NULL); if (rc != 0) { cb_status = rc; goto done; @@ -766,12 +798,12 @@ ble_l2cap_sig_credit_base_reconfig_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_credit_base_reconfig_rsp *rsp; struct ble_hs_conn *conn; struct os_mbuf *txom; - int i; + unsigned int i; int rc; - uint8_t cid_cnt; + unsigned int cid_cnt; uint8_t reduction_mps = 0; - rc = ble_hs_mbuf_pullup_base(om, hdr->length); + rc = ble_l2cap_sig_mbuf_pullup_base(om, sizeof(*req), &cid_cnt); if (rc != 0) { return rc; } @@ -794,11 +826,6 @@ ble_l2cap_sig_credit_base_reconfig_req_rx(uint16_t conn_handle, return 0; } - if (hdr->length <= sizeof(*req)) { - rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_UNACCEPTED_PARAM); - goto failed; - } - req = (struct ble_l2cap_sig_credit_base_reconfig_req *)(*om)->om_data; if ((req->mps < BLE_L2CAP_ECOC_MIN_MTU) || (req->mtu < BLE_L2CAP_ECOC_MIN_MTU)) { @@ -809,12 +836,6 @@ ble_l2cap_sig_credit_base_reconfig_req_rx(uint16_t conn_handle, /* Assume request will succeed. If not, result will be updated */ rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_SUCCEED); - cid_cnt = (hdr->length - sizeof(*req)) / sizeof(uint16_t); - if (cid_cnt > BLE_L2CAP_MAX_COC_CONN_REQ) { - rsp->result = htole16(BLE_L2CAP_ERR_RECONFIG_UNACCEPTED_PARAM); - goto failed; - } - for (i = 0; i < cid_cnt; i++) { chan[i] = ble_hs_conn_chan_find_by_dcid(conn, req->dcids[i]); if (!chan[i]) { @@ -899,7 +920,7 @@ ble_l2cap_sig_credit_base_reconfig_rsp_rx(uint16_t conn_handle, return 0; } - rc = ble_hs_mbuf_pullup_base(om, hdr->length); + rc = ble_l2cap_sig_mbuf_pullup_base(om, sizeof(*rsp), NULL); if (rc != 0) { return rc; } @@ -923,17 +944,17 @@ ble_l2cap_sig_credit_base_con_req_rx(uint16_t conn_handle, struct ble_l2cap_chan *chans[5] = { 0 }; struct ble_hs_conn *conn; uint16_t scid; - uint8_t num_of_scids; + unsigned int num_of_scids; uint8_t chan_created = 0; int i; - uint8_t len; + unsigned int len; - rc = ble_hs_mbuf_pullup_base(om, hdr->length); + rc = ble_l2cap_sig_mbuf_pullup_base(om, sizeof(*req), &num_of_scids); if (rc != 0) { return rc; } - len = (hdr->length > sizeof(*req)) ? hdr->length : sizeof(*req); + len = sizeof(*rsp) + (num_of_scids * sizeof(rsp->dcids[0])); rsp = ble_l2cap_sig_cmd_get(BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP, hdr->identifier, len , &txom); @@ -960,12 +981,6 @@ ble_l2cap_sig_credit_base_con_req_rx(uint16_t conn_handle, req = (struct ble_l2cap_sig_credit_base_connect_req *)(*om)->om_data; - num_of_scids = (hdr->length - sizeof(*req)) / sizeof(uint16_t); - if (num_of_scids > 5) { - rsp->result = htole16(BLE_L2CAP_COC_ERR_INVALID_PARAMETERS); - goto failed; - } - if ((req->mtu < BLE_L2CAP_ECOC_MIN_MTU) || (req->mps < BLE_L2CAP_ECOC_MIN_MTU)) { rsp->result = htole16(BLE_L2CAP_COC_ERR_INVALID_PARAMETERS); goto failed; @@ -1089,6 +1104,7 @@ ble_l2cap_sig_credit_base_con_rsp_rx(uint16_t conn_handle, int rc; int i; uint16_t duplicated_cids[5] = {}; + unsigned int num_of_dcids; #if !BLE_MONITOR BLE_HS_LOG(DEBUG, "L2CAP LE COC connection response received\n"); @@ -1101,11 +1117,16 @@ ble_l2cap_sig_credit_base_con_rsp_rx(uint16_t conn_handle, return 0; } - rc = ble_hs_mbuf_pullup_base(om, hdr->length); + rc = ble_l2cap_sig_mbuf_pullup_base(om, sizeof(*rsp), &num_of_dcids); if (rc != 0) { goto done; } + /* spec doesn't say what to do in that case so just fail */ + if (proc->connect.chan_cnt != num_of_dcids) { + goto done; + } + rsp = (struct ble_l2cap_sig_credit_base_connect_rsp *)(*om)->om_data; if (rsp->result) { @@ -1181,7 +1202,7 @@ ble_l2cap_sig_coc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, struct ble_hs_conn *conn; uint16_t scid; - rc = ble_hs_mbuf_pullup_base(om, sizeof(*req)); + rc = ble_l2cap_sig_mbuf_pullup_base(om, sizeof(*req), NULL); if (rc != 0) { return rc; } @@ -1295,7 +1316,7 @@ ble_l2cap_sig_coc_rsp_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, return 0; } - rc = ble_hs_mbuf_pullup_base(om, sizeof(*rsp)); + rc = ble_l2cap_sig_mbuf_pullup_base(om, sizeof(*rsp), NULL); if (rc != 0) { goto done; } @@ -1577,7 +1598,7 @@ ble_l2cap_sig_disc_req_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, uint16_t scid; uint16_t dcid; - rc = ble_hs_mbuf_pullup_base(om, sizeof(*req)); + rc = ble_l2cap_sig_mbuf_pullup_base(om, sizeof(*req), NULL); if (rc != 0) { return rc; } @@ -1690,7 +1711,7 @@ ble_l2cap_sig_disc_rsp_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, return 0; } - rc = ble_hs_mbuf_pullup_base(om, sizeof(*rsp)); + rc = ble_l2cap_sig_mbuf_pullup_base(om, sizeof(*rsp), NULL); if (rc != 0) { goto done; } @@ -1770,7 +1791,7 @@ ble_l2cap_sig_le_credits_rx(uint16_t conn_handle, struct ble_l2cap_sig_hdr *hdr, struct ble_l2cap_sig_le_credits *req; int rc; - rc = ble_hs_mbuf_pullup_base(om, sizeof(*req)); + rc = ble_l2cap_sig_mbuf_pullup_base(om, sizeof(*req), NULL); if (rc != 0) { return 0; } From c8842468c661af71d334dc194d3d7a30e48bb9e2 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 6 Mar 2025 18:05:59 +0100 Subject: [PATCH 1214/1333] porting: add missing call to ble_ll_init `nimble_port_init()` needs to call ble_ll_init() when controller is enabled. Signed-off-by: Gerard Marull-Paretas --- porting/nimble/src/nimble_port.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/porting/nimble/src/nimble_port.c b/porting/nimble/src/nimble_port.c index bb26f22a3f..c071da732e 100644 --- a/porting/nimble/src/nimble_port.c +++ b/porting/nimble/src/nimble_port.c @@ -31,6 +31,9 @@ static struct ble_npl_eventq g_eventq_dflt; extern void os_msys_init(void); extern void os_mempool_module_init(void); +#if NIMBLE_CFG_CONTROLLER +extern void ble_ll_init(void); +#endif void nimble_port_init(void) @@ -40,6 +43,11 @@ nimble_port_init(void) /* Initialize the global memory pool */ os_mempool_module_init(); os_msys_init(); + +#if NIMBLE_CFG_CONTROLLER + ble_ll_init(); +#endif + /* Initialize transport */ ble_transport_init(); /* Initialize the host */ From 7b14eab3d07caffa3a70046271b9f5b805f5c965 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Fri, 28 Feb 2025 15:51:40 +0100 Subject: [PATCH 1215/1333] apps: bttester: add characteristic to bttester database This characteristic is needed to pass tests that verify if IUT is able to respond with Insufficient Authorization error code to read, write requests from PTS. --- apps/bttester/src/btp_gatt.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/apps/bttester/src/btp_gatt.c b/apps/bttester/src/btp_gatt.c index 7275460d6d..157e7da1cb 100644 --- a/apps/bttester/src/btp_gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -68,6 +68,7 @@ #define PTS_DSC_READ_WRITE 0x000b #define PTS_CHR_NOTIFY 0x0025 #define PTS_CHR_NOTIFY_ALT 0x0026 +#define PTS_CHR_READ_WRITE_AUTHOR 0x0027 #define PTS_LONG_CHR_READ_WRITE 0x0015 #define PTS_LONG_CHR_READ_WRITE_ALT 0x0016 #define PTS_LONG_DSC_READ_WRITE 0x001b @@ -107,6 +108,11 @@ gatt_svr_read_write_auth_test(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); +static int +gatt_svr_read_write_author_test(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg); + static int gatt_svr_read_write_enc_test(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, @@ -210,6 +216,13 @@ static const struct ble_gatt_svc_def gatt_svr_svcs[] = { BLE_GATT_CHR_F_WRITE_AUTHEN | BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_AUTHEN, + }, { + .uuid = PTS_UUID_DECLARE(PTS_CHR_READ_WRITE_AUTHOR), + .access_cb = gatt_svr_read_write_author_test, + .flags = BLE_GATT_CHR_F_READ_AUTHOR | + BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_WRITE_AUTHOR | + BLE_GATT_CHR_F_WRITE }, { .uuid = PTS_UUID_DECLARE(PTS_CHR_RELIABLE_WRITE), .access_cb = gatt_svr_rel_write_test, @@ -419,6 +432,29 @@ gatt_svr_read_write_auth_test(uint16_t conn_handle, uint16_t attr_handle, } } +static int +gatt_svr_read_write_author_test(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg) +{ + uint16_t uuid16; + + uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid); + assert(uuid16 != 0); + + switch (uuid16) { + case PTS_CHR_READ_WRITE_AUTHOR: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + return BLE_ATT_ERR_INSUFFICIENT_AUTHOR; + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + return BLE_ATT_ERR_INSUFFICIENT_AUTHOR; + } + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } +} + static int gatt_svr_read_write_enc_test(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, From 043ba6f1b4a1dc40c92ad5da9817f47b65149da9 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 7 Mar 2025 12:10:28 +0100 Subject: [PATCH 1216/1333] nimble/ll: Fix ISO BIG events scheduling ISO events should have 'fixed' flag set for scheduling, except for the 1st one, so they can preempt any other event. --- nimble/controller/src/ble_ll_iso_big.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 570bf01a70..286e558145 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -611,7 +611,7 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) big_sched_set(big); /* XXX this should always succeed since we preempt anything for now */ - rc = ble_ll_sched_iso_big(&big->sch, 0, 0); + rc = ble_ll_sched_iso_big(&big->sch, 0, 1); assert(rc == 0); } while (rc < 0); From 6bb6f7b12cf05881d759a3eeba7631b719261816 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 7 Mar 2025 12:15:31 +0100 Subject: [PATCH 1217/1333] nimble/ll: Update assert and related comment in BIG code The comment is still valid since scheduling should never fail if we allow to preempt any other event. --- nimble/controller/src/ble_ll_iso_big.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 286e558145..492bf23765 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -610,9 +610,9 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) big->anchor_offset++; big_sched_set(big); - /* XXX this should always succeed since we preempt anything for now */ + /* This should always succeed since we preempt anything for now */ rc = ble_ll_sched_iso_big(&big->sch, 0, 1); - assert(rc == 0); + BLE_LL_ASSERT(rc == 0); } while (rc < 0); ble_ll_iso_big_update_event_start(big, big_counter); From eff02647da47e5b65a3c9a1a627b32275a901731 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 7 Mar 2025 16:11:23 +0100 Subject: [PATCH 1218/1333] Fix uncrustify configuration Set multiline #define indentation to 4 spaces. --- uncrustify.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uncrustify.cfg b/uncrustify.cfg index 43dee3b91c..0fddbf7b4e 100644 --- a/uncrustify.cfg +++ b/uncrustify.cfg @@ -3482,7 +3482,7 @@ pp_ignore_define_body = false # true/false # (ex. 3 ==> the body is indented starting 3 columns at the right of '#') # # Default: 8 -pp_multiline_define_body_indent = 8 # number +pp_multiline_define_body_indent = 4 # number # Whether to indent case statements between #if, #else, and #endif. # Only applies to the indent of the preprocessor that the case statements From 64a5af6b664080070616b2d196672ae829021182 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 10 Mar 2025 17:48:16 +0100 Subject: [PATCH 1219/1333] porting: add missing os/os_cputime.h include When building controller, `os_cputime_init` is called, however, header where it is declared was not included. Signed-off-by: Gerard Marull-Paretas --- porting/nimble/src/nimble_port.c | 1 + 1 file changed, 1 insertion(+) diff --git a/porting/nimble/src/nimble_port.c b/porting/nimble/src/nimble_port.c index c071da732e..cfb288549b 100644 --- a/porting/nimble/src/nimble_port.c +++ b/porting/nimble/src/nimble_port.c @@ -25,6 +25,7 @@ #include "nimble/transport.h" #if NIMBLE_CFG_CONTROLLER #include "controller/ble_ll.h" +#include "os/os_cputime.h" #endif static struct ble_npl_eventq g_eventq_dflt; From 98cd77dc3e6dc55ff0d57260cc7f78e51b9c70e2 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 10 Mar 2025 17:53:00 +0100 Subject: [PATCH 1220/1333] controller: add missing os/util.h include ble_ll_adv.c module uses ARRAY_SIZE, defined in os/util.h. Signed-off-by: Gerard Marull-Paretas --- nimble/controller/src/ble_ll_adv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 401fe2747e..84f6e789d6 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -24,6 +24,7 @@ #include #include "syscfg/syscfg.h" #include "os/os.h" +#include "os/util.h" #include "ble/xcvr.h" #include "nimble/ble.h" #include "nimble/nimble_opt.h" From d4b97f371c564619abc2f8c350b33eff0bb6c48d Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 7 Jan 2025 11:29:55 +0100 Subject: [PATCH 1221/1333] nimble/ll: Fix missing include This fixes missing syscfg.h include that is neeed to evaluate MYNEWT_VAL(). --- nimble/controller/include/controller/ble_ll_isoal.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/controller/include/controller/ble_ll_isoal.h b/nimble/controller/include/controller/ble_ll_isoal.h index 4ad8d858bd..caf15e2d59 100644 --- a/nimble/controller/include/controller/ble_ll_isoal.h +++ b/nimble/controller/include/controller/ble_ll_isoal.h @@ -20,6 +20,8 @@ #ifndef H_BLE_LL_ISOAL_ #define H_BLE_LL_ISOAL_ +#include + #ifdef __cplusplus extern "C" { #endif From 694d389e2267b333f33891cff4a4bccb7d4b31ff Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Wed, 8 Jan 2025 13:56:04 +0100 Subject: [PATCH 1222/1333] nimble/ll: Move HCI command handler out from ble_ll_isoal This moves the ISO ralated command handlers out from ISOAL. This adds new ble_ll_iso source file that will hold common code for ISO connections. --- .../include/controller/ble_ll_iso.h | 9 +- .../include/controller/ble_ll_isoal.h | 8 -- nimble/controller/src/ble_ll_hci.c | 6 +- nimble/controller/src/ble_ll_iso.c | 116 ++++++++++++++++++ nimble/controller/src/ble_ll_isoal.c | 93 +------------- 5 files changed, 130 insertions(+), 102 deletions(-) create mode 100644 nimble/controller/src/ble_ll_iso.c diff --git a/nimble/controller/include/controller/ble_ll_iso.h b/nimble/controller/include/controller/ble_ll_iso.h index 2944b07476..fb20a4f34b 100644 --- a/nimble/controller/include/controller/ble_ll_iso.h +++ b/nimble/controller/include/controller/ble_ll_iso.h @@ -26,7 +26,8 @@ extern "C" { #endif -int ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t len); +/* HCI command handlers */ +int ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); int ble_ll_iso_set_cig_param(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); int ble_ll_iso_set_cig_param_test(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); int ble_ll_iso_create_cis(const uint8_t *cmdbuf, uint8_t len); @@ -39,13 +40,15 @@ int ble_ll_iso_create_big_test(const uint8_t *cmdbuf, uint8_t len); int ble_ll_iso_terminate_big(const uint8_t *cmdbuf, uint8_t len); int ble_ll_iso_big_create_sync(const uint8_t *cmdbuf, uint8_t len); int ble_ll_iso_big_terminate_sync(const uint8_t *cmdbuf, uint8_t len); -int ble_ll_iso_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t len); -int ble_ll_iso_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t len); +int ble_ll_iso_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); +int ble_ll_iso_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); int ble_ll_iso_transmit_test(const uint8_t *cmdbuf, uint8_t len); int ble_ll_iso_receive_test(const uint8_t *cmdbuf, uint8_t len); int ble_ll_iso_read_counters_test(const uint8_t *cmdbuf, uint8_t len); int ble_ll_iso_end_test(const uint8_t *cmdbuf, uint8_t len); +struct ble_ll_isoal_mux *ble_ll_iso_find_mux_by_handle(uint16_t conn_handle); + #ifdef __cplusplus } #endif diff --git a/nimble/controller/include/controller/ble_ll_isoal.h b/nimble/controller/include/controller/ble_ll_isoal.h index caf15e2d59..3bb7075bc0 100644 --- a/nimble/controller/include/controller/ble_ll_isoal.h +++ b/nimble/controller/include/controller/ble_ll_isoal.h @@ -70,14 +70,6 @@ int ble_ll_isoal_mux_unframed_get(struct ble_ll_isoal_mux *mux, uint8_t idx, uint8_t *llid, void *dptr); -/* HCI command handlers */ -int ble_ll_isoal_hci_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen, - uint8_t *rspbuf, uint8_t *rsplen); -int ble_ll_isoal_hci_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen, - uint8_t *rspbuf, uint8_t *rsplen); -int ble_ll_isoal_hci_read_tx_sync(const uint8_t *cmdbuf, uint8_t cmdlen, - uint8_t *rspbuf, uint8_t *rsplen); - void ble_ll_isoal_init(void); void ble_ll_isoal_reset(void); int ble_ll_isoal_data_in(struct os_mbuf *om); diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index 93fac9d604..e8250284e2 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1287,13 +1287,13 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, #endif /* BLE_LL_ISO_BROADCASTER */ #if MYNEWT_VAL(BLE_LL_ISO) case BLE_HCI_OCF_LE_SETUP_ISO_DATA_PATH: - rc = ble_ll_isoal_hci_setup_iso_data_path(cmdbuf, len, rspbuf, rsplen); + rc = ble_ll_iso_setup_iso_data_path(cmdbuf, len, rspbuf, rsplen); break; case BLE_HCI_OCF_LE_REMOVE_ISO_DATA_PATH: - rc = ble_ll_isoal_hci_remove_iso_data_path(cmdbuf, len, rspbuf, rsplen); + rc = ble_ll_iso_remove_iso_data_path(cmdbuf, len, rspbuf, rsplen); break; case BLE_HCI_OCF_LE_READ_ISO_TX_SYNC: - rc = ble_ll_isoal_hci_read_tx_sync(cmdbuf, len, rspbuf, rsplen); + rc = ble_ll_iso_read_tx_sync(cmdbuf, len, rspbuf, rsplen); break; case BLE_HCI_OCF_LE_RD_BUF_SIZE_V2: if (len == 0) { diff --git a/nimble/controller/src/ble_ll_iso.c b/nimble/controller/src/ble_ll_iso.c new file mode 100644 index 0000000000..46e25ee52c --- /dev/null +++ b/nimble/controller/src/ble_ll_iso.c @@ -0,0 +1,116 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +#if MYNEWT_VAL(BLE_LL_ISO) + +int +ble_ll_iso_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_le_setup_iso_data_path_cp *cmd = (const void *)cmdbuf; + struct ble_hci_le_setup_iso_data_path_rp *rsp = (void *)rspbuf; + struct ble_ll_iso_bis *bis; + uint16_t conn_handle; + + conn_handle = le16toh(cmd->conn_handle); + switch (BLE_LL_CONN_HANDLE_TYPE(conn_handle)) { + case BLE_LL_CONN_HANDLE_TYPE_BIS: + bis = ble_ll_iso_big_find_bis_by_handle(conn_handle); + if (bis) { + break; + } + default: + return BLE_ERR_UNK_CONN_ID; + } + + /* Only input for now since we only support BIS */ + if (cmd->data_path_dir) { + return BLE_ERR_CMD_DISALLOWED; + } + + /* We do not (yet) support any vendor-specific data path */ + if (cmd->data_path_id) { + return BLE_ERR_CMD_DISALLOWED; + } + + rsp->conn_handle = cmd->conn_handle; + *rsplen = sizeof(*rsp); + + return 0; +} + +int +ble_ll_iso_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_le_remove_iso_data_path_cp *cmd = (const void *)cmdbuf; + struct ble_hci_le_remove_iso_data_path_rp *rsp = (void *)rspbuf; + + /* XXX accepts anything for now */ + rsp->conn_handle = cmd->conn_handle; + *rsplen = sizeof(*rsp); + + return 0; +} + +int +ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t cmdlen, + uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_le_read_iso_tx_sync_cp *cmd = (const void *)cmdbuf; + struct ble_hci_le_read_iso_tx_sync_rp *rsp = (void *)rspbuf; + struct ble_ll_isoal_mux *mux; + uint16_t handle; + + handle = le16toh(cmd->conn_handle); + mux = ble_ll_iso_find_mux_by_handle(handle); + if (!mux) { + return BLE_ERR_UNK_CONN_ID; + } + + rsp->conn_handle = cmd->conn_handle; + rsp->packet_seq_num = htole16(mux->last_tx_packet_seq_num); + rsp->tx_timestamp = htole32(mux->last_tx_timestamp); + put_le24(rsp->time_offset, 0); + + *rsplen = sizeof(*rsp); + + return 0; +} + +struct ble_ll_isoal_mux * +ble_ll_iso_find_mux_by_handle(uint16_t conn_handle) +{ + switch (BLE_LL_CONN_HANDLE_TYPE(conn_handle)) { + case BLE_LL_CONN_HANDLE_TYPE_BIS: + return ble_ll_iso_big_find_mux_by_handle(conn_handle); + default: + return NULL; + } +} + +#endif /* BLE_LL_ISO */ diff --git a/nimble/controller/src/ble_ll_isoal.c b/nimble/controller/src/ble_ll_isoal.c index d23382c966..8e7bfa4d0d 100644 --- a/nimble/controller/src/ble_ll_isoal.c +++ b/nimble/controller/src/ble_ll_isoal.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #ifndef min #define min(a, b) ((a) < (b) ? (a) : (b)) @@ -309,97 +309,14 @@ ble_ll_isoal_tx_pkt_in(struct ble_npl_event *ev) continue; } - switch (BLE_LL_CONN_HANDLE_TYPE(conn_handle)) { - case BLE_LL_CONN_HANDLE_TYPE_BIS: - mux = ble_ll_iso_big_find_mux_by_handle(conn_handle); - ble_ll_isoal_mux_tx_pkt_in(mux, om, pb_flag, timestamp); - break; - default: + mux = ble_ll_iso_find_mux_by_handle(conn_handle); + if (!mux) { os_mbuf_free_chain(om); - break; - } - } -} - -int -ble_ll_isoal_hci_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen, - uint8_t *rspbuf, uint8_t *rsplen) -{ - const struct ble_hci_le_setup_iso_data_path_cp *cmd = (const void *)cmdbuf; - struct ble_hci_le_setup_iso_data_path_rp *rsp = (void *)rspbuf; - struct ble_ll_iso_bis *bis; - uint16_t conn_handle; - - conn_handle = le16toh(cmd->conn_handle); - switch (BLE_LL_CONN_HANDLE_TYPE(conn_handle)) { - case BLE_LL_CONN_HANDLE_TYPE_BIS: - bis = ble_ll_iso_big_find_bis_by_handle(conn_handle); - if (bis) { - break; + continue; } - default: - return BLE_ERR_UNK_CONN_ID; - } - - /* Only input for now since we only support BIS */ - if (cmd->data_path_dir) { - return BLE_ERR_CMD_DISALLOWED; - } - - /* We do not (yet) support any vendor-specific data path */ - if (cmd->data_path_id) { - return BLE_ERR_CMD_DISALLOWED; - } - - rsp->conn_handle = cmd->conn_handle; - *rsplen = sizeof(*rsp); - - return 0; -} -int -ble_ll_isoal_hci_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen, - uint8_t *rspbuf, uint8_t *rsplen) -{ - const struct ble_hci_le_remove_iso_data_path_cp *cmd = (const void *)cmdbuf; - struct ble_hci_le_remove_iso_data_path_rp *rsp = (void *)rspbuf; - - /* XXX accepts anything for now */ - rsp->conn_handle = cmd->conn_handle; - *rsplen = sizeof(*rsp); - - return 0; -} - -int -ble_ll_isoal_hci_read_tx_sync(const uint8_t *cmdbuf, uint8_t cmdlen, - uint8_t *rspbuf, uint8_t *rsplen) -{ - const struct ble_hci_le_read_iso_tx_sync_cp *cmd = (const void *)cmdbuf; - struct ble_hci_le_read_iso_tx_sync_rp *rsp = (void *)rspbuf; - struct ble_ll_isoal_mux *mux; - uint16_t handle; - - handle = le16toh(cmd->conn_handle); - switch (BLE_LL_CONN_HANDLE_TYPE(handle)) { - case BLE_LL_CONN_HANDLE_TYPE_BIS: - mux = ble_ll_iso_big_find_mux_by_handle(handle); - if (!mux) { - return BLE_ERR_UNK_CONN_ID; - } - break; - default: - return BLE_ERR_UNK_CONN_ID; + ble_ll_isoal_mux_tx_pkt_in(mux, om, pb_flag, timestamp); } - - rsp->conn_handle = cmd->conn_handle; - rsp->packet_seq_num = htole16(mux->last_tx_packet_seq_num); - rsp->tx_timestamp = htole32(mux->last_tx_timestamp); - put_le24(rsp->time_offset, 0); - - *rsplen = sizeof(*rsp); - - return 0; } void From a9ac9116c338a3541bae4e5a62c097ec0745d88e Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 17 Dec 2024 11:24:11 +0100 Subject: [PATCH 1223/1333] nimble/ll: Remove unused function This removes unused ble_ll_iso_big_last_tx_timestamp_get function. --- .../include/controller/ble_ll_iso_big.h | 3 --- nimble/controller/src/ble_ll_iso_big.c | 15 --------------- 2 files changed, 18 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_iso_big.h b/nimble/controller/include/controller/ble_ll_iso_big.h index 30cf1b46af..47d33bd3b3 100644 --- a/nimble/controller/include/controller/ble_ll_iso_big.h +++ b/nimble/controller/include/controller/ble_ll_iso_big.h @@ -35,9 +35,6 @@ int ble_ll_iso_big_biginfo_len(struct ble_ll_iso_big *big); struct ble_ll_iso_bis *ble_ll_iso_big_find_bis_by_handle(uint16_t conn_handle); struct ble_ll_isoal_mux *ble_ll_iso_big_find_mux_by_handle(uint16_t conn_handle); -int ble_ll_iso_big_last_tx_timestamp_get(struct ble_ll_iso_bis *bis, - uint16_t *packet_seq_num, - uint32_t *timestamp); void ble_ll_iso_big_chan_map_update(void); diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 492bf23765..8976c5e267 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -240,21 +240,6 @@ ble_ll_iso_big_find_mux_by_handle(uint16_t conn_handle) return NULL; } -int -ble_ll_iso_big_last_tx_timestamp_get(struct ble_ll_iso_bis *bis, - uint16_t *packet_seq_num, uint32_t *timestamp) -{ - struct ble_ll_iso_big *big; - - big = bis->big; - - *packet_seq_num = big->bis_counter; - *timestamp = (uint64_t)big->event_start * 1000000 / 32768 + - big->event_start_us; - - return 0; -} - static void ble_ll_iso_big_biginfo_chanmap_update(struct ble_ll_iso_big *big) { From 03f4d1645adf1ad13041ec4b650ed207a45b2edd Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Tue, 7 Jan 2025 11:30:09 +0100 Subject: [PATCH 1224/1333] nimble/ll/isoal: Add initial framed PDU ISOAL support This adds framed PDU ISOAL support --- .../include/controller/ble_ll_iso.h | 35 +- .../include/controller/ble_ll_iso_big.h | 3 - .../include/controller/ble_ll_isoal.h | 43 +- nimble/controller/src/ble_ll.c | 11 +- nimble/controller/src/ble_ll_hci.c | 2 +- nimble/controller/src/ble_ll_iso.c | 194 +++- nimble/controller/src/ble_ll_iso_big.c | 103 +- nimble/controller/src/ble_ll_isoal.c | 375 ++++--- nimble/controller/test/src/ble_ll_isoal.c | 966 ++++++++++++++++++ nimble/controller/test/src/ble_ll_test.c | 2 + nimble/controller/test/syscfg.yml | 4 + nimble/include/nimble/ble.h | 2 + nimble/include/nimble/hci_common.h | 4 + 13 files changed, 1501 insertions(+), 243 deletions(-) create mode 100644 nimble/controller/test/src/ble_ll_isoal.c diff --git a/nimble/controller/include/controller/ble_ll_iso.h b/nimble/controller/include/controller/ble_ll_iso.h index fb20a4f34b..768dd9923e 100644 --- a/nimble/controller/include/controller/ble_ll_iso.h +++ b/nimble/controller/include/controller/ble_ll_iso.h @@ -21,11 +21,28 @@ #define H_BLE_LL_ISO #include +#include #ifdef __cplusplus extern "C" { #endif +struct ble_ll_iso_conn { + /* Connection handle */ + uint16_t handle; + + /* ISOAL Multiplexer */ + struct ble_ll_isoal_mux mux; + + /* HCI SDU Fragment */ + struct os_mbuf *frag; + + /* Number of Completed Packets */ + uint16_t num_completed_pkt; + + STAILQ_ENTRY(ble_ll_iso_conn) iso_conn_q_next; +}; + /* HCI command handlers */ int ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); int ble_ll_iso_set_cig_param(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); @@ -47,7 +64,23 @@ int ble_ll_iso_receive_test(const uint8_t *cmdbuf, uint8_t len); int ble_ll_iso_read_counters_test(const uint8_t *cmdbuf, uint8_t len); int ble_ll_iso_end_test(const uint8_t *cmdbuf, uint8_t len); -struct ble_ll_isoal_mux *ble_ll_iso_find_mux_by_handle(uint16_t conn_handle); +void ble_ll_iso_init(void); +void ble_ll_iso_reset(void); + +/* ISO Data handler */ +int ble_ll_iso_data_in(struct os_mbuf *om); + +int ble_ll_iso_pdu_get(struct ble_ll_iso_conn *conn, uint8_t idx, uint8_t *llid, void *dptr); + +void ble_ll_iso_conn_init(struct ble_ll_iso_conn *conn, uint16_t conn_handle, + uint8_t max_pdu, uint32_t iso_interval_us, + uint32_t sdu_interval_us, uint8_t bn, uint8_t pte, uint8_t framing); +void ble_ll_iso_conn_free(struct ble_ll_iso_conn *conn); + +int ble_ll_iso_conn_event_start(struct ble_ll_iso_conn *conn, uint32_t timestamp); +int ble_ll_iso_conn_event_done(struct ble_ll_iso_conn *conn); + +struct ble_ll_iso_conn *ble_ll_iso_conn_find_by_handle(uint16_t conn_handle); #ifdef __cplusplus } diff --git a/nimble/controller/include/controller/ble_ll_iso_big.h b/nimble/controller/include/controller/ble_ll_iso_big.h index 47d33bd3b3..8576fc5494 100644 --- a/nimble/controller/include/controller/ble_ll_iso_big.h +++ b/nimble/controller/include/controller/ble_ll_iso_big.h @@ -33,9 +33,6 @@ int ble_ll_iso_big_biginfo_copy(struct ble_ll_iso_big *big, uint8_t *dptr, uint32_t base_ticks, uint8_t base_rem_us); int ble_ll_iso_big_biginfo_len(struct ble_ll_iso_big *big); -struct ble_ll_iso_bis *ble_ll_iso_big_find_bis_by_handle(uint16_t conn_handle); -struct ble_ll_isoal_mux *ble_ll_iso_big_find_mux_by_handle(uint16_t conn_handle); - void ble_ll_iso_big_chan_map_update(void); void ble_ll_iso_big_halt(void); diff --git a/nimble/controller/include/controller/ble_ll_isoal.h b/nimble/controller/include/controller/ble_ll_isoal.h index 3bb7075bc0..a590a0f6e7 100644 --- a/nimble/controller/include/controller/ble_ll_isoal.h +++ b/nimble/controller/include/controller/ble_ll_isoal.h @@ -20,14 +20,13 @@ #ifndef H_BLE_LL_ISOAL_ #define H_BLE_LL_ISOAL_ +#include #include #ifdef __cplusplus extern "C" { #endif -#if MYNEWT_VAL(BLE_LL_ISO) - struct ble_ll_isoal_mux { #if MYNEWT_VAL(BLE_LL_ISOAL_MUX_PREFILL) uint8_t active; @@ -44,37 +43,53 @@ struct ble_ll_isoal_mux { /* Number of SDUs available for current event */ uint8_t sdu_in_event; + /* Burst Number */ + uint8_t bn; + STAILQ_HEAD(, os_mbuf_pkthdr) sdu_q; uint16_t sdu_q_len; - struct os_mbuf *frag; - uint32_t sdu_counter; uint32_t event_tx_timestamp; uint32_t last_tx_timestamp; uint16_t last_tx_packet_seq_num; + + /* The head SDU Segment is the Continuation of an SDU */ + uint8_t sc : 1; + uint8_t framed : 1; + uint8_t framing_mode : 1; }; -void -ble_ll_isoal_mux_init(struct ble_ll_isoal_mux *mux, uint8_t max_pdu, - uint32_t iso_interval_us, uint32_t sdu_interval_us, - uint8_t bn, uint8_t pte); +#define BLE_LL_ISOAL_SEGHDR(sc, cmplt, len) \ + ((uint16_t)((sc) & 0x01) | (((cmplt) & 0x01) << 1) | ((len) & 0xff) << 8) + +#define BLE_LL_ISOAL_SEGHDR_SC(word) ((word) & 0x01) +#define BLE_LL_ISOAL_SEGHDR_CMPLT(word) ((word >> 1) & 0x01) +#define BLE_LL_ISOAL_SEGHDR_LEN(word) ((word >> 8) & 0xff) + +#define BLE_LL_ISOAL_MUX_IS_FRAMED(framing) \ + ((framing) == BLE_HCI_ISO_FRAMING_FRAMED_SEGMENTABLE || \ + (framing) == BLE_HCI_ISO_FRAMING_FRAMED_UNSEGMENTED) + +void ble_ll_isoal_mux_init(struct ble_ll_isoal_mux *mux, uint8_t max_pdu, + uint32_t iso_interval_us, uint32_t sdu_interval_us, + uint8_t bn, uint8_t pte, bool framed, + uint8_t framing_mode); void ble_ll_isoal_mux_free(struct ble_ll_isoal_mux *mux); int ble_ll_isoal_mux_event_start(struct ble_ll_isoal_mux *mux, uint32_t timestamp); int ble_ll_isoal_mux_event_done(struct ble_ll_isoal_mux *mux); -int -ble_ll_isoal_mux_unframed_get(struct ble_ll_isoal_mux *mux, uint8_t idx, - uint8_t *llid, void *dptr); +int ble_ll_isoal_mux_pdu_get(struct ble_ll_isoal_mux *mux, uint8_t idx, + uint8_t *llid, void *dptr); + +void ble_ll_isoal_mux_sdu_enqueue(struct ble_ll_isoal_mux *mux, + struct os_mbuf *om); void ble_ll_isoal_init(void); void ble_ll_isoal_reset(void); -int ble_ll_isoal_data_in(struct os_mbuf *om); - -#endif /* BLE_LL_ISO */ #ifdef __cplusplus } diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 238bfad1d3..cc11a93b46 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -47,7 +47,7 @@ #include "controller/ble_ll_sync.h" #include "controller/ble_fem.h" #if MYNEWT_VAL(BLE_LL_ISO) -#include "controller/ble_ll_isoal.h" +#include "controller/ble_ll_iso.h" #endif #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) #include "controller/ble_ll_iso_big.h" @@ -1685,13 +1685,14 @@ ble_ll_reset(void) ble_fem_lna_init(); #endif -#if MYNEWT_VAL(BLE_LL_ISO) - ble_ll_isoal_reset(); -#endif #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) ble_ll_iso_big_reset(); #endif +#if MYNEWT_VAL(BLE_LL_ISO) + ble_ll_iso_reset(); +#endif + /* Re-initialize the PHY */ rc = ble_phy_init(); @@ -1968,7 +1969,7 @@ ble_ll_init(void) #endif #if MYNEWT_VAL(BLE_LL_ISO) - ble_ll_isoal_init(); + ble_ll_iso_init(); #endif #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) ble_ll_iso_big_init(); diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index e8250284e2..e969963ae0 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1995,7 +1995,7 @@ int ble_ll_hci_iso_rx(struct os_mbuf *om) { #if MYNEWT_VAL(BLE_LL_ISO) - ble_ll_isoal_data_in(om); + ble_ll_iso_data_in(om); #else os_mbuf_free_chain(om); #endif diff --git a/nimble/controller/src/ble_ll_iso.c b/nimble/controller/src/ble_ll_iso.c index 46e25ee52c..034996d5ff 100644 --- a/nimble/controller/src/ble_ll_iso.c +++ b/nimble/controller/src/ble_ll_iso.c @@ -23,27 +23,26 @@ #include #include #include -#include +#include #if MYNEWT_VAL(BLE_LL_ISO) +STAILQ_HEAD(ble_ll_iso_conn_q, ble_ll_iso_conn); +struct ble_ll_iso_conn_q ll_iso_conn_q; + int ble_ll_iso_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen) { const struct ble_hci_le_setup_iso_data_path_cp *cmd = (const void *)cmdbuf; struct ble_hci_le_setup_iso_data_path_rp *rsp = (void *)rspbuf; - struct ble_ll_iso_bis *bis; + struct ble_ll_iso_conn *conn; uint16_t conn_handle; conn_handle = le16toh(cmd->conn_handle); - switch (BLE_LL_CONN_HANDLE_TYPE(conn_handle)) { - case BLE_LL_CONN_HANDLE_TYPE_BIS: - bis = ble_ll_iso_big_find_bis_by_handle(conn_handle); - if (bis) { - break; - } - default: + + conn = ble_ll_iso_conn_find_by_handle(conn_handle); + if (!conn) { return BLE_ERR_UNK_CONN_ID; } @@ -83,18 +82,18 @@ ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t cmdlen, { const struct ble_hci_le_read_iso_tx_sync_cp *cmd = (const void *)cmdbuf; struct ble_hci_le_read_iso_tx_sync_rp *rsp = (void *)rspbuf; - struct ble_ll_isoal_mux *mux; + struct ble_ll_iso_conn *iso_conn; uint16_t handle; handle = le16toh(cmd->conn_handle); - mux = ble_ll_iso_find_mux_by_handle(handle); - if (!mux) { + iso_conn = ble_ll_iso_conn_find_by_handle(handle); + if (!iso_conn) { return BLE_ERR_UNK_CONN_ID; } rsp->conn_handle = cmd->conn_handle; - rsp->packet_seq_num = htole16(mux->last_tx_packet_seq_num); - rsp->tx_timestamp = htole32(mux->last_tx_timestamp); + rsp->packet_seq_num = htole16(iso_conn->mux.last_tx_packet_seq_num); + rsp->tx_timestamp = htole32(iso_conn->mux.last_tx_timestamp); put_le24(rsp->time_offset, 0); *rsplen = sizeof(*rsp); @@ -102,15 +101,170 @@ ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t cmdlen, return 0; } -struct ble_ll_isoal_mux * -ble_ll_iso_find_mux_by_handle(uint16_t conn_handle) +struct ble_ll_iso_conn * +ble_ll_iso_conn_find_by_handle(uint16_t conn_handle) +{ + struct ble_ll_iso_conn *conn; + + STAILQ_FOREACH(conn, &ll_iso_conn_q, iso_conn_q_next) { + if (conn_handle == conn->handle) { + return conn; + } + } + + return NULL; +} + +void +ble_ll_iso_init(void) +{ + STAILQ_INIT(&ll_iso_conn_q); + ble_ll_isoal_init(); +} + +void +ble_ll_iso_reset(void) +{ + STAILQ_INIT(&ll_iso_conn_q); + ble_ll_isoal_reset(); +} + +int +ble_ll_iso_data_in(struct os_mbuf *om) { - switch (BLE_LL_CONN_HANDLE_TYPE(conn_handle)) { - case BLE_LL_CONN_HANDLE_TYPE_BIS: - return ble_ll_iso_big_find_mux_by_handle(conn_handle); + struct ble_hci_iso *hci_iso; + struct ble_hci_iso_data *hci_iso_data; + struct ble_ll_iso_conn *conn; + struct ble_mbuf_hdr *blehdr; + uint16_t data_hdr_len; + uint16_t handle; + uint16_t conn_handle; + uint16_t length; + uint16_t pb_flag; + uint16_t ts_flag; + uint32_t timestamp = 0; + + hci_iso = (void *)om->om_data; + + handle = le16toh(hci_iso->handle); + conn_handle = BLE_HCI_ISO_CONN_HANDLE(handle); + pb_flag = BLE_HCI_ISO_PB_FLAG(handle); + ts_flag = BLE_HCI_ISO_TS_FLAG(handle); + length = BLE_HCI_ISO_LENGTH(le16toh(hci_iso->length)); + + conn = ble_ll_iso_conn_find_by_handle(conn_handle); + if (!conn) { + os_mbuf_free_chain(om); + return BLE_ERR_UNK_CONN_ID; + } + + data_hdr_len = 0; + if ((pb_flag == BLE_HCI_ISO_PB_FIRST) || + (pb_flag == BLE_HCI_ISO_PB_COMPLETE)) { + blehdr = BLE_MBUF_HDR_PTR(om); + blehdr->txiso.packet_seq_num = ++conn->mux.sdu_counter; + blehdr->txiso.cpu_timestamp = ble_ll_tmr_get(); + + if (ts_flag) { + timestamp = get_le32(om->om_data + sizeof(*hci_iso)); + data_hdr_len += sizeof(uint32_t); + } + blehdr->txiso.hci_timestamp = timestamp; + + hci_iso_data = (void *)(om->om_data + sizeof(*hci_iso) + data_hdr_len); + data_hdr_len += sizeof(*hci_iso_data); + } + os_mbuf_adj(om, sizeof(*hci_iso) + data_hdr_len); + + if (OS_MBUF_PKTLEN(om) != length - data_hdr_len) { + os_mbuf_free_chain(om); + return BLE_ERR_MEM_CAPACITY; + } + + switch (pb_flag) { + case BLE_HCI_ISO_PB_FIRST: + BLE_LL_ASSERT(!conn->frag); + conn->frag = om; + om = NULL; + break; + case BLE_HCI_ISO_PB_CONTINUATION: + BLE_LL_ASSERT(conn->frag); + os_mbuf_concat(conn->frag, om); + om = NULL; + break; + case BLE_HCI_ISO_PB_COMPLETE: + BLE_LL_ASSERT(!conn->frag); + break; + case BLE_HCI_ISO_PB_LAST: + BLE_LL_ASSERT(conn->frag); + os_mbuf_concat(conn->frag, om); + om = conn->frag; + conn->frag = NULL; + break; default: - return NULL; + BLE_LL_ASSERT(0); + break; + } + + if (om) { + ble_ll_isoal_mux_sdu_enqueue(&conn->mux, om); } + + return 0; +} + +int +ble_ll_iso_pdu_get(struct ble_ll_iso_conn *conn, uint8_t idx, uint8_t *llid, void *dptr) +{ + return ble_ll_isoal_mux_pdu_get(&conn->mux, idx, llid, dptr); +} + +void +ble_ll_iso_conn_init(struct ble_ll_iso_conn *conn, uint16_t conn_handle, + uint8_t max_pdu, uint32_t iso_interval_us, + uint32_t sdu_interval_us, uint8_t bn, uint8_t pte, + uint8_t framing) +{ + os_sr_t sr; + + memset(conn, 0, sizeof(*conn)); + + conn->handle = conn_handle; + ble_ll_isoal_mux_init(&conn->mux, max_pdu, iso_interval_us, sdu_interval_us, + bn, pte, BLE_LL_ISOAL_MUX_IS_FRAMED(framing), + framing == BLE_HCI_ISO_FRAMING_FRAMED_UNSEGMENTED); + + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&ll_iso_conn_q, conn, iso_conn_q_next); + OS_EXIT_CRITICAL(sr); +} + +void +ble_ll_iso_conn_free(struct ble_ll_iso_conn *conn) +{ + os_sr_t sr; + + OS_ENTER_CRITICAL(sr); + STAILQ_REMOVE(&ll_iso_conn_q, conn, ble_ll_iso_conn, iso_conn_q_next); + OS_EXIT_CRITICAL(sr); + + ble_ll_isoal_mux_free(&conn->mux); +} + +int +ble_ll_iso_conn_event_start(struct ble_ll_iso_conn *conn, uint32_t timestamp) +{ + ble_ll_isoal_mux_event_start(&conn->mux, timestamp); + + return 0; +} + +int +ble_ll_iso_conn_event_done(struct ble_ll_iso_conn *conn) +{ + conn->num_completed_pkt += ble_ll_isoal_mux_event_done(&conn->mux); + + return conn->num_completed_pkt; } #endif /* BLE_LL_ISO */ diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 8976c5e267..2a5e60de33 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -53,7 +53,6 @@ struct ble_ll_iso_big; struct ble_ll_iso_bis { struct ble_ll_iso_big *big; uint8_t num; - uint16_t conn_handle; uint32_t aa; uint32_t crc_init; @@ -69,8 +68,7 @@ struct ble_ll_iso_bis { uint8_t g; } tx; - struct ble_ll_isoal_mux mux; - uint16_t num_completed_pkt; + struct ble_ll_iso_conn conn; STAILQ_ENTRY(ble_ll_iso_bis) bis_q_next; }; @@ -88,8 +86,8 @@ struct big_params { uint16_t max_sdu; uint8_t max_pdu; uint8_t phy; + uint8_t framing; uint8_t interleaved : 1; - uint8_t framed : 1; uint8_t encrypted : 1; uint8_t broadcast_code[16]; }; @@ -112,6 +110,7 @@ struct ble_ll_iso_big { uint8_t nse; /* 1-31 */ uint8_t interleaved : 1; uint8_t framed : 1; + uint8_t framing_mode : 1; uint8_t encrypted : 1; uint8_t giv[8]; uint8_t gskd[16]; @@ -203,43 +202,6 @@ big_sched_set(struct ble_ll_iso_big *big) } } -struct ble_ll_iso_bis * -ble_ll_iso_big_find_bis_by_handle(uint16_t conn_handle) -{ - struct ble_ll_iso_bis *bis; - uint8_t bis_idx; - - if (!BLE_LL_CONN_HANDLE_IS_BIS(conn_handle)) { - return NULL; - } - - bis_idx = BLE_LL_CONN_HANDLE_IDX(conn_handle); - - if (bis_idx >= BIS_POOL_SIZE) { - return NULL; - } - - bis = &bis_pool[bis_idx]; - if (!bis->big) { - return NULL; - } - - return bis; -} - -struct ble_ll_isoal_mux * -ble_ll_iso_big_find_mux_by_handle(uint16_t conn_handle) -{ - struct ble_ll_iso_bis *bis; - - bis = ble_ll_iso_big_find_bis_by_handle(conn_handle); - if (bis) { - return &bis->mux; - } - - return NULL; -} - static void ble_ll_iso_big_biginfo_chanmap_update(struct ble_ll_iso_big *big) { @@ -275,8 +237,8 @@ ble_ll_iso_big_biginfo_calc(struct ble_ll_iso_big *big, uint32_t seed_aa) put_le24(buf, (big->irc << 20) | (big->bis_spacing)); buf += 3; - /* max_pdu, rfu */ - put_le16(buf, big->max_pdu); + /* max_pdu, rfu, framing_mode */ + put_le16(buf, big->max_pdu | (big->framing_mode) << 15); buf += 2; /* seed_access_address */ @@ -296,7 +258,8 @@ ble_ll_iso_big_biginfo_calc(struct ble_ll_iso_big *big, uint32_t seed_aa) buf += 5; /* bis_payload_cnt, framing */ - memset(buf, 0x00, 5); + memset(buf, 0x01, 5); + buf[4] |= (big->framed << 7) & 0x80; } int @@ -357,7 +320,7 @@ ble_ll_iso_big_biginfo_copy(struct ble_ll_iso_big *big, uint8_t *dptr, *dptr++ = (counter >> 8) & 0xff; *dptr++ = (counter >> 16) & 0xff; *dptr++ = (counter >> 24) & 0xff; - *dptr++ = (counter >> 32) & 0xff; + *dptr++ = ((counter >> 32) & 0x7f) | ((big->framed << 7) & 0x80); if (big->encrypted) { memcpy(dptr, big->giv, 8); @@ -390,7 +353,7 @@ ble_ll_iso_big_free(struct ble_ll_iso_big *big) ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &big->event_done); STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) { - ble_ll_isoal_mux_free(&bis->mux); + ble_ll_iso_conn_free(&bis->conn); bis->big = NULL; bis_pool_free++; } @@ -503,15 +466,12 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) #endif STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) { - num_completed_pkt = ble_ll_isoal_mux_event_done(&bis->mux); + num_completed_pkt = ble_ll_iso_conn_event_done(&bis->conn); if (hci_ev && num_completed_pkt) { idx = hci_ev_ncp->count++; - hci_ev_ncp->completed[idx].handle = htole16(bis->conn_handle); - hci_ev_ncp->completed[idx].packets = htole16(num_completed_pkt + - bis->num_completed_pkt); - bis->num_completed_pkt = 0; - } else { - bis->num_completed_pkt += num_completed_pkt; + hci_ev_ncp->completed[idx].handle = htole16(bis->conn.handle); + hci_ev_ncp->completed[idx].packets = htole16(num_completed_pkt); + bis->conn.num_completed_pkt = 0; } #if MYNEWT_VAL(BLE_LL_ISO_HCI_FEEDBACK_INTERVAL_MS) @@ -523,7 +483,7 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big) */ exp = bis->mux.sdu_per_event - bis->mux.sdu_per_interval; idx = fb_hci_subev->count++; - fb_hci_subev->feedback[idx].handle = htole16(bis->conn_handle); + fb_hci_subev->feedback[idx].handle = htole16(bis->conn.handle); fb_hci_subev->feedback[idx].sdu_per_interval = bis->mux.sdu_per_interval; fb_hci_subev->feedback[idx].diff = (int8_t)(bis->mux.sdu_q_len - exp); } @@ -723,7 +683,7 @@ ble_ll_iso_big_subevent_pdu_cb(uint8_t *dptr, void *arg, uint8_t *hdr_byte) } #if 1 - pdu_len = ble_ll_isoal_mux_unframed_get(&bis->mux, idx, &llid, dptr); + pdu_len = ble_ll_iso_pdu_get(&bis->conn, idx, &llid, dptr); #else llid = 0; pdu_len = big->max_pdu; @@ -860,12 +820,10 @@ ble_ll_iso_big_event_sched_cb(struct ble_ll_sched_item *sch) ble_ll_tx_power_set(g_ble_ll_tx_power); - BLE_LL_ASSERT(!big->framed); - /* XXX calculate this in advance at the end of previous event? */ big->tx.subevents_rem = big->num_bis * big->nse; STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) { - ble_ll_isoal_mux_event_start(&bis->mux, (uint64_t)big->event_start * + ble_ll_iso_conn_event_start(&bis->conn, (uint64_t)big->event_start * 1000000 / 32768 + big->event_start_us); @@ -969,6 +927,7 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, struct ble_ll_iso_bis *bis; struct ble_ll_adv_sm *advsm; uint32_t seed_aa; + uint16_t conn_handle; uint8_t pte; uint8_t gc; uint8_t idx; @@ -1046,10 +1005,11 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, bis->num = big->num_bis; bis->crc_init = (big->crc_init << 8) | (big->num_bis); - BLE_LL_ASSERT(!big->framed); + conn_handle = BLE_LL_CONN_HANDLE(BLE_LL_CONN_HANDLE_TYPE_BIS, idx); - ble_ll_isoal_mux_init(&bis->mux, bp->max_pdu, bp->iso_interval * 1250, - bp->sdu_interval, bp->bn, pte); + ble_ll_iso_conn_init(&bis->conn, conn_handle, bp->max_pdu, + bp->iso_interval * 1250, bp->sdu_interval, + bp->bn, pte, bp->framing); } bis_pool_free -= num_bis; @@ -1059,7 +1019,8 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, big->irc = bp->irc; big->nse = bp->nse; big->interleaved = bp->interleaved; - big->framed = bp->framed; + big->framed = bp->framing != BLE_HCI_ISO_FRAMING_UNFRAMED; + big->framing_mode = bp->framing == BLE_HCI_ISO_FRAMING_FRAMED_UNSEGMENTED; big->encrypted = bp->encrypted; big->sdu_interval = bp->sdu_interval; big->iso_interval = bp->iso_interval; @@ -1288,7 +1249,7 @@ ble_ll_iso_big_hci_evt_complete(void) idx = 0; STAILQ_FOREACH(bis, &big->bis_q, bis_q_next) { - evt->conn_handle[idx] = htole16(bis->conn_handle); + evt->conn_handle[idx] = htole16(bis->conn.handle); idx++; } @@ -1314,7 +1275,7 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len) !IN_RANGE(le16toh(cmd->max_sdu), 0x0001, 0x0fff) || !IN_RANGE(le16toh(cmd->max_transport_latency), 0x0005, 0x0fa0) || !IN_RANGE(cmd->rtn, 0x00, 0x1e) || - (cmd->packing > 1) || (cmd->framing > 1) || (cmd->encryption) > 1) { + (cmd->packing > 1) || (cmd->framing > 2) || (cmd->encryption) > 1) { return BLE_ERR_INV_HCI_CMD_PARMS; } @@ -1341,7 +1302,7 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len) bp.phy = BLE_PHY_CODED; } bp.interleaved = cmd->packing; - bp.framed = cmd->framing; + bp.framing = cmd->framing; bp.encrypted = cmd->encryption; memcpy(bp.broadcast_code, cmd->broadcast_code, 16); @@ -1424,7 +1385,7 @@ ble_ll_iso_big_hci_create_test(const uint8_t *cmdbuf, uint8_t len) bp.phy = BLE_PHY_CODED; } bp.interleaved = cmd->packing; - bp.framed = cmd->framing; + bp.framing = cmd->framing; bp.encrypted = cmd->encryption; memcpy(bp.broadcast_code, cmd->broadcast_code, 16); @@ -1434,7 +1395,7 @@ ble_ll_iso_big_hci_create_test(const uint8_t *cmdbuf, uint8_t len) iso_interval_us = bp.iso_interval * 1250; - if (!bp.framed) { + if (bp.framing == BLE_HCI_ISO_FRAMING_UNFRAMED) { /* sdu_interval shall be an integer multiple of iso_interval */ if (iso_interval_us % bp.sdu_interval) { return BLE_ERR_INV_HCI_CMD_PARMS; @@ -1491,7 +1452,6 @@ void ble_ll_iso_big_init(void) { struct ble_ll_iso_big *big; - struct ble_ll_iso_bis *bis; uint8_t idx; memset(big_pool, 0, sizeof(big_pool)); @@ -1509,11 +1469,6 @@ ble_ll_iso_big_init(void) ble_npl_event_init(&big->event_done, ble_ll_iso_big_event_done_ev, big); } - for (idx = 0; idx < BIS_POOL_SIZE; idx++) { - bis = &bis_pool[idx]; - bis->conn_handle = BLE_LL_CONN_HANDLE(BLE_LL_CONN_HANDLE_TYPE_BIS, idx); - } - big_pool_free = ARRAY_SIZE(big_pool); bis_pool_free = ARRAY_SIZE(bis_pool); } diff --git a/nimble/controller/src/ble_ll_isoal.c b/nimble/controller/src/ble_ll_isoal.c index 8e7bfa4d0d..8c8516b6d3 100644 --- a/nimble/controller/src/ble_ll_isoal.c +++ b/nimble/controller/src/ble_ll_isoal.c @@ -19,10 +19,8 @@ #include #include -#include #include #include -#include #ifndef min #define min(a, b) ((a) < (b) ? (a) : (b)) @@ -30,27 +28,32 @@ #if MYNEWT_VAL(BLE_LL_ISO) -STAILQ_HEAD(ble_ll_iso_tx_q, os_mbuf_pkthdr); - -static struct ble_npl_event ll_isoal_tx_pkt_in; -static struct ble_ll_iso_tx_q ll_isoal_tx_q; - void ble_ll_isoal_mux_init(struct ble_ll_isoal_mux *mux, uint8_t max_pdu, uint32_t iso_interval_us, uint32_t sdu_interval_us, - uint8_t bn, uint8_t pte) + uint8_t bn, uint8_t pte, bool framed, uint8_t framing_mode) { memset(mux, 0, sizeof(*mux)); mux->max_pdu = max_pdu; /* Core 5.3, Vol 6, Part G, 2.1 */ mux->sdu_per_interval = iso_interval_us / sdu_interval_us; - mux->pdu_per_sdu = bn / mux->sdu_per_interval; + + if (framed) { + /* TODO */ + } else { + mux->pdu_per_sdu = bn / mux->sdu_per_interval; + } mux->sdu_per_event = (1 + pte) * mux->sdu_per_interval; + mux->bn = bn; + STAILQ_INIT(&mux->sdu_q); mux->sdu_q_len = 0; + + mux->framed = framed; + mux->framing_mode = framing_mode; } void @@ -77,54 +80,20 @@ ble_ll_isoal_mux_free(struct ble_ll_isoal_mux *mux) STAILQ_INIT(&mux->sdu_q); } -static void -ble_ll_isoal_mux_tx_pkt_in(struct ble_ll_isoal_mux *mux, struct os_mbuf *om, - uint8_t pb, uint32_t timestamp) +void +ble_ll_isoal_mux_sdu_enqueue(struct ble_ll_isoal_mux *mux, struct os_mbuf *om) { struct os_mbuf_pkthdr *pkthdr; - struct ble_mbuf_hdr *blehdr; os_sr_t sr; BLE_LL_ASSERT(mux); - switch (pb) { - case BLE_HCI_ISO_PB_FIRST: - BLE_LL_ASSERT(!mux->frag); - mux->frag = om; - om = NULL; - break; - case BLE_HCI_ISO_PB_CONTINUATION: - BLE_LL_ASSERT(mux->frag); - os_mbuf_concat(mux->frag, om); - om = NULL; - break; - case BLE_HCI_ISO_PB_COMPLETE: - BLE_LL_ASSERT(!mux->frag); - break; - case BLE_HCI_ISO_PB_LAST: - BLE_LL_ASSERT(mux->frag); - os_mbuf_concat(mux->frag, om); - om = mux->frag; - mux->frag = NULL; - break; - default: - BLE_LL_ASSERT(0); - break; - } - - if (!om) { - return; - } - - blehdr = BLE_MBUF_HDR_PTR(om); - blehdr->txiso.packet_seq_num = ++mux->sdu_counter; - OS_ENTER_CRITICAL(sr); pkthdr = OS_MBUF_PKTHDR(om); STAILQ_INSERT_TAIL(&mux->sdu_q, pkthdr, omp_next); mux->sdu_q_len++; #if MYNEWT_VAL(BLE_LL_ISOAL_MUX_PREFILL) - if (mux->sdu_q_len == mux->sdu_per_event) { + if (mux->sdu_q_len >= mux->sdu_per_event) { mux->active = 1; } #endif @@ -138,26 +107,32 @@ ble_ll_isoal_mux_event_start(struct ble_ll_isoal_mux *mux, uint32_t timestamp) /* If prefill is enabled, we always expect to have required number of SDUs * in queue, otherwise we disable mux until enough SDUs are queued again. */ - mux->sdu_in_event = mux->sdu_per_event; - if (mux->sdu_in_event > mux->sdu_q_len) { + if (mux->sdu_per_event > mux->sdu_q_len) { mux->active = 0; } - if (!mux->active) { + if (mux->active && mux->framed) { + mux->sdu_in_event = mux->sdu_q_len; + } else if (mux->active) { + mux->sdu_in_event = mux->sdu_per_event; + } else { mux->sdu_in_event = 0; } #else - mux->sdu_in_event = min(mux->sdu_q_len, mux->sdu_per_event); + if (mux->framed) { + mux->sdu_in_event = mux->sdu_q_len; + } else { + mux->sdu_in_event = min(mux->sdu_q_len, mux->sdu_per_event); + } #endif mux->event_tx_timestamp = timestamp; return mux->sdu_in_event; } -int -ble_ll_isoal_mux_event_done(struct ble_ll_isoal_mux *mux) +static int +ble_ll_isoal_mux_unframed_event_done(struct ble_ll_isoal_mux *mux) { struct os_mbuf_pkthdr *pkthdr; - struct ble_mbuf_hdr *blehdr; struct os_mbuf *om; struct os_mbuf *om_next; uint8_t num_sdu; @@ -166,14 +141,6 @@ ble_ll_isoal_mux_event_done(struct ble_ll_isoal_mux *mux) num_sdu = min(mux->sdu_in_event, mux->sdu_per_interval); - pkthdr = STAILQ_FIRST(&mux->sdu_q); - if (pkthdr) { - om = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); - blehdr = BLE_MBUF_HDR_PTR(om); - mux->last_tx_timestamp = mux->event_tx_timestamp; - mux->last_tx_packet_seq_num = blehdr->txiso.packet_seq_num; - } - #if MYNEWT_VAL(BLE_LL_ISO_HCI_DISCARD_THRESHOLD) /* Drop queued SDUs if number of queued SDUs exceeds defined threshold. * Threshold is defined as number of ISO events. If number of queued SDUs @@ -188,6 +155,7 @@ ble_ll_isoal_mux_event_done(struct ble_ll_isoal_mux *mux) } #endif + pkthdr = STAILQ_FIRST(&mux->sdu_q); while (pkthdr && num_sdu--) { OS_ENTER_CRITICAL(sr); STAILQ_REMOVE_HEAD(&mux->sdu_q, omp_next); @@ -211,7 +179,119 @@ ble_ll_isoal_mux_event_done(struct ble_ll_isoal_mux *mux) return pkt_freed; } +static int +ble_ll_isoal_mux_framed_event_done(struct ble_ll_isoal_mux *mux) +{ + struct os_mbuf_pkthdr *pkthdr; + struct os_mbuf *om; + struct os_mbuf *om_next; + uint8_t num_sdu; + uint8_t num_pdu; + uint8_t pdu_offset = 0; + uint8_t frag_len = 0; + uint8_t rem_len = 0; + uint8_t hdr_len = 0; + int pkt_freed = 0; + bool sc = mux->sc; + os_sr_t sr; + + num_sdu = mux->sdu_in_event; + if (num_sdu == 0) { + return 0; + } + + num_pdu = mux->bn; + +#if MYNEWT_VAL(BLE_LL_ISO_HCI_DISCARD_THRESHOLD) + /* Drop queued SDUs if number of queued SDUs exceeds defined threshold. + * Threshold is defined as number of ISO events. If number of queued SDUs + * exceeds number of SDUs required for single event (i.e. including pt) + * and number of subsequent ISO events defined by threshold value, we'll + * drop any excessive SDUs and notify host as if they were sent. + */ + uint32_t thr = MYNEWT_VAL(BLE_LL_ISO_HCI_DISCARD_THRESHOLD); + if (mux->sdu_q_len > mux->sdu_per_event + thr * mux->sdu_per_interval) { + num_sdu = mux->sdu_q_len - mux->sdu_per_event - + thr * mux->sdu_per_interval; + } +#endif + + /* Drop num_pdu PDUs */ + pkthdr = STAILQ_FIRST(&mux->sdu_q); + while (pkthdr && num_sdu--) { + om = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); + + while (om && num_pdu > 0) { + rem_len = om->om_len; + hdr_len = sc ? 2 /* Segmentation Header */ + : 5 /* Segmentation Header + TimeOffset */; + + if (mux->max_pdu <= hdr_len + pdu_offset) { + /* Advance to next PDU */ + pdu_offset = 0; + num_pdu--; + continue; + } + + frag_len = min(rem_len, mux->max_pdu - hdr_len - pdu_offset); + + pdu_offset += hdr_len + frag_len; + + os_mbuf_adj(om, frag_len); + + if (frag_len == rem_len) { + om_next = SLIST_NEXT(om, om_next); + os_mbuf_free(om); + pkt_freed++; + om = om_next; + } else { + sc = 1; + } + } + + if (num_pdu == 0) { + break; + } + + OS_ENTER_CRITICAL(sr); + STAILQ_REMOVE_HEAD(&mux->sdu_q, omp_next); + BLE_LL_ASSERT(mux->sdu_q_len > 0); + mux->sdu_q_len--; + OS_EXIT_CRITICAL(sr); + + sc = 0; + pkthdr = STAILQ_FIRST(&mux->sdu_q); + } + + mux->sdu_in_event = 0; + mux->sc = sc; + + return pkt_freed; +} + int +ble_ll_isoal_mux_event_done(struct ble_ll_isoal_mux *mux) +{ + struct os_mbuf_pkthdr *pkthdr; + struct ble_mbuf_hdr *blehdr; + struct os_mbuf *om; + + pkthdr = STAILQ_FIRST(&mux->sdu_q); + if (pkthdr) { + om = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); + blehdr = BLE_MBUF_HDR_PTR(om); + mux->last_tx_timestamp = mux->event_tx_timestamp; + mux->last_tx_packet_seq_num = blehdr->txiso.packet_seq_num; + } + + if (mux->framed) { + return ble_ll_isoal_mux_framed_event_done(mux); + } + + return ble_ll_isoal_mux_unframed_event_done(mux); +} + +static int ble_ll_isoal_mux_unframed_get(struct ble_ll_isoal_mux *mux, uint8_t idx, uint8_t *llid, void *dptr) { @@ -258,96 +338,141 @@ ble_ll_isoal_mux_unframed_get(struct ble_ll_isoal_mux *mux, uint8_t idx, return pdu_len; } -static void -ble_ll_isoal_tx_pkt_in(struct ble_npl_event *ev) +static int +ble_ll_isoal_mux_framed_get(struct ble_ll_isoal_mux *mux, uint8_t idx, + uint8_t *llid, uint8_t *dptr) { - struct os_mbuf *om; + struct ble_mbuf_hdr *blehdr; struct os_mbuf_pkthdr *pkthdr; - struct ble_hci_iso *hci_iso; - struct ble_hci_iso_data *hci_iso_data; - struct ble_ll_isoal_mux *mux; - uint16_t data_hdr_len; - uint16_t handle; - uint16_t conn_handle; - uint16_t length; - uint16_t pb_flag; - uint16_t ts_flag; - uint32_t timestamp = 0; - os_sr_t sr; + struct os_mbuf *om; + uint32_t time_offset; + uint16_t seghdr; + uint16_t rem_len = 0; + uint16_t sdu_offset = 0; + uint8_t num_sdu; + uint8_t num_pdu; + uint8_t frag_len; + uint8_t pdu_offset = 0; + bool sc = mux->sc; + uint8_t hdr_len = 0; + + *llid = 0b10; - while (STAILQ_FIRST(&ll_isoal_tx_q)) { - pkthdr = STAILQ_FIRST(&ll_isoal_tx_q); + num_sdu = mux->sdu_in_event; + if (num_sdu == 0) { + return 0; + } + + num_pdu = idx; + + /* Skip the idx PDUs */ + pkthdr = STAILQ_FIRST(&mux->sdu_q); + while (pkthdr && num_sdu > 0 && num_pdu > 0) { om = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); - OS_ENTER_CRITICAL(sr); - STAILQ_REMOVE_HEAD(&ll_isoal_tx_q, omp_next); - OS_EXIT_CRITICAL(sr); + rem_len = OS_MBUF_PKTLEN(om) - sdu_offset; + hdr_len = sc ? 2 /* Segmentation Header */ + : 5 /* Segmentation Header + TimeOffset */; - hci_iso = (void *)om->om_data; + if (mux->max_pdu <= hdr_len + pdu_offset) { + /* Advance to next PDU */ + pdu_offset = 0; + num_pdu--; + continue; + } - handle = le16toh(hci_iso->handle); - conn_handle = BLE_HCI_ISO_CONN_HANDLE(handle); - pb_flag = BLE_HCI_ISO_PB_FLAG(handle); - ts_flag = BLE_HCI_ISO_TS_FLAG(handle); - length = BLE_HCI_ISO_LENGTH(le16toh(hci_iso->length)); + frag_len = min(rem_len, mux->max_pdu - hdr_len - pdu_offset); - data_hdr_len = 0; - if ((pb_flag == BLE_HCI_ISO_PB_FIRST) || - (pb_flag == BLE_HCI_ISO_PB_COMPLETE)) { - if (ts_flag) { - timestamp = get_le32(om->om_data + sizeof(*hci_iso)); - data_hdr_len += sizeof(uint32_t); - } + pdu_offset += hdr_len + frag_len; + + if (frag_len == rem_len) { + /* Process next SDU */ + sdu_offset = 0; + num_sdu--; + pkthdr = STAILQ_NEXT(pkthdr, omp_next); + + sc = 0; + } else { + sdu_offset += frag_len; - hci_iso_data = (void *)(om->om_data + sizeof(*hci_iso) + data_hdr_len); - data_hdr_len += sizeof(*hci_iso_data); + sc = 1; } - os_mbuf_adj(om, sizeof(*hci_iso) + data_hdr_len); + } - if (OS_MBUF_PKTLEN(om) != length - data_hdr_len) { - os_mbuf_free_chain(om); - continue; + if (num_pdu > 0) { + return 0; + } + + BLE_LL_ASSERT(pdu_offset == 0); + + while (pkthdr && num_sdu > 0) { + om = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); + + rem_len = OS_MBUF_PKTLEN(om) - sdu_offset; + hdr_len = sc ? 2 /* Segmentation Header */ + : 5 /* Segmentation Header + TimeOffset */; + + if (mux->max_pdu <= hdr_len + pdu_offset) { + break; } - mux = ble_ll_iso_find_mux_by_handle(conn_handle); - if (!mux) { - os_mbuf_free_chain(om); - continue; + frag_len = min(rem_len, mux->max_pdu - hdr_len - pdu_offset); + + /* Segmentation Header */ + seghdr = BLE_LL_ISOAL_SEGHDR(sc, frag_len == rem_len, frag_len + hdr_len - 2); + put_le16(dptr + pdu_offset, seghdr); + pdu_offset += 2; + + /* Time Offset */ + if (hdr_len > 2) { + blehdr = BLE_MBUF_HDR_PTR(om); + + time_offset = mux->event_tx_timestamp - + blehdr->txiso.cpu_timestamp; + put_le24(dptr + pdu_offset, time_offset); + pdu_offset += 3; + } + + /* ISO Data Fragment */ + os_mbuf_copydata(om, sdu_offset, frag_len, dptr + pdu_offset); + pdu_offset += frag_len; + + if (frag_len == rem_len) { + /* Process next SDU */ + sdu_offset = 0; + num_sdu--; + pkthdr = STAILQ_NEXT(pkthdr, omp_next); + + sc = 0; + } else { + sdu_offset += frag_len; + + sc = 1; } + } + + return pdu_offset; +} - ble_ll_isoal_mux_tx_pkt_in(mux, om, pb_flag, timestamp); +int +ble_ll_isoal_mux_pdu_get(struct ble_ll_isoal_mux *mux, uint8_t idx, + uint8_t *llid, void *dptr) +{ + if (mux->framed) { + return ble_ll_isoal_mux_framed_get(mux, idx, llid, dptr); } + + return ble_ll_isoal_mux_unframed_get(mux, idx, llid, dptr); } void ble_ll_isoal_init(void) { - STAILQ_INIT(&ll_isoal_tx_q); - ble_npl_event_init(&ll_isoal_tx_pkt_in, ble_ll_isoal_tx_pkt_in, NULL); } void ble_ll_isoal_reset(void) { - STAILQ_INIT(&ll_isoal_tx_q); - ble_npl_eventq_remove(&g_ble_ll_data.ll_evq, &ll_isoal_tx_pkt_in); -} - -int -ble_ll_isoal_data_in(struct os_mbuf *om) -{ - struct os_mbuf_pkthdr *hdr; - os_sr_t sr; - - hdr = OS_MBUF_PKTHDR(om); - - OS_ENTER_CRITICAL(sr); - STAILQ_INSERT_TAIL(&ll_isoal_tx_q, hdr, omp_next); - OS_EXIT_CRITICAL(sr); - - ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &ll_isoal_tx_pkt_in); - - return 0; } #endif /* BLE_LL_ISO */ diff --git a/nimble/controller/test/src/ble_ll_isoal.c b/nimble/controller/test/src/ble_ll_isoal.c new file mode 100644 index 0000000000..c10006c143 --- /dev/null +++ b/nimble/controller/test/src/ble_ll_isoal.c @@ -0,0 +1,966 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#define TSPX_max_sdu_length (503) +#define HCI_iso_sdu_max (MYNEWT_VAL(BLE_TRANSPORT_ISO_SIZE) - 4) + +#define MBUF_TEST_POOL_BUF_SIZE (TSPX_max_sdu_length + BLE_MBUF_MEMBLOCK_OVERHEAD) +#define MBUF_TEST_POOL_BUF_COUNT (10) + +os_membuf_t os_mbuf_membuf[OS_MEMPOOL_SIZE(MBUF_TEST_POOL_BUF_SIZE, MBUF_TEST_POOL_BUF_COUNT)]; + +static struct os_mbuf_pool os_mbuf_pool; +static struct os_mempool os_mbuf_mempool; +static uint8_t os_mbuf_test_data[TSPX_max_sdu_length]; + +void +os_mbuf_test_setup(void) +{ + int rc; + int i; + + rc = os_mempool_init(&os_mbuf_mempool, MBUF_TEST_POOL_BUF_COUNT, + MBUF_TEST_POOL_BUF_SIZE, &os_mbuf_membuf[0], "mbuf_pool"); + TEST_ASSERT_FATAL(rc == 0, "Error creating memory pool %d", rc); + + rc = os_mbuf_pool_init(&os_mbuf_pool, &os_mbuf_mempool, + MBUF_TEST_POOL_BUF_SIZE, MBUF_TEST_POOL_BUF_COUNT); + TEST_ASSERT_FATAL(rc == 0, "Error creating mbuf pool %d", rc); + + for (i = 0; i < sizeof os_mbuf_test_data; i++) { + os_mbuf_test_data[i] = i; + } + + TEST_ASSERT_FATAL(os_mbuf_mempool.mp_block_size == MBUF_TEST_POOL_BUF_SIZE, + "mp_block_size is %d", os_mbuf_mempool.mp_block_size); + TEST_ASSERT_FATAL(os_mbuf_mempool.mp_num_free == MBUF_TEST_POOL_BUF_COUNT, + "mp_num_free is %d", os_mbuf_mempool.mp_num_free); +} + +TEST_CASE_SELF(test_ble_ll_isoal_mux_init) { + struct ble_ll_isoal_mux mux; + const uint32_t iso_interval_us = 10000; + const uint32_t sdu_interval_us = 10000; + const bool Framed = 0; + const bool Framing_Mode = 0; + const uint8_t bn = 1; + const uint8_t max_pdu = 250; + + ble_ll_isoal_mux_init(&mux, max_pdu, iso_interval_us, sdu_interval_us, bn, + 0, Framed, Framing_Mode); + + TEST_ASSERT(mux.pdu_per_sdu == (bn * sdu_interval_us) / iso_interval_us); + + ble_ll_isoal_mux_free(&mux); +} + +TEST_CASE_SELF(ble_ll_isoal_mux_pdu_get_unframed_1_sdu_2_pdu) { + struct ble_ll_isoal_mux mux; + struct os_mbuf *sdu_1, *sdu_2; + const uint32_t iso_interval_us = 20000; + const uint32_t sdu_interval_us = 10000; + const bool Framed = 0; + const bool Framing_Mode = 0; + const uint8_t bn = 6; + const uint8_t max_pdu = 40; + const uint8_t sdu_len = 3 * max_pdu; + static uint8_t data[40]; + int num_completed_pkt; + int pdu_len; + uint8_t llid = 0x00; + int rc; + + ble_ll_isoal_mux_init(&mux, max_pdu, iso_interval_us, sdu_interval_us, bn, + 0, Framed, Framing_Mode); + + /* SDU #1 */ + sdu_1 = os_mbuf_get_pkthdr(&os_mbuf_pool, sizeof(struct ble_mbuf_hdr)); + TEST_ASSERT_FATAL(sdu_1 != NULL); + rc = os_mbuf_append(sdu_1, os_mbuf_test_data, sdu_len); + TEST_ASSERT_FATAL(rc == 0); + ble_ll_isoal_mux_sdu_enqueue(&mux, sdu_1); + + /* SDU #2 */ + sdu_2 = os_mbuf_get_pkthdr(&os_mbuf_pool, sizeof(struct ble_mbuf_hdr)); + TEST_ASSERT_FATAL(sdu_2 != NULL); + rc = os_mbuf_append(sdu_2, os_mbuf_test_data, sdu_len); + TEST_ASSERT_FATAL(rc == 0); + ble_ll_isoal_mux_sdu_enqueue(&mux, sdu_2); + + ble_ll_isoal_mux_event_start(&mux, 90990); + + /* PDU #1 */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, data); + TEST_ASSERT(pdu_len == max_pdu, "PDU length is incorrect %d", pdu_len); + /* Unframed CIS Data PDU; start or continuation fragment of an SDU. */ + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + + /* PDU #2 */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 1, &llid, data); + TEST_ASSERT(pdu_len == max_pdu, "PDU length is incorrect %d", pdu_len); + /* Unframed CIS Data PDU; start or continuation fragment of an SDU. */ + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + + /* PDU #3 */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 2, &llid, data); + TEST_ASSERT(pdu_len == max_pdu, "PDU length is incorrect %d", pdu_len); + /* Unframed CIS Data PDU; end fragment of an SDU or a complete SDU. */ + TEST_ASSERT(llid == 0b00, "LLID is incorrect %d", llid); + + /* PDU #4 */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, data); + TEST_ASSERT(pdu_len == max_pdu, "PDU length is incorrect %d", pdu_len); + /* Unframed CIS Data PDU; start or continuation fragment of an SDU. */ + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + + /* PDU #5 */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 1, &llid, data); + TEST_ASSERT(pdu_len == max_pdu, "PDU length is incorrect %d", pdu_len); + /* Unframed CIS Data PDU; start or continuation fragment of an SDU. */ + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + + /* PDU #6 */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 2, &llid, data); + TEST_ASSERT(pdu_len == max_pdu, "PDU length is incorrect %d", pdu_len); + /* Unframed CIS Data PDU; end fragment of an SDU or a complete SDU. */ + TEST_ASSERT(llid == 0b00, "LLID is incorrect %d", llid); + + num_completed_pkt = ble_ll_isoal_mux_event_done(&mux); + TEST_ASSERT(num_completed_pkt > 0, "num_completed_pkt is incorrect %d", num_completed_pkt); + + ble_ll_isoal_mux_free(&mux); +} + +TEST_CASE_SELF(test_ble_ll_isoal_mux_get_unframed_pdu) { + struct ble_ll_isoal_mux mux; + struct os_mbuf *sdu_1, *sdu_2; + const uint32_t iso_interval_us = 20000; + const uint32_t sdu_interval_us = 10000; + const bool Framed = 0; + const bool Framing_Mode = 0; + const uint8_t bn = 6; + const uint8_t max_pdu = 40; + const uint8_t sdu_len = 3 * max_pdu; + static uint8_t data[40]; + int num_completed_pkt; + int pdu_len; + uint8_t llid = 0x00; + int rc; + + ble_ll_isoal_mux_init(&mux, max_pdu, iso_interval_us, sdu_interval_us, bn, + 0, Framed, Framing_Mode); + + /* SDU #1 */ + sdu_1 = os_mbuf_get_pkthdr(&os_mbuf_pool, sizeof(struct ble_mbuf_hdr)); + TEST_ASSERT_FATAL(sdu_1 != NULL); + rc = os_mbuf_append(sdu_1, os_mbuf_test_data, sdu_len); + TEST_ASSERT_FATAL(rc == 0); + ble_ll_isoal_mux_sdu_enqueue(&mux, sdu_1); + + /* SDU #2 */ + sdu_2 = os_mbuf_get_pkthdr(&os_mbuf_pool, sizeof(struct ble_mbuf_hdr)); + TEST_ASSERT_FATAL(sdu_2 != NULL); + rc = os_mbuf_append(sdu_2, os_mbuf_test_data, sdu_len); + TEST_ASSERT_FATAL(rc == 0); + ble_ll_isoal_mux_sdu_enqueue(&mux, sdu_2); + + ble_ll_isoal_mux_event_start(&mux, 90990); + + /* PDU #1 */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, data); + TEST_ASSERT(pdu_len == max_pdu, "PDU length is incorrect %d", pdu_len); + /* Unframed CIS Data PDU; start or continuation fragment of an SDU. */ + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + + /* PDU #2 */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 1, &llid, data); + TEST_ASSERT(pdu_len == max_pdu, "PDU length is incorrect %d", pdu_len); + /* Unframed CIS Data PDU; start or continuation fragment of an SDU. */ + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + + /* PDU #3 */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 2, &llid, data); + TEST_ASSERT(pdu_len == max_pdu, "PDU length is incorrect %d", pdu_len); + /* Unframed CIS Data PDU; end fragment of an SDU or a complete SDU. */ + TEST_ASSERT(llid == 0b00, "LLID is incorrect %d", llid); + + /* PDU #4 */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, data); + TEST_ASSERT(pdu_len == max_pdu, "PDU length is incorrect %d", pdu_len); + /* Unframed CIS Data PDU; start or continuation fragment of an SDU. */ + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + + /* PDU #5 */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 1, &llid, data); + TEST_ASSERT(pdu_len == max_pdu, "PDU length is incorrect %d", pdu_len); + /* Unframed CIS Data PDU; start or continuation fragment of an SDU. */ + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + + /* PDU #6 */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 2, &llid, data); + TEST_ASSERT(pdu_len == max_pdu, "PDU length is incorrect %d", pdu_len); + /* Unframed CIS Data PDU; end fragment of an SDU or a complete SDU. */ + TEST_ASSERT(llid == 0b00, "LLID is incorrect %d", llid); + + num_completed_pkt = ble_ll_isoal_mux_event_done(&mux); + TEST_ASSERT(num_completed_pkt > 0, "num_completed_pkt is incorrect %d", + num_completed_pkt); + + ble_ll_isoal_mux_free(&mux); +} + +TEST_CASE_SELF(test_ble_ll_isoal_mux_sdu_not_in_event) { + struct ble_ll_isoal_mux mux; + struct os_mbuf *sdu_1; + const uint32_t iso_interval_us = 10000; + const uint32_t sdu_interval_us = 10000; + const bool Framed = 1; + const bool Framing_Mode = 0; + const uint8_t bn = 2; + const uint8_t max_pdu = 40; + const uint8_t sdu_len = 40; + static uint8_t data[40]; + int num_completed_pkt; + int pdu_len; + uint8_t llid = 0x00; + int rc; + + ble_ll_isoal_mux_init(&mux, max_pdu, iso_interval_us, sdu_interval_us, bn, + 0, Framed, Framing_Mode); + + ble_ll_isoal_mux_event_start(&mux, 90990); + TEST_ASSERT_FATAL(mux.sdu_in_event == 0, + "sdu_in_event %d != 0", mux.sdu_in_event); + + /* SDU #1 */ + sdu_1 = os_mbuf_get_pkthdr(&os_mbuf_pool, sizeof(struct ble_mbuf_hdr)); + TEST_ASSERT_FATAL(sdu_1 != NULL); + rc = os_mbuf_append(sdu_1, os_mbuf_test_data, sdu_len); + TEST_ASSERT_FATAL(rc == 0); + ble_ll_isoal_mux_sdu_enqueue(&mux, sdu_1); + + TEST_ASSERT_FATAL(mux.sdu_in_event == 0, + "sdu_in_event %d != 0", mux.sdu_in_event); + + /* PDU #1 */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, data); + TEST_ASSERT(pdu_len == 0, "PDU length is incorrect %d", pdu_len); + TEST_ASSERT(llid == 0b10, "LLID is incorrect %d", llid); + + /* PDU #2 */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 1, &llid, data); + TEST_ASSERT(pdu_len == 0, "PDU length is incorrect %d", pdu_len); + TEST_ASSERT(llid == 0b10, "LLID is incorrect %d", llid); + + num_completed_pkt = ble_ll_isoal_mux_event_done(&mux); + TEST_ASSERT(num_completed_pkt == 0, "num_completed_pkt is incorrect %d", + num_completed_pkt); + + ble_ll_isoal_mux_free(&mux); +} + +static int +test_sdu_enqueue(struct ble_ll_isoal_mux *mux, uint16_t sdu_len, + uint16_t packet_seq_num, uint32_t timestamp) +{ + struct ble_mbuf_hdr *blehdr; + struct os_mbuf *sdu, *frag; + uint16_t sdu_frag_len; + uint16_t offset = 0; + uint8_t num_pkt = 0; + int rc; + + TEST_ASSERT_FATAL(sdu_len <= TSPX_max_sdu_length, "incorrect sdu length"); + + sdu = os_mbuf_get_pkthdr(&os_mbuf_pool, sizeof(struct ble_mbuf_hdr)); + TEST_ASSERT_FATAL(sdu != NULL); + blehdr = BLE_MBUF_HDR_PTR(sdu); + blehdr->txiso.packet_seq_num = packet_seq_num; + blehdr->txiso.cpu_timestamp = timestamp; + + /* First SDU Fragment */ + sdu_frag_len = min(sdu_len, HCI_iso_sdu_max); + rc = os_mbuf_append(sdu, os_mbuf_test_data, sdu_frag_len); + TEST_ASSERT_FATAL(rc == 0); + + offset += sdu_frag_len; + num_pkt++; + + while (offset < sdu_len) { + frag = os_mbuf_get_pkthdr(&os_mbuf_pool, sizeof(struct ble_mbuf_hdr)); + TEST_ASSERT_FATAL(frag != NULL); + + /* Subsequent SDU Fragments */ + sdu_frag_len = min(sdu_len - offset, HCI_iso_sdu_max); + rc = os_mbuf_append(sdu, &os_mbuf_test_data[offset], sdu_frag_len); + TEST_ASSERT_FATAL(rc == 0); + + offset += sdu_frag_len; + num_pkt++; + + os_mbuf_concat(sdu, frag); + } + + ble_ll_isoal_mux_sdu_enqueue(mux, sdu); + + return num_pkt; +} + +static void +test_pdu_verify(uint8_t *pdu, int pdu_len, uint16_t sdu_offset) +{ + for (int i = 0; i < pdu_len; i++) { + TEST_ASSERT(pdu[i] == os_mbuf_test_data[sdu_offset + i], + "PDU verification failed pdu[%d] %d != %d", + i, pdu[i], os_mbuf_test_data[sdu_offset + i]); + } +} + +struct test_ial_broadcast_single_sdu_bis_cfg { + uint8_t NSE; + uint8_t Framed; + uint8_t Framing_Mode; + uint8_t Max_PDU; + uint8_t LLID; + uint8_t BN; + uint32_t SDU_Interval; + uint32_t ISO_Interval; +}; + +static void +test_ial_teardown(struct ble_ll_isoal_mux *mux) +{ + ble_ll_isoal_mux_free(mux); + TEST_ASSERT_FATAL(os_mbuf_mempool.mp_block_size == MBUF_TEST_POOL_BUF_SIZE, + "mp_block_size is %d", os_mbuf_mempool.mp_block_size); + TEST_ASSERT_FATAL(os_mbuf_mempool.mp_num_free == MBUF_TEST_POOL_BUF_COUNT, + "mp_num_free is %d", os_mbuf_mempool.mp_num_free); +} + +static void +test_ial_setup(struct ble_ll_isoal_mux *mux, uint8_t max_pdu, + uint32_t iso_interval_us, uint32_t sdu_interval_us, + uint8_t bn, uint8_t pte, bool framed, uint8_t framing_mode) +{ + ble_ll_isoal_mux_init(mux, max_pdu, iso_interval_us, sdu_interval_us, + bn, pte, framed, framing_mode); +} + +static void +test_ial_broadcast_single_sdu_bis(const struct test_ial_broadcast_single_sdu_bis_cfg *cfg) +{ + struct ble_ll_isoal_mux mux; + int num_completed_pkt; + int pdu_len; + uint32_t timeoffset; + uint16_t seg_hdr; + const uint8_t Max_SDU = 32; + uint8_t pdu[cfg->Max_PDU]; + uint8_t llid = 0xff; + + test_ial_setup(&mux, cfg->Max_PDU, cfg->ISO_Interval, + cfg->SDU_Interval, cfg->BN, 0, cfg->Framed, + cfg->Framing_Mode); + + /* Send Single SDU */ + test_sdu_enqueue(&mux, Max_SDU, 0, 20000); + + ble_ll_isoal_mux_event_start(&mux, 30500); + + /* PDU #1 */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, pdu); + TEST_ASSERT(llid == cfg->LLID, "LLID is incorrect %d", llid); + + if (cfg->Framed) { + TEST_ASSERT(pdu_len == 2 /* Header */ + 3 /* TimeOffset */ + Max_SDU, + "PDU length is incorrect %d", pdu_len); + seg_hdr = get_le16(&pdu[0]); + TEST_ASSERT(BLE_LL_ISOAL_SEGHDR_SC(seg_hdr) == 0, "SC is incorrect %d", + BLE_LL_ISOAL_SEGHDR_SC(seg_hdr)); + TEST_ASSERT(BLE_LL_ISOAL_SEGHDR_CMPLT(seg_hdr) == 1, "CMPLT is incorrect %d", + BLE_LL_ISOAL_SEGHDR_CMPLT(seg_hdr)); + TEST_ASSERT(BLE_LL_ISOAL_SEGHDR_LEN(seg_hdr) == 3 /* TimeOffset */ + Max_SDU, + "Length is incorrect %d", BLE_LL_ISOAL_SEGHDR_LEN(seg_hdr)); + timeoffset = get_le24(&pdu[2]); + TEST_ASSERT(timeoffset == 10500, "Time offset is incorrect %d", timeoffset); + + test_pdu_verify(&pdu[5], Max_SDU, 0); + } else { + TEST_ASSERT(pdu_len == Max_SDU, "PDU length is incorrect %d", pdu_len); + + test_pdu_verify(&pdu[0], Max_SDU, 0); + } + + num_completed_pkt = ble_ll_isoal_mux_event_done(&mux); + TEST_ASSERT(num_completed_pkt > 0, "num_completed_pkt is incorrect %d", num_completed_pkt); + + test_ial_teardown(&mux); +} + +TEST_CASE_SELF(test_ial_bis_unf_brd_bv_01_c) { + const struct test_ial_broadcast_single_sdu_bis_cfg cfg = { + .NSE = 2, + .Framed = 0, + .Framing_Mode = 0, + .Max_PDU = 40, + .LLID = 0b00, + .BN = 1, + .SDU_Interval = 10000, + .ISO_Interval = 10000, + }; + + test_ial_broadcast_single_sdu_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_unf_brd_bv_02_c) { + const struct test_ial_broadcast_single_sdu_bis_cfg cfg = { + .NSE = 4, + .Framed = 0, + .Framing_Mode = 0, + .Max_PDU = 40, + .LLID = 0b00, + .BN = 2, + .SDU_Interval = 5000, + .ISO_Interval = 10000, + }; + + test_ial_broadcast_single_sdu_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_fra_brd_bv_06_c) { + const struct test_ial_broadcast_single_sdu_bis_cfg cfg = { + .NSE = 4, + .Framed = 1, + .Framing_Mode = 0, + .Max_PDU = 40, + .LLID = 0b10, + .BN = 2, + .SDU_Interval = 5000, + .ISO_Interval = 10000, + }; + + test_ial_broadcast_single_sdu_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_fra_brd_bv_08_c) { + const struct test_ial_broadcast_single_sdu_bis_cfg cfg = { + .NSE = 2, + .Framed = 1, + .Framing_Mode = 0, + .Max_PDU = 40, + .LLID = 0b10, + .BN = 1, + .SDU_Interval = 10000, + .ISO_Interval = 10000, + }; + + test_ial_broadcast_single_sdu_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_fra_brd_bv_29_c) { + const struct test_ial_broadcast_single_sdu_bis_cfg cfg = { + .NSE = 6, + .Framed = 1, + .Framing_Mode = 1, + .Max_PDU = 32 + 5, + .LLID = 0b10, + .BN = 3, + .SDU_Interval = 5000, + .ISO_Interval = 10000, + }; + + test_ial_broadcast_single_sdu_bis(&cfg); +} + +struct test_ial_broadcast_large_sdu_bis_cfg { + uint8_t NSE; + uint8_t Framed; + uint8_t Framing_Mode; + uint8_t BN; + uint32_t SDU_Interval; + uint32_t ISO_Interval; +}; +struct test_ial_broadcast_large_sdu_bis_round { + uint16_t sdu_len; + uint8_t sc_packets_num; +}; + +static void +test_ial_broadcast_large_sdu_bis(const struct test_ial_broadcast_large_sdu_bis_cfg *cfg) +{ + const struct test_ial_broadcast_large_sdu_bis_round rounds[] = { + {.sdu_len = 495, .sc_packets_num = 1}, + {.sdu_len = 503, .sc_packets_num = 2}, + }; + struct ble_ll_isoal_mux mux; + /* const uint16_t Max_SDU = 503; */ + const uint8_t Max_PDU = 251; + int num_completed_pkt; + int num_expected_pkt; + int pdu_len; + uint8_t pdu[Max_PDU]; + uint32_t timestamp; + uint16_t seg_hdr; + uint16_t sdu_offset; + uint8_t llid = 0xff; + uint8_t sc_packets_num; + uint8_t seg_len; + uint8_t idx; + + test_ial_setup(&mux, Max_PDU, cfg->ISO_Interval, + cfg->SDU_Interval, cfg->BN, 0, cfg->Framed, + cfg->Framing_Mode); + + for (size_t round = 0; round < ARRAY_SIZE(rounds); round++) { + sc_packets_num = 0; + sdu_offset = 0; + + timestamp = (round + 1) * cfg->SDU_Interval; + + num_expected_pkt = test_sdu_enqueue(&mux, rounds[round].sdu_len, round, timestamp); + + ble_ll_isoal_mux_event_start(&mux, timestamp + 100); + + for (idx = 0; idx < cfg->BN; idx++) { + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, idx, &llid, pdu); + if (pdu_len == 0) { + TEST_ASSERT_FATAL(sdu_offset == rounds[round].sdu_len, + "Round #%d: idx %d sdu_offset %d", + round, idx, sdu_offset); + continue; + } + + /* The IUT sends the specified number of Start/Continuation + * packets specified in Table 4.29 of ISO Data PDUs to the + * Lower Tester with the LLID=0b01 for unframed payloads and + * LLID=0b10 for framed payloads, and Payload Data every 251 + * bytes offset in step 1. + */ + if (sc_packets_num < rounds[round].sc_packets_num) { + TEST_ASSERT_FATAL(pdu_len == 251, "Round #%d: idx #%d: Length is incorrect %d", + round, idx, pdu_len); + + if (cfg->Framed) { + TEST_ASSERT_FATAL(llid == 0b10, "Round #%d: LLID is incorrect %d", round, llid); + + seg_hdr = get_le16(&pdu[0]); + seg_len = BLE_LL_ISOAL_SEGHDR_LEN(seg_hdr); + if (idx == 0) { + TEST_ASSERT_FATAL(BLE_LL_ISOAL_SEGHDR_SC(seg_hdr) == 0, + "Round #%d: SC is incorrect %d", + round, BLE_LL_ISOAL_SEGHDR_SC(seg_hdr)); + + test_pdu_verify(&pdu[5], seg_len - 3, 0); + sdu_offset += seg_len - 3; + } else { + TEST_ASSERT_FATAL(BLE_LL_ISOAL_SEGHDR_SC(seg_hdr) == 1, + "Round #%d: SC is incorrect %d", + round, BLE_LL_ISOAL_SEGHDR_SC(seg_hdr)); + + test_pdu_verify(&pdu[2], seg_len, sdu_offset); + sdu_offset += seg_len; + } + } else { + TEST_ASSERT_FATAL(llid == 0b01, "Round #%d: LLID is incorrect %d", round, llid); + + test_pdu_verify(&pdu[0], pdu_len, sdu_offset); + sdu_offset += pdu_len; + } + + sc_packets_num++; + } else { + /* The IUT sends the last ISO Data PDU to the Lower Tester + * with the LLID=0b00 for unframed payloads and LLID=0b10 + * for framed payloads, with the remaining Payload Data. + */ + if (cfg->Framed) { + TEST_ASSERT_FATAL(pdu_len == rounds[round].sdu_len - sdu_offset + 2, + "Round #%d: idx %d: PDU length is incorrect %d != %d", + round, idx, pdu_len, rounds[round].sdu_len - sdu_offset + 2); + TEST_ASSERT_FATAL(llid == 0b10, "Round #%d: LLID is incorrect %d", + round, llid); + + seg_hdr = get_le16(&pdu[0]); + TEST_ASSERT_FATAL(BLE_LL_ISOAL_SEGHDR_SC(seg_hdr), + "Round #%d: SC is incorrect %d", + round, BLE_LL_ISOAL_SEGHDR_SC(seg_hdr)); + TEST_ASSERT_FATAL(BLE_LL_ISOAL_SEGHDR_CMPLT(seg_hdr), + "Round #%d: CMPLT is incorrect %d", + round, BLE_LL_ISOAL_SEGHDR_CMPLT(seg_hdr)); + seg_len = BLE_LL_ISOAL_SEGHDR_LEN(seg_hdr); + + test_pdu_verify(&pdu[2], seg_len, sdu_offset); + sdu_offset += seg_len; + } else { + TEST_ASSERT_FATAL(pdu_len == rounds[round].sdu_len - sdu_offset, + "Round #%d: idx %d: PDU length is incorrect %d != %d", + round, idx, pdu_len, rounds[round].sdu_len - sdu_offset); + TEST_ASSERT_FATAL(llid == 0b00, "Round #%d: LLID is incorrect %d", round, llid); + + test_pdu_verify(&pdu[0], pdu_len, sdu_offset); + sdu_offset += pdu_len; + } + } + } + + num_completed_pkt = ble_ll_isoal_mux_event_done(&mux); + TEST_ASSERT(num_completed_pkt == num_expected_pkt, + "num_completed_pkt %d != %d", num_completed_pkt, num_expected_pkt); + } + + test_ial_teardown(&mux); +} + +TEST_CASE_SELF(test_ial_bis_fra_brd_bv_13_c) { + const struct test_ial_broadcast_large_sdu_bis_cfg cfg = { + .NSE = 10, + .Framed = 1, + .Framing_Mode = 0, + .BN = 5, + .SDU_Interval = 15000, + .ISO_Interval = 30000, + }; + + test_ial_broadcast_large_sdu_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_fra_brd_bv_15_c) { + const struct test_ial_broadcast_large_sdu_bis_cfg cfg = { + .NSE = 6, + .Framed = 1, + .Framing_Mode = 0, + .BN = 3, + .SDU_Interval = 20000, + .ISO_Interval = 20000, + }; + + test_ial_broadcast_large_sdu_bis(&cfg); +} + +struct test_ial_broadcast_multiple_small_sdus_bis_cfg { + uint8_t NSE; + uint8_t BN; + uint8_t Max_PDU; + uint32_t SDU_Interval; + uint32_t ISO_Interval; +}; + +static void +test_ial_broadcast_multiple_small_sdus_bis(const struct test_ial_broadcast_multiple_small_sdus_bis_cfg *cfg) +{ + struct ble_ll_isoal_mux mux; + /* const uint16_t Max_SDU = 25; */ + const uint8_t LLID = 0b10; + const uint8_t Framed = 0x01; + const uint8_t Framing_Mode = 0; + int pdu_len; + uint8_t pdu[cfg->Max_PDU]; + uint32_t sdu_1_ts, sdu_2_ts, event_ts; + uint32_t timeoffset; + uint16_t seg_hdr; + uint8_t llid = 0xff; + uint8_t seg_len; + uint8_t *seg; + + test_ial_setup(&mux, cfg->Max_PDU, cfg->ISO_Interval, + cfg->SDU_Interval, cfg->BN, 0, Framed, + Framing_Mode); + + /* The Upper Tester sends to the IUT a small SDU1 with data length of 20 bytes. */ + sdu_1_ts = 100; + test_sdu_enqueue(&mux, 20, 0, sdu_1_ts); + + /* The Upper Tester sends to the IUT a small SDU2 with data length of 25 bytes. */ + sdu_2_ts = sdu_1_ts + cfg->SDU_Interval; + test_sdu_enqueue(&mux, 25, 0, sdu_2_ts); + + event_ts = sdu_2_ts + 200; + ble_ll_isoal_mux_event_start(&mux, event_ts); + + /* The IUT sends a single Broadcast ISO Data PDU with SDU1 followed by SDU2 over the BIS. + * Each SDU header has SC = 0 and CMPT = 1. + */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, pdu); + TEST_ASSERT(llid == LLID, "LLID is incorrect %d", llid); + + /* SDU 1 */ + seg = &pdu[0]; + TEST_ASSERT(pdu_len > 24, "PDU length is incorrect %d", pdu_len); + seg_hdr = get_le16(&seg[0]); + TEST_ASSERT(BLE_LL_ISOAL_SEGHDR_SC(seg_hdr) == 0, + "SC is incorrect %d", BLE_LL_ISOAL_SEGHDR_SC(seg_hdr)); + TEST_ASSERT(BLE_LL_ISOAL_SEGHDR_CMPLT(seg_hdr) == 1, + "SC is incorrect %d", BLE_LL_ISOAL_SEGHDR_CMPLT(seg_hdr)); + seg_len = BLE_LL_ISOAL_SEGHDR_LEN(seg_hdr); + TEST_ASSERT(seg_len == 20 + 3, "Segment length is incorrect %d", pdu_len); + timeoffset = get_le24(&seg[2]); + TEST_ASSERT(timeoffset == event_ts - sdu_1_ts, + "Time offset is incorrect %d", timeoffset); + + /* SDU 1 */ + seg = &pdu[25]; + TEST_ASSERT(pdu_len == 55, "PDU length is incorrect %d", pdu_len); + seg_hdr = get_le16(&seg[0]); + TEST_ASSERT(BLE_LL_ISOAL_SEGHDR_SC(seg_hdr) == 0, + "SC is incorrect %d", BLE_LL_ISOAL_SEGHDR_SC(seg_hdr)); + TEST_ASSERT(BLE_LL_ISOAL_SEGHDR_CMPLT(seg_hdr) == 1, + "SC is incorrect %d", BLE_LL_ISOAL_SEGHDR_CMPLT(seg_hdr)); + seg_len = BLE_LL_ISOAL_SEGHDR_LEN(seg_hdr); + TEST_ASSERT(seg_len == 25 + 3, "Segment length is incorrect %d", pdu_len); + timeoffset = get_le24(&seg[2]); + TEST_ASSERT(timeoffset == event_ts - sdu_2_ts, + "Time offset is incorrect %d", timeoffset); + + (void)ble_ll_isoal_mux_event_done(&mux); + + test_ial_teardown(&mux); +} + +TEST_CASE_SELF(test_ial_bis_fra_brd_bv_17_c) { + const struct test_ial_broadcast_multiple_small_sdus_bis_cfg cfg = { + .NSE = 2, + .BN = 1, + .Max_PDU = 68, + .SDU_Interval = 500, + .ISO_Interval = 1000, + }; + + test_ial_broadcast_multiple_small_sdus_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_fra_brd_bv_18_c) { + const struct test_ial_broadcast_multiple_small_sdus_bis_cfg cfg = { + .NSE = 2, + .BN = 1, + .Max_PDU = 68, + .SDU_Interval = 1000, + .ISO_Interval = 2000, + }; + + test_ial_broadcast_multiple_small_sdus_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_fra_brd_bv_20_c) { + const struct test_ial_broadcast_multiple_small_sdus_bis_cfg cfg = { + .NSE = 4, + .BN = 2, + .Max_PDU = 65, + .SDU_Interval = 500, + .ISO_Interval = 2000, + }; + + test_ial_broadcast_multiple_small_sdus_bis(&cfg); +} + +struct test_ial_segmentation_header { + uint8_t SC; + uint8_t CMPLT; + uint8_t LENGTH; +}; +struct test_ial_broadcast_zero_length_sdu_bis_cfg { + uint8_t NSE; + uint8_t Framed; + uint8_t Framing_Mode; + uint8_t LLID; + uint8_t BN; + struct test_ial_segmentation_header Segmentation_Header; + bool Time_Offset; +}; + +static void +test_ial_broadcast_zero_length_sdu_bis(const struct test_ial_broadcast_zero_length_sdu_bis_cfg *cfg) +{ + struct ble_ll_isoal_mux mux; + const uint32_t ISO_Interval = 10000; + const uint32_t SDU_Interval = 10000; + /* const uint16_t Max_SDU = 32; */ + const uint16_t Max_PDU = 32; + int pdu_len; + uint8_t pdu[Max_PDU]; + uint32_t timeoffset; + uint16_t seg_hdr; + uint8_t llid = 0xff; + + test_ial_setup(&mux, Max_PDU, ISO_Interval, SDU_Interval, + cfg->BN, 0, cfg->Framed, cfg->Framing_Mode); + + /* The Upper Tester sends an HCI ISO Data packet to the IUT with zero data length. */ + test_sdu_enqueue(&mux, 0, 0, 100); + + ble_ll_isoal_mux_event_start(&mux, 500); + + /* The IUT sends a single Broadcast ISO Data PDU with the LLID, + * Framed, Framing_Mode, the segmentation header and time offset + * fields as specified in Table 4.35. Length is 0 if LLID is 0b00 + * and is 5 (Segmentation Header + TimeOffset) if LLID is 0b10. + * SDU field is empty.. + */ + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, pdu); + TEST_ASSERT(llid == cfg->LLID, "LLID is incorrect %d", llid); + + if (cfg->LLID == 0b00) { + TEST_ASSERT(pdu_len == 0, "PDU length is incorrect %d", pdu_len); + } else if (cfg->LLID == 0b01) { + TEST_ASSERT(pdu_len == 5, "PDU length is incorrect %d", pdu_len); + } + + if (cfg->Framed) { + seg_hdr = get_le16(&pdu[0]); + TEST_ASSERT(BLE_LL_ISOAL_SEGHDR_SC(seg_hdr) == cfg->Segmentation_Header.SC, + "SC is incorrect %d", BLE_LL_ISOAL_SEGHDR_SC(seg_hdr)); + TEST_ASSERT(BLE_LL_ISOAL_SEGHDR_CMPLT(seg_hdr) == cfg->Segmentation_Header.CMPLT, + "CMPLT is incorrect %d", BLE_LL_ISOAL_SEGHDR_CMPLT(seg_hdr)); + TEST_ASSERT(BLE_LL_ISOAL_SEGHDR_LEN(seg_hdr) == cfg->Segmentation_Header.LENGTH, + "LENGTH is incorrect %d", BLE_LL_ISOAL_SEGHDR_LEN(seg_hdr)); + timeoffset = get_le24(&pdu[2]); + TEST_ASSERT(timeoffset == 400, "Time offset is incorrect %d", timeoffset); + } + + for (uint8_t idx = 1; idx < cfg->BN; idx++) { + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, idx, &llid, pdu); + TEST_ASSERT(llid == cfg->LLID, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == 0, "PDU length is incorrect %d", pdu_len); + } + + (void)ble_ll_isoal_mux_event_done(&mux); + + test_ial_teardown(&mux); +} + +TEST_CASE_SELF(test_ial_bis_fra_brd_bv_25_c) { + const struct test_ial_broadcast_zero_length_sdu_bis_cfg cfg = { + .NSE = 6, + .Framed = 1, + .Framing_Mode = 0, + .LLID = 0b10, + .BN = 2, + .Segmentation_Header.SC = 0, + .Segmentation_Header.CMPLT = 1, + .Segmentation_Header.LENGTH = 3, + .Time_Offset = true, + }; + + test_ial_broadcast_zero_length_sdu_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_fra_brd_bv_26_c) { + const struct test_ial_broadcast_zero_length_sdu_bis_cfg cfg = { + .NSE = 2, + .Framed = 1, + .Framing_Mode = 0, + .LLID = 0b10, + .BN = 1, + .Segmentation_Header.SC = 0, + .Segmentation_Header.CMPLT = 1, + .Segmentation_Header.LENGTH = 3, + .Time_Offset = true, + }; + + test_ial_broadcast_zero_length_sdu_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_fra_brd_bv_27_c) { + const struct test_ial_broadcast_zero_length_sdu_bis_cfg cfg = { + .NSE = 4, + .Framed = 1, + .Framing_Mode = 0, + .LLID = 0b10, + .BN = 1, + .Segmentation_Header.SC = 0, + .Segmentation_Header.CMPLT = 1, + .Segmentation_Header.LENGTH = 3, + .Time_Offset = true, + }; + + test_ial_broadcast_zero_length_sdu_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_fra_brd_bv_28_c) { + const struct test_ial_broadcast_zero_length_sdu_bis_cfg cfg = { + .NSE = 6, + .Framed = 1, + .Framing_Mode = 0, + .LLID = 0b10, + .BN = 3, + .Segmentation_Header.SC = 0, + .Segmentation_Header.CMPLT = 1, + .Segmentation_Header.LENGTH = 3, + .Time_Offset = true, + }; + + test_ial_broadcast_zero_length_sdu_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_fra_brd_bv_30_c) { + const struct test_ial_broadcast_zero_length_sdu_bis_cfg cfg = { + .NSE = 6, + .Framed = 1, + .Framing_Mode = 1, + .LLID = 0b10, + .BN = 2, + .Segmentation_Header.SC = 0, + .Segmentation_Header.CMPLT = 1, + .Segmentation_Header.LENGTH = 3, + .Time_Offset = true, + }; + + test_ial_broadcast_zero_length_sdu_bis(&cfg); +} + +TEST_SUITE(ble_ll_isoal_test_suite) { + os_mbuf_test_setup(); + + ble_ll_isoal_init(); + + test_ble_ll_isoal_mux_init(); + test_ble_ll_isoal_mux_get_unframed_pdu(); + test_ble_ll_isoal_mux_sdu_not_in_event(); + + /* Broadcast Single SDU, BIS */ + test_ial_bis_unf_brd_bv_01_c(); + test_ial_bis_unf_brd_bv_02_c(); + test_ial_bis_fra_brd_bv_06_c(); + test_ial_bis_fra_brd_bv_08_c(); + test_ial_bis_fra_brd_bv_29_c(); + + /* Broadcast Large SDU, BIS */ + test_ial_bis_fra_brd_bv_13_c(); + test_ial_bis_fra_brd_bv_15_c(); + + /* Broadcast Multiple, Small SDUs, BIS */ + test_ial_bis_fra_brd_bv_17_c(); + test_ial_bis_fra_brd_bv_18_c(); + test_ial_bis_fra_brd_bv_20_c(); + + /* Broadcast a Zero-Length SDU, BIS */ + test_ial_bis_fra_brd_bv_25_c(); + test_ial_bis_fra_brd_bv_26_c(); + test_ial_bis_fra_brd_bv_27_c(); + test_ial_bis_fra_brd_bv_28_c(); + test_ial_bis_fra_brd_bv_30_c(); + + ble_ll_isoal_reset(); +} diff --git a/nimble/controller/test/src/ble_ll_test.c b/nimble/controller/test/src/ble_ll_test.c index 2b36cb1f3c..7bfbf9bd21 100644 --- a/nimble/controller/test/src/ble_ll_test.c +++ b/nimble/controller/test/src/ble_ll_test.c @@ -25,6 +25,7 @@ TEST_SUITE_DECL(ble_ll_aa_test_suite); TEST_SUITE_DECL(ble_ll_crypto_test_suite); TEST_SUITE_DECL(ble_ll_csa2_test_suite); +TEST_SUITE_DECL(ble_ll_isoal_test_suite); int main(int argc, char **argv) @@ -32,6 +33,7 @@ main(int argc, char **argv) ble_ll_aa_test_suite(); ble_ll_crypto_test_suite(); ble_ll_csa2_test_suite(); + ble_ll_isoal_test_suite(); return tu_any_failed; } diff --git a/nimble/controller/test/syscfg.yml b/nimble/controller/test/syscfg.yml index 6edad438bb..f7a3c4ef5e 100644 --- a/nimble/controller/test/syscfg.yml +++ b/nimble/controller/test/syscfg.yml @@ -18,8 +18,12 @@ syscfg.vals: BLE_LL_CFG_FEAT_LE_CSA2: 1 + BLE_LL_ISO: 1 + BLE_VERSION: 54 # Prevent priority conflict with controller task. MCU_TIMER_POLLER_PRIO: 1 MCU_UART_POLLER_PRIO: 2 NATIVE_SOCKETS_PRIO: 3 + + BLE_TRANSPORT_ISO_SIZE: 255 diff --git a/nimble/include/nimble/ble.h b/nimble/include/nimble/ble.h index a2add5d79a..d5e41a37c8 100644 --- a/nimble/include/nimble/ble.h +++ b/nimble/include/nimble/ble.h @@ -128,6 +128,8 @@ struct ble_mbuf_hdr_txinfo struct ble_mbuf_hdr_txiso { uint16_t packet_seq_num; + uint32_t cpu_timestamp; + uint32_t hci_timestamp; }; /** diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index f4fe5a7f81..f1d2eb46d3 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -2466,6 +2466,10 @@ struct hci_data_hdr #define BLE_HCI_ISO_DATA_PATH_ID_HCI 0x00 +#define BLE_HCI_ISO_FRAMING_UNFRAMED 0x00 +#define BLE_HCI_ISO_FRAMING_FRAMED_SEGMENTABLE 0x01 +#define BLE_HCI_ISO_FRAMING_FRAMED_UNSEGMENTED 0x02 + struct ble_hci_iso { uint16_t handle; uint16_t length; From 559b16b75a152e1ced0d24a3975eedbff1d672f1 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 13 Feb 2025 08:40:00 +0100 Subject: [PATCH 1225/1333] nimble/ll/isoal: Fix broadcast of a Zero-Length SDU This fixes invalid LLID and PDU length of Zero-Length SDU in tests IAL/BIS/UNF/BRD/BV-21-C IAL/BIS/UNF/BRD/BV-22-C --- nimble/controller/src/ble_ll_isoal.c | 9 +- nimble/controller/test/src/ble_ll_isoal.c | 128 ++++++++++++++++++++++ 2 files changed, 135 insertions(+), 2 deletions(-) diff --git a/nimble/controller/src/ble_ll_isoal.c b/nimble/controller/src/ble_ll_isoal.c index 8c8516b6d3..fd2c6ac6a2 100644 --- a/nimble/controller/src/ble_ll_isoal.c +++ b/nimble/controller/src/ble_ll_isoal.c @@ -297,10 +297,10 @@ ble_ll_isoal_mux_unframed_get(struct ble_ll_isoal_mux *mux, uint8_t idx, { struct os_mbuf_pkthdr *pkthdr; struct os_mbuf *om; + int32_t rem_len; uint8_t sdu_idx; uint8_t pdu_idx; uint16_t sdu_offset; - uint16_t rem_len; uint8_t pdu_len; sdu_idx = idx / mux->pdu_per_sdu; @@ -325,7 +325,12 @@ ble_ll_isoal_mux_unframed_get(struct ble_ll_isoal_mux *mux, uint8_t idx, sdu_offset = pdu_idx * mux->max_pdu; rem_len = OS_MBUF_PKTLEN(om) - sdu_offset; - if ((int32_t)rem_len <= 0) { + if (OS_MBUF_PKTLEN(om) == 0) { + /* LLID = 0b00: Zero-Length SDU (complete SDU) */ + *llid = 0; + pdu_len = 0; + } else if (rem_len <= 0) { + /* LLID = 0b01: ISO Data PDU used as padding */ *llid = 1; pdu_len = 0; } else { diff --git a/nimble/controller/test/src/ble_ll_isoal.c b/nimble/controller/test/src/ble_ll_isoal.c index c10006c143..6423ed7252 100644 --- a/nimble/controller/test/src/ble_ll_isoal.c +++ b/nimble/controller/test/src/ble_ll_isoal.c @@ -850,6 +850,54 @@ test_ial_broadcast_zero_length_sdu_bis(const struct test_ial_broadcast_zero_leng test_ial_teardown(&mux); } +TEST_CASE_SELF(test_ial_bis_unf_brd_bv_21_c) { + const struct test_ial_broadcast_zero_length_sdu_bis_cfg cfg = { + .NSE = 4, + .Framed = 0, + .Framing_Mode = 0, + .LLID = 0b00, + .BN = 2, + }; + + test_ial_broadcast_zero_length_sdu_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_unf_brd_bv_22_c) { + const struct test_ial_broadcast_zero_length_sdu_bis_cfg cfg = { + .NSE = 6, + .Framed = 0, + .Framing_Mode = 0, + .LLID = 0b00, + .BN = 3, + }; + + test_ial_broadcast_zero_length_sdu_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_unf_brd_bv_23_c) { + const struct test_ial_broadcast_zero_length_sdu_bis_cfg cfg = { + .NSE = 1, + .Framed = 0, + .Framing_Mode = 0, + .LLID = 0b00, + .BN = 1, + }; + + test_ial_broadcast_zero_length_sdu_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_unf_brd_bv_24_c) { + const struct test_ial_broadcast_zero_length_sdu_bis_cfg cfg = { + .NSE = 2, + .Framed = 0, + .Framing_Mode = 0, + .LLID = 0b00, + .BN = 1, + }; + + test_ial_broadcast_zero_length_sdu_bis(&cfg); +} + TEST_CASE_SELF(test_ial_bis_fra_brd_bv_25_c) { const struct test_ial_broadcast_zero_length_sdu_bis_cfg cfg = { .NSE = 6, @@ -930,6 +978,76 @@ TEST_CASE_SELF(test_ial_bis_fra_brd_bv_30_c) { test_ial_broadcast_zero_length_sdu_bis(&cfg); } +struct test_ial_unframed_empty_pdus_with_llid_0b01_cfg { + uint32_t sdu_int; + uint32_t iso_int; + uint8_t nse; + uint16_t mx_sdu; + uint8_t mx_pdu; + uint8_t bn; + uint8_t irc; + uint8_t pto; +}; + +static void +test_ial_unframed_empty_pdus_with_llid_0b01(const struct test_ial_unframed_empty_pdus_with_llid_0b01_cfg *cfg) +{ + struct ble_ll_isoal_mux mux; + int pdu_len; + uint8_t pdu[cfg->mx_pdu]; + uint32_t timestamp; + uint8_t llid = 0xff; + + ble_ll_isoal_mux_init(&mux, cfg->mx_pdu, cfg->iso_int, cfg->sdu_int, + cfg->bn, 0, false, 0); + + for (uint16_t sdu_len = 4; sdu_len < cfg->mx_sdu; sdu_len++) { + timestamp = sdu_len * cfg->sdu_int; + test_sdu_enqueue(&mux, sdu_len, sdu_len, timestamp); + + ble_ll_isoal_mux_event_start(&mux, timestamp + 50); + + /* As the mx_sdu == mx_pdu, the data will always fit the single PDU */ + TEST_ASSERT(cfg->mx_sdu == cfg->mx_pdu, + "#%d: SDU and PDU length should be same", sdu_len); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, pdu); + TEST_ASSERT(llid == 0b00, + "#%d: LLID is incorrect %d", sdu_len, llid); + TEST_ASSERT(pdu_len == sdu_len, + "#%d: PDU length is incorrect %d", sdu_len, pdu_len); + + /* Padding */ + for (uint8_t idx = 1; idx < cfg->bn; idx++) { + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, idx, &llid, pdu); + TEST_ASSERT(llid == 0b01, + "#%d #%d: LLID is incorrect %d", sdu_len, idx, llid); + TEST_ASSERT(pdu_len == 0, + "#%d #%d: PDU length is incorrect %d", + sdu_len, idx, pdu_len); + } + + (void)ble_ll_isoal_mux_event_done(&mux); + } + + ble_ll_isoal_mux_free(&mux); +} + +TEST_CASE_SELF(test_ial_bis_unf_brd_bv_29_c) { + const struct test_ial_unframed_empty_pdus_with_llid_0b01_cfg cfg = { + .sdu_int = 100, + .iso_int = 100, + .nse = 12, + .mx_sdu = 128, + .mx_pdu = 128, + .bn = 4, + .irc = 3, + .pto = 0, + }; + + test_ial_unframed_empty_pdus_with_llid_0b01(&cfg); +} + TEST_SUITE(ble_ll_isoal_test_suite) { os_mbuf_test_setup(); @@ -956,11 +1074,21 @@ TEST_SUITE(ble_ll_isoal_test_suite) { test_ial_bis_fra_brd_bv_20_c(); /* Broadcast a Zero-Length SDU, BIS */ + test_ial_bis_unf_brd_bv_21_c(); + test_ial_bis_unf_brd_bv_22_c(); + test_ial_bis_unf_brd_bv_23_c(); + test_ial_bis_unf_brd_bv_24_c(); test_ial_bis_fra_brd_bv_25_c(); test_ial_bis_fra_brd_bv_26_c(); test_ial_bis_fra_brd_bv_27_c(); test_ial_bis_fra_brd_bv_28_c(); test_ial_bis_fra_brd_bv_30_c(); + /* Broadcasting Unframed Empty PDUs with LLID=0b01, BIS */ + test_ial_bis_unf_brd_bv_29_c(); + /* test_ial_bis_unf_brd_bv_30_c(); + * Same as test_ial_bis_unf_brd_bv_29_c except encryption is required. + */ + ble_ll_isoal_reset(); } From b9a5982cd989b613560414cd26826221b47e549f Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Wed, 19 Feb 2025 10:57:52 +0300 Subject: [PATCH 1226/1333] nimble/ll/isoal: Fix unframed PDU end fragment LLID This fixes unframed PDU end fragment LLID thta shall be set to 0b00 when the payload of the ISO Data PDU contains the end fragment of an SDU. --- nimble/controller/src/ble_ll_isoal.c | 7 +++- nimble/controller/test/src/ble_ll_isoal.c | 42 +++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_isoal.c b/nimble/controller/src/ble_ll_isoal.c index fd2c6ac6a2..2cb842aa4f 100644 --- a/nimble/controller/src/ble_ll_isoal.c +++ b/nimble/controller/src/ble_ll_isoal.c @@ -334,7 +334,12 @@ ble_ll_isoal_mux_unframed_get(struct ble_ll_isoal_mux *mux, uint8_t idx, *llid = 1; pdu_len = 0; } else { - *llid = (pdu_idx < mux->pdu_per_sdu - 1); + /* LLID = 0b00: Data remaining fits the ISO Data PDU size, + * it's end fragment of an SDU or complete SDU. + * LLID = 0b01: Data remaining exceeds the ISO Data PDU size, + * it's start or continuation fragment of an SDU. + */ + *llid = rem_len > mux->max_pdu; pdu_len = min(mux->max_pdu, rem_len); } diff --git a/nimble/controller/test/src/ble_ll_isoal.c b/nimble/controller/test/src/ble_ll_isoal.c index 6423ed7252..cfb9d74cf0 100644 --- a/nimble/controller/test/src/ble_ll_isoal.c +++ b/nimble/controller/test/src/ble_ll_isoal.c @@ -634,6 +634,45 @@ test_ial_broadcast_large_sdu_bis(const struct test_ial_broadcast_large_sdu_bis_c test_ial_teardown(&mux); } +TEST_CASE_SELF(test_ial_bis_unf_brd_bv_09_c) { + const struct test_ial_broadcast_large_sdu_bis_cfg cfg = { + .NSE = 12, + .Framed = 0, + .Framing_Mode = 0, + .BN = 6, + .SDU_Interval = 20000, + .ISO_Interval = 40000, + }; + + test_ial_broadcast_large_sdu_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_unf_brd_bv_10_c) { + const struct test_ial_broadcast_large_sdu_bis_cfg cfg = { + .NSE = 6, + .Framed = 0, + .Framing_Mode = 0, + .BN = 4, + .SDU_Interval = 20000, + .ISO_Interval = 20000, + }; + + test_ial_broadcast_large_sdu_bis(&cfg); +} + +TEST_CASE_SELF(test_ial_bis_unf_brd_bv_11_c) { + const struct test_ial_broadcast_large_sdu_bis_cfg cfg = { + .NSE = 8, + .Framed = 0, + .Framing_Mode = 0, + .BN = 4, + .SDU_Interval = 25000, + .ISO_Interval = 25000, + }; + + test_ial_broadcast_large_sdu_bis(&cfg); +} + TEST_CASE_SELF(test_ial_bis_fra_brd_bv_13_c) { const struct test_ial_broadcast_large_sdu_bis_cfg cfg = { .NSE = 10, @@ -1065,6 +1104,9 @@ TEST_SUITE(ble_ll_isoal_test_suite) { test_ial_bis_fra_brd_bv_29_c(); /* Broadcast Large SDU, BIS */ + test_ial_bis_unf_brd_bv_09_c(); + test_ial_bis_unf_brd_bv_10_c(); + test_ial_bis_unf_brd_bv_11_c(); test_ial_bis_fra_brd_bv_13_c(); test_ial_bis_fra_brd_bv_15_c(); From e98e2d239138a1b02cb2e474597a61b725d83fa1 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Wed, 19 Feb 2025 18:57:02 +0300 Subject: [PATCH 1227/1333] nimble/ll/test: Add tests for early HCI ISO SDU rx This adds tests for handling early SDU's. This has been seen with Harmony that violates SDU Interval. --- nimble/controller/test/src/ble_ll_isoal.c | 196 ++++++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/nimble/controller/test/src/ble_ll_isoal.c b/nimble/controller/test/src/ble_ll_isoal.c index cfb9d74cf0..b7c0aa2c35 100644 --- a/nimble/controller/test/src/ble_ll_isoal.c +++ b/nimble/controller/test/src/ble_ll_isoal.c @@ -1087,6 +1087,199 @@ TEST_CASE_SELF(test_ial_bis_unf_brd_bv_29_c) { test_ial_unframed_empty_pdus_with_llid_0b01(&cfg); } +TEST_CASE_SELF(test_ial_bis_unf_early_sdus) { + struct ble_ll_isoal_mux mux; + const uint32_t sdu_int = 7500; + const uint32_t iso_int = 7500; + /* const uint16_t mx_sdu = 40; */ + const uint8_t mx_pdu = 40; + const uint8_t bn = 4; + int num_completed_pkt; + int pdu_len; + uint8_t pdu[mx_pdu]; + uint32_t timestamp = 0; + uint8_t llid = 0xff; + + test_ial_setup(&mux, mx_pdu, iso_int, sdu_int, bn, 0, false, 0); + + test_sdu_enqueue(&mux, 21, 0, timestamp++); + test_sdu_enqueue(&mux, 32, 0, timestamp++); + test_sdu_enqueue(&mux, 40, 0, timestamp++); + + ble_ll_isoal_mux_event_start(&mux, timestamp + 50); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, pdu); + TEST_ASSERT(llid == 0b00, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == 21, "PDU length is incorrect %d", pdu_len); + test_pdu_verify(pdu, pdu_len, 0); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 1, &llid, pdu); + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == 0, "PDU length is incorrect %d", pdu_len); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 2, &llid, pdu); + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == 0, "PDU length is incorrect %d", pdu_len); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 3, &llid, pdu); + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == 0, "PDU length is incorrect %d", pdu_len); + + num_completed_pkt = ble_ll_isoal_mux_event_done(&mux); + TEST_ASSERT(num_completed_pkt == 1, + "num_completed_pkt is incorrect %d", num_completed_pkt); + + ble_ll_isoal_mux_event_start(&mux, timestamp + 50 + iso_int); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, pdu); + TEST_ASSERT(llid == 0b00, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == 32, "PDU length is incorrect %d", pdu_len); + test_pdu_verify(pdu, pdu_len, 0); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 1, &llid, pdu); + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == 0, "PDU length is incorrect %d", pdu_len); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 2, &llid, pdu); + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == 0, "PDU length is incorrect %d", pdu_len); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 3, &llid, pdu); + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == 0, "PDU length is incorrect %d", pdu_len); + + num_completed_pkt = ble_ll_isoal_mux_event_done(&mux); + TEST_ASSERT(num_completed_pkt == 1, + "num_completed_pkt is incorrect %d", num_completed_pkt); + + ble_ll_isoal_mux_event_start(&mux, timestamp + 50 + 2 * iso_int); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, pdu); + TEST_ASSERT(llid == 0b00, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == 40, "PDU length is incorrect %d", pdu_len); + test_pdu_verify(pdu, pdu_len, 0); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 1, &llid, pdu); + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == 0, "PDU length is incorrect %d", pdu_len); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 2, &llid, pdu); + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == 0, "PDU length is incorrect %d", pdu_len); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 3, &llid, pdu); + TEST_ASSERT(llid == 0b01, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == 0, "PDU length is incorrect %d", pdu_len); + + num_completed_pkt = ble_ll_isoal_mux_event_done(&mux); + TEST_ASSERT(num_completed_pkt == 1, + "num_completed_pkt is incorrect %d", num_completed_pkt); + + test_ial_teardown(&mux); +} + +TEST_CASE_SELF(test_ial_bis_fra_early_sdus) { + struct ble_ll_isoal_mux mux; + const uint32_t sdu_int = 87072; + const uint32_t iso_int = 87500; + const uint16_t mx_sdu = 32; + const uint8_t mx_pdu = 37; + const uint8_t bn = 2; + int num_completed_pkt; + int pdu_len; + uint8_t pdu[mx_pdu]; + uint32_t timestamp = 0; + uint8_t llid = 0xff; + + test_ial_setup(&mux, mx_pdu, iso_int, sdu_int, bn, 0, true, 0); + + for (int seq_num = 0; seq_num < 10; seq_num++) { + test_sdu_enqueue(&mux, mx_sdu, seq_num, timestamp++); + } + + ble_ll_isoal_mux_event_start(&mux, timestamp); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, pdu); + TEST_ASSERT(llid == 0b10, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == mx_pdu, "PDU length is incorrect %d", pdu_len); + test_pdu_verify(&pdu[5], mx_sdu, 0); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 1, &llid, pdu); + TEST_ASSERT(llid == 0b10, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == mx_pdu, "PDU length is incorrect %d", pdu_len); + test_pdu_verify(&pdu[5], mx_sdu, 0); + + num_completed_pkt = ble_ll_isoal_mux_event_done(&mux); + TEST_ASSERT(num_completed_pkt == 2, + "num_completed_pkt is incorrect %d", num_completed_pkt); + + ble_ll_isoal_mux_event_start(&mux, timestamp); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, pdu); + TEST_ASSERT(llid == 0b10, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == mx_pdu, "PDU length is incorrect %d", pdu_len); + test_pdu_verify(&pdu[5], mx_sdu, 0); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 1, &llid, pdu); + TEST_ASSERT(llid == 0b10, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == mx_pdu, "PDU length is incorrect %d", pdu_len); + test_pdu_verify(&pdu[5], mx_sdu, 0); + + num_completed_pkt = ble_ll_isoal_mux_event_done(&mux); + TEST_ASSERT(num_completed_pkt == 2, + "num_completed_pkt is incorrect %d", num_completed_pkt); + + ble_ll_isoal_mux_event_start(&mux, timestamp); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, pdu); + TEST_ASSERT(llid == 0b10, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == mx_pdu, "PDU length is incorrect %d", pdu_len); + test_pdu_verify(&pdu[5], mx_sdu, 0); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 1, &llid, pdu); + TEST_ASSERT(llid == 0b10, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == mx_pdu, "PDU length is incorrect %d", pdu_len); + test_pdu_verify(&pdu[5], mx_sdu, 0); + + num_completed_pkt = ble_ll_isoal_mux_event_done(&mux); + TEST_ASSERT(num_completed_pkt == 2, + "num_completed_pkt is incorrect %d", num_completed_pkt); + + ble_ll_isoal_mux_event_start(&mux, timestamp); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, pdu); + TEST_ASSERT(llid == 0b10, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == mx_pdu, "PDU length is incorrect %d", pdu_len); + test_pdu_verify(&pdu[5], mx_sdu, 0); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 1, &llid, pdu); + TEST_ASSERT(llid == 0b10, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == mx_pdu, "PDU length is incorrect %d", pdu_len); + test_pdu_verify(&pdu[5], mx_sdu, 0); + + num_completed_pkt = ble_ll_isoal_mux_event_done(&mux); + TEST_ASSERT(num_completed_pkt == 2, + "num_completed_pkt is incorrect %d", num_completed_pkt); + + ble_ll_isoal_mux_event_start(&mux, timestamp); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 0, &llid, pdu); + TEST_ASSERT(llid == 0b10, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == mx_pdu, "PDU length is incorrect %d", pdu_len); + test_pdu_verify(&pdu[5], mx_sdu, 0); + + pdu_len = ble_ll_isoal_mux_pdu_get(&mux, 1, &llid, pdu); + TEST_ASSERT(llid == 0b10, "LLID is incorrect %d", llid); + TEST_ASSERT(pdu_len == mx_pdu, "PDU length is incorrect %d", pdu_len); + test_pdu_verify(&pdu[5], mx_sdu, 0); + + num_completed_pkt = ble_ll_isoal_mux_event_done(&mux); + TEST_ASSERT(num_completed_pkt == 2, + "num_completed_pkt is incorrect %d", num_completed_pkt); + + test_ial_teardown(&mux); +} + TEST_SUITE(ble_ll_isoal_test_suite) { os_mbuf_test_setup(); @@ -1132,5 +1325,8 @@ TEST_SUITE(ble_ll_isoal_test_suite) { * Same as test_ial_bis_unf_brd_bv_29_c except encryption is required. */ + test_ial_bis_unf_early_sdus(); + test_ial_bis_fra_early_sdus(); + ble_ll_isoal_reset(); } From 47d1e9c27885779d93015f021aa379f631583a98 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Wed, 19 Feb 2025 18:46:17 +0300 Subject: [PATCH 1228/1333] nimble/ll/big: Force using framed PDUs if needed This fixes policy that shall force using framed PDUs when requirements for using unframed PDUs is not met. Fixes: LL/BIS/BRD/BV-20-C, LL/BIS/BRD/BV-21-C --- nimble/controller/src/ble_ll_iso_big.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 2a5e60de33..3ce5ddb746 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -1302,7 +1302,6 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len) bp.phy = BLE_PHY_CODED; } bp.interleaved = cmd->packing; - bp.framing = cmd->framing; bp.encrypted = cmd->encryption; memcpy(bp.broadcast_code, cmd->broadcast_code, 16); @@ -1310,11 +1309,22 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len) * to RTN */ bp.nse = MIN(cmd->rtn + 1, 0x0f);; - bp.bn = 1; bp.irc = MIN(cmd->rtn + 1, 0x0f); bp.pto = 0; - bp.iso_interval = bp.sdu_interval / 1250; - bp.max_pdu = bp.max_sdu; + + uint32_t iso_interval = bp.sdu_interval / 1250; + if (bp.sdu_interval > iso_interval * 1250) { + /* The requirements for using Unframed PDUs are not met */ + bp.framing = BLE_HCI_ISO_FRAMING_FRAMED_SEGMENTABLE; + bp.iso_interval = iso_interval + 1; + bp.bn = 2; + bp.max_pdu = bp.max_sdu + 5; + } else { + bp.framing = cmd->framing; + bp.iso_interval = iso_interval; + bp.bn = 1; + bp.max_pdu = bp.max_sdu; + } rc = ble_ll_iso_big_create(cmd->big_handle, cmd->adv_handle, cmd->num_bis, &bp); From 47eeaea89611170b89b953486f1555f863333dfc Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 20 Feb 2025 11:54:02 +0300 Subject: [PATCH 1229/1333] nimble/ll: Increase link-layer default stack size It has been seen that stack usage reaches 180 bytes running IAL/BIS/UNF/BRD/BV-30-C. his increases stack size by 20 bytes. --- nimble/controller/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index b6770f0879..7c3aeae9a8 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -671,7 +671,7 @@ syscfg.vals.'BLE_ISO_BROADCAST_SOURCE || BLE_ISO_BROADCAST_SINK': syscfg.vals.BLE_LL_ISO_BROADCASTER: BLE_LL_CFG_FEAT_LE_ENCRYPTION: 1 - BLE_LL_STACK_SIZE: 180 + BLE_LL_STACK_SIZE: 200 # Enable vendor event on assert in standalone build to make failed assertions in # controller code visible when connected to external host From 8bb24379f7821f1b6f0eaca50cfcb837288c1df6 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 20 Feb 2025 16:29:05 +0300 Subject: [PATCH 1230/1333] nimble/ll/iso: Add HCI LE ISO Transmit Test command This adds command implementation along with unit test. Fixes: LL/IST/BRD/BV-01-C --- .../include/controller/ble_ll_iso.h | 42 +++- nimble/controller/src/ble_ll_hci.c | 6 + nimble/controller/src/ble_ll_hci_supp_cmd.c | 6 + nimble/controller/src/ble_ll_iso.c | 187 ++++++++++++++++- nimble/controller/src/ble_ll_iso_big.c | 22 +- nimble/controller/test/src/ble_ll_iso.c | 191 ++++++++++++++++++ nimble/controller/test/src/ble_ll_test.c | 2 + nimble/include/nimble/hci_common.h | 5 + 8 files changed, 435 insertions(+), 26 deletions(-) create mode 100644 nimble/controller/test/src/ble_ll_iso.c diff --git a/nimble/controller/include/controller/ble_ll_iso.h b/nimble/controller/include/controller/ble_ll_iso.h index 768dd9923e..8d6cbde562 100644 --- a/nimble/controller/include/controller/ble_ll_iso.h +++ b/nimble/controller/include/controller/ble_ll_iso.h @@ -27,10 +27,30 @@ extern "C" { #endif +struct ble_ll_iso_data_path { + uint8_t data_path_id; + uint8_t enabled : 1; +}; +struct ble_ll_iso_test_mode { + struct { + uint32_t rand; + uint8_t payload_type; + uint8_t enabled : 1; + } transmit; +}; struct ble_ll_iso_conn { /* Connection handle */ uint16_t handle; + /* Maximum SDU size */ + uint16_t max_sdu; + + /* ISO Data Path */ + struct ble_ll_iso_data_path data_path; + + /* ISO Test Mode */ + struct ble_ll_iso_test_mode test_mode; + /* ISOAL Multiplexer */ struct ble_ll_isoal_mux mux; @@ -48,7 +68,6 @@ int ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, int ble_ll_iso_set_cig_param(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); int ble_ll_iso_set_cig_param_test(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); int ble_ll_iso_create_cis(const uint8_t *cmdbuf, uint8_t len); -int ble_ll_iso_disconnect_cmd(const struct ble_hci_lc_disconnect_cp *cmd); int ble_ll_iso_remove_cig(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); int ble_ll_iso_accept_cis_req(const uint8_t *cmdbuf, uint8_t len); int ble_ll_iso_reject_cis_req(const uint8_t *cmdbuf, uint8_t len); @@ -59,10 +78,10 @@ int ble_ll_iso_big_create_sync(const uint8_t *cmdbuf, uint8_t len); int ble_ll_iso_big_terminate_sync(const uint8_t *cmdbuf, uint8_t len); int ble_ll_iso_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); int ble_ll_iso_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); -int ble_ll_iso_transmit_test(const uint8_t *cmdbuf, uint8_t len); +int ble_ll_iso_transmit_test(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); int ble_ll_iso_receive_test(const uint8_t *cmdbuf, uint8_t len); int ble_ll_iso_read_counters_test(const uint8_t *cmdbuf, uint8_t len); -int ble_ll_iso_end_test(const uint8_t *cmdbuf, uint8_t len); +int ble_ll_iso_end_test(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen); void ble_ll_iso_init(void); void ble_ll_iso_reset(void); @@ -70,11 +89,20 @@ void ble_ll_iso_reset(void); /* ISO Data handler */ int ble_ll_iso_data_in(struct os_mbuf *om); -int ble_ll_iso_pdu_get(struct ble_ll_iso_conn *conn, uint8_t idx, uint8_t *llid, void *dptr); +int ble_ll_iso_pdu_get(struct ble_ll_iso_conn *conn, uint8_t idx, uint32_t pkt_counter, uint8_t *llid, void *dptr); + +struct ble_ll_iso_conn_init_param { + uint32_t iso_interval_us; + uint32_t sdu_interval_us; + uint16_t conn_handle; + uint16_t max_sdu; + uint8_t max_pdu; + uint8_t framing; + uint8_t pte; + uint8_t bn; +}; -void ble_ll_iso_conn_init(struct ble_ll_iso_conn *conn, uint16_t conn_handle, - uint8_t max_pdu, uint32_t iso_interval_us, - uint32_t sdu_interval_us, uint8_t bn, uint8_t pte, uint8_t framing); +void ble_ll_iso_conn_init(struct ble_ll_iso_conn *conn, struct ble_ll_iso_conn_init_param *param); void ble_ll_iso_conn_free(struct ble_ll_iso_conn *conn); int ble_ll_iso_conn_event_start(struct ble_ll_iso_conn *conn, uint32_t timestamp); diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c index e969963ae0..07b0aec1c5 100644 --- a/nimble/controller/src/ble_ll_hci.c +++ b/nimble/controller/src/ble_ll_hci.c @@ -1284,6 +1284,9 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, case BLE_HCI_OCF_LE_TERMINATE_BIG: rc = ble_ll_iso_big_hci_terminate(cmdbuf, len); break; + case BLE_HCI_OCF_LE_ISO_TRANSMIT_TEST: + rc = ble_ll_iso_transmit_test(cmdbuf, len, rspbuf, rsplen); + break; #endif /* BLE_LL_ISO_BROADCASTER */ #if MYNEWT_VAL(BLE_LL_ISO) case BLE_HCI_OCF_LE_SETUP_ISO_DATA_PATH: @@ -1292,6 +1295,9 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf, case BLE_HCI_OCF_LE_REMOVE_ISO_DATA_PATH: rc = ble_ll_iso_remove_iso_data_path(cmdbuf, len, rspbuf, rsplen); break; + case BLE_HCI_OCF_LE_ISO_TEST_END: + rc = ble_ll_iso_end_test(cmdbuf, len, rspbuf, rsplen); + break; case BLE_HCI_OCF_LE_READ_ISO_TX_SYNC: rc = ble_ll_iso_read_tx_sync(cmdbuf, len, rspbuf, rsplen); break; diff --git a/nimble/controller/src/ble_ll_hci_supp_cmd.c b/nimble/controller/src/ble_ll_hci_supp_cmd.c index d9d6bd6045..31edf1c2aa 100644 --- a/nimble/controller/src/ble_ll_hci_supp_cmd.c +++ b/nimble/controller/src/ble_ll_hci_supp_cmd.c @@ -288,9 +288,15 @@ static const uint8_t octet_43 = OCTET( BIT(3) /* HCI LE Setup ISO Data Path */ BIT(4) /* HCI LE Remove ISO Data Path */ #endif +#if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER) + BIT(5) /* HCI LE ISO Transmit Test */ +#endif ); static const uint8_t octet_44 = OCTET( +#if MYNEWT_VAL(BLE_LL_ISO) + BIT(0) /* HCI LE ISO Test End */ +#endif #if BLE_LL_HOST_CONTROLLED_FEATURES BIT(1) /* HCI LE Set Host Feature */ #endif diff --git a/nimble/controller/src/ble_ll_iso.c b/nimble/controller/src/ble_ll_iso.c index 034996d5ff..03a31d5fab 100644 --- a/nimble/controller/src/ble_ll_iso.c +++ b/nimble/controller/src/ble_ll_iso.c @@ -46,6 +46,14 @@ ble_ll_iso_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen, return BLE_ERR_UNK_CONN_ID; } + if (conn->mux.bn == 0) { + return BLE_ERR_UNSUPPORTED; + } + + if (conn->data_path.enabled) { + return BLE_ERR_CMD_DISALLOWED; + } + /* Only input for now since we only support BIS */ if (cmd->data_path_dir) { return BLE_ERR_CMD_DISALLOWED; @@ -56,6 +64,9 @@ ble_ll_iso_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen, return BLE_ERR_CMD_DISALLOWED; } + conn->data_path.enabled = 1; + conn->data_path.data_path_id = cmd->data_path_id; + rsp->conn_handle = cmd->conn_handle; *rsplen = sizeof(*rsp); @@ -68,8 +79,23 @@ ble_ll_iso_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t cmdlen, { const struct ble_hci_le_remove_iso_data_path_cp *cmd = (const void *)cmdbuf; struct ble_hci_le_remove_iso_data_path_rp *rsp = (void *)rspbuf; + struct ble_ll_iso_conn *conn; + uint16_t conn_handle; + + conn_handle = le16toh(cmd->conn_handle); + + conn = ble_ll_iso_conn_find_by_handle(conn_handle); + if (!conn) { + return BLE_ERR_UNK_CONN_ID; + } + + /* Only input for now since we only support BIS */ + if (cmd->data_path_dir) { + return BLE_ERR_CMD_DISALLOWED; + } + + conn->data_path.enabled = 0; - /* XXX accepts anything for now */ rsp->conn_handle = cmd->conn_handle; *rsplen = sizeof(*rsp); @@ -101,6 +127,76 @@ ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t cmdlen, return 0; } +int +ble_ll_iso_transmit_test(const uint8_t *cmdbuf, uint8_t cmdlen, uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_le_iso_transmit_test_cp *cmd = (const void *)cmdbuf; + struct ble_hci_le_iso_transmit_test_rp *rsp = (void *)rspbuf; + struct ble_ll_iso_conn *conn; + uint16_t handle; + + handle = le16toh(cmd->conn_handle); + + conn = ble_ll_iso_conn_find_by_handle(handle); + if (!conn) { + return BLE_ERR_UNK_CONN_ID; + } + + if (conn->mux.bn == 0) { + return BLE_ERR_UNSUPPORTED; + } + + if (conn->data_path.enabled) { + return BLE_ERR_CMD_DISALLOWED; + } + + if (cmd->payload_type > BLE_HCI_PAYLOAD_TYPE_MAXIMUM_LENGTH) { + return BLE_ERR_INV_LMP_LL_PARM; + } + + conn->data_path.enabled = 1; + conn->data_path.data_path_id = BLE_HCI_ISO_DATA_PATH_ID_HCI; + conn->test_mode.transmit.enabled = 1; + conn->test_mode.transmit.payload_type = cmd->payload_type; + + rsp->conn_handle = cmd->conn_handle; + + *rsplen = sizeof(*rsp); + + return 0; +} + +int +ble_ll_iso_end_test(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen) +{ + const struct ble_hci_le_iso_test_end_cp *cmd = (const void *)cmdbuf; + struct ble_hci_le_iso_test_end_rp *rsp = (void *)rspbuf; + struct ble_ll_iso_conn *iso_conn; + uint16_t handle; + + handle = le16toh(cmd->conn_handle); + iso_conn = ble_ll_iso_conn_find_by_handle(handle); + if (!iso_conn) { + return BLE_ERR_UNK_CONN_ID; + } + + if (!iso_conn->test_mode.transmit.enabled) { + return BLE_ERR_UNSUPPORTED; + } + + iso_conn->data_path.enabled = 0; + iso_conn->test_mode.transmit.enabled = 0; + + rsp->conn_handle = cmd->conn_handle; + rsp->received_sdu_count = 0; + rsp->missed_sdu_count = 0; + rsp->failed_sdu_count = 0; + + *rsplen = sizeof(*rsp); + + return 0; +} + struct ble_ll_iso_conn * ble_ll_iso_conn_find_by_handle(uint16_t conn_handle) { @@ -213,26 +309,93 @@ ble_ll_iso_data_in(struct os_mbuf *om) return 0; } +static int +ble_ll_iso_test_pdu_get(struct ble_ll_iso_conn *conn, uint8_t idx, uint32_t pkt_counter, uint8_t *llid, uint8_t *dptr) +{ + uint32_t payload_len; + uint16_t rem_len; + uint8_t sdu_idx; + uint8_t pdu_idx; + int pdu_len; + + BLE_LL_ASSERT(!conn->mux.framed); + + sdu_idx = idx / conn->mux.pdu_per_sdu; + pdu_idx = idx - sdu_idx * conn->mux.pdu_per_sdu; + + switch (conn->test_mode.transmit.payload_type) { + case BLE_HCI_PAYLOAD_TYPE_ZERO_LENGTH: + *llid = 0b00; + pdu_len = 0; + break; + case BLE_HCI_PAYLOAD_TYPE_VARIABLE_LENGTH: + payload_len = max(conn->test_mode.transmit.rand + (sdu_idx * pdu_idx), 4); + + rem_len = payload_len - pdu_idx * conn->mux.max_pdu; + if (rem_len == 0) { + *llid = 0b01; + pdu_len = 0; + } else { + *llid = rem_len > conn->mux.max_pdu; + pdu_len = min(conn->mux.max_pdu, rem_len); + } + + memset(dptr, 0, pdu_len); + + if (payload_len == rem_len) { + put_le32(dptr, pkt_counter); + } + + break; + case BLE_HCI_PAYLOAD_TYPE_MAXIMUM_LENGTH: + payload_len = conn->max_sdu; + + rem_len = payload_len - pdu_idx * conn->mux.max_pdu; + if (rem_len == 0) { + *llid = 0b01; + pdu_len = 0; + } else { + *llid = rem_len > conn->mux.max_pdu; + pdu_len = min(conn->mux.max_pdu, rem_len); + } + + memset(dptr, 0, pdu_len); + + if (payload_len == rem_len) { + put_le32(dptr, pkt_counter); + } + + break; + default: + BLE_LL_ASSERT(0); + } + + return pdu_len; +} + int -ble_ll_iso_pdu_get(struct ble_ll_iso_conn *conn, uint8_t idx, uint8_t *llid, void *dptr) +ble_ll_iso_pdu_get(struct ble_ll_iso_conn *conn, uint8_t idx, uint32_t pkt_counter, uint8_t *llid, void *dptr) { + if (conn->test_mode.transmit.enabled) { + return ble_ll_iso_test_pdu_get(conn, idx, pkt_counter, llid, dptr); + } + return ble_ll_isoal_mux_pdu_get(&conn->mux, idx, llid, dptr); } void -ble_ll_iso_conn_init(struct ble_ll_iso_conn *conn, uint16_t conn_handle, - uint8_t max_pdu, uint32_t iso_interval_us, - uint32_t sdu_interval_us, uint8_t bn, uint8_t pte, - uint8_t framing) +ble_ll_iso_conn_init(struct ble_ll_iso_conn *conn, struct ble_ll_iso_conn_init_param *param) { os_sr_t sr; memset(conn, 0, sizeof(*conn)); - conn->handle = conn_handle; - ble_ll_isoal_mux_init(&conn->mux, max_pdu, iso_interval_us, sdu_interval_us, - bn, pte, BLE_LL_ISOAL_MUX_IS_FRAMED(framing), - framing == BLE_HCI_ISO_FRAMING_FRAMED_UNSEGMENTED); + conn->handle = param->conn_handle; + conn->max_sdu = param->max_sdu; + + ble_ll_isoal_mux_init(&conn->mux, param->max_pdu, param->iso_interval_us, param->sdu_interval_us, + param->bn, param->pte, BLE_LL_ISOAL_MUX_IS_FRAMED(param->framing), + param->framing == BLE_HCI_ISO_FRAMING_FRAMED_UNSEGMENTED); OS_ENTER_CRITICAL(sr); STAILQ_INSERT_TAIL(&ll_iso_conn_q, conn, iso_conn_q_next); @@ -254,6 +417,10 @@ ble_ll_iso_conn_free(struct ble_ll_iso_conn *conn) int ble_ll_iso_conn_event_start(struct ble_ll_iso_conn *conn, uint32_t timestamp) { + if (conn->test_mode.transmit.enabled) { + conn->test_mode.transmit.rand = ble_ll_rand() % conn->max_sdu; + } + ble_ll_isoal_mux_event_start(&conn->mux, timestamp); return 0; diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 3ce5ddb746..1454ed6a5c 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -683,7 +683,7 @@ ble_ll_iso_big_subevent_pdu_cb(uint8_t *dptr, void *arg, uint8_t *hdr_byte) } #if 1 - pdu_len = ble_ll_iso_pdu_get(&bis->conn, idx, &llid, dptr); + pdu_len = ble_ll_iso_pdu_get(&bis->conn, idx, big->bis_counter + idx, &llid, dptr); #else llid = 0; pdu_len = big->max_pdu; @@ -923,12 +923,18 @@ static int ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, struct big_params *bp) { + struct ble_ll_iso_conn_init_param conn_init_param = { + .iso_interval_us = bp->iso_interval * 1250, + .sdu_interval_us = bp->sdu_interval, + .max_sdu = bp->max_sdu, + .max_pdu = bp->max_pdu, + .framing = bp->framing, + .bn = bp->bn, + }; struct ble_ll_iso_big *big = NULL; struct ble_ll_iso_bis *bis; struct ble_ll_adv_sm *advsm; uint32_t seed_aa; - uint16_t conn_handle; - uint8_t pte; uint8_t gc; uint8_t idx; int rc; @@ -984,9 +990,9 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, /* Core 5.3, Vol 6, Part B, 4.4.6.6 */ gc = bp->nse / bp->bn; if (bp->irc == gc) { - pte = 0; + conn_init_param.pte = 0; } else { - pte = bp->pto * (gc - bp->irc); + conn_init_param.pte = bp->pto * (gc - bp->irc); } /* Allocate BISes */ @@ -1005,11 +1011,9 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, bis->num = big->num_bis; bis->crc_init = (big->crc_init << 8) | (big->num_bis); - conn_handle = BLE_LL_CONN_HANDLE(BLE_LL_CONN_HANDLE_TYPE_BIS, idx); + conn_init_param.conn_handle = BLE_LL_CONN_HANDLE(BLE_LL_CONN_HANDLE_TYPE_BIS, idx); - ble_ll_iso_conn_init(&bis->conn, conn_handle, bp->max_pdu, - bp->iso_interval * 1250, bp->sdu_interval, - bp->bn, pte, bp->framing); + ble_ll_iso_conn_init(&bis->conn, &conn_init_param); } bis_pool_free -= num_bis; diff --git a/nimble/controller/test/src/ble_ll_iso.c b/nimble/controller/test/src/ble_ll_iso.c new file mode 100644 index 0000000000..2f88214c93 --- /dev/null +++ b/nimble/controller/test/src/ble_ll_iso.c @@ -0,0 +1,191 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef max +#define max(a, b) ((a) > (b) ? (a) : (b)) +#endif + +#define TSPX_max_tx_nse 3 +#define TSPX_max_tx_payload 32 + +/* LL.TS.p24 4.11.2 Common Parameters */ +struct test_ll_common_params { + uint8_t TxNumBIS; + uint8_t RxNumBIS; + uint8_t NumDataPDUs; + uint8_t RTN; + uint8_t NSE; + uint8_t IRC; + uint8_t PTO; + uint8_t BN; + uint8_t Transport_Latency; + uint8_t SDU_Interval; + uint8_t ISO_Interval; + uint8_t BIG_Sync_Timeout; + uint8_t Data_Size; + uint8_t PHY; + uint8_t Packing; + uint8_t Framing; + uint8_t Encryption; + uint8_t PADV_Interval; + uint8_t Sync_Timeout; +}; + +const struct test_ll_common_params test_ll_common_params_bn_1 = { + .TxNumBIS = 1, + .RxNumBIS = 1, + .NumDataPDUs = 20, + .RTN = TSPX_max_tx_nse, + .NSE = TSPX_max_tx_nse, + .IRC = TSPX_max_tx_nse, + .PTO = 0, + .BN = 1, + .Transport_Latency = 20, + .SDU_Interval = 10, + .ISO_Interval = 10, + .BIG_Sync_Timeout = 100, + .Data_Size = 0, + .PHY = 0x01, + .Packing = 0x00, + .Framing = 0x00, + .Encryption = 0x00, + .PADV_Interval = 20, + .Sync_Timeout = 100, +}; + +TEST_CASE_SELF(test_ll_ist_brd_bv_01_c) { + const uint8_t payload_types[] = { + BLE_HCI_PAYLOAD_TYPE_ZERO_LENGTH, + BLE_HCI_PAYLOAD_TYPE_VARIABLE_LENGTH, + BLE_HCI_PAYLOAD_TYPE_MAXIMUM_LENGTH + }; + const struct test_ll_common_params *params = &test_ll_common_params_bn_1; + struct ble_hci_le_setup_iso_data_path_cp setup_iso_data_path_cp; + struct ble_hci_le_setup_iso_data_path_rp setup_iso_data_path_rp; + struct ble_hci_le_iso_transmit_test_cp iso_transmit_test_cp; + struct ble_hci_le_iso_transmit_test_rp iso_transmit_test_rp; + struct ble_hci_le_iso_test_end_cp iso_test_end_cp; + struct ble_hci_le_iso_test_end_rp iso_test_end_rp; + struct ble_ll_iso_conn_init_param conn_param = { + .iso_interval_us = params->SDU_Interval * 1000, + .sdu_interval_us = params->SDU_Interval * 1000, + .conn_handle = 0x0001, + .max_sdu = TSPX_max_tx_payload, + .max_pdu = TSPX_max_tx_payload, + .framing = params->Framing, + .bn = params->BN + }; + struct ble_ll_iso_conn conn; + uint8_t payload_type; + uint8_t pdu[100]; + uint8_t llid; + uint8_t rsplen = 0; + int rc; + + ble_ll_iso_conn_init(&conn, &conn_param); + + for (uint8_t i = 0; i < ARRAY_SIZE(payload_types); i++) { + payload_type = payload_types[i]; + + /* 2. The Upper Tester sends the HCI_LE_ISO_Transmit_Test command with Payload_Type as + * specified in Table 4.12-2 and receives a successful HCI_Command_Complete event from the IUT in response. + */ + rsplen = 0xFF; + iso_transmit_test_cp.conn_handle = htole16(conn.handle); + iso_transmit_test_cp.payload_type = payload_type; + rc = ble_ll_iso_transmit_test((uint8_t *)&iso_transmit_test_cp, sizeof(iso_transmit_test_cp), + (uint8_t *)&iso_transmit_test_rp, &rsplen); + TEST_ASSERT(rc == 0); + TEST_ASSERT(rsplen == sizeof(iso_transmit_test_rp)); + TEST_ASSERT(iso_transmit_test_rp.conn_handle == iso_transmit_test_cp.conn_handle); + + /* 3. The IUT sends isochronous data PDUs with Payload as specified in Table 4.12-2. The SDU + * Count value meets the requirements for unframed PDUs as specified in [14] Section 7.1. + * 4. Repeat step 3 for a total of 5 payloads. + */ + for (uint8_t j = 0; j < 5; j++) { + rc = ble_ll_iso_conn_event_start(&conn, 30000); + TEST_ASSERT(rc == 0); + + for (uint8_t k = 0; k < conn_param.bn; k++) { + llid = 0xFF; + rc = ble_ll_iso_pdu_get(&conn, k, k, &llid, pdu); + if (payload_type == BLE_HCI_PAYLOAD_TYPE_ZERO_LENGTH) { + TEST_ASSERT(rc == 0); + TEST_ASSERT(llid == 0b00); + } else if (payload_type == BLE_HCI_PAYLOAD_TYPE_VARIABLE_LENGTH) { + TEST_ASSERT(rc >= 4); + TEST_ASSERT(llid == 0b00); + } else if (payload_type == BLE_HCI_PAYLOAD_TYPE_MAXIMUM_LENGTH) { + TEST_ASSERT(rc == conn_param.max_pdu); + TEST_ASSERT(llid == 0b00); + } + } + + rc = ble_ll_iso_conn_event_done(&conn); + TEST_ASSERT(rc == 0); + } + + /* 5. The Upper Tester sends an HCI_LE_Setup_ISO_Data_Path command to the IUT. + * 6. The IUT sends an HCI_Command_Complete event to the Upper Tester with Status set to 0x0C. + */ + setup_iso_data_path_cp.conn_handle = htole16(conn.handle); + setup_iso_data_path_cp.data_path_dir = 0x00; + setup_iso_data_path_cp.data_path_id = 0x00; + rc = ble_ll_iso_setup_iso_data_path((uint8_t *)&setup_iso_data_path_cp, sizeof(setup_iso_data_path_cp), + (uint8_t *)&setup_iso_data_path_rp, &rsplen); + TEST_ASSERT(rc == 0x0C); + + /* 7. The Upper Tester sends the HCI_LE_ISO_Test_End command to the IUT and receives an + * HCI_Command_Status event from the IUT with the Status field set to Success. The returned + * Received_SDU_Count, Missed_SDU_Count, and Failed_SDU_Count are all zero. + */ + rsplen = 0xFF; + iso_test_end_cp.conn_handle = htole16(conn.handle); + rc = ble_ll_iso_end_test((uint8_t *)&iso_test_end_cp, sizeof(iso_test_end_cp), + (uint8_t *)&iso_test_end_rp, &rsplen); + TEST_ASSERT(rc == 0); + TEST_ASSERT(rsplen == sizeof(iso_test_end_rp)); + TEST_ASSERT(iso_test_end_rp.conn_handle == iso_test_end_cp.conn_handle); + TEST_ASSERT(iso_test_end_rp.received_sdu_count == 0); + TEST_ASSERT(iso_test_end_rp.missed_sdu_count == 0); + TEST_ASSERT(iso_test_end_rp.failed_sdu_count == 0); + } + + ble_ll_iso_conn_free(&conn); +} + +TEST_SUITE(ble_ll_iso_test_suite) { + ble_ll_iso_init(); + + test_ll_ist_brd_bv_01_c(); + + ble_ll_iso_reset(); +} diff --git a/nimble/controller/test/src/ble_ll_test.c b/nimble/controller/test/src/ble_ll_test.c index 7bfbf9bd21..818430c577 100644 --- a/nimble/controller/test/src/ble_ll_test.c +++ b/nimble/controller/test/src/ble_ll_test.c @@ -26,6 +26,7 @@ TEST_SUITE_DECL(ble_ll_aa_test_suite); TEST_SUITE_DECL(ble_ll_crypto_test_suite); TEST_SUITE_DECL(ble_ll_csa2_test_suite); TEST_SUITE_DECL(ble_ll_isoal_test_suite); +TEST_SUITE_DECL(ble_ll_iso_test_suite); int main(int argc, char **argv) @@ -34,6 +35,7 @@ main(int argc, char **argv) ble_ll_crypto_test_suite(); ble_ll_csa2_test_suite(); ble_ll_isoal_test_suite(); + ble_ll_iso_test_suite(); return tu_any_failed; } diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index f1d2eb46d3..24843de3c2 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -1647,6 +1647,11 @@ struct ble_hci_vs_set_scan_cfg_cp { #define BLE_HCI_PRIVACY_NETWORK (0) #define BLE_HCI_PRIVACY_DEVICE (1) +/* --- LE iso transmit test payload type options (OCF 0x0070) */ +#define BLE_HCI_PAYLOAD_TYPE_ZERO_LENGTH (0x00) +#define BLE_HCI_PAYLOAD_TYPE_VARIABLE_LENGTH (0x01) +#define BLE_HCI_PAYLOAD_TYPE_MAXIMUM_LENGTH (0x02) + /* --- LE set advertising coded PHY options (OCF 0x007F) */ #define BLE_HCI_ADVERTISING_PHY_OPT_NO_PREF 0x0 #define BLE_HCI_ADVERTISING_PHY_OPT_S2_PREF 0x1 From dc8ba53cf6c2feaeb6d1d50729ba729fa0bf209f Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Mon, 18 Nov 2024 16:05:44 +0100 Subject: [PATCH 1231/1333] nimble/ll: Advertising Coding Selection support --- nimble/controller/include/controller/ble_ll.h | 7 ++-- nimble/controller/src/ble_ll.c | 17 +++++++++- nimble/controller/src/ble_ll_scan_aux.c | 34 +++++++++++++++++-- nimble/controller/syscfg.yml | 7 ++++ 4 files changed, 60 insertions(+), 5 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 752ca43e97..ab75edcba3 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -285,6 +285,8 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats; #define BLE_LL_FEAT_CONN_SUBRATING (0x0002000000000) #define BLE_LL_FEAT_CONN_SUBRATING_HOST (0x0004000000000) #define BLE_LL_FEAT_CHANNEL_CLASS (0x0008000000000) +#define BLE_LL_FEAT_ADV_CODING_SEL (0x0010000000000) +#define BLE_LL_FEAT_ADV_CODING_SEL_HOST (0x0020000000000) #define BLE_LL_FEAT_CS (0x0400000000000) #define BLE_LL_FEAT_CS_HOST_SUPPORT (0x0800000000000) #define BLE_LL_FEAT_CS_PCT_QUALITY_IND (0x1000000000000) @@ -298,8 +300,9 @@ extern STATS_SECT_DECL(ble_ll_stats) ble_ll_stats; #define BLE_LL_CONN_CLEAR_FEATURE(connsm, feature) (connsm->conn_features &= ~(feature)) /* All the features which can be controlled by the Host */ -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) -#define BLE_LL_HOST_CONTROLLED_FEATURES (BLE_LL_FEAT_CONN_SUBRATING_HOST) +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) | \ + MYNEWT_VAL(BLE_LL_ADV_CODING_SELECTION) +#define BLE_LL_HOST_CONTROLLED_FEATURES (1) #else #define BLE_LL_HOST_CONTROLLED_FEATURES (0) #endif diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index cc11a93b46..a0d6dbbc03 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -86,6 +86,17 @@ static int8_t g_ble_ll_tx_power_phy_current; int8_t g_ble_ll_tx_power_compensation; int8_t g_ble_ll_rx_power_compensation; +#if BLE_LL_HOST_CONTROLLED_FEATURES +static const uint64_t g_ble_ll_host_controlled_features = +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE) + BLE_LL_FEAT_CONN_SUBRATING_HOST | +#endif +#if MYNEWT_VAL(BLE_LL_ADV_CODING_SELECTION) + BLE_LL_FEAT_ADV_CODING_SEL_HOST | +#endif + 0; +#endif + /* Supported states */ #if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER) #define BLE_LL_S_NCA ((uint64_t)1 << 0) @@ -1491,7 +1502,7 @@ ble_ll_set_host_feat(const uint8_t *cmdbuf, uint8_t len) } mask = (uint64_t)1 << (cmd->bit_num); - if (!(mask & BLE_LL_HOST_CONTROLLED_FEATURES)) { + if (!(mask & g_ble_ll_host_controlled_features)) { return BLE_ERR_UNSUPPORTED; } @@ -1947,6 +1958,10 @@ ble_ll_init(void) features |= BLE_LL_FEAT_PERIODIC_ADV_ADI; #endif +#if MYNEWT_VAL(BLE_LL_ADV_CODING_SELECTION) + features |= BLE_LL_FEAT_ADV_CODING_SEL; +#endif + lldata->ll_supp_features = features; /* Initialize random number generation */ diff --git a/nimble/controller/src/ble_ll_scan_aux.c b/nimble/controller/src/ble_ll_scan_aux.c index 535c9c6470..0cb734a240 100644 --- a/nimble/controller/src/ble_ll_scan_aux.c +++ b/nimble/controller/src/ble_ll_scan_aux.c @@ -84,6 +84,9 @@ struct ble_ll_scan_aux_data { #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) int8_t rpa_index; #endif +#if MYNEWT_VAL(BLE_LL_ADV_CODING_SELECTION) + uint8_t pri_phy_mode; +#endif }; #define AUX_MEMPOOL_SIZE (OS_MEMPOOL_SIZE( \ @@ -216,7 +219,8 @@ ble_ll_scan_aux_need_truncation(struct ble_ll_scan_aux_data *aux) } static struct ble_hci_ev * -ble_ll_hci_ev_alloc_ext_adv_report_for_aux(struct ble_ll_scan_addr_data *addrd, +ble_ll_hci_ev_alloc_ext_adv_report_for_aux(struct ble_mbuf_hdr_rxinfo *rxinfo, + struct ble_ll_scan_addr_data *addrd, struct ble_ll_scan_aux_data *aux) { struct ble_hci_ev_le_subev_ext_adv_rpt *hci_subev; @@ -257,6 +261,16 @@ ble_ll_hci_ev_alloc_ext_adv_report_for_aux(struct ble_ll_scan_addr_data *addrd, report->tx_power = 0x7f; report->rssi = 0x7f; report->periodic_itvl = 0; + +#if MYNEWT_VAL(BLE_LL_ADV_CODING_SELECTION) + if (aux->pri_phy_mode == BLE_PHY_MODE_CODED_500KBPS) { + report->pri_phy = 0x04; + } + if (rxinfo->phy_mode == BLE_PHY_MODE_CODED_500KBPS) { + report->sec_phy = 0x04; + } +#endif + if (addrd->targeta) { report->evt_type |= BLE_HCI_ADV_DIRECT_MASK; report->dir_addr_type = addrd->targeta_type; @@ -326,6 +340,12 @@ ble_ll_hci_ev_update_ext_adv_report_from_aux(struct ble_hci_ev *hci_ev, } report->sec_phy = rxhdr->rxinfo.phy; +#if MYNEWT_VAL(BLE_LL_ADV_CODING_SELECTION) + if (rxhdr->rxinfo.phy_mode == BLE_PHY_MODE_CODED_500KBPS) { + report->sec_phy = 0x04; + } +#endif + /* Strip PDU header and ext header, leave only AD */ os_mbuf_adj(rxpdu, 3 + eh_len); @@ -419,6 +439,12 @@ ble_ll_hci_ev_update_ext_adv_report_from_ext(struct ble_hci_ev *hci_ev, report->periodic_itvl = 0; report->data_len = 0; +#if MYNEWT_VAL(BLE_LL_ADV_CODING_SELECTION) + if (rxinfo->phy_mode == BLE_PHY_MODE_CODED_500KBPS) { + report->pri_phy = 0x04; + } +#endif + /* Now parse extended header... */ if (eh_flags & (1 << BLE_LL_EXT_ADV_ADVA_BIT)) { @@ -609,7 +635,7 @@ ble_ll_hci_ev_send_ext_adv_report_for_aux(struct os_mbuf *rxpdu, hci_ev = aux->hci_ev; aux->hci_ev = NULL; } else { - hci_ev = ble_ll_hci_ev_alloc_ext_adv_report_for_aux(addrd, aux); + hci_ev = ble_ll_hci_ev_alloc_ext_adv_report_for_aux(&rxhdr->rxinfo, addrd, aux); if (!hci_ev) { aux->hci_state = BLE_LL_SCAN_AUX_H_DONE; return -1; @@ -1077,6 +1103,10 @@ ble_ll_scan_aux_rx_isr_end_on_ext(struct ble_ll_scan_sm *scansm, aux->pri_phy = rxinfo->phy; aux->aux_ptr = aux_ptr; +#if MYNEWT_VAL(BLE_LL_ADV_CODING_SELECTION) + aux->pri_phy_mode = rxinfo->phy_mode; +#endif + if (addrd.adva) { memcpy(aux->adva, addrd.adva, 6); aux->adva_type = addrd.adva_type; diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 7c3aeae9a8..1e830dbecb 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -357,6 +357,13 @@ syscfg.defs: restrictions: - '(BLE_VERSION >= 53) if 1' + BLE_LL_ADV_CODING_SELECTION: + description: > + Enables support Advertising Coding Selection. + value: 0 + restrictions: + - '(BLE_VERSION >= 54) if 1' + BLE_LL_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: description: > This option is used to enable/disable support for From 5ab995f8f262a9827f4ead69fb8934e8244c6825 Mon Sep 17 00:00:00 2001 From: Mynewt Bot Date: Thu, 13 Mar 2025 14:04:52 +0000 Subject: [PATCH 1232/1333] porting: Update ports syscfg --- porting/npl/riot/include/syscfg/syscfg.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 35d448cc7a..51aa76911d 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -1304,6 +1304,10 @@ #define MYNEWT_VAL_BLE_LL_ADD_STRICT_SCHED_PERIODS (0) #endif +#ifndef MYNEWT_VAL_BLE_LL_ADV_CODING_SELECTION +#define MYNEWT_VAL_BLE_LL_ADV_CODING_SELECTION (0) +#endif + #ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_CONN_PARAM_REQ #define MYNEWT_VAL_BLE_LL_CFG_FEAT_CONN_PARAM_REQ (MYNEWT_VAL_BLE_LL_ROLE_CENTRAL || MYNEWT_VAL_BLE_LL_ROLE_PERIPHERAL) #endif From 4e744fabcef7b0929e1346b22df9f1ca0ffe0d96 Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Wed, 26 Mar 2025 17:31:14 +0100 Subject: [PATCH 1233/1333] nimble/ll: Set ext adv params v2 command fix Now adv state machine contains also advertising phy options fields instead of trying to store information about coded phy mode in pri_phy and sec_phy fields. Those fields should always contain just PHY information without mode, because few other functions assume it is this way (for example ble_ll_adv_put_aux_ptr) --- nimble/controller/src/ble_ll_adv.c | 52 +++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c index 84f6e789d6..e62b2c3a66 100644 --- a/nimble/controller/src/ble_ll_adv.c +++ b/nimble/controller/src/ble_ll_adv.c @@ -155,6 +155,10 @@ struct ble_ll_adv_sm uint8_t events; uint8_t pri_phy; uint8_t sec_phy; +#if MYNEWT_VAL(BLE_VERSION) >= 54 + uint8_t pri_phy_opt; + uint8_t sec_phy_opt; +#endif #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) struct os_mbuf *periodic_adv_data; struct os_mbuf *periodic_new_data; @@ -1125,6 +1129,9 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch) uint8_t end_trans; uint32_t txstart; struct ble_ll_adv_sm *advsm; +#if MYNEWT_VAL(BLE_LL_PHY) && MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + uint8_t phy_mode; +#endif /* Get the state machine for the event */ advsm = (struct ble_ll_adv_sm *)sch->cb_arg; @@ -1146,10 +1153,15 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch) #if MYNEWT_VAL(BLE_LL_PHY) /* Set phy mode */ #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +#if MYNEWT_VAL(BLE_VERSION) >= 54 + phy_mode = ble_ll_phy_to_phy_mode(advsm->pri_phy, advsm->pri_phy_opt); +#else + phy_mode = ble_ll_phy_to_phy_mode(advsm->pri_phy, BLE_HCI_LE_PHY_CODED_ANY); +#endif if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) { ble_phy_mode_set(BLE_PHY_MODE_1M, BLE_PHY_MODE_1M); } else { - ble_phy_mode_set(advsm->pri_phy, advsm->pri_phy); + ble_phy_mode_set(phy_mode, phy_mode); } #else ble_phy_mode_set(BLE_PHY_MODE_1M, BLE_PHY_MODE_1M); @@ -1274,6 +1286,9 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch) struct ble_ll_adv_sm *advsm; ble_phy_tx_pducb_t pducb; struct ble_ll_adv_aux *aux; +#if MYNEWT_VAL(BLE_LL_PHY) + uint8_t phy_mode; +#endif /* Get the state machine for the event */ advsm = (struct ble_ll_adv_sm *)sch->cb_arg; @@ -1290,8 +1305,13 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch) BLE_LL_ASSERT(rc == 0); #if MYNEWT_VAL(BLE_LL_PHY) +#if MYNEWT_VAL(BLE_VERSION) >= 54 + phy_mode = ble_ll_phy_to_phy_mode(advsm->sec_phy, advsm->sec_phy_opt); +#else + phy_mode = ble_ll_phy_to_phy_mode(advsm->sec_phy, BLE_HCI_LE_PHY_CODED_ANY); +#endif /* Set phy mode */ - ble_phy_mode_set(advsm->sec_phy, advsm->sec_phy); + ble_phy_mode_set(phy_mode, phy_mode); #endif /* Set the power */ @@ -3695,21 +3715,18 @@ ble_ll_adv_ext_set_param(const uint8_t *cmdbuf, uint8_t len, } #if MYNEWT_VAL(BLE_VERSION) >= 54 -static uint8_t -ble_ll_adv_ext_phy_mode_get(uint8_t phy, uint8_t phy_opt) +static inline uint8_t +ble_ll_adv_convert_phy_opt(uint8_t cmd_phy_opt) { - if (phy != BLE_HCI_LE_PHY_CODED) { - return phy; - } - - switch (phy_opt) { + switch (cmd_phy_opt) { + case BLE_HCI_ADVERTISING_PHY_OPT_NO_PREF: + return BLE_HCI_LE_PHY_CODED_ANY; case BLE_HCI_ADVERTISING_PHY_OPT_S2_PREF: case BLE_HCI_ADVERTISING_PHY_OPT_S2_REQ: - return BLE_PHY_MODE_CODED_500KBPS; - case BLE_HCI_ADVERTISING_PHY_OPT_NO_PREF: + return BLE_HCI_LE_PHY_CODED_S2_PREF; case BLE_HCI_ADVERTISING_PHY_OPT_S8_PREF: case BLE_HCI_ADVERTISING_PHY_OPT_S8_REQ: - return BLE_PHY_MODE_CODED_125KBPS; + return BLE_HCI_LE_PHY_CODED_S8_PREF; default: BLE_LL_ASSERT(0); } @@ -3727,7 +3744,8 @@ ble_ll_adv_ext_set_param_v2(const uint8_t *cmdbuf, uint8_t len, return BLE_ERR_INV_HCI_CMD_PARMS; } - if ((cmd->pri_phy_opt > 4) || (cmd->sec_phy_opt > 4)) { + if ((cmd->pri_phy_opt > BLE_HCI_ADVERTISING_PHY_OPT_S8_REQ) || + (cmd->sec_phy_opt > BLE_HCI_ADVERTISING_PHY_OPT_S8_REQ)) { return BLE_ERR_INV_HCI_CMD_PARMS; } @@ -3738,8 +3756,12 @@ ble_ll_adv_ext_set_param_v2(const uint8_t *cmdbuf, uint8_t len, advsm = ble_ll_adv_sm_get(cmd->params_v1.adv_handle); - advsm->pri_phy = ble_ll_adv_ext_phy_mode_get(cmd->params_v1.pri_phy, cmd->pri_phy_opt); - advsm->sec_phy = ble_ll_adv_ext_phy_mode_get(cmd->params_v1.sec_phy, cmd->sec_phy_opt); + if (advsm->pri_phy == BLE_HCI_LE_PHY_CODED) { + advsm->pri_phy_opt = ble_ll_adv_convert_phy_opt(cmd->pri_phy_opt); + } + if (advsm->sec_phy == BLE_HCI_LE_PHY_CODED) { + advsm->sec_phy_opt = ble_ll_adv_convert_phy_opt(cmd->sec_phy_opt); + } return rc; } From 02ceea9f54908939c123d9ebfaee6f3ab53801f5 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 7 Apr 2025 10:15:30 +0200 Subject: [PATCH 1234/1333] nimble/ll/big: Ensure the Segmentation Header fits the SDU As a workaround for SDU Interval issue, if the user requests the Framed PDUs to be used, make sure the Segmentation Header fits the PDU, so that we could avoid the segmentation. --- nimble/controller/src/ble_ll_iso_big.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_iso_big.c b/nimble/controller/src/ble_ll_iso_big.c index 1454ed6a5c..774465315e 100644 --- a/nimble/controller/src/ble_ll_iso_big.c +++ b/nimble/controller/src/ble_ll_iso_big.c @@ -1327,7 +1327,15 @@ ble_ll_iso_big_hci_create(const uint8_t *cmdbuf, uint8_t len) bp.framing = cmd->framing; bp.iso_interval = iso_interval; bp.bn = 1; - bp.max_pdu = bp.max_sdu; + if (cmd->framing == BLE_HCI_ISO_FRAMING_UNFRAMED) { + bp.max_pdu = bp.max_sdu; + } else { + /** + * XXX: The requirements for using Unframed PDUs are met but the user + * requested Framed PDUs explicitly. Ensure the PDU fits the Segmentation Header. + */ + bp.max_pdu = bp.max_sdu + 5; + } } rc = ble_ll_iso_big_create(cmd->big_handle, cmd->adv_handle, cmd->num_bis, From f3c49e185dc1a2571bd90ce30a0d061da95c5e7c Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Mon, 31 Mar 2025 12:41:32 +0200 Subject: [PATCH 1235/1333] controller: add missing os/util.h include ble_ll_hci_vs.c module uses ARRAY_SIZE, defined in os/util.h. --- nimble/controller/src/ble_ll_hci_vs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c index df8b688697..2027ce61a6 100644 --- a/nimble/controller/src/ble_ll_hci_vs.c +++ b/nimble/controller/src/ble_ll_hci_vs.c @@ -27,6 +27,7 @@ #include "controller/ble_ll_scan.h" #include "controller/ble_hw.h" #include "controller/ble_fem.h" +#include "os/util.h" #include "ble_ll_conn_priv.h" #include "ble_ll_priv.h" #include "controller/ble_ll_resolv.h" From 21957a460553022f792aedfd8ff6b079e168bbb7 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Mon, 31 Mar 2025 11:59:37 +0200 Subject: [PATCH 1236/1333] porting: fix missing include for stdio It is needed for vprinf --- porting/npl/freertos/include/nimble/nimble_npl_os_log.h | 1 + 1 file changed, 1 insertion(+) diff --git a/porting/npl/freertos/include/nimble/nimble_npl_os_log.h b/porting/npl/freertos/include/nimble/nimble_npl_os_log.h index 5fcce6aeec..24315a21a7 100644 --- a/porting/npl/freertos/include/nimble/nimble_npl_os_log.h +++ b/porting/npl/freertos/include/nimble/nimble_npl_os_log.h @@ -21,6 +21,7 @@ #define _NIMBLE_NPL_OS_LOG_H_ #include +#include /* Example on how to use macro to generate module logging functions */ #define BLE_NPL_LOG_IMPL(lvl) \ From 71eaa1cc519483783babf1e898cac914bc333d45 Mon Sep 17 00:00:00 2001 From: Mynewt Bot Date: Fri, 11 Apr 2025 16:23:20 +0000 Subject: [PATCH 1237/1333] porting: Update ports syscfg --- porting/npl/riot/include/syscfg/syscfg.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 51aa76911d..788bb102f7 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -29,6 +29,10 @@ #undef MYNEWT_VAL_LINK_TEMPLATE +#ifndef MYNEWT_VAL_MAIN_STACK_FILL +#define MYNEWT_VAL_MAIN_STACK_FILL (0) +#endif + #ifndef MYNEWT_VAL_MAIN_STACK_SIZE #define MYNEWT_VAL_MAIN_STACK_SIZE (768) #endif From 1922030943d8b21daab92a604b9911a41e3d30ed Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 22 Apr 2025 16:27:36 +0200 Subject: [PATCH 1238/1333] nimble/phy: Fix resolving list entry removal in nRF5X g_nrf_irk_list is array of uint32_t while IRKs are 4 words long so this needs to be accounted for. This was causing IRK corruption if entry removed was not the first entry in memory. --- nimble/drivers/nrf5x/src/ble_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/drivers/nrf5x/src/ble_hw.c b/nimble/drivers/nrf5x/src/ble_hw.c index 9a46fa6c85..f8cd59f098 100644 --- a/nimble/drivers/nrf5x/src/ble_hw.c +++ b/nimble/drivers/nrf5x/src/ble_hw.c @@ -482,7 +482,7 @@ ble_hw_resolv_list_rmv(int index) if (index < g_nrf_num_irks) { --g_nrf_num_irks; - irk_entry = &g_nrf_irk_list[index]; + irk_entry = &g_nrf_irk_list[4 * index]; if (g_nrf_num_irks > index) { memmove(irk_entry, irk_entry + 4, 16 * (g_nrf_num_irks - index)); } From 4c113a93f887c7dfd7bb38df00937dee3b62a666 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 22 Apr 2025 16:31:10 +0200 Subject: [PATCH 1239/1333] nimble/phy: Fix resolving list entry removal in nRF51 g_nrf_irk_list is array of uint32_t while IRKs are 4 words long so this needs to be accounted for. This was causing IRK corruption if entry removed was not the first entry in memory. --- nimble/drivers/nrf51/src/ble_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/drivers/nrf51/src/ble_hw.c b/nimble/drivers/nrf51/src/ble_hw.c index fb6e844b0f..fc07506efe 100644 --- a/nimble/drivers/nrf51/src/ble_hw.c +++ b/nimble/drivers/nrf51/src/ble_hw.c @@ -452,7 +452,7 @@ ble_hw_resolv_list_rmv(int index) if (index < g_nrf_num_irks) { --g_nrf_num_irks; - irk_entry = &g_nrf_irk_list[index]; + irk_entry = &g_nrf_irk_list[4 * index]; if (g_nrf_num_irks > index) { memmove(irk_entry, irk_entry + 4, 16 * (g_nrf_num_irks - index)); } From bcc77cefad58fb664c7c5913be01351b3f2788e9 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 22 Apr 2025 17:26:54 +0200 Subject: [PATCH 1240/1333] ci: Update CodeQL actions ubuntu 20.04 runner is being deprecated. --- .github/workflows/codeql.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index cc4b6c74b3..9c5c927091 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -27,7 +27,7 @@ jobs: # - https://gh.io/supported-runners-and-hardware-resources # - https://gh.io/using-larger-runners # Consider using larger runners for possible analysis time improvements. - runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-20.04' }} + runs-on: ubuntu-latest timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} permissions: actions: read From 590eefe16e207af2fe577360a4b599a1f6db20c1 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 4 Apr 2025 15:55:50 +0200 Subject: [PATCH 1241/1333] nimble/eatt: Minor formatting fixes Refactor some of the returns to keep constant styling trough ble_eatt.c --- nimble/host/src/ble_eatt.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c index 3ec9bd3b8e..047a087641 100644 --- a/nimble/host/src/ble_eatt.c +++ b/nimble/host/src/ble_eatt.c @@ -87,6 +87,7 @@ ble_eatt_find_not_busy(uint16_t conn_handle) return eatt; } } + return NULL; } @@ -100,8 +101,8 @@ ble_eatt_find_by_conn_handle(uint16_t conn_handle) return eatt; } } - return NULL; + return NULL; } static struct ble_eatt * @@ -114,8 +115,8 @@ ble_eatt_find_by_conn_handle_and_busy_op(uint16_t conn_handle, uint8_t op) return eatt; } } - return NULL; + return NULL; } static struct ble_eatt * @@ -130,8 +131,8 @@ ble_eatt_find(uint16_t conn_handle, uint16_t cid) return eatt; } } - return NULL; + return NULL; } static int @@ -197,6 +198,7 @@ ble_eatt_alloc(void) STAILQ_INIT(&eatt->eatt_tx_q); ble_npl_event_init(&eatt->setup_ev, ble_eatt_setup_cb, eatt); ble_npl_event_init(&eatt->wakeup_ev, ble_eatt_wakeup_cb, eatt); + return eatt; } @@ -356,6 +358,7 @@ ble_gatt_eatt_write_cl_cb(uint16_t conn_handle, } ble_eatt_start(conn_handle); + return 0; } @@ -431,6 +434,7 @@ ble_eatt_gap_event(struct ble_gap_event *event, void *arg) default: break; } + return 0; } @@ -445,6 +449,7 @@ ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op) } eatt->client_op = op; + return eatt->chan->scid; } @@ -497,6 +502,7 @@ ble_eatt_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom) error: os_mbuf_free_chain(txom); + return rc; } From 0061748426d18f8fe13767986c186ec543716afa Mon Sep 17 00:00:00 2001 From: Victor Luque Date: Thu, 24 Apr 2025 11:09:19 +0200 Subject: [PATCH 1242/1333] port: add ble_npl_hw_is_in_critical implementation --- porting/npl/freertos/include/nimble/nimble_npl_os.h | 11 +++++++++++ porting/npl/freertos/src/npl_os_freertos.c | 2 ++ 2 files changed, 13 insertions(+) diff --git a/porting/npl/freertos/include/nimble/nimble_npl_os.h b/porting/npl/freertos/include/nimble/nimble_npl_os.h index 00f64ba2d7..44d216c879 100644 --- a/porting/npl/freertos/include/nimble/nimble_npl_os.h +++ b/porting/npl/freertos/include/nimble/nimble_npl_os.h @@ -65,6 +65,8 @@ struct ble_npl_sem { SemaphoreHandle_t handle; }; +extern volatile uint32_t s_critical_nesting; + /* * Simple APIs are just defined as static inline below, but some are a bit more * complex or require some global state variables and thus are defined in .c @@ -282,14 +284,23 @@ static inline uint32_t ble_npl_hw_enter_critical(void) { vPortEnterCritical(); + s_critical_nesting++; return 0; } static inline void ble_npl_hw_exit_critical(uint32_t ctx) { + if (s_critical_nesting > 0) { + s_critical_nesting--; + } vPortExitCritical(); +} +static inline bool +ble_npl_hw_is_in_critical(void) +{ + return (s_critical_nesting > 0); } #ifdef __cplusplus diff --git a/porting/npl/freertos/src/npl_os_freertos.c b/porting/npl/freertos/src/npl_os_freertos.c index a671a80ea0..584333c318 100644 --- a/porting/npl/freertos/src/npl_os_freertos.c +++ b/porting/npl/freertos/src/npl_os_freertos.c @@ -27,6 +27,8 @@ #include NIMBLE_NPL_OS_EXTRA_INCLUDE #endif +volatile uint32_t s_critical_nesting = 0; + static inline bool in_isr(void) { From 3db68d930d19b81ed6f1b33ce413847863359eb3 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 7 May 2025 17:22:28 +0530 Subject: [PATCH 1243/1333] nimble/host: Add support for Anonymous address type Devices can send anonymous address type during advertising Add support for this address type needed while Adding device to filter accept list --- nimble/host/src/ble_gap.c | 6 ++++-- nimble/include/nimble/ble.h | 6 ++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 6369b44788..64f96bd27d 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -2404,7 +2404,8 @@ ble_gap_wl_tx_add(const ble_addr_t *addr) { struct ble_hci_le_add_whte_list_cp cmd; - if (addr->type > BLE_ADDR_RANDOM) { + if (addr->type > BLE_ADDR_RANDOM && + addr->type != BLE_ADDR_ANONYMOUS) { return BLE_HS_EINVAL; } @@ -2459,7 +2460,8 @@ ble_gap_wl_set(const ble_addr_t *addrs, uint8_t white_list_count) for (i = 0; i < white_list_count; i++) { if (addrs[i].type != BLE_ADDR_PUBLIC && - addrs[i].type != BLE_ADDR_RANDOM) { + addrs[i].type != BLE_ADDR_RANDOM && + addrs[i].type != BLE_ADDR_ANONYMOUS) { rc = BLE_HS_EINVAL; goto done; diff --git a/nimble/include/nimble/ble.h b/nimble/include/nimble/ble.h index d5e41a37c8..0370f966cd 100644 --- a/nimble/include/nimble/ble.h +++ b/nimble/include/nimble/ble.h @@ -359,6 +359,12 @@ enum ble_error_codes */ #define BLE_ADDR_RANDOM_ID (0x03) +/** + * Bluetooth Device Address Type: Anonymous + * (Corresponds to devices sending anonymous advertisements). + */ +#define BLE_ADDR_ANONYMOUS (0xFF) + /** @} */ /** From 760df6f6eb2dcfd940be0d79d62aa97436364730 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 8 May 2025 14:42:57 +0200 Subject: [PATCH 1244/1333] apps/bttester: Add error check for setting adv data Add proper error check to improve robustness. --- apps/bttester/src/btp_gap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index f6747b0f49..b9d5040491 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -531,6 +531,10 @@ start_advertising(const void *cmd, uint16_t cmd_len, #else err = ble_gap_adv_set_data(buf, buf_len); #endif + if (err) { + SYS_LOG_ERR("Failed to set advertising data; rc=%d", err); + return BTP_STATUS_FAILED; + } if (sd_len) { buf_len = 0; From 912e38e24e9a3b5576aa219c3aa064b4243af441 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 8 May 2025 18:26:00 +0200 Subject: [PATCH 1245/1333] ci: Make CodeQL fail_on_error.py more robust Avoid hardcoded index which causes issues if json structure is modified. --- .github/workflows/fail_on_error.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/fail_on_error.py b/.github/workflows/fail_on_error.py index 29791742b2..e500e24df1 100755 --- a/.github/workflows/fail_on_error.py +++ b/.github/workflows/fail_on_error.py @@ -11,7 +11,10 @@ def codeql_sarif_contain_error(filename): for run in s.get('runs', []): rules_metadata = run['tool']['driver']['rules'] if not rules_metadata: - rules_metadata = run['tool']['extensions'][0]['rules'] + for extension in run['tool']['extensions']: + if 'rules' in extension: + rules_metadata = extension['rules'] + break for res in run.get('results', []): if 'ruleIndex' in res: From 4c144c992208d8af6d94f424d40fddda84661b14 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 9 May 2025 14:29:16 +0200 Subject: [PATCH 1246/1333] apps/bttester: Fix loop condition Fix condition for stopping loop. Include scan response data in sd construction. --- apps/bttester/src/btp_gap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index b9d5040491..5d7e34f340 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -496,7 +496,7 @@ start_advertising(const void *cmd, uint16_t cmd_len, i += ad[adv_len].data_len; } - for (sd_len = 0U; i < cp->scan_rsp_len; sd_len++) { + for (sd_len = 0U; i < (cp->adv_data_len + cp->scan_rsp_len); sd_len++) { if (sd_len >= ARRAY_SIZE(sd)) { SYS_LOG_ERR("sd[] Out of memory"); return BTP_STATUS_FAILED; From 7f7ab2d5129989f1aa29093b2c2e247bcf8b8f3c Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 9 May 2025 14:37:11 +0200 Subject: [PATCH 1247/1333] apps/bttester: Enable adv filter policy when accept list is set Add support for setting filter policy. When set, policy will allow to process scan and request only from devices in the Filter Accept List. Also, introduce the flag to control this setting during advertising setup. --- apps/bttester/src/btp_gap.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 5d7e34f340..b7f7090e8f 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -64,6 +64,8 @@ static ble_addr_t peer_id_addr; static ble_addr_t peer_ota_addr; static bool encrypted = false; +static bool use_filter_policy = false; + static struct os_callout update_params_co; static struct btp_gap_conn_param_update_cmd update_params; @@ -515,6 +517,10 @@ start_advertising(const void *cmd, uint16_t cmd_len, #if MYNEWT_VAL(BLE_EXT_ADV) adv_params.own_addr_type = own_addr_type; + if (use_filter_policy) { + adv_params.filter_policy = BLE_HCI_ADV_FILT_BOTH; + } + err = ble_gap_ext_adv_configure(0, &adv_params, NULL, gap_event_cb, NULL); if (err) { SYS_LOG_ERR("Failed to configure extended advertiser; rc=%d", err); @@ -1988,6 +1994,8 @@ set_filter_accept_list(const void *cmd, uint16_t cmd_len, SYS_LOG_DBG(""); + use_filter_policy = cp->list_len != 0; + /* * Check if the nb of bytes received matches the len of addrs list. * Then set the filter accept list. From cc1418744e867888c0eef48606a1b7d1aa8b0b66 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 9 May 2025 18:15:51 +0200 Subject: [PATCH 1248/1333] apps/bttester: Set scannable flag if data is present Set scannable option for adv_params when scan response data is provided. Ensure extended advertising is configured correctly. --- apps/bttester/src/btp_gap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index b7f7090e8f..0f0fcb31f3 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -455,7 +455,7 @@ start_advertising(const void *cmd, uint16_t cmd_len, struct btp_gap_start_advertising_rp *rp = rsp; uint8_t buf[BLE_HS_ADV_MAX_SZ]; uint8_t buf_len = 0; - uint8_t adv_len, sd_len; + uint8_t adv_len, sd_len = 0; uint8_t addr_type; uint32_t duration; int err; @@ -517,6 +517,11 @@ start_advertising(const void *cmd, uint16_t cmd_len, #if MYNEWT_VAL(BLE_EXT_ADV) adv_params.own_addr_type = own_addr_type; + + if (sd_len != 0 && adv_params.legacy_pdu) { + adv_params.scannable = 1; + } + if (use_filter_policy) { adv_params.filter_policy = BLE_HCI_ADV_FILT_BOTH; } From ca51138f488703884301e907a7219dcf12b7982a Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Tue, 28 Jan 2025 17:33:06 +0100 Subject: [PATCH 1249/1333] apps: bttester: Add notify multiple command Add functionality to utilize BTP notify multiple command. Existing notify handling parses non-existent data. --- apps/bttester/src/btp/btp_gatt.h | 7 ++++++ apps/bttester/src/btp_gatt.c | 39 +++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/apps/bttester/src/btp/btp_gatt.h b/apps/bttester/src/btp/btp_gatt.h index 8da6f43df8..7849263de3 100644 --- a/apps/bttester/src/btp/btp_gatt.h +++ b/apps/bttester/src/btp/btp_gatt.h @@ -320,6 +320,13 @@ struct btp_gatt_set_mult_val_cmd { uint8_t data[0]; } __packed; +#define BTP_GATT_NOTIFY_MULTIPLE 0x21 +struct btp_gatt_notify_mult_val_cmd { + ble_addr_t addr; + uint16_t count; + uint16_t handles[0]; +} __packed; + /* GATT events */ #define BTP_GATT_EV_NOTIFICATION 0x80 struct btp_gatt_notification_ev { diff --git a/apps/bttester/src/btp_gatt.c b/apps/bttester/src/btp_gatt.c index 157e7da1cb..cbfe1f8fee 100644 --- a/apps/bttester/src/btp_gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -95,7 +95,7 @@ struct find_attr_data { struct notify_mult_cb_data { size_t tuple_cnt; - uint16_t handles[0]; + uint16_t handles[8]; }; static int @@ -1950,6 +1950,38 @@ set_mult(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +static uint8_t +notify_mult(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_gatt_notify_mult_val_cmd *cp = cmd; + struct notify_mult_cb_data cb_data; + int i; + + + if (cmd_len < sizeof(*cp) || + (cmd_len != (sizeof(*cp) + + (le16toh(cp->count) * sizeof(cp->handles[0]))))) { + + return BTP_STATUS_FAILED; + } + + if (le16toh(cp->count) > sizeof(cb_data.handles)) { + SYS_LOG_ERR("Too many handles to notify"); + return BTP_STATUS_FAILED; + } + + for (i = 0; i < cp->count; i++) { + cb_data.handles[i] = le16toh(cp->handles[i]); + } + + cb_data.tuple_cnt = cp->count; + + ble_gap_conn_foreach_handle(notify_multiple, (void *)&cb_data); + + return BTP_STATUS_SUCCESS; +} + static uint8_t change_database(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) @@ -2137,6 +2169,11 @@ static const struct btp_handler handlers[] = { .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = set_mult, }, + { + .opcode = BTP_GATT_NOTIFY_MULTIPLE, + .expect_len = BTP_HANDLER_LENGTH_VARIABLE, + .func = notify_mult, + }, }; int From 75a3ec3ad2caca69e08788c7a429d2f7d25de6dc Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Wed, 29 Jan 2025 16:59:24 +0100 Subject: [PATCH 1250/1333] apps: bttester: Remove set_mult support This command has no corresponding auto-pts procedure. Notify is now utilized via function specially designed for notify purpose. --- apps/bttester/src/btp/btp_gatt.h | 6 ---- apps/bttester/src/btp_gatt.c | 48 -------------------------------- 2 files changed, 54 deletions(-) diff --git a/apps/bttester/src/btp/btp_gatt.h b/apps/bttester/src/btp/btp_gatt.h index 7849263de3..6c57ade092 100644 --- a/apps/bttester/src/btp/btp_gatt.h +++ b/apps/bttester/src/btp/btp_gatt.h @@ -314,12 +314,6 @@ struct btp_gatt_change_database_cmd { uint8_t visibility; } __packed; -#define BTP_GATT_SET_MULT_VALUE 0x20 -struct btp_gatt_set_mult_val_cmd { - uint16_t count; - uint8_t data[0]; -} __packed; - #define BTP_GATT_NOTIFY_MULTIPLE 0x21 struct btp_gatt_notify_mult_val_cmd { ble_addr_t addr; diff --git a/apps/bttester/src/btp_gatt.c b/apps/bttester/src/btp_gatt.c index cbfe1f8fee..b6ac433c0f 100644 --- a/apps/bttester/src/btp_gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -1907,49 +1907,6 @@ notify_multiple(uint16_t conn_handle, void *arg) return rc; } -static uint8_t -set_mult(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_gatt_set_mult_val_cmd *cp = cmd; - struct ble_gatt_notif tuples[16]; - int i; - int rc = 0; - int data_idx = 0; - uint16_t data_len; - struct notify_mult_cb_data cb_data; - - for (i = 0; i < cp->count; i++) { - tuples[i].handle = get_le16(cp->data + data_idx); - data_idx += 2; - tuples[i].value = ble_hs_mbuf_att_pkt(); - if (tuples[i].value == NULL) { - rc = ENOMEM; - goto done; - } - - data_len = get_le16(cp->data + data_idx); - data_idx += 2; - - os_mbuf_append(tuples[i].value, cp->data + data_idx, data_len); - data_idx += data_len; - } - - for (i = 0; i < cp->count; i++) { - ble_att_svr_write_local(tuples[i].handle, tuples[i].value); - cb_data.handles[i] = tuples[i].handle; - } - - cb_data.tuple_cnt = cp->count; - ble_gap_conn_foreach_handle(notify_multiple, (void *)&cb_data); -done: - if (rc != 0) { - return BTP_STATUS_FAILED; - } - - return BTP_STATUS_SUCCESS; -} - static uint8_t notify_mult(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) @@ -2164,11 +2121,6 @@ static const struct btp_handler handlers[] = { .expect_len = sizeof(struct btp_gatt_get_attribute_value_cmd), .func = get_attr_val, }, - { - .opcode = BTP_GATT_SET_MULT_VALUE, - .expect_len = BTP_HANDLER_LENGTH_VARIABLE, - .func = set_mult, - }, { .opcode = BTP_GATT_NOTIFY_MULTIPLE, .expect_len = BTP_HANDLER_LENGTH_VARIABLE, From a021c1cc21e8111f53970c7fca99fe65258cb3d0 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 16 May 2025 14:00:20 +0200 Subject: [PATCH 1251/1333] nimble/bttester: Add option to enable/disable leaudio support Add syscfg fields to allow user to enable/disable leaudio. Some testcases were failing due to having leaudio services and performing writes which resulted in errors. --- apps/bttester/syscfg.yml | 45 ++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 1be2945575..646c1b66ab 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -22,6 +22,9 @@ syscfg.defs: Disable any NimBLE configuration in bttester app. This is useful for building bttester apps with custom configuration. value: 0 + BTTESTER_LEAUDIO: + description: 'Enable NimBLE LE Audio support in bttester app' + value: 0 BTTESTER_UART_BAUD: description: 'Console UART baud rate.' value: '115200' @@ -117,9 +120,31 @@ syscfg.vals: BLE_STORE_CONFIG_PERSIST: 0 +syscfg.vals.BTTESTER_LEAUDIO: + BLE_ISO: 1 + BLE_AUDIO: 1 + BLE_AUDIO_BROADCAST_SINK: 1 + BLE_AUDIO_BROADCAST_SINK_MAX: 2 + BLE_AUDIO_MAX_CODEC_RECORDS: 3 + BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 + BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: 1 + BLE_ROLE_BROADCASTER: 1 + BLE_ISO_BROADCAST_SOURCE: 1 + BLE_ISO_BROADCAST_SINK: 1 + BLE_ISO_MAX_BISES: 3 + BLE_ISO_MAX_BIGS: 3 + BLE_EXT_ADV: 1 + BLE_PHY_2M: 1 + BLE_EXT_ADV_MAX_SIZE: 40 + BLE_PERIODIC_ADV: 1 + BLE_MULTI_ADV_INSTANCES: 3 + BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ: 256 + BLE_SVC_AUDIO_BASS_SUB_NUM_MAX: 10 + syscfg.vals.!BTTESTER_NODEFAULT: BLE_VERSION: 54 + BTTESTER_LEAUDIO: 1 BLE_L2CAP_COC_MAX_NUM: 5 BLE_L2CAP_SIG_MAX_PROCS: 2 BLE_L2CAP_ENHANCED_COC: 1 @@ -140,26 +165,6 @@ syscfg.vals.!BTTESTER_NODEFAULT: BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM: 0 BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH: 6 - BLE_ISO: 1 - BLE_AUDIO: 1 - BLE_AUDIO_BROADCAST_SINK: 1 - BLE_AUDIO_BROADCAST_SINK_MAX: 2 - BLE_AUDIO_MAX_CODEC_RECORDS: 3 - BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 - BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: 1 - BLE_ROLE_BROADCASTER: 1 - BLE_ISO_BROADCAST_SOURCE: 1 - BLE_ISO_BROADCAST_SINK: 1 - BLE_ISO_MAX_BISES: 3 - BLE_ISO_MAX_BIGS: 3 - BLE_EXT_ADV: 1 - BLE_PHY_2M: 1 - BLE_EXT_ADV_MAX_SIZE: 40 - BLE_PERIODIC_ADV: 1 - BLE_MULTI_ADV_INSTANCES: 3 - BLE_SVC_AUDIO_BASS_METADATA_MAX_SZ: 256 - BLE_SVC_AUDIO_BASS_SUB_NUM_MAX: 10 - BLE_MESH: 1 BLE_MESH_SHELL: 0 BLE_MESH_PROV: 1 From 9d0217ac673c7912df98608f1f53ca6479515285 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 20 Mar 2025 12:50:20 +0100 Subject: [PATCH 1252/1333] host/store: remove unneeded base64/base64.h include The include is not needed in ble_store_config.c. It also makes it impossible to compile config store without persistent storage out of mynewt. Signed-off-by: Gerard Marull-Paretas --- nimble/host/store/config/src/ble_store_config.c | 1 - 1 file changed, 1 deletion(-) diff --git a/nimble/host/store/config/src/ble_store_config.c b/nimble/host/store/config/src/ble_store_config.c index b800a4ee58..741c73a5f5 100644 --- a/nimble/host/store/config/src/ble_store_config.c +++ b/nimble/host/store/config/src/ble_store_config.c @@ -23,7 +23,6 @@ #include "sysinit/sysinit.h" #include "syscfg/syscfg.h" #include "host/ble_hs.h" -#include "base64/base64.h" #include "os/util.h" #include "store/config/ble_store_config.h" #include "ble_store_config_priv.h" From 6c30f96322f7650bddbde40f7aa4ee74f837b54b Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 22 May 2025 12:54:58 +0200 Subject: [PATCH 1253/1333] apps/bttester: Refactor reporting supported commands Implement new way for reporting supported commands. Now only commands with registered handler will be present in the queried response. --- apps/bttester/src/btp/bttester.h | 3 ++ apps/bttester/src/btp_bap.c | 14 ++------- apps/bttester/src/btp_core.c | 8 ++--- apps/bttester/src/btp_gap.c | 51 ++------------------------------ apps/bttester/src/btp_gatt.c | 34 ++------------------- apps/bttester/src/btp_gatt_cl.c | 31 ++----------------- apps/bttester/src/btp_l2cap.c | 11 ++----- apps/bttester/src/btp_mesh.c | 28 ++---------------- apps/bttester/src/btp_pacs.c | 9 ++---- apps/bttester/src/bttester.c | 19 ++++++++++++ 10 files changed, 38 insertions(+), 170 deletions(-) diff --git a/apps/bttester/src/btp/bttester.h b/apps/bttester/src/btp/bttester.h index 6e1fb3a87b..ac56d8846d 100644 --- a/apps/bttester/src/btp/bttester.h +++ b/apps/bttester/src/btp/bttester.h @@ -93,6 +93,9 @@ struct btp_handler { void tester_register_command_handlers(uint8_t service, const struct btp_handler *handlers, size_t num); + +uint16_t tester_supported_commands(uint8_t service, uint8_t *cmds); + void tester_send_buf(uint8_t service, uint8_t opcode, uint8_t index, struct os_mbuf *buf); diff --git a/apps/bttester/src/btp_bap.c b/apps/bttester/src/btp_bap.c index 37ecedb0e4..7ff489bb92 100644 --- a/apps/bttester/src/btp_bap.c +++ b/apps/bttester/src/btp_bap.c @@ -139,18 +139,8 @@ supported_commands(const void *cmd, uint16_t cmd_len, { struct btp_bap_read_supported_commands_rp *rp = rsp; - /* octet 0 */ - tester_set_bit(rp->data, BTP_BAP_READ_SUPPORTED_COMMANDS); - tester_set_bit(rp->data, BTP_BAP_BROADCAST_SOURCE_SETUP); - tester_set_bit(rp->data, BTP_BAP_BROADCAST_SOURCE_RELEASE); - tester_set_bit(rp->data, BTP_BAP_BROADCAST_ADV_START); - tester_set_bit(rp->data, BTP_BAP_BROADCAST_ADV_STOP); - - /* octet 1 */ - tester_set_bit(rp->data, BTP_BAP_BROADCAST_SOURCE_START); - tester_set_bit(rp->data, BTP_BAP_BROADCAST_SOURCE_STOP); - - *rsp_len = sizeof(*rp) + 2; + *rsp_len = tester_supported_commands(BTP_SERVICE_ID_BAP, rp->data); + *rsp_len += sizeof(*rp); return BTP_STATUS_SUCCESS; } diff --git a/apps/bttester/src/btp_core.c b/apps/bttester/src/btp_core.c index a1eafb300c..65f3491a19 100644 --- a/apps/bttester/src/btp_core.c +++ b/apps/bttester/src/btp_core.c @@ -35,12 +35,8 @@ supported_commands(const void *cmd, uint16_t cmd_len, { struct btp_core_read_supported_commands_rp *rp = rsp; - tester_set_bit(rp->data, BTP_CORE_READ_SUPPORTED_COMMANDS); - tester_set_bit(rp->data, BTP_CORE_READ_SUPPORTED_SERVICES); - tester_set_bit(rp->data, BTP_CORE_REGISTER_SERVICE); - tester_set_bit(rp->data, BTP_CORE_UNREGISTER_SERVICE); - - *rsp_len = sizeof(*rp) + 1; + *rsp_len = tester_supported_commands(BTP_SERVICE_ID_CORE, rp->data); + *rsp_len += sizeof(*rp); return BTP_STATUS_SUCCESS; } diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 0f0fcb31f3..9448bd60b0 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -128,55 +128,8 @@ supported_commands(const void *cmd, uint16_t cmd_len, { struct btp_gap_read_supported_commands_rp *rp = rsp; - /* octet 0 */ - tester_set_bit(rp->data, BTP_GAP_READ_SUPPORTED_COMMANDS); - tester_set_bit(rp->data, BTP_GAP_READ_CONTROLLER_INDEX_LIST); - tester_set_bit(rp->data, BTP_GAP_READ_CONTROLLER_INFO); - tester_set_bit(rp->data, BTP_GAP_SET_CONNECTABLE); - - /* octet 1 */ - tester_set_bit(rp->data, BTP_GAP_SET_DISCOVERABLE); - tester_set_bit(rp->data, BTP_GAP_SET_BONDABLE); - tester_set_bit(rp->data, BTP_GAP_START_ADVERTISING); - tester_set_bit(rp->data, BTP_GAP_STOP_ADVERTISING); - tester_set_bit(rp->data, BTP_GAP_START_DISCOVERY); - tester_set_bit(rp->data, BTP_GAP_STOP_DISCOVERY); - tester_set_bit(rp->data, BTP_GAP_CONNECT); - tester_set_bit(rp->data, BTP_GAP_DISCONNECT); - - /* octet 2 */ - tester_set_bit(rp->data, BTP_GAP_SET_IO_CAP); - tester_set_bit(rp->data, BTP_GAP_PAIR); - tester_set_bit(rp->data, BTP_GAP_UNPAIR); - tester_set_bit(rp->data, BTP_GAP_PASSKEY_ENTRY); - tester_set_bit(rp->data, BTP_GAP_PASSKEY_CONFIRM); - tester_set_bit(rp->data, BTP_GAP_START_DIRECT_ADV); - tester_set_bit(rp->data, BTP_GAP_CONN_PARAM_UPDATE); - - /* octet 3 */ - tester_set_bit(rp->data, BTP_GAP_OOB_LEGACY_SET_DATA); - tester_set_bit(rp->data, BTP_GAP_OOB_SC_GET_LOCAL_DATA); - tester_set_bit(rp->data, BTP_GAP_OOB_SC_SET_REMOTE_DATA); - tester_set_bit(rp->data, BTP_GAP_SET_MITM); - tester_set_bit(rp->data, BTP_GAP_SET_FILTER_ACCEPT_LIST); - - /* octet 4 */ -#if MYNEWT_VAL(BLE_PERIODIC_ADV) - tester_set_bit(rp->data, GAP_SET_EXT_ADV); - tester_set_bit(rp->data, GAP_PADV_CONFIGURE); - tester_set_bit(rp->data, GAP_PADV_START); - tester_set_bit(rp->data, GAP_PADV_SET_DATA); - tester_set_bit(rp->data, GAP_PADV_CREATE_SYNC); -#endif -#if MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) - tester_set_bit(rp->data, GAP_PADV_SYNC_TRANSFER_SET_INFO); - tester_set_bit(rp->data, GAP_PADV_SYNC_TRANSFER_START); - tester_set_bit(rp->data, GAP_PADV_SYNC_TRANSFER_START); -#endif - - *rsp_len = sizeof(*rp) + 4 + - (MYNEWT_VAL(BLE_PERIODIC_ADV) || - MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER) ? 1 : 0); + *rsp_len = tester_supported_commands(BTP_SERVICE_ID_GAP, rp->data); + *rsp_len += sizeof(*rp); return BTP_STATUS_SUCCESS; } diff --git a/apps/bttester/src/btp_gatt.c b/apps/bttester/src/btp_gatt.c index b6ac433c0f..2baa1c8353 100644 --- a/apps/bttester/src/btp_gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -1960,38 +1960,8 @@ supported_commands(const void *cmd, uint16_t cmd_len, { struct btp_gatt_read_supported_commands_rp *rp = rsp; - /* octet 0 */ - tester_set_bit(rp->data, BTP_GATT_READ_SUPPORTED_COMMANDS); - tester_set_bit(rp->data, BTP_GATT_START_SERVER); - - /* octet 1 */ - tester_set_bit(rp->data, BTP_GATT_EXCHANGE_MTU); - tester_set_bit(rp->data, BTP_GATT_DISC_ALL_PRIM_SVCS); - tester_set_bit(rp->data, BTP_GATT_DISC_PRIM_UUID); - tester_set_bit(rp->data, BTP_GATT_FIND_INCLUDED); - tester_set_bit(rp->data, BTP_GATT_DISC_ALL_CHRC); - tester_set_bit(rp->data, BTP_GATT_DISC_CHRC_UUID); - - /* octet 2 */ - tester_set_bit(rp->data, BTP_GATT_DISC_ALL_DESC); - tester_set_bit(rp->data, BTP_GATT_READ); - tester_set_bit(rp->data, BTP_GATT_READ_LONG); - tester_set_bit(rp->data, BTP_GATT_READ_MULTIPLE); - tester_set_bit(rp->data, BTP_GATT_WRITE_WITHOUT_RSP); -#if 0 - tester_set_bit(rp->data, BTP_GATT_SIGNED_WRITE_WITHOUT_RSP); -#endif - tester_set_bit(rp->data, BTP_GATT_WRITE); - - /* octet 3 */ - tester_set_bit(rp->data, BTP_GATT_WRITE_LONG); - tester_set_bit(rp->data, BTP_GATT_CFG_NOTIFY); - tester_set_bit(rp->data, BTP_GATT_CFG_INDICATE); - tester_set_bit(rp->data, BTP_GATT_GET_ATTRIBUTES); - tester_set_bit(rp->data, BTP_GATT_GET_ATTRIBUTE_VALUE); - tester_set_bit(rp->data, BTP_GATT_CHANGE_DATABASE); - - *rsp_len = sizeof(*rp) + 4; + *rsp_len = tester_supported_commands(BTP_SERVICE_ID_GATT, rp->data); + *rsp_len += sizeof(*rp); return BTP_STATUS_SUCCESS; } diff --git a/apps/bttester/src/btp_gatt_cl.c b/apps/bttester/src/btp_gatt_cl.c index e4da8a3eaa..8771c395b8 100644 --- a/apps/bttester/src/btp_gatt_cl.c +++ b/apps/bttester/src/btp_gatt_cl.c @@ -1491,35 +1491,8 @@ supported_commands(const void *cmd, uint16_t cmd_len, { struct btp_gattc_read_supported_commands_rp *rp = rsp; - SYS_LOG_DBG(""); - - /* octet 0 */ - tester_set_bit(rp->data, BTP_GATTC_READ_SUPPORTED_COMMANDS); - tester_set_bit(rp->data, BTP_GATTC_EXCHANGE_MTU); - tester_set_bit(rp->data, BTP_GATTC_DISC_ALL_PRIM_SVCS); - tester_set_bit(rp->data, BTP_GATTC_DISC_PRIM_UUID); - tester_set_bit(rp->data, BTP_GATTC_FIND_INCLUDED); - tester_set_bit(rp->data, BTP_GATTC_DISC_ALL_CHRC); - tester_set_bit(rp->data, BTP_GATTC_DISC_CHRC_UUID); - /* octet 1 */ - tester_set_bit(rp->data, BTP_GATTC_DISC_ALL_DESC); - tester_set_bit(rp->data, BTP_GATTC_READ); - tester_set_bit(rp->data, BTP_GATTC_READ_UUID); - tester_set_bit(rp->data, BTP_GATTC_READ_LONG); - tester_set_bit(rp->data, BTP_GATTC_READ_MULTIPLE); - tester_set_bit(rp->data, BTP_GATTC_WRITE_WITHOUT_RSP); -#if 0 - tester_set_bit(rp->data, BTP_GATTC_SIGNED_WRITE_WITHOUT_RSP); -#endif - tester_set_bit(rp->data, BTP_GATTC_WRITE); - /* octet 2 */ - tester_set_bit(rp->data, BTP_GATTC_WRITE_LONG); - tester_set_bit(rp->data, BTP_GATTC_RELIABLE_WRITE); - tester_set_bit(rp->data, BTP_GATTC_CFG_NOTIFY); - tester_set_bit(rp->data, BTP_GATTC_CFG_INDICATE); - tester_set_bit(rp->data, BTP_GATTC_READ_MULTIPLE_VAR); - - *rsp_len = sizeof(*rp) + 3; + *rsp_len = tester_supported_commands(BTP_SERVICE_ID_GATTC, rp->data); + *rsp_len += sizeof(*rp); return BTP_STATUS_SUCCESS; } diff --git a/apps/bttester/src/btp_l2cap.c b/apps/bttester/src/btp_l2cap.c index 916e714e7d..03099b7784 100644 --- a/apps/bttester/src/btp_l2cap.c +++ b/apps/bttester/src/btp_l2cap.c @@ -678,15 +678,8 @@ supported_commands(const void *cmd, uint16_t cmd_len, { struct btp_l2cap_read_supported_commands_rp *rp = rsp; - /* octet 0 */ - tester_set_bit(rp->data, BTP_L2CAP_READ_SUPPORTED_COMMANDS); - tester_set_bit(rp->data, BTP_L2CAP_CONNECT); - tester_set_bit(rp->data, BTP_L2CAP_DISCONNECT); - tester_set_bit(rp->data, BTP_L2CAP_SEND_DATA); - tester_set_bit(rp->data, BTP_L2CAP_LISTEN); - /* octet 1 */ - tester_set_bit(rp->data, BTP_L2CAP_CREDITS); - *rsp_len = sizeof(*rp) + 2; + *rsp_len = tester_supported_commands(BTP_SERVICE_ID_L2CAP, rp->data); + *rsp_len += sizeof(*rp); return BTP_STATUS_SUCCESS; } diff --git a/apps/bttester/src/btp_mesh.c b/apps/bttester/src/btp_mesh.c index aad7eb4ada..4815dbe5b8 100644 --- a/apps/bttester/src/btp_mesh.c +++ b/apps/bttester/src/btp_mesh.c @@ -94,32 +94,8 @@ supported_commands(const void *cmd, uint16_t cmd_len, { struct btp_mesh_read_supported_commands_rp *rp = rsp; - /* octet 0 */ - tester_set_bit(rp->data, BTP_MESH_READ_SUPPORTED_COMMANDS); - tester_set_bit(rp->data, BTP_MESH_CONFIG_PROVISIONING); - tester_set_bit(rp->data, BTP_MESH_PROVISION_NODE); - tester_set_bit(rp->data, BTP_MESH_INIT); - tester_set_bit(rp->data, BTP_MESH_RESET); - tester_set_bit(rp->data, BTP_MESH_INPUT_NUMBER); - tester_set_bit(rp->data, BTP_MESH_INPUT_STRING); - /* octet 1 */ - tester_set_bit(rp->data, BTP_MESH_IVU_TEST_MODE); - tester_set_bit(rp->data, BTP_MESH_IVU_TOGGLE_STATE); - tester_set_bit(rp->data, BTP_MESH_NET_SEND); - tester_set_bit(rp->data, BTP_MESH_HEALTH_GENERATE_FAULTS); - tester_set_bit(rp->data, BTP_MESH_HEALTH_CLEAR_FAULTS); - tester_set_bit(rp->data, BTP_MESH_LPN); - tester_set_bit(rp->data, BTP_MESH_LPN_POLL); - tester_set_bit(rp->data, BTP_MESH_MODEL_SEND); - /* octet 2 */ -#if MYNEWT_VAL(BLE_MESH_TESTING) - tester_set_bit(rp->data, BTP_MESH_LPN_SUBSCRIBE); - tester_set_bit(rp->data, BTP_MESH_LPN_UNSUBSCRIBE); - tester_set_bit(rp->data, BTP_MESH_RPL_CLEAR); -#endif /* CONFIG_BT_TESTING */ - tester_set_bit(rp->data, BTP_MESH_PROXY_IDENTITY); - - *rsp_len = sizeof(*rp) + 3; + *rsp_len = tester_supported_commands(BTP_SERVICE_ID_GAP, rp->data); + *rsp_len += sizeof(*rp); return BTP_STATUS_SUCCESS; } diff --git a/apps/bttester/src/btp_pacs.c b/apps/bttester/src/btp_pacs.c index 9404cd946e..2ccc6f1b9a 100644 --- a/apps/bttester/src/btp_pacs.c +++ b/apps/bttester/src/btp_pacs.c @@ -266,13 +266,8 @@ supported_commands(const void *cmd, uint16_t cmd_len, { struct btp_pacs_read_supported_commands_rp *rp = rsp; - /* octet 0 */ - tester_set_bit(rp->data, BTP_PACS_READ_SUPPORTED_COMMANDS); - tester_set_bit(rp->data, BTP_PACS_UPDATE_CHARACTERISTIC); - tester_set_bit(rp->data, BTP_PACS_SET_AVAILABLE_CONTEXTS); - tester_set_bit(rp->data, BTP_PACS_SET_SUPPORTED_CONTEXTS); - - *rsp_len = sizeof(*rp) + 1; + *rsp_len = tester_supported_commands(BTP_SERVICE_ID_PACS, rp->data); + *rsp_len += sizeof(*rp); return BTP_STATUS_SUCCESS; } diff --git a/apps/bttester/src/bttester.c b/apps/bttester/src/bttester.c index fa4a82bb6f..8bbca9f2e9 100644 --- a/apps/bttester/src/bttester.c +++ b/apps/bttester/src/bttester.c @@ -377,3 +377,22 @@ tester_rsp(uint8_t service, uint8_t opcode, uint8_t status) os_eventq_put(&avail_queue, CONTAINER_OF(cmd, struct btp_buf, data)->ev); } + +uint16_t +tester_supported_commands(uint8_t service, uint8_t *cmds) +{ + uint8_t opcode_max = 0; + + assert(service <= BTP_SERVICE_ID_MAX); + + for (size_t i = 0; i < service_handler[service].num; i++) { + const struct btp_handler *handler = &service_handler[service].handlers[i]; + tester_set_bit(cmds, handler->opcode); + + if (handler->opcode > opcode_max) { + opcode_max = handler->opcode; + } + } + + return (opcode_max / 8) + 1; +} From abf1d5dd1d70dad187fe1aec27254b44ef866145 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 22 May 2025 10:54:51 +0200 Subject: [PATCH 1254/1333] apps/bttester: Refactor periodic transfer event Modify existing structure and function to be compliant with current autopts state of periodic sync transfer event. --- apps/bttester/src/btp/btp_gap.h | 11 +++-------- apps/bttester/src/btp_gap.c | 17 +++++++++-------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/apps/bttester/src/btp/btp_gap.h b/apps/bttester/src/btp/btp_gap.h index 9c691878f2..5485cd66e4 100644 --- a/apps/bttester/src/btp/btp_gap.h +++ b/apps/bttester/src/btp/btp_gap.h @@ -439,13 +439,8 @@ struct gap_periodic_report_ev { #define GAP_EV_PERIODIC_TRANSFER_RECEIVED 0x90 struct gap_periodic_transfer_recieved_ev { - uint8_t status; - uint16_t sync_handle; - uint16_t conn_handle; - uint16_t service_data; - uint8_t sid; ble_addr_t adv_addr; - uint8_t adv_phy; - uint16_t per_adv_itvl; - uint8_t adv_clk_accuracy; + uint16_t sync_handle; + uint8_t status; + ble_addr_t peer_addr; } __packed; diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 9448bd60b0..040bcd58e0 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -1246,17 +1246,18 @@ periodic_report(struct ble_gap_event *event) static void periodic_transfer_received(struct ble_gap_event *event) { + int rc; + struct ble_gap_conn_desc desc; struct gap_periodic_transfer_recieved_ev ev; - ev.status = event->periodic_transfer.status; - ev.sync_handle = event->periodic_transfer.sync_handle; - ev.conn_handle = event->periodic_transfer.conn_handle; - ev.service_data = event->periodic_transfer.service_data; - ev.sid = event->periodic_transfer.sid; ev.adv_addr = event->periodic_transfer.adv_addr; - ev.adv_phy = event->periodic_transfer.adv_phy; - ev.per_adv_itvl = event->periodic_transfer.per_adv_itvl; - ev.adv_clk_accuracy = event->periodic_transfer.adv_clk_accuracy; + ev.sync_handle = event->periodic_transfer.sync_handle; + ev.status = event->periodic_transfer.status; + + rc = ble_gap_conn_find(ev.sync_handle, &desc); + assert(rc == 0); + + ev.peer_addr = desc.peer_id_addr; tester_event(BTP_SERVICE_ID_GAP, GAP_EV_PERIODIC_TRANSFER_RECEIVED, (uint8_t *) &ev, sizeof(ev)); From fcc541c4214254445cf3e08af7b008f106bcb24c Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 22 May 2025 10:59:37 +0200 Subject: [PATCH 1255/1333] apps/bttester: Assign address field in sync established event Peer address field in sync established event wast not set. --- apps/bttester/src/btp_gap.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 040bcd58e0..ef87b0154b 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -1202,11 +1202,18 @@ bond_lost(uint16_t conn_handle) static void sync_established(struct ble_gap_event *event) { + int rc; + struct ble_gap_conn_desc desc; struct gap_periodic_sync_est_ev ev; ev.status = event->periodic_sync.status; ev.sync_handle = event->periodic_sync.sync_handle; + rc = ble_gap_conn_find(ev.sync_handle, &desc); + assert(rc == 0); + + ev.peer_addr = desc.peer_id_addr; + tester_event(BTP_SERVICE_ID_GAP, GAP_EV_PERIODIC_SYNC_ESTABLISHED, (uint8_t *) &ev, sizeof(ev)); } From 14a0f7806a4d872379f816b92b8187c9151af6e9 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 27 Feb 2025 15:51:45 +0100 Subject: [PATCH 1256/1333] nimble/hci: Document vendor specific commands Commands were not documented. Lack of the descriptions could led to some ambiguous interpretations. --- nimble/doc/hci_vendor.md | 336 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 336 insertions(+) create mode 100644 nimble/doc/hci_vendor.md diff --git a/nimble/doc/hci_vendor.md b/nimble/doc/hci_vendor.md new file mode 100644 index 0000000000..ad9d465e7e --- /dev/null +++ b/nimble/doc/hci_vendor.md @@ -0,0 +1,336 @@ + + + +Nimble Vendor Supported Commands +================================ + +*OGF = 0x003F* + + +Read Static Address Command +--------------------------- + +Read the static random address assigned to the controller + +| Command | OCF | Params |Return params | +|-------------------|--------|------------|--------------| +| Read_Addr | 0x0001 | *none* | Static_Addr | + +
+Static_Addr + +| Value | Description | +|--------------------|-------------| +| 0xXXXXXXXXXXXX | Address | + +*Size: 6 octets* + + +Set Default Transmit Power +-------------------------- + +Set default transmit power level
+Selected TX power is returned
+Setting 0xFF restores controller setting to default
+ +| Command | OCF | Params | Return params | +|-------------------|--------|------------|---------------| +| Set_Tx_Pwr | 0x0002 | Tx_Pwr | Sel_Tx_Pwr | + +
+Tx_Pwr + +| Value | Description | +|----------------------------|------------------------| +| 0xXX | Desired TX Power Level | + +*Size: 1 octet* + +
+Sel_Tx_Pwr + +| Value | Description | +|------------------|------------------------------| +| 0xXX | Controller Selected TX power | + +*Size: 1 octet* + + +Configure Connection Strict Scheduling +-------------------------------------- + +Configure Connection Strict Scheduling + +| Command | OCF | Params | Return params | +|-------------------|--------|------------|---------------| +| CSS_Configure | 0x0003 | Slot_us | *none* | +| | | Num_Slots | | + +
+Slot_us + +| Value | Description | +|----------------------------|-----------------------| +| 0xXXXXXX | Slot duration in msec | + +*Size: 4 octets* + +
+Number_Of_Slots + +| Value | Description | +|----------------------------|------------------------| +| 0xXXXXXX | Number of period slots | + +*Size: 4 octets* + + +Connection strict scheduling enable +----------------------------------- + +Enable/Disable Connection Strict Scheduling + +| Command | OCF | Params | Return params | +|--------------|--------|--------------|---------------| +| CSS_Enable | 0x0004 |Enable/Disale | *none* | + + +
+Enable/Disable + +| Value | Description | +|----------------------------|--------------------| +| 0xXX | Enable/Disable CSS | + +*Size: 1 octet* + + +Connection Strict Scheduling - Select Next Slot +----------------------------------------------- + +Set next slot index for future connection + +| Command | OCF | Params | Return params | +|-------------------|--------|--------------|---------------| +| CSS_Set_Next_Slot | 0x0005 |Next_Slot_Idx | *none* | + + +
+Next_Slot_Idx + +| Value | Description | +|----------------------------|--------------| +| 0xXXXX | Next Slot ID | + +*Size: 2 octets* + + +Connection Strict Scheduling - Select Slot For Specific Connection +------------------------------------------------------------------ + +Set slot index for current connection + +| Command | OCF | Params | Return params | +|-------------------|--------|------------|---------------| +| CSS_Configure | 0x0006 | Conn_Hdl | *none* | +| | | Slot_Idx | | + +
+Conn_Hdl + +| Value | Description | +|----------------------------|-------------------| +| 0xXXXX | Connection Handle | + +*Size: 2 octets* + +
+Slot_Idx + +| Value | Description | +|----------------------------|-------------| +| 0xXXXX | Slot ID | + +*Size: 2 octets* + + +Connection Strict Scheduling - Read Connection Slot +--------------------------------------------------- + +Read current connection slot index + +| Command | OCF | Params | Return params | +|-------------------|--------|--------------|---------------| +| CSS_Set_Next_Slot | 0x0007 | Conn_Hdl | Conn_Hdl | +| | | | Slot_Idx | + +
+Conn_Hdl + +| Value | Description | +|----------------------------|-------------------| +| 0xXXXX | Connection Handle | + +*Size: 2 octets* + +
+Slot_Idx + +| Value | Description | +|--------------------|-------------| +| 0xXXXX | Slot_ID | +*Size: 2 octets* + + +Set Data Length +--------------- + +Change TX/RX values. +Waits for Data Length Changed event. + +| Command | OCF | Params | Return params | +|--------------|--------|-----------------|---------------| +| Set_Data_Len | 0x0008 | Conn_Hdl
| Conn_Hdl | +| | | Tx_Octets
| | +| | | Tx_Time
| | +| | | Rx_Octets
| | +| | | Rx_Time
| | + +
+Conn_Hdl + +| Value | Description | +|----------------------------|-------------------| +| 0xXXXX | Connection Handle | + +*Size: 2 octets* + +
+Tx_Octets + +| Value | Description | +|----------------------------|-----------------| +| 0xXXXX | Transmit octets | + +*Size: 2 octets* + +
+Tx_Time + +| Value | Description | +|----------------------------|-------------------| +| 0xXXXX | Transmission time | + +*Size: 2 octets* + +
+Rx_Octets + +| Value | Description | +|----------------------------|-----------------| +| 0xXXXX | Receiver octets | + +*Size: 2 octets* + +
+Rx_Time + +| Value | Description | +|----------------------------|---------------| +| 0xXXXX | Receiver time | + +*Size: 2 octets* + + +Set Antenna Location +-------------------- + +| Command | OCF | Params | Return params | +|---------------|--------|----------------|---------------| +| Set_Ant_Loc | 0x0009 | Ant_Loc | *none* | + + +
+Ant_Loc + +| Value | Description | +|----------------------------|------------------| +| 0xXX | Antenna location | + +*Size: 1 ocet* + + +Set Local Identity Resolving Key +-------------------------------- + +Set own address type & identity resolving key + +| Command | OCF | Params | Return params | +|-----------------|--------|---------------|---------------| +| Set_Local_IRK | 0x000A | Own_Addr_Type | *none* | +| | | IRK | | + +
+Rx_Time + +| Value | Description | +|----------------------------|---------------------| +| 0xXX | Device Address Type | + +*Size: 1 ocet* + +
+IRK + +| Value | Description | +|--------------------|------------------------| +| 0xXX(16) | Identity Resolving Key | + +*Size: 16 ocets* + + +Set Scan Configuration +---------------------- + +| Command | OCF | Params | Return params | +|-----------------|--------|---------------|---------------| +| Set_Scan_Cfg | 0x000B | Flags | *none* | +| | | Rssi_Tres | | + +
+Flags + +| Value | Description | +|----------------------------|-------------------------| +| 0x00000001
| No legacy advertising | +| 0x00000002 | No extended advertising | + +*Size: 4 octets* + +
+Rssi_Tres + +| Value | Description | +|----------------------------|---------------------| +| 0xXX | RSSI treshold value | + +*Size: 1 octet* From 4416e2b280b825e97932b6e2f6370e5309dad0cd Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 13 Jun 2025 17:27:54 +0200 Subject: [PATCH 1257/1333] ci: Add clang-format configuration file Add the clang-format configuration file to the repository to enforce consistent code formatting across the project. --- .clang-format | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000..276f7fe434 --- /dev/null +++ b/.clang-format @@ -0,0 +1,86 @@ +# Use LLVM style as a base +BasedOnStyle: LLVM + +# Indentation settings +IndentWidth: 4 +UseTab: Never +TabWidth: 10 + +# Line length +ColumnLimit: 79 +PenaltyExcessCharacter: 2 + +# Braces placement +BreakBeforeBraces: Custom +BraceWrapping: + AfterClass: true + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: true + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false + +MacroBlockBegin: '(STATS_NAME_START|STATS_SECT_START)' +MacroBlockEnd: '(STATS_NAME_END|STATS_SECT_END)' +StatementMacros: ['SLIST_HEAD'] + +ForEachMacros: + - 'SLIST_FOREACH' + - 'SLIST_FOREACH_FROM' + - 'SLIST_FOREACH_SAFE' + - 'SLIST_FOREACH_FROM_SAFE' + - 'SLIST_FOREACH_PREVPTR' + - 'STAILQ_FOREACH' + - 'STAILQ_FOREACH_FROM' + - 'STAILQ_FOREACH_SAFE' + - 'STAILQ_FOREACH_FROM_SAFE' + - 'LIST_FOREACH' + - 'LIST_FOREACH_FROM' + - 'LIST_FOREACH_SAFE' + - 'LIST_FOREACH_FROM_SAFE' + - 'TAILQ_FOREACH' + - 'TAILQ_FOREACH_FROM' + - 'TAILQ_FOREACH_SAFE' + - 'TAILQ_FOREACH_FROM_SAFE' + - 'TAILQ_FOREACH_REVERSE' + - 'TAILQ_FOREACH_REVERSE_FROM' + - 'TAILQ_FOREACH_REVERSE_SAFE' + - 'TAILQ_FOREACH_REVERSE_FROM_SAFE' + +# Pointer and reference alignment +PointerAlignment: Right + +# Function declaration formatting +AllowAllParametersOfDeclarationOnNextLine: false +BinPackParameters: true +BinPackArguments: true +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignConsecutiveMacros: true + +# Control statements +AlwaysBreakAfterReturnType: TopLevelDefinitions +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AllowShortFunctionsOnASingleLine: InlineOnly +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false + +Cpp11BracedListStyle: false +SpacesInParentheses: false +SpaceAfterCStyleCast: false +SpaceBeforeParens: ControlStatementsExceptControlMacros +SpaceInEmptyParentheses: false + +AlignArrayOfStructures: Left +SortIncludes: false +DisableFormat: false +InsertNewlineAtEOF: true From 2d21eb0466d6cd15d3a070e2968536872ecf3ae8 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 13 Jun 2025 17:29:30 +0200 Subject: [PATCH 1258/1333] ci: Remove uncrustify configuration file The project no longer uses Uncrustify for formatting. This commit removes the old uncrustify config file to avoid confusion. Update rat-excludes file accordingly. --- .rat-excludes | 2 +- uncrustify.cfg | 3708 ------------------------------------------------ 2 files changed, 1 insertion(+), 3709 deletions(-) delete mode 100644 uncrustify.cfg diff --git a/.rat-excludes b/.rat-excludes index d465abc867..666ab501be 100644 --- a/.rat-excludes +++ b/.rat-excludes @@ -8,7 +8,7 @@ docs RELEASE_NOTES.md .gitignore README.md -uncrustify.cfg +.clang-format .style_ignored_dirs .mailmap requirements.txt diff --git a/uncrustify.cfg b/uncrustify.cfg deleted file mode 100644 index 0fddbf7b4e..0000000000 --- a/uncrustify.cfg +++ /dev/null @@ -1,3708 +0,0 @@ -# Uncrustify_d-0.78.1_f - -# -# General options -# - -# The type of line endings. -# -# Default: auto -newlines = lf # lf/crlf/cr/auto - -# The original size of tabs in the input. -# -# Default: 8 -input_tab_size = 4 # unsigned number - -# The size of tabs in the output (only used if align_with_tabs=true). -# -# Default: 8 -output_tab_size = 4 # unsigned number - -# The ASCII value of the string escape char, usually 92 (\) or (Pawn) 94 (^). -# -# Default: 92 -string_escape_char = 92 # unsigned number - -# Alternate string escape char (usually only used for Pawn). -# Only works right before the quote char. -string_escape_char2 = 0 # unsigned number - -# Replace tab characters found in string literals with the escape sequence \t -# instead. -string_replace_tab_chars = false # true/false - -# Allow interpreting '>=' and '>>=' as part of a template in code like -# 'void f(list>=val);'. If true, 'assert(x<0 && y>=3)' will be broken. -# Improvements to template detection may make this option obsolete. -tok_split_gte = false # true/false - -# Disable formatting of NL_CONT ('\\n') ended lines (e.g. multi-line macros). -disable_processing_nl_cont = false # true/false - -# Specify the marker used in comments to disable processing of part of the -# file. -# -# Default: *INDENT-OFF* -disable_processing_cmt = "" # string - -# Specify the marker used in comments to (re)enable processing in a file. -# -# Default: *INDENT-ON* -enable_processing_cmt = "" # string - -# Enable parsing of digraphs. -enable_digraphs = false # true/false - -# Option to allow both disable_processing_cmt and enable_processing_cmt -# strings, if specified, to be interpreted as ECMAScript regular expressions. -# If true, a regex search will be performed within comments according to the -# specified patterns in order to disable/enable processing. -processing_cmt_as_regex = false # true/false - -# Add or remove the UTF-8 BOM (recommend 'remove'). -utf8_bom = ignore # ignore/add/remove/force/not_defined - -# If the file contains bytes with values between 128 and 255, but is not -# UTF-8, then output as UTF-8. -utf8_byte = false # true/false - -# Force the output encoding to UTF-8. -utf8_force = false # true/false - -# -# Spacing options -# - -# Add or remove space around non-assignment symbolic operators ('+', '/', '%', -# '<<', and so forth). -sp_arith = force # ignore/add/remove/force/not_defined - -# Add or remove space around arithmetic operators '+' and '-'. -# -# Overrides sp_arith. -sp_arith_additive = ignore # ignore/add/remove/force/not_defined - -# Add or remove space around assignment operator '=', '+=', etc. -sp_assign = force # ignore/add/remove/force/not_defined - -# Add or remove space around '=' in C++11 lambda capture specifications. -# -# Overrides sp_assign. -sp_cpp_lambda_assign = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after the capture specification of a C++11 lambda when -# an argument list is present, as in '[] (int x){ ... }'. -sp_cpp_lambda_square_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after the capture specification of a C++11 lambda with -# no argument list is present, as in '[] { ... }'. -sp_cpp_lambda_square_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after the opening parenthesis and before the closing -# parenthesis of a argument list of a C++11 lambda, as in -# '[]( ){ ... }' -# with an empty list. -sp_cpp_lambda_argument_list_empty = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after the opening parenthesis and before the closing -# parenthesis of a argument list of a C++11 lambda, as in -# '[]( int x ){ ... }'. -sp_cpp_lambda_argument_list = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after the argument list of a C++11 lambda, as in -# '[](int x) { ... }'. -sp_cpp_lambda_paren_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between a lambda body and its call operator of an -# immediately invoked lambda, as in '[]( ... ){ ... } ( ... )'. -sp_cpp_lambda_fparen = ignore # ignore/add/remove/force/not_defined - -# Add or remove space around assignment operator '=' in a prototype. -# -# If set to ignore, use sp_assign. -sp_assign_default = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before assignment operator '=', '+=', etc. -# -# Overrides sp_assign. -sp_before_assign = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after assignment operator '=', '+=', etc. -# -# Overrides sp_assign. -sp_after_assign = ignore # ignore/add/remove/force/not_defined - -# Add or remove space in 'enum {'. -# -# Default: add -sp_enum_brace = add # ignore/add/remove/force/not_defined - -# Add or remove space in 'NS_ENUM ('. -sp_enum_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space around assignment '=' in enum. -sp_enum_assign = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before assignment '=' in enum. -# -# Overrides sp_enum_assign. -sp_enum_before_assign = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after assignment '=' in enum. -# -# Overrides sp_enum_assign. -sp_enum_after_assign = ignore # ignore/add/remove/force/not_defined - -# Add or remove space around assignment ':' in enum. -sp_enum_colon = ignore # ignore/add/remove/force/not_defined - -# Add or remove space around preprocessor '##' concatenation operator. -# -# Default: add -sp_pp_concat = add # ignore/add/remove/force/not_defined - -# Add or remove space after preprocessor '#' stringify operator. -# Also affects the '#@' charizing operator. -sp_pp_stringify = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before preprocessor '#' stringify operator -# as in '#define x(y) L#y'. -sp_before_pp_stringify = ignore # ignore/add/remove/force/not_defined - -# Add or remove space around boolean operators '&&' and '||'. -sp_bool = force # ignore/add/remove/force/not_defined - -# Add or remove space around compare operator '<', '>', '==', etc. -sp_compare = force # ignore/add/remove/force/not_defined - -# Add or remove space inside '(' and ')'. -sp_inside_paren = remove # ignore/add/remove/force/not_defined - -# Add or remove space between nested parentheses, i.e. '((' vs. ') )'. -sp_paren_paren = remove # ignore/add/remove/force/not_defined - -# Add or remove space between back-to-back parentheses, i.e. ')(' vs. ') ('. -sp_cparen_oparen = ignore # ignore/add/remove/force/not_defined - -# Whether to balance spaces inside nested parentheses. -sp_balance_nested_parens = false # true/false - -# Add or remove space between ')' and '{'. -sp_paren_brace = force # ignore/add/remove/force/not_defined - -# Add or remove space between nested braces, i.e. '{{' vs. '{ {'. -sp_brace_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before pointer star '*'. -sp_before_ptr_star = force # ignore/add/remove/force/not_defined - -# Add or remove space before pointer star '*' that isn't followed by a -# variable name. If set to ignore, sp_before_ptr_star is used instead. -sp_before_unnamed_ptr_star = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before pointer star '*' that is followed by a qualifier. -# If set to ignore, sp_before_unnamed_ptr_star is used instead. -sp_before_qualifier_ptr_star = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before pointer star '*' that is followed by 'operator' keyword. -# If set to ignore, sp_before_unnamed_ptr_star is used instead. -sp_before_operator_ptr_star = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before pointer star '*' that is followed by -# a class scope (as in 'int *MyClass::method()') or namespace scope -# (as in 'int *my_ns::func()'). -# If set to ignore, sp_before_unnamed_ptr_star is used instead. -sp_before_scope_ptr_star = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before pointer star '*' that is followed by '::', -# as in 'int *::func()'. -# If set to ignore, sp_before_unnamed_ptr_star is used instead. -sp_before_global_scope_ptr_star = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between a qualifier and a pointer star '*' that isn't -# followed by a variable name, as in '(char const *)'. If set to ignore, -# sp_before_ptr_star is used instead. -sp_qualifier_unnamed_ptr_star = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between pointer stars '*', as in 'int ***a;'. -sp_between_ptr_star = remove # ignore/add/remove/force/not_defined - -# Add or remove space between pointer star '*' and reference '&', as in 'int *& a;'. -sp_between_ptr_ref = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after pointer star '*', if followed by a word. -# -# Overrides sp_type_func. -sp_after_ptr_star = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after pointer caret '^', if followed by a word. -sp_after_ptr_block_caret = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after pointer star '*', if followed by a qualifier. -sp_after_ptr_star_qualifier = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after a pointer star '*', if followed by a function -# prototype or function definition. -# -# Overrides sp_after_ptr_star and sp_type_func. -sp_after_ptr_star_func = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after a pointer star '*' in the trailing return of a -# function prototype or function definition. -sp_after_ptr_star_trailing = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between the pointer star '*' and the name of the variable -# in a function pointer definition. -sp_ptr_star_func_var = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between the pointer star '*' and the name of the type -# in a function pointer type definition. -sp_ptr_star_func_type = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after a pointer star '*', if followed by an open -# parenthesis, as in 'void* (*)()'. -sp_ptr_star_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before a pointer star '*', if followed by a function -# prototype or function definition. If set to ignore, sp_before_ptr_star is -# used instead. -sp_before_ptr_star_func = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between a qualifier and a pointer star '*' followed by -# the name of the function in a function prototype or definition, as in -# 'char const *foo()`. If set to ignore, sp_before_ptr_star is used instead. -sp_qualifier_ptr_star_func = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before a pointer star '*' in the trailing return of a -# function prototype or function definition. -sp_before_ptr_star_trailing = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between a qualifier and a pointer star '*' in the -# trailing return of a function prototype or function definition, as in -# 'auto foo() -> char const *'. -sp_qualifier_ptr_star_trailing = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before a reference sign '&'. -sp_before_byref = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before a reference sign '&' that isn't followed by a -# variable name. If set to ignore, sp_before_byref is used instead. -sp_before_unnamed_byref = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after reference sign '&', if followed by a word. -# -# Overrides sp_type_func. -sp_after_byref = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after a reference sign '&', if followed by a function -# prototype or function definition. -# -# Overrides sp_after_byref and sp_type_func. -sp_after_byref_func = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before a reference sign '&', if followed by a function -# prototype or function definition. -sp_before_byref_func = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after a reference sign '&', if followed by an open -# parenthesis, as in 'char& (*)()'. -sp_byref_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between type and word. In cases where total removal of -# whitespace would be a syntax error, a value of 'remove' is treated the same -# as 'force'. -# -# This also affects some other instances of space following a type that are -# not covered by other options; for example, between the return type and -# parenthesis of a function type template argument, between the type and -# parenthesis of an array parameter, or between 'decltype(...)' and the -# following word. -# -# Default: force -sp_after_type = force # ignore/add/remove/force/not_defined - -# Add or remove space between 'decltype(...)' and word, -# brace or function call. -sp_after_decltype = ignore # ignore/add/remove/force/not_defined - -# (D) Add or remove space before the parenthesis in the D constructs -# 'template Foo(' and 'class Foo('. -sp_before_template_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'template' and '<'. -# If set to ignore, sp_before_angle is used. -sp_template_angle = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before '<'. -sp_before_angle = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside '<' and '>'. -sp_inside_angle = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside '<>'. -# if empty. -sp_inside_angle_empty = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between '>' and ':'. -sp_angle_colon = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after '>'. -sp_after_angle = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between '>' and '(' as found in 'new List(foo);'. -sp_angle_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between '>' and '()' as found in 'new List();'. -sp_angle_paren_empty = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between '>' and a word as in 'List m;' or -# 'template static ...'. -sp_angle_word = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between '>' and '>' in '>>' (template stuff). -# -# Default: add -sp_angle_shift = add # ignore/add/remove/force/not_defined - -# (C++11) Permit removal of the space between '>>' in 'foo >'. Note -# that sp_angle_shift cannot remove the space without this option. -sp_permit_cpp11_shift = false # true/false - -# Add or remove space before '(' of control statements ('if', 'for', 'switch', -# 'while', etc.). -sp_before_sparen = add # ignore/add/remove/force/not_defined - -# Add or remove space inside '(' and ')' of control statements other than -# 'for'. -sp_inside_sparen = remove # ignore/add/remove/force/not_defined - -# Add or remove space after '(' of control statements other than 'for'. -# -# Overrides sp_inside_sparen. -sp_inside_sparen_open = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before ')' of control statements other than 'for'. -# -# Overrides sp_inside_sparen. -sp_inside_sparen_close = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside '(' and ')' of 'for' statements. -sp_inside_for = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after '(' of 'for' statements. -# -# Overrides sp_inside_for. -sp_inside_for_open = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before ')' of 'for' statements. -# -# Overrides sp_inside_for. -sp_inside_for_close = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between '((' or '))' of control statements. -sp_sparen_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after ')' of control statements. -sp_after_sparen = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between ')' and '{' of control statements. -sp_sparen_brace = add # ignore/add/remove/force/not_defined - -# Add or remove space between 'do' and '{'. -sp_do_brace_open = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between '}' and 'while'. -sp_brace_close_while = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'while' and '('. Overrides sp_before_sparen. -sp_while_paren_open = ignore # ignore/add/remove/force/not_defined - -# (D) Add or remove space between 'invariant' and '('. -sp_invariant_paren = ignore # ignore/add/remove/force/not_defined - -# (D) Add or remove space after the ')' in 'invariant (C) c'. -sp_after_invariant_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before empty statement ';' on 'if', 'for' and 'while'. -sp_special_semi = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before ';'. -# -# Default: remove -sp_before_semi = remove # ignore/add/remove/force/not_defined - -# Add or remove space before ';' in non-empty 'for' statements. -sp_before_semi_for = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before a semicolon of an empty left part of a for -# statement, as in 'for ( ; ; )'. -sp_before_semi_for_empty = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between the semicolons of an empty middle part of a for -# statement, as in 'for ( ; ; )'. -sp_between_semi_for_empty = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after ';', except when followed by a comment. -# -# Default: add -sp_after_semi = add # ignore/add/remove/force/not_defined - -# Add or remove space after ';' in non-empty 'for' statements. -# -# Default: force -sp_after_semi_for = force # ignore/add/remove/force/not_defined - -# Add or remove space after the final semicolon of an empty part of a for -# statement, as in 'for ( ; ; )'. -sp_after_semi_for_empty = remove # ignore/add/remove/force/not_defined - -# Add or remove space before '[' (except '[]'). -sp_before_square = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before '[' for a variable definition. -# -# Default: remove -sp_before_vardef_square = remove # ignore/add/remove/force/not_defined - -# Add or remove space before '[' for asm block. -sp_before_square_asm_block = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before '[]'. -sp_before_squares = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before C++17 structured bindings. -sp_cpp_before_struct_binding = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside a non-empty '[' and ']'. -sp_inside_square = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside '[]'. -# if empty. -sp_inside_square_empty = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space inside a non-empty Objective-C boxed array '@[' and -# ']'. If set to ignore, sp_inside_square is used. -sp_inside_square_oc_array = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after ',', i.e. 'a,b' vs. 'a, b'. -sp_after_comma = force # ignore/add/remove/force/not_defined - -# Add or remove space before ',', i.e. 'a,b' vs. 'a ,b'. -# -# Default: remove -sp_before_comma = remove # ignore/add/remove/force/not_defined - -# (C#, Vala) Add or remove space between ',' and ']' in multidimensional array type -# like 'int[,,]'. -sp_after_mdatype_commas = ignore # ignore/add/remove/force/not_defined - -# (C#, Vala) Add or remove space between '[' and ',' in multidimensional array type -# like 'int[,,]'. -sp_before_mdatype_commas = ignore # ignore/add/remove/force/not_defined - -# (C#, Vala) Add or remove space between ',' in multidimensional array type -# like 'int[,,]'. -sp_between_mdatype_commas = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between an open parenthesis and comma, -# i.e. '(,' vs. '( ,'. -# -# Default: force -sp_paren_comma = force # ignore/add/remove/force/not_defined - -# Add or remove space between a type and ':'. -sp_type_colon = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after the variadic '...' when preceded by a -# non-punctuator. -# The value REMOVE will be overridden with FORCE -sp_after_ellipsis = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before the variadic '...' when preceded by a -# non-punctuator. -# The value REMOVE will be overridden with FORCE -sp_before_ellipsis = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between a type and '...'. -sp_type_ellipsis = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between a '*' and '...'. -sp_ptr_type_ellipsis = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between ')' and '...'. -sp_paren_ellipsis = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between '&&' and '...'. -sp_byref_ellipsis = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between ')' and a qualifier such as 'const'. -sp_paren_qualifier = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between ')' and 'noexcept'. -sp_paren_noexcept = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after class ':'. -sp_after_class_colon = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before class ':'. -sp_before_class_colon = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after class constructor ':'. -# -# Default: add -sp_after_constr_colon = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before class constructor ':'. -# -# Default: add -sp_before_constr_colon = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before case ':'. -# -# Default: remove -sp_before_case_colon = remove # ignore/add/remove/force/not_defined - -# Add or remove space between 'operator' and operator sign. -sp_after_operator = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between the operator symbol and the open parenthesis, as -# in 'operator ++('. -sp_after_operator_sym = ignore # ignore/add/remove/force/not_defined - -# Overrides sp_after_operator_sym when the operator has no arguments, as in -# 'operator *()'. -sp_after_operator_sym_empty = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after C/D cast, i.e. 'cast(int)a' vs. 'cast(int) a' or -# '(int)a' vs. '(int) a'. -sp_after_cast = ignore # ignore/add/remove/force/not_defined - -# Add or remove spaces inside cast parentheses. -sp_inside_paren_cast = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between the type and open parenthesis in a C++ cast, -# i.e. 'int(exp)' vs. 'int (exp)'. -sp_cpp_cast_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'sizeof' and '('. -sp_sizeof_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'sizeof' and '...'. -sp_sizeof_ellipsis = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'sizeof...' and '('. -sp_sizeof_ellipsis_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between '...' and a parameter pack. -sp_ellipsis_parameter_pack = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between a parameter pack and '...'. -sp_parameter_pack_ellipsis = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'decltype' and '('. -sp_decltype_paren = ignore # ignore/add/remove/force/not_defined - -# (Pawn) Add or remove space after the tag keyword. -sp_after_tag = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside enum '{' and '}'. -sp_inside_braces_enum = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside struct/union '{' and '}'. -sp_inside_braces_struct = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space inside Objective-C boxed dictionary '{' and '}' -sp_inside_braces_oc_dict = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after open brace in an unnamed temporary -# direct-list-initialization -# if statement is a brace_init_lst -# works only if sp_brace_brace is set to ignore. -sp_after_type_brace_init_lst_open = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before close brace in an unnamed temporary -# direct-list-initialization -# if statement is a brace_init_lst -# works only if sp_brace_brace is set to ignore. -sp_before_type_brace_init_lst_close = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside an unnamed temporary direct-list-initialization -# if statement is a brace_init_lst -# works only if sp_brace_brace is set to ignore -# works only if sp_before_type_brace_init_lst_close is set to ignore. -sp_inside_type_brace_init_lst = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside '{' and '}'. -sp_inside_braces = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside '{}'. -# if empty. -sp_inside_braces_empty = ignore # ignore/add/remove/force/not_defined - -# Add or remove space around trailing return operator '->'. -sp_trailing_return = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between return type and function name. A minimum of 1 -# is forced except for pointer return types. -sp_type_func = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between type and open brace of an unnamed temporary -# direct-list-initialization. -sp_type_brace_init_lst = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between function name and '(' on function declaration. -sp_func_proto_paren = remove # ignore/add/remove/force/not_defined - -# Add or remove space between function name and '()' on function declaration -# if empty. -sp_func_proto_paren_empty = remove # ignore/add/remove/force/not_defined - -# Add or remove space between function name and '(' with a typedef specifier. -sp_func_type_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between alias name and '(' of a non-pointer function type typedef. -sp_func_def_paren = remove # ignore/add/remove/force/not_defined - -# Add or remove space between function name and '()' on function definition -# if empty. -sp_func_def_paren_empty = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside empty function '()'. -# Overrides sp_after_angle unless use_sp_after_angle_always is set to true. -sp_inside_fparens = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside function '(' and ')'. -sp_inside_fparen = remove # ignore/add/remove/force/not_defined - -# Add or remove space inside user functor '(' and ')'. -sp_func_call_user_inside_rparen = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside empty functor '()'. -# Overrides sp_after_angle unless use_sp_after_angle_always is set to true. -sp_inside_rparens = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside functor '(' and ')'. -sp_inside_rparen = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside the first parentheses in a function type, as in -# 'void (*x)(...)'. -sp_inside_tparen = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between the ')' and '(' in a function type, as in -# 'void (*x)(...)'. -sp_after_tparen_close = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between ']' and '(' when part of a function call. -sp_square_fparen = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between ')' and '{' of function. -sp_fparen_brace = add # ignore/add/remove/force/not_defined - -# Add or remove space between ')' and '{' of a function call in object -# initialization. -# -# Overrides sp_fparen_brace. -sp_fparen_brace_initializer = ignore # ignore/add/remove/force/not_defined - -# (Java) Add or remove space between ')' and '{{' of double brace initializer. -sp_fparen_dbrace = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between function name and '(' on function calls. -sp_func_call_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between function name and '()' on function calls without -# parameters. If set to ignore (the default), sp_func_call_paren is used. -sp_func_call_paren_empty = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between the user function name and '(' on function -# calls. You need to set a keyword to be a user function in the config file, -# like: -# set func_call_user tr _ i18n -sp_func_call_user_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside user function '(' and ')'. -sp_func_call_user_inside_fparen = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between nested parentheses with user functions, -# i.e. '((' vs. '( ('. -sp_func_call_user_paren_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between a constructor/destructor and the open -# parenthesis. -sp_func_class_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between a constructor without parameters or destructor -# and '()'. -sp_func_class_paren_empty = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after 'return'. -# -# Default: force -sp_return = force # ignore/add/remove/force/not_defined - -# Add or remove space between 'return' and '('. -sp_return_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'return' and '{'. -sp_return_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between '__attribute__' and '('. -sp_attribute_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'defined' and '(' in '#if defined (FOO)'. -sp_defined_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'throw' and '(' in 'throw (something)'. -sp_throw_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'throw' and anything other than '(' as in -# '@throw [...];'. -sp_after_throw = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'catch' and '(' in 'catch (something) { }'. -# If set to ignore, sp_before_sparen is used. -sp_catch_paren = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space between '@catch' and '(' -# in '@catch (something) { }'. If set to ignore, sp_catch_paren is used. -sp_oc_catch_paren = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space before Objective-C protocol list -# as in '@protocol Protocol' or '@interface MyClass : NSObject'. -sp_before_oc_proto_list = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space between class name and '(' -# in '@interface className(categoryName):BaseClass' -sp_oc_classname_paren = ignore # ignore/add/remove/force/not_defined - -# (D) Add or remove space between 'version' and '(' -# in 'version (something) { }'. If set to ignore, sp_before_sparen is used. -sp_version_paren = ignore # ignore/add/remove/force/not_defined - -# (D) Add or remove space between 'scope' and '(' -# in 'scope (something) { }'. If set to ignore, sp_before_sparen is used. -sp_scope_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'super' and '(' in 'super (something)'. -# -# Default: remove -sp_super_paren = remove # ignore/add/remove/force/not_defined - -# Add or remove space between 'this' and '(' in 'this (something)'. -# -# Default: remove -sp_this_paren = remove # ignore/add/remove/force/not_defined - -# Add or remove space between a macro name and its definition. -sp_macro = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between a macro function ')' and its definition. -sp_macro_func = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'else' and '{' if on the same line. -sp_else_brace = add # ignore/add/remove/force/not_defined - -# Add or remove space between '}' and 'else' if on the same line. -sp_brace_else = add # ignore/add/remove/force/not_defined - -# Add or remove space between '}' and the name of a typedef on the same line. -sp_brace_typedef = add # ignore/add/remove/force/not_defined - -# Add or remove space before the '{' of a 'catch' statement, if the '{' and -# 'catch' are on the same line, as in 'catch (decl) {'. -sp_catch_brace = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space before the '{' of a '@catch' statement, if the '{' -# and '@catch' are on the same line, as in '@catch (decl) {'. -# If set to ignore, sp_catch_brace is used. -sp_oc_catch_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between '}' and 'catch' if on the same line. -sp_brace_catch = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space between '}' and '@catch' if on the same line. -# If set to ignore, sp_brace_catch is used. -sp_oc_brace_catch = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'finally' and '{' if on the same line. -sp_finally_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between '}' and 'finally' if on the same line. -sp_brace_finally = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'try' and '{' if on the same line. -sp_try_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between get/set and '{' if on the same line. -sp_getset_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between a variable and '{' for C++ uniform -# initialization. -sp_word_brace_init_lst = add # ignore/add/remove/force/not_defined - -# Add or remove space between a variable and '{' for a namespace. -# -# Default: add -sp_word_brace_ns = add # ignore/add/remove/force/not_defined - -# Add or remove space before the '::' operator. -sp_before_dc = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after the '::' operator. -sp_after_dc = ignore # ignore/add/remove/force/not_defined - -# (D) Add or remove around the D named array initializer ':' operator. -sp_d_array_colon = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after the '!' (not) unary operator. -# -# Default: remove -sp_not = remove # ignore/add/remove/force/not_defined - -# Add or remove space between two '!' (not) unary operators. -# If set to ignore, sp_not will be used. -sp_not_not = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after the '~' (invert) unary operator. -# -# Default: remove -sp_inv = remove # ignore/add/remove/force/not_defined - -# Add or remove space after the '&' (address-of) unary operator. This does not -# affect the spacing after a '&' that is part of a type. -# -# Default: remove -sp_addr = remove # ignore/add/remove/force/not_defined - -# Add or remove space around the '.' or '->' operators. -# -# Default: remove -sp_member = remove # ignore/add/remove/force/not_defined - -# Add or remove space after the '*' (dereference) unary operator. This does -# not affect the spacing after a '*' that is part of a type. -# -# Default: remove -sp_deref = remove # ignore/add/remove/force/not_defined - -# Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. -# -# Default: remove -sp_sign = remove # ignore/add/remove/force/not_defined - -# Add or remove space between '++' and '--' the word to which it is being -# applied, as in '(--x)' or 'y++;'. -# -# Default: remove -sp_incdec = remove # ignore/add/remove/force/not_defined - -# Add or remove space before a backslash-newline at the end of a line. -# -# Default: add -sp_before_nl_cont = add # ignore/add/remove/force/not_defined - -# (OC) Add or remove space after the scope '+' or '-', as in '-(void) foo;' -# or '+(int) bar;'. -sp_after_oc_scope = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space after the colon in message specs, -# i.e. '-(int) f:(int) x;' vs. '-(int) f: (int) x;'. -sp_after_oc_colon = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space before the colon in message specs, -# i.e. '-(int) f: (int) x;' vs. '-(int) f : (int) x;'. -sp_before_oc_colon = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space after the colon in immutable dictionary expression -# 'NSDictionary *test = @{@"foo" :@"bar"};'. -sp_after_oc_dict_colon = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space before the colon in immutable dictionary expression -# 'NSDictionary *test = @{@"foo" :@"bar"};'. -sp_before_oc_dict_colon = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space after the colon in message specs, -# i.e. '[object setValue:1];' vs. '[object setValue: 1];'. -sp_after_send_oc_colon = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space before the colon in message specs, -# i.e. '[object setValue:1];' vs. '[object setValue :1];'. -sp_before_send_oc_colon = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space after the (type) in message specs, -# i.e. '-(int)f: (int) x;' vs. '-(int)f: (int)x;'. -sp_after_oc_type = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space after the first (type) in message specs, -# i.e. '-(int) f:(int)x;' vs. '-(int)f:(int)x;'. -sp_after_oc_return_type = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space between '@selector' and '(', -# i.e. '@selector(msgName)' vs. '@selector (msgName)'. -# Also applies to '@protocol()' constructs. -sp_after_oc_at_sel = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space between '@selector(x)' and the following word, -# i.e. '@selector(foo) a:' vs. '@selector(foo)a:'. -sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space inside '@selector' parentheses, -# i.e. '@selector(foo)' vs. '@selector( foo )'. -# Also applies to '@protocol()' constructs. -sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space before a block pointer caret, -# i.e. '^int (int arg){...}' vs. ' ^int (int arg){...}'. -sp_before_oc_block_caret = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space after a block pointer caret, -# i.e. '^int (int arg){...}' vs. '^ int (int arg){...}'. -sp_after_oc_block_caret = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space between the receiver and selector in a message, -# as in '[receiver selector ...]'. -sp_after_oc_msg_receiver = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space after '@property'. -sp_after_oc_property = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove space between '@synchronized' and the open parenthesis, -# i.e. '@synchronized(foo)' vs. '@synchronized (foo)'. -sp_after_oc_synchronized = ignore # ignore/add/remove/force/not_defined - -# Add or remove space around the ':' in 'b ? t : f'. -sp_cond_colon = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before the ':' in 'b ? t : f'. -# -# Overrides sp_cond_colon. -sp_cond_colon_before = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after the ':' in 'b ? t : f'. -# -# Overrides sp_cond_colon. -sp_cond_colon_after = ignore # ignore/add/remove/force/not_defined - -# Add or remove space around the '?' in 'b ? t : f'. -sp_cond_question = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before the '?' in 'b ? t : f'. -# -# Overrides sp_cond_question. -sp_cond_question_before = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after the '?' in 'b ? t : f'. -# -# Overrides sp_cond_question. -sp_cond_question_after = ignore # ignore/add/remove/force/not_defined - -# In the abbreviated ternary form '(a ?: b)', add or remove space between '?' -# and ':'. -# -# Overrides all other sp_cond_* options. -sp_cond_ternary_short = ignore # ignore/add/remove/force/not_defined - -# Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make -# sense here. -sp_case_label = ignore # ignore/add/remove/force/not_defined - -# (D) Add or remove space around the D '..' operator. -sp_range = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after ':' in a Java/C++11 range-based 'for', -# as in 'for (Type var : expr)'. -sp_after_for_colon = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before ':' in a Java/C++11 range-based 'for', -# as in 'for (Type var : expr)'. -sp_before_for_colon = ignore # ignore/add/remove/force/not_defined - -# (D) Add or remove space between 'extern' and '(' as in 'extern (C)'. -sp_extern_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after the opening of a C++ comment, as in '// A'. -sp_cmt_cpp_start = ignore # ignore/add/remove/force/not_defined - -# remove space after the '//' and the pvs command '-V1234', -# only works with sp_cmt_cpp_start set to add or force. -sp_cmt_cpp_pvs = false # true/false - -# remove space after the '//' and the command 'lint', -# only works with sp_cmt_cpp_start set to add or force. -sp_cmt_cpp_lint = false # true/false - -# Add or remove space in a C++ region marker comment, as in '// BEGIN'. -# A region marker is defined as a comment which is not preceded by other text -# (i.e. the comment is the first non-whitespace on the line), and which starts -# with either 'BEGIN' or 'END'. -# -# Overrides sp_cmt_cpp_start. -sp_cmt_cpp_region = ignore # ignore/add/remove/force/not_defined - -# If true, space added with sp_cmt_cpp_start will be added after Doxygen -# sequences like '///', '///<', '//!' and '//!<'. -sp_cmt_cpp_doxygen = false # true/false - -# If true, space added with sp_cmt_cpp_start will be added after Qt translator -# or meta-data comments like '//:', '//=', and '//~'. -sp_cmt_cpp_qttr = false # true/false - -# Add or remove space between #else or #endif and a trailing comment. -sp_endif_cmt = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after 'new', 'delete' and 'delete[]'. -sp_after_new = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between 'new' and '(' in 'new()'. -sp_between_new_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space between ')' and type in 'new(foo) BAR'. -sp_after_newop_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space inside parentheses of the new operator -# as in 'new(foo) BAR'. -sp_inside_newop_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after the open parenthesis of the new operator, -# as in 'new(foo) BAR'. -# -# Overrides sp_inside_newop_paren. -sp_inside_newop_paren_open = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before the close parenthesis of the new operator, -# as in 'new(foo) BAR'. -# -# Overrides sp_inside_newop_paren. -sp_inside_newop_paren_close = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before a trailing comment. -sp_before_tr_cmt = ignore # ignore/add/remove/force/not_defined - -# Number of spaces before a trailing comment. -sp_num_before_tr_cmt = 0 # unsigned number - -# Add or remove space before an embedded comment. -# -# Default: force -sp_before_emb_cmt = force # ignore/add/remove/force/not_defined - -# Number of spaces before an embedded comment. -# -# Default: 1 -sp_num_before_emb_cmt = 1 # unsigned number - -# Add or remove space after an embedded comment. -# -# Default: force -sp_after_emb_cmt = force # ignore/add/remove/force/not_defined - -# Number of spaces after an embedded comment. -# -# Default: 1 -sp_num_after_emb_cmt = 1 # unsigned number - -# (Java) Add or remove space between an annotation and the open parenthesis. -sp_annotation_paren = ignore # ignore/add/remove/force/not_defined - -# If true, vbrace tokens are dropped to the previous token and skipped. -sp_skip_vbrace_tokens = false # true/false - -# Add or remove space after 'noexcept'. -sp_after_noexcept = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after '_'. -sp_vala_after_translation = ignore # ignore/add/remove/force/not_defined - -# Add or remove space before a bit colon ':'. -sp_before_bit_colon = ignore # ignore/add/remove/force/not_defined - -# Add or remove space after a bit colon ':'. -sp_after_bit_colon = ignore # ignore/add/remove/force/not_defined - -# If true, a is inserted after #define. -force_tab_after_define = false # true/false - -# -# Indenting options -# - -# The number of columns to indent per level. Usually 2, 3, 4, or 8. -# -# Default: 8 -indent_columns = 4 # unsigned number - -# Whether to ignore indent for the first continuation line. Subsequent -# continuation lines will still be indented to match the first. -indent_ignore_first_continue = false # true/false - -# The continuation indent. If non-zero, this overrides the indent of '(', '[' -# and '=' continuation indents. Negative values are OK; negative value is -# absolute and not increased for each '(' or '[' level. -# -# For FreeBSD, this is set to 4. -# Requires indent_ignore_first_continue=false. -indent_continue = 0 # number - -# The continuation indent, only for class header line(s). If non-zero, this -# overrides the indent of 'class' continuation indents. -# Requires indent_ignore_first_continue=false. -indent_continue_class_head = 0 # unsigned number - -# Whether to indent empty lines (i.e. lines which contain only spaces before -# the newline character). -indent_single_newlines = false # true/false - -# The continuation indent for func_*_param if they are true. If non-zero, this -# overrides the indent. -indent_param = 0 # unsigned number - -# How to use tabs when indenting code. -# -# 0: Spaces only -# 1: Indent with tabs to brace level, align with spaces (default) -# 2: Indent and align with tabs, using spaces when not on a tabstop -# -# Default: 1 -indent_with_tabs = 0 # unsigned number - -# Whether to indent comments that are not at a brace level with tabs on a -# tabstop. Requires indent_with_tabs=2. If false, will use spaces. -indent_cmt_with_tabs = false # true/false - -# Whether to indent strings broken by '\' so that they line up. -indent_align_string = false # true/false - -# The number of spaces to indent multi-line XML strings. -# Requires indent_align_string=true. -indent_xml_string = 0 # unsigned number - -# Spaces to indent '{' from level. -indent_brace = 0 # unsigned number - -# Whether braces are indented to the body level. -indent_braces = false # true/false - -# Whether to disable indenting function braces if indent_braces=true. -indent_braces_no_func = false # true/false - -# Whether to disable indenting class braces if indent_braces=true. -indent_braces_no_class = false # true/false - -# Whether to disable indenting struct braces if indent_braces=true. -indent_braces_no_struct = false # true/false - -# Whether to indent based on the size of the brace parent, -# i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc. -indent_brace_parent = false # true/false - -# Whether to indent based on the open parenthesis instead of the open brace -# in '({\n'. -indent_paren_open_brace = false # true/false - -# (C#) Whether to indent the brace of a C# delegate by another level. -indent_cs_delegate_brace = false # true/false - -# (C#) Whether to indent a C# delegate (to handle delegates with no brace) by -# another level. -indent_cs_delegate_body = false # true/false - -# Whether to indent the body of a 'namespace'. -indent_namespace = false # true/false - -# Whether to indent only the first namespace, and not any nested namespaces. -# Requires indent_namespace=true. -indent_namespace_single_indent = false # true/false - -# The number of spaces to indent a namespace block. -# If set to zero, use the value indent_columns -indent_namespace_level = 0 # unsigned number - -# If the body of the namespace is longer than this number, it won't be -# indented. Requires indent_namespace=true. 0 means no limit. -indent_namespace_limit = 0 # unsigned number - -# Whether to indent only in inner namespaces (nested in other namespaces). -# Requires indent_namespace=true. -indent_namespace_inner_only = false # true/false - -# Whether the 'extern "C"' body is indented. -indent_extern = false # true/false - -# Whether the 'class' body is indented. -indent_class = true # true/false - -# Whether to ignore indent for the leading base class colon. -indent_ignore_before_class_colon = false # true/false - -# Additional indent before the leading base class colon. -# Negative values decrease indent down to the first column. -# Requires indent_ignore_before_class_colon=false and a newline break before -# the colon (see pos_class_colon and nl_class_colon) -indent_before_class_colon = 0 # number - -# Whether to indent the stuff after a leading base class colon. -indent_class_colon = true # true/false - -# Whether to indent based on a class colon instead of the stuff after the -# colon. Requires indent_class_colon=true. -indent_class_on_colon = false # true/false - -# Whether to ignore indent for a leading class initializer colon. -indent_ignore_before_constr_colon = false # true/false - -# Whether to indent the stuff after a leading class initializer colon. -indent_constr_colon = false # true/false - -# Virtual indent from the ':' for leading member initializers. -# -# Default: 2 -indent_ctor_init_leading = 2 # unsigned number - -# Virtual indent from the ':' for following member initializers. -# -# Default: 2 -indent_ctor_init_following = 2 # unsigned number - -# Additional indent for constructor initializer list. -# Negative values decrease indent down to the first column. -indent_ctor_init = 0 # number - -# Whether to indent 'if' following 'else' as a new block under the 'else'. -# If false, 'else\nif' is treated as 'else if' for indenting purposes. -indent_else_if = false # true/false - -# Amount to indent variable declarations after a open brace. -# -# <0: Relative -# >=0: Absolute -indent_var_def_blk = 0 # number - -# Whether to indent continued variable declarations instead of aligning. -indent_var_def_cont = false # true/false - -# How to indent continued shift expressions ('<<' and '>>'). -# Set align_left_shift=false when using this. -# 0: Align shift operators instead of indenting them (default) -# 1: Indent by one level -# -1: Preserve original indentation -indent_shift = 0 # number - -# Whether to force indentation of function definitions to start in column 1. -indent_func_def_force_col1 = false # true/false - -# Whether to indent continued function call parameters one indent level, -# rather than aligning parameters under the open parenthesis. -indent_func_call_param = false # true/false - -# Whether to indent continued function definition parameters one indent level, -# rather than aligning parameters under the open parenthesis. -indent_func_def_param = false # true/false - -# for function definitions, only if indent_func_def_param is false -# Allows to align params when appropriate and indent them when not -# behave as if it was true if paren position is more than this value -# if paren position is more than the option value -indent_func_def_param_paren_pos_threshold = 0 # unsigned number - -# Whether to indent continued function call prototype one indent level, -# rather than aligning parameters under the open parenthesis. -indent_func_proto_param = false # true/false - -# Whether to indent continued function call declaration one indent level, -# rather than aligning parameters under the open parenthesis. -indent_func_class_param = false # true/false - -# Whether to indent continued class variable constructors one indent level, -# rather than aligning parameters under the open parenthesis. -indent_func_ctor_var_param = false # true/false - -# Whether to indent continued template parameter list one indent level, -# rather than aligning parameters under the open parenthesis. -indent_template_param = false # true/false - -# Double the indent for indent_func_xxx_param options. -# Use both values of the options indent_columns and indent_param. -indent_func_param_double = false # true/false - -# Indentation column for standalone 'const' qualifier on a function -# prototype. -indent_func_const = 0 # unsigned number - -# Indentation column for standalone 'throw' qualifier on a function -# prototype. -indent_func_throw = 0 # unsigned number - -# How to indent within a macro followed by a brace on the same line -# This allows reducing the indent in macros that have (for example) -# `do { ... } while (0)` blocks bracketing them. -# -# true: add an indent for the brace on the same line as the macro -# false: do not add an indent for the brace on the same line as the macro -# -# Default: true -indent_macro_brace = true # true/false - -# The number of spaces to indent a continued '->' or '.'. -# Usually set to 0, 1, or indent_columns. -indent_member = 0 # unsigned number - -# Whether lines broken at '.' or '->' should be indented by a single indent. -# The indent_member option will not be effective if this is set to true. -indent_member_single = false # true/false - -# Spaces to indent single line ('//') comments on lines before code. -indent_single_line_comments_before = 0 # unsigned number - -# Spaces to indent single line ('//') comments on lines after code. -indent_single_line_comments_after = 0 # unsigned number - -# When opening a paren for a control statement (if, for, while, etc), increase -# the indent level by this value. Negative values decrease the indent level. -indent_sparen_extra = 0 # number - -# Whether to indent trailing single line ('//') comments relative to the code -# instead of trying to keep the same absolute column. -indent_relative_single_line_comments = false # true/false - -# Spaces to indent 'case' from 'switch'. Usually 0 or indent_columns. -# It might be wise to choose the same value for the option indent_case_brace. -indent_switch_case = 0 # unsigned number - -# Spaces to indent the body of a 'switch' before any 'case'. -# Usually the same as indent_columns or indent_switch_case. -indent_switch_body = 0 # unsigned number - -# Whether to ignore indent for '{' following 'case'. -indent_ignore_case_brace = false # true/false - -# Spaces to indent '{' from 'case'. By default, the brace will appear under -# the 'c' in case. Usually set to 0 or indent_columns. Negative values are OK. -# It might be wise to choose the same value for the option indent_switch_case. -indent_case_brace = 0 # number - -# indent 'break' with 'case' from 'switch'. -indent_switch_break_with_case = false # true/false - -# Whether to indent preprocessor statements inside of switch statements. -# -# Default: true -indent_switch_pp = true # true/false - -# Spaces to shift the 'case' line, without affecting any other lines. -# Usually 0. -indent_case_shift = 0 # unsigned number - -# Whether to align comments before 'case' with the 'case'. -# -# Default: true -indent_case_comment = true # true/false - -# Whether to indent comments not found in first column. -# -# Default: true -indent_comment = true # true/false - -# Whether to indent comments found in first column. -indent_col1_comment = false # true/false - -# Whether to indent multi string literal in first column. -indent_col1_multi_string_literal = false # true/false - -# Align comments on adjacent lines that are this many columns apart or less. -# -# Default: 3 -indent_comment_align_thresh = 3 # unsigned number - -# Whether to ignore indent for goto labels. -indent_ignore_label = false # true/false - -# How to indent goto labels. Requires indent_ignore_label=false. -# -# >0: Absolute column where 1 is the leftmost column -# <=0: Subtract from brace indent -# -# Default: 1 -indent_label = 1 # number - -# How to indent access specifiers that are followed by a -# colon. -# -# >0: Absolute column where 1 is the leftmost column -# <=0: Subtract from brace indent -# -# Default: 1 -indent_access_spec = 1 # number - -# Whether to indent the code after an access specifier by one level. -# If true, this option forces 'indent_access_spec=0'. -indent_access_spec_body = false # true/false - -# If an open parenthesis is followed by a newline, whether to indent the next -# line so that it lines up after the open parenthesis (not recommended). -indent_paren_nl = false # true/false - -# How to indent a close parenthesis after a newline. -# -# 0: Indent to body level (default) -# 1: Align under the open parenthesis -# 2: Indent to the brace level -# -1: Preserve original indentation -indent_paren_close = 2 # number - -# Whether to indent the open parenthesis of a function definition, -# if the parenthesis is on its own line. -indent_paren_after_func_def = false # true/false - -# Whether to indent the open parenthesis of a function declaration, -# if the parenthesis is on its own line. -indent_paren_after_func_decl = false # true/false - -# Whether to indent the open parenthesis of a function call, -# if the parenthesis is on its own line. -indent_paren_after_func_call = false # true/false - -# How to indent a comma when inside braces. -# 0: Indent by one level (default) -# 1: Align under the open brace -# -1: Preserve original indentation -indent_comma_brace = 0 # number - -# How to indent a comma when inside parentheses. -# 0: Indent by one level (default) -# 1: Align under the open parenthesis -# -1: Preserve original indentation -indent_comma_paren = 0 # number - -# How to indent a Boolean operator when inside parentheses. -# 0: Indent by one level (default) -# 1: Align under the open parenthesis -# -1: Preserve original indentation -indent_bool_paren = 0 # number - -# Whether to ignore the indentation of a Boolean operator when outside -# parentheses. -indent_ignore_bool = false # true/false - -# Whether to ignore the indentation of an arithmetic operator. -indent_ignore_arith = false # true/false - -# Whether to indent a semicolon when inside a for parenthesis. -# If true, aligns under the open for parenthesis. -indent_semicolon_for_paren = false # true/false - -# Whether to ignore the indentation of a semicolon outside of a 'for' -# statement. -indent_ignore_semicolon = false # true/false - -# Whether to align the first expression to following ones -# if indent_bool_paren=1. -indent_first_bool_expr = false # true/false - -# Whether to align the first expression to following ones -# if indent_semicolon_for_paren=true. -indent_first_for_expr = false # true/false - -# If an open square is followed by a newline, whether to indent the next line -# so that it lines up after the open square (not recommended). -indent_square_nl = false # true/false - -# (ESQL/C) Whether to preserve the relative indent of 'EXEC SQL' bodies. -indent_preserve_sql = false # true/false - -# Whether to ignore the indentation of an assignment operator. -indent_ignore_assign = false # true/false - -# Whether to align continued statements at the '='. If false or if the '=' is -# followed by a newline, the next line is indent one tab. -# -# Default: true -indent_align_assign = true # true/false - -# If true, the indentation of the chunks after a '=' sequence will be set at -# LHS token indentation column before '='. -indent_off_after_assign = false # true/false - -# Whether to align continued statements at the '('. If false or the '(' is -# followed by a newline, the next line indent is one tab. -# -# Default: true -indent_align_paren = true # true/false - -# (OC) Whether to indent Objective-C code inside message selectors. -indent_oc_inside_msg_sel = false # true/false - -# (OC) Whether to indent Objective-C blocks at brace level instead of usual -# rules. -indent_oc_block = false # true/false - -# (OC) Indent for Objective-C blocks in a message relative to the parameter -# name. -# -# =0: Use indent_oc_block rules -# >0: Use specified number of spaces to indent -indent_oc_block_msg = 0 # unsigned number - -# (OC) Minimum indent for subsequent parameters -indent_oc_msg_colon = 0 # unsigned number - -# (OC) Whether to prioritize aligning with initial colon (and stripping spaces -# from lines, if necessary). -# -# Default: true -indent_oc_msg_prioritize_first_colon = true # true/false - -# (OC) Whether to indent blocks the way that Xcode does by default -# (from the keyword if the parameter is on its own line; otherwise, from the -# previous indentation level). Requires indent_oc_block_msg=true. -indent_oc_block_msg_xcode_style = false # true/false - -# (OC) Whether to indent blocks from where the brace is, relative to a -# message keyword. Requires indent_oc_block_msg=true. -indent_oc_block_msg_from_keyword = false # true/false - -# (OC) Whether to indent blocks from where the brace is, relative to a message -# colon. Requires indent_oc_block_msg=true. -indent_oc_block_msg_from_colon = false # true/false - -# (OC) Whether to indent blocks from where the block caret is. -# Requires indent_oc_block_msg=true. -indent_oc_block_msg_from_caret = false # true/false - -# (OC) Whether to indent blocks from where the brace caret is. -# Requires indent_oc_block_msg=true. -indent_oc_block_msg_from_brace = false # true/false - -# When indenting after virtual brace open and newline add further spaces to -# reach this minimum indent. -indent_min_vbrace_open = 0 # unsigned number - -# Whether to add further spaces after regular indent to reach next tabstop -# when indenting after virtual brace open and newline. -indent_vbrace_open_on_tabstop = false # true/false - -# How to indent after a brace followed by another token (not a newline). -# true: indent all contained lines to match the token -# false: indent all contained lines to match the brace -# -# Default: true -indent_token_after_brace = true # true/false - -# Whether to indent the body of a C++11 lambda. -indent_cpp_lambda_body = false # true/false - -# How to indent compound literals that are being returned. -# true: add both the indent from return & the compound literal open brace -# (i.e. 2 indent levels) -# false: only indent 1 level, don't add the indent for the open brace, only -# add the indent for the return. -# -# Default: true -indent_compound_literal_return = true # true/false - -# (C#) Whether to indent a 'using' block if no braces are used. -# -# Default: true -indent_using_block = true # true/false - -# How to indent the continuation of ternary operator. -# -# 0: Off (default) -# 1: When the `if_false` is a continuation, indent it under the `if_true` branch -# 2: When the `:` is a continuation, indent it under `?` -indent_ternary_operator = 0 # unsigned number - -# Whether to indent the statements inside ternary operator. -indent_inside_ternary_operator = false # true/false - -# If true, the indentation of the chunks after a `return` sequence will be set at return indentation column. -indent_off_after_return = false # true/false - -# If true, the indentation of the chunks after a `return new` sequence will be set at return indentation column. -indent_off_after_return_new = false # true/false - -# If true, the tokens after return are indented with regular single indentation. By default (false) the indentation is after the return token. -indent_single_after_return = false # true/false - -# Whether to ignore indent and alignment for 'asm' blocks (i.e. assume they -# have their own indentation). -indent_ignore_asm_block = false # true/false - -# Don't indent the close parenthesis of a function definition, -# if the parenthesis is on its own line. -donot_indent_func_def_close_paren = false # true/false - -# -# Newline adding and removing options -# - -# Whether to collapse empty blocks between '{' and '}' except for functions. -# Use nl_collapse_empty_body_functions to specify how empty function braces -# should be formatted. -nl_collapse_empty_body = false # true/false - -# Whether to collapse empty blocks between '{' and '}' for functions only. -# If true, overrides nl_inside_empty_func. -nl_collapse_empty_body_functions = false # true/false - -# Don't split one-line braced assignments, as in 'foo_t f = { 1, 2 };'. -nl_assign_leave_one_liners = true # true/false - -# Don't split one-line braced statements inside a 'class xx { }' body. -nl_class_leave_one_liners = false # true/false - -# Don't split one-line enums, as in 'enum foo { BAR = 15 };' -nl_enum_leave_one_liners = false # true/false - -# Don't split one-line get or set functions. -nl_getset_leave_one_liners = false # true/false - -# (C#) Don't split one-line property get or set functions. -nl_cs_property_leave_one_liners = false # true/false - -# Don't split one-line function definitions, as in 'int foo() { return 0; }'. -# might modify nl_func_type_name -nl_func_leave_one_liners = false # true/false - -# Don't split one-line C++11 lambdas, as in '[]() { return 0; }'. -nl_cpp_lambda_leave_one_liners = false # true/false - -# Don't split one-line if/else statements, as in 'if(...) b++;'. -nl_if_leave_one_liners = false # true/false - -# Don't split one-line while statements, as in 'while(...) b++;'. -nl_while_leave_one_liners = true # true/false - -# Don't split one-line do statements, as in 'do { b++; } while(...);'. -nl_do_leave_one_liners = false # true/false - -# Don't split one-line for statements, as in 'for(...) b++;'. -nl_for_leave_one_liners = false # true/false - -# (OC) Don't split one-line Objective-C messages. -nl_oc_msg_leave_one_liner = false # true/false - -# (OC) Add or remove newline between method declaration and '{'. -nl_oc_mdef_brace = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove newline between Objective-C block signature and '{'. -nl_oc_block_brace = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove blank line before '@interface' statement. -nl_oc_before_interface = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove blank line before '@implementation' statement. -nl_oc_before_implementation = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove blank line before '@end' statement. -nl_oc_before_end = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove newline between '@interface' and '{'. -nl_oc_interface_brace = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove newline between '@implementation' and '{'. -nl_oc_implementation_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove newlines at the start of the file. -nl_start_of_file = remove # ignore/add/remove/force/not_defined - -# The minimum number of newlines at the start of the file (only used if -# nl_start_of_file is 'add' or 'force'). -nl_start_of_file_min = 0 # unsigned number - -# Add or remove newline at the end of the file. -nl_end_of_file = force # ignore/add/remove/force/not_defined - -# The minimum number of newlines at the end of the file (only used if -# nl_end_of_file is 'add' or 'force'). -nl_end_of_file_min = 1 # unsigned number - -# Add or remove newline between '=' and '{'. -nl_assign_brace = remove # ignore/add/remove/force/not_defined - -# (D) Add or remove newline between '=' and '['. -nl_assign_square = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between '[]' and '{'. -nl_tsquare_brace = ignore # ignore/add/remove/force/not_defined - -# (D) Add or remove newline after '= ['. Will also affect the newline before -# the ']'. -nl_after_square_assign = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between a function call's ')' and '{', as in -# 'list_for_each(item, &list) { }'. -nl_fcall_brace = remove # ignore/add/remove/force/not_defined - -# Add or remove newline between 'enum' and '{'. -nl_enum_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between 'enum' and 'class'. -nl_enum_class = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between 'enum class' and the identifier. -nl_enum_class_identifier = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between 'enum class' type and ':'. -nl_enum_identifier_colon = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between 'enum class identifier :' and type. -nl_enum_colon_type = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between 'struct and '{'. -nl_struct_brace = remove # ignore/add/remove/force/not_defined - -# Add or remove newline between 'union' and '{'. -nl_union_brace = remove # ignore/add/remove/force/not_defined - -# Add or remove newline between 'if' and '{'. -nl_if_brace = remove # ignore/add/remove/force/not_defined - -# Add or remove newline between '}' and 'else'. -nl_brace_else = remove # ignore/add/remove/force/not_defined - -# Add or remove newline between 'else if' and '{'. If set to ignore, -# nl_if_brace is used instead. -nl_elseif_brace = remove # ignore/add/remove/force/not_defined - -# Add or remove newline between 'else' and '{'. -nl_else_brace = remove # ignore/add/remove/force/not_defined - -# Add or remove newline between 'else' and 'if'. -nl_else_if = remove # ignore/add/remove/force/not_defined - -# Add or remove newline before '{' opening brace -nl_before_opening_brace_func_class_def = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline before 'if'/'else if' closing parenthesis. -nl_before_if_closing_paren = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between '}' and 'finally'. -nl_brace_finally = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between 'finally' and '{'. -nl_finally_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between 'try' and '{'. -nl_try_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between get/set and '{'. -nl_getset_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between 'for' and '{'. -nl_for_brace = remove # ignore/add/remove/force/not_defined - -# Add or remove newline before the '{' of a 'catch' statement, as in -# 'catch (decl) {'. -nl_catch_brace = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove newline before the '{' of a '@catch' statement, as in -# '@catch (decl) {'. If set to ignore, nl_catch_brace is used. -nl_oc_catch_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between '}' and 'catch'. -nl_brace_catch = ignore # ignore/add/remove/force/not_defined - -# (OC) Add or remove newline between '}' and '@catch'. If set to ignore, -# nl_brace_catch is used. -nl_oc_brace_catch = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between '}' and ']'. -nl_brace_square = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between '}' and ')' in a function invocation. -nl_brace_fparen = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between 'while' and '{'. -nl_while_brace = remove # ignore/add/remove/force/not_defined - -# (D) Add or remove newline between 'scope (x)' and '{'. -nl_scope_brace = ignore # ignore/add/remove/force/not_defined - -# (D) Add or remove newline between 'unittest' and '{'. -nl_unittest_brace = ignore # ignore/add/remove/force/not_defined - -# (D) Add or remove newline between 'version (x)' and '{'. -nl_version_brace = ignore # ignore/add/remove/force/not_defined - -# (C#) Add or remove newline between 'using' and '{'. -nl_using_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between two open or close braces. Due to general -# newline/brace handling, REMOVE may not work. -nl_brace_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between 'do' and '{'. -nl_do_brace = remove # ignore/add/remove/force/not_defined - -# Add or remove newline between '}' and 'while' of 'do' statement. -nl_brace_while = remove # ignore/add/remove/force/not_defined - -# Add or remove newline between 'switch' and '{'. -nl_switch_brace = remove # ignore/add/remove/force/not_defined - -# Add or remove newline between 'synchronized' and '{'. -nl_synchronized_brace = ignore # ignore/add/remove/force/not_defined - -# Add a newline between ')' and '{' if the ')' is on a different line than the -# if/for/etc. -# -# Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch and -# nl_catch_brace. -nl_multi_line_cond = false # true/false - -# Add a newline after '(' if an if/for/while/switch condition spans multiple -# lines -nl_multi_line_sparen_open = ignore # ignore/add/remove/force/not_defined - -# Add a newline before ')' if an if/for/while/switch condition spans multiple -# lines. Overrides nl_before_if_closing_paren if both are specified. -nl_multi_line_sparen_close = ignore # ignore/add/remove/force/not_defined - -# Force a newline in a define after the macro name for multi-line defines. -nl_multi_line_define = false # true/false - -# Whether to add a newline before 'case', and a blank line before a 'case' -# statement that follows a ';' or '}'. -nl_before_case = false # true/false - -# Whether to add a newline after a 'case' statement. -nl_after_case = false # true/false - -# Add or remove newline between a case ':' and '{'. -# -# Overrides nl_after_case. -nl_case_colon_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between ')' and 'throw'. -nl_before_throw = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between 'namespace' and '{'. -nl_namespace_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline after 'template<...>' of a template class. -nl_template_class = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline after 'template<...>' of a template class declaration. -# -# Overrides nl_template_class. -nl_template_class_decl = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline after 'template<>' of a specialized class declaration. -# -# Overrides nl_template_class_decl. -nl_template_class_decl_special = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline after 'template<...>' of a template class definition. -# -# Overrides nl_template_class. -nl_template_class_def = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline after 'template<>' of a specialized class definition. -# -# Overrides nl_template_class_def. -nl_template_class_def_special = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline after 'template<...>' of a template function. -nl_template_func = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline after 'template<...>' of a template function -# declaration. -# -# Overrides nl_template_func. -nl_template_func_decl = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline after 'template<>' of a specialized function -# declaration. -# -# Overrides nl_template_func_decl. -nl_template_func_decl_special = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline after 'template<...>' of a template function -# definition. -# -# Overrides nl_template_func. -nl_template_func_def = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline after 'template<>' of a specialized function -# definition. -# -# Overrides nl_template_func_def. -nl_template_func_def_special = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline after 'template<...>' of a template variable. -nl_template_var = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between 'template<...>' and 'using' of a templated -# type alias. -nl_template_using = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between 'class' and '{'. -nl_class_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline before or after (depending on pos_class_comma, -# may not be IGNORE) each',' in the base class list. -nl_class_init_args = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline after each ',' in the constructor member -# initialization. Related to nl_constr_colon, pos_constr_colon and -# pos_constr_comma. -nl_constr_init_args = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline before first element, after comma, and after last -# element, in 'enum'. -nl_enum_own_lines = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between return type and function name in a function -# definition. -# might be modified by nl_func_leave_one_liners -nl_func_type_name = add # ignore/add/remove/force/not_defined - -# Add or remove newline between return type and function name inside a class -# definition. If set to ignore, nl_func_type_name or nl_func_proto_type_name -# is used instead. -nl_func_type_name_class = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between class specification and '::' -# in 'void A::f() { }'. Only appears in separate member implementation (does -# not appear with in-line implementation). -nl_func_class_scope = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between function scope and name, as in -# 'void A :: f() { }'. -nl_func_scope_name = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between return type and function name in a prototype. -nl_func_proto_type_name = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between a function name and the opening '(' in the -# declaration. -nl_func_paren = remove # ignore/add/remove/force/not_defined - -# Overrides nl_func_paren for functions with no parameters. -nl_func_paren_empty = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between a function name and the opening '(' in the -# definition. -nl_func_def_paren = remove # ignore/add/remove/force/not_defined - -# Overrides nl_func_def_paren for functions with no parameters. -nl_func_def_paren_empty = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between a function name and the opening '(' in the -# call. -nl_func_call_paren = ignore # ignore/add/remove/force/not_defined - -# Overrides nl_func_call_paren for functions with no parameters. -nl_func_call_paren_empty = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline after '(' in a function declaration. -nl_func_decl_start = remove # ignore/add/remove/force/not_defined - -# Add or remove newline after '(' in a function definition. -nl_func_def_start = remove # ignore/add/remove/force/not_defined - -# Overrides nl_func_decl_start when there is only one parameter. -nl_func_decl_start_single = ignore # ignore/add/remove/force/not_defined - -# Overrides nl_func_def_start when there is only one parameter. -nl_func_def_start_single = ignore # ignore/add/remove/force/not_defined - -# Whether to add a newline after '(' in a function declaration if '(' and ')' -# are in different lines. If false, nl_func_decl_start is used instead. -nl_func_decl_start_multi_line = false # true/false - -# Whether to add a newline after '(' in a function definition if '(' and ')' -# are in different lines. If false, nl_func_def_start is used instead. -nl_func_def_start_multi_line = false # true/false - -# Add or remove newline after each ',' in a function declaration. -nl_func_decl_args = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline after each ',' in a function definition. -nl_func_def_args = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline after each ',' in a function call. -nl_func_call_args = ignore # ignore/add/remove/force/not_defined - -# Whether to add a newline after each ',' in a function declaration if '(' -# and ')' are in different lines. If false, nl_func_decl_args is used instead. -nl_func_decl_args_multi_line = false # true/false - -# Whether to add a newline after each ',' in a function definition if '(' -# and ')' are in different lines. If false, nl_func_def_args is used instead. -nl_func_def_args_multi_line = false # true/false - -# Add or remove newline before the ')' in a function declaration. -nl_func_decl_end = remove # ignore/add/remove/force/not_defined - -# Add or remove newline before the ')' in a function definition. -nl_func_def_end = remove # ignore/add/remove/force/not_defined - -# Overrides nl_func_decl_end when there is only one parameter. -nl_func_decl_end_single = ignore # ignore/add/remove/force/not_defined - -# Overrides nl_func_def_end when there is only one parameter. -nl_func_def_end_single = ignore # ignore/add/remove/force/not_defined - -# Whether to add a newline before ')' in a function declaration if '(' and ')' -# are in different lines. If false, nl_func_decl_end is used instead. -nl_func_decl_end_multi_line = false # true/false - -# Whether to add a newline before ')' in a function definition if '(' and ')' -# are in different lines. If false, nl_func_def_end is used instead. -nl_func_def_end_multi_line = false # true/false - -# Add or remove newline between '()' in a function declaration. -nl_func_decl_empty = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between '()' in a function definition. -nl_func_def_empty = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between '()' in a function call. -nl_func_call_empty = ignore # ignore/add/remove/force/not_defined - -# Whether to add a newline after '(' in a function call, -# has preference over nl_func_call_start_multi_line. -nl_func_call_start = ignore # ignore/add/remove/force/not_defined - -# Whether to add a newline before ')' in a function call. -nl_func_call_end = ignore # ignore/add/remove/force/not_defined - -# Whether to add a newline after '(' in a function call if '(' and ')' are in -# different lines. -nl_func_call_start_multi_line = false # true/false - -# Whether to add a newline after each ',' in a function call if '(' and ')' -# are in different lines. -nl_func_call_args_multi_line = false # true/false - -# Whether to add a newline before ')' in a function call if '(' and ')' are in -# different lines. -nl_func_call_end_multi_line = false # true/false - -# Whether to respect nl_func_call_XXX option in case of closure args. -nl_func_call_args_multi_line_ignore_closures = false # true/false - -# Whether to add a newline after '<' of a template parameter list. -nl_template_start = false # true/false - -# Whether to add a newline after each ',' in a template parameter list. -nl_template_args = false # true/false - -# Whether to add a newline before '>' of a template parameter list. -nl_template_end = false # true/false - -# (OC) Whether to put each Objective-C message parameter on a separate line. -# See nl_oc_msg_leave_one_liner. -nl_oc_msg_args = false # true/false - -# (OC) Minimum number of Objective-C message parameters before applying nl_oc_msg_args. -nl_oc_msg_args_min_params = 0 # unsigned number - -# (OC) Max code width of Objective-C message before applying nl_oc_msg_args. -nl_oc_msg_args_max_code_width = 0 # unsigned number - -# Add or remove newline between function signature and '{'. -nl_fdef_brace = add # ignore/add/remove/force/not_defined - -# Add or remove newline between function signature and '{', -# if signature ends with ')'. Overrides nl_fdef_brace. -nl_fdef_brace_cond = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between C++11 lambda signature and '{'. -nl_cpp_ldef_brace = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between 'return' and the return expression. -nl_return_expr = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline between 'throw' and the throw expression. -nl_throw_expr = ignore # ignore/add/remove/force/not_defined - -# Whether to add a newline after semicolons, except in 'for' statements. -nl_after_semicolon = false # true/false - -# (Java) Add or remove newline between the ')' and '{{' of the double brace -# initializer. -nl_paren_dbrace_open = ignore # ignore/add/remove/force/not_defined - -# Whether to add a newline after the type in an unnamed temporary -# direct-list-initialization, better: -# before a direct-list-initialization. -nl_type_brace_init_lst = ignore # ignore/add/remove/force/not_defined - -# Whether to add a newline after the open brace in an unnamed temporary -# direct-list-initialization. -nl_type_brace_init_lst_open = ignore # ignore/add/remove/force/not_defined - -# Whether to add a newline before the close brace in an unnamed temporary -# direct-list-initialization. -nl_type_brace_init_lst_close = ignore # ignore/add/remove/force/not_defined - -# Whether to add a newline before '{'. -nl_before_brace_open = false # true/false - -# Whether to add a newline after '{'. -nl_after_brace_open = false # true/false - -# Whether to add a newline between the open brace and a trailing single-line -# comment. Requires nl_after_brace_open=true. -nl_after_brace_open_cmt = false # true/false - -# Whether to add a newline after a virtual brace open with a non-empty body. -# These occur in un-braced if/while/do/for statement bodies. -nl_after_vbrace_open = false # true/false - -# Whether to add a newline after a virtual brace open with an empty body. -# These occur in un-braced if/while/do/for statement bodies. -nl_after_vbrace_open_empty = false # true/false - -# Whether to add a newline after '}'. Does not apply if followed by a -# necessary ';'. -nl_after_brace_close = false # true/false - -# Whether to add a newline after a virtual brace close, -# as in 'if (foo) a++; return;'. -nl_after_vbrace_close = false # true/false - -# Add or remove newline between the close brace and identifier, -# as in 'struct { int a; } b;'. Affects enumerations, unions and -# structures. If set to ignore, uses nl_after_brace_close. -nl_brace_struct_var = ignore # ignore/add/remove/force/not_defined - -# Whether to alter newlines in '#define' macros. -nl_define_macro = false # true/false - -# Whether to alter newlines between consecutive parenthesis closes. The number -# of closing parentheses in a line will depend on respective open parenthesis -# lines. -nl_squeeze_paren_close = false # true/false - -# Whether to remove blanks after '#ifxx' and '#elxx', or before '#elxx' and -# '#endif'. Does not affect top-level #ifdefs. -nl_squeeze_ifdef = false # true/false - -# Makes the nl_squeeze_ifdef option affect the top-level #ifdefs as well. -nl_squeeze_ifdef_top_level = false # true/false - -# Add or remove blank line before 'if'. -nl_before_if = ignore # ignore/add/remove/force/not_defined - -# Add or remove blank line after 'if' statement. Add/Force work only if the -# next token is not a closing brace. -nl_after_if = ignore # ignore/add/remove/force/not_defined - -# Add or remove blank line before 'for'. -nl_before_for = ignore # ignore/add/remove/force/not_defined - -# Add or remove blank line after 'for' statement. -nl_after_for = ignore # ignore/add/remove/force/not_defined - -# Add or remove blank line before 'while'. -nl_before_while = ignore # ignore/add/remove/force/not_defined - -# Add or remove blank line after 'while' statement. -nl_after_while = ignore # ignore/add/remove/force/not_defined - -# Add or remove blank line before 'switch'. -nl_before_switch = ignore # ignore/add/remove/force/not_defined - -# Add or remove blank line after 'switch' statement. -nl_after_switch = ignore # ignore/add/remove/force/not_defined - -# Add or remove blank line before 'synchronized'. -nl_before_synchronized = ignore # ignore/add/remove/force/not_defined - -# Add or remove blank line after 'synchronized' statement. -nl_after_synchronized = ignore # ignore/add/remove/force/not_defined - -# Add or remove blank line before 'do'. -nl_before_do = ignore # ignore/add/remove/force/not_defined - -# Add or remove blank line after 'do/while' statement. -nl_after_do = ignore # ignore/add/remove/force/not_defined - -# Ignore nl_before_{if,for,switch,do,synchronized} if the control -# statement is immediately after a case statement. -# if nl_before_{if,for,switch,do} is set to remove, this option -# does nothing. -nl_before_ignore_after_case = false # true/false - -# Whether to put a blank line before 'return' statements, unless after an open -# brace. -nl_before_return = false # true/false - -# Whether to put a blank line after 'return' statements, unless followed by a -# close brace. -nl_after_return = false # true/false - -# Whether to put a blank line before a member '.' or '->' operators. -nl_before_member = ignore # ignore/add/remove/force/not_defined - -# (Java) Whether to put a blank line after a member '.' or '->' operators. -nl_after_member = ignore # ignore/add/remove/force/not_defined - -# Whether to double-space commented-entries in 'struct'/'union'/'enum'. -nl_ds_struct_enum_cmt = false # true/false - -# Whether to force a newline before '}' of a 'struct'/'union'/'enum'. -# (Lower priority than eat_blanks_before_close_brace.) -nl_ds_struct_enum_close_brace = false # true/false - -# Add or remove newline before or after (depending on pos_class_colon) a class -# colon, as in 'class Foo : public Bar'. -nl_class_colon = ignore # ignore/add/remove/force/not_defined - -# Add or remove newline around a class constructor colon. The exact position -# depends on nl_constr_init_args, pos_constr_colon and pos_constr_comma. -nl_constr_colon = ignore # ignore/add/remove/force/not_defined - -# Whether to collapse a two-line namespace, like 'namespace foo\n{ decl; }' -# into a single line. If true, prevents other brace newline rules from turning -# such code into four lines. If true, it also preserves one-liner namespaces. -nl_namespace_two_to_one_liner = false # true/false - -# Whether to remove a newline in simple unbraced if statements, turning them -# into one-liners, as in 'if(b)\n i++;' => 'if(b) i++;'. -nl_create_if_one_liner = false # true/false - -# Whether to remove a newline in simple unbraced for statements, turning them -# into one-liners, as in 'for (...)\n stmt;' => 'for (...) stmt;'. -nl_create_for_one_liner = false # true/false - -# Whether to remove a newline in simple unbraced while statements, turning -# them into one-liners, as in 'while (expr)\n stmt;' => 'while (expr) stmt;'. -nl_create_while_one_liner = false # true/false - -# Whether to collapse a function definition whose body (not counting braces) -# is only one line so that the entire definition (prototype, braces, body) is -# a single line. -nl_create_func_def_one_liner = false # true/false - -# Whether to split one-line simple list definitions into three lines by -# adding newlines, as in 'int a[12] = { 0 };'. -nl_create_list_one_liner = false # true/false - -# Whether to split one-line simple unbraced if statements into two lines by -# adding a newline, as in 'if(b) i++;'. -nl_split_if_one_liner = false # true/false - -# Whether to split one-line simple unbraced for statements into two lines by -# adding a newline, as in 'for (...) stmt;'. -nl_split_for_one_liner = false # true/false - -# Whether to split one-line simple unbraced while statements into two lines by -# adding a newline, as in 'while (expr) stmt;'. -nl_split_while_one_liner = false # true/false - -# Don't add a newline before a cpp-comment in a parameter list of a function -# call. -donot_add_nl_before_cpp_comment = false # true/false - -# -# Blank line options -# - -# The maximum number of consecutive newlines (3 = 2 blank lines). -nl_max = 0 # unsigned number - -# The maximum number of consecutive newlines in a function. -nl_max_blank_in_func = 0 # unsigned number - -# The number of newlines inside an empty function body. -# This option overrides eat_blanks_after_open_brace and -# eat_blanks_before_close_brace, but is ignored when -# nl_collapse_empty_body_functions=true -nl_inside_empty_func = 0 # unsigned number - -# The number of newlines before a function prototype. -nl_before_func_body_proto = 0 # unsigned number - -# The number of newlines before a multi-line function definition. Where -# applicable, this option is overridden with eat_blanks_after_open_brace=true -nl_before_func_body_def = 0 # unsigned number - -# The number of newlines before a class constructor/destructor prototype. -nl_before_func_class_proto = 0 # unsigned number - -# The number of newlines before a class constructor/destructor definition. -nl_before_func_class_def = 0 # unsigned number - -# The number of newlines after a function prototype. -nl_after_func_proto = 0 # unsigned number - -# The number of newlines after a function prototype, if not followed by -# another function prototype. -nl_after_func_proto_group = 0 # unsigned number - -# The number of newlines after a class constructor/destructor prototype. -nl_after_func_class_proto = 0 # unsigned number - -# The number of newlines after a class constructor/destructor prototype, -# if not followed by another constructor/destructor prototype. -nl_after_func_class_proto_group = 0 # unsigned number - -# Whether one-line method definitions inside a class body should be treated -# as if they were prototypes for the purposes of adding newlines. -# -# Requires nl_class_leave_one_liners=true. Overrides nl_before_func_body_def -# and nl_before_func_class_def for one-liners. -nl_class_leave_one_liner_groups = false # true/false - -# The number of newlines after '}' of a multi-line function body. -# -# Overrides nl_min_after_func_body and nl_max_after_func_body. -nl_after_func_body = 0 # unsigned number - -# The minimum number of newlines after '}' of a multi-line function body. -# -# Only works when nl_after_func_body is 0. -nl_min_after_func_body = 0 # unsigned number - -# The maximum number of newlines after '}' of a multi-line function body. -# -# Only works when nl_after_func_body is 0. -# Takes precedence over nl_min_after_func_body. -nl_max_after_func_body = 0 # unsigned number - -# The number of newlines after '}' of a multi-line function body in a class -# declaration. Also affects class constructors/destructors. -# -# Overrides nl_after_func_body. -nl_after_func_body_class = 0 # unsigned number - -# The number of newlines after '}' of a single line function body. Also -# affects class constructors/destructors. -# -# Overrides nl_after_func_body and nl_after_func_body_class. -nl_after_func_body_one_liner = 0 # unsigned number - -# The number of newlines before a block of typedefs. If nl_after_access_spec -# is non-zero, that option takes precedence. -# -# 0: No change (default). -nl_typedef_blk_start = 0 # unsigned number - -# The number of newlines after a block of typedefs. -# -# 0: No change (default). -nl_typedef_blk_end = 0 # unsigned number - -# The maximum number of consecutive newlines within a block of typedefs. -# -# 0: No change (default). -nl_typedef_blk_in = 0 # unsigned number - -# The minimum number of blank lines after a block of variable definitions -# at the top of a function body. If any preprocessor directives appear -# between the opening brace of the function and the variable block, then -# it is considered as not at the top of the function.Newlines are added -# before trailing preprocessor directives, if any exist. -# -# 0: No change (default). -nl_var_def_blk_end_func_top = 1 # unsigned number - -# The minimum number of empty newlines before a block of variable definitions -# not at the top of a function body. If nl_after_access_spec is non-zero, -# that option takes precedence. Newlines are not added at the top of the -# file or just after an opening brace. Newlines are added above any -# preprocessor directives before the block. -# -# 0: No change (default). -nl_var_def_blk_start = 1 # unsigned number - -# The minimum number of empty newlines after a block of variable definitions -# not at the top of a function body. Newlines are not added if the block -# is at the bottom of the file or just before a preprocessor directive. -# -# 0: No change (default). -nl_var_def_blk_end = 1 # unsigned number - -# The maximum number of consecutive newlines within a block of variable -# definitions. -# -# 0: No change (default). -nl_var_def_blk_in = 1 # unsigned number - -# The minimum number of newlines before a multi-line comment. -# Doesn't apply if after a brace open or another multi-line comment. -nl_before_block_comment = 0 # unsigned number - -# The minimum number of newlines before a single-line C comment. -# Doesn't apply if after a brace open or other single-line C comments. -nl_before_c_comment = 0 # unsigned number - -# The minimum number of newlines before a CPP comment. -# Doesn't apply if after a brace open or other CPP comments. -nl_before_cpp_comment = 0 # unsigned number - -# Whether to force a newline after a multi-line comment. -nl_after_multiline_comment = false # true/false - -# Whether to force a newline after a label's colon. -nl_after_label_colon = false # true/false - -# The number of newlines before a struct definition. -nl_before_struct = 0 # unsigned number - -# The number of newlines after '}' or ';' of a struct/enum/union definition. -nl_after_struct = 0 # unsigned number - -# The number of newlines before a class definition. -nl_before_class = 0 # unsigned number - -# The number of newlines after '}' or ';' of a class definition. -nl_after_class = 0 # unsigned number - -# The number of newlines before a namespace. -nl_before_namespace = 0 # unsigned number - -# The number of newlines after '{' of a namespace. This also adds newlines -# before the matching '}'. -# -# 0: Apply eat_blanks_after_open_brace or eat_blanks_before_close_brace if -# applicable, otherwise no change. -# -# Overrides eat_blanks_after_open_brace and eat_blanks_before_close_brace. -nl_inside_namespace = 0 # unsigned number - -# The number of newlines after '}' of a namespace. -nl_after_namespace = 0 # unsigned number - -# The number of newlines before an access specifier label. This also includes -# the Qt-specific 'signals:' and 'slots:'. Will not change the newline count -# if after a brace open. -# -# 0: No change (default). -nl_before_access_spec = 0 # unsigned number - -# The number of newlines after an access specifier label. This also includes -# the Qt-specific 'signals:' and 'slots:'. Will not change the newline count -# if after a brace open. -# -# 0: No change (default). -# -# Overrides nl_typedef_blk_start and nl_var_def_blk_start. -nl_after_access_spec = 0 # unsigned number - -# The number of newlines between a function definition and the function -# comment, as in '// comment\n void foo() {...}'. -# -# 0: No change (default). -nl_comment_func_def = 0 # unsigned number - -# The number of newlines after a try-catch-finally block that isn't followed -# by a brace close. -# -# 0: No change (default). -nl_after_try_catch_finally = 0 # unsigned number - -# (C#) The number of newlines before and after a property, indexer or event -# declaration. -# -# 0: No change (default). -nl_around_cs_property = 0 # unsigned number - -# (C#) The number of newlines between the get/set/add/remove handlers. -# -# 0: No change (default). -nl_between_get_set = 0 # unsigned number - -# (C#) Add or remove newline between property and the '{'. -nl_property_brace = ignore # ignore/add/remove/force/not_defined - -# Whether to remove blank lines after '{'. -eat_blanks_after_open_brace = true # true/false - -# Whether to remove blank lines before '}'. -eat_blanks_before_close_brace = true # true/false - -# How aggressively to remove extra newlines not in preprocessor. -# -# 0: No change (default) -# 1: Remove most newlines not handled by other config -# 2: Remove all newlines and reformat completely by config -nl_remove_extra_newlines = 0 # unsigned number - -# (Java) Add or remove newline after an annotation statement. Only affects -# annotations that are after a newline. -nl_after_annotation = ignore # ignore/add/remove/force/not_defined - -# (Java) Add or remove newline between two annotations. -nl_between_annotation = ignore # ignore/add/remove/force/not_defined - -# The number of newlines before a whole-file #ifdef. -# -# 0: No change (default). -nl_before_whole_file_ifdef = 0 # unsigned number - -# The number of newlines after a whole-file #ifdef. -# -# 0: No change (default). -nl_after_whole_file_ifdef = 0 # unsigned number - -# The number of newlines before a whole-file #endif. -# -# 0: No change (default). -nl_before_whole_file_endif = 0 # unsigned number - -# The number of newlines after a whole-file #endif. -# -# 0: No change (default). -nl_after_whole_file_endif = 0 # unsigned number - -# -# Positioning options -# - -# The position of arithmetic operators in wrapped expressions. -pos_arith = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of assignment in wrapped expressions. Do not affect '=' -# followed by '{'. -pos_assign = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of Boolean operators in wrapped expressions. -pos_bool = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of comparison operators in wrapped expressions. -pos_compare = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of conditional operators, as in the '?' and ':' of -# 'expr ? stmt : stmt', in wrapped expressions. -pos_conditional = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of the comma in wrapped expressions. -pos_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of the comma in enum entries. -pos_enum_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of the comma in the base class list if there is more than one -# line. Affects nl_class_init_args. -pos_class_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of the comma in the constructor initialization list. -# Related to nl_constr_colon, nl_constr_init_args and pos_constr_colon. -pos_constr_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of trailing/leading class colon, between class and base class -# list. Affects nl_class_colon. -pos_class_colon = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of colons between constructor and member initialization. -# Related to nl_constr_colon, nl_constr_init_args and pos_constr_comma. -pos_constr_colon = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of shift operators in wrapped expressions. -pos_shift = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# -# Line splitting options -# - -# Try to limit code width to N columns. -code_width = 119 # unsigned number - -# Whether to fully split long 'for' statements at semi-colons. -ls_for_split_full = false # true/false - -# Whether to fully split long function prototypes/calls at commas. -# The option ls_code_width has priority over the option ls_func_split_full. -ls_func_split_full = false # true/false - -# Whether to split lines as close to code_width as possible and ignore some -# groupings. -# The option ls_code_width has priority over the option ls_func_split_full. -ls_code_width = false # true/false - -# -# Code alignment options (not left column spaces/tabs) -# - -# Whether to keep non-indenting tabs. -align_keep_tabs = false # true/false - -# Whether to use tabs for aligning. -align_with_tabs = false # true/false - -# Whether to bump out to the next tab when aligning. -align_on_tabstop = false # true/false - -# Whether to right-align numbers. -align_number_right = false # true/false - -# Whether to keep whitespace not required for alignment. -align_keep_extra_space = false # true/false - -# Whether to align variable definitions in prototypes and functions. -align_func_params = false # true/false - -# The span for aligning parameter definitions in function on parameter name. -# -# 0: Don't align (default). -align_func_params_span = 0 # unsigned number - -# The threshold for aligning function parameter definitions. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_func_params_thresh = 0 # number - -# The gap for aligning function parameter definitions. -align_func_params_gap = 0 # unsigned number - -# The span for aligning constructor value. -# -# 0: Don't align (default). -align_constr_value_span = 0 # unsigned number - -# The threshold for aligning constructor value. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_constr_value_thresh = 0 # number - -# The gap for aligning constructor value. -align_constr_value_gap = 0 # unsigned number - -# Whether to align parameters in single-line functions that have the same -# name. The function names must already be aligned with each other. -align_same_func_call_params = false # true/false - -# The span for aligning function-call parameters for single line functions. -# -# 0: Don't align (default). -align_same_func_call_params_span = 0 # unsigned number - -# The threshold for aligning function-call parameters for single line -# functions. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_same_func_call_params_thresh = 0 # number - -# The span for aligning variable definitions. -# -# 0: Don't align (default). -align_var_def_span = 0 # unsigned number - -# How to consider (or treat) the '*' in the alignment of variable definitions. -# -# 0: Part of the type 'void * foo;' (default) -# 1: Part of the variable 'void *foo;' -# 2: Dangling 'void *foo;' -# Dangling: the '*' will not be taken into account when aligning. -align_var_def_star_style = 1 # unsigned number - -# How to consider (or treat) the '&' in the alignment of variable definitions. -# -# 0: Part of the type 'long & foo;' (default) -# 1: Part of the variable 'long &foo;' -# 2: Dangling 'long &foo;' -# Dangling: the '&' will not be taken into account when aligning. -align_var_def_amp_style = 0 # unsigned number - -# The threshold for aligning variable definitions. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_var_def_thresh = 0 # number - -# The gap for aligning variable definitions. -align_var_def_gap = 0 # unsigned number - -# Whether to align the colon in struct bit fields. -align_var_def_colon = false # true/false - -# The gap for aligning the colon in struct bit fields. -align_var_def_colon_gap = 0 # unsigned number - -# Whether to align any attribute after the variable name. -align_var_def_attribute = false # true/false - -# Whether to align inline struct/enum/union variable definitions. -align_var_def_inline = true # true/false - -# The span for aligning on '=' in assignments. -# -# 0: Don't align (default). -align_assign_span = 0 # unsigned number - -# The span for aligning on '=' in function prototype modifier. -# -# 0: Don't align (default). -align_assign_func_proto_span = 0 # unsigned number - -# The threshold for aligning on '=' in assignments. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_assign_thresh = 0 # number - -# Whether to align on the left most assignment when multiple -# definitions are found on the same line. -# Depends on 'align_assign_span' and 'align_assign_thresh' settings. -align_assign_on_multi_var_defs = false # true/false - -# The span for aligning on '{' in braced init list. -# -# 0: Don't align (default). -align_braced_init_list_span = 0 # unsigned number - -# The threshold for aligning on '{' in braced init list. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_braced_init_list_thresh = 0 # number - -# How to apply align_assign_span to function declaration "assignments", i.e. -# 'virtual void foo() = 0' or '~foo() = {default|delete}'. -# -# 0: Align with other assignments (default) -# 1: Align with each other, ignoring regular assignments -# 2: Don't align -align_assign_decl_func = 0 # unsigned number - -# The span for aligning on '=' in enums. -# -# 0: Don't align (default). -align_enum_equ_span = 0 # unsigned number - -# The threshold for aligning on '=' in enums. -# Use a negative number for absolute thresholds. -# -# 0: no limit (default). -align_enum_equ_thresh = 0 # number - -# The span for aligning class member definitions. -# -# 0: Don't align (default). -align_var_class_span = 0 # unsigned number - -# The threshold for aligning class member definitions. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_var_class_thresh = 0 # number - -# The gap for aligning class member definitions. -align_var_class_gap = 0 # unsigned number - -# The span for aligning struct/union member definitions. -# -# 0: Don't align (default). -align_var_struct_span = 0 # unsigned number - -# The threshold for aligning struct/union member definitions. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_var_struct_thresh = 0 # number - -# The gap for aligning struct/union member definitions. -align_var_struct_gap = 0 # unsigned number - -# The span for aligning struct initializer values. -# -# 0: Don't align (default). -align_struct_init_span = 0 # unsigned number - -# The span for aligning single-line typedefs. -# -# 0: Don't align (default). -align_typedef_span = 0 # unsigned number - -# The minimum space between the type and the synonym of a typedef. -align_typedef_gap = 0 # unsigned number - -# How to align typedef'd functions with other typedefs. -# -# 0: Don't mix them at all (default) -# 1: Align the open parenthesis with the types -# 2: Align the function type name with the other type names -align_typedef_func = 0 # unsigned number - -# How to consider (or treat) the '*' in the alignment of typedefs. -# -# 0: Part of the typedef type, 'typedef int * pint;' (default) -# 1: Part of type name: 'typedef int *pint;' -# 2: Dangling: 'typedef int *pint;' -# Dangling: the '*' will not be taken into account when aligning. -align_typedef_star_style = 1 # unsigned number - -# How to consider (or treat) the '&' in the alignment of typedefs. -# -# 0: Part of the typedef type, 'typedef int & intref;' (default) -# 1: Part of type name: 'typedef int &intref;' -# 2: Dangling: 'typedef int &intref;' -# Dangling: the '&' will not be taken into account when aligning. -align_typedef_amp_style = 0 # unsigned number - -# The span for aligning comments that end lines. -# -# 0: Don't align (default). -align_right_cmt_span = 0 # unsigned number - -# Minimum number of columns between preceding text and a trailing comment in -# order for the comment to qualify for being aligned. Must be non-zero to have -# an effect. -align_right_cmt_gap = 0 # unsigned number - -# If aligning comments, whether to mix with comments after '}' and #endif with -# less than three spaces before the comment. -align_right_cmt_mix = false # true/false - -# Whether to only align trailing comments that are at the same brace level. -align_right_cmt_same_level = false # true/false - -# Minimum column at which to align trailing comments. Comments which are -# aligned beyond this column, but which can be aligned in a lesser column, -# may be "pulled in". -# -# 0: Ignore (default). -align_right_cmt_at_col = 0 # unsigned number - -# The span for aligning function prototypes. -# -# 0: Don't align (default). -align_func_proto_span = 0 # unsigned number - -# Whether to ignore continuation lines when evaluating the number of -# new lines for the function prototype alignment's span. -# -# false: continuation lines are part of the newlines count -# true: continuation lines are not counted -align_func_proto_span_ignore_cont_lines = false # true/false - -# How to consider (or treat) the '*' in the alignment of function prototypes. -# -# 0: Part of the type 'void * foo();' (default) -# 1: Part of the function 'void *foo();' -# 2: Dangling 'void *foo();' -# Dangling: the '*' will not be taken into account when aligning. -align_func_proto_star_style = 0 # unsigned number - -# How to consider (or treat) the '&' in the alignment of function prototypes. -# -# 0: Part of the type 'long & foo();' (default) -# 1: Part of the function 'long &foo();' -# 2: Dangling 'long &foo();' -# Dangling: the '&' will not be taken into account when aligning. -align_func_proto_amp_style = 0 # unsigned number - -# The threshold for aligning function prototypes. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_func_proto_thresh = 0 # number - -# Minimum gap between the return type and the function name. -align_func_proto_gap = 0 # unsigned number - -# Whether to align function prototypes on the 'operator' keyword instead of -# what follows. -align_on_operator = false # true/false - -# Whether to mix aligning prototype and variable declarations. If true, -# align_var_def_XXX options are used instead of align_func_proto_XXX options. -align_mix_var_proto = false # true/false - -# Whether to align single-line functions with function prototypes. -# Uses align_func_proto_span. -align_single_line_func = false # true/false - -# Whether to align the open brace of single-line functions. -# Requires align_single_line_func=true. Uses align_func_proto_span. -align_single_line_brace = false # true/false - -# Gap for align_single_line_brace. -align_single_line_brace_gap = 0 # unsigned number - -# (OC) The span for aligning Objective-C message specifications. -# -# 0: Don't align (default). -align_oc_msg_spec_span = 0 # unsigned number - -# Whether and how to align backslashes that split a macro onto multiple lines. -# This will not work right if the macro contains a multi-line comment. -# -# 0: Do nothing (default) -# 1: Align the backslashes in the column at the end of the longest line -# 2: Align with the backslash that is farthest to the left, or, if that -# backslash is farther left than the end of the longest line, at the end of -# the longest line -# 3: Align with the backslash that is farthest to the right -align_nl_cont = 0 # unsigned number - -# The minimum number of spaces between the end of a line and its continuation -# backslash. Requires align_nl_cont. -# -# Default: 1 -align_nl_cont_spaces = 1 # unsigned number - -# Whether to align macro functions and variables together. -align_pp_define_together = false # true/false - -# The span for aligning on '#define' bodies. -# -# =0: Don't align (default) -# >0: Number of lines (including comments) between blocks -align_pp_define_span = 0 # unsigned number - -# The minimum space between label and value of a preprocessor define. -align_pp_define_gap = 0 # unsigned number - -# Whether to align lines that start with '<<' with previous '<<'. -# -# Default: true -align_left_shift = true # true/false - -# Whether to align comma-separated statements following '<<' (as used to -# initialize Eigen matrices). -align_eigen_comma_init = false # true/false - -# Whether to align text after 'asm volatile ()' colons. -align_asm_colon = false # true/false - -# (OC) Span for aligning parameters in an Objective-C message call -# on the ':'. -# -# 0: Don't align. -align_oc_msg_colon_span = 0 # unsigned number - -# (OC) Whether to always align with the first parameter, even if it is too -# short. -align_oc_msg_colon_first = false # true/false - -# (OC) Whether to align parameters in an Objective-C '+' or '-' declaration -# on the ':'. -align_oc_decl_colon = false # true/false - -# (OC) Whether to not align parameters in an Objectve-C message call if first -# colon is not on next line of the message call (the same way Xcode does -# alignment) -align_oc_msg_colon_xcode_like = false # true/false - -# -# Comment modification options -# - -# Try to wrap comments at N columns. -cmt_width = 0 # unsigned number - -# How to reflow comments. -# -# 0: No reflowing (apart from the line wrapping due to cmt_width) (default) -# 1: No touching at all -# 2: Full reflow (enable cmt_indent_multi for indent with line wrapping due to cmt_width) -cmt_reflow_mode = 0 # unsigned number - -# Path to a file that contains regular expressions describing patterns for -# which the end of one line and the beginning of the next will be folded into -# the same sentence or paragraph during full comment reflow. The regular -# expressions are described using ECMAScript syntax. The syntax for this -# specification is as follows, where "..." indicates the custom regular -# expression and "n" indicates the nth end_of_prev_line_regex and -# beg_of_next_line_regex regular expression pair: -# -# end_of_prev_line_regex[1] = "...$" -# beg_of_next_line_regex[1] = "^..." -# end_of_prev_line_regex[2] = "...$" -# beg_of_next_line_regex[2] = "^..." -# . -# . -# . -# end_of_prev_line_regex[n] = "...$" -# beg_of_next_line_regex[n] = "^..." -# -# Note that use of this option overrides the default reflow fold regular -# expressions, which are internally defined as follows: -# -# end_of_prev_line_regex[1] = "[\w,\]\)]$" -# beg_of_next_line_regex[1] = "^[\w,\[\(]" -# end_of_prev_line_regex[2] = "\.$" -# beg_of_next_line_regex[2] = "^[A-Z]" -cmt_reflow_fold_regex_file = "" # string - -# Whether to indent wrapped lines to the start of the encompassing paragraph -# during full comment reflow (cmt_reflow_mode = 2). Overrides the value -# specified by cmt_sp_after_star_cont. -# -# Note that cmt_align_doxygen_javadoc_tags overrides this option for -# paragraphs associated with javadoc tags -cmt_reflow_indent_to_paragraph_start = false # true/false - -# Whether to convert all tabs to spaces in comments. If false, tabs in -# comments are left alone, unless used for indenting. -cmt_convert_tab_to_spaces = true # true/false - -# Whether to apply changes to multi-line comments, including cmt_width, -# keyword substitution and leading chars. -# -# Default: true -cmt_indent_multi = true # true/false - -# Whether to align doxygen javadoc-style tags ('@param', '@return', etc.) -# and corresponding fields such that groups of consecutive block tags, -# parameter names, and descriptions align with one another. Overrides that -# which is specified by the cmt_sp_after_star_cont. If cmt_width > 0, it may -# be necessary to enable cmt_indent_multi and set cmt_reflow_mode = 2 -# in order to achieve the desired alignment for line-wrapping. -cmt_align_doxygen_javadoc_tags = false # true/false - -# The number of spaces to insert after the star and before doxygen -# javadoc-style tags (@param, @return, etc). Requires enabling -# cmt_align_doxygen_javadoc_tags. Overrides that which is specified by the -# cmt_sp_after_star_cont. -# -# Default: 1 -cmt_sp_before_doxygen_javadoc_tags = 1 # unsigned number - -# Whether to change trailing, single-line c-comments into cpp-comments. -cmt_trailing_single_line_c_to_cpp = false # true/false - -# Whether to group c-comments that look like they are in a block. -cmt_c_group = false # true/false - -# Whether to put an empty '/*' on the first line of the combined c-comment. -cmt_c_nl_start = false # true/false - -# Whether to add a newline before the closing '*/' of the combined c-comment. -cmt_c_nl_end = false # true/false - -# Whether to change cpp-comments into c-comments. -cmt_cpp_to_c = true # true/false - -# Whether to group cpp-comments that look like they are in a block. Only -# meaningful if cmt_cpp_to_c=true. -cmt_cpp_group = true # true/false - -# Whether to put an empty '/*' on the first line of the combined cpp-comment -# when converting to a c-comment. -# -# Requires cmt_cpp_to_c=true and cmt_cpp_group=true. -cmt_cpp_nl_start = true # true/false - -# Whether to add a newline before the closing '*/' of the combined cpp-comment -# when converting to a c-comment. -# -# Requires cmt_cpp_to_c=true and cmt_cpp_group=true. -cmt_cpp_nl_end = true # true/false - -# Whether to put a star on subsequent comment lines. -cmt_star_cont = false # true/false - -# The number of spaces to insert at the start of subsequent comment lines. -cmt_sp_before_star_cont = 0 # unsigned number - -# The number of spaces to insert after the star on subsequent comment lines. -cmt_sp_after_star_cont = 0 # unsigned number - -# For multi-line comments with a '*' lead, remove leading spaces if the first -# and last lines of the comment are the same length. -# -# Default: true -cmt_multi_check_last = true # true/false - -# For multi-line comments with a '*' lead, remove leading spaces if the first -# and last lines of the comment are the same length AND if the length is -# bigger as the first_len minimum. -# -# Default: 4 -cmt_multi_first_len_minimum = 4 # unsigned number - -# Path to a file that contains text to insert at the beginning of a file if -# the file doesn't start with a C/C++ comment. If the inserted text contains -# '$(filename)', that will be replaced with the current file's name. -cmt_insert_file_header = "" # string - -# Path to a file that contains text to insert at the end of a file if the -# file doesn't end with a C/C++ comment. If the inserted text contains -# '$(filename)', that will be replaced with the current file's name. -cmt_insert_file_footer = "" # string - -# Path to a file that contains text to insert before a function definition if -# the function isn't preceded by a C/C++ comment. If the inserted text -# contains '$(function)', '$(javaparam)' or '$(fclass)', these will be -# replaced with, respectively, the name of the function, the javadoc '@param' -# and '@return' stuff, or the name of the class to which the member function -# belongs. -cmt_insert_func_header = "" # string - -# Path to a file that contains text to insert before a class if the class -# isn't preceded by a C/C++ comment. If the inserted text contains '$(class)', -# that will be replaced with the class name. -cmt_insert_class_header = "" # string - -# Path to a file that contains text to insert before an Objective-C message -# specification, if the method isn't preceded by a C/C++ comment. If the -# inserted text contains '$(message)' or '$(javaparam)', these will be -# replaced with, respectively, the name of the function, or the javadoc -# '@param' and '@return' stuff. -cmt_insert_oc_msg_header = "" # string - -# Whether a comment should be inserted if a preprocessor is encountered when -# stepping backwards from a function name. -# -# Applies to cmt_insert_oc_msg_header, cmt_insert_func_header and -# cmt_insert_class_header. -cmt_insert_before_preproc = false # true/false - -# Whether a comment should be inserted if a function is declared inline to a -# class definition. -# -# Applies to cmt_insert_func_header. -# -# Default: true -cmt_insert_before_inlines = true # true/false - -# Whether a comment should be inserted if the function is a class constructor -# or destructor. -# -# Applies to cmt_insert_func_header. -cmt_insert_before_ctor_dtor = false # true/false - -# -# Code modifying options (non-whitespace) -# - -# Add or remove braces on a single-line 'do' statement. -mod_full_brace_do = add # ignore/add/remove/force/not_defined - -# Add or remove braces on a single-line 'for' statement. -mod_full_brace_for = add # ignore/add/remove/force/not_defined - -# (Pawn) Add or remove braces on a single-line function definition. -mod_full_brace_function = ignore # ignore/add/remove/force/not_defined - -# Add or remove braces on a single-line 'if' statement. Braces will not be -# removed if the braced statement contains an 'else'. -mod_full_brace_if = add # ignore/add/remove/force/not_defined - -# Whether to enforce that all blocks of an 'if'/'else if'/'else' chain either -# have, or do not have, braces. Overrides mod_full_brace_if. -# -# 0: Don't override mod_full_brace_if -# 1: Add braces to all blocks if any block needs braces and remove braces if -# they can be removed from all blocks -# 2: Add braces to all blocks if any block already has braces, regardless of -# whether it needs them -# 3: Add braces to all blocks if any block needs braces and remove braces if -# they can be removed from all blocks, except if all blocks have braces -# despite none needing them -mod_full_brace_if_chain = 0 # unsigned number - -# Whether to add braces to all blocks of an 'if'/'else if'/'else' chain. -# If true, mod_full_brace_if_chain will only remove braces from an 'if' that -# does not have an 'else if' or 'else'. -mod_full_brace_if_chain_only = false # true/false - -# Add or remove braces on single-line 'while' statement. -mod_full_brace_while = ignore # ignore/add/remove/force/not_defined - -# Add or remove braces on single-line 'using ()' statement. -mod_full_brace_using = ignore # ignore/add/remove/force/not_defined - -# Don't remove braces around statements that span N newlines -mod_full_brace_nl = 0 # unsigned number - -# Whether to prevent removal of braces from 'if'/'for'/'while'/etc. blocks -# which span multiple lines. -# -# Affects: -# mod_full_brace_for -# mod_full_brace_if -# mod_full_brace_if_chain -# mod_full_brace_if_chain_only -# mod_full_brace_while -# mod_full_brace_using -# -# Does not affect: -# mod_full_brace_do -# mod_full_brace_function -mod_full_brace_nl_block_rem_mlcond = false # true/false - -# Add or remove unnecessary parentheses on 'return' statement. -mod_paren_on_return = ignore # ignore/add/remove/force/not_defined - -# Add or remove unnecessary parentheses on 'throw' statement. -mod_paren_on_throw = ignore # ignore/add/remove/force/not_defined - -# (Pawn) Whether to change optional semicolons to real semicolons. -mod_pawn_semicolon = false # true/false - -# Whether to fully parenthesize Boolean expressions in 'while' and 'if' -# statement, as in 'if (a && b > c)' => 'if (a && (b > c))'. -mod_full_paren_if_bool = false # true/false - -# Whether to fully parenthesize Boolean expressions after '=' -# statement, as in 'x = a && b > c;' => 'x = (a && (b > c));'. -mod_full_paren_assign_bool = false # true/false - -# Whether to fully parenthesize Boolean expressions after '=' -# statement, as in 'return a && b > c;' => 'return (a && (b > c));'. -mod_full_paren_return_bool = false # true/false - -# Whether to remove superfluous semicolons. -mod_remove_extra_semicolon = false # true/false - -# Whether to remove duplicate include. -mod_remove_duplicate_include = false # true/false - -# the following options (mod_XX_closebrace_comment) use different comment, -# depending of the setting of the next option. -# false: Use the c comment (default) -# true : Use the cpp comment -mod_add_force_c_closebrace_comment = false # true/false - -# If a function body exceeds the specified number of newlines and doesn't have -# a comment after the close brace, a comment will be added. -mod_add_long_function_closebrace_comment = 0 # unsigned number - -# If a namespace body exceeds the specified number of newlines and doesn't -# have a comment after the close brace, a comment will be added. -mod_add_long_namespace_closebrace_comment = 0 # unsigned number - -# If a class body exceeds the specified number of newlines and doesn't have a -# comment after the close brace, a comment will be added. -mod_add_long_class_closebrace_comment = 0 # unsigned number - -# If a switch body exceeds the specified number of newlines and doesn't have a -# comment after the close brace, a comment will be added. -mod_add_long_switch_closebrace_comment = 0 # unsigned number - -# If an #ifdef body exceeds the specified number of newlines and doesn't have -# a comment after the #endif, a comment will be added. -mod_add_long_ifdef_endif_comment = 0 # unsigned number - -# If an #ifdef or #else body exceeds the specified number of newlines and -# doesn't have a comment after the #else, a comment will be added. -mod_add_long_ifdef_else_comment = 0 # unsigned number - -# Whether to take care of the case by the mod_sort_xx options. -mod_sort_case_sensitive = false # true/false - -# Whether to sort consecutive single-line 'import' statements. -mod_sort_import = false # true/false - -# (C#) Whether to sort consecutive single-line 'using' statements. -mod_sort_using = false # true/false - -# Whether to sort consecutive single-line '#include' statements (C/C++) and -# '#import' statements (Objective-C). Be aware that this has the potential to -# break your code if your includes/imports have ordering dependencies. -mod_sort_include = false # true/false - -# Whether to prioritize '#include' and '#import' statements that contain -# filename without extension when sorting is enabled. -mod_sort_incl_import_prioritize_filename = false # true/false - -# Whether to prioritize '#include' and '#import' statements that does not -# contain extensions when sorting is enabled. -mod_sort_incl_import_prioritize_extensionless = false # true/false - -# Whether to prioritize '#include' and '#import' statements that contain -# angle over quotes when sorting is enabled. -mod_sort_incl_import_prioritize_angle_over_quotes = false # true/false - -# Whether to ignore file extension in '#include' and '#import' statements -# for sorting comparison. -mod_sort_incl_import_ignore_extension = false # true/false - -# Whether to group '#include' and '#import' statements when sorting is enabled. -mod_sort_incl_import_grouping_enabled = false # true/false - -# Whether to move a 'break' that appears after a fully braced 'case' before -# the close brace, as in 'case X: { ... } break;' => 'case X: { ... break; }'. -mod_move_case_break = false # true/false - -# Whether to move a 'return' that appears after a fully braced 'case' before -# the close brace, as in 'case X: { ... } return;' => 'case X: { ... return; }'. -mod_move_case_return = false # true/false - -# Add or remove braces around a fully braced case statement. Will only remove -# braces if there are no variable declarations in the block. -mod_case_brace = ignore # ignore/add/remove/force/not_defined - -# Whether to remove a void 'return;' that appears as the last statement in a -# function. -mod_remove_empty_return = false # true/false - -# Add or remove the comma after the last value of an enumeration. -mod_enum_last_comma = ignore # ignore/add/remove/force/not_defined - -# Syntax to use for infinite loops. -# -# 0: Leave syntax alone (default) -# 1: Rewrite as `for(;;)` -# 2: Rewrite as `while(true)` -# 3: Rewrite as `do`...`while(true);` -# 4: Rewrite as `while(1)` -# 5: Rewrite as `do`...`while(1);` -# -# Infinite loops that do not already match one of these syntaxes are ignored. -# Other options that affect loop formatting will be applied after transforming -# the syntax. -mod_infinite_loop = 0 # unsigned number - -# Add or remove the 'int' keyword in 'int short'. -mod_int_short = ignore # ignore/add/remove/force/not_defined - -# Add or remove the 'int' keyword in 'short int'. -mod_short_int = ignore # ignore/add/remove/force/not_defined - -# Add or remove the 'int' keyword in 'int long'. -mod_int_long = ignore # ignore/add/remove/force/not_defined - -# Add or remove the 'int' keyword in 'long int'. -mod_long_int = ignore # ignore/add/remove/force/not_defined - -# Add or remove the 'int' keyword in 'int signed'. -mod_int_signed = ignore # ignore/add/remove/force/not_defined - -# Add or remove the 'int' keyword in 'signed int'. -mod_signed_int = ignore # ignore/add/remove/force/not_defined - -# Add or remove the 'int' keyword in 'int unsigned'. -mod_int_unsigned = ignore # ignore/add/remove/force/not_defined - -# Add or remove the 'int' keyword in 'unsigned int'. -mod_unsigned_int = ignore # ignore/add/remove/force/not_defined - -# If there is a situation where mod_int_* and mod_*_int would result in -# multiple int keywords, whether to keep the rightmost int (the default) or the -# leftmost int. -mod_int_prefer_int_on_left = false # true/false - -# (OC) Whether to organize the properties. If true, properties will be -# rearranged according to the mod_sort_oc_property_*_weight factors. -mod_sort_oc_properties = false # true/false - -# (OC) Weight of a class property modifier. -mod_sort_oc_property_class_weight = 0 # number - -# (OC) Weight of 'atomic' and 'nonatomic'. -mod_sort_oc_property_thread_safe_weight = 0 # number - -# (OC) Weight of 'readwrite' when organizing properties. -mod_sort_oc_property_readwrite_weight = 0 # number - -# (OC) Weight of a reference type specifier ('retain', 'copy', 'assign', -# 'weak', 'strong') when organizing properties. -mod_sort_oc_property_reference_weight = 0 # number - -# (OC) Weight of getter type ('getter=') when organizing properties. -mod_sort_oc_property_getter_weight = 0 # number - -# (OC) Weight of setter type ('setter=') when organizing properties. -mod_sort_oc_property_setter_weight = 0 # number - -# (OC) Weight of nullability type ('nullable', 'nonnull', 'null_unspecified', -# 'null_resettable') when organizing properties. -mod_sort_oc_property_nullability_weight = 0 # number - -# -# Preprocessor options -# - -# How to use tabs when indenting preprocessor code. -# -# -1: Use 'indent_with_tabs' setting (default) -# 0: Spaces only -# 1: Indent with tabs to brace level, align with spaces -# 2: Indent and align with tabs, using spaces when not on a tabstop -# -# Default: -1 -pp_indent_with_tabs = -1 # number - -# Add or remove indentation of preprocessor directives inside #if blocks -# at brace level 0 (file-level). -pp_indent = ignore # ignore/add/remove/force/not_defined - -# Whether to indent #if/#else/#endif at the brace level. If false, these are -# indented from column 1. -pp_indent_at_level = false # true/false - -# Whether to indent #if/#else/#endif at the parenthesis level if the brace -# level is 0. If false, these are indented from column 1. -pp_indent_at_level0 = false # true/false - -# Specifies the number of columns to indent preprocessors per level -# at brace level 0 (file-level). If pp_indent_at_level=false, also specifies -# the number of columns to indent preprocessors per level -# at brace level > 0 (function-level). -# -# Default: 1 -pp_indent_count = 1 # unsigned number - -# Add or remove space after # based on pp level of #if blocks. -pp_space_after = ignore # ignore/add/remove/force/not_defined - -# Sets the number of spaces per level added with pp_space_after. -pp_space_count = 0 # unsigned number - -# The indent for '#region' and '#endregion' in C# and '#pragma region' in -# C/C++. Negative values decrease indent down to the first column. -pp_indent_region = 0 # number - -# Whether to indent the code between #region and #endregion. -pp_region_indent_code = false # true/false - -# If pp_indent_at_level=true, sets the indent for #if, #else and #endif when -# not at file-level. Negative values decrease indent down to the first column. -# -# =0: Indent preprocessors using output_tab_size -# >0: Column at which all preprocessors will be indented -pp_indent_if = 0 # number - -# Whether to indent the code between #if, #else and #endif. -pp_if_indent_code = false # true/false - -# Whether to indent the body of an #if that encompasses all the code in the file. -pp_indent_in_guard = false # true/false - -# Whether to indent '#define' at the brace level. If false, these are -# indented from column 1. -pp_define_at_level = false # true/false - -# Whether to indent '#include' at the brace level. -pp_include_at_level = false # true/false - -# Whether to ignore the '#define' body while formatting. -pp_ignore_define_body = false # true/false - -# An offset value that controls the indentation of the body of a multiline #define. -# 'body' refers to all the lines of a multiline #define except the first line. -# Requires 'pp_ignore_define_body = false'. -# -# <0: Absolute column: the body indentation starts off at the specified column -# (ex. -3 ==> the body is indented starting from column 3) -# >=0: Relative to the column of the '#' of '#define' -# (ex. 3 ==> the body is indented starting 3 columns at the right of '#') -# -# Default: 8 -pp_multiline_define_body_indent = 4 # number - -# Whether to indent case statements between #if, #else, and #endif. -# Only applies to the indent of the preprocessor that the case statements -# directly inside of. -# -# Default: true -pp_indent_case = true # true/false - -# Whether to indent whole function definitions between #if, #else, and #endif. -# Only applies to the indent of the preprocessor that the function definition -# is directly inside of. -# -# Default: true -pp_indent_func_def = true # true/false - -# Whether to indent extern C blocks between #if, #else, and #endif. -# Only applies to the indent of the preprocessor that the extern block is -# directly inside of. -# -# Default: true -pp_indent_extern = true # true/false - -# How to indent braces directly inside #if, #else, and #endif. -# Requires pp_if_indent_code=true and only applies to the indent of the -# preprocessor that the braces are directly inside of. -# 0: No extra indent -# 1: Indent by one level -# -1: Preserve original indentation -# -# Default: 1 -pp_indent_brace = 1 # number - -# Whether to print warning messages for unbalanced #if and #else blocks. -# This will print a message in the following cases: -# - if an #ifdef block ends on a different indent level than -# where it started from. Example: -# -# #ifdef TEST -# int i; -# { -# int j; -# #endif -# -# - an #elif/#else block ends on a different indent level than -# the corresponding #ifdef block. Example: -# -# #ifdef TEST -# int i; -# #else -# } -# int j; -# #endif -pp_warn_unbalanced_if = false # true/false - -# -# Sort includes options -# - -# The regex for include category with priority 0. -include_category_0 = "" # string - -# The regex for include category with priority 1. -include_category_1 = "" # string - -# The regex for include category with priority 2. -include_category_2 = "" # string - -# -# Use or Do not Use options -# - -# true: indent_func_call_param will be used (default) -# false: indent_func_call_param will NOT be used -# -# Default: true -use_indent_func_call_param = true # true/false - -# The value of the indentation for a continuation line is calculated -# differently if the statement is: -# - a declaration: your case with QString fileName ... -# - an assignment: your case with pSettings = new QSettings( ... -# -# At the second case the indentation value might be used twice: -# - at the assignment -# - at the function call (if present) -# -# To prevent the double use of the indentation value, use this option with the -# value 'true'. -# -# true: indent_continue will be used only once -# false: indent_continue will be used every time (default) -# -# Requires indent_ignore_first_continue=false. -use_indent_continue_only_once = false # true/false - -# The indentation can be: -# - after the assignment, at the '[' character -# - at the beginning of the lambda body -# -# true: indentation will be at the beginning of the lambda body -# false: indentation will be after the assignment (default) -indent_cpp_lambda_only_once = false # true/false - -# Whether sp_after_angle takes precedence over sp_inside_fparen. This was the -# historic behavior, but is probably not the desired behavior, so this is off -# by default. -use_sp_after_angle_always = false # true/false - -# Whether to apply special formatting for Qt SIGNAL/SLOT macros. Essentially, -# this tries to format these so that they match Qt's normalized form (i.e. the -# result of QMetaObject::normalizedSignature), which can slightly improve the -# performance of the QObject::connect call, rather than how they would -# otherwise be formatted. -# -# See options_for_QT.cpp for details. -# -# Default: true -use_options_overriding_for_qt_macros = true # true/false - -# If true: the form feed character is removed from the list of whitespace -# characters. See https://en.cppreference.com/w/cpp/string/byte/isspace. -use_form_feed_no_more_as_whitespace_character = false # true/false - -# -# Warn levels - 1: error, 2: warning (default), 3: note -# - -# (C#) Warning is given if doing tab-to-\t replacement and we have found one -# in a C# verbatim string literal. -# -# Default: 2 -warn_level_tabs_found_in_verbatim_string_literals = 2 # unsigned number - -# Limit the number of loops. -# Used by uncrustify.cpp to exit from infinite loop. -# 0: no limit. -debug_max_number_of_loops = 0 # number - -# Set the number of the line to protocol; -# Used in the function prot_the_line if the 2. parameter is zero. -# 0: nothing protocol. -debug_line_number_to_protocol = 0 # number - -# Set the number of second(s) before terminating formatting the current file, -# 0: no timeout. -# only for linux -debug_timeout = 0 # number - -# Set the number of characters to be printed if the text is too long, -# 0: do not truncate. -debug_truncate = 0 # unsigned number - -# sort (or not) the tracking info. -# -# Default: true -debug_sort_the_tracks = true # true/false - -# decode (or not) the flags as a new line. -# only if the -p option is set. -debug_decode_the_flags = false # true/false - -# use (or not) the exit(EX_SOFTWARE) function. -# -# Default: true -debug_use_the_exit_function_pop = true # true/false - -# insert the number of the line at the beginning of each line -set_numbering_for_html_output = false # true/false - -# Meaning of the settings: -# Ignore - do not do any changes -# Add - makes sure there is 1 or more space/brace/newline/etc -# Force - makes sure there is exactly 1 space/brace/newline/etc, -# behaves like Add in some contexts -# Remove - removes space/brace/newline/etc -# -# -# - Token(s) can be treated as specific type(s) with the 'set' option: -# `set tokenType tokenString [tokenString...]` -# -# Example: -# `set BOOL __AND__ __OR__` -# -# tokenTypes are defined in src/token_enum.h, use them without the -# 'CT_' prefix: 'CT_BOOL' => 'BOOL' -# -# -# - Token(s) can be treated as type(s) with the 'type' option. -# `type tokenString [tokenString...]` -# -# Example: -# `type int c_uint_8 Rectangle` -# -# This can also be achieved with `set TYPE int c_uint_8 Rectangle` -# -# -# To embed whitespace in tokenStrings use the '\' escape character, or quote -# the tokenStrings. These quotes are supported: "'` -# -# -# - Support for the auto detection of languages through the file ending can be -# added using the 'file_ext' command. -# `file_ext langType langString [langString..]` -# -# Example: -# `file_ext CPP .ch .cxx .cpp.in` -# -# langTypes are defined in uncrusify_types.h in the lang_flag_e enum, use -# them without the 'LANG_' prefix: 'LANG_CPP' => 'CPP' -# -# -# - Custom macro-based indentation can be set up using 'macro-open', -# 'macro-else' and 'macro-close'. -# `(macro-open | macro-else | macro-close) tokenString` -# -# Example: -# `macro-open BEGIN_TEMPLATE_MESSAGE_MAP` -# `macro-open BEGIN_MESSAGE_MAP` -# `macro-close END_MESSAGE_MAP` -# -# -# option(s) with 'not default' value: 75 -# From 17c882f1d749c6df4bea1e2f29f67935485f83db Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 13 Jun 2025 17:30:50 +0200 Subject: [PATCH 1259/1333] ci: Replace uncrustify with clang-format in style-check Remove uncrustify installation and config usage. Install clang-format instead. Add check to compare local .clang-format with core version to prevent config mismatch. Use clang-format-diff on git diff to enforce style. --- .github/workflows/compliance_check.yml | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index a0eef08bba..e40ffede8c 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -33,13 +33,30 @@ jobs: shell: bash run: | sudo apt-get update - sudo apt-get install -y uncrustify - mkdir repos - git clone --depth=1 https://github.com/apache/mynewt-core repos/apache-mynewt-core + sudo apt-get install -y clang-format - name: check style shell: bash run: | - ./repos/apache-mynewt-core/.github/check_style.py + wget -O .clang-format-core https://raw.githubusercontent.com/apache/mynewt-core/refs/heads/master/.clang-format + if ! cmp -s ".clang-format-core" ".clang-format"; then + echo "Mismatched clang-format configurations!" + exit 1 + fi + + set +e + INFO_URL="https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md" + git diff -U0 origin/master...HEAD > diff.patch + clang-format-diff -p1 -style=file < diff.patch > clang-fmt.patch + if [ -s clang-fmt.patch ]; then + echo "Code formatting issues found:" + cat clang-fmt.patch + echo "" + echo "For formatting guidelines, see:" + echo " $INFO_URL" + exit 1 + else + echo "All good, no formatting issues." + fi style_license: name: Licensing From 3ae5a2a41fcfdf0b40f5248a0076f4d9aa67b520 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 23 Jun 2025 13:16:19 +0200 Subject: [PATCH 1260/1333] ci: Add workflows up-to-date check This checks if PRs are using up-to-date workflows. --- check_workflows.yml | 71 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 check_workflows.yml diff --git a/check_workflows.yml b/check_workflows.yml new file mode 100644 index 0000000000..1d9f6e90be --- /dev/null +++ b/check_workflows.yml @@ -0,0 +1,71 @@ +# +# 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. +# + +name: Check workflows status + +on: + pull_request_target: + types: [opened, synchronize, reopened, labeled, unlabeled] + +permissions: + pull-requests: read + contents: read + +jobs: + check-workflows: + runs-on: ubuntu-latest + steps: + - name: Check out master branch (base) + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.base.ref }} + path: master_branch + + - name: Check out PR branch (head) + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + path: pr_branch + + - name: Check for label override + id: label_check + uses: actions/github-script@v7 + with: + script: | + const labelName = 'workflows-update'; + const labels = await github.rest.issues.listLabelsOnIssue({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number, + }); + const hasLabel = labels.data.some(label => label.name === labelName); + core.setOutput('skip', hasLabel); + + - name: Compare workflows between master and PR + if: steps.label_check.outputs.skip != 'true' + run: | + echo "Checking if .github/workflows/ differs from master..." + diff -r master_branch/.github/workflows pr_branch/.github/workflows || { + echo "::error::Workflows differ from master. Please rebase or apply 'workflows-update' label to bypass."; + exit 1; + } + + - name: Skip message if label present + if: steps.label_check.outputs.skip == 'true' + run: echo "Skipping workflows check because 'workflows-update' label is present." From 5d07ffe1bd40b30d2660f7b0b985a55cf4704a1b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 23 Jun 2025 15:06:00 +0200 Subject: [PATCH 1261/1333] ci: Move workflow to correct place It was accidentally commited into top folder. --- check_workflows.yml => .github/workflows/check_workflows.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename check_workflows.yml => .github/workflows/check_workflows.yml (100%) diff --git a/check_workflows.yml b/.github/workflows/check_workflows.yml similarity index 100% rename from check_workflows.yml rename to .github/workflows/check_workflows.yml From 037568d4a973c965a7159df91dce9ede20bc99fe Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Fri, 20 Jun 2025 09:09:11 +0200 Subject: [PATCH 1262/1333] host tests: Fix test that accessed unspecified memory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Depending on compiler optimization and version ble_att_svr_test_read_mult() could rise error: In function ‘memcpy’, inlined from ‘TEST_CASE_ble_att_svr_test_read_mult’ at repos/apache-mynewt-nimble/nimble/host/test/src/ble_att_svr_test.c:1027:5: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:29:10: error: ‘__builtin_memcpy’ forming offset [18, 19] is out of the bounds [0, 18] of object ‘({anonymous})’ with type ‘uint8_t[18]’ {aka ‘unsigned char[18]’} [-Werror=array-bounds=] 29 | return __builtin___memcpy_chk (__dest, __src, __len, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 30 | __glibc_objsize0 (__dest)); array was clearly to short for memcpy and later data with 20 bytes had 2 unspecified values at the end Signed-off-by: Jerzy Kasenberg --- nimble/host/test/src/ble_att_svr_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/test/src/ble_att_svr_test.c b/nimble/host/test/src/ble_att_svr_test.c index 95b5eec67c..0a31280dcf 100644 --- a/nimble/host/test/src/ble_att_svr_test.c +++ b/nimble/host/test/src/ble_att_svr_test.c @@ -1026,7 +1026,7 @@ TEST_CASE_SELF(ble_att_svr_test_read_mult) attrs[1].value_len = 20; memcpy(attrs[1].value, ((uint8_t[]){ - 22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39 + 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39 }), attrs[1].value_len); ble_att_svr_test_attr_r_2_len = attrs[1].value_len; From fe23e0693adbcfa92520eaf878516facbebc2c0e Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Fri, 20 Jun 2025 10:07:30 +0200 Subject: [PATCH 1263/1333] nimble/gatt: Silence test build build warnings Two test functions trigger false positive warning about usage of uninitialized variables. Now some local variables are initialized to silence those warnings Signed-off-by: Jerzy Kasenberg --- nimble/host/test/src/ble_gatts_notify_test.c | 6 +++--- nimble/host/test/src/ble_gatts_reg_test.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nimble/host/test/src/ble_gatts_notify_test.c b/nimble/host/test/src/ble_gatts_notify_test.c index 254ac4407b..72fd637512 100644 --- a/nimble/host/test/src/ble_gatts_notify_test.c +++ b/nimble/host/test/src/ble_gatts_notify_test.c @@ -474,9 +474,9 @@ static void ble_gatts_notify_test_misc_verify_tx_gen(uint16_t conn_handle, int attr_idx, uint8_t chr_flags) { - uint16_t attr_handle; - uint16_t attr_len; - void *attr_val; + uint16_t attr_handle = 0; + uint16_t attr_len = 0; + void *attr_val = NULL; switch (attr_idx) { case 1: diff --git a/nimble/host/test/src/ble_gatts_reg_test.c b/nimble/host/test/src/ble_gatts_reg_test.c index ea69028e88..ddbfe8f24f 100644 --- a/nimble/host/test/src/ble_gatts_reg_test.c +++ b/nimble/host/test/src/ble_gatts_reg_test.c @@ -261,7 +261,7 @@ ble_gatts_reg_test_misc_lookup_bad(struct ble_gatts_reg_test_entry *entry) static void ble_gatts_reg_test_misc_verify_entry(uint8_t op, const ble_uuid_t *uuid) { - struct ble_gatts_reg_test_entry *entry; + struct ble_gatts_reg_test_entry *entry = NULL; int i; for (i = 0; i < ble_gatts_reg_test_num_entries; i++) { From 7cb544a8f81875257d5437176b81f123a1ab1df9 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Tue, 24 Jun 2025 13:02:51 +0200 Subject: [PATCH 1264/1333] ci: Force style check workflow to use pip-installed clang-format Replace apt-based clang-format install with pip to ensure consistency across environments. Also update diff base to use merge-base and switch to clang-format-diff.py for more accurate formatting checks. --- .github/workflows/compliance_check.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index e40ffede8c..cd92851cfc 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -32,8 +32,7 @@ jobs: - name: Install Dependencies shell: bash run: | - sudo apt-get update - sudo apt-get install -y clang-format + python -m pip install clang-format - name: check style shell: bash run: | @@ -45,8 +44,9 @@ jobs: set +e INFO_URL="https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md" - git diff -U0 origin/master...HEAD > diff.patch - clang-format-diff -p1 -style=file < diff.patch > clang-fmt.patch + GIT_BASE=$(git merge-base origin/master HEAD) + git diff -U0 "$GIT_BASE"...HEAD > diff.patch + clang-format-diff.py -p1 -style=file < diff.patch > clang-fmt.patch if [ -s clang-fmt.patch ]; then echo "Code formatting issues found:" cat clang-fmt.patch From 248f50b1d2124de4b36d3aa9909bf96d29a2ba02 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Thu, 26 Jun 2025 15:56:13 +0530 Subject: [PATCH 1265/1333] nimble/host: Add a missing instance of ble_hs_unblock() --- nimble/host/src/ble_att.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index 471f6cab97..6d4e05af12 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -515,6 +515,7 @@ ble_att_send_outstanding_after_response(uint16_t conn_handle) rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT, &conn, &chan); if (rc) { + ble_hs_unlock(); return; } conn->client_att_busy = false; From b9035d28c68a19789a1427a029b03fa759d906f9 Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Wed, 25 Jun 2025 12:43:53 +0200 Subject: [PATCH 1266/1333] nimble/host: ble_hs_stop: Handle BLE_HS_EALREADY case If `ble_hs_stop_terminate_conn()` returns `BLE_HS_EALREADY`, the stop callback may be triggered before the HCI Disconnection Complete event is received. Until that event, some connection-related resources are still in use, and calling APIs like `ble_gatts_reset()` will return BUSY. Let's use the host stop timeout for the use case with BLE_HS_EALREADY to make sure the stop callback won't be sent too early. Call HCI reset in the stop sequence to reset the LL state. --- nimble/host/src/ble_hs_stop.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_hs_stop.c b/nimble/host/src/ble_hs_stop.c index e48fff389c..2a07329eb5 100644 --- a/nimble/host/src/ble_hs_stop.c +++ b/nimble/host/src/ble_hs_stop.c @@ -42,6 +42,13 @@ static uint8_t ble_hs_stop_conn_cnt; static struct ble_npl_callout ble_hs_stop_terminate_tmo; +static int +ble_hs_stop_hci_reset(void) +{ + return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, BLE_HCI_OCF_CB_RESET), + NULL, 0, NULL, 0); +} + /** * Called when a stop procedure has completed. */ @@ -62,6 +69,14 @@ ble_hs_stop_done(int status) ble_hs_enabled_state = BLE_HS_ENABLED_STATE_OFF; + ble_hs_stop_hci_reset(); + + /* After LL reset the controller loses its random address */ + ble_hs_id_reset(); + + /* Clear advertising, scanning and connection states. */ + ble_gap_reset_state(0); + ble_hs_unlock(); SLIST_FOREACH(listener, &slist, link) { @@ -114,7 +129,7 @@ ble_hs_stop_terminate_conn(struct ble_hs_conn *conn, void *arg) int rc; rc = ble_gap_terminate_with_conn(conn, BLE_ERR_REM_USER_CONN_TERM); - if (rc == 0) { + if (rc == 0 || rc == BLE_HS_EALREADY) { /* Terminate procedure successfully initiated. Let the GAP event * handler deal with the result. */ @@ -256,6 +271,8 @@ ble_hs_stop(struct ble_hs_stop_listener *listener, return rc; } + ble_hs_stop_conn_cnt = 0; + ble_hs_lock(); ble_hs_conn_foreach(ble_hs_stop_terminate_conn, NULL); ble_hs_unlock(); From c870b0a3bb3783ba9515fcf032d5542d0017d591 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 26 Jun 2025 17:32:45 +0200 Subject: [PATCH 1267/1333] ci: Disable string breaking in clang-format Previous configuration produced weirdly formatted results while dealing with long strings. --- .clang-format | 1 + 1 file changed, 1 insertion(+) diff --git a/.clang-format b/.clang-format index 276f7fe434..626746ae31 100644 --- a/.clang-format +++ b/.clang-format @@ -79,6 +79,7 @@ SpacesInParentheses: false SpaceAfterCStyleCast: false SpaceBeforeParens: ControlStatementsExceptControlMacros SpaceInEmptyParentheses: false +BreakStringLiterals: false AlignArrayOfStructures: Left SortIncludes: false From 3afbb0da97655ce8390a10c6e9ae14d2e22a664c Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 26 Jun 2025 17:50:46 +0200 Subject: [PATCH 1268/1333] nimble/btp: Keep sizeof parenthesis consistent Ensure all sizeof use parenthesis for consitency. --- apps/bttester/src/btp_gatt.c | 56 ++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/apps/bttester/src/btp_gatt.c b/apps/bttester/src/btp_gatt.c index 2baa1c8353..17c083bf3a 100644 --- a/apps/bttester/src/btp_gatt.c +++ b/apps/bttester/src/btp_gatt.c @@ -355,14 +355,13 @@ gatt_svr_read_write_test(uint16_t conn_handle, uint16_t attr_handle, case PTS_CHR_NOTIFY: case PTS_CHR_NOTIFY_ALT: if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_short_val, + rc = gatt_svr_chr_write(conn_handle, attr_handle, ctxt->om, 0, + sizeof(gatt_svr_pts_static_short_val), &gatt_svr_pts_static_short_val, NULL); return rc; } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_short_val, - sizeof gatt_svr_pts_static_short_val); + sizeof(gatt_svr_pts_static_short_val)); return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } default: @@ -386,14 +385,13 @@ gatt_svr_read_write_long_test(uint16_t conn_handle, uint16_t attr_handle, case PTS_LONG_CHR_READ_WRITE: case PTS_LONG_CHR_READ_WRITE_ALT: if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_long_val, + rc = gatt_svr_chr_write(conn_handle, attr_handle, ctxt->om, 0, + sizeof(gatt_svr_pts_static_long_val), &gatt_svr_pts_static_long_val, NULL); return rc; } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_long_val, - sizeof gatt_svr_pts_static_long_val); + sizeof(gatt_svr_pts_static_long_val)); return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } default: @@ -416,14 +414,13 @@ gatt_svr_read_write_auth_test(uint16_t conn_handle, uint16_t attr_handle, switch (uuid16) { case PTS_CHR_READ_WRITE_AUTHEN: if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_val, + rc = gatt_svr_chr_write(conn_handle, attr_handle, ctxt->om, 0, + sizeof(gatt_svr_pts_static_val), &gatt_svr_pts_static_val, NULL); return rc; } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_val, - sizeof gatt_svr_pts_static_val); + sizeof(gatt_svr_pts_static_val)); return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } default: @@ -470,12 +467,11 @@ gatt_svr_read_write_enc_test(uint16_t conn_handle, uint16_t attr_handle, case PTS_CHR_READ_WRITE_ENC: if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_val, - sizeof gatt_svr_pts_static_val); + sizeof(gatt_svr_pts_static_val)); return rc; } else if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_val, + rc = gatt_svr_chr_write(conn_handle, attr_handle, ctxt->om, 0, + sizeof(gatt_svr_pts_static_val), &gatt_svr_pts_static_val, NULL); return rc; } @@ -499,14 +495,13 @@ gatt_svr_dsc_read_write_test(uint16_t conn_handle, uint16_t attr_handle, switch (uuid16) { case PTS_DSC_READ_WRITE: if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_DSC) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_short_val, + rc = gatt_svr_chr_write(conn_handle, attr_handle, ctxt->om, 0, + sizeof(gatt_svr_pts_static_short_val), &gatt_svr_pts_static_short_val, NULL); return rc; } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC) { rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_short_val, - sizeof gatt_svr_pts_static_short_val); + sizeof(gatt_svr_pts_static_short_val)); return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } default: @@ -529,14 +524,13 @@ gatt_svr_dsc_read_write_long_test(uint16_t conn_handle, uint16_t attr_handle, switch (uuid16) { case PTS_LONG_DSC_READ_WRITE: if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_DSC) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_long_val, + rc = gatt_svr_chr_write(conn_handle, attr_handle, ctxt->om, 0, + sizeof(gatt_svr_pts_static_long_val), &gatt_svr_pts_static_long_val, NULL); return rc; } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC) { rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_long_val, - sizeof gatt_svr_pts_static_long_val); + sizeof(gatt_svr_pts_static_long_val)); return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } default: @@ -560,7 +554,7 @@ gatt_svr_dsc_read_test(uint16_t conn_handle, uint16_t attr_handle, case PTS_DSC_READ: if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC) { rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_long_val, - sizeof gatt_svr_pts_static_long_val); + sizeof(gatt_svr_pts_static_long_val)); return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } default: @@ -583,14 +577,13 @@ gatt_svr_write_no_rsp_test(uint16_t conn_handle, uint16_t attr_handle, switch (uuid16) { case PTS_CHR_WRITE_NO_RSP: if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_short_val, + rc = gatt_svr_chr_write(conn_handle, attr_handle, ctxt->om, 0, + sizeof(gatt_svr_pts_static_short_val), &gatt_svr_pts_static_short_val, NULL); return rc; } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_short_val, - sizeof gatt_svr_pts_static_short_val); + sizeof(gatt_svr_pts_static_short_val)); return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } default: @@ -613,9 +606,8 @@ gatt_svr_rel_write_test(uint16_t conn_handle, uint16_t attr_handle, switch (uuid16) { case PTS_CHR_RELIABLE_WRITE: if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - rc = gatt_svr_chr_write(conn_handle, attr_handle, - ctxt->om, 0, - sizeof gatt_svr_pts_static_val, + rc = gatt_svr_chr_write(conn_handle, attr_handle, ctxt->om, 0, + sizeof(gatt_svr_pts_static_val), &gatt_svr_pts_static_val, NULL); return rc; } From da659c9f800bc7d310c7e9e2d7cadb34bfe513c9 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 27 Jun 2025 14:17:33 +0200 Subject: [PATCH 1269/1333] ci: Add workflow to sync .clang-format If changes are detected, it updates the local file and automatically opens a pull request on the current repository to apply the update. This ensures consistent and up-to-date code formatting configuration. Uses: - GitHub Actions with cron trigger (daily at 06:00 UTC) - peter-evans/create-pull-request@v7 for automated PR creation [1]: https://github.com/peter-evans/create-pull-request --- .github/workflows/format_file_check.yml | 68 +++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .github/workflows/format_file_check.yml diff --git a/.github/workflows/format_file_check.yml b/.github/workflows/format_file_check.yml new file mode 100644 index 0000000000..c1b477ec06 --- /dev/null +++ b/.github/workflows/format_file_check.yml @@ -0,0 +1,68 @@ +# +# 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. +# + +name: Sync clang-format + +on: + schedule: + - cron: '0 6 * * *' + +jobs: + sync: + runs-on: ubuntu-24.04 + permissions: + contents: write + pull-requests: write + + if: github.event.repository.fork == false + steps: + - name: Checkout current repo + uses: actions/checkout@v4 + + - name: Download .clang-format from source + run: | + wget -O .clang-format-core https://raw.githubusercontent.com/apache/mynewt-core/refs/heads/master/.clang-format + + - name: Check for changes & replace + id: changed + run: | + if ! cmp -s ".clang-format-core" ".clang-format"; then + echo "🔄 .clang-format has changed, updating..." + diff -u .clang-format .clang-format-core + mv .clang-format-core .clang-format + echo "changed=true" >> $GITHUB_OUTPUT + else + echo "✅ No changes detected." + echo "changed=false" >> $GITHUB_OUTPUT + fi + + - name: Create Pull Request + if: steps.changed.outputs.changed == 'true' + uses: peter-evans/create-pull-request@v7 + with: + author: Mynewt Bot + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: | + ci: Update .clang-format from apache-mynewt-core + branch: update-clang-format + title: "Update clang format" + body: | + Syncing the latest .clang-format file from apache-mynewt-core + + [1]: https://github.com/peter-evans/create-pull-request From 99b805cb84c5edd499ccce4996a4ff115278956c Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 27 Jun 2025 14:56:46 +0200 Subject: [PATCH 1270/1333] ci: Remove compliance check for config file Configuration file will be updated daily. No need to check it for every pull request. --- .github/workflows/compliance_check.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index cd92851cfc..7da84f929b 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -36,12 +36,6 @@ jobs: - name: check style shell: bash run: | - wget -O .clang-format-core https://raw.githubusercontent.com/apache/mynewt-core/refs/heads/master/.clang-format - if ! cmp -s ".clang-format-core" ".clang-format"; then - echo "Mismatched clang-format configurations!" - exit 1 - fi - set +e INFO_URL="https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md" GIT_BASE=$(git merge-base origin/master HEAD) From 76c5704d77bfcd1b163f76c1114b166a72e7853f Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Mon, 30 Jun 2025 10:53:35 +0200 Subject: [PATCH 1271/1333] ci: Format file check - disable exit on failure Add `set +e` to the format_file_check.yml. to allow non-critical commands (e.g., git diff) to fail gracefully. This prevents early termination and enables custom handling of command exit codes when needed. --- .github/workflows/format_file_check.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/format_file_check.yml b/.github/workflows/format_file_check.yml index c1b477ec06..f67a053117 100644 --- a/.github/workflows/format_file_check.yml +++ b/.github/workflows/format_file_check.yml @@ -42,6 +42,7 @@ jobs: - name: Check for changes & replace id: changed run: | + set +e if ! cmp -s ".clang-format-core" ".clang-format"; then echo "🔄 .clang-format has changed, updating..." diff -u .clang-format .clang-format-core From dedfaf5c9cc9c71d1b88f611548210a280745995 Mon Sep 17 00:00:00 2001 From: Henrik Schnor Date: Fri, 27 Jun 2025 15:27:10 +0200 Subject: [PATCH 1272/1333] nimble/ll: Avoid dereferencing an invalid pointer The data pointer in the mbuf of outgoing empty packets is invalid. This adds a check to avoid dereferencing it. --- nimble/controller/src/ble_ll_conn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 52446b6471..e9e5fc6f15 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -1341,7 +1341,8 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm) (CONN_IS_PERIPHERAL(connsm) && (md == 0) && (connsm->cons_rxd_bad_crc == 0) && ((connsm->last_rxd_hdr_byte & BLE_LL_DATA_HDR_MD_MASK) == 0) && - !ble_ll_ctrl_is_terminate_ind(hdr_byte, m->om_data[0]))) { + ((connsm->flags.empty_pdu_txd) || + !ble_ll_ctrl_is_terminate_ind(hdr_byte, m->om_data[0])))) { /* We will end the connection event */ end_transition = BLE_PHY_TRANSITION_NONE; txend_func = ble_ll_conn_wait_txend; From d2ec455b6d39089386ae5cf9debd37b88b9de994 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Fri, 27 Jun 2025 17:14:23 +0200 Subject: [PATCH 1273/1333] ci: Skip style-check workflow if label is present This update adds a label-based conditional to the compliance_check.yml GitHub Actions workflow. If a pull request includes the label `skip-style-check`, the style check step will be skipped. This allows maintainers to bypass formatting validation in exceptional cases, such as bulk updates or style-irrelevant changes. --- .github/workflows/compliance_check.yml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index 7da84f929b..9ad768a404 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -19,7 +19,9 @@ name: Compliance check -on: [pull_request] +on: + pull_request: + types: [opened, synchronize, reopened, labeled, unlabeled] jobs: style_check: @@ -33,7 +35,23 @@ jobs: shell: bash run: | python -m pip install clang-format + + - name: Check label + id: label_check + uses: actions/github-script@v7 + with: + script: | + const labelName = 'skip-style-check'; + const labels = await github.rest.issues.listLabelsOnIssue({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number, + }); + const hasLabel = labels.data.some(label => label.name === labelName); + core.setOutput('skip', hasLabel); + - name: check style + if: steps.label_check.outputs.skip != 'true' shell: bash run: | set +e From cd7effe8cc0d801de0e271725834fdd6252a87ee Mon Sep 17 00:00:00 2001 From: Mynewt Bot Date: Tue, 1 Jul 2025 06:03:58 +0000 Subject: [PATCH 1274/1333] ci: Update .clang-format from apache-mynewt-core --- .clang-format | 1 + 1 file changed, 1 insertion(+) diff --git a/.clang-format b/.clang-format index 626746ae31..193a5f6b51 100644 --- a/.clang-format +++ b/.clang-format @@ -32,6 +32,7 @@ MacroBlockEnd: '(STATS_NAME_END|STATS_SECT_END)' StatementMacros: ['SLIST_HEAD'] ForEachMacros: + - 'LINK_TABLE_FOREACH' - 'SLIST_FOREACH' - 'SLIST_FOREACH_FROM' - 'SLIST_FOREACH_SAFE' From 4659d199835ca680631fa3d54494377c8796e780 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 30 Jun 2025 17:56:37 +0200 Subject: [PATCH 1275/1333] host/pvcy: reset state when stopping host Without this fix, connections were not automatically resolved after stopping/starting the host/controller. Signed-off-by: Gerard Marull-Paretas --- nimble/host/src/ble_hs_pvcy.c | 7 +++++++ nimble/host/src/ble_hs_pvcy_priv.h | 1 + nimble/host/src/ble_hs_stop.c | 2 ++ 3 files changed, 10 insertions(+) diff --git a/nimble/host/src/ble_hs_pvcy.c b/nimble/host/src/ble_hs_pvcy.c index f7cf090c09..c122633563 100644 --- a/nimble/host/src/ble_hs_pvcy.c +++ b/nimble/host/src/ble_hs_pvcy.c @@ -261,3 +261,10 @@ ble_hs_pvcy_set_mode(const ble_addr_t *addr, uint8_t priv_mode) BLE_HCI_OCF_LE_SET_PRIVACY_MODE), &cmd, sizeof(cmd), NULL, 0); } + +void +ble_hs_pvcy_reset(void) +{ + ble_hs_pvcy_started = 0; + memset(ble_hs_pvcy_irk, 0, sizeof(ble_hs_pvcy_irk)); +} diff --git a/nimble/host/src/ble_hs_pvcy_priv.h b/nimble/host/src/ble_hs_pvcy_priv.h index 7f0aa4b907..59a132cd4d 100644 --- a/nimble/host/src/ble_hs_pvcy_priv.h +++ b/nimble/host/src/ble_hs_pvcy_priv.h @@ -35,6 +35,7 @@ int ble_hs_pvcy_add_entry(const uint8_t *addr, uint8_t addrtype, const uint8_t *irk); int ble_hs_pvcy_ensure_started(void); int ble_hs_pvcy_set_mode(const ble_addr_t *addr, uint8_t priv_mode); +void ble_hs_pvcy_reset(void); #ifdef __cplusplus } diff --git a/nimble/host/src/ble_hs_stop.c b/nimble/host/src/ble_hs_stop.c index 2a07329eb5..6d5c36d8fc 100644 --- a/nimble/host/src/ble_hs_stop.c +++ b/nimble/host/src/ble_hs_stop.c @@ -74,6 +74,8 @@ ble_hs_stop_done(int status) /* After LL reset the controller loses its random address */ ble_hs_id_reset(); + ble_hs_pvcy_reset(); + /* Clear advertising, scanning and connection states. */ ble_gap_reset_state(0); From e48a0af8740128a76989cc295f6ce27d114a111e Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 3 Feb 2025 18:52:19 +0100 Subject: [PATCH 1276/1333] nimble/ll: Prevent BIG event preemption by periodic advertising This update adjusts the scheduling policy for periodic advertising to ensure it does not preempt BIG events. This ensures stability and performance of audio. --- nimble/controller/src/ble_ll_sched.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c index 8f4599bdf3..7f1ac96054 100644 --- a/nimble/controller/src/ble_ll_sched.c +++ b/nimble/controller/src/ble_ll_sched.c @@ -114,6 +114,16 @@ preempt_any_except_conn(struct ble_ll_sched_item *sch, return ble_ll_conn_is_lru(sch->cb_arg, item->cb_arg); } +static int +preempt_any_except_big(struct ble_ll_sched_item *sch, struct ble_ll_sched_item *item) +{ + if (item->sched_type == BLE_LL_SCHED_TYPE_BIG) { + return 0; + } + + return 1; +} + static inline int ble_ll_sched_check_overlap(struct ble_ll_sched_item *sch1, struct ble_ll_sched_item *sch2) @@ -746,7 +756,7 @@ ble_ll_sched_periodic_adv(struct ble_ll_sched_item *sch, bool first_event) rc = ble_ll_sched_insert(sch, BLE_LL_SCHED_MAX_DELAY_ANY, preempt_none); } else { - rc = ble_ll_sched_insert(sch, 0, preempt_any); + rc = ble_ll_sched_insert(sch, 0, preempt_any_except_big); } OS_EXIT_CRITICAL(sr); From 9073465a8e5e58d0ad7d615182900c37db873c9a Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Fri, 4 Jul 2025 12:07:17 +0200 Subject: [PATCH 1277/1333] drivers/nrf5x/phy: use nrf52_clock_hfxo_request|release if PEBBLEOS On PebbleOS we need reference counted access to HFXO because other parts of the system rely on it (I2S). It seems like this needs a more generic solution (maybe a porting layer function?), as on a sufficiently complex system this will likely be needed. For now adding PEBBLEOS define check, similar to what was done for RIOT. Signed-off-by: Gerard Marull-Paretas --- nimble/drivers/nrf5x/src/ble_phy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 3deec7dd63..634d580712 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -2319,7 +2319,7 @@ ble_phy_dtm_carrier(uint8_t rf_channel) void ble_phy_rfclk_enable(void) { -#if MYNEWT || defined(RIOT_VERSION) +#if MYNEWT || defined(RIOT_VERSION) || defined(PEBBLEOS) #ifdef NRF52_SERIES nrf52_clock_hfxo_request(); #endif @@ -2334,7 +2334,7 @@ ble_phy_rfclk_enable(void) void ble_phy_rfclk_disable(void) { -#if MYNEWT || defined(RIOT_VERSION) +#if MYNEWT || defined(RIOT_VERSION) || defined(PEBBLEOS) #ifdef NRF52_SERIES nrf52_clock_hfxo_release(); #endif From 3160b8c4c7ff8db4e0f9badcdf7df684b151e077 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 30 Jun 2025 16:48:09 +0200 Subject: [PATCH 1278/1333] nimble/gap: Check if conn is present if with asserts disabled BLE_HS_DBG_ASSERT is not enabled by default, and that code is already handling error path. --- nimble/host/src/ble_gap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 64f96bd27d..baa010e0b4 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -2092,6 +2092,9 @@ ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance) /* We verified that there is a free connection when the procedure began. */ conn = ble_hs_conn_alloc(evt->connection_handle); BLE_HS_DBG_ASSERT(conn != NULL); + if (conn == NULL) { + return BLE_HS_ENOMEM; + } conn->bhc_itvl = evt->conn_itvl; conn->bhc_latency = evt->conn_latency; From 0caf9baeb271ede85fcc5237ab87ddbf938600da Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 30 Jun 2025 16:50:29 +0200 Subject: [PATCH 1279/1333] nimble/host: Check if HCI command buffer was allocated BLE_HS_DBG_ASSERT is not enabled by default, and that code is already handling error path. --- nimble/host/src/ble_hs_hci_cmd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/host/src/ble_hs_hci_cmd.c b/nimble/host/src/ble_hs_hci_cmd.c index 689cb1765b..9d1ecf9ca2 100644 --- a/nimble/host/src/ble_hs_hci_cmd.c +++ b/nimble/host/src/ble_hs_hci_cmd.c @@ -51,6 +51,9 @@ ble_hs_hci_cmd_send(uint16_t opcode, uint8_t len, const void *cmddata) cmd = ble_transport_alloc_cmd(); BLE_HS_DBG_ASSERT(cmd != NULL); + if (cmd == NULL) { + return BLE_HS_ENOMEM; + } cmd->opcode = htole16(opcode); cmd->length = len; From b973df0c6cf7b30efbf8eb2cafdc1ee843464b76 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 30 Jun 2025 15:31:04 +0200 Subject: [PATCH 1280/1333] nimble/transport: Skip H4 event parsing if received event is too big If received HCI event is too big to handle just return error and stop parsing instead of overwriting data in memeory. --- nimble/transport/common/hci_h4/src/hci_h4.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimble/transport/common/hci_h4/src/hci_h4.c b/nimble/transport/common/hci_h4/src/hci_h4.c index 9af046ab63..fd89154a34 100644 --- a/nimble/transport/common/hci_h4/src/hci_h4.c +++ b/nimble/transport/common/hci_h4/src/hci_h4.c @@ -168,6 +168,9 @@ hci_h4_sm_w4_header(struct hci_h4_sm *h4sm, struct hci_h4_input_buffer *ib) } h4sm->exp_len = h4sm->hdr[1] + 2; + if (h4sm->exp_len > MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE)) { + return -1; + } break; case HCI_H4_ISO: assert(h4sm->allocs && h4sm->allocs->iso); From 0474bee43a27ff73f1dcbff29a11777f91b20b93 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Fri, 4 Jul 2025 10:21:38 +0200 Subject: [PATCH 1281/1333] nimble/phy/nrf5x: Fix races in TIMER0 setup In cases where RADIO ISR is delayed during transitions it's possible that TIMER0 is not set properly and that could stall phy in waiting state. This is more likely to happen on non-Mynewt systems where IRQs can be configured/handled differently than on Mynewt. There are few issues handled here: 1. Make sure we always set CC register in proper order, i.e. clear COMPARE event, then enable related PPI, then set the proper CC value. This ensures that whenever COMPARE event is triggered, radio is ready to handle it. 2. Handle case where CC may be set to the current value of TIMER0. This would not trigger COMPARE event so it should be handled as a miss. 3. Reset all CC registers to 0 on start of each event. This prevents spurious triggers of COMPARE event due to some leftovers from previous event. We don't need to do this on each TX/RX because at the start of each TX/RX the values in CC registers are either start times or captured timer of previous TX/RX thus they are always in the past. --- nimble/drivers/nrf5x/src/ble_phy.c | 70 ++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/nimble/drivers/nrf5x/src/ble_phy.c b/nimble/drivers/nrf5x/src/ble_phy.c index 634d580712..6f9e051423 100644 --- a/nimble/drivers/nrf5x/src/ble_phy.c +++ b/nimble/drivers/nrf5x/src/ble_phy.c @@ -349,6 +349,32 @@ struct nrf_ccm_data struct nrf_ccm_data g_nrf_ccm_data; #endif +static void +timer0_reset(void) +{ + /* Reset CC registers to avoid triggering spurious COMPARE events */ + NRF_TIMER0->CC[0] = 0; + NRF_TIMER0->CC[1] = 0; + NRF_TIMER0->CC[2] = 0; + NRF_TIMER0->CC[3] = 0; +} + +static bool +timer0_did_miss(int cc, int cc_scratch) +{ + uint32_t now, target; + + nrf_timer_task_trigger(NRF_TIMER0, nrf_timer_capture_task_get(cc_scratch)); + target = NRF_TIMER0->CC[cc]; + now = NRF_TIMER0->CC[cc_scratch]; + + /* COMPARE event is not triggered when CC is set to the current value of + * TIMER0 (at the time it was set), so the case of equal CC values without + * a COMPARE event should be also considered a miss here. + */ + return (now >= target) && !NRF_TIMER0->EVENTS_COMPARE[cc]; +} + #if MYNEWT_VAL(BLE_LL_PHY) /* Packet start offset (in usecs). This is the preamble plus access address. @@ -706,6 +732,8 @@ ble_phy_set_start_time(uint32_t cputime, uint8_t rem_us, bool tx) return -1; } + timer0_reset(); + /* Clear and set TIMER0 to fire off at proper time */ nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CLEAR); nrf_timer_cc_set(NRF_TIMER0, 0, radio_rem_us + rem_us_corr); @@ -885,27 +913,24 @@ ble_phy_wfr_enable(int txrx, uint8_t tx_phy_mode, uint32_t wfr_usecs) /* Adjust for delay between actual access address RX and EVENT_ADDRESS */ end_time += g_ble_phy_t_rxaddrdelay[phy]; - /* wfr_secs is the time from rxen until timeout */ - nrf_timer_cc_set(NRF_TIMER0, 3, end_time); - NRF_TIMER0->EVENTS_COMPARE[3] = 0; - /* Enable wait for response PPI */ + NRF_TIMER0->EVENTS_COMPARE[3] = 0; phy_ppi_wfr_enable(); + nrf_timer_cc_set(NRF_TIMER0, 3, end_time); /* - * It may happen that if CPU is halted for a brief moment (e.g. during flash - * erase or write), TIMER0 already counted past CC[3] and thus wfr will not - * fire as expected. In case this happened, let's just disable PPIs for wfr - * and trigger wfr manually (i.e. disable radio). + * It may happen that if CPU is halted for a brief moment (e.g. during + * flash, erase or write), TIMER0 already counted past CC[3] and thus wfr + * will not fire as expected. In case this happened, let's just disable + * PPIs for wfr and trigger wfr manually (i.e. disable radio). * * Note that the same applies to RX start time set in CC[0] but since it * should fire earlier than wfr, fixing wfr is enough. * - * CC[1] is only used as a reference on RX start, we do not need it here so - * it can be used to read TIMER0 counter. + * CC[1] is only used as a reference on RX start. We do not need it here, + * so we can use it as a scratch register. */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE1); - if (NRF_TIMER0->CC[1] > NRF_TIMER0->CC[3]) { + if (timer0_did_miss(3, 1)) { phy_ppi_wfr_disable(); nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); } @@ -1096,15 +1121,15 @@ ble_phy_tx_end_isr(void) #if PHY_USE_FEM_LNA fem_time = rx_time - MYNEWT_VAL(BLE_FEM_LNA_TURN_ON_US); - nrf_timer_cc_set(NRF_TIMER0, 2, fem_time); NRF_TIMER0->EVENTS_COMPARE[2] = 0; phy_fem_enable_lna(); + nrf_timer_cc_set(NRF_TIMER0, 2, fem_time); #endif radio_time = rx_time - BLE_PHY_T_RXENFAST; - nrf_timer_cc_set(NRF_TIMER0, 0, radio_time); NRF_TIMER0->EVENTS_COMPARE[0] = 0; phy_ppi_timer0_compare0_to_radio_rxen_enable(); + nrf_timer_cc_set(NRF_TIMER0, 0, radio_time); /* In case TIMER0 did already count past CC[0] and/or CC[2], radio * and/or LNA may not be enabled. In any case we won't be stuck since @@ -1142,18 +1167,17 @@ ble_phy_tx_end_isr(void) tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; radio_time = tx_time - BLE_PHY_T_TXENFAST; - nrf_timer_cc_set(NRF_TIMER0, 0, radio_time); NRF_TIMER0->EVENTS_COMPARE[0] = 0; phy_ppi_timer0_compare0_to_radio_txen_enable(); + nrf_timer_cc_set(NRF_TIMER0, 0, radio_time); #if PHY_USE_FEM_PA - nrf_timer_cc_set(NRF_TIMER0, 2, fem_time); NRF_TIMER0->EVENTS_COMPARE[2] = 0; phy_fem_enable_pa(); + nrf_timer_cc_set(NRF_TIMER0, 2, fem_time); #endif - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); - if (NRF_TIMER0->CC[3] > NRF_TIMER0->CC[0]) { + if (timer0_did_miss(0, 3)) { phy_ppi_timer0_compare0_to_radio_txen_disable(); g_ble_phy_data.phy_transition_late = 1; } @@ -1292,14 +1316,14 @@ ble_phy_rx_end_isr(void) tx_time -= g_ble_phy_t_txdelay[g_ble_phy_data.phy_cur_phy_mode]; radio_time = tx_time - BLE_PHY_T_TXENFAST; - nrf_timer_cc_set(NRF_TIMER0, 0, radio_time); NRF_TIMER0->EVENTS_COMPARE[0] = 0; phy_ppi_timer0_compare0_to_radio_txen_enable(); + nrf_timer_cc_set(NRF_TIMER0, 0, radio_time); #if PHY_USE_FEM_PA - nrf_timer_cc_set(NRF_TIMER0, 2, fem_time); NRF_TIMER0->EVENTS_COMPARE[2] = 0; phy_fem_enable_pa(); + nrf_timer_cc_set(NRF_TIMER0, 2, fem_time); #endif /* Need to check if TIMER0 did not already count past CC[0] and/or CC[2], so @@ -1308,11 +1332,9 @@ ble_phy_rx_end_isr(void) * * Note: CC[3] is used only for wfr which we do not need here. */ - nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); - is_late = (NRF_TIMER0->CC[3] > radio_time) && !NRF_TIMER0->EVENTS_COMPARE[0]; + is_late = timer0_did_miss(0, 3); #if PHY_USE_FEM_PA - is_late = is_late || - ((NRF_TIMER0->CC[3] > fem_time) && !NRF_TIMER0->EVENTS_COMPARE[2]); + is_late = is_late || timer0_did_miss(2, 3); #endif if (is_late) { phy_ppi_timer0_compare0_to_radio_txen_disable(); From c64845826b66aa79d6a21a97c4e049e3f92300d8 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Mon, 7 Jul 2025 12:48:17 +0200 Subject: [PATCH 1282/1333] controller: Add subrating condition in syscfg Add condition for enabling subrating for controller based on value set in host configuration. --- nimble/controller/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 1e830dbecb..517cfe0fdf 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -353,7 +353,7 @@ syscfg.defs: Enables support LE Enhanced Connection Update. This allows to use Conenction Subrate Update and Connection Subrate Request procedures to modify subrate paramters for a connection. - value: 0 + value: MYNEWT_VAL(BLE_CONN_SUBRATING) restrictions: - '(BLE_VERSION >= 53) if 1' From c24e5ed33cd19b16f021dbbe566a740a73b61b1a Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Tue, 8 Jul 2025 14:54:14 +0200 Subject: [PATCH 1283/1333] nimble/btp: Fix address assignment in padv operations In periodic sync procedure assignment was wrong due to device not being connected - this resulted in assert condition trigger. Also during periodic transfer reception we now assign proper address to send to tester. Previous lookup for connection was wrong, due to invalid parameter passed into `ble_gap_conn_find` function. --- apps/bttester/src/btp_gap.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index ef87b0154b..48e9958677 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -1202,17 +1202,11 @@ bond_lost(uint16_t conn_handle) static void sync_established(struct ble_gap_event *event) { - int rc; - struct ble_gap_conn_desc desc; struct gap_periodic_sync_est_ev ev; ev.status = event->periodic_sync.status; ev.sync_handle = event->periodic_sync.sync_handle; - - rc = ble_gap_conn_find(ev.sync_handle, &desc); - assert(rc == 0); - - ev.peer_addr = desc.peer_id_addr; + ev.peer_addr = event->periodic_sync.adv_addr; tester_event(BTP_SERVICE_ID_GAP, GAP_EV_PERIODIC_SYNC_ESTABLISHED, (uint8_t *) &ev, sizeof(ev)); @@ -1261,7 +1255,7 @@ periodic_transfer_received(struct ble_gap_event *event) ev.sync_handle = event->periodic_transfer.sync_handle; ev.status = event->periodic_transfer.status; - rc = ble_gap_conn_find(ev.sync_handle, &desc); + rc = ble_gap_conn_find(event->periodic_transfer.conn_handle, &desc); assert(rc == 0); ev.peer_addr = desc.peer_id_addr; From 77a383d4ba68f6dd8d1c7faa32670ea593ffcacd Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 3 Jul 2025 12:04:18 +0200 Subject: [PATCH 1284/1333] ci: Add information about skipping style check If skip-style-check label is present print information about skipping the workflow. --- .github/workflows/compliance_check.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index 9ad768a404..ba90fc26d8 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -70,6 +70,10 @@ jobs: echo "All good, no formatting issues." fi + - name: Skip style-check if label present + if: steps.label_check.outputs.skip == 'true' + run: echo "Skipping style check because 'skip-style-check' label is present." + style_license: name: Licensing runs-on: ubuntu-24.04 From 3bb26716e66f8db4663e7972d27fce9c09898fca Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Thu, 3 Jul 2025 11:09:32 +0200 Subject: [PATCH 1285/1333] ci: add GitHub Action to validate commit message style This workflow checks all commits between the current branch and upstream/master. It enforces subject length, colon usage in the subject line, and body line length. This helps maintain consistency and readability in the project's history. --- .github/workflows/compliance_check.yml | 70 ++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index ba90fc26d8..afc2458477 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -110,3 +110,73 @@ jobs: shell: bash run: | .github/check_doxygen.py + + commits-check: + name: Check commit messages + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Validate commit message style + shell: bash + run: | + set -e + has_errors=0 + COMMIT_URL="https://cwiki.apache.org/confluence/display/MYNEWT/Contributing+to+Apache+Mynewt" + + # Determine commit range for PR or fallback to origin/master + if [ -n "${GITHUB_BASE_REF}" ]; then + base_ref="origin/${GITHUB_BASE_REF}" + else + base_ref="origin/master" + fi + + base_commit=$(git merge-base HEAD ${base_ref}) + + echo "Checking commits from ${base_commit} to HEAD" + + for commit in $(git rev-list --no-merges ${base_commit}..HEAD); do + short_sha=$(git rev-parse --short=7 $commit) + subject=$(git log -1 --pretty=format:%s $commit) + body=$(git log -1 --pretty=format:%b $commit) + + if [ ${#subject} -gt 72 ]; then + echo "Commit $short_sha subject too long (${#subject} > 72):" + echo "$subject" + has_errors=1 + fi + + if [[ "$subject" != *:* ]]; then + echo "Commit $short_sha subject missing colon (e.g. 'subsystem: msg')" + echo "$subject" + has_errors=1 + fi + + if [ -z "$body" ]; then + echo "Commit $short_sha body is missing" + has_errors=1 + else + line_num=0 + while IFS= read -r line; do + line_num=$((line_num + 1)) + if [ ${#line} -gt 72 ]; then + echo "Commit $short_sha body line $line_num too long (${#line} > 72):" + echo "$line" + has_errors=1 + fi + done <<< "$body" + fi + + echo "" + done + + if [ "$has_errors" -eq 1 ]; then + echo "::error::Commit message check failed." + echo "For contributing guidelines, see:" + echo " $COMMIT_URL" + exit 1 + else + echo "All commit messages pass style rules." + fi From 90ce3a4caa5b5ffb67416dce19f17da051cf0ced Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Mon, 7 Jul 2025 12:49:50 +0200 Subject: [PATCH 1286/1333] nimble/bttester: Enable subrating for bttester Enable subrating features for bttester. This feature is required for following tests: GAP/CSUB/CSR/BV-01-C & GAP/CSUB/CSU/BV-01-C. --- apps/bttester/syscfg.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 646c1b66ab..18fa8afb0f 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -189,3 +189,4 @@ syscfg.vals.!BTTESTER_NODEFAULT: BLE_MESH_RX_SEG_MAX: 13 BLE_MESH_TX_SEG_MSG_COUNT: 2 BLE_MAX_CONNECTIONS: 8 + BLE_CONN_SUBRATING: 1 From 78e3b2f9fd53f395ff1d5ef8ce7a7282c775cc7f Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Mon, 7 Jul 2025 12:51:43 +0200 Subject: [PATCH 1287/1333] nimble/btp: Add support for subrating procedures Add proper BTP subrating commands and functions in GAP. Required to satisfy corresponding auto-pts layer. --- apps/bttester/src/btp/btp_gap.h | 11 +++++++++++ apps/bttester/src/btp_gap.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/apps/bttester/src/btp/btp_gap.h b/apps/bttester/src/btp/btp_gap.h index 5485cd66e4..ac6f26d5a4 100644 --- a/apps/bttester/src/btp/btp_gap.h +++ b/apps/bttester/src/btp/btp_gap.h @@ -328,6 +328,17 @@ struct gap_periodic_adv_sync_transfer_recv_cmd { uint16_t sync_timeout; uint8_t flags; } __packed; + +#define GAP_SUBRATE_REQUEST 0x2b +struct gap_subrate_request_cmd { + ble_addr_t address; + uint16_t subrate_min; + uint16_t subrate_max; + uint16_t max_latency; + uint16_t cont_num; + uint16_t supervision_timeout; +} __packed; + /* events */ #define BTP_GAP_EV_NEW_SETTINGS 0x80 struct btp_gap_new_settings_ev { diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 48e9958677..220bbd74ed 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -2210,6 +2210,29 @@ periodic_adv_sync_transfer_set_info(const void *cmd, uint16_t cmd_len, } #endif +#if MYNEWT_VAL(BLE_CONN_SUBRATING) +static uint8_t +subrate_request(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) +{ + const struct gap_subrate_request_cmd *cp = cmd; + struct ble_gap_conn_desc desc; + int rc; + + rc = gap_conn_find_by_addr(&cp->address, &desc); + if (rc) { + return BTP_STATUS_FAILED; + } + + rc = ble_gap_subrate_req(desc.conn_handle, cp->subrate_min, cp->subrate_max, + cp->max_latency, cp->cont_num, cp->supervision_timeout); + if (rc) { + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} +#endif + static const struct btp_handler handlers[] = { { .opcode = BTP_GAP_READ_SUPPORTED_COMMANDS, @@ -2380,6 +2403,13 @@ static const struct btp_handler handlers[] = { .func = periodic_adv_sync_transfer_recv, }, #endif +#if MYNEWT_VAL(BLE_CONN_SUBRATING) + { + .opcode = GAP_SUBRATE_REQUEST, + .expect_len = sizeof(struct gap_subrate_request_cmd), + .func = subrate_request, + }, +#endif }; static void From 2022fb776ae63bb4302b397d25d6dc2d7fb0fc8c Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Mon, 7 Jul 2025 17:10:51 +0200 Subject: [PATCH 1288/1333] nimble/btp: Subrate change event handling Add Subrate change event definition and handling in BTP layer. --- apps/bttester/src/btp/btp_gap.h | 11 ++++++++++ apps/bttester/src/btp_gap.c | 37 +++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/apps/bttester/src/btp/btp_gap.h b/apps/bttester/src/btp/btp_gap.h index ac6f26d5a4..c95a0d219f 100644 --- a/apps/bttester/src/btp/btp_gap.h +++ b/apps/bttester/src/btp/btp_gap.h @@ -455,3 +455,14 @@ struct gap_periodic_transfer_recieved_ev { uint8_t status; ble_addr_t peer_addr; } __packed; + +#define GAP_EV_SUBRATE_CHANGE 0x92 +struct gap_subrate_change_ev { + ble_addr_t addr; + uint8_t status; + uint16_t conn_handle; + uint16_t subrate_factor; + uint16_t periph_latency; + uint16_t cont_num; + uint16_t supervision_tmo; +} __packed; diff --git a/apps/bttester/src/btp_gap.c b/apps/bttester/src/btp_gap.c index 220bbd74ed..29fb50a103 100644 --- a/apps/bttester/src/btp_gap.c +++ b/apps/bttester/src/btp_gap.c @@ -1265,6 +1265,30 @@ periodic_transfer_received(struct ble_gap_event *event) } #endif +#if MYNEWT_VAL(BLE_CONN_SUBRATING) +static void +subrate_change_received(struct ble_gap_event *event) +{ + int rc; + struct ble_gap_conn_desc desc; + struct gap_subrate_change_ev ev; + + rc = ble_gap_conn_find(event->subrate_change.conn_handle, &desc); + assert(rc == 0); + + ev.addr = desc.peer_ota_addr; + ev.status = event->subrate_change.status; + ev.conn_handle = event->subrate_change.conn_handle; + ev.subrate_factor = event->subrate_change.subrate_factor; + ev.periph_latency = event->subrate_change.periph_latency; + ev.cont_num = event->subrate_change.cont_num; + ev.supervision_tmo = event->subrate_change.supervision_tmo; + + tester_event(BTP_SERVICE_ID_GAP, GAP_EV_SUBRATE_CHANGE, (uint8_t *)&ev, + sizeof(ev)); +} +#endif + static void print_bytes(const uint8_t *bytes, int len) { @@ -1563,6 +1587,19 @@ gap_event_cb(struct ble_gap_event *event, void *arg) event->periodic_transfer.adv_clk_accuracy); periodic_transfer_received(event); break; +#endif +#if MYNEWT_VAL(BLE_CONN_SUBRATING) + case BLE_GAP_EVENT_SUBRATE_CHANGE: + console_printf( + "Subrate change received:" + "status=%d, conn_handle=%d, subrate_factor=%d, perpih_latency=%d," + "cont_num=%d supervision_tmo=%d", + event->subrate_change.status, event->subrate_change.conn_handle, + event->subrate_change.subrate_factor, + event->subrate_change.periph_latency, event->subrate_change.cont_num, + event->subrate_change.supervision_tmo); + subrate_change_received(event); + break; #endif default: break; From ae62dda39e6f155025cdb4199f9aee34370b6f69 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Tue, 8 Jul 2025 10:58:03 +0200 Subject: [PATCH 1289/1333] nimble/host/gap: Add callback for subrate change event `ble_gap_rx_subrate_change()` handler now invokes `ble_gap_call_conn_event_cb()` to allow applications to react to subrate change events. This addition ensures that registered connection event callbacks are notified when a subrate change occurs, providing better support for LE Subrate procedures. --- nimble/host/src/ble_gap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index baa010e0b4..80ab840c8b 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -1993,6 +1993,7 @@ ble_gap_rx_subrate_change(const struct ble_hci_ev_le_subev_subrate_change *ev) event.subrate_change.supervision_tmo = le16toh(ev->supervision_tmo); ble_gap_event_listener_call(&event); + ble_gap_call_conn_event_cb(&event, ev->conn_handle); } #endif From 3cd999ad0eaa2d60fdaef55f8697974927c61d1c Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 7 Jul 2025 16:55:06 +0200 Subject: [PATCH 1290/1333] nimble/ll: Remove unused parameter This was used in the past, but no longer needed. --- .../controller/include/controller/ble_ll_ctrl.h | 3 +-- nimble/controller/src/ble_ll_conn.c | 17 ++++++++--------- nimble/controller/src/ble_ll_conn_hci.c | 10 +++++----- nimble/controller/src/ble_ll_ctrl.c | 17 ++++++++--------- 4 files changed, 22 insertions(+), 25 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index 89502a45a3..402755988b 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -294,8 +294,7 @@ struct ble_ll_len_req /* API */ struct ble_ll_conn_sm; -void ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc, - void *data); +void ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc); void ble_ll_ctrl_proc_stop(struct ble_ll_conn_sm *connsm, int ctrl_proc); int ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om); void ble_ll_ctrl_chk_proc_start(struct ble_ll_conn_sm *connsm); diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index e9e5fc6f15..bd3f2f64d3 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -586,7 +586,7 @@ ble_ll_conn_phy_update_if_needed(struct ble_ll_conn_sm *connsm) connsm->phy_data.pref_mask_tx_req = connsm->phy_data.pref_mask_tx; connsm->phy_data.pref_mask_rx_req = connsm->phy_data.pref_mask_rx; - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_PHY_UPDATE, NULL); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_PHY_UPDATE); return 0; } @@ -1727,7 +1727,7 @@ ble_ll_conn_auth_pyld_timer_cb(struct ble_npl_event *ev) connsm = (struct ble_ll_conn_sm *)ble_npl_event_get_arg(ev); ble_ll_auth_pyld_tmo_event_send(connsm); - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_LE_PING, NULL); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_LE_PING); ble_ll_conn_auth_pyld_timer_start(connsm); } @@ -2325,7 +2325,7 @@ ble_ll_conn_move_anchor(struct ble_ll_conn_sm *connsm, uint16_t offset) } connsm->conn_update_anchor_offset_req = offset; - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_CONN_UPDATE, NULL); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_CONN_UPDATE); return 0; } @@ -2900,8 +2900,7 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr) * models; for peripheral just assume central will initiate features xchg * if it has some additional features to use. */ - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG, - NULL); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG); break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) @@ -4109,7 +4108,7 @@ ble_ll_conn_chan_map_update(void) /* Perform channel map update */ SLIST_FOREACH(connsm, &g_ble_ll_conn_active_list, act_sle) { if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) { - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_CHAN_MAP_UPD, NULL); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_CHAN_MAP_UPD); } } #endif @@ -4305,14 +4304,14 @@ ble_ll_conn_subrate_req_hci(struct ble_ll_conn_sm *connsm, connsm->subrate_trans.cont_num = srp->cont_num; connsm->subrate_trans.supervision_tmo = srp->supervision_tmo; connsm->flags.subrate_host_req = 1; - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SUBRATE_UPDATE, NULL); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SUBRATE_UPDATE); break; #endif #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) case BLE_LL_CONN_ROLE_PERIPHERAL: connsm->subrate_req = *srp; connsm->flags.subrate_host_req = 1; - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SUBRATE_REQ, NULL); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SUBRATE_REQ); break; #endif default: @@ -4361,7 +4360,7 @@ ble_ll_conn_subrate_req_llcp(struct ble_ll_conn_sm *connsm, connsm->subrate_trans.supervision_tmo = MIN(connsm->supervision_tmo, srp->supervision_tmo); - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SUBRATE_UPDATE, NULL); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SUBRATE_UPDATE); return 0; } diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 877a100386..925bab8b49 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -943,7 +943,7 @@ ble_ll_conn_hci_read_rem_features(const uint8_t *cmdbuf, uint8_t len) } #endif - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG, NULL); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_FEATURE_XCHG); } connsm->flags.features_host_req = 1; @@ -1139,7 +1139,7 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len) connsm->flags.conn_update_host_initd = 1; /* Start the control procedure */ - ble_ll_ctrl_proc_start(connsm, ctrl_proc, NULL); + ble_ll_ctrl_proc_start(connsm, ctrl_proc); } return rc; @@ -1416,7 +1416,7 @@ ble_ll_conn_hci_rd_rem_ver_cmd(const uint8_t *cmdbuf, uint8_t len) * be queued before the command status. */ if (!connsm->flags.version_ind_txd) { - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_VERSION_XCHG, NULL); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_VERSION_XCHG); } else { connsm->pending_ctrl_procs |= (1 << BLE_LL_CTRL_PROC_VERSION_XCHG); } @@ -1588,7 +1588,7 @@ ble_ll_conn_hci_le_start_encrypt(const uint8_t *cmdbuf, uint8_t len) connsm->enc_data.host_rand_num = le64toh(cmd->rand); connsm->enc_data.enc_div = le16toh(cmd->div); swap_buf(connsm->enc_data.enc_block.key, cmd->ltk, 16); - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_ENCRYPT, NULL); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_ENCRYPT); rc = BLE_ERR_SUCCESS; } @@ -1738,7 +1738,7 @@ ble_ll_conn_req_peer_sca(const uint8_t *cmdbuf, uint8_t len, return BLE_ERR_CTLR_BUSY; } - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SCA_UPDATE, NULL); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SCA_UPDATE); return 0; } diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index a05b5c9d8b..bfb9de7e39 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -2135,7 +2135,7 @@ ble_ll_ctrl_initiate_dle(struct ble_ll_conn_sm *connsm, bool initial) } } - ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_DATA_LEN_UPD, NULL); + ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_DATA_LEN_UPD); } static void @@ -2467,7 +2467,7 @@ ble_ll_ctrl_rx_chanmap_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr) * @param ctrl_proc */ static struct os_mbuf * -ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc, void *data) +ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc) { uint8_t len; uint8_t opcode = 0; @@ -2486,7 +2486,7 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc, void *data) switch (ctrl_proc) { case BLE_LL_CTRL_PROC_CONN_UPDATE: opcode = BLE_LL_CTRL_CONN_UPDATE_IND; - ble_ll_ctrl_conn_update_init_proc(connsm, data); + ble_ll_ctrl_conn_update_init_proc(connsm, NULL); break; case BLE_LL_CTRL_PROC_CHAN_MAP_UPD: opcode = BLE_LL_CTRL_CHANNEL_MAP_REQ; @@ -2644,7 +2644,7 @@ ble_ll_ctrl_terminate_start(struct ble_ll_conn_sm *connsm) BLE_LL_ASSERT(connsm->disconnect_reason != 0); ctrl_proc = BLE_LL_CTRL_PROC_TERMINATE; - om = ble_ll_ctrl_proc_init(connsm, ctrl_proc, NULL); + om = ble_ll_ctrl_proc_init(connsm, ctrl_proc); if (om) { connsm->flags.terminate_started = 1; @@ -2664,8 +2664,7 @@ ble_ll_ctrl_terminate_start(struct ble_ll_conn_sm *connsm) * @param connsm Pointer to connection state machine. */ void -ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc, - void *data) +ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc) { struct os_mbuf *om; @@ -2674,7 +2673,7 @@ ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc, om = NULL; if (connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_IDLE) { /* Initiate the control procedure. */ - om = ble_ll_ctrl_proc_init(connsm, ctrl_proc, data); + om = ble_ll_ctrl_proc_init(connsm, ctrl_proc); if (om) { /* Set the current control procedure */ connsm->cur_ctrl_proc = ctrl_proc; @@ -2735,7 +2734,7 @@ ble_ll_ctrl_chk_proc_start(struct ble_ll_conn_sm *connsm) BLE_LL_ASSERT(connsm->cur_ctrl_proc == BLE_LL_CTRL_PROC_ENCRYPT); BLE_LL_ASSERT(IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_ENCRYPT)); - om = ble_ll_ctrl_proc_init(connsm, BLE_LL_CTRL_PROC_ENCRYPT, NULL); + om = ble_ll_ctrl_proc_init(connsm, BLE_LL_CTRL_PROC_ENCRYPT); if (om) { connsm->flags.pending_encrypt_restart = 0; } @@ -2760,7 +2759,7 @@ ble_ll_ctrl_chk_proc_start(struct ble_ll_conn_sm *connsm) ble_ll_hci_ev_rd_rem_ver(connsm, BLE_ERR_SUCCESS); CLR_PENDING_CTRL_PROC(connsm, i); } else { - ble_ll_ctrl_proc_start(connsm, i, NULL); + ble_ll_ctrl_proc_start(connsm, i); break; } } From 6bd38aea404917049a70a98973fda7854eca4299 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 29 Jul 2025 13:32:48 +0200 Subject: [PATCH 1291/1333] nimble/host: Fix timeout values in tests Those are in milliseconds and not ticks. --- nimble/host/test/src/ble_att_svr_test.c | 11 +++++++---- nimble/host/test/src/ble_l2cap_test.c | 12 ++++++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/nimble/host/test/src/ble_att_svr_test.c b/nimble/host/test/src/ble_att_svr_test.c index 0a31280dcf..c61c7d413c 100644 --- a/nimble/host/test/src/ble_att_svr_test.c +++ b/nimble/host/test/src/ble_att_svr_test.c @@ -1832,12 +1832,15 @@ TEST_CASE_SELF(ble_att_svr_test_notify) TEST_CASE_SELF(ble_att_svr_test_prep_write_tmo) { int32_t ticks_from_now; + uint32_t timeout_ticks; uint16_t conn_handle; int rc; int i; static uint8_t data[1024]; + timeout_ticks = ble_npl_time_ms_to_ticks32(BLE_HS_ATT_SVR_QUEUED_WRITE_TMO); + conn_handle = ble_att_svr_test_misc_init(205); /* Initialize some attribute data. */ @@ -1859,10 +1862,10 @@ TEST_CASE_SELF(ble_att_svr_test_prep_write_tmo) /* Ensure timer will expire in 30 seconds. */ ticks_from_now = ble_hs_conn_timer(); - TEST_ASSERT(ticks_from_now == BLE_HS_ATT_SVR_QUEUED_WRITE_TMO); + TEST_ASSERT(ticks_from_now == timeout_ticks); /* Almost let the timer expire. */ - os_time_advance(BLE_HS_ATT_SVR_QUEUED_WRITE_TMO - 1); + os_time_advance(timeout_ticks - 1); ticks_from_now = ble_hs_conn_timer(); TEST_ASSERT(ticks_from_now == 1); @@ -1871,11 +1874,11 @@ TEST_CASE_SELF(ble_att_svr_test_prep_write_tmo) /* Ensure timer got reset. */ ticks_from_now = ble_hs_conn_timer(); - TEST_ASSERT(ticks_from_now == BLE_HS_ATT_SVR_QUEUED_WRITE_TMO); + TEST_ASSERT(ticks_from_now == timeout_ticks); /* Allow the timer to expire. */ ble_hs_test_util_hci_ack_set_disconnect(0); - os_time_advance(BLE_HS_ATT_SVR_QUEUED_WRITE_TMO); + os_time_advance(timeout_ticks); ticks_from_now = ble_hs_conn_timer(); TEST_ASSERT(ticks_from_now == BLE_HS_FOREVER); diff --git a/nimble/host/test/src/ble_l2cap_test.c b/nimble/host/test/src/ble_l2cap_test.c index 0f55bc006b..d1db844db9 100644 --- a/nimble/host/test/src/ble_l2cap_test.c +++ b/nimble/host/test/src/ble_l2cap_test.c @@ -415,8 +415,12 @@ TEST_CASE_SELF(ble_l2cap_test_case_frag_channels) TEST_CASE_SELF(ble_l2cap_test_case_frag_timeout) { int32_t ticks_from_now; + uint32_t timeout_ticks; int rc; + timeout_ticks = + ble_npl_time_ms_to_ticks32(MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT)); + ble_l2cap_test_util_init(); ble_l2cap_test_util_create_conn(2, ((uint8_t[]){1,2,3,4,5,6}), @@ -432,10 +436,10 @@ TEST_CASE_SELF(ble_l2cap_test_case_frag_timeout) /* Ensure timer will expire in 30 seconds. */ ticks_from_now = ble_hs_conn_timer(); - TEST_ASSERT(ticks_from_now == MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT)); + TEST_ASSERT(ticks_from_now == timeout_ticks); /* Almost let the timer expire. */ - os_time_advance(MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT) - 1); + os_time_advance(timeout_ticks - 1); ticks_from_now = ble_hs_conn_timer(); TEST_ASSERT(ticks_from_now == 1); @@ -445,11 +449,11 @@ TEST_CASE_SELF(ble_l2cap_test_case_frag_timeout) /* Ensure timer got reset. */ ticks_from_now = ble_hs_conn_timer(); - TEST_ASSERT(ticks_from_now == MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT)); + TEST_ASSERT(ticks_from_now == timeout_ticks); /* Allow the timer to expire. */ ble_hs_test_util_hci_ack_set_disconnect(0); - os_time_advance(MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT)); + os_time_advance(timeout_ticks); ticks_from_now = ble_hs_conn_timer(); TEST_ASSERT(ticks_from_now == BLE_HS_FOREVER); From 10825d02ef1eb951334cc7fbbd935777ae24d46b Mon Sep 17 00:00:00 2001 From: Guy Mishol Date: Mon, 28 Jul 2025 11:27:48 +0300 Subject: [PATCH 1292/1333] nimble/host: Convert BLE_HS_ATT_SVR_QUEUED_WRITE_TMO to system ticks The value of BLE_HS_ATT_SVR_QUEUED_WRITE_TMO is the expiry time for incoming ATT queued writes in ms. When used it needs to be converted to system ticks. --- nimble/host/src/ble_att_svr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index e584cae32d..8fdf0e8457 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -2425,7 +2425,8 @@ ble_att_svr_insert_prep_entry(uint16_t conn_handle, #if BLE_HS_ATT_SVR_QUEUED_WRITE_TMO != 0 conn->bhc_att_svr.basc_prep_timeout_at = - ble_npl_time_get() + BLE_HS_ATT_SVR_QUEUED_WRITE_TMO; + ble_npl_time_get() + + ble_npl_time_ms_to_ticks32(BLE_HS_ATT_SVR_QUEUED_WRITE_TMO); ble_hs_timer_resched(); #endif From 55194911f305dc8e00c77a9b513732d9bf2c8994 Mon Sep 17 00:00:00 2001 From: Guy Mishol Date: Mon, 28 Jul 2025 14:10:03 +0300 Subject: [PATCH 1293/1333] nimble/host: Convert BLE_L2CAP_RX_FRAG_TIMEOUT to system ticks The value of BLE_L2CAP_RX_FRAG_TIMEOUT is the expiry time for incoming data packets in ms. When used it needs to be converted to system ticks. --- nimble/host/src/ble_l2cap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_l2cap.c b/nimble/host/src/ble_l2cap.c index 2b979e9181..d88f006162 100644 --- a/nimble/host/src/ble_l2cap.c +++ b/nimble/host/src/ble_l2cap.c @@ -289,7 +289,8 @@ ble_l2cap_rx_payload(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, /* More fragments remain. */ #if MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT) != 0 conn->bhc_rx_timeout = - ble_npl_time_get() + MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT); + ble_npl_time_get() + + ble_npl_time_ms_to_ticks32(MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT)); ble_hs_timer_resched(); #endif From 427f3b5abbd4c61aa7e88a287df249e154d60b81 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 25 Jul 2025 18:54:05 +0200 Subject: [PATCH 1294/1333] porting: Sync OS components with Mynewt There were some fixes in core that should be also used in NimBLE ports. Some msys code qwere also synchronized with core for easier future updates. --- porting/nimble/include/os/os_mbuf.h | 190 +++-- porting/nimble/include/os/os_mempool.h | 98 ++- porting/nimble/include/os/queue.h | 788 +++++++++++++----- porting/nimble/src/os_mbuf.c | 204 +---- porting/nimble/src/os_mempool.c | 71 +- .../nimble/src/{os_msys_init.c => os_msys.c} | 153 +++- 6 files changed, 1000 insertions(+), 504 deletions(-) rename porting/nimble/src/{os_msys_init.c => os_msys.c} (59%) diff --git a/porting/nimble/include/os/os_mbuf.h b/porting/nimble/include/os/os_mbuf.h index 6c05b2a739..81fcab9d0f 100644 --- a/porting/nimble/include/os/os_mbuf.h +++ b/porting/nimble/include/os/os_mbuf.h @@ -53,6 +53,9 @@ struct os_mbuf_pool { */ struct os_mempool *omp_pool; + /** + * Next mbuf pool in the list + */ STAILQ_ENTRY(os_mbuf_pool) omp_next; }; @@ -70,6 +73,9 @@ struct os_mbuf_pkthdr { */ uint16_t omp_flags; + /** + * Next mbuf packet header in the list + */ STAILQ_ENTRY(os_mbuf_pkthdr) omp_next; }; @@ -99,6 +105,9 @@ struct os_mbuf { */ struct os_mbuf_pool *om_omp; + /** + * Next mbuf in the list + */ SLIST_ENTRY(os_mbuf) om_next; /** @@ -111,34 +120,34 @@ struct os_mbuf { * Structure representing a queue of mbufs. */ struct os_mqueue { + /** A queue of mbuf packet headers. */ STAILQ_HEAD(, os_mbuf_pkthdr) mq_head; /** Event to post when new buffers are available on the queue. */ struct ble_npl_event mq_ev; }; -/* +/** * Given a flag number, provide the mask for it * - * @param __n The number of the flag in the mask + * @param __n The number of the flag in the mask */ #define OS_MBUF_F_MASK(__n) (1 << (__n)) -/* +/** * Checks whether a given mbuf is a packet header mbuf * - * @param __om The mbuf to check + * @param __om The mbuf to check */ #define OS_MBUF_IS_PKTHDR(__om) \ ((__om)->om_pkthdr_len >= sizeof (struct os_mbuf_pkthdr)) /** Get a packet header pointer given an mbuf pointer */ -#define OS_MBUF_PKTHDR(__om) ((struct os_mbuf_pkthdr *)(uintptr_t) \ - (void *)((uint8_t *)&(__om)->om_data \ - + sizeof(struct os_mbuf))) +#define OS_MBUF_PKTHDR(__om) ((struct os_mbuf_pkthdr *) \ + ((uint8_t *)&(__om)->om_data + sizeof(struct os_mbuf))) /** Given a mbuf packet header pointer, return a pointer to the mbuf */ #define OS_MBUF_PKTHDR_TO_MBUF(__hdr) \ - (struct os_mbuf *)(uintptr_t)((uint8_t *)(__hdr) - sizeof(struct os_mbuf)) + (struct os_mbuf *)((uint8_t *)(__hdr) - sizeof(struct os_mbuf)) /** * Gets the length of an entire mbuf chain. The specified mbuf must have a @@ -149,8 +158,8 @@ struct os_mqueue { /** * Access the data of a mbuf, and cast it to type * - * @param __om The mbuf to access, and cast - * @param __type The type to cast it to + * @param __om The mbuf to access, and cast + * @param __type The type to cast it to */ #define OS_MBUF_DATA(__om, __type) \ (__type) ((__om)->om_data) @@ -190,7 +199,7 @@ _os_mbuf_leadingspace(struct os_mbuf *om) } leadingspace = (uint16_t) (OS_MBUF_DATA(om, uint8_t *) - - ((uint8_t *) &om->om_databuf[0] + startoff)); + ((uint8_t *) &om->om_databuf[0] + startoff)); return (leadingspace); } @@ -202,10 +211,10 @@ _os_mbuf_leadingspace(struct os_mbuf *om) * Works on both packet header, and regular mbufs, as it accounts * for the additional space allocated to the packet header. * - * @param __omp Is the mbuf pool (which contains packet header length.) - * @param __om Is the mbuf in that pool to get the leadingspace for + * @param __om The mbuf in that pool to get the leading + * space for * - * @return Amount of leading space available in the mbuf + * @return Amount of leading space available in the mbuf */ #define OS_MBUF_LEADINGSPACE(__om) _os_mbuf_leadingspace(__om) @@ -221,7 +230,7 @@ _os_mbuf_trailingspace(struct os_mbuf *om) omp = om->om_omp; return (&om->om_databuf[0] + omp->omp_databuf_len) - - (om->om_data + om->om_len); + (om->om_data + om->om_len); } /** @endcond */ @@ -230,10 +239,10 @@ _os_mbuf_trailingspace(struct os_mbuf *om) * Returns the trailing space (space at the end) of the mbuf. * Works on both packet header and regular mbufs. * - * @param __omp The mbuf pool for this mbuf - * @param __om Is the mbuf in that pool to get trailing space for + * @param __om The mbuf in that pool to get the trailing + * space for * - * @return The amount of trailing space available in the mbuf + * @return Amount of trailing space available in the mbuf */ #define OS_MBUF_TRAILINGSPACE(__om) _os_mbuf_trailingspace(__om) @@ -260,11 +269,12 @@ int os_mqueue_init(struct os_mqueue *mq, ble_npl_event_fn *ev_cb, void *arg); /** * Remove and return a single mbuf from the mbuf queue. Does not block. * - * @param mq The mbuf queue to pull an element off of. + * @param mq The mbuf queue to pull an element off of. * - * @return The next mbuf in the queue, or NULL if queue has no mbufs. + * @return The next mbuf in the queue; + * NULL if queue has no mbufs. */ -struct os_mbuf *os_mqueue_get(struct os_mqueue *); +struct os_mbuf *os_mqueue_get(struct os_mqueue *mq); /** * Adds a packet (i.e. packet header mbuf) to an mqueue. The event associated @@ -272,11 +282,12 @@ struct os_mbuf *os_mqueue_get(struct os_mqueue *); * * @param mq The mbuf queue to append the mbuf to. * @param evq The event queue to post an event to. - * @param m The mbuf to append to the mbuf queue. + * @param om The mbuf to append to the mbuf queue. * * @return 0 on success, non-zero on failure. */ -int os_mqueue_put(struct os_mqueue *, struct ble_npl_eventq *, struct os_mbuf *); +int os_mqueue_put(struct os_mqueue *mq, struct ble_npl_eventq *evq, + struct os_mbuf *om); /** * MSYS is a system level mbuf registry. Allows the system to share @@ -290,20 +301,24 @@ int os_mqueue_put(struct os_mqueue *, struct ble_npl_eventq *, struct os_mbuf *) * os_msys_register() registers a mbuf pool with MSYS, and allows MSYS to * allocate mbufs out of it. * - * @param new_pool The pool to register with MSYS + * @param new_pool The pool to register with MSYS * - * @return 0 on success, non-zero on failure + * @return 0 on success; + * non-zero on failure */ -int os_msys_register(struct os_mbuf_pool *); +int os_msys_register(struct os_mbuf_pool *new_pool); /** * Allocate a mbuf from msys. Based upon the data size requested, * os_msys_get() will choose the mbuf pool that has the best fit. * - * @param dsize The estimated size of the data being stored in the mbuf - * @param leadingspace The amount of leadingspace to allocate in the mbuf + * @param dsize The estimated size of the data being stored in + * the mbuf + * @param leadingspace The amount of leadingspace to allocate in + * the mbuf * - * @return A freshly allocated mbuf on success, NULL on failure. + * @return A freshly allocated mbuf on success; + * NULL on failure. */ struct os_mbuf *os_msys_get(uint16_t dsize, uint16_t leadingspace); @@ -316,72 +331,77 @@ void os_msys_reset(void); * Allocate a packet header structure from the MSYS pool. See * os_msys_register() for a description of MSYS. * - * @param dsize The estimated size of the data being stored in the mbuf - * @param user_hdr_len The length to allocate for the packet header structure + * @param dsize The estimated size of the data being stored in + * the mbuf + * @param user_hdr_len The length to allocate for the packet header + * structure * - * @return A freshly allocated mbuf on success, NULL on failure. + * @return A freshly allocated mbuf on success; + * NULL on failure. */ struct os_mbuf *os_msys_get_pkthdr(uint16_t dsize, uint16_t user_hdr_len); /** * Count the number of blocks in all the mbuf pools that are allocated. * - * @return total number of blocks allocated in Msys + * @return total number of blocks allocated in Msys */ int os_msys_count(void); /** * Return the number of free blocks in Msys * - * @return Number of free blocks available in Msys + * @return Number of free blocks available in Msys */ int os_msys_num_free(void); /** * Initialize a pool of mbufs. * - * @param omp The mbuf pool to initialize - * @param mp The memory pool that will hold this mbuf pool - * @param buf_len The length of the buffer itself. - * @param nbufs The number of buffers in the pool + * @param omp The mbuf pool to initialize + * @param mp The memory pool that will hold this mbuf pool + * @param buf_len The length of the buffer itself. + * @param nbufs The number of buffers in the pool * - * @return 0 on success, error code on failure. + * @return 0 on success; + * error code on failure. */ -int os_mbuf_pool_init(struct os_mbuf_pool *, struct os_mempool *mp, - uint16_t, uint16_t); - +int os_mbuf_pool_init(struct os_mbuf_pool *omp, struct os_mempool *mp, + uint16_t buf_len, uint16_t nbufs); /** * Get an mbuf from the mbuf pool. The mbuf is allocated, and initialized * prior to being returned. * - * @param omp The mbuf pool to return the packet from - * @param leadingspace The amount of leadingspace to put before the data - * section by default. + * @param omp The mbuf pool to return the packet from + * @param leadingspace The amount of leadingspace to put before the + * data section by default. * - * @return An initialized mbuf on success, and NULL on failure. + * @return An initialized mbuf on success; + * NULL on failure. */ -struct os_mbuf *os_mbuf_get(struct os_mbuf_pool *omp, uint16_t); +struct os_mbuf *os_mbuf_get(struct os_mbuf_pool *omp, uint16_t leadingspace); /** * Allocate a new packet header mbuf out of the os_mbuf_pool. * - * @param omp The mbuf pool to allocate out of - * @param user_pkthdr_len The packet header length to reserve for the caller. + * @param omp The mbuf pool to allocate out of + * @param user_pkthdr_len The packet header length to reserve for the + * caller. * - * @return A freshly allocated mbuf on success, NULL on failure. + * @return A freshly allocated mbuf on success; + * NULL on failure. */ struct os_mbuf *os_mbuf_get_pkthdr(struct os_mbuf_pool *omp, - uint8_t pkthdr_len); + uint8_t user_pkthdr_len); /** * Duplicate a chain of mbufs. Return the start of the duplicated chain. * - * @param omp The mbuf pool to duplicate out of - * @param om The mbuf chain to duplicate + * @param om The mbuf chain to duplicate * - * @return A pointer to the new chain of mbufs + * @return A pointer to the new chain of mbufs */ -struct os_mbuf *os_mbuf_dup(struct os_mbuf *m); +struct os_mbuf *os_mbuf_dup(struct os_mbuf *om); /** * Locates the specified absolute offset within an mbuf chain. The offset @@ -400,11 +420,11 @@ struct os_mbuf *os_mbuf_off(const struct os_mbuf *om, int off, uint16_t *out_off); -/* +/** * Copy data from an mbuf chain starting "off" bytes from the beginning, * continuing for "len" bytes, into the indicated buffer. * - * @param m The mbuf chain to copy from + * @param om The mbuf chain to copy from * @param off The offset into the mbuf chain to begin copying from * @param len The length of the data to copy * @param dst The destination buffer to copy into @@ -412,7 +432,7 @@ struct os_mbuf *os_mbuf_off(const struct os_mbuf *om, int off, * @return 0 on success; * -1 if the mbuf does not contain enough data. */ -int os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst); +int os_mbuf_copydata(const struct os_mbuf *om, int off, int len, void *dst); /** * @brief Calculates the length of an mbuf chain. @@ -431,13 +451,14 @@ uint16_t os_mbuf_len(const struct os_mbuf *om); /** * Append data onto a mbuf * - * @param om The mbuf to append the data onto - * @param data The data to append onto the mbuf - * @param len The length of the data to append + * @param om The mbuf to append the data onto + * @param data The data to append onto the mbuf + * @param len The length of the data to append * - * @return 0 on success, and an error code on failure + * @return 0 on success; + * an error code on failure */ -int os_mbuf_append(struct os_mbuf *m, const void *, uint16_t); +int os_mbuf_append(struct os_mbuf *om, const void *data, uint16_t len); /** * Reads data from one mbuf and appends it to another. On error, the specified @@ -460,20 +481,21 @@ int os_mbuf_appendfrom(struct os_mbuf *dst, const struct os_mbuf *src, /** * Release a mbuf back to the pool * - * @param omp The Mbuf pool to release back to - * @param om The Mbuf to release back to the pool + * @param om The Mbuf to release back to the pool * - * @return 0 on success, -1 on failure + * @return 0 on success; + * -1 on failure */ -int os_mbuf_free(struct os_mbuf *mb); +int os_mbuf_free(struct os_mbuf *om); /** * Free a chain of mbufs * - * @param omp The mbuf pool to free the chain of mbufs into - * @param om The starting mbuf of the chain to free back into the pool + * @param om The starting mbuf of the chain to free back into + * the pool * - * @return 0 on success, -1 on failure + * @return 0 on success; + * -1 on failure */ int os_mbuf_free_chain(struct os_mbuf *om); @@ -481,12 +503,12 @@ int os_mbuf_free_chain(struct os_mbuf *om); * Adjust the length of a mbuf, trimming either from the head or the tail * of the mbuf. * - * @param mp The mbuf chain to adjust - * @param req_len The length to trim from the mbuf. If positive, trims - * from the head of the mbuf, if negative, trims from the - * tail of the mbuf. + * @param om The mbuf chain to adjust + * @param req_len The length to trim from the mbuf. If positive, + * trims from the head of the mbuf, if + * negative, trims from the tail of the mbuf. */ -void os_mbuf_adj(struct os_mbuf *mp, int req_len); +void os_mbuf_adj(struct os_mbuf *om, int req_len); /** @@ -536,7 +558,6 @@ int os_mbuf_cmpm(const struct os_mbuf *om1, uint16_t offset1, * * The specified mbuf chain does not need to contain a packet header. * - * @param omp The mbuf pool to allocate from. * @param om The head of the mbuf chain. * @param len The number of bytes to prepend. * @@ -564,7 +585,6 @@ struct os_mbuf *os_mbuf_prepend_pullup(struct os_mbuf *om, uint16_t len); * it is extended as necessary. If the destination mbuf contains a packet * header, the header length is updated. * - * @param omp The mbuf pool to allocate from. * @param om The mbuf chain to copy into. * @param off The offset within the chain to copy to. * @param src The source buffer to copy from. @@ -591,7 +611,6 @@ void os_mbuf_concat(struct os_mbuf *first, struct os_mbuf *second); * appended to the chain. It is an error to request more data than can fit in * a single buffer. * - * @param omp * @param om The head of the chain to extend. * @param len The number of bytes to extend by. * @@ -610,11 +629,12 @@ void *os_mbuf_extend(struct os_mbuf *om, uint16_t len); * extra bytes to the contiguous region, in an attempt to avoid being * called next time. * - * @param omp The mbuf pool to take the mbufs out of - * @param om The mbuf chain to make contiguous - * @param len The number of bytes in the chain to make contiguous + * @param om The mbuf chain to make contiguous + * @param len The number of bytes in the chain to make + * contiguous * - * @return The contiguous mbuf chain on success, NULL on failure. + * @return The contiguous mbuf chain on success; + * NULL on failure. */ struct os_mbuf *os_mbuf_pullup(struct os_mbuf *om, uint16_t len); @@ -657,10 +677,10 @@ int os_mbuf_widen(struct os_mbuf *om, uint16_t off, uint16_t len); * header it is discarded. If m1 is NULL, NULL is returned and * m2 is left untouched. * - * @param m1 Pointer to first mbuf chain to pack - * @param m2 Pointer to second mbuf chain to pack + * @param m1 Pointer to first mbuf chain to pack + * @param m2 Pointer to second mbuf chain to pack * - * @return struct os_mbuf* Pointer to resulting mbuf chain + * @return Pointer to resulting mbuf chain */ struct os_mbuf *os_mbuf_pack_chains(struct os_mbuf *m1, struct os_mbuf *m2); diff --git a/porting/nimble/include/os/os_mempool.h b/porting/nimble/include/os/os_mempool.h index 74bc43fe0d..d4c3313a3f 100644 --- a/porting/nimble/include/os/os_mempool.h +++ b/porting/nimble/include/os/os_mempool.h @@ -43,6 +43,7 @@ extern "C" { * caller. */ struct os_memblock { + /** Next memory block in the list. */ SLIST_ENTRY(os_memblock) mb_next; }; @@ -66,8 +67,10 @@ struct os_mempool { /** Bitmap of OS_MEMPOOL_F_[...] values. */ uint8_t mp_flags; /** Address of memory buffer used by pool */ - uint32_t mp_membuf_addr; + uintptr_t mp_membuf_addr; + /** Next memory pool in the list. */ STAILQ_ENTRY(os_mempool) mp_list; + /** Head of the list of memory blocks. */ SLIST_HEAD(,os_memblock); /** Name for memory block */ char *name; @@ -102,14 +105,19 @@ struct os_mempool_ext; typedef os_error_t os_mempool_put_fn(struct os_mempool_ext *ome, void *data, void *arg); +/** Extended memory pool. */ struct os_mempool_ext { + /** Standard memory pool. */ struct os_mempool mpe_mp; - /* Callback that is executed immediately when a block is freed. */ + /** Callback that is executed immediately when a block is freed. */ os_mempool_put_fn *mpe_put_cb; + + /** Optional argument passed to the callback function. */ void *mpe_put_arg; }; +/** Length of the name of memory pool */ #define OS_MEMPOOL_INFO_NAME_LEN (32) /** @@ -132,15 +140,30 @@ struct os_mempool_info { /** * Get information about the next system memory pool. * - * @param mempool The current memory pool, or NULL if starting iteration. - * @param info A pointer to the structure to return memory pool information - * into. + * @param mp The current memory pool, or NULL if starting + * iteration. + * @param omi A pointer to the structure to return memory pool + * information into. * - * @return The next memory pool in the list to get information about, or NULL - * when at the last memory pool. + * @return The next memory pool in the list to get + * information about; + * NULL when at the last memory pool. */ -struct os_mempool *os_mempool_info_get_next(struct os_mempool *, - struct os_mempool_info *); +struct os_mempool *os_mempool_info_get_next(struct os_mempool *mp, + struct os_mempool_info *omi); + +/** + * Get information system memory pool by name. + * + * @param mempool_name The name of mempool. + * @param info A pointer to the structure to return memory pool + * information into, can be NULL. + * + * @return The memory pool found; + * NULL when there is no such memory pool. + */ +struct os_mempool *os_mempool_get(const char *mempool_name, + struct os_mempool_info *info); /* * To calculate size of the memory buffer needed for the pool. NOTE: This size @@ -148,11 +171,10 @@ struct os_mempool *os_mempool_info_get_next(struct os_mempool *, * the memory pool. */ #if MYNEWT_VAL(OS_MEMPOOL_GUARD) -/* - * Leave extra 4 bytes of guard area at the end. - */ +/** Leave extra 4 bytes of guard area at the end. */ #define OS_MEMPOOL_BLOCK_SZ(sz) ((sz) + sizeof(os_membuf_t)) #else +/** Size of a memory pool block. */ #define OS_MEMPOOL_BLOCK_SZ(sz) (sz) #endif #if (OS_ALIGNMENT == 4) @@ -164,6 +186,8 @@ typedef __uint128_t os_membuf_t; #else #error "Unhandled `OS_ALIGNMENT` for `os_membuf_t`" #endif /* OS_ALIGNMENT == * */ + +/** The total size of a memory pool, including alignment. */ #define OS_MEMPOOL_SIZE(n,blksize) (((OS_MEMPOOL_BLOCK_SZ(blksize) + ((OS_ALIGNMENT)-1)) / (OS_ALIGNMENT)) * (n)) /** Calculates the number of bytes required to initialize a memory pool. */ @@ -173,13 +197,14 @@ typedef __uint128_t os_membuf_t; /** * Initialize a memory pool. * - * @param mp Pointer to a pointer to a mempool - * @param blocks The number of blocks in the pool - * @param blocks_size The size of the block, in bytes. - * @param membuf Pointer to memory to contain blocks. - * @param name Name of the pool. + * @param mp Pointer to a pointer to a mempool + * @param blocks The number of blocks in the pool + * @param block_size The size of the block, in bytes. + * @param membuf Pointer to memory to contain blocks. + * @param name Name of the pool. * - * @return os_error_t + * @return 0 on success; + * Non-zero error code on failure. */ os_error_t os_mempool_init(struct os_mempool *mp, uint16_t blocks, uint32_t block_size, void *membuf, char *name); @@ -189,13 +214,14 @@ os_error_t os_mempool_init(struct os_mempool *mp, uint16_t blocks, * are not specified when this function is called; they are assigned manually * after initialization. * - * @param mpe The extended memory pool to initialize. - * @param blocks The number of blocks in the pool. - * @param block_size The size of each block, in bytes. - * @param membuf Pointer to memory to contain blocks. - * @param name Name of the pool. + * @param mpe The extended memory pool to initialize. + * @param blocks The number of blocks in the pool. + * @param block_size The size of each block, in bytes. + * @param membuf Pointer to memory to contain blocks. + * @param name Name of the pool. * - * @return os_error_t + * @return 0 on success; + * Non-zero error code on failure. */ os_error_t os_mempool_ext_init(struct os_mempool_ext *mpe, uint16_t blocks, uint32_t block_size, void *membuf, char *name); @@ -214,9 +240,10 @@ os_error_t os_mempool_unregister(struct os_mempool *mp); /** * Clears a memory pool. * - * @param mp The mempool to clear. + * @param mp The mempool to clear. * - * @return os_error_t + * @return 0 on success; + * Non-zero error code on failure. */ os_error_t os_mempool_clear(struct os_mempool *mp); @@ -246,9 +273,10 @@ int os_memblock_from(const struct os_mempool *mp, const void *block_addr); /** * Get a memory block from a memory pool * - * @param mp Pointer to the memory pool + * @param mp Pointer to the memory pool * - * @return void* Pointer to block if available; NULL otherwise + * @return Pointer to block if available; + * NULL otherwise */ void *os_memblock_get(struct os_mempool *mp); @@ -257,20 +285,22 @@ void *os_memblock_get(struct os_mempool *mp); * This function should only be called from a put callback to free a block * without causing infinite recursion. * - * @param mp Pointer to memory pool - * @param block_addr Pointer to memory block + * @param mp Pointer to memory pool + * @param block_addr Pointer to memory block * - * @return os_error_t + * @return 0 on success; + * Non-zero error code on failure. */ os_error_t os_memblock_put_from_cb(struct os_mempool *mp, void *block_addr); /** * Puts the memory block back into the pool * - * @param mp Pointer to memory pool - * @param block_addr Pointer to memory block + * @param mp Pointer to memory pool + * @param block_addr Pointer to memory block * - * @return os_error_t + * @return 0 on success; + * Non-zero error code on failure. */ os_error_t os_memblock_put(struct os_mempool *mp, void *block_addr); diff --git a/porting/nimble/include/os/queue.h b/porting/nimble/include/os/queue.h index c19edb113c..ed05c619d6 100644 --- a/porting/nimble/include/os/queue.h +++ b/porting/nimble/include/os/queue.h @@ -1,4 +1,6 @@ -/* +/*- + * SPDX-License-Identifier: BSD-3-Clause + * * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -27,19 +29,16 @@ * SUCH DAMAGE. * * @(#)queue.h 8.5 (Berkeley) 8/20/94 - * $FreeBSD: src/sys/sys/queue.h,v 1.32.2.7 2002/04/17 14:21:02 des Exp $ */ -#ifndef _QUEUE_H_ -#define _QUEUE_H_ +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ -#ifdef __cplusplus -extern "C" { -#endif +#include /* - * This file defines five types of data structures: singly-linked lists, - * singly-linked tail queues, lists, tail queues, and circular queues. + * This file defines four types of data structures: singly-linked lists, + * singly-linked tail queues, lists and tail queues. * * A singly-linked list is headed by a single forward pointer. The elements * are singly linked for minimum space and pointer manipulation overhead at @@ -67,7 +66,7 @@ extern "C" { * so that an arbitrary element can be removed without a need to * traverse the list. New elements can be added to the list before * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. + * may be traversed in either direction. * * A tail queue is headed by a pair of pointers, one to the head of the * list and the other to the tail of the list. The elements are doubly @@ -76,99 +75,246 @@ extern "C" { * after an existing element, at the head of the list, or at the end of * the list. A tail queue may be traversed in either direction. * - * A circle queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the list. - * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. - * * For details on the use of these macros, see the queue(3) manual page. * + * Below is a summary of implemented functions where: + * + means the macro is available + * - means the macro is not available + * s means the macro is available but is slow (runs in O(n) time) * - * SLIST LIST STAILQ TAILQ CIRCLEQ - * _HEAD + + + + + - * _HEAD_INITIALIZER + + + + + - * _ENTRY + + + + + - * _INIT + + + + + - * _EMPTY + + + + + - * _FIRST + + + + + - * _NEXT + + + + + - * _PREV - - - + + - * _LAST - - + + + - * _FOREACH + + + + + - * _FOREACH_REVERSE - - - + + - * _INSERT_HEAD + + + + + - * _INSERT_BEFORE - + - + + - * _INSERT_AFTER + + + + + - * _INSERT_TAIL - - + + + - * _REMOVE_HEAD + - + - - - * _REMOVE + + + + + + * SLIST LIST STAILQ TAILQ + * _HEAD + + + + + * _CLASS_HEAD + + + + + * _HEAD_INITIALIZER + + + + + * _ENTRY + + + + + * _CLASS_ENTRY + + + + + * _INIT + + + + + * _EMPTY + + + + + * _END + + + + + * _FIRST + + + + + * _NEXT + + + + + * _PREV - + - + + * _LAST - - + + + * _LAST_FAST - - - + + * _FOREACH + + + + + * _FOREACH_FROM + + + + + * _FOREACH_SAFE + + + + + * _FOREACH_FROM_SAFE + + + + + * _FOREACH_REVERSE - - - + + * _FOREACH_REVERSE_FROM - - - + + * _FOREACH_REVERSE_SAFE - - - + + * _FOREACH_REVERSE_FROM_SAFE - - - + + * _INSERT_HEAD + + + + + * _INSERT_BEFORE - + - + + * _INSERT_AFTER + + + + + * _INSERT_TAIL - - + + + * _CONCAT s s + + + * _REMOVE_AFTER + - + - + * _REMOVE_HEAD + + + + + * _REMOVE s + s + + * _REPLACE - + - + + * _SWAP + + + + * */ +#ifndef __containerof +#define __containerof CONTAINER_OF +#endif + +#ifdef QUEUE_MACRO_DEBUG +#warn Use QUEUE_MACRO_DEBUG_TRACE and/or QUEUE_MACRO_DEBUG_TRASH +#define QUEUE_MACRO_DEBUG_TRACE +#define QUEUE_MACRO_DEBUG_TRASH +#endif + +#ifdef QUEUE_MACRO_DEBUG_TRACE +/* Store the last 2 places the queue element or head was altered */ +struct qm_trace { + unsigned long lastline; + unsigned long prevline; + const char *lastfile; + const char *prevfile; +}; + +#define TRACEBUF struct qm_trace trace; +#define TRACEBUF_INITIALIZER { __LINE__, 0, __FILE__, NULL } , + +#define QMD_TRACE_HEAD(head) do { \ + (head)->trace.prevline = (head)->trace.lastline; \ + (head)->trace.prevfile = (head)->trace.lastfile; \ + (head)->trace.lastline = __LINE__; \ + (head)->trace.lastfile = __FILE__; \ +} while (0) + +#define QMD_TRACE_ELEM(elem) do { \ + (elem)->trace.prevline = (elem)->trace.lastline; \ + (elem)->trace.prevfile = (elem)->trace.lastfile; \ + (elem)->trace.lastline = __LINE__; \ + (elem)->trace.lastfile = __FILE__; \ +} while (0) + +#else /* !QUEUE_MACRO_DEBUG_TRACE */ +#define QMD_TRACE_ELEM(elem) +#define QMD_TRACE_HEAD(head) +#define TRACEBUF +#define TRACEBUF_INITIALIZER +#endif /* QUEUE_MACRO_DEBUG_TRACE */ + +#ifdef QUEUE_MACRO_DEBUG_TRASH +#define QMD_SAVELINK(name, link) void **name = (void *)&(link) +#define TRASHIT(x) do {(x) = (void *)-1;} while (0) +#define QMD_IS_TRASHED(x) ((x) == (void *)(intptr_t)-1) +#else /* !QUEUE_MACRO_DEBUG_TRASH */ +#define QMD_SAVELINK(name, link) +#define TRASHIT(x) +#define QMD_IS_TRASHED(x) 0 +#endif /* QUEUE_MACRO_DEBUG_TRASH */ + +#ifdef __cplusplus +/* + * In C++ there can be structure lists and class lists: + */ +#define QUEUE_TYPEOF(type) type +#else +#define QUEUE_TYPEOF(type) struct type +#endif + /* * Singly-linked List declarations. */ -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_CLASS_HEAD(name, type) \ +struct name { \ + class type *slh_first; /* first element */ \ } -#define SLIST_HEAD_INITIALIZER(head) \ - { NULL } +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +#define SLIST_CLASS_ENTRY(type) \ +struct { \ + class type *sle_next; /* next element */ \ } /* * Singly-linked List functions. */ -#define SLIST_EMPTY(head) ((head)->slh_first == NULL) +#if (defined(_KERNEL) && defined(INVARIANTS)) +#define QMD_SLIST_CHECK_PREVPTR(prevp, elm) do { \ + if (*(prevp) != (elm)) \ + panic("Bad prevptr *(%p) == %p != %p", \ + (prevp), *(prevp), (elm)); \ +} while (0) +#else +#define QMD_SLIST_CHECK_PREVPTR(prevp, elm) +#endif -#define SLIST_FIRST(head) ((head)->slh_first) +#define SLIST_CONCAT(head1, head2, type, field) do { \ + QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1); \ + if (curelm == NULL) { \ + if ((SLIST_FIRST(head1) = SLIST_FIRST(head2)) != NULL) \ + SLIST_INIT(head2); \ + } else if (SLIST_FIRST(head2) != NULL) { \ + while (SLIST_NEXT(curelm, field) != NULL) \ + curelm = SLIST_NEXT(curelm, field); \ + SLIST_NEXT(curelm, field) = SLIST_FIRST(head2); \ + SLIST_INIT(head2); \ + } \ +} while (0) + +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) -#define SLIST_FOREACH(var, head, field) \ - for ((var) = SLIST_FIRST((head)); \ - (var); \ - (var) = SLIST_NEXT((var), field)) +#define SLIST_FIRST(head) ((head)->slh_first) -#define SLIST_INIT(head) do { \ - SLIST_FIRST((head)) = NULL; \ +#define SLIST_FOREACH(var, head, field) \ + for ((var) = SLIST_FIRST((head)); \ + (var); \ + (var) = SLIST_NEXT((var), field)) + +#define SLIST_FOREACH_FROM(var, head, field) \ + for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \ + (var); \ + (var) = SLIST_NEXT((var), field)) + +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SLIST_FIRST((head)); \ + (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ + for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \ + (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ + for ((varp) = &SLIST_FIRST((head)); \ + ((var) = *(varp)) != NULL; \ + (varp) = &SLIST_NEXT((var), field)) + +#define SLIST_INIT(head) do { \ + SLIST_FIRST((head)) = NULL; \ +} while (0) + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ + SLIST_NEXT((slistelm), field) = (elm); \ } while (0) -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ - SLIST_NEXT((slistelm), field) = (elm); \ +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ + SLIST_FIRST((head)) = (elm); \ +} while (0) + +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if (SLIST_FIRST((head)) == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head); \ + while (SLIST_NEXT(curelm, field) != (elm)) \ + curelm = SLIST_NEXT(curelm, field); \ + SLIST_REMOVE_AFTER(curelm, field); \ + } \ } while (0) -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ - SLIST_FIRST((head)) = (elm); \ +#define SLIST_REMOVE_AFTER(elm, field) do { \ + QMD_SAVELINK(oldnext, SLIST_NEXT(elm, field)->field.sle_next); \ + SLIST_NEXT(elm, field) = \ + SLIST_NEXT(SLIST_NEXT(elm, field), field); \ + TRASHIT(*oldnext); \ } while (0) -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) +#define SLIST_REMOVE_HEAD(head, field) do { \ + QMD_SAVELINK(oldnext, SLIST_FIRST(head)->field.sle_next); \ + SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ + TRASHIT(*oldnext); \ +} while (0) -#define SLIST_REMOVE(head, elm, type, field) do { \ - if (SLIST_FIRST((head)) == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = SLIST_FIRST((head)); \ - while (SLIST_NEXT(curelm, field) != (elm)) \ - curelm = SLIST_NEXT(curelm, field); \ - SLIST_NEXT(curelm, field) = \ - SLIST_NEXT(SLIST_NEXT(curelm, field), field); \ - } \ +#define SLIST_REMOVE_PREVPTR(prevp, elm, field) do { \ + QMD_SLIST_CHECK_PREVPTR(prevp, elm); \ + *(prevp) = SLIST_NEXT(elm, field); \ + TRASHIT((elm)->field.sle_next); \ } while (0) -#define SLIST_REMOVE_HEAD(head, field) do { \ - SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ +#define SLIST_SWAP(head1, head2, type) do { \ + QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \ + SLIST_FIRST(head1) = SLIST_FIRST(head2); \ + SLIST_FIRST(head2) = swap_first; \ } while (0) +#define SLIST_END(head) NULL + /* * Singly-linked Tail queue declarations. */ @@ -178,6 +324,12 @@ struct name { \ struct type **stqh_last;/* addr of last next element */ \ } +#define STAILQ_CLASS_HEAD(name, type) \ +struct name { \ + class type *stqh_first; /* first element */ \ + class type **stqh_last; /* addr of last next element */ \ +} + #define STAILQ_HEAD_INITIALIZER(head) \ { NULL, &(head).stqh_first } @@ -186,9 +338,22 @@ struct { \ struct type *stqe_next; /* next element */ \ } +#define STAILQ_CLASS_ENTRY(type) \ +struct { \ + class type *stqe_next; /* next element */ \ +} + /* * Singly-linked Tail queue functions. */ +#define STAILQ_CONCAT(head1, head2) do { \ + if (!STAILQ_EMPTY((head2))) { \ + *(head1)->stqh_last = (head2)->stqh_first; \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_INIT((head2)); \ + } \ +} while (0) + #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) #define STAILQ_FIRST(head) ((head)->stqh_first) @@ -198,6 +363,21 @@ struct { \ (var); \ (var) = STAILQ_NEXT((var), field)) +#define STAILQ_FOREACH_FROM(var, head, field) \ + for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \ + (var); \ + (var) = STAILQ_NEXT((var), field)) + +#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = STAILQ_FIRST((head)); \ + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ + for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \ + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + #define STAILQ_INIT(head) do { \ STAILQ_FIRST((head)) = NULL; \ (head)->stqh_last = &STAILQ_FIRST((head)); \ @@ -222,25 +402,30 @@ struct { \ } while (0) #define STAILQ_LAST(head, type, field) \ - (STAILQ_EMPTY(head) ? \ - NULL : \ - ((struct type *) \ - ((char *)((head)->stqh_last) - offsetof(struct type, field)))) + (STAILQ_EMPTY((head)) ? NULL : \ + __containerof((head)->stqh_last, \ + QUEUE_TYPEOF(type), field.stqe_next)) #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) #define STAILQ_REMOVE(head, elm, type, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \ if (STAILQ_FIRST((head)) == (elm)) { \ - STAILQ_REMOVE_HEAD(head, field); \ + STAILQ_REMOVE_HEAD((head), field); \ } \ else { \ - struct type *curelm = STAILQ_FIRST((head)); \ + QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head); \ while (STAILQ_NEXT(curelm, field) != (elm)) \ curelm = STAILQ_NEXT(curelm, field); \ - if ((STAILQ_NEXT(curelm, field) = \ - STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\ - (head)->stqh_last = &STAILQ_NEXT((curelm), field);\ + STAILQ_REMOVE_AFTER(head, curelm, field); \ } \ + TRASHIT(*oldnext); \ +} while (0) + +#define STAILQ_REMOVE_AFTER(head, elm, field) do { \ + if ((STAILQ_NEXT(elm, field) = \ + STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ } while (0) #define STAILQ_REMOVE_HEAD(head, field) do { \ @@ -249,16 +434,21 @@ struct { \ (head)->stqh_last = &STAILQ_FIRST((head)); \ } while (0) -#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ - if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ +#define STAILQ_SWAP(head1, head2, type) do { \ + QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1); \ + QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last; \ + STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_FIRST(head2) = swap_first; \ + (head2)->stqh_last = swap_last; \ + if (STAILQ_EMPTY(head1)) \ + (head1)->stqh_last = &STAILQ_FIRST(head1); \ + if (STAILQ_EMPTY(head2)) \ + (head2)->stqh_last = &STAILQ_FIRST(head2); \ } while (0) -#define STAILQ_REMOVE_AFTER(head, elm, field) do { \ - if ((STAILQ_NEXT(elm, field) = \ - STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ -} while (0) +#define STAILQ_END(head) NULL + /* * List declarations. @@ -268,6 +458,11 @@ struct name { \ struct type *lh_first; /* first element */ \ } +#define LIST_CLASS_HEAD(name, type) \ +struct name { \ + class type *lh_first; /* first element */ \ +} + #define LIST_HEAD_INITIALIZER(head) \ { NULL } @@ -277,10 +472,75 @@ struct { \ struct type **le_prev; /* address of previous next element */ \ } +#define LIST_CLASS_ENTRY(type) \ +struct { \ + class type *le_next; /* next element */ \ + class type **le_prev; /* address of previous next element */ \ +} + /* * List functions. */ +#if (defined(_KERNEL) && defined(INVARIANTS)) +/* + * QMD_LIST_CHECK_HEAD(LIST_HEAD *head, LIST_ENTRY NAME) + * + * If the list is non-empty, validates that the first element of the list + * points back at 'head.' + */ +#define QMD_LIST_CHECK_HEAD(head, field) do { \ + if (LIST_FIRST((head)) != NULL && \ + LIST_FIRST((head))->field.le_prev != \ + &LIST_FIRST((head))) \ + panic("Bad list head %p first->prev != head", (head)); \ +} while (0) + +/* + * QMD_LIST_CHECK_NEXT(TYPE *elm, LIST_ENTRY NAME) + * + * If an element follows 'elm' in the list, validates that the next element + * points back at 'elm.' + */ +#define QMD_LIST_CHECK_NEXT(elm, field) do { \ + if (LIST_NEXT((elm), field) != NULL && \ + LIST_NEXT((elm), field)->field.le_prev != \ + &((elm)->field.le_next)) \ + panic("Bad link elm %p next->prev != elm", (elm)); \ +} while (0) + +/* + * QMD_LIST_CHECK_PREV(TYPE *elm, LIST_ENTRY NAME) + * + * Validates that the previous element (or head of the list) points to 'elm.' + */ +#define QMD_LIST_CHECK_PREV(elm, field) do { \ + if (*(elm)->field.le_prev != (elm)) \ + panic("Bad link elm %p prev->next != elm", (elm)); \ +} while (0) +#else +#define QMD_LIST_CHECK_HEAD(head, field) +#define QMD_LIST_CHECK_NEXT(elm, field) +#define QMD_LIST_CHECK_PREV(elm, field) +#endif /* (_KERNEL && INVARIANTS) */ + +#define LIST_CONCAT(head1, head2, type, field) do { \ + QUEUE_TYPEOF(type) *curelm = LIST_FIRST(head1); \ + if (curelm == NULL) { \ + if ((LIST_FIRST(head1) = LIST_FIRST(head2)) != NULL) { \ + LIST_FIRST(head2)->field.le_prev = \ + &LIST_FIRST((head1)); \ + LIST_INIT(head2); \ + } \ + } else if (LIST_FIRST(head2) != NULL) { \ + while (LIST_NEXT(curelm, field) != NULL) \ + curelm = LIST_NEXT(curelm, field); \ + LIST_NEXT(curelm, field) = LIST_FIRST(head2); \ + LIST_FIRST(head2)->field.le_prev = &LIST_NEXT(curelm, field);\ + LIST_INIT(head2); \ + } \ +} while (0) + #define LIST_EMPTY(head) ((head)->lh_first == NULL) #define LIST_FIRST(head) ((head)->lh_first) @@ -290,11 +550,27 @@ struct { \ (var); \ (var) = LIST_NEXT((var), field)) +#define LIST_FOREACH_FROM(var, head, field) \ + for ((var) = ((var) ? (var) : LIST_FIRST((head))); \ + (var); \ + (var) = LIST_NEXT((var), field)) + +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = LIST_FIRST((head)); \ + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define LIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ + for ((var) = ((var) ? (var) : LIST_FIRST((head))); \ + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ + (var) = (tvar)) + #define LIST_INIT(head) do { \ LIST_FIRST((head)) = NULL; \ } while (0) #define LIST_INSERT_AFTER(listelm, elm, field) do { \ + QMD_LIST_CHECK_NEXT(listelm, field); \ if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ LIST_NEXT((listelm), field)->field.le_prev = \ &LIST_NEXT((elm), field); \ @@ -303,6 +579,7 @@ struct { \ } while (0) #define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + QMD_LIST_CHECK_PREV(listelm, field); \ (elm)->field.le_prev = (listelm)->field.le_prev; \ LIST_NEXT((elm), field) = (listelm); \ *(listelm)->field.le_prev = (elm); \ @@ -310,6 +587,7 @@ struct { \ } while (0) #define LIST_INSERT_HEAD(head, elm, field) do { \ + QMD_LIST_CHECK_HEAD((head), field); \ if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ LIST_FIRST((head)) = (elm); \ @@ -318,13 +596,54 @@ struct { \ #define LIST_NEXT(elm, field) ((elm)->field.le_next) +#define LIST_PREV(elm, head, type, field) \ + ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \ + __containerof((elm)->field.le_prev, \ + QUEUE_TYPEOF(type), field.le_next)) + +#define LIST_REMOVE_HEAD(head, field) \ + LIST_REMOVE(LIST_FIRST(head), field) + #define LIST_REMOVE(elm, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.le_next); \ + QMD_SAVELINK(oldprev, (elm)->field.le_prev); \ + QMD_LIST_CHECK_NEXT(elm, field); \ + QMD_LIST_CHECK_PREV(elm, field); \ if (LIST_NEXT((elm), field) != NULL) \ - LIST_NEXT((elm), field)->field.le_prev = \ + LIST_NEXT((elm), field)->field.le_prev = \ (elm)->field.le_prev; \ *(elm)->field.le_prev = LIST_NEXT((elm), field); \ + TRASHIT(*oldnext); \ + TRASHIT(*oldprev); \ } while (0) +#define LIST_REPLACE(elm, elm2, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.le_next); \ + QMD_SAVELINK(oldprev, (elm)->field.le_prev); \ + QMD_LIST_CHECK_NEXT(elm, field); \ + QMD_LIST_CHECK_PREV(elm, field); \ + LIST_NEXT((elm2), field) = LIST_NEXT((elm), field); \ + if (LIST_NEXT((elm2), field) != NULL) \ + LIST_NEXT((elm2), field)->field.le_prev = \ + &(elm2)->field.le_next; \ + (elm2)->field.le_prev = (elm)->field.le_prev; \ + *(elm2)->field.le_prev = (elm2); \ + TRASHIT(*oldnext); \ + TRASHIT(*oldprev); \ +} while (0) + +#define LIST_SWAP(head1, head2, type, field) do { \ + QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \ + LIST_FIRST((head1)) = LIST_FIRST((head2)); \ + LIST_FIRST((head2)) = swap_tmp; \ + if ((swap_tmp = LIST_FIRST((head1))) != NULL) \ + swap_tmp->field.le_prev = &LIST_FIRST((head1)); \ + if ((swap_tmp = LIST_FIRST((head2))) != NULL) \ + swap_tmp->field.le_prev = &LIST_FIRST((head2)); \ +} while (0) + +#define LIST_END(head) NULL + /* * Tail queue declarations. */ @@ -332,20 +651,100 @@ struct { \ struct name { \ struct type *tqh_first; /* first element */ \ struct type **tqh_last; /* addr of last next element */ \ + TRACEBUF \ +} + +#define TAILQ_CLASS_HEAD(name, type) \ +struct name { \ + class type *tqh_first; /* first element */ \ + class type **tqh_last; /* addr of last next element */ \ + TRACEBUF \ } #define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } + { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER } #define TAILQ_ENTRY(type) \ struct { \ struct type *tqe_next; /* next element */ \ struct type **tqe_prev; /* address of previous next element */ \ + TRACEBUF \ +} + +#define TAILQ_CLASS_ENTRY(type) \ +struct { \ + class type *tqe_next; /* next element */ \ + class type **tqe_prev; /* address of previous next element */ \ + TRACEBUF \ } /* * Tail queue functions. */ +#if (defined(_KERNEL) && defined(INVARIANTS)) +/* + * QMD_TAILQ_CHECK_HEAD(TAILQ_HEAD *head, TAILQ_ENTRY NAME) + * + * If the tailq is non-empty, validates that the first element of the tailq + * points back at 'head.' + */ +#define QMD_TAILQ_CHECK_HEAD(head, field) do { \ + if (!TAILQ_EMPTY(head) && \ + TAILQ_FIRST((head))->field.tqe_prev != \ + &TAILQ_FIRST((head))) \ + panic("Bad tailq head %p first->prev != head", (head)); \ +} while (0) + +/* + * QMD_TAILQ_CHECK_TAIL(TAILQ_HEAD *head, TAILQ_ENTRY NAME) + * + * Validates that the tail of the tailq is a pointer to pointer to NULL. + */ +#define QMD_TAILQ_CHECK_TAIL(head, field) do { \ + if (*(head)->tqh_last != NULL) \ + panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \ +} while (0) + +/* + * QMD_TAILQ_CHECK_NEXT(TYPE *elm, TAILQ_ENTRY NAME) + * + * If an element follows 'elm' in the tailq, validates that the next element + * points back at 'elm.' + */ +#define QMD_TAILQ_CHECK_NEXT(elm, field) do { \ + if (TAILQ_NEXT((elm), field) != NULL && \ + TAILQ_NEXT((elm), field)->field.tqe_prev != \ + &((elm)->field.tqe_next)) \ + panic("Bad link elm %p next->prev != elm", (elm)); \ +} while (0) + +/* + * QMD_TAILQ_CHECK_PREV(TYPE *elm, TAILQ_ENTRY NAME) + * + * Validates that the previous element (or head of the tailq) points to 'elm.' + */ +#define QMD_TAILQ_CHECK_PREV(elm, field) do { \ + if (*(elm)->field.tqe_prev != (elm)) \ + panic("Bad link elm %p prev->next != elm", (elm)); \ +} while (0) +#else +#define QMD_TAILQ_CHECK_HEAD(head, field) +#define QMD_TAILQ_CHECK_TAIL(head, headname) +#define QMD_TAILQ_CHECK_NEXT(elm, field) +#define QMD_TAILQ_CHECK_PREV(elm, field) +#endif /* (_KERNEL && INVARIANTS) */ + +#define TAILQ_CONCAT(head1, head2, field) do { \ + if (!TAILQ_EMPTY(head2)) { \ + *(head1)->tqh_last = (head2)->tqh_first; \ + (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ + (head1)->tqh_last = (head2)->tqh_last; \ + TAILQ_INIT((head2)); \ + QMD_TRACE_HEAD(head1); \ + QMD_TRACE_HEAD(head2); \ + } \ +} while (0) + #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) #define TAILQ_FIRST(head) ((head)->tqh_first) @@ -355,34 +754,74 @@ struct { \ (var); \ (var) = TAILQ_NEXT((var), field)) +#define TAILQ_FOREACH_FROM(var, head, field) \ + for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ + (var); \ + (var) = TAILQ_NEXT((var), field)) + +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = TAILQ_FIRST((head)); \ + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ + for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ for ((var) = TAILQ_LAST((head), headname); \ (var); \ (var) = TAILQ_PREV((var), headname, field)) +#define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \ + for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ + (var); \ + (var) = TAILQ_PREV((var), headname, field)) + +#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ + (var) = (tvar)) + +#define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar)\ + for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ + (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ + (var) = (tvar)) + #define TAILQ_INIT(head) do { \ TAILQ_FIRST((head)) = NULL; \ (head)->tqh_last = &TAILQ_FIRST((head)); \ + QMD_TRACE_HEAD(head); \ } while (0) #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + QMD_TAILQ_CHECK_NEXT(listelm, field); \ if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ &TAILQ_NEXT((elm), field); \ - else \ + else { \ (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + } \ TAILQ_NEXT((listelm), field) = (elm); \ (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&(listelm)->field); \ } while (0) #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + QMD_TAILQ_CHECK_PREV(listelm, field); \ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ TAILQ_NEXT((elm), field) = (listelm); \ *(listelm)->field.tqe_prev = (elm); \ (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&(listelm)->field); \ } while (0) #define TAILQ_INSERT_HEAD(head, elm, field) do { \ + QMD_TAILQ_CHECK_HEAD(head, field); \ if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ TAILQ_FIRST((head))->field.tqe_prev = \ &TAILQ_NEXT((elm), field); \ @@ -390,133 +829,98 @@ struct { \ (head)->tqh_last = &TAILQ_NEXT((elm), field); \ TAILQ_FIRST((head)) = (elm); \ (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ } while (0) #define TAILQ_INSERT_TAIL(head, elm, field) do { \ + QMD_TAILQ_CHECK_TAIL(head, field); \ TAILQ_NEXT((elm), field) = NULL; \ (elm)->field.tqe_prev = (head)->tqh_last; \ *(head)->tqh_last = (elm); \ (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ } while (0) #define TAILQ_LAST(head, headname) \ (*(((struct headname *)((head)->tqh_last))->tqh_last)) +/* + * The FAST function is fast in that it causes no data access other + * then the access to the head. The standard LAST function above + * will cause a data access of both the element you want and + * the previous element. FAST is very useful for instances when + * you may want to prefetch the last data element. + */ +#define TAILQ_LAST_FAST(head, type, field) \ + (TAILQ_EMPTY(head) ? NULL : __containerof((head)->tqh_last, QUEUE_TYPEOF(type), field.tqe_next)) + #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) #define TAILQ_PREV(elm, headname, field) \ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) +#define TAILQ_PREV_FAST(elm, head, type, field) \ + ((elm)->field.tqe_prev == &(head)->tqh_first ? NULL : \ + __containerof((elm)->field.tqe_prev, QUEUE_TYPEOF(type), field.tqe_next)) + +#define TAILQ_REMOVE_HEAD(head, field) \ + TAILQ_REMOVE(head, TAILQ_FIRST(head), field) + #define TAILQ_REMOVE(head, elm, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \ + QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \ + QMD_TAILQ_CHECK_NEXT(elm, field); \ + QMD_TAILQ_CHECK_PREV(elm, field); \ if ((TAILQ_NEXT((elm), field)) != NULL) \ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ (elm)->field.tqe_prev; \ - else \ + else { \ (head)->tqh_last = (elm)->field.tqe_prev; \ + QMD_TRACE_HEAD(head); \ + } \ *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ + TRASHIT(*oldnext); \ + TRASHIT(*oldprev); \ + QMD_TRACE_ELEM(&(elm)->field); \ } while (0) -/* - * Circular queue declarations. - */ -#define CIRCLEQ_HEAD(name, type) \ -struct name { \ - struct type *cqh_first; /* first element */ \ - struct type *cqh_last; /* last element */ \ -} - -#define CIRCLEQ_HEAD_INITIALIZER(head) \ - { (void *)&(head), (void *)&(head) } - -#define CIRCLEQ_ENTRY(type) \ -struct { \ - struct type *cqe_next; /* next element */ \ - struct type *cqe_prev; /* previous element */ \ -} - -/* - * Circular queue functions. - */ -#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) - -#define CIRCLEQ_FIRST(head) ((head)->cqh_first) - -#define CIRCLEQ_FOREACH(var, head, field) \ - for ((var) = CIRCLEQ_FIRST((head)); \ - (var) != (void *)(head) || ((var) = NULL); \ - (var) = CIRCLEQ_NEXT((var), field)) - -#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ - for ((var) = CIRCLEQ_LAST((head)); \ - (var) != (void *)(head) || ((var) = NULL); \ - (var) = CIRCLEQ_PREV((var), field)) - -#define CIRCLEQ_INIT(head) do { \ - CIRCLEQ_FIRST((head)) = (void *)(head); \ - CIRCLEQ_LAST((head)) = (void *)(head); \ -} while (0) - -#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - CIRCLEQ_NEXT((elm), field) = CIRCLEQ_NEXT((listelm), field); \ - CIRCLEQ_PREV((elm), field) = (listelm); \ - if (CIRCLEQ_NEXT((listelm), field) == (void *)(head)) \ - CIRCLEQ_LAST((head)) = (elm); \ - else \ - CIRCLEQ_PREV(CIRCLEQ_NEXT((listelm), field), field) = (elm);\ - CIRCLEQ_NEXT((listelm), field) = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ - CIRCLEQ_NEXT((elm), field) = (listelm); \ - CIRCLEQ_PREV((elm), field) = CIRCLEQ_PREV((listelm), field); \ - if (CIRCLEQ_PREV((listelm), field) == (void *)(head)) \ - CIRCLEQ_FIRST((head)) = (elm); \ - else \ - CIRCLEQ_NEXT(CIRCLEQ_PREV((listelm), field), field) = (elm);\ - CIRCLEQ_PREV((listelm), field) = (elm); \ +#define TAILQ_REPLACE(head, elm, elm2, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \ + QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \ + QMD_TAILQ_CHECK_NEXT(elm, field); \ + QMD_TAILQ_CHECK_PREV(elm, field); \ + TAILQ_NEXT((elm2), field) = TAILQ_NEXT((elm), field); \ + if (TAILQ_NEXT((elm2), field) != TAILQ_END(head)) \ + TAILQ_NEXT((elm2), field)->field.tqe_prev = \ + &(elm2)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm2)->field.tqe_next; \ + (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ + *(elm2)->field.tqe_prev = (elm2); \ + TRASHIT(*oldnext); \ + TRASHIT(*oldprev); \ + QMD_TRACE_ELEM(&(elm)->field); \ } while (0) -#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ - CIRCLEQ_NEXT((elm), field) = CIRCLEQ_FIRST((head)); \ - CIRCLEQ_PREV((elm), field) = (void *)(head); \ - if (CIRCLEQ_LAST((head)) == (void *)(head)) \ - CIRCLEQ_LAST((head)) = (elm); \ +#define TAILQ_SWAP(head1, head2, type, field) do { \ + QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \ + QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \ + (head1)->tqh_first = (head2)->tqh_first; \ + (head1)->tqh_last = (head2)->tqh_last; \ + (head2)->tqh_first = swap_first; \ + (head2)->tqh_last = swap_last; \ + if ((swap_first = (head1)->tqh_first) != NULL) \ + swap_first->field.tqe_prev = &(head1)->tqh_first; \ else \ - CIRCLEQ_PREV(CIRCLEQ_FIRST((head)), field) = (elm); \ - CIRCLEQ_FIRST((head)) = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ - CIRCLEQ_NEXT((elm), field) = (void *)(head); \ - CIRCLEQ_PREV((elm), field) = CIRCLEQ_LAST((head)); \ - if (CIRCLEQ_FIRST((head)) == (void *)(head)) \ - CIRCLEQ_FIRST((head)) = (elm); \ - else \ - CIRCLEQ_NEXT(CIRCLEQ_LAST((head)), field) = (elm); \ - CIRCLEQ_LAST((head)) = (elm); \ -} while (0) - -#define CIRCLEQ_LAST(head) ((head)->cqh_last) - -#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next) - -#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev) - -#define CIRCLEQ_REMOVE(head, elm, field) do { \ - if (CIRCLEQ_NEXT((elm), field) == (void *)(head)) \ - CIRCLEQ_LAST((head)) = CIRCLEQ_PREV((elm), field); \ - else \ - CIRCLEQ_PREV(CIRCLEQ_NEXT((elm), field), field) = \ - CIRCLEQ_PREV((elm), field); \ - if (CIRCLEQ_PREV((elm), field) == (void *)(head)) \ - CIRCLEQ_FIRST((head)) = CIRCLEQ_NEXT((elm), field); \ + (head1)->tqh_last = &(head1)->tqh_first; \ + if ((swap_first = (head2)->tqh_first) != NULL) \ + swap_first->field.tqe_prev = &(head2)->tqh_first; \ else \ - CIRCLEQ_NEXT(CIRCLEQ_PREV((elm), field), field) = \ - CIRCLEQ_NEXT((elm), field); \ + (head2)->tqh_last = &(head2)->tqh_first; \ } while (0) -#ifdef __cplusplus -} -#endif +#define TAILQ_END(head) NULL #endif /* !_SYS_QUEUE_H_ */ diff --git a/porting/nimble/src/os_mbuf.c b/porting/nimble/src/os_mbuf.c index 6d84be1f4b..829d798583 100644 --- a/porting/nimble/src/os_mbuf.c +++ b/porting/nimble/src/os_mbuf.c @@ -49,15 +49,12 @@ #define max(a, b) ((a) > (b) ? (a) : (b)) #endif -/** - * @addtogroup OSKernel - * @{ - * @defgroup OSMqueue Queue of Mbufs - * @{ - */ +#include "syscfg/syscfg.h" +#if !MYNEWT_VAL(OS_SYSVIEW_TRACE_MBUF) +#define OS_TRACE_DISABLE_FILE_API +#endif + -STAILQ_HEAD(, os_mbuf_pool) g_msys_pool_list = - STAILQ_HEAD_INITIALIZER(g_msys_pool_list); int @@ -97,19 +94,19 @@ os_mqueue_get(struct os_mqueue *mq) } int -os_mqueue_put(struct os_mqueue *mq, struct ble_npl_eventq *evq, struct os_mbuf *m) +os_mqueue_put(struct os_mqueue *mq, struct ble_npl_eventq *evq, struct os_mbuf *om) { struct os_mbuf_pkthdr *mp; os_sr_t sr; int rc; /* Can only place the head of a chained mbuf on the queue. */ - if (!OS_MBUF_IS_PKTHDR(m)) { + if (!OS_MBUF_IS_PKTHDR(om)) { rc = OS_EINVAL; goto err; } - mp = OS_MBUF_PKTHDR(m); + mp = OS_MBUF_PKTHDR(om); OS_ENTER_CRITICAL(sr); STAILQ_INSERT_TAIL(&mq->mq_head, mp, omp_next); @@ -125,141 +122,6 @@ os_mqueue_put(struct os_mqueue *mq, struct ble_npl_eventq *evq, struct os_mbuf * return (rc); } -int -os_msys_register(struct os_mbuf_pool *new_pool) -{ - struct os_mbuf_pool *pool; - - pool = NULL; - STAILQ_FOREACH(pool, &g_msys_pool_list, omp_next) { - if (new_pool->omp_databuf_len > pool->omp_databuf_len) { - break; - } - } - - if (pool) { - STAILQ_INSERT_AFTER(&g_msys_pool_list, pool, new_pool, omp_next); - } else { - STAILQ_INSERT_TAIL(&g_msys_pool_list, new_pool, omp_next); - } - - return (0); -} - -void -os_msys_reset(void) -{ - STAILQ_INIT(&g_msys_pool_list); -} - -static struct os_mbuf_pool * -os_msys_find_pool(uint16_t dsize) -{ - struct os_mbuf_pool *pool; - struct os_mbuf_pool *pool_with_free_blocks = NULL; - uint16_t pool_free_blocks; - - STAILQ_FOREACH(pool, &g_msys_pool_list, omp_next) { - pool_free_blocks = pool->omp_pool->mp_num_free; - if (pool_free_blocks != 0) { - pool_with_free_blocks = pool; - if (dsize <= pool->omp_databuf_len) { - break; - } - } - } - - return pool_with_free_blocks; -} - -static struct os_mbuf_pool * -os_msys_find_biggest_pool(void) -{ - return os_msys_find_pool(0xFFFF); -} - -struct os_mbuf * -os_msys_get(uint16_t dsize, uint16_t leadingspace) -{ - struct os_mbuf *m; - struct os_mbuf_pool *pool; - - /* If dsize = 0 that means user has no idea how big block size is needed, - * therefore lets find for him the biggest one - */ - if (dsize == 0) { - pool = os_msys_find_biggest_pool(); - } else { - pool = os_msys_find_pool(dsize); - } - - if (!pool) { - goto err; - } - - m = os_mbuf_get(pool, leadingspace); - return (m); -err: - return (NULL); -} - -struct os_mbuf * -os_msys_get_pkthdr(uint16_t dsize, uint16_t user_hdr_len) -{ - uint16_t total_pkthdr_len; - struct os_mbuf *m; - struct os_mbuf_pool *pool; - - total_pkthdr_len = user_hdr_len + sizeof(struct os_mbuf_pkthdr); - - /* If dsize = 0 that means user has no idea how big block size is needed, - * therefore lets find for him the biggest one - */ - if (dsize == 0) { - pool = os_msys_find_biggest_pool(); - } else { - pool = os_msys_find_pool(dsize + total_pkthdr_len); - } - - if (!pool) { - goto err; - } - - m = os_mbuf_get_pkthdr(pool, user_hdr_len); - return (m); -err: - return (NULL); -} - -int -os_msys_count(void) -{ - struct os_mbuf_pool *omp; - int total; - - total = 0; - STAILQ_FOREACH(omp, &g_msys_pool_list, omp_next) { - total += omp->omp_pool->mp_num_blocks; - } - - return total; -} - -int -os_msys_num_free(void) -{ - struct os_mbuf_pool *omp; - int total; - - total = 0; - STAILQ_FOREACH(omp, &g_msys_pool_list, omp_next) { - total += omp->omp_pool->mp_num_free; - } - - return total; -} - - int os_mbuf_pool_init(struct os_mbuf_pool *omp, struct os_mempool *mp, uint16_t buf_len, uint16_t nbufs) @@ -275,8 +137,8 @@ os_mbuf_get(struct os_mbuf_pool *omp, uint16_t leadingspace) { struct os_mbuf *om; - os_trace_api_u32x2(OS_TRACE_ID_MBUF_GET, (uint32_t)omp, - (uint32_t)(uintptr_t)leadingspace); + os_trace_api_u32x2(OS_TRACE_ID_MBUF_GET, (uintptr_t)omp, + (uint32_t)leadingspace); if (leadingspace > omp->omp_databuf_len) { om = NULL; @@ -296,7 +158,7 @@ os_mbuf_get(struct os_mbuf_pool *omp, uint16_t leadingspace) om->om_omp = omp; done: - os_trace_api_ret_u32(OS_TRACE_ID_MBUF_GET, (uint32_t)(uintptr_t)om); + os_trace_api_ret_u32(OS_TRACE_ID_MBUF_GET, (uintptr_t)om); return om; } @@ -307,7 +169,7 @@ os_mbuf_get_pkthdr(struct os_mbuf_pool *omp, uint8_t user_pkthdr_len) struct os_mbuf_pkthdr *pkthdr; struct os_mbuf *om; - os_trace_api_u32x2(OS_TRACE_ID_MBUF_GET_PKTHDR, (uint32_t)(uintptr_t)omp, + os_trace_api_u32x2(OS_TRACE_ID_MBUF_GET_PKTHDR, (uintptr_t)omp, (uint32_t)user_pkthdr_len); /* User packet header must fit inside mbuf */ @@ -329,7 +191,7 @@ os_mbuf_get_pkthdr(struct os_mbuf_pool *omp, uint8_t user_pkthdr_len) } done: - os_trace_api_ret_u32(OS_TRACE_ID_MBUF_GET_PKTHDR, (uint32_t)(uintptr_t)om); + os_trace_api_ret_u32(OS_TRACE_ID_MBUF_GET_PKTHDR, (uintptr_t)om); return om; } @@ -338,7 +200,7 @@ os_mbuf_free(struct os_mbuf *om) { int rc; - os_trace_api_u32(OS_TRACE_ID_MBUF_FREE, (uint32_t)(uintptr_t)om); + os_trace_api_u32(OS_TRACE_ID_MBUF_FREE, (uintptr_t)om); if (om->om_omp != NULL) { rc = os_memblock_put(om->om_omp->omp_pool, om); @@ -360,7 +222,7 @@ os_mbuf_free_chain(struct os_mbuf *om) struct os_mbuf *next; int rc; - os_trace_api_u32(OS_TRACE_ID_MBUF_FREE_CHAIN, (uint32_t)(uintptr_t)om); + os_trace_api_u32(OS_TRACE_ID_MBUF_FREE_CHAIN, (uintptr_t)om); while (om != NULL) { next = SLIST_NEXT(om, om_next); @@ -588,7 +450,7 @@ os_mbuf_off(const struct os_mbuf *om, int off, uint16_t *out_off) } int -os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst) +os_mbuf_copydata(const struct os_mbuf *om, int off, int len, void *dst) { unsigned int count; uint8_t *udst; @@ -600,36 +462,38 @@ os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst) udst = dst; while (off > 0) { - if (!m) { + if (!om) { return (-1); } - if (off < m->om_len) + if (off < om->om_len) { break; - off -= m->om_len; - m = SLIST_NEXT(m, om_next); + } + off -= om->om_len; + om = SLIST_NEXT(om, om_next); } - while (len > 0 && m != NULL) { - count = min(m->om_len - off, len); - memcpy(udst, m->om_data + off, count); + while (len > 0 && om != NULL) { + count = min(om->om_len - off, len); + memcpy(udst, om->om_data + off, count); len -= count; udst += count; off = 0; - m = SLIST_NEXT(m, om_next); + om = SLIST_NEXT(om, om_next); } return (len > 0 ? -1 : 0); } void -os_mbuf_adj(struct os_mbuf *mp, int req_len) +os_mbuf_adj(struct os_mbuf *om, int req_len) { int len = req_len; struct os_mbuf *m; int count; - if ((m = mp) == NULL) + if ((m = om) == NULL) { return; + } if (len >= 0) { /* * Trim from head. @@ -645,8 +509,9 @@ os_mbuf_adj(struct os_mbuf *mp, int req_len) len = 0; } } - if (OS_MBUF_IS_PKTHDR(mp)) - OS_MBUF_PKTHDR(mp)->omp_len -= (req_len - len); + if (OS_MBUF_IS_PKTHDR(om)) { + OS_MBUF_PKTHDR(om)->omp_len -= (req_len - len); + } } else { /* * Trim from tail. Scan the mbuf chain, @@ -665,8 +530,9 @@ os_mbuf_adj(struct os_mbuf *mp, int req_len) } if (m->om_len >= len) { m->om_len -= len; - if (OS_MBUF_IS_PKTHDR(mp)) - OS_MBUF_PKTHDR(mp)->omp_len -= len; + if (OS_MBUF_IS_PKTHDR(om)) { + OS_MBUF_PKTHDR(om)->omp_len -= len; + } return; } count -= len; @@ -677,7 +543,7 @@ os_mbuf_adj(struct os_mbuf *mp, int req_len) * Find the mbuf with last data, adjust its length, * and toss data from remaining mbufs on chain. */ - m = mp; + m = om; if (OS_MBUF_IS_PKTHDR(m)) OS_MBUF_PKTHDR(m)->omp_len = count; for (; m; m = SLIST_NEXT(m, om_next)) { diff --git a/porting/nimble/src/os_mempool.c b/porting/nimble/src/os_mempool.c index 09d5e35263..9800d88087 100644 --- a/porting/nimble/src/os_mempool.c +++ b/porting/nimble/src/os_mempool.c @@ -32,8 +32,8 @@ #if MYNEWT_VAL(OS_MEMPOOL_GUARD) #define OS_MEMPOOL_TRUE_BLOCK_SIZE(mp) \ (((mp)->mp_flags & OS_MEMPOOL_F_EXT) ? \ - OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size) : \ - (OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size) + sizeof(os_membuf_t))) + OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size) : \ + (OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size) + sizeof(os_membuf_t))) #else #define OS_MEMPOOL_TRUE_BLOCK_SIZE(mp) OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size) #endif @@ -95,7 +95,7 @@ os_mempool_guard(const struct os_mempool *mp, void *start) if ((mp->mp_flags & OS_MEMPOOL_F_EXT) == 0) { tgt = (uint32_t *)((uintptr_t)start + - OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size)); + OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size)); *tgt = OS_MEMPOOL_GUARD_PATTERN; } } @@ -107,7 +107,7 @@ os_mempool_guard_check(const struct os_mempool *mp, void *start) if ((mp->mp_flags & OS_MEMPOOL_F_EXT) == 0) { tgt = (uint32_t *)((uintptr_t)start + - OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size)); + OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size)); assert(*tgt == OS_MEMPOOL_GUARD_PATTERN); } } @@ -139,7 +139,7 @@ os_mempool_init_internal(struct os_mempool *mp, uint16_t blocks, /* Blocks need to be sized properly and memory buffer should be * aligned */ - if (((uint32_t)(uintptr_t)membuf & (OS_ALIGNMENT - 1)) != 0) { + if (((uintptr_t)membuf & (OS_ALIGNMENT - 1)) != 0) { return OS_MEM_NOT_ALIGNED; } } @@ -150,7 +150,7 @@ os_mempool_init_internal(struct os_mempool *mp, uint16_t blocks, mp->mp_min_free = blocks; mp->mp_flags = flags; mp->mp_num_blocks = blocks; - mp->mp_membuf_addr = (uint32_t)(uintptr_t)membuf; + mp->mp_membuf_addr = (uintptr_t)membuf; mp->name = name; SLIST_FIRST(mp) = membuf; @@ -261,10 +261,10 @@ os_mempool_clear(struct os_mempool *mp) mp->mp_min_free = mp->mp_num_blocks; os_mempool_poison(mp, (void *)mp->mp_membuf_addr); os_mempool_guard(mp, (void *)mp->mp_membuf_addr); - SLIST_FIRST(mp) = (void *)(uintptr_t)mp->mp_membuf_addr; + SLIST_FIRST(mp) = (void *)mp->mp_membuf_addr; /* Chain the memory blocks to the free list */ - block_addr = (uint8_t *)(uintptr_t)mp->mp_membuf_addr; + block_addr = (uint8_t *)mp->mp_membuf_addr; block_ptr = (struct os_memblock *)block_addr; blocks = mp->mp_num_blocks; @@ -304,23 +304,20 @@ int os_memblock_from(const struct os_mempool *mp, const void *block_addr) { uint32_t true_block_size; - uintptr_t baddr32; - uint32_t end; + uintptr_t baddr; + uintptr_t end; - static_assert(sizeof block_addr == sizeof baddr32, - "Pointer to void must be 32-bits."); - - baddr32 = (uint32_t)(uintptr_t)block_addr; + baddr = (uintptr_t)block_addr; true_block_size = OS_MEMPOOL_TRUE_BLOCK_SIZE(mp); end = mp->mp_membuf_addr + (mp->mp_num_blocks * true_block_size); /* Check that the block is in the memory buffer range. */ - if ((baddr32 < mp->mp_membuf_addr) || (baddr32 >= end)) { + if ((baddr < mp->mp_membuf_addr) || (baddr >= end)) { return 0; } /* All freed blocks should be on true block size boundaries! */ - if (((baddr32 - mp->mp_membuf_addr) % true_block_size) != 0) { + if (((baddr - mp->mp_membuf_addr) % true_block_size) != 0) { return 0; } @@ -333,7 +330,7 @@ os_memblock_get(struct os_mempool *mp) os_sr_t sr; struct os_memblock *block; - os_trace_api_u32(OS_TRACE_ID_MEMBLOCK_GET, (uint32_t)(uintptr_t)mp); + os_trace_api_u32(OS_TRACE_ID_MEMBLOCK_GET, (uintptr_t)mp); /* Check to make sure they passed in a memory pool (or something) */ block = NULL; @@ -361,7 +358,7 @@ os_memblock_get(struct os_mempool *mp) } } - os_trace_api_ret_u32(OS_TRACE_ID_MEMBLOCK_GET, (uint32_t)(uintptr_t)block); + os_trace_api_ret_u32(OS_TRACE_ID_MEMBLOCK_GET, (uintptr_t)block); return (void *)block; } @@ -372,8 +369,8 @@ os_memblock_put_from_cb(struct os_mempool *mp, void *block_addr) os_sr_t sr; struct os_memblock *block; - os_trace_api_u32x2(OS_TRACE_ID_MEMBLOCK_PUT_FROM_CB, (uint32_t)(uintptr_t)mp, - (uint32_t)(uintptr_t)block_addr); + os_trace_api_u32x2(OS_TRACE_ID_MEMBLOCK_PUT_FROM_CB, (uintptr_t)mp, + (uintptr_t)block_addr); os_mempool_guard_check(mp, block_addr); os_mempool_poison(mp, block_addr); @@ -403,10 +400,11 @@ os_memblock_put(struct os_mempool *mp, void *block_addr) os_error_t ret; #if MYNEWT_VAL(OS_MEMPOOL_CHECK) struct os_memblock *block; + int sr; #endif - os_trace_api_u32x2(OS_TRACE_ID_MEMBLOCK_PUT, (uint32_t)(uintptr_t)mp, - (uint32_t)(uintptr_t)block_addr); + os_trace_api_u32x2(OS_TRACE_ID_MEMBLOCK_PUT, (uintptr_t)mp, + (uintptr_t)block_addr); /* Make sure parameters are valid */ if ((mp == NULL) || (block_addr == NULL)) { @@ -421,9 +419,12 @@ os_memblock_put(struct os_mempool *mp, void *block_addr) /* * Check for duplicate free. */ + OS_ENTER_CRITICAL(sr); SLIST_FOREACH(block, mp, mb_next) { assert(block != (struct os_memblock *)block_addr); } + OS_EXIT_CRITICAL(sr); + #endif /* If this is an extended mempool with a put callback, call the callback * instead of freeing the block directly. @@ -469,8 +470,34 @@ os_mempool_info_get_next(struct os_mempool *mp, struct os_mempool_info *omi) return (cur); } +struct os_mempool * +os_mempool_get(const char *mempool_name, struct os_mempool_info *info) +{ + struct os_mempool *mp; + + mp = STAILQ_FIRST(&g_os_mempool_list); + while (mp) { + if (strcmp(mempool_name, mp->name) == 0) { + break; + } + mp = STAILQ_NEXT(mp, mp_list); + } + + if (mp != NULL && info != NULL) { + info->omi_block_size = mp->mp_block_size; + info->omi_num_blocks = mp->mp_num_blocks; + info->omi_num_free = mp->mp_num_free; + info->omi_min_free = mp->mp_min_free; + info->omi_name[0] = '\0'; + strncat(info->omi_name, mp->name, sizeof(info->omi_name) - 1); + } + + return mp; +} + void os_mempool_module_init(void) { STAILQ_INIT(&g_os_mempool_list); } + diff --git a/porting/nimble/src/os_msys_init.c b/porting/nimble/src/os_msys.c similarity index 59% rename from porting/nimble/src/os_msys_init.c rename to porting/nimble/src/os_msys.c index d22ae351f3..7f1069fab0 100644 --- a/porting/nimble/src/os_msys_init.c +++ b/porting/nimble/src/os_msys.c @@ -22,7 +22,7 @@ #include "mem/mem.h" #include "sysinit/sysinit.h" -static STAILQ_HEAD(, os_mbuf_pool) g_msys_pool_list = +static STAILQ_HEAD(os_mbuf_list, os_mbuf_pool) g_msys_pool_list = STAILQ_HEAD_INITIALIZER(g_msys_pool_list); #if MYNEWT_VAL(MSYS_1_BLOCK_COUNT) > 0 @@ -55,6 +55,147 @@ static struct os_mempool os_msys_2_mempool; static struct os_sanity_check os_msys_sc; #endif +int +os_msys_register(struct os_mbuf_pool *new_pool) +{ + struct os_mbuf_pool *pool; + struct os_mbuf_pool *prev; + + /* We want to have order from smallest to biggest mempool. */ + prev = NULL; + pool = NULL; + STAILQ_FOREACH(pool, &g_msys_pool_list, omp_next) { + if (new_pool->omp_databuf_len < pool->omp_databuf_len) { + break; + } + prev = pool; + } + + if (prev) { + STAILQ_INSERT_AFTER(&g_msys_pool_list, prev, new_pool, omp_next); + } else { + STAILQ_INSERT_HEAD(&g_msys_pool_list, new_pool, omp_next); + } + + return (0); +} + +void +os_msys_reset(void) +{ + STAILQ_INIT(&g_msys_pool_list); +} + +static struct os_mbuf_pool *os_msys_find_pool(uint16_t dsize); + +static struct os_mbuf_pool * +os_msys_find_biggest_pool(void) +{ + return os_msys_find_pool(0xFFFF); +} + +static struct os_mbuf_pool * +os_msys_find_pool(uint16_t dsize) +{ + struct os_mbuf_pool *pool; + struct os_mbuf_pool *pool_with_free_blocks = NULL; + uint16_t pool_free_blocks; + + STAILQ_FOREACH(pool, &g_msys_pool_list, omp_next) { + pool_free_blocks = pool->omp_pool->mp_num_free; + if (pool_free_blocks != 0) { + pool_with_free_blocks = pool; + if (dsize <= pool->omp_databuf_len) { + break; + } + } + } + + return pool_with_free_blocks; +} + + +struct os_mbuf * +os_msys_get(uint16_t dsize, uint16_t leadingspace) +{ + struct os_mbuf *m; + struct os_mbuf_pool *pool; + + /* If dsize = 0 that means user has no idea how big block size is needed, + * therefore lets find for him the biggest one + */ + if (dsize == 0) { + pool = os_msys_find_biggest_pool(); + } else { + pool = os_msys_find_pool(dsize); + } + + if (!pool) { + goto err; + } + + m = os_mbuf_get(pool, leadingspace); + return (m); +err: + return (NULL); +} + +struct os_mbuf * +os_msys_get_pkthdr(uint16_t dsize, uint16_t user_hdr_len) +{ + uint16_t total_pkthdr_len; + struct os_mbuf *m; + struct os_mbuf_pool *pool; + + total_pkthdr_len = user_hdr_len + sizeof(struct os_mbuf_pkthdr); + + /* If dsize = 0 that means user has no idea how big block size is needed, + * therefore lets find for him the biggest one + */ + if (dsize == 0) { + pool = os_msys_find_biggest_pool(); + } else { + pool = os_msys_find_pool(dsize + total_pkthdr_len); + } + + if (!pool) { + goto err; + } + + m = os_mbuf_get_pkthdr(pool, user_hdr_len); + return (m); +err: + return (NULL); +} + +int +os_msys_count(void) +{ + struct os_mbuf_pool *omp; + int total; + + total = 0; + STAILQ_FOREACH(omp, &g_msys_pool_list, omp_next) { + total += omp->omp_pool->mp_num_blocks; + } + + return total; +} + +int +os_msys_num_free(void) +{ + struct os_mbuf_pool *omp; + int total; + + total = 0; + STAILQ_FOREACH(omp, &g_msys_pool_list, omp_next) { + total += omp->omp_pool->mp_num_free; + } + + return total; +} + #if OS_MSYS_SANITY_ENABLED /** @@ -153,4 +294,12 @@ os_msys_init(void) rc = os_sanity_check_register(&os_msys_sc); SYSINIT_PANIC_ASSERT(rc == 0); #endif -} \ No newline at end of file +} + +#if MYNEWT_VAL(SELFTEST) +struct os_mbuf_list * +get_msys_pool_list(void) +{ + return &g_msys_pool_list; +} +#endif From 69c7f254055c6b0868c7712d42a5b68f3e8b4b58 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 29 Jul 2025 15:11:40 +0200 Subject: [PATCH 1295/1333] porting/linux: Fix implixit declaration warnings Some API (to allow inline implementation) need to be declared in OS specific nimble_npl_os.h. --- porting/npl/linux/include/nimble/nimble_npl_os.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/porting/npl/linux/include/nimble/nimble_npl_os.h b/porting/npl/linux/include/nimble/nimble_npl_os.h index d171fc048c..d8688d3e6d 100644 --- a/porting/npl/linux/include/nimble/nimble_npl_os.h +++ b/porting/npl/linux/include/nimble/nimble_npl_os.h @@ -35,6 +35,9 @@ extern "C" { #define BLE_NPL_TIME_FOREVER INT32_MAX +struct ble_npl_eventq * ble_npl_eventq_dflt_get(void); +void ble_npl_eventq_run(struct ble_npl_eventq *evq); + #ifdef __cplusplus } #endif From 217e7ff1f7de6457cb2a23c01714058c14f27aac Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 23 Jul 2025 16:44:10 +0200 Subject: [PATCH 1296/1333] nimble: Add option to select Core 6.1 This allows to configure stack as Bluetooth Core 6.1. --- nimble/include/nimble/hci_common.h | 5 +++++ nimble/syscfg.yml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h index 24843de3c2..01c3dbc14b 100644 --- a/nimble/include/nimble/hci_common.h +++ b/nimble/include/nimble/hci_common.h @@ -2379,6 +2379,7 @@ struct ble_hci_ev_le_subev_cs_test_end_complete { #define BLE_HCI_VER_BCS_5_3 (12) #define BLE_HCI_VER_BCS_5_4 (13) #define BLE_HCI_VER_BCS_6_0 (14) +#define BLE_HCI_VER_BCS_6_1 (15) #define BLE_LMP_VER_BCS_1_0b (0) #define BLE_LMP_VER_BCS_1_1 (1) @@ -2395,6 +2396,7 @@ struct ble_hci_ev_le_subev_cs_test_end_complete { #define BLE_LMP_VER_BCS_5_3 (12) #define BLE_LMP_VER_BCS_5_4 (13) #define BLE_LMP_VER_BCS_6_0 (14) +#define BLE_LMP_VER_BCS_6_1 (15) /* selected HCI and LMP version */ #if MYNEWT_VAL(BLE_VERSION) == 50 @@ -2415,6 +2417,9 @@ struct ble_hci_ev_le_subev_cs_test_end_complete { #elif MYNEWT_VAL(BLE_VERSION) == 60 #define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_6_0 #define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_6_0 +#elif MYNEWT_VAL(BLE_VERSION) == 61 +#define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_6_1 +#define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_6_1 #else #error Unsupported BLE_VERSION selected #endif diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml index 638a40832c..a1948c65d6 100644 --- a/nimble/syscfg.yml +++ b/nimble/syscfg.yml @@ -87,7 +87,7 @@ syscfg.defs: This allows to configure supported Bluetooth Core version. Some features may not be available if version is too low. Version is integer for easy comparison. - range: 50, 51, 52, 53, 54, 60 + range: 50, 51, 52, 53, 54, 60, 61 value: 50 BLE_ISO: description: > From 8e8eb4d48a9a721e4bcb579e9170f6ab30794828 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 30 Jul 2025 13:36:04 +0200 Subject: [PATCH 1297/1333] ci: Fix RIOT port build RIOT reordered examples fodler structure. --- .github/workflows/build_ports.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_ports.yml b/.github/workflows/build_ports.yml index fc508aa3a3..83efa8047e 100644 --- a/.github/workflows/build_ports.yml +++ b/.github/workflows/build_ports.yml @@ -51,7 +51,7 @@ jobs: rm RIOT/pkg/nimble/patches/ -rf sed -i 's|PKG_URL.*|PKG_URL = '$(pwd)'|' RIOT/pkg/nimble/Makefile sed -i 's|PKG_VERSION.*|PKG_VERSION = '${{ github.sha }}'|' RIOT/pkg/nimble/Makefile - make -C RIOT/examples/nimble_gatt + make -C RIOT/examples/networking/ble/nimble/nimble_gatt - name: Build Nuttx port shell: bash if: success() || failure() From cbb3172609f31fc9f17df083bf278d4aef8cb105 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 30 Jul 2025 15:22:36 +0200 Subject: [PATCH 1298/1333] nimble/host: Fix available packets counter leak Mark connection as disconnected as soon as HCI Disconnection Complete event is processed. At this point ACL handle is no longer valid and controller will ignore any ACL data sent to it. Since later GAP Disconnected event is not handled atomically it may lead to TX data on that handle and thus 'leaking' available packets count on host. This is especially possible when there is connection timoue while host is in the middle of data transmission (eg sending nitifications). --- nimble/host/src/ble_hs_conn_priv.h | 1 + nimble/host/src/ble_hs_hci.c | 11 +++++++++++ nimble/host/src/ble_hs_hci_evt.c | 3 ++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/nimble/host/src/ble_hs_conn_priv.h b/nimble/host/src/ble_hs_conn_priv.h index 31e831c878..2d23422f54 100644 --- a/nimble/host/src/ble_hs_conn_priv.h +++ b/nimble/host/src/ble_hs_conn_priv.h @@ -37,6 +37,7 @@ typedef uint8_t ble_hs_conn_flags_t; #define BLE_HS_CONN_F_MASTER 0x01 #define BLE_HS_CONN_F_TERMINATING 0x02 #define BLE_HS_CONN_F_TX_FRAG 0x04 /* Cur ACL packet partially txed. */ +#define BLE_HS_CONN_F_TERMINATED 0x08 #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) #define BLE_HS_CONN_L2CAP_COC_CID_MASK_LEN_REM \ diff --git a/nimble/host/src/ble_hs_hci.c b/nimble/host/src/ble_hs_hci.c index 2321b90cb8..e3fe335f5b 100644 --- a/nimble/host/src/ble_hs_hci.c +++ b/nimble/host/src/ble_hs_hci.c @@ -515,6 +515,17 @@ ble_hs_hci_acl_tx_now(struct ble_hs_conn *conn, struct os_mbuf **om) BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task()); + /* conn may be already disconnected but GAP events were not yet + * processed and thus connection object is stil on list, just ignore it + * in such case as ACL handle is not valid anymore and conn object will + * be removed shortly. + */ + if (conn->bhc_flags & BLE_HS_CONN_F_TERMINATED) { + os_mbuf_free_chain(*om); + *om = NULL; + return 0; + } + txom = *om; *om = NULL; diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 47430423be..55031fcd70 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -213,7 +213,7 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, unsigned int len) { const struct ble_hci_ev_disconn_cmp *ev = data; - const struct ble_hs_conn *conn; + struct ble_hs_conn *conn; if (len != sizeof(*ev)) { return BLE_HS_ECONTROLLER; @@ -223,6 +223,7 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, conn = ble_hs_conn_find(le16toh(ev->conn_handle)); if (conn != NULL) { ble_hs_hci_add_avail_pkts(conn->bhc_outstanding_pkts); + conn->bhc_flags |= BLE_HS_CONN_F_TERMINATED; } ble_hs_unlock(); From f14e458938d8296cc2f578f42ec3100c73b85890 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 1 Aug 2025 10:34:49 +0200 Subject: [PATCH 1299/1333] ci: Add GCC 14 to build matrix Validates if things build with GCC 14. --- .github/workflows/build_cc_target.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_cc_target.yml b/.github/workflows/build_cc_target.yml index a44f3e70c3..4b78c6536f 100644 --- a/.github/workflows/build_cc_target.yml +++ b/.github/workflows/build_cc_target.yml @@ -28,14 +28,14 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - gcc: ['13.2.Rel1', '12.2.Rel1', '11.3.Rel1', '10.3-2021.10', '9-2020-q2', '8-2019-q3'] + gcc: ['14.2.Rel1', '13.2.Rel1', '12.2.Rel1', '11.3.Rel1', '10.3-2021.10', '9-2020-q2', '8-2019-q3'] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: go-version: 'stable' - - uses: carlosperate/arm-none-eabi-gcc-action@v1.8.1 + - uses: carlosperate/arm-none-eabi-gcc-action@v1.10.1 with: release: ${{ matrix.gcc }} - name: Install newt From ccfc8bff3ee59f97ad9da85e42af431348dce2a2 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 5 Aug 2025 16:34:59 +0200 Subject: [PATCH 1300/1333] nimble/host: Fix typo in ble_l2cap_sig_rx_reject Transaction ID was used instead of procedure opcode which resulted in not calling application callback on second and subsequent rejection. --- nimble/host/src/ble_l2cap_sig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index f360ad708b..8a2d1922c3 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -1842,7 +1842,7 @@ ble_l2cap_sig_rx_reject(uint16_t conn_handle, return 0; } - switch (proc->id) { + switch (proc->op) { #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 case BLE_L2CAP_SIG_PROC_OP_CONNECT: ble_l2cap_sig_coc_connect_cb(proc, BLE_HS_EREJECT); From 68261e708075704dca84219409ed4cab631faede Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 6 Aug 2025 10:46:56 +0200 Subject: [PATCH 1301/1333] nimble/host: Fix switch-case coding style in L2CAP signaling cases were incorrectly indented. --- nimble/host/src/ble_l2cap_sig.c | 44 ++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index 8a2d1922c3..6e8960e92b 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -1844,12 +1844,12 @@ ble_l2cap_sig_rx_reject(uint16_t conn_handle, switch (proc->op) { #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 - case BLE_L2CAP_SIG_PROC_OP_CONNECT: - ble_l2cap_sig_coc_connect_cb(proc, BLE_HS_EREJECT); - break; + case BLE_L2CAP_SIG_PROC_OP_CONNECT: + ble_l2cap_sig_coc_connect_cb(proc, BLE_HS_EREJECT); + break; #endif - default: - break; + default: + break; } ble_l2cap_sig_proc_free(proc); @@ -1986,23 +1986,23 @@ ble_l2cap_sig_conn_broken(uint16_t conn_handle, int reason) /* Report a failure for each timed out procedure. */ while ((proc = STAILQ_FIRST(&ble_l2cap_sig_procs)) != NULL) { switch(proc->op) { - case BLE_L2CAP_SIG_PROC_OP_UPDATE: - ble_l2cap_sig_update_call_cb(proc, reason); - break; + case BLE_L2CAP_SIG_PROC_OP_UPDATE: + ble_l2cap_sig_update_call_cb(proc, reason); + break; #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 - case BLE_L2CAP_SIG_PROC_OP_CONNECT: - ble_l2cap_sig_coc_connect_cb(proc, reason); + case BLE_L2CAP_SIG_PROC_OP_CONNECT: + ble_l2cap_sig_coc_connect_cb(proc, reason); break; - case BLE_L2CAP_SIG_PROC_OP_DISCONNECT: - ble_l2cap_sig_coc_disconnect_cb(proc, reason); + case BLE_L2CAP_SIG_PROC_OP_DISCONNECT: + ble_l2cap_sig_coc_disconnect_cb(proc, reason); break; #if MYNEWT_VAL(BLE_L2CAP_ENHANCED_COC) - case BLE_L2CAP_SIG_PROC_OP_RECONFIG: - ble_l2cap_sig_coc_reconfig_cb(proc, reason); + case BLE_L2CAP_SIG_PROC_OP_RECONFIG: + ble_l2cap_sig_coc_reconfig_cb(proc, reason); break; #endif #endif - } + } STAILQ_REMOVE_HEAD(&ble_l2cap_sig_procs, next); ble_l2cap_sig_proc_free(proc); @@ -2033,15 +2033,15 @@ ble_l2cap_sig_timer(void) while ((proc = STAILQ_FIRST(&temp_list)) != NULL) { STATS_INC(ble_l2cap_stats, proc_timeout); switch(proc->op) { - case BLE_L2CAP_SIG_PROC_OP_UPDATE: - ble_l2cap_sig_update_call_cb(proc, BLE_HS_ETIMEOUT); - break; + case BLE_L2CAP_SIG_PROC_OP_UPDATE: + ble_l2cap_sig_update_call_cb(proc, BLE_HS_ETIMEOUT); + break; #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 - case BLE_L2CAP_SIG_PROC_OP_CONNECT: - ble_l2cap_sig_coc_connect_cb(proc, BLE_HS_ETIMEOUT); + case BLE_L2CAP_SIG_PROC_OP_CONNECT: + ble_l2cap_sig_coc_connect_cb(proc, BLE_HS_ETIMEOUT); break; - case BLE_L2CAP_SIG_PROC_OP_DISCONNECT: - ble_l2cap_sig_coc_disconnect_cb(proc, BLE_HS_ETIMEOUT); + case BLE_L2CAP_SIG_PROC_OP_DISCONNECT: + ble_l2cap_sig_coc_disconnect_cb(proc, BLE_HS_ETIMEOUT); break; #endif } From 53f81096b6462f18e044c0188e1f934d89270f9e Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 6 Aug 2025 15:54:26 +0200 Subject: [PATCH 1302/1333] nimble/l2cap: Fix cleaning up pending procedures on disconnect Procedures needs to be removed based on diconnected connection handle and not all of them. Otherwsie this could lead to droping pending procedure for other connection. Also ble_l2cap_sig_procs list could be corrupted since it is being modified without host lock held. --- nimble/host/src/ble_l2cap_sig.c | 48 ++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index 6e8960e92b..0a3591cd45 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -1983,31 +1983,37 @@ ble_l2cap_sig_conn_broken(uint16_t conn_handle, int reason) { struct ble_l2cap_sig_proc *proc; - /* Report a failure for each timed out procedure. */ - while ((proc = STAILQ_FIRST(&ble_l2cap_sig_procs)) != NULL) { - switch(proc->op) { - case BLE_L2CAP_SIG_PROC_OP_UPDATE: - ble_l2cap_sig_update_call_cb(proc, reason); - break; + /* If there were any pending procedure, indicate to the application that it + * did not complete. + */ + proc = ble_l2cap_sig_proc_extract(conn_handle, BLE_L2CAP_SIG_PROC_OP_UPDATE, 0); + if (proc != NULL) { + ble_l2cap_sig_update_call_cb(proc, reason); + ble_l2cap_sig_proc_free(proc); + } + #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 - case BLE_L2CAP_SIG_PROC_OP_CONNECT: - ble_l2cap_sig_coc_connect_cb(proc, reason); - break; - case BLE_L2CAP_SIG_PROC_OP_DISCONNECT: - ble_l2cap_sig_coc_disconnect_cb(proc, reason); - break; -#if MYNEWT_VAL(BLE_L2CAP_ENHANCED_COC) - case BLE_L2CAP_SIG_PROC_OP_RECONFIG: - ble_l2cap_sig_coc_reconfig_cb(proc, reason); - break; -#endif -#endif - } + proc = ble_l2cap_sig_proc_extract(conn_handle, BLE_L2CAP_SIG_PROC_OP_CONNECT, 0); + if (proc != NULL) { + ble_l2cap_sig_coc_connect_cb(proc, reason); + ble_l2cap_sig_proc_free(proc); + } - STAILQ_REMOVE_HEAD(&ble_l2cap_sig_procs, next); - ble_l2cap_sig_proc_free(proc); + proc = ble_l2cap_sig_proc_extract(conn_handle, + BLE_L2CAP_SIG_PROC_OP_DISCONNECT, 0); + if (proc != NULL) { + ble_l2cap_sig_coc_disconnect_cb(proc, reason); + ble_l2cap_sig_proc_free(proc); } +#if MYNEWT_VAL(BLE_L2CAP_ENHANCED_COC) + proc = ble_l2cap_sig_proc_extract(conn_handle, BLE_L2CAP_SIG_PROC_OP_RECONFIG, 0); + if (proc != NULL) { + ble_l2cap_sig_coc_reconfig_cb(proc, reason); + ble_l2cap_sig_proc_free(proc); + } +#endif +#endif } /** From a22602c47a3aa50b5b00d2b2b30aa8345c3aaea3 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Fri, 27 Jun 2025 16:16:46 +0200 Subject: [PATCH 1303/1333] nimble/host: Add method for retrieving configuration values of CCCD This metod allows reading configuration flags of Client Characteristic Configuration Descriptor for specified characteristic. --- nimble/host/include/host/ble_gatt.h | 31 +++++++++++++++++++++++++++++ nimble/host/src/ble_gatts.c | 27 +++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/nimble/host/include/host/ble_gatt.h b/nimble/host/include/host/ble_gatt.h index 229d99dda3..aebfc7ef3d 100644 --- a/nimble/host/include/host/ble_gatt.h +++ b/nimble/host/include/host/ble_gatt.h @@ -185,6 +185,19 @@ struct ble_hs_cfg; /** @} */ +/** + * @defgroup ble_gatts_clt_cfg Client Characteristic Configuration Descriptor (CCCD) Flags Types + * @{ + */ + +/** GATT Client Charactaristic Configuration Flag: Notify. */ +#define BLE_GATT_CCCD_NOTIFY 0x01 + +/** GATT Client Charactaristic Configuration Flag: Indicate. */ +#define BLE_GATT_CCCD_INDICATE 0x02 + +/** @} */ + /*** @client. */ /** Represents a GATT error. */ struct ble_gatt_error { @@ -1214,6 +1227,24 @@ int ble_gatts_start(void); */ int ble_gatts_peer_cl_sup_feat_get(uint16_t conn_handle, uint8_t *out_supported_feat, uint8_t len); +/** + * Reads configuration values from Client Characteristic Configuration + * Descriptor for specified characteristic. + * + * @param conn_handle Connection handle identifying the connection + * to which CCC instance is related. + * @param chr_val_handle The value handle of characteristic. + * @param cccd_value Configuration value of CCC. + * + * @return 0 on success; + * BLE_HS_ENOTCONN if no matching connection + * was found + * BLE_HS_ENOENT if descriptor could not be found. + * + */ +int ble_gatts_read_cccd(uint16_t conn_handle, uint16_t chr_val_handle, + uint8_t *cccd_value); + #ifdef __cplusplus } #endif diff --git a/nimble/host/src/ble_gatts.c b/nimble/host/src/ble_gatts.c index ee6a8a3c65..6c3ae19de9 100644 --- a/nimble/host/src/ble_gatts.c +++ b/nimble/host/src/ble_gatts.c @@ -737,6 +737,33 @@ ble_gatts_clt_cfg_access_locked(struct ble_hs_conn *conn, uint16_t attr_handle, return 0; } +int +ble_gatts_read_cccd(uint16_t conn_handle, uint16_t chr_val_handle, uint8_t *cccd_value) +{ + struct ble_gatts_clt_cfg *clt_cfg; + struct ble_hs_conn *conn; + + ble_hs_lock(); + + conn = ble_hs_conn_find(conn_handle); + if (conn == NULL) { + ble_hs_unlock(); + return BLE_HS_ENOTCONN; + } + + clt_cfg = ble_gatts_clt_cfg_find(conn->bhc_gatt_svr.clt_cfgs, chr_val_handle); + if (clt_cfg == NULL) { + ble_hs_unlock(); + return BLE_HS_ENOENT; + } + + *cccd_value = clt_cfg->flags & ~BLE_GATTS_CLT_CFG_F_RESERVED; + + ble_hs_unlock(); + + return 0; +} + int ble_gatts_clt_cfg_access(uint16_t conn_handle, uint16_t attr_handle, uint8_t op, uint16_t offset, struct os_mbuf **om, From 26254691863b90aeec0947c5ff238ae4fb6b2aa9 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 7 Aug 2025 14:04:32 +0200 Subject: [PATCH 1304/1333] host/services/bas: some minor fixes - Internal battery level can be `static` - s/tabs/spaces - Initialize battery level to 0 when initializing the service Signed-off-by: Gerard Marull-Paretas --- nimble/host/services/bas/src/ble_svc_bas.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/nimble/host/services/bas/src/ble_svc_bas.c b/nimble/host/services/bas/src/ble_svc_bas.c index 631519cf9d..b49eb862e2 100644 --- a/nimble/host/services/bas/src/ble_svc_bas.c +++ b/nimble/host/services/bas/src/ble_svc_bas.c @@ -32,7 +32,7 @@ static uint16_t ble_svc_bas_battery_handle; #endif /* Battery level */ -uint8_t ble_svc_bas_battery_level; +static uint8_t ble_svc_bas_battery_level; /* Access function */ static int @@ -98,9 +98,9 @@ ble_svc_bas_access(uint16_t conn_handle, uint16_t attr_handle, int ble_svc_bas_battery_level_set(uint8_t level) { if (level > 100) - level = 100; + level = 100; if (ble_svc_bas_battery_level != level) { - ble_svc_bas_battery_level = level; + ble_svc_bas_battery_level = level; #if MYNEWT_VAL(BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE) > 0 ble_gatts_chr_updated(ble_svc_bas_battery_handle); #endif @@ -119,6 +119,8 @@ ble_svc_bas_init(void) /* Ensure this function only gets called by sysinit. */ SYSINIT_ASSERT_ACTIVE(); + ble_svc_bas_battery_level = 0; + rc = ble_gatts_count_cfg(ble_svc_bas_defs); SYSINIT_PANIC_ASSERT(rc == 0); From 53c2b4bd6960fbf2c42a357831436075a4e854f7 Mon Sep 17 00:00:00 2001 From: Szymon Czapracki Date: Wed, 9 Jul 2025 13:27:12 +0200 Subject: [PATCH 1305/1333] nimble/btp: Implement missing BAP layer commands & events Bring BAP commands and events up to date with their corresponding counterparts in Auto-PTS. Bring file structure up to coding standards. --- apps/bttester/src/btp/btp_bap.h | 242 +++++++++++++++++++++++++++----- 1 file changed, 208 insertions(+), 34 deletions(-) diff --git a/apps/bttester/src/btp/btp_bap.h b/apps/bttester/src/btp/btp_bap.h index 804c9d4c87..ea117ac4a5 100644 --- a/apps/bttester/src/btp/btp_bap.h +++ b/apps/bttester/src/btp/btp_bap.h @@ -29,7 +29,7 @@ /* BAP Service */ /* commands */ -#define BTP_BAP_READ_SUPPORTED_COMMANDS 0x01 +#define BTP_BAP_READ_SUPPORTED_COMMANDS 0x01 struct btp_bap_read_supported_commands_rp { uint8_t data[0]; } __packed; @@ -58,70 +58,244 @@ struct bap_broadcast_source_setup_rp { uint8_t broadcast_id[3]; } __packed; -#define BTP_BAP_BROADCAST_SOURCE_RELEASE 0x05 +#define BTP_BAP_BROADCAST_SOURCE_RELEASE 0x05 struct bap_bap_broadcast_source_release_cmd { uint8_t broadcast_id[3]; } __packed; -#define BTP_BAP_BROADCAST_ADV_START 0x06 +#define BTP_BAP_BROADCAST_ADV_START 0x06 struct bap_bap_broadcast_adv_start_cmd { uint8_t broadcast_id[3]; } __packed; -#define BTP_BAP_BROADCAST_ADV_STOP 0x07 +#define BTP_BAP_BROADCAST_ADV_STOP 0x07 struct bap_bap_broadcast_adv_stop_cmd { uint8_t broadcast_id[3]; } __packed; -#define BTP_BAP_BROADCAST_SOURCE_START 0x08 +#define BTP_BAP_BROADCAST_SOURCE_START 0x08 struct bap_bap_broadcast_source_start_cmd { uint8_t broadcast_id[3]; } __packed; -#define BTP_BAP_BROADCAST_SOURCE_STOP 0x09 +#define BTP_BAP_BROADCAST_SOURCE_STOP 0x09 struct bap_bap_broadcast_source_stop_cmd { uint8_t broadcast_id[3]; } __packed; -#define BTP_BAP_BROADCAST_SINK_SETUP 0x0a +#define BTP_BAP_BROADCAST_SINK_SETUP 0x0a +struct btp_bap_broadcast_sink_setup_cmd { +} __packed; + +#define BTP_BAP_BROADCAST_SINK_RELEASE 0x0b +struct btp_bap_broadcast_sink_release_cmd { +} __packed; + +#define BTP_BAP_BROADCAST_SCAN_START 0x0c +struct btp_bap_broadcast_scan_start_cmd { +} __packed; + +#define BTP_BAP_BROADCAST_SCAN_STOP 0x0d +struct btp_bap_broadcast_scan_stop_cmd { +} __packed; -#define BTP_BAP_BROADCAST_SINK_STOP 0x0f +#define BTP_BAP_BROADCAST_SINK_SYNC 0x0e +struct btp_bap_broadcast_sink_sync_cmd { + ble_addr_t addr; + uint8_t broadcast_id[3]; + uint8_t advertiser_sid; + uint16_t skip; + uint16_t sync_timeout; + uint8_t past_avail; + uint8_t src_id; +} __packed; + +#define BTP_BAP_BROADCAST_SINK_STOP 0x0f struct btp_bap_broadcast_sink_stop_cmd { ble_addr_t address; uint8_t broadcast_id[3]; } __packed; -#define BTP_BAP_SET_BROADCAST_CODE 0x17 +#define BTP_BAP_BROADCAST_SINK_BIS_SYNC 0x10 +struct btp_bap_broadcast_sink_bis_sync_cmd { + ble_addr_t address; + uint8_t broadcast_id[3]; + uint32_t requested_bis_sync; +} __packed; + +#define BTP_BAP_DISCOVER_SCAN_DELEGATOR 0x11 +struct btp_bap_discover_scan_delegator_cmd { + ble_addr_t address; +} __packed; + +#define BTP_BAP_BROADCAST_ASSISTANT_SCAN_START 0x12 +struct btp_bap_broadcast_assistant_scan_start_cmd { + ble_addr_t address; +} __packed; + +#define BTP_BAP_BROADCAST_ASSISTANT_SCAN_STOP 0x13 +struct btp_bap_broadcast_assistant_scan_stop_cmd { + ble_addr_t address; +} __packed; + +#define BTP_BAP_ADD_BROADCAST_SRC 0x14 +struct btp_bap_add_broadcast_src_cmd { + ble_addr_t address; + ble_addr_t broadcaster_address; + uint8_t advertiser_sid; + uint8_t broadcast_id[3]; + uint8_t padv_sync; + uint16_t padv_interval; + uint8_t num_subgroups; + uint8_t subgroups[0]; +} __packed; + +#define BTP_BAP_REMOVE_BROADCAST_SRC 0x15 +struct btp_bap_remove_broadcast_src_cmd { + ble_addr_t address; + uint8_t source_id; +} __packed; + +#define BTP_BAP_MODIFY_BROADCAST_SRC 0x16 +struct btp_bap_modify_broadcast_src_cmd { + ble_addr_t address; + uint8_t source_id; + uint8_t padv_sync; + uint16_t padv_interval; + uint8_t num_subgroups; + uint8_t subgroups[0]; +} __packed; + +#define BTP_BAP_SET_BROADCAST_CODE 0x17 struct btp_bap_set_broadcast_code_cmd { ble_addr_t addr; uint8_t source_id; uint8_t broadcast_code[16]; } __packed; -#define BTP_BAP_BROADCAST_SINK_RELEASE 0x0b -#define BTP_BAP_BROADCAST_SCAN_START 0x0c -#define BTP_BAP_BROADCAST_SCAN_STOP 0x0d -#define BTP_BAP_BROADCAST_SINK_SYNC 0x0e -#define BTP_BAP_BROADCAST_SINK_BIS_SYNC 0x10 -#define BTP_BAP_DISCOVER_SCAN_DELEGATOR 0x11 -#define BTP_BAP_BROADCAST_ASSISTANT_SCAN_START 0x12 -#define BTP_BAP_BROADCAST_ASSISTANT_SCAN_STOP 0x13 -#define BTP_BAP_ADD_BROADCAST_SRC 0x14 -#define BTP_BAP_REMOVE_BROADCAST_SRC 0x15 -#define BTP_BAP_MODIFY_BROADCAST_SRC 0x16 -#define BTP_BAP_SET_BROADCAST_CODE 0x17 -#define BTP_BAP_SEND_PAST 0x18 - -#define BTP_BAP_EV_DISCOVERY_COMPLETED 0x80 -#define BTP_BAP_EV_CODEC_CAP_FOUND 0x81 -#define BTP_BAP_EV_ASE_FOUND 0x82 -#define BTP_BAP_EV_STREAM_RECEIVED 0x83 -#define BTP_BAP_EV_BAA_FOUND 0x84 -#define BTP_BAP_EV_BIS_FOUND 0x85 -#define BTP_BAP_EV_BIS_SYNCED 0x86 -#define BTP_BAP_EV_BIS_STREAM_RECEIVED 0x87 -#define BTP_BAP_EV_SCAN_DELEGATOR_FOUND 0x88 -#define BTP_BAP_EV_BROADCAST_RECEIVE_STATE 0x89 -#define BTP_BAP_EV_PA_SYNC_REQ 0x8a +#define BTP_BAP_SEND_PAST 0x18 +struct btp_bap_send_past_cmd { + ble_addr_t address; + uint8_t src_id; +} __packed; + +#define BTP_BAP_BROADCAST_SOURCE_SETUP_V2 0x19 +struct btp_bap_broadcast_source_setup_v2_cmd { + uint8_t broadcast_id[3]; + uint8_t streams_per_subgroup; + uint8_t subgroups; + uint8_t sdu_interval[3]; + uint8_t framing; + uint16_t max_sdu; + uint8_t retransmission_num; + uint16_t max_transport_latency; + uint8_t presentation_delay[3]; + uint8_t coding_format; + uint16_t vid; + uint16_t cid; + uint8_t cc_ltvs_len; + uint8_t cc_ltvs[]; +} __packed; +struct btp_bap_broadcast_source_setup_v2_rp { + uint32_t gap_settings; +} __packed; + +#define BTP_BAP_EV_DISCOVERY_COMPLETED 0x80 +struct btp_bap_discovery_completed_ev { + ble_addr_t address; + uint8_t status; +} __packed; + +#define BTP_BAP_EV_CODEC_CAP_FOUND 0x81 +struct btp_bap_codec_cap_found_ev { + ble_addr_t address; + uint8_t dir; + uint8_t coding_format; + uint16_t frequencies; + uint8_t frame_durations; + uint32_t octets_per_frame; + uint8_t channel_counts; +} __packed; + +#define BTP_BAP_EV_ASE_FOUND 0x82 +struct btp_bap_ase_found_ev { + ble_addr_t address; + uint8_t dir; + uint8_t ase_id; +} __packed; + +#define BTP_BAP_EV_STREAM_RECEIVED 0x83 +struct btp_bap_stream_received_ev { + ble_addr_t address; + uint8_t ase_id; + uint8_t data_len; + uint8_t data[]; +} __packed; + +#define BTP_BAP_EV_BAA_FOUND 0x84 +struct btp_bap_baa_found_ev { + ble_addr_t address; + uint8_t broadcast_id[3]; + uint8_t advertiser_sid; + uint16_t padv_interval; +} __packed; + +#define BTP_BAP_EV_BIS_FOUND 0x85 +struct btp_bap_bis_found_ev { + ble_addr_t address; + uint8_t broadcast_id[3]; + uint8_t presentation_delay[3]; + uint8_t subgroup_id; + uint8_t bis_id; + uint8_t coding_format; + uint16_t vid; + uint16_t cid; + uint8_t cc_ltvs_len; + uint8_t cc_ltvs[]; +} __packed; + +#define BTP_BAP_EV_BIS_SYNCED 0x86 +struct btp_bap_bis_synced_ev { + ble_addr_t address; + uint8_t broadcast_id[3]; + uint8_t bis_id; +} __packed; + +#define BTP_BAP_EV_BIS_STREAM_RECEIVED 0x87 +struct btp_bap_bis_stream_received_ev { + ble_addr_t address; + uint8_t broadcast_id[3]; + uint8_t bis_id; + uint8_t data_len; + uint8_t data[]; +} __packed; + +#define BTP_BAP_EV_SCAN_DELEGATOR_FOUND 0x88 +struct btp_bap_scan_delegator_found_ev { + ble_addr_t address; +} __packed; + +#define BTP_BAP_EV_BROADCAST_RECEIVE_STATE 0x89 +struct btp_bap_broadcast_receive_state_ev { + ble_addr_t address; + uint8_t source_id; + ble_addr_t broadcaster_address; + uint8_t advertiser_sid; + uint8_t broadcast_id[3]; + uint8_t pa_sync_state; + uint8_t big_encryption; + uint8_t num_subgroups; + uint8_t subgroups[0]; +} __packed; + +#define BTP_BAP_EV_PA_SYNC_REQ 0x8a +struct btp_bap_pa_sync_req_ev { + ble_addr_t address; + uint8_t source_id; + uint8_t advertiser_sid; + uint8_t broadcast_id[3]; + uint8_t past_avail; + uint16_t pa_interval; +} __packed; #endif /* H_BTP_BAP_ */ From ae97cc421d70ebf67076b1acb0232916b9a9b03b Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 13 Aug 2025 16:18:32 +0200 Subject: [PATCH 1306/1333] apps/bttester: Set default L2CAP MTU value to match PTS This value is currently used as default by PTS. --- apps/bttester/syscfg.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bttester/syscfg.yml b/apps/bttester/syscfg.yml index 18fa8afb0f..c66bcdbd27 100644 --- a/apps/bttester/syscfg.yml +++ b/apps/bttester/syscfg.yml @@ -87,7 +87,7 @@ syscfg.defs: BTTESTER_L2CAP_COC_MTU: description: Maximum MTU size the application can handle - value: 230 + value: 260 BTTESTER_NRPA_TIMEOUT: description: NRPA rotation timeout in seconds From 9d8a37e20ce3f03a6cd29cab2f743b367b98ba6e Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 13 Aug 2025 16:19:39 +0200 Subject: [PATCH 1307/1333] apps/bttester: Improve BTP logging Mark BTP trace logs as BTP. --- apps/bttester/src/bttester.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/apps/bttester/src/bttester.c b/apps/bttester/src/bttester.c index 8bbca9f2e9..ad8a827d30 100644 --- a/apps/bttester/src/bttester.c +++ b/apps/bttester/src/bttester.c @@ -148,10 +148,8 @@ cmd_handler(struct os_event *ev) len = le16toh(cmd->hdr.len); if (MYNEWT_VAL(BTTESTER_BTP_LOG)) { - console_printf("[DBG] received %d bytes: %s\n", - sizeof(cmd->hdr) + len, - string_from_bytes(cmd->data, - sizeof(cmd->hdr) + len)); + console_printf("[DBG] BTP received %d bytes: %s\n", sizeof(cmd->hdr) + len, + string_from_bytes(cmd->data, sizeof(cmd->hdr) + len)); } btp = find_btp_handler(cmd->hdr.service, cmd->hdr.opcode); @@ -293,11 +291,11 @@ tester_send_with_index(uint8_t service, uint8_t opcode, uint8_t index, } if (MYNEWT_VAL(BTTESTER_BTP_LOG)) { - console_printf("[DBG] send %d bytes hdr: %s\n", sizeof(msg), - string_from_bytes((char *) &msg, sizeof(msg))); + console_printf("[DBG] BTP send %d bytes hdr: %s\n", sizeof(msg), + string_from_bytes((char *)&msg, sizeof(msg))); if (data && len) { - console_printf("[DBG] send %d bytes data: %s\n", len, - string_from_bytes((char *) data, len)); + console_printf("[DBG] BTP send %d bytes data: %s\n", len, + string_from_bytes((char *)data, len)); } } } From 318efbfc2cd9f26131b6319ff2754f9416e805a2 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 13 Aug 2025 16:20:26 +0200 Subject: [PATCH 1308/1333] apps/bttester: Add support for queueing L2CAP COC data Stalled return value is handled internally by bttester and thus AutoPTS may send another data before channel is unstalled. This results in BTP error. Add simple support for queueing (just one per channel currently) data. --- apps/bttester/src/btp_l2cap.c | 39 ++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/apps/bttester/src/btp_l2cap.c b/apps/bttester/src/btp_l2cap.c index 03099b7784..e11c54de3c 100644 --- a/apps/bttester/src/btp_l2cap.c +++ b/apps/bttester/src/btp_l2cap.c @@ -54,6 +54,7 @@ static struct channel { uint8_t chan_id; /* Internal number that identifies L2CAP channel. */ uint8_t state; struct ble_l2cap_chan *chan; + struct os_mbuf *queued_sdu_tx; } channels[CHANNELS]; static uint8_t @@ -102,6 +103,16 @@ get_channel(uint8_t chan_id) return &channels[chan_id]; } +static void +free_channel(struct channel *chan) +{ + if (chan->queued_sdu_tx) { + os_mbuf_free_chain(chan->queued_sdu_tx); + } + + memset(chan, 0, sizeof(*chan)); +} + static void tester_l2cap_coc_recv(struct ble_l2cap_chan *chan, struct os_mbuf *sdu) { @@ -207,11 +218,11 @@ disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan, channel = find_channel(chan); assert(channel != NULL); - channel->state = 0; - channel->chan = chan; ev.chan_id = channel->chan_id; ev.psm = chan_info->psm; + free_channel(channel); + if (!ble_gap_conn_find(conn_handle, &desc)) { memcpy(&ev.address, &desc.peer_ota_addr, sizeof(ev.address)); } @@ -244,6 +255,8 @@ tester_l2cap_event(struct ble_l2cap_event *event, void *arg) { struct ble_l2cap_chan_info chan_info; struct ble_gap_conn_desc conn; + struct channel *chan; + int rc; switch (event->type) { case BLE_L2CAP_EVENT_COC_CONNECTED: @@ -336,6 +349,19 @@ tester_l2cap_event(struct ble_l2cap_event *event, void *arg) (uint32_t) event->tx_unstalled.chan, event->tx_unstalled.conn_handle, event->tx_unstalled.status); + + chan = find_channel(event->tx_unstalled.chan); + assert(chan != NULL); + + if (chan->queued_sdu_tx) { + rc = ble_l2cap_send(event->tx_unstalled.chan, chan->queued_sdu_tx); + if (rc != 0 && rc != BLE_HS_ESTALLED) { + os_mbuf_free_chain(chan->queued_sdu_tx); + } + + chan->queued_sdu_tx = NULL; + } + return 0; case BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED: if (ble_l2cap_get_chan_info(event->reconfigured.chan, @@ -527,7 +553,8 @@ send_data(const void *cmd, uint16_t cmd_len, /* FIXME: For now, fail if data length exceeds buffer length */ if (data_len > TESTER_COC_MTU) { - SYS_LOG_ERR("Data length exceeds buffer length"); + SYS_LOG_ERR("Data length exceeds buffer length (%u > %u)", data_len, + TESTER_COC_MTU); return BTP_STATUS_FAILED; } @@ -546,6 +573,12 @@ send_data(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } + /* autopts may queue more SDUs, for now support at least one queued*/ + if (rc == BLE_HS_EBUSY && chan->queued_sdu_tx == NULL) { + chan->queued_sdu_tx = sdu_tx; + return BTP_STATUS_SUCCESS; + } + fail: SYS_LOG_ERR("Unable to send data: %d", rc); os_mbuf_free_chain(sdu_tx); From ecc1a6d175c56d2b0f0ac8700651c92ef4571323 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 6 Aug 2025 15:45:42 +0200 Subject: [PATCH 1309/1333] nimble/host: Remove dead code from ble_l2cap_sig_coc_disconnect_cb This is static function and all callers pass valid proc so no need for runtime check (make it assert). --- nimble/host/src/ble_l2cap_sig.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index 0a3591cd45..2e356d2e43 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -1666,25 +1666,15 @@ static void ble_l2cap_sig_coc_disconnect_cb(struct ble_l2cap_sig_proc *proc, int status) { struct ble_l2cap_chan *chan; - struct ble_l2cap_event event; struct ble_hs_conn *conn; - if (!proc) { - return; - } + assert(proc); - memset(&event, 0, sizeof(event)); chan = proc->disconnect.chan; - if (!chan) { return; } - if (!chan->cb) { - goto done; - } - -done: ble_hs_lock(); conn = ble_hs_conn_find_assert(chan->conn_handle); if (conn) { From 94ee7f6ea3aa58d78071d08fd9f37017eb52fba6 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 6 Aug 2025 12:45:51 +0200 Subject: [PATCH 1310/1333] nimble: Use BLE_NPL_TIME_FOREVER for ble_npl_mutex_pend timeout If no timeout is required we should use BLE_NPL_TIME_FOREVER when locking. --- nimble/host/src/ble_gap.c | 2 +- nimble/host/src/ble_hs.c | 2 +- nimble/transport/src/monitor.c | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c index 80ab840c8b..4928454d4a 100644 --- a/nimble/host/src/ble_gap.c +++ b/nimble/host/src/ble_gap.c @@ -6965,7 +6965,7 @@ ble_gap_preempt_done(void) disc_preempted = 0; /* Protects slaves from accessing by multiple threads */ - ble_npl_mutex_pend(&preempt_done_mutex, 0xFFFFFFFF); + ble_npl_mutex_pend(&preempt_done_mutex, BLE_NPL_TIME_FOREVER); memset(slaves, 0, sizeof(slaves)); ble_hs_lock(); diff --git a/nimble/host/src/ble_hs.c b/nimble/host/src/ble_hs.c index 70a4aa6c9d..42c83c9b72 100644 --- a/nimble/host/src/ble_hs.c +++ b/nimble/host/src/ble_hs.c @@ -164,7 +164,7 @@ ble_hs_lock_nested(void) } #endif - rc = ble_npl_mutex_pend(&ble_hs_mutex, 0xffffffff); + rc = ble_npl_mutex_pend(&ble_hs_mutex, BLE_NPL_TIME_FOREVER); BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED); } diff --git a/nimble/transport/src/monitor.c b/nimble/transport/src/monitor.c index c67b18df21..66382c0736 100644 --- a/nimble/transport/src/monitor.c +++ b/nimble/transport/src/monitor.c @@ -281,7 +281,7 @@ static FILE *btmon = (FILE *) &(struct File) { static void drops_tmp_cb(struct ble_npl_event *ev) { - ble_npl_mutex_pend(&lock, OS_TIMEOUT_NEVER); + ble_npl_mutex_pend(&lock, BLE_NPL_TIME_FOREVER); /* * There's no "nop" in btsnoop protocol so we just send empty system note @@ -352,7 +352,7 @@ ble_monitor_init(void) int ble_monitor_send(uint16_t opcode, const void *data, size_t len) { - ble_npl_mutex_pend(&lock, OS_TIMEOUT_NEVER); + ble_npl_mutex_pend(&lock, BLE_NPL_TIME_FOREVER); monitor_write_header(opcode, len); monitor_write(data, len); @@ -374,7 +374,7 @@ ble_monitor_send_om(uint16_t opcode, const struct os_mbuf *om) om_tmp = SLIST_NEXT(om_tmp, om_next); } - ble_npl_mutex_pend(&lock, OS_TIMEOUT_NEVER); + ble_npl_mutex_pend(&lock, BLE_NPL_TIME_FOREVER); monitor_write_header(opcode, length); @@ -436,7 +436,7 @@ ble_monitor_log(int level, const char *fmt, ...) ulog.ident_len = sizeof(id); - ble_npl_mutex_pend(&lock, OS_TIMEOUT_NEVER); + ble_npl_mutex_pend(&lock, BLE_NPL_TIME_FOREVER); monitor_write_header(BLE_MONITOR_OPCODE_USER_LOGGING, sizeof(ulog) + sizeof(id) + len + 1); From 35087de0563446b11faf0918eb49637f308e1e16 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 6 Aug 2025 11:27:45 +0200 Subject: [PATCH 1311/1333] porting/linux: Fix ble_npl_mutex_pend failing pthread_mutex_timedlock fails if invalid struct timespec values are provided. --- porting/npl/linux/src/os_mutex.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/porting/npl/linux/src/os_mutex.c b/porting/npl/linux/src/os_mutex.c index 86cad965da..3d3a72ef12 100644 --- a/porting/npl/linux/src/os_mutex.c +++ b/porting/npl/linux/src/os_mutex.c @@ -71,6 +71,14 @@ ble_npl_mutex_pend(struct ble_npl_mutex *mu, uint32_t timeout) mu->wait.tv_sec += timeout / 1000; mu->wait.tv_nsec += (timeout % 1000) * 1000000; + /* struct timespec tv_nsec holds nanosecond and allowed range is + * 0 - 999999999, otherwise pthread_mutex_timedlock returns EINVAL + */ + if (mu->wait.tv_nsec >= 1000000000) { + mu->wait.tv_sec += mu->wait.tv_nsec / 1000000000; + mu->wait.tv_nsec = mu->wait.tv_nsec % 1000000000; + } + err = pthread_mutex_timedlock(&mu->lock, &mu->wait); if (err == ETIMEDOUT) { return BLE_NPL_TIMEOUT; From d5e471c5271dd15915f11dd3334f7bacd284633a Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 6 Aug 2025 11:30:52 +0200 Subject: [PATCH 1312/1333] porting/linux: Make BLE_NPL_TIME_FOREVER unsigned There is no point in using singed value for this since ble_npl_mutex_pend takes uint32 as timeout parameter. --- porting/npl/linux/include/nimble/nimble_npl_os.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porting/npl/linux/include/nimble/nimble_npl_os.h b/porting/npl/linux/include/nimble/nimble_npl_os.h index d8688d3e6d..1db56794a9 100644 --- a/porting/npl/linux/include/nimble/nimble_npl_os.h +++ b/porting/npl/linux/include/nimble/nimble_npl_os.h @@ -33,7 +33,7 @@ extern "C" { #define BLE_NPL_OS_ALIGNMENT (__WORDSIZE / 8) -#define BLE_NPL_TIME_FOREVER INT32_MAX +#define BLE_NPL_TIME_FOREVER UINT32_MAX struct ble_npl_eventq * ble_npl_eventq_dflt_get(void); void ble_npl_eventq_run(struct ble_npl_eventq *evq); From efa5688ef30c36fa87746f4aac3288eb72ec0af3 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 6 Aug 2025 11:47:35 +0200 Subject: [PATCH 1313/1333] porting/linux: Fix some coding style issues This code didn't follow coding style guidelines. --- .../npl/linux/include/nimble/nimble_npl_os.h | 8 ++-- .../linux/include/nimble/nimble_npl_os_log.h | 20 ++++---- porting/npl/linux/include/nimble/os_types.h | 45 +++++++++-------- porting/npl/linux/src/os_callout.c | 46 ++++++++++-------- porting/npl/linux/src/os_task.c | 48 +++++++++++-------- porting/npl/linux/src/os_time.c | 2 + 6 files changed, 91 insertions(+), 78 deletions(-) diff --git a/porting/npl/linux/include/nimble/nimble_npl_os.h b/porting/npl/linux/include/nimble/nimble_npl_os.h index 1db56794a9..0006f8b407 100644 --- a/porting/npl/linux/include/nimble/nimble_npl_os.h +++ b/porting/npl/linux/include/nimble/nimble_npl_os.h @@ -31,15 +31,15 @@ extern "C" { #endif -#define BLE_NPL_OS_ALIGNMENT (__WORDSIZE / 8) +#define BLE_NPL_OS_ALIGNMENT (__WORDSIZE / 8) -#define BLE_NPL_TIME_FOREVER UINT32_MAX +#define BLE_NPL_TIME_FOREVER UINT32_MAX -struct ble_npl_eventq * ble_npl_eventq_dflt_get(void); +struct ble_npl_eventq *ble_npl_eventq_dflt_get(void); void ble_npl_eventq_run(struct ble_npl_eventq *evq); #ifdef __cplusplus } #endif -#endif /* _NPL_H_ */ +#endif /* _NPL_H_ */ diff --git a/porting/npl/linux/include/nimble/nimble_npl_os_log.h b/porting/npl/linux/include/nimble/nimble_npl_os_log.h index 24315a21a7..2e359f878d 100644 --- a/porting/npl/linux/include/nimble/nimble_npl_os_log.h +++ b/porting/npl/linux/include/nimble/nimble_npl_os_log.h @@ -24,14 +24,14 @@ #include /* Example on how to use macro to generate module logging functions */ -#define BLE_NPL_LOG_IMPL(lvl) \ - static inline void _BLE_NPL_LOG_CAT(BLE_NPL_LOG_MODULE, \ - _BLE_NPL_LOG_CAT(_, lvl))(const char *fmt, ...)\ - { \ - va_list args; \ - va_start(args, fmt); \ - vprintf(fmt, args); \ - va_end(args); \ - } +#define BLE_NPL_LOG_IMPL(lvl) \ + static inline void _BLE_NPL_LOG_CAT( \ + BLE_NPL_LOG_MODULE, _BLE_NPL_LOG_CAT(_, lvl))(const char *fmt, ...) \ + { \ + va_list args; \ + va_start(args, fmt); \ + vprintf(fmt, args); \ + va_end(args); \ + } -#endif /* _NIMBLE_NPL_OS_LOG_H_ */ +#endif /* _NIMBLE_NPL_OS_LOG_H_ */ diff --git a/porting/npl/linux/include/nimble/os_types.h b/porting/npl/linux/include/nimble/os_types.h index aa24745f5f..fa92cd1821 100644 --- a/porting/npl/linux/include/nimble/os_types.h +++ b/porting/npl/linux/include/nimble/os_types.h @@ -32,50 +32,49 @@ typedef uint32_t ble_npl_time_t; typedef int32_t ble_npl_stime_t; -//typedef int os_sr_t; typedef int ble_npl_stack_t; - struct ble_npl_event { - uint8_t ev_queued; - ble_npl_event_fn *ev_cb; - void *ev_arg; + uint8_t ev_queued; + ble_npl_event_fn *ev_cb; + void *ev_arg; }; struct ble_npl_eventq { - void *q; + void *q; }; struct ble_npl_callout { - struct ble_npl_event c_ev; - struct ble_npl_eventq *c_evq; - uint32_t c_ticks; - timer_t c_timer; - bool c_active; + struct ble_npl_event c_ev; + struct ble_npl_eventq *c_evq; + uint32_t c_ticks; + timer_t c_timer; + bool c_active; }; struct ble_npl_mutex { - pthread_mutex_t lock; - pthread_mutexattr_t attr; - struct timespec wait; + pthread_mutex_t lock; + pthread_mutexattr_t attr; + struct timespec wait; }; struct ble_npl_sem { - sem_t lock; + sem_t lock; }; struct ble_npl_task { - pthread_t handle; - pthread_attr_t attr; - struct sched_param param; - const char* name; + pthread_t handle; + pthread_attr_t attr; + struct sched_param param; + const char *name; }; typedef void *(*ble_npl_task_func_t)(void *); -int ble_npl_task_init(struct ble_npl_task *t, const char *name, ble_npl_task_func_t func, - void *arg, uint8_t prio, ble_npl_time_t sanity_itvl, - ble_npl_stack_t *stack_bottom, uint16_t stack_size); +int ble_npl_task_init(struct ble_npl_task *t, const char *name, + ble_npl_task_func_t func, void *arg, uint8_t prio, + ble_npl_time_t sanity_itvl, + ble_npl_stack_t *stack_bottom, uint16_t stack_size); int ble_npl_task_remove(struct ble_npl_task *t); @@ -83,4 +82,4 @@ uint8_t ble_npl_task_count(void); void ble_npl_task_yield(void); -#endif // _NPL_OS_TYPES_H +#endif /* _NPL_OS_TYPES_H */ diff --git a/porting/npl/linux/src/os_callout.c b/porting/npl/linux/src/os_callout.c index 76c8b2eefd..90c190cefd 100644 --- a/porting/npl/linux/src/os_callout.c +++ b/porting/npl/linux/src/os_callout.c @@ -31,7 +31,9 @@ static void ble_npl_callout_timer_cb(union sigval sv) { struct ble_npl_callout *c = (struct ble_npl_callout *)sv.sival_ptr; + assert(c); + c->c_active = false; if (c->c_evq) { ble_npl_eventq_put(c->c_evq, &c->c_ev); @@ -40,12 +42,11 @@ ble_npl_callout_timer_cb(union sigval sv) } } -void ble_npl_callout_init(struct ble_npl_callout *c, - struct ble_npl_eventq *evq, - ble_npl_event_fn *ev_cb, - void *ev_arg) +void +ble_npl_callout_init(struct ble_npl_callout *c, struct ble_npl_eventq *evq, + ble_npl_event_fn *ev_cb, void *ev_arg) { - struct sigevent event; + struct sigevent event; /* Initialize the callout. */ memset(c, 0, sizeof(*c)); @@ -55,29 +56,32 @@ void ble_npl_callout_init(struct ble_npl_callout *c, c->c_active = false; event.sigev_notify = SIGEV_THREAD; - event.sigev_value.sival_ptr = c; // put callout obj in signal args + event.sigev_value.sival_ptr = c; // put callout obj in signal args event.sigev_notify_function = ble_npl_callout_timer_cb; event.sigev_notify_attributes = NULL; timer_create(CLOCK_REALTIME, &event, &c->c_timer); } -bool ble_npl_callout_is_active(struct ble_npl_callout *c) +bool +ble_npl_callout_is_active(struct ble_npl_callout *c) { - // TODO: seek native posix method to determine whether timer_t is active. - // TODO: fix bug where one-shot timer is still active after fired. + /* TODO: seek native posix method to determine whether timer_t is active. + * TODO: fix bug where one-shot timer is still active after fired. + */ return c->c_active; } -int ble_npl_callout_inited(struct ble_npl_callout *c) +int +ble_npl_callout_inited(struct ble_npl_callout *c) { return (c->c_timer != NULL); } -ble_npl_error_t ble_npl_callout_reset(struct ble_npl_callout *c, - ble_npl_time_t ticks) +ble_npl_error_t +ble_npl_callout_reset(struct ble_npl_callout *c, ble_npl_time_t ticks) { - struct itimerspec its; + struct itimerspec its; if (ticks < 0) { return BLE_NPL_EINVAL; @@ -90,7 +94,7 @@ ble_npl_error_t ble_npl_callout_reset(struct ble_npl_callout *c, c->c_ticks = ble_npl_time_get() + ticks; its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 0; // one shot + its.it_interval.tv_nsec = 0; // one shot its.it_value.tv_sec = (ticks / 1000); its.it_value.tv_nsec = (ticks % 1000) * 1000000; // expiration its.it_value.tv_nsec %= 1000000000; @@ -100,16 +104,17 @@ ble_npl_error_t ble_npl_callout_reset(struct ble_npl_callout *c, return BLE_NPL_OK; } -int ble_npl_callout_queued(struct ble_npl_callout *c) +int +ble_npl_callout_queued(struct ble_npl_callout *c) { struct itimerspec its; timer_gettime(c->c_timer, &its); - return ((its.it_value.tv_sec > 0) || - (its.it_value.tv_nsec > 0)); + return ((its.it_value.tv_sec > 0) || (its.it_value.tv_nsec > 0)); } -void ble_npl_callout_stop(struct ble_npl_callout *c) +void +ble_npl_callout_stop(struct ble_npl_callout *c) { if (!ble_npl_callout_inited(c)) { return; @@ -137,13 +142,12 @@ ble_npl_callout_set_arg(struct ble_npl_callout *co, void *arg) } uint32_t -ble_npl_callout_remaining_ticks(struct ble_npl_callout *co, - ble_npl_time_t now) +ble_npl_callout_remaining_ticks(struct ble_npl_callout *co, ble_npl_time_t now) { ble_npl_time_t rt; uint32_t exp; - struct itimerspec its; + timer_gettime(co->c_timer, &its); exp = its.it_value.tv_sec * 1000; diff --git a/porting/npl/linux/src/os_task.c b/porting/npl/linux/src/os_task.c index b03deb0661..c34507f150 100644 --- a/porting/npl/linux/src/os_task.c +++ b/porting/npl/linux/src/os_task.c @@ -34,23 +34,22 @@ extern "C" { * and sets the task as ready to run, and inserts it into the operating * system scheduler. * - * @param t The task to initialize - * @param name The name of the task to initialize - * @param func The task function to call - * @param arg The argument to pass to this task function - * @param prio The priority at which to run this task - * @param sanity_itvl The time at which this task should check in with the - * sanity task. OS_WAIT_FOREVER means never check in - * here. - * @param stack_bottom A pointer to the bottom of a task's stack - * @param stack_size The overall size of the task's stack. + * @param t The task to initialize + * @param name The name of the task to initialize + * @param func The task function to call + * @param arg The argument to pass to this task function + * @param prio The priority at which to run this task + * @param sanity_itvl The time at which this task should check in with the + * sanity task. OS_WAIT_FOREVER means never check in here. + * @param stack_bottom A pointer to the bottom of a task's stack + * @param stack_size The overall size of the task's stack. * * @return 0 on success, non-zero on failure. */ int ble_npl_task_init(struct ble_npl_task *t, const char *name, ble_npl_task_func_t func, - void *arg, uint8_t prio, ble_npl_time_t sanity_itvl, - ble_npl_stack_t *stack_bottom, uint16_t stack_size) + void *arg, uint8_t prio, ble_npl_time_t sanity_itvl, + ble_npl_stack_t *stack_bottom, uint16_t stack_size) { int err; if ((t == NULL) || (func == NULL)) { @@ -58,14 +57,21 @@ ble_npl_task_init(struct ble_npl_task *t, const char *name, ble_npl_task_func_t } err = pthread_attr_init(&t->attr); - if (err) return err; - err = pthread_attr_getschedparam (&t->attr, &t->param); - if (err) return err; + if (err) + return err; + + err = pthread_attr_getschedparam(&t->attr, &t->param); + if (err) + return err; + err = pthread_attr_setschedpolicy(&t->attr, SCHED_RR); - if (err) return err; + if (err) + return err; + t->param.sched_priority = prio; - err = pthread_attr_setschedparam (&t->attr, &t->param); - if (err) return err; + err = pthread_attr_setschedparam(&t->attr, &t->param); + if (err) + return err; t->name = name; err = pthread_create(&t->handle, &t->attr, func, arg); @@ -101,12 +107,14 @@ ble_npl_get_current_task_id(void) return (void *)pthread_self(); } -bool ble_npl_os_started(void) +bool +ble_npl_os_started(void) { return true; } -void ble_npl_task_yield(void) +void +ble_npl_task_yield(void) { sched_yield(); } diff --git a/porting/npl/linux/src/os_time.c b/porting/npl/linux/src/os_time.c index 4625159f2f..2af544e5f6 100644 --- a/porting/npl/linux/src/os_time.c +++ b/porting/npl/linux/src/os_time.c @@ -33,9 +33,11 @@ ble_npl_time_t ble_npl_time_get(void) { struct timespec now; + if (clock_gettime(CLOCK_MONOTONIC, &now)) { return 0; } + return now.tv_sec * 1000.0 + now.tv_nsec / 1000000.0; } From 438a70dde57e42cf8f67afd88a58f0a5ea33e0b3 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Wed, 6 Aug 2025 11:50:32 +0200 Subject: [PATCH 1314/1333] gitignore: Add linux port tests Those shall not be added to repository. --- .gitignore | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index bcc3a72bd1..66b3d75410 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ # Dummy NPL build *.o -/porting/examples/dummy/dummy -/porting/examples/linux/nimble-linux -/porting/examples/linux_blemesh/nimble-linux-blemesh +porting/examples/dummy/dummy +porting/examples/linux/nimble-linux +porting/examples/linux_blemesh/nimble-linux-blemesh +porting/npl/linux/test/.depend +porting/npl/linux/test/*.exe From d869f39783892efb9e4c21a35ce434e7b1834826 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 31 Jul 2025 17:24:54 +0200 Subject: [PATCH 1315/1333] nimble/host: Fix stopping host with pending connections ble_gap_reset_state() may stil require valid local(own) addresses. So ID and RPAs should be cleaned only after that. --- nimble/host/src/ble_hs_stop.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nimble/host/src/ble_hs_stop.c b/nimble/host/src/ble_hs_stop.c index 6d5c36d8fc..c0ff67e455 100644 --- a/nimble/host/src/ble_hs_stop.c +++ b/nimble/host/src/ble_hs_stop.c @@ -71,14 +71,14 @@ ble_hs_stop_done(int status) ble_hs_stop_hci_reset(); + /* Clear advertising, scanning and connection states. */ + ble_gap_reset_state(0); + /* After LL reset the controller loses its random address */ ble_hs_id_reset(); ble_hs_pvcy_reset(); - /* Clear advertising, scanning and connection states. */ - ble_gap_reset_state(0); - ble_hs_unlock(); SLIST_FOREACH(listener, &slist, link) { From b2c720e79a0e70d29162a91b87e38c6cb31d1de2 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Wed, 20 Aug 2025 12:21:29 +0200 Subject: [PATCH 1316/1333] apps/dtm: Fix compilation error Fixes error: main.c:169:10: error: implicit declaration of function 'ble_hs_hci_send_vs_cmd' [-Wimplicit-function-declaration] 169 | rc = ble_hs_hci_send_vs_cmd(BLE_HCI_OCF_VS_SET_TX_PWR, | ^~~~~~~~~~~~~~~~~~~~~~ --- apps/dtm/src/main.c | 1 + apps/dtm/syscfg.yml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/apps/dtm/src/main.c b/apps/dtm/src/main.c index f3e218bc88..1f8fc11319 100644 --- a/apps/dtm/src/main.c +++ b/apps/dtm/src/main.c @@ -24,6 +24,7 @@ #include "nimble/ble.h" #include "nimble/nimble_opt.h" #include "host/ble_hs.h" +#include "host/ble_hs_hci.h" #include "host/ble_dtm.h" #include #include diff --git a/apps/dtm/syscfg.yml b/apps/dtm/syscfg.yml index 7e00a4736a..82517013e3 100644 --- a/apps/dtm/syscfg.yml +++ b/apps/dtm/syscfg.yml @@ -27,3 +27,5 @@ syscfg.vals: BLE_LL_DTM: 1 BLE_LL_DTM_EXTENSIONS: 1 + + BLE_HCI_VS: 1 From 164f1c23c18a290908df76ed83fe848bfe4a4903 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 14 Aug 2025 12:42:57 +0200 Subject: [PATCH 1317/1333] nimble/ll: Restrict allowed LL Control PDUs received This restricts allowed Control PDUs that can be received in specific encryption state. --- .../include/controller/ble_ll_ctrl.h | 3 +- nimble/controller/src/ble_ll_conn.c | 2 +- nimble/controller/src/ble_ll_ctrl.c | 46 ++++++++++++++++++- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index 402755988b..918cc977b8 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -306,7 +306,8 @@ uint8_t ble_ll_ctrl_conn_param_reply(struct ble_ll_conn_sm *connsm, int ble_ll_ctrl_reject_ind_send(struct ble_ll_conn_sm *connsm, uint8_t rej_opcode, uint8_t err); int ble_ll_ctrl_start_enc_send(struct ble_ll_conn_sm *connsm); -int ble_ll_ctrl_enc_allowed_pdu_rx(struct os_mbuf *rxpdu); +int ble_ll_ctrl_enc_allowed_pdu_rx(struct ble_ll_conn_sm *connsm, + struct os_mbuf *rxpdu); int ble_ll_ctrl_enc_allowed_pdu_tx(struct os_mbuf_pkthdr *pkthdr); int ble_ll_ctrl_tx_start(struct ble_ll_conn_sm *connsm, struct os_mbuf *txpdu); int ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm); diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index bd3f2f64d3..e74f8b6154 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -3533,7 +3533,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) CONN_IS_CENTRAL(connsm)) || (connsm->enc_data.enc_state >= CONN_ENC_S_ENC_RSP_TO_BE_SENT && CONN_IS_PERIPHERAL(connsm))) { - if (!ble_ll_ctrl_enc_allowed_pdu_rx(rxpdu)) { + if (!ble_ll_ctrl_enc_allowed_pdu_rx(connsm, rxpdu)) { ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC); goto conn_rx_data_pdu_end; } diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index bfb9de7e39..6a13c28ed1 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1451,11 +1451,13 @@ ble_ll_ctrl_enc_allowed_pdu(uint8_t llid, uint8_t len, uint8_t opcode) } int -ble_ll_ctrl_enc_allowed_pdu_rx(struct os_mbuf *rxpdu) +ble_ll_ctrl_enc_allowed_pdu_rx(struct ble_ll_conn_sm *connsm, struct os_mbuf *rxpdu) { uint8_t llid; uint8_t len; uint8_t opcode; + uint8_t state; + int allowed; llid = rxpdu->om_data[0] & BLE_LL_DATA_HDR_LLID_MASK; len = rxpdu->om_data[1]; @@ -1465,7 +1467,47 @@ ble_ll_ctrl_enc_allowed_pdu_rx(struct os_mbuf *rxpdu) opcode = 0; } - return ble_ll_ctrl_enc_allowed_pdu(llid, len, opcode); + allowed = 0; + state = connsm->enc_data.enc_state; + + switch (llid) { + case BLE_LL_LLID_CTRL: + switch (opcode) { + case BLE_LL_CTRL_REJECT_IND: + case BLE_LL_CTRL_REJECT_IND_EXT: + allowed = state == CONN_ENC_S_ENC_RSP_WAIT || + state == CONN_ENC_S_START_ENC_REQ_WAIT; + break; + case BLE_LL_CTRL_START_ENC_RSP: + allowed = state == CONN_ENC_S_START_ENC_RSP_WAIT; + break; + case BLE_LL_CTRL_START_ENC_REQ: + allowed = state == CONN_ENC_S_START_ENC_REQ_WAIT; + break; + case BLE_LL_CTRL_ENC_REQ: + allowed = state == CONN_ENC_S_ENCRYPTED || state == CONN_ENC_S_PAUSED; + break; + case BLE_LL_CTRL_ENC_RSP: + allowed = state == CONN_ENC_S_ENC_RSP_WAIT; + break; + case BLE_LL_CTRL_PAUSE_ENC_REQ: + allowed = state == CONN_ENC_S_ENCRYPTED; + break; + case BLE_LL_CTRL_PAUSE_ENC_RSP: + allowed = state == CONN_ENC_S_PAUSE_ENC_RSP_WAIT; + break; + case BLE_LL_CTRL_TERMINATE_IND: + allowed = 1; + break; + } + break; + case BLE_LL_LLID_DATA_FRAG: + /* Empty PDUs are allowed */ + allowed = len == 0; + break; + } + + return allowed; } int From ec3d75e909fa6dcadf1836fefc4432794a673d18 Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Thu, 14 Aug 2025 13:15:20 +0200 Subject: [PATCH 1318/1333] nimble/ll: Disconnect the link on LTK negative reply As per Core 6.1 | Vol 6, Part B | 5.1.3.1 Encryption Start proc If this procedure is being performed after a Pause Encryption procedure, and the Peripheral's Host does not provide a Long Term Key, the Peripheral shall perform the ACL Termination procedure with the error code PIN or Key Missing (0x06). --- .../controller/include/controller/ble_ll_conn.h | 1 + nimble/controller/src/ble_ll_conn.c | 16 +++++++++++++--- nimble/controller/src/ble_ll_conn_hci.c | 16 +++++++++++++--- nimble/controller/src/ble_ll_ctrl.c | 4 ++++ 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h index 2b0c606dd6..90f013fbe1 100644 --- a/nimble/controller/include/controller/ble_ll_conn.h +++ b/nimble/controller/include/controller/ble_ll_conn.h @@ -108,6 +108,7 @@ struct ble_ll_conn_sm_flags { uint32_t encrypted : 1; uint32_t encrypt_ltk_req : 1; uint32_t encrypt_event_sent : 1; + uint32_t encrypt_paused : 1; uint32_t pending_encrypt_restart : 1; uint32_t version_ind_txd : 1; uint32_t version_ind_rxd : 1; diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index e74f8b6154..a702f35323 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -972,11 +972,21 @@ ble_ll_conn_chk_csm_flags(struct ble_ll_conn_sm *connsm) if (connsm->flags.encrypt_ltk_req) { /* * Send Long term key request event to host. If masked, we need to - * send a REJECT_IND. + * send a REJECT_IND or TERMINATE_IND. */ if (ble_ll_hci_ev_ltk_req(connsm)) { - ble_ll_ctrl_reject_ind_send(connsm, BLE_LL_CTRL_ENC_REQ, - BLE_ERR_PINKEY_MISSING); + /* Core 6.1 | Vol 6, Part B | 5.1.3.1 + * If this procedure is being performed after a Pause Encryption procedure, and the + * Peripheral's Host does not provide a Long Term Key, the Peripheral shall perform the + * ACL Termination procedure with the error code PIN or Key Missing (0x06). + */ + if (connsm->flags.encrypt_paused) { + connsm->disconnect_reason = BLE_ERR_PINKEY_MISSING; + ble_ll_ctrl_terminate_start(connsm); + } else { + ble_ll_ctrl_reject_ind_send(connsm, BLE_LL_CTRL_ENC_REQ, + BLE_ERR_PINKEY_MISSING); + } } connsm->flags.encrypt_ltk_req = 0; } diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c index 925bab8b49..0a601c4a00 100644 --- a/nimble/controller/src/ble_ll_conn_hci.c +++ b/nimble/controller/src/ble_ll_conn_hci.c @@ -1701,9 +1701,19 @@ ble_ll_conn_hci_le_ltk_neg_reply(const uint8_t *cmdbuf, uint8_t len, goto ltk_key_cmd_complete; } - /* We received a negative reply! Send REJECT_IND */ - ble_ll_ctrl_reject_ind_send(connsm, BLE_LL_CTRL_ENC_REQ, - BLE_ERR_PINKEY_MISSING); + /* Core 6.1 | Vol 6, Part B | 5.1.3.1 + * If this procedure is being performed after a Pause Encryption procedure, and the + * Peripheral's Host does not provide a Long Term Key, the Peripheral shall perform the + * ACL Termination procedure with the error code PIN or Key Missing (0x06). + */ + if (connsm->flags.encrypt_paused) { + connsm->disconnect_reason = BLE_ERR_PINKEY_MISSING; + ble_ll_ctrl_terminate_start(connsm); + } else { + /* We received a negative reply! Send REJECT_IND */ + ble_ll_ctrl_reject_ind_send(connsm, BLE_LL_CTRL_ENC_REQ, BLE_ERR_PINKEY_MISSING); + } + connsm->enc_data.enc_state = CONN_ENC_S_LTK_NEG_REPLY; rc = BLE_ERR_SUCCESS; diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 6a13c28ed1..5d6e3bcea9 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -1845,6 +1845,7 @@ ble_ll_ctrl_rx_start_enc_rsp(struct ble_ll_conn_sm *connsm) /* We are encrypted */ connsm->enc_data.enc_state = CONN_ENC_S_ENCRYPTED; + connsm->flags.encrypt_paused = 0; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) ble_ll_conn_auth_pyld_timer_start(connsm); #endif @@ -3246,6 +3247,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) break; #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) case BLE_LL_CTRL_PAUSE_ENC_REQ: + connsm->flags.encrypt_paused = 1; /* note: fall-through intentional */ case BLE_LL_CTRL_ENC_REQ: connsm->enc_data.enc_state = CONN_ENC_S_ENC_RSP_WAIT; @@ -3258,6 +3260,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) case BLE_LL_CTRL_START_ENC_RSP: if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { connsm->enc_data.enc_state = CONN_ENC_S_ENCRYPTED; + connsm->flags.encrypt_paused = 0; if (connsm->flags.le_ping_supp) { ble_ll_conn_auth_pyld_timer_start(connsm); } @@ -3266,6 +3269,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) case BLE_LL_CTRL_PAUSE_ENC_RSP: if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) { connsm->enc_data.enc_state = CONN_ENC_S_PAUSE_ENC_RSP_WAIT; + connsm->flags.encrypt_paused = 1; } else { connsm->flags.pending_encrypt_restart = 1; } From b0f06d8da8b8c4963b17ccfdc21eb91472c040be Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Wed, 20 Aug 2025 15:50:40 +0200 Subject: [PATCH 1319/1333] nimble/phy/cmac: Remove redundant assert The assert was originally added for debugging purposes a long time ago. It has been reported to cause issues in DTM, so it is now removed to prevent further problems. --- nimble/drivers/dialog_cmac/src/ble_phy.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/nimble/drivers/dialog_cmac/src/ble_phy.c b/nimble/drivers/dialog_cmac/src/ble_phy.c index c077f25ff3..de7024b463 100644 --- a/nimble/drivers/dialog_cmac/src/ble_phy.c +++ b/nimble/drivers/dialog_cmac/src/ble_phy.c @@ -1365,8 +1365,6 @@ ble_phy_rx_set_start_time(uint32_t cputime, uint8_t rem_usecs) ble_phy_mode_apply(g_ble_phy_data.phy_mode_rx); #endif - assert(ble_rf_is_enabled()); - ble_phy_rx(); /* Store LLT value at RX start, we'll need this to set wfr */ From 3f9d551d1cdda534cf6982a847a44dd079547c3a Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Sat, 23 Aug 2025 10:41:03 +0200 Subject: [PATCH 1320/1333] nuttx/nimble_npl_os_log.h: fix log level config from Kconfig The log messages control was broken since: da4e2f0f12859079f1bde47cbd69f39026c3cc73. All log messages were printed. With this change we can configure the log level from Kconfig again. Signed-off-by: raiden00pl --- .../nuttx/include/nimble/nimble_npl_os_log.h | 53 ++++++++++++++----- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/porting/npl/nuttx/include/nimble/nimble_npl_os_log.h b/porting/npl/nuttx/include/nimble/nimble_npl_os_log.h index 24315a21a7..01220b805d 100644 --- a/porting/npl/nuttx/include/nimble/nimble_npl_os_log.h +++ b/porting/npl/nuttx/include/nimble/nimble_npl_os_log.h @@ -20,18 +20,45 @@ #ifndef _NIMBLE_NPL_OS_LOG_H_ #define _NIMBLE_NPL_OS_LOG_H_ -#include -#include - -/* Example on how to use macro to generate module logging functions */ -#define BLE_NPL_LOG_IMPL(lvl) \ - static inline void _BLE_NPL_LOG_CAT(BLE_NPL_LOG_MODULE, \ - _BLE_NPL_LOG_CAT(_, lvl))(const char *fmt, ...)\ - { \ - va_list args; \ - va_start(args, fmt); \ - vprintf(fmt, args); \ - va_end(args); \ - } +#include +#include + +/* Debug log level configurable from Kconfig */ + +#ifdef CONFIG_NIMBLE_DEBUG_ERROR +#define nimble_err _err +#else +#define nimble_err _none +#endif + +#ifdef CONFIG_NIMBLE_DEBUG_WARN +#define nimble_warn _warn +#else +#define nimble_warn _none +#endif + +#ifdef CONFIG_NIMBLE_DEBUG_INFO +#define nimble_info _info +#else +#define nimble_info _none +#endif + +#define DFLT_LOG_DEBUG(msg, ...) nimble_info(msg, ##__VA_ARGS__) +#define DFLT_LOG_INFO(msg, ...) nimble_info(msg, ##__VA_ARGS__) +#define DFLT_LOG_WARN(msg, ...) nimble_warn(msg, ##__VA_ARGS__) +#define DFLT_LOG_ERROR(msg, ...) nimble_err(msg, ##__VA_ARGS__) +#define DFLT_LOG_CRITICAL(msg, ...) nimble_err(msg, ##__VA_ARGS__) + +#define BLE_HS_LOG_DEBUG(msg, ...) nimble_info(msg, ##__VA_ARGS__) +#define BLE_HS_LOG_INFO(msg, ...) nimble_info(msg, ##__VA_ARGS__) +#define BLE_HS_LOG_WARN(msg, ...) nimble_warn(msg, ##__VA_ARGS__) +#define BLE_HS_LOG_ERROR(msg, ...) nimble_err(msg, ##__VA_ARGS__) +#define BLE_HS_LOG_CRITICAL(msg, ...) nimble_err(msg, ##__VA_ARGS__) + +#define BLE_EATT_LOG_DEBUG(msg, ...) nimble_info(msg, ##__VA_ARGS__) +#define BLE_EATT_LOG_INFO(msg, ...) nimble_info(msg, ##__VA_ARGS__) +#define BLE_EATT_LOG_WARN(msg, ...) nimble_warn(msg, ##__VA_ARGS__) +#define BLE_EATT_LOG_ERROR(msg, ...) nimble_err(msg, ##__VA_ARGS__) +#define BLE_EATT_LOG_CRITICAL(msg, ...) nimble_err(msg, ##__VA_ARGS__) #endif /* _NIMBLE_NPL_OS_LOG_H_ */ From 4c9630f537fedd861fec0e1ca547b9b8ae44fd61 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Sat, 23 Aug 2025 11:11:33 +0200 Subject: [PATCH 1321/1333] transport/ble_hci_socket.c: fix implicit declaration error fix NuttX compilation error with GCC14: mynewt-nimble/nimble/transport/socket/src/ble_hci_socket.c:921:12: error: implicit declaration of function 'ble_hci_sock_iso_tx'; Signed-off-by: raiden00pl --- nimble/transport/socket/src/ble_hci_socket.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/transport/socket/src/ble_hci_socket.c b/nimble/transport/socket/src/ble_hci_socket.c index c0581c6359..d76c4dfa5d 100644 --- a/nimble/transport/socket/src/ble_hci_socket.c +++ b/nimble/transport/socket/src/ble_hci_socket.c @@ -915,11 +915,13 @@ ble_hci_sock_init(void) SYSINIT_PANIC_ASSERT(rc == 0); } +#if MYNEWT_VAL(BLE_SOCK_USE_LINUX_BLUE) || MYNEWT_VAL(BLE_SOCK_USE_TCP) int ble_transport_to_ll_iso_impl(struct os_mbuf *om) { return ble_hci_sock_iso_tx(om); } +#endif void ble_transport_ll_init(void) From b6831813cfe6da9b25c8be7136b40ce060bf9710 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Sat, 23 Aug 2025 12:59:11 +0200 Subject: [PATCH 1322/1333] transport/rx_task.c: fix defined but not used warning fix warning on NuttX: mynewt-nimble/nimble/transport/src/rx_task.c:49:1: warning: 'rx_task_func' defined but not used [-Wunused-function] Signed-off-by: raiden00pl --- nimble/transport/src/rx_task.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/transport/src/rx_task.c b/nimble/transport/src/rx_task.c index 4e7d7196a9..957ab79073 100644 --- a/nimble/transport/src/rx_task.c +++ b/nimble/transport/src/rx_task.c @@ -45,6 +45,7 @@ rx_event_func(struct ble_npl_event *ev) rx_func(rx_func_arg); } +#ifdef MYNEWT static void rx_task_func(void *arg) { @@ -57,6 +58,7 @@ rx_task_func(void *arg) ble_npl_event_run(ev); } } +#endif void ble_transport_rx_register(ble_transport_rx_func_t *func, void *arg) From 5ad616a7e2c1984626f63586c2fd78b1e91bdd4b Mon Sep 17 00:00:00 2001 From: Mynewt Bot Date: Tue, 2 Sep 2025 21:46:06 +0000 Subject: [PATCH 1323/1333] porting: Update ports syscfg --- porting/npl/riot/include/syscfg/syscfg.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 788bb102f7..23d4e962ee 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -776,6 +776,8 @@ #endif #undef MYNEWT_VAL_MYNEWT_DEBUGGER +#undef MYNEWT_VAL_MYNEWT_DEBUGGER_SN + #ifndef MYNEWT_VAL_MYNEWT_DOWNLOADER__ezflashcli #define MYNEWT_VAL_MYNEWT_DOWNLOADER__ezflashcli (0) #endif From c9dbee471a0e35e44e0fffd6a7fffb422bb52f85 Mon Sep 17 00:00:00 2001 From: Piotr Narajowski Date: Tue, 19 Aug 2025 13:40:39 +0200 Subject: [PATCH 1324/1333] nimble/host: fix ble_svc_gatt_cl_sup_feat_access Fix ble_svc_gatt_cl_sup_feat_access. If an error occured while client writes to client supported features only BLE_ATT_ERR_UNLIKELY was returned. --- nimble/host/services/gatt/src/ble_svc_gatt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nimble/host/services/gatt/src/ble_svc_gatt.c b/nimble/host/services/gatt/src/ble_svc_gatt.c index 91abf9ad65..331d6bedd8 100644 --- a/nimble/host/services/gatt/src/ble_svc_gatt.c +++ b/nimble/host/services/gatt/src/ble_svc_gatt.c @@ -113,8 +113,9 @@ ble_svc_gatt_cl_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle, return 0; } if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - if (ble_gatts_peer_cl_sup_feat_update(conn_handle, ctxt->om)) { - return BLE_ATT_ERR_UNLIKELY; + rc = ble_gatts_peer_cl_sup_feat_update(conn_handle, ctxt->om); + if (rc != 0) { + return rc; } } From ac1f8373f9b79db122f9cb1a1ba06064fff31783 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 8 Apr 2025 11:55:49 +0200 Subject: [PATCH 1325/1333] nimble/host: Rework L2CAP RX This reworks L2CAP RX path to simplify flow and fix reassembly issues. RX is now done in conn context instead of chan context. This allows to save few bytes of memory per chan since RX data are now held per-conn instead of per-chan. The new code also fixes reassembly issue where we couldn't properly reassemble L2CAP SDU if the first fragment was shorter than the L2CAP header. --- nimble/host/src/ble_att.c | 4 +- nimble/host/src/ble_hs_conn.c | 11 +- nimble/host/src/ble_hs_conn_priv.h | 14 +- nimble/host/src/ble_hs_hci_evt.c | 51 +----- nimble/host/src/ble_l2cap.c | 285 ++++++++++++----------------- nimble/host/src/ble_l2cap_coc.c | 7 +- nimble/host/src/ble_l2cap_priv.h | 21 +-- nimble/host/src/ble_l2cap_sig.c | 4 +- nimble/host/src/ble_sm.c | 8 +- 9 files changed, 152 insertions(+), 253 deletions(-) diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index 6d4e05af12..8bde29b2ac 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -564,7 +564,7 @@ ble_att_rx_extended(uint16_t conn_handle, uint16_t cid, struct os_mbuf **om) } static int -ble_att_rx(struct ble_l2cap_chan *chan) +ble_att_rx(struct ble_l2cap_chan *chan, struct os_mbuf **om) { uint16_t conn_handle; @@ -573,7 +573,7 @@ ble_att_rx(struct ble_l2cap_chan *chan) return BLE_HS_ENOTCONN; } - return ble_att_rx_extended(conn_handle, chan->scid, &chan->rx_buf); + return ble_att_rx_extended(conn_handle, chan->scid, om); } uint16_t diff --git a/nimble/host/src/ble_hs_conn.c b/nimble/host/src/ble_hs_conn.c index 1e83d33de2..ba034a2703 100644 --- a/nimble/host/src/ble_hs_conn.c +++ b/nimble/host/src/ble_hs_conn.c @@ -207,10 +207,6 @@ ble_hs_conn_alloc(uint16_t conn_handle) void ble_hs_conn_delete_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) { - if (conn->bhc_rx_chan == chan) { - conn->bhc_rx_chan = NULL; - } - SLIST_REMOVE(&conn->bhc_channels, chan, ble_l2cap_chan, next); ble_l2cap_chan_free(conn, chan); } @@ -244,6 +240,9 @@ ble_hs_conn_free(struct ble_hs_conn *conn) return; } + os_mbuf_free_chain(conn->rx_frags); + conn->rx_frags = NULL; + ble_att_svr_prep_clear(&conn->bhc_att_svr.basc_prep_list); while ((chan = SLIST_FIRST(&conn->bhc_channels)) != NULL) { @@ -504,8 +503,8 @@ ble_hs_conn_timer(void) * passes after a partial packet is received, the connection is * terminated. */ - if (conn->bhc_rx_chan != NULL) { - time_diff = conn->bhc_rx_timeout - now; + if (conn->rx_len) { + time_diff = conn->rx_frag_tmo - now; if (time_diff <= 0) { /* ACL reassembly has timed out.*/ diff --git a/nimble/host/src/ble_hs_conn_priv.h b/nimble/host/src/ble_hs_conn_priv.h index 2d23422f54..8a0412fa5b 100644 --- a/nimble/host/src/ble_hs_conn_priv.h +++ b/nimble/host/src/ble_hs_conn_priv.h @@ -69,8 +69,18 @@ struct ble_hs_conn { ble_hs_conn_flags_t bhc_flags; struct ble_l2cap_chan_list bhc_channels; - struct ble_l2cap_chan *bhc_rx_chan; /* Channel rxing current packet. */ - ble_npl_time_t bhc_rx_timeout; + + /* ACL RX fragments */ + struct os_mbuf *rx_frags; + /* Expected data length for ACL RX */ + uint16_t rx_len; + /* L2CAP Source CID for ACL RX */ + uint16_t rx_cid; +#if MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT) != 0 + /* Timeout for next fragment for ACL RX */ + ble_npl_time_t rx_frag_tmo; +#endif + #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) uint32_t l2cap_coc_cid_mask[BLE_HS_CONN_L2CAP_COC_CID_MASK_LEN]; #endif diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c index 55031fcd70..8526d8caf2 100644 --- a/nimble/host/src/ble_hs_hci_evt.c +++ b/nimble/host/src/ble_hs_hci_evt.c @@ -1099,15 +1099,14 @@ ble_hs_hci_evt_acl_process(struct os_mbuf *om) { #if NIMBLE_BLE_CONNECT struct hci_data_hdr hci_hdr; - struct ble_hs_conn *conn; - ble_l2cap_rx_fn *rx_cb; uint16_t conn_handle; - int reject_cid; + uint8_t pb; int rc; rc = ble_hs_hci_util_data_hdr_strip(om, &hci_hdr); if (rc != 0) { - goto err; + os_mbuf_free_chain(om); + return rc; } #if (BLETEST_THROUGHPUT_TEST == 0) @@ -1123,50 +1122,14 @@ ble_hs_hci_evt_acl_process(struct os_mbuf *om) #endif if (hci_hdr.hdh_len != OS_MBUF_PKTHDR(om)->omp_len) { - rc = BLE_HS_EBADDATA; - goto err; + os_mbuf_free_chain(om); + return BLE_HS_EBADDATA; } conn_handle = BLE_HCI_DATA_HANDLE(hci_hdr.hdh_handle_pb_bc); + pb = BLE_HCI_DATA_PB(hci_hdr.hdh_handle_pb_bc); + rc = ble_l2cap_rx(conn_handle, pb, om); - ble_hs_lock(); - - conn = ble_hs_conn_find(conn_handle); - if (conn == NULL) { - /* Peer not connected; quietly discard packet. */ - rc = BLE_HS_ENOTCONN; - reject_cid = -1; - } else { - /* Forward ACL data to L2CAP. */ - rc = ble_l2cap_rx(conn, &hci_hdr, om, &rx_cb, &reject_cid); - om = NULL; - } - - ble_hs_unlock(); - - switch (rc) { - case 0: - /* Final fragment received. */ - BLE_HS_DBG_ASSERT(rx_cb != NULL); - rc = rx_cb(conn->bhc_rx_chan); - ble_l2cap_remove_rx(conn, conn->bhc_rx_chan); - break; - - case BLE_HS_EAGAIN: - /* More fragments on the way. */ - break; - - default: - if (reject_cid != -1) { - ble_l2cap_sig_reject_invalid_cid_tx(conn_handle, 0, 0, reject_cid); - } - goto err; - } - - return 0; - -err: - os_mbuf_free_chain(om); return rc; #else return BLE_HS_ENOTSUP; diff --git a/nimble/host/src/ble_l2cap.c b/nimble/host/src/ble_l2cap.c index d88f006162..5a4ff9ad4b 100644 --- a/nimble/host/src/ble_l2cap.c +++ b/nimble/host/src/ble_l2cap.c @@ -80,7 +80,6 @@ ble_l2cap_chan_free(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) return; } - os_mbuf_free_chain(chan->rx_buf); ble_l2cap_coc_cleanup_chan(conn, chan); #if MYNEWT_VAL(BLE_HS_DEBUG) @@ -99,18 +98,17 @@ ble_l2cap_is_mtu_req_sent(const struct ble_l2cap_chan *chan) } int -ble_l2cap_parse_hdr(struct os_mbuf *om, int off, - struct ble_l2cap_hdr *l2cap_hdr) +ble_l2cap_parse_hdr(struct os_mbuf *om, struct ble_l2cap_hdr *hdr) { int rc; - rc = os_mbuf_copydata(om, off, sizeof *l2cap_hdr, l2cap_hdr); + rc = os_mbuf_copydata(om, 0, sizeof(*hdr), hdr); if (rc != 0) { return BLE_HS_EMSGSIZE; } - l2cap_hdr->len = get_le16(&l2cap_hdr->len); - l2cap_hdr->cid = get_le16(&l2cap_hdr->cid); + hdr->len = get_le16(&hdr->len); + hdr->cid = get_le16(&hdr->cid); return 0; } @@ -233,213 +231,168 @@ ble_l2cap_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx) return ble_l2cap_coc_recv_ready(chan, sdu_rx); } -void -ble_l2cap_remove_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) +static uint16_t +ble_l2cap_get_mtu(struct ble_l2cap_chan *chan) { - conn->bhc_rx_chan = NULL; - os_mbuf_free_chain(chan->rx_buf); - chan->rx_buf = NULL; - chan->rx_len = 0; + if (chan->scid == BLE_L2CAP_CID_ATT) { + /* In case of ATT chan->my_mtu keeps preferred MTU which is later + * used during exchange MTU procedure. Helper below gives us actual + * MTU on the channel, which is 23 or higher if exchange MTU has been + * done + */ + return ble_att_chan_mtu(chan); + } + + return chan->my_mtu; } static void -ble_l2cap_append_rx(struct ble_l2cap_chan *chan, struct os_mbuf *frag) +ble_l2cap_rx_free(struct ble_hs_conn *conn) { -#if MYNEWT_VAL(BLE_L2CAP_JOIN_RX_FRAGS) - struct os_mbuf *m; - - /* Copy the data from the incoming fragment into the packet in progress. */ - m = os_mbuf_pack_chains(chan->rx_buf, frag); - assert(m); -#else - /* Join disabled or append failed due to mbuf shortage. Just attach the - * mbuf to the end of the packet. - */ - os_mbuf_concat(chan->rx_buf, frag); -#endif + os_mbuf_free_chain(conn->rx_frags); + conn->rx_frags = NULL; + conn->rx_len = 0; + conn->rx_cid = 0; } static int -ble_l2cap_rx_payload(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, - struct os_mbuf *om, - ble_l2cap_rx_fn **out_rx_cb) +ble_l2cap_rx_frags_process(struct ble_hs_conn *conn) { - int len_diff; + int rem_rx_len; int rc; - if (chan->rx_buf == NULL) { - /* First fragment in packet. */ - chan->rx_buf = om; - } else { - /* Continuation of packet in progress. */ - ble_l2cap_append_rx(chan, om); - } - - /* Determine if packet is fully reassembled. */ - len_diff = OS_MBUF_PKTLEN(chan->rx_buf) - chan->rx_len; - if (len_diff > 0) { - /* More data than expected; data corruption. */ - ble_l2cap_remove_rx(conn, chan); - rc = BLE_HS_EBADDATA; - } else if (len_diff == 0) { - /* All fragments received. */ - *out_rx_cb = chan->rx_fn; + rem_rx_len = conn->rx_len - OS_MBUF_PKTLEN(conn->rx_frags); + if (rem_rx_len == 0) { rc = 0; - } else { - /* More fragments remain. */ + } else if (rem_rx_len > 0) { #if MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT) != 0 - conn->bhc_rx_timeout = + conn->rx_frag_tmo = ble_npl_time_get() + ble_npl_time_ms_to_ticks32(MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT)); ble_hs_timer_resched(); #endif rc = BLE_HS_EAGAIN; + } else { + ble_l2cap_rx_free(conn); + rc = BLE_HS_EBADDATA; } return rc; } -static uint16_t -ble_l2cap_get_mtu(struct ble_l2cap_chan *chan) -{ - if (chan->scid == BLE_L2CAP_CID_ATT) { - /* In case of ATT chan->my_mtu keeps preferred MTU which is later - * used during exchange MTU procedure. Helper below will gives us actual - * MTU on the channel, which is 23 or higher if exchange MTU has been - * done - */ - return ble_att_chan_mtu(chan); - } - - return chan->my_mtu; -} - -/** - * Processes an incoming L2CAP fragment. - * - * @param conn The connection the L2CAP fragment was sent - * over. - * @param hci_hdr The ACL data header that was at the start of - * the L2CAP fragment. This header has been - * stripped from the mbuf parameter. - * @param om An mbuf containing the L2CAP data. If this is - * the first fragment, the L2CAP header is at - * the start of the mbuf. For subsequent - * fragments, the mbuf starts with L2CAP - * payload data. - * @param out_rx_cb If a full L2CAP packet has been received, a - * pointer to the appropriate handler gets - * written here. The caller should pass the - * receive buffer to this callback. - * @param out_reject_cid Indicates whether an L2CAP Command Reject - * command should be sent. If this equals -1, - * no reject should get sent. Otherwise, the - * value indicates the CID that the outgoing - * reject should specify. - * - * @return 0 if a complete L2CAP packet has been received. - * BLE_HS_EAGAIN if a partial L2CAP packet has - * been received; more fragments are expected. - * Other value on error. - */ int -ble_l2cap_rx(struct ble_hs_conn *conn, - struct hci_data_hdr *hci_hdr, - struct os_mbuf *om, - ble_l2cap_rx_fn **out_rx_cb, - int *out_reject_cid) +ble_l2cap_rx(uint16_t conn_handle, uint8_t pb, struct os_mbuf *om) { + struct ble_hs_conn *conn; struct ble_l2cap_chan *chan; - struct ble_l2cap_hdr l2cap_hdr; - uint8_t pb; + struct ble_l2cap_hdr hdr; + struct os_mbuf *rx_frags; + uint16_t rx_len; + uint16_t rx_cid; int rc; - *out_reject_cid = -1; + ble_hs_lock(); + + conn = ble_hs_conn_find(conn_handle); + if (!conn) { + /* Invalid connection handle, discard packet */ + os_mbuf_free_chain(om); + rc = BLE_HS_ENOTCONN; + goto done; + } - pb = BLE_HCI_DATA_PB(hci_hdr->hdh_handle_pb_bc); switch (pb) { case BLE_HCI_PB_FIRST_FLUSH: - /* First fragment. */ - rc = ble_l2cap_parse_hdr(om, 0, &l2cap_hdr); - if (rc != 0) { - goto err; + if (conn->rx_frags) { + /* Previously received data is incomplete, discard it */ + ble_l2cap_rx_free(conn); } - - /* Strip L2CAP header from the front of the mbuf. */ - os_mbuf_adj(om, BLE_L2CAP_HDR_SZ); - - chan = ble_hs_conn_chan_find_by_scid(conn, l2cap_hdr.cid); - if (chan == NULL) { - rc = BLE_HS_ENOENT; - - /* Unsupported channel. If the target CID is the black hole - * channel, quietly drop the packet. Otherwise, send an invalid - * CID response. + conn->rx_frags = om; + break; + case BLE_HCI_PB_MIDDLE: + if (!conn->rx_frags) { + /* Received continuation without 1st packet, discard it. + * This can also happen if we received invalid data earlier which + * was discarded, so we'll just keep discarding until valid 1st + * packet is received. */ - if (l2cap_hdr.cid != BLE_L2CAP_CID_BLACK_HOLE) { - BLE_HS_LOG(DEBUG, "rx on unknown L2CAP channel: %d\n", - l2cap_hdr.cid); - *out_reject_cid = l2cap_hdr.cid; - } - goto err; - } - - /* For CIDs from dynamic range we check if SDU size isn't larger than MPS */ - if (chan->dcid >= BLE_L2CAP_COC_CID_START && - chan->dcid <= BLE_L2CAP_COC_CID_END && - l2cap_hdr.len > chan->my_coc_mps) { - /* Data exceeds MPS */ - BLE_HS_LOG(ERROR, "error: sdu_len > chan->my_coc_mps (%d>%d)\n", - l2cap_hdr.len, chan->my_coc_mps); - ble_l2cap_disconnect(chan); + os_mbuf_free_chain(om); rc = BLE_HS_EBADDATA; - goto err; + goto done; } - if (chan->rx_buf != NULL) { - /* Previous data packet never completed. Discard old packet. */ - ble_l2cap_remove_rx(conn, chan); - } + /* Append fragment to rx buffer */ +#if MYNEWT_VAL(BLE_L2CAP_JOIN_RX_FRAGS) + os_mbuf_pack_chains(conn->rx_frags, om); +#else + os_mbuf_concat(conn->rx_frag, om); +#endif + break; + default: + /* Invalid PB, discard packet */ + os_mbuf_free_chain(om); + ble_l2cap_rx_free(conn); + rc = BLE_HS_EBADDATA; + goto done; + } - if (l2cap_hdr.len > ble_l2cap_get_mtu(chan)) { - /* More data than we expected on the channel. - * Disconnect peer with invalid behaviour - */ - rc = BLE_HS_EBADDATA; - ble_l2cap_disconnect(chan); - goto err; + /* Parse L2CAP header if not yet done */ + if (!conn->rx_len) { + rc = ble_l2cap_parse_hdr(conn->rx_frags, &hdr); + if (rc) { + /* Incomplete header, wait for continuation */ + rc = BLE_HS_EAGAIN; + goto done; } - /* Remember channel and length of L2CAP data for reassembly. */ - conn->bhc_rx_chan = chan; - chan->rx_len = l2cap_hdr.len; - break; + os_mbuf_adj(conn->rx_frags, BLE_L2CAP_HDR_SZ); - case BLE_HCI_PB_MIDDLE: - chan = conn->bhc_rx_chan; - if (chan == NULL || chan->rx_buf == NULL) { - /* Middle fragment without the start. Discard new packet. */ - rc = BLE_HS_EBADDATA; - goto err; - } - break; + conn->rx_len = hdr.len; + conn->rx_cid = hdr.cid; + } - default: - rc = BLE_HS_EBADDATA; - goto err; + /* Process fragments */ + rc = ble_l2cap_rx_frags_process(conn); + if (rc) { + goto done; } - rc = ble_l2cap_rx_payload(conn, chan, om, out_rx_cb); - om = NULL; - if (rc != 0) { - goto err; + rx_frags = conn->rx_frags; + rx_len = conn->rx_len; + rx_cid = conn->rx_cid; + + conn->rx_frags = NULL; + ble_l2cap_rx_free(conn); + + chan = ble_hs_conn_chan_find_by_scid(conn, rx_cid); + + ble_hs_unlock(); + + if (!chan) { + ble_l2cap_sig_reject_invalid_cid_tx(conn_handle, 0, 0, rx_cid); + return BLE_HS_ENOENT; } - return 0; + if (chan->dcid >= BLE_L2CAP_COC_CID_START && + chan->dcid <= BLE_L2CAP_COC_CID_END && rx_len > chan->my_coc_mps) { + ble_l2cap_disconnect(chan); + return BLE_HS_EBADDATA; + } + + if (rx_len > ble_l2cap_get_mtu(chan)) { + ble_l2cap_disconnect(chan); + return BLE_HS_EBADDATA; + } + + rc = chan->rx_fn(chan, &rx_frags); + os_mbuf_free_chain(rx_frags); + + return rc; + +done: + ble_hs_unlock(); -err: - os_mbuf_free_chain(om); return rc; } diff --git a/nimble/host/src/ble_l2cap_coc.c b/nimble/host/src/ble_l2cap_coc.c index 3a483c7510..cb74e7b70d 100644 --- a/nimble/host/src/ble_l2cap_coc.c +++ b/nimble/host/src/ble_l2cap_coc.c @@ -183,18 +183,13 @@ ble_l2cap_event_coc_received_data(struct ble_l2cap_chan *chan, } static int -ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan) +ble_l2cap_coc_rx_fn(struct ble_l2cap_chan *chan, struct os_mbuf **om) { int rc; - struct os_mbuf **om; struct os_mbuf *rx_sdu; struct ble_l2cap_coc_endpoint *rx; uint16_t om_total; - /* Create a shortcut to rx_buf */ - om = &chan->rx_buf; - BLE_HS_DBG_ASSERT(*om != NULL); - /* Create a shortcut to rx endpoint */ rx = &chan->coc_rx; BLE_HS_DBG_ASSERT(rx != NULL); diff --git a/nimble/host/src/ble_l2cap_priv.h b/nimble/host/src/ble_l2cap_priv.h index 21e6a8bf64..926d1b9acb 100644 --- a/nimble/host/src/ble_l2cap_priv.h +++ b/nimble/host/src/ble_l2cap_priv.h @@ -49,16 +49,11 @@ extern STATS_SECT_DECL(ble_l2cap_stats) ble_l2cap_stats; extern struct os_mempool ble_l2cap_chan_pool; -/* This is nimble specific; packets sent to the black hole CID do not elicit - * an "invalid CID" response. - */ -#define BLE_L2CAP_CID_BLACK_HOLE 0xffff - #define BLE_L2CAP_HDR_SZ 4 typedef uint8_t ble_l2cap_chan_flags; -typedef int ble_l2cap_rx_fn(struct ble_l2cap_chan *chan); +typedef int ble_l2cap_rx_fn(struct ble_l2cap_chan *chan, struct os_mbuf **om); struct ble_l2cap_chan { SLIST_ENTRY(ble_l2cap_chan) next; @@ -81,9 +76,6 @@ struct ble_l2cap_chan { ble_l2cap_chan_flags flags; - struct os_mbuf *rx_buf; - uint16_t rx_len; /* Length of current reassembled rx packet. */ - ble_l2cap_rx_fn *rx_fn; #if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 @@ -109,8 +101,7 @@ typedef int ble_l2cap_tx_fn(struct ble_hs_conn *conn, SLIST_HEAD(ble_l2cap_chan_list, ble_l2cap_chan); -int ble_l2cap_parse_hdr(struct os_mbuf *om, int off, - struct ble_l2cap_hdr *l2cap_hdr); +int ble_l2cap_parse_hdr(struct os_mbuf *om, struct ble_l2cap_hdr *hdr); struct os_mbuf *ble_l2cap_prepend_hdr(struct os_mbuf *om, uint16_t cid, uint16_t len); @@ -119,16 +110,10 @@ void ble_l2cap_chan_free(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); bool ble_l2cap_is_mtu_req_sent(const struct ble_l2cap_chan *chan); -int ble_l2cap_rx(struct ble_hs_conn *conn, - struct hci_data_hdr *hci_hdr, - struct os_mbuf *om, - ble_l2cap_rx_fn **out_rx_cb, - int *out_reject_cid); +int ble_l2cap_rx(uint16_t conn_handle, uint8_t pb, struct os_mbuf *om); int ble_l2cap_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, struct os_mbuf *txom); -void ble_l2cap_remove_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); - int ble_l2cap_init(void); /* Below experimental API is available when BLE_VERSION >= 52 */ diff --git a/nimble/host/src/ble_l2cap_sig.c b/nimble/host/src/ble_l2cap_sig.c index 2e356d2e43..3b9e452e5b 100644 --- a/nimble/host/src/ble_l2cap_sig.c +++ b/nimble/host/src/ble_l2cap_sig.c @@ -1850,16 +1850,14 @@ ble_l2cap_sig_rx_reject(uint16_t conn_handle, *****************************************************************************/ static int -ble_l2cap_sig_rx(struct ble_l2cap_chan *chan) +ble_l2cap_sig_rx(struct ble_l2cap_chan *chan, struct os_mbuf **om) { struct ble_l2cap_sig_hdr hdr; ble_l2cap_sig_rx_fn *rx_cb; uint16_t conn_handle; - struct os_mbuf **om; int rc; conn_handle = chan->conn_handle; - om = &chan->rx_buf; STATS_INC(ble_l2cap_stats, sig_rx); diff --git a/nimble/host/src/ble_sm.c b/nimble/host/src/ble_sm.c index a83b9ff287..a6ed2986ce 100644 --- a/nimble/host/src/ble_sm.c +++ b/nimble/host/src/ble_sm.c @@ -2684,13 +2684,12 @@ ble_sm_enc_initiate(uint16_t conn_handle, uint8_t key_size, } static int -ble_sm_rx(struct ble_l2cap_chan *chan) +ble_sm_rx(struct ble_l2cap_chan *chan, struct os_mbuf **om) { struct ble_sm_result res; ble_sm_rx_fn *rx_cb; uint8_t op; uint16_t conn_handle; - struct os_mbuf **om; int rc; STATS_INC(ble_l2cap_stats, sm_rx); @@ -2700,9 +2699,6 @@ ble_sm_rx(struct ble_l2cap_chan *chan) return BLE_HS_ENOTCONN; } - om = &chan->rx_buf; - BLE_HS_DBG_ASSERT(*om != NULL); - rc = os_mbuf_copydata(*om, 0, 1, &op); if (rc != 0) { return BLE_HS_EBADDATA; @@ -2873,7 +2869,7 @@ ble_sm_init(void) * simple */ static int -ble_sm_rx(struct ble_l2cap_chan *chan) +ble_sm_rx(struct ble_l2cap_chan *chan, struct os_mbuf **om) { struct ble_sm_pair_fail *cmd; struct os_mbuf *txom; From a119bdaf5bb992681819c944a67d253d1a40b5f2 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Tue, 8 Apr 2025 11:55:44 +0200 Subject: [PATCH 1326/1333] nimble/host: Fix L2CAP unit tests This fixes L2CAP unit tests after latest rework. --- nimble/host/test/src/ble_hs_test_util.c | 38 ++++--------------------- nimble/host/test/src/ble_l2cap_test.c | 18 +++++------- 2 files changed, 13 insertions(+), 43 deletions(-) diff --git a/nimble/host/test/src/ble_hs_test_util.c b/nimble/host/test/src/ble_hs_test_util.c index f5463b3ea4..f0b26128b0 100644 --- a/nimble/host/test/src/ble_hs_test_util.c +++ b/nimble/host/test/src/ble_hs_test_util.c @@ -104,7 +104,7 @@ ble_hs_test_util_prev_tx_dequeue(void) pb = BLE_HCI_DATA_PB(hci_hdr.hdh_handle_pb_bc); TEST_ASSERT_FATAL(pb == BLE_HCI_PB_FIRST_NON_FLUSH); - rc = ble_l2cap_parse_hdr(om, 0, &l2cap_hdr); + rc = ble_l2cap_parse_hdr(om, &l2cap_hdr); TEST_ASSERT_FATAL(rc == 0); os_mbuf_adj(om, BLE_L2CAP_HDR_SZ); @@ -670,36 +670,13 @@ ble_hs_test_util_l2cap_rx(uint16_t conn_handle, struct hci_data_hdr *hci_hdr, struct os_mbuf *om) { - struct ble_hs_conn *conn; - ble_l2cap_rx_fn *rx_cb; - int reject_cid; + uint8_t pb; int rc; - ble_hs_lock(); - - conn = ble_hs_conn_find(conn_handle); - if (conn != NULL) { - rc = ble_l2cap_rx(conn, hci_hdr, om, &rx_cb, &reject_cid); - } else { - rc = os_mbuf_free_chain(om); - TEST_ASSERT_FATAL(rc == 0); - } - - ble_hs_unlock(); - - if (conn == NULL) { - rc = BLE_HS_ENOTCONN; - } else if (rc == 0) { - TEST_ASSERT_FATAL(rx_cb != NULL); - rc = rx_cb(conn->bhc_rx_chan); - ble_l2cap_remove_rx(conn, conn->bhc_rx_chan); - } else if (rc == BLE_HS_EAGAIN) { - /* More fragments on the way. */ + pb = BLE_HCI_DATA_PB(hci_hdr->hdh_handle_pb_bc); + rc = ble_l2cap_rx(conn_handle, pb, om); + if (rc == BLE_HS_EAGAIN) { rc = 0; - } else { - if (reject_cid != -1) { - ble_l2cap_sig_reject_invalid_cid_tx(conn_handle, 0, 0, reject_cid); - } } return rc; @@ -1787,7 +1764,6 @@ ble_hs_test_util_mbuf_count(const struct ble_hs_test_util_mbuf_params *params) { const struct ble_att_prep_entry *prep; const struct os_mbuf_pkthdr *omp; - const struct ble_l2cap_chan *chan; const struct ble_hs_conn *conn; const struct os_mbuf *om; int count; @@ -1813,9 +1789,7 @@ ble_hs_test_util_mbuf_count(const struct ble_hs_test_util_mbuf_params *params) } if (params->rx_queue) { - SLIST_FOREACH(chan, &conn->bhc_channels, next) { - count += ble_hs_test_util_mbuf_chain_len(chan->rx_buf); - } + count += ble_hs_test_util_mbuf_chain_len(conn->rx_frags); } if (params->prep_list) { diff --git a/nimble/host/test/src/ble_l2cap_test.c b/nimble/host/test/src/ble_l2cap_test.c index d1db844db9..6fd294b82b 100644 --- a/nimble/host/test/src/ble_l2cap_test.c +++ b/nimble/host/test/src/ble_l2cap_test.c @@ -124,7 +124,7 @@ ble_l2cap_test_util_verify_tx_update_conn( } static int -ble_l2cap_test_util_dummy_rx(struct ble_l2cap_chan *chan) +ble_l2cap_test_util_dummy_rx(struct ble_l2cap_chan *chan, struct os_mbuf **om) { return 0; } @@ -220,8 +220,7 @@ ble_l2cap_test_util_verify_first_frag(uint16_t conn_handle, conn = ble_hs_conn_find(conn_handle); TEST_ASSERT_FATAL(conn != NULL); - TEST_ASSERT(conn->bhc_rx_chan != NULL && - conn->bhc_rx_chan->scid == BLE_L2CAP_TEST_CID); + TEST_ASSERT(conn->rx_len && conn->rx_cid == BLE_L2CAP_TEST_CID); ble_hs_unlock(); } @@ -240,8 +239,7 @@ ble_l2cap_test_util_verify_middle_frag(uint16_t conn_handle, conn = ble_hs_conn_find(conn_handle); TEST_ASSERT_FATAL(conn != NULL); - TEST_ASSERT(conn->bhc_rx_chan != NULL && - conn->bhc_rx_chan->scid == BLE_L2CAP_TEST_CID); + TEST_ASSERT(conn->rx_len && conn->rx_cid == BLE_L2CAP_TEST_CID); ble_hs_unlock(); } @@ -260,7 +258,7 @@ ble_l2cap_test_util_verify_last_frag(uint16_t conn_handle, conn = ble_hs_conn_find(conn_handle); TEST_ASSERT_FATAL(conn != NULL); - TEST_ASSERT(conn->bhc_rx_chan == NULL); + TEST_ASSERT(conn->rx_len == 0); ble_hs_unlock(); } @@ -279,7 +277,7 @@ TEST_CASE_SELF(ble_l2cap_test_case_bad_header) NULL, NULL); rc = ble_l2cap_test_util_rx_first_frag(2, 14, 1234, 10); - TEST_ASSERT(rc == BLE_HS_ENOENT); + TEST_ASSERT(rc == BLE_HS_EBADDATA); ble_hs_test_util_assert_mbufs_freed(NULL); } @@ -386,8 +384,7 @@ TEST_CASE_SELF(ble_l2cap_test_case_frag_channels) ble_hs_lock(); conn = ble_hs_conn_find(2); TEST_ASSERT_FATAL(conn != NULL); - TEST_ASSERT(conn->bhc_rx_chan != NULL && - conn->bhc_rx_chan->scid == BLE_L2CAP_TEST_CID); + TEST_ASSERT(conn->rx_len && conn->rx_cid == BLE_L2CAP_TEST_CID); ble_hs_unlock(); /* Receive a starting fragment on a different channel. The first fragment @@ -400,8 +397,7 @@ TEST_CASE_SELF(ble_l2cap_test_case_frag_channels) ble_hs_lock(); conn = ble_hs_conn_find(2); TEST_ASSERT_FATAL(conn != NULL); - TEST_ASSERT(conn->bhc_rx_chan != NULL && - conn->bhc_rx_chan->scid == BLE_L2CAP_CID_ATT); + TEST_ASSERT(conn->rx_len && conn->rx_cid == BLE_L2CAP_CID_ATT); ble_hs_unlock(); /* Terminate the connection. The received fragments should get freed. From 1701428134710ab718fb20fdfd138652cfb91516 Mon Sep 17 00:00:00 2001 From: v-tangmeng Date: Mon, 15 Sep 2025 13:51:22 +0800 Subject: [PATCH 1327/1333] porting/npl/nuttx: fix compile error porting/npl/nuttx/src/os_callout.c:125:24: error: comparison between pointer and integer [-Werror] 125 | return (c->c_timer != NULL); | ^~ cc1: all warnings being treated as errors Signed-off-by: v-tangmeng --- porting/npl/nuttx/src/os_callout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porting/npl/nuttx/src/os_callout.c b/porting/npl/nuttx/src/os_callout.c index 3b4ee5fb0e..5b384dc8f3 100644 --- a/porting/npl/nuttx/src/os_callout.c +++ b/porting/npl/nuttx/src/os_callout.c @@ -122,7 +122,7 @@ ble_npl_callout_is_active(struct ble_npl_callout *c) int ble_npl_callout_inited(struct ble_npl_callout *c) { - return (c->c_timer != NULL); + return (c->c_timer != 0); } ble_npl_error_t From 6a5a16c7c0fab0fe7e95154493ff1fe9f0824fe3 Mon Sep 17 00:00:00 2001 From: v-tangmeng Date: Wed, 24 Sep 2025 13:38:41 +0800 Subject: [PATCH 1328/1333] nimble/host: Rename STRINGIFY to aviod compile error If `STRINGIFY` is also defined in the kernel or other third-party libraries, it will cause the following error: ble_gatts_lcl.c:95: error:"STRINGIFY" redefined [-Werror] 95 | #define STRINGIFY(X) #X In order to prevent this situation, rename to `NIMBLE_STRINGIFY`. Signed-off-by: v-tangmeng --- nimble/host/src/ble_gatts_lcl.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/nimble/host/src/ble_gatts_lcl.c b/nimble/host/src/ble_gatts_lcl.c index f824e9000a..8d829ae51a 100644 --- a/nimble/host/src/ble_gatts_lcl.c +++ b/nimble/host/src/ble_gatts_lcl.c @@ -91,10 +91,9 @@ ble_gatts_flags_to_str(uint16_t flags, char *buf, return buf; } - -#define STRINGIFY(X) #X -#define FIELD_NAME_LEN STRINGIFY(12) -#define FIELD_INDENT STRINGIFY(2) +#define NIMBLE_STRINGIFY(X) #X +#define FIELD_NAME_LEN NIMBLE_STRINGIFY(12) +#define FIELD_INDENT NIMBLE_STRINGIFY(2) static void ble_gatt_show_local_chr(const struct ble_gatt_svc_def *svc, From b7590dc3499f6b1da45dc41bb2f05a4d6122d753 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 16 Sep 2025 14:01:17 +0200 Subject: [PATCH 1329/1333] porting: Fix name length in advertising data for linux sample Advertised name unnecessarily contained NULL termination. --- porting/examples/linux/ble.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porting/examples/linux/ble.c b/porting/examples/linux/ble.c index ea6655f21f..f196f514ab 100644 --- a/porting/examples/linux/ble.c +++ b/porting/examples/linux/ble.c @@ -52,7 +52,7 @@ update_ad(void) uint8_t ad_flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; put_ad(BLE_HS_ADV_TYPE_FLAGS, 1, &ad_flags, ad, &ad_len); - put_ad(BLE_HS_ADV_TYPE_COMP_NAME, sizeof(gap_name), gap_name, ad, &ad_len); + put_ad(BLE_HS_ADV_TYPE_COMP_NAME, strlen(gap_name), gap_name, ad, &ad_len); ble_gap_adv_set_data(ad, ad_len); } From 321dc0b999a1a8ba4ce19ada17056c1e2c534ea7 Mon Sep 17 00:00:00 2001 From: Rahul <79141360+rahult-github@users.noreply.github.com> Date: Thu, 9 Oct 2025 19:52:03 +0530 Subject: [PATCH 1330/1333] porting: Fix buffer copy for mbuf in different pools Given a chain of at least 2 mbufs, of which the mbufs come from more than one pool of different-sized buffers and the first mbuf is smaller in size than at least one of the rest, the memcpy() in os_mbuf_dup() will write beyond the limits of the allocated mbuf. This is because os_mbuf_dup() assumes all mbufs in a chain come from the same pool as the first mbuf in the chain. Fixed the same. --- porting/nimble/src/os_mbuf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/porting/nimble/src/os_mbuf.c b/porting/nimble/src/os_mbuf.c index 829d798583..93126c62d3 100644 --- a/porting/nimble/src/os_mbuf.c +++ b/porting/nimble/src/os_mbuf.c @@ -384,12 +384,13 @@ os_mbuf_dup(struct os_mbuf *om) struct os_mbuf *head; struct os_mbuf *copy; - omp = om->om_omp; - head = NULL; copy = NULL; for (; om != NULL; om = SLIST_NEXT(om, om_next)) { + + omp = om->om_omp; + if (head) { SLIST_NEXT(copy, om_next) = os_mbuf_get(omp, OS_MBUF_LEADINGSPACE(om)); From 3881e2c467bb24d6b5115e15732a4d4bccedd2f2 Mon Sep 17 00:00:00 2001 From: Mynewt Bot Date: Fri, 10 Oct 2025 21:46:27 +0000 Subject: [PATCH 1331/1333] porting: Update ports syscfg --- porting/npl/riot/include/syscfg/syscfg.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/porting/npl/riot/include/syscfg/syscfg.h b/porting/npl/riot/include/syscfg/syscfg.h index 23d4e962ee..30d0a44e05 100644 --- a/porting/npl/riot/include/syscfg/syscfg.h +++ b/porting/npl/riot/include/syscfg/syscfg.h @@ -778,6 +778,9 @@ #undef MYNEWT_VAL_MYNEWT_DEBUGGER_SN +#ifndef MYNEWT_VAL_MYNEWT_DOWNLOADER__bsp_downloader +#define MYNEWT_VAL_MYNEWT_DOWNLOADER__bsp_downloader (0) +#endif #ifndef MYNEWT_VAL_MYNEWT_DOWNLOADER__ezflashcli #define MYNEWT_VAL_MYNEWT_DOWNLOADER__ezflashcli (0) #endif @@ -816,6 +819,8 @@ #undef MYNEWT_VAL_MYNEWT_DOWNLOADER_OPENOCD_INTERFACE +#undef MYNEWT_VAL_MYNEWT_DOWNLOADER_SCRIPT + #undef MYNEWT_VAL_NRFJPROG_COPROCESSOR #undef MYNEWT_VAL_NRFUTIL_TRAITS From d5644bb5c2d597117345272c128dd56b60cbcadb Mon Sep 17 00:00:00 2001 From: Michal Gorecki Date: Tue, 21 Oct 2025 14:14:17 +0200 Subject: [PATCH 1332/1333] host/store: Fix null pointer dereference If config_fcb reads an empty string it returns NULL pointer. We should handle this in ble_store_config module --- nimble/host/store/config/src/ble_store_config_conf.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimble/host/store/config/src/ble_store_config_conf.c b/nimble/host/store/config/src/ble_store_config_conf.c index e74127ae93..4090b6020b 100644 --- a/nimble/host/store/config/src/ble_store_config_conf.c +++ b/nimble/host/store/config/src/ble_store_config_conf.c @@ -91,6 +91,11 @@ ble_store_config_conf_set(int argc, char **argv, char *val) { int rc; + /* Config returns NULL pointer if it reads an empty string. We change this back into an empty string. */ + if (!val) { + val = ""; + } + if (argc == 1) { if (strcmp(argv[0], "our_sec") == 0) { rc = ble_store_config_deserialize_arr( From 8ec54641e54c631f3597c79d3fb16d5ba4697faf Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 23 Oct 2025 10:20:43 +0200 Subject: [PATCH 1333/1333] ci: Update RAT to 0.17 This updates RAT to version 0.17 and sync with last changes in core. --- .github/workflows/compliance_check.yml | 6 +++--- .rat-excludes | 29 ++++++++++++-------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/.github/workflows/compliance_check.yml b/.github/workflows/compliance_check.yml index afc2458477..23fdfdfbcd 100644 --- a/.github/workflows/compliance_check.yml +++ b/.github/workflows/compliance_check.yml @@ -86,9 +86,9 @@ jobs: run: | mkdir repos git clone --depth=1 https://github.com/apache/mynewt-core repos/apache-mynewt-core - wget https://dlcdn.apache.org//creadur/apache-rat-0.16.1/apache-rat-0.16.1-bin.tar.gz - tar zxf apache-rat-0.16.1-bin.tar.gz apache-rat-0.16.1/apache-rat-0.16.1.jar - mv apache-rat-0.16.1/apache-rat-0.16.1.jar apache-rat.jar + wget https://archive.apache.org/dist/creadur/apache-rat-0.17/apache-rat-0.17-bin.tar.gz + tar zxf apache-rat-0.17-bin.tar.gz apache-rat-0.17/apache-rat-0.17.jar + mv apache-rat-0.17/apache-rat-0.17.jar apache-rat.jar - name: Check licensing shell: bash run: | diff --git a/.rat-excludes b/.rat-excludes index 666ab501be..85397a1dc4 100644 --- a/.rat-excludes +++ b/.rat-excludes @@ -1,33 +1,30 @@ # Can't easily add license to rat-excludes file. .rat-excludes - -# Ignore documentation folder -docs +repos # Non-source files RELEASE_NOTES.md -.gitignore -README.md +**/README.md +Doxyfile .clang-format -.style_ignored_dirs .mailmap -requirements.txt -Doxyfile +.style_ignored_dirs +**/requirements.txt -# tinycrypt - BSD License. -tinycrypt +# Ignore documentation folder +docs -# Queue implementation - BSD License -queue.h +# tinycrypt - BSD License. +ext/tinycrypt # mbuf implementation - BSD License -os_mbuf.c +porting/nimble/src/os_mbuf.c # Nordic nRF5 SDK - BSD License -system_nrf52.c +babblesim/hw/mcu/nordic/nrf52_bsim/src/system_nrf52.c # CMSIS-CORE - BSD License. -cmsis_nvic.h +babblesim/hw/mcu/nordic/nrf52_bsim/include/mcu/cmsis_nvic.h # Linker scripts for Nordics nRF5X - TCL license -nrf5340-mcu.ld +targets/auracast_usb/nrf5340-mcu.ld